@stringsync/splates 0.0.0-stage → 0.0.45

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 (251) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +308 -2
  3. package/acp-extensions.d.ts +82 -0
  4. package/add.d.ts +53 -0
  5. package/adherence.d.ts +49 -0
  6. package/age.d.ts +2 -0
  7. package/agent-connection.d.ts +171 -0
  8. package/agent-errors.d.ts +2 -0
  9. package/agent-process.d.ts +65 -0
  10. package/agent-stream.d.ts +91 -0
  11. package/agents.d.ts +15 -0
  12. package/artifact-room.d.ts +47 -0
  13. package/artifact-viewers.d.ts +6 -0
  14. package/artifact.d.ts +30 -0
  15. package/artifacts.d.ts +161 -0
  16. package/asked.d.ts +146 -0
  17. package/asked.js +7 -0
  18. package/assumed.d.ts +34 -0
  19. package/attach.d.ts +30 -0
  20. package/attachments.d.ts +43 -0
  21. package/baselines.d.ts +55 -0
  22. package/claim.d.ts +17 -0
  23. package/cloudflare-api.d.ts +25 -0
  24. package/cloudflare-error.d.ts +5 -0
  25. package/cloudflared-tunnel-provider.d.ts +27 -0
  26. package/codex-limits.d.ts +19 -0
  27. package/compaction.d.ts +17 -0
  28. package/config-source.d.ts +13 -0
  29. package/config.d.ts +98 -0
  30. package/config.js +7 -0
  31. package/conversation-archive.d.ts +6 -0
  32. package/conversation-background.d.ts +21 -0
  33. package/conversation-choice.d.ts +4 -0
  34. package/conversation-files.d.ts +51 -0
  35. package/conversation-given.d.ts +8 -0
  36. package/conversation-host.d.ts +102 -0
  37. package/conversation-listing.d.ts +15 -0
  38. package/conversation-log.d.ts +301 -0
  39. package/conversation-messages.d.ts +18 -0
  40. package/conversation-name.d.ts +28 -0
  41. package/conversation-options.d.ts +73 -0
  42. package/conversation-reference.d.ts +2 -0
  43. package/conversation-state.d.ts +472 -0
  44. package/conversation-turns.d.ts +115 -0
  45. package/conversation.d.ts +209 -0
  46. package/conversations.d.ts +140 -0
  47. package/coordinator-state.d.ts +28 -0
  48. package/creds.d.ts +123 -0
  49. package/darwin-temperature.d.ts +7 -0
  50. package/decided.d.ts +18 -0
  51. package/demo.d.ts +29 -0
  52. package/dev/api.d.ts +209 -0
  53. package/dev/assets.d.ts +24 -0
  54. package/dev/conversation-address.d.ts +47 -0
  55. package/dev/conversation-feed.d.ts +166 -0
  56. package/dev/live-stream.d.ts +29 -0
  57. package/dev/worker.d.ts +33 -0
  58. package/dev-access.d.ts +61 -0
  59. package/dev-artifacts.d.ts +22 -0
  60. package/dev-budgets.d.ts +18 -0
  61. package/dev-conversation-events.d.ts +39 -0
  62. package/dev-conversation-routes.d.ts +90 -0
  63. package/dev-creds.d.ts +17 -0
  64. package/dev-dictation-connection.d.ts +18 -0
  65. package/dev-dictation.d.ts +17 -0
  66. package/dev-http.d.ts +76 -0
  67. package/dev-open.d.ts +15 -0
  68. package/dev-options.d.ts +133 -0
  69. package/dev-outcomes.d.ts +21 -0
  70. package/dev-pages.d.ts +16 -0
  71. package/dev-picker.d.ts +57 -0
  72. package/dev-port-socket.d.ts +26 -0
  73. package/dev-ports.d.ts +11 -0
  74. package/dev-project-watch.d.ts +44 -0
  75. package/dev-project.d.ts +168 -0
  76. package/dev-push.d.ts +59 -0
  77. package/dev-restart.d.ts +141 -0
  78. package/dev-servers.d.ts +30 -0
  79. package/dev-setup-native.d.ts +23 -0
  80. package/dev-setup-opencode.d.ts +29 -0
  81. package/dev-setup.d.ts +16 -0
  82. package/dev-shell.d.ts +70 -0
  83. package/dev-slot.d.ts +28 -0
  84. package/dev-sockets.d.ts +13 -0
  85. package/dev-task-ports.d.ts +73 -0
  86. package/dev-tasks.d.ts +20 -0
  87. package/dev-terminal-connection.d.ts +19 -0
  88. package/dev-terminal.d.ts +42 -0
  89. package/dev-todos.d.ts +35 -0
  90. package/dev-transcriber.d.ts +15 -0
  91. package/dev-tunnel.d.ts +38 -0
  92. package/dev-versions.d.ts +53 -0
  93. package/dev-workers.d.ts +55 -0
  94. package/dev.d.ts +24 -0
  95. package/diff.d.ts +29 -0
  96. package/dispatched.d.ts +16 -0
  97. package/editors.d.ts +22 -0
  98. package/escalate.d.ts +27 -0
  99. package/events.d.ts +311 -0
  100. package/everywhere.d.ts +41 -0
  101. package/exhibit.d.ts +21 -0
  102. package/exit.d.ts +54 -0
  103. package/fact-todos.d.ts +18 -0
  104. package/fake-agent.d.ts +107 -0
  105. package/fake-agent.js +284 -0
  106. package/finding-facts.d.ts +38 -0
  107. package/findings.d.ts +84 -0
  108. package/fold.d.ts +43 -0
  109. package/follow.d.ts +41 -0
  110. package/format.d.ts +68 -0
  111. package/git.d.ts +112 -0
  112. package/handed-out.d.ts +79 -0
  113. package/handoff.d.ts +23 -0
  114. package/heavy-run.d.ts +12 -0
  115. package/heavy.d.ts +28 -0
  116. package/heavy.js +16 -0
  117. package/held.d.ts +22 -0
  118. package/index-0tfvy823.js +272 -0
  119. package/index-43pq33n4.js +157 -0
  120. package/index-4776671w.js +698 -0
  121. package/index-d4hjrzaq.js +464 -0
  122. package/index-gcfq7awr.js +740 -0
  123. package/index-k73tsw5g.js +101 -0
  124. package/index-kaa44k7q.js +59 -0
  125. package/index-vcv9m93e.js +1265 -0
  126. package/index-xmfmy729.js +249 -0
  127. package/index.d.ts +2 -0
  128. package/index.js +26928 -0
  129. package/init.d.ts +28 -0
  130. package/journal.d.ts +57 -0
  131. package/landed.d.ts +14 -0
  132. package/lane-todos.d.ts +44 -0
  133. package/lane.d.ts +55 -0
  134. package/lanes-from-tags.d.ts +17 -0
  135. package/lanes.d.ts +96 -0
  136. package/legacy-names.d.ts +70 -0
  137. package/legacy-ps.d.ts +31 -0
  138. package/limits.d.ts +32 -0
  139. package/list.d.ts +18 -0
  140. package/load-config.d.ts +44 -0
  141. package/log.d.ts +14 -0
  142. package/machine.d.ts +42 -0
  143. package/merge.d.ts +35 -0
  144. package/migrate-config.d.ts +31 -0
  145. package/models.d.ts +24 -0
  146. package/needs.d.ts +115 -0
  147. package/notices.d.ts +39 -0
  148. package/offered.d.ts +39 -0
  149. package/opencode-usage.d.ts +37 -0
  150. package/outcomes.d.ts +114 -0
  151. package/package.json +74 -5
  152. package/path.d.ts +13 -0
  153. package/plan.d.ts +236 -0
  154. package/port-forward.d.ts +22 -0
  155. package/port-pipe.d.ts +36 -0
  156. package/ports-list.d.ts +19 -0
  157. package/probe-runtime.d.ts +5 -0
  158. package/probe-runtime.js +13 -0
  159. package/project-reaches.d.ts +23 -0
  160. package/projects.d.ts +136 -0
  161. package/prompts.d.ts +128 -0
  162. package/pty.d.ts +39 -0
  163. package/pulse.d.ts +8 -0
  164. package/recommend.d.ts +31 -0
  165. package/release.d.ts +41 -0
  166. package/remote-process.d.ts +26 -0
  167. package/remote-pty.d.ts +29 -0
  168. package/remote-worker.d.ts +77 -0
  169. package/remove.d.ts +31 -0
  170. package/repository.d.ts +91 -0
  171. package/retry.d.ts +34 -0
  172. package/roster.d.ts +63 -0
  173. package/saved-ports-host.d.ts +25 -0
  174. package/saved-tunnel.d.ts +44 -0
  175. package/server-worker-socket.d.ts +21 -0
  176. package/setup-areas.d.ts +7 -0
  177. package/setup-opencode-model-error.d.ts +3 -0
  178. package/setup-opencode-models.d.ts +54 -0
  179. package/setup-opencode-recipe.d.ts +26 -0
  180. package/setup-opencode.d.ts +46 -0
  181. package/setup.d.ts +102 -0
  182. package/shared-browser.d.ts +50 -0
  183. package/shell.d.ts +17 -0
  184. package/show.d.ts +106 -0
  185. package/skill-checks.d.ts +73 -0
  186. package/skill-checks.js +10 -0
  187. package/skills.d.ts +16 -0
  188. package/slot-tunnel.d.ts +27 -0
  189. package/slots.d.ts +135 -0
  190. package/snapshot.d.ts +75 -0
  191. package/splates-artifact.d.ts +3 -0
  192. package/splates-creds.d.ts +3 -0
  193. package/splates-dev.d.ts +22 -0
  194. package/splates-flags.d.ts +34 -0
  195. package/splates-lane.d.ts +3 -0
  196. package/splates-projects.d.ts +3 -0
  197. package/splates-setup.d.ts +17 -0
  198. package/splates-slots.d.ts +3 -0
  199. package/splates-todo.d.ts +3 -0
  200. package/splates-tunnel.d.ts +3 -0
  201. package/splates-worker.d.ts +3 -0
  202. package/splates.d.ts +28 -0
  203. package/stats.d.ts +186 -0
  204. package/supervise.d.ts +50 -0
  205. package/system-changes.d.ts +67 -0
  206. package/system.d.ts +28 -0
  207. package/systems.d.ts +119 -0
  208. package/systems.js +21 -0
  209. package/table.d.ts +5 -0
  210. package/task-log.d.ts +35 -0
  211. package/task-ports.d.ts +25 -0
  212. package/tell.d.ts +47 -0
  213. package/todo-edit.d.ts +60 -0
  214. package/todo-file.d.ts +6 -0
  215. package/todo-lanes.d.ts +82 -0
  216. package/todo-list.d.ts +26 -0
  217. package/todo-take.d.ts +27 -0
  218. package/todo.d.ts +146 -0
  219. package/todos.d.ts +157 -0
  220. package/tool-calls.d.ts +18 -0
  221. package/tunnel-provider.d.ts +37 -0
  222. package/tunnel-provider.js +0 -0
  223. package/tunnel-remove.d.ts +28 -0
  224. package/tunnel-setup.d.ts +104 -0
  225. package/unix-worker-listener.d.ts +23 -0
  226. package/unix-worker-socket.d.ts +30 -0
  227. package/update.d.ts +29 -0
  228. package/update.js +10 -0
  229. package/vocabulary.d.ts +9 -0
  230. package/wait.d.ts +36 -0
  231. package/watch.d.ts +46 -0
  232. package/watched.d.ts +43 -0
  233. package/websocket-worker-socket.d.ts +18 -0
  234. package/worker-call-host.d.ts +51 -0
  235. package/worker-channel.d.ts +83 -0
  236. package/worker-connection.d.ts +24 -0
  237. package/worker-daemon.d.ts +64 -0
  238. package/worker-git.d.ts +18 -0
  239. package/worker-list.d.ts +49 -0
  240. package/worker-machine.d.ts +34 -0
  241. package/worker-port-host.d.ts +21 -0
  242. package/worker-process-host.d.ts +29 -0
  243. package/worker-protocol.d.ts +104 -0
  244. package/worker-pty-host.d.ts +34 -0
  245. package/worker-registry.d.ts +68 -0
  246. package/worker-replay.d.ts +25 -0
  247. package/worker-run.d.ts +20 -0
  248. package/worker-session.d.ts +189 -0
  249. package/worker-socket.d.ts +15 -0
  250. package/worktree-service.d.ts +113 -0
  251. package/worktree.d.ts +232 -0
@@ -0,0 +1,82 @@
1
+ import type { Fs } from "webappwiz/system";
2
+ import { type LaneRecord } from "./lanes.js";
3
+ import type { TodoState } from "./todo.js";
4
+ import type { Todos } from "./todos.js";
5
+ /**
6
+ * The lanes of a `Todos`: their records in `lanes` beside the todos, and every
7
+ * change that moves todos between them, each made under the todos' lock.
8
+ */
9
+ export declare class TodoLanes {
10
+ private readonly todos;
11
+ private readonly fs;
12
+ constructor(todos: Todos, fs: Fs);
13
+ /**
14
+ * Moves every todo in lane `from` to the bottom of lane `into`, in the
15
+ * order they had, and the lane `from` is gone.
16
+ */
17
+ joinLanes(from: number, into: number): Promise<void>;
18
+ /** Starts an empty lane called `name`, after the others. */
19
+ addLane(name: string): Promise<LaneRecord>;
20
+ /** Calls lane `id` by another name. */
21
+ renameLane(id: number, name: string): Promise<LaneRecord>;
22
+ /**
23
+ * Puts lane `id` at `position` among the lanes, 1 the first column, past
24
+ * the last meaning the last; the others close up around it.
25
+ */
26
+ moveLane(id: number, position: number): Promise<LaneRecord[]>;
27
+ /** Removes lane `id`, putting its todos back in none, untriaged. */
28
+ dropLane(id: number): Promise<void>;
29
+ /**
30
+ * @internal Removes each lane in `ids` that no todo is in any more: a lane
31
+ * whose last todo merged is done. One emptied by hand stays, to be filled.
32
+ */
33
+ endLanes(ids: number[]): Promise<void>;
34
+ /**
35
+ * Moves todos saved while splates kept tags into lanes, one lane a tag,
36
+ * and drops their tags, which splates refuses to read until then. A todo
37
+ * in no lane goes to the lane of its tag the most todos share, at the
38
+ * bottom, in list order, below anything in that lane blocking it; a lane
39
+ * already called that takes them. Gives back each lane it filled, with
40
+ * the todos it put there, in board order; none once no todo has tags.
41
+ */
42
+ moveTagsToLanes(): Promise<{
43
+ lane: LaneRecord;
44
+ todos: number[];
45
+ }[]>;
46
+ /**
47
+ * @internal The lane `lane` names: null for none, one there is, or for
48
+ * `"new"` one started for `todos`, called `name` or named after them. Call
49
+ * it under the lock.
50
+ */
51
+ laneId(lane: number | "new" | null, states: TodoState[], todos: TodoState[], name?: string): Promise<number | null>;
52
+ /**
53
+ * Starts a lane for `todos` after the others, called `name`, or aptly
54
+ * named without one. Call it under the lock.
55
+ */
56
+ private newLane;
57
+ /**
58
+ * A lane id never handed out before, so a lane's number never comes back
59
+ * meaning another. Call it under the lock.
60
+ */
61
+ private nextLaneId;
62
+ /**
63
+ * @internal The lanes as stored, and after them any lane a todo is in that
64
+ * has no record. A file that will not parse reads as none.
65
+ */
66
+ records(states: TodoState[]): Promise<LaneRecord[]>;
67
+ /**
68
+ * The name of every lane there has been: those on the board, and after
69
+ * them each that is gone as it was last called, so an orchestrator whose
70
+ * lanes are done still goes by their names.
71
+ */
72
+ names(states: TodoState[]): Promise<LaneRecord[]>;
73
+ /** The lane records in `file`, none when it is missing or will not parse. */
74
+ private read;
75
+ /**
76
+ * Writes the lanes, in board order, keeping the name of each lane they
77
+ * drop in `ended-lanes`. Call it under the lock.
78
+ */
79
+ private writeLanes;
80
+ /** Writes `records` to `file` whole, so a reader never sees half of it. */
81
+ private write;
82
+ }
package/todo-list.d.ts ADDED
@@ -0,0 +1,26 @@
1
+ import { type Logger } from "webappwiz/log";
2
+ import type { Todos } from "./todos.js";
3
+ export interface TodoListOptions {
4
+ /** Print the todos as JSON instead of a table. */
5
+ json?: boolean;
6
+ /** Only those no task has taken: the ones free to pick up. */
7
+ open?: boolean;
8
+ /**
9
+ * Only those free to start now: nobody has taken them, and nothing they
10
+ * is blocked by is still open.
11
+ */
12
+ ready?: boolean;
13
+ }
14
+ export declare function todoList({ todos, log }: {
15
+ todos: Todos;
16
+ log: Logger;
17
+ }, { json, open, ready }?: TodoListOptions): Promise<void>;
18
+ export interface TodoShowOptions {
19
+ /** Print the todo as JSON instead of prose. */
20
+ json?: boolean;
21
+ }
22
+ /** One todo in full: what `todo list` shows of it, its files, and its detail. */
23
+ export declare function todoShow({ todos, log }: {
24
+ todos: Todos;
25
+ log: Logger;
26
+ }, id: number, { json }?: TodoShowOptions): Promise<void>;
package/todo-take.d.ts ADDED
@@ -0,0 +1,27 @@
1
+ import { type Logger } from "webappwiz/log";
2
+ import type { Todo } from "./todo.js";
3
+ import type { Todos } from "./todos.js";
4
+ /**
5
+ * Takes up todos for `task` after it started, as when one turns out to be
6
+ * part of the work. Every id is checked before any is taken, so one that is
7
+ * gone or another task's refuses them all.
8
+ */
9
+ export declare function todoTake({ todos, log }: {
10
+ todos: Todos;
11
+ log: Logger;
12
+ }, ids: number[], task: string | null): Promise<Todo[]>;
13
+ /**
14
+ * Puts todos back on the list, as when a task is landing without finishing
15
+ * them: say what is left with `splates todo update` first. From a worktree it
16
+ * gives back only its own task's todos.
17
+ */
18
+ export declare function todoRelease({ todos, log }: {
19
+ todos: Todos;
20
+ log: Logger;
21
+ }, ids: number[], task: string | null): Promise<Todo[]>;
22
+ /**
23
+ * The lines warning that `todo` was taken while `blockers` have yet to merge,
24
+ * or none when nothing blocks it: it may be started, but what it builds on
25
+ * is not there yet.
26
+ */
27
+ export declare function blockedWarning(todo: Todo, blockers: Todo[]): string[];
package/todo.d.ts ADDED
@@ -0,0 +1,146 @@
1
+ import type { Attachment, Attachments } from "./attachments.js";
2
+ import type { Journal } from "./journal.js";
3
+ import type { AgentPick } from "./roster.js";
4
+ import type { Todos } from "./todos.js";
5
+ /** What a todo is on disk: one file apiece, so two agents never rewrite one. */
6
+ export interface TodoState {
7
+ id: number;
8
+ /** What is left to do, in a line. */
9
+ subject: string;
10
+ /** Whatever more there is to say about it, or empty when the line is enough. */
11
+ text: string;
12
+ /** Where it stands in the list, 1 at the top: the one to pick up first. */
13
+ position: number;
14
+ /** The task it came up in, or null when a person added it from the main tree. */
15
+ from: string | null;
16
+ createdAt: string;
17
+ /** The task working on it now, or null while it waits to be picked up. */
18
+ takenBy: string | null;
19
+ /** Absolute paths of the files attached, in `todos/<id>/`. */
20
+ files: string[];
21
+ /**
22
+ * The todos that have to merge before this one starts, sorted. One leaves
23
+ * the list when it merges or is removed, and with it every link to it.
24
+ */
25
+ blockedBy: number[];
26
+ /** The lane it runs in, or null for none. */
27
+ lane: number | null;
28
+ /** The agent, and model, that should work it, over its lane's; absent for none. */
29
+ assignee?: AgentPick;
30
+ /** The other project it was added from; absent for one added here. */
31
+ origin?: TodoOrigin;
32
+ }
33
+ /**
34
+ * Work deferred for later: what an agent notes when something outside its
35
+ * task comes up, so it can move on instead of growing the task. Kept under the
36
+ * shared `.git`, so every worktree sees a new one at once, with nothing to
37
+ * commit and nothing to merge.
38
+ */
39
+ export declare class Todo {
40
+ private readonly todos;
41
+ readonly state: TodoState;
42
+ constructor(todos: Todos, state: TodoState);
43
+ get id(): number;
44
+ get subject(): string;
45
+ get text(): string;
46
+ get position(): number;
47
+ get from(): string | null;
48
+ get takenBy(): string | null;
49
+ get createdAt(): Date;
50
+ /** How long it has waited, in milliseconds. */
51
+ get waited(): number;
52
+ /**
53
+ * The todos blocking it that have yet to merge, leaving out those `task`
54
+ * has or takes in the same breath, among `together`: what it should not be
55
+ * started before.
56
+ */
57
+ blockers(task: string, together?: number[]): Promise<Todo[]>;
58
+ /** Marks it as the work of `task`, refusing one another task already has. */
59
+ take(task: string): Promise<Todo>;
60
+ /** Puts it back on the list, as when the task that took it is removed. */
61
+ release(): Promise<Todo>;
62
+ get files(): string[];
63
+ /** The todos that have to merge before it starts. */
64
+ get blockedBy(): number[];
65
+ get lane(): number | null;
66
+ get attachments(): Attachments;
67
+ /**
68
+ * Says what is left to do in other words, with other files, or higher or
69
+ * lower in the list, keeping its id and history.
70
+ */
71
+ update({ subject, text, position, files, keep, blockedBy, lane, assignee, }: TodoChange): Promise<Todo>;
72
+ remove(): Promise<void>;
73
+ /** Removes it, as the person did, keeping it for `Todos.restore` to put back. */
74
+ discard(): Promise<void>;
75
+ }
76
+ /** A todo's words, place or files changed: new ones added, some of the old kept. */
77
+ export interface TodoChange {
78
+ /** A new line; the old one stays when this is absent. */
79
+ subject?: string;
80
+ /** New detail, empty for none; the old stays when this is absent. */
81
+ text?: string;
82
+ /** Where to move it in the list; it stays put when this is absent. */
83
+ position?: number;
84
+ /** Files to add. */
85
+ files?: Attachment[];
86
+ /** The paths of the files it has now to keep; absent keeps them all. */
87
+ keep?: string[];
88
+ /** Every todo blocking it from now on; the old stay when this is absent. */
89
+ blockedBy?: number[];
90
+ /** The lane it runs in, `"new"` for one of its own, null for none; it stays when absent. */
91
+ lane?: number | "new" | null;
92
+ /** The agent that should work it, null for none; it stays when absent. */
93
+ assignee?: AgentPick | null;
94
+ }
95
+ /**
96
+ * Where a todo came up, as a list shows it: its task here, or for one added
97
+ * from another project, `<project>/<task>`, the project by its directory's
98
+ * name; null for one a person added from the main tree.
99
+ */
100
+ export declare function cameFrom({ from, origin }: TodoState): string | null;
101
+ /** The other project a todo was added from, and the task there it came up in. */
102
+ export interface TodoOrigin {
103
+ /** That project's main tree. */
104
+ project: string;
105
+ /** Its task the todo came up in, or null for its main tree. */
106
+ task: string | null;
107
+ }
108
+ /** What a new todo has besides its subject, all of it optional. */
109
+ export interface TodoNew {
110
+ /** Whatever more there is to say about it. */
111
+ text?: string;
112
+ files?: Attachment[];
113
+ /** Where it goes in the list, pushing those from there down; the bottom by default. */
114
+ position?: number;
115
+ /** The todos blocking it: each has to merge before it starts. */
116
+ blockedBy?: number[];
117
+ /** The lane it goes in, `"new"` for one of its own; none by default. */
118
+ lane?: number | "new" | null;
119
+ /** The agent that should work it; none by default. */
120
+ assignee?: AgentPick | null;
121
+ /** The other project it is added from; none by default. */
122
+ origin?: TodoOrigin;
123
+ }
124
+ /** `state` worked by `assignee`, or by nobody in particular for null. */
125
+ export declare function assigned<State extends {
126
+ assignee?: AgentPick;
127
+ }>(state: State, assignee: AgentPick | null | undefined): State;
128
+ /**
129
+ * A subject and its detail, trimmed. A subject running past one line keeps
130
+ * only the first, the rest leading the detail, so the list stays one line a
131
+ * todo however it was written.
132
+ */
133
+ export declare function wording(subject: string, text: string): {
134
+ subject: string;
135
+ text: string;
136
+ };
137
+ /**
138
+ * Runs `update`, which changes todo `id`, and journals it with what moved
139
+ * between the todo before and after, so a refused one is journaled bare.
140
+ */
141
+ export declare function recordUpdate(journal: Journal, todos: Todos, id: number, update: () => Promise<Todo>): Promise<Todo>;
142
+ /** `todos` as an event names them: each by its id and subject. */
143
+ export declare function todosNamed(todos: readonly Todo[]): {
144
+ id: number;
145
+ subject: string;
146
+ }[];
package/todos.d.ts ADDED
@@ -0,0 +1,157 @@
1
+ import { type IdProvider } from "webappwiz/id";
2
+ import { type Fs, type Lock } from "webappwiz/system";
3
+ import { Attachments } from "./attachments.js";
4
+ import { type LaneRecord } from "./lanes.js";
5
+ import { Todo, type TodoNew, type TodoState } from "./todo.js";
6
+ /** Every todo in the repo, one JSON file each under `.git/splates/todos`. */
7
+ export declare class Todos {
8
+ readonly dir: string;
9
+ /**
10
+ * Held while numbering a new todo, so two agents never share an id, and
11
+ * while writing one, so a move renumbering the rest never loses to a
12
+ * write of a position it just changed.
13
+ */
14
+ private readonly lock;
15
+ private readonly fs;
16
+ private readonly ids;
17
+ private readonly laneFiles;
18
+ constructor(dir: string,
19
+ /**
20
+ * Held while numbering a new todo, so two agents never share an id, and
21
+ * while writing one, so a move renumbering the rest never loses to a
22
+ * write of a position it just changed.
23
+ */
24
+ lock: Lock, opts?: TodosOptions);
25
+ /** Where a todo's files live, beside its record. */
26
+ attachments(id: number): Attachments;
27
+ /** Whether `path` is a file some todo holds, and not a way out of here. */
28
+ owns(path: string): boolean;
29
+ add(subject: string, from: string | null, { text, files, position, blockedBy, lane, assignee, origin, }?: TodoNew): Promise<Todo>;
30
+ /**
31
+ * Top of the list first. A file that will not parse is skipped rather than
32
+ * fatal, and positions are counted again from 1 as they are read, so a
33
+ * gap or a tie left by a crash, or a todo saved before they had any (it
34
+ * goes below those that do, oldest first), never shows.
35
+ */
36
+ all(): Promise<Todo[]>;
37
+ find(id: number): Promise<Todo>;
38
+ /** The todos `task` has taken; what a merge or remove settles. */
39
+ takenBy(task: string): Promise<Todo[]>;
40
+ /**
41
+ * Puts a todo at `position`, 1 at the top, past the bottom meaning the
42
+ * bottom, and numbers the rest around it. Refuses to put one above a todo
43
+ * in its own lane that it comes after, or below one that comes after it.
44
+ */
45
+ move(id: number, position: number): Promise<Todo>;
46
+ /**
47
+ * Says `id` comes after the todos in `add`, and no longer after those in
48
+ * `drop`: it is not to be started until they merge. Refuses a link that
49
+ * would make a loop, naming the todos in it, and moves a todo down below
50
+ * anything in its own lane it now comes after.
51
+ */
52
+ link(id: number, { add, drop }: {
53
+ add?: number[];
54
+ drop?: number[];
55
+ }): Promise<Todo>;
56
+ /**
57
+ * Puts a todo in a lane, or in none for null. `"new"` starts a lane of its
58
+ * own, called `name`, or after the todo without one. With `before`, it goes just above that todo; otherwise it goes
59
+ * below the rest of the lane, or keeps its place when that is in none or
60
+ * new. Refuses a place above a todo in the lane that it comes after, or
61
+ * below one that comes after it.
62
+ */
63
+ arrange(id: number, lane: number | "new" | null, { before, name }?: {
64
+ before?: number;
65
+ name?: string;
66
+ }): Promise<Todo>;
67
+ /** Every lane, in board order. */
68
+ lanes(): Promise<LaneRecord[]>;
69
+ /** The name of every lane there has been, those on the board first. */
70
+ laneNames(): Promise<LaneRecord[]>;
71
+ /** Moves every todo in lane `from` to the bottom of lane `into`; `from` is gone. */
72
+ joinLanes(from: number, into: number): Promise<void>;
73
+ /** Starts an empty lane called `name`, after the others. */
74
+ addLane(name: string): Promise<LaneRecord>;
75
+ /** Calls lane `id` by another name. */
76
+ renameLane(id: number, name: string): Promise<LaneRecord>;
77
+ /** Puts lane `id` at `position` among the lanes, 1 the first column. */
78
+ moveLane(id: number, position: number): Promise<LaneRecord[]>;
79
+ /** Removes lane `id`, putting its todos back in none, untriaged. */
80
+ dropLane(id: number): Promise<void>;
81
+ /** @internal Removes each lane in `ids` that no todo is in any more. */
82
+ endLanes(ids: number[]): Promise<void>;
83
+ /** Moves todos saved while splates kept tags into lanes, one lane a tag. */
84
+ moveTagsToLanes(): Promise<{
85
+ lane: LaneRecord;
86
+ todos: number[];
87
+ }[]>;
88
+ /**
89
+ * @internal Rewrites one todo as it stands on disk now, under the lock, so
90
+ * a change to its words or who has it never undoes a move made meanwhile.
91
+ */
92
+ revise(id: number, change: (state: TodoState) => TodoState): Promise<Todo>;
93
+ /** @internal Writes one todo. Rename makes the swap atomic for readers. */
94
+ save(state: TodoState): Promise<Todo>;
95
+ /**
96
+ * @internal Removes one, moving those below it up to close the gap. What
97
+ * came after it no longer waits on it, so no todo is left naming one that
98
+ * is gone.
99
+ */
100
+ delete(id: number): Promise<void>;
101
+ /**
102
+ * @internal Removes one as `delete` does, keeping it and its files under
103
+ * `removed/` for `restore` to put back. Only the newest `REMOVED_KEPT` are
104
+ * kept, the older going for good.
105
+ */
106
+ discard(state: TodoState): Promise<void>;
107
+ /**
108
+ * Puts a todo `discard` removed back under its id, where it stood in the
109
+ * list, untaken: in its lane while that lane is still on the board, after
110
+ * those it waited on that still are.
111
+ */
112
+ restore(id: number): Promise<Todo>;
113
+ /** @internal Runs `run` holding the lock every write goes through. */
114
+ locked<T>(run: () => Promise<T>): Promise<T>;
115
+ /**
116
+ * Settles the list after a link or a lane changed, moving each todo below
117
+ * what it comes after in its lane, and gives back `id` as it ends up.
118
+ * Call it under the lock.
119
+ */
120
+ private settled;
121
+ /** Refuses `order` when a lane in it puts a todo above one it comes after. */
122
+ private ordered;
123
+ /** One todo as it stands on disk; call it under the lock. */
124
+ private state;
125
+ /**
126
+ * Slots `state` in at `position` among the rest and saves whichever moved.
127
+ * Call it under the lock.
128
+ */
129
+ private place;
130
+ /**
131
+ * @internal Every todo in list order, with the positions it has on disk. `tagged`
132
+ * are read though they still have tags, to move them into lanes.
133
+ */
134
+ stored(tagged?: number[]): Promise<TodoState[]>;
135
+ /** @internal Saves each todo in `order` whose position on disk is not its place there. */
136
+ renumber(order: TodoState[]): Promise<void>;
137
+ private get removedDir();
138
+ private removedPath;
139
+ /** The todos `discard` kept, the oldest removed first. */
140
+ private removed;
141
+ private path;
142
+ private lastId;
143
+ /**
144
+ * One todo, or null when it will not parse. One saved with tags is
145
+ * refused, unless it is one of `tagged`: dropping them unasked would lose
146
+ * what they grouped.
147
+ */
148
+ private read;
149
+ }
150
+ /** How many removed todos `Todos.discard` keeps for `restore`. */
151
+ export declare const REMOVED_KEPT = 50;
152
+ /** What `Todos` is stored through; the real filesystem by default. */
153
+ export interface TodosOptions {
154
+ fs?: Fs;
155
+ /** What names stored files apart; random ids by default. */
156
+ ids?: IdProvider;
157
+ }
@@ -0,0 +1,18 @@
1
+ import type * as acp from "@agentclientprotocol/sdk";
2
+ import type { ConversationState, Tool } from "./conversation-state.js";
3
+ /** How much of a tool call's output, and of each side of an edit, is kept. */
4
+ export declare const TOOL_CHARS = 20000;
5
+ /**
6
+ * Takes what an update says of a tool call into it. Adapters say it in
7
+ * different places: Claude sends a command's output whole as `rawOutput`
8
+ * once it ends, Codex streams it in `_meta` and says how it exited there.
9
+ */
10
+ export declare function fill(tool: Tool, update: acp.ToolCall | acp.ToolCallUpdate, at: string | null): void;
11
+ /** The tool call `id`, wherever in the conversation it was made. */
12
+ export declare function toolIn(state: ConversationState, id: string): Tool | null;
13
+ /** The subagent's tool call an update came from; null for the agent's own. */
14
+ export declare function parentOf(update: {
15
+ _meta?: {
16
+ [key: string]: unknown;
17
+ } | null;
18
+ }): string | null;
@@ -0,0 +1,37 @@
1
+ import type { AsyncResource } from "webappwiz/disposable";
2
+ import type { Logger } from "webappwiz/log";
3
+ /** What a provider is asked to publish. */
4
+ export interface TunnelRoute {
5
+ /** The public host name that must reach `url`. */
6
+ host: string;
7
+ /** The page on this machine, `http://localhost:<port>`. */
8
+ url: string;
9
+ /** Where the provider says what it is doing, such as where it is reachable. */
10
+ log: Logger;
11
+ }
12
+ /**
13
+ * TunnelProvider is the seam onto whatever puts the `splates server` page on a
14
+ * public host name: `cloudflared` by default, or any tunnel a repo's
15
+ * `splates.config.ts` names as `tunnel`:
16
+ *
17
+ * ```ts
18
+ * export default { tunnel: new MyTunnel() } satisfies ConfigFile;
19
+ * ```
20
+ *
21
+ * Whatever it is, `--tunnel` still refuses to run without Cloudflare Access in
22
+ * front, which is what decides who may enter; a provider only carries traffic.
23
+ */
24
+ export interface TunnelProvider {
25
+ /**
26
+ * Throws unless whatever runs the tunnel is installed and signed in, with a
27
+ * message saying what to do about it. Asked before `run`, which is skipped
28
+ * when it throws: the page keeps serving on this machine.
29
+ */
30
+ ready(): Promise<void>;
31
+ /**
32
+ * Starts carrying `route.host` to `route.url`, and answers with the run,
33
+ * which serves until it is disposed of. Disposing stops the tunnel and
34
+ * returns once it is gone; disposing one that stopped on its own is silent.
35
+ */
36
+ run(route: TunnelRoute): AsyncResource;
37
+ }
File without changes
@@ -0,0 +1,28 @@
1
+ import { type Logger } from "webappwiz/log";
2
+ import type { Fs } from "webappwiz/system";
3
+ import type { Creds } from "./creds.js";
4
+ import { type SavedTunnel } from "./saved-tunnel.js";
5
+ /** What `splates tunnel remove` is asked to remove, and what it runs with. */
6
+ export interface RemoveOptions {
7
+ /** The tunnel `splates tunnel setup` saved for this machine. */
8
+ saved: SavedTunnel;
9
+ /** Each slot home's tunnel, in the pool's order, whether or not it has one. */
10
+ slots: SavedTunnel[];
11
+ /** Where the API token is read from, and the tunnels' tokens forgotten. */
12
+ creds: Creds;
13
+ /** The task asking, for the request to name; null outside any. */
14
+ task: string | null;
15
+ fs: Fs;
16
+ log: Logger;
17
+ fetch?: typeof fetch;
18
+ }
19
+ /**
20
+ * Deletes what `splates tunnel setup` and `splates server --slot` made, by what they
21
+ * saved: each tunnel and the DNS record routing to it, the Access application
22
+ * in front of the machine's host and the one in front of every slot, and the
23
+ * policy they share. Then forgets each saved file and the tunnel token kept
24
+ * for it. What is already gone is passed over, and a file is forgotten only
25
+ * once its tunnel is, so running it again after a failure finishes the job.
26
+ * The Cloudflare API token is kept, for `splates tunnel setup` to use again.
27
+ */
28
+ export declare function tunnelRemove(opts: RemoveOptions): Promise<void>;
@@ -0,0 +1,104 @@
1
+ import { type Logger } from "webappwiz/log";
2
+ import { z } from "zod";
3
+ import { CloudflareApi } from "./cloudflare-api.js";
4
+ import type { Creds } from "./creds.js";
5
+ import { type SavedTunnel } from "./saved-tunnel.js";
6
+ /** What `splates tunnel setup` is asked to make, and what it runs with. */
7
+ export interface SetupOptions {
8
+ /** The public host name, in a zone of the account. */
9
+ host: string;
10
+ /** Who Access lets in, comma separated. */
11
+ email: string;
12
+ /** What the tunnel, the Access application and its policy are called. */
13
+ name: string;
14
+ /**
15
+ * The Zero Trust team to make, as in `<team>.cloudflareaccess.com`, when
16
+ * the account has none yet; "" to use the one it has.
17
+ */
18
+ team: string;
19
+ /** Where the API token is read from, or requested, and the tunnel's token saved. */
20
+ creds: Creds;
21
+ /** The task asking, for the request to name; null outside any. */
22
+ task: string | null;
23
+ /** Where what it made is saved for `splates server`. */
24
+ saved: SavedTunnel;
25
+ log: Logger;
26
+ fetch?: typeof fetch;
27
+ }
28
+ /**
29
+ * Makes everything that carries `host` to `splates server` behind Cloudflare
30
+ * Access, through the API alone, with the API token the person pasted as
31
+ * `API_TOKEN`: the Zero Trust organization when the account has none, a
32
+ * tunnel and its token, the DNS record routing `host` to it, and an Access
33
+ * application letting in only `email`. What already exists by name is
34
+ * reused, and changed only where it differs, so running it again is safe,
35
+ * like `splates init`. Saves what it made, so a bare `splates server` runs it.
36
+ *
37
+ * Without the API token, it requests one with instructions for making it,
38
+ * and refuses with `requested`, to run again once it is saved.
39
+ */
40
+ export declare function tunnelSetup(opts: SetupOptions): Promise<void>;
41
+ /**
42
+ * The cred the Cloudflare API token is kept as, on the device, since the
43
+ * account is the person's. Not `CLOUDFLARE_API_TOKEN`, which scry's Workers
44
+ * AI token goes by in the same store.
45
+ */
46
+ export declare const API_TOKEN = "SPLATES_CLOUDFLARE_API_TOKEN";
47
+ /** What the API token has to be allowed, as the dashboard names each. */
48
+ export declare const TOKEN_PERMISSIONS: string[];
49
+ /** Where an API token is made. */
50
+ export declare const TOKENS_PAGE = "https://dash.cloudflare.com/profile/api-tokens";
51
+ declare const Zone: z.ZodObject<{
52
+ id: z.ZodString;
53
+ name: z.ZodString;
54
+ account: z.ZodObject<{
55
+ id: z.ZodString;
56
+ }, z.core.$strip>;
57
+ }, z.core.$strip>;
58
+ declare const Tunnel: z.ZodObject<{
59
+ id: z.ZodString;
60
+ name: z.ZodString;
61
+ }, z.core.$strip>;
62
+ export declare const App: z.ZodObject<{
63
+ id: z.ZodString;
64
+ domain: z.ZodOptional<z.ZodString>;
65
+ aud: z.ZodString;
66
+ policies: z.ZodDefault<z.ZodArray<z.ZodObject<{
67
+ id: z.ZodString;
68
+ }, z.core.$strip>>>;
69
+ }, z.core.$strip>;
70
+ /**
71
+ * The Cloudflare account `splates tunnel` works in, through the API with the
72
+ * token kept as `API_TOKEN`, reporting what it makes to `log`.
73
+ */
74
+ export declare class CloudflareTunnels {
75
+ readonly api: CloudflareApi;
76
+ private readonly log;
77
+ private constructor();
78
+ /**
79
+ * Opens the account with the token kept as `API_TOKEN`. Without it,
80
+ * requests it with instructions for making it, and refuses with
81
+ * `requested`, to run again once it is saved.
82
+ */
83
+ static open(creds: Creds, host: string, task: string | null, log: Logger, fetch?: typeof globalThis.fetch): Promise<CloudflareTunnels>;
84
+ /** The zone serving `host`: the longest of its suffixes the account has. */
85
+ findZone(host: string): Promise<z.infer<typeof Zone>>;
86
+ /**
87
+ * The tunnel called `name`, made when there is none. Configured locally, so
88
+ * `cloudflared` carries the host to whichever port `splates server` bound, which
89
+ * its `--url` says, rather than to one the dashboard pins.
90
+ */
91
+ ensureTunnel(account: string, name: string): Promise<z.infer<typeof Tunnel>>;
92
+ /**
93
+ * The proxied CNAME routing `host` to the tunnel. One already pointing at
94
+ * another tunnel is moved to this one; any other record for `host` is someone
95
+ * else's, and refused rather than replaced.
96
+ */
97
+ ensureRoute(zone: string, host: string, tunnel: string): Promise<void>;
98
+ /**
99
+ * The self-hosted Access application in front of `host`, guarded by
100
+ * `policy` alone, and its AUD tag, which Cloudflare assigns when it is made.
101
+ */
102
+ ensureApp(account: string, name: string, host: string, policy: string): Promise<string>;
103
+ }
104
+ export {};
@@ -0,0 +1,23 @@
1
+ import type { AsyncResource } from "webappwiz/disposable";
2
+ import { type Eventful } from "webappwiz/events";
3
+ import type { Fs } from "webappwiz/system";
4
+ import { UnixWorkerSocket } from "./unix-worker-socket.js";
5
+ /** What a `UnixWorkerListener` hears: a worker dialed in. */
6
+ export interface UnixWorkerListenerEvents extends Record<string, unknown> {
7
+ socket: UnixWorkerSocket;
8
+ }
9
+ /**
10
+ * Where the local worker dials its coordinator: a Unix socket only this
11
+ * user may open. Listening takes the path over from a coordinator that died
12
+ * without cleaning up, and refuses one still answering there.
13
+ */
14
+ export declare class UnixWorkerListener implements Eventful<UnixWorkerListenerEvents>, AsyncResource {
15
+ readonly path: string;
16
+ private readonly listener;
17
+ private readonly fs;
18
+ private readonly dispatcher;
19
+ readonly events: import("webappwiz/events").Events<UnixWorkerListenerEvents>;
20
+ private constructor();
21
+ static listen(path: string, fs: Fs): Promise<UnixWorkerListener>;
22
+ disposeAsync(): Promise<void>;
23
+ }