@nebutra/agent-runtime 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (179) hide show
  1. package/.turbo/turbo-build.log +115 -0
  2. package/.turbo/turbo-test.log +44 -0
  3. package/.turbo/turbo-typecheck.log +4 -0
  4. package/CHANGELOG.md +253 -0
  5. package/LICENSE +676 -0
  6. package/README.md +50 -0
  7. package/dist/adapters/dispatcher-sse.d.ts +68 -0
  8. package/dist/adapters/dispatcher-sse.js +11 -0
  9. package/dist/adapters/dispatcher-sse.js.map +1 -0
  10. package/dist/adapters/index.d.ts +12 -0
  11. package/dist/adapters/index.js +21 -0
  12. package/dist/adapters/index.js.map +1 -0
  13. package/dist/adapters/mcp-catalog.d.ts +58 -0
  14. package/dist/adapters/mcp-catalog.js +9 -0
  15. package/dist/adapters/mcp-catalog.js.map +1 -0
  16. package/dist/adapters/prisma-rollout.d.ts +60 -0
  17. package/dist/adapters/prisma-rollout.js +7 -0
  18. package/dist/adapters/prisma-rollout.js.map +1 -0
  19. package/dist/chunk-24ZXP7FI.js +93 -0
  20. package/dist/chunk-24ZXP7FI.js.map +1 -0
  21. package/dist/chunk-2DA6Q6TN.js +126 -0
  22. package/dist/chunk-2DA6Q6TN.js.map +1 -0
  23. package/dist/chunk-37BBB2P2.js +73 -0
  24. package/dist/chunk-37BBB2P2.js.map +1 -0
  25. package/dist/chunk-57W3AR43.js +52 -0
  26. package/dist/chunk-57W3AR43.js.map +1 -0
  27. package/dist/chunk-5N4644PB.js +67 -0
  28. package/dist/chunk-5N4644PB.js.map +1 -0
  29. package/dist/chunk-5YS7WAPS.js +177 -0
  30. package/dist/chunk-5YS7WAPS.js.map +1 -0
  31. package/dist/chunk-6EGG2OZC.js +13 -0
  32. package/dist/chunk-6EGG2OZC.js.map +1 -0
  33. package/dist/chunk-7BUOF367.js +126 -0
  34. package/dist/chunk-7BUOF367.js.map +1 -0
  35. package/dist/chunk-BJBBR3QA.js +121 -0
  36. package/dist/chunk-BJBBR3QA.js.map +1 -0
  37. package/dist/chunk-CGRCUKGT.js +73 -0
  38. package/dist/chunk-CGRCUKGT.js.map +1 -0
  39. package/dist/chunk-FUG5DT2C.js +75 -0
  40. package/dist/chunk-FUG5DT2C.js.map +1 -0
  41. package/dist/chunk-LO24VOA3.js +199 -0
  42. package/dist/chunk-LO24VOA3.js.map +1 -0
  43. package/dist/chunk-MUF7ZZTO.js +57 -0
  44. package/dist/chunk-MUF7ZZTO.js.map +1 -0
  45. package/dist/chunk-NN7DATXA.js +46 -0
  46. package/dist/chunk-NN7DATXA.js.map +1 -0
  47. package/dist/chunk-PGGWSUTM.js +33 -0
  48. package/dist/chunk-PGGWSUTM.js.map +1 -0
  49. package/dist/chunk-RDKYDMXT.js +135 -0
  50. package/dist/chunk-RDKYDMXT.js.map +1 -0
  51. package/dist/chunk-YYFPDBJG.js +63 -0
  52. package/dist/chunk-YYFPDBJG.js.map +1 -0
  53. package/dist/chunk-ZMYX5VBU.js +135 -0
  54. package/dist/chunk-ZMYX5VBU.js.map +1 -0
  55. package/dist/chunk-ZTSKS42I.js +131 -0
  56. package/dist/chunk-ZTSKS42I.js.map +1 -0
  57. package/dist/commands.d.ts +74 -0
  58. package/dist/commands.js +10 -0
  59. package/dist/commands.js.map +1 -0
  60. package/dist/definitions.d.ts +94 -0
  61. package/dist/definitions.js +15 -0
  62. package/dist/definitions.js.map +1 -0
  63. package/dist/dispatcher.d.ts +50 -0
  64. package/dist/dispatcher.js +8 -0
  65. package/dist/dispatcher.js.map +1 -0
  66. package/dist/durable-turn.d.ts +58 -0
  67. package/dist/durable-turn.js +9 -0
  68. package/dist/durable-turn.js.map +1 -0
  69. package/dist/hook-pipeline.d.ts +114 -0
  70. package/dist/hook-pipeline.js +13 -0
  71. package/dist/hook-pipeline.js.map +1 -0
  72. package/dist/index.d.ts +1874 -0
  73. package/dist/index.js +3117 -0
  74. package/dist/index.js.map +1 -0
  75. package/dist/loop.d.ts +78 -0
  76. package/dist/loop.js +9 -0
  77. package/dist/loop.js.map +1 -0
  78. package/dist/mcp-bridge.d.ts +48 -0
  79. package/dist/mcp-bridge.js +8 -0
  80. package/dist/mcp-bridge.js.map +1 -0
  81. package/dist/model.d.ts +154 -0
  82. package/dist/model.js +9 -0
  83. package/dist/model.js.map +1 -0
  84. package/dist/policy.d.ts +130 -0
  85. package/dist/policy.js +23 -0
  86. package/dist/policy.js.map +1 -0
  87. package/dist/protocol.d.ts +170 -0
  88. package/dist/protocol.js +15 -0
  89. package/dist/protocol.js.map +1 -0
  90. package/dist/rollout-store-persistent.d.ts +48 -0
  91. package/dist/rollout-store-persistent.js +9 -0
  92. package/dist/rollout-store-persistent.js.map +1 -0
  93. package/dist/rollout.d.ts +82 -0
  94. package/dist/rollout.js +15 -0
  95. package/dist/rollout.js.map +1 -0
  96. package/dist/sandbox.d.ts +65 -0
  97. package/dist/sandbox.js +15 -0
  98. package/dist/sandbox.js.map +1 -0
  99. package/dist/skills.d.ts +93 -0
  100. package/dist/skills.js +10 -0
  101. package/dist/skills.js.map +1 -0
  102. package/dist/subagents.d.ts +129 -0
  103. package/dist/subagents.js +21 -0
  104. package/dist/subagents.js.map +1 -0
  105. package/dist/tools.d.ts +77 -0
  106. package/dist/tools.js +9 -0
  107. package/dist/tools.js.map +1 -0
  108. package/package.json +74 -0
  109. package/src/adapters/dispatcher-sse.test.ts +218 -0
  110. package/src/adapters/dispatcher-sse.ts +222 -0
  111. package/src/adapters/index.ts +18 -0
  112. package/src/adapters/mcp-catalog.test.ts +213 -0
  113. package/src/adapters/mcp-catalog.ts +188 -0
  114. package/src/adapters/prisma-rollout.test.ts +153 -0
  115. package/src/adapters/prisma-rollout.ts +104 -0
  116. package/src/agent-runtime.test.ts +176 -0
  117. package/src/artifact-stream.test.ts +330 -0
  118. package/src/artifact-stream.ts +453 -0
  119. package/src/channel-gateway.test.ts +432 -0
  120. package/src/channel-gateway.ts +357 -0
  121. package/src/code-review.test.ts +501 -0
  122. package/src/code-review.ts +495 -0
  123. package/src/command-suggestions.test.ts +251 -0
  124. package/src/command-suggestions.ts +338 -0
  125. package/src/commands.test.ts +184 -0
  126. package/src/commands.ts +140 -0
  127. package/src/commit-message.test.ts +249 -0
  128. package/src/commit-message.ts +180 -0
  129. package/src/context-compaction.test.ts +522 -0
  130. package/src/context-compaction.ts +434 -0
  131. package/src/definitions.test.ts +78 -0
  132. package/src/definitions.ts +190 -0
  133. package/src/deployment-status.test.ts +215 -0
  134. package/src/deployment-status.ts +227 -0
  135. package/src/design-context.test.ts +195 -0
  136. package/src/design-context.ts +198 -0
  137. package/src/dispatcher.test.ts +234 -0
  138. package/src/dispatcher.ts +189 -0
  139. package/src/durable-turn.test.ts +209 -0
  140. package/src/durable-turn.ts +135 -0
  141. package/src/edit-planner.test.ts +204 -0
  142. package/src/edit-planner.ts +325 -0
  143. package/src/fuzzy-match.test.ts +311 -0
  144. package/src/fuzzy-match.ts +444 -0
  145. package/src/hook-pipeline.test.ts +279 -0
  146. package/src/hook-pipeline.ts +373 -0
  147. package/src/inbound-admission.test.ts +394 -0
  148. package/src/inbound-admission.ts +246 -0
  149. package/src/index.ts +47 -0
  150. package/src/loop.test.ts +161 -0
  151. package/src/loop.ts +211 -0
  152. package/src/mcp-bridge.test.ts +165 -0
  153. package/src/mcp-bridge.ts +76 -0
  154. package/src/memory-provider.test.ts +232 -0
  155. package/src/memory-provider.ts +257 -0
  156. package/src/model.ts +168 -0
  157. package/src/permission-ruleset.test.ts +301 -0
  158. package/src/permission-ruleset.ts +200 -0
  159. package/src/policy.ts +151 -0
  160. package/src/project-repo.test.ts +232 -0
  161. package/src/project-repo.ts +311 -0
  162. package/src/protocol.ts +159 -0
  163. package/src/rollout-store-persistent.test.ts +217 -0
  164. package/src/rollout-store-persistent.ts +166 -0
  165. package/src/rollout.ts +150 -0
  166. package/src/sandbox.ts +113 -0
  167. package/src/session-share.test.ts +360 -0
  168. package/src/session-share.ts +310 -0
  169. package/src/skill-distillation.test.ts +177 -0
  170. package/src/skill-distillation.ts +369 -0
  171. package/src/skills.test.ts +277 -0
  172. package/src/skills.ts +255 -0
  173. package/src/subagents.test.ts +290 -0
  174. package/src/subagents.ts +332 -0
  175. package/src/tools.ts +126 -0
  176. package/src/workbench.test.ts +0 -0
  177. package/src/workbench.ts +0 -0
  178. package/tsconfig.json +12 -0
  179. package/tsup.config.ts +33 -0
package/dist/loop.d.ts ADDED
@@ -0,0 +1,78 @@
1
+ import { TurnConfig, TurnUsage, ThreadEvent } from './model.js';
2
+ import { ReviewDecision, RuleDecision, ApprovalPolicy } from './policy.js';
3
+ import { ServerRequest } from './protocol.js';
4
+ import { RolloutStore } from './rollout.js';
5
+ import { ToolRegistry } from './tools.js';
6
+ import 'zod';
7
+
8
+ /**
9
+ * Agent loop runner (WRAP — the turn engine).
10
+ *
11
+ * Faithful re-expression of the upstream loop: a turn is
12
+ * `loop { model_call → emit items → execute tools → feed results back }`
13
+ * until the model stops requesting tools or a bounded step ceiling is hit.
14
+ * Single-threaded (Cognition teaching: shared context, no conflicting
15
+ * sub-agent decisions). Every item is appended to the tenant-scoped rollout
16
+ * as it reaches a terminal state, so the turn is resumable by replay.
17
+ *
18
+ * The model call is abstracted behind {@link ModelInvoker} so this WRAPs an
19
+ * existing model stack (e.g. `@nebutra/agents`) rather than re-porting
20
+ * provider/routing/fallback. No untrusted code runs here — command items are
21
+ * dispatched through the tool registry / external-sandbox seam.
22
+ */
23
+
24
+ /** A single thing the model emitted in one round. */
25
+ type ModelEmission = {
26
+ readonly kind: "text";
27
+ readonly text: string;
28
+ } | {
29
+ readonly kind: "tool_call";
30
+ readonly id: string;
31
+ readonly name: string;
32
+ readonly args: unknown;
33
+ };
34
+ interface ModelRoundResult {
35
+ readonly emissions: readonly ModelEmission[];
36
+ readonly usage?: Partial<TurnUsage>;
37
+ }
38
+ interface ModelRoundRequest {
39
+ readonly config: TurnConfig;
40
+ /** Running transcript: user input, agent text, and tool results. */
41
+ readonly history: readonly {
42
+ readonly role: string;
43
+ readonly content: string;
44
+ }[];
45
+ readonly toolNames: readonly string[];
46
+ }
47
+ /** Abstracts the model stack — implement over `@nebutra/agents`, etc. */
48
+ interface ModelInvoker {
49
+ invoke(request: ModelRoundRequest): Promise<ModelRoundResult>;
50
+ }
51
+ /** Server-initiated approval transport (see {@link ServerRequest}). */
52
+ interface ApprovalGate {
53
+ request(serverRequest: ServerRequest): Promise<ReviewDecision>;
54
+ }
55
+ /** Classifies a tool call into a static rule decision before approval. */
56
+ type RuleEvaluator = (toolName: string, args: unknown) => RuleDecision;
57
+ interface RunTurnDeps {
58
+ readonly tenantId: string;
59
+ readonly threadId: string;
60
+ readonly config: TurnConfig;
61
+ readonly approvalPolicy: ApprovalPolicy;
62
+ readonly model: ModelInvoker;
63
+ readonly tools: ToolRegistry;
64
+ readonly store: RolloutStore;
65
+ readonly approvalGate: ApprovalGate;
66
+ /** Defaults to: everything requires a prompt (safe). */
67
+ readonly ruleEvaluator?: RuleEvaluator;
68
+ /** Bounded steps (parity with upstream step ceiling). Default 20. */
69
+ readonly maxSteps?: number;
70
+ }
71
+ /**
72
+ * Drive one turn to completion. Yields the {@link ThreadEvent} stream and
73
+ * appends each terminal item + the turn outcome to the rollout store.
74
+ * Never throws to the caller — failures surface as a `turn.failed` event.
75
+ */
76
+ declare function runTurn(userInput: string, deps: RunTurnDeps): AsyncGenerator<ThreadEvent>;
77
+
78
+ export { type ApprovalGate, type ModelEmission, type ModelInvoker, type ModelRoundRequest, type ModelRoundResult, type RuleEvaluator, type RunTurnDeps, runTurn };
package/dist/loop.js ADDED
@@ -0,0 +1,9 @@
1
+ import {
2
+ runTurn
3
+ } from "./chunk-BJBBR3QA.js";
4
+ import "./chunk-CGRCUKGT.js";
5
+ import "./chunk-37BBB2P2.js";
6
+ export {
7
+ runTurn
8
+ };
9
+ //# sourceMappingURL=loop.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
@@ -0,0 +1,48 @@
1
+ import { ToolDefinition, ToolRegistry, McpClientLike } from './tools.js';
2
+ import 'zod';
3
+
4
+ /**
5
+ * MCP activation bridge (WRAP — capability #9, activation seam).
6
+ *
7
+ * Concrete bridge that registers external MCP-server tools into the runtime's
8
+ * uniform tool model. It does NOT import `@nebutra/mcp` (WIP / do-not-import):
9
+ * instead it defines minimal injectable ports so callers wire `@nebutra/mcp`
10
+ * (`serverRegistry` + `mcpClient`) without this package taking a hard dep.
11
+ *
12
+ * Tenant-scoped by construction: the catalog port is always queried with the
13
+ * caller's `{ tenantId, plan }`, so a tenant only ever sees its own MCP
14
+ * servers/tools. Fail-closed on missing tenant.
15
+ */
16
+
17
+ /**
18
+ * Port over an MCP server catalog (satisfied by `@nebutra/mcp`'s
19
+ * `serverRegistry` + plan middleware). Returns only the tools visible to the
20
+ * given tenant/plan — visibility/plan-gating is the port's responsibility.
21
+ */
22
+ interface McpServerCatalogPort {
23
+ listTools(ctx: {
24
+ tenantId: string;
25
+ plan?: string;
26
+ }): Promise<{
27
+ server: string;
28
+ definition: ToolDefinition;
29
+ }[]>;
30
+ }
31
+ interface ActivateMcpToolsResult {
32
+ /** Tool names newly registered into the registry, in catalog order. */
33
+ readonly registered: readonly string[];
34
+ /** Tool names skipped because the name was already registered. */
35
+ readonly skipped: readonly string[];
36
+ }
37
+ /**
38
+ * List the tenant/plan-visible MCP tools, adapt each via {@link adaptMcpTool},
39
+ * and register them into the {@link ToolRegistry}. A tool whose name is already
40
+ * registered is skipped (reported, never thrown). Empty/blank tenantId fails
41
+ * closed before any catalog call.
42
+ */
43
+ declare function activateMcpTools(registry: ToolRegistry, catalog: McpServerCatalogPort, client: McpClientLike, ctx: {
44
+ tenantId: string;
45
+ plan?: string;
46
+ }): Promise<ActivateMcpToolsResult>;
47
+
48
+ export { type ActivateMcpToolsResult, type McpServerCatalogPort, activateMcpTools };
@@ -0,0 +1,8 @@
1
+ import {
2
+ activateMcpTools
3
+ } from "./chunk-PGGWSUTM.js";
4
+ import "./chunk-NN7DATXA.js";
5
+ export {
6
+ activateMcpTools
7
+ };
8
+ //# sourceMappingURL=mcp-bridge.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
@@ -0,0 +1,154 @@
1
+ /**
2
+ * Thread / Turn / Item model + event lifecycle (WRAP — capability #6).
3
+ *
4
+ * Faithful re-expression of the upstream agent-runtime item taxonomy and event
5
+ * stream (generated TS types in the source SDK, themselves derived from the
6
+ * Rust `exec_events` definitions). Renamed to neutral domain terms and made
7
+ * tenant-scoped. No enforcement here — pure data + state machine.
8
+ *
9
+ * Hierarchy: Thread -> Turn -> Item.
10
+ * Thread : a durable, tenant-scoped conversation (resumable by replay).
11
+ * Turn : one user-input -> model-completion cycle.
12
+ * Item : the atomic recorded unit inside a turn.
13
+ */
14
+ /** Lifecycle of a stateful item that runs over time. */
15
+ type RunStatus = "in_progress" | "completed" | "failed";
16
+ /** Terminal status for an applied patch (no `in_progress` terminal form). */
17
+ type PatchApplyStatus = "completed" | "failed";
18
+ /** Kind of a single file mutation within a patch. */
19
+ type PatchChangeKind = "add" | "delete" | "update";
20
+ interface FileUpdateChange {
21
+ readonly path: string;
22
+ readonly kind: PatchChangeKind;
23
+ }
24
+ interface ItemBase {
25
+ /** Stable identifier, unique within the owning thread. */
26
+ readonly id: string;
27
+ }
28
+ /** Natural-language (or structured-JSON) response from the agent. */
29
+ interface AgentMessageItem extends ItemBase {
30
+ readonly type: "agent_message";
31
+ readonly text: string;
32
+ }
33
+ /** The agent's reasoning summary. */
34
+ interface ReasoningItem extends ItemBase {
35
+ readonly type: "reasoning";
36
+ readonly text: string;
37
+ }
38
+ /**
39
+ * A command the agent asked to run. The runtime itself never executes it —
40
+ * see {@link ./sandbox} for the external-sandbox delegation seam.
41
+ */
42
+ interface CommandExecutionItem extends ItemBase {
43
+ readonly type: "command_execution";
44
+ readonly command: string;
45
+ /** Aggregated stdout+stderr captured by the external executor. */
46
+ readonly aggregatedOutput: string;
47
+ /** Present once the command exits. */
48
+ readonly exitCode?: number;
49
+ readonly status: RunStatus;
50
+ }
51
+ /** A patch produced by the agent. Emitted once it succeeds or fails. */
52
+ interface FileChangeItem extends ItemBase {
53
+ readonly type: "file_change";
54
+ readonly changes: readonly FileUpdateChange[];
55
+ readonly status: PatchApplyStatus;
56
+ }
57
+ /** A call to a tool exposed via an MCP server. */
58
+ interface McpToolCallItem extends ItemBase {
59
+ readonly type: "mcp_tool_call";
60
+ readonly server: string;
61
+ readonly tool: string;
62
+ readonly arguments: unknown;
63
+ readonly result?: {
64
+ readonly content: unknown;
65
+ readonly structuredContent?: unknown;
66
+ };
67
+ readonly error?: {
68
+ readonly message: string;
69
+ };
70
+ readonly status: RunStatus;
71
+ }
72
+ /** A web-search request issued by the agent. */
73
+ interface WebSearchItem extends ItemBase {
74
+ readonly type: "web_search";
75
+ readonly query: string;
76
+ }
77
+ interface TodoEntry {
78
+ readonly text: string;
79
+ readonly completed: boolean;
80
+ }
81
+ /** The agent's running to-do list for the turn. */
82
+ interface TodoListItem extends ItemBase {
83
+ readonly type: "todo_list";
84
+ readonly items: readonly TodoEntry[];
85
+ }
86
+ /** A non-fatal error surfaced as an item (the turn may continue). */
87
+ interface ErrorItem extends ItemBase {
88
+ readonly type: "error";
89
+ readonly message: string;
90
+ }
91
+ /** Canonical closed union of thread items. */
92
+ type ThreadItem = AgentMessageItem | ReasoningItem | CommandExecutionItem | FileChangeItem | McpToolCallItem | WebSearchItem | TodoListItem | ErrorItem;
93
+ type ThreadItemType = ThreadItem["type"];
94
+ /** Token accounting for a completed turn. */
95
+ interface TurnUsage {
96
+ readonly inputTokens: number;
97
+ readonly cachedInputTokens: number;
98
+ readonly outputTokens: number;
99
+ readonly reasoningOutputTokens: number;
100
+ }
101
+ /** Fatal error payload emitted by the stream. */
102
+ interface ThreadError {
103
+ readonly message: string;
104
+ }
105
+ /**
106
+ * Event lifecycle observed by a client:
107
+ * thread.started -> turn.started -> (item.started -> item.updated* ->
108
+ * item.completed)* -> turn.completed | turn.failed, with a terminal `error`.
109
+ */
110
+ type ThreadEvent = {
111
+ readonly type: "thread.started";
112
+ readonly threadId: string;
113
+ } | {
114
+ readonly type: "turn.started";
115
+ } | {
116
+ readonly type: "turn.completed";
117
+ readonly usage: TurnUsage;
118
+ } | {
119
+ readonly type: "turn.failed";
120
+ readonly error: ThreadError;
121
+ } | {
122
+ readonly type: "item.started";
123
+ readonly item: ThreadItem;
124
+ } | {
125
+ readonly type: "item.updated";
126
+ readonly item: ThreadItem;
127
+ } | {
128
+ readonly type: "item.completed";
129
+ readonly item: ThreadItem;
130
+ } | {
131
+ readonly type: "error";
132
+ readonly message: string;
133
+ };
134
+ type ThreadEventType = ThreadEvent["type"];
135
+ /**
136
+ * Per-turn config snapshot. Immutable within a turn; rebindable between turns.
137
+ * Tenant defaults are merged with per-request overrides via {@link mergeTurnConfig}.
138
+ */
139
+ interface TurnConfig {
140
+ readonly model: string;
141
+ readonly provider: string;
142
+ /** Stringly-typed approval-policy tag — see {@link ./policy}. */
143
+ readonly approvalPolicy: string;
144
+ /** Stringly-typed capability-policy tag — see {@link ./policy}. */
145
+ readonly capabilityPolicy: string;
146
+ readonly reasoningEffort?: "low" | "medium" | "high";
147
+ }
148
+ type TurnConfigOverrides = Partial<TurnConfig>;
149
+ /** Freeze a tenant-default config against per-turn overrides. */
150
+ declare function mergeTurnConfig(base: TurnConfig, overrides?: TurnConfigOverrides): TurnConfig;
151
+ /** Whether an event is a terminal turn outcome. */
152
+ declare function isTurnTerminal(event: ThreadEvent): boolean;
153
+
154
+ export { type AgentMessageItem, type CommandExecutionItem, type ErrorItem, type FileChangeItem, type FileUpdateChange, type McpToolCallItem, type PatchApplyStatus, type PatchChangeKind, type ReasoningItem, type RunStatus, type ThreadError, type ThreadEvent, type ThreadEventType, type ThreadItem, type ThreadItemType, type TodoEntry, type TodoListItem, type TurnConfig, type TurnConfigOverrides, type TurnUsage, type WebSearchItem, isTurnTerminal, mergeTurnConfig };
package/dist/model.js ADDED
@@ -0,0 +1,9 @@
1
+ import {
2
+ isTurnTerminal,
3
+ mergeTurnConfig
4
+ } from "./chunk-6EGG2OZC.js";
5
+ export {
6
+ isTurnTerminal,
7
+ mergeTurnConfig
8
+ };
9
+ //# sourceMappingURL=model.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
@@ -0,0 +1,130 @@
1
+ import { z } from 'zod';
2
+
3
+ /**
4
+ * Approval + capability policy (WRAP — capability #8).
5
+ *
6
+ * Faithful re-expression of the upstream two orthogonal axes:
7
+ * 1. Approval policy — *when* to ask a human (AskForApproval).
8
+ * 2. Capability policy — *what* an external executor is permitted to do
9
+ * (SandboxPolicy). Policy/semantics only; enforcement is out of scope
10
+ * and lives behind the external-sandbox seam (see ./sandbox).
11
+ *
12
+ * Plus the static rule decision (execpolicy `Decision`) and the human's rich
13
+ * answer (`ReviewDecision`). Built on `@nebutra/permissions` for *who may
14
+ * approve*; this module models *what tier / what answer*.
15
+ */
16
+
17
+ /** Fine-grained per-category gates. `false` = auto-reject (not auto-ask). */
18
+ declare const granularApprovalConfigSchema: z.ZodObject<{
19
+ sandboxApproval: z.ZodBoolean;
20
+ rules: z.ZodBoolean;
21
+ skillApproval: z.ZodDefault<z.ZodBoolean>;
22
+ requestPermissions: z.ZodDefault<z.ZodBoolean>;
23
+ mcpElicitations: z.ZodBoolean;
24
+ }, z.core.$strip>;
25
+ type GranularApprovalConfig = z.infer<typeof granularApprovalConfigSchema>;
26
+ /**
27
+ * Approval tier.
28
+ * - `unless_trusted` : only known-safe read-only ops auto-approved; else ask.
29
+ * - `on_failure` : DEPRECATED — auto-run sandboxed, escalate on failure.
30
+ * - `on_request` : the model decides when to ask (default).
31
+ * - `granular` : per-category booleans.
32
+ * - `never` : failures returned to the model, never escalated.
33
+ */
34
+ declare const approvalPolicySchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
35
+ kind: z.ZodLiteral<"unless_trusted">;
36
+ }, z.core.$strip>, z.ZodObject<{
37
+ kind: z.ZodLiteral<"on_failure">;
38
+ }, z.core.$strip>, z.ZodObject<{
39
+ kind: z.ZodLiteral<"on_request">;
40
+ }, z.core.$strip>, z.ZodObject<{
41
+ kind: z.ZodLiteral<"granular">;
42
+ config: z.ZodObject<{
43
+ sandboxApproval: z.ZodBoolean;
44
+ rules: z.ZodBoolean;
45
+ skillApproval: z.ZodDefault<z.ZodBoolean>;
46
+ requestPermissions: z.ZodDefault<z.ZodBoolean>;
47
+ mcpElicitations: z.ZodBoolean;
48
+ }, z.core.$strip>;
49
+ }, z.core.$strip>, z.ZodObject<{
50
+ kind: z.ZodLiteral<"never">;
51
+ }, z.core.$strip>], "kind">;
52
+ type ApprovalPolicy = z.infer<typeof approvalPolicySchema>;
53
+ declare const DEFAULT_APPROVAL_POLICY: ApprovalPolicy;
54
+ /** A writable root with read-only sub-paths and escalation-protected names. */
55
+ declare const writableRootSchema: z.ZodObject<{
56
+ root: z.ZodString;
57
+ readOnlySubpaths: z.ZodDefault<z.ZodArray<z.ZodString>>;
58
+ protectedMetadataNames: z.ZodDefault<z.ZodArray<z.ZodString>>;
59
+ }, z.core.$strip>;
60
+ type WritableRoot = z.infer<typeof writableRootSchema>;
61
+ /**
62
+ * Capability policy — a vocabulary of *capabilities*, not OS mechanisms.
63
+ * Per the dual-track governance decision, `external_sandbox` is the default
64
+ * posture: this runtime never enforces isolation itself.
65
+ */
66
+ declare const capabilityPolicySchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
67
+ kind: z.ZodLiteral<"danger_full_access">;
68
+ }, z.core.$strip>, z.ZodObject<{
69
+ kind: z.ZodLiteral<"read_only">;
70
+ networkAccess: z.ZodDefault<z.ZodBoolean>;
71
+ }, z.core.$strip>, z.ZodObject<{
72
+ kind: z.ZodLiteral<"external_sandbox">;
73
+ networkAccess: z.ZodDefault<z.ZodBoolean>;
74
+ }, z.core.$strip>, z.ZodObject<{
75
+ kind: z.ZodLiteral<"workspace_write">;
76
+ writableRoots: z.ZodDefault<z.ZodArray<z.ZodObject<{
77
+ root: z.ZodString;
78
+ readOnlySubpaths: z.ZodDefault<z.ZodArray<z.ZodString>>;
79
+ protectedMetadataNames: z.ZodDefault<z.ZodArray<z.ZodString>>;
80
+ }, z.core.$strip>>>;
81
+ networkAccess: z.ZodDefault<z.ZodBoolean>;
82
+ excludeTmpdir: z.ZodDefault<z.ZodBoolean>;
83
+ excludeSlashTmp: z.ZodDefault<z.ZodBoolean>;
84
+ }, z.core.$strip>], "kind">;
85
+ type CapabilityPolicy = z.infer<typeof capabilityPolicySchema>;
86
+ /** Default posture for a multi-tenant web runtime (governance: ExternalSandbox). */
87
+ declare const DEFAULT_CAPABILITY_POLICY: CapabilityPolicy;
88
+ /** Classification of a command *before* approval. */
89
+ type RuleDecision = "allow" | "prompt" | "forbidden";
90
+ /** A session-scoped amendment that remembers an allowed command prefix. */
91
+ interface RuleAmendment {
92
+ readonly allowPrefix: readonly string[];
93
+ }
94
+ /** Persist allow/deny for future requests to the same host. */
95
+ interface NetworkPolicyAmendment {
96
+ readonly host: string;
97
+ readonly effect: "allow" | "deny";
98
+ }
99
+ /**
100
+ * The reviewer's rich answer. Mirrors upstream `ReviewDecision`; `denied`
101
+ * is the safe default.
102
+ */
103
+ type ReviewDecision = {
104
+ readonly kind: "approved";
105
+ } | {
106
+ readonly kind: "approved_rule_amendment";
107
+ readonly amendment: RuleAmendment;
108
+ } | {
109
+ readonly kind: "approved_for_session";
110
+ } | {
111
+ readonly kind: "network_policy_amendment";
112
+ readonly amendment: NetworkPolicyAmendment;
113
+ } | {
114
+ readonly kind: "denied";
115
+ } | {
116
+ readonly kind: "timed_out";
117
+ } | {
118
+ readonly kind: "abort";
119
+ };
120
+ declare const DENIED: ReviewDecision;
121
+ /** Whether a decision permits the action to proceed. */
122
+ declare function isApproval(decision: ReviewDecision): boolean;
123
+ /**
124
+ * Resolve a static rule decision against an approval policy into whether the
125
+ * action proceeds without a human, must be asked, or is auto-rejected.
126
+ * Pure; the actual prompting/escalation transport lives in ./protocol.
127
+ */
128
+ declare function resolveRuleDecision(rule: RuleDecision, policy: ApprovalPolicy): "auto_allow" | "ask_human" | "auto_reject";
129
+
130
+ export { type ApprovalPolicy, type CapabilityPolicy, DEFAULT_APPROVAL_POLICY, DEFAULT_CAPABILITY_POLICY, DENIED, type GranularApprovalConfig, type NetworkPolicyAmendment, type ReviewDecision, type RuleAmendment, type RuleDecision, type WritableRoot, approvalPolicySchema, capabilityPolicySchema, granularApprovalConfigSchema, isApproval, resolveRuleDecision, writableRootSchema };
package/dist/policy.js ADDED
@@ -0,0 +1,23 @@
1
+ import {
2
+ DEFAULT_APPROVAL_POLICY,
3
+ DEFAULT_CAPABILITY_POLICY,
4
+ DENIED,
5
+ approvalPolicySchema,
6
+ capabilityPolicySchema,
7
+ granularApprovalConfigSchema,
8
+ isApproval,
9
+ resolveRuleDecision,
10
+ writableRootSchema
11
+ } from "./chunk-CGRCUKGT.js";
12
+ export {
13
+ DEFAULT_APPROVAL_POLICY,
14
+ DEFAULT_CAPABILITY_POLICY,
15
+ DENIED,
16
+ approvalPolicySchema,
17
+ capabilityPolicySchema,
18
+ granularApprovalConfigSchema,
19
+ isApproval,
20
+ resolveRuleDecision,
21
+ writableRootSchema
22
+ };
23
+ //# sourceMappingURL=policy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
@@ -0,0 +1,170 @@
1
+ import { z } from 'zod';
2
+
3
+ /**
4
+ * App-server protocol contract (WRAP — capability #5).
5
+ *
6
+ * Faithful re-expression of the upstream JSON-RPC method registry, the
7
+ * serialization-scope concurrency model, server-initiated approval requests,
8
+ * and the notification event stream.
9
+ *
10
+ * Multi-tenant adaptation (non-negotiable): every serialization scope is
11
+ * additionally keyed by `tenantId`. Upstream `Thread { thread_id }` becomes
12
+ * `{ tenantId, threadId }` — natural per-tenant ordering + isolation for free.
13
+ * This is the only coupling seam to an optional decoupled kernel sidecar
14
+ * (Track B); transport (WS/SSE/stdio) is pluggable and not defined here.
15
+ */
16
+
17
+ /**
18
+ * Requests sharing a scope are serialized; distinct scopes run in parallel.
19
+ * `tenantId` is mandatory on every scope — cross-tenant requests can never
20
+ * share a scope.
21
+ */
22
+ type SerializationScope = {
23
+ readonly tenantId: string;
24
+ readonly kind: "none";
25
+ } | {
26
+ readonly tenantId: string;
27
+ readonly kind: "global";
28
+ readonly key: string;
29
+ } | {
30
+ readonly tenantId: string;
31
+ readonly kind: "global_shared_read";
32
+ readonly key: string;
33
+ } | {
34
+ readonly tenantId: string;
35
+ readonly kind: "thread";
36
+ readonly threadId: string;
37
+ } | {
38
+ readonly tenantId: string;
39
+ readonly kind: "command_exec";
40
+ readonly processId: string;
41
+ } | {
42
+ readonly tenantId: string;
43
+ readonly kind: "mcp_oauth";
44
+ readonly server: string;
45
+ };
46
+ /** Stable string key used to coalesce requests into the same serial lane. */
47
+ declare function scopeKey(scope: SerializationScope): string;
48
+ /** How a method's scope is derived from its params. */
49
+ type ScopeRule = {
50
+ readonly kind: "none";
51
+ } | {
52
+ readonly kind: "global";
53
+ readonly key: string;
54
+ } | {
55
+ readonly kind: "thread";
56
+ };
57
+ interface MethodSpec {
58
+ /** Namespaced `domain/verb` wire name. */
59
+ readonly method: string;
60
+ readonly scope: ScopeRule;
61
+ readonly experimental?: boolean;
62
+ }
63
+ /**
64
+ * The faithful subset of the upstream registry relevant to a multi-tenant web
65
+ * product. `thread`-scoped methods derive `{ tenantId, threadId }`.
66
+ */
67
+ declare const METHOD_REGISTRY: {
68
+ readonly initialize: {
69
+ readonly method: "initialize";
70
+ readonly scope: {
71
+ readonly kind: "none";
72
+ };
73
+ };
74
+ readonly threadStart: {
75
+ readonly method: "thread/start";
76
+ readonly scope: {
77
+ readonly kind: "none";
78
+ };
79
+ };
80
+ readonly threadResume: {
81
+ readonly method: "thread/resume";
82
+ readonly scope: {
83
+ readonly kind: "thread";
84
+ };
85
+ };
86
+ readonly threadFork: {
87
+ readonly method: "thread/fork";
88
+ readonly scope: {
89
+ readonly kind: "thread";
90
+ };
91
+ };
92
+ readonly threadArchive: {
93
+ readonly method: "thread/archive";
94
+ readonly scope: {
95
+ readonly kind: "thread";
96
+ };
97
+ };
98
+ readonly threadCompactStart: {
99
+ readonly method: "thread/compact/start";
100
+ readonly scope: {
101
+ readonly kind: "thread";
102
+ };
103
+ };
104
+ readonly threadRollback: {
105
+ readonly method: "thread/rollback";
106
+ readonly scope: {
107
+ readonly kind: "thread";
108
+ };
109
+ };
110
+ readonly turnStart: {
111
+ readonly method: "turn/start";
112
+ readonly scope: {
113
+ readonly kind: "thread";
114
+ };
115
+ };
116
+ readonly turnSteer: {
117
+ readonly method: "turn/steer";
118
+ readonly scope: {
119
+ readonly kind: "thread";
120
+ };
121
+ };
122
+ readonly turnInterrupt: {
123
+ readonly method: "turn/interrupt";
124
+ readonly scope: {
125
+ readonly kind: "thread";
126
+ };
127
+ };
128
+ readonly modelList: {
129
+ readonly method: "model/list";
130
+ readonly scope: {
131
+ readonly kind: "none";
132
+ };
133
+ };
134
+ };
135
+ type MethodName = (typeof METHOD_REGISTRY)[keyof typeof METHOD_REGISTRY]["method"];
136
+ /** Resolve a method's runtime scope from tenant + params. */
137
+ declare function resolveScope(spec: MethodSpec, tenantId: string, params: {
138
+ threadId?: string;
139
+ }): SerializationScope;
140
+ /** Approvals are server-initiated RPC, not side channels. */
141
+ type ServerRequest = {
142
+ readonly type: "command_execution.request_approval";
143
+ readonly requestId: string;
144
+ readonly command: string;
145
+ } | {
146
+ readonly type: "file_change.request_approval";
147
+ readonly requestId: string;
148
+ readonly paths: readonly string[];
149
+ } | {
150
+ readonly type: "permissions.request_approval";
151
+ readonly requestId: string;
152
+ readonly summary: string;
153
+ } | {
154
+ readonly type: "mcp.elicitation";
155
+ readonly requestId: string;
156
+ readonly server: string;
157
+ readonly schema: unknown;
158
+ };
159
+ declare const NOTIFICATIONS: readonly ["thread/started", "turn/started", "turn/completed", "turn/failed", "item/started", "item/updated", "item/completed", "model/rerouted", "thread/compacted"];
160
+ type NotificationName = (typeof NOTIFICATIONS)[number];
161
+ declare const requestEnvelopeSchema: z.ZodObject<{
162
+ jsonrpc: z.ZodLiteral<"2.0">;
163
+ id: z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>;
164
+ method: z.ZodString;
165
+ tenantId: z.ZodString;
166
+ params: z.ZodOptional<z.ZodUnknown>;
167
+ }, z.core.$strip>;
168
+ type RequestEnvelope = z.infer<typeof requestEnvelopeSchema>;
169
+
170
+ export { METHOD_REGISTRY, type MethodName, type MethodSpec, NOTIFICATIONS, type NotificationName, type RequestEnvelope, type ScopeRule, type SerializationScope, type ServerRequest, requestEnvelopeSchema, resolveScope, scopeKey };
@@ -0,0 +1,15 @@
1
+ import {
2
+ METHOD_REGISTRY,
3
+ NOTIFICATIONS,
4
+ requestEnvelopeSchema,
5
+ resolveScope,
6
+ scopeKey
7
+ } from "./chunk-FUG5DT2C.js";
8
+ export {
9
+ METHOD_REGISTRY,
10
+ NOTIFICATIONS,
11
+ requestEnvelopeSchema,
12
+ resolveScope,
13
+ scopeKey
14
+ };
15
+ //# sourceMappingURL=protocol.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}