@planu/cli 4.3.25 → 4.4.1

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 (40) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/dist/engine/constitution/sdd-rules-registry.d.ts +12 -0
  3. package/dist/engine/constitution/sdd-rules-registry.js +105 -0
  4. package/dist/engine/evidence-gates/artifact-reader.js +10 -5
  5. package/dist/engine/evidence-index/done-drift.d.ts +6 -0
  6. package/dist/engine/evidence-index/done-drift.js +44 -0
  7. package/dist/engine/evidence-index/index-builder.d.ts +10 -0
  8. package/dist/engine/evidence-index/index-builder.js +138 -0
  9. package/dist/engine/host-rules-templates/templates.js +3 -0
  10. package/dist/engine/spec-format/lean-spec-generator.js +17 -12
  11. package/dist/engine/spec-grounding/contract.d.ts +19 -0
  12. package/dist/engine/spec-grounding/contract.js +186 -0
  13. package/dist/engine/spec-metrics/actionable-metrics.d.ts +10 -0
  14. package/dist/engine/spec-metrics/actionable-metrics.js +69 -0
  15. package/dist/engine/spec-migrator/planu-canonical-policy.d.ts +1 -0
  16. package/dist/engine/spec-migrator/planu-canonical-policy.js +7 -0
  17. package/dist/engine/spec-migrator/strict-planu-cleanup.d.ts +2 -2
  18. package/dist/engine/spec-migrator/strict-planu-cleanup.js +35 -20
  19. package/dist/engine/spec-quality/generic-output-gate.d.ts +3 -0
  20. package/dist/engine/spec-quality/generic-output-gate.js +105 -0
  21. package/dist/tools/create-spec.js +160 -30
  22. package/dist/tools/update-status/evidence-gate.js +23 -6
  23. package/dist/tools/update-status/transition-guard.js +49 -0
  24. package/dist/tools/validate.js +5 -3
  25. package/dist/types/actionable-spec-metrics.d.ts +8 -0
  26. package/dist/types/actionable-spec-metrics.js +2 -0
  27. package/dist/types/evidence-gates.d.ts +1 -1
  28. package/dist/types/evidence-index.d.ts +24 -0
  29. package/dist/types/evidence-index.js +2 -0
  30. package/dist/types/index.d.ts +5 -0
  31. package/dist/types/index.js +5 -0
  32. package/dist/types/sdd-constitution.d.ts +27 -0
  33. package/dist/types/sdd-constitution.js +2 -0
  34. package/dist/types/spec-format.d.ts +12 -0
  35. package/dist/types/spec-grounding.d.ts +22 -0
  36. package/dist/types/spec-grounding.js +2 -0
  37. package/dist/types/spec-quality.d.ts +10 -0
  38. package/package.json +11 -11
  39. package/planu-native.json +29 -8
  40. package/planu-plugin.json +35 -7
@@ -4,10 +4,13 @@ import { extractCriteria, extractListItems, extractSection, } from '../../engine
4
4
  import { stripFrontmatter } from '../../engine/frontmatter-parser.js';
5
5
  import { readEvidenceArtifacts } from '../../engine/evidence-gates/artifact-reader.js';
6
6
  import { checkLifecycleEvidenceGate } from '../../engine/evidence-gates/lifecycle-gate.js';
7
+ import { buildSpecEvidenceIndex } from '../../engine/evidence-index/index-builder.js';
8
+ import { checkDoneDriftContract } from '../../engine/evidence-index/done-drift.js';
9
+ import { parseTechnicalReferenceGroundingRecords } from '../../engine/spec-grounding/contract.js';
7
10
  /** SPEC-1054: BDD/SDD lifecycle evidence gate. */
8
11
  export async function checkLifecycleEvidenceTransitionGate(args) {
9
- const [criteria, artifacts] = await Promise.all([
10
- extractLifecycleGateCriteria(args.spec, args.projectPath),
12
+ const [criteriaResult, artifacts] = await Promise.all([
13
+ extractLifecycleGateCriteriaAndBody(args.spec, args.projectPath),
11
14
  readEvidenceArtifacts({
12
15
  spec: args.spec,
13
16
  projectId: args.projectId,
@@ -15,13 +18,26 @@ export async function checkLifecycleEvidenceTransitionGate(args) {
15
18
  projectPath: args.projectPath,
16
19
  }),
17
20
  ]);
21
+ const { criteria, body } = criteriaResult;
18
22
  const result = checkLifecycleEvidenceGate({
19
23
  transition: args.transition,
20
24
  spec: args.spec,
21
25
  criteria,
22
26
  artifacts,
23
27
  });
24
- if (result.passed) {
28
+ if (args.transition === 'done') {
29
+ const index = await buildSpecEvidenceIndex({
30
+ specId: args.specId,
31
+ criteria,
32
+ artifacts,
33
+ projectPath: args.projectPath,
34
+ });
35
+ const groundedTechnicalPaths = body
36
+ ? parseTechnicalReferenceGroundingRecords(body).map((record) => record.path)
37
+ : [];
38
+ result.issues.push(...checkDoneDriftContract({ index, groundedTechnicalPaths }));
39
+ }
40
+ if (result.issues.length === 0) {
25
41
  return null;
26
42
  }
27
43
  return evidenceGateError({
@@ -34,7 +50,7 @@ export async function checkLifecycleEvidenceTransitionGate(args) {
34
50
  requiredContractKinds: result.requiredContractKinds,
35
51
  });
36
52
  }
37
- async function extractLifecycleGateCriteria(spec, projectPath) {
53
+ async function extractLifecycleGateCriteriaAndBody(spec, projectPath) {
38
54
  const specPath = isAbsolute(spec.specPath) || !projectPath ? spec.specPath : join(projectPath, spec.specPath);
39
55
  try {
40
56
  const raw = await readFile(specPath, 'utf-8');
@@ -43,14 +59,14 @@ async function extractLifecycleGateCriteria(spec, projectPath) {
43
59
  if (acceptanceCriteria) {
44
60
  const items = extractListItems(acceptanceCriteria);
45
61
  if (items.length > 0) {
46
- return [...new Set(items)];
62
+ return { criteria: [...new Set(items)], body: raw };
47
63
  }
48
64
  }
49
65
  }
50
66
  catch {
51
67
  // Fall back to the broader validator extractor when the canonical file is unavailable.
52
68
  }
53
- return extractCriteria(spec);
69
+ return { criteria: await extractCriteria(spec), body: null };
54
70
  }
55
71
  function evidenceGateError(args) {
56
72
  return {
@@ -72,6 +88,7 @@ function evidenceGateError(args) {
72
88
  structuredContent: {
73
89
  error: 'lifecycle_evidence_gate_failed',
74
90
  code: 422,
91
+ sddConstitutionRuleId: args.transition === 'done' ? 'sdd.done-evidence-required' : 'sdd.grounded-contract',
75
92
  context: {
76
93
  specId: args.specId,
77
94
  transition: args.transition,
@@ -6,6 +6,8 @@ import { dispatchFeedbackEvent } from '../learn.js';
6
6
  import { scoreAmbiguityFromPath } from '../../engine/ambiguity-scorer.js';
7
7
  import { checkReadinessInternal } from '../../engine/readiness-checker.js';
8
8
  import { validateEnglishOnlySpecText } from '../../engine/spec-language/english-only.js';
9
+ import { checkGroundedSpecContract } from '../../engine/spec-grounding/contract.js';
10
+ import { checkGenericSpecOutput } from '../../engine/spec-quality/generic-output-gate.js';
9
11
  /**
10
12
  * Valid state transitions for spec lifecycle.
11
13
  * draft -> review -> approved -> implementing -> done
@@ -224,6 +226,53 @@ export async function checkReadinessGate(spec, newStatus, forceApprove) {
224
226
  qualityWarnings: [],
225
227
  };
226
228
  }
229
+ const groundingResult = checkGroundedSpecContract(spec, body);
230
+ if (!groundingResult.passed) {
231
+ return {
232
+ blockResult: {
233
+ content: [
234
+ {
235
+ type: 'text',
236
+ text: `Grounded spec contract blocked transition to ${newStatus}. ` +
237
+ groundingResult.issues.slice(0, 3).join('; '),
238
+ },
239
+ ],
240
+ isError: true,
241
+ structuredContent: {
242
+ error: 'GROUNDED_SPEC_CONTRACT_BLOCKED',
243
+ sddConstitutionRuleId: 'sdd.grounded-contract',
244
+ issues: groundingResult.issues,
245
+ fixHint: 'Add grounding metadata for every contract criterion or move ungrounded criteria to advisory/discovery before review or approval.',
246
+ },
247
+ },
248
+ qualityWarnings: [],
249
+ };
250
+ }
251
+ const genericOutputGate = checkGenericSpecOutput(body);
252
+ if (!genericOutputGate.passed) {
253
+ return {
254
+ blockResult: {
255
+ content: [
256
+ {
257
+ type: 'text',
258
+ text: `Spec quality gate blocked transition to ${newStatus}. ` +
259
+ genericOutputGate.issues
260
+ .slice(0, 3)
261
+ .map((issue) => `${issue.phrase}: ${issue.reason}`)
262
+ .join('; '),
263
+ },
264
+ ],
265
+ isError: true,
266
+ structuredContent: {
267
+ error: 'GENERIC_SPEC_OUTPUT_BLOCKED',
268
+ sddConstitutionRuleId: 'sdd.no-generic-output',
269
+ issues: genericOutputGate.issues,
270
+ fixHint: 'Replace generic criteria or placeholder references with grounded, testable behavior before review or approval.',
271
+ },
272
+ },
273
+ qualityWarnings: [],
274
+ };
275
+ }
227
276
  let score;
228
277
  let warnings;
229
278
  let criteriaCount;
@@ -73,9 +73,11 @@ export async function handleValidate(args, server) {
73
73
  const projectPath = knowledge.projectPath;
74
74
  // SPEC-1017: fail closed when planu/ contains non-canonical artifacts.
75
75
  try {
76
- const { runStrictPlanuCleanup, validateStrictPlanuLayout } = await import('../engine/spec-migrator/index.js');
77
- await runStrictPlanuCleanup(projectPath);
78
- const layout = await validateStrictPlanuLayout(projectPath);
76
+ const { validateStrictPlanuLayout } = await import('../engine/spec-migrator/index.js');
77
+ const layout = await validateStrictPlanuLayout(projectPath, {
78
+ specPath: spec.specPath,
79
+ includeRoot: false,
80
+ });
79
81
  if (!layout.ok) {
80
82
  return {
81
83
  content: [
@@ -0,0 +1,8 @@
1
+ export type ActionableSpecMetricName = 'groundingCoverage' | 'verificationCoverage' | 'ambiguityCount' | 'driftRisk';
2
+ export interface ActionableSpecMetric {
3
+ name: ActionableSpecMetricName;
4
+ value: number | 'none' | 'low' | 'medium' | 'high';
5
+ inputs: string[];
6
+ nextAction: string;
7
+ }
8
+ //# sourceMappingURL=actionable-spec-metrics.d.ts.map
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=actionable-spec-metrics.js.map
@@ -54,7 +54,7 @@ export interface EvidenceArtifacts {
54
54
  invalidArtifacts: string[];
55
55
  }
56
56
  export interface EvidenceGateIssue {
57
- code: 'discovery_missing' | 'discovery_unresolved_questions' | 'task_plan_missing' | 'task_plan_uncovered_criteria' | 'traceability_missing' | 'traceability_uncovered_criteria' | 'traceability_incomplete_rows' | 'contract_validation_missing' | 'contract_validation_failed' | 'evidence_artifact_invalid';
57
+ code: 'discovery_missing' | 'discovery_unresolved_questions' | 'task_plan_missing' | 'task_plan_uncovered_criteria' | 'traceability_missing' | 'traceability_uncovered_criteria' | 'traceability_incomplete_rows' | 'contract_validation_missing' | 'contract_validation_failed' | 'done_drift_uncovered_criteria' | 'done_drift_stale_evidence' | 'done_drift_unapproved_scope' | 'evidence_artifact_invalid';
58
58
  message: string;
59
59
  }
60
60
  export interface EvidenceGateResult {
@@ -0,0 +1,24 @@
1
+ export type EvidenceRecordKind = 'scenario' | 'test' | 'contract' | 'manual' | 'changed-file' | 'validation' | 'reviewer';
2
+ export type EvidenceRecordStatus = 'valid' | 'stale' | 'invalid' | 'missing';
3
+ export interface EvidenceRecord {
4
+ kind: EvidenceRecordKind;
5
+ value: string;
6
+ status: EvidenceRecordStatus;
7
+ source: string;
8
+ command?: string;
9
+ passed?: boolean;
10
+ timestamp?: string;
11
+ reason?: string;
12
+ }
13
+ export interface CriterionEvidenceIndexEntry {
14
+ criterion: string;
15
+ criterionKey: string;
16
+ evidence: EvidenceRecord[];
17
+ }
18
+ export interface SpecEvidenceIndex {
19
+ specId: string;
20
+ generatedAt: string;
21
+ criteria: CriterionEvidenceIndexEntry[];
22
+ diagnostics: string[];
23
+ }
24
+ //# sourceMappingURL=evidence-index.d.ts.map
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=evidence-index.js.map
@@ -25,6 +25,8 @@ export * from './migration/index.js';
25
25
  export * from './migration-advanced.js';
26
26
  export * from './privacy.js';
27
27
  export * from './events.js';
28
+ export * from './evidence-gates.js';
29
+ export * from './evidence-index.js';
28
30
  export * from './analytics.js';
29
31
  export * from './sdd-flow.js';
30
32
  export * from './sdd-model-routing.js';
@@ -48,6 +50,7 @@ export * from './dynamic-migration.js';
48
50
  export * from './multi-agent.js';
49
51
  export * from './ai-native.js';
50
52
  export * from './actuals-tracking.js';
53
+ export * from './actionable-spec-metrics.js';
51
54
  export * from './actuals.js';
52
55
  export * from './risk.js';
53
56
  export * from './context-budget.js';
@@ -62,6 +65,7 @@ export * from './webhook.js';
62
65
  export * from './ci.js';
63
66
  export * from './spec-templates.js';
64
67
  export * from './spec-generator.js';
68
+ export * from './spec-grounding.js';
65
69
  export * from './registry.js';
66
70
  export * from './tool-groups.js';
67
71
  export * from './code-transforms.js';
@@ -104,6 +108,7 @@ export * from './legal.js';
104
108
  export * from './mcp-recommendation.js';
105
109
  export * from './approval.js';
106
110
  export * from './scan-project.js';
111
+ export * from './sdd-constitution.js';
107
112
  export * from './import-spec.js';
108
113
  export * from './error-telemetry.js';
109
114
  export * from './audit-trail.js';
@@ -26,6 +26,8 @@ export * from './migration/index.js';
26
26
  export * from './migration-advanced.js';
27
27
  export * from './privacy.js';
28
28
  export * from './events.js';
29
+ export * from './evidence-gates.js';
30
+ export * from './evidence-index.js';
29
31
  export * from './analytics.js';
30
32
  export * from './sdd-flow.js';
31
33
  export * from './sdd-model-routing.js';
@@ -49,6 +51,7 @@ export * from './dynamic-migration.js';
49
51
  export * from './multi-agent.js';
50
52
  export * from './ai-native.js';
51
53
  export * from './actuals-tracking.js';
54
+ export * from './actionable-spec-metrics.js';
52
55
  export * from './actuals.js';
53
56
  export * from './risk.js';
54
57
  export * from './context-budget.js';
@@ -63,6 +66,7 @@ export * from './webhook.js';
63
66
  export * from './ci.js';
64
67
  export * from './spec-templates.js';
65
68
  export * from './spec-generator.js';
69
+ export * from './spec-grounding.js';
66
70
  export * from './registry.js';
67
71
  export * from './tool-groups.js';
68
72
  export * from './code-transforms.js';
@@ -105,6 +109,7 @@ export * from './legal.js';
105
109
  export * from './mcp-recommendation.js';
106
110
  export * from './approval.js';
107
111
  export * from './scan-project.js';
112
+ export * from './sdd-constitution.js';
108
113
  export * from './import-spec.js';
109
114
  export * from './error-telemetry.js';
110
115
  export * from './audit-trail.js';
@@ -0,0 +1,27 @@
1
+ export type SddConstitutionRuleLevel = 'blocking' | 'advisory';
2
+ export interface SddConstitutionRule {
3
+ id: string;
4
+ title: string;
5
+ level: SddConstitutionRuleLevel;
6
+ category: 'grounding' | 'quality' | 'evidence' | 'approval' | 'metrics';
7
+ description: string;
8
+ nextAction: string;
9
+ }
10
+ export interface SddConstitutionOverride {
11
+ ruleId: string;
12
+ level?: SddConstitutionRuleLevel;
13
+ enabled?: boolean;
14
+ rationale: string;
15
+ }
16
+ export interface EffectiveSddConstitutionRule extends SddConstitutionRule {
17
+ enabled: boolean;
18
+ overrideRationale?: string;
19
+ }
20
+ export interface SddConstitutionViolation {
21
+ ruleId: string;
22
+ level: SddConstitutionRuleLevel;
23
+ message: string;
24
+ evidence: string[];
25
+ nextAction: string;
26
+ }
27
+ //# sourceMappingURL=sdd-constitution.d.ts.map
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=sdd-constitution.js.map
@@ -1,6 +1,7 @@
1
1
  import type { Spec } from './spec/core.js';
2
2
  import type { Estimation } from './estimation.js';
3
3
  import type { SpecStatus } from './common/index.js';
4
+ import type { CriterionGroundingRecord, TechnicalReferenceGroundingRecord } from './spec-grounding.js';
4
5
  /** A criterion in the lean spec frontmatter. */
5
6
  export interface LeanCriterion {
6
7
  text: string;
@@ -29,6 +30,12 @@ export interface LeanSpecInput {
29
30
  estimation: Estimation;
30
31
  /** SPEC-461 Phase 3: Extra criteria from autopilot pattern detection. */
31
32
  extraCriteria?: string[];
33
+ /** SPEC-1074: Explicit criteria after grounding filters are applied. */
34
+ criteriaOverride?: LeanCriterion[];
35
+ /** SPEC-1074: Criterion-level grounding records for new specs. */
36
+ groundingCriteria?: CriterionGroundingRecord[];
37
+ /** SPEC-1074: Technical reference grounding records for new specs. */
38
+ groundingTechnicalReferences?: TechnicalReferenceGroundingRecord[];
32
39
  /** SPEC-481: Acceptance criteria format. Defaults to 'checkbox'. */
33
40
  acFormat?: 'checkbox' | 'bdd';
34
41
  }
@@ -47,6 +54,7 @@ export interface PlanuCanonicalPathPolicy {
47
54
  readonly canonicalRootFiles: readonly string[];
48
55
  readonly canonicalRootDirs: readonly string[];
49
56
  readonly canonicalSpecFiles: readonly string[];
57
+ readonly canonicalSpecDirs: readonly string[];
50
58
  readonly forbiddenHostAssetRootDirs: readonly string[];
51
59
  readonly generatedRuntimePatterns: readonly string[];
52
60
  readonly legacyMergeBeforeDeleteFiles: readonly string[];
@@ -61,6 +69,10 @@ export interface StrictPlanuValidationResult {
61
69
  offenders: string[];
62
70
  contract: string;
63
71
  }
72
+ export interface StrictPlanuValidationOptions {
73
+ specPath?: string;
74
+ includeRoot?: boolean;
75
+ }
64
76
  export interface UpdateStatusBatchInput {
65
77
  specIds: string[];
66
78
  status: SpecStatus;
@@ -0,0 +1,22 @@
1
+ export type GroundingSource = 'user_input' | 'project_evidence' | 'documented_assumption' | 'ungrounded_advisory';
2
+ export type GroundingConfidence = 'low' | 'medium' | 'high';
3
+ export interface CriterionGroundingRecord {
4
+ text: string;
5
+ source: GroundingSource;
6
+ evidence: string[];
7
+ confidence: GroundingConfidence;
8
+ }
9
+ export interface TechnicalReferenceGroundingRecord {
10
+ path: string;
11
+ section: 'create' | 'modify' | 'test';
12
+ source: GroundingSource;
13
+ evidence: string[];
14
+ confidence: GroundingConfidence;
15
+ }
16
+ export interface GroundingGateResult {
17
+ passed: boolean;
18
+ required: boolean;
19
+ issues: string[];
20
+ records: CriterionGroundingRecord[];
21
+ }
22
+ //# sourceMappingURL=spec-grounding.d.ts.map
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=spec-grounding.js.map
@@ -35,6 +35,16 @@ export interface SpecQualityReport {
35
35
  risk: QualityDimensionDetail;
36
36
  };
37
37
  }
38
+ export type GenericSpecOutputIssueKind = 'generic-criterion' | 'unsupported-verification' | 'placeholder-reference' | 'generic-technical-reference';
39
+ export interface GenericSpecOutputIssue {
40
+ kind: GenericSpecOutputIssueKind;
41
+ phrase: string;
42
+ reason: string;
43
+ }
44
+ export interface GenericSpecOutputGateResult {
45
+ passed: boolean;
46
+ issues: GenericSpecOutputIssue[];
47
+ }
38
48
  /** A single over-engineering signal detected in a spec. SPEC-485 */
39
49
  export interface ComplexitySignal {
40
50
  type: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@planu/cli",
3
- "version": "4.3.25",
3
+ "version": "4.4.1",
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",
@@ -34,14 +34,14 @@
34
34
  "packageName": "@planu/core"
35
35
  },
36
36
  "optionalDependencies": {
37
- "@planu/core-darwin-arm64": "4.3.25",
38
- "@planu/core-darwin-x64": "4.3.25",
39
- "@planu/core-linux-arm64-gnu": "4.3.25",
40
- "@planu/core-linux-arm64-musl": "4.3.25",
41
- "@planu/core-linux-x64-gnu": "4.3.25",
42
- "@planu/core-linux-x64-musl": "4.3.25",
43
- "@planu/core-win32-arm64-msvc": "4.3.25",
44
- "@planu/core-win32-x64-msvc": "4.3.25"
37
+ "@planu/core-darwin-arm64": "4.4.1",
38
+ "@planu/core-darwin-x64": "4.4.1",
39
+ "@planu/core-linux-arm64-gnu": "4.4.1",
40
+ "@planu/core-linux-arm64-musl": "4.4.1",
41
+ "@planu/core-linux-x64-gnu": "4.4.1",
42
+ "@planu/core-linux-x64-musl": "4.4.1",
43
+ "@planu/core-win32-arm64-msvc": "4.4.1",
44
+ "@planu/core-win32-x64-msvc": "4.4.1"
45
45
  },
46
46
  "engines": {
47
47
  "node": ">=24.0.0"
@@ -185,12 +185,12 @@
185
185
  "@types/node": "^25.9.1",
186
186
  "@vitejs/plugin-vue": "^6.0.7",
187
187
  "@vitest/coverage-v8": "^4.1.8",
188
- "@vue/test-utils": "^2.4.10",
188
+ "@vue/test-utils": "^2.4.11",
189
189
  "eslint": "^10.4.1",
190
190
  "eslint-config-prettier": "^10.1.8",
191
191
  "eslint-import-resolver-typescript": "^4.4.5",
192
192
  "eslint-plugin-import": "^2.32.0",
193
- "happy-dom": "^20.9.0",
193
+ "happy-dom": "^20.10.1",
194
194
  "husky": "^9.1.7",
195
195
  "javascript-obfuscator": "^5.4.3",
196
196
  "knip": "^6.15.0",
package/planu-native.json CHANGED
@@ -1,20 +1,26 @@
1
1
  {
2
2
  "name": "dev.planu.native",
3
3
  "displayName": "Planu Native Lightweight Surface",
4
- "version": "4.3.25",
4
+ "version": "4.4.1",
5
5
  "packageName": "@planu/cli",
6
6
  "modes": {
7
7
  "lightweight": {
8
8
  "requiresMcp": false,
9
9
  "requiresDaemon": false,
10
- "hosts": ["codex", "claude-code"],
10
+ "hosts": [
11
+ "codex",
12
+ "claude-code"
13
+ ],
11
14
  "commands": [
12
15
  {
13
16
  "id": "planu.status",
14
17
  "title": "Project status",
15
18
  "description": "Show the compact Planu project snapshot without loading the MCP tool graph.",
16
19
  "invocation": "planu status",
17
- "hosts": ["codex", "claude-code"],
20
+ "hosts": [
21
+ "codex",
22
+ "claude-code"
23
+ ],
18
24
  "requiresMcp": false,
19
25
  "requiresDaemon": false,
20
26
  "mapsTo": "handlePlanStatus"
@@ -24,7 +30,10 @@
24
30
  "title": "Create spec",
25
31
  "description": "Create a new spec through the CLI-backed SDD contract.",
26
32
  "invocation": "planu spec create \"<title>\"",
27
- "hosts": ["codex", "claude-code"],
33
+ "hosts": [
34
+ "codex",
35
+ "claude-code"
36
+ ],
28
37
  "requiresMcp": false,
29
38
  "requiresDaemon": false,
30
39
  "mapsTo": "handleCreateSpec"
@@ -34,7 +43,10 @@
34
43
  "title": "List specs",
35
44
  "description": "List specs in the current project with optional status/type filters.",
36
45
  "invocation": "planu spec list",
37
- "hosts": ["codex", "claude-code"],
46
+ "hosts": [
47
+ "codex",
48
+ "claude-code"
49
+ ],
38
50
  "requiresMcp": false,
39
51
  "requiresDaemon": false,
40
52
  "mapsTo": "handleListSpecs"
@@ -44,7 +56,10 @@
44
56
  "title": "Validate spec",
45
57
  "description": "Validate a spec against the current codebase from the native CLI surface.",
46
58
  "invocation": "planu spec validate SPEC-001",
47
- "hosts": ["codex", "claude-code"],
59
+ "hosts": [
60
+ "codex",
61
+ "claude-code"
62
+ ],
48
63
  "requiresMcp": false,
49
64
  "requiresDaemon": false,
50
65
  "mapsTo": "handleValidate"
@@ -54,7 +69,10 @@
54
69
  "title": "Audit technical debt",
55
70
  "description": "Run the read-only project audit path for lightweight debt checks.",
56
71
  "invocation": "planu audit debt",
57
- "hosts": ["codex", "claude-code"],
72
+ "hosts": [
73
+ "codex",
74
+ "claude-code"
75
+ ],
58
76
  "requiresMcp": false,
59
77
  "requiresDaemon": false,
60
78
  "mapsTo": "handleAudit"
@@ -64,7 +82,10 @@
64
82
  "title": "Check release readiness",
65
83
  "description": "Check local branch cleanliness and main/develop/release sync readiness.",
66
84
  "invocation": "planu release check",
67
- "hosts": ["codex", "claude-code"],
85
+ "hosts": [
86
+ "codex",
87
+ "claude-code"
88
+ ],
68
89
  "requiresMcp": false,
69
90
  "requiresDaemon": false,
70
91
  "mapsTo": "releaseCommand"
package/planu-plugin.json CHANGED
@@ -2,9 +2,12 @@
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": "4.3.25",
5
+ "version": "4.4.1",
6
6
  "icon": "assets/plugin/icon.svg",
7
- "command": ["npx", "@planu/cli@latest"],
7
+ "command": [
8
+ "npx",
9
+ "@planu/cli@latest"
10
+ ],
8
11
  "packageName": "@planu/cli",
9
12
  "capabilities": {
10
13
  "tools": [
@@ -23,17 +26,42 @@
23
26
  "create_skill",
24
27
  "skill_search"
25
28
  ],
26
- "resources": ["planu://specs/list", "planu://specs/{id}", "planu://project/status", "planu://roadmap"],
27
- "prompts": ["create-spec-from-idea", "review-spec-readiness", "generate-implementation-plan"],
28
- "subagents": ["sdd-orchestrator", "spec-challenger", "test-generator"]
29
+ "resources": [
30
+ "planu://specs/list",
31
+ "planu://specs/{id}",
32
+ "planu://project/status",
33
+ "planu://roadmap"
34
+ ],
35
+ "prompts": [
36
+ "create-spec-from-idea",
37
+ "review-spec-readiness",
38
+ "generate-implementation-plan"
39
+ ],
40
+ "subagents": [
41
+ "sdd-orchestrator",
42
+ "spec-challenger",
43
+ "test-generator"
44
+ ]
29
45
  },
30
46
  "compatibility": {
31
47
  "minimumHostVersion": "1.0.0",
32
- "requiredFeatures": ["mcp-tools", "file-editing"]
48
+ "requiredFeatures": [
49
+ "mcp-tools",
50
+ "file-editing"
51
+ ]
33
52
  },
34
53
  "repository": "https://github.com/planu-dev/planu",
35
54
  "author": "Planu",
36
55
  "license": "MIT",
37
56
  "homepage": "https://planu.dev",
38
- "keywords": ["sdd", "spec-driven-development", "mcp", "specs", "planning", "ai", "bdd", "tdd"]
57
+ "keywords": [
58
+ "sdd",
59
+ "spec-driven-development",
60
+ "mcp",
61
+ "specs",
62
+ "planning",
63
+ "ai",
64
+ "bdd",
65
+ "tdd"
66
+ ]
39
67
  }