Compare commits
17
Commits
v1.2.23
...
node-build
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6c80e2662c | ||
|
|
39ef7fc90e | ||
|
|
37ae0a4051 | ||
|
|
b312928e9f | ||
|
|
2f2856e20a | ||
|
|
831eb6881b | ||
|
|
f20ee2fad2 | ||
|
|
8b9710e56c | ||
|
|
c6262f9d40 | ||
|
|
b749fa90f2 | ||
|
|
8a51cbd253 | ||
|
|
399b8f0701 | ||
|
|
3742e42fdf | ||
|
|
0388ec6862 | ||
|
|
366b8a8034 | ||
|
|
ef9bc4ec9e | ||
|
|
5838b58913 |
@@ -0,0 +1,38 @@
|
|||||||
|
name: storybook
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [dev]
|
||||||
|
paths:
|
||||||
|
- ".github/workflows/storybook.yml"
|
||||||
|
- "package.json"
|
||||||
|
- "bun.lock"
|
||||||
|
- "packages/storybook/**"
|
||||||
|
- "packages/ui/**"
|
||||||
|
pull_request:
|
||||||
|
branches: [dev]
|
||||||
|
paths:
|
||||||
|
- ".github/workflows/storybook.yml"
|
||||||
|
- "package.json"
|
||||||
|
- "bun.lock"
|
||||||
|
- "packages/storybook/**"
|
||||||
|
- "packages/ui/**"
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
concurrency:
|
||||||
|
group: ${{ github.workflow }}-${{ github.ref }}
|
||||||
|
cancel-in-progress: true
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
name: storybook build
|
||||||
|
runs-on: blacksmith-4vcpu-ubuntu-2404
|
||||||
|
steps:
|
||||||
|
- name: Checkout repository
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Setup Bun
|
||||||
|
uses: ./.github/actions/setup-bun
|
||||||
|
|
||||||
|
- name: Build Storybook
|
||||||
|
run: bun --cwd packages/storybook build
|
||||||
@@ -5,6 +5,11 @@
|
|||||||
"options": {},
|
"options": {},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
"permission": {
|
||||||
|
"edit": {
|
||||||
|
"packages/opencode/migration/*": "deny",
|
||||||
|
},
|
||||||
|
},
|
||||||
"mcp": {},
|
"mcp": {},
|
||||||
"tools": {
|
"tools": {
|
||||||
"github-triage": false,
|
"github-triage": false,
|
||||||
|
|||||||
@@ -26,7 +26,7 @@
|
|||||||
},
|
},
|
||||||
"packages/app": {
|
"packages/app": {
|
||||||
"name": "@opencode-ai/app",
|
"name": "@opencode-ai/app",
|
||||||
"version": "1.2.23",
|
"version": "1.2.24",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@kobalte/core": "catalog:",
|
"@kobalte/core": "catalog:",
|
||||||
"@opencode-ai/sdk": "workspace:*",
|
"@opencode-ai/sdk": "workspace:*",
|
||||||
@@ -76,7 +76,7 @@
|
|||||||
},
|
},
|
||||||
"packages/console/app": {
|
"packages/console/app": {
|
||||||
"name": "@opencode-ai/console-app",
|
"name": "@opencode-ai/console-app",
|
||||||
"version": "1.2.23",
|
"version": "1.2.24",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@cloudflare/vite-plugin": "1.15.2",
|
"@cloudflare/vite-plugin": "1.15.2",
|
||||||
"@ibm/plex": "6.4.1",
|
"@ibm/plex": "6.4.1",
|
||||||
@@ -110,7 +110,7 @@
|
|||||||
},
|
},
|
||||||
"packages/console/core": {
|
"packages/console/core": {
|
||||||
"name": "@opencode-ai/console-core",
|
"name": "@opencode-ai/console-core",
|
||||||
"version": "1.2.23",
|
"version": "1.2.24",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@aws-sdk/client-sts": "3.782.0",
|
"@aws-sdk/client-sts": "3.782.0",
|
||||||
"@jsx-email/render": "1.1.1",
|
"@jsx-email/render": "1.1.1",
|
||||||
@@ -137,7 +137,7 @@
|
|||||||
},
|
},
|
||||||
"packages/console/function": {
|
"packages/console/function": {
|
||||||
"name": "@opencode-ai/console-function",
|
"name": "@opencode-ai/console-function",
|
||||||
"version": "1.2.23",
|
"version": "1.2.24",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@ai-sdk/anthropic": "2.0.0",
|
"@ai-sdk/anthropic": "2.0.0",
|
||||||
"@ai-sdk/openai": "2.0.2",
|
"@ai-sdk/openai": "2.0.2",
|
||||||
@@ -161,7 +161,7 @@
|
|||||||
},
|
},
|
||||||
"packages/console/mail": {
|
"packages/console/mail": {
|
||||||
"name": "@opencode-ai/console-mail",
|
"name": "@opencode-ai/console-mail",
|
||||||
"version": "1.2.23",
|
"version": "1.2.24",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@jsx-email/all": "2.2.3",
|
"@jsx-email/all": "2.2.3",
|
||||||
"@jsx-email/cli": "1.4.3",
|
"@jsx-email/cli": "1.4.3",
|
||||||
@@ -185,7 +185,7 @@
|
|||||||
},
|
},
|
||||||
"packages/desktop": {
|
"packages/desktop": {
|
||||||
"name": "@opencode-ai/desktop",
|
"name": "@opencode-ai/desktop",
|
||||||
"version": "1.2.23",
|
"version": "1.2.24",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@opencode-ai/app": "workspace:*",
|
"@opencode-ai/app": "workspace:*",
|
||||||
"@opencode-ai/ui": "workspace:*",
|
"@opencode-ai/ui": "workspace:*",
|
||||||
@@ -218,7 +218,7 @@
|
|||||||
},
|
},
|
||||||
"packages/desktop-electron": {
|
"packages/desktop-electron": {
|
||||||
"name": "@opencode-ai/desktop-electron",
|
"name": "@opencode-ai/desktop-electron",
|
||||||
"version": "1.2.23",
|
"version": "1.2.24",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@opencode-ai/app": "workspace:*",
|
"@opencode-ai/app": "workspace:*",
|
||||||
"@opencode-ai/ui": "workspace:*",
|
"@opencode-ai/ui": "workspace:*",
|
||||||
@@ -248,7 +248,7 @@
|
|||||||
},
|
},
|
||||||
"packages/enterprise": {
|
"packages/enterprise": {
|
||||||
"name": "@opencode-ai/enterprise",
|
"name": "@opencode-ai/enterprise",
|
||||||
"version": "1.2.23",
|
"version": "1.2.24",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@opencode-ai/ui": "workspace:*",
|
"@opencode-ai/ui": "workspace:*",
|
||||||
"@opencode-ai/util": "workspace:*",
|
"@opencode-ai/util": "workspace:*",
|
||||||
@@ -277,7 +277,7 @@
|
|||||||
},
|
},
|
||||||
"packages/function": {
|
"packages/function": {
|
||||||
"name": "@opencode-ai/function",
|
"name": "@opencode-ai/function",
|
||||||
"version": "1.2.23",
|
"version": "1.2.24",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@octokit/auth-app": "8.0.1",
|
"@octokit/auth-app": "8.0.1",
|
||||||
"@octokit/rest": "catalog:",
|
"@octokit/rest": "catalog:",
|
||||||
@@ -293,7 +293,7 @@
|
|||||||
},
|
},
|
||||||
"packages/opencode": {
|
"packages/opencode": {
|
||||||
"name": "opencode",
|
"name": "opencode",
|
||||||
"version": "1.2.23",
|
"version": "1.2.24",
|
||||||
"bin": {
|
"bin": {
|
||||||
"opencode": "./bin/opencode",
|
"opencode": "./bin/opencode",
|
||||||
},
|
},
|
||||||
@@ -324,6 +324,8 @@
|
|||||||
"@clack/prompts": "1.0.0-alpha.1",
|
"@clack/prompts": "1.0.0-alpha.1",
|
||||||
"@gitlab/gitlab-ai-provider": "3.6.0",
|
"@gitlab/gitlab-ai-provider": "3.6.0",
|
||||||
"@gitlab/opencode-gitlab-auth": "1.3.3",
|
"@gitlab/opencode-gitlab-auth": "1.3.3",
|
||||||
|
"@hono/node-server": "1.19.11",
|
||||||
|
"@hono/node-ws": "1.3.0",
|
||||||
"@hono/standard-validator": "0.1.5",
|
"@hono/standard-validator": "0.1.5",
|
||||||
"@hono/zod-validator": "catalog:",
|
"@hono/zod-validator": "catalog:",
|
||||||
"@modelcontextprotocol/sdk": "1.25.2",
|
"@modelcontextprotocol/sdk": "1.25.2",
|
||||||
@@ -366,6 +368,7 @@
|
|||||||
"opentui-spinner": "0.0.6",
|
"opentui-spinner": "0.0.6",
|
||||||
"partial-json": "0.1.7",
|
"partial-json": "0.1.7",
|
||||||
"remeda": "catalog:",
|
"remeda": "catalog:",
|
||||||
|
"semver": "^7.6.3",
|
||||||
"solid-js": "catalog:",
|
"solid-js": "catalog:",
|
||||||
"strip-ansi": "7.1.2",
|
"strip-ansi": "7.1.2",
|
||||||
"tree-sitter-bash": "0.25.0",
|
"tree-sitter-bash": "0.25.0",
|
||||||
@@ -395,6 +398,7 @@
|
|||||||
"@types/babel__core": "7.20.5",
|
"@types/babel__core": "7.20.5",
|
||||||
"@types/bun": "catalog:",
|
"@types/bun": "catalog:",
|
||||||
"@types/mime-types": "3.0.1",
|
"@types/mime-types": "3.0.1",
|
||||||
|
"@types/semver": "^7.5.8",
|
||||||
"@types/turndown": "5.0.5",
|
"@types/turndown": "5.0.5",
|
||||||
"@types/which": "3.0.4",
|
"@types/which": "3.0.4",
|
||||||
"@types/yargs": "17.0.33",
|
"@types/yargs": "17.0.33",
|
||||||
@@ -409,7 +413,7 @@
|
|||||||
},
|
},
|
||||||
"packages/plugin": {
|
"packages/plugin": {
|
||||||
"name": "@opencode-ai/plugin",
|
"name": "@opencode-ai/plugin",
|
||||||
"version": "1.2.23",
|
"version": "1.2.24",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@opencode-ai/sdk": "workspace:*",
|
"@opencode-ai/sdk": "workspace:*",
|
||||||
"zod": "catalog:",
|
"zod": "catalog:",
|
||||||
@@ -423,13 +427,17 @@
|
|||||||
},
|
},
|
||||||
"packages/script": {
|
"packages/script": {
|
||||||
"name": "@opencode-ai/script",
|
"name": "@opencode-ai/script",
|
||||||
|
"dependencies": {
|
||||||
|
"semver": "^7.6.3",
|
||||||
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/bun": "catalog:",
|
"@types/bun": "catalog:",
|
||||||
|
"@types/semver": "^7.5.8",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"packages/sdk/js": {
|
"packages/sdk/js": {
|
||||||
"name": "@opencode-ai/sdk",
|
"name": "@opencode-ai/sdk",
|
||||||
"version": "1.2.23",
|
"version": "1.2.24",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@hey-api/openapi-ts": "0.90.10",
|
"@hey-api/openapi-ts": "0.90.10",
|
||||||
"@tsconfig/node22": "catalog:",
|
"@tsconfig/node22": "catalog:",
|
||||||
@@ -440,7 +448,7 @@
|
|||||||
},
|
},
|
||||||
"packages/slack": {
|
"packages/slack": {
|
||||||
"name": "@opencode-ai/slack",
|
"name": "@opencode-ai/slack",
|
||||||
"version": "1.2.23",
|
"version": "1.2.24",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@opencode-ai/sdk": "workspace:*",
|
"@opencode-ai/sdk": "workspace:*",
|
||||||
"@slack/bolt": "^3.17.1",
|
"@slack/bolt": "^3.17.1",
|
||||||
@@ -475,7 +483,7 @@
|
|||||||
},
|
},
|
||||||
"packages/ui": {
|
"packages/ui": {
|
||||||
"name": "@opencode-ai/ui",
|
"name": "@opencode-ai/ui",
|
||||||
"version": "1.2.23",
|
"version": "1.2.24",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@kobalte/core": "catalog:",
|
"@kobalte/core": "catalog:",
|
||||||
"@opencode-ai/sdk": "workspace:*",
|
"@opencode-ai/sdk": "workspace:*",
|
||||||
@@ -521,7 +529,7 @@
|
|||||||
},
|
},
|
||||||
"packages/util": {
|
"packages/util": {
|
||||||
"name": "@opencode-ai/util",
|
"name": "@opencode-ai/util",
|
||||||
"version": "1.2.23",
|
"version": "1.2.24",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"zod": "catalog:",
|
"zod": "catalog:",
|
||||||
},
|
},
|
||||||
@@ -532,7 +540,7 @@
|
|||||||
},
|
},
|
||||||
"packages/web": {
|
"packages/web": {
|
||||||
"name": "@opencode-ai/web",
|
"name": "@opencode-ai/web",
|
||||||
"version": "1.2.23",
|
"version": "1.2.24",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@astrojs/cloudflare": "12.6.3",
|
"@astrojs/cloudflare": "12.6.3",
|
||||||
"@astrojs/markdown-remark": "6.3.1",
|
"@astrojs/markdown-remark": "6.3.1",
|
||||||
@@ -1086,6 +1094,8 @@
|
|||||||
|
|
||||||
"@fontsource/inter": ["@fontsource/inter@5.2.8", "", {}, "sha512-P6r5WnJoKiNVV+zvW2xM13gNdFhAEpQ9dQJHt3naLvfg+LkF2ldgSLiF4T41lf1SQCM9QmkqPTn4TH568IRagg=="],
|
"@fontsource/inter": ["@fontsource/inter@5.2.8", "", {}, "sha512-P6r5WnJoKiNVV+zvW2xM13gNdFhAEpQ9dQJHt3naLvfg+LkF2ldgSLiF4T41lf1SQCM9QmkqPTn4TH568IRagg=="],
|
||||||
|
|
||||||
|
"@gar/promisify": ["@gar/promisify@1.1.3", "", {}, "sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw=="],
|
||||||
|
|
||||||
"@gitlab/gitlab-ai-provider": ["@gitlab/gitlab-ai-provider@3.6.0", "", { "dependencies": { "@anthropic-ai/sdk": "^0.71.0", "@anycable/core": "^0.9.2", "graphql-request": "^6.1.0", "isomorphic-ws": "^5.0.0", "openai": "^6.16.0", "socket.io-client": "^4.8.1", "vscode-jsonrpc": "^8.2.1", "zod": "^3.25.76" }, "peerDependencies": { "@ai-sdk/provider": ">=2.0.0", "@ai-sdk/provider-utils": ">=3.0.0" } }, "sha512-8LmcIQ86xkMtC7L4P1/QYVEC+yKMTRerfPeniaaQGalnzXKtX6iMHLjLPOL9Rxp55lOXi6ed0WrFuJzZx+fNRg=="],
|
"@gitlab/gitlab-ai-provider": ["@gitlab/gitlab-ai-provider@3.6.0", "", { "dependencies": { "@anthropic-ai/sdk": "^0.71.0", "@anycable/core": "^0.9.2", "graphql-request": "^6.1.0", "isomorphic-ws": "^5.0.0", "openai": "^6.16.0", "socket.io-client": "^4.8.1", "vscode-jsonrpc": "^8.2.1", "zod": "^3.25.76" }, "peerDependencies": { "@ai-sdk/provider": ">=2.0.0", "@ai-sdk/provider-utils": ">=3.0.0" } }, "sha512-8LmcIQ86xkMtC7L4P1/QYVEC+yKMTRerfPeniaaQGalnzXKtX6iMHLjLPOL9Rxp55lOXi6ed0WrFuJzZx+fNRg=="],
|
||||||
|
|
||||||
"@gitlab/opencode-gitlab-auth": ["@gitlab/opencode-gitlab-auth@1.3.3", "", { "dependencies": { "@fastify/rate-limit": "^10.2.0", "@opencode-ai/plugin": "*", "fastify": "^5.2.0", "open": "^10.0.0" } }, "sha512-FT+KsCmAJjtqWr1YAq0MywGgL9kaLQ4apmsoowAXrPqHtoYf2i/nY10/A+L06kNj22EATeEDRpbB1NWXMto/SA=="],
|
"@gitlab/opencode-gitlab-auth": ["@gitlab/opencode-gitlab-auth@1.3.3", "", { "dependencies": { "@fastify/rate-limit": "^10.2.0", "@opencode-ai/plugin": "*", "fastify": "^5.2.0", "open": "^10.0.0" } }, "sha512-FT+KsCmAJjtqWr1YAq0MywGgL9kaLQ4apmsoowAXrPqHtoYf2i/nY10/A+L06kNj22EATeEDRpbB1NWXMto/SA=="],
|
||||||
@@ -1102,7 +1112,9 @@
|
|||||||
|
|
||||||
"@hey-api/types": ["@hey-api/types@0.1.2", "", {}, "sha512-uNNtiVAWL7XNrV/tFXx7GLY9lwaaDazx1173cGW3+UEaw4RUPsHEmiB4DSpcjNxMIcrctfz2sGKLnVx5PBG2RA=="],
|
"@hey-api/types": ["@hey-api/types@0.1.2", "", {}, "sha512-uNNtiVAWL7XNrV/tFXx7GLY9lwaaDazx1173cGW3+UEaw4RUPsHEmiB4DSpcjNxMIcrctfz2sGKLnVx5PBG2RA=="],
|
||||||
|
|
||||||
"@hono/node-server": ["@hono/node-server@1.19.9", "", { "peerDependencies": { "hono": "^4" } }, "sha512-vHL6w3ecZsky+8P5MD+eFfaGTyCeOHUIFYMGpQGbrBTSmNNoxv0if69rEZ5giu36weC5saFuznL411gRX7bJDw=="],
|
"@hono/node-server": ["@hono/node-server@1.19.11", "", { "peerDependencies": { "hono": "^4" } }, "sha512-dr8/3zEaB+p0D2n/IUrlPF1HZm586qgJNXK1a9fhg/PzdtkK7Ksd5l312tJX2yBuALqDYBlG20QEbayqPyxn+g=="],
|
||||||
|
|
||||||
|
"@hono/node-ws": ["@hono/node-ws@1.3.0", "", { "dependencies": { "ws": "^8.17.0" }, "peerDependencies": { "@hono/node-server": "^1.19.2", "hono": "^4.6.0" } }, "sha512-ju25YbbvLuXdqBCmLZLqnNYu1nbHIQjoyUqA8ApZOeL1k4skuiTcw5SW77/5SUYo2Xi2NVBJoVlfQurnKEp03Q=="],
|
||||||
|
|
||||||
"@hono/standard-validator": ["@hono/standard-validator@0.1.5", "", { "peerDependencies": { "@standard-schema/spec": "1.0.0", "hono": ">=3.9.0" } }, "sha512-EIyZPPwkyLn6XKwFj5NBEWHXhXbgmnVh2ceIFo5GO7gKI9WmzTjPDKnppQB0KrqKeAkq3kpoW4SIbu5X1dgx3w=="],
|
"@hono/standard-validator": ["@hono/standard-validator@0.1.5", "", { "peerDependencies": { "@standard-schema/spec": "1.0.0", "hono": ">=3.9.0" } }, "sha512-EIyZPPwkyLn6XKwFj5NBEWHXhXbgmnVh2ceIFo5GO7gKI9WmzTjPDKnppQB0KrqKeAkq3kpoW4SIbu5X1dgx3w=="],
|
||||||
|
|
||||||
@@ -1324,7 +1336,9 @@
|
|||||||
|
|
||||||
"@npmcli/agent": ["@npmcli/agent@3.0.0", "", { "dependencies": { "agent-base": "^7.1.0", "http-proxy-agent": "^7.0.0", "https-proxy-agent": "^7.0.1", "lru-cache": "^10.0.1", "socks-proxy-agent": "^8.0.3" } }, "sha512-S79NdEgDQd/NGCay6TCoVzXSj74skRZIKJcpJjC5lOq34SZzyI6MqtiiWoiVWoVrTcGjNeC4ipbh1VIHlpfF5Q=="],
|
"@npmcli/agent": ["@npmcli/agent@3.0.0", "", { "dependencies": { "agent-base": "^7.1.0", "http-proxy-agent": "^7.0.0", "https-proxy-agent": "^7.0.1", "lru-cache": "^10.0.1", "socks-proxy-agent": "^8.0.3" } }, "sha512-S79NdEgDQd/NGCay6TCoVzXSj74skRZIKJcpJjC5lOq34SZzyI6MqtiiWoiVWoVrTcGjNeC4ipbh1VIHlpfF5Q=="],
|
||||||
|
|
||||||
"@npmcli/fs": ["@npmcli/fs@4.0.0", "", { "dependencies": { "semver": "^7.3.5" } }, "sha512-/xGlezI6xfGO9NwuJlnwz/K14qD1kCSAGtacBHnGzeAIuJGazcp45KP5NuyARXoKb7cwulAGWVsbeSxdG/cb0Q=="],
|
"@npmcli/fs": ["@npmcli/fs@1.1.1", "", { "dependencies": { "@gar/promisify": "^1.0.1", "semver": "^7.3.5" } }, "sha512-8KG5RD0GVP4ydEzRn/I4BNDuxDtqVbOdm8675T49OIG/NGhaK0pjPX7ZcDlvKYbA+ulvVK3ztfcF4uBdOxuJbQ=="],
|
||||||
|
|
||||||
|
"@npmcli/move-file": ["@npmcli/move-file@1.1.2", "", { "dependencies": { "mkdirp": "^1.0.4", "rimraf": "^3.0.2" } }, "sha512-1SUf/Cg2GzGDyaf15aR9St9TWlb+XvbZXWpDx8YKs7MLzMH/BCeopv+y9vzrzgkfykCGuWOlSu3mZhj2+FQcrg=="],
|
||||||
|
|
||||||
"@octokit/auth-app": ["@octokit/auth-app@8.0.1", "", { "dependencies": { "@octokit/auth-oauth-app": "^9.0.1", "@octokit/auth-oauth-user": "^6.0.0", "@octokit/request": "^10.0.2", "@octokit/request-error": "^7.0.0", "@octokit/types": "^14.0.0", "toad-cache": "^3.7.0", "universal-github-app-jwt": "^2.2.0", "universal-user-agent": "^7.0.0" } }, "sha512-P2J5pB3pjiGwtJX4WqJVYCtNkcZ+j5T2Wm14aJAEIC3WJOrv12jvBley3G1U/XI8q9o1A7QMG54LiFED2BiFlg=="],
|
"@octokit/auth-app": ["@octokit/auth-app@8.0.1", "", { "dependencies": { "@octokit/auth-oauth-app": "^9.0.1", "@octokit/auth-oauth-user": "^6.0.0", "@octokit/request": "^10.0.2", "@octokit/request-error": "^7.0.0", "@octokit/types": "^14.0.0", "toad-cache": "^3.7.0", "universal-github-app-jwt": "^2.2.0", "universal-user-agent": "^7.0.0" } }, "sha512-P2J5pB3pjiGwtJX4WqJVYCtNkcZ+j5T2Wm14aJAEIC3WJOrv12jvBley3G1U/XI8q9o1A7QMG54LiFED2BiFlg=="],
|
||||||
|
|
||||||
@@ -1998,6 +2012,8 @@
|
|||||||
|
|
||||||
"@tokenizer/token": ["@tokenizer/token@0.3.0", "", {}, "sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A=="],
|
"@tokenizer/token": ["@tokenizer/token@0.3.0", "", {}, "sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A=="],
|
||||||
|
|
||||||
|
"@tootallnate/once": ["@tootallnate/once@1.1.2", "", {}, "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw=="],
|
||||||
|
|
||||||
"@tsconfig/bun": ["@tsconfig/bun@1.0.9", "", {}, "sha512-4M0/Ivfwcpz325z6CwSifOBZYji3DFOEpY6zEUt0+Xi2qRhzwvmqQN9XAHJh3OVvRJuAqVTLU2abdCplvp6mwQ=="],
|
"@tsconfig/bun": ["@tsconfig/bun@1.0.9", "", {}, "sha512-4M0/Ivfwcpz325z6CwSifOBZYji3DFOEpY6zEUt0+Xi2qRhzwvmqQN9XAHJh3OVvRJuAqVTLU2abdCplvp6mwQ=="],
|
||||||
|
|
||||||
"@tsconfig/node22": ["@tsconfig/node22@22.0.2", "", {}, "sha512-Kmwj4u8sDRDrMYRoN9FDEcXD8UpBSaPQQ24Gz+Gamqfm7xxn+GBR7ge/Z7pK8OXNGyUzbSwJj+TH6B+DS/epyA=="],
|
"@tsconfig/node22": ["@tsconfig/node22@22.0.2", "", {}, "sha512-Kmwj4u8sDRDrMYRoN9FDEcXD8UpBSaPQQ24Gz+Gamqfm7xxn+GBR7ge/Z7pK8OXNGyUzbSwJj+TH6B+DS/epyA=="],
|
||||||
@@ -2104,6 +2120,8 @@
|
|||||||
|
|
||||||
"@types/scheduler": ["@types/scheduler@0.26.0", "", {}, "sha512-WFHp9YUJQ6CKshqoC37iOlHnQSmxNc795UhB26CyBBttrN9svdIrUjl/NjnNmfcwtncN0h/0PPAFWv9ovP8mLA=="],
|
"@types/scheduler": ["@types/scheduler@0.26.0", "", {}, "sha512-WFHp9YUJQ6CKshqoC37iOlHnQSmxNc795UhB26CyBBttrN9svdIrUjl/NjnNmfcwtncN0h/0PPAFWv9ovP8mLA=="],
|
||||||
|
|
||||||
|
"@types/semver": ["@types/semver@7.7.1", "", {}, "sha512-FmgJfu+MOcQ370SD0ev7EI8TlCAfKYU+B4m5T3yXc1CiRN94g/SZPtsCkk506aUDtlMnFZvasDwHHUcZUEaYuA=="],
|
||||||
|
|
||||||
"@types/send": ["@types/send@1.2.1", "", { "dependencies": { "@types/node": "*" } }, "sha512-arsCikDvlU99zl1g69TcAB3mzZPpxgw0UQnaHeC1Nwb015xp8bknZv5rIfri9xTOcMuaVgvabfIRA7PSZVuZIQ=="],
|
"@types/send": ["@types/send@1.2.1", "", { "dependencies": { "@types/node": "*" } }, "sha512-arsCikDvlU99zl1g69TcAB3mzZPpxgw0UQnaHeC1Nwb015xp8bknZv5rIfri9xTOcMuaVgvabfIRA7PSZVuZIQ=="],
|
||||||
|
|
||||||
"@types/serve-static": ["@types/serve-static@1.15.10", "", { "dependencies": { "@types/http-errors": "*", "@types/node": "*", "@types/send": "<1" } }, "sha512-tRs1dB+g8Itk72rlSI2ZrW6vZg0YrLI81iQSTkMmOqnqCaNr/8Ek4VwWcN5vZgCYWbg/JJSGBlUaYGAOP73qBw=="],
|
"@types/serve-static": ["@types/serve-static@1.15.10", "", { "dependencies": { "@types/http-errors": "*", "@types/node": "*", "@types/send": "<1" } }, "sha512-tRs1dB+g8Itk72rlSI2ZrW6vZg0YrLI81iQSTkMmOqnqCaNr/8Ek4VwWcN5vZgCYWbg/JJSGBlUaYGAOP73qBw=="],
|
||||||
@@ -2212,6 +2230,8 @@
|
|||||||
|
|
||||||
"agentkeepalive": ["agentkeepalive@4.6.0", "", { "dependencies": { "humanize-ms": "^1.2.1" } }, "sha512-kja8j7PjmncONqaTsB8fQ+wE2mSU2DJ9D4XKoJ5PFWIdRMa6SLSN1ff4mOr4jCbfRSsxR4keIiySJU0N9T5hIQ=="],
|
"agentkeepalive": ["agentkeepalive@4.6.0", "", { "dependencies": { "humanize-ms": "^1.2.1" } }, "sha512-kja8j7PjmncONqaTsB8fQ+wE2mSU2DJ9D4XKoJ5PFWIdRMa6SLSN1ff4mOr4jCbfRSsxR4keIiySJU0N9T5hIQ=="],
|
||||||
|
|
||||||
|
"aggregate-error": ["aggregate-error@3.1.0", "", { "dependencies": { "clean-stack": "^2.0.0", "indent-string": "^4.0.0" } }, "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA=="],
|
||||||
|
|
||||||
"ai": ["ai@5.0.124", "", { "dependencies": { "@ai-sdk/gateway": "2.0.30", "@ai-sdk/provider": "2.0.1", "@ai-sdk/provider-utils": "3.0.20", "@opentelemetry/api": "1.9.0" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-Li6Jw9F9qsvFJXZPBfxj38ddP2iURCnMs96f9Q3OeQzrDVcl1hvtwSEAuxA/qmfh6SDV2ERqFUOFzigvr0697g=="],
|
"ai": ["ai@5.0.124", "", { "dependencies": { "@ai-sdk/gateway": "2.0.30", "@ai-sdk/provider": "2.0.1", "@ai-sdk/provider-utils": "3.0.20", "@opentelemetry/api": "1.9.0" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-Li6Jw9F9qsvFJXZPBfxj38ddP2iURCnMs96f9Q3OeQzrDVcl1hvtwSEAuxA/qmfh6SDV2ERqFUOFzigvr0697g=="],
|
||||||
|
|
||||||
"ai-gateway-provider": ["ai-gateway-provider@2.3.1", "", { "dependencies": { "@ai-sdk/provider": "^2.0.0", "@ai-sdk/provider-utils": "^3.0.19", "ai": "^5.0.116" }, "optionalDependencies": { "@ai-sdk/amazon-bedrock": "^3.0.71", "@ai-sdk/anthropic": "^2.0.56", "@ai-sdk/azure": "^2.0.90", "@ai-sdk/cerebras": "^1.0.33", "@ai-sdk/cohere": "^2.0.21", "@ai-sdk/deepgram": "^1.0.21", "@ai-sdk/deepseek": "^1.0.32", "@ai-sdk/elevenlabs": "^1.0.21", "@ai-sdk/fireworks": "^1.0.30", "@ai-sdk/google": "^2.0.51", "@ai-sdk/google-vertex": "3.0.90", "@ai-sdk/groq": "^2.0.33", "@ai-sdk/mistral": "^2.0.26", "@ai-sdk/openai": "^2.0.88", "@ai-sdk/perplexity": "^2.0.22", "@ai-sdk/xai": "^2.0.42", "@openrouter/ai-sdk-provider": "^1.5.3" }, "peerDependencies": { "@ai-sdk/openai-compatible": "^1.0.29" } }, "sha512-PqI6TVNEDNwr7kOhy7XUGnA8XJB1SpeA9aLqGjr0CyWkKgH+y+ofPm8MZGZ74DOwVejDF+POZq0Qs9jKEKUeYg=="],
|
"ai-gateway-provider": ["ai-gateway-provider@2.3.1", "", { "dependencies": { "@ai-sdk/provider": "^2.0.0", "@ai-sdk/provider-utils": "^3.0.19", "ai": "^5.0.116" }, "optionalDependencies": { "@ai-sdk/amazon-bedrock": "^3.0.71", "@ai-sdk/anthropic": "^2.0.56", "@ai-sdk/azure": "^2.0.90", "@ai-sdk/cerebras": "^1.0.33", "@ai-sdk/cohere": "^2.0.21", "@ai-sdk/deepgram": "^1.0.21", "@ai-sdk/deepseek": "^1.0.32", "@ai-sdk/elevenlabs": "^1.0.21", "@ai-sdk/fireworks": "^1.0.30", "@ai-sdk/google": "^2.0.51", "@ai-sdk/google-vertex": "3.0.90", "@ai-sdk/groq": "^2.0.33", "@ai-sdk/mistral": "^2.0.26", "@ai-sdk/openai": "^2.0.88", "@ai-sdk/perplexity": "^2.0.22", "@ai-sdk/xai": "^2.0.42", "@openrouter/ai-sdk-provider": "^1.5.3" }, "peerDependencies": { "@ai-sdk/openai-compatible": "^1.0.29" } }, "sha512-PqI6TVNEDNwr7kOhy7XUGnA8XJB1SpeA9aLqGjr0CyWkKgH+y+ofPm8MZGZ74DOwVejDF+POZq0Qs9jKEKUeYg=="],
|
||||||
@@ -2244,12 +2264,16 @@
|
|||||||
|
|
||||||
"app-builder-lib": ["app-builder-lib@26.8.1", "", { "dependencies": { "@develar/schema-utils": "~2.6.5", "@electron/asar": "3.4.1", "@electron/fuses": "^1.8.0", "@electron/get": "^3.0.0", "@electron/notarize": "2.5.0", "@electron/osx-sign": "1.3.3", "@electron/rebuild": "^4.0.3", "@electron/universal": "2.0.3", "@malept/flatpak-bundler": "^0.4.0", "@types/fs-extra": "9.0.13", "async-exit-hook": "^2.0.1", "builder-util": "26.8.1", "builder-util-runtime": "9.5.1", "chromium-pickle-js": "^0.2.0", "ci-info": "4.3.1", "debug": "^4.3.4", "dotenv": "^16.4.5", "dotenv-expand": "^11.0.6", "ejs": "^3.1.8", "electron-publish": "26.8.1", "fs-extra": "^10.1.0", "hosted-git-info": "^4.1.0", "isbinaryfile": "^5.0.0", "jiti": "^2.4.2", "js-yaml": "^4.1.0", "json5": "^2.2.3", "lazy-val": "^1.0.5", "minimatch": "^10.0.3", "plist": "3.1.0", "proper-lockfile": "^4.1.2", "resedit": "^1.7.0", "semver": "~7.7.3", "tar": "^7.5.7", "temp-file": "^3.4.0", "tiny-async-pool": "1.3.0", "which": "^5.0.0" }, "peerDependencies": { "dmg-builder": "26.8.1", "electron-builder-squirrel-windows": "26.8.1" } }, "sha512-p0Im/Dx5C4tmz8QEE1Yn4MkuPC8PrnlRneMhWJj7BBXQfNTJUshM/bp3lusdEsDbvvfJZpXWnYesgSLvwtM2Zw=="],
|
"app-builder-lib": ["app-builder-lib@26.8.1", "", { "dependencies": { "@develar/schema-utils": "~2.6.5", "@electron/asar": "3.4.1", "@electron/fuses": "^1.8.0", "@electron/get": "^3.0.0", "@electron/notarize": "2.5.0", "@electron/osx-sign": "1.3.3", "@electron/rebuild": "^4.0.3", "@electron/universal": "2.0.3", "@malept/flatpak-bundler": "^0.4.0", "@types/fs-extra": "9.0.13", "async-exit-hook": "^2.0.1", "builder-util": "26.8.1", "builder-util-runtime": "9.5.1", "chromium-pickle-js": "^0.2.0", "ci-info": "4.3.1", "debug": "^4.3.4", "dotenv": "^16.4.5", "dotenv-expand": "^11.0.6", "ejs": "^3.1.8", "electron-publish": "26.8.1", "fs-extra": "^10.1.0", "hosted-git-info": "^4.1.0", "isbinaryfile": "^5.0.0", "jiti": "^2.4.2", "js-yaml": "^4.1.0", "json5": "^2.2.3", "lazy-val": "^1.0.5", "minimatch": "^10.0.3", "plist": "3.1.0", "proper-lockfile": "^4.1.2", "resedit": "^1.7.0", "semver": "~7.7.3", "tar": "^7.5.7", "temp-file": "^3.4.0", "tiny-async-pool": "1.3.0", "which": "^5.0.0" }, "peerDependencies": { "dmg-builder": "26.8.1", "electron-builder-squirrel-windows": "26.8.1" } }, "sha512-p0Im/Dx5C4tmz8QEE1Yn4MkuPC8PrnlRneMhWJj7BBXQfNTJUshM/bp3lusdEsDbvvfJZpXWnYesgSLvwtM2Zw=="],
|
||||||
|
|
||||||
|
"aproba": ["aproba@2.1.0", "", {}, "sha512-tLIEcj5GuR2RSTnxNKdkK0dJ/GrC7P38sUkiDmDuHfsHmbagTFAxDVIBltoklXEVIQ/f14IL8IMJ5pn9Hez1Ew=="],
|
||||||
|
|
||||||
"archiver": ["archiver@7.0.1", "", { "dependencies": { "archiver-utils": "^5.0.2", "async": "^3.2.4", "buffer-crc32": "^1.0.0", "readable-stream": "^4.0.0", "readdir-glob": "^1.1.2", "tar-stream": "^3.0.0", "zip-stream": "^6.0.1" } }, "sha512-ZcbTaIqJOfCc03QwD468Unz/5Ir8ATtvAHsK+FdXbDIbGfihqh9mrvdcYunQzqn4HrvWWaFyaxJhGZagaJJpPQ=="],
|
"archiver": ["archiver@7.0.1", "", { "dependencies": { "archiver-utils": "^5.0.2", "async": "^3.2.4", "buffer-crc32": "^1.0.0", "readable-stream": "^4.0.0", "readdir-glob": "^1.1.2", "tar-stream": "^3.0.0", "zip-stream": "^6.0.1" } }, "sha512-ZcbTaIqJOfCc03QwD468Unz/5Ir8ATtvAHsK+FdXbDIbGfihqh9mrvdcYunQzqn4HrvWWaFyaxJhGZagaJJpPQ=="],
|
||||||
|
|
||||||
"archiver-utils": ["archiver-utils@5.0.2", "", { "dependencies": { "glob": "^10.0.0", "graceful-fs": "^4.2.0", "is-stream": "^2.0.1", "lazystream": "^1.0.0", "lodash": "^4.17.15", "normalize-path": "^3.0.0", "readable-stream": "^4.0.0" } }, "sha512-wuLJMmIBQYCsGZgYLTy5FIB2pF6Lfb6cXMSF8Qywwk3t20zWnAi7zLcQFdKQmIB8wyZpY5ER38x08GbwtR2cLA=="],
|
"archiver-utils": ["archiver-utils@5.0.2", "", { "dependencies": { "glob": "^10.0.0", "graceful-fs": "^4.2.0", "is-stream": "^2.0.1", "lazystream": "^1.0.0", "lodash": "^4.17.15", "normalize-path": "^3.0.0", "readable-stream": "^4.0.0" } }, "sha512-wuLJMmIBQYCsGZgYLTy5FIB2pF6Lfb6cXMSF8Qywwk3t20zWnAi7zLcQFdKQmIB8wyZpY5ER38x08GbwtR2cLA=="],
|
||||||
|
|
||||||
"arctic": ["arctic@2.3.4", "", { "dependencies": { "@oslojs/crypto": "1.0.1", "@oslojs/encoding": "1.1.0", "@oslojs/jwt": "0.2.0" } }, "sha512-+p30BOWsctZp+CVYCt7oAean/hWGW42sH5LAcRQX56ttEkFJWbzXBhmSpibbzwSJkRrotmsA+oAoJoVsU0f5xA=="],
|
"arctic": ["arctic@2.3.4", "", { "dependencies": { "@oslojs/crypto": "1.0.1", "@oslojs/encoding": "1.1.0", "@oslojs/jwt": "0.2.0" } }, "sha512-+p30BOWsctZp+CVYCt7oAean/hWGW42sH5LAcRQX56ttEkFJWbzXBhmSpibbzwSJkRrotmsA+oAoJoVsU0f5xA=="],
|
||||||
|
|
||||||
|
"are-we-there-yet": ["are-we-there-yet@3.0.1", "", { "dependencies": { "delegates": "^1.0.0", "readable-stream": "^3.6.0" } }, "sha512-QZW4EDmGwlYur0Yyf/b2uGucHQMa8aFUP7eu9ddR73vvhFyt4V0Vl3QHPcTNJ8l6qYOBdxgXdnBXQrHilfRQBg=="],
|
||||||
|
|
||||||
"arg": ["arg@5.0.2", "", {}, "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg=="],
|
"arg": ["arg@5.0.2", "", {}, "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg=="],
|
||||||
|
|
||||||
"argparse": ["argparse@2.0.1", "", {}, "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="],
|
"argparse": ["argparse@2.0.1", "", {}, "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="],
|
||||||
@@ -2352,6 +2376,8 @@
|
|||||||
|
|
||||||
"binary-extensions": ["binary-extensions@2.3.0", "", {}, "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw=="],
|
"binary-extensions": ["binary-extensions@2.3.0", "", {}, "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw=="],
|
||||||
|
|
||||||
|
"bindings": ["bindings@1.5.0", "", { "dependencies": { "file-uri-to-path": "1.0.0" } }, "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ=="],
|
||||||
|
|
||||||
"bl": ["bl@6.1.6", "", { "dependencies": { "@types/readable-stream": "^4.0.0", "buffer": "^6.0.3", "inherits": "^2.0.4", "readable-stream": "^4.2.0" } }, "sha512-jLsPgN/YSvPUg9UX0Kd73CXpm2Psg9FxMeCSXnk3WBO3CMT10JMwijubhGfHCnFu6TPn1ei3b975dxv7K2pWVg=="],
|
"bl": ["bl@6.1.6", "", { "dependencies": { "@types/readable-stream": "^4.0.0", "buffer": "^6.0.3", "inherits": "^2.0.4", "readable-stream": "^4.2.0" } }, "sha512-jLsPgN/YSvPUg9UX0Kd73CXpm2Psg9FxMeCSXnk3WBO3CMT10JMwijubhGfHCnFu6TPn1ei3b975dxv7K2pWVg=="],
|
||||||
|
|
||||||
"blake3-wasm": ["blake3-wasm@2.1.5", "", {}, "sha512-F1+K8EbfOZE49dtoPtmxUQrpXaBIl3ICvasLh+nJta0xkz+9kF/7uet9fLnwKqhDrmj6g+6K3Tw9yQPUg2ka5g=="],
|
"blake3-wasm": ["blake3-wasm@2.1.5", "", {}, "sha512-F1+K8EbfOZE49dtoPtmxUQrpXaBIl3ICvasLh+nJta0xkz+9kF/7uet9fLnwKqhDrmj6g+6K3Tw9yQPUg2ka5g=="],
|
||||||
@@ -2420,7 +2446,7 @@
|
|||||||
|
|
||||||
"cac": ["cac@6.7.14", "", {}, "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ=="],
|
"cac": ["cac@6.7.14", "", {}, "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ=="],
|
||||||
|
|
||||||
"cacache": ["cacache@19.0.1", "", { "dependencies": { "@npmcli/fs": "^4.0.0", "fs-minipass": "^3.0.0", "glob": "^10.2.2", "lru-cache": "^10.0.1", "minipass": "^7.0.3", "minipass-collect": "^2.0.1", "minipass-flush": "^1.0.5", "minipass-pipeline": "^1.2.4", "p-map": "^7.0.2", "ssri": "^12.0.0", "tar": "^7.4.3", "unique-filename": "^4.0.0" } }, "sha512-hdsUxulXCi5STId78vRVYEtDAjq99ICAUktLTeTYsLoTE6Z8dS0c8pWNCxwdrk9YfJeobDZc2Y186hD/5ZQgFQ=="],
|
"cacache": ["cacache@15.3.0", "", { "dependencies": { "@npmcli/fs": "^1.0.0", "@npmcli/move-file": "^1.0.1", "chownr": "^2.0.0", "fs-minipass": "^2.0.0", "glob": "^7.1.4", "infer-owner": "^1.0.4", "lru-cache": "^6.0.0", "minipass": "^3.1.1", "minipass-collect": "^1.0.2", "minipass-flush": "^1.0.5", "minipass-pipeline": "^1.2.2", "mkdirp": "^1.0.3", "p-map": "^4.0.0", "promise-inflight": "^1.0.1", "rimraf": "^3.0.2", "ssri": "^8.0.1", "tar": "^6.0.2", "unique-filename": "^1.1.1" } }, "sha512-VVdYzXEn+cnbXpFgWs5hTT7OScegHVmLhJIR8Ufqk3iFD6A6j5iSX1KuBTfNEv4tdJWE2PzA6IVFtcLC7fN9wQ=="],
|
||||||
|
|
||||||
"cacheable-lookup": ["cacheable-lookup@5.0.4", "", {}, "sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA=="],
|
"cacheable-lookup": ["cacheable-lookup@5.0.4", "", {}, "sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA=="],
|
||||||
|
|
||||||
@@ -2478,6 +2504,8 @@
|
|||||||
|
|
||||||
"clean-css": ["clean-css@5.3.3", "", { "dependencies": { "source-map": "~0.6.0" } }, "sha512-D5J+kHaVb/wKSFcyyV75uCn8fiY4sV38XJoe4CUyGQ+mOU/fMVYUdH1hJC+CJQ5uY3EnW27SbJYS4X8BiLrAFg=="],
|
"clean-css": ["clean-css@5.3.3", "", { "dependencies": { "source-map": "~0.6.0" } }, "sha512-D5J+kHaVb/wKSFcyyV75uCn8fiY4sV38XJoe4CUyGQ+mOU/fMVYUdH1hJC+CJQ5uY3EnW27SbJYS4X8BiLrAFg=="],
|
||||||
|
|
||||||
|
"clean-stack": ["clean-stack@2.2.0", "", {}, "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A=="],
|
||||||
|
|
||||||
"cli-boxes": ["cli-boxes@3.0.0", "", {}, "sha512-/lzGpEWL/8PfI0BmBOPRwp0c/wFNX1RdUML3jK/RcSBA9T8mZDdQpqYBKtCFTOfQbwPqWEOpjqW+Fnayc0969g=="],
|
"cli-boxes": ["cli-boxes@3.0.0", "", {}, "sha512-/lzGpEWL/8PfI0BmBOPRwp0c/wFNX1RdUML3jK/RcSBA9T8mZDdQpqYBKtCFTOfQbwPqWEOpjqW+Fnayc0969g=="],
|
||||||
|
|
||||||
"cli-cursor": ["cli-cursor@3.1.0", "", { "dependencies": { "restore-cursor": "^3.1.0" } }, "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw=="],
|
"cli-cursor": ["cli-cursor@3.1.0", "", { "dependencies": { "restore-cursor": "^3.1.0" } }, "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw=="],
|
||||||
@@ -2534,6 +2562,8 @@
|
|||||||
|
|
||||||
"consola": ["consola@3.4.2", "", {}, "sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA=="],
|
"consola": ["consola@3.4.2", "", {}, "sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA=="],
|
||||||
|
|
||||||
|
"console-control-strings": ["console-control-strings@1.1.0", "", {}, "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ=="],
|
||||||
|
|
||||||
"content-disposition": ["content-disposition@0.5.4", "", { "dependencies": { "safe-buffer": "5.2.1" } }, "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ=="],
|
"content-disposition": ["content-disposition@0.5.4", "", { "dependencies": { "safe-buffer": "5.2.1" } }, "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ=="],
|
||||||
|
|
||||||
"content-type": ["content-type@1.0.5", "", {}, "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA=="],
|
"content-type": ["content-type@1.0.5", "", {}, "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA=="],
|
||||||
@@ -2600,6 +2630,8 @@
|
|||||||
|
|
||||||
"deep-eql": ["deep-eql@5.0.2", "", {}, "sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q=="],
|
"deep-eql": ["deep-eql@5.0.2", "", {}, "sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q=="],
|
||||||
|
|
||||||
|
"deep-extend": ["deep-extend@0.6.0", "", {}, "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA=="],
|
||||||
|
|
||||||
"deepmerge": ["deepmerge@4.3.1", "", {}, "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A=="],
|
"deepmerge": ["deepmerge@4.3.1", "", {}, "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A=="],
|
||||||
|
|
||||||
"default-browser": ["default-browser@5.5.0", "", { "dependencies": { "bundle-name": "^4.1.0", "default-browser-id": "^5.0.0" } }, "sha512-H9LMLr5zwIbSxrmvikGuI/5KGhZ8E2zH3stkMgM5LpOWDutGM2JZaj460Udnf1a+946zc7YBgrqEWwbk7zHvGw=="],
|
"default-browser": ["default-browser@5.5.0", "", { "dependencies": { "bundle-name": "^4.1.0", "default-browser-id": "^5.0.0" } }, "sha512-H9LMLr5zwIbSxrmvikGuI/5KGhZ8E2zH3stkMgM5LpOWDutGM2JZaj460Udnf1a+946zc7YBgrqEWwbk7zHvGw=="],
|
||||||
@@ -2620,6 +2652,8 @@
|
|||||||
|
|
||||||
"delayed-stream": ["delayed-stream@1.0.0", "", {}, "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ=="],
|
"delayed-stream": ["delayed-stream@1.0.0", "", {}, "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ=="],
|
||||||
|
|
||||||
|
"delegates": ["delegates@1.0.0", "", {}, "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ=="],
|
||||||
|
|
||||||
"denque": ["denque@2.1.0", "", {}, "sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw=="],
|
"denque": ["denque@2.1.0", "", {}, "sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw=="],
|
||||||
|
|
||||||
"depd": ["depd@2.0.0", "", {}, "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw=="],
|
"depd": ["depd@2.0.0", "", {}, "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw=="],
|
||||||
@@ -2822,6 +2856,8 @@
|
|||||||
|
|
||||||
"exit-hook": ["exit-hook@2.2.1", "", {}, "sha512-eNTPlAD67BmP31LDINZ3U7HSF8l57TxOY2PmBJ1shpCvpnxBF93mWCE8YHBnXs8qiUZJc9WDcWIeC3a2HIAMfw=="],
|
"exit-hook": ["exit-hook@2.2.1", "", {}, "sha512-eNTPlAD67BmP31LDINZ3U7HSF8l57TxOY2PmBJ1shpCvpnxBF93mWCE8YHBnXs8qiUZJc9WDcWIeC3a2HIAMfw=="],
|
||||||
|
|
||||||
|
"expand-template": ["expand-template@2.0.3", "", {}, "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg=="],
|
||||||
|
|
||||||
"expect-type": ["expect-type@1.3.0", "", {}, "sha512-knvyeauYhqjOYvQ66MznSMs83wmHrCycNEN6Ao+2AeYEfxUIkuiVxdEa1qlGEPK+We3n0THiDciYSsCcgW/DoA=="],
|
"expect-type": ["expect-type@1.3.0", "", {}, "sha512-knvyeauYhqjOYvQ66MznSMs83wmHrCycNEN6Ao+2AeYEfxUIkuiVxdEa1qlGEPK+We3n0THiDciYSsCcgW/DoA=="],
|
||||||
|
|
||||||
"exponential-backoff": ["exponential-backoff@3.1.3", "", {}, "sha512-ZgEeZXj30q+I0EN+CbSSpIyPaJ5HVQD18Z1m+u1FXbAeT94mr1zw50q4q6jiiC447Nl/YTcIYSAftiGqetwXCA=="],
|
"exponential-backoff": ["exponential-backoff@3.1.3", "", {}, "sha512-ZgEeZXj30q+I0EN+CbSSpIyPaJ5HVQD18Z1m+u1FXbAeT94mr1zw50q4q6jiiC447Nl/YTcIYSAftiGqetwXCA=="],
|
||||||
@@ -2876,6 +2912,8 @@
|
|||||||
|
|
||||||
"file-type": ["file-type@16.5.4", "", { "dependencies": { "readable-web-to-node-stream": "^3.0.0", "strtok3": "^6.2.4", "token-types": "^4.1.1" } }, "sha512-/yFHK0aGjFEgDJjEKP0pWCplsPFPhwyfwevf/pVxiN0tmE4L9LmwWxWukdJSHdoCli4VgQLehjJtwQBnqmsKcw=="],
|
"file-type": ["file-type@16.5.4", "", { "dependencies": { "readable-web-to-node-stream": "^3.0.0", "strtok3": "^6.2.4", "token-types": "^4.1.1" } }, "sha512-/yFHK0aGjFEgDJjEKP0pWCplsPFPhwyfwevf/pVxiN0tmE4L9LmwWxWukdJSHdoCli4VgQLehjJtwQBnqmsKcw=="],
|
||||||
|
|
||||||
|
"file-uri-to-path": ["file-uri-to-path@1.0.0", "", {}, "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw=="],
|
||||||
|
|
||||||
"filelist": ["filelist@1.0.6", "", { "dependencies": { "minimatch": "^5.0.1" } }, "sha512-5giy2PkLYY1cP39p17Ech+2xlpTRL9HLspOfEgm0L6CwBXBTgsK5ou0JtzYuepxkaQ/tvhCFIJ5uXo0OrM2DxA=="],
|
"filelist": ["filelist@1.0.6", "", { "dependencies": { "minimatch": "^5.0.1" } }, "sha512-5giy2PkLYY1cP39p17Ech+2xlpTRL9HLspOfEgm0L6CwBXBTgsK5ou0JtzYuepxkaQ/tvhCFIJ5uXo0OrM2DxA=="],
|
||||||
|
|
||||||
"fill-range": ["fill-range@7.1.1", "", { "dependencies": { "to-regex-range": "^5.0.1" } }, "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg=="],
|
"fill-range": ["fill-range@7.1.1", "", { "dependencies": { "to-regex-range": "^5.0.1" } }, "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg=="],
|
||||||
@@ -2918,9 +2956,11 @@
|
|||||||
|
|
||||||
"fresh": ["fresh@0.5.2", "", {}, "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q=="],
|
"fresh": ["fresh@0.5.2", "", {}, "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q=="],
|
||||||
|
|
||||||
|
"fs-constants": ["fs-constants@1.0.0", "", {}, "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow=="],
|
||||||
|
|
||||||
"fs-extra": ["fs-extra@10.1.0", "", { "dependencies": { "graceful-fs": "^4.2.0", "jsonfile": "^6.0.1", "universalify": "^2.0.0" } }, "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ=="],
|
"fs-extra": ["fs-extra@10.1.0", "", { "dependencies": { "graceful-fs": "^4.2.0", "jsonfile": "^6.0.1", "universalify": "^2.0.0" } }, "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ=="],
|
||||||
|
|
||||||
"fs-minipass": ["fs-minipass@3.0.3", "", { "dependencies": { "minipass": "^7.0.3" } }, "sha512-XUBA9XClHbnJWSfBzjkm6RvPsyg3sryZt06BEQoXcF7EK/xpGaQYJgQKDJSUH5SGZ76Y7pFx1QBnXz09rU5Fbw=="],
|
"fs-minipass": ["fs-minipass@2.1.0", "", { "dependencies": { "minipass": "^3.0.0" } }, "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg=="],
|
||||||
|
|
||||||
"fs.realpath": ["fs.realpath@1.0.0", "", {}, "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw=="],
|
"fs.realpath": ["fs.realpath@1.0.0", "", {}, "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw=="],
|
||||||
|
|
||||||
@@ -2934,6 +2974,8 @@
|
|||||||
|
|
||||||
"fuzzysort": ["fuzzysort@3.1.0", "", {}, "sha512-sR9BNCjBg6LNgwvxlBd0sBABvQitkLzoVY9MYYROQVX/FvfJ4Mai9LsGhDgd8qYdds0bY77VzYd5iuB+v5rwQQ=="],
|
"fuzzysort": ["fuzzysort@3.1.0", "", {}, "sha512-sR9BNCjBg6LNgwvxlBd0sBABvQitkLzoVY9MYYROQVX/FvfJ4Mai9LsGhDgd8qYdds0bY77VzYd5iuB+v5rwQQ=="],
|
||||||
|
|
||||||
|
"gauge": ["gauge@4.0.4", "", { "dependencies": { "aproba": "^1.0.3 || ^2.0.0", "color-support": "^1.1.3", "console-control-strings": "^1.1.0", "has-unicode": "^2.0.1", "signal-exit": "^3.0.7", "string-width": "^4.2.3", "strip-ansi": "^6.0.1", "wide-align": "^1.1.5" } }, "sha512-f9m+BEN5jkg6a0fZjleidjN51VE1X+mPFQ2DJ0uv1V39oCLCbsGe6yjbBnp7eK7z/+GAon99a3nHuqbuuthyPg=="],
|
||||||
|
|
||||||
"gaxios": ["gaxios@7.1.3", "", { "dependencies": { "extend": "^3.0.2", "https-proxy-agent": "^7.0.1", "node-fetch": "^3.3.2", "rimraf": "^5.0.1" } }, "sha512-YGGyuEdVIjqxkxVH1pUTMY/XtmmsApXrCVv5EU25iX6inEPbV+VakJfLealkBtJN69AQmh1eGOdCl9Sm1UP6XQ=="],
|
"gaxios": ["gaxios@7.1.3", "", { "dependencies": { "extend": "^3.0.2", "https-proxy-agent": "^7.0.1", "node-fetch": "^3.3.2", "rimraf": "^5.0.1" } }, "sha512-YGGyuEdVIjqxkxVH1pUTMY/XtmmsApXrCVv5EU25iX6inEPbV+VakJfLealkBtJN69AQmh1eGOdCl9Sm1UP6XQ=="],
|
||||||
|
|
||||||
"gcp-metadata": ["gcp-metadata@8.1.2", "", { "dependencies": { "gaxios": "^7.0.0", "google-logging-utils": "^1.0.0", "json-bigint": "^1.0.0" } }, "sha512-zV/5HKTfCeKWnxG0Dmrw51hEWFGfcF2xiXqcA3+J90WDuP0SvoiSO5ORvcBsifmx/FoIjgQN3oNOGaQ5PhLFkg=="],
|
"gcp-metadata": ["gcp-metadata@8.1.2", "", { "dependencies": { "gaxios": "^7.0.0", "google-logging-utils": "^1.0.0", "json-bigint": "^1.0.0" } }, "sha512-zV/5HKTfCeKWnxG0Dmrw51hEWFGfcF2xiXqcA3+J90WDuP0SvoiSO5ORvcBsifmx/FoIjgQN3oNOGaQ5PhLFkg=="],
|
||||||
@@ -2968,6 +3010,8 @@
|
|||||||
|
|
||||||
"giget": ["giget@2.0.0", "", { "dependencies": { "citty": "^0.1.6", "consola": "^3.4.0", "defu": "^6.1.4", "node-fetch-native": "^1.6.6", "nypm": "^0.6.0", "pathe": "^2.0.3" }, "bin": { "giget": "dist/cli.mjs" } }, "sha512-L5bGsVkxJbJgdnwyuheIunkGatUF/zssUoxxjACCseZYAVbaqdh9Tsmmlkl8vYan09H7sbvKt4pS8GqKLBrEzA=="],
|
"giget": ["giget@2.0.0", "", { "dependencies": { "citty": "^0.1.6", "consola": "^3.4.0", "defu": "^6.1.4", "node-fetch-native": "^1.6.6", "nypm": "^0.6.0", "pathe": "^2.0.3" }, "bin": { "giget": "dist/cli.mjs" } }, "sha512-L5bGsVkxJbJgdnwyuheIunkGatUF/zssUoxxjACCseZYAVbaqdh9Tsmmlkl8vYan09H7sbvKt4pS8GqKLBrEzA=="],
|
||||||
|
|
||||||
|
"github-from-package": ["github-from-package@0.0.0", "", {}, "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw=="],
|
||||||
|
|
||||||
"github-slugger": ["github-slugger@2.0.0", "", {}, "sha512-IaOQ9puYtjrkq7Y0Ygl9KDZnrf/aiUJYUpVf89y8kyaxbRG7Y1SrX/jaumrv81vc61+kiMempujsM3Yw7w5qcw=="],
|
"github-slugger": ["github-slugger@2.0.0", "", {}, "sha512-IaOQ9puYtjrkq7Y0Ygl9KDZnrf/aiUJYUpVf89y8kyaxbRG7Y1SrX/jaumrv81vc61+kiMempujsM3Yw7w5qcw=="],
|
||||||
|
|
||||||
"glob": ["glob@13.0.5", "", { "dependencies": { "minimatch": "^10.2.1", "minipass": "^7.1.2", "path-scurry": "^2.0.0" } }, "sha512-BzXxZg24Ibra1pbQ/zE7Kys4Ua1ks7Bn6pKLkVPZ9FZe4JQS6/Q7ef3LG1H+k7lUf5l4T3PLSyYyYJVYUvfgTw=="],
|
"glob": ["glob@13.0.5", "", { "dependencies": { "minimatch": "^10.2.1", "minipass": "^7.1.2", "path-scurry": "^2.0.0" } }, "sha512-BzXxZg24Ibra1pbQ/zE7Kys4Ua1ks7Bn6pKLkVPZ9FZe4JQS6/Q7ef3LG1H+k7lUf5l4T3PLSyYyYJVYUvfgTw=="],
|
||||||
@@ -3016,6 +3060,8 @@
|
|||||||
|
|
||||||
"has-tostringtag": ["has-tostringtag@1.0.2", "", { "dependencies": { "has-symbols": "^1.0.3" } }, "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw=="],
|
"has-tostringtag": ["has-tostringtag@1.0.2", "", { "dependencies": { "has-symbols": "^1.0.3" } }, "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw=="],
|
||||||
|
|
||||||
|
"has-unicode": ["has-unicode@2.0.1", "", {}, "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ=="],
|
||||||
|
|
||||||
"hasown": ["hasown@2.0.2", "", { "dependencies": { "function-bind": "^1.1.2" } }, "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ=="],
|
"hasown": ["hasown@2.0.2", "", { "dependencies": { "function-bind": "^1.1.2" } }, "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ=="],
|
||||||
|
|
||||||
"hast-util-embedded": ["hast-util-embedded@3.0.0", "", { "dependencies": { "@types/hast": "^3.0.0", "hast-util-is-element": "^3.0.0" } }, "sha512-naH8sld4Pe2ep03qqULEtvYr7EjrLK2QHY8KJR6RJkTUjPGObe1vnx585uzem2hGra+s1q08DZZpfgDVYRbaXA=="],
|
"hast-util-embedded": ["hast-util-embedded@3.0.0", "", { "dependencies": { "@types/hast": "^3.0.0", "hast-util-is-element": "^3.0.0" } }, "sha512-naH8sld4Pe2ep03qqULEtvYr7EjrLK2QHY8KJR6RJkTUjPGObe1vnx585uzem2hGra+s1q08DZZpfgDVYRbaXA=="],
|
||||||
@@ -3122,6 +3168,8 @@
|
|||||||
|
|
||||||
"indent-string": ["indent-string@4.0.0", "", {}, "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg=="],
|
"indent-string": ["indent-string@4.0.0", "", {}, "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg=="],
|
||||||
|
|
||||||
|
"infer-owner": ["infer-owner@1.0.4", "", {}, "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A=="],
|
||||||
|
|
||||||
"inflight": ["inflight@1.0.6", "", { "dependencies": { "once": "^1.3.0", "wrappy": "1" } }, "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA=="],
|
"inflight": ["inflight@1.0.6", "", { "dependencies": { "once": "^1.3.0", "wrappy": "1" } }, "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA=="],
|
||||||
|
|
||||||
"inherits": ["inherits@2.0.4", "", {}, "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="],
|
"inherits": ["inherits@2.0.4", "", {}, "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="],
|
||||||
@@ -3192,6 +3240,8 @@
|
|||||||
|
|
||||||
"is-interactive": ["is-interactive@1.0.0", "", {}, "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w=="],
|
"is-interactive": ["is-interactive@1.0.0", "", {}, "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w=="],
|
||||||
|
|
||||||
|
"is-lambda": ["is-lambda@1.0.1", "", {}, "sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ=="],
|
||||||
|
|
||||||
"is-map": ["is-map@2.0.3", "", {}, "sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw=="],
|
"is-map": ["is-map@2.0.3", "", {}, "sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw=="],
|
||||||
|
|
||||||
"is-negative-zero": ["is-negative-zero@2.0.3", "", {}, "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw=="],
|
"is-negative-zero": ["is-negative-zero@2.0.3", "", {}, "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw=="],
|
||||||
@@ -3408,7 +3458,7 @@
|
|||||||
|
|
||||||
"magicast": ["magicast@0.3.5", "", { "dependencies": { "@babel/parser": "^7.25.4", "@babel/types": "^7.25.4", "source-map-js": "^1.2.0" } }, "sha512-L0WhttDl+2BOsybvEOLK7fW3UA0OQ0IQ2d6Zl2x/a6vVRs3bAY0ECOSHHeL5jD+SbOpOCUEi0y1DgHEn9Qn1AQ=="],
|
"magicast": ["magicast@0.3.5", "", { "dependencies": { "@babel/parser": "^7.25.4", "@babel/types": "^7.25.4", "source-map-js": "^1.2.0" } }, "sha512-L0WhttDl+2BOsybvEOLK7fW3UA0OQ0IQ2d6Zl2x/a6vVRs3bAY0ECOSHHeL5jD+SbOpOCUEi0y1DgHEn9Qn1AQ=="],
|
||||||
|
|
||||||
"make-fetch-happen": ["make-fetch-happen@14.0.3", "", { "dependencies": { "@npmcli/agent": "^3.0.0", "cacache": "^19.0.1", "http-cache-semantics": "^4.1.1", "minipass": "^7.0.2", "minipass-fetch": "^4.0.0", "minipass-flush": "^1.0.5", "minipass-pipeline": "^1.2.4", "negotiator": "^1.0.0", "proc-log": "^5.0.0", "promise-retry": "^2.0.1", "ssri": "^12.0.0" } }, "sha512-QMjGbFTP0blj97EeidG5hk/QhKQ3T4ICckQGLgz38QF7Vgbk6e6FTARN8KhKxyBbWn8R0HU+bnw8aSoFPD4qtQ=="],
|
"make-fetch-happen": ["make-fetch-happen@9.1.0", "", { "dependencies": { "agentkeepalive": "^4.1.3", "cacache": "^15.2.0", "http-cache-semantics": "^4.1.0", "http-proxy-agent": "^4.0.1", "https-proxy-agent": "^5.0.0", "is-lambda": "^1.0.1", "lru-cache": "^6.0.0", "minipass": "^3.1.3", "minipass-collect": "^1.0.2", "minipass-fetch": "^1.3.2", "minipass-flush": "^1.0.5", "minipass-pipeline": "^1.2.4", "negotiator": "^0.6.2", "promise-retry": "^2.0.1", "socks-proxy-agent": "^6.0.0", "ssri": "^8.0.0" } }, "sha512-+zopwDy7DNknmwPQplem5lAZX/eCOzSvSNNcSKm5eVwTkOBzoktEfXsa9L23J/GIRhxRsaxzkPEhrJEpE2F4Gg=="],
|
||||||
|
|
||||||
"markdown-extensions": ["markdown-extensions@2.0.0", "", {}, "sha512-o5vL7aDWatOTX8LzaS1WMoaoxIiLRQJuIKKe2wAw6IeULDHaqbiqiggmx+pKvZDb1Sj+pE46Sn1T7lCqfFtg1Q=="],
|
"markdown-extensions": ["markdown-extensions@2.0.0", "", {}, "sha512-o5vL7aDWatOTX8LzaS1WMoaoxIiLRQJuIKKe2wAw6IeULDHaqbiqiggmx+pKvZDb1Sj+pE46Sn1T7lCqfFtg1Q=="],
|
||||||
|
|
||||||
@@ -3572,9 +3622,9 @@
|
|||||||
|
|
||||||
"minipass": ["minipass@7.1.2", "", {}, "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw=="],
|
"minipass": ["minipass@7.1.2", "", {}, "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw=="],
|
||||||
|
|
||||||
"minipass-collect": ["minipass-collect@2.0.1", "", { "dependencies": { "minipass": "^7.0.3" } }, "sha512-D7V8PO9oaz7PWGLbCACuI1qEOsq7UKfLotx/C0Aet43fCUB/wfQ7DYeq2oR/svFJGYDHPr38SHATeaj/ZoKHKw=="],
|
"minipass-collect": ["minipass-collect@1.0.2", "", { "dependencies": { "minipass": "^3.0.0" } }, "sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA=="],
|
||||||
|
|
||||||
"minipass-fetch": ["minipass-fetch@4.0.1", "", { "dependencies": { "minipass": "^7.0.3", "minipass-sized": "^1.0.3", "minizlib": "^3.0.1" }, "optionalDependencies": { "encoding": "^0.1.13" } }, "sha512-j7U11C5HXigVuutxebFadoYBbd7VSdZWggSe64NVdvWNBqGAiXPL2QVCehjmw7lY1oF9gOllYbORh+hiNgfPgQ=="],
|
"minipass-fetch": ["minipass-fetch@1.4.1", "", { "dependencies": { "minipass": "^3.1.0", "minipass-sized": "^1.0.3", "minizlib": "^2.0.0" }, "optionalDependencies": { "encoding": "^0.1.12" } }, "sha512-CGH1eblLq26Y15+Azk7ey4xh0J/XfJfrCox5LDJiKqI2Q2iwOLOKrlmIaODiSQS8d18jalF6y2K2ePUm0CmShw=="],
|
||||||
|
|
||||||
"minipass-flush": ["minipass-flush@1.0.5", "", { "dependencies": { "minipass": "^3.0.0" } }, "sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw=="],
|
"minipass-flush": ["minipass-flush@1.0.5", "", { "dependencies": { "minipass": "^3.0.0" } }, "sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw=="],
|
||||||
|
|
||||||
@@ -3586,6 +3636,8 @@
|
|||||||
|
|
||||||
"mkdirp": ["mkdirp@0.5.6", "", { "dependencies": { "minimist": "^1.2.6" }, "bin": { "mkdirp": "bin/cmd.js" } }, "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw=="],
|
"mkdirp": ["mkdirp@0.5.6", "", { "dependencies": { "minimist": "^1.2.6" }, "bin": { "mkdirp": "bin/cmd.js" } }, "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw=="],
|
||||||
|
|
||||||
|
"mkdirp-classic": ["mkdirp-classic@0.5.3", "", {}, "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A=="],
|
||||||
|
|
||||||
"morphdom": ["morphdom@2.7.8", "", {}, "sha512-D/fR4xgGUyVRbdMGU6Nejea1RFzYxYtyurG4Fbv2Fi/daKlWKuXGLOdXtl+3eIwL110cI2hz1ZojGICjjFLgTg=="],
|
"morphdom": ["morphdom@2.7.8", "", {}, "sha512-D/fR4xgGUyVRbdMGU6Nejea1RFzYxYtyurG4Fbv2Fi/daKlWKuXGLOdXtl+3eIwL110cI2hz1ZojGICjjFLgTg=="],
|
||||||
|
|
||||||
"motion": ["motion@12.34.5", "", { "dependencies": { "framer-motion": "^12.34.5", "tslib": "^2.4.0" }, "peerDependencies": { "@emotion/is-prop-valid": "*", "react": "^18.0.0 || ^19.0.0", "react-dom": "^18.0.0 || ^19.0.0" }, "optionalPeers": ["@emotion/is-prop-valid", "react", "react-dom"] }, "sha512-N06NLJ9IeBHeielRqIvYvjPfXuRdyTxa+9++BgpGa+hY2D7TcMkI6QzV3jaRuv0aZRXgMa7cPy9YcBUBisPzAQ=="],
|
"motion": ["motion@12.34.5", "", { "dependencies": { "framer-motion": "^12.34.5", "tslib": "^2.4.0" }, "peerDependencies": { "@emotion/is-prop-valid": "*", "react": "^18.0.0 || ^19.0.0", "react-dom": "^18.0.0 || ^19.0.0" }, "optionalPeers": ["@emotion/is-prop-valid", "react", "react-dom"] }, "sha512-N06NLJ9IeBHeielRqIvYvjPfXuRdyTxa+9++BgpGa+hY2D7TcMkI6QzV3jaRuv0aZRXgMa7cPy9YcBUBisPzAQ=="],
|
||||||
@@ -3616,6 +3668,8 @@
|
|||||||
|
|
||||||
"nanoid": ["nanoid@3.3.11", "", { "bin": { "nanoid": "bin/nanoid.cjs" } }, "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w=="],
|
"nanoid": ["nanoid@3.3.11", "", { "bin": { "nanoid": "bin/nanoid.cjs" } }, "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w=="],
|
||||||
|
|
||||||
|
"napi-build-utils": ["napi-build-utils@2.0.0", "", {}, "sha512-GEbrYkbfF7MoNaoh2iGG84Mnf/WZfB0GdGEsM8wz7Expx/LlWf5U8t9nvJKXSp3qr5IsEbK04cBGhol/KwOsWA=="],
|
||||||
|
|
||||||
"native-duplexpair": ["native-duplexpair@1.0.0", "", {}, "sha512-E7QQoM+3jvNtlmyfqRZ0/U75VFgCls+fSkbml2MpgWkWyz3ox8Y58gNhfuziuQYGNNQAbFZJQck55LHCnCK6CA=="],
|
"native-duplexpair": ["native-duplexpair@1.0.0", "", {}, "sha512-E7QQoM+3jvNtlmyfqRZ0/U75VFgCls+fSkbml2MpgWkWyz3ox8Y58gNhfuziuQYGNNQAbFZJQck55LHCnCK6CA=="],
|
||||||
|
|
||||||
"negotiator": ["negotiator@0.6.3", "", {}, "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg=="],
|
"negotiator": ["negotiator@0.6.3", "", {}, "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg=="],
|
||||||
@@ -3630,7 +3684,7 @@
|
|||||||
|
|
||||||
"no-case": ["no-case@3.0.4", "", { "dependencies": { "lower-case": "^2.0.2", "tslib": "^2.0.3" } }, "sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg=="],
|
"no-case": ["no-case@3.0.4", "", { "dependencies": { "lower-case": "^2.0.2", "tslib": "^2.0.3" } }, "sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg=="],
|
||||||
|
|
||||||
"node-abi": ["node-abi@4.26.0", "", { "dependencies": { "semver": "^7.6.3" } }, "sha512-8QwIZqikRvDIkXS2S93LjzhsSPJuIbfaMETWH+Bx8oOT9Sa9UsUtBFQlc3gBNd1+QINjaTloitXr1W3dQLi9Iw=="],
|
"node-abi": ["node-abi@3.87.0", "", { "dependencies": { "semver": "^7.3.5" } }, "sha512-+CGM1L1CgmtheLcBuleyYOn7NWPVu0s0EJH2C4puxgEZb9h8QpR9G2dBfZJOAUhi7VQxuBPMd0hiISWcTyiYyQ=="],
|
||||||
|
|
||||||
"node-addon-api": ["node-addon-api@7.1.1", "", {}, "sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ=="],
|
"node-addon-api": ["node-addon-api@7.1.1", "", {}, "sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ=="],
|
||||||
|
|
||||||
@@ -3642,7 +3696,7 @@
|
|||||||
|
|
||||||
"node-fetch-native": ["node-fetch-native@1.6.7", "", {}, "sha512-g9yhqoedzIUm0nTnTqAQvueMPVOuIY16bqgAJJC8XOOubYFNwz6IER9qs0Gq2Xd0+CecCKFjtdDTMA4u4xG06Q=="],
|
"node-fetch-native": ["node-fetch-native@1.6.7", "", {}, "sha512-g9yhqoedzIUm0nTnTqAQvueMPVOuIY16bqgAJJC8XOOubYFNwz6IER9qs0Gq2Xd0+CecCKFjtdDTMA4u4xG06Q=="],
|
||||||
|
|
||||||
"node-gyp": ["node-gyp@11.5.0", "", { "dependencies": { "env-paths": "^2.2.0", "exponential-backoff": "^3.1.1", "graceful-fs": "^4.2.6", "make-fetch-happen": "^14.0.3", "nopt": "^8.0.0", "proc-log": "^5.0.0", "semver": "^7.3.5", "tar": "^7.4.3", "tinyglobby": "^0.2.12", "which": "^5.0.0" }, "bin": { "node-gyp": "bin/node-gyp.js" } }, "sha512-ra7Kvlhxn5V9Slyus0ygMa2h+UqExPqUIkfk7Pc8QTLT956JLSy51uWFwHtIYy0vI8cB4BDhc/S03+880My/LQ=="],
|
"node-gyp": ["node-gyp@8.4.1", "", { "dependencies": { "env-paths": "^2.2.0", "glob": "^7.1.4", "graceful-fs": "^4.2.6", "make-fetch-happen": "^9.1.0", "nopt": "^5.0.0", "npmlog": "^6.0.0", "rimraf": "^3.0.2", "semver": "^7.3.5", "tar": "^6.1.2", "which": "^2.0.2" }, "bin": { "node-gyp": "bin/node-gyp.js" } }, "sha512-olTJRgUtAb/hOXG0E93wZDs5YiJlgbXxTwQAFHyNlRsXQnYzUaF2aGgujZbw+hR8aF4ZG/rST57bWMWD16jr9w=="],
|
||||||
|
|
||||||
"node-gyp-build": ["node-gyp-build@4.8.4", "", { "bin": { "node-gyp-build": "bin.js", "node-gyp-build-optional": "optional.js", "node-gyp-build-test": "build-test.js" } }, "sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ=="],
|
"node-gyp-build": ["node-gyp-build@4.8.4", "", { "bin": { "node-gyp-build": "bin.js", "node-gyp-build-optional": "optional.js", "node-gyp-build-test": "build-test.js" } }, "sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ=="],
|
||||||
|
|
||||||
@@ -3660,6 +3714,8 @@
|
|||||||
|
|
||||||
"npm-run-path": ["npm-run-path@5.3.0", "", { "dependencies": { "path-key": "^4.0.0" } }, "sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ=="],
|
"npm-run-path": ["npm-run-path@5.3.0", "", { "dependencies": { "path-key": "^4.0.0" } }, "sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ=="],
|
||||||
|
|
||||||
|
"npmlog": ["npmlog@6.0.2", "", { "dependencies": { "are-we-there-yet": "^3.0.0", "console-control-strings": "^1.1.0", "gauge": "^4.0.3", "set-blocking": "^2.0.0" } }, "sha512-/vBvz5Jfr9dT/aFWd0FIRf+T/Q2WBsLENygUaFUqstqsycmZAP/t5BvFJTK0viFmSUxiUKTUplWy5vt+rvKIxg=="],
|
||||||
|
|
||||||
"nth-check": ["nth-check@2.1.1", "", { "dependencies": { "boolbase": "^1.0.0" } }, "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w=="],
|
"nth-check": ["nth-check@2.1.1", "", { "dependencies": { "boolbase": "^1.0.0" } }, "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w=="],
|
||||||
|
|
||||||
"nypm": ["nypm@0.6.5", "", { "dependencies": { "citty": "^0.2.0", "pathe": "^2.0.3", "tinyexec": "^1.0.2" }, "bin": { "nypm": "dist/cli.mjs" } }, "sha512-K6AJy1GMVyfyMXRVB88700BJqNUkByijGJM8kEHpLdcAt+vSQAVfkWWHYzuRXHSY6xA2sNc5RjTj0p9rE2izVQ=="],
|
"nypm": ["nypm@0.6.5", "", { "dependencies": { "citty": "^0.2.0", "pathe": "^2.0.3", "tinyexec": "^1.0.2" }, "bin": { "nypm": "dist/cli.mjs" } }, "sha512-K6AJy1GMVyfyMXRVB88700BJqNUkByijGJM8kEHpLdcAt+vSQAVfkWWHYzuRXHSY6xA2sNc5RjTj0p9rE2izVQ=="],
|
||||||
@@ -3728,7 +3784,7 @@
|
|||||||
|
|
||||||
"p-locate": ["p-locate@4.1.0", "", { "dependencies": { "p-limit": "^2.2.0" } }, "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A=="],
|
"p-locate": ["p-locate@4.1.0", "", { "dependencies": { "p-limit": "^2.2.0" } }, "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A=="],
|
||||||
|
|
||||||
"p-map": ["p-map@7.0.4", "", {}, "sha512-tkAQEw8ysMzmkhgw8k+1U/iPhWNhykKnSk4Rd5zLoPJCuJaGRPo6YposrZgaxHKzDHdDWWZvE/Sk7hsL2X/CpQ=="],
|
"p-map": ["p-map@4.0.0", "", { "dependencies": { "aggregate-error": "^3.0.0" } }, "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ=="],
|
||||||
|
|
||||||
"p-queue": ["p-queue@8.1.1", "", { "dependencies": { "eventemitter3": "^5.0.1", "p-timeout": "^6.1.2" } }, "sha512-aNZ+VfjobsWryoiPnEApGGmf5WmNsCo9xu8dfaYamG5qaLP7ClhLN6NgsFe6SwJ2UbLEBK5dv9x8Mn5+RVhMWQ=="],
|
"p-queue": ["p-queue@8.1.1", "", { "dependencies": { "eventemitter3": "^5.0.1", "p-timeout": "^6.1.2" } }, "sha512-aNZ+VfjobsWryoiPnEApGGmf5WmNsCo9xu8dfaYamG5qaLP7ClhLN6NgsFe6SwJ2UbLEBK5dv9x8Mn5+RVhMWQ=="],
|
||||||
|
|
||||||
@@ -3860,6 +3916,8 @@
|
|||||||
|
|
||||||
"powershell-utils": ["powershell-utils@0.1.0", "", {}, "sha512-dM0jVuXJPsDN6DvRpea484tCUaMiXWjuCn++HGTqUWzGDjv5tZkEZldAJ/UMlqRYGFrD/etByo4/xOuC/snX2A=="],
|
"powershell-utils": ["powershell-utils@0.1.0", "", {}, "sha512-dM0jVuXJPsDN6DvRpea484tCUaMiXWjuCn++HGTqUWzGDjv5tZkEZldAJ/UMlqRYGFrD/etByo4/xOuC/snX2A=="],
|
||||||
|
|
||||||
|
"prebuild-install": ["prebuild-install@7.1.3", "", { "dependencies": { "detect-libc": "^2.0.0", "expand-template": "^2.0.3", "github-from-package": "0.0.0", "minimist": "^1.2.3", "mkdirp-classic": "^0.5.3", "napi-build-utils": "^2.0.0", "node-abi": "^3.3.0", "pump": "^3.0.0", "rc": "^1.2.7", "simple-get": "^4.0.0", "tar-fs": "^2.0.0", "tunnel-agent": "^0.6.0" }, "bin": { "prebuild-install": "bin.js" } }, "sha512-8Mf2cbV7x1cXPUILADGI3wuhfqWvtiLA1iclTDbFRZkgRQS0NqsPZphna9V+HyTEadheuPmjaJMsbzKQFOzLug=="],
|
||||||
|
|
||||||
"prettier": ["prettier@3.6.2", "", { "bin": { "prettier": "bin/prettier.cjs" } }, "sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ=="],
|
"prettier": ["prettier@3.6.2", "", { "bin": { "prettier": "bin/prettier.cjs" } }, "sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ=="],
|
||||||
|
|
||||||
"pretty": ["pretty@2.0.0", "", { "dependencies": { "condense-newlines": "^0.2.1", "extend-shallow": "^2.0.1", "js-beautify": "^1.6.12" } }, "sha512-G9xUchgTEiNpormdYBl+Pha50gOUovT18IvAe7EYMZ1/f9W/WWMPRn+xI68yXNMUk3QXHDwo/1wV/4NejVNe1w=="],
|
"pretty": ["pretty@2.0.0", "", { "dependencies": { "condense-newlines": "^0.2.1", "extend-shallow": "^2.0.1", "js-beautify": "^1.6.12" } }, "sha512-G9xUchgTEiNpormdYBl+Pha50gOUovT18IvAe7EYMZ1/f9W/WWMPRn+xI68yXNMUk3QXHDwo/1wV/4NejVNe1w=="],
|
||||||
@@ -3878,6 +3936,8 @@
|
|||||||
|
|
||||||
"progress": ["progress@2.0.3", "", {}, "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA=="],
|
"progress": ["progress@2.0.3", "", {}, "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA=="],
|
||||||
|
|
||||||
|
"promise-inflight": ["promise-inflight@1.0.1", "", {}, "sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g=="],
|
||||||
|
|
||||||
"promise-retry": ["promise-retry@2.0.1", "", { "dependencies": { "err-code": "^2.0.2", "retry": "^0.12.0" } }, "sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g=="],
|
"promise-retry": ["promise-retry@2.0.1", "", { "dependencies": { "err-code": "^2.0.2", "retry": "^0.12.0" } }, "sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g=="],
|
||||||
|
|
||||||
"promise.allsettled": ["promise.allsettled@1.0.7", "", { "dependencies": { "array.prototype.map": "^1.0.5", "call-bind": "^1.0.2", "define-properties": "^1.2.0", "es-abstract": "^1.22.1", "get-intrinsic": "^1.2.1", "iterate-value": "^1.0.2" } }, "sha512-hezvKvQQmsFkOdrZfYxUxkyxl8mgFQeT259Ajj9PXdbg9VzBCWrItOev72JyWxkCD5VSSqAeHmlN3tWx4DlmsA=="],
|
"promise.allsettled": ["promise.allsettled@1.0.7", "", { "dependencies": { "array.prototype.map": "^1.0.5", "call-bind": "^1.0.2", "define-properties": "^1.2.0", "es-abstract": "^1.22.1", "get-intrinsic": "^1.2.1", "iterate-value": "^1.0.2" } }, "sha512-hezvKvQQmsFkOdrZfYxUxkyxl8mgFQeT259Ajj9PXdbg9VzBCWrItOev72JyWxkCD5VSSqAeHmlN3tWx4DlmsA=="],
|
||||||
@@ -3916,6 +3976,8 @@
|
|||||||
|
|
||||||
"raw-body": ["raw-body@2.5.3", "", { "dependencies": { "bytes": "~3.1.2", "http-errors": "~2.0.1", "iconv-lite": "~0.4.24", "unpipe": "~1.0.0" } }, "sha512-s4VSOf6yN0rvbRZGxs8Om5CWj6seneMwK3oDb4lWDH0UPhWcxwOWw5+qk24bxq87szX1ydrwylIOp2uG1ojUpA=="],
|
"raw-body": ["raw-body@2.5.3", "", { "dependencies": { "bytes": "~3.1.2", "http-errors": "~2.0.1", "iconv-lite": "~0.4.24", "unpipe": "~1.0.0" } }, "sha512-s4VSOf6yN0rvbRZGxs8Om5CWj6seneMwK3oDb4lWDH0UPhWcxwOWw5+qk24bxq87szX1ydrwylIOp2uG1ojUpA=="],
|
||||||
|
|
||||||
|
"rc": ["rc@1.2.8", "", { "dependencies": { "deep-extend": "^0.6.0", "ini": "~1.3.0", "minimist": "^1.2.0", "strip-json-comments": "~2.0.1" }, "bin": { "rc": "./cli.js" } }, "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw=="],
|
||||||
|
|
||||||
"rc9": ["rc9@2.1.2", "", { "dependencies": { "defu": "^6.1.4", "destr": "^2.0.3" } }, "sha512-btXCnMmRIBINM2LDZoEmOogIZU7Qe7zn4BpomSKZ/ykbLObuBdvG+mFq11DL6fjH1DRwHhrlgtYWG96bJiC7Cg=="],
|
"rc9": ["rc9@2.1.2", "", { "dependencies": { "defu": "^6.1.4", "destr": "^2.0.3" } }, "sha512-btXCnMmRIBINM2LDZoEmOogIZU7Qe7zn4BpomSKZ/ykbLObuBdvG+mFq11DL6fjH1DRwHhrlgtYWG96bJiC7Cg=="],
|
||||||
|
|
||||||
"react": ["react@18.2.0", "", { "dependencies": { "loose-envify": "^1.1.0" } }, "sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ=="],
|
"react": ["react@18.2.0", "", { "dependencies": { "loose-envify": "^1.1.0" } }, "sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ=="],
|
||||||
@@ -4108,6 +4170,8 @@
|
|||||||
|
|
||||||
"serve-static": ["serve-static@1.16.3", "", { "dependencies": { "encodeurl": "~2.0.0", "escape-html": "~1.0.3", "parseurl": "~1.3.3", "send": "~0.19.1" } }, "sha512-x0RTqQel6g5SY7Lg6ZreMmsOzncHFU7nhnRWkKgWuMTu5NN0DR5oruckMqRvacAN9d5w6ARnRBXl9xhDCgfMeA=="],
|
"serve-static": ["serve-static@1.16.3", "", { "dependencies": { "encodeurl": "~2.0.0", "escape-html": "~1.0.3", "parseurl": "~1.3.3", "send": "~0.19.1" } }, "sha512-x0RTqQel6g5SY7Lg6ZreMmsOzncHFU7nhnRWkKgWuMTu5NN0DR5oruckMqRvacAN9d5w6ARnRBXl9xhDCgfMeA=="],
|
||||||
|
|
||||||
|
"set-blocking": ["set-blocking@2.0.0", "", {}, "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw=="],
|
||||||
|
|
||||||
"set-cookie-parser": ["set-cookie-parser@2.7.2", "", {}, "sha512-oeM1lpU/UvhTxw+g3cIfxXHyJRc/uidd3yK1P242gzHds0udQBYzs3y8j4gCCW+ZJ7ad0yctld8RYO+bdurlvw=="],
|
"set-cookie-parser": ["set-cookie-parser@2.7.2", "", {}, "sha512-oeM1lpU/UvhTxw+g3cIfxXHyJRc/uidd3yK1P242gzHds0udQBYzs3y8j4gCCW+ZJ7ad0yctld8RYO+bdurlvw=="],
|
||||||
|
|
||||||
"set-function-length": ["set-function-length@1.2.2", "", { "dependencies": { "define-data-property": "^1.1.4", "es-errors": "^1.3.0", "function-bind": "^1.1.2", "get-intrinsic": "^1.2.4", "gopd": "^1.0.1", "has-property-descriptors": "^1.0.2" } }, "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg=="],
|
"set-function-length": ["set-function-length@1.2.2", "", { "dependencies": { "define-data-property": "^1.1.4", "es-errors": "^1.3.0", "function-bind": "^1.1.2", "get-intrinsic": "^1.2.4", "gopd": "^1.0.1", "has-property-descriptors": "^1.0.2" } }, "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg=="],
|
||||||
@@ -4140,6 +4204,10 @@
|
|||||||
|
|
||||||
"signal-exit": ["signal-exit@4.1.0", "", {}, "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw=="],
|
"signal-exit": ["signal-exit@4.1.0", "", {}, "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw=="],
|
||||||
|
|
||||||
|
"simple-concat": ["simple-concat@1.0.1", "", {}, "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q=="],
|
||||||
|
|
||||||
|
"simple-get": ["simple-get@4.0.1", "", { "dependencies": { "decompress-response": "^6.0.0", "once": "^1.3.1", "simple-concat": "^1.0.0" } }, "sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA=="],
|
||||||
|
|
||||||
"simple-swizzle": ["simple-swizzle@0.2.4", "", { "dependencies": { "is-arrayish": "^0.3.1" } }, "sha512-nAu1WFPQSMNr2Zn9PGSZK9AGn4t/y97lEm+MXTtUDwfP0ksAIX4nO+6ruD9Jwut4C49SB1Ws+fbXsm/yScWOHw=="],
|
"simple-swizzle": ["simple-swizzle@0.2.4", "", { "dependencies": { "is-arrayish": "^0.3.1" } }, "sha512-nAu1WFPQSMNr2Zn9PGSZK9AGn4t/y97lEm+MXTtUDwfP0ksAIX4nO+6ruD9Jwut4C49SB1Ws+fbXsm/yScWOHw=="],
|
||||||
|
|
||||||
"simple-update-notifier": ["simple-update-notifier@2.0.0", "", { "dependencies": { "semver": "^7.5.3" } }, "sha512-a2B9Y0KlNXl9u/vsW6sTIu9vGEpfKu2wRV6l1H3XEas/0gUIzGzBoP/IouTcUQbm9JWZLH3COxyn03TYlFax6w=="],
|
"simple-update-notifier": ["simple-update-notifier@2.0.0", "", { "dependencies": { "semver": "^7.5.3" } }, "sha512-a2B9Y0KlNXl9u/vsW6sTIu9vGEpfKu2wRV6l1H3XEas/0gUIzGzBoP/IouTcUQbm9JWZLH3COxyn03TYlFax6w=="],
|
||||||
@@ -4164,7 +4232,7 @@
|
|||||||
|
|
||||||
"socks": ["socks@2.8.7", "", { "dependencies": { "ip-address": "^10.0.1", "smart-buffer": "^4.2.0" } }, "sha512-HLpt+uLy/pxB+bum/9DzAgiKS8CX1EvbWxI4zlmgGCExImLdiad2iCwXT5Z4c9c3Eq8rP2318mPW2c+QbtjK8A=="],
|
"socks": ["socks@2.8.7", "", { "dependencies": { "ip-address": "^10.0.1", "smart-buffer": "^4.2.0" } }, "sha512-HLpt+uLy/pxB+bum/9DzAgiKS8CX1EvbWxI4zlmgGCExImLdiad2iCwXT5Z4c9c3Eq8rP2318mPW2c+QbtjK8A=="],
|
||||||
|
|
||||||
"socks-proxy-agent": ["socks-proxy-agent@8.0.5", "", { "dependencies": { "agent-base": "^7.1.2", "debug": "^4.3.4", "socks": "^2.8.3" } }, "sha512-HehCEsotFqbPW9sJ8WVYB6UbmIMv7kUUORIF2Nncq4VQvBfNBLibW9YZR5dlYCSUhwcD628pRllm7n+E+YTzJw=="],
|
"socks-proxy-agent": ["socks-proxy-agent@6.2.1", "", { "dependencies": { "agent-base": "^6.0.2", "debug": "^4.3.3", "socks": "^2.6.2" } }, "sha512-a6KW9G+6B3nWZ1yB8G7pJwL3ggLy1uTzKAgCb7ttblwqdz9fMGJUuTy3uFzEP48FAs9FLILlmzDlE2JJhVQaXQ=="],
|
||||||
|
|
||||||
"solid-js": ["solid-js@1.9.10", "", { "dependencies": { "csstype": "^3.1.0", "seroval": "~1.3.0", "seroval-plugins": "~1.3.0" } }, "sha512-Coz956cos/EPDlhs6+jsdTxKuJDPT7B5SVIWgABwROyxjY7Xbr8wkzD68Et+NxnV7DLJ3nJdAC2r9InuV/4Jew=="],
|
"solid-js": ["solid-js@1.9.10", "", { "dependencies": { "csstype": "^3.1.0", "seroval": "~1.3.0", "seroval-plugins": "~1.3.0" } }, "sha512-Coz956cos/EPDlhs6+jsdTxKuJDPT7B5SVIWgABwROyxjY7Xbr8wkzD68Et+NxnV7DLJ3nJdAC2r9InuV/4Jew=="],
|
||||||
|
|
||||||
@@ -4194,11 +4262,13 @@
|
|||||||
|
|
||||||
"sprintf-js": ["sprintf-js@1.1.3", "", {}, "sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA=="],
|
"sprintf-js": ["sprintf-js@1.1.3", "", {}, "sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA=="],
|
||||||
|
|
||||||
|
"sqlite3": ["sqlite3@5.1.7", "", { "dependencies": { "bindings": "^1.5.0", "node-addon-api": "^7.0.0", "prebuild-install": "^7.1.1", "tar": "^6.1.11" }, "optionalDependencies": { "node-gyp": "8.x" } }, "sha512-GGIyOiFaG+TUra3JIfkI/zGP8yZYLPQ0pl1bH+ODjiX57sPhrLU5sQJn1y9bDKZUFYkX1crlrPfSYt0BKKdkog=="],
|
||||||
|
|
||||||
"sqlstring": ["sqlstring@2.3.3", "", {}, "sha512-qC9iz2FlN7DQl3+wjwn3802RTyjCx7sDvfQEXchwa6CWOx07/WVfh91gBmQ9fahw8snwGEWU3xGzOt4tFyHLxg=="],
|
"sqlstring": ["sqlstring@2.3.3", "", {}, "sha512-qC9iz2FlN7DQl3+wjwn3802RTyjCx7sDvfQEXchwa6CWOx07/WVfh91gBmQ9fahw8snwGEWU3xGzOt4tFyHLxg=="],
|
||||||
|
|
||||||
"srvx": ["srvx@0.9.8", "", { "bin": { "srvx": "bin/srvx.mjs" } }, "sha512-RZaxTKJEE/14HYn8COLuUOJAt0U55N9l1Xf6jj+T0GoA01EUH1Xz5JtSUOI+EHn+AEgPCVn7gk6jHJffrr06fQ=="],
|
"srvx": ["srvx@0.9.8", "", { "bin": { "srvx": "bin/srvx.mjs" } }, "sha512-RZaxTKJEE/14HYn8COLuUOJAt0U55N9l1Xf6jj+T0GoA01EUH1Xz5JtSUOI+EHn+AEgPCVn7gk6jHJffrr06fQ=="],
|
||||||
|
|
||||||
"ssri": ["ssri@12.0.0", "", { "dependencies": { "minipass": "^7.0.3" } }, "sha512-S7iGNosepx9RadX82oimUkvr0Ct7IjJbEbs4mJcTxst8um95J3sDYU1RBEOvdu6oL1Wek2ODI5i4MAw+dZ6cAQ=="],
|
"ssri": ["ssri@8.0.1", "", { "dependencies": { "minipass": "^3.1.1" } }, "sha512-97qShzy1AiyxvPNIkLWoGua7xoQzzPjQ0HAH4B0rWKo7SZ6USuPcrUiAFrws0UH8RrbWmgq3LMTObhPIHbbBeQ=="],
|
||||||
|
|
||||||
"sst": ["sst@3.18.10", "", { "dependencies": { "aws-sdk": "2.1692.0", "aws4fetch": "1.0.18", "jose": "5.2.3", "opencontrol": "0.0.6", "openid-client": "5.6.4" }, "optionalDependencies": { "sst-darwin-arm64": "3.18.10", "sst-darwin-x64": "3.18.10", "sst-linux-arm64": "3.18.10", "sst-linux-x64": "3.18.10", "sst-linux-x86": "3.18.10", "sst-win32-arm64": "3.18.10", "sst-win32-x64": "3.18.10", "sst-win32-x86": "3.18.10" }, "bin": { "sst": "bin/sst.mjs" } }, "sha512-SY+ldeJ9K5E9q+DhjXA3e2W3BEOzBwkE3IyLSD71uA3/5nRhUAST31iOWEpW36LbIvSQ9uOVDFcebztoLJ8s7w=="],
|
"sst": ["sst@3.18.10", "", { "dependencies": { "aws-sdk": "2.1692.0", "aws4fetch": "1.0.18", "jose": "5.2.3", "opencontrol": "0.0.6", "openid-client": "5.6.4" }, "optionalDependencies": { "sst-darwin-arm64": "3.18.10", "sst-darwin-x64": "3.18.10", "sst-linux-arm64": "3.18.10", "sst-linux-x64": "3.18.10", "sst-linux-x86": "3.18.10", "sst-win32-arm64": "3.18.10", "sst-win32-x64": "3.18.10", "sst-win32-x86": "3.18.10" }, "bin": { "sst": "bin/sst.mjs" } }, "sha512-SY+ldeJ9K5E9q+DhjXA3e2W3BEOzBwkE3IyLSD71uA3/5nRhUAST31iOWEpW36LbIvSQ9uOVDFcebztoLJ8s7w=="],
|
||||||
|
|
||||||
@@ -4266,6 +4336,8 @@
|
|||||||
|
|
||||||
"strip-indent": ["strip-indent@3.0.0", "", { "dependencies": { "min-indent": "^1.0.0" } }, "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ=="],
|
"strip-indent": ["strip-indent@3.0.0", "", { "dependencies": { "min-indent": "^1.0.0" } }, "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ=="],
|
||||||
|
|
||||||
|
"strip-json-comments": ["strip-json-comments@2.0.1", "", {}, "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ=="],
|
||||||
|
|
||||||
"stripe": ["stripe@18.0.0", "", { "dependencies": { "@types/node": ">=8.1.0", "qs": "^6.11.0" } }, "sha512-3Fs33IzKUby//9kCkCa1uRpinAoTvj6rJgQ2jrBEysoxEvfsclvXdna1amyEYbA2EKkjynuB4+L/kleCCaWTpA=="],
|
"stripe": ["stripe@18.0.0", "", { "dependencies": { "@types/node": ">=8.1.0", "qs": "^6.11.0" } }, "sha512-3Fs33IzKUby//9kCkCa1uRpinAoTvj6rJgQ2jrBEysoxEvfsclvXdna1amyEYbA2EKkjynuB4+L/kleCCaWTpA=="],
|
||||||
|
|
||||||
"strnum": ["strnum@1.1.2", "", {}, "sha512-vrN+B7DBIoTTZjnPNewwhx6cBA/H+IS7rfW68n7XxC1y7uoiGQBxaKzqucGUgavX15dJgiGztLJ8vxuEzwqBdA=="],
|
"strnum": ["strnum@1.1.2", "", {}, "sha512-vrN+B7DBIoTTZjnPNewwhx6cBA/H+IS7rfW68n7XxC1y7uoiGQBxaKzqucGUgavX15dJgiGztLJ8vxuEzwqBdA=="],
|
||||||
@@ -4298,6 +4370,8 @@
|
|||||||
|
|
||||||
"tar": ["tar@7.5.9", "", { "dependencies": { "@isaacs/fs-minipass": "^4.0.0", "chownr": "^3.0.0", "minipass": "^7.1.2", "minizlib": "^3.1.0", "yallist": "^5.0.0" } }, "sha512-BTLcK0xsDh2+PUe9F6c2TlRp4zOOBMTkoQHQIWSIzI0R7KG46uEwq4OPk2W7bZcprBMsuaeFsqwYr7pjh6CuHg=="],
|
"tar": ["tar@7.5.9", "", { "dependencies": { "@isaacs/fs-minipass": "^4.0.0", "chownr": "^3.0.0", "minipass": "^7.1.2", "minizlib": "^3.1.0", "yallist": "^5.0.0" } }, "sha512-BTLcK0xsDh2+PUe9F6c2TlRp4zOOBMTkoQHQIWSIzI0R7KG46uEwq4OPk2W7bZcprBMsuaeFsqwYr7pjh6CuHg=="],
|
||||||
|
|
||||||
|
"tar-fs": ["tar-fs@2.1.4", "", { "dependencies": { "chownr": "^1.1.1", "mkdirp-classic": "^0.5.2", "pump": "^3.0.0", "tar-stream": "^2.1.4" } }, "sha512-mDAjwmZdh7LTT6pNleZ05Yt65HC3E+NiQzl672vQG38jIrehtJk/J3mNwIg+vShQPcLF/LV7CMnDW6vjj6sfYQ=="],
|
||||||
|
|
||||||
"tar-stream": ["tar-stream@3.1.7", "", { "dependencies": { "b4a": "^1.6.4", "fast-fifo": "^1.2.0", "streamx": "^2.15.0" } }, "sha512-qJj60CXt7IU1Ffyc3NJMjh6EkuCFej46zUqJ4J7pqYlThyd9bO0XBTmcOIhSzZJVWfsLks0+nle/j538YAW9RQ=="],
|
"tar-stream": ["tar-stream@3.1.7", "", { "dependencies": { "b4a": "^1.6.4", "fast-fifo": "^1.2.0", "streamx": "^2.15.0" } }, "sha512-qJj60CXt7IU1Ffyc3NJMjh6EkuCFej46zUqJ4J7pqYlThyd9bO0XBTmcOIhSzZJVWfsLks0+nle/j538YAW9RQ=="],
|
||||||
|
|
||||||
"tarn": ["tarn@3.0.2", "", {}, "sha512-51LAVKUSZSVfI05vjPESNc5vwqqZpbXCsU+/+wxlOrUjk2SnFTt97v9ZgQrD4YmxYW1Px6w2KjaDitCfkvgxMQ=="],
|
"tarn": ["tarn@3.0.2", "", {}, "sha512-51LAVKUSZSVfI05vjPESNc5vwqqZpbXCsU+/+wxlOrUjk2SnFTt97v9ZgQrD4YmxYW1Px6w2KjaDitCfkvgxMQ=="],
|
||||||
@@ -4390,6 +4464,8 @@
|
|||||||
|
|
||||||
"tunnel": ["tunnel@0.0.6", "", {}, "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg=="],
|
"tunnel": ["tunnel@0.0.6", "", {}, "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg=="],
|
||||||
|
|
||||||
|
"tunnel-agent": ["tunnel-agent@0.6.0", "", { "dependencies": { "safe-buffer": "^5.0.1" } }, "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w=="],
|
||||||
|
|
||||||
"turbo": ["turbo@2.8.13", "", { "optionalDependencies": { "turbo-darwin-64": "2.8.13", "turbo-darwin-arm64": "2.8.13", "turbo-linux-64": "2.8.13", "turbo-linux-arm64": "2.8.13", "turbo-windows-64": "2.8.13", "turbo-windows-arm64": "2.8.13" }, "bin": { "turbo": "bin/turbo" } }, "sha512-nyM99hwFB9/DHaFyKEqatdayGjsMNYsQ/XBNO6MITc7roncZetKb97MpHxWf3uiU+LB9c9HUlU3Jp2Ixei2k1A=="],
|
"turbo": ["turbo@2.8.13", "", { "optionalDependencies": { "turbo-darwin-64": "2.8.13", "turbo-darwin-arm64": "2.8.13", "turbo-linux-64": "2.8.13", "turbo-linux-arm64": "2.8.13", "turbo-windows-64": "2.8.13", "turbo-windows-arm64": "2.8.13" }, "bin": { "turbo": "bin/turbo" } }, "sha512-nyM99hwFB9/DHaFyKEqatdayGjsMNYsQ/XBNO6MITc7roncZetKb97MpHxWf3uiU+LB9c9HUlU3Jp2Ixei2k1A=="],
|
||||||
|
|
||||||
"turbo-darwin-64": ["turbo-darwin-64@2.8.13", "", { "os": "darwin", "cpu": "x64" }, "sha512-PmOvodQNiOj77+Zwoqku70vwVjKzL34RTNxxoARjp5RU5FOj/CGiC6vcDQhNtFPUOWSAaogHF5qIka9TBhX4XA=="],
|
"turbo-darwin-64": ["turbo-darwin-64@2.8.13", "", { "os": "darwin", "cpu": "x64" }, "sha512-PmOvodQNiOj77+Zwoqku70vwVjKzL34RTNxxoARjp5RU5FOj/CGiC6vcDQhNtFPUOWSAaogHF5qIka9TBhX4XA=="],
|
||||||
@@ -4452,9 +4528,9 @@
|
|||||||
|
|
||||||
"unifont": ["unifont@0.5.2", "", { "dependencies": { "css-tree": "^3.0.0", "ofetch": "^1.4.1", "ohash": "^2.0.0" } }, "sha512-LzR4WUqzH9ILFvjLAUU7dK3Lnou/qd5kD+IakBtBK4S15/+x2y9VX+DcWQv6s551R6W+vzwgVS6tFg3XggGBgg=="],
|
"unifont": ["unifont@0.5.2", "", { "dependencies": { "css-tree": "^3.0.0", "ofetch": "^1.4.1", "ohash": "^2.0.0" } }, "sha512-LzR4WUqzH9ILFvjLAUU7dK3Lnou/qd5kD+IakBtBK4S15/+x2y9VX+DcWQv6s551R6W+vzwgVS6tFg3XggGBgg=="],
|
||||||
|
|
||||||
"unique-filename": ["unique-filename@4.0.0", "", { "dependencies": { "unique-slug": "^5.0.0" } }, "sha512-XSnEewXmQ+veP7xX2dS5Q4yZAvO40cBN2MWkJ7D/6sW4Dg6wYBNwM1Vrnz1FhH5AdeLIlUXRI9e28z1YZi71NQ=="],
|
"unique-filename": ["unique-filename@1.1.1", "", { "dependencies": { "unique-slug": "^2.0.0" } }, "sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ=="],
|
||||||
|
|
||||||
"unique-slug": ["unique-slug@5.0.0", "", { "dependencies": { "imurmurhash": "^0.1.4" } }, "sha512-9OdaqO5kwqR+1kVgHAhsp5vPNU0hnxRa26rBFNfNgM7M6pNtgzeBn3s/xbyCQL3dcjzOatcef6UUHpB/6MaETg=="],
|
"unique-slug": ["unique-slug@2.0.2", "", { "dependencies": { "imurmurhash": "^0.1.4" } }, "sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w=="],
|
||||||
|
|
||||||
"unist-util-find-after": ["unist-util-find-after@5.0.0", "", { "dependencies": { "@types/unist": "^3.0.0", "unist-util-is": "^6.0.0" } }, "sha512-amQa0Ep2m6hE2g72AugUItjbuM8X8cGQnFoHk0pGfrFeT9GZhzN5SW8nRsiGKK7Aif4CrACPENkA6P/Lw6fHGQ=="],
|
"unist-util-find-after": ["unist-util-find-after@5.0.0", "", { "dependencies": { "@types/unist": "^3.0.0", "unist-util-is": "^6.0.0" } }, "sha512-amQa0Ep2m6hE2g72AugUItjbuM8X8cGQnFoHk0pGfrFeT9GZhzN5SW8nRsiGKK7Aif4CrACPENkA6P/Lw6fHGQ=="],
|
||||||
|
|
||||||
@@ -4604,6 +4680,8 @@
|
|||||||
|
|
||||||
"why-is-node-running": ["why-is-node-running@3.2.2", "", { "bin": { "why-is-node-running": "cli.js" } }, "sha512-NKUzAelcoCXhXL4dJzKIwXeR8iEVqsA0Lq6Vnd0UXvgaKbzVo4ZTHROF2Jidrv+SgxOQ03fMinnNhzZATxOD3A=="],
|
"why-is-node-running": ["why-is-node-running@3.2.2", "", { "bin": { "why-is-node-running": "cli.js" } }, "sha512-NKUzAelcoCXhXL4dJzKIwXeR8iEVqsA0Lq6Vnd0UXvgaKbzVo4ZTHROF2Jidrv+SgxOQ03fMinnNhzZATxOD3A=="],
|
||||||
|
|
||||||
|
"wide-align": ["wide-align@1.1.5", "", { "dependencies": { "string-width": "^1.0.2 || 2 || 3 || 4" } }, "sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg=="],
|
||||||
|
|
||||||
"widest-line": ["widest-line@5.0.0", "", { "dependencies": { "string-width": "^7.0.0" } }, "sha512-c9bZp7b5YtRj2wOe6dlj32MK+Bx/M/d+9VB2SHM1OtsUHR0aV0tdP6DWh/iMt0kWi1t5g1Iudu6hQRNd1A4PVA=="],
|
"widest-line": ["widest-line@5.0.0", "", { "dependencies": { "string-width": "^7.0.0" } }, "sha512-c9bZp7b5YtRj2wOe6dlj32MK+Bx/M/d+9VB2SHM1OtsUHR0aV0tdP6DWh/iMt0kWi1t5g1Iudu6hQRNd1A4PVA=="],
|
||||||
|
|
||||||
"workerd": ["workerd@1.20251118.0", "", { "optionalDependencies": { "@cloudflare/workerd-darwin-64": "1.20251118.0", "@cloudflare/workerd-darwin-arm64": "1.20251118.0", "@cloudflare/workerd-linux-64": "1.20251118.0", "@cloudflare/workerd-linux-arm64": "1.20251118.0", "@cloudflare/workerd-windows-64": "1.20251118.0" }, "bin": { "workerd": "bin/workerd" } }, "sha512-Om5ns0Lyx/LKtYI04IV0bjIrkBgoFNg0p6urzr2asekJlfP18RqFzyqMFZKf0i9Gnjtz/JfAS/Ol6tjCe5JJsQ=="],
|
"workerd": ["workerd@1.20251118.0", "", { "optionalDependencies": { "@cloudflare/workerd-darwin-64": "1.20251118.0", "@cloudflare/workerd-darwin-arm64": "1.20251118.0", "@cloudflare/workerd-linux-64": "1.20251118.0", "@cloudflare/workerd-linux-arm64": "1.20251118.0", "@cloudflare/workerd-windows-64": "1.20251118.0" }, "bin": { "workerd": "bin/workerd" } }, "sha512-Om5ns0Lyx/LKtYI04IV0bjIrkBgoFNg0p6urzr2asekJlfP18RqFzyqMFZKf0i9Gnjtz/JfAS/Ol6tjCe5JJsQ=="],
|
||||||
@@ -4940,6 +5018,10 @@
|
|||||||
|
|
||||||
"@electron/rebuild/detect-libc": ["detect-libc@2.1.2", "", {}, "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ=="],
|
"@electron/rebuild/detect-libc": ["detect-libc@2.1.2", "", {}, "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ=="],
|
||||||
|
|
||||||
|
"@electron/rebuild/node-abi": ["node-abi@4.26.0", "", { "dependencies": { "semver": "^7.6.3" } }, "sha512-8QwIZqikRvDIkXS2S93LjzhsSPJuIbfaMETWH+Bx8oOT9Sa9UsUtBFQlc3gBNd1+QINjaTloitXr1W3dQLi9Iw=="],
|
||||||
|
|
||||||
|
"@electron/rebuild/node-gyp": ["node-gyp@11.5.0", "", { "dependencies": { "env-paths": "^2.2.0", "exponential-backoff": "^3.1.1", "graceful-fs": "^4.2.6", "make-fetch-happen": "^14.0.3", "nopt": "^8.0.0", "proc-log": "^5.0.0", "semver": "^7.3.5", "tar": "^7.4.3", "tinyglobby": "^0.2.12", "which": "^5.0.0" }, "bin": { "node-gyp": "bin/node-gyp.js" } }, "sha512-ra7Kvlhxn5V9Slyus0ygMa2h+UqExPqUIkfk7Pc8QTLT956JLSy51uWFwHtIYy0vI8cB4BDhc/S03+880My/LQ=="],
|
||||||
|
|
||||||
"@electron/rebuild/yargs": ["yargs@17.7.2", "", { "dependencies": { "cliui": "^8.0.1", "escalade": "^3.1.1", "get-caller-file": "^2.0.5", "require-directory": "^2.1.1", "string-width": "^4.2.3", "y18n": "^5.0.5", "yargs-parser": "^21.1.1" } }, "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w=="],
|
"@electron/rebuild/yargs": ["yargs@17.7.2", "", { "dependencies": { "cliui": "^8.0.1", "escalade": "^3.1.1", "get-caller-file": "^2.0.5", "require-directory": "^2.1.1", "string-width": "^4.2.3", "y18n": "^5.0.5", "yargs-parser": "^21.1.1" } }, "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w=="],
|
||||||
|
|
||||||
"@electron/universal/fs-extra": ["fs-extra@11.3.3", "", { "dependencies": { "graceful-fs": "^4.2.0", "jsonfile": "^6.0.1", "universalify": "^2.0.0" } }, "sha512-VWSRii4t0AFm6ixFFmLLx1t7wS1gh+ckoa84aOeapGum0h+EZd1EhEumSB+ZdDLnEPuucsVB9oB7cxJHap6Afg=="],
|
"@electron/universal/fs-extra": ["fs-extra@11.3.3", "", { "dependencies": { "graceful-fs": "^4.2.0", "jsonfile": "^6.0.1", "universalify": "^2.0.0" } }, "sha512-VWSRii4t0AFm6ixFFmLLx1t7wS1gh+ckoa84aOeapGum0h+EZd1EhEumSB+ZdDLnEPuucsVB9oB7cxJHap6Afg=="],
|
||||||
@@ -4958,6 +5040,8 @@
|
|||||||
|
|
||||||
"@hey-api/openapi-ts/semver": ["semver@7.7.3", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q=="],
|
"@hey-api/openapi-ts/semver": ["semver@7.7.3", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q=="],
|
||||||
|
|
||||||
|
"@hono/node-ws/ws": ["ws@8.19.0", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": ">=5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-blAT2mjOEIi0ZzruJfIhb3nps74PRWTCz1IjglWEEpQl5XS/UNama6u2/rjFkDDouqr4L67ry+1aGIALViWjDg=="],
|
||||||
|
|
||||||
"@hono/zod-validator/zod": ["zod@3.25.76", "", {}, "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ=="],
|
"@hono/zod-validator/zod": ["zod@3.25.76", "", {}, "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ=="],
|
||||||
|
|
||||||
"@jimp/plugin-blit/zod": ["zod@3.25.76", "", {}, "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ=="],
|
"@jimp/plugin-blit/zod": ["zod@3.25.76", "", {}, "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ=="],
|
||||||
@@ -5006,6 +5090,8 @@
|
|||||||
|
|
||||||
"@mdx-js/mdx/source-map": ["source-map@0.7.6", "", {}, "sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ=="],
|
"@mdx-js/mdx/source-map": ["source-map@0.7.6", "", {}, "sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ=="],
|
||||||
|
|
||||||
|
"@modelcontextprotocol/sdk/@hono/node-server": ["@hono/node-server@1.19.9", "", { "peerDependencies": { "hono": "^4" } }, "sha512-vHL6w3ecZsky+8P5MD+eFfaGTyCeOHUIFYMGpQGbrBTSmNNoxv0if69rEZ5giu36weC5saFuznL411gRX7bJDw=="],
|
||||||
|
|
||||||
"@modelcontextprotocol/sdk/express": ["express@5.2.1", "", { "dependencies": { "accepts": "^2.0.0", "body-parser": "^2.2.1", "content-disposition": "^1.0.0", "content-type": "^1.0.5", "cookie": "^0.7.1", "cookie-signature": "^1.2.1", "debug": "^4.4.0", "depd": "^2.0.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" } }, "sha512-hIS4idWWai69NezIdRt2xFVofaF4j+6INOpJlVOLDO8zXGpUVEVzIYk12UUi2JzjEzWL3IOAxcTubgz9Po0yXw=="],
|
"@modelcontextprotocol/sdk/express": ["express@5.2.1", "", { "dependencies": { "accepts": "^2.0.0", "body-parser": "^2.2.1", "content-disposition": "^1.0.0", "content-type": "^1.0.5", "cookie": "^0.7.1", "cookie-signature": "^1.2.1", "debug": "^4.4.0", "depd": "^2.0.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" } }, "sha512-hIS4idWWai69NezIdRt2xFVofaF4j+6INOpJlVOLDO8zXGpUVEVzIYk12UUi2JzjEzWL3IOAxcTubgz9Po0yXw=="],
|
||||||
|
|
||||||
"@modelcontextprotocol/sdk/jose": ["jose@6.1.3", "", {}, "sha512-0TpaTfihd4QMNwrz/ob2Bp7X04yuxJkjRGi4aKmOqwhov54i6u79oCv7T+C7lo70MKH6BesI3vscD1yb/yzKXQ=="],
|
"@modelcontextprotocol/sdk/jose": ["jose@6.1.3", "", {}, "sha512-0TpaTfihd4QMNwrz/ob2Bp7X04yuxJkjRGi4aKmOqwhov54i6u79oCv7T+C7lo70MKH6BesI3vscD1yb/yzKXQ=="],
|
||||||
@@ -5016,6 +5102,12 @@
|
|||||||
|
|
||||||
"@npmcli/agent/lru-cache": ["lru-cache@10.4.3", "", {}, "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ=="],
|
"@npmcli/agent/lru-cache": ["lru-cache@10.4.3", "", {}, "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ=="],
|
||||||
|
|
||||||
|
"@npmcli/agent/socks-proxy-agent": ["socks-proxy-agent@8.0.5", "", { "dependencies": { "agent-base": "^7.1.2", "debug": "^4.3.4", "socks": "^2.8.3" } }, "sha512-HehCEsotFqbPW9sJ8WVYB6UbmIMv7kUUORIF2Nncq4VQvBfNBLibW9YZR5dlYCSUhwcD628pRllm7n+E+YTzJw=="],
|
||||||
|
|
||||||
|
"@npmcli/move-file/mkdirp": ["mkdirp@1.0.4", "", { "bin": { "mkdirp": "bin/cmd.js" } }, "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw=="],
|
||||||
|
|
||||||
|
"@npmcli/move-file/rimraf": ["rimraf@3.0.2", "", { "dependencies": { "glob": "^7.1.3" }, "bin": { "rimraf": "bin.js" } }, "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA=="],
|
||||||
|
|
||||||
"@octokit/auth-app/@octokit/request": ["@octokit/request@10.0.7", "", { "dependencies": { "@octokit/endpoint": "^11.0.2", "@octokit/request-error": "^7.0.2", "@octokit/types": "^16.0.0", "fast-content-type-parse": "^3.0.0", "universal-user-agent": "^7.0.2" } }, "sha512-v93h0i1yu4idj8qFPZwjehoJx4j3Ntn+JhXsdJrG9pYaX6j/XRz2RmasMUHtNgQD39nrv/VwTWSqK0RNXR8upA=="],
|
"@octokit/auth-app/@octokit/request": ["@octokit/request@10.0.7", "", { "dependencies": { "@octokit/endpoint": "^11.0.2", "@octokit/request-error": "^7.0.2", "@octokit/types": "^16.0.0", "fast-content-type-parse": "^3.0.0", "universal-user-agent": "^7.0.2" } }, "sha512-v93h0i1yu4idj8qFPZwjehoJx4j3Ntn+JhXsdJrG9pYaX6j/XRz2RmasMUHtNgQD39nrv/VwTWSqK0RNXR8upA=="],
|
||||||
|
|
||||||
"@octokit/auth-app/@octokit/request-error": ["@octokit/request-error@7.1.0", "", { "dependencies": { "@octokit/types": "^16.0.0" } }, "sha512-KMQIfq5sOPpkQYajXHwnhjCC0slzCNScLHs9JafXc4RAJI+9f+jNDlBNaIMTvazOPLgb4BnlhGJOTbnN0wIjPw=="],
|
"@octokit/auth-app/@octokit/request-error": ["@octokit/request-error@7.1.0", "", { "dependencies": { "@octokit/types": "^16.0.0" } }, "sha512-KMQIfq5sOPpkQYajXHwnhjCC0slzCNScLHs9JafXc4RAJI+9f+jNDlBNaIMTvazOPLgb4BnlhGJOTbnN0wIjPw=="],
|
||||||
@@ -5212,6 +5304,8 @@
|
|||||||
|
|
||||||
"archiver-utils/is-stream": ["is-stream@2.0.1", "", {}, "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg=="],
|
"archiver-utils/is-stream": ["is-stream@2.0.1", "", {}, "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg=="],
|
||||||
|
|
||||||
|
"are-we-there-yet/readable-stream": ["readable-stream@3.6.2", "", { "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", "util-deprecate": "^1.0.1" } }, "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA=="],
|
||||||
|
|
||||||
"astro/@astrojs/internal-helpers": ["@astrojs/internal-helpers@0.6.1", "", {}, "sha512-l5Pqf6uZu31aG+3Lv8nl/3s4DbUzdlxTWDof4pEpto6GUJNhhCbelVi9dEyurOVyqaelwmS9oSyOWOENSfgo9A=="],
|
"astro/@astrojs/internal-helpers": ["@astrojs/internal-helpers@0.6.1", "", {}, "sha512-l5Pqf6uZu31aG+3Lv8nl/3s4DbUzdlxTWDof4pEpto6GUJNhhCbelVi9dEyurOVyqaelwmS9oSyOWOENSfgo9A=="],
|
||||||
|
|
||||||
"astro/diff": ["diff@5.2.2", "", {}, "sha512-vtcDfH3TOjP8UekytvnHH1o1P4FcUdt4eQ1Y+Abap1tk/OB2MWQvcwS2ClCd1zuIhc3JKOx6p3kod8Vfys3E+A=="],
|
"astro/diff": ["diff@5.2.2", "", {}, "sha512-vtcDfH3TOjP8UekytvnHH1o1P4FcUdt4eQ1Y+Abap1tk/OB2MWQvcwS2ClCd1zuIhc3JKOx6p3kod8Vfys3E+A=="],
|
||||||
@@ -5250,9 +5344,19 @@
|
|||||||
|
|
||||||
"c12/dotenv": ["dotenv@17.3.1", "", {}, "sha512-IO8C/dzEb6O3F9/twg6ZLXz164a2fhTnEWb95H23Dm4OuN+92NmEAlTrupP9VW6Jm3sO26tQlqyvyi4CsnY9GA=="],
|
"c12/dotenv": ["dotenv@17.3.1", "", {}, "sha512-IO8C/dzEb6O3F9/twg6ZLXz164a2fhTnEWb95H23Dm4OuN+92NmEAlTrupP9VW6Jm3sO26tQlqyvyi4CsnY9GA=="],
|
||||||
|
|
||||||
"cacache/glob": ["glob@10.5.0", "", { "dependencies": { "foreground-child": "^3.1.0", "jackspeak": "^3.1.2", "minimatch": "^9.0.4", "minipass": "^7.1.2", "package-json-from-dist": "^1.0.0", "path-scurry": "^1.11.1" }, "bin": { "glob": "dist/esm/bin.mjs" } }, "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg=="],
|
"cacache/chownr": ["chownr@2.0.0", "", {}, "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ=="],
|
||||||
|
|
||||||
"cacache/lru-cache": ["lru-cache@10.4.3", "", {}, "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ=="],
|
"cacache/glob": ["glob@7.2.3", "", { "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", "minimatch": "^3.1.1", "once": "^1.3.0", "path-is-absolute": "^1.0.0" } }, "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q=="],
|
||||||
|
|
||||||
|
"cacache/lru-cache": ["lru-cache@6.0.0", "", { "dependencies": { "yallist": "^4.0.0" } }, "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA=="],
|
||||||
|
|
||||||
|
"cacache/minipass": ["minipass@3.3.6", "", { "dependencies": { "yallist": "^4.0.0" } }, "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw=="],
|
||||||
|
|
||||||
|
"cacache/mkdirp": ["mkdirp@1.0.4", "", { "bin": { "mkdirp": "bin/cmd.js" } }, "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw=="],
|
||||||
|
|
||||||
|
"cacache/rimraf": ["rimraf@3.0.2", "", { "dependencies": { "glob": "^7.1.3" }, "bin": { "rimraf": "bin.js" } }, "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA=="],
|
||||||
|
|
||||||
|
"cacache/tar": ["tar@6.2.1", "", { "dependencies": { "chownr": "^2.0.0", "fs-minipass": "^2.0.0", "minipass": "^5.0.0", "minizlib": "^2.1.1", "mkdirp": "^1.0.3", "yallist": "^4.0.0" } }, "sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A=="],
|
||||||
|
|
||||||
"cli-truncate/string-width": ["string-width@4.2.3", "", { "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" } }, "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g=="],
|
"cli-truncate/string-width": ["string-width@4.2.3", "", { "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" } }, "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g=="],
|
||||||
|
|
||||||
@@ -5334,6 +5438,14 @@
|
|||||||
|
|
||||||
"fs-extra/jsonfile": ["jsonfile@6.2.0", "", { "dependencies": { "universalify": "^2.0.0" }, "optionalDependencies": { "graceful-fs": "^4.1.6" } }, "sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg=="],
|
"fs-extra/jsonfile": ["jsonfile@6.2.0", "", { "dependencies": { "universalify": "^2.0.0" }, "optionalDependencies": { "graceful-fs": "^4.1.6" } }, "sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg=="],
|
||||||
|
|
||||||
|
"fs-minipass/minipass": ["minipass@3.3.6", "", { "dependencies": { "yallist": "^4.0.0" } }, "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw=="],
|
||||||
|
|
||||||
|
"gauge/signal-exit": ["signal-exit@3.0.7", "", {}, "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ=="],
|
||||||
|
|
||||||
|
"gauge/string-width": ["string-width@4.2.3", "", { "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" } }, "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g=="],
|
||||||
|
|
||||||
|
"gauge/strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="],
|
||||||
|
|
||||||
"gaxios/node-fetch": ["node-fetch@3.3.2", "", { "dependencies": { "data-uri-to-buffer": "^4.0.0", "fetch-blob": "^3.1.4", "formdata-polyfill": "^4.0.10" } }, "sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA=="],
|
"gaxios/node-fetch": ["node-fetch@3.3.2", "", { "dependencies": { "data-uri-to-buffer": "^4.0.0", "fetch-blob": "^3.1.4", "formdata-polyfill": "^4.0.10" } }, "sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA=="],
|
||||||
|
|
||||||
"glob/minimatch": ["minimatch@10.2.1", "", { "dependencies": { "brace-expansion": "^5.0.2" } }, "sha512-MClCe8IL5nRRmawL6ib/eT4oLyeKMGCghibcDWK+J0hh0Q8kqSdia6BvbRMVk6mPa6WqUa5uR2oxt6C5jd533A=="],
|
"glob/minimatch": ["minimatch@10.2.1", "", { "dependencies": { "brace-expansion": "^5.0.2" } }, "sha512-MClCe8IL5nRRmawL6ib/eT4oLyeKMGCghibcDWK+J0hh0Q8kqSdia6BvbRMVk6mPa6WqUa5uR2oxt6C5jd533A=="],
|
||||||
@@ -5366,7 +5478,13 @@
|
|||||||
|
|
||||||
"log-symbols/chalk": ["chalk@4.1.2", "", { "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA=="],
|
"log-symbols/chalk": ["chalk@4.1.2", "", { "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA=="],
|
||||||
|
|
||||||
"make-fetch-happen/negotiator": ["negotiator@1.0.0", "", {}, "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg=="],
|
"make-fetch-happen/http-proxy-agent": ["http-proxy-agent@4.0.1", "", { "dependencies": { "@tootallnate/once": "1", "agent-base": "6", "debug": "4" } }, "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg=="],
|
||||||
|
|
||||||
|
"make-fetch-happen/https-proxy-agent": ["https-proxy-agent@5.0.1", "", { "dependencies": { "agent-base": "6", "debug": "4" } }, "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA=="],
|
||||||
|
|
||||||
|
"make-fetch-happen/lru-cache": ["lru-cache@6.0.0", "", { "dependencies": { "yallist": "^4.0.0" } }, "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA=="],
|
||||||
|
|
||||||
|
"make-fetch-happen/minipass": ["minipass@3.3.6", "", { "dependencies": { "yallist": "^4.0.0" } }, "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw=="],
|
||||||
|
|
||||||
"matcher/escape-string-regexp": ["escape-string-regexp@4.0.0", "", {}, "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA=="],
|
"matcher/escape-string-regexp": ["escape-string-regexp@4.0.0", "", {}, "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA=="],
|
||||||
|
|
||||||
@@ -5382,6 +5500,12 @@
|
|||||||
|
|
||||||
"miniflare/zod": ["zod@3.22.3", "", {}, "sha512-EjIevzuJRiRPbVH4mGc8nApb/lVLKVpmUhAaR5R5doKGfAnGJ6Gr3CViAVjP+4FWSxCsybeWQdcgCtbX+7oZug=="],
|
"miniflare/zod": ["zod@3.22.3", "", {}, "sha512-EjIevzuJRiRPbVH4mGc8nApb/lVLKVpmUhAaR5R5doKGfAnGJ6Gr3CViAVjP+4FWSxCsybeWQdcgCtbX+7oZug=="],
|
||||||
|
|
||||||
|
"minipass-collect/minipass": ["minipass@3.3.6", "", { "dependencies": { "yallist": "^4.0.0" } }, "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw=="],
|
||||||
|
|
||||||
|
"minipass-fetch/minipass": ["minipass@3.3.6", "", { "dependencies": { "yallist": "^4.0.0" } }, "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw=="],
|
||||||
|
|
||||||
|
"minipass-fetch/minizlib": ["minizlib@2.1.2", "", { "dependencies": { "minipass": "^3.0.0", "yallist": "^4.0.0" } }, "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg=="],
|
||||||
|
|
||||||
"minipass-flush/minipass": ["minipass@3.3.6", "", { "dependencies": { "yallist": "^4.0.0" } }, "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw=="],
|
"minipass-flush/minipass": ["minipass@3.3.6", "", { "dependencies": { "yallist": "^4.0.0" } }, "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw=="],
|
||||||
|
|
||||||
"minipass-pipeline/minipass": ["minipass@3.3.6", "", { "dependencies": { "yallist": "^4.0.0" } }, "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw=="],
|
"minipass-pipeline/minipass": ["minipass@3.3.6", "", { "dependencies": { "yallist": "^4.0.0" } }, "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw=="],
|
||||||
@@ -5394,9 +5518,15 @@
|
|||||||
|
|
||||||
"nitro/h3": ["h3@2.0.1-rc.5", "", { "dependencies": { "rou3": "^0.7.9", "srvx": "^0.9.1" }, "peerDependencies": { "crossws": "^0.4.1" }, "optionalPeers": ["crossws"] }, "sha512-qkohAzCab0nLzXNm78tBjZDvtKMTmtygS8BJLT3VPczAQofdqlFXDPkXdLMJN4r05+xqneG8snZJ0HgkERCZTg=="],
|
"nitro/h3": ["h3@2.0.1-rc.5", "", { "dependencies": { "rou3": "^0.7.9", "srvx": "^0.9.1" }, "peerDependencies": { "crossws": "^0.4.1" }, "optionalPeers": ["crossws"] }, "sha512-qkohAzCab0nLzXNm78tBjZDvtKMTmtygS8BJLT3VPczAQofdqlFXDPkXdLMJN4r05+xqneG8snZJ0HgkERCZTg=="],
|
||||||
|
|
||||||
"node-gyp/nopt": ["nopt@8.1.0", "", { "dependencies": { "abbrev": "^3.0.0" }, "bin": { "nopt": "bin/nopt.js" } }, "sha512-ieGu42u/Qsa4TFktmaKEwM6MQH0pOWnaB3htzh0JRtx84+Mebc0cbZYN5bC+6WTZ4+77xrL9Pn5m7CV6VIkV7A=="],
|
"node-gyp/glob": ["glob@7.2.3", "", { "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", "minimatch": "^3.1.1", "once": "^1.3.0", "path-is-absolute": "^1.0.0" } }, "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q=="],
|
||||||
|
|
||||||
"node-gyp/which": ["which@5.0.0", "", { "dependencies": { "isexe": "^3.1.1" }, "bin": { "node-which": "bin/which.js" } }, "sha512-JEdGzHwwkrbWoGOlIHqQ5gtprKGOenpDHpxE9zVR1bWbOtYRyPPHMe9FaP6x61CmNaTThSkb0DAJte5jD+DmzQ=="],
|
"node-gyp/nopt": ["nopt@5.0.0", "", { "dependencies": { "abbrev": "1" }, "bin": { "nopt": "bin/nopt.js" } }, "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ=="],
|
||||||
|
|
||||||
|
"node-gyp/rimraf": ["rimraf@3.0.2", "", { "dependencies": { "glob": "^7.1.3" }, "bin": { "rimraf": "bin.js" } }, "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA=="],
|
||||||
|
|
||||||
|
"node-gyp/tar": ["tar@6.2.1", "", { "dependencies": { "chownr": "^2.0.0", "fs-minipass": "^2.0.0", "minipass": "^5.0.0", "minizlib": "^2.1.1", "mkdirp": "^1.0.3", "yallist": "^4.0.0" } }, "sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A=="],
|
||||||
|
|
||||||
|
"node-gyp/which": ["which@2.0.2", "", { "dependencies": { "isexe": "^2.0.0" }, "bin": { "node-which": "./bin/node-which" } }, "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA=="],
|
||||||
|
|
||||||
"npm-run-path/path-key": ["path-key@4.0.0", "", {}, "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ=="],
|
"npm-run-path/path-key": ["path-key@4.0.0", "", {}, "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ=="],
|
||||||
|
|
||||||
@@ -5454,6 +5584,8 @@
|
|||||||
|
|
||||||
"postject/commander": ["commander@9.5.0", "", {}, "sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ=="],
|
"postject/commander": ["commander@9.5.0", "", {}, "sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ=="],
|
||||||
|
|
||||||
|
"prebuild-install/detect-libc": ["detect-libc@2.1.2", "", {}, "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ=="],
|
||||||
|
|
||||||
"pretty-format/ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="],
|
"pretty-format/ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="],
|
||||||
|
|
||||||
"pretty-format/ansi-styles": ["ansi-styles@5.2.0", "", {}, "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA=="],
|
"pretty-format/ansi-styles": ["ansi-styles@5.2.0", "", {}, "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA=="],
|
||||||
@@ -5494,6 +5626,12 @@
|
|||||||
|
|
||||||
"sitemap/sax": ["sax@1.4.4", "", {}, "sha512-1n3r/tGXO6b6VXMdFT54SHzT9ytu9yr7TaELowdYpMqY/Ao7EnlQGmAQ1+RatX7Tkkdm6hONI2owqNx2aZj5Sw=="],
|
"sitemap/sax": ["sax@1.4.4", "", {}, "sha512-1n3r/tGXO6b6VXMdFT54SHzT9ytu9yr7TaELowdYpMqY/Ao7EnlQGmAQ1+RatX7Tkkdm6hONI2owqNx2aZj5Sw=="],
|
||||||
|
|
||||||
|
"socks-proxy-agent/agent-base": ["agent-base@6.0.2", "", { "dependencies": { "debug": "4" } }, "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ=="],
|
||||||
|
|
||||||
|
"sqlite3/tar": ["tar@6.2.1", "", { "dependencies": { "chownr": "^2.0.0", "fs-minipass": "^2.0.0", "minipass": "^5.0.0", "minizlib": "^2.1.1", "mkdirp": "^1.0.3", "yallist": "^4.0.0" } }, "sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A=="],
|
||||||
|
|
||||||
|
"ssri/minipass": ["minipass@3.3.6", "", { "dependencies": { "yallist": "^4.0.0" } }, "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw=="],
|
||||||
|
|
||||||
"sst/aws4fetch": ["aws4fetch@1.0.18", "", {}, "sha512-3Cf+YaUl07p24MoQ46rFwulAmiyCwH2+1zw1ZyPAX5OtJ34Hh185DwB8y/qRLb6cYYYtSFJ9pthyLc0MD4e8sQ=="],
|
"sst/aws4fetch": ["aws4fetch@1.0.18", "", {}, "sha512-3Cf+YaUl07p24MoQ46rFwulAmiyCwH2+1zw1ZyPAX5OtJ34Hh185DwB8y/qRLb6cYYYtSFJ9pthyLc0MD4e8sQ=="],
|
||||||
|
|
||||||
"sst/jose": ["jose@5.2.3", "", {}, "sha512-KUXdbctm1uHVL8BYhnyHkgp3zDX5KW8ZhAKVFEfUbU2P8Alpzjb+48hHvjOdQIyPshoblhzsuqOwEEAbtHVirA=="],
|
"sst/jose": ["jose@5.2.3", "", {}, "sha512-KUXdbctm1uHVL8BYhnyHkgp3zDX5KW8ZhAKVFEfUbU2P8Alpzjb+48hHvjOdQIyPshoblhzsuqOwEEAbtHVirA=="],
|
||||||
@@ -5514,6 +5652,10 @@
|
|||||||
|
|
||||||
"tar/yallist": ["yallist@5.0.0", "", {}, "sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw=="],
|
"tar/yallist": ["yallist@5.0.0", "", {}, "sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw=="],
|
||||||
|
|
||||||
|
"tar-fs/chownr": ["chownr@1.1.4", "", {}, "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg=="],
|
||||||
|
|
||||||
|
"tar-fs/tar-stream": ["tar-stream@2.2.0", "", { "dependencies": { "bl": "^4.0.3", "end-of-stream": "^1.4.1", "fs-constants": "^1.0.0", "inherits": "^2.0.3", "readable-stream": "^3.1.1" } }, "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ=="],
|
||||||
|
|
||||||
"tedious/iconv-lite": ["iconv-lite@0.6.3", "", { "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" } }, "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw=="],
|
"tedious/iconv-lite": ["iconv-lite@0.6.3", "", { "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" } }, "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw=="],
|
||||||
|
|
||||||
"temp/rimraf": ["rimraf@2.6.3", "", { "dependencies": { "glob": "^7.1.3" }, "bin": { "rimraf": "./bin.js" } }, "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA=="],
|
"temp/rimraf": ["rimraf@2.6.3", "", { "dependencies": { "glob": "^7.1.3" }, "bin": { "rimraf": "./bin.js" } }, "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA=="],
|
||||||
@@ -5556,6 +5698,8 @@
|
|||||||
|
|
||||||
"which-builtin-type/isarray": ["isarray@2.0.5", "", {}, "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw=="],
|
"which-builtin-type/isarray": ["isarray@2.0.5", "", {}, "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw=="],
|
||||||
|
|
||||||
|
"wide-align/string-width": ["string-width@4.2.3", "", { "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" } }, "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g=="],
|
||||||
|
|
||||||
"wrangler/esbuild": ["esbuild@0.25.4", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.25.4", "@esbuild/android-arm": "0.25.4", "@esbuild/android-arm64": "0.25.4", "@esbuild/android-x64": "0.25.4", "@esbuild/darwin-arm64": "0.25.4", "@esbuild/darwin-x64": "0.25.4", "@esbuild/freebsd-arm64": "0.25.4", "@esbuild/freebsd-x64": "0.25.4", "@esbuild/linux-arm": "0.25.4", "@esbuild/linux-arm64": "0.25.4", "@esbuild/linux-ia32": "0.25.4", "@esbuild/linux-loong64": "0.25.4", "@esbuild/linux-mips64el": "0.25.4", "@esbuild/linux-ppc64": "0.25.4", "@esbuild/linux-riscv64": "0.25.4", "@esbuild/linux-s390x": "0.25.4", "@esbuild/linux-x64": "0.25.4", "@esbuild/netbsd-arm64": "0.25.4", "@esbuild/netbsd-x64": "0.25.4", "@esbuild/openbsd-arm64": "0.25.4", "@esbuild/openbsd-x64": "0.25.4", "@esbuild/sunos-x64": "0.25.4", "@esbuild/win32-arm64": "0.25.4", "@esbuild/win32-ia32": "0.25.4", "@esbuild/win32-x64": "0.25.4" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-8pgjLUcUjcgDg+2Q4NYXnPbo/vncAY4UmyaCm0jZevERqCHZIaWwdJHkf8XQtu4AxSKCdvrUbT0XUr1IdZzI8Q=="],
|
"wrangler/esbuild": ["esbuild@0.25.4", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.25.4", "@esbuild/android-arm": "0.25.4", "@esbuild/android-arm64": "0.25.4", "@esbuild/android-x64": "0.25.4", "@esbuild/darwin-arm64": "0.25.4", "@esbuild/darwin-x64": "0.25.4", "@esbuild/freebsd-arm64": "0.25.4", "@esbuild/freebsd-x64": "0.25.4", "@esbuild/linux-arm": "0.25.4", "@esbuild/linux-arm64": "0.25.4", "@esbuild/linux-ia32": "0.25.4", "@esbuild/linux-loong64": "0.25.4", "@esbuild/linux-mips64el": "0.25.4", "@esbuild/linux-ppc64": "0.25.4", "@esbuild/linux-riscv64": "0.25.4", "@esbuild/linux-s390x": "0.25.4", "@esbuild/linux-x64": "0.25.4", "@esbuild/netbsd-arm64": "0.25.4", "@esbuild/netbsd-x64": "0.25.4", "@esbuild/openbsd-arm64": "0.25.4", "@esbuild/openbsd-x64": "0.25.4", "@esbuild/sunos-x64": "0.25.4", "@esbuild/win32-arm64": "0.25.4", "@esbuild/win32-ia32": "0.25.4", "@esbuild/win32-x64": "0.25.4" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-8pgjLUcUjcgDg+2Q4NYXnPbo/vncAY4UmyaCm0jZevERqCHZIaWwdJHkf8XQtu4AxSKCdvrUbT0XUr1IdZzI8Q=="],
|
||||||
|
|
||||||
"wrap-ansi/ansi-styles": ["ansi-styles@6.2.3", "", {}, "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg=="],
|
"wrap-ansi/ansi-styles": ["ansi-styles@6.2.3", "", {}, "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg=="],
|
||||||
@@ -5688,6 +5832,12 @@
|
|||||||
|
|
||||||
"@electron/notarize/fs-extra/jsonfile": ["jsonfile@6.2.0", "", { "dependencies": { "universalify": "^2.0.0" }, "optionalDependencies": { "graceful-fs": "^4.1.6" } }, "sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg=="],
|
"@electron/notarize/fs-extra/jsonfile": ["jsonfile@6.2.0", "", { "dependencies": { "universalify": "^2.0.0" }, "optionalDependencies": { "graceful-fs": "^4.1.6" } }, "sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg=="],
|
||||||
|
|
||||||
|
"@electron/rebuild/node-gyp/make-fetch-happen": ["make-fetch-happen@14.0.3", "", { "dependencies": { "@npmcli/agent": "^3.0.0", "cacache": "^19.0.1", "http-cache-semantics": "^4.1.1", "minipass": "^7.0.2", "minipass-fetch": "^4.0.0", "minipass-flush": "^1.0.5", "minipass-pipeline": "^1.2.4", "negotiator": "^1.0.0", "proc-log": "^5.0.0", "promise-retry": "^2.0.1", "ssri": "^12.0.0" } }, "sha512-QMjGbFTP0blj97EeidG5hk/QhKQ3T4ICckQGLgz38QF7Vgbk6e6FTARN8KhKxyBbWn8R0HU+bnw8aSoFPD4qtQ=="],
|
||||||
|
|
||||||
|
"@electron/rebuild/node-gyp/nopt": ["nopt@8.1.0", "", { "dependencies": { "abbrev": "^3.0.0" }, "bin": { "nopt": "bin/nopt.js" } }, "sha512-ieGu42u/Qsa4TFktmaKEwM6MQH0pOWnaB3htzh0JRtx84+Mebc0cbZYN5bC+6WTZ4+77xrL9Pn5m7CV6VIkV7A=="],
|
||||||
|
|
||||||
|
"@electron/rebuild/node-gyp/which": ["which@5.0.0", "", { "dependencies": { "isexe": "^3.1.1" }, "bin": { "node-which": "bin/which.js" } }, "sha512-JEdGzHwwkrbWoGOlIHqQ5gtprKGOenpDHpxE9zVR1bWbOtYRyPPHMe9FaP6x61CmNaTThSkb0DAJte5jD+DmzQ=="],
|
||||||
|
|
||||||
"@electron/rebuild/yargs/cliui": ["cliui@8.0.1", "", { "dependencies": { "string-width": "^4.2.0", "strip-ansi": "^6.0.1", "wrap-ansi": "^7.0.0" } }, "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ=="],
|
"@electron/rebuild/yargs/cliui": ["cliui@8.0.1", "", { "dependencies": { "string-width": "^4.2.0", "strip-ansi": "^6.0.1", "wrap-ansi": "^7.0.0" } }, "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ=="],
|
||||||
|
|
||||||
"@electron/rebuild/yargs/string-width": ["string-width@4.2.3", "", { "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" } }, "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g=="],
|
"@electron/rebuild/yargs/string-width": ["string-width@4.2.3", "", { "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" } }, "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g=="],
|
||||||
@@ -5782,6 +5932,8 @@
|
|||||||
|
|
||||||
"@modelcontextprotocol/sdk/express/type-is": ["type-is@2.0.1", "", { "dependencies": { "content-type": "^1.0.5", "media-typer": "^1.1.0", "mime-types": "^3.0.0" } }, "sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw=="],
|
"@modelcontextprotocol/sdk/express/type-is": ["type-is@2.0.1", "", { "dependencies": { "content-type": "^1.0.5", "media-typer": "^1.1.0", "mime-types": "^3.0.0" } }, "sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw=="],
|
||||||
|
|
||||||
|
"@npmcli/move-file/rimraf/glob": ["glob@7.2.3", "", { "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", "minimatch": "^3.1.1", "once": "^1.3.0", "path-is-absolute": "^1.0.0" } }, "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q=="],
|
||||||
|
|
||||||
"@octokit/auth-app/@octokit/request/@octokit/endpoint": ["@octokit/endpoint@11.0.2", "", { "dependencies": { "@octokit/types": "^16.0.0", "universal-user-agent": "^7.0.2" } }, "sha512-4zCpzP1fWc7QlqunZ5bSEjxc6yLAlRTnDwKtgXfcI/FxxGoqedDG8V2+xJ60bV2kODqcGB+nATdtap/XYq2NZQ=="],
|
"@octokit/auth-app/@octokit/request/@octokit/endpoint": ["@octokit/endpoint@11.0.2", "", { "dependencies": { "@octokit/types": "^16.0.0", "universal-user-agent": "^7.0.2" } }, "sha512-4zCpzP1fWc7QlqunZ5bSEjxc6yLAlRTnDwKtgXfcI/FxxGoqedDG8V2+xJ60bV2kODqcGB+nATdtap/XYq2NZQ=="],
|
||||||
|
|
||||||
"@octokit/auth-app/@octokit/request/@octokit/types": ["@octokit/types@16.0.0", "", { "dependencies": { "@octokit/openapi-types": "^27.0.0" } }, "sha512-sKq+9r1Mm4efXW1FCk7hFSeJo4QKreL/tTbR0rz/qx/r1Oa2VV83LTA/H/MuCOX7uCIJmQVRKBcbmWoySjAnSg=="],
|
"@octokit/auth-app/@octokit/request/@octokit/types": ["@octokit/types@16.0.0", "", { "dependencies": { "@octokit/openapi-types": "^27.0.0" } }, "sha512-sKq+9r1Mm4efXW1FCk7hFSeJo4QKreL/tTbR0rz/qx/r1Oa2VV83LTA/H/MuCOX7uCIJmQVRKBcbmWoySjAnSg=="],
|
||||||
@@ -5956,11 +6108,11 @@
|
|||||||
|
|
||||||
"c12/chokidar/readdirp": ["readdirp@5.0.0", "", {}, "sha512-9u/XQ1pvrQtYyMpZe7DXKv2p5CNvyVwzUB6uhLAnQwHMSgKMBR62lc7AHljaeteeHXn11XTAaLLUVZYVZyuRBQ=="],
|
"c12/chokidar/readdirp": ["readdirp@5.0.0", "", {}, "sha512-9u/XQ1pvrQtYyMpZe7DXKv2p5CNvyVwzUB6uhLAnQwHMSgKMBR62lc7AHljaeteeHXn11XTAaLLUVZYVZyuRBQ=="],
|
||||||
|
|
||||||
"cacache/glob/jackspeak": ["jackspeak@3.4.3", "", { "dependencies": { "@isaacs/cliui": "^8.0.2" }, "optionalDependencies": { "@pkgjs/parseargs": "^0.11.0" } }, "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw=="],
|
"cacache/glob/minimatch": ["minimatch@3.1.5", "", { "dependencies": { "brace-expansion": "^1.1.7" } }, "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w=="],
|
||||||
|
|
||||||
"cacache/glob/minimatch": ["minimatch@9.0.5", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow=="],
|
"cacache/tar/minipass": ["minipass@5.0.0", "", {}, "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ=="],
|
||||||
|
|
||||||
"cacache/glob/path-scurry": ["path-scurry@1.11.1", "", { "dependencies": { "lru-cache": "^10.2.0", "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" } }, "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA=="],
|
"cacache/tar/minizlib": ["minizlib@2.1.2", "", { "dependencies": { "minipass": "^3.0.0", "yallist": "^4.0.0" } }, "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg=="],
|
||||||
|
|
||||||
"cli-truncate/string-width/emoji-regex": ["emoji-regex@8.0.0", "", {}, "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="],
|
"cli-truncate/string-width/emoji-regex": ["emoji-regex@8.0.0", "", {}, "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="],
|
||||||
|
|
||||||
@@ -5994,6 +6146,10 @@
|
|||||||
|
|
||||||
"form-data/mime-types/mime-db": ["mime-db@1.52.0", "", {}, "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg=="],
|
"form-data/mime-types/mime-db": ["mime-db@1.52.0", "", {}, "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg=="],
|
||||||
|
|
||||||
|
"gauge/string-width/emoji-regex": ["emoji-regex@8.0.0", "", {}, "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="],
|
||||||
|
|
||||||
|
"gauge/strip-ansi/ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="],
|
||||||
|
|
||||||
"gray-matter/js-yaml/argparse": ["argparse@1.0.10", "", { "dependencies": { "sprintf-js": "~1.0.2" } }, "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg=="],
|
"gray-matter/js-yaml/argparse": ["argparse@1.0.10", "", { "dependencies": { "sprintf-js": "~1.0.2" } }, "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg=="],
|
||||||
|
|
||||||
"js-beautify/glob/jackspeak": ["jackspeak@3.4.3", "", { "dependencies": { "@isaacs/cliui": "^8.0.2" }, "optionalDependencies": { "@pkgjs/parseargs": "^0.11.0" } }, "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw=="],
|
"js-beautify/glob/jackspeak": ["jackspeak@3.4.3", "", { "dependencies": { "@isaacs/cliui": "^8.0.2" }, "optionalDependencies": { "@pkgjs/parseargs": "^0.11.0" } }, "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw=="],
|
||||||
@@ -6008,11 +6164,25 @@
|
|||||||
|
|
||||||
"lazystream/readable-stream/string_decoder": ["string_decoder@1.1.1", "", { "dependencies": { "safe-buffer": "~5.1.0" } }, "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg=="],
|
"lazystream/readable-stream/string_decoder": ["string_decoder@1.1.1", "", { "dependencies": { "safe-buffer": "~5.1.0" } }, "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg=="],
|
||||||
|
|
||||||
|
"make-fetch-happen/http-proxy-agent/agent-base": ["agent-base@6.0.2", "", { "dependencies": { "debug": "4" } }, "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ=="],
|
||||||
|
|
||||||
|
"make-fetch-happen/https-proxy-agent/agent-base": ["agent-base@6.0.2", "", { "dependencies": { "debug": "4" } }, "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ=="],
|
||||||
|
|
||||||
"motion/framer-motion/motion-dom": ["motion-dom@12.34.5", "", { "dependencies": { "motion-utils": "^12.29.2" } }, "sha512-k33CsnxO2K3gBRMUZT+vPmc4Utlb5menKdG0RyVNLtlqRaaJPRWlE9fXl8NTtfZ5z3G8TDvqSu0MENLqSTaHZA=="],
|
"motion/framer-motion/motion-dom": ["motion-dom@12.34.5", "", { "dependencies": { "motion-utils": "^12.29.2" } }, "sha512-k33CsnxO2K3gBRMUZT+vPmc4Utlb5menKdG0RyVNLtlqRaaJPRWlE9fXl8NTtfZ5z3G8TDvqSu0MENLqSTaHZA=="],
|
||||||
|
|
||||||
"node-gyp/nopt/abbrev": ["abbrev@3.0.1", "", {}, "sha512-AO2ac6pjRB3SJmGJo+v5/aK6Omggp6fsLrs6wN9bd35ulu4cCwaAU9+7ZhXjeqHVkaHThLuzH0nZr0YpCDhygg=="],
|
"node-gyp/glob/minimatch": ["minimatch@3.1.5", "", { "dependencies": { "brace-expansion": "^1.1.7" } }, "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w=="],
|
||||||
|
|
||||||
"node-gyp/which/isexe": ["isexe@3.1.5", "", {}, "sha512-6B3tLtFqtQS4ekarvLVMZ+X+VlvQekbe4taUkf/rhVO3d/h0M2rfARm/pXLcPEsjjMsFgrFgSrhQIxcSVrBz8w=="],
|
"node-gyp/nopt/abbrev": ["abbrev@1.1.1", "", {}, "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q=="],
|
||||||
|
|
||||||
|
"node-gyp/tar/chownr": ["chownr@2.0.0", "", {}, "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ=="],
|
||||||
|
|
||||||
|
"node-gyp/tar/minipass": ["minipass@5.0.0", "", {}, "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ=="],
|
||||||
|
|
||||||
|
"node-gyp/tar/minizlib": ["minizlib@2.1.2", "", { "dependencies": { "minipass": "^3.0.0", "yallist": "^4.0.0" } }, "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg=="],
|
||||||
|
|
||||||
|
"node-gyp/tar/mkdirp": ["mkdirp@1.0.4", "", { "bin": { "mkdirp": "bin/cmd.js" } }, "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw=="],
|
||||||
|
|
||||||
|
"node-gyp/which/isexe": ["isexe@2.0.0", "", {}, "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw=="],
|
||||||
|
|
||||||
"opencode/@ai-sdk/openai/@ai-sdk/provider-utils": ["@ai-sdk/provider-utils@3.0.20", "", { "dependencies": { "@ai-sdk/provider": "2.0.1", "@standard-schema/spec": "^1.0.0", "eventsource-parser": "^3.0.6" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-iXHVe0apM2zUEzauqJwqmpC37A5rihrStAih5Ks+JE32iTe4LZ58y17UGBjpQQTCRw9YxMeo2UFLxLpBluyvLQ=="],
|
"opencode/@ai-sdk/openai/@ai-sdk/provider-utils": ["@ai-sdk/provider-utils@3.0.20", "", { "dependencies": { "@ai-sdk/provider": "2.0.1", "@standard-schema/spec": "^1.0.0", "eventsource-parser": "^3.0.6" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-iXHVe0apM2zUEzauqJwqmpC37A5rihrStAih5Ks+JE32iTe4LZ58y17UGBjpQQTCRw9YxMeo2UFLxLpBluyvLQ=="],
|
||||||
|
|
||||||
@@ -6050,6 +6220,14 @@
|
|||||||
|
|
||||||
"send/debug/ms": ["ms@2.0.0", "", {}, "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="],
|
"send/debug/ms": ["ms@2.0.0", "", {}, "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="],
|
||||||
|
|
||||||
|
"sqlite3/tar/chownr": ["chownr@2.0.0", "", {}, "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ=="],
|
||||||
|
|
||||||
|
"sqlite3/tar/minipass": ["minipass@5.0.0", "", {}, "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ=="],
|
||||||
|
|
||||||
|
"sqlite3/tar/minizlib": ["minizlib@2.1.2", "", { "dependencies": { "minipass": "^3.0.0", "yallist": "^4.0.0" } }, "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg=="],
|
||||||
|
|
||||||
|
"sqlite3/tar/mkdirp": ["mkdirp@1.0.4", "", { "bin": { "mkdirp": "bin/cmd.js" } }, "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw=="],
|
||||||
|
|
||||||
"storybook/esbuild/@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.27.3", "", { "os": "aix", "cpu": "ppc64" }, "sha512-9fJMTNFTWZMh5qwrBItuziu834eOCUcEqymSH7pY+zoMVEZg3gcPuBNxH1EvfVYe9h0x/Ptw8KBzv7qxb7l8dg=="],
|
"storybook/esbuild/@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.27.3", "", { "os": "aix", "cpu": "ppc64" }, "sha512-9fJMTNFTWZMh5qwrBItuziu834eOCUcEqymSH7pY+zoMVEZg3gcPuBNxH1EvfVYe9h0x/Ptw8KBzv7qxb7l8dg=="],
|
||||||
|
|
||||||
"storybook/esbuild/@esbuild/android-arm": ["@esbuild/android-arm@0.27.3", "", { "os": "android", "cpu": "arm" }, "sha512-i5D1hPY7GIQmXlXhs2w8AWHhenb00+GxjxRncS2ZM7YNVGNfaMxgzSGuO8o8SJzRc/oZwU2bcScvVERk03QhzA=="],
|
"storybook/esbuild/@esbuild/android-arm": ["@esbuild/android-arm@0.27.3", "", { "os": "android", "cpu": "arm" }, "sha512-i5D1hPY7GIQmXlXhs2w8AWHhenb00+GxjxRncS2ZM7YNVGNfaMxgzSGuO8o8SJzRc/oZwU2bcScvVERk03QhzA=="],
|
||||||
@@ -6106,6 +6284,10 @@
|
|||||||
|
|
||||||
"string-width-cjs/strip-ansi/ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="],
|
"string-width-cjs/strip-ansi/ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="],
|
||||||
|
|
||||||
|
"tar-fs/tar-stream/bl": ["bl@4.1.0", "", { "dependencies": { "buffer": "^5.5.0", "inherits": "^2.0.4", "readable-stream": "^3.4.0" } }, "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w=="],
|
||||||
|
|
||||||
|
"tar-fs/tar-stream/readable-stream": ["readable-stream@3.6.2", "", { "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", "util-deprecate": "^1.0.1" } }, "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA=="],
|
||||||
|
|
||||||
"temp/rimraf/glob": ["glob@7.2.3", "", { "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", "minimatch": "^3.1.1", "once": "^1.3.0", "path-is-absolute": "^1.0.0" } }, "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q=="],
|
"temp/rimraf/glob": ["glob@7.2.3", "", { "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", "minimatch": "^3.1.1", "once": "^1.3.0", "path-is-absolute": "^1.0.0" } }, "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q=="],
|
||||||
|
|
||||||
"tsx/esbuild/@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.27.3", "", { "os": "aix", "cpu": "ppc64" }, "sha512-9fJMTNFTWZMh5qwrBItuziu834eOCUcEqymSH7pY+zoMVEZg3gcPuBNxH1EvfVYe9h0x/Ptw8KBzv7qxb7l8dg=="],
|
"tsx/esbuild/@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.27.3", "", { "os": "aix", "cpu": "ppc64" }, "sha512-9fJMTNFTWZMh5qwrBItuziu834eOCUcEqymSH7pY+zoMVEZg3gcPuBNxH1EvfVYe9h0x/Ptw8KBzv7qxb7l8dg=="],
|
||||||
@@ -6176,6 +6358,10 @@
|
|||||||
|
|
||||||
"vitest/@vitest/expect/chai": ["chai@6.2.2", "", {}, "sha512-NUPRluOfOiTKBKvWPtSD4PhFvWCqOi0BGStNWs57X9js7XGTprSmFoz5F0tWhR4WPjNeR9jXqdC7/UpSJTnlRg=="],
|
"vitest/@vitest/expect/chai": ["chai@6.2.2", "", {}, "sha512-NUPRluOfOiTKBKvWPtSD4PhFvWCqOi0BGStNWs57X9js7XGTprSmFoz5F0tWhR4WPjNeR9jXqdC7/UpSJTnlRg=="],
|
||||||
|
|
||||||
|
"wide-align/string-width/emoji-regex": ["emoji-regex@8.0.0", "", {}, "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="],
|
||||||
|
|
||||||
|
"wide-align/string-width/strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="],
|
||||||
|
|
||||||
"wrangler/esbuild/@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.25.4", "", { "os": "aix", "cpu": "ppc64" }, "sha512-1VCICWypeQKhVbE9oW/sJaAmjLxhVqacdkvPLEjwlttjfwENRSClS8EjBz0KzRyFSCPDIkuXW34Je/vk7zdB7Q=="],
|
"wrangler/esbuild/@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.25.4", "", { "os": "aix", "cpu": "ppc64" }, "sha512-1VCICWypeQKhVbE9oW/sJaAmjLxhVqacdkvPLEjwlttjfwENRSClS8EjBz0KzRyFSCPDIkuXW34Je/vk7zdB7Q=="],
|
||||||
|
|
||||||
"wrangler/esbuild/@esbuild/android-arm": ["@esbuild/android-arm@0.25.4", "", { "os": "android", "cpu": "arm" }, "sha512-QNdQEps7DfFwE3hXiU4BZeOV68HHzYwGd0Nthhd3uCkkEKK7/R6MTgM0P7H7FAs5pU/DIWsviMmEGxEoxIZ+ZQ=="],
|
"wrangler/esbuild/@esbuild/android-arm": ["@esbuild/android-arm@0.25.4", "", { "os": "android", "cpu": "arm" }, "sha512-QNdQEps7DfFwE3hXiU4BZeOV68HHzYwGd0Nthhd3uCkkEKK7/R6MTgM0P7H7FAs5pU/DIWsviMmEGxEoxIZ+ZQ=="],
|
||||||
@@ -6290,6 +6476,18 @@
|
|||||||
|
|
||||||
"@electron/asar/minimatch/brace-expansion/balanced-match": ["balanced-match@1.0.2", "", {}, "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="],
|
"@electron/asar/minimatch/brace-expansion/balanced-match": ["balanced-match@1.0.2", "", {}, "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="],
|
||||||
|
|
||||||
|
"@electron/rebuild/node-gyp/make-fetch-happen/cacache": ["cacache@19.0.1", "", { "dependencies": { "@npmcli/fs": "^4.0.0", "fs-minipass": "^3.0.0", "glob": "^10.2.2", "lru-cache": "^10.0.1", "minipass": "^7.0.3", "minipass-collect": "^2.0.1", "minipass-flush": "^1.0.5", "minipass-pipeline": "^1.2.4", "p-map": "^7.0.2", "ssri": "^12.0.0", "tar": "^7.4.3", "unique-filename": "^4.0.0" } }, "sha512-hdsUxulXCi5STId78vRVYEtDAjq99ICAUktLTeTYsLoTE6Z8dS0c8pWNCxwdrk9YfJeobDZc2Y186hD/5ZQgFQ=="],
|
||||||
|
|
||||||
|
"@electron/rebuild/node-gyp/make-fetch-happen/minipass-fetch": ["minipass-fetch@4.0.1", "", { "dependencies": { "minipass": "^7.0.3", "minipass-sized": "^1.0.3", "minizlib": "^3.0.1" }, "optionalDependencies": { "encoding": "^0.1.13" } }, "sha512-j7U11C5HXigVuutxebFadoYBbd7VSdZWggSe64NVdvWNBqGAiXPL2QVCehjmw7lY1oF9gOllYbORh+hiNgfPgQ=="],
|
||||||
|
|
||||||
|
"@electron/rebuild/node-gyp/make-fetch-happen/negotiator": ["negotiator@1.0.0", "", {}, "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg=="],
|
||||||
|
|
||||||
|
"@electron/rebuild/node-gyp/make-fetch-happen/ssri": ["ssri@12.0.0", "", { "dependencies": { "minipass": "^7.0.3" } }, "sha512-S7iGNosepx9RadX82oimUkvr0Ct7IjJbEbs4mJcTxst8um95J3sDYU1RBEOvdu6oL1Wek2ODI5i4MAw+dZ6cAQ=="],
|
||||||
|
|
||||||
|
"@electron/rebuild/node-gyp/nopt/abbrev": ["abbrev@3.0.1", "", {}, "sha512-AO2ac6pjRB3SJmGJo+v5/aK6Omggp6fsLrs6wN9bd35ulu4cCwaAU9+7ZhXjeqHVkaHThLuzH0nZr0YpCDhygg=="],
|
||||||
|
|
||||||
|
"@electron/rebuild/node-gyp/which/isexe": ["isexe@3.1.5", "", {}, "sha512-6B3tLtFqtQS4ekarvLVMZ+X+VlvQekbe4taUkf/rhVO3d/h0M2rfARm/pXLcPEsjjMsFgrFgSrhQIxcSVrBz8w=="],
|
||||||
|
|
||||||
"@electron/rebuild/yargs/cliui/strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="],
|
"@electron/rebuild/yargs/cliui/strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="],
|
||||||
|
|
||||||
"@electron/rebuild/yargs/cliui/wrap-ansi": ["wrap-ansi@7.0.0", "", { "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", "strip-ansi": "^6.0.0" } }, "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q=="],
|
"@electron/rebuild/yargs/cliui/wrap-ansi": ["wrap-ansi@7.0.0", "", { "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", "strip-ansi": "^6.0.0" } }, "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q=="],
|
||||||
@@ -6352,6 +6550,8 @@
|
|||||||
|
|
||||||
"@modelcontextprotocol/sdk/express/type-is/media-typer": ["media-typer@1.1.0", "", {}, "sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw=="],
|
"@modelcontextprotocol/sdk/express/type-is/media-typer": ["media-typer@1.1.0", "", {}, "sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw=="],
|
||||||
|
|
||||||
|
"@npmcli/move-file/rimraf/glob/minimatch": ["minimatch@3.1.5", "", { "dependencies": { "brace-expansion": "^1.1.7" } }, "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w=="],
|
||||||
|
|
||||||
"@octokit/auth-app/@octokit/request-error/@octokit/types/@octokit/openapi-types": ["@octokit/openapi-types@27.0.0", "", {}, "sha512-whrdktVs1h6gtR+09+QsNk2+FO+49j6ga1c55YZudfEG+oKJVvJLQi3zkOm5JjiUXAagWK2tI2kTGKJ2Ys7MGA=="],
|
"@octokit/auth-app/@octokit/request-error/@octokit/types/@octokit/openapi-types": ["@octokit/openapi-types@27.0.0", "", {}, "sha512-whrdktVs1h6gtR+09+QsNk2+FO+49j6ga1c55YZudfEG+oKJVvJLQi3zkOm5JjiUXAagWK2tI2kTGKJ2Ys7MGA=="],
|
||||||
|
|
||||||
"@octokit/auth-app/@octokit/request/@octokit/types/@octokit/openapi-types": ["@octokit/openapi-types@27.0.0", "", {}, "sha512-whrdktVs1h6gtR+09+QsNk2+FO+49j6ga1c55YZudfEG+oKJVvJLQi3zkOm5JjiUXAagWK2tI2kTGKJ2Ys7MGA=="],
|
"@octokit/auth-app/@octokit/request/@octokit/types/@octokit/openapi-types": ["@octokit/openapi-types@27.0.0", "", {}, "sha512-whrdktVs1h6gtR+09+QsNk2+FO+49j6ga1c55YZudfEG+oKJVvJLQi3zkOm5JjiUXAagWK2tI2kTGKJ2Ys7MGA=="],
|
||||||
@@ -6400,9 +6600,9 @@
|
|||||||
|
|
||||||
"babel-plugin-module-resolver/glob/path-scurry/minipass": ["minipass@7.1.2", "", {}, "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw=="],
|
"babel-plugin-module-resolver/glob/path-scurry/minipass": ["minipass@7.1.2", "", {}, "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw=="],
|
||||||
|
|
||||||
"cacache/glob/jackspeak/@isaacs/cliui": ["@isaacs/cliui@8.0.2", "", { "dependencies": { "string-width": "^5.1.2", "string-width-cjs": "npm:string-width@^4.2.0", "strip-ansi": "^7.0.1", "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", "wrap-ansi": "^8.1.0", "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" } }, "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA=="],
|
"cacache/glob/minimatch/brace-expansion": ["brace-expansion@1.1.12", "", { "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg=="],
|
||||||
|
|
||||||
"cacache/glob/minimatch/brace-expansion": ["brace-expansion@2.0.2", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ=="],
|
"cacache/tar/minizlib/minipass": ["minipass@3.3.6", "", { "dependencies": { "yallist": "^4.0.0" } }, "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw=="],
|
||||||
|
|
||||||
"cli-truncate/string-width/strip-ansi/ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="],
|
"cli-truncate/string-width/strip-ansi/ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="],
|
||||||
|
|
||||||
@@ -6430,6 +6630,10 @@
|
|||||||
|
|
||||||
"js-beautify/glob/path-scurry/lru-cache": ["lru-cache@10.4.3", "", {}, "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ=="],
|
"js-beautify/glob/path-scurry/lru-cache": ["lru-cache@10.4.3", "", {}, "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ=="],
|
||||||
|
|
||||||
|
"node-gyp/glob/minimatch/brace-expansion": ["brace-expansion@1.1.12", "", { "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg=="],
|
||||||
|
|
||||||
|
"node-gyp/tar/minizlib/minipass": ["minipass@3.3.6", "", { "dependencies": { "yallist": "^4.0.0" } }, "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw=="],
|
||||||
|
|
||||||
"opencontrol/@modelcontextprotocol/sdk/express/accepts": ["accepts@2.0.0", "", { "dependencies": { "mime-types": "^3.0.0", "negotiator": "^1.0.0" } }, "sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng=="],
|
"opencontrol/@modelcontextprotocol/sdk/express/accepts": ["accepts@2.0.0", "", { "dependencies": { "mime-types": "^3.0.0", "negotiator": "^1.0.0" } }, "sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng=="],
|
||||||
|
|
||||||
"opencontrol/@modelcontextprotocol/sdk/express/body-parser": ["body-parser@2.2.2", "", { "dependencies": { "bytes": "^3.1.2", "content-type": "^1.0.5", "debug": "^4.4.3", "http-errors": "^2.0.0", "iconv-lite": "^0.7.0", "on-finished": "^2.4.1", "qs": "^6.14.1", "raw-body": "^3.0.1", "type-is": "^2.0.1" } }, "sha512-oP5VkATKlNwcgvxi0vM0p/D3n2C3EReYVX+DNYs5TjZFn/oQt2j+4sVJtSMr18pdRr8wjTcBl6LoV+FUwzPmNA=="],
|
"opencontrol/@modelcontextprotocol/sdk/express/body-parser": ["body-parser@2.2.2", "", { "dependencies": { "bytes": "^3.1.2", "content-type": "^1.0.5", "debug": "^4.4.3", "http-errors": "^2.0.0", "iconv-lite": "^0.7.0", "on-finished": "^2.4.1", "qs": "^6.14.1", "raw-body": "^3.0.1", "type-is": "^2.0.1" } }, "sha512-oP5VkATKlNwcgvxi0vM0p/D3n2C3EReYVX+DNYs5TjZFn/oQt2j+4sVJtSMr18pdRr8wjTcBl6LoV+FUwzPmNA=="],
|
||||||
@@ -6466,12 +6670,18 @@
|
|||||||
|
|
||||||
"rimraf/glob/path-scurry/lru-cache": ["lru-cache@10.4.3", "", {}, "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ=="],
|
"rimraf/glob/path-scurry/lru-cache": ["lru-cache@10.4.3", "", {}, "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ=="],
|
||||||
|
|
||||||
|
"sqlite3/tar/minizlib/minipass": ["minipass@3.3.6", "", { "dependencies": { "yallist": "^4.0.0" } }, "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw=="],
|
||||||
|
|
||||||
|
"tar-fs/tar-stream/bl/buffer": ["buffer@5.7.1", "", { "dependencies": { "base64-js": "^1.3.1", "ieee754": "^1.1.13" } }, "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ=="],
|
||||||
|
|
||||||
"temp/rimraf/glob/minimatch": ["minimatch@3.1.5", "", { "dependencies": { "brace-expansion": "^1.1.7" } }, "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w=="],
|
"temp/rimraf/glob/minimatch": ["minimatch@3.1.5", "", { "dependencies": { "brace-expansion": "^1.1.7" } }, "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w=="],
|
||||||
|
|
||||||
"tw-to-css/tailwindcss/chokidar/glob-parent": ["glob-parent@5.1.2", "", { "dependencies": { "is-glob": "^4.0.1" } }, "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow=="],
|
"tw-to-css/tailwindcss/chokidar/glob-parent": ["glob-parent@5.1.2", "", { "dependencies": { "is-glob": "^4.0.1" } }, "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow=="],
|
||||||
|
|
||||||
"tw-to-css/tailwindcss/chokidar/readdirp": ["readdirp@3.6.0", "", { "dependencies": { "picomatch": "^2.2.1" } }, "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA=="],
|
"tw-to-css/tailwindcss/chokidar/readdirp": ["readdirp@3.6.0", "", { "dependencies": { "picomatch": "^2.2.1" } }, "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA=="],
|
||||||
|
|
||||||
|
"wide-align/string-width/strip-ansi/ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="],
|
||||||
|
|
||||||
"@astrojs/check/yargs/cliui/strip-ansi/ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="],
|
"@astrojs/check/yargs/cliui/strip-ansi/ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="],
|
||||||
|
|
||||||
"@astrojs/check/yargs/string-width/strip-ansi/ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="],
|
"@astrojs/check/yargs/string-width/strip-ansi/ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="],
|
||||||
@@ -6504,12 +6714,28 @@
|
|||||||
|
|
||||||
"@aws-sdk/token-providers/@aws-sdk/core/@aws-sdk/xml-builder/fast-xml-parser/strnum": ["strnum@2.1.2", "", {}, "sha512-l63NF9y/cLROq/yqKXSLtcMeeyOfnSQlfMSlzFt/K73oIaD8DGaQWd7Z34X9GPiKqP5rbSh84Hl4bOlLcjiSrQ=="],
|
"@aws-sdk/token-providers/@aws-sdk/core/@aws-sdk/xml-builder/fast-xml-parser/strnum": ["strnum@2.1.2", "", {}, "sha512-l63NF9y/cLROq/yqKXSLtcMeeyOfnSQlfMSlzFt/K73oIaD8DGaQWd7Z34X9GPiKqP5rbSh84Hl4bOlLcjiSrQ=="],
|
||||||
|
|
||||||
|
"@electron/rebuild/node-gyp/make-fetch-happen/cacache/@npmcli/fs": ["@npmcli/fs@4.0.0", "", { "dependencies": { "semver": "^7.3.5" } }, "sha512-/xGlezI6xfGO9NwuJlnwz/K14qD1kCSAGtacBHnGzeAIuJGazcp45KP5NuyARXoKb7cwulAGWVsbeSxdG/cb0Q=="],
|
||||||
|
|
||||||
|
"@electron/rebuild/node-gyp/make-fetch-happen/cacache/fs-minipass": ["fs-minipass@3.0.3", "", { "dependencies": { "minipass": "^7.0.3" } }, "sha512-XUBA9XClHbnJWSfBzjkm6RvPsyg3sryZt06BEQoXcF7EK/xpGaQYJgQKDJSUH5SGZ76Y7pFx1QBnXz09rU5Fbw=="],
|
||||||
|
|
||||||
|
"@electron/rebuild/node-gyp/make-fetch-happen/cacache/glob": ["glob@10.5.0", "", { "dependencies": { "foreground-child": "^3.1.0", "jackspeak": "^3.1.2", "minimatch": "^9.0.4", "minipass": "^7.1.2", "package-json-from-dist": "^1.0.0", "path-scurry": "^1.11.1" }, "bin": { "glob": "dist/esm/bin.mjs" } }, "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg=="],
|
||||||
|
|
||||||
|
"@electron/rebuild/node-gyp/make-fetch-happen/cacache/lru-cache": ["lru-cache@10.4.3", "", {}, "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ=="],
|
||||||
|
|
||||||
|
"@electron/rebuild/node-gyp/make-fetch-happen/cacache/minipass-collect": ["minipass-collect@2.0.1", "", { "dependencies": { "minipass": "^7.0.3" } }, "sha512-D7V8PO9oaz7PWGLbCACuI1qEOsq7UKfLotx/C0Aet43fCUB/wfQ7DYeq2oR/svFJGYDHPr38SHATeaj/ZoKHKw=="],
|
||||||
|
|
||||||
|
"@electron/rebuild/node-gyp/make-fetch-happen/cacache/p-map": ["p-map@7.0.4", "", {}, "sha512-tkAQEw8ysMzmkhgw8k+1U/iPhWNhykKnSk4Rd5zLoPJCuJaGRPo6YposrZgaxHKzDHdDWWZvE/Sk7hsL2X/CpQ=="],
|
||||||
|
|
||||||
|
"@electron/rebuild/node-gyp/make-fetch-happen/cacache/unique-filename": ["unique-filename@4.0.0", "", { "dependencies": { "unique-slug": "^5.0.0" } }, "sha512-XSnEewXmQ+veP7xX2dS5Q4yZAvO40cBN2MWkJ7D/6sW4Dg6wYBNwM1Vrnz1FhH5AdeLIlUXRI9e28z1YZi71NQ=="],
|
||||||
|
|
||||||
"@electron/rebuild/yargs/cliui/strip-ansi/ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="],
|
"@electron/rebuild/yargs/cliui/strip-ansi/ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="],
|
||||||
|
|
||||||
"@electron/rebuild/yargs/string-width/strip-ansi/ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="],
|
"@electron/rebuild/yargs/string-width/strip-ansi/ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="],
|
||||||
|
|
||||||
"@jsx-email/cli/tailwindcss/chokidar/readdirp/picomatch": ["picomatch@2.3.1", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="],
|
"@jsx-email/cli/tailwindcss/chokidar/readdirp/picomatch": ["picomatch@2.3.1", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="],
|
||||||
|
|
||||||
|
"@npmcli/move-file/rimraf/glob/minimatch/brace-expansion": ["brace-expansion@1.1.12", "", { "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg=="],
|
||||||
|
|
||||||
"@solidjs/start/shiki/@shikijs/engine-javascript/oniguruma-to-es/regex": ["regex@5.1.1", "", { "dependencies": { "regex-utilities": "^2.3.0" } }, "sha512-dN5I359AVGPnwzJm2jN1k0W9LPZ+ePvoOeVMMfqIMFz53sSwXkxaJoxr50ptnsC771lK95BnTrVSZxq0b9yCGw=="],
|
"@solidjs/start/shiki/@shikijs/engine-javascript/oniguruma-to-es/regex": ["regex@5.1.1", "", { "dependencies": { "regex-utilities": "^2.3.0" } }, "sha512-dN5I359AVGPnwzJm2jN1k0W9LPZ+ePvoOeVMMfqIMFz53sSwXkxaJoxr50ptnsC771lK95BnTrVSZxq0b9yCGw=="],
|
||||||
|
|
||||||
"@solidjs/start/shiki/@shikijs/engine-javascript/oniguruma-to-es/regex-recursion": ["regex-recursion@5.1.1", "", { "dependencies": { "regex": "^5.1.1", "regex-utilities": "^2.3.0" } }, "sha512-ae7SBCbzVNrIjgSbh7wMznPcQel1DNlDtzensnFxpiNpXt1U2ju/bHugH422r+4LAVS1FpW1YCwilmnNsjum9w=="],
|
"@solidjs/start/shiki/@shikijs/engine-javascript/oniguruma-to-es/regex-recursion": ["regex-recursion@5.1.1", "", { "dependencies": { "regex": "^5.1.1", "regex-utilities": "^2.3.0" } }, "sha512-ae7SBCbzVNrIjgSbh7wMznPcQel1DNlDtzensnFxpiNpXt1U2ju/bHugH422r+4LAVS1FpW1YCwilmnNsjum9w=="],
|
||||||
@@ -6522,10 +6748,6 @@
|
|||||||
|
|
||||||
"babel-plugin-module-resolver/glob/minimatch/brace-expansion/balanced-match": ["balanced-match@1.0.2", "", {}, "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="],
|
"babel-plugin-module-resolver/glob/minimatch/brace-expansion/balanced-match": ["balanced-match@1.0.2", "", {}, "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="],
|
||||||
|
|
||||||
"cacache/glob/jackspeak/@isaacs/cliui/string-width": ["string-width@5.1.2", "", { "dependencies": { "eastasianwidth": "^0.2.0", "emoji-regex": "^9.2.2", "strip-ansi": "^7.0.1" } }, "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA=="],
|
|
||||||
|
|
||||||
"cacache/glob/jackspeak/@isaacs/cliui/wrap-ansi": ["wrap-ansi@8.1.0", "", { "dependencies": { "ansi-styles": "^6.1.0", "string-width": "^5.0.1", "strip-ansi": "^7.0.1" } }, "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ=="],
|
|
||||||
|
|
||||||
"cacache/glob/minimatch/brace-expansion/balanced-match": ["balanced-match@1.0.2", "", {}, "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="],
|
"cacache/glob/minimatch/brace-expansion/balanced-match": ["balanced-match@1.0.2", "", {}, "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="],
|
||||||
|
|
||||||
"electron-builder/yargs/cliui/strip-ansi/ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="],
|
"electron-builder/yargs/cliui/strip-ansi/ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="],
|
||||||
@@ -6538,6 +6760,8 @@
|
|||||||
|
|
||||||
"js-beautify/glob/minimatch/brace-expansion/balanced-match": ["balanced-match@1.0.2", "", {}, "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="],
|
"js-beautify/glob/minimatch/brace-expansion/balanced-match": ["balanced-match@1.0.2", "", {}, "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="],
|
||||||
|
|
||||||
|
"node-gyp/glob/minimatch/brace-expansion/balanced-match": ["balanced-match@1.0.2", "", {}, "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="],
|
||||||
|
|
||||||
"opencontrol/@modelcontextprotocol/sdk/express/accepts/negotiator": ["negotiator@1.0.0", "", {}, "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg=="],
|
"opencontrol/@modelcontextprotocol/sdk/express/accepts/negotiator": ["negotiator@1.0.0", "", {}, "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg=="],
|
||||||
|
|
||||||
"opencontrol/@modelcontextprotocol/sdk/express/type-is/media-typer": ["media-typer@1.1.0", "", {}, "sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw=="],
|
"opencontrol/@modelcontextprotocol/sdk/express/type-is/media-typer": ["media-typer@1.1.0", "", {}, "sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw=="],
|
||||||
@@ -6550,20 +6774,28 @@
|
|||||||
|
|
||||||
"rimraf/glob/minimatch/brace-expansion/balanced-match": ["balanced-match@1.0.2", "", {}, "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="],
|
"rimraf/glob/minimatch/brace-expansion/balanced-match": ["balanced-match@1.0.2", "", {}, "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="],
|
||||||
|
|
||||||
|
"tar-fs/tar-stream/bl/buffer/ieee754": ["ieee754@1.2.1", "", {}, "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA=="],
|
||||||
|
|
||||||
"temp/rimraf/glob/minimatch/brace-expansion": ["brace-expansion@1.1.12", "", { "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg=="],
|
"temp/rimraf/glob/minimatch/brace-expansion": ["brace-expansion@1.1.12", "", { "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg=="],
|
||||||
|
|
||||||
"tw-to-css/tailwindcss/chokidar/readdirp/picomatch": ["picomatch@2.3.1", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="],
|
"tw-to-css/tailwindcss/chokidar/readdirp/picomatch": ["picomatch@2.3.1", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="],
|
||||||
|
|
||||||
"@aws-sdk/credential-provider-cognito-identity/@aws-sdk/client-cognito-identity/@aws-sdk/core/@aws-sdk/xml-builder/fast-xml-parser/strnum": ["strnum@2.1.2", "", {}, "sha512-l63NF9y/cLROq/yqKXSLtcMeeyOfnSQlfMSlzFt/K73oIaD8DGaQWd7Z34X9GPiKqP5rbSh84Hl4bOlLcjiSrQ=="],
|
"@aws-sdk/credential-provider-cognito-identity/@aws-sdk/client-cognito-identity/@aws-sdk/core/@aws-sdk/xml-builder/fast-xml-parser/strnum": ["strnum@2.1.2", "", {}, "sha512-l63NF9y/cLROq/yqKXSLtcMeeyOfnSQlfMSlzFt/K73oIaD8DGaQWd7Z34X9GPiKqP5rbSh84Hl4bOlLcjiSrQ=="],
|
||||||
|
|
||||||
|
"@electron/rebuild/node-gyp/make-fetch-happen/cacache/glob/jackspeak": ["jackspeak@3.4.3", "", { "dependencies": { "@isaacs/cliui": "^8.0.2" }, "optionalDependencies": { "@pkgjs/parseargs": "^0.11.0" } }, "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw=="],
|
||||||
|
|
||||||
|
"@electron/rebuild/node-gyp/make-fetch-happen/cacache/glob/minimatch": ["minimatch@9.0.5", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow=="],
|
||||||
|
|
||||||
|
"@electron/rebuild/node-gyp/make-fetch-happen/cacache/glob/path-scurry": ["path-scurry@1.11.1", "", { "dependencies": { "lru-cache": "^10.2.0", "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" } }, "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA=="],
|
||||||
|
|
||||||
|
"@electron/rebuild/node-gyp/make-fetch-happen/cacache/unique-filename/unique-slug": ["unique-slug@5.0.0", "", { "dependencies": { "imurmurhash": "^0.1.4" } }, "sha512-9OdaqO5kwqR+1kVgHAhsp5vPNU0hnxRa26rBFNfNgM7M6pNtgzeBn3s/xbyCQL3dcjzOatcef6UUHpB/6MaETg=="],
|
||||||
|
|
||||||
|
"@npmcli/move-file/rimraf/glob/minimatch/brace-expansion/balanced-match": ["balanced-match@1.0.2", "", {}, "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="],
|
||||||
|
|
||||||
"archiver-utils/glob/jackspeak/@isaacs/cliui/string-width/emoji-regex": ["emoji-regex@9.2.2", "", {}, "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg=="],
|
"archiver-utils/glob/jackspeak/@isaacs/cliui/string-width/emoji-regex": ["emoji-regex@9.2.2", "", {}, "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg=="],
|
||||||
|
|
||||||
"archiver-utils/glob/jackspeak/@isaacs/cliui/wrap-ansi/ansi-styles": ["ansi-styles@6.2.3", "", {}, "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg=="],
|
"archiver-utils/glob/jackspeak/@isaacs/cliui/wrap-ansi/ansi-styles": ["ansi-styles@6.2.3", "", {}, "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg=="],
|
||||||
|
|
||||||
"cacache/glob/jackspeak/@isaacs/cliui/string-width/emoji-regex": ["emoji-regex@9.2.2", "", {}, "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg=="],
|
|
||||||
|
|
||||||
"cacache/glob/jackspeak/@isaacs/cliui/wrap-ansi/ansi-styles": ["ansi-styles@6.2.3", "", {}, "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg=="],
|
|
||||||
|
|
||||||
"js-beautify/glob/jackspeak/@isaacs/cliui/string-width/emoji-regex": ["emoji-regex@9.2.2", "", {}, "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg=="],
|
"js-beautify/glob/jackspeak/@isaacs/cliui/string-width/emoji-regex": ["emoji-regex@9.2.2", "", {}, "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg=="],
|
||||||
|
|
||||||
"js-beautify/glob/jackspeak/@isaacs/cliui/wrap-ansi/ansi-styles": ["ansi-styles@6.2.3", "", {}, "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg=="],
|
"js-beautify/glob/jackspeak/@isaacs/cliui/wrap-ansi/ansi-styles": ["ansi-styles@6.2.3", "", {}, "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg=="],
|
||||||
@@ -6573,5 +6805,19 @@
|
|||||||
"rimraf/glob/jackspeak/@isaacs/cliui/wrap-ansi/ansi-styles": ["ansi-styles@6.2.3", "", {}, "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg=="],
|
"rimraf/glob/jackspeak/@isaacs/cliui/wrap-ansi/ansi-styles": ["ansi-styles@6.2.3", "", {}, "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg=="],
|
||||||
|
|
||||||
"temp/rimraf/glob/minimatch/brace-expansion/balanced-match": ["balanced-match@1.0.2", "", {}, "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="],
|
"temp/rimraf/glob/minimatch/brace-expansion/balanced-match": ["balanced-match@1.0.2", "", {}, "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="],
|
||||||
|
|
||||||
|
"@electron/rebuild/node-gyp/make-fetch-happen/cacache/glob/jackspeak/@isaacs/cliui": ["@isaacs/cliui@8.0.2", "", { "dependencies": { "string-width": "^5.1.2", "string-width-cjs": "npm:string-width@^4.2.0", "strip-ansi": "^7.0.1", "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", "wrap-ansi": "^8.1.0", "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" } }, "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA=="],
|
||||||
|
|
||||||
|
"@electron/rebuild/node-gyp/make-fetch-happen/cacache/glob/minimatch/brace-expansion": ["brace-expansion@2.0.2", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ=="],
|
||||||
|
|
||||||
|
"@electron/rebuild/node-gyp/make-fetch-happen/cacache/glob/jackspeak/@isaacs/cliui/string-width": ["string-width@5.1.2", "", { "dependencies": { "eastasianwidth": "^0.2.0", "emoji-regex": "^9.2.2", "strip-ansi": "^7.0.1" } }, "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA=="],
|
||||||
|
|
||||||
|
"@electron/rebuild/node-gyp/make-fetch-happen/cacache/glob/jackspeak/@isaacs/cliui/wrap-ansi": ["wrap-ansi@8.1.0", "", { "dependencies": { "ansi-styles": "^6.1.0", "string-width": "^5.0.1", "strip-ansi": "^7.0.1" } }, "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ=="],
|
||||||
|
|
||||||
|
"@electron/rebuild/node-gyp/make-fetch-happen/cacache/glob/minimatch/brace-expansion/balanced-match": ["balanced-match@1.0.2", "", {}, "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="],
|
||||||
|
|
||||||
|
"@electron/rebuild/node-gyp/make-fetch-happen/cacache/glob/jackspeak/@isaacs/cliui/string-width/emoji-regex": ["emoji-regex@9.2.2", "", {}, "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg=="],
|
||||||
|
|
||||||
|
"@electron/rebuild/node-gyp/make-fetch-happen/cacache/glob/jackspeak/@isaacs/cliui/wrap-ansi/ansi-styles": ["ansi-styles@6.2.3", "", {}, "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg=="],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@opencode-ai/app",
|
"name": "@opencode-ai/app",
|
||||||
"version": "1.2.23",
|
"version": "1.2.24",
|
||||||
"description": "",
|
"description": "",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"exports": {
|
"exports": {
|
||||||
|
|||||||
@@ -424,6 +424,17 @@ export default function Layout(props: ParentProps) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
e.details?.type === "question.replied" ||
|
||||||
|
e.details?.type === "question.rejected" ||
|
||||||
|
e.details?.type === "permission.replied"
|
||||||
|
) {
|
||||||
|
const props = e.details.properties as { sessionID: string }
|
||||||
|
const sessionKey = `${e.name}:${props.sessionID}`
|
||||||
|
dismissSessionAlert(sessionKey)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
if (e.details?.type !== "permission.asked" && e.details?.type !== "question.asked") return
|
if (e.details?.type !== "permission.asked" && e.details?.type !== "question.asked") return
|
||||||
const title =
|
const title =
|
||||||
e.details.type === "permission.asked"
|
e.details.type === "permission.asked"
|
||||||
|
|||||||
@@ -37,7 +37,6 @@ import { createOpenReviewFile, createSizing } from "@/pages/session/helpers"
|
|||||||
import { MessageTimeline } from "@/pages/session/message-timeline"
|
import { MessageTimeline } from "@/pages/session/message-timeline"
|
||||||
import { type DiffStyle, SessionReviewTab, type SessionReviewTabProps } from "@/pages/session/review-tab"
|
import { type DiffStyle, SessionReviewTab, type SessionReviewTabProps } from "@/pages/session/review-tab"
|
||||||
import { resetSessionModel, syncSessionModel } from "@/pages/session/session-model-helpers"
|
import { resetSessionModel, syncSessionModel } from "@/pages/session/session-model-helpers"
|
||||||
import { createScrollSpy } from "@/pages/session/scroll-spy"
|
|
||||||
import { SessionMobileTabs } from "@/pages/session/session-mobile-tabs"
|
import { SessionMobileTabs } from "@/pages/session/session-mobile-tabs"
|
||||||
import { SessionSidePanel } from "@/pages/session/session-side-panel"
|
import { SessionSidePanel } from "@/pages/session/session-side-panel"
|
||||||
import { TerminalPanel } from "@/pages/session/terminal-panel"
|
import { TerminalPanel } from "@/pages/session/terminal-panel"
|
||||||
@@ -486,20 +485,49 @@ export default function Page() {
|
|||||||
return "main"
|
return "main"
|
||||||
})
|
})
|
||||||
|
|
||||||
const activeMessage = createMemo(() => {
|
|
||||||
if (!store.messageId) return lastUserMessage()
|
|
||||||
const found = visibleUserMessages()?.find((m) => m.id === store.messageId)
|
|
||||||
return found ?? lastUserMessage()
|
|
||||||
})
|
|
||||||
const setActiveMessage = (message: UserMessage | undefined) => {
|
const setActiveMessage = (message: UserMessage | undefined) => {
|
||||||
|
messageMark = scrollMark
|
||||||
setStore("messageId", message?.id)
|
setStore("messageId", message?.id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const anchor = (id: string) => `message-${id}`
|
||||||
|
|
||||||
|
const cursor = () => {
|
||||||
|
const root = scroller
|
||||||
|
if (!root) return store.messageId
|
||||||
|
|
||||||
|
const box = root.getBoundingClientRect()
|
||||||
|
const line = box.top + 100
|
||||||
|
const list = [...root.querySelectorAll<HTMLElement>("[data-message-id]")]
|
||||||
|
.map((el) => {
|
||||||
|
const id = el.dataset.messageId
|
||||||
|
if (!id) return
|
||||||
|
|
||||||
|
const rect = el.getBoundingClientRect()
|
||||||
|
return { id, top: rect.top, bottom: rect.bottom }
|
||||||
|
})
|
||||||
|
.filter((item): item is { id: string; top: number; bottom: number } => !!item)
|
||||||
|
|
||||||
|
const shown = list.filter((item) => item.bottom > box.top && item.top < box.bottom)
|
||||||
|
const hit = shown.find((item) => item.top <= line && item.bottom >= line)
|
||||||
|
if (hit) return hit.id
|
||||||
|
|
||||||
|
const near = [...shown].sort((a, b) => {
|
||||||
|
const da = Math.abs(a.top - line)
|
||||||
|
const db = Math.abs(b.top - line)
|
||||||
|
if (da !== db) return da - db
|
||||||
|
return a.top - b.top
|
||||||
|
})[0]
|
||||||
|
if (near) return near.id
|
||||||
|
|
||||||
|
return list.filter((item) => item.top <= line).at(-1)?.id ?? list[0]?.id ?? store.messageId
|
||||||
|
}
|
||||||
|
|
||||||
function navigateMessageByOffset(offset: number) {
|
function navigateMessageByOffset(offset: number) {
|
||||||
const msgs = visibleUserMessages()
|
const msgs = visibleUserMessages()
|
||||||
if (msgs.length === 0) return
|
if (msgs.length === 0) return
|
||||||
|
|
||||||
const current = store.messageId
|
const current = store.messageId && messageMark === scrollMark ? store.messageId : cursor()
|
||||||
const base = current ? msgs.findIndex((m) => m.id === current) : msgs.length
|
const base = current ? msgs.findIndex((m) => m.id === current) : msgs.length
|
||||||
const currentIndex = base === -1 ? msgs.length : base
|
const currentIndex = base === -1 ? msgs.length : base
|
||||||
const targetIndex = currentIndex + offset
|
const targetIndex = currentIndex + offset
|
||||||
@@ -572,6 +600,8 @@ export default function Page() {
|
|||||||
let dockHeight = 0
|
let dockHeight = 0
|
||||||
let scroller: HTMLDivElement | undefined
|
let scroller: HTMLDivElement | undefined
|
||||||
let content: HTMLDivElement | undefined
|
let content: HTMLDivElement | undefined
|
||||||
|
let scrollMark = 0
|
||||||
|
let messageMark = 0
|
||||||
|
|
||||||
const scrollGestureWindowMs = 250
|
const scrollGestureWindowMs = 250
|
||||||
|
|
||||||
@@ -616,6 +646,7 @@ export default function Page() {
|
|||||||
() => {
|
() => {
|
||||||
setStore("messageId", undefined)
|
setStore("messageId", undefined)
|
||||||
setStore("changes", "session")
|
setStore("changes", "session")
|
||||||
|
setUi("pendingMessage", undefined)
|
||||||
},
|
},
|
||||||
{ defer: true },
|
{ defer: true },
|
||||||
),
|
),
|
||||||
@@ -1110,12 +1141,6 @@ export default function Page() {
|
|||||||
|
|
||||||
let scrollStateFrame: number | undefined
|
let scrollStateFrame: number | undefined
|
||||||
let scrollStateTarget: HTMLDivElement | undefined
|
let scrollStateTarget: HTMLDivElement | undefined
|
||||||
const scrollSpy = createScrollSpy({
|
|
||||||
onActive: (id) => {
|
|
||||||
if (id === store.messageId) return
|
|
||||||
setStore("messageId", id)
|
|
||||||
},
|
|
||||||
})
|
|
||||||
|
|
||||||
const updateScrollState = (el: HTMLDivElement) => {
|
const updateScrollState = (el: HTMLDivElement) => {
|
||||||
const max = el.scrollHeight - el.clientHeight
|
const max = el.scrollHeight - el.clientHeight
|
||||||
@@ -1163,31 +1188,21 @@ export default function Page() {
|
|||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
createEffect(
|
|
||||||
on(
|
|
||||||
sessionKey,
|
|
||||||
() => {
|
|
||||||
scrollSpy.clear()
|
|
||||||
},
|
|
||||||
{ defer: true },
|
|
||||||
),
|
|
||||||
)
|
|
||||||
|
|
||||||
const anchor = (id: string) => `message-${id}`
|
|
||||||
|
|
||||||
const setScrollRef = (el: HTMLDivElement | undefined) => {
|
const setScrollRef = (el: HTMLDivElement | undefined) => {
|
||||||
scroller = el
|
scroller = el
|
||||||
autoScroll.scrollRef(el)
|
autoScroll.scrollRef(el)
|
||||||
scrollSpy.setContainer(el)
|
|
||||||
if (el) scheduleScrollState(el)
|
if (el) scheduleScrollState(el)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const markUserScroll = () => {
|
||||||
|
scrollMark += 1
|
||||||
|
}
|
||||||
|
|
||||||
createResizeObserver(
|
createResizeObserver(
|
||||||
() => content,
|
() => content,
|
||||||
() => {
|
() => {
|
||||||
const el = scroller
|
const el = scroller
|
||||||
if (el) scheduleScrollState(el)
|
if (el) scheduleScrollState(el)
|
||||||
scrollSpy.markDirty()
|
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -1220,7 +1235,6 @@ export default function Page() {
|
|||||||
if (stick) autoScroll.forceScrollToBottom()
|
if (stick) autoScroll.forceScrollToBottom()
|
||||||
|
|
||||||
if (el) scheduleScrollState(el)
|
if (el) scheduleScrollState(el)
|
||||||
scrollSpy.markDirty()
|
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -1248,7 +1262,6 @@ export default function Page() {
|
|||||||
|
|
||||||
onCleanup(() => {
|
onCleanup(() => {
|
||||||
document.removeEventListener("keydown", handleKeyDown)
|
document.removeEventListener("keydown", handleKeyDown)
|
||||||
scrollSpy.destroy()
|
|
||||||
if (reviewFrame !== undefined) cancelAnimationFrame(reviewFrame)
|
if (reviewFrame !== undefined) cancelAnimationFrame(reviewFrame)
|
||||||
if (scrollStateFrame !== undefined) cancelAnimationFrame(scrollStateFrame)
|
if (scrollStateFrame !== undefined) cancelAnimationFrame(scrollStateFrame)
|
||||||
})
|
})
|
||||||
@@ -1280,7 +1293,7 @@ export default function Page() {
|
|||||||
<div class="flex-1 min-h-0 overflow-hidden">
|
<div class="flex-1 min-h-0 overflow-hidden">
|
||||||
<Switch>
|
<Switch>
|
||||||
<Match when={params.id}>
|
<Match when={params.id}>
|
||||||
<Show when={activeMessage()}>
|
<Show when={lastUserMessage()}>
|
||||||
<MessageTimeline
|
<MessageTimeline
|
||||||
mobileChanges={mobileChanges()}
|
mobileChanges={mobileChanges()}
|
||||||
mobileFallback={reviewContent({
|
mobileFallback={reviewContent({
|
||||||
@@ -1300,8 +1313,7 @@ export default function Page() {
|
|||||||
onAutoScrollHandleScroll={autoScroll.handleScroll}
|
onAutoScrollHandleScroll={autoScroll.handleScroll}
|
||||||
onMarkScrollGesture={markScrollGesture}
|
onMarkScrollGesture={markScrollGesture}
|
||||||
hasScrollGesture={hasScrollGesture}
|
hasScrollGesture={hasScrollGesture}
|
||||||
isDesktop={isDesktop()}
|
onUserScroll={markUserScroll}
|
||||||
onScrollSpyScroll={scrollSpy.onScroll}
|
|
||||||
onTurnBackfillScroll={historyWindow.onScrollerScroll}
|
onTurnBackfillScroll={historyWindow.onScrollerScroll}
|
||||||
onAutoScrollInteraction={autoScroll.handleInteraction}
|
onAutoScrollInteraction={autoScroll.handleInteraction}
|
||||||
centered={centered()}
|
centered={centered()}
|
||||||
@@ -1320,8 +1332,6 @@ export default function Page() {
|
|||||||
}}
|
}}
|
||||||
renderedUserMessages={historyWindow.renderedUserMessages()}
|
renderedUserMessages={historyWindow.renderedUserMessages()}
|
||||||
anchor={anchor}
|
anchor={anchor}
|
||||||
onRegisterMessage={scrollSpy.register}
|
|
||||||
onUnregisterMessage={scrollSpy.unregister}
|
|
||||||
/>
|
/>
|
||||||
</Show>
|
</Show>
|
||||||
</Match>
|
</Match>
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import { IconButton } from "@opencode-ai/ui/icon-button"
|
|||||||
import { DropdownMenu } from "@opencode-ai/ui/dropdown-menu"
|
import { DropdownMenu } from "@opencode-ai/ui/dropdown-menu"
|
||||||
import { Dialog } from "@opencode-ai/ui/dialog"
|
import { Dialog } from "@opencode-ai/ui/dialog"
|
||||||
import { InlineInput } from "@opencode-ai/ui/inline-input"
|
import { InlineInput } from "@opencode-ai/ui/inline-input"
|
||||||
|
import { Spinner } from "@opencode-ai/ui/spinner"
|
||||||
import { SessionTurn } from "@opencode-ai/ui/session-turn"
|
import { SessionTurn } from "@opencode-ai/ui/session-turn"
|
||||||
import { ScrollView } from "@opencode-ai/ui/scroll-view"
|
import { ScrollView } from "@opencode-ai/ui/scroll-view"
|
||||||
import type { AssistantMessage, Message as MessageType, Part, TextPart, UserMessage } from "@opencode-ai/sdk/v2"
|
import type { AssistantMessage, Message as MessageType, Part, TextPart, UserMessage } from "@opencode-ai/sdk/v2"
|
||||||
@@ -192,8 +193,7 @@ export function MessageTimeline(props: {
|
|||||||
onAutoScrollHandleScroll: () => void
|
onAutoScrollHandleScroll: () => void
|
||||||
onMarkScrollGesture: (target?: EventTarget | null) => void
|
onMarkScrollGesture: (target?: EventTarget | null) => void
|
||||||
hasScrollGesture: () => boolean
|
hasScrollGesture: () => boolean
|
||||||
isDesktop: boolean
|
onUserScroll: () => void
|
||||||
onScrollSpyScroll: () => void
|
|
||||||
onTurnBackfillScroll: () => void
|
onTurnBackfillScroll: () => void
|
||||||
onAutoScrollInteraction: (event: MouseEvent) => void
|
onAutoScrollInteraction: (event: MouseEvent) => void
|
||||||
centered: boolean
|
centered: boolean
|
||||||
@@ -204,8 +204,6 @@ export function MessageTimeline(props: {
|
|||||||
onLoadEarlier: () => void
|
onLoadEarlier: () => void
|
||||||
renderedUserMessages: UserMessage[]
|
renderedUserMessages: UserMessage[]
|
||||||
anchor: (id: string) => string
|
anchor: (id: string) => string
|
||||||
onRegisterMessage: (el: HTMLDivElement, id: string) => void
|
|
||||||
onUnregisterMessage: (id: string) => void
|
|
||||||
}) {
|
}) {
|
||||||
let touchGesture: number | undefined
|
let touchGesture: number | undefined
|
||||||
|
|
||||||
@@ -235,6 +233,40 @@ export function MessageTimeline(props: {
|
|||||||
if (!id) return idle
|
if (!id) return idle
|
||||||
return sync.data.session_status[id] ?? idle
|
return sync.data.session_status[id] ?? idle
|
||||||
})
|
})
|
||||||
|
const working = createMemo(() => !!pending() || sessionStatus().type !== "idle")
|
||||||
|
|
||||||
|
const [slot, setSlot] = createStore({
|
||||||
|
open: false,
|
||||||
|
show: false,
|
||||||
|
fade: false,
|
||||||
|
})
|
||||||
|
|
||||||
|
let f: number | undefined
|
||||||
|
const clear = () => {
|
||||||
|
if (f !== undefined) window.clearTimeout(f)
|
||||||
|
f = undefined
|
||||||
|
}
|
||||||
|
|
||||||
|
onCleanup(clear)
|
||||||
|
createEffect(
|
||||||
|
on(
|
||||||
|
working,
|
||||||
|
(on, prev) => {
|
||||||
|
clear()
|
||||||
|
if (on) {
|
||||||
|
setSlot({ open: true, show: true, fade: false })
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (prev) {
|
||||||
|
setSlot({ open: false, show: true, fade: true })
|
||||||
|
f = window.setTimeout(() => setSlot({ show: false, fade: false }), 260)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
setSlot({ open: false, show: false, fade: false })
|
||||||
|
},
|
||||||
|
{ defer: true },
|
||||||
|
),
|
||||||
|
)
|
||||||
const activeMessageID = createMemo(() => {
|
const activeMessageID = createMemo(() => {
|
||||||
const parentID = pending()?.parentID
|
const parentID = pending()?.parentID
|
||||||
if (parentID) {
|
if (parentID) {
|
||||||
@@ -539,9 +571,9 @@ export function MessageTimeline(props: {
|
|||||||
props.onScheduleScrollState(e.currentTarget)
|
props.onScheduleScrollState(e.currentTarget)
|
||||||
props.onTurnBackfillScroll()
|
props.onTurnBackfillScroll()
|
||||||
if (!props.hasScrollGesture()) return
|
if (!props.hasScrollGesture()) return
|
||||||
|
props.onUserScroll()
|
||||||
props.onAutoScrollHandleScroll()
|
props.onAutoScrollHandleScroll()
|
||||||
props.onMarkScrollGesture(e.currentTarget)
|
props.onMarkScrollGesture(e.currentTarget)
|
||||||
if (props.isDesktop) props.onScrollSpyScroll()
|
|
||||||
}}
|
}}
|
||||||
onClick={props.onAutoScrollInteraction}
|
onClick={props.onAutoScrollInteraction}
|
||||||
class="relative min-w-0 w-full h-full"
|
class="relative min-w-0 w-full h-full"
|
||||||
@@ -573,43 +605,64 @@ export function MessageTimeline(props: {
|
|||||||
aria-label={language.t("common.goBack")}
|
aria-label={language.t("common.goBack")}
|
||||||
/>
|
/>
|
||||||
</Show>
|
</Show>
|
||||||
<Show when={titleValue() || title.editing}>
|
<div class="flex items-center min-w-0 grow-1">
|
||||||
<Show
|
<div
|
||||||
when={title.editing}
|
class="shrink-0 flex items-center justify-center overflow-hidden transition-[width,margin] duration-300 ease-[cubic-bezier(0.22,1,0.36,1)]"
|
||||||
fallback={
|
style={{
|
||||||
<h1
|
width: slot.open ? "16px" : "0px",
|
||||||
class="text-14-medium text-text-strong truncate grow-1 min-w-0 pl-2"
|
"margin-right": slot.open ? "8px" : "0px",
|
||||||
onDblClick={openTitleEditor}
|
}}
|
||||||
>
|
aria-hidden="true"
|
||||||
{titleValue()}
|
|
||||||
</h1>
|
|
||||||
}
|
|
||||||
>
|
>
|
||||||
<InlineInput
|
<Show when={slot.show}>
|
||||||
ref={(el) => {
|
<div
|
||||||
titleRef = el
|
class="transition-opacity duration-200 ease-out"
|
||||||
}}
|
classList={{
|
||||||
value={title.draft}
|
"opacity-0": slot.fade,
|
||||||
disabled={title.saving}
|
}}
|
||||||
class="text-14-medium text-text-strong grow-1 min-w-0 pl-2 rounded-[6px]"
|
>
|
||||||
style={{ "--inline-input-shadow": "var(--shadow-xs-border-select)" }}
|
<Spinner class="size-4" style={{ color: "var(--icon-interactive-base)" }} />
|
||||||
onInput={(event) => setTitle("draft", event.currentTarget.value)}
|
</div>
|
||||||
onKeyDown={(event) => {
|
</Show>
|
||||||
event.stopPropagation()
|
</div>
|
||||||
if (event.key === "Enter") {
|
<Show when={titleValue() || title.editing}>
|
||||||
event.preventDefault()
|
<Show
|
||||||
void saveTitleEditor()
|
when={title.editing}
|
||||||
return
|
fallback={
|
||||||
}
|
<h1
|
||||||
if (event.key === "Escape") {
|
class="text-14-medium text-text-strong truncate grow-1 min-w-0"
|
||||||
event.preventDefault()
|
onDblClick={openTitleEditor}
|
||||||
closeTitleEditor()
|
>
|
||||||
}
|
{titleValue()}
|
||||||
}}
|
</h1>
|
||||||
onBlur={closeTitleEditor}
|
}
|
||||||
/>
|
>
|
||||||
|
<InlineInput
|
||||||
|
ref={(el) => {
|
||||||
|
titleRef = el
|
||||||
|
}}
|
||||||
|
value={title.draft}
|
||||||
|
disabled={title.saving}
|
||||||
|
class="text-14-medium text-text-strong grow-1 min-w-0 rounded-[6px]"
|
||||||
|
style={{ "--inline-input-shadow": "var(--shadow-xs-border-select)" }}
|
||||||
|
onInput={(event) => setTitle("draft", event.currentTarget.value)}
|
||||||
|
onKeyDown={(event) => {
|
||||||
|
event.stopPropagation()
|
||||||
|
if (event.key === "Enter") {
|
||||||
|
event.preventDefault()
|
||||||
|
void saveTitleEditor()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (event.key === "Escape") {
|
||||||
|
event.preventDefault()
|
||||||
|
closeTitleEditor()
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
onBlur={closeTitleEditor}
|
||||||
|
/>
|
||||||
|
</Show>
|
||||||
</Show>
|
</Show>
|
||||||
</Show>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<Show when={sessionID()}>
|
<Show when={sessionID()}>
|
||||||
{(id) => (
|
{(id) => (
|
||||||
@@ -707,10 +760,6 @@ export function MessageTimeline(props: {
|
|||||||
<div
|
<div
|
||||||
id={props.anchor(messageID)}
|
id={props.anchor(messageID)}
|
||||||
data-message-id={messageID}
|
data-message-id={messageID}
|
||||||
ref={(el) => {
|
|
||||||
props.onRegisterMessage(el, messageID)
|
|
||||||
onCleanup(() => props.onUnregisterMessage(messageID))
|
|
||||||
}}
|
|
||||||
classList={{
|
classList={{
|
||||||
"min-w-0 w-full max-w-full": true,
|
"min-w-0 w-full max-w-full": true,
|
||||||
"md:max-w-200 2xl:max-w-[1000px]": props.centered,
|
"md:max-w-200 2xl:max-w-[1000px]": props.centered,
|
||||||
|
|||||||
@@ -1,127 +0,0 @@
|
|||||||
import { describe, expect, test } from "bun:test"
|
|
||||||
import { createScrollSpy, pickOffsetId, pickVisibleId } from "./scroll-spy"
|
|
||||||
|
|
||||||
const rect = (top: number, height = 80): DOMRect =>
|
|
||||||
({
|
|
||||||
x: 0,
|
|
||||||
y: top,
|
|
||||||
top,
|
|
||||||
left: 0,
|
|
||||||
right: 800,
|
|
||||||
bottom: top + height,
|
|
||||||
width: 800,
|
|
||||||
height,
|
|
||||||
toJSON: () => ({}),
|
|
||||||
}) as DOMRect
|
|
||||||
|
|
||||||
const setRect = (el: Element, top: number, height = 80) => {
|
|
||||||
Object.defineProperty(el, "getBoundingClientRect", {
|
|
||||||
configurable: true,
|
|
||||||
value: () => rect(top, height),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
describe("pickVisibleId", () => {
|
|
||||||
test("prefers higher intersection ratio", () => {
|
|
||||||
const id = pickVisibleId(
|
|
||||||
[
|
|
||||||
{ id: "a", ratio: 0.2, top: 100 },
|
|
||||||
{ id: "b", ratio: 0.8, top: 300 },
|
|
||||||
],
|
|
||||||
120,
|
|
||||||
)
|
|
||||||
|
|
||||||
expect(id).toBe("b")
|
|
||||||
})
|
|
||||||
|
|
||||||
test("breaks ratio ties by nearest line", () => {
|
|
||||||
const id = pickVisibleId(
|
|
||||||
[
|
|
||||||
{ id: "a", ratio: 0.5, top: 90 },
|
|
||||||
{ id: "b", ratio: 0.5, top: 140 },
|
|
||||||
],
|
|
||||||
130,
|
|
||||||
)
|
|
||||||
|
|
||||||
expect(id).toBe("b")
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
describe("pickOffsetId", () => {
|
|
||||||
test("uses binary search cutoff", () => {
|
|
||||||
const id = pickOffsetId(
|
|
||||||
[
|
|
||||||
{ id: "a", top: 0 },
|
|
||||||
{ id: "b", top: 200 },
|
|
||||||
{ id: "c", top: 400 },
|
|
||||||
],
|
|
||||||
350,
|
|
||||||
)
|
|
||||||
|
|
||||||
expect(id).toBe("b")
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
describe("createScrollSpy fallback", () => {
|
|
||||||
test("tracks active id from offsets and dirty refresh", () => {
|
|
||||||
const active: string[] = []
|
|
||||||
const root = document.createElement("div") as HTMLDivElement
|
|
||||||
const one = document.createElement("div")
|
|
||||||
const two = document.createElement("div")
|
|
||||||
const three = document.createElement("div")
|
|
||||||
|
|
||||||
root.append(one, two, three)
|
|
||||||
document.body.append(root)
|
|
||||||
|
|
||||||
Object.defineProperty(root, "scrollTop", { configurable: true, writable: true, value: 250 })
|
|
||||||
setRect(root, 0, 800)
|
|
||||||
setRect(one, -250)
|
|
||||||
setRect(two, -50)
|
|
||||||
setRect(three, 150)
|
|
||||||
|
|
||||||
const queue: FrameRequestCallback[] = []
|
|
||||||
const flush = () => {
|
|
||||||
const run = [...queue]
|
|
||||||
queue.length = 0
|
|
||||||
for (const cb of run) cb(0)
|
|
||||||
}
|
|
||||||
|
|
||||||
const spy = createScrollSpy({
|
|
||||||
onActive: (id) => active.push(id),
|
|
||||||
raf: (cb) => (queue.push(cb), queue.length),
|
|
||||||
caf: () => {},
|
|
||||||
IntersectionObserver: undefined,
|
|
||||||
ResizeObserver: undefined,
|
|
||||||
MutationObserver: undefined,
|
|
||||||
})
|
|
||||||
|
|
||||||
spy.setContainer(root)
|
|
||||||
spy.register(one, "a")
|
|
||||||
spy.register(two, "b")
|
|
||||||
spy.register(three, "c")
|
|
||||||
spy.onScroll()
|
|
||||||
flush()
|
|
||||||
|
|
||||||
expect(spy.getActiveId()).toBe("b")
|
|
||||||
expect(active.at(-1)).toBe("b")
|
|
||||||
|
|
||||||
root.scrollTop = 450
|
|
||||||
setRect(one, -450)
|
|
||||||
setRect(two, -250)
|
|
||||||
setRect(three, -50)
|
|
||||||
spy.onScroll()
|
|
||||||
flush()
|
|
||||||
expect(spy.getActiveId()).toBe("c")
|
|
||||||
|
|
||||||
root.scrollTop = 250
|
|
||||||
setRect(one, -250)
|
|
||||||
setRect(two, 250)
|
|
||||||
setRect(three, 150)
|
|
||||||
spy.markDirty()
|
|
||||||
spy.onScroll()
|
|
||||||
flush()
|
|
||||||
expect(spy.getActiveId()).toBe("a")
|
|
||||||
|
|
||||||
spy.destroy()
|
|
||||||
})
|
|
||||||
})
|
|
||||||
@@ -1,275 +0,0 @@
|
|||||||
type Visible = {
|
|
||||||
id: string
|
|
||||||
ratio: number
|
|
||||||
top: number
|
|
||||||
}
|
|
||||||
|
|
||||||
type Offset = {
|
|
||||||
id: string
|
|
||||||
top: number
|
|
||||||
}
|
|
||||||
|
|
||||||
type Input = {
|
|
||||||
onActive: (id: string) => void
|
|
||||||
raf?: (cb: FrameRequestCallback) => number
|
|
||||||
caf?: (id: number) => void
|
|
||||||
IntersectionObserver?: typeof globalThis.IntersectionObserver
|
|
||||||
ResizeObserver?: typeof globalThis.ResizeObserver
|
|
||||||
MutationObserver?: typeof globalThis.MutationObserver
|
|
||||||
}
|
|
||||||
|
|
||||||
export const pickVisibleId = (list: Visible[], line: number) => {
|
|
||||||
if (list.length === 0) return
|
|
||||||
|
|
||||||
const sorted = [...list].sort((a, b) => {
|
|
||||||
if (b.ratio !== a.ratio) return b.ratio - a.ratio
|
|
||||||
|
|
||||||
const da = Math.abs(a.top - line)
|
|
||||||
const db = Math.abs(b.top - line)
|
|
||||||
if (da !== db) return da - db
|
|
||||||
|
|
||||||
return a.top - b.top
|
|
||||||
})
|
|
||||||
|
|
||||||
return sorted[0]?.id
|
|
||||||
}
|
|
||||||
|
|
||||||
export const pickOffsetId = (list: Offset[], cutoff: number) => {
|
|
||||||
if (list.length === 0) return
|
|
||||||
|
|
||||||
let lo = 0
|
|
||||||
let hi = list.length - 1
|
|
||||||
let out = 0
|
|
||||||
|
|
||||||
while (lo <= hi) {
|
|
||||||
const mid = (lo + hi) >> 1
|
|
||||||
const top = list[mid]?.top
|
|
||||||
if (top === undefined) break
|
|
||||||
|
|
||||||
if (top <= cutoff) {
|
|
||||||
out = mid
|
|
||||||
lo = mid + 1
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
hi = mid - 1
|
|
||||||
}
|
|
||||||
|
|
||||||
return list[out]?.id
|
|
||||||
}
|
|
||||||
|
|
||||||
export const createScrollSpy = (input: Input) => {
|
|
||||||
const raf = input.raf ?? requestAnimationFrame
|
|
||||||
const caf = input.caf ?? cancelAnimationFrame
|
|
||||||
const CtorIO = input.IntersectionObserver ?? globalThis.IntersectionObserver
|
|
||||||
const CtorRO = input.ResizeObserver ?? globalThis.ResizeObserver
|
|
||||||
const CtorMO = input.MutationObserver ?? globalThis.MutationObserver
|
|
||||||
|
|
||||||
let root: HTMLDivElement | undefined
|
|
||||||
let io: IntersectionObserver | undefined
|
|
||||||
let ro: ResizeObserver | undefined
|
|
||||||
let mo: MutationObserver | undefined
|
|
||||||
let frame: number | undefined
|
|
||||||
let active: string | undefined
|
|
||||||
let dirty = true
|
|
||||||
|
|
||||||
const node = new Map<string, HTMLElement>()
|
|
||||||
const id = new WeakMap<HTMLElement, string>()
|
|
||||||
const visible = new Map<string, { ratio: number; top: number }>()
|
|
||||||
let offset: Offset[] = []
|
|
||||||
|
|
||||||
const schedule = () => {
|
|
||||||
if (frame !== undefined) return
|
|
||||||
frame = raf(() => {
|
|
||||||
frame = undefined
|
|
||||||
update()
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
const refreshOffset = () => {
|
|
||||||
const el = root
|
|
||||||
if (!el) {
|
|
||||||
offset = []
|
|
||||||
dirty = false
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
const base = el.getBoundingClientRect().top
|
|
||||||
offset = [...node].map(([next, item]) => ({
|
|
||||||
id: next,
|
|
||||||
top: item.getBoundingClientRect().top - base + el.scrollTop,
|
|
||||||
}))
|
|
||||||
offset.sort((a, b) => a.top - b.top)
|
|
||||||
dirty = false
|
|
||||||
}
|
|
||||||
|
|
||||||
const update = () => {
|
|
||||||
const el = root
|
|
||||||
if (!el) return
|
|
||||||
|
|
||||||
const line = el.getBoundingClientRect().top + 100
|
|
||||||
const next =
|
|
||||||
pickVisibleId(
|
|
||||||
[...visible].map(([k, v]) => ({
|
|
||||||
id: k,
|
|
||||||
ratio: v.ratio,
|
|
||||||
top: v.top,
|
|
||||||
})),
|
|
||||||
line,
|
|
||||||
) ??
|
|
||||||
(() => {
|
|
||||||
if (dirty) refreshOffset()
|
|
||||||
return pickOffsetId(offset, el.scrollTop + 100)
|
|
||||||
})()
|
|
||||||
|
|
||||||
if (!next || next === active) return
|
|
||||||
active = next
|
|
||||||
input.onActive(next)
|
|
||||||
}
|
|
||||||
|
|
||||||
const observe = () => {
|
|
||||||
const el = root
|
|
||||||
if (!el) return
|
|
||||||
|
|
||||||
io?.disconnect()
|
|
||||||
io = undefined
|
|
||||||
if (CtorIO) {
|
|
||||||
try {
|
|
||||||
io = new CtorIO(
|
|
||||||
(entries) => {
|
|
||||||
for (const entry of entries) {
|
|
||||||
const item = entry.target
|
|
||||||
if (!(item instanceof HTMLElement)) continue
|
|
||||||
const key = id.get(item)
|
|
||||||
if (!key) continue
|
|
||||||
|
|
||||||
if (!entry.isIntersecting || entry.intersectionRatio <= 0) {
|
|
||||||
visible.delete(key)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
visible.set(key, {
|
|
||||||
ratio: entry.intersectionRatio,
|
|
||||||
top: entry.boundingClientRect.top,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
schedule()
|
|
||||||
},
|
|
||||||
{
|
|
||||||
root: el,
|
|
||||||
threshold: [0, 0.25, 0.5, 0.75, 1],
|
|
||||||
},
|
|
||||||
)
|
|
||||||
} catch {
|
|
||||||
io = undefined
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (io) {
|
|
||||||
for (const item of node.values()) io.observe(item)
|
|
||||||
}
|
|
||||||
|
|
||||||
ro?.disconnect()
|
|
||||||
ro = undefined
|
|
||||||
if (CtorRO) {
|
|
||||||
ro = new CtorRO(() => {
|
|
||||||
dirty = true
|
|
||||||
schedule()
|
|
||||||
})
|
|
||||||
ro.observe(el)
|
|
||||||
for (const item of node.values()) ro.observe(item)
|
|
||||||
}
|
|
||||||
|
|
||||||
mo?.disconnect()
|
|
||||||
mo = undefined
|
|
||||||
if (CtorMO) {
|
|
||||||
mo = new CtorMO(() => {
|
|
||||||
dirty = true
|
|
||||||
schedule()
|
|
||||||
})
|
|
||||||
mo.observe(el, { subtree: true, childList: true, characterData: true })
|
|
||||||
}
|
|
||||||
|
|
||||||
dirty = true
|
|
||||||
schedule()
|
|
||||||
}
|
|
||||||
|
|
||||||
const setContainer = (el?: HTMLDivElement) => {
|
|
||||||
if (root === el) return
|
|
||||||
|
|
||||||
root = el
|
|
||||||
visible.clear()
|
|
||||||
active = undefined
|
|
||||||
observe()
|
|
||||||
}
|
|
||||||
|
|
||||||
const register = (el: HTMLElement, key: string) => {
|
|
||||||
const prev = node.get(key)
|
|
||||||
if (prev && prev !== el) {
|
|
||||||
io?.unobserve(prev)
|
|
||||||
ro?.unobserve(prev)
|
|
||||||
}
|
|
||||||
|
|
||||||
node.set(key, el)
|
|
||||||
id.set(el, key)
|
|
||||||
if (io) io.observe(el)
|
|
||||||
if (ro) ro.observe(el)
|
|
||||||
dirty = true
|
|
||||||
schedule()
|
|
||||||
}
|
|
||||||
|
|
||||||
const unregister = (key: string) => {
|
|
||||||
const item = node.get(key)
|
|
||||||
if (!item) return
|
|
||||||
|
|
||||||
io?.unobserve(item)
|
|
||||||
ro?.unobserve(item)
|
|
||||||
node.delete(key)
|
|
||||||
visible.delete(key)
|
|
||||||
dirty = true
|
|
||||||
schedule()
|
|
||||||
}
|
|
||||||
|
|
||||||
const markDirty = () => {
|
|
||||||
dirty = true
|
|
||||||
schedule()
|
|
||||||
}
|
|
||||||
|
|
||||||
const clear = () => {
|
|
||||||
for (const item of node.values()) {
|
|
||||||
io?.unobserve(item)
|
|
||||||
ro?.unobserve(item)
|
|
||||||
}
|
|
||||||
|
|
||||||
node.clear()
|
|
||||||
visible.clear()
|
|
||||||
offset = []
|
|
||||||
active = undefined
|
|
||||||
dirty = true
|
|
||||||
}
|
|
||||||
|
|
||||||
const destroy = () => {
|
|
||||||
if (frame !== undefined) caf(frame)
|
|
||||||
frame = undefined
|
|
||||||
clear()
|
|
||||||
io?.disconnect()
|
|
||||||
ro?.disconnect()
|
|
||||||
mo?.disconnect()
|
|
||||||
io = undefined
|
|
||||||
ro = undefined
|
|
||||||
mo = undefined
|
|
||||||
root = undefined
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
setContainer,
|
|
||||||
register,
|
|
||||||
unregister,
|
|
||||||
onScroll: schedule,
|
|
||||||
markDirty,
|
|
||||||
clear,
|
|
||||||
destroy,
|
|
||||||
getActiveId: () => active,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
import type { UserMessage } from "@opencode-ai/sdk/v2"
|
import type { UserMessage } from "@opencode-ai/sdk/v2"
|
||||||
import { useLocation, useNavigate } from "@solidjs/router"
|
import { useLocation, useNavigate } from "@solidjs/router"
|
||||||
import { createEffect, createMemo, onMount } from "solid-js"
|
import { createEffect, createMemo, onCleanup, onMount } from "solid-js"
|
||||||
import { messageIdFromHash } from "./message-id-from-hash"
|
import { messageIdFromHash } from "./message-id-from-hash"
|
||||||
|
|
||||||
export { messageIdFromHash } from "./message-id-from-hash"
|
export { messageIdFromHash } from "./message-id-from-hash"
|
||||||
@@ -26,17 +26,38 @@ export const useSessionHashScroll = (input: {
|
|||||||
const messageById = createMemo(() => new Map(visibleUserMessages().map((m) => [m.id, m])))
|
const messageById = createMemo(() => new Map(visibleUserMessages().map((m) => [m.id, m])))
|
||||||
const messageIndex = createMemo(() => new Map(visibleUserMessages().map((m, i) => [m.id, i])))
|
const messageIndex = createMemo(() => new Map(visibleUserMessages().map((m, i) => [m.id, i])))
|
||||||
let pendingKey = ""
|
let pendingKey = ""
|
||||||
|
let clearing = false
|
||||||
|
|
||||||
const location = useLocation()
|
const location = useLocation()
|
||||||
const navigate = useNavigate()
|
const navigate = useNavigate()
|
||||||
|
|
||||||
|
const frames = new Set<number>()
|
||||||
|
const queue = (fn: () => void) => {
|
||||||
|
const id = requestAnimationFrame(() => {
|
||||||
|
frames.delete(id)
|
||||||
|
fn()
|
||||||
|
})
|
||||||
|
frames.add(id)
|
||||||
|
}
|
||||||
|
const cancel = () => {
|
||||||
|
for (const id of frames) cancelAnimationFrame(id)
|
||||||
|
frames.clear()
|
||||||
|
}
|
||||||
|
|
||||||
const clearMessageHash = () => {
|
const clearMessageHash = () => {
|
||||||
|
cancel()
|
||||||
|
input.consumePendingMessage(input.sessionKey())
|
||||||
|
if (input.pendingMessage()) input.setPendingMessage(undefined)
|
||||||
if (!location.hash) return
|
if (!location.hash) return
|
||||||
|
clearing = true
|
||||||
navigate(location.pathname + location.search, { replace: true })
|
navigate(location.pathname + location.search, { replace: true })
|
||||||
}
|
}
|
||||||
|
|
||||||
const updateHash = (id: string) => {
|
const updateHash = (id: string) => {
|
||||||
navigate(location.pathname + location.search + `#${input.anchor(id)}`, {
|
const hash = `#${input.anchor(id)}`
|
||||||
|
if (location.hash === hash) return
|
||||||
|
clearing = false
|
||||||
|
navigate(location.pathname + location.search + hash, {
|
||||||
replace: true,
|
replace: true,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -54,51 +75,37 @@ export const useSessionHashScroll = (input: {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const seek = (id: string, behavior: ScrollBehavior, left = 4): boolean => {
|
||||||
|
const el = document.getElementById(input.anchor(id))
|
||||||
|
if (el) return scrollToElement(el, behavior)
|
||||||
|
if (left <= 0) return false
|
||||||
|
queue(() => {
|
||||||
|
seek(id, behavior, left - 1)
|
||||||
|
})
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
const scrollToMessage = (message: UserMessage, behavior: ScrollBehavior = "smooth") => {
|
const scrollToMessage = (message: UserMessage, behavior: ScrollBehavior = "smooth") => {
|
||||||
console.log({ message, behavior })
|
cancel()
|
||||||
if (input.currentMessageId() !== message.id) input.setActiveMessage(message)
|
if (input.currentMessageId() !== message.id) input.setActiveMessage(message)
|
||||||
|
|
||||||
const index = messageIndex().get(message.id) ?? -1
|
const index = messageIndex().get(message.id) ?? -1
|
||||||
if (index !== -1 && index < input.turnStart()) {
|
if (index !== -1 && index < input.turnStart()) {
|
||||||
input.setTurnStart(index)
|
input.setTurnStart(index)
|
||||||
|
|
||||||
requestAnimationFrame(() => {
|
queue(() => {
|
||||||
const el = document.getElementById(input.anchor(message.id))
|
seek(message.id, behavior)
|
||||||
if (!el) {
|
|
||||||
requestAnimationFrame(() => {
|
|
||||||
const next = document.getElementById(input.anchor(message.id))
|
|
||||||
if (!next) return
|
|
||||||
scrollToElement(next, behavior)
|
|
||||||
})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
scrollToElement(el, behavior)
|
|
||||||
})
|
})
|
||||||
|
|
||||||
updateHash(message.id)
|
updateHash(message.id)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
const el = document.getElementById(input.anchor(message.id))
|
if (seek(message.id, behavior)) {
|
||||||
if (!el) {
|
|
||||||
updateHash(message.id)
|
|
||||||
requestAnimationFrame(() => {
|
|
||||||
const next = document.getElementById(input.anchor(message.id))
|
|
||||||
if (!next) return
|
|
||||||
if (!scrollToElement(next, behavior)) return
|
|
||||||
})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if (scrollToElement(el, behavior)) {
|
|
||||||
updateHash(message.id)
|
updateHash(message.id)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
requestAnimationFrame(() => {
|
|
||||||
const next = document.getElementById(input.anchor(message.id))
|
|
||||||
if (!next) return
|
|
||||||
if (!scrollToElement(next, behavior)) return
|
|
||||||
})
|
|
||||||
updateHash(message.id)
|
updateHash(message.id)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -135,9 +142,11 @@ export const useSessionHashScroll = (input: {
|
|||||||
}
|
}
|
||||||
|
|
||||||
createEffect(() => {
|
createEffect(() => {
|
||||||
location.hash
|
const hash = location.hash
|
||||||
|
if (!hash) clearing = false
|
||||||
if (!input.sessionID() || !input.messagesReady()) return
|
if (!input.sessionID() || !input.messagesReady()) return
|
||||||
requestAnimationFrame(() => applyHash("auto"))
|
cancel()
|
||||||
|
queue(() => applyHash("auto"))
|
||||||
})
|
})
|
||||||
|
|
||||||
createEffect(() => {
|
createEffect(() => {
|
||||||
@@ -159,16 +168,19 @@ export const useSessionHashScroll = (input: {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!targetId) targetId = messageIdFromHash(location.hash)
|
if (!targetId && !clearing) targetId = messageIdFromHash(location.hash)
|
||||||
if (!targetId) return
|
if (!targetId) return
|
||||||
if (input.currentMessageId() === targetId) return
|
|
||||||
|
|
||||||
|
const pending = input.pendingMessage() === targetId
|
||||||
const msg = messageById().get(targetId)
|
const msg = messageById().get(targetId)
|
||||||
if (!msg) return
|
if (!msg) return
|
||||||
|
|
||||||
if (input.pendingMessage() === targetId) input.setPendingMessage(undefined)
|
if (pending) input.setPendingMessage(undefined)
|
||||||
|
if (input.currentMessageId() === targetId && !pending) return
|
||||||
|
|
||||||
input.autoScroll.pause()
|
input.autoScroll.pause()
|
||||||
requestAnimationFrame(() => scrollToMessage(msg, "auto"))
|
cancel()
|
||||||
|
queue(() => scrollToMessage(msg, "auto"))
|
||||||
})
|
})
|
||||||
|
|
||||||
onMount(() => {
|
onMount(() => {
|
||||||
@@ -177,6 +189,8 @@ export const useSessionHashScroll = (input: {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
onCleanup(cancel)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
clearMessageHash,
|
clearMessageHash,
|
||||||
scrollToMessage,
|
scrollToMessage,
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@opencode-ai/console-app",
|
"name": "@opencode-ai/console-app",
|
||||||
"version": "1.2.23",
|
"version": "1.2.24",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"$schema": "https://json.schemastore.org/package.json",
|
"$schema": "https://json.schemastore.org/package.json",
|
||||||
"name": "@opencode-ai/console-core",
|
"name": "@opencode-ai/console-core",
|
||||||
"version": "1.2.23",
|
"version": "1.2.24",
|
||||||
"private": true,
|
"private": true,
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@opencode-ai/console-function",
|
"name": "@opencode-ai/console-function",
|
||||||
"version": "1.2.23",
|
"version": "1.2.24",
|
||||||
"$schema": "https://json.schemastore.org/package.json",
|
"$schema": "https://json.schemastore.org/package.json",
|
||||||
"private": true,
|
"private": true,
|
||||||
"type": "module",
|
"type": "module",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@opencode-ai/console-mail",
|
"name": "@opencode-ai/console-mail",
|
||||||
"version": "1.2.23",
|
"version": "1.2.24",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@jsx-email/all": "2.2.3",
|
"@jsx-email/all": "2.2.3",
|
||||||
"@jsx-email/cli": "1.4.3",
|
"@jsx-email/cli": "1.4.3",
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "@opencode-ai/desktop-electron",
|
"name": "@opencode-ai/desktop-electron",
|
||||||
"private": true,
|
"private": true,
|
||||||
"version": "1.2.23",
|
"version": "1.2.24",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"homepage": "https://opencode.ai",
|
"homepage": "https://opencode.ai",
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "@opencode-ai/desktop",
|
"name": "@opencode-ai/desktop",
|
||||||
"private": true,
|
"private": true,
|
||||||
"version": "1.2.23",
|
"version": "1.2.24",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@opencode-ai/enterprise",
|
"name": "@opencode-ai/enterprise",
|
||||||
"version": "1.2.23",
|
"version": "1.2.24",
|
||||||
"private": true,
|
"private": true,
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
id = "opencode"
|
id = "opencode"
|
||||||
name = "OpenCode"
|
name = "OpenCode"
|
||||||
description = "The open source coding agent."
|
description = "The open source coding agent."
|
||||||
version = "1.2.23"
|
version = "1.2.24"
|
||||||
schema_version = 1
|
schema_version = 1
|
||||||
authors = ["Anomaly"]
|
authors = ["Anomaly"]
|
||||||
repository = "https://github.com/anomalyco/opencode"
|
repository = "https://github.com/anomalyco/opencode"
|
||||||
@@ -11,26 +11,26 @@ name = "OpenCode"
|
|||||||
icon = "./icons/opencode.svg"
|
icon = "./icons/opencode.svg"
|
||||||
|
|
||||||
[agent_servers.opencode.targets.darwin-aarch64]
|
[agent_servers.opencode.targets.darwin-aarch64]
|
||||||
archive = "https://github.com/anomalyco/opencode/releases/download/v1.2.23/opencode-darwin-arm64.zip"
|
archive = "https://github.com/anomalyco/opencode/releases/download/v1.2.24/opencode-darwin-arm64.zip"
|
||||||
cmd = "./opencode"
|
cmd = "./opencode"
|
||||||
args = ["acp"]
|
args = ["acp"]
|
||||||
|
|
||||||
[agent_servers.opencode.targets.darwin-x86_64]
|
[agent_servers.opencode.targets.darwin-x86_64]
|
||||||
archive = "https://github.com/anomalyco/opencode/releases/download/v1.2.23/opencode-darwin-x64.zip"
|
archive = "https://github.com/anomalyco/opencode/releases/download/v1.2.24/opencode-darwin-x64.zip"
|
||||||
cmd = "./opencode"
|
cmd = "./opencode"
|
||||||
args = ["acp"]
|
args = ["acp"]
|
||||||
|
|
||||||
[agent_servers.opencode.targets.linux-aarch64]
|
[agent_servers.opencode.targets.linux-aarch64]
|
||||||
archive = "https://github.com/anomalyco/opencode/releases/download/v1.2.23/opencode-linux-arm64.tar.gz"
|
archive = "https://github.com/anomalyco/opencode/releases/download/v1.2.24/opencode-linux-arm64.tar.gz"
|
||||||
cmd = "./opencode"
|
cmd = "./opencode"
|
||||||
args = ["acp"]
|
args = ["acp"]
|
||||||
|
|
||||||
[agent_servers.opencode.targets.linux-x86_64]
|
[agent_servers.opencode.targets.linux-x86_64]
|
||||||
archive = "https://github.com/anomalyco/opencode/releases/download/v1.2.23/opencode-linux-x64.tar.gz"
|
archive = "https://github.com/anomalyco/opencode/releases/download/v1.2.24/opencode-linux-x64.tar.gz"
|
||||||
cmd = "./opencode"
|
cmd = "./opencode"
|
||||||
args = ["acp"]
|
args = ["acp"]
|
||||||
|
|
||||||
[agent_servers.opencode.targets.windows-x86_64]
|
[agent_servers.opencode.targets.windows-x86_64]
|
||||||
archive = "https://github.com/anomalyco/opencode/releases/download/v1.2.23/opencode-windows-x64.zip"
|
archive = "https://github.com/anomalyco/opencode/releases/download/v1.2.24/opencode-windows-x64.zip"
|
||||||
cmd = "./opencode.exe"
|
cmd = "./opencode.exe"
|
||||||
args = ["acp"]
|
args = ["acp"]
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@opencode-ai/function",
|
"name": "@opencode-ai/function",
|
||||||
"version": "1.2.23",
|
"version": "1.2.24",
|
||||||
"$schema": "https://json.schemastore.org/package.json",
|
"$schema": "https://json.schemastore.org/package.json",
|
||||||
"private": true,
|
"private": true,
|
||||||
"type": "module",
|
"type": "module",
|
||||||
|
|||||||
@@ -1,136 +0,0 @@
|
|||||||
# Bun shell migration plan
|
|
||||||
|
|
||||||
Practical phased replacement of Bun `$` calls.
|
|
||||||
|
|
||||||
## Goal
|
|
||||||
|
|
||||||
Replace runtime Bun shell template-tag usage in `packages/opencode/src` with a unified `Process` API in `util/process.ts`.
|
|
||||||
|
|
||||||
Keep behavior stable while improving safety, testability, and observability.
|
|
||||||
|
|
||||||
Current baseline from audit:
|
|
||||||
|
|
||||||
- 143 runtime command invocations across 17 files
|
|
||||||
- 84 are git commands
|
|
||||||
- Largest hotspots:
|
|
||||||
- `src/cli/cmd/github.ts` (33)
|
|
||||||
- `src/worktree/index.ts` (22)
|
|
||||||
- `src/lsp/server.ts` (21)
|
|
||||||
- `src/installation/index.ts` (20)
|
|
||||||
- `src/snapshot/index.ts` (18)
|
|
||||||
|
|
||||||
## Decisions
|
|
||||||
|
|
||||||
- Extend `src/util/process.ts` (do not create a separate exec module).
|
|
||||||
- Proceed with phased migration for both git and non-git paths.
|
|
||||||
- Keep plugin `$` compatibility in 1.x and remove in 2.0.
|
|
||||||
|
|
||||||
## Non-goals
|
|
||||||
|
|
||||||
- Do not remove plugin `$` compatibility in this effort.
|
|
||||||
- Do not redesign command semantics beyond what is needed to preserve behavior.
|
|
||||||
|
|
||||||
## Constraints
|
|
||||||
|
|
||||||
- Keep migration phased, not big-bang.
|
|
||||||
- Minimize behavioral drift.
|
|
||||||
- Keep these explicit shell-only exceptions:
|
|
||||||
- `src/session/prompt.ts` raw command execution
|
|
||||||
- worktree start scripts in `src/worktree/index.ts`
|
|
||||||
|
|
||||||
## Process API proposal (`src/util/process.ts`)
|
|
||||||
|
|
||||||
Add higher-level wrappers on top of current spawn support.
|
|
||||||
|
|
||||||
Core methods:
|
|
||||||
|
|
||||||
- `Process.run(cmd, opts)`
|
|
||||||
- `Process.text(cmd, opts)`
|
|
||||||
- `Process.lines(cmd, opts)`
|
|
||||||
- `Process.status(cmd, opts)`
|
|
||||||
- `Process.shell(command, opts)` for intentional shell execution
|
|
||||||
|
|
||||||
Git helpers:
|
|
||||||
|
|
||||||
- `Process.git(args, opts)`
|
|
||||||
- `Process.gitText(args, opts)`
|
|
||||||
|
|
||||||
Shared options:
|
|
||||||
|
|
||||||
- `cwd`, `env`, `stdin`, `stdout`, `stderr`, `abort`, `timeout`, `kill`
|
|
||||||
- `allowFailure` / non-throw mode
|
|
||||||
- optional redaction + trace metadata
|
|
||||||
|
|
||||||
Standard result shape:
|
|
||||||
|
|
||||||
- `code`, `stdout`, `stderr`, `duration_ms`, `cmd`
|
|
||||||
- helpers like `text()` and `arrayBuffer()` where useful
|
|
||||||
|
|
||||||
## Phased rollout
|
|
||||||
|
|
||||||
### Phase 0: Foundation
|
|
||||||
|
|
||||||
- Implement Process wrappers in `src/util/process.ts`.
|
|
||||||
- Refactor `src/util/git.ts` to use Process only.
|
|
||||||
- Add tests for exit handling, timeout, abort, and output capture.
|
|
||||||
|
|
||||||
### Phase 1: High-impact hotspots
|
|
||||||
|
|
||||||
Migrate these first:
|
|
||||||
|
|
||||||
- `src/cli/cmd/github.ts`
|
|
||||||
- `src/worktree/index.ts`
|
|
||||||
- `src/lsp/server.ts`
|
|
||||||
- `src/installation/index.ts`
|
|
||||||
- `src/snapshot/index.ts`
|
|
||||||
|
|
||||||
Within each file, migrate git paths first where applicable.
|
|
||||||
|
|
||||||
### Phase 2: Remaining git-heavy files
|
|
||||||
|
|
||||||
Migrate git-centric call sites to `Process.git*` helpers:
|
|
||||||
|
|
||||||
- `src/file/index.ts`
|
|
||||||
- `src/project/vcs.ts`
|
|
||||||
- `src/file/watcher.ts`
|
|
||||||
- `src/storage/storage.ts`
|
|
||||||
- `src/cli/cmd/pr.ts`
|
|
||||||
|
|
||||||
### Phase 3: Remaining non-git files
|
|
||||||
|
|
||||||
Migrate residual non-git usages:
|
|
||||||
|
|
||||||
- `src/cli/cmd/tui/util/clipboard.ts`
|
|
||||||
- `src/util/archive.ts`
|
|
||||||
- `src/file/ripgrep.ts`
|
|
||||||
- `src/tool/bash.ts`
|
|
||||||
- `src/cli/cmd/uninstall.ts`
|
|
||||||
|
|
||||||
### Phase 4: Stabilize
|
|
||||||
|
|
||||||
- Remove dead wrappers and one-off patterns.
|
|
||||||
- Keep plugin `$` compatibility isolated and documented as temporary.
|
|
||||||
- Create linked 2.0 task for plugin `$` removal.
|
|
||||||
|
|
||||||
## Validation strategy
|
|
||||||
|
|
||||||
- Unit tests for new `Process` methods and options.
|
|
||||||
- Integration tests on hotspot modules.
|
|
||||||
- Smoke tests for install, snapshot, worktree, and GitHub flows.
|
|
||||||
- Regression checks for output parsing behavior.
|
|
||||||
|
|
||||||
## Risk mitigation
|
|
||||||
|
|
||||||
- File-by-file PRs with small diffs.
|
|
||||||
- Preserve behavior first, simplify second.
|
|
||||||
- Keep shell-only exceptions explicit and documented.
|
|
||||||
- Add consistent error shaping and logging at Process layer.
|
|
||||||
|
|
||||||
## Definition of done
|
|
||||||
|
|
||||||
- Runtime Bun `$` usage in `packages/opencode/src` is removed except:
|
|
||||||
- approved shell-only exceptions
|
|
||||||
- temporary plugin compatibility path (1.x)
|
|
||||||
- Git paths use `Process.git*` consistently.
|
|
||||||
- CI and targeted smoke tests pass.
|
|
||||||
- 2.0 issue exists for plugin `$` removal.
|
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"$schema": "https://json.schemastore.org/package.json",
|
"$schema": "https://json.schemastore.org/package.json",
|
||||||
"version": "1.2.23",
|
"version": "1.2.24",
|
||||||
"name": "opencode",
|
"name": "opencode",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
@@ -41,6 +41,7 @@
|
|||||||
"@types/babel__core": "7.20.5",
|
"@types/babel__core": "7.20.5",
|
||||||
"@types/bun": "catalog:",
|
"@types/bun": "catalog:",
|
||||||
"@types/mime-types": "3.0.1",
|
"@types/mime-types": "3.0.1",
|
||||||
|
"@types/semver": "^7.5.8",
|
||||||
"@types/turndown": "5.0.5",
|
"@types/turndown": "5.0.5",
|
||||||
"@types/yargs": "17.0.33",
|
"@types/yargs": "17.0.33",
|
||||||
"@types/which": "3.0.4",
|
"@types/which": "3.0.4",
|
||||||
@@ -80,6 +81,8 @@
|
|||||||
"@gitlab/gitlab-ai-provider": "3.6.0",
|
"@gitlab/gitlab-ai-provider": "3.6.0",
|
||||||
"@gitlab/opencode-gitlab-auth": "1.3.3",
|
"@gitlab/opencode-gitlab-auth": "1.3.3",
|
||||||
"@hono/standard-validator": "0.1.5",
|
"@hono/standard-validator": "0.1.5",
|
||||||
|
"@hono/node-server": "1.19.11",
|
||||||
|
"@hono/node-ws": "1.3.0",
|
||||||
"@hono/zod-validator": "catalog:",
|
"@hono/zod-validator": "catalog:",
|
||||||
"@modelcontextprotocol/sdk": "1.25.2",
|
"@modelcontextprotocol/sdk": "1.25.2",
|
||||||
"@octokit/graphql": "9.0.2",
|
"@octokit/graphql": "9.0.2",
|
||||||
@@ -121,6 +124,7 @@
|
|||||||
"opentui-spinner": "0.0.6",
|
"opentui-spinner": "0.0.6",
|
||||||
"partial-json": "0.1.7",
|
"partial-json": "0.1.7",
|
||||||
"remeda": "catalog:",
|
"remeda": "catalog:",
|
||||||
|
"semver": "^7.6.3",
|
||||||
"solid-js": "catalog:",
|
"solid-js": "catalog:",
|
||||||
"strip-ansi": "7.1.2",
|
"strip-ansi": "7.1.2",
|
||||||
"tree-sitter-bash": "0.25.0",
|
"tree-sitter-bash": "0.25.0",
|
||||||
|
|||||||
Executable
+8
@@ -0,0 +1,8 @@
|
|||||||
|
#!/usr/bin/env bun
|
||||||
|
|
||||||
|
Bun.build({
|
||||||
|
entrypoints: ["./src/node.ts"],
|
||||||
|
target: "node",
|
||||||
|
outdir: "./dist",
|
||||||
|
format: "esm",
|
||||||
|
})
|
||||||
@@ -29,7 +29,7 @@ import {
|
|||||||
} from "@agentclientprotocol/sdk"
|
} from "@agentclientprotocol/sdk"
|
||||||
|
|
||||||
import { Log } from "../util/log"
|
import { Log } from "../util/log"
|
||||||
import { pathToFileURL } from "bun"
|
import { pathToFileURL } from "url"
|
||||||
import { Filesystem } from "../util/filesystem"
|
import { Filesystem } from "../util/filesystem"
|
||||||
import { Hash } from "../util/hash"
|
import { Hash } from "../util/hash"
|
||||||
import { ACPSessionManager } from "./session"
|
import { ACPSessionManager } from "./session"
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { semver } from "bun"
|
import semver from "semver"
|
||||||
import { text } from "node:stream/consumers"
|
import { text } from "node:stream/consumers"
|
||||||
import { Log } from "../util/log"
|
import { Log } from "../util/log"
|
||||||
import { Process } from "../util/process"
|
import { Process } from "../util/process"
|
||||||
@@ -45,6 +45,6 @@ export namespace PackageRegistry {
|
|||||||
const isRange = /[\s^~*xX<>|=]/.test(cachedVersion)
|
const isRange = /[\s^~*xX<>|=]/.test(cachedVersion)
|
||||||
if (isRange) return !semver.satisfies(latestVersion, cachedVersion)
|
if (isRange) return !semver.satisfies(latestVersion, cachedVersion)
|
||||||
|
|
||||||
return semver.order(cachedVersion, latestVersion) === -1
|
return semver.lt(cachedVersion, latestVersion)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,8 +27,9 @@ import { Provider } from "../../provider/provider"
|
|||||||
import { Bus } from "../../bus"
|
import { Bus } from "../../bus"
|
||||||
import { MessageV2 } from "../../session/message-v2"
|
import { MessageV2 } from "../../session/message-v2"
|
||||||
import { SessionPrompt } from "@/session/prompt"
|
import { SessionPrompt } from "@/session/prompt"
|
||||||
import { $ } from "bun"
|
|
||||||
import { setTimeout as sleep } from "node:timers/promises"
|
import { setTimeout as sleep } from "node:timers/promises"
|
||||||
|
import { Process } from "@/util/process"
|
||||||
|
import { git } from "@/util/git"
|
||||||
|
|
||||||
type GitHubAuthor = {
|
type GitHubAuthor = {
|
||||||
login: string
|
login: string
|
||||||
@@ -255,7 +256,7 @@ export const GithubInstallCommand = cmd({
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Get repo info
|
// Get repo info
|
||||||
const info = (await $`git remote get-url origin`.quiet().nothrow().text()).trim()
|
const info = (await git(["remote", "get-url", "origin"], { cwd: Instance.worktree })).text().trim()
|
||||||
const parsed = parseGitHubRemote(info)
|
const parsed = parseGitHubRemote(info)
|
||||||
if (!parsed) {
|
if (!parsed) {
|
||||||
prompts.log.error(`Could not find git repository. Please run this command from a git repository.`)
|
prompts.log.error(`Could not find git repository. Please run this command from a git repository.`)
|
||||||
@@ -493,6 +494,26 @@ export const GithubRunCommand = cmd({
|
|||||||
? "pr_review"
|
? "pr_review"
|
||||||
: "issue"
|
: "issue"
|
||||||
: undefined
|
: undefined
|
||||||
|
const gitText = async (args: string[]) => {
|
||||||
|
const result = await git(args, { cwd: Instance.worktree })
|
||||||
|
if (result.exitCode !== 0) {
|
||||||
|
throw new Process.RunFailedError(["git", ...args], result.exitCode, result.stdout, result.stderr)
|
||||||
|
}
|
||||||
|
return result.text().trim()
|
||||||
|
}
|
||||||
|
const gitRun = async (args: string[]) => {
|
||||||
|
const result = await git(args, { cwd: Instance.worktree })
|
||||||
|
if (result.exitCode !== 0) {
|
||||||
|
throw new Process.RunFailedError(["git", ...args], result.exitCode, result.stdout, result.stderr)
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
const gitStatus = (args: string[]) => git(args, { cwd: Instance.worktree })
|
||||||
|
const commitChanges = async (summary: string, actor?: string) => {
|
||||||
|
const args = ["commit", "-m", summary]
|
||||||
|
if (actor) args.push("-m", `Co-authored-by: ${actor} <${actor}@users.noreply.github.com>`)
|
||||||
|
await gitRun(args)
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (useGithubToken) {
|
if (useGithubToken) {
|
||||||
@@ -553,7 +574,7 @@ export const GithubRunCommand = cmd({
|
|||||||
}
|
}
|
||||||
const branchPrefix = isWorkflowDispatchEvent ? "dispatch" : "schedule"
|
const branchPrefix = isWorkflowDispatchEvent ? "dispatch" : "schedule"
|
||||||
const branch = await checkoutNewBranch(branchPrefix)
|
const branch = await checkoutNewBranch(branchPrefix)
|
||||||
const head = (await $`git rev-parse HEAD`).stdout.toString().trim()
|
const head = await gitText(["rev-parse", "HEAD"])
|
||||||
const response = await chat(userPrompt, promptFiles)
|
const response = await chat(userPrompt, promptFiles)
|
||||||
const { dirty, uncommittedChanges, switched } = await branchIsDirty(head, branch)
|
const { dirty, uncommittedChanges, switched } = await branchIsDirty(head, branch)
|
||||||
if (switched) {
|
if (switched) {
|
||||||
@@ -587,7 +608,7 @@ export const GithubRunCommand = cmd({
|
|||||||
// Local PR
|
// Local PR
|
||||||
if (prData.headRepository.nameWithOwner === prData.baseRepository.nameWithOwner) {
|
if (prData.headRepository.nameWithOwner === prData.baseRepository.nameWithOwner) {
|
||||||
await checkoutLocalBranch(prData)
|
await checkoutLocalBranch(prData)
|
||||||
const head = (await $`git rev-parse HEAD`).stdout.toString().trim()
|
const head = await gitText(["rev-parse", "HEAD"])
|
||||||
const dataPrompt = buildPromptDataForPR(prData)
|
const dataPrompt = buildPromptDataForPR(prData)
|
||||||
const response = await chat(`${userPrompt}\n\n${dataPrompt}`, promptFiles)
|
const response = await chat(`${userPrompt}\n\n${dataPrompt}`, promptFiles)
|
||||||
const { dirty, uncommittedChanges, switched } = await branchIsDirty(head, prData.headRefName)
|
const { dirty, uncommittedChanges, switched } = await branchIsDirty(head, prData.headRefName)
|
||||||
@@ -605,7 +626,7 @@ export const GithubRunCommand = cmd({
|
|||||||
// Fork PR
|
// Fork PR
|
||||||
else {
|
else {
|
||||||
const forkBranch = await checkoutForkBranch(prData)
|
const forkBranch = await checkoutForkBranch(prData)
|
||||||
const head = (await $`git rev-parse HEAD`).stdout.toString().trim()
|
const head = await gitText(["rev-parse", "HEAD"])
|
||||||
const dataPrompt = buildPromptDataForPR(prData)
|
const dataPrompt = buildPromptDataForPR(prData)
|
||||||
const response = await chat(`${userPrompt}\n\n${dataPrompt}`, promptFiles)
|
const response = await chat(`${userPrompt}\n\n${dataPrompt}`, promptFiles)
|
||||||
const { dirty, uncommittedChanges, switched } = await branchIsDirty(head, forkBranch)
|
const { dirty, uncommittedChanges, switched } = await branchIsDirty(head, forkBranch)
|
||||||
@@ -624,7 +645,7 @@ export const GithubRunCommand = cmd({
|
|||||||
// Issue
|
// Issue
|
||||||
else {
|
else {
|
||||||
const branch = await checkoutNewBranch("issue")
|
const branch = await checkoutNewBranch("issue")
|
||||||
const head = (await $`git rev-parse HEAD`).stdout.toString().trim()
|
const head = await gitText(["rev-parse", "HEAD"])
|
||||||
const issueData = await fetchIssue()
|
const issueData = await fetchIssue()
|
||||||
const dataPrompt = buildPromptDataForIssue(issueData)
|
const dataPrompt = buildPromptDataForIssue(issueData)
|
||||||
const response = await chat(`${userPrompt}\n\n${dataPrompt}`, promptFiles)
|
const response = await chat(`${userPrompt}\n\n${dataPrompt}`, promptFiles)
|
||||||
@@ -658,7 +679,7 @@ export const GithubRunCommand = cmd({
|
|||||||
exitCode = 1
|
exitCode = 1
|
||||||
console.error(e instanceof Error ? e.message : String(e))
|
console.error(e instanceof Error ? e.message : String(e))
|
||||||
let msg = e
|
let msg = e
|
||||||
if (e instanceof $.ShellError) {
|
if (e instanceof Process.RunFailedError) {
|
||||||
msg = e.stderr.toString()
|
msg = e.stderr.toString()
|
||||||
} else if (e instanceof Error) {
|
} else if (e instanceof Error) {
|
||||||
msg = e.message
|
msg = e.message
|
||||||
@@ -1049,29 +1070,29 @@ export const GithubRunCommand = cmd({
|
|||||||
const config = "http.https://github.com/.extraheader"
|
const config = "http.https://github.com/.extraheader"
|
||||||
// actions/checkout@v6 no longer stores credentials in .git/config,
|
// actions/checkout@v6 no longer stores credentials in .git/config,
|
||||||
// so this may not exist - use nothrow() to handle gracefully
|
// so this may not exist - use nothrow() to handle gracefully
|
||||||
const ret = await $`git config --local --get ${config}`.nothrow()
|
const ret = await gitStatus(["config", "--local", "--get", config])
|
||||||
if (ret.exitCode === 0) {
|
if (ret.exitCode === 0) {
|
||||||
gitConfig = ret.stdout.toString().trim()
|
gitConfig = ret.stdout.toString().trim()
|
||||||
await $`git config --local --unset-all ${config}`
|
await gitRun(["config", "--local", "--unset-all", config])
|
||||||
}
|
}
|
||||||
|
|
||||||
const newCredentials = Buffer.from(`x-access-token:${appToken}`, "utf8").toString("base64")
|
const newCredentials = Buffer.from(`x-access-token:${appToken}`, "utf8").toString("base64")
|
||||||
|
|
||||||
await $`git config --local ${config} "AUTHORIZATION: basic ${newCredentials}"`
|
await gitRun(["config", "--local", config, `AUTHORIZATION: basic ${newCredentials}`])
|
||||||
await $`git config --global user.name "${AGENT_USERNAME}"`
|
await gitRun(["config", "--global", "user.name", AGENT_USERNAME])
|
||||||
await $`git config --global user.email "${AGENT_USERNAME}@users.noreply.github.com"`
|
await gitRun(["config", "--global", "user.email", `${AGENT_USERNAME}@users.noreply.github.com`])
|
||||||
}
|
}
|
||||||
|
|
||||||
async function restoreGitConfig() {
|
async function restoreGitConfig() {
|
||||||
if (gitConfig === undefined) return
|
if (gitConfig === undefined) return
|
||||||
const config = "http.https://github.com/.extraheader"
|
const config = "http.https://github.com/.extraheader"
|
||||||
await $`git config --local ${config} "${gitConfig}"`
|
await gitRun(["config", "--local", config, gitConfig])
|
||||||
}
|
}
|
||||||
|
|
||||||
async function checkoutNewBranch(type: "issue" | "schedule" | "dispatch") {
|
async function checkoutNewBranch(type: "issue" | "schedule" | "dispatch") {
|
||||||
console.log("Checking out new branch...")
|
console.log("Checking out new branch...")
|
||||||
const branch = generateBranchName(type)
|
const branch = generateBranchName(type)
|
||||||
await $`git checkout -b ${branch}`
|
await gitRun(["checkout", "-b", branch])
|
||||||
return branch
|
return branch
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1081,8 +1102,8 @@ export const GithubRunCommand = cmd({
|
|||||||
const branch = pr.headRefName
|
const branch = pr.headRefName
|
||||||
const depth = Math.max(pr.commits.totalCount, 20)
|
const depth = Math.max(pr.commits.totalCount, 20)
|
||||||
|
|
||||||
await $`git fetch origin --depth=${depth} ${branch}`
|
await gitRun(["fetch", "origin", `--depth=${depth}`, branch])
|
||||||
await $`git checkout ${branch}`
|
await gitRun(["checkout", branch])
|
||||||
}
|
}
|
||||||
|
|
||||||
async function checkoutForkBranch(pr: GitHubPullRequest) {
|
async function checkoutForkBranch(pr: GitHubPullRequest) {
|
||||||
@@ -1092,9 +1113,9 @@ export const GithubRunCommand = cmd({
|
|||||||
const localBranch = generateBranchName("pr")
|
const localBranch = generateBranchName("pr")
|
||||||
const depth = Math.max(pr.commits.totalCount, 20)
|
const depth = Math.max(pr.commits.totalCount, 20)
|
||||||
|
|
||||||
await $`git remote add fork https://github.com/${pr.headRepository.nameWithOwner}.git`
|
await gitRun(["remote", "add", "fork", `https://github.com/${pr.headRepository.nameWithOwner}.git`])
|
||||||
await $`git fetch fork --depth=${depth} ${remoteBranch}`
|
await gitRun(["fetch", "fork", `--depth=${depth}`, remoteBranch])
|
||||||
await $`git checkout -b ${localBranch} fork/${remoteBranch}`
|
await gitRun(["checkout", "-b", localBranch, `fork/${remoteBranch}`])
|
||||||
return localBranch
|
return localBranch
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1115,28 +1136,23 @@ export const GithubRunCommand = cmd({
|
|||||||
async function pushToNewBranch(summary: string, branch: string, commit: boolean, isSchedule: boolean) {
|
async function pushToNewBranch(summary: string, branch: string, commit: boolean, isSchedule: boolean) {
|
||||||
console.log("Pushing to new branch...")
|
console.log("Pushing to new branch...")
|
||||||
if (commit) {
|
if (commit) {
|
||||||
await $`git add .`
|
await gitRun(["add", "."])
|
||||||
if (isSchedule) {
|
if (isSchedule) {
|
||||||
// No co-author for scheduled events - the schedule is operating as the repo
|
await commitChanges(summary)
|
||||||
await $`git commit -m "${summary}"`
|
|
||||||
} else {
|
} else {
|
||||||
await $`git commit -m "${summary}
|
await commitChanges(summary, actor)
|
||||||
|
|
||||||
Co-authored-by: ${actor} <${actor}@users.noreply.github.com>"`
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
await $`git push -u origin ${branch}`
|
await gitRun(["push", "-u", "origin", branch])
|
||||||
}
|
}
|
||||||
|
|
||||||
async function pushToLocalBranch(summary: string, commit: boolean) {
|
async function pushToLocalBranch(summary: string, commit: boolean) {
|
||||||
console.log("Pushing to local branch...")
|
console.log("Pushing to local branch...")
|
||||||
if (commit) {
|
if (commit) {
|
||||||
await $`git add .`
|
await gitRun(["add", "."])
|
||||||
await $`git commit -m "${summary}
|
await commitChanges(summary, actor)
|
||||||
|
|
||||||
Co-authored-by: ${actor} <${actor}@users.noreply.github.com>"`
|
|
||||||
}
|
}
|
||||||
await $`git push`
|
await gitRun(["push"])
|
||||||
}
|
}
|
||||||
|
|
||||||
async function pushToForkBranch(summary: string, pr: GitHubPullRequest, commit: boolean) {
|
async function pushToForkBranch(summary: string, pr: GitHubPullRequest, commit: boolean) {
|
||||||
@@ -1145,30 +1161,28 @@ Co-authored-by: ${actor} <${actor}@users.noreply.github.com>"`
|
|||||||
const remoteBranch = pr.headRefName
|
const remoteBranch = pr.headRefName
|
||||||
|
|
||||||
if (commit) {
|
if (commit) {
|
||||||
await $`git add .`
|
await gitRun(["add", "."])
|
||||||
await $`git commit -m "${summary}
|
await commitChanges(summary, actor)
|
||||||
|
|
||||||
Co-authored-by: ${actor} <${actor}@users.noreply.github.com>"`
|
|
||||||
}
|
}
|
||||||
await $`git push fork HEAD:${remoteBranch}`
|
await gitRun(["push", "fork", `HEAD:${remoteBranch}`])
|
||||||
}
|
}
|
||||||
|
|
||||||
async function branchIsDirty(originalHead: string, expectedBranch: string) {
|
async function branchIsDirty(originalHead: string, expectedBranch: string) {
|
||||||
console.log("Checking if branch is dirty...")
|
console.log("Checking if branch is dirty...")
|
||||||
// Detect if the agent switched branches during chat (e.g. created
|
// Detect if the agent switched branches during chat (e.g. created
|
||||||
// its own branch, committed, and possibly pushed/created a PR).
|
// its own branch, committed, and possibly pushed/created a PR).
|
||||||
const current = (await $`git rev-parse --abbrev-ref HEAD`).stdout.toString().trim()
|
const current = await gitText(["rev-parse", "--abbrev-ref", "HEAD"])
|
||||||
if (current !== expectedBranch) {
|
if (current !== expectedBranch) {
|
||||||
console.log(`Branch changed during chat: expected ${expectedBranch}, now on ${current}`)
|
console.log(`Branch changed during chat: expected ${expectedBranch}, now on ${current}`)
|
||||||
return { dirty: true, uncommittedChanges: false, switched: true }
|
return { dirty: true, uncommittedChanges: false, switched: true }
|
||||||
}
|
}
|
||||||
|
|
||||||
const ret = await $`git status --porcelain`
|
const ret = await gitStatus(["status", "--porcelain"])
|
||||||
const status = ret.stdout.toString().trim()
|
const status = ret.stdout.toString().trim()
|
||||||
if (status.length > 0) {
|
if (status.length > 0) {
|
||||||
return { dirty: true, uncommittedChanges: true, switched: false }
|
return { dirty: true, uncommittedChanges: true, switched: false }
|
||||||
}
|
}
|
||||||
const head = (await $`git rev-parse HEAD`).stdout.toString().trim()
|
const head = await gitText(["rev-parse", "HEAD"])
|
||||||
return {
|
return {
|
||||||
dirty: head !== originalHead,
|
dirty: head !== originalHead,
|
||||||
uncommittedChanges: false,
|
uncommittedChanges: false,
|
||||||
@@ -1180,11 +1194,11 @@ Co-authored-by: ${actor} <${actor}@users.noreply.github.com>"`
|
|||||||
// Falls back to fetching from origin when local refs are missing
|
// Falls back to fetching from origin when local refs are missing
|
||||||
// (common in shallow clones from actions/checkout).
|
// (common in shallow clones from actions/checkout).
|
||||||
async function hasNewCommits(base: string, head: string) {
|
async function hasNewCommits(base: string, head: string) {
|
||||||
const result = await $`git rev-list --count ${base}..${head}`.nothrow()
|
const result = await gitStatus(["rev-list", "--count", `${base}..${head}`])
|
||||||
if (result.exitCode !== 0) {
|
if (result.exitCode !== 0) {
|
||||||
console.log(`rev-list failed, fetching origin/${base}...`)
|
console.log(`rev-list failed, fetching origin/${base}...`)
|
||||||
await $`git fetch origin ${base} --depth=1`.nothrow()
|
await gitStatus(["fetch", "origin", base, "--depth=1"])
|
||||||
const retry = await $`git rev-list --count origin/${base}..${head}`.nothrow()
|
const retry = await gitStatus(["rev-list", "--count", `origin/${base}..${head}`])
|
||||||
if (retry.exitCode !== 0) return true // assume dirty if we can't tell
|
if (retry.exitCode !== 0) return true // assume dirty if we can't tell
|
||||||
return parseInt(retry.stdout.toString().trim()) > 0
|
return parseInt(retry.stdout.toString().trim()) > 0
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
import { UI } from "../ui"
|
import { UI } from "../ui"
|
||||||
import { cmd } from "./cmd"
|
import { cmd } from "./cmd"
|
||||||
import { Instance } from "@/project/instance"
|
import { Instance } from "@/project/instance"
|
||||||
import { $ } from "bun"
|
import { Process } from "@/util/process"
|
||||||
|
import { git } from "@/util/git"
|
||||||
|
|
||||||
export const PrCommand = cmd({
|
export const PrCommand = cmd({
|
||||||
command: "pr <number>",
|
command: "pr <number>",
|
||||||
@@ -27,21 +28,35 @@ export const PrCommand = cmd({
|
|||||||
UI.println(`Fetching and checking out PR #${prNumber}...`)
|
UI.println(`Fetching and checking out PR #${prNumber}...`)
|
||||||
|
|
||||||
// Use gh pr checkout with custom branch name
|
// Use gh pr checkout with custom branch name
|
||||||
const result = await $`gh pr checkout ${prNumber} --branch ${localBranchName} --force`.nothrow()
|
const result = await Process.run(
|
||||||
|
["gh", "pr", "checkout", `${prNumber}`, "--branch", localBranchName, "--force"],
|
||||||
|
{
|
||||||
|
nothrow: true,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
if (result.exitCode !== 0) {
|
if (result.code !== 0) {
|
||||||
UI.error(`Failed to checkout PR #${prNumber}. Make sure you have gh CLI installed and authenticated.`)
|
UI.error(`Failed to checkout PR #${prNumber}. Make sure you have gh CLI installed and authenticated.`)
|
||||||
process.exit(1)
|
process.exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fetch PR info for fork handling and session link detection
|
// Fetch PR info for fork handling and session link detection
|
||||||
const prInfoResult =
|
const prInfoResult = await Process.text(
|
||||||
await $`gh pr view ${prNumber} --json headRepository,headRepositoryOwner,isCrossRepository,headRefName,body`.nothrow()
|
[
|
||||||
|
"gh",
|
||||||
|
"pr",
|
||||||
|
"view",
|
||||||
|
`${prNumber}`,
|
||||||
|
"--json",
|
||||||
|
"headRepository,headRepositoryOwner,isCrossRepository,headRefName,body",
|
||||||
|
],
|
||||||
|
{ nothrow: true },
|
||||||
|
)
|
||||||
|
|
||||||
let sessionId: string | undefined
|
let sessionId: string | undefined
|
||||||
|
|
||||||
if (prInfoResult.exitCode === 0) {
|
if (prInfoResult.code === 0) {
|
||||||
const prInfoText = prInfoResult.text()
|
const prInfoText = prInfoResult.text
|
||||||
if (prInfoText.trim()) {
|
if (prInfoText.trim()) {
|
||||||
const prInfo = JSON.parse(prInfoText)
|
const prInfo = JSON.parse(prInfoText)
|
||||||
|
|
||||||
@@ -52,15 +67,19 @@ export const PrCommand = cmd({
|
|||||||
const remoteName = forkOwner
|
const remoteName = forkOwner
|
||||||
|
|
||||||
// Check if remote already exists
|
// Check if remote already exists
|
||||||
const remotes = (await $`git remote`.nothrow().text()).trim()
|
const remotes = (await git(["remote"], { cwd: Instance.worktree })).text().trim()
|
||||||
if (!remotes.split("\n").includes(remoteName)) {
|
if (!remotes.split("\n").includes(remoteName)) {
|
||||||
await $`git remote add ${remoteName} https://github.com/${forkOwner}/${forkName}.git`.nothrow()
|
await git(["remote", "add", remoteName, `https://github.com/${forkOwner}/${forkName}.git`], {
|
||||||
|
cwd: Instance.worktree,
|
||||||
|
})
|
||||||
UI.println(`Added fork remote: ${remoteName}`)
|
UI.println(`Added fork remote: ${remoteName}`)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set upstream to the fork so pushes go there
|
// Set upstream to the fork so pushes go there
|
||||||
const headRefName = prInfo.headRefName
|
const headRefName = prInfo.headRefName
|
||||||
await $`git branch --set-upstream-to=${remoteName}/${headRefName} ${localBranchName}`.nothrow()
|
await git(["branch", `--set-upstream-to=${remoteName}/${headRefName}`, localBranchName], {
|
||||||
|
cwd: Instance.worktree,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check for opencode session link in PR body
|
// Check for opencode session link in PR body
|
||||||
@@ -71,9 +90,11 @@ export const PrCommand = cmd({
|
|||||||
UI.println(`Found opencode session: ${sessionUrl}`)
|
UI.println(`Found opencode session: ${sessionUrl}`)
|
||||||
UI.println(`Importing session...`)
|
UI.println(`Importing session...`)
|
||||||
|
|
||||||
const importResult = await $`opencode import ${sessionUrl}`.nothrow()
|
const importResult = await Process.text(["opencode", "import", sessionUrl], {
|
||||||
if (importResult.exitCode === 0) {
|
nothrow: true,
|
||||||
const importOutput = importResult.text().trim()
|
})
|
||||||
|
if (importResult.code === 0) {
|
||||||
|
const importOutput = importResult.text.trim()
|
||||||
// Extract session ID from the output (format: "Imported session: <session-id>")
|
// Extract session ID from the output (format: "Imported session: <session-id>")
|
||||||
const sessionIdMatch = importOutput.match(/Imported session: ([a-zA-Z0-9_-]+)/)
|
const sessionIdMatch = importOutput.match(/Imported session: ([a-zA-Z0-9_-]+)/)
|
||||||
if (sessionIdMatch) {
|
if (sessionIdMatch) {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import type { Argv } from "yargs"
|
import type { Argv } from "yargs"
|
||||||
import path from "path"
|
import path from "path"
|
||||||
import { pathToFileURL } from "bun"
|
import { pathToFileURL } from "url"
|
||||||
import { UI } from "../ui"
|
import { UI } from "../ui"
|
||||||
import { cmd } from "./cmd"
|
import { cmd } from "./cmd"
|
||||||
import { Flag } from "../../flag/flag"
|
import { Flag } from "../../flag/flag"
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ import { DialogHelp } from "./ui/dialog-help"
|
|||||||
import { CommandProvider, useCommandDialog } from "@tui/component/dialog-command"
|
import { CommandProvider, useCommandDialog } from "@tui/component/dialog-command"
|
||||||
import { DialogAgent } from "@tui/component/dialog-agent"
|
import { DialogAgent } from "@tui/component/dialog-agent"
|
||||||
import { DialogSessionList } from "@tui/component/dialog-session-list"
|
import { DialogSessionList } from "@tui/component/dialog-session-list"
|
||||||
|
import { DialogWorkspaceList } from "@tui/component/dialog-workspace-list"
|
||||||
import { KeybindProvider } from "@tui/context/keybind"
|
import { KeybindProvider } from "@tui/context/keybind"
|
||||||
import { ThemeProvider, useTheme } from "@tui/context/theme"
|
import { ThemeProvider, useTheme } from "@tui/context/theme"
|
||||||
import { Home } from "@tui/routes/home"
|
import { Home } from "@tui/routes/home"
|
||||||
@@ -371,6 +372,22 @@ function App() {
|
|||||||
dialog.replace(() => <DialogSessionList />)
|
dialog.replace(() => <DialogSessionList />)
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
...(Flag.OPENCODE_EXPERIMENTAL_WORKSPACES_TUI
|
||||||
|
? [
|
||||||
|
{
|
||||||
|
title: "Manage workspaces",
|
||||||
|
value: "workspace.list",
|
||||||
|
category: "Workspace",
|
||||||
|
suggested: true,
|
||||||
|
slash: {
|
||||||
|
name: "workspaces",
|
||||||
|
},
|
||||||
|
onSelect: () => {
|
||||||
|
dialog.replace(() => <DialogWorkspaceList />)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
]
|
||||||
|
: []),
|
||||||
{
|
{
|
||||||
title: "New session",
|
title: "New session",
|
||||||
suggested: route.data.type === "session",
|
suggested: route.data.type === "session",
|
||||||
|
|||||||
@@ -0,0 +1,326 @@
|
|||||||
|
import { useDialog } from "@tui/ui/dialog"
|
||||||
|
import { DialogSelect } from "@tui/ui/dialog-select"
|
||||||
|
import { useRoute } from "@tui/context/route"
|
||||||
|
import { useSync } from "@tui/context/sync"
|
||||||
|
import { createEffect, createMemo, createSignal, onMount } from "solid-js"
|
||||||
|
import type { Session } from "@opencode-ai/sdk/v2"
|
||||||
|
import { useSDK } from "../context/sdk"
|
||||||
|
import { useToast } from "../ui/toast"
|
||||||
|
import { useKeybind } from "../context/keybind"
|
||||||
|
import { DialogSessionList } from "./workspace/dialog-session-list"
|
||||||
|
import { createOpencodeClient } from "@opencode-ai/sdk/v2"
|
||||||
|
|
||||||
|
async function openWorkspace(input: {
|
||||||
|
dialog: ReturnType<typeof useDialog>
|
||||||
|
route: ReturnType<typeof useRoute>
|
||||||
|
sdk: ReturnType<typeof useSDK>
|
||||||
|
sync: ReturnType<typeof useSync>
|
||||||
|
toast: ReturnType<typeof useToast>
|
||||||
|
workspaceID: string
|
||||||
|
forceCreate?: boolean
|
||||||
|
}) {
|
||||||
|
const cacheSession = (session: Session) => {
|
||||||
|
input.sync.set(
|
||||||
|
"session",
|
||||||
|
[...input.sync.data.session.filter((item) => item.id !== session.id), session].toSorted((a, b) =>
|
||||||
|
a.id.localeCompare(b.id),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
const client = createOpencodeClient({
|
||||||
|
baseUrl: input.sdk.url,
|
||||||
|
fetch: input.sdk.fetch,
|
||||||
|
directory: input.sync.data.path.directory || input.sdk.directory,
|
||||||
|
experimental_workspaceID: input.workspaceID,
|
||||||
|
})
|
||||||
|
const listed = input.forceCreate ? undefined : await client.session.list({ roots: true, limit: 1 })
|
||||||
|
const session = listed?.data?.[0]
|
||||||
|
if (session?.id) {
|
||||||
|
cacheSession(session)
|
||||||
|
input.route.navigate({
|
||||||
|
type: "session",
|
||||||
|
sessionID: session.id,
|
||||||
|
})
|
||||||
|
input.dialog.clear()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
let created: Session | undefined
|
||||||
|
while (!created) {
|
||||||
|
const result = await client.session.create({}).catch(() => undefined)
|
||||||
|
if (!result) {
|
||||||
|
input.toast.show({
|
||||||
|
message: "Failed to open workspace",
|
||||||
|
variant: "error",
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (result.response.status >= 500 && result.response.status < 600) {
|
||||||
|
await Bun.sleep(1000)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if (!result.data) {
|
||||||
|
input.toast.show({
|
||||||
|
message: "Failed to open workspace",
|
||||||
|
variant: "error",
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
created = result.data
|
||||||
|
}
|
||||||
|
cacheSession(created)
|
||||||
|
input.route.navigate({
|
||||||
|
type: "session",
|
||||||
|
sessionID: created.id,
|
||||||
|
})
|
||||||
|
input.dialog.clear()
|
||||||
|
}
|
||||||
|
|
||||||
|
function DialogWorkspaceCreate(props: { onSelect: (workspaceID: string) => Promise<void> }) {
|
||||||
|
const dialog = useDialog()
|
||||||
|
const sync = useSync()
|
||||||
|
const sdk = useSDK()
|
||||||
|
const toast = useToast()
|
||||||
|
const [creating, setCreating] = createSignal<string>()
|
||||||
|
|
||||||
|
onMount(() => {
|
||||||
|
dialog.setSize("medium")
|
||||||
|
})
|
||||||
|
|
||||||
|
const options = createMemo(() => {
|
||||||
|
const type = creating()
|
||||||
|
if (type) {
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
title: `Creating ${type} workspace...`,
|
||||||
|
value: "creating" as const,
|
||||||
|
description: "This can take a while for remote environments",
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
title: "Worktree",
|
||||||
|
value: "worktree" as const,
|
||||||
|
description: "Create a local git worktree",
|
||||||
|
},
|
||||||
|
]
|
||||||
|
})
|
||||||
|
|
||||||
|
const createWorkspace = async (type: string) => {
|
||||||
|
if (creating()) return
|
||||||
|
setCreating(type)
|
||||||
|
|
||||||
|
const result = await sdk.client.experimental.workspace.create({ type, branch: null }).catch((err) => {
|
||||||
|
console.log(err)
|
||||||
|
return undefined
|
||||||
|
})
|
||||||
|
console.log(JSON.stringify(result, null, 2))
|
||||||
|
const workspace = result?.data
|
||||||
|
if (!workspace) {
|
||||||
|
setCreating(undefined)
|
||||||
|
toast.show({
|
||||||
|
message: "Failed to create workspace",
|
||||||
|
variant: "error",
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
await sync.workspace.sync()
|
||||||
|
await props.onSelect(workspace.id)
|
||||||
|
setCreating(undefined)
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<DialogSelect
|
||||||
|
title={creating() ? "Creating Workspace" : "New Workspace"}
|
||||||
|
skipFilter={true}
|
||||||
|
options={options()}
|
||||||
|
onSelect={(option) => {
|
||||||
|
if (option.value === "creating") return
|
||||||
|
void createWorkspace(option.value)
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export function DialogWorkspaceList() {
|
||||||
|
const dialog = useDialog()
|
||||||
|
const route = useRoute()
|
||||||
|
const sync = useSync()
|
||||||
|
const sdk = useSDK()
|
||||||
|
const toast = useToast()
|
||||||
|
const keybind = useKeybind()
|
||||||
|
const [toDelete, setToDelete] = createSignal<string>()
|
||||||
|
const [counts, setCounts] = createSignal<Record<string, number | null | undefined>>({})
|
||||||
|
|
||||||
|
const open = (workspaceID: string, forceCreate?: boolean) =>
|
||||||
|
openWorkspace({
|
||||||
|
dialog,
|
||||||
|
route,
|
||||||
|
sdk,
|
||||||
|
sync,
|
||||||
|
toast,
|
||||||
|
workspaceID,
|
||||||
|
forceCreate,
|
||||||
|
})
|
||||||
|
|
||||||
|
async function selectWorkspace(workspaceID: string) {
|
||||||
|
if (workspaceID === "__local__") {
|
||||||
|
if (localCount() > 0) {
|
||||||
|
dialog.replace(() => <DialogSessionList localOnly={true} />)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
route.navigate({
|
||||||
|
type: "home",
|
||||||
|
})
|
||||||
|
dialog.clear()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const count = counts()[workspaceID]
|
||||||
|
if (count && count > 0) {
|
||||||
|
dialog.replace(() => <DialogSessionList workspaceID={workspaceID} />)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (count === 0) {
|
||||||
|
await open(workspaceID)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const client = createOpencodeClient({
|
||||||
|
baseUrl: sdk.url,
|
||||||
|
fetch: sdk.fetch,
|
||||||
|
directory: sync.data.path.directory || sdk.directory,
|
||||||
|
experimental_workspaceID: workspaceID,
|
||||||
|
})
|
||||||
|
const listed = await client.session.list({ roots: true, limit: 1 }).catch(() => undefined)
|
||||||
|
if (listed?.data?.length) {
|
||||||
|
dialog.replace(() => <DialogSessionList workspaceID={workspaceID} />)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
await open(workspaceID)
|
||||||
|
}
|
||||||
|
|
||||||
|
const currentWorkspaceID = createMemo(() => {
|
||||||
|
if (route.data.type === "session") {
|
||||||
|
return sync.session.get(route.data.sessionID)?.workspaceID ?? "__local__"
|
||||||
|
}
|
||||||
|
return "__local__"
|
||||||
|
})
|
||||||
|
|
||||||
|
const localCount = createMemo(
|
||||||
|
() => sync.data.session.filter((session) => !session.workspaceID && !session.parentID).length,
|
||||||
|
)
|
||||||
|
|
||||||
|
let run = 0
|
||||||
|
createEffect(() => {
|
||||||
|
const workspaces = sync.data.workspaceList
|
||||||
|
const next = ++run
|
||||||
|
if (!workspaces.length) {
|
||||||
|
setCounts({})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
setCounts(Object.fromEntries(workspaces.map((workspace) => [workspace.id, undefined])))
|
||||||
|
void Promise.all(
|
||||||
|
workspaces.map(async (workspace) => {
|
||||||
|
const client = createOpencodeClient({
|
||||||
|
baseUrl: sdk.url,
|
||||||
|
fetch: sdk.fetch,
|
||||||
|
directory: sync.data.path.directory || sdk.directory,
|
||||||
|
experimental_workspaceID: workspace.id,
|
||||||
|
})
|
||||||
|
const result = await client.session.list({ roots: true }).catch(() => undefined)
|
||||||
|
return [workspace.id, result ? (result.data?.length ?? 0) : null] as const
|
||||||
|
}),
|
||||||
|
).then((entries) => {
|
||||||
|
if (run !== next) return
|
||||||
|
setCounts(Object.fromEntries(entries))
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
const options = createMemo(() => [
|
||||||
|
{
|
||||||
|
title: "Local",
|
||||||
|
value: "__local__",
|
||||||
|
category: "Workspace",
|
||||||
|
description: "Use the local machine",
|
||||||
|
footer: `${localCount()} session${localCount() === 1 ? "" : "s"}`,
|
||||||
|
},
|
||||||
|
...sync.data.workspaceList.map((workspace) => {
|
||||||
|
const count = counts()[workspace.id]
|
||||||
|
return {
|
||||||
|
title:
|
||||||
|
toDelete() === workspace.id
|
||||||
|
? `Delete ${workspace.id}? Press ${keybind.print("session_delete")} again`
|
||||||
|
: workspace.id,
|
||||||
|
value: workspace.id,
|
||||||
|
category: workspace.type,
|
||||||
|
description: workspace.branch ? `Branch ${workspace.branch}` : undefined,
|
||||||
|
footer:
|
||||||
|
count === undefined
|
||||||
|
? "Loading sessions..."
|
||||||
|
: count === null
|
||||||
|
? "Sessions unavailable"
|
||||||
|
: `${count} session${count === 1 ? "" : "s"}`,
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
{
|
||||||
|
title: "+ New workspace",
|
||||||
|
value: "__create__",
|
||||||
|
category: "Actions",
|
||||||
|
description: "Create a new workspace",
|
||||||
|
},
|
||||||
|
])
|
||||||
|
|
||||||
|
onMount(() => {
|
||||||
|
dialog.setSize("large")
|
||||||
|
void sync.workspace.sync()
|
||||||
|
})
|
||||||
|
|
||||||
|
return (
|
||||||
|
<DialogSelect
|
||||||
|
title="Workspaces"
|
||||||
|
skipFilter={true}
|
||||||
|
options={options()}
|
||||||
|
current={currentWorkspaceID()}
|
||||||
|
onMove={() => {
|
||||||
|
setToDelete(undefined)
|
||||||
|
}}
|
||||||
|
onSelect={(option) => {
|
||||||
|
setToDelete(undefined)
|
||||||
|
if (option.value === "__create__") {
|
||||||
|
dialog.replace(() => <DialogWorkspaceCreate onSelect={(workspaceID) => open(workspaceID, true)} />)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
void selectWorkspace(option.value)
|
||||||
|
}}
|
||||||
|
keybind={[
|
||||||
|
{
|
||||||
|
keybind: keybind.all.session_delete?.[0],
|
||||||
|
title: "delete",
|
||||||
|
onTrigger: async (option) => {
|
||||||
|
if (option.value === "__create__" || option.value === "__local__") return
|
||||||
|
if (toDelete() !== option.value) {
|
||||||
|
setToDelete(option.value)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const result = await sdk.client.experimental.workspace.remove({ id: option.value }).catch(() => undefined)
|
||||||
|
setToDelete(undefined)
|
||||||
|
if (result?.error) {
|
||||||
|
toast.show({
|
||||||
|
message: "Failed to delete workspace",
|
||||||
|
variant: "error",
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (currentWorkspaceID() === option.value) {
|
||||||
|
route.navigate({
|
||||||
|
type: "home",
|
||||||
|
})
|
||||||
|
}
|
||||||
|
await sync.workspace.sync()
|
||||||
|
},
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -539,12 +539,25 @@ export function Prompt(props: PromptProps) {
|
|||||||
promptModelWarning()
|
promptModelWarning()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
const sessionID = props.sessionID
|
|
||||||
? props.sessionID
|
let sessionID = props.sessionID
|
||||||
: await (async () => {
|
if (sessionID == null) {
|
||||||
const sessionID = await sdk.client.session.create({}).then((x) => x.data!.id)
|
const res = await sdk.client.session.create({})
|
||||||
return sessionID
|
|
||||||
})()
|
if (res.error) {
|
||||||
|
console.log("Creating a session failed:", res.error)
|
||||||
|
|
||||||
|
toast.show({
|
||||||
|
message: "Creating a session failed. Open console for more details.",
|
||||||
|
variant: "error",
|
||||||
|
})
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
sessionID = res.data.id
|
||||||
|
}
|
||||||
|
|
||||||
const messageID = Identifier.ascending("message")
|
const messageID = Identifier.ascending("message")
|
||||||
let inputText = store.prompt.input
|
let inputText = store.prompt.input
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,151 @@
|
|||||||
|
import { useDialog } from "@tui/ui/dialog"
|
||||||
|
import { DialogSelect } from "@tui/ui/dialog-select"
|
||||||
|
import { useRoute } from "@tui/context/route"
|
||||||
|
import { useSync } from "@tui/context/sync"
|
||||||
|
import { createMemo, createSignal, createResource, onMount, Show } from "solid-js"
|
||||||
|
import { Locale } from "@/util/locale"
|
||||||
|
import { useKeybind } from "../../context/keybind"
|
||||||
|
import { useTheme } from "../../context/theme"
|
||||||
|
import { useSDK } from "../../context/sdk"
|
||||||
|
import { DialogSessionRename } from "../dialog-session-rename"
|
||||||
|
import { useKV } from "../../context/kv"
|
||||||
|
import { createDebouncedSignal } from "../../util/signal"
|
||||||
|
import { Spinner } from "../spinner"
|
||||||
|
import { useToast } from "../../ui/toast"
|
||||||
|
|
||||||
|
export function DialogSessionList(props: { workspaceID?: string; localOnly?: boolean } = {}) {
|
||||||
|
const dialog = useDialog()
|
||||||
|
const route = useRoute()
|
||||||
|
const sync = useSync()
|
||||||
|
const keybind = useKeybind()
|
||||||
|
const { theme } = useTheme()
|
||||||
|
const sdk = useSDK()
|
||||||
|
const kv = useKV()
|
||||||
|
const toast = useToast()
|
||||||
|
const [toDelete, setToDelete] = createSignal<string>()
|
||||||
|
const [search, setSearch] = createDebouncedSignal("", 150)
|
||||||
|
|
||||||
|
const [listed, listedActions] = createResource(
|
||||||
|
() => props.workspaceID,
|
||||||
|
async (workspaceID) => {
|
||||||
|
if (!workspaceID) return undefined
|
||||||
|
const result = await sdk.client.session.list({ roots: true })
|
||||||
|
return result.data ?? []
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
const [searchResults] = createResource(search, async (query) => {
|
||||||
|
if (!query || props.localOnly) return undefined
|
||||||
|
const result = await sdk.client.session.list({
|
||||||
|
search: query,
|
||||||
|
limit: 30,
|
||||||
|
...(props.workspaceID ? { roots: true } : {}),
|
||||||
|
})
|
||||||
|
return result.data ?? []
|
||||||
|
})
|
||||||
|
|
||||||
|
const currentSessionID = createMemo(() => (route.data.type === "session" ? route.data.sessionID : undefined))
|
||||||
|
|
||||||
|
const sessions = createMemo(() => {
|
||||||
|
if (searchResults()) return searchResults()!
|
||||||
|
if (props.workspaceID) return listed() ?? []
|
||||||
|
if (props.localOnly) return sync.data.session.filter((session) => !session.workspaceID)
|
||||||
|
return sync.data.session
|
||||||
|
})
|
||||||
|
|
||||||
|
const options = createMemo(() => {
|
||||||
|
const today = new Date().toDateString()
|
||||||
|
return sessions()
|
||||||
|
.filter((x) => {
|
||||||
|
if (x.parentID !== undefined) return false
|
||||||
|
if (props.workspaceID && listed()) return true
|
||||||
|
if (props.workspaceID) return x.workspaceID === props.workspaceID
|
||||||
|
if (props.localOnly) return !x.workspaceID
|
||||||
|
return true
|
||||||
|
})
|
||||||
|
.toSorted((a, b) => b.time.updated - a.time.updated)
|
||||||
|
.map((x) => {
|
||||||
|
const date = new Date(x.time.updated)
|
||||||
|
let category = date.toDateString()
|
||||||
|
if (category === today) {
|
||||||
|
category = "Today"
|
||||||
|
}
|
||||||
|
const isDeleting = toDelete() === x.id
|
||||||
|
const status = sync.data.session_status?.[x.id]
|
||||||
|
const isWorking = status?.type === "busy"
|
||||||
|
return {
|
||||||
|
title: isDeleting ? `Press ${keybind.print("session_delete")} again to confirm` : x.title,
|
||||||
|
bg: isDeleting ? theme.error : undefined,
|
||||||
|
value: x.id,
|
||||||
|
category,
|
||||||
|
footer: Locale.time(x.time.updated),
|
||||||
|
gutter: isWorking ? <Spinner /> : undefined,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
onMount(() => {
|
||||||
|
dialog.setSize("large")
|
||||||
|
})
|
||||||
|
|
||||||
|
return (
|
||||||
|
<DialogSelect
|
||||||
|
title={props.workspaceID ? `Workspace Sessions` : props.localOnly ? "Local Sessions" : "Sessions"}
|
||||||
|
options={options()}
|
||||||
|
skipFilter={!props.localOnly}
|
||||||
|
current={currentSessionID()}
|
||||||
|
onFilter={setSearch}
|
||||||
|
onMove={() => {
|
||||||
|
setToDelete(undefined)
|
||||||
|
}}
|
||||||
|
onSelect={(option) => {
|
||||||
|
route.navigate({
|
||||||
|
type: "session",
|
||||||
|
sessionID: option.value,
|
||||||
|
})
|
||||||
|
dialog.clear()
|
||||||
|
}}
|
||||||
|
keybind={[
|
||||||
|
{
|
||||||
|
keybind: keybind.all.session_delete?.[0],
|
||||||
|
title: "delete",
|
||||||
|
onTrigger: async (option) => {
|
||||||
|
if (toDelete() === option.value) {
|
||||||
|
const deleted = await sdk.client.session
|
||||||
|
.delete({
|
||||||
|
sessionID: option.value,
|
||||||
|
})
|
||||||
|
.then(() => true)
|
||||||
|
.catch(() => false)
|
||||||
|
setToDelete(undefined)
|
||||||
|
if (!deleted) {
|
||||||
|
toast.show({
|
||||||
|
message: "Failed to delete session",
|
||||||
|
variant: "error",
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (props.workspaceID) {
|
||||||
|
listedActions.mutate((sessions) => sessions?.filter((session) => session.id !== option.value))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
sync.set(
|
||||||
|
"session",
|
||||||
|
sync.data.session.filter((session) => session.id !== option.value),
|
||||||
|
)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
setToDelete(option.value)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
keybind: keybind.all.session_rename?.[0],
|
||||||
|
title: "rename",
|
||||||
|
onTrigger: async (option) => {
|
||||||
|
dialog.replace(() => <DialogSessionRename session={option.value} />)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -5,6 +5,7 @@ import { batch, onCleanup, onMount } from "solid-js"
|
|||||||
|
|
||||||
export type EventSource = {
|
export type EventSource = {
|
||||||
on: (handler: (event: Event) => void) => () => void
|
on: (handler: (event: Event) => void) => () => void
|
||||||
|
setWorkspace?: (workspaceID?: string) => void
|
||||||
}
|
}
|
||||||
|
|
||||||
export const { use: useSDK, provider: SDKProvider } = createSimpleContext({
|
export const { use: useSDK, provider: SDKProvider } = createSimpleContext({
|
||||||
@@ -17,13 +18,21 @@ export const { use: useSDK, provider: SDKProvider } = createSimpleContext({
|
|||||||
events?: EventSource
|
events?: EventSource
|
||||||
}) => {
|
}) => {
|
||||||
const abort = new AbortController()
|
const abort = new AbortController()
|
||||||
const sdk = createOpencodeClient({
|
let workspaceID: string | undefined
|
||||||
baseUrl: props.url,
|
let sse: AbortController | undefined
|
||||||
signal: abort.signal,
|
|
||||||
directory: props.directory,
|
function createSDK() {
|
||||||
fetch: props.fetch,
|
return createOpencodeClient({
|
||||||
headers: props.headers,
|
baseUrl: props.url,
|
||||||
})
|
signal: abort.signal,
|
||||||
|
directory: props.directory,
|
||||||
|
fetch: props.fetch,
|
||||||
|
headers: props.headers,
|
||||||
|
experimental_workspaceID: workspaceID,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
let sdk = createSDK()
|
||||||
|
|
||||||
const emitter = createGlobalEmitter<{
|
const emitter = createGlobalEmitter<{
|
||||||
[key in Event["type"]]: Extract<Event, { type: key }>
|
[key in Event["type"]]: Extract<Event, { type: key }>
|
||||||
@@ -61,41 +70,56 @@ export const { use: useSDK, provider: SDKProvider } = createSimpleContext({
|
|||||||
flush()
|
flush()
|
||||||
}
|
}
|
||||||
|
|
||||||
onMount(async () => {
|
function startSSE() {
|
||||||
// If an event source is provided, use it instead of SSE
|
sse?.abort()
|
||||||
|
const ctrl = new AbortController()
|
||||||
|
sse = ctrl
|
||||||
|
;(async () => {
|
||||||
|
while (true) {
|
||||||
|
if (abort.signal.aborted || ctrl.signal.aborted) break
|
||||||
|
const events = await sdk.event.subscribe({}, { signal: ctrl.signal })
|
||||||
|
|
||||||
|
for await (const event of events.stream) {
|
||||||
|
if (ctrl.signal.aborted) break
|
||||||
|
handleEvent(event)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (timer) clearTimeout(timer)
|
||||||
|
if (queue.length > 0) flush()
|
||||||
|
}
|
||||||
|
})().catch(() => {})
|
||||||
|
}
|
||||||
|
|
||||||
|
onMount(() => {
|
||||||
if (props.events) {
|
if (props.events) {
|
||||||
const unsub = props.events.on(handleEvent)
|
const unsub = props.events.on(handleEvent)
|
||||||
onCleanup(unsub)
|
onCleanup(unsub)
|
||||||
return
|
} else {
|
||||||
}
|
startSSE()
|
||||||
|
|
||||||
// Fall back to SSE
|
|
||||||
while (true) {
|
|
||||||
if (abort.signal.aborted) break
|
|
||||||
const events = await sdk.event.subscribe(
|
|
||||||
{},
|
|
||||||
{
|
|
||||||
signal: abort.signal,
|
|
||||||
},
|
|
||||||
)
|
|
||||||
|
|
||||||
for await (const event of events.stream) {
|
|
||||||
handleEvent(event)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Flush any remaining events
|
|
||||||
if (timer) clearTimeout(timer)
|
|
||||||
if (queue.length > 0) {
|
|
||||||
flush()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
onCleanup(() => {
|
onCleanup(() => {
|
||||||
abort.abort()
|
abort.abort()
|
||||||
|
sse?.abort()
|
||||||
if (timer) clearTimeout(timer)
|
if (timer) clearTimeout(timer)
|
||||||
})
|
})
|
||||||
|
|
||||||
return { client: sdk, event: emitter, url: props.url }
|
return {
|
||||||
|
get client() {
|
||||||
|
return sdk
|
||||||
|
},
|
||||||
|
directory: props.directory,
|
||||||
|
event: emitter,
|
||||||
|
fetch: props.fetch ?? fetch,
|
||||||
|
setWorkspace(next?: string) {
|
||||||
|
if (workspaceID === next) return
|
||||||
|
workspaceID = next
|
||||||
|
sdk = createSDK()
|
||||||
|
props.events?.setWorkspace?.(next)
|
||||||
|
if (!props.events) startSSE()
|
||||||
|
},
|
||||||
|
url: props.url,
|
||||||
|
}
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ import { useArgs } from "./args"
|
|||||||
import { batch, onMount } from "solid-js"
|
import { batch, onMount } from "solid-js"
|
||||||
import { Log } from "@/util/log"
|
import { Log } from "@/util/log"
|
||||||
import type { Path } from "@opencode-ai/sdk"
|
import type { Path } from "@opencode-ai/sdk"
|
||||||
|
import type { Workspace } from "@opencode-ai/sdk/v2"
|
||||||
|
|
||||||
export const { use: useSync, provider: SyncProvider } = createSimpleContext({
|
export const { use: useSync, provider: SyncProvider } = createSimpleContext({
|
||||||
name: "Sync",
|
name: "Sync",
|
||||||
@@ -73,6 +74,7 @@ export const { use: useSync, provider: SyncProvider } = createSimpleContext({
|
|||||||
formatter: FormatterStatus[]
|
formatter: FormatterStatus[]
|
||||||
vcs: VcsInfo | undefined
|
vcs: VcsInfo | undefined
|
||||||
path: Path
|
path: Path
|
||||||
|
workspaceList: Workspace[]
|
||||||
}>({
|
}>({
|
||||||
provider_next: {
|
provider_next: {
|
||||||
all: [],
|
all: [],
|
||||||
@@ -100,10 +102,17 @@ export const { use: useSync, provider: SyncProvider } = createSimpleContext({
|
|||||||
formatter: [],
|
formatter: [],
|
||||||
vcs: undefined,
|
vcs: undefined,
|
||||||
path: { state: "", config: "", worktree: "", directory: "" },
|
path: { state: "", config: "", worktree: "", directory: "" },
|
||||||
|
workspaceList: [],
|
||||||
})
|
})
|
||||||
|
|
||||||
const sdk = useSDK()
|
const sdk = useSDK()
|
||||||
|
|
||||||
|
async function syncWorkspaces() {
|
||||||
|
const result = await sdk.client.experimental.workspace.list().catch(() => undefined)
|
||||||
|
if (!result?.data) return
|
||||||
|
setStore("workspaceList", reconcile(result.data))
|
||||||
|
}
|
||||||
|
|
||||||
sdk.event.listen((e) => {
|
sdk.event.listen((e) => {
|
||||||
const event = e.details
|
const event = e.details
|
||||||
switch (event.type) {
|
switch (event.type) {
|
||||||
@@ -413,6 +422,7 @@ export const { use: useSync, provider: SyncProvider } = createSimpleContext({
|
|||||||
sdk.client.provider.auth().then((x) => setStore("provider_auth", reconcile(x.data ?? {}))),
|
sdk.client.provider.auth().then((x) => setStore("provider_auth", reconcile(x.data ?? {}))),
|
||||||
sdk.client.vcs.get().then((x) => setStore("vcs", reconcile(x.data))),
|
sdk.client.vcs.get().then((x) => setStore("vcs", reconcile(x.data))),
|
||||||
sdk.client.path.get().then((x) => setStore("path", reconcile(x.data!))),
|
sdk.client.path.get().then((x) => setStore("path", reconcile(x.data!))),
|
||||||
|
syncWorkspaces(),
|
||||||
]).then(() => {
|
]).then(() => {
|
||||||
setStore("status", "complete")
|
setStore("status", "complete")
|
||||||
})
|
})
|
||||||
@@ -481,6 +491,12 @@ export const { use: useSync, provider: SyncProvider } = createSimpleContext({
|
|||||||
fullSyncedSessions.add(sessionID)
|
fullSyncedSessions.add(sessionID)
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
workspace: {
|
||||||
|
get(workspaceID: string) {
|
||||||
|
return store.workspaceList.find((workspace) => workspace.id === workspaceID)
|
||||||
|
},
|
||||||
|
sync: syncWorkspaces,
|
||||||
|
},
|
||||||
bootstrap,
|
bootstrap,
|
||||||
}
|
}
|
||||||
return result
|
return result
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { Prompt, type PromptRef } from "@tui/component/prompt"
|
import { Prompt, type PromptRef } from "@tui/component/prompt"
|
||||||
import { createMemo, Match, onMount, Show, Switch } from "solid-js"
|
import { createEffect, createMemo, Match, on, onMount, Show, Switch } from "solid-js"
|
||||||
import { useTheme } from "@tui/context/theme"
|
import { useTheme } from "@tui/context/theme"
|
||||||
import { useKeybind } from "@tui/context/keybind"
|
import { useKeybind } from "@tui/context/keybind"
|
||||||
import { Logo } from "../component/logo"
|
import { Logo } from "../component/logo"
|
||||||
@@ -14,6 +14,7 @@ import { usePromptRef } from "../context/prompt"
|
|||||||
import { Installation } from "@/installation"
|
import { Installation } from "@/installation"
|
||||||
import { useKV } from "../context/kv"
|
import { useKV } from "../context/kv"
|
||||||
import { useCommandDialog } from "../component/dialog-command"
|
import { useCommandDialog } from "../component/dialog-command"
|
||||||
|
import { useLocal } from "../context/local"
|
||||||
|
|
||||||
// TODO: what is the best way to do this?
|
// TODO: what is the best way to do this?
|
||||||
let once = false
|
let once = false
|
||||||
@@ -76,6 +77,7 @@ export function Home() {
|
|||||||
|
|
||||||
let prompt: PromptRef
|
let prompt: PromptRef
|
||||||
const args = useArgs()
|
const args = useArgs()
|
||||||
|
const local = useLocal()
|
||||||
onMount(() => {
|
onMount(() => {
|
||||||
if (once) return
|
if (once) return
|
||||||
if (route.initialPrompt) {
|
if (route.initialPrompt) {
|
||||||
@@ -84,9 +86,21 @@ export function Home() {
|
|||||||
} else if (args.prompt) {
|
} else if (args.prompt) {
|
||||||
prompt.set({ input: args.prompt, parts: [] })
|
prompt.set({ input: args.prompt, parts: [] })
|
||||||
once = true
|
once = true
|
||||||
prompt.submit()
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// Wait for sync and model store to be ready before auto-submitting --prompt
|
||||||
|
createEffect(
|
||||||
|
on(
|
||||||
|
() => sync.ready && local.model.ready,
|
||||||
|
(ready) => {
|
||||||
|
if (!ready) return
|
||||||
|
if (!args.prompt) return
|
||||||
|
if (prompt.current?.input !== args.prompt) return
|
||||||
|
prompt.submit()
|
||||||
|
},
|
||||||
|
),
|
||||||
|
)
|
||||||
const directory = useDirectory()
|
const directory = useDirectory()
|
||||||
|
|
||||||
const keybind = useKeybind()
|
const keybind = useKeybind()
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import { SplitBorder } from "@tui/component/border"
|
|||||||
import type { AssistantMessage, Session } from "@opencode-ai/sdk/v2"
|
import type { AssistantMessage, Session } from "@opencode-ai/sdk/v2"
|
||||||
import { useCommandDialog } from "@tui/component/dialog-command"
|
import { useCommandDialog } from "@tui/component/dialog-command"
|
||||||
import { useKeybind } from "../../context/keybind"
|
import { useKeybind } from "../../context/keybind"
|
||||||
|
import { Flag } from "@/flag/flag"
|
||||||
import { useTerminalDimensions } from "@opentui/solid"
|
import { useTerminalDimensions } from "@opentui/solid"
|
||||||
|
|
||||||
const Title = (props: { session: Accessor<Session> }) => {
|
const Title = (props: { session: Accessor<Session> }) => {
|
||||||
@@ -29,6 +30,17 @@ const ContextInfo = (props: { context: Accessor<string | undefined>; cost: Acces
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const WorkspaceInfo = (props: { workspace: Accessor<string | undefined> }) => {
|
||||||
|
const { theme } = useTheme()
|
||||||
|
return (
|
||||||
|
<Show when={props.workspace()}>
|
||||||
|
<text fg={theme.textMuted} wrapMode="none" flexShrink={0}>
|
||||||
|
{props.workspace()}
|
||||||
|
</text>
|
||||||
|
</Show>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
export function Header() {
|
export function Header() {
|
||||||
const route = useRouteData("session")
|
const route = useRouteData("session")
|
||||||
const sync = useSync()
|
const sync = useSync()
|
||||||
@@ -59,6 +71,14 @@ export function Header() {
|
|||||||
return result
|
return result
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const workspace = createMemo(() => {
|
||||||
|
const id = session()?.workspaceID
|
||||||
|
if (!id) return "Workspace local"
|
||||||
|
const info = sync.workspace.get(id)
|
||||||
|
if (!info) return `Workspace ${id}`
|
||||||
|
return `Workspace ${id} (${info.type})`
|
||||||
|
})
|
||||||
|
|
||||||
const { theme } = useTheme()
|
const { theme } = useTheme()
|
||||||
const keybind = useKeybind()
|
const keybind = useKeybind()
|
||||||
const command = useCommandDialog()
|
const command = useCommandDialog()
|
||||||
@@ -83,9 +103,19 @@ export function Header() {
|
|||||||
<Match when={session()?.parentID}>
|
<Match when={session()?.parentID}>
|
||||||
<box flexDirection="column" gap={1}>
|
<box flexDirection="column" gap={1}>
|
||||||
<box flexDirection={narrow() ? "column" : "row"} justifyContent="space-between" gap={narrow() ? 1 : 0}>
|
<box flexDirection={narrow() ? "column" : "row"} justifyContent="space-between" gap={narrow() ? 1 : 0}>
|
||||||
<text fg={theme.text}>
|
{Flag.OPENCODE_EXPERIMENTAL_WORKSPACES_TUI ? (
|
||||||
<b>Subagent session</b>
|
<box flexDirection="column">
|
||||||
</text>
|
<text fg={theme.text}>
|
||||||
|
<b>Subagent session</b>
|
||||||
|
</text>
|
||||||
|
<WorkspaceInfo workspace={workspace} />
|
||||||
|
</box>
|
||||||
|
) : (
|
||||||
|
<text fg={theme.text}>
|
||||||
|
<b>Subagent session</b>
|
||||||
|
</text>
|
||||||
|
)}
|
||||||
|
|
||||||
<ContextInfo context={context} cost={cost} />
|
<ContextInfo context={context} cost={cost} />
|
||||||
</box>
|
</box>
|
||||||
<box flexDirection="row" gap={2}>
|
<box flexDirection="row" gap={2}>
|
||||||
@@ -124,7 +154,14 @@ export function Header() {
|
|||||||
</Match>
|
</Match>
|
||||||
<Match when={true}>
|
<Match when={true}>
|
||||||
<box flexDirection={narrow() ? "column" : "row"} justifyContent="space-between" gap={1}>
|
<box flexDirection={narrow() ? "column" : "row"} justifyContent="space-between" gap={1}>
|
||||||
<Title session={session} />
|
{Flag.OPENCODE_EXPERIMENTAL_WORKSPACES_TUI ? (
|
||||||
|
<box flexDirection="column">
|
||||||
|
<Title session={session} />
|
||||||
|
<WorkspaceInfo workspace={workspace} />
|
||||||
|
</box>
|
||||||
|
) : (
|
||||||
|
<Title session={session} />
|
||||||
|
)}
|
||||||
<ContextInfo context={context} cost={cost} />
|
<ContextInfo context={context} cost={cost} />
|
||||||
</box>
|
</box>
|
||||||
</Match>
|
</Match>
|
||||||
|
|||||||
@@ -182,6 +182,12 @@ export function Session() {
|
|||||||
return new CustomSpeedScroll(3)
|
return new CustomSpeedScroll(3)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
createEffect(() => {
|
||||||
|
if (session()?.workspaceID) {
|
||||||
|
sdk.setWorkspace(session()?.workspaceID)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
createEffect(async () => {
|
createEffect(async () => {
|
||||||
await sync.session
|
await sync.session
|
||||||
.sync(route.sessionID)
|
.sync(route.sessionID)
|
||||||
|
|||||||
@@ -42,6 +42,9 @@ function createWorkerFetch(client: RpcClient): typeof fetch {
|
|||||||
function createEventSource(client: RpcClient): EventSource {
|
function createEventSource(client: RpcClient): EventSource {
|
||||||
return {
|
return {
|
||||||
on: (handler) => client.on<Event>("event", handler),
|
on: (handler) => client.on<Event>("event", handler),
|
||||||
|
setWorkspace: (workspaceID) => {
|
||||||
|
void client.call("setWorkspace", { workspaceID })
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
import { $ } from "bun"
|
|
||||||
import { platform, release } from "os"
|
import { platform, release } from "os"
|
||||||
import clipboardy from "clipboardy"
|
import clipboardy from "clipboardy"
|
||||||
import { lazy } from "../../../../util/lazy.js"
|
import { lazy } from "../../../../util/lazy.js"
|
||||||
import { tmpdir } from "os"
|
import { tmpdir } from "os"
|
||||||
import path from "path"
|
import path from "path"
|
||||||
|
import fs from "fs/promises"
|
||||||
import { Filesystem } from "../../../../util/filesystem"
|
import { Filesystem } from "../../../../util/filesystem"
|
||||||
import { Process } from "../../../../util/process"
|
import { Process } from "../../../../util/process"
|
||||||
import { which } from "../../../../util/which"
|
import { which } from "../../../../util/which"
|
||||||
@@ -34,23 +34,38 @@ export namespace Clipboard {
|
|||||||
if (os === "darwin") {
|
if (os === "darwin") {
|
||||||
const tmpfile = path.join(tmpdir(), "opencode-clipboard.png")
|
const tmpfile = path.join(tmpdir(), "opencode-clipboard.png")
|
||||||
try {
|
try {
|
||||||
await $`osascript -e 'set imageData to the clipboard as "PNGf"' -e 'set fileRef to open for access POSIX file "${tmpfile}" with write permission' -e 'set eof fileRef to 0' -e 'write imageData to fileRef' -e 'close access fileRef'`
|
await Process.run(
|
||||||
.nothrow()
|
[
|
||||||
.quiet()
|
"osascript",
|
||||||
|
"-e",
|
||||||
|
'set imageData to the clipboard as "PNGf"',
|
||||||
|
"-e",
|
||||||
|
`set fileRef to open for access POSIX file "${tmpfile}" with write permission`,
|
||||||
|
"-e",
|
||||||
|
"set eof fileRef to 0",
|
||||||
|
"-e",
|
||||||
|
"write imageData to fileRef",
|
||||||
|
"-e",
|
||||||
|
"close access fileRef",
|
||||||
|
],
|
||||||
|
{ nothrow: true },
|
||||||
|
)
|
||||||
const buffer = await Filesystem.readBytes(tmpfile)
|
const buffer = await Filesystem.readBytes(tmpfile)
|
||||||
return { data: buffer.toString("base64"), mime: "image/png" }
|
return { data: buffer.toString("base64"), mime: "image/png" }
|
||||||
} catch {
|
} catch {
|
||||||
} finally {
|
} finally {
|
||||||
await $`rm -f "${tmpfile}"`.nothrow().quiet()
|
await fs.rm(tmpfile, { force: true }).catch(() => {})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (os === "win32" || release().includes("WSL")) {
|
if (os === "win32" || release().includes("WSL")) {
|
||||||
const script =
|
const script =
|
||||||
"Add-Type -AssemblyName System.Windows.Forms; $img = [System.Windows.Forms.Clipboard]::GetImage(); if ($img) { $ms = New-Object System.IO.MemoryStream; $img.Save($ms, [System.Drawing.Imaging.ImageFormat]::Png); [System.Convert]::ToBase64String($ms.ToArray()) }"
|
"Add-Type -AssemblyName System.Windows.Forms; $img = [System.Windows.Forms.Clipboard]::GetImage(); if ($img) { $ms = New-Object System.IO.MemoryStream; $img.Save($ms, [System.Drawing.Imaging.ImageFormat]::Png); [System.Convert]::ToBase64String($ms.ToArray()) }"
|
||||||
const base64 = await $`powershell.exe -NonInteractive -NoProfile -command "${script}"`.nothrow().text()
|
const base64 = await Process.text(["powershell.exe", "-NonInteractive", "-NoProfile", "-command", script], {
|
||||||
if (base64) {
|
nothrow: true,
|
||||||
const imageBuffer = Buffer.from(base64.trim(), "base64")
|
})
|
||||||
|
if (base64.text) {
|
||||||
|
const imageBuffer = Buffer.from(base64.text.trim(), "base64")
|
||||||
if (imageBuffer.length > 0) {
|
if (imageBuffer.length > 0) {
|
||||||
return { data: imageBuffer.toString("base64"), mime: "image/png" }
|
return { data: imageBuffer.toString("base64"), mime: "image/png" }
|
||||||
}
|
}
|
||||||
@@ -58,13 +73,15 @@ export namespace Clipboard {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (os === "linux") {
|
if (os === "linux") {
|
||||||
const wayland = await $`wl-paste -t image/png`.nothrow().arrayBuffer()
|
const wayland = await Process.run(["wl-paste", "-t", "image/png"], { nothrow: true })
|
||||||
if (wayland && wayland.byteLength > 0) {
|
if (wayland.stdout.byteLength > 0) {
|
||||||
return { data: Buffer.from(wayland).toString("base64"), mime: "image/png" }
|
return { data: Buffer.from(wayland.stdout).toString("base64"), mime: "image/png" }
|
||||||
}
|
}
|
||||||
const x11 = await $`xclip -selection clipboard -t image/png -o`.nothrow().arrayBuffer()
|
const x11 = await Process.run(["xclip", "-selection", "clipboard", "-t", "image/png", "-o"], {
|
||||||
if (x11 && x11.byteLength > 0) {
|
nothrow: true,
|
||||||
return { data: Buffer.from(x11).toString("base64"), mime: "image/png" }
|
})
|
||||||
|
if (x11.stdout.byteLength > 0) {
|
||||||
|
return { data: Buffer.from(x11.stdout).toString("base64"), mime: "image/png" }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -81,7 +98,7 @@ export namespace Clipboard {
|
|||||||
console.log("clipboard: using osascript")
|
console.log("clipboard: using osascript")
|
||||||
return async (text: string) => {
|
return async (text: string) => {
|
||||||
const escaped = text.replace(/\\/g, "\\\\").replace(/"/g, '\\"')
|
const escaped = text.replace(/\\/g, "\\\\").replace(/"/g, '\\"')
|
||||||
await $`osascript -e 'set the clipboard to "${escaped}"'`.nothrow().quiet()
|
await Process.run(["osascript", "-e", `set the clipboard to "${escaped}"`], { nothrow: true })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ const eventStream = {
|
|||||||
abort: undefined as AbortController | undefined,
|
abort: undefined as AbortController | undefined,
|
||||||
}
|
}
|
||||||
|
|
||||||
const startEventStream = (directory: string) => {
|
const startEventStream = (input: { directory: string; workspaceID?: string }) => {
|
||||||
if (eventStream.abort) eventStream.abort.abort()
|
if (eventStream.abort) eventStream.abort.abort()
|
||||||
const abort = new AbortController()
|
const abort = new AbortController()
|
||||||
eventStream.abort = abort
|
eventStream.abort = abort
|
||||||
@@ -59,7 +59,8 @@ const startEventStream = (directory: string) => {
|
|||||||
|
|
||||||
const sdk = createOpencodeClient({
|
const sdk = createOpencodeClient({
|
||||||
baseUrl: "http://opencode.internal",
|
baseUrl: "http://opencode.internal",
|
||||||
directory,
|
directory: input.directory,
|
||||||
|
experimental_workspaceID: input.workspaceID,
|
||||||
fetch: fetchFn,
|
fetch: fetchFn,
|
||||||
signal,
|
signal,
|
||||||
})
|
})
|
||||||
@@ -95,7 +96,7 @@ const startEventStream = (directory: string) => {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
startEventStream(process.cwd())
|
startEventStream({ directory: process.cwd() })
|
||||||
|
|
||||||
export const rpc = {
|
export const rpc = {
|
||||||
async fetch(input: { url: string; method: string; headers: Record<string, string>; body?: string }) {
|
async fetch(input: { url: string; method: string; headers: Record<string, string>; body?: string }) {
|
||||||
@@ -135,6 +136,9 @@ export const rpc = {
|
|||||||
Config.global.reset()
|
Config.global.reset()
|
||||||
await Instance.disposeAll()
|
await Instance.disposeAll()
|
||||||
},
|
},
|
||||||
|
async setWorkspace(input: { workspaceID?: string }) {
|
||||||
|
startEventStream({ directory: process.cwd(), workspaceID: input.workspaceID })
|
||||||
|
},
|
||||||
async shutdown() {
|
async shutdown() {
|
||||||
Log.Default.info("worker shutting down")
|
Log.Default.info("worker shutting down")
|
||||||
if (eventStream.abort) eventStream.abort.abort()
|
if (eventStream.abort) eventStream.abort.abort()
|
||||||
|
|||||||
@@ -3,11 +3,11 @@ import { UI } from "../ui"
|
|||||||
import * as prompts from "@clack/prompts"
|
import * as prompts from "@clack/prompts"
|
||||||
import { Installation } from "../../installation"
|
import { Installation } from "../../installation"
|
||||||
import { Global } from "../../global"
|
import { Global } from "../../global"
|
||||||
import { $ } from "bun"
|
|
||||||
import fs from "fs/promises"
|
import fs from "fs/promises"
|
||||||
import path from "path"
|
import path from "path"
|
||||||
import os from "os"
|
import os from "os"
|
||||||
import { Filesystem } from "../../util/filesystem"
|
import { Filesystem } from "../../util/filesystem"
|
||||||
|
import { Process } from "../../util/process"
|
||||||
|
|
||||||
interface UninstallArgs {
|
interface UninstallArgs {
|
||||||
keepConfig: boolean
|
keepConfig: boolean
|
||||||
@@ -192,16 +192,13 @@ async function executeUninstall(method: Installation.Method, targets: RemovalTar
|
|||||||
const cmd = cmds[method]
|
const cmd = cmds[method]
|
||||||
if (cmd) {
|
if (cmd) {
|
||||||
spinner.start(`Running ${cmd.join(" ")}...`)
|
spinner.start(`Running ${cmd.join(" ")}...`)
|
||||||
const result =
|
const result = await Process.run(method === "choco" ? ["choco", "uninstall", "opencode", "-y", "-r"] : cmd, {
|
||||||
method === "choco"
|
nothrow: true,
|
||||||
? await $`echo Y | choco uninstall opencode -y -r`.quiet().nothrow()
|
})
|
||||||
: await $`${cmd}`.quiet().nothrow()
|
if (result.code !== 0) {
|
||||||
if (result.exitCode !== 0) {
|
spinner.stop(`Package manager uninstall failed: exit code ${result.code}`, 1)
|
||||||
spinner.stop(`Package manager uninstall failed: exit code ${result.exitCode}`, 1)
|
const text = `${result.stdout.toString("utf8")}\n${result.stderr.toString("utf8")}`
|
||||||
if (
|
if (method === "choco" && text.includes("not running from an elevated command shell")) {
|
||||||
method === "choco" &&
|
|
||||||
result.stdout.toString("utf8").includes("not running from an elevated command shell")
|
|
||||||
) {
|
|
||||||
prompts.log.warn(`You may need to run '${cmd.join(" ")}' from an elevated command shell`)
|
prompts.log.warn(`You may need to run '${cmd.join(" ")}' from an elevated command shell`)
|
||||||
} else {
|
} else {
|
||||||
prompts.log.warn(`You may need to run manually: ${cmd.join(" ")}`)
|
prompts.log.warn(`You may need to run manually: ${cmd.join(" ")}`)
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import { BusEvent } from "@/bus/bus-event"
|
import { BusEvent } from "@/bus/bus-event"
|
||||||
import z from "zod"
|
import z from "zod"
|
||||||
import { $ } from "bun"
|
|
||||||
import { formatPatch, structuredPatch } from "diff"
|
import { formatPatch, structuredPatch } from "diff"
|
||||||
import path from "path"
|
import path from "path"
|
||||||
import fs from "fs"
|
import fs from "fs"
|
||||||
@@ -11,6 +10,7 @@ import { Instance } from "../project/instance"
|
|||||||
import { Ripgrep } from "./ripgrep"
|
import { Ripgrep } from "./ripgrep"
|
||||||
import fuzzysort from "fuzzysort"
|
import fuzzysort from "fuzzysort"
|
||||||
import { Global } from "../global"
|
import { Global } from "../global"
|
||||||
|
import { git } from "@/util/git"
|
||||||
|
|
||||||
export namespace File {
|
export namespace File {
|
||||||
const log = Log.create({ service: "file" })
|
const log = Log.create({ service: "file" })
|
||||||
@@ -418,11 +418,11 @@ export namespace File {
|
|||||||
const project = Instance.project
|
const project = Instance.project
|
||||||
if (project.vcs !== "git") return []
|
if (project.vcs !== "git") return []
|
||||||
|
|
||||||
const diffOutput = await $`git -c core.fsmonitor=false -c core.quotepath=false diff --numstat HEAD`
|
const diffOutput = (
|
||||||
.cwd(Instance.directory)
|
await git(["-c", "core.fsmonitor=false", "-c", "core.quotepath=false", "diff", "--numstat", "HEAD"], {
|
||||||
.quiet()
|
cwd: Instance.directory,
|
||||||
.nothrow()
|
})
|
||||||
.text()
|
).text()
|
||||||
|
|
||||||
const changedFiles: Info[] = []
|
const changedFiles: Info[] = []
|
||||||
|
|
||||||
@@ -439,12 +439,14 @@ export namespace File {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const untrackedOutput =
|
const untrackedOutput = (
|
||||||
await $`git -c core.fsmonitor=false -c core.quotepath=false ls-files --others --exclude-standard`
|
await git(
|
||||||
.cwd(Instance.directory)
|
["-c", "core.fsmonitor=false", "-c", "core.quotepath=false", "ls-files", "--others", "--exclude-standard"],
|
||||||
.quiet()
|
{
|
||||||
.nothrow()
|
cwd: Instance.directory,
|
||||||
.text()
|
},
|
||||||
|
)
|
||||||
|
).text()
|
||||||
|
|
||||||
if (untrackedOutput.trim()) {
|
if (untrackedOutput.trim()) {
|
||||||
const untrackedFiles = untrackedOutput.trim().split("\n")
|
const untrackedFiles = untrackedOutput.trim().split("\n")
|
||||||
@@ -465,12 +467,14 @@ export namespace File {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Get deleted files
|
// Get deleted files
|
||||||
const deletedOutput =
|
const deletedOutput = (
|
||||||
await $`git -c core.fsmonitor=false -c core.quotepath=false diff --name-only --diff-filter=D HEAD`
|
await git(
|
||||||
.cwd(Instance.directory)
|
["-c", "core.fsmonitor=false", "-c", "core.quotepath=false", "diff", "--name-only", "--diff-filter=D", "HEAD"],
|
||||||
.quiet()
|
{
|
||||||
.nothrow()
|
cwd: Instance.directory,
|
||||||
.text()
|
},
|
||||||
|
)
|
||||||
|
).text()
|
||||||
|
|
||||||
if (deletedOutput.trim()) {
|
if (deletedOutput.trim()) {
|
||||||
const deletedFiles = deletedOutput.trim().split("\n")
|
const deletedFiles = deletedOutput.trim().split("\n")
|
||||||
@@ -541,16 +545,14 @@ export namespace File {
|
|||||||
const content = (await Filesystem.readText(full).catch(() => "")).trim()
|
const content = (await Filesystem.readText(full).catch(() => "")).trim()
|
||||||
|
|
||||||
if (project.vcs === "git") {
|
if (project.vcs === "git") {
|
||||||
let diff = await $`git -c core.fsmonitor=false diff ${file}`.cwd(Instance.directory).quiet().nothrow().text()
|
let diff = (await git(["-c", "core.fsmonitor=false", "diff", "--", file], { cwd: Instance.directory })).text()
|
||||||
if (!diff.trim()) {
|
if (!diff.trim()) {
|
||||||
diff = await $`git -c core.fsmonitor=false diff --staged ${file}`
|
diff = (
|
||||||
.cwd(Instance.directory)
|
await git(["-c", "core.fsmonitor=false", "diff", "--staged", "--", file], { cwd: Instance.directory })
|
||||||
.quiet()
|
).text()
|
||||||
.nothrow()
|
|
||||||
.text()
|
|
||||||
}
|
}
|
||||||
if (diff.trim()) {
|
if (diff.trim()) {
|
||||||
const original = await $`git show HEAD:${file}`.cwd(Instance.directory).quiet().nothrow().text()
|
const original = (await git(["show", `HEAD:${file}`], { cwd: Instance.directory })).text()
|
||||||
const patch = structuredPatch(file, file, original, content, "old", "new", {
|
const patch = structuredPatch(file, file, original, content, "old", "new", {
|
||||||
context: Infinity,
|
context: Infinity,
|
||||||
ignoreWhitespace: true,
|
ignoreWhitespace: true,
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import fs from "fs/promises"
|
|||||||
import z from "zod"
|
import z from "zod"
|
||||||
import { NamedError } from "@opencode-ai/util/error"
|
import { NamedError } from "@opencode-ai/util/error"
|
||||||
import { lazy } from "../util/lazy"
|
import { lazy } from "../util/lazy"
|
||||||
import { $ } from "bun"
|
|
||||||
import { Filesystem } from "../util/filesystem"
|
import { Filesystem } from "../util/filesystem"
|
||||||
import { Process } from "../util/process"
|
import { Process } from "../util/process"
|
||||||
import { which } from "../util/which"
|
import { which } from "../util/which"
|
||||||
@@ -338,7 +338,7 @@ export namespace Ripgrep {
|
|||||||
limit?: number
|
limit?: number
|
||||||
follow?: boolean
|
follow?: boolean
|
||||||
}) {
|
}) {
|
||||||
const args = [`${await filepath()}`, "--json", "--hidden", "--glob='!.git/*'"]
|
const args = [`${await filepath()}`, "--json", "--hidden", "--glob=!.git/*"]
|
||||||
if (input.follow) args.push("--follow")
|
if (input.follow) args.push("--follow")
|
||||||
|
|
||||||
if (input.glob) {
|
if (input.glob) {
|
||||||
@@ -354,14 +354,16 @@ export namespace Ripgrep {
|
|||||||
args.push("--")
|
args.push("--")
|
||||||
args.push(input.pattern)
|
args.push(input.pattern)
|
||||||
|
|
||||||
const command = args.join(" ")
|
const result = await Process.text(args, {
|
||||||
const result = await $`${{ raw: command }}`.cwd(input.cwd).quiet().nothrow()
|
cwd: input.cwd,
|
||||||
if (result.exitCode !== 0) {
|
nothrow: true,
|
||||||
|
})
|
||||||
|
if (result.code !== 0) {
|
||||||
return []
|
return []
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle both Unix (\n) and Windows (\r\n) line endings
|
// Handle both Unix (\n) and Windows (\r\n) line endings
|
||||||
const lines = result.text().trim().split(/\r?\n/).filter(Boolean)
|
const lines = result.text.trim().split(/\r?\n/).filter(Boolean)
|
||||||
// Parse JSON lines from ripgrep output
|
// Parse JSON lines from ripgrep output
|
||||||
|
|
||||||
return lines
|
return lines
|
||||||
|
|||||||
@@ -11,9 +11,9 @@ import { createWrapper } from "@parcel/watcher/wrapper"
|
|||||||
import { lazy } from "@/util/lazy"
|
import { lazy } from "@/util/lazy"
|
||||||
import { withTimeout } from "@/util/timeout"
|
import { withTimeout } from "@/util/timeout"
|
||||||
import type ParcelWatcher from "@parcel/watcher"
|
import type ParcelWatcher from "@parcel/watcher"
|
||||||
import { $ } from "bun"
|
|
||||||
import { Flag } from "@/flag/flag"
|
import { Flag } from "@/flag/flag"
|
||||||
import { readdir } from "fs/promises"
|
import { readdir } from "fs/promises"
|
||||||
|
import { git } from "@/util/git"
|
||||||
|
|
||||||
const SUBSCRIBE_TIMEOUT_MS = 10_000
|
const SUBSCRIBE_TIMEOUT_MS = 10_000
|
||||||
|
|
||||||
@@ -88,13 +88,10 @@ export namespace FileWatcher {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (Instance.project.vcs === "git") {
|
if (Instance.project.vcs === "git") {
|
||||||
const vcsDir = await $`git rev-parse --git-dir`
|
const result = await git(["rev-parse", "--git-dir"], {
|
||||||
.quiet()
|
cwd: Instance.worktree,
|
||||||
.nothrow()
|
})
|
||||||
.cwd(Instance.worktree)
|
const vcsDir = result.exitCode === 0 ? path.resolve(Instance.worktree, result.text().trim()) : undefined
|
||||||
.text()
|
|
||||||
.then((x) => path.resolve(Instance.worktree, x.trim()))
|
|
||||||
.catch(() => undefined)
|
|
||||||
if (vcsDir && !cfgIgnores.includes(".git") && !cfgIgnores.includes(vcsDir)) {
|
if (vcsDir && !cfgIgnores.includes(".git") && !cfgIgnores.includes(vcsDir)) {
|
||||||
const gitDirContents = await readdir(vcsDir).catch(() => [])
|
const gitDirContents = await readdir(vcsDir).catch(() => [])
|
||||||
const ignoreList = gitDirContents.filter((entry) => entry !== "HEAD")
|
const ignoreList = gitDirContents.filter((entry) => entry !== "HEAD")
|
||||||
|
|||||||
@@ -57,6 +57,8 @@ export namespace Flag {
|
|||||||
export const OPENCODE_EXPERIMENTAL_LSP_TOOL = OPENCODE_EXPERIMENTAL || truthy("OPENCODE_EXPERIMENTAL_LSP_TOOL")
|
export const OPENCODE_EXPERIMENTAL_LSP_TOOL = OPENCODE_EXPERIMENTAL || truthy("OPENCODE_EXPERIMENTAL_LSP_TOOL")
|
||||||
export const OPENCODE_DISABLE_FILETIME_CHECK = truthy("OPENCODE_DISABLE_FILETIME_CHECK")
|
export const OPENCODE_DISABLE_FILETIME_CHECK = truthy("OPENCODE_DISABLE_FILETIME_CHECK")
|
||||||
export const OPENCODE_EXPERIMENTAL_PLAN_MODE = OPENCODE_EXPERIMENTAL || truthy("OPENCODE_EXPERIMENTAL_PLAN_MODE")
|
export const OPENCODE_EXPERIMENTAL_PLAN_MODE = OPENCODE_EXPERIMENTAL || truthy("OPENCODE_EXPERIMENTAL_PLAN_MODE")
|
||||||
|
export const OPENCODE_EXPERIMENTAL_WORKSPACES_TUI =
|
||||||
|
OPENCODE_EXPERIMENTAL || truthy("OPENCODE_EXPERIMENTAL_WORKSPACES_TUI")
|
||||||
export const OPENCODE_EXPERIMENTAL_MARKDOWN = !falsy("OPENCODE_EXPERIMENTAL_MARKDOWN")
|
export const OPENCODE_EXPERIMENTAL_MARKDOWN = !falsy("OPENCODE_EXPERIMENTAL_MARKDOWN")
|
||||||
export const OPENCODE_MODELS_URL = process.env["OPENCODE_MODELS_URL"]
|
export const OPENCODE_MODELS_URL = process.env["OPENCODE_MODELS_URL"]
|
||||||
export const OPENCODE_MODELS_PATH = process.env["OPENCODE_MODELS_PATH"]
|
export const OPENCODE_MODELS_PATH = process.env["OPENCODE_MODELS_PATH"]
|
||||||
|
|||||||
@@ -1,11 +1,12 @@
|
|||||||
import { BusEvent } from "@/bus/bus-event"
|
import { BusEvent } from "@/bus/bus-event"
|
||||||
import path from "path"
|
import path from "path"
|
||||||
import { $ } from "bun"
|
|
||||||
import z from "zod"
|
import z from "zod"
|
||||||
import { NamedError } from "@opencode-ai/util/error"
|
import { NamedError } from "@opencode-ai/util/error"
|
||||||
import { Log } from "../util/log"
|
import { Log } from "../util/log"
|
||||||
import { iife } from "@/util/iife"
|
import { iife } from "@/util/iife"
|
||||||
import { Flag } from "../flag/flag"
|
import { Flag } from "../flag/flag"
|
||||||
|
import { Process } from "@/util/process"
|
||||||
|
import { buffer } from "node:stream/consumers"
|
||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
const OPENCODE_VERSION: string
|
const OPENCODE_VERSION: string
|
||||||
@@ -15,6 +16,38 @@ declare global {
|
|||||||
export namespace Installation {
|
export namespace Installation {
|
||||||
const log = Log.create({ service: "installation" })
|
const log = Log.create({ service: "installation" })
|
||||||
|
|
||||||
|
async function text(cmd: string[], opts: { cwd?: string; env?: NodeJS.ProcessEnv } = {}) {
|
||||||
|
return Process.text(cmd, {
|
||||||
|
cwd: opts.cwd,
|
||||||
|
env: opts.env,
|
||||||
|
nothrow: true,
|
||||||
|
}).then((x) => x.text)
|
||||||
|
}
|
||||||
|
|
||||||
|
async function upgradeCurl(target: string) {
|
||||||
|
const body = await fetch("https://opencode.ai/install").then((res) => {
|
||||||
|
if (!res.ok) throw new Error(res.statusText)
|
||||||
|
return res.text()
|
||||||
|
})
|
||||||
|
const proc = Process.spawn(["bash"], {
|
||||||
|
stdin: "pipe",
|
||||||
|
stdout: "pipe",
|
||||||
|
stderr: "pipe",
|
||||||
|
env: {
|
||||||
|
...process.env,
|
||||||
|
VERSION: target,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
if (!proc.stdin || !proc.stdout || !proc.stderr) throw new Error("Process output not available")
|
||||||
|
proc.stdin.end(body)
|
||||||
|
const [code, stdout, stderr] = await Promise.all([proc.exited, buffer(proc.stdout), buffer(proc.stderr)])
|
||||||
|
return {
|
||||||
|
code,
|
||||||
|
stdout,
|
||||||
|
stderr,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export type Method = Awaited<ReturnType<typeof method>>
|
export type Method = Awaited<ReturnType<typeof method>>
|
||||||
|
|
||||||
export const Event = {
|
export const Event = {
|
||||||
@@ -65,31 +98,31 @@ export namespace Installation {
|
|||||||
const checks = [
|
const checks = [
|
||||||
{
|
{
|
||||||
name: "npm" as const,
|
name: "npm" as const,
|
||||||
command: () => $`npm list -g --depth=0`.throws(false).quiet().text(),
|
command: () => text(["npm", "list", "-g", "--depth=0"]),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "yarn" as const,
|
name: "yarn" as const,
|
||||||
command: () => $`yarn global list`.throws(false).quiet().text(),
|
command: () => text(["yarn", "global", "list"]),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "pnpm" as const,
|
name: "pnpm" as const,
|
||||||
command: () => $`pnpm list -g --depth=0`.throws(false).quiet().text(),
|
command: () => text(["pnpm", "list", "-g", "--depth=0"]),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "bun" as const,
|
name: "bun" as const,
|
||||||
command: () => $`bun pm ls -g`.throws(false).quiet().text(),
|
command: () => text(["bun", "pm", "ls", "-g"]),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "brew" as const,
|
name: "brew" as const,
|
||||||
command: () => $`brew list --formula opencode`.throws(false).quiet().text(),
|
command: () => text(["brew", "list", "--formula", "opencode"]),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "scoop" as const,
|
name: "scoop" as const,
|
||||||
command: () => $`scoop list opencode`.throws(false).quiet().text(),
|
command: () => text(["scoop", "list", "opencode"]),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "choco" as const,
|
name: "choco" as const,
|
||||||
command: () => $`choco list --limit-output opencode`.throws(false).quiet().text(),
|
command: () => text(["choco", "list", "--limit-output", "opencode"]),
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -121,61 +154,70 @@ export namespace Installation {
|
|||||||
)
|
)
|
||||||
|
|
||||||
async function getBrewFormula() {
|
async function getBrewFormula() {
|
||||||
const tapFormula = await $`brew list --formula anomalyco/tap/opencode`.throws(false).quiet().text()
|
const tapFormula = await text(["brew", "list", "--formula", "anomalyco/tap/opencode"])
|
||||||
if (tapFormula.includes("opencode")) return "anomalyco/tap/opencode"
|
if (tapFormula.includes("opencode")) return "anomalyco/tap/opencode"
|
||||||
const coreFormula = await $`brew list --formula opencode`.throws(false).quiet().text()
|
const coreFormula = await text(["brew", "list", "--formula", "opencode"])
|
||||||
if (coreFormula.includes("opencode")) return "opencode"
|
if (coreFormula.includes("opencode")) return "opencode"
|
||||||
return "opencode"
|
return "opencode"
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function upgrade(method: Method, target: string) {
|
export async function upgrade(method: Method, target: string) {
|
||||||
let cmd
|
let result: Awaited<ReturnType<typeof upgradeCurl>> | undefined
|
||||||
switch (method) {
|
switch (method) {
|
||||||
case "curl":
|
case "curl":
|
||||||
cmd = $`curl -fsSL https://opencode.ai/install | bash`.env({
|
result = await upgradeCurl(target)
|
||||||
...process.env,
|
|
||||||
VERSION: target,
|
|
||||||
})
|
|
||||||
break
|
break
|
||||||
case "npm":
|
case "npm":
|
||||||
cmd = $`npm install -g opencode-ai@${target}`
|
result = await Process.run(["npm", "install", "-g", `opencode-ai@${target}`], { nothrow: true })
|
||||||
break
|
break
|
||||||
case "pnpm":
|
case "pnpm":
|
||||||
cmd = $`pnpm install -g opencode-ai@${target}`
|
result = await Process.run(["pnpm", "install", "-g", `opencode-ai@${target}`], { nothrow: true })
|
||||||
break
|
break
|
||||||
case "bun":
|
case "bun":
|
||||||
cmd = $`bun install -g opencode-ai@${target}`
|
result = await Process.run(["bun", "install", "-g", `opencode-ai@${target}`], { nothrow: true })
|
||||||
break
|
break
|
||||||
case "brew": {
|
case "brew": {
|
||||||
const formula = await getBrewFormula()
|
const formula = await getBrewFormula()
|
||||||
if (formula.includes("/")) {
|
const env = {
|
||||||
cmd =
|
|
||||||
$`brew tap anomalyco/tap && cd "$(brew --repo anomalyco/tap)" && git pull --ff-only && brew upgrade ${formula}`.env(
|
|
||||||
{
|
|
||||||
HOMEBREW_NO_AUTO_UPDATE: "1",
|
|
||||||
...process.env,
|
|
||||||
},
|
|
||||||
)
|
|
||||||
break
|
|
||||||
}
|
|
||||||
cmd = $`brew upgrade ${formula}`.env({
|
|
||||||
HOMEBREW_NO_AUTO_UPDATE: "1",
|
HOMEBREW_NO_AUTO_UPDATE: "1",
|
||||||
...process.env,
|
...process.env,
|
||||||
})
|
}
|
||||||
|
if (formula.includes("/")) {
|
||||||
|
const tap = await Process.run(["brew", "tap", "anomalyco/tap"], { env, nothrow: true })
|
||||||
|
if (tap.code !== 0) {
|
||||||
|
result = tap
|
||||||
|
break
|
||||||
|
}
|
||||||
|
const repo = await Process.text(["brew", "--repo", "anomalyco/tap"], { env, nothrow: true })
|
||||||
|
if (repo.code !== 0) {
|
||||||
|
result = repo
|
||||||
|
break
|
||||||
|
}
|
||||||
|
const dir = repo.text.trim()
|
||||||
|
if (dir) {
|
||||||
|
const pull = await Process.run(["git", "pull", "--ff-only"], { cwd: dir, env, nothrow: true })
|
||||||
|
if (pull.code !== 0) {
|
||||||
|
result = pull
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
result = await Process.run(["brew", "upgrade", formula], { env, nothrow: true })
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
case "choco":
|
case "choco":
|
||||||
cmd = $`echo Y | choco upgrade opencode --version=${target}`
|
result = await Process.run(["choco", "upgrade", "opencode", `--version=${target}`, "-y"], { nothrow: true })
|
||||||
break
|
break
|
||||||
case "scoop":
|
case "scoop":
|
||||||
cmd = $`scoop install opencode@${target}`
|
result = await Process.run(["scoop", "install", `opencode@${target}`], { nothrow: true })
|
||||||
break
|
break
|
||||||
default:
|
default:
|
||||||
throw new Error(`Unknown method: ${method}`)
|
throw new Error(`Unknown method: ${method}`)
|
||||||
}
|
}
|
||||||
const result = await cmd.quiet().throws(false)
|
if (!result || result.code !== 0) {
|
||||||
if (result.exitCode !== 0) {
|
const stderr =
|
||||||
const stderr = method === "choco" ? "not running from an elevated command shell" : result.stderr.toString("utf8")
|
method === "choco" ? "not running from an elevated command shell" : result?.stderr.toString("utf8") || ""
|
||||||
throw new UpgradeFailedError({
|
throw new UpgradeFailedError({
|
||||||
stderr: stderr,
|
stderr: stderr,
|
||||||
})
|
})
|
||||||
@@ -186,7 +228,7 @@ export namespace Installation {
|
|||||||
stdout: result.stdout.toString(),
|
stdout: result.stdout.toString(),
|
||||||
stderr: result.stderr.toString(),
|
stderr: result.stderr.toString(),
|
||||||
})
|
})
|
||||||
await $`${process.execPath} --version`.nothrow().quiet().text()
|
await Process.text([process.execPath, "--version"], { nothrow: true })
|
||||||
}
|
}
|
||||||
|
|
||||||
export const VERSION = typeof OPENCODE_VERSION === "string" ? OPENCODE_VERSION : "local"
|
export const VERSION = typeof OPENCODE_VERSION === "string" ? OPENCODE_VERSION : "local"
|
||||||
@@ -199,7 +241,7 @@ export namespace Installation {
|
|||||||
if (detectedMethod === "brew") {
|
if (detectedMethod === "brew") {
|
||||||
const formula = await getBrewFormula()
|
const formula = await getBrewFormula()
|
||||||
if (formula.includes("/")) {
|
if (formula.includes("/")) {
|
||||||
const infoJson = await $`brew info --json=v2 ${formula}`.quiet().text()
|
const infoJson = await text(["brew", "info", "--json=v2", formula])
|
||||||
const info = JSON.parse(infoJson)
|
const info = JSON.parse(infoJson)
|
||||||
const version = info.formulae?.[0]?.versions?.stable
|
const version = info.formulae?.[0]?.versions?.stable
|
||||||
if (!version) throw new Error(`Could not detect version for tap formula: ${formula}`)
|
if (!version) throw new Error(`Could not detect version for tap formula: ${formula}`)
|
||||||
@@ -215,7 +257,7 @@ export namespace Installation {
|
|||||||
|
|
||||||
if (detectedMethod === "npm" || detectedMethod === "bun" || detectedMethod === "pnpm") {
|
if (detectedMethod === "npm" || detectedMethod === "bun" || detectedMethod === "pnpm") {
|
||||||
const registry = await iife(async () => {
|
const registry = await iife(async () => {
|
||||||
const r = (await $`npm config get registry`.quiet().nothrow().text()).trim()
|
const r = (await text(["npm", "config", "get", "registry"])).trim()
|
||||||
const reg = r || "https://registry.npmjs.org"
|
const reg = r || "https://registry.npmjs.org"
|
||||||
return reg.endsWith("/") ? reg.slice(0, -1) : reg
|
return reg.endsWith("/") ? reg.slice(0, -1) : reg
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ import os from "os"
|
|||||||
import { Global } from "../global"
|
import { Global } from "../global"
|
||||||
import { Log } from "../util/log"
|
import { Log } from "../util/log"
|
||||||
import { BunProc } from "../bun"
|
import { BunProc } from "../bun"
|
||||||
import { $ } from "bun"
|
|
||||||
import { text } from "node:stream/consumers"
|
import { text } from "node:stream/consumers"
|
||||||
import fs from "fs/promises"
|
import fs from "fs/promises"
|
||||||
import { Filesystem } from "../util/filesystem"
|
import { Filesystem } from "../util/filesystem"
|
||||||
@@ -13,6 +12,7 @@ import { Flag } from "../flag/flag"
|
|||||||
import { Archive } from "../util/archive"
|
import { Archive } from "../util/archive"
|
||||||
import { Process } from "../util/process"
|
import { Process } from "../util/process"
|
||||||
import { which } from "../util/which"
|
import { which } from "../util/which"
|
||||||
|
import { Module } from "@opencode-ai/util/module"
|
||||||
|
|
||||||
export namespace LSPServer {
|
export namespace LSPServer {
|
||||||
const log = Log.create({ service: "lsp.server" })
|
const log = Log.create({ service: "lsp.server" })
|
||||||
@@ -21,6 +21,8 @@ export namespace LSPServer {
|
|||||||
.stat(p)
|
.stat(p)
|
||||||
.then(() => true)
|
.then(() => true)
|
||||||
.catch(() => false)
|
.catch(() => false)
|
||||||
|
const run = (cmd: string[], opts: Process.RunOptions = {}) => Process.run(cmd, { ...opts, nothrow: true })
|
||||||
|
const output = (cmd: string[], opts: Process.RunOptions = {}) => Process.text(cmd, { ...opts, nothrow: true })
|
||||||
|
|
||||||
export interface Handle {
|
export interface Handle {
|
||||||
process: ChildProcessWithoutNullStreams
|
process: ChildProcessWithoutNullStreams
|
||||||
@@ -97,7 +99,7 @@ export namespace LSPServer {
|
|||||||
),
|
),
|
||||||
extensions: [".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs", ".mts", ".cts"],
|
extensions: [".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs", ".mts", ".cts"],
|
||||||
async spawn(root) {
|
async spawn(root) {
|
||||||
const tsserver = await Bun.resolve("typescript/lib/tsserver.js", Instance.directory).catch(() => {})
|
const tsserver = Module.resolve("typescript/lib/tsserver.js", Instance.directory)
|
||||||
log.info("typescript server", { tsserver })
|
log.info("typescript server", { tsserver })
|
||||||
if (!tsserver) return
|
if (!tsserver) return
|
||||||
const proc = spawn(BunProc.which(), ["x", "typescript-language-server", "--stdio"], {
|
const proc = spawn(BunProc.which(), ["x", "typescript-language-server", "--stdio"], {
|
||||||
@@ -172,7 +174,7 @@ export namespace LSPServer {
|
|||||||
root: NearestRoot(["package-lock.json", "bun.lockb", "bun.lock", "pnpm-lock.yaml", "yarn.lock"]),
|
root: NearestRoot(["package-lock.json", "bun.lockb", "bun.lock", "pnpm-lock.yaml", "yarn.lock"]),
|
||||||
extensions: [".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs", ".mts", ".cts", ".vue"],
|
extensions: [".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs", ".mts", ".cts", ".vue"],
|
||||||
async spawn(root) {
|
async spawn(root) {
|
||||||
const eslint = await Bun.resolve("eslint", Instance.directory).catch(() => {})
|
const eslint = Module.resolve("eslint", Instance.directory)
|
||||||
if (!eslint) return
|
if (!eslint) return
|
||||||
log.info("spawning eslint server")
|
log.info("spawning eslint server")
|
||||||
const serverPath = path.join(Global.Path.bin, "vscode-eslint", "server", "out", "eslintServer.js")
|
const serverPath = path.join(Global.Path.bin, "vscode-eslint", "server", "out", "eslintServer.js")
|
||||||
@@ -205,8 +207,8 @@ export namespace LSPServer {
|
|||||||
await fs.rename(extractedPath, finalPath)
|
await fs.rename(extractedPath, finalPath)
|
||||||
|
|
||||||
const npmCmd = process.platform === "win32" ? "npm.cmd" : "npm"
|
const npmCmd = process.platform === "win32" ? "npm.cmd" : "npm"
|
||||||
await $`${npmCmd} install`.cwd(finalPath).quiet()
|
await Process.run([npmCmd, "install"], { cwd: finalPath })
|
||||||
await $`${npmCmd} run compile`.cwd(finalPath).quiet()
|
await Process.run([npmCmd, "run", "compile"], { cwd: finalPath })
|
||||||
|
|
||||||
log.info("installed VS Code ESLint server", { serverPath })
|
log.info("installed VS Code ESLint server", { serverPath })
|
||||||
}
|
}
|
||||||
@@ -340,7 +342,7 @@ export namespace LSPServer {
|
|||||||
let args = ["lsp-proxy", "--stdio"]
|
let args = ["lsp-proxy", "--stdio"]
|
||||||
|
|
||||||
if (!bin) {
|
if (!bin) {
|
||||||
const resolved = await Bun.resolve("biome", root).catch(() => undefined)
|
const resolved = Module.resolve("biome", root)
|
||||||
if (!resolved) return
|
if (!resolved) return
|
||||||
bin = BunProc.which()
|
bin = BunProc.which()
|
||||||
args = ["x", "biome", "lsp-proxy", "--stdio"]
|
args = ["x", "biome", "lsp-proxy", "--stdio"]
|
||||||
@@ -602,10 +604,11 @@ export namespace LSPServer {
|
|||||||
recursive: true,
|
recursive: true,
|
||||||
})
|
})
|
||||||
|
|
||||||
await $`mix deps.get && mix compile && mix elixir_ls.release2 -o release`
|
const cwd = path.join(Global.Path.bin, "elixir-ls-master")
|
||||||
.quiet()
|
const env = { MIX_ENV: "prod", ...process.env }
|
||||||
.cwd(path.join(Global.Path.bin, "elixir-ls-master"))
|
await Process.run(["mix", "deps.get"], { cwd, env })
|
||||||
.env({ MIX_ENV: "prod", ...process.env })
|
await Process.run(["mix", "compile"], { cwd, env })
|
||||||
|
await Process.run(["mix", "elixir_ls.release2", "-o", "release"], { cwd, env })
|
||||||
|
|
||||||
log.info(`installed elixir-ls`, {
|
log.info(`installed elixir-ls`, {
|
||||||
path: elixirLsPath,
|
path: elixirLsPath,
|
||||||
@@ -706,7 +709,7 @@ export namespace LSPServer {
|
|||||||
})
|
})
|
||||||
if (!ok) return
|
if (!ok) return
|
||||||
} else {
|
} else {
|
||||||
await $`tar -xf ${tempPath}`.cwd(Global.Path.bin).quiet().nothrow()
|
await run(["tar", "-xf", tempPath], { cwd: Global.Path.bin })
|
||||||
}
|
}
|
||||||
|
|
||||||
await fs.rm(tempPath, { force: true })
|
await fs.rm(tempPath, { force: true })
|
||||||
@@ -719,7 +722,7 @@ export namespace LSPServer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (platform !== "win32") {
|
if (platform !== "win32") {
|
||||||
await $`chmod +x ${bin}`.quiet().nothrow()
|
await fs.chmod(bin, 0o755).catch(() => {})
|
||||||
}
|
}
|
||||||
|
|
||||||
log.info(`installed zls`, { bin })
|
log.info(`installed zls`, { bin })
|
||||||
@@ -831,11 +834,11 @@ export namespace LSPServer {
|
|||||||
// This is specific to macOS where sourcekit-lsp is typically installed with Xcode
|
// This is specific to macOS where sourcekit-lsp is typically installed with Xcode
|
||||||
if (!which("xcrun")) return
|
if (!which("xcrun")) return
|
||||||
|
|
||||||
const lspLoc = await $`xcrun --find sourcekit-lsp`.quiet().nothrow()
|
const lspLoc = await output(["xcrun", "--find", "sourcekit-lsp"])
|
||||||
|
|
||||||
if (lspLoc.exitCode !== 0) return
|
if (lspLoc.code !== 0) return
|
||||||
|
|
||||||
const bin = lspLoc.text().trim()
|
const bin = lspLoc.text.trim()
|
||||||
|
|
||||||
return {
|
return {
|
||||||
process: spawn(bin, {
|
process: spawn(bin, {
|
||||||
@@ -1010,7 +1013,7 @@ export namespace LSPServer {
|
|||||||
if (!ok) return
|
if (!ok) return
|
||||||
}
|
}
|
||||||
if (tar) {
|
if (tar) {
|
||||||
await $`tar -xf ${archive}`.cwd(Global.Path.bin).quiet().nothrow()
|
await run(["tar", "-xf", archive], { cwd: Global.Path.bin })
|
||||||
}
|
}
|
||||||
await fs.rm(archive, { force: true })
|
await fs.rm(archive, { force: true })
|
||||||
|
|
||||||
@@ -1021,7 +1024,7 @@ export namespace LSPServer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (platform !== "win32") {
|
if (platform !== "win32") {
|
||||||
await $`chmod +x ${bin}`.quiet().nothrow()
|
await fs.chmod(bin, 0o755).catch(() => {})
|
||||||
}
|
}
|
||||||
|
|
||||||
await fs.unlink(path.join(Global.Path.bin, "clangd")).catch(() => {})
|
await fs.unlink(path.join(Global.Path.bin, "clangd")).catch(() => {})
|
||||||
@@ -1082,7 +1085,7 @@ export namespace LSPServer {
|
|||||||
extensions: [".astro"],
|
extensions: [".astro"],
|
||||||
root: NearestRoot(["package-lock.json", "bun.lockb", "bun.lock", "pnpm-lock.yaml", "yarn.lock"]),
|
root: NearestRoot(["package-lock.json", "bun.lockb", "bun.lock", "pnpm-lock.yaml", "yarn.lock"]),
|
||||||
async spawn(root) {
|
async spawn(root) {
|
||||||
const tsserver = await Bun.resolve("typescript/lib/tsserver.js", Instance.directory).catch(() => {})
|
const tsserver = Module.resolve("typescript/lib/tsserver.js", Instance.directory)
|
||||||
if (!tsserver) {
|
if (!tsserver) {
|
||||||
log.info("typescript not found, required for Astro language server")
|
log.info("typescript not found, required for Astro language server")
|
||||||
return
|
return
|
||||||
@@ -1130,7 +1133,30 @@ export namespace LSPServer {
|
|||||||
|
|
||||||
export const JDTLS: Info = {
|
export const JDTLS: Info = {
|
||||||
id: "jdtls",
|
id: "jdtls",
|
||||||
root: NearestRoot(["pom.xml", "build.gradle", "build.gradle.kts", ".project", ".classpath"]),
|
root: async (file) => {
|
||||||
|
// Without exclusions, NearestRoot defaults to instance directory so we can't
|
||||||
|
// distinguish between a) no project found and b) project found at instance dir.
|
||||||
|
// So we can't choose the root from (potential) monorepo markers first.
|
||||||
|
// Look for potential subproject markers first while excluding potential monorepo markers.
|
||||||
|
const settingsMarkers = ["settings.gradle", "settings.gradle.kts"]
|
||||||
|
const gradleMarkers = ["gradlew", "gradlew.bat"]
|
||||||
|
const exclusionsForMonorepos = gradleMarkers.concat(settingsMarkers)
|
||||||
|
|
||||||
|
const [projectRoot, wrapperRoot, settingsRoot] = await Promise.all([
|
||||||
|
NearestRoot(
|
||||||
|
["pom.xml", "build.gradle", "build.gradle.kts", ".project", ".classpath"],
|
||||||
|
exclusionsForMonorepos,
|
||||||
|
)(file),
|
||||||
|
NearestRoot(gradleMarkers, settingsMarkers)(file),
|
||||||
|
NearestRoot(settingsMarkers)(file),
|
||||||
|
])
|
||||||
|
|
||||||
|
// If projectRoot is undefined we know we are in a monorepo or no project at all.
|
||||||
|
// So can safely fall through to the other roots
|
||||||
|
if (projectRoot) return projectRoot
|
||||||
|
if (wrapperRoot) return wrapperRoot
|
||||||
|
if (settingsRoot) return settingsRoot
|
||||||
|
},
|
||||||
extensions: [".java"],
|
extensions: [".java"],
|
||||||
async spawn(root) {
|
async spawn(root) {
|
||||||
const java = which("java")
|
const java = which("java")
|
||||||
@@ -1138,13 +1164,10 @@ export namespace LSPServer {
|
|||||||
log.error("Java 21 or newer is required to run the JDTLS. Please install it first.")
|
log.error("Java 21 or newer is required to run the JDTLS. Please install it first.")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
const javaMajorVersion = await $`java -version`
|
const javaMajorVersion = await run(["java", "-version"]).then((result) => {
|
||||||
.quiet()
|
const m = /"(\d+)\.\d+\.\d+"/.exec(result.stderr.toString())
|
||||||
.nothrow()
|
return !m ? undefined : parseInt(m[1])
|
||||||
.then(({ stderr }) => {
|
})
|
||||||
const m = /"(\d+)\.\d+\.\d+"/.exec(stderr.toString())
|
|
||||||
return !m ? undefined : parseInt(m[1])
|
|
||||||
})
|
|
||||||
if (javaMajorVersion == null || javaMajorVersion < 21) {
|
if (javaMajorVersion == null || javaMajorVersion < 21) {
|
||||||
log.error("JDTLS requires at least Java 21.")
|
log.error("JDTLS requires at least Java 21.")
|
||||||
return
|
return
|
||||||
@@ -1161,27 +1184,27 @@ export namespace LSPServer {
|
|||||||
const archiveName = "release.tar.gz"
|
const archiveName = "release.tar.gz"
|
||||||
|
|
||||||
log.info("Downloading JDTLS archive", { url: releaseURL, dest: distPath })
|
log.info("Downloading JDTLS archive", { url: releaseURL, dest: distPath })
|
||||||
const curlResult = await $`curl -L -o ${archiveName} '${releaseURL}'`.cwd(distPath).quiet().nothrow()
|
const download = await fetch(releaseURL)
|
||||||
if (curlResult.exitCode !== 0) {
|
if (!download.ok || !download.body) {
|
||||||
log.error("Failed to download JDTLS", { exitCode: curlResult.exitCode, stderr: curlResult.stderr.toString() })
|
log.error("Failed to download JDTLS", { status: download.status, statusText: download.statusText })
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
await Filesystem.writeStream(path.join(distPath, archiveName), download.body)
|
||||||
|
|
||||||
log.info("Extracting JDTLS archive")
|
log.info("Extracting JDTLS archive")
|
||||||
const tarResult = await $`tar -xzf ${archiveName}`.cwd(distPath).quiet().nothrow()
|
const tarResult = await run(["tar", "-xzf", archiveName], { cwd: distPath })
|
||||||
if (tarResult.exitCode !== 0) {
|
if (tarResult.code !== 0) {
|
||||||
log.error("Failed to extract JDTLS", { exitCode: tarResult.exitCode, stderr: tarResult.stderr.toString() })
|
log.error("Failed to extract JDTLS", { exitCode: tarResult.code, stderr: tarResult.stderr.toString() })
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
await fs.rm(path.join(distPath, archiveName), { force: true })
|
await fs.rm(path.join(distPath, archiveName), { force: true })
|
||||||
log.info("JDTLS download and extraction completed")
|
log.info("JDTLS download and extraction completed")
|
||||||
}
|
}
|
||||||
const jarFileName = await $`ls org.eclipse.equinox.launcher_*.jar`
|
const jarFileName =
|
||||||
.cwd(launcherDir)
|
(await fs.readdir(launcherDir).catch(() => []))
|
||||||
.quiet()
|
.find((item) => /^org\.eclipse\.equinox\.launcher_.*\.jar$/.test(item))
|
||||||
.nothrow()
|
?.trim() ?? ""
|
||||||
.then(({ stdout }) => stdout.toString().trim())
|
|
||||||
const launcherJar = path.join(launcherDir, jarFileName)
|
const launcherJar = path.join(launcherDir, jarFileName)
|
||||||
if (!(await pathExists(launcherJar))) {
|
if (!(await pathExists(launcherJar))) {
|
||||||
log.error(`Failed to locate the JDTLS launcher module in the installed directory: ${distPath}.`)
|
log.error(`Failed to locate the JDTLS launcher module in the installed directory: ${distPath}.`)
|
||||||
@@ -1294,7 +1317,15 @@ export namespace LSPServer {
|
|||||||
|
|
||||||
await fs.mkdir(distPath, { recursive: true })
|
await fs.mkdir(distPath, { recursive: true })
|
||||||
const archivePath = path.join(distPath, "kotlin-ls.zip")
|
const archivePath = path.join(distPath, "kotlin-ls.zip")
|
||||||
await $`curl -L -o '${archivePath}' '${releaseURL}'`.quiet().nothrow()
|
const download = await fetch(releaseURL)
|
||||||
|
if (!download.ok || !download.body) {
|
||||||
|
log.error("Failed to download Kotlin Language Server", {
|
||||||
|
status: download.status,
|
||||||
|
statusText: download.statusText,
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
await Filesystem.writeStream(archivePath, download.body)
|
||||||
const ok = await Archive.extractZip(archivePath, distPath)
|
const ok = await Archive.extractZip(archivePath, distPath)
|
||||||
.then(() => true)
|
.then(() => true)
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
@@ -1304,7 +1335,7 @@ export namespace LSPServer {
|
|||||||
if (!ok) return
|
if (!ok) return
|
||||||
await fs.rm(archivePath, { force: true })
|
await fs.rm(archivePath, { force: true })
|
||||||
if (process.platform !== "win32") {
|
if (process.platform !== "win32") {
|
||||||
await $`chmod +x ${launcherScript}`.quiet().nothrow()
|
await fs.chmod(launcherScript, 0o755).catch(() => {})
|
||||||
}
|
}
|
||||||
log.info("Installed Kotlin Language Server", { path: launcherScript })
|
log.info("Installed Kotlin Language Server", { path: launcherScript })
|
||||||
}
|
}
|
||||||
@@ -1468,10 +1499,9 @@ export namespace LSPServer {
|
|||||||
})
|
})
|
||||||
if (!ok) return
|
if (!ok) return
|
||||||
} else {
|
} else {
|
||||||
const ok = await $`tar -xzf ${tempPath} -C ${installDir}`
|
const ok = await run(["tar", "-xzf", tempPath, "-C", installDir])
|
||||||
.quiet()
|
.then((result) => result.code === 0)
|
||||||
.then(() => true)
|
.catch((error: unknown) => {
|
||||||
.catch((error) => {
|
|
||||||
log.error("Failed to extract lua-language-server archive", { error })
|
log.error("Failed to extract lua-language-server archive", { error })
|
||||||
return false
|
return false
|
||||||
})
|
})
|
||||||
@@ -1489,11 +1519,15 @@ export namespace LSPServer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (platform !== "win32") {
|
if (platform !== "win32") {
|
||||||
const ok = await $`chmod +x ${bin}`.quiet().catch((error) => {
|
const ok = await fs
|
||||||
log.error("Failed to set executable permission for lua-language-server binary", {
|
.chmod(bin, 0o755)
|
||||||
error,
|
.then(() => true)
|
||||||
|
.catch((error: unknown) => {
|
||||||
|
log.error("Failed to set executable permission for lua-language-server binary", {
|
||||||
|
error,
|
||||||
|
})
|
||||||
|
return false
|
||||||
})
|
})
|
||||||
})
|
|
||||||
if (!ok) return
|
if (!ok) return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1707,7 +1741,7 @@ export namespace LSPServer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (platform !== "win32") {
|
if (platform !== "win32") {
|
||||||
await $`chmod +x ${bin}`.quiet().nothrow()
|
await fs.chmod(bin, 0o755).catch(() => {})
|
||||||
}
|
}
|
||||||
|
|
||||||
log.info(`installed terraform-ls`, { bin })
|
log.info(`installed terraform-ls`, { bin })
|
||||||
@@ -1790,7 +1824,7 @@ export namespace LSPServer {
|
|||||||
if (!ok) return
|
if (!ok) return
|
||||||
}
|
}
|
||||||
if (ext === "tar.gz") {
|
if (ext === "tar.gz") {
|
||||||
await $`tar -xzf ${tempPath}`.cwd(Global.Path.bin).quiet().nothrow()
|
await run(["tar", "-xzf", tempPath], { cwd: Global.Path.bin })
|
||||||
}
|
}
|
||||||
|
|
||||||
await fs.rm(tempPath, { force: true })
|
await fs.rm(tempPath, { force: true })
|
||||||
@@ -1803,7 +1837,7 @@ export namespace LSPServer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (platform !== "win32") {
|
if (platform !== "win32") {
|
||||||
await $`chmod +x ${bin}`.quiet().nothrow()
|
await fs.chmod(bin, 0o755).catch(() => {})
|
||||||
}
|
}
|
||||||
|
|
||||||
log.info("installed texlab", { bin })
|
log.info("installed texlab", { bin })
|
||||||
@@ -1995,7 +2029,7 @@ export namespace LSPServer {
|
|||||||
})
|
})
|
||||||
if (!ok) return
|
if (!ok) return
|
||||||
} else {
|
} else {
|
||||||
await $`tar -xzf ${tempPath} --strip-components=1`.cwd(Global.Path.bin).quiet().nothrow()
|
await run(["tar", "-xzf", tempPath, "--strip-components=1"], { cwd: Global.Path.bin })
|
||||||
}
|
}
|
||||||
|
|
||||||
await fs.rm(tempPath, { force: true })
|
await fs.rm(tempPath, { force: true })
|
||||||
@@ -2008,7 +2042,7 @@ export namespace LSPServer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (platform !== "win32") {
|
if (platform !== "win32") {
|
||||||
await $`chmod +x ${bin}`.quiet().nothrow()
|
await fs.chmod(bin, 0o755).catch(() => {})
|
||||||
}
|
}
|
||||||
|
|
||||||
log.info("installed tinymist", { bin })
|
log.info("installed tinymist", { bin })
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
export { Server } from "./server/server"
|
||||||
@@ -1,11 +1,11 @@
|
|||||||
import { BusEvent } from "@/bus/bus-event"
|
import { BusEvent } from "@/bus/bus-event"
|
||||||
import { Bus } from "@/bus"
|
import { Bus } from "@/bus"
|
||||||
import { $ } from "bun"
|
|
||||||
import path from "path"
|
import path from "path"
|
||||||
import z from "zod"
|
import z from "zod"
|
||||||
import { Log } from "@/util/log"
|
import { Log } from "@/util/log"
|
||||||
import { Instance } from "./instance"
|
import { Instance } from "./instance"
|
||||||
import { FileWatcher } from "@/file/watcher"
|
import { FileWatcher } from "@/file/watcher"
|
||||||
|
import { git } from "@/util/git"
|
||||||
|
|
||||||
const log = Log.create({ service: "vcs" })
|
const log = Log.create({ service: "vcs" })
|
||||||
|
|
||||||
@@ -29,13 +29,13 @@ export namespace Vcs {
|
|||||||
export type Info = z.infer<typeof Info>
|
export type Info = z.infer<typeof Info>
|
||||||
|
|
||||||
async function currentBranch() {
|
async function currentBranch() {
|
||||||
return $`git rev-parse --abbrev-ref HEAD`
|
const result = await git(["rev-parse", "--abbrev-ref", "HEAD"], {
|
||||||
.quiet()
|
cwd: Instance.worktree,
|
||||||
.nothrow()
|
})
|
||||||
.cwd(Instance.worktree)
|
if (result.exitCode !== 0) return
|
||||||
.text()
|
const text = result.text().trim()
|
||||||
.then((x) => x.trim())
|
if (!text) return
|
||||||
.catch(() => undefined)
|
return text
|
||||||
}
|
}
|
||||||
|
|
||||||
const state = Instance.state(
|
const state = Instance.state(
|
||||||
|
|||||||
@@ -480,6 +480,7 @@ export namespace Provider {
|
|||||||
|
|
||||||
const aiGatewayHeaders = {
|
const aiGatewayHeaders = {
|
||||||
"User-Agent": `opencode/${Installation.VERSION} gitlab-ai-provider/${GITLAB_PROVIDER_VERSION} (${os.platform()} ${os.release()}; ${os.arch()})`,
|
"User-Agent": `opencode/${Installation.VERSION} gitlab-ai-provider/${GITLAB_PROVIDER_VERSION} (${os.platform()} ${os.release()}; ${os.arch()})`,
|
||||||
|
"anthropic-beta": "context-1m-2025-08-07",
|
||||||
...(providerConfig?.options?.aiGatewayHeaders || {}),
|
...(providerConfig?.options?.aiGatewayHeaders || {}),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -440,7 +440,9 @@ export namespace ProviderTransform {
|
|||||||
const copilotEfforts = iife(() => {
|
const copilotEfforts = iife(() => {
|
||||||
if (id.includes("5.1-codex-max") || id.includes("5.2") || id.includes("5.3"))
|
if (id.includes("5.1-codex-max") || id.includes("5.2") || id.includes("5.3"))
|
||||||
return [...WIDELY_SUPPORTED_EFFORTS, "xhigh"]
|
return [...WIDELY_SUPPORTED_EFFORTS, "xhigh"]
|
||||||
return WIDELY_SUPPORTED_EFFORTS
|
const arr = [...WIDELY_SUPPORTED_EFFORTS]
|
||||||
|
if (id.includes("gpt-5") && model.release_date >= "2025-12-04") arr.push("xhigh")
|
||||||
|
return arr
|
||||||
})
|
})
|
||||||
return Object.fromEntries(
|
return Object.fromEntries(
|
||||||
copilotEfforts.map((effort) => [
|
copilotEfforts.map((effort) => [
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
import { Hono } from "hono"
|
import { Hono } from "hono"
|
||||||
import { describeRoute, validator, resolver } from "hono-openapi"
|
import { describeRoute, validator, resolver } from "hono-openapi"
|
||||||
import { upgradeWebSocket } from "hono/bun"
|
|
||||||
import z from "zod"
|
import z from "zod"
|
||||||
import { Pty } from "@/pty"
|
import { Pty } from "@/pty"
|
||||||
import { NotFoundError } from "../../storage/db"
|
import { NotFoundError } from "../../storage/db"
|
||||||
import { errors } from "../error"
|
import { errors } from "../error"
|
||||||
import { lazy } from "../../util/lazy"
|
import { lazy } from "../../util/lazy"
|
||||||
|
import { Server } from "../server"
|
||||||
|
|
||||||
export const PtyRoutes = lazy(() =>
|
export const PtyRoutes = lazy(() =>
|
||||||
new Hono()
|
new Hono()
|
||||||
@@ -149,7 +149,7 @@ export const PtyRoutes = lazy(() =>
|
|||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
validator("param", z.object({ ptyID: z.string() })),
|
validator("param", z.object({ ptyID: z.string() })),
|
||||||
upgradeWebSocket((c) => {
|
Server.upgradeWebSocket((c) => {
|
||||||
const id = c.req.param("ptyID")
|
const id = c.req.param("ptyID")
|
||||||
const cursor = (() => {
|
const cursor = (() => {
|
||||||
const value = c.req.query("cursor")
|
const value = c.req.query("cursor")
|
||||||
|
|||||||
@@ -35,7 +35,8 @@ import { lazy } from "../util/lazy"
|
|||||||
import { InstanceBootstrap } from "../project/bootstrap"
|
import { InstanceBootstrap } from "../project/bootstrap"
|
||||||
import { NotFoundError } from "../storage/db"
|
import { NotFoundError } from "../storage/db"
|
||||||
import type { ContentfulStatusCode } from "hono/utils/http-status"
|
import type { ContentfulStatusCode } from "hono/utils/http-status"
|
||||||
import { websocket } from "hono/bun"
|
import { createAdaptorServer } from "@hono/node-server"
|
||||||
|
import { createNodeWebSocket } from "@hono/node-ws"
|
||||||
import { HTTPException } from "hono/http-exception"
|
import { HTTPException } from "hono/http-exception"
|
||||||
import { errors } from "./error"
|
import { errors } from "./error"
|
||||||
import { Filesystem } from "@/util/filesystem"
|
import { Filesystem } from "@/util/filesystem"
|
||||||
@@ -58,6 +59,8 @@ export namespace Server {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const app = new Hono()
|
const app = new Hono()
|
||||||
|
const ws = createNodeWebSocket({ app })
|
||||||
|
export const upgradeWebSocket = ws.upgradeWebSocket
|
||||||
export const App: () => Hono = lazy(
|
export const App: () => Hono = lazy(
|
||||||
() =>
|
() =>
|
||||||
// TODO: Break server.ts into smaller route files to fix type inference
|
// TODO: Break server.ts into smaller route files to fix type inference
|
||||||
@@ -246,7 +249,7 @@ export namespace Server {
|
|||||||
),
|
),
|
||||||
)
|
)
|
||||||
.route("/project", ProjectRoutes())
|
.route("/project", ProjectRoutes())
|
||||||
.route("/pty", PtyRoutes())
|
// .route("/pty", PtyRoutes())
|
||||||
.route("/config", ConfigRoutes())
|
.route("/config", ConfigRoutes())
|
||||||
.route("/experimental", ExperimentalRoutes())
|
.route("/experimental", ExperimentalRoutes())
|
||||||
.route("/session", SessionRoutes())
|
.route("/session", SessionRoutes())
|
||||||
@@ -594,7 +597,7 @@ export namespace Server {
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
export function listen(opts: {
|
export async function listen(opts: {
|
||||||
port: number
|
port: number
|
||||||
hostname: string
|
hostname: string
|
||||||
mdns?: boolean
|
mdns?: boolean
|
||||||
@@ -603,42 +606,83 @@ export namespace Server {
|
|||||||
}) {
|
}) {
|
||||||
_corsWhitelist = opts.cors ?? []
|
_corsWhitelist = opts.cors ?? []
|
||||||
|
|
||||||
const args = {
|
const start = async (port: number) => {
|
||||||
hostname: opts.hostname,
|
const server = createAdaptorServer(App())
|
||||||
idleTimeout: 0,
|
ws.injectWebSocket(server)
|
||||||
fetch: App().fetch,
|
await new Promise<void>((resolve, reject) => {
|
||||||
websocket: websocket,
|
const fail = (err: Error) => {
|
||||||
} as const
|
cleanup()
|
||||||
const tryServe = (port: number) => {
|
reject(err)
|
||||||
try {
|
}
|
||||||
return Bun.serve({ ...args, port })
|
const ready = () => {
|
||||||
} catch {
|
cleanup()
|
||||||
return undefined
|
resolve()
|
||||||
}
|
}
|
||||||
|
const cleanup = () => {
|
||||||
|
server.off("error", fail)
|
||||||
|
server.off("listening", ready)
|
||||||
|
}
|
||||||
|
server.once("error", fail)
|
||||||
|
server.once("listening", ready)
|
||||||
|
server.listen(port, opts.hostname)
|
||||||
|
})
|
||||||
|
return server
|
||||||
}
|
}
|
||||||
const server = opts.port === 0 ? (tryServe(4096) ?? tryServe(0)) : tryServe(opts.port)
|
|
||||||
if (!server) throw new Error(`Failed to start server on port ${opts.port}`)
|
|
||||||
|
|
||||||
_url = server.url
|
const server = await (async () => {
|
||||||
|
if (opts.port !== 0) return start(opts.port)
|
||||||
|
try {
|
||||||
|
return await start(4096)
|
||||||
|
} catch {
|
||||||
|
return start(0)
|
||||||
|
}
|
||||||
|
})()
|
||||||
|
|
||||||
|
const addr = server.address()
|
||||||
|
if (!addr || typeof addr === "string") {
|
||||||
|
throw new Error(`Failed to resolve server address for port ${opts.port}`)
|
||||||
|
}
|
||||||
|
|
||||||
|
const url = new URL("http://localhost")
|
||||||
|
url.hostname = opts.hostname
|
||||||
|
url.port = String(addr.port)
|
||||||
|
_url = url
|
||||||
|
|
||||||
const shouldPublishMDNS =
|
const shouldPublishMDNS =
|
||||||
opts.mdns &&
|
opts.mdns &&
|
||||||
server.port &&
|
addr.port &&
|
||||||
opts.hostname !== "127.0.0.1" &&
|
opts.hostname !== "127.0.0.1" &&
|
||||||
opts.hostname !== "localhost" &&
|
opts.hostname !== "localhost" &&
|
||||||
opts.hostname !== "::1"
|
opts.hostname !== "::1"
|
||||||
if (shouldPublishMDNS) {
|
if (shouldPublishMDNS) {
|
||||||
MDNS.publish(server.port!, opts.mdnsDomain)
|
MDNS.publish(addr.port, opts.mdnsDomain)
|
||||||
} else if (opts.mdns) {
|
} else if (opts.mdns) {
|
||||||
log.warn("mDNS enabled but hostname is loopback; skipping mDNS publish")
|
log.warn("mDNS enabled but hostname is loopback; skipping mDNS publish")
|
||||||
}
|
}
|
||||||
|
|
||||||
const originalStop = server.stop.bind(server)
|
let closing: Promise<void> | undefined
|
||||||
server.stop = async (closeActiveConnections?: boolean) => {
|
return {
|
||||||
if (shouldPublishMDNS) MDNS.unpublish()
|
hostname: opts.hostname,
|
||||||
return originalStop(closeActiveConnections)
|
port: addr.port,
|
||||||
|
url,
|
||||||
|
stop(close?: boolean) {
|
||||||
|
closing ??= new Promise<void>((resolve, reject) => {
|
||||||
|
if (shouldPublishMDNS) MDNS.unpublish()
|
||||||
|
server.close((err?: Error) => {
|
||||||
|
if (err) {
|
||||||
|
reject(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
resolve()
|
||||||
|
})
|
||||||
|
if (close) {
|
||||||
|
const node = server as { closeAllConnections?: () => void; closeIdleConnections?: () => void }
|
||||||
|
node.closeAllConnections?.()
|
||||||
|
node.closeIdleConnections?.()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return closing
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
return server
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,12 +8,8 @@ import { Snapshot } from "@/snapshot"
|
|||||||
import { fn } from "@/util/fn"
|
import { fn } from "@/util/fn"
|
||||||
import { Database, eq, desc, inArray } from "@/storage/db"
|
import { Database, eq, desc, inArray } from "@/storage/db"
|
||||||
import { MessageTable, PartTable } from "./session.sql"
|
import { MessageTable, PartTable } from "./session.sql"
|
||||||
import { ProviderTransform } from "@/provider/transform"
|
|
||||||
import { STATUS_CODES } from "http"
|
|
||||||
import { Storage } from "@/storage/storage"
|
|
||||||
import { ProviderError } from "@/provider/error"
|
import { ProviderError } from "@/provider/error"
|
||||||
import { iife } from "@/util/iife"
|
import { iife } from "@/util/iife"
|
||||||
import { type SystemError } from "bun"
|
|
||||||
import type { Provider } from "@/provider/provider"
|
import type { Provider } from "@/provider/provider"
|
||||||
|
|
||||||
export namespace MessageV2 {
|
export namespace MessageV2 {
|
||||||
@@ -843,15 +839,15 @@ export namespace MessageV2 {
|
|||||||
},
|
},
|
||||||
{ cause: e },
|
{ cause: e },
|
||||||
).toObject()
|
).toObject()
|
||||||
case (e as SystemError)?.code === "ECONNRESET":
|
case (e as any)?.code === "ECONNRESET":
|
||||||
return new MessageV2.APIError(
|
return new MessageV2.APIError(
|
||||||
{
|
{
|
||||||
message: "Connection reset by server",
|
message: "Connection reset by server",
|
||||||
isRetryable: true,
|
isRetryable: true,
|
||||||
metadata: {
|
metadata: {
|
||||||
code: (e as SystemError).code ?? "",
|
code: (e as any).code ?? "",
|
||||||
syscall: (e as SystemError).syscall ?? "",
|
syscall: (e as any).syscall ?? "",
|
||||||
message: (e as SystemError).message ?? "",
|
message: (e as any).message ?? "",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{ cause: e },
|
{ cause: e },
|
||||||
|
|||||||
@@ -29,9 +29,12 @@ import { ReadTool } from "../tool/read"
|
|||||||
import { FileTime } from "../file/time"
|
import { FileTime } from "../file/time"
|
||||||
import { Flag } from "../flag/flag"
|
import { Flag } from "../flag/flag"
|
||||||
import { ulid } from "ulid"
|
import { ulid } from "ulid"
|
||||||
|
import { Process } from "../util/process"
|
||||||
import { spawn } from "child_process"
|
import { spawn } from "child_process"
|
||||||
|
|
||||||
import { Command } from "../command"
|
import { Command } from "../command"
|
||||||
import { $, fileURLToPath, pathToFileURL } from "bun"
|
|
||||||
|
import { pathToFileURL, fileURLToPath } from "url"
|
||||||
import { ConfigMarkdown } from "../config/markdown"
|
import { ConfigMarkdown } from "../config/markdown"
|
||||||
import { SessionSummary } from "./summary"
|
import { SessionSummary } from "./summary"
|
||||||
import { NamedError } from "@opencode-ai/util/error"
|
import { NamedError } from "@opencode-ai/util/error"
|
||||||
@@ -1777,15 +1780,13 @@ NOTE: At any point in time through this workflow you should feel free to ask the
|
|||||||
template = template + "\n\n" + input.arguments
|
template = template + "\n\n" + input.arguments
|
||||||
}
|
}
|
||||||
|
|
||||||
const shell = ConfigMarkdown.shell(template)
|
const shellMatches = ConfigMarkdown.shell(template)
|
||||||
if (shell.length > 0) {
|
if (shellMatches.length > 0) {
|
||||||
|
const sh = Shell.preferred()
|
||||||
const results = await Promise.all(
|
const results = await Promise.all(
|
||||||
shell.map(async ([, cmd]) => {
|
shellMatches.map(async ([, cmd]) => {
|
||||||
try {
|
const out = await Process.text([cmd], { shell: sh, nothrow: true })
|
||||||
return await $`${{ raw: cmd }}`.quiet().nothrow().text()
|
return out.text
|
||||||
} catch (error) {
|
|
||||||
return `Error executing command: ${error instanceof Error ? error.message : String(error)}`
|
|
||||||
}
|
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
let index = 0
|
let index = 0
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
import { $ } from "bun"
|
|
||||||
import path from "path"
|
import path from "path"
|
||||||
import fs from "fs/promises"
|
import fs from "fs/promises"
|
||||||
import { Filesystem } from "../util/filesystem"
|
import { Filesystem } from "../util/filesystem"
|
||||||
@@ -9,12 +8,17 @@ import z from "zod"
|
|||||||
import { Config } from "../config/config"
|
import { Config } from "../config/config"
|
||||||
import { Instance } from "../project/instance"
|
import { Instance } from "../project/instance"
|
||||||
import { Scheduler } from "../scheduler"
|
import { Scheduler } from "../scheduler"
|
||||||
|
import { Process } from "@/util/process"
|
||||||
|
|
||||||
export namespace Snapshot {
|
export namespace Snapshot {
|
||||||
const log = Log.create({ service: "snapshot" })
|
const log = Log.create({ service: "snapshot" })
|
||||||
const hour = 60 * 60 * 1000
|
const hour = 60 * 60 * 1000
|
||||||
const prune = "7.days"
|
const prune = "7.days"
|
||||||
|
|
||||||
|
function args(git: string, cmd: string[]) {
|
||||||
|
return ["--git-dir", git, "--work-tree", Instance.worktree, ...cmd]
|
||||||
|
}
|
||||||
|
|
||||||
export function init() {
|
export function init() {
|
||||||
Scheduler.register({
|
Scheduler.register({
|
||||||
id: "snapshot.cleanup",
|
id: "snapshot.cleanup",
|
||||||
@@ -34,13 +38,13 @@ export namespace Snapshot {
|
|||||||
.then(() => true)
|
.then(() => true)
|
||||||
.catch(() => false)
|
.catch(() => false)
|
||||||
if (!exists) return
|
if (!exists) return
|
||||||
const result = await $`git --git-dir ${git} --work-tree ${Instance.worktree} gc --prune=${prune}`
|
const result = await Process.run(["git", ...args(git, ["gc", `--prune=${prune}`])], {
|
||||||
.quiet()
|
cwd: Instance.directory,
|
||||||
.cwd(Instance.directory)
|
nothrow: true,
|
||||||
.nothrow()
|
})
|
||||||
if (result.exitCode !== 0) {
|
if (result.code !== 0) {
|
||||||
log.warn("cleanup failed", {
|
log.warn("cleanup failed", {
|
||||||
exitCode: result.exitCode,
|
exitCode: result.code,
|
||||||
stderr: result.stderr.toString(),
|
stderr: result.stderr.toString(),
|
||||||
stdout: result.stdout.toString(),
|
stdout: result.stdout.toString(),
|
||||||
})
|
})
|
||||||
@@ -55,27 +59,27 @@ export namespace Snapshot {
|
|||||||
if (cfg.snapshot === false) return
|
if (cfg.snapshot === false) return
|
||||||
const git = gitdir()
|
const git = gitdir()
|
||||||
if (await fs.mkdir(git, { recursive: true })) {
|
if (await fs.mkdir(git, { recursive: true })) {
|
||||||
await $`git init`
|
await Process.run(["git", "init"], {
|
||||||
.env({
|
env: {
|
||||||
...process.env,
|
...process.env,
|
||||||
GIT_DIR: git,
|
GIT_DIR: git,
|
||||||
GIT_WORK_TREE: Instance.worktree,
|
GIT_WORK_TREE: Instance.worktree,
|
||||||
})
|
},
|
||||||
.quiet()
|
nothrow: true,
|
||||||
.nothrow()
|
})
|
||||||
|
|
||||||
// Configure git to not convert line endings on Windows
|
// Configure git to not convert line endings on Windows
|
||||||
await $`git --git-dir ${git} config core.autocrlf false`.quiet().nothrow()
|
await Process.run(["git", "--git-dir", git, "config", "core.autocrlf", "false"], { nothrow: true })
|
||||||
await $`git --git-dir ${git} config core.longpaths true`.quiet().nothrow()
|
await Process.run(["git", "--git-dir", git, "config", "core.longpaths", "true"], { nothrow: true })
|
||||||
await $`git --git-dir ${git} config core.symlinks true`.quiet().nothrow()
|
await Process.run(["git", "--git-dir", git, "config", "core.symlinks", "true"], { nothrow: true })
|
||||||
await $`git --git-dir ${git} config core.fsmonitor false`.quiet().nothrow()
|
await Process.run(["git", "--git-dir", git, "config", "core.fsmonitor", "false"], { nothrow: true })
|
||||||
log.info("initialized")
|
log.info("initialized")
|
||||||
}
|
}
|
||||||
await add(git)
|
await add(git)
|
||||||
const hash = await $`git --git-dir ${git} --work-tree ${Instance.worktree} write-tree`
|
const hash = await Process.text(["git", ...args(git, ["write-tree"])], {
|
||||||
.quiet()
|
cwd: Instance.directory,
|
||||||
.cwd(Instance.directory)
|
nothrow: true,
|
||||||
.nothrow()
|
}).then((x) => x.text)
|
||||||
.text()
|
|
||||||
log.info("tracking", { hash, cwd: Instance.directory, git })
|
log.info("tracking", { hash, cwd: Instance.directory, git })
|
||||||
return hash.trim()
|
return hash.trim()
|
||||||
}
|
}
|
||||||
@@ -89,19 +93,32 @@ export namespace Snapshot {
|
|||||||
export async function patch(hash: string): Promise<Patch> {
|
export async function patch(hash: string): Promise<Patch> {
|
||||||
const git = gitdir()
|
const git = gitdir()
|
||||||
await add(git)
|
await add(git)
|
||||||
const result =
|
const result = await Process.text(
|
||||||
await $`git -c core.autocrlf=false -c core.longpaths=true -c core.symlinks=true -c core.quotepath=false --git-dir ${git} --work-tree ${Instance.worktree} diff --no-ext-diff --name-only ${hash} -- .`
|
[
|
||||||
.quiet()
|
"git",
|
||||||
.cwd(Instance.directory)
|
"-c",
|
||||||
.nothrow()
|
"core.autocrlf=false",
|
||||||
|
"-c",
|
||||||
|
"core.longpaths=true",
|
||||||
|
"-c",
|
||||||
|
"core.symlinks=true",
|
||||||
|
"-c",
|
||||||
|
"core.quotepath=false",
|
||||||
|
...args(git, ["diff", "--no-ext-diff", "--name-only", hash, "--", "."]),
|
||||||
|
],
|
||||||
|
{
|
||||||
|
cwd: Instance.directory,
|
||||||
|
nothrow: true,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
// If git diff fails, return empty patch
|
// If git diff fails, return empty patch
|
||||||
if (result.exitCode !== 0) {
|
if (result.code !== 0) {
|
||||||
log.warn("failed to get diff", { hash, exitCode: result.exitCode })
|
log.warn("failed to get diff", { hash, exitCode: result.code })
|
||||||
return { hash, files: [] }
|
return { hash, files: [] }
|
||||||
}
|
}
|
||||||
|
|
||||||
const files = result.text()
|
const files = result.text
|
||||||
return {
|
return {
|
||||||
hash,
|
hash,
|
||||||
files: files
|
files: files
|
||||||
@@ -116,20 +133,37 @@ export namespace Snapshot {
|
|||||||
export async function restore(snapshot: string) {
|
export async function restore(snapshot: string) {
|
||||||
log.info("restore", { commit: snapshot })
|
log.info("restore", { commit: snapshot })
|
||||||
const git = gitdir()
|
const git = gitdir()
|
||||||
const result =
|
const result = await Process.run(
|
||||||
await $`git -c core.longpaths=true -c core.symlinks=true --git-dir ${git} --work-tree ${Instance.worktree} read-tree ${snapshot} && git -c core.longpaths=true -c core.symlinks=true --git-dir ${git} --work-tree ${Instance.worktree} checkout-index -a -f`
|
["git", "-c", "core.longpaths=true", "-c", "core.symlinks=true", ...args(git, ["read-tree", snapshot])],
|
||||||
.quiet()
|
{
|
||||||
.cwd(Instance.worktree)
|
cwd: Instance.worktree,
|
||||||
.nothrow()
|
nothrow: true,
|
||||||
|
},
|
||||||
if (result.exitCode !== 0) {
|
)
|
||||||
|
if (result.code === 0) {
|
||||||
|
const checkout = await Process.run(
|
||||||
|
["git", "-c", "core.longpaths=true", "-c", "core.symlinks=true", ...args(git, ["checkout-index", "-a", "-f"])],
|
||||||
|
{
|
||||||
|
cwd: Instance.worktree,
|
||||||
|
nothrow: true,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
if (checkout.code === 0) return
|
||||||
log.error("failed to restore snapshot", {
|
log.error("failed to restore snapshot", {
|
||||||
snapshot,
|
snapshot,
|
||||||
exitCode: result.exitCode,
|
exitCode: checkout.code,
|
||||||
stderr: result.stderr.toString(),
|
stderr: checkout.stderr.toString(),
|
||||||
stdout: result.stdout.toString(),
|
stdout: checkout.stdout.toString(),
|
||||||
})
|
})
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
log.error("failed to restore snapshot", {
|
||||||
|
snapshot,
|
||||||
|
exitCode: result.code,
|
||||||
|
stderr: result.stderr.toString(),
|
||||||
|
stdout: result.stdout.toString(),
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function revert(patches: Patch[]) {
|
export async function revert(patches: Patch[]) {
|
||||||
@@ -139,19 +173,37 @@ export namespace Snapshot {
|
|||||||
for (const file of item.files) {
|
for (const file of item.files) {
|
||||||
if (files.has(file)) continue
|
if (files.has(file)) continue
|
||||||
log.info("reverting", { file, hash: item.hash })
|
log.info("reverting", { file, hash: item.hash })
|
||||||
const result =
|
const result = await Process.run(
|
||||||
await $`git -c core.longpaths=true -c core.symlinks=true --git-dir ${git} --work-tree ${Instance.worktree} checkout ${item.hash} -- ${file}`
|
[
|
||||||
.quiet()
|
"git",
|
||||||
.cwd(Instance.worktree)
|
"-c",
|
||||||
.nothrow()
|
"core.longpaths=true",
|
||||||
if (result.exitCode !== 0) {
|
"-c",
|
||||||
|
"core.symlinks=true",
|
||||||
|
...args(git, ["checkout", item.hash, "--", file]),
|
||||||
|
],
|
||||||
|
{
|
||||||
|
cwd: Instance.worktree,
|
||||||
|
nothrow: true,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
if (result.code !== 0) {
|
||||||
const relativePath = path.relative(Instance.worktree, file)
|
const relativePath = path.relative(Instance.worktree, file)
|
||||||
const checkTree =
|
const checkTree = await Process.text(
|
||||||
await $`git -c core.longpaths=true -c core.symlinks=true --git-dir ${git} --work-tree ${Instance.worktree} ls-tree ${item.hash} -- ${relativePath}`
|
[
|
||||||
.quiet()
|
"git",
|
||||||
.cwd(Instance.worktree)
|
"-c",
|
||||||
.nothrow()
|
"core.longpaths=true",
|
||||||
if (checkTree.exitCode === 0 && checkTree.text().trim()) {
|
"-c",
|
||||||
|
"core.symlinks=true",
|
||||||
|
...args(git, ["ls-tree", item.hash, "--", relativePath]),
|
||||||
|
],
|
||||||
|
{
|
||||||
|
cwd: Instance.worktree,
|
||||||
|
nothrow: true,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
if (checkTree.code === 0 && checkTree.text.trim()) {
|
||||||
log.info("file existed in snapshot but checkout failed, keeping", {
|
log.info("file existed in snapshot but checkout failed, keeping", {
|
||||||
file,
|
file,
|
||||||
})
|
})
|
||||||
@@ -168,23 +220,36 @@ export namespace Snapshot {
|
|||||||
export async function diff(hash: string) {
|
export async function diff(hash: string) {
|
||||||
const git = gitdir()
|
const git = gitdir()
|
||||||
await add(git)
|
await add(git)
|
||||||
const result =
|
const result = await Process.text(
|
||||||
await $`git -c core.autocrlf=false -c core.longpaths=true -c core.symlinks=true -c core.quotepath=false --git-dir ${git} --work-tree ${Instance.worktree} diff --no-ext-diff ${hash} -- .`
|
[
|
||||||
.quiet()
|
"git",
|
||||||
.cwd(Instance.worktree)
|
"-c",
|
||||||
.nothrow()
|
"core.autocrlf=false",
|
||||||
|
"-c",
|
||||||
|
"core.longpaths=true",
|
||||||
|
"-c",
|
||||||
|
"core.symlinks=true",
|
||||||
|
"-c",
|
||||||
|
"core.quotepath=false",
|
||||||
|
...args(git, ["diff", "--no-ext-diff", hash, "--", "."]),
|
||||||
|
],
|
||||||
|
{
|
||||||
|
cwd: Instance.worktree,
|
||||||
|
nothrow: true,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
if (result.exitCode !== 0) {
|
if (result.code !== 0) {
|
||||||
log.warn("failed to get diff", {
|
log.warn("failed to get diff", {
|
||||||
hash,
|
hash,
|
||||||
exitCode: result.exitCode,
|
exitCode: result.code,
|
||||||
stderr: result.stderr.toString(),
|
stderr: result.stderr.toString(),
|
||||||
stdout: result.stdout.toString(),
|
stdout: result.stdout.toString(),
|
||||||
})
|
})
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
return result.text().trim()
|
return result.text.trim()
|
||||||
}
|
}
|
||||||
|
|
||||||
export const FileDiff = z
|
export const FileDiff = z
|
||||||
@@ -205,12 +270,24 @@ export namespace Snapshot {
|
|||||||
const result: FileDiff[] = []
|
const result: FileDiff[] = []
|
||||||
const status = new Map<string, "added" | "deleted" | "modified">()
|
const status = new Map<string, "added" | "deleted" | "modified">()
|
||||||
|
|
||||||
const statuses =
|
const statuses = await Process.text(
|
||||||
await $`git -c core.autocrlf=false -c core.longpaths=true -c core.symlinks=true -c core.quotepath=false --git-dir ${git} --work-tree ${Instance.worktree} diff --no-ext-diff --name-status --no-renames ${from} ${to} -- .`
|
[
|
||||||
.quiet()
|
"git",
|
||||||
.cwd(Instance.directory)
|
"-c",
|
||||||
.nothrow()
|
"core.autocrlf=false",
|
||||||
.text()
|
"-c",
|
||||||
|
"core.longpaths=true",
|
||||||
|
"-c",
|
||||||
|
"core.symlinks=true",
|
||||||
|
"-c",
|
||||||
|
"core.quotepath=false",
|
||||||
|
...args(git, ["diff", "--no-ext-diff", "--name-status", "--no-renames", from, to, "--", "."]),
|
||||||
|
],
|
||||||
|
{
|
||||||
|
cwd: Instance.directory,
|
||||||
|
nothrow: true,
|
||||||
|
},
|
||||||
|
).then((x) => x.text)
|
||||||
|
|
||||||
for (const line of statuses.trim().split("\n")) {
|
for (const line of statuses.trim().split("\n")) {
|
||||||
if (!line) continue
|
if (!line) continue
|
||||||
@@ -220,26 +297,57 @@ export namespace Snapshot {
|
|||||||
status.set(file, kind)
|
status.set(file, kind)
|
||||||
}
|
}
|
||||||
|
|
||||||
for await (const line of $`git -c core.autocrlf=false -c core.longpaths=true -c core.symlinks=true -c core.quotepath=false --git-dir ${git} --work-tree ${Instance.worktree} diff --no-ext-diff --no-renames --numstat ${from} ${to} -- .`
|
for (const line of await Process.lines(
|
||||||
.quiet()
|
[
|
||||||
.cwd(Instance.directory)
|
"git",
|
||||||
.nothrow()
|
"-c",
|
||||||
.lines()) {
|
"core.autocrlf=false",
|
||||||
|
"-c",
|
||||||
|
"core.longpaths=true",
|
||||||
|
"-c",
|
||||||
|
"core.symlinks=true",
|
||||||
|
"-c",
|
||||||
|
"core.quotepath=false",
|
||||||
|
...args(git, ["diff", "--no-ext-diff", "--no-renames", "--numstat", from, to, "--", "."]),
|
||||||
|
],
|
||||||
|
{
|
||||||
|
cwd: Instance.directory,
|
||||||
|
nothrow: true,
|
||||||
|
},
|
||||||
|
)) {
|
||||||
if (!line) continue
|
if (!line) continue
|
||||||
const [additions, deletions, file] = line.split("\t")
|
const [additions, deletions, file] = line.split("\t")
|
||||||
const isBinaryFile = additions === "-" && deletions === "-"
|
const isBinaryFile = additions === "-" && deletions === "-"
|
||||||
const before = isBinaryFile
|
const before = isBinaryFile
|
||||||
? ""
|
? ""
|
||||||
: await $`git -c core.autocrlf=false -c core.longpaths=true -c core.symlinks=true --git-dir ${git} --work-tree ${Instance.worktree} show ${from}:${file}`
|
: await Process.text(
|
||||||
.quiet()
|
[
|
||||||
.nothrow()
|
"git",
|
||||||
.text()
|
"-c",
|
||||||
|
"core.autocrlf=false",
|
||||||
|
"-c",
|
||||||
|
"core.longpaths=true",
|
||||||
|
"-c",
|
||||||
|
"core.symlinks=true",
|
||||||
|
...args(git, ["show", `${from}:${file}`]),
|
||||||
|
],
|
||||||
|
{ nothrow: true },
|
||||||
|
).then((x) => x.text)
|
||||||
const after = isBinaryFile
|
const after = isBinaryFile
|
||||||
? ""
|
? ""
|
||||||
: await $`git -c core.autocrlf=false -c core.longpaths=true -c core.symlinks=true --git-dir ${git} --work-tree ${Instance.worktree} show ${to}:${file}`
|
: await Process.text(
|
||||||
.quiet()
|
[
|
||||||
.nothrow()
|
"git",
|
||||||
.text()
|
"-c",
|
||||||
|
"core.autocrlf=false",
|
||||||
|
"-c",
|
||||||
|
"core.longpaths=true",
|
||||||
|
"-c",
|
||||||
|
"core.symlinks=true",
|
||||||
|
...args(git, ["show", `${to}:${file}`]),
|
||||||
|
],
|
||||||
|
{ nothrow: true },
|
||||||
|
).then((x) => x.text)
|
||||||
const added = isBinaryFile ? 0 : parseInt(additions)
|
const added = isBinaryFile ? 0 : parseInt(additions)
|
||||||
const deleted = isBinaryFile ? 0 : parseInt(deletions)
|
const deleted = isBinaryFile ? 0 : parseInt(deletions)
|
||||||
result.push({
|
result.push({
|
||||||
@@ -261,10 +369,22 @@ export namespace Snapshot {
|
|||||||
|
|
||||||
async function add(git: string) {
|
async function add(git: string) {
|
||||||
await syncExclude(git)
|
await syncExclude(git)
|
||||||
await $`git -c core.autocrlf=false -c core.longpaths=true -c core.symlinks=true --git-dir ${git} --work-tree ${Instance.worktree} add .`
|
await Process.run(
|
||||||
.quiet()
|
[
|
||||||
.cwd(Instance.directory)
|
"git",
|
||||||
.nothrow()
|
"-c",
|
||||||
|
"core.autocrlf=false",
|
||||||
|
"-c",
|
||||||
|
"core.longpaths=true",
|
||||||
|
"-c",
|
||||||
|
"core.symlinks=true",
|
||||||
|
...args(git, ["add", "."]),
|
||||||
|
],
|
||||||
|
{
|
||||||
|
cwd: Instance.directory,
|
||||||
|
nothrow: true,
|
||||||
|
},
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
async function syncExclude(git: string) {
|
async function syncExclude(git: string) {
|
||||||
@@ -281,11 +401,10 @@ export namespace Snapshot {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function excludes() {
|
async function excludes() {
|
||||||
const file = await $`git rev-parse --path-format=absolute --git-path info/exclude`
|
const file = await Process.text(["git", "rev-parse", "--path-format=absolute", "--git-path", "info/exclude"], {
|
||||||
.quiet()
|
cwd: Instance.worktree,
|
||||||
.cwd(Instance.worktree)
|
nothrow: true,
|
||||||
.nothrow()
|
}).then((x) => x.text)
|
||||||
.text()
|
|
||||||
if (!file.trim()) return
|
if (!file.trim()) return
|
||||||
const exists = await fs
|
const exists = await fs
|
||||||
.stat(file.trim())
|
.stat(file.trim())
|
||||||
|
|||||||
@@ -5,10 +5,10 @@ import { Global } from "../global"
|
|||||||
import { Filesystem } from "../util/filesystem"
|
import { Filesystem } from "../util/filesystem"
|
||||||
import { lazy } from "../util/lazy"
|
import { lazy } from "../util/lazy"
|
||||||
import { Lock } from "../util/lock"
|
import { Lock } from "../util/lock"
|
||||||
import { $ } from "bun"
|
|
||||||
import { NamedError } from "@opencode-ai/util/error"
|
import { NamedError } from "@opencode-ai/util/error"
|
||||||
import z from "zod"
|
import z from "zod"
|
||||||
import { Glob } from "../util/glob"
|
import { Glob } from "../util/glob"
|
||||||
|
import { git } from "@/util/git"
|
||||||
|
|
||||||
export namespace Storage {
|
export namespace Storage {
|
||||||
const log = Log.create({ service: "storage" })
|
const log = Log.create({ service: "storage" })
|
||||||
@@ -49,18 +49,15 @@ export namespace Storage {
|
|||||||
}
|
}
|
||||||
if (!worktree) continue
|
if (!worktree) continue
|
||||||
if (!(await Filesystem.isDir(worktree))) continue
|
if (!(await Filesystem.isDir(worktree))) continue
|
||||||
const [id] = await $`git rev-list --max-parents=0 --all`
|
const result = await git(["rev-list", "--max-parents=0", "--all"], {
|
||||||
.quiet()
|
cwd: worktree,
|
||||||
.nothrow()
|
})
|
||||||
.cwd(worktree)
|
const [id] = result
|
||||||
.text()
|
.text()
|
||||||
.then((x) =>
|
.split("\n")
|
||||||
x
|
.filter(Boolean)
|
||||||
.split("\n")
|
.map((x) => x.trim())
|
||||||
.filter(Boolean)
|
.toSorted()
|
||||||
.map((x) => x.trim())
|
|
||||||
.toSorted(),
|
|
||||||
)
|
|
||||||
if (!id) continue
|
if (!id) continue
|
||||||
projectID = id
|
projectID = id
|
||||||
|
|
||||||
|
|||||||
@@ -7,8 +7,8 @@ import { Log } from "../util/log"
|
|||||||
import { Instance } from "../project/instance"
|
import { Instance } from "../project/instance"
|
||||||
import { lazy } from "@/util/lazy"
|
import { lazy } from "@/util/lazy"
|
||||||
import { Language } from "web-tree-sitter"
|
import { Language } from "web-tree-sitter"
|
||||||
|
import fs from "fs/promises"
|
||||||
|
|
||||||
import { $ } from "bun"
|
|
||||||
import { Filesystem } from "@/util/filesystem"
|
import { Filesystem } from "@/util/filesystem"
|
||||||
import { fileURLToPath } from "url"
|
import { fileURLToPath } from "url"
|
||||||
import { Flag } from "@/flag/flag.ts"
|
import { Flag } from "@/flag/flag.ts"
|
||||||
@@ -116,12 +116,7 @@ export const BashTool = Tool.define("bash", async () => {
|
|||||||
if (["cd", "rm", "cp", "mv", "mkdir", "touch", "chmod", "chown", "cat"].includes(command[0])) {
|
if (["cd", "rm", "cp", "mv", "mkdir", "touch", "chmod", "chown", "cat"].includes(command[0])) {
|
||||||
for (const arg of command.slice(1)) {
|
for (const arg of command.slice(1)) {
|
||||||
if (arg.startsWith("-") || (command[0] === "chmod" && arg.startsWith("+"))) continue
|
if (arg.startsWith("-") || (command[0] === "chmod" && arg.startsWith("+"))) continue
|
||||||
const resolved = await $`realpath ${arg}`
|
const resolved = await fs.realpath(path.resolve(cwd, arg)).catch(() => "")
|
||||||
.cwd(cwd)
|
|
||||||
.quiet()
|
|
||||||
.nothrow()
|
|
||||||
.text()
|
|
||||||
.then((x) => x.trim())
|
|
||||||
log.info("resolved path", { arg, resolved })
|
log.info("resolved path", { arg, resolved })
|
||||||
if (resolved) {
|
if (resolved) {
|
||||||
const normalized =
|
const normalized =
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { $ } from "bun"
|
|
||||||
import path from "path"
|
import path from "path"
|
||||||
|
import { Process } from "./process"
|
||||||
|
|
||||||
export namespace Archive {
|
export namespace Archive {
|
||||||
export async function extractZip(zipPath: string, destDir: string) {
|
export async function extractZip(zipPath: string, destDir: string) {
|
||||||
@@ -8,9 +8,10 @@ export namespace Archive {
|
|||||||
const winDestDir = path.resolve(destDir)
|
const winDestDir = path.resolve(destDir)
|
||||||
// $global:ProgressPreference suppresses PowerShell's blue progress bar popup
|
// $global:ProgressPreference suppresses PowerShell's blue progress bar popup
|
||||||
const cmd = `$global:ProgressPreference = 'SilentlyContinue'; Expand-Archive -Path '${winZipPath}' -DestinationPath '${winDestDir}' -Force`
|
const cmd = `$global:ProgressPreference = 'SilentlyContinue'; Expand-Archive -Path '${winZipPath}' -DestinationPath '${winDestDir}' -Force`
|
||||||
await $`powershell -NoProfile -NonInteractive -Command ${cmd}`.quiet()
|
await Process.run(["powershell", "-NoProfile", "-NonInteractive", "-Command", cmd])
|
||||||
} else {
|
return
|
||||||
await $`unzip -o -q ${zipPath} -d ${destDir}`.quiet()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
await Process.run(["unzip", "-o", "-q", zipPath, "-d", destDir])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ export namespace Process {
|
|||||||
abort?: AbortSignal
|
abort?: AbortSignal
|
||||||
kill?: NodeJS.Signals | number
|
kill?: NodeJS.Signals | number
|
||||||
timeout?: number
|
timeout?: number
|
||||||
|
shell?: string | boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface RunOptions extends Omit<Options, "stdout" | "stderr"> {
|
export interface RunOptions extends Omit<Options, "stdout" | "stderr"> {
|
||||||
@@ -25,6 +26,10 @@ export namespace Process {
|
|||||||
stderr: Buffer
|
stderr: Buffer
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface TextResult extends Result {
|
||||||
|
text: string
|
||||||
|
}
|
||||||
|
|
||||||
export class RunFailedError extends Error {
|
export class RunFailedError extends Error {
|
||||||
readonly cmd: string[]
|
readonly cmd: string[]
|
||||||
readonly code: number
|
readonly code: number
|
||||||
@@ -55,6 +60,7 @@ export namespace Process {
|
|||||||
const proc = launch(cmd[0], cmd.slice(1), {
|
const proc = launch(cmd[0], cmd.slice(1), {
|
||||||
cwd: opts.cwd,
|
cwd: opts.cwd,
|
||||||
env: opts.env === null ? {} : opts.env ? { ...process.env, ...opts.env } : undefined,
|
env: opts.env === null ? {} : opts.env ? { ...process.env, ...opts.env } : undefined,
|
||||||
|
shell: opts.shell,
|
||||||
stdio: [opts.stdin ?? "ignore", opts.stdout ?? "ignore", opts.stderr ?? "ignore"],
|
stdio: [opts.stdin ?? "ignore", opts.stdout ?? "ignore", opts.stderr ?? "ignore"],
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -104,6 +110,7 @@ export namespace Process {
|
|||||||
const proc = spawn(cmd, {
|
const proc = spawn(cmd, {
|
||||||
cwd: opts.cwd,
|
cwd: opts.cwd,
|
||||||
env: opts.env,
|
env: opts.env,
|
||||||
|
shell: opts.shell,
|
||||||
stdin: opts.stdin,
|
stdin: opts.stdin,
|
||||||
abort: opts.abort,
|
abort: opts.abort,
|
||||||
kill: opts.kill,
|
kill: opts.kill,
|
||||||
@@ -114,13 +121,33 @@ export namespace Process {
|
|||||||
|
|
||||||
if (!proc.stdout || !proc.stderr) throw new Error("Process output not available")
|
if (!proc.stdout || !proc.stderr) throw new Error("Process output not available")
|
||||||
|
|
||||||
const [code, stdout, stderr] = await Promise.all([proc.exited, buffer(proc.stdout), buffer(proc.stderr)])
|
const out = await Promise.all([proc.exited, buffer(proc.stdout), buffer(proc.stderr)])
|
||||||
const out = {
|
.then(([code, stdout, stderr]) => ({
|
||||||
code,
|
code,
|
||||||
stdout,
|
stdout,
|
||||||
stderr,
|
stderr,
|
||||||
}
|
}))
|
||||||
|
.catch((err: unknown) => {
|
||||||
|
if (!opts.nothrow) throw err
|
||||||
|
return {
|
||||||
|
code: 1,
|
||||||
|
stdout: Buffer.alloc(0),
|
||||||
|
stderr: Buffer.from(err instanceof Error ? err.message : String(err)),
|
||||||
|
}
|
||||||
|
})
|
||||||
if (out.code === 0 || opts.nothrow) return out
|
if (out.code === 0 || opts.nothrow) return out
|
||||||
throw new RunFailedError(cmd, out.code, out.stdout, out.stderr)
|
throw new RunFailedError(cmd, out.code, out.stdout, out.stderr)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function text(cmd: string[], opts: RunOptions = {}): Promise<TextResult> {
|
||||||
|
const out = await run(cmd, opts)
|
||||||
|
return {
|
||||||
|
...out,
|
||||||
|
text: out.stdout.toString(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function lines(cmd: string[], opts: RunOptions = {}): Promise<string[]> {
|
||||||
|
return (await text(cmd, opts)).text.split(/\r?\n/).filter(Boolean)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
import { $ } from "bun"
|
|
||||||
import fs from "fs/promises"
|
import fs from "fs/promises"
|
||||||
import path from "path"
|
import path from "path"
|
||||||
import z from "zod"
|
import z from "zod"
|
||||||
@@ -11,6 +10,8 @@ import { Database, eq } from "../storage/db"
|
|||||||
import { ProjectTable } from "../project/project.sql"
|
import { ProjectTable } from "../project/project.sql"
|
||||||
import { fn } from "../util/fn"
|
import { fn } from "../util/fn"
|
||||||
import { Log } from "../util/log"
|
import { Log } from "../util/log"
|
||||||
|
import { Process } from "../util/process"
|
||||||
|
import { git } from "../util/git"
|
||||||
import { BusEvent } from "@/bus/bus-event"
|
import { BusEvent } from "@/bus/bus-event"
|
||||||
import { GlobalBus } from "@/bus/global"
|
import { GlobalBus } from "@/bus/global"
|
||||||
|
|
||||||
@@ -248,14 +249,14 @@ export namespace Worktree {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function sweep(root: string) {
|
async function sweep(root: string) {
|
||||||
const first = await $`git clean -ffdx`.quiet().nothrow().cwd(root)
|
const first = await git(["clean", "-ffdx"], { cwd: root })
|
||||||
if (first.exitCode === 0) return first
|
if (first.exitCode === 0) return first
|
||||||
|
|
||||||
const entries = failed(first)
|
const entries = failed(first)
|
||||||
if (!entries.length) return first
|
if (!entries.length) return first
|
||||||
|
|
||||||
await prune(root, entries)
|
await prune(root, entries)
|
||||||
return $`git clean -ffdx`.quiet().nothrow().cwd(root)
|
return git(["clean", "-ffdx"], { cwd: root })
|
||||||
}
|
}
|
||||||
|
|
||||||
async function canonical(input: string) {
|
async function canonical(input: string) {
|
||||||
@@ -274,7 +275,9 @@ export namespace Worktree {
|
|||||||
if (await exists(directory)) continue
|
if (await exists(directory)) continue
|
||||||
|
|
||||||
const ref = `refs/heads/${branch}`
|
const ref = `refs/heads/${branch}`
|
||||||
const branchCheck = await $`git show-ref --verify --quiet ${ref}`.quiet().nothrow().cwd(Instance.worktree)
|
const branchCheck = await git(["show-ref", "--verify", "--quiet", ref], {
|
||||||
|
cwd: Instance.worktree,
|
||||||
|
})
|
||||||
if (branchCheck.exitCode === 0) continue
|
if (branchCheck.exitCode === 0) continue
|
||||||
|
|
||||||
return Info.parse({ name, branch, directory })
|
return Info.parse({ name, branch, directory })
|
||||||
@@ -285,9 +288,9 @@ export namespace Worktree {
|
|||||||
|
|
||||||
async function runStartCommand(directory: string, cmd: string) {
|
async function runStartCommand(directory: string, cmd: string) {
|
||||||
if (process.platform === "win32") {
|
if (process.platform === "win32") {
|
||||||
return $`cmd /c ${cmd}`.nothrow().cwd(directory)
|
return Process.run(["cmd", "/c", cmd], { cwd: directory, nothrow: true })
|
||||||
}
|
}
|
||||||
return $`bash -lc ${cmd}`.nothrow().cwd(directory)
|
return Process.run(["bash", "-lc", cmd], { cwd: directory, nothrow: true })
|
||||||
}
|
}
|
||||||
|
|
||||||
type StartKind = "project" | "worktree"
|
type StartKind = "project" | "worktree"
|
||||||
@@ -297,7 +300,7 @@ export namespace Worktree {
|
|||||||
if (!text) return true
|
if (!text) return true
|
||||||
|
|
||||||
const ran = await runStartCommand(directory, text)
|
const ran = await runStartCommand(directory, text)
|
||||||
if (ran.exitCode === 0) return true
|
if (ran.code === 0) return true
|
||||||
|
|
||||||
log.error("worktree start command failed", {
|
log.error("worktree start command failed", {
|
||||||
kind,
|
kind,
|
||||||
@@ -344,10 +347,9 @@ export namespace Worktree {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export async function createFromInfo(info: Info, startCommand?: string) {
|
export async function createFromInfo(info: Info, startCommand?: string) {
|
||||||
const created = await $`git worktree add --no-checkout -b ${info.branch} ${info.directory}`
|
const created = await git(["worktree", "add", "--no-checkout", "-b", info.branch, info.directory], {
|
||||||
.quiet()
|
cwd: Instance.worktree,
|
||||||
.nothrow()
|
})
|
||||||
.cwd(Instance.worktree)
|
|
||||||
if (created.exitCode !== 0) {
|
if (created.exitCode !== 0) {
|
||||||
throw new CreateFailedError({ message: errorText(created) || "Failed to create git worktree" })
|
throw new CreateFailedError({ message: errorText(created) || "Failed to create git worktree" })
|
||||||
}
|
}
|
||||||
@@ -359,7 +361,7 @@ export namespace Worktree {
|
|||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
const start = async () => {
|
const start = async () => {
|
||||||
const populated = await $`git reset --hard`.quiet().nothrow().cwd(info.directory)
|
const populated = await git(["reset", "--hard"], { cwd: info.directory })
|
||||||
if (populated.exitCode !== 0) {
|
if (populated.exitCode !== 0) {
|
||||||
const message = errorText(populated) || "Failed to populate worktree"
|
const message = errorText(populated) || "Failed to populate worktree"
|
||||||
log.error("worktree checkout failed", { directory: info.directory, message })
|
log.error("worktree checkout failed", { directory: info.directory, message })
|
||||||
@@ -476,10 +478,10 @@ export namespace Worktree {
|
|||||||
|
|
||||||
const stop = async (target: string) => {
|
const stop = async (target: string) => {
|
||||||
if (!(await exists(target))) return
|
if (!(await exists(target))) return
|
||||||
await $`git fsmonitor--daemon stop`.quiet().nothrow().cwd(target)
|
await git(["fsmonitor--daemon", "stop"], { cwd: target })
|
||||||
}
|
}
|
||||||
|
|
||||||
const list = await $`git worktree list --porcelain`.quiet().nothrow().cwd(Instance.worktree)
|
const list = await git(["worktree", "list", "--porcelain"], { cwd: Instance.worktree })
|
||||||
if (list.exitCode !== 0) {
|
if (list.exitCode !== 0) {
|
||||||
throw new RemoveFailedError({ message: errorText(list) || "Failed to read git worktrees" })
|
throw new RemoveFailedError({ message: errorText(list) || "Failed to read git worktrees" })
|
||||||
}
|
}
|
||||||
@@ -496,9 +498,11 @@ export namespace Worktree {
|
|||||||
}
|
}
|
||||||
|
|
||||||
await stop(entry.path)
|
await stop(entry.path)
|
||||||
const removed = await $`git worktree remove --force ${entry.path}`.quiet().nothrow().cwd(Instance.worktree)
|
const removed = await git(["worktree", "remove", "--force", entry.path], {
|
||||||
|
cwd: Instance.worktree,
|
||||||
|
})
|
||||||
if (removed.exitCode !== 0) {
|
if (removed.exitCode !== 0) {
|
||||||
const next = await $`git worktree list --porcelain`.quiet().nothrow().cwd(Instance.worktree)
|
const next = await git(["worktree", "list", "--porcelain"], { cwd: Instance.worktree })
|
||||||
if (next.exitCode !== 0) {
|
if (next.exitCode !== 0) {
|
||||||
throw new RemoveFailedError({
|
throw new RemoveFailedError({
|
||||||
message: errorText(removed) || errorText(next) || "Failed to remove git worktree",
|
message: errorText(removed) || errorText(next) || "Failed to remove git worktree",
|
||||||
@@ -515,7 +519,7 @@ export namespace Worktree {
|
|||||||
|
|
||||||
const branch = entry.branch?.replace(/^refs\/heads\//, "")
|
const branch = entry.branch?.replace(/^refs\/heads\//, "")
|
||||||
if (branch) {
|
if (branch) {
|
||||||
const deleted = await $`git branch -D ${branch}`.quiet().nothrow().cwd(Instance.worktree)
|
const deleted = await git(["branch", "-D", branch], { cwd: Instance.worktree })
|
||||||
if (deleted.exitCode !== 0) {
|
if (deleted.exitCode !== 0) {
|
||||||
throw new RemoveFailedError({ message: errorText(deleted) || "Failed to delete worktree branch" })
|
throw new RemoveFailedError({ message: errorText(deleted) || "Failed to delete worktree branch" })
|
||||||
}
|
}
|
||||||
@@ -535,7 +539,7 @@ export namespace Worktree {
|
|||||||
throw new ResetFailedError({ message: "Cannot reset the primary workspace" })
|
throw new ResetFailedError({ message: "Cannot reset the primary workspace" })
|
||||||
}
|
}
|
||||||
|
|
||||||
const list = await $`git worktree list --porcelain`.quiet().nothrow().cwd(Instance.worktree)
|
const list = await git(["worktree", "list", "--porcelain"], { cwd: Instance.worktree })
|
||||||
if (list.exitCode !== 0) {
|
if (list.exitCode !== 0) {
|
||||||
throw new ResetFailedError({ message: errorText(list) || "Failed to read git worktrees" })
|
throw new ResetFailedError({ message: errorText(list) || "Failed to read git worktrees" })
|
||||||
}
|
}
|
||||||
@@ -568,7 +572,7 @@ export namespace Worktree {
|
|||||||
throw new ResetFailedError({ message: "Worktree not found" })
|
throw new ResetFailedError({ message: "Worktree not found" })
|
||||||
}
|
}
|
||||||
|
|
||||||
const remoteList = await $`git remote`.quiet().nothrow().cwd(Instance.worktree)
|
const remoteList = await git(["remote"], { cwd: Instance.worktree })
|
||||||
if (remoteList.exitCode !== 0) {
|
if (remoteList.exitCode !== 0) {
|
||||||
throw new ResetFailedError({ message: errorText(remoteList) || "Failed to list git remotes" })
|
throw new ResetFailedError({ message: errorText(remoteList) || "Failed to list git remotes" })
|
||||||
}
|
}
|
||||||
@@ -587,18 +591,19 @@ export namespace Worktree {
|
|||||||
: ""
|
: ""
|
||||||
|
|
||||||
const remoteHead = remote
|
const remoteHead = remote
|
||||||
? await $`git symbolic-ref refs/remotes/${remote}/HEAD`.quiet().nothrow().cwd(Instance.worktree)
|
? await git(["symbolic-ref", `refs/remotes/${remote}/HEAD`], { cwd: Instance.worktree })
|
||||||
: { exitCode: 1, stdout: undefined, stderr: undefined }
|
: { exitCode: 1, stdout: undefined, stderr: undefined }
|
||||||
|
|
||||||
const remoteRef = remoteHead.exitCode === 0 ? outputText(remoteHead.stdout) : ""
|
const remoteRef = remoteHead.exitCode === 0 ? outputText(remoteHead.stdout) : ""
|
||||||
const remoteTarget = remoteRef ? remoteRef.replace(/^refs\/remotes\//, "") : ""
|
const remoteTarget = remoteRef ? remoteRef.replace(/^refs\/remotes\//, "") : ""
|
||||||
const remoteBranch = remote && remoteTarget.startsWith(`${remote}/`) ? remoteTarget.slice(`${remote}/`.length) : ""
|
const remoteBranch = remote && remoteTarget.startsWith(`${remote}/`) ? remoteTarget.slice(`${remote}/`.length) : ""
|
||||||
|
|
||||||
const mainCheck = await $`git show-ref --verify --quiet refs/heads/main`.quiet().nothrow().cwd(Instance.worktree)
|
const mainCheck = await git(["show-ref", "--verify", "--quiet", "refs/heads/main"], {
|
||||||
const masterCheck = await $`git show-ref --verify --quiet refs/heads/master`
|
cwd: Instance.worktree,
|
||||||
.quiet()
|
})
|
||||||
.nothrow()
|
const masterCheck = await git(["show-ref", "--verify", "--quiet", "refs/heads/master"], {
|
||||||
.cwd(Instance.worktree)
|
cwd: Instance.worktree,
|
||||||
|
})
|
||||||
const localBranch = mainCheck.exitCode === 0 ? "main" : masterCheck.exitCode === 0 ? "master" : ""
|
const localBranch = mainCheck.exitCode === 0 ? "main" : masterCheck.exitCode === 0 ? "master" : ""
|
||||||
|
|
||||||
const target = remoteBranch ? `${remote}/${remoteBranch}` : localBranch
|
const target = remoteBranch ? `${remote}/${remoteBranch}` : localBranch
|
||||||
@@ -607,7 +612,7 @@ export namespace Worktree {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (remoteBranch) {
|
if (remoteBranch) {
|
||||||
const fetch = await $`git fetch ${remote} ${remoteBranch}`.quiet().nothrow().cwd(Instance.worktree)
|
const fetch = await git(["fetch", remote, remoteBranch], { cwd: Instance.worktree })
|
||||||
if (fetch.exitCode !== 0) {
|
if (fetch.exitCode !== 0) {
|
||||||
throw new ResetFailedError({ message: errorText(fetch) || `Failed to fetch ${target}` })
|
throw new ResetFailedError({ message: errorText(fetch) || `Failed to fetch ${target}` })
|
||||||
}
|
}
|
||||||
@@ -619,7 +624,7 @@ export namespace Worktree {
|
|||||||
|
|
||||||
const worktreePath = entry.path
|
const worktreePath = entry.path
|
||||||
|
|
||||||
const resetToTarget = await $`git reset --hard ${target}`.quiet().nothrow().cwd(worktreePath)
|
const resetToTarget = await git(["reset", "--hard", target], { cwd: worktreePath })
|
||||||
if (resetToTarget.exitCode !== 0) {
|
if (resetToTarget.exitCode !== 0) {
|
||||||
throw new ResetFailedError({ message: errorText(resetToTarget) || "Failed to reset worktree to target" })
|
throw new ResetFailedError({ message: errorText(resetToTarget) || "Failed to reset worktree to target" })
|
||||||
}
|
}
|
||||||
@@ -629,22 +634,26 @@ export namespace Worktree {
|
|||||||
throw new ResetFailedError({ message: errorText(clean) || "Failed to clean worktree" })
|
throw new ResetFailedError({ message: errorText(clean) || "Failed to clean worktree" })
|
||||||
}
|
}
|
||||||
|
|
||||||
const update = await $`git submodule update --init --recursive --force`.quiet().nothrow().cwd(worktreePath)
|
const update = await git(["submodule", "update", "--init", "--recursive", "--force"], { cwd: worktreePath })
|
||||||
if (update.exitCode !== 0) {
|
if (update.exitCode !== 0) {
|
||||||
throw new ResetFailedError({ message: errorText(update) || "Failed to update submodules" })
|
throw new ResetFailedError({ message: errorText(update) || "Failed to update submodules" })
|
||||||
}
|
}
|
||||||
|
|
||||||
const subReset = await $`git submodule foreach --recursive git reset --hard`.quiet().nothrow().cwd(worktreePath)
|
const subReset = await git(["submodule", "foreach", "--recursive", "git", "reset", "--hard"], {
|
||||||
|
cwd: worktreePath,
|
||||||
|
})
|
||||||
if (subReset.exitCode !== 0) {
|
if (subReset.exitCode !== 0) {
|
||||||
throw new ResetFailedError({ message: errorText(subReset) || "Failed to reset submodules" })
|
throw new ResetFailedError({ message: errorText(subReset) || "Failed to reset submodules" })
|
||||||
}
|
}
|
||||||
|
|
||||||
const subClean = await $`git submodule foreach --recursive git clean -fdx`.quiet().nothrow().cwd(worktreePath)
|
const subClean = await git(["submodule", "foreach", "--recursive", "git", "clean", "-fdx"], {
|
||||||
|
cwd: worktreePath,
|
||||||
|
})
|
||||||
if (subClean.exitCode !== 0) {
|
if (subClean.exitCode !== 0) {
|
||||||
throw new ResetFailedError({ message: errorText(subClean) || "Failed to clean submodules" })
|
throw new ResetFailedError({ message: errorText(subClean) || "Failed to clean submodules" })
|
||||||
}
|
}
|
||||||
|
|
||||||
const status = await $`git -c core.fsmonitor=false status --porcelain=v1`.quiet().nothrow().cwd(worktreePath)
|
const status = await git(["-c", "core.fsmonitor=false", "status", "--porcelain=v1"], { cwd: worktreePath })
|
||||||
if (status.exitCode !== 0) {
|
if (status.exitCode !== 0) {
|
||||||
throw new ResetFailedError({ message: errorText(status) || "Failed to read git status" })
|
throw new ResetFailedError({ message: errorText(status) || "Failed to read git status" })
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -198,6 +198,30 @@ test("GitLab Duo: config apiKey takes precedence over environment variable", asy
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
test("GitLab Duo: includes context-1m beta header in aiGatewayHeaders", async () => {
|
||||||
|
await using tmp = await tmpdir({
|
||||||
|
init: async (dir) => {
|
||||||
|
await Bun.write(
|
||||||
|
path.join(dir, "opencode.json"),
|
||||||
|
JSON.stringify({
|
||||||
|
$schema: "https://opencode.ai/config.json",
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
},
|
||||||
|
})
|
||||||
|
await Instance.provide({
|
||||||
|
directory: tmp.path,
|
||||||
|
init: async () => {
|
||||||
|
Env.set("GITLAB_TOKEN", "test-token")
|
||||||
|
},
|
||||||
|
fn: async () => {
|
||||||
|
const providers = await Provider.list()
|
||||||
|
expect(providers["gitlab"]).toBeDefined()
|
||||||
|
expect(providers["gitlab"].options?.aiGatewayHeaders?.["anthropic-beta"]).toContain("context-1m-2025-08-07")
|
||||||
|
},
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
test("GitLab Duo: supports feature flags configuration", async () => {
|
test("GitLab Duo: supports feature flags configuration", async () => {
|
||||||
await using tmp = await tmpdir({
|
await using tmp = await tmpdir({
|
||||||
init: async (dir) => {
|
init: async (dir) => {
|
||||||
|
|||||||
@@ -2002,6 +2002,35 @@ describe("ProviderTransform.variants", () => {
|
|||||||
const result = ProviderTransform.variants(model)
|
const result = ProviderTransform.variants(model)
|
||||||
expect(Object.keys(result)).toEqual(["low", "medium", "high", "xhigh"])
|
expect(Object.keys(result)).toEqual(["low", "medium", "high", "xhigh"])
|
||||||
})
|
})
|
||||||
|
|
||||||
|
test("gpt-5.3-codex includes xhigh", () => {
|
||||||
|
const model = createMockModel({
|
||||||
|
id: "gpt-5.3-codex",
|
||||||
|
providerID: "github-copilot",
|
||||||
|
api: {
|
||||||
|
id: "gpt-5.3-codex",
|
||||||
|
url: "https://api.githubcopilot.com",
|
||||||
|
npm: "@ai-sdk/github-copilot",
|
||||||
|
},
|
||||||
|
})
|
||||||
|
const result = ProviderTransform.variants(model)
|
||||||
|
expect(Object.keys(result)).toEqual(["low", "medium", "high", "xhigh"])
|
||||||
|
})
|
||||||
|
|
||||||
|
test("gpt-5.4 includes xhigh", () => {
|
||||||
|
const model = createMockModel({
|
||||||
|
id: "gpt-5.4",
|
||||||
|
release_date: "2026-03-05",
|
||||||
|
providerID: "github-copilot",
|
||||||
|
api: {
|
||||||
|
id: "gpt-5.4",
|
||||||
|
url: "https://api.githubcopilot.com",
|
||||||
|
npm: "@ai-sdk/github-copilot",
|
||||||
|
},
|
||||||
|
})
|
||||||
|
const result = ProviderTransform.variants(model)
|
||||||
|
expect(Object.keys(result)).toEqual(["low", "medium", "high", "xhigh"])
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
describe("@ai-sdk/cerebras", () => {
|
describe("@ai-sdk/cerebras", () => {
|
||||||
|
|||||||
@@ -0,0 +1,59 @@
|
|||||||
|
import { describe, expect, test } from "bun:test"
|
||||||
|
import path from "path"
|
||||||
|
import { Module } from "@opencode-ai/util/module"
|
||||||
|
import { Filesystem } from "../../src/util/filesystem"
|
||||||
|
import { tmpdir } from "../fixture/fixture"
|
||||||
|
|
||||||
|
describe("util.module", () => {
|
||||||
|
test("resolves package subpaths from the provided dir", async () => {
|
||||||
|
await using tmp = await tmpdir()
|
||||||
|
const root = path.join(tmp.path, "proj")
|
||||||
|
const file = path.join(root, "node_modules/typescript/lib/tsserver.js")
|
||||||
|
await Filesystem.write(file, "export {}\n")
|
||||||
|
await Filesystem.writeJson(path.join(root, "node_modules/typescript/package.json"), { name: "typescript" })
|
||||||
|
|
||||||
|
expect(Module.resolve("typescript/lib/tsserver.js", root)).toBe(file)
|
||||||
|
})
|
||||||
|
|
||||||
|
test("resolves packages through ancestor node_modules", async () => {
|
||||||
|
await using tmp = await tmpdir()
|
||||||
|
const root = path.join(tmp.path, "proj")
|
||||||
|
const cwd = path.join(root, "apps/web")
|
||||||
|
const file = path.join(root, "node_modules/eslint/lib/api.js")
|
||||||
|
await Filesystem.write(file, "export {}\n")
|
||||||
|
await Filesystem.writeJson(path.join(root, "node_modules/eslint/package.json"), {
|
||||||
|
name: "eslint",
|
||||||
|
main: "lib/api.js",
|
||||||
|
})
|
||||||
|
await Filesystem.write(path.join(cwd, ".keep"), "")
|
||||||
|
|
||||||
|
expect(Module.resolve("eslint", cwd)).toBe(file)
|
||||||
|
})
|
||||||
|
|
||||||
|
test("resolves relative to the provided dir", async () => {
|
||||||
|
await using tmp = await tmpdir()
|
||||||
|
const a = path.join(tmp.path, "a")
|
||||||
|
const b = path.join(tmp.path, "b")
|
||||||
|
const left = path.join(a, "node_modules/biome/index.js")
|
||||||
|
const right = path.join(b, "node_modules/biome/index.js")
|
||||||
|
await Filesystem.write(left, "export {}\n")
|
||||||
|
await Filesystem.write(right, "export {}\n")
|
||||||
|
await Filesystem.writeJson(path.join(a, "node_modules/biome/package.json"), {
|
||||||
|
name: "biome",
|
||||||
|
main: "index.js",
|
||||||
|
})
|
||||||
|
await Filesystem.writeJson(path.join(b, "node_modules/biome/package.json"), {
|
||||||
|
name: "biome",
|
||||||
|
main: "index.js",
|
||||||
|
})
|
||||||
|
|
||||||
|
expect(Module.resolve("biome", a)).toBe(left)
|
||||||
|
expect(Module.resolve("biome", b)).toBe(right)
|
||||||
|
expect(Module.resolve("biome", a)).not.toBe(Module.resolve("biome", b))
|
||||||
|
})
|
||||||
|
|
||||||
|
test("returns undefined when resolution fails", async () => {
|
||||||
|
await using tmp = await tmpdir()
|
||||||
|
expect(Module.resolve("missing-package", tmp.path)).toBeUndefined()
|
||||||
|
})
|
||||||
|
})
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"$schema": "https://json.schemastore.org/package.json",
|
"$schema": "https://json.schemastore.org/package.json",
|
||||||
"name": "@opencode-ai/plugin",
|
"name": "@opencode-ai/plugin",
|
||||||
"version": "1.2.23",
|
"version": "1.2.24",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
|||||||
@@ -2,8 +2,12 @@
|
|||||||
"$schema": "https://json.schemastore.org/package",
|
"$schema": "https://json.schemastore.org/package",
|
||||||
"name": "@opencode-ai/script",
|
"name": "@opencode-ai/script",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"semver": "^7.6.3"
|
||||||
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/bun": "catalog:"
|
"@types/bun": "catalog:",
|
||||||
|
"@types/semver": "^7.5.8"
|
||||||
},
|
},
|
||||||
"exports": {
|
"exports": {
|
||||||
".": "./src/index.ts"
|
".": "./src/index.ts"
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import { $, semver } from "bun"
|
import { $ } from "bun"
|
||||||
|
import semver from "semver"
|
||||||
import path from "path"
|
import path from "path"
|
||||||
|
|
||||||
const rootPkgPath = path.resolve(import.meta.dir, "../../../package.json")
|
const rootPkgPath = path.resolve(import.meta.dir, "../../../package.json")
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"$schema": "https://json.schemastore.org/package.json",
|
"$schema": "https://json.schemastore.org/package.json",
|
||||||
"name": "@opencode-ai/sdk",
|
"name": "@opencode-ai/sdk",
|
||||||
"version": "1.2.23",
|
"version": "1.2.24",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import { type Config } from "./gen/client/types.gen.js"
|
|||||||
import { OpencodeClient } from "./gen/sdk.gen.js"
|
import { OpencodeClient } from "./gen/sdk.gen.js"
|
||||||
export { type Config as OpencodeClientConfig, OpencodeClient }
|
export { type Config as OpencodeClientConfig, OpencodeClient }
|
||||||
|
|
||||||
export function createOpencodeClient(config?: Config & { directory?: string }) {
|
export function createOpencodeClient(config?: Config & { directory?: string; experimental_workspaceID?: string }) {
|
||||||
if (!config?.fetch) {
|
if (!config?.fetch) {
|
||||||
const customFetch: any = (req: any) => {
|
const customFetch: any = (req: any) => {
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
@@ -27,6 +27,13 @@ export function createOpencodeClient(config?: Config & { directory?: string }) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (config?.experimental_workspaceID) {
|
||||||
|
config.headers = {
|
||||||
|
...config.headers,
|
||||||
|
"x-opencode-workspace": config.experimental_workspaceID,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const client = createClient(config)
|
const client = createClient(config)
|
||||||
return new OpencodeClient({ client })
|
return new OpencodeClient({ client })
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@opencode-ai/slack",
|
"name": "@opencode-ai/slack",
|
||||||
"version": "1.2.23",
|
"version": "1.2.24",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@opencode-ai/ui",
|
"name": "@opencode-ai/ui",
|
||||||
"version": "1.2.23",
|
"version": "1.2.24",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"exports": {
|
"exports": {
|
||||||
|
|||||||
@@ -0,0 +1,19 @@
|
|||||||
|
import { describe, expect, test } from "bun:test"
|
||||||
|
import { scrollKey } from "./scroll-view"
|
||||||
|
|
||||||
|
describe("scrollKey", () => {
|
||||||
|
test("maps plain navigation keys", () => {
|
||||||
|
expect(scrollKey({ key: "PageDown", altKey: false, ctrlKey: false, metaKey: false, shiftKey: false })).toBe(
|
||||||
|
"page-down",
|
||||||
|
)
|
||||||
|
expect(scrollKey({ key: "ArrowUp", altKey: false, ctrlKey: false, metaKey: false, shiftKey: false })).toBe("up")
|
||||||
|
})
|
||||||
|
|
||||||
|
test("ignores modified keybinds", () => {
|
||||||
|
expect(
|
||||||
|
scrollKey({ key: "ArrowDown", altKey: false, ctrlKey: false, metaKey: true, shiftKey: false }),
|
||||||
|
).toBeUndefined()
|
||||||
|
expect(scrollKey({ key: "PageUp", altKey: false, ctrlKey: true, metaKey: false, shiftKey: false })).toBeUndefined()
|
||||||
|
expect(scrollKey({ key: "End", altKey: false, ctrlKey: false, metaKey: false, shiftKey: true })).toBeUndefined()
|
||||||
|
})
|
||||||
|
})
|
||||||
@@ -6,6 +6,25 @@ export interface ScrollViewProps extends ComponentProps<"div"> {
|
|||||||
orientation?: "vertical" | "horizontal" // currently only vertical is fully implemented for thumb
|
orientation?: "vertical" | "horizontal" // currently only vertical is fully implemented for thumb
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const scrollKey = (event: Pick<KeyboardEvent, "key" | "altKey" | "ctrlKey" | "metaKey" | "shiftKey">) => {
|
||||||
|
if (event.altKey || event.ctrlKey || event.metaKey || event.shiftKey) return
|
||||||
|
|
||||||
|
switch (event.key) {
|
||||||
|
case "PageDown":
|
||||||
|
return "page-down"
|
||||||
|
case "PageUp":
|
||||||
|
return "page-up"
|
||||||
|
case "Home":
|
||||||
|
return "home"
|
||||||
|
case "End":
|
||||||
|
return "end"
|
||||||
|
case "ArrowUp":
|
||||||
|
return "up"
|
||||||
|
case "ArrowDown":
|
||||||
|
return "down"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export function ScrollView(props: ScrollViewProps) {
|
export function ScrollView(props: ScrollViewProps) {
|
||||||
const i18n = useI18n()
|
const i18n = useI18n()
|
||||||
const merged = mergeProps({ orientation: "vertical" }, props)
|
const merged = mergeProps({ orientation: "vertical" }, props)
|
||||||
@@ -133,31 +152,34 @@ export function ScrollView(props: ScrollViewProps) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const next = scrollKey(e)
|
||||||
|
if (!next) return
|
||||||
|
|
||||||
const scrollAmount = viewportRef.clientHeight * 0.8
|
const scrollAmount = viewportRef.clientHeight * 0.8
|
||||||
const lineAmount = 40
|
const lineAmount = 40
|
||||||
|
|
||||||
switch (e.key) {
|
switch (next) {
|
||||||
case "PageDown":
|
case "page-down":
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
viewportRef.scrollBy({ top: scrollAmount, behavior: "smooth" })
|
viewportRef.scrollBy({ top: scrollAmount, behavior: "smooth" })
|
||||||
break
|
break
|
||||||
case "PageUp":
|
case "page-up":
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
viewportRef.scrollBy({ top: -scrollAmount, behavior: "smooth" })
|
viewportRef.scrollBy({ top: -scrollAmount, behavior: "smooth" })
|
||||||
break
|
break
|
||||||
case "Home":
|
case "home":
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
viewportRef.scrollTo({ top: 0, behavior: "smooth" })
|
viewportRef.scrollTo({ top: 0, behavior: "smooth" })
|
||||||
break
|
break
|
||||||
case "End":
|
case "end":
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
viewportRef.scrollTo({ top: viewportRef.scrollHeight, behavior: "smooth" })
|
viewportRef.scrollTo({ top: viewportRef.scrollHeight, behavior: "smooth" })
|
||||||
break
|
break
|
||||||
case "ArrowUp":
|
case "up":
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
viewportRef.scrollBy({ top: -lineAmount, behavior: "smooth" })
|
viewportRef.scrollBy({ top: -lineAmount, behavior: "smooth" })
|
||||||
break
|
break
|
||||||
case "ArrowDown":
|
case "down":
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
viewportRef.scrollBy({ top: lineAmount, behavior: "smooth" })
|
viewportRef.scrollBy({ top: lineAmount, behavior: "smooth" })
|
||||||
break
|
break
|
||||||
|
|||||||
@@ -41,6 +41,7 @@ export function Spinner(props: {
|
|||||||
animation: square.corner
|
animation: square.corner
|
||||||
? undefined
|
? undefined
|
||||||
: `${square.outer ? "pulse-opacity-dim" : "pulse-opacity"} ${square.duration}s ease-in-out infinite`,
|
: `${square.outer ? "pulse-opacity-dim" : "pulse-opacity"} ${square.duration}s ease-in-out infinite`,
|
||||||
|
"animation-fill-mode": square.corner ? undefined : "both",
|
||||||
"animation-delay": square.corner ? undefined : `${square.delay}s`,
|
"animation-delay": square.corner ? undefined : `${square.delay}s`,
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -26,10 +26,10 @@
|
|||||||
@keyframes pulse-opacity-dim {
|
@keyframes pulse-opacity-dim {
|
||||||
0%,
|
0%,
|
||||||
100% {
|
100% {
|
||||||
opacity: 0;
|
opacity: 0.15;
|
||||||
}
|
}
|
||||||
50% {
|
50% {
|
||||||
opacity: 0.2;
|
opacity: 0.35;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@opencode-ai/util",
|
"name": "@opencode-ai/util",
|
||||||
"version": "1.2.23",
|
"version": "1.2.24",
|
||||||
"private": true,
|
"private": true,
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
|||||||
@@ -0,0 +1,10 @@
|
|||||||
|
import { createRequire } from "node:module"
|
||||||
|
import path from "node:path"
|
||||||
|
|
||||||
|
export namespace Module {
|
||||||
|
export function resolve(id: string, dir: string) {
|
||||||
|
try {
|
||||||
|
return createRequire(path.join(dir, "package.json")).resolve(id)
|
||||||
|
} catch {}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
"name": "@opencode-ai/web",
|
"name": "@opencode-ai/web",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"version": "1.2.23",
|
"version": "1.2.24",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "astro dev",
|
"dev": "astro dev",
|
||||||
"dev:remote": "VITE_API_URL=https://api.opencode.ai astro dev",
|
"dev:remote": "VITE_API_URL=https://api.opencode.ai astro dev",
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
"name": "opencode",
|
"name": "opencode",
|
||||||
"displayName": "opencode",
|
"displayName": "opencode",
|
||||||
"description": "opencode for VS Code",
|
"description": "opencode for VS Code",
|
||||||
"version": "1.2.23",
|
"version": "1.2.24",
|
||||||
"publisher": "sst-dev",
|
"publisher": "sst-dev",
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
|
|||||||
Reference in New Issue
Block a user