@planu/cli 5.1.1 → 5.2.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 +27 -0
- package/dist/cli/commands/doctor.d.ts +22 -0
- package/dist/cli/commands/doctor.js +176 -2
- package/dist/engine/autopilot/bootstrap.js +27 -0
- package/dist/engine/core-bridge.d.ts +28 -0
- package/dist/engine/core-bridge.js +67 -0
- package/dist/engine/drift-monitor.js +16 -18
- package/dist/engine/living-spec/hash-tracker.js +26 -28
- package/dist/engine/planu-core.darwin-arm64.node.manifest.json +7 -7
- package/dist/engine/planu-core.darwin-arm64.node.sbom.json +4 -4
- package/dist/engine/planu-core.darwin-x64.node.manifest.json +7 -7
- package/dist/engine/planu-core.darwin-x64.node.sbom.json +4 -4
- package/dist/engine/planu-core.linux-arm64-gnu.node.manifest.json +7 -7
- package/dist/engine/planu-core.linux-arm64-gnu.node.sbom.json +4 -4
- package/dist/engine/planu-core.linux-arm64-musl.node.manifest.json +7 -7
- package/dist/engine/planu-core.linux-arm64-musl.node.sbom.json +4 -4
- package/dist/engine/planu-core.linux-x64-gnu.node.manifest.json +7 -7
- package/dist/engine/planu-core.linux-x64-gnu.node.sbom.json +4 -4
- package/dist/engine/planu-core.linux-x64-musl.node.manifest.json +7 -7
- package/dist/engine/planu-core.linux-x64-musl.node.sbom.json +4 -4
- package/dist/engine/planu-core.win32-arm64-msvc.node.manifest.json +7 -7
- package/dist/engine/planu-core.win32-arm64-msvc.node.sbom.json +4 -4
- package/dist/engine/planu-core.win32-x64-msvc.node.manifest.json +7 -7
- package/dist/engine/planu-core.win32-x64-msvc.node.sbom.json +4 -4
- package/dist/engine/spec-language/english-only.d.ts +14 -0
- package/dist/engine/spec-language/english-only.js +58 -0
- package/dist/engine/spec-migrator/criteria-scanner.js +11 -13
- package/dist/engine/spec-migrator/drift-detector.js +10 -12
- package/dist/engine/vector-store/tfidf.d.ts +13 -9
- package/dist/engine/vector-store/tfidf.js +26 -0
- package/dist/engine/worker-config-loader.d.ts +1 -1
- package/dist/engine/worker-config-loader.js +1 -11
- package/dist/engine/workers/schema.d.ts +0 -8
- package/dist/engine/workers/schema.js +0 -1
- package/dist/i18n/index.d.ts +18 -0
- package/dist/i18n/index.js +40 -1
- package/dist/storage/global-store.d.ts +9 -0
- package/dist/storage/global-store.js +23 -0
- package/dist/storage/semantic-index-store.d.ts +23 -0
- package/dist/storage/semantic-index-store.js +105 -0
- package/dist/storage/status-store/self-healing.js +15 -17
- package/dist/tools/challenge-spec/scenarios-utils.js +5 -1
- package/dist/tools/create-spec.js +60 -15
- package/dist/tools/init-project/handler.js +78 -25
- package/dist/tools/learn.js +10 -8
- package/dist/tools/registry/auth.js +1 -11
- package/dist/tools/semantic-search-handler.js +5 -6
- package/dist/tools/status-handler.js +19 -6
- package/dist/tools/validation-loop-handler.js +16 -15
- package/dist/types/spec-language-translation.d.ts +18 -0
- package/dist/types/spec-language-translation.js +5 -0
- package/dist/types/spec-registry.d.ts +0 -2
- package/dist/types/status.d.ts +2 -0
- package/dist/types/vector-store.d.ts +18 -0
- package/dist/types/workers.d.ts +0 -3
- package/package.json +9 -9
- package/planu-native.json +8 -29
- package/planu-plugin.json +1 -1
- package/dist/engine/security/cve-refresher.d.ts +0 -12
- package/dist/engine/security/cve-refresher.js +0 -128
|
@@ -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
|