@namzu/cli 11.0.0 → 12.0.1
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 +390 -46
- package/dist/cli.d.ts +15 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +132 -4
- package/dist/cli.js.map +1 -1
- package/dist/commands/acp.d.ts +29 -0
- package/dist/commands/acp.d.ts.map +1 -0
- package/dist/commands/acp.js +156 -0
- package/dist/commands/acp.js.map +1 -0
- package/dist/commands/doctor.d.ts +12 -1
- package/dist/commands/doctor.d.ts.map +1 -1
- package/dist/commands/doctor.js +18 -2
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/drain.d.ts +2 -2
- package/dist/commands/drain.d.ts.map +1 -1
- package/dist/commands/drain.js +31 -8
- package/dist/commands/drain.js.map +1 -1
- package/dist/commands/run-flags.d.ts.map +1 -1
- package/dist/commands/run-flags.js +33 -0
- package/dist/commands/run-flags.js.map +1 -1
- package/dist/commands/run-stream.d.ts +3 -3
- package/dist/commands/run-stream.d.ts.map +1 -1
- package/dist/commands/run-stream.js +27 -10
- package/dist/commands/run-stream.js.map +1 -1
- package/dist/commands/run.d.ts.map +1 -1
- package/dist/commands/run.js +50 -4
- package/dist/commands/run.js.map +1 -1
- package/dist/commands/types.d.ts +10 -0
- package/dist/commands/types.d.ts.map +1 -1
- package/dist/config/load.d.ts +64 -0
- package/dist/config/load.d.ts.map +1 -1
- package/dist/config/load.js +137 -20
- package/dist/config/load.js.map +1 -1
- package/dist/config/schema.d.ts +51 -0
- package/dist/config/schema.d.ts.map +1 -1
- package/dist/config/schema.js.map +1 -1
- package/dist/context/capabilities.d.ts +88 -0
- package/dist/context/capabilities.d.ts.map +1 -0
- package/dist/context/capabilities.js +160 -0
- package/dist/context/capabilities.js.map +1 -0
- package/dist/context/sandbox.d.ts +13 -0
- package/dist/context/sandbox.d.ts.map +1 -1
- package/dist/context/sandbox.js +15 -0
- package/dist/context/sandbox.js.map +1 -1
- package/dist/doctor/checks/index.d.ts +6 -1
- package/dist/doctor/checks/index.d.ts.map +1 -1
- package/dist/doctor/checks/index.js +45 -2
- package/dist/doctor/checks/index.js.map +1 -1
- package/dist/doctor/checks/invariants.d.ts +23 -0
- package/dist/doctor/checks/invariants.d.ts.map +1 -0
- package/dist/doctor/checks/invariants.js +79 -0
- package/dist/doctor/checks/invariants.js.map +1 -0
- package/dist/doctor/checks/logging.d.ts +10 -0
- package/dist/doctor/checks/logging.d.ts.map +1 -0
- package/dist/doctor/checks/logging.js +69 -0
- package/dist/doctor/checks/logging.js.map +1 -0
- package/dist/doctor/checks/session-export.d.ts +21 -0
- package/dist/doctor/checks/session-export.d.ts.map +1 -0
- package/dist/doctor/checks/session-export.js +62 -0
- package/dist/doctor/checks/session-export.js.map +1 -0
- package/dist/doctor/checks/telemetry.d.ts +15 -28
- package/dist/doctor/checks/telemetry.d.ts.map +1 -1
- package/dist/doctor/checks/telemetry.js +34 -54
- package/dist/doctor/checks/telemetry.js.map +1 -1
- package/dist/doctor/checks/vault.d.ts +4 -20
- package/dist/doctor/checks/vault.d.ts.map +1 -1
- package/dist/doctor/checks/vault.js +58 -19
- package/dist/doctor/checks/vault.js.map +1 -1
- package/dist/doctor/registry.d.ts.map +1 -1
- package/dist/doctor/registry.js +13 -6
- package/dist/doctor/registry.js.map +1 -1
- package/dist/index.d.ts +3 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -2
- package/dist/index.js.map +1 -1
- package/dist/integrations/files/attachment-store.d.ts +44 -0
- package/dist/integrations/files/attachment-store.d.ts.map +1 -0
- package/dist/integrations/files/attachment-store.js +86 -0
- package/dist/integrations/files/attachment-store.js.map +1 -0
- package/dist/integrations/providers/credential-provider.d.ts +39 -0
- package/dist/integrations/providers/credential-provider.d.ts.map +1 -0
- package/dist/integrations/providers/credential-provider.js +74 -0
- package/dist/integrations/providers/credential-provider.js.map +1 -0
- package/dist/integrations/providers/discover.d.ts.map +1 -1
- package/dist/integrations/providers/discover.js +15 -3
- package/dist/integrations/providers/discover.js.map +1 -1
- package/dist/integrations/providers/oauth.d.ts.map +1 -1
- package/dist/integrations/providers/oauth.js +24 -1
- package/dist/integrations/providers/oauth.js.map +1 -1
- package/dist/integrations/sessions/store.d.ts +2 -2
- package/dist/integrations/sessions/store.d.ts.map +1 -1
- package/dist/integrations/sessions/store.js +21 -9
- package/dist/integrations/sessions/store.js.map +1 -1
- package/dist/integrations/subagents/runtime.d.ts +3 -3
- package/dist/integrations/subagents/runtime.d.ts.map +1 -1
- package/dist/integrations/subagents/runtime.js +12 -12
- package/dist/integrations/subagents/runtime.js.map +1 -1
- package/dist/integrations/telemetry/session-export.d.ts +99 -0
- package/dist/integrations/telemetry/session-export.d.ts.map +1 -0
- package/dist/integrations/telemetry/session-export.js +119 -0
- package/dist/integrations/telemetry/session-export.js.map +1 -0
- package/dist/logging.d.ts +79 -0
- package/dist/logging.d.ts.map +1 -0
- package/dist/logging.js +67 -0
- package/dist/logging.js.map +1 -0
- package/dist/permissions/rules.d.ts +3 -3
- package/dist/permissions/rules.d.ts.map +1 -1
- package/dist/permissions/rules.js +1 -1
- package/dist/permissions/rules.js.map +1 -1
- package/dist/skills/store.d.ts +1 -1
- package/dist/skills/store.js +1 -1
- package/dist/tui/App.d.ts.map +1 -1
- package/dist/tui/App.js +92 -6
- package/dist/tui/App.js.map +1 -1
- package/dist/tui/StatusBar.d.ts +1 -1
- package/dist/tui/StatusBar.d.ts.map +1 -1
- package/dist/tui/agent.d.ts +54 -24
- package/dist/tui/agent.d.ts.map +1 -1
- package/dist/tui/agent.js +330 -127
- package/dist/tui/agent.js.map +1 -1
- package/dist/tui/index.d.ts.map +1 -1
- package/dist/tui/index.js +17 -6
- package/dist/tui/index.js.map +1 -1
- package/dist/tui/log-pane.d.ts +48 -0
- package/dist/tui/log-pane.d.ts.map +1 -0
- package/dist/tui/log-pane.js +106 -0
- package/dist/tui/log-pane.js.map +1 -0
- package/dist/tui/slashCommands.d.ts +134 -11
- package/dist/tui/slashCommands.d.ts.map +1 -1
- package/dist/tui/slashCommands.js +169 -15
- package/dist/tui/slashCommands.js.map +1 -1
- package/dist/tui/types.d.ts +11 -2
- package/dist/tui/types.d.ts.map +1 -1
- package/package.json +8 -6
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Log level + format resolution for the CLI's five entry points that used
|
|
3
|
+
* to force the SDK logger's level to `silent` via `configureLogger` and
|
|
4
|
+
* never turn it back on: `tui/index.tsx`, `commands/run.ts`,
|
|
5
|
+
* `commands/drain.ts` and `commands/run-stream.ts` (twice — `run-stream`
|
|
6
|
+
* itself and `providers-json`). LOG-05.
|
|
7
|
+
*
|
|
8
|
+
* Kept out of `config/load.ts`'s cascade on purpose. That system merges
|
|
9
|
+
* four sources for `format`/`quiet`/`permissions`/`sandbox`, all of them
|
|
10
|
+
* either boolean or a closed enum with a config-file counterpart.
|
|
11
|
+
* `NAMZU_LOG_LEVEL` has no config-file counterpart in this increment and is
|
|
12
|
+
* not boolean-shaped — it names a level directly, string-valued, the same
|
|
13
|
+
* way `--verbose`/`--quiet` do. Precedence here is exactly what the design
|
|
14
|
+
* specifies and nothing more: an explicit flag beats the environment beats
|
|
15
|
+
* the default that used to be silence.
|
|
16
|
+
*/
|
|
17
|
+
import type { LevelFilter, LogSink } from '@namzu/sdk';
|
|
18
|
+
export type LogFormat = 'pretty' | 'json';
|
|
19
|
+
/** What every entry point installs as its process sink, resolved once per
|
|
20
|
+
* invocation in `cli.ts#getContext()` and threaded through
|
|
21
|
+
* `CommandContext`/`TuiContext`. */
|
|
22
|
+
export interface ResolvedLogging {
|
|
23
|
+
readonly level: LevelFilter;
|
|
24
|
+
readonly format: LogFormat;
|
|
25
|
+
}
|
|
26
|
+
export interface LogLevelFlags {
|
|
27
|
+
/** `-v, --verbose` as Commander parsed it — `undefined` unless given. */
|
|
28
|
+
readonly verbose?: boolean;
|
|
29
|
+
/**
|
|
30
|
+
* `-q, --quiet` as Commander parsed it — `undefined` unless given.
|
|
31
|
+
* Reuses the CLI's existing global flag rather than minting a second
|
|
32
|
+
* "quiet" that means something different depending which one you typed.
|
|
33
|
+
*/
|
|
34
|
+
readonly quiet?: boolean;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* `--verbose` -> `debug`, `--quiet` -> `warn`, otherwise `NAMZU_LOG_LEVEL`
|
|
38
|
+
* if it names a real level, otherwise `info` — the floor that used to be
|
|
39
|
+
* silence.
|
|
40
|
+
*
|
|
41
|
+
* `cli.ts` declares `--verbose` and `--quiet` as a `.conflicts()`-paired
|
|
42
|
+
* pair of Commander options, so through the CLI itself at most one of
|
|
43
|
+
* `flags.verbose` / `flags.quiet` is ever true at once. The `verbose`-first
|
|
44
|
+
* check below is what a caller that builds `LogLevelFlags` by hand — every
|
|
45
|
+
* test in `logging.test.ts` — gets instead of relying on that invariant.
|
|
46
|
+
*/
|
|
47
|
+
export declare function resolveLogLevel(flags: LogLevelFlags, env?: NodeJS.ProcessEnv): LevelFilter;
|
|
48
|
+
export interface LogFormatFlags {
|
|
49
|
+
/**
|
|
50
|
+
* `--log-format <pretty|json>`. Commander's `.choices(['pretty','json'])`
|
|
51
|
+
* already rejects anything else at parse time, so `undefined` is the
|
|
52
|
+
* only other value `cli.ts` can hand this. Re-checked below anyway
|
|
53
|
+
* because a caller building this by hand (every test in
|
|
54
|
+
* `logging.test.ts`) is not bound by what Commander would have refused.
|
|
55
|
+
*/
|
|
56
|
+
readonly logFormat?: string;
|
|
57
|
+
}
|
|
58
|
+
export declare function resolveLogFormat(flags: LogFormatFlags, env?: NodeJS.ProcessEnv): LogFormat;
|
|
59
|
+
/**
|
|
60
|
+
* The sink `run`/`drain` install, chosen by `--log-format`/
|
|
61
|
+
* `NAMZU_LOG_FORMAT`. `run-stream` does NOT use this — its stderr is a
|
|
62
|
+
* machine-read NDJSON channel regardless of the format flag, the same way
|
|
63
|
+
* its stdout protocol is unaffected by anything the operator passes. See
|
|
64
|
+
* `commands/run-stream.ts`.
|
|
65
|
+
*/
|
|
66
|
+
export declare function createStderrSink(format: LogFormat): LogSink;
|
|
67
|
+
/**
|
|
68
|
+
* Falls back to the same resolution `cli.ts#getContext()` would have
|
|
69
|
+
* produced with no flags and the live environment, for a `ctx`/`TuiContext`
|
|
70
|
+
* a test built by hand without a `logging` field — a fixture omitting a
|
|
71
|
+
* field it does not care about must not crash the handler it exercises.
|
|
72
|
+
* Every production `ctx` carries `logging`; only a test double hits the
|
|
73
|
+
* fallback, and `test-setup.ts` defaults `NAMZU_LOG_LEVEL` to `silent` so
|
|
74
|
+
* that fallback stays quiet unless a test deliberately overrides it.
|
|
75
|
+
*/
|
|
76
|
+
export declare function contextLogging(ctx: {
|
|
77
|
+
readonly logging?: ResolvedLogging;
|
|
78
|
+
}): ResolvedLogging;
|
|
79
|
+
//# sourceMappingURL=logging.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logging.d.ts","sourceRoot":"","sources":["../src/logging.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,YAAY,CAAA;AAGtD,MAAM,MAAM,SAAS,GAAG,QAAQ,GAAG,MAAM,CAAA;AAEzC;;qCAEqC;AACrC,MAAM,WAAW,eAAe;IAC/B,QAAQ,CAAC,KAAK,EAAE,WAAW,CAAA;IAC3B,QAAQ,CAAC,MAAM,EAAE,SAAS,CAAA;CAC1B;AAQD,MAAM,WAAW,aAAa;IAC7B,yEAAyE;IACzE,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAA;IAC1B;;;;OAIG;IACH,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAA;CACxB;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,eAAe,CAC9B,KAAK,EAAE,aAAa,EACpB,GAAG,GAAE,MAAM,CAAC,UAAwB,GAClC,WAAW,CAIb;AAED,MAAM,WAAW,cAAc;IAC9B;;;;;;OAMG;IACH,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAC3B;AAED,wBAAgB,gBAAgB,CAC/B,KAAK,EAAE,cAAc,EACrB,GAAG,GAAE,MAAM,CAAC,UAAwB,GAClC,SAAS,CAGX;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,SAAS,GAAG,OAAO,CAE3D;AAED;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE;IAAE,QAAQ,CAAC,OAAO,CAAC,EAAE,eAAe,CAAA;CAAE,GAAG,eAAe,CAE3F"}
|
package/dist/logging.js
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Log level + format resolution for the CLI's five entry points that used
|
|
3
|
+
* to force the SDK logger's level to `silent` via `configureLogger` and
|
|
4
|
+
* never turn it back on: `tui/index.tsx`, `commands/run.ts`,
|
|
5
|
+
* `commands/drain.ts` and `commands/run-stream.ts` (twice — `run-stream`
|
|
6
|
+
* itself and `providers-json`). LOG-05.
|
|
7
|
+
*
|
|
8
|
+
* Kept out of `config/load.ts`'s cascade on purpose. That system merges
|
|
9
|
+
* four sources for `format`/`quiet`/`permissions`/`sandbox`, all of them
|
|
10
|
+
* either boolean or a closed enum with a config-file counterpart.
|
|
11
|
+
* `NAMZU_LOG_LEVEL` has no config-file counterpart in this increment and is
|
|
12
|
+
* not boolean-shaped — it names a level directly, string-valued, the same
|
|
13
|
+
* way `--verbose`/`--quiet` do. Precedence here is exactly what the design
|
|
14
|
+
* specifies and nothing more: an explicit flag beats the environment beats
|
|
15
|
+
* the default that used to be silence.
|
|
16
|
+
*/
|
|
17
|
+
import { jsonLinesSink, prettySink } from '@namzu/sdk';
|
|
18
|
+
const LEVEL_FILTERS = new Set(['debug', 'info', 'warn', 'error', 'silent']);
|
|
19
|
+
function isLevelFilter(value) {
|
|
20
|
+
return value !== undefined && LEVEL_FILTERS.has(value);
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* `--verbose` -> `debug`, `--quiet` -> `warn`, otherwise `NAMZU_LOG_LEVEL`
|
|
24
|
+
* if it names a real level, otherwise `info` — the floor that used to be
|
|
25
|
+
* silence.
|
|
26
|
+
*
|
|
27
|
+
* `cli.ts` declares `--verbose` and `--quiet` as a `.conflicts()`-paired
|
|
28
|
+
* pair of Commander options, so through the CLI itself at most one of
|
|
29
|
+
* `flags.verbose` / `flags.quiet` is ever true at once. The `verbose`-first
|
|
30
|
+
* check below is what a caller that builds `LogLevelFlags` by hand — every
|
|
31
|
+
* test in `logging.test.ts` — gets instead of relying on that invariant.
|
|
32
|
+
*/
|
|
33
|
+
export function resolveLogLevel(flags, env = process.env) {
|
|
34
|
+
if (flags.verbose)
|
|
35
|
+
return 'debug';
|
|
36
|
+
if (flags.quiet)
|
|
37
|
+
return 'warn';
|
|
38
|
+
return isLevelFilter(env.NAMZU_LOG_LEVEL) ? env.NAMZU_LOG_LEVEL : 'info';
|
|
39
|
+
}
|
|
40
|
+
export function resolveLogFormat(flags, env = process.env) {
|
|
41
|
+
if (flags.logFormat === 'pretty' || flags.logFormat === 'json')
|
|
42
|
+
return flags.logFormat;
|
|
43
|
+
return env.NAMZU_LOG_FORMAT === 'json' ? 'json' : 'pretty';
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* The sink `run`/`drain` install, chosen by `--log-format`/
|
|
47
|
+
* `NAMZU_LOG_FORMAT`. `run-stream` does NOT use this — its stderr is a
|
|
48
|
+
* machine-read NDJSON channel regardless of the format flag, the same way
|
|
49
|
+
* its stdout protocol is unaffected by anything the operator passes. See
|
|
50
|
+
* `commands/run-stream.ts`.
|
|
51
|
+
*/
|
|
52
|
+
export function createStderrSink(format) {
|
|
53
|
+
return format === 'json' ? jsonLinesSink(process.stderr) : prettySink(process.stderr);
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Falls back to the same resolution `cli.ts#getContext()` would have
|
|
57
|
+
* produced with no flags and the live environment, for a `ctx`/`TuiContext`
|
|
58
|
+
* a test built by hand without a `logging` field — a fixture omitting a
|
|
59
|
+
* field it does not care about must not crash the handler it exercises.
|
|
60
|
+
* Every production `ctx` carries `logging`; only a test double hits the
|
|
61
|
+
* fallback, and `test-setup.ts` defaults `NAMZU_LOG_LEVEL` to `silent` so
|
|
62
|
+
* that fallback stays quiet unless a test deliberately overrides it.
|
|
63
|
+
*/
|
|
64
|
+
export function contextLogging(ctx) {
|
|
65
|
+
return ctx.logging ?? { level: resolveLogLevel({}), format: resolveLogFormat({}) };
|
|
66
|
+
}
|
|
67
|
+
//# sourceMappingURL=logging.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logging.js","sourceRoot":"","sources":["../src/logging.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAGH,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AAYtD,MAAM,aAAa,GAAG,IAAI,GAAG,CAAS,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC,CAAA;AAEnF,SAAS,aAAa,CAAC,KAAyB;IAC/C,OAAO,KAAK,KAAK,SAAS,IAAI,aAAa,CAAC,GAAG,CAAC,KAAK,CAAC,CAAA;AACvD,CAAC;AAaD;;;;;;;;;;GAUG;AACH,MAAM,UAAU,eAAe,CAC9B,KAAoB,EACpB,MAAyB,OAAO,CAAC,GAAG;IAEpC,IAAI,KAAK,CAAC,OAAO;QAAE,OAAO,OAAO,CAAA;IACjC,IAAI,KAAK,CAAC,KAAK;QAAE,OAAO,MAAM,CAAA;IAC9B,OAAO,aAAa,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC,CAAC,MAAM,CAAA;AACzE,CAAC;AAaD,MAAM,UAAU,gBAAgB,CAC/B,KAAqB,EACrB,MAAyB,OAAO,CAAC,GAAG;IAEpC,IAAI,KAAK,CAAC,SAAS,KAAK,QAAQ,IAAI,KAAK,CAAC,SAAS,KAAK,MAAM;QAAE,OAAO,KAAK,CAAC,SAAS,CAAA;IACtF,OAAO,GAAG,CAAC,gBAAgB,KAAK,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAA;AAC3D,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,gBAAgB,CAAC,MAAiB;IACjD,OAAO,MAAM,KAAK,MAAM,CAAC,CAAC,CAAC,aAAa,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,OAAO,CAAC,MAAM,CAAC,CAAA;AACtF,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,cAAc,CAAC,GAA2C;IACzE,OAAO,GAAG,CAAC,OAAO,IAAI,EAAE,KAAK,EAAE,eAAe,CAAC,EAAE,CAAC,EAAE,MAAM,EAAE,gBAAgB,CAAC,EAAE,CAAC,EAAE,CAAA;AACnF,CAAC"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Operator-authored tool permissions, compiled to the kernel's rule vocabulary.
|
|
3
3
|
*
|
|
4
|
-
* The kernel already has the engine — `
|
|
4
|
+
* The kernel already has the engine — `AuthorizationRule[]` with an
|
|
5
5
|
* allow/deny/review decision, evaluated first-match-wins. What was missing was
|
|
6
6
|
* any way for a person to author those rules: the CLI passed `rules: []`, so a
|
|
7
7
|
* gate with seven rule types ran with none of them and every decision fell back
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
* The whole surface is pure: config in, rules out. The gate stays the only
|
|
11
11
|
* thing that decides anything, which is what keeps this testable without a run.
|
|
12
12
|
*/
|
|
13
|
-
import type {
|
|
13
|
+
import type { AuthorizationRule } from '@namzu/sdk';
|
|
14
14
|
/** What the operator wants to happen when a rule matches. */
|
|
15
15
|
export type PermissionEffect = 'allow' | 'ask' | 'deny';
|
|
16
16
|
export declare function isPermissionEffect(value: unknown): value is PermissionEffect;
|
|
@@ -30,7 +30,7 @@ export interface CompileDiagnostic {
|
|
|
30
30
|
readonly message: string;
|
|
31
31
|
}
|
|
32
32
|
export interface CompiledPermissions {
|
|
33
|
-
readonly rules: readonly
|
|
33
|
+
readonly rules: readonly AuthorizationRule[];
|
|
34
34
|
/**
|
|
35
35
|
* What was wrong with the config, for the caller to print.
|
|
36
36
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rules.d.ts","sourceRoot":"","sources":["../../src/permissions/rules.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"rules.d.ts","sourceRoot":"","sources":["../../src/permissions/rules.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAA;AAEnD,6DAA6D;AAC7D,MAAM,MAAM,gBAAgB,GAAG,OAAO,GAAG,KAAK,GAAG,MAAM,CAAA;AAIvD,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,gBAAgB,CAE5E;AAED;;;;;;;GAOG;AACH,MAAM,MAAM,cAAc,GAAG,gBAAgB,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC,CAAA;AAE1F,MAAM,MAAM,iBAAiB,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC,CAAA;AAExE,MAAM,WAAW,iBAAiB;IACjC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAA;IACzB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;CACxB;AAED,MAAM,WAAW,mBAAmB;IACnC,QAAQ,CAAC,KAAK,EAAE,SAAS,iBAAiB,EAAE,CAAA;IAC5C;;;;;;;OAOG;IACH,QAAQ,CAAC,WAAW,EAAE,SAAS,iBAAiB,EAAE,CAAA;CAClD;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAQ7D;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwDG;AACH,wBAAgB,iBAAiB,CAChC,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,EACf,QAAQ,GAAE,OAAO,GAAG,MAAe,GACjC,MAAM,CASR;AAMD,oEAAoE;AACpE,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAKtE;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,aAAa,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAU1D;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,iBAAiB,GAAG,SAAS,GAAG,mBAAmB,CAgD7F"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Operator-authored tool permissions, compiled to the kernel's rule vocabulary.
|
|
3
3
|
*
|
|
4
|
-
* The kernel already has the engine — `
|
|
4
|
+
* The kernel already has the engine — `AuthorizationRule[]` with an
|
|
5
5
|
* allow/deny/review decision, evaluated first-match-wins. What was missing was
|
|
6
6
|
* any way for a person to author those rules: the CLI passed `rules: []`, so a
|
|
7
7
|
* gate with seven rule types ran with none of them and every decision fell back
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rules.js","sourceRoot":"","sources":["../../src/permissions/rules.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"rules.js","sourceRoot":"","sources":["../../src/permissions/rules.ts"],"names":[],"mappings":"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"}
|
package/dist/skills/store.d.ts
CHANGED
|
@@ -48,7 +48,7 @@ interface ParsedSkill {
|
|
|
48
48
|
* ## Absent frontmatter is fine; broken frontmatter is not
|
|
49
49
|
*
|
|
50
50
|
* These were the same case here and are not the same thing. A file with no
|
|
51
|
-
* frontmatter is a documented, supported shape
|
|
51
|
+
* frontmatter is a documented, supported shape: the body
|
|
52
52
|
* is the skill. A file that opens a fence and then fails to parse is an author
|
|
53
53
|
* who tried to write metadata and got it wrong, and answering that with "no
|
|
54
54
|
* metadata, carry on" put the broken YAML into the body — and from there
|
package/dist/skills/store.js
CHANGED
|
@@ -34,7 +34,7 @@ export function projectSkillsDir(cwd = process.cwd()) {
|
|
|
34
34
|
* ## Absent frontmatter is fine; broken frontmatter is not
|
|
35
35
|
*
|
|
36
36
|
* These were the same case here and are not the same thing. A file with no
|
|
37
|
-
* frontmatter is a documented, supported shape
|
|
37
|
+
* frontmatter is a documented, supported shape: the body
|
|
38
38
|
* is the skill. A file that opens a fence and then fails to parse is an author
|
|
39
39
|
* who tried to write metadata and got it wrong, and answering that with "no
|
|
40
40
|
* metadata, carry on" put the broken YAML into the body — and from there
|
package/dist/tui/App.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"App.d.ts","sourceRoot":"","sources":["../../src/tui/App.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;
|
|
1
|
+
{"version":3,"file":"App.d.ts","sourceRoot":"","sources":["../../src/tui/App.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAmFH,OAAO,KAAK,EAAqB,UAAU,EAAE,MAAM,YAAY,CAAA;AAE/D,MAAM,WAAW,QAAQ;IACxB,QAAQ,CAAC,GAAG,EAAE,UAAU,CAAA;CACxB;AAqCD,wBAAgB,GAAG,CAAC,EAAE,GAAG,EAAE,EAAE,QAAQ,2CAqsDpC"}
|
package/dist/tui/App.js
CHANGED
|
@@ -1,6 +1,19 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
/**
|
|
3
|
+
* TUI root. Composes the banner, transcript, composer, status bar, and
|
|
4
|
+
* the first-run provider picker overlay.
|
|
5
|
+
*
|
|
6
|
+
* Session lifecycle:
|
|
7
|
+
* 1. Mount → probeAgentSession() (readPreferences + discoverProviders).
|
|
8
|
+
* 2. If a v2 preferences file exists → createAgentSession(prefs, detected) → ready.
|
|
9
|
+
* 3. If preferences missing OR v1 (legacy) → show <Picker/>.
|
|
10
|
+
* After picker submit, writePreferences + hydrate session.
|
|
11
|
+
* 4. If discovery returned zero providers → show <Picker/> in
|
|
12
|
+
* empty-state mode (explains where to put credentials).
|
|
13
|
+
*/
|
|
14
|
+
import { DiskMessageFeedbackStore, HostCommandRegistry, kernelHostCommands, } from '@namzu/sdk';
|
|
2
15
|
import { Box, Text, useApp, useInput } from 'ink';
|
|
3
|
-
import { relative } from 'node:path';
|
|
16
|
+
import { join, relative } from 'node:path';
|
|
4
17
|
import { useCallback, useEffect, useRef, useState } from 'react';
|
|
5
18
|
import { beginSubscriptionLogin, clearStoredSubscriptionCredential, credentialsPath, primaryProvider, readStoredSubscriptionCredential, writePreferences, } from '../integrations/providers/index.js';
|
|
6
19
|
import { describeLoginOutcome, describeLoginStart, describeLogout } from './login-prompt.js';
|
|
@@ -26,7 +39,7 @@ import { appendMessages, listRecent, loadConversation, openSessions, startConver
|
|
|
26
39
|
import { createAgentSession, probeAgentSession, } from './agent.js';
|
|
27
40
|
import { ResumePicker } from './ResumePicker.js';
|
|
28
41
|
import { discoverUserCommands } from '../user-commands/store.js';
|
|
29
|
-
import {
|
|
42
|
+
import { hostCommandNames, kernelCommandDescriptors, mergeHostCommands, renderOutcome, runSlash, } from './slashCommands.js';
|
|
30
43
|
import { splitCompleteBlocks } from './stream-blocks.js';
|
|
31
44
|
import { theme } from './theme.js';
|
|
32
45
|
/**
|
|
@@ -41,6 +54,14 @@ import { theme } from './theme.js';
|
|
|
41
54
|
const LIVE_FURNITURE_ROWS = 10;
|
|
42
55
|
export function App({ ctx }) {
|
|
43
56
|
const { exit } = useApp();
|
|
57
|
+
/**
|
|
58
|
+
* The last assistant message id the run reported, for `/feedback`.
|
|
59
|
+
*
|
|
60
|
+
* A ref rather than state: nothing renders it, and making it state would
|
|
61
|
+
* re-render the transcript on every delta — the exact cost the `pending`
|
|
62
|
+
* buffering two hundred lines down exists to avoid.
|
|
63
|
+
*/
|
|
64
|
+
const lastAssistantMessage = useRef(null);
|
|
44
65
|
const [messages, setMessages] = useState([]);
|
|
45
66
|
const [history, setHistory] = useState([]);
|
|
46
67
|
const [state, setState] = useState('idle');
|
|
@@ -253,7 +274,7 @@ export function App({ ctx }) {
|
|
|
253
274
|
sessionsRef.current = sessions;
|
|
254
275
|
scopeRef.current = {
|
|
255
276
|
sessionId,
|
|
256
|
-
|
|
277
|
+
topicId: sessions.topicId,
|
|
257
278
|
projectId: sessions.projectId,
|
|
258
279
|
tenantId: sessions.tenantId,
|
|
259
280
|
};
|
|
@@ -283,7 +304,7 @@ export function App({ ctx }) {
|
|
|
283
304
|
// Builtins are reserved: a `help.md` must not take over `/help`.
|
|
284
305
|
// Passing the names here is what lets the loader tell its author
|
|
285
306
|
// the file is shadowed instead of leaving it silently unused.
|
|
286
|
-
reserved:
|
|
307
|
+
reserved: hostCommandNames(),
|
|
287
308
|
}));
|
|
288
309
|
setCurrentProvider(primaryProvider(prefs).id);
|
|
289
310
|
if (s.hasProvider) {
|
|
@@ -547,7 +568,15 @@ export function App({ ctx }) {
|
|
|
547
568
|
liveRows: LIVE_FURNITURE_ROWS + window.rows,
|
|
548
569
|
})
|
|
549
570
|
: 0;
|
|
571
|
+
// One merged vocabulary for the session: this host's own commands plus
|
|
572
|
+
// whatever the kernel's registry reports. Built here so `/help`, the
|
|
573
|
+
// autocomplete and the dispatcher all answer from the same list — three
|
|
574
|
+
// places that used to read one hardcoded array and would otherwise
|
|
575
|
+
// disagree the moment a capability added a command.
|
|
576
|
+
const hostCommands = mergeHostCommands(kernelCommandDescriptors());
|
|
550
577
|
const slashCtx = {
|
|
578
|
+
builtins: hostCommands,
|
|
579
|
+
lastAssistantMessageId: () => lastAssistantMessage.current?.messageId ?? null,
|
|
551
580
|
// Called when `/tools` renders, not read here — the same shape, and the
|
|
552
581
|
// same reason, as `neverPrompted` below.
|
|
553
582
|
availableTools: () => session?.toolNames() ?? [],
|
|
@@ -573,7 +602,6 @@ export function App({ ctx }) {
|
|
|
573
602
|
approvalLatched: () => session?.approvalLatched() ?? false,
|
|
574
603
|
neverPrompted: () => session?.promptExemptTools() ?? [],
|
|
575
604
|
},
|
|
576
|
-
agentIds: session?.agentIds ?? [],
|
|
577
605
|
instructionFiles: session?.instructionFiles ?? [],
|
|
578
606
|
userCommands,
|
|
579
607
|
};
|
|
@@ -758,6 +786,9 @@ export function App({ ctx }) {
|
|
|
758
786
|
switch (event.kind) {
|
|
759
787
|
case 'delta': {
|
|
760
788
|
setState('thinking');
|
|
789
|
+
if (event.messageId && event.runId) {
|
|
790
|
+
lastAssistantMessage.current = { runId: event.runId, messageId: event.messageId };
|
|
791
|
+
}
|
|
761
792
|
st.text += event.text;
|
|
762
793
|
// Held, not appended. Appending each delta is what produced text
|
|
763
794
|
// that types itself out — nothing animates it, but a few
|
|
@@ -989,7 +1020,7 @@ export function App({ ctx }) {
|
|
|
989
1020
|
// including the queue — so a command-driven turn is not a second way
|
|
990
1021
|
// to run one.
|
|
991
1022
|
let outgoing = value;
|
|
992
|
-
const slash = runSlash(value, slashCtx);
|
|
1023
|
+
const slash = runSlash(value, slashCtx, hostCommands);
|
|
993
1024
|
if (slash) {
|
|
994
1025
|
switch (slash.kind) {
|
|
995
1026
|
case 'message':
|
|
@@ -1167,6 +1198,61 @@ export function App({ ctx }) {
|
|
|
1167
1198
|
break;
|
|
1168
1199
|
case 'none':
|
|
1169
1200
|
return;
|
|
1201
|
+
case 'host-command': {
|
|
1202
|
+
// Dispatched through the kernel's registry, built with what
|
|
1203
|
+
// THIS session can answer from. The descriptors used for
|
|
1204
|
+
// the merge above carry no store — they are names — so the
|
|
1205
|
+
// registry is rebuilt here with the live one.
|
|
1206
|
+
const registry = new HostCommandRegistry();
|
|
1207
|
+
registry.register(kernelHostCommands({ allowedAgentIds: session?.agentIds ?? [] }));
|
|
1208
|
+
void (async () => {
|
|
1209
|
+
const outcome = await registry.dispatch(`/${slash.name} ${slash.args.join(' ')}`.trim());
|
|
1210
|
+
pushMessage('system', outcome
|
|
1211
|
+
? renderOutcome(outcome)
|
|
1212
|
+
: `/${slash.name} is registered but this session cannot run it.`);
|
|
1213
|
+
})();
|
|
1214
|
+
return;
|
|
1215
|
+
}
|
|
1216
|
+
case 'feedback': {
|
|
1217
|
+
const target = lastAssistantMessage.current;
|
|
1218
|
+
// Written under the same `<cwd>/.namzu` root the runs live
|
|
1219
|
+
// in, so a rating and the transcript it judges are one
|
|
1220
|
+
// directory apart and travel together.
|
|
1221
|
+
if (!target) {
|
|
1222
|
+
pushMessage('system', 'Nothing to rate yet.');
|
|
1223
|
+
return;
|
|
1224
|
+
}
|
|
1225
|
+
const store = new DiskMessageFeedbackStore({
|
|
1226
|
+
rootDir: join(ctx.cwd, '.namzu', 'feedback'),
|
|
1227
|
+
runsDir: join(ctx.cwd, '.namzu', 'runs'),
|
|
1228
|
+
});
|
|
1229
|
+
const runId = target.runId;
|
|
1230
|
+
const messageId = slash.messageId;
|
|
1231
|
+
// Fire-and-forget: this switch is synchronous, and the
|
|
1232
|
+
// transcript reports the outcome either way rather than
|
|
1233
|
+
// blocking a keystroke on a disk write.
|
|
1234
|
+
void (async () => {
|
|
1235
|
+
try {
|
|
1236
|
+
// A first rating expects nothing; a second replaces the
|
|
1237
|
+
// first, which is what a rater changing their mind does.
|
|
1238
|
+
// Read-then-write rather than blind overwrite, so two
|
|
1239
|
+
// raters on one message still collide loudly.
|
|
1240
|
+
const current = (await store.listMessageFeedback({ runId })).find((r) => r.messageId === messageId);
|
|
1241
|
+
const record = await store.putMessageFeedback({
|
|
1242
|
+
runId,
|
|
1243
|
+
messageId,
|
|
1244
|
+
rating: slash.rating,
|
|
1245
|
+
...(slash.note ? { note: slash.note } : {}),
|
|
1246
|
+
expectedVersion: current?.ownerVersion ?? 0,
|
|
1247
|
+
});
|
|
1248
|
+
pushMessage('system', `Recorded ${record.rating} for ${record.messageId}.`);
|
|
1249
|
+
}
|
|
1250
|
+
catch (err) {
|
|
1251
|
+
pushMessage('system', `Could not record feedback: ${err instanceof Error ? err.message : String(err)}`);
|
|
1252
|
+
}
|
|
1253
|
+
})();
|
|
1254
|
+
return;
|
|
1255
|
+
}
|
|
1170
1256
|
default: {
|
|
1171
1257
|
// Exhaustive on purpose. Without it a `SlashAction` kind added
|
|
1172
1258
|
// and not handled here falls out of the switch into the send
|