@planu/cli 5.3.64 → 5.3.65
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
CHANGED
package/dist/.planu-build.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"schemaVersion":1,"commit":"
|
|
1
|
+
{"schemaVersion":1,"commit":"edd0806d011981ac5b4185880a2871baa5497384"}
|
|
@@ -7,6 +7,35 @@ function knowledgeFile(projectId) {
|
|
|
7
7
|
function isKnowledgeOrNull(value) {
|
|
8
8
|
return value === null || (typeof value === 'object' && !Array.isArray(value));
|
|
9
9
|
}
|
|
10
|
+
function neutralArchitectureDetection() {
|
|
11
|
+
return {
|
|
12
|
+
primary: 'custom',
|
|
13
|
+
secondary: [],
|
|
14
|
+
layers: [],
|
|
15
|
+
boundaries: [],
|
|
16
|
+
communicationPatterns: [],
|
|
17
|
+
deploymentUnits: [],
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
function isValidArchitectureDetection(value) {
|
|
21
|
+
if (typeof value !== 'object' || value === null) {
|
|
22
|
+
return false;
|
|
23
|
+
}
|
|
24
|
+
const candidate = value;
|
|
25
|
+
return (typeof candidate.primary === 'string' &&
|
|
26
|
+
candidate.primary.length > 0 &&
|
|
27
|
+
Array.isArray(candidate.secondary) &&
|
|
28
|
+
Array.isArray(candidate.layers) &&
|
|
29
|
+
Array.isArray(candidate.boundaries) &&
|
|
30
|
+
Array.isArray(candidate.communicationPatterns) &&
|
|
31
|
+
Array.isArray(candidate.deploymentUnits));
|
|
32
|
+
}
|
|
33
|
+
function withNormalizedArchitecture(knowledge) {
|
|
34
|
+
if (isValidArchitectureDetection(knowledge.architecture)) {
|
|
35
|
+
return knowledge;
|
|
36
|
+
}
|
|
37
|
+
return { ...knowledge, architecture: neutralArchitectureDetection() };
|
|
38
|
+
}
|
|
10
39
|
registerCriticalSchema({
|
|
11
40
|
name: 'project-knowledge',
|
|
12
41
|
currentVersion: 1,
|
|
@@ -20,7 +49,8 @@ registerCriticalSchema({
|
|
|
20
49
|
},
|
|
21
50
|
});
|
|
22
51
|
async function readKnowledge(projectId) {
|
|
23
|
-
|
|
52
|
+
const knowledge = (await readCriticalSchema(knowledgeFile(projectId), 'project-knowledge')).data;
|
|
53
|
+
return knowledge === null ? null : withNormalizedArchitecture(knowledge);
|
|
24
54
|
}
|
|
25
55
|
async function writeKnowledge(projectId, knowledge) {
|
|
26
56
|
await writeJson(knowledgeFile(projectId), { schemaVersion: 1, data: knowledge });
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
// Planu — Agent Challenge Scenarios
|
|
2
2
|
// SPEC-016a criteria 4 and 19: AI agent-specific failure modes for challenge_spec.
|
|
3
|
+
import { hasAffirmedMatch } from '../../engine/text-signal-boundaries.js';
|
|
3
4
|
/**
|
|
4
5
|
* Generate AI agent-specific failure scenarios.
|
|
5
6
|
* Criteria 4: hallucinations, data leaks, wrong decisions, rate limits, cost.
|
|
@@ -89,19 +90,39 @@ export function generateAgentChallengeScenarios(spec, _specContent, _knowledge)
|
|
|
89
90
|
});
|
|
90
91
|
return scenarios;
|
|
91
92
|
}
|
|
93
|
+
const AGENT_CONTENT_DISJUNCT_TERM = '(?:ai\\s+agent|agent\\s+contract|llm|tool\\s+call)';
|
|
94
|
+
const AGENT_RUNTIME_EVIDENCE_TERM = '(?:tool\\s+schema|mcp|handler|agent\\s+loop|subagent|llm\\s+call|inputschema|tool\\s+definition)';
|
|
95
|
+
const AGENT_CONTENT_EVIDENCE_PROXIMITY_RE = new RegExp(`\\b${AGENT_CONTENT_DISJUNCT_TERM}\\b(?:\\W+\\w+){0,6}?\\W+\\b${AGENT_RUNTIME_EVIDENCE_TERM}\\b` +
|
|
96
|
+
`|\\b${AGENT_RUNTIME_EVIDENCE_TERM}\\b(?:\\W+\\w+){0,6}?\\W+\\b${AGENT_CONTENT_DISJUNCT_TERM}\\b`, 'i');
|
|
97
|
+
const AGENT_TITLE_DISJUNCT_RE = /\b(?:agent|assistant|bot)\b/i;
|
|
98
|
+
const AGENT_OR_MCP_FILE_OWNERSHIP_RE = /\b[\w./-]*(?:agent|mcp)[\w./-]*\.(?:ts|tsx|js|jsx|mjs|cjs)\b/i;
|
|
99
|
+
function hasAgentRuntimeEvidenceNearby(specContent) {
|
|
100
|
+
return hasAffirmedMatch(specContent, AGENT_CONTENT_EVIDENCE_PROXIMITY_RE);
|
|
101
|
+
}
|
|
102
|
+
const FILES_SECTION_HEADING_RE = /^##\s+Files\s*$/im;
|
|
103
|
+
const NEXT_SECTION_HEADING_RE = /^##\s+/m;
|
|
104
|
+
function extractFilesSection(specContent) {
|
|
105
|
+
const headingMatch = FILES_SECTION_HEADING_RE.exec(specContent);
|
|
106
|
+
if (headingMatch === null) {
|
|
107
|
+
return '';
|
|
108
|
+
}
|
|
109
|
+
const sectionStart = headingMatch.index + headingMatch[0].length;
|
|
110
|
+
const remainder = specContent.slice(sectionStart);
|
|
111
|
+
const nextHeadingMatch = NEXT_SECTION_HEADING_RE.exec(remainder);
|
|
112
|
+
return nextHeadingMatch === null ? remainder : remainder.slice(0, nextHeadingMatch.index);
|
|
113
|
+
}
|
|
114
|
+
function titleClaimsAgentOrMcpSurface(spec, specContent) {
|
|
115
|
+
if (!AGENT_TITLE_DISJUNCT_RE.test(spec.title)) {
|
|
116
|
+
return false;
|
|
117
|
+
}
|
|
118
|
+
return AGENT_OR_MCP_FILE_OWNERSHIP_RE.test(extractFilesSection(specContent));
|
|
119
|
+
}
|
|
92
120
|
/**
|
|
93
121
|
* Check whether the spec is an AI agent spec.
|
|
94
122
|
*/
|
|
95
123
|
export function isAgentSpec(spec, specContent) {
|
|
96
|
-
const lower = specContent.toLowerCase();
|
|
97
|
-
const titleLower = spec.title.toLowerCase();
|
|
98
124
|
return (spec.type === 'agent' ||
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
lower.includes('llm') ||
|
|
102
|
-
lower.includes('tool call') ||
|
|
103
|
-
titleLower.includes('agent') ||
|
|
104
|
-
titleLower.includes('assistant') ||
|
|
105
|
-
titleLower.includes('bot'));
|
|
125
|
+
hasAgentRuntimeEvidenceNearby(specContent) ||
|
|
126
|
+
titleClaimsAgentOrMcpSurface(spec, specContent));
|
|
106
127
|
}
|
|
107
128
|
//# sourceMappingURL=agent-challenge-scenarios.js.map
|
package/package.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.65",
|
|
6
6
|
"icon": "assets/plugin/icon.svg",
|
|
7
7
|
"command": ["npx", "@planu/cli@latest"],
|
|
8
8
|
"packageName": "@planu/cli",
|