@webpresso/agent-kit 0.28.0 → 0.29.1
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/.claude-plugin/marketplace.json +2 -2
- package/.claude-plugin/plugin.json +2 -3
- package/README.md +2 -2
- package/bin/_run.js +6 -0
- package/bin/wp +5 -0
- package/catalog/base-kit/.github/actions/setup-webpresso/action.yml.tmpl +21 -0
- package/catalog/base-kit/.github/workflows/{ci.webpresso.yml.tmpl → ci.yml.tmpl} +17 -7
- package/catalog/base-kit/tsconfig.json.tmpl +1 -1
- package/catalog/docs/templates/blueprint.yaml +1 -1
- package/dist/esm/audit/_budgets.d.ts +9 -1
- package/dist/esm/audit/_budgets.js +8 -1
- package/dist/esm/audit/blueprint-db-consistency.js +2 -2
- package/dist/esm/audit/blueprint-lifecycle-sql.d.ts +17 -7
- package/dist/esm/audit/blueprint-lifecycle-sql.js +298 -48
- package/dist/esm/audit/blueprint-readme-drift.d.ts +6 -0
- package/dist/esm/audit/blueprint-readme-drift.js +110 -0
- package/dist/esm/audit/no-first-party-mjs.js +5 -4
- package/dist/esm/audit/package-surface.js +79 -10
- package/dist/esm/audit/repo-guardrails.d.ts +1 -1
- package/dist/esm/audit/repo-guardrails.js +43 -3
- package/dist/esm/audit/tech-debt-cadence.js +2 -3
- package/dist/esm/audit/toolchain-isolation.js +2 -3
- package/dist/esm/blueprint/core/parser.js +3 -2
- package/dist/esm/blueprint/core/schema.d.ts +3 -2
- package/dist/esm/blueprint/core/schema.js +1 -1
- package/dist/esm/blueprint/cross-repo/audit.js +3 -4
- package/dist/esm/blueprint/db/cold-start.js +2 -3
- package/dist/esm/blueprint/db/enums.d.ts +1 -1
- package/dist/esm/blueprint/db/ephemeral-projection.d.ts +25 -0
- package/dist/esm/blueprint/db/ephemeral-projection.js +36 -0
- package/dist/esm/blueprint/db/gc.d.ts +11 -0
- package/dist/esm/blueprint/db/gc.js +55 -0
- package/dist/esm/blueprint/db/ingester.js +39 -1
- package/dist/esm/blueprint/db/migrations/run.js +5 -3
- package/dist/esm/blueprint/db/paths.d.ts +13 -24
- package/dist/esm/blueprint/db/paths.js +25 -33
- package/dist/esm/blueprint/execution/progress-bridge.js +5 -4
- package/dist/esm/blueprint/freshness.d.ts +2 -0
- package/dist/esm/blueprint/freshness.js +3 -1
- package/dist/esm/blueprint/lifecycle/audit.js +6 -6
- package/dist/esm/blueprint/lifecycle/engine.d.ts +1 -1
- package/dist/esm/blueprint/lifecycle/engine.js +13 -9
- package/dist/esm/blueprint/lifecycle/transition-matrix.d.ts +5 -0
- package/dist/esm/blueprint/lifecycle/transition-matrix.js +20 -0
- package/dist/esm/blueprint/markdown/helpers.d.ts +1 -1
- package/dist/esm/blueprint/projection-ready.js +2 -0
- package/dist/esm/blueprint/service/BlueprintService.js +1 -1
- package/dist/esm/blueprint/service/blueprint-records.js +1 -1
- package/dist/esm/blueprint/tracked-document/parser.js +1 -1
- package/dist/esm/blueprint/utils/archive.d.ts +2 -2
- package/dist/esm/blueprint/utils/archive.js +5 -2
- package/dist/esm/blueprint/utils/package-assets.d.ts +13 -0
- package/dist/esm/blueprint/utils/package-assets.js +38 -6
- package/dist/esm/build/normalize-tsconfig-json-exports.d.ts +13 -0
- package/dist/esm/build/normalize-tsconfig-json-exports.js +39 -0
- package/dist/esm/build/package-manifest.js +12 -4
- package/dist/esm/build/release-policy.d.ts +9 -18
- package/dist/esm/build/release-policy.js +10 -19
- package/dist/esm/build/runtime-surface-policy.d.ts +14 -0
- package/dist/esm/build/runtime-surface-policy.js +13 -0
- package/dist/esm/cli/commands/audit-core.d.ts +2 -2
- package/dist/esm/cli/commands/audit.js +7 -3
- package/dist/esm/cli/commands/blueprint/db-commands.js +0 -3
- package/dist/esm/cli/commands/blueprint/mutations.d.ts +3 -2
- package/dist/esm/cli/commands/blueprint/mutations.js +45 -39
- package/dist/esm/cli/commands/blueprint/router-output.js +2 -2
- package/dist/esm/cli/commands/doctor.d.ts +1 -1
- package/dist/esm/cli/commands/doctor.js +4 -5
- package/dist/esm/cli/commands/init/config.d.ts +6 -10
- package/dist/esm/cli/commands/init/config.js +36 -20
- package/dist/esm/cli/commands/init/gitignore-patcher.js +0 -1
- package/dist/esm/cli/commands/init/index.d.ts +8 -1
- package/dist/esm/cli/commands/init/index.js +17 -19
- package/dist/esm/cli/commands/init/package-root.d.ts +20 -0
- package/dist/esm/cli/commands/init/package-root.js +110 -0
- package/dist/esm/cli/commands/init/scaffold-base-kit.js +5 -1
- package/dist/esm/cli/commands/init/scaffolders/agent-hooks/index.d.ts +3 -0
- package/dist/esm/cli/commands/init/scaffolders/agent-hooks/index.js +8 -24
- package/dist/esm/cli/commands/init/scaffolders/agent-kit-global/index.d.ts +9 -0
- package/dist/esm/cli/commands/init/scaffolders/agent-kit-global/index.js +79 -1
- package/dist/esm/cli/commands/init/scaffolders/claude-rules/index.js +2 -12
- package/dist/esm/cli/commands/init/scaffolders/subagents/index.js +2 -12
- package/dist/esm/config/tsconfig/cloudflare.json +1 -1
- package/dist/esm/config/tsconfig/library.json +1 -1
- package/dist/esm/config/tsconfig/react-library.json +3 -2
- package/dist/esm/config/tsconfig/react-router.json +1 -1
- package/dist/esm/dev/restore-dev-links/index.js +3 -4
- package/dist/esm/docs-linter/blueprint-plan.js +46 -4
- package/dist/esm/hooks/check-dev-link/index.js +3 -4
- package/dist/esm/hooks/doctor.d.ts +11 -0
- package/dist/esm/hooks/doctor.js +174 -30
- package/dist/esm/hooks/guard-switch/index.js +3 -5
- package/dist/esm/hooks/post-tool/lint-after-edit.js +4 -5
- package/dist/esm/hooks/pretool-guard/index.js +2 -4
- package/dist/esm/hooks/pretool-guard/runner.js +2 -4
- package/dist/esm/hooks/pretool-guard/validators/forbidden-commands.js +47 -6
- package/dist/esm/hooks/sessionstart/index.js +3 -4
- package/dist/esm/hooks/shared/direct-entrypoint.d.ts +10 -0
- package/dist/esm/hooks/shared/direct-entrypoint.js +21 -0
- package/dist/esm/hooks/stop/qa-changed-files.js +3 -5
- package/dist/esm/hooks/test-quality-check.js +3 -4
- package/dist/esm/mcp/blueprint-server.js +26 -3
- package/dist/esm/mcp/cli.js +2 -6
- package/dist/esm/mcp/server.d.ts +2 -0
- package/dist/esm/mcp/server.js +18 -3
- package/dist/esm/mcp/tools/_shared/audit-kinds.d.ts +1 -1
- package/dist/esm/mcp/tools/_shared/audit-kinds.js +1 -0
- package/dist/esm/mcp/tools/audit.d.ts +2 -1
- package/dist/esm/mcp/tools/audit.js +13 -3
- package/dist/esm/package.json +2 -0
- package/package.json +24 -15
- package/tsconfig/cloudflare.json +1 -1
- package/tsconfig/library.json +1 -1
- package/tsconfig/react-library.json +3 -2
- package/tsconfig/react-router.json +1 -1
- package/dist/esm/blueprint/db/legacy-migration.d.ts +0 -41
- package/dist/esm/blueprint/db/legacy-migration.js +0 -122
|
@@ -8,6 +8,7 @@ const DEPENDENCY_SECTIONS = [
|
|
|
8
8
|
'optionalDependencies',
|
|
9
9
|
'peerDependencies',
|
|
10
10
|
];
|
|
11
|
+
const NON_PUBLISHABLE_DEPENDENCY_PROTOCOLS = ['link:', 'workspace:', 'file:'];
|
|
11
12
|
const BACKUP_FILENAME = '.package.json.prepack.backup';
|
|
12
13
|
const DIST_BACKUP_DIRNAME = '.dist-prepack-backup';
|
|
13
14
|
function asStringMap(value) {
|
|
@@ -61,16 +62,23 @@ export function resolveCatalogSpecifier(dependencyName, version, workspaceCatalo
|
|
|
61
62
|
}
|
|
62
63
|
return resolved;
|
|
63
64
|
}
|
|
65
|
+
function assertPublishableDependencySpecifier(section, dependencyName, version) {
|
|
66
|
+
const blockedProtocol = NON_PUBLISHABLE_DEPENDENCY_PROTOCOLS.find((protocol) => version.startsWith(protocol));
|
|
67
|
+
if (!blockedProtocol)
|
|
68
|
+
return;
|
|
69
|
+
throw new Error(`Cannot pack ${section}.${dependencyName} with non-publishable ${blockedProtocol} specifier ${JSON.stringify(version)}`);
|
|
70
|
+
}
|
|
64
71
|
export function createPackedManifest(manifest, workspaceCatalogs) {
|
|
65
72
|
const packedManifest = { ...manifest };
|
|
66
73
|
for (const section of DEPENDENCY_SECTIONS) {
|
|
67
74
|
const dependencies = manifest[section];
|
|
68
75
|
if (!dependencies)
|
|
69
76
|
continue;
|
|
70
|
-
packedManifest[section] = Object.fromEntries(Object.entries(dependencies).map(([dependencyName, version]) =>
|
|
71
|
-
dependencyName,
|
|
72
|
-
|
|
73
|
-
|
|
77
|
+
packedManifest[section] = Object.fromEntries(Object.entries(dependencies).map(([dependencyName, version]) => {
|
|
78
|
+
const resolvedVersion = resolveCatalogSpecifier(dependencyName, version, workspaceCatalogs);
|
|
79
|
+
assertPublishableDependencySpecifier(section, dependencyName, resolvedVersion);
|
|
80
|
+
return [dependencyName, resolvedVersion];
|
|
81
|
+
}));
|
|
74
82
|
}
|
|
75
83
|
if ('bin' in packedManifest) {
|
|
76
84
|
packedManifest.bin = normalizePackedBinField(packedManifest.bin);
|
|
@@ -1,27 +1,18 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Release-time policy decisions for the publish pipeline.
|
|
2
|
+
* Release-time policy decisions for the native runtime publish pipeline.
|
|
3
3
|
*
|
|
4
|
-
* The
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
* still
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
* MUST NOT attempt to publish the matrix: a first-time `npm publish` of a
|
|
11
|
-
* never-created scoped package returns 404, which previously aborted the entire
|
|
12
|
-
* release before the main `@webpresso/agent-kit` package published (the root
|
|
13
|
-
* cause of the 0.22.x publish stall).
|
|
14
|
-
*
|
|
15
|
-
* The matrix publish is therefore gated behind an explicit opt-in. When the
|
|
16
|
-
* native-distribution feature lands, the release workflow sets
|
|
17
|
-
* `WP_PUBLISH_RUNTIME_MATRIX=1` (after bootstrapping the scoped packages on the
|
|
18
|
-
* registry) to turn it back on.
|
|
4
|
+
* The canonical package surface now includes the per-platform
|
|
5
|
+
* `@webpresso/agent-kit-runtime-*` packages plus the staged native `bin/wp`
|
|
6
|
+
* launcher, so release publishes the runtime matrix by default. Operators may
|
|
7
|
+
* still set `WP_PUBLISH_RUNTIME_MATRIX=0` to force a diagnostics-only dry lane
|
|
8
|
+
* when debugging a broken registry/bootstrap environment, but the normal
|
|
9
|
+
* shipping path is "publish the matrix".
|
|
19
10
|
*/
|
|
20
11
|
export declare const PUBLISH_RUNTIME_MATRIX_ENV = "WP_PUBLISH_RUNTIME_MATRIX";
|
|
21
12
|
/**
|
|
22
13
|
* Whether the release pipeline should build, stage, and publish the per-platform
|
|
23
|
-
* native runtime matrix. Defaults to `
|
|
24
|
-
*
|
|
14
|
+
* native runtime matrix. Defaults to `true`; only an explicit
|
|
15
|
+
* `WP_PUBLISH_RUNTIME_MATRIX=0` disables the matrix.
|
|
25
16
|
*/
|
|
26
17
|
export declare function shouldPublishRuntimeMatrix(env: NodeJS.ProcessEnv): boolean;
|
|
27
18
|
//# sourceMappingURL=release-policy.d.ts.map
|
|
@@ -1,29 +1,20 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Release-time policy decisions for the publish pipeline.
|
|
2
|
+
* Release-time policy decisions for the native runtime publish pipeline.
|
|
3
3
|
*
|
|
4
|
-
* The
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
* still
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
* MUST NOT attempt to publish the matrix: a first-time `npm publish` of a
|
|
11
|
-
* never-created scoped package returns 404, which previously aborted the entire
|
|
12
|
-
* release before the main `@webpresso/agent-kit` package published (the root
|
|
13
|
-
* cause of the 0.22.x publish stall).
|
|
14
|
-
*
|
|
15
|
-
* The matrix publish is therefore gated behind an explicit opt-in. When the
|
|
16
|
-
* native-distribution feature lands, the release workflow sets
|
|
17
|
-
* `WP_PUBLISH_RUNTIME_MATRIX=1` (after bootstrapping the scoped packages on the
|
|
18
|
-
* registry) to turn it back on.
|
|
4
|
+
* The canonical package surface now includes the per-platform
|
|
5
|
+
* `@webpresso/agent-kit-runtime-*` packages plus the staged native `bin/wp`
|
|
6
|
+
* launcher, so release publishes the runtime matrix by default. Operators may
|
|
7
|
+
* still set `WP_PUBLISH_RUNTIME_MATRIX=0` to force a diagnostics-only dry lane
|
|
8
|
+
* when debugging a broken registry/bootstrap environment, but the normal
|
|
9
|
+
* shipping path is "publish the matrix".
|
|
19
10
|
*/
|
|
20
11
|
export const PUBLISH_RUNTIME_MATRIX_ENV = 'WP_PUBLISH_RUNTIME_MATRIX';
|
|
21
12
|
/**
|
|
22
13
|
* Whether the release pipeline should build, stage, and publish the per-platform
|
|
23
|
-
* native runtime matrix. Defaults to `
|
|
24
|
-
*
|
|
14
|
+
* native runtime matrix. Defaults to `true`; only an explicit
|
|
15
|
+
* `WP_PUBLISH_RUNTIME_MATRIX=0` disables the matrix.
|
|
25
16
|
*/
|
|
26
17
|
export function shouldPublishRuntimeMatrix(env) {
|
|
27
|
-
return env[PUBLISH_RUNTIME_MATRIX_ENV]
|
|
18
|
+
return env[PUBLISH_RUNTIME_MATRIX_ENV] !== '0';
|
|
28
19
|
}
|
|
29
20
|
//# sourceMappingURL=release-policy.js.map
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export declare const AGENT_KIT_TARBALL_SIZE_BUDGET_BYTES = 29704296;
|
|
2
|
+
export declare const AGENT_KIT_TARBALL_UNPACKED_SIZE_BUDGET_BYTES = 86643227;
|
|
3
|
+
export interface TarballSizeBudgetInput {
|
|
4
|
+
readonly size?: number;
|
|
5
|
+
readonly unpackedSize?: number;
|
|
6
|
+
}
|
|
7
|
+
export interface TarballSizeBudgetResult {
|
|
8
|
+
readonly sizeOk: boolean;
|
|
9
|
+
readonly unpackedOk: boolean;
|
|
10
|
+
readonly size: number;
|
|
11
|
+
readonly unpackedSize: number;
|
|
12
|
+
}
|
|
13
|
+
export declare function evaluateAgentKitTarballSizeBudget(packSummary: TarballSizeBudgetInput): TarballSizeBudgetResult;
|
|
14
|
+
//# sourceMappingURL=runtime-surface-policy.d.ts.map
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export const AGENT_KIT_TARBALL_SIZE_BUDGET_BYTES = 29_704_296;
|
|
2
|
+
export const AGENT_KIT_TARBALL_UNPACKED_SIZE_BUDGET_BYTES = 86_643_227;
|
|
3
|
+
export function evaluateAgentKitTarballSizeBudget(packSummary) {
|
|
4
|
+
const size = packSummary.size ?? 0;
|
|
5
|
+
const unpackedSize = packSummary.unpackedSize ?? 0;
|
|
6
|
+
return {
|
|
7
|
+
sizeOk: size <= AGENT_KIT_TARBALL_SIZE_BUDGET_BYTES,
|
|
8
|
+
unpackedOk: unpackedSize <= AGENT_KIT_TARBALL_UNPACKED_SIZE_BUDGET_BYTES,
|
|
9
|
+
size,
|
|
10
|
+
unpackedSize,
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=runtime-surface-policy.js.map
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { RepoAuditResult } from '#audit/repo-guardrails';
|
|
2
|
-
export type AuditKind = 'tph' | 'tph-e2e' | 'bundle-budget' | 'commit-message' | 'blueprint-lifecycle' | 'roadmap-links' | 'docs-frontmatter' | 'catalog-drift' | 'package-surface' | 'agents' | 'tech-debt' | 'no-relative-parent-imports' | 'no-link-protocol' | 'vision' | 'bucket-boundary' | 'skill-sizes' | 'broken-refs' | 'memory-rotation' | 'gitignore-agent-surfaces' | 'memory-unified' | 'compile-drift' | 'architecture-drift' | 'cloudflare-deploy-contract' | 'toolchain-isolation' | 'absolute-path-policy' | 'no-first-party-mjs' | 'agent-cost' | 'blueprint-db-consistency' | '
|
|
2
|
+
export type AuditKind = 'tph' | 'tph-e2e' | 'bundle-budget' | 'commit-message' | 'blueprint-readme-drift' | 'blueprint-lifecycle' | 'roadmap-links' | 'docs-frontmatter' | 'catalog-drift' | 'package-surface' | 'agents' | 'tech-debt' | 'no-relative-parent-imports' | 'no-link-protocol' | 'vision' | 'bucket-boundary' | 'skill-sizes' | 'broken-refs' | 'memory-rotation' | 'gitignore-agent-surfaces' | 'memory-unified' | 'compile-drift' | 'architecture-drift' | 'cloudflare-deploy-contract' | 'toolchain-isolation' | 'absolute-path-policy' | 'no-first-party-mjs' | 'agent-cost' | 'blueprint-db-consistency' | 'tech-debt-cadence' | 'cross-repo-correlation' | 'ai-contracts' | 'mutation' | 'quality' | 'guardrails' | 'hook-surface' | 'no-relative-package-scripts';
|
|
3
3
|
export type AuditOutcome = {
|
|
4
4
|
kind: 'invalid-usage';
|
|
5
5
|
message: string;
|
|
@@ -34,7 +34,7 @@ export interface AuditActionOptions {
|
|
|
34
34
|
htmlEntry?: string;
|
|
35
35
|
ignore?: string | string[];
|
|
36
36
|
json?: boolean;
|
|
37
|
-
|
|
37
|
+
omxPlans?: boolean;
|
|
38
38
|
loreWarn?: boolean;
|
|
39
39
|
maxHtmlEagerJsAssetBytes?: string;
|
|
40
40
|
maxHtmlEagerJsTotalBytes?: string;
|
|
@@ -13,7 +13,12 @@ import { resolveAuditScriptPath } from '#audit/resolve-audit-script';
|
|
|
13
13
|
const REPO_AUDIT_REGISTRY = {
|
|
14
14
|
'catalog-drift': async (root) => (await import('#audit/repo-guardrails')).auditCatalogDrift(root),
|
|
15
15
|
'package-surface': async (root) => (await import('#audit/package-surface')).auditPackageSurface(root),
|
|
16
|
-
'blueprint-
|
|
16
|
+
'blueprint-readme-drift': async (root, options) => (await import('#audit/blueprint-readme-drift')).auditBlueprintReadmeDrift(root, {
|
|
17
|
+
fix: options.fix,
|
|
18
|
+
}),
|
|
19
|
+
'blueprint-lifecycle': async (root, options) => (await import('#audit/blueprint-lifecycle-sql')).auditBlueprintLifecycleSql(root, {
|
|
20
|
+
includeOmxPlans: options.omxPlans,
|
|
21
|
+
}),
|
|
17
22
|
'roadmap-links': async (root, options) => (await import('#audit/roadmap-links')).auditRoadmapLinks(root, {
|
|
18
23
|
failOrphans: options.strict,
|
|
19
24
|
}),
|
|
@@ -65,7 +70,6 @@ const REPO_AUDIT_REGISTRY = {
|
|
|
65
70
|
'no-first-party-mjs': async (root) => (await import('#audit/no-first-party-mjs')).auditNoFirstPartyMjs(root),
|
|
66
71
|
'agent-cost': async (root) => (await import('#audit/agent-cost')).auditAgentCost(root),
|
|
67
72
|
'blueprint-db-consistency': async (root) => (await import('#audit/blueprint-db-consistency')).auditBlueprintDbConsistency(root),
|
|
68
|
-
'blueprint-lifecycle-sql': async (root) => (await import('#audit/blueprint-lifecycle-sql')).auditBlueprintLifecycleSql(root),
|
|
69
73
|
'tech-debt-cadence': async (root) => (await import('#audit/tech-debt-cadence')).auditTechDebtCadence(root),
|
|
70
74
|
'cross-repo-correlation': async (root) => (await import('#audit/cross-repo-correlation')).auditCrossRepoCorrelationAsRepoResult(root),
|
|
71
75
|
'ai-contracts': async (root) => (await import('#audit/ai-contracts')).auditAiContracts(root),
|
|
@@ -189,7 +193,7 @@ export function registerAuditCommand(cli) {
|
|
|
189
193
|
.option('--message-file <file>', 'Commit message file for commit-message')
|
|
190
194
|
.option('--require-lore', 'Require Lore trailers (hard-fail on missing/malformed trailers)')
|
|
191
195
|
.option('--lore-warn', 'Warn about missing Lore trailers but always exit 0 (soft adoption mode)')
|
|
192
|
-
.option('--
|
|
196
|
+
.option('--omx-plans', 'Also audit .omx/plans derived-handoff governance for blueprint-lifecycle')
|
|
193
197
|
.option('--html-entry <file>', 'HTML entry relative to dist for bundle-budget')
|
|
194
198
|
.option('--max-js-asset-bytes <bytes>', 'Max size for any generated JS asset')
|
|
195
199
|
.option('--max-html-eager-js-asset-bytes <bytes>', 'Max size for any HTML-eager JS asset')
|
|
@@ -5,7 +5,6 @@ import path from 'node:path';
|
|
|
5
5
|
import { coldStartIfNeeded } from '#db/cold-start.js';
|
|
6
6
|
import { openDb } from '#db/connection.js';
|
|
7
7
|
import { ingestAll } from '#db/ingester.js';
|
|
8
|
-
import { migrateLegacyAgentDb } from '#db/legacy-migration.js';
|
|
9
8
|
import { resolveBlueprintProjectionDbPath, withProjectionDbWriteLock } from '#db/paths.js';
|
|
10
9
|
import { runTemplate } from '#db/template-runner.js';
|
|
11
10
|
// ---------------------------------------------------------------------------
|
|
@@ -13,8 +12,6 @@ import { runTemplate } from '#db/template-runner.js';
|
|
|
13
12
|
// ---------------------------------------------------------------------------
|
|
14
13
|
const METADATA_FILENAME = '.datasette-metadata.json';
|
|
15
14
|
function agentDbPath(projectRoot) {
|
|
16
|
-
// Migrate any legacy DB (idempotent + memoized) before resolving canonical path.
|
|
17
|
-
migrateLegacyAgentDb(projectRoot);
|
|
18
15
|
return resolveBlueprintProjectionDbPath(projectRoot);
|
|
19
16
|
}
|
|
20
17
|
function agentMetadataPath(projectRoot) {
|
|
@@ -2,7 +2,8 @@
|
|
|
2
2
|
* Blueprint mutation verbs — advanceTask, promoteBlueprint, finalizeBlueprint
|
|
3
3
|
*
|
|
4
4
|
* All mutations:
|
|
5
|
-
* 1. Edit the canonical
|
|
5
|
+
* 1. Edit the canonical blueprint markdown document on disk (flat `.md` or
|
|
6
|
+
* folder `_overview.md`) via atomic tmp+rename
|
|
6
7
|
* 2. Re-ingest into the structured-store DB via ingestAll
|
|
7
8
|
*
|
|
8
9
|
* Platform-first sync (Tasks 2.6 + 2.7):
|
|
@@ -85,7 +86,7 @@ export interface PromoteBlueprintResult {
|
|
|
85
86
|
readonly message: string;
|
|
86
87
|
}
|
|
87
88
|
/**
|
|
88
|
-
* Advance a task's status in its blueprint
|
|
89
|
+
* Advance a task's status in its blueprint markdown document, then re-ingest.
|
|
89
90
|
*
|
|
90
91
|
* Atomic: writes to a temp file then renames onto the original.
|
|
91
92
|
* Idempotent: if the task is already at `toStatus`, reports "already <toStatus>" and exits cleanly.
|
|
@@ -2,7 +2,8 @@
|
|
|
2
2
|
* Blueprint mutation verbs — advanceTask, promoteBlueprint, finalizeBlueprint
|
|
3
3
|
*
|
|
4
4
|
* All mutations:
|
|
5
|
-
* 1. Edit the canonical
|
|
5
|
+
* 1. Edit the canonical blueprint markdown document on disk (flat `.md` or
|
|
6
|
+
* folder `_overview.md`) via atomic tmp+rename
|
|
6
7
|
* 2. Re-ingest into the structured-store DB via ingestAll
|
|
7
8
|
*
|
|
8
9
|
* Platform-first sync (Tasks 2.6 + 2.7):
|
|
@@ -18,8 +19,8 @@ import path from 'node:path';
|
|
|
18
19
|
import { parseBlueprint } from '#core/parser';
|
|
19
20
|
import { openDb } from '#db/connection.js';
|
|
20
21
|
import { ingestAll } from '#db/ingester.js';
|
|
21
|
-
import { migrateLegacyAgentDb } from '#db/legacy-migration.js';
|
|
22
22
|
import { resolveBlueprintProjectionDbPath, withMarkdownWriteLock, withProjectionDbWriteLock, } from '#db/paths.js';
|
|
23
|
+
import { getBlueprintDocumentPaths } from '#utils/document-paths.js';
|
|
23
24
|
import { resolveBlueprintRoot } from '#utils/blueprint-root.js';
|
|
24
25
|
import { assertAllTasksHaveCanonicalPassingEvidence } from '#verification.js';
|
|
25
26
|
/**
|
|
@@ -80,16 +81,27 @@ const TASK_STATUSES = ['todo', 'in-progress', 'blocked', 'done', 'dropped'];
|
|
|
80
81
|
// Helpers
|
|
81
82
|
// ---------------------------------------------------------------------------
|
|
82
83
|
function dbPath(cwd) {
|
|
83
|
-
// Migrate any legacy `.agent/.blueprints.db` once per process per repo
|
|
84
|
-
// before resolving the canonical worktree-scoped path.
|
|
85
|
-
migrateLegacyAgentDb(cwd);
|
|
86
84
|
return resolveBlueprintProjectionDbPath(cwd);
|
|
87
85
|
}
|
|
88
|
-
function
|
|
86
|
+
function findBlueprintDocument(blueprintRoot, slug) {
|
|
89
87
|
for (const state of ALL_STATES) {
|
|
90
|
-
const
|
|
91
|
-
if (existsSync(
|
|
92
|
-
return {
|
|
88
|
+
const paths = getBlueprintDocumentPaths(blueprintRoot, state, slug);
|
|
89
|
+
if (existsSync(paths.flat)) {
|
|
90
|
+
return {
|
|
91
|
+
dir: path.dirname(paths.flat),
|
|
92
|
+
documentPath: paths.flat,
|
|
93
|
+
shape: 'flat',
|
|
94
|
+
state,
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
if (existsSync(paths.folder)) {
|
|
98
|
+
return {
|
|
99
|
+
dir: paths.directory,
|
|
100
|
+
documentPath: paths.folder,
|
|
101
|
+
shape: 'folder',
|
|
102
|
+
state,
|
|
103
|
+
};
|
|
104
|
+
}
|
|
93
105
|
}
|
|
94
106
|
return null;
|
|
95
107
|
}
|
|
@@ -164,7 +176,7 @@ function findTaskStatusLine(lines, taskId) {
|
|
|
164
176
|
// advanceTask
|
|
165
177
|
// ---------------------------------------------------------------------------
|
|
166
178
|
/**
|
|
167
|
-
* Advance a task's status in its blueprint
|
|
179
|
+
* Advance a task's status in its blueprint markdown document, then re-ingest.
|
|
168
180
|
*
|
|
169
181
|
* Atomic: writes to a temp file then renames onto the original.
|
|
170
182
|
* Idempotent: if the task is already at `toStatus`, reports "already <toStatus>" and exits cleanly.
|
|
@@ -175,15 +187,11 @@ export async function advanceTask(cwd, blueprintSlug, taskId, toStatus) {
|
|
|
175
187
|
}
|
|
176
188
|
async function advanceTaskLocked(cwd, blueprintSlug, taskId, toStatus) {
|
|
177
189
|
const blueprintRoot = resolveBlueprintRoot(cwd);
|
|
178
|
-
const found =
|
|
190
|
+
const found = findBlueprintDocument(blueprintRoot, blueprintSlug);
|
|
179
191
|
if (!found) {
|
|
180
192
|
throw new Error(`Blueprint "${blueprintSlug}" not found in any state directory under ${blueprintRoot}`);
|
|
181
193
|
}
|
|
182
|
-
const
|
|
183
|
-
if (!existsSync(overviewPath)) {
|
|
184
|
-
throw new Error(`Blueprint overview not found: ${overviewPath}`);
|
|
185
|
-
}
|
|
186
|
-
const content = readFileSync(overviewPath, 'utf8');
|
|
194
|
+
const content = readFileSync(found.documentPath, 'utf8');
|
|
187
195
|
const lines = content.split('\n');
|
|
188
196
|
const result = findTaskStatusLine(lines, taskId);
|
|
189
197
|
if (!result) {
|
|
@@ -226,7 +234,7 @@ async function advanceTaskLocked(cwd, blueprintSlug, taskId, toStatus) {
|
|
|
226
234
|
const updatedLines = [...lines];
|
|
227
235
|
updatedLines[lineIndex] = `**Status:** ${toStatus}`;
|
|
228
236
|
const newContent = updatedLines.join('\n');
|
|
229
|
-
atomicWriteFile(
|
|
237
|
+
atomicWriteFile(found.documentPath, newContent);
|
|
230
238
|
await reIngestDb(cwd);
|
|
231
239
|
return {
|
|
232
240
|
blueprintSlug,
|
|
@@ -253,25 +261,21 @@ export async function promoteBlueprint(cwd, slug, toState) {
|
|
|
253
261
|
}
|
|
254
262
|
async function promoteBlueprintLocked(cwd, slug, toState) {
|
|
255
263
|
const blueprintRoot = resolveBlueprintRoot(cwd);
|
|
256
|
-
const found =
|
|
264
|
+
const found = findBlueprintDocument(blueprintRoot, slug);
|
|
257
265
|
if (!found) {
|
|
258
266
|
throw new Error(`Blueprint "${slug}" not found in any state directory under ${blueprintRoot}`);
|
|
259
267
|
}
|
|
260
|
-
const { dir: currentDir, state: currentState } = found;
|
|
261
|
-
const overviewPath = path.join(currentDir, '_overview.md');
|
|
262
|
-
if (!existsSync(overviewPath)) {
|
|
263
|
-
throw new Error(`Blueprint overview not found: ${overviewPath}`);
|
|
264
|
-
}
|
|
268
|
+
const { dir: currentDir, documentPath: currentDocumentPath, shape, state: currentState, } = found;
|
|
265
269
|
// Guard: refuse to complete if any tasks are not done/dropped
|
|
266
270
|
if (toState === 'completed') {
|
|
267
|
-
const markdown = readFileSync(
|
|
271
|
+
const markdown = readFileSync(currentDocumentPath, 'utf8');
|
|
268
272
|
const blueprint = parseBlueprint(markdown, slug);
|
|
269
|
-
const unfinished = blueprint.tasks.filter((task) => task.status !== 'done');
|
|
273
|
+
const unfinished = blueprint.tasks.filter((task) => task.status !== 'done' && task.status !== 'dropped');
|
|
270
274
|
if (unfinished.length > 0) {
|
|
271
275
|
const list = unfinished.map((task) => `${task.id} (${task.status})`).join(', ');
|
|
272
|
-
throw new Error(`Cannot promote "${slug}" to completed: the following tasks are not done: ${list}`);
|
|
276
|
+
throw new Error(`Cannot promote "${slug}" to completed: the following tasks are not done/dropped: ${list}`);
|
|
273
277
|
}
|
|
274
|
-
assertAllTasksHaveCanonicalPassingEvidence(markdown, blueprint.tasks.map((task) => task.id));
|
|
278
|
+
assertAllTasksHaveCanonicalPassingEvidence(markdown, blueprint.tasks.filter((task) => task.status === 'done').map((task) => task.id));
|
|
275
279
|
const target = dbPath(cwd);
|
|
276
280
|
if (existsSync(target)) {
|
|
277
281
|
const conn = openDb(target);
|
|
@@ -311,37 +315,39 @@ async function promoteBlueprintLocked(cwd, slug, toState) {
|
|
|
311
315
|
// Always update local markdown + SQLite.
|
|
312
316
|
// Platform-first: these become derived artifacts; disabled: these are canonical.
|
|
313
317
|
// Update frontmatter in the current location first, then move
|
|
314
|
-
let content = readFileSync(
|
|
318
|
+
let content = readFileSync(currentDocumentPath, 'utf8');
|
|
315
319
|
content = updateFrontmatterStatus(content, toState);
|
|
316
320
|
if (toState === 'completed') {
|
|
317
321
|
const today = new Date().toISOString().split('T')[0] ?? new Date().toISOString();
|
|
318
322
|
content = upsertCompletedAt(content, today);
|
|
319
323
|
}
|
|
320
|
-
const
|
|
321
|
-
const
|
|
322
|
-
|
|
324
|
+
const targetPaths = getBlueprintDocumentPaths(blueprintRoot, toState, slug);
|
|
325
|
+
const destDir = targetPaths.directory;
|
|
326
|
+
const destDocumentPath = shape === 'flat' ? targetPaths.flat : targetPaths.folder;
|
|
327
|
+
if (currentDocumentPath === destDocumentPath) {
|
|
323
328
|
// Same directory — only update frontmatter
|
|
324
|
-
atomicWriteFile(
|
|
329
|
+
atomicWriteFile(currentDocumentPath, content);
|
|
325
330
|
await reIngestDb(cwd);
|
|
326
331
|
return {
|
|
327
332
|
slug,
|
|
328
333
|
oldState: currentState,
|
|
329
334
|
newState: toState,
|
|
330
|
-
newPath:
|
|
331
|
-
message: `Promoted ${slug}: ${currentState} → ${toState} (path unchanged: ${
|
|
335
|
+
newPath: currentDocumentPath,
|
|
336
|
+
message: `Promoted ${slug}: ${currentState} → ${toState} (path unchanged: ${currentDocumentPath})`,
|
|
332
337
|
};
|
|
333
338
|
}
|
|
334
|
-
// Write updated content to current location first, then move
|
|
335
|
-
|
|
339
|
+
// Write updated content to the current location first, then move the owning
|
|
340
|
+
// file/directory according to the blueprint shape.
|
|
341
|
+
atomicWriteFile(currentDocumentPath, content);
|
|
336
342
|
mkdirSync(path.dirname(destDir), { recursive: true });
|
|
337
|
-
renameSync(currentDir, destDir);
|
|
343
|
+
renameSync(shape === 'flat' ? currentDocumentPath : currentDir, shape === 'flat' ? destDocumentPath : destDir);
|
|
338
344
|
await reIngestDb(cwd);
|
|
339
345
|
return {
|
|
340
346
|
slug,
|
|
341
347
|
oldState: currentState,
|
|
342
348
|
newState: toState,
|
|
343
|
-
newPath:
|
|
344
|
-
message: `Promoted ${slug}: ${currentState} → ${toState} (new path: ${
|
|
349
|
+
newPath: destDocumentPath,
|
|
350
|
+
message: `Promoted ${slug}: ${currentState} → ${toState} (new path: ${destDocumentPath})`,
|
|
345
351
|
};
|
|
346
352
|
}
|
|
347
353
|
// ---------------------------------------------------------------------------
|
|
@@ -22,7 +22,7 @@ const BLUEPRINT_HELP = [
|
|
|
22
22
|
' move <slug> <status> --force-recovery',
|
|
23
23
|
].join('\n');
|
|
24
24
|
export function formatTaskLine(task) {
|
|
25
|
-
const checkbox = task.status === 'done' ? 'x' : ' ';
|
|
25
|
+
const checkbox = task.status === 'done' || task.status === 'dropped' ? 'x' : ' ';
|
|
26
26
|
return `- [${checkbox}] ${task.id} ${task.title}`;
|
|
27
27
|
}
|
|
28
28
|
export function getBlueprintHelpText() {
|
|
@@ -113,7 +113,7 @@ export function formatBlueprintSummaries(summaries) {
|
|
|
113
113
|
return [...lines, inventorySummary].join('\n');
|
|
114
114
|
}
|
|
115
115
|
export function formatBlueprintDetails(result) {
|
|
116
|
-
const doneTasks = result.blueprint.tasks.filter((task) => task.status === 'done').length;
|
|
116
|
+
const doneTasks = result.blueprint.tasks.filter((task) => task.status === 'done' || task.status === 'dropped').length;
|
|
117
117
|
const header = [
|
|
118
118
|
`title: ${result.blueprint.title}`,
|
|
119
119
|
`slug: ${result.slug}`,
|
|
@@ -3,7 +3,7 @@ export interface RunDoctorOptions {
|
|
|
3
3
|
root?: string;
|
|
4
4
|
docsRoot?: string;
|
|
5
5
|
fix?: boolean;
|
|
6
|
-
|
|
6
|
+
omxPlans?: boolean;
|
|
7
7
|
}
|
|
8
8
|
export declare function runDoctor(options?: RunDoctorOptions): Promise<number>;
|
|
9
9
|
export declare function registerDoctorCommand(cli: CAC): void;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { auditBlueprintLifecycleSql } from '#audit/blueprint-lifecycle-sql';
|
|
2
|
+
import { auditCatalogDrift, auditDocsFrontmatter, formatRepoAuditReport, } from '#audit/repo-guardrails';
|
|
2
3
|
const REMEDIATIONS = {
|
|
3
4
|
'Catalog drift': 'wp audit catalog-drift',
|
|
4
5
|
'Catalog drift — single package (no workspace file)': 'none needed',
|
|
@@ -14,9 +15,7 @@ export async function runDoctor(options = {}) {
|
|
|
14
15
|
docsRoot: options.docsRoot,
|
|
15
16
|
fix: options.fix,
|
|
16
17
|
}),
|
|
17
|
-
|
|
18
|
-
includeLegacyOmx: options.legacyOmx,
|
|
19
|
-
}),
|
|
18
|
+
await auditBlueprintLifecycleSql(root, { includeOmxPlans: options.omxPlans }),
|
|
20
19
|
];
|
|
21
20
|
let failed = false;
|
|
22
21
|
for (const result of results) {
|
|
@@ -44,7 +43,7 @@ export function registerDoctorCommand(cli) {
|
|
|
44
43
|
.option('--root <dir>', 'Repository root to inspect')
|
|
45
44
|
.option('--docs-root <dir>', 'Docs directory for docs-frontmatter')
|
|
46
45
|
.option('--fix', 'Apply supported safe fixes during doctor (currently docs-frontmatter)')
|
|
47
|
-
.option('--
|
|
46
|
+
.option('--omx-plans', 'Also audit .omx/plans derived-handoff governance for blueprint-lifecycle')
|
|
48
47
|
.action(async (options) => {
|
|
49
48
|
const code = await runDoctor(options);
|
|
50
49
|
return code;
|
|
@@ -1,12 +1,18 @@
|
|
|
1
1
|
import type { AgentHost, VisibilityStatus } from './host-visibility.js';
|
|
2
2
|
export declare const CONFIG_VERSION = "1";
|
|
3
3
|
export declare const CONFIG_FILENAME = ".webpressorc.json";
|
|
4
|
+
export declare const LEGACY_CONFIG_FILENAME = ".agent-kitrc.json";
|
|
4
5
|
export declare const DEFAULT_DURABLE_PLANNING_ROOT = ".agent/planning/";
|
|
5
6
|
export interface AgentkitConfig {
|
|
6
7
|
version: string;
|
|
7
8
|
installed: {
|
|
8
9
|
tier3Skills: string[];
|
|
9
10
|
};
|
|
11
|
+
audit?: {
|
|
12
|
+
toolchainIsolation?: {
|
|
13
|
+
allowDependencies?: string[];
|
|
14
|
+
};
|
|
15
|
+
};
|
|
10
16
|
hosts?: {
|
|
11
17
|
selected: AgentHost[];
|
|
12
18
|
requiredCapabilities: string[];
|
|
@@ -24,16 +30,6 @@ export interface AgentkitConfig {
|
|
|
24
30
|
packageManager?: 'vp-only';
|
|
25
31
|
scriptRoutes?: Record<string, string>;
|
|
26
32
|
};
|
|
27
|
-
/** Audit policy overrides. `mechanism` lives in agent-kit; this is per-repo
|
|
28
|
-
* `data`. `toolchainIsolation.allowDependencies` lists dependency names that
|
|
29
|
-
* are exempt from the toolchain-isolation audit because they are legitimate
|
|
30
|
-
* app-specific runtimes (e.g. `tsx` for a Pulumi program's TS loader,
|
|
31
|
-
* `@playwright/test` imported by e2e specs), not generic toolchain. */
|
|
32
|
-
audit?: {
|
|
33
|
-
toolchainIsolation?: {
|
|
34
|
-
allowDependencies?: string[];
|
|
35
|
-
};
|
|
36
|
-
};
|
|
37
33
|
rules: {
|
|
38
34
|
overrides: string[];
|
|
39
35
|
};
|
|
@@ -7,6 +7,7 @@ import { join } from 'node:path';
|
|
|
7
7
|
import { REQUIRED_CORE_CAPABILITIES } from './host-visibility.js';
|
|
8
8
|
export const CONFIG_VERSION = '1';
|
|
9
9
|
export const CONFIG_FILENAME = '.webpressorc.json';
|
|
10
|
+
export const LEGACY_CONFIG_FILENAME = '.agent-kitrc.json';
|
|
10
11
|
export const DEFAULT_DURABLE_PLANNING_ROOT = '.agent/planning/';
|
|
11
12
|
function readOptionalString(value) {
|
|
12
13
|
if (typeof value !== 'string')
|
|
@@ -27,14 +28,12 @@ export function defaultConfig() {
|
|
|
27
28
|
durablePlanningRoot: DEFAULT_DURABLE_PLANNING_ROOT,
|
|
28
29
|
};
|
|
29
30
|
}
|
|
30
|
-
|
|
31
|
-
const path = join(repoRoot, CONFIG_FILENAME);
|
|
32
|
-
if (!existsSync(path))
|
|
33
|
-
return null;
|
|
31
|
+
function parseConfigFile(path) {
|
|
34
32
|
try {
|
|
35
33
|
const raw = readFileSync(path, 'utf8');
|
|
36
34
|
const parsed = JSON.parse(raw);
|
|
37
35
|
const installed = parsed.installed;
|
|
36
|
+
const audit = parsed.audit;
|
|
38
37
|
const mcp = parsed.mcp;
|
|
39
38
|
const hosts = parsed.hosts;
|
|
40
39
|
const rules = parsed.rules;
|
|
@@ -60,12 +59,17 @@ export function readConfig(repoRoot) {
|
|
|
60
59
|
...(scriptRoutes ? { scriptRoutes } : {}),
|
|
61
60
|
}
|
|
62
61
|
: undefined;
|
|
63
|
-
const
|
|
64
|
-
const
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
62
|
+
const rawToolchainIsolation = audit?.toolchainIsolation;
|
|
63
|
+
const allowDependencies = Array.isArray(rawToolchainIsolation?.allowDependencies)
|
|
64
|
+
? rawToolchainIsolation.allowDependencies.filter((value) => typeof value === 'string' && value.length > 0)
|
|
65
|
+
: undefined;
|
|
66
|
+
const normalizedAudit = allowDependencies && allowDependencies.length > 0
|
|
67
|
+
? {
|
|
68
|
+
toolchainIsolation: {
|
|
69
|
+
allowDependencies,
|
|
70
|
+
},
|
|
71
|
+
}
|
|
72
|
+
: undefined;
|
|
69
73
|
const selectedHosts = Array.isArray(hosts?.selected)
|
|
70
74
|
? hosts.selected.filter((s) => ['codex', 'claude', 'opencode'].includes(String(s)))
|
|
71
75
|
: [];
|
|
@@ -83,9 +87,9 @@ export function readConfig(repoRoot) {
|
|
|
83
87
|
requiredCapabilities,
|
|
84
88
|
...(visibility ? { visibility } : {}),
|
|
85
89
|
},
|
|
90
|
+
...(normalizedAudit ? { audit: normalizedAudit } : {}),
|
|
86
91
|
...(normalizedMcp ? { mcp: normalizedMcp } : {}),
|
|
87
92
|
...(normalizedGuard ? { guard: normalizedGuard } : {}),
|
|
88
|
-
...(normalizedAudit ? { audit: normalizedAudit } : {}),
|
|
89
93
|
rules: { overrides: overrides.filter((s) => typeof s === 'string') },
|
|
90
94
|
scripts: {
|
|
91
95
|
'setup-agent': readOptionalString(scripts?.['setup-agent']),
|
|
@@ -102,6 +106,15 @@ export function readConfig(repoRoot) {
|
|
|
102
106
|
return null;
|
|
103
107
|
}
|
|
104
108
|
}
|
|
109
|
+
export function readConfig(repoRoot) {
|
|
110
|
+
const configPath = join(repoRoot, CONFIG_FILENAME);
|
|
111
|
+
if (existsSync(configPath))
|
|
112
|
+
return parseConfigFile(configPath);
|
|
113
|
+
const legacyConfigPath = join(repoRoot, LEGACY_CONFIG_FILENAME);
|
|
114
|
+
if (existsSync(legacyConfigPath))
|
|
115
|
+
return parseConfigFile(legacyConfigPath);
|
|
116
|
+
return null;
|
|
117
|
+
}
|
|
105
118
|
export function mergeConfig(existing, incoming) {
|
|
106
119
|
if (!existing)
|
|
107
120
|
return incoming;
|
|
@@ -113,6 +126,17 @@ export function mergeConfig(existing, incoming) {
|
|
|
113
126
|
...incoming.mcp,
|
|
114
127
|
}
|
|
115
128
|
: undefined;
|
|
129
|
+
const mergedAllowDependencies = Array.from(new Set([
|
|
130
|
+
...(existing.audit?.toolchainIsolation?.allowDependencies ?? []),
|
|
131
|
+
...(incoming.audit?.toolchainIsolation?.allowDependencies ?? []),
|
|
132
|
+
])).toSorted();
|
|
133
|
+
const mergedAudit = mergedAllowDependencies.length > 0
|
|
134
|
+
? {
|
|
135
|
+
toolchainIsolation: {
|
|
136
|
+
allowDependencies: mergedAllowDependencies,
|
|
137
|
+
},
|
|
138
|
+
}
|
|
139
|
+
: undefined;
|
|
116
140
|
const mergedScriptRoutes = existing.guard?.scriptRoutes || incoming.guard?.scriptRoutes
|
|
117
141
|
? { ...existing.guard?.scriptRoutes, ...incoming.guard?.scriptRoutes }
|
|
118
142
|
: undefined;
|
|
@@ -123,21 +147,13 @@ export function mergeConfig(existing, incoming) {
|
|
|
123
147
|
...(mergedScriptRoutes ? { scriptRoutes: mergedScriptRoutes } : {}),
|
|
124
148
|
}
|
|
125
149
|
: undefined;
|
|
126
|
-
const existingAllowDeps = existing.audit?.toolchainIsolation?.allowDependencies;
|
|
127
|
-
const incomingAllowDeps = incoming.audit?.toolchainIsolation?.allowDependencies;
|
|
128
|
-
const mergedAllowDeps = existingAllowDeps || incomingAllowDeps
|
|
129
|
-
? Array.from(new Set([...(existingAllowDeps ?? []), ...(incomingAllowDeps ?? [])])).toSorted()
|
|
130
|
-
: undefined;
|
|
131
|
-
const mergedAudit = mergedAllowDeps
|
|
132
|
-
? { toolchainIsolation: { allowDependencies: mergedAllowDeps } }
|
|
133
|
-
: undefined;
|
|
134
150
|
return {
|
|
135
151
|
version: incoming.version,
|
|
136
152
|
installed: { tier3Skills: tier3 },
|
|
137
153
|
hosts: incoming.hosts ?? existing.hosts,
|
|
154
|
+
...(mergedAudit ? { audit: mergedAudit } : {}),
|
|
138
155
|
...(mergedMcp ? { mcp: mergedMcp } : {}),
|
|
139
156
|
...(mergedGuard ? { guard: mergedGuard } : {}),
|
|
140
|
-
...(mergedAudit ? { audit: mergedAudit } : {}),
|
|
141
157
|
rules: { overrides },
|
|
142
158
|
scripts: {
|
|
143
159
|
'setup-agent': incoming.scripts['setup-agent'] ?? existing.scripts['setup-agent'],
|
|
@@ -73,7 +73,6 @@ export const GENERATED_PATHS_BLOCK = {
|
|
|
73
73
|
'.agent/.merged.provenance.json',
|
|
74
74
|
'.agent/.compile-manifest.json',
|
|
75
75
|
'.agent/.rotation-log.jsonl',
|
|
76
|
-
'.agent/.blueprints.db',
|
|
77
76
|
'.agent/.blueprints.lock',
|
|
78
77
|
'.agent/.blueprints.snapshot.sql',
|
|
79
78
|
'.agent/.tail-hint-history.jsonl',
|
|
@@ -17,7 +17,14 @@ export declare const EXIT_SUCCESS = 0;
|
|
|
17
17
|
export declare const EXIT_SETUP_FAIL = 1;
|
|
18
18
|
export declare const EXIT_USER_ABORT = 2;
|
|
19
19
|
export declare const EXIT_WRITE_FAIL = 3;
|
|
20
|
-
export
|
|
20
|
+
export interface ResolveCatalogDirOptions {
|
|
21
|
+
readonly moduleUrl?: string;
|
|
22
|
+
readonly execPath?: string;
|
|
23
|
+
readonly argv0?: string;
|
|
24
|
+
readonly argv1?: string;
|
|
25
|
+
readonly pathEnv?: string;
|
|
26
|
+
}
|
|
27
|
+
export declare function resolveCatalogDir(options?: ResolveCatalogDirOptions): string;
|
|
21
28
|
export declare function runInit(flags: InitFlags): Promise<number>;
|
|
22
29
|
export type InitCommandName = 'setup' | 'init';
|
|
23
30
|
export declare function registerInitCommand(cli: CAC, commandName?: InitCommandName): void;
|