peaks-loop 4.0.16 → 4.0.18

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 (80) hide show
  1. package/CHANGELOG.md +55 -0
  2. package/README-en.md +12 -9
  3. package/README.md +15 -4
  4. package/config/eslint/.peaks-rules.cjs +39 -26
  5. package/dist/cli/commands/_register.js +2 -1
  6. package/dist/cli/commands/audit-commands.d.ts +1 -1
  7. package/dist/cli/commands/code-gate-command.d.ts +25 -0
  8. package/dist/cli/commands/code-gate-command.js +86 -0
  9. package/dist/cli/commands/code-mode-gate-commands.js +3 -4
  10. package/dist/cli/commands/code-orchestrator-can-do.js +2 -1
  11. package/dist/cli/commands/cron-commands.js +16 -4
  12. package/dist/cli/commands/dashboard-long-run.js +8 -4
  13. package/dist/cli/commands/dispatch-from-dag.d.ts +1 -1
  14. package/dist/cli/commands/hooks-commands.js +56 -3
  15. package/dist/cli/commands/primer-command.d.ts +59 -0
  16. package/dist/cli/commands/primer-command.js +160 -0
  17. package/dist/cli/commands/qa-commands.js +1 -2
  18. package/dist/cli/commands/sediment-commands.d.ts +1 -1
  19. package/dist/cli/commands/slice-commands.js +20 -8
  20. package/dist/cli/commands/statusline-commands.d.ts +1 -0
  21. package/dist/cli/commands/statusline-commands.js +17 -3
  22. package/dist/cli/commands/tech-commands.d.ts +1 -1
  23. package/dist/cli/program.js +8 -0
  24. package/dist/services/artifacts/request-artifact-service.d.ts +2 -2
  25. package/dist/services/artifacts/request-artifact-service.js +10 -1
  26. package/dist/services/audit/enforcers/lint-reference-shape.js +18 -4
  27. package/dist/services/code/auto-compact-orchestrator.js +9 -1
  28. package/dist/services/code/batch-heartbeat-poller.js +26 -0
  29. package/dist/services/code/orchestrator-can-do.d.ts +24 -0
  30. package/dist/services/code/orchestrator-can-do.js +48 -2
  31. package/dist/services/code/post-compact-detector.d.ts +1 -1
  32. package/dist/services/compact-statusline/compact-statusline-service.js +19 -11
  33. package/dist/services/config/config-safety.d.ts +23 -0
  34. package/dist/services/config/config-safety.js +62 -0
  35. package/dist/services/config/config-service.d.ts +1 -1
  36. package/dist/services/config/config-service.js +2 -4
  37. package/dist/services/container/container-lease.js +21 -8
  38. package/dist/services/context/spillover-store.d.ts +1 -1
  39. package/dist/services/crystallization/crystallization-types.js +20 -8
  40. package/dist/services/crystallization/evidence-brief-builder.js +22 -11
  41. package/dist/services/dispatch/dispatch-record-writer.js +231 -141
  42. package/dist/services/evolution/evolution-types.js +38 -21
  43. package/dist/services/feedback/feedback-promotion-service.js +9 -1
  44. package/dist/services/hooks/pre-tool-code-gate.d.ts +46 -0
  45. package/dist/services/hooks/pre-tool-code-gate.js +91 -0
  46. package/dist/services/ide/current-model-detector.js +1 -2
  47. package/dist/services/lint/detect-eslint.js +8 -5
  48. package/dist/services/lint/eslint-runner.d.ts +1 -2
  49. package/dist/services/lint/eslint-runner.js +86 -23
  50. package/dist/services/lint/npx-resolver.d.ts +6 -0
  51. package/dist/services/lint/npx-resolver.js +47 -0
  52. package/dist/services/loop/loop-release-types.js +32 -13
  53. package/dist/services/loop/spec-service.d.ts +7 -1
  54. package/dist/services/loop/spec-service.js +218 -182
  55. package/dist/services/rd/rd-service.js +22 -9
  56. package/dist/services/scan/archetype-service.js +21 -9
  57. package/dist/services/session/binding-store.js +1 -2
  58. package/dist/services/share/bundle-reader.d.ts +6 -9
  59. package/dist/services/share/bundle-reader.js +297 -223
  60. package/dist/services/skills/hooks-settings-service.d.ts +33 -0
  61. package/dist/services/skills/hooks-settings-service.js +48 -3
  62. package/dist/services/skills/{outer-cache-hook-constants.d.ts → session-start-hook-constants.d.ts} +20 -0
  63. package/dist/services/skills/{outer-cache-hook-constants.js → session-start-hook-constants.js} +20 -0
  64. package/dist/services/skills/skill-statusline-renderer.d.ts +50 -1
  65. package/dist/services/skills/skill-statusline-renderer.js +96 -8
  66. package/dist/services/skills/skill-statusline-service.d.ts +41 -0
  67. package/dist/services/skills/skill-statusline-service.js +56 -6
  68. package/dist/services/slice/calibration-store.js +21 -8
  69. package/dist/services/slice/slice-check-service.js +35 -14
  70. package/dist/services/slice/slice-decompose-service.js +459 -223
  71. package/dist/services/standards/project-context.js +135 -73
  72. package/dist/services/verdict/envelopes.d.ts +1 -2
  73. package/dist/services/verdict/envelopes.js +1 -2
  74. package/dist/services/verdict/verdict-aggregator.d.ts +1 -2
  75. package/dist/services/vm/vm-lease.js +19 -8
  76. package/dist/services/worktree/worktree-lease.d.ts +0 -10
  77. package/dist/services/worktree/worktree-lease.js +19 -8
  78. package/dist/shared/fs-utils.d.ts +1 -1
  79. package/package.json +7 -4
  80. package/skills/peaks-code/SKILL.md +46 -0
@@ -10,6 +10,23 @@ import { isDirectory } from 'peaks-loop-shared/fs';
10
10
  import { verifyPipeline } from '../workflow/pipeline-verify-service.js';
11
11
  import { findMockViolations } from '../audit/enforcers/mock-placement.js';
12
12
  import { runRedLinesAudit } from '../audit/red-lines-service.js';
13
+ /**
14
+ * PRD-002b slice 2 — extract timeouts + budget constants for the
15
+ * slice-check pipeline (typecheck / unit-tests / git diff / fixture
16
+ * staging thresholds). Values are bytewise-identical to the original
17
+ * literals.
18
+ */
19
+ const TYPECHECK_TIMEOUT_MS = 180_000;
20
+ const UNIT_TESTS_TIMEOUT_MS = 600_000;
21
+ const GIT_DIFF_TIMEOUT_MS = 30_000;
22
+ const BYTES_PER_KB = 1024;
23
+ const BYTES_PER_MB = BYTES_PER_KB * BYTES_PER_KB;
24
+ const EXEC_MAX_BUFFER_BYTES = 32 * BYTES_PER_MB;
25
+ const TYPECHECK_TAIL_LINES = 10;
26
+ const UNIT_TEST_TAIL_LINES = 12;
27
+ const HEAD_LINES_IN_TAIL = 3;
28
+ const AUDIT_MIN_RED_LINES = 60;
29
+ const REVIEW_FILE_MIN_BYTES = 20;
13
30
  /**
14
31
  * Resolve a CLI binary to a project-local path, falling back to
15
32
  * the system `npx`. pnpm (and npm/yarn) all create
@@ -52,7 +69,7 @@ function runCommand(command, args, cwd, timeoutMs, shell = false) {
52
69
  cwd,
53
70
  stdio: ['ignore', 'pipe', 'pipe'],
54
71
  timeout: timeoutMs,
55
- maxBuffer: 32 * 1024 * 1024,
72
+ maxBuffer: EXEC_MAX_BUFFER_BYTES,
56
73
  shell
57
74
  }).toString('utf8');
58
75
  return {
@@ -64,13 +81,17 @@ function runCommand(command, args, cwd, timeoutMs, shell = false) {
64
81
  };
65
82
  }
66
83
  catch (error) {
67
- const stdout = (error?.stdout ?? '').toString('utf8');
68
- const stderr = (error?.stderr ?? '').toString('utf8');
84
+ // execFileSync throws `Error & { stdout, stderr, status }` on
85
+ // non-zero exit (Node child_process typings). We narrow inline to
86
+ // preserve the existing optional-chain fallback for non-Error throws.
87
+ const e = error;
88
+ const stdout = (e.stdout ?? '').toString('utf8');
89
+ const stderr = (e.stderr ?? '').toString('utf8');
69
90
  return {
70
91
  status: 'fail',
71
92
  stdout,
72
93
  stderr,
73
- exitCode: typeof error?.status === 'number' ? error.status : 1,
94
+ exitCode: typeof e.status === 'number' ? e.status : 1,
74
95
  durationMs: Date.now() - start
75
96
  };
76
97
  }
@@ -79,7 +100,7 @@ function tailLines(text, max) {
79
100
  const lines = text.split('\n').filter((l) => l.trim().length > 0);
80
101
  if (lines.length <= max)
81
102
  return lines.join('\n');
82
- return [...lines.slice(0, 3), `... (${lines.length - max} more lines) ...`, ...lines.slice(-max + 3)].join('\n');
103
+ return [...lines.slice(0, HEAD_LINES_IN_TAIL), `... (${lines.length - max} more lines) ...`, ...lines.slice(-max + HEAD_LINES_IN_TAIL)].join('\n');
83
104
  }
84
105
  async function runTypecheck(projectRoot) {
85
106
  const start = Date.now();
@@ -89,7 +110,7 @@ async function runTypecheck(projectRoot) {
89
110
  // installed by pnpm at workspace-install time and avoids the
90
111
  // npx PATH-lookup issue.
91
112
  const tsc = resolveLocalBinary(projectRoot, 'tsc');
92
- const result = runCommand(tsc.command, [...tsc.args, '--noEmit'], projectRoot, 180_000, tsc.shell);
113
+ const result = runCommand(tsc.command, [...tsc.args, '--noEmit'], projectRoot, TYPECHECK_TIMEOUT_MS, tsc.shell);
93
114
  const testFiles = result.stdout.match(/(tests?\/.*\.test\.ts)/g) ?? [];
94
115
  return {
95
116
  name: 'typecheck',
@@ -98,7 +119,7 @@ async function runTypecheck(projectRoot) {
98
119
  durationMs: result.durationMs,
99
120
  detail: result.status === 'pass'
100
121
  ? `Typecheck passed in ${result.durationMs}ms.`
101
- : tailLines(result.stdout + result.stderr, 10) || `tsc exited with code ${result.exitCode}.`,
122
+ : tailLines(result.stdout + result.stderr, TYPECHECK_TAIL_LINES) || `tsc exited with code ${result.exitCode}.`,
102
123
  data: { exitCode: result.exitCode }
103
124
  };
104
125
  }
@@ -134,7 +155,7 @@ async function runUnitTests(projectRoot, runTests) {
134
155
  const description = runTests
135
156
  ? `${vitest.command} run (full test suite, coverage off)`
136
157
  : `${vitest.command} run --changed (tests for git-changed files only, coverage off)`;
137
- const result = runCommand(vitest.command, [...vitest.args, ...vitestArgs], projectRoot, 600_000, vitest.shell);
158
+ const result = runCommand(vitest.command, [...vitest.args, ...vitestArgs], projectRoot, UNIT_TESTS_TIMEOUT_MS, vitest.shell);
138
159
  const summary = parseVitestSummary(result.stdout, result.durationMs);
139
160
  // Vitest doesn't always print the per-bucket counts cleanly; infer "passed"
140
161
  // as total - failed - skipped when failed/skipped buckets are present.
@@ -146,7 +167,7 @@ async function runUnitTests(projectRoot, runTests) {
146
167
  durationMs: result.durationMs,
147
168
  detail: result.status === 'pass'
148
169
  ? `All tests passed in ${result.durationMs}ms.`
149
- : tailLines(result.stdout + result.stderr, 12) || `vitest exited with code ${result.exitCode}.`,
170
+ : tailLines(result.stdout + result.stderr, UNIT_TEST_TAIL_LINES) || `vitest exited with code ${result.exitCode}.`,
150
171
  data: {
151
172
  tests: summary.tests,
152
173
  passed,
@@ -212,7 +233,7 @@ async function runReviewFanout(projectRoot, rid, refresh) {
212
233
  const abs = join(projectRoot, '.peaks', scope, candidate);
213
234
  if (existsSync(abs)) {
214
235
  const bytes = statSync(abs).size;
215
- if (bytes >= 20) {
236
+ if (bytes >= REVIEW_FILE_MIN_BYTES) {
216
237
  hit = { abs, scope, bytes };
217
238
  break;
218
239
  }
@@ -268,7 +289,7 @@ async function runGateVerifyPipeline(projectRoot, rid, sessionId) {
268
289
  description: 'peaks workflow verify-pipeline (RD/QA gate checks against .peaks/_runtime/change/<sessionId>/)',
269
290
  status: 'fail',
270
291
  durationMs: Date.now() - start,
271
- detail: error?.message ?? 'verify-pipeline threw',
292
+ detail: error instanceof Error ? error.message : 'verify-pipeline threw',
272
293
  data: {}
273
294
  };
274
295
  }
@@ -372,7 +393,7 @@ async function runAuditRegression(projectRoot) {
372
393
  // - totalRedLines >= 60 (catalog grew to 66; pins the lower bound)
373
394
  // - enforcerFindings has no rl-audit-no-orphan-enforcer / rl-audit-no-orphan-catalog hits
374
395
  const issues = [];
375
- if (result.audit.totalRedLines < 60) {
396
+ if (result.audit.totalRedLines < AUDIT_MIN_RED_LINES) {
376
397
  issues.push(`totalRedLines ${result.audit.totalRedLines} < 60`);
377
398
  }
378
399
  const orphanFindings = result.audit.enforcerFindings.filter((f) => f.enforcerId === 'rl-audit-no-orphan-enforcer-001' ||
@@ -403,7 +424,7 @@ async function runAuditRegression(projectRoot) {
403
424
  description: 'audit-regression: catalog integrity + runtime budget (L2.4 P2-b stage 6)',
404
425
  status: 'fail',
405
426
  durationMs: Date.now() - start,
406
- detail: 'audit-regression failed: ' + (error?.message ?? String(error)),
427
+ detail: 'audit-regression failed: ' + (error instanceof Error ? error.message : String(error)),
407
428
  };
408
429
  }
409
430
  }
@@ -411,7 +432,7 @@ async function runMockPlacement(projectRoot) {
411
432
  const start = Date.now();
412
433
  // List changed files via git. `--name-only` produces one path per line;
413
434
  // we filter to text files in scope and read each.
414
- const diffResult = runCommand('git', ['diff', '--name-only', '--diff-filter=ACMR', 'HEAD'], projectRoot, 30_000);
435
+ const diffResult = runCommand('git', ['diff', '--name-only', '--diff-filter=ACMR', 'HEAD'], projectRoot, GIT_DIFF_TIMEOUT_MS);
415
436
  if (diffResult.status !== 'pass') {
416
437
  return {
417
438
  name: 'mock-placement',