@planu/cli 5.3.27 → 5.3.29
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 +12 -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 +79 -18
- 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/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@planu/cli",
|
|
3
|
-
"version": "5.3.
|
|
4
|
-
"description": "Planu — MCP Server for Spec Driven Development
|
|
3
|
+
"version": "5.3.29",
|
|
4
|
+
"description": "Planu — MCP Server for Spec Driven Development. Cross-platform (Linux/macOS/Windows, x64/arm64).",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
7
7
|
"bin": {
|
|
@@ -11,57 +11,25 @@
|
|
|
11
11
|
"files": [
|
|
12
12
|
"dist/",
|
|
13
13
|
"!dist/**/*.map",
|
|
14
|
-
"!dist/engine/*.node",
|
|
15
14
|
"scripts/lib/pending-release-file.mjs",
|
|
16
15
|
"scripts/lib/portable-paths.mjs",
|
|
17
16
|
"src/i18n/messages/",
|
|
18
|
-
"planu-native.json",
|
|
19
17
|
"planu-plugin.json",
|
|
20
18
|
"README.md",
|
|
21
19
|
"CHANGELOG.md",
|
|
22
20
|
"LICENSE"
|
|
23
21
|
],
|
|
24
|
-
"napi": {
|
|
25
|
-
"binaryName": "planu-core",
|
|
26
|
-
"targets": [
|
|
27
|
-
"aarch64-apple-darwin",
|
|
28
|
-
"x86_64-apple-darwin",
|
|
29
|
-
"aarch64-unknown-linux-gnu",
|
|
30
|
-
"aarch64-unknown-linux-musl",
|
|
31
|
-
"x86_64-unknown-linux-gnu",
|
|
32
|
-
"x86_64-unknown-linux-musl",
|
|
33
|
-
"aarch64-pc-windows-msvc",
|
|
34
|
-
"x86_64-pc-windows-msvc"
|
|
35
|
-
],
|
|
36
|
-
"packageName": "@planu/core"
|
|
37
|
-
},
|
|
38
|
-
"optionalDependencies": {
|
|
39
|
-
"@planu/core-darwin-arm64": "5.3.27",
|
|
40
|
-
"@planu/core-darwin-x64": "5.3.27",
|
|
41
|
-
"@planu/core-linux-arm64-gnu": "5.3.27",
|
|
42
|
-
"@planu/core-linux-arm64-musl": "5.3.27",
|
|
43
|
-
"@planu/core-linux-x64-gnu": "5.3.27",
|
|
44
|
-
"@planu/core-linux-x64-musl": "5.3.27",
|
|
45
|
-
"@planu/core-win32-arm64-msvc": "5.3.27",
|
|
46
|
-
"@planu/core-win32-x64-msvc": "5.3.27"
|
|
47
|
-
},
|
|
48
22
|
"engines": {
|
|
49
23
|
"node": ">=24.0.0"
|
|
50
24
|
},
|
|
51
25
|
"packageManager": "pnpm@11.9.0+sha512.bd682d5d03fe525ef7c9fd6780c6884d1e756ac4c9c9fe00c538782824310dcf90e3ddc4f53835f06dfaebd5085e41855e0bcbb3b60de2ac5bbab89e5036f03b",
|
|
52
26
|
"scripts": {
|
|
53
|
-
"build:rust": "bash scripts/build-rust-local.sh --host",
|
|
54
|
-
"build:rust:all": "bash scripts/build-rust-local.sh --all",
|
|
55
|
-
"build:rust:check-tools": "bash scripts/build-rust-local.sh --check-tools",
|
|
56
|
-
"check:native-version-parity": "node scripts/check-native-version-parity.mjs",
|
|
57
|
-
"check:release-authorities": "node scripts/check-release-authorities.mjs",
|
|
58
27
|
"check:commercial-surfaces": "node scripts/check-commercial-surfaces.mjs",
|
|
59
28
|
"check:tool-registration": "bash scripts/check-tool-registration.sh",
|
|
60
29
|
"generate:host-tool-registry": "node scripts/generate-host-tool-registry.mjs",
|
|
61
30
|
"release:local": "bash scripts/release-local.sh",
|
|
62
|
-
"release:
|
|
63
|
-
"
|
|
64
|
-
"build": "pnpm clean && pnpm build:rust && pnpm build:ts",
|
|
31
|
+
"release:publish": "bash scripts/release-local.sh --publish",
|
|
32
|
+
"build": "pnpm clean && pnpm build:ts",
|
|
65
33
|
"build:ts": "pnpm clean && tsc -p tsconfig.build.json && tsc-alias -p tsconfig.build.json && node scripts/copy-runtime-assets.mjs",
|
|
66
34
|
"build:obfuscated": "pnpm build && node scripts/obfuscate.mjs",
|
|
67
35
|
"dev": "tsc --watch",
|
|
@@ -85,12 +53,9 @@
|
|
|
85
53
|
"test:website:browser": "playwright test --config playwright.website.config.ts",
|
|
86
54
|
"test:website:lighthouse": "lhci autorun --config=.lighthouserc.cjs",
|
|
87
55
|
"test:website:lighthouse:production": "PLANU_LIGHTHOUSE_PRODUCTION=1 lhci autorun --config=.lighthouserc.cjs",
|
|
88
|
-
"
|
|
89
|
-
"native:project-graph:benchmark": "node scripts/benchmark-native-performance.mjs --operation project_graph_query --samples 30 --warmups 5 --project-path . --spec-id SPEC-1119 --json",
|
|
90
|
-
"benchmark:execution-kernel": "pnpm build && node scripts/benchmark-execution-kernel.mjs",
|
|
91
|
-
"check": "pnpm typecheck && pnpm lint:gate && pnpm format:check && pnpm check:destructive-ops && pnpm check:release-authorities && pnpm check:commercial-surfaces && pnpm check:tool-registration && pnpm check:public-privacy && pnpm check:website-proof && pnpm check:donation-assets && pnpm check:website-public-assets",
|
|
56
|
+
"check": "pnpm typecheck && pnpm lint:gate && pnpm format:check && pnpm check:destructive-ops && pnpm check:commercial-surfaces && pnpm check:tool-registration && pnpm check:public-privacy && pnpm check:website-proof && pnpm check:donation-assets && pnpm check:website-public-assets",
|
|
92
57
|
"check:destructive-ops": "bash scripts/check-no-automatic-destructive-ops.sh",
|
|
93
|
-
"check:strict": "pnpm check && pnpm generate:host-tool-registry -- --check && pnpm check:
|
|
58
|
+
"check:strict": "pnpm check && pnpm generate:host-tool-registry -- --check && pnpm check:environment-schema && pnpm audit:hardcodes && pnpm audit:deadcode && pnpm audit:circular && pnpm audit:types && pnpm audit:security && pnpm audit:i18n",
|
|
94
59
|
"check:preflight": "pnpm typecheck && pnpm lint:gate && pnpm format:check && node scripts/check-public-privacy.mjs && node scripts/check-preflight.mjs",
|
|
95
60
|
"check:reliability": "node scripts/check-reliability-policies.mjs",
|
|
96
61
|
"check:environment-schema": "node scripts/check-environment-schema.mjs",
|
|
@@ -98,7 +63,7 @@
|
|
|
98
63
|
"test:migrations": "vitest run tests/storage/corruption-contract.test.ts tests/integration/runtime-storage.test.ts tests/integration/canonical-storage-migration.test.ts",
|
|
99
64
|
"test:fault-injection": "vitest run tests/engine/auto-updater/atomic-upgrade.test.ts tests/integration/durable-job-runtime.test.ts tests/integration/idempotent-operations.test.ts",
|
|
100
65
|
"check:website-public-assets": "node scripts/check-website-public-assets.mjs",
|
|
101
|
-
"check:public-privacy": "node scripts/check-public-privacy.mjs
|
|
66
|
+
"check:public-privacy": "node scripts/check-public-privacy.mjs",
|
|
102
67
|
"check:readme-parity": "node scripts/check-readme-parity.mjs --package-root .",
|
|
103
68
|
"privacy:prepublish": "node scripts/check-prepublish-privacy.mjs --package-root .",
|
|
104
69
|
"generate:website-proof": "node scripts/generate-website-proof.mjs",
|
|
@@ -176,7 +141,6 @@
|
|
|
176
141
|
"@commitlint/config-conventional": "^21.2.0",
|
|
177
142
|
"@eslint/js": "^10.0.1",
|
|
178
143
|
"@lhci/cli": "0.15.1",
|
|
179
|
-
"@napi-rs/cli": "3.8.2",
|
|
180
144
|
"@noble/hashes": "2.2.0",
|
|
181
145
|
"@playwright/test": "1.62.1",
|
|
182
146
|
"@scure/base": "2.2.0",
|
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.3.
|
|
5
|
+
"version": "5.3.29",
|
|
6
6
|
"icon": "assets/plugin/icon.svg",
|
|
7
7
|
"command": ["npx", "@planu/cli@latest"],
|
|
8
8
|
"packageName": "@planu/cli",
|
|
@@ -1,87 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"schemaVersion": 1,
|
|
3
|
-
"binaryName": "planu-core",
|
|
4
|
-
"packageScope": "@planu/core",
|
|
5
|
-
"targets": [
|
|
6
|
-
{
|
|
7
|
-
"directory": "darwin-arm64",
|
|
8
|
-
"package": "@planu/core-darwin-arm64",
|
|
9
|
-
"rustTarget": "aarch64-apple-darwin",
|
|
10
|
-
"runtimeTarget": "darwin-arm64",
|
|
11
|
-
"platform": "darwin",
|
|
12
|
-
"arch": "arm64",
|
|
13
|
-
"libc": null,
|
|
14
|
-
"runner": "macos-15"
|
|
15
|
-
},
|
|
16
|
-
{
|
|
17
|
-
"directory": "darwin-x64",
|
|
18
|
-
"package": "@planu/core-darwin-x64",
|
|
19
|
-
"rustTarget": "x86_64-apple-darwin",
|
|
20
|
-
"runtimeTarget": "darwin-x64",
|
|
21
|
-
"platform": "darwin",
|
|
22
|
-
"arch": "x64",
|
|
23
|
-
"libc": null,
|
|
24
|
-
"runner": "macos-15-intel"
|
|
25
|
-
},
|
|
26
|
-
{
|
|
27
|
-
"directory": "linux-arm64-gnu",
|
|
28
|
-
"package": "@planu/core-linux-arm64-gnu",
|
|
29
|
-
"rustTarget": "aarch64-unknown-linux-gnu",
|
|
30
|
-
"runtimeTarget": "linux-arm64-glibc",
|
|
31
|
-
"platform": "linux",
|
|
32
|
-
"arch": "arm64",
|
|
33
|
-
"libc": "glibc",
|
|
34
|
-
"runner": "ubuntu-24.04-arm"
|
|
35
|
-
},
|
|
36
|
-
{
|
|
37
|
-
"directory": "linux-arm64-musl",
|
|
38
|
-
"package": "@planu/core-linux-arm64-musl",
|
|
39
|
-
"rustTarget": "aarch64-unknown-linux-musl",
|
|
40
|
-
"runtimeTarget": "linux-arm64-musl",
|
|
41
|
-
"platform": "linux",
|
|
42
|
-
"arch": "arm64",
|
|
43
|
-
"libc": "musl",
|
|
44
|
-
"runner": "ubuntu-24.04-arm"
|
|
45
|
-
},
|
|
46
|
-
{
|
|
47
|
-
"directory": "linux-x64-gnu",
|
|
48
|
-
"package": "@planu/core-linux-x64-gnu",
|
|
49
|
-
"rustTarget": "x86_64-unknown-linux-gnu",
|
|
50
|
-
"runtimeTarget": "linux-x64-glibc",
|
|
51
|
-
"platform": "linux",
|
|
52
|
-
"arch": "x64",
|
|
53
|
-
"libc": "glibc",
|
|
54
|
-
"runner": "ubuntu-24.04"
|
|
55
|
-
},
|
|
56
|
-
{
|
|
57
|
-
"directory": "linux-x64-musl",
|
|
58
|
-
"package": "@planu/core-linux-x64-musl",
|
|
59
|
-
"rustTarget": "x86_64-unknown-linux-musl",
|
|
60
|
-
"runtimeTarget": "linux-x64-musl",
|
|
61
|
-
"platform": "linux",
|
|
62
|
-
"arch": "x64",
|
|
63
|
-
"libc": "musl",
|
|
64
|
-
"runner": "ubuntu-24.04"
|
|
65
|
-
},
|
|
66
|
-
{
|
|
67
|
-
"directory": "win32-arm64-msvc",
|
|
68
|
-
"package": "@planu/core-win32-arm64-msvc",
|
|
69
|
-
"rustTarget": "aarch64-pc-windows-msvc",
|
|
70
|
-
"runtimeTarget": "win32-arm64",
|
|
71
|
-
"platform": "win32",
|
|
72
|
-
"arch": "arm64",
|
|
73
|
-
"libc": null,
|
|
74
|
-
"runner": "windows-11-arm"
|
|
75
|
-
},
|
|
76
|
-
{
|
|
77
|
-
"directory": "win32-x64-msvc",
|
|
78
|
-
"package": "@planu/core-win32-x64-msvc",
|
|
79
|
-
"rustTarget": "x86_64-pc-windows-msvc",
|
|
80
|
-
"runtimeTarget": "win32-x64",
|
|
81
|
-
"platform": "win32",
|
|
82
|
-
"arch": "x64",
|
|
83
|
-
"libc": null,
|
|
84
|
-
"runner": "windows-2025"
|
|
85
|
-
}
|
|
86
|
-
]
|
|
87
|
-
}
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import type { DurableJobExecutorOptions } from '../../types/durable-job.js';
|
|
2
|
-
import type { DurableJobRecord } from '../../storage/runtime-db.js';
|
|
3
|
-
/** Claims and executes allowlisted native jobs while preserving lease and cancellation fencing. */
|
|
4
|
-
export declare class DurableJobExecutor {
|
|
5
|
-
private readonly runtime;
|
|
6
|
-
private readonly workerId;
|
|
7
|
-
private readonly leaseMs;
|
|
8
|
-
private readonly heartbeatMs;
|
|
9
|
-
private readonly maxConcurrency;
|
|
10
|
-
private readonly runNative;
|
|
11
|
-
constructor(options: DurableJobExecutorOptions);
|
|
12
|
-
/** Execute one bounded batch. Jobs not claimed by this worker remain untouched. */
|
|
13
|
-
runOnce(projectId: string, workspaceId?: string): Promise<readonly DurableJobRecord[]>;
|
|
14
|
-
private execute;
|
|
15
|
-
}
|
|
16
|
-
//# sourceMappingURL=job-executor.d.ts.map
|
|
@@ -1,140 +0,0 @@
|
|
|
1
|
-
import { isNativeWorkerOperation } from './native-worker-protocol.js';
|
|
2
|
-
import { runNativeWorkerOperation } from './native-worker-runtime.js';
|
|
3
|
-
import { reportClassifiedDegradation } from '../../errors/classified-degradation.js';
|
|
4
|
-
const DEFAULT_WORKSPACE_ID = 'global';
|
|
5
|
-
const DEFAULT_LEASE_MS = 5_000;
|
|
6
|
-
const DEFAULT_HEARTBEAT_MS = 25;
|
|
7
|
-
const DEFAULT_MAX_CONCURRENCY = 2;
|
|
8
|
-
const MAX_CONCURRENCY = 8;
|
|
9
|
-
const RUNNABLE_STATES = new Set(['accepted', 'checkpointed']);
|
|
10
|
-
/** Claims and executes allowlisted native jobs while preserving lease and cancellation fencing. */
|
|
11
|
-
export class DurableJobExecutor {
|
|
12
|
-
runtime;
|
|
13
|
-
workerId;
|
|
14
|
-
leaseMs;
|
|
15
|
-
heartbeatMs;
|
|
16
|
-
maxConcurrency;
|
|
17
|
-
runNative;
|
|
18
|
-
constructor(options) {
|
|
19
|
-
requireIdentifier(options.workerId, 'workerId');
|
|
20
|
-
this.leaseMs = options.leaseMs ?? DEFAULT_LEASE_MS;
|
|
21
|
-
this.heartbeatMs = options.heartbeatMs ?? DEFAULT_HEARTBEAT_MS;
|
|
22
|
-
this.maxConcurrency = options.maxConcurrency ?? DEFAULT_MAX_CONCURRENCY;
|
|
23
|
-
if (!Number.isSafeInteger(this.leaseMs) || this.leaseMs < 100 || this.leaseMs > 60_000) {
|
|
24
|
-
throw new Error('[Planu] executor leaseMs must be an integer between 100 and 60000');
|
|
25
|
-
}
|
|
26
|
-
if (!Number.isSafeInteger(this.heartbeatMs) ||
|
|
27
|
-
this.heartbeatMs < 10 ||
|
|
28
|
-
this.heartbeatMs >= this.leaseMs / 2) {
|
|
29
|
-
throw new Error('[Planu] executor heartbeatMs must be at least 10 and below half the lease');
|
|
30
|
-
}
|
|
31
|
-
if (!Number.isSafeInteger(this.maxConcurrency) ||
|
|
32
|
-
this.maxConcurrency < 1 ||
|
|
33
|
-
this.maxConcurrency > MAX_CONCURRENCY) {
|
|
34
|
-
throw new Error(`[Planu] executor maxConcurrency must be between 1 and ${String(MAX_CONCURRENCY)}`);
|
|
35
|
-
}
|
|
36
|
-
this.runtime = options.runtime;
|
|
37
|
-
this.workerId = options.workerId;
|
|
38
|
-
this.runNative = options.runNative ?? runNativeWorkerOperation;
|
|
39
|
-
}
|
|
40
|
-
/** Execute one bounded batch. Jobs not claimed by this worker remain untouched. */
|
|
41
|
-
async runOnce(projectId, workspaceId = DEFAULT_WORKSPACE_ID) {
|
|
42
|
-
requireIdentifier(projectId, 'projectId');
|
|
43
|
-
requireIdentifier(workspaceId, 'workspaceId');
|
|
44
|
-
const candidates = this.runtime
|
|
45
|
-
.list(projectId, workspaceId)
|
|
46
|
-
.filter((job) => RUNNABLE_STATES.has(job.state))
|
|
47
|
-
.slice(0, this.maxConcurrency);
|
|
48
|
-
return Promise.all(candidates.map((job) => this.execute({
|
|
49
|
-
operationId: job.id,
|
|
50
|
-
projectId: job.projectId,
|
|
51
|
-
workspaceId: job.workspaceId,
|
|
52
|
-
})));
|
|
53
|
-
}
|
|
54
|
-
async execute(identity) {
|
|
55
|
-
const claimed = this.runtime.claim({
|
|
56
|
-
...identity,
|
|
57
|
-
workerId: this.workerId,
|
|
58
|
-
leaseMs: this.leaseMs,
|
|
59
|
-
});
|
|
60
|
-
if (!claimed) {
|
|
61
|
-
return this.runtime.get(identity);
|
|
62
|
-
}
|
|
63
|
-
const controller = new AbortController();
|
|
64
|
-
const heartbeat = setInterval(() => {
|
|
65
|
-
const current = this.runtime.get(identity);
|
|
66
|
-
if (current.state === 'cancelled' || current.cancelRequested) {
|
|
67
|
-
controller.abort(new Error('[Planu] Durable native job cancelled'));
|
|
68
|
-
return;
|
|
69
|
-
}
|
|
70
|
-
if (!this.runtime.renew({
|
|
71
|
-
...identity,
|
|
72
|
-
workerId: this.workerId,
|
|
73
|
-
fencingToken: claimed.fencingToken,
|
|
74
|
-
leaseMs: this.leaseMs,
|
|
75
|
-
})) {
|
|
76
|
-
controller.abort(new Error('[Planu] Durable native job lease was lost'));
|
|
77
|
-
}
|
|
78
|
-
}, this.heartbeatMs);
|
|
79
|
-
heartbeat.unref();
|
|
80
|
-
try {
|
|
81
|
-
const payload = parseNativePayload(claimed.payload);
|
|
82
|
-
const value = await this.runNative({
|
|
83
|
-
projectId: identity.projectId,
|
|
84
|
-
operation: payload.operation,
|
|
85
|
-
payload: payload.payload,
|
|
86
|
-
deadlineAt: payload.deadlineAt,
|
|
87
|
-
requestId: identity.operationId,
|
|
88
|
-
cancellationId: payload.cancellationId ?? identity.operationId,
|
|
89
|
-
signal: controller.signal,
|
|
90
|
-
});
|
|
91
|
-
return this.runtime.complete({
|
|
92
|
-
...identity,
|
|
93
|
-
workerId: this.workerId,
|
|
94
|
-
fencingToken: claimed.fencingToken,
|
|
95
|
-
result: value,
|
|
96
|
-
});
|
|
97
|
-
}
|
|
98
|
-
catch (error) {
|
|
99
|
-
/* reliability-optional: DURABLE_JOB_EXECUTION_FAILURE — runtime records typed failure below */
|
|
100
|
-
reportClassifiedDegradation('DURABLE_JOB_EXECUTION_FAILURE', error);
|
|
101
|
-
const current = this.runtime.get(identity);
|
|
102
|
-
if (current.state === 'cancelled') {
|
|
103
|
-
return current;
|
|
104
|
-
}
|
|
105
|
-
return this.runtime.fail({
|
|
106
|
-
...identity,
|
|
107
|
-
workerId: this.workerId,
|
|
108
|
-
fencingToken: claimed.fencingToken,
|
|
109
|
-
error: boundedError(error),
|
|
110
|
-
});
|
|
111
|
-
}
|
|
112
|
-
finally {
|
|
113
|
-
clearInterval(heartbeat);
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
function parseNativePayload(value) {
|
|
118
|
-
if (!value || typeof value !== 'object') {
|
|
119
|
-
throw new Error('[Planu] Durable job payload must be an object');
|
|
120
|
-
}
|
|
121
|
-
const payload = value;
|
|
122
|
-
if (payload.kind !== 'native-worker' ||
|
|
123
|
-
!isNativeWorkerOperation(payload.operation) ||
|
|
124
|
-
!payload.payload ||
|
|
125
|
-
typeof payload.payload !== 'object' ||
|
|
126
|
-
!Number.isSafeInteger(payload.deadlineAt)) {
|
|
127
|
-
throw new Error('[Planu] Durable job payload is not an allowlisted native operation');
|
|
128
|
-
}
|
|
129
|
-
return payload;
|
|
130
|
-
}
|
|
131
|
-
function boundedError(error) {
|
|
132
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
133
|
-
return message.slice(0, 4_096) || 'Native worker failed';
|
|
134
|
-
}
|
|
135
|
-
function requireIdentifier(value, label) {
|
|
136
|
-
if (!value || value.length > 128 || !/^[A-Za-z0-9][A-Za-z0-9._:-]*$/.test(value)) {
|
|
137
|
-
throw new Error(`[Planu] Invalid ${label}`);
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
//# sourceMappingURL=job-executor.js.map
|
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
import { fastFindFilesByExt, fastReadFiles } from '../core-bridge.js';
|
|
2
|
-
// Content scoring is advisory. Keep it bounded so a create_spec acknowledgement
|
|
3
|
-
// never turns into an O(project-files) content read on large repositories.
|
|
4
|
-
const MAX_CONTENT_CANDIDATES = 2_048;
|
|
5
|
-
function normalizedRelativePath(rootPath, filePath) {
|
|
6
|
-
const normalizedRoot = rootPath.replaceAll('\\', '/').replace(/\/$/, '');
|
|
7
|
-
const normalizedFile = filePath.replaceAll('\\', '/');
|
|
8
|
-
return normalizedFile.startsWith(`${normalizedRoot}/`)
|
|
9
|
-
? normalizedFile.slice(normalizedRoot.length + 1)
|
|
10
|
-
: normalizedFile;
|
|
11
|
-
}
|
|
12
|
-
function isRelevantSourcePath(rootPath, filePath) {
|
|
13
|
-
const relativePath = normalizedRelativePath(rootPath, filePath);
|
|
14
|
-
return ((relativePath.startsWith('src/') || relativePath.startsWith('tests/')) &&
|
|
15
|
-
!relativePath.includes('/node_modules/') &&
|
|
16
|
-
!relativePath.includes('/dist/'));
|
|
17
|
-
}
|
|
18
|
-
export function findRelevantFilesNative(input) {
|
|
19
|
-
const keywords = [...new Set(input.keywords.map((value) => value.trim()))].filter(Boolean);
|
|
20
|
-
if (keywords.length === 0 || !Number.isSafeInteger(input.limit) || input.limit < 1) {
|
|
21
|
-
return [];
|
|
22
|
-
}
|
|
23
|
-
const candidates = fastFindFilesByExt(input.rootPath, ['ts'])
|
|
24
|
-
.filter((filePath) => isRelevantSourcePath(input.rootPath, filePath))
|
|
25
|
-
.sort((left, right) => left.localeCompare(right));
|
|
26
|
-
const scores = new Map();
|
|
27
|
-
const pathMatched = new Set();
|
|
28
|
-
for (const filePath of candidates) {
|
|
29
|
-
const pathTokens = new Set(normalizedRelativePath(input.rootPath, filePath)
|
|
30
|
-
.toLowerCase()
|
|
31
|
-
.split(/[/\\.\-_]+/)
|
|
32
|
-
.filter((token) => token.length >= 3));
|
|
33
|
-
const pathScore = keywords.filter((keyword) => pathTokens.has(keyword)).length;
|
|
34
|
-
if (pathScore > 0) {
|
|
35
|
-
scores.set(filePath, pathScore * 2);
|
|
36
|
-
pathMatched.add(filePath);
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
// Prefer files already related by path, then inspect a deterministic bounded
|
|
40
|
-
// sample for content-only matches. The previous fastFindPatterns call walked
|
|
41
|
-
// and opened every source file a second time (10s+ at 100k files).
|
|
42
|
-
const contentCandidates = [
|
|
43
|
-
...pathMatched,
|
|
44
|
-
...candidates.filter((filePath) => !pathMatched.has(filePath)),
|
|
45
|
-
].slice(0, MAX_CONTENT_CANDIDATES);
|
|
46
|
-
for (const file of fastReadFiles(contentCandidates)) {
|
|
47
|
-
const content = file.content.toLowerCase();
|
|
48
|
-
let contentScore = 0;
|
|
49
|
-
for (const keyword of keywords) {
|
|
50
|
-
if (content.includes(keyword.toLowerCase())) {
|
|
51
|
-
contentScore += 1;
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
if (contentScore > 0) {
|
|
55
|
-
scores.set(file.path, (scores.get(file.path) ?? 0) + contentScore);
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
return [...scores]
|
|
59
|
-
.filter(([, score]) => score > 0)
|
|
60
|
-
.sort(([leftPath, leftScore], [rightPath, rightScore]) => rightScore === leftScore ? leftPath.localeCompare(rightPath) : rightScore - leftScore)
|
|
61
|
-
.slice(0, input.limit)
|
|
62
|
-
.map(([filePath]) => filePath);
|
|
63
|
-
}
|
|
64
|
-
//# sourceMappingURL=native-relevance-scorer.js.map
|
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
import { fastDetectDriftParallel, fastScanAndHashFiles, fastScanProjectGraphSources, fastScanProjectMetadata, fastScanSpecAnnotations, fastScanSpecs, } from '../core-bridge.js';
|
|
2
|
-
import { findRelevantFilesNative } from './native-relevance-scorer.js';
|
|
3
|
-
function requiredString(payload, key) {
|
|
4
|
-
const value = payload[key];
|
|
5
|
-
if (typeof value !== 'string' || value.trim() === '') {
|
|
6
|
-
throw new Error(`[Planu] Native worker payload requires ${key}`);
|
|
7
|
-
}
|
|
8
|
-
return value;
|
|
9
|
-
}
|
|
10
|
-
function stringArray(payload, key) {
|
|
11
|
-
const value = payload[key];
|
|
12
|
-
if (!Array.isArray(value) || !value.every((item) => typeof item === 'string')) {
|
|
13
|
-
throw new Error(`[Planu] Native worker payload requires string[] ${key}`);
|
|
14
|
-
}
|
|
15
|
-
return value;
|
|
16
|
-
}
|
|
17
|
-
function positiveInteger(payload, key) {
|
|
18
|
-
const value = payload[key];
|
|
19
|
-
if (!Number.isSafeInteger(value) || value < 1) {
|
|
20
|
-
throw new Error(`[Planu] Native worker payload requires positive integer ${key}`);
|
|
21
|
-
}
|
|
22
|
-
return value;
|
|
23
|
-
}
|
|
24
|
-
export function dispatchNativeWorkerRequest(request) {
|
|
25
|
-
switch (request.operation) {
|
|
26
|
-
case 'scan-and-hash-files':
|
|
27
|
-
return fastScanAndHashFiles(requiredString(request.payload, 'rootPath'));
|
|
28
|
-
case 'scan-project-metadata':
|
|
29
|
-
return fastScanProjectMetadata(requiredString(request.payload, 'rootPath'));
|
|
30
|
-
case 'scan-spec-annotations':
|
|
31
|
-
return fastScanSpecAnnotations(requiredString(request.payload, 'rootPath'));
|
|
32
|
-
case 'detect-drift':
|
|
33
|
-
return fastDetectDriftParallel(requiredString(request.payload, 'rootPath'), stringArray(request.payload, 'keywords'));
|
|
34
|
-
case 'scan-specs':
|
|
35
|
-
return fastScanSpecs(requiredString(request.payload, 'rootPath'));
|
|
36
|
-
case 'find-relevant-files':
|
|
37
|
-
return findRelevantFilesNative({
|
|
38
|
-
rootPath: requiredString(request.payload, 'rootPath'),
|
|
39
|
-
keywords: stringArray(request.payload, 'keywords'),
|
|
40
|
-
limit: positiveInteger(request.payload, 'limit'),
|
|
41
|
-
});
|
|
42
|
-
case 'scan-project-graph-sources':
|
|
43
|
-
return fastScanProjectGraphSources(requiredString(request.payload, 'rootPath'), request.payload.policy, request.payload.overrides ?? {});
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
//# sourceMappingURL=native-worker-dispatch.js.map
|
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
import type { NativeWorkerOperation } from '../../types/native-worker.js';
|
|
2
|
-
export type { NativeWorkerHandshake, NativeWorkerOperation, NativeWorkerRequest, NativeWorkerResponse, } from '../../types/native-worker.js';
|
|
3
|
-
export declare const NATIVE_WORKER_OPERATIONS: readonly ["scan-and-hash-files", "scan-project-metadata", "scan-spec-annotations", "detect-drift", "scan-specs", "find-relevant-files", "scan-project-graph-sources"];
|
|
4
|
-
export declare function nativeWorkerSchemaHash(): string;
|
|
5
|
-
export declare function isNativeWorkerOperation(value: unknown): value is NativeWorkerOperation;
|
|
6
|
-
//# sourceMappingURL=native-worker-protocol.d.ts.map
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
import { createHash } from 'node:crypto';
|
|
2
|
-
import { NATIVE_CAPABILITY_ABI, NATIVE_PROTOCOL_ABI, RUNTIME_STORAGE_SCHEMA, } from '../native-runtime-handshake.js';
|
|
3
|
-
export const NATIVE_WORKER_OPERATIONS = [
|
|
4
|
-
'scan-and-hash-files',
|
|
5
|
-
'scan-project-metadata',
|
|
6
|
-
'scan-spec-annotations',
|
|
7
|
-
'detect-drift',
|
|
8
|
-
'scan-specs',
|
|
9
|
-
'find-relevant-files',
|
|
10
|
-
'scan-project-graph-sources',
|
|
11
|
-
];
|
|
12
|
-
export function nativeWorkerSchemaHash() {
|
|
13
|
-
return createHash('sha256')
|
|
14
|
-
.update(JSON.stringify({
|
|
15
|
-
protocolAbi: NATIVE_PROTOCOL_ABI,
|
|
16
|
-
capabilityAbi: NATIVE_CAPABILITY_ABI,
|
|
17
|
-
storageSchema: RUNTIME_STORAGE_SCHEMA,
|
|
18
|
-
capabilities: NATIVE_WORKER_OPERATIONS,
|
|
19
|
-
requestFields: [
|
|
20
|
-
'requestId',
|
|
21
|
-
'projectId',
|
|
22
|
-
'deadlineAt',
|
|
23
|
-
'cancellationId',
|
|
24
|
-
'operation',
|
|
25
|
-
'payload',
|
|
26
|
-
],
|
|
27
|
-
}))
|
|
28
|
-
.digest('hex');
|
|
29
|
-
}
|
|
30
|
-
export function isNativeWorkerOperation(value) {
|
|
31
|
-
return (typeof value === 'string' && NATIVE_WORKER_OPERATIONS.includes(value));
|
|
32
|
-
}
|
|
33
|
-
//# sourceMappingURL=native-worker-protocol.js.map
|
|
@@ -1,4 +0,0 @@
|
|
|
1
|
-
import type { NativeWorkerCall, NativeWorkerFactory } from '../../types/native-worker.js';
|
|
2
|
-
export type { NativeWorkerCall } from '../../types/native-worker.js';
|
|
3
|
-
export declare function runNativeWorkerOperation(call: NativeWorkerCall, workerFactory?: NativeWorkerFactory): Promise<unknown>;
|
|
4
|
-
//# sourceMappingURL=native-worker-runtime.d.ts.map
|