@mafdet/cli 0.4.0-preview.0 → 0.4.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/CHANGELOG.md CHANGED
@@ -6,11 +6,27 @@ The version is the contract for the JSON output shapes and the exit codes.
6
6
  Being 0.x, semver still permits a break in a minor bump; the intent is not to
7
7
  use that latitude, and the promise becomes binding at 1.0.0.
8
8
 
9
- ## 0.4.0-preview.0 - 2026-08-07
9
+ ## 0.4.1 - 2026-08-07
10
+
11
+ Fixes Ctrl+C in the interactive session, which did nothing while a model
12
+ request was in flight - the request ran to completion and only then did the
13
+ CLI respond, so it looked like a hang.
14
+
15
+ Two things went wrong. In raw mode Ctrl+C arrives as a byte rather than a
16
+ signal, and nothing was reading keys during a request, so the byte simply
17
+ queued. And the two-stage interrupt logic, though written and unit-tested, was
18
+ never connected to the session.
19
+
20
+ Now the first press cancels the request in flight - the connection is closed,
21
+ verified against a server that records the hang-up - and the session returns to
22
+ the prompt. A press at the prompt exits, and a second press during cleanup
23
+ forces out and says that a charge is still possible.
24
+
25
+ ## 0.4.0 - 2026-08-07
10
26
 
11
27
  An interactive session. Running `mafdet` with no arguments in a terminal now
12
28
  opens one: choose how to authenticate, pick a model, then work with the agent.
13
- Everything else is unchanged, and `latest` still points at 0.3.0.
29
+ Everything else is unchanged; scripts are unaffected (see below).
14
30
 
15
31
  ### The session
16
32
 
package/README.md CHANGED
@@ -3,7 +3,7 @@
3
3
  The official Mafdet AI command line: model calls, account queries, and a
4
4
  permissioned local agent.
5
5
 
6
- > **0.4.0 Preview.** 中文版见 [README.zh-CN.md](./README.zh-CN.md). The CLI never
6
+ > **0.4.1.** 中文版见 [README.zh-CN.md](./README.zh-CN.md). The CLI never
7
7
  > advertises a command it cannot serve, so `mafdet help` always lists exactly
8
8
  > what works.
9
9
  >
@@ -18,19 +18,18 @@ Node.js 20 or newer, and a Mafdet API key.
18
18
  ## Install
19
19
 
20
20
  ```bash
21
- npm install -g @mafdet/cli # 0.3.0, the stable release
22
- npm install -g @mafdet/cli@preview # 0.4.0 preview, with the interactive UI
21
+ npm install -g @mafdet/cli
23
22
  ```
24
23
 
25
24
  Or build it from this repository:
26
25
 
27
26
  ```bash
28
27
  pnpm --filter @mafdet/cli build
29
- cd packages/cli && npm pack # -> mafdet-cli-0.4.0-preview.0.tgz
30
- npm install -g ./mafdet-cli-0.4.0-preview.0.tgz
28
+ cd packages/cli && npm pack # -> mafdet-cli-0.4.1.tgz
29
+ npm install -g ./mafdet-cli-0.4.1.tgz
31
30
  ```
32
31
 
33
- ## The interactive session (0.4 preview)
32
+ ## The interactive session
34
33
 
35
34
  Run `mafdet` with no arguments in a terminal and it opens a session: pick how
36
35
  to authenticate, choose a model, then talk to the agent.
package/README.zh-CN.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  Mafdet AI 官方命令行:模型调用、账户查询,以及一个受权限约束的本地 Agent。
4
4
 
5
- > **0.4.0 Preview。** 英文版见 [README.md](./README.md)。
5
+ > **0.4.1。** 英文版见 [README.md](./README.md)。
6
6
 
7
7
  ## 环境要求
8
8
 
@@ -11,11 +11,10 @@ Node.js 20 或更高,以及一把 Mafdet API Key。
11
11
  ## 安装
12
12
 
13
13
  ```bash
14
- npm install -g @mafdet/cli # 0.3.0 稳定版
15
- npm install -g @mafdet/cli@preview # 0.4.0 预览版,带交互界面
14
+ npm install -g @mafdet/cli
16
15
  ```
17
16
 
18
- ## 交互式会话(0.4 预览)
17
+ ## 交互式会话
19
18
 
20
19
  在终端里不带参数直接敲 `mafdet` 就进入会话:选认证方式、选模型,然后和 Agent 对话。
21
20
 
@@ -9,6 +9,13 @@ export interface AgentSurfaceOptions {
9
9
  };
10
10
  /** Everything runSession needs except the parts this surface supplies. */
11
11
  readonly session: Omit<SessionOptions, "stdout" | "stderr" | "readLine" | "approver" | "onEvent">;
12
+ /**
13
+ * Read fresh for every turn, so a cancelled request can be followed by a new
14
+ * one. Passed as a function rather than a getter on `session`: the spread
15
+ * below would evaluate a getter once and copy the result, quietly freezing
16
+ * the signal to whatever controller existed at startup.
17
+ */
18
+ readonly getSignal?: () => AbortSignal | undefined;
12
19
  /** Injected by the tests; production uses runSession. */
13
20
  readonly run?: typeof runSession;
14
21
  }
@@ -1 +1 @@
1
- {"version":3,"file":"agent-surface.d.ts","sourceRoot":"","sources":["../../src/tui/agent-surface.ts"],"names":[],"mappings":"AAQA,OAAO,EACL,UAAU,EACV,KAAK,cAAc,EACnB,KAAK,cAAc,EACpB,MAAM,qBAAqB,CAAC;AAI7B,OAAO,EAAW,KAAK,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAEhE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAE7C,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,EAAE,EAAE,QAAQ,CAAC;IACtB,QAAQ,CAAC,YAAY,EAAE,oBAAoB,CAAC;IAC5C,QAAQ,CAAC,MAAM,EAAE;QAAE,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAA;KAAE,CAAC;IAClD,0EAA0E;IAC1E,QAAQ,CAAC,OAAO,EAAE,IAAI,CACpB,cAAc,EACd,QAAQ,GAAG,QAAQ,GAAG,UAAU,GAAG,UAAU,GAAG,SAAS,CAC1D,CAAC;IACF,yDAAyD;IACzD,QAAQ,CAAC,GAAG,CAAC,EAAE,OAAO,UAAU,CAAC;CAClC;AAED;;;;;;GAMG;AACH,wBAAsB,UAAU,CAC9B,EAAE,EAAE,QAAQ,EACZ,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CA+B7B;AAED,wBAAsB,eAAe,CACnC,OAAO,EAAE,mBAAmB,GAC3B,OAAO,CAAC,cAAc,CAAC,CAkCzB;AAED,wBAAgB,aAAa,CAC3B,OAAO,EAAE,cAAc,EACvB,YAAY,EAAE,oBAAoB,GACjC,MAAM,CAgBR"}
1
+ {"version":3,"file":"agent-surface.d.ts","sourceRoot":"","sources":["../../src/tui/agent-surface.ts"],"names":[],"mappings":"AAQA,OAAO,EACL,UAAU,EACV,KAAK,cAAc,EACnB,KAAK,cAAc,EACpB,MAAM,qBAAqB,CAAC;AAI7B,OAAO,EAAW,KAAK,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAEhE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAE7C,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,EAAE,EAAE,QAAQ,CAAC;IACtB,QAAQ,CAAC,YAAY,EAAE,oBAAoB,CAAC;IAC5C,QAAQ,CAAC,MAAM,EAAE;QAAE,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAA;KAAE,CAAC;IAClD,0EAA0E;IAC1E,QAAQ,CAAC,OAAO,EAAE,IAAI,CACpB,cAAc,EACd,QAAQ,GAAG,QAAQ,GAAG,UAAU,GAAG,UAAU,GAAG,SAAS,CAC1D,CAAC;IACF;;;;;OAKG;IACH,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,WAAW,GAAG,SAAS,CAAC;IACnD,yDAAyD;IACzD,QAAQ,CAAC,GAAG,CAAC,EAAE,OAAO,UAAU,CAAC;CAClC;AAED;;;;;;GAMG;AACH,wBAAsB,UAAU,CAC9B,EAAE,EAAE,QAAQ,EACZ,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CA+B7B;AAED,wBAAsB,eAAe,CACnC,OAAO,EAAE,mBAAmB,GAC3B,OAAO,CAAC,cAAc,CAAC,CA6CzB;AAED,wBAAgB,aAAa,CAC3B,OAAO,EAAE,cAAc,EACvB,YAAY,EAAE,oBAAoB,GACjC,MAAM,CAgBR"}
@@ -67,7 +67,7 @@ export async function runAgentSurface(options) {
67
67
  options.stdout.write(dim(` rate limited - waiting ${Math.round(event.waitMs / 1000)}s\n`));
68
68
  }
69
69
  };
70
- const summary = await run({
70
+ const sessionOptions = {
71
71
  ...options.session,
72
72
  stdout: (text) => void options.stdout.write(text),
73
73
  // The line session sends progress to stderr so it survives redirection.
@@ -76,7 +76,16 @@ export async function runAgentSurface(options) {
76
76
  approver: tuiApprover(io),
77
77
  readLine: () => promptLine(io, "> "),
78
78
  onEvent,
79
- });
79
+ };
80
+ // Installed after the spread, on purpose - see getSignal above.
81
+ if (options.getSignal !== undefined) {
82
+ Object.defineProperty(sessionOptions, "signal", {
83
+ get: options.getSignal,
84
+ enumerable: true,
85
+ configurable: true,
86
+ });
87
+ }
88
+ const summary = await run(sessionOptions);
80
89
  options.stdout.write(renderSummary(summary, capabilities));
81
90
  return summary;
82
91
  }
@@ -1 +1 @@
1
- {"version":3,"file":"app.d.ts","sourceRoot":"","sources":["../../src/tui/app.ts"],"names":[],"mappings":"AAUA,OAAO,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AACnD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAYxD,OAAO,EAAwB,KAAK,SAAS,EAAE,MAAM,eAAe,CAAC;AAQrE,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,MAAM,EAAE;QAAE,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAA;KAAE,CAAC;IAClD,QAAQ,CAAC,MAAM,EAAE;QAAE,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAA;KAAE,CAAC;IAClD,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC,UAAU,GAAG;QAAE,KAAK,CAAC,EAAE,OAAO,CAAC;QAAC,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC;IACzE,QAAQ,CAAC,GAAG,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC,CAAC;IAC3D,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IACzB,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,CAAC;IACrC,QAAQ,CAAC,SAAS,EAAE,SAAS,CAAC;IAC9B,wEAAwE;IACxE,QAAQ,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,CAAC;CAClC;AAED,wBAAsB,MAAM,CAAC,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC,QAAQ,CAAC,CAuFnE"}
1
+ {"version":3,"file":"app.d.ts","sourceRoot":"","sources":["../../src/tui/app.ts"],"names":[],"mappings":"AAUA,OAAO,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AACnD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAaxD,OAAO,EAAwB,KAAK,SAAS,EAAE,MAAM,eAAe,CAAC;AAQrE,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,MAAM,EAAE;QAAE,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAA;KAAE,CAAC;IAClD,QAAQ,CAAC,MAAM,EAAE;QAAE,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAA;KAAE,CAAC;IAClD,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC,UAAU,GAAG;QAAE,KAAK,CAAC,EAAE,OAAO,CAAC;QAAC,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC;IACzE,QAAQ,CAAC,GAAG,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC,CAAC;IAC3D,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IACzB,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,CAAC;IACrC,QAAQ,CAAC,SAAS,EAAE,SAAS,CAAC;IAC9B,wEAAwE;IACxE,QAAQ,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,CAAC;CAClC;AAED,wBAAsB,MAAM,CAAC,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC,QAAQ,CAAC,CAgInE"}
package/dist/tui/app.js CHANGED
@@ -9,6 +9,7 @@ import { ExitCode } from "../output/exit-codes.js";
9
9
  import { loadCatalogue, saveDefaultModel } from "./adapters/models.js";
10
10
  import { renderBanner } from "./banner.js";
11
11
  import { keyboard } from "./input.js";
12
+ import { FORCED_EXIT_NOTICE, InterruptTracker } from "./interrupt.js";
12
13
  import { runOnboarding } from "./onboarding.js";
13
14
  import { noAgentModelsNotice, pickModel } from "./picker.js";
14
15
  import { palette, detectCapabilities, } from "./theme.js";
@@ -35,10 +36,46 @@ export async function runTui(options) {
35
36
  options.stderr.write(`mafdet: ${message}\n`);
36
37
  },
37
38
  });
38
- const keys = keyboard(options.stdin);
39
+ // Two-stage Ctrl+C (plan 19.7). In raw mode Ctrl+C arrives as a byte rather
40
+ // than a signal, and during a model request nothing is reading keys - so
41
+ // without this it did nothing at all until the request finished by itself.
42
+ const interrupts = new InterruptTracker();
43
+ let inFlight;
44
+ const { dim } = palette(capabilities);
45
+ const onInterrupt = () => {
46
+ const outcome = interrupts.press();
47
+ if (outcome.action === "cancel-operation") {
48
+ options.stdout.write(dim("\n cancelling...\n"));
49
+ // Abort what is running, then hand the session a fresh controller so it
50
+ // returns to the prompt instead of ending.
51
+ inFlight?.abort();
52
+ inFlight = new AbortController();
53
+ return true;
54
+ }
55
+ if (outcome.action === "force-exit") {
56
+ options.stdout.write(`\n ${FORCED_EXIT_NOTICE}\n`);
57
+ guard.restore();
58
+ options.host.exit(130);
59
+ return true;
60
+ }
61
+ // Idle: leave it to whatever is reading, which already treats Ctrl+C as
62
+ // "cancel this prompt" and ends the session.
63
+ return false;
64
+ };
65
+ const keys = keyboard(options.stdin, { onInterrupt });
39
66
  const io = {
40
67
  write: (text) => void options.stdout.write(text),
41
- nextKeys: () => keys.nextKeys(),
68
+ // Waiting for input is exactly what "idle" means, so the tracker learns it
69
+ // here rather than by being told from inside the session.
70
+ nextKeys: async () => {
71
+ interrupts.finish();
72
+ try {
73
+ return await keys.nextKeys();
74
+ }
75
+ finally {
76
+ interrupts.begin();
77
+ }
78
+ },
42
79
  capabilities,
43
80
  };
44
81
  try {
@@ -76,6 +113,10 @@ export async function runTui(options) {
76
113
  model: chosen,
77
114
  workspace: options.workspace,
78
115
  permissions: parsePermissions(options.argv),
116
+ getSignal: () => {
117
+ inFlight ??= new AbortController();
118
+ return inFlight.signal;
119
+ },
79
120
  });
80
121
  }
81
122
  finally {
@@ -13,5 +13,17 @@ export interface RawStdin {
13
13
  off?(event: string, listener: (chunk: string) => void): unknown;
14
14
  readonly isTTY?: boolean;
15
15
  }
16
- export declare function keyboard(stdin: RawStdin): KeySource;
16
+ export interface KeyboardOptions {
17
+ /**
18
+ * Called the moment an interrupt key is decoded, whether or not anyone is
19
+ * waiting for input. Return true to consume it, so a Ctrl+C that cancelled a
20
+ * request is not also delivered to the prompt as "quit".
21
+ *
22
+ * Without this the byte simply queued: in raw mode Ctrl+C is not a signal,
23
+ * and during a model request nothing is calling nextKeys(), so pressing it
24
+ * did nothing at all until the request finished on its own.
25
+ */
26
+ readonly onInterrupt?: () => boolean;
27
+ }
28
+ export declare function keyboard(stdin: RawStdin, options?: KeyboardOptions): KeySource;
17
29
  //# sourceMappingURL=input.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"input.d.ts","sourceRoot":"","sources":["../../src/tui/input.ts"],"names":[],"mappings":"AAQA,OAAO,EAAc,KAAK,GAAG,EAAE,MAAM,WAAW,CAAC;AAEjD,MAAM,WAAW,SAAS;IACxB,QAAQ,IAAI,OAAO,CAAC,SAAS,GAAG,EAAE,GAAG,SAAS,CAAC,CAAC;IAChD,4DAA4D;IAC5D,KAAK,IAAI,IAAI,CAAC;CACf;AAED,MAAM,WAAW,QAAQ;IACvB,UAAU,CAAC,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC;IACpC,MAAM,CAAC,IAAI,OAAO,CAAC;IACnB,KAAK,CAAC,IAAI,OAAO,CAAC;IAClB,WAAW,CAAC,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC;IACxC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,GAAG,OAAO,CAAC;IAC9D,GAAG,CAAC,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,GAAG,OAAO,CAAC;IAChE,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC;CAC1B;AAED,wBAAgB,QAAQ,CAAC,KAAK,EAAE,QAAQ,GAAG,SAAS,CA8CnD"}
1
+ {"version":3,"file":"input.d.ts","sourceRoot":"","sources":["../../src/tui/input.ts"],"names":[],"mappings":"AAQA,OAAO,EAAc,KAAK,GAAG,EAAE,MAAM,WAAW,CAAC;AAEjD,MAAM,WAAW,SAAS;IACxB,QAAQ,IAAI,OAAO,CAAC,SAAS,GAAG,EAAE,GAAG,SAAS,CAAC,CAAC;IAChD,4DAA4D;IAC5D,KAAK,IAAI,IAAI,CAAC;CACf;AAED,MAAM,WAAW,QAAQ;IACvB,UAAU,CAAC,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC;IACpC,MAAM,CAAC,IAAI,OAAO,CAAC;IACnB,KAAK,CAAC,IAAI,OAAO,CAAC;IAClB,WAAW,CAAC,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC;IACxC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,GAAG,OAAO,CAAC;IAC9D,GAAG,CAAC,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,GAAG,OAAO,CAAC;IAChE,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC;CAC1B;AAED,MAAM,WAAW,eAAe;IAC9B;;;;;;;;OAQG;IACH,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,OAAO,CAAC;CACtC;AAED,wBAAgB,QAAQ,CACtB,KAAK,EAAE,QAAQ,EACf,OAAO,GAAE,eAAoB,GAC5B,SAAS,CAsDX"}
package/dist/tui/input.js CHANGED
@@ -6,7 +6,7 @@
6
6
  // that arrives is decoded and kept, and a widget asking for input drains the
7
7
  // queue before it waits.
8
8
  import { decodeKeys } from "./keys.js";
9
- export function keyboard(stdin) {
9
+ export function keyboard(stdin, options = {}) {
10
10
  const pending = [];
11
11
  let waiting;
12
12
  let ended = false;
@@ -21,7 +21,14 @@ export function keyboard(stdin) {
21
21
  pending.push([...keys]);
22
22
  };
23
23
  const onData = (chunk) => {
24
- const keys = decodeKeys(chunk);
24
+ let keys = decodeKeys(chunk);
25
+ if (options.onInterrupt !== undefined &&
26
+ keys.some((k) => k.kind === "interrupt")) {
27
+ // Handled out of band; only drop the key if the handler took it.
28
+ const consumed = options.onInterrupt();
29
+ if (consumed)
30
+ keys = keys.filter((k) => k.kind !== "interrupt");
31
+ }
25
32
  if (keys.length > 0)
26
33
  deliver(keys);
27
34
  };
@@ -25,7 +25,13 @@ export interface StartAgentOptions {
25
25
  readonly model: ResolvedModel;
26
26
  readonly workspace: string;
27
27
  readonly permissions: AgentPermissions;
28
- readonly signal?: AbortSignal;
28
+ /**
29
+ * Read fresh for every goal. A cancel aborts the request in flight and then
30
+ * swaps in a new controller, so the session survives Ctrl+C instead of
31
+ * ending on it - runSession re-reads `signal` each turn, which is what makes
32
+ * that possible.
33
+ */
34
+ readonly getSignal?: () => AbortSignal | undefined;
29
35
  }
30
36
  export declare function startAgent(options: StartAgentOptions): Promise<ExitCode>;
31
37
  //# sourceMappingURL=start-agent.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"start-agent.d.ts","sourceRoot":"","sources":["../../src/tui/start-agent.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,EAAgB,KAAK,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAEtE,OAAO,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AAEnD,OAAO,EAAW,KAAK,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAChE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAE7C,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC;IAC7B,QAAQ,CAAC,eAAe,EAAE,SAAS,MAAM,EAAE,CAAC;CAC7C;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG,gBAAgB,CAe1E;AAED,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,EAAE,EAAE,QAAQ,CAAC;IACtB,QAAQ,CAAC,YAAY,EAAE,oBAAoB,CAAC;IAC5C,QAAQ,CAAC,MAAM,EAAE;QAAE,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAA;KAAE,CAAC;IAClD,QAAQ,CAAC,SAAS,EAAE,SAAS,CAAC;IAC9B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,KAAK,EAAE,aAAa,CAAC;IAC9B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,WAAW,EAAE,gBAAgB,CAAC;IACvC,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,CAAC;CAC/B;AAED,wBAAsB,UAAU,CAC9B,OAAO,EAAE,iBAAiB,GACzB,OAAO,CAAC,QAAQ,CAAC,CAwDnB"}
1
+ {"version":3,"file":"start-agent.d.ts","sourceRoot":"","sources":["../../src/tui/start-agent.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,EAAgB,KAAK,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAEtE,OAAO,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AAEnD,OAAO,EAAW,KAAK,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAChE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAE7C,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC;IAC7B,QAAQ,CAAC,eAAe,EAAE,SAAS,MAAM,EAAE,CAAC;CAC7C;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG,gBAAgB,CAe1E;AAED,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,EAAE,EAAE,QAAQ,CAAC;IACtB,QAAQ,CAAC,YAAY,EAAE,oBAAoB,CAAC;IAC5C,QAAQ,CAAC,MAAM,EAAE;QAAE,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAA;KAAE,CAAC;IAClD,QAAQ,CAAC,SAAS,EAAE,SAAS,CAAC;IAC9B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,KAAK,EAAE,aAAa,CAAC;IAC9B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,WAAW,EAAE,gBAAgB,CAAC;IACvC;;;;;OAKG;IACH,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,WAAW,GAAG,SAAS,CAAC;CACpD;AAED,wBAAsB,UAAU,CAC9B,OAAO,EAAE,iBAAiB,GACzB,OAAO,CAAC,QAAQ,CAAC,CA0DnB"}
@@ -62,6 +62,9 @@ export async function startAgent(options) {
62
62
  io: options.io,
63
63
  capabilities: options.capabilities,
64
64
  stdout: options.stdout,
65
+ ...(options.getSignal === undefined
66
+ ? {}
67
+ : { getSignal: options.getSignal }),
65
68
  session: {
66
69
  client: runtime.dataPlane,
67
70
  model: options.model.modelId,
@@ -75,7 +78,6 @@ export async function startAgent(options) {
75
78
  },
76
79
  mode,
77
80
  allowedCommands: options.permissions.allowedCommands,
78
- ...(options.signal === undefined ? {} : { signal: options.signal }),
79
81
  },
80
82
  });
81
83
  return ExitCode.Ok;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mafdet/cli",
3
- "version": "0.4.0-preview.0",
3
+ "version": "0.4.1",
4
4
  "description": "Mafdet AI command line — model calls, account queries, and a permissioned local agent.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -30,8 +30,7 @@
30
30
  "LICENSE"
31
31
  ],
32
32
  "publishConfig": {
33
- "access": "public",
34
- "tag": "preview"
33
+ "access": "public"
35
34
  },
36
35
  "scripts": {
37
36
  "build": "tsc -p tsconfig.json",