@planu/cli 4.4.1 → 4.4.2

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 CHANGED
@@ -1,3 +1,9 @@
1
+ ## [4.4.2] - 2026-06-05
2
+
3
+ ### Bug Fixes
4
+ - fix: keep spec folders spec.md-only and store evidence externally
5
+
6
+
1
7
  ## [4.4.1] - 2026-06-04
2
8
 
3
9
  ### Bug Fixes
@@ -4029,4 +4035,4 @@ Format: [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) · Versioning:
4029
4035
  - Mermaid diagram generation (architecture, sequence, state machine, ER, data flow)
4030
4036
  - Multi-language i18n (EN/ES/PT) for generated specs
4031
4037
  - Clean Architecture (hexagonal) — engine, tools, storage, types layers
4032
- - 10,857 tests with ≥95% coverage
4038
+ - 10,857 tests with ≥95% coverage
@@ -1,5 +1,5 @@
1
1
  import { readFile } from 'node:fs/promises';
2
- import { dirname, isAbsolute, join } from 'node:path';
2
+ import { join } from 'node:path';
3
3
  import { z } from 'zod';
4
4
  import { projectDataDir } from '../../storage/base-store.js';
5
5
  const DiscoverySchema = z.object({
@@ -49,20 +49,6 @@ const ContractValidationSchema = z.object({
49
49
  reportPath: z.string().optional(),
50
50
  summary: z.string().optional(),
51
51
  });
52
- function resolveSpecPath(spec, projectPath) {
53
- const specPath = spec.specPath;
54
- if (!specPath?.trim()) {
55
- return null;
56
- }
57
- if (isAbsolute(specPath) || !projectPath) {
58
- return specPath;
59
- }
60
- return join(projectPath, specPath);
61
- }
62
- function specEvidencePath(spec, filename, projectPath) {
63
- const specPath = resolveSpecPath(spec, projectPath);
64
- return specPath ? join(dirname(specPath), 'evidence', filename) : null;
65
- }
66
52
  function handoffEvidencePath(projectId, specId, filename) {
67
53
  return join(projectDataDir(projectId), 'handoffs', specId, filename);
68
54
  }
@@ -108,28 +94,19 @@ export async function readEvidenceArtifacts(args) {
108
94
  label: 'Discovery evidence',
109
95
  invalidArtifacts,
110
96
  schema: DiscoverySchema,
111
- paths: [
112
- specEvidencePath(args.spec, 'discovery.json', args.projectPath),
113
- handoffEvidencePath(args.projectId, args.specId, 'discovery.json'),
114
- ],
97
+ paths: [handoffEvidencePath(args.projectId, args.specId, 'discovery.json')],
115
98
  });
116
99
  const taskPlan = await readOptional({
117
100
  label: 'Task plan evidence',
118
101
  invalidArtifacts,
119
102
  schema: TaskPlanSchema,
120
- paths: [
121
- specEvidencePath(args.spec, 'task-plan.json', args.projectPath),
122
- handoffEvidencePath(args.projectId, args.specId, 'task-plan.json'),
123
- ],
103
+ paths: [handoffEvidencePath(args.projectId, args.specId, 'task-plan.json')],
124
104
  });
125
105
  const traceabilityMatrix = await readOptional({
126
106
  label: 'Traceability matrix evidence',
127
107
  invalidArtifacts,
128
108
  schema: TraceabilityMatrixSchema,
129
- paths: [
130
- specEvidencePath(args.spec, 'traceability-matrix.json', args.projectPath),
131
- handoffEvidencePath(args.projectId, args.specId, 'traceability-matrix.json'),
132
- ],
109
+ paths: [handoffEvidencePath(args.projectId, args.specId, 'traceability-matrix.json')],
133
110
  });
134
111
  const contractValidations = [];
135
112
  for (const filename of [
@@ -143,10 +120,7 @@ export async function readEvidenceArtifacts(args) {
143
120
  label: filename,
144
121
  invalidArtifacts,
145
122
  schema: ContractValidationSchema,
146
- paths: [
147
- specEvidencePath(args.spec, filename, args.projectPath),
148
- handoffEvidencePath(args.projectId, args.specId, filename),
149
- ],
123
+ paths: [handoffEvidencePath(args.projectId, args.specId, filename)],
150
124
  });
151
125
  if (evidence) {
152
126
  contractValidations.push(evidence);
@@ -4,7 +4,7 @@ export const PLANU_CANONICAL_POLICY = {
4
4
  canonicalRootFiles: ['conventions.json', 'context.md', 'session-context.md', 'session.json'],
5
5
  canonicalRootDirs: ['releases', 'specs'],
6
6
  canonicalSpecFiles: ['spec.md'],
7
- canonicalSpecDirs: ['evidence'],
7
+ canonicalSpecDirs: [],
8
8
  forbiddenHostAssetRootDirs: ['agents', 'skills', 'rules', 'hooks'],
9
9
  generatedRuntimePatterns: [
10
10
  'planu/index.html',
@@ -71,8 +71,8 @@ export function canonicalContractText() {
71
71
  ' specs/',
72
72
  ' SPEC-XXX-slug/',
73
73
  ' spec.md',
74
- ' evidence/',
75
- ' *.json',
74
+ '',
75
+ 'Evidence artifacts are Planu runtime data and are stored outside planu/specs/.',
76
76
  '',
77
77
  'Host adapters are written outside planu/:',
78
78
  ' Claude Code: .claude/agents, .claude/skills, .claude/rules',
@@ -28,7 +28,7 @@ For non-trivial specs, Planu blocks lifecycle transitions unless evidence is pre
28
28
  | done | Traceability matrix covering every acceptance criterion |
29
29
  | done for API/UI/event/MCP work | Passing contract validation evidence |
30
30
 
31
- Evidence can live under \`planu/specs/<spec>/evidence/\` or the external Planu handoff store. Trivial specs may use lightweight evidence, but \`done\` still needs at least one traceability row.
31
+ Evidence lives in the external Planu handoff store, not under \`planu/specs/<spec>/\`. Spec folders remain \`spec.md\`-only. Trivial specs may use lightweight evidence, but \`done\` still needs at least one traceability row.
32
32
 
33
33
  ## When to use \`facilitate\`
34
34
 
@@ -80,7 +80,7 @@ function evidenceGateError(args) {
80
80
  transition: args.transition,
81
81
  issues: args.issues,
82
82
  requiredContractKinds: args.requiredContractKinds,
83
- fixHint: 'Add the missing evidence artifact under planu/specs/<spec>/evidence/ or external Planu project data handoffs/<specId>/, then retry the transition.',
83
+ fixHint: 'Add the missing evidence artifact to the external Planu project data handoff store, then retry the transition. Do not create JSON files under planu/specs/<spec>/.',
84
84
  }, null, 2),
85
85
  },
86
86
  ],
@@ -95,7 +95,7 @@ function evidenceGateError(args) {
95
95
  issues: args.issues,
96
96
  requiredContractKinds: args.requiredContractKinds,
97
97
  },
98
- fixHint: 'Add discovery.json, task-plan.json, traceability-matrix.json, and contract-validation-*.json as required for this transition.',
98
+ fixHint: 'Add discovery.json, task-plan.json, traceability-matrix.json, and contract-validation-*.json to the external Planu handoff store as required for this transition. Spec folders remain spec.md-only.',
99
99
  },
100
100
  };
101
101
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@planu/cli",
3
- "version": "4.4.1",
3
+ "version": "4.4.2",
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.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"
37
+ "@planu/core-darwin-arm64": "4.4.2",
38
+ "@planu/core-darwin-x64": "4.4.2",
39
+ "@planu/core-linux-arm64-gnu": "4.4.2",
40
+ "@planu/core-linux-arm64-musl": "4.4.2",
41
+ "@planu/core-linux-x64-gnu": "4.4.2",
42
+ "@planu/core-linux-x64-musl": "4.4.2",
43
+ "@planu/core-win32-arm64-msvc": "4.4.2",
44
+ "@planu/core-win32-x64-msvc": "4.4.2"
45
45
  },
46
46
  "engines": {
47
47
  "node": ">=24.0.0"
package/planu-native.json CHANGED
@@ -1,26 +1,20 @@
1
1
  {
2
2
  "name": "dev.planu.native",
3
3
  "displayName": "Planu Native Lightweight Surface",
4
- "version": "4.4.1",
4
+ "version": "4.4.2",
5
5
  "packageName": "@planu/cli",
6
6
  "modes": {
7
7
  "lightweight": {
8
8
  "requiresMcp": false,
9
9
  "requiresDaemon": false,
10
- "hosts": [
11
- "codex",
12
- "claude-code"
13
- ],
10
+ "hosts": ["codex", "claude-code"],
14
11
  "commands": [
15
12
  {
16
13
  "id": "planu.status",
17
14
  "title": "Project status",
18
15
  "description": "Show the compact Planu project snapshot without loading the MCP tool graph.",
19
16
  "invocation": "planu status",
20
- "hosts": [
21
- "codex",
22
- "claude-code"
23
- ],
17
+ "hosts": ["codex", "claude-code"],
24
18
  "requiresMcp": false,
25
19
  "requiresDaemon": false,
26
20
  "mapsTo": "handlePlanStatus"
@@ -30,10 +24,7 @@
30
24
  "title": "Create spec",
31
25
  "description": "Create a new spec through the CLI-backed SDD contract.",
32
26
  "invocation": "planu spec create \"<title>\"",
33
- "hosts": [
34
- "codex",
35
- "claude-code"
36
- ],
27
+ "hosts": ["codex", "claude-code"],
37
28
  "requiresMcp": false,
38
29
  "requiresDaemon": false,
39
30
  "mapsTo": "handleCreateSpec"
@@ -43,10 +34,7 @@
43
34
  "title": "List specs",
44
35
  "description": "List specs in the current project with optional status/type filters.",
45
36
  "invocation": "planu spec list",
46
- "hosts": [
47
- "codex",
48
- "claude-code"
49
- ],
37
+ "hosts": ["codex", "claude-code"],
50
38
  "requiresMcp": false,
51
39
  "requiresDaemon": false,
52
40
  "mapsTo": "handleListSpecs"
@@ -56,10 +44,7 @@
56
44
  "title": "Validate spec",
57
45
  "description": "Validate a spec against the current codebase from the native CLI surface.",
58
46
  "invocation": "planu spec validate SPEC-001",
59
- "hosts": [
60
- "codex",
61
- "claude-code"
62
- ],
47
+ "hosts": ["codex", "claude-code"],
63
48
  "requiresMcp": false,
64
49
  "requiresDaemon": false,
65
50
  "mapsTo": "handleValidate"
@@ -69,10 +54,7 @@
69
54
  "title": "Audit technical debt",
70
55
  "description": "Run the read-only project audit path for lightweight debt checks.",
71
56
  "invocation": "planu audit debt",
72
- "hosts": [
73
- "codex",
74
- "claude-code"
75
- ],
57
+ "hosts": ["codex", "claude-code"],
76
58
  "requiresMcp": false,
77
59
  "requiresDaemon": false,
78
60
  "mapsTo": "handleAudit"
@@ -82,10 +64,7 @@
82
64
  "title": "Check release readiness",
83
65
  "description": "Check local branch cleanliness and main/develop/release sync readiness.",
84
66
  "invocation": "planu release check",
85
- "hosts": [
86
- "codex",
87
- "claude-code"
88
- ],
67
+ "hosts": ["codex", "claude-code"],
89
68
  "requiresMcp": false,
90
69
  "requiresDaemon": false,
91
70
  "mapsTo": "releaseCommand"
package/planu-plugin.json CHANGED
@@ -2,12 +2,9 @@
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.4.1",
5
+ "version": "4.4.2",
6
6
  "icon": "assets/plugin/icon.svg",
7
- "command": [
8
- "npx",
9
- "@planu/cli@latest"
10
- ],
7
+ "command": ["npx", "@planu/cli@latest"],
11
8
  "packageName": "@planu/cli",
12
9
  "capabilities": {
13
10
  "tools": [
@@ -26,42 +23,17 @@
26
23
  "create_skill",
27
24
  "skill_search"
28
25
  ],
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
- ]
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"]
45
29
  },
46
30
  "compatibility": {
47
31
  "minimumHostVersion": "1.0.0",
48
- "requiredFeatures": [
49
- "mcp-tools",
50
- "file-editing"
51
- ]
32
+ "requiredFeatures": ["mcp-tools", "file-editing"]
52
33
  },
53
34
  "repository": "https://github.com/planu-dev/planu",
54
35
  "author": "Planu",
55
36
  "license": "MIT",
56
37
  "homepage": "https://planu.dev",
57
- "keywords": [
58
- "sdd",
59
- "spec-driven-development",
60
- "mcp",
61
- "specs",
62
- "planning",
63
- "ai",
64
- "bdd",
65
- "tdd"
66
- ]
38
+ "keywords": ["sdd", "spec-driven-development", "mcp", "specs", "planning", "ai", "bdd", "tdd"]
67
39
  }