@ahpd/server 0.1.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/LICENSE +21 -0
  2. package/README.md +129 -0
  3. package/dist/automations.d.ts +4 -0
  4. package/dist/automations.d.ts.map +1 -0
  5. package/dist/automations.js +191 -0
  6. package/dist/automations.js.map +1 -0
  7. package/dist/catalog.d.ts +48 -0
  8. package/dist/catalog.d.ts.map +1 -0
  9. package/dist/catalog.js +51 -0
  10. package/dist/catalog.js.map +1 -0
  11. package/dist/changes.d.ts +4 -0
  12. package/dist/changes.d.ts.map +1 -0
  13. package/dist/changes.js +601 -0
  14. package/dist/changes.js.map +1 -0
  15. package/dist/cron.d.ts +43 -0
  16. package/dist/cron.d.ts.map +1 -0
  17. package/dist/cron.js +211 -0
  18. package/dist/cron.js.map +1 -0
  19. package/dist/git.d.ts +16 -0
  20. package/dist/git.d.ts.map +1 -0
  21. package/dist/git.js +126 -0
  22. package/dist/git.js.map +1 -0
  23. package/dist/host.d.ts +24 -0
  24. package/dist/host.d.ts.map +1 -0
  25. package/dist/host.js +5850 -0
  26. package/dist/host.js.map +1 -0
  27. package/dist/index.d.ts +36 -0
  28. package/dist/index.d.ts.map +1 -0
  29. package/dist/index.js +34 -0
  30. package/dist/index.js.map +1 -0
  31. package/dist/listen.d.ts +3 -0
  32. package/dist/listen.d.ts.map +1 -0
  33. package/dist/listen.js +183 -0
  34. package/dist/listen.js.map +1 -0
  35. package/dist/paging.d.ts +38 -0
  36. package/dist/paging.d.ts.map +1 -0
  37. package/dist/paging.js +53 -0
  38. package/dist/paging.js.map +1 -0
  39. package/dist/paths.d.ts +15 -0
  40. package/dist/paths.d.ts.map +1 -0
  41. package/dist/paths.js +19 -0
  42. package/dist/paths.js.map +1 -0
  43. package/dist/resources.d.ts +122 -0
  44. package/dist/resources.d.ts.map +1 -0
  45. package/dist/resources.js +494 -0
  46. package/dist/resources.js.map +1 -0
  47. package/dist/rpc.d.ts +63 -0
  48. package/dist/rpc.d.ts.map +1 -0
  49. package/dist/rpc.js +208 -0
  50. package/dist/rpc.js.map +1 -0
  51. package/dist/scheduled.d.ts +48 -0
  52. package/dist/scheduled.d.ts.map +1 -0
  53. package/dist/scheduled.js +325 -0
  54. package/dist/scheduled.js.map +1 -0
  55. package/dist/terminals.d.ts +29 -0
  56. package/dist/terminals.d.ts.map +1 -0
  57. package/dist/terminals.js +346 -0
  58. package/dist/terminals.js.map +1 -0
  59. package/dist/tools.d.ts +18 -0
  60. package/dist/tools.d.ts.map +1 -0
  61. package/dist/tools.js +65 -0
  62. package/dist/tools.js.map +1 -0
  63. package/dist/types/agent.d.ts +245 -0
  64. package/dist/types/agent.d.ts.map +1 -0
  65. package/dist/types/agent.js +3 -0
  66. package/dist/types/agent.js.map +1 -0
  67. package/dist/types/automations.d.ts +164 -0
  68. package/dist/types/automations.d.ts.map +1 -0
  69. package/dist/types/automations.js +3 -0
  70. package/dist/types/automations.js.map +1 -0
  71. package/dist/types/catalog.d.ts +30 -0
  72. package/dist/types/catalog.d.ts.map +1 -0
  73. package/dist/types/catalog.js +3 -0
  74. package/dist/types/catalog.js.map +1 -0
  75. package/dist/types/changes.d.ts +272 -0
  76. package/dist/types/changes.d.ts.map +1 -0
  77. package/dist/types/changes.js +3 -0
  78. package/dist/types/changes.js.map +1 -0
  79. package/dist/types/common.d.ts +9 -0
  80. package/dist/types/common.d.ts.map +1 -0
  81. package/dist/types/common.js +3 -0
  82. package/dist/types/common.js.map +1 -0
  83. package/dist/types/host.d.ts +372 -0
  84. package/dist/types/host.d.ts.map +1 -0
  85. package/dist/types/host.js +3 -0
  86. package/dist/types/host.js.map +1 -0
  87. package/dist/types/index.d.ts +20 -0
  88. package/dist/types/index.d.ts.map +1 -0
  89. package/dist/types/index.js +8 -0
  90. package/dist/types/index.js.map +1 -0
  91. package/dist/types/listen.d.ts +48 -0
  92. package/dist/types/listen.d.ts.map +1 -0
  93. package/dist/types/listen.js +3 -0
  94. package/dist/types/listen.js.map +1 -0
  95. package/dist/types/paging.d.ts +10 -0
  96. package/dist/types/paging.d.ts.map +1 -0
  97. package/dist/types/paging.js +3 -0
  98. package/dist/types/paging.js.map +1 -0
  99. package/dist/types/probe.d.ts +46 -0
  100. package/dist/types/probe.d.ts.map +1 -0
  101. package/dist/types/probe.js +3 -0
  102. package/dist/types/probe.js.map +1 -0
  103. package/dist/types/resources.d.ts +83 -0
  104. package/dist/types/resources.d.ts.map +1 -0
  105. package/dist/types/resources.js +3 -0
  106. package/dist/types/resources.js.map +1 -0
  107. package/dist/types/rpc.d.ts +65 -0
  108. package/dist/types/rpc.d.ts.map +1 -0
  109. package/dist/types/rpc.js +3 -0
  110. package/dist/types/rpc.js.map +1 -0
  111. package/dist/types/session.d.ts +395 -0
  112. package/dist/types/session.d.ts.map +1 -0
  113. package/dist/types/session.js +3 -0
  114. package/dist/types/session.js.map +1 -0
  115. package/dist/types/terminals.d.ts +131 -0
  116. package/dist/types/terminals.d.ts.map +1 -0
  117. package/dist/types/terminals.js +3 -0
  118. package/dist/types/terminals.js.map +1 -0
  119. package/dist/types/wire.d.ts +62 -0
  120. package/dist/types/wire.d.ts.map +1 -0
  121. package/dist/types/wire.js +13 -0
  122. package/dist/types/wire.js.map +1 -0
  123. package/dist/types/worktrees.d.ts +86 -0
  124. package/dist/types/worktrees.d.ts.map +1 -0
  125. package/dist/types/worktrees.js +3 -0
  126. package/dist/types/worktrees.js.map +1 -0
  127. package/dist/worktrees.d.ts +27 -0
  128. package/dist/worktrees.d.ts.map +1 -0
  129. package/dist/worktrees.js +152 -0
  130. package/dist/worktrees.js.map +1 -0
  131. package/package.json +61 -0
  132. package/src/automations.ts +204 -0
  133. package/src/catalog.ts +53 -0
  134. package/src/changes.ts +629 -0
  135. package/src/cron.ts +251 -0
  136. package/src/git.ts +132 -0
  137. package/src/host.ts +5947 -0
  138. package/src/index.ts +40 -0
  139. package/src/listen.ts +240 -0
  140. package/src/paging.ts +56 -0
  141. package/src/paths.ts +19 -0
  142. package/src/resources.ts +513 -0
  143. package/src/rpc.ts +222 -0
  144. package/src/scheduled.ts +369 -0
  145. package/src/terminals.ts +353 -0
  146. package/src/tools.ts +64 -0
  147. package/src/types/agent.ts +255 -0
  148. package/src/types/automations.ts +164 -0
  149. package/src/types/catalog.ts +26 -0
  150. package/src/types/changes.ts +266 -0
  151. package/src/types/common.ts +9 -0
  152. package/src/types/host.ts +386 -0
  153. package/src/types/index.ts +27 -0
  154. package/src/types/listen.ts +53 -0
  155. package/src/types/paging.ts +11 -0
  156. package/src/types/probe.ts +42 -0
  157. package/src/types/resources.ts +107 -0
  158. package/src/types/rpc.ts +68 -0
  159. package/src/types/session.ts +415 -0
  160. package/src/types/terminals.ts +133 -0
  161. package/src/types/wire.ts +69 -0
  162. package/src/types/worktrees.ts +91 -0
  163. package/src/worktrees.ts +162 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Luiz Fernando Softov <lfs@softov.dev>
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,129 @@
1
+ # @ahpd/server
2
+
3
+ A server library for the [Agent Host Protocol](https://github.com/microsoft/agent-host-protocol).
4
+
5
+ It has no agent in it. You pass one in when you create the host.
6
+
7
+ ## Install
8
+
9
+ ```bash
10
+ pnpm add @ahpd/server @microsoft/agent-host-protocol
11
+ ```
12
+
13
+ The protocol package is a peer dependency. This package uses runtime values from it, so there should only be one copy in the dependency tree.
14
+
15
+ ## Use
16
+
17
+ A small host using the Claude backend looks like this:
18
+
19
+ ```ts
20
+ import { createHost, listen } from '@ahpd/server';
21
+ import { claude } from '@ahpd/agent-claude';
22
+
23
+ const host = createHost({
24
+ path: process.cwd(),
25
+ agents: [claude({ paths: [process.cwd()] })],
26
+ });
27
+
28
+ const listener = await listen({ port: 9187 }, (peer) => host.accept(peer));
29
+ console.log(`on ws://${listener.host}:${listener.port} (${listener.runtime})`);
30
+ ```
31
+
32
+ `createHost()` creates the AHP host.
33
+
34
+ `listen()` is the WebSocket listener included for Node, Bun and Deno. The host itself is not tied to WebSockets.
35
+
36
+ Once a client is connected, the host takes care of version negotiation, snapshots, subscriptions, sequence numbers, transcript paging, completions, queued messages, shared drafts, read and archived flags, multiple chats per session, and turns.
37
+
38
+ `accept(peer)` takes anything that can `send`, `notify` and `close`, and returns a handler. `listen` is a WebSocket implementation for Node, Bun and Deno. Tests supply their own, which is why the test suite runs without a network.
39
+
40
+ ## Options
41
+
42
+ `path` and `agents` are required. The rest are optional. If you leave one out, the host returns an error for the commands it cannot serve instead of an empty result.
43
+
44
+
45
+ ```ts
46
+ import {
47
+ createHost,
48
+ fileResources,
49
+ shellTerminals,
50
+ gitChanges,
51
+ gitBranches,
52
+ gitWorktrees,
53
+ hostTools,
54
+ scheduledAutomations,
55
+ } from '@ahpd/server';
56
+
57
+ const host = createHost({
58
+ path,
59
+ agents,
60
+ resources: fileResources(),
61
+ terminals: shellTerminals(),
62
+ changes: gitChanges(),
63
+ directories: gitBranches(),
64
+ worktrees: gitWorktrees(),
65
+ tools: hostTools(),
66
+ automations: scheduledAutomations({ file: './automations.json', }),
67
+ });
68
+
69
+ ```
70
+
71
+ | option | |
72
+ | --- | --- |
73
+ | `path` | the directory whose sessions this host serves |
74
+ | `agents` | the backends to serve, as `Agent` implementations |
75
+ | `resources` | file reads, writes, and `@` completion. Use `fileResources()` |
76
+ | `terminals` | a shell as a terminal channel. Use `shellTerminals()` |
77
+ | `changes` | uncommitted changes as a changeset. Use `gitChanges()` |
78
+ | `directories` | the current branch of each served directory. Use `gitBranches()` |
79
+ | `automations` | triggered agents. Use `memoryAutomations()`, or `scheduledAutomations({ file })` for cron |
80
+ | `worktrees` | sessions in their own git worktree. Use `gitWorktrees()` |
81
+ | `tools` | tools the host adds to every session. Use `hostTools()` |
82
+ | `onEvent` | called with one line per notable event, for logging |
83
+
84
+ None of these are imported by the host itself. `fileResources` reads files, `shellTerminals` spawns shells, and `gitBranches` runs `git`, and you pass them in.
85
+
86
+ ## Writing a backend
87
+
88
+ `Agent` has five required members: `provider`, `displayName`, `schema`, `defaults` and `create`.
89
+
90
+ ```ts
91
+ import type { Agent, Session, Start } from '@ahpd/server';
92
+
93
+ export function parrot(): Agent {
94
+ return {
95
+ provider: 'parrot',
96
+ displayName: 'Parrot',
97
+ schema: () => ({ properties: {} }),
98
+ defaults: () => ({}),
99
+ create: (start: Start): Session => converse(start),
100
+ };
101
+ }
102
+ ```
103
+
104
+ `provider` is the id a client names in `createSession`. It has to be unique among the agents one host was given.
105
+
106
+ `schema()` says what a session of this kind can be configured with, and `defaults()` says where those keys start. Both can be empty.
107
+
108
+ `create()` returns the session. The session holds the state of the session and chat channels, and calls `start.emit('chat', ...)` as things happen.
109
+
110
+ Pass it to the host like any other backend: `createHost({ path, agents: [parrot()] })`. Your backend and [`@ahpd/agent-claude`](https://www.npmjs.com/package/@ahpd/agent-claude) register identically and can run side by side.
111
+
112
+ See [docs/AGENT.md](https://github.com/softov/ahpd/blob/main/docs/AGENT.md) for the contract, and [examples/echo](https://github.com/softov/ahpd/tree/main/examples/echo) for a working backend in about two hundred lines.
113
+
114
+ ## Types
115
+
116
+ All types are exported. Nothing under `types/` imports a runtime value, so you can read the contract without loading the implementation.
117
+
118
+ ## Documentation
119
+
120
+ | | |
121
+ | --- | --- |
122
+ | [LIBRARY.md](https://github.com/softov/ahpd/blob/main/docs/LIBRARY.md) | `createHost` and the ports in full |
123
+ | [AGENT.md](https://github.com/softov/ahpd/blob/main/docs/AGENT.md) | The `Agent` and `Session` contracts |
124
+ | [AHP.md](https://github.com/softov/ahpd/blob/main/docs/AHP.md) | Protocol coverage action by action |
125
+
126
+ ## License
127
+
128
+ MIT © Softov
129
+
@@ -0,0 +1,4 @@
1
+ /** Automations held in memory, run when somebody asks. */
2
+ import type { AutomationStore } from './types/automations.js';
3
+ export declare function memoryAutomations(): AutomationStore;
4
+ //# sourceMappingURL=automations.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"automations.d.ts","sourceRoot":"","sources":["../src/automations.ts"],"names":[],"mappings":"AAAA,0DAA0D;AAG1D,OAAO,KAAK,EAA6B,eAAe,EAAgB,MAAM,wBAAwB,CAAC;AAsBvG,wBAAgB,iBAAiB,IAAI,eAAe,CAkLnD"}
@@ -0,0 +1,191 @@
1
+ /** Automations held in memory, run when somebody asks. */
2
+ import { randomUUID } from 'node:crypto';
3
+ /**
4
+ * The automations of a host that does not schedule.
5
+ *
6
+ * Deliberately half a store, and the half worth having first: definitions can
7
+ * be written, patched, listed and *run*, and nothing here holds a clock. An
8
+ * automation with a schedule trigger is accepted, kept and reported with no
9
+ * `nextRunAt` - which is the honest form of "this host will not fire that",
10
+ * and is what stops a client drawing a next-run time that will never arrive.
11
+ *
12
+ * Everything is in memory, so it goes when the process does. A store that
13
+ * outlives a restart is a different implementation of the same interface, and
14
+ * the reason the interface exists.
15
+ */
16
+ const now = () => new Date().toISOString();
17
+ /** How many runs a summary list carries before it needs a cursor. */
18
+ const PAGE = 20;
19
+ export function memoryAutomations() {
20
+ const held = new Map();
21
+ /** Runs by automation, newest first. */
22
+ const history = new Map();
23
+ /** Every run by its own URI, for the channel a client watches it on. */
24
+ const byRun = new Map();
25
+ const listeners = [];
26
+ const said = (event) => {
27
+ for (const listener of listeners)
28
+ listener(event);
29
+ };
30
+ /** The summary form of a run, which is what an automation carries. */
31
+ const summary = (run) => ({
32
+ resource: run.resource,
33
+ automation: run.automation,
34
+ origin: run.origin,
35
+ lifecycle: run.lifecycle,
36
+ sessionCount: run.sessions.length,
37
+ ...(run.primarySession !== undefined ? { primarySession: run.primarySession } : {}),
38
+ });
39
+ /** Rebuild the entry a client reads, so `runs` and `operations` are never stale. */
40
+ const entry = (automation) => {
41
+ const enabled = automation.definition.enabled !== false;
42
+ return {
43
+ ...automation,
44
+ runs: (history.get(automation.resource) ?? []).slice(0, PAGE).map(summary),
45
+ ...((history.get(automation.resource) ?? []).length > PAGE
46
+ ? { runsNextCursor: String(PAGE) }
47
+ : {}),
48
+ // `run` only where it would do something. A disabled automation is one
49
+ // somebody switched off, and offering the button anyway is a control
50
+ // that argues with the switch beside it.
51
+ operations: enabled ? ['update', 'remove', 'run'] : ['update', 'remove'],
52
+ };
53
+ };
54
+ return {
55
+ list: () => [...held.values()].map(entry),
56
+ get: (resource) => {
57
+ const found = held.get(resource);
58
+ return found && entry(found);
59
+ },
60
+ /*
61
+ * What this store understands, which is nothing.
62
+ *
63
+ * This command answers with *event* triggers. Schedule triggers are
64
+ * protocol-defined and never listed here, and manual is not a trigger at
65
+ * all - the protocol says an empty trigger list is what manual-only means.
66
+ * So a store with no event triggers answers with none, and a client reads
67
+ * "this host will not fire that" from the absent `nextRunAt` instead.
68
+ */
69
+ triggers: () => [],
70
+ create: (resource, definition) => {
71
+ const at = now();
72
+ const made = {
73
+ resource,
74
+ definition,
75
+ runs: [],
76
+ operations: [],
77
+ createdAt: at,
78
+ modifiedAt: at,
79
+ };
80
+ held.set(resource, made);
81
+ said({ automation: resource });
82
+ return entry(made);
83
+ },
84
+ update: (resource, changes) => {
85
+ const found = held.get(resource);
86
+ if (!found)
87
+ return undefined;
88
+ // A patch: absent keys are left alone, which is the whole difference
89
+ // between this and a write. A client sending the whole definition back
90
+ // would otherwise revert whatever another client changed meanwhile.
91
+ const after = {
92
+ ...found,
93
+ definition: { ...found.definition, ...changes },
94
+ modifiedAt: now(),
95
+ };
96
+ held.set(resource, after);
97
+ said({ automation: resource });
98
+ return entry(after);
99
+ },
100
+ remove: (resource) => {
101
+ if (!held.delete(resource))
102
+ return false;
103
+ for (const run of history.get(resource) ?? [])
104
+ byRun.delete(run.resource);
105
+ history.delete(resource);
106
+ said({ removed: resource });
107
+ return true;
108
+ },
109
+ run: async (resource, origin, start) => {
110
+ const found = held.get(resource);
111
+ if (!found)
112
+ return undefined;
113
+ if (found.definition.enabled === false)
114
+ return undefined;
115
+ const template = (typeof found.definition.session === 'object' && found.definition.session !== null
116
+ ? found.definition.session
117
+ : {});
118
+ const message = (typeof found.definition.message === 'object' && found.definition.message !== null
119
+ ? found.definition.message
120
+ : {});
121
+ const run = {
122
+ resource: `ahp-automation-run:/${randomUUID()}`,
123
+ automation: resource,
124
+ origin,
125
+ lifecycle: { status: 'pending', createdAt: now() },
126
+ sessions: [],
127
+ };
128
+ byRun.set(run.resource, run);
129
+ const past = history.get(resource) ?? [];
130
+ // Newest first, which is the order a client shows them in.
131
+ history.set(resource, [run, ...past]);
132
+ said({ automation: resource, run: run.resource });
133
+ const directories = Array.isArray(template.workingDirectories) ? template.workingDirectories : [];
134
+ const where = typeof directories[0] === 'string'
135
+ ? directories[0].replace(/^file:\/\//, '')
136
+ : undefined;
137
+ const options = {
138
+ ...(typeof template.provider === 'string' ? { provider: template.provider } : {}),
139
+ ...(where !== undefined ? { workingDirectory: where } : {}),
140
+ ...(typeof template.config === 'object' && template.config !== null
141
+ ? { config: template.config }
142
+ : {}),
143
+ text: typeof message.text === 'string' ? message.text : String(found.definition.title ?? ''),
144
+ origin: { kind: 'automation', automation: resource, run: run.resource },
145
+ };
146
+ try {
147
+ const session = await start(options);
148
+ run.sessions = [session];
149
+ run.primarySession = session;
150
+ run.lifecycle = { ...run.lifecycle, status: 'running', startedAt: now() };
151
+ }
152
+ catch (error) {
153
+ // Failed, and why. A run that vanished would be indistinguishable from
154
+ // one that never started.
155
+ run.lifecycle = {
156
+ ...run.lifecycle,
157
+ status: 'failed',
158
+ endedAt: now(),
159
+ error: { message: error instanceof Error ? error.message : String(error) },
160
+ };
161
+ }
162
+ said({ automation: resource, run: run.resource });
163
+ return run;
164
+ },
165
+ runOf: (resource) => byRun.get(resource),
166
+ unlink: (resource, session) => {
167
+ const run = byRun.get(resource);
168
+ if (run === undefined || !run.sessions.includes(session))
169
+ return false;
170
+ run.sessions = run.sessions.filter((one) => one !== session);
171
+ // The protocol says removing the primary clears it. A run pointing at a
172
+ // session that is gone is a run a client opens onto nothing.
173
+ if (run.primarySession === session)
174
+ delete run.primarySession;
175
+ said({ automation: run.automation, run: run.resource });
176
+ return true;
177
+ },
178
+ runs: (resource, cursor) => {
179
+ const all = history.get(resource) ?? [];
180
+ const from = cursor === undefined ? 0 : Number(cursor);
181
+ const at = Number.isFinite(from) && from >= 0 ? from : 0;
182
+ const page = all.slice(at, at + PAGE);
183
+ return {
184
+ items: page.map(summary),
185
+ ...(at + PAGE < all.length ? { nextCursor: String(at + PAGE) } : {}),
186
+ };
187
+ },
188
+ onChanged: (observer) => { listeners.push(observer); },
189
+ };
190
+ }
191
+ //# sourceMappingURL=automations.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"automations.js","sourceRoot":"","sources":["../src/automations.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,48 @@
1
+ /**
2
+ * How a session is named, and what its status bits are worth.
3
+ *
4
+ * URIs and numbers, and nothing that knows what a session *is*: the listing
5
+ * itself belongs to whichever backend wrote the sessions down, because only
6
+ * that one can say which exist. See `catalogue` in `@ahpd/agent-claude`.
7
+ */
8
+ /**
9
+ * `SessionStatus`, as values.
10
+ *
11
+ * The protocol declares it as a `const enum`, which exists only in the type
12
+ * system - importing it at runtime is a value import of something that was
13
+ * erased. So the numbers are restated here, and they are the protocol's:
14
+ * `InputNeeded` is 24 and *carries* `InProgress` (8), which is why anything
15
+ * testing activity has to test it first.
16
+ */
17
+ export declare const Status: {
18
+ readonly Idle: 1;
19
+ readonly Error: 2;
20
+ readonly InProgress: 8;
21
+ readonly InputNeeded: 24;
22
+ readonly IsRead: 32;
23
+ readonly IsArchived: 64;
24
+ };
25
+ /**
26
+ * A URI for a session this host found on disk. `ahp-session:/<uuid>`, and the
27
+ * SDK's id is already a uuid.
28
+ *
29
+ * Only for rows this host names itself. A session a *client* created is named
30
+ * by that client, in whatever scheme it likes - see {@link idOf}.
31
+ */
32
+ export declare const uriFor: (sessionId: string) => string;
33
+ /**
34
+ * The id inside a channel URI, whatever scheme the client chose.
35
+ *
36
+ * A channel URI is the **client's** to name and this host's to echo. VS Code
37
+ * names a session after its provider - `claude:/<uuid>`, with the provider as
38
+ * the *scheme* - and its terminals `agenthost-terminal:/<uuid>`. This used to
39
+ * strip a literal `ahp-session:/` and refuse anything else, so every session
40
+ * and every terminal VS Code opened was answered `is not a session URI`.
41
+ *
42
+ * So: everything after the scheme, without its leading slashes. The result is
43
+ * an opaque key, not something to parse further.
44
+ */
45
+ export declare const idOf: (uri: string) => string;
46
+ /** The same, and the name it goes by where a session rather than a chat is meant. */
47
+ export declare const idFor: (uri: string) => string;
48
+ //# sourceMappingURL=catalog.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"catalog.d.ts","sourceRoot":"","sources":["../src/catalog.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH;;;;;;;;GAQG;AACH,eAAO,MAAM,MAAM;;;;;;;CAOT,CAAC;AAEX;;;;;;GAMG;AACH,eAAO,MAAM,MAAM,GAAI,WAAW,MAAM,KAAG,MAAqC,CAAC;AAEjF;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,IAAI,GAAI,KAAK,MAAM,KAAG,MAGlC,CAAC;AACF,qFAAqF;AACrF,eAAO,MAAM,KAAK,QALQ,MAAM,KAAG,MAKV,CAAC"}
@@ -0,0 +1,51 @@
1
+ /**
2
+ * How a session is named, and what its status bits are worth.
3
+ *
4
+ * URIs and numbers, and nothing that knows what a session *is*: the listing
5
+ * itself belongs to whichever backend wrote the sessions down, because only
6
+ * that one can say which exist. See `catalogue` in `@ahpd/agent-claude`.
7
+ */
8
+ /**
9
+ * `SessionStatus`, as values.
10
+ *
11
+ * The protocol declares it as a `const enum`, which exists only in the type
12
+ * system - importing it at runtime is a value import of something that was
13
+ * erased. So the numbers are restated here, and they are the protocol's:
14
+ * `InputNeeded` is 24 and *carries* `InProgress` (8), which is why anything
15
+ * testing activity has to test it first.
16
+ */
17
+ export const Status = {
18
+ Idle: 1,
19
+ Error: 2,
20
+ InProgress: 8,
21
+ InputNeeded: 24,
22
+ IsRead: 32,
23
+ IsArchived: 64,
24
+ };
25
+ /**
26
+ * A URI for a session this host found on disk. `ahp-session:/<uuid>`, and the
27
+ * SDK's id is already a uuid.
28
+ *
29
+ * Only for rows this host names itself. A session a *client* created is named
30
+ * by that client, in whatever scheme it likes - see {@link idOf}.
31
+ */
32
+ export const uriFor = (sessionId) => `ahp-session:/${sessionId}`;
33
+ /**
34
+ * The id inside a channel URI, whatever scheme the client chose.
35
+ *
36
+ * A channel URI is the **client's** to name and this host's to echo. VS Code
37
+ * names a session after its provider - `claude:/<uuid>`, with the provider as
38
+ * the *scheme* - and its terminals `agenthost-terminal:/<uuid>`. This used to
39
+ * strip a literal `ahp-session:/` and refuse anything else, so every session
40
+ * and every terminal VS Code opened was answered `is not a session URI`.
41
+ *
42
+ * So: everything after the scheme, without its leading slashes. The result is
43
+ * an opaque key, not something to parse further.
44
+ */
45
+ export const idOf = (uri) => {
46
+ const colon = uri.indexOf(':');
47
+ return (colon < 0 ? uri : uri.slice(colon + 1)).replace(/^\/+/, '');
48
+ };
49
+ /** The same, and the name it goes by where a session rather than a chat is meant. */
50
+ export const idFor = idOf;
51
+ //# sourceMappingURL=catalog.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"catalog.js","sourceRoot":"","sources":["../src/catalog.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,MAAM,GAAG;IACpB,IAAI,EAAE,CAAC;IACP,KAAK,EAAE,CAAC;IACR,UAAU,EAAE,CAAC;IACb,WAAW,EAAE,EAAE;IACf,MAAM,EAAE,EAAE;IACV,UAAU,EAAE,EAAE;CACN,CAAC;AAEX;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,MAAM,GAAG,CAAC,SAAiB,EAAU,EAAE,CAAC,gBAAgB,SAAS,EAAE,CAAC;AAEjF;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,MAAM,IAAI,GAAG,CAAC,GAAW,EAAU,EAAE;IAC1C,MAAM,KAAK,GAAG,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IAC/B,OAAO,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;AACtE,CAAC,CAAC;AACF,qFAAqF;AACrF,MAAM,CAAC,MAAM,KAAK,GAAG,IAAI,CAAC"}
@@ -0,0 +1,4 @@
1
+ /** What git says a directory has changed, as a host's `ChangesetSource`. */
2
+ import type { ChangesetSource } from './types/changes.js';
3
+ export declare function gitChanges(): ChangesetSource;
4
+ //# sourceMappingURL=changes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"changes.d.ts","sourceRoot":"","sources":["../src/changes.ts"],"names":[],"mappings":"AAAA,4EAA4E;AAI5E,OAAO,KAAK,EACyC,eAAe,EACnE,MAAM,oBAAoB,CAAC;AAuJ5B,wBAAgB,UAAU,IAAI,eAAe,CAud5C"}