Update files
This commit is contained in:
Generated
+38
-300
@@ -56,20 +56,6 @@
|
|||||||
"zod": "^3.25.76 || ^4.1.8"
|
"zod": "^3.25.76 || ^4.1.8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@ai-sdk/openai": {
|
|
||||||
"version": "2.0.53",
|
|
||||||
"license": "Apache-2.0",
|
|
||||||
"dependencies": {
|
|
||||||
"@ai-sdk/provider": "2.0.0",
|
|
||||||
"@ai-sdk/provider-utils": "3.0.12"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=18"
|
|
||||||
},
|
|
||||||
"peerDependencies": {
|
|
||||||
"zod": "^3.25.76 || ^4.1.8"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@ai-sdk/provider": {
|
"node_modules/@ai-sdk/provider": {
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
@@ -4175,280 +4161,6 @@
|
|||||||
"@lezer/lr": "^1.0.0"
|
"@lezer/lr": "^1.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@modelcontextprotocol/sdk": {
|
|
||||||
"version": "1.20.2",
|
|
||||||
"license": "MIT",
|
|
||||||
"optional": true,
|
|
||||||
"peer": true,
|
|
||||||
"dependencies": {
|
|
||||||
"ajv": "^6.12.6",
|
|
||||||
"content-type": "^1.0.5",
|
|
||||||
"cors": "^2.8.5",
|
|
||||||
"cross-spawn": "^7.0.5",
|
|
||||||
"eventsource": "^3.0.2",
|
|
||||||
"eventsource-parser": "^3.0.0",
|
|
||||||
"express": "^5.0.1",
|
|
||||||
"express-rate-limit": "^7.5.0",
|
|
||||||
"pkce-challenge": "^5.0.0",
|
|
||||||
"raw-body": "^3.0.0",
|
|
||||||
"zod": "^3.23.8",
|
|
||||||
"zod-to-json-schema": "^3.24.1"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=18"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@modelcontextprotocol/sdk/node_modules/accepts": {
|
|
||||||
"version": "2.0.0",
|
|
||||||
"license": "MIT",
|
|
||||||
"optional": true,
|
|
||||||
"peer": true,
|
|
||||||
"dependencies": {
|
|
||||||
"mime-types": "^3.0.0",
|
|
||||||
"negotiator": "^1.0.0"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 0.6"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@modelcontextprotocol/sdk/node_modules/body-parser": {
|
|
||||||
"version": "2.2.0",
|
|
||||||
"license": "MIT",
|
|
||||||
"optional": true,
|
|
||||||
"peer": true,
|
|
||||||
"dependencies": {
|
|
||||||
"bytes": "^3.1.2",
|
|
||||||
"content-type": "^1.0.5",
|
|
||||||
"debug": "^4.4.0",
|
|
||||||
"http-errors": "^2.0.0",
|
|
||||||
"iconv-lite": "^0.6.3",
|
|
||||||
"on-finished": "^2.4.1",
|
|
||||||
"qs": "^6.14.0",
|
|
||||||
"raw-body": "^3.0.0",
|
|
||||||
"type-is": "^2.0.0"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=18"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@modelcontextprotocol/sdk/node_modules/content-disposition": {
|
|
||||||
"version": "1.0.0",
|
|
||||||
"license": "MIT",
|
|
||||||
"optional": true,
|
|
||||||
"peer": true,
|
|
||||||
"dependencies": {
|
|
||||||
"safe-buffer": "5.2.1"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 0.6"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@modelcontextprotocol/sdk/node_modules/cookie-signature": {
|
|
||||||
"version": "1.2.2",
|
|
||||||
"license": "MIT",
|
|
||||||
"optional": true,
|
|
||||||
"peer": true,
|
|
||||||
"engines": {
|
|
||||||
"node": ">=6.6.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@modelcontextprotocol/sdk/node_modules/express": {
|
|
||||||
"version": "5.1.0",
|
|
||||||
"license": "MIT",
|
|
||||||
"optional": true,
|
|
||||||
"peer": true,
|
|
||||||
"dependencies": {
|
|
||||||
"accepts": "^2.0.0",
|
|
||||||
"body-parser": "^2.2.0",
|
|
||||||
"content-disposition": "^1.0.0",
|
|
||||||
"content-type": "^1.0.5",
|
|
||||||
"cookie": "^0.7.1",
|
|
||||||
"cookie-signature": "^1.2.1",
|
|
||||||
"debug": "^4.4.0",
|
|
||||||
"encodeurl": "^2.0.0",
|
|
||||||
"escape-html": "^1.0.3",
|
|
||||||
"etag": "^1.8.1",
|
|
||||||
"finalhandler": "^2.1.0",
|
|
||||||
"fresh": "^2.0.0",
|
|
||||||
"http-errors": "^2.0.0",
|
|
||||||
"merge-descriptors": "^2.0.0",
|
|
||||||
"mime-types": "^3.0.0",
|
|
||||||
"on-finished": "^2.4.1",
|
|
||||||
"once": "^1.4.0",
|
|
||||||
"parseurl": "^1.3.3",
|
|
||||||
"proxy-addr": "^2.0.7",
|
|
||||||
"qs": "^6.14.0",
|
|
||||||
"range-parser": "^1.2.1",
|
|
||||||
"router": "^2.2.0",
|
|
||||||
"send": "^1.1.0",
|
|
||||||
"serve-static": "^2.2.0",
|
|
||||||
"statuses": "^2.0.1",
|
|
||||||
"type-is": "^2.0.1",
|
|
||||||
"vary": "^1.1.2"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 18"
|
|
||||||
},
|
|
||||||
"funding": {
|
|
||||||
"type": "opencollective",
|
|
||||||
"url": "https://opencollective.com/express"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@modelcontextprotocol/sdk/node_modules/finalhandler": {
|
|
||||||
"version": "2.1.0",
|
|
||||||
"license": "MIT",
|
|
||||||
"optional": true,
|
|
||||||
"peer": true,
|
|
||||||
"dependencies": {
|
|
||||||
"debug": "^4.4.0",
|
|
||||||
"encodeurl": "^2.0.0",
|
|
||||||
"escape-html": "^1.0.3",
|
|
||||||
"on-finished": "^2.4.1",
|
|
||||||
"parseurl": "^1.3.3",
|
|
||||||
"statuses": "^2.0.1"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 0.8"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@modelcontextprotocol/sdk/node_modules/fresh": {
|
|
||||||
"version": "2.0.0",
|
|
||||||
"license": "MIT",
|
|
||||||
"optional": true,
|
|
||||||
"peer": true,
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 0.8"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@modelcontextprotocol/sdk/node_modules/iconv-lite": {
|
|
||||||
"version": "0.6.3",
|
|
||||||
"license": "MIT",
|
|
||||||
"optional": true,
|
|
||||||
"peer": true,
|
|
||||||
"dependencies": {
|
|
||||||
"safer-buffer": ">= 2.1.2 < 3.0.0"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=0.10.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@modelcontextprotocol/sdk/node_modules/media-typer": {
|
|
||||||
"version": "1.1.0",
|
|
||||||
"license": "MIT",
|
|
||||||
"optional": true,
|
|
||||||
"peer": true,
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 0.8"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@modelcontextprotocol/sdk/node_modules/merge-descriptors": {
|
|
||||||
"version": "2.0.0",
|
|
||||||
"license": "MIT",
|
|
||||||
"optional": true,
|
|
||||||
"peer": true,
|
|
||||||
"engines": {
|
|
||||||
"node": ">=18"
|
|
||||||
},
|
|
||||||
"funding": {
|
|
||||||
"url": "https://github.com/sponsors/sindresorhus"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@modelcontextprotocol/sdk/node_modules/mime-types": {
|
|
||||||
"version": "3.0.1",
|
|
||||||
"license": "MIT",
|
|
||||||
"optional": true,
|
|
||||||
"peer": true,
|
|
||||||
"dependencies": {
|
|
||||||
"mime-db": "^1.54.0"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 0.6"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@modelcontextprotocol/sdk/node_modules/negotiator": {
|
|
||||||
"version": "1.0.0",
|
|
||||||
"license": "MIT",
|
|
||||||
"optional": true,
|
|
||||||
"peer": true,
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 0.6"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@modelcontextprotocol/sdk/node_modules/qs": {
|
|
||||||
"version": "6.14.0",
|
|
||||||
"license": "BSD-3-Clause",
|
|
||||||
"optional": true,
|
|
||||||
"peer": true,
|
|
||||||
"dependencies": {
|
|
||||||
"side-channel": "^1.1.0"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=0.6"
|
|
||||||
},
|
|
||||||
"funding": {
|
|
||||||
"url": "https://github.com/sponsors/ljharb"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@modelcontextprotocol/sdk/node_modules/send": {
|
|
||||||
"version": "1.2.0",
|
|
||||||
"license": "MIT",
|
|
||||||
"optional": true,
|
|
||||||
"peer": true,
|
|
||||||
"dependencies": {
|
|
||||||
"debug": "^4.3.5",
|
|
||||||
"encodeurl": "^2.0.0",
|
|
||||||
"escape-html": "^1.0.3",
|
|
||||||
"etag": "^1.8.1",
|
|
||||||
"fresh": "^2.0.0",
|
|
||||||
"http-errors": "^2.0.0",
|
|
||||||
"mime-types": "^3.0.1",
|
|
||||||
"ms": "^2.1.3",
|
|
||||||
"on-finished": "^2.4.1",
|
|
||||||
"range-parser": "^1.2.1",
|
|
||||||
"statuses": "^2.0.1"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 18"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@modelcontextprotocol/sdk/node_modules/serve-static": {
|
|
||||||
"version": "2.2.0",
|
|
||||||
"license": "MIT",
|
|
||||||
"optional": true,
|
|
||||||
"peer": true,
|
|
||||||
"dependencies": {
|
|
||||||
"encodeurl": "^2.0.0",
|
|
||||||
"escape-html": "^1.0.3",
|
|
||||||
"parseurl": "^1.3.3",
|
|
||||||
"send": "^1.2.0"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 18"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@modelcontextprotocol/sdk/node_modules/type-is": {
|
|
||||||
"version": "2.0.1",
|
|
||||||
"license": "MIT",
|
|
||||||
"optional": true,
|
|
||||||
"peer": true,
|
|
||||||
"dependencies": {
|
|
||||||
"content-type": "^1.0.5",
|
|
||||||
"media-typer": "^1.1.0",
|
|
||||||
"mime-types": "^3.0.0"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 0.6"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@modelcontextprotocol/sdk/node_modules/zod": {
|
|
||||||
"version": "3.25.76",
|
|
||||||
"license": "MIT",
|
|
||||||
"optional": true,
|
|
||||||
"peer": true,
|
|
||||||
"funding": {
|
|
||||||
"url": "https://github.com/sponsors/colinhacks"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@nodelib/fs.scandir": {
|
"node_modules/@nodelib/fs.scandir": {
|
||||||
"version": "2.1.5",
|
"version": "2.1.5",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
@@ -5224,6 +4936,16 @@
|
|||||||
"react-native": "^0.0.0-0 || >=0.65 <1.0"
|
"react-native": "^0.0.0-0 || >=0.65 <1.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@react-native-masked-view/masked-view": {
|
||||||
|
"version": "0.3.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@react-native-masked-view/masked-view/-/masked-view-0.3.2.tgz",
|
||||||
|
"integrity": "sha512-XwuQoW7/GEgWRMovOQtX3A4PrXhyaZm0lVUiY8qJDvdngjLms9Cpdck6SmGAUNqQwcj2EadHC1HwL0bEyoa/SQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"peerDependencies": {
|
||||||
|
"react": ">=16",
|
||||||
|
"react-native": ">=0.57"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@react-native/assets-registry": {
|
"node_modules/@react-native/assets-registry": {
|
||||||
"version": "0.81.5",
|
"version": "0.81.5",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
@@ -5458,11 +5180,6 @@
|
|||||||
"version": "2.1.0",
|
"version": "2.1.0",
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/@react-native/normalize-colors": {
|
|
||||||
"version": "0.82.1",
|
|
||||||
"license": "MIT",
|
|
||||||
"peer": true
|
|
||||||
},
|
|
||||||
"node_modules/@react-native/virtualized-lists": {
|
"node_modules/@react-native/virtualized-lists": {
|
||||||
"version": "0.81.5",
|
"version": "0.81.5",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
@@ -7039,7 +6756,7 @@
|
|||||||
},
|
},
|
||||||
"node_modules/ajv": {
|
"node_modules/ajv": {
|
||||||
"version": "6.12.6",
|
"version": "6.12.6",
|
||||||
"devOptional": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"fast-deep-equal": "^3.1.1",
|
"fast-deep-equal": "^3.1.1",
|
||||||
@@ -15446,6 +15163,7 @@
|
|||||||
},
|
},
|
||||||
"node_modules/playwright": {
|
"node_modules/playwright": {
|
||||||
"version": "1.56.1",
|
"version": "1.56.1",
|
||||||
|
"dev": true,
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"playwright-core": "1.56.1"
|
"playwright-core": "1.56.1"
|
||||||
@@ -15462,6 +15180,7 @@
|
|||||||
},
|
},
|
||||||
"node_modules/playwright-core": {
|
"node_modules/playwright-core": {
|
||||||
"version": "1.56.1",
|
"version": "1.56.1",
|
||||||
|
"dev": true,
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"bin": {
|
"bin": {
|
||||||
"playwright-core": "cli.js"
|
"playwright-core": "cli.js"
|
||||||
@@ -20087,7 +19806,7 @@
|
|||||||
"@dnd-kit/utilities": "^3.2.2",
|
"@dnd-kit/utilities": "^3.2.2",
|
||||||
"@expo/vector-icons": "^15.0.2",
|
"@expo/vector-icons": "^15.0.2",
|
||||||
"@floating-ui/react-native": "^0.10.7",
|
"@floating-ui/react-native": "^0.10.7",
|
||||||
"@getpaseo/server": "*",
|
"@getpaseo/server": "0.1.0",
|
||||||
"@gorhom/bottom-sheet": "^5.2.6",
|
"@gorhom/bottom-sheet": "^5.2.6",
|
||||||
"@gorhom/portal": "^1.0.14",
|
"@gorhom/portal": "^1.0.14",
|
||||||
"@lezer/common": "^1.5.0",
|
"@lezer/common": "^1.5.0",
|
||||||
@@ -20099,6 +19818,7 @@
|
|||||||
"@lezer/markdown": "^1.6.2",
|
"@lezer/markdown": "^1.6.2",
|
||||||
"@lezer/python": "^1.1.18",
|
"@lezer/python": "^1.1.18",
|
||||||
"@react-native-async-storage/async-storage": "2.2.0",
|
"@react-native-async-storage/async-storage": "2.2.0",
|
||||||
|
"@react-native-masked-view/masked-view": "^0.3.2",
|
||||||
"@react-navigation/bottom-tabs": "^7.4.0",
|
"@react-navigation/bottom-tabs": "^7.4.0",
|
||||||
"@react-navigation/elements": "^2.6.3",
|
"@react-navigation/elements": "^2.6.3",
|
||||||
"@react-navigation/native": "^7.1.8",
|
"@react-navigation/native": "^7.1.8",
|
||||||
@@ -20188,7 +19908,8 @@
|
|||||||
"name": "@getpaseo/cli",
|
"name": "@getpaseo/cli",
|
||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@getpaseo/server": "*",
|
"@getpaseo/relay": "0.1.0",
|
||||||
|
"@getpaseo/server": "0.1.0",
|
||||||
"chalk": "^5.3.0",
|
"chalk": "^5.3.0",
|
||||||
"commander": "^12.0.0",
|
"commander": "^12.0.0",
|
||||||
"mime-types": "^2.1.35",
|
"mime-types": "^2.1.35",
|
||||||
@@ -20263,8 +19984,10 @@
|
|||||||
"name": "@getpaseo/server",
|
"name": "@getpaseo/server",
|
||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@ai-sdk/openai": "^2.0.52",
|
"@ai-sdk/openai": "2.0.52",
|
||||||
|
"@anthropic-ai/claude-agent-sdk": "^0.2.11",
|
||||||
"@deepgram/sdk": "^3.4.0",
|
"@deepgram/sdk": "^3.4.0",
|
||||||
|
"@getpaseo/relay": "0.1.0",
|
||||||
"@lezer/common": "^1.5.0",
|
"@lezer/common": "^1.5.0",
|
||||||
"@lezer/css": "^1.3.0",
|
"@lezer/css": "^1.3.0",
|
||||||
"@lezer/highlight": "^1.2.3",
|
"@lezer/highlight": "^1.2.3",
|
||||||
@@ -20277,7 +20000,7 @@
|
|||||||
"@opencode-ai/sdk": "^1.1.12",
|
"@opencode-ai/sdk": "^1.1.12",
|
||||||
"@sctg/sentencepiece-js": "^1.1.0",
|
"@sctg/sentencepiece-js": "^1.1.0",
|
||||||
"@xterm/headless": "^6.0.0",
|
"@xterm/headless": "^6.0.0",
|
||||||
"ai": "^5.0.76",
|
"ai": "5.0.78",
|
||||||
"ajv": "^8.17.1",
|
"ajv": "^8.17.1",
|
||||||
"dotenv": "^17.2.3",
|
"dotenv": "^17.2.3",
|
||||||
"express": "^4.18.2",
|
"express": "^4.18.2",
|
||||||
@@ -20288,7 +20011,6 @@
|
|||||||
"openai": "^4.20.0",
|
"openai": "^4.20.0",
|
||||||
"pino": "^10.2.0",
|
"pino": "^10.2.0",
|
||||||
"pino-pretty": "^13.1.3",
|
"pino-pretty": "^13.1.3",
|
||||||
"playwright": "^1.56.1",
|
|
||||||
"qrcode": "^1.5.4",
|
"qrcode": "^1.5.4",
|
||||||
"sherpa-onnx": "^1.12.23",
|
"sherpa-onnx": "^1.12.23",
|
||||||
"sherpa-onnx-node": "^1.12.23",
|
"sherpa-onnx-node": "^1.12.23",
|
||||||
@@ -20300,7 +20022,6 @@
|
|||||||
"zod-to-json-schema": "^3.25.1"
|
"zod-to-json-schema": "^3.25.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@getpaseo/relay": "*",
|
|
||||||
"@playwright/test": "^1.56.1",
|
"@playwright/test": "^1.56.1",
|
||||||
"@types/express": "^4.17.20",
|
"@types/express": "^4.17.20",
|
||||||
"@types/node": "^20.9.0",
|
"@types/node": "^20.9.0",
|
||||||
@@ -20308,11 +20029,28 @@
|
|||||||
"@types/uuid": "^9.0.7",
|
"@types/uuid": "^9.0.7",
|
||||||
"@types/ws": "^8.5.8",
|
"@types/ws": "^8.5.8",
|
||||||
"@vitest/ui": "^3.2.4",
|
"@vitest/ui": "^3.2.4",
|
||||||
|
"playwright": "^1.56.1",
|
||||||
"tsx": "^4.6.0",
|
"tsx": "^4.6.0",
|
||||||
"typescript": "^5.2.2",
|
"typescript": "^5.2.2",
|
||||||
"vitest": "^3.2.4"
|
"vitest": "^3.2.4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"packages/server/node_modules/@ai-sdk/openai": {
|
||||||
|
"version": "2.0.52",
|
||||||
|
"resolved": "https://registry.npmjs.org/@ai-sdk/openai/-/openai-2.0.52.tgz",
|
||||||
|
"integrity": "sha512-n1arAo4+63e6/FFE6z/1ZsZbiOl4cfsoZ3F4i2X7LPIEea786Y2yd7Qdr7AdB4HTLVo3OSb1PHVIcQmvYIhmEA==",
|
||||||
|
"license": "Apache-2.0",
|
||||||
|
"dependencies": {
|
||||||
|
"@ai-sdk/provider": "2.0.0",
|
||||||
|
"@ai-sdk/provider-utils": "3.0.12"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"zod": "^3.25.76 || ^4.1.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
"packages/server/node_modules/@modelcontextprotocol/sdk": {
|
"packages/server/node_modules/@modelcontextprotocol/sdk": {
|
||||||
"version": "1.20.1",
|
"version": "1.20.1",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
|||||||
+8
-1
@@ -31,7 +31,14 @@
|
|||||||
"web": "npm run web --workspace=@getpaseo/app",
|
"web": "npm run web --workspace=@getpaseo/app",
|
||||||
"dev:desktop": "npm run dev --workspace=@getpaseo/desktop",
|
"dev:desktop": "npm run dev --workspace=@getpaseo/desktop",
|
||||||
"build:desktop": "npm run build --workspace=@getpaseo/desktop",
|
"build:desktop": "npm run build --workspace=@getpaseo/desktop",
|
||||||
"cli": "npx tsx packages/cli/src/index.js"
|
"cli": "npx tsx packages/cli/src/index.js",
|
||||||
|
"version:sync-internal": "node scripts/sync-workspace-versions.mjs",
|
||||||
|
"version:all:patch": "npm version patch --workspaces --include-workspace-root --no-git-tag-version && npm run version:sync-internal && npm install --package-lock-only",
|
||||||
|
"version:all:minor": "npm version minor --workspaces --include-workspace-root --no-git-tag-version && npm run version:sync-internal && npm install --package-lock-only",
|
||||||
|
"version:all:major": "npm version major --workspaces --include-workspace-root --no-git-tag-version && npm run version:sync-internal && npm install --package-lock-only",
|
||||||
|
"release:check": "npm run typecheck --workspace=@getpaseo/relay && npm run typecheck --workspace=@getpaseo/server && npm run typecheck --workspace=@getpaseo/cli && npm run build --workspace=@getpaseo/relay && npm run build --workspace=@getpaseo/server && npm run build --workspace=@getpaseo/cli && npm pack --dry-run --workspace=@getpaseo/relay && npm pack --dry-run --workspace=@getpaseo/server && npm pack --dry-run --workspace=@getpaseo/cli",
|
||||||
|
"release:publish:dry-run": "npm publish --dry-run --workspace=@getpaseo/relay --access public && npm publish --dry-run --workspace=@getpaseo/server --access public && npm publish --dry-run --workspace=@getpaseo/cli --access public",
|
||||||
|
"release:publish": "npm publish --workspace=@getpaseo/relay --access public && npm publish --workspace=@getpaseo/server --access public && npm publish --workspace=@getpaseo/cli --access public"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"concurrently": "^9.2.1",
|
"concurrently": "^9.2.1",
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
"name": "@getpaseo/app",
|
"name": "@getpaseo/app",
|
||||||
"main": "index.ts",
|
"main": "index.ts",
|
||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "expo start",
|
"start": "expo start",
|
||||||
"reset-project": "node ./scripts/reset-project.js",
|
"reset-project": "node ./scripts/reset-project.js",
|
||||||
@@ -29,6 +30,7 @@
|
|||||||
"@dnd-kit/utilities": "^3.2.2",
|
"@dnd-kit/utilities": "^3.2.2",
|
||||||
"@expo/vector-icons": "^15.0.2",
|
"@expo/vector-icons": "^15.0.2",
|
||||||
"@floating-ui/react-native": "^0.10.7",
|
"@floating-ui/react-native": "^0.10.7",
|
||||||
|
"@getpaseo/server": "0.1.0",
|
||||||
"@gorhom/bottom-sheet": "^5.2.6",
|
"@gorhom/bottom-sheet": "^5.2.6",
|
||||||
"@gorhom/portal": "^1.0.14",
|
"@gorhom/portal": "^1.0.14",
|
||||||
"@lezer/common": "^1.5.0",
|
"@lezer/common": "^1.5.0",
|
||||||
@@ -39,8 +41,8 @@
|
|||||||
"@lezer/json": "^1.0.3",
|
"@lezer/json": "^1.0.3",
|
||||||
"@lezer/markdown": "^1.6.2",
|
"@lezer/markdown": "^1.6.2",
|
||||||
"@lezer/python": "^1.1.18",
|
"@lezer/python": "^1.1.18",
|
||||||
"@getpaseo/server": "*",
|
|
||||||
"@react-native-async-storage/async-storage": "2.2.0",
|
"@react-native-async-storage/async-storage": "2.2.0",
|
||||||
|
"@react-native-masked-view/masked-view": "^0.3.2",
|
||||||
"@react-navigation/bottom-tabs": "^7.4.0",
|
"@react-navigation/bottom-tabs": "^7.4.0",
|
||||||
"@react-navigation/elements": "^2.6.3",
|
"@react-navigation/elements": "^2.6.3",
|
||||||
"@react-navigation/native": "^7.1.8",
|
"@react-navigation/native": "^7.1.8",
|
||||||
|
|||||||
@@ -53,6 +53,7 @@ import { ToolCallSheetProvider } from "./tool-call-sheet";
|
|||||||
import { createMarkdownStyles } from "@/styles/markdown-styles";
|
import { createMarkdownStyles } from "@/styles/markdown-styles";
|
||||||
import { MAX_CONTENT_WIDTH } from "@/constants/layout";
|
import { MAX_CONTENT_WIDTH } from "@/constants/layout";
|
||||||
import { isPerfLoggingEnabled, measurePayload, perfLog } from "@/utils/perf";
|
import { isPerfLoggingEnabled, measurePayload, perfLog } from "@/utils/perf";
|
||||||
|
import { getMarkdownListMarker } from "@/utils/markdown-list";
|
||||||
|
|
||||||
const isUserMessageItem = (item?: StreamItem) => item?.kind === "user_message";
|
const isUserMessageItem = (item?: StreamItem) => item?.kind === "user_message";
|
||||||
const isToolSequenceItem = (item?: StreamItem) =>
|
const isToolSequenceItem = (item?: StreamItem) =>
|
||||||
@@ -973,9 +974,7 @@ function PermissionRequestCard({
|
|||||||
parent: any,
|
parent: any,
|
||||||
styles: any
|
styles: any
|
||||||
) => {
|
) => {
|
||||||
const isOrdered = parent?.type === "ordered_list";
|
const { isOrdered, marker } = getMarkdownListMarker(node, parent);
|
||||||
const index = parent?.children?.indexOf(node) ?? 0;
|
|
||||||
const bullet = isOrdered ? `${index + 1}.` : "•";
|
|
||||||
const iconStyle = isOrdered
|
const iconStyle = isOrdered
|
||||||
? styles.ordered_list_icon
|
? styles.ordered_list_icon
|
||||||
: styles.bullet_list_icon;
|
: styles.bullet_list_icon;
|
||||||
@@ -985,7 +984,7 @@ function PermissionRequestCard({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<View key={node.key} style={[styles.list_item, { flexShrink: 0 }]}>
|
<View key={node.key} style={[styles.list_item, { flexShrink: 0 }]}>
|
||||||
<Text style={iconStyle}>{bullet}</Text>
|
<Text style={iconStyle}>{marker}</Text>
|
||||||
<Text
|
<Text
|
||||||
style={[contentStyle, { flex: 1, flexShrink: 1, minWidth: 0 }]}
|
style={[contentStyle, { flex: 1, flexShrink: 1, minWidth: 0 }]}
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { RefreshControl } from "react-native";
|
import { RefreshControl } from "react-native";
|
||||||
import { useCallback } from "react";
|
import { useCallback, useState } from "react";
|
||||||
import DraggableFlatList, {
|
import DraggableFlatList, {
|
||||||
type RenderItemParams,
|
type RenderItemParams,
|
||||||
} from "react-native-draggable-flatlist";
|
} from "react-native-draggable-flatlist";
|
||||||
@@ -28,6 +28,7 @@ export function DraggableList<T>({
|
|||||||
waitFor,
|
waitFor,
|
||||||
}: DraggableListProps<T>) {
|
}: DraggableListProps<T>) {
|
||||||
const { theme } = useUnistyles();
|
const { theme } = useUnistyles();
|
||||||
|
const [isDragging, setIsDragging] = useState(false);
|
||||||
|
|
||||||
// Pass the ref directly to DraggableFlatList - it handles the gesture coordination
|
// Pass the ref directly to DraggableFlatList - it handles the gesture coordination
|
||||||
// The ref may not have .current set yet, but that's okay - DraggableFlatList will
|
// The ref may not have .current set yet, but that's okay - DraggableFlatList will
|
||||||
@@ -50,11 +51,22 @@ export function DraggableList<T>({
|
|||||||
|
|
||||||
const handleDragEnd = useCallback(
|
const handleDragEnd = useCallback(
|
||||||
({ data: newData }: { data: T[] }) => {
|
({ data: newData }: { data: T[] }) => {
|
||||||
|
setIsDragging(false);
|
||||||
onDragEnd(newData);
|
onDragEnd(newData);
|
||||||
},
|
},
|
||||||
[onDragEnd]
|
[onDragEnd]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const handleDragBegin = useCallback(() => {
|
||||||
|
setIsDragging(true);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const handleRelease = useCallback(() => {
|
||||||
|
setIsDragging(false);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const showRefreshControl = Boolean(onRefresh) && (!isDragging || Boolean(refreshing));
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<DraggableFlatList
|
<DraggableFlatList
|
||||||
data={data}
|
data={data}
|
||||||
@@ -71,10 +83,12 @@ export function DraggableList<T>({
|
|||||||
simultaneousHandlers={simultaneousHandlers}
|
simultaneousHandlers={simultaneousHandlers}
|
||||||
// Higher activationDistance prevents drag from interfering with nested onLongPress handlers
|
// Higher activationDistance prevents drag from interfering with nested onLongPress handlers
|
||||||
activationDistance={20}
|
activationDistance={20}
|
||||||
|
onDragBegin={handleDragBegin}
|
||||||
|
onRelease={handleRelease}
|
||||||
// @ts-expect-error - waitFor is supported by RNGH FlatList but not typed in DraggableFlatList
|
// @ts-expect-error - waitFor is supported by RNGH FlatList but not typed in DraggableFlatList
|
||||||
waitFor={waitFor}
|
waitFor={waitFor}
|
||||||
refreshControl={
|
refreshControl={
|
||||||
onRefresh ? (
|
showRefreshControl ? (
|
||||||
<RefreshControl
|
<RefreshControl
|
||||||
refreshing={refreshing ?? false}
|
refreshing={refreshing ?? false}
|
||||||
onRefresh={onRefresh}
|
onRefresh={onRefresh}
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import {
|
|||||||
Text,
|
Text,
|
||||||
Pressable,
|
Pressable,
|
||||||
ActivityIndicator,
|
ActivityIndicator,
|
||||||
LayoutChangeEvent,
|
type LayoutChangeEvent,
|
||||||
StyleProp,
|
StyleProp,
|
||||||
ViewStyle,
|
ViewStyle,
|
||||||
Platform,
|
Platform,
|
||||||
@@ -19,22 +19,9 @@ import {
|
|||||||
useContext,
|
useContext,
|
||||||
} from "react";
|
} from "react";
|
||||||
import type { ReactNode, ComponentType } from "react";
|
import type { ReactNode, ComponentType } from "react";
|
||||||
import Animated, {
|
|
||||||
useSharedValue,
|
|
||||||
useAnimatedStyle,
|
|
||||||
withRepeat,
|
|
||||||
withTiming,
|
|
||||||
Easing,
|
|
||||||
cancelAnimation,
|
|
||||||
} from "react-native-reanimated";
|
|
||||||
import Svg, {
|
|
||||||
Defs,
|
|
||||||
LinearGradient,
|
|
||||||
Stop,
|
|
||||||
Rect,
|
|
||||||
} from "react-native-svg";
|
|
||||||
import Markdown, { MarkdownIt } from "react-native-markdown-display";
|
import Markdown, { MarkdownIt } from "react-native-markdown-display";
|
||||||
import * as Linking from "expo-linking";
|
import * as Linking from "expo-linking";
|
||||||
|
import MaskedView from "@react-native-masked-view/masked-view";
|
||||||
import {
|
import {
|
||||||
Circle,
|
Circle,
|
||||||
Info,
|
Info,
|
||||||
@@ -55,6 +42,20 @@ import {
|
|||||||
useUnistyles,
|
useUnistyles,
|
||||||
UnistylesRuntime,
|
UnistylesRuntime,
|
||||||
} from "react-native-unistyles";
|
} from "react-native-unistyles";
|
||||||
|
import Animated, {
|
||||||
|
Easing,
|
||||||
|
cancelAnimation,
|
||||||
|
useAnimatedStyle,
|
||||||
|
useSharedValue,
|
||||||
|
withRepeat,
|
||||||
|
withTiming,
|
||||||
|
} from "react-native-reanimated";
|
||||||
|
import Svg, {
|
||||||
|
Defs,
|
||||||
|
LinearGradient as SvgLinearGradient,
|
||||||
|
Rect,
|
||||||
|
Stop,
|
||||||
|
} from "react-native-svg";
|
||||||
import { theme } from "@/styles/theme";
|
import { theme } from "@/styles/theme";
|
||||||
import {
|
import {
|
||||||
createMarkdownStyles,
|
createMarkdownStyles,
|
||||||
@@ -69,6 +70,7 @@ import {
|
|||||||
import { resolveToolCallIcon } from "@/utils/tool-call-icon";
|
import { resolveToolCallIcon } from "@/utils/tool-call-icon";
|
||||||
import { getNowMs, isPerfLoggingEnabled, perfLog } from "@/utils/perf";
|
import { getNowMs, isPerfLoggingEnabled, perfLog } from "@/utils/perf";
|
||||||
import { parseInlinePathToken, type InlinePathTarget } from "@/utils/inline-path";
|
import { parseInlinePathToken, type InlinePathTarget } from "@/utils/inline-path";
|
||||||
|
import { getMarkdownListMarker } from "@/utils/markdown-list";
|
||||||
export type { InlinePathTarget } from "@/utils/inline-path";
|
export type { InlinePathTarget } from "@/utils/inline-path";
|
||||||
import { useToolCallSheet } from "./tool-call-sheet";
|
import { useToolCallSheet } from "./tool-call-sheet";
|
||||||
import { ToolCallDetailsContent } from "./tool-call-details";
|
import { ToolCallDetailsContent } from "./tool-call-details";
|
||||||
@@ -102,6 +104,45 @@ function useDisableOuterSpacing(disableOuterSpacing: boolean | undefined) {
|
|||||||
return disableOuterSpacing ?? contextValue;
|
return disableOuterSpacing ?? contextValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const WEB_TOOLCALL_SHIMMER_KEYFRAME_ID = "paseo-toolcall-shimmer-keyframes";
|
||||||
|
const WEB_TOOLCALL_SHIMMER_ANIMATION_NAME = "paseo-toolcall-shimmer";
|
||||||
|
const WEB_TOOLCALL_SHIMMER_KEYFRAME_CSS = `
|
||||||
|
@keyframes ${WEB_TOOLCALL_SHIMMER_ANIMATION_NAME} {
|
||||||
|
0% {
|
||||||
|
background-position: var(--paseo-shimmer-start, -200px) 0;
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
background-position: var(--paseo-shimmer-end, 200px) 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
let webToolCallShimmerRegistered = false;
|
||||||
|
|
||||||
|
function ensureWebToolCallShimmerKeyframes() {
|
||||||
|
if (Platform.OS !== "web") {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (typeof document === "undefined") {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const existing = document.getElementById(WEB_TOOLCALL_SHIMMER_KEYFRAME_ID);
|
||||||
|
if (existing) {
|
||||||
|
if (existing.textContent !== WEB_TOOLCALL_SHIMMER_KEYFRAME_CSS) {
|
||||||
|
existing.textContent = WEB_TOOLCALL_SHIMMER_KEYFRAME_CSS;
|
||||||
|
}
|
||||||
|
webToolCallShimmerRegistered = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (webToolCallShimmerRegistered) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const styleElement = document.createElement("style");
|
||||||
|
styleElement.id = WEB_TOOLCALL_SHIMMER_KEYFRAME_ID;
|
||||||
|
styleElement.textContent = WEB_TOOLCALL_SHIMMER_KEYFRAME_CSS;
|
||||||
|
document.head.appendChild(styleElement);
|
||||||
|
webToolCallShimmerRegistered = true;
|
||||||
|
}
|
||||||
|
|
||||||
const userMessageStylesheet = StyleSheet.create((theme) => ({
|
const userMessageStylesheet = StyleSheet.create((theme) => ({
|
||||||
container: {
|
container: {
|
||||||
flexDirection: "row",
|
flexDirection: "row",
|
||||||
@@ -381,6 +422,10 @@ const expandableBadgeStylesheet = StyleSheet.create((theme) => ({
|
|||||||
fontWeight: theme.fontWeight.normal,
|
fontWeight: theme.fontWeight.normal,
|
||||||
flexShrink: 0,
|
flexShrink: 0,
|
||||||
},
|
},
|
||||||
|
labelLoading: {
|
||||||
|
color: theme.colors.foreground,
|
||||||
|
opacity: 0.72,
|
||||||
|
},
|
||||||
secondaryLabel: {
|
secondaryLabel: {
|
||||||
flex: 1,
|
flex: 1,
|
||||||
color: theme.colors.foregroundMuted,
|
color: theme.colors.foregroundMuted,
|
||||||
@@ -388,6 +433,12 @@ const expandableBadgeStylesheet = StyleSheet.create((theme) => ({
|
|||||||
fontWeight: theme.fontWeight.normal,
|
fontWeight: theme.fontWeight.normal,
|
||||||
marginLeft: theme.spacing[2],
|
marginLeft: theme.spacing[2],
|
||||||
},
|
},
|
||||||
|
shimmerText: {
|
||||||
|
color: "transparent",
|
||||||
|
fontSize: theme.fontSize.base,
|
||||||
|
fontWeight: theme.fontWeight.normal,
|
||||||
|
flexShrink: 1,
|
||||||
|
},
|
||||||
spacer: {
|
spacer: {
|
||||||
flex: 1,
|
flex: 1,
|
||||||
},
|
},
|
||||||
@@ -414,7 +465,32 @@ const expandableBadgeStylesheet = StyleSheet.create((theme) => ({
|
|||||||
shimmerOverlay: {
|
shimmerOverlay: {
|
||||||
position: "absolute",
|
position: "absolute",
|
||||||
top: 0,
|
top: 0,
|
||||||
|
right: 0,
|
||||||
bottom: 0,
|
bottom: 0,
|
||||||
|
left: 0,
|
||||||
|
flexDirection: "row",
|
||||||
|
alignItems: "center",
|
||||||
|
overflow: "hidden",
|
||||||
|
},
|
||||||
|
shimmerMaskRow: {
|
||||||
|
flexDirection: "row",
|
||||||
|
alignItems: "center",
|
||||||
|
width: "100%",
|
||||||
|
height: "100%",
|
||||||
|
},
|
||||||
|
nativeShimmerTrack: {
|
||||||
|
position: "absolute",
|
||||||
|
top: 0,
|
||||||
|
right: 0,
|
||||||
|
bottom: 0,
|
||||||
|
left: 0,
|
||||||
|
overflow: "hidden",
|
||||||
|
},
|
||||||
|
nativeShimmerPeak: {
|
||||||
|
position: "absolute",
|
||||||
|
top: 0,
|
||||||
|
bottom: 0,
|
||||||
|
left: 0,
|
||||||
},
|
},
|
||||||
}));
|
}));
|
||||||
|
|
||||||
@@ -562,9 +638,7 @@ export const AssistantMessage = memo(function AssistantMessage({
|
|||||||
parent: any,
|
parent: any,
|
||||||
styles: any
|
styles: any
|
||||||
) => {
|
) => {
|
||||||
const isOrdered = parent?.type === "ordered_list";
|
const { isOrdered, marker } = getMarkdownListMarker(node, parent);
|
||||||
const index = parent?.children?.indexOf(node) ?? 0;
|
|
||||||
const bullet = isOrdered ? `${index + 1}.` : "•";
|
|
||||||
const iconStyle = isOrdered
|
const iconStyle = isOrdered
|
||||||
? styles.ordered_list_icon
|
? styles.ordered_list_icon
|
||||||
: styles.bullet_list_icon;
|
: styles.bullet_list_icon;
|
||||||
@@ -574,7 +648,7 @@ export const AssistantMessage = memo(function AssistantMessage({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<View key={node.key} style={styles.list_item}>
|
<View key={node.key} style={styles.list_item}>
|
||||||
<Text style={iconStyle}>{bullet}</Text>
|
<Text style={iconStyle}>{marker}</Text>
|
||||||
<View
|
<View
|
||||||
style={[contentStyle, { flex: 1, flexShrink: 1, minWidth: 0 }]}
|
style={[contentStyle, { flex: 1, flexShrink: 1, minWidth: 0 }]}
|
||||||
>
|
>
|
||||||
@@ -997,41 +1071,167 @@ const ExpandableBadge = memo(function ExpandableBadge({
|
|||||||
const { theme } = useUnistyles();
|
const { theme } = useUnistyles();
|
||||||
const resolvedDisableOuterSpacing =
|
const resolvedDisableOuterSpacing =
|
||||||
useDisableOuterSpacing(disableOuterSpacing);
|
useDisableOuterSpacing(disableOuterSpacing);
|
||||||
const hasDetails = Boolean(renderDetails);
|
const isInteractive = Boolean(onToggle);
|
||||||
const detailContent = hasDetails && isExpanded ? renderDetails?.() : null;
|
const hasDetailContent = Boolean(renderDetails);
|
||||||
|
const detailContent =
|
||||||
|
hasDetailContent && isExpanded ? renderDetails?.() : null;
|
||||||
|
|
||||||
const [badgeWidth, setBadgeWidth] = useState(0);
|
const nativeGradientIdRef = useRef(
|
||||||
const handleLayout = useCallback((e: LayoutChangeEvent) => {
|
`shimmer-gradient-${Math.random().toString(36).substring(2, 9)}`
|
||||||
setBadgeWidth(e.nativeEvent.layout.width);
|
);
|
||||||
}, []);
|
const [labelRowWidth, setLabelRowWidth] = useState(0);
|
||||||
|
const [labelRowHeight, setLabelRowHeight] = useState(0);
|
||||||
|
const [labelOffsetX, setLabelOffsetX] = useState(0);
|
||||||
|
const [labelWidth, setLabelWidth] = useState(0);
|
||||||
|
const [secondaryOffsetX, setSecondaryOffsetX] = useState(0);
|
||||||
|
const [secondaryWidth, setSecondaryWidth] = useState(0);
|
||||||
|
const shimmerTranslateX = useSharedValue(0);
|
||||||
|
|
||||||
const shimmer = useSharedValue(-1);
|
const totalShimmerChars =
|
||||||
|
label.trim().length + (secondaryLabel?.trim().length ?? 0);
|
||||||
|
const shortTextDurationAdjustment = totalShimmerChars <= 12 ? 0.25 : 0;
|
||||||
|
const shimmerDuration = Math.max(
|
||||||
|
1,
|
||||||
|
Math.min(2.3, 1.25 + totalShimmerChars * 0.008 - shortTextDurationAdjustment)
|
||||||
|
);
|
||||||
|
const nativeShimmerPeakWidth = Math.max(
|
||||||
|
32,
|
||||||
|
Math.min(120, labelRowWidth > 0 ? labelRowWidth * 0.28 : 0)
|
||||||
|
);
|
||||||
|
const isWebShimmer = isLoading && Platform.OS === "web";
|
||||||
|
const shouldMeasureWebShimmer = isWebShimmer;
|
||||||
|
const shouldMeasureNativeShimmer = isLoading && Platform.OS !== "web";
|
||||||
|
const isNativeShimmer =
|
||||||
|
shouldMeasureNativeShimmer &&
|
||||||
|
labelRowWidth > 0 &&
|
||||||
|
labelRowHeight > 0;
|
||||||
|
const webShimmerSpanStartX = labelOffsetX;
|
||||||
|
const webShimmerSpanEndX = secondaryLabel
|
||||||
|
? secondaryOffsetX + secondaryWidth
|
||||||
|
: labelOffsetX + labelWidth;
|
||||||
|
const webShimmerSpanWidth = Math.max(
|
||||||
|
1,
|
||||||
|
webShimmerSpanEndX - webShimmerSpanStartX
|
||||||
|
);
|
||||||
|
const webShimmerPeakWidth = Math.max(
|
||||||
|
42,
|
||||||
|
Math.min(120, webShimmerSpanWidth * 0.22)
|
||||||
|
);
|
||||||
|
const webShimmerTrackStart = webShimmerSpanStartX - webShimmerPeakWidth;
|
||||||
|
const webShimmerTrackEnd = webShimmerSpanEndX;
|
||||||
|
|
||||||
|
const handleLabelRowLayout = useCallback((event: LayoutChangeEvent) => {
|
||||||
|
if (!shouldMeasureNativeShimmer) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const { width, height } = event.nativeEvent.layout;
|
||||||
|
setLabelRowWidth((previous) =>
|
||||||
|
Math.abs(previous - width) > 0.5 ? width : previous
|
||||||
|
);
|
||||||
|
setLabelRowHeight((previous) =>
|
||||||
|
Math.abs(previous - height) > 0.5 ? height : previous
|
||||||
|
);
|
||||||
|
}, [shouldMeasureNativeShimmer]);
|
||||||
|
|
||||||
|
const handleLabelLayout = useCallback((event: LayoutChangeEvent) => {
|
||||||
|
if (!shouldMeasureWebShimmer) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const { x, width } = event.nativeEvent.layout;
|
||||||
|
setLabelOffsetX((previous) =>
|
||||||
|
Math.abs(previous - x) > 0.5 ? x : previous
|
||||||
|
);
|
||||||
|
setLabelWidth((previous) =>
|
||||||
|
Math.abs(previous - width) > 0.5 ? width : previous
|
||||||
|
);
|
||||||
|
}, [shouldMeasureWebShimmer]);
|
||||||
|
|
||||||
|
const handleSecondaryLayout = useCallback((event: LayoutChangeEvent) => {
|
||||||
|
if (!shouldMeasureWebShimmer || !secondaryLabel) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const { x, width } = event.nativeEvent.layout;
|
||||||
|
setSecondaryOffsetX((previous) =>
|
||||||
|
Math.abs(previous - x) > 0.5 ? x : previous
|
||||||
|
);
|
||||||
|
setSecondaryWidth((previous) =>
|
||||||
|
Math.abs(previous - width) > 0.5 ? width : previous
|
||||||
|
);
|
||||||
|
}, [shouldMeasureWebShimmer, secondaryLabel]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (isLoading) {
|
if (!isWebShimmer) {
|
||||||
shimmer.value = -1;
|
return;
|
||||||
shimmer.value = withRepeat(
|
|
||||||
withTiming(1, { duration: 2400, easing: Easing.bezier(0.4, 0, 0.6, 1) }),
|
|
||||||
-1
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
cancelAnimation(shimmer);
|
|
||||||
shimmer.value = -1;
|
|
||||||
}
|
}
|
||||||
}, [isLoading]);
|
ensureWebToolCallShimmerKeyframes();
|
||||||
|
}, [isWebShimmer]);
|
||||||
|
|
||||||
const shimmerBandWidth = 18;
|
useEffect(() => {
|
||||||
const shimmerStyle = useAnimatedStyle(() => {
|
if (!isNativeShimmer) {
|
||||||
const travel = badgeWidth + shimmerBandWidth;
|
cancelAnimation(shimmerTranslateX);
|
||||||
return {
|
shimmerTranslateX.value = -nativeShimmerPeakWidth;
|
||||||
transform: [
|
return;
|
||||||
{
|
}
|
||||||
translateX:
|
const startPosition = -nativeShimmerPeakWidth;
|
||||||
-shimmerBandWidth + ((shimmer.value + 1) / 2) * travel,
|
const endPosition = labelRowWidth + nativeShimmerPeakWidth;
|
||||||
},
|
shimmerTranslateX.value = startPosition;
|
||||||
],
|
shimmerTranslateX.value = withRepeat(
|
||||||
|
withTiming(endPosition, {
|
||||||
|
duration: shimmerDuration * 1000,
|
||||||
|
easing: Easing.linear,
|
||||||
|
}),
|
||||||
|
-1,
|
||||||
|
false
|
||||||
|
);
|
||||||
|
return () => {
|
||||||
|
cancelAnimation(shimmerTranslateX);
|
||||||
};
|
};
|
||||||
});
|
}, [
|
||||||
|
isNativeShimmer,
|
||||||
|
labelRowWidth,
|
||||||
|
nativeShimmerPeakWidth,
|
||||||
|
shimmerDuration,
|
||||||
|
shimmerTranslateX,
|
||||||
|
]);
|
||||||
|
|
||||||
|
const nativeShimmerPeakStyle = useAnimatedStyle(() => ({
|
||||||
|
transform: [{ translateX: shimmerTranslateX.value }],
|
||||||
|
}));
|
||||||
|
|
||||||
|
const shimmerGradient =
|
||||||
|
"linear-gradient(90deg, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.45) 24%, #ffffff 40%, #ffffff 60%, rgba(255, 255, 255, 0.45) 76%, rgba(255, 255, 255, 0) 100%)";
|
||||||
|
|
||||||
|
const shimmerLabelStyle = isWebShimmer
|
||||||
|
? ({
|
||||||
|
opacity: 1,
|
||||||
|
color: "transparent",
|
||||||
|
backgroundImage: shimmerGradient,
|
||||||
|
backgroundSize: `${webShimmerPeakWidth}px 100%`,
|
||||||
|
backgroundRepeat: "no-repeat",
|
||||||
|
backgroundClip: "text",
|
||||||
|
WebkitBackgroundClip: "text",
|
||||||
|
WebkitTextFillColor: "transparent",
|
||||||
|
animation: `${WEB_TOOLCALL_SHIMMER_ANIMATION_NAME} ${shimmerDuration}s linear infinite`,
|
||||||
|
"--paseo-shimmer-start": `${webShimmerTrackStart - labelOffsetX}px`,
|
||||||
|
"--paseo-shimmer-end": `${webShimmerTrackEnd - labelOffsetX}px`,
|
||||||
|
} as never)
|
||||||
|
: null;
|
||||||
|
|
||||||
|
const shimmerSecondaryStyle = isWebShimmer
|
||||||
|
? ({
|
||||||
|
opacity: 1,
|
||||||
|
color: "transparent",
|
||||||
|
backgroundImage: shimmerGradient,
|
||||||
|
backgroundSize: `${webShimmerPeakWidth}px 100%`,
|
||||||
|
backgroundRepeat: "no-repeat",
|
||||||
|
backgroundClip: "text",
|
||||||
|
WebkitBackgroundClip: "text",
|
||||||
|
WebkitTextFillColor: "transparent",
|
||||||
|
animation: `${WEB_TOOLCALL_SHIMMER_ANIMATION_NAME} ${shimmerDuration}s linear infinite`,
|
||||||
|
"--paseo-shimmer-start": `${webShimmerTrackStart - secondaryOffsetX}px`,
|
||||||
|
"--paseo-shimmer-end": `${webShimmerTrackEnd - secondaryOffsetX}px`,
|
||||||
|
} as never)
|
||||||
|
: null;
|
||||||
|
|
||||||
const IconComponent = icon;
|
const IconComponent = icon;
|
||||||
const iconColor = isError
|
const iconColor = isError
|
||||||
@@ -1058,14 +1258,13 @@ const ExpandableBadge = memo(function ExpandableBadge({
|
|||||||
testID={testID}
|
testID={testID}
|
||||||
>
|
>
|
||||||
<Pressable
|
<Pressable
|
||||||
onPress={hasDetails ? onToggle : undefined}
|
onPress={isInteractive ? onToggle : undefined}
|
||||||
onLayout={handleLayout}
|
disabled={!isInteractive}
|
||||||
disabled={!hasDetails}
|
accessibilityRole={isInteractive ? "button" : undefined}
|
||||||
accessibilityRole={hasDetails ? "button" : undefined}
|
accessibilityState={isInteractive ? { expanded: isExpanded } : undefined}
|
||||||
accessibilityState={hasDetails ? { expanded: isExpanded } : undefined}
|
|
||||||
style={({ pressed }) => [
|
style={({ pressed }) => [
|
||||||
expandableBadgeStylesheet.pressable,
|
expandableBadgeStylesheet.pressable,
|
||||||
pressed && hasDetails
|
pressed && isInteractive
|
||||||
? expandableBadgeStylesheet.pressablePressed
|
? expandableBadgeStylesheet.pressablePressed
|
||||||
: null,
|
: null,
|
||||||
isExpanded && expandableBadgeStylesheet.pressableExpanded,
|
isExpanded && expandableBadgeStylesheet.pressableExpanded,
|
||||||
@@ -1075,53 +1274,147 @@ const ExpandableBadge = memo(function ExpandableBadge({
|
|||||||
<>
|
<>
|
||||||
<View style={expandableBadgeStylesheet.headerRow}>
|
<View style={expandableBadgeStylesheet.headerRow}>
|
||||||
<View style={expandableBadgeStylesheet.iconBadge}>{iconNode}</View>
|
<View style={expandableBadgeStylesheet.iconBadge}>{iconNode}</View>
|
||||||
<View style={expandableBadgeStylesheet.labelRow}>
|
<View
|
||||||
<Text style={expandableBadgeStylesheet.label} numberOfLines={1}>
|
style={expandableBadgeStylesheet.labelRow}
|
||||||
|
onLayout={shouldMeasureNativeShimmer ? handleLabelRowLayout : undefined}
|
||||||
|
>
|
||||||
|
<Text
|
||||||
|
style={[
|
||||||
|
expandableBadgeStylesheet.label,
|
||||||
|
isLoading && expandableBadgeStylesheet.labelLoading,
|
||||||
|
]}
|
||||||
|
numberOfLines={1}
|
||||||
|
onLayout={shouldMeasureWebShimmer ? handleLabelLayout : undefined}
|
||||||
|
>
|
||||||
{label}
|
{label}
|
||||||
</Text>
|
</Text>
|
||||||
{secondaryLabel ? (
|
{secondaryLabel ? (
|
||||||
<Text
|
<Text
|
||||||
style={expandableBadgeStylesheet.secondaryLabel}
|
style={expandableBadgeStylesheet.secondaryLabel}
|
||||||
numberOfLines={1}
|
numberOfLines={1}
|
||||||
|
onLayout={shouldMeasureWebShimmer ? handleSecondaryLayout : undefined}
|
||||||
>
|
>
|
||||||
{secondaryLabel}
|
{secondaryLabel}
|
||||||
</Text>
|
</Text>
|
||||||
) : (
|
) : (
|
||||||
<View style={expandableBadgeStylesheet.spacer} />
|
<View style={expandableBadgeStylesheet.spacer} />
|
||||||
)}
|
)}
|
||||||
{isLoading && badgeWidth > 0 ? (
|
{isWebShimmer ? (
|
||||||
<Animated.View
|
<View
|
||||||
|
style={expandableBadgeStylesheet.shimmerOverlay}
|
||||||
pointerEvents="none"
|
pointerEvents="none"
|
||||||
style={[
|
|
||||||
expandableBadgeStylesheet.shimmerOverlay,
|
|
||||||
{ width: shimmerBandWidth },
|
|
||||||
shimmerStyle,
|
|
||||||
]}
|
|
||||||
>
|
>
|
||||||
<Svg width="100%" height="100%" preserveAspectRatio="none">
|
<Text
|
||||||
<Defs>
|
style={[
|
||||||
<LinearGradient
|
expandableBadgeStylesheet.label,
|
||||||
id="shimmerGrad"
|
isLoading && expandableBadgeStylesheet.labelLoading,
|
||||||
x1="0"
|
expandableBadgeStylesheet.shimmerText,
|
||||||
y1="0"
|
shimmerLabelStyle,
|
||||||
x2="1"
|
]}
|
||||||
y2="0"
|
numberOfLines={1}
|
||||||
|
>
|
||||||
|
{label}
|
||||||
|
</Text>
|
||||||
|
{secondaryLabel ? (
|
||||||
|
<Text
|
||||||
|
style={[
|
||||||
|
expandableBadgeStylesheet.secondaryLabel,
|
||||||
|
expandableBadgeStylesheet.shimmerText,
|
||||||
|
shimmerSecondaryStyle,
|
||||||
|
]}
|
||||||
|
numberOfLines={1}
|
||||||
|
>
|
||||||
|
{secondaryLabel}
|
||||||
|
</Text>
|
||||||
|
) : (
|
||||||
|
<View style={expandableBadgeStylesheet.spacer} />
|
||||||
|
)}
|
||||||
|
</View>
|
||||||
|
) : null}
|
||||||
|
{isNativeShimmer ? (
|
||||||
|
<View
|
||||||
|
style={expandableBadgeStylesheet.shimmerOverlay}
|
||||||
|
pointerEvents="none"
|
||||||
|
>
|
||||||
|
<MaskedView
|
||||||
|
style={[
|
||||||
|
expandableBadgeStylesheet.nativeShimmerTrack,
|
||||||
|
{ width: labelRowWidth, height: labelRowHeight },
|
||||||
|
]}
|
||||||
|
maskElement={
|
||||||
|
<View
|
||||||
|
style={[
|
||||||
|
expandableBadgeStylesheet.shimmerMaskRow,
|
||||||
|
{ width: labelRowWidth, height: labelRowHeight },
|
||||||
|
]}
|
||||||
>
|
>
|
||||||
<Stop offset="0" stopColor={theme.colors.surface1} stopOpacity="0" />
|
<Text
|
||||||
<Stop offset="0.42" stopColor={theme.colors.surface1} stopOpacity="0" />
|
style={[
|
||||||
<Stop offset="0.48" stopColor={theme.colors.surface1} stopOpacity="0.35" />
|
expandableBadgeStylesheet.label,
|
||||||
<Stop offset="0.5" stopColor={theme.colors.surface1} stopOpacity="1" />
|
{ color: "#000000", opacity: 1 },
|
||||||
<Stop offset="0.52" stopColor={theme.colors.surface1} stopOpacity="0.35" />
|
]}
|
||||||
<Stop offset="0.58" stopColor={theme.colors.surface1} stopOpacity="0" />
|
numberOfLines={1}
|
||||||
<Stop offset="1" stopColor={theme.colors.surface1} stopOpacity="0" />
|
>
|
||||||
</LinearGradient>
|
{label}
|
||||||
</Defs>
|
</Text>
|
||||||
<Rect width="100%" height="100%" fill="url(#shimmerGrad)" />
|
{secondaryLabel ? (
|
||||||
</Svg>
|
<Text
|
||||||
</Animated.View>
|
style={[
|
||||||
|
expandableBadgeStylesheet.secondaryLabel,
|
||||||
|
{ color: "#000000", opacity: 1 },
|
||||||
|
]}
|
||||||
|
numberOfLines={1}
|
||||||
|
>
|
||||||
|
{secondaryLabel}
|
||||||
|
</Text>
|
||||||
|
) : (
|
||||||
|
<View style={expandableBadgeStylesheet.spacer} />
|
||||||
|
)}
|
||||||
|
</View>
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<View
|
||||||
|
style={[
|
||||||
|
expandableBadgeStylesheet.nativeShimmerTrack,
|
||||||
|
{ width: labelRowWidth, height: labelRowHeight },
|
||||||
|
]}
|
||||||
|
>
|
||||||
|
<Animated.View
|
||||||
|
style={[
|
||||||
|
expandableBadgeStylesheet.nativeShimmerPeak,
|
||||||
|
nativeShimmerPeakStyle,
|
||||||
|
{ width: nativeShimmerPeakWidth, height: labelRowHeight },
|
||||||
|
]}
|
||||||
|
>
|
||||||
|
<Svg width="100%" height="100%" preserveAspectRatio="none">
|
||||||
|
<Defs>
|
||||||
|
<SvgLinearGradient
|
||||||
|
id={nativeGradientIdRef.current}
|
||||||
|
x1="0%"
|
||||||
|
y1="0%"
|
||||||
|
x2="100%"
|
||||||
|
y2="0%"
|
||||||
|
>
|
||||||
|
<Stop offset="0%" stopColor="#ffffff" stopOpacity={0} />
|
||||||
|
<Stop offset="50%" stopColor="#ffffff" stopOpacity={1} />
|
||||||
|
<Stop offset="100%" stopColor="#ffffff" stopOpacity={0} />
|
||||||
|
</SvgLinearGradient>
|
||||||
|
</Defs>
|
||||||
|
<Rect
|
||||||
|
x="0"
|
||||||
|
y="0"
|
||||||
|
width="100%"
|
||||||
|
height="100%"
|
||||||
|
fill={`url(#${nativeGradientIdRef.current})`}
|
||||||
|
/>
|
||||||
|
</Svg>
|
||||||
|
</Animated.View>
|
||||||
|
</View>
|
||||||
|
</MaskedView>
|
||||||
|
</View>
|
||||||
) : null}
|
) : null}
|
||||||
</View>
|
</View>
|
||||||
{hasDetails && hovered ? (
|
{isInteractive && hovered ? (
|
||||||
<ChevronRight
|
<ChevronRight
|
||||||
size={14}
|
size={14}
|
||||||
color={theme.colors.foregroundMuted}
|
color={theme.colors.foregroundMuted}
|
||||||
@@ -1146,7 +1439,28 @@ const ExpandableBadge = memo(function ExpandableBadge({
|
|||||||
) : null}
|
) : null}
|
||||||
</View>
|
</View>
|
||||||
);
|
);
|
||||||
});
|
}, areExpandableBadgePropsEqual);
|
||||||
|
|
||||||
|
function areExpandableBadgePropsEqual(
|
||||||
|
previous: ExpandableBadgeProps,
|
||||||
|
next: ExpandableBadgeProps
|
||||||
|
) {
|
||||||
|
if (previous.label !== next.label) return false;
|
||||||
|
if (previous.secondaryLabel !== next.secondaryLabel) return false;
|
||||||
|
if (previous.icon !== next.icon) return false;
|
||||||
|
if (previous.isExpanded !== next.isExpanded) return false;
|
||||||
|
if (previous.style !== next.style) return false;
|
||||||
|
if (previous.isLoading !== next.isLoading) return false;
|
||||||
|
if (previous.isError !== next.isError) return false;
|
||||||
|
if (previous.isLastInSequence !== next.isLastInSequence) return false;
|
||||||
|
if (previous.disableOuterSpacing !== next.disableOuterSpacing) return false;
|
||||||
|
if (previous.testID !== next.testID) return false;
|
||||||
|
if (Boolean(previous.onToggle) !== Boolean(next.onToggle)) return false;
|
||||||
|
if (previous.isExpanded && previous.renderDetails !== next.renderDetails) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
interface ToolCallProps {
|
interface ToolCallProps {
|
||||||
toolName: string;
|
toolName: string;
|
||||||
@@ -1329,18 +1643,26 @@ export const ToolCall = memo(function ToolCall({
|
|||||||
icon={IconComponent}
|
icon={IconComponent}
|
||||||
isExpanded={!isMobile && isExpanded}
|
isExpanded={!isMobile && isExpanded}
|
||||||
onToggle={hasDetails ? handleToggle : undefined}
|
onToggle={hasDetails ? handleToggle : undefined}
|
||||||
renderDetails={
|
renderDetails={hasDetails && !isMobile ? renderDetails : undefined}
|
||||||
hasDetails && !isMobile
|
isLoading={status === "running" || status === "executing"}
|
||||||
? renderDetails
|
|
||||||
: hasDetails
|
|
||||||
? () => null
|
|
||||||
: undefined
|
|
||||||
}
|
|
||||||
isLoading={status === "executing" || status === "running"}
|
|
||||||
isError={status === "failed"}
|
isError={status === "failed"}
|
||||||
isLastInSequence={isLastInSequence}
|
isLastInSequence={isLastInSequence}
|
||||||
disableOuterSpacing={disableOuterSpacing}
|
disableOuterSpacing={disableOuterSpacing}
|
||||||
onDetailHoverChange={onInlineDetailsHoverChange}
|
onDetailHoverChange={onInlineDetailsHoverChange}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
});
|
}, areToolCallPropsEqual);
|
||||||
|
|
||||||
|
function areToolCallPropsEqual(previous: ToolCallProps, next: ToolCallProps) {
|
||||||
|
if (previous.toolName !== next.toolName) return false;
|
||||||
|
if (previous.args !== next.args) return false;
|
||||||
|
if (previous.result !== next.result) return false;
|
||||||
|
if (previous.error !== next.error) return false;
|
||||||
|
if (previous.status !== next.status) return false;
|
||||||
|
if (previous.detail !== next.detail) return false;
|
||||||
|
if (previous.cwd !== next.cwd) return false;
|
||||||
|
if (previous.metadata !== next.metadata) return false;
|
||||||
|
if (previous.isLastInSequence !== next.isLastInSequence) return false;
|
||||||
|
if (previous.disableOuterSpacing !== next.disableOuterSpacing) return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|||||||
@@ -125,8 +125,8 @@ export function SlidingSidebar({ selectedAgentId }: SlidingSidebarProps) {
|
|||||||
if (isMobile) {
|
if (isMobile) {
|
||||||
translateX.value = -windowWidth;
|
translateX.value = -windowWidth;
|
||||||
backdropOpacity.value = 0;
|
backdropOpacity.value = 0;
|
||||||
|
closeToAgent();
|
||||||
}
|
}
|
||||||
closeToAgent();
|
|
||||||
router.push("/agents");
|
router.push("/agents");
|
||||||
}, [backdropOpacity, closeToAgent, isMobile, translateX, windowWidth]);
|
}, [backdropOpacity, closeToAgent, isMobile, translateX, windowWidth]);
|
||||||
|
|
||||||
|
|||||||
@@ -254,7 +254,7 @@ export function createMarkdownStyles(theme: Theme) {
|
|||||||
color: theme.colors.foregroundMuted,
|
color: theme.colors.foregroundMuted,
|
||||||
marginRight: 4,
|
marginRight: 4,
|
||||||
fontSize: theme.fontSize.base,
|
fontSize: theme.fontSize.base,
|
||||||
fontWeight: theme.fontWeight.semibold,
|
fontWeight: theme.fontWeight.normal,
|
||||||
lineHeight: 22,
|
lineHeight: 22,
|
||||||
minWidth: 12,
|
minWidth: 12,
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -0,0 +1,52 @@
|
|||||||
|
import { describe, expect, it } from "vitest";
|
||||||
|
import { getMarkdownListMarker } from "./markdown-list";
|
||||||
|
|
||||||
|
describe("getMarkdownListMarker", () => {
|
||||||
|
it("returns a bullet marker for unordered list items", () => {
|
||||||
|
expect(
|
||||||
|
getMarkdownListMarker(
|
||||||
|
{ index: 0 },
|
||||||
|
[{ type: "bullet_list" }]
|
||||||
|
)
|
||||||
|
).toEqual({
|
||||||
|
isOrdered: false,
|
||||||
|
marker: "•",
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it("returns numbered markers for ordered list items", () => {
|
||||||
|
expect(
|
||||||
|
getMarkdownListMarker(
|
||||||
|
{ index: 1, markup: "." },
|
||||||
|
[{ type: "ordered_list" }]
|
||||||
|
)
|
||||||
|
).toEqual({
|
||||||
|
isOrdered: true,
|
||||||
|
marker: "2.",
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it("respects ordered list start attribute", () => {
|
||||||
|
expect(
|
||||||
|
getMarkdownListMarker(
|
||||||
|
{ index: 2, markup: ")" },
|
||||||
|
[{ type: "ordered_list", attributes: { start: "5" } }]
|
||||||
|
)
|
||||||
|
).toEqual({
|
||||||
|
isOrdered: true,
|
||||||
|
marker: "7)",
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it("prefers the nearest list ancestor in nested lists", () => {
|
||||||
|
expect(
|
||||||
|
getMarkdownListMarker(
|
||||||
|
{ index: 0, markup: "." },
|
||||||
|
[{ type: "ordered_list" }, { type: "bullet_list" }]
|
||||||
|
)
|
||||||
|
).toEqual({
|
||||||
|
isOrdered: true,
|
||||||
|
marker: "1.",
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -0,0 +1,87 @@
|
|||||||
|
type MarkdownNode = {
|
||||||
|
type?: string;
|
||||||
|
index?: number;
|
||||||
|
markup?: string;
|
||||||
|
attributes?: {
|
||||||
|
start?: number | string;
|
||||||
|
};
|
||||||
|
children?: MarkdownNode[];
|
||||||
|
};
|
||||||
|
|
||||||
|
const LIST_BULLET = "•";
|
||||||
|
const DEFAULT_ORDERED_LIST_MARKUP = ".";
|
||||||
|
|
||||||
|
function toParentNodes(parent: unknown): MarkdownNode[] {
|
||||||
|
if (Array.isArray(parent)) {
|
||||||
|
return parent;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (parent && typeof parent === "object") {
|
||||||
|
return [parent as MarkdownNode];
|
||||||
|
}
|
||||||
|
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
function getNearestListParent(parent: unknown): MarkdownNode | undefined {
|
||||||
|
return toParentNodes(parent).find(
|
||||||
|
(ancestor) =>
|
||||||
|
ancestor?.type === "ordered_list" || ancestor?.type === "bullet_list"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getOrderedListItemIndex(node: MarkdownNode, listParent: MarkdownNode): number {
|
||||||
|
if (typeof node.index === "number" && Number.isFinite(node.index) && node.index >= 0) {
|
||||||
|
return node.index;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Array.isArray(listParent.children)) {
|
||||||
|
const fallbackIndex = listParent.children.indexOf(node);
|
||||||
|
if (fallbackIndex >= 0) {
|
||||||
|
return fallbackIndex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
function parseOrderedListStart(node: MarkdownNode): number {
|
||||||
|
const rawStart = node.attributes?.start;
|
||||||
|
if (typeof rawStart === "number" && Number.isFinite(rawStart)) {
|
||||||
|
return rawStart;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof rawStart === "string") {
|
||||||
|
const parsed = Number.parseInt(rawStart, 10);
|
||||||
|
if (Number.isFinite(parsed)) {
|
||||||
|
return parsed;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getMarkdownListMarker(node: MarkdownNode, parent: unknown): {
|
||||||
|
isOrdered: boolean;
|
||||||
|
marker: string;
|
||||||
|
} {
|
||||||
|
const listParent = getNearestListParent(parent);
|
||||||
|
if (!listParent || listParent.type !== "ordered_list") {
|
||||||
|
return {
|
||||||
|
isOrdered: false,
|
||||||
|
marker: LIST_BULLET,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const orderedIndex = getOrderedListItemIndex(node, listParent);
|
||||||
|
const orderedStart = parseOrderedListStart(listParent);
|
||||||
|
const orderedMarkup =
|
||||||
|
typeof node.markup === "string" && node.markup.length > 0
|
||||||
|
? node.markup
|
||||||
|
: DEFAULT_ORDERED_LIST_MARKUP;
|
||||||
|
|
||||||
|
return {
|
||||||
|
isOrdered: true,
|
||||||
|
marker: `${orderedStart + orderedIndex}${orderedMarkup}`,
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -7,23 +7,22 @@
|
|||||||
"bin",
|
"bin",
|
||||||
"dist"
|
"dist"
|
||||||
],
|
],
|
||||||
"bundleDependencies": [
|
"publishConfig": {
|
||||||
"@getpaseo/server",
|
"access": "public"
|
||||||
"@getpaseo/relay"
|
},
|
||||||
],
|
|
||||||
"bin": {
|
"bin": {
|
||||||
"paseo": "./bin/paseo"
|
"paseo": "bin/paseo"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "node -e \"require('node:fs').rmSync('dist',{ recursive: true, force: true })\" && tsc -p tsconfig.json --incremental false",
|
"build": "node -e \"require('node:fs').rmSync('dist',{ recursive: true, force: true })\" && tsc -p tsconfig.json --incremental false",
|
||||||
"prepack": "npm --prefix ../.. run build --workspace=@getpaseo/relay && npm --prefix ../.. run build --workspace=@getpaseo/server && npm run build && bash ./scripts/prepare-bundled-deps.sh",
|
"prepack": "npm run build",
|
||||||
"typecheck": "tsc --noEmit",
|
"typecheck": "tsc --noEmit",
|
||||||
"test:e2e": "npx zx tests/run-all.ts",
|
"test:e2e": "npx zx tests/run-all.ts",
|
||||||
"test:e2e:lifecycle": "npx tsx tests/e2e/agent-lifecycle.test.ts"
|
"test:e2e:lifecycle": "npx tsx tests/e2e/agent-lifecycle.test.ts"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@getpaseo/relay": "*",
|
"@getpaseo/relay": "0.1.0",
|
||||||
"@getpaseo/server": "*",
|
"@getpaseo/server": "0.1.0",
|
||||||
"chalk": "^5.3.0",
|
"chalk": "^5.3.0",
|
||||||
"commander": "^12.0.0",
|
"commander": "^12.0.0",
|
||||||
"mime-types": "^2.1.35",
|
"mime-types": "^2.1.35",
|
||||||
|
|||||||
@@ -1,32 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
set -euo pipefail
|
|
||||||
|
|
||||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
||||||
CLI_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
|
|
||||||
REPO_ROOT="$(cd "$CLI_DIR/../.." && pwd)"
|
|
||||||
TMP_DIR="$(mktemp -d "${TMPDIR:-/tmp}/paseo-bundle-XXXXXX")"
|
|
||||||
|
|
||||||
cleanup() {
|
|
||||||
rm -rf "$TMP_DIR"
|
|
||||||
}
|
|
||||||
trap cleanup EXIT
|
|
||||||
|
|
||||||
# Nested npm calls can inherit dry-run mode from a parent `npm pack --dry-run`.
|
|
||||||
# Force real pack/install here so bundled deps are materialized.
|
|
||||||
export npm_config_dry_run=false
|
|
||||||
|
|
||||||
npm --prefix "$REPO_ROOT" pack --silent --workspace=@getpaseo/relay --pack-destination "$TMP_DIR"
|
|
||||||
npm --prefix "$REPO_ROOT" pack --silent --workspace=@getpaseo/server --pack-destination "$TMP_DIR"
|
|
||||||
|
|
||||||
RELAY_TGZ="$(ls "$TMP_DIR"/getpaseo-relay-*.tgz | head -n 1)"
|
|
||||||
SERVER_TGZ="$(ls "$TMP_DIR"/getpaseo-server-*.tgz | head -n 1)"
|
|
||||||
|
|
||||||
mkdir -p "$CLI_DIR/node_modules/@getpaseo"
|
|
||||||
rm -rf "$CLI_DIR/node_modules/@getpaseo/relay" "$CLI_DIR/node_modules/@getpaseo/server"
|
|
||||||
|
|
||||||
npm --prefix "$CLI_DIR" install --no-save --no-package-lock --workspaces=false --silent "$RELAY_TGZ" "$SERVER_TGZ"
|
|
||||||
|
|
||||||
if [ -L "$CLI_DIR/node_modules/@getpaseo/relay" ] || [ -L "$CLI_DIR/node_modules/@getpaseo/server" ]; then
|
|
||||||
echo "Expected bundled @getpaseo deps to be real directories, not symlinks." >&2
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
@@ -1,9 +1,11 @@
|
|||||||
{
|
{
|
||||||
"name": "@getpaseo/relay",
|
"name": "@getpaseo/relay",
|
||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
"private": true,
|
|
||||||
"description": "Paseo relay for bridging daemon and client connections",
|
"description": "Paseo relay for bridging daemon and client connections",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
|
"publishConfig": {
|
||||||
|
"access": "public"
|
||||||
|
},
|
||||||
"types": "./dist/index.d.ts",
|
"types": "./dist/index.d.ts",
|
||||||
"files": [
|
"files": [
|
||||||
"dist"
|
"dist"
|
||||||
|
|||||||
@@ -1,9 +1,11 @@
|
|||||||
{
|
{
|
||||||
"name": "@getpaseo/server",
|
"name": "@getpaseo/server",
|
||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
"private": true,
|
|
||||||
"description": "Paseo backend server",
|
"description": "Paseo backend server",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
|
"publishConfig": {
|
||||||
|
"access": "public"
|
||||||
|
},
|
||||||
"types": "./dist/server/server/exports.d.ts",
|
"types": "./dist/server/server/exports.d.ts",
|
||||||
"files": [
|
"files": [
|
||||||
"dist/server",
|
"dist/server",
|
||||||
@@ -49,7 +51,8 @@
|
|||||||
"test:e2e:mobile": "playwright test --project='Mobile Chrome'"
|
"test:e2e:mobile": "playwright test --project='Mobile Chrome'"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@getpaseo/relay": "*",
|
"@anthropic-ai/claude-agent-sdk": "^0.2.11",
|
||||||
|
"@getpaseo/relay": "0.1.0",
|
||||||
"@ai-sdk/openai": "2.0.52",
|
"@ai-sdk/openai": "2.0.52",
|
||||||
"@deepgram/sdk": "^3.4.0",
|
"@deepgram/sdk": "^3.4.0",
|
||||||
"@lezer/common": "^1.5.0",
|
"@lezer/common": "^1.5.0",
|
||||||
|
|||||||
@@ -0,0 +1,73 @@
|
|||||||
|
import { existsSync, readFileSync, writeFileSync } from 'node:fs'
|
||||||
|
import path from 'node:path'
|
||||||
|
import { fileURLToPath } from 'node:url'
|
||||||
|
|
||||||
|
const __dirname = path.dirname(fileURLToPath(import.meta.url))
|
||||||
|
const rootDir = path.resolve(__dirname, '..')
|
||||||
|
const rootPackagePath = path.join(rootDir, 'package.json')
|
||||||
|
|
||||||
|
const rootPackage = JSON.parse(readFileSync(rootPackagePath, 'utf8'))
|
||||||
|
const rootVersion = rootPackage.version
|
||||||
|
const workspacePaths = Array.isArray(rootPackage.workspaces) ? rootPackage.workspaces : []
|
||||||
|
|
||||||
|
if (typeof rootVersion !== 'string' || rootVersion.length === 0) {
|
||||||
|
throw new Error('Root package.json must contain a valid "version"')
|
||||||
|
}
|
||||||
|
|
||||||
|
const dependencySections = [
|
||||||
|
'dependencies',
|
||||||
|
'devDependencies',
|
||||||
|
'peerDependencies',
|
||||||
|
'optionalDependencies',
|
||||||
|
]
|
||||||
|
|
||||||
|
const touched = []
|
||||||
|
|
||||||
|
for (const workspacePath of workspacePaths) {
|
||||||
|
const packagePath = path.join(rootDir, workspacePath, 'package.json')
|
||||||
|
if (!existsSync(packagePath)) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
const pkg = JSON.parse(readFileSync(packagePath, 'utf8'))
|
||||||
|
let changed = false
|
||||||
|
|
||||||
|
if (pkg.version !== rootVersion) {
|
||||||
|
pkg.version = rootVersion
|
||||||
|
changed = true
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const section of dependencySections) {
|
||||||
|
const deps = pkg[section]
|
||||||
|
if (!deps || typeof deps !== 'object') {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const name of Object.keys(deps)) {
|
||||||
|
if (!name.startsWith('@getpaseo/')) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if (name === pkg.name) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if (deps[name] !== rootVersion) {
|
||||||
|
deps[name] = rootVersion
|
||||||
|
changed = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (changed) {
|
||||||
|
writeFileSync(packagePath, `${JSON.stringify(pkg, null, 2)}\n`)
|
||||||
|
touched.push(path.relative(rootDir, packagePath))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (touched.length === 0) {
|
||||||
|
console.log(`Workspace versions and internal deps already synced to ${rootVersion}`)
|
||||||
|
} else {
|
||||||
|
console.log(`Synced to ${rootVersion}:`)
|
||||||
|
for (const file of touched) {
|
||||||
|
console.log(`- ${file}`)
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user