From 643f33a317b160840edd9a10d136e80970102082 Mon Sep 17 00:00:00 2001 From: Sergey Ochkasov Date: Wed, 6 May 2026 09:30:32 +0300 Subject: [PATCH] fix(deps): move ai-factory to dependencies, probe at agent boot MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The agent invokes the ai-factory CLI at task-run time to scaffold .ai-factory/ inside every user project (packages/runtime/projectInit.ts). This is a hard runtime requirement, not a developer-only convenience — yet the package was declared in devDependencies. With npm ci --omit=dev or NODE_ENV=production npm install, ai-factory is not installed; the runtime then falls back to `npx ai-factory ...`, which silently requires network access to the npm registry at task time. In air-gapped or offline-deployed installations every task fails with a buried "Project .ai-factory/ scaffold missing" warning. Changes: - Move `ai-factory` from devDependencies to dependencies in root package.json. Reflowed package-lock.json: lines that look unrelated (libc array drops, dev→peer flag flips on optional native binaries) come from npm 10.9.7 normalising the existing lockfile and are not deliberate edits. - Probe `require.resolve('ai-factory/bin/ai-factory.js')` at agent boot (packages/agent/src/index.ts). Log a clear warning if the CLI is not resolvable so the failure is diagnosable from the first agent log line, instead of surfacing later as a per-task skip. - Document the requirement in the README Quick Start so installers know why ai-factory must be in node_modules and what happens otherwise. No behavioural change for default `npm install` flows — ai-factory was already resolvable; this PR makes it resolvable for production install modes as well. --- README.md | 8 ++ package-lock.json | 175 ++++++++++++------------------------ package.json | 4 +- packages/agent/src/index.ts | 24 +++++ 4 files changed, 91 insertions(+), 120 deletions(-) diff --git a/README.md b/README.md index 93f0f1b7..49a949dd 100644 --- a/README.md +++ b/README.md @@ -49,6 +49,14 @@ npm run dev Set `MCP_PORT` in your shell or root `.env` before `npm run dev` if you also want the MCP HTTP server in local development. Use an integer port between `1` and `65535`; invalid values are ignored by the dev launcher and the settings install route falls back to the local `stdio` entry instead of writing an HTTP MCP endpoint. +> **`ai-factory` is a required runtime dependency**, not an optional plugin. The agent uses +> the `ai-factory` CLI to scaffold `.ai-factory/` inside every project you create through the +> UI. It is declared in the root `package.json` and is installed automatically by `npm install`. +> If you install with `npm ci --omit=dev` or `NODE_ENV=production npm install`, make sure +> `ai-factory` ends up in `node_modules/` — otherwise the agent falls back to `npx ai-factory ...` +> at task-run time, which requires network access to the npm registry. The agent logs a clear +> warning at boot when the CLI is not resolvable. + ### With Docker ```bash diff --git a/package-lock.json b/package-lock.json index b0a389e5..d9876011 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,9 +11,11 @@ "workspaces": [ "packages/*" ], + "dependencies": { + "ai-factory": "^2.10.0" + }, "devDependencies": { "@vitest/coverage-v8": "^4.1.2", - "ai-factory": "^2.10.0", "eslint": "^9.39.4", "eslint-plugin-react-hooks": "^7.0.1", "globals": "^17.4.0", @@ -1493,9 +1495,6 @@ "cpu": [ "arm" ], - "libc": [ - "glibc" - ], "license": "LGPL-3.0-or-later", "optional": true, "os": [ @@ -1512,9 +1511,6 @@ "cpu": [ "arm64" ], - "libc": [ - "glibc" - ], "license": "LGPL-3.0-or-later", "optional": true, "os": [ @@ -1531,9 +1527,6 @@ "cpu": [ "x64" ], - "libc": [ - "glibc" - ], "license": "LGPL-3.0-or-later", "optional": true, "os": [ @@ -1550,9 +1543,6 @@ "cpu": [ "arm64" ], - "libc": [ - "musl" - ], "license": "LGPL-3.0-or-later", "optional": true, "os": [ @@ -1569,9 +1559,6 @@ "cpu": [ "x64" ], - "libc": [ - "musl" - ], "license": "LGPL-3.0-or-later", "optional": true, "os": [ @@ -1588,9 +1575,6 @@ "cpu": [ "arm" ], - "libc": [ - "glibc" - ], "license": "Apache-2.0", "optional": true, "os": [ @@ -1613,9 +1597,6 @@ "cpu": [ "arm64" ], - "libc": [ - "glibc" - ], "license": "Apache-2.0", "optional": true, "os": [ @@ -1638,9 +1619,6 @@ "cpu": [ "x64" ], - "libc": [ - "glibc" - ], "license": "Apache-2.0", "optional": true, "os": [ @@ -1663,9 +1641,6 @@ "cpu": [ "arm64" ], - "libc": [ - "musl" - ], "license": "Apache-2.0", "optional": true, "os": [ @@ -1688,9 +1663,6 @@ "cpu": [ "x64" ], - "libc": [ - "musl" - ], "license": "Apache-2.0", "optional": true, "os": [ @@ -1748,7 +1720,6 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/@inquirer/external-editor/-/external-editor-1.0.3.tgz", "integrity": "sha512-RWbSrDiYmO4LbejWY7ttpxczuwQyZLBUyygsA9Nsv95hpzUWwnNTVQmAq3xuh7vNwCp07UTmE5i11XAEExx4RA==", - "dev": true, "license": "MIT", "dependencies": { "chardet": "^2.1.1", @@ -1770,7 +1741,6 @@ "version": "1.0.15", "resolved": "https://registry.npmjs.org/@inquirer/figures/-/figures-1.0.15.tgz", "integrity": "sha512-t2IEY+unGHOzAaVM5Xx6DEWKeXlDDcNPeDyUpsRc6CUhBfU3VQOEl+Vssh7VNp1dR8MdUJBWhuObjXCsVpjN5g==", - "dev": true, "license": "MIT", "engines": { "node": ">=18" @@ -2086,6 +2056,7 @@ "os": [ "android" ], + "peer": true, "engines": { "node": "^20.19.0 || >=22.12.0" } @@ -2103,6 +2074,7 @@ "os": [ "darwin" ], + "peer": true, "engines": { "node": "^20.19.0 || >=22.12.0" } @@ -2120,6 +2092,7 @@ "os": [ "darwin" ], + "peer": true, "engines": { "node": "^20.19.0 || >=22.12.0" } @@ -2137,6 +2110,7 @@ "os": [ "freebsd" ], + "peer": true, "engines": { "node": "^20.19.0 || >=22.12.0" } @@ -2154,6 +2128,7 @@ "os": [ "linux" ], + "peer": true, "engines": { "node": "^20.19.0 || >=22.12.0" } @@ -2166,14 +2141,12 @@ "arm64" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ "linux" ], + "peer": true, "engines": { "node": "^20.19.0 || >=22.12.0" } @@ -2186,14 +2159,12 @@ "arm64" ], "dev": true, - "libc": [ - "musl" - ], "license": "MIT", "optional": true, "os": [ "linux" ], + "peer": true, "engines": { "node": "^20.19.0 || >=22.12.0" } @@ -2206,14 +2177,12 @@ "ppc64" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ "linux" ], + "peer": true, "engines": { "node": "^20.19.0 || >=22.12.0" } @@ -2226,14 +2195,12 @@ "s390x" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ "linux" ], + "peer": true, "engines": { "node": "^20.19.0 || >=22.12.0" } @@ -2246,14 +2213,12 @@ "x64" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ "linux" ], + "peer": true, "engines": { "node": "^20.19.0 || >=22.12.0" } @@ -2266,14 +2231,12 @@ "x64" ], "dev": true, - "libc": [ - "musl" - ], "license": "MIT", "optional": true, "os": [ "linux" ], + "peer": true, "engines": { "node": "^20.19.0 || >=22.12.0" } @@ -2291,6 +2254,7 @@ "os": [ "openharmony" ], + "peer": true, "engines": { "node": "^20.19.0 || >=22.12.0" } @@ -2305,6 +2269,7 @@ "dev": true, "license": "MIT", "optional": true, + "peer": true, "dependencies": { "@emnapi/core": "1.9.2", "@emnapi/runtime": "1.9.2", @@ -2327,6 +2292,7 @@ "os": [ "win32" ], + "peer": true, "engines": { "node": "^20.19.0 || >=22.12.0" } @@ -2344,6 +2310,7 @@ "os": [ "win32" ], + "peer": true, "engines": { "node": "^20.19.0 || >=22.12.0" } @@ -2495,9 +2462,6 @@ "arm64" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -2515,9 +2479,6 @@ "arm64" ], "dev": true, - "libc": [ - "musl" - ], "license": "MIT", "optional": true, "os": [ @@ -2535,9 +2496,6 @@ "x64" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -2555,9 +2513,6 @@ "x64" ], "dev": true, - "libc": [ - "musl" - ], "license": "MIT", "optional": true, "os": [ @@ -3482,7 +3437,6 @@ "version": "2.10.0", "resolved": "https://registry.npmjs.org/ai-factory/-/ai-factory-2.10.0.tgz", "integrity": "sha512-wp8fCh77mxjsV4dEmuPYAQ7l9sr7MstHQIKSnYISdM8kvwuc/cc3r4qmfnCt19P/L/uk01KmfwYQ4EygBiE6Xg==", - "dev": true, "license": "MIT", "dependencies": { "chalk": "^5.3.0", @@ -3558,7 +3512,6 @@ "version": "4.3.2", "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", - "dev": true, "license": "MIT", "dependencies": { "type-fest": "^0.21.3" @@ -3574,7 +3527,6 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -3928,7 +3880,6 @@ "version": "5.6.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.6.2.tgz", "integrity": "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==", - "dev": true, "license": "MIT", "engines": { "node": "^12.17.0 || ^14.13 || >=16.0.0" @@ -3981,7 +3932,6 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/chardet/-/chardet-2.1.1.tgz", "integrity": "sha512-PsezH1rqdV9VvyNhxxOW32/d75r01NY7TQCmOqomRo15ZSOKbpTFVsfjghxo6JloQUCGnH4k1LGu0R4yCLlWQQ==", - "dev": true, "license": "MIT" }, "node_modules/chownr": { @@ -4022,7 +3972,6 @@ "version": "2.9.2", "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.9.2.tgz", "integrity": "sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==", - "dev": true, "license": "MIT", "engines": { "node": ">=6" @@ -4098,7 +4047,6 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-4.1.0.tgz", "integrity": "sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ==", - "dev": true, "license": "ISC", "engines": { "node": ">= 12" @@ -4108,7 +4056,6 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", "integrity": "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==", - "dev": true, "license": "MIT", "engines": { "node": ">=0.8" @@ -4127,7 +4074,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, "license": "MIT", "dependencies": { "color-name": "~1.1.4" @@ -4140,7 +4086,6 @@ "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true, "license": "MIT" }, "node_modules/colorette": { @@ -4164,7 +4109,6 @@ "version": "12.1.0", "resolved": "https://registry.npmjs.org/commander/-/commander-12.1.0.tgz", "integrity": "sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==", - "dev": true, "license": "MIT", "engines": { "node": ">=18" @@ -4368,7 +4312,6 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.4.tgz", "integrity": "sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==", - "dev": true, "license": "MIT", "dependencies": { "clone": "^1.0.2" @@ -5092,7 +5035,6 @@ "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true, "license": "MIT" }, "node_modules/encodeurl": { @@ -5729,7 +5671,6 @@ "version": "11.3.4", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.4.tgz", "integrity": "sha512-CTXd6rk/M3/ULNQj8FBqBWHYBVYybQ3VPBw0xGKFe3tuH7ytT6ACnvzpIQ3UZtB8yvUKC2cXn1a+x+5EVQLovA==", - "dev": true, "license": "MIT", "dependencies": { "graceful-fs": "^4.2.0", @@ -5751,6 +5692,7 @@ "os": [ "darwin" ], + "peer": true, "engines": { "node": "^8.16.0 || ^10.6.0 || >=11.0.0" } @@ -5885,14 +5827,12 @@ "version": "4.2.11", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", - "dev": true, "license": "ISC" }, "node_modules/has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -6159,7 +6099,6 @@ "version": "9.3.8", "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-9.3.8.tgz", "integrity": "sha512-pFGGdaHrmRKMh4WoDDSowddgjT1Vkl90atobmTeSmcPGdYiwikch/m/Ef5wRaiamHejtw0cUUMMerzDUXCci2w==", - "dev": true, "license": "MIT", "dependencies": { "@inquirer/external-editor": "^1.0.2", @@ -6284,7 +6223,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz", "integrity": "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==", - "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -6319,7 +6257,6 @@ "version": "0.1.0", "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", - "dev": true, "license": "MIT", "engines": { "node": ">=10" @@ -6533,7 +6470,6 @@ "version": "6.2.1", "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.2.1.tgz", "integrity": "sha512-zwOTdL3rFQ/lRdBnntKVOX6k5cKJwEc1HdilT71BWEu7J41gXIB2MRp+vxduPSwZJPWBxEzv4yH1wYLJGUHX4Q==", - "dev": true, "license": "MIT", "dependencies": { "universalify": "^2.0.0" @@ -6609,6 +6545,7 @@ "os": [ "android" ], + "peer": true, "engines": { "node": ">= 12.0.0" }, @@ -6630,6 +6567,7 @@ "os": [ "darwin" ], + "peer": true, "engines": { "node": ">= 12.0.0" }, @@ -6651,6 +6589,7 @@ "os": [ "darwin" ], + "peer": true, "engines": { "node": ">= 12.0.0" }, @@ -6672,6 +6611,7 @@ "os": [ "freebsd" ], + "peer": true, "engines": { "node": ">= 12.0.0" }, @@ -6693,6 +6633,7 @@ "os": [ "linux" ], + "peer": true, "engines": { "node": ">= 12.0.0" }, @@ -6709,14 +6650,12 @@ "arm64" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MPL-2.0", "optional": true, "os": [ "linux" ], + "peer": true, "engines": { "node": ">= 12.0.0" }, @@ -6733,14 +6672,12 @@ "arm64" ], "dev": true, - "libc": [ - "musl" - ], "license": "MPL-2.0", "optional": true, "os": [ "linux" ], + "peer": true, "engines": { "node": ">= 12.0.0" }, @@ -6757,14 +6694,12 @@ "x64" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MPL-2.0", "optional": true, "os": [ "linux" ], + "peer": true, "engines": { "node": ">= 12.0.0" }, @@ -6781,14 +6716,12 @@ "x64" ], "dev": true, - "libc": [ - "musl" - ], "license": "MPL-2.0", "optional": true, "os": [ "linux" ], + "peer": true, "engines": { "node": ">= 12.0.0" }, @@ -6810,6 +6743,7 @@ "os": [ "win32" ], + "peer": true, "engines": { "node": ">= 12.0.0" }, @@ -6831,6 +6765,7 @@ "os": [ "win32" ], + "peer": true, "engines": { "node": ">= 12.0.0" }, @@ -6990,7 +6925,6 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", - "dev": true, "license": "MIT", "dependencies": { "chalk": "^4.1.0", @@ -7007,7 +6941,6 @@ "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, "license": "MIT", "dependencies": { "color-convert": "^2.0.1" @@ -7023,7 +6956,6 @@ "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", @@ -8159,7 +8091,6 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", - "dev": true, "license": "MIT", "engines": { "node": ">=6" @@ -8238,7 +8169,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-1.0.0.tgz", "integrity": "sha512-avsJQhyd+680gKXyG/sQc0nXaC6rBkPOfyHYcFb9+hdkqQkR9bdnkJ0AMZhke0oesPqIO+mFFJ+IdBc7mst4IA==", - "dev": true, "license": "ISC", "engines": { "node": "^14.17.0 || ^16.13.0 || >=18.0.0" @@ -8404,7 +8334,6 @@ "version": "5.4.1", "resolved": "https://registry.npmjs.org/ora/-/ora-5.4.1.tgz", "integrity": "sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==", - "dev": true, "license": "MIT", "dependencies": { "bl": "^4.1.0", @@ -8428,7 +8357,6 @@ "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, "license": "MIT", "dependencies": { "color-convert": "^2.0.1" @@ -8444,7 +8372,6 @@ "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", @@ -8461,7 +8388,6 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", - "dev": true, "license": "MIT", "dependencies": { "restore-cursor": "^3.1.0" @@ -8474,7 +8400,6 @@ "version": "5.1.2", "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", - "dev": true, "license": "MIT", "dependencies": { "mimic-fn": "^2.1.0" @@ -8490,7 +8415,6 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", - "dev": true, "license": "MIT", "dependencies": { "onetime": "^5.1.0", @@ -8504,7 +8428,6 @@ "version": "3.0.7", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", - "dev": true, "license": "ISC" }, "node_modules/p-limit": { @@ -9251,7 +9174,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/run-async/-/run-async-3.0.0.tgz", "integrity": "sha512-540WwVDOMxA6dN6We19EcT9sc3hkXPw5mzRNGM3FkdN/vtE9NFvj5lFAPNwUDmJjXidm3v7TC1cTE7t17Ulm1Q==", - "dev": true, "license": "MIT", "engines": { "node": ">=0.12.0" @@ -9261,7 +9183,6 @@ "version": "7.8.2", "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.2.tgz", "integrity": "sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==", - "dev": true, "license": "Apache-2.0", "dependencies": { "tslib": "^2.1.0" @@ -9676,7 +9597,6 @@ "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, "license": "MIT", "dependencies": { "emoji-regex": "^8.0.0", @@ -9691,7 +9611,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -9715,7 +9634,6 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, "license": "MIT", "dependencies": { "ansi-regex": "^5.0.1" @@ -9772,7 +9690,6 @@ "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, "license": "MIT", "dependencies": { "has-flag": "^4.0.0" @@ -10036,6 +9953,7 @@ "os": [ "aix" ], + "peer": true, "engines": { "node": ">=18" } @@ -10053,6 +9971,7 @@ "os": [ "android" ], + "peer": true, "engines": { "node": ">=18" } @@ -10070,6 +9989,7 @@ "os": [ "android" ], + "peer": true, "engines": { "node": ">=18" } @@ -10087,6 +10007,7 @@ "os": [ "android" ], + "peer": true, "engines": { "node": ">=18" } @@ -10104,6 +10025,7 @@ "os": [ "darwin" ], + "peer": true, "engines": { "node": ">=18" } @@ -10121,6 +10043,7 @@ "os": [ "darwin" ], + "peer": true, "engines": { "node": ">=18" } @@ -10138,6 +10061,7 @@ "os": [ "freebsd" ], + "peer": true, "engines": { "node": ">=18" } @@ -10155,6 +10079,7 @@ "os": [ "freebsd" ], + "peer": true, "engines": { "node": ">=18" } @@ -10172,6 +10097,7 @@ "os": [ "linux" ], + "peer": true, "engines": { "node": ">=18" } @@ -10189,6 +10115,7 @@ "os": [ "linux" ], + "peer": true, "engines": { "node": ">=18" } @@ -10206,6 +10133,7 @@ "os": [ "linux" ], + "peer": true, "engines": { "node": ">=18" } @@ -10223,6 +10151,7 @@ "os": [ "linux" ], + "peer": true, "engines": { "node": ">=18" } @@ -10240,6 +10169,7 @@ "os": [ "linux" ], + "peer": true, "engines": { "node": ">=18" } @@ -10257,6 +10187,7 @@ "os": [ "linux" ], + "peer": true, "engines": { "node": ">=18" } @@ -10274,6 +10205,7 @@ "os": [ "linux" ], + "peer": true, "engines": { "node": ">=18" } @@ -10291,6 +10223,7 @@ "os": [ "linux" ], + "peer": true, "engines": { "node": ">=18" } @@ -10308,6 +10241,7 @@ "os": [ "linux" ], + "peer": true, "engines": { "node": ">=18" } @@ -10325,6 +10259,7 @@ "os": [ "netbsd" ], + "peer": true, "engines": { "node": ">=18" } @@ -10342,6 +10277,7 @@ "os": [ "netbsd" ], + "peer": true, "engines": { "node": ">=18" } @@ -10359,6 +10295,7 @@ "os": [ "openbsd" ], + "peer": true, "engines": { "node": ">=18" } @@ -10376,6 +10313,7 @@ "os": [ "openbsd" ], + "peer": true, "engines": { "node": ">=18" } @@ -10393,6 +10331,7 @@ "os": [ "openharmony" ], + "peer": true, "engines": { "node": ">=18" } @@ -10410,6 +10349,7 @@ "os": [ "sunos" ], + "peer": true, "engines": { "node": ">=18" } @@ -10427,6 +10367,7 @@ "os": [ "win32" ], + "peer": true, "engines": { "node": ">=18" } @@ -10444,6 +10385,7 @@ "os": [ "win32" ], + "peer": true, "engines": { "node": ">=18" } @@ -10461,6 +10403,7 @@ "os": [ "win32" ], + "peer": true, "engines": { "node": ">=18" } @@ -10554,7 +10497,6 @@ "version": "0.21.3", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", - "dev": true, "license": "(MIT OR CC0-1.0)", "engines": { "node": ">=10" @@ -10723,7 +10665,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", - "dev": true, "license": "MIT", "engines": { "node": ">= 10.0.0" @@ -11007,7 +10948,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", "integrity": "sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==", - "dev": true, "license": "MIT", "dependencies": { "defaults": "^1.0.3" @@ -11094,7 +11034,6 @@ "version": "6.2.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", - "dev": true, "license": "MIT", "dependencies": { "ansi-styles": "^4.0.0", @@ -11109,7 +11048,6 @@ "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, "license": "MIT", "dependencies": { "color-convert": "^2.0.1" @@ -11204,7 +11142,6 @@ "version": "2.1.3", "resolved": "https://registry.npmjs.org/yoctocolors-cjs/-/yoctocolors-cjs-2.1.3.tgz", "integrity": "sha512-U/PBtDf35ff0D8X8D0jfdzHYEPFxAI7jJlxZXwCSez5M3190m+QobIfh+sWDWSHMCWWJN2AWamkegn6vr6YBTw==", - "dev": true, "license": "MIT", "engines": { "node": ">=18" diff --git a/package.json b/package.json index 5852371f..f02dab9f 100644 --- a/package.json +++ b/package.json @@ -47,9 +47,11 @@ "lint-staged": { "*.{ts,tsx,js,jsx,json,md,css}": "prettier --write" }, + "dependencies": { + "ai-factory": "^2.10.0" + }, "devDependencies": { "@vitest/coverage-v8": "^4.1.2", - "ai-factory": "^2.10.0", "eslint": "^9.39.4", "eslint-plugin-react-hooks": "^7.0.1", "globals": "^17.4.0", diff --git a/packages/agent/src/index.ts b/packages/agent/src/index.ts index c35e556d..660703a0 100644 --- a/packages/agent/src/index.ts +++ b/packages/agent/src/index.ts @@ -1,3 +1,4 @@ +import { createRequire } from "node:module"; import { createDbUsageSink, listProjects } from "@aif/data"; import { getEnv, logger } from "@aif/shared"; import { bootstrapRuntimeRegistry } from "@aif/runtime"; @@ -11,6 +12,29 @@ import { startLoginBroker, type BrokerServer } from "./codex/loginBroker.js"; const log = logger("agent"); +// `ai-factory` is a hard runtime dependency: the runtime layer invokes its +// CLI to scaffold `.ai-factory/` for every new project (see +// `@aif/runtime/projectInit`). If it is missing locally, the runtime falls +// back to `npx ai-factory ...`, which requires network access and a registry +// hit at task-run time — fragile in air-gapped or production deploys +// installed with `npm ci --omit=dev`. Probe at boot and warn loudly so the +// failure is diagnosable from the first agent log line, not buried under a +// later "skipped task" warning. +function probeAiFactory(): void { + const localRequire = createRequire(import.meta.url); + try { + localRequire.resolve("ai-factory/bin/ai-factory.js"); + } catch { + log.warn( + "ai-factory CLI is not installed locally. The agent will fall back to " + + "`npx ai-factory ...` for project scaffolding, which requires network " + + "access. Add `ai-factory` to dependencies (not devDependencies) and " + + "reinstall to make this offline-safe.", + ); + } +} +probeAiFactory(); + // Validate env const env = getEnv();