@pareto4/pp-core 1.6.0 → 1.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (58) hide show
  1. package/.claude-plugin/plugin.json +1 -1
  2. package/agents/pp-code-fixer.md +3 -3
  3. package/bin/install.js +0 -6
  4. package/gemini-extension.json +1 -1
  5. package/package.json +1 -1
  6. package/pp-core/bin/lib/agent-install-check.cjs +1 -1
  7. package/pp-core/bin/lib/audit-command-router.cjs +3 -3
  8. package/pp-core/bin/lib/audit.cjs +1 -1
  9. package/pp-core/bin/lib/capability-activation.cjs +1 -1
  10. package/pp-core/bin/lib/capability-registry.cjs +177 -4
  11. package/pp-core/bin/lib/capability-state.cjs +1 -1
  12. package/pp-core/bin/lib/capability-writer.cjs +1 -1
  13. package/pp-core/bin/lib/check-command-router.cjs +82 -8
  14. package/pp-core/bin/lib/cjs-command-router-adapter.cjs +1 -1
  15. package/pp-core/bin/lib/code-review-flags.cjs +1 -1
  16. package/pp-core/bin/lib/config-loader.cjs +1 -1
  17. package/pp-core/bin/lib/config.cjs +1 -1
  18. package/pp-core/bin/lib/context-utilization.cjs +1 -1
  19. package/pp-core/bin/lib/docs.cjs +1 -1
  20. package/pp-core/bin/lib/frontmatter.cjs +1 -1
  21. package/pp-core/bin/lib/git-base-branch.cjs +2 -2
  22. package/pp-core/bin/lib/graphify-command-router.cjs +4 -4
  23. package/pp-core/bin/lib/graphify.cjs +1 -1
  24. package/pp-core/bin/lib/gsd2-import.cjs +1 -1
  25. package/pp-core/bin/lib/init-command-router.cjs +1 -1
  26. package/pp-core/bin/lib/init.cjs +1 -1
  27. package/pp-core/bin/lib/intel-command-router.cjs +5 -5
  28. package/pp-core/bin/lib/intel.cjs +1 -1
  29. package/pp-core/bin/lib/io.cjs +2 -2
  30. package/pp-core/bin/lib/loop-resolver.cjs +1 -1
  31. package/pp-core/bin/lib/phase-command-router.cjs +1 -1
  32. package/pp-core/bin/lib/phases-command-router.cjs +1 -1
  33. package/pp-core/bin/lib/plan-drift-guard.cjs +1 -1
  34. package/pp-core/bin/lib/platform-bindings.cjs +13 -0
  35. package/pp-core/bin/lib/prohibition-enforcement.cjs +2 -2
  36. package/pp-core/bin/lib/roadmap-command-router.cjs +2 -2
  37. package/pp-core/bin/lib/roadmap-parser.cjs +1 -1
  38. package/pp-core/bin/lib/state-command-router.cjs +1 -1
  39. package/pp-core/bin/lib/state.cjs +2 -2
  40. package/pp-core/bin/lib/validate-command-router.cjs +1 -1
  41. package/pp-core/bin/lib/vault-command-router.cjs +56 -0
  42. package/pp-core/bin/lib/vault.cjs +686 -0
  43. package/pp-core/bin/lib/verify-command-router.cjs +1 -1
  44. package/pp-core/bin/lib/verify.cjs +1 -1
  45. package/pp-core/bin/lib/worktree-base-ref.cjs +2 -2
  46. package/pp-core/bin/lib/worktree-safety.cjs +1 -1
  47. package/pp-core/bin/pp-tools.cjs +21 -21
  48. package/pp-core/bin/shared/config-defaults.manifest.json +2 -2
  49. package/pp-core/references/planning-config.md +10 -10
  50. package/pp-core/workflows/execute-phase/steps/vault-fetch.md +25 -0
  51. package/pp-core/workflows/execute-phase/steps/vault-load-gate.md +119 -0
  52. package/pp-core/workflows/plan-phase.md +12 -0
  53. package/pp-core/workflows/settings-advanced.md +4 -4
  54. package/scripts/lint-test-file-count.allowlist.json +9 -0
  55. package/assets/gsd-logo-2000-transparent.png +0 -0
  56. package/assets/gsd-logo-2000-transparent.svg +0 -17
  57. package/assets/gsd-logo-2000.png +0 -0
  58. package/assets/gsd-logo-2000.svg +0 -21
@@ -208,9 +208,9 @@ function gitWorktreeInfoInternal(cwd) {
208
208
  }
209
209
  // ─── CLI entry point ──────────────────────────────────────────────────────────
210
210
  /**
211
- * CLI command: `gsd-tools git base-branch`
211
+ * CLI command: `pp-tools git base-branch`
212
212
  * Resolves the default branch and writes it to stdout (raw string, newline-terminated).
213
- * Called by workflows via `gsd_run query git.base-branch`.
213
+ * Called by workflows via `pp_run query git.base-branch`.
214
214
  */
215
215
  function cmdGitBaseBranch(cwd, _args, deps) {
216
216
  const branch = resolveBaseBranch(cwd, deps);
@@ -1,9 +1,9 @@
1
1
  'use strict';
2
2
  /**
3
- * Graphify command router — CLI subcommand dispatcher for `gsd-tools graphify`.
3
+ * Graphify command router — CLI subcommand dispatcher for `pp-tools graphify`.
4
4
  *
5
5
  * ADR-959 (phase 4d-impl-2) pilot: first real capability command cutover.
6
- * Extracted from the hardcoded `case 'graphify':` arm in gsd-tools.cjs.
6
+ * Extracted from the hardcoded `case 'graphify':` arm in pp-tools.cjs.
7
7
  * Behaviour is preserved byte-for-behaviour from the prior inline case;
8
8
  * the dispatch path now flows: default → dispatchCapabilityCommand →
9
9
  * require(graphify-command-router.cjs) → routeGraphifyCommand.
@@ -34,7 +34,7 @@ function routeGraphifyCommand({ args, cwd, raw, error, _graphify }) {
34
34
  if (subcommand === 'query') {
35
35
  const term = args[2];
36
36
  if (!term) {
37
- error('Usage: gsd-tools graphify query <term>', ERROR_REASON.USAGE);
37
+ error('Usage: pp-tools graphify query <term>', ERROR_REASON.USAGE);
38
38
  return;
39
39
  }
40
40
  const budgetIdx = args.indexOf('--budget');
@@ -42,7 +42,7 @@ function routeGraphifyCommand({ args, cwd, raw, error, _graphify }) {
42
42
  if (budgetIdx !== -1) {
43
43
  const rawBudget = args[budgetIdx + 1];
44
44
  if (rawBudget === undefined || Number.isNaN(parseInt(rawBudget, 10))) {
45
- error('Usage: gsd-tools graphify query <term> [--budget <N>]', ERROR_REASON.USAGE);
45
+ error('Usage: pp-tools graphify query <term> [--budget <N>]', ERROR_REASON.USAGE);
46
46
  return;
47
47
  }
48
48
  budget = parseInt(rawBudget, 10);
@@ -20,7 +20,7 @@ const { isCapabilityActive } = capabilityStateMod;
20
20
  * Return the standard disabled response object.
21
21
  */
22
22
  function disabledResponse() {
23
- return { disabled: true, message: 'graphify is not enabled. Enable with: gsd-tools config-set graphify.enabled true' };
23
+ return { disabled: true, message: 'graphify is not enabled. Enable with: pp-tools config-set graphify.enabled true' };
24
24
  }
25
25
  // ─── Subprocess Helper ───────────────────────────────────────────────────────
26
26
  /**
@@ -392,7 +392,7 @@ function writePlanningDir(artifacts, planningRoot) {
392
392
  }
393
393
  // ─── Command Handler ──────────────────────────────────────────────────────────
394
394
  /**
395
- * Entry point called from gsd-tools.cjs.
395
+ * Entry point called from pp-tools.cjs.
396
396
  * Supports: --force, --dry-run, --path <dir>
397
397
  */
398
398
  function cmdFromGsd2(args, cwd, raw) {
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  /**
3
3
  * Manifest-backed init subcommand router.
4
- * Keeps gsd-tools.cjs thin while preserving existing command semantics.
4
+ * Keeps pp-tools.cjs thin while preserving existing command semantics.
5
5
  *
6
6
  * Phase 6: all init.* subcommands have SDK equivalents and are dispatched
7
7
  * via executeForCjs (the sync bridge). CJS fallback retained when:
@@ -1218,7 +1218,7 @@ function cmdInitManager(cwd, raw) {
1218
1218
  const safe = tokens.every((t) => /^--[a-zA-Z0-9][-a-zA-Z0-9]*$/.test(t) ||
1219
1219
  /^[a-zA-Z0-9][-a-zA-Z0-9_.]*$/.test(t));
1220
1220
  if (!safe) {
1221
- process.stderr.write(`gsd-tools: warning: manager.flags contains invalid tokens, ignoring: ${val}\n`);
1221
+ process.stderr.write(`pp-tools: warning: manager.flags contains invalid tokens, ignoring: ${val}\n`);
1222
1222
  return '';
1223
1223
  }
1224
1224
  return val;
@@ -1,10 +1,10 @@
1
1
  'use strict';
2
2
  /**
3
- * Intel command router — CLI subcommand dispatcher for `gsd-tools intel`.
3
+ * Intel command router — CLI subcommand dispatcher for `pp-tools intel`.
4
4
  *
5
5
  * ADR-959 (phase 4d-impl-4): intel command family cutover — last first-party
6
6
  * command cutover in the initial capability rollout.
7
- * Extracted from the hardcoded `case 'intel':` arm in gsd-tools.cjs.
7
+ * Extracted from the hardcoded `case 'intel':` arm in pp-tools.cjs.
8
8
  * Behaviour is preserved byte-for-behaviour from the prior inline case;
9
9
  * the dispatch path now flows: default → dispatchCapabilityCommand →
10
10
  * require(intel-command-router.cjs) → routeIntelCommand.
@@ -56,7 +56,7 @@ function routeIntelCommand({ args, cwd, raw, error, _intel, _core }) {
56
56
  if (subcommand === 'query') {
57
57
  const term = args[2];
58
58
  if (!term) {
59
- error('Usage: gsd-tools intel query <term>', ERROR_REASON.USAGE);
59
+ error('Usage: pp-tools intel query <term>', ERROR_REASON.USAGE);
60
60
  return;
61
61
  }
62
62
  const planningDir = path.join(cwd, '.planning');
@@ -85,7 +85,7 @@ function routeIntelCommand({ args, cwd, raw, error, _intel, _core }) {
85
85
  else if (subcommand === 'patch-meta') {
86
86
  const filePath = args[2];
87
87
  if (!filePath) {
88
- error('Usage: gsd-tools intel patch-meta <file-path>', ERROR_REASON.USAGE);
88
+ error('Usage: pp-tools intel patch-meta <file-path>', ERROR_REASON.USAGE);
89
89
  return;
90
90
  }
91
91
  c.output(intel.intelPatchMeta(path.resolve(cwd, filePath)), raw);
@@ -97,7 +97,7 @@ function routeIntelCommand({ args, cwd, raw, error, _intel, _core }) {
97
97
  else if (subcommand === 'extract-exports') {
98
98
  const filePath = args[2];
99
99
  if (!filePath) {
100
- error('Usage: gsd-tools intel extract-exports <file-path>', ERROR_REASON.USAGE);
100
+ error('Usage: pp-tools intel extract-exports <file-path>', ERROR_REASON.USAGE);
101
101
  return;
102
102
  }
103
103
  c.output(intel.intelExtractExports(path.resolve(cwd, filePath)), raw);
@@ -240,7 +240,7 @@ function intelUpdate(planningDir) {
240
240
  return disabledResponse();
241
241
  return {
242
242
  action: 'spawn_agent',
243
- message: 'Run gsd-tools intel update or spawn gsd-intel-updater agent for full refresh',
243
+ message: 'Run pp-tools intel update or spawn gsd-intel-updater agent for full refresh',
244
244
  };
245
245
  }
246
246
  /**
@@ -161,7 +161,7 @@ const ERROR_REASON = Object.freeze({
161
161
  CONFIG_NO_FILE: 'config_no_file',
162
162
  CONFIG_PARSE_FAILED: 'config_parse_failed',
163
163
  CONFIG_INVALID_KEY: 'config_invalid_key',
164
- // SDK / gsd-tools dispatch
164
+ // SDK / pp-tools dispatch
165
165
  SDK_FAIL_FAST: 'sdk_fail_fast',
166
166
  SDK_UNKNOWN_COMMAND: 'sdk_unknown_command',
167
167
  SDK_MISSING_ARG: 'sdk_missing_arg',
@@ -183,7 +183,7 @@ const ERROR_REASON = Object.freeze({
183
183
  });
184
184
  /**
185
185
  * Process-level flag: when true, error() emits structured JSON to stderr
186
- * instead of plain "Error: <message>" text. Set by gsd-tools.cjs when the
186
+ * instead of plain "Error: <message>" text. Set by pp-tools.cjs when the
187
187
  * CLI is invoked with `--json-errors`. Tests opt in to typed-IR error
188
188
  * assertions by passing that flag and parsing the JSON.
189
189
  *
@@ -10,7 +10,7 @@
10
10
  * at plan:pre (ui-phase) and autonomous.md at verify:post (ui-review). Further per-feature
11
11
  * cutovers are ongoing.
12
12
  *
13
- * Command surface: gsd-tools loop render-hooks <point>
13
+ * Command surface: pp-tools loop render-hooks <point>
14
14
  *
15
15
  * Exports (three things):
16
16
  * resolveLoopHooks({ point, registry, config }) → { point, activeHooks }
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  /**
3
3
  * Manifest-backed phase subcommand router.
4
- * Keeps gsd-tools.cjs thin while preserving existing command semantics.
4
+ * Keeps pp-tools.cjs thin while preserving existing command semantics.
5
5
  *
6
6
  * Unsupported in this router:
7
7
  * - scaffold: routed through top-level scaffold command.
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  /**
3
3
  * Manifest-backed phases subcommand router.
4
- * Keeps gsd-tools.cjs thin while preserving current CJS semantics.
4
+ * Keeps pp-tools.cjs thin while preserving current CJS semantics.
5
5
  *
6
6
  * Unsupported in this router (treated as unknown):
7
7
  * - archive: `phases archive` is excluded from the subcommands list so it
@@ -8,7 +8,7 @@
8
8
  * Design constraints:
9
9
  * - Pure module: no I/O, no require() calls, no side effects.
10
10
  * - All inputs are validated; unknown values throw a TypeError.
11
- * - Consumed by the `gsd-tools drift-guard` CLI seam and by tests.
11
+ * - Consumed by the `pp-tools drift-guard` CLI seam and by tests.
12
12
  *
13
13
  * Authority ladder (rung values determine MISSING severity):
14
14
  * grep=0 intel=1 treesitter=2 lsp=3 scip=4
@@ -48,6 +48,12 @@ const PLATFORM_REPO_RE = /^[\w.-]+\/[\w.-]+$/;
48
48
  const PLATFORM_TAG_RE = /^v\d+\.\d+\.\d+/;
49
49
  // Provisional namespace pattern (lenient): only enforced if client.slug is present.
50
50
  const SLUG_RE = /^[a-z0-9][a-z0-9-]*$/;
51
+ // Provisional vault repo pattern (lenient): only enforced if client.vaultRepo is present.
52
+ // MUST mirror schemas/platform-bindings.schema.json vaultRepo.pattern byte-for-byte —
53
+ // the schema↔validator coupling test machine-enforces this so neither side can drift.
54
+ // ReDoS note (T-11-01): anchored at both ends; single non-overlapping + quantifiers over
55
+ // disjoint character classes — no nested/ambiguous quantifier, linear complexity only.
56
+ const VAULT_REPO_RE = /^[\w.-]+(\/[\w.-]+)+$/;
51
57
  function isObject(v) {
52
58
  return typeof v === 'object' && v !== null && !Array.isArray(v);
53
59
  }
@@ -87,6 +93,13 @@ function validateBindings(o) {
87
93
  errors.push('client.slug: present but not a url-safe lowercase slug');
88
94
  }
89
95
  }
96
+ // client.vaultRepo — lenient present-only check, mirrors client.slug pattern.
97
+ // Only fires when vaultRepo is actually present; absent vault fields are fully valid (D-03).
98
+ if (isObject(o.client) && o.client.vaultRepo !== undefined) {
99
+ if (typeof o.client.vaultRepo !== 'string' || !VAULT_REPO_RE.test(o.client.vaultRepo)) {
100
+ errors.push('client.vaultRepo: present but not a valid nested group/project path (e.g. pareto4-clients/acme/acme-vault)');
101
+ }
102
+ }
90
103
  // IN-03: project.slug — symmetric lenient check matching client.slug behaviour.
91
104
  // The schema defines the same ^[a-z0-9][a-z0-9-]*$ pattern for both fields.
92
105
  if (isObject(o.project) && o.project.slug !== undefined) {
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  /**
3
3
  * prohibition-enforcement — the deterministic PRODUCER for test-tier prohibition verification
4
- * (#1259, ADR-550 Decision 5d "heavy half"; the D1 seam — a NEW deterministic gsd-tools
4
+ * (#1259, ADR-550 Decision 5d "heavy half"; the D1 seam — a NEW deterministic pp-tools
5
5
  * sub-command, NOT free-form workflow prose).
6
6
  *
7
7
  * Today `dispositionForProhibition()` (src/probe-core.cts) already carries the POLICY seam: with
@@ -645,7 +645,7 @@ function parseRequest(args) {
645
645
  }
646
646
  }
647
647
  /**
648
- * CLI surface: `gsd_run check prohibition-enforcement <request.json>` (or `--json '<inline>'`).
648
+ * CLI surface: `pp_run check prohibition-enforcement <request.json>` (or `--json '<inline>'`).
649
649
  * Parses the request, runs the producer, and emits the result as JSON. Honors the no-throw
650
650
  * contract: malformed input -> structured `error(...)`, never an uncaught throw.
651
651
  */
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  /**
3
3
  * Manifest-backed roadmap subcommand router.
4
- * Keeps gsd-tools.cjs thin while preserving existing command semantics.
4
+ * Keeps pp-tools.cjs thin while preserving existing command semantics.
5
5
  *
6
6
  * ADR-457 build-at-publish: the hand-written bin/lib/roadmap-command-router.cjs
7
7
  * collapsed to a TypeScript source of truth. Behaviour is preserved byte-for-behaviour
@@ -40,7 +40,7 @@ function checkW021(content) {
40
40
  const warnings = [];
41
41
  // Sentinel milestone integers exempt from W021
42
42
  const SENTINELS = new Set([0, 999]);
43
- const MIGRATION_CMD = 'gsd-tools roadmap upgrade --convention milestone-prefixed';
43
+ const MIGRATION_CMD = 'pp-tools roadmap upgrade --convention milestone-prefixed';
44
44
  // Milestone section heading: ## [GSD] v2.0 — Label OR ## v2.0: Label OR ## Roadmap v2.0
45
45
  // OR ## ✅ v2.0 OR ## 🚧 v2.0 (emoji-prefixed variants used by roadmap templates)
46
46
  // Capture the major integer.
@@ -346,7 +346,7 @@ function getMilestonePhaseFilter(cwd, versionOverride, phaseIdConvention) {
346
346
  if (!hasVersionedMilestonesGlobal && hasPhaseHeadings && phaseIdConvention === 'milestone-prefixed') {
347
347
  console.warn('[gsd] Deprecated: free-form ROADMAP.md detected (no versioned milestone headings). ' +
348
348
  'The project has phase_id_convention set to "milestone-prefixed" in config.json but the ' +
349
- 'ROADMAP does not use versioned milestone headings. Run `gsd-tools roadmap upgrade --convention milestone-prefixed` to migrate (dry-run by default).');
349
+ 'ROADMAP does not use versioned milestone headings. Run `pp-tools roadmap upgrade --convention milestone-prefixed` to migrate (dry-run by default).');
350
350
  }
351
351
  if (versionOverride) {
352
352
  const escapedVersion = escapeRegex(versionOverride);
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  /**
3
3
  * Manifest-backed state subcommand router.
4
- * Keeps gsd-tools.cjs thin while preserving existing command semantics.
4
+ * Keeps pp-tools.cjs thin while preserving existing command semantics.
5
5
  *
6
6
  * Phase 5.1: handlers that have SDK equivalents are dispatched via
7
7
  * executeForCjs (the sync bridge). CJS fallback is retained for:
@@ -50,7 +50,7 @@ function shouldResyncStateProgress(fields) {
50
50
  // ─── Cache ────────────────────────────────────────────────────────────────────
51
51
  // Cache disk scan results from buildStateFrontmatter per cwd per process (#1967).
52
52
  // Avoids re-reading N+1 directories on every state write when the phase structure
53
- // hasn't changed within the same gsd-tools invocation.
53
+ // hasn't changed within the same pp-tools invocation.
54
54
  const _diskScanCache = new Map();
55
55
  // Track all lock files held by this process so they can be removed on exit.
56
56
  // process.on('exit') fires even on process.exit(1), unlike try/finally which is
@@ -250,7 +250,7 @@ function stateReplaceFieldWithFallback(content, primary, fallback, value) {
250
250
  }
251
251
  // Neither pattern matched — field may have been reformatted or removed.
252
252
  // Log diagnostic so template drift is detected early rather than silently swallowed.
253
- process.stderr.write(`[gsd-tools] WARNING: STATE.md field "${primary}"${fallback ? ` (fallback: "${fallback}")` : ''} not found — update skipped. ` +
253
+ process.stderr.write(`[pp-tools] WARNING: STATE.md field "${primary}"${fallback ? ` (fallback: "${fallback}")` : ''} not found — update skipped. ` +
254
254
  `This may indicate STATE.md was externally modified or uses an unexpected format.\n`);
255
255
  return content;
256
256
  }
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  /**
3
3
  * Manifest-backed validate subcommand router.
4
- * Keeps gsd-tools.cjs thin while preserving existing command semantics.
4
+ * Keeps pp-tools.cjs thin while preserving existing command semantics.
5
5
  *
6
6
  * Phase 6: validate.consistency, validate.health, validate.agents are
7
7
  * dispatched via executeForCjs when the SDK is available. CJS fallback
@@ -0,0 +1,56 @@
1
+ 'use strict';
2
+ /**
3
+ * Vault command router — CLI subcommand dispatcher for `pp-tools vault`.
4
+ *
5
+ * Milestone v1.7.0 Client Vault Load, Phase 12-03: wires the fetch/status/summary
6
+ * impl from Plans 12-01/12-02 (src/vault.cts) into the CLI as real verbs. The
7
+ * dispatch path flows: default → dispatchCapabilityCommand →
8
+ * require(vault-command-router.cjs) → routeVaultCommand, discovered by name via
9
+ * the capability registry (capabilities/vault/capability.json commands[]). No
10
+ * hardcoded `case 'vault':` arm in pp-tools.cjs (ADR-959 declarative registration).
11
+ *
12
+ * Router signature: { args, cwd, raw, error } — identical to the host routers
13
+ * (mirrors src/intel-command-router.cts exactly).
14
+ *
15
+ * Arg indexing:
16
+ * args[0] = 'vault' (family — matched by dispatchCapabilityCommand)
17
+ * args[1] = subcommand (fetch | status | summary)
18
+ *
19
+ * Test seams: pass `_vault` to inject a mock vault module; pass `_core` to inject
20
+ * a mock core module that captures `output()` calls instead of writing to real
21
+ * stdout. The `_`-prefix follows the repo's established seam convention (see
22
+ * intel-command-router.cts / audit-command-router.cts). Production callers omit
23
+ * both and the real ./vault.cjs is lazy-required INSIDE the route function so it
24
+ * only loads when a vault command is actually dispatched.
25
+ *
26
+ * ADR-457 build-at-publish: this TypeScript file is the SOURCE OF TRUTH. It
27
+ * compiles to the git-ignored `pp-core/bin/lib/vault-command-router.cjs`; do NOT
28
+ * hand-edit the compiled output.
29
+ */
30
+ // eslint-disable-next-line @typescript-eslint/no-require-imports
31
+ const io = require("./io.cjs");
32
+ const { ERROR_REASON } = io;
33
+ // Default CoreModule implementation. _core seam overrides this for test injection.
34
+ const _defaultCore = { output: io.output };
35
+ // ─── Implementation ───────────────────────────────────────────────────────────
36
+ function routeVaultCommand({ args, cwd, raw, error, _vault, _core }) {
37
+ // eslint-disable-next-line @typescript-eslint/no-require-imports, @typescript-eslint/no-unsafe-assignment
38
+ const vault = _vault ?? require('./vault.cjs');
39
+ const c = _core ?? _defaultCore;
40
+ const subcommand = args[1];
41
+ if (subcommand === 'fetch') {
42
+ c.output(vault.vaultFetch(cwd), raw);
43
+ }
44
+ else if (subcommand === 'status') {
45
+ c.output(vault.vaultStatus(cwd), raw);
46
+ }
47
+ else if (subcommand === 'summary') {
48
+ c.output(vault.vaultSummary(cwd), raw);
49
+ }
50
+ else {
51
+ error('Unknown vault subcommand. Available: fetch, status, summary', ERROR_REASON.SDK_UNKNOWN_COMMAND);
52
+ }
53
+ }
54
+ module.exports = {
55
+ routeVaultCommand,
56
+ };