@smeltjs/core 0.1.0 → 0.2.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/README.md +2 -2
- package/dist/cli/args.d.ts +12 -1
- package/dist/cli/args.d.ts.map +1 -1
- package/dist/cli/args.js +61 -0
- package/dist/cli/args.js.map +1 -1
- package/dist/cli/config.d.ts +22 -0
- package/dist/cli/config.d.ts.map +1 -1
- package/dist/cli/config.js +32 -1
- package/dist/cli/config.js.map +1 -1
- package/dist/cli/hooks.d.ts +153 -0
- package/dist/cli/hooks.d.ts.map +1 -0
- package/dist/cli/hooks.js +1180 -0
- package/dist/cli/hooks.js.map +1 -0
- package/dist/cli/init.d.ts +3 -1
- package/dist/cli/init.d.ts.map +1 -1
- package/dist/cli/init.js +6 -0
- package/dist/cli/init.js.map +1 -1
- package/dist/cli/run.d.ts +1 -1
- package/dist/cli/run.d.ts.map +1 -1
- package/dist/cli/run.js +19 -0
- package/dist/cli/run.js.map +1 -1
- package/dist/hooks/guard-core.d.ts +164 -0
- package/dist/hooks/guard-core.d.ts.map +1 -0
- package/dist/hooks/guard-core.js +513 -0
- package/dist/hooks/guard-core.js.map +1 -0
- package/dist/hooks/shim.d.ts +85 -0
- package/dist/hooks/shim.d.ts.map +1 -0
- package/dist/hooks/shim.js +107 -0
- package/dist/hooks/shim.js.map +1 -0
- package/dist/hooks/shims/claude-code.d.ts +23 -0
- package/dist/hooks/shims/claude-code.d.ts.map +1 -0
- package/dist/hooks/shims/claude-code.js +61 -0
- package/dist/hooks/shims/claude-code.js.map +1 -0
- package/dist/hooks/shims/cline.d.ts +17 -0
- package/dist/hooks/shims/cline.d.ts.map +1 -0
- package/dist/hooks/shims/cline.js +39 -0
- package/dist/hooks/shims/cline.js.map +1 -0
- package/dist/hooks/shims/codex.d.ts +23 -0
- package/dist/hooks/shims/codex.d.ts.map +1 -0
- package/dist/hooks/shims/codex.js +56 -0
- package/dist/hooks/shims/codex.js.map +1 -0
- package/dist/hooks/shims/cursor.d.ts +19 -0
- package/dist/hooks/shims/cursor.d.ts.map +1 -0
- package/dist/hooks/shims/cursor.js +47 -0
- package/dist/hooks/shims/cursor.js.map +1 -0
- package/dist/hooks/shims/gemini.d.ts +23 -0
- package/dist/hooks/shims/gemini.d.ts.map +1 -0
- package/dist/hooks/shims/gemini.js +53 -0
- package/dist/hooks/shims/gemini.js.map +1 -0
- package/dist/hooks/shims/grok.d.ts +18 -0
- package/dist/hooks/shims/grok.d.ts.map +1 -0
- package/dist/hooks/shims/grok.js +37 -0
- package/dist/hooks/shims/grok.js.map +1 -0
- package/dist/hooks/shims/hermes.d.ts +22 -0
- package/dist/hooks/shims/hermes.d.ts.map +1 -0
- package/dist/hooks/shims/hermes.js +50 -0
- package/dist/hooks/shims/hermes.js.map +1 -0
- package/dist/net/policy.d.ts.map +1 -1
- package/dist/net/policy.js +1 -0
- package/dist/net/policy.js.map +1 -1
- package/package.json +12 -4
package/README.md
CHANGED
|
@@ -4,7 +4,7 @@ Structure-aware, reversible context optimization for coding agents. Zero network
|
|
|
4
4
|
|
|
5
5
|
This is the library package. The project README, the four laws and their reasoning, the
|
|
6
6
|
build plan and the consumer contract all live in the repository root:
|
|
7
|
-
**https://github.com/
|
|
7
|
+
**https://github.com/smeltjs/smelt**
|
|
8
8
|
|
|
9
9
|
```ts
|
|
10
10
|
import { createSmelter } from '@smeltjs/core';
|
|
@@ -50,6 +50,6 @@ signatures and doc comments always kept), the lexical planner, a persistent
|
|
|
50
50
|
content-addressed store, cache-prefix hygiene (detect, never rewrite), a repo-map
|
|
51
51
|
planner modelled on Aider's, the `smelt init` wizard, and a committed measurement
|
|
52
52
|
harness. An unsupported language under `strategy: 'structural'` is refused, never
|
|
53
|
-
approximated. See [`docs/HANDOFF.md`](https://github.com/
|
|
53
|
+
approximated. See [`docs/HANDOFF.md`](https://github.com/smeltjs/smelt/blob/main/docs/HANDOFF.md).
|
|
54
54
|
|
|
55
55
|
Apache-2.0.
|
package/dist/cli/args.d.ts
CHANGED
|
@@ -53,8 +53,19 @@ export interface StatsInvocation {
|
|
|
53
53
|
readonly mode: 'stats';
|
|
54
54
|
readonly json: boolean;
|
|
55
55
|
}
|
|
56
|
+
/**
|
|
57
|
+
* `smelt hooks install` / `smelt hooks remove` — the harness-hooks installer. Like
|
|
58
|
+
* `init`, the subcommand is interactive; the only flag is `--harness`, which skips
|
|
59
|
+
* the selection step. Validation of the id happens in `cli/hooks.ts`, where the
|
|
60
|
+
* harness registry lives.
|
|
61
|
+
*/
|
|
62
|
+
export interface HooksInvocation {
|
|
63
|
+
readonly mode: 'hooks';
|
|
64
|
+
readonly action: 'install' | 'remove';
|
|
65
|
+
readonly harness?: string;
|
|
66
|
+
}
|
|
56
67
|
/** Everything `parseSmeltArgs` can return. Narrow on `mode`. */
|
|
57
|
-
export type CliInvocation = SmeltInvocation | MapInvocation | RetrieveInvocation | StatsInvocation;
|
|
68
|
+
export type CliInvocation = SmeltInvocation | MapInvocation | RetrieveInvocation | StatsInvocation | HooksInvocation;
|
|
58
69
|
/**
|
|
59
70
|
* Argument parsing on `node:util.parseArgs` — stable since Node 20, which `engines`
|
|
60
71
|
* already requires.
|
package/dist/cli/args.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"args.d.ts","sourceRoot":"","sources":["../../src/cli/args.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAEpD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAEpD,gEAAgE;AAChE,eAAO,MAAM,QAAQ,UAAU,CAAC;AAEhC,oFAAoF;AACpF,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,IAAI,EAAE,OAAO,GAAG,aAAa,GAAG,MAAM,GAAG,SAAS,GAAG,MAAM,CAAC;IACrE,6CAA6C;IAC7C,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB;;;OAGG;IACH,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;IAClC,QAAQ,CAAC,QAAQ,CAAC,EAAE,gBAAgB,CAAC;IACrC,+EAA+E;IAC/E,QAAQ,CAAC,QAAQ,CAAC,EAAE,QAAQ,CAAC;IAC7B,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;CACxB;AAED;;;;;GAKG;AACH,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,IAAI,EAAE,KAAK,CAAC;IACrB,+FAA+F;IAC/F,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,+EAA+E;IAC/E,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;IAClC,8EAA8E;IAC9E,QAAQ,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC;IACnC,mEAAmE;IACnE,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;CACxB;AAED;;;;;GAKG;AACH,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC;IAC1B,mFAAmF;IACnF,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AAED,wEAAwE;AACxE,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IACvB,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;CACxB;AAED,gEAAgE;AAChE,MAAM,MAAM,aAAa,
|
|
1
|
+
{"version":3,"file":"args.d.ts","sourceRoot":"","sources":["../../src/cli/args.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAEpD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAEpD,gEAAgE;AAChE,eAAO,MAAM,QAAQ,UAAU,CAAC;AAEhC,oFAAoF;AACpF,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,IAAI,EAAE,OAAO,GAAG,aAAa,GAAG,MAAM,GAAG,SAAS,GAAG,MAAM,CAAC;IACrE,6CAA6C;IAC7C,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB;;;OAGG;IACH,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;IAClC,QAAQ,CAAC,QAAQ,CAAC,EAAE,gBAAgB,CAAC;IACrC,+EAA+E;IAC/E,QAAQ,CAAC,QAAQ,CAAC,EAAE,QAAQ,CAAC;IAC7B,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;CACxB;AAED;;;;;GAKG;AACH,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,IAAI,EAAE,KAAK,CAAC;IACrB,+FAA+F;IAC/F,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,+EAA+E;IAC/E,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;IAClC,8EAA8E;IAC9E,QAAQ,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC;IACnC,mEAAmE;IACnE,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;CACxB;AAED;;;;;GAKG;AACH,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC;IAC1B,mFAAmF;IACnF,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AAED,wEAAwE;AACxE,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IACvB,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;CACxB;AAED;;;;;GAKG;AACH,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IACvB,QAAQ,CAAC,MAAM,EAAE,SAAS,GAAG,QAAQ,CAAC;IACtC,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED,gEAAgE;AAChE,MAAM,MAAM,aAAa,GACvB,eAAe,GAAG,aAAa,GAAG,kBAAkB,GAAG,eAAe,GAAG,eAAe,CAAC;AAE3F;;;;;;;;;GASG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG,aAAa,CAqHrE;AAsMD,0EAA0E;AAC1E,wBAAgB,QAAQ,IAAI,MAAM,CAmHjC"}
|
package/dist/cli/args.js
CHANGED
|
@@ -29,6 +29,7 @@ export function parseSmeltArgs(argv) {
|
|
|
29
29
|
strategy: { type: 'string' },
|
|
30
30
|
ignore: { type: 'string', multiple: true },
|
|
31
31
|
cache: { type: 'string' },
|
|
32
|
+
harness: { type: 'string' },
|
|
32
33
|
json: { type: 'boolean' },
|
|
33
34
|
reconstruct: { type: 'boolean' },
|
|
34
35
|
help: { type: 'boolean', short: 'h' },
|
|
@@ -69,12 +70,19 @@ export function parseSmeltArgs(argv) {
|
|
|
69
70
|
if (positionals[0] === 'stats') {
|
|
70
71
|
return parseStatsArgs(values, positionals);
|
|
71
72
|
}
|
|
73
|
+
if (positionals[0] === 'hooks') {
|
|
74
|
+
return parseHooksArgs(values, positionals);
|
|
75
|
+
}
|
|
72
76
|
// These two belong to `smelt map` alone; silently ignoring a flag the user typed
|
|
73
77
|
// would be a setting they believed was in force.
|
|
74
78
|
if (values.ignore !== undefined || values.cache !== undefined) {
|
|
75
79
|
throw new CliUsageError(`${CLI_NAME}: --ignore and --cache belong to \`${CLI_NAME} map\`. A single-blob ` +
|
|
76
80
|
`run reads one file or stdin; there is no tree to walk and nothing to cache.`);
|
|
77
81
|
}
|
|
82
|
+
if (values.harness !== undefined) {
|
|
83
|
+
throw new CliUsageError(`${CLI_NAME}: --harness belongs to \`${CLI_NAME} hooks\`. A single-blob run ` +
|
|
84
|
+
`has no harness to install into.`);
|
|
85
|
+
}
|
|
78
86
|
if (positionals.length > 1) {
|
|
79
87
|
throw new CliUsageError(`${CLI_NAME}: expected at most one file, got ${String(positionals.length)} ` +
|
|
80
88
|
`(${positionals.join(', ')}). smelt reads one blob at a time.`);
|
|
@@ -127,6 +135,10 @@ function parseMapArgs(values, positionals) {
|
|
|
127
135
|
`whole tree, detects each file's language itself, and is not a planner ` +
|
|
128
136
|
`strategy — it returns a map, not an elision plan.`);
|
|
129
137
|
}
|
|
138
|
+
if (values.harness !== undefined) {
|
|
139
|
+
throw new CliUsageError(`${CLI_NAME}: --harness belongs to \`${CLI_NAME} hooks\`. map has no harness ` +
|
|
140
|
+
`to install into.`);
|
|
141
|
+
}
|
|
130
142
|
const budgetBytes = parseBudget(values.budget);
|
|
131
143
|
return {
|
|
132
144
|
mode: 'map',
|
|
@@ -173,6 +185,34 @@ function parseStatsArgs(values, positionals) {
|
|
|
173
185
|
}
|
|
174
186
|
return { mode: 'stats', json: values['json'] === true };
|
|
175
187
|
}
|
|
188
|
+
/**
|
|
189
|
+
* `hooks` takes an action and at most `--harness`. It is interactive like `init` —
|
|
190
|
+
* the wizard asks everything else — so every other flag is refused rather than
|
|
191
|
+
* ignored.
|
|
192
|
+
*/
|
|
193
|
+
function parseHooksArgs(values, positionals) {
|
|
194
|
+
const action = positionals[1];
|
|
195
|
+
if (action !== 'install' && action !== 'remove') {
|
|
196
|
+
throw new CliUsageError(`${CLI_NAME}: hooks needs an action — install or remove.\n` +
|
|
197
|
+
` ${CLI_NAME} hooks install [--harness <id>]\n` +
|
|
198
|
+
` ${CLI_NAME} hooks remove [--harness <id>]`);
|
|
199
|
+
}
|
|
200
|
+
if (positionals.length > 2) {
|
|
201
|
+
throw new CliUsageError(`${CLI_NAME}: hooks ${action} takes no further arguments, got ` +
|
|
202
|
+
`${positionals.slice(2).join(', ')}.`);
|
|
203
|
+
}
|
|
204
|
+
const flags = Object.entries(values).filter(([name, value]) => value !== undefined && name !== 'harness');
|
|
205
|
+
if (flags.length > 0) {
|
|
206
|
+
throw new CliUsageError(`${CLI_NAME}: hooks takes only --harness ` +
|
|
207
|
+
`(got --${flags.map(([name]) => name).join(', --')}). The wizard asks the rest.`);
|
|
208
|
+
}
|
|
209
|
+
const harness = values['harness'];
|
|
210
|
+
return {
|
|
211
|
+
mode: 'hooks',
|
|
212
|
+
action,
|
|
213
|
+
...(typeof harness === 'string' ? { harness } : {}),
|
|
214
|
+
};
|
|
215
|
+
}
|
|
176
216
|
/**
|
|
177
217
|
* `--budget` has no built-in default, for the same reason `smelt()` has none: a budget
|
|
178
218
|
* smelt invented would be smelt deciding how much of the caller's context to throw
|
|
@@ -219,6 +259,8 @@ USAGE
|
|
|
219
259
|
${CLI_NAME} map <dir> --budget <bytes> [--focus <term>]... [--ignore <entry>]... [--cache <dir>]
|
|
220
260
|
${CLI_NAME} retrieve <hash>
|
|
221
261
|
${CLI_NAME} stats [--json]
|
|
262
|
+
${CLI_NAME} hooks install [--harness <id>]
|
|
263
|
+
${CLI_NAME} hooks remove [--harness <id>]
|
|
222
264
|
${CLI_NAME} --reconstruct <result.json>
|
|
223
265
|
${CLI_NAME} --reconstruct < result.json
|
|
224
266
|
${CLI_NAME} init
|
|
@@ -266,6 +308,22 @@ RETRIEVE & STATS
|
|
|
266
308
|
is nothing to retrieve across runs, and that is a usage error rather than a
|
|
267
309
|
quiet empty answer.
|
|
268
310
|
|
|
311
|
+
HOOKS
|
|
312
|
+
${CLI_NAME} hooks install wires the smelt guard into agent-harness hooks: a
|
|
313
|
+
PreToolUse size-guard that refuses oversized raw reads with the exact ${CLI_NAME}
|
|
314
|
+
replacement command (default on), \`${CLI_NAME} stats\` at session end (default
|
|
315
|
+
on), and an opening \`${CLI_NAME} map\` at session start (opt-in) — plus an
|
|
316
|
+
instruction-file snippet that teaches \`${CLI_NAME} retrieve\` after a deny.
|
|
317
|
+
Harnesses are tiered honestly: verified (Claude Code, Codex), experimental
|
|
318
|
+
(Gemini, Grok, Hermes, Cursor, opencode, Cline — schemas from the capability
|
|
319
|
+
matrix, not yet smoke-tested), advisory (KiloCode, Aider — instructions only,
|
|
320
|
+
nothing enforced). Same discipline as init: every file listed before a final
|
|
321
|
+
confirm, no existing file overwritten without a per-file yes, re-runs edit
|
|
322
|
+
toggles. ${CLI_NAME} hooks remove takes it back out. Guard settings live in
|
|
323
|
+
smelt.config.json ("hooks": {"thresholdBytes", "enforcement": "deny"|"rewrite"});
|
|
324
|
+
deny is the default — rewrite substitutes commands in-flight only where a
|
|
325
|
+
harness supports it, and never silently.
|
|
326
|
+
|
|
269
327
|
OPTIONS
|
|
270
328
|
--budget <bytes> Required, unless smelt.config.json sets defaultBudgetBytes.
|
|
271
329
|
Soft ceiling for the output, in UTF-8 bytes (for map: a hard
|
|
@@ -285,6 +343,9 @@ OPTIONS
|
|
|
285
343
|
an entry containing / is a root-relative prefix.
|
|
286
344
|
--cache <dir> map only. Directory for the tags cache, keyed by content
|
|
287
345
|
hash. Only when given does the map write to disk at all.
|
|
346
|
+
--harness <id> hooks only. Skip harness detection and target one id:
|
|
347
|
+
claude-code, codex, gemini, grok, hermes, cursor, opencode,
|
|
348
|
+
cline, kilocode, aider.
|
|
288
349
|
--json Print a JSON envelope on stdout instead of the text:
|
|
289
350
|
{ format, result, elided } for a smelt run — \`result\` is
|
|
290
351
|
the SmeltResult verbatim, \`elided\` carries the bytes, so
|
package/dist/cli/args.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"args.js","sourceRoot":"","sources":["../../src/cli/args.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAEtC,OAAO,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AACnD,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC7C,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAE7D,OAAO,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAG7D,gEAAgE;AAChE,MAAM,CAAC,MAAM,QAAQ,GAAG,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"args.js","sourceRoot":"","sources":["../../src/cli/args.ts"],"names":[],"mappings":"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"}
|
package/dist/cli/config.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { EnforcementMode } from '../hooks/guard-core.ts';
|
|
1
2
|
import type { Strategy } from '../plan/planners.ts';
|
|
2
3
|
/**
|
|
3
4
|
* `smelt.config.json` — CLI defaults, and nothing more.
|
|
@@ -27,6 +28,25 @@ export type SmeltConfigStore = {
|
|
|
27
28
|
/** Resolved relative to the directory holding the config file, not the cwd. */
|
|
28
29
|
readonly path: string;
|
|
29
30
|
};
|
|
31
|
+
/**
|
|
32
|
+
* The `hooks` block — settings for the harness guard (`smelt hooks install`).
|
|
33
|
+
*
|
|
34
|
+
* Parsed strictly here, like every other key: the CLI refuses a malformed config.
|
|
35
|
+
* The guard core (`src/hooks/guard-core.ts`) reads the same file with its own
|
|
36
|
+
* *tolerant* reader — a guard running inside somebody's session fails open where the
|
|
37
|
+
* CLI correctly refuses — and `test/hooks-guard-core.test.ts` pins the two readers to
|
|
38
|
+
* the same key names and defaults so they cannot drift apart.
|
|
39
|
+
*/
|
|
40
|
+
export interface SmeltConfigHooks {
|
|
41
|
+
/** Reads at or under this many bytes pass the guard untouched. Default 8192. */
|
|
42
|
+
readonly thresholdBytes?: number;
|
|
43
|
+
/**
|
|
44
|
+
* `'deny'` (default): oversized raw reads are refused with a reason naming the
|
|
45
|
+
* exact replacement command. `'rewrite'`: on harnesses whose hooks can modify tool
|
|
46
|
+
* input, the command is substituted instead (never silently — the reason says so).
|
|
47
|
+
*/
|
|
48
|
+
readonly enforcement?: EnforcementMode;
|
|
49
|
+
}
|
|
30
50
|
/** The parsed shape of `smelt.config.json`. Every field beyond the version is optional. */
|
|
31
51
|
export interface SmeltConfig {
|
|
32
52
|
readonly smeltConfig: typeof CONFIG_VERSION;
|
|
@@ -36,6 +56,8 @@ export interface SmeltConfig {
|
|
|
36
56
|
readonly strategy?: Strategy;
|
|
37
57
|
/** Used for every run; there is no store flag. Defaults to memory when absent. */
|
|
38
58
|
readonly store?: SmeltConfigStore;
|
|
59
|
+
/** Settings for the harness guard. See {@link SmeltConfigHooks}. */
|
|
60
|
+
readonly hooks?: SmeltConfigHooks;
|
|
39
61
|
}
|
|
40
62
|
/** A config plus where it was found — the path matters for resolving `store.path`. */
|
|
41
63
|
export interface LoadedConfig {
|
package/dist/cli/config.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/cli/config.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAIpD;;;;;;;;;;;;;;;GAeG;AAEH,mEAAmE;AACnE,eAAO,MAAM,gBAAgB,sBAAsB,CAAC;AAEpD,sDAAsD;AACtD,eAAO,MAAM,cAAc,IAAI,CAAC;AAEhC,wDAAwD;AACxD,MAAM,MAAM,gBAAgB,GACxB;IAAE,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAA;CAAE,GAC3B;IACE,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAC;IAC3B,+EAA+E;IAC/E,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB,CAAC;AAEN,2FAA2F;AAC3F,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,WAAW,EAAE,OAAO,cAAc,CAAC;IAC5C,sFAAsF;IACtF,QAAQ,CAAC,kBAAkB,CAAC,EAAE,MAAM,CAAC;IACrC,2FAA2F;IAC3F,QAAQ,CAAC,QAAQ,CAAC,EAAE,QAAQ,CAAC;IAC7B,kFAAkF;IAClF,QAAQ,CAAC,KAAK,CAAC,EAAE,gBAAgB,CAAC;CACnC;AAED,sFAAsF;AACtF,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC;CAC9B;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAS9D;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,YAAY,GAAG,SAAS,CAIvE;AAED;;;;;;;;;GASG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,WAAW,
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/cli/config.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAE9D,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAIpD;;;;;;;;;;;;;;;GAeG;AAEH,mEAAmE;AACnE,eAAO,MAAM,gBAAgB,sBAAsB,CAAC;AAEpD,sDAAsD;AACtD,eAAO,MAAM,cAAc,IAAI,CAAC;AAEhC,wDAAwD;AACxD,MAAM,MAAM,gBAAgB,GACxB;IAAE,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAA;CAAE,GAC3B;IACE,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAC;IAC3B,+EAA+E;IAC/E,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB,CAAC;AAEN;;;;;;;;GAQG;AACH,MAAM,WAAW,gBAAgB;IAC/B,gFAAgF;IAChF,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;IACjC;;;;OAIG;IACH,QAAQ,CAAC,WAAW,CAAC,EAAE,eAAe,CAAC;CACxC;AAED,2FAA2F;AAC3F,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,WAAW,EAAE,OAAO,cAAc,CAAC;IAC5C,sFAAsF;IACtF,QAAQ,CAAC,kBAAkB,CAAC,EAAE,MAAM,CAAC;IACrC,2FAA2F;IAC3F,QAAQ,CAAC,QAAQ,CAAC,EAAE,QAAQ,CAAC;IAC7B,kFAAkF;IAClF,QAAQ,CAAC,KAAK,CAAC,EAAE,gBAAgB,CAAC;IAClC,oEAAoE;IACpE,QAAQ,CAAC,KAAK,CAAC,EAAE,gBAAgB,CAAC;CACnC;AAED,sFAAsF;AACtF,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC;CAC9B;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAS9D;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,YAAY,GAAG,SAAS,CAIvE;AAED;;;;;;;;;GASG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,WAAW,CA+DnE;AAsED,qFAAqF;AACrF,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,YAAY,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAE3E"}
|
package/dist/cli/config.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { existsSync, readFileSync } from 'node:fs';
|
|
2
2
|
import { dirname, join, resolve } from 'node:path';
|
|
3
3
|
import { CliUsageError } from '../errors.js';
|
|
4
|
+
import { ENFORCEMENT_MODES } from '../hooks/guard-core.js';
|
|
4
5
|
import { isStrategy, STRATEGIES } from '../plan/planners.js';
|
|
5
6
|
import { CLI_NAME } from './args.js';
|
|
6
7
|
/**
|
|
@@ -84,7 +85,7 @@ export function parseConfig(text, path) {
|
|
|
84
85
|
`${String(CONFIG_VERSION)}. The schema is versioned so a mismatch is visible ` +
|
|
85
86
|
`instead of half-understood.`);
|
|
86
87
|
}
|
|
87
|
-
const known = ['smeltConfig', 'defaultBudgetBytes', 'strategy', 'store'];
|
|
88
|
+
const known = ['smeltConfig', 'defaultBudgetBytes', 'strategy', 'store', 'hooks'];
|
|
88
89
|
const unknown = Object.keys(fields).filter((key) => !known.includes(key));
|
|
89
90
|
if (unknown.length > 0) {
|
|
90
91
|
throw bad(`unknown key${unknown.length === 1 ? '' : 's'} ${unknown.map((k) => `"${k}"`).join(', ')}. ` +
|
|
@@ -104,11 +105,13 @@ export function parseConfig(text, path) {
|
|
|
104
105
|
`got ${JSON.stringify(strategy)}.`);
|
|
105
106
|
}
|
|
106
107
|
const store = parseStore(fields['store'], bad);
|
|
108
|
+
const hooks = parseHooks(fields['hooks'], bad);
|
|
107
109
|
return {
|
|
108
110
|
smeltConfig: CONFIG_VERSION,
|
|
109
111
|
...(budget === undefined ? {} : { defaultBudgetBytes: budget }),
|
|
110
112
|
...(strategy === undefined ? {} : { strategy }),
|
|
111
113
|
...(store === undefined ? {} : { store }),
|
|
114
|
+
...(hooks === undefined ? {} : { hooks }),
|
|
112
115
|
};
|
|
113
116
|
}
|
|
114
117
|
function parseStore(value, bad) {
|
|
@@ -137,6 +140,34 @@ function parseStore(value, bad) {
|
|
|
137
140
|
}
|
|
138
141
|
throw bad(`"store".kind must be "memory" or "directory", got ${JSON.stringify(kind)}.`);
|
|
139
142
|
}
|
|
143
|
+
function parseHooks(value, bad) {
|
|
144
|
+
if (value === undefined)
|
|
145
|
+
return undefined;
|
|
146
|
+
if (typeof value !== 'object' || value === null || Array.isArray(value)) {
|
|
147
|
+
throw bad(`"hooks" must be an object like {"thresholdBytes":8192,"enforcement":"deny"}.`);
|
|
148
|
+
}
|
|
149
|
+
const fields = value;
|
|
150
|
+
const extra = Object.keys(fields).filter((key) => key !== 'thresholdBytes' && key !== 'enforcement');
|
|
151
|
+
if (extra.length > 0) {
|
|
152
|
+
throw bad(`"hooks" takes only "thresholdBytes" and "enforcement", ` +
|
|
153
|
+
`got ${extra.map((k) => `"${k}"`).join(', ')}.`);
|
|
154
|
+
}
|
|
155
|
+
const threshold = fields['thresholdBytes'];
|
|
156
|
+
if (threshold !== undefined &&
|
|
157
|
+
(typeof threshold !== 'number' || !Number.isInteger(threshold) || threshold <= 0)) {
|
|
158
|
+
throw bad(`"hooks".thresholdBytes must be a whole number of bytes greater than zero.`);
|
|
159
|
+
}
|
|
160
|
+
const enforcement = fields['enforcement'];
|
|
161
|
+
if (enforcement !== undefined &&
|
|
162
|
+
!ENFORCEMENT_MODES.includes(enforcement)) {
|
|
163
|
+
throw bad(`"hooks".enforcement must be ${ENFORCEMENT_MODES.map((m) => `"${m}"`).join(' or ')}, ` +
|
|
164
|
+
`got ${JSON.stringify(enforcement)}.`);
|
|
165
|
+
}
|
|
166
|
+
return {
|
|
167
|
+
...(threshold === undefined ? {} : { thresholdBytes: threshold }),
|
|
168
|
+
...(enforcement === undefined ? {} : { enforcement: enforcement }),
|
|
169
|
+
};
|
|
170
|
+
}
|
|
140
171
|
/** `store.path` is relative to the config file, so the config works from any cwd. */
|
|
141
172
|
export function resolveStorePath(loaded, path) {
|
|
142
173
|
return resolve(dirname(loaded.path), path);
|
package/dist/cli/config.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/cli/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEnD,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC7C,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAG7D,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAErC;;;;;;;;;;;;;;;GAeG;AAEH,mEAAmE;AACnE,MAAM,CAAC,MAAM,gBAAgB,GAAG,mBAAmB,CAAC;AAEpD,sDAAsD;AACtD,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/cli/config.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
import type { EnforcementMode } from '../hooks/guard-core.ts';
|
|
2
|
+
import type { SmeltConfig, SmeltConfigHooks } from './config.ts';
|
|
3
|
+
/**
|
|
4
|
+
* `smelt hooks install` / `smelt hooks remove` — the multi-harness guard preset.
|
|
5
|
+
*
|
|
6
|
+
* The design (KOT-212, founder rulings 2026-09-02): one zero-dependency guard core
|
|
7
|
+
* (`src/hooks/guard-core.ts`), thin per-harness shims mapping each harness's native
|
|
8
|
+
* hook schema onto it, and this installer, which writes the harness config that wires
|
|
9
|
+
* a shim in — plus an instruction-file snippet as belt and braces, because the
|
|
10
|
+
* snippet is also what teaches the model to run `smelt retrieve` after a deny.
|
|
11
|
+
*
|
|
12
|
+
* Harnesses come in three honesty tiers (docs/research/2026-09-02-harness-capability-matrix.md):
|
|
13
|
+
*
|
|
14
|
+
* - **verified** — Claude Code, Codex: schemas verified against primary docs and
|
|
15
|
+
* exercised against recorded fixtures; first-class targets.
|
|
16
|
+
* - **experimental** — Gemini, Grok, Hermes, Cursor, opencode, Cline: hook schemas
|
|
17
|
+
* mapped from the capability matrix but not yet smoke-tested green against the
|
|
18
|
+
* real binary. Labelled as such in code, docs, and this installer's output.
|
|
19
|
+
* - **advisory** — KiloCode, Aider: no usable hook API, so what ships is
|
|
20
|
+
* instructions (and, for KiloCode, a permissions/MCP sketch). Nothing enforces
|
|
21
|
+
* them, and the output says so rather than implying a guard exists.
|
|
22
|
+
*
|
|
23
|
+
* The wizard discipline is `smelt init`'s, verbatim: every step accepts `back`,
|
|
24
|
+
* nothing is written until a final confirm that lists every file, and an existing
|
|
25
|
+
* file is never overwritten without an explicit per-file `yes` — guarded by
|
|
26
|
+
* `test/guards/hooks-preset.test.ts`, with mutation `hooks-install-overwrite-without-consent`
|
|
27
|
+
* proving the guard goes red.
|
|
28
|
+
*/
|
|
29
|
+
/** Where the wizard's bytes come from and go. Injected so `runHooks` tests in-process. */
|
|
30
|
+
export interface HooksIo {
|
|
31
|
+
readonly input: NodeJS.ReadableStream;
|
|
32
|
+
readonly output: (text: string) => void;
|
|
33
|
+
/** Project directory: detection, config discovery, and every write are relative to it. */
|
|
34
|
+
readonly cwd: string;
|
|
35
|
+
/** Home directory for detection only. Tests point it at a temp dir; nothing writes here. */
|
|
36
|
+
readonly home?: string;
|
|
37
|
+
}
|
|
38
|
+
export type HarnessTier = 'verified' | 'experimental' | 'advisory';
|
|
39
|
+
export type HarnessId = 'claude-code' | 'codex' | 'gemini' | 'grok' | 'hermes' | 'cursor' | 'opencode' | 'cline' | 'kilocode' | 'aider';
|
|
40
|
+
export interface HarnessSpec {
|
|
41
|
+
readonly id: HarnessId;
|
|
42
|
+
readonly name: string;
|
|
43
|
+
readonly tier: HarnessTier;
|
|
44
|
+
/** Paths (relative to the project) whose existence means "this harness is in use here". */
|
|
45
|
+
readonly detect: readonly string[];
|
|
46
|
+
/** Paths relative to the user's home directory — "installed on this machine". */
|
|
47
|
+
readonly detectHome: readonly string[];
|
|
48
|
+
/** The standing-instructions file this harness reads (capability matrix column d). */
|
|
49
|
+
readonly instructionFile: string;
|
|
50
|
+
/** Caveats carried from the capability matrix, shown at install time. */
|
|
51
|
+
readonly caveats: readonly string[];
|
|
52
|
+
}
|
|
53
|
+
/** One line of honesty per tier, shown wherever a tier label appears. */
|
|
54
|
+
export declare const TIER_HONESTY: Record<HarnessTier, string>;
|
|
55
|
+
export declare const HARNESSES: readonly HarnessSpec[];
|
|
56
|
+
export declare function harnessById(id: string): HarnessSpec | undefined;
|
|
57
|
+
/** A harness whose config directory exists in the project or the home directory. */
|
|
58
|
+
export declare function detectedHarnesses(cwd: string, home: string): readonly HarnessSpec[];
|
|
59
|
+
/** Marker lines bracketing every block this installer owns inside a shared file. */
|
|
60
|
+
export declare const SNIPPET_START_MD = "<!-- smelt:hooks v1 start -->";
|
|
61
|
+
export declare const SNIPPET_END_MD = "<!-- smelt:hooks v1 end -->";
|
|
62
|
+
/**
|
|
63
|
+
* The instruction snippet — belt and braces under every shim, and the *only* layer
|
|
64
|
+
* for advisory harnesses. It teaches the three commands, and in particular what to do
|
|
65
|
+
* after a guard deny: run the named replacement, then `smelt retrieve` per marker.
|
|
66
|
+
*/
|
|
67
|
+
export declare function instructionSnippet(thresholdBytes: number, budgetBytes: number): string;
|
|
68
|
+
/**
|
|
69
|
+
* Merge our hook entries into a JSON settings file, preserving everything foreign
|
|
70
|
+
* **byte-faithfully**: the merged `hooks` value is spliced into the original text, so
|
|
71
|
+
* unknown top-level keys, string escapes, number spellings, indentation and key order
|
|
72
|
+
* outside the `hooks` property ride through verbatim (founder ruling: an installer
|
|
73
|
+
* that reformats somebody's settings file has edited what it was never asked to).
|
|
74
|
+
* Inside `hooks`, unmanaged events and other people's entries under managed events
|
|
75
|
+
* are preserved; our previous entries are replaced (that is what makes a re-run edit
|
|
76
|
+
* toggles), and events left with no entries disappear. A semantic no-op returns the
|
|
77
|
+
* input text unchanged. Returns `undefined` when the existing file is not a JSON
|
|
78
|
+
* object — the caller skips the file rather than clobbering something it cannot
|
|
79
|
+
* understand.
|
|
80
|
+
*/
|
|
81
|
+
export declare function mergeJsonHooks(existingText: string | undefined, events: Record<string, readonly unknown[]>, shape?: {
|
|
82
|
+
readonly version?: number;
|
|
83
|
+
}): string | undefined;
|
|
84
|
+
/** Replace this installer's marker block in `existingText`, or append it. */
|
|
85
|
+
export declare function upsertMarkerBlock(existingText: string | undefined, block: string, start: string, end: string): string;
|
|
86
|
+
/** Remove the marker block. `undefined` when nothing (or only whitespace) remains. */
|
|
87
|
+
export declare function stripMarkerBlock(existingText: string, start: string, end: string): string | undefined;
|
|
88
|
+
interface PlannedFile {
|
|
89
|
+
/** Display path, relative to the project. */
|
|
90
|
+
readonly name: string;
|
|
91
|
+
readonly path: string;
|
|
92
|
+
readonly content: string;
|
|
93
|
+
readonly exists: boolean;
|
|
94
|
+
readonly unchanged: boolean;
|
|
95
|
+
/** chmod after writing (the cline hook must be executable). */
|
|
96
|
+
readonly mode?: number;
|
|
97
|
+
}
|
|
98
|
+
interface SkippedFile {
|
|
99
|
+
readonly name: string;
|
|
100
|
+
readonly why: string;
|
|
101
|
+
}
|
|
102
|
+
interface PlannedRemoval {
|
|
103
|
+
readonly name: string;
|
|
104
|
+
readonly path: string;
|
|
105
|
+
/** `'delete'` removes the file; `'modify'` writes `content` (ours stripped out). */
|
|
106
|
+
readonly action: 'delete' | 'modify';
|
|
107
|
+
readonly content?: string;
|
|
108
|
+
}
|
|
109
|
+
export interface HooksChoices {
|
|
110
|
+
harnesses: HarnessSpec[];
|
|
111
|
+
guard: boolean;
|
|
112
|
+
statsOnStop: boolean;
|
|
113
|
+
mapOnStart: boolean;
|
|
114
|
+
enforcement: EnforcementMode;
|
|
115
|
+
thresholdBytes: number;
|
|
116
|
+
}
|
|
117
|
+
interface InstallPlan {
|
|
118
|
+
readonly files: readonly PlannedFile[];
|
|
119
|
+
readonly skipped: readonly SkippedFile[];
|
|
120
|
+
readonly notes: readonly string[];
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Every file `install` would write, computed against the current disk state — pure
|
|
124
|
+
* planning, nothing written. Shared instruction files (several harnesses read
|
|
125
|
+
* AGENTS.md) are planned once.
|
|
126
|
+
*
|
|
127
|
+
* @throws {CliUsageError} when an existing `smelt.config.json` is malformed — the
|
|
128
|
+
* same refusal every other subcommand makes; an installer that guessed around a
|
|
129
|
+
* broken config would write settings the guard then ignores.
|
|
130
|
+
*/
|
|
131
|
+
export declare function planInstall(cwd: string, choices: HooksChoices): InstallPlan;
|
|
132
|
+
/** Where the installed config points the persistent store, relative to the config file. */
|
|
133
|
+
export declare const DEFAULT_STORE_DIR = ".smelt/store";
|
|
134
|
+
/**
|
|
135
|
+
* Existing config re-rendered with the hooks block, other fields carried verbatim —
|
|
136
|
+
* except that a config with **no** store block gains a directory store. The deny
|
|
137
|
+
* reasons and the instruction snippet teach `smelt retrieve <hash>`, and retrieval
|
|
138
|
+
* across processes needs a persistent store (`smelt retrieve` refuses a memory
|
|
139
|
+
* store, exit 2) — an install whose own guard promises a command the installed
|
|
140
|
+
* config cannot run would be the exact silent-failure shape this project refuses.
|
|
141
|
+
* An *explicit* `{"kind":"memory"}` is respected; the guard then conditions its
|
|
142
|
+
* retrieve promise on the store kind instead (`retrieveSentence` in guard-core).
|
|
143
|
+
*/
|
|
144
|
+
export declare function renderConfigWithHooks(existing: SmeltConfig | undefined, hooks: SmeltConfigHooks): string;
|
|
145
|
+
/** Everything `remove` would delete or strip, computed against the current disk state. */
|
|
146
|
+
export declare function planRemove(cwd: string, harnesses: readonly HarnessSpec[]): readonly PlannedRemoval[];
|
|
147
|
+
/**
|
|
148
|
+
* `smelt hooks <install|remove>`, start to finish. The same testability pattern as
|
|
149
|
+
* `runInit`: a pure function over an input/output pair, exit code returned.
|
|
150
|
+
*/
|
|
151
|
+
export declare function runHooks(action: 'install' | 'remove', harnessFlag: string | undefined, io: HooksIo): Promise<number>;
|
|
152
|
+
export {};
|
|
153
|
+
//# sourceMappingURL=hooks.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hooks.d.ts","sourceRoot":"","sources":["../../src/cli/hooks.ts"],"names":[],"mappings":"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"}
|