@raymondchins/agentmap 0.4.0 → 0.6.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/agentmap.mjs +209 -13
- package/package.json +2 -2
package/agentmap.mjs
CHANGED
|
@@ -17,6 +17,9 @@ import { writeFileSync, readFileSync, existsSync, mkdirSync, renameSync, readdir
|
|
|
17
17
|
import { execSync, execFileSync } from "node:child_process";
|
|
18
18
|
import { createHash } from "node:crypto";
|
|
19
19
|
import { createRequire } from "node:module";
|
|
20
|
+
import { homedir } from "node:os";
|
|
21
|
+
import { fileURLToPath } from "node:url";
|
|
22
|
+
import { join, dirname } from "node:path";
|
|
20
23
|
|
|
21
24
|
// Lazy ts-morph: its ~105ms module init only fires on a COLD rebuild. Warm cache
|
|
22
25
|
// queries (the common case) never construct a Project, so they skip the load
|
|
@@ -28,7 +31,10 @@ const tsMorph = () => (_tsm ??= _require("ts-morph"));
|
|
|
28
31
|
|
|
29
32
|
const MAP = ".claude/agentmap/map.json";
|
|
30
33
|
const MAP_LEGACY = ".claude/agentmap.json"; // pre-namespacing path; read for migration
|
|
31
|
-
|
|
34
|
+
// Bumped 2 → 3: Vue SFC support. `.vue` files now appear in the map and the
|
|
35
|
+
// source-discovery / freshness checks treat them as first-class source files.
|
|
36
|
+
// Old caches (schema 2) are ignored so the first run after upgrade rebuilds.
|
|
37
|
+
const SCHEMA_VERSION = 3;
|
|
32
38
|
|
|
33
39
|
// ---------------------------------------------------------------------------
|
|
34
40
|
// Tuning constants — KEEP THESE VALUES IDENTICAL (output + marketing must not
|
|
@@ -85,7 +91,7 @@ const dirtyCount = () =>
|
|
|
85
91
|
let p = l.slice(3); // strip "XY " status prefix
|
|
86
92
|
if (p.includes(" -> ")) p = p.split(" -> ").pop(); // rename: keep the new path
|
|
87
93
|
p = p.replace(/^"|"$/g, ""); // unquote space/special paths
|
|
88
|
-
return /\.(ts|tsx|mjs|cjs|
|
|
94
|
+
return /\.(ts|tsx|mts|cts|js|jsx|mjs|cjs|vue)$/.test(p);
|
|
89
95
|
}).length;
|
|
90
96
|
const tokEst = (s) => Math.ceil((s || "").length / 4); // rough chars/4 estimate
|
|
91
97
|
|
|
@@ -96,7 +102,8 @@ const getOrSet = (m, k, make) => { let v = m.get(k); if (v === undefined) { v =
|
|
|
96
102
|
// "path:mtimeMs:size" for source files so the cache can be trusted between runs
|
|
97
103
|
// without a full reparse. Skips node_modules/.git/.next. Any error ⇒ "" (caller
|
|
98
104
|
// falls through to build, i.e. current behavior). Never used on the git path.
|
|
99
|
-
|
|
105
|
+
// Includes `.vue` so editing a Vue SFC invalidates the non-git cache too.
|
|
106
|
+
const SRC_EXT = /\.(ts|tsx|mts|cts|jsx|js|mjs|cjs|vue)$/;
|
|
100
107
|
function sourceFingerprint() {
|
|
101
108
|
try {
|
|
102
109
|
const entries = [];
|
|
@@ -121,6 +128,70 @@ function sourceFingerprint() {
|
|
|
121
128
|
} catch { return ""; }
|
|
122
129
|
}
|
|
123
130
|
|
|
131
|
+
// =============================================================================
|
|
132
|
+
// Vue Single File Component support — best-effort, zero-dependency.
|
|
133
|
+
//
|
|
134
|
+
// agentmap is TS/JS-first. Vue `.vue` SFCs are NOT TypeScript; the Vue compiler
|
|
135
|
+
// (`@vue/compiler-sfc`) is intentionally NOT a dependency (CONTRIBUTING near-
|
|
136
|
+
// zero-deps rule). Instead we extract ONLY the `<script>` / `<script setup>`
|
|
137
|
+
// block text with a conservative regex and feed it to ts-morph as a VIRTUAL
|
|
138
|
+
// source file (e.g. `App.vue.ts`). A virtual→real path map (see build())
|
|
139
|
+
// rewrites every user-facing path back to the real `.vue` path so no
|
|
140
|
+
// `.vue.ts` / `.vue.js` ever leaks into JSON or prose.
|
|
141
|
+
//
|
|
142
|
+
// Non-goals: no template AST, no `<style>` parsing, no Nuxt auto-import
|
|
143
|
+
// resolution, no Svelte/Astro. Only `<script>` blocks that look like JS/TS.
|
|
144
|
+
// =============================================================================
|
|
145
|
+
|
|
146
|
+
// Find the first top-level `<script ...>` block (optionally `<script setup ...>`)
|
|
147
|
+
// whose opening tag does NOT carry `src="..."` (external script reference —
|
|
148
|
+
// the actual JS lives in another file agentmap already indexes on its own).
|
|
149
|
+
// Handles single + double quoted lang/src attributes and `lang="ts"`/`ts`.
|
|
150
|
+
// Returns { lang, setup, text } for the matched block, or null if none.
|
|
151
|
+
//
|
|
152
|
+
// Greedy-free: stops at the FIRST `</script>` on its own. Vue forbids nested
|
|
153
|
+
// `<script>` tags, so a non-greedy match up to `</script>` is safe. We do NOT
|
|
154
|
+
// support `<script>` + `<script setup>` in the same SFC for indexing — we pick
|
|
155
|
+
// the richer one: prefer `setup` block if present, else the normal block.
|
|
156
|
+
function extractVueScripts(text) {
|
|
157
|
+
const blocks = [];
|
|
158
|
+
// Open-tag matcher is QUOTE-AWARE: attribute values may legitimately contain
|
|
159
|
+
// `>` (e.g. `<script setup lang="ts" generic="T extends Record<string, unknown>">`
|
|
160
|
+
// — a common Vue 3 idiom for typed generic components). We require all
|
|
161
|
+
// attributes to be either bare (`setup`) or quoted (`name="value"` or
|
|
162
|
+
// `name='value'`), which matches valid SFC syntax. Bareword and unquoted forms
|
|
163
|
+
// are intentionally not matched because they're not valid HTML and would
|
|
164
|
+
// almost certainly indicate a parsing bug we want to surface, not silently
|
|
165
|
+
// misparse.
|
|
166
|
+
const re = /<script(\s+[a-zA-Z][\w-]*(\s*=\s*(?:"[^"]*"|'[^']*'))?)*\s*\/?>/gi;
|
|
167
|
+
let m;
|
|
168
|
+
while ((m = re.exec(text)) !== null) {
|
|
169
|
+
const attrs = (m[0].slice(7, -1) || "").trim(); // strip <script…> wrapper
|
|
170
|
+
// find body: text after the opening tag up to </script>
|
|
171
|
+
const openEnd = m.index + m[0].length;
|
|
172
|
+
const closeStart = text.toLowerCase().indexOf("</script>", openEnd);
|
|
173
|
+
if (closeStart === -1) break; // unterminated — stop scanning
|
|
174
|
+
const body = text.slice(openEnd, closeStart);
|
|
175
|
+
// external script reference → skip (the target file is indexed directly).
|
|
176
|
+
if (/\bsrc\s*=\s*["'][^"']+["']/i.test(attrs)) continue;
|
|
177
|
+
if (!body.trim()) continue; // empty body (e.g. <script/>) — not useful
|
|
178
|
+
const setup = /\bsetup\b/i.test(attrs);
|
|
179
|
+
const lang = (attrs.match(/\blang\s*=\s*["']([^"']+)["']/i) || [])[1] || "js";
|
|
180
|
+
blocks.push({ lang: lang.toLowerCase(), setup, text: body });
|
|
181
|
+
re.lastIndex = closeStart + "</script>".length; // resume after </script>
|
|
182
|
+
}
|
|
183
|
+
if (!blocks.length) return null;
|
|
184
|
+
// Prefer a setup block (the modern idiom) when present; else the plain block.
|
|
185
|
+
return blocks.find((b) => b.setup) || blocks[0];
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
// Virtual file path mapping for a `.vue` source. The virtual path is what
|
|
189
|
+
// ts-morph sees (so `.ts`/`.js` parsing kicks in); the real path is what every
|
|
190
|
+
// user-facing output shows. `lang="ts"` → `.vue.ts`, otherwise `.vue.js`.
|
|
191
|
+
function vueVirtualPath(realPath, lang) {
|
|
192
|
+
return lang === "ts" ? `${realPath}.ts` : `${realPath}.js`;
|
|
193
|
+
}
|
|
194
|
+
|
|
124
195
|
// Feature = first real route segment under app/ (or src/app/), skipping route
|
|
125
196
|
// groups (parens), dynamic segments ([id]) and parallel routes (@slot).
|
|
126
197
|
function featureOf(path) {
|
|
@@ -246,13 +317,25 @@ function makeProject() {
|
|
|
246
317
|
const loaded = new Set(project.getSourceFiles().map((s) => s.getFilePath()));
|
|
247
318
|
const cwdp = process.cwd().replace(/\\/g, "/");
|
|
248
319
|
const listed = sh("git ls-files --cached --others --exclude-standard").split("\n").filter(Boolean);
|
|
320
|
+
// `.vue` discovery: same channel as TS/JS (git ls-files when available, else
|
|
321
|
+
// a broad glob fallback). We do NOT hand `.vue` straight to ts-morph (it is
|
|
322
|
+
// not TS/JS). Instead, for each `.vue` file we read its `<script>` block via
|
|
323
|
+
// extractVueScripts() and register it as a VIRTUAL source file
|
|
324
|
+
// (`App.vue.ts` / `App.vue.js`). A virtual→real path map is returned alongside
|
|
325
|
+
// the project so build() can rewrite every user-facing path back to `.vue`.
|
|
326
|
+
const vueFiles = [];
|
|
249
327
|
if (listed.length) {
|
|
250
328
|
const missing = [];
|
|
251
329
|
for (const f of listed) {
|
|
252
|
-
if (
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
330
|
+
if (/\.(ts|tsx|mts|cts|js|jsx|mjs|cjs)$/.test(f)) {
|
|
331
|
+
const segs = f.split("/");
|
|
332
|
+
if (segs.includes("node_modules") || segs.includes(".next")) continue;
|
|
333
|
+
if (!loaded.has(`${cwdp}/${f}`)) missing.push(f);
|
|
334
|
+
} else if (f.endsWith(".vue")) {
|
|
335
|
+
const segs = f.split("/");
|
|
336
|
+
if (segs.includes("node_modules") || segs.includes(".next")) continue;
|
|
337
|
+
vueFiles.push(f);
|
|
338
|
+
}
|
|
256
339
|
}
|
|
257
340
|
if (missing.length) project.addSourceFilesAtPaths(missing);
|
|
258
341
|
} else {
|
|
@@ -262,8 +345,38 @@ function makeProject() {
|
|
|
262
345
|
"components/**/*.{ts,tsx,mts,cts,js,jsx,mjs,cjs}", "lib/**/*.{ts,tsx,mts,cts,js,jsx,mjs,cjs}",
|
|
263
346
|
"pages/**/*.{ts,tsx,mts,cts,js,jsx,mjs,cjs}", "*.{ts,tsx,mts,cts,js,jsx,mjs,cjs}",
|
|
264
347
|
]);
|
|
348
|
+
// Non-git `.vue` fallback: walk the tree like sourceFingerprint() does.
|
|
349
|
+
try {
|
|
350
|
+
const walk = (dir) => {
|
|
351
|
+
for (const name of readdirSync(dir)) {
|
|
352
|
+
if (name === "node_modules" || name === ".git" || name === ".next") continue;
|
|
353
|
+
const full = dir + "/" + name;
|
|
354
|
+
// lstatSync (NOT statSync) + skip symlinks, matching sourceFingerprint():
|
|
355
|
+
// a circular symlink would otherwise recurse until the stack overflows.
|
|
356
|
+
let st; try { st = lstatSync(full); } catch { continue; }
|
|
357
|
+
if (st.isSymbolicLink()) continue;
|
|
358
|
+
if (st.isDirectory()) walk(full);
|
|
359
|
+
else if (name.endsWith(".vue")) vueFiles.push(full.replace(/^\.\//, ""));
|
|
360
|
+
}
|
|
361
|
+
};
|
|
362
|
+
walk(".");
|
|
363
|
+
} catch { /* ignore — proceed without Vue */ }
|
|
265
364
|
}
|
|
266
|
-
|
|
365
|
+
// Build the virtual→real map and register each `<script>` block as a virtual
|
|
366
|
+
// ts-morph source. Files without a usable `<script>` block are silently
|
|
367
|
+
// skipped (template/style-only SFCs contribute nothing to the import graph).
|
|
368
|
+
const vueMap = Object.create(null); // virtualPath → realPath
|
|
369
|
+
const vueReal = Object.create(null); // realPath → true (for resolver)
|
|
370
|
+
for (const f of vueFiles) {
|
|
371
|
+
let text; try { text = readFileSync(f, "utf8"); } catch { continue; }
|
|
372
|
+
const block = extractVueScripts(text);
|
|
373
|
+
if (!block || !block.text.trim()) continue;
|
|
374
|
+
const vpath = vueVirtualPath(f, block.lang);
|
|
375
|
+
project.createSourceFile(`${cwdp}/${vpath}`, block.text, { overwrite: true });
|
|
376
|
+
vueMap[`${cwdp}/${vpath}`] = `${cwdp}/${f}`;
|
|
377
|
+
vueReal[`${cwdp}/${f}`] = true;
|
|
378
|
+
}
|
|
379
|
+
return { project, vueMap, vueReal };
|
|
267
380
|
}
|
|
268
381
|
|
|
269
382
|
// ---------------------------------------------------------------------------
|
|
@@ -273,11 +386,18 @@ function makeProject() {
|
|
|
273
386
|
// ---------------------------------------------------------------------------
|
|
274
387
|
function build() {
|
|
275
388
|
const t0 = Date.now();
|
|
276
|
-
const project = makeProject();
|
|
389
|
+
const { project, vueMap, vueReal } = makeProject();
|
|
277
390
|
const { SyntaxKind } = tsMorph();
|
|
278
391
|
const CallExpression = SyntaxKind.CallExpression;
|
|
279
392
|
const cwd = process.cwd().replace(/\\/g, "/");
|
|
280
|
-
|
|
393
|
+
// rel() rewrites ts-morph file paths to repo-relative keys. For Vue virtual
|
|
394
|
+
// sources (`App.vue.ts`), vueMap rewrites back to the real `.vue` path so
|
|
395
|
+
// users never see virtual paths in the map, hubs, --relates, or --find.
|
|
396
|
+
const rel = (p) => {
|
|
397
|
+
const abs = p.replace(/\\/g, "/");
|
|
398
|
+
const real = vueMap[abs];
|
|
399
|
+
return (real || abs).replace(cwd + "/", "");
|
|
400
|
+
};
|
|
281
401
|
const files = {}, dependents = {}, features = {};
|
|
282
402
|
// PATH-SEGMENT exclusion (not substring) so e.g. components/.next-demo or
|
|
283
403
|
// src/node_modules_helper.ts are NOT wrongly excluded.
|
|
@@ -298,10 +418,19 @@ function build() {
|
|
|
298
418
|
};
|
|
299
419
|
const baseAbs = join(fromAbsDir, spec);
|
|
300
420
|
const tryGet = (abs) => { const sf = project.getSourceFile(abs); return sf ? sf : null; };
|
|
421
|
+
// Vue SFC: `import X from "./C.vue"` (exact) ALWAYS wins — the user wrote
|
|
422
|
+
// `.vue` explicitly, so we honor that. This check must stay BEFORE the
|
|
423
|
+
// TS/JS loop.
|
|
424
|
+
if (vueReal[baseAbs]) return rel(baseAbs);
|
|
301
425
|
let sf = tryGet(baseAbs);
|
|
302
426
|
if (!sf) for (const e of RES_EXT) { sf = tryGet(`${baseAbs}.${e}`); if (sf) break; }
|
|
303
427
|
if (!sf) for (const e of RES_EXT) { sf = tryGet(`${baseAbs}/index.${e}`); if (sf) break; }
|
|
304
|
-
|
|
428
|
+
// TS/JS SHADOW WINS: when a same-name .ts/.js exists, the extensionless
|
|
429
|
+
// `import "./C"` resolves to it (TS/JS-first priority is preserved). Only
|
|
430
|
+
// fall through to `.vue` as a last resort, when no TS/JS shadow exists.
|
|
431
|
+
if (sf) return rel(sf.getFilePath());
|
|
432
|
+
if (vueReal[`${baseAbs}.vue`]) return rel(`${baseAbs}.vue`);
|
|
433
|
+
return null;
|
|
305
434
|
};
|
|
306
435
|
|
|
307
436
|
const sourceFiles = project.getSourceFiles();
|
|
@@ -598,7 +727,7 @@ function parseSettings(text, settingsPath) {
|
|
|
598
727
|
try { return JSON.parse(text) || {}; }
|
|
599
728
|
catch {
|
|
600
729
|
try { return JSON.parse(stripJsonComments(text)) || {}; }
|
|
601
|
-
catch { throw new Error(`${settingsPath} is not valid JSON — fix or remove it, then re-run
|
|
730
|
+
catch { throw new Error(`${settingsPath} is not valid JSON — fix or remove it, then re-run`); }
|
|
602
731
|
}
|
|
603
732
|
}
|
|
604
733
|
|
|
@@ -717,6 +846,65 @@ function installHooks({ dryRun = false } = {}) {
|
|
|
717
846
|
console.log("\nDone — the map auto-refreshes on commit, and greps are nudged to agentmap first.");
|
|
718
847
|
}
|
|
719
848
|
|
|
849
|
+
// ---------------------------------------------------------------------------
|
|
850
|
+
// --setup-mcp: register the agentmap MCP server in the global configs of
|
|
851
|
+
// MCP-capable IDEs that aren't Claude Code (which uses --install-hooks instead).
|
|
852
|
+
// Merge-safe + idempotent; with { dryRun:true } it prints the plan and writes
|
|
853
|
+
// nothing. Throws on the first malformed config so the caller can stderr+exit 1.
|
|
854
|
+
// ---------------------------------------------------------------------------
|
|
855
|
+
function setupMcp({ dryRun = false } = {}) {
|
|
856
|
+
const mcpPath = fileURLToPath(new URL("./mcp.mjs", import.meta.url));
|
|
857
|
+
|
|
858
|
+
// npx materializes the package under a `_npx` cache dir that gets garbage-
|
|
859
|
+
// collected, so a config pointing at that path would rot. When invoked via npx,
|
|
860
|
+
// pin to the published spec instead; otherwise reference the resolved file.
|
|
861
|
+
const isNpx = mcpPath.includes("_npx");
|
|
862
|
+
const command = isNpx ? "npx" : process.execPath;
|
|
863
|
+
const args = isNpx ? ["-y", "@raymondchins/agentmap", "--mcp"] : [mcpPath];
|
|
864
|
+
|
|
865
|
+
// Each target: a global config file + how to graft the agentmap entry into it.
|
|
866
|
+
// Antigravity is written to BOTH paths on purpose — older builds read only the
|
|
867
|
+
// IDE-specific ~/.gemini/antigravity path, newer unified builds read the shared
|
|
868
|
+
// ~/.gemini/config path, so writing both is version-proof.
|
|
869
|
+
const targets = [
|
|
870
|
+
{
|
|
871
|
+
label: "OpenCode",
|
|
872
|
+
path: join(homedir(), ".config", "opencode", "opencode.json"),
|
|
873
|
+
graft: (cfg) => { (cfg.mcp ??= {}).agentmap = { type: "stdio", command, args, enabled: true }; },
|
|
874
|
+
},
|
|
875
|
+
{
|
|
876
|
+
label: "Antigravity IDE",
|
|
877
|
+
path: join(homedir(), ".gemini", "antigravity", "mcp_config.json"),
|
|
878
|
+
graft: (cfg) => { (cfg.mcpServers ??= {}).agentmap = { command, args }; },
|
|
879
|
+
},
|
|
880
|
+
{
|
|
881
|
+
label: "Antigravity (shared)",
|
|
882
|
+
path: join(homedir(), ".gemini", "config", "mcp_config.json"),
|
|
883
|
+
graft: (cfg) => { (cfg.mcpServers ??= {}).agentmap = { command, args }; },
|
|
884
|
+
},
|
|
885
|
+
];
|
|
886
|
+
|
|
887
|
+
if (dryRun) console.log("--dry-run: would configure MCP server (no changes written):");
|
|
888
|
+
|
|
889
|
+
for (const { label, path, graft } of targets) {
|
|
890
|
+
// Reuse parseSettings so JSONC (comments) is tolerated and a malformed file
|
|
891
|
+
// throws a clear error WITHOUT clobbering the original (we never write on the
|
|
892
|
+
// failure path, so no .bak dance is needed).
|
|
893
|
+
let cfg = {};
|
|
894
|
+
if (existsSync(path)) cfg = parseSettings(readFileSync(path, "utf8"), path);
|
|
895
|
+
graft(cfg);
|
|
896
|
+
|
|
897
|
+
if (dryRun) {
|
|
898
|
+
console.log(` ${label}: would write to ${path}`);
|
|
899
|
+
} else {
|
|
900
|
+
mkdirSync(dirname(path), { recursive: true });
|
|
901
|
+
writeFileSync(path, JSON.stringify(cfg, null, 2) + "\n");
|
|
902
|
+
console.log(`configured ${label} MCP server → ${path}`);
|
|
903
|
+
}
|
|
904
|
+
}
|
|
905
|
+
}
|
|
906
|
+
|
|
907
|
+
|
|
720
908
|
// ---------------------------------------------------------------------------
|
|
721
909
|
// CLI
|
|
722
910
|
// ---------------------------------------------------------------------------
|
|
@@ -739,7 +927,7 @@ const out = (obj, prose) => { if (wantJson) console.log(JSON.stringify(obj)); el
|
|
|
739
927
|
// NOT in this set is an unknown flag → usage error (exit 2), not a silent build.
|
|
740
928
|
const KNOWN = new Set([
|
|
741
929
|
"--json", "--print",
|
|
742
|
-
"--help", "-h", "--version", "-v", "--install-hooks", "--dry-run", "--mcp",
|
|
930
|
+
"--help", "-h", "--version", "-v", "--install-hooks", "--dry-run", "--setup-mcp", "--mcp",
|
|
743
931
|
"--any", "--find", "--relates", "--map", "--focus", "--tokens",
|
|
744
932
|
"--symbols", "--feature", "--features", "--hubs",
|
|
745
933
|
]);
|
|
@@ -776,6 +964,9 @@ Maintenance:
|
|
|
776
964
|
--install-hooks [--dry-run]
|
|
777
965
|
install git post-commit + copy the PreToolUse nudge +
|
|
778
966
|
wire .claude/settings.json (--dry-run = preview, no writes)
|
|
967
|
+
--setup-mcp [--dry-run]
|
|
968
|
+
configure MCP server for OpenCode & Antigravity IDE
|
|
969
|
+
(--dry-run = preview, no writes)
|
|
779
970
|
--mcp start a stdio MCP server (for MCP-capable agents)
|
|
780
971
|
--help, -h show this help
|
|
781
972
|
--version, -v print the version
|
|
@@ -811,6 +1002,11 @@ else if (has("--install-hooks")) {
|
|
|
811
1002
|
try { installHooks({ dryRun: has("--dry-run") }); process.exit(0); }
|
|
812
1003
|
catch (e) { console.error(`agentmap --install-hooks failed: ${e?.message || e}`); process.exit(1); }
|
|
813
1004
|
}
|
|
1005
|
+
// --setup-mcp: configure MCP server for OpenCode & Antigravity IDE.
|
|
1006
|
+
else if (has("--setup-mcp")) {
|
|
1007
|
+
try { setupMcp({ dryRun: has("--dry-run") }); process.exit(0); }
|
|
1008
|
+
catch (e) { console.error(`agentmap --setup-mcp failed: ${e?.message || e}`); process.exit(1); }
|
|
1009
|
+
}
|
|
814
1010
|
// Unknown-flag guard: any "-"-prefixed token not in KNOWN → usage error (exit
|
|
815
1011
|
// 2). Runs BEFORE the bare-build fallthrough so a typo never silently rebuilds.
|
|
816
1012
|
// Bare invocation with NO flags still builds (handled in the final else).
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@raymondchins/agentmap",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"access": "public"
|
|
6
6
|
},
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
],
|
|
19
19
|
"scripts": {
|
|
20
20
|
"map": "node agentmap.mjs",
|
|
21
|
-
"test": "node --test test/*.test.mjs",
|
|
21
|
+
"test": "node --test test/*.test.mjs test/**/*.test.mjs",
|
|
22
22
|
"eval": "node eval/eval.mjs"
|
|
23
23
|
},
|
|
24
24
|
"engines": {
|