@spikedpunch/mast 0.2.0 → 0.4.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/MAST_SPEC.md +169 -44
- package/README.md +266 -20
- package/assets/prime.md +18 -0
- package/assets/signals.md +51 -0
- package/assets/skill.md +13 -15
- package/dist/ast/types.d.ts +137 -1
- package/dist/ast/types.d.ts.map +1 -1
- package/dist/cli/docs-cmd.d.ts +1 -0
- package/dist/cli/docs-cmd.d.ts.map +1 -1
- package/dist/cli/docs-cmd.js +2 -1
- package/dist/cli/docs-cmd.js.map +1 -1
- package/dist/cli/hook-cmd.d.ts +3 -0
- package/dist/cli/hook-cmd.d.ts.map +1 -0
- package/dist/cli/hook-cmd.js +13 -0
- package/dist/cli/hook-cmd.js.map +1 -0
- package/dist/cli/hook-state-dir.d.ts +24 -0
- package/dist/cli/hook-state-dir.d.ts.map +1 -0
- package/dist/cli/hook-state-dir.js +57 -0
- package/dist/cli/hook-state-dir.js.map +1 -0
- package/dist/cli/hook.d.ts +44 -0
- package/dist/cli/hook.d.ts.map +1 -0
- package/dist/cli/hook.js +200 -0
- package/dist/cli/hook.js.map +1 -0
- package/dist/cli/index.js +12 -2
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/installed-artifacts.d.ts +23 -0
- package/dist/cli/installed-artifacts.d.ts.map +1 -0
- package/dist/cli/installed-artifacts.js +39 -0
- package/dist/cli/installed-artifacts.js.map +1 -0
- package/dist/cli/prime-cmd.d.ts +17 -0
- package/dist/cli/prime-cmd.d.ts.map +1 -0
- package/dist/cli/prime-cmd.js +70 -0
- package/dist/cli/prime-cmd.js.map +1 -0
- package/dist/cli/program.d.ts.map +1 -1
- package/dist/cli/program.js +6 -0
- package/dist/cli/program.js.map +1 -1
- package/dist/cli/query.d.ts +40 -1
- package/dist/cli/query.d.ts.map +1 -1
- package/dist/cli/query.js +36 -2
- package/dist/cli/query.js.map +1 -1
- package/dist/cli/search-cmd.d.ts +6 -1
- package/dist/cli/search-cmd.d.ts.map +1 -1
- package/dist/cli/search-cmd.js +9 -2
- package/dist/cli/search-cmd.js.map +1 -1
- package/dist/cli/serve.d.ts +6 -1
- package/dist/cli/serve.d.ts.map +1 -1
- package/dist/cli/serve.js +14 -4
- package/dist/cli/serve.js.map +1 -1
- package/dist/cli/setup-cmd.d.ts +34 -0
- package/dist/cli/setup-cmd.d.ts.map +1 -0
- package/dist/cli/setup-cmd.js +205 -0
- package/dist/cli/setup-cmd.js.map +1 -0
- package/dist/cli/setup-command.d.ts +32 -0
- package/dist/cli/setup-command.d.ts.map +1 -0
- package/dist/cli/setup-command.js +43 -0
- package/dist/cli/setup-command.js.map +1 -0
- package/dist/cli/setup-plan.d.ts +52 -0
- package/dist/cli/setup-plan.d.ts.map +1 -0
- package/dist/cli/setup-plan.js +221 -0
- package/dist/cli/setup-plan.js.map +1 -0
- package/dist/cli/setup-rules.d.ts +41 -0
- package/dist/cli/setup-rules.d.ts.map +1 -0
- package/dist/cli/setup-rules.js +76 -0
- package/dist/cli/setup-rules.js.map +1 -0
- package/dist/cli/setup-static.d.ts +13 -0
- package/dist/cli/setup-static.d.ts.map +1 -0
- package/dist/cli/setup-static.js +116 -0
- package/dist/cli/setup-static.js.map +1 -0
- package/dist/cli/skill-install.d.ts +2 -0
- package/dist/cli/skill-install.d.ts.map +1 -1
- package/dist/cli/skill-install.js +2 -0
- package/dist/cli/skill-install.js.map +1 -1
- package/dist/cli/status.d.ts +15 -0
- package/dist/cli/status.d.ts.map +1 -1
- package/dist/cli/status.js +32 -6
- package/dist/cli/status.js.map +1 -1
- package/dist/cli/upgrade-cmd.d.ts +5 -1
- package/dist/cli/upgrade-cmd.d.ts.map +1 -1
- package/dist/cli/upgrade-cmd.js +28 -3
- package/dist/cli/upgrade-cmd.js.map +1 -1
- package/dist/indexer/freshness.d.ts +10 -0
- package/dist/indexer/freshness.d.ts.map +1 -1
- package/dist/indexer/freshness.js +7 -1
- package/dist/indexer/freshness.js.map +1 -1
- package/dist/indexer/import-resolver.js +28 -16
- package/dist/indexer/import-resolver.js.map +1 -1
- package/dist/indexer/index.d.ts +38 -3
- package/dist/indexer/index.d.ts.map +1 -1
- package/dist/indexer/index.js +47 -4
- package/dist/indexer/index.js.map +1 -1
- package/dist/indexer/watcher.d.ts +94 -0
- package/dist/indexer/watcher.d.ts.map +1 -1
- package/dist/indexer/watcher.js +172 -19
- package/dist/indexer/watcher.js.map +1 -1
- package/dist/mcp/context.d.ts +16 -0
- package/dist/mcp/context.d.ts.map +1 -1
- package/dist/mcp/freshness-probe.d.ts +82 -0
- package/dist/mcp/freshness-probe.d.ts.map +1 -0
- package/dist/mcp/freshness-probe.js +111 -0
- package/dist/mcp/freshness-probe.js.map +1 -0
- package/dist/mcp/instructions.d.ts +7 -0
- package/dist/mcp/instructions.d.ts.map +1 -0
- package/dist/mcp/instructions.js +10 -0
- package/dist/mcp/instructions.js.map +1 -0
- package/dist/mcp/server.d.ts +54 -3
- package/dist/mcp/server.d.ts.map +1 -1
- package/dist/mcp/server.js +79 -4
- package/dist/mcp/server.js.map +1 -1
- package/dist/mcp/tools/_helpers.d.ts +40 -0
- package/dist/mcp/tools/_helpers.d.ts.map +1 -1
- package/dist/mcp/tools/_helpers.js +27 -0
- package/dist/mcp/tools/_helpers.js.map +1 -1
- package/dist/mcp/tools/callers.d.ts.map +1 -1
- package/dist/mcp/tools/callers.js +6 -1
- package/dist/mcp/tools/callers.js.map +1 -1
- package/dist/mcp/tools/dependencies.d.ts.map +1 -1
- package/dist/mcp/tools/dependencies.js +2 -1
- package/dist/mcp/tools/dependencies.js.map +1 -1
- package/dist/mcp/tools/exports.d.ts.map +1 -1
- package/dist/mcp/tools/exports.js +2 -1
- package/dist/mcp/tools/exports.js.map +1 -1
- package/dist/mcp/tools/implementors.d.ts.map +1 -1
- package/dist/mcp/tools/implementors.js +2 -1
- package/dist/mcp/tools/implementors.js.map +1 -1
- package/dist/mcp/tools/project-skeleton.d.ts.map +1 -1
- package/dist/mcp/tools/project-skeleton.js +2 -1
- package/dist/mcp/tools/project-skeleton.js.map +1 -1
- package/dist/mcp/tools/reindex.d.ts.map +1 -1
- package/dist/mcp/tools/reindex.js +3 -0
- package/dist/mcp/tools/reindex.js.map +1 -1
- package/dist/mcp/tools/rename-impact.d.ts.map +1 -1
- package/dist/mcp/tools/rename-impact.js +4 -1
- package/dist/mcp/tools/rename-impact.js.map +1 -1
- package/dist/mcp/tools/search.d.ts.map +1 -1
- package/dist/mcp/tools/search.js +13 -2
- package/dist/mcp/tools/search.js.map +1 -1
- package/dist/mcp/tools/signature.d.ts.map +1 -1
- package/dist/mcp/tools/signature.js +2 -1
- package/dist/mcp/tools/signature.js.map +1 -1
- package/dist/mcp/tools/status.d.ts.map +1 -1
- package/dist/mcp/tools/status.js +8 -2
- package/dist/mcp/tools/status.js.map +1 -1
- package/dist/store/config.d.ts.map +1 -1
- package/dist/store/config.js +4 -5
- package/dist/store/config.js.map +1 -1
- package/dist/store/defaults.d.ts +9 -0
- package/dist/store/defaults.d.ts.map +1 -0
- package/dist/store/defaults.js +12 -0
- package/dist/store/defaults.js.map +1 -0
- package/package.json +5 -2
package/dist/cli/search-cmd.js
CHANGED
|
@@ -89,11 +89,16 @@ export function formatSearchResults(responseText) {
|
|
|
89
89
|
}
|
|
90
90
|
return lines.join('\n');
|
|
91
91
|
}
|
|
92
|
-
|
|
92
|
+
/**
|
|
93
|
+
* @param run Injected so the `--reindex` wiring can be tested without a real
|
|
94
|
+
* index (§4.4). Production passes {@link runQuery}.
|
|
95
|
+
*/
|
|
96
|
+
export function registerSearchCommand(program, run = runQuery) {
|
|
93
97
|
program
|
|
94
98
|
.command('search <query> [path]')
|
|
95
99
|
.description('Search the index and print readable results (see `mast query mast_search` for raw MCP output)')
|
|
96
100
|
.option('--state-dir <dir>', 'State directory')
|
|
101
|
+
.option('--reindex', 'Incrementally reindex before searching — the CLI has no watcher (see `mast serve`)')
|
|
97
102
|
.option('-n, --limit <n>', 'Max results (1-50, default 10)')
|
|
98
103
|
.option('-t, --type <kind>', 'Restrict to a chunk kind: function, method, class_shell, interface, type, export, block, doc')
|
|
99
104
|
.option('-l, --language <lang>', 'Restrict to typescript, javascript, or markdown')
|
|
@@ -102,7 +107,9 @@ export function registerSearchCommand(program) {
|
|
|
102
107
|
.option('--json', 'Emit the raw MCP response instead of text')
|
|
103
108
|
.action(async (query, path, opts) => {
|
|
104
109
|
try {
|
|
105
|
-
const text = await
|
|
110
|
+
const text = await run('mast_search', buildSearchArgs(query, opts), {
|
|
111
|
+
stateDir: opts.stateDir, path, reindex: opts.reindex === true,
|
|
112
|
+
});
|
|
106
113
|
process.stdout.write((opts.json === true ? text : formatSearchResults(text)) + '\n');
|
|
107
114
|
}
|
|
108
115
|
catch (err) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"search-cmd.js","sourceRoot":"","sources":["../../src/cli/search-cmd.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAuBlD,+FAA+F;AAC/F,MAAM,UAAU,eAAe,CAAC,KAAa,EAAE,KAAkB;IAC/D,MAAM,IAAI,GAA4B,EAAE,KAAK,EAAE,CAAC;IAChD,IAAI,KAAK,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;QAC9B,4EAA4E;QAC5E,kEAAkE;QAClE,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QAClC,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC;YAAE,MAAM,IAAI,UAAU,CAAC,wCAAwC,KAAK,CAAC,KAAK,GAAG,CAAC,CAAC;QAC3G,IAAI,CAAC,OAAO,CAAC,GAAG,KAAK,CAAC;IACxB,CAAC;IACD,IAAI,KAAK,CAAC,IAAI,KAAK,SAAS;QAAE,IAAI,CAAC,YAAY,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC;IAC9D,IAAI,KAAK,CAAC,QAAQ,KAAK,SAAS;QAAE,IAAI,CAAC,UAAU,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAC;IACpE,IAAI,KAAK,CAAC,QAAQ,KAAK,IAAI;QAAE,IAAI,CAAC,eAAe,CAAC,GAAG,IAAI,CAAC;IAC1D,IAAI,KAAK,CAAC,IAAI,KAAK,SAAS;QAAE,IAAI,CAAC,cAAc,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC;IAChE,OAAO,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;AAC9B,CAAC;AAqBD;;;;;;;GAOG;AACH,MAAM,UAAU,mBAAmB,CAAC,YAAoB;IACtD,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAYlC,CAAC;IACF,MAAM,KAAK,GAAa,EAAE,CAAC;IAE3B,mEAAmE;IACnE,mFAAmF;IACnF,kFAAkF;IAClF,2DAA2D;IAC3D,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,MAAM,CACrC,CAAC,CAAC,EAAE,EAAE,CAAC,8DAA8D,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,KAAK,IAAI,CACjG,CAAC;IACF,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC;QAAE,KAAK,CAAC,IAAI,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,kCAAkC,EAAE,EAAE,CAAC,CAAC;IAElG,MAAM,IAAI,GAAG,GAAG,CAAC,OAAO,IAAI,EAAE,CAAC;IAC/B,MAAM,SAAS,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,KAAK,IAAI,CAAC,CAAC,MAAM,CAAC;IAC9D,IAAI,SAAS,GAAG,CAAC,EAAE,CAAC;QAClB,KAAK,CAAC,IAAI,CACR,KAAK,MAAM,CAAC,SAAS,CAAC,OAAO,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,uDAAuD,EACvG,2EAA2E,EAC3E,EAAE,CACH,CAAC;IACJ,CAAC;IAED,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACtB,IAAI,GAAG,CAAC,WAAW,KAAK,IAAI,EAAE,CAAC;YAC7B,wEAAwE;YACxE,sEAAsE;YACtE,KAAK,CAAC,IAAI,CAAC,8EAA8E,CAAC,CAAC;YAC3F,KAAK,CAAC,IAAI,CAAC,yEAAyE,CAAC,CAAC;QACxF,CAAC;aAAM,CAAC;YACN,KAAK,CAAC,IAAI,CAAC,sEAAsE,CAAC,CAAC;YACnF,KAAK,CAAC,IAAI,CAAC,8EAA8E,CAAC,CAAC;QAC7F,CAAC;QACD,KAAK,MAAM,CAAC,IAAI,GAAG,CAAC,WAAW,IAAI,EAAE,EAAE,CAAC;YACtC,KAAK,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC,MAAM,IAAI,GAAG,GAAG,CAAC,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,SAAS,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QAC3G,CAAC;IACH,CAAC;SAAM,CAAC;QACN,KAAK,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC;YACrB,MAAM,KAAK,GAAG,GAAG,CAAC,CAAC,SAAS,IAAI,GAAG,IAAI,MAAM,CAAC,CAAC,CAAC,UAAU,IAAI,GAAG,CAAC,EAAE,CAAC;YACrE,MAAM,IAAI,GAAG,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,UAAU,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACtE,MAAM,KAAK,GAAG,CAAC,CAAC,CAAC,WAAW,KAAK,IAAI,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,KAAK,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC;iBAC1F,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAC9B,KAAK,CAAC,IAAI,CAAC,GAAG,KAAK,KAAK,IAAI,GAAG,KAAK,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,KAAK,EAAE,EAAE,CAAC,CAAC;YACnE,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC;gBAAE,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;YACtE,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACjB,CAAC;IACH,CAAC;IAED,MAAM,CAAC,GAAG,GAAG,CAAC,MAAM,CAAC;IACrB,MAAM,GAAG,GAAG,CAAC,EAAE,eAAe,CAAC;IAC/B,MAAM,KAAK,GAAG,CAAC,EAAE,4BAA4B,CAAC;IAC9C,iFAAiF;IACjF,gFAAgF;IAChF,wBAAwB;IACxB,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,IAAI,GAAG,KAAK,SAAS,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QAChE,4EAA4E;QAC5E,6EAA6E;QAC7E,6EAA6E;QAC7E,yEAAyE;QACzE,MAAM,KAAK,GAAG,KAAK,GAAG,GAAG,CAAC;QAC1B,MAAM,GAAG,GAAG,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,KAAK,GAAG,KAAK,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC9D,KAAK,CAAC,IAAI,CAAC,KAAK,IAAI,CAAC;YACnB,CAAC,CAAC,GAAG,MAAM,CAAC,GAAG,CAAC,uBAAuB,MAAM,CAAC,KAAK,CAAC,8BAA8B,MAAM,CAAC,GAAG,CAAC,SAAS;YACtG,CAAC,CAAC,GAAG,MAAM,CAAC,GAAG,CAAC,uBAAuB,MAAM,CAAC,KAAK,CAAC,8BAA8B,MAAM,CAAC,CAAC,GAAG,CAAC,8DAA8D,CAAC,CAAC;IAClK,CAAC;IACD,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC;AAED,MAAM,UAAU,qBAAqB,CAAC,OAAgB;
|
|
1
|
+
{"version":3,"file":"search-cmd.js","sourceRoot":"","sources":["../../src/cli/search-cmd.ts"],"names":[],"mappings":"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"}
|
package/dist/cli/serve.d.ts
CHANGED
|
@@ -1,3 +1,8 @@
|
|
|
1
1
|
import type { Command } from 'commander';
|
|
2
|
-
|
|
2
|
+
import { type ServeOptions } from '../mcp/server.js';
|
|
3
|
+
/**
|
|
4
|
+
* @param runServe Injected so the flag semantics below can be tested without
|
|
5
|
+
* standing up a real stdio MCP server (§4.4). Production passes `serve`.
|
|
6
|
+
*/
|
|
7
|
+
export declare function registerServeCommand(program: Command, runServe?: (options: ServeOptions) => Promise<void>): void;
|
|
3
8
|
//# sourceMappingURL=serve.d.ts.map
|
package/dist/cli/serve.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"serve.d.ts","sourceRoot":"","sources":["../../src/cli/serve.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"serve.d.ts","sourceRoot":"","sources":["../../src/cli/serve.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEzC,OAAO,EAAS,KAAK,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAE5D;;;GAGG;AACH,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,OAAO,EAChB,QAAQ,GAAE,CAAC,OAAO,EAAE,YAAY,KAAK,OAAO,CAAC,IAAI,CAAS,GACzD,IAAI,CAyBN"}
|
package/dist/cli/serve.js
CHANGED
|
@@ -1,18 +1,28 @@
|
|
|
1
1
|
import { resolveConfig } from '../store/config.js';
|
|
2
2
|
import { serve } from '../mcp/server.js';
|
|
3
|
-
|
|
3
|
+
/**
|
|
4
|
+
* @param runServe Injected so the flag semantics below can be tested without
|
|
5
|
+
* standing up a real stdio MCP server (§4.4). Production passes `serve`.
|
|
6
|
+
*/
|
|
7
|
+
export function registerServeCommand(program, runServe = serve) {
|
|
4
8
|
program
|
|
5
9
|
.command('serve')
|
|
6
10
|
.description('Start the MCP server over stdio')
|
|
7
11
|
.option('--state-dir <dir>', 'State directory')
|
|
8
12
|
.option('--no-startup-reindex', 'Skip the startup staleness check (not recommended)')
|
|
9
|
-
|
|
13
|
+
// Declaration order is load-bearing: commander gives a boolean pair its
|
|
14
|
+
// default from whichever half is declared FIRST, so `--no-watch` must come
|
|
15
|
+
// before `--watch` for the default to be true. `--watch` is kept because
|
|
16
|
+
// existing MCP client configs pass it explicitly; it is now a no-op that
|
|
17
|
+
// selects the default. Pinned by cli/__tests__/serve-options.test.ts.
|
|
18
|
+
.option('--no-watch', 'Do not watch source files; rely on the startup reindex and explicit mast_reindex calls')
|
|
19
|
+
.option('--watch', 'Watch source files and incrementally reindex on change (the default)')
|
|
10
20
|
.action(async (opts) => {
|
|
11
21
|
const config = resolveConfig({ stateDirOverride: opts.stateDir });
|
|
12
|
-
await
|
|
22
|
+
await runServe({
|
|
13
23
|
config,
|
|
14
24
|
noStartupReindex: !opts.startupReindex,
|
|
15
|
-
watch: opts.watch
|
|
25
|
+
watch: opts.watch,
|
|
16
26
|
});
|
|
17
27
|
});
|
|
18
28
|
}
|
package/dist/cli/serve.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"serve.js","sourceRoot":"","sources":["../../src/cli/serve.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,KAAK,
|
|
1
|
+
{"version":3,"file":"serve.js","sourceRoot":"","sources":["../../src/cli/serve.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,KAAK,EAAqB,MAAM,kBAAkB,CAAC;AAE5D;;;GAGG;AACH,MAAM,UAAU,oBAAoB,CAClC,OAAgB,EAChB,WAAqD,KAAK;IAE1D,OAAO;SACJ,OAAO,CAAC,OAAO,CAAC;SAChB,WAAW,CAAC,iCAAiC,CAAC;SAC9C,MAAM,CAAC,mBAAmB,EAAE,iBAAiB,CAAC;SAC9C,MAAM,CAAC,sBAAsB,EAAE,oDAAoD,CAAC;QACrF,wEAAwE;QACxE,2EAA2E;QAC3E,yEAAyE;QACzE,yEAAyE;QACzE,sEAAsE;SACrE,MAAM,CAAC,YAAY,EAAE,wFAAwF,CAAC;SAC9G,MAAM,CAAC,SAAS,EAAE,sEAAsE,CAAC;SACzF,MAAM,CAAC,KAAK,EAAE,IAId,EAAE,EAAE;QACH,MAAM,MAAM,GAAG,aAAa,CAAC,EAAE,gBAAgB,EAAE,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC;QAClE,MAAM,QAAQ,CAAC;YACb,MAAM;YACN,gBAAgB,EAAE,CAAC,IAAI,CAAC,cAAc;YACtC,KAAK,EAAE,IAAI,CAAC,KAAK;SAClB,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACP,CAAC"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type { Command } from 'commander';
|
|
2
|
+
import { type InstallKind } from './upgrade-cmd.js';
|
|
3
|
+
export interface SetupOptions {
|
|
4
|
+
readonly harness: string;
|
|
5
|
+
readonly projectRoot: string;
|
|
6
|
+
readonly global: boolean;
|
|
7
|
+
readonly check: boolean;
|
|
8
|
+
readonly remove: boolean;
|
|
9
|
+
readonly dryRun: boolean;
|
|
10
|
+
}
|
|
11
|
+
/** Everything about the machine `setup` reads, injected so tests never touch the real home. */
|
|
12
|
+
export interface SetupEnv {
|
|
13
|
+
readonly installKind: InstallKind;
|
|
14
|
+
readonly home: string;
|
|
15
|
+
readonly cliEntry: string;
|
|
16
|
+
/** The text of `assets/skill.md`, which every rules file is rendered from. */
|
|
17
|
+
readonly skillText: string;
|
|
18
|
+
}
|
|
19
|
+
export interface SetupIo {
|
|
20
|
+
/** Null when the file does not exist. Throws on any other failure. */
|
|
21
|
+
readFile(path: string): string | null;
|
|
22
|
+
/** Creates parent directories. Must never leave a half-written file at `path`. */
|
|
23
|
+
writeFileAtomic(path: string, content: string): void;
|
|
24
|
+
removeFile(path: string): void;
|
|
25
|
+
fileExists(path: string): boolean;
|
|
26
|
+
directoryExists(path: string): boolean;
|
|
27
|
+
out(line: string): void;
|
|
28
|
+
err(line: string): void;
|
|
29
|
+
}
|
|
30
|
+
/** Returns the process exit code: 0 done, 1 refused or failed, 2 usage error. */
|
|
31
|
+
export declare function runSetup(opts: SetupOptions, env: SetupEnv, io: SetupIo): number;
|
|
32
|
+
export declare function createNodeSetupIo(): SetupIo;
|
|
33
|
+
export declare function registerSetupCommand(program: Command): void;
|
|
34
|
+
//# sourceMappingURL=setup-cmd.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"setup-cmd.d.ts","sourceRoot":"","sources":["../../src/cli/setup-cmd.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAUzC,OAAO,EAAqB,KAAK,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAcvE,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IACzB,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;IACxB,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IACzB,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;CAC1B;AAED,+FAA+F;AAC/F,MAAM,WAAW,QAAQ;IACvB,QAAQ,CAAC,WAAW,EAAE,WAAW,CAAC;IAClC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,8EAA8E;IAC9E,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;CAC5B;AAED,MAAM,WAAW,OAAO;IACtB,sEAAsE;IACtE,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC;IACtC,kFAAkF;IAClF,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACrD,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;IAClC,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;IACvC,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;CACzB;AAyDD,iFAAiF;AACjF,wBAAgB,QAAQ,CAAC,IAAI,EAAE,YAAY,EAAE,GAAG,EAAE,QAAQ,EAAE,EAAE,EAAE,OAAO,GAAG,MAAM,CAoB/E;AAsED,wBAAgB,iBAAiB,IAAI,OAAO,CAoB3C;AAED,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAkB3D"}
|
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
import { chmodSync, existsSync, mkdirSync, readFileSync, realpathSync, renameSync, rmSync, statSync, writeFileSync } from 'node:fs';
|
|
2
|
+
import { homedir } from 'node:os';
|
|
3
|
+
import { basename, dirname, join, resolve } from 'node:path';
|
|
4
|
+
import { fileURLToPath } from 'node:url';
|
|
5
|
+
import { readDoc } from './docs-cmd.js';
|
|
6
|
+
import { buildHookCommand, hookFilePath } from './setup-command.js';
|
|
7
|
+
import { HOOK_DEFS, planFor } from './setup-plan.js';
|
|
8
|
+
import { runCursorRules, runStaticSetup, STATIC_HARNESSES } from './setup-static.js';
|
|
9
|
+
import { detectInstallKind } from './upgrade-cmd.js';
|
|
10
|
+
import { PACKAGE_NAME } from './version.js';
|
|
11
|
+
/**
|
|
12
|
+
* `mast setup <harness>` writes hook configuration and, for harnesses with a rules file
|
|
13
|
+
* mast can own (or Zed's, via a marked block), that file too. It follows the rules
|
|
14
|
+
* `skill-install.ts` states: touch nothing it does not own, and be a byte-level no-op on
|
|
15
|
+
* re-run. Unlike `skill --install` it creates its file when absent, because a hook file
|
|
16
|
+
* is tool configuration and not a hand-curated prompt (ADR 017 section 3).
|
|
17
|
+
*/
|
|
18
|
+
const HOOK_HARNESSES = ['claude', 'cursor', 'vscode'];
|
|
19
|
+
const ALL_HARNESSES = [...HOOK_HARNESSES, ...STATIC_HARNESSES];
|
|
20
|
+
/** Re-emits `value` in the file's own indentation, line endings and trailing-newline state. */
|
|
21
|
+
function serialize(value, previous) {
|
|
22
|
+
const indent = previous === null ? ' ' : (/^([ \t]+)\S/m.exec(previous)?.[1] ?? ' ');
|
|
23
|
+
const trailingNewline = previous === null || previous.endsWith('\n');
|
|
24
|
+
let text = JSON.stringify(value, null, indent) + (trailingNewline ? '\n' : '');
|
|
25
|
+
if (previous?.includes('\r\n'))
|
|
26
|
+
text = text.replace(/\n/g, '\r\n');
|
|
27
|
+
return text;
|
|
28
|
+
}
|
|
29
|
+
function parseJson(raw) {
|
|
30
|
+
try {
|
|
31
|
+
return { ok: true, value: JSON.parse(raw) };
|
|
32
|
+
}
|
|
33
|
+
catch (error) {
|
|
34
|
+
return { ok: false, problem: `not valid JSON (${error instanceof Error ? error.message : String(error)})` };
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
function buildCommands(harness, scope, env) {
|
|
38
|
+
const commands = {};
|
|
39
|
+
for (const def of HOOK_DEFS[harness]) {
|
|
40
|
+
const built = buildHookCommand({ harness, event: def.event, installKind: env.installKind, scope, cliEntry: env.cliEntry });
|
|
41
|
+
if (!built.ok)
|
|
42
|
+
return built;
|
|
43
|
+
commands[def.event] = built.command;
|
|
44
|
+
}
|
|
45
|
+
return { ok: true, commands };
|
|
46
|
+
}
|
|
47
|
+
function notesFor(harness, scope, env) {
|
|
48
|
+
const notes = [];
|
|
49
|
+
if (harness === 'vscode') {
|
|
50
|
+
notes.push('Only the session primer is installed for VS Code. A search reminder is not: VS Code ignores hook matchers, ' +
|
|
51
|
+
'so it would run on every tool call, and the name of its search tool is not documented.');
|
|
52
|
+
}
|
|
53
|
+
if (env.installKind === 'source') {
|
|
54
|
+
notes.push('The hook command contains a path specific to this machine; do not commit this file.');
|
|
55
|
+
}
|
|
56
|
+
if (env.installKind === 'local' && scope === 'project' && harness === 'vscode') {
|
|
57
|
+
notes.push('The relative command node_modules/.bin/mast is unverified in VS Code: its docs do not say what directory hooks run in.');
|
|
58
|
+
}
|
|
59
|
+
return notes;
|
|
60
|
+
}
|
|
61
|
+
function describePlan(plan, existed, remove) {
|
|
62
|
+
if (remove)
|
|
63
|
+
return plan.removedCount > 0 ? 'removed' : 'not installed';
|
|
64
|
+
if (!plan.changed)
|
|
65
|
+
return 'already up to date';
|
|
66
|
+
return !existed || plan.items.every((i) => i.state === 'missing') ? 'installed' : 'updated';
|
|
67
|
+
}
|
|
68
|
+
function reportProblem(io, path, problem) {
|
|
69
|
+
io.err(`mast setup: cannot update ${path}: ${problem}.`);
|
|
70
|
+
io.err('The file was left unchanged. Fix or delete it, then run the command again.');
|
|
71
|
+
}
|
|
72
|
+
/** Returns the process exit code: 0 done, 1 refused or failed, 2 usage error. */
|
|
73
|
+
export function runSetup(opts, env, io) {
|
|
74
|
+
const hookHarness = HOOK_HARNESSES.find((h) => h === opts.harness);
|
|
75
|
+
const staticHarness = STATIC_HARNESSES.find((h) => h === opts.harness);
|
|
76
|
+
if (hookHarness === undefined && staticHarness === undefined) {
|
|
77
|
+
io.err(`mast setup: unknown harness "${opts.harness}". Supported: ${ALL_HARNESSES.join(', ')}.`);
|
|
78
|
+
return 2;
|
|
79
|
+
}
|
|
80
|
+
if (opts.check && (opts.remove || opts.dryRun)) {
|
|
81
|
+
io.err('mast setup: --check cannot be combined with --remove or --dry-run.');
|
|
82
|
+
return 2;
|
|
83
|
+
}
|
|
84
|
+
if (staticHarness !== undefined)
|
|
85
|
+
return runStaticSetup(staticHarness, opts, env, io);
|
|
86
|
+
if (hookHarness === undefined)
|
|
87
|
+
return 2;
|
|
88
|
+
const hookCode = runHookSetup(hookHarness, opts, env, io);
|
|
89
|
+
if (hookHarness !== 'cursor')
|
|
90
|
+
return hookCode;
|
|
91
|
+
// A failed hooks step stops the rules step, except under --check, which reports both.
|
|
92
|
+
if (hookCode !== 0 && !opts.check)
|
|
93
|
+
return hookCode;
|
|
94
|
+
const rulesCode = runCursorRules(opts, env, io);
|
|
95
|
+
return hookCode !== 0 ? hookCode : rulesCode;
|
|
96
|
+
}
|
|
97
|
+
function runHookSetup(harness, opts, env, io) {
|
|
98
|
+
const scope = opts.global ? 'global' : 'project';
|
|
99
|
+
const path = hookFilePath(harness, scope, opts.projectRoot, env.home);
|
|
100
|
+
let mode = { kind: 'remove' };
|
|
101
|
+
if (!opts.remove) {
|
|
102
|
+
const built = buildCommands(harness, scope, env);
|
|
103
|
+
if (!built.ok) {
|
|
104
|
+
io.err(`mast setup: ${built.problem}`);
|
|
105
|
+
return 1;
|
|
106
|
+
}
|
|
107
|
+
if (env.installKind === 'local' && scope === 'project' && !io.fileExists(join(opts.projectRoot, 'node_modules', '.bin', 'mast'))) {
|
|
108
|
+
io.err(`mast setup: ${join(opts.projectRoot, 'node_modules', '.bin', 'mast')} does not exist, so the hook command would not run. Install mast in this project (pnpm add -D ${PACKAGE_NAME}) or install it globally.`);
|
|
109
|
+
return 1;
|
|
110
|
+
}
|
|
111
|
+
mode = { kind: 'install', commands: built.commands };
|
|
112
|
+
}
|
|
113
|
+
try {
|
|
114
|
+
const raw = io.readFile(path);
|
|
115
|
+
let existing = null;
|
|
116
|
+
if (raw !== null) {
|
|
117
|
+
const parsed = parseJson(raw);
|
|
118
|
+
if (!parsed.ok) {
|
|
119
|
+
reportProblem(io, path, parsed.problem);
|
|
120
|
+
return 1;
|
|
121
|
+
}
|
|
122
|
+
existing = parsed.value;
|
|
123
|
+
}
|
|
124
|
+
const plan = planFor(harness, existing, mode);
|
|
125
|
+
if (!plan.ok) {
|
|
126
|
+
reportProblem(io, path, plan.problem);
|
|
127
|
+
return 1;
|
|
128
|
+
}
|
|
129
|
+
if (opts.check) {
|
|
130
|
+
const stale = plan.items.filter((i) => i.state !== 'current');
|
|
131
|
+
if (stale.length === 0) {
|
|
132
|
+
io.out(`${path}: already up to date`);
|
|
133
|
+
return 0;
|
|
134
|
+
}
|
|
135
|
+
// A settings file that exists but holds none of mast's hooks is "not installed",
|
|
136
|
+
// the same as no file: "out of date" would send someone looking for a stale entry.
|
|
137
|
+
io.out(`${path}: ${stale.length === plan.items.length && stale.every((i) => i.state === 'missing') ? 'not installed' : 'out of date'}`);
|
|
138
|
+
for (const item of stale)
|
|
139
|
+
io.out(` ${item.state === 'missing' ? 'missing' : 'out of date'}: ${item.label}`);
|
|
140
|
+
return 1;
|
|
141
|
+
}
|
|
142
|
+
const status = describePlan(plan, raw !== null, opts.remove);
|
|
143
|
+
const willWrite = plan.changed;
|
|
144
|
+
if (opts.dryRun) {
|
|
145
|
+
io.out(`${path}: ${status} (dry run, nothing written)`);
|
|
146
|
+
if (willWrite)
|
|
147
|
+
io.out(plan.next === null ? '(the file would be deleted)' : serialize(plan.next, raw).trimEnd());
|
|
148
|
+
}
|
|
149
|
+
else {
|
|
150
|
+
if (willWrite) {
|
|
151
|
+
if (plan.next === null)
|
|
152
|
+
io.removeFile(path);
|
|
153
|
+
else
|
|
154
|
+
io.writeFileAtomic(path, serialize(plan.next, raw));
|
|
155
|
+
}
|
|
156
|
+
io.out(`${path}: ${status}`);
|
|
157
|
+
}
|
|
158
|
+
if (!opts.remove)
|
|
159
|
+
for (const note of notesFor(harness, scope, env))
|
|
160
|
+
io.out(`Note: ${note}`);
|
|
161
|
+
return 0;
|
|
162
|
+
}
|
|
163
|
+
catch (error) {
|
|
164
|
+
io.err(`mast setup: ${path}: ${error instanceof Error ? error.message : String(error)}`);
|
|
165
|
+
return 1;
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
export function createNodeSetupIo() {
|
|
169
|
+
return {
|
|
170
|
+
readFile: (path) => (existsSync(path) ? readFileSync(path, 'utf8') : null),
|
|
171
|
+
writeFileAtomic: (path, content) => {
|
|
172
|
+
// Resolve a symlinked settings file first, or the rename would replace the link
|
|
173
|
+
// (a dotfiles checkout, say) with a regular file.
|
|
174
|
+
const target = existsSync(path) ? realpathSync(path) : path;
|
|
175
|
+
mkdirSync(dirname(target), { recursive: true });
|
|
176
|
+
// Same directory, so the rename cannot cross a filesystem and stays atomic.
|
|
177
|
+
const temp = join(dirname(target), `.${basename(target)}.${process.pid}.tmp`);
|
|
178
|
+
writeFileSync(temp, content);
|
|
179
|
+
if (existsSync(target))
|
|
180
|
+
chmodSync(temp, statSync(target).mode & 0o777);
|
|
181
|
+
renameSync(temp, target);
|
|
182
|
+
},
|
|
183
|
+
removeFile: (path) => { rmSync(path); },
|
|
184
|
+
fileExists: existsSync,
|
|
185
|
+
directoryExists: (path) => existsSync(path) && statSync(path).isDirectory(),
|
|
186
|
+
out: (line) => { process.stdout.write(`${line}\n`); },
|
|
187
|
+
err: (line) => { process.stderr.write(`${line}\n`); },
|
|
188
|
+
};
|
|
189
|
+
}
|
|
190
|
+
export function registerSetupCommand(program) {
|
|
191
|
+
program
|
|
192
|
+
.command('setup <harness> [path]')
|
|
193
|
+
.description('Install the hooks and rules files that tell an agent to use mast (claude|cursor|vscode|windsurf|zed|desktop)')
|
|
194
|
+
.option('--global', 'Write the user-level file instead of the project one')
|
|
195
|
+
.option('--check', 'Write nothing; exit 0 only if everything is installed and current')
|
|
196
|
+
.option('--remove', 'Remove what mast installed')
|
|
197
|
+
.option('--dry-run', 'Print the file that would be written, and write nothing')
|
|
198
|
+
.action((harness, path, opts) => {
|
|
199
|
+
const projectRoot = resolve(path ?? '.');
|
|
200
|
+
const moduleDir = dirname(fileURLToPath(import.meta.url));
|
|
201
|
+
// The home directory is resolved here, at the edge, and nowhere below.
|
|
202
|
+
process.exitCode = runSetup({ harness, projectRoot, global: opts.global === true, check: opts.check === true, remove: opts.remove === true, dryRun: opts.dryRun === true }, { installKind: detectInstallKind(moduleDir, projectRoot), home: homedir(), cliEntry: join(moduleDir, 'index.js'), skillText: readDoc('skill') }, createNodeSetupIo());
|
|
203
|
+
});
|
|
204
|
+
}
|
|
205
|
+
//# sourceMappingURL=setup-cmd.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"setup-cmd.js","sourceRoot":"","sources":["../../src/cli/setup-cmd.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { Harness, HookEvent } from './hook.js';
|
|
2
|
+
import type { InstallKind } from './upgrade-cmd.js';
|
|
3
|
+
export type SetupScope = 'project' | 'global';
|
|
4
|
+
export interface HookCommandInput {
|
|
5
|
+
readonly harness: Harness;
|
|
6
|
+
readonly event: HookEvent;
|
|
7
|
+
readonly installKind: InstallKind;
|
|
8
|
+
readonly scope: SetupScope;
|
|
9
|
+
/** Absolute path of this build's `cli/index.js`; used only for a source checkout. */
|
|
10
|
+
readonly cliEntry: string;
|
|
11
|
+
}
|
|
12
|
+
export type HookCommandResult = {
|
|
13
|
+
readonly ok: true;
|
|
14
|
+
readonly command: string;
|
|
15
|
+
} | {
|
|
16
|
+
readonly ok: false;
|
|
17
|
+
readonly problem: string;
|
|
18
|
+
};
|
|
19
|
+
/** The hook file `setup` writes for a harness: project-level, or under the user's home. */
|
|
20
|
+
export declare function hookFilePath(harness: Harness, scope: SetupScope, projectRoot: string, home: string): string;
|
|
21
|
+
/**
|
|
22
|
+
* The command line a harness runs for one hook. Every spelling ends in
|
|
23
|
+
* ` hook <harness> <event>`: `setup` finds its own entries by that suffix, so the part
|
|
24
|
+
* before it can change between installs without orphaning the old entry.
|
|
25
|
+
*
|
|
26
|
+
* A project-dependency install cannot be written into user-level settings: the path
|
|
27
|
+
* points into one project's node_modules and fails in every other project.
|
|
28
|
+
*/
|
|
29
|
+
export declare function buildHookCommand(input: HookCommandInput): HookCommandResult;
|
|
30
|
+
/** True when `command` is the one `setup` installs for this harness and event, in any spelling. */
|
|
31
|
+
export declare function isMastCommand(command: string | undefined, harness: Harness, event: HookEvent): boolean;
|
|
32
|
+
//# sourceMappingURL=setup-command.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"setup-command.d.ts","sourceRoot":"","sources":["../../src/cli/setup-command.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAEpD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAEpD,MAAM,MAAM,UAAU,GAAG,SAAS,GAAG,QAAQ,CAAC;AAE9C,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,KAAK,EAAE,SAAS,CAAC;IAC1B,QAAQ,CAAC,WAAW,EAAE,WAAW,CAAC;IAClC,QAAQ,CAAC,KAAK,EAAE,UAAU,CAAC;IAC3B,qFAAqF;IACrF,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,MAAM,iBAAiB,GACzB;IAAE,QAAQ,CAAC,EAAE,EAAE,IAAI,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GAC/C;IAAE,QAAQ,CAAC,EAAE,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAErD,2FAA2F;AAC3F,wBAAgB,YAAY,CAAC,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAK3G;AAOD;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,gBAAgB,GAAG,iBAAiB,CAc3E;AAED,mGAAmG;AACnG,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,SAAS,GAAG,OAAO,CAEtG"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { join } from 'node:path';
|
|
2
|
+
/** The hook file `setup` writes for a harness: project-level, or under the user's home. */
|
|
3
|
+
export function hookFilePath(harness, scope, projectRoot, home) {
|
|
4
|
+
const base = scope === 'global' ? home : projectRoot;
|
|
5
|
+
if (harness === 'claude')
|
|
6
|
+
return join(base, '.claude', 'settings.json');
|
|
7
|
+
if (harness === 'cursor')
|
|
8
|
+
return join(base, '.cursor', 'hooks.json');
|
|
9
|
+
return scope === 'global' ? join(home, '.copilot', 'hooks', 'mast.json') : join(projectRoot, '.github', 'hooks', 'mast.json');
|
|
10
|
+
}
|
|
11
|
+
// Claude Code expands this variable itself when it runs a project hook, so the spelling
|
|
12
|
+
// holds wherever the project is checked out. A template literal would interpolate it.
|
|
13
|
+
const CLAUDE_LOCAL_BIN = '"$' + '{CLAUDE_PROJECT_DIR}"/node_modules/.bin/mast';
|
|
14
|
+
const RELATIVE_LOCAL_BIN = 'node_modules/.bin/mast';
|
|
15
|
+
/**
|
|
16
|
+
* The command line a harness runs for one hook. Every spelling ends in
|
|
17
|
+
* ` hook <harness> <event>`: `setup` finds its own entries by that suffix, so the part
|
|
18
|
+
* before it can change between installs without orphaning the old entry.
|
|
19
|
+
*
|
|
20
|
+
* A project-dependency install cannot be written into user-level settings: the path
|
|
21
|
+
* points into one project's node_modules and fails in every other project.
|
|
22
|
+
*/
|
|
23
|
+
export function buildHookCommand(input) {
|
|
24
|
+
const tail = ` hook ${input.harness} ${input.event}`;
|
|
25
|
+
if (input.installKind === 'global')
|
|
26
|
+
return { ok: true, command: `mast${tail}` };
|
|
27
|
+
if (input.installKind === 'source')
|
|
28
|
+
return { ok: true, command: `node "${input.cliEntry}"${tail}` };
|
|
29
|
+
if (input.scope === 'global') {
|
|
30
|
+
return {
|
|
31
|
+
ok: false,
|
|
32
|
+
problem: 'this mast is a project dependency, and a user-level hook that points into one project\'s node_modules ' +
|
|
33
|
+
'breaks in every other project. Install mast globally, or run without --global.',
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
const bin = input.harness === 'claude' ? CLAUDE_LOCAL_BIN : RELATIVE_LOCAL_BIN;
|
|
37
|
+
return { ok: true, command: `${bin}${tail}` };
|
|
38
|
+
}
|
|
39
|
+
/** True when `command` is the one `setup` installs for this harness and event, in any spelling. */
|
|
40
|
+
export function isMastCommand(command, harness, event) {
|
|
41
|
+
return command !== undefined && command.endsWith(` hook ${harness} ${event}`);
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=setup-command.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"setup-command.js","sourceRoot":"","sources":["../../src/cli/setup-command.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAkBjC,2FAA2F;AAC3F,MAAM,UAAU,YAAY,CAAC,OAAgB,EAAE,KAAiB,EAAE,WAAmB,EAAE,IAAY;IACjG,MAAM,IAAI,GAAG,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,WAAW,CAAC;IACrD,IAAI,OAAO,KAAK,QAAQ;QAAE,OAAO,IAAI,CAAC,IAAI,EAAE,SAAS,EAAE,eAAe,CAAC,CAAC;IACxE,IAAI,OAAO,KAAK,QAAQ;QAAE,OAAO,IAAI,CAAC,IAAI,EAAE,SAAS,EAAE,YAAY,CAAC,CAAC;IACrE,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,UAAU,EAAE,OAAO,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,EAAE,SAAS,EAAE,OAAO,EAAE,WAAW,CAAC,CAAC;AAChI,CAAC;AAED,wFAAwF;AACxF,sFAAsF;AACtF,MAAM,gBAAgB,GAAG,IAAI,GAAG,8CAA8C,CAAC;AAC/E,MAAM,kBAAkB,GAAG,wBAAwB,CAAC;AAEpD;;;;;;;GAOG;AACH,MAAM,UAAU,gBAAgB,CAAC,KAAuB;IACtD,MAAM,IAAI,GAAG,SAAS,KAAK,CAAC,OAAO,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;IACrD,IAAI,KAAK,CAAC,WAAW,KAAK,QAAQ;QAAE,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,IAAI,EAAE,EAAE,CAAC;IAChF,IAAI,KAAK,CAAC,WAAW,KAAK,QAAQ;QAAE,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,SAAS,KAAK,CAAC,QAAQ,IAAI,IAAI,EAAE,EAAE,CAAC;IACpG,IAAI,KAAK,CAAC,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC7B,OAAO;YACL,EAAE,EAAE,KAAK;YACT,OAAO,EACL,wGAAwG;gBACxG,gFAAgF;SACnF,CAAC;IACJ,CAAC;IACD,MAAM,GAAG,GAAG,KAAK,CAAC,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,kBAAkB,CAAC;IAC/E,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,GAAG,GAAG,IAAI,EAAE,EAAE,CAAC;AAChD,CAAC;AAED,mGAAmG;AACnG,MAAM,UAAU,aAAa,CAAC,OAA2B,EAAE,OAAgB,EAAE,KAAgB;IAC3F,OAAO,OAAO,KAAK,SAAS,IAAI,OAAO,CAAC,QAAQ,CAAC,SAAS,OAAO,IAAI,KAAK,EAAE,CAAC,CAAC;AAChF,CAAC"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import type { Harness, HookEvent } from './hook.js';
|
|
2
|
+
interface HookDef {
|
|
3
|
+
readonly event: HookEvent;
|
|
4
|
+
/** The harness's own name for the event, which is also the key in its hooks object. */
|
|
5
|
+
readonly nativeEvent: string;
|
|
6
|
+
readonly matcher?: string;
|
|
7
|
+
readonly timeout: number;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* The hooks each harness gets. The Claude session-start group has no matcher on purpose:
|
|
11
|
+
* that matches every source, including `compact`. VS Code has no search hook because its
|
|
12
|
+
* docs say matchers are ignored (it would run on every tool call) and the search tool's
|
|
13
|
+
* name is undocumented.
|
|
14
|
+
*/
|
|
15
|
+
export declare const HOOK_DEFS: Readonly<Record<Harness, readonly HookDef[]>>;
|
|
16
|
+
export type Commands = Readonly<Partial<Record<HookEvent, string>>>;
|
|
17
|
+
export type PlanMode = {
|
|
18
|
+
readonly kind: 'install';
|
|
19
|
+
readonly commands: Commands;
|
|
20
|
+
} | {
|
|
21
|
+
readonly kind: 'remove';
|
|
22
|
+
};
|
|
23
|
+
export type ItemState = 'missing' | 'outdated' | 'current';
|
|
24
|
+
export interface PlanItem {
|
|
25
|
+
readonly label: string;
|
|
26
|
+
readonly state: ItemState;
|
|
27
|
+
}
|
|
28
|
+
export type PlanResult = {
|
|
29
|
+
readonly ok: true;
|
|
30
|
+
/** The whole file's next value, or null when the file should be deleted. */
|
|
31
|
+
readonly next: object | null;
|
|
32
|
+
/** False means the file must not be written at all. */
|
|
33
|
+
readonly changed: boolean;
|
|
34
|
+
/** Install mode: the state of each hook found. */
|
|
35
|
+
readonly items: readonly PlanItem[];
|
|
36
|
+
/** Remove mode: how many of mast's entries were taken out. */
|
|
37
|
+
readonly removedCount: number;
|
|
38
|
+
} | {
|
|
39
|
+
readonly ok: false;
|
|
40
|
+
readonly problem: string;
|
|
41
|
+
};
|
|
42
|
+
/**
|
|
43
|
+
* Claude Code: `hooks.<Event>` is a list of groups, each `{matcher?, hooks: [handler]}`.
|
|
44
|
+
* Within a group only mast's handler is touched; a group mast empties is removed, a group
|
|
45
|
+
* with other handlers keeps them.
|
|
46
|
+
*/
|
|
47
|
+
export declare function planClaude(existing: unknown, mode: PlanMode): PlanResult;
|
|
48
|
+
export declare const planCursor: (existing: unknown, mode: PlanMode) => PlanResult;
|
|
49
|
+
export declare const planVscode: (existing: unknown, mode: PlanMode) => PlanResult;
|
|
50
|
+
export declare function planFor(harness: Harness, existing: unknown, mode: PlanMode): PlanResult;
|
|
51
|
+
export {};
|
|
52
|
+
//# sourceMappingURL=setup-plan.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"setup-plan.d.ts","sourceRoot":"","sources":["../../src/cli/setup-plan.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAOpD,UAAU,OAAO;IACf,QAAQ,CAAC,KAAK,EAAE,SAAS,CAAC;IAC1B,uFAAuF;IACvF,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AAED;;;;;GAKG;AACH,eAAO,MAAM,SAAS,EAAE,QAAQ,CAAC,MAAM,CAAC,OAAO,EAAE,SAAS,OAAO,EAAE,CAAC,CAUnE,CAAC;AAEF,MAAM,MAAM,QAAQ,GAAG,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC;AACpE,MAAM,MAAM,QAAQ,GAChB;IAAE,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IAAC,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAA;CAAE,GACzD;IAAE,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAA;CAAE,CAAC;AAEhC,MAAM,MAAM,SAAS,GAAG,SAAS,GAAG,UAAU,GAAG,SAAS,CAAC;AAC3D,MAAM,WAAW,QAAQ;IACvB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,KAAK,EAAE,SAAS,CAAC;CAC3B;AAED,MAAM,MAAM,UAAU,GAClB;IACE,QAAQ,CAAC,EAAE,EAAE,IAAI,CAAC;IAClB,4EAA4E;IAC5E,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,uDAAuD;IACvD,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,kDAAkD;IAClD,QAAQ,CAAC,KAAK,EAAE,SAAS,QAAQ,EAAE,CAAC;IACpC,8DAA8D;IAC9D,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;CAC/B,GACD;IAAE,QAAQ,CAAC,EAAE,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AA2CrD;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,GAAG,UAAU,CA6ExE;AA2ED,eAAO,MAAM,UAAU,GAAI,UAAU,OAAO,EAAE,MAAM,QAAQ,KAAG,UAAgD,CAAC;AAChH,eAAO,MAAM,UAAU,GAAI,UAAU,OAAO,EAAE,MAAM,QAAQ,KAAG,UAAgD,CAAC;AAEhH,wBAAgB,OAAO,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,GAAG,UAAU,CAGvF"}
|