@nyte-ai/plugin 0.0.0-stage → 0.0.18
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/LICENSE +21 -0
- package/THIRD-PARTY-NOTICES.md +800 -0
- package/dist/chunks/billing-0y7dfkp2.js +146 -0
- package/dist/chunks/billing-2v3g7rd9.js +190 -0
- package/dist/chunks/billing-3j77ss7y.js +86 -0
- package/dist/chunks/billing-3scqmkzb.js +559 -0
- package/dist/chunks/billing-6z2kgtyt.js +51 -0
- package/dist/chunks/billing-8rjk35gr.js +444 -0
- package/dist/chunks/billing-9mfedmsh.js +373 -0
- package/dist/chunks/billing-9nn3yp18.js +176 -0
- package/dist/chunks/billing-9qc0eqh4.js +174 -0
- package/dist/chunks/billing-a9vqn66p.js +351 -0
- package/dist/chunks/billing-bv5zr32b.js +369 -0
- package/dist/chunks/billing-cy1rg619.js +302 -0
- package/dist/chunks/billing-ejx2hv52.js +323 -0
- package/dist/chunks/billing-h13r0byk.js +80 -0
- package/dist/chunks/billing-j643d12p.js +197 -0
- package/dist/chunks/billing-k2p1t25n.js +109 -0
- package/dist/chunks/billing-kn3d30b4.js +276 -0
- package/dist/chunks/billing-mvc33pv6.js +36 -0
- package/dist/chunks/billing-s4rrspsk.js +7 -0
- package/dist/chunks/billing-svrhh5a5.js +307 -0
- package/dist/chunks/billing-sxc70w72.js +161 -0
- package/dist/chunks/billing-t1qrxe16.js +41 -0
- package/dist/chunks/billing-tzr3cebf.js +20 -0
- package/dist/chunks/billing-wmcbg6fw.js +52 -0
- package/dist/chunks/billing-wmkxkypm.js +527 -0
- package/dist/chunks/billing-ye3wk5r3.js +205 -0
- package/dist/chunks/billing-zfpm2rt0.js +29 -0
- package/dist/examples/claude-code/LICENSE +21 -0
- package/dist/examples/claude-code/billing.d.ts +7 -0
- package/dist/examples/claude-code/billing.js +11 -0
- package/dist/examples/claude-code/claude-cli.d.ts +35 -0
- package/dist/examples/claude-code/claude-cli.js +15 -0
- package/dist/examples/claude-code/env.d.ts +1 -0
- package/dist/examples/claude-code/env.js +6 -0
- package/dist/examples/claude-code/index.d.ts +24 -0
- package/dist/examples/claude-code/index.js +149 -0
- package/dist/examples/claude-code/inert-mcp.d.ts +1 -0
- package/dist/examples/claude-code/inert-mcp.js +6 -0
- package/dist/examples/claude-code/model-catalog.d.ts +27 -0
- package/dist/examples/claude-code/model-catalog.js +12 -0
- package/dist/examples/claude-code/process.d.ts +22 -0
- package/dist/examples/claude-code/process.js +25 -0
- package/dist/examples/claude-code/replay.d.ts +4 -0
- package/dist/examples/claude-code/replay.js +11 -0
- package/dist/examples/claude-code/stream.d.ts +3 -0
- package/dist/examples/claude-code/stream.js +16 -0
- package/dist/examples/claude-code/transcript.d.ts +83 -0
- package/dist/examples/claude-code/transcript.js +23 -0
- package/dist/examples/claude-code/turn-relay.d.ts +48 -0
- package/dist/examples/claude-code/turn-relay.js +9 -0
- package/dist/examples/claude-code/wire.d.ts +372 -0
- package/dist/examples/claude-code/wire.js +18 -0
- package/dist/src/acp/connection.d.ts +24 -0
- package/dist/src/acp/connection.js +8 -0
- package/dist/src/acp/index.d.ts +54 -0
- package/dist/src/acp/index.js +1004 -0
- package/dist/src/acp/registry.d.ts +18 -0
- package/dist/src/acp/registry.js +8 -0
- package/dist/src/acp/thread.d.ts +46 -0
- package/dist/src/acp/thread.js +7 -0
- package/dist/src/acp/transcript.d.ts +8 -0
- package/dist/src/acp/transcript.js +11 -0
- package/dist/src/acp/translate.d.ts +33 -0
- package/dist/src/acp/translate.js +20 -0
- package/dist/src/approvals/approvals.d.ts +189 -0
- package/dist/src/approvals/approvals.js +143 -0
- package/dist/src/approvals/schema.d.ts +169 -0
- package/dist/src/approvals/schema.js +18 -0
- package/dist/src/bash-description.d.ts +30 -0
- package/dist/src/bash-description.js +18 -0
- package/dist/src/browser-tools.d.ts +25 -0
- package/dist/src/browser-tools.js +246 -0
- package/dist/src/canvas/canvas-compile.d.ts +48 -0
- package/dist/src/canvas/canvas-compile.js +8 -0
- package/dist/src/canvas/canvas-libraries.d.ts +32 -0
- package/dist/src/canvas/canvas-libraries.js +6 -0
- package/dist/src/canvas/canvas-preview.d.ts +107 -0
- package/dist/src/canvas/canvas-preview.js +12 -0
- package/dist/src/canvas/canvas-protocol.d.ts +184 -0
- package/dist/src/canvas/canvas-protocol.js +75 -0
- package/dist/src/canvas/canvas.d.ts +50 -0
- package/dist/src/canvas/canvas.js +221 -0
- package/dist/src/canvas/schema.d.ts +47 -0
- package/dist/src/canvas/schema.js +8 -0
- package/dist/src/claude-code-sdk/index.d.ts +35 -0
- package/dist/src/claude-code-sdk/index.js +368 -0
- package/dist/src/claude-code-sdk/session.d.ts +48 -0
- package/dist/src/claude-code-sdk/session.js +7 -0
- package/dist/src/claude-code-sdk/transcript.d.ts +19 -0
- package/dist/src/claude-code-sdk/transcript.js +15 -0
- package/dist/src/claude-code-sdk/translate.d.ts +18 -0
- package/dist/src/claude-code-sdk/translate.js +20 -0
- package/dist/src/client/mount.d.ts +44 -0
- package/dist/src/client/mount.js +252 -0
- package/dist/src/client/notifications.d.ts +35 -0
- package/dist/src/client/notifications.js +26 -0
- package/dist/src/client/presentation.d.ts +336 -0
- package/dist/src/client/presentation.js +373 -0
- package/dist/src/client/transcript-tui.d.ts +23 -0
- package/dist/src/client/transcript-tui.js +20 -0
- package/dist/src/client/transcript.d.ts +23 -0
- package/dist/src/client/transcript.js +51 -0
- package/dist/src/client.d.ts +53 -0
- package/dist/src/client.js +22 -0
- package/dist/src/codemode-runtime.d.ts +11 -0
- package/dist/src/codemode-runtime.js +10 -0
- package/dist/src/codemode-worker.d.ts +1 -0
- package/dist/src/codemode-worker.js +2 -0
- package/dist/src/codemode.d.ts +21 -0
- package/dist/src/codemode.js +170 -0
- package/dist/src/core.d.ts +43 -0
- package/dist/src/core.js +11 -0
- package/dist/src/openai-astra-context.d.ts +23 -0
- package/dist/src/openai-astra-context.js +14 -0
- package/dist/src/openai-compaction.d.ts +15 -0
- package/dist/src/openai-compaction.js +55 -0
- package/dist/src/question/client/questions-tui.d.ts +9 -0
- package/dist/src/question/client/questions-tui.js +19 -0
- package/dist/src/question/client/questions.d.ts +9 -0
- package/dist/src/question/client/questions.js +160 -0
- package/dist/src/question/question.d.ts +63 -0
- package/dist/src/question/question.js +9 -0
- package/dist/src/question/schema.d.ts +101 -0
- package/dist/src/question/schema.js +14 -0
- package/dist/src/rename.d.ts +78 -0
- package/dist/src/rename.js +78 -0
- package/dist/src/telemetry.d.ts +36 -0
- package/dist/src/telemetry.js +84 -0
- package/dist/src/web-search.d.ts +78 -0
- package/dist/src/web-search.js +219 -0
- package/package.json +190 -3
- package/README.md +0 -3
|
@@ -0,0 +1,373 @@
|
|
|
1
|
+
// src/client/presentation.ts
|
|
2
|
+
import { isPart, text, thinking, tool } from "@nyte-ai/core";
|
|
3
|
+
function showsTool(message) {
|
|
4
|
+
return isPart(message, tool);
|
|
5
|
+
}
|
|
6
|
+
function showsText(message) {
|
|
7
|
+
return isPart(message, text);
|
|
8
|
+
}
|
|
9
|
+
function showsThinking(message) {
|
|
10
|
+
return isPart(message, thinking);
|
|
11
|
+
}
|
|
12
|
+
function readRawPart(message) {
|
|
13
|
+
const { state } = message;
|
|
14
|
+
if (typeof state === "object" && state !== null && !Array.isArray(state)) {
|
|
15
|
+
const prose = "markdown" in state ? state.markdown : ("text" in state) ? state.text : undefined;
|
|
16
|
+
if (typeof prose === "string")
|
|
17
|
+
return { format: "text", body: prose };
|
|
18
|
+
}
|
|
19
|
+
return { format: "json", body: state === undefined ? "null" : JSON.stringify(state, null, 2) };
|
|
20
|
+
}
|
|
21
|
+
function showsReport(message) {
|
|
22
|
+
return message.source.kind === "child" || message.source.kind === "job";
|
|
23
|
+
}
|
|
24
|
+
function shownContent(message) {
|
|
25
|
+
return message.source.kind === "action" ? message.source.label : message.content;
|
|
26
|
+
}
|
|
27
|
+
var RUNNING = { tense: "running", tone: "running", word: undefined };
|
|
28
|
+
function toolStatus(message) {
|
|
29
|
+
const { state, status } = message;
|
|
30
|
+
if (state.phase !== "settled") {
|
|
31
|
+
if (status.kind === "failed")
|
|
32
|
+
return status.failure.class === "aborted" ? { tense: "none", tone: "stopped", word: "Stopped" } : { tense: "none", tone: "stopped", word: "Interrupted" };
|
|
33
|
+
if (status.kind === "waiting" && status.on.kind === "part")
|
|
34
|
+
return { tense: "running", tone: "attention", word: "Needs input" };
|
|
35
|
+
return RUNNING;
|
|
36
|
+
}
|
|
37
|
+
switch (state.outcome.kind) {
|
|
38
|
+
case "ok":
|
|
39
|
+
return { tense: "past", tone: "success", word: undefined };
|
|
40
|
+
case "failed":
|
|
41
|
+
return { tense: "none", tone: "failure", word: "Failed" };
|
|
42
|
+
case "rejected":
|
|
43
|
+
return { tense: "none", tone: "failure", word: "Blocked" };
|
|
44
|
+
case "stopped":
|
|
45
|
+
return { tense: "none", tone: "stopped", word: "Stopped" };
|
|
46
|
+
case "interrupted":
|
|
47
|
+
return { tense: "none", tone: "stopped", word: "Interrupted" };
|
|
48
|
+
default: {
|
|
49
|
+
const _exhaustive = state.outcome;
|
|
50
|
+
return _exhaustive;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
function toolOutput(state) {
|
|
55
|
+
if (state.phase !== "settled")
|
|
56
|
+
return "";
|
|
57
|
+
switch (state.outcome.kind) {
|
|
58
|
+
case "ok":
|
|
59
|
+
return state.outcome.content.flatMap((content) => content.kind === "text" && content.text !== "" ? [content.text] : []).join(`
|
|
60
|
+
`);
|
|
61
|
+
case "failed":
|
|
62
|
+
return state.outcome.message;
|
|
63
|
+
case "rejected":
|
|
64
|
+
return state.outcome.reason;
|
|
65
|
+
case "stopped":
|
|
66
|
+
case "interrupted":
|
|
67
|
+
return "";
|
|
68
|
+
default: {
|
|
69
|
+
const _exhaustive = state.outcome;
|
|
70
|
+
return _exhaustive;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
function executionMark(execution) {
|
|
75
|
+
switch (execution?.kind) {
|
|
76
|
+
case undefined:
|
|
77
|
+
return "idle";
|
|
78
|
+
case "idle":
|
|
79
|
+
return execution.lastRun?.end.kind === "failed" ? "failed" : "idle";
|
|
80
|
+
case "live":
|
|
81
|
+
return "working";
|
|
82
|
+
case "waiting":
|
|
83
|
+
return execution.on.kind === "part" ? "waiting" : "working";
|
|
84
|
+
case "retrying":
|
|
85
|
+
return "retry";
|
|
86
|
+
default: {
|
|
87
|
+
const _exhaustive = execution;
|
|
88
|
+
return _exhaustive;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
function mainHead(session) {
|
|
93
|
+
return session.heads.find((head) => head.name === "main") ?? session.heads[0];
|
|
94
|
+
}
|
|
95
|
+
function sessionMark(session) {
|
|
96
|
+
return executionMark(mainHead(session)?.execution);
|
|
97
|
+
}
|
|
98
|
+
var COMMAND_ARGUMENT = /^[ \t]*\/([a-z0-9][a-z0-9-]*)[ \t]+/u;
|
|
99
|
+
function findCommandArgument(value, cursor) {
|
|
100
|
+
const found = COMMAND_ARGUMENT.exec(value);
|
|
101
|
+
const command = found?.[1];
|
|
102
|
+
if (found === null || command === undefined || /[\r\n]/u.test(value))
|
|
103
|
+
return;
|
|
104
|
+
const start = found[0].length;
|
|
105
|
+
return cursor < start ? undefined : { command, start, query: value.slice(start, cursor) };
|
|
106
|
+
}
|
|
107
|
+
function completionTrigger(value, cursor = value.length) {
|
|
108
|
+
const caret = Math.max(0, Math.min(cursor, value.length));
|
|
109
|
+
let start = caret;
|
|
110
|
+
while (start > 0 && (value[start - 1] ?? "").trim() !== "")
|
|
111
|
+
start -= 1;
|
|
112
|
+
const kind = value[start];
|
|
113
|
+
if (start === caret || kind !== "@" && kind !== "/")
|
|
114
|
+
return;
|
|
115
|
+
let end = caret;
|
|
116
|
+
while (end < value.length && (value[end] ?? "").trim() !== "")
|
|
117
|
+
end += 1;
|
|
118
|
+
return { kind, start, end, query: value.slice(start + 1, caret) };
|
|
119
|
+
}
|
|
120
|
+
var RAN = { running: "Running", past: "Ran" };
|
|
121
|
+
var CLASS_VERBS = {
|
|
122
|
+
read: { running: "Reading", past: "Read" },
|
|
123
|
+
list: { running: "Listing", past: "Listed" },
|
|
124
|
+
edit: { running: "Editing", past: "Edited" },
|
|
125
|
+
shell: RAN
|
|
126
|
+
};
|
|
127
|
+
var DELEGATE_VERBS = {
|
|
128
|
+
task: { running: "Delegating", past: "Delegated" },
|
|
129
|
+
create: { running: "Creating", past: "Created" },
|
|
130
|
+
send: { running: "Messaging", past: "Messaged" },
|
|
131
|
+
await: { running: "Waiting on", past: "Waited on" },
|
|
132
|
+
read: { running: "Reading transcript", past: "Read transcript" },
|
|
133
|
+
stop: { running: "Stopping", past: "Stopped" }
|
|
134
|
+
};
|
|
135
|
+
var DELEGATE_NOUNS = {
|
|
136
|
+
task: "agent",
|
|
137
|
+
create: "agent",
|
|
138
|
+
send: "message",
|
|
139
|
+
await: "wait",
|
|
140
|
+
read: "transcript",
|
|
141
|
+
stop: "stop"
|
|
142
|
+
};
|
|
143
|
+
var NAMED_TOOLS = new Map([
|
|
144
|
+
["codemode", { verbs: { running: "Running script", past: "Ran script" } }],
|
|
145
|
+
["tool_search", { verbs: { running: "Exploring", past: "Explored" }, detail: "available tools" }],
|
|
146
|
+
["websearch", { verbs: { running: "Searching web", past: "Searched web" } }],
|
|
147
|
+
["web_search", { verbs: { running: "Searching web", past: "Searched web" } }],
|
|
148
|
+
["webfetch", { verbs: { running: "Fetching page", past: "Fetched page" } }],
|
|
149
|
+
["web_fetch", { verbs: { running: "Fetching page", past: "Fetched page" } }],
|
|
150
|
+
["rename_chat", { verbs: { running: "Renaming chat", past: "Renamed chat" } }],
|
|
151
|
+
["browser_open", { verbs: { running: "Opening page", past: "Opened page" } }],
|
|
152
|
+
["browser_click", { verbs: { running: "Clicking", past: "Clicked" } }],
|
|
153
|
+
["browser_type", { verbs: { running: "Typing", past: "Typed" } }],
|
|
154
|
+
["browser_press", { verbs: { running: "Pressing key", past: "Pressed key" } }],
|
|
155
|
+
["browser_scroll", { verbs: { running: "Scrolling", past: "Scrolled" } }],
|
|
156
|
+
["browser_wait", { verbs: { running: "Waiting", past: "Waited" } }],
|
|
157
|
+
["browser_snapshot", { verbs: { running: "Taking snapshot", past: "Took snapshot" } }],
|
|
158
|
+
[
|
|
159
|
+
"browser_console",
|
|
160
|
+
{ verbs: { running: "Checking console logs", past: "Checked console logs" } }
|
|
161
|
+
],
|
|
162
|
+
["browser_evaluate", { verbs: { running: "Executing JS", past: "Executed JS" } }]
|
|
163
|
+
]);
|
|
164
|
+
var MCP_LABEL = /^(?<server>[^:\s]+): (?<name>\S+)$/u;
|
|
165
|
+
var MCP_NAME = /^mcp__(?<server>.+?)__(?<name>.+)$/u;
|
|
166
|
+
function customTool(label) {
|
|
167
|
+
const named = NAMED_TOOLS.get(label);
|
|
168
|
+
if (named !== undefined)
|
|
169
|
+
return named;
|
|
170
|
+
const mcp = (MCP_LABEL.exec(label) ?? MCP_NAME.exec(label))?.groups;
|
|
171
|
+
if (mcp?.server !== undefined && mcp.name !== undefined)
|
|
172
|
+
return { verbs: RAN, name: mcp.name, server: mcp.server };
|
|
173
|
+
if (/\s/u.test(label))
|
|
174
|
+
return { verbs: { running: label, past: label } };
|
|
175
|
+
return { verbs: RAN, name: label };
|
|
176
|
+
}
|
|
177
|
+
function customDetail(custom) {
|
|
178
|
+
if (custom.name === undefined)
|
|
179
|
+
return custom.detail;
|
|
180
|
+
return custom.server === undefined ? custom.name : `${custom.name} in ${custom.server}`;
|
|
181
|
+
}
|
|
182
|
+
function toolVerbs(toolClass) {
|
|
183
|
+
switch (toolClass.kind) {
|
|
184
|
+
case "read":
|
|
185
|
+
case "list":
|
|
186
|
+
case "edit":
|
|
187
|
+
case "shell":
|
|
188
|
+
return CLASS_VERBS[toolClass.kind];
|
|
189
|
+
case "delegate":
|
|
190
|
+
return DELEGATE_VERBS[toolClass.role];
|
|
191
|
+
case "custom":
|
|
192
|
+
return customTool(toolClass.label).verbs;
|
|
193
|
+
default: {
|
|
194
|
+
const _exhaustive = toolClass;
|
|
195
|
+
return _exhaustive;
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
function toolNoun(toolClass) {
|
|
200
|
+
switch (toolClass.kind) {
|
|
201
|
+
case "read":
|
|
202
|
+
case "list":
|
|
203
|
+
case "edit":
|
|
204
|
+
return toolClass.kind;
|
|
205
|
+
case "delegate":
|
|
206
|
+
return DELEGATE_NOUNS[toolClass.role];
|
|
207
|
+
case "shell":
|
|
208
|
+
case "custom":
|
|
209
|
+
return;
|
|
210
|
+
default: {
|
|
211
|
+
const _exhaustive = toolClass;
|
|
212
|
+
return _exhaustive;
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
function delegateSubject(toolClass) {
|
|
217
|
+
return toolClass.title ?? "subagent";
|
|
218
|
+
}
|
|
219
|
+
function toolSubject(toolClass) {
|
|
220
|
+
switch (toolClass.kind) {
|
|
221
|
+
case "read":
|
|
222
|
+
case "list":
|
|
223
|
+
case "edit":
|
|
224
|
+
return toolClass.path;
|
|
225
|
+
case "shell":
|
|
226
|
+
return toolClass.command;
|
|
227
|
+
case "delegate":
|
|
228
|
+
return delegateSubject(toolClass);
|
|
229
|
+
case "custom":
|
|
230
|
+
return customDetail(customTool(toolClass.label));
|
|
231
|
+
default: {
|
|
232
|
+
const _exhaustive = toolClass;
|
|
233
|
+
return _exhaustive;
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
function toolTitle(toolClass, tense, subject = toolSubject(toolClass)) {
|
|
238
|
+
if (tense !== "none") {
|
|
239
|
+
const verb = toolVerbs(toolClass)[tense];
|
|
240
|
+
return subject === undefined ? verb : `${verb} ${subject}`;
|
|
241
|
+
}
|
|
242
|
+
if (toolClass.kind === "custom" && customTool(toolClass.label).name === undefined)
|
|
243
|
+
return toolClass.label;
|
|
244
|
+
return [subject, toolNoun(toolClass)].filter((word) => word !== undefined).join(" ");
|
|
245
|
+
}
|
|
246
|
+
function tidyPath(path, cwd) {
|
|
247
|
+
if (cwd !== undefined && path.startsWith(`${cwd}/`))
|
|
248
|
+
return path.slice(cwd.length + 1);
|
|
249
|
+
return path;
|
|
250
|
+
}
|
|
251
|
+
function basename(path) {
|
|
252
|
+
return path.split(/[\\/]/u).at(-1) ?? path;
|
|
253
|
+
}
|
|
254
|
+
function placeName(path, cwd) {
|
|
255
|
+
const tidy = tidyPath(path, cwd);
|
|
256
|
+
if (tidy === "." || tidy === "./" || tidy === cwd)
|
|
257
|
+
return basename(cwd ?? tidy) || tidy;
|
|
258
|
+
return basename(tidy.replace(/[\\/]+$/u, "")) || tidy;
|
|
259
|
+
}
|
|
260
|
+
function condensedCommand(command, cwd) {
|
|
261
|
+
const compact = command.replaceAll(/\s+/gu, " ").trim();
|
|
262
|
+
if (cwd === undefined)
|
|
263
|
+
return compact;
|
|
264
|
+
const prefix = [cwd, `"${cwd}"`, `'${cwd}'`].flatMap((dir) => [`cd ${dir} && `, `cd ${dir}; `]).find((candidate) => compact.startsWith(candidate));
|
|
265
|
+
return prefix === undefined ? compact : compact.slice(prefix.length);
|
|
266
|
+
}
|
|
267
|
+
function formatDuration(ms) {
|
|
268
|
+
const seconds = Math.max(0, ms) / 1000;
|
|
269
|
+
if (seconds < 10)
|
|
270
|
+
return `${seconds.toFixed(1)}s`;
|
|
271
|
+
if (seconds < 60)
|
|
272
|
+
return `${String(Math.floor(seconds))}s`;
|
|
273
|
+
const minutes = Math.floor(seconds / 60);
|
|
274
|
+
if (minutes < 60)
|
|
275
|
+
return `${String(minutes)}m ${String(Math.floor(seconds % 60))}s`;
|
|
276
|
+
return `${String(Math.floor(minutes / 60))}h ${String(minutes % 60)}m`;
|
|
277
|
+
}
|
|
278
|
+
function formatWholeDuration(ms) {
|
|
279
|
+
const seconds = Math.max(0, Math.round(ms / 1000));
|
|
280
|
+
const minutes = Math.floor(seconds / 60);
|
|
281
|
+
const hours = Math.floor(minutes / 60);
|
|
282
|
+
if (hours > 0)
|
|
283
|
+
return minutes % 60 === 0 ? `${String(hours)}h` : `${String(hours)}h ${String(minutes % 60)}m`;
|
|
284
|
+
if (minutes > 0)
|
|
285
|
+
return seconds % 60 === 0 ? `${String(minutes)}m` : `${String(minutes)}m ${String(seconds % 60)}s`;
|
|
286
|
+
return `${String(seconds)}s`;
|
|
287
|
+
}
|
|
288
|
+
function toolDetail(toolClass, cwd) {
|
|
289
|
+
switch (toolClass.kind) {
|
|
290
|
+
case "edit": {
|
|
291
|
+
const title = tidyPath(toolClass.path, cwd);
|
|
292
|
+
return { text: basename(title), title };
|
|
293
|
+
}
|
|
294
|
+
case "read":
|
|
295
|
+
case "list":
|
|
296
|
+
return { text: placeName(toolClass.path, cwd), title: tidyPath(toolClass.path, cwd) };
|
|
297
|
+
case "shell":
|
|
298
|
+
return { text: condensedCommand(toolClass.command, cwd) };
|
|
299
|
+
case "delegate":
|
|
300
|
+
return { text: delegateSubject(toolClass) };
|
|
301
|
+
case "custom": {
|
|
302
|
+
const detail = customDetail(customTool(toolClass.label));
|
|
303
|
+
return detail === undefined ? undefined : { text: detail };
|
|
304
|
+
}
|
|
305
|
+
default: {
|
|
306
|
+
const _exhaustive = toolClass;
|
|
307
|
+
return _exhaustive;
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
var NOTICE_LIMIT = 180;
|
|
312
|
+
function oneLine(message) {
|
|
313
|
+
const compact = message.replaceAll(/\s+/gu, " ").trim();
|
|
314
|
+
if (compact === "")
|
|
315
|
+
return;
|
|
316
|
+
return compact.length <= NOTICE_LIMIT ? compact : `${compact.slice(0, NOTICE_LIMIT - 1).trimEnd()}…`;
|
|
317
|
+
}
|
|
318
|
+
function danger(notice, recovery) {
|
|
319
|
+
return { text: notice, tone: "danger", recovery };
|
|
320
|
+
}
|
|
321
|
+
function failureNotice(failure) {
|
|
322
|
+
switch (failure.class) {
|
|
323
|
+
case "aborted":
|
|
324
|
+
return { text: "Run stopped.", tone: "neutral", recovery: undefined };
|
|
325
|
+
case "rate_limit":
|
|
326
|
+
return danger("Rate limit reached. Try again shortly.");
|
|
327
|
+
case "context_window":
|
|
328
|
+
return danger("This chat no longer fits the model's context window.", "compact");
|
|
329
|
+
case "quota":
|
|
330
|
+
return danger("Provider quota reached.", "switch-model");
|
|
331
|
+
case "auth":
|
|
332
|
+
return danger("The provider rejected the sign-in.", "sign-in");
|
|
333
|
+
case "overloaded":
|
|
334
|
+
return danger("The model is temporarily unavailable. Try again shortly.");
|
|
335
|
+
case "network":
|
|
336
|
+
return danger("Connection lost. Check your network and try again.");
|
|
337
|
+
case "provider":
|
|
338
|
+
case "runner":
|
|
339
|
+
return danger(oneLine(failure.message) ?? "Request failed.");
|
|
340
|
+
default: {
|
|
341
|
+
const _exhaustive = failure.class;
|
|
342
|
+
return _exhaustive;
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
export {
|
|
347
|
+
completionTrigger,
|
|
348
|
+
condensedCommand,
|
|
349
|
+
customTool,
|
|
350
|
+
delegateSubject,
|
|
351
|
+
executionMark,
|
|
352
|
+
failureNotice,
|
|
353
|
+
findCommandArgument,
|
|
354
|
+
formatDuration,
|
|
355
|
+
formatWholeDuration,
|
|
356
|
+
mainHead,
|
|
357
|
+
placeName,
|
|
358
|
+
readRawPart,
|
|
359
|
+
sessionMark,
|
|
360
|
+
shownContent,
|
|
361
|
+
showsReport,
|
|
362
|
+
showsText,
|
|
363
|
+
showsThinking,
|
|
364
|
+
showsTool,
|
|
365
|
+
tidyPath,
|
|
366
|
+
toolDetail,
|
|
367
|
+
toolNoun,
|
|
368
|
+
toolOutput,
|
|
369
|
+
toolStatus,
|
|
370
|
+
toolSubject,
|
|
371
|
+
toolTitle,
|
|
372
|
+
toolVerbs
|
|
373
|
+
};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { Renderer } from "@nyte-ai/plugin/client";
|
|
2
|
+
/**
|
|
3
|
+
* Renderers for the terminal client, as OpenTUI nodes: the five built-in
|
|
4
|
+
* part kinds. Feature plugins contribute their own renderers. A state its
|
|
5
|
+
* schema rejects draws nothing, for the client to show raw.
|
|
6
|
+
*
|
|
7
|
+
* @category plugins
|
|
8
|
+
* @since 0.1.0
|
|
9
|
+
*/
|
|
10
|
+
export declare const transcriptRenderers: readonly Renderer[];
|
|
11
|
+
/**
|
|
12
|
+
* The terminal renderers as a client plugin.
|
|
13
|
+
*
|
|
14
|
+
* @category plugins
|
|
15
|
+
* @since 0.1.0
|
|
16
|
+
*/
|
|
17
|
+
declare const _default: {
|
|
18
|
+
id: string;
|
|
19
|
+
contribute: {
|
|
20
|
+
renderers: readonly Renderer<import("@nyte-ai/plugin/client").PartDefinition<unknown, import("@nyte-ai/core").ActionSchemas>, unknown>[];
|
|
21
|
+
};
|
|
22
|
+
};
|
|
23
|
+
export default _default;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
// src/client/transcript-tui.ts
|
|
2
|
+
import { Box, Text } from "@opentui/core";
|
|
3
|
+
import { branchSummary, compaction, text, thinking, tool } from "@nyte-ai/plugin/client";
|
|
4
|
+
import { defineRenderer } from "@nyte-ai/plugin/client";
|
|
5
|
+
var unreadable = () => null;
|
|
6
|
+
var transcriptRenderers = [
|
|
7
|
+
defineRenderer(text, "tui", (state) => Text({ content: state.markdown }), unreadable),
|
|
8
|
+
defineRenderer(thinking, "tui", (state) => Text({ content: `Thinking: ${state.markdown}` }), unreadable),
|
|
9
|
+
defineRenderer(tool, "tui", (state, act) => Box({ flexDirection: "row", gap: 1 }, Text({ content: state.class.kind === "custom" ? state.class.label : state.name }), state.phase === "settled" ? Text({ content: state.outcome.kind }) : Text({ content: "[stop]", onMouseDown: () => void act("stop", {}) })), unreadable),
|
|
10
|
+
defineRenderer(compaction, "tui", (state) => Text({ content: state.summary ?? `Context compacted at ${state.tokensBefore} tokens.` }), unreadable),
|
|
11
|
+
defineRenderer(branchSummary, "tui", (state) => Text({ content: `Branch summary: ${state.markdown}` }), unreadable)
|
|
12
|
+
];
|
|
13
|
+
var transcript_tui_default = {
|
|
14
|
+
id: "transcript-tui",
|
|
15
|
+
contribute: { renderers: transcriptRenderers }
|
|
16
|
+
};
|
|
17
|
+
export {
|
|
18
|
+
transcript_tui_default as default,
|
|
19
|
+
transcriptRenderers
|
|
20
|
+
};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { Renderer } from "@nyte-ai/plugin/client";
|
|
2
|
+
/**
|
|
3
|
+
* Renderers for React clients, the desktop and the web: the five built-in
|
|
4
|
+
* part kinds. The tool's Stop action calls `act`. A state its schema rejects
|
|
5
|
+
* draws nothing, for the client to show raw.
|
|
6
|
+
*
|
|
7
|
+
* @category plugins
|
|
8
|
+
* @since 0.1.0
|
|
9
|
+
*/
|
|
10
|
+
export declare const transcriptRenderers: readonly Renderer[];
|
|
11
|
+
/**
|
|
12
|
+
* The React renderers as a client plugin.
|
|
13
|
+
*
|
|
14
|
+
* @category plugins
|
|
15
|
+
* @since 0.1.0
|
|
16
|
+
*/
|
|
17
|
+
declare const _default: {
|
|
18
|
+
id: string;
|
|
19
|
+
contribute: {
|
|
20
|
+
renderers: readonly Renderer<import("@nyte-ai/plugin/client").PartDefinition<unknown, import("@nyte-ai/core").ActionSchemas>, unknown>[];
|
|
21
|
+
};
|
|
22
|
+
};
|
|
23
|
+
export default _default;
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
// src/client/transcript.tsx
|
|
2
|
+
import { branchSummary, compaction, text, thinking, tool } from "@nyte-ai/plugin/client";
|
|
3
|
+
import { defineRenderer } from "@nyte-ai/plugin/client";
|
|
4
|
+
import { jsxDEV } from "react/jsx-dev-runtime";
|
|
5
|
+
var unreadable = () => null;
|
|
6
|
+
var transcriptRenderers = [
|
|
7
|
+
defineRenderer(text, "react", (state) => /* @__PURE__ */ jsxDEV("div", {
|
|
8
|
+
"data-part": "text",
|
|
9
|
+
children: state.markdown
|
|
10
|
+
}, undefined, false, undefined, this), unreadable),
|
|
11
|
+
defineRenderer(thinking, "react", (state) => /* @__PURE__ */ jsxDEV("details", {
|
|
12
|
+
"data-part": "thinking",
|
|
13
|
+
children: [
|
|
14
|
+
/* @__PURE__ */ jsxDEV("summary", {
|
|
15
|
+
children: "Thinking"
|
|
16
|
+
}, undefined, false, undefined, this),
|
|
17
|
+
state.markdown
|
|
18
|
+
]
|
|
19
|
+
}, undefined, true, undefined, this), unreadable),
|
|
20
|
+
defineRenderer(tool, "react", (state, act) => /* @__PURE__ */ jsxDEV("div", {
|
|
21
|
+
"data-part": "tool",
|
|
22
|
+
"data-phase": state.phase,
|
|
23
|
+
children: [
|
|
24
|
+
/* @__PURE__ */ jsxDEV("span", {
|
|
25
|
+
children: state.class.kind === "custom" ? state.class.label : state.name
|
|
26
|
+
}, undefined, false, undefined, this),
|
|
27
|
+
state.phase === "settled" ? /* @__PURE__ */ jsxDEV("span", {
|
|
28
|
+
children: state.outcome.kind
|
|
29
|
+
}, undefined, false, undefined, this) : /* @__PURE__ */ jsxDEV("button", {
|
|
30
|
+
onClick: () => void act("stop", {}),
|
|
31
|
+
children: "Stop"
|
|
32
|
+
}, undefined, false, undefined, this)
|
|
33
|
+
]
|
|
34
|
+
}, undefined, true, undefined, this), unreadable),
|
|
35
|
+
defineRenderer(compaction, "react", (state) => /* @__PURE__ */ jsxDEV("div", {
|
|
36
|
+
"data-part": "compaction",
|
|
37
|
+
children: state.summary ?? `Context compacted at ${state.tokensBefore} tokens.`
|
|
38
|
+
}, undefined, false, undefined, this), unreadable),
|
|
39
|
+
defineRenderer(branchSummary, "react", (state) => /* @__PURE__ */ jsxDEV("div", {
|
|
40
|
+
"data-part": "branchSummary",
|
|
41
|
+
children: state.markdown
|
|
42
|
+
}, undefined, false, undefined, this), unreadable)
|
|
43
|
+
];
|
|
44
|
+
var transcript_default = {
|
|
45
|
+
id: "transcript",
|
|
46
|
+
contribute: { renderers: transcriptRenderers }
|
|
47
|
+
};
|
|
48
|
+
export {
|
|
49
|
+
transcript_default as default,
|
|
50
|
+
transcriptRenderers
|
|
51
|
+
};
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import type { Part, PartDefinition, PartState, Renderer } from "@nyte-ai/core";
|
|
2
|
+
import type { HookEntry as SideHookEntry, HookHandler as SideHookHandler, HookName as SideHookName, Plugin as CorePlugin, PluginApi as CorePluginApi } from "@nyte-ai/core";
|
|
3
|
+
export { branchSummary, compaction, definePart, isPart, text, thinking, tool } from "@nyte-ai/core";
|
|
4
|
+
export type { ClientApi, Command, Keybinding, Part, PartDefinition, PartState, Renderer, SettingDefinition, } from "@nyte-ai/core";
|
|
5
|
+
/**
|
|
6
|
+
* A client plugin: once per app, with renderers, commands, settings,
|
|
7
|
+
* keybindings and client hooks. It declares the frameworks it renders for;
|
|
8
|
+
* the client mounts what it can.
|
|
9
|
+
*
|
|
10
|
+
* @category plugins
|
|
11
|
+
* @since 0.1.0
|
|
12
|
+
*/
|
|
13
|
+
export type Plugin = CorePlugin<"client">;
|
|
14
|
+
/**
|
|
15
|
+
* What a client plugin's `activate` and hook handlers receive: the app's
|
|
16
|
+
* connection, the session on screen and notifications.
|
|
17
|
+
*
|
|
18
|
+
* @category plugins
|
|
19
|
+
* @since 0.1.0
|
|
20
|
+
*/
|
|
21
|
+
export type PluginApi = CorePluginApi<"client">;
|
|
22
|
+
/**
|
|
23
|
+
* Names a hook a client plugin may handle.
|
|
24
|
+
*
|
|
25
|
+
* @category hooks
|
|
26
|
+
* @since 0.1.0
|
|
27
|
+
*/
|
|
28
|
+
export type HookName = SideHookName<"client">;
|
|
29
|
+
/**
|
|
30
|
+
* Returns a client hook handler's signature.
|
|
31
|
+
*
|
|
32
|
+
* @category hooks
|
|
33
|
+
* @since 0.1.0
|
|
34
|
+
*/
|
|
35
|
+
export type HookHandler<N extends HookName> = SideHookHandler<"client", N>;
|
|
36
|
+
/**
|
|
37
|
+
* Returns a client hook entry: a handler, or a handler with an order.
|
|
38
|
+
*
|
|
39
|
+
* @category hooks
|
|
40
|
+
* @since 0.1.0
|
|
41
|
+
*/
|
|
42
|
+
export type HookEntry<N extends HookName> = SideHookEntry<"client", N>;
|
|
43
|
+
/**
|
|
44
|
+
* Returns a renderer for one part kind whose `draw` gets the state checked
|
|
45
|
+
* against the kind's schema, typed; a state the schema rejects draws
|
|
46
|
+
* `unreadable`. The untyped `Renderer` is what a client mounts: a typed
|
|
47
|
+
* `Renderer<K>` is not assignable to it while the untyped `act` carries no
|
|
48
|
+
* action outputs (Part 2 §32), so the check is also the narrowing.
|
|
49
|
+
*
|
|
50
|
+
* @category plugins
|
|
51
|
+
* @since 0.1.0
|
|
52
|
+
*/
|
|
53
|
+
export declare function defineRenderer<K extends PartDefinition, View>(kind: K, framework: string, draw: (state: PartState<K>, act: Part<PartDefinition>["act"]) => View, unreadable: (kind: string) => View): Renderer;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
// src/client.ts
|
|
2
|
+
import { branchSummary, compaction, definePart, isPart, text, thinking, tool } from "@nyte-ai/core";
|
|
3
|
+
function defineRenderer(kind, framework, draw, unreadable) {
|
|
4
|
+
return {
|
|
5
|
+
kind,
|
|
6
|
+
framework,
|
|
7
|
+
render(part, act) {
|
|
8
|
+
const checked = kind.state["~standard"].validate(part.state);
|
|
9
|
+
return checked instanceof Promise || checked.issues !== undefined ? unreadable(kind.kind) : draw(checked.value, act);
|
|
10
|
+
}
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
export {
|
|
14
|
+
branchSummary,
|
|
15
|
+
compaction,
|
|
16
|
+
definePart,
|
|
17
|
+
defineRenderer,
|
|
18
|
+
isPart,
|
|
19
|
+
text,
|
|
20
|
+
thinking,
|
|
21
|
+
tool
|
|
22
|
+
};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export { loadQuickJSWasm } from "@earendil-works/pi-codemode";
|
|
2
|
+
export type { CodemodeSandboxOptions } from "@earendil-works/pi-codemode";
|
|
3
|
+
/**
|
|
4
|
+
* Returns the path of the QuickJS wasm the codemode sandbox loads, for a
|
|
5
|
+
* bundler that copies it next to its output. Node only: it resolves through
|
|
6
|
+
* `node:module`.
|
|
7
|
+
*
|
|
8
|
+
* @category plugins
|
|
9
|
+
* @since 0.1.0
|
|
10
|
+
*/
|
|
11
|
+
export declare function resolveQuickJSWasmPath(): string;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
// src/codemode-runtime.ts
|
|
2
|
+
import { createRequire } from "node:module";
|
|
3
|
+
import { loadQuickJSWasm } from "@earendil-works/pi-codemode";
|
|
4
|
+
function resolveQuickJSWasmPath() {
|
|
5
|
+
return createRequire(import.meta.resolve("@earendil-works/pi-codemode")).resolve("quickjs-wasi/quickjs.wasm");
|
|
6
|
+
}
|
|
7
|
+
export {
|
|
8
|
+
loadQuickJSWasm,
|
|
9
|
+
resolveQuickJSWasmPath
|
|
10
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {} from "@earendil-works/pi-codemode/worker";
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { CodemodeSandboxOptions } from "@earendil-works/pi-codemode";
|
|
2
|
+
import type { Plugin } from "@nyte-ai/plugin/core";
|
|
3
|
+
/**
|
|
4
|
+
* Returns the codemode plugin with the sandbox runtime a bundled client
|
|
5
|
+
* passes (its worker entry and wasm); the default export uses the installed
|
|
6
|
+
* package's own. The `codemode` tool runs a script in a QuickJS worker whose
|
|
7
|
+
* only capability is calling the session's tools through
|
|
8
|
+
* `invocation.tools.execute`, including those exposed to code only.
|
|
9
|
+
*
|
|
10
|
+
* @category plugins
|
|
11
|
+
* @since 0.1.0
|
|
12
|
+
*/
|
|
13
|
+
export declare function codemodePlugin(runtime: Pick<CodemodeSandboxOptions, "workerUrl" | "wasm">): Plugin;
|
|
14
|
+
/**
|
|
15
|
+
* The codemode plugin over the installed sandbox runtime.
|
|
16
|
+
*
|
|
17
|
+
* @category plugins
|
|
18
|
+
* @since 0.1.0
|
|
19
|
+
*/
|
|
20
|
+
declare const _default: Plugin;
|
|
21
|
+
export default _default;
|