@planu/cli 5.3.12 → 5.3.13
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 +16 -0
- package/dist/engine/evidence-index/index-builder.js +28 -3
- 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-quality/generic-output-gate.js +18 -2
- package/dist/engine/validation/validation-source-policy.js +1 -0
- package/dist/tools/create-spec.js +16 -4
- package/dist/tools/update-status/evidence-gate.js +6 -2
- package/dist/types/spec-quality.d.ts +3 -0
- package/package.json +9 -9
- package/planu-native.json +1 -1
- package/planu-plugin.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,19 @@
|
|
|
1
|
+
## [5.3.13] - 2026-08-10
|
|
2
|
+
|
|
3
|
+
### Bug Fixes
|
|
4
|
+
- fix(spec-1468): word-boundary guard on evidence marker truncation
|
|
5
|
+
- fix(lifecycle): evidence-only rebind + planu digest exclusion (SPEC-1468)
|
|
6
|
+
- fix(spec-1469): close path-echo exemption bypass found in implementation review
|
|
7
|
+
- fix(spec-quality): path-token guard in restatement check + actionable gate rejection (SPEC-1469)
|
|
8
|
+
|
|
9
|
+
### Chores
|
|
10
|
+
- chore(spec-1468): record done transition lifecycle state
|
|
11
|
+
- chore(spec-1469): record done transition lifecycle state
|
|
12
|
+
- chore(planu): capture auto-generated session context
|
|
13
|
+
- chore(specs): move SPEC-1468/1469 to implementing
|
|
14
|
+
- chore(specs): approve SPEC-1468/1469 after round-2 dual review + arbitration
|
|
15
|
+
|
|
16
|
+
|
|
1
17
|
## [5.3.12] - 2026-08-10
|
|
2
18
|
|
|
3
19
|
### Bug Fixes
|
|
@@ -4,13 +4,38 @@ import { createCriterionIdentity, criterionIdentitiesMatch } from '../criterion-
|
|
|
4
4
|
export function criterionKey(criterion) {
|
|
5
5
|
return createCriterionIdentity(criterion).stableKey;
|
|
6
6
|
}
|
|
7
|
+
const EVIDENCE_MARKER = /\b(?:FILES|FUNCTIONS|TEST):/;
|
|
8
|
+
function truncateAtEvidenceMarker(value) {
|
|
9
|
+
const markerIndex = value.search(EVIDENCE_MARKER);
|
|
10
|
+
return markerIndex === -1 ? value : value.slice(0, markerIndex);
|
|
11
|
+
}
|
|
7
12
|
export async function buildSpecEvidenceIndex(args) {
|
|
8
13
|
const diagnostics = [...args.artifacts.invalidArtifacts];
|
|
9
14
|
const matrixRows = args.artifacts.traceabilityMatrix?.rows ?? [];
|
|
10
15
|
const contractValidations = args.artifacts.contractValidations;
|
|
11
|
-
const
|
|
12
|
-
|
|
13
|
-
|
|
16
|
+
const criterionEntries = args.criteria.map((criterion, index) => ({
|
|
17
|
+
criterion,
|
|
18
|
+
identity: createCriterionIdentity(criterion, { index }),
|
|
19
|
+
truncatedIdentity: createCriterionIdentity(truncateAtEvidenceMarker(criterion), { index }),
|
|
20
|
+
}));
|
|
21
|
+
const rowCriterionIndexes = matrixRows.map((row, rowIndex) => {
|
|
22
|
+
const rowIdentity = createCriterionIdentity(row.acceptanceCriterion, { index: rowIndex });
|
|
23
|
+
const exactMatches = criterionEntries
|
|
24
|
+
.map((entry, criterionIndex) => criterionIdentitiesMatch(rowIdentity, entry.identity) ? criterionIndex : -1)
|
|
25
|
+
.filter((criterionIndex) => criterionIndex !== -1);
|
|
26
|
+
if (exactMatches.length > 0) {
|
|
27
|
+
return exactMatches;
|
|
28
|
+
}
|
|
29
|
+
const truncatedRowIdentity = createCriterionIdentity(truncateAtEvidenceMarker(row.acceptanceCriterion), { index: rowIndex });
|
|
30
|
+
const truncatedMatches = criterionEntries
|
|
31
|
+
.map((entry, criterionIndex) => criterionIdentitiesMatch(truncatedRowIdentity, entry.truncatedIdentity)
|
|
32
|
+
? criterionIndex
|
|
33
|
+
: -1)
|
|
34
|
+
.filter((criterionIndex) => criterionIndex !== -1);
|
|
35
|
+
return truncatedMatches.length === 1 ? truncatedMatches : [];
|
|
36
|
+
});
|
|
37
|
+
const entries = await Promise.all(criterionEntries.map(async ({ criterion, identity }, criterionIndex) => {
|
|
38
|
+
const rows = matrixRows.filter((_, rowIndex) => (rowCriterionIndexes[rowIndex] ?? []).includes(criterionIndex));
|
|
14
39
|
const evidence = await collectEvidence({
|
|
15
40
|
rows,
|
|
16
41
|
contractValidations,
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schemaVersion": 2,
|
|
3
|
-
"cliVersion": "5.3.
|
|
4
|
-
"engineVersion": "5.3.
|
|
5
|
-
"buildId": "1-5.3.
|
|
3
|
+
"cliVersion": "5.3.13",
|
|
4
|
+
"engineVersion": "5.3.13",
|
|
5
|
+
"buildId": "1-5.3.13-aarch64-apple-darwin",
|
|
6
6
|
"protocolAbi": 1,
|
|
7
7
|
"capabilityAbi": 2,
|
|
8
8
|
"nodeApiAbi": 4,
|
|
@@ -17,15 +17,15 @@
|
|
|
17
17
|
"platform": "darwin",
|
|
18
18
|
"arch": "arm64",
|
|
19
19
|
"libc": null,
|
|
20
|
-
"artifactSha256": "
|
|
20
|
+
"artifactSha256": "63b4e21bd8fd8154d97f9f1a471fd7a731c6bc0514dec2ef9a2a5d9f1a98eb32",
|
|
21
21
|
"sbom": {
|
|
22
22
|
"format": "CycloneDX-1.5",
|
|
23
23
|
"path": "planu-core.darwin-arm64.node.sbom.json",
|
|
24
|
-
"sha256": "
|
|
24
|
+
"sha256": "b25f5ddbd51db18f2bebb1e86e7cd31f174e3613e187ec00c7ebc66132a66d0c"
|
|
25
25
|
},
|
|
26
26
|
"provenance": {
|
|
27
27
|
"builder": "scripts/build-rust-local.sh",
|
|
28
|
-
"sourceCommit": "
|
|
28
|
+
"sourceCommit": "4c29cf026dcfa833b89a328afa3546aecbc02d22",
|
|
29
29
|
"sourceTreeDirty": false,
|
|
30
30
|
"sourceDateEpoch": 1,
|
|
31
31
|
"rustToolchain": "rustc 1.95.0 (59807616e 2026-04-14)",
|
|
@@ -34,6 +34,6 @@
|
|
|
34
34
|
"signature": {
|
|
35
35
|
"algorithm": "Ed25519",
|
|
36
36
|
"keyId": "e2ee765cb5ad9fbdc433ece332bce26d746d5e350b3acde0721a4c8c6337ff7b",
|
|
37
|
-
"value": "
|
|
37
|
+
"value": "8h2IO454Azg9cLFFiaQj1bEZ8np+FAUG+F7hZqLueM1Cu8k3lWakVBIB4h10CNEYk59TFsi02SfqUBXiUhr1DQ=="
|
|
38
38
|
}
|
|
39
39
|
}
|
|
@@ -4,14 +4,14 @@
|
|
|
4
4
|
"version": 1,
|
|
5
5
|
"metadata": {
|
|
6
6
|
"component": {
|
|
7
|
-
"bom-ref": "pkg:cargo/planu-core@5.3.
|
|
7
|
+
"bom-ref": "pkg:cargo/planu-core@5.3.13",
|
|
8
8
|
"type": "library",
|
|
9
9
|
"name": "planu-core",
|
|
10
|
-
"version": "5.3.
|
|
10
|
+
"version": "5.3.13",
|
|
11
11
|
"hashes": [
|
|
12
12
|
{
|
|
13
13
|
"alg": "SHA-256",
|
|
14
|
-
"content": "
|
|
14
|
+
"content": "63b4e21bd8fd8154d97f9f1a471fd7a731c6bc0514dec2ef9a2a5d9f1a98eb32"
|
|
15
15
|
}
|
|
16
16
|
]
|
|
17
17
|
}
|
|
@@ -1106,7 +1106,7 @@
|
|
|
1106
1106
|
"dependsOn": []
|
|
1107
1107
|
},
|
|
1108
1108
|
{
|
|
1109
|
-
"ref": "pkg:cargo/planu-core@5.3.
|
|
1109
|
+
"ref": "pkg:cargo/planu-core@5.3.13",
|
|
1110
1110
|
"dependsOn": [
|
|
1111
1111
|
"pkg:cargo/core-foundation@0.10.1",
|
|
1112
1112
|
"pkg:cargo/hmac@0.12.1",
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schemaVersion": 2,
|
|
3
|
-
"cliVersion": "5.3.
|
|
4
|
-
"engineVersion": "5.3.
|
|
5
|
-
"buildId": "1-5.3.
|
|
3
|
+
"cliVersion": "5.3.13",
|
|
4
|
+
"engineVersion": "5.3.13",
|
|
5
|
+
"buildId": "1-5.3.13-x86_64-apple-darwin",
|
|
6
6
|
"protocolAbi": 1,
|
|
7
7
|
"capabilityAbi": 2,
|
|
8
8
|
"nodeApiAbi": 4,
|
|
@@ -17,15 +17,15 @@
|
|
|
17
17
|
"platform": "darwin",
|
|
18
18
|
"arch": "x64",
|
|
19
19
|
"libc": null,
|
|
20
|
-
"artifactSha256": "
|
|
20
|
+
"artifactSha256": "6af7f8df49b56c0e440dbb5088a957943d0b1e8bd6d243392d00e224205dab63",
|
|
21
21
|
"sbom": {
|
|
22
22
|
"format": "CycloneDX-1.5",
|
|
23
23
|
"path": "planu-core.darwin-x64.node.sbom.json",
|
|
24
|
-
"sha256": "
|
|
24
|
+
"sha256": "7fccd089cc1a35511497238f84f697bcee2d0c00534f6fefe3ddfbe770d3d617"
|
|
25
25
|
},
|
|
26
26
|
"provenance": {
|
|
27
27
|
"builder": "scripts/build-rust-local.sh",
|
|
28
|
-
"sourceCommit": "
|
|
28
|
+
"sourceCommit": "4c29cf026dcfa833b89a328afa3546aecbc02d22",
|
|
29
29
|
"sourceTreeDirty": false,
|
|
30
30
|
"sourceDateEpoch": 1,
|
|
31
31
|
"rustToolchain": "rustc 1.95.0 (59807616e 2026-04-14)",
|
|
@@ -34,6 +34,6 @@
|
|
|
34
34
|
"signature": {
|
|
35
35
|
"algorithm": "Ed25519",
|
|
36
36
|
"keyId": "e2ee765cb5ad9fbdc433ece332bce26d746d5e350b3acde0721a4c8c6337ff7b",
|
|
37
|
-
"value": "
|
|
37
|
+
"value": "tnN9tivctc9090o+HeQTDhLowV/Z+Kp4mUQcxpxj7CKiLWrClaGzwlcEABXsF8YJcSLHSrxiUnB+397bAOaQDw=="
|
|
38
38
|
}
|
|
39
39
|
}
|
|
@@ -4,14 +4,14 @@
|
|
|
4
4
|
"version": 1,
|
|
5
5
|
"metadata": {
|
|
6
6
|
"component": {
|
|
7
|
-
"bom-ref": "pkg:cargo/planu-core@5.3.
|
|
7
|
+
"bom-ref": "pkg:cargo/planu-core@5.3.13",
|
|
8
8
|
"type": "library",
|
|
9
9
|
"name": "planu-core",
|
|
10
|
-
"version": "5.3.
|
|
10
|
+
"version": "5.3.13",
|
|
11
11
|
"hashes": [
|
|
12
12
|
{
|
|
13
13
|
"alg": "SHA-256",
|
|
14
|
-
"content": "
|
|
14
|
+
"content": "6af7f8df49b56c0e440dbb5088a957943d0b1e8bd6d243392d00e224205dab63"
|
|
15
15
|
}
|
|
16
16
|
]
|
|
17
17
|
}
|
|
@@ -1106,7 +1106,7 @@
|
|
|
1106
1106
|
"dependsOn": []
|
|
1107
1107
|
},
|
|
1108
1108
|
{
|
|
1109
|
-
"ref": "pkg:cargo/planu-core@5.3.
|
|
1109
|
+
"ref": "pkg:cargo/planu-core@5.3.13",
|
|
1110
1110
|
"dependsOn": [
|
|
1111
1111
|
"pkg:cargo/core-foundation@0.10.1",
|
|
1112
1112
|
"pkg:cargo/hmac@0.12.1",
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schemaVersion": 2,
|
|
3
|
-
"cliVersion": "5.3.
|
|
4
|
-
"engineVersion": "5.3.
|
|
5
|
-
"buildId": "1-5.3.
|
|
3
|
+
"cliVersion": "5.3.13",
|
|
4
|
+
"engineVersion": "5.3.13",
|
|
5
|
+
"buildId": "1-5.3.13-aarch64-unknown-linux-gnu",
|
|
6
6
|
"protocolAbi": 1,
|
|
7
7
|
"capabilityAbi": 2,
|
|
8
8
|
"nodeApiAbi": 4,
|
|
@@ -16,15 +16,15 @@
|
|
|
16
16
|
"platform": "linux",
|
|
17
17
|
"arch": "arm64",
|
|
18
18
|
"libc": "glibc",
|
|
19
|
-
"artifactSha256": "
|
|
19
|
+
"artifactSha256": "6dc15d18af613ad34ab23bc8d36387596c6d4e56a32130500d87581637afc5c6",
|
|
20
20
|
"sbom": {
|
|
21
21
|
"format": "CycloneDX-1.5",
|
|
22
22
|
"path": "planu-core.linux-arm64-gnu.node.sbom.json",
|
|
23
|
-
"sha256": "
|
|
23
|
+
"sha256": "5284d0de91c78b38db90e45d503bdfc1663bdd347d02afa2d4ee077973a558c5"
|
|
24
24
|
},
|
|
25
25
|
"provenance": {
|
|
26
26
|
"builder": "scripts/build-rust-local.sh",
|
|
27
|
-
"sourceCommit": "
|
|
27
|
+
"sourceCommit": "4c29cf026dcfa833b89a328afa3546aecbc02d22",
|
|
28
28
|
"sourceTreeDirty": false,
|
|
29
29
|
"sourceDateEpoch": 1,
|
|
30
30
|
"rustToolchain": "rustc 1.95.0 (59807616e 2026-04-14)",
|
|
@@ -33,6 +33,6 @@
|
|
|
33
33
|
"signature": {
|
|
34
34
|
"algorithm": "Ed25519",
|
|
35
35
|
"keyId": "e2ee765cb5ad9fbdc433ece332bce26d746d5e350b3acde0721a4c8c6337ff7b",
|
|
36
|
-
"value": "
|
|
36
|
+
"value": "QBwJ3Bv0Cu43hS/zvTdSyOE9ua2CpkENsXB8xP6XmxGGXvGiJSQkkK2Un6PQ/7EZKt88wuJd95a6bZKfCSzdDw=="
|
|
37
37
|
}
|
|
38
38
|
}
|
|
@@ -4,14 +4,14 @@
|
|
|
4
4
|
"version": 1,
|
|
5
5
|
"metadata": {
|
|
6
6
|
"component": {
|
|
7
|
-
"bom-ref": "pkg:cargo/planu-core@5.3.
|
|
7
|
+
"bom-ref": "pkg:cargo/planu-core@5.3.13",
|
|
8
8
|
"type": "library",
|
|
9
9
|
"name": "planu-core",
|
|
10
|
-
"version": "5.3.
|
|
10
|
+
"version": "5.3.13",
|
|
11
11
|
"hashes": [
|
|
12
12
|
{
|
|
13
13
|
"alg": "SHA-256",
|
|
14
|
-
"content": "
|
|
14
|
+
"content": "6dc15d18af613ad34ab23bc8d36387596c6d4e56a32130500d87581637afc5c6"
|
|
15
15
|
}
|
|
16
16
|
]
|
|
17
17
|
}
|
|
@@ -1106,7 +1106,7 @@
|
|
|
1106
1106
|
"dependsOn": []
|
|
1107
1107
|
},
|
|
1108
1108
|
{
|
|
1109
|
-
"ref": "pkg:cargo/planu-core@5.3.
|
|
1109
|
+
"ref": "pkg:cargo/planu-core@5.3.13",
|
|
1110
1110
|
"dependsOn": [
|
|
1111
1111
|
"pkg:cargo/core-foundation@0.10.1",
|
|
1112
1112
|
"pkg:cargo/hmac@0.12.1",
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schemaVersion": 2,
|
|
3
|
-
"cliVersion": "5.3.
|
|
4
|
-
"engineVersion": "5.3.
|
|
5
|
-
"buildId": "1-5.3.
|
|
3
|
+
"cliVersion": "5.3.13",
|
|
4
|
+
"engineVersion": "5.3.13",
|
|
5
|
+
"buildId": "1-5.3.13-aarch64-unknown-linux-musl",
|
|
6
6
|
"protocolAbi": 1,
|
|
7
7
|
"capabilityAbi": 2,
|
|
8
8
|
"nodeApiAbi": 4,
|
|
@@ -16,15 +16,15 @@
|
|
|
16
16
|
"platform": "linux",
|
|
17
17
|
"arch": "arm64",
|
|
18
18
|
"libc": "musl",
|
|
19
|
-
"artifactSha256": "
|
|
19
|
+
"artifactSha256": "b47bdce610685474cc5ffbe8efbe504bf22c547d87aca9f6971a5a645e63cdca",
|
|
20
20
|
"sbom": {
|
|
21
21
|
"format": "CycloneDX-1.5",
|
|
22
22
|
"path": "planu-core.linux-arm64-musl.node.sbom.json",
|
|
23
|
-
"sha256": "
|
|
23
|
+
"sha256": "0d6797a7c84e1699db01fbeb55299d9ad870e888cbd6b9a6f694e5bf7146630d"
|
|
24
24
|
},
|
|
25
25
|
"provenance": {
|
|
26
26
|
"builder": "scripts/build-rust-local.sh",
|
|
27
|
-
"sourceCommit": "
|
|
27
|
+
"sourceCommit": "4c29cf026dcfa833b89a328afa3546aecbc02d22",
|
|
28
28
|
"sourceTreeDirty": false,
|
|
29
29
|
"sourceDateEpoch": 1,
|
|
30
30
|
"rustToolchain": "rustc 1.95.0 (59807616e 2026-04-14)",
|
|
@@ -33,6 +33,6 @@
|
|
|
33
33
|
"signature": {
|
|
34
34
|
"algorithm": "Ed25519",
|
|
35
35
|
"keyId": "e2ee765cb5ad9fbdc433ece332bce26d746d5e350b3acde0721a4c8c6337ff7b",
|
|
36
|
-
"value": "
|
|
36
|
+
"value": "CdnJ0CdQkjvrwcF8st5Tp/4WFb+5WZhBOQAJJOCb2tbb9jiRzC0BNuzg3O6kNlcUYDjltRSTYDo/3mamDJ2CDQ=="
|
|
37
37
|
}
|
|
38
38
|
}
|
|
@@ -4,14 +4,14 @@
|
|
|
4
4
|
"version": 1,
|
|
5
5
|
"metadata": {
|
|
6
6
|
"component": {
|
|
7
|
-
"bom-ref": "pkg:cargo/planu-core@5.3.
|
|
7
|
+
"bom-ref": "pkg:cargo/planu-core@5.3.13",
|
|
8
8
|
"type": "library",
|
|
9
9
|
"name": "planu-core",
|
|
10
|
-
"version": "5.3.
|
|
10
|
+
"version": "5.3.13",
|
|
11
11
|
"hashes": [
|
|
12
12
|
{
|
|
13
13
|
"alg": "SHA-256",
|
|
14
|
-
"content": "
|
|
14
|
+
"content": "b47bdce610685474cc5ffbe8efbe504bf22c547d87aca9f6971a5a645e63cdca"
|
|
15
15
|
}
|
|
16
16
|
]
|
|
17
17
|
}
|
|
@@ -1106,7 +1106,7 @@
|
|
|
1106
1106
|
"dependsOn": []
|
|
1107
1107
|
},
|
|
1108
1108
|
{
|
|
1109
|
-
"ref": "pkg:cargo/planu-core@5.3.
|
|
1109
|
+
"ref": "pkg:cargo/planu-core@5.3.13",
|
|
1110
1110
|
"dependsOn": [
|
|
1111
1111
|
"pkg:cargo/core-foundation@0.10.1",
|
|
1112
1112
|
"pkg:cargo/hmac@0.12.1",
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schemaVersion": 2,
|
|
3
|
-
"cliVersion": "5.3.
|
|
4
|
-
"engineVersion": "5.3.
|
|
5
|
-
"buildId": "1-5.3.
|
|
3
|
+
"cliVersion": "5.3.13",
|
|
4
|
+
"engineVersion": "5.3.13",
|
|
5
|
+
"buildId": "1-5.3.13-x86_64-unknown-linux-gnu",
|
|
6
6
|
"protocolAbi": 1,
|
|
7
7
|
"capabilityAbi": 2,
|
|
8
8
|
"nodeApiAbi": 4,
|
|
@@ -16,15 +16,15 @@
|
|
|
16
16
|
"platform": "linux",
|
|
17
17
|
"arch": "x64",
|
|
18
18
|
"libc": "glibc",
|
|
19
|
-
"artifactSha256": "
|
|
19
|
+
"artifactSha256": "e23b8e1541a7d2d9887dfe4c2baa0669a6b6f7b40d8f7537174c68ea9eab3ea2",
|
|
20
20
|
"sbom": {
|
|
21
21
|
"format": "CycloneDX-1.5",
|
|
22
22
|
"path": "planu-core.linux-x64-gnu.node.sbom.json",
|
|
23
|
-
"sha256": "
|
|
23
|
+
"sha256": "d0395e69523bda89502adf30f3f0c5bc9b7a03050cdf959fc918b462ae652406"
|
|
24
24
|
},
|
|
25
25
|
"provenance": {
|
|
26
26
|
"builder": "scripts/build-rust-local.sh",
|
|
27
|
-
"sourceCommit": "
|
|
27
|
+
"sourceCommit": "4c29cf026dcfa833b89a328afa3546aecbc02d22",
|
|
28
28
|
"sourceTreeDirty": false,
|
|
29
29
|
"sourceDateEpoch": 1,
|
|
30
30
|
"rustToolchain": "rustc 1.95.0 (59807616e 2026-04-14)",
|
|
@@ -33,6 +33,6 @@
|
|
|
33
33
|
"signature": {
|
|
34
34
|
"algorithm": "Ed25519",
|
|
35
35
|
"keyId": "e2ee765cb5ad9fbdc433ece332bce26d746d5e350b3acde0721a4c8c6337ff7b",
|
|
36
|
-
"value": "+
|
|
36
|
+
"value": "bLbpq7CqGP2XT5gEjs+A9x0HU5ltLdGJxXqCKI9WKa0GOjrNFvJZSi+G/TSMeSE6oQnh2xTFtn4uTH5oYl5QBA=="
|
|
37
37
|
}
|
|
38
38
|
}
|
|
@@ -4,14 +4,14 @@
|
|
|
4
4
|
"version": 1,
|
|
5
5
|
"metadata": {
|
|
6
6
|
"component": {
|
|
7
|
-
"bom-ref": "pkg:cargo/planu-core@5.3.
|
|
7
|
+
"bom-ref": "pkg:cargo/planu-core@5.3.13",
|
|
8
8
|
"type": "library",
|
|
9
9
|
"name": "planu-core",
|
|
10
|
-
"version": "5.3.
|
|
10
|
+
"version": "5.3.13",
|
|
11
11
|
"hashes": [
|
|
12
12
|
{
|
|
13
13
|
"alg": "SHA-256",
|
|
14
|
-
"content": "
|
|
14
|
+
"content": "e23b8e1541a7d2d9887dfe4c2baa0669a6b6f7b40d8f7537174c68ea9eab3ea2"
|
|
15
15
|
}
|
|
16
16
|
]
|
|
17
17
|
}
|
|
@@ -1106,7 +1106,7 @@
|
|
|
1106
1106
|
"dependsOn": []
|
|
1107
1107
|
},
|
|
1108
1108
|
{
|
|
1109
|
-
"ref": "pkg:cargo/planu-core@5.3.
|
|
1109
|
+
"ref": "pkg:cargo/planu-core@5.3.13",
|
|
1110
1110
|
"dependsOn": [
|
|
1111
1111
|
"pkg:cargo/core-foundation@0.10.1",
|
|
1112
1112
|
"pkg:cargo/hmac@0.12.1",
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schemaVersion": 2,
|
|
3
|
-
"cliVersion": "5.3.
|
|
4
|
-
"engineVersion": "5.3.
|
|
5
|
-
"buildId": "1-5.3.
|
|
3
|
+
"cliVersion": "5.3.13",
|
|
4
|
+
"engineVersion": "5.3.13",
|
|
5
|
+
"buildId": "1-5.3.13-x86_64-unknown-linux-musl",
|
|
6
6
|
"protocolAbi": 1,
|
|
7
7
|
"capabilityAbi": 2,
|
|
8
8
|
"nodeApiAbi": 4,
|
|
@@ -16,15 +16,15 @@
|
|
|
16
16
|
"platform": "linux",
|
|
17
17
|
"arch": "x64",
|
|
18
18
|
"libc": "musl",
|
|
19
|
-
"artifactSha256": "
|
|
19
|
+
"artifactSha256": "ad695974ac459aab230a6d08dab91747078bc5619906be58d0667ea2a6a07521",
|
|
20
20
|
"sbom": {
|
|
21
21
|
"format": "CycloneDX-1.5",
|
|
22
22
|
"path": "planu-core.linux-x64-musl.node.sbom.json",
|
|
23
|
-
"sha256": "
|
|
23
|
+
"sha256": "8c57317b906d44a1076fd15349dad0518d743d902a9ae48e0205ca3af2fd3da8"
|
|
24
24
|
},
|
|
25
25
|
"provenance": {
|
|
26
26
|
"builder": "scripts/build-rust-local.sh",
|
|
27
|
-
"sourceCommit": "
|
|
27
|
+
"sourceCommit": "4c29cf026dcfa833b89a328afa3546aecbc02d22",
|
|
28
28
|
"sourceTreeDirty": false,
|
|
29
29
|
"sourceDateEpoch": 1,
|
|
30
30
|
"rustToolchain": "rustc 1.95.0 (59807616e 2026-04-14)",
|
|
@@ -33,6 +33,6 @@
|
|
|
33
33
|
"signature": {
|
|
34
34
|
"algorithm": "Ed25519",
|
|
35
35
|
"keyId": "e2ee765cb5ad9fbdc433ece332bce26d746d5e350b3acde0721a4c8c6337ff7b",
|
|
36
|
-
"value": "
|
|
36
|
+
"value": "5hurMVndDnUmbfntnmEPNN2WFsbeujSqDm5GyON1f8K5j9CfXF3P5ChNpxwHHHr8Da7SfiIwBmflAeyTU/nHCA=="
|
|
37
37
|
}
|
|
38
38
|
}
|
|
@@ -4,14 +4,14 @@
|
|
|
4
4
|
"version": 1,
|
|
5
5
|
"metadata": {
|
|
6
6
|
"component": {
|
|
7
|
-
"bom-ref": "pkg:cargo/planu-core@5.3.
|
|
7
|
+
"bom-ref": "pkg:cargo/planu-core@5.3.13",
|
|
8
8
|
"type": "library",
|
|
9
9
|
"name": "planu-core",
|
|
10
|
-
"version": "5.3.
|
|
10
|
+
"version": "5.3.13",
|
|
11
11
|
"hashes": [
|
|
12
12
|
{
|
|
13
13
|
"alg": "SHA-256",
|
|
14
|
-
"content": "
|
|
14
|
+
"content": "ad695974ac459aab230a6d08dab91747078bc5619906be58d0667ea2a6a07521"
|
|
15
15
|
}
|
|
16
16
|
]
|
|
17
17
|
}
|
|
@@ -1106,7 +1106,7 @@
|
|
|
1106
1106
|
"dependsOn": []
|
|
1107
1107
|
},
|
|
1108
1108
|
{
|
|
1109
|
-
"ref": "pkg:cargo/planu-core@5.3.
|
|
1109
|
+
"ref": "pkg:cargo/planu-core@5.3.13",
|
|
1110
1110
|
"dependsOn": [
|
|
1111
1111
|
"pkg:cargo/core-foundation@0.10.1",
|
|
1112
1112
|
"pkg:cargo/hmac@0.12.1",
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schemaVersion": 2,
|
|
3
|
-
"cliVersion": "5.3.
|
|
4
|
-
"engineVersion": "5.3.
|
|
5
|
-
"buildId": "1-5.3.
|
|
3
|
+
"cliVersion": "5.3.13",
|
|
4
|
+
"engineVersion": "5.3.13",
|
|
5
|
+
"buildId": "1-5.3.13-aarch64-pc-windows-msvc",
|
|
6
6
|
"protocolAbi": 1,
|
|
7
7
|
"capabilityAbi": 2,
|
|
8
8
|
"nodeApiAbi": 4,
|
|
@@ -16,15 +16,15 @@
|
|
|
16
16
|
"platform": "win32",
|
|
17
17
|
"arch": "arm64",
|
|
18
18
|
"libc": null,
|
|
19
|
-
"artifactSha256": "
|
|
19
|
+
"artifactSha256": "509c952dde3408081c65f343258ca79f553fe72a3e3ae73c8ab1c6775bad6ac1",
|
|
20
20
|
"sbom": {
|
|
21
21
|
"format": "CycloneDX-1.5",
|
|
22
22
|
"path": "planu-core.win32-arm64-msvc.node.sbom.json",
|
|
23
|
-
"sha256": "
|
|
23
|
+
"sha256": "eac44b50bc2422b46b61e251dd9e85dc504e8c69229ae40b80794d18471da7b6"
|
|
24
24
|
},
|
|
25
25
|
"provenance": {
|
|
26
26
|
"builder": "scripts/build-rust-local.sh",
|
|
27
|
-
"sourceCommit": "
|
|
27
|
+
"sourceCommit": "4c29cf026dcfa833b89a328afa3546aecbc02d22",
|
|
28
28
|
"sourceTreeDirty": false,
|
|
29
29
|
"sourceDateEpoch": 1,
|
|
30
30
|
"rustToolchain": "rustc 1.95.0 (59807616e 2026-04-14)",
|
|
@@ -33,6 +33,6 @@
|
|
|
33
33
|
"signature": {
|
|
34
34
|
"algorithm": "Ed25519",
|
|
35
35
|
"keyId": "e2ee765cb5ad9fbdc433ece332bce26d746d5e350b3acde0721a4c8c6337ff7b",
|
|
36
|
-
"value": "
|
|
36
|
+
"value": "fUPD7OvB98bmo61bccKDAY3fzL8aT96h7u07WBPo+FSm3jyyM+NSKLX6Jeyoz6yJKKxV9V+7ldHZ2YkgY/aNDQ=="
|
|
37
37
|
}
|
|
38
38
|
}
|
|
@@ -4,14 +4,14 @@
|
|
|
4
4
|
"version": 1,
|
|
5
5
|
"metadata": {
|
|
6
6
|
"component": {
|
|
7
|
-
"bom-ref": "pkg:cargo/planu-core@5.3.
|
|
7
|
+
"bom-ref": "pkg:cargo/planu-core@5.3.13",
|
|
8
8
|
"type": "library",
|
|
9
9
|
"name": "planu-core",
|
|
10
|
-
"version": "5.3.
|
|
10
|
+
"version": "5.3.13",
|
|
11
11
|
"hashes": [
|
|
12
12
|
{
|
|
13
13
|
"alg": "SHA-256",
|
|
14
|
-
"content": "
|
|
14
|
+
"content": "509c952dde3408081c65f343258ca79f553fe72a3e3ae73c8ab1c6775bad6ac1"
|
|
15
15
|
}
|
|
16
16
|
]
|
|
17
17
|
}
|
|
@@ -1106,7 +1106,7 @@
|
|
|
1106
1106
|
"dependsOn": []
|
|
1107
1107
|
},
|
|
1108
1108
|
{
|
|
1109
|
-
"ref": "pkg:cargo/planu-core@5.3.
|
|
1109
|
+
"ref": "pkg:cargo/planu-core@5.3.13",
|
|
1110
1110
|
"dependsOn": [
|
|
1111
1111
|
"pkg:cargo/core-foundation@0.10.1",
|
|
1112
1112
|
"pkg:cargo/hmac@0.12.1",
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schemaVersion": 2,
|
|
3
|
-
"cliVersion": "5.3.
|
|
4
|
-
"engineVersion": "5.3.
|
|
5
|
-
"buildId": "1-5.3.
|
|
3
|
+
"cliVersion": "5.3.13",
|
|
4
|
+
"engineVersion": "5.3.13",
|
|
5
|
+
"buildId": "1-5.3.13-x86_64-pc-windows-msvc",
|
|
6
6
|
"protocolAbi": 1,
|
|
7
7
|
"capabilityAbi": 2,
|
|
8
8
|
"nodeApiAbi": 4,
|
|
@@ -16,15 +16,15 @@
|
|
|
16
16
|
"platform": "win32",
|
|
17
17
|
"arch": "x64",
|
|
18
18
|
"libc": null,
|
|
19
|
-
"artifactSha256": "
|
|
19
|
+
"artifactSha256": "be0545ccb62c32ac1f690fc8f916d2bbb926df8f394a73c4294959bbddc12ed3",
|
|
20
20
|
"sbom": {
|
|
21
21
|
"format": "CycloneDX-1.5",
|
|
22
22
|
"path": "planu-core.win32-x64-msvc.node.sbom.json",
|
|
23
|
-
"sha256": "
|
|
23
|
+
"sha256": "c859ada03fa2df805d9c64b5e4d742bd2a0f45d73f6749b187b1458fca90ae6c"
|
|
24
24
|
},
|
|
25
25
|
"provenance": {
|
|
26
26
|
"builder": "scripts/build-rust-local.sh",
|
|
27
|
-
"sourceCommit": "
|
|
27
|
+
"sourceCommit": "4c29cf026dcfa833b89a328afa3546aecbc02d22",
|
|
28
28
|
"sourceTreeDirty": false,
|
|
29
29
|
"sourceDateEpoch": 1,
|
|
30
30
|
"rustToolchain": "rustc 1.95.0 (59807616e 2026-04-14)",
|
|
@@ -33,6 +33,6 @@
|
|
|
33
33
|
"signature": {
|
|
34
34
|
"algorithm": "Ed25519",
|
|
35
35
|
"keyId": "e2ee765cb5ad9fbdc433ece332bce26d746d5e350b3acde0721a4c8c6337ff7b",
|
|
36
|
-
"value": "
|
|
36
|
+
"value": "Uui7dVZf7K+hIaahkXrmkoHi9ySHm1WR3+9bldHk8btGB9vFbqq29ThLuVIBX1RSNDxzI80dMJxNIRqkPIt3Bg=="
|
|
37
37
|
}
|
|
38
38
|
}
|
|
@@ -4,14 +4,14 @@
|
|
|
4
4
|
"version": 1,
|
|
5
5
|
"metadata": {
|
|
6
6
|
"component": {
|
|
7
|
-
"bom-ref": "pkg:cargo/planu-core@5.3.
|
|
7
|
+
"bom-ref": "pkg:cargo/planu-core@5.3.13",
|
|
8
8
|
"type": "library",
|
|
9
9
|
"name": "planu-core",
|
|
10
|
-
"version": "5.3.
|
|
10
|
+
"version": "5.3.13",
|
|
11
11
|
"hashes": [
|
|
12
12
|
{
|
|
13
13
|
"alg": "SHA-256",
|
|
14
|
-
"content": "
|
|
14
|
+
"content": "be0545ccb62c32ac1f690fc8f916d2bbb926df8f394a73c4294959bbddc12ed3"
|
|
15
15
|
}
|
|
16
16
|
]
|
|
17
17
|
}
|
|
@@ -1106,7 +1106,7 @@
|
|
|
1106
1106
|
"dependsOn": []
|
|
1107
1107
|
},
|
|
1108
1108
|
{
|
|
1109
|
-
"ref": "pkg:cargo/planu-core@5.3.
|
|
1109
|
+
"ref": "pkg:cargo/planu-core@5.3.13",
|
|
1110
1110
|
"dependsOn": [
|
|
1111
1111
|
"pkg:cargo/core-foundation@0.10.1",
|
|
1112
1112
|
"pkg:cargo/hmac@0.12.1",
|
|
@@ -119,10 +119,13 @@ function checkInterpolatedSections(content, criteria) {
|
|
|
119
119
|
}
|
|
120
120
|
const start = heading.index + heading[0].length;
|
|
121
121
|
const end = headingMatches[i + 1]?.index ?? content.length;
|
|
122
|
-
const
|
|
122
|
+
const bulletLines = content
|
|
123
123
|
.slice(start, end)
|
|
124
124
|
.split('\n')
|
|
125
|
-
.map((line) =>
|
|
125
|
+
.map((line) => line.trim())
|
|
126
|
+
.filter((line) => BULLET_LINE_RE.test(line));
|
|
127
|
+
const bullets = bulletLines
|
|
128
|
+
.map((line) => BULLET_LINE_RE.exec(line)?.[1])
|
|
126
129
|
.filter((line) => Boolean(line));
|
|
127
130
|
if (isFileListSection(bullets)) {
|
|
128
131
|
continue;
|
|
@@ -132,6 +135,7 @@ function checkInterpolatedSections(content, criteria) {
|
|
|
132
135
|
kind: STRUCTURAL_INTERPOLATION_KIND,
|
|
133
136
|
phrase: heading[1],
|
|
134
137
|
reason: `subsection "${heading[1]}" restates each criterion into the same template with no new information`,
|
|
138
|
+
evidence: bulletLines[0],
|
|
135
139
|
});
|
|
136
140
|
}
|
|
137
141
|
}
|
|
@@ -192,10 +196,22 @@ function restatesCriterion(variable, criteria) {
|
|
|
192
196
|
if (normalizedCriterion.length < CRITERION_RESTATEMENT_MIN_LENGTH) {
|
|
193
197
|
return false;
|
|
194
198
|
}
|
|
199
|
+
if (isCriterionPathTokenEcho(normalizedVariable, criterion)) {
|
|
200
|
+
return false;
|
|
201
|
+
}
|
|
195
202
|
return (normalizedVariable.includes(normalizedCriterion) ||
|
|
196
203
|
normalizedCriterion.includes(normalizedVariable));
|
|
197
204
|
});
|
|
198
205
|
}
|
|
206
|
+
function isCriterionPathTokenEcho(normalizedVariable, criterion) {
|
|
207
|
+
return criterionPathTokens(criterion).some((token) => normalizeForRestatementMatch(token).includes(normalizedVariable));
|
|
208
|
+
}
|
|
209
|
+
function criterionPathTokens(criterion) {
|
|
210
|
+
return criterion
|
|
211
|
+
.split(/\s+/)
|
|
212
|
+
.map((word) => word.replace(/^[`'"]+|[`'".,;:]+$/g, ''))
|
|
213
|
+
.filter((word) => PATH_TOKEN_RE.test(word));
|
|
214
|
+
}
|
|
199
215
|
function normalizeForRestatementMatch(value) {
|
|
200
216
|
return value
|
|
201
217
|
.replace(/[`*_"]/g, '')
|
|
@@ -927,6 +927,21 @@ function applyEnglishOnlyGate(gate) {
|
|
|
927
927
|
function quotePosixShellArgument(value) {
|
|
928
928
|
return `'${value.replaceAll("'", `'"'"'`)}'`;
|
|
929
929
|
}
|
|
930
|
+
/**
|
|
931
|
+
* SPEC-1469: the quality gate finding alone (`phrase` + `reason`) forced callers into
|
|
932
|
+
* trial-and-error rewording because it dropped the offending rendered line and the rule
|
|
933
|
+
* needed to pass. Quoting `evidence` verbatim and naming the generator-owned FILES:/TEST:
|
|
934
|
+
* marker exemption gives a what-failed + what-to-do-next message on the first read.
|
|
935
|
+
*/
|
|
936
|
+
function formatGenericOutputIssue(issue) {
|
|
937
|
+
const base = `${issue.phrase}: ${issue.reason}`;
|
|
938
|
+
if (!issue.evidence) {
|
|
939
|
+
return base;
|
|
940
|
+
}
|
|
941
|
+
return (`${base}. Offending row: "${issue.evidence}". ` +
|
|
942
|
+
"A row that only echoes a criterion's own mandatory FILES:/TEST: marker path is generator-owned " +
|
|
943
|
+
"and already exempt; rewrite the row's remaining content so it adds information beyond the fixed template.");
|
|
944
|
+
}
|
|
930
945
|
function earlyPreparation(result, clarificationProjectId) {
|
|
931
946
|
return {
|
|
932
947
|
kind: 'early',
|
|
@@ -1144,10 +1159,7 @@ async function prepareCreateSpecCandidate(initialParams, server) {
|
|
|
1144
1159
|
{
|
|
1145
1160
|
type: 'text',
|
|
1146
1161
|
text: 'Spec quality gate blocked generic output before persistence. ' +
|
|
1147
|
-
genericOutputGate.issues
|
|
1148
|
-
.slice(0, 3)
|
|
1149
|
-
.map((issue) => `${issue.phrase}: ${issue.reason}`)
|
|
1150
|
-
.join('; '),
|
|
1162
|
+
genericOutputGate.issues.slice(0, 3).map(formatGenericOutputIssue).join('; '),
|
|
1151
1163
|
},
|
|
1152
1164
|
],
|
|
1153
1165
|
isError: true,
|
|
@@ -67,6 +67,7 @@ import { reportClassifiedDegradation } from '../../errors/classified-degradation
|
|
|
67
67
|
import { captureValidationFreshnessLease } from '../../engine/validation/validation-freshness.js';
|
|
68
68
|
import { computeDurableValidationBindings, toValidationReceiptBindings, } from '../../engine/validation/durable-validation.js';
|
|
69
69
|
import { checkReconciliationFreshness } from '../../engine/evidence-gates/reconciliation-freshness.js';
|
|
70
|
+
import { doneReceiptBindingsDifferOnlyInEvidence } from './done-receipt-verifier.js';
|
|
70
71
|
import { extractCanonicalFileOwnership } from '../../engine/handoff-packager.js';
|
|
71
72
|
import { generateTaskPlanSkeleton, writeEvidenceSkeleton, } from '../../engine/evidence-gates/evidence-skeletons.js';
|
|
72
73
|
import { extractSection } from '../../engine/spec-format/markdown-sections.js';
|
|
@@ -285,8 +286,11 @@ async function currentBindingsAreFresh(identity, currentBindings) {
|
|
|
285
286
|
projectPath: identity.projectPath,
|
|
286
287
|
specPath,
|
|
287
288
|
});
|
|
288
|
-
|
|
289
|
-
|
|
289
|
+
const observedBindings = toValidationReceiptBindings(observed.bindings, observed.artifactDigests);
|
|
290
|
+
if (JSON.stringify(observedBindings) === JSON.stringify(currentBindings)) {
|
|
291
|
+
return true;
|
|
292
|
+
}
|
|
293
|
+
return doneReceiptBindingsDifferOnlyInEvidence(observedBindings, currentBindings);
|
|
290
294
|
}
|
|
291
295
|
catch (error) {
|
|
292
296
|
reportClassifiedDegradation('VALIDATION_RECEIPT_RECOMPUTE_FAILED', error);
|
|
@@ -45,6 +45,9 @@ export interface GenericSpecOutputIssue {
|
|
|
45
45
|
kind: GenericSpecOutputIssueKind;
|
|
46
46
|
phrase: string;
|
|
47
47
|
reason: string;
|
|
48
|
+
/** SPEC-1469: the first offending bullet verbatim, so the tool boundary can quote the exact
|
|
49
|
+
* rendered line instead of forcing the caller to guess which row collided. */
|
|
50
|
+
evidence?: string;
|
|
48
51
|
}
|
|
49
52
|
export interface GenericSpecOutputGateResult {
|
|
50
53
|
passed: boolean;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@planu/cli",
|
|
3
|
-
"version": "5.3.
|
|
3
|
+
"version": "5.3.13",
|
|
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",
|
|
@@ -35,14 +35,14 @@
|
|
|
35
35
|
"packageName": "@planu/core"
|
|
36
36
|
},
|
|
37
37
|
"optionalDependencies": {
|
|
38
|
-
"@planu/core-darwin-arm64": "5.3.
|
|
39
|
-
"@planu/core-darwin-x64": "5.3.
|
|
40
|
-
"@planu/core-linux-arm64-gnu": "5.3.
|
|
41
|
-
"@planu/core-linux-arm64-musl": "5.3.
|
|
42
|
-
"@planu/core-linux-x64-gnu": "5.3.
|
|
43
|
-
"@planu/core-linux-x64-musl": "5.3.
|
|
44
|
-
"@planu/core-win32-arm64-msvc": "5.3.
|
|
45
|
-
"@planu/core-win32-x64-msvc": "5.3.
|
|
38
|
+
"@planu/core-darwin-arm64": "5.3.13",
|
|
39
|
+
"@planu/core-darwin-x64": "5.3.13",
|
|
40
|
+
"@planu/core-linux-arm64-gnu": "5.3.13",
|
|
41
|
+
"@planu/core-linux-arm64-musl": "5.3.13",
|
|
42
|
+
"@planu/core-linux-x64-gnu": "5.3.13",
|
|
43
|
+
"@planu/core-linux-x64-musl": "5.3.13",
|
|
44
|
+
"@planu/core-win32-arm64-msvc": "5.3.13",
|
|
45
|
+
"@planu/core-win32-x64-msvc": "5.3.13"
|
|
46
46
|
},
|
|
47
47
|
"engines": {
|
|
48
48
|
"node": ">=24.0.0"
|
package/planu-native.json
CHANGED
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.13",
|
|
6
6
|
"icon": "assets/plugin/icon.svg",
|
|
7
7
|
"command": ["npx", "@planu/cli@latest"],
|
|
8
8
|
"packageName": "@planu/cli",
|