fix: restore lost delegation code, switch CI to Bun, and clean up unused files (#163)
* feat: add background agents and background bash processes (#161) Add async background delegation system (delegate, delegation_read, delegation_list) for read-only research that persists to disk and notifies the session on completion. Extend bash tool with background mode for long-running processes (dev servers, watchers) with companion process_logs, process_stop, and process_list tools. Cherry-picked from a10a337 — lost during merge of cursor/agent-new-architecture-b3d5. * feat: add prompt queuing with follow-ups UI Allow users to submit messages while the agent is processing. Queued messages display in a follow-ups panel above the prompt and are processed sequentially after the current response completes. Cherry-picked from 299023b — lost during merge of cursor/agent-new-architecture-b3d5. * chore: switch CI to Bun, remove unused files and dead code - Update security workflow to use Bun instead of npm (fixes ERESOLVE peer dependency conflict) - Delete unused files: hello.py, package-lock.json, .eslintrc.js - Remove broken ESLint config and devDependencies (lint was non-functional) - Remove unused exports: MODEL_GROUPS, Skill interface, formatDuration * chore: update lockfile after removing ESLint dependencies * fix: use ref for mode color to prevent stale closure in message borders * feat: add Biome for linting and formatting, update CI workflow - Add Biome as linter and formatter with project-appropriate config - Add lint, format, format:fix, and lint:fix scripts to package.json - Rename typecheck workflow to CI, switch from npm to Bun, add format and lint steps alongside typecheck - Auto-fix formatting and import ordering across all source files * fix: improve cancellation flow and queued message editing * fix: improve cancellation flow and prompt footer context display * chore: update Bun version and refresh lockfile
This commit is contained in:
1 parent
85c2b7caf4
commit
92505acc66
22 files changed
+1334
-5751
No files matched your search
@@ -1,16 +0,0 @@
|
||||
module.exports = {
|
||||
parser: '@typescript-eslint/parser',
|
||||
plugins: ['@typescript-eslint'],
|
||||
extends: [
|
||||
'eslint:recommended',
|
||||
'@typescript-eslint/recommended',
|
||||
],
|
||||
env: {
|
||||
node: true,
|
||||
es6: true,
|
||||
},
|
||||
rules: {
|
||||
'@typescript-eslint/no-unused-vars': 'error',
|
||||
'@typescript-eslint/no-explicit-any': 'warn',
|
||||
},
|
||||
};
|
||||
@@ -13,19 +13,18 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Use Node.js
|
||||
uses: actions/setup-node@v3
|
||||
- name: Setup Bun
|
||||
uses: oven-sh/setup-bun@v2
|
||||
with:
|
||||
node-version: '18'
|
||||
cache: 'npm'
|
||||
bun-version: 1.3.11
|
||||
|
||||
- name: Install Dependencies
|
||||
run: npm ci
|
||||
run: bun install --frozen-lockfile
|
||||
|
||||
- name: Run Security Audit
|
||||
run: npm audit --audit-level=high
|
||||
run: bun pm untrusted
|
||||
|
||||
- name: Scan for Secrets
|
||||
uses: trufflesecurity/trufflehog@v3.90.1
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
name: Type Check
|
||||
name: CI
|
||||
|
||||
on:
|
||||
push:
|
||||
@@ -7,20 +7,25 @@ on:
|
||||
branches: [ main, develop ]
|
||||
|
||||
jobs:
|
||||
typecheck:
|
||||
ci:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Use Node.js
|
||||
uses: actions/setup-node@v3
|
||||
- name: Setup Bun
|
||||
uses: oven-sh/setup-bun@v2
|
||||
with:
|
||||
node-version: '18'
|
||||
cache: 'npm'
|
||||
bun-version: 1.3.11
|
||||
|
||||
- name: Install Dependencies
|
||||
run: npm ci
|
||||
run: bun install --frozen-lockfile
|
||||
|
||||
- name: Run TypeScript Type Check
|
||||
run: npm run typecheck
|
||||
- name: Format Check
|
||||
run: bun run format
|
||||
|
||||
- name: Lint
|
||||
run: bun run lint
|
||||
|
||||
- name: Type Check
|
||||
run: bun run typecheck
|
||||
+51
@@ -0,0 +1,51 @@
|
||||
{
|
||||
"$schema": "https://biomejs.dev/schemas/2.4.8/schema.json",
|
||||
"vcs": {
|
||||
"enabled": true,
|
||||
"clientKind": "git",
|
||||
"useIgnoreFile": true
|
||||
},
|
||||
"files": {
|
||||
"includes": ["**", "!!**/dist"]
|
||||
},
|
||||
"formatter": {
|
||||
"enabled": true,
|
||||
"indentStyle": "space",
|
||||
"indentWidth": 2,
|
||||
"lineWidth": 120
|
||||
},
|
||||
"linter": {
|
||||
"enabled": true,
|
||||
"rules": {
|
||||
"recommended": true,
|
||||
"suspicious": {
|
||||
"noExplicitAny": "error",
|
||||
"noArrayIndexKey": "warn"
|
||||
},
|
||||
"correctness": {
|
||||
"noUnusedFunctionParameters": "warn"
|
||||
},
|
||||
"complexity": {
|
||||
"noForEach": "off"
|
||||
},
|
||||
"style": {
|
||||
"noNonNullAssertion": "off",
|
||||
"useNodejsImportProtocol": "off"
|
||||
}
|
||||
}
|
||||
},
|
||||
"javascript": {
|
||||
"formatter": {
|
||||
"quoteStyle": "double",
|
||||
"trailingCommas": "all"
|
||||
}
|
||||
},
|
||||
"assist": {
|
||||
"enabled": true,
|
||||
"actions": {
|
||||
"source": {
|
||||
"organizeImports": "on"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -15,12 +15,10 @@
|
||||
"zod": "^4.3.6",
|
||||
},
|
||||
"devDependencies": {
|
||||
"@biomejs/biome": "^2.4.8",
|
||||
"@types/diff": "^8.0.0",
|
||||
"@types/node": "^22.0.0",
|
||||
"@types/react": "^19.1.0",
|
||||
"@typescript-eslint/eslint-plugin": "^8.37.0",
|
||||
"@typescript-eslint/parser": "^8.37.0",
|
||||
"eslint": "^9.31.0",
|
||||
"typescript": "^5.8.0",
|
||||
},
|
||||
},
|
||||
@@ -36,34 +34,26 @@
|
||||
|
||||
"@ai-sdk/xai": ["@ai-sdk/xai@3.0.67", "", { "dependencies": { "@ai-sdk/openai-compatible": "2.0.35", "@ai-sdk/provider": "3.0.8", "@ai-sdk/provider-utils": "4.0.19" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-KQQIDc91dUA5IGFMnXBuvPBeraYNTdpDC1qUS+JG8vE+/299//5sZFafI1kKYUu3f3p7LaZrKXYgZ1Ni7QIRbw=="],
|
||||
|
||||
"@biomejs/biome": ["@biomejs/biome@2.4.8", "", { "optionalDependencies": { "@biomejs/cli-darwin-arm64": "2.4.8", "@biomejs/cli-darwin-x64": "2.4.8", "@biomejs/cli-linux-arm64": "2.4.8", "@biomejs/cli-linux-arm64-musl": "2.4.8", "@biomejs/cli-linux-x64": "2.4.8", "@biomejs/cli-linux-x64-musl": "2.4.8", "@biomejs/cli-win32-arm64": "2.4.8", "@biomejs/cli-win32-x64": "2.4.8" }, "bin": { "biome": "bin/biome" } }, "sha512-ponn0oKOky1oRXBV+rlSaUlixUxf1aZvWC19Z41zBfUOUesthrQqL3OtiAlSB1EjFjyWpn98Q64DHelhA6jNlA=="],
|
||||
|
||||
"@biomejs/cli-darwin-arm64": ["@biomejs/cli-darwin-arm64@2.4.8", "", { "os": "darwin", "cpu": "arm64" }, "sha512-ARx0tECE8I7S2C2yjnWYLNbBdDoPdq3oyNLhMglmuctThwUsuzFWRKrHmIGwIRWKz0Mat9DuzLEDp52hGnrxGQ=="],
|
||||
|
||||
"@biomejs/cli-darwin-x64": ["@biomejs/cli-darwin-x64@2.4.8", "", { "os": "darwin", "cpu": "x64" }, "sha512-Jg9/PsB9vDCJlANE8uhG7qDhb5w0Ix69D7XIIc8IfZPUoiPrbLm33k2Ig3NOJ/7nb3UbesFz3D1aDKm9DvzjhQ=="],
|
||||
|
||||
"@biomejs/cli-linux-arm64": ["@biomejs/cli-linux-arm64@2.4.8", "", { "os": "linux", "cpu": "arm64" }, "sha512-5CdrsJct76XG2hpKFwXnEtlT1p+4g4yV+XvvwBpzKsTNLO9c6iLlAxwcae2BJ7ekPGWjNGw9j09T5KGPKKxQig=="],
|
||||
|
||||
"@biomejs/cli-linux-arm64-musl": ["@biomejs/cli-linux-arm64-musl@2.4.8", "", { "os": "linux", "cpu": "arm64" }, "sha512-Zo9OhBQDJ3IBGPlqHiTISloo5H0+FBIpemqIJdW/0edJ+gEcLR+MZeZozcUyz3o1nXkVA7++DdRKQT0599j9jA=="],
|
||||
|
||||
"@biomejs/cli-linux-x64": ["@biomejs/cli-linux-x64@2.4.8", "", { "os": "linux", "cpu": "x64" }, "sha512-PdKXspVEaMCQLjtZCn6vfSck/li4KX9KGwSDbZdgIqlrizJ2MnMcE3TvHa2tVfXNmbjMikzcfJpuPWH695yJrw=="],
|
||||
|
||||
"@biomejs/cli-linux-x64-musl": ["@biomejs/cli-linux-x64-musl@2.4.8", "", { "os": "linux", "cpu": "x64" }, "sha512-Gi8quv8MEuDdKaPFtS2XjEnMqODPsRg6POT6KhoP+VrkNb+T2ywunVB+TvOU0LX1jAZzfBr+3V1mIbBhzAMKvw=="],
|
||||
|
||||
"@biomejs/cli-win32-arm64": ["@biomejs/cli-win32-arm64@2.4.8", "", { "os": "win32", "cpu": "arm64" }, "sha512-LoFatS0tnHv6KkCVpIy3qZCih+MxUMvdYiPWLHRri7mhi2vyOOs8OrbZBcLTUEWCS+ktO72nZMy4F96oMhkOHQ=="],
|
||||
|
||||
"@biomejs/cli-win32-x64": ["@biomejs/cli-win32-x64@2.4.8", "", { "os": "win32", "cpu": "x64" }, "sha512-vAn7iXDoUbqFXqVocuq1sMYAd33p8+mmurqJkWl6CtIhobd/O6moe4rY5AJvzbunn/qZCdiDVcveqtkFh1e7Hg=="],
|
||||
|
||||
"@dimforge/rapier2d-simd-compat": ["@dimforge/rapier2d-simd-compat@0.17.3", "", {}, "sha512-bijvwWz6NHsNj5e5i1vtd3dU2pDhthSaTUZSh14DUGGKJfw8eMnlWZsxwHBxB/a3AXVNDjL9abuHw1k9FGR+jg=="],
|
||||
|
||||
"@eslint-community/eslint-utils": ["@eslint-community/eslint-utils@4.9.0", "", { "dependencies": { "eslint-visitor-keys": "^3.4.3" }, "peerDependencies": { "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" } }, "sha512-ayVFHdtZ+hsq1t2Dy24wCmGXGe4q9Gu3smhLYALJrr473ZH27MsnSL+LKUlimp4BWJqMDMLmPpx/Q9R3OAlL4g=="],
|
||||
|
||||
"@eslint-community/regexpp": ["@eslint-community/regexpp@4.12.1", "", {}, "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ=="],
|
||||
|
||||
"@eslint/config-array": ["@eslint/config-array@0.21.0", "", { "dependencies": { "@eslint/object-schema": "^2.1.6", "debug": "^4.3.1", "minimatch": "^3.1.2" } }, "sha512-ENIdc4iLu0d93HeYirvKmrzshzofPw6VkZRKQGe9Nv46ZnWUzcF1xV01dcvEg/1wXUR61OmmlSfyeyO7EvjLxQ=="],
|
||||
|
||||
"@eslint/config-helpers": ["@eslint/config-helpers@0.3.1", "", {}, "sha512-xR93k9WhrDYpXHORXpxVL5oHj3Era7wo6k/Wd8/IsQNnZUTzkGS29lyn3nAT05v6ltUuTFVCCYDEGfy2Or/sPA=="],
|
||||
|
||||
"@eslint/core": ["@eslint/core@0.15.2", "", { "dependencies": { "@types/json-schema": "^7.0.15" } }, "sha512-78Md3/Rrxh83gCxoUc0EiciuOHsIITzLy53m3d9UyiW8y9Dj2D29FeETqyKA+BRK76tnTp6RXWb3pCay8Oyomg=="],
|
||||
|
||||
"@eslint/eslintrc": ["@eslint/eslintrc@3.3.1", "", { "dependencies": { "ajv": "^6.12.4", "debug": "^4.3.2", "espree": "^10.0.1", "globals": "^14.0.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", "js-yaml": "^4.1.0", "minimatch": "^3.1.2", "strip-json-comments": "^3.1.1" } }, "sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ=="],
|
||||
|
||||
"@eslint/js": ["@eslint/js@9.35.0", "", {}, "sha512-30iXE9whjlILfWobBkNerJo+TXYsgVM5ERQwMcMKCHckHflCmf7wXDAHlARoWnh0s1U72WqlbeyE7iAcCzuCPw=="],
|
||||
|
||||
"@eslint/object-schema": ["@eslint/object-schema@2.1.6", "", {}, "sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA=="],
|
||||
|
||||
"@eslint/plugin-kit": ["@eslint/plugin-kit@0.3.5", "", { "dependencies": { "@eslint/core": "^0.15.2", "levn": "^0.4.1" } }, "sha512-Z5kJ+wU3oA7MMIqVR9tyZRtjYPr4OC004Q4Rw7pgOKUOKkJfZ3O24nz3WYfGRpMDNmcOi3TwQOmgm7B7Tpii0w=="],
|
||||
|
||||
"@humanfs/core": ["@humanfs/core@0.19.1", "", {}, "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA=="],
|
||||
|
||||
"@humanfs/node": ["@humanfs/node@0.16.7", "", { "dependencies": { "@humanfs/core": "^0.19.1", "@humanwhocodes/retry": "^0.4.0" } }, "sha512-/zUx+yOsIrG4Y43Eh2peDeKCxlRt/gET6aHfaKpuq267qXdYDFViVHfMaLyygZOnl0kGWxFIgsBy8QFuTLUXEQ=="],
|
||||
|
||||
"@humanwhocodes/module-importer": ["@humanwhocodes/module-importer@1.0.1", "", {}, "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA=="],
|
||||
|
||||
"@humanwhocodes/retry": ["@humanwhocodes/retry@0.4.3", "", {}, "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ=="],
|
||||
|
||||
"@jimp/core": ["@jimp/core@1.6.0", "", { "dependencies": { "@jimp/file-ops": "1.6.0", "@jimp/types": "1.6.0", "@jimp/utils": "1.6.0", "await-to-js": "^3.0.0", "exif-parser": "^0.1.12", "file-type": "^16.0.0", "mime": "3" } }, "sha512-EQQlKU3s9QfdJqiSrZWNTxBs3rKXgO2W+GxNXDtwchF3a4IqxDheFX1ti+Env9hdJXDiYLp2jTRjlxhPthsk8w=="],
|
||||
|
||||
"@jimp/diff": ["@jimp/diff@1.6.0", "", { "dependencies": { "@jimp/plugin-resize": "1.6.0", "@jimp/types": "1.6.0", "@jimp/utils": "1.6.0", "pixelmatch": "^5.3.0" } }, "sha512-+yUAQ5gvRC5D1WHYxjBHZI7JBRusGGSLf8AmPRPCenTzh4PA+wZ1xv2+cYqQwTfQHU5tXYOhA0xDytfHUf1Zyw=="],
|
||||
@@ -120,12 +110,6 @@
|
||||
|
||||
"@jimp/utils": ["@jimp/utils@1.6.0", "", { "dependencies": { "@jimp/types": "1.6.0", "tinycolor2": "^1.6.0" } }, "sha512-gqFTGEosKbOkYF/WFj26jMHOI5OH2jeP1MmC/zbK6BF6VJBf8rIC5898dPfSzZEbSA0wbbV5slbntWVc5PKLFA=="],
|
||||
|
||||
"@nodelib/fs.scandir": ["@nodelib/fs.scandir@2.1.5", "", { "dependencies": { "@nodelib/fs.stat": "2.0.5", "run-parallel": "^1.1.9" } }, "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g=="],
|
||||
|
||||
"@nodelib/fs.stat": ["@nodelib/fs.stat@2.0.5", "", {}, "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A=="],
|
||||
|
||||
"@nodelib/fs.walk": ["@nodelib/fs.walk@1.2.8", "", { "dependencies": { "@nodelib/fs.scandir": "2.1.5", "fastq": "^1.6.0" } }, "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg=="],
|
||||
|
||||
"@opentelemetry/api": ["@opentelemetry/api@1.9.0", "", {}, "sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg=="],
|
||||
|
||||
"@opentui/core": ["@opentui/core@0.1.88", "", { "dependencies": { "bun-ffi-structs": "0.1.2", "diff": "8.0.2", "jimp": "1.6.0", "marked": "17.0.1", "yoga-layout": "3.2.1" }, "optionalDependencies": { "@dimforge/rapier2d-simd-compat": "^0.17.3", "@opentui/core-darwin-arm64": "0.1.88", "@opentui/core-darwin-x64": "0.1.88", "@opentui/core-linux-arm64": "0.1.88", "@opentui/core-linux-x64": "0.1.88", "@opentui/core-win32-arm64": "0.1.88", "@opentui/core-win32-x64": "0.1.88", "bun-webgpu": "0.1.5", "planck": "^1.4.2", "three": "0.177.0" }, "peerDependencies": { "web-tree-sitter": "0.25.10" } }, "sha512-eaDVZfAzZraddOIkgWSHMVkyaY0O20foYnPWKPQx1TY4t7G1oatIoan2zkytx67epW+4BZQ9vGib+61/uNM1MA=="],
|
||||
@@ -150,66 +134,26 @@
|
||||
|
||||
"@types/diff": ["@types/diff@8.0.0", "", { "dependencies": { "diff": "*" } }, "sha512-o7jqJM04gfaYrdCecCVMbZhNdG6T1MHg/oQoRFdERLV+4d+V7FijhiEAbFu0Usww84Yijk9yH58U4Jk4HbtzZw=="],
|
||||
|
||||
"@types/estree": ["@types/estree@1.0.8", "", {}, "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w=="],
|
||||
|
||||
"@types/json-schema": ["@types/json-schema@7.0.15", "", {}, "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA=="],
|
||||
|
||||
"@types/node": ["@types/node@22.19.15", "", { "dependencies": { "undici-types": "~6.21.0" } }, "sha512-F0R/h2+dsy5wJAUe3tAU6oqa2qbWY5TpNfL/RGmo1y38hiyO1w3x2jPtt76wmuaJI4DQnOBu21cNXQ2STIUUWg=="],
|
||||
|
||||
"@types/react": ["@types/react@19.2.14", "", { "dependencies": { "csstype": "^3.2.2" } }, "sha512-ilcTH/UniCkMdtexkoCN0bI7pMcJDvmQFPvuPvmEaYA/NSfFTAgdUSLAoVjaRJm7+6PvcM+q1zYOwS4wTYMF9w=="],
|
||||
|
||||
"@typescript-eslint/eslint-plugin": ["@typescript-eslint/eslint-plugin@8.43.0", "", { "dependencies": { "@eslint-community/regexpp": "^4.10.0", "@typescript-eslint/scope-manager": "8.43.0", "@typescript-eslint/type-utils": "8.43.0", "@typescript-eslint/utils": "8.43.0", "@typescript-eslint/visitor-keys": "8.43.0", "graphemer": "^1.4.0", "ignore": "^7.0.0", "natural-compare": "^1.4.0", "ts-api-utils": "^2.1.0" }, "peerDependencies": { "@typescript-eslint/parser": "^8.43.0", "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-8tg+gt7ENL7KewsKMKDHXR1vm8tt9eMxjJBYINf6swonlWgkYn5NwyIgXpbbDxTNU5DgpDFfj95prcTq2clIQQ=="],
|
||||
|
||||
"@typescript-eslint/parser": ["@typescript-eslint/parser@8.43.0", "", { "dependencies": { "@typescript-eslint/scope-manager": "8.43.0", "@typescript-eslint/types": "8.43.0", "@typescript-eslint/typescript-estree": "8.43.0", "@typescript-eslint/visitor-keys": "8.43.0", "debug": "^4.3.4" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-B7RIQiTsCBBmY+yW4+ILd6mF5h1FUwJsVvpqkrgpszYifetQ2Ke+Z4u6aZh0CblkUGIdR59iYVyXqqZGkZ3aBw=="],
|
||||
|
||||
"@typescript-eslint/project-service": ["@typescript-eslint/project-service@8.43.0", "", { "dependencies": { "@typescript-eslint/tsconfig-utils": "^8.43.0", "@typescript-eslint/types": "^8.43.0", "debug": "^4.3.4" }, "peerDependencies": { "typescript": ">=4.8.4 <6.0.0" } }, "sha512-htB/+D/BIGoNTQYffZw4uM4NzzuolCoaA/BusuSIcC8YjmBYQioew5VUZAYdAETPjeed0hqCaW7EHg+Robq8uw=="],
|
||||
|
||||
"@typescript-eslint/scope-manager": ["@typescript-eslint/scope-manager@8.43.0", "", { "dependencies": { "@typescript-eslint/types": "8.43.0", "@typescript-eslint/visitor-keys": "8.43.0" } }, "sha512-daSWlQ87ZhsjrbMLvpuuMAt3y4ba57AuvadcR7f3nl8eS3BjRc8L9VLxFLk92RL5xdXOg6IQ+qKjjqNEimGuAg=="],
|
||||
|
||||
"@typescript-eslint/tsconfig-utils": ["@typescript-eslint/tsconfig-utils@8.43.0", "", { "peerDependencies": { "typescript": ">=4.8.4 <6.0.0" } }, "sha512-ALC2prjZcj2YqqL5X/bwWQmHA2em6/94GcbB/KKu5SX3EBDOsqztmmX1kMkvAJHzxk7TazKzJfFiEIagNV3qEA=="],
|
||||
|
||||
"@typescript-eslint/type-utils": ["@typescript-eslint/type-utils@8.43.0", "", { "dependencies": { "@typescript-eslint/types": "8.43.0", "@typescript-eslint/typescript-estree": "8.43.0", "@typescript-eslint/utils": "8.43.0", "debug": "^4.3.4", "ts-api-utils": "^2.1.0" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-qaH1uLBpBuBBuRf8c1mLJ6swOfzCXryhKND04Igr4pckzSEW9JX5Aw9AgW00kwfjWJF0kk0ps9ExKTfvXfw4Qg=="],
|
||||
|
||||
"@typescript-eslint/types": ["@typescript-eslint/types@8.43.0", "", {}, "sha512-vQ2FZaxJpydjSZJKiSW/LJsabFFvV7KgLC5DiLhkBcykhQj8iK9BOaDmQt74nnKdLvceM5xmhaTF+pLekrxEkw=="],
|
||||
|
||||
"@typescript-eslint/typescript-estree": ["@typescript-eslint/typescript-estree@8.43.0", "", { "dependencies": { "@typescript-eslint/project-service": "8.43.0", "@typescript-eslint/tsconfig-utils": "8.43.0", "@typescript-eslint/types": "8.43.0", "@typescript-eslint/visitor-keys": "8.43.0", "debug": "^4.3.4", "fast-glob": "^3.3.2", "is-glob": "^4.0.3", "minimatch": "^9.0.4", "semver": "^7.6.0", "ts-api-utils": "^2.1.0" }, "peerDependencies": { "typescript": ">=4.8.4 <6.0.0" } }, "sha512-7Vv6zlAhPb+cvEpP06WXXy/ZByph9iL6BQRBDj4kmBsW98AqEeQHlj/13X+sZOrKSo9/rNKH4Ul4f6EICREFdw=="],
|
||||
|
||||
"@typescript-eslint/utils": ["@typescript-eslint/utils@8.43.0", "", { "dependencies": { "@eslint-community/eslint-utils": "^4.7.0", "@typescript-eslint/scope-manager": "8.43.0", "@typescript-eslint/types": "8.43.0", "@typescript-eslint/typescript-estree": "8.43.0" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-S1/tEmkUeeswxd0GGcnwuVQPFWo8NzZTOMxCvw8BX7OMxnNae+i8Tm7REQen/SwUIPoPqfKn7EaZ+YLpiB3k9g=="],
|
||||
|
||||
"@typescript-eslint/visitor-keys": ["@typescript-eslint/visitor-keys@8.43.0", "", { "dependencies": { "@typescript-eslint/types": "8.43.0", "eslint-visitor-keys": "^4.2.1" } }, "sha512-T+S1KqRD4sg/bHfLwrpF/K3gQLBM1n7Rp7OjjikjTEssI2YJzQpi5WXoynOaQ93ERIuq3O8RBTOUYDKszUCEHw=="],
|
||||
|
||||
"@vercel/oidc": ["@vercel/oidc@3.1.0", "", {}, "sha512-Fw28YZpRnA3cAHHDlkt7xQHiJ0fcL+NRcIqsocZQUSmbzeIKRpwttJjik5ZGanXP+vlA4SbTg+AbA3bP363l+w=="],
|
||||
|
||||
"@webgpu/types": ["@webgpu/types@0.1.69", "", {}, "sha512-RPmm6kgRbI8e98zSD3RVACvnuktIja5+yLgDAkTmxLr90BEwdTXRQWNLF3ETTTyH/8mKhznZuN5AveXYFEsMGQ=="],
|
||||
|
||||
"abort-controller": ["abort-controller@3.0.0", "", { "dependencies": { "event-target-shim": "^5.0.0" } }, "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg=="],
|
||||
|
||||
"acorn": ["acorn@8.15.0", "", { "bin": "bin/acorn" }, "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg=="],
|
||||
|
||||
"acorn-jsx": ["acorn-jsx@5.3.2", "", { "peerDependencies": { "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ=="],
|
||||
|
||||
"ai": ["ai@6.0.116", "", { "dependencies": { "@ai-sdk/gateway": "3.0.66", "@ai-sdk/provider": "3.0.8", "@ai-sdk/provider-utils": "4.0.19", "@opentelemetry/api": "1.9.0" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-7yM+cTmyRLeNIXwt4Vj+mrrJgVQ9RMIW5WO0ydoLoYkewIvsMcvUmqS4j2RJTUXaF1HphwmSKUMQ/HypNRGOmA=="],
|
||||
|
||||
"ajv": ["ajv@6.12.6", "", { "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", "json-schema-traverse": "^0.4.1", "uri-js": "^4.2.2" } }, "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g=="],
|
||||
|
||||
"ansi-styles": ["ansi-styles@4.3.0", "", { "dependencies": { "color-convert": "^2.0.1" } }, "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="],
|
||||
|
||||
"any-base": ["any-base@1.1.0", "", {}, "sha512-uMgjozySS8adZZYePpaWs8cxB9/kdzmpX6SgJZ+wbz1K5eYk5QMYDVJaZKhxyIHUdnnJkfR7SVgStgH7LkGUyg=="],
|
||||
|
||||
"argparse": ["argparse@2.0.1", "", {}, "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="],
|
||||
|
||||
"await-to-js": ["await-to-js@3.0.0", "", {}, "sha512-zJAaP9zxTcvTHRlejau3ZOY4V7SRpiByf3/dxx2uyKxxor19tpmpV2QRsTKikckwhaPmr2dVpxxMr7jOCYVp5g=="],
|
||||
|
||||
"balanced-match": ["balanced-match@1.0.2", "", {}, "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="],
|
||||
|
||||
"base64-js": ["base64-js@1.5.1", "", {}, "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA=="],
|
||||
|
||||
"bmp-ts": ["bmp-ts@1.0.9", "", {}, "sha512-cTEHk2jLrPyi+12M3dhpEbnnPOsaZuq7C45ylbbQIiWgDFZq4UVYPEY5mlqjvsj/6gJv9qX5sa+ebDzLXT28Vw=="],
|
||||
|
||||
"brace-expansion": ["brace-expansion@1.1.12", "", { "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg=="],
|
||||
|
||||
"braces": ["braces@3.0.3", "", { "dependencies": { "fill-range": "^7.1.1" } }, "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA=="],
|
||||
|
||||
"buffer": ["buffer@6.0.3", "", { "dependencies": { "base64-js": "^1.3.1", "ieee754": "^1.2.1" } }, "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA=="],
|
||||
|
||||
"bun-ffi-structs": ["bun-ffi-structs@0.1.2", "", { "peerDependencies": { "typescript": "^5" } }, "sha512-Lh1oQAYHDcnesJauieA4UNkWGXY9hYck7OA5IaRwE3Bp6K2F2pJSNYqq+hIy7P3uOvo3km3oxS8304g5gDMl/w=="],
|
||||
@@ -224,48 +168,14 @@
|
||||
|
||||
"bun-webgpu-win32-x64": ["bun-webgpu-win32-x64@0.1.5", "", { "os": "win32", "cpu": "x64" }, "sha512-zvnUl4EAsQbKsmZVu+lEJcH8axQ7MiCfqg2OmnHd6uw1THABmHaX0GbpKiHshdgadNN2Nf+4zDyTJB5YMcAdrA=="],
|
||||
|
||||
"callsites": ["callsites@3.1.0", "", {}, "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ=="],
|
||||
|
||||
"chalk": ["chalk@4.1.2", "", { "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA=="],
|
||||
|
||||
"color-convert": ["color-convert@2.0.1", "", { "dependencies": { "color-name": "~1.1.4" } }, "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ=="],
|
||||
|
||||
"color-name": ["color-name@1.1.4", "", {}, "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="],
|
||||
|
||||
"commander": ["commander@12.1.0", "", {}, "sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA=="],
|
||||
|
||||
"concat-map": ["concat-map@0.0.1", "", {}, "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg=="],
|
||||
|
||||
"cross-spawn": ["cross-spawn@7.0.6", "", { "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", "which": "^2.0.1" } }, "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA=="],
|
||||
|
||||
"csstype": ["csstype@3.2.3", "", {}, "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ=="],
|
||||
|
||||
"debug": ["debug@4.4.1", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ=="],
|
||||
|
||||
"deep-is": ["deep-is@0.1.4", "", {}, "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ=="],
|
||||
|
||||
"diff": ["diff@8.0.3", "", {}, "sha512-qejHi7bcSD4hQAZE0tNAawRK1ZtafHDmMTMkrrIGgSLl7hTnQHmKCeB45xAcbfTqK2zowkM3j3bHt/4b/ARbYQ=="],
|
||||
|
||||
"dotenv": ["dotenv@16.6.1", "", {}, "sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow=="],
|
||||
|
||||
"escape-string-regexp": ["escape-string-regexp@4.0.0", "", {}, "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA=="],
|
||||
|
||||
"eslint": ["eslint@9.35.0", "", { "dependencies": { "@eslint-community/eslint-utils": "^4.8.0", "@eslint-community/regexpp": "^4.12.1", "@eslint/config-array": "^0.21.0", "@eslint/config-helpers": "^0.3.1", "@eslint/core": "^0.15.2", "@eslint/eslintrc": "^3.3.1", "@eslint/js": "9.35.0", "@eslint/plugin-kit": "^0.3.5", "@humanfs/node": "^0.16.6", "@humanwhocodes/module-importer": "^1.0.1", "@humanwhocodes/retry": "^0.4.2", "@types/estree": "^1.0.6", "@types/json-schema": "^7.0.15", "ajv": "^6.12.4", "chalk": "^4.0.0", "cross-spawn": "^7.0.6", "debug": "^4.3.2", "escape-string-regexp": "^4.0.0", "eslint-scope": "^8.4.0", "eslint-visitor-keys": "^4.2.1", "espree": "^10.4.0", "esquery": "^1.5.0", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", "file-entry-cache": "^8.0.0", "find-up": "^5.0.0", "glob-parent": "^6.0.2", "ignore": "^5.2.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", "json-stable-stringify-without-jsonify": "^1.0.1", "lodash.merge": "^4.6.2", "minimatch": "^3.1.2", "natural-compare": "^1.4.0", "optionator": "^0.9.3" }, "peerDependencies": { "jiti": "*" }, "optionalPeers": ["jiti"], "bin": "bin/eslint.js" }, "sha512-QePbBFMJFjgmlE+cXAlbHZbHpdFVS2E/6vzCy7aKlebddvl1vadiC4JFV5u/wqTkNUwEV8WrQi257jf5f06hrg=="],
|
||||
|
||||
"eslint-scope": ["eslint-scope@8.4.0", "", { "dependencies": { "esrecurse": "^4.3.0", "estraverse": "^5.2.0" } }, "sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg=="],
|
||||
|
||||
"eslint-visitor-keys": ["eslint-visitor-keys@4.2.1", "", {}, "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ=="],
|
||||
|
||||
"espree": ["espree@10.4.0", "", { "dependencies": { "acorn": "^8.15.0", "acorn-jsx": "^5.3.2", "eslint-visitor-keys": "^4.2.1" } }, "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ=="],
|
||||
|
||||
"esquery": ["esquery@1.6.0", "", { "dependencies": { "estraverse": "^5.1.0" } }, "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg=="],
|
||||
|
||||
"esrecurse": ["esrecurse@4.3.0", "", { "dependencies": { "estraverse": "^5.2.0" } }, "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag=="],
|
||||
|
||||
"estraverse": ["estraverse@5.3.0", "", {}, "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA=="],
|
||||
|
||||
"esutils": ["esutils@2.0.3", "", {}, "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g=="],
|
||||
|
||||
"event-target-shim": ["event-target-shim@5.0.1", "", {}, "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ=="],
|
||||
|
||||
"events": ["events@3.3.0", "", {}, "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q=="],
|
||||
@@ -274,132 +184,44 @@
|
||||
|
||||
"exif-parser": ["exif-parser@0.1.12", "", {}, "sha512-c2bQfLNbMzLPmzQuOr8fy0csy84WmwnER81W88DzTp9CYNPJ6yzOj2EZAh9pywYpqHnshVLHQJ8WzldAyfY+Iw=="],
|
||||
|
||||
"fast-deep-equal": ["fast-deep-equal@3.1.3", "", {}, "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="],
|
||||
|
||||
"fast-glob": ["fast-glob@3.3.3", "", { "dependencies": { "@nodelib/fs.stat": "^2.0.2", "@nodelib/fs.walk": "^1.2.3", "glob-parent": "^5.1.2", "merge2": "^1.3.0", "micromatch": "^4.0.8" } }, "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg=="],
|
||||
|
||||
"fast-json-stable-stringify": ["fast-json-stable-stringify@2.1.0", "", {}, "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw=="],
|
||||
|
||||
"fast-levenshtein": ["fast-levenshtein@2.0.6", "", {}, "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw=="],
|
||||
|
||||
"fastq": ["fastq@1.19.1", "", { "dependencies": { "reusify": "^1.0.4" } }, "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ=="],
|
||||
|
||||
"file-entry-cache": ["file-entry-cache@8.0.0", "", { "dependencies": { "flat-cache": "^4.0.0" } }, "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ=="],
|
||||
|
||||
"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=="],
|
||||
|
||||
"fill-range": ["fill-range@7.1.1", "", { "dependencies": { "to-regex-range": "^5.0.1" } }, "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg=="],
|
||||
|
||||
"find-up": ["find-up@5.0.0", "", { "dependencies": { "locate-path": "^6.0.0", "path-exists": "^4.0.0" } }, "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng=="],
|
||||
|
||||
"flat-cache": ["flat-cache@4.0.1", "", { "dependencies": { "flatted": "^3.2.9", "keyv": "^4.5.4" } }, "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw=="],
|
||||
|
||||
"flatted": ["flatted@3.3.3", "", {}, "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg=="],
|
||||
|
||||
"gifwrap": ["gifwrap@0.10.1", "", { "dependencies": { "image-q": "^4.0.0", "omggif": "^1.0.10" } }, "sha512-2760b1vpJHNmLzZ/ubTtNnEx5WApN/PYWJvXvgS+tL1egTTthayFYIQQNi136FLEDcN/IyEY2EcGpIITD6eYUw=="],
|
||||
|
||||
"glob-parent": ["glob-parent@6.0.2", "", { "dependencies": { "is-glob": "^4.0.3" } }, "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A=="],
|
||||
|
||||
"globals": ["globals@14.0.0", "", {}, "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ=="],
|
||||
|
||||
"graphemer": ["graphemer@1.4.0", "", {}, "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag=="],
|
||||
|
||||
"has-flag": ["has-flag@4.0.0", "", {}, "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ=="],
|
||||
|
||||
"ieee754": ["ieee754@1.2.1", "", {}, "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA=="],
|
||||
|
||||
"ignore": ["ignore@7.0.5", "", {}, "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg=="],
|
||||
|
||||
"image-q": ["image-q@4.0.0", "", { "dependencies": { "@types/node": "16.9.1" } }, "sha512-PfJGVgIfKQJuq3s0tTDOKtztksibuUEbJQIYT3by6wctQo+Rdlh7ef4evJ5NCdxY4CfMbvFkocEwbl4BF8RlJw=="],
|
||||
|
||||
"import-fresh": ["import-fresh@3.3.1", "", { "dependencies": { "parent-module": "^1.0.0", "resolve-from": "^4.0.0" } }, "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ=="],
|
||||
|
||||
"imurmurhash": ["imurmurhash@0.1.4", "", {}, "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA=="],
|
||||
|
||||
"is-extglob": ["is-extglob@2.1.1", "", {}, "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ=="],
|
||||
|
||||
"is-glob": ["is-glob@4.0.3", "", { "dependencies": { "is-extglob": "^2.1.1" } }, "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg=="],
|
||||
|
||||
"is-number": ["is-number@7.0.0", "", {}, "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng=="],
|
||||
|
||||
"isexe": ["isexe@2.0.0", "", {}, "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw=="],
|
||||
|
||||
"jimp": ["jimp@1.6.0", "", { "dependencies": { "@jimp/core": "1.6.0", "@jimp/diff": "1.6.0", "@jimp/js-bmp": "1.6.0", "@jimp/js-gif": "1.6.0", "@jimp/js-jpeg": "1.6.0", "@jimp/js-png": "1.6.0", "@jimp/js-tiff": "1.6.0", "@jimp/plugin-blit": "1.6.0", "@jimp/plugin-blur": "1.6.0", "@jimp/plugin-circle": "1.6.0", "@jimp/plugin-color": "1.6.0", "@jimp/plugin-contain": "1.6.0", "@jimp/plugin-cover": "1.6.0", "@jimp/plugin-crop": "1.6.0", "@jimp/plugin-displace": "1.6.0", "@jimp/plugin-dither": "1.6.0", "@jimp/plugin-fisheye": "1.6.0", "@jimp/plugin-flip": "1.6.0", "@jimp/plugin-hash": "1.6.0", "@jimp/plugin-mask": "1.6.0", "@jimp/plugin-print": "1.6.0", "@jimp/plugin-quantize": "1.6.0", "@jimp/plugin-resize": "1.6.0", "@jimp/plugin-rotate": "1.6.0", "@jimp/plugin-threshold": "1.6.0", "@jimp/types": "1.6.0", "@jimp/utils": "1.6.0" } }, "sha512-YcwCHw1kiqEeI5xRpDlPPBGL2EOpBKLwO4yIBJcXWHPj5PnA5urGq0jbyhM5KoNpypQ6VboSoxc9D8HyfvngSg=="],
|
||||
|
||||
"jpeg-js": ["jpeg-js@0.4.4", "", {}, "sha512-WZzeDOEtTOBK4Mdsar0IqEU5sMr3vSV2RqkAIzUEV2BHnUfKGyswWFPFwK5EeDo93K3FohSHbLAjj0s1Wzd+dg=="],
|
||||
|
||||
"js-yaml": ["js-yaml@4.1.0", "", { "dependencies": { "argparse": "^2.0.1" }, "bin": "bin/js-yaml.js" }, "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA=="],
|
||||
|
||||
"json-buffer": ["json-buffer@3.0.1", "", {}, "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ=="],
|
||||
|
||||
"json-schema": ["json-schema@0.4.0", "", {}, "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA=="],
|
||||
|
||||
"json-schema-traverse": ["json-schema-traverse@0.4.1", "", {}, "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg=="],
|
||||
|
||||
"json-stable-stringify-without-jsonify": ["json-stable-stringify-without-jsonify@1.0.1", "", {}, "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw=="],
|
||||
|
||||
"keyv": ["keyv@4.5.4", "", { "dependencies": { "json-buffer": "3.0.1" } }, "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw=="],
|
||||
|
||||
"levn": ["levn@0.4.1", "", { "dependencies": { "prelude-ls": "^1.2.1", "type-check": "~0.4.0" } }, "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ=="],
|
||||
|
||||
"locate-path": ["locate-path@6.0.0", "", { "dependencies": { "p-locate": "^5.0.0" } }, "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw=="],
|
||||
|
||||
"lodash.merge": ["lodash.merge@4.6.2", "", {}, "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ=="],
|
||||
|
||||
"marked": ["marked@17.0.1", "", { "bin": { "marked": "bin/marked.js" } }, "sha512-boeBdiS0ghpWcSwoNm/jJBwdpFaMnZWRzjA6SkUMYb40SVaN1x7mmfGKp0jvexGcx+7y2La5zRZsYFZI6Qpypg=="],
|
||||
|
||||
"merge2": ["merge2@1.4.1", "", {}, "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg=="],
|
||||
|
||||
"micromatch": ["micromatch@4.0.8", "", { "dependencies": { "braces": "^3.0.3", "picomatch": "^2.3.1" } }, "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA=="],
|
||||
|
||||
"mime": ["mime@3.0.0", "", { "bin": { "mime": "cli.js" } }, "sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A=="],
|
||||
|
||||
"minimatch": ["minimatch@3.1.2", "", { "dependencies": { "brace-expansion": "^1.1.7" } }, "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw=="],
|
||||
|
||||
"ms": ["ms@2.1.3", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="],
|
||||
|
||||
"natural-compare": ["natural-compare@1.4.0", "", {}, "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw=="],
|
||||
|
||||
"omggif": ["omggif@1.0.10", "", {}, "sha512-LMJTtvgc/nugXj0Vcrrs68Mn2D1r0zf630VNtqtpI1FEO7e+O9FP4gqs9AcnBaSEeoHIPm28u6qgPR0oyEpGSw=="],
|
||||
|
||||
"optionator": ["optionator@0.9.4", "", { "dependencies": { "deep-is": "^0.1.3", "fast-levenshtein": "^2.0.6", "levn": "^0.4.1", "prelude-ls": "^1.2.1", "type-check": "^0.4.0", "word-wrap": "^1.2.5" } }, "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g=="],
|
||||
|
||||
"p-limit": ["p-limit@3.1.0", "", { "dependencies": { "yocto-queue": "^0.1.0" } }, "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ=="],
|
||||
|
||||
"p-locate": ["p-locate@5.0.0", "", { "dependencies": { "p-limit": "^3.0.2" } }, "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw=="],
|
||||
|
||||
"pako": ["pako@1.0.11", "", {}, "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw=="],
|
||||
|
||||
"parent-module": ["parent-module@1.0.1", "", { "dependencies": { "callsites": "^3.0.0" } }, "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g=="],
|
||||
|
||||
"parse-bmfont-ascii": ["parse-bmfont-ascii@1.0.6", "", {}, "sha512-U4RrVsUFCleIOBsIGYOMKjn9PavsGOXxbvYGtMOEfnId0SVNsgehXh1DxUdVPLoxd5mvcEtvmKs2Mmf0Mpa1ZA=="],
|
||||
|
||||
"parse-bmfont-binary": ["parse-bmfont-binary@1.0.6", "", {}, "sha512-GxmsRea0wdGdYthjuUeWTMWPqm2+FAd4GI8vCvhgJsFnoGhTrLhXDDupwTo7rXVAgaLIGoVHDZS9p/5XbSqeWA=="],
|
||||
|
||||
"parse-bmfont-xml": ["parse-bmfont-xml@1.1.6", "", { "dependencies": { "xml-parse-from-string": "^1.0.0", "xml2js": "^0.5.0" } }, "sha512-0cEliVMZEhrFDwMh4SxIyVJpqYoOWDJ9P895tFuS+XuNzI5UBmBk5U5O4KuJdTnZpSBI4LFA2+ZiJaiwfSwlMA=="],
|
||||
|
||||
"path-exists": ["path-exists@4.0.0", "", {}, "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w=="],
|
||||
|
||||
"path-key": ["path-key@3.1.1", "", {}, "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q=="],
|
||||
|
||||
"peek-readable": ["peek-readable@4.1.0", "", {}, "sha512-ZI3LnwUv5nOGbQzD9c2iDG6toheuXSZP5esSHBjopsXH4dg19soufvpUGA3uohi5anFtGb2lhAVdHzH6R/Evvg=="],
|
||||
|
||||
"picomatch": ["picomatch@2.3.1", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="],
|
||||
|
||||
"pixelmatch": ["pixelmatch@5.3.0", "", { "dependencies": { "pngjs": "^6.0.0" }, "bin": { "pixelmatch": "bin/pixelmatch" } }, "sha512-o8mkY4E/+LNUf6LzX96ht6k6CEDi65k9G2rjMtBe9Oo+VPKSvl+0GKHuH/AlG+GA5LPG/i5hrekkxUc3s2HU+Q=="],
|
||||
|
||||
"planck": ["planck@1.4.3", "", { "peerDependencies": { "stage-js": "^1.0.0-alpha.12" } }, "sha512-B+lHKhRSeg7vZOfEyEzyQVu7nx8JHcX3QgnAcHXrPW0j04XYKX5eXSiUrxH2Z5QR8OoqvjD6zKIaPMdMYAd0uA=="],
|
||||
|
||||
"pngjs": ["pngjs@7.0.0", "", {}, "sha512-LKWqWJRhstyYo9pGvgor/ivk2w94eSjE3RGVuzLGlr3NmD8bf7RcYGze1mNdEHRP6TRP6rMuDHk5t44hnTRyow=="],
|
||||
|
||||
"prelude-ls": ["prelude-ls@1.2.1", "", {}, "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g=="],
|
||||
|
||||
"process": ["process@0.11.10", "", {}, "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A=="],
|
||||
|
||||
"punycode": ["punycode@2.3.1", "", {}, "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg=="],
|
||||
|
||||
"queue-microtask": ["queue-microtask@1.2.3", "", {}, "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A=="],
|
||||
|
||||
"react": ["react@19.2.4", "", {}, "sha512-9nfp2hYpCwOjAN+8TZFGhtWEwgvWHXqESH8qT89AT/lWklpLON22Lc8pEtnpsZz7VmawabSU0gCjnj8aC0euHQ=="],
|
||||
|
||||
"react-devtools-core": ["react-devtools-core@7.0.1", "", { "dependencies": { "shell-quote": "^1.6.1", "ws": "^7" } }, "sha512-C3yNvRHaizlpiASzy7b9vbnBGLrhvdhl1CbdU6EnZgxPNbai60szdLtl+VL76UNOt5bOoVTOz5rNWZxgGt+Gsw=="],
|
||||
@@ -410,24 +232,12 @@
|
||||
|
||||
"readable-web-to-node-stream": ["readable-web-to-node-stream@3.0.4", "", { "dependencies": { "readable-stream": "^4.7.0" } }, "sha512-9nX56alTf5bwXQ3ZDipHJhusu9NTQJ/CVPtb/XHAJCXihZeitfJvIRS4GqQ/mfIoOE3IelHMrpayVrosdHBuLw=="],
|
||||
|
||||
"resolve-from": ["resolve-from@4.0.0", "", {}, "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g=="],
|
||||
|
||||
"reusify": ["reusify@1.1.0", "", {}, "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw=="],
|
||||
|
||||
"run-parallel": ["run-parallel@1.2.0", "", { "dependencies": { "queue-microtask": "^1.2.2" } }, "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA=="],
|
||||
|
||||
"safe-buffer": ["safe-buffer@5.2.1", "", {}, "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ=="],
|
||||
|
||||
"sax": ["sax@1.6.0", "", {}, "sha512-6R3J5M4AcbtLUdZmRv2SygeVaM7IhrLXu9BmnOGmmACak8fiUtOsYNWUS4uK7upbmHIBbLBeFeI//477BKLBzA=="],
|
||||
|
||||
"scheduler": ["scheduler@0.26.0", "", {}, "sha512-NlHwttCI/l5gCPR3D1nNXtWABUmBwvZpEQiD4IXSbIDq8BzLIK/7Ir5gTFSGZDUu37K5cMNp0hFtzO38sC7gWA=="],
|
||||
|
||||
"semver": ["semver@7.7.2", "", { "bin": "bin/semver.js" }, "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA=="],
|
||||
|
||||
"shebang-command": ["shebang-command@2.0.0", "", { "dependencies": { "shebang-regex": "^3.0.0" } }, "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA=="],
|
||||
|
||||
"shebang-regex": ["shebang-regex@3.0.0", "", {}, "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A=="],
|
||||
|
||||
"shell-quote": ["shell-quote@1.8.3", "", {}, "sha512-ObmnIF4hXNg1BqhnHmgbDETF8dLPCggZWBjkQfhZpbszZnYur5DUljTcCHii5LC3J5E0yeO/1LIMyH+UvHQgyw=="],
|
||||
|
||||
"simple-xml-to-json": ["simple-xml-to-json@1.2.4", "", {}, "sha512-3MY16e0ocMHL7N1ufpdObURGyX+lCo0T/A+y6VCwosLdH1HSda4QZl1Sdt/O+2qWp48WFi26XEp5rF0LoaL0Dg=="],
|
||||
@@ -436,38 +246,22 @@
|
||||
|
||||
"string_decoder": ["string_decoder@1.3.0", "", { "dependencies": { "safe-buffer": "~5.2.0" } }, "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA=="],
|
||||
|
||||
"strip-json-comments": ["strip-json-comments@3.1.1", "", {}, "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig=="],
|
||||
|
||||
"strtok3": ["strtok3@6.3.0", "", { "dependencies": { "@tokenizer/token": "^0.3.0", "peek-readable": "^4.1.0" } }, "sha512-fZtbhtvI9I48xDSywd/somNqgUHl2L2cstmXCCif0itOf96jeW18MBSyrLuNicYQVkvpOxkZtkzujiTJ9LW5Jw=="],
|
||||
|
||||
"supports-color": ["supports-color@7.2.0", "", { "dependencies": { "has-flag": "^4.0.0" } }, "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw=="],
|
||||
|
||||
"three": ["three@0.177.0", "", {}, "sha512-EiXv5/qWAaGI+Vz2A+JfavwYCMdGjxVsrn3oBwllUoqYeaBO75J63ZfyaQKoiLrqNHoTlUc6PFgMXnS0kI45zg=="],
|
||||
|
||||
"tinycolor2": ["tinycolor2@1.6.0", "", {}, "sha512-XPaBkWQJdsf3pLKJV9p4qN/S+fm2Oj8AIPo1BTUhg5oxkvm9+SVEGFdhyOz7tTdUTfvxMiAs4sp6/eZO2Ew+pw=="],
|
||||
|
||||
"to-regex-range": ["to-regex-range@5.0.1", "", { "dependencies": { "is-number": "^7.0.0" } }, "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ=="],
|
||||
|
||||
"token-types": ["token-types@4.2.1", "", { "dependencies": { "@tokenizer/token": "^0.3.0", "ieee754": "^1.2.1" } }, "sha512-6udB24Q737UD/SDsKAHI9FCRP7Bqc9D/MQUV02ORQg5iskjtLJlZJNdN4kKtcdtwCeWIwIHDGaUsTsCCAa8sFQ=="],
|
||||
|
||||
"ts-api-utils": ["ts-api-utils@2.1.0", "", { "peerDependencies": { "typescript": ">=4.8.4" } }, "sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ=="],
|
||||
|
||||
"type-check": ["type-check@0.4.0", "", { "dependencies": { "prelude-ls": "^1.2.1" } }, "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew=="],
|
||||
|
||||
"typescript": ["typescript@5.9.2", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-CWBzXQrc/qOkhidw1OzBTQuYRbfyxDXJMVJ1XNwUHGROVmuaeiEm3OslpZ1RV96d7SKKjZKrSJu3+t/xlw3R9A=="],
|
||||
"typescript": ["typescript@5.9.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw=="],
|
||||
|
||||
"undici-types": ["undici-types@6.21.0", "", {}, "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ=="],
|
||||
|
||||
"uri-js": ["uri-js@4.4.1", "", { "dependencies": { "punycode": "^2.1.0" } }, "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg=="],
|
||||
|
||||
"utif2": ["utif2@4.1.0", "", { "dependencies": { "pako": "^1.0.11" } }, "sha512-+oknB9FHrJ7oW7A2WZYajOcv4FcDR4CfoGB0dPNfxbi4GO05RRnFmt5oa23+9w32EanrYcSJWspUiJkLMs+37w=="],
|
||||
|
||||
"web-tree-sitter": ["web-tree-sitter@0.25.10", "", { "peerDependencies": { "@types/emscripten": "^1.40.0" }, "optionalPeers": ["@types/emscripten"] }, "sha512-Y09sF44/13XvgVKgO2cNDw5rGk6s26MgoZPXLESvMXeefBf7i6/73eFurre0IsTW6E14Y0ArIzhUMmjoc7xyzA=="],
|
||||
|
||||
"which": ["which@2.0.2", "", { "dependencies": { "isexe": "^2.0.0" }, "bin": { "node-which": "bin/node-which" } }, "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA=="],
|
||||
|
||||
"word-wrap": ["word-wrap@1.2.5", "", {}, "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA=="],
|
||||
|
||||
"ws": ["ws@8.18.3", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": ">=5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg=="],
|
||||
|
||||
"xml-parse-from-string": ["xml-parse-from-string@1.0.1", "", {}, "sha512-ErcKwJTF54uRzzNMXq2X5sMIy88zJvfN2DmdoQvy7PAFJ+tPRU6ydWuOKNMyfmOjdyBQTFREi60s0Y0SyI0G0g=="],
|
||||
@@ -476,16 +270,10 @@
|
||||
|
||||
"xmlbuilder": ["xmlbuilder@11.0.1", "", {}, "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA=="],
|
||||
|
||||
"yocto-queue": ["yocto-queue@0.1.0", "", {}, "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q=="],
|
||||
|
||||
"yoga-layout": ["yoga-layout@3.2.1", "", {}, "sha512-0LPOt3AxKqMdFBZA3HBAt/t/8vIKq7VaQYbuA8WxCgung+p9TVyKRYdpvCb80HcdTN2NkbIKbhNwKUfm3tQywQ=="],
|
||||
|
||||
"zod": ["zod@4.3.6", "", {}, "sha512-rftlrkhHZOcjDwkGlnUtZZkvaPHCsDATp4pGpuOOMDaTdDDXF91wuVDJoWoPsKX/3YPQ5fHuF3STjcYyKr+Qhg=="],
|
||||
|
||||
"@eslint-community/eslint-utils/eslint-visitor-keys": ["eslint-visitor-keys@3.4.3", "", {}, "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag=="],
|
||||
|
||||
"@eslint/eslintrc/ignore": ["ignore@5.3.2", "", {}, "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g=="],
|
||||
|
||||
"@jimp/plugin-blit/zod": ["zod@3.25.76", "", {}, "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ=="],
|
||||
|
||||
"@jimp/plugin-circle/zod": ["zod@3.25.76", "", {}, "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ=="],
|
||||
@@ -520,18 +308,10 @@
|
||||
|
||||
"@opentui/core/diff": ["diff@8.0.2", "", {}, "sha512-sSuxWU5j5SR9QQji/o2qMvqRNYRDOcBTgsJ/DeCf4iSN4gW+gNMXM7wFIP+fdXZxoNiAnHUTGjCr+TSWXdRDKg=="],
|
||||
|
||||
"@typescript-eslint/typescript-estree/minimatch": ["minimatch@9.0.5", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow=="],
|
||||
|
||||
"eslint/ignore": ["ignore@5.3.2", "", {}, "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g=="],
|
||||
|
||||
"fast-glob/glob-parent": ["glob-parent@5.1.2", "", { "dependencies": { "is-glob": "^4.0.1" } }, "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow=="],
|
||||
|
||||
"image-q/@types/node": ["@types/node@16.9.1", "", {}, "sha512-QpLcX9ZSsq3YYUUnD3nFDY8H7wctAhQj/TFKL8Ya8v5fMm3CFXxo8zStsLAl780ltoYoo1WvKUVGBQK+1ifr7g=="],
|
||||
|
||||
"pixelmatch/pngjs": ["pngjs@6.0.0", "", {}, "sha512-TRzzuFRRmEoSW/p1KVAmiOgPco2Irlah+bGFCeNfJXxxYGwSw7YwAOAcd7X28K/m5bjBWKsC29KyoMfHbypayg=="],
|
||||
|
||||
"react-devtools-core/ws": ["ws@7.5.10", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": "^5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ=="],
|
||||
|
||||
"@typescript-eslint/typescript-estree/minimatch/brace-expansion": ["brace-expansion@2.0.2", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ=="],
|
||||
}
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
def hello_world():
|
||||
print("Hello, World!")
|
||||
|
||||
if __name__ == "__main__":
|
||||
hello_world()
|
||||
Generated
-4787
File diff suppressed because it is too large.
Load diff
+12
-11
@@ -17,8 +17,11 @@
|
||||
"dev": "bun run src/index.ts",
|
||||
"build": "tsc",
|
||||
"start": "bun run dist/index.js",
|
||||
"lint": "eslint . --ext .js,.jsx,.ts,.tsx",
|
||||
"typecheck": "tsc --noEmit"
|
||||
"typecheck": "tsc --noEmit",
|
||||
"lint": "biome check src/",
|
||||
"format": "biome format src/",
|
||||
"format:fix": "biome format --write src/",
|
||||
"lint:fix": "biome check --fix src/"
|
||||
},
|
||||
"keywords": [
|
||||
"cli",
|
||||
@@ -36,20 +39,18 @@
|
||||
"@opentui/core": "^0.1.88",
|
||||
"@opentui/react": "^0.1.88",
|
||||
"ai": "^6.0.116",
|
||||
"commander": "^12.0.0",
|
||||
"commander": "^12.1.0",
|
||||
"diff": "^8.0.3",
|
||||
"dotenv": "^16.4.0",
|
||||
"react": "^19.1.0",
|
||||
"dotenv": "^16.6.1",
|
||||
"react": "^19.2.4",
|
||||
"zod": "^4.3.6"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@biomejs/biome": "^2.4.8",
|
||||
"@types/diff": "^8.0.0",
|
||||
"@types/node": "^22.0.0",
|
||||
"@types/react": "^19.1.0",
|
||||
"@typescript-eslint/eslint-plugin": "^8.37.0",
|
||||
"@typescript-eslint/parser": "^8.37.0",
|
||||
"eslint": "^9.31.0",
|
||||
"typescript": "^5.8.0"
|
||||
"@types/node": "^22.19.15",
|
||||
"@types/react": "^19.2.14",
|
||||
"typescript": "^5.9.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18.0.0"
|
||||
|
||||
+120
-23
@@ -1,9 +1,7 @@
|
||||
import { streamText, stepCountIs, type ModelMessage } from "ai";
|
||||
import { DelegationManager } from "./delegations.js";
|
||||
import { type ModelMessage, stepCountIs, streamText } from "ai";
|
||||
import { createProvider, generateTitle as genTitle, type XaiProvider } from "../grok/client.js";
|
||||
import { createTools } from "../grok/tools.js";
|
||||
import { BashTool } from "../tools/bash.js";
|
||||
import { loadCustomInstructions } from "../utils/instructions.js";
|
||||
import type {
|
||||
AgentMode,
|
||||
Plan,
|
||||
@@ -13,6 +11,8 @@ import type {
|
||||
ToolCall,
|
||||
ToolResult,
|
||||
} from "../types/index.js";
|
||||
import { loadCustomInstructions } from "../utils/instructions.js";
|
||||
import { DelegationManager } from "./delegations.js";
|
||||
|
||||
const MAX_TOOL_ROUNDS = 400;
|
||||
|
||||
@@ -167,6 +167,7 @@ export class Agent {
|
||||
private bash: BashTool;
|
||||
private delegations: DelegationManager;
|
||||
private messages: ModelMessage[] = [];
|
||||
private recordedTokens = 0;
|
||||
private abortController: AbortController | null = null;
|
||||
private maxToolRounds: number;
|
||||
private mode: AgentMode = "agent";
|
||||
@@ -201,6 +202,7 @@ export class Agent {
|
||||
if (mode !== this.mode) {
|
||||
this.mode = mode;
|
||||
this.messages = [];
|
||||
this.recordedTokens = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -212,16 +214,42 @@ export class Agent {
|
||||
return this.bash.getCwd();
|
||||
}
|
||||
|
||||
getContextStats(
|
||||
contextWindow: number,
|
||||
inFlightText = "",
|
||||
): {
|
||||
contextWindow: number;
|
||||
usedTokens: number;
|
||||
remainingTokens: number;
|
||||
ratioUsed: number;
|
||||
ratioRemaining: number;
|
||||
} {
|
||||
const system = buildSystemPrompt(this.bash.getCwd(), this.mode, this.planContext);
|
||||
const estimatedTokens = estimateTokens(`${system}\n${JSON.stringify(this.messages)}\n${inFlightText}`);
|
||||
const usedTokens = Math.min(contextWindow, Math.max(estimatedTokens, this.recordedTokens));
|
||||
const remainingTokens = Math.max(0, contextWindow - usedTokens);
|
||||
|
||||
return {
|
||||
contextWindow,
|
||||
usedTokens,
|
||||
remainingTokens,
|
||||
ratioUsed: usedTokens / contextWindow,
|
||||
ratioRemaining: remainingTokens / contextWindow,
|
||||
};
|
||||
}
|
||||
|
||||
async generateTitle(userMessage: string): Promise<string> {
|
||||
return genTitle(this.provider, userMessage);
|
||||
}
|
||||
|
||||
abort(): void {
|
||||
this.abortController?.abort();
|
||||
this.emitSubagentStatus(null);
|
||||
}
|
||||
|
||||
clearHistory(): void {
|
||||
this.messages = [];
|
||||
this.recordedTokens = 0;
|
||||
}
|
||||
|
||||
onSubagentStatus(listener: (status: SubagentStatus | null) => void): () => void {
|
||||
@@ -237,6 +265,21 @@ export class Agent {
|
||||
}
|
||||
}
|
||||
|
||||
private discardAbortedTurn(userMessage: ModelMessage): void {
|
||||
const idx = this.messages.lastIndexOf(userMessage);
|
||||
if (idx >= 0) {
|
||||
this.messages.splice(idx, 1);
|
||||
}
|
||||
}
|
||||
|
||||
private recordUsage(usage?: { totalTokens?: number; inputTokens?: number; outputTokens?: number }): void {
|
||||
if (!usage) return;
|
||||
const total = usage.totalTokens ?? (usage.inputTokens ?? 0) + (usage.outputTokens ?? 0);
|
||||
if (Number.isFinite(total) && total > 0) {
|
||||
this.recordedTokens += total;
|
||||
}
|
||||
}
|
||||
|
||||
async consumeBackgroundNotifications(): Promise<string[]> {
|
||||
try {
|
||||
const notifications = await this.delegations.consumeNotifications();
|
||||
@@ -252,7 +295,9 @@ export class Agent {
|
||||
async runTaskRequest(
|
||||
request: TaskRequest,
|
||||
onActivity?: (detail: string) => void,
|
||||
abortSignal?: AbortSignal,
|
||||
): Promise<ToolResult> {
|
||||
const signal = abortSignal;
|
||||
const childMode: AgentMode = request.agent === "explore" ? "ask" : "agent";
|
||||
const childBash = new BashTool(this.bash.getCwd());
|
||||
const childTools = createTools(childBash, this.provider, childMode);
|
||||
@@ -270,12 +315,19 @@ export class Agent {
|
||||
tools: childTools,
|
||||
stopWhen: stepCountIs(Math.min(this.maxToolRounds, request.agent === "explore" ? 60 : 120)),
|
||||
maxRetries: 0,
|
||||
abortSignal: this.abortController?.signal,
|
||||
abortSignal: signal,
|
||||
temperature: request.agent === "explore" ? 0.2 : 0.5,
|
||||
maxOutputTokens: Math.min(this.maxTokens, 8_192),
|
||||
onFinish: ({ totalUsage }) => {
|
||||
this.recordUsage(totalUsage);
|
||||
},
|
||||
});
|
||||
|
||||
for await (const part of result.fullStream) {
|
||||
if (signal?.aborted) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (part.type === "text-delta") {
|
||||
assistantText += part.text;
|
||||
continue;
|
||||
@@ -287,6 +339,10 @@ export class Agent {
|
||||
}
|
||||
}
|
||||
|
||||
if (signal?.aborted) {
|
||||
return { success: false, output: "[Cancelled]" };
|
||||
}
|
||||
|
||||
await result.response;
|
||||
|
||||
const output = assistantText.trim() || `Task completed. Last action: ${lastActivity}`;
|
||||
@@ -301,6 +357,7 @@ export class Agent {
|
||||
},
|
||||
};
|
||||
} catch (err: unknown) {
|
||||
if (signal?.aborted) throw err;
|
||||
const msg = err instanceof Error ? err.message : String(err);
|
||||
const output = `Task failed: ${msg}`;
|
||||
return {
|
||||
@@ -316,28 +373,38 @@ export class Agent {
|
||||
}
|
||||
}
|
||||
|
||||
private async runTask(request: TaskRequest): Promise<ToolResult> {
|
||||
private async runTask(request: TaskRequest, abortSignal?: AbortSignal): Promise<ToolResult> {
|
||||
try {
|
||||
return await this.runTaskRequest(request, (detail) => {
|
||||
this.emitSubagentStatus({
|
||||
agent: request.agent,
|
||||
description: request.description,
|
||||
detail,
|
||||
});
|
||||
});
|
||||
return await this.runTaskRequest(
|
||||
request,
|
||||
(detail) => {
|
||||
if (abortSignal?.aborted) return;
|
||||
this.emitSubagentStatus({
|
||||
agent: request.agent,
|
||||
description: request.description,
|
||||
detail,
|
||||
});
|
||||
},
|
||||
abortSignal,
|
||||
);
|
||||
} finally {
|
||||
this.emitSubagentStatus(null);
|
||||
}
|
||||
}
|
||||
|
||||
private async runDelegation(request: TaskRequest): Promise<ToolResult> {
|
||||
private async runDelegation(request: TaskRequest, abortSignal?: AbortSignal): Promise<ToolResult> {
|
||||
try {
|
||||
if (abortSignal?.aborted) {
|
||||
return { success: false, output: "[Cancelled]" };
|
||||
}
|
||||
|
||||
return await this.delegations.start(request, {
|
||||
model: this.modelId,
|
||||
maxToolRounds: this.maxToolRounds,
|
||||
maxTokens: this.maxTokens,
|
||||
});
|
||||
} catch (err: unknown) {
|
||||
if (abortSignal?.aborted) throw err;
|
||||
const msg = err instanceof Error ? err.message : String(err);
|
||||
return {
|
||||
success: false,
|
||||
@@ -391,18 +458,20 @@ export class Agent {
|
||||
|
||||
async *processMessage(userMessage: string): AsyncGenerator<StreamChunk, void, unknown> {
|
||||
this.abortController = new AbortController();
|
||||
const signal = this.abortController.signal;
|
||||
this.emitSubagentStatus(null);
|
||||
|
||||
await this.consumeBackgroundNotifications();
|
||||
this.messages.push({ role: "user", content: userMessage });
|
||||
const userModelMessage: ModelMessage = { role: "user", content: userMessage };
|
||||
this.messages.push(userModelMessage);
|
||||
|
||||
let assistantText = "";
|
||||
let streamOk = false;
|
||||
|
||||
try {
|
||||
const tools = createTools(this.bash, this.provider, this.mode, {
|
||||
runTask: (request) => this.runTask(request),
|
||||
runDelegation: (request) => this.runDelegation(request),
|
||||
runTask: (request, abortSignal) => this.runTask(request, abortSignal ?? signal),
|
||||
runDelegation: (request, abortSignal) => this.runDelegation(request, abortSignal ?? signal),
|
||||
readDelegation: (id) => this.readDelegation(id),
|
||||
listDelegations: () => this.listDelegations(),
|
||||
});
|
||||
@@ -416,13 +485,16 @@ export class Agent {
|
||||
tools,
|
||||
stopWhen: stepCountIs(this.maxToolRounds),
|
||||
maxRetries: 0,
|
||||
abortSignal: this.abortController.signal,
|
||||
abortSignal: signal,
|
||||
temperature: 0.7,
|
||||
maxOutputTokens: this.maxTokens,
|
||||
onFinish: ({ totalUsage }) => {
|
||||
this.recordUsage(totalUsage);
|
||||
},
|
||||
});
|
||||
|
||||
for await (const part of result.fullStream) {
|
||||
if (this.abortController.signal.aborted) {
|
||||
if (signal.aborted) {
|
||||
yield { type: "content", content: "\n\n[Cancelled]" };
|
||||
break;
|
||||
}
|
||||
@@ -457,35 +529,56 @@ export class Agent {
|
||||
case "error":
|
||||
yield { type: "error", content: String(part.error) };
|
||||
break;
|
||||
|
||||
case "abort":
|
||||
yield { type: "content", content: "\n\n[Cancelled]" };
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (signal.aborted) {
|
||||
this.discardAbortedTurn(userModelMessage);
|
||||
yield { type: "done" };
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const response = await result.response;
|
||||
this.messages.push(...response.messages);
|
||||
streamOk = true;
|
||||
if (!signal.aborted) {
|
||||
this.messages.push(...response.messages);
|
||||
streamOk = true;
|
||||
}
|
||||
} catch {
|
||||
// response promise can fail after stream errors — fall back to manual message
|
||||
}
|
||||
|
||||
if (signal.aborted) {
|
||||
this.discardAbortedTurn(userModelMessage);
|
||||
yield { type: "done" };
|
||||
return;
|
||||
}
|
||||
|
||||
if (!streamOk && assistantText.trim()) {
|
||||
this.messages.push({ role: "assistant", content: assistantText });
|
||||
}
|
||||
|
||||
yield { type: "done" };
|
||||
} catch (err: unknown) {
|
||||
if (this.abortController.signal.aborted) {
|
||||
if (signal.aborted) {
|
||||
this.discardAbortedTurn(userModelMessage);
|
||||
yield { type: "content", content: "\n\n[Cancelled]" };
|
||||
} else {
|
||||
const msg = err instanceof Error ? err.message : String(err);
|
||||
yield { type: "error", content: `Error: ${msg}` };
|
||||
}
|
||||
if (assistantText.trim()) {
|
||||
if (!signal.aborted && assistantText.trim()) {
|
||||
this.messages.push({ role: "assistant", content: assistantText });
|
||||
}
|
||||
yield { type: "done" };
|
||||
} finally {
|
||||
this.abortController = null;
|
||||
if (this.abortController?.signal === signal) {
|
||||
this.abortController = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -553,3 +646,7 @@ function firstLine(text: string): string {
|
||||
function truncate(text: string, max: number): string {
|
||||
return text.length <= max ? text : `${text.slice(0, max - 1)}…`;
|
||||
}
|
||||
|
||||
function estimateTokens(text: string): number {
|
||||
return Math.ceil(text.length / 4);
|
||||
}
|
||||
+12
-51
@@ -3,46 +3,13 @@ import { createHash } from "crypto";
|
||||
import { promises as fs } from "fs";
|
||||
import os from "os";
|
||||
import path from "path";
|
||||
import type { DelegationRun, DelegationStatus, TaskRequest, ToolResult } from "../types/index.js";
|
||||
import type { DelegationRun, DelegationStatus, TaskRequest, ToolResult } from "../types/index";
|
||||
|
||||
const ID_ADJECTIVES = [
|
||||
"brisk",
|
||||
"calm",
|
||||
"clever",
|
||||
"eager",
|
||||
"gentle",
|
||||
"keen",
|
||||
"lively",
|
||||
"nimble",
|
||||
"quiet",
|
||||
"steady",
|
||||
];
|
||||
const ID_ADJECTIVES = ["brisk", "calm", "clever", "eager", "gentle", "keen", "lively", "nimble", "quiet", "steady"];
|
||||
|
||||
const ID_COLORS = [
|
||||
"amber",
|
||||
"blue",
|
||||
"copper",
|
||||
"emerald",
|
||||
"indigo",
|
||||
"ivory",
|
||||
"silver",
|
||||
"teal",
|
||||
"violet",
|
||||
"white",
|
||||
];
|
||||
const ID_COLORS = ["amber", "blue", "copper", "emerald", "indigo", "ivory", "silver", "teal", "violet", "white"];
|
||||
|
||||
const ID_ANIMALS = [
|
||||
"badger",
|
||||
"falcon",
|
||||
"fox",
|
||||
"heron",
|
||||
"lynx",
|
||||
"otter",
|
||||
"owl",
|
||||
"panda",
|
||||
"sparrow",
|
||||
"wolf",
|
||||
];
|
||||
const ID_ANIMALS = ["badger", "falcon", "fox", "heron", "lynx", "otter", "owl", "panda", "sparrow", "wolf"];
|
||||
|
||||
export interface StoredDelegation {
|
||||
id: string;
|
||||
@@ -217,11 +184,7 @@ export async function loadDelegation(jobPath: string): Promise<StoredDelegation>
|
||||
return record;
|
||||
}
|
||||
|
||||
export async function completeDelegation(
|
||||
jobPath: string,
|
||||
output: string,
|
||||
fallbackSummary?: string,
|
||||
): Promise<void> {
|
||||
export async function completeDelegation(jobPath: string, output: string, fallbackSummary?: string): Promise<void> {
|
||||
const record = await loadDelegation(jobPath);
|
||||
record.status = "complete";
|
||||
record.completedAt = new Date().toISOString();
|
||||
@@ -306,7 +269,11 @@ function resolveCliArgs(): string[] {
|
||||
}
|
||||
|
||||
function getProjectId(cwd: string): string {
|
||||
const base = path.basename(cwd).replace(/[^a-zA-Z0-9._-]+/g, "-").replace(/^-+|-+$/g, "") || "project";
|
||||
const base =
|
||||
path
|
||||
.basename(cwd)
|
||||
.replace(/[^a-zA-Z0-9._-]+/g, "-")
|
||||
.replace(/^-+|-+$/g, "") || "project";
|
||||
const hash = createHash("sha1").update(cwd).digest("hex").slice(0, 10);
|
||||
return `${base}-${hash}`;
|
||||
}
|
||||
@@ -359,11 +326,7 @@ function formatNotification(record: StoredDelegation): string {
|
||||
const title = record.title || record.description || record.id;
|
||||
const summary = record.summary || (record.error ? createSummary(record.error) : "No summary available.");
|
||||
const statusText = record.status === "complete" ? "complete" : "failed";
|
||||
const lines = [
|
||||
`Background agent ${statusText}: \`${record.id}\``,
|
||||
`Title: ${title}`,
|
||||
`Summary: ${summary}`,
|
||||
];
|
||||
const lines = [`Background agent ${statusText}: \`${record.id}\``, `Title: ${title}`, `Summary: ${summary}`];
|
||||
|
||||
if (record.error) {
|
||||
lines.push(`Error: ${record.error}`);
|
||||
@@ -378,9 +341,7 @@ function toDelegationRun(record: StoredDelegation): DelegationRun {
|
||||
id: record.id,
|
||||
agent: "explore",
|
||||
description: record.description,
|
||||
summary:
|
||||
record.summary ||
|
||||
(record.status === "running" ? "Running in the background." : "No summary available."),
|
||||
summary: record.summary || (record.status === "running" ? "Running in the background." : "No summary available."),
|
||||
status: record.status,
|
||||
};
|
||||
}
|
||||
+1
-4
@@ -10,10 +10,7 @@ export function createProvider(apiKey: string, baseURL?: string): XaiProvider {
|
||||
});
|
||||
}
|
||||
|
||||
export async function generateTitle(
|
||||
provider: XaiProvider,
|
||||
userMessage: string,
|
||||
): Promise<string> {
|
||||
export async function generateTitle(provider: XaiProvider, userMessage: string): Promise<string> {
|
||||
try {
|
||||
const { text } = await generateText({
|
||||
model: provider("grok-3-mini-fast"),
|
||||
|
||||
+2
-17
@@ -1,4 +1,4 @@
|
||||
import type { ModelInfo } from "../types/index.js";
|
||||
import type { ModelInfo } from "../types/index";
|
||||
|
||||
export const MODELS: ModelInfo[] = [
|
||||
{
|
||||
@@ -66,21 +66,6 @@ export const MODELS: ModelInfo[] = [
|
||||
},
|
||||
];
|
||||
|
||||
export const MODEL_GROUPS: { category: string; models: string[] }[] = [
|
||||
{
|
||||
category: "Grok 4",
|
||||
models: ["grok-4-0709", "grok-4.20-beta-0309", "grok-4-fast", "grok-4-1-fast"],
|
||||
},
|
||||
{
|
||||
category: "Grok Code",
|
||||
models: ["grok-code-fast-1"],
|
||||
},
|
||||
{
|
||||
category: "Grok 3",
|
||||
models: ["grok-3", "grok-3-mini"],
|
||||
},
|
||||
];
|
||||
|
||||
export const DEFAULT_MODEL = "grok-4-1-fast";
|
||||
|
||||
export function getModelInfo(modelId: string): ModelInfo | undefined {
|
||||
@@ -89,4 +74,4 @@ export function getModelInfo(modelId: string): ModelInfo | undefined {
|
||||
|
||||
export function getModelIds(): string[] {
|
||||
return MODELS.map((m) => m.id);
|
||||
}
|
||||
}
|
||||
+63
-91
@@ -1,15 +1,15 @@
|
||||
import { tool, generateText } from "ai";
|
||||
import { generateText, type ToolSet, tool } from "ai";
|
||||
import { z } from "zod";
|
||||
import type { BashTool } from "../tools/bash.js";
|
||||
import { readFile, writeFile, editFile } from "../tools/file.js";
|
||||
import type { XaiProvider } from "./client.js";
|
||||
import { editFile, readFile, writeFile } from "../tools/file.js";
|
||||
import type { AgentMode, TaskRequest, ToolResult } from "../types/index.js";
|
||||
import type { XaiProvider } from "./client.js";
|
||||
|
||||
const SEARCH_MODEL = "grok-3-mini-fast";
|
||||
|
||||
interface CreateToolsOptions {
|
||||
runTask?: (request: TaskRequest) => Promise<ToolResult>;
|
||||
runDelegation?: (request: TaskRequest) => Promise<ToolResult>;
|
||||
runTask?: (request: TaskRequest, abortSignal?: AbortSignal) => Promise<ToolResult>;
|
||||
runDelegation?: (request: TaskRequest, abortSignal?: AbortSignal) => Promise<ToolResult>;
|
||||
readDelegation?: (id: string) => Promise<ToolResult>;
|
||||
listDelegations?: () => Promise<ToolResult>;
|
||||
}
|
||||
@@ -60,10 +60,7 @@ export function createTools(
|
||||
"View recent output (stdout + stderr) from a background process by its ID. Returns the last N lines of the log.",
|
||||
inputSchema: z.object({
|
||||
id: z.number().describe("The background process ID"),
|
||||
tail: z
|
||||
.number()
|
||||
.optional()
|
||||
.describe("Number of lines to return from the end (default: 50)"),
|
||||
tail: z.number().optional().describe("Number of lines to return from the end (default: 50)"),
|
||||
}),
|
||||
execute: async ({ id, tail }) => {
|
||||
return bash.getProcessLogs(id, tail);
|
||||
@@ -82,8 +79,7 @@ export function createTools(
|
||||
}),
|
||||
|
||||
process_list: tool({
|
||||
description:
|
||||
"List all background processes with their ID, status, PID, age, and command.",
|
||||
description: "List all background processes with their ID, status, PID, age, and command.",
|
||||
inputSchema: z.object({}),
|
||||
execute: async () => {
|
||||
return bash.listProcesses();
|
||||
@@ -95,14 +91,8 @@ export function createTools(
|
||||
"Read the contents of a file. Returns numbered lines with a header showing the range and total line count. Use start_line/end_line to read specific sections of large files iteratively.",
|
||||
inputSchema: z.object({
|
||||
path: z.string().describe("File path (relative to cwd or absolute)"),
|
||||
start_line: z
|
||||
.number()
|
||||
.optional()
|
||||
.describe("First line to read (1-indexed, default: 1)"),
|
||||
end_line: z
|
||||
.number()
|
||||
.optional()
|
||||
.describe("Last line to read (inclusive, default: end of file)"),
|
||||
start_line: z.number().optional().describe("First line to read (1-indexed, default: 1)"),
|
||||
end_line: z.number().optional().describe("Last line to read (inclusive, default: end of file)"),
|
||||
}),
|
||||
execute: async ({ path, start_line, end_line }) => {
|
||||
return readFile(path, cwd(), start_line, end_line);
|
||||
@@ -168,10 +158,9 @@ export function createTools(
|
||||
}
|
||||
},
|
||||
}),
|
||||
|
||||
};
|
||||
|
||||
const tools: Record<string, any> = { ...base };
|
||||
const tools: ToolSet = { ...base };
|
||||
|
||||
if (mode === "agent") {
|
||||
tools.write_file = tool({
|
||||
@@ -204,19 +193,14 @@ export function createTools(
|
||||
description:
|
||||
"Delegate a focused foreground task to a sub-agent. Prefer this proactively for review, research, investigation, and code quality work instead of waiting for the user to request a sub-agent. Use `general` for multi-step execution and `explore` for fast read-only investigation. Provide a short description plus a detailed prompt for the child agent.",
|
||||
inputSchema: z.object({
|
||||
agent: z
|
||||
.enum(["general", "explore"])
|
||||
.default("general")
|
||||
.describe("Which sub-agent to use"),
|
||||
agent: z.enum(["general", "explore"]).default("general").describe("Which sub-agent to use"),
|
||||
description: z
|
||||
.string()
|
||||
.describe("A short label for the delegated task, such as 'Deep code quality analysis'"),
|
||||
prompt: z
|
||||
.string()
|
||||
.describe("Detailed instructions for the sub-agent to complete"),
|
||||
prompt: z.string().describe("Detailed instructions for the sub-agent to complete"),
|
||||
}),
|
||||
execute: async ({ agent, description, prompt }) => {
|
||||
return options.runTask!({ agent, description, prompt });
|
||||
execute: async ({ agent, description, prompt }, { abortSignal }) => {
|
||||
return options.runTask!({ agent, description, prompt }, abortSignal);
|
||||
},
|
||||
});
|
||||
}
|
||||
@@ -230,15 +214,11 @@ export function createTools(
|
||||
.enum(["explore"])
|
||||
.default("explore")
|
||||
.describe("Background delegations currently support only the read-only explore agent"),
|
||||
description: z
|
||||
.string()
|
||||
.describe("A short label for the delegation, such as 'OAuth callback research'"),
|
||||
prompt: z
|
||||
.string()
|
||||
.describe("Detailed instructions for the background agent to complete"),
|
||||
description: z.string().describe("A short label for the delegation, such as 'OAuth callback research'"),
|
||||
prompt: z.string().describe("Detailed instructions for the background agent to complete"),
|
||||
}),
|
||||
execute: async ({ agent, description, prompt }) => {
|
||||
return options.runDelegation!({ agent, description, prompt });
|
||||
execute: async ({ agent, description, prompt }, { abortSignal }) => {
|
||||
return options.runDelegation!({ agent, description, prompt }, abortSignal);
|
||||
},
|
||||
});
|
||||
}
|
||||
@@ -271,59 +251,51 @@ export function createTools(
|
||||
if (mode !== "plan") return tools;
|
||||
|
||||
tools.generate_plan = tool({
|
||||
description:
|
||||
"Generate an interactive implementation plan with steps and optional questions for the user. The plan is displayed in a structured UI where the user can review steps and answer questions. Always use this tool when creating plans.",
|
||||
inputSchema: z.object({
|
||||
title: z.string().describe("Plan title"),
|
||||
summary: z.string().describe("Brief summary of what the plan accomplishes"),
|
||||
steps: z
|
||||
.array(
|
||||
z.object({
|
||||
title: z.string().describe("Step title"),
|
||||
description: z
|
||||
.string()
|
||||
.describe("Detailed description of what this step involves"),
|
||||
filePaths: z
|
||||
.array(z.string())
|
||||
.optional()
|
||||
.describe("Files affected by this step"),
|
||||
}),
|
||||
)
|
||||
.describe("Ordered list of implementation steps"),
|
||||
questions: z
|
||||
.array(
|
||||
z.object({
|
||||
id: z.string().describe("Unique question identifier"),
|
||||
question: z.string().describe("The question to ask the user"),
|
||||
header: z
|
||||
.string()
|
||||
.optional()
|
||||
.describe("Single-word tab label (e.g. 'Format', 'Storage', 'Testing')"),
|
||||
type: z
|
||||
.enum(["select", "multiselect", "text"])
|
||||
.describe("Question type: select (pick one), multiselect (pick many), or text (free-form)"),
|
||||
options: z
|
||||
.array(
|
||||
z.object({
|
||||
id: z.string().describe("Option identifier"),
|
||||
label: z.string().describe("Option display text"),
|
||||
}),
|
||||
)
|
||||
.optional()
|
||||
.describe("Options for select/multiselect questions"),
|
||||
}),
|
||||
)
|
||||
.optional()
|
||||
.describe("Questions for the user to answer before proceeding"),
|
||||
}),
|
||||
execute: async ({ title, summary, steps, questions }) => {
|
||||
return {
|
||||
success: true,
|
||||
output: `Plan "${title}" generated with ${steps.length} steps`,
|
||||
plan: { title, summary, steps, questions },
|
||||
};
|
||||
},
|
||||
});
|
||||
description:
|
||||
"Generate an interactive implementation plan with steps and optional questions for the user. The plan is displayed in a structured UI where the user can review steps and answer questions. Always use this tool when creating plans.",
|
||||
inputSchema: z.object({
|
||||
title: z.string().describe("Plan title"),
|
||||
summary: z.string().describe("Brief summary of what the plan accomplishes"),
|
||||
steps: z
|
||||
.array(
|
||||
z.object({
|
||||
title: z.string().describe("Step title"),
|
||||
description: z.string().describe("Detailed description of what this step involves"),
|
||||
filePaths: z.array(z.string()).optional().describe("Files affected by this step"),
|
||||
}),
|
||||
)
|
||||
.describe("Ordered list of implementation steps"),
|
||||
questions: z
|
||||
.array(
|
||||
z.object({
|
||||
id: z.string().describe("Unique question identifier"),
|
||||
question: z.string().describe("The question to ask the user"),
|
||||
header: z.string().optional().describe("Single-word tab label (e.g. 'Format', 'Storage', 'Testing')"),
|
||||
type: z
|
||||
.enum(["select", "multiselect", "text"])
|
||||
.describe("Question type: select (pick one), multiselect (pick many), or text (free-form)"),
|
||||
options: z
|
||||
.array(
|
||||
z.object({
|
||||
id: z.string().describe("Option identifier"),
|
||||
label: z.string().describe("Option display text"),
|
||||
}),
|
||||
)
|
||||
.optional()
|
||||
.describe("Options for select/multiselect questions"),
|
||||
}),
|
||||
)
|
||||
.optional()
|
||||
.describe("Questions for the user to answer before proceeding"),
|
||||
}),
|
||||
execute: async ({ title, summary, steps, questions }) => {
|
||||
return {
|
||||
success: true,
|
||||
output: `Plan "${title}" generated with ${steps.length} steps`,
|
||||
plan: { title, summary, steps, questions },
|
||||
};
|
||||
},
|
||||
});
|
||||
|
||||
return tools;
|
||||
}
|
||||
+17
-24
@@ -1,14 +1,14 @@
|
||||
#!/usr/bin/env bun
|
||||
import { program } from "commander";
|
||||
import * as dotenv from "dotenv";
|
||||
import { createCliRenderer } from "@opentui/core";
|
||||
import { createRoot } from "@opentui/react";
|
||||
import { program } from "commander";
|
||||
import * as dotenv from "dotenv";
|
||||
import { createElement } from "react";
|
||||
import { Agent } from "./agent/agent.js";
|
||||
import { completeDelegation, failDelegation, loadDelegation } from "./agent/delegations.js";
|
||||
import { App } from "./ui/app.js";
|
||||
import { getApiKey, getBaseURL, getCurrentModel, saveUserSettings } from "./utils/settings.js";
|
||||
import { MODELS } from "./grok/models.js";
|
||||
import { Agent } from "./agent/agent";
|
||||
import { completeDelegation, failDelegation, loadDelegation } from "./agent/delegations";
|
||||
import { MODELS } from "./grok/models";
|
||||
import { App } from "./ui/app";
|
||||
import { getApiKey, getBaseURL, getCurrentModel, saveUserSettings } from "./utils/settings";
|
||||
|
||||
dotenv.config();
|
||||
|
||||
@@ -39,18 +39,15 @@ async function startInteractive(
|
||||
exitOnCtrlC: false,
|
||||
});
|
||||
|
||||
const onExit = () => { renderer.destroy(); process.exit(0); };
|
||||
const onExit = () => {
|
||||
renderer.destroy();
|
||||
process.exit(0);
|
||||
};
|
||||
|
||||
createRoot(renderer).render(createElement(App, { agent, initialMessage, onExit }));
|
||||
}
|
||||
|
||||
async function runHeadless(
|
||||
prompt: string,
|
||||
apiKey: string,
|
||||
baseURL: string,
|
||||
model: string,
|
||||
maxToolRounds: number,
|
||||
) {
|
||||
async function runHeadless(prompt: string, apiKey: string, baseURL: string, model: string, maxToolRounds: number) {
|
||||
const agent = new Agent(apiKey, baseURL, model, maxToolRounds);
|
||||
|
||||
process.stdout.write(`\x1b[36m⏳ Processing...\x1b[0m\n`);
|
||||
@@ -91,15 +88,13 @@ async function runBackgroundDelegation(jobPath: string, options: Record<string,
|
||||
const delegation = await loadDelegation(jobPath);
|
||||
const apiKey = options.apiKey || getApiKey();
|
||||
if (!apiKey) {
|
||||
throw new Error(
|
||||
"API key required. Set GROK_API_KEY, use --api-key, or save it to ~/.grok/user-settings.json.",
|
||||
);
|
||||
throw new Error("API key required. Set GROK_API_KEY, use --api-key, or save it to ~/.grok/user-settings.json.");
|
||||
}
|
||||
|
||||
const baseURL = options.baseUrl || getBaseURL();
|
||||
const model = options.model || delegation.model || getCurrentModel();
|
||||
const maxToolRounds = parseInt(options.maxToolRounds || String(delegation.maxToolRounds), 10)
|
||||
|| delegation.maxToolRounds;
|
||||
const maxToolRounds =
|
||||
parseInt(options.maxToolRounds || String(delegation.maxToolRounds), 10) || delegation.maxToolRounds;
|
||||
const agent = new Agent(apiKey, baseURL, model, maxToolRounds);
|
||||
const result = await agent.runTaskRequest({
|
||||
agent: delegation.agent,
|
||||
@@ -130,7 +125,7 @@ function resolveConfig(options: Record<string, string | undefined>) {
|
||||
const apiKey = options.apiKey || getApiKey();
|
||||
const baseURL = options.baseUrl || getBaseURL();
|
||||
const model = options.model || getCurrentModel();
|
||||
const maxToolRounds = parseInt(options.maxToolRounds || "400") || 400;
|
||||
const maxToolRounds = parseInt(options.maxToolRounds || "400", 10) || 400;
|
||||
|
||||
if (!apiKey) {
|
||||
console.error(
|
||||
@@ -191,9 +186,7 @@ program
|
||||
console.log("\nAvailable Grok Models:\n");
|
||||
for (const m of MODELS) {
|
||||
const reasoning = m.reasoning ? " (reasoning)" : "";
|
||||
console.log(
|
||||
` \x1b[36m${m.id}\x1b[0m — ${m.name}${reasoning}`,
|
||||
);
|
||||
console.log(` \x1b[36m${m.id}\x1b[0m — ${m.name}${reasoning}`);
|
||||
console.log(
|
||||
` ${m.description} | ${formatContext(m.contextWindow)} context | $${m.inputPrice}/$${m.outputPrice} per 1M tokens`,
|
||||
);
|
||||
|
||||
+33
-12
@@ -1,10 +1,10 @@
|
||||
import { exec, spawn, type ChildProcess } from "child_process";
|
||||
import { createWriteStream, createReadStream } from "fs";
|
||||
import { stat, mkdtemp, readFile, unlink, rm } from "fs/promises";
|
||||
import { type ChildProcess, exec, spawn } from "child_process";
|
||||
import { createReadStream, createWriteStream } from "fs";
|
||||
import { mkdtemp, rm, stat, unlink } from "fs/promises";
|
||||
import os from "os";
|
||||
import path from "path";
|
||||
import { promisify } from "util";
|
||||
import type { ToolResult } from "../types/index.js";
|
||||
import type { ToolResult } from "../types/index";
|
||||
|
||||
const execAsync = promisify(exec);
|
||||
|
||||
@@ -44,7 +44,10 @@ export class BashTool {
|
||||
async execute(command: string, timeout = 30_000): Promise<ToolResult> {
|
||||
try {
|
||||
if (command.startsWith("cd ")) {
|
||||
const dir = command.substring(3).trim().replace(/^["']|["']$/g, "");
|
||||
const dir = command
|
||||
.substring(3)
|
||||
.trim()
|
||||
.replace(/^["']|["']$/g, "");
|
||||
try {
|
||||
const nextCwd = path.resolve(this.cwd, dir);
|
||||
const info = await stat(nextCwd);
|
||||
@@ -74,8 +77,7 @@ export class BashTool {
|
||||
} catch (err: unknown) {
|
||||
if (err && typeof err === "object" && "stdout" in err) {
|
||||
const execErr = err as { stdout?: string; stderr?: string; message: string };
|
||||
const output =
|
||||
(execErr.stdout || "") + (execErr.stderr ? `\nSTDERR: ${execErr.stderr}` : "");
|
||||
const output = (execErr.stdout || "") + (execErr.stderr ? `\nSTDERR: ${execErr.stderr}` : "");
|
||||
if (output.trim()) {
|
||||
return { success: false, error: output.trim() };
|
||||
}
|
||||
@@ -208,10 +210,17 @@ export class BashTool {
|
||||
entry.child.kill("SIGTERM");
|
||||
await new Promise<void>((resolve) => {
|
||||
const timeout = setTimeout(() => {
|
||||
try { entry.child.kill("SIGKILL"); } catch { /* already dead */ }
|
||||
try {
|
||||
entry.child.kill("SIGKILL");
|
||||
} catch {
|
||||
/* already dead */
|
||||
}
|
||||
resolve();
|
||||
}, 3_000);
|
||||
entry.child.on("exit", () => { clearTimeout(timeout); resolve(); });
|
||||
entry.child.on("exit", () => {
|
||||
clearTimeout(timeout);
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
|
||||
return {
|
||||
@@ -245,13 +254,25 @@ export class BashTool {
|
||||
async cleanup(): Promise<void> {
|
||||
for (const entry of this.bgProcesses.values()) {
|
||||
if (entry.alive) {
|
||||
try { entry.child.kill("SIGTERM"); } catch { /* */ }
|
||||
try {
|
||||
entry.child.kill("SIGTERM");
|
||||
} catch {
|
||||
/* */
|
||||
}
|
||||
}
|
||||
try {
|
||||
await unlink(entry.logPath);
|
||||
} catch {
|
||||
/* */
|
||||
}
|
||||
try { await unlink(entry.logPath); } catch { /* */ }
|
||||
}
|
||||
this.bgProcesses.clear();
|
||||
if (this.tmpDir) {
|
||||
try { await rm(this.tmpDir, { recursive: true, force: true }); } catch { /* */ }
|
||||
try {
|
||||
await rm(this.tmpDir, { recursive: true, force: true });
|
||||
} catch {
|
||||
/* */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+3
-8
@@ -1,6 +1,6 @@
|
||||
import { readFileSync, writeFileSync, existsSync, mkdirSync } from "fs";
|
||||
import { dirname, resolve, isAbsolute } from "path";
|
||||
import { createTwoFilesPatch } from "diff";
|
||||
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";
|
||||
import { dirname, isAbsolute, resolve } from "path";
|
||||
|
||||
export interface FileDiff {
|
||||
filePath: string;
|
||||
@@ -79,12 +79,7 @@ export function writeFile(filePath: string, content: string, cwd: string): FileR
|
||||
}
|
||||
}
|
||||
|
||||
export function editFile(
|
||||
filePath: string,
|
||||
oldString: string,
|
||||
newString: string,
|
||||
cwd: string,
|
||||
): FileResult {
|
||||
export function editFile(filePath: string, oldString: string, newString: string, cwd: string): FileResult {
|
||||
try {
|
||||
const full = resolvePath(filePath, cwd);
|
||||
if (!existsSync(full)) {
|
||||
|
||||
@@ -111,13 +111,6 @@ export interface ModelInfo {
|
||||
description: string;
|
||||
}
|
||||
|
||||
export interface Skill {
|
||||
id: string;
|
||||
title: string;
|
||||
description: string;
|
||||
executable?: boolean;
|
||||
}
|
||||
|
||||
export type AgentMode = "agent" | "plan" | "ask";
|
||||
|
||||
export const MODES: { id: AgentMode; label: string; color: string }[] = [
|
||||
|
||||
+937
-327
File diff suppressed because it is too large.
Load diff
+4
-10
@@ -1,6 +1,6 @@
|
||||
import React, { useMemo } from "react";
|
||||
import { SyntaxStyle, RGBA } from "@opentui/core";
|
||||
import type { Theme } from "./theme.js";
|
||||
import { RGBA, SyntaxStyle } from "@opentui/core";
|
||||
import { useMemo } from "react";
|
||||
import type { Theme } from "./theme";
|
||||
|
||||
function buildSyntaxStyle(t: Theme): SyntaxStyle {
|
||||
return SyntaxStyle.fromStyles({
|
||||
@@ -36,12 +36,6 @@ export function Markdown({ content, t }: { content: string; t: Theme }) {
|
||||
const syntaxStyle = useMemo(() => buildSyntaxStyle(t), [t]);
|
||||
|
||||
return (
|
||||
<markdown
|
||||
content={content}
|
||||
syntaxStyle={syntaxStyle}
|
||||
conceal={true}
|
||||
tableOptions={TABLE_OPTIONS}
|
||||
flexShrink={0}
|
||||
/>
|
||||
<markdown content={content} syntaxStyle={syntaxStyle} conceal={true} tableOptions={TABLE_OPTIONS} flexShrink={0} />
|
||||
);
|
||||
}
|
||||
+32
-90
@@ -1,6 +1,5 @@
|
||||
import React from "react";
|
||||
import type { Plan, PlanQuestion } from "../types/index.js";
|
||||
import type { Theme } from "./theme.js";
|
||||
import type { Plan, PlanQuestion } from "../types/index";
|
||||
import type { Theme } from "./theme";
|
||||
|
||||
export type PlanAnswers = Record<string, string | string[]>;
|
||||
|
||||
@@ -17,7 +16,10 @@ export function PlanView({ plan, t }: PlanViewProps) {
|
||||
<box marginBottom={1}>
|
||||
<text>
|
||||
<span style={{ fg: t.planTitle }}>
|
||||
<b>{"◆ "}{plan.title}</b>
|
||||
<b>
|
||||
{"◆ "}
|
||||
{plan.title}
|
||||
</b>
|
||||
</span>
|
||||
</text>
|
||||
</box>
|
||||
@@ -93,11 +95,7 @@ interface PlanQuestionsPanelProps {
|
||||
state: PlanQuestionsState;
|
||||
}
|
||||
|
||||
export function PlanQuestionsPanel({
|
||||
t,
|
||||
questions,
|
||||
state,
|
||||
}: PlanQuestionsPanelProps) {
|
||||
export function PlanQuestionsPanel({ t, questions, state }: PlanQuestionsPanelProps) {
|
||||
const isSingle = questions.length === 1 && questions[0]?.type !== "multiselect";
|
||||
const isConfirmTab = !isSingle && state.tab === questions.length;
|
||||
const q = questions[state.tab];
|
||||
@@ -126,11 +124,7 @@ export function PlanQuestionsPanel({
|
||||
<text key={q.id}>
|
||||
<span
|
||||
style={{
|
||||
fg: isActive
|
||||
? t.planTitle
|
||||
: isAnswered
|
||||
? t.planOptionCheck
|
||||
: t.textMuted,
|
||||
fg: isActive ? t.planTitle : isAnswered ? t.planOptionCheck : t.textMuted,
|
||||
}}
|
||||
>
|
||||
{isActive ? <b>{label}</b> : label}
|
||||
@@ -155,11 +149,7 @@ export function PlanQuestionsPanel({
|
||||
{isConfirmTab ? (
|
||||
<ConfirmView t={t} questions={questions} answers={state.answers} />
|
||||
) : q ? (
|
||||
<QuestionBody
|
||||
t={t}
|
||||
question={q}
|
||||
state={state}
|
||||
/>
|
||||
<QuestionBody t={t} question={q} state={state} />
|
||||
) : null}
|
||||
|
||||
{/* Footer hints */}
|
||||
@@ -177,13 +167,7 @@ export function PlanQuestionsPanel({
|
||||
<text>
|
||||
<span style={{ fg: t.text }}>{"enter"}</span>
|
||||
<span style={{ fg: t.planHint }}>
|
||||
{isConfirmTab
|
||||
? " submit"
|
||||
: q?.type === "multiselect"
|
||||
? " toggle"
|
||||
: isSingle
|
||||
? " submit"
|
||||
: " confirm"}
|
||||
{isConfirmTab ? " submit" : q?.type === "multiselect" ? " toggle" : isSingle ? " submit" : " confirm"}
|
||||
</span>
|
||||
</text>
|
||||
<text>
|
||||
@@ -197,15 +181,7 @@ export function PlanQuestionsPanel({
|
||||
|
||||
/* ── Question Body ────────────────────────────────────────── */
|
||||
|
||||
function QuestionBody({
|
||||
t,
|
||||
question: q,
|
||||
state,
|
||||
}: {
|
||||
t: Theme;
|
||||
question: PlanQuestion;
|
||||
state: PlanQuestionsState;
|
||||
}) {
|
||||
function QuestionBody({ t, question: q, state }: { t: Theme; question: PlanQuestion; state: PlanQuestionsState }) {
|
||||
const isMulti = q.type === "multiselect";
|
||||
const options = q.options ?? [];
|
||||
const showCustom = q.type !== "text";
|
||||
@@ -227,9 +203,11 @@ function QuestionBody({
|
||||
/* Free-form text input */
|
||||
<box backgroundColor={t.planInputBg} paddingLeft={1} paddingRight={1}>
|
||||
<text fg={t.planInputText}>
|
||||
{state.editing || customText
|
||||
? customText + (state.editing ? "▌" : "")
|
||||
: <span style={{ fg: t.textMuted }}>{"Type your answer..."}</span>}
|
||||
{state.editing || customText ? (
|
||||
customText + (state.editing ? "▌" : "")
|
||||
) : (
|
||||
<span style={{ fg: t.textMuted }}>{"Type your answer..."}</span>
|
||||
)}
|
||||
</text>
|
||||
</box>
|
||||
) : (
|
||||
@@ -246,25 +224,15 @@ function QuestionBody({
|
||||
flexDirection="row"
|
||||
>
|
||||
<text>
|
||||
<span style={{ fg: t.textMuted }}>
|
||||
{`${i + 1}. `}
|
||||
</span>
|
||||
<span style={{ fg: t.textMuted }}>{`${i + 1}. `}</span>
|
||||
<span
|
||||
style={{
|
||||
fg: isFocused
|
||||
? t.selected
|
||||
: isPicked
|
||||
? t.planOptionCheck
|
||||
: t.text,
|
||||
fg: isFocused ? t.selected : isPicked ? t.planOptionCheck : t.text,
|
||||
}}
|
||||
>
|
||||
{isMulti
|
||||
? `[${isPicked ? "✓" : " "}] ${opt.label}`
|
||||
: opt.label}
|
||||
{isMulti ? `[${isPicked ? "✓" : " "}] ${opt.label}` : opt.label}
|
||||
</span>
|
||||
{isPicked && !isMulti ? (
|
||||
<span style={{ fg: t.planOptionCheck }}>{" ✓"}</span>
|
||||
) : null}
|
||||
{isPicked && !isMulti ? <span style={{ fg: t.planOptionCheck }}>{" ✓"}</span> : null}
|
||||
</text>
|
||||
</box>
|
||||
);
|
||||
@@ -272,21 +240,14 @@ function QuestionBody({
|
||||
|
||||
{/* "Type your own answer" option */}
|
||||
{showCustom && (
|
||||
<box
|
||||
backgroundColor={isOnCustom ? t.selectedBg : undefined}
|
||||
paddingLeft={1}
|
||||
>
|
||||
<box backgroundColor={isOnCustom ? t.selectedBg : undefined} paddingLeft={1}>
|
||||
{state.editing && isOnCustom ? (
|
||||
<box backgroundColor={t.planInputBg} paddingLeft={1} paddingRight={1} flexGrow={1}>
|
||||
<text fg={t.planInputText}>
|
||||
{customText + "▌"}
|
||||
</text>
|
||||
<text fg={t.planInputText}>{`${customText}▌`}</text>
|
||||
</box>
|
||||
) : (
|
||||
<text>
|
||||
<span style={{ fg: t.textMuted }}>
|
||||
{`${totalItems}. `}
|
||||
</span>
|
||||
<span style={{ fg: t.textMuted }}>{`${totalItems}. `}</span>
|
||||
<span
|
||||
style={{
|
||||
fg: isOnCustom ? t.planOptionSelected : t.textMuted,
|
||||
@@ -296,9 +257,7 @@ function QuestionBody({
|
||||
? `[${customText && isOptionPicked(state.answers, q, customText) ? "✓" : " "}] Type your own answer`
|
||||
: "Type your own answer"}
|
||||
</span>
|
||||
{customText ? (
|
||||
<span style={{ fg: t.textDim }}>{` (${customText})`}</span>
|
||||
) : null}
|
||||
{customText ? <span style={{ fg: t.textDim }}>{` (${customText})`}</span> : null}
|
||||
</text>
|
||||
)}
|
||||
</box>
|
||||
@@ -311,15 +270,7 @@ function QuestionBody({
|
||||
|
||||
/* ── Confirm/Review Tab ───────────────────────────────────── */
|
||||
|
||||
function ConfirmView({
|
||||
t,
|
||||
questions,
|
||||
answers,
|
||||
}: {
|
||||
t: Theme;
|
||||
questions: PlanQuestion[];
|
||||
answers: PlanAnswers;
|
||||
}) {
|
||||
function ConfirmView({ t, questions, answers }: { t: Theme; questions: PlanQuestion[]; answers: PlanAnswers }) {
|
||||
return (
|
||||
<box flexDirection="column">
|
||||
<box marginBottom={1}>
|
||||
@@ -336,9 +287,7 @@ function ConfirmView({
|
||||
<span style={{ fg: t.text }}>
|
||||
<b>{tabLabel(q)}:</b>
|
||||
</span>
|
||||
<span style={{ fg: answered ? t.planOptionCheck : t.textMuted }}>
|
||||
{" "}{val}
|
||||
</span>
|
||||
<span style={{ fg: answered ? t.planOptionCheck : t.textMuted }}> {val}</span>
|
||||
</text>
|
||||
</box>
|
||||
);
|
||||
@@ -352,7 +301,9 @@ function ConfirmView({
|
||||
function tabLabel(q: PlanQuestion): string {
|
||||
if (q.header) return q.header;
|
||||
const words = q.question.replace(/[?.,!:]+$/, "").split(/\s+/);
|
||||
const key = words.find((w) => w.length > 2 && !/^(what|how|should|which|does|the|and|for|are|can|will|you|this|that|with|from)$/i.test(w));
|
||||
const key = words.find(
|
||||
(w) => w.length > 2 && !/^(what|how|should|which|does|the|and|for|are|can|will|you|this|that|with|from)$/i.test(w),
|
||||
);
|
||||
return key ?? words[0] ?? "Question";
|
||||
}
|
||||
|
||||
@@ -363,11 +314,7 @@ function hasAnswer(answers: PlanAnswers, q: PlanQuestion): boolean {
|
||||
return a.trim().length > 0;
|
||||
}
|
||||
|
||||
function isOptionPicked(
|
||||
answers: PlanAnswers,
|
||||
q: PlanQuestion,
|
||||
optionId: string,
|
||||
): boolean {
|
||||
function isOptionPicked(answers: PlanAnswers, q: PlanQuestion, optionId: string): boolean {
|
||||
const a = answers[q.id];
|
||||
if (!a) return false;
|
||||
if (Array.isArray(a)) return a.includes(optionId);
|
||||
@@ -384,15 +331,10 @@ function formatAnswer(q: PlanQuestion, answers: PlanAnswers): string {
|
||||
}
|
||||
const arr = a as string[];
|
||||
if (arr.length === 0) return "(not answered)";
|
||||
return arr
|
||||
.map((id) => q.options?.find((o) => o.id === id)?.label ?? id)
|
||||
.join(", ");
|
||||
return arr.map((id) => q.options?.find((o) => o.id === id)?.label ?? id).join(", ");
|
||||
}
|
||||
|
||||
export function formatPlanAnswers(
|
||||
questions: PlanQuestion[],
|
||||
answers: PlanAnswers,
|
||||
): string {
|
||||
export function formatPlanAnswers(questions: PlanQuestion[], answers: PlanAnswers): string {
|
||||
const parts: string[] = ["Here are my answers to the plan questions:\n"];
|
||||
|
||||
for (const q of questions) {
|
||||
|
||||
@@ -1,21 +1,16 @@
|
||||
import * as fs from "fs";
|
||||
import * as path from "path";
|
||||
import * as os from "os";
|
||||
import * as path from "path";
|
||||
|
||||
export function loadCustomInstructions(): string | null {
|
||||
const candidates = [
|
||||
path.join(process.cwd(), ".grok", "GROK.md"),
|
||||
path.join(os.homedir(), ".grok", "GROK.md"),
|
||||
];
|
||||
const candidates = [path.join(process.cwd(), ".grok", "GROK.md"), path.join(os.homedir(), ".grok", "GROK.md")];
|
||||
|
||||
for (const p of candidates) {
|
||||
try {
|
||||
if (fs.existsSync(p)) {
|
||||
return fs.readFileSync(p, "utf-8").trim();
|
||||
}
|
||||
} catch {
|
||||
continue;
|
||||
}
|
||||
} catch {}
|
||||
}
|
||||
|
||||
return null;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import * as fs from "fs";
|
||||
import * as path from "path";
|
||||
import * as os from "os";
|
||||
import { DEFAULT_MODEL, getModelIds } from "../grok/models.js";
|
||||
import * as path from "path";
|
||||
import { DEFAULT_MODEL, getModelIds } from "../grok/models";
|
||||
|
||||
export interface UserSettings {
|
||||
apiKey?: string;
|
||||
@@ -77,4 +77,4 @@ export function getCurrentModel(): string {
|
||||
if (project.model) return project.model;
|
||||
const user = loadUserSettings();
|
||||
return user.defaultModel || DEFAULT_MODEL;
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user