@planu/cli 5.1.1 → 5.3.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 (74) hide show
  1. package/CHANGELOG.md +54 -0
  2. package/dist/cli/commands/doctor.d.ts +22 -0
  3. package/dist/cli/commands/doctor.js +176 -2
  4. package/dist/config/environment-schema.json +161 -21
  5. package/dist/config/release-policy.json +0 -8
  6. package/dist/engine/autopilot/bootstrap.js +27 -0
  7. package/dist/engine/core-bridge.d.ts +28 -0
  8. package/dist/engine/core-bridge.js +67 -0
  9. package/dist/engine/drift-monitor.js +16 -18
  10. package/dist/engine/living-spec/hash-tracker.js +26 -28
  11. package/dist/engine/planu-core.darwin-arm64.node.manifest.json +7 -7
  12. package/dist/engine/planu-core.darwin-arm64.node.sbom.json +4 -4
  13. package/dist/engine/planu-core.darwin-x64.node.manifest.json +7 -7
  14. package/dist/engine/planu-core.darwin-x64.node.sbom.json +4 -4
  15. package/dist/engine/planu-core.linux-arm64-gnu.node.manifest.json +7 -7
  16. package/dist/engine/planu-core.linux-arm64-gnu.node.sbom.json +4 -4
  17. package/dist/engine/planu-core.linux-arm64-musl.node.manifest.json +7 -7
  18. package/dist/engine/planu-core.linux-arm64-musl.node.sbom.json +4 -4
  19. package/dist/engine/planu-core.linux-x64-gnu.node.manifest.json +7 -7
  20. package/dist/engine/planu-core.linux-x64-gnu.node.sbom.json +4 -4
  21. package/dist/engine/planu-core.linux-x64-musl.node.manifest.json +7 -7
  22. package/dist/engine/planu-core.linux-x64-musl.node.sbom.json +4 -4
  23. package/dist/engine/planu-core.win32-arm64-msvc.node.manifest.json +7 -7
  24. package/dist/engine/planu-core.win32-arm64-msvc.node.sbom.json +4 -4
  25. package/dist/engine/planu-core.win32-x64-msvc.node.manifest.json +7 -7
  26. package/dist/engine/planu-core.win32-x64-msvc.node.sbom.json +4 -4
  27. package/dist/engine/spec-language/english-only.d.ts +14 -0
  28. package/dist/engine/spec-language/english-only.js +58 -0
  29. package/dist/engine/spec-migrator/criteria-scanner.js +11 -13
  30. package/dist/engine/spec-migrator/drift-detector.js +10 -12
  31. package/dist/engine/validation/validation-freshness.d.ts +20 -1
  32. package/dist/engine/validation/validation-freshness.js +181 -21
  33. package/dist/engine/validator/analyzer.d.ts +5 -2
  34. package/dist/engine/validator/analyzer.js +81 -23
  35. package/dist/engine/validator/deep-code-checker.d.ts +10 -0
  36. package/dist/engine/validator/deep-code-checker.js +33 -0
  37. package/dist/engine/validator/test-evidence-grounding.d.ts +56 -0
  38. package/dist/engine/validator/test-evidence-grounding.js +187 -0
  39. package/dist/engine/validator.js +15 -4
  40. package/dist/engine/vector-store/tfidf.d.ts +13 -9
  41. package/dist/engine/vector-store/tfidf.js +26 -0
  42. package/dist/engine/worker-config-loader.d.ts +1 -1
  43. package/dist/engine/worker-config-loader.js +1 -11
  44. package/dist/engine/workers/schema.d.ts +0 -8
  45. package/dist/engine/workers/schema.js +0 -1
  46. package/dist/i18n/index.d.ts +18 -0
  47. package/dist/i18n/index.js +40 -1
  48. package/dist/storage/global-store.d.ts +9 -0
  49. package/dist/storage/global-store.js +23 -0
  50. package/dist/storage/semantic-index-store.d.ts +23 -0
  51. package/dist/storage/semantic-index-store.js +105 -0
  52. package/dist/storage/status-store/self-healing.js +15 -17
  53. package/dist/tools/challenge-spec/scenarios-utils.js +5 -1
  54. package/dist/tools/create-spec.js +60 -15
  55. package/dist/tools/init-project/handler.js +78 -25
  56. package/dist/tools/learn.js +10 -8
  57. package/dist/tools/registry/auth.js +1 -11
  58. package/dist/tools/semantic-search-handler.js +5 -6
  59. package/dist/tools/status-handler.js +19 -6
  60. package/dist/tools/validate.js +6 -2
  61. package/dist/tools/validation-loop-handler.js +16 -15
  62. package/dist/types/analysis.d.ts +2 -0
  63. package/dist/types/spec-language-translation.d.ts +18 -0
  64. package/dist/types/spec-language-translation.js +5 -0
  65. package/dist/types/spec-registry.d.ts +0 -2
  66. package/dist/types/status.d.ts +2 -0
  67. package/dist/types/validation-receipt.d.ts +7 -0
  68. package/dist/types/vector-store.d.ts +18 -0
  69. package/dist/types/workers.d.ts +0 -3
  70. package/package.json +20 -20
  71. package/planu-native.json +8 -29
  72. package/planu-plugin.json +1 -1
  73. package/dist/engine/security/cve-refresher.d.ts +0 -12
  74. package/dist/engine/security/cve-refresher.js +0 -128
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": "5.1.1",
4
+ "version": "5.3.0",
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-first release readiness, branch cleanliness, and optional gitflow drift.",
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,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.1.1",
5
+ "version": "5.3.0",
6
6
  "icon": "assets/plugin/icon.svg",
7
7
  "command": ["npx", "@planu/cli@latest"],
8
8
  "packageName": "@planu/cli",
@@ -1,12 +0,0 @@
1
- import type { StalenessInfo } from '../../types/security/index.js';
2
- export type { StalenessInfo };
3
- export declare const CVE_DB_PATH: string;
4
- /** Check if known-cves.json is older than 7 days. */
5
- export declare function isCveDatabaseStale(): Promise<StalenessInfo>;
6
- /**
7
- * Refresh known-cves.json from OSV.dev for the given ecosystems.
8
- * Queries each package already in the database to get up-to-date CVE data.
9
- * Writes updated JSON via atomicWriteFile. Records refresh in cve-refresh-log.json.
10
- */
11
- export declare function refreshCveDatabase(ecosystems: string[]): Promise<void>;
12
- //# sourceMappingURL=cve-refresher.d.ts.map
@@ -1,128 +0,0 @@
1
- // engine/security/cve-refresher.ts — SPEC-773
2
- // Auto-refresh known-cves.json from OSV.dev public API.
3
- import { stat, readFile, mkdir } from 'node:fs/promises';
4
- import { resolve, dirname } from 'node:path';
5
- import { fileURLToPath } from 'node:url';
6
- import { atomicWriteFile } from '../safety/atomic-write-file.js';
7
- import { globalDataDir } from '../../storage/base-store.js';
8
- const MODULE_DIR = dirname(fileURLToPath(import.meta.url));
9
- export const CVE_DB_PATH = resolve(MODULE_DIR, '../../config/known-cves.json');
10
- const OSV_API = 'https://api.osv.dev/v1/query';
11
- const STALE_THRESHOLD_MS = 7 * 24 * 60 * 60 * 1000;
12
- /** Check if known-cves.json is older than 7 days. */
13
- export async function isCveDatabaseStale() {
14
- try {
15
- const s = await stat(CVE_DB_PATH);
16
- const ageMs = Date.now() - s.mtimeMs;
17
- return { stale: ageMs > STALE_THRESHOLD_MS, ageDays: Math.floor(ageMs / 86400000) };
18
- }
19
- catch {
20
- return { stale: true, ageDays: 999 };
21
- }
22
- }
23
- function toEntry(vuln, pkgName, ecosystem) {
24
- const cveId = vuln.aliases?.find((a) => a.startsWith('CVE-'));
25
- if (!cveId) {
26
- return null;
27
- }
28
- let fixVersion;
29
- outer: for (const aff of vuln.affected ?? []) {
30
- for (const range of aff.ranges ?? []) {
31
- for (const ev of range.events ?? []) {
32
- if (ev.fixed) {
33
- fixVersion = ev.fixed;
34
- break outer;
35
- }
36
- }
37
- }
38
- }
39
- const score = parseFloat(vuln.affected?.[0]?.severity?.[0]?.score ?? '0');
40
- const severity = score >= 7 ? 'critical' : 'warning';
41
- return {
42
- package: pkgName,
43
- ecosystem,
44
- affectedVersions: fixVersion ? `<${fixVersion}` : 'unknown',
45
- cveId,
46
- severity,
47
- description: vuln.summary ?? '',
48
- ...(fixVersion ? { fixVersion } : {}),
49
- };
50
- }
51
- /**
52
- * Refresh known-cves.json from OSV.dev for the given ecosystems.
53
- * Queries each package already in the database to get up-to-date CVE data.
54
- * Writes updated JSON via atomicWriteFile. Records refresh in cve-refresh-log.json.
55
- */
56
- export async function refreshCveDatabase(ecosystems) {
57
- let currentDb;
58
- try {
59
- const raw = await readFile(CVE_DB_PATH, 'utf-8');
60
- currentDb = JSON.parse(raw);
61
- }
62
- catch {
63
- currentDb = { lastUpdated: '', vulnerabilities: [] };
64
- }
65
- // Build package list per ecosystem for ecosystems being refreshed (AC-5: ecosystem-scoped)
66
- const byEcosystem = new Map();
67
- for (const vuln of currentDb.vulnerabilities) {
68
- if (!ecosystems.includes(vuln.ecosystem)) {
69
- continue;
70
- }
71
- const set = byEcosystem.get(vuln.ecosystem) ?? new Set();
72
- set.add(vuln.package);
73
- byEcosystem.set(vuln.ecosystem, set);
74
- }
75
- // Query OSV.dev per package with ecosystem filter (not a generic all-ecosystems fetch)
76
- const freshVulns = [];
77
- for (const [ecosystem, packages] of byEcosystem) {
78
- for (const pkgName of packages) {
79
- try {
80
- const resp = await fetch(OSV_API, {
81
- method: 'POST',
82
- headers: { 'Content-Type': 'application/json' },
83
- body: JSON.stringify({ package: { name: pkgName, ecosystem } }),
84
- });
85
- if (!resp.ok) {
86
- continue;
87
- }
88
- const data = (await resp.json());
89
- for (const vuln of data.vulns ?? []) {
90
- const entry = toEntry(vuln, pkgName, ecosystem);
91
- if (entry) {
92
- freshVulns.push(entry);
93
- }
94
- }
95
- }
96
- catch {
97
- // per-package error — skip and continue
98
- }
99
- }
100
- }
101
- // Preserve untouched ecosystems; replace refreshed ones with fresh data (or keep stale if
102
- // OSV returned nothing new for that ecosystem)
103
- const untouched = currentDb.vulnerabilities.filter((v) => !ecosystems.includes(v.ecosystem));
104
- const refreshedEcos = new Set(freshVulns.map((v) => v.ecosystem));
105
- const staleKept = currentDb.vulnerabilities.filter((v) => ecosystems.includes(v.ecosystem) && !refreshedEcos.has(v.ecosystem));
106
- const merged = [...untouched, ...staleKept, ...freshVulns];
107
- const updatedDb = {
108
- lastUpdated: new Date().toISOString().slice(0, 10),
109
- vulnerabilities: merged,
110
- };
111
- await atomicWriteFile(CVE_DB_PATH, JSON.stringify(updatedDb, null, 2));
112
- // Write refresh log (best-effort — non-fatal)
113
- try {
114
- const dir = globalDataDir();
115
- await mkdir(dir, { recursive: true });
116
- const log = {
117
- refreshedAt: new Date().toISOString(),
118
- source: 'osv.dev',
119
- ecosystems,
120
- entryCount: merged.length,
121
- };
122
- await atomicWriteFile(`${dir}/cve-refresh-log.json`, JSON.stringify(log, null, 2));
123
- }
124
- catch {
125
- // log write failure is non-fatal
126
- }
127
- }
128
- //# sourceMappingURL=cve-refresher.js.map