@corenel/harness 0.2.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (163) hide show
  1. package/dist/acp/agentMap.d.ts +34 -0
  2. package/dist/acp/agentMap.d.ts.map +1 -0
  3. package/dist/acp/agentMap.js +110 -0
  4. package/dist/acp/agentMap.js.map +1 -0
  5. package/dist/acp/index.d.ts +4 -0
  6. package/dist/acp/index.d.ts.map +1 -0
  7. package/dist/acp/index.js +6 -0
  8. package/dist/acp/index.js.map +1 -0
  9. package/dist/acp/policyMap.d.ts +55 -0
  10. package/dist/acp/policyMap.d.ts.map +1 -0
  11. package/dist/acp/policyMap.js +121 -0
  12. package/dist/acp/policyMap.js.map +1 -0
  13. package/dist/acp/types.d.ts +41 -0
  14. package/dist/acp/types.d.ts.map +1 -0
  15. package/dist/acp/types.js +14 -0
  16. package/dist/acp/types.js.map +1 -0
  17. package/dist/api/backend.d.ts +39 -0
  18. package/dist/api/backend.d.ts.map +1 -0
  19. package/dist/api/backend.js +126 -0
  20. package/dist/api/backend.js.map +1 -0
  21. package/dist/api/client.d.ts +95 -0
  22. package/dist/api/client.d.ts.map +1 -0
  23. package/dist/api/client.js +212 -0
  24. package/dist/api/client.js.map +1 -0
  25. package/dist/api/fileMirrorSource.d.ts +24 -0
  26. package/dist/api/fileMirrorSource.d.ts.map +1 -0
  27. package/dist/api/fileMirrorSource.js +59 -0
  28. package/dist/api/fileMirrorSource.js.map +1 -0
  29. package/dist/api/mirror.d.ts +102 -0
  30. package/dist/api/mirror.d.ts.map +1 -0
  31. package/dist/api/mirror.js +204 -0
  32. package/dist/api/mirror.js.map +1 -0
  33. package/dist/api/mirrorScheduler.d.ts +56 -0
  34. package/dist/api/mirrorScheduler.d.ts.map +1 -0
  35. package/dist/api/mirrorScheduler.js +167 -0
  36. package/dist/api/mirrorScheduler.js.map +1 -0
  37. package/dist/compression.d.ts +15 -1
  38. package/dist/compression.d.ts.map +1 -1
  39. package/dist/compression.js +32 -1
  40. package/dist/compression.js.map +1 -1
  41. package/dist/core/loop.d.ts +12 -0
  42. package/dist/core/loop.d.ts.map +1 -1
  43. package/dist/core/loop.js +138 -14
  44. package/dist/core/loop.js.map +1 -1
  45. package/dist/core/spawn.d.ts +54 -0
  46. package/dist/core/spawn.d.ts.map +1 -0
  47. package/dist/core/spawn.js +58 -0
  48. package/dist/core/spawn.js.map +1 -0
  49. package/dist/dag/executeNode.js +2 -2
  50. package/dist/fileSchema.js +1 -1
  51. package/dist/guardrail/guardrail.js +1 -1
  52. package/dist/guardrail/index.js +7 -7
  53. package/dist/guardrail/permission-service.js +1 -1
  54. package/dist/guardrail/serialize.js +1 -1
  55. package/dist/guardrail/store.js +2 -2
  56. package/dist/install/lockfile.d.ts +79 -0
  57. package/dist/install/lockfile.d.ts.map +1 -0
  58. package/dist/install/lockfile.js +155 -0
  59. package/dist/install/lockfile.js.map +1 -0
  60. package/dist/install/store.d.ts +13 -0
  61. package/dist/install/store.d.ts.map +1 -0
  62. package/dist/install/store.js +38 -0
  63. package/dist/install/store.js.map +1 -0
  64. package/dist/log.d.ts.map +1 -1
  65. package/dist/log.js +6 -1
  66. package/dist/log.js.map +1 -1
  67. package/dist/prompts/config.js +2 -2
  68. package/dist/prompts/host.d.ts +4 -0
  69. package/dist/prompts/host.d.ts.map +1 -1
  70. package/dist/prompts/host.js.map +1 -1
  71. package/dist/prompts/index.d.ts.map +1 -1
  72. package/dist/prompts/index.js +13 -6
  73. package/dist/prompts/index.js.map +1 -1
  74. package/dist/prompts/library/defaults.generated.js +2 -2
  75. package/dist/prompts/library/defaults.generated.js.map +1 -1
  76. package/dist/prompts/library/index.js +1 -1
  77. package/dist/providers/contextWindow.d.ts +19 -0
  78. package/dist/providers/contextWindow.d.ts.map +1 -0
  79. package/dist/providers/contextWindow.js +68 -0
  80. package/dist/providers/contextWindow.js.map +1 -0
  81. package/dist/providers/gateway.d.ts +3 -0
  82. package/dist/providers/gateway.d.ts.map +1 -1
  83. package/dist/providers/gateway.js +4 -1
  84. package/dist/providers/gateway.js.map +1 -1
  85. package/dist/sessions/apiLeaseStore.d.ts +10 -0
  86. package/dist/sessions/apiLeaseStore.d.ts.map +1 -0
  87. package/dist/sessions/apiLeaseStore.js +41 -0
  88. package/dist/sessions/apiLeaseStore.js.map +1 -0
  89. package/dist/sessions/blobGc.d.ts +62 -0
  90. package/dist/sessions/blobGc.d.ts.map +1 -0
  91. package/dist/sessions/blobGc.js +154 -0
  92. package/dist/sessions/blobGc.js.map +1 -0
  93. package/dist/sessions/fileRecallStore.js +1 -1
  94. package/dist/sessions/fileSessionStore.js +1 -1
  95. package/dist/sessions/head.d.ts +90 -0
  96. package/dist/sessions/head.d.ts.map +1 -0
  97. package/dist/sessions/head.js +82 -0
  98. package/dist/sessions/head.js.map +1 -0
  99. package/dist/sessions/inflight.d.ts +58 -0
  100. package/dist/sessions/inflight.d.ts.map +1 -0
  101. package/dist/sessions/inflight.js +0 -0
  102. package/dist/sessions/inflight.js.map +1 -0
  103. package/dist/sessions/lease.d.ts +59 -0
  104. package/dist/sessions/lease.d.ts.map +1 -0
  105. package/dist/sessions/lease.js +115 -0
  106. package/dist/sessions/lease.js.map +1 -0
  107. package/dist/sessions/leaseStore.d.ts +46 -0
  108. package/dist/sessions/leaseStore.d.ts.map +1 -0
  109. package/dist/sessions/leaseStore.js +58 -0
  110. package/dist/sessions/leaseStore.js.map +1 -0
  111. package/dist/sessions/timeline.d.ts +134 -0
  112. package/dist/sessions/timeline.d.ts.map +1 -0
  113. package/dist/sessions/timeline.js +127 -0
  114. package/dist/sessions/timeline.js.map +1 -0
  115. package/dist/sidecar/host.d.ts +241 -5
  116. package/dist/sidecar/host.d.ts.map +1 -1
  117. package/dist/sidecar/host.js +630 -5
  118. package/dist/sidecar/host.js.map +1 -1
  119. package/dist/sidecar/server.d.ts +124 -2
  120. package/dist/sidecar/server.d.ts.map +1 -1
  121. package/dist/sidecar/server.js +620 -9
  122. package/dist/sidecar/server.js.map +1 -1
  123. package/dist/sidecar/wsChannel.d.ts +4 -0
  124. package/dist/sidecar/wsChannel.d.ts.map +1 -0
  125. package/dist/sidecar/wsChannel.js +62 -0
  126. package/dist/sidecar/wsChannel.js.map +1 -0
  127. package/dist/skills.js +2 -2
  128. package/dist/snapshot/effects.d.ts +69 -0
  129. package/dist/snapshot/effects.d.ts.map +1 -0
  130. package/dist/snapshot/effects.js +67 -0
  131. package/dist/snapshot/effects.js.map +1 -0
  132. package/dist/snapshot/manifest.d.ts +73 -0
  133. package/dist/snapshot/manifest.d.ts.map +1 -0
  134. package/dist/snapshot/manifest.js +141 -0
  135. package/dist/snapshot/manifest.js.map +1 -0
  136. package/dist/snapshot/tree.d.ts +62 -0
  137. package/dist/snapshot/tree.d.ts.map +1 -0
  138. package/dist/snapshot/tree.js +147 -0
  139. package/dist/snapshot/tree.js.map +1 -0
  140. package/dist/tools/builtins.d.ts.map +1 -1
  141. package/dist/tools/builtins.js +67 -8
  142. package/dist/tools/builtins.js.map +1 -1
  143. package/dist/tools/callAgent.d.ts +16 -0
  144. package/dist/tools/callAgent.d.ts.map +1 -0
  145. package/dist/tools/callAgent.js +53 -0
  146. package/dist/tools/callAgent.js.map +1 -0
  147. package/dist/tools/files.d.ts +10 -0
  148. package/dist/tools/files.d.ts.map +1 -1
  149. package/dist/tools/files.js +159 -8
  150. package/dist/tools/files.js.map +1 -1
  151. package/dist/tools/http.js +1 -1
  152. package/dist/tools/namespaces.d.ts +1 -1
  153. package/dist/tools/namespaces.d.ts.map +1 -1
  154. package/dist/tools/namespaces.js +40 -2
  155. package/dist/tools/namespaces.js.map +1 -1
  156. package/dist/tools/procs.d.ts +18 -0
  157. package/dist/tools/procs.d.ts.map +1 -0
  158. package/dist/tools/procs.js +281 -0
  159. package/dist/tools/procs.js.map +1 -0
  160. package/dist/tools/todo.d.ts.map +1 -1
  161. package/dist/tools/todo.js +12 -0
  162. package/dist/tools/todo.js.map +1 -1
  163. package/package.json +18 -7
@@ -0,0 +1,34 @@
1
+ import type { AgentEvent } from '@corenel/protocol';
2
+ import type { AcpToolKind } from './types';
3
+ /**
4
+ * Describe one of our tools in ACP's `kind` vocabulary.
5
+ *
6
+ * Accepts either a bare wire name (`write_file`) or a policy address
7
+ * (`fs:write_file`), because callers have one or the other depending on where in
8
+ * the loop they sit.
9
+ *
10
+ * The `fs` namespace fallback is `read` rather than `edit` on purpose: a tool we
11
+ * cannot name is more likely a reader, and this value drives only the client's
12
+ * icon and progress display. The AUTHORIZATION for that same call is decided by
13
+ * our own Policy before we ever emit this.
14
+ */
15
+ export declare function kindForTool(nameOrAddress: string): AcpToolKind;
16
+ /** An ACP `session/update` payload, as the agent sends it. */
17
+ export interface AcpSessionUpdate {
18
+ sessionUpdate: string;
19
+ [k: string]: unknown;
20
+ }
21
+ /**
22
+ * Render one agent-loop event as an ACP `session/update`, or null when the event
23
+ * has no ACP equivalent worth sending.
24
+ *
25
+ * Returning null rather than a placeholder matters: our loop emits far more than
26
+ * ACP models (budget breaches, heals, policy notes, usage), and forwarding those
27
+ * as text would clutter a client's transcript with our internals. A client that
28
+ * wants them can read the run's RUN.jsonl.
29
+ */
30
+ export declare function eventToSessionUpdate(ev: AgentEvent): AcpSessionUpdate | null;
31
+ /** Map our loop's stop reason onto ACP's. Unknown reasons report `end_turn`
32
+ * rather than inventing a value the client would not recognize. */
33
+ export declare function stopReasonForAcp(reason: string): string;
34
+ //# sourceMappingURL=agentMap.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agentMap.d.ts","sourceRoot":"","sources":["../../acp/agentMap.ts"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAmC3C;;;;;;;;;;;GAWG;AACH,wBAAgB,WAAW,CAAC,aAAa,EAAE,MAAM,GAAG,WAAW,CAQ9D;AAED,8DAA8D;AAC9D,MAAM,WAAW,gBAAgB;IAC/B,aAAa,EAAE,MAAM,CAAC;IACtB,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;CACtB;AAED;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,CAAC,EAAE,EAAE,UAAU,GAAG,gBAAgB,GAAG,IAAI,CA6B5E;AAED;mEACmE;AACnE,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAavD"}
@@ -0,0 +1,110 @@
1
+ /** Explicit kinds for built-in tools whose namespace alone is ambiguous. */
2
+ const TOOL_KINDS = {
3
+ read_file: 'read',
4
+ stat_file: 'read',
5
+ list_files: 'read',
6
+ search_files: 'search',
7
+ search_sessions: 'search',
8
+ search_packages: 'search',
9
+ write_file: 'edit',
10
+ create_file: 'edit',
11
+ propose_edit: 'edit',
12
+ delete_file: 'delete',
13
+ rename_file: 'move',
14
+ web_search: 'fetch',
15
+ compile_prompd: 'other',
16
+ todo_write: 'think',
17
+ ask_user: 'think',
18
+ };
19
+ /** Namespace fallbacks, for tools not named above (including dynamic MCP and
20
+ * skill tools, which cannot be enumerated). */
21
+ const NAMESPACE_KINDS = {
22
+ fs: 'read',
23
+ shell: 'execute',
24
+ web: 'fetch',
25
+ memory: 'other',
26
+ agent: 'think',
27
+ prompd: 'other',
28
+ system: 'other',
29
+ mcp: 'other',
30
+ skill: 'other',
31
+ };
32
+ /**
33
+ * Describe one of our tools in ACP's `kind` vocabulary.
34
+ *
35
+ * Accepts either a bare wire name (`write_file`) or a policy address
36
+ * (`fs:write_file`), because callers have one or the other depending on where in
37
+ * the loop they sit.
38
+ *
39
+ * The `fs` namespace fallback is `read` rather than `edit` on purpose: a tool we
40
+ * cannot name is more likely a reader, and this value drives only the client's
41
+ * icon and progress display. The AUTHORIZATION for that same call is decided by
42
+ * our own Policy before we ever emit this.
43
+ */
44
+ export function kindForTool(nameOrAddress) {
45
+ const colon = nameOrAddress.indexOf(':');
46
+ const ns = colon > 0 ? nameOrAddress.slice(0, colon) : '';
47
+ const name = colon > 0 ? nameOrAddress.slice(colon + 1) : nameOrAddress;
48
+ const byName = TOOL_KINDS[name];
49
+ if (byName)
50
+ return byName;
51
+ if (ns)
52
+ return NAMESPACE_KINDS[ns] ?? 'other';
53
+ return 'other';
54
+ }
55
+ /**
56
+ * Render one agent-loop event as an ACP `session/update`, or null when the event
57
+ * has no ACP equivalent worth sending.
58
+ *
59
+ * Returning null rather than a placeholder matters: our loop emits far more than
60
+ * ACP models (budget breaches, heals, policy notes, usage), and forwarding those
61
+ * as text would clutter a client's transcript with our internals. A client that
62
+ * wants them can read the run's RUN.jsonl.
63
+ */
64
+ export function eventToSessionUpdate(ev) {
65
+ switch (ev.type) {
66
+ case 'assistant-delta':
67
+ return { sessionUpdate: 'agent_message_chunk', content: { type: 'text', text: ev.delta } };
68
+ case 'tool-call':
69
+ return {
70
+ sessionUpdate: 'tool_call',
71
+ toolCallId: ev.id,
72
+ title: ev.name,
73
+ kind: kindForTool(ev.name),
74
+ status: 'in_progress',
75
+ rawInput: ev.args,
76
+ };
77
+ case 'tool-result':
78
+ return {
79
+ sessionUpdate: 'tool_call_update',
80
+ toolCallId: ev.id,
81
+ status: ev.isError ? 'failed' : 'completed',
82
+ rawOutput: ev.result,
83
+ };
84
+ case 'error':
85
+ return { sessionUpdate: 'agent_message_chunk', content: { type: 'text', text: `Error: ${ev.message}` } };
86
+ default:
87
+ // 'assistant' duplicates the deltas already streamed; 'turn', 'usage',
88
+ // 'heal', 'offload', 'permission*', 'policy-violation', 'budget-*',
89
+ // 'artifact' and 'done' have no ACP shape. 'done' is reported as the
90
+ // prompt's stopReason instead, which is where ACP expects it.
91
+ return null;
92
+ }
93
+ }
94
+ /** Map our loop's stop reason onto ACP's. Unknown reasons report `end_turn`
95
+ * rather than inventing a value the client would not recognize. */
96
+ export function stopReasonForAcp(reason) {
97
+ switch (reason) {
98
+ case 'cancelled':
99
+ case 'aborted':
100
+ return 'cancelled';
101
+ case 'max-turns':
102
+ case 'max_turns':
103
+ return 'max_turn_requests';
104
+ case 'refusal':
105
+ return 'refusal';
106
+ default:
107
+ return 'end_turn';
108
+ }
109
+ }
110
+ //# sourceMappingURL=agentMap.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agentMap.js","sourceRoot":"","sources":["../../acp/agentMap.ts"],"names":[],"mappings":"AAmBA,4EAA4E;AAC5E,MAAM,UAAU,GAAgC;IAC9C,SAAS,EAAE,MAAM;IACjB,SAAS,EAAE,MAAM;IACjB,UAAU,EAAE,MAAM;IAClB,YAAY,EAAE,QAAQ;IACtB,eAAe,EAAE,QAAQ;IACzB,eAAe,EAAE,QAAQ;IACzB,UAAU,EAAE,MAAM;IAClB,WAAW,EAAE,MAAM;IACnB,YAAY,EAAE,MAAM;IACpB,WAAW,EAAE,QAAQ;IACrB,WAAW,EAAE,MAAM;IACnB,UAAU,EAAE,OAAO;IACnB,cAAc,EAAE,OAAO;IACvB,UAAU,EAAE,OAAO;IACnB,QAAQ,EAAE,OAAO;CAClB,CAAC;AAEF;+CAC+C;AAC/C,MAAM,eAAe,GAAgC;IACnD,EAAE,EAAE,MAAM;IACV,KAAK,EAAE,SAAS;IAChB,GAAG,EAAE,OAAO;IACZ,MAAM,EAAE,OAAO;IACf,KAAK,EAAE,OAAO;IACd,MAAM,EAAE,OAAO;IACf,MAAM,EAAE,OAAO;IACf,GAAG,EAAE,OAAO;IACZ,KAAK,EAAE,OAAO;CACf,CAAC;AAEF;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,WAAW,CAAC,aAAqB;IAC/C,MAAM,KAAK,GAAG,aAAa,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IACzC,MAAM,EAAE,GAAG,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IAC1D,MAAM,IAAI,GAAG,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,KAAK,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC;IACxE,MAAM,MAAM,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC;IAChC,IAAI,MAAM;QAAE,OAAO,MAAM,CAAC;IAC1B,IAAI,EAAE;QAAE,OAAO,eAAe,CAAC,EAAE,CAAC,IAAI,OAAO,CAAC;IAC9C,OAAO,OAAO,CAAC;AACjB,CAAC;AAQD;;;;;;;;GAQG;AACH,MAAM,UAAU,oBAAoB,CAAC,EAAc;IACjD,QAAQ,EAAE,CAAC,IAAI,EAAE,CAAC;QAChB,KAAK,iBAAiB;YACpB,OAAO,EAAE,aAAa,EAAE,qBAAqB,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC;QAC7F,KAAK,WAAW;YACd,OAAO;gBACL,aAAa,EAAE,WAAW;gBAC1B,UAAU,EAAE,EAAE,CAAC,EAAE;gBACjB,KAAK,EAAE,EAAE,CAAC,IAAI;gBACd,IAAI,EAAE,WAAW,CAAC,EAAE,CAAC,IAAI,CAAC;gBAC1B,MAAM,EAAE,aAAa;gBACrB,QAAQ,EAAE,EAAE,CAAC,IAAI;aAClB,CAAC;QACJ,KAAK,aAAa;YAChB,OAAO;gBACL,aAAa,EAAE,kBAAkB;gBACjC,UAAU,EAAE,EAAE,CAAC,EAAE;gBACjB,MAAM,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,WAAW;gBAC3C,SAAS,EAAE,EAAE,CAAC,MAAM;aACrB,CAAC;QACJ,KAAK,OAAO;YACV,OAAO,EAAE,aAAa,EAAE,qBAAqB,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC,OAAO,EAAE,EAAE,EAAE,CAAC;QAC3G;YACE,uEAAuE;YACvE,oEAAoE;YACpE,qEAAqE;YACrE,8DAA8D;YAC9D,OAAO,IAAI,CAAC;IAChB,CAAC;AACH,CAAC;AAED;mEACmE;AACnE,MAAM,UAAU,gBAAgB,CAAC,MAAc;IAC7C,QAAQ,MAAM,EAAE,CAAC;QACf,KAAK,WAAW,CAAC;QACjB,KAAK,SAAS;YACZ,OAAO,WAAW,CAAC;QACrB,KAAK,WAAW,CAAC;QACjB,KAAK,WAAW;YACd,OAAO,mBAAmB,CAAC;QAC7B,KAAK,SAAS;YACZ,OAAO,SAAS,CAAC;QACnB;YACE,OAAO,UAAU,CAAC;IACtB,CAAC;AACH,CAAC"}
@@ -0,0 +1,4 @@
1
+ export { acpToSubject, acpDisplayTitle, levelToOptionId, ACP_KIND_ADDRESSES, ALLOW_KINDS, REJECT_KINDS, type AcpPermissionAnswer, } from './policyMap';
2
+ export { kindForTool, eventToSessionUpdate, stopReasonForAcp, type AcpSessionUpdate, } from './agentMap';
3
+ export type { AcpToolKind, AcpToolCallLocation, AcpToolCallUpdate, AcpPermissionOption, AcpPermissionOptionKind, AcpRequestPermissionRequest, } from './types';
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../acp/index.ts"],"names":[],"mappings":"AAGA,OAAO,EACL,YAAY,EACZ,eAAe,EACf,eAAe,EACf,kBAAkB,EAClB,WAAW,EACX,YAAY,EACZ,KAAK,mBAAmB,GACzB,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,WAAW,EACX,oBAAoB,EACpB,gBAAgB,EAChB,KAAK,gBAAgB,GACtB,MAAM,YAAY,CAAC;AACpB,YAAY,EACV,WAAW,EACX,mBAAmB,EACnB,iBAAiB,EACjB,mBAAmB,EACnB,uBAAuB,EACvB,2BAA2B,GAC5B,MAAM,SAAS,CAAC"}
@@ -0,0 +1,6 @@
1
+ /* ACP module barrel — the client-side translation between the Agent Client
2
+ * Protocol and this harness's governance layer. Pure: no transport, no node.
3
+ * The wire lives in packages/sidecar/src/acp/. */
4
+ export { acpToSubject, acpDisplayTitle, levelToOptionId, ACP_KIND_ADDRESSES, ALLOW_KINDS, REJECT_KINDS, } from './policyMap.js';
5
+ export { kindForTool, eventToSessionUpdate, stopReasonForAcp, } from './agentMap.js';
6
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../acp/index.ts"],"names":[],"mappings":"AAAA;;kDAEkD;AAClD,OAAO,EACL,YAAY,EACZ,eAAe,EACf,eAAe,EACf,kBAAkB,EAClB,WAAW,EACX,YAAY,GAEb,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,WAAW,EACX,oBAAoB,EACpB,gBAAgB,GAEjB,MAAM,YAAY,CAAC"}
@@ -0,0 +1,55 @@
1
+ import type { PermissionSubject } from '../guardrail/permission-service';
2
+ import type { PermissionDecision } from '@corenel/protocol';
3
+ import type { AcpPermissionOption, AcpPermissionOptionKind, AcpToolCallUpdate } from './types';
4
+ /**
5
+ * Translate an ACP tool call into the subject our PermissionService resolves.
6
+ *
7
+ * THE INVARIANT: an unknown, absent, or unrecognized `kind` is MUTATING.
8
+ * ACP marks `kind` optional with a default of 'other', so an agent that does not
9
+ * label its calls reports nothing at all. Were that mapped to non-mutating,
10
+ * STANDARD_POLICY — which sets no defaultPermission and falls through to the
11
+ * read/write heuristic — would resolve it via `defaultForReadOnly` ('allow') and
12
+ * silently auto-approve a destructive call. Absence must never read as
13
+ * permissive.
14
+ *
15
+ * `name` is deliberately the SAME string as `address`, not the human title:
16
+ * PermissionService matches policy globs against a subject's address AND its
17
+ * name (subjectMatches), and matches session pre-approvals against the name
18
+ * alone (decide -> sessionAllow). Letting agent-supplied text be the name would
19
+ * hand an external process a second, softer path into policy matching — a title
20
+ * of `fs:acp_read` could satisfy a rule or a pre-approval written for the real
21
+ * thing. One identity, derived entirely from data we control. The human-readable
22
+ * title is carried separately by acpDisplayTitle() for the approval prompt.
23
+ */
24
+ export declare function acpToSubject(call: AcpToolCallUpdate): PermissionSubject;
25
+ /** The human-facing label for an approval prompt. Raw agent text — safe to
26
+ * DISPLAY, never safe to match policy against (see acpToSubject). */
27
+ export declare function acpDisplayTitle(call: AcpToolCallUpdate): string;
28
+ /** Our answer, expressed in the agent's own option vocabulary. */
29
+ export type AcpPermissionAnswer = {
30
+ ok: true;
31
+ optionId: string;
32
+ } | {
33
+ ok: false;
34
+ reason: string;
35
+ };
36
+ declare const ALLOW_KINDS: AcpPermissionOptionKind[];
37
+ declare const REJECT_KINDS: AcpPermissionOptionKind[];
38
+ /**
39
+ * Turn a resolved decision into an `optionId` drawn from what the agent OFFERED.
40
+ * We never synthesize an id: the agent defines its own option set, and answering
41
+ * with an unknown id is a protocol error.
42
+ *
43
+ * FAILS CLOSED. If no acceptable option exists we return `ok: false` rather than
44
+ * throwing or falling back to something permissive — an agent that offers only
45
+ * allow-shaped options must not thereby win a denial. The caller reports the
46
+ * refusal and cancels the call.
47
+ */
48
+ export declare function levelToOptionId(decision: PermissionDecision, options: readonly AcpPermissionOption[], opts?: {
49
+ sessionApproved?: boolean;
50
+ }): AcpPermissionAnswer;
51
+ /** Exported for tests and for a capabilities UI that wants to show what a
52
+ * proxied agent can address. */
53
+ export declare const ACP_KIND_ADDRESSES: readonly string[];
54
+ export { ALLOW_KINDS, REJECT_KINDS };
55
+ //# sourceMappingURL=policyMap.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"policyMap.d.ts","sourceRoot":"","sources":["../../acp/policyMap.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,iCAAiC,CAAC;AACzE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAC5D,OAAO,KAAK,EACV,mBAAmB,EACnB,uBAAuB,EACvB,iBAAiB,EAElB,MAAM,SAAS,CAAC;AAiDjB;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,iBAAiB,GAAG,iBAAiB,CAQvE;AAED;qEACqE;AACrE,wBAAgB,eAAe,CAAC,IAAI,EAAE,iBAAiB,GAAG,MAAM,CAI/D;AAED,kEAAkE;AAClE,MAAM,MAAM,mBAAmB,GAC3B;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GAC9B;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAElC,QAAA,MAAM,WAAW,EAAE,uBAAuB,EAAmC,CAAC;AAC9E,QAAA,MAAM,YAAY,EAAE,uBAAuB,EAAqC,CAAC;AAajF;;;;;;;;;GASG;AACH,wBAAgB,eAAe,CAC7B,QAAQ,EAAE,kBAAkB,EAC5B,OAAO,EAAE,SAAS,mBAAmB,EAAE,EACvC,IAAI,GAAE;IAAE,eAAe,CAAC,EAAE,OAAO,CAAA;CAAO,GACvC,mBAAmB,CAarB;AAED;gCACgC;AAChC,eAAO,MAAM,kBAAkB,EAAE,SAAS,MAAM,EAEJ,CAAC;AAE7C,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,CAAC"}
@@ -0,0 +1,121 @@
1
+ /** How each ACP kind addresses into our policy namespaces, and whether it has
2
+ * side effects. Anything NOT in this table is mutating — see toSafety(). */
3
+ const KIND_MAP = {
4
+ read: { ns: 'fs', mutates: false },
5
+ search: { ns: 'fs', mutates: false },
6
+ think: { ns: 'agent', mutates: false },
7
+ edit: { ns: 'fs', mutates: true },
8
+ delete: { ns: 'fs', mutates: true },
9
+ move: { ns: 'fs', mutates: true },
10
+ execute: { ns: 'shell', mutates: true },
11
+ fetch: { ns: 'web', mutates: true },
12
+ other: { ns: 'other', mutates: true },
13
+ };
14
+ /** Upper bound on the slug derived from an agent-supplied title. Long enough to
15
+ * stay readable in a policy file, short enough that a hostile title cannot bloat
16
+ * an address. */
17
+ const SLUG_MAX = 48;
18
+ /**
19
+ * Reduce untrusted agent-supplied text to a policy-safe token.
20
+ *
21
+ * SECURITY. `title` is free text from an external process, and it reaches a
22
+ * policy ADDRESS. Without this, a title of `fs:read` would forge an address in a
23
+ * privileged namespace, and a title containing `*` would inject a glob wildcard
24
+ * into the very expression being matched. Everything outside [a-z0-9_] is
25
+ * collapsed, so neither `:` nor `*` can survive.
26
+ */
27
+ function slugify(raw) {
28
+ const slug = (raw ?? '')
29
+ .toLowerCase()
30
+ .replace(/[^a-z0-9]+/g, '_')
31
+ .replace(/^_+|_+$/g, '')
32
+ .slice(0, SLUG_MAX)
33
+ .replace(/_+$/g, '');
34
+ return slug || 'unknown';
35
+ }
36
+ /** Resolve a wire `kind` to its table entry. An absent, unrecognized, or
37
+ * newer-protocol kind lands on `other`, which is MUTATING. */
38
+ function toSafety(kind) {
39
+ if (kind && Object.prototype.hasOwnProperty.call(KIND_MAP, kind)) {
40
+ return KIND_MAP[kind];
41
+ }
42
+ return KIND_MAP.other;
43
+ }
44
+ /**
45
+ * Translate an ACP tool call into the subject our PermissionService resolves.
46
+ *
47
+ * THE INVARIANT: an unknown, absent, or unrecognized `kind` is MUTATING.
48
+ * ACP marks `kind` optional with a default of 'other', so an agent that does not
49
+ * label its calls reports nothing at all. Were that mapped to non-mutating,
50
+ * STANDARD_POLICY — which sets no defaultPermission and falls through to the
51
+ * read/write heuristic — would resolve it via `defaultForReadOnly` ('allow') and
52
+ * silently auto-approve a destructive call. Absence must never read as
53
+ * permissive.
54
+ *
55
+ * `name` is deliberately the SAME string as `address`, not the human title:
56
+ * PermissionService matches policy globs against a subject's address AND its
57
+ * name (subjectMatches), and matches session pre-approvals against the name
58
+ * alone (decide -> sessionAllow). Letting agent-supplied text be the name would
59
+ * hand an external process a second, softer path into policy matching — a title
60
+ * of `fs:acp_read` could satisfy a rule or a pre-approval written for the real
61
+ * thing. One identity, derived entirely from data we control. The human-readable
62
+ * title is carried separately by acpDisplayTitle() for the approval prompt.
63
+ */
64
+ export function acpToSubject(call) {
65
+ const { ns, mutates } = toSafety(call.kind);
66
+ // A recognized kind addresses by that kind (fs:acp_edit) so one policy rule
67
+ // covers every edit the agent makes. An unrecognized one has no such handle,
68
+ // so it falls back to the sanitized title to stay at least distinguishable.
69
+ const leaf = ns === 'other' ? slugify(call.title) : slugify(call.kind);
70
+ const address = `${ns}:acp_${leaf}`;
71
+ return { name: address, address, mutates };
72
+ }
73
+ /** The human-facing label for an approval prompt. Raw agent text — safe to
74
+ * DISPLAY, never safe to match policy against (see acpToSubject). */
75
+ export function acpDisplayTitle(call) {
76
+ const t = (call.title ?? '').trim();
77
+ if (t)
78
+ return t;
79
+ return call.kind ? `${call.kind} (untitled)` : 'untitled tool call';
80
+ }
81
+ const ALLOW_KINDS = ['allow_once', 'allow_always'];
82
+ const REJECT_KINDS = ['reject_once', 'reject_always'];
83
+ function pick(options, preferred) {
84
+ for (const kind of preferred) {
85
+ const hit = options.find((o) => o.kind === kind);
86
+ if (hit)
87
+ return hit;
88
+ }
89
+ return undefined;
90
+ }
91
+ /**
92
+ * Turn a resolved decision into an `optionId` drawn from what the agent OFFERED.
93
+ * We never synthesize an id: the agent defines its own option set, and answering
94
+ * with an unknown id is a protocol error.
95
+ *
96
+ * FAILS CLOSED. If no acceptable option exists we return `ok: false` rather than
97
+ * throwing or falling back to something permissive — an agent that offers only
98
+ * allow-shaped options must not thereby win a denial. The caller reports the
99
+ * refusal and cancels the call.
100
+ */
101
+ export function levelToOptionId(decision, options, opts = {}) {
102
+ if (decision === 'allow') {
103
+ // A session pre-approval is durable on our side, so prefer the durable
104
+ // option when the agent offers one — it stops the agent re-asking for
105
+ // something the user already blanket-approved.
106
+ const order = opts.sessionApproved
107
+ ? ['allow_always', 'allow_once']
108
+ : ['allow_once', 'allow_always'];
109
+ const hit = pick(options, order);
110
+ return hit ? { ok: true, optionId: hit.optionId } : { ok: false, reason: 'agent offered no allow option' };
111
+ }
112
+ const hit = pick(options, REJECT_KINDS);
113
+ return hit ? { ok: true, optionId: hit.optionId } : { ok: false, reason: 'agent offered no reject option' };
114
+ }
115
+ /** Exported for tests and for a capabilities UI that wants to show what a
116
+ * proxied agent can address. */
117
+ export const ACP_KIND_ADDRESSES = Object.entries(KIND_MAP)
118
+ .filter(([kind]) => kind !== 'other')
119
+ .map(([kind, v]) => `${v.ns}:acp_${kind}`);
120
+ export { ALLOW_KINDS, REJECT_KINDS };
121
+ //# sourceMappingURL=policyMap.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"policyMap.js","sourceRoot":"","sources":["../../acp/policyMap.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,41 @@
1
+ /** How the agent categorizes a tool call. A UI hint in ACP, and our only signal
2
+ * for whether the call has side effects. OPTIONAL on the wire, defaulting to
3
+ * 'other' — see the ACP_KINDS note in policyMap.ts. */
4
+ export type AcpToolKind = 'read' | 'edit' | 'delete' | 'move' | 'search' | 'execute' | 'think' | 'fetch' | 'other';
5
+ /** Where a tool call acts. Present only when the agent chooses to report it. */
6
+ export interface AcpToolCallLocation {
7
+ path: string;
8
+ line?: number;
9
+ }
10
+ /** The tool-call description carried by a permission request. ACP models this as
11
+ * a partial update, so everything except the id may be absent. */
12
+ export interface AcpToolCallUpdate {
13
+ toolCallId?: string;
14
+ /** Human-readable description of what the tool is doing. UNTRUSTED text from
15
+ * an external process — never interpolate it into an address without
16
+ * sanitizing (policyMap.ts slugifies it). */
17
+ title?: string;
18
+ kind?: AcpToolKind;
19
+ status?: 'pending' | 'in_progress' | 'completed' | 'failed';
20
+ locations?: AcpToolCallLocation[];
21
+ /** The original parameters the agent passed to its tool. Opaque to us; passed
22
+ * through to the permission prompt so a human sees what they are approving. */
23
+ rawInput?: unknown;
24
+ }
25
+ /** Scope of a permission answer, as offered by the agent. */
26
+ export type AcpPermissionOptionKind = 'allow_once' | 'allow_always' | 'reject_once' | 'reject_always';
27
+ /** One choice the agent is willing to accept back. We must answer with an
28
+ * `optionId` drawn from the offered list — never a synthesized one. */
29
+ export interface AcpPermissionOption {
30
+ optionId: string;
31
+ name: string;
32
+ kind: AcpPermissionOptionKind;
33
+ }
34
+ /** `session/request_permission` — an agent asking the CLIENT to authorize a tool
35
+ * call. We are the client, so this is where our Policy is consulted. */
36
+ export interface AcpRequestPermissionRequest {
37
+ sessionId: string;
38
+ toolCall: AcpToolCallUpdate;
39
+ options: AcpPermissionOption[];
40
+ }
41
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../acp/types.ts"],"names":[],"mappings":"AAaA;;uDAEuD;AACvD,MAAM,MAAM,WAAW,GACnB,MAAM,GACN,MAAM,GACN,QAAQ,GACR,MAAM,GACN,QAAQ,GACR,SAAS,GACT,OAAO,GACP,OAAO,GACP,OAAO,CAAC;AAEZ,gFAAgF;AAChF,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED;kEACkE;AAClE,MAAM,WAAW,iBAAiB;IAChC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;iDAE6C;IAC7C,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,WAAW,CAAC;IACnB,MAAM,CAAC,EAAE,SAAS,GAAG,aAAa,GAAG,WAAW,GAAG,QAAQ,CAAC;IAC5D,SAAS,CAAC,EAAE,mBAAmB,EAAE,CAAC;IAClC;mFAC+E;IAC/E,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,6DAA6D;AAC7D,MAAM,MAAM,uBAAuB,GAC/B,YAAY,GACZ,cAAc,GACd,aAAa,GACb,eAAe,CAAC;AAEpB;uEACuE;AACvE,MAAM,WAAW,mBAAmB;IAClC,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,uBAAuB,CAAC;CAC/B;AAED;wEACwE;AACxE,MAAM,WAAW,2BAA2B;IAC1C,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,iBAAiB,CAAC;IAC5B,OAAO,EAAE,mBAAmB,EAAE,CAAC;CAChC"}
@@ -0,0 +1,14 @@
1
+ /* The subset of the Agent Client Protocol wire format we consume as an ACP
2
+ * CLIENT (driving an external agent such as Claude Code).
3
+ *
4
+ * Hand-written rather than generated from the published schema.json: we touch a
5
+ * handful of fields on two messages, and a generated multi-thousand-line mirror
6
+ * would be a maintenance liability that hides which parts we actually depend on.
7
+ *
8
+ * Source: agentclientprotocol.com/protocol/{tool-calls,schema}. Every field the
9
+ * spec marks optional is optional here too — that faithfulness is load-bearing,
10
+ * because `kind` being absent is exactly the case the policy mapping must fail
11
+ * closed on (see policyMap.ts).
12
+ */
13
+ export {};
14
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../acp/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG"}
@@ -0,0 +1,39 @@
1
+ import { CorenelApiClient } from './client';
2
+ /** Capabilities a backend may advertise. Strings, not an enum: an older client
3
+ * must be able to read a newer backend's list without choking on a name it does
4
+ * not know. */
5
+ export declare const CAP_SESSIONS = "sessions";
6
+ export declare const CAP_BLOBS = "blobs";
7
+ export declare const CAP_SNAPSHOTS = "snapshots";
8
+ export interface BackendConfig {
9
+ /** e.g. https://api.corenel.ai/api/v1 — trailing slashes are trimmed. */
10
+ baseUrl: string;
11
+ getToken(): Promise<string> | string;
12
+ /** Injected so a test needs no network; defaults to the ambient fetch. */
13
+ fetch?: typeof fetch;
14
+ }
15
+ export interface Backend {
16
+ readonly baseUrl: string;
17
+ readonly client: CorenelApiClient;
18
+ /** What the last probe found. Empty before probing, and empty is honest: we
19
+ * have not asked, so we do not know. */
20
+ capabilities(): readonly string[];
21
+ supports(capability: string): boolean;
22
+ /** Ask the backend what it is. Safe to call more than once. */
23
+ probe(): Promise<readonly string[]>;
24
+ }
25
+ /**
26
+ * Point at a backend, or at none.
27
+ *
28
+ * Called by a HOST — the browser app, the sidecar, a hosted runner — and by
29
+ * nothing else. Passing null detaches, which a config change that removes the URL
30
+ * must do rather than leaving the last one running.
31
+ */
32
+ export declare function configureBackend(cfg: BackendConfig | null): Backend | null;
33
+ /** The configured backend, or null when this host runs local-only. */
34
+ export declare function backend(): Backend | null;
35
+ /** True when a backend is attached AND says it can do this. Both halves matter:
36
+ * attached-but-incapable is the prompd gateway, and using it for sessions would
37
+ * be a 404 on every push. */
38
+ export declare function backendSupports(capability: string): boolean;
39
+ //# sourceMappingURL=backend.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"backend.d.ts","sourceRoot":"","sources":["../../api/backend.ts"],"names":[],"mappings":"AAsBA,OAAO,EAAE,gBAAgB,EAAqB,MAAM,UAAU,CAAC;AAE/D;;eAEe;AACf,eAAO,MAAM,YAAY,aAAa,CAAC;AACvC,eAAO,MAAM,SAAS,UAAU,CAAC;AACjC,eAAO,MAAM,aAAa,cAAc,CAAC;AAEzC,MAAM,WAAW,aAAa;IAC5B,yEAAyE;IACzE,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,IAAI,OAAO,CAAC,MAAM,CAAC,GAAG,MAAM,CAAC;IACrC,0EAA0E;IAC1E,KAAK,CAAC,EAAE,OAAO,KAAK,CAAC;CACtB;AAED,MAAM,WAAW,OAAO;IACtB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,MAAM,EAAE,gBAAgB,CAAC;IAClC;4CACwC;IACxC,YAAY,IAAI,SAAS,MAAM,EAAE,CAAC;IAClC,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC;IACtC,+DAA+D;IAC/D,KAAK,IAAI,OAAO,CAAC,SAAS,MAAM,EAAE,CAAC,CAAC;CACrC;AAuDD;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,aAAa,GAAG,IAAI,GAAG,OAAO,GAAG,IAAI,CAG1E;AAED,sEAAsE;AACtE,wBAAgB,OAAO,IAAI,OAAO,GAAG,IAAI,CAExC;AAED;;6BAE6B;AAC7B,wBAAgB,eAAe,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAE3D"}
@@ -0,0 +1,126 @@
1
+ /* THE BACKEND: one place that knows where it is and what it can do.
2
+ *
3
+ * Replaces a per-host flag with a per-host CONFIGURATION. A sidecar had grown
4
+ * `--api`, the browser had an env var, and the hosted runner would have grown a
5
+ * third — three mechanisms for one decision, which is how they drift. A host
6
+ * configures a backend; everything else asks this.
7
+ *
8
+ * IT ASKS THE BACKEND WHAT IT IS, rather than being told by a flag. Pointing at
9
+ * `api.prompd.app` and pointing at `api.corenel.ai` are not the same thing —
10
+ * prompd's gateway has no sessions, no blobs and no lease — and a caller should
11
+ * not have to be configured with that fact when the server can simply say so.
12
+ * `probe()` reads `/meta`; a backend that does not answer, or answers without a
13
+ * capability, does not get used for it.
14
+ *
15
+ * WHY A PROBE AND NOT A SECOND FLAG. A flag can be wrong. A machine pointed at
16
+ * the wrong backend with `--api` set would push into a 404 forever and look like
17
+ * a quiet session; asking removes the class of error entirely, and costs one
18
+ * request at startup.
19
+ *
20
+ * Absent is normal. No backend means local-only, which is the correct state for a
21
+ * laptop working alone and never an error to report.
22
+ */
23
+ import { CorenelApiClient } from './client.js';
24
+ /** Capabilities a backend may advertise. Strings, not an enum: an older client
25
+ * must be able to read a newer backend's list without choking on a name it does
26
+ * not know. */
27
+ export const CAP_SESSIONS = 'sessions';
28
+ export const CAP_BLOBS = 'blobs';
29
+ export const CAP_SNAPSHOTS = 'snapshots';
30
+ class RemoteBackend {
31
+ constructor(cfg) {
32
+ Object.defineProperty(this, "baseUrl", {
33
+ enumerable: true,
34
+ configurable: true,
35
+ writable: true,
36
+ value: void 0
37
+ });
38
+ Object.defineProperty(this, "client", {
39
+ enumerable: true,
40
+ configurable: true,
41
+ writable: true,
42
+ value: void 0
43
+ });
44
+ Object.defineProperty(this, "caps", {
45
+ enumerable: true,
46
+ configurable: true,
47
+ writable: true,
48
+ value: []
49
+ });
50
+ Object.defineProperty(this, "probed", {
51
+ enumerable: true,
52
+ configurable: true,
53
+ writable: true,
54
+ value: null
55
+ });
56
+ Object.defineProperty(this, "fetchImpl", {
57
+ enumerable: true,
58
+ configurable: true,
59
+ writable: true,
60
+ value: void 0
61
+ });
62
+ this.baseUrl = cfg.baseUrl.replace(/\/+$/, '');
63
+ this.fetchImpl = cfg.fetch ?? ((...args) => fetch(...args));
64
+ const transport = {
65
+ fetch: this.fetchImpl,
66
+ baseUrl: this.baseUrl,
67
+ getToken: cfg.getToken,
68
+ };
69
+ this.client = new CorenelApiClient(transport);
70
+ }
71
+ capabilities() {
72
+ return this.caps;
73
+ }
74
+ supports(capability) {
75
+ return this.caps.includes(capability);
76
+ }
77
+ probe() {
78
+ if (this.probed)
79
+ return this.probed;
80
+ this.probed = (async () => {
81
+ try {
82
+ // Unauthenticated on purpose: "what are you" must be answerable before a
83
+ // credential is sorted out, or a signed-out machine could never discover
84
+ // that signing in would be worth it.
85
+ const res = await this.fetchImpl(`${this.baseUrl}/meta`);
86
+ if (!res.ok)
87
+ return [];
88
+ const body = await res.json();
89
+ this.caps = Array.isArray(body.capabilities)
90
+ ? body.capabilities.filter((c) => typeof c === 'string')
91
+ : [];
92
+ return this.caps;
93
+ }
94
+ catch {
95
+ // Unreachable, not JSON, or not a corenel backend at all. All of them
96
+ // mean the same thing: do not use it for anything.
97
+ this.caps = [];
98
+ return this.caps;
99
+ }
100
+ })();
101
+ return this.probed;
102
+ }
103
+ }
104
+ let current = null;
105
+ /**
106
+ * Point at a backend, or at none.
107
+ *
108
+ * Called by a HOST — the browser app, the sidecar, a hosted runner — and by
109
+ * nothing else. Passing null detaches, which a config change that removes the URL
110
+ * must do rather than leaving the last one running.
111
+ */
112
+ export function configureBackend(cfg) {
113
+ current = cfg && cfg.baseUrl ? new RemoteBackend(cfg) : null;
114
+ return current;
115
+ }
116
+ /** The configured backend, or null when this host runs local-only. */
117
+ export function backend() {
118
+ return current;
119
+ }
120
+ /** True when a backend is attached AND says it can do this. Both halves matter:
121
+ * attached-but-incapable is the prompd gateway, and using it for sessions would
122
+ * be a 404 on every push. */
123
+ export function backendSupports(capability) {
124
+ return current?.supports(capability) ?? false;
125
+ }
126
+ //# sourceMappingURL=backend.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"backend.js","sourceRoot":"","sources":["../../api/backend.ts"],"names":[],"mappings":"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"}