@jaimevalasek/aioson 1.21.0 → 1.21.4
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/CHANGELOG.md +26 -1
- package/docs/pt/living-memory/reflexao-in-harness.md +2 -0
- package/package.json +1 -1
- package/src/agents.js +23 -22
- package/src/cli.js +48 -20
- package/src/commands/agent-audit.js +189 -119
- package/src/commands/artifact-validate.js +31 -14
- package/src/commands/context-health.js +205 -36
- package/src/commands/devlog-process.js +35 -13
- package/src/commands/feature-close.js +36 -0
- package/src/commands/learning.js +98 -19
- package/src/commands/live.js +48 -22
- package/src/commands/memory-archive.js +193 -193
- package/src/commands/memory-reflect-commit.js +28 -4
- package/src/commands/memory-restore.js +177 -177
- package/src/commands/memory-search.js +135 -135
- package/src/commands/memory-trim.js +191 -0
- package/src/commands/preflight.js +16 -7
- package/src/commands/quality-audit.js +119 -0
- package/src/commands/skill-audit.js +200 -0
- package/src/commands/squad-playbook.js +100 -0
- package/src/commands/squad-role-scan.js +188 -0
- package/src/commands/state-save.js +9 -7
- package/src/commands/workflow-execute.js +172 -32
- package/src/commands/workflow-next.js +148 -40
- package/src/commands/workflow-status.js +54 -22
- package/src/constants.js +1 -0
- package/src/current-state-trim.js +170 -0
- package/src/handoff-contract.js +11 -6
- package/src/i18n/messages/en.js +25 -7
- package/src/i18n/messages/es.js +19 -5
- package/src/i18n/messages/fr.js +19 -5
- package/src/i18n/messages/pt-BR.js +25 -7
- package/src/learning-import-claude.js +218 -0
- package/src/learning-loop-engine.js +268 -254
- package/src/learning-loop-migration.js +177 -163
- package/src/learning-materialize.js +192 -0
- package/src/lib/quality/provider.js +132 -0
- package/src/lib/quality/report.js +82 -0
- package/src/lib/quality/result.js +185 -0
- package/src/memory-reflect-engine.js +10 -4
- package/src/parser.js +5 -4
- package/src/preflight-engine.js +49 -22
- package/src/runtime-store.js +2 -1
- package/template/.aioson/agents/analyst.md +18 -6
- package/template/.aioson/agents/architect.md +3 -0
- package/template/.aioson/agents/committer.md +6 -6
- package/template/.aioson/agents/copywriter.md +27 -27
- package/template/.aioson/agents/dev.md +60 -41
- package/template/.aioson/agents/deyvin.md +44 -32
- package/template/.aioson/agents/discovery-design-doc.md +27 -13
- package/template/.aioson/agents/genome.md +81 -82
- package/template/.aioson/agents/manifests/dev.manifest.json +5 -4
- package/template/.aioson/agents/manifests/deyvin.manifest.json +4 -3
- package/template/.aioson/agents/neo.md +1 -1
- package/template/.aioson/agents/orchestrator.md +1 -1
- package/template/.aioson/agents/pentester.md +3 -2
- package/template/.aioson/agents/product.md +27 -19
- package/template/.aioson/agents/qa.md +8 -4
- package/template/.aioson/agents/setup.md +1 -1
- package/template/.aioson/agents/sheldon.md +1 -0
- package/template/.aioson/agents/site-forge.md +17 -19
- package/template/.aioson/agents/squad.md +4 -0
- package/template/.aioson/agents/tester.md +180 -153
- package/template/.aioson/agents/ux-ui.md +1 -1
- package/template/.aioson/config/autonomy-protocol.json +1 -0
- package/template/.aioson/config.md +12 -12
- package/template/.aioson/context/design-doc.md +136 -136
- package/template/.aioson/context/project-map.md +7 -5
- package/template/.aioson/context/seeds/seed-example.md +27 -27
- package/template/.aioson/context/user-profile.md +42 -42
- package/template/.aioson/design-docs/agent-loading-contract.md +117 -0
- package/template/.aioson/docs/dev/simple-plan-lane.md +92 -0
- package/template/.aioson/docs/product/conversation-playbook.md +15 -17
- package/template/.aioson/docs/quality/code-health-analysis.md +79 -0
- package/template/.aioson/docs/site-forge-build.md +2 -2
- package/template/.aioson/docs/site-forge-recon.md +5 -5
- package/template/.aioson/docs/squad/creation-flow.md +55 -0
- package/template/.aioson/docs/squad/eval-gate.md +79 -0
- package/template/.aioson/docs/squad/package-contract.md +39 -6
- package/template/.aioson/docs/squad/persona-grounding.md +62 -0
- package/template/.aioson/docs/squad/quality-lens.md +12 -1
- package/template/.aioson/genomes/INDEX.md +37 -37
- package/template/.aioson/genomes/copywriting/references/application-notes.md +2 -2
- package/template/.aioson/genomes/copywriting/references/frameworks/pms-research.md +1 -1
- package/template/.aioson/genomes/copywriting-brunson/references/application-notes.md +2 -2
- package/template/.aioson/learnings/gotchas/.gitkeep +1 -0
- package/template/.aioson/learnings/recipes/.gitkeep +1 -0
- package/template/.aioson/rules/agent-language-policy.md +21 -21
- package/template/.aioson/rules/agent-structural-contract.md +2 -2
- package/template/.aioson/rules/aioson-context-boundary.md +8 -6
- package/template/.aioson/rules/canonical-path-contract.md +10 -5
- package/template/.aioson/rules/data-format-convention.md +11 -11
- package/template/.aioson/rules/disk-first-artifacts.md +5 -4
- package/template/.aioson/rules/prd-section-ownership.md +12 -12
- package/template/.aioson/rules/simple-plan-lane.md +48 -0
- package/template/.aioson/rules/spec-level-ownership.md +5 -4
- package/template/.aioson/schemas/squad-blueprint.schema.json +32 -11
- package/template/.aioson/schemas/squad-manifest.schema.json +29 -8
- package/template/.aioson/skills/design/clean-saas-ui/SKILL.md +4 -4
- package/template/.aioson/skills/design/clean-saas-ui/references/art-direction.md +30 -30
- package/template/.aioson/skills/design/clean-saas-ui/references/motion.md +4 -4
- package/template/.aioson/skills/design/cognitive-core-ui/SKILL.md +2 -2
- package/template/.aioson/skills/design/cognitive-core-ui/references/design-tokens.md +1 -1
- package/template/.aioson/skills/design/cognitive-core-ui/references/patterns.md +1 -1
- package/template/.aioson/skills/design/neo-brutalist-ui/SKILL.md +5 -5
- package/template/.aioson/skills/design/pt.squarespace.com/references/components.md +2 -2
- package/template/.aioson/skills/design/pt.squarespace.com/references/websites.md +4 -4
- package/template/.aioson/skills/design-system/dashboards/SKILL.md +5 -5
- package/template/.aioson/skills/design-system/patterns/SKILL.md +1 -1
- package/template/.aioson/skills/marketing/references/cta-matrix.md +43 -43
- package/template/.aioson/skills/marketing/references/headline-matrix.md +33 -33
- package/template/.aioson/skills/marketing/references/market-intelligence.md +2 -2
- package/template/.aioson/skills/marketing/references/platform-constraints.md +2 -2
- package/template/.aioson/skills/marketing/references/pms-research.md +3 -3
- package/template/.aioson/skills/process/aioson-spec-driven/references/approval-gates.md +7 -7
- package/template/.aioson/skills/process/aioson-spec-driven/references/dev.md +13 -11
- package/template/.aioson/skills/process/aioson-spec-driven/references/ui-language.md +85 -75
- package/template/.aioson/skills/process/decision-presentation/SKILL.md +11 -11
- package/template/.aioson/skills/process/decision-presentation/references/jargon-map.pt-BR.yaml +4 -4
- package/template/.aioson/skills/squad/references/executor-archetypes.md +77 -2
- package/template/.aioson/skills/static/harness-validate/SKILL.md +55 -46
- package/template/.aioson/skills/static/react-motion-patterns.md +1 -1
- package/template/.aioson/skills/static/static-html-patterns.md +2 -2
- package/template/.aioson/skills/static/threejs-patterns.md +2 -2
- package/template/.aioson/tasks/implementation-plan.md +325 -327
- package/template/.aioson/tasks/squad-analyze.md +93 -83
- package/template/.aioson/tasks/squad-create.md +156 -148
- package/template/.aioson/tasks/squad-design.md +223 -206
- package/template/.aioson/tasks/squad-eval.md +72 -0
- package/template/.aioson/tasks/squad-execution-plan.md +279 -279
- package/template/.aioson/tasks/squad-export.md +20 -20
- package/template/.aioson/tasks/squad-extend.md +73 -68
- package/template/.aioson/tasks/squad-investigate.md +57 -57
- package/template/.aioson/tasks/squad-pipeline.md +122 -122
- package/template/.aioson/tasks/squad-profile.md +48 -48
- package/template/.aioson/tasks/squad-refresh.md +242 -236
- package/template/.aioson/tasks/squad-repair.md +85 -85
- package/template/.aioson/tasks/squad-review.md +61 -61
- package/template/.aioson/tasks/squad-task-decompose.md +66 -66
- package/template/.aioson/tasks/squad-validate.md +65 -58
- package/template/.aioson/templates/squads/content-basic/template.json +1 -1
- package/template/.aioson/templates/squads/media-channel/template.json +1 -1
- package/template/.aioson/templates/squads/research-analysis/template.json +1 -1
- package/template/AGENTS.md +10 -6
- package/template/CLAUDE.md +10 -6
- package/template/OPENCODE.md +9 -5
- package/template/agents/_shared/learning-capture-directive.md +88 -0
package/CHANGELOG.md
CHANGED
|
@@ -4,7 +4,32 @@ All notable changes to this project will be documented in this file.
|
|
|
4
4
|
|
|
5
5
|
## [Unreleased]
|
|
6
6
|
|
|
7
|
-
## [1.21.
|
|
7
|
+
## [1.21.3] - 2026-05-28
|
|
8
|
+
|
|
9
|
+
### Security
|
|
10
|
+
- **`memory:trim --archive=<path>` is now contained under the project root (TS-LC-01).** It was resolved relative to `cwd` with no containment, so a crafted/typo'd path could write or overwrite a file outside the project. Now resolved under the project root and rejected with `archive_path_escape` on absolute or `..`-traversal escape — mirroring the containment wall in `memory-reflect-commit`. Localized message added in all 4 locales.
|
|
11
|
+
- **`feature:close` auto-trim hook now honors `AIOSON_RUNTIME_HOOK` (TS-LC-02).** The hook called the trim engine directly, bypassing the hook-context guard that `memory:trim` enforces. It now skips when running in a hook/automation context, so a tier-2 memory mutation never fires outside explicit human action.
|
|
12
|
+
|
|
13
|
+
### Tests
|
|
14
|
+
- Coverage pass over the v1.21.2 agent-loading-contract code (`node --test --experimental-test-coverage`): `current-state-trim.js` 98.8%→100% line, `memory-trim.js` 73.9%→88.6% line / 64.4%→76.7% branch. Adds error/edge-path tests (`no_current_state`, `section_not_found`, custom/escaping `--archive`, headerless archive, hook skip paths) and verifies all `cli.memory_{archive,restore,search}` keys resolve.
|
|
15
|
+
|
|
16
|
+
## [1.21.2] - 2026-05-28
|
|
17
|
+
|
|
18
|
+
### Added
|
|
19
|
+
- **Agent loading contract + `memory:trim`.** `bootstrap/current-state.md` is an append-only log that every implementation/review agent read in full at activation (~81KB / ~33k tokens, 84% of the bootstrap). New `aioson memory:trim [--keep=<N>] [--archive=<path>] [--dry-run] [--json]` splits its "## What the system already has" section into a HOT log + a cold `current-state-archive.md` (entries MOVED verbatim, never deleted; active-feature entries exempt). `feature:close` (PASS) auto-rolls aged entries (`--no-trim` to opt out). New governance doc `.aioson/design-docs/agent-loading-contract.md` defines the three loading tiers + retention policy. The repo's own current-state was trimmed 81KB → 21KB.
|
|
20
|
+
- **`context:health` now measures `bootstrap/*.md`** — the per-activation layer it previously ignored — and excludes the cold `*-archive.md`; a heavy `current-state.md` now points to `memory:trim`.
|
|
21
|
+
- **Shared code-health analysis lens** `.aioson/docs/quality/code-health-analysis.md` (plan → investigate → refine → operate → test → adjust over coverage, test sufficiency, regression need, execution-chain, performance, componentization), wired on-demand into `@tester`/`@qa`/`@pentester`/`@architect`/`@sheldon`/`@deyvin`.
|
|
22
|
+
- **Current-state entry tagging** — the reflect engine, `@dev`, and `@committer` now prefix new entries with `[{slug} · {YYYY-MM-DD}]` for precise rollup; `@qa`/`@architect`/`@dev`/`@deyvin` bootstrap sections gained archive-awareness (grep the archive before flagging a capability as missing).
|
|
23
|
+
|
|
24
|
+
### Fixed
|
|
25
|
+
- **`memory:archive` / `memory:restore` / `memory:search` logged raw i18n keys** in every locale — they called message keys without the required `cli.` namespace prefix, so `t()` missed and echoed the key (e.g. `memory_archive.id_required`). All 25 calls now use the `cli.` prefix and localize correctly.
|
|
26
|
+
|
|
27
|
+
## [1.21.1] - 2026-06-XX
|
|
28
|
+
|
|
29
|
+
### Fixed
|
|
30
|
+
- **`memory:reflect-commit --dry-run` is now non-destructive.** The command never read the `--dry-run` flag, so a "dry run" silently performed the full destructive commit — it wrote the bootstrap files **and** unlinked the single-use manifest, leaving the flow unrecoverable (`missing_manifest`) on the next call. `--dry-run` now runs validation + path containment exactly like a real commit, then returns `{ ok: true, dryRun: true, would_write: [...] }` without writing any file or consuming the manifest, so a real commit can still follow. Regression coverage in `tests/memory-reflect-commit-dry-run.test.js`. Note: the reflect manifest remains single-use — a successful real commit consumes it (re-run by re-running `memory:reflect-prepare`).
|
|
31
|
+
|
|
32
|
+
## [1.21.0] - 2026-05-28
|
|
8
33
|
|
|
9
34
|
### Added
|
|
10
35
|
- **Gemini CLI deprecation warning (gemini-phaseout Phase 1).** Google announced (2026-05-20) that the Gemini CLI free/personal tier ends 2026-06-18.
|
|
@@ -121,6 +121,8 @@ O agente é livre para usar o LLM como achar melhor para fazer a reescrita. O CL
|
|
|
121
121
|
|
|
122
122
|
Se tudo passa: escreve, apaga o manifest, emite `memory_reflect_committed` em runtime. Se falha: emite `memory_reflect_failed` com a lista de erros e o agente tem 1 retry.
|
|
123
123
|
|
|
124
|
+
> **`--dry-run` (pré-visualização não-destrutiva):** `aioson memory:reflect-commit . --agent=dev --output=<json> --dry-run` roda a validação + containment de path exatamente como o commit real, mas **não escreve nada e não consome o manifest** — retorna `{ ok: true, dryRun: true, would_write: [...] }`. Use pra conferir o output antes de aplicar. Atenção: o manifest é **single-use** — um commit real (sem `--dry-run`) o apaga; pra recomeçar, rode `memory:reflect-prepare` de novo.
|
|
125
|
+
|
|
124
126
|
## Exemplo end-to-end
|
|
125
127
|
|
|
126
128
|
```bash
|
package/package.json
CHANGED
package/src/agents.js
CHANGED
|
@@ -29,14 +29,15 @@ function buildAgentPrompt(agent, tool, options = {}) {
|
|
|
29
29
|
const safeTool = String(tool || 'codex').toLowerCase();
|
|
30
30
|
const instructionPath = options.instructionPath || agent.path;
|
|
31
31
|
const targetDir = options.targetDir ? String(options.targetDir) : '.';
|
|
32
|
-
const interactionLanguage = String(options.interactionLanguage || 'en');
|
|
33
|
-
const autonomyMode = String(options.autonomyMode || '').trim();
|
|
34
|
-
const capabilitySummary = String(options.capabilitySummary || '').trim();
|
|
35
|
-
const activationContext = String(options.activationContext || '').trim();
|
|
36
|
-
const
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
32
|
+
const interactionLanguage = String(options.interactionLanguage || 'en');
|
|
33
|
+
const autonomyMode = String(options.autonomyMode || '').trim();
|
|
34
|
+
const capabilitySummary = String(options.capabilitySummary || '').trim();
|
|
35
|
+
const activationContext = String(options.activationContext || '').trim();
|
|
36
|
+
const dependsOn = Array.isArray(options.dependsOn) ? options.dependsOn : agent.dependsOn;
|
|
37
|
+
const dependencyText =
|
|
38
|
+
dependsOn.length > 0
|
|
39
|
+
? `Check required context files first: ${dependsOn.join(', ')}.`
|
|
40
|
+
: 'No prerequisite context files are required.';
|
|
40
41
|
const activationBlock = activationContext
|
|
41
42
|
? [
|
|
42
43
|
'',
|
|
@@ -68,20 +69,20 @@ function buildAgentPrompt(agent, tool, options = {}) {
|
|
|
68
69
|
`**Scope boundary:** You operate exclusively as ${agent.command}. Do not perform work that belongs to another agent. When your work is complete, output only the handoff — which agent is next and why. Do not continue into that agent\'s territory.`,
|
|
69
70
|
].join('\n');
|
|
70
71
|
|
|
71
|
-
if (safeTool === 'claude') {
|
|
72
|
-
return `Read ${instructionPath} and execute ${agent.command}. ${dependencyText}${activationBlock}
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
if (safeTool === 'gemini') {
|
|
76
|
-
return `Run the Gemini command mapped to ${instructionPath} and execute ${agent.command}. ${dependencyText}${activationBlock}
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
if (safeTool === 'opencode') {
|
|
80
|
-
return `Use agent "${agent.id}" from ${instructionPath}. ${dependencyText}${activationBlock}
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
return `Read AGENTS.md and execute ${agent.command} using ${instructionPath}. ${dependencyText}${activationBlock}
|
|
84
|
-
}
|
|
72
|
+
if (safeTool === 'claude') {
|
|
73
|
+
return `Read ${instructionPath} and execute ${agent.command}. ${dependencyText}${activationBlock}\n\nWrite output to ${agent.output}.${autonomyBlock}${lifecycleBlock}`;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
if (safeTool === 'gemini') {
|
|
77
|
+
return `Run the Gemini command mapped to ${instructionPath} and execute ${agent.command}. ${dependencyText}${activationBlock}\n\nSave result to ${agent.output}.${autonomyBlock}${lifecycleBlock}`;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
if (safeTool === 'opencode') {
|
|
81
|
+
return `Use agent "${agent.id}" from ${instructionPath}. ${dependencyText}${activationBlock}\n\nSave output to ${agent.output}.${autonomyBlock}${lifecycleBlock}`;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
return `Read AGENTS.md and execute ${agent.command} using ${instructionPath}. ${dependencyText}${activationBlock}\n\nSave output to ${agent.output}.${autonomyBlock}${lifecycleBlock}`;
|
|
85
|
+
}
|
|
85
86
|
|
|
86
87
|
module.exports = {
|
|
87
88
|
normalizeAgentName,
|
package/src/cli.js
CHANGED
|
@@ -18,6 +18,7 @@ const { runChainAudit } = require('./commands/chain-audit');
|
|
|
18
18
|
const { runMemorySearch } = require('./commands/memory-search');
|
|
19
19
|
const { runMemoryArchive } = require('./commands/memory-archive');
|
|
20
20
|
const { runMemoryRestore } = require('./commands/memory-restore');
|
|
21
|
+
const { runMemoryTrim } = require('./commands/memory-trim');
|
|
21
22
|
const { runSetupContext } = require('./commands/setup-context');
|
|
22
23
|
const { runLocaleApply } = require('./commands/locale-apply');
|
|
23
24
|
const { runSmokeTest } = require('./commands/smoke');
|
|
@@ -57,6 +58,8 @@ const { runSquadStatus } = require('./commands/squad-status');
|
|
|
57
58
|
const { runSquadDoctor } = require('./commands/squad-doctor');
|
|
58
59
|
const { runSquadRepairGenomes } = require('./commands/squad-repair-genomes');
|
|
59
60
|
const { runSquadValidate } = require('./commands/squad-validate');
|
|
61
|
+
const { runSquadRoleScan } = require('./commands/squad-role-scan');
|
|
62
|
+
const { runSquadPlaybook } = require('./commands/squad-playbook');
|
|
60
63
|
const { runSquadExport } = require('./commands/squad-export');
|
|
61
64
|
const { runSquadPipeline } = require('./commands/squad-pipeline');
|
|
62
65
|
const { runSquadAgentCreate } = require('./commands/squad-agent-create');
|
|
@@ -79,10 +82,12 @@ const { runSquadWebhook } = require('./commands/squad-webhook');
|
|
|
79
82
|
const { runSquadBus } = require('./commands/squad-bus');
|
|
80
83
|
const { runSquadAutorun } = require('./commands/squad-autorun');
|
|
81
84
|
const { runSquadDependencyGraph } = require('./commands/squad-dependency-graph');
|
|
82
|
-
const { runSquadToolRegister } = require('./commands/squad-tool-register');
|
|
83
|
-
const { runSquadReview } = require('./commands/squad-review');
|
|
84
|
-
const { runAgentAudit } = require('./commands/agent-audit');
|
|
85
|
-
const {
|
|
85
|
+
const { runSquadToolRegister } = require('./commands/squad-tool-register');
|
|
86
|
+
const { runSquadReview } = require('./commands/squad-review');
|
|
87
|
+
const { runAgentAudit } = require('./commands/agent-audit');
|
|
88
|
+
const { runSkillAudit } = require('./commands/skill-audit');
|
|
89
|
+
const { runQualityAudit } = require('./commands/quality-audit');
|
|
90
|
+
const { runBriefGen } = require('./commands/brief-gen');
|
|
86
91
|
const { runHarnessInit, runHarnessValidate, runHarnessApplyValidation } = require('./commands/harness');
|
|
87
92
|
const { runVerifyGate } = require('./commands/verify-gate');
|
|
88
93
|
const {
|
|
@@ -324,6 +329,10 @@ const JSON_SUPPORTED_COMMANDS = new Set([
|
|
|
324
329
|
'squad-repair-genomes',
|
|
325
330
|
'squad:validate',
|
|
326
331
|
'squad-validate',
|
|
332
|
+
'squad:role-scan',
|
|
333
|
+
'squad-role-scan',
|
|
334
|
+
'squad:playbook',
|
|
335
|
+
'squad-playbook',
|
|
327
336
|
'squad:export',
|
|
328
337
|
'squad-export',
|
|
329
338
|
'squad:pipeline',
|
|
@@ -375,9 +384,13 @@ const JSON_SUPPORTED_COMMANDS = new Set([
|
|
|
375
384
|
'squad-tool-register',
|
|
376
385
|
'squad:review',
|
|
377
386
|
'squad-review',
|
|
378
|
-
'agent:audit',
|
|
379
|
-
'agent-audit',
|
|
380
|
-
'
|
|
387
|
+
'agent:audit',
|
|
388
|
+
'agent-audit',
|
|
389
|
+
'skill:audit',
|
|
390
|
+
'skill-audit',
|
|
391
|
+
'quality:audit',
|
|
392
|
+
'quality-audit',
|
|
393
|
+
'brief:gen',
|
|
381
394
|
'harness:init',
|
|
382
395
|
'harness-init',
|
|
383
396
|
'harness:validate',
|
|
@@ -525,6 +538,8 @@ const JSON_SUPPORTED_COMMANDS = new Set([
|
|
|
525
538
|
'memory-archive',
|
|
526
539
|
'memory:restore',
|
|
527
540
|
'memory-restore',
|
|
541
|
+
'memory:trim',
|
|
542
|
+
'memory-trim',
|
|
528
543
|
'memory:reflect-prepare',
|
|
529
544
|
'memory-reflect-prepare',
|
|
530
545
|
'memory:reflect-commit',
|
|
@@ -809,9 +824,11 @@ function printHelp(t, logger) {
|
|
|
809
824
|
logHelpLine(t, logger, 'cli.help_squad_daemon');
|
|
810
825
|
logHelpLine(t, logger, 'cli.help_squad_mcp');
|
|
811
826
|
logHelpLine(t, logger, 'cli.help_squad_roi');
|
|
812
|
-
logHelpLine(t, logger, 'cli.help_squad_score');
|
|
813
|
-
logHelpLine(t, logger, 'cli.help_squad_learning');
|
|
814
|
-
logHelpLine(t, logger, 'cli.
|
|
827
|
+
logHelpLine(t, logger, 'cli.help_squad_score');
|
|
828
|
+
logHelpLine(t, logger, 'cli.help_squad_learning');
|
|
829
|
+
logHelpLine(t, logger, 'cli.help_agent_audit');
|
|
830
|
+
logHelpLine(t, logger, 'cli.help_quality_audit');
|
|
831
|
+
logHelpLine(t, logger, 'cli.help_learning');
|
|
815
832
|
logHelpLine(t, logger, 'cli.help_runtime_init');
|
|
816
833
|
logHelpLine(t, logger, 'cli.help_runtime_ingest');
|
|
817
834
|
logHelpLine(t, logger, 'cli.help_runtime_task_start');
|
|
@@ -834,9 +851,10 @@ function printHelp(t, logger) {
|
|
|
834
851
|
logHelpLine(t, logger, 'cli.help_scaffold_complete');
|
|
835
852
|
logHelpLine(t, logger, 'cli.help_runtime_backup');
|
|
836
853
|
logHelpLine(t, logger, 'cli.help_runtime_restore');
|
|
837
|
-
logHelpLine(t, logger, 'cli.help_skill_install');
|
|
838
|
-
logHelpLine(t, logger, 'cli.help_skill_list');
|
|
839
|
-
logHelpLine(t, logger, 'cli.help_skill_remove');
|
|
854
|
+
logHelpLine(t, logger, 'cli.help_skill_install');
|
|
855
|
+
logHelpLine(t, logger, 'cli.help_skill_list');
|
|
856
|
+
logHelpLine(t, logger, 'cli.help_skill_remove');
|
|
857
|
+
logHelpLine(t, logger, 'cli.help_skill_audit');
|
|
840
858
|
logHelpLine(t, logger, 'cli.help_design_hybrid_options');
|
|
841
859
|
logHelpLine(t, logger, 'cli.help_cloud_import_squad');
|
|
842
860
|
logHelpLine(t, logger, 'cli.help_cloud_import_genome');
|
|
@@ -1161,6 +1179,10 @@ async function main() {
|
|
|
1161
1179
|
result = await runSquadRepairGenomes({ args, options, logger: commandLogger, t });
|
|
1162
1180
|
} else if (command === 'squad:validate' || command === 'squad-validate') {
|
|
1163
1181
|
result = await runSquadValidate({ args, options, logger: commandLogger, t });
|
|
1182
|
+
} else if (command === 'squad:role-scan' || command === 'squad-role-scan') {
|
|
1183
|
+
result = await runSquadRoleScan({ args, options, logger: commandLogger });
|
|
1184
|
+
} else if (command === 'squad:playbook' || command === 'squad-playbook') {
|
|
1185
|
+
result = await runSquadPlaybook({ args, options, logger: commandLogger });
|
|
1164
1186
|
} else if (command === 'squad:export' || command === 'squad-export') {
|
|
1165
1187
|
result = await runSquadExport({ args, options, logger: commandLogger, t });
|
|
1166
1188
|
} else if (command === 'squad:pipeline' || command === 'squad-pipeline') {
|
|
@@ -1213,10 +1235,14 @@ async function main() {
|
|
|
1213
1235
|
result = await runSquadToolRegister({ args, options, logger: commandLogger });
|
|
1214
1236
|
} else if (command === 'squad:review' || command === 'squad-review') {
|
|
1215
1237
|
result = await runSquadReview({ args, options, logger: commandLogger });
|
|
1216
|
-
} else if (command === 'agent:audit' || command === 'agent-audit') {
|
|
1217
|
-
result = await runAgentAudit({ args, options, logger: commandLogger });
|
|
1218
|
-
} else if (command === '
|
|
1219
|
-
result = await
|
|
1238
|
+
} else if (command === 'agent:audit' || command === 'agent-audit') {
|
|
1239
|
+
result = await runAgentAudit({ args, options, logger: commandLogger });
|
|
1240
|
+
} else if (command === 'skill:audit' || command === 'skill-audit') {
|
|
1241
|
+
result = await runSkillAudit({ args, options, logger: commandLogger });
|
|
1242
|
+
} else if (command === 'quality:audit' || command === 'quality-audit') {
|
|
1243
|
+
result = await runQualityAudit({ args, options, logger: commandLogger });
|
|
1244
|
+
} else if (command === 'brief:gen' || command === 'brief-gen') {
|
|
1245
|
+
result = await runBriefGen({ args, options, logger: commandLogger, t });
|
|
1220
1246
|
} else if (command === 'harness:init' || command === 'harness-init') {
|
|
1221
1247
|
result = await runHarnessInit({ args, options, logger: commandLogger, t });
|
|
1222
1248
|
} else if (command === 'harness:validate' || command === 'harness-validate') {
|
|
@@ -1265,9 +1291,9 @@ async function main() {
|
|
|
1265
1291
|
result = await runSpecCheckpoint({ args, options, logger: commandLogger });
|
|
1266
1292
|
} else if (command === 'spec:tasks' || command === 'spec-tasks') {
|
|
1267
1293
|
result = await runSpecTasks({ args, options, logger: commandLogger });
|
|
1268
|
-
} else if (command.startsWith('learning:') || command === 'learning') {
|
|
1269
|
-
const sub = command === 'learning' ? (args[1] || 'list') : command.split(':')[1];
|
|
1270
|
-
result = await runLearning({ args, options: { ...options, sub }, logger: commandLogger, t });
|
|
1294
|
+
} else if (command.startsWith('learning:') || command === 'learning') {
|
|
1295
|
+
const sub = command === 'learning' ? (options.sub || args[1] || 'list') : command.split(':')[1];
|
|
1296
|
+
result = await runLearning({ args, options: { ...options, sub }, logger: commandLogger, t });
|
|
1271
1297
|
} else if (command.startsWith('plan:') || command === 'plan') {
|
|
1272
1298
|
const sub = command === 'plan' ? (args[1] || 'show') : command.split(':')[1];
|
|
1273
1299
|
result = await runImplementationPlan({ args, options: { ...options, sub }, logger: commandLogger, t });
|
|
@@ -1355,6 +1381,8 @@ async function main() {
|
|
|
1355
1381
|
result = await runMemoryArchive({ args, options, logger: commandLogger, t });
|
|
1356
1382
|
} else if (command === 'memory:restore' || command === 'memory-restore') {
|
|
1357
1383
|
result = await runMemoryRestore({ args, options, logger: commandLogger, t });
|
|
1384
|
+
} else if (command === 'memory:trim' || command === 'memory-trim') {
|
|
1385
|
+
result = await runMemoryTrim({ args, options, logger: commandLogger, t });
|
|
1358
1386
|
} else if (command === 'memory:reflect-prepare' || command === 'memory-reflect-prepare') {
|
|
1359
1387
|
result = await runMemoryReflectPrepare({ args, options, logger: commandLogger });
|
|
1360
1388
|
} else if (command === 'memory:reflect-commit' || command === 'memory-reflect-commit') {
|
|
@@ -19,8 +19,11 @@
|
|
|
19
19
|
*
|
|
20
20
|
* Usage:
|
|
21
21
|
* aioson agent:audit .
|
|
22
|
-
* aioson agent:audit . --verbose Show per-section breakdown
|
|
23
|
-
* aioson agent:audit . --locales Include locale variant files
|
|
22
|
+
* aioson agent:audit . --verbose Show per-section breakdown
|
|
23
|
+
* aioson agent:audit . --locales Include locale variant files
|
|
24
|
+
* aioson agent:audit . --runtime-only Scan project/runtime surfaces only
|
|
25
|
+
* aioson agent:audit . --template-only Scan template surfaces only
|
|
26
|
+
* aioson agent:audit . --inception Scan project and template surfaces
|
|
24
27
|
* aioson agent:audit . --fix Write savings report to .aioson/docs/agent-audit.md
|
|
25
28
|
* aioson agent:audit . --json
|
|
26
29
|
*/
|
|
@@ -117,7 +120,7 @@ function parseSections(content) {
|
|
|
117
120
|
|
|
118
121
|
// ─── File scanner ─────────────────────────────────────────────────────────────
|
|
119
122
|
|
|
120
|
-
async function scanAgentFile(filePath, relativePath) {
|
|
123
|
+
async function scanAgentFile(filePath, relativePath, category = 'workspace_agent') {
|
|
121
124
|
let content;
|
|
122
125
|
try {
|
|
123
126
|
content = await fs.readFile(filePath, 'utf8');
|
|
@@ -140,10 +143,11 @@ async function scanAgentFile(filePath, relativePath) {
|
|
|
140
143
|
? 'over_target'
|
|
141
144
|
: 'ok';
|
|
142
145
|
|
|
143
|
-
return {
|
|
144
|
-
file: relativePath,
|
|
145
|
-
slug,
|
|
146
|
-
|
|
146
|
+
return {
|
|
147
|
+
file: relativePath,
|
|
148
|
+
slug,
|
|
149
|
+
category,
|
|
150
|
+
agent_type: typeDef.type,
|
|
147
151
|
chars,
|
|
148
152
|
tokens: estimateTokens(chars),
|
|
149
153
|
target_chars: typeDef.target,
|
|
@@ -156,7 +160,7 @@ async function scanAgentFile(filePath, relativePath) {
|
|
|
156
160
|
};
|
|
157
161
|
}
|
|
158
162
|
|
|
159
|
-
async function scanDir(dirPath, projectDir, results) {
|
|
163
|
+
async function scanDir(dirPath, projectDir, results, category = 'workspace_agent') {
|
|
160
164
|
let entries;
|
|
161
165
|
try {
|
|
162
166
|
entries = await fs.readdir(dirPath, { withFileTypes: true });
|
|
@@ -166,12 +170,70 @@ async function scanDir(dirPath, projectDir, results) {
|
|
|
166
170
|
|
|
167
171
|
for (const entry of entries) {
|
|
168
172
|
if (!entry.isFile() || !entry.name.endsWith('.md')) continue;
|
|
169
|
-
const filePath = path.join(dirPath, entry.name);
|
|
170
|
-
const rel = path.relative(projectDir, filePath).split(path.sep).join('/');
|
|
171
|
-
const result = await scanAgentFile(filePath, rel);
|
|
172
|
-
if (result) results.push(result);
|
|
173
|
-
}
|
|
174
|
-
}
|
|
173
|
+
const filePath = path.join(dirPath, entry.name);
|
|
174
|
+
const rel = path.relative(projectDir, filePath).split(path.sep).join('/');
|
|
175
|
+
const result = await scanAgentFile(filePath, rel, category);
|
|
176
|
+
if (result) results.push(result);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
function normalizeRel(projectDir, filePath) {
|
|
181
|
+
return path.relative(projectDir, filePath).split(path.sep).join('/');
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
function getAuditMode(options) {
|
|
185
|
+
const selected = [
|
|
186
|
+
options['runtime-only'] ? 'runtime' : null,
|
|
187
|
+
options['template-only'] ? 'template' : null,
|
|
188
|
+
options.inception ? 'inception' : null
|
|
189
|
+
].filter(Boolean);
|
|
190
|
+
|
|
191
|
+
if (selected.length > 1) {
|
|
192
|
+
return { error: 'conflicting_modes', selected };
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
return { mode: selected[0] || 'inception' };
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
function buildAgentRoots(targetDir, mode) {
|
|
199
|
+
const roots = [];
|
|
200
|
+
|
|
201
|
+
if (mode === 'runtime' || mode === 'inception') {
|
|
202
|
+
roots.push({
|
|
203
|
+
type: 'dir',
|
|
204
|
+
path: path.join(targetDir, '.aioson', 'agents'),
|
|
205
|
+
rel: '.aioson/agents',
|
|
206
|
+
category: 'workspace_agent'
|
|
207
|
+
});
|
|
208
|
+
for (const name of ['CLAUDE.md', 'AGENTS.md']) {
|
|
209
|
+
roots.push({
|
|
210
|
+
type: 'file',
|
|
211
|
+
path: path.join(targetDir, name),
|
|
212
|
+
rel: name,
|
|
213
|
+
category: 'auto_loaded'
|
|
214
|
+
});
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
if (mode === 'template' || mode === 'inception') {
|
|
219
|
+
roots.push({
|
|
220
|
+
type: 'dir',
|
|
221
|
+
path: path.join(targetDir, 'template', '.aioson', 'agents'),
|
|
222
|
+
rel: 'template/.aioson/agents',
|
|
223
|
+
category: 'template_agent'
|
|
224
|
+
});
|
|
225
|
+
for (const name of ['CLAUDE.md', 'AGENTS.md']) {
|
|
226
|
+
roots.push({
|
|
227
|
+
type: 'file',
|
|
228
|
+
path: path.join(targetDir, 'template', name),
|
|
229
|
+
rel: `template/${name}`,
|
|
230
|
+
category: 'auto_loaded'
|
|
231
|
+
});
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
return roots;
|
|
236
|
+
}
|
|
175
237
|
|
|
176
238
|
// ─── Report writer ────────────────────────────────────────────────────────────
|
|
177
239
|
|
|
@@ -238,104 +300,98 @@ function buildMarkdownReport(files, projectDir) {
|
|
|
238
300
|
|
|
239
301
|
// ─── Main command ─────────────────────────────────────────────────────────────
|
|
240
302
|
|
|
241
|
-
async function runAgentAudit({ args, options = {}, logger }) {
|
|
242
|
-
const targetDir = path.resolve(process.cwd(), args[0] || '.');
|
|
243
|
-
const verbose = Boolean(options.verbose || options.v);
|
|
244
|
-
const includeLocales = Boolean(options.locales);
|
|
245
|
-
const writeFix = Boolean(options.fix);
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
if (
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
files.
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
logger.log('
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
logger.log(
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
'
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
for (const s of topSections) {
|
|
334
|
-
const flag = s.onDemandCandidate ? ' [on-demand candidate]' : '';
|
|
335
|
-
logger.log(` ${'§ ' + s.title.slice(0, 40)} ${formatKb(s.chars)}${flag}`);
|
|
336
|
-
}
|
|
337
|
-
}
|
|
338
|
-
}
|
|
303
|
+
async function runAgentAudit({ args, options = {}, logger }) {
|
|
304
|
+
const targetDir = path.resolve(process.cwd(), args[0] || '.');
|
|
305
|
+
const verbose = Boolean(options.verbose || options.v);
|
|
306
|
+
const includeLocales = Boolean(options.locales);
|
|
307
|
+
const writeFix = Boolean(options.fix);
|
|
308
|
+
const modeResult = getAuditMode(options);
|
|
309
|
+
|
|
310
|
+
if (modeResult.error) {
|
|
311
|
+
if (!options.json) logger.error('Choose only one audit mode: --runtime-only, --template-only, or --inception.');
|
|
312
|
+
return { ok: false, reason: modeResult.error, selected: modeResult.selected };
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
const mode = modeResult.mode;
|
|
316
|
+
const scanRoots = buildAgentRoots(targetDir, mode);
|
|
317
|
+
|
|
318
|
+
const files = [];
|
|
319
|
+
|
|
320
|
+
for (const root of scanRoots) {
|
|
321
|
+
if (root.type === 'dir') {
|
|
322
|
+
if (await dirExists(root.path)) await scanDir(root.path, targetDir, files, root.category);
|
|
323
|
+
continue;
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
const r = await scanAgentFile(root.path, normalizeRel(targetDir, root.path), root.category);
|
|
327
|
+
if (r) files.push(r);
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
// Optionally include locales
|
|
331
|
+
if (includeLocales && (mode === 'runtime' || mode === 'inception')) {
|
|
332
|
+
await scanLocaleAgents(path.join(targetDir, '.aioson', 'locales'), targetDir, files, 'workspace_agent');
|
|
333
|
+
}
|
|
334
|
+
if (includeLocales && (mode === 'template' || mode === 'inception')) {
|
|
335
|
+
await scanLocaleAgents(path.join(targetDir, 'template', '.aioson', 'locales'), targetDir, files, 'template_agent');
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
const roots = scanRoots.map((r) => r.rel);
|
|
339
|
+
|
|
340
|
+
if (files.length === 0) {
|
|
341
|
+
if (!options.json) logger.log('No agent files found. Run from the aioson project root or a project with .aioson/agents/.');
|
|
342
|
+
return { ok: false, reason: 'no_files', mode, roots };
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
// Sort by size descending
|
|
346
|
+
files.sort((a, b) => b.chars - a.chars);
|
|
347
|
+
|
|
348
|
+
if (options.json) return { ok: true, mode, roots, files };
|
|
349
|
+
|
|
350
|
+
// ── Console report ─────────────────────────────────────────────────────────
|
|
351
|
+
const overHard = files.filter((f) => f.status === 'over_hard');
|
|
352
|
+
const overTarget = files.filter((f) => f.status === 'over_target');
|
|
353
|
+
const totalTokens = files.reduce((s, f) => s + f.tokens, 0);
|
|
354
|
+
const totalSavings = files.reduce((s, f) => s + f.savings_tokens, 0);
|
|
355
|
+
|
|
356
|
+
logger.log('Agent Audit');
|
|
357
|
+
logger.log('─'.repeat(70));
|
|
358
|
+
logger.log(`Mode : ${mode}`);
|
|
359
|
+
logger.log(`Roots : ${roots.join(', ')}`);
|
|
360
|
+
logger.log(`Files scanned : ${files.length}`);
|
|
361
|
+
logger.log(`Total tokens : ~${totalTokens.toLocaleString()} per session`);
|
|
362
|
+
logger.log(`Over hard limit: ${overHard.length} Over target: ${overTarget.length}`);
|
|
363
|
+
logger.log(`Potential save : ~${totalSavings.toLocaleString()} tokens/session (on-demand split)`);
|
|
364
|
+
logger.log('');
|
|
365
|
+
|
|
366
|
+
// File table
|
|
367
|
+
const COL = { file: 45, type: 14, size: 9, tokens: 12, status: 8 };
|
|
368
|
+
logger.log(
|
|
369
|
+
'File'.padEnd(COL.file) +
|
|
370
|
+
'Type'.padEnd(COL.type) +
|
|
371
|
+
'Size'.padEnd(COL.size) +
|
|
372
|
+
'Tokens'.padEnd(COL.tokens) +
|
|
373
|
+
'Status'
|
|
374
|
+
);
|
|
375
|
+
logger.log('─'.repeat(70));
|
|
376
|
+
|
|
377
|
+
for (const f of files) {
|
|
378
|
+
const statusLabel = { ok: '✓ ok', over_target: '⚠ target', over_hard: '✗ hard' }[f.status];
|
|
379
|
+
logger.log(
|
|
380
|
+
f.file.slice(0, COL.file - 1).padEnd(COL.file) +
|
|
381
|
+
f.agent_type.padEnd(COL.type) +
|
|
382
|
+
formatKb(f.chars).padEnd(COL.size) +
|
|
383
|
+
formatTokens(f.chars).padEnd(COL.tokens) +
|
|
384
|
+
statusLabel
|
|
385
|
+
);
|
|
386
|
+
|
|
387
|
+
if (verbose && f.sections.length > 0) {
|
|
388
|
+
const topSections = [...f.sections].sort((a, b) => b.chars - a.chars).slice(0, 5);
|
|
389
|
+
for (const s of topSections) {
|
|
390
|
+
const flag = s.onDemandCandidate ? ' [on-demand candidate]' : '';
|
|
391
|
+
logger.log(` ${'§ ' + s.title.slice(0, 40)} ${formatKb(s.chars)}${flag}`);
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
}
|
|
339
395
|
|
|
340
396
|
logger.log('');
|
|
341
397
|
|
|
@@ -375,15 +431,29 @@ async function runAgentAudit({ args, options = {}, logger }) {
|
|
|
375
431
|
logger.log(' Run with --verbose to see per-section breakdown.');
|
|
376
432
|
}
|
|
377
433
|
|
|
378
|
-
return {
|
|
379
|
-
ok: true,
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
434
|
+
return {
|
|
435
|
+
ok: true,
|
|
436
|
+
mode,
|
|
437
|
+
roots,
|
|
438
|
+
files: files.length,
|
|
439
|
+
over_hard: overHard.length,
|
|
440
|
+
over_target: overTarget.length,
|
|
441
|
+
total_tokens: totalTokens,
|
|
384
442
|
potential_savings_tokens: totalSavings
|
|
385
443
|
};
|
|
386
|
-
}
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
async function scanLocaleAgents(localesBase, targetDir, files, category) {
|
|
447
|
+
try {
|
|
448
|
+
const langs = await fs.readdir(localesBase, { withFileTypes: true });
|
|
449
|
+
for (const lang of langs) {
|
|
450
|
+
if (!lang.isDirectory()) continue;
|
|
451
|
+
await scanDir(path.join(localesBase, lang.name, 'agents'), targetDir, files, category);
|
|
452
|
+
}
|
|
453
|
+
} catch {
|
|
454
|
+
// locales dir optional
|
|
455
|
+
}
|
|
456
|
+
}
|
|
387
457
|
|
|
388
458
|
async function dirExists(dirPath) {
|
|
389
459
|
try {
|