@planu/cli 0.97.2 → 0.98.0
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/dist/config/license-plans.json +6 -2
- package/dist/config/mobile-ci-templates/android-github-actions.yml +149 -0
- package/dist/config/mobile-ci-templates/ios-github-actions.yml +120 -0
- package/dist/engine/api-validation/graphql-schema-validator.d.ts +3 -0
- package/dist/engine/api-validation/graphql-schema-validator.d.ts.map +1 -0
- package/dist/engine/api-validation/graphql-schema-validator.js +134 -0
- package/dist/engine/api-validation/graphql-schema-validator.js.map +1 -0
- package/dist/engine/api-validation/index.d.ts +3 -0
- package/dist/engine/api-validation/index.d.ts.map +1 -0
- package/dist/engine/api-validation/index.js +4 -0
- package/dist/engine/api-validation/index.js.map +1 -0
- package/dist/engine/api-validation/openapi-impl-validator.d.ts +3 -0
- package/dist/engine/api-validation/openapi-impl-validator.d.ts.map +1 -0
- package/dist/engine/api-validation/openapi-impl-validator.js +205 -0
- package/dist/engine/api-validation/openapi-impl-validator.js.map +1 -0
- package/dist/engine/ci-generator/android-jobs.d.ts +17 -0
- package/dist/engine/ci-generator/android-jobs.d.ts.map +1 -0
- package/dist/engine/ci-generator/android-jobs.js +168 -0
- package/dist/engine/ci-generator/android-jobs.js.map +1 -0
- package/dist/engine/ci-generator/ios-jobs.d.ts +17 -0
- package/dist/engine/ci-generator/ios-jobs.d.ts.map +1 -0
- package/dist/engine/ci-generator/ios-jobs.js +151 -0
- package/dist/engine/ci-generator/ios-jobs.js.map +1 -0
- package/dist/engine/ci-generator/yaml-builder.d.ts +10 -1
- package/dist/engine/ci-generator/yaml-builder.d.ts.map +1 -1
- package/dist/engine/ci-generator/yaml-builder.js +46 -1
- package/dist/engine/ci-generator/yaml-builder.js.map +1 -1
- package/dist/engine/coverage-gap-analyzer.d.ts +6 -0
- package/dist/engine/coverage-gap-analyzer.d.ts.map +1 -0
- package/dist/engine/coverage-gap-analyzer.js +177 -0
- package/dist/engine/coverage-gap-analyzer.js.map +1 -0
- package/dist/engine/dashboard/templates-kanban.d.ts.map +1 -1
- package/dist/engine/dashboard/templates-kanban.js +22 -0
- package/dist/engine/dashboard/templates-kanban.js.map +1 -1
- package/dist/engine/dashboard/templates-layout.d.ts.map +1 -1
- package/dist/engine/dashboard/templates-layout.js +59 -7
- package/dist/engine/dashboard/templates-layout.js.map +1 -1
- package/dist/engine/mutation-config-generator.d.ts +6 -0
- package/dist/engine/mutation-config-generator.d.ts.map +1 -0
- package/dist/engine/mutation-config-generator.js +111 -0
- package/dist/engine/mutation-config-generator.js.map +1 -0
- package/dist/engine/tdd-scaffold-generator.d.ts +7 -0
- package/dist/engine/tdd-scaffold-generator.d.ts.map +1 -0
- package/dist/engine/tdd-scaffold-generator.js +252 -0
- package/dist/engine/tdd-scaffold-generator.js.map +1 -0
- package/dist/engine/version-resolver.d.ts +10 -0
- package/dist/engine/version-resolver.d.ts.map +1 -0
- package/dist/engine/version-resolver.js +144 -0
- package/dist/engine/version-resolver.js.map +1 -0
- package/dist/engine/web-fetcher/stack-advisor.d.ts.map +1 -1
- package/dist/engine/web-fetcher/stack-advisor.js +32 -4
- package/dist/engine/web-fetcher/stack-advisor.js.map +1 -1
- package/dist/index.js +7 -11
- package/dist/index.js.map +1 -1
- package/dist/tools/checkpoint-handler.d.ts.map +1 -1
- package/dist/tools/checkpoint-handler.js +24 -1
- package/dist/tools/checkpoint-handler.js.map +1 -1
- package/dist/tools/dashboard.d.ts.map +1 -1
- package/dist/tools/dashboard.js +2 -0
- package/dist/tools/dashboard.js.map +1 -1
- package/dist/tools/register-spec-322-tools.d.ts +3 -0
- package/dist/tools/register-spec-322-tools.d.ts.map +1 -0
- package/dist/tools/register-spec-322-tools.js +41 -0
- package/dist/tools/register-spec-322-tools.js.map +1 -0
- package/dist/tools/register-spec-323-tools.d.ts +3 -0
- package/dist/tools/register-spec-323-tools.d.ts.map +1 -0
- package/dist/tools/register-spec-323-tools.js +57 -0
- package/dist/tools/register-spec-323-tools.js.map +1 -0
- package/dist/tools/tdd-scaffold-handler.d.ts +5 -0
- package/dist/tools/tdd-scaffold-handler.d.ts.map +1 -0
- package/dist/tools/tdd-scaffold-handler.js +92 -0
- package/dist/tools/tdd-scaffold-handler.js.map +1 -0
- package/dist/tools/validate-api-contract-handler.d.ts +3 -0
- package/dist/tools/validate-api-contract-handler.d.ts.map +1 -0
- package/dist/tools/validate-api-contract-handler.js +74 -0
- package/dist/tools/validate-api-contract-handler.js.map +1 -0
- package/dist/tools/validate.d.ts.map +1 -1
- package/dist/tools/validate.js +22 -2
- package/dist/tools/validate.js.map +1 -1
- package/dist/types/api-contract.d.ts +58 -0
- package/dist/types/api-contract.d.ts.map +1 -1
- package/dist/types/ci.d.ts +8 -0
- package/dist/types/ci.d.ts.map +1 -1
- package/dist/types/index.d.ts +1 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js +1 -0
- package/dist/types/index.js.map +1 -1
- package/dist/types/testing.d.ts +60 -0
- package/dist/types/testing.d.ts.map +1 -1
- package/dist/types/version-resolution.d.ts +23 -0
- package/dist/types/version-resolution.d.ts.map +1 -0
- package/dist/types/version-resolution.js +3 -0
- package/dist/types/version-resolution.js.map +1 -0
- package/package.json +1 -1
- package/src/config/license-plans.json +6 -2
- package/src/config/mobile-ci-templates/android-github-actions.yml +149 -0
- package/src/config/mobile-ci-templates/ios-github-actions.yml +120 -0
|
@@ -0,0 +1,252 @@
|
|
|
1
|
+
// engine/tdd-scaffold-generator.ts — SPEC-323
|
|
2
|
+
// Generates TDD scaffold (failing test stubs + impl skeleton) from spec ACs.
|
|
3
|
+
import { readFile } from 'node:fs/promises';
|
|
4
|
+
import { join } from 'node:path';
|
|
5
|
+
// ---------------------------------------------------------------------------
|
|
6
|
+
// Internal helpers
|
|
7
|
+
// ---------------------------------------------------------------------------
|
|
8
|
+
/** Extract checkbox ACs from spec.md content: lines starting with "- [ ]". */
|
|
9
|
+
function extractAcceptanceCriteria(specContent) {
|
|
10
|
+
const lines = specContent.split('\n');
|
|
11
|
+
const criteria = [];
|
|
12
|
+
for (const line of lines) {
|
|
13
|
+
const match = /^\s*-\s*\[\s*\]\s+(.+)$/.exec(line);
|
|
14
|
+
if (match?.[1]) {
|
|
15
|
+
criteria.push(match[1].trim());
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
return criteria;
|
|
19
|
+
}
|
|
20
|
+
/** Convert a criterion string to a camelCase test name. */
|
|
21
|
+
function criterionToTestName(criterion) {
|
|
22
|
+
const cleaned = criterion
|
|
23
|
+
.replace(/[^\w\s]/g, ' ')
|
|
24
|
+
.replace(/\s+/g, ' ')
|
|
25
|
+
.trim()
|
|
26
|
+
.toLowerCase();
|
|
27
|
+
const words = cleaned.split(' ').filter(Boolean);
|
|
28
|
+
if (words.length === 0) {
|
|
29
|
+
return 'criterion';
|
|
30
|
+
}
|
|
31
|
+
const [first, ...rest] = words;
|
|
32
|
+
return ((first ?? 'criterion') + rest.map((w) => (w[0]?.toUpperCase() ?? '') + w.slice(1)).join(''));
|
|
33
|
+
}
|
|
34
|
+
/** Detect test framework from package.json devDependencies / dependencies. */
|
|
35
|
+
async function detectFramework(projectPath) {
|
|
36
|
+
const pkgPath = join(projectPath, 'package.json');
|
|
37
|
+
try {
|
|
38
|
+
const raw = await readFile(pkgPath, 'utf8');
|
|
39
|
+
const pkg = JSON.parse(raw);
|
|
40
|
+
const deps = {
|
|
41
|
+
...(pkg.dependencies ?? {}),
|
|
42
|
+
...(pkg.devDependencies ?? {}),
|
|
43
|
+
};
|
|
44
|
+
if ('vitest' in deps) {
|
|
45
|
+
return 'vitest';
|
|
46
|
+
}
|
|
47
|
+
if ('jest' in deps) {
|
|
48
|
+
return 'jest';
|
|
49
|
+
}
|
|
50
|
+
if ('mocha' in deps) {
|
|
51
|
+
return 'mocha';
|
|
52
|
+
}
|
|
53
|
+
return 'unknown';
|
|
54
|
+
}
|
|
55
|
+
catch {
|
|
56
|
+
// Check for Python or Java markers
|
|
57
|
+
const setup = await readFile(join(projectPath, 'setup.py'), 'utf8').catch(() => null);
|
|
58
|
+
if (setup !== null) {
|
|
59
|
+
return 'pytest';
|
|
60
|
+
}
|
|
61
|
+
const pom = await readFile(join(projectPath, 'pom.xml'), 'utf8').catch(() => null);
|
|
62
|
+
if (pom !== null) {
|
|
63
|
+
return 'junit';
|
|
64
|
+
}
|
|
65
|
+
return 'unknown';
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
/** Extract spec slug from path for naming generated files. */
|
|
69
|
+
function specSlugFromPath(specPath) {
|
|
70
|
+
const parts = specPath.replace(/\\/g, '/').split('/');
|
|
71
|
+
// Try to find SPEC-XXX pattern in path
|
|
72
|
+
for (const part of [...parts].reverse()) {
|
|
73
|
+
if (/SPEC-\d+/.test(part)) {
|
|
74
|
+
return part.toLowerCase().replace(/[^a-z0-9-]/g, '-');
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
return 'spec-unknown';
|
|
78
|
+
}
|
|
79
|
+
// ---------------------------------------------------------------------------
|
|
80
|
+
// Test content builders
|
|
81
|
+
// ---------------------------------------------------------------------------
|
|
82
|
+
function buildVitestContent(stubs) {
|
|
83
|
+
const lines = [
|
|
84
|
+
"import { describe, it, expect } from 'vitest';",
|
|
85
|
+
'',
|
|
86
|
+
'// TDD scaffold — generated by Planu (SPEC-323)',
|
|
87
|
+
'// Each test is a FAILING STUB. Implement the production code to make them pass.',
|
|
88
|
+
'',
|
|
89
|
+
'describe("Acceptance Criteria", () => {',
|
|
90
|
+
];
|
|
91
|
+
for (const stub of stubs) {
|
|
92
|
+
lines.push(` it("should ${stub.testName}", () => {`);
|
|
93
|
+
lines.push(` // AC: ${stub.criterion}`);
|
|
94
|
+
lines.push(' expect.fail("Not implemented — write the implementation first");');
|
|
95
|
+
lines.push(' });');
|
|
96
|
+
lines.push('');
|
|
97
|
+
}
|
|
98
|
+
lines.push('});');
|
|
99
|
+
return lines.join('\n');
|
|
100
|
+
}
|
|
101
|
+
function buildJestContent(stubs) {
|
|
102
|
+
const lines = [
|
|
103
|
+
'// TDD scaffold — generated by Planu (SPEC-323)',
|
|
104
|
+
'// Each test is a FAILING STUB. Implement the production code to make them pass.',
|
|
105
|
+
'',
|
|
106
|
+
'describe("Acceptance Criteria", () => {',
|
|
107
|
+
];
|
|
108
|
+
for (const stub of stubs) {
|
|
109
|
+
lines.push(` it("should ${stub.testName}", () => {`);
|
|
110
|
+
lines.push(` // AC: ${stub.criterion}`);
|
|
111
|
+
lines.push(' throw new Error("Not implemented — write the implementation first");');
|
|
112
|
+
lines.push(' });');
|
|
113
|
+
lines.push('');
|
|
114
|
+
}
|
|
115
|
+
lines.push('});');
|
|
116
|
+
return lines.join('\n');
|
|
117
|
+
}
|
|
118
|
+
function buildMochaContent(stubs) {
|
|
119
|
+
const lines = [
|
|
120
|
+
"import assert from 'node:assert';",
|
|
121
|
+
'',
|
|
122
|
+
'// TDD scaffold — generated by Planu (SPEC-323)',
|
|
123
|
+
'',
|
|
124
|
+
'describe("Acceptance Criteria", function () {',
|
|
125
|
+
];
|
|
126
|
+
for (const stub of stubs) {
|
|
127
|
+
lines.push(` it("should ${stub.testName}", function () {`);
|
|
128
|
+
lines.push(` // AC: ${stub.criterion}`);
|
|
129
|
+
lines.push(' assert.fail("Not implemented — write the implementation first");');
|
|
130
|
+
lines.push(' });');
|
|
131
|
+
lines.push('');
|
|
132
|
+
}
|
|
133
|
+
lines.push('});');
|
|
134
|
+
return lines.join('\n');
|
|
135
|
+
}
|
|
136
|
+
function buildPytestContent(stubs) {
|
|
137
|
+
const lines = [
|
|
138
|
+
'# TDD scaffold — generated by Planu (SPEC-323)',
|
|
139
|
+
'# Each test is a FAILING STUB. Implement the production code to make them pass.',
|
|
140
|
+
'',
|
|
141
|
+
'import pytest',
|
|
142
|
+
'',
|
|
143
|
+
];
|
|
144
|
+
for (const stub of stubs) {
|
|
145
|
+
const fnName = stub.testName.replace(/([A-Z])/g, '_$1').toLowerCase();
|
|
146
|
+
lines.push(`def test_${fnName}():`);
|
|
147
|
+
lines.push(` # AC: ${stub.criterion}`);
|
|
148
|
+
lines.push(' raise NotImplementedError("Not implemented — write the implementation first")');
|
|
149
|
+
lines.push('');
|
|
150
|
+
}
|
|
151
|
+
return lines.join('\n');
|
|
152
|
+
}
|
|
153
|
+
function buildJunitContent(stubs) {
|
|
154
|
+
const lines = [
|
|
155
|
+
'// TDD scaffold — generated by Planu (SPEC-323)',
|
|
156
|
+
'import org.junit.jupiter.api.Test;',
|
|
157
|
+
'import static org.junit.jupiter.api.Assertions.*;',
|
|
158
|
+
'',
|
|
159
|
+
'class AcceptanceCriteriaTest {',
|
|
160
|
+
];
|
|
161
|
+
for (const stub of stubs) {
|
|
162
|
+
const method = stub.testName.replace(/[^a-zA-Z0-9]/g, '');
|
|
163
|
+
const first = method[0]?.toUpperCase() ?? '';
|
|
164
|
+
const rest = method.slice(1);
|
|
165
|
+
lines.push(' @Test');
|
|
166
|
+
lines.push(` void should${first}${rest}() {`);
|
|
167
|
+
lines.push(` // AC: ${stub.criterion}`);
|
|
168
|
+
lines.push(' fail("Not implemented — write the implementation first");');
|
|
169
|
+
lines.push(' }');
|
|
170
|
+
lines.push('');
|
|
171
|
+
}
|
|
172
|
+
lines.push('}');
|
|
173
|
+
return lines.join('\n');
|
|
174
|
+
}
|
|
175
|
+
function buildTestContent(stubs, framework) {
|
|
176
|
+
switch (framework) {
|
|
177
|
+
case 'vitest':
|
|
178
|
+
return buildVitestContent(stubs);
|
|
179
|
+
case 'jest':
|
|
180
|
+
return buildJestContent(stubs);
|
|
181
|
+
case 'mocha':
|
|
182
|
+
return buildMochaContent(stubs);
|
|
183
|
+
case 'pytest':
|
|
184
|
+
return buildPytestContent(stubs);
|
|
185
|
+
case 'junit':
|
|
186
|
+
return buildJunitContent(stubs);
|
|
187
|
+
case 'unknown':
|
|
188
|
+
return buildVitestContent(stubs);
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
// ---------------------------------------------------------------------------
|
|
192
|
+
// Implementation skeleton builder
|
|
193
|
+
// ---------------------------------------------------------------------------
|
|
194
|
+
function buildImplSkeleton(stubs, slug) {
|
|
195
|
+
const lines = [
|
|
196
|
+
`// ${slug}.ts — implementation skeleton generated by Planu (SPEC-323)`,
|
|
197
|
+
'// TODO: implement each function to make the TDD stubs pass.',
|
|
198
|
+
'',
|
|
199
|
+
];
|
|
200
|
+
for (const stub of stubs) {
|
|
201
|
+
lines.push(`// AC: ${stub.criterion}`);
|
|
202
|
+
lines.push(`export function ${stub.testName}(): void {`);
|
|
203
|
+
lines.push(' throw new Error("Not implemented");');
|
|
204
|
+
lines.push('}');
|
|
205
|
+
lines.push('');
|
|
206
|
+
}
|
|
207
|
+
return lines.join('\n');
|
|
208
|
+
}
|
|
209
|
+
// ---------------------------------------------------------------------------
|
|
210
|
+
// Public API
|
|
211
|
+
// ---------------------------------------------------------------------------
|
|
212
|
+
/**
|
|
213
|
+
* Generate a TDD scaffold from a spec's acceptance criteria.
|
|
214
|
+
* Returns paths and content for a failing test file and an impl skeleton.
|
|
215
|
+
*/
|
|
216
|
+
export async function generateTddScaffold(specPath, projectPath) {
|
|
217
|
+
const specContent = await readFile(join(specPath, 'spec.md'), 'utf8').catch(() => readFile(specPath, 'utf8'));
|
|
218
|
+
const criteria = extractAcceptanceCriteria(specContent);
|
|
219
|
+
const framework = await detectFramework(projectPath);
|
|
220
|
+
const slug = specSlugFromPath(specPath);
|
|
221
|
+
const stubs = criteria.map((criterion) => ({
|
|
222
|
+
criterion,
|
|
223
|
+
testName: criterionToTestName(criterion),
|
|
224
|
+
framework,
|
|
225
|
+
}));
|
|
226
|
+
const ext = framework === 'pytest' ? 'py' : framework === 'junit' ? 'java' : 'ts';
|
|
227
|
+
const testExt = framework === 'pytest' ? '_test.py' : framework === 'junit' ? 'Test.java' : '.test.ts';
|
|
228
|
+
const testDir = framework === 'pytest' ? 'tests' : framework === 'junit' ? 'src/test' : 'tests';
|
|
229
|
+
const testFilePath = join(projectPath, testDir, `${slug}${testExt}`);
|
|
230
|
+
const implFilePath = join(projectPath, 'src', `${slug}.${ext}`);
|
|
231
|
+
const testContent = buildTestContent(stubs, framework);
|
|
232
|
+
const implContent = buildImplSkeleton(stubs, slug);
|
|
233
|
+
const instructions = [
|
|
234
|
+
`Test file: ${testFilePath}`,
|
|
235
|
+
`Implementation skeleton: ${implFilePath}`,
|
|
236
|
+
`Framework detected: ${framework}`,
|
|
237
|
+
`Generated ${stubs.length} failing stub(s) from acceptance criteria.`,
|
|
238
|
+
'Run the tests — they should ALL fail (red phase).',
|
|
239
|
+
'Implement each function in the skeleton until all tests pass (green phase).',
|
|
240
|
+
'Refactor for clarity while keeping all tests green.',
|
|
241
|
+
];
|
|
242
|
+
return {
|
|
243
|
+
testFilePath,
|
|
244
|
+
implFilePath,
|
|
245
|
+
testContent,
|
|
246
|
+
implContent,
|
|
247
|
+
stubs,
|
|
248
|
+
instructions,
|
|
249
|
+
framework,
|
|
250
|
+
};
|
|
251
|
+
}
|
|
252
|
+
//# sourceMappingURL=tdd-scaffold-generator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tdd-scaffold-generator.js","sourceRoot":"","sources":["../../src/engine/tdd-scaffold-generator.ts"],"names":[],"mappings":"AAAA,8CAA8C;AAC9C,6EAA6E;AAE7E,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAGjC,8EAA8E;AAC9E,mBAAmB;AACnB,8EAA8E;AAE9E,8EAA8E;AAC9E,SAAS,yBAAyB,CAAC,WAAmB;IACpD,MAAM,KAAK,GAAG,WAAW,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IACtC,MAAM,QAAQ,GAAa,EAAE,CAAC;IAC9B,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,KAAK,GAAG,yBAAyB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACnD,IAAI,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACf,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;QACjC,CAAC;IACH,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,2DAA2D;AAC3D,SAAS,mBAAmB,CAAC,SAAiB;IAC5C,MAAM,OAAO,GAAG,SAAS;SACtB,OAAO,CAAC,UAAU,EAAE,GAAG,CAAC;SACxB,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC;SACpB,IAAI,EAAE;SACN,WAAW,EAAE,CAAC;IACjB,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IACjD,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACvB,OAAO,WAAW,CAAC;IACrB,CAAC;IACD,MAAM,CAAC,KAAK,EAAE,GAAG,IAAI,CAAC,GAAG,KAAK,CAAC;IAC/B,OAAO,CACL,CAAC,KAAK,IAAI,WAAW,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAC5F,CAAC;AACJ,CAAC;AAED,8EAA8E;AAC9E,KAAK,UAAU,eAAe,CAAC,WAAmB;IAChD,MAAM,OAAO,GAAG,IAAI,CAAC,WAAW,EAAE,cAAc,CAAC,CAAC;IAClD,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QAC5C,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAA4B,CAAC;QACvD,MAAM,IAAI,GAA4B;YACpC,GAAG,CAAE,GAAG,CAAC,YAAoD,IAAI,EAAE,CAAC;YACpE,GAAG,CAAE,GAAG,CAAC,eAAuD,IAAI,EAAE,CAAC;SACxE,CAAC;QACF,IAAI,QAAQ,IAAI,IAAI,EAAE,CAAC;YACrB,OAAO,QAAQ,CAAC;QAClB,CAAC;QACD,IAAI,MAAM,IAAI,IAAI,EAAE,CAAC;YACnB,OAAO,MAAM,CAAC;QAChB,CAAC;QACD,IAAI,OAAO,IAAI,IAAI,EAAE,CAAC;YACpB,OAAO,OAAO,CAAC;QACjB,CAAC;QACD,OAAO,SAAS,CAAC;IACnB,CAAC;IAAC,MAAM,CAAC;QACP,mCAAmC;QACnC,MAAM,KAAK,GAAG,MAAM,QAAQ,CAAC,IAAI,CAAC,WAAW,EAAE,UAAU,CAAC,EAAE,MAAM,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC;QACtF,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;YACnB,OAAO,QAAQ,CAAC;QAClB,CAAC;QACD,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,IAAI,CAAC,WAAW,EAAE,SAAS,CAAC,EAAE,MAAM,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC;QACnF,IAAI,GAAG,KAAK,IAAI,EAAE,CAAC;YACjB,OAAO,OAAO,CAAC;QACjB,CAAC;QACD,OAAO,SAAS,CAAC;IACnB,CAAC;AACH,CAAC;AAED,8DAA8D;AAC9D,SAAS,gBAAgB,CAAC,QAAgB;IACxC,MAAM,KAAK,GAAG,QAAQ,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACtD,uCAAuC;IACvC,KAAK,MAAM,IAAI,IAAI,CAAC,GAAG,KAAK,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC;QACxC,IAAI,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;YAC1B,OAAO,IAAI,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,aAAa,EAAE,GAAG,CAAC,CAAC;QACxD,CAAC;IACH,CAAC;IACD,OAAO,cAAc,CAAC;AACxB,CAAC;AAED,8EAA8E;AAC9E,wBAAwB;AACxB,8EAA8E;AAE9E,SAAS,kBAAkB,CAAC,KAAgB;IAC1C,MAAM,KAAK,GAAa;QACtB,gDAAgD;QAChD,EAAE;QACF,iDAAiD;QACjD,kFAAkF;QAClF,EAAE;QACF,yCAAyC;KAC1C,CAAC;IACF,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,KAAK,CAAC,IAAI,CAAC,gBAAgB,IAAI,CAAC,QAAQ,YAAY,CAAC,CAAC;QACtD,KAAK,CAAC,IAAI,CAAC,cAAc,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC;QAC3C,KAAK,CAAC,IAAI,CAAC,sEAAsE,CAAC,CAAC;QACnF,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACpB,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACjB,CAAC;IACD,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAClB,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC;AAED,SAAS,gBAAgB,CAAC,KAAgB;IACxC,MAAM,KAAK,GAAa;QACtB,iDAAiD;QACjD,kFAAkF;QAClF,EAAE;QACF,yCAAyC;KAC1C,CAAC;IACF,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,KAAK,CAAC,IAAI,CAAC,gBAAgB,IAAI,CAAC,QAAQ,YAAY,CAAC,CAAC;QACtD,KAAK,CAAC,IAAI,CAAC,cAAc,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC;QAC3C,KAAK,CAAC,IAAI,CAAC,0EAA0E,CAAC,CAAC;QACvF,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACpB,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACjB,CAAC;IACD,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAClB,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC;AAED,SAAS,iBAAiB,CAAC,KAAgB;IACzC,MAAM,KAAK,GAAa;QACtB,mCAAmC;QACnC,EAAE;QACF,iDAAiD;QACjD,EAAE;QACF,+CAA+C;KAChD,CAAC;IACF,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,KAAK,CAAC,IAAI,CAAC,gBAAgB,IAAI,CAAC,QAAQ,kBAAkB,CAAC,CAAC;QAC5D,KAAK,CAAC,IAAI,CAAC,cAAc,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC;QAC3C,KAAK,CAAC,IAAI,CAAC,sEAAsE,CAAC,CAAC;QACnF,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACpB,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACjB,CAAC;IACD,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAClB,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC;AAED,SAAS,kBAAkB,CAAC,KAAgB;IAC1C,MAAM,KAAK,GAAa;QACtB,gDAAgD;QAChD,iFAAiF;QACjF,EAAE;QACF,eAAe;QACf,EAAE;KACH,CAAC;IACF,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,MAAM,GAAG,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC,WAAW,EAAE,CAAC;QACtE,KAAK,CAAC,IAAI,CAAC,YAAY,MAAM,KAAK,CAAC,CAAC;QACpC,KAAK,CAAC,IAAI,CAAC,aAAa,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC;QAC1C,KAAK,CAAC,IAAI,CAAC,mFAAmF,CAAC,CAAC;QAChG,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACjB,CAAC;IACD,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC;AAED,SAAS,iBAAiB,CAAC,KAAgB;IACzC,MAAM,KAAK,GAAa;QACtB,iDAAiD;QACjD,oCAAoC;QACpC,mDAAmD;QACnD,EAAE;QACF,gCAAgC;KACjC,CAAC;IACF,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,MAAM,GAAG,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,eAAe,EAAE,EAAE,CAAC,CAAC;QAC1D,MAAM,KAAK,GAAG,MAAM,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC;QAC7C,MAAM,IAAI,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QAC7B,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QACxB,KAAK,CAAC,IAAI,CAAC,kBAAkB,KAAK,GAAG,IAAI,MAAM,CAAC,CAAC;QACjD,KAAK,CAAC,IAAI,CAAC,kBAAkB,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC;QAC/C,KAAK,CAAC,IAAI,CAAC,mEAAmE,CAAC,CAAC;QAChF,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACpB,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACjB,CAAC;IACD,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAChB,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC;AAED,SAAS,gBAAgB,CAAC,KAAgB,EAAE,SAA+B;IACzE,QAAQ,SAAS,EAAE,CAAC;QAClB,KAAK,QAAQ;YACX,OAAO,kBAAkB,CAAC,KAAK,CAAC,CAAC;QACnC,KAAK,MAAM;YACT,OAAO,gBAAgB,CAAC,KAAK,CAAC,CAAC;QACjC,KAAK,OAAO;YACV,OAAO,iBAAiB,CAAC,KAAK,CAAC,CAAC;QAClC,KAAK,QAAQ;YACX,OAAO,kBAAkB,CAAC,KAAK,CAAC,CAAC;QACnC,KAAK,OAAO;YACV,OAAO,iBAAiB,CAAC,KAAK,CAAC,CAAC;QAClC,KAAK,SAAS;YACZ,OAAO,kBAAkB,CAAC,KAAK,CAAC,CAAC;IACrC,CAAC;AACH,CAAC;AAED,8EAA8E;AAC9E,kCAAkC;AAClC,8EAA8E;AAE9E,SAAS,iBAAiB,CAAC,KAAgB,EAAE,IAAY;IACvD,MAAM,KAAK,GAAa;QACtB,MAAM,IAAI,6DAA6D;QACvE,8DAA8D;QAC9D,EAAE;KACH,CAAC;IACF,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,KAAK,CAAC,IAAI,CAAC,UAAU,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC;QACvC,KAAK,CAAC,IAAI,CAAC,mBAAmB,IAAI,CAAC,QAAQ,YAAY,CAAC,CAAC;QACzD,KAAK,CAAC,IAAI,CAAC,uCAAuC,CAAC,CAAC;QACpD,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAChB,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACjB,CAAC;IACD,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC;AAED,8EAA8E;AAC9E,aAAa;AACb,8EAA8E;AAE9E;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB,CACvC,QAAgB,EAChB,WAAmB;IAEnB,MAAM,WAAW,GAAG,MAAM,QAAQ,CAAC,IAAI,CAAC,QAAQ,EAAE,SAAS,CAAC,EAAE,MAAM,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAC/E,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC,CAC3B,CAAC;IAEF,MAAM,QAAQ,GAAG,yBAAyB,CAAC,WAAW,CAAC,CAAC;IACxD,MAAM,SAAS,GAAG,MAAM,eAAe,CAAC,WAAW,CAAC,CAAC;IACrD,MAAM,IAAI,GAAG,gBAAgB,CAAC,QAAQ,CAAC,CAAC;IAExC,MAAM,KAAK,GAAc,QAAQ,CAAC,GAAG,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC;QACpD,SAAS;QACT,QAAQ,EAAE,mBAAmB,CAAC,SAAS,CAAC;QACxC,SAAS;KACV,CAAC,CAAC,CAAC;IAEJ,MAAM,GAAG,GAAG,SAAS,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,KAAK,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC;IAClF,MAAM,OAAO,GACX,SAAS,KAAK,QAAQ,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,SAAS,KAAK,OAAO,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,UAAU,CAAC;IACzF,MAAM,OAAO,GAAG,SAAS,KAAK,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,KAAK,OAAO,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,OAAO,CAAC;IAChG,MAAM,YAAY,GAAG,IAAI,CAAC,WAAW,EAAE,OAAO,EAAE,GAAG,IAAI,GAAG,OAAO,EAAE,CAAC,CAAC;IACrE,MAAM,YAAY,GAAG,IAAI,CAAC,WAAW,EAAE,KAAK,EAAE,GAAG,IAAI,IAAI,GAAG,EAAE,CAAC,CAAC;IAEhE,MAAM,WAAW,GAAG,gBAAgB,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;IACvD,MAAM,WAAW,GAAG,iBAAiB,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;IAEnD,MAAM,YAAY,GAAG;QACnB,cAAc,YAAY,EAAE;QAC5B,4BAA4B,YAAY,EAAE;QAC1C,uBAAuB,SAAS,EAAE;QAClC,aAAa,KAAK,CAAC,MAAM,4CAA4C;QACrE,mDAAmD;QACnD,6EAA6E;QAC7E,qDAAqD;KACtD,CAAC;IAEF,OAAO;QACL,YAAY;QACZ,YAAY;QACZ,WAAW;QACX,WAAW;QACX,KAAK;QACL,YAAY;QACZ,SAAS;KACV,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { PackageRegistry, VersionCachePolicy, VersionResolutionResult } from '../types/index.js';
|
|
2
|
+
/**
|
|
3
|
+
* Resolve the latest version of a framework package.
|
|
4
|
+
* Order: memory cache → persistent cache → registry → fallback.
|
|
5
|
+
* Never throws — always returns a result.
|
|
6
|
+
*/
|
|
7
|
+
export declare function resolveFrameworkVersion(packageName: string, registry: PackageRegistry, cachePolicy?: VersionCachePolicy): Promise<VersionResolutionResult>;
|
|
8
|
+
/** Clear the in-memory cache (useful for testing). */
|
|
9
|
+
export declare function clearVersionCache(): void;
|
|
10
|
+
//# sourceMappingURL=version-resolver.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"version-resolver.d.ts","sourceRoot":"","sources":["../../src/engine/version-resolver.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EACV,eAAe,EAGf,kBAAkB,EAClB,uBAAuB,EACxB,MAAM,mBAAmB,CAAC;AA6F3B;;;;GAIG;AACH,wBAAsB,uBAAuB,CAC3C,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,eAAe,EACzB,WAAW,GAAE,kBAA+B,GAC3C,OAAO,CAAC,uBAAuB,CAAC,CA0DlC;AAED,sDAAsD;AACtD,wBAAgB,iBAAiB,IAAI,IAAI,CAExC"}
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
// Planu — Version Resolver (SPEC-321)
|
|
2
|
+
// Resolves framework versions: in-memory cache → persistent cache → registry → fallback.
|
|
3
|
+
// Never throws — always returns a VersionResolutionResult.
|
|
4
|
+
import { readFile, writeFile } from 'node:fs/promises';
|
|
5
|
+
import { tmpdir } from 'node:os';
|
|
6
|
+
import { join } from 'node:path';
|
|
7
|
+
// -- Constants ---------------------------------------------------------------
|
|
8
|
+
const CACHE_TTL_MS = 24 * 60 * 60 * 1000; // 24 hours
|
|
9
|
+
const CACHE_FILE = join(tmpdir(), 'planu-version-cache.json');
|
|
10
|
+
// -- In-memory cache ---------------------------------------------------------
|
|
11
|
+
const memoryCache = new Map();
|
|
12
|
+
function cacheKey(packageName, registry) {
|
|
13
|
+
return `${registry}:${packageName}`;
|
|
14
|
+
}
|
|
15
|
+
function isExpired(entry) {
|
|
16
|
+
const age = Date.now() - new Date(entry.fetchedAt).getTime();
|
|
17
|
+
return age > CACHE_TTL_MS;
|
|
18
|
+
}
|
|
19
|
+
// -- Persistent cache --------------------------------------------------------
|
|
20
|
+
async function loadPersistentCache() {
|
|
21
|
+
try {
|
|
22
|
+
const raw = await readFile(CACHE_FILE, 'utf-8');
|
|
23
|
+
return JSON.parse(raw);
|
|
24
|
+
}
|
|
25
|
+
catch {
|
|
26
|
+
return { entries: {} };
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
async function savePersistentCache(store) {
|
|
30
|
+
try {
|
|
31
|
+
await writeFile(CACHE_FILE, JSON.stringify(store, null, 2), 'utf-8');
|
|
32
|
+
}
|
|
33
|
+
catch {
|
|
34
|
+
// Ignore write errors — cache is best-effort
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
async function getFromPersistentCache(key) {
|
|
38
|
+
const store = await loadPersistentCache();
|
|
39
|
+
return store.entries[key] ?? null;
|
|
40
|
+
}
|
|
41
|
+
async function setInPersistentCache(key, entry) {
|
|
42
|
+
const store = await loadPersistentCache();
|
|
43
|
+
store.entries[key] = entry;
|
|
44
|
+
await savePersistentCache(store);
|
|
45
|
+
}
|
|
46
|
+
// -- Registry fetch ----------------------------------------------------------
|
|
47
|
+
async function fetchFromRegistry(packageName, registry) {
|
|
48
|
+
try {
|
|
49
|
+
const { fetchLatestVersion } = await import('./package-registry.js');
|
|
50
|
+
const result = await fetchLatestVersion(packageName, registry);
|
|
51
|
+
if (!result) {
|
|
52
|
+
return null;
|
|
53
|
+
}
|
|
54
|
+
return { version: result.version, isDeprecated: result.deprecated };
|
|
55
|
+
}
|
|
56
|
+
catch {
|
|
57
|
+
return null;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
// -- Fallback versions -------------------------------------------------------
|
|
61
|
+
const FALLBACK_VERSIONS = {
|
|
62
|
+
'npm:next': '14.0.0',
|
|
63
|
+
'npm:react': '18.0.0',
|
|
64
|
+
'npm:hono': '4.0.0',
|
|
65
|
+
'npm:expo': '50.0.0',
|
|
66
|
+
'npm:commander': '12.0.0',
|
|
67
|
+
'npm:tsup': '8.0.0',
|
|
68
|
+
'npm:astro': '4.0.0',
|
|
69
|
+
'npm:remix': '2.0.0',
|
|
70
|
+
'npm:@remix-run/node': '2.0.0',
|
|
71
|
+
'pypi:fastapi': '0.100.0',
|
|
72
|
+
'pypi:django': '5.0.0',
|
|
73
|
+
'go:gin': '1.9.0',
|
|
74
|
+
'pub:flutter': '3.0.0',
|
|
75
|
+
};
|
|
76
|
+
function getFallbackVersion(packageName, registry) {
|
|
77
|
+
const key = `${registry}:${packageName}`;
|
|
78
|
+
return FALLBACK_VERSIONS[key] ?? '1.0.0';
|
|
79
|
+
}
|
|
80
|
+
// -- Public API --------------------------------------------------------------
|
|
81
|
+
/**
|
|
82
|
+
* Resolve the latest version of a framework package.
|
|
83
|
+
* Order: memory cache → persistent cache → registry → fallback.
|
|
84
|
+
* Never throws — always returns a result.
|
|
85
|
+
*/
|
|
86
|
+
export async function resolveFrameworkVersion(packageName, registry, cachePolicy = 'flexible') {
|
|
87
|
+
const key = cacheKey(packageName, registry);
|
|
88
|
+
// Offline mode: use cache only, fall back if not found
|
|
89
|
+
if (cachePolicy === 'offline') {
|
|
90
|
+
const memEntry = memoryCache.get(key);
|
|
91
|
+
if (memEntry) {
|
|
92
|
+
return { ...memEntry, source: 'cache' };
|
|
93
|
+
}
|
|
94
|
+
const persEntry = await getFromPersistentCache(key);
|
|
95
|
+
if (persEntry) {
|
|
96
|
+
memoryCache.set(key, persEntry);
|
|
97
|
+
return { ...persEntry, source: 'cache' };
|
|
98
|
+
}
|
|
99
|
+
return {
|
|
100
|
+
version: getFallbackVersion(packageName, registry),
|
|
101
|
+
source: 'fallback',
|
|
102
|
+
fetchedAt: new Date().toISOString(),
|
|
103
|
+
isDeprecated: false,
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
// Check memory cache
|
|
107
|
+
const memEntry = memoryCache.get(key);
|
|
108
|
+
if (memEntry && !isExpired(memEntry)) {
|
|
109
|
+
return { ...memEntry, source: 'cache' };
|
|
110
|
+
}
|
|
111
|
+
// Check persistent cache (flexible mode accepts non-expired entries)
|
|
112
|
+
if (cachePolicy === 'flexible') {
|
|
113
|
+
const persEntry = await getFromPersistentCache(key);
|
|
114
|
+
if (persEntry && !isExpired(persEntry)) {
|
|
115
|
+
memoryCache.set(key, persEntry);
|
|
116
|
+
return { ...persEntry, source: 'cache' };
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
// Fetch from registry
|
|
120
|
+
const fetched = await fetchFromRegistry(packageName, registry);
|
|
121
|
+
if (fetched) {
|
|
122
|
+
const entry = {
|
|
123
|
+
version: fetched.version,
|
|
124
|
+
isDeprecated: fetched.isDeprecated,
|
|
125
|
+
fetchedAt: new Date().toISOString(),
|
|
126
|
+
};
|
|
127
|
+
memoryCache.set(key, entry);
|
|
128
|
+
await setInPersistentCache(key, entry);
|
|
129
|
+
return { ...entry, source: 'registry' };
|
|
130
|
+
}
|
|
131
|
+
// Fallback: registry unreachable
|
|
132
|
+
const fallbackVersion = getFallbackVersion(packageName, registry);
|
|
133
|
+
return {
|
|
134
|
+
version: fallbackVersion,
|
|
135
|
+
source: 'fallback',
|
|
136
|
+
fetchedAt: new Date().toISOString(),
|
|
137
|
+
isDeprecated: false,
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
/** Clear the in-memory cache (useful for testing). */
|
|
141
|
+
export function clearVersionCache() {
|
|
142
|
+
memoryCache.clear();
|
|
143
|
+
}
|
|
144
|
+
//# sourceMappingURL=version-resolver.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"version-resolver.js","sourceRoot":"","sources":["../../src/engine/version-resolver.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stack-advisor.d.ts","sourceRoot":"","sources":["../../../src/engine/web-fetcher/stack-advisor.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"stack-advisor.d.ts","sourceRoot":"","sources":["../../../src/engine/web-fetcher/stack-advisor.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAyBpF,wBAAsB,sBAAsB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAStF;AAwHD,wBAAgB,cAAc,CAC5B,WAAW,EAAE,MAAM,EACnB,YAAY,EAAE,MAAM,EAAE,EACtB,WAAW,EAAE,MAAM,EAAE,GACpB,mBAAmB,CAUrB;AAED,wBAAgB,yBAAyB,CACvC,WAAW,EAAE,MAAM,EACnB,aAAa,EAAE,MAAM,EAAE,GACtB,mBAAmB,CAiErB;AAED,wBAAgB,iBAAiB,CAC/B,YAAY,EAAE,MAAM,EACpB,eAAe,EAAE,MAAM,GACtB;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,EAAE,CA4BpC;AAED,wBAAgB,qBAAqB,CACnC,KAAK,EAAE,mBAAmB,GACzB;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,EAAE,CAgCvD;AAmCD,wBAAsB,uBAAuB,CAC3C,WAAW,EAAE,MAAM,EACnB,YAAY,EAAE,MAAM,EAAE,EACtB,WAAW,EAAE,MAAM,EAAE,GACpB,OAAO,CAAC,kBAAkB,CAAC,CA+B7B"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
// Planu — Web Fetcher: Stack recommendation logic
|
|
2
|
+
import { resolveFrameworkVersion } from '../version-resolver.js';
|
|
2
3
|
const FRAMEWORK_PACKAGES = {
|
|
3
4
|
'next.js': 'next',
|
|
4
5
|
react: 'react',
|
|
@@ -258,17 +259,44 @@ export function buildMcpCompatibility(stack) {
|
|
|
258
259
|
results.push({ mcp: 'puppeteer', compatible: true, notes: 'Browser automation for testing.' });
|
|
259
260
|
return results;
|
|
260
261
|
}
|
|
262
|
+
async function resolveVersionForFramework(framework, language) {
|
|
263
|
+
const packageName = FRAMEWORK_PACKAGES[framework.toLowerCase()];
|
|
264
|
+
if (packageName) {
|
|
265
|
+
const result = await resolveFrameworkVersion(packageName, 'npm');
|
|
266
|
+
if (result.source !== 'fallback') {
|
|
267
|
+
return result.version;
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
// Try language-specific registries for non-npm frameworks
|
|
271
|
+
if (language === 'python' && framework === 'fastapi') {
|
|
272
|
+
const result = await resolveFrameworkVersion('fastapi', 'pypi');
|
|
273
|
+
return result.source !== 'fallback' ? result.version : null;
|
|
274
|
+
}
|
|
275
|
+
if (language === 'python' && framework === 'django') {
|
|
276
|
+
const result = await resolveFrameworkVersion('django', 'pypi');
|
|
277
|
+
return result.source !== 'fallback' ? result.version : null;
|
|
278
|
+
}
|
|
279
|
+
if (language === 'go' && framework === 'gin') {
|
|
280
|
+
const result = await resolveFrameworkVersion('gin-gonic/gin', 'go');
|
|
281
|
+
return result.source !== 'fallback' ? result.version : null;
|
|
282
|
+
}
|
|
283
|
+
if ((language === 'dart' || language === 'flutter') && framework === 'flutter') {
|
|
284
|
+
const result = await resolveFrameworkVersion('flutter', 'pub');
|
|
285
|
+
return result.source !== 'fallback' ? result.version : null;
|
|
286
|
+
}
|
|
287
|
+
return null;
|
|
288
|
+
}
|
|
261
289
|
export async function buildSuggestStackResult(projectType, requirements, constraints) {
|
|
262
290
|
const primary = recommendStack(projectType, requirements, constraints);
|
|
263
291
|
const alternative = recommendAlternativeStack(projectType, requirements);
|
|
264
292
|
let confidence = 'low';
|
|
265
293
|
try {
|
|
266
|
-
const
|
|
267
|
-
if (
|
|
268
|
-
primary.version =
|
|
294
|
+
const primaryVersion = await resolveVersionForFramework(primary.framework, primary.language);
|
|
295
|
+
if (primaryVersion) {
|
|
296
|
+
primary.version = primaryVersion;
|
|
269
297
|
confidence = 'high';
|
|
270
298
|
}
|
|
271
|
-
const altVersion = await
|
|
299
|
+
const altVersion = await resolveVersionForFramework(alternative.framework, alternative.language);
|
|
272
300
|
if (altVersion) {
|
|
273
301
|
alternative.version = altVersion;
|
|
274
302
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stack-advisor.js","sourceRoot":"","sources":["../../../src/engine/web-fetcher/stack-advisor.ts"],"names":[],"mappings":"AAAA,kDAAkD;
|
|
1
|
+
{"version":3,"file":"stack-advisor.js","sourceRoot":"","sources":["../../../src/engine/web-fetcher/stack-advisor.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -146,9 +146,9 @@ import { registerEvalSkillTools } from './tools/register-spec-316.js';
|
|
|
146
146
|
import { registerJiraLinearTools } from './tools/register-spec-317.js';
|
|
147
147
|
import { registerComplianceTools } from './tools/register-spec-319.js';
|
|
148
148
|
import { registerSpecMarketplaceTools } from './tools/register-spec-320.js';
|
|
149
|
-
|
|
149
|
+
import { registerApiContractValidationTools } from './tools/register-spec-322-tools.js';
|
|
150
|
+
import { registerSpec323Tools } from './tools/register-spec-323-tools.js';
|
|
150
151
|
// Server setup
|
|
151
|
-
// ---------------------------------------------------------------------------
|
|
152
152
|
const SERVER_INSTRUCTIONS = [
|
|
153
153
|
'CONTEXT — Why structured specs matter:',
|
|
154
154
|
'- Vibe Coding (describing features informally to AI) creates technical debt at scale',
|
|
@@ -363,22 +363,19 @@ function registerExtendedTools(s) {
|
|
|
363
363
|
registerJiraLinearTools(s);
|
|
364
364
|
registerComplianceTools(s);
|
|
365
365
|
registerSpecMarketplaceTools(s);
|
|
366
|
+
registerApiContractValidationTools(s);
|
|
367
|
+
registerSpec323Tools(s);
|
|
366
368
|
registerPrompts(s);
|
|
367
369
|
}
|
|
368
|
-
function registerAllTools(s) {
|
|
369
|
-
registerCoreTools(s);
|
|
370
|
-
registerExtendedTools(s);
|
|
371
|
-
}
|
|
372
370
|
function createMcpServer() {
|
|
373
371
|
const s = withToolTracking(new McpServer({ name: 'planu', version: PLANU_VERSION }, { instructions: SERVER_INSTRUCTIONS }));
|
|
374
|
-
|
|
372
|
+
registerCoreTools(s);
|
|
373
|
+
registerExtendedTools(s);
|
|
375
374
|
return s;
|
|
376
375
|
}
|
|
377
376
|
// Primary server instance (used for stdio and group manager init)
|
|
378
377
|
const server = createMcpServer();
|
|
379
|
-
// ---------------------------------------------------------------------------
|
|
380
378
|
// Start server
|
|
381
|
-
// ---------------------------------------------------------------------------
|
|
382
379
|
async function main() {
|
|
383
380
|
// SPEC-251: Check npm registry for newer version (fire-and-forget, 24h cache)
|
|
384
381
|
checkForUpdates().catch(() => {
|
|
@@ -392,8 +389,7 @@ async function main() {
|
|
|
392
389
|
console.error('[Planu] License activation from SDD_LICENSE_KEY failed:', err);
|
|
393
390
|
});
|
|
394
391
|
}
|
|
395
|
-
// SPEC-074: Initialize tool group manager
|
|
396
|
-
// Uses local tool registry instead of SDK-internal _registeredTools.
|
|
392
|
+
// SPEC-074: Initialize tool group manager using local registry instead of SDK-internal _registeredTools.
|
|
397
393
|
const toolMap = getRegisteredTools();
|
|
398
394
|
const groupManager = new GroupManager(toolMap, () => {
|
|
399
395
|
server.sendToolListChanged();
|