agent-method 1.5.1 → 1.5.3

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/lib/cli/route.js CHANGED
@@ -1,4 +1,4 @@
1
- /** agent-method route — show how a query routes through the pipeline. */
1
+ /** wwa route — show how a query routes through the pipeline. */
2
2
 
3
3
  import {
4
4
  resolveProjectType,
package/lib/cli/scan.js CHANGED
@@ -1,4 +1,4 @@
1
- /** agent-method scan — detect project type from directory contents. */
1
+ /** wwa scan — detect project type from directory contents. */
2
2
 
3
3
  import { getPipeline, outputData } from "./helpers.js";
4
4
 
@@ -17,9 +17,9 @@ export function register(program) {
17
17
  const friendlyMap = { analytical: "context", mixed: "mix" };
18
18
  if (ptype in friendlyMap) {
19
19
  result.friendly_name = friendlyMap[ptype];
20
- result.init_command = `npx agent-method init ${friendlyMap[ptype]}`;
20
+ result.init_command = `npx wwa init ${friendlyMap[ptype]}`;
21
21
  } else {
22
- result.init_command = `npx agent-method init ${ptype}`;
22
+ result.init_command = `npx wwa init ${ptype}`;
23
23
  }
24
24
 
25
25
  console.log(`Scanning: ${directory}`);
@@ -0,0 +1,23 @@
1
+ /** wwa serve — start MCP server on stdio transport. */
2
+
3
+ export function register(program) {
4
+ program
5
+ .command("serve")
6
+ .description("Start MCP server exposing methodology tools via stdio transport")
7
+ .option("--registry <path>", "Path to feature-registry.yaml")
8
+ .action(async (opts) => {
9
+ // Redirect all non-MCP output to stderr so stdout stays clean for JSON-RPC
10
+ const info = (msg) => process.stderr.write(msg + "\n");
11
+
12
+ info("wwa MCP server starting...");
13
+
14
+ try {
15
+ const { startServer } = await import("../mcp-server.js");
16
+ await startServer(opts.registry || undefined);
17
+ info("wwa MCP server running on stdio. Press Ctrl+C to stop.");
18
+ } catch (err) {
19
+ info(`Error: ${err.message}`);
20
+ process.exit(1);
21
+ }
22
+ });
23
+ }
package/lib/cli/status.js CHANGED
@@ -1,4 +1,4 @@
1
- /** agent-method status — check if methodology version is current. */
1
+ /** wwa status — check if methodology version is current. */
2
2
 
3
3
  import { findEntryPoint, readMethodVersion, basename_of, pkg } from "./helpers.js";
4
4
 
@@ -38,7 +38,7 @@ export function register(program) {
38
38
  message =
39
39
  `Entry point ${basename_of(ep)} is outdated ` +
40
40
  `(method_version: ${epVersion}, installed: ${installed}). ` +
41
- `Run \`npx agent-method upgrade ${directory}\` to update.`;
41
+ `Run \`npx wwa upgrade ${directory}\` to update.`;
42
42
  }
43
43
 
44
44
  if (opts.json) {
@@ -1,4 +1,4 @@
1
- /** agent-method upgrade — brownfield-safe methodology update. */
1
+ /** wwa upgrade — brownfield-safe methodology update. */
2
2
 
3
3
  import {
4
4
  readFileSync, existsSync, copyFileSync, mkdirSync, writeFileSync,
@@ -39,7 +39,7 @@ export function register(program) {
39
39
  if (!existsSync(srcDir)) {
40
40
  console.error(
41
41
  `Template directory not found: ${srcDir}. ` +
42
- "Run from the agent-method repo or install from source."
42
+ "Run from the wwa repo or install from source."
43
43
  );
44
44
  process.exit(1);
45
45
  }
@@ -65,7 +65,7 @@ export function register(program) {
65
65
  `## Method version\n\n` +
66
66
  `method_version: ${newVer}\n` +
67
67
  `<!-- Tracks which methodology version generated this entry point -->\n` +
68
- `<!-- Use \`npx agent-method status\` to compare against latest -->\n\n`;
68
+ `<!-- Use \`npx wwa status\` to compare against latest -->\n\n`;
69
69
  content = content.replace("## Conventions", insert + "## Conventions");
70
70
  writeFileSync(ep, content, "utf-8");
71
71
  }
@@ -100,8 +100,8 @@ export function register(program) {
100
100
  if (content.includes("<!-- INSTRUCTION: Add project-specific cascade")) {
101
101
  content = content.replace(
102
102
  "<!-- INSTRUCTION: Add project-specific cascade",
103
- "| Session close | SESSION-LOG.md (append micro-entry" +
104
- " \u2014 workflow, features, cascades, friction, findings) " +
103
+ "| Session close or high-effort task completion | SESSION-LOG.md (append metrics entry" +
104
+ " \u2014 effort, ambiguity, context level, tokens, time, workflow, features, cascades, friction, findings) " +
105
105
  "|\n\n<!-- INSTRUCTION: Add project-specific cascade"
106
106
  );
107
107
  writeFileSync(ep, content, "utf-8");
@@ -119,8 +119,9 @@ export function register(program) {
119
119
  if (content.includes("## Do not")) {
120
120
  content = content.replace(
121
121
  "## Do not",
122
- "- At session close, append a micro-entry to " +
123
- "SESSION-LOG.md \u2014 never skip, never read " +
122
+ "- At session close or after any high-effort task, append a metrics entry to " +
123
+ "SESSION-LOG.md \u2014 include effort level, question ambiguity, context level, " +
124
+ "estimated tokens, and time. Never skip, never read " +
124
125
  "previous entries during normal work\n\n" +
125
126
  "## Do not"
126
127
  );
@@ -0,0 +1,32 @@
1
+ /** wwa watch — file watcher for proactive validation. */
2
+
3
+ export function register(program) {
4
+ program
5
+ .command("watch [directory]")
6
+ .description("Watch entry points and markdown files for changes, validate on save")
7
+ .option("--registry <path>", "Path to feature-registry.yaml")
8
+ .action(async (directory, opts) => {
9
+ const dir = directory || ".";
10
+
11
+ console.log(`Watching: ${dir}`);
12
+ console.log("Monitoring entry points, registry, and markdown files...");
13
+ console.log("Press Ctrl+C to stop.\n");
14
+
15
+ try {
16
+ const { createWatcher } = await import("../watcher.js");
17
+ const watcher = createWatcher(dir, {
18
+ registryPath: opts.registry || undefined,
19
+ });
20
+
21
+ // Keep process alive
22
+ process.on("SIGINT", () => {
23
+ watcher.close();
24
+ console.log("\nWatcher stopped.");
25
+ process.exit(0);
26
+ });
27
+ } catch (err) {
28
+ console.error(`Error: ${err.message}`);
29
+ process.exit(1);
30
+ }
31
+ });
32
+ }
package/lib/init.js CHANGED
@@ -5,7 +5,7 @@
5
5
  * prompts for project configuration.
6
6
  */
7
7
 
8
- import { existsSync, mkdirSync, copyFileSync, readFileSync, writeFileSync, readdirSync } from "node:fs";
8
+ import { existsSync, mkdirSync, copyFileSync, readFileSync, writeFileSync, readdirSync, unlinkSync } from "node:fs";
9
9
  import { resolve, join, dirname, basename, relative } from "node:path";
10
10
  import { fileURLToPath } from "node:url";
11
11
 
@@ -26,11 +26,17 @@ const FRIENDLY_NAMES = {
26
26
  general: "General project",
27
27
  };
28
28
 
29
+ const RUNTIME_ENTRY_POINTS = {
30
+ claude: "CLAUDE.md",
31
+ cursor: ".cursorrules",
32
+ all: null, // keep all
33
+ };
34
+
29
35
  /**
30
36
  * Set up a new project with methodology templates.
31
37
  */
32
38
  export async function initProject(projectType, directory, opts = {}) {
33
- const { tier = "starter", registryPath } = opts;
39
+ const { tier = "starter", runtime = "all", profile = "standard", registryPath } = opts;
34
40
  const targetDir = resolve(directory);
35
41
  const methodRoot = resolve(__dirname, "..");
36
42
 
@@ -42,6 +48,8 @@ export async function initProject(projectType, directory, opts = {}) {
42
48
 
43
49
  console.log(`\nSetting up ${FRIENDLY_NAMES[projectType] || projectType} project`);
44
50
  console.log(` Template: ${tier}`);
51
+ console.log(` Profile: ${profile}`);
52
+ console.log(` Runtime: ${runtime}`);
45
53
  console.log(` Target: ${targetDir}\n`);
46
54
 
47
55
  // Detect brownfield (existing project with methodology files)
@@ -72,21 +80,38 @@ export async function initProject(projectType, directory, opts = {}) {
72
80
  // Replace placeholders in entry points
73
81
  replacePlaceholders(targetDir, projectType, tier);
74
82
 
83
+ // Set integration profile in entry points
84
+ setProfile(targetDir, profile);
85
+
86
+ // Remove unused entry points based on runtime choice
87
+ const removed = removeUnusedEntryPoints(targetDir, runtime, isBrownfield);
88
+
75
89
  // Report
76
90
  console.log(` Files created: ${copied.length}`);
77
91
  for (const f of copied) console.log(` + ${f}`);
92
+ if (removed.length > 0) {
93
+ console.log(` Entry points removed: ${removed.length}`);
94
+ for (const f of removed) console.log(` - ${f}`);
95
+ }
78
96
  if (skipped.length > 0) {
79
97
  console.log(` Files skipped (already exist): ${skipped.length}`);
80
98
  for (const f of skipped) console.log(` ~ ${f}`);
81
99
  }
82
100
 
101
+ // Determine which entry point the user kept
102
+ const keptEntry = runtime === "claude" ? "CLAUDE.md"
103
+ : runtime === "cursor" ? ".cursorrules"
104
+ : "CLAUDE.md / .cursorrules / AGENT.md";
105
+
83
106
  console.log(`\nNext steps:`);
84
107
  console.log(` 1. cd ${relative(process.cwd(), targetDir) || "."}`);
85
108
  console.log(` 2. Fill in PROJECT.md with your project vision`);
86
- console.log(` 3. Delete the two entry point files you don't use`);
87
- console.log(` (keep CLAUDE.md, .cursorrules, or AGENT.md)`);
88
- console.log(` 4. Start a conversation — the agent reads the entry point`);
89
- console.log(`\nRun \`npx agent-method check\` to validate your setup.`);
109
+ if (runtime === "all") {
110
+ console.log(` 3. Delete the two entry point files you don't use`);
111
+ console.log(` (keep CLAUDE.md, .cursorrules, or AGENT.md)`);
112
+ }
113
+ console.log(` ${runtime === "all" ? "4" : "3"}. Start a conversation — the agent reads ${keptEntry} automatically`);
114
+ console.log(`\nVerify: npx wwa check`);
90
115
  }
91
116
 
92
117
  function detectBrownfield(dir) {
@@ -238,3 +263,34 @@ function replacePlaceholders(targetDir, projectType, tier) {
238
263
  writeFileSync(epPath, content, "utf-8");
239
264
  }
240
265
  }
266
+
267
+ function setProfile(targetDir, profile) {
268
+ for (const epName of ["CLAUDE.md", ".cursorrules", "AGENT.md"]) {
269
+ const epPath = join(targetDir, epName);
270
+ if (!existsSync(epPath)) continue;
271
+
272
+ let content = readFileSync(epPath, "utf-8");
273
+ content = content.replace(/tier:\s*(lite|standard|full)/, `tier: ${profile}`);
274
+ writeFileSync(epPath, content, "utf-8");
275
+ }
276
+ }
277
+
278
+ function removeUnusedEntryPoints(targetDir, runtime, isBrownfield) {
279
+ if (runtime === "all" || isBrownfield) return [];
280
+
281
+ const allEntryPoints = ["CLAUDE.md", ".cursorrules", "AGENT.md"];
282
+ const keep = RUNTIME_ENTRY_POINTS[runtime];
283
+ if (!keep) return [];
284
+
285
+ const removed = [];
286
+ for (const ep of allEntryPoints) {
287
+ if (ep !== keep) {
288
+ const epPath = join(targetDir, ep);
289
+ if (existsSync(epPath)) {
290
+ unlinkSync(epPath);
291
+ removed.push(ep);
292
+ }
293
+ }
294
+ }
295
+ return removed;
296
+ }