@nyte-ai/plugin 0.0.25-beta.1 → 0.0.25-nightly.20261101.40

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.
Files changed (88) hide show
  1. package/THIRD-PARTY-NOTICES.md +49 -32
  2. package/dist/chunks/bash-description-0ah30s12.js +33 -0
  3. package/dist/chunks/bash-description-4h0hnsv4.js +68 -0
  4. package/dist/chunks/{bash-description-dnvgk30y.js → bash-description-4rfavmha.js} +32 -1
  5. package/dist/chunks/bash-description-5dpf5hpt.js +724 -0
  6. package/dist/chunks/{bash-description-yyd9jznf.js → bash-description-94km1hm2.js} +1 -1
  7. package/dist/chunks/{bash-description-svrhh5a5.js → bash-description-99k8z2r7.js} +3 -2
  8. package/dist/chunks/bash-description-9gw9ets8.js +162 -0
  9. package/dist/chunks/{bash-description-h13r0byk.js → bash-description-axnga0jz.js} +3 -3
  10. package/dist/chunks/bash-description-b78pre8c.js +147 -0
  11. package/dist/chunks/{bash-description-ye3wk5r3.js → bash-description-bas41ptb.js} +6 -24
  12. package/dist/chunks/{bash-description-2v3g7rd9.js → bash-description-bj5yh7tr.js} +26 -64
  13. package/dist/chunks/{bash-description-6z2kgtyt.js → bash-description-bkhr9zrz.js} +4 -4
  14. package/dist/chunks/{bash-description-hg64tqf1.js → bash-description-f754ge33.js} +49 -3
  15. package/dist/chunks/{bash-description-zz15raxk.js → bash-description-ff18794t.js} +1 -1
  16. package/dist/chunks/{bash-description-wmcbg6fw.js → bash-description-g7gfy7nw.js} +1 -1
  17. package/dist/chunks/{bash-description-1neewp76.js → bash-description-hp4rb8k4.js} +4 -3
  18. package/dist/chunks/bash-description-myvnmtt2.js +125 -0
  19. package/dist/chunks/{bash-description-9nn3yp18.js → bash-description-q2v8wbn8.js} +9 -1
  20. package/dist/chunks/bash-description-qwyy182r.js +452 -0
  21. package/dist/chunks/bash-description-rxpx004v.js +295 -0
  22. package/dist/chunks/{bash-description-eqp7ap2w.js → bash-description-z1581a29.js} +23 -9
  23. package/dist/src/acp/connection.d.ts +3 -1
  24. package/dist/src/acp/connection.js +3 -3
  25. package/dist/src/acp/index.d.ts +7 -4
  26. package/dist/src/acp/index.js +41 -8
  27. package/dist/src/acp/registry.d.ts +9 -0
  28. package/dist/src/acp/registry.js +5 -3
  29. package/dist/src/acp/thread.js +2 -2
  30. package/dist/src/acp/transcript.js +2 -2
  31. package/dist/src/acp/translate.d.ts +10 -2
  32. package/dist/src/acp/translate.js +3 -1
  33. package/dist/src/approvals/approvals.d.ts +1 -1
  34. package/dist/src/approvals/approvals.js +2 -2
  35. package/dist/src/approvals/schema.d.ts +3 -3
  36. package/dist/src/approvals/schema.js +1 -1
  37. package/dist/src/browser-tools.js +8 -2
  38. package/dist/src/canvas/canvas-compile.js +2 -2
  39. package/dist/src/canvas/canvas-preview.js +2 -2
  40. package/dist/src/canvas/canvas-protocol.d.ts +46 -0
  41. package/dist/src/canvas/canvas-protocol.js +11 -1
  42. package/dist/src/canvas/canvas.d.ts +17 -3
  43. package/dist/src/canvas/canvas.js +75 -31
  44. package/dist/src/canvas/schema.d.ts +28 -7
  45. package/dist/src/canvas/schema.js +2 -2
  46. package/dist/src/claude-code-sdk/index.d.ts +0 -10
  47. package/dist/src/claude-code-sdk/index.js +19 -179
  48. package/dist/src/claude-code-sdk/session.d.ts +22 -23
  49. package/dist/src/claude-code-sdk/session.js +6 -3
  50. package/dist/src/claude-code-sdk/transcript.d.ts +0 -6
  51. package/dist/src/claude-code-sdk/transcript.js +2 -4
  52. package/dist/src/claude-code-sdk/translate.d.ts +1 -5
  53. package/dist/src/claude-code-sdk/translate.js +2 -8
  54. package/dist/src/client/mount.d.ts +4 -2
  55. package/dist/src/client/mount.js +3 -0
  56. package/dist/src/client/notifications.d.ts +12 -4
  57. package/dist/src/client/notifications.js +25 -10
  58. package/dist/src/client/presentation.d.ts +138 -8
  59. package/dist/src/client/presentation.js +86 -371
  60. package/dist/src/codemode.js +151 -46
  61. package/dist/src/core.d.ts +1 -1
  62. package/dist/src/question/client/questions-tui.js +3 -3
  63. package/dist/src/question/client/questions.js +3 -3
  64. package/dist/src/question/question.js +84 -5
  65. package/dist/src/question/schema.js +3 -3
  66. package/dist/src/rename.d.ts +7 -35
  67. package/dist/src/rename.js +115 -48
  68. package/dist/src/subagents.d.ts +30 -0
  69. package/dist/src/subagents.js +323 -0
  70. package/dist/src/tool-search.d.ts +49 -0
  71. package/dist/src/tool-search.js +14 -0
  72. package/dist/src/web/body.d.ts +3 -0
  73. package/dist/src/web/body.js +6 -0
  74. package/dist/src/web/fetch.d.ts +16 -0
  75. package/dist/src/web/fetch.js +8 -0
  76. package/dist/src/web/html-markdown.d.ts +9 -0
  77. package/dist/src/web/html-markdown.js +10 -0
  78. package/dist/src/web/index.d.ts +24 -0
  79. package/dist/src/web/index.js +93 -0
  80. package/dist/src/web/providers.d.ts +60 -0
  81. package/dist/src/web/providers.js +11 -0
  82. package/dist/src/web/search.d.ts +21 -0
  83. package/dist/src/web/search.js +6 -0
  84. package/package.json +16 -7
  85. package/dist/chunks/bash-description-3j77ss7y.js +0 -86
  86. package/dist/chunks/bash-description-wbe8w0te.js +0 -530
  87. package/dist/src/web-search.d.ts +0 -78
  88. package/dist/src/web-search.js +0 -219
@@ -1,29 +1,21 @@
1
1
  import {
2
2
  findOnPath2
3
3
  } from "../../chunks/bash-description-4vz9pxyx.js";
4
- import {
5
- answerInput2
6
- } from "../../chunks/bash-description-6z2kgtyt.js";
7
- import {
8
- question2
9
- } from "../../chunks/bash-description-3j77ss7y.js";
10
4
  import {
11
5
  CLAUDE_CODE_PROVIDER2,
12
- MIRROR_TOOL3,
13
- BACKGROUND_TOOL2,
14
6
  emptyMessage3,
15
7
  Translator3
16
- } from "../../chunks/bash-description-ye3wk5r3.js";
17
- import {
18
- ClaudeCodeSession2
19
- } from "../../chunks/bash-description-wbe8w0te.js";
8
+ } from "../../chunks/bash-description-bas41ptb.js";
20
9
  import {
21
- mirrorArguments3,
22
10
  userBlocks3,
23
11
  messageKey3,
24
12
  sessionEntries2,
25
13
  flatPrompt2
26
- } from "../../chunks/bash-description-2v3g7rd9.js";
14
+ } from "../../chunks/bash-description-bj5yh7tr.js";
15
+ import {
16
+ isolatedOptions2,
17
+ ClaudeCodeSession2
18
+ } from "../../chunks/bash-description-rxpx004v.js";
27
19
 
28
20
  // src/claude-code-sdk/index.ts
29
21
  import { randomUUID } from "node:crypto";
@@ -42,31 +34,9 @@ import {
42
34
  registerSessionResourceCleanup
43
35
  } from "@nyte-ai/ai";
44
36
  import { processEnvironment } from "@nyte-ai/core";
45
- import { standard } from "@nyte-ai/schema";
46
- import { Type } from "typebox";
47
- import { Value } from "typebox/value";
48
37
  var API = "claude-agent-sdk";
49
38
  var EFFORTS = ["low", "medium", "high", "xhigh", "max"];
50
39
  var NOT_RUNNING = "Claude Code is no longer running this turn. Send a message to continue.";
51
- var CLAUDE_CODE_HAS_ITS_OWN = new Set([
52
- "read",
53
- "write",
54
- "edit",
55
- "list",
56
- "web_search",
57
- "question"
58
- ]);
59
- var ultracodeSetting = {
60
- id: "claude_code.ultracode",
61
- label: "Claude Code ultracode",
62
- schema: standard(Type.Boolean()),
63
- choices: [
64
- { value: false, label: "Off" },
65
- { value: true, label: "On", badge: "ultracode" }
66
- ],
67
- default: false,
68
- scope: "session"
69
- };
70
40
  function effortFor(model, reasoning) {
71
41
  if (reasoning === undefined)
72
42
  return;
@@ -100,22 +70,17 @@ function answerOnce(start, model, context, options) {
100
70
  (async () => {
101
71
  try {
102
72
  stream.push({ type: "start", partial: output });
103
- const claude = await findClaudeCode();
104
73
  for await (const message of start({
105
74
  prompt: flatPrompt2(context.messages),
106
75
  options: {
76
+ ...isolatedOptions2(await findClaudeCode(), options?.env),
107
77
  model: model.id,
108
78
  abortController: controller,
109
79
  systemPrompt: getCurrentSystemPrompt(context.messages),
110
- tools: [],
111
- settingSources: [],
112
- strictMcpConfig: true,
113
80
  maxTurns: 1,
114
81
  persistSession: false,
115
82
  includePartialMessages: true,
116
- thinking: { type: "disabled" },
117
- env: { ...process.env, ...options?.env },
118
- pathToClaudeCodeExecutable: claude
83
+ thinking: { type: "disabled" }
119
84
  }
120
85
  })) {
121
86
  if (message.type === "stream_event" && message.parent_tool_use_id === null)
@@ -140,112 +105,6 @@ function answerOnce(start, model, context, options) {
140
105
  })();
141
106
  return stream;
142
107
  }
143
- var nonEmpty = Type.String({ minLength: 1 });
144
- function field(input, key) {
145
- const value = input[key];
146
- return Value.Check(nonEmpty, value) ? value : undefined;
147
- }
148
- var claudeQuestions = Type.Array(Type.Object({
149
- question: Type.String(),
150
- header: Type.String(),
151
- options: Type.Array(Type.Object({ label: Type.String(), description: Type.String() })),
152
- multiSelect: Type.Optional(Type.Boolean())
153
- }));
154
- async function askUser(session, id, input, invocation) {
155
- if (!Value.Check(claudeQuestions, input.questions))
156
- return { answers: null, part: null };
157
- const questions = input.questions.map((item) => ({
158
- question: item.question,
159
- header: item.header.slice(0, 30),
160
- options: item.options.map(({ label, description }) => ({ label, description })),
161
- multiple: item.multiSelect === true
162
- }));
163
- const part = await invocation.session.parts.create(question2, {
164
- state: { questions, answers: null },
165
- placement: { kind: "modal" }
166
- });
167
- const outcome = await invocation.wait({ kind: "part", part: part.id });
168
- const checked = outcome.kind === "part" && outcome.answer?.action === "answer" ? await answerInput2["~standard"].validate(outcome.answer.input) : undefined;
169
- if (checked === undefined || checked.issues !== undefined)
170
- return { answers: null, part: part.id };
171
- const answers = questions.flatMap((item, index) => {
172
- const chosen = checked.value.answers[index]?.join(", ") ?? "";
173
- return chosen === "" ? [] : [[item.question, chosen]];
174
- });
175
- return { answers: answers.length === 0 ? null : Object.fromEntries(answers), part: part.id };
176
- }
177
- function classifyClaudeTool(name, input) {
178
- const path = field(input, "file_path") ?? field(input, "notebook_path");
179
- const command = field(input, "command");
180
- const description = field(input, "description");
181
- switch (name) {
182
- case "Read":
183
- return path === undefined ? { kind: "custom", label: name } : { kind: "read", path };
184
- case "Edit":
185
- case "MultiEdit":
186
- case "Write":
187
- case "NotebookEdit":
188
- return path === undefined ? { kind: "custom", label: name } : { kind: "edit", path };
189
- case "Bash":
190
- if (command === undefined)
191
- return { kind: "custom", label: name };
192
- return description === undefined ? { kind: "shell", command } : { kind: "shell", command, description };
193
- case "Agent":
194
- case "Task":
195
- return {
196
- kind: "delegate",
197
- child: null,
198
- role: "task",
199
- title: description ?? null
200
- };
201
- case "Skill":
202
- return { kind: "custom", label: `Skill ${field(input, "skill") ?? ""}`.trim() };
203
- case "Workflow":
204
- return {
205
- kind: "custom",
206
- label: `Workflow ${field(input, "title") ?? field(input, "name") ?? ""}`.trim()
207
- };
208
- case "AskUserQuestion": {
209
- const headers = Value.Check(claudeQuestions, input.questions) ? input.questions.map((item) => item.header).join(", ") : "";
210
- return { kind: "custom", label: `Asking ${headers}`.trim() };
211
- }
212
- case BACKGROUND_TOOL2:
213
- return { kind: "custom", label: "Waiting for background work" };
214
- default: {
215
- const subject = field(input, "pattern") ?? field(input, "url") ?? field(input, "query");
216
- return { kind: "custom", label: subject === undefined ? name : `${name} ${subject}` };
217
- }
218
- }
219
- }
220
- function mirrorTool(sessions) {
221
- return {
222
- name: MIRROR_TOOL3,
223
- description: "A tool Claude Code ran. Claude Code reports the result; Nyte records it.",
224
- parameters: standard(mirrorArguments3),
225
- exposure: "hidden",
226
- approval: "runtime",
227
- replay: "safe",
228
- class: ({ name, input }) => classifyClaudeTool(name, input),
229
- async execute({ id, name, input }, invocation) {
230
- const session = sessions.get(invocation.session.id);
231
- if (session === undefined || session.closed)
232
- throw new Error(NOT_RUNNING);
233
- if (name === BACKGROUND_TOOL2)
234
- return { content: [{ kind: "text", text: await session.background(invocation.signal) }] };
235
- session.recording(id);
236
- let parts = [];
237
- if (name === "AskUserQuestion") {
238
- const asked = await askUser(session, id, input, invocation);
239
- session.answer(id, asked.answers);
240
- parts = asked.part === null ? [] : [asked.part];
241
- }
242
- const output = await session.result(id, invocation.signal);
243
- if (output.isError)
244
- throw new Error(output.text);
245
- return { content: [{ kind: "text", text: output.text }], parts };
246
- }
247
- };
248
- }
249
108
  function claudeCodeSdk(start = query) {
250
109
  const catalog = anthropicProvider();
251
110
  const sessions = new Map;
@@ -264,27 +123,25 @@ function claudeCodeSdk(start = query) {
264
123
  if (id === undefined || binding === undefined)
265
124
  throw new Error("Claude Code answers inside a Nyte session with the claude-code-sdk plugin.");
266
125
  const effort = effortFor(model, options?.reasoning);
267
- const ultracode = await binding.ultracode();
268
- const key = JSON.stringify([model.id, binding.cwd, options?.reasoning !== undefined]);
126
+ const system = getCurrentSystemPrompt(context.messages);
127
+ const key = JSON.stringify([model.id, binding.cwd, options?.reasoning !== undefined, system]);
269
128
  const messages = context.messages.filter((message) => message.role !== "system");
270
129
  const keys = messages.map(messageKey3);
271
- const tools = getCurrentTools(context.messages).filter((tool) => !CLAUDE_CODE_HAS_ITS_OWN.has(tool.name));
272
- let session = sessions.get(id);
273
- const continues = session !== undefined && !session.closed && !session.asking && session.key === key && session.known.length < keys.length && session.known.every((known, index) => keys[index] === known);
130
+ const tools = getCurrentTools(context.messages);
274
131
  const prompt = messages.slice(messages.findLastIndex((message) => message.role !== "user") + 1);
275
- if (!continues) {
132
+ let session = sessions.get(id);
133
+ if (session === undefined || !session.follows(key, keys)) {
276
134
  session?.close();
277
135
  if (prompt.length === 0)
278
136
  throw new Error(NOT_RUNNING);
279
- const claude = await findClaudeCode();
280
137
  const claudeSession = randomUUID();
281
138
  session = new ClaudeCodeSession2({
282
139
  key,
283
140
  model: model.id,
284
141
  cwd: binding.cwd,
142
+ system,
285
143
  thinking: options?.reasoning !== undefined,
286
144
  effort,
287
- ultracode,
288
145
  env: options?.env,
289
146
  session: claudeSession,
290
147
  history: sessionEntries2(messages.slice(0, -prompt.length), {
@@ -294,24 +151,16 @@ function claudeCodeSdk(start = query) {
294
151
  }),
295
152
  tools,
296
153
  query: start,
297
- claude,
298
- approve: binding.approve
154
+ claude: await findClaudeCode()
299
155
  });
300
156
  sessions.set(id, session);
301
157
  }
302
- if (session === undefined)
303
- throw new Error(NOT_RUNNING);
304
158
  session.expose(tools);
305
159
  session.deliver(messages);
306
- await session.configure(effort, ultracode);
160
+ await session.configure(effort);
307
161
  if (prompt.length > 0)
308
162
  session.send(prompt.flatMap((message) => message.role === "user" ? userBlocks3(message) : []));
309
- const live = session;
310
- const stream = live.respond(model, options?.signal);
311
- stream.result().then((message) => {
312
- live.known = message.stopReason === "error" || message.stopReason === "aborted" ? [] : [...keys, messageKey3(message)];
313
- });
314
- return stream;
163
+ return session.respond(model, keys, options?.signal);
315
164
  }
316
165
  const stream = (model, context, options) => getCurrentTools(context.messages).length === 0 ? answerOnce(start, model, context, options) : lazyStream(model, () => respond(model, context, options));
317
166
  const provider = {
@@ -346,17 +195,9 @@ function claudeCodeSdk(start = query) {
346
195
  };
347
196
  const plugin = {
348
197
  id: "claude-code-sdk",
349
- contribute: { tools: [mirrorTool(sessions)], settings: [ultracodeSetting] },
350
198
  activate(api) {
351
199
  const id = api.session.id;
352
- const binding = {
353
- cwd: api.env.cwd,
354
- ultracode: async () => await api.contribute.settings.value(ultracodeSetting.id) === true,
355
- approve: async (name, input, signal) => {
356
- const verdict = await api.approve({ name, class: classifyClaudeTool(name, input) }, signal);
357
- return verdict.kind === "allow" ? { behavior: "allow" } : { behavior: "deny", message: verdict.reason };
358
- }
359
- };
200
+ const binding = { cwd: api.env.cwd };
360
201
  const release = acquireSessionResources(id);
361
202
  bindings.set(id, binding);
362
203
  const unbind = () => {
@@ -373,6 +214,5 @@ function claudeCodeSdk(start = query) {
373
214
  return { provider, plugin };
374
215
  }
375
216
  export {
376
- claudeCodeSdk,
377
- ultracodeSetting
217
+ claudeCodeSdk
378
218
  };
@@ -1,50 +1,49 @@
1
- import type { CanUseTool, EffortLevel, PermissionResult, Query, SDKMessage, SessionStoreEntry, query } from "@anthropic-ai/claude-agent-sdk";
2
- import type { Api, AssistantMessageEventStream, Message, Model, Tool } from "@nyte-ai/ai";
1
+ import type { EffortLevel, Options, Query, SDKMessage, SessionStoreEntry, query } from "@anthropic-ai/claude-agent-sdk";
2
+ import type { Api, AssistantMessageEventStream, Message, Model, ProviderEnv, Tool } from "@nyte-ai/ai";
3
3
  import type { ContentBlock } from "./transcript.ts";
4
4
  interface Launch {
5
+ /** What only a new process can change: model, folder, thinking and system prompt. Effort and tools change on a running one. */
5
6
  readonly key: string;
6
7
  readonly model: string;
7
8
  readonly cwd: string;
9
+ readonly system: string;
8
10
  readonly thinking: boolean;
9
11
  readonly effort: EffortLevel | undefined;
10
- readonly ultracode: boolean;
11
- readonly env: Record<string, string | undefined> | undefined;
12
+ readonly env: ProviderEnv | undefined;
12
13
  readonly session: string;
13
14
  readonly history: readonly SessionStoreEntry[];
14
15
  readonly tools: readonly Tool[];
15
16
  readonly query: StartQuery;
16
17
  /** The installed `claude` to run; without one the Agent SDK looks for its own. */
17
18
  readonly claude: string | undefined;
18
- readonly approve: Approve;
19
19
  }
20
- /** Decides a call Claude Code asks to run under Nyte's permissions policy, by the tool's own name. */
21
- export type Approve = (name: string, input: Parameters<CanUseTool>[1], signal: AbortSignal) => Promise<PermissionResult>;
22
20
  /** Starts Claude Code: the Agent SDK's `query`, or a stand-in with the parts of its `Query` a session uses. */
23
21
  export type StartQuery = (params: Parameters<typeof query>[0]) => AsyncIterable<SDKMessage> & Pick<Query, "applyFlagSettings" | "close">;
24
- export type QuestionAnswers = Record<string, string> | null;
25
- interface ClaudeToolOutput {
26
- readonly text: string;
27
- readonly isError: boolean;
28
- }
22
+ /**
23
+ * Claude Code as a bare model: only the tools and system prompt Nyte passes, none of the user's
24
+ * Claude Code settings, hooks, MCP servers, skills or CLAUDE.md, and prompts sent as written
25
+ * (`verbatimPrompts` needs Claude Code 2.1.248 or later).
26
+ */
27
+ export declare function isolatedOptions(claude: string | undefined, env: ProviderEnv | undefined): Options;
28
+ /**
29
+ * One running `claude` for a Nyte session. Claude's calls to Nyte's tools end the response that
30
+ * makes them; Nyte runs them like any model's calls, and their results answer Claude's MCP
31
+ * requests when the next response starts.
32
+ */
29
33
  export declare class ClaudeCodeSession {
30
34
  #private;
31
- readonly key: string;
32
- known: readonly string[];
33
35
  constructor(launch: Launch);
34
36
  get closed(): boolean;
35
- configure(effort: EffortLevel | undefined, ultracode: boolean): Promise<void>;
37
+ /** Whether this process can take the turn for `keys`: it was launched as `key` and has seen their start. */
38
+ follows(key: string, keys: readonly string[]): boolean;
39
+ configure(effort: EffortLevel | undefined): Promise<void>;
36
40
  /** Serves `tools` as the Nyte MCP server's tools from now on, telling Claude Code when they changed. */
37
41
  expose(tools: readonly Tool[]): void;
38
- /** Answers Claude Code from Nyte's tool results: a Nyte tool call gets its result, and a call Claude Code asked to run but Nyte settled without running it is denied with that result. */
42
+ /** Answers Claude's waiting Nyte tool calls with the results Nyte recorded for them. */
39
43
  deliver(messages: readonly Message[]): void;
40
- /** Lets Claude Code's call `id` go on to its approval now that Nyte records it (so the workspace snapshot before it is taken), and denies the calls before it in the same message that Nyte settled without running. */
41
- recording(id: string): void;
42
44
  send(content: readonly ContentBlock[]): void;
43
- respond(model: Model<Api>, signal: AbortSignal | undefined): AssistantMessageEventStream;
44
- get asking(): boolean;
45
- answer(id: string, answers: QuestionAnswers): void;
46
- result(id: string, signal: AbortSignal): Promise<ClaudeToolOutput>;
47
- background(signal: AbortSignal): Promise<string>;
45
+ /** Streams Claude's next response to the transcript whose message keys are `keys`. */
46
+ respond(model: Model<Api>, keys: readonly string[], signal: AbortSignal | undefined): AssistantMessageEventStream;
48
47
  close(reason?: Error): void;
49
48
  }
50
49
  export {};
@@ -1,7 +1,10 @@
1
1
  import {
2
+ isolatedOptions2,
2
3
  ClaudeCodeSession2
3
- } from "../../chunks/bash-description-wbe8w0te.js";
4
- import"../../chunks/bash-description-ye3wk5r3.js";
4
+ } from "../../chunks/bash-description-rxpx004v.js";
5
+ import"../../chunks/bash-description-bj5yh7tr.js";
6
+ import"../../chunks/bash-description-bas41ptb.js";
5
7
  export {
6
- ClaudeCodeSession2 as ClaudeCodeSession
8
+ ClaudeCodeSession2 as ClaudeCodeSession,
9
+ isolatedOptions2 as isolatedOptions
7
10
  };
@@ -1,15 +1,9 @@
1
1
  import type { SDKUserMessage, SessionStoreEntry } from "@anthropic-ai/claude-agent-sdk";
2
2
  import type { Message, UserMessage } from "@nyte-ai/ai";
3
- import { Type } from "typebox";
4
3
  type MessageParam = Exclude<SDKUserMessage["message"], {
5
4
  role: "system";
6
5
  }>;
7
6
  export type ContentBlock = Exclude<MessageParam["content"], string>[number];
8
- export declare const mirrorArguments: Type.TObject<{
9
- id: Type.TString;
10
- name: Type.TString;
11
- input: Type.TRecord<"^.*$", Type.TUnknown>;
12
- }>;
13
7
  export declare function userBlocks(message: UserMessage): ContentBlock[];
14
8
  export declare function messageKey(message: Message): string;
15
9
  export declare function sessionEntries(messages: readonly Message[], input: {
@@ -1,15 +1,13 @@
1
1
  import {
2
- mirrorArguments3,
3
2
  userBlocks3,
4
3
  messageKey3,
5
4
  sessionEntries2,
6
5
  flatPrompt2
7
- } from "../../chunks/bash-description-2v3g7rd9.js";
8
- import"../../chunks/bash-description-ye3wk5r3.js";
6
+ } from "../../chunks/bash-description-bj5yh7tr.js";
7
+ import"../../chunks/bash-description-bas41ptb.js";
9
8
  export {
10
9
  flatPrompt2 as flatPrompt,
11
10
  messageKey3 as messageKey,
12
- mirrorArguments3 as mirrorArguments,
13
11
  sessionEntries2 as sessionEntries,
14
12
  userBlocks3 as userBlocks
15
13
  };
@@ -1,18 +1,14 @@
1
1
  import type { SDKPartialAssistantMessage } from "@anthropic-ai/claude-agent-sdk";
2
- import type { Api, AssistantMessage, AssistantMessageEventStream, Model, ToolCall } from "@nyte-ai/ai";
2
+ import type { Api, AssistantMessage, AssistantMessageEventStream, Model } from "@nyte-ai/ai";
3
3
  type StreamEvent = SDKPartialAssistantMessage["event"];
4
4
  export declare const CLAUDE_CODE_PROVIDER = "claude-code";
5
- export declare const MIRROR_TOOL = "claude_code";
6
- export declare const BACKGROUND_TOOL = "BackgroundTasks";
7
5
  export declare const NYTE_SERVER = "nyte";
8
6
  export declare const NYTE_TOOL_PREFIX = "mcp__nyte__";
9
7
  export declare function emptyMessage(model: Model<Api>): AssistantMessage;
10
- export declare function mirrorCall(id: string, name: string, input: Record<string, unknown>): ToolCall;
11
8
  export declare class Translator {
12
9
  #private;
13
10
  constructor(model: Model<Api>, output: AssistantMessage, stream: AssistantMessageEventStream);
14
11
  /** Applies one stream event. Returns the raw stop reason at a message's end, and `"tool_use"` as soon as a Nyte tool call's input is complete: Claude Code waits for Nyte to run it before it runs the message's later calls. */
15
12
  apply(event: StreamEvent): string | undefined;
16
- append(call: ToolCall): void;
17
13
  }
18
14
  export {};
@@ -1,20 +1,14 @@
1
1
  import {
2
2
  CLAUDE_CODE_PROVIDER2,
3
- MIRROR_TOOL3,
4
- BACKGROUND_TOOL2,
5
3
  NYTE_SERVER2,
6
4
  NYTE_TOOL_PREFIX2,
7
5
  emptyMessage3,
8
- mirrorCall2,
9
6
  Translator3
10
- } from "../../chunks/bash-description-ye3wk5r3.js";
7
+ } from "../../chunks/bash-description-bas41ptb.js";
11
8
  export {
12
- BACKGROUND_TOOL2 as BACKGROUND_TOOL,
13
9
  CLAUDE_CODE_PROVIDER2 as CLAUDE_CODE_PROVIDER,
14
- MIRROR_TOOL3 as MIRROR_TOOL,
15
10
  NYTE_SERVER2 as NYTE_SERVER,
16
11
  NYTE_TOOL_PREFIX2 as NYTE_TOOL_PREFIX,
17
12
  Translator3 as Translator,
18
- emptyMessage3 as emptyMessage,
19
- mirrorCall2 as mirrorCall
13
+ emptyMessage3 as emptyMessage
20
14
  };
@@ -1,11 +1,12 @@
1
1
  import type { Connection, Session } from "@nyte-ai/core";
2
- import type { Decision, Placement, SessionInfo, SubmitDraft } from "@nyte-ai/schema";
2
+ import type { Decision, Placement, SessionId, SessionInfo, SubmitDraft } from "@nyte-ai/schema";
3
3
  import type { Plugin, PluginApi } from "../client.ts";
4
4
  import type { PartMessage } from "./presentation.ts";
5
5
  type Notification = Parameters<PluginApi["ui"]["notify"]>[0];
6
6
  /**
7
7
  * What a client hands the plugins it mounts: its connection, the frameworks
8
- * it draws, the session on screen, and where notices and plugin errors go.
8
+ * it draws, the session input goes to, the sessions someone is looking at,
9
+ * and where notices and plugin errors go.
9
10
  *
10
11
  * @category plugins
11
12
  */
@@ -14,6 +15,7 @@ export interface MountOptions {
14
15
  readonly plugins: readonly Plugin[];
15
16
  readonly client: PluginApi["client"];
16
17
  readonly session: () => Session | null;
18
+ readonly looking: () => ReadonlySet<SessionId>;
17
19
  readonly notify: (input: Notification) => void;
18
20
  readonly report: (plugin: string, message: string) => void;
19
21
  }
@@ -173,6 +173,9 @@ async function mountClientPlugins(options) {
173
173
  get session() {
174
174
  return options.session();
175
175
  },
176
+ get looking() {
177
+ return options.looking();
178
+ },
176
179
  ui: { notify: options.notify }
177
180
  };
178
181
  const hooks = plugin.hooks ?? {};
@@ -1,9 +1,10 @@
1
1
  import type { RunEnd } from "@nyte-ai/schema";
2
2
  /**
3
- * Tells the user when a run ends in any session this client can see:
4
- * finished, or failed with the reason. A stopped run stays quiet because
5
- * someone asked for it, and so do sessions a parent spawned, so a delegation
6
- * does not ring once per child.
3
+ * Tells the user when a run ends in a session this client can see but nobody
4
+ * is looking at: finished, or failed with the reason. A session someone is
5
+ * looking at shows its own result, a stopped run stays quiet because someone
6
+ * asked for it, and so do sessions a parent spawned, so a delegation does not
7
+ * ring once per child.
7
8
  *
8
9
  * @category plugins
9
10
  * @since 0.1.0
@@ -34,3 +35,10 @@ declare const _default: {
34
35
  };
35
36
  };
36
37
  export default _default;
38
+ /**
39
+ * What to tell the user about a run's end: that it's done, or that it failed and why, on one
40
+ * line of at most 120 characters. A stopped run says nothing, because someone asked for it.
41
+ *
42
+ * @category plugins
43
+ */
44
+ export declare function describeRunEnd(end: RunEnd): string | undefined;
@@ -1,24 +1,39 @@
1
+ import {
2
+ taskLabel2,
3
+ endedStatus2,
4
+ sessionTitle2
5
+ } from "../../chunks/bash-description-qwyy182r.js";
6
+
1
7
  // src/client/notifications.ts
2
8
  var notifications_default = {
3
9
  id: "notifications",
4
10
  hooks: {
5
11
  run_ended_anywhere: async (event, { api }) => {
12
+ if (api.looking.has(event.session))
13
+ return;
6
14
  const info = await api.sdk.session(event.session).info();
7
15
  if (info.parent !== null)
8
16
  return;
9
- const title = info.name ?? undefined;
10
- const { end } = event;
11
- if (end.kind === "completed")
12
- api.ui.notify({ title, message: "Run finished", level: "info" });
13
- else if (end.kind === "failed")
14
- api.ui.notify({ title, message: `Run failed: ${line(end)}`, level: "error" });
17
+ const message = describeRunEnd(event.end);
18
+ if (message !== undefined)
19
+ api.ui.notify({
20
+ title: sessionTitle2(info),
21
+ message,
22
+ level: event.end.kind === "failed" ? "error" : "info"
23
+ });
15
24
  }
16
25
  }
17
26
  };
18
- function line(end) {
19
- const text = end.failure.message.replace(/\s+/g, " ").trim();
20
- return text.length > 120 ? `${text.slice(0, 119)}…` : text;
27
+ function describeRunEnd(end) {
28
+ const status = endedStatus2(end);
29
+ if (status.kind === "completed")
30
+ return taskLabel2("done");
31
+ if (status.kind !== "failed")
32
+ return;
33
+ const text = status.failure.message.replace(/\s+/g, " ").trim();
34
+ return `${taskLabel2("failed")}: ${text.length > 120 ? `${text.slice(0, 119)}…` : text}`;
21
35
  }
22
36
  export {
23
- notifications_default as default
37
+ notifications_default as default,
38
+ describeRunEnd
24
39
  };