@planu/cli 4.6.1 → 4.7.1
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 +18 -0
- package/dist/config/project-knowledge-graph.json +65 -0
- package/dist/engine/project-graph/builder.d.ts +7 -0
- package/dist/engine/project-graph/builder.js +92 -0
- package/dist/engine/project-graph/cache.d.ts +26 -0
- package/dist/engine/project-graph/cache.js +160 -0
- package/dist/engine/project-graph/extractors/git-extractor.d.ts +7 -0
- package/dist/engine/project-graph/extractors/git-extractor.js +89 -0
- package/dist/engine/project-graph/extractors/handoff-extractor.d.ts +3 -0
- package/dist/engine/project-graph/extractors/handoff-extractor.js +55 -0
- package/dist/engine/project-graph/extractors/spec-extractor.d.ts +3 -0
- package/dist/engine/project-graph/extractors/spec-extractor.js +189 -0
- package/dist/engine/project-graph/extractors/validation-extractor.d.ts +3 -0
- package/dist/engine/project-graph/extractors/validation-extractor.js +36 -0
- package/dist/engine/project-graph/index.d.ts +4 -0
- package/dist/engine/project-graph/index.js +4 -0
- package/dist/engine/project-graph/query.d.ts +9 -0
- package/dist/engine/project-graph/query.js +161 -0
- package/dist/tools/create-spec/post-creation.js +13 -1
- package/dist/tools/package-handoff.js +31 -2
- package/dist/tools/schemas/index.d.ts +1 -0
- package/dist/tools/schemas/index.js +1 -0
- package/dist/tools/schemas/project-graph.d.ts +18 -0
- package/dist/tools/schemas/project-graph.js +8 -0
- package/dist/tools/schemas/token-intelligence.d.ts +1 -0
- package/dist/tools/schemas/token-intelligence.js +3 -2
- package/dist/tools/status-handler.js +9 -2
- package/dist/tools/token-intelligence-handler.js +28 -1
- package/dist/tools/validate.js +75 -30
- package/dist/types/index.d.ts +1 -0
- package/dist/types/index.js +1 -0
- package/dist/types/project-knowledge-graph.d.ts +139 -0
- package/dist/types/project-knowledge-graph.js +2 -0
- package/package.json +12 -11
- package/planu-native.json +1 -1
- package/planu-plugin.json +1 -1
|
@@ -2,6 +2,7 @@ import { getEntries, getAggregation } from '../storage/token-ledger-store.js';
|
|
|
2
2
|
import { hashProjectPath } from '../storage/base-store.js';
|
|
3
3
|
import { buildTokenWasteReport, detectTokenWasteLoops, formatTokenWasteReport, loadTokenWastePolicy, recommendRelevantTools, } from '../engine/token-optimizer/index.js';
|
|
4
4
|
import { join } from 'node:path';
|
|
5
|
+
import { formatProjectGraphContext, queryProjectGraphSlice, } from '../engine/project-graph/index.js';
|
|
5
6
|
// ---------------------------------------------------------------------------
|
|
6
7
|
// Constants
|
|
7
8
|
// ---------------------------------------------------------------------------
|
|
@@ -390,6 +391,26 @@ async function renderAutopilot(entries, agg, period, projectPath) {
|
|
|
390
391
|
'',
|
|
391
392
|
].join('\n');
|
|
392
393
|
}
|
|
394
|
+
async function renderGraphView(projectPath, specId) {
|
|
395
|
+
const slice = await queryProjectGraphSlice({ projectPath, specId }).catch(() => null);
|
|
396
|
+
if (slice === null) {
|
|
397
|
+
return [
|
|
398
|
+
'# Token Intelligence Dashboard — Graph View',
|
|
399
|
+
'',
|
|
400
|
+
'Project graph is unavailable; existing token intelligence views still work.',
|
|
401
|
+
'',
|
|
402
|
+
].join('\n');
|
|
403
|
+
}
|
|
404
|
+
return [
|
|
405
|
+
'# Token Intelligence Dashboard — Graph View',
|
|
406
|
+
'',
|
|
407
|
+
`Graph freshness: ${slice.freshness.stale ? slice.freshness.reason : 'fresh'}`,
|
|
408
|
+
`Compact slice: ${String(slice.nodes.length)} nodes / ${String(slice.edges.length)} edges`,
|
|
409
|
+
`Estimated raw context avoided: ${String(slice.tokenSavings.estimatedRawContextAvoided)} graph items`,
|
|
410
|
+
'',
|
|
411
|
+
await formatProjectGraphContext(slice),
|
|
412
|
+
].join('\n');
|
|
413
|
+
}
|
|
393
414
|
// ---------------------------------------------------------------------------
|
|
394
415
|
// Empty state
|
|
395
416
|
// ---------------------------------------------------------------------------
|
|
@@ -429,7 +450,10 @@ export async function handleTokenIntelligence(input) {
|
|
|
429
450
|
getEntries(projectHash, dataDir, filter),
|
|
430
451
|
getAggregation(projectHash, dataDir, filter),
|
|
431
452
|
]);
|
|
432
|
-
if (entries.length === 0 &&
|
|
453
|
+
if (entries.length === 0 &&
|
|
454
|
+
view !== 'reconciliation' &&
|
|
455
|
+
view !== 'autopilot' &&
|
|
456
|
+
view !== 'graph') {
|
|
433
457
|
return { content: [{ type: 'text', text: renderEmpty(view, period) }] };
|
|
434
458
|
}
|
|
435
459
|
let text;
|
|
@@ -449,6 +473,9 @@ export async function handleTokenIntelligence(input) {
|
|
|
449
473
|
case 'autopilot':
|
|
450
474
|
text = await renderAutopilot(entries, agg, period, projectPath);
|
|
451
475
|
break;
|
|
476
|
+
case 'graph':
|
|
477
|
+
text = await renderGraphView(projectPath, specId);
|
|
478
|
+
break;
|
|
452
479
|
default:
|
|
453
480
|
text = renderSummary(agg, entries, period, groupBy);
|
|
454
481
|
break;
|
package/dist/tools/validate.js
CHANGED
|
@@ -17,8 +17,67 @@ import { validateScopeCompliance } from '../engine/scope-boundaries/index.js';
|
|
|
17
17
|
import { compareWithBaseline } from '../storage/convention-baseline.js';
|
|
18
18
|
import { writeImplementationReviewReport } from '../engine/validator/validation-report-writer.js';
|
|
19
19
|
import { evaluateNewCodeGate } from '../engine/ai-assurance/index.js';
|
|
20
|
+
import { queryProjectGraphSlice } from '../engine/project-graph/index.js';
|
|
20
21
|
// Re-export for external use (SPEC-018)
|
|
21
22
|
export { validateContractCompliance };
|
|
23
|
+
function graphCoverageGaps(slice) {
|
|
24
|
+
if (slice === null) {
|
|
25
|
+
return [];
|
|
26
|
+
}
|
|
27
|
+
const criteria = slice.nodes.filter((node) => node.type === 'criterion');
|
|
28
|
+
return criteria
|
|
29
|
+
.filter((criterion) => {
|
|
30
|
+
const outgoing = slice.edges.filter((edge) => edge.from === criterion.id);
|
|
31
|
+
return !outgoing.some((edge) => edge.type === 'implements' || edge.type === 'tests');
|
|
32
|
+
})
|
|
33
|
+
.map((criterion) => criterion.label)
|
|
34
|
+
.slice(0, 10);
|
|
35
|
+
}
|
|
36
|
+
async function buildGraphCoverageReport(args) {
|
|
37
|
+
const graphSlice = await queryProjectGraphSlice(args).catch(() => null);
|
|
38
|
+
return {
|
|
39
|
+
freshness: graphSlice?.freshness,
|
|
40
|
+
gaps: graphCoverageGaps(graphSlice),
|
|
41
|
+
compactNodes: graphSlice?.nodes.length ?? 0,
|
|
42
|
+
compactEdges: graphSlice?.edges.length ?? 0,
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
function formatGraphCoverageText(report) {
|
|
46
|
+
return report.gaps.length > 0
|
|
47
|
+
? `\nGRAPH ${String(report.gaps.length)} graph-backed coverage gap(s)`
|
|
48
|
+
: '';
|
|
49
|
+
}
|
|
50
|
+
async function validateStrictLayoutOrError(args) {
|
|
51
|
+
try {
|
|
52
|
+
const { validateStrictPlanuLayout } = await import('../engine/spec-migrator/index.js');
|
|
53
|
+
const layout = await validateStrictPlanuLayout(args.projectPath, {
|
|
54
|
+
specPath: args.specPath,
|
|
55
|
+
includeRoot: false,
|
|
56
|
+
});
|
|
57
|
+
if (layout.ok) {
|
|
58
|
+
return null;
|
|
59
|
+
}
|
|
60
|
+
return {
|
|
61
|
+
content: [
|
|
62
|
+
{
|
|
63
|
+
type: 'text',
|
|
64
|
+
text: `Strict Planu layout validation failed for ${args.specId}.\n\n` +
|
|
65
|
+
`Non-canonical paths:\n${layout.offenders.map((p) => `- ${p}`).join('\n')}\n\n` +
|
|
66
|
+
`Canonical contract:\n${layout.contract}`,
|
|
67
|
+
},
|
|
68
|
+
],
|
|
69
|
+
isError: true,
|
|
70
|
+
structuredContent: {
|
|
71
|
+
error: 'strict_planu_layout_violation',
|
|
72
|
+
offenders: layout.offenders,
|
|
73
|
+
contract: layout.contract,
|
|
74
|
+
},
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
catch {
|
|
78
|
+
return null;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
22
81
|
/** Build the fallback interactiveQuestion for validation failures. */
|
|
23
82
|
function buildValidateFailureFallback(failedCount) {
|
|
24
83
|
return {
|
|
@@ -72,36 +131,17 @@ export async function handleValidate(args, server) {
|
|
|
72
131
|
}
|
|
73
132
|
const projectPath = knowledge.projectPath;
|
|
74
133
|
// SPEC-1017: fail closed when planu/ contains non-canonical artifacts.
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
return {
|
|
83
|
-
content: [
|
|
84
|
-
{
|
|
85
|
-
type: 'text',
|
|
86
|
-
text: `Strict Planu layout validation failed for ${specId}.\n\n` +
|
|
87
|
-
`Non-canonical paths:\n${layout.offenders.map((p) => `- ${p}`).join('\n')}\n\n` +
|
|
88
|
-
`Canonical contract:\n${layout.contract}`,
|
|
89
|
-
},
|
|
90
|
-
],
|
|
91
|
-
isError: true,
|
|
92
|
-
structuredContent: {
|
|
93
|
-
error: 'strict_planu_layout_violation',
|
|
94
|
-
offenders: layout.offenders,
|
|
95
|
-
contract: layout.contract,
|
|
96
|
-
},
|
|
97
|
-
};
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
catch {
|
|
101
|
-
/* best-effort — implementation validation still runs if layout check is unavailable */
|
|
134
|
+
const strictLayoutError = await validateStrictLayoutOrError({
|
|
135
|
+
projectPath,
|
|
136
|
+
specId,
|
|
137
|
+
specPath: spec.specPath,
|
|
138
|
+
});
|
|
139
|
+
if (strictLayoutError !== null) {
|
|
140
|
+
return strictLayoutError;
|
|
102
141
|
}
|
|
103
142
|
// 3. Run validation engine
|
|
104
143
|
const result = await validateSpec(spec, projectPath);
|
|
144
|
+
const graphCoverage = await buildGraphCoverageReport({ projectId, projectPath, specId });
|
|
105
145
|
// 4. Generate DoR and DoD checklists
|
|
106
146
|
const dor = generateDoR(spec);
|
|
107
147
|
const dod = await generateDoD(spec, result, undefined, projectPath);
|
|
@@ -222,6 +262,7 @@ export async function handleValidate(args, server) {
|
|
|
222
262
|
lintCheck,
|
|
223
263
|
assuranceGates,
|
|
224
264
|
validationReport,
|
|
265
|
+
graphCoverage,
|
|
225
266
|
};
|
|
226
267
|
// SPEC-612: Scope boundary validation — warn if impl files match outOfScope items
|
|
227
268
|
if (spec.outOfScope !== undefined && spec.outOfScope.length > 0) {
|
|
@@ -256,6 +297,9 @@ export async function handleValidate(args, server) {
|
|
|
256
297
|
if (result.missing.length > 0) {
|
|
257
298
|
suggestions.push(`${result.missing.length} criteria still missing. Run detect_drift to identify gaps.`);
|
|
258
299
|
}
|
|
300
|
+
if (graphCoverage.gaps.length > 0) {
|
|
301
|
+
suggestions.push(`${graphCoverage.gaps.length} graph-backed coverage gap(s) found without broad repository scan.`);
|
|
302
|
+
}
|
|
259
303
|
if (conventionViolations.length > 0) {
|
|
260
304
|
suggestions.push(`${conventionViolations.length} convention violation(s) detected. Fix before marking as done.`);
|
|
261
305
|
}
|
|
@@ -327,6 +371,7 @@ export async function handleValidate(args, server) {
|
|
|
327
371
|
commitReminder,
|
|
328
372
|
planuReminder,
|
|
329
373
|
});
|
|
374
|
+
const graphText = formatGraphCoverageText(graphCoverage);
|
|
330
375
|
// SPEC-512: Compact structuredContent — essential fields only at top level
|
|
331
376
|
const compactSummary = {
|
|
332
377
|
specId,
|
|
@@ -346,7 +391,7 @@ export async function handleValidate(args, server) {
|
|
|
346
391
|
return {
|
|
347
392
|
phaseEvent: createBasicPhaseEvent('validate', 'completed', 100, 'validating'),
|
|
348
393
|
content: [
|
|
349
|
-
{ type: 'text', text: compactText },
|
|
394
|
+
{ type: 'text', text: compactText + graphText },
|
|
350
395
|
{
|
|
351
396
|
type: 'text',
|
|
352
397
|
text: '⚡ INTERACTIVE — call AskUserQuestion now with the interactiveQuestions from structuredContent',
|
|
@@ -364,7 +409,7 @@ export async function handleValidate(args, server) {
|
|
|
364
409
|
: 're-implement';
|
|
365
410
|
return {
|
|
366
411
|
phaseEvent: createBasicPhaseEvent('validate', 'completed', 100, 'validating'),
|
|
367
|
-
content: [{ type: 'text', text: compactText }],
|
|
412
|
+
content: [{ type: 'text', text: compactText + graphText }],
|
|
368
413
|
structuredContent: {
|
|
369
414
|
...outputWithSuggestions,
|
|
370
415
|
summary: compactSummary,
|
|
@@ -374,7 +419,7 @@ export async function handleValidate(args, server) {
|
|
|
374
419
|
}
|
|
375
420
|
return {
|
|
376
421
|
phaseEvent: createBasicPhaseEvent('validate', 'completed', 100, 'validating'),
|
|
377
|
-
content: [{ type: 'text', text: compactText }],
|
|
422
|
+
content: [{ type: 'text', text: compactText + graphText }],
|
|
378
423
|
structuredContent: {
|
|
379
424
|
...outputWithSuggestions,
|
|
380
425
|
summary: compactSummary,
|
package/dist/types/index.d.ts
CHANGED
|
@@ -220,6 +220,7 @@ export * from './sentry.js';
|
|
|
220
220
|
export * from './supabase.js';
|
|
221
221
|
export * from './skill-bootstrap.js';
|
|
222
222
|
export * from './technology-selection.js';
|
|
223
|
+
export * from './project-knowledge-graph.js';
|
|
223
224
|
export * from './compliance-gate.js';
|
|
224
225
|
export * from './schema-parity.js';
|
|
225
226
|
export * from './auto-update.js';
|
package/dist/types/index.js
CHANGED
|
@@ -217,6 +217,7 @@ export * from './sentry.js';
|
|
|
217
217
|
export * from './supabase.js';
|
|
218
218
|
export * from './skill-bootstrap.js';
|
|
219
219
|
export * from './technology-selection.js';
|
|
220
|
+
export * from './project-knowledge-graph.js';
|
|
220
221
|
export * from './compliance-gate.js';
|
|
221
222
|
export * from './schema-parity.js';
|
|
222
223
|
export * from './auto-update.js';
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
export type ProjectGraphNodeType = string;
|
|
2
|
+
export type ProjectGraphEdgeType = string;
|
|
3
|
+
export type ProjectGraphConfidence = 'high' | 'medium' | 'low';
|
|
4
|
+
export type ProjectGraphEdgeClassification = 'extracted' | 'inferred' | 'ambiguous';
|
|
5
|
+
export interface ProjectGraphPolicy {
|
|
6
|
+
version: 1;
|
|
7
|
+
graphVersion: string;
|
|
8
|
+
enabled: boolean;
|
|
9
|
+
artifactPaths: {
|
|
10
|
+
directory: string;
|
|
11
|
+
graph: string;
|
|
12
|
+
sourceHashes: string;
|
|
13
|
+
};
|
|
14
|
+
nodeTypes: string[];
|
|
15
|
+
edgeTypes: string[];
|
|
16
|
+
classifications: ProjectGraphEdgeClassification[];
|
|
17
|
+
confidenceLabels: ProjectGraphConfidence[];
|
|
18
|
+
freshness: {
|
|
19
|
+
staleAfterMinutes: number;
|
|
20
|
+
};
|
|
21
|
+
query: {
|
|
22
|
+
maxNodes: number;
|
|
23
|
+
maxEdges: number;
|
|
24
|
+
maxListItems: number;
|
|
25
|
+
};
|
|
26
|
+
redaction: {
|
|
27
|
+
maxSnippetChars: number;
|
|
28
|
+
redactPatterns: string[];
|
|
29
|
+
};
|
|
30
|
+
toolNamePatterns: string[];
|
|
31
|
+
}
|
|
32
|
+
export interface ProjectGraphEvidencePointer {
|
|
33
|
+
path: string;
|
|
34
|
+
selector?: string;
|
|
35
|
+
hash?: string;
|
|
36
|
+
}
|
|
37
|
+
export interface ProjectGraphNode {
|
|
38
|
+
id: string;
|
|
39
|
+
type: ProjectGraphNodeType;
|
|
40
|
+
label: string;
|
|
41
|
+
source: string;
|
|
42
|
+
evidence: ProjectGraphEvidencePointer[];
|
|
43
|
+
metadata?: Record<string, string | number | boolean | string[] | null>;
|
|
44
|
+
updatedAt: string;
|
|
45
|
+
}
|
|
46
|
+
export interface ProjectGraphEdge {
|
|
47
|
+
id: string;
|
|
48
|
+
from: string;
|
|
49
|
+
to: string;
|
|
50
|
+
type: ProjectGraphEdgeType;
|
|
51
|
+
source: string;
|
|
52
|
+
confidence: ProjectGraphConfidence;
|
|
53
|
+
evidence: ProjectGraphEvidencePointer;
|
|
54
|
+
classification: ProjectGraphEdgeClassification;
|
|
55
|
+
updatedAt: string;
|
|
56
|
+
}
|
|
57
|
+
export interface ProjectKnowledgeGraph {
|
|
58
|
+
version: 1;
|
|
59
|
+
graphVersion: string;
|
|
60
|
+
projectId: string;
|
|
61
|
+
projectPath?: string;
|
|
62
|
+
generatedAt: string;
|
|
63
|
+
sourceHash: string;
|
|
64
|
+
sourceHashes: Record<string, string>;
|
|
65
|
+
metadata: {
|
|
66
|
+
nodeCount: number;
|
|
67
|
+
edgeCount: number;
|
|
68
|
+
sourceCount: number;
|
|
69
|
+
reprocessedSourceCount: number;
|
|
70
|
+
skippedSourceCount: number;
|
|
71
|
+
};
|
|
72
|
+
nodes: ProjectGraphNode[];
|
|
73
|
+
edges: ProjectGraphEdge[];
|
|
74
|
+
}
|
|
75
|
+
export interface ProjectGraphSource {
|
|
76
|
+
id: string;
|
|
77
|
+
kind: string;
|
|
78
|
+
path: string;
|
|
79
|
+
content: string;
|
|
80
|
+
hash: string;
|
|
81
|
+
}
|
|
82
|
+
export interface ProjectGraphExtractionResult {
|
|
83
|
+
nodes: ProjectGraphNode[];
|
|
84
|
+
edges: ProjectGraphEdge[];
|
|
85
|
+
}
|
|
86
|
+
export interface ProjectGraphBuildResult {
|
|
87
|
+
graph: ProjectKnowledgeGraph;
|
|
88
|
+
graphPath: string;
|
|
89
|
+
cachePath: string;
|
|
90
|
+
reprocessedSources: string[];
|
|
91
|
+
skippedSources: string[];
|
|
92
|
+
usedCache: boolean;
|
|
93
|
+
}
|
|
94
|
+
export interface ProjectGraphFreshness {
|
|
95
|
+
exists: boolean;
|
|
96
|
+
stale: boolean;
|
|
97
|
+
reason: 'missing' | 'fresh' | 'expired' | 'source_changed' | 'corrupt';
|
|
98
|
+
graphPath: string;
|
|
99
|
+
generatedAt?: string;
|
|
100
|
+
changedSources: string[];
|
|
101
|
+
}
|
|
102
|
+
export interface ProjectGraphSlice {
|
|
103
|
+
graphVersion: string;
|
|
104
|
+
generatedAt: string;
|
|
105
|
+
freshness: ProjectGraphFreshness;
|
|
106
|
+
nodes: ProjectGraphNode[];
|
|
107
|
+
edges: ProjectGraphEdge[];
|
|
108
|
+
summary: {
|
|
109
|
+
specs: number;
|
|
110
|
+
criteria: number;
|
|
111
|
+
files: number;
|
|
112
|
+
tests: number;
|
|
113
|
+
decisions: number;
|
|
114
|
+
risks: number;
|
|
115
|
+
tools: number;
|
|
116
|
+
releases: number;
|
|
117
|
+
};
|
|
118
|
+
tokenSavings: {
|
|
119
|
+
compactNodes: number;
|
|
120
|
+
compactEdges: number;
|
|
121
|
+
estimatedRawContextAvoided: number;
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
export interface ProjectGraphQueryInput {
|
|
125
|
+
projectId?: string;
|
|
126
|
+
projectPath: string;
|
|
127
|
+
specId?: string;
|
|
128
|
+
filePath?: string;
|
|
129
|
+
nodeId?: string;
|
|
130
|
+
maxNodes?: number;
|
|
131
|
+
maxEdges?: number;
|
|
132
|
+
}
|
|
133
|
+
export interface GraphCoverageReport {
|
|
134
|
+
freshness?: ProjectGraphFreshness;
|
|
135
|
+
gaps: string[];
|
|
136
|
+
compactNodes: number;
|
|
137
|
+
compactEdges: number;
|
|
138
|
+
}
|
|
139
|
+
//# sourceMappingURL=project-knowledge-graph.d.ts.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@planu/cli",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.7.1",
|
|
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",
|
|
@@ -34,14 +34,14 @@
|
|
|
34
34
|
"packageName": "@planu/core"
|
|
35
35
|
},
|
|
36
36
|
"optionalDependencies": {
|
|
37
|
-
"@planu/core-darwin-arm64": "4.
|
|
38
|
-
"@planu/core-darwin-x64": "4.
|
|
39
|
-
"@planu/core-linux-arm64-gnu": "4.
|
|
40
|
-
"@planu/core-linux-arm64-musl": "4.
|
|
41
|
-
"@planu/core-linux-x64-gnu": "4.
|
|
42
|
-
"@planu/core-linux-x64-musl": "4.
|
|
43
|
-
"@planu/core-win32-arm64-msvc": "4.
|
|
44
|
-
"@planu/core-win32-x64-msvc": "4.
|
|
37
|
+
"@planu/core-darwin-arm64": "4.7.1",
|
|
38
|
+
"@planu/core-darwin-x64": "4.7.1",
|
|
39
|
+
"@planu/core-linux-arm64-gnu": "4.7.1",
|
|
40
|
+
"@planu/core-linux-arm64-musl": "4.7.1",
|
|
41
|
+
"@planu/core-linux-x64-gnu": "4.7.1",
|
|
42
|
+
"@planu/core-linux-x64-musl": "4.7.1",
|
|
43
|
+
"@planu/core-win32-arm64-msvc": "4.7.1",
|
|
44
|
+
"@planu/core-win32-x64-msvc": "4.7.1"
|
|
45
45
|
},
|
|
46
46
|
"engines": {
|
|
47
47
|
"node": ">=24.0.0"
|
|
@@ -147,6 +147,7 @@
|
|
|
147
147
|
"lodash-es": ">=4.18.0",
|
|
148
148
|
"hono": ">=4.12.14",
|
|
149
149
|
"postcss": ">=8.5.10",
|
|
150
|
+
"esbuild": "0.28.1",
|
|
150
151
|
"fast-uri": ">=3.1.2",
|
|
151
152
|
"qs": ">=6.15.2"
|
|
152
153
|
},
|
|
@@ -186,11 +187,11 @@
|
|
|
186
187
|
"@vitejs/plugin-vue": "^6.0.7",
|
|
187
188
|
"@vitest/coverage-v8": "^4.1.8",
|
|
188
189
|
"@vue/test-utils": "^2.4.11",
|
|
189
|
-
"eslint": "^10.
|
|
190
|
+
"eslint": "^10.5.0",
|
|
190
191
|
"eslint-config-prettier": "^10.1.8",
|
|
191
192
|
"eslint-import-resolver-typescript": "^4.4.5",
|
|
192
193
|
"eslint-plugin-import": "^2.32.0",
|
|
193
|
-
"happy-dom": "^20.10.
|
|
194
|
+
"happy-dom": "^20.10.3",
|
|
194
195
|
"husky": "^9.1.7",
|
|
195
196
|
"javascript-obfuscator": "^5.4.3",
|
|
196
197
|
"knip": "^6.16.1",
|
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": "4.
|
|
5
|
+
"version": "4.7.1",
|
|
6
6
|
"icon": "assets/plugin/icon.svg",
|
|
7
7
|
"command": [
|
|
8
8
|
"npx",
|