agent-method 1.5.13 → 1.5.15
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/docs/internal/doc-tokens.yaml +1 -1
- package/lib/cli/add.js +170 -96
- package/lib/cli/casestudy.js +152 -92
- package/lib/cli/close.js +164 -141
- package/lib/cli/helpers.js +13 -0
- package/lib/cli/record.js +81 -59
- package/lib/cli/upgrade.js +47 -36
- package/lib/init.js +1 -2
- package/lib/mcp-server.js +842 -1
- package/package.json +1 -1
package/lib/cli/upgrade.js
CHANGED
|
@@ -1,4 +1,9 @@
|
|
|
1
|
-
/**
|
|
1
|
+
/**
|
|
2
|
+
* wwa upgrade — brownfield-safe methodology update.
|
|
3
|
+
*
|
|
4
|
+
* Invariant (all wwa commands): canonical names persist in the working directory;
|
|
5
|
+
* versioned/archived copies live only under .wwa-archive/ (see helpers.WWA_ARCHIVE_DIR).
|
|
6
|
+
*/
|
|
2
7
|
|
|
3
8
|
import {
|
|
4
9
|
readFileSync, existsSync, mkdirSync, copyFileSync, unlinkSync,
|
|
@@ -6,7 +11,7 @@ import {
|
|
|
6
11
|
import { resolve, join, dirname } from "node:path";
|
|
7
12
|
import {
|
|
8
13
|
findEntryPoint, readMethodVersion, basename_of, pkg, packageRoot,
|
|
9
|
-
safeWriteFile, safeCopyFile,
|
|
14
|
+
safeWriteFile, safeCopyFile, WWA_ARCHIVE_DIR,
|
|
10
15
|
} from "./helpers.js";
|
|
11
16
|
|
|
12
17
|
export function register(program) {
|
|
@@ -206,12 +211,12 @@ export function register(program) {
|
|
|
206
211
|
}
|
|
207
212
|
}
|
|
208
213
|
|
|
209
|
-
// 6. Non-destructive template/schema upgrades (
|
|
214
|
+
// 6. Non-destructive template/schema upgrades (archived originals + live latest)
|
|
210
215
|
//
|
|
211
|
-
// When templates or schemas change, we never
|
|
212
|
-
//
|
|
213
|
-
// -
|
|
214
|
-
// - Add a backlog entry pointing to the
|
|
216
|
+
// When templates or schemas change, we never delete user content. Instead we:
|
|
217
|
+
// - Archive the existing file into a subdirectory (e.g. .wwa-archive/entry-points/CLAUDE.md)
|
|
218
|
+
// - Replace the live file with the latest template/schema
|
|
219
|
+
// - Add a backlog entry pointing to the archived copy so migration can be reviewed.
|
|
215
220
|
|
|
216
221
|
// 6a. Entry point templates (CLAUDE.md / .cursorrules / AGENT.md)
|
|
217
222
|
if (ep) {
|
|
@@ -220,19 +225,20 @@ export function register(program) {
|
|
|
220
225
|
if (existsSync(templatePath)) {
|
|
221
226
|
const change = classifyMarkdownChange(templatePath, ep);
|
|
222
227
|
if (change === "present_diverged_user") {
|
|
223
|
-
const
|
|
224
|
-
const
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
228
|
+
const archiveDir = join(d, WWA_ARCHIVE_DIR, "entry-points");
|
|
229
|
+
const baseArchivePath = join(archiveDir, entryName);
|
|
230
|
+
const archivePath = nextVersionedPathInsideArchive(archiveDir, entryName);
|
|
231
|
+
const relArchive = archivePath.replace(d, "").replace(/^[\\/]/, "");
|
|
232
|
+
actions.push(`Archive existing entry point to ${relArchive} and replace with latest template`);
|
|
233
|
+
if (!opts.dryRun) {
|
|
234
|
+
mkdirSync(dirname(archivePath), { recursive: true });
|
|
235
|
+
safeCopyFile(ep, archivePath);
|
|
236
|
+
safeCopyFile(templatePath, ep);
|
|
231
237
|
}
|
|
232
238
|
ensureBacklogEntry(
|
|
233
239
|
d,
|
|
234
|
-
|
|
235
|
-
`- [ ] **Review
|
|
240
|
+
relArchive,
|
|
241
|
+
`- [ ] **Review upgraded entry point** — Existing entry point archived at ${relArchive}. Compare with current ${entryName} and reconcile any custom conventions.`
|
|
236
242
|
);
|
|
237
243
|
}
|
|
238
244
|
}
|
|
@@ -249,19 +255,19 @@ export function register(program) {
|
|
|
249
255
|
if (existsSync(projectTokensPath) && existsSync(templateTokensPath)) {
|
|
250
256
|
const change = classifyYamlChange(templateTokensPath, projectTokensPath);
|
|
251
257
|
if (change === "schema_changed" || change === "present_diverged_user") {
|
|
252
|
-
const
|
|
253
|
-
const
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
258
|
+
const archiveDir = join(d, WWA_ARCHIVE_DIR, "registry");
|
|
259
|
+
const archivePath = nextVersionedPathInsideArchive(archiveDir, "doc-tokens.yaml");
|
|
260
|
+
const relArchive = archivePath.replace(d, "").replace(/^[\\/]/, "");
|
|
261
|
+
actions.push(`Archive existing registry/doc-tokens.yaml to ${relArchive} and replace with latest schema`);
|
|
262
|
+
if (!opts.dryRun) {
|
|
263
|
+
mkdirSync(dirname(archivePath), { recursive: true });
|
|
264
|
+
safeCopyFile(projectTokensPath, archivePath);
|
|
265
|
+
safeCopyFile(templateTokensPath, projectTokensPath);
|
|
260
266
|
}
|
|
261
267
|
ensureBacklogEntry(
|
|
262
268
|
d,
|
|
263
|
-
|
|
264
|
-
`- [ ] **
|
|
269
|
+
relArchive,
|
|
270
|
+
`- [ ] **Review doc-tokens schema migration** — Previous schema archived at ${relArchive}. Confirm that tooling and docs are compatible with the updated registry/doc-tokens.yaml.`
|
|
265
271
|
);
|
|
266
272
|
}
|
|
267
273
|
}
|
|
@@ -282,8 +288,12 @@ export function register(program) {
|
|
|
282
288
|
}
|
|
283
289
|
|
|
284
290
|
// ---------------------------------------------------------------------------
|
|
285
|
-
// Helper functions — change classification,
|
|
291
|
+
// Helper functions — change classification, archive paths, backlog entries
|
|
286
292
|
// ---------------------------------------------------------------------------
|
|
293
|
+
//
|
|
294
|
+
// Versioned filenames are only ever created inside the archive subdirectory,
|
|
295
|
+
// never in the working directory, so canonical names (CLAUDE.md, doc-tokens.yaml)
|
|
296
|
+
// always persist in place.
|
|
287
297
|
|
|
288
298
|
function classifyMarkdownChange(templatePath, projectPath) {
|
|
289
299
|
if (!existsSync(projectPath) || !existsSync(templatePath)) return "missing";
|
|
@@ -303,16 +313,17 @@ function classifyYamlChange(templatePath, projectPath) {
|
|
|
303
313
|
return "schema_changed";
|
|
304
314
|
}
|
|
305
315
|
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
316
|
+
/**
|
|
317
|
+
* Return a path for an archived copy, with a version suffix only inside the archive dir.
|
|
318
|
+
* Ensures we never write *.v2.* in the working directory — only under archiveDir.
|
|
319
|
+
*/
|
|
320
|
+
function nextVersionedPathInsideArchive(archiveDir, filename) {
|
|
321
|
+
const match = filename.match(/^(.*)(\.[^./\\]+)$/);
|
|
322
|
+
const stem = match ? match[1] : filename;
|
|
309
323
|
const ext = match ? match[2] : "";
|
|
310
324
|
let counter = 2;
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
// eslint-disable-next-line no-constant-condition
|
|
314
|
-
while (true) {
|
|
315
|
-
const candidate = `${stem}.v${counter}${ext}`;
|
|
325
|
+
for (;;) {
|
|
326
|
+
const candidate = join(archiveDir, `${stem}.v${counter}${ext}`);
|
|
316
327
|
if (!existsSync(candidate)) return candidate;
|
|
317
328
|
counter += 1;
|
|
318
329
|
}
|
package/lib/init.js
CHANGED
|
@@ -57,8 +57,7 @@ export async function initProject(projectType, directory, opts = {}) {
|
|
|
57
57
|
|
|
58
58
|
const templateDir = join(methodRoot, "templates", tier);
|
|
59
59
|
if (!existsSync(templateDir)) {
|
|
60
|
-
|
|
61
|
-
process.exit(1);
|
|
60
|
+
throw new Error(`Template directory not found: ${templateDir}`);
|
|
62
61
|
}
|
|
63
62
|
|
|
64
63
|
console.log(`\nSetting up ${FRIENDLY_NAMES[projectType] || projectType} project`);
|