peaks-loop 4.0.0-beta.14 → 4.0.0-beta.16

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 (204) hide show
  1. package/CHANGELOG.md +230 -148
  2. package/README-en.md +1 -1
  3. package/README.md +32 -1
  4. package/bin/peaks.js +0 -0
  5. package/dist/cli/cli-helpers.d.ts +1 -1
  6. package/dist/cli/cli-helpers.js +1 -1
  7. package/dist/cli/commands/adapter-commands-s2a.js +1 -1
  8. package/dist/cli/commands/asset-commands.js +33 -16
  9. package/dist/cli/commands/audit-commands.js +1 -1
  10. package/dist/cli/commands/bee-commands.js +1 -1
  11. package/dist/cli/commands/capability-commands.js +1 -1
  12. package/dist/cli/commands/classify-classify-commands.js +1 -1
  13. package/dist/cli/commands/code-commands.js +1 -1
  14. package/dist/cli/commands/code-review-commands.js +1 -1
  15. package/dist/cli/commands/codegraph-commands.js +1 -1
  16. package/dist/cli/commands/compact-command.js +1 -1
  17. package/dist/cli/commands/complexity-commands.js +1 -1
  18. package/dist/cli/commands/config-commands.js +1 -1
  19. package/dist/cli/commands/context-commands.js +1 -1
  20. package/dist/cli/commands/contract-commands.js +1 -1
  21. package/dist/cli/commands/core/artifacts-command.js +1 -1
  22. package/dist/cli/commands/core/binding-commands.js +1 -1
  23. package/dist/cli/commands/core/doctor-command.js +63 -3
  24. package/dist/cli/commands/core/memory-command.js +1 -1
  25. package/dist/cli/commands/core/profile-command.js +1 -1
  26. package/dist/cli/commands/core/proxy-command.js +1 -1
  27. package/dist/cli/commands/core/session-command.js +1 -1
  28. package/dist/cli/commands/core/skill-command.js +2 -2
  29. package/dist/cli/commands/core/standards-command.js +1 -1
  30. package/dist/cli/commands/dispatch-commands.js +2 -2
  31. package/dist/cli/commands/dispatch-from-dag.js +1 -1
  32. package/dist/cli/commands/doc-commands.js +1 -1
  33. package/dist/cli/commands/ecc-commands.js +2 -2
  34. package/dist/cli/commands/evolution-commands.js +1 -1
  35. package/dist/cli/commands/feedback-commands.js +1 -1
  36. package/dist/cli/commands/final-review-commands.js +1 -1
  37. package/dist/cli/commands/fixture-commands.js +1 -1
  38. package/dist/cli/commands/fork-commands.js +1 -1
  39. package/dist/cli/commands/gate-commands.js +1 -1
  40. package/dist/cli/commands/heartbeat-commands.js +1 -1
  41. package/dist/cli/commands/hook-handle.js +1 -1
  42. package/dist/cli/commands/hooks-commands.js +1 -1
  43. package/dist/cli/commands/ide-commands.js +1 -1
  44. package/dist/cli/commands/impact-commands.js +1 -1
  45. package/dist/cli/commands/job-commands.js +1 -1
  46. package/dist/cli/commands/legacy-commands.js +1 -1
  47. package/dist/cli/commands/log-commands.js +1 -1
  48. package/dist/cli/commands/loop-commands.js +1 -1
  49. package/dist/cli/commands/loop-eval-commands.js +1 -1
  50. package/dist/cli/commands/memory-commands.js +1 -1
  51. package/dist/cli/commands/migrate-1-4-1-command.js +1 -1
  52. package/dist/cli/commands/migrate-v2-10-to-v2-11-command.js +1 -1
  53. package/dist/cli/commands/mut-commands.d.ts +1 -1
  54. package/dist/cli/commands/mut-commands.js +1 -5
  55. package/dist/cli/commands/observability-commands.js +1 -1
  56. package/dist/cli/commands/openspec-commands.js +2 -2
  57. package/dist/cli/commands/perf-audit-commands.js +2 -2
  58. package/dist/cli/commands/perf-commands.js +1 -1
  59. package/dist/cli/commands/polyrepo-commands.js +1 -1
  60. package/dist/cli/commands/prd-blocks-commands.js +1 -1
  61. package/dist/cli/commands/prd-commands.js +1 -1
  62. package/dist/cli/commands/project-commands.js +1 -1
  63. package/dist/cli/commands/qa-business-review-commands.js +1 -1
  64. package/dist/cli/commands/qa-commands.d.ts +1 -1
  65. package/dist/cli/commands/qa-commands.js +2 -2
  66. package/dist/cli/commands/release-commands.js +1 -1
  67. package/dist/cli/commands/request-commands.js +1 -1
  68. package/dist/cli/commands/retrospective-commands.js +1 -1
  69. package/dist/cli/commands/reviewer-commands.js +1 -1
  70. package/dist/cli/commands/role-commands.js +1 -1
  71. package/dist/cli/commands/runtime-commands.js +1 -2
  72. package/dist/cli/commands/sc-commands.js +1 -1
  73. package/dist/cli/commands/scan-commands.js +1 -1
  74. package/dist/cli/commands/security-audit-commands.js +2 -2
  75. package/dist/cli/commands/share-commands.d.ts +19 -0
  76. package/dist/cli/commands/share-commands.js +121 -2
  77. package/dist/cli/commands/skill-conformance-commands.js +1 -1
  78. package/dist/cli/commands/skill-loop-engineering-readiness-commands.js +1 -1
  79. package/dist/cli/commands/skill-search-commands.js +1 -1
  80. package/dist/cli/commands/slice-commands.js +1 -1
  81. package/dist/cli/commands/slice-integrate-commands.js +1 -1
  82. package/dist/cli/commands/slice-review-commands.js +1 -1
  83. package/dist/cli/commands/smoke-commands.js +1 -1
  84. package/dist/cli/commands/sop-commands.js +1 -1
  85. package/dist/cli/commands/statusline-commands.js +1 -1
  86. package/dist/cli/commands/sub-agent-commands.js +2 -1
  87. package/dist/cli/commands/understand-commands.js +1 -1
  88. package/dist/cli/commands/upgrade-commands.js +1 -1
  89. package/dist/cli/commands/user-touchpoint-commands.js +1 -1
  90. package/dist/cli/commands/verdict-aggregate-command.js +1 -1
  91. package/dist/cli/commands/workflow-commands.js +1 -1
  92. package/dist/cli/commands/workflow-plan-commands.js +1 -1
  93. package/dist/cli/commands/workspace/init-command.js +1 -1
  94. package/dist/cli/commands/workspace/migrate-command.js +1 -1
  95. package/dist/cli/commands/workspace/reconcile-command.js +1 -1
  96. package/dist/cli/index.js +1 -1
  97. package/dist/cli/program.js +2 -2
  98. package/dist/services/artifacts/artifact-prerequisites.js +1 -1
  99. package/dist/services/artifacts/request-artifact-service.js +1 -1
  100. package/dist/services/artifacts/workspace-service.js +1 -1
  101. package/dist/services/code/auto-compact-orchestrator.js +5 -2
  102. package/dist/services/code-review/ocr-service.d.ts +1 -1
  103. package/dist/services/code-review/ocr-service.js +6 -3
  104. package/dist/services/config/config-types.js +1 -1
  105. package/dist/services/dashboard/project-dashboard-service.js +2 -2
  106. package/dist/services/dispatch/batch-counter.js +1 -1
  107. package/dist/services/dispatch/dispatch-record-writer.js +1 -1
  108. package/dist/services/job/job-progress-store.d.ts +2 -2
  109. package/dist/services/job/job-types.d.ts +27 -27
  110. package/dist/services/log/retention.js +1 -1
  111. package/dist/services/openspec/openspec-archive-service.js +1 -1
  112. package/dist/services/openspec/openspec-bridge-service.js +1 -1
  113. package/dist/services/openspec/openspec-init-service.js +1 -1
  114. package/dist/services/openspec/openspec-propose-from-doctor-service.js +1 -1
  115. package/dist/services/openspec/openspec-render-service.js +1 -1
  116. package/dist/services/openspec/openspec-scan-service.js +1 -1
  117. package/dist/services/openspec/openspec-validate-service.js +1 -1
  118. package/dist/services/scan/acceptance-coverage-service.js +1 -1
  119. package/dist/services/scan/archetype-service.js +1 -1
  120. package/dist/services/scan/existing-system-service.js +1 -1
  121. package/dist/services/scan/libraries-service.js +1 -1
  122. package/dist/services/skill/skill-search-service.d.ts +5 -5
  123. package/dist/services/skill/skill-search-service.js +2 -2
  124. package/dist/services/skills/skill-registry.js +2 -2
  125. package/dist/services/skills/skill-runbook-service.js +1 -1
  126. package/dist/services/slice/slice-check-service.js +1 -1
  127. package/dist/services/understand/understand-hybrid-service.js +1 -1
  128. package/dist/services/understand/understand-scan-service.js +2 -2
  129. package/dist/services/upgrade/upgrade-service.js +4 -3
  130. package/dist/services/verdict/envelopes.d.ts +2 -2
  131. package/dist/services/verdict/envelopes.js +2 -2
  132. package/dist/services/verdict/verdict-aggregator.d.ts +3 -3
  133. package/dist/services/workflow/autonomous-resume-writer.js +1 -1
  134. package/dist/services/workflow/plan-reader.d.ts +1 -1
  135. package/dist/services/workflow/plan-reader.js +1 -1
  136. package/dist/services/workflow/plan-refresher.d.ts +1 -1
  137. package/dist/services/workflow/plan-refresher.js +1 -1
  138. package/dist/services/workflow/plan-trigger-detector.d.ts +1 -1
  139. package/dist/services/workflow/plan-trigger-detector.js +1 -1
  140. package/dist/services/workflow/workflow-router-service.js +11 -9
  141. package/dist/services/workspace/migrate-service.js +1 -1
  142. package/dist/services/workspace/workspace-service.js +1 -1
  143. package/package.json +13 -8
  144. package/scripts/sync-version.mjs +8 -1
  145. package/skills/bee/peaks-rd/SKILL.md +14 -1
  146. package/skills/peaks-code/SKILL.md +44 -0
  147. package/skills/peaks-code/references/sub-agent-dispatch.md +30 -0
  148. package/dist/services/agent/ecc-cache-service.d.ts +0 -97
  149. package/dist/services/agent/ecc-cache-service.js +0 -491
  150. package/dist/services/audit-independent/perf-audit-service.d.ts +0 -151
  151. package/dist/services/audit-independent/perf-audit-service.js +0 -316
  152. package/dist/services/audit-independent/security-audit-service.d.ts +0 -155
  153. package/dist/services/audit-independent/security-audit-service.js +0 -316
  154. package/dist/services/context/dispatch-context-guard.d.ts +0 -27
  155. package/dist/services/context/dispatch-context-guard.js +0 -192
  156. package/dist/services/context/shared-channel.d.ts +0 -93
  157. package/dist/services/context/shared-channel.js +0 -308
  158. package/dist/services/crystallization/crystallization-service.d.ts +0 -239
  159. package/dist/services/crystallization/crystallization-service.js +0 -397
  160. package/dist/services/crystallization/crystallization-store.d.ts +0 -75
  161. package/dist/services/crystallization/crystallization-store.js +0 -193
  162. package/dist/services/crystallization/crystallization-types.d.ts +0 -313
  163. package/dist/services/crystallization/crystallization-types.js +0 -299
  164. package/dist/services/crystallization/evidence-brief-builder.d.ts +0 -237
  165. package/dist/services/crystallization/evidence-brief-builder.js +0 -240
  166. package/dist/services/doctor/doctor-service.d.ts +0 -149
  167. package/dist/services/doctor/doctor-service.js +0 -929
  168. package/dist/services/filesystem/file-lock.d.ts +0 -11
  169. package/dist/services/filesystem/file-lock.js +0 -152
  170. package/dist/services/final-review/final-review-service.d.ts +0 -12
  171. package/dist/services/final-review/final-review-service.js +0 -52
  172. package/dist/services/final-review/final-review-types.d.ts +0 -42
  173. package/dist/services/final-review/final-review-types.js +0 -18
  174. package/dist/services/job/job-resource-snapshot.d.ts +0 -7
  175. package/dist/services/job/job-resource-snapshot.js +0 -75
  176. package/dist/services/mut/assert-scanner.d.ts +0 -6
  177. package/dist/services/mut/assert-scanner.js +0 -116
  178. package/dist/services/mut/index.d.ts +0 -8
  179. package/dist/services/mut/index.js +0 -7
  180. package/dist/services/mut/mut-runner.d.ts +0 -39
  181. package/dist/services/mut/mut-runner.js +0 -29
  182. package/dist/services/mut/production-stryker.d.ts +0 -2
  183. package/dist/services/mut/production-stryker.js +0 -75
  184. package/dist/services/mut/report-builder.d.ts +0 -11
  185. package/dist/services/mut/report-builder.js +0 -110
  186. package/dist/services/mut/report-loader.d.ts +0 -31
  187. package/dist/services/mut/report-loader.js +0 -78
  188. package/dist/services/mut/thresholds.d.ts +0 -21
  189. package/dist/services/mut/thresholds.js +0 -22
  190. package/dist/services/mut/types.d.ts +0 -336
  191. package/dist/services/mut/types.js +0 -59
  192. package/dist/shared/fs.d.ts +0 -4
  193. package/dist/shared/fs.js +0 -26
  194. package/dist/shared/paths.d.ts +0 -6
  195. package/dist/shared/paths.js +0 -50
  196. package/dist/shared/result.d.ts +0 -22
  197. package/dist/shared/result.js +0 -46
  198. package/dist/shared/version.d.ts +0 -1
  199. package/dist/shared/version.js +0 -1
  200. package/examples/video-demo/README.md +0 -142
  201. package/examples/video-demo/out/en-closing-960.png +0 -0
  202. package/examples/video-demo/out/zh-closing-960.png +0 -0
  203. package/examples/video-demo/preview/peaks-loop-demo-en.mp4 +0 -0
  204. package/examples/video-demo/preview/peaks-loop-demo.mp4 +0 -0
@@ -1,5 +1,5 @@
1
1
  import { existsSync } from 'node:fs';
2
- import { fail, ok } from '../../shared/result.js';
2
+ import { fail, ok } from 'peaks-loop-shared/result';
3
3
  import { addJsonOption, printResult, getErrorMessage } from '../cli-helpers.js';
4
4
  import { findProjectRoot } from '../../services/config/config-safety.js';
5
5
  import { applyHookInstall, planHookInstall, readHookStatus, readInstalledEntriesFromSettings, removeHookInstall } from '../../services/skills/hooks-settings-service.js';
@@ -1,6 +1,6 @@
1
1
  import { detectCurrentIdeModel } from '../../services/ide/current-model-detector.js';
2
2
  import { addJsonOption, printResult } from '../cli-helpers.js';
3
- import { fail, ok } from '../../shared/result.js';
3
+ import { fail, ok } from 'peaks-loop-shared/result';
4
4
  import { listAdapterIds } from '../../services/ide/ide-registry.js';
5
5
  export function registerIdeCommands(program, io) {
6
6
  const ide = program.command('ide').description('Read-only introspection helpers for the registered IDE adapter layer (slice 2026-07-09 add-zcode-adapter, Slice C)');
@@ -12,7 +12,7 @@
12
12
  */
13
13
  import { findProjectRoot } from '../../services/config/config-safety.js';
14
14
  import { mustCheckFromReport, runImpactScan } from '../../services/impact/impact-scan-service.js';
15
- import { fail, ok } from '../../shared/result.js';
15
+ import { fail, ok } from 'peaks-loop-shared/result';
16
16
  import { addJsonOption, printResult } from '../cli-helpers.js';
17
17
  export function registerImpactCommands(program, io) {
18
18
  const impact = program
@@ -1,7 +1,7 @@
1
1
  // src/cli/commands/job-commands.ts
2
2
  import { join } from 'node:path';
3
3
  import { Command } from 'commander';
4
- import { fail, ok } from '../../shared/result.js';
4
+ import { fail, ok } from 'peaks-loop-shared/result';
5
5
  import { addJsonOption, printResult } from '../cli-helpers.js';
6
6
  import { JobStateStore } from '../../services/job/job-state-store.js';
7
7
  import { JobOrchestrator } from '../../services/job/job-orchestrator.js';
@@ -8,7 +8,7 @@
8
8
  */
9
9
  import { findProjectRoot } from '../../services/config/config-safety.js';
10
10
  import { detectLegacy } from '../../services/legacy/legacy-detector.js';
11
- import { ok } from '../../shared/result.js';
11
+ import { ok } from 'peaks-loop-shared/result';
12
12
  import { addJsonOption, printResult } from '../cli-helpers.js';
13
13
  export function registerLegacyCommands(program, io) {
14
14
  addJsonOption(program
@@ -16,7 +16,7 @@ import { join } from 'node:path';
16
16
  import { homedir } from 'node:os';
17
17
  import { tailLog, listLogFiles } from '../../services/log/log-commands-service.js';
18
18
  import { getErrorMessage, printResult, addJsonOption } from '../cli-helpers.js';
19
- import { ok, fail } from '../../shared/result.js';
19
+ import { ok, fail } from 'peaks-loop-shared/result';
20
20
  export function registerLogCommands(program, io) {
21
21
  const log = program
22
22
  .command('log')
@@ -25,7 +25,7 @@
25
25
  import { existsSync, mkdirSync } from 'node:fs';
26
26
  import { join } from 'node:path';
27
27
  import { addJsonOption, getErrorMessage, printResult } from '../cli-helpers.js';
28
- import { fail, ok } from '../../shared/result.js';
28
+ import { fail, ok } from 'peaks-loop-shared/result';
29
29
  import { findProjectRoot } from '../../services/config/config-safety.js';
30
30
  import { openStateDb } from '../../services/skillhub/sqlite-store.js';
31
31
  import { writeBundle, BundleNotShareableError, BundleAssetNotFoundError, } from '../../services/share/bundle-writer.js';
@@ -7,7 +7,7 @@ import { runMonotonicCheck, resolveMonotonicContext } from '../../services/loop/
7
7
  import { resolveLoopSpec, persistSpec, buildSpec, lintLoopSpec, lintSpecFile, specPath, MONOTONIC_TERMINATION, DEFAULT_MAX_CYCLES } from '../../services/loop/spec-service.js';
8
8
  import { runLoop, resolveRunContext } from '../../services/loop/run-driver.js';
9
9
  import { addJsonOption, getErrorMessage, printResult } from '../cli-helpers.js';
10
- import { fail, ok } from '../../shared/result.js';
10
+ import { fail, ok } from 'peaks-loop-shared/result';
11
11
  import { findProjectRoot } from '../../services/config/config-safety.js';
12
12
  const VALID_EVALUATORS = new Set([
13
13
  'karpathy',
@@ -2,7 +2,7 @@ import { findProjectRoot } from '../../services/config/config-safety.js';
2
2
  import { resolveCanonicalProjectRoot } from '../../services/config/config-service.js';
3
3
  import { loadMemoryIndex, searchMemoryWithResults } from '../../services/memory/memory-search-service.js';
4
4
  import { pickFromList } from '../../services/fuzzy-matching/fzf-pick-service.js';
5
- import { fail, ok } from '../../shared/result.js';
5
+ import { fail, ok } from 'peaks-loop-shared/result';
6
6
  import { getErrorMessage, printResult } from '../cli-helpers.js';
7
7
  import { join } from 'node:path';
8
8
  const VALID_KINDS = [
@@ -6,7 +6,7 @@
6
6
  * `.peaks/_runtime/<sid>/<role>/<file>.md` path. Default is dry-run; pass
7
7
  * `--apply` to actually `rename` the files and remove emptied legacy dirs.
8
8
  */
9
- import { ok, fail } from '../../shared/result.js';
9
+ import { ok, fail } from 'peaks-loop-shared/result';
10
10
  import { resolveCanonicalProjectRoot } from '../../services/config/config-service.js';
11
11
  import { addJsonOption } from '../cli-helpers.js';
12
12
  import { planMigrate1_4_1, applyMigrate1_4_1 } from '../../services/workspace/migrate-1-4-1-service.js';
@@ -18,7 +18,7 @@
18
18
  import { addJsonOption } from '../cli-helpers.js';
19
19
  import { resolveCanonicalProjectRoot } from '../../services/config/config-service.js';
20
20
  import { planV2ToV11Migration, applyV2ToV11Migration, dryRunV2ToV11Migration } from '../../services/migration/v2-10-to-v2-11-service.js';
21
- import { ok, fail } from '../../shared/result.js';
21
+ import { ok, fail } from 'peaks-loop-shared/result';
22
22
  export function registerMigrateV2ToV11Command(workspace, io) {
23
23
  addJsonOption(workspace
24
24
  .command('migrate-v2-10-to-v2-11')
@@ -1,5 +1,5 @@
1
1
  import { Command } from 'commander';
2
- import { type StrykerInvoker } from '../../services/mut/mut-runner.js';
2
+ import { type StrykerInvoker } from 'peaks-loop-mut';
3
3
  import type { ProgramIO } from '../cli-helpers.js';
4
4
  export interface MutCommandsOptions {
5
5
  readonly invokeStryker: StrykerInvoker;
@@ -15,11 +15,7 @@
15
15
  */
16
16
  import { readFile } from 'node:fs/promises';
17
17
  import { Command } from 'commander';
18
- import { scanAssertions } from '../../services/mut/assert-scanner.js';
19
- import { runMutation } from '../../services/mut/mut-runner.js';
20
- import { buildMutReport } from '../../services/mut/report-builder.js';
21
- import { createProductionStrykerInvoker } from '../../services/mut/production-stryker.js';
22
- import { MutReportSchema } from '../../services/mut/types.js';
18
+ import { scanAssertions, runMutation, buildMutReport, createProductionStrykerInvoker, MutReportSchema, } from 'peaks-loop-mut';
23
19
  /**
24
20
  * Pure helper: a stub AssertionsReport used when only Stryker ran.
25
21
  * The mutants-only path does NOT touch the AST scanner; we still need
@@ -19,7 +19,7 @@
19
19
  */
20
20
  import { findProjectRoot } from '../../services/config/config-safety.js';
21
21
  import { resolveCanonicalProjectRoot } from '../../services/config/config-service.js';
22
- import { fail, ok } from '../../shared/result.js';
22
+ import { fail, ok } from 'peaks-loop-shared/result';
23
23
  import { getSessionIdCanonical } from '../../services/session/session-manager.js';
24
24
  import { addJsonOption, getErrorMessage, printResult } from '../cli-helpers.js';
25
25
  import { aggregateFanout, aggregateRepairCycles, aggregateSlices, aggregateStatus, filterByPeriod, periodStartIso, readAllSessionEvents, readSessionEvents } from '../../services/observability/aggregation.js';
@@ -6,8 +6,8 @@ import { validateOpenSpecChange } from '../../services/openspec/openspec-validat
6
6
  import { archiveOpenSpecChange } from '../../services/openspec/openspec-archive-service.js';
7
7
  import { executeOpenSpecInit } from '../../services/openspec/openspec-init-service.js';
8
8
  import { proposeFromDoctor } from '../../services/openspec/openspec-propose-from-doctor-service.js';
9
- import { runDoctor } from '../../services/doctor/doctor-service.js';
10
- import { fail, ok } from '../../shared/result.js';
9
+ import { runDoctor } from 'peaks-loop-doctor';
10
+ import { fail, ok } from 'peaks-loop-shared/result';
11
11
  import { addJsonOption, getErrorMessage, printResult } from '../cli-helpers.js';
12
12
  function resolveScanOptions(project) {
13
13
  if (project === undefined) {
@@ -1,7 +1,7 @@
1
1
  import { readFileSync } from 'node:fs';
2
- import { detectPerfAudit, isPerfAuditEnvelope, runPerfAudit, } from '../../services/audit-independent/perf-audit-service.js';
2
+ import { detectPerfAudit, isPerfAuditEnvelope, runPerfAudit, } from 'peaks-loop-audit-independent';
3
3
  import { addJsonOption, getErrorMessage, printResult } from '../cli-helpers.js';
4
- import { fail, ok } from '../../shared/result.js';
4
+ import { fail, ok } from 'peaks-loop-shared/result';
5
5
  function resolveEnvelope(envelopePath) {
6
6
  if (envelopePath === undefined || envelopePath === '-') {
7
7
  // Read from stdin
@@ -1,5 +1,5 @@
1
1
  import { executePerfBaselineInit, resolveProjectRootFromCwd } from '../../services/perf/perf-baseline-service.js';
2
- import { fail, ok } from '../../shared/result.js';
2
+ import { fail, ok } from 'peaks-loop-shared/result';
3
3
  import { addJsonOption, getErrorMessage, printResult } from '../cli-helpers.js';
4
4
  export function registerPerfCommands(program, io) {
5
5
  const perf = program.command('perf').description('Manage performance baseline scaffolding for the RD stage');
@@ -1,6 +1,6 @@
1
1
  import { existsSync } from 'node:fs';
2
2
  import { addJsonOption, printResult } from '../cli-helpers.js';
3
- import { fail, ok, getErrorMessage } from '../../shared/result.js';
3
+ import { fail, ok, getErrorMessage } from 'peaks-loop-shared/result';
4
4
  import { PolyrepoService } from '../../services/polyrepo/polyrepo-service.js';
5
5
  function parseChildren(raw) {
6
6
  if (raw === undefined || raw.length === 0)
@@ -15,7 +15,7 @@
15
15
  */
16
16
  import { findProjectRoot } from '../../services/config/config-safety.js';
17
17
  import { checkPrdBlocks } from '../../services/prd/prd-blocks-checker.js';
18
- import { ok } from '../../shared/result.js';
18
+ import { ok } from 'peaks-loop-shared/result';
19
19
  import { addJsonOption, printResult } from '../cli-helpers.js';
20
20
  export function registerPrdBlocksCommands(program, io) {
21
21
  // Find existing `prd` top-level command (registered by prd-commands.ts).
@@ -15,7 +15,7 @@
15
15
  */
16
16
  import { readFile } from 'node:fs/promises';
17
17
  import { initHandoff, readHandoff, showHandoff, verifyHandoff, writeHandoff } from '../../services/prd/handoff-service.js';
18
- import { fail, ok } from '../../shared/result.js';
18
+ import { fail, ok } from 'peaks-loop-shared/result';
19
19
  import { addJsonOption, getErrorMessage, printResult } from '../cli-helpers.js';
20
20
  /** Split a comma-separated string into a trimmed, non-empty list.
21
21
  * Empty / undefined input → empty array. */
@@ -4,7 +4,7 @@ import { extractSessionMemories, readMemoryIndex, readProjectMemories, readProje
4
4
  import { readBusinessKnowledge } from '../../services/prd/project-scan-reader.js';
5
5
  import { applyStalePolicy, DEFAULT_STALE_DAYS } from '../../shared/stale-policy.js';
6
6
  import { formatMdCompact } from '../../shared/format-md-compact.js';
7
- import { fail, ok } from '../../shared/result.js';
7
+ import { fail, ok } from 'peaks-loop-shared/result';
8
8
  import { addJsonOption, getErrorMessage, printResult } from '../cli-helpers.js';
9
9
  export function registerProjectCommands(program, io) {
10
10
  const project = program.command('project').description('Aggregate Peaks state for a target project (read-only)');
@@ -15,7 +15,7 @@
15
15
  import { findProjectRoot } from '../../services/config/config-safety.js';
16
16
  import { getCurrentSessionId } from '../../services/skills/skill-presence-service.js';
17
17
  import { acceptQaReview, buildEmptyQaReview, deriveQaDecision, QA_BUSINESS_ITEMS, readQaReview, rejectQaReview, scoreQaItem, writeQaReview } from '../../services/qa/qa-business-review-state.js';
18
- import { fail, ok } from '../../shared/result.js';
18
+ import { fail, ok } from 'peaks-loop-shared/result';
19
19
  import { addJsonOption, printResult } from '../cli-helpers.js';
20
20
  export function registerQaBusinessReviewCommands(program, io) {
21
21
  // G5 commands registered as TOP-LEVEL commands prefixed with `qa-business-`
@@ -28,7 +28,7 @@
28
28
  import { Command } from 'commander';
29
29
  import { type ProgramIO } from '../cli-helpers.js';
30
30
  import { type BrowserEvent } from '../../services/qa/browser-restart-detector.js';
31
- import type { MutReportJson } from '../../services/mut/types.js';
31
+ import { type MutReportJson } from 'peaks-loop-mut';
32
32
  export type QaRunOptions = {
33
33
  project: string;
34
34
  browser?: boolean;
@@ -27,7 +27,7 @@
27
27
  */
28
28
  import { join } from 'node:path';
29
29
  import { addJsonOption, printResult } from '../cli-helpers.js';
30
- import { fail, ok } from '../../shared/result.js';
30
+ import { fail, ok } from 'peaks-loop-shared/result';
31
31
  import { BrowserRestartDetector } from '../../services/qa/browser-restart-detector.js';
32
32
  import { BrowserEventLogger } from '../../services/qa/browser-event-logger.js';
33
33
  import { BROWSER_REUSE_HINT } from '../../services/qa/browser-reuse-hint.js';
@@ -36,7 +36,7 @@ import { buildContext } from '../../services/context/context-builder.js';
36
36
  // Plan 1 / Task 10 — production fetcher (replaces mockFetcher).
37
37
  import { createHeadroomFetcher } from '../../services/context/headroom-fetcher.js';
38
38
  // Plan 2 / Task 8 — consume MUT.sig from peaks-mut into verdict envelope.
39
- import { loadMutReport, mutReportPath } from '../../services/mut/index.js';
39
+ import { loadMutReport, mutReportPath } from 'peaks-loop-mut';
40
40
  function buildHeadroomFetcher(sid) {
41
41
  return createHeadroomFetcher({
42
42
  cacheDir: `.peaks/_runtime/${sid}/doc-cache`,
@@ -19,7 +19,7 @@
19
19
  */
20
20
  import { findProjectRoot } from '../../services/config/config-safety.js';
21
21
  import { hotfixRelease, isReleaseStage, planRelease, readReleaseState, rollbackRelease, transitionRelease, watchWindow, writeReleaseState } from '../../services/release/release-state.js';
22
- import { fail, ok } from '../../shared/result.js';
22
+ import { fail, ok } from 'peaks-loop-shared/result';
23
23
  import { addJsonOption, printResult } from '../cli-helpers.js';
24
24
  const CANARY_PERCENTS = {
25
25
  10: 'canary-10',
@@ -4,7 +4,7 @@ import { ConfirmationRequiredError } from '../../services/mode/mode-enforcement.
4
4
  import { recordBypass, isBypassLimitReached, MAX_BYPASSES_PER_SESSION } from '../../services/mode/bypass-tracker.js';
5
5
  import { lintRequestArtifact } from '../../services/artifacts/artifact-lint-service.js';
6
6
  import { getRepairCycleStatus } from '../../services/artifacts/repair-cycle-service.js';
7
- import { fail, ok } from '../../shared/result.js';
7
+ import { fail, ok } from 'peaks-loop-shared/result';
8
8
  import { formatMdCompact } from '../../shared/format-md-compact.js';
9
9
  import { addJsonOption, getErrorMessage, printResult } from '../cli-helpers.js';
10
10
  /**
@@ -5,7 +5,7 @@ import { loadRetrospectiveIndex } from '../../services/retrospective/retrospecti
5
5
  import { showRetrospective } from '../../services/retrospective/retrospective-show.js';
6
6
  import { searchRetrospective } from '../../services/retrospective/retrospective-search-service.js';
7
7
  import { pickFromList } from '../../services/fuzzy-matching/fzf-pick-service.js';
8
- import { fail, ok } from '../../shared/result.js';
8
+ import { fail, ok } from 'peaks-loop-shared/result';
9
9
  import { addJsonOption, getErrorMessage, printResult } from '../cli-helpers.js';
10
10
  const VALID_RETRO_TYPES = ['refactor', 'feature', 'bugfix', 'config', 'docs', 'chore'];
11
11
  const VALID_RETRO_OUTCOMES = ['shipped', 'blocked', 'in-flight', 'cancelled'];
@@ -2,7 +2,7 @@ import { runReviewer, REVIEWER_ID } from '../../services/reviewer/reviewer-servi
2
2
  import { loadReviewerConfig } from '../../services/reviewer/reviewer-config.js';
3
3
  import { deriveModelFamily } from '../../services/reviewer/model-family.js';
4
4
  import { addJsonOption, printResult } from '../cli-helpers.js';
5
- import { fail, ok } from '../../shared/result.js';
5
+ import { fail, ok } from 'peaks-loop-shared/result';
6
6
  export function registerReviewerCommands(program, io) {
7
7
  const reviewer = program
8
8
  .command('reviewer')
@@ -10,7 +10,7 @@
10
10
  */
11
11
  import { findProjectRoot } from '../../services/config/config-safety.js';
12
12
  import { DEFAULT_SENIOR_FE_ROLE, grantPermission, readRoleRegistry, roleHasPermission, upsertRole, writeRoleRegistry } from '../../services/role/role-registry.js';
13
- import { fail, ok } from '../../shared/result.js';
13
+ import { fail, ok } from 'peaks-loop-shared/result';
14
14
  import { addJsonOption, printResult } from '../cli-helpers.js';
15
15
  export function registerRoleCommands(program, io) {
16
16
  const role = program
@@ -1,8 +1,7 @@
1
1
  import { existsSync, mkdirSync } from 'node:fs';
2
2
  import { join, dirname } from 'node:path';
3
3
  import { addJsonOption, printResult } from '../cli-helpers.js';
4
- import { fail, ok } from '../../shared/result.js';
5
- import { getErrorMessage } from '../../shared/result.js';
4
+ import { fail, getErrorMessage, ok } from 'peaks-loop-shared/result';
6
5
  import { detectRuntime } from '../../services/runtime/runtime-detector.js';
7
6
  import { RuntimeService } from '../../services/runtime/runtime-service.js';
8
7
  import { AdapterRegistry } from '../../services/adapter/adapter-registry.js';
@@ -1,5 +1,5 @@
1
1
  import { createArtifactRetentionReport, createChangeImpact, getChangeTraceabilityStatus, getScHelpText, recordCommitBoundary, validateArtifactRetention } from '../../services/sc/sc-service.js';
2
- import { ok } from '../../shared/result.js';
2
+ import { ok } from 'peaks-loop-shared/result';
3
3
  import { addJsonOption, multipleOption, printResult } from '../cli-helpers.js';
4
4
  export function registerSCCommands(program, io) {
5
5
  const sc = program
@@ -10,7 +10,7 @@ import { scanApiSurface, formatApiSurfaceMarkdown } from '../../services/scan/ap
10
10
  import { scanOrphans, formatOrphanMarkdown } from '../../services/scan/orphan-service.js';
11
11
  import { scanKarpathy, formatKarpathyMarkdown } from '../../services/scan/karpathy-service.js';
12
12
  import { isRequestType, VALID_REQUEST_TYPES } from '../../services/artifacts/artifact-prerequisites.js';
13
- import { fail, ok } from '../../shared/result.js';
13
+ import { fail, ok } from 'peaks-loop-shared/result';
14
14
  import { addJsonOption, getErrorMessage, printResult } from '../cli-helpers.js';
15
15
  function parsePositiveInt(value, fallback) {
16
16
  if (value === undefined)
@@ -1,7 +1,7 @@
1
1
  import { readFileSync } from 'node:fs';
2
- import { detectSecurityAudit, isSecurityAuditEnvelope, runSecurityAudit, } from '../../services/audit-independent/security-audit-service.js';
2
+ import { detectSecurityAudit, isSecurityAuditEnvelope, runSecurityAudit, } from 'peaks-loop-audit-independent';
3
3
  import { addJsonOption, getErrorMessage, printResult } from '../cli-helpers.js';
4
- import { fail, ok } from '../../shared/result.js';
4
+ import { fail, ok } from 'peaks-loop-shared/result';
5
5
  function resolveEnvelope(envelopePath) {
6
6
  if (envelopePath === undefined || envelopePath === '-') {
7
7
  // Read from stdin
@@ -15,3 +15,22 @@ import { type ProgramIO } from '../cli-helpers.js';
15
15
  export declare function registerShareCommand(parent: Command, io: ProgramIO): void;
16
16
  export declare function registerSharedReadCommand(parent: Command, io: ProgramIO): void;
17
17
  export declare function registerAwaitCommand(parent: Command, io: ProgramIO): void;
18
+ /**
19
+ * Slice 2026-07-17-D21: peaks sub-agent finalize — LLM-side completion
20
+ * signal. Without this, dispatch records stay queued forever.
21
+ *
22
+ * Contract:
23
+ * - LLM MUST call once per dispatched Task, in post-completion branch.
24
+ * - --all-stale bulk-marks every queued record for this session (crash recovery).
25
+ */
26
+ export interface FinalizeOptions {
27
+ batch?: string;
28
+ requestId?: string;
29
+ outcome?: string;
30
+ error?: string;
31
+ allStale?: boolean;
32
+ project?: string;
33
+ sessionId?: string;
34
+ json?: boolean;
35
+ }
36
+ export declare function registerFinalizeCommand(parent: Command, io: ProgramIO): void;
@@ -1,6 +1,7 @@
1
- import { fail, getErrorMessage, ok } from '../../shared/result.js';
1
+ import { resolve } from 'node:path';
2
+ import { fail, getErrorMessage, ok } from 'peaks-loop-shared/result';
2
3
  import { addJsonOption, printResult } from '../cli-helpers.js';
3
- import { readSharedChannel, writeSharedEntry, SHARED_CHANNEL_SOFT_VALUE_WARN } from '../../services/context/shared-channel.js';
4
+ import { readSharedChannel, writeSharedEntry, SHARED_CHANNEL_SOFT_VALUE_WARN } from 'peaks-loop-shared-channel';
4
5
  import { writeLogEntry } from '../../services/log/logger.js';
5
6
  import { getCurrentSessionId } from '../../services/skills/skill-presence-service.js';
6
7
  import { summarizeBatchResults } from './sub-agent-shared.js';
@@ -294,3 +295,121 @@ function awaitErrorNextActions(code) {
294
295
  }
295
296
  return 'See error message; check that --batch matches the dispatch envelope and --timeout is a positive integer ms.';
296
297
  }
298
+ export function registerFinalizeCommand(parent, io) {
299
+ addJsonOption(parent
300
+ .command('finalize')
301
+ .description('D21: signal that a dispatched sub-agent has finished (success/failure/cancellation). Pass --all-stale for crash-recovery sweep.')
302
+ .option('--batch <batchId>', 'batchId from dispatch envelope')
303
+ .option('--request-id <rid>', 'requestId from dispatch envelope')
304
+ .option('--outcome <state>', 'done | failed | cancelled (default: done)')
305
+ .option('--error <msg>', 'error message (when --outcome=failed)')
306
+ .option('--all-stale', 'bulk-mark every queued record for this session as done')
307
+ .option('--project <path>', 'target project root (defaults to cwd)')
308
+ .option('--session-id <sid>', 'override active session id')).action((options) => {
309
+ void (async () => {
310
+ const asJson = options.json === true;
311
+ try {
312
+ const projectRoot = resolve(options.project ?? process.cwd());
313
+ const sessionId = options.sessionId ?? getCurrentSessionId(projectRoot) ?? 'unknown-sid';
314
+ if (!options.allStale && !options.requestId && !options.batch) {
315
+ printResult(io, fail('sub-agent.finalize', 'MISSING_TARGET', 'Pass --request-id or --batch (or --all-stale)', { ok: false }, ['Call finalize after each Task completes.']), asJson);
316
+ process.exitCode = 1;
317
+ return;
318
+ }
319
+ const outcome = (options.outcome ?? 'done');
320
+ const writerMod = await import('../../services/dispatch/dispatch-record-writer.js');
321
+ const { readRecord, markCompleted, readActiveDispatchIndex } = writerMod;
322
+ // map outcome -> (status, outcome)
323
+ const outcomeMap = {
324
+ done: { status: 'done', outcome: 'success' },
325
+ failed: { status: 'failed', outcome: 'failed' },
326
+ cancelled: { status: 'cancelled', outcome: 'cancelled' },
327
+ };
328
+ const mapped = outcomeMap[outcome] ?? outcomeMap['done'];
329
+ const finalized = [];
330
+ const skipped = [];
331
+ const errors = [];
332
+ const applyOutcome = (recordPath, rid) => {
333
+ markCompleted({ recordPath, now: () => new Date(), status: mapped.status, outcome: mapped.outcome, projectRoot });
334
+ finalized.push({ recordPath, requestId: rid, status: mapped.status });
335
+ };
336
+ if (options.allStale) {
337
+ const index = readActiveDispatchIndex(projectRoot, sessionId);
338
+ for (const [recordPath, entry] of Object.entries(index)) {
339
+ if (entry.status !== 'queued') {
340
+ skipped.push({ recordPath, reason: 'status is ' + entry.status });
341
+ continue;
342
+ }
343
+ try {
344
+ applyOutcome(recordPath, entry.requestId);
345
+ }
346
+ catch (e) {
347
+ errors.push({ recordPath, error: getErrorMessage(e) });
348
+ }
349
+ }
350
+ }
351
+ else if (options.requestId) {
352
+ const fs2 = await import('node:fs');
353
+ const path2 = await import('node:path');
354
+ const dir = path2.resolve(projectRoot, '.peaks', '_sub_agents', sessionId);
355
+ let resolvedPath = null;
356
+ if (fs2.existsSync(dir)) {
357
+ for (const f of fs2.readdirSync(dir)) {
358
+ if (!f.endsWith('.json'))
359
+ continue;
360
+ const p = path2.join(dir, f);
361
+ const r = readRecord(p);
362
+ if (r.requestId === options.requestId) {
363
+ resolvedPath = p;
364
+ break;
365
+ }
366
+ }
367
+ }
368
+ if (!resolvedPath) {
369
+ printResult(io, fail('sub-agent.finalize', 'RECORD_NOT_FOUND', 'No dispatch record for requestId=' + options.requestId, { ok: false }, ['Check --request-id matches the dispatch envelope.']), asJson);
370
+ process.exitCode = 1;
371
+ return;
372
+ }
373
+ try {
374
+ applyOutcome(resolvedPath, options.requestId);
375
+ }
376
+ catch (e) {
377
+ errors.push({ recordPath: resolvedPath, error: getErrorMessage(e) });
378
+ }
379
+ }
380
+ else {
381
+ const fs2 = await import('node:fs');
382
+ const path2 = await import('node:path');
383
+ const dir = path2.resolve(projectRoot, '.peaks', '_sub_agents', sessionId);
384
+ if (fs2.existsSync(dir)) {
385
+ for (const f of fs2.readdirSync(dir)) {
386
+ if (!f.startsWith('dispatch-') || !f.endsWith('.json'))
387
+ continue;
388
+ const p = path2.join(dir, f);
389
+ const r = readRecord(p);
390
+ if (r.batchId !== options.batch)
391
+ continue;
392
+ if (r.status !== 'queued') {
393
+ skipped.push({ recordPath: p, reason: 'status is ' + r.status });
394
+ continue;
395
+ }
396
+ try {
397
+ applyOutcome(p, r.requestId);
398
+ }
399
+ catch (e) {
400
+ errors.push({ recordPath: p, error: getErrorMessage(e) });
401
+ }
402
+ }
403
+ }
404
+ }
405
+ printResult(io, ok('sub-agent.finalize', { finalized, skipped, errors, sessionId, outcome }, errors.length > 0 ? [errors.length + ' failed'] : [], errors.length > 0 ? ['Re-run after fixing.'] : ['All targeted records transitioned out of queued.']), asJson);
406
+ if (errors.length > 0)
407
+ process.exitCode = 1;
408
+ }
409
+ catch (error) {
410
+ printResult(io, fail('sub-agent.finalize', 'FINALIZE_ERROR', getErrorMessage(error), { ok: false }, ['Inspect the error.']), asJson);
411
+ process.exitCode = 1;
412
+ }
413
+ })();
414
+ });
415
+ }
@@ -6,7 +6,7 @@
6
6
  */
7
7
  import { auditSkillConformance } from '../../services/skills/skill-conformance-service.js';
8
8
  import { getErrorMessage, printResult } from '../cli-helpers.js';
9
- import { fail, ok } from '../../shared/result.js';
9
+ import { fail, ok } from 'peaks-loop-shared/result';
10
10
  export function registerSkillConformanceCommands(program, io) {
11
11
  program
12
12
  .command('skills:audit-conformance')
@@ -36,7 +36,7 @@ import { readFileSync, existsSync, statSync } from 'node:fs';
36
36
  import { join, resolve } from 'node:path';
37
37
  import { lintSkillLoopEngineeringReadiness, } from '../../services/standards/loop-engineering-readiness-lint.js';
38
38
  import { addJsonOption, getErrorMessage, printResult } from '../cli-helpers.js';
39
- import { fail, ok } from '../../shared/result.js';
39
+ import { fail, ok } from 'peaks-loop-shared/result';
40
40
  export const LOOP_ENGINEERING_READINESS_CATEGORY = 'loop-engineering-readiness';
41
41
  /**
42
42
  * Resolve the SKILL.md file path from a `--path <skill-dir>` value.
@@ -1,5 +1,5 @@
1
1
  import { searchSkills, SkillSearchInputSchema } from '../../services/skill/skill-search-service.js';
2
- import { getErrorMessage } from '../../shared/result.js';
2
+ import { getErrorMessage } from 'peaks-loop-shared/result';
3
3
  /**
4
4
  * Validate the raw CLI flags, call the service, and emit a JSON
5
5
  * envelope on stdout. Errors flow through stderr + non-zero exit
@@ -7,7 +7,7 @@ import { decomposeSlicesWithBenchmark } from '../../services/slice/slice-benchma
7
7
  import { pickSlicesInteractive } from '../../services/slice/slice-pick-service.js';
8
8
  import { decompose as multiPassDecompose } from '../../services/slice/multi-pass-orchestrator.js';
9
9
  import { readResult as readDecompositionResult, writeResult as writeSchemaResult } from '../../services/slice/schema-router.js';
10
- import { fail, ok } from '../../shared/result.js';
10
+ import { fail, ok } from 'peaks-loop-shared/result';
11
11
  import { addJsonOption, getErrorMessage, printResult } from '../cli-helpers.js';
12
12
  export function registerSliceCommands(program, io) {
13
13
  const slice = program.command('slice').description('Slice lifecycle: check (boundary), decompose (PRD -> 6-stage algorithm), ' +
@@ -10,7 +10,7 @@ import { existsSync, readFileSync } from 'node:fs';
10
10
  import { join, resolve } from 'node:path';
11
11
  import { getCurrentSessionId } from '../../services/skills/skill-presence-service.js';
12
12
  import { integrateSlices } from '../../services/slice/slice-integration.js';
13
- import { fail, ok } from '../../shared/result.js';
13
+ import { fail, ok } from 'peaks-loop-shared/result';
14
14
  import { addJsonOption, printResult } from '../cli-helpers.js';
15
15
  function loadContractsForSlices(projectRoot, sessionId, sliceIds) {
16
16
  const dir = resolve(projectRoot, '.peaks', '_runtime', sessionId, 'dispatch', 'contracts');
@@ -21,7 +21,7 @@
21
21
  import { findProjectRoot } from '../../services/config/config-safety.js';
22
22
  import { getCurrentSessionId } from '../../services/skills/skill-presence-service.js';
23
23
  import { acceptReview, buildEmptySliceReview, DEFAULT_REVIEW_ITEMS, deriveDecision, readSliceReview, rejectReview, renderChecklist, scoreItem, writeSliceReview } from '../../services/slice/slice-review-state.js';
24
- import { fail, ok } from '../../shared/result.js';
24
+ import { fail, ok } from 'peaks-loop-shared/result';
25
25
  import { addJsonOption, printResult } from '../cli-helpers.js';
26
26
  export function registerSliceReviewCommands(program, io) {
27
27
  // G1 commands registered as TOP-LEVEL commands prefixed with `slice-review-`
@@ -18,7 +18,7 @@ import { readFileSync } from 'node:fs';
18
18
  import { resolve as resolvePath } from 'node:path';
19
19
  import { findProjectRoot } from '../../services/config/config-safety.js';
20
20
  import { addCriticalPath, CRITICAL_PATH_SOURCES, EMPTY_SMOKE_STATE, isCriticalPathSource, makeCriticalPathId, readSmokeState, recordRun, summarizeState, writeSmokeState } from '../../services/smoke/smoke-paths-state.js';
21
- import { fail, ok } from '../../shared/result.js';
21
+ import { fail, ok } from 'peaks-loop-shared/result';
22
22
  import { addJsonOption, printResult } from '../cli-helpers.js';
23
23
  const RUN_STATUSES = ['pending', 'pass', 'fail'];
24
24
  export function registerSmokeCommands(program, io) {
@@ -6,7 +6,7 @@ import { advanceSop, SopAdvanceError, SopGateBlockedError, SopPhaseSkipError } f
6
6
  import { sopStateDir } from '../../services/sop/sop-paths.js';
7
7
  import { getSkillPresence } from '../../services/skills/skill-presence-service.js';
8
8
  import { recordBypass, isBypassLimitReached, MAX_BYPASSES_PER_SESSION } from '../../services/mode/bypass-tracker.js';
9
- import { fail, ok } from '../../shared/result.js';
9
+ import { fail, ok } from 'peaks-loop-shared/result';
10
10
  import { addJsonOption, getErrorMessage, printResult } from '../cli-helpers.js';
11
11
  export function registerSopCommands(program, io) {
12
12
  const sop = program.command('sop').description('Author and validate user-defined SOP skills');
@@ -1,4 +1,4 @@
1
- import { fail, ok } from '../../shared/result.js';
1
+ import { fail, ok } from 'peaks-loop-shared/result';
2
2
  import { addJsonOption, printResult, getErrorMessage } from '../cli-helpers.js';
3
3
  import { findProjectRoot } from '../../services/config/config-safety.js';
4
4
  import { buildStatusLineModel, parseStatusLineStdin } from '../../services/skills/skill-statusline-service.js';