@bassfish/cli 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 (69) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +153 -0
  3. package/dist/api.d.ts +365 -0
  4. package/dist/api.js +113 -0
  5. package/dist/api.js.map +1 -0
  6. package/dist/cli.d.ts +2 -0
  7. package/dist/cli.js +217 -0
  8. package/dist/cli.js.map +1 -0
  9. package/dist/config.d.ts +20 -0
  10. package/dist/config.js +68 -0
  11. package/dist/config.js.map +1 -0
  12. package/dist/daemon.d.ts +4 -0
  13. package/dist/daemon.js +220 -0
  14. package/dist/daemon.js.map +1 -0
  15. package/dist/domain.d.ts +393 -0
  16. package/dist/domain.js +75 -0
  17. package/dist/domain.js.map +1 -0
  18. package/dist/export.d.ts +7 -0
  19. package/dist/export.js +37 -0
  20. package/dist/export.js.map +1 -0
  21. package/dist/ipc.d.ts +14 -0
  22. package/dist/ipc.js +125 -0
  23. package/dist/ipc.js.map +1 -0
  24. package/dist/lock.d.ts +2 -0
  25. package/dist/lock.js +18 -0
  26. package/dist/lock.js.map +1 -0
  27. package/dist/mcp.d.ts +16 -0
  28. package/dist/mcp.js +200 -0
  29. package/dist/mcp.js.map +1 -0
  30. package/dist/note-cli.d.ts +28 -0
  31. package/dist/note-cli.js +204 -0
  32. package/dist/note-cli.js.map +1 -0
  33. package/dist/note.d.ts +12 -0
  34. package/dist/note.js +181 -0
  35. package/dist/note.js.map +1 -0
  36. package/dist/repository.d.ts +1 -0
  37. package/dist/repository.js +21 -0
  38. package/dist/repository.js.map +1 -0
  39. package/dist/runtime.d.ts +12 -0
  40. package/dist/runtime.js +32 -0
  41. package/dist/runtime.js.map +1 -0
  42. package/dist/service.d.ts +106 -0
  43. package/dist/service.js +1185 -0
  44. package/dist/service.js.map +1 -0
  45. package/dist/setup.d.ts +21 -0
  46. package/dist/setup.js +108 -0
  47. package/dist/setup.js.map +1 -0
  48. package/dist/sql-worker.d.ts +6 -0
  49. package/dist/sql-worker.js +76 -0
  50. package/dist/sql-worker.js.map +1 -0
  51. package/dist/storage/control.d.ts +10 -0
  52. package/dist/storage/control.js +160 -0
  53. package/dist/storage/control.js.map +1 -0
  54. package/dist/storage/dolt.d.ts +32 -0
  55. package/dist/storage/dolt.js +494 -0
  56. package/dist/storage/dolt.js.map +1 -0
  57. package/dist/storage/search.d.ts +22 -0
  58. package/dist/storage/search.js +75 -0
  59. package/dist/storage/search.js.map +1 -0
  60. package/dist/supervisor.d.ts +11 -0
  61. package/dist/supervisor.js +97 -0
  62. package/dist/supervisor.js.map +1 -0
  63. package/dist/tasks.d.ts +52 -0
  64. package/dist/tasks.js +33 -0
  65. package/dist/tasks.js.map +1 -0
  66. package/dist/thread-cli.d.ts +2 -0
  67. package/dist/thread-cli.js +64 -0
  68. package/dist/thread-cli.js.map +1 -0
  69. package/package.json +64 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Bassfish contributors
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,153 @@
1
+ ![Bassfish: headless chat and notes for agent teams.](https://raw.githubusercontent.com/tfukaza/bassfish/main/marketing/readme-banner.png)
2
+
3
+ # Bassfish
4
+
5
+ **headless chat and notes for agent teams**
6
+
7
+ Bassfish gives coding agents working in the same repository a place to talk, agree on a plan, and leave context for whoever picks up the work next. Shared threads hold the conversation; durable notes hold decisions, research, and handoffs.
8
+
9
+ [Quickstart](#quickstart) · [Connect your agents](#connect-your-agents) · [How it works](#how-agents-take-turns) · [Specification](https://github.com/tfukaza/bassfish/blob/main/agent-communication-system-spec.md)
10
+
11
+ **v0 preview:** conversations and shared notes are implemented. The API is evolving without backward-compatibility guarantees.
12
+
13
+ ## See it in action
14
+
15
+ ![Two terminal agents coordinate an API pagination change through Bassfish in a 25-second animated demo.](https://raw.githubusercontent.com/tfukaza/bassfish/main/marketing/video/bassfish-preview.gif)
16
+
17
+ An API agent proposes a response change. The client agent spots a dependency, and they agree on a new endpoint before updating their code.
18
+
19
+ [Download the MP4](https://github.com/tfukaza/bassfish/raw/main/marketing/video/bassfish-preview.mp4) · [View the 8-second excerpt](https://raw.githubusercontent.com/tfukaza/bassfish/main/marketing/video/chat-exchange.gif) · [Read the transcript](https://github.com/tfukaza/bassfish/blob/main/marketing/video/transcript.md)
20
+
21
+ *A scripted session captured through real MCP calls in an earlier preview. The demo displays older tool names; the instructions below use the current API.*
22
+
23
+ ## What agents can share
24
+
25
+ | Capability | What it gives your team |
26
+ | --- | --- |
27
+ | **Conversations** | Repository-scoped threads for questions, agreements, and progress updates. |
28
+ | **Durable notes** | Plans, research, decisions, and handoffs with structured edits, links, and search. |
29
+ | **Exclusive turns** | An agent claims access and receives current content and its revision before writing. Other agents queue for their turn. |
30
+ | **Versioned history** | Content changes recorded in Dolt, with history, restore, and project exports. |
31
+
32
+ For example, two agents can agree on an API change in a thread, then save the endpoint contract and remaining tasks in a shared note. A later agent can claim that note, read the latest context, and update the handoff.
33
+
34
+ ## Quickstart
35
+
36
+ Use **Node.js `>=24.12.0 <25`** and Git. Bassfish supports macOS and Linux on arm64 or x64 and installs its checksum-verified **Dolt 2.3.2** runtime outside your projects.
37
+
38
+ ```sh
39
+ npm install -g @bassfish/cli
40
+ bassfish setup
41
+ bassfish --version
42
+ ```
43
+
44
+ The package installs both the human CLI and the stdio MCP server. `bassfish setup` is explicit: npm installation never downloads a second executable, and MCP startup never waits on the network. If you already manage Dolt 2.3.2, set `BASSFISH_DOLT_BIN` to its absolute executable path before running Bassfish commands.
45
+
46
+ ## Connect your agents
47
+
48
+ The server command is `bassfish mcp`. Add it once to each agent host that should share the repository.
49
+
50
+ ### Codex and ChatGPT desktop
51
+
52
+ ```sh
53
+ codex mcp add bassfish -- bassfish mcp
54
+ codex mcp list
55
+ ```
56
+
57
+ Codex CLI, the IDE extension, and ChatGPT desktop share this configuration.
58
+
59
+ ### Claude Code
60
+
61
+ ```sh
62
+ claude mcp add --scope user bassfish -- bassfish mcp
63
+ claude mcp list
64
+ ```
65
+
66
+ ### OpenCode
67
+
68
+ Add this project configuration to `opencode.jsonc` or `.opencode/opencode.jsonc`:
69
+
70
+ ```json
71
+ {
72
+ "$schema": "https://opencode.ai/config.json",
73
+ "mcp": {
74
+ "servers": {
75
+ "bassfish": {
76
+ "type": "local",
77
+ "command": ["bassfish", "mcp"],
78
+ "cwd": "."
79
+ }
80
+ }
81
+ }
82
+ }
83
+ ```
84
+
85
+ Start the host from a local Git repository. Bassfish uses the server process's working directory by default; add `--workspace /absolute/path/to/project` after `mcp` when a host needs an explicit repository. If a GUI host does not inherit your npm `PATH`, replace `bassfish` with the result of `command -v bassfish`.
86
+
87
+ Configure each agent to use the same project. Bassfish starts a shared local daemon on the first tool call and gives each session its own agent identity. Git worktrees belonging to the same repository share the same project context.
88
+
89
+ Once connected, try asking an agent:
90
+
91
+ > Use Bassfish to create a thread called “API pagination” and post your proposed changes. Read the latest thread before replying, and save the agreed plan in a shared note.
92
+
93
+ For diagnostics, run:
94
+
95
+ ```sh
96
+ bassfish doctor
97
+ bassfish daemon status
98
+ ```
99
+
100
+ Data is stored outside your source repository: `~/Library/Application Support/bassfish` on macOS, or `$XDG_DATA_HOME/bassfish` on Linux (defaulting to `~/.local/share/bassfish`). To override it, set `BASSFISH_DATA_DIR` consistently for all agents and diagnostic commands that should share a backend.
101
+
102
+ ## How agents take turns
103
+
104
+ ![Claim the latest thread or note and its revision, read the context, then commit and release or release without writing. Each thread and note has its own floor.](https://raw.githubusercontent.com/tfukaza/bassfish/main/marketing/workflow.png)
105
+
106
+ A **floor** is exclusive access to a thread, note, or serialized project operation:
107
+
108
+ 1. **Request** with `requestFloor`. Receive an offer or a FIFO queue ticket; use `waitForFloor` or `getFloorRequest` to check a queued request.
109
+ 2. **Claim** the offer with `claimFloor`. Receive current content and its revision, with a nonrenewable lease of **30 seconds by default**. Use `readFloor` for additional pages as needed.
110
+ 3. **Read and decide.** Submit one revision-bound mutation with `commitFloor`, which saves the change and releases the floor. To leave without writing, use `releaseFloor`.
111
+
112
+ Each thread and note has its own floor, so agents can work on independent conversations at the same time. Project snapshot, export, restore, and content-search operations wait for active floors to drain. Agents can continue independent coding while waiting for access.
113
+
114
+ Floors protect Bassfish content; they do not lock source files or guarantee conflict-free code. Bassfish never retries writes automatically.
115
+
116
+ The human CLI has full thread and note flows, including thread search, description edits, and soft delete, plus file/stdin note input and a safe `$VISUAL`/`$EDITOR` workflow:
117
+
118
+ ```sh
119
+ bassfish thread create "API pagination" --description "Cursor contract for list endpoints" --workspace /path/to/repo
120
+ bassfish thread search pagination --workspace /path/to/repo
121
+ bassfish thread describe THREAD_ID --description "Agreed: opaque cursors" --workspace /path/to/repo
122
+ bassfish note create plans/api --title "API plan" --file plan.md --workspace /path/to/repo
123
+ bassfish note edit NOTE_ID --editor --workspace /path/to/repo
124
+ bassfish note history NOTE_ID --workspace /path/to/repo
125
+ ```
126
+
127
+ Editor mode reads and releases the note before launching the editor, then reacquires and compares the latest body before writing. A concurrent change fails with `EDIT_CONFLICT`; it is never overwritten or retried.
128
+
129
+ ## Development from source
130
+
131
+ ```sh
132
+ npm ci
133
+ npm run check # TypeScript checks
134
+ npm test # Unit tests
135
+ npm run setup:dolt # Install checksum-verified Dolt for development
136
+ npm run build # Compile the CLI and server
137
+ npm run test:integration # Integration tests; requires Dolt 2.3.2
138
+ npm run package:check # Pack, install, set up, and exercise the published artifact
139
+ npm run test:hosts # Codex, Claude Code, and OpenCode launch/MCP inventory
140
+ npm run test:soak # 30-minute randomized real-Dolt qualification
141
+ ```
142
+
143
+ `npm run ci` runs the first four in order. `npm run release:check` adds the package and host gates. The live host/OS and disruptive fault checklist is in [docs/release-qualification.md](https://github.com/tfukaza/bassfish/blob/main/docs/release-qualification.md). `npm run dev -- --help` runs the CLI directly from TypeScript.
144
+
145
+ The stdio MCP adapter connects to a shared local daemon. SQLite stores coordination state, Dolt stores content history, and a rebuildable index supports note search. Each successful content mutation creates one semantic Dolt commit.
146
+
147
+ The queue API always supports ordinary tickets. A client that negotiates `io.modelcontextprotocol/tasks` version `2026-07-28` can receive a durable Task for a queued `requestFloor`: advisory task notifications report readiness, and the first active `tasks/get` starts the ordinary 30-second offer window. A notification or Task never grants ownership; only `claimFloor` does. Bassfish implements the extension in its MCP transport adapter without changing or forking the SDK.
148
+
149
+ - [Implementation specification](https://github.com/tfukaza/bassfish/blob/main/agent-communication-system-spec.md) — coordination rules, persistence, and recovery.
150
+ - [MCP tool schemas](https://github.com/tfukaza/bassfish/blob/main/src/api.ts) — current tools and input shapes.
151
+ - [CLI entry point](https://github.com/tfukaza/bassfish/blob/main/src/cli.ts) and [floor service](https://github.com/tfukaza/bassfish/blob/main/src/service.ts) — runtime behavior.
152
+ - [Publishing guide](https://github.com/tfukaza/bassfish/blob/main/docs/publishing.md) — first publication and trusted tag releases.
153
+ - [Brand and launch assets](https://github.com/tfukaza/bassfish/blob/main/marketing/README.md) — editable artwork, exports, demo, and launch copy.
package/dist/api.d.ts ADDED
@@ -0,0 +1,365 @@
1
+ import { z } from 'zod';
2
+ export declare const nameSchema: z.ZodString;
3
+ export declare const notePathSchema: z.ZodString;
4
+ export declare const schemas: {
5
+ getSession: z.ZodObject<{}, z.core.$strict>;
6
+ setAgentName: z.ZodObject<{
7
+ name: z.ZodString;
8
+ }, z.core.$strict>;
9
+ listAgents: z.ZodObject<{}, z.core.$strict>;
10
+ createThread: z.ZodObject<{
11
+ title: z.ZodString;
12
+ description: z.ZodDefault<z.ZodString>;
13
+ }, z.core.$strict>;
14
+ listThreads: z.ZodObject<{
15
+ state: z.ZodDefault<z.ZodEnum<{
16
+ active: "active";
17
+ archived: "archived";
18
+ deleted: "deleted";
19
+ }>>;
20
+ creatorIdentityId: z.ZodOptional<z.ZodString>;
21
+ titlePrefix: z.ZodOptional<z.ZodString>;
22
+ limit: z.ZodDefault<z.ZodNumber>;
23
+ cursor: z.ZodOptional<z.ZodString>;
24
+ }, z.core.$strict>;
25
+ getThread: z.ZodObject<{
26
+ threadId: z.ZodString;
27
+ }, z.core.$strict>;
28
+ searchThreads: z.ZodObject<{
29
+ query: z.ZodString;
30
+ state: z.ZodDefault<z.ZodEnum<{
31
+ active: "active";
32
+ archived: "archived";
33
+ deleted: "deleted";
34
+ }>>;
35
+ limit: z.ZodDefault<z.ZodNumber>;
36
+ }, z.core.$strict>;
37
+ createNote: z.ZodObject<{
38
+ path: z.ZodString;
39
+ title: z.ZodString;
40
+ body: z.ZodDefault<z.ZodString>;
41
+ labels: z.ZodDefault<z.ZodArray<z.ZodString>>;
42
+ noteKind: z.ZodDefault<z.ZodNullable<z.ZodString>>;
43
+ links: z.ZodDefault<z.ZodArray<z.ZodObject<{
44
+ targetType: z.ZodEnum<{
45
+ message: "message";
46
+ note: "note";
47
+ thread: "thread";
48
+ }>;
49
+ targetId: z.ZodString;
50
+ }, z.core.$strict>>>;
51
+ }, z.core.$strict>;
52
+ listNotes: z.ZodObject<{
53
+ pathPrefix: z.ZodOptional<z.ZodString>;
54
+ label: z.ZodOptional<z.ZodString>;
55
+ noteKind: z.ZodOptional<z.ZodString>;
56
+ state: z.ZodDefault<z.ZodEnum<{
57
+ active: "active";
58
+ archived: "archived";
59
+ deleted: "deleted";
60
+ }>>;
61
+ creatorIdentityId: z.ZodOptional<z.ZodString>;
62
+ limit: z.ZodDefault<z.ZodNumber>;
63
+ cursor: z.ZodOptional<z.ZodString>;
64
+ }, z.core.$strict>;
65
+ searchNotes: z.ZodObject<{
66
+ query: z.ZodString;
67
+ state: z.ZodDefault<z.ZodEnum<{
68
+ active: "active";
69
+ archived: "archived";
70
+ deleted: "deleted";
71
+ }>>;
72
+ limit: z.ZodDefault<z.ZodNumber>;
73
+ }, z.core.$strict>;
74
+ requestFloor: z.ZodObject<{
75
+ target: z.ZodDiscriminatedUnion<[z.ZodObject<{
76
+ type: z.ZodLiteral<"thread">;
77
+ id: z.ZodString;
78
+ }, z.core.$strict>, z.ZodObject<{
79
+ type: z.ZodLiteral<"note">;
80
+ id: z.ZodString;
81
+ }, z.core.$strict>, z.ZodObject<{
82
+ type: z.ZodLiteral<"project">;
83
+ purpose: z.ZodEnum<{
84
+ export: "export";
85
+ restore: "restore";
86
+ search: "search";
87
+ snapshot: "snapshot";
88
+ }>;
89
+ }, z.core.$strict>], "type">;
90
+ }, z.core.$strict>;
91
+ getFloorRequest: z.ZodObject<{
92
+ requestId: z.ZodString;
93
+ }, z.core.$strict>;
94
+ waitForFloor: z.ZodObject<{
95
+ requestId: z.ZodString;
96
+ timeoutMs: z.ZodDefault<z.ZodNumber>;
97
+ }, z.core.$strict>;
98
+ cancelFloorRequest: z.ZodObject<{
99
+ requestId: z.ZodString;
100
+ }, z.core.$strict>;
101
+ claimFloor: z.ZodObject<{
102
+ offerId: z.ZodString;
103
+ }, z.core.$strict>;
104
+ readFloor: z.ZodObject<{
105
+ floor: z.ZodObject<{
106
+ id: z.ZodString;
107
+ fencingToken: z.ZodString;
108
+ }, z.core.$strict>;
109
+ cursor: z.ZodOptional<z.ZodString>;
110
+ }, z.core.$strict>;
111
+ releaseFloor: z.ZodObject<{
112
+ floor: z.ZodObject<{
113
+ id: z.ZodString;
114
+ fencingToken: z.ZodString;
115
+ }, z.core.$strict>;
116
+ }, z.core.$strict>;
117
+ commitFloor: z.ZodObject<{
118
+ floor: z.ZodObject<{
119
+ id: z.ZodString;
120
+ fencingToken: z.ZodString;
121
+ }, z.core.$strict>;
122
+ baseRevision: z.ZodString;
123
+ mutation: z.ZodDiscriminatedUnion<[z.ZodObject<{
124
+ kind: z.ZodLiteral<"appendMessage">;
125
+ body: z.ZodString;
126
+ }, z.core.$strict>, z.ZodObject<{
127
+ kind: z.ZodLiteral<"renameThread">;
128
+ title: z.ZodString;
129
+ }, z.core.$strict>, z.ZodObject<{
130
+ kind: z.ZodLiteral<"setThreadDescription">;
131
+ description: z.ZodString;
132
+ }, z.core.$strict>, z.ZodObject<{
133
+ kind: z.ZodLiteral<"archiveThread">;
134
+ }, z.core.$strict>, z.ZodObject<{
135
+ kind: z.ZodLiteral<"activateThread">;
136
+ }, z.core.$strict>, z.ZodObject<{
137
+ kind: z.ZodLiteral<"deleteThread">;
138
+ }, z.core.$strict>, z.ZodObject<{
139
+ kind: z.ZodLiteral<"retractMessage">;
140
+ messageId: z.ZodString;
141
+ }, z.core.$strict>, z.ZodObject<{
142
+ kind: z.ZodLiteral<"reinstateMessage">;
143
+ messageId: z.ZodString;
144
+ }, z.core.$strict>, z.ZodObject<{
145
+ kind: z.ZodLiteral<"replaceNoteBody">;
146
+ body: z.ZodString;
147
+ }, z.core.$strict>, z.ZodObject<{
148
+ kind: z.ZodLiteral<"patchNoteBody">;
149
+ patch: z.ZodString;
150
+ }, z.core.$strict>, z.ZodObject<{
151
+ kind: z.ZodLiteral<"appendNoteBody">;
152
+ body: z.ZodString;
153
+ }, z.core.$strict>, z.ZodObject<{
154
+ kind: z.ZodLiteral<"prependNoteBody">;
155
+ body: z.ZodString;
156
+ }, z.core.$strict>, z.ZodObject<{
157
+ kind: z.ZodLiteral<"moveNote">;
158
+ path: z.ZodString;
159
+ }, z.core.$strict>, z.ZodObject<{
160
+ kind: z.ZodLiteral<"setNoteMetadata">;
161
+ title: z.ZodOptional<z.ZodString>;
162
+ labels: z.ZodOptional<z.ZodArray<z.ZodString>>;
163
+ noteKind: z.ZodOptional<z.ZodNullable<z.ZodString>>;
164
+ }, z.core.$strict>, z.ZodObject<{
165
+ kind: z.ZodLiteral<"setLinks">;
166
+ links: z.ZodArray<z.ZodObject<{
167
+ targetType: z.ZodEnum<{
168
+ message: "message";
169
+ note: "note";
170
+ thread: "thread";
171
+ }>;
172
+ targetId: z.ZodString;
173
+ }, z.core.$strict>>;
174
+ }, z.core.$strict>, z.ZodObject<{
175
+ kind: z.ZodLiteral<"archiveNote">;
176
+ }, z.core.$strict>, z.ZodObject<{
177
+ kind: z.ZodLiteral<"deleteNote">;
178
+ }, z.core.$strict>, z.ZodObject<{
179
+ kind: z.ZodLiteral<"activateNote">;
180
+ }, z.core.$strict>, z.ZodObject<{
181
+ kind: z.ZodLiteral<"replaceNoteText">;
182
+ find: z.ZodString;
183
+ replace: z.ZodString;
184
+ expectedOccurrences: z.ZodNumber;
185
+ }, z.core.$strict>, z.ZodObject<{
186
+ kind: z.ZodLiteral<"upsertNoteSection">;
187
+ headingPath: z.ZodArray<z.ZodString>;
188
+ body: z.ZodString;
189
+ occurrence: z.ZodOptional<z.ZodNumber>;
190
+ createIfMissing: z.ZodDefault<z.ZodBoolean>;
191
+ }, z.core.$strict>, z.ZodObject<{
192
+ kind: z.ZodLiteral<"batchNote">;
193
+ mutations: z.ZodArray<z.ZodDiscriminatedUnion<readonly [z.ZodObject<{
194
+ kind: z.ZodLiteral<"replaceNoteBody">;
195
+ body: z.ZodString;
196
+ }, z.core.$strict>, z.ZodObject<{
197
+ kind: z.ZodLiteral<"patchNoteBody">;
198
+ patch: z.ZodString;
199
+ }, z.core.$strict>, z.ZodObject<{
200
+ kind: z.ZodLiteral<"appendNoteBody">;
201
+ body: z.ZodString;
202
+ }, z.core.$strict>, z.ZodObject<{
203
+ kind: z.ZodLiteral<"prependNoteBody">;
204
+ body: z.ZodString;
205
+ }, z.core.$strict>, z.ZodObject<{
206
+ kind: z.ZodLiteral<"moveNote">;
207
+ path: z.ZodString;
208
+ }, z.core.$strict>, z.ZodObject<{
209
+ kind: z.ZodLiteral<"setNoteMetadata">;
210
+ title: z.ZodOptional<z.ZodString>;
211
+ labels: z.ZodOptional<z.ZodArray<z.ZodString>>;
212
+ noteKind: z.ZodOptional<z.ZodNullable<z.ZodString>>;
213
+ }, z.core.$strict>, z.ZodObject<{
214
+ kind: z.ZodLiteral<"setLinks">;
215
+ links: z.ZodArray<z.ZodObject<{
216
+ targetType: z.ZodEnum<{
217
+ message: "message";
218
+ note: "note";
219
+ thread: "thread";
220
+ }>;
221
+ targetId: z.ZodString;
222
+ }, z.core.$strict>>;
223
+ }, z.core.$strict>, z.ZodObject<{
224
+ kind: z.ZodLiteral<"archiveNote">;
225
+ }, z.core.$strict>, z.ZodObject<{
226
+ kind: z.ZodLiteral<"deleteNote">;
227
+ }, z.core.$strict>, z.ZodObject<{
228
+ kind: z.ZodLiteral<"activateNote">;
229
+ }, z.core.$strict>, z.ZodObject<{
230
+ kind: z.ZodLiteral<"replaceNoteText">;
231
+ find: z.ZodString;
232
+ replace: z.ZodString;
233
+ expectedOccurrences: z.ZodNumber;
234
+ }, z.core.$strict>, z.ZodObject<{
235
+ kind: z.ZodLiteral<"upsertNoteSection">;
236
+ headingPath: z.ZodArray<z.ZodString>;
237
+ body: z.ZodString;
238
+ occurrence: z.ZodOptional<z.ZodNumber>;
239
+ createIfMissing: z.ZodDefault<z.ZodBoolean>;
240
+ }, z.core.$strict>], "kind">>;
241
+ }, z.core.$strict>], "kind">;
242
+ }, z.core.$strict>;
243
+ listHistory: z.ZodObject<{
244
+ floor: z.ZodObject<{
245
+ id: z.ZodString;
246
+ fencingToken: z.ZodString;
247
+ }, z.core.$strict>;
248
+ offset: z.ZodDefault<z.ZodNumber>;
249
+ limit: z.ZodDefault<z.ZodNumber>;
250
+ }, z.core.$strict>;
251
+ readRevision: z.ZodObject<{
252
+ floor: z.ZodObject<{
253
+ id: z.ZodString;
254
+ fencingToken: z.ZodString;
255
+ }, z.core.$strict>;
256
+ revision: z.ZodString;
257
+ cursor: z.ZodOptional<z.ZodString>;
258
+ }, z.core.$strict>;
259
+ diffRevision: z.ZodObject<{
260
+ floor: z.ZodObject<{
261
+ id: z.ZodString;
262
+ fencingToken: z.ZodString;
263
+ }, z.core.$strict>;
264
+ revision: z.ZodString;
265
+ }, z.core.$strict>;
266
+ previewRestore: z.ZodObject<{
267
+ floor: z.ZodObject<{
268
+ id: z.ZodString;
269
+ fencingToken: z.ZodString;
270
+ }, z.core.$strict>;
271
+ revision: z.ZodString;
272
+ }, z.core.$strict>;
273
+ restoreRevision: z.ZodObject<{
274
+ floor: z.ZodObject<{
275
+ id: z.ZodString;
276
+ fencingToken: z.ZodString;
277
+ }, z.core.$strict>;
278
+ previewToken: z.ZodString;
279
+ }, z.core.$strict>;
280
+ getNoteOutline: z.ZodObject<{
281
+ floor: z.ZodObject<{
282
+ id: z.ZodString;
283
+ fencingToken: z.ZodString;
284
+ }, z.core.$strict>;
285
+ }, z.core.$strict>;
286
+ findInNote: z.ZodObject<{
287
+ floor: z.ZodObject<{
288
+ id: z.ZodString;
289
+ fencingToken: z.ZodString;
290
+ }, z.core.$strict>;
291
+ query: z.ZodString;
292
+ mode: z.ZodDefault<z.ZodEnum<{
293
+ literal: "literal";
294
+ regex: "regex";
295
+ }>>;
296
+ limit: z.ZodDefault<z.ZodNumber>;
297
+ }, z.core.$strict>;
298
+ inspectSnapshot: z.ZodObject<{
299
+ floor: z.ZodObject<{
300
+ id: z.ZodString;
301
+ fencingToken: z.ZodString;
302
+ }, z.core.$strict>;
303
+ }, z.core.$strict>;
304
+ searchProjectNotes: z.ZodObject<{
305
+ floor: z.ZodObject<{
306
+ id: z.ZodString;
307
+ fencingToken: z.ZodString;
308
+ }, z.core.$strict>;
309
+ query: z.ZodString;
310
+ states: z.ZodDefault<z.ZodArray<z.ZodEnum<{
311
+ active: "active";
312
+ archived: "archived";
313
+ deleted: "deleted";
314
+ }>>>;
315
+ limit: z.ZodDefault<z.ZodNumber>;
316
+ cursor: z.ZodOptional<z.ZodString>;
317
+ }, z.core.$strict>;
318
+ searchProjectNoteHistory: z.ZodObject<{
319
+ floor: z.ZodObject<{
320
+ id: z.ZodString;
321
+ fencingToken: z.ZodString;
322
+ }, z.core.$strict>;
323
+ query: z.ZodString;
324
+ noteId: z.ZodOptional<z.ZodString>;
325
+ states: z.ZodDefault<z.ZodArray<z.ZodEnum<{
326
+ active: "active";
327
+ archived: "archived";
328
+ deleted: "deleted";
329
+ }>>>;
330
+ limit: z.ZodDefault<z.ZodNumber>;
331
+ cursor: z.ZodOptional<z.ZodString>;
332
+ }, z.core.$strict>;
333
+ exportSnapshot: z.ZodObject<{
334
+ floor: z.ZodObject<{
335
+ id: z.ZodString;
336
+ fencingToken: z.ZodString;
337
+ }, z.core.$strict>;
338
+ }, z.core.$strict>;
339
+ listSnapshotHistory: z.ZodObject<{
340
+ floor: z.ZodObject<{
341
+ id: z.ZodString;
342
+ fencingToken: z.ZodString;
343
+ }, z.core.$strict>;
344
+ limit: z.ZodDefault<z.ZodNumber>;
345
+ cursor: z.ZodOptional<z.ZodString>;
346
+ }, z.core.$strict>;
347
+ previewSnapshotRestore: z.ZodObject<{
348
+ floor: z.ZodObject<{
349
+ id: z.ZodString;
350
+ fencingToken: z.ZodString;
351
+ }, z.core.$strict>;
352
+ targetCommit: z.ZodString;
353
+ limit: z.ZodDefault<z.ZodNumber>;
354
+ cursor: z.ZodOptional<z.ZodString>;
355
+ }, z.core.$strict>;
356
+ restoreSnapshot: z.ZodObject<{
357
+ floor: z.ZodObject<{
358
+ id: z.ZodString;
359
+ fencingToken: z.ZodString;
360
+ }, z.core.$strict>;
361
+ previewToken: z.ZodString;
362
+ }, z.core.$strict>;
363
+ };
364
+ export type ToolName = keyof typeof schemas;
365
+ export declare const descriptions: Record<ToolName, string>;
package/dist/api.js ADDED
@@ -0,0 +1,113 @@
1
+ import { z } from 'zod';
2
+ const id = z.string().min(1).max(200);
3
+ const counter = z.string().regex(/^(0|[1-9][0-9]{0,19})$/);
4
+ export const nameSchema = z.string().regex(/^[A-Za-z][A-Za-z0-9_-]{0,63}$/);
5
+ const floor = z.object({ id, fencingToken: counter }).strict();
6
+ const withFloor = { floor };
7
+ const title = z.string().trim().min(1).max(200);
8
+ const threadDescription = z.string().max(2000);
9
+ const threadState = z.enum(['active', 'archived', 'deleted']);
10
+ export const notePathSchema = z.string().max(240).regex(/^[a-z0-9](?:[a-z0-9._-]{0,62}[a-z0-9])?(?:\/[a-z0-9](?:[a-z0-9._-]{0,62}[a-z0-9])?){0,15}$/);
11
+ const noteToken = z.string().regex(/^[a-z][a-z0-9_-]{0,31}$/);
12
+ const noteBody = z.string().refine(value => Buffer.byteLength(value, 'utf8') <= 256 * 1024, 'Note body exceeds 256 KiB.');
13
+ const links = z.array(z.object({ targetType: z.enum(['note', 'thread', 'message']), targetId: id }).strict()).max(64);
14
+ const noteMutationBase = [
15
+ z.object({ kind: z.literal('replaceNoteBody'), body: noteBody }).strict(),
16
+ z.object({ kind: z.literal('patchNoteBody'), patch: z.string().min(1).max(512 * 1024) }).strict(),
17
+ z.object({ kind: z.literal('appendNoteBody'), body: z.string().min(1).max(256 * 1024) }).strict(),
18
+ z.object({ kind: z.literal('prependNoteBody'), body: z.string().min(1).max(256 * 1024) }).strict(),
19
+ z.object({ kind: z.literal('moveNote'), path: notePathSchema }).strict(),
20
+ z.object({ kind: z.literal('setNoteMetadata'), title: title.optional(), labels: z.array(noteToken).max(16).optional(), noteKind: noteToken.nullable().optional() }).strict(),
21
+ z.object({ kind: z.literal('setLinks'), links }).strict(),
22
+ z.object({ kind: z.literal('archiveNote') }).strict(),
23
+ z.object({ kind: z.literal('deleteNote') }).strict(),
24
+ z.object({ kind: z.literal('activateNote') }).strict(),
25
+ z.object({ kind: z.literal('replaceNoteText'), find: z.string().min(1), replace: z.string(), expectedOccurrences: z.number().int().min(0).max(10_000) }).strict(),
26
+ z.object({ kind: z.literal('upsertNoteSection'), headingPath: z.array(z.string().trim().min(1).max(200)).min(1).max(6), body: noteBody, occurrence: z.number().int().min(1).optional(), createIfMissing: z.boolean().default(false) }).strict(),
27
+ ];
28
+ const mutation = z.discriminatedUnion('kind', [
29
+ z.object({ kind: z.literal('appendMessage'), body: z.string().min(1).max(16_000) }).strict(),
30
+ z.object({ kind: z.literal('renameThread'), title }).strict(),
31
+ z.object({ kind: z.literal('setThreadDescription'), description: threadDescription }).strict(),
32
+ z.object({ kind: z.literal('archiveThread') }).strict(),
33
+ z.object({ kind: z.literal('activateThread') }).strict(),
34
+ z.object({ kind: z.literal('deleteThread') }).strict(),
35
+ z.object({ kind: z.literal('retractMessage'), messageId: id }).strict(),
36
+ z.object({ kind: z.literal('reinstateMessage'), messageId: id }).strict(),
37
+ ...noteMutationBase,
38
+ z.object({ kind: z.literal('batchNote'), mutations: z.array(z.discriminatedUnion('kind', noteMutationBase)).min(1).max(32) }).strict(),
39
+ ]);
40
+ const target = z.discriminatedUnion('type', [
41
+ z.object({ type: z.literal('thread'), id }).strict(),
42
+ z.object({ type: z.literal('note'), id }).strict(),
43
+ z.object({ type: z.literal('project'), purpose: z.enum(['snapshot', 'export', 'search', 'restore']) }).strict(),
44
+ ]);
45
+ export const schemas = {
46
+ getSession: z.object({}).strict(),
47
+ setAgentName: z.object({ name: nameSchema }).strict(),
48
+ listAgents: z.object({}).strict(),
49
+ createThread: z.object({ title, description: threadDescription.default('') }).strict(),
50
+ listThreads: z.object({ state: threadState.default('active'), creatorIdentityId: id.optional(), titlePrefix: z.string().max(200).optional(), limit: z.number().int().min(1).max(100).default(100), cursor: z.string().max(500).optional() }).strict(),
51
+ getThread: z.object({ threadId: id }).strict(),
52
+ searchThreads: z.object({ query: z.string().trim().min(1).max(200), state: threadState.default('active'), limit: z.number().int().min(1).max(100).default(100) }).strict(),
53
+ createNote: z.object({ path: notePathSchema, title, body: noteBody.default(''), labels: z.array(noteToken).max(16).default([]), noteKind: noteToken.nullable().default(null), links: links.default([]) }).strict(),
54
+ listNotes: z.object({ pathPrefix: z.string().max(240).optional(), label: noteToken.optional(), noteKind: noteToken.optional(), state: z.enum(['active', 'archived', 'deleted']).default('active'), creatorIdentityId: id.optional(), limit: z.number().int().min(1).max(100).default(100), cursor: z.string().max(500).optional() }).strict(),
55
+ searchNotes: z.object({ query: z.string().trim().min(1).max(200), state: z.enum(['active', 'archived', 'deleted']).default('active'), limit: z.number().int().min(1).max(100).default(100) }).strict(),
56
+ requestFloor: z.object({ target }).strict(),
57
+ getFloorRequest: z.object({ requestId: id }).strict(),
58
+ waitForFloor: z.object({ requestId: id, timeoutMs: z.number().int().min(0).max(20_000).default(20_000) }).strict(),
59
+ cancelFloorRequest: z.object({ requestId: id }).strict(),
60
+ claimFloor: z.object({ offerId: id }).strict(),
61
+ readFloor: z.object({ ...withFloor, cursor: z.string().max(500).optional() }).strict(),
62
+ releaseFloor: z.object(withFloor).strict(),
63
+ commitFloor: z.object({ ...withFloor, baseRevision: counter, mutation }).strict(),
64
+ listHistory: z.object({ ...withFloor, offset: z.number().int().min(0).default(0), limit: z.number().int().min(1).max(100).default(50) }).strict(),
65
+ readRevision: z.object({ ...withFloor, revision: counter, cursor: z.string().max(500).optional() }).strict(),
66
+ diffRevision: z.object({ ...withFloor, revision: counter }).strict(),
67
+ previewRestore: z.object({ ...withFloor, revision: counter }).strict(),
68
+ restoreRevision: z.object({ ...withFloor, previewToken: z.string().min(1).max(4096) }).strict(),
69
+ getNoteOutline: z.object(withFloor).strict(),
70
+ findInNote: z.object({ ...withFloor, query: z.string().min(1).max(1024), mode: z.enum(['literal', 'regex']).default('literal'), limit: z.number().int().min(1).max(100).default(100) }).strict(),
71
+ inspectSnapshot: z.object(withFloor).strict(),
72
+ searchProjectNotes: z.object({ ...withFloor, query: z.string().min(1).max(1024), states: z.array(z.enum(['active', 'archived', 'deleted'])).min(1).max(3).default(['active']), limit: z.number().int().min(1).max(100).default(100), cursor: z.string().max(4096).optional() }).strict(),
73
+ searchProjectNoteHistory: z.object({ ...withFloor, query: z.string().min(1).max(1024), noteId: id.optional(), states: z.array(z.enum(['active', 'archived', 'deleted'])).min(1).max(3).default(['active', 'archived', 'deleted']), limit: z.number().int().min(1).max(100).default(100), cursor: z.string().max(4096).optional() }).strict(),
74
+ exportSnapshot: z.object(withFloor).strict(),
75
+ listSnapshotHistory: z.object({ ...withFloor, limit: z.number().int().min(1).max(100).default(50), cursor: z.string().max(4096).optional() }).strict(),
76
+ previewSnapshotRestore: z.object({ ...withFloor, targetCommit: z.string().min(8).max(128), limit: z.number().int().min(1).max(100).default(100), cursor: z.string().max(4096).optional() }).strict(),
77
+ restoreSnapshot: z.object({ ...withFloor, previewToken: z.string().min(1).max(4096) }).strict(),
78
+ };
79
+ export const descriptions = {
80
+ getSession: 'Get the current repository-scoped Bassfish session and pending requests.',
81
+ setAgentName: 'Choose or reclaim an inactive repository-scoped agent identity.',
82
+ listAgents: 'List repository-scoped agent identities and current liveness.',
83
+ createThread: 'Create a thread in one semantic Dolt commit.',
84
+ listThreads: 'List thread metadata, including descriptions, without message bodies.',
85
+ getThread: 'Get one thread\'s metadata, including its description, without message bodies.',
86
+ searchThreads: 'Search thread titles and descriptions without message bodies.',
87
+ createNote: 'Create a uniquely addressed note; never upserts.',
88
+ listNotes: 'List note metadata without bodies or snippets.',
89
+ searchNotes: 'Search note metadata without bodies or snippets.',
90
+ requestFloor: 'Request FIFO access to a thread, note, or drained project operation.',
91
+ getFloorRequest: 'Inspect one durable floor request without retrying it.',
92
+ waitForFloor: 'Wait briefly for an existing request while preserving FIFO position.',
93
+ cancelFloorRequest: 'Cancel a queued request or unclaimed offer.',
94
+ claimFloor: 'Claim an offer, read a fresh snapshot, and start the hard lease.',
95
+ readFloor: 'Read the next cursor-bounded page from the claimed snapshot.',
96
+ releaseFloor: 'Release a held floor without writing.',
97
+ commitFloor: 'Commit one revision-bound mutation and release; never retries.',
98
+ listHistory: 'List semantic operations for the held resource.',
99
+ readRevision: 'Read a historical revision under the current floor.',
100
+ diffRevision: 'Compare a historical revision with current held content.',
101
+ previewRestore: 'Bind a historical restore preview to the current floor.',
102
+ restoreRevision: 'Apply a validated preview as a new revision and release.',
103
+ getNoteOutline: 'Return Markdown headings and line ranges for the held note.',
104
+ findInNote: 'Return bounded literal or RE2-compatible matches in the held note.',
105
+ inspectSnapshot: 'Inspect the Dolt snapshot pinned by a project floor.',
106
+ searchProjectNotes: 'Search note bodies under a search project floor.',
107
+ searchProjectNoteHistory: 'Search all semantic note revisions under a search project floor.',
108
+ exportSnapshot: 'Write a deterministic ZIP from an export project floor.',
109
+ listSnapshotHistory: 'List semantic project commits under a restore project floor.',
110
+ previewSnapshotRestore: 'Preview an exact visible-state project restore and bind it to this floor.',
111
+ restoreSnapshot: 'Apply a validated project restore preview in one Dolt commit and release.',
112
+ };
113
+ //# sourceMappingURL=api.js.map