@planu/cli 3.9.14 → 4.0.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.
- package/CHANGELOG.md +5 -0
- package/dist/cli/commands/spec.js +20 -1
- package/dist/cli/commands/status.js +18 -1
- package/dist/config/license-plans.json +1 -0
- package/dist/engine/ai-integration/codex/hooks-generator.js +1 -0
- package/dist/engine/ai-integration/gemini/settings-generator.js +4 -1
- package/dist/engine/ai-integration/kiro/hooks-generator.js +2 -1
- package/dist/engine/autopilot/action-registry.js +5 -14
- package/dist/engine/autopilot/state-updater.js +13 -10
- package/dist/engine/cascade-hooks/hooks/git-auto-stage.hook.js +3 -0
- package/dist/engine/cascade-hooks/hooks/html-regen.hook.js +1 -1
- package/dist/engine/cascade-hooks/hooks/status-json.hook.js +1 -1
- package/dist/engine/cascade-hooks/state-drift-detector.d.ts +1 -1
- package/dist/engine/cascade-hooks/state-drift-detector.js +15 -12
- package/dist/engine/git/planu-autocommit.d.ts +1 -0
- package/dist/engine/git/planu-autocommit.js +6 -0
- package/dist/engine/git-hook-injector.js +3 -3
- package/dist/engine/handoff-artifacts/io.js +3 -2
- package/dist/engine/handoff-packager.js +2 -1
- package/dist/engine/hooks/full-spectrum-generator.d.ts +2 -1
- package/dist/engine/hooks/full-spectrum-generator.js +5 -3
- package/dist/engine/release/postmortem-generator.d.ts +1 -1
- package/dist/engine/release/postmortem-generator.js +3 -2
- package/dist/engine/safety/cross-process-lock.js +2 -2
- package/dist/engine/session/checkpoint-writer.js +0 -1
- package/dist/engine/session-context-generator.js +4 -1
- package/dist/engine/spec-audit/index.js +2 -2
- package/dist/engine/spec-audit/report-writer.d.ts +1 -1
- package/dist/engine/spec-audit/report-writer.js +5 -4
- package/dist/engine/spec-migrator/index.d.ts +1 -0
- package/dist/engine/spec-migrator/index.js +1 -0
- package/dist/engine/spec-migrator/planu-canonical-policy.d.ts +9 -0
- package/dist/engine/spec-migrator/planu-canonical-policy.js +62 -0
- package/dist/engine/spec-migrator/planu-root-cleaner.js +18 -94
- package/dist/engine/spec-migrator/strict-planu-cleanup.d.ts +6 -0
- package/dist/engine/spec-migrator/strict-planu-cleanup.js +199 -0
- package/dist/engine/spec-summary-html.d.ts +5 -5
- package/dist/engine/spec-summary-html.js +7 -32
- package/dist/storage/gaps-log.js +4 -4
- package/dist/storage/transition-log.js +3 -2
- package/dist/tools/audit-specs-drift.js +3 -3
- package/dist/tools/create-spec/post-creation.d.ts +2 -1
- package/dist/tools/create-spec/post-creation.js +9 -11
- package/dist/tools/create-spec/spec-builder.js +1 -1
- package/dist/tools/create-spec.js +42 -18
- package/dist/tools/flag-spec-gap.d.ts +1 -1
- package/dist/tools/flag-spec-gap.js +1 -1
- package/dist/tools/generate-dashboard.js +3 -3
- package/dist/tools/housekeeping-sweep.js +16 -0
- package/dist/tools/init-project/git-setup.js +11 -2
- package/dist/tools/init-project/handler.js +1 -27
- package/dist/tools/init-project/migration-runner.js +8 -0
- package/dist/tools/license-gate.d.ts +1 -0
- package/dist/tools/license-gate.js +5 -1
- package/dist/tools/list-specs.js +13 -0
- package/dist/tools/register-sdd-tools.d.ts +1 -1
- package/dist/tools/register-sdd-tools.js +1 -0
- package/dist/tools/register-spec-tools/core-spec-tools.js +16 -0
- package/dist/tools/spec-lock-handler.js +1 -1
- package/dist/tools/tool-registry/group-misc.js +4 -4
- package/dist/tools/update-status/batch.d.ts +3 -0
- package/dist/tools/update-status/batch.js +96 -0
- package/dist/tools/update-status/dod-gates.js +1 -1
- package/dist/tools/update-status/file-sync.js +3 -1
- package/dist/tools/update-status/index.js +15 -2
- package/dist/tools/update-status-actions.js +2 -6
- package/dist/tools/validate.js +27 -0
- package/dist/tools/workspace-dashboard-handler.js +6 -9
- package/dist/types/git.d.ts +1 -1
- package/dist/types/spec-format.d.ts +26 -0
- package/package.json +1 -1
package/dist/tools/validate.js
CHANGED
|
@@ -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
|
|
130
|
-
async function hasPendingAnalysis(projectPath,
|
|
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(
|
|
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
|
-
|
|
159
|
-
|
|
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
|
}
|
package/dist/types/git.d.ts
CHANGED
|
@@ -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). */
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@planu/cli",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "4.0.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",
|