@mafdet/cli 0.3.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/CHANGELOG.md +43 -0
- package/README.md +22 -3
- package/README.zh-CN.md +17 -1
- package/dist/agent/loop.d.ts +17 -0
- package/dist/agent/loop.d.ts.map +1 -1
- package/dist/agent/loop.js +17 -7
- package/dist/agent/session.d.ts +8 -1
- package/dist/agent/session.d.ts.map +1 -1
- package/dist/agent/session.js +1 -1
- package/dist/commands/agent.d.ts +9 -0
- package/dist/commands/agent.d.ts.map +1 -1
- package/dist/commands/agent.js +3 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +45 -6
- package/dist/tui/adapters/auth.d.ts +26 -0
- package/dist/tui/adapters/auth.d.ts.map +1 -0
- package/dist/tui/adapters/auth.js +76 -0
- package/dist/tui/adapters/models.d.ts +47 -0
- package/dist/tui/adapters/models.d.ts.map +1 -0
- package/dist/tui/adapters/models.js +146 -0
- package/dist/tui/agent-surface.d.ts +25 -0
- package/dist/tui/agent-surface.d.ts.map +1 -0
- package/dist/tui/agent-surface.js +95 -0
- package/dist/tui/app.d.ts +25 -0
- package/dist/tui/app.d.ts.map +1 -0
- package/dist/tui/app.js +159 -0
- package/dist/tui/approval.d.ts +27 -0
- package/dist/tui/approval.d.ts.map +1 -0
- package/dist/tui/approval.js +79 -0
- package/dist/tui/banner.d.ts +13 -0
- package/dist/tui/banner.d.ts.map +1 -0
- package/dist/tui/banner.js +97 -0
- package/dist/tui/input.d.ts +17 -0
- package/dist/tui/input.d.ts.map +1 -0
- package/dist/tui/input.js +57 -0
- package/dist/tui/interrupt.d.ts +32 -0
- package/dist/tui/interrupt.d.ts.map +1 -0
- package/dist/tui/interrupt.js +47 -0
- package/dist/tui/keys.d.ts +30 -0
- package/dist/tui/keys.d.ts.map +1 -0
- package/dist/tui/keys.js +86 -0
- package/dist/tui/onboarding.d.ts +28 -0
- package/dist/tui/onboarding.d.ts.map +1 -0
- package/dist/tui/onboarding.js +117 -0
- package/dist/tui/picker.d.ts +24 -0
- package/dist/tui/picker.d.ts.map +1 -0
- package/dist/tui/picker.js +146 -0
- package/dist/tui/resize.d.ts +22 -0
- package/dist/tui/resize.d.ts.map +1 -0
- package/dist/tui/resize.js +37 -0
- package/dist/tui/route.d.ts +26 -0
- package/dist/tui/route.d.ts.map +1 -0
- package/dist/tui/route.js +68 -0
- package/dist/tui/start-agent.d.ts +31 -0
- package/dist/tui/start-agent.d.ts.map +1 -0
- package/dist/tui/start-agent.js +82 -0
- package/dist/tui/terminal.d.ts +41 -0
- package/dist/tui/terminal.d.ts.map +1 -0
- package/dist/tui/terminal.js +78 -0
- package/dist/tui/theme.d.ts +22 -0
- package/dist/tui/theme.d.ts.map +1 -0
- package/dist/tui/theme.js +59 -0
- package/dist/tui/tool-card.d.ts +41 -0
- package/dist/tui/tool-card.d.ts.map +1 -0
- package/dist/tui/tool-card.js +132 -0
- package/dist/tui/widgets.d.ts +44 -0
- package/dist/tui/widgets.d.ts.map +1 -0
- package/dist/tui/widgets.js +137 -0
- package/dist/tui/workspace-summary.d.ts +10 -0
- package/dist/tui/workspace-summary.d.ts.map +1 -0
- package/dist/tui/workspace-summary.js +49 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -6,6 +6,49 @@ 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 - 2026-08-07
|
|
10
|
+
|
|
11
|
+
An interactive session. Running `mafdet` with no arguments in a terminal now
|
|
12
|
+
opens one: choose how to authenticate, pick a model, then work with the agent.
|
|
13
|
+
Everything else is unchanged; scripts are unaffected (see below).
|
|
14
|
+
|
|
15
|
+
### The session
|
|
16
|
+
|
|
17
|
+
- The welcome page, then authentication, then a model picker that narrows as
|
|
18
|
+
you type, then the agent.
|
|
19
|
+
- Authentication offers only what the system can serve: the environment key, a
|
|
20
|
+
key pasted for this session only, or instructions for creating one. A pasted
|
|
21
|
+
key is held in memory, never written to a file and never put into the
|
|
22
|
+
environment.
|
|
23
|
+
- The model picker lists only what this key can call. Where any model has
|
|
24
|
+
verified tool calling, only those are offered, so a model the agent cannot
|
|
25
|
+
drive never becomes the default. Route RPM is reported as not published,
|
|
26
|
+
because the catalogue does not publish it.
|
|
27
|
+
- Tool calls appear as cards that move from running to succeeded, refused or
|
|
28
|
+
failed. Changes are shown as a diff and approved one at a time; there is no
|
|
29
|
+
"always allow".
|
|
30
|
+
- Two-stage Ctrl+C: the first cancels what is running, and a second during
|
|
31
|
+
cleanup forces out and says that a charge is still possible.
|
|
32
|
+
|
|
33
|
+
### Same agent, drawn differently
|
|
34
|
+
|
|
35
|
+
The session drives the same code `mafdet agent` does, so the tools, approvals
|
|
36
|
+
and cost accounting cannot diverge. `--allow-write` and `--allow-command` mean
|
|
37
|
+
exactly what they mean there, and a session given neither has no write or
|
|
38
|
+
command tool loaded at all.
|
|
39
|
+
|
|
40
|
+
### Nothing that reads the output is affected
|
|
41
|
+
|
|
42
|
+
In a pipeline, under `--json` or `--quiet`, in CI, with `TERM=dumb`, or with
|
|
43
|
+
`--no-tui`, `mafdet` behaves exactly as it did in 0.3: usage on stderr, exit 2.
|
|
44
|
+
|
|
45
|
+
### Known limitations
|
|
46
|
+
|
|
47
|
+
- macOS and Windows are still unverified. Linux, WSL, tmux, SSH and SSH+tmux
|
|
48
|
+
were checked on real terminals.
|
|
49
|
+
- ASCII is still the default. The block wordmark appears only where the
|
|
50
|
+
encoding is known to be UTF-8: a UTF-8 locale, or Windows Terminal.
|
|
51
|
+
|
|
9
52
|
## 0.3.0 — 2026-08-07
|
|
10
53
|
|
|
11
54
|
First published release. It contains everything through the plan's 0.3 scope,
|
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.
|
|
6
|
+
> **0.4.0.** 中文版见 [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
|
>
|
|
@@ -25,10 +25,29 @@ Or build it from this repository:
|
|
|
25
25
|
|
|
26
26
|
```bash
|
|
27
27
|
pnpm --filter @mafdet/cli build
|
|
28
|
-
cd packages/cli && npm pack # -> mafdet-cli-0.
|
|
29
|
-
npm install -g ./mafdet-cli-0.
|
|
28
|
+
cd packages/cli && npm pack # -> mafdet-cli-0.4.0.tgz
|
|
29
|
+
npm install -g ./mafdet-cli-0.4.0.tgz
|
|
30
30
|
```
|
|
31
31
|
|
|
32
|
+
## The interactive session
|
|
33
|
+
|
|
34
|
+
Run `mafdet` with no arguments in a terminal and it opens a session: pick how
|
|
35
|
+
to authenticate, choose a model, then talk to the agent.
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
mafdet # read-only
|
|
39
|
+
mafdet --allow-write # changes are shown as a diff and confirmed first
|
|
40
|
+
mafdet --allow-command "pnpm test"
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
It is the same agent as `mafdet agent`, drawn differently - the same tools, the
|
|
44
|
+
same approvals, the same cost accounting. The flags mean exactly what they mean
|
|
45
|
+
there, and a session given neither has no write or command tool loaded at all.
|
|
46
|
+
|
|
47
|
+
`mafdet` in a pipeline, under `--json`, in CI, or with `--no-tui` behaves
|
|
48
|
+
exactly as it did in 0.3: usage on stderr, exit 2. Nothing that reads the
|
|
49
|
+
CLI's output will start receiving a drawing.
|
|
50
|
+
|
|
32
51
|
## Quickstart
|
|
33
52
|
|
|
34
53
|
```bash
|
package/README.zh-CN.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
Mafdet AI 官方命令行:模型调用、账户查询,以及一个受权限约束的本地 Agent。
|
|
4
4
|
|
|
5
|
-
> **0.
|
|
5
|
+
> **0.4.0。** 英文版见 [README.md](./README.md)。
|
|
6
6
|
|
|
7
7
|
## 环境要求
|
|
8
8
|
|
|
@@ -14,6 +14,22 @@ Node.js 20 或更高,以及一把 Mafdet API Key。
|
|
|
14
14
|
npm install -g @mafdet/cli
|
|
15
15
|
```
|
|
16
16
|
|
|
17
|
+
## 交互式会话
|
|
18
|
+
|
|
19
|
+
在终端里不带参数直接敲 `mafdet` 就进入会话:选认证方式、选模型,然后和 Agent 对话。
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
mafdet # 只读
|
|
23
|
+
mafdet --allow-write # 改动先展示 diff 再确认
|
|
24
|
+
mafdet --allow-command "pnpm test"
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
它和 `mafdet agent` 是**同一个 Agent**,只是画法不同——同样的工具、同样的审批、
|
|
28
|
+
同样的计费。参数含义与那边完全一致,两个都不给的会话**根本没有加载**写工具和命令工具。
|
|
29
|
+
|
|
30
|
+
管道里、`--json` 下、CI 中、或带 `--no-tui` 时,`mafdet` 的行为与 0.3 完全一样:
|
|
31
|
+
用法写 stderr、exit 2。**任何读取 CLI 输出的程序都不会突然收到一个界面。**
|
|
32
|
+
|
|
17
33
|
## 快速开始
|
|
18
34
|
|
|
19
35
|
```bash
|
package/dist/agent/loop.d.ts
CHANGED
|
@@ -56,9 +56,26 @@ export interface AgentOptions {
|
|
|
56
56
|
now?: () => number;
|
|
57
57
|
random?: () => number;
|
|
58
58
|
}
|
|
59
|
+
/**
|
|
60
|
+
* Progress, for whoever is drawing.
|
|
61
|
+
*
|
|
62
|
+
* The lifecycle events (`tool_started`, `tool_awaiting_approval`) were added
|
|
63
|
+
* for the TUI's tool cards in CLI-021. They are additive: `tool` and
|
|
64
|
+
* `declined` still fire exactly as before, so the line-based session renders
|
|
65
|
+
* unchanged and the two surfaces cannot drift on what happened - only on how
|
|
66
|
+
* it is shown.
|
|
67
|
+
*/
|
|
59
68
|
export type AgentEvent = {
|
|
60
69
|
type: "turn";
|
|
61
70
|
turn: number;
|
|
71
|
+
} | {
|
|
72
|
+
type: "tool_started";
|
|
73
|
+
name: string;
|
|
74
|
+
arguments: string;
|
|
75
|
+
} | {
|
|
76
|
+
type: "tool_awaiting_approval";
|
|
77
|
+
name: string;
|
|
78
|
+
summary: string;
|
|
62
79
|
} | {
|
|
63
80
|
type: "tool";
|
|
64
81
|
name: string;
|
package/dist/agent/loop.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"loop.d.ts","sourceRoot":"","sources":["../../src/agent/loop.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"loop.d.ts","sourceRoot":"","sources":["../../src/agent/loop.ts"],"names":[],"mappings":"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"}
|
package/dist/agent/loop.js
CHANGED
|
@@ -101,6 +101,11 @@ export async function runAgent(options) {
|
|
|
101
101
|
for (const call of calls) {
|
|
102
102
|
if (options.signal?.aborted)
|
|
103
103
|
return stop(report, "cancelled");
|
|
104
|
+
options.onEvent?.({
|
|
105
|
+
type: "tool_started",
|
|
106
|
+
name: call.function.name,
|
|
107
|
+
arguments: call.function.arguments,
|
|
108
|
+
});
|
|
104
109
|
const { text, ok } = await runToolCall(call, byName, options);
|
|
105
110
|
report.toolRuns.push({ name: call.function.name, ok });
|
|
106
111
|
options.onEvent?.({
|
|
@@ -160,13 +165,18 @@ async function runToolCall(call, byName, options) {
|
|
|
160
165
|
// An action can carry advance approval - an --allow-command entry the user
|
|
161
166
|
// declared up front - which is the only way anything runs unprompted.
|
|
162
167
|
const approver = options.approver;
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
168
|
+
let approved = action.preApproved === true;
|
|
169
|
+
if (!approved && approver) {
|
|
170
|
+
options.onEvent?.({
|
|
171
|
+
type: "tool_awaiting_approval",
|
|
172
|
+
name: tool.name,
|
|
173
|
+
summary: action.summary,
|
|
174
|
+
});
|
|
175
|
+
approved = await approver.approve({
|
|
176
|
+
summary: action.summary,
|
|
177
|
+
preview: action.preview,
|
|
178
|
+
});
|
|
179
|
+
}
|
|
170
180
|
if (!approved) {
|
|
171
181
|
options.onEvent?.({
|
|
172
182
|
type: "declined",
|
package/dist/agent/session.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { HttpClient } from "../api/http.js";
|
|
2
2
|
import type { CatalogModel } from "../api/models.js";
|
|
3
3
|
import type { Approver } from "./approvals.js";
|
|
4
|
-
import { type ChatMessage } from "./loop.js";
|
|
4
|
+
import { type AgentEvent, type ChatMessage } from "./loop.js";
|
|
5
5
|
import type { ToolContext, ToolDefinition } from "./tools/types.js";
|
|
6
6
|
export interface SessionOptions {
|
|
7
7
|
client: HttpClient;
|
|
@@ -25,6 +25,13 @@ export interface SessionOptions {
|
|
|
25
25
|
*/
|
|
26
26
|
readLine?: () => Promise<string | undefined>;
|
|
27
27
|
signal?: AbortSignal;
|
|
28
|
+
/**
|
|
29
|
+
* Where progress goes. Defaults to the line-based rendering below; the TUI
|
|
30
|
+
* (CLI-021) supplies its own so that both surfaces share this session's
|
|
31
|
+
* conversation, cost accounting and approval flow, and differ only in how
|
|
32
|
+
* the same events are drawn.
|
|
33
|
+
*/
|
|
34
|
+
onEvent?: (event: AgentEvent) => void;
|
|
28
35
|
}
|
|
29
36
|
export interface SessionSummary {
|
|
30
37
|
goals: number;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../src/agent/session.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AACjD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAIrD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC/C,OAAO,
|
|
1
|
+
{"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../src/agent/session.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AACjD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAIrD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC/C,OAAO,EAAY,KAAK,UAAU,EAAE,KAAK,WAAW,EAAE,MAAM,WAAW,CAAC;AACxE,OAAO,KAAK,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAapE,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,UAAU,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,YAAY,CAAC;IACvB,oEAAoE;IACpE,OAAO,EAAE,SAAS,YAAY,EAAE,CAAC;IACjC,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,cAAc,EAAE,CAAC;IACxB,WAAW,EAAE,WAAW,CAAC;IACzB,QAAQ,CAAC,EAAE,QAAQ,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,eAAe,EAAE,SAAS,MAAM,EAAE,CAAC;IACnC,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/B,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/B,KAAK,CAAC,EAAE,MAAM,CAAC,cAAc,CAAC;IAC9B;;;;OAIG;IACH,QAAQ,CAAC,EAAE,MAAM,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;IAC7C,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB;;;;;OAKG;IACH,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,CAAC;CACvC;AAED,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,gBAAgB,EAAE,MAAM,CAAC;IACzB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED;;;;;;;GAOG;AACH,wBAAsB,UAAU,CAC9B,OAAO,EAAE,cAAc,GACtB,OAAO,CAAC,cAAc,CAAC,CAwFzB;AAgHD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,WAAW,EAAE,GAAG,MAAM,CA2B7D"}
|
package/dist/agent/session.js
CHANGED
|
@@ -80,7 +80,7 @@ export async function runSession(options) {
|
|
|
80
80
|
history,
|
|
81
81
|
approver: options.approver,
|
|
82
82
|
signal: options.signal,
|
|
83
|
-
onEvent: (event) => reportEvent(event, options),
|
|
83
|
+
onEvent: options.onEvent ?? ((event) => reportEvent(event, options)),
|
|
84
84
|
});
|
|
85
85
|
summary.turns += report.turns;
|
|
86
86
|
summary.modelRequests += report.modelRequests;
|
package/dist/commands/agent.d.ts
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
|
+
import { type ApprovalMode } from "../agent/approvals.js";
|
|
1
2
|
import { ExitCode } from "../output/exit-codes.js";
|
|
2
3
|
import { type CommandIo } from "./runtime.js";
|
|
4
|
+
export declare const READ_ONLY_PROMPT = "You are the Mafdet CLI agent working inside a user's workspace.\n\nUse the provided tools to inspect the workspace. You cannot modify anything:\nthere are no write or shell tools, so do not claim to have changed a file.\nRead before you conclude - never guess a file's contents. When you have the\nanswer, reply with it directly instead of calling another tool. Be concise.";
|
|
5
|
+
export declare const WRITE_PROMPT = "You are the Mafdet CLI agent working inside a user's workspace.\n\nInspect with the read tools, and change files with edit_file and create_file.\nAlways read a file before editing it, and quote old_text exactly as it appears,\nwith enough surrounding lines to be unique - a near miss is refused rather than\nguessed at. Every change is shown to the user and applied only if they accept\nit; if one is declined, do not retry the same change. There is no shell, so do\nnot claim to have run anything. Be concise.";
|
|
3
6
|
export interface AgentIo extends CommandIo {
|
|
4
7
|
signal?: AbortSignal;
|
|
5
8
|
/** Overridden in tests; production reads the TTY. */
|
|
@@ -7,4 +10,10 @@ export interface AgentIo extends CommandIo {
|
|
|
7
10
|
approver?: import("../agent/approvals.js").Approver;
|
|
8
11
|
}
|
|
9
12
|
export declare function agentCommand(argv: readonly string[], io: AgentIo): Promise<ExitCode>;
|
|
13
|
+
/**
|
|
14
|
+
* A tool the run cannot use is not offered at all. Read-only means the model
|
|
15
|
+
* never sees a write tool, and run_command appears only when the user named at
|
|
16
|
+
* least one allowed command or can approve interactively.
|
|
17
|
+
*/
|
|
18
|
+
export declare function buildToolset(mode: ApprovalMode, hasAllowedCommands: boolean): import("../agent/tools/types.js").ToolDefinition<import("zod").ZodType<unknown, unknown, import("zod/v4/core").$ZodTypeInternals<unknown, unknown>>>[];
|
|
10
19
|
//# sourceMappingURL=agent.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent.d.ts","sourceRoot":"","sources":["../../src/commands/agent.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"agent.d.ts","sourceRoot":"","sources":["../../src/commands/agent.ts"],"names":[],"mappings":"AAKA,OAAO,EAAe,KAAK,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAOvE,OAAO,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AAGnD,OAAO,EAIL,KAAK,SAAS,EACf,MAAM,cAAc,CAAC;AAatB,eAAO,MAAM,gBAAgB,0XAK+C,CAAC;AAE7E,eAAO,MAAM,YAAY,mgBAOmB,CAAC;AAE7C,MAAM,WAAW,OAAQ,SAAQ,SAAS;IACxC,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,qDAAqD;IACrD,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,QAAQ,CAAC,EAAE,OAAO,uBAAuB,EAAE,QAAQ,CAAC;CACrD;AAED,wBAAsB,YAAY,CAChC,IAAI,EAAE,SAAS,MAAM,EAAE,EACvB,EAAE,EAAE,OAAO,GACV,OAAO,CAAC,QAAQ,CAAC,CA+GnB;AAgFD;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,YAAY,EAAE,kBAAkB,EAAE,OAAO,0JAI3E"}
|
package/dist/commands/agent.js
CHANGED
|
@@ -20,13 +20,13 @@ and every change is shown as a diff and confirmed before it is written. There
|
|
|
20
20
|
is no flag that approves everything in advance, and a non-interactive run
|
|
21
21
|
cannot write at all.
|
|
22
22
|
`;
|
|
23
|
-
const READ_ONLY_PROMPT = `You are the Mafdet CLI agent working inside a user's workspace.
|
|
23
|
+
export const READ_ONLY_PROMPT = `You are the Mafdet CLI agent working inside a user's workspace.
|
|
24
24
|
|
|
25
25
|
Use the provided tools to inspect the workspace. You cannot modify anything:
|
|
26
26
|
there are no write or shell tools, so do not claim to have changed a file.
|
|
27
27
|
Read before you conclude - never guess a file's contents. When you have the
|
|
28
28
|
answer, reply with it directly instead of calling another tool. Be concise.`;
|
|
29
|
-
const WRITE_PROMPT = `You are the Mafdet CLI agent working inside a user's workspace.
|
|
29
|
+
export const WRITE_PROMPT = `You are the Mafdet CLI agent working inside a user's workspace.
|
|
30
30
|
|
|
31
31
|
Inspect with the read tools, and change files with edit_file and create_file.
|
|
32
32
|
Always read a file before editing it, and quote old_text exactly as it appears,
|
|
@@ -205,7 +205,7 @@ function parseArgs(argv, io) {
|
|
|
205
205
|
* never sees a write tool, and run_command appears only when the user named at
|
|
206
206
|
* least one allowed command or can approve interactively.
|
|
207
207
|
*/
|
|
208
|
-
function buildToolset(mode, hasAllowedCommands) {
|
|
208
|
+
export function buildToolset(mode, hasAllowedCommands) {
|
|
209
209
|
if (mode === "read-only" && !hasAllowedCommands)
|
|
210
210
|
return READ_ONLY_TOOLS;
|
|
211
211
|
if (mode === "read-only")
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAcA,OAAO,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAcA,OAAO,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AAgDlD,wBAAsB,GAAG,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG,OAAO,CAAC,QAAQ,CAAC,CAsGpE"}
|
package/dist/index.js
CHANGED
|
@@ -11,6 +11,7 @@ import { embedCommand } from "./commands/embed.js";
|
|
|
11
11
|
import { speechCommand } from "./commands/speech.js";
|
|
12
12
|
import { modelsCommand } from "./commands/models.js";
|
|
13
13
|
import { ExitCode } from "./output/exit-codes.js";
|
|
14
|
+
import { decideEntry, explainRefusal } from "./tui/route.js";
|
|
14
15
|
// Read from the installed package rather than baking a literal in at build
|
|
15
16
|
// time, so `mafdet --version` can never disagree with what npm installed.
|
|
16
17
|
function version() {
|
|
@@ -54,12 +55,8 @@ async function readStdin() {
|
|
|
54
55
|
}
|
|
55
56
|
export async function run(argv) {
|
|
56
57
|
const [command] = argv;
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
// stderr so a bare `mafdet` in a pipeline never pollutes stdout.
|
|
60
|
-
process.stderr.write(HELP);
|
|
61
|
-
return ExitCode.Usage;
|
|
62
|
-
}
|
|
58
|
+
// Asking for help or the version is always answered the same way, terminal
|
|
59
|
+
// or not. These come first so that neither can be swallowed by the TUI.
|
|
63
60
|
if (command === "help" || command === "--help" || command === "-h") {
|
|
64
61
|
process.stdout.write(HELP);
|
|
65
62
|
return ExitCode.Ok;
|
|
@@ -68,6 +65,48 @@ export async function run(argv) {
|
|
|
68
65
|
process.stdout.write(`${version()}\n`);
|
|
69
66
|
return ExitCode.Ok;
|
|
70
67
|
}
|
|
68
|
+
// CLI-018: a bare `mafdet` (or one carrying only flags) opens the TUI on an
|
|
69
|
+
// interactive terminal, and keeps its 0.3 behaviour everywhere else.
|
|
70
|
+
// `mafdet <command>` never reaches this branch, so the command surface and
|
|
71
|
+
// its exit codes are untouched.
|
|
72
|
+
if (command === undefined || command.startsWith("-")) {
|
|
73
|
+
const decision = decideEntry({
|
|
74
|
+
argv,
|
|
75
|
+
stdinIsTTY: process.stdin.isTTY === true,
|
|
76
|
+
stdoutIsTTY: process.stdout.isTTY === true,
|
|
77
|
+
env: process.env,
|
|
78
|
+
});
|
|
79
|
+
if (decision.kind === "tui") {
|
|
80
|
+
// Imported here, not at the top: the command path must not pay for
|
|
81
|
+
// loading the TUI, and `mafdet version` staying fast is the check.
|
|
82
|
+
const { runTui } = await import("./tui/app.js");
|
|
83
|
+
return runTui({
|
|
84
|
+
version: version(),
|
|
85
|
+
workspace: process.cwd(),
|
|
86
|
+
stdout: process.stdout,
|
|
87
|
+
stderr: process.stderr,
|
|
88
|
+
stdin: process.stdin,
|
|
89
|
+
env: process.env,
|
|
90
|
+
host: process,
|
|
91
|
+
columns: process.stdout.columns,
|
|
92
|
+
argv,
|
|
93
|
+
commandIo: {
|
|
94
|
+
stdout: (text) => process.stdout.write(text),
|
|
95
|
+
stderr: (text) => process.stderr.write(text),
|
|
96
|
+
env: process.env,
|
|
97
|
+
cwd: process.cwd(),
|
|
98
|
+
version: version(),
|
|
99
|
+
},
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
// Not an error the user asked for, but not a result either: usage goes to
|
|
103
|
+
// stderr so a bare `mafdet` in a pipeline never pollutes stdout.
|
|
104
|
+
process.stderr.write(HELP);
|
|
105
|
+
if (decision.kind === "usage") {
|
|
106
|
+
process.stderr.write(`\nmafdet: ${explainRefusal(decision.refusedBecause)}.\n`);
|
|
107
|
+
}
|
|
108
|
+
return ExitCode.Usage;
|
|
109
|
+
}
|
|
71
110
|
const io = {
|
|
72
111
|
stdout: (text) => process.stdout.write(text),
|
|
73
112
|
stderr: (text) => process.stderr.write(text),
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { type CommandIo } from "../../commands/runtime.js";
|
|
2
|
+
export interface KeyDiagnosis {
|
|
3
|
+
readonly ok: boolean;
|
|
4
|
+
/** Never the key itself. `sk-mafdet-live-<redacted>`, as everywhere else. */
|
|
5
|
+
readonly fingerprint: string;
|
|
6
|
+
readonly modelCount: number;
|
|
7
|
+
/** Undefined when account:read was not granted - not an error. */
|
|
8
|
+
readonly balance?: string;
|
|
9
|
+
/** Present when account:read is missing, so the UI can say so once. */
|
|
10
|
+
readonly missingAccountRead: boolean;
|
|
11
|
+
/** Set when the key does not work at all. Already redacted. */
|
|
12
|
+
readonly problem?: string;
|
|
13
|
+
}
|
|
14
|
+
export interface DiagnoseOptions {
|
|
15
|
+
readonly apiKey: string;
|
|
16
|
+
readonly io: CommandIo;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Verify a key with the cheapest calls that prove it works.
|
|
20
|
+
*
|
|
21
|
+
* Deliberately never a model completion: asking a model to prove a key is
|
|
22
|
+
* valid spends the user's money to learn something a catalogue read already
|
|
23
|
+
* tells us.
|
|
24
|
+
*/
|
|
25
|
+
export declare function diagnoseKey(options: DiagnoseOptions): Promise<KeyDiagnosis>;
|
|
26
|
+
//# sourceMappingURL=auth.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../../src/tui/adapters/auth.ts"],"names":[],"mappings":"AAUA,OAAO,EAAgB,KAAK,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAIzE,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,EAAE,EAAE,OAAO,CAAC;IACrB,6EAA6E;IAC7E,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,kEAAkE;IAClE,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,uEAAuE;IACvE,QAAQ,CAAC,kBAAkB,EAAE,OAAO,CAAC;IACrC,+DAA+D;IAC/D,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,EAAE,EAAE,SAAS,CAAC;CACxB;AAED;;;;;;GAMG;AACH,wBAAsB,WAAW,CAC/B,OAAO,EAAE,eAAe,GACvB,OAAO,CAAC,YAAY,CAAC,CA4CvB"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
// CLI-019 · Checking a key, using the machinery that already exists.
|
|
2
|
+
//
|
|
3
|
+
// The TUI owns no API client and no idea of what a valid key is. It calls the
|
|
4
|
+
// same two planes `doctor` does, and it reaches them by building a runtime
|
|
5
|
+
// over an env object it constructs - never by writing to process.env, so a
|
|
6
|
+
// session-only key cannot leak into a child process or a later read.
|
|
7
|
+
import { ApiError } from "../../api/errors.js";
|
|
8
|
+
import { fetchAccessibleModels } from "../../api/models.js";
|
|
9
|
+
import { fetchWallet } from "../../api/account.js";
|
|
10
|
+
import { buildRuntime } from "../../commands/runtime.js";
|
|
11
|
+
import { formatUsd } from "../../output/money.js";
|
|
12
|
+
import { keyFingerprint } from "../../security/redact.js";
|
|
13
|
+
/**
|
|
14
|
+
* Verify a key with the cheapest calls that prove it works.
|
|
15
|
+
*
|
|
16
|
+
* Deliberately never a model completion: asking a model to prove a key is
|
|
17
|
+
* valid spends the user's money to learn something a catalogue read already
|
|
18
|
+
* tells us.
|
|
19
|
+
*/
|
|
20
|
+
export async function diagnoseKey(options) {
|
|
21
|
+
const fingerprint = keyFingerprint(options.apiKey);
|
|
22
|
+
// A constructed env, not process.env: the key stays inside this call.
|
|
23
|
+
const runtime = buildRuntime({
|
|
24
|
+
...options.io,
|
|
25
|
+
env: { ...options.io.env, MAFDET_API_KEY: options.apiKey },
|
|
26
|
+
});
|
|
27
|
+
let modelCount = 0;
|
|
28
|
+
try {
|
|
29
|
+
const models = await fetchAccessibleModels(runtime.dataPlane);
|
|
30
|
+
modelCount = models.length;
|
|
31
|
+
}
|
|
32
|
+
catch (error) {
|
|
33
|
+
return {
|
|
34
|
+
ok: false,
|
|
35
|
+
fingerprint,
|
|
36
|
+
modelCount: 0,
|
|
37
|
+
missingAccountRead: false,
|
|
38
|
+
problem: describeAuthFailure(error),
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
// account:read is optional. Without it model calls still work, so its
|
|
42
|
+
// absence downgrades the display and nothing else.
|
|
43
|
+
try {
|
|
44
|
+
const wallet = await fetchWallet(runtime.accountPlane);
|
|
45
|
+
return {
|
|
46
|
+
ok: true,
|
|
47
|
+
fingerprint,
|
|
48
|
+
modelCount,
|
|
49
|
+
balance: formatUsd(wallet.available_micro_usd),
|
|
50
|
+
missingAccountRead: false,
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
catch (error) {
|
|
54
|
+
const scopeProblem = error instanceof ApiError && error.kind === "auth";
|
|
55
|
+
return {
|
|
56
|
+
ok: true,
|
|
57
|
+
fingerprint,
|
|
58
|
+
modelCount,
|
|
59
|
+
missingAccountRead: scopeProblem,
|
|
60
|
+
problem: scopeProblem ? undefined : describeAuthFailure(error),
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* A sentence for the welcome page. ApiError redacts on construction, so this
|
|
66
|
+
* cannot reintroduce a key that the error was carrying.
|
|
67
|
+
*/
|
|
68
|
+
function describeAuthFailure(error) {
|
|
69
|
+
if (error instanceof ApiError) {
|
|
70
|
+
if (error.kind === "auth") {
|
|
71
|
+
return "the key was rejected - check it was copied whole, and that it is not revoked";
|
|
72
|
+
}
|
|
73
|
+
return error.message;
|
|
74
|
+
}
|
|
75
|
+
return error instanceof Error ? error.message : String(error);
|
|
76
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { type ModelSets, type ResolvedModel } from "../../api/models.js";
|
|
2
|
+
import { type CommandIo } from "../../commands/runtime.js";
|
|
3
|
+
/**
|
|
4
|
+
* The catalogue does not publish a per-route RPM - checked against the live
|
|
5
|
+
* `/models` response, which has 31 models and no rate field at all. Plan §19.5
|
|
6
|
+
* says to show `unknown` rather than guess from the model id, so this constant
|
|
7
|
+
* exists to make the absence explicit instead of quietly dropping the column.
|
|
8
|
+
*/
|
|
9
|
+
export declare const ROUTE_RPM_AVAILABLE = false;
|
|
10
|
+
export interface ModelCatalogue extends ModelSets {
|
|
11
|
+
/** Callable, described, chat-surface models: what the picker lists. */
|
|
12
|
+
readonly chat: readonly ResolvedModel[];
|
|
13
|
+
/** Of those, the ones the agent is allowed to drive. */
|
|
14
|
+
readonly agentReady: readonly ResolvedModel[];
|
|
15
|
+
}
|
|
16
|
+
export declare function loadCatalogue(options: {
|
|
17
|
+
readonly apiKey: string;
|
|
18
|
+
readonly io: CommandIo;
|
|
19
|
+
}): Promise<ModelCatalogue>;
|
|
20
|
+
/** One line of facts under a model's name. Only what the catalogue states. */
|
|
21
|
+
export declare function describeModel(model: ResolvedModel): string;
|
|
22
|
+
/**
|
|
23
|
+
* Filter by a typed query. Matches the id, the display name, the provider and
|
|
24
|
+
* the capabilities, so "tool", "deepseek" and "flash" all narrow the list the
|
|
25
|
+
* way a user would expect.
|
|
26
|
+
*/
|
|
27
|
+
export declare function filterModels(models: readonly ResolvedModel[], query: string): readonly ResolvedModel[];
|
|
28
|
+
export interface SaveResult {
|
|
29
|
+
readonly saved: boolean;
|
|
30
|
+
/** Shown to the user: they should know where a preference landed. */
|
|
31
|
+
readonly path: string;
|
|
32
|
+
readonly problem?: string;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Remember a default model in the user config.
|
|
36
|
+
*
|
|
37
|
+
* Only `model` is written, and the existing file is re-validated on the way
|
|
38
|
+
* through, so this can never introduce a credential or an endpoint into a file
|
|
39
|
+
* that is not allowed to carry one. The write is atomic: a crash must not
|
|
40
|
+
* leave a half-written config that the next run refuses to parse.
|
|
41
|
+
*/
|
|
42
|
+
export declare function saveDefaultModel(options: {
|
|
43
|
+
readonly modelId: string;
|
|
44
|
+
readonly env: NodeJS.ProcessEnv;
|
|
45
|
+
readonly configPath?: string;
|
|
46
|
+
}): SaveResult;
|
|
47
|
+
//# sourceMappingURL=models.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"models.d.ts","sourceRoot":"","sources":["../../../src/tui/adapters/models.ts"],"names":[],"mappings":"AAiBA,OAAO,EAIL,KAAK,SAAS,EACd,KAAK,aAAa,EACnB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAgB,KAAK,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAKzE;;;;;GAKG;AACH,eAAO,MAAM,mBAAmB,QAAQ,CAAC;AAEzC,MAAM,WAAW,cAAe,SAAQ,SAAS;IAC/C,uEAAuE;IACvE,QAAQ,CAAC,IAAI,EAAE,SAAS,aAAa,EAAE,CAAC;IACxC,wDAAwD;IACxD,QAAQ,CAAC,UAAU,EAAE,SAAS,aAAa,EAAE,CAAC;CAC/C;AAED,wBAAsB,aAAa,CAAC,OAAO,EAAE;IAC3C,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,EAAE,EAAE,SAAS,CAAC;CACxB,GAAG,OAAO,CAAC,cAAc,CAAC,CAoB1B;AAED,8EAA8E;AAC9E,wBAAgB,aAAa,CAAC,KAAK,EAAE,aAAa,GAAG,MAAM,CAkB1D;AASD;;;;GAIG;AACH,wBAAgB,YAAY,CAC1B,MAAM,EAAE,SAAS,aAAa,EAAE,EAChC,KAAK,EAAE,MAAM,GACZ,SAAS,aAAa,EAAE,CAgB1B;AAED,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;IACxB,qEAAqE;IACrE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE;IACxC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC,UAAU,CAAC;IAChC,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;CAC9B,GAAG,UAAU,CA8Cb"}
|