@planu/cli 5.3.27 → 5.3.28
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 +6 -0
- package/dist/cli/commands/doctor.d.ts +4 -10
- package/dist/cli/commands/doctor.js +5 -31
- package/dist/cli/commands/inspect.js +2 -14
- package/dist/cli/commands/offline.d.ts +1 -2
- package/dist/cli/commands/offline.js +24 -41
- package/dist/config/release-policy.json +1 -79
- package/dist/engine/auto-updater/release-verifier.js +17 -35
- package/dist/engine/core-bridge.d.ts +6 -23
- package/dist/engine/core-bridge.js +35 -376
- package/dist/engine/execution/job-runtime.d.ts +0 -11
- package/dist/engine/execution/job-runtime.js +0 -23
- package/dist/engine/living-spec/annotation-parser.js +0 -14
- package/dist/engine/project-graph/native.js +2 -2
- package/dist/engine/sandbox/profiles/macos.sb +33 -0
- package/dist/engine/scan-project/module-discoverer.js +10 -53
- package/dist/engine/validation/validation-receipt.d.ts +5 -0
- package/dist/engine/validation/validation-receipt.js +9 -1
- package/dist/engine/validator/deep-code-checker.js +19 -26
- package/dist/security/adapters/macos-keychain.d.ts +5 -3
- package/dist/security/adapters/macos-keychain.js +46 -20
- package/dist/tools/create-spec/autopilot-analyzer.d.ts +1 -1
- package/dist/tools/create-spec/autopilot-analyzer.js +2 -2
- package/dist/tools/create-spec/relevance-scorer.d.ts +1 -1
- package/dist/tools/create-spec/relevance-scorer.js +1 -17
- package/dist/tools/create-spec.js +1 -1
- package/dist/types/atomic-upgrade.d.ts +0 -2
- package/dist/types/core-bridge.d.ts +0 -108
- package/dist/types/core-bridge.js +1 -1
- package/dist/types/durable-job.d.ts +0 -40
- package/dist/types/security.d.ts +0 -5
- package/package.json +7 -43
- package/planu-plugin.json +1 -1
- package/dist/config/native-release-public-key.pem +0 -3
- package/dist/config/native-targets.json +0 -87
- package/dist/engine/execution/job-executor.d.ts +0 -16
- package/dist/engine/execution/job-executor.js +0 -140
- package/dist/engine/execution/native-relevance-scorer.d.ts +0 -6
- package/dist/engine/execution/native-relevance-scorer.js +0 -64
- package/dist/engine/execution/native-worker-dispatch.d.ts +0 -3
- package/dist/engine/execution/native-worker-dispatch.js +0 -46
- package/dist/engine/execution/native-worker-protocol.d.ts +0 -6
- package/dist/engine/execution/native-worker-protocol.js +0 -33
- package/dist/engine/execution/native-worker-runtime.d.ts +0 -4
- package/dist/engine/execution/native-worker-runtime.js +0 -177
- package/dist/engine/execution/native-worker-thread.d.ts +0 -2
- package/dist/engine/execution/native-worker-thread.js +0 -66
- package/dist/engine/macos-keychain-native-port.d.ts +0 -10
- package/dist/engine/macos-keychain-native-port.js +0 -64
- package/dist/engine/native-capability-policy.d.ts +0 -4
- package/dist/engine/native-capability-policy.js +0 -24
- package/dist/engine/native-platform.d.ts +0 -3
- package/dist/engine/native-platform.js +0 -44
- package/dist/engine/native-runtime-handshake.d.ts +0 -20
- package/dist/engine/native-runtime-handshake.js +0 -230
- package/dist/engine/planu-core.darwin-arm64.node.manifest.json +0 -39
- package/dist/engine/planu-core.darwin-arm64.node.sbom.json +0 -1310
- package/dist/engine/planu-core.darwin-x64.node.manifest.json +0 -39
- package/dist/engine/planu-core.darwin-x64.node.sbom.json +0 -1310
- package/dist/engine/planu-core.linux-arm64-gnu.node.manifest.json +0 -38
- package/dist/engine/planu-core.linux-arm64-gnu.node.sbom.json +0 -1310
- package/dist/engine/planu-core.linux-arm64-musl.node.manifest.json +0 -38
- package/dist/engine/planu-core.linux-arm64-musl.node.sbom.json +0 -1310
- package/dist/engine/planu-core.linux-x64-gnu.node.manifest.json +0 -38
- package/dist/engine/planu-core.linux-x64-gnu.node.sbom.json +0 -1310
- package/dist/engine/planu-core.linux-x64-musl.node.manifest.json +0 -38
- package/dist/engine/planu-core.linux-x64-musl.node.sbom.json +0 -1310
- package/dist/engine/planu-core.win32-arm64-msvc.node.manifest.json +0 -38
- package/dist/engine/planu-core.win32-arm64-msvc.node.sbom.json +0 -1310
- package/dist/engine/planu-core.win32-x64-msvc.node.manifest.json +0 -38
- package/dist/engine/planu-core.win32-x64-msvc.node.sbom.json +0 -1310
- package/dist/types/native-worker.d.ts +0 -48
- package/dist/types/native-worker.js +0 -2
- package/planu-native.json +0 -82
package/CHANGELOG.md
CHANGED
|
@@ -19,20 +19,14 @@ interface DeepCheckResult {
|
|
|
19
19
|
declare function checkTool(check: ToolCheck): ToolReport[];
|
|
20
20
|
/** Check (1): the running Node version satisfies the `engines.node` field in package.json. */
|
|
21
21
|
declare function checkNodeVersion(): DeepCheckResult;
|
|
22
|
-
/**
|
|
23
|
-
* Check (2): the native Rust module loads, with a remediation hint when it doesn't.
|
|
24
|
-
* Missing native is a supported degraded mode (TypeScript fallback stays correct), so
|
|
25
|
-
* this reports 'warn' rather than 'fail' — it never blocks `planu doctor`'s exit code.
|
|
26
|
-
*/
|
|
27
|
-
declare function checkNativeModule(): DeepCheckResult;
|
|
28
|
-
/** Check (3): PLANU_HOME / the resolved data directory is writable. */
|
|
22
|
+
/** Check (2): PLANU_HOME / the resolved data directory is writable. */
|
|
29
23
|
declare function checkDataDirWritable(): DeepCheckResult;
|
|
30
|
-
/** Check (
|
|
24
|
+
/** Check (3): the runtime SQLite database opens without corruption. */
|
|
31
25
|
declare function checkRuntimeDatabase(): DeepCheckResult;
|
|
32
|
-
/** Check (
|
|
26
|
+
/** Check (4): the active locale resolves to a real translated message. */
|
|
33
27
|
declare function checkLocaleResolution(): DeepCheckResult;
|
|
34
28
|
declare function runDeepChecks(): DeepCheckResult[];
|
|
35
|
-
export { checkNodeVersion,
|
|
29
|
+
export { checkNodeVersion, checkDataDirWritable, checkRuntimeDatabase, checkLocaleResolution, runDeepChecks, };
|
|
36
30
|
export { checkTool };
|
|
37
31
|
export declare const doctorCommand: CliCommand;
|
|
38
32
|
//# sourceMappingURL=doctor.d.ts.map
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// cli/commands/doctor.ts — planu doctor: verify MCP installations health (SPEC-236)
|
|
2
|
-
// Deep diagnostics (Node version,
|
|
2
|
+
// Deep diagnostics (Node version, storage writability, runtime DB,
|
|
3
3
|
// locale resolution) added by SPEC-1346 / SPEC-1344.
|
|
4
4
|
import { existsSync, mkdirSync, readFileSync, unlinkSync, writeFileSync } from 'node:fs';
|
|
5
5
|
import { homedir } from 'node:os';
|
|
@@ -9,7 +9,6 @@ import { bold, cyan, green, yellow, red, dim } from '../colors.js';
|
|
|
9
9
|
import { readJsonFile, hasPlanuEntry } from './install.js';
|
|
10
10
|
import { resolveStorageLayout } from '../../storage/storage-layout.js';
|
|
11
11
|
import { RuntimeDatabase } from '../../storage/runtime-db.js';
|
|
12
|
-
import { probeNativeLoad } from '../../engine/core-bridge.js';
|
|
13
12
|
import { getLocale, t } from '../../i18n/index.js';
|
|
14
13
|
// ---------------------------------------------------------------------------
|
|
15
14
|
// Constants
|
|
@@ -144,31 +143,7 @@ function checkNodeVersion() {
|
|
|
144
143
|
detail: `${process.version} does not satisfy required range ${requiredRange}. Upgrade Node to continue.`,
|
|
145
144
|
};
|
|
146
145
|
}
|
|
147
|
-
/**
|
|
148
|
-
* Check (2): the native Rust module loads, with a remediation hint when it doesn't.
|
|
149
|
-
* Missing native is a supported degraded mode (TypeScript fallback stays correct), so
|
|
150
|
-
* this reports 'warn' rather than 'fail' — it never blocks `planu doctor`'s exit code.
|
|
151
|
-
*/
|
|
152
|
-
function checkNativeModule() {
|
|
153
|
-
if (process.env.DISABLE_NATIVE_CORE === '1') {
|
|
154
|
-
return {
|
|
155
|
-
name: 'Native engine',
|
|
156
|
-
status: 'ok',
|
|
157
|
-
detail: 'Disabled via DISABLE_NATIVE_CORE=1 (TypeScript fallback in use)',
|
|
158
|
-
};
|
|
159
|
-
}
|
|
160
|
-
const diagnostic = probeNativeLoad();
|
|
161
|
-
if (diagnostic.loaded) {
|
|
162
|
-
return { name: 'Native engine', status: 'ok', detail: `Loaded (${diagnostic.loaded})` };
|
|
163
|
-
}
|
|
164
|
-
const reason = diagnostic.errors[0] ?? 'unknown failure';
|
|
165
|
-
return {
|
|
166
|
-
name: 'Native engine',
|
|
167
|
-
status: 'warn',
|
|
168
|
-
detail: `Failed to load (${reason}). Running on the TypeScript fallback. Reinstall the platform package for your OS/arch to restore native acceleration.`,
|
|
169
|
-
};
|
|
170
|
-
}
|
|
171
|
-
/** Check (3): PLANU_HOME / the resolved data directory is writable. */
|
|
146
|
+
/** Check (2): PLANU_HOME / the resolved data directory is writable. */
|
|
172
147
|
function checkDataDirWritable() {
|
|
173
148
|
const layout = resolveStorageLayout();
|
|
174
149
|
const probePath = join(layout.data, `.doctor-write-probe-${String(process.pid)}`);
|
|
@@ -187,7 +162,7 @@ function checkDataDirWritable() {
|
|
|
187
162
|
};
|
|
188
163
|
}
|
|
189
164
|
}
|
|
190
|
-
/** Check (
|
|
165
|
+
/** Check (3): the runtime SQLite database opens without corruption. */
|
|
191
166
|
function checkRuntimeDatabase() {
|
|
192
167
|
const layout = resolveStorageLayout();
|
|
193
168
|
try {
|
|
@@ -208,7 +183,7 @@ function checkRuntimeDatabase() {
|
|
|
208
183
|
};
|
|
209
184
|
}
|
|
210
185
|
}
|
|
211
|
-
/** Check (
|
|
186
|
+
/** Check (4): the active locale resolves to a real translated message. */
|
|
212
187
|
function checkLocaleResolution() {
|
|
213
188
|
const locale = getLocale();
|
|
214
189
|
const sample = t('locale.changed', locale);
|
|
@@ -224,7 +199,6 @@ function checkLocaleResolution() {
|
|
|
224
199
|
function runDeepChecks() {
|
|
225
200
|
return [
|
|
226
201
|
checkNodeVersion(),
|
|
227
|
-
checkNativeModule(),
|
|
228
202
|
checkDataDirWritable(),
|
|
229
203
|
checkRuntimeDatabase(),
|
|
230
204
|
checkLocaleResolution(),
|
|
@@ -252,7 +226,7 @@ function printDeepChecks(results) {
|
|
|
252
226
|
}
|
|
253
227
|
}
|
|
254
228
|
// Exported for tests
|
|
255
|
-
export { checkNodeVersion,
|
|
229
|
+
export { checkNodeVersion, checkDataDirWritable, checkRuntimeDatabase, checkLocaleResolution, runDeepChecks, };
|
|
256
230
|
function statusIcon(status) {
|
|
257
231
|
switch (status) {
|
|
258
232
|
case 'ok':
|
|
@@ -5,7 +5,7 @@ import { homedir } from 'node:os';
|
|
|
5
5
|
import { PLANU_VERSION } from '../../config/version.js';
|
|
6
6
|
import { createStorageCatalog } from '../../storage/storage-catalog.js';
|
|
7
7
|
import { resolveStorageLayout } from '../../storage/storage-layout.js';
|
|
8
|
-
import {
|
|
8
|
+
import { RUNTIME_STORAGE_SCHEMA } from '../../engine/core-bridge.js';
|
|
9
9
|
import { readInstallationManifest } from './install.js';
|
|
10
10
|
import { getProjects } from '../../storage/global-projects-store.js';
|
|
11
11
|
async function inspectPath(path) {
|
|
@@ -96,23 +96,11 @@ export async function buildInspectionReport() {
|
|
|
96
96
|
path: portablePath(path),
|
|
97
97
|
exists: (await inspectPath(path)).exists,
|
|
98
98
|
})));
|
|
99
|
-
const native = nativeLoadDiagnostic();
|
|
100
|
-
const displayArtifact = (value) => isAbsolute(value) ? `<local>/${basename(value)}` : value;
|
|
101
99
|
return {
|
|
102
100
|
schemaVersion: 1,
|
|
103
101
|
cliVersion: PLANU_VERSION,
|
|
104
102
|
offline: process.env.PLANU_OFFLINE === '1',
|
|
105
|
-
|
|
106
|
-
loaded: native.loaded ? displayArtifact(native.loaded) : null,
|
|
107
|
-
compatibility: native.compatibility ?? null,
|
|
108
|
-
attempted: native.attempted.map(displayArtifact),
|
|
109
|
-
errorCount: native.errors.length,
|
|
110
|
-
capabilities: native.capabilities ?? [],
|
|
111
|
-
executionScope: native.executionScope ?? null,
|
|
112
|
-
protocolAbi: NATIVE_PROTOCOL_ABI,
|
|
113
|
-
capabilityAbi: NATIVE_CAPABILITY_ABI,
|
|
114
|
-
storageSchema: RUNTIME_STORAGE_SCHEMA,
|
|
115
|
-
},
|
|
103
|
+
storageSchema: RUNTIME_STORAGE_SCHEMA,
|
|
116
104
|
installation,
|
|
117
105
|
hostAdapters: installation && typeof installation === 'object' && 'installations' in installation
|
|
118
106
|
? installation.installations
|
|
@@ -2,9 +2,8 @@ import type { CliCommand } from '../../types/cli.js';
|
|
|
2
2
|
interface OfflinePrepareReport {
|
|
3
3
|
schemaVersion: 1;
|
|
4
4
|
cli: string;
|
|
5
|
-
native: string | null;
|
|
6
5
|
cacheReady: boolean;
|
|
7
|
-
|
|
6
|
+
schemaReady: boolean;
|
|
8
7
|
mcpStartupReady: boolean;
|
|
9
8
|
smokeReady: boolean;
|
|
10
9
|
errors: string[];
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { spawnSync } from 'node:child_process';
|
|
2
2
|
import { PLANU_VERSION } from '../../config/version.js';
|
|
3
|
-
import {
|
|
3
|
+
import { RUNTIME_STORAGE_SCHEMA } from '../../engine/core-bridge.js';
|
|
4
4
|
const MCP_INITIALIZE_REQUEST = `${JSON.stringify({
|
|
5
5
|
jsonrpc: '2.0',
|
|
6
6
|
id: 1,
|
|
@@ -38,47 +38,31 @@ function provesMcpStartup(stdout) {
|
|
|
38
38
|
}
|
|
39
39
|
});
|
|
40
40
|
}
|
|
41
|
-
function
|
|
41
|
+
function provesStorageSchema(stdout) {
|
|
42
42
|
try {
|
|
43
43
|
const report = JSON.parse(stdout);
|
|
44
|
-
|
|
45
|
-
const storageSchemaMin = handshake?.storageSchemaMin;
|
|
46
|
-
const storageSchemaMax = handshake?.storageSchemaMax;
|
|
47
|
-
return (typeof report.native?.loaded === 'string' &&
|
|
48
|
-
report.native.loaded.length > 0 &&
|
|
49
|
-
report.native.compatibility?.compatible === true &&
|
|
50
|
-
typeof storageSchemaMin === 'number' &&
|
|
51
|
-
typeof storageSchemaMax === 'number' &&
|
|
52
|
-
storageSchemaMin <= RUNTIME_STORAGE_SCHEMA &&
|
|
53
|
-
storageSchemaMax >= RUNTIME_STORAGE_SCHEMA);
|
|
44
|
+
return report.storageSchema === RUNTIME_STORAGE_SCHEMA;
|
|
54
45
|
}
|
|
55
46
|
catch {
|
|
56
47
|
return false;
|
|
57
48
|
}
|
|
58
49
|
}
|
|
59
|
-
// eslint-disable-next-line complexity -- report aggregates cache, native and smoke diagnostics
|
|
60
50
|
export function prepareOfflineRuntime() {
|
|
61
|
-
const
|
|
62
|
-
const packages = [`@planu/cli@${PLANU_VERSION}`];
|
|
63
|
-
if (nativeName) {
|
|
64
|
-
packages.push(`${nativeName}@${PLANU_VERSION}`);
|
|
65
|
-
}
|
|
51
|
+
const packageSpec = `@planu/cli@${PLANU_VERSION}`;
|
|
66
52
|
const npmExecutable = process.platform === 'win32' ? 'npm.cmd' : 'npm';
|
|
67
53
|
const errors = [];
|
|
68
54
|
let cacheReady = true;
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
errors.push((cache.stderr || cache.stdout || `npm cache add failed: ${packageSpec}`).trim());
|
|
81
|
-
}
|
|
55
|
+
const cache = spawnSync(npmExecutable, ['cache', 'add', ...(process.env.PLANU_OFFLINE === '1' ? ['--offline'] : []), packageSpec], {
|
|
56
|
+
encoding: 'utf8',
|
|
57
|
+
timeout: 120_000,
|
|
58
|
+
env: { ...process.env },
|
|
59
|
+
});
|
|
60
|
+
if (cache.error) {
|
|
61
|
+
errors.push(cache.error.message);
|
|
62
|
+
}
|
|
63
|
+
if (cache.status !== 0) {
|
|
64
|
+
cacheReady = false;
|
|
65
|
+
errors.push((cache.stderr || cache.stdout || `npm cache add failed: ${packageSpec}`).trim());
|
|
82
66
|
}
|
|
83
67
|
const npxExecutable = process.platform === 'win32' ? 'npx.cmd' : 'npx';
|
|
84
68
|
const smokeEnvironment = { ...process.env, PLANU_OFFLINE: '1' };
|
|
@@ -92,22 +76,21 @@ export function prepareOfflineRuntime() {
|
|
|
92
76
|
if (!mcpStartupReady) {
|
|
93
77
|
errors.push(errorText(mcpSmoke, 'offline MCP startup handshake failed'));
|
|
94
78
|
}
|
|
95
|
-
const
|
|
79
|
+
const schemaSmoke = spawnSync(npxExecutable, ['--offline', '-y', `@planu/cli@${PLANU_VERSION}`, 'inspect', '--json'], {
|
|
96
80
|
encoding: 'utf8',
|
|
97
81
|
timeout: 30_000,
|
|
98
82
|
env: smokeEnvironment,
|
|
99
83
|
});
|
|
100
|
-
const
|
|
101
|
-
if (!
|
|
102
|
-
errors.push(errorText(
|
|
84
|
+
const schemaReady = schemaSmoke.status === 0 && provesStorageSchema(schemaSmoke.stdout);
|
|
85
|
+
if (!schemaReady) {
|
|
86
|
+
errors.push(errorText(schemaSmoke, 'cached runtime failed storage schema verification'));
|
|
103
87
|
}
|
|
104
|
-
const smokeReady = mcpStartupReady &&
|
|
88
|
+
const smokeReady = mcpStartupReady && schemaReady;
|
|
105
89
|
return {
|
|
106
90
|
schemaVersion: 1,
|
|
107
|
-
cli:
|
|
108
|
-
native: nativeName ? `${nativeName}@${PLANU_VERSION}` : null,
|
|
91
|
+
cli: packageSpec,
|
|
109
92
|
cacheReady,
|
|
110
|
-
|
|
93
|
+
schemaReady,
|
|
111
94
|
mcpStartupReady,
|
|
112
95
|
smokeReady,
|
|
113
96
|
errors: errors.filter(Boolean),
|
|
@@ -115,7 +98,7 @@ export function prepareOfflineRuntime() {
|
|
|
115
98
|
}
|
|
116
99
|
export const offlineCommand = {
|
|
117
100
|
name: 'offline',
|
|
118
|
-
description: 'Preload and verify exact CLI
|
|
101
|
+
description: 'Preload and verify the exact CLI asset for offline startup',
|
|
119
102
|
usage: 'planu offline prepare [--json]',
|
|
120
103
|
run(args, flags) {
|
|
121
104
|
if (args[0] !== 'prepare') {
|
|
@@ -123,7 +106,7 @@ export const offlineCommand = {
|
|
|
123
106
|
}
|
|
124
107
|
const report = prepareOfflineRuntime();
|
|
125
108
|
process.stdout.write(`${JSON.stringify(report, null, flags?.json ? 0 : 2)}\n`);
|
|
126
|
-
if (!report.cacheReady || !report.
|
|
109
|
+
if (!report.cacheReady || !report.schemaReady || !report.smokeReady) {
|
|
127
110
|
process.exitCode = 1;
|
|
128
111
|
}
|
|
129
112
|
return Promise.resolve();
|
|
@@ -1,21 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schemaVersion": 1,
|
|
3
|
-
"supportedNativeTargets": 8,
|
|
4
3
|
"gitIdentity": { "name": "planudev", "email": "hello@planu.dev" },
|
|
5
4
|
"quality": { "branchCoverageMinimum": 88.1, "mutationScoreMinimum": 80 },
|
|
6
|
-
"native": {
|
|
7
|
-
"blockingCommands": [
|
|
8
|
-
"cargo fmt --manifest-path rust/planu-core/Cargo.toml --all -- --check",
|
|
9
|
-
"cargo clippy --manifest-path rust/planu-core/Cargo.toml --all-targets --all-features -- -D warnings",
|
|
10
|
-
"cargo test --manifest-path rust/planu-core/Cargo.toml --all-features",
|
|
11
|
-
"cargo test --manifest-path rust/planu-core/Cargo.toml --test property_invariants",
|
|
12
|
-
"cargo audit --file rust/planu-core/Cargo.lock",
|
|
13
|
-
"cargo deny check --config deny.toml"
|
|
14
|
-
],
|
|
15
|
-
"performance": { "samples": 30, "warmups": 5, "p95RatioMaximum": 1.1, "rssP95RatioMaximum": 1.15 }
|
|
16
|
-
},
|
|
17
5
|
"releaseOptimization": {
|
|
18
|
-
"rustNightlyToolchain": "nightly-2026-04-14",
|
|
19
6
|
"releaseSloSeconds": { "warm": 1500, "cold": 2100, "recovery": 180 },
|
|
20
7
|
"sourceReceiptInputPatterns": [
|
|
21
8
|
"(^|/)package\\.json$",
|
|
@@ -29,72 +16,7 @@
|
|
|
29
16
|
{ "id": "reliability", "executable": "pnpm", "args": ["check:reliability"], "timeoutSeconds": 1800 },
|
|
30
17
|
{ "id": "dependency-freshness", "executable": "pnpm", "args": ["check:deps:fresh"], "timeoutSeconds": 1800 },
|
|
31
18
|
{ "id": "coverage", "executable": "pnpm", "args": ["test:coverage"], "timeoutSeconds": 1800 },
|
|
32
|
-
{ "id": "mutation", "executable": "pnpm", "args": ["audit:mutation"], "timeoutSeconds": 1800 }
|
|
33
|
-
{
|
|
34
|
-
"id": "rust-format",
|
|
35
|
-
"executable": "cargo",
|
|
36
|
-
"args": ["fmt", "--manifest-path", "rust/planu-core/Cargo.toml", "--all", "--", "--check"],
|
|
37
|
-
"timeoutSeconds": 1800
|
|
38
|
-
},
|
|
39
|
-
{
|
|
40
|
-
"id": "rust-clippy",
|
|
41
|
-
"executable": "cargo",
|
|
42
|
-
"args": [
|
|
43
|
-
"clippy",
|
|
44
|
-
"--manifest-path",
|
|
45
|
-
"rust/planu-core/Cargo.toml",
|
|
46
|
-
"--all-targets",
|
|
47
|
-
"--all-features",
|
|
48
|
-
"--",
|
|
49
|
-
"-D",
|
|
50
|
-
"warnings"
|
|
51
|
-
],
|
|
52
|
-
"timeoutSeconds": 1800
|
|
53
|
-
},
|
|
54
|
-
{
|
|
55
|
-
"id": "rust-test",
|
|
56
|
-
"executable": "cargo",
|
|
57
|
-
"args": ["test", "--manifest-path", "rust/planu-core/Cargo.toml", "--all-features"],
|
|
58
|
-
"timeoutSeconds": 1800
|
|
59
|
-
},
|
|
60
|
-
{
|
|
61
|
-
"id": "rust-audit",
|
|
62
|
-
"executable": "cargo",
|
|
63
|
-
"args": ["audit", "--file", "rust/planu-core/Cargo.lock"],
|
|
64
|
-
"timeoutSeconds": 1800
|
|
65
|
-
},
|
|
66
|
-
{
|
|
67
|
-
"id": "rust-policy",
|
|
68
|
-
"executable": "cargo",
|
|
69
|
-
"args": [
|
|
70
|
-
"deny",
|
|
71
|
-
"--manifest-path",
|
|
72
|
-
"rust/planu-core/Cargo.toml",
|
|
73
|
-
"check",
|
|
74
|
-
"--config",
|
|
75
|
-
"rust/planu-core/deny.toml"
|
|
76
|
-
],
|
|
77
|
-
"timeoutSeconds": 1800
|
|
78
|
-
},
|
|
79
|
-
{
|
|
80
|
-
"id": "rust-fuzz",
|
|
81
|
-
"executable": "cargo",
|
|
82
|
-
"args": [
|
|
83
|
-
"+nightly-2026-04-14",
|
|
84
|
-
"fuzz",
|
|
85
|
-
"run",
|
|
86
|
-
"public-inputs",
|
|
87
|
-
"--fuzz-dir",
|
|
88
|
-
"rust/planu-core/fuzz",
|
|
89
|
-
"--",
|
|
90
|
-
"-max_total_time=60"
|
|
91
|
-
],
|
|
92
|
-
"timeoutSeconds": 1800
|
|
93
|
-
}
|
|
94
|
-
],
|
|
95
|
-
"effectiveLinkers": [
|
|
96
|
-
{ "id": "CC", "command": "clang" },
|
|
97
|
-
{ "id": "CXX", "command": "clang++" }
|
|
19
|
+
{ "id": "mutation", "executable": "pnpm", "args": ["audit:mutation"], "timeoutSeconds": 1800 }
|
|
98
20
|
]
|
|
99
21
|
}
|
|
100
22
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { spawnSync } from 'node:child_process';
|
|
2
|
-
import {
|
|
2
|
+
import { RUNTIME_STORAGE_SCHEMA } from '../core-bridge.js';
|
|
3
3
|
import { redactFailureMessage, reportClassifiedDegradation, } from '../../errors/classified-degradation.js';
|
|
4
4
|
const EXACT_VERSION = /^(?:0|[1-9]\d*)\.(?:0|[1-9]\d*)\.(?:0|[1-9]\d*)$/;
|
|
5
5
|
const CLI_PACKAGE = '@planu/cli';
|
|
@@ -35,23 +35,14 @@ function verifiesMcp(stdout, version) {
|
|
|
35
35
|
}
|
|
36
36
|
});
|
|
37
37
|
}
|
|
38
|
-
function
|
|
38
|
+
function verifiesSchema(stdout, version) {
|
|
39
39
|
try {
|
|
40
40
|
const report = JSON.parse(stdout);
|
|
41
|
-
|
|
42
|
-
return (report.cliVersion === version &&
|
|
43
|
-
typeof report.native?.loaded === 'string' &&
|
|
44
|
-
report.native.loaded.includes(nativePackage) &&
|
|
45
|
-
report.native.compatibility?.compatible === true &&
|
|
46
|
-
handshake?.engineVersion === version &&
|
|
47
|
-
typeof handshake.storageSchemaMin === 'number' &&
|
|
48
|
-
typeof handshake.storageSchemaMax === 'number' &&
|
|
49
|
-
handshake.storageSchemaMin <= RUNTIME_STORAGE_SCHEMA &&
|
|
50
|
-
handshake.storageSchemaMax >= RUNTIME_STORAGE_SCHEMA);
|
|
41
|
+
return report.cliVersion === version && report.storageSchema === RUNTIME_STORAGE_SCHEMA;
|
|
51
42
|
}
|
|
52
43
|
catch (error) {
|
|
53
|
-
/* reliability-optional:
|
|
54
|
-
reportClassifiedDegradation('
|
|
44
|
+
/* reliability-optional: UPGRADE_SCHEMA_REPORT_INVALID */
|
|
45
|
+
reportClassifiedDegradation('UPGRADE_SCHEMA_REPORT_INVALID', error);
|
|
55
46
|
return false;
|
|
56
47
|
}
|
|
57
48
|
}
|
|
@@ -59,24 +50,17 @@ export function stageAndVerifyRelease(version, runner = spawnSync) {
|
|
|
59
50
|
if (!EXACT_VERSION.test(version)) {
|
|
60
51
|
throw new Error(`[Planu upgrade] Refusing non-exact release version: ${version}`);
|
|
61
52
|
}
|
|
62
|
-
const nativeName = currentNativePackageName();
|
|
63
|
-
if (nativeName === null) {
|
|
64
|
-
throw new Error('[Planu upgrade] No native package exists for this platform; upgrade aborted.');
|
|
65
|
-
}
|
|
66
53
|
const cliPackage = `${CLI_PACKAGE}@${version}`;
|
|
67
|
-
const nativePackage = `${nativeName}@${version}`;
|
|
68
54
|
const npm = process.platform === 'win32' ? 'npm.cmd' : 'npm';
|
|
69
55
|
const npx = process.platform === 'win32' ? 'npx.cmd' : 'npx';
|
|
70
56
|
const environment = { ...process.env };
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
throw commandFailure(`failed to stage ${packageSpec}`, staged);
|
|
79
|
-
}
|
|
57
|
+
const staged = runner(npm, ['cache', 'add', cliPackage], {
|
|
58
|
+
encoding: 'utf8',
|
|
59
|
+
timeout: 120_000,
|
|
60
|
+
env: environment,
|
|
61
|
+
});
|
|
62
|
+
if (staged.status !== 0 || staged.error) {
|
|
63
|
+
throw commandFailure(`failed to stage ${cliPackage}`, staged);
|
|
80
64
|
}
|
|
81
65
|
const isolatedEnvironment = { ...environment, PLANU_OFFLINE: '1' };
|
|
82
66
|
const mcpSmoke = runner(npx, ['--offline', '-y', cliPackage], {
|
|
@@ -88,22 +72,20 @@ export function stageAndVerifyRelease(version, runner = spawnSync) {
|
|
|
88
72
|
if (mcpSmoke.status !== 0 || mcpSmoke.error || !verifiesMcp(mcpSmoke.stdout, version)) {
|
|
89
73
|
throw commandFailure(`exact CLI ${version} failed MCP smoke test`, mcpSmoke);
|
|
90
74
|
}
|
|
91
|
-
const
|
|
75
|
+
const schemaSmoke = runner(npx, ['--offline', '-y', cliPackage, 'inspect', '--json'], {
|
|
92
76
|
encoding: 'utf8',
|
|
93
77
|
timeout: 30_000,
|
|
94
78
|
env: isolatedEnvironment,
|
|
95
79
|
});
|
|
96
|
-
if (
|
|
97
|
-
|
|
98
|
-
!
|
|
99
|
-
throw commandFailure(`exact
|
|
80
|
+
if (schemaSmoke.status !== 0 ||
|
|
81
|
+
schemaSmoke.error ||
|
|
82
|
+
!verifiesSchema(schemaSmoke.stdout, version)) {
|
|
83
|
+
throw commandFailure(`exact CLI ${version} failed storage schema smoke test`, schemaSmoke);
|
|
100
84
|
}
|
|
101
85
|
return Promise.resolve({
|
|
102
86
|
version,
|
|
103
87
|
cliPackage,
|
|
104
|
-
nativePackage,
|
|
105
88
|
cliVerified: true,
|
|
106
|
-
nativeVerified: true,
|
|
107
89
|
mcpSmokeVerified: true,
|
|
108
90
|
canaryVerified: true,
|
|
109
91
|
verifiedAt: new Date().toISOString(),
|
|
@@ -1,11 +1,7 @@
|
|
|
1
|
-
import type { FileHash, FileMetadata, SpecAnnotation, DriftResult,
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
export {
|
|
5
|
-
export type { FileHash, FileMetadata, SpecAnnotation, DriftResult, PlanuCore, DuplicateRawBlockRs, DuplicateBlockLocationRs, FastGrepMatch, FileContent, SpecBriefRs, AmbiguousCriterionRs, GapsLogChainResultRs, NativeVectorSearchResult, VectorNode, ProjectGraphSourceFileRs, TsRelationRs, GraphNodeInputRs, GraphEdgeInputRs, AffectedNodeRs, ShortestPathResultRs, CompactGraphSliceRs, CompactGraphEdgesRs, ProjectGraphLimitsPolicyRs, ResolvedProjectGraphLimitsRs, NativeRuntimeHandshake, NativeRuntimeCompatibility, NativeArtifactManifest, NativeLoadDiagnostic as LoadDiagnostic, };
|
|
6
|
-
export declare function currentNativePackageName(): string | null;
|
|
7
|
-
/** Main-thread port for async Keychain calls; never accepts override or unverified native code. */
|
|
8
|
-
export declare function requireMacOSKeychainNativePort(): MacOSKeychainNativePort;
|
|
1
|
+
import type { FileHash, FileMetadata, SpecAnnotation, DriftResult, DuplicateRawBlockRs, DuplicateBlockLocationRs, FastGrepMatch, FileContent, SpecBriefRs, AmbiguousCriterionRs, GapsLogChainResultRs, NativeVectorSearchResult, VectorNode, ProjectGraphSourceFileRs, TsRelationRs, GraphNodeInputRs, GraphEdgeInputRs, AffectedNodeRs, ShortestPathResultRs, CompactGraphSliceRs, CompactGraphEdgesRs, ProjectGraphLimitsPolicyRs, ResolvedProjectGraphLimitsRs } from '../types/core-bridge.js';
|
|
2
|
+
/** Must match RuntimeDatabase.schemaVersion and the packaged runtime's release contract. */
|
|
3
|
+
export declare const RUNTIME_STORAGE_SCHEMA = 4;
|
|
4
|
+
export type { FileHash, FileMetadata, SpecAnnotation, DriftResult, DuplicateRawBlockRs, DuplicateBlockLocationRs, FastGrepMatch, FileContent, SpecBriefRs, AmbiguousCriterionRs, GapsLogChainResultRs, NativeVectorSearchResult, VectorNode, ProjectGraphSourceFileRs, TsRelationRs, GraphNodeInputRs, GraphEdgeInputRs, AffectedNodeRs, ShortestPathResultRs, CompactGraphSliceRs, CompactGraphEdgesRs, ProjectGraphLimitsPolicyRs, ResolvedProjectGraphLimitsRs, };
|
|
9
5
|
export declare function fastHashProjectPath(projectPath: string): string;
|
|
10
6
|
export declare function fastGetProjectDataPath(baseDir: string, projectId: string): string | null;
|
|
11
7
|
export declare function fastIsSafeProjectId(projectId: string): boolean;
|
|
@@ -19,7 +15,8 @@ export declare function fastFindPatterns(rootPath: string, patterns: string[], e
|
|
|
19
15
|
export declare function fastFindFilesByName(rootPath: string, names: string[]): string[];
|
|
20
16
|
export declare function fastFindFilesByExt(rootPath: string, extensions: string[]): string[];
|
|
21
17
|
export declare function fastReadFiles(paths: string[]): FileContent[];
|
|
22
|
-
|
|
18
|
+
/** No TS-only replacement exists yet — callers detect `null` and use the regular spec scanner. */
|
|
19
|
+
export declare function fastScanSpecs(_rootPath: string): SpecBriefRs[] | null;
|
|
23
20
|
export declare function fastVerifyGapsChain(filePath: string): GapsLogChainResultRs;
|
|
24
21
|
export declare function fastAppendGapEntry(filePath: string, id: string, timestamp: string, specId: string, description: string, severity: string, affectedSpecs: string[]): string;
|
|
25
22
|
export declare function fastCosineSimilarity(v1: number[], v2: number[]): number;
|
|
@@ -31,34 +28,20 @@ export declare function fastExtractTsRelations(rootPath: string, paths: string[]
|
|
|
31
28
|
export declare function fastQueryAffectedNodes(seed: string, edges: GraphEdgeInputRs[], relationFilter: string[], policy: ProjectGraphLimitsPolicyRs, overrides?: Partial<ResolvedProjectGraphLimitsRs>): AffectedNodeRs[];
|
|
32
29
|
export declare function fastQueryShortestPath(from: string, to: string, edges: GraphEdgeInputRs[], relationFilter: string[], policy: ProjectGraphLimitsPolicyRs, overrides?: Partial<ResolvedProjectGraphLimitsRs>): ShortestPathResultRs;
|
|
33
30
|
export declare function fastSelectCompactGraphSlice(seeds: string[], nodes: GraphNodeInputRs[], edges: GraphEdgeInputRs[], policy: ProjectGraphLimitsPolicyRs, overrides?: Partial<ResolvedProjectGraphLimitsRs>): CompactGraphSliceRs;
|
|
34
|
-
/** Worker-dispatched variant of {@link fastDetectDriftParallel} for main-thread callers. */
|
|
35
31
|
export declare function fastDetectDriftParallelAsync(rootPath: string, keywords: string[]): Promise<{
|
|
36
32
|
value: DriftResult;
|
|
37
33
|
degradationNotice?: string;
|
|
38
34
|
}>;
|
|
39
|
-
/** Worker-dispatched variant of {@link fastScanAndHashFiles} for main-thread callers. */
|
|
40
35
|
export declare function fastScanAndHashFilesAsync(rootPath: string): Promise<{
|
|
41
36
|
value: FileHash[];
|
|
42
37
|
degradationNotice?: string;
|
|
43
38
|
}>;
|
|
44
|
-
/** Worker-dispatched variant of {@link fastScanProjectMetadata} for main-thread callers. */
|
|
45
39
|
export declare function fastScanProjectMetadataAsync(rootPath: string): Promise<{
|
|
46
40
|
value: FileMetadata[];
|
|
47
41
|
degradationNotice?: string;
|
|
48
42
|
}>;
|
|
49
|
-
/** Worker-dispatched variant of {@link fastScanSpecs} for main-thread callers. */
|
|
50
43
|
export declare function fastScanSpecsAsync(rootPath: string): Promise<{
|
|
51
44
|
value: SpecBriefRs[] | null;
|
|
52
45
|
degradationNotice?: string;
|
|
53
46
|
}>;
|
|
54
|
-
export declare const isNativeActive: () => boolean;
|
|
55
|
-
export declare const nativeLoadDiagnostic: () => NativeLoadDiagnostic;
|
|
56
|
-
/**
|
|
57
|
-
* Force a native load attempt regardless of the calling thread and return the
|
|
58
|
-
* resulting diagnostic. `nativeLoadDiagnostic()` alone only reports load state
|
|
59
|
-
* that some other main-thread-bypassing caller already triggered (e.g. the
|
|
60
|
-
* macOS Keychain port); this is the main-thread-safe way to actually probe
|
|
61
|
-
* native availability, used by `planu doctor`.
|
|
62
|
-
*/
|
|
63
|
-
export declare const probeNativeLoad: () => NativeLoadDiagnostic;
|
|
64
47
|
//# sourceMappingURL=core-bridge.d.ts.map
|