@hybridlabor-api/aos 4.8.0 โ 4.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.agents/agents.md +1 -1
- package/.agents/nodes.json +1 -1
- package/.agents/vendor-manifest.json +23 -1
- package/.claude/agents/godmode-media-eventtech.md +1 -1
- package/.claude/hooks/conventional-commits.mjs +125 -0
- package/.claude/hooks/env-file-protection.mjs +105 -0
- package/.claude/hooks/go-gate.mjs +101 -81
- package/.claude/settings.json +13 -0
- package/.opencode/agents/godmode-media-eventtech.md +1 -1
- package/.opencode/plugins/bdb-aos.js +31 -4
- package/README.de.md +1 -1
- package/README.md +1 -1
- package/README.pt.md +1 -1
- package/THIRD_PARTY_NOTICES.md +88 -0
- package/docs/skills_table.md +1 -1
- package/installer.js +174 -46
- package/package.json +6 -2
- package/packages/aos-cli/README.md +80 -0
- package/packages/aos-cli/bin/aos-cli.mjs +134 -0
- package/packages/aos-cli/core-skills.json +12 -0
- package/packages/aos-cli/extensions/aos.ts +321 -0
- package/packages/aos-cli/package-lock.json +1923 -0
- package/packages/aos-cli/package.json +29 -0
- package/packages/aos-cli/scripts/check-theme.mjs +63 -0
- package/packages/aos-cli/themes/aos.json +97 -0
- package/scripts/build-plugin-manifest.mjs +131 -0
- package/scripts/validate-skills.mjs +81 -6
- package/skills/basic/ao-orchestrator/SKILL.md +116 -0
- package/skills/global_config/agenttrail/SKILL.md +6 -1
- package/skills/global_config/ask-tim/SKILL.md +4 -4
- package/skills/global_config/bash-script-generator/SKILL.md +201 -0
- package/skills/global_config/bash-script-generator/assets/templates/standard-template.sh +96 -0
- package/skills/global_config/bash-script-generator/docs/bash-scripting-guide.md +729 -0
- package/skills/global_config/bash-script-generator/docs/generation-best-practices.md +193 -0
- package/skills/global_config/bash-script-generator/docs/script-patterns.md +566 -0
- package/skills/global_config/bash-script-generator/docs/text-processing-guide.md +437 -0
- package/skills/global_config/bash-script-generator/examples/log-analyzer.sh +92 -0
- package/skills/global_config/bash-script-generator/scripts/generate_script_template.sh +123 -0
- package/skills/global_config/bash-script-generator/scripts/run_ci_checks.sh +172 -0
- package/skills/global_config/bash-script-generator/scripts/test_generator.sh +413 -0
- package/skills/global_config/bash-script-validator/SKILL.md +249 -0
- package/skills/global_config/bash-script-validator/docs/awk-reference.md +449 -0
- package/skills/global_config/bash-script-validator/docs/bash-reference.md +468 -0
- package/skills/global_config/bash-script-validator/docs/common-mistakes.md +623 -0
- package/skills/global_config/bash-script-validator/docs/grep-reference.md +395 -0
- package/skills/global_config/bash-script-validator/docs/regex-reference.md +391 -0
- package/skills/global_config/bash-script-validator/docs/sed-reference.md +454 -0
- package/skills/global_config/bash-script-validator/docs/shell-reference.md +463 -0
- package/skills/global_config/bash-script-validator/docs/shellcheck-reference.md +399 -0
- package/skills/global_config/bash-script-validator/examples/bad-bash.sh +55 -0
- package/skills/global_config/bash-script-validator/examples/bad-shell.sh +54 -0
- package/skills/global_config/bash-script-validator/examples/good-bash.sh +71 -0
- package/skills/global_config/bash-script-validator/examples/good-shell.sh +69 -0
- package/skills/global_config/bash-script-validator/scripts/run_ci_checks.sh +23 -0
- package/skills/global_config/bash-script-validator/scripts/shellcheck_wrapper.sh +174 -0
- package/skills/global_config/bash-script-validator/scripts/test_validate.sh +446 -0
- package/skills/global_config/bash-script-validator/scripts/validate.sh +512 -0
- package/skills/global_config/ci-pipeline/SKILL.md +135 -0
- package/skills/global_config/dispatching-parallel-agents/SKILL.md +170 -0
- package/skills/global_config/dockerfile-generator/SKILL.md +1038 -0
- package/skills/global_config/dockerfile-generator/examples/example.dockerignore +95 -0
- package/skills/global_config/dockerfile-generator/examples/golang-distroless.Dockerfile +34 -0
- package/skills/global_config/dockerfile-generator/examples/java-springboot.Dockerfile +45 -0
- package/skills/global_config/dockerfile-generator/examples/nextjs-production.Dockerfile +49 -0
- package/skills/global_config/dockerfile-generator/examples/nodejs-multistage.Dockerfile +55 -0
- package/skills/global_config/dockerfile-generator/examples/python-fastapi.Dockerfile +48 -0
- package/skills/global_config/dockerfile-generator/references/language_specific_guides.md +510 -0
- package/skills/global_config/dockerfile-generator/references/multistage_builds.md +570 -0
- package/skills/global_config/dockerfile-generator/references/optimization_patterns.md +492 -0
- package/skills/global_config/dockerfile-generator/references/security_best_practices.md +375 -0
- package/skills/global_config/dockerfile-generator/scripts/generate_dockerignore.sh +199 -0
- package/skills/global_config/dockerfile-generator/scripts/generate_golang.sh +172 -0
- package/skills/global_config/dockerfile-generator/scripts/generate_java.sh +185 -0
- package/skills/global_config/dockerfile-generator/scripts/generate_nodejs.sh +279 -0
- package/skills/global_config/dockerfile-generator/scripts/generate_python.sh +218 -0
- package/skills/global_config/dockerfile-generator/scripts/test_generator.sh +210 -0
- package/skills/global_config/dockerfile-validator/SKILL.md +300 -0
- package/skills/global_config/dockerfile-validator/examples/.dockerignore.example +34 -0
- package/skills/global_config/dockerfile-validator/examples/bad-example.Dockerfile +37 -0
- package/skills/global_config/dockerfile-validator/examples/golang-distroless.Dockerfile +50 -0
- package/skills/global_config/dockerfile-validator/examples/good-example.Dockerfile +52 -0
- package/skills/global_config/dockerfile-validator/examples/python-optimized.Dockerfile +53 -0
- package/skills/global_config/dockerfile-validator/examples/security-issues.Dockerfile +42 -0
- package/skills/global_config/dockerfile-validator/references/docker_best_practices.md +348 -0
- package/skills/global_config/dockerfile-validator/references/optimization_guide.md +473 -0
- package/skills/global_config/dockerfile-validator/references/security_checklist.md +208 -0
- package/skills/global_config/dockerfile-validator/scripts/dockerfile-validate.sh +699 -0
- package/skills/global_config/dockerfile-validator/scripts/test_validate.sh +35 -0
- package/skills/global_config/dockerfile-validator/tests/fixtures/copy-before-yarn-lock-read.Dockerfile +6 -0
- package/skills/global_config/dockerfile-validator/tests/fixtures/copy-before-yarn.Dockerfile +6 -0
- package/skills/global_config/dockerfile-validator/tests/fixtures/from-platform-nonroot.Dockerfile +7 -0
- package/skills/global_config/dockerfile-validator/tests/test_regression.sh +164 -0
- package/skills/global_config/finishing-a-development-branch/SKILL.md +228 -0
- package/skills/global_config/github-actions-generator/SKILL.md +353 -0
- package/skills/global_config/github-actions-generator/assets/templates/action/composite/action.yml +82 -0
- package/skills/global_config/github-actions-generator/assets/templates/action/docker/Dockerfile +25 -0
- package/skills/global_config/github-actions-generator/assets/templates/action/docker/action.yml +42 -0
- package/skills/global_config/github-actions-generator/assets/templates/action/docker/entrypoint.sh +27 -0
- package/skills/global_config/github-actions-generator/assets/templates/action/javascript/action.yml +33 -0
- package/skills/global_config/github-actions-generator/assets/templates/action/javascript/index.js +50 -0
- package/skills/global_config/github-actions-generator/assets/templates/action/javascript/package.json +27 -0
- package/skills/global_config/github-actions-generator/assets/templates/workflow/basic_workflow.yml +242 -0
- package/skills/global_config/github-actions-generator/assets/templates/workflow/reusable_workflow.yml +106 -0
- package/skills/global_config/github-actions-generator/examples/README.md +147 -0
- package/skills/global_config/github-actions-generator/examples/actions/setup-node-cached/action.yml +93 -0
- package/skills/global_config/github-actions-generator/examples/caching/docker-buildkit.yml +256 -0
- package/skills/global_config/github-actions-generator/examples/security/dependency-review.yml +62 -0
- package/skills/global_config/github-actions-generator/examples/security/sbom-attestation.yml +119 -0
- package/skills/global_config/github-actions-generator/examples/triggers/chatops-commands.yml +475 -0
- package/skills/global_config/github-actions-generator/examples/triggers/repository-dispatch.yml +418 -0
- package/skills/global_config/github-actions-generator/examples/triggers/workflow-orchestration.yml +404 -0
- package/skills/global_config/github-actions-generator/examples/workflows/docker-build-push.yml +68 -0
- package/skills/global_config/github-actions-generator/examples/workflows/go-ci.yml +161 -0
- package/skills/global_config/github-actions-generator/examples/workflows/monorepo-ci.yml +340 -0
- package/skills/global_config/github-actions-generator/examples/workflows/multi-environment-deploy.yml +406 -0
- package/skills/global_config/github-actions-generator/examples/workflows/nodejs-ci.yml +122 -0
- package/skills/global_config/github-actions-generator/examples/workflows/python-ci.yml +157 -0
- package/skills/global_config/github-actions-generator/examples/workflows/scheduled-tasks.yml +376 -0
- package/skills/global_config/github-actions-generator/references/advanced-triggers.md +917 -0
- package/skills/global_config/github-actions-generator/references/best-practices.md +755 -0
- package/skills/global_config/github-actions-generator/references/common-actions.md +715 -0
- package/skills/global_config/github-actions-generator/references/custom-actions.md +320 -0
- package/skills/global_config/github-actions-generator/references/expressions-and-contexts.md +688 -0
- package/skills/global_config/github-actions-generator/references/modern-features.md +421 -0
- package/skills/global_config/github-actions-generator/scripts/test_generator.sh +344 -0
- package/skills/global_config/github-actions-templates/SKILL.md +7 -0
- package/skills/global_config/github-actions-validator/SKILL.md +576 -0
- package/skills/global_config/github-actions-validator/examples/README.md +88 -0
- package/skills/global_config/github-actions-validator/examples/outdated-versions.yml +76 -0
- package/skills/global_config/github-actions-validator/examples/valid-ci.yml +79 -0
- package/skills/global_config/github-actions-validator/examples/with-errors.yml +47 -0
- package/skills/global_config/github-actions-validator/references/act_usage.md +233 -0
- package/skills/global_config/github-actions-validator/references/action_versions.md +122 -0
- package/skills/global_config/github-actions-validator/references/actionlint_usage.md +343 -0
- package/skills/global_config/github-actions-validator/references/common_errors.md +512 -0
- package/skills/global_config/github-actions-validator/references/modern_features.md +384 -0
- package/skills/global_config/github-actions-validator/references/runners.md +317 -0
- package/skills/global_config/github-actions-validator/scripts/install_tools.sh +113 -0
- package/skills/global_config/github-actions-validator/scripts/validate_workflow.sh +910 -0
- package/skills/global_config/github-actions-validator/tests/test_validate_workflow.sh +237 -0
- package/skills/global_config/makefile-generator/SKILL.md +614 -0
- package/skills/global_config/makefile-generator/assets/templates/.gitkeep +1 -0
- package/skills/global_config/makefile-generator/docs/makefile-structure.md +530 -0
- package/skills/global_config/makefile-generator/docs/optimization-guide.md +784 -0
- package/skills/global_config/makefile-generator/docs/patterns-guide.md +642 -0
- package/skills/global_config/makefile-generator/docs/security-guide.md +361 -0
- package/skills/global_config/makefile-generator/docs/targets-guide.md +642 -0
- package/skills/global_config/makefile-generator/docs/variables-guide.md +596 -0
- package/skills/global_config/makefile-generator/scripts/add_standard_targets.sh +539 -0
- package/skills/global_config/makefile-generator/scripts/generate_makefile_template.sh +690 -0
- package/skills/global_config/makefile-generator/test/test_helper_scripts.sh +190 -0
- package/skills/global_config/makefile-validator/SKILL.md +244 -0
- package/skills/global_config/makefile-validator/docs/bake-tool.md +1000 -0
- package/skills/global_config/makefile-validator/docs/best-practices.md +858 -0
- package/skills/global_config/makefile-validator/docs/common-mistakes.md +944 -0
- package/skills/global_config/makefile-validator/examples/bad-makefile.mk +77 -0
- package/skills/global_config/makefile-validator/examples/good-makefile.mk +103 -0
- package/skills/global_config/makefile-validator/scripts/test_validate.sh +382 -0
- package/skills/global_config/makefile-validator/scripts/validate_makefile.sh +712 -0
- package/skills/global_config/{MCP_Manage โ mcp-manage}/SKILL.md +3 -3
- package/skills/global_config/requesting-code-review/SKILL.md +98 -0
- package/skills/global_config/requesting-code-review/code-reviewer.md +198 -0
- package/skills/global_config/using-git-worktrees/SKILL.md +170 -0
- package/skills/global_config/verification-before-completion/SKILL.md +123 -0
- package/skills/global_config/writing-plans/SKILL.md +126 -46
- package/skills/global_config/writing-plans-legacy/SKILL.md +139 -0
package/THIRD_PARTY_NOTICES.md
CHANGED
|
@@ -287,6 +287,94 @@ the upstream offensive exploit content is stripped and not carried over.
|
|
|
287
287
|
|
|
288
288
|
---
|
|
289
289
|
|
|
290
|
+
## obra/superpowers
|
|
291
|
+
|
|
292
|
+
<https://github.com/obra/superpowers> โ MIT. Copyright (c) 2025 Jesse Vincent.
|
|
293
|
+
|
|
294
|
+
Tracked in `.agents/vendor-manifest.json` at pinned commit
|
|
295
|
+
`8ca22dba9a94f28898bbce59f2537ff4d87c747d` (v6.4.2).
|
|
296
|
+
|
|
297
|
+
Five workflow skills are vendored under `skills/global_config/`, each carried
|
|
298
|
+
whole with its companion files: `verification-before-completion`,
|
|
299
|
+
`requesting-code-review` (plus `code-reviewer.md`),
|
|
300
|
+
`finishing-a-development-branch`, `using-git-worktrees`, and
|
|
301
|
+
`dispatching-parallel-agents`. A sixth, `writing-plans`, **replaces** the AOS
|
|
302
|
+
version of that skill; the superseded AOS original is kept alongside it as
|
|
303
|
+
`writing-plans-legacy` (`source: community`, marked `deprecated_by`) rather than
|
|
304
|
+
deleted.
|
|
305
|
+
|
|
306
|
+
AOS modifications: `category:`, `source:` and `date_added:` added to the
|
|
307
|
+
frontmatter; the `superpowers:` namespace prefix stripped from cross-skill
|
|
308
|
+
references so they resolve to AOS skill names. AOS adaptations to
|
|
309
|
+
`writing-plans`: the plan output path is kept at AOS's `docs/plans/` rather
|
|
310
|
+
than upstream's `docs/superpowers/plans/`, and the AOS `risk: critical` marker
|
|
311
|
+
is carried over.
|
|
312
|
+
|
|
313
|
+
AOS already vendored four other skills from this repository earlier
|
|
314
|
+
(`brainstorming`, `test-driven-development`, `executing-plans`,
|
|
315
|
+
`subagent-driven-development`) without recording it here. Those imports still
|
|
316
|
+
carry the `superpowers:` prefix in their cross-references.
|
|
317
|
+
|
|
318
|
+
---
|
|
319
|
+
|
|
320
|
+
## akin-ozer/cc-devops-skills
|
|
321
|
+
|
|
322
|
+
<https://github.com/akin-ozer/cc-devops-skills> โ Apache-2.0.
|
|
323
|
+
Copyright [yyyy] [name of copyright owner] (upstream ships the unfilled
|
|
324
|
+
Apache-2.0 notice).
|
|
325
|
+
|
|
326
|
+
Tracked in `.agents/vendor-manifest.json` at pinned commit
|
|
327
|
+
`276af751e659315aaf56d3ad13d7c26f4e72e28a`.
|
|
328
|
+
|
|
329
|
+
Four generator/validator pairs are vendored under `skills/global_config/`, each
|
|
330
|
+
carried whole including its `references/`, `scripts/`, `examples/`, `docs/` and
|
|
331
|
+
`test/` subtrees: `github-actions-generator` + `github-actions-validator`,
|
|
332
|
+
`dockerfile-generator` + `dockerfile-validator`, `bash-script-generator` +
|
|
333
|
+
`bash-script-validator`, `makefile-generator` + `makefile-validator`.
|
|
334
|
+
|
|
335
|
+
AOS modifications: `category:`, `source:` and `date_added:` added to the
|
|
336
|
+
frontmatter; the `devops-skills:` namespace prefix stripped from cross-skill
|
|
337
|
+
references so they resolve to AOS skill names; the Docker example user
|
|
338
|
+
`appuser` renamed to `app` throughout `dockerfile-generator` and
|
|
339
|
+
`dockerfile-validator` to satisfy the E-PATH01 username check.
|
|
340
|
+
|
|
341
|
+
---
|
|
342
|
+
|
|
343
|
+
## davila7/claude-code-templates
|
|
344
|
+
|
|
345
|
+
<https://github.com/davila7/claude-code-templates> โ MIT.
|
|
346
|
+
Copyright (c) 2025 Daniel (San) รvila.
|
|
347
|
+
|
|
348
|
+
`conventional-commits` (`.claude/hooks/conventional-commits.mjs`) and
|
|
349
|
+
`env-file-protection` (`.claude/hooks/env-file-protection.mjs`) are ported from
|
|
350
|
+
upstream's `conventional-commits.py` and `env-file-protection.json`, selected
|
|
351
|
+
from a set of 62 hooks. Tracked in `.agents/vendor-manifest.json`.
|
|
352
|
+
|
|
353
|
+
Both are ports, not verbatim copies, and the differences are behavioural:
|
|
354
|
+
|
|
355
|
+
- **Python to .mjs.** Upstream ships Python. Node is already a hard AOS install
|
|
356
|
+
dependency and every other AOS hook is `.mjs`; `python3` is absent on a stock
|
|
357
|
+
Windows install, where the installer also runs.
|
|
358
|
+
- **Both harnesses.** Upstream's `env-file-protection` is an inline `echo`
|
|
359
|
+
guarded by a matcher `if` field, which Antigravity and the Gemini CLI ignore โ
|
|
360
|
+
there it would fire on every write. The check lives in code instead, and both
|
|
361
|
+
hooks emit the Antigravity `{"decision":...}` stdout form as well as the
|
|
362
|
+
Claude Code stderr/exit-2 form.
|
|
363
|
+
- **`.env.example` and friends are allowed.** Upstream's matcher blocks
|
|
364
|
+
`.env*`, which contradicts its own advice to put new values in
|
|
365
|
+
`.env.example`. Templates (`example`, `sample`, `template`, `dist`) are
|
|
366
|
+
committed and hold no live secret, so they are exempt here.
|
|
367
|
+
- **Both hooks fail open.** An unreadable payload or an unextractable commit
|
|
368
|
+
message allows the call, unlike `go-gate`, which fails closed. A regex miss
|
|
369
|
+
must not wedge a commit.
|
|
370
|
+
|
|
371
|
+
Upstream's `secret-scanner`, `tdd-gate`, and `dangerous-command-blocker` were
|
|
372
|
+
reviewed and **not** shipped; they remain available on demand from the ECC
|
|
373
|
+
store. Reasons are in `docs/handover/` and the branch description for
|
|
374
|
+
`feat/cicd-skills-import`.
|
|
375
|
+
|
|
376
|
+
---
|
|
377
|
+
|
|
290
378
|
## Note on `mcps/`
|
|
291
379
|
|
|
292
380
|
Sub-repositories vendored under `mcps/` carry their own `LICENSE` files in
|
package/docs/skills_table.md
CHANGED
|
@@ -52,7 +52,7 @@
|
|
|
52
52
|
#### ๐จ Frontend & UI/UX
|
|
53
53
|
| Skill Name | Description |
|
|
54
54
|
|------------|-------------|
|
|
55
|
-
| `
|
|
55
|
+
| `mcp-manage` | Manages the BDB specialized MCP servers including Unreal Engine, Rhino 7/8, DaVinci Resolve, grandMA3, Resolume, GitHub, Chrome DevTools, and TouchDesigner. |
|
|
56
56
|
| `api-design-principles` | Master REST and GraphQL API design principles to build intuitive, scalable, and maintainable APIs that delight developers and stand the test of time. |
|
|
57
57
|
| `api-patterns` | API design principles and decision-making. REST vs GraphQL vs tRPC selection, response formats, versioning, pagination. |
|
|
58
58
|
| `bdbdesignpro` | Use when choosing an animation engine, defining motion tokens, adding scroll effects or micro-interactions, or auditing motion for accessibility and performance in BDB projects. Covers engine selection (GSAP, Motion.dev, Anime.js, React-Spring, Three.js, CSS Native), BDB brand-locked motion tokens, and the anti-slop/a11y quality gate. |
|
package/installer.js
CHANGED
|
@@ -115,8 +115,8 @@ if (mcpsArgRaw && mcpsArg === null) {
|
|
|
115
115
|
// not express that in a script or CI, and got Antigravity as their primary
|
|
116
116
|
// target instead. Values match the menu: 0 universal, 1 Antigravity,
|
|
117
117
|
// 2 Claude Desktop/Code, 3 Cursor, 4 custom, 5 Codex, 6 Windsurf, 7 Roo/Cline,
|
|
118
|
-
// 8 Aider (9 = project harness has its own --project-harness flag).
|
|
119
|
-
const VALID_PLATFORMS = ['0', '1', '2', '3', '4', '5', '6', '7', '8'];
|
|
118
|
+
// 8 Aider, 10 AOS CLI (9 = project harness has its own --project-harness flag).
|
|
119
|
+
const VALID_PLATFORMS = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '10'];
|
|
120
120
|
const platformsArgRaw = process.argv.find(a => a === '--platforms' || a.startsWith('--platforms='));
|
|
121
121
|
let PLATFORMS_ARG = null;
|
|
122
122
|
if (platformsArgRaw) {
|
|
@@ -1257,6 +1257,7 @@ function syncSkillsToGlobalHarnesses(excludeSkills = []) {
|
|
|
1257
1257
|
{ dir: path.join(homeDir, '.codex', 'skills'), key: 'codex' },
|
|
1258
1258
|
{ dir: path.join(homeDir, '.cursor', 'skills'), key: 'cursor' },
|
|
1259
1259
|
{ dir: path.join(homeDir, '.roo', 'skills'), key: 'vscode' },
|
|
1260
|
+
{ dir: process.platform === 'win32' ? path.join(process.env.APPDATA || homeDir, 'opencode', 'skills') : path.join(homeDir, '.config', 'opencode', 'skills'), key: 'opencode' },
|
|
1260
1261
|
].filter((d) => d.key === null || detectedKeys.has(d.key));
|
|
1261
1262
|
|
|
1262
1263
|
for (const { dir: dest } of extraSkillDestinations) {
|
|
@@ -1709,8 +1710,12 @@ function checkModuleUpdate(pkgName, targetDir) {
|
|
|
1709
1710
|
let remoteVer = null;
|
|
1710
1711
|
let checkFailed = false;
|
|
1711
1712
|
try {
|
|
1712
|
-
const
|
|
1713
|
-
|
|
1713
|
+
const npmCmd = process.platform === 'win32' ? 'npm.cmd' : 'npm';
|
|
1714
|
+
if (process.platform === 'win32') {
|
|
1715
|
+
remoteVer = execSync(`"${npmCmd}" view ${pkgName} version`, { stdio: ['ignore', 'pipe', 'ignore'], encoding: 'utf8', timeout: 4000 }).trim();
|
|
1716
|
+
} else {
|
|
1717
|
+
remoteVer = execFileSync(npmCmd, ['view', pkgName, 'version'], { stdio: ['ignore', 'pipe', 'ignore'], encoding: 'utf8', timeout: 4000 }).trim();
|
|
1718
|
+
}
|
|
1714
1719
|
} catch (e) {
|
|
1715
1720
|
// Offline, a proxy, or a misconfigured registry. Swallowing this
|
|
1716
1721
|
// made every module report "up to date" forever on such a machine,
|
|
@@ -1805,15 +1810,40 @@ function downloadOrUpdateModule(pkgName, targetDir, displayName) {
|
|
|
1805
1810
|
}
|
|
1806
1811
|
}
|
|
1807
1812
|
|
|
1813
|
+
// Phase 1: retire the live tree. On Windows a running daemon holds open
|
|
1814
|
+
// file handles into targetDir โ retry with brief backoff before failing.
|
|
1815
|
+
// ponytail: 3 retries ร 600ms; escalate to process kill if this ceiling matters
|
|
1816
|
+
let phase1Done = false;
|
|
1817
|
+
for (let attempt = 0; attempt < 3 && !phase1Done; attempt++) {
|
|
1818
|
+
try {
|
|
1819
|
+
fs.renameSync(targetDir, retiredDir);
|
|
1820
|
+
phase1Done = true;
|
|
1821
|
+
} catch (retireError) {
|
|
1822
|
+
const retriable = retireError.code === 'EPERM' || retireError.code === 'EBUSY';
|
|
1823
|
+
if (retriable && attempt < 2) {
|
|
1824
|
+
const delayMs = 600 * (attempt + 1);
|
|
1825
|
+
try {
|
|
1826
|
+
if (process.platform === 'win32') {
|
|
1827
|
+
execSync(`powershell -NoProfile -Command "Start-Sleep -Milliseconds ${delayMs}"`, { stdio: 'ignore' });
|
|
1828
|
+
} else {
|
|
1829
|
+
execSync(`sleep ${delayMs / 1000}`, { stdio: 'ignore' });
|
|
1830
|
+
}
|
|
1831
|
+
} catch (_) {}
|
|
1832
|
+
continue;
|
|
1833
|
+
}
|
|
1834
|
+
safeRmDirSync(stagingDir);
|
|
1835
|
+
throw retireError;
|
|
1836
|
+
}
|
|
1837
|
+
}
|
|
1838
|
+
|
|
1839
|
+
// Phase 2: promote the staging tree. stagingDir was just unpacked and
|
|
1840
|
+
// has no open handles, so a single attempt is sufficient.
|
|
1808
1841
|
try {
|
|
1809
|
-
fs.renameSync(targetDir, retiredDir);
|
|
1810
1842
|
fs.renameSync(stagingDir, targetDir);
|
|
1811
|
-
} catch (
|
|
1812
|
-
|
|
1813
|
-
try { fs.renameSync(retiredDir, targetDir); } catch (_) {}
|
|
1814
|
-
}
|
|
1843
|
+
} catch (promoteError) {
|
|
1844
|
+
try { fs.renameSync(retiredDir, targetDir); } catch (_) {}
|
|
1815
1845
|
safeRmDirSync(stagingDir);
|
|
1816
|
-
throw
|
|
1846
|
+
throw promoteError;
|
|
1817
1847
|
}
|
|
1818
1848
|
|
|
1819
1849
|
// On Windows especially, deleting a directory that was just renamed or contains
|
|
@@ -1886,6 +1916,21 @@ async function installMemB(interactive) {
|
|
|
1886
1916
|
}));
|
|
1887
1917
|
}
|
|
1888
1918
|
const membDir = path.join(moduleBasePath(), 'memB');
|
|
1919
|
+
// On Windows the memB WebUI process holds open file handles inside membDir.
|
|
1920
|
+
// The atomic rename inside downloadOrUpdateModule fails with EPERM as long as
|
|
1921
|
+
// those handles are live โ retry backoff cannot help. Kill the process on
|
|
1922
|
+
// port 8088 before attempting the download so the rename succeeds.
|
|
1923
|
+
if (process.platform === 'win32') {
|
|
1924
|
+
try {
|
|
1925
|
+
execSync(
|
|
1926
|
+
'powershell -NoProfile -Command "' +
|
|
1927
|
+
'Get-NetTCPConnection -LocalPort 8088 -ErrorAction SilentlyContinue |' +
|
|
1928
|
+
' Select-Object -ExpandProperty OwningProcess |' +
|
|
1929
|
+
' ForEach-Object { Stop-Process -Id $_ -Force -ErrorAction SilentlyContinue }"',
|
|
1930
|
+
{ stdio: 'ignore' }
|
|
1931
|
+
);
|
|
1932
|
+
} catch (_) {}
|
|
1933
|
+
}
|
|
1889
1934
|
// A failed download used to fall through into venv setup and daemon
|
|
1890
1935
|
// registration, each of which then failed on its own terms or, worse,
|
|
1891
1936
|
// "succeeded" against a stale tree -- and the run still ended in a success
|
|
@@ -2561,10 +2606,15 @@ async function installOSAgentWorkspace() {
|
|
|
2561
2606
|
execFileSync(binTarget, ['service', 'install'], { stdio: 'ignore' });
|
|
2562
2607
|
}, 'Start it by hand with: ao service install');
|
|
2563
2608
|
|
|
2564
|
-
|
|
2609
|
+
// Windows startup entries fire asynchronously โ give the service more time
|
|
2610
|
+
const aoTimeout = process.platform === 'win32' ? 20000 : 8000;
|
|
2611
|
+
if (await verifyDaemonListening(3101, 'AO Orchestrator', aoTimeout)) {
|
|
2565
2612
|
log.success('AO Orchestrator running on http://localhost:3101');
|
|
2566
2613
|
} else {
|
|
2567
|
-
|
|
2614
|
+
const hint = process.platform === 'win32'
|
|
2615
|
+
? 'Run `ao service install` again or log out and back in, then check `ao service status`.'
|
|
2616
|
+
: 'Check `ao service status` and `ao service logs`.';
|
|
2617
|
+
log.warn(`AO did not answer on :3101 โ ${hint}`);
|
|
2568
2618
|
}
|
|
2569
2619
|
}
|
|
2570
2620
|
async function promptMemBIngestion(mcpCodeTarget) {
|
|
@@ -2638,8 +2688,10 @@ function verifyEcosystemInstallation() {
|
|
|
2638
2688
|
let newerVersion = null;
|
|
2639
2689
|
let newerTag = null;
|
|
2640
2690
|
try {
|
|
2641
|
-
const
|
|
2642
|
-
const distTagsJson =
|
|
2691
|
+
const npmCmd = process.platform === 'win32' ? 'npm.cmd' : 'npm';
|
|
2692
|
+
const distTagsJson = process.platform === 'win32'
|
|
2693
|
+
? execSync(`"${npmCmd}" view ${mod.pkg} dist-tags --json`, { stdio: ['ignore', 'pipe', 'ignore'], encoding: 'utf8', timeout: 4000 }).trim()
|
|
2694
|
+
: execFileSync(npmCmd, ['view', mod.pkg, 'dist-tags', '--json'], { stdio: ['ignore', 'pipe', 'ignore'], encoding: 'utf8', timeout: 4000 }).trim();
|
|
2643
2695
|
const distTags = JSON.parse(distTagsJson);
|
|
2644
2696
|
for (const [tag, ver] of Object.entries(distTags)) {
|
|
2645
2697
|
if (isNewerVersion(localVer, ver)) {
|
|
@@ -2685,7 +2737,7 @@ function verifyEcosystemInstallation() {
|
|
|
2685
2737
|
|
|
2686
2738
|
console.log('');
|
|
2687
2739
|
console.log(` ${colors.bold}โโโ BDB Agent OS Dashboard โโโ${colors.reset}`);
|
|
2688
|
-
console.log(` Interactive Control Center:
|
|
2740
|
+
console.log(` Interactive Control Center: aos-dashboard`);
|
|
2689
2741
|
console.log(` ${colors.dim}(Live status & service control at http://127.0.0.1:7900)${colors.reset}`);
|
|
2690
2742
|
}
|
|
2691
2743
|
|
|
@@ -3625,23 +3677,23 @@ function injectHarnessRules() {
|
|
|
3625
3677
|
// that adds or changes a hook silently never received it -- which is exactly
|
|
3626
3678
|
// what happened to memb-inject.mjs in v4.4.0, on the machines that needed it
|
|
3627
3679
|
// most (a fresh install got it; every machine that already had AOS did not).
|
|
3628
|
-
function installGlobalHooks() {
|
|
3680
|
+
function installGlobalHooks({ targetHome = homeDir, targetGemini = geminiDir } = {}) {
|
|
3629
3681
|
const hooksSrc = path.join(srcDir, '.claude', 'hooks');
|
|
3630
3682
|
const workflowsSrc = path.join(srcDir, '.claude', 'workflows');
|
|
3631
3683
|
|
|
3632
3684
|
// 1. Claude Code
|
|
3633
3685
|
if (fs.existsSync(hooksSrc)) {
|
|
3634
|
-
copyDirRecursiveSync(hooksSrc, path.join(
|
|
3635
|
-
log.step(`Installed hooks to ${path.join(
|
|
3686
|
+
copyDirRecursiveSync(hooksSrc, path.join(targetHome, '.claude', 'hooks'));
|
|
3687
|
+
log.step(`Installed hooks to ${path.join(targetHome, '.claude', 'hooks')}`);
|
|
3636
3688
|
}
|
|
3637
3689
|
if (fs.existsSync(workflowsSrc)) {
|
|
3638
|
-
copyDirRecursiveSync(workflowsSrc, path.join(
|
|
3690
|
+
copyDirRecursiveSync(workflowsSrc, path.join(targetHome, '.claude', 'workflows'));
|
|
3639
3691
|
}
|
|
3640
|
-
mergeBdbSettingsHooks(path.join(
|
|
3692
|
+
mergeBdbSettingsHooks(path.join(targetHome, '.claude', 'settings.json'));
|
|
3641
3693
|
|
|
3642
3694
|
// 2. Google Antigravity
|
|
3643
|
-
const agyHooksDir = path.join(
|
|
3644
|
-
const agyWorkflowsDir = path.join(
|
|
3695
|
+
const agyHooksDir = path.join(targetGemini, 'config', 'hooks');
|
|
3696
|
+
const agyWorkflowsDir = path.join(targetGemini, 'config', 'workflows');
|
|
3645
3697
|
if (fs.existsSync(hooksSrc)) {
|
|
3646
3698
|
copyDirRecursiveSync(hooksSrc, agyHooksDir);
|
|
3647
3699
|
log.step(`Installed hooks to ${agyHooksDir}`);
|
|
@@ -3649,14 +3701,24 @@ function installGlobalHooks() {
|
|
|
3649
3701
|
if (fs.existsSync(workflowsSrc)) {
|
|
3650
3702
|
copyDirRecursiveSync(workflowsSrc, agyWorkflowsDir);
|
|
3651
3703
|
}
|
|
3652
|
-
mergeAntigravityHooks(path.join(
|
|
3653
|
-
|
|
3654
|
-
|
|
3704
|
+
mergeAntigravityHooks(path.join(targetGemini, 'config', 'hooks.json'));
|
|
3705
|
+
const agyCliDir = path.join(targetGemini, 'antigravity-cli');
|
|
3706
|
+
if (fs.existsSync(agyCliDir)) {
|
|
3707
|
+
const agyCliHooksDir = path.join(agyCliDir, 'hooks');
|
|
3708
|
+
const agyCliWorkflowsDir = path.join(agyCliDir, 'workflows');
|
|
3709
|
+
if (fs.existsSync(hooksSrc)) {
|
|
3710
|
+
copyDirRecursiveSync(hooksSrc, agyCliHooksDir);
|
|
3711
|
+
log.step(`Installed hooks to ${agyCliHooksDir}`);
|
|
3712
|
+
}
|
|
3713
|
+
if (fs.existsSync(workflowsSrc)) {
|
|
3714
|
+
copyDirRecursiveSync(workflowsSrc, agyCliWorkflowsDir);
|
|
3715
|
+
}
|
|
3716
|
+
mergeAntigravityHooks(path.join(agyCliDir, 'hooks.json'));
|
|
3655
3717
|
}
|
|
3656
3718
|
|
|
3657
3719
|
// 3. OpenAI Codex CLI
|
|
3658
|
-
const codexHooksDir = path.join(
|
|
3659
|
-
const codexWorkflowsDir = path.join(
|
|
3720
|
+
const codexHooksDir = path.join(targetHome, '.codex', 'hooks');
|
|
3721
|
+
const codexWorkflowsDir = path.join(targetHome, '.codex', 'workflows');
|
|
3660
3722
|
if (fs.existsSync(hooksSrc)) {
|
|
3661
3723
|
copyDirRecursiveSync(hooksSrc, codexHooksDir);
|
|
3662
3724
|
log.step(`Installed hooks to ${codexHooksDir}`);
|
|
@@ -3664,12 +3726,12 @@ function installGlobalHooks() {
|
|
|
3664
3726
|
if (fs.existsSync(workflowsSrc)) {
|
|
3665
3727
|
copyDirRecursiveSync(workflowsSrc, codexWorkflowsDir);
|
|
3666
3728
|
}
|
|
3667
|
-
mergeCodexTomlHooks(path.join(
|
|
3729
|
+
mergeCodexTomlHooks(path.join(targetHome, '.codex', 'config.toml'));
|
|
3668
3730
|
|
|
3669
3731
|
// 4. OpenCode CLI
|
|
3670
3732
|
const opencodeDir = process.platform === 'win32'
|
|
3671
|
-
? path.join(process.env.APPDATA ||
|
|
3672
|
-
: path.join(
|
|
3733
|
+
? path.join(process.env.APPDATA || targetHome, 'opencode')
|
|
3734
|
+
: path.join(targetHome, '.config', 'opencode');
|
|
3673
3735
|
const opencodePluginSrc = path.join(srcDir, '.opencode', 'plugins', 'bdb-aos.js');
|
|
3674
3736
|
if (fs.existsSync(opencodePluginSrc)) {
|
|
3675
3737
|
const opencodePluginsDir = path.join(opencodeDir, 'plugins');
|
|
@@ -3745,7 +3807,7 @@ function installGlobalBinaries() {
|
|
|
3745
3807
|
// merged result goes to a .bdb-new.json sidecar -- the same recovery pattern
|
|
3746
3808
|
// the MCP config merge in installMcpsForTarget uses.
|
|
3747
3809
|
function mergeBdbSettingsHooks(settingsPath, { projectLocal = false } = {}) {
|
|
3748
|
-
const bdbHookScripts = ['go-gate.mjs', 'graph-gate.mjs', 'memb-inject.mjs', 'trail-relay.mjs'];
|
|
3810
|
+
const bdbHookScripts = ['go-gate.mjs', 'graph-gate.mjs', 'memb-inject.mjs', 'trail-relay.mjs', 'conventional-commits.mjs', 'env-file-protection.mjs'];
|
|
3749
3811
|
// memb-inject reads the machine-global memB store under $HOME and is
|
|
3750
3812
|
// installed once per machine, so it stays $HOME-anchored even inside a
|
|
3751
3813
|
// project harness -- unlike the two gate hooks, which are per-checkout by
|
|
@@ -3817,7 +3879,7 @@ function mergeBdbSettingsHooks(settingsPath, { projectLocal = false } = {}) {
|
|
|
3817
3879
|
// Merge the BDB hooks into Google Antigravity's hooks.json (.agents/hooks.json or
|
|
3818
3880
|
// ~/.gemini/config/hooks.json), preserving user-defined foreign hooks.
|
|
3819
3881
|
function mergeAntigravityHooks(hooksPath, { projectLocal = false } = {}) {
|
|
3820
|
-
const bdbHookScripts = ['go-gate.mjs', 'graph-gate.mjs', 'memb-inject.mjs', 'startcycle-dispatch.mjs', 'trail-relay.mjs'];
|
|
3882
|
+
const bdbHookScripts = ['go-gate.mjs', 'graph-gate.mjs', 'memb-inject.mjs', 'startcycle-dispatch.mjs', 'trail-relay.mjs', 'conventional-commits.mjs', 'env-file-protection.mjs'];
|
|
3821
3883
|
const isBdbEntry = (entry) => {
|
|
3822
3884
|
const cmds = (entry && Array.isArray(entry.hooks) ? entry.hooks : [entry])
|
|
3823
3885
|
.map((h) => (h && typeof h.command === 'string' ? h.command : (typeof h === 'string' ? h : '')))
|
|
@@ -3834,7 +3896,14 @@ function mergeAntigravityHooks(hooksPath, { projectLocal = false } = {}) {
|
|
|
3834
3896
|
PreToolUse: [
|
|
3835
3897
|
{
|
|
3836
3898
|
matcher: "run_command|Bash",
|
|
3837
|
-
hooks: [
|
|
3899
|
+
hooks: [
|
|
3900
|
+
{ type: "command", command: `node "${path.join(hooksDir, 'go-gate.mjs')}"`, timeout: 10000 },
|
|
3901
|
+
{ type: "command", command: `node "${path.join(hooksDir, 'conventional-commits.mjs')}"`, timeout: 10000 }
|
|
3902
|
+
]
|
|
3903
|
+
},
|
|
3904
|
+
{
|
|
3905
|
+
matcher: "write_file|edit_file|replace|Write|Edit|MultiEdit",
|
|
3906
|
+
hooks: [{ type: "command", command: `node "${path.join(hooksDir, 'env-file-protection.mjs')}"`, timeout: 10000 }]
|
|
3838
3907
|
},
|
|
3839
3908
|
{
|
|
3840
3909
|
hooks: [{ type: "command", command: `node "${path.join(globalHooksDir, 'trail-relay.mjs')}" --agent agy --event PreToolUse`, timeout: 2000 }]
|
|
@@ -4856,18 +4925,24 @@ async function runQuickUpdate(installState) {
|
|
|
4856
4925
|
injectHarnessRules();
|
|
4857
4926
|
}, 'Harness files keep whatever version this machine already had.');
|
|
4858
4927
|
|
|
4859
|
-
// OpenWiki
|
|
4860
|
-
//
|
|
4861
|
-
//
|
|
4862
|
-
//
|
|
4863
|
-
// that case, so this is a no-op confirm for anyone already configured and a
|
|
4864
|
-
// real one-time offer for anyone who isn't (including installs from before
|
|
4865
|
-
// this feature existed).
|
|
4928
|
+
// OpenWiki: if already configured, refresh the daemon silently (no prompt).
|
|
4929
|
+
// Only ask when there is no key yet โ i.e. a first-time offer or a machine
|
|
4930
|
+
// that predates this feature. This avoids the "keep existing?" confirmation
|
|
4931
|
+
// on every Quick Update for users who have already set up OpenWiki.
|
|
4866
4932
|
if (!isAutoYes) {
|
|
4867
|
-
const
|
|
4868
|
-
|
|
4869
|
-
|
|
4933
|
+
const _owEnv = loadExistingEnv(paths.targetMcpDir);
|
|
4934
|
+
const _owProvider = _owEnv['OPENWIKI_PROVIDER'] || 'google';
|
|
4935
|
+
const _owKeyName = PROVIDER_KEY_ENV_NAMES[_owProvider] || 'GEMINI_API_KEY';
|
|
4936
|
+
const _owKey = _owEnv[_owKeyName] || _owEnv['GEMINI_API_KEY'] || _owEnv['GOOGLE_API_KEY'] || _owEnv['OPENWIKI_API_KEY'] || '';
|
|
4937
|
+
if (_owKey || _owProvider === 'ollama') {
|
|
4938
|
+
await installOpenWikiDaemon(_owKey, paths.targetSkillDir, { provider: _owProvider, model: _owEnv['OPENWIKI_MODEL'] || '', baseUrl: _owEnv['OPENWIKI_BASE_URL'] || '' });
|
|
4870
4939
|
await installOpenWikiVisualizer();
|
|
4940
|
+
} else {
|
|
4941
|
+
const creds = await promptCredentials(paths.targetMcpDir);
|
|
4942
|
+
if (creds !== BACK) {
|
|
4943
|
+
await installOpenWikiDaemon(creds.gemini, paths.targetSkillDir, { provider: creds.openwikiProvider, model: creds.openwikiModel, baseUrl: creds.openwikiBaseUrl });
|
|
4944
|
+
await installOpenWikiVisualizer();
|
|
4945
|
+
}
|
|
4871
4946
|
}
|
|
4872
4947
|
}
|
|
4873
4948
|
|
|
@@ -4920,6 +4995,40 @@ function buildAoAnnouncementBanner() {
|
|
|
4920
4995
|
].join('\n');
|
|
4921
4996
|
}
|
|
4922
4997
|
|
|
4998
|
+
// AOS CLI ships as a separate npm package under packages/ for one reason: pi
|
|
4999
|
+
// updates on its own cadence, and folding it into this release cycle would turn
|
|
5000
|
+
// every pi bump into a full AOS reinstall. So it installs as an ordinary global
|
|
5001
|
+
// package and pulls pi in as its own dependency -- and it writes nothing to
|
|
5002
|
+
// ~/.agents, because it reads that directory rather than owning it.
|
|
5003
|
+
function installAosCli() {
|
|
5004
|
+
const pkgDir = path.join(srcDir, 'packages', 'aos-cli');
|
|
5005
|
+
const manual = 'cd packages/aos-cli && npm install -g .';
|
|
5006
|
+
|
|
5007
|
+
if (!fs.existsSync(path.join(pkgDir, 'package.json'))) {
|
|
5008
|
+
log.warn(`AOS CLI package missing at ${pkgDir} -- skipped. Install it later: ${manual}`);
|
|
5009
|
+
return;
|
|
5010
|
+
}
|
|
5011
|
+
if (hasExecutable('aos-cli')) {
|
|
5012
|
+
log.step('aos-cli is already on PATH.');
|
|
5013
|
+
return;
|
|
5014
|
+
}
|
|
5015
|
+
if (DRY_RUN) {
|
|
5016
|
+
log.step('[dry-run] would run: npm install -g <packages/aos-cli>');
|
|
5017
|
+
return;
|
|
5018
|
+
}
|
|
5019
|
+
|
|
5020
|
+
const res = installStep('install AOS CLI', () => {
|
|
5021
|
+
log.step('Installing AOS CLI globally (pi is installed as its dependency)...');
|
|
5022
|
+
execSync(`npm install -g ${JSON.stringify(pkgDir)}`, { stdio: 'ignore' });
|
|
5023
|
+
}, `The rest of AOS is installed. Install AOS CLI later: ${manual}`);
|
|
5024
|
+
|
|
5025
|
+
if (res.ok && hasExecutable('aos-cli')) {
|
|
5026
|
+
log.success('AOS CLI installed -- run `aos-cli`.');
|
|
5027
|
+
} else if (res.ok) {
|
|
5028
|
+
log.warn('AOS CLI is installed but `aos-cli` is not on PATH. launchd and some Windows shells start with a PATH that omits npm\'s global bin.');
|
|
5029
|
+
}
|
|
5030
|
+
}
|
|
5031
|
+
|
|
4923
5032
|
async function main() {
|
|
4924
5033
|
if (process.argv[2] === 'store') {
|
|
4925
5034
|
const storeScript = path.join(srcDir, 'bin', 'aos-store.mjs');
|
|
@@ -5061,6 +5170,7 @@ async function main() {
|
|
|
5061
5170
|
{ value: '7', label: 'Roo Code / Cline / VS Code', hint: '~/.roo' },
|
|
5062
5171
|
{ value: '8', label: 'Aider CLI', hint: '~/.aider' },
|
|
5063
5172
|
{ value: '9', label: '๐ Local Project Harness', hint: 'copy dispatcher contract to current project' },
|
|
5173
|
+
{ value: '10', label: '๐ฅ๏ธ AOS CLI', hint: 'pi harness -- reads ~/.agents, no own skill copy' },
|
|
5064
5174
|
{ value: '4', label: 'โ๏ธ Custom Installation', hint: 'specify paths manually' }
|
|
5065
5175
|
];
|
|
5066
5176
|
|
|
@@ -5090,7 +5200,7 @@ async function main() {
|
|
|
5090
5200
|
selectedMcps = await promptMcpSelection(tier);
|
|
5091
5201
|
} else {
|
|
5092
5202
|
const ctx = { tier: '1', selectedPlatforms: ['0'], mode: 'merge', customPaths: null, creds: null, selectedMcps: null };
|
|
5093
|
-
const platformNames = { '0': '๐ Universal Harness', '1': 'Google Antigravity', '2': 'Claude Desktop/Code', '3': 'Cursor/Generic IDE', '4': 'Custom Paths', '5': 'ChatGPT Codex CLI', '6': 'Windsurf', '7': 'Roo Code / Cline / VS Code', '8': 'Aider CLI', '9': 'Local Project Harness' };
|
|
5203
|
+
const platformNames = { '0': '๐ Universal Harness', '1': 'Google Antigravity', '2': 'Claude Desktop/Code', '3': 'Cursor/Generic IDE', '4': 'Custom Paths', '5': 'ChatGPT Codex CLI', '6': 'Windsurf', '7': 'Roo Code / Cline / VS Code', '8': 'Aider CLI', '9': 'Local Project Harness', '10': 'AOS CLI' };
|
|
5094
5204
|
|
|
5095
5205
|
const stepTier = async () => {
|
|
5096
5206
|
const t = await selectWithBack({
|
|
@@ -5256,7 +5366,22 @@ async function main() {
|
|
|
5256
5366
|
fs.mkdirSync(backupDir, { recursive: true, mode: 0o700 });
|
|
5257
5367
|
}, 'The installation continues, but existing files are not backed up.');
|
|
5258
5368
|
|
|
5259
|
-
|
|
5369
|
+
// '10' is an action, not a directory target. AOS CLI reads
|
|
5370
|
+
// ~/.agents/skills, which syncSkillsToGlobalHarnesses() already writes --
|
|
5371
|
+
// left in this list it would fall through resolveTargetPaths()'s universal
|
|
5372
|
+
// defaults and install a second full copy of every skill somewhere nobody
|
|
5373
|
+
// reads them from.
|
|
5374
|
+
const aosCliRequested = specificPlatforms.includes('10');
|
|
5375
|
+
const dirPlatforms = specificPlatforms.filter(p => p !== '10');
|
|
5376
|
+
|
|
5377
|
+
if (aosCliRequested && dirPlatforms.length === 0) {
|
|
5378
|
+
// AOS CLI alone would have no skills to load, and an empty target list
|
|
5379
|
+
// leaves primaryTarget undefined for everything downstream of it.
|
|
5380
|
+
log.warn('AOS CLI was the only target -- adding the universal skill target so it has something to load.');
|
|
5381
|
+
dirPlatforms.push('1');
|
|
5382
|
+
}
|
|
5383
|
+
|
|
5384
|
+
const targets = dirPlatforms.map(p => ({
|
|
5260
5385
|
value: p,
|
|
5261
5386
|
...resolveTargetPaths(p, customPaths)
|
|
5262
5387
|
}));
|
|
@@ -5343,10 +5468,13 @@ async function main() {
|
|
|
5343
5468
|
// Flush file-level install manifest after all writes are done.
|
|
5344
5469
|
flushSessionManifest();
|
|
5345
5470
|
|
|
5471
|
+
// After the skill sync, because AOS CLI is useless without ~/.agents.
|
|
5472
|
+
if (aosCliRequested) installAosCli();
|
|
5473
|
+
|
|
5346
5474
|
console.log('');
|
|
5347
5475
|
verifyEcosystemInstallation();
|
|
5348
5476
|
|
|
5349
|
-
outro(`๐ Installation complete! Targets: ${targets.map(t => t.value).join(', ')} ยท Tier: ${tier === '1' ? 'Pro MEDIA' : 'Basic'}${DRY_RUN ? ' ยท DRY-RUN (nothing was modified)' : ''}`);
|
|
5477
|
+
outro(`๐ Installation complete! Targets: ${targets.map(t => t.value).join(', ')}${aosCliRequested ? ' + AOS CLI' : ''} ยท Tier: ${tier === '1' ? 'Pro MEDIA' : 'Basic'}${DRY_RUN ? ' ยท DRY-RUN (nothing was modified)' : ''}`);
|
|
5350
5478
|
}
|
|
5351
5479
|
|
|
5352
5480
|
if (require.main === module) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hybridlabor-api/aos",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.9.0",
|
|
4
4
|
"description": "AOS โ A Curated AI AGENT OS. Optimized agent skills and add-ons like memB, OpenWiki, Heimdall Token Saver, and Godmode architectures.",
|
|
5
5
|
"main": "installer.js",
|
|
6
6
|
"engines": {
|
|
@@ -24,8 +24,10 @@
|
|
|
24
24
|
"validate": "node scripts/validate-skills.mjs",
|
|
25
25
|
"validate:strict": "node scripts/validate-skills.mjs --strict",
|
|
26
26
|
"store:index": "node scripts/build-ecc-store-index.mjs",
|
|
27
|
+
"plugin:build": "node scripts/build-plugin-manifest.mjs",
|
|
28
|
+
"plugin:check": "node scripts/build-plugin-manifest.mjs --check",
|
|
27
29
|
"doctor": "node bin/aos-doctor.mjs",
|
|
28
|
-
"test": "node scripts/validate-skills.mjs --selftest && node scripts/validate-skills.mjs && node tests/aos-store.test.mjs && node tests/aos-doctor.test.mjs"
|
|
30
|
+
"test": "node scripts/validate-skills.mjs --selftest && node scripts/validate-skills.mjs && node scripts/build-plugin-manifest.mjs --check && node tests/aos-store.test.mjs && node tests/aos-doctor.test.mjs && node tests/build-plugin-manifest.test.mjs"
|
|
29
31
|
},
|
|
30
32
|
"publishConfig": {
|
|
31
33
|
"access": "public"
|
|
@@ -58,6 +60,8 @@
|
|
|
58
60
|
"mcps/",
|
|
59
61
|
"scripts/",
|
|
60
62
|
"vendor/",
|
|
63
|
+
"packages/aos-cli/",
|
|
64
|
+
"!packages/aos-cli/node_modules",
|
|
61
65
|
"!mcps/**/*.png",
|
|
62
66
|
"!mcps/**/*.jpg",
|
|
63
67
|
"!mcps/**/*.jpeg",
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
# AOS CLI
|
|
2
|
+
|
|
3
|
+
The AOS dispatcher contract and AOS skills, on the [pi](https://github.com/earendil-works/pi) coding agent.
|
|
4
|
+
|
|
5
|
+
```
|
|
6
|
+
aos-cli
|
|
7
|
+
aos-cli "why is the go build failing"
|
|
8
|
+
aos-cli --continue
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Which skills are loaded
|
|
12
|
+
|
|
13
|
+
**Ten, not all of them.** pi advertises every discovered skill by name and description in *every* system prompt. Measured on this machine: 210 skills, **~11,150 tokens per request**, of which the four `firecrawl` entries alone are ~2,250. That is a permanent tax on every turn.
|
|
14
|
+
|
|
15
|
+
`core-skills.json` narrows that to the handful worth having always:
|
|
16
|
+
|
|
17
|
+
```
|
|
18
|
+
ask-tim aos-setup aos-project-init mcp-manage systematic-debugging
|
|
19
|
+
planning-with-files token-saver-config archify deja-memory grill-me
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
Edit the file. It is a flat list of directory names under `~/.agents/skills/`, nothing more.
|
|
23
|
+
|
|
24
|
+
**The tradeoff, stated plainly:** a skill outside that list is not merely unadvertised โ it is unreachable, `/skill:name` included. That is the cost of `--no-skills`, and it is why `aos-store` is how one gets added. If you want a skill in every session, put it in the list.
|
|
25
|
+
|
|
26
|
+
Names that are not installed are skipped with a note rather than being fatal: the list should quietly shrink when a skill is pruned, not stop pi from starting.
|
|
27
|
+
|
|
28
|
+
## In-session commands
|
|
29
|
+
|
|
30
|
+
| | |
|
|
31
|
+
|---|---|
|
|
32
|
+
| `/aos-status` | Runs `aos-doctor --json` and shows every check, with the failing ones marked |
|
|
33
|
+
| `/aos` | Menu: status, or the command to run outside for install / update / uninstall |
|
|
34
|
+
|
|
35
|
+
Both are **read-only**. `aos-doctor --json` exits 1 whenever a check is not ok, which is the normal "something needs attention" answer, so the exit code is ignored and the report's own `ok` field decides. The install, update and uninstall entries do not spawn the installer: it animates and prompts, and nesting it inside pi's TUI corrupts both renderers. They report the command to run in a separate terminal instead.
|
|
36
|
+
|
|
37
|
+
## What it actually is
|
|
38
|
+
|
|
39
|
+
A launcher, not a reimplementation. It adds three things to a plain `pi`:
|
|
40
|
+
|
|
41
|
+
| | |
|
|
42
|
+
|---|---|
|
|
43
|
+
| **AOS theme** | `themes/aos.json` โ pi's `dark`, with the AOS palette (purple, amethyst, gold, forge, emerald, beige) |
|
|
44
|
+
| **Dispatcher graph** | `~/.agents/AGENTS.md` appended to the system prompt |
|
|
45
|
+
| **AOS skills** | nothing to do โ pi already discovers `~/.agents/skills` (Agent Skills spec) |
|
|
46
|
+
|
|
47
|
+
Everything else โ the agent loop, the model providers, the TUI, sessions, MCP-less tool use โ is pi's. AOS CLI does not fork pi and does not wrap it; it starts it with three flags.
|
|
48
|
+
|
|
49
|
+
## What it deliberately does not do
|
|
50
|
+
|
|
51
|
+
**It does not depend on `@hybridlabor-api/aos`.** It reads `~/.agents/` at runtime, which the `aos` installer writes. That is the whole contract:
|
|
52
|
+
|
|
53
|
+
- AOS CLI and the AOS installer version and update independently. A pi update never drags in a 98 MB AOS reinstall.
|
|
54
|
+
- AOS CLI runs without AOS installed โ it just starts with no AOS skills and says so.
|
|
55
|
+
- **It is not a pipeline executor.** The 7-node dispatcher graph reaches pi as instructions in `~/.agents/AGENTS.md`, not as machinery: the nodes are agent definitions, and the main session acts as the dispatcher, which is what `.agents/graph.md` specifies anyway. There is no `state.json` loop.
|
|
56
|
+
- **No MCP.** pi has no MCP client, so memB, deja and mcsc are not available here. AOS CLI is a chat + skills harness; the other seven harnesses remain the machinery.
|
|
57
|
+
|
|
58
|
+
## Install
|
|
59
|
+
|
|
60
|
+
Through the AOS installer (picks this up automatically once the menu entry lands), or directly:
|
|
61
|
+
|
|
62
|
+
```sh
|
|
63
|
+
npm i -g @earendil-works/pi-coding-agent # if you do not have pi yet
|
|
64
|
+
cd packages/aos-cli && npm i && npm link
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
Requires Node >= 22.19 โ pi's floor. The AOS installer itself still supports Node >= 20, because AOS CLI is a separate install step.
|
|
68
|
+
|
|
69
|
+
## Layout
|
|
70
|
+
|
|
71
|
+
```
|
|
72
|
+
bin/aos-cli.mjs the launcher (~40 lines)
|
|
73
|
+
themes/aos.json pi dark theme, AOS palette
|
|
74
|
+
extensions/aos.ts /aos and /aos-status
|
|
75
|
+
scripts/check-theme.mjs theme contract guard, run by `npm test`
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
## Licence
|
|
79
|
+
|
|
80
|
+
MIT, same as AOS. pi is MIT, ยฉ the pi authors.
|