@planu/cli 5.5.3 → 5.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 (118) hide show
  1. package/CHANGELOG.md +58 -0
  2. package/dist/.planu-build.json +1 -1
  3. package/dist/cli/commands/telemetry.d.ts +3 -0
  4. package/dist/cli/commands/telemetry.js +118 -0
  5. package/dist/cli/router.js +3 -1
  6. package/dist/config/environment-schema.json +14 -0
  7. package/dist/engine/autopilot/bootstrap.js +1 -1
  8. package/dist/engine/cascade-hooks/core/append-releases.js +22 -12
  9. package/dist/engine/contradiction-detector.d.ts +2 -1
  10. package/dist/engine/contradiction-detector.js +215 -0
  11. package/dist/engine/detection-utils.d.ts +1 -0
  12. package/dist/engine/detection-utils.js +33 -0
  13. package/dist/engine/doc-generator/portal/index.d.ts +1 -1
  14. package/dist/engine/doc-generator/portal/index.js +1 -1
  15. package/dist/engine/doc-generator/portal/portal-regenerator.d.ts +8 -3
  16. package/dist/engine/doc-generator/portal/portal-regenerator.js +16 -7
  17. package/dist/engine/evidence-gates/evidence-autofill.d.ts +1 -1
  18. package/dist/engine/evidence-gates/evidence-autofill.js +1 -1
  19. package/dist/engine/framework-detector.js +8 -6
  20. package/dist/engine/handoff-artifacts/schemas.js +4 -0
  21. package/dist/engine/housekeeping/history-log.d.ts +1 -0
  22. package/dist/engine/housekeeping/history-log.js +58 -3
  23. package/dist/engine/housekeeping/index.d.ts +2 -1
  24. package/dist/engine/housekeeping/index.js +2 -1
  25. package/dist/engine/housekeeping/legacy-planu-demolisher.d.ts +3 -0
  26. package/dist/engine/housekeeping/legacy-planu-demolisher.js +164 -0
  27. package/dist/engine/housekeeping/runtime-residue-sweep.d.ts +9 -0
  28. package/dist/engine/housekeeping/runtime-residue-sweep.js +57 -0
  29. package/dist/engine/lifecycle-reconciliation.js +87 -40
  30. package/dist/engine/next-spec-resolver/orchestration-planner.js +1 -1
  31. package/dist/engine/next-spec-resolver/session-writer.js +1 -1
  32. package/dist/engine/project-graph/cache.js +23 -3
  33. package/dist/engine/readiness-checker.js +14 -2
  34. package/dist/engine/sdd-flow/checkpoints.js +29 -2
  35. package/dist/engine/session/checkpoint-writer.d.ts +1 -1
  36. package/dist/engine/session/checkpoint-writer.js +6 -5
  37. package/dist/engine/session-state/writer.js +4 -3
  38. package/dist/engine/spec-format/lean-spec-generator.js +1 -1
  39. package/dist/engine/spec-migrator/planu-canonical-policy.d.ts +8 -1
  40. package/dist/engine/spec-migrator/planu-canonical-policy.js +14 -13
  41. package/dist/engine/spec-migrator/strict-planu-cleanup.js +28 -3
  42. package/dist/engine/telemetry/error-reporter.d.ts +9 -9
  43. package/dist/engine/telemetry/error-reporter.js +15 -34
  44. package/dist/engine/telemetry/event-envelope.d.ts +11 -0
  45. package/dist/engine/telemetry/event-envelope.js +124 -0
  46. package/dist/engine/telemetry/telemetry-client.d.ts +8 -1
  47. package/dist/engine/telemetry/telemetry-client.js +38 -20
  48. package/dist/engine/telemetry/telemetry-store.d.ts +15 -2
  49. package/dist/engine/telemetry/telemetry-store.js +73 -2
  50. package/dist/engine/universal-rules/rules/planu-release-policy.js +1 -1
  51. package/dist/engine/validator/spec-compliance-runner.d.ts +2 -1
  52. package/dist/engine/validator/spec-compliance-runner.js +123 -1
  53. package/dist/hosts/claude-code/ux/mcp-resources.js +7 -23
  54. package/dist/index.js +26 -0
  55. package/dist/resources/specs.js +12 -33
  56. package/dist/storage/current-project.d.ts +3 -0
  57. package/dist/storage/current-project.js +21 -0
  58. package/dist/storage/index.d.ts +1 -0
  59. package/dist/storage/index.js +1 -0
  60. package/dist/storage/migrations/canonical-storage.js +5 -0
  61. package/dist/storage/retention.d.ts +14 -0
  62. package/dist/storage/retention.js +279 -0
  63. package/dist/storage/spec-index.d.ts +23 -0
  64. package/dist/storage/spec-index.js +123 -0
  65. package/dist/storage/spec-store.d.ts +8 -3
  66. package/dist/storage/spec-store.js +76 -6
  67. package/dist/storage/storage-catalog.js +3 -3
  68. package/dist/storage/storage-layout.d.ts +8 -0
  69. package/dist/storage/storage-layout.js +9 -0
  70. package/dist/storage/transition-log.js +2 -0
  71. package/dist/tools/challenge-spec.js +35 -19
  72. package/dist/tools/create-spec.js +10 -0
  73. package/dist/tools/execute-sdd-flow.js +11 -2
  74. package/dist/tools/export-spec.js +2 -1
  75. package/dist/tools/force-status-analytics.js +2 -1
  76. package/dist/tools/generate-docs-site.js +2 -1
  77. package/dist/tools/generate-proposal.js +6 -2
  78. package/dist/tools/init-project/claude-md-generator.js +19 -2
  79. package/dist/tools/init-project/conventions-writer.d.ts +5 -2
  80. package/dist/tools/init-project/conventions-writer.js +18 -13
  81. package/dist/tools/init-project/git-setup.js +9 -0
  82. package/dist/tools/init-project/handler.js +9 -1
  83. package/dist/tools/init-project/legacy-planu.d.ts +2 -0
  84. package/dist/tools/init-project/legacy-planu.js +18 -0
  85. package/dist/tools/init-project/legacy-root-migration.d.ts +15 -0
  86. package/dist/tools/init-project/legacy-root-migration.js +213 -0
  87. package/dist/tools/init-project/runtime-residue.d.ts +2 -0
  88. package/dist/tools/init-project/runtime-residue.js +11 -0
  89. package/dist/tools/init-project/schedule-housekeeping.d.ts +2 -0
  90. package/dist/tools/init-project/schedule-housekeeping.js +8 -0
  91. package/dist/tools/reconcile-spec.js +29 -2
  92. package/dist/tools/register-spec-tools/analysis-tools.d.ts +7 -0
  93. package/dist/tools/register-spec-tools/analysis-tools.js +13 -1
  94. package/dist/tools/safe-handler.js +6 -12
  95. package/dist/tools/session-checkpoint.js +1 -1
  96. package/dist/tools/update-status/index.js +7 -1
  97. package/dist/tools/update-status-actions.d.ts +7 -1
  98. package/dist/tools/update-status-actions.js +10 -2
  99. package/dist/types/handoff-artifacts.d.ts +1 -0
  100. package/dist/types/housekeeping.d.ts +38 -0
  101. package/dist/types/housekeeping.js +0 -1
  102. package/dist/types/index.d.ts +1 -0
  103. package/dist/types/index.js +1 -0
  104. package/dist/types/retention.d.ts +12 -0
  105. package/dist/types/retention.js +3 -0
  106. package/dist/types/scope.d.ts +23 -0
  107. package/dist/types/spec/core.d.ts +7 -0
  108. package/dist/types/spec/index-cache.d.ts +25 -0
  109. package/dist/types/spec/index-cache.js +3 -0
  110. package/dist/types/spec/index.d.ts +1 -0
  111. package/dist/types/spec/index.js +1 -0
  112. package/dist/types/spec/inputs.d.ts +9 -0
  113. package/dist/types/spec-format.d.ts +1 -0
  114. package/dist/types/telemetry.d.ts +39 -1
  115. package/dist/types/validation-evidence.d.ts +6 -0
  116. package/package.json +1 -1
  117. package/planu-plugin.json +1 -1
  118. package/scripts/lib/pending-release-file.mjs +20 -4
@@ -6,4 +6,5 @@ export * from './agent.js';
6
6
  export * from './repair.js';
7
7
  export * from './health-score.js';
8
8
  export * from './versioning.js';
9
+ export * from './index-cache.js';
9
10
  //# sourceMappingURL=index.d.ts.map
@@ -8,4 +8,5 @@ export * from './agent.js';
8
8
  export * from './repair.js';
9
9
  export * from './health-score.js';
10
10
  export * from './versioning.js';
11
+ export * from './index-cache.js';
11
12
  //# sourceMappingURL=index.js.map
@@ -109,6 +109,8 @@ export interface UpdateStatusInput {
109
109
  * When true, the transition proceeds and qualityWarnings[] is written to spec.md frontmatter.
110
110
  */
111
111
  forceApprove?: boolean;
112
+ /** Marker set by reconcile_spec's declared-drift route; accepts the declared reason as reconciliation evidence in place of validation-report.json. */
113
+ declaredDriftKind?: 'architectural-premise';
112
114
  }
113
115
  /**
114
116
  * SPEC-769: Output from the readiness gate check in update_status(approved).
@@ -159,12 +161,19 @@ export interface GenerateChecklistInput {
159
161
  focus?: ChecklistCategory[];
160
162
  experienceLevel?: 'beginner' | 'expert';
161
163
  }
164
+ /** An orchestrator-declared drift that produces no auto-detectable file/scope change. */
165
+ export interface DeclaredSpecDrift {
166
+ kind: 'architectural-premise';
167
+ /** Why the implementation drifted from the approved premise. Minimum 100 characters. */
168
+ reason: string;
169
+ }
162
170
  export interface ReconcileSpecInput {
163
171
  specId: string;
164
172
  projectId: string;
165
173
  autoDetect?: boolean;
166
174
  livingSpec?: boolean;
167
175
  changes?: ReconcileChange[];
176
+ declaredDrift?: DeclaredSpecDrift;
168
177
  }
169
178
  export interface ClarifyRequirementsInput {
170
179
  projectId: string;
@@ -72,6 +72,7 @@ export interface PlanuCanonicalPathPolicy {
72
72
  readonly canonicalSpecFiles: readonly string[];
73
73
  readonly canonicalSpecDirs: readonly string[];
74
74
  readonly forbiddenHostAssetRootDirs: readonly string[];
75
+ readonly runtimeHomeDir: string;
75
76
  readonly generatedRuntimePatterns: readonly string[];
76
77
  readonly legacyMergeBeforeDeleteFiles: readonly string[];
77
78
  }
@@ -4,11 +4,47 @@ export interface GeoData {
4
4
  city: string;
5
5
  timezone: string;
6
6
  }
7
+ /** SPEC-1704: the six allowlisted schemaVersion-1 envelope event names. */
8
+ export type TelemetryEnvelopeEventName = 'installation_activated' | 'mcp_server_started' | 'mcp_tool_completed' | 'mcp_tool_failed' | 'spec_lifecycle_transitioned' | 'release_check_completed';
7
9
  export type TelemetryEventName = 'init_project' | 'create_spec' | 'tool_used' | 'tool_error' | 'tool_blocked'
8
10
  /** SPEC-705: Emitted when agent parallelism is downgraded due to host RAM constraints. */
9
11
  | 'ram_guardrail_downgrade'
10
12
  /** SPEC-727: Emitted when a panel is aborted because two specialists share the same (modelId, promptHash). */
11
- | 'panel_heterogeneity_violation';
13
+ | 'panel_heterogeneity_violation' | TelemetryEnvelopeEventName;
14
+ export type TelemetryEnvelopeResult = 'success' | 'error' | 'blocked' | 'cancelled';
15
+ export type TelemetryDurationBucket = 'lt_100ms' | '100ms_1s' | '1s_5s' | 'gte_5s';
16
+ export type TelemetryOperatingSystem = 'darwin' | 'linux' | 'win32' | 'other';
17
+ export type TelemetryMcpHost = 'claude-code' | 'claude-desktop' | 'cursor' | 'codex' | 'other' | 'unknown';
18
+ /** SPEC-1704: the exact, closed shape of a schemaVersion-1 telemetry event. */
19
+ export interface TelemetryEnvelopeV1 {
20
+ schemaVersion: 1;
21
+ eventId: string;
22
+ eventName: TelemetryEnvelopeEventName;
23
+ occurredAt: string;
24
+ anonymousInstallationId: string;
25
+ sessionId: string;
26
+ planuVersion: string;
27
+ toolName?: string;
28
+ result?: TelemetryEnvelopeResult;
29
+ durationBucket?: TelemetryDurationBucket;
30
+ operatingSystem: TelemetryOperatingSystem;
31
+ nodeMajor: number;
32
+ mcpHost: TelemetryMcpHost;
33
+ }
34
+ /** Caller-supplied fields for buildTelemetryEnvelope; unknown keys are rejected. */
35
+ export interface TelemetryEnvelopeInput {
36
+ anonymousInstallationId: string;
37
+ sessionId: string;
38
+ toolName?: string;
39
+ result?: TelemetryEnvelopeResult;
40
+ durationMs?: number;
41
+ mcpHost?: TelemetryMcpHost;
42
+ }
43
+ /** Injectable determinism for tests and the `planu telemetry show` command. */
44
+ export interface TelemetryEnvelopeBuildOptions {
45
+ uuid?: () => string;
46
+ clock?: () => Date;
47
+ }
12
48
  export interface TelemetryConfig {
13
49
  enabled: boolean;
14
50
  /** ISO timestamp of when the user was first shown the opt-in prompt */
@@ -17,6 +53,8 @@ export interface TelemetryConfig {
17
53
  consentVersion?: number;
18
54
  /** SPEC-572: Opt-in to cross-project Observatory aggregated insights (requires telemetry enabled) */
19
55
  enableObservatory?: boolean;
56
+ /** SPEC-1704: generated on enable, deleted on disable, regenerated fresh on the next enable. */
57
+ anonymousInstallationId?: string;
20
58
  }
21
59
  export interface TelemetryEvent {
22
60
  event: TelemetryEventName;
@@ -83,12 +83,18 @@ export interface PerScenarioResult {
83
83
  evidence: string[];
84
84
  unverifiable?: true;
85
85
  }
86
+ export interface DoneDriftMissingFileFinding {
87
+ kind: 'done-drift-missing-files';
88
+ specId: string;
89
+ missingPath: string;
90
+ }
86
91
  export interface SpecComplianceResult {
87
92
  dimensionScore: number;
88
93
  perScenario: PerScenarioResult[];
89
94
  command: string;
90
95
  evidenceSource?: 'frontmatter' | 'criteria' | 'none';
91
96
  ignoredCriteriaTitles?: string[];
97
+ doneDriftFindings?: DoneDriftMissingFileFinding[];
92
98
  }
93
99
  export interface EvidenceTestLink {
94
100
  path: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@planu/cli",
3
- "version": "5.5.3",
3
+ "version": "5.7.0",
4
4
  "description": "Planu — MCP Server for Spec Driven Development. Cross-platform (Linux/macOS/Windows, x64/arm64).",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
package/planu-plugin.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "dev.planu.cli",
3
3
  "displayName": "Planu — Spec Driven Development",
4
4
  "description": "Manage software specs, estimations, and autonomous SDD workflows. Language-agnostic MCP server for Claude Code.",
5
- "version": "5.5.3",
5
+ "version": "5.7.0",
6
6
  "icon": "assets/plugin/icon.svg",
7
7
  "command": ["npx", "@planu/cli@latest"],
8
8
  "packageName": "@planu/cli",
@@ -116,15 +116,31 @@ export function isCommitReachable(repoRoot, commit, ontoCommit) {
116
116
  throw new Error(`git merge-base --is-ancestor exited with status ${String(result.status)}`);
117
117
  }
118
118
 
119
- export async function writePendingReleaseLedger(pendingPath, entries) {
120
- const temporaryPath = `${pendingPath}.${process.pid}.${Date.now()}.tmp`;
119
+ async function readJsonObject(path) {
121
120
  try {
122
- await writeFile(temporaryPath, `${JSON.stringify(entries, null, 2)}\n`, {
121
+ const parsed = JSON.parse(await readFile(path, 'utf8'));
122
+ return parsed !== null && typeof parsed === 'object' && !Array.isArray(parsed) ? parsed : {};
123
+ } catch (error) {
124
+ if (error?.code === 'ENOENT') return {};
125
+ throw error;
126
+ }
127
+ }
128
+
129
+ /**
130
+ * SPEC-1699: writes `entries` into the `releases` field of the committed
131
+ * planu/project.json, preserving every other field already on disk.
132
+ */
133
+ export async function writePendingReleaseLedger(projectJsonPath, entries) {
134
+ const project = await readJsonObject(projectJsonPath);
135
+ const nextProject = { ...project, releases: entries };
136
+ const temporaryPath = `${projectJsonPath}.${process.pid}.${Date.now()}.tmp`;
137
+ try {
138
+ await writeFile(temporaryPath, `${JSON.stringify(nextProject, null, 2)}\n`, {
123
139
  encoding: 'utf8',
124
140
  flag: 'wx',
125
141
  mode: 0o644,
126
142
  });
127
- await rename(temporaryPath, pendingPath);
143
+ await rename(temporaryPath, projectJsonPath);
128
144
  } catch (error) {
129
145
  await rm(temporaryPath, { force: true });
130
146
  throw error;