@nyte-ai/plugin 0.0.0-stage → 0.0.19

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 (137) hide show
  1. package/LICENSE +21 -0
  2. package/THIRD-PARTY-NOTICES.md +866 -0
  3. package/dist/chunks/billing-0y7dfkp2.js +146 -0
  4. package/dist/chunks/billing-2v3g7rd9.js +190 -0
  5. package/dist/chunks/billing-3j77ss7y.js +86 -0
  6. package/dist/chunks/billing-3scqmkzb.js +559 -0
  7. package/dist/chunks/billing-4vz9pxyx.js +22 -0
  8. package/dist/chunks/billing-6z2kgtyt.js +51 -0
  9. package/dist/chunks/billing-8rjk35gr.js +444 -0
  10. package/dist/chunks/billing-9nn3yp18.js +176 -0
  11. package/dist/chunks/billing-9qc0eqh4.js +174 -0
  12. package/dist/chunks/billing-a9vqn66p.js +351 -0
  13. package/dist/chunks/billing-bv5zr32b.js +369 -0
  14. package/dist/chunks/billing-cy1rg619.js +302 -0
  15. package/dist/chunks/billing-ejx2hv52.js +323 -0
  16. package/dist/chunks/billing-h13r0byk.js +80 -0
  17. package/dist/chunks/billing-hg64tqf1.js +97 -0
  18. package/dist/chunks/billing-j643d12p.js +197 -0
  19. package/dist/chunks/billing-kn3d30b4.js +276 -0
  20. package/dist/chunks/billing-mvc33pv6.js +36 -0
  21. package/dist/chunks/billing-s4rrspsk.js +7 -0
  22. package/dist/chunks/billing-svrhh5a5.js +307 -0
  23. package/dist/chunks/billing-sxc70w72.js +161 -0
  24. package/dist/chunks/billing-t1qrxe16.js +41 -0
  25. package/dist/chunks/billing-tm34gm2p.js +528 -0
  26. package/dist/chunks/billing-tzr3cebf.js +20 -0
  27. package/dist/chunks/billing-v3hg5rc7.js +373 -0
  28. package/dist/chunks/billing-wmcbg6fw.js +52 -0
  29. package/dist/chunks/billing-ye3wk5r3.js +205 -0
  30. package/dist/chunks/billing-zfpm2rt0.js +29 -0
  31. package/dist/examples/claude-code/LICENSE +21 -0
  32. package/dist/examples/claude-code/billing.d.ts +7 -0
  33. package/dist/examples/claude-code/billing.js +11 -0
  34. package/dist/examples/claude-code/claude-cli.d.ts +35 -0
  35. package/dist/examples/claude-code/claude-cli.js +15 -0
  36. package/dist/examples/claude-code/env.d.ts +1 -0
  37. package/dist/examples/claude-code/env.js +6 -0
  38. package/dist/examples/claude-code/index.d.ts +24 -0
  39. package/dist/examples/claude-code/index.js +149 -0
  40. package/dist/examples/claude-code/inert-mcp.d.ts +1 -0
  41. package/dist/examples/claude-code/inert-mcp.js +6 -0
  42. package/dist/examples/claude-code/model-catalog.d.ts +27 -0
  43. package/dist/examples/claude-code/model-catalog.js +12 -0
  44. package/dist/examples/claude-code/process.d.ts +22 -0
  45. package/dist/examples/claude-code/process.js +25 -0
  46. package/dist/examples/claude-code/replay.d.ts +4 -0
  47. package/dist/examples/claude-code/replay.js +11 -0
  48. package/dist/examples/claude-code/stream.d.ts +3 -0
  49. package/dist/examples/claude-code/stream.js +16 -0
  50. package/dist/examples/claude-code/transcript.d.ts +83 -0
  51. package/dist/examples/claude-code/transcript.js +23 -0
  52. package/dist/examples/claude-code/turn-relay.d.ts +48 -0
  53. package/dist/examples/claude-code/turn-relay.js +9 -0
  54. package/dist/examples/claude-code/wire.d.ts +372 -0
  55. package/dist/examples/claude-code/wire.js +18 -0
  56. package/dist/src/acp/connection.d.ts +24 -0
  57. package/dist/src/acp/connection.js +8 -0
  58. package/dist/src/acp/index.d.ts +54 -0
  59. package/dist/src/acp/index.js +1005 -0
  60. package/dist/src/acp/registry.d.ts +18 -0
  61. package/dist/src/acp/registry.js +9 -0
  62. package/dist/src/acp/thread.d.ts +46 -0
  63. package/dist/src/acp/thread.js +7 -0
  64. package/dist/src/acp/transcript.d.ts +8 -0
  65. package/dist/src/acp/transcript.js +11 -0
  66. package/dist/src/acp/translate.d.ts +33 -0
  67. package/dist/src/acp/translate.js +20 -0
  68. package/dist/src/approvals/approvals.d.ts +189 -0
  69. package/dist/src/approvals/approvals.js +143 -0
  70. package/dist/src/approvals/schema.d.ts +169 -0
  71. package/dist/src/approvals/schema.js +18 -0
  72. package/dist/src/bash-description.d.ts +30 -0
  73. package/dist/src/bash-description.js +18 -0
  74. package/dist/src/browser-tools.d.ts +25 -0
  75. package/dist/src/browser-tools.js +246 -0
  76. package/dist/src/canvas/canvas-compile.d.ts +48 -0
  77. package/dist/src/canvas/canvas-compile.js +8 -0
  78. package/dist/src/canvas/canvas-libraries.d.ts +32 -0
  79. package/dist/src/canvas/canvas-libraries.js +6 -0
  80. package/dist/src/canvas/canvas-preview.d.ts +107 -0
  81. package/dist/src/canvas/canvas-preview.js +12 -0
  82. package/dist/src/canvas/canvas-protocol.d.ts +184 -0
  83. package/dist/src/canvas/canvas-protocol.js +75 -0
  84. package/dist/src/canvas/canvas.d.ts +50 -0
  85. package/dist/src/canvas/canvas.js +221 -0
  86. package/dist/src/canvas/schema.d.ts +47 -0
  87. package/dist/src/canvas/schema.js +8 -0
  88. package/dist/src/claude-code-sdk/index.d.ts +35 -0
  89. package/dist/src/claude-code-sdk/index.js +379 -0
  90. package/dist/src/claude-code-sdk/session.d.ts +50 -0
  91. package/dist/src/claude-code-sdk/session.js +7 -0
  92. package/dist/src/claude-code-sdk/transcript.d.ts +19 -0
  93. package/dist/src/claude-code-sdk/transcript.js +15 -0
  94. package/dist/src/claude-code-sdk/translate.d.ts +18 -0
  95. package/dist/src/claude-code-sdk/translate.js +20 -0
  96. package/dist/src/client/mount.d.ts +44 -0
  97. package/dist/src/client/mount.js +252 -0
  98. package/dist/src/client/notifications.d.ts +36 -0
  99. package/dist/src/client/notifications.js +24 -0
  100. package/dist/src/client/presentation.d.ts +362 -0
  101. package/dist/src/client/presentation.js +391 -0
  102. package/dist/src/client/transcript-tui.d.ts +23 -0
  103. package/dist/src/client/transcript-tui.js +20 -0
  104. package/dist/src/client/transcript.d.ts +23 -0
  105. package/dist/src/client/transcript.js +51 -0
  106. package/dist/src/client.d.ts +53 -0
  107. package/dist/src/client.js +22 -0
  108. package/dist/src/codemode-runtime.d.ts +11 -0
  109. package/dist/src/codemode-runtime.js +10 -0
  110. package/dist/src/codemode-worker.d.ts +1 -0
  111. package/dist/src/codemode-worker.js +2 -0
  112. package/dist/src/codemode.d.ts +21 -0
  113. package/dist/src/codemode.js +170 -0
  114. package/dist/src/core.d.ts +43 -0
  115. package/dist/src/core.js +11 -0
  116. package/dist/src/find-on-path.d.ts +4 -0
  117. package/dist/src/find-on-path.js +8 -0
  118. package/dist/src/openai-astra-context.d.ts +23 -0
  119. package/dist/src/openai-astra-context.js +14 -0
  120. package/dist/src/openai-compaction.d.ts +15 -0
  121. package/dist/src/openai-compaction.js +55 -0
  122. package/dist/src/question/client/questions-tui.d.ts +9 -0
  123. package/dist/src/question/client/questions-tui.js +19 -0
  124. package/dist/src/question/client/questions.d.ts +9 -0
  125. package/dist/src/question/client/questions.js +160 -0
  126. package/dist/src/question/question.d.ts +63 -0
  127. package/dist/src/question/question.js +9 -0
  128. package/dist/src/question/schema.d.ts +101 -0
  129. package/dist/src/question/schema.js +14 -0
  130. package/dist/src/rename.d.ts +79 -0
  131. package/dist/src/rename.js +91 -0
  132. package/dist/src/telemetry.d.ts +36 -0
  133. package/dist/src/telemetry.js +84 -0
  134. package/dist/src/web-search.d.ts +78 -0
  135. package/dist/src/web-search.js +219 -0
  136. package/package.json +190 -3
  137. package/README.md +0 -3
@@ -0,0 +1,18 @@
1
+ /** An ACP agent this machine can start without downloading anything. */
2
+ export interface AcpAgent {
3
+ readonly id: string;
4
+ readonly name: string;
5
+ readonly command: string;
6
+ readonly args: readonly string[];
7
+ readonly env: Readonly<Record<string, string>>;
8
+ }
9
+ /** The agent entries of a registry document; anything else is no entries. */
10
+ export declare function registryEntries(document: unknown): readonly unknown[];
11
+ /**
12
+ * The registry agents installed on this machine, in registry order: a binary
13
+ * agent whose command is on `path`, or an npx agent whose package is
14
+ * installed globally beside `npx` (its own bin, not another command of the
15
+ * same name), run with the registry's arguments. An agent only the registry
16
+ * can download is left out, so choosing a model never downloads one.
17
+ */
18
+ export declare function installedAgents(entries: readonly unknown[], path: string): Promise<readonly AcpAgent[]>;
@@ -0,0 +1,9 @@
1
+ import {
2
+ registryEntries2,
3
+ installedAgents2
4
+ } from "../../chunks/billing-hg64tqf1.js";
5
+ import"../../chunks/billing-4vz9pxyx.js";
6
+ export {
7
+ installedAgents2 as installedAgents,
8
+ registryEntries2 as registryEntries
9
+ };
@@ -0,0 +1,46 @@
1
+ import type { ContentBlock, PromptResponse, RequestPermissionRequest, RequestPermissionResponse, SessionUpdate } from "@agentclientprotocol/sdk";
2
+ import type { Api, AssistantMessageEventStream, Model } from "@nyte-ai/ai";
3
+ import type { RuntimeCall, RuntimeVerdict } from "@nyte-ai/core";
4
+ /** Decides a call the agent asks permission for, under the session's policy. */
5
+ export type AcpApprove = (call: RuntimeCall, signal: AbortSignal) => Promise<RuntimeVerdict>;
6
+ /** What one of the agent's tool calls reported once it finished, or as far as it got when the turn ended. */
7
+ export interface AcpToolOutput {
8
+ readonly text: string;
9
+ readonly failed: boolean;
10
+ }
11
+ /** How a thread reaches its agent: one prompt turn, the cancel notification for it, the folder its session runs in, and how a permission it asks for is decided. */
12
+ export interface AcpChannel {
13
+ readonly cwd: string;
14
+ prompt(blocks: readonly ContentBlock[]): Promise<PromptResponse>;
15
+ cancel(): void;
16
+ readonly approve: AcpApprove;
17
+ }
18
+ /**
19
+ * One ACP session on an agent: the prompt turns Nyte sends it, the updates
20
+ * it streams back as assistant messages, and its tool calls, which Nyte
21
+ * records as mirror calls whose ids start with `prefix`. A permission the
22
+ * agent asks for waits until Nyte records that call, then goes to the
23
+ * channel's `approve` under the call's ACP kind; a call Nyte skips is
24
+ * refused.
25
+ */
26
+ export declare class AcpThread {
27
+ #private;
28
+ readonly prefix: string;
29
+ constructor(prefix: string, channel: AcpChannel);
30
+ get closed(): boolean;
31
+ /** Sends a prompt turn, or queues it behind the turn the agent is running, since ACP takes no message mid-turn. */
32
+ send(blocks: readonly ContentBlock[]): void;
33
+ update(update: SessionUpdate): void;
34
+ permission(request: RequestPermissionRequest): Promise<RequestPermissionResponse>;
35
+ /** Lets the agent's permission ask for `id`, now or later, go on to its approval: Nyte is recording the call. */
36
+ recording(id: string): void;
37
+ /** Refuses `id` when the agent asks, now or later: Nyte settled it without running it. A call this thread never saw is left alone. */
38
+ skip(id: string): void;
39
+ /** Streams the turn as one assistant message, ending at the agent's next new tool call or at the turn's end; with `tools` false, its tool calls are refused and skipped. */
40
+ respond(model: Model<Api>, signal: AbortSignal | undefined, tools?: boolean): AssistantMessageEventStream;
41
+ /** Waits for the agent to finish tool call `id`: until it completes or fails, the turn ends, or the agent waits on another call's permission. */
42
+ result(id: string, signal: AbortSignal): Promise<AcpToolOutput>;
43
+ /** Stops the running turn: tells the agent, and answers its waiting permissions as cancelled. */
44
+ cancel(): void;
45
+ close(reason?: Error): void;
46
+ }
@@ -0,0 +1,7 @@
1
+ import {
2
+ AcpThread2
3
+ } from "../../chunks/billing-svrhh5a5.js";
4
+ import"../../chunks/billing-9nn3yp18.js";
5
+ export {
6
+ AcpThread2 as AcpThread
7
+ };
@@ -0,0 +1,8 @@
1
+ import type { ContentBlock } from "@agentclientprotocol/sdk";
2
+ import type { Message, UserMessage } from "@nyte-ai/ai";
3
+ /** A message's identity for telling whether the agent's session already holds it. */
4
+ export declare function messageKey(message: Message): string;
5
+ /** A user message as prompt blocks; an image the agent cannot read becomes a note of its type. */
6
+ export declare function userBlocks(message: UserMessage, images: boolean): ContentBlock[];
7
+ /** The conversation as plain text, for an agent session that did not see it happen. */
8
+ export declare function transcriptText(messages: readonly Message[]): string;
@@ -0,0 +1,11 @@
1
+ import {
2
+ messageKey2,
3
+ userBlocks2,
4
+ transcriptText2
5
+ } from "../../chunks/billing-wmcbg6fw.js";
6
+ import"../../chunks/billing-9nn3yp18.js";
7
+ export {
8
+ messageKey2 as messageKey,
9
+ transcriptText2 as transcriptText,
10
+ userBlocks2 as userBlocks
11
+ };
@@ -0,0 +1,33 @@
1
+ import type { ToolCallContent, Usage } from "@agentclientprotocol/sdk";
2
+ import type { Api, AssistantMessage, AssistantMessageEventStream, Model, ToolCall } from "@nyte-ai/ai";
3
+ import type { ToolClass } from "@nyte-ai/schema";
4
+ import { Type } from "typebox";
5
+ import type { Static } from "typebox";
6
+ export declare const ACP_PROVIDER = "acp";
7
+ export declare const ACP_API = "acp";
8
+ export declare const MIRROR_TOOL = "acp";
9
+ /** A mirror call's arguments: the ACP session it ran in, the agent's own call id, title, kind, input and the paths it touches. */
10
+ export declare const mirrorArguments: Type.TObject<{
11
+ thread: Type.TString;
12
+ id: Type.TString;
13
+ title: Type.TString;
14
+ kind: Type.TString;
15
+ input: Type.TRecord<"^.*$", Type.TUnknown>;
16
+ paths: Type.TArray<Type.TString>;
17
+ }>;
18
+ export type MirrorArguments = Static<typeof mirrorArguments>;
19
+ export declare function emptyMessage(model: Model<Api>): AssistantMessage;
20
+ /** The class Nyte shows and gates an agent's tool call by, from the ACP kind, its paths and its input. */
21
+ export declare function mirrorClass(args: MirrorArguments): ToolClass;
22
+ /** What a finished agent tool call reports, as the text its mirror call returns. */
23
+ export declare function toolText(content: readonly ToolCallContent[], rawOutput: unknown): string;
24
+ /** Builds one assistant message from an agent's streamed text, thoughts and tool calls. */
25
+ export declare class Translator {
26
+ #private;
27
+ constructor(model: Model<Api>, output: AssistantMessage, stream: AssistantMessageEventStream);
28
+ text(delta: string): void;
29
+ thinking(delta: string): void;
30
+ call(call: ToolCall): void;
31
+ usage(usage: Usage): void;
32
+ end(): void;
33
+ }
@@ -0,0 +1,20 @@
1
+ import {
2
+ ACP_PROVIDER2,
3
+ ACP_API2,
4
+ MIRROR_TOOL2,
5
+ mirrorArguments2,
6
+ emptyMessage2,
7
+ mirrorClass2,
8
+ toolText2,
9
+ Translator2
10
+ } from "../../chunks/billing-9nn3yp18.js";
11
+ export {
12
+ ACP_API2 as ACP_API,
13
+ ACP_PROVIDER2 as ACP_PROVIDER,
14
+ MIRROR_TOOL2 as MIRROR_TOOL,
15
+ Translator2 as Translator,
16
+ emptyMessage2 as emptyMessage,
17
+ mirrorArguments2 as mirrorArguments,
18
+ mirrorClass2 as mirrorClass,
19
+ toolText2 as toolText
20
+ };
@@ -0,0 +1,189 @@
1
+ import type { PluginApi, RuntimeCall, RuntimeVerdict, SettingDefinition, ToolDefinition } from "@nyte-ai/core";
2
+ import type { ApprovalPolicy, ApprovalState } from "./schema.ts";
3
+ /** A tool call as the policy sees it: its tool's name, its class, and whether its tool lets a policy hold it. */
4
+ export interface ApprovalTool extends RuntimeCall {
5
+ readonly approval?: ToolDefinition["approval"];
6
+ }
7
+ /**
8
+ * The host's policy for tool calls, `full` by default. It applies to every
9
+ * session at its next call, including one already running.
10
+ *
11
+ * @category plugins
12
+ * @since 0.1.0
13
+ */
14
+ export declare const permissions: SettingDefinition<ApprovalPolicy>;
15
+ /**
16
+ * Why `policy` stops `tool` for the user in a workspace at `cwd`, or null
17
+ * when the call runs without asking. Reads, listings, delegation and tools
18
+ * whose `approval` is not `policy` never ask (a subagent's own calls ask in
19
+ * its session); under `auto-edit` an edit in the workspace runs unless it is
20
+ * under `.claude`, `.git` or `.nyte`.
21
+ *
22
+ * @category plugins
23
+ * @since 0.1.0
24
+ */
25
+ export declare function approvalReason(policy: ApprovalPolicy, tool: ApprovalTool, cwd: string): ApprovalState["reason"] | null;
26
+ /**
27
+ * The approval part with its handlers: the first answer is kept, and
28
+ * `session` records a grant for the tool and answers the session's other
29
+ * waiting approvals for it.
30
+ *
31
+ * @category plugins
32
+ * @since 0.1.0
33
+ */
34
+ export declare const approval: import("@nyte-ai/core").PartDefinition<{
35
+ class: {
36
+ kind: "read";
37
+ path: string;
38
+ } | {
39
+ kind: "list";
40
+ path: string;
41
+ } | {
42
+ kind: "edit";
43
+ path: string;
44
+ } | {
45
+ description?: string | undefined;
46
+ kind: "shell";
47
+ command: string;
48
+ } | {
49
+ kind: "delegate";
50
+ title: string | null;
51
+ role: "read" | "task" | "create" | "send" | "await" | "stop";
52
+ child: import("@nyte-ai/schema").Id<"session"> | null;
53
+ } | {
54
+ kind: "custom";
55
+ label: string;
56
+ };
57
+ reason: "edit" | "shell" | "tool" | "outside";
58
+ tool: string;
59
+ decision: "session" | "once" | "deny" | null;
60
+ }, {
61
+ once: {
62
+ input: import("@nyte-ai/schema").Schema<object>;
63
+ };
64
+ session: {
65
+ input: import("@nyte-ai/schema").Schema<object>;
66
+ };
67
+ deny: {
68
+ input: import("@nyte-ai/schema").Schema<object>;
69
+ };
70
+ }>;
71
+ declare function approveRuntimeCall(call: RuntimeCall, context: {
72
+ readonly api: PluginApi<"core">;
73
+ readonly signal: AbortSignal;
74
+ }): Promise<RuntimeVerdict>;
75
+ /**
76
+ * Gates tool calls on the session's `permissions` policy, keying grants on
77
+ * each tool's own name. A call in Nyte's loop that asks parks its
78
+ * before_tool hook on an approval part, so the request outlives a host
79
+ * restart and any client watching the session can answer it; a denial
80
+ * reaches the model as the rejected call's reason. A call another agent
81
+ * runtime asks to run comes through `approve` and waits on the same part
82
+ * while its runtime runs; its mirror call (`approval: "runtime"`) is not
83
+ * asked about again. Only a principal with owner authority can allow.
84
+ *
85
+ * @category plugins
86
+ * @since 0.1.0
87
+ */
88
+ declare const _default: {
89
+ id: string;
90
+ contribute: {
91
+ parts: import("@nyte-ai/core").PartDefinition<{
92
+ class: {
93
+ kind: "read";
94
+ path: string;
95
+ } | {
96
+ kind: "list";
97
+ path: string;
98
+ } | {
99
+ kind: "edit";
100
+ path: string;
101
+ } | {
102
+ description?: string | undefined;
103
+ kind: "shell";
104
+ command: string;
105
+ } | {
106
+ kind: "delegate";
107
+ title: string | null;
108
+ role: "read" | "task" | "create" | "send" | "await" | "stop";
109
+ child: import("@nyte-ai/schema").Id<"session"> | null;
110
+ } | {
111
+ kind: "custom";
112
+ label: string;
113
+ };
114
+ reason: "edit" | "shell" | "tool" | "outside";
115
+ tool: string;
116
+ decision: "session" | "once" | "deny" | null;
117
+ }, {
118
+ once: {
119
+ input: import("@nyte-ai/schema").Schema<object>;
120
+ };
121
+ session: {
122
+ input: import("@nyte-ai/schema").Schema<object>;
123
+ };
124
+ deny: {
125
+ input: import("@nyte-ai/schema").Schema<object>;
126
+ };
127
+ }>[];
128
+ settings: SettingDefinition<"ask" | "auto-edit" | "full">[];
129
+ };
130
+ approve: typeof approveRuntimeCall;
131
+ hooks: {
132
+ before_tool: (call: Readonly<{
133
+ readonly call: import("@nyte-ai/schema").Id<"call">;
134
+ readonly name: string;
135
+ readonly args: import("@nyte-ai/schema").Json;
136
+ readonly class: {
137
+ readonly kind: "read";
138
+ readonly path: string;
139
+ } | {
140
+ readonly kind: "list";
141
+ readonly path: string;
142
+ } | {
143
+ readonly kind: "edit";
144
+ readonly path: string;
145
+ } | {
146
+ readonly description?: string | undefined;
147
+ readonly kind: "shell";
148
+ readonly command: string;
149
+ } | {
150
+ readonly kind: "delegate";
151
+ readonly title: string | null;
152
+ readonly role: "read" | "task" | "create" | "send" | "await" | "stop";
153
+ readonly child: import("@nyte-ai/schema").Id<"session"> | null;
154
+ } | {
155
+ readonly kind: "custom";
156
+ readonly label: string;
157
+ };
158
+ }>, context: {
159
+ readonly api: {
160
+ readonly side: "core";
161
+ readonly sdk: import("@nyte-ai/core").Connection;
162
+ readonly contribute: import("@nyte-ai/core").Registries<"core">;
163
+ readonly storage: import("@nyte-ai/core").PluginStorage;
164
+ readonly signal: AbortSignal;
165
+ hook<N extends "session_activated" | "before_send" | "run_started" | "transform_transcript" | "before_compaction" | "before_request" | "before_tool" | "after_tool" | "after_request" | "run_ended">(name: N, entry: import("@nyte-ai/core").HookEntry<"core", N>): import("@nyte-ai/schema").Disposer;
166
+ report(issue: import("@nyte-ai/schema").ValidationIssue): void;
167
+ reload(): void;
168
+ } & {
169
+ readonly session: import("@nyte-ai/core").Session;
170
+ readonly env: import("@nyte-ai/core").ExecutionEnv;
171
+ wrapEnv(wrap: import("@nyte-ai/core").EnvironmentWrap): import("@nyte-ai/schema").Disposer;
172
+ readonly inputs: import("@nyte-ai/core").Resources;
173
+ request<T = string>(input: import("@nyte-ai/schema").ModelRequestInput<T>): Promise<import("@nyte-ai/schema").ModelRequestOutcome<T>>;
174
+ approve(call: RuntimeCall, signal: AbortSignal): Promise<RuntimeVerdict>;
175
+ };
176
+ readonly signal: AbortSignal;
177
+ readonly session: import("@nyte-ai/schema").SessionId | null;
178
+ readonly head: import("@nyte-ai/schema").HeadName | null;
179
+ readonly run: import("@nyte-ai/schema").RunId | null;
180
+ } & import("@nyte-ai/core").Durable) => Promise<{
181
+ action: "continue";
182
+ reason?: undefined;
183
+ } | {
184
+ action: "reject";
185
+ reason: string;
186
+ }>;
187
+ };
188
+ };
189
+ export default _default;
@@ -0,0 +1,143 @@
1
+ import {
2
+ PERMISSIONS2,
3
+ approvalPolicy2,
4
+ APPROVAL_POLICIES2,
5
+ approval2,
6
+ openApprovals2
7
+ } from "../../chunks/billing-h13r0byk.js";
8
+
9
+ // src/approvals/approvals.ts
10
+ import { posix } from "node:path";
11
+ import { definePart } from "@nyte-ai/core";
12
+ import { SdkError } from "@nyte-ai/schema";
13
+ var DENIED = "The user denied this tool call. Ask them how to proceed instead of retrying it.";
14
+ var UNANSWERED = "The approval request closed before the user answered.";
15
+ var permissions = {
16
+ id: PERMISSIONS2,
17
+ label: "Permissions",
18
+ schema: approvalPolicy2,
19
+ choices: APPROVAL_POLICIES2,
20
+ default: "full",
21
+ scope: "host"
22
+ };
23
+ var GUARDED = new Set([".claude", ".git", ".nyte"]);
24
+ function grantKey(tool) {
25
+ return `grant:${tool}`;
26
+ }
27
+ function workspacePath(cwd, path) {
28
+ const root = posix.resolve(cwd);
29
+ const target = posix.resolve(root, path);
30
+ if (target === root)
31
+ return "";
32
+ return target.startsWith(`${root}/`) ? target.slice(root.length + 1) : null;
33
+ }
34
+ function approvalReason(policy, tool, cwd) {
35
+ const subject = tool.class;
36
+ if (policy === "full" || (tool.approval ?? "policy") !== "policy")
37
+ return null;
38
+ if (subject.kind === "read" || subject.kind === "list" || subject.kind === "delegate")
39
+ return null;
40
+ if (subject.kind === "shell")
41
+ return "shell";
42
+ if (subject.kind === "edit") {
43
+ const path = workspacePath(cwd, subject.path);
44
+ if (path === null)
45
+ return "outside";
46
+ return policy === "ask" || GUARDED.has(path.split("/", 1)[0] ?? "") ? "edit" : null;
47
+ }
48
+ return "tool";
49
+ }
50
+ async function readPolicy(api) {
51
+ const value = await api.contribute.settings.value(PERMISSIONS2);
52
+ const checked = approvalPolicy2["~standard"].validate(value);
53
+ return checked instanceof Promise || checked.issues !== undefined ? permissions.default : checked.value;
54
+ }
55
+ async function pendingReason(api, tool) {
56
+ const reason = approvalReason(await readPolicy(api), tool, api.env.cwd);
57
+ if (reason === null)
58
+ return null;
59
+ return await api.storage.get(grantKey(tool.name)) === true ? null : reason;
60
+ }
61
+ function verdict(action) {
62
+ if (action === "once" || action === "session")
63
+ return { kind: "allow" };
64
+ return { kind: "deny", reason: action === "deny" ? DENIED : UNANSWERED };
65
+ }
66
+ async function decide(decision, context) {
67
+ const allowed = decision === "deny" || context.authority.has("owner");
68
+ let granted = null;
69
+ let refused = false;
70
+ const outcome = await context.part.update((current) => {
71
+ refused = current.decision === null && !allowed;
72
+ granted = current.decision === null || current.decision === decision ? current.tool : null;
73
+ return current.decision === null && allowed ? { ...current, decision } : current;
74
+ });
75
+ if (outcome.kind !== "updated")
76
+ throw new SdkError("invalid", "This approval is no longer waiting.");
77
+ if (refused)
78
+ throw new SdkError("denied", "Only the host's owner can allow a tool call.");
79
+ if (granted === null)
80
+ throw new SdkError("invalid", "This approval was already answered.");
81
+ if (decision !== "session")
82
+ return;
83
+ await context.api.storage.set(grantKey(granted), true);
84
+ for (const sibling of openApprovals2(await context.api.session.view())) {
85
+ if (sibling.part !== context.part.id && sibling.tool === granted)
86
+ await context.api.session.part(sibling.part).act("once", {});
87
+ }
88
+ return;
89
+ }
90
+ var handlers = {
91
+ once: (_input, context) => decide("once", context),
92
+ session: (_input, context) => decide("session", context),
93
+ deny: (_input, context) => decide("deny", context)
94
+ };
95
+ var approval = definePart({
96
+ ...approval2,
97
+ onAction: (action, input, context) => handlers[action](input, context)
98
+ });
99
+ async function approveRuntimeCall(call, context) {
100
+ const { api, signal } = context;
101
+ const reason = await pendingReason(api, call);
102
+ if (reason === null)
103
+ return { kind: "allow" };
104
+ const part = await api.session.parts.create(approval, {
105
+ state: { tool: call.name, class: call.class, reason, decision: null },
106
+ placement: { kind: "modal" }
107
+ });
108
+ try {
109
+ return verdict((await part.answer({ signal }))?.action);
110
+ } finally {
111
+ if (signal.aborted)
112
+ await part.close().catch(() => {
113
+ return;
114
+ });
115
+ }
116
+ }
117
+ var approvals_default = {
118
+ id: "approvals",
119
+ contribute: { parts: [approval], settings: [permissions] },
120
+ approve: approveRuntimeCall,
121
+ hooks: {
122
+ before_tool: async (call, context) => {
123
+ const { api } = context;
124
+ const definition = api.contribute.tools.list().find((tool) => tool.name === call.name);
125
+ const reason = await context.memo("reason", () => pendingReason(api, { name: call.name, class: call.class, approval: definition?.approval }));
126
+ if (reason === null)
127
+ return { action: "continue" };
128
+ const part = await api.session.parts.create(approval, {
129
+ state: { tool: call.name, class: call.class, reason, decision: null },
130
+ placement: { kind: "modal" }
131
+ });
132
+ const outcome = await context.wait({ kind: "part", part: part.id });
133
+ const answered = verdict(outcome.kind === "part" ? outcome.answer?.action : undefined);
134
+ return answered.kind === "allow" ? { action: "continue" } : { action: "reject", reason: answered.reason };
135
+ }
136
+ }
137
+ };
138
+ export {
139
+ approval,
140
+ approvalReason,
141
+ approvals_default as default,
142
+ permissions
143
+ };
@@ -0,0 +1,169 @@
1
+ import type { Infer, PartId, SessionView } from "@nyte-ai/schema";
2
+ declare const policy: import("@nyte-ai/schema").Schema<"ask" | "auto-edit" | "full">;
3
+ /**
4
+ * When a tool call waits for the user: `ask` before any call that may change
5
+ * the workspace, `auto-edit` before shell commands, edits outside the
6
+ * workspace and tools whose effects are unknown, `full` never.
7
+ */
8
+ export type ApprovalPolicy = Infer<typeof policy>;
9
+ /** The setting that holds the policy; it names the terminal's `/permissions` command. */
10
+ export declare const PERMISSIONS = "permissions";
11
+ /** The policy setting's schema, shared by the plugin and the clients that read it. */
12
+ export declare const approvalPolicy: import("@nyte-ai/schema").Schema<"ask" | "auto-edit" | "full">;
13
+ /** Each policy with the words every client shows for it, in menu order. */
14
+ export declare const APPROVAL_POLICIES: readonly [{
15
+ readonly value: "ask";
16
+ readonly label: "Ask first";
17
+ readonly description: "Asks before every command and file change";
18
+ }, {
19
+ readonly value: "auto-edit";
20
+ readonly label: "Auto-edit";
21
+ readonly description: "Edits workspace files, asks before commands and anything outside";
22
+ }, {
23
+ readonly value: "full";
24
+ readonly label: "Full access";
25
+ readonly description: "Runs every tool without asking";
26
+ }];
27
+ declare const state: import("@nyte-ai/schema").Schema<{
28
+ class: {
29
+ kind: "read";
30
+ path: string;
31
+ } | {
32
+ kind: "list";
33
+ path: string;
34
+ } | {
35
+ kind: "edit";
36
+ path: string;
37
+ } | {
38
+ description?: string | undefined;
39
+ kind: "shell";
40
+ command: string;
41
+ } | {
42
+ kind: "delegate";
43
+ title: string | null;
44
+ role: "read" | "task" | "create" | "send" | "await" | "stop";
45
+ child: import("@nyte-ai/schema").Id<"session"> | null;
46
+ } | {
47
+ kind: "custom";
48
+ label: string;
49
+ };
50
+ reason: "edit" | "shell" | "tool" | "outside";
51
+ tool: string;
52
+ decision: "session" | "once" | "deny" | null;
53
+ }>;
54
+ /**
55
+ * One gated tool call: its tool, its class, why it asks (`shell`, `edit` in
56
+ * the workspace, `outside` the workspace, or another `tool`), and the user's
57
+ * first decision, null while it waits.
58
+ */
59
+ export type ApprovalState = Infer<typeof state>;
60
+ /** What the user can answer, as part actions. */
61
+ export type ApprovalDecision = Exclude<ApprovalState["decision"], null>;
62
+ /** The three answers in the order every client offers them, with their shared labels. */
63
+ export declare const APPROVAL_ACTIONS: readonly [{
64
+ readonly action: "once";
65
+ readonly label: "Allow once";
66
+ }, {
67
+ readonly action: "session";
68
+ readonly label: "Allow for this session";
69
+ }, {
70
+ readonly action: "deny";
71
+ readonly label: "Deny";
72
+ }];
73
+ /** The question an approval asks and the command, path or label it is about. */
74
+ export interface ApprovalPrompt {
75
+ readonly title: string;
76
+ readonly detail: string;
77
+ }
78
+ /** The words every client shows for an approval. */
79
+ export declare function approvalPrompt(current: Pick<ApprovalState, "tool" | "class" | "reason">): ApprovalPrompt;
80
+ /**
81
+ * A modal request to run one tool call. Its first answer stands: once,
82
+ * session (which also allows the tool for the rest of the session), or deny.
83
+ *
84
+ * @category plugins
85
+ * @since 0.1.0
86
+ */
87
+ export declare const approval: {
88
+ kind: string;
89
+ state: import("@nyte-ai/schema").Schema<{
90
+ class: {
91
+ kind: "read";
92
+ path: string;
93
+ } | {
94
+ kind: "list";
95
+ path: string;
96
+ } | {
97
+ kind: "edit";
98
+ path: string;
99
+ } | {
100
+ description?: string | undefined;
101
+ kind: "shell";
102
+ command: string;
103
+ } | {
104
+ kind: "delegate";
105
+ title: string | null;
106
+ role: "read" | "task" | "create" | "send" | "await" | "stop";
107
+ child: import("@nyte-ai/schema").Id<"session"> | null;
108
+ } | {
109
+ kind: "custom";
110
+ label: string;
111
+ };
112
+ reason: "edit" | "shell" | "tool" | "outside";
113
+ tool: string;
114
+ decision: "session" | "once" | "deny" | null;
115
+ }>;
116
+ actions: {
117
+ once: {
118
+ input: import("@nyte-ai/schema").Schema<object>;
119
+ };
120
+ session: {
121
+ input: import("@nyte-ai/schema").Schema<object>;
122
+ };
123
+ deny: {
124
+ input: import("@nyte-ai/schema").Schema<object>;
125
+ };
126
+ };
127
+ fallback: (current: {
128
+ class: {
129
+ kind: "read";
130
+ path: string;
131
+ } | {
132
+ kind: "list";
133
+ path: string;
134
+ } | {
135
+ kind: "edit";
136
+ path: string;
137
+ } | {
138
+ description?: string | undefined;
139
+ kind: "shell";
140
+ command: string;
141
+ } | {
142
+ kind: "delegate";
143
+ title: string | null;
144
+ role: "read" | "task" | "create" | "send" | "await" | "stop";
145
+ child: import("@nyte-ai/schema").Id<"session"> | null;
146
+ } | {
147
+ kind: "custom";
148
+ label: string;
149
+ };
150
+ reason: "edit" | "shell" | "tool" | "outside";
151
+ tool: string;
152
+ decision: "session" | "once" | "deny" | null;
153
+ }, { id }: {
154
+ readonly id: PartId;
155
+ }) => string;
156
+ };
157
+ /** An approval still waiting for the user, with the part its answer goes to. */
158
+ export type OpenApproval = Pick<ApprovalState, "tool" | "class" | "reason"> & {
159
+ readonly part: PartId;
160
+ };
161
+ /**
162
+ * Returns the live approvals nobody has answered, oldest first. Parts from a
163
+ * stopped run and parts with invalid state are left out.
164
+ *
165
+ * @category plugins
166
+ * @since 0.1.0
167
+ */
168
+ export declare function openApprovals(view: Pick<SessionView, "parts"> | undefined): readonly OpenApproval[];
169
+ export {};