@planu/cli 3.9.14 → 4.1.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 (102) hide show
  1. package/CHANGELOG.md +17 -1
  2. package/dist/cli/commands/spec.js +20 -1
  3. package/dist/cli/commands/status.js +18 -1
  4. package/dist/config/license-plans.json +1 -0
  5. package/dist/engine/ai-integration/agents-md/generator.js +4 -1
  6. package/dist/engine/ai-integration/cline/clinerules-generator.js +7 -2
  7. package/dist/engine/ai-integration/codex/agents-md-generator.js +2 -0
  8. package/dist/engine/ai-integration/codex/hooks-generator.js +1 -0
  9. package/dist/engine/ai-integration/cursor/cursorrules-generator.js +7 -2
  10. package/dist/engine/ai-integration/gemini/settings-generator.js +4 -1
  11. package/dist/engine/ai-integration/kiro/hooks-generator.js +2 -1
  12. package/dist/engine/ai-integration/windsurf/windsurfrules-generator.js +7 -2
  13. package/dist/engine/autopilot/action-registry.js +5 -14
  14. package/dist/engine/autopilot/state-updater.js +13 -10
  15. package/dist/engine/cascade-hooks/hooks/git-auto-stage.hook.js +3 -0
  16. package/dist/engine/cascade-hooks/hooks/html-regen.hook.js +1 -1
  17. package/dist/engine/cascade-hooks/hooks/status-json.hook.js +1 -1
  18. package/dist/engine/cascade-hooks/state-drift-detector.d.ts +1 -1
  19. package/dist/engine/cascade-hooks/state-drift-detector.js +15 -12
  20. package/dist/engine/git/planu-autocommit.d.ts +1 -0
  21. package/dist/engine/git/planu-autocommit.js +6 -0
  22. package/dist/engine/git-hook-injector.js +3 -3
  23. package/dist/engine/handoff-artifacts/io.js +3 -2
  24. package/dist/engine/handoff-packager.js +2 -1
  25. package/dist/engine/hooks/full-spectrum-generator.d.ts +2 -1
  26. package/dist/engine/hooks/full-spectrum-generator.js +5 -3
  27. package/dist/engine/marketplace-fetcher/anthropic-source.js +2 -0
  28. package/dist/engine/opencode/config-scaffold.js +4 -0
  29. package/dist/engine/release/postmortem-generator.d.ts +1 -1
  30. package/dist/engine/release/postmortem-generator.js +3 -2
  31. package/dist/engine/rules-generator/index.js +2 -0
  32. package/dist/engine/rules-reconciler.js +2 -0
  33. package/dist/engine/safety/cross-process-lock.js +2 -2
  34. package/dist/engine/session/checkpoint-writer.js +0 -1
  35. package/dist/engine/session-context-generator.js +4 -1
  36. package/dist/engine/skill-bootstrap/skill-writer.js +2 -0
  37. package/dist/engine/skill-generation/multi-agent-writer.js +2 -0
  38. package/dist/engine/spec-audit/index.js +2 -2
  39. package/dist/engine/spec-audit/report-writer.d.ts +1 -1
  40. package/dist/engine/spec-audit/report-writer.js +5 -4
  41. package/dist/engine/spec-language/english-only.d.ts +8 -7
  42. package/dist/engine/spec-language/english-only.js +27 -3
  43. package/dist/engine/spec-migrator/index.d.ts +1 -0
  44. package/dist/engine/spec-migrator/index.js +1 -0
  45. package/dist/engine/spec-migrator/planu-canonical-policy.d.ts +9 -0
  46. package/dist/engine/spec-migrator/planu-canonical-policy.js +62 -0
  47. package/dist/engine/spec-migrator/planu-root-cleaner.js +18 -94
  48. package/dist/engine/spec-migrator/strict-planu-cleanup.d.ts +6 -0
  49. package/dist/engine/spec-migrator/strict-planu-cleanup.js +199 -0
  50. package/dist/engine/spec-summary-html.d.ts +5 -5
  51. package/dist/engine/spec-summary-html.js +7 -32
  52. package/dist/engine/universal-rules/host-writer.js +8 -2
  53. package/dist/engine/universal-rules/rules/planu-english-specs.js +9 -5
  54. package/dist/hosts/claude-code/ux/skills-writer.js +2 -0
  55. package/dist/hosts/codex/config-scaffold.js +5 -0
  56. package/dist/hosts/gemini/config-scaffold.js +4 -0
  57. package/dist/storage/gaps-log.js +4 -4
  58. package/dist/storage/transition-log.js +3 -2
  59. package/dist/tools/audit-specs-drift.js +3 -3
  60. package/dist/tools/create-skill.js +21 -0
  61. package/dist/tools/create-spec/post-creation.d.ts +2 -1
  62. package/dist/tools/create-spec/post-creation.js +9 -11
  63. package/dist/tools/create-spec/spec-builder.js +1 -1
  64. package/dist/tools/create-spec.js +42 -18
  65. package/dist/tools/flag-spec-gap.d.ts +1 -1
  66. package/dist/tools/flag-spec-gap.js +1 -1
  67. package/dist/tools/generate-dashboard.js +3 -3
  68. package/dist/tools/housekeeping-sweep.js +16 -0
  69. package/dist/tools/init-project/agents-md-writer.js +2 -0
  70. package/dist/tools/init-project/conventions-writer.js +2 -0
  71. package/dist/tools/init-project/find-skills-writer.js +2 -0
  72. package/dist/tools/init-project/git-setup.js +11 -2
  73. package/dist/tools/init-project/handler.js +1 -27
  74. package/dist/tools/init-project/helpers.js +5 -0
  75. package/dist/tools/init-project/migration-runner.js +8 -0
  76. package/dist/tools/init-project/per-client-files-writer.js +2 -0
  77. package/dist/tools/init-project/planu-workflow-generator.js +2 -0
  78. package/dist/tools/init-project/rules-generator.js +7 -1
  79. package/dist/tools/init-project/rules-writer.js +3 -0
  80. package/dist/tools/init-project/skills-multi-teammate-review-writer.js +2 -0
  81. package/dist/tools/init-project/skills-writer.js +2 -0
  82. package/dist/tools/license-gate.d.ts +1 -0
  83. package/dist/tools/license-gate.js +5 -1
  84. package/dist/tools/list-specs.js +13 -0
  85. package/dist/tools/register-sdd-tools.d.ts +1 -1
  86. package/dist/tools/register-sdd-tools.js +1 -0
  87. package/dist/tools/register-spec-tools/core-spec-tools.js +16 -0
  88. package/dist/tools/spec-lock-handler.js +1 -1
  89. package/dist/tools/tool-registry/group-misc.js +4 -4
  90. package/dist/tools/update-status/batch.d.ts +3 -0
  91. package/dist/tools/update-status/batch.js +96 -0
  92. package/dist/tools/update-status/dod-gates.js +1 -1
  93. package/dist/tools/update-status/file-sync.js +3 -1
  94. package/dist/tools/update-status/index.js +15 -2
  95. package/dist/tools/update-status-actions.js +2 -6
  96. package/dist/tools/validate.js +27 -0
  97. package/dist/tools/workspace-dashboard-handler.js +6 -9
  98. package/dist/types/git.d.ts +1 -1
  99. package/dist/types/spec-format.d.ts +26 -0
  100. package/dist/types/spec-language.d.ts +8 -0
  101. package/dist/types/spec-language.js +2 -0
  102. package/package.json +20 -20
@@ -1182,11 +1182,11 @@ export function registerMiscGroupTools(s) {
1182
1182
  registerRepairFrontmatterDriftTool(s);
1183
1183
  // ── Generate dashboard ─────────────────────────────────────────────────────
1184
1184
  s.registerTool('generate_spec_dashboard', {
1185
- description: 'Regenerate planu/index.html dashboard with all specs, metrics, and pagination. Call after bulk changes or to fix a stale dashboard.',
1185
+ description: 'Deprecated compatibility tool. Planu no longer writes generated dashboard HTML into planu/.',
1186
1186
  inputSchema: {
1187
1187
  projectPath: z.string().describe('Absolute path to the project root directory'),
1188
1188
  },
1189
- annotations: { readOnlyHint: false },
1189
+ annotations: { readOnlyHint: true },
1190
1190
  }, async (args) => {
1191
1191
  const projectId = hashProjectPath(args.projectPath);
1192
1192
  const specs = await specStore.listSpecs(projectId);
@@ -1196,7 +1196,7 @@ export function registerMiscGroupTools(s) {
1196
1196
  content: [
1197
1197
  {
1198
1198
  type: 'text',
1199
- text: `Dashboard regenerated: ${String(specs.length)} specs (${String(doneCount)} done). File: planu/index.html`,
1199
+ text: `Dashboard generation is deprecated; no project files were written. Current specs: ${String(specs.length)} (${String(doneCount)} done).`,
1200
1200
  },
1201
1201
  ],
1202
1202
  };
@@ -1331,7 +1331,7 @@ export function registerMiscGroupTools(s) {
1331
1331
  // ── SPEC-739: flag_spec_gap ─────────────────────────────────────────────────
1332
1332
  s.registerTool('flag_spec_gap', {
1333
1333
  description: 'Record a spec implementation gap discovered mid-implementation. ' +
1334
- 'Persists a hash-chained entry to planu/research/gaps.jsonl with severity ' +
1334
+ 'Persists a hash-chained entry to external Planu project data with severity ' +
1335
1335
  "classification ('low' | 'medium' | 'high') and affected spec links. " +
1336
1336
  'Existing callers without severity or affectedSpecs continue to work (defaults applied).',
1337
1337
  inputSchema: {
@@ -0,0 +1,3 @@
1
+ import type { ToolResult, UpdateStatusBatchInput } from '../../types/index.js';
2
+ export declare function handleUpdateStatusBatch(input: UpdateStatusBatchInput): Promise<ToolResult>;
3
+ //# sourceMappingURL=batch.d.ts.map
@@ -0,0 +1,96 @@
1
+ // tools/update-status/batch.ts — SPEC-1017 batch status transitions
2
+ import { handleUpdateStatus } from './index.js';
3
+ import { resolveProjectIdOrAutoDetect } from '../resolve-project-id.js';
4
+ function firstText(result) {
5
+ const first = result.content[0];
6
+ return first?.type === 'text' ? first.text : JSON.stringify(result.structuredContent ?? {});
7
+ }
8
+ export async function handleUpdateStatusBatch(input) {
9
+ const uniqueSpecIds = [...new Set(input.specIds)].sort();
10
+ if (uniqueSpecIds.length === 0) {
11
+ return { content: [{ type: 'text', text: 'update_status_batch requires at least one specId.' }], isError: true };
12
+ }
13
+ const resolved = await resolveProjectIdOrAutoDetect({
14
+ projectId: input.projectId,
15
+ projectPath: input.projectPath,
16
+ });
17
+ if (!resolved.ok) {
18
+ return resolved.errorResult;
19
+ }
20
+ if (input.dryRun) {
21
+ return {
22
+ content: [
23
+ {
24
+ type: 'text',
25
+ text: `Batch status dry run: ${uniqueSpecIds.length} spec(s) would transition to ${input.status}.\n` +
26
+ uniqueSpecIds.map((id) => `- ${id}`).join('\n'),
27
+ },
28
+ ],
29
+ structuredContent: {
30
+ dryRun: true,
31
+ status: input.status,
32
+ specIds: uniqueSpecIds,
33
+ },
34
+ };
35
+ }
36
+ const updated = [];
37
+ const skipped = [];
38
+ const failed = [];
39
+ const previousSuppress = process.env.PLANU_SUPPRESS_AUTOCOMMIT;
40
+ process.env.PLANU_SUPPRESS_AUTOCOMMIT = 'true';
41
+ try {
42
+ for (const specId of uniqueSpecIds) {
43
+ const result = await handleUpdateStatus({
44
+ specId,
45
+ status: input.status,
46
+ projectId: resolved.projectId,
47
+ projectPath: resolved.projectPath,
48
+ reviewNotes: input.reviewNotes,
49
+ });
50
+ const message = firstText(result);
51
+ if (result.isError === true) {
52
+ if (/already|idempotent|same status/i.test(message)) {
53
+ skipped.push({ specId, message });
54
+ }
55
+ else {
56
+ failed.push({ specId, message });
57
+ }
58
+ }
59
+ else {
60
+ updated.push({ specId, message });
61
+ }
62
+ }
63
+ }
64
+ finally {
65
+ if (previousSuppress === undefined) {
66
+ delete process.env.PLANU_SUPPRESS_AUTOCOMMIT;
67
+ }
68
+ else {
69
+ process.env.PLANU_SUPPRESS_AUTOCOMMIT = previousSuppress;
70
+ }
71
+ }
72
+ try {
73
+ const { runStrictPlanuCleanup } = await import('../../engine/spec-migrator/index.js');
74
+ await runStrictPlanuCleanup(resolved.projectPath);
75
+ }
76
+ catch {
77
+ /* best-effort final pass */
78
+ }
79
+ const text = [
80
+ `Batch status transition complete: ${input.status}`,
81
+ `Updated: ${updated.length}`,
82
+ `Skipped: ${skipped.length}`,
83
+ `Failed: ${failed.length}`,
84
+ ].join('\n');
85
+ return {
86
+ content: [{ type: 'text', text }],
87
+ isError: failed.length > 0,
88
+ structuredContent: {
89
+ updated,
90
+ skipped,
91
+ failed,
92
+ sideEffectsFlushed: ['strict-planu-cleanup'],
93
+ },
94
+ };
95
+ }
96
+ //# sourceMappingURL=batch.js.map
@@ -264,7 +264,7 @@ export async function checkValidationReportGate(specId, projectId, force) {
264
264
  return null;
265
265
  }
266
266
  if (!result.payload.passed) {
267
- const artifactPath = `planu/data/projects/${projectId}/handoffs/${specId}/validation-report.json`;
267
+ const artifactPath = `external Planu project data: handoffs/${specId}/validation-report.json`;
268
268
  return {
269
269
  content: [
270
270
  {
@@ -86,7 +86,9 @@ export async function syncSpecFiles(updatedSpec, currentStatus, newStatus, proje
86
86
  // Commit message must reflect the actual transition — 'mark-done' is only
87
87
  // correct when newStatus === 'done'; any other transition uses 'status-update'
88
88
  // to avoid misleading "mark as done" messages on approved/implementing/etc.
89
- if (projectPath) {
89
+ if (projectPath &&
90
+ process.env.PLANU_ENABLE_AUTOCOMMIT === 'true' &&
91
+ process.env.PLANU_SUPPRESS_AUTOCOMMIT !== 'true') {
90
92
  try {
91
93
  const { git: gitCmd } = await import('../git/git-helpers.js');
92
94
  await gitCmd(projectPath, ['add', '--', updatedSpec.specPath]);
@@ -240,6 +240,16 @@ export async function handleUpdateStatus(params, server) {
240
240
  return resolved.errorResult;
241
241
  }
242
242
  const projectId = resolved.projectId;
243
+ const effectiveProjectPath = resolved.projectPath;
244
+ if (effectiveProjectPath) {
245
+ try {
246
+ const { runStrictPlanuCleanup } = await import('../../engine/spec-migrator/index.js');
247
+ await runStrictPlanuCleanup(effectiveProjectPath);
248
+ }
249
+ catch {
250
+ /* strict cleanup is best-effort here; validate fails closed if artifacts remain */
251
+ }
252
+ }
243
253
  try {
244
254
  // Get the current spec
245
255
  const spec = await specStore.getSpec(projectId, specId);
@@ -271,7 +281,7 @@ export async function handleUpdateStatus(params, server) {
271
281
  content: [
272
282
  {
273
283
  type: 'text',
274
- text: `Spec ${specId} is locked by another process (cross-process lock). Retry later or inspect planu/.locks/${specId}.lock`,
284
+ text: `Spec ${specId} is locked by another process (cross-process lock). Retry later or inspect data/.locks/planu/${specId}.lock`,
275
285
  },
276
286
  ],
277
287
  isError: true,
@@ -864,7 +874,10 @@ export async function handleUpdateStatus(params, server) {
864
874
  }
865
875
  // SPEC-544: Final git add after all writes complete (covers auto-advance multi-step transitions)
866
876
  // SPEC-575: Auto-commit staged planu/ docs (idempotent, safe-fail)
867
- if (effectiveGatePath && updatedSpec.specPath) {
877
+ if (effectiveGatePath &&
878
+ updatedSpec.specPath &&
879
+ process.env.PLANU_ENABLE_AUTOCOMMIT === 'true' &&
880
+ process.env.PLANU_SUPPRESS_AUTOCOMMIT !== 'true') {
868
881
  try {
869
882
  const { git: gitCmd } = await import('../git/git-helpers.js');
870
883
  await gitCmd(effectiveGatePath, ['add', 'planu/']);
@@ -162,22 +162,18 @@ export async function runDoneActions(projectId, specId, gitBranch) {
162
162
  }
163
163
  return null;
164
164
  })(),
165
- // SPEC-544: Auto-stage planu/ files, then warn only if non-planu changes remain
166
- // SPEC-575: Auto-commit staged planu/ docs (idempotent, safe-fail)
165
+ // Warn if non-planu changes remain. Planu autocommit/staging is opt-in only.
167
166
  (async () => {
168
167
  try {
169
168
  const { resolveProjectPath, git: gitCmd } = await import('./git/git-helpers.js');
170
169
  const projectPath = await resolveProjectPath(projectId);
171
- try {
170
+ if (process.env.PLANU_ENABLE_AUTOCOMMIT === 'true') {
172
171
  await gitCmd(projectPath, ['add', 'planu/']);
173
172
  const { planuAutoCommit } = await import('../engine/git/planu-autocommit.js');
174
173
  void planuAutoCommit({ projectPath, specId, reason: 'mark-done' }).catch((err) => {
175
174
  console.error('[update-status] planuAutoCommit failed:', err instanceof Error ? err.message : String(err));
176
175
  });
177
176
  }
178
- catch {
179
- // git add failed (nothing to stage, or not a git repo) — continue to status check
180
- }
181
177
  const { stdout } = await gitCmd(projectPath, ['status', '--porcelain']);
182
178
  const nonPlanuLines = stdout
183
179
  .trim()
@@ -68,6 +68,33 @@ export async function handleValidate(args, server) {
68
68
  };
69
69
  }
70
70
  const projectPath = knowledge.projectPath;
71
+ // SPEC-1017: fail closed when planu/ contains non-canonical artifacts.
72
+ try {
73
+ const { runStrictPlanuCleanup, validateStrictPlanuLayout } = await import('../engine/spec-migrator/index.js');
74
+ await runStrictPlanuCleanup(projectPath);
75
+ const layout = await validateStrictPlanuLayout(projectPath);
76
+ if (!layout.ok) {
77
+ return {
78
+ content: [
79
+ {
80
+ type: 'text',
81
+ text: `Strict Planu layout validation failed for ${specId}.\n\n` +
82
+ `Non-canonical paths:\n${layout.offenders.map((p) => `- ${p}`).join('\n')}\n\n` +
83
+ `Canonical contract:\n${layout.contract}`,
84
+ },
85
+ ],
86
+ isError: true,
87
+ structuredContent: {
88
+ error: 'strict_planu_layout_violation',
89
+ offenders: layout.offenders,
90
+ contract: layout.contract,
91
+ },
92
+ };
93
+ }
94
+ }
95
+ catch {
96
+ /* best-effort — implementation validation still runs if layout check is unavailable */
97
+ }
71
98
  // 3. Run validation engine
72
99
  const result = await validateSpec(spec, projectPath);
73
100
  // 4. Generate DoR and DoD checklists
@@ -10,6 +10,7 @@ import { readRecentAutopilotAlerts } from '../storage/autopilot-log-store.js';
10
10
  import { verifyStateFiles } from '../engine/cascade-hooks/state-drift-detector.js';
11
11
  import { readFile } from 'node:fs/promises';
12
12
  import { join } from 'node:path';
13
+ import { getAsyncAnalysisPath } from './create-spec/post-creation.js';
13
14
  export async function handleWorkspaceOverview(args) {
14
15
  const result = await buildWorkspaceOverview(args.healthThreshold);
15
16
  if (result.projectCount === 0) {
@@ -126,10 +127,10 @@ export async function handleWorkspaceSearch(args) {
126
127
  }
127
128
  return { content: [{ type: 'text', text: lines.join('\n') }] };
128
129
  }
129
- /** SPEC-781: Check if a spec has a pending async analysis (no .analysis.json yet). */
130
- async function hasPendingAnalysis(projectPath, specDir) {
130
+ /** SPEC-781: Check if a spec has pending async analysis in external project data. */
131
+ async function hasPendingAnalysis(projectPath, specId) {
131
132
  try {
132
- await readFile(join(projectPath, specDir, '.analysis.json'), 'utf-8');
133
+ await readFile(getAsyncAnalysisPath(projectPath, specId), 'utf-8');
133
134
  return false;
134
135
  }
135
136
  catch {
@@ -144,7 +145,6 @@ async function collectPendingAnalysisAlerts(projectPath) {
144
145
  const results = [];
145
146
  const PENDING_RE = /^pendingAnalysis:\s*true/m;
146
147
  const ID_RE = /^id:\s*(SPEC-\d+)/m;
147
- const SPEC_DIR_RE = /planu\/specs\/([^/]+)\/spec\.md$/;
148
148
  for (const specFile of specFiles) {
149
149
  const content = await readFile(specFile, 'utf-8').catch(() => '');
150
150
  if (!PENDING_RE.test(content)) {
@@ -155,11 +155,8 @@ async function collectPendingAnalysisAlerts(projectPath) {
155
155
  if (specId === undefined) {
156
156
  continue;
157
157
  }
158
- const dirMatch = SPEC_DIR_RE.exec(specFile);
159
- const dirName = dirMatch?.[1];
160
- const specDir = dirName !== undefined ? join('planu/specs', dirName) : null;
161
- if (specDir !== null && !(await hasPendingAnalysis(projectPath, specDir))) {
162
- continue; // .analysis.json exists — analysis done
158
+ if (!(await hasPendingAnalysis(projectPath, specId))) {
159
+ continue;
163
160
  }
164
161
  results.push({ specId, message: `Spec ${specId} analysis still running` });
165
162
  }
@@ -310,7 +310,7 @@ export interface ListSpecPrsInput {
310
310
  projectPath: string;
311
311
  specId?: string;
312
312
  }
313
- export type PlanuAutocommitSkipReason = 'no-staged-changes' | 'mid-merge' | 'detached-head';
313
+ export type PlanuAutocommitSkipReason = 'disabled' | 'no-staged-changes' | 'mid-merge' | 'detached-head';
314
314
  export type PlanuAutocommitReason = 'mark-done' | 'sync-release' | 'status-update' | 'session-checkpoint';
315
315
  export interface PlanuAutocommitResult {
316
316
  committed: boolean;
@@ -1,5 +1,6 @@
1
1
  import type { Spec } from './spec/core.js';
2
2
  import type { Estimation } from './estimation.js';
3
+ import type { SpecStatus } from './common/index.js';
3
4
  /** A criterion in the lean spec frontmatter. */
4
5
  export interface LeanCriterion {
5
6
  text: string;
@@ -42,6 +43,31 @@ export interface CleanupResult {
42
43
  deletedSpecFiles: string[];
43
44
  totalDeleted: number;
44
45
  }
46
+ export interface PlanuCanonicalPathPolicy {
47
+ readonly canonicalRootFiles: readonly string[];
48
+ readonly canonicalRootDirs: readonly string[];
49
+ readonly canonicalSpecFiles: readonly string[];
50
+ readonly generatedRuntimePatterns: readonly string[];
51
+ readonly legacyMergeBeforeDeleteFiles: readonly string[];
52
+ }
53
+ export interface StrictPlanuCleanupResult {
54
+ deleted: string[];
55
+ merged: string[];
56
+ gitignoreUpdated: boolean;
57
+ }
58
+ export interface StrictPlanuValidationResult {
59
+ ok: boolean;
60
+ offenders: string[];
61
+ contract: string;
62
+ }
63
+ export interface UpdateStatusBatchInput {
64
+ specIds: string[];
65
+ status: SpecStatus;
66
+ projectId?: string;
67
+ projectPath?: string;
68
+ dryRun?: boolean;
69
+ reviewNotes?: string;
70
+ }
45
71
  /** Report of detected migration drift (SPEC-715). Read-only — no FS mutations. */
46
72
  export interface MigrationDriftReport {
47
73
  /** Count of specs that still have a stray technical.md (need unified migration). */
@@ -0,0 +1,8 @@
1
+ export type EnglishOnlyArtifactKind = 'spec' | 'skill' | 'agent' | 'rule';
2
+ export interface EnglishOnlyValidationResult {
3
+ ok: boolean;
4
+ detectedLanguage: 'en' | 'es' | 'pt' | 'unknown';
5
+ reason?: string;
6
+ signals: string[];
7
+ }
8
+ //# sourceMappingURL=spec-language.d.ts.map
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=spec-language.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@planu/cli",
3
- "version": "3.9.14",
3
+ "version": "4.1.0",
4
4
  "description": "Planu — MCP Server for Spec Driven Development with native Rust acceleration for hot paths. Cross-platform (Linux/macOS/Windows, x64/arm64, glibc/musl).",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -32,12 +32,12 @@
32
32
  "packageName": "@planu/core"
33
33
  },
34
34
  "optionalDependencies": {
35
- "@planu/core-darwin-arm64": "3.9.14",
36
- "@planu/core-darwin-x64": "3.9.14",
37
- "@planu/core-linux-arm64-gnu": "3.9.14",
38
- "@planu/core-linux-arm64-musl": "3.9.14",
39
- "@planu/core-linux-x64-gnu": "3.9.14",
40
- "@planu/core-linux-x64-musl": "3.9.14"
35
+ "@planu/core-darwin-arm64": "4.1.0",
36
+ "@planu/core-darwin-x64": "4.1.0",
37
+ "@planu/core-linux-arm64-gnu": "4.1.0",
38
+ "@planu/core-linux-arm64-musl": "4.1.0",
39
+ "@planu/core-linux-x64-gnu": "4.1.0",
40
+ "@planu/core-linux-x64-musl": "4.1.0"
41
41
  },
42
42
  "engines": {
43
43
  "node": ">=24.0.0"
@@ -149,8 +149,8 @@
149
149
  "@commitlint/config-conventional": "^21.0.1",
150
150
  "@eslint/js": "^10.0.1",
151
151
  "@napi-rs/cli": "^3.6.2",
152
- "@secretlint/secretlint-rule-no-homedir": "^13.0.0",
153
- "@secretlint/secretlint-rule-preset-recommend": "^13.0.0",
152
+ "@secretlint/secretlint-rule-no-homedir": "^13.0.2",
153
+ "@secretlint/secretlint-rule-preset-recommend": "^13.0.2",
154
154
  "@semantic-release/changelog": "^6.0.3",
155
155
  "@semantic-release/commit-analyzer": "^13.0.1",
156
156
  "@semantic-release/git": "^10.0.1",
@@ -159,30 +159,30 @@
159
159
  "@semantic-release/release-notes-generator": "^14.1.1",
160
160
  "@stryker-mutator/core": "^9.6.1",
161
161
  "@stryker-mutator/vitest-runner": "^9.6.1",
162
- "@supabase/supabase-js": "^2.105.4",
163
- "@types/node": "^25.7.0",
164
- "@vitejs/plugin-vue": "^6.0.6",
165
- "@vitest/coverage-v8": "^4.1.6",
162
+ "@supabase/supabase-js": "^2.106.1",
163
+ "@types/node": "^25.9.1",
164
+ "@vitejs/plugin-vue": "^6.0.7",
165
+ "@vitest/coverage-v8": "^4.1.7",
166
166
  "@vue/test-utils": "^2.4.10",
167
- "eslint": "^10.3.0",
167
+ "eslint": "^10.4.0",
168
168
  "eslint-config-prettier": "^10.1.8",
169
169
  "eslint-import-resolver-typescript": "^4.4.4",
170
170
  "eslint-plugin-import": "^2.32.0",
171
171
  "happy-dom": "^20.9.0",
172
172
  "husky": "^9.1.7",
173
173
  "javascript-obfuscator": "^5.4.2",
174
- "knip": "^6.13.1",
175
- "lint-staged": "^17.0.4",
174
+ "knip": "^6.14.1",
175
+ "lint-staged": "^17.0.5",
176
176
  "madge": "^8.0.0",
177
177
  "prettier": "^3.8.3",
178
- "secretlint": "^13.0.0",
178
+ "secretlint": "^13.0.2",
179
179
  "semantic-release": "^25.0.3",
180
180
  "tsc-alias": "^1.8.17",
181
181
  "type-coverage": "^2.29.7",
182
182
  "typescript": "^6.0.3",
183
- "typescript-eslint": "^8.59.3",
184
- "vite": "^8.0.12",
185
- "vitest": "^4.1.6",
183
+ "typescript-eslint": "^8.59.4",
184
+ "vite": "^8.0.14",
185
+ "vitest": "^4.1.7",
186
186
  "vue": "^3.5.34"
187
187
  }
188
188
  }