@amsterdamdatalabs/adl-agent-control-linux-x64 0.1.10 → 0.1.26
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/bin/adl +2 -2
- package/bin/git +17 -18
- package/bin/git-ado +27 -26
- package/bin/git-defaults +173 -0
- package/bin/health-check +8 -1
- package/bin/kimi-hooks +1 -1
- package/bin/lib/adl-package.sh +257 -0
- package/bin/lib/bun-compile-build.sh +1 -1
- package/bin/lib/fleet-host.sh +62 -0
- package/bin/lib/lean-ctx-observe-hooks.sh +9 -9
- package/bin/reconcile +693 -470
- package/bin/reconcile-host +121 -0
- package/bin/setup +219 -0
- package/bin/shell-path-policy +15 -5
- package/bin/sync-and-reconcile +79 -68
- package/bin/validate-manifest +46 -51
- package/package.json +2 -12
- package/packages/agent-hooks/README.md +14 -9
- package/packages/agent-hooks/assets/hooks.json +0 -20
- package/packages/agent-hooks/package.json +1 -2
- package/packages/agent-hooks/src/cli/args.ts +1 -1
- package/packages/agent-hooks/src/cli/doctor.ts +6 -58
- package/packages/agent-hooks/src/deploy/deploy.ts +12 -41
- package/packages/agent-hooks/src/deploy/doctor.ts +8 -11
- package/packages/agent-hooks/src/deploy/index.ts +14 -14
- package/packages/agent-hooks/src/deploy/json-merge.ts +7 -8
- package/packages/agent-hooks/src/deploy/legacy-lock.ts +2 -2
- package/packages/agent-hooks/src/deploy/list.ts +1 -1
- package/packages/agent-hooks/src/deploy/lock.ts +31 -12
- package/packages/agent-hooks/src/deploy/profile.ts +3 -4
- package/packages/agent-hooks/src/deploy/source.ts +1 -1
- package/packages/agent-hooks/src/gating/config.ts +10 -24
- package/packages/agent-hooks/src/gating/root.ts +3 -3
- package/packages/agent-hooks/src/hooks/briefing/handler.ts +2 -2
- package/packages/agent-hooks/src/hooks/briefing/index.ts +27 -287
- package/packages/agent-hooks/src/hooks/contract.ts +17 -17
- package/packages/agent-hooks/src/hooks/crg/background.ts +27 -0
- package/packages/agent-hooks/src/hooks/crg/index.ts +7 -6
- package/packages/agent-hooks/src/hooks/log.ts +8 -10
- package/packages/agent-hooks/src/hooks/user-prompt-submit/match.ts +1 -1
- package/packages/agent-hooks/src/hooks/user-prompt-submit/tokenizer.ts +1 -1
- package/packages/agent-hooks/src/hooks/user-prompt-submit/vector.ts +6 -5
- package/packages/agent-hooks/src/hosts/registry.ts +1 -1
- package/packages/agent-hooks/src/log/adl-dir.ts +44 -0
- package/packages/agent-hooks/src/log/writer.ts +16 -2
- package/packages/agent-hooks/src/main.ts +7 -41
- package/packages/agent-hooks/src/pre-tool-use/handler.ts +71 -82
- package/packages/agent-hooks/src/rules/engine.ts +13 -17
- package/packages/agent-hooks/src/rules/impl/adl-build-run-denied.ts +3 -3
- package/packages/agent-hooks/src/rules/impl/adl-git-credential-bypass.ts +12 -14
- package/packages/agent-hooks/src/rules/impl/adl-git-identity.ts +28 -28
- package/packages/agent-hooks/src/rules/impl/adl-git-push-policy.ts +8 -9
- package/packages/agent-hooks/src/rules/impl/adl-human-azdo-bypass.ts +56 -59
- package/packages/agent-hooks/src/rules/impl/adl-identity.ts +16 -23
- package/packages/agent-hooks/src/rules/impl/adl-mcp-cli.ts +19 -16
- package/packages/agent-hooks/src/rules/impl/adl-pr-complete-pending.ts +2 -2
- package/packages/agent-hooks/src/rules/impl/adl-pr-review-role.ts +9 -12
- package/packages/agent-hooks/src/rules/impl/adl-pr-role.ts +5 -7
- package/packages/agent-hooks/src/rules/impl/adl-run-required.ts +411 -0
- package/packages/agent-hooks/src/rules/impl/adl-token-minting-role.ts +4 -5
- package/packages/agent-hooks/src/rules/impl/adl-workitem-role.ts +6 -7
- package/packages/agent-hooks/src/rules/impl/agent-tamper-protection.ts +77 -70
- package/packages/agent-hooks/src/rules/impl/deny-allowlist.ts +159 -0
- package/packages/agent-hooks/src/rules/impl/fs-trash.ts +2 -2
- package/packages/agent-hooks/src/rules/impl/git-helpers.ts +21 -23
- package/packages/agent-hooks/src/rules/impl/git-worktree.ts +14 -28
- package/packages/agent-hooks/src/rules/impl/mcp-tool.ts +3 -3
- package/packages/agent-hooks/src/rules/impl/messages.ts +1 -1
- package/packages/agent-hooks/src/rules/impl/pr-completion.ts +1 -1
- package/packages/agent-hooks/src/rules/impl/tool-azure-devops.ts +35 -46
- package/packages/agent-hooks/src/rules/impl/tool-find.ts +34 -7
- package/packages/agent-hooks/src/rules/impl/tool-grep.ts +34 -12
- package/packages/agent-hooks/src/rules/impl/tool-native-search.ts +52 -9
- package/packages/agent-hooks/src/rules/ports.ts +5 -7
- package/packages/agent-hooks/src/rules/registry.ts +4 -6
- package/packages/agent-hooks/src/rules/shell/git-identity.ts +86 -101
- package/packages/agent-hooks/src/rules/shell/git-internals.ts +1 -1
- package/packages/agent-hooks/src/rules/shell/invocation.ts +24 -118
- package/packages/agent-hooks/src/rules/shell/piped-script.ts +1 -1
- package/packages/agent-hooks/src/rules/shell/prefixes.ts +1 -1
- package/packages/agent-hooks/src/rules/shell/protected-carrier-writes.ts +11 -10
- package/packages/agent-hooks/src/rules/shell/protected-carriers.ts +26 -26
- package/packages/agent-hooks/src/rules/shell/substitution.ts +1 -1
- package/packages/agent-hooks/src/rules/shell/xargs.ts +2 -2
- package/packages/agent-hooks/src/rules/spec.ts +2 -2
- package/packages/agent-settings/README.md +287 -0
- package/packages/agent-settings/assets/GLOBAL-AGENTS.md +18 -18
- package/packages/agent-settings/assets/agents/architect.toml +2 -0
- package/packages/agent-settings/assets/agents/code-reviewer.toml +2 -0
- package/packages/agent-settings/assets/agents/executor.toml +2 -0
- package/packages/agent-settings/assets/agents/explore.toml +2 -0
- package/packages/agent-settings/assets/agents/planner.toml +2 -0
- package/packages/agent-settings/assets/mcp.json +0 -4
- package/packages/agent-settings/deploy-profile.json +139 -0
- package/packages/agent-settings/deploy-profile.schema.json +147 -0
- package/packages/agent-settings/managed/README.md +29 -30
- package/packages/agent-settings/managed/codex-requirements.toml +9 -9
- package/packages/agent-settings/package.json +20 -0
- package/packages/agent-settings/src/deploy/agent-render.ts +2 -2
- package/packages/agent-settings/src/deploy/agent-toml.ts +1 -1
- package/packages/agent-settings/src/deploy/agents-deploy.ts +17 -3
- package/packages/agent-settings/src/deploy/doctor.ts +3 -83
- package/packages/agent-settings/src/deploy/index.ts +6 -33
- package/packages/agent-settings/src/deploy/legacy-lock.ts +6 -6
- package/packages/agent-settings/src/deploy/list.ts +5 -19
- package/packages/agent-settings/src/deploy/lock.ts +8 -18
- package/packages/agent-settings/src/deploy/mcp-deploy.ts +10 -5
- package/packages/agent-settings/src/deploy/mcp-merge.ts +22 -3
- package/packages/agent-settings/src/deploy/mcp-source.ts +1 -1
- package/packages/agent-settings/src/deploy/profile.ts +11 -35
- package/packages/agent-settings/src/deploy/retire-lean-ctx.ts +184 -0
- package/packages/agent-settings/src/deploy/settings.ts +17 -22
- package/packages/agent-settings/src/global-surface-sweep.ts +5 -17
- package/packages/agent-settings/src/kimi-hooks.ts +339 -192
- package/packages/agent-settings/src/opencode-hooks.ts +1 -1
- package/packages/agent-settings/tsconfig.json +23 -0
- package/packages/agent-skills/assets/agent-search-tool-audit/SKILL.md +120 -0
- package/packages/agent-skills/assets/agent-search-tool-audit/scripts/audit.sh +276 -0
- package/packages/agent-skills/assets/debug-issue/SKILL.md +8 -7
- package/packages/agent-skills/assets/explore-codebase/SKILL.md +13 -13
- package/packages/agent-skills/assets/refactor-safely/SKILL.md +12 -11
- package/packages/agent-skills/assets/review-changes/SKILL.md +7 -7
- package/packages/agent-skills/assets/testing/references/e2e.md +37 -0
- package/packages/agent-skills/assets/testing/references/integration.md +37 -0
- package/packages/agent-skills/assets/testing/references/unit.md +32 -0
- package/packages/agent-skills/dist/deploy.d.ts +2 -0
- package/packages/agent-skills/dist/deploy.d.ts.map +1 -1
- package/packages/agent-skills/dist/deploy.js +27 -1
- package/packages/agent-skills/dist/deploy.js.map +1 -1
- package/packages/agent-skills/dist/doctor.d.ts +0 -2
- package/packages/agent-skills/dist/doctor.d.ts.map +1 -1
- package/packages/agent-skills/dist/doctor.js +1 -1
- package/packages/agent-skills/dist/doctor.js.map +1 -1
- package/packages/agent-skills/dist/fs-utils.d.ts +0 -1
- package/packages/agent-skills/dist/fs-utils.d.ts.map +1 -1
- package/packages/agent-skills/dist/fs-utils.js +1 -1
- package/packages/agent-skills/dist/fs-utils.js.map +1 -1
- package/packages/agent-skills/package.json +1 -1
- package/packages/agent-skills/src/deploy.ts +29 -1
- package/packages/agent-skills/src/doctor.ts +1 -1
- package/packages/agent-skills/src/fs-utils.ts +1 -1
- package/packages/azdo/README.md +10 -9
- package/packages/azdo/package.json +2 -5
- package/packages/azdo/src/azdo-pl.ts +2 -54
- package/packages/azdo/src/azdo-pr-review.ts +4 -4
- package/packages/azdo/src/azdo-repo-doctor.ts +101 -52
- package/packages/azdo/src/azdo-wit.ts +41 -2
- package/packages/azdo/src/lib/agent-identity.ts +12 -14
- package/packages/azdo/src/lib/agent-token.ts +2 -2
- package/packages/azdo/src/lib/client.ts +0 -5
- package/packages/azdo/src/lib/graph-identity.ts +4 -4
- package/packages/azdo/src/workflow-rules-matrix.csv +85 -0
- package/packages/azdo/src/workflow-rules.ts +128 -0
- package/packages/fleet/manifest.json +38 -33
- package/packages/fleet/manifest.schema.json +67 -65
- package/packages/fleet/src/default-agent-file.ts +3 -3
- package/packages/fleet/src/install-adl-package.ts +73 -15
- package/packages/fleet/src/install-embedding-model.ts +14 -14
- package/packages/fleet/src/managed-settings.ts +7 -7
- package/packages/fleet/src/repo-maintain.ts +439 -0
- package/packages/fleet/src/scratch-reap.ts +6 -6
- package/packages/fleet/src/vscode-settings.ts +5 -5
- package/packages/repo-controls/README.md +141 -43
- package/packages/repo-controls/assets/promote.ts +4 -4
- package/packages/repo-controls/assets/reconcile-guard.sh +10 -46
- package/packages/repo-controls/assets/version-bump.sh +31 -84
- package/packages/repo-controls/bunfig.toml +6 -7
- package/packages/repo-controls/package/adl-compliance/AGENTS.md +5 -6
- package/packages/repo-controls/package/adl-compliance/conftest.py +3 -1
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/__init__.py +4 -16
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/adr_lifecycle/test_check.py +9 -2
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/closed_set/fixtures/docs/notes.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/closed_set/test_check.py +11 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/__init__.py +7 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/check.py +266 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-assets/docs/guide/.drafts/c.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-assets/docs/guide/.drafts/d.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-assets/docs/guide/.hidden.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-assets/docs/guide/a.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-assets/docs/guide/b.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-assets/docs/guide/data.csv +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-assets/docs/guide/diagram.png +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-assets/docs/guide/mock.png +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-assets/docs/guide/sub/nested.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-assets/docs.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-assets/grants.yaml +4 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-assets/plans/deep/p1.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-assets/plans/deep/p2.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-assets/plans/deep/p3.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-assets/plans/deep/p4.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-assets/plans/deep/p5.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-clean/docs/architecture/build.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-clean/docs/architecture/overview.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-clean/docs/guide/install.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-clean/docs/guide/start.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-clean/grants.yaml +4 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-decisions/docs/decisions/adr-001-tenancy.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-decisions/docs/decisions/adr-002-carrier.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-decisions/docs/decisions/adr-003-cli.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-decisions/docs/decisions/archive/adr-000-old.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-decisions/docs/decisions/archive/adr-000-older.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-decisions/docs/guide/a.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-decisions/docs/guide/b.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-decisions/docs/guide/c.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-decisions/grants.yaml +4 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-default-cap/docs/guide/page-01.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-default-cap/docs/guide/page-02.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-default-cap/docs/guide/page-03.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-default-cap/docs/guide/page-04.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-default-cap/docs/guide/page-05.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-default-cap/docs/guide/page-06.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-default-cap/docs/guide/page-07.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-default-cap/docs/guide/page-08.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-default-cap/docs/guide/page-09.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-default-cap/docs/guide/page-10.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-default-cap/docs/guide/page-11.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-default-cap/docs/guide/page-12.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-default-cap/docs/guide/page-13.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-default-cap/docs/guide/page-14.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-default-cap/docs/guide/page-15.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-default-cap/docs/guide/page-16.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-default-cap/grants.yaml +4 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-exempt/docs/guide/a.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-exempt/docs/guide/b.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-exempt/docs/guide/c.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-exempt/grants.yaml +4 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-grew/docs/guide/a.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-grew/docs/guide/b.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-grew/docs/guide/c.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-grew/grants.yaml +4 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-no-section/docs/guide/a.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-no-section/docs/guide/b.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-no-section/docs/guide/c.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-no-section/docs/guide/d.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-no-section/docs/guide/e.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-no-section/grants.yaml +4 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-over-cap/docs/guide/a.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-over-cap/docs/guide/b.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-over-cap/docs/guide/c.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-over-cap/docs/short/only.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-over-cap/grants.yaml +4 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-stale/docs/held/a.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-stale/docs/held/b.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-stale/docs/held/c.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-stale/docs/held/d.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-stale/docs/shrunk/a.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-stale/docs/shrunk/b.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-stale/grants.yaml +6 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-unusable/docs/guide/a.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-unusable/docs/guide/b.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-unusable/docs/guide/c.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-unusable/grants.yaml +3 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/test_check.py +345 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/english_only/check.py +18 -5
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/english_only/test_check.py +35 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/filename/__init__.py +7 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/filename/check.py +91 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/filename/fixtures/docs/AGENTS.md +3 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/filename/fixtures/docs/CLAUDE.md +3 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/filename/fixtures/docs/architecture/-leading-hyphen.md +3 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/filename/fixtures/docs/architecture/AGENTS.md +3 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/filename/fixtures/docs/architecture/double--hyphen.md +3 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/filename/fixtures/docs/architecture/getting started.md +3 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/filename/fixtures/docs/architecture/nested/page-here.md +3 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/filename/fixtures/docs/architecture/trailing-hyphen-.md +3 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/filename/fixtures/docs/architecture/ui-contract.md +4 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/filename/fixtures/docs/architecture/user_profile.md +3 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/filename/fixtures/docs/assets/UI-CONTRACT.png +2 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/filename/fixtures/docs/assets/diagram.png +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/filename/fixtures/docs/index.md +4 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/filename/fixtures/docs/notes.md +3 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/filename/fixtures/docs/reference.html +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/filename/fixtures/docs/research/2026-10-experiment.md +3 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/filename/fixtures/docs/research/UI-CONTRACT.md +6 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/filename/fixtures/docs.md +5 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/filename/test_check.py +194 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/indexes/check.py +14 -2
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/indexes/docs-knowledge-indexes.yaml +5 -5
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/indexes/fixtures/knowledge-indexes-shipped-register-legacy/docs/compliance/index.md +10 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/indexes/fixtures/knowledge-indexes-shipped-register-type/docs/compliance/index.md +10 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/indexes/test_check.py +58 -6
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/ledger/test_check.py +0 -1
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/check.py +64 -17
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/docs-okf-profiles.yaml +60 -9
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-ledger-clean/docs/notes.md +17 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-ledger-no-lines/docs/notes.md +13 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-profile-clean/docs/architecture/demo.md +0 -1
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-profile-clean/docs-okf-profiles.yaml +0 -1
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-profile-untyped/docs/research/no-type.md +9 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-profile-untyped/docs/research/typed-experiment.md +10 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-profile-untyped/docs/research/typed-research.md +10 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-profile-untyped/docs-okf-profiles.yaml +5 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-profile-violation/docs/architecture/bad-status.md +0 -1
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-profile-violation/docs-okf-profiles.yaml +0 -1
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-research/docs/research/experiment-ok.md +15 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-research/docs/research/extra-key.md +15 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-research/docs/research/extra-keys.md +16 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-research/docs/research/missing-created.md +11 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-research/docs/research/missing-description.md +11 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-research/docs/research/missing-last-update.md +11 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-research/docs/research/missing-sources.md +10 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-research/docs/research/missing-status.md +11 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-research/docs/research/missing-title.md +11 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-research/docs/research/optional-keys.md +16 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-research/docs/research/research-ok.md +14 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-research-neighbours/docs/architecture/created-date.md +21 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-research-neighbours/docs/architecture/research-shaped.md +19 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-research-neighbours/docs/operations/runbook.md +26 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/test_check.py +228 -2
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/register.py +5 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/semantics/test_check.py +11 -2
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/__init__.py +5 -3
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/check.py +160 -44
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-clean/grants.yaml +0 -2
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-empty-register/frontend/packages/desktop/src/a.ts +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-empty-register/frontend/packages/desktop/src/b.ts +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-empty-register/grants.yaml +3 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-excluded/grants.yaml +0 -2
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-missing-tree/frontend/packages/desktop/src/renderer/solo/item.ts +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-missing-tree/grants.yaml +5 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-no-ceilings/frontend/packages/desktop/src/a.ts +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-no-ceilings/frontend/packages/desktop/src/b.ts +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-no-ceilings/frontend/packages/desktop/src/c.ts +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-no-ceilings/grants.yaml +4 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-stale-entry/frontend/packages/desktop/src/renderer/solo/item.ts +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-stale-entry/grants.yaml +5 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-unbaselined/grants.yaml +0 -2
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-unusable-register/frontend/packages/desktop/src/renderer/solo/item.ts +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-unusable-register/grants.yaml +3 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/register.py +127 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/test_check.py +265 -29
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/markdown_trees/check.py +75 -2
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/markdown_trees/test_check.py +194 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/open_work_cap/check.py +56 -10
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/open_work_cap/test_check.py +256 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/placement/check.py +40 -12
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/placement/test_check.py +108 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/plans_layout/test_check.py +1 -1
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/references/check.py +2 -3
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/root_closed_set/check.py +23 -6
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/root_closed_set/test_check.py +76 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/root_markdown_allowlist/check.py +58 -17
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/root_markdown_allowlist/test_check.py +161 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/scripts_size_depth/check.py +35 -3
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/scripts_size_depth/test_check.py +108 -1
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/check.py +281 -61
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/malformed/absolute-path.yaml +3 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/malformed/backslash-path.yaml +3 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/malformed/baseline-is-a-list.yaml +2 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/malformed/boolean-size.yaml +3 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/malformed/dot-segment.yaml +3 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/malformed/duplicate-path.yaml +4 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/malformed/empty-file.yaml +0 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/malformed/empty-segment.yaml +3 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/malformed/float-size.yaml +3 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/malformed/negative-size.yaml +3 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/malformed/no-over-limit-baseline.yaml +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/malformed/no-schema-version.yaml +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/malformed/non-string-path.yaml +3 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/malformed/not-yaml.yaml +2 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/malformed/null-size.yaml +3 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/malformed/parent-segment.yaml +3 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/malformed/string-size.yaml +3 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/malformed/top-level-is-a-list.yaml +2 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/malformed/trailing-slash.yaml +3 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/malformed/unknown-key.yaml +3 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/malformed/wrong-schema-version.yaml +2 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/malformed/zero-size.yaml +3 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/valid.yaml +4 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/test_check.py +758 -45
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/repository/ignored_paths/check.py +4 -3
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/repository/ignored_paths/test_check.py +2 -2
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/repository/lockfile_integrity/cargo_lock.py +490 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/repository/lockfile_integrity/check.py +368 -55
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/repository/lockfile_integrity/test_check.py +4 -2
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/repository/lockfile_integrity/test_declared_paths.py +523 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/repository/lockfile_integrity/test_stale_lock.py +1179 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/cli.py +122 -3
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/core/check.py +33 -1
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/core/constants.py +0 -11
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/core/context.py +16 -1
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/policy/config.py +1 -2
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/policy/docs_shape.py +12 -1
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/policy/gate-registry.alt.yaml +133 -147
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/policy/gate-registry.yaml +133 -147
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/policy/registry.py +1 -1
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/policy/root_shape.py +52 -10
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/runner.py +23 -4
- package/packages/repo-controls/package.json +2 -10
- package/packages/repo-controls/scripts/hooks/post-merge +13 -0
- package/packages/repo-controls/scripts/hooks/pre-push +3 -3
- package/packages/repo-controls/src/azdo-push.ts +64 -36
- package/packages/repo-controls/src/azure-devops-governance.ts +7 -9
- package/packages/repo-controls/src/azure-devops-remote.ts +1 -1
- package/packages/repo-controls/src/cli.ts +29 -8
- package/packages/repo-controls/src/compliance-config.ts +410 -2
- package/packages/repo-controls/src/config.ts +133 -60
- package/packages/repo-controls/src/constants.ts +13 -27
- package/packages/repo-controls/src/coverage-ratchet.ts +4 -4
- package/packages/repo-controls/src/doctor.ts +46 -19
- package/packages/repo-controls/src/gitignore-block.ts +5 -29
- package/packages/repo-controls/src/hook-log.ts +1 -2
- package/packages/repo-controls/src/hook.ts +201 -45
- package/packages/repo-controls/src/install.ts +14 -8
- package/packages/repo-controls/src/integrity.ts +3 -3
- package/packages/repo-controls/src/lfs.ts +111 -0
- package/packages/repo-controls/src/promote.ts +8 -8
- package/packages/repo-controls/src/runtime.ts +9 -1
- package/packages/repo-controls/src/workflows-drift.ts +4 -5
- package/packages/repo-controls/src/worktree-guard.ts +3 -3
- package/packages/fleet/jobs/git-maintain/src/main.ts +0 -848
- package/packages/fleet/systemd/adl-azure-agent-update.service +0 -13
- package/packages/fleet/systemd/adl-azure-agent-update.timer +0 -10
|
@@ -1,33 +1,6 @@
|
|
|
1
|
-
export {
|
|
2
|
-
export {
|
|
3
|
-
export {
|
|
4
|
-
export {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
doctorLeanCtx,
|
|
8
|
-
mergeDoctorResults,
|
|
9
|
-
type DoctorIssue,
|
|
10
|
-
type DoctorResult,
|
|
11
|
-
type DoctorMcpOptions,
|
|
12
|
-
type DoctorAgentsOptions,
|
|
13
|
-
type DoctorLeanCtxOptions,
|
|
14
|
-
} from "./doctor.js";
|
|
15
|
-
export { listSettings, type ListOptions, type ListResult, type ListEntry, type ItemOwner } from "./list.js";
|
|
16
|
-
export { deploySettings, doctorSettings, type SettingsTargetOptions, type DeploySettingsResult } from "./settings.js";
|
|
17
|
-
export { lockPathFor, readLock, writeLock, mcpServerOwned, agentOwned, leanCtxOwned, LOCK_RELATIVE_PATH, type SettingsLock, type McpLockEntry } from "./lock.js";
|
|
18
|
-
export {
|
|
19
|
-
DEFAULT_PROFILE_PATH,
|
|
20
|
-
DEFAULT_PROFILE_SCHEMA_PATH,
|
|
21
|
-
loadProfile,
|
|
22
|
-
validateProfileDocument,
|
|
23
|
-
type DeployProfile,
|
|
24
|
-
type McpSurface,
|
|
25
|
-
type AgentSurface,
|
|
26
|
-
type LeanCtxFile,
|
|
27
|
-
type LeanCtxProfileSection,
|
|
28
|
-
type ProfileIssue,
|
|
29
|
-
} from "./profile.js";
|
|
30
|
-
export { loadMcpSource, DEFAULT_MCP_SOURCE_PATH, type McpServerSpec } from "./mcp-source.js";
|
|
31
|
-
export { loadAgentSources, parseAgentToml, type AgentDef } from "./agent-toml.js";
|
|
32
|
-
export { renderAgent, extensionFor } from "./agent-render.js";
|
|
33
|
-
export { stringifyPretty } from "./json-pretty.js";
|
|
1
|
+
export { type DoctorResult } from "./doctor.js";
|
|
2
|
+
export { listSettings } from "./list.js";
|
|
3
|
+
export { deploySettings, doctorSettings, type DeploySettingsResult } from "./settings.js";
|
|
4
|
+
export { loadProfile } from "./profile.js";
|
|
5
|
+
export { loadMcpSource, type McpServerSpec } from "./mcp-source.js";
|
|
6
|
+
export { loadAgentSources, type AgentDef } from "./agent-toml.js";
|
|
@@ -65,7 +65,7 @@ export const sha256Hex = (input: string | Buffer): string => createHash("sha256"
|
|
|
65
65
|
* legacy lock's `merged` section. An entry's identity must not change just
|
|
66
66
|
* because a host or a user rewrote the file and reordered its keys.
|
|
67
67
|
*/
|
|
68
|
-
|
|
68
|
+
function stableStringify(value: unknown): string {
|
|
69
69
|
if (Array.isArray(value)) return `[${value.map(stableStringify).join(",")}]`;
|
|
70
70
|
if (value && typeof value === "object") {
|
|
71
71
|
return `{${Object.keys(value as Record<string, unknown>)
|
|
@@ -81,18 +81,18 @@ export const legacyValueHash = (value: unknown): string => sha256Hex(stableStrin
|
|
|
81
81
|
|
|
82
82
|
export type LegacyJsonPath = readonly (string | number)[];
|
|
83
83
|
|
|
84
|
-
|
|
84
|
+
interface LegacyJsonMergeEntry {
|
|
85
85
|
readonly type: string;
|
|
86
86
|
readonly path: LegacyJsonPath;
|
|
87
87
|
readonly sha256: string;
|
|
88
88
|
}
|
|
89
89
|
|
|
90
|
-
|
|
90
|
+
interface LegacyMergedRecord {
|
|
91
91
|
readonly entries?: readonly LegacyJsonMergeEntry[];
|
|
92
92
|
readonly [key: string]: unknown;
|
|
93
93
|
}
|
|
94
94
|
|
|
95
|
-
|
|
95
|
+
interface LegacyGitignoreRecord {
|
|
96
96
|
readonly created?: boolean;
|
|
97
97
|
readonly lines?: readonly string[];
|
|
98
98
|
readonly appended?: string;
|
|
@@ -126,7 +126,7 @@ export function readLegacyLock(path: string): LegacyLockDoc | undefined {
|
|
|
126
126
|
}
|
|
127
127
|
|
|
128
128
|
/** The legacy lock's recorded whole-file sha256 for `file` under `files`, or `undefined` when unrecorded. */
|
|
129
|
-
|
|
129
|
+
function legacyFileHash(doc: LegacyLockDoc | undefined, file: string): string | undefined {
|
|
130
130
|
return doc?.files?.[file]?.sha256;
|
|
131
131
|
}
|
|
132
132
|
|
|
@@ -207,7 +207,7 @@ export function legacyTakeoverForGitignore(content: string, doc: LegacyLockDoc |
|
|
|
207
207
|
return false;
|
|
208
208
|
}
|
|
209
209
|
|
|
210
|
-
|
|
210
|
+
interface LegacyMergedRemoval {
|
|
211
211
|
readonly file: string;
|
|
212
212
|
readonly paths: readonly LegacyJsonPath[];
|
|
213
213
|
}
|
|
@@ -6,18 +6,18 @@
|
|
|
6
6
|
* (mirrors packages/agent-skills/src/list.ts's shape).
|
|
7
7
|
*/
|
|
8
8
|
import { existsSync, readdirSync } from "node:fs";
|
|
9
|
-
import {
|
|
9
|
+
import { join } from "node:path";
|
|
10
10
|
import { extensionFor } from "./agent-render.js";
|
|
11
11
|
import { loadAgentSources, type AgentDef } from "./agent-toml.js";
|
|
12
|
-
import { agentOwned,
|
|
12
|
+
import { agentOwned, mcpServerOwned, readLock } from "./lock.js";
|
|
13
13
|
import { readDeployedMcpServerNames } from "./mcp-inspect.js";
|
|
14
14
|
import { loadMcpSource, type McpServerSpec } from "./mcp-source.js";
|
|
15
15
|
import { type DeployProfile, loadProfile } from "./profile.js";
|
|
16
16
|
|
|
17
|
-
|
|
17
|
+
type ItemOwner = "adl" | "user" | "conflict" | "-";
|
|
18
18
|
|
|
19
|
-
|
|
20
|
-
readonly kind: "mcp" | "agent"
|
|
19
|
+
interface ListEntry {
|
|
20
|
+
readonly kind: "mcp" | "agent";
|
|
21
21
|
readonly name: string;
|
|
22
22
|
readonly available: boolean;
|
|
23
23
|
readonly deployedIn: readonly string[];
|
|
@@ -117,19 +117,5 @@ export function listSettings(options: ListOptions): ListResult {
|
|
|
117
117
|
entries.push({ ...base, line: formatLine(`agent:${name}`, base) });
|
|
118
118
|
}
|
|
119
119
|
|
|
120
|
-
// --- lean-ctx ---
|
|
121
|
-
if (profile.leanCtx !== undefined) {
|
|
122
|
-
const leanCtxAssetsDir = join(options.assetsRoot, profile.leanCtx.source);
|
|
123
|
-
for (const file of profile.leanCtx.files) {
|
|
124
|
-
const targetAbs = join(options.targetRepo, file.target);
|
|
125
|
-
const deployed = existsSync(targetAbs);
|
|
126
|
-
const owned = leanCtxOwned(lock, file.target);
|
|
127
|
-
const available = existsSync(join(leanCtxAssetsDir, file.asset));
|
|
128
|
-
const owner: ItemOwner = deployed ? (owned ? "adl" : "conflict") : "-";
|
|
129
|
-
const base = { kind: "lean-ctx" as const, name: file.target, available, deployedIn: deployed ? [file.target] : [], owner };
|
|
130
|
-
entries.push({ ...base, line: formatLine(`lean-ctx:${basename(file.target)}`, base) });
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
|
|
134
120
|
return { entries, lines: entries.map((e) => e.line) };
|
|
135
121
|
}
|
|
@@ -13,32 +13,27 @@
|
|
|
13
13
|
* breakdown is needed.
|
|
14
14
|
* - `agents`: target folder -> the agent NAMES this deploy wrote as files
|
|
15
15
|
* in that folder (one file per agent, so this is the removal unit).
|
|
16
|
-
* - `leanCtx`: target path -> `true` for each repo-local lean-ctx file
|
|
17
|
-
* (config.toml, layout.toml, .agents/.gitignore) this deploy wrote —
|
|
18
|
-
* one whole file is the removal unit, same as agents but keyed directly
|
|
19
|
-
* by target path since there is no per-file "container".
|
|
20
16
|
*
|
|
21
17
|
* A name/file missing from a later run's lock (because it fell out of
|
|
22
18
|
* assets/) is removed from the target on that run; anything not recorded
|
|
23
19
|
* here was never written by us and is never touched.
|
|
24
20
|
*
|
|
25
|
-
* `leanCtx`
|
|
26
|
-
*
|
|
27
|
-
* a malformed lock.
|
|
21
|
+
* The optional `leanCtx` field remains readable only so deploy can retire
|
|
22
|
+
* paths recorded by older releases. New locks never write it.
|
|
28
23
|
*/
|
|
29
24
|
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
30
25
|
import { dirname, join } from "node:path";
|
|
31
26
|
|
|
32
|
-
|
|
27
|
+
const LOCK_RELATIVE_PATH = ".agents/agent-settings.lock.json";
|
|
33
28
|
const LOCK_SCHEMA = 1;
|
|
34
29
|
|
|
35
|
-
|
|
30
|
+
interface McpJsonLockEntry {
|
|
36
31
|
readonly kind: "json";
|
|
37
32
|
/** MCP server names this deploy owns in this file's server map. */
|
|
38
33
|
readonly servers: readonly string[];
|
|
39
34
|
}
|
|
40
35
|
|
|
41
|
-
|
|
36
|
+
interface McpBlockLockEntry {
|
|
42
37
|
readonly kind: "block";
|
|
43
38
|
readonly owned: true;
|
|
44
39
|
}
|
|
@@ -49,10 +44,10 @@ export interface SettingsLock {
|
|
|
49
44
|
readonly schema: number;
|
|
50
45
|
readonly mcp: Readonly<Record<string, McpLockEntry>>;
|
|
51
46
|
readonly agents: Readonly<Record<string, readonly string[]>>;
|
|
52
|
-
readonly leanCtx
|
|
47
|
+
readonly leanCtx?: Readonly<Record<string, boolean>>;
|
|
53
48
|
}
|
|
54
49
|
|
|
55
|
-
const EMPTY_LOCK: SettingsLock = { schema: LOCK_SCHEMA, mcp: {}, agents: {}
|
|
50
|
+
const EMPTY_LOCK: SettingsLock = { schema: LOCK_SCHEMA, mcp: {}, agents: {} };
|
|
56
51
|
|
|
57
52
|
export function lockPathFor(targetRepo: string): string {
|
|
58
53
|
return join(targetRepo, LOCK_RELATIVE_PATH);
|
|
@@ -92,7 +87,7 @@ export function readLock(targetRepo: string): SettingsLock {
|
|
|
92
87
|
/** Skips the write entirely when the serialized content is already byte-identical (independent review, 2026-09-29, finding 8: a genuine no-op run must not touch the lock file's mtime either). */
|
|
93
88
|
export function writeLock(targetRepo: string, lock: SettingsLock): void {
|
|
94
89
|
const path = lockPathFor(targetRepo);
|
|
95
|
-
const next = `${JSON.stringify({ schema: LOCK_SCHEMA, mcp: lock.mcp, agents: lock.agents
|
|
90
|
+
const next = `${JSON.stringify({ schema: LOCK_SCHEMA, mcp: lock.mcp, agents: lock.agents }, null, 2)}\n`;
|
|
96
91
|
if (existsSync(path) && readFileSync(path, "utf8") === next) return;
|
|
97
92
|
mkdirSync(dirname(path), { recursive: true });
|
|
98
93
|
writeFileSync(path, next);
|
|
@@ -108,8 +103,3 @@ export function mcpServerOwned(lock: SettingsLock, file: string, serverName: str
|
|
|
108
103
|
export function agentOwned(lock: SettingsLock, folder: string, agentName: string): boolean {
|
|
109
104
|
return (lock.agents[folder] ?? []).includes(agentName);
|
|
110
105
|
}
|
|
111
|
-
|
|
112
|
-
/** True iff the lock records `targetPath` as an adl-owned lean-ctx file. */
|
|
113
|
-
export function leanCtxOwned(lock: SettingsLock, targetPath: string): boolean {
|
|
114
|
-
return lock.leanCtx[targetPath] === true;
|
|
115
|
-
}
|
|
@@ -24,7 +24,7 @@ import {
|
|
|
24
24
|
readLegacyLock,
|
|
25
25
|
stripLegacyOwnership,
|
|
26
26
|
} from "./legacy-lock.js";
|
|
27
|
-
import { type
|
|
27
|
+
import { type McpLockEntry, readLock, writeLock } from "./lock.js";
|
|
28
28
|
import { hasForeignTopLevelTable, mergeCodexBlock, mergeServerMap } from "./mcp-merge.js";
|
|
29
29
|
import { renderCodexManagedBlock, renderMcpJsonEntry } from "./mcp-render.js";
|
|
30
30
|
import { loadMcpSource, type McpServerSpec } from "./mcp-source.js";
|
|
@@ -40,7 +40,7 @@ export interface DeployMcpOptions {
|
|
|
40
40
|
readonly dryRun?: boolean;
|
|
41
41
|
}
|
|
42
42
|
|
|
43
|
-
|
|
43
|
+
interface McpFileConflict {
|
|
44
44
|
readonly file: string;
|
|
45
45
|
readonly server: string;
|
|
46
46
|
readonly reason: string;
|
|
@@ -50,6 +50,8 @@ export interface DeployMcpResult {
|
|
|
50
50
|
readonly written: readonly string[];
|
|
51
51
|
readonly unchanged: readonly string[];
|
|
52
52
|
readonly conflicts: readonly McpFileConflict[];
|
|
53
|
+
/** Same-name entries not in the lock whose value was identical to what deploy renders: taken over, locked, never a conflict. */
|
|
54
|
+
readonly adopted: readonly { readonly file: string; readonly server: string }[];
|
|
53
55
|
readonly lockPath: string;
|
|
54
56
|
}
|
|
55
57
|
|
|
@@ -95,6 +97,7 @@ export function deployMcp(options: DeployMcpOptions): DeployMcpResult {
|
|
|
95
97
|
const written: string[] = [];
|
|
96
98
|
const unchanged: string[] = [];
|
|
97
99
|
const conflicts: McpFileConflict[] = [];
|
|
100
|
+
const adopted: { file: string; server: string }[] = [];
|
|
98
101
|
const legacyMergedRemovals: { file: string; paths: LegacyJsonPath[] }[] = [];
|
|
99
102
|
const legacyTomlRemovals: string[] = [];
|
|
100
103
|
let anyLegacyTakeover = false;
|
|
@@ -147,15 +150,16 @@ export function deployMcp(options: DeployMcpOptions): DeployMcpResult {
|
|
|
147
150
|
const effectivePreviousOwned = legacyTakeover.matched ? [...new Set([...previousOwned, ...legacyTakeover.ownedServers])] : previousOwned;
|
|
148
151
|
const desired = new Map<string, unknown>(servers.map((spec) => [spec.name, renderMcpJsonEntry(surface.entry, spec)]));
|
|
149
152
|
|
|
150
|
-
const { fileContent, ownedServers, conflicts: serverConflicts, changed } = mergeServerMap(existingRaw, topKey, desired, effectivePreviousOwned);
|
|
153
|
+
const { fileContent, ownedServers, conflicts: serverConflicts, adopted: serverAdopted, changed } = mergeServerMap(existingRaw, topKey, desired, effectivePreviousOwned);
|
|
151
154
|
for (const c of serverConflicts) conflicts.push({ file: surface.file, server: c.server, reason: c.reason });
|
|
155
|
+
for (const server of serverAdopted) adopted.push({ file: surface.file, server });
|
|
152
156
|
|
|
153
157
|
writeIfChanged(targetAbs, `${serializeJsonStyle(surface.jsonStyle as "width-aware" | "expanded", fileContent)}\n`, changed, dryRun);
|
|
154
158
|
(changed ? written : unchanged).push(surface.file);
|
|
155
159
|
newMcpEntries[surface.file] = { kind: "json", servers: ownedServers };
|
|
156
160
|
}
|
|
157
161
|
|
|
158
|
-
if (!dryRun) writeLock(targetRepo, { schema: 1, mcp: newMcpEntries, agents: lock.agents
|
|
162
|
+
if (!dryRun) writeLock(targetRepo, { schema: 1, mcp: newMcpEntries, agents: lock.agents });
|
|
159
163
|
|
|
160
164
|
// Once anything was actually taken over, this package's own footprint in
|
|
161
165
|
// the legacy lock (the four MCP `merged` sections and the codex `toml`
|
|
@@ -171,8 +175,9 @@ export function deployMcp(options: DeployMcpOptions): DeployMcpResult {
|
|
|
171
175
|
written: written.sort(),
|
|
172
176
|
unchanged: unchanged.sort(),
|
|
173
177
|
conflicts: conflicts.sort((a, b) => `${a.file}/${a.server}`.localeCompare(`${b.file}/${b.server}`)),
|
|
178
|
+
adopted: adopted.sort((a, b) => `${a.file}/${a.server}`.localeCompare(`${b.file}/${b.server}`)),
|
|
174
179
|
lockPath: join(targetRepo, ".agents/agent-settings.lock.json"),
|
|
175
180
|
};
|
|
176
181
|
}
|
|
177
182
|
|
|
178
|
-
|
|
183
|
+
;
|
|
@@ -22,7 +22,9 @@
|
|
|
22
22
|
* `.cursor/mcp.json` / `.kimi-code/mcp.json` / the `mcp` key of
|
|
23
23
|
* `opencode.json` / the codex block (up to its marker line) byte-for-byte.
|
|
24
24
|
*/
|
|
25
|
-
|
|
25
|
+
import { isDeepStrictEqual } from "node:util";
|
|
26
|
+
|
|
27
|
+
interface McpServerConflict {
|
|
26
28
|
readonly server: string;
|
|
27
29
|
readonly reason: string;
|
|
28
30
|
}
|
|
@@ -32,6 +34,8 @@ export interface JsonServerMergeResult {
|
|
|
32
34
|
/** New lock contents: the MCP server names this deploy now owns in this file's server map. */
|
|
33
35
|
readonly ownedServers: readonly string[];
|
|
34
36
|
readonly conflicts: readonly McpServerConflict[];
|
|
37
|
+
/** Same-name servers not recorded as ours whose value is deep-equal to what deploy renders: adopted into `ownedServers`, never a conflict. */
|
|
38
|
+
readonly adopted: readonly string[];
|
|
35
39
|
readonly changed: boolean;
|
|
36
40
|
}
|
|
37
41
|
|
|
@@ -40,7 +44,11 @@ export interface JsonServerMergeResult {
|
|
|
40
44
|
* `desired` must be provided in the exact order a fresh file should list
|
|
41
45
|
* servers in. A same-name server already present and NOT recorded as ours
|
|
42
46
|
* in a previous run (`previousOwned`) is a conflict: left untouched,
|
|
43
|
-
* reported, never claimed in `ownedServers` (M4/D5-equivalent for MCP)
|
|
47
|
+
* reported, never claimed in `ownedServers` (M4/D5-equivalent for MCP) —
|
|
48
|
+
* unless its value is deep-equal to the desired one, in which case it holds
|
|
49
|
+
* no user content and is ADOPTED (Tarun, 2026-10-01): recorded in
|
|
50
|
+
* `ownedServers` and named in `adopted`, same rule as lean-ctx's
|
|
51
|
+
* `adoptUnmarkedManagedText`. Any difference at all stays a conflict.
|
|
44
52
|
*/
|
|
45
53
|
export function mergeServerMap(
|
|
46
54
|
existing: Record<string, unknown> | undefined,
|
|
@@ -64,8 +72,19 @@ export function mergeServerMap(
|
|
|
64
72
|
|
|
65
73
|
const conflicts: McpServerConflict[] = [];
|
|
66
74
|
const owned: string[] = [];
|
|
75
|
+
const adopted: string[] = [];
|
|
67
76
|
for (const [name, value] of desired) {
|
|
68
77
|
if (Object.prototype.hasOwnProperty.call(newServers, name)) {
|
|
78
|
+
if (isDeepStrictEqual(newServers[name], value)) {
|
|
79
|
+
// Identical to what we would write: take it over. Re-added below at
|
|
80
|
+
// the desired position, exactly like an entry we already owned, so
|
|
81
|
+
// the next run's drop-and-re-add sees the same order (no-op).
|
|
82
|
+
delete newServers[name];
|
|
83
|
+
newServers[name] = value;
|
|
84
|
+
owned.push(name);
|
|
85
|
+
adopted.push(name);
|
|
86
|
+
continue;
|
|
87
|
+
}
|
|
69
88
|
conflicts.push({ server: name, reason: "a user-owned MCP server already exists with this name; deploy left it untouched" });
|
|
70
89
|
continue; // never overwrite it, never claim it in the lock
|
|
71
90
|
}
|
|
@@ -76,7 +95,7 @@ export function mergeServerMap(
|
|
|
76
95
|
base[topKey] = newServers;
|
|
77
96
|
const changed = existing === undefined || JSON.stringify(existingServers) !== JSON.stringify(newServers);
|
|
78
97
|
|
|
79
|
-
return { fileContent: base, ownedServers: owned, conflicts, changed };
|
|
98
|
+
return { fileContent: base, ownedServers: owned, conflicts, adopted, changed };
|
|
80
99
|
}
|
|
81
100
|
|
|
82
101
|
export interface CodexBlockMergeResult {
|
|
@@ -14,7 +14,7 @@ export interface McpServerSpec {
|
|
|
14
14
|
readonly args: readonly string[];
|
|
15
15
|
}
|
|
16
16
|
|
|
17
|
-
|
|
17
|
+
const DEFAULT_MCP_SOURCE_PATH = fileURLToPath(new URL("../../assets/mcp.json", import.meta.url));
|
|
18
18
|
|
|
19
19
|
function isServerSpec(value: unknown): value is { command: string; args: readonly string[] } {
|
|
20
20
|
if (typeof value !== "object" || value === null) return false;
|
|
@@ -34,13 +34,13 @@ import Ajv, { type ErrorObject, type ValidateFunction } from "ajv";
|
|
|
34
34
|
import { readFileSync } from "node:fs";
|
|
35
35
|
import { fileURLToPath } from "node:url";
|
|
36
36
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
37
|
+
type McpSurfaceFormat = "json" | "toml-block";
|
|
38
|
+
type AgentSurfaceFormat = "md" | "toml";
|
|
39
|
+
type McpJsonStyle = "width-aware" | "expanded";
|
|
40
40
|
export type McpFromToken = "command" | "args" | "commandArgs";
|
|
41
41
|
/** The full set a `from` token may name across BOTH front-matter fields and TOML fields; which subset is valid for which is enforced by the schema's two separate enums (agentFrontMatterField vs agentTomlField). */
|
|
42
42
|
export type AgentFromToken = "name" | "description" | "model" | "claude_model" | "cursor_model" | "tools" | "model_reasoning_effort" | "sandbox_mode";
|
|
43
|
-
|
|
43
|
+
type AgentFieldStyle = "plain" | "csv-list";
|
|
44
44
|
|
|
45
45
|
export interface McpEntryField {
|
|
46
46
|
readonly key: string;
|
|
@@ -49,7 +49,7 @@ export interface McpEntryField {
|
|
|
49
49
|
}
|
|
50
50
|
|
|
51
51
|
/** A static (non-per-server) field in a `topLevel` TOML table — always a constant, since there is no per-server spec to draw `from`. */
|
|
52
|
-
|
|
52
|
+
interface McpTopLevelField {
|
|
53
53
|
readonly key: string;
|
|
54
54
|
readonly const: string | boolean | number;
|
|
55
55
|
}
|
|
@@ -103,40 +103,28 @@ export interface AgentSurface {
|
|
|
103
103
|
readonly bodyField?: "developer_instructions";
|
|
104
104
|
}
|
|
105
105
|
|
|
106
|
-
|
|
106
|
+
interface McpProfileSection {
|
|
107
107
|
readonly source: string;
|
|
108
108
|
readonly marker?: string;
|
|
109
109
|
readonly surfaces: readonly McpSurface[];
|
|
110
110
|
}
|
|
111
111
|
|
|
112
|
-
|
|
112
|
+
interface AgentProfileSection {
|
|
113
113
|
readonly source: string;
|
|
114
114
|
readonly surfaces: readonly AgentSurface[];
|
|
115
115
|
}
|
|
116
116
|
|
|
117
|
-
export interface LeanCtxFile {
|
|
118
|
-
readonly asset: string;
|
|
119
|
-
readonly target: string;
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
export interface LeanCtxProfileSection {
|
|
123
|
-
readonly source: string;
|
|
124
|
-
readonly files: readonly LeanCtxFile[];
|
|
125
|
-
}
|
|
126
|
-
|
|
127
117
|
export interface DeployProfile {
|
|
128
118
|
readonly mcp: McpProfileSection;
|
|
129
119
|
readonly agents: AgentProfileSection;
|
|
130
|
-
/** Optional: absent in older/fixture profiles (e.g. tests/fixtures/two-surface-profile.json), which cover only mcp/agents. deployLeanCtx/doctorLeanCtx throw if called against a profile without this section. */
|
|
131
|
-
readonly leanCtx?: LeanCtxProfileSection;
|
|
132
120
|
/** Repo-relative path to the pre-agent-settings engine's own install lock, if this repo may still carry one (see deploy-profile.schema.json and legacy-lock.ts). */
|
|
133
121
|
readonly legacyLock?: string;
|
|
134
122
|
}
|
|
135
123
|
|
|
136
|
-
|
|
137
|
-
|
|
124
|
+
const DEFAULT_PROFILE_PATH = fileURLToPath(new URL("../../deploy-profile.json", import.meta.url));
|
|
125
|
+
const DEFAULT_PROFILE_SCHEMA_PATH = fileURLToPath(new URL("../../deploy-profile.schema.json", import.meta.url));
|
|
138
126
|
|
|
139
|
-
|
|
127
|
+
interface ProfileIssue {
|
|
140
128
|
readonly path: string;
|
|
141
129
|
readonly message: string;
|
|
142
130
|
}
|
|
@@ -250,18 +238,6 @@ function crossFieldChecks(doc: DeployProfile): readonly ProfileIssue[] {
|
|
|
250
238
|
}
|
|
251
239
|
});
|
|
252
240
|
|
|
253
|
-
if (doc.leanCtx !== undefined) {
|
|
254
|
-
const leanCtxTargets = new Set<string>();
|
|
255
|
-
const leanCtxAssets = new Set<string>();
|
|
256
|
-
doc.leanCtx.files.forEach((file, index) => {
|
|
257
|
-
const p = `/leanCtx/files/${index}`;
|
|
258
|
-
if (leanCtxTargets.has(file.target)) issues.push({ path: `${p}/target`, message: `duplicate leanCtx target: ${file.target}` });
|
|
259
|
-
leanCtxTargets.add(file.target);
|
|
260
|
-
if (leanCtxAssets.has(file.asset)) issues.push({ path: `${p}/asset`, message: `duplicate leanCtx asset: ${file.asset}` });
|
|
261
|
-
leanCtxAssets.add(file.asset);
|
|
262
|
-
});
|
|
263
|
-
}
|
|
264
|
-
|
|
265
241
|
return issues;
|
|
266
242
|
}
|
|
267
243
|
|
|
@@ -271,7 +247,7 @@ function crossFieldChecks(doc: DeployProfile): readonly ProfileIssue[] {
|
|
|
271
247
|
* comment). Pure: never throws for a structurally-wrong `doc` (returns
|
|
272
248
|
* issues instead); only a missing/malformed `schemaPath` throws.
|
|
273
249
|
*/
|
|
274
|
-
|
|
250
|
+
function validateProfileDocument(doc: unknown, schemaPath: string = DEFAULT_PROFILE_SCHEMA_PATH): readonly ProfileIssue[] {
|
|
275
251
|
const validate = compileValidator(schemaPath);
|
|
276
252
|
if (!validate(doc)) {
|
|
277
253
|
return (validate.errors ?? []).map(formatAjvError);
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
/** Remove repo-local lean-ctx artifacts recorded by older agent-settings locks. */
|
|
2
|
+
import { existsSync, lstatSync, readFileSync, rmSync, rmdirSync, unlinkSync, writeFileSync } from "node:fs";
|
|
3
|
+
import { dirname, isAbsolute, relative, resolve, sep } from "node:path";
|
|
4
|
+
import {
|
|
5
|
+
legacyFileTakeover,
|
|
6
|
+
legacyTakeoverForGitignore,
|
|
7
|
+
readLegacyLock,
|
|
8
|
+
stripLegacyOwnership,
|
|
9
|
+
type LegacyLockDoc,
|
|
10
|
+
} from "./legacy-lock.js";
|
|
11
|
+
import { readLock, writeLock } from "./lock.js";
|
|
12
|
+
|
|
13
|
+
const LOCKED_LEAN_CTX_ROOT = ".agents/lean-ctx";
|
|
14
|
+
const AGENTS_GITIGNORE = ".agents/.gitignore";
|
|
15
|
+
const RETIRED_GITIGNORE_LINE = /^\/(?:lean-ctx\/(?:data|cache|state|bin)\/|lean-ctx\/config\/lean-ctx\/workspace-trust\.toml)$/;
|
|
16
|
+
|
|
17
|
+
export interface RetireLeanCtxOptions {
|
|
18
|
+
readonly targetRepo: string;
|
|
19
|
+
readonly legacyLockPath?: string;
|
|
20
|
+
readonly dryRun?: boolean;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export interface RetireLeanCtxResult {
|
|
24
|
+
readonly removed: readonly string[];
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function isWithin(root: string, path: string): boolean {
|
|
28
|
+
const rel = relative(root, path);
|
|
29
|
+
return rel !== "" && rel !== ".." && !rel.startsWith(`..${sep}`) && !isAbsolute(rel);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function assertOwnedTarget(targetRepo: string, target: string): string {
|
|
33
|
+
if (target !== AGENTS_GITIGNORE && !target.startsWith(`${LOCKED_LEAN_CTX_ROOT}/`)) {
|
|
34
|
+
throw new Error(`agent-settings retirement lock contains an unexpected lean-ctx path: ${target}`);
|
|
35
|
+
}
|
|
36
|
+
const absolute = resolve(targetRepo, target);
|
|
37
|
+
if (!isWithin(resolve(targetRepo), absolute)) {
|
|
38
|
+
throw new Error(`agent-settings retirement path escapes target repo: ${target}`);
|
|
39
|
+
}
|
|
40
|
+
return absolute;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function assertRegularFile(path: string): void {
|
|
44
|
+
const stat = lstatSync(path);
|
|
45
|
+
if (!stat.isFile()) throw new Error(`agent-settings retirement target is not a regular file: ${path}`);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function removeLegacyGitignore(content: string, record: NonNullable<LegacyLockDoc["gitignore"]>[string]): string | undefined {
|
|
49
|
+
if (record.created === true) return undefined;
|
|
50
|
+
const owned = record.appended ?? (record.lines === undefined ? undefined : `${record.lines.join("\n")}\n`);
|
|
51
|
+
if (owned === undefined || !content.endsWith(owned)) {
|
|
52
|
+
throw new Error("agent-settings retirement could not isolate the legacy lean-ctx .agents/.gitignore addition");
|
|
53
|
+
}
|
|
54
|
+
const remaining = content.slice(0, -owned.length);
|
|
55
|
+
return remaining.length === 0 ? undefined : remaining;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
function removeManagedGitignoreBlock(content: string): string | undefined {
|
|
59
|
+
const lines = content.match(/[^\n]*\n|[^\n]+$/g) ?? [];
|
|
60
|
+
const open = "# >>> adl managed (do not edit within this block) >>>\n";
|
|
61
|
+
const close = "# <<< adl managed <<<\n";
|
|
62
|
+
const starts = lines.flatMap((line, index) => line === open ? [index] : []);
|
|
63
|
+
const ends = lines.flatMap((line, index) => line === close ? [index] : []);
|
|
64
|
+
if (starts.length !== ends.length || starts.length > 1 || (starts.length === 1 && (ends[0] as number) < (starts[0] as number))) {
|
|
65
|
+
throw new Error("agent-settings retirement found malformed managed markers in .agents/.gitignore");
|
|
66
|
+
}
|
|
67
|
+
if (starts.length === 1) lines.splice(starts[0] as number, (ends[0] as number) - (starts[0] as number) + 1);
|
|
68
|
+
const remaining = lines
|
|
69
|
+
.filter((line) => !RETIRED_GITIGNORE_LINE.test(line.replace(/\r?\n$/, "")))
|
|
70
|
+
.join("");
|
|
71
|
+
return remaining.length === 0 ? undefined : remaining;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
function pruneEmptyDirectories(targetRepo: string, start: string, dryRun: boolean): void {
|
|
75
|
+
const stop = resolve(targetRepo, LOCKED_LEAN_CTX_ROOT);
|
|
76
|
+
let current = dirname(start);
|
|
77
|
+
while (current === stop || isWithin(stop, current)) {
|
|
78
|
+
if (!dryRun) {
|
|
79
|
+
try {
|
|
80
|
+
rmdirSync(current);
|
|
81
|
+
} catch (error) {
|
|
82
|
+
const code = (error as NodeJS.ErrnoException).code;
|
|
83
|
+
if (code === "ENOENT") {
|
|
84
|
+
current = dirname(current);
|
|
85
|
+
continue;
|
|
86
|
+
}
|
|
87
|
+
if (code === "ENOTEMPTY" || code === "EEXIST") return;
|
|
88
|
+
throw error;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
if (current === stop) return;
|
|
92
|
+
current = dirname(current);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* One-time migration for the leanCtx lock field and the legacy installer
|
|
98
|
+
* records. It removes only lock-owned paths; new locks omit the retired field.
|
|
99
|
+
*/
|
|
100
|
+
export function retireLeanCtx(options: RetireLeanCtxOptions): RetireLeanCtxResult {
|
|
101
|
+
const { targetRepo, dryRun = false } = options;
|
|
102
|
+
const lock = readLock(targetRepo);
|
|
103
|
+
const legacy = options.legacyLockPath === undefined ? undefined : readLegacyLock(options.legacyLockPath);
|
|
104
|
+
const targets = new Set(Object.entries(lock.leanCtx ?? {}).filter(([, owned]) => owned === true).map(([target]) => target));
|
|
105
|
+
const legacyFiles: string[] = [];
|
|
106
|
+
const legacyGitignore: string[] = [];
|
|
107
|
+
const legacyReplacements = new Map<string, string | undefined>();
|
|
108
|
+
|
|
109
|
+
for (const target of Object.keys(legacy?.files ?? {})) {
|
|
110
|
+
if (!target.startsWith(`${LOCKED_LEAN_CTX_ROOT}/`)) continue;
|
|
111
|
+
const absolute = assertOwnedTarget(targetRepo, target);
|
|
112
|
+
if (!existsSync(absolute)) continue;
|
|
113
|
+
assertRegularFile(absolute);
|
|
114
|
+
if (legacyFileTakeover(readFileSync(absolute), legacy, target)) {
|
|
115
|
+
targets.add(target);
|
|
116
|
+
legacyFiles.push(target);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
const legacyGitignoreRecord = legacy?.gitignore?.[AGENTS_GITIGNORE];
|
|
121
|
+
const gitignoreAbs = targets.has(AGENTS_GITIGNORE) || legacyGitignoreRecord !== undefined
|
|
122
|
+
? assertOwnedTarget(targetRepo, AGENTS_GITIGNORE)
|
|
123
|
+
: undefined;
|
|
124
|
+
if (legacyGitignoreRecord !== undefined && gitignoreAbs !== undefined && existsSync(gitignoreAbs)) {
|
|
125
|
+
assertRegularFile(gitignoreAbs);
|
|
126
|
+
const current = readFileSync(gitignoreAbs, "utf8");
|
|
127
|
+
if (legacyTakeoverForGitignore(current, legacy, AGENTS_GITIGNORE)) {
|
|
128
|
+
legacyReplacements.set(AGENTS_GITIGNORE, removeLegacyGitignore(current, legacyGitignoreRecord));
|
|
129
|
+
legacyGitignore.push(AGENTS_GITIGNORE);
|
|
130
|
+
targets.add(AGENTS_GITIGNORE);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
for (const target of targets) {
|
|
135
|
+
const absolute = assertOwnedTarget(targetRepo, target);
|
|
136
|
+
if (!existsSync(absolute) || target === AGENTS_GITIGNORE) continue;
|
|
137
|
+
assertRegularFile(absolute);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
const removed: string[] = [];
|
|
141
|
+
const ownsRepoTree = [...targets].some((target) => target.startsWith(`${LOCKED_LEAN_CTX_ROOT}/`));
|
|
142
|
+
const repoTreeAbs = resolve(targetRepo, LOCKED_LEAN_CTX_ROOT);
|
|
143
|
+
if (ownsRepoTree && existsSync(repoTreeAbs)) {
|
|
144
|
+
const treeStat = lstatSync(repoTreeAbs);
|
|
145
|
+
if (!treeStat.isDirectory() || treeStat.isSymbolicLink()) {
|
|
146
|
+
throw new Error(`agent-settings retirement tree is not a real directory: ${repoTreeAbs}`);
|
|
147
|
+
}
|
|
148
|
+
if (!dryRun) rmSync(repoTreeAbs, { recursive: true });
|
|
149
|
+
removed.push(LOCKED_LEAN_CTX_ROOT);
|
|
150
|
+
}
|
|
151
|
+
for (const target of targets) {
|
|
152
|
+
const absolute = assertOwnedTarget(targetRepo, target);
|
|
153
|
+
if (target.startsWith(`${LOCKED_LEAN_CTX_ROOT}/`)) continue;
|
|
154
|
+
if (!existsSync(absolute)) {
|
|
155
|
+
if (target !== AGENTS_GITIGNORE) pruneEmptyDirectories(targetRepo, absolute, dryRun);
|
|
156
|
+
continue;
|
|
157
|
+
}
|
|
158
|
+
if (target === AGENTS_GITIGNORE) {
|
|
159
|
+
assertRegularFile(absolute);
|
|
160
|
+
const current = readFileSync(absolute, "utf8");
|
|
161
|
+
const replacement = legacyReplacements.has(target)
|
|
162
|
+
? legacyReplacements.get(target)
|
|
163
|
+
: removeManagedGitignoreBlock(current);
|
|
164
|
+
if (replacement === undefined || replacement.length === 0) {
|
|
165
|
+
if (!dryRun) unlinkSync(absolute);
|
|
166
|
+
} else if (replacement !== current && !dryRun) {
|
|
167
|
+
writeFileSync(absolute, replacement);
|
|
168
|
+
}
|
|
169
|
+
removed.push(target);
|
|
170
|
+
continue;
|
|
171
|
+
}
|
|
172
|
+
if (!dryRun) unlinkSync(absolute);
|
|
173
|
+
removed.push(target);
|
|
174
|
+
pruneEmptyDirectories(targetRepo, absolute, dryRun);
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
if (!dryRun) {
|
|
178
|
+
if (lock.leanCtx !== undefined) writeLock(targetRepo, { schema: 1, mcp: lock.mcp, agents: lock.agents });
|
|
179
|
+
if (legacy !== undefined && options.legacyLockPath !== undefined && (legacyFiles.length > 0 || legacyGitignore.length > 0)) {
|
|
180
|
+
stripLegacyOwnership(legacy, options.legacyLockPath, { files: legacyFiles, gitignore: legacyGitignore });
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
return { removed: removed.sort() };
|
|
184
|
+
}
|