@open-agent-toolkit/cli 0.2.51 → 0.2.52
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/assets/bundle-metadata.json +1 -1
- package/assets/docs/cli-utilities/bootstrap.md +6 -2
- package/assets/docs/cli-utilities/tool-packs.md +87 -33
- package/assets/docs/provider-sync/commands.md +30 -2
- package/assets/docs/provider-sync/config.md +19 -0
- package/assets/docs/provider-sync/manifest-and-drift.md +37 -0
- package/assets/docs/provider-sync/providers.md +69 -2
- package/assets/docs/provider-sync/scope-and-surface.md +44 -0
- package/assets/docs/reference/cli-reference.md +1 -0
- package/assets/docs/reference/oat-directory-structure.md +11 -4
- package/assets/docs/workflows/projects/evidence-layers.md +110 -1
- package/assets/docs/workflows/projects/implementation-execution.md +13 -0
- package/assets/docs/workflows/projects/orchestration-model.md +18 -0
- package/assets/public-package-versions.json +4 -4
- package/assets/skills/oat-dispatch-subagents/SKILL.md +57 -1
- package/assets/skills/oat-dispatch-subagents/references/record-schema.md +77 -1
- package/assets/skills/oat-project-autonomous/references/gate-inventory.md +1 -1
- package/assets/skills/oat-project-dispatch-subagents/SKILL.md +24 -1
- package/assets/skills/oat-project-document/references/docs/autonomy-contract.md +1 -1
- package/assets/skills/oat-project-implement/references/dispatch-and-dry-run.md +11 -0
- package/assets/skills/oat-project-implement/references/docs/autonomy-contract.md +1 -1
- package/assets/skills/oat-project-plan-writing/SKILL.md +12 -1
- package/assets/skills/oat-project-pr-final/references/docs/autonomy-contract.md +1 -1
- package/assets/skills/oat-project-quick-start/references/docs/autonomy-contract.md +1 -1
- package/assets/skills/oat-project-review-provide/SKILL.md +12 -1
- package/assets/skills/oat-project-review-provide-remote/SKILL.md +12 -1
- package/dist/agents/canonical/index.d.ts +2 -0
- package/dist/agents/canonical/index.d.ts.map +1 -1
- package/dist/agents/canonical/index.js +1 -0
- package/dist/agents/canonical/resolve.d.ts +45 -0
- package/dist/agents/canonical/resolve.d.ts.map +1 -0
- package/dist/agents/canonical/resolve.js +175 -0
- package/dist/commands/decision/agents-guidance.d.ts +2 -2
- package/dist/commands/decision/agents-guidance.d.ts.map +1 -1
- package/dist/commands/decision/agents-guidance.js +1 -4
- package/dist/commands/decision/index.d.ts.map +1 -1
- package/dist/commands/decision/index.js +25 -6
- package/dist/commands/docs/init/index.d.ts +7 -1
- package/dist/commands/docs/init/index.d.ts.map +1 -1
- package/dist/commands/docs/init/index.js +53 -20
- package/dist/commands/doctor/index.d.ts +8 -2
- package/dist/commands/doctor/index.d.ts.map +1 -1
- package/dist/commands/doctor/index.js +157 -46
- package/dist/commands/init/index.d.ts +8 -3
- package/dist/commands/init/index.d.ts.map +1 -1
- package/dist/commands/init/index.js +64 -26
- package/dist/commands/init/tools/index.d.ts +12 -12
- package/dist/commands/init/tools/index.d.ts.map +1 -1
- package/dist/commands/init/tools/index.js +430 -99
- package/dist/commands/init/tools/install-state.d.ts +2 -0
- package/dist/commands/init/tools/install-state.d.ts.map +1 -1
- package/dist/commands/init/tools/install-state.js +11 -0
- package/dist/commands/init/tools/project-guidance.d.ts +49 -0
- package/dist/commands/init/tools/project-guidance.d.ts.map +1 -0
- package/dist/commands/init/tools/project-guidance.js +144 -0
- package/dist/commands/init/tools/workflows/index.d.ts +7 -0
- package/dist/commands/init/tools/workflows/index.d.ts.map +1 -1
- package/dist/commands/init/tools/workflows/index.js +160 -7
- package/dist/commands/pjm/index.d.ts.map +1 -1
- package/dist/commands/pjm/index.js +28 -3
- package/dist/commands/pjm/init.d.ts +5 -0
- package/dist/commands/pjm/init.d.ts.map +1 -1
- package/dist/commands/pjm/init.js +19 -3
- package/dist/commands/project/dispatch/index.d.ts +10 -0
- package/dist/commands/project/dispatch/index.d.ts.map +1 -0
- package/dist/commands/project/dispatch/index.js +137 -0
- package/dist/commands/project/dispatch/record.d.ts +91 -0
- package/dist/commands/project/dispatch/record.d.ts.map +1 -0
- package/dist/commands/project/dispatch/record.js +402 -0
- package/dist/commands/project/index.d.ts.map +1 -1
- package/dist/commands/project/index.js +2 -0
- package/dist/commands/providers/inspect/inspect.d.ts +8 -1
- package/dist/commands/providers/inspect/inspect.d.ts.map +1 -1
- package/dist/commands/providers/inspect/inspect.js +146 -26
- package/dist/commands/providers/list/list.d.ts +8 -1
- package/dist/commands/providers/list/list.d.ts.map +1 -1
- package/dist/commands/providers/list/list.js +139 -23
- package/dist/commands/providers/providers.types.d.ts +25 -1
- package/dist/commands/providers/providers.types.d.ts.map +1 -1
- package/dist/commands/providers/set/index.d.ts +9 -1
- package/dist/commands/providers/set/index.d.ts.map +1 -1
- package/dist/commands/providers/set/index.js +43 -33
- package/dist/commands/remove/skill/remove-skill.d.ts.map +1 -1
- package/dist/commands/remove/skill/remove-skill.js +11 -0
- package/dist/commands/shared/agents-md.d.ts +42 -14
- package/dist/commands/shared/agents-md.d.ts.map +1 -1
- package/dist/commands/shared/agents-md.js +364 -70
- package/dist/commands/status/index.d.ts +8 -3
- package/dist/commands/status/index.d.ts.map +1 -1
- package/dist/commands/status/index.js +147 -32
- package/dist/commands/sync/apply.d.ts.map +1 -1
- package/dist/commands/sync/apply.js +220 -29
- package/dist/commands/sync/dry-run.d.ts.map +1 -1
- package/dist/commands/sync/dry-run.js +30 -6
- package/dist/commands/sync/index.d.ts +17 -2
- package/dist/commands/sync/index.d.ts.map +1 -1
- package/dist/commands/sync/index.js +106 -41
- package/dist/commands/sync/sync.types.d.ts +39 -2
- package/dist/commands/sync/sync.types.d.ts.map +1 -1
- package/dist/commands/sync/sync.utils.d.ts +5 -1
- package/dist/commands/sync/sync.utils.d.ts.map +1 -1
- package/dist/commands/sync/sync.utils.js +73 -0
- package/dist/commands/tools/info/info-tool.d.ts +2 -0
- package/dist/commands/tools/info/info-tool.d.ts.map +1 -1
- package/dist/commands/tools/info/info-tool.js +34 -12
- package/dist/commands/tools/install/index.d.ts.map +1 -1
- package/dist/commands/tools/install/index.js +19 -3
- package/dist/commands/tools/list/list-tools.d.ts +2 -0
- package/dist/commands/tools/list/list-tools.d.ts.map +1 -1
- package/dist/commands/tools/list/list-tools.js +36 -7
- package/dist/commands/tools/remove/index.d.ts.map +1 -1
- package/dist/commands/tools/remove/index.js +150 -21
- package/dist/commands/tools/remove/remove-tools.d.ts +20 -0
- package/dist/commands/tools/remove/remove-tools.d.ts.map +1 -1
- package/dist/commands/tools/remove/remove-tools.js +122 -1
- package/dist/commands/tools/shared/format-pack-inventory.d.ts +19 -0
- package/dist/commands/tools/shared/format-pack-inventory.d.ts.map +1 -1
- package/dist/commands/tools/shared/format-pack-inventory.js +109 -0
- package/dist/commands/tools/shared/pack-evidence.d.ts +66 -0
- package/dist/commands/tools/shared/pack-evidence.d.ts.map +1 -0
- package/dist/commands/tools/shared/pack-evidence.js +132 -0
- package/dist/commands/tools/shared/pack-inventory.d.ts +1 -0
- package/dist/commands/tools/shared/pack-inventory.d.ts.map +1 -1
- package/dist/commands/tools/shared/pack-lifecycle-outcome.d.ts +44 -0
- package/dist/commands/tools/shared/pack-lifecycle-outcome.d.ts.map +1 -0
- package/dist/commands/tools/shared/pack-lifecycle-outcome.js +91 -0
- package/dist/commands/tools/update/index.d.ts.map +1 -1
- package/dist/commands/tools/update/index.js +74 -4
- package/dist/commands/tools/update/update-tools.d.ts +5 -0
- package/dist/commands/tools/update/update-tools.d.ts.map +1 -1
- package/dist/commands/tools/update/update-tools.js +64 -2
- package/dist/config/oat-config.d.ts +5 -0
- package/dist/config/oat-config.d.ts.map +1 -1
- package/dist/config/oat-config.js +17 -5
- package/dist/config/user-sync-config.d.ts +1 -0
- package/dist/config/user-sync-config.d.ts.map +1 -1
- package/dist/config/user-sync-config.js +8 -0
- package/dist/drift/detector.d.ts +2 -2
- package/dist/drift/detector.d.ts.map +1 -1
- package/dist/drift/detector.js +18 -0
- package/dist/drift/strays.d.ts.map +1 -1
- package/dist/drift/strays.js +5 -0
- package/dist/engine/collection-sync.d.ts +14 -0
- package/dist/engine/collection-sync.d.ts.map +1 -0
- package/dist/engine/collection-sync.js +282 -0
- package/dist/engine/compute-plan.d.ts +8 -1
- package/dist/engine/compute-plan.d.ts.map +1 -1
- package/dist/engine/compute-plan.js +303 -12
- package/dist/engine/engine.types.d.ts +61 -0
- package/dist/engine/engine.types.d.ts.map +1 -1
- package/dist/engine/execute-plan.d.ts +22 -2
- package/dist/engine/execute-plan.d.ts.map +1 -1
- package/dist/engine/execute-plan.js +459 -27
- package/dist/engine/provider-path-safety.d.ts +1 -0
- package/dist/engine/provider-path-safety.d.ts.map +1 -1
- package/dist/engine/provider-path-safety.js +15 -0
- package/dist/engine/scanner.d.ts +2 -2
- package/dist/engine/scanner.d.ts.map +1 -1
- package/dist/engine/scanner.js +21 -4
- package/dist/fs/io.d.ts +67 -0
- package/dist/fs/io.d.ts.map +1 -1
- package/dist/fs/io.js +536 -3
- package/dist/manifest/index.d.ts +2 -2
- package/dist/manifest/index.d.ts.map +1 -1
- package/dist/manifest/index.js +1 -1
- package/dist/manifest/manager.d.ts +2 -2
- package/dist/manifest/manager.d.ts.map +1 -1
- package/dist/manifest/manager.js +20 -3
- package/dist/manifest/manifest.types.d.ts +704 -13
- package/dist/manifest/manifest.types.d.ts.map +1 -1
- package/dist/manifest/manifest.types.js +131 -15
- package/dist/providers/codex/codec/sync-extension.d.ts.map +1 -1
- package/dist/providers/codex/codec/sync-extension.js +41 -10
- package/dist/providers/cursor/codec/sync-extension.d.ts.map +1 -1
- package/dist/providers/cursor/codec/sync-extension.js +41 -10
- package/dist/providers/identity/absolute-paths.d.ts +68 -0
- package/dist/providers/identity/absolute-paths.d.ts.map +1 -0
- package/dist/providers/identity/absolute-paths.js +144 -0
- package/dist/providers/identity/claude-runtime-observation.d.ts +105 -0
- package/dist/providers/identity/claude-runtime-observation.d.ts.map +1 -0
- package/dist/providers/identity/claude-runtime-observation.fixtures.d.ts +40 -0
- package/dist/providers/identity/claude-runtime-observation.fixtures.d.ts.map +1 -0
- package/dist/providers/identity/claude-runtime-observation.fixtures.js +146 -0
- package/dist/providers/identity/claude-runtime-observation.js +229 -0
- package/dist/providers/identity/codex-runtime-observation.d.ts +75 -0
- package/dist/providers/identity/codex-runtime-observation.d.ts.map +1 -0
- package/dist/providers/identity/codex-runtime-observation.fixtures.d.ts +37 -0
- package/dist/providers/identity/codex-runtime-observation.fixtures.d.ts.map +1 -0
- package/dist/providers/identity/codex-runtime-observation.fixtures.js +539 -0
- package/dist/providers/identity/codex-runtime-observation.js +255 -0
- package/dist/providers/identity/generic-dispatch-record.d.ts +313 -0
- package/dist/providers/identity/generic-dispatch-record.d.ts.map +1 -0
- package/dist/providers/identity/generic-dispatch-record.js +539 -0
- package/dist/providers/identity/oat-dispatch-record.d.ts +1964 -0
- package/dist/providers/identity/oat-dispatch-record.d.ts.map +1 -0
- package/dist/providers/identity/oat-dispatch-record.js +691 -0
- package/dist/providers/identity/runtime-observation.d.ts +100 -0
- package/dist/providers/identity/runtime-observation.d.ts.map +1 -0
- package/dist/providers/identity/runtime-observation.js +169 -0
- package/dist/providers/shared/index.d.ts +2 -0
- package/dist/providers/shared/index.d.ts.map +1 -1
- package/dist/providers/shared/index.js +1 -0
- package/dist/providers/shared/materialization-extension.d.ts +12 -0
- package/dist/providers/shared/materialization-extension.d.ts.map +1 -1
- package/dist/providers/shared/registry.d.ts +69 -0
- package/dist/providers/shared/registry.d.ts.map +1 -0
- package/dist/providers/shared/registry.js +252 -0
- package/dist/providers/shared/restart-adviser.d.ts +26 -0
- package/dist/providers/shared/restart-adviser.d.ts.map +1 -0
- package/dist/providers/shared/restart-adviser.js +96 -0
- package/dist/shared/types.d.ts +4 -0
- package/dist/shared/types.d.ts.map +1 -1
- package/package.json +2 -2
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { execFile } from 'node:child_process';
|
|
2
2
|
import { buildCommandContext } from '../../../app/command-context.js';
|
|
3
|
-
import { consumeInitToolsRunMetadata, createInitToolsCommand, } from '../../init/tools/index.js';
|
|
3
|
+
import { consumeInitToolsRunMetadata, createInitToolsCommand, wasInstallSyncHandled, } from '../../init/tools/index.js';
|
|
4
|
+
import { withProjectGuidanceOptions } from '../../init/tools/project-guidance.js';
|
|
4
5
|
import { withScopeOption } from '../../shared/scope-option.js';
|
|
5
6
|
import { readGlobalOptions, resolveConcreteScopes, } from '../../shared/shared.utils.js';
|
|
6
7
|
import { autoSync, } from '../../tools/shared/auto-sync.js';
|
|
@@ -28,22 +29,37 @@ const defaultSyncDependencies = {
|
|
|
28
29
|
},
|
|
29
30
|
};
|
|
30
31
|
export function createToolsInstallCommand(syncDependencies = defaultSyncDependencies, initOverrides = {}, createBaseCommand) {
|
|
32
|
+
let syncEnabled = true;
|
|
33
|
+
const buildContext = initOverrides.buildCommandContext ?? buildCommandContext;
|
|
34
|
+
const effectiveOverrides = {
|
|
35
|
+
...initOverrides,
|
|
36
|
+
syncAfterInstall: async (scopes, context, installedCanonicalPaths) => syncEnabled
|
|
37
|
+
? autoSync(scopes, context.cwd, context.home, context.logger, syncDependencies, { installedCanonicalPaths })
|
|
38
|
+
: { synced: false, scopes: [], error: null },
|
|
39
|
+
};
|
|
31
40
|
const cmd = createBaseCommand === undefined
|
|
32
|
-
? createInitToolsCommand(
|
|
41
|
+
? createInitToolsCommand(effectiveOverrides)
|
|
33
42
|
: createBaseCommand();
|
|
34
43
|
cmd.name('install');
|
|
35
44
|
withScopeOption(cmd);
|
|
45
|
+
withProjectGuidanceOptions(cmd);
|
|
36
46
|
cmd.option('--no-sync', 'Skip auto-sync after install');
|
|
47
|
+
cmd.hook('preAction', (thisCommand) => {
|
|
48
|
+
syncEnabled = thisCommand.opts().sync !== false;
|
|
49
|
+
});
|
|
37
50
|
cmd.hook('postAction', async (thisCommand, actionCommand) => {
|
|
38
51
|
if (process.exitCode !== 0 && process.exitCode !== undefined)
|
|
39
52
|
return;
|
|
53
|
+
if (wasInstallSyncHandled(actionCommand))
|
|
54
|
+
return;
|
|
40
55
|
const opts = thisCommand.opts();
|
|
41
56
|
if (opts.sync === false)
|
|
42
57
|
return;
|
|
43
58
|
const globalOptions = readGlobalOptions(actionCommand);
|
|
44
|
-
const buildContext = initOverrides.buildCommandContext ?? buildCommandContext;
|
|
45
59
|
const context = buildContext(globalOptions);
|
|
46
60
|
const metadata = consumeInitToolsRunMetadata();
|
|
61
|
+
if (metadata?.syncHandled)
|
|
62
|
+
return;
|
|
47
63
|
const scopes = metadata === null
|
|
48
64
|
? resolveConcreteScopes(context.scope)
|
|
49
65
|
: metadata.affectedScopes;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { CommandContext } from '../../../app/command-context.js';
|
|
2
|
+
import { type PackEvidenceBlockV1 } from '../../tools/shared/format-pack-inventory.js';
|
|
2
3
|
import { type InventoryPackInput, type PackInventory } from '../../tools/shared/pack-inventory.js';
|
|
3
4
|
import type { ScanToolsOptions } from '../../tools/shared/scan-tools.js';
|
|
4
5
|
import type { ToolInfo } from '../../tools/shared/types.js';
|
|
@@ -11,6 +12,7 @@ export interface ListToolsDependencies {
|
|
|
11
12
|
export interface ListToolsResult {
|
|
12
13
|
tools: ToolInfo[];
|
|
13
14
|
packs: PackInventory[];
|
|
15
|
+
packEvidence: PackEvidenceBlockV1;
|
|
14
16
|
}
|
|
15
17
|
export declare function runListTools(context: CommandContext, dependencies: ListToolsDependencies): Promise<ListToolsResult>;
|
|
16
18
|
//# sourceMappingURL=list-tools.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"list-tools.d.ts","sourceRoot":"","sources":["../../../../src/commands/tools/list/list-tools.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"list-tools.d.ts","sourceRoot":"","sources":["../../../../src/commands/tools/list/list-tools.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAE3D,OAAO,EAML,KAAK,mBAAmB,EACzB,MAAM,8CAA8C,CAAC;AACtD,OAAO,EAEL,KAAK,kBAAkB,EACvB,KAAK,aAAa,EACnB,MAAM,uCAAuC,CAAC;AAE/C,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mCAAmC,CAAC;AAC1E,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,8BAA8B,CAAC;AAE7D,MAAM,WAAW,qBAAqB;IACpC,SAAS,EAAE,CAAC,OAAO,EAAE,gBAAgB,KAAK,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC;IAC9D,gBAAgB,EAAE,CAChB,KAAK,EAAE,SAAS,GAAG,MAAM,EACzB,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,MAAM,KACT,OAAO,CAAC,MAAM,CAAC,CAAC;IACrB,iBAAiB,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,CAAC;IACzC,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,kBAAkB,KAAK,OAAO,CAAC,aAAa,CAAC,CAAC;CACvE;AAED,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,QAAQ,EAAE,CAAC;IAClB,KAAK,EAAE,aAAa,EAAE,CAAC;IACvB,YAAY,EAAE,mBAAmB,CAAC;CACnC;AAED,wBAAsB,YAAY,CAChC,OAAO,EAAE,cAAc,EACvB,YAAY,EAAE,qBAAqB,GAClC,OAAO,CAAC,eAAe,CAAC,CAkI1B"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { resolveConcreteScopes } from '../../shared/shared.utils.js';
|
|
2
|
-
import { formatPackInventoryDetails } from '../../tools/shared/format-pack-inventory.js';
|
|
2
|
+
import { formatPackEvidenceDetails, formatPackInventoryDetails, packEvidenceBlock, projectRenderablePackEvidence, unavailablePackEvidence, } from '../../tools/shared/format-pack-inventory.js';
|
|
3
3
|
import { inventoryPack, } from '../../tools/shared/pack-inventory.js';
|
|
4
4
|
import { PACK_MANIFEST } from '../../tools/shared/pack-manifest.js';
|
|
5
5
|
export async function runListTools(context, dependencies) {
|
|
@@ -18,16 +18,35 @@ export async function runListTools(context, dependencies) {
|
|
|
18
18
|
allTools.push(...tools);
|
|
19
19
|
roots[scope] = scopeRoot;
|
|
20
20
|
}
|
|
21
|
+
const packRoots = {
|
|
22
|
+
projectRoot: roots.project,
|
|
23
|
+
userRoot: roots.user,
|
|
24
|
+
};
|
|
21
25
|
const inspectPack = dependencies.inventoryPack ?? inventoryPack;
|
|
22
|
-
const
|
|
26
|
+
const inspected = await Promise.all(PACK_MANIFEST.map(({ name }) => inspectPack({
|
|
23
27
|
pack: name,
|
|
24
28
|
assetsRoot,
|
|
25
29
|
projectRoot: roots.project,
|
|
26
30
|
userRoot: roots.user,
|
|
27
|
-
}))
|
|
31
|
+
}).then((canonical) => ({
|
|
32
|
+
canonical,
|
|
33
|
+
evidence: projectRenderablePackEvidence(canonical, packRoots),
|
|
34
|
+
}), (error) => ({
|
|
35
|
+
canonical: null,
|
|
36
|
+
evidence: unavailablePackEvidence({
|
|
37
|
+
pack: name,
|
|
38
|
+
scopes,
|
|
39
|
+
reason: error instanceof Error ? error.message : String(error),
|
|
40
|
+
roots: packRoots,
|
|
41
|
+
}),
|
|
42
|
+
}))));
|
|
43
|
+
const packs = inspected
|
|
44
|
+
.map(({ canonical }) => canonical)
|
|
45
|
+
.filter((pack) => pack !== null);
|
|
46
|
+
const packEvidence = packEvidenceBlock(inspected.map(({ evidence }) => evidence));
|
|
28
47
|
if (context.json) {
|
|
29
|
-
logger.json({ tools: allTools, packs });
|
|
30
|
-
return { tools: allTools, packs };
|
|
48
|
+
logger.json({ tools: allTools, packs, packEvidence });
|
|
49
|
+
return { tools: allTools, packs, packEvidence };
|
|
31
50
|
}
|
|
32
51
|
if (allTools.length === 0) {
|
|
33
52
|
logger.info('No tools installed.');
|
|
@@ -37,7 +56,11 @@ export async function runListTools(context, dependencies) {
|
|
|
37
56
|
for (const line of formatPackInventoryDetails(pack))
|
|
38
57
|
logger.info(line);
|
|
39
58
|
}
|
|
40
|
-
|
|
59
|
+
for (const evidence of packEvidence.items) {
|
|
60
|
+
for (const line of formatPackEvidenceDetails(evidence))
|
|
61
|
+
logger.info(line);
|
|
62
|
+
}
|
|
63
|
+
return { tools: allTools, packs, packEvidence };
|
|
41
64
|
}
|
|
42
65
|
logger.info('Installed tools:\n');
|
|
43
66
|
const header = formatRow('NAME', 'TYPE', 'VERSION', 'PACK', 'SCOPE', 'STATUS');
|
|
@@ -56,7 +79,13 @@ export async function runListTools(context, dependencies) {
|
|
|
56
79
|
for (const line of formatPackInventoryDetails(pack))
|
|
57
80
|
logger.info(line);
|
|
58
81
|
}
|
|
59
|
-
|
|
82
|
+
logger.info('\nNormalized pack evidence:');
|
|
83
|
+
for (const evidence of packEvidence.items) {
|
|
84
|
+
logger.info(`${evidence.pack}: ${evidence.realizedPlacement}`);
|
|
85
|
+
for (const line of formatPackEvidenceDetails(evidence))
|
|
86
|
+
logger.info(line);
|
|
87
|
+
}
|
|
88
|
+
return { tools: allTools, packs, packEvidence };
|
|
60
89
|
}
|
|
61
90
|
function formatRow(name, type, version, pack, scope, status) {
|
|
62
91
|
return [
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/commands/tools/remove/index.ts"],"names":[],"mappings":"AAUA,OAAO,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/commands/tools/remove/index.ts"],"names":[],"mappings":"AAUA,OAAO,EAEL,KAAK,oBAAoB,EAE1B,MAAM,kCAAkC,CAAC;AAW1C,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,OAAO,EAEL,KAAK,uBAAuB,EAM7B,MAAM,gBAAgB,CAAC;AAqExB,wBAAgB,wBAAwB,CACtC,YAAY,GAAE,uBAA6C,EAC3D,gBAAgB,GAAE,oBAA8C,GAC/D,OAAO,CAkOT"}
|
|
@@ -5,12 +5,13 @@ import { buildCommandContext } from '../../../app/command-context.js';
|
|
|
5
5
|
import { withScopeOption } from '../../shared/scope-option.js';
|
|
6
6
|
import { readGlobalOptions, resolveConcreteScopes, } from '../../shared/shared.utils.js';
|
|
7
7
|
import { autoSync, } from '../../tools/shared/auto-sync.js';
|
|
8
|
+
import { inventoryScopedPack } from '../../tools/shared/pack-inventory.js';
|
|
8
9
|
import { scanTools } from '../../tools/shared/scan-tools.js';
|
|
9
10
|
import { hasScopedPackOwnershipEvidence, writeScopedPackIntent, } from '../../tools/shared/scoped-pack-intent.js';
|
|
10
11
|
import { resolveAssetsRoot } from '../../../fs/assets.js';
|
|
11
12
|
import { resolveProjectRoot, resolveScopeRoot } from '../../../fs/paths.js';
|
|
12
13
|
import { Command } from 'commander';
|
|
13
|
-
import { removeTools, } from './remove-tools.js';
|
|
14
|
+
import { failedPostRemovalLifecycleOutcomes, failedRemovalLifecycleOutcomes, removalLifecycleOutcomes, removeTools, selectedPacks, } from './remove-tools.js';
|
|
14
15
|
const defaultDependencies = {
|
|
15
16
|
scanTools,
|
|
16
17
|
resolveScopeRoot: async (scope, cwd, home) => {
|
|
@@ -41,6 +42,8 @@ const defaultDependencies = {
|
|
|
41
42
|
}
|
|
42
43
|
},
|
|
43
44
|
hasPackOwnershipEvidence: async (pack, scope, scopeRoot) => hasScopedPackOwnershipEvidence({ pack, scope, scopeRoot }),
|
|
45
|
+
inventoryScopedPack,
|
|
46
|
+
writeScopedPackIntent,
|
|
44
47
|
};
|
|
45
48
|
const defaultSyncDependencies = {
|
|
46
49
|
runSync: async ({ scope, cwd, removedCanonicalPaths }) => {
|
|
@@ -94,28 +97,98 @@ export function createToolsRemoveCommand(dependencies = defaultDependencies, syn
|
|
|
94
97
|
}
|
|
95
98
|
const scopes = resolveConcreteScopes(context.scope);
|
|
96
99
|
const dryRun = opts.dryRun ?? false;
|
|
97
|
-
|
|
100
|
+
let result;
|
|
101
|
+
try {
|
|
102
|
+
result = await removeTools(target, scopes, context.cwd, context.home, dryRun, dependencies);
|
|
103
|
+
}
|
|
104
|
+
catch (error) {
|
|
105
|
+
if (target.kind === 'name' || !context.json)
|
|
106
|
+
throw error;
|
|
107
|
+
const lifecycle = failedRemovalLifecycleOutcomes(target, scopes, error);
|
|
108
|
+
logger.json({
|
|
109
|
+
target: describeTarget(target),
|
|
110
|
+
dryRun,
|
|
111
|
+
result: {
|
|
112
|
+
removed: [],
|
|
113
|
+
removedAssets: [],
|
|
114
|
+
retainedOwnerData: [],
|
|
115
|
+
packOutcomes: [],
|
|
116
|
+
notInstalled: [],
|
|
117
|
+
},
|
|
118
|
+
lifecycle,
|
|
119
|
+
});
|
|
120
|
+
process.exitCode = 1;
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
98
123
|
if (!dryRun && target.kind !== 'name') {
|
|
99
124
|
const packs = target.kind === 'pack' ? [target.pack] : [...VALID_PACKS];
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
125
|
+
let stage = 'intent-write';
|
|
126
|
+
let currentPack = packs[0];
|
|
127
|
+
let currentScope = scopes[0];
|
|
128
|
+
try {
|
|
129
|
+
for (const scope of scopes) {
|
|
130
|
+
currentScope = scope;
|
|
131
|
+
const scopeRoot = await dependencies.resolveScopeRoot(scope, context.cwd, context.home);
|
|
132
|
+
for (const pack of packs) {
|
|
133
|
+
currentPack = pack;
|
|
134
|
+
// Durable scoped intent is what lets `oat tools update` restore a
|
|
135
|
+
// pack whose files are all missing, so it may only be cleared for a
|
|
136
|
+
// pack this run actually removed something for.
|
|
137
|
+
const removedForPack = result.packOutcomes.some((outcome) => outcome.pack === pack &&
|
|
138
|
+
outcome.scope === scope &&
|
|
139
|
+
outcome.removed);
|
|
140
|
+
if (!removedForPack)
|
|
141
|
+
continue;
|
|
142
|
+
await (dependencies.writeScopedPackIntent ?? writeScopedPackIntent)({
|
|
143
|
+
pack,
|
|
144
|
+
scope,
|
|
145
|
+
scopeRoot,
|
|
146
|
+
enabled: false,
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
if (dependencies.inventoryScopedPack) {
|
|
151
|
+
stage = 'final-inventory';
|
|
152
|
+
const assetsRoot = await dependencies.resolveAssetsRoot();
|
|
153
|
+
const finalInventories = [];
|
|
154
|
+
for (const scope of scopes) {
|
|
155
|
+
currentScope = scope;
|
|
156
|
+
const scopeRoot = await dependencies.resolveScopeRoot(scope, context.cwd, context.home);
|
|
157
|
+
for (const pack of selectedPacks(target)) {
|
|
158
|
+
currentPack = pack;
|
|
159
|
+
finalInventories.push(await dependencies.inventoryScopedPack({
|
|
160
|
+
pack,
|
|
161
|
+
scope,
|
|
162
|
+
scopeRoot,
|
|
163
|
+
assetsRoot,
|
|
164
|
+
}));
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
result.lifecycle = removalLifecycleOutcomes(selectedPacks(target), scopes, result.packOutcomes, false, finalInventories);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
catch (error) {
|
|
171
|
+
const lifecycle = failedPostRemovalLifecycleOutcomes(target, scopes, result.packOutcomes, stage, currentPack, currentScope, error);
|
|
172
|
+
const legacyResult = { ...result };
|
|
173
|
+
delete legacyResult.lifecycle;
|
|
174
|
+
if (context.json) {
|
|
175
|
+
logger.json({
|
|
176
|
+
target: describeTarget(target),
|
|
177
|
+
dryRun,
|
|
178
|
+
result: legacyResult,
|
|
179
|
+
lifecycle,
|
|
117
180
|
});
|
|
118
181
|
}
|
|
182
|
+
else {
|
|
183
|
+
for (const tool of result.removed) {
|
|
184
|
+
logger.success(`Removed: ${tool.name} (${tool.scope})`);
|
|
185
|
+
}
|
|
186
|
+
for (const outcome of lifecycle) {
|
|
187
|
+
logger.warn(outcome.recovery.map(({ message }) => message).join('; '));
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
process.exitCode = 1;
|
|
191
|
+
return;
|
|
119
192
|
}
|
|
120
193
|
}
|
|
121
194
|
if (result.notInstalled.length > 0) {
|
|
@@ -129,17 +202,29 @@ export function createToolsRemoveCommand(dependencies = defaultDependencies, syn
|
|
|
129
202
|
return;
|
|
130
203
|
}
|
|
131
204
|
// Auto-sync after mutations (before output so sync errors are captured)
|
|
205
|
+
const syncResults = [];
|
|
132
206
|
if (!dryRun && opts.sync !== false) {
|
|
133
207
|
for (const scope of scopes) {
|
|
134
208
|
const scopeRoot = await dependencies.resolveScopeRoot(scope, context.cwd, context.home);
|
|
135
209
|
const removedCanonicalPaths = canonicalRemovalPaths(result, scope, scopeRoot);
|
|
136
210
|
if (removedCanonicalPaths.length === 0)
|
|
137
211
|
continue;
|
|
138
|
-
await autoSync([scope], context.cwd, context.home, logger, syncDependencies, { removedCanonicalPaths });
|
|
212
|
+
syncResults.push(await autoSync([scope], context.cwd, context.home, logger, syncDependencies, { removedCanonicalPaths }));
|
|
139
213
|
}
|
|
140
214
|
}
|
|
215
|
+
const lifecycle = finalizeRemovalLifecycle(result.lifecycle, syncResults);
|
|
216
|
+
const legacyResult = { ...result };
|
|
217
|
+
delete legacyResult.lifecycle;
|
|
141
218
|
if (context.json) {
|
|
142
|
-
logger.json({
|
|
219
|
+
logger.json({
|
|
220
|
+
target: describeTarget(target),
|
|
221
|
+
dryRun,
|
|
222
|
+
result: legacyResult,
|
|
223
|
+
...(lifecycle ? { lifecycle } : {}),
|
|
224
|
+
});
|
|
225
|
+
if (lifecycle?.some(({ status }) => status !== 'complete')) {
|
|
226
|
+
process.exitCode = 1;
|
|
227
|
+
}
|
|
143
228
|
return;
|
|
144
229
|
}
|
|
145
230
|
if (result.removed.length > 0) {
|
|
@@ -151,6 +236,50 @@ export function createToolsRemoveCommand(dependencies = defaultDependencies, syn
|
|
|
151
236
|
else {
|
|
152
237
|
logger.info('No tools to remove.');
|
|
153
238
|
}
|
|
239
|
+
for (const outcome of lifecycle ?? []) {
|
|
240
|
+
if (outcome.status === 'complete')
|
|
241
|
+
continue;
|
|
242
|
+
logger.warn(`Pack ${outcome.selection.pack} removal ${outcome.status}: ${outcome.recovery.map(({ message }) => message).join('; ')}`);
|
|
243
|
+
process.exitCode = 1;
|
|
244
|
+
}
|
|
245
|
+
});
|
|
246
|
+
}
|
|
247
|
+
function finalizeRemovalLifecycle(lifecycle, syncResults) {
|
|
248
|
+
if (!lifecycle || syncResults.length === 0)
|
|
249
|
+
return lifecycle;
|
|
250
|
+
return lifecycle.map((outcome) => {
|
|
251
|
+
const relevant = syncResults.filter(({ scopes }) => scopes.some((scope) => outcome.selection.targetScopes.includes(scope)));
|
|
252
|
+
if (relevant.length === 0 || relevant.every(({ synced }) => synced)) {
|
|
253
|
+
return relevant.length === 0
|
|
254
|
+
? outcome
|
|
255
|
+
: {
|
|
256
|
+
...outcome,
|
|
257
|
+
sync: {
|
|
258
|
+
scopes: [...new Set(relevant.flatMap(({ scopes }) => scopes))],
|
|
259
|
+
status: 'complete',
|
|
260
|
+
providers: [],
|
|
261
|
+
},
|
|
262
|
+
};
|
|
263
|
+
}
|
|
264
|
+
const error = relevant.find((result) => result.error)?.error;
|
|
265
|
+
return {
|
|
266
|
+
...outcome,
|
|
267
|
+
sync: {
|
|
268
|
+
scopes: [...new Set(relevant.flatMap(({ scopes }) => scopes))],
|
|
269
|
+
status: 'failed',
|
|
270
|
+
providers: [],
|
|
271
|
+
...(error ? { error } : {}),
|
|
272
|
+
},
|
|
273
|
+
status: 'partial',
|
|
274
|
+
recovery: [
|
|
275
|
+
...outcome.recovery,
|
|
276
|
+
{
|
|
277
|
+
code: 'provider-sync-incomplete',
|
|
278
|
+
message: error ??
|
|
279
|
+
`Run oat sync for ${outcome.selection.targetScopes.join(', ')} scope`,
|
|
280
|
+
},
|
|
281
|
+
],
|
|
282
|
+
};
|
|
154
283
|
});
|
|
155
284
|
}
|
|
156
285
|
function canonicalRemovalPaths(result, scope, scopeRoot) {
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import type { InventoryScopedPackInput, ScopedPackInventory } from '../../tools/shared/pack-inventory.js';
|
|
2
|
+
import type { PackLifecycleOutcome } from '../../tools/shared/pack-lifecycle-outcome.js';
|
|
1
3
|
import type { ScanToolsOptions } from '../../tools/shared/scan-tools.js';
|
|
2
4
|
import type { PackName, ToolInfo } from '../../tools/shared/types.js';
|
|
3
5
|
import type { ConcreteScope } from '../../../shared/types.js';
|
|
@@ -18,6 +20,13 @@ export interface RemoveToolsDependencies {
|
|
|
18
20
|
removeFile: (path: string) => Promise<void>;
|
|
19
21
|
pathExists: (path: string) => Promise<boolean>;
|
|
20
22
|
hasPackOwnershipEvidence: (pack: PackName, scope: ConcreteScope, scopeRoot: string) => Promise<boolean>;
|
|
23
|
+
inventoryScopedPack?: (input: InventoryScopedPackInput) => Promise<ScopedPackInventory>;
|
|
24
|
+
writeScopedPackIntent?: (input: {
|
|
25
|
+
pack: PackName;
|
|
26
|
+
scope: ConcreteScope;
|
|
27
|
+
scopeRoot: string;
|
|
28
|
+
enabled: boolean;
|
|
29
|
+
}) => Promise<unknown>;
|
|
21
30
|
}
|
|
22
31
|
interface RemovedTool {
|
|
23
32
|
name: string;
|
|
@@ -53,7 +62,18 @@ export interface RemoveResult {
|
|
|
53
62
|
}>;
|
|
54
63
|
packOutcomes: PackRemovalOutcome[];
|
|
55
64
|
notInstalled: string[];
|
|
65
|
+
lifecycle?: PackLifecycleOutcome[];
|
|
56
66
|
}
|
|
67
|
+
export declare function selectedPacks(target: Exclude<RemoveTarget, {
|
|
68
|
+
kind: 'name';
|
|
69
|
+
}>): PackName[];
|
|
57
70
|
export declare function removeTools(target: RemoveTarget, scopes: ConcreteScope[], cwd: string, home: string, dryRun: boolean, deps: RemoveToolsDependencies): Promise<RemoveResult>;
|
|
71
|
+
export declare function removalLifecycleOutcomes(packs: readonly PackName[], scopes: readonly ConcreteScope[], outcomes: readonly PackRemovalOutcome[], dryRun: boolean, finalInventories: readonly ScopedPackInventory[]): PackLifecycleOutcome[];
|
|
72
|
+
export declare function failedRemovalLifecycleOutcomes(target: Exclude<RemoveTarget, {
|
|
73
|
+
kind: 'name';
|
|
74
|
+
}>, scopes: readonly ConcreteScope[], error: unknown): PackLifecycleOutcome[];
|
|
75
|
+
export declare function failedPostRemovalLifecycleOutcomes(target: Exclude<RemoveTarget, {
|
|
76
|
+
kind: 'name';
|
|
77
|
+
}>, scopes: readonly ConcreteScope[], outcomes: readonly PackRemovalOutcome[], stage: 'intent-write' | 'final-inventory', failedPack: PackName, failedScope: ConcreteScope, error: unknown): PackLifecycleOutcome[];
|
|
58
78
|
export {};
|
|
59
79
|
//# sourceMappingURL=remove-tools.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"remove-tools.d.ts","sourceRoot":"","sources":["../../../../src/commands/tools/remove/remove-tools.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"remove-tools.d.ts","sourceRoot":"","sources":["../../../../src/commands/tools/remove/remove-tools.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { join } from 'node:path';
|
|
2
|
+
import { packScopeFactsFromInventory, projectPackEvidence, } from '../../tools/shared/pack-evidence.js';
|
|
2
3
|
import { PACK_MANIFEST } from '../../tools/shared/pack-manifest.js';
|
|
3
4
|
import { resolveSharedOwnerRetentions } from '../../tools/shared/pack-reconcile.js';
|
|
4
5
|
import { resolveManagedScopeRoots, validateManagedPath, } from '../../../fs/paths.js';
|
|
@@ -27,7 +28,7 @@ async function removeTool(tool, scopeRoot, dryRun, deps) {
|
|
|
27
28
|
function isDirectoryAsset(asset) {
|
|
28
29
|
return asset.kind === 'skill' || asset.kind === 'directory';
|
|
29
30
|
}
|
|
30
|
-
function selectedPacks(target) {
|
|
31
|
+
export function selectedPacks(target) {
|
|
31
32
|
return target.kind === 'pack'
|
|
32
33
|
? [target.pack]
|
|
33
34
|
: PACK_MANIFEST.map(({ name }) => name);
|
|
@@ -146,6 +147,14 @@ export async function removeTools(target, scopes, cwd, home, dryRun, deps) {
|
|
|
146
147
|
const tools = await deps.scanTools({ scope, scopeRoot, assetsRoot });
|
|
147
148
|
const matched = tools.filter((tool) => matchesTarget(tool, target));
|
|
148
149
|
const managedPlan = await planManagedPackRemoval(selectedPacks(target), scope, scopeRoot, dryRun, deps);
|
|
150
|
+
const beforeInventories = deps.inventoryScopedPack
|
|
151
|
+
? await Promise.all(selectedPacks(target).map((pack) => deps.inventoryScopedPack({
|
|
152
|
+
pack,
|
|
153
|
+
scope,
|
|
154
|
+
scopeRoot,
|
|
155
|
+
assetsRoot,
|
|
156
|
+
})))
|
|
157
|
+
: [];
|
|
149
158
|
const seedData = PACK_MANIFEST.filter(({ name }) => selectedPacks(target).includes(name)).flatMap(({ assets }) => assets
|
|
150
159
|
.filter((asset) => asset.scopes.includes(scope) &&
|
|
151
160
|
asset.ownership[scope] === 'seed-if-missing')
|
|
@@ -160,6 +169,7 @@ export async function removeTools(target, scopes, cwd, home, dryRun, deps) {
|
|
|
160
169
|
managedTargets: managedPlan.targets,
|
|
161
170
|
retainedOwnerData: [...managedPlan.retained, ...seedData],
|
|
162
171
|
presentPacks: managedPlan.presentPacks,
|
|
172
|
+
beforeInventories,
|
|
163
173
|
});
|
|
164
174
|
}
|
|
165
175
|
for (const plan of plans) {
|
|
@@ -184,11 +194,122 @@ export async function removeTools(target, scopes, cwd, home, dryRun, deps) {
|
|
|
184
194
|
plan.presentPacks.includes(pack),
|
|
185
195
|
})));
|
|
186
196
|
}
|
|
197
|
+
const finalInventories = dryRun
|
|
198
|
+
? plans.flatMap(({ beforeInventories }) => beforeInventories)
|
|
199
|
+
: [];
|
|
187
200
|
return {
|
|
188
201
|
removed,
|
|
189
202
|
removedAssets,
|
|
190
203
|
retainedOwnerData,
|
|
191
204
|
packOutcomes,
|
|
192
205
|
notInstalled: [],
|
|
206
|
+
lifecycle: removalLifecycleOutcomes(selectedPacks(target), scopes, packOutcomes, dryRun, finalInventories),
|
|
193
207
|
};
|
|
194
208
|
}
|
|
209
|
+
export function removalLifecycleOutcomes(packs, scopes, outcomes, dryRun, finalInventories) {
|
|
210
|
+
if (finalInventories.length === 0)
|
|
211
|
+
return [];
|
|
212
|
+
return packs.map((pack) => {
|
|
213
|
+
const packInventories = finalInventories.filter((inventory) => inventory.pack === pack);
|
|
214
|
+
const finalEvidence = packInventories.length === 0
|
|
215
|
+
? null
|
|
216
|
+
: projectPackEvidence({
|
|
217
|
+
canonical: null,
|
|
218
|
+
scopes: packInventories.map(packScopeFactsFromInventory),
|
|
219
|
+
});
|
|
220
|
+
const removed = outcomes.some((outcome) => outcome.pack === pack && outcome.removed);
|
|
221
|
+
const inventoriedScopes = new Set(packInventories.map(({ scope }) => scope));
|
|
222
|
+
const inventoryVerified = finalEvidence !== null &&
|
|
223
|
+
finalEvidence.unknownScopes.length === 0 &&
|
|
224
|
+
scopes.every((scope) => inventoriedScopes.has(scope));
|
|
225
|
+
const remainingScopes = finalEvidence
|
|
226
|
+
? scopes.filter((scope) => finalEvidence.knownRealizedScopes.includes(scope))
|
|
227
|
+
: [...scopes];
|
|
228
|
+
const verified = inventoryVerified && (dryRun || remainingScopes.length === 0);
|
|
229
|
+
const recovery = !inventoryVerified
|
|
230
|
+
? [
|
|
231
|
+
{
|
|
232
|
+
code: 'final-inventory-unverified',
|
|
233
|
+
message: `Re-run status for ${pack}; final removal state could not be verified`,
|
|
234
|
+
},
|
|
235
|
+
]
|
|
236
|
+
: !dryRun && remainingScopes.length > 0
|
|
237
|
+
? remainingScopes.map((scope) => ({
|
|
238
|
+
code: 'canonical-verification-failed',
|
|
239
|
+
message: `Removal remains incomplete for ${pack} at ${scope} scope; rerun oat tools remove --pack ${pack} --scope ${scope}`,
|
|
240
|
+
}))
|
|
241
|
+
: [];
|
|
242
|
+
return {
|
|
243
|
+
schemaVersion: 1,
|
|
244
|
+
selection: {
|
|
245
|
+
pack,
|
|
246
|
+
requested: scopes.includes('project') && scopes.includes('user')
|
|
247
|
+
? 'both'
|
|
248
|
+
: scopes[0],
|
|
249
|
+
retainedRealizedScopes: finalEvidence?.knownRealizedScopes ?? [],
|
|
250
|
+
targetScopes: scopes,
|
|
251
|
+
},
|
|
252
|
+
canonical: {
|
|
253
|
+
status: removed && !dryRun ? 'applied' : 'unchanged',
|
|
254
|
+
results: [],
|
|
255
|
+
},
|
|
256
|
+
sync: { scopes: [], status: 'not-run', providers: [] },
|
|
257
|
+
finalEvidence,
|
|
258
|
+
status: verified ? 'complete' : inventoryVerified ? 'partial' : 'failed',
|
|
259
|
+
recovery,
|
|
260
|
+
};
|
|
261
|
+
});
|
|
262
|
+
}
|
|
263
|
+
export function failedRemovalLifecycleOutcomes(target, scopes, error) {
|
|
264
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
265
|
+
return selectedPacks(target).map((pack) => ({
|
|
266
|
+
schemaVersion: 1,
|
|
267
|
+
selection: {
|
|
268
|
+
pack,
|
|
269
|
+
requested: scopes.includes('project') && scopes.includes('user')
|
|
270
|
+
? 'both'
|
|
271
|
+
: scopes[0],
|
|
272
|
+
retainedRealizedScopes: [],
|
|
273
|
+
targetScopes: scopes,
|
|
274
|
+
},
|
|
275
|
+
canonical: { status: 'failed', results: [] },
|
|
276
|
+
sync: { scopes: [], status: 'not-run', providers: [] },
|
|
277
|
+
finalEvidence: null,
|
|
278
|
+
status: 'failed',
|
|
279
|
+
recovery: [{ code: 'canonical-apply-failed', message }],
|
|
280
|
+
}));
|
|
281
|
+
}
|
|
282
|
+
export function failedPostRemovalLifecycleOutcomes(target, scopes, outcomes, stage, failedPack, failedScope, error) {
|
|
283
|
+
const detail = error instanceof Error ? error.message : String(error);
|
|
284
|
+
return selectedPacks(target).map((pack) => {
|
|
285
|
+
const canonicalApplied = outcomes.some((outcome) => outcome.pack === pack && outcome.removed);
|
|
286
|
+
const stageLabel = stage === 'intent-write'
|
|
287
|
+
? 'durable intent update failed'
|
|
288
|
+
: 'final inventory failed';
|
|
289
|
+
const canonicalSummary = canonicalApplied
|
|
290
|
+
? `Canonical removal was applied for ${pack}, but final state is unverified`
|
|
291
|
+
: `No canonical removal was observed for ${pack}; final state remains unverified`;
|
|
292
|
+
return {
|
|
293
|
+
schemaVersion: 1,
|
|
294
|
+
selection: {
|
|
295
|
+
pack,
|
|
296
|
+
requested: scopes.includes('project') && scopes.includes('user')
|
|
297
|
+
? 'both'
|
|
298
|
+
: scopes[0],
|
|
299
|
+
retainedRealizedScopes: [],
|
|
300
|
+
targetScopes: scopes,
|
|
301
|
+
},
|
|
302
|
+
canonical: {
|
|
303
|
+
status: canonicalApplied ? 'applied' : 'unchanged',
|
|
304
|
+
results: [],
|
|
305
|
+
},
|
|
306
|
+
sync: { scopes: [], status: 'not-run', providers: [] },
|
|
307
|
+
finalEvidence: null,
|
|
308
|
+
status: 'failed',
|
|
309
|
+
recovery: scopes.map((scope) => ({
|
|
310
|
+
code: 'final-inventory-unverified',
|
|
311
|
+
message: `${canonicalSummary} because ${stageLabel} for ${failedPack} at ${failedScope} scope: ${detail}. Rerun oat tools remove --pack ${pack} --scope ${scope}`,
|
|
312
|
+
})),
|
|
313
|
+
};
|
|
314
|
+
});
|
|
315
|
+
}
|
|
@@ -1,3 +1,22 @@
|
|
|
1
|
+
import type { ConcreteScope } from '../../../shared/types.js';
|
|
2
|
+
import { type PackEvidenceDiagnostic, type ToolPackEvidence } from './pack-evidence.js';
|
|
1
3
|
import type { PackInventory } from './pack-inventory.js';
|
|
4
|
+
import { type PackPathRoots } from './pack-paths.js';
|
|
5
|
+
import type { PackName } from './types.js';
|
|
6
|
+
export interface PackEvidenceBlockV1 {
|
|
7
|
+
schemaVersion: 1;
|
|
8
|
+
status: 'ok' | 'partial' | 'error';
|
|
9
|
+
items: readonly ToolPackEvidence[];
|
|
10
|
+
diagnostics: readonly PackEvidenceDiagnostic[];
|
|
11
|
+
}
|
|
12
|
+
export declare function unavailablePackEvidence(input: {
|
|
13
|
+
pack: PackName;
|
|
14
|
+
scopes: readonly ConcreteScope[];
|
|
15
|
+
reason: string;
|
|
16
|
+
roots?: PackPathRoots;
|
|
17
|
+
}): ToolPackEvidence;
|
|
18
|
+
export declare function projectRenderablePackEvidence(canonical: PackInventory, roots: PackPathRoots): ToolPackEvidence;
|
|
19
|
+
export declare function packEvidenceBlock(items: readonly ToolPackEvidence[]): PackEvidenceBlockV1;
|
|
20
|
+
export declare function formatPackEvidenceDetails(evidence: ToolPackEvidence, indent?: string): string[];
|
|
2
21
|
export declare function formatPackInventoryDetails(inventory: PackInventory, indent?: string): string[];
|
|
3
22
|
//# sourceMappingURL=format-pack-inventory.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"format-pack-inventory.d.ts","sourceRoot":"","sources":["../../../../src/commands/tools/shared/format-pack-inventory.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"format-pack-inventory.d.ts","sourceRoot":"","sources":["../../../../src/commands/tools/shared/format-pack-inventory.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAEnD,OAAO,EAIL,KAAK,sBAAsB,EAC3B,KAAK,gBAAgB,EACtB,MAAM,iBAAiB,CAAC;AACzB,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,EAAkB,KAAK,aAAa,EAAE,MAAM,cAAc,CAAC;AAClE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAExC,MAAM,WAAW,mBAAmB;IAClC,aAAa,EAAE,CAAC,CAAC;IACjB,MAAM,EAAE,IAAI,GAAG,SAAS,GAAG,OAAO,CAAC;IACnC,KAAK,EAAE,SAAS,gBAAgB,EAAE,CAAC;IACnC,WAAW,EAAE,SAAS,sBAAsB,EAAE,CAAC;CAChD;AAED,wBAAgB,uBAAuB,CAAC,KAAK,EAAE;IAC7C,IAAI,EAAE,QAAQ,CAAC;IACf,MAAM,EAAE,SAAS,aAAa,EAAE,CAAC;IACjC,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,aAAa,CAAC;CACvB,GAAG,gBAAgB,CAiBnB;AA4CD,wBAAgB,6BAA6B,CAC3C,SAAS,EAAE,aAAa,EACxB,KAAK,EAAE,aAAa,GACnB,gBAAgB,CAiClB;AAED,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,SAAS,gBAAgB,EAAE,GACjC,mBAAmB,CAQrB;AAUD,wBAAgB,yBAAyB,CACvC,QAAQ,EAAE,gBAAgB,EAC1B,MAAM,SAAO,GACZ,MAAM,EAAE,CAuBV;AAED,wBAAgB,0BAA0B,CACxC,SAAS,EAAE,aAAa,EACxB,MAAM,SAAO,GACZ,MAAM,EAAE,CAuBV"}
|