@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.
- package/LICENSE +21 -0
- package/README.md +308 -2
- package/acp-extensions.d.ts +82 -0
- package/add.d.ts +53 -0
- package/adherence.d.ts +49 -0
- package/age.d.ts +2 -0
- package/agent-connection.d.ts +171 -0
- package/agent-errors.d.ts +2 -0
- package/agent-process.d.ts +65 -0
- package/agent-stream.d.ts +91 -0
- package/agents.d.ts +15 -0
- package/artifact-room.d.ts +47 -0
- package/artifact-viewers.d.ts +6 -0
- package/artifact.d.ts +30 -0
- package/artifacts.d.ts +161 -0
- package/asked.d.ts +146 -0
- package/asked.js +7 -0
- package/assumed.d.ts +34 -0
- package/attach.d.ts +30 -0
- package/attachments.d.ts +43 -0
- package/baselines.d.ts +55 -0
- package/claim.d.ts +17 -0
- package/cloudflare-api.d.ts +25 -0
- package/cloudflare-error.d.ts +5 -0
- package/cloudflared-tunnel-provider.d.ts +27 -0
- package/codex-limits.d.ts +19 -0
- package/compaction.d.ts +17 -0
- package/config-source.d.ts +13 -0
- package/config.d.ts +98 -0
- package/config.js +7 -0
- package/conversation-archive.d.ts +6 -0
- package/conversation-background.d.ts +21 -0
- package/conversation-choice.d.ts +4 -0
- package/conversation-files.d.ts +51 -0
- package/conversation-given.d.ts +8 -0
- package/conversation-host.d.ts +102 -0
- package/conversation-listing.d.ts +15 -0
- package/conversation-log.d.ts +301 -0
- package/conversation-messages.d.ts +18 -0
- package/conversation-name.d.ts +28 -0
- package/conversation-options.d.ts +73 -0
- package/conversation-reference.d.ts +2 -0
- package/conversation-state.d.ts +472 -0
- package/conversation-turns.d.ts +115 -0
- package/conversation.d.ts +209 -0
- package/conversations.d.ts +140 -0
- package/coordinator-state.d.ts +28 -0
- package/creds.d.ts +123 -0
- package/darwin-temperature.d.ts +7 -0
- package/decided.d.ts +18 -0
- package/demo.d.ts +29 -0
- package/dev/api.d.ts +209 -0
- package/dev/assets.d.ts +24 -0
- package/dev/conversation-address.d.ts +47 -0
- package/dev/conversation-feed.d.ts +166 -0
- package/dev/live-stream.d.ts +29 -0
- package/dev/worker.d.ts +33 -0
- package/dev-access.d.ts +61 -0
- package/dev-artifacts.d.ts +22 -0
- package/dev-budgets.d.ts +18 -0
- package/dev-conversation-events.d.ts +39 -0
- package/dev-conversation-routes.d.ts +90 -0
- package/dev-creds.d.ts +17 -0
- package/dev-dictation-connection.d.ts +18 -0
- package/dev-dictation.d.ts +17 -0
- package/dev-http.d.ts +76 -0
- package/dev-open.d.ts +15 -0
- package/dev-options.d.ts +133 -0
- package/dev-outcomes.d.ts +21 -0
- package/dev-pages.d.ts +16 -0
- package/dev-picker.d.ts +57 -0
- package/dev-port-socket.d.ts +26 -0
- package/dev-ports.d.ts +11 -0
- package/dev-project-watch.d.ts +44 -0
- package/dev-project.d.ts +168 -0
- package/dev-push.d.ts +59 -0
- package/dev-restart.d.ts +141 -0
- package/dev-servers.d.ts +30 -0
- package/dev-setup-native.d.ts +23 -0
- package/dev-setup-opencode.d.ts +29 -0
- package/dev-setup.d.ts +16 -0
- package/dev-shell.d.ts +70 -0
- package/dev-slot.d.ts +28 -0
- package/dev-sockets.d.ts +13 -0
- package/dev-task-ports.d.ts +73 -0
- package/dev-tasks.d.ts +20 -0
- package/dev-terminal-connection.d.ts +19 -0
- package/dev-terminal.d.ts +42 -0
- package/dev-todos.d.ts +35 -0
- package/dev-transcriber.d.ts +15 -0
- package/dev-tunnel.d.ts +38 -0
- package/dev-versions.d.ts +53 -0
- package/dev-workers.d.ts +55 -0
- package/dev.d.ts +24 -0
- package/diff.d.ts +29 -0
- package/dispatched.d.ts +16 -0
- package/editors.d.ts +22 -0
- package/escalate.d.ts +27 -0
- package/events.d.ts +311 -0
- package/everywhere.d.ts +41 -0
- package/exhibit.d.ts +21 -0
- package/exit.d.ts +54 -0
- package/fact-todos.d.ts +18 -0
- package/fake-agent.d.ts +107 -0
- package/fake-agent.js +284 -0
- package/finding-facts.d.ts +38 -0
- package/findings.d.ts +84 -0
- package/fold.d.ts +43 -0
- package/follow.d.ts +41 -0
- package/format.d.ts +68 -0
- package/git.d.ts +112 -0
- package/handed-out.d.ts +79 -0
- package/handoff.d.ts +23 -0
- package/heavy-run.d.ts +12 -0
- package/heavy.d.ts +28 -0
- package/heavy.js +16 -0
- package/held.d.ts +22 -0
- package/index-0tfvy823.js +272 -0
- package/index-43pq33n4.js +157 -0
- package/index-4776671w.js +698 -0
- package/index-d4hjrzaq.js +464 -0
- package/index-gcfq7awr.js +740 -0
- package/index-k73tsw5g.js +101 -0
- package/index-kaa44k7q.js +59 -0
- package/index-vcv9m93e.js +1265 -0
- package/index-xmfmy729.js +249 -0
- package/index.d.ts +2 -0
- package/index.js +26928 -0
- package/init.d.ts +28 -0
- package/journal.d.ts +57 -0
- package/landed.d.ts +14 -0
- package/lane-todos.d.ts +44 -0
- package/lane.d.ts +55 -0
- package/lanes-from-tags.d.ts +17 -0
- package/lanes.d.ts +96 -0
- package/legacy-names.d.ts +70 -0
- package/legacy-ps.d.ts +31 -0
- package/limits.d.ts +32 -0
- package/list.d.ts +18 -0
- package/load-config.d.ts +44 -0
- package/log.d.ts +14 -0
- package/machine.d.ts +42 -0
- package/merge.d.ts +35 -0
- package/migrate-config.d.ts +31 -0
- package/models.d.ts +24 -0
- package/needs.d.ts +115 -0
- package/notices.d.ts +39 -0
- package/offered.d.ts +39 -0
- package/opencode-usage.d.ts +37 -0
- package/outcomes.d.ts +114 -0
- package/package.json +74 -5
- package/path.d.ts +13 -0
- package/plan.d.ts +236 -0
- package/port-forward.d.ts +22 -0
- package/port-pipe.d.ts +36 -0
- package/ports-list.d.ts +19 -0
- package/probe-runtime.d.ts +5 -0
- package/probe-runtime.js +13 -0
- package/project-reaches.d.ts +23 -0
- package/projects.d.ts +136 -0
- package/prompts.d.ts +128 -0
- package/pty.d.ts +39 -0
- package/pulse.d.ts +8 -0
- package/recommend.d.ts +31 -0
- package/release.d.ts +41 -0
- package/remote-process.d.ts +26 -0
- package/remote-pty.d.ts +29 -0
- package/remote-worker.d.ts +77 -0
- package/remove.d.ts +31 -0
- package/repository.d.ts +91 -0
- package/retry.d.ts +34 -0
- package/roster.d.ts +63 -0
- package/saved-ports-host.d.ts +25 -0
- package/saved-tunnel.d.ts +44 -0
- package/server-worker-socket.d.ts +21 -0
- package/setup-areas.d.ts +7 -0
- package/setup-opencode-model-error.d.ts +3 -0
- package/setup-opencode-models.d.ts +54 -0
- package/setup-opencode-recipe.d.ts +26 -0
- package/setup-opencode.d.ts +46 -0
- package/setup.d.ts +102 -0
- package/shared-browser.d.ts +50 -0
- package/shell.d.ts +17 -0
- package/show.d.ts +106 -0
- package/skill-checks.d.ts +73 -0
- package/skill-checks.js +10 -0
- package/skills.d.ts +16 -0
- package/slot-tunnel.d.ts +27 -0
- package/slots.d.ts +135 -0
- package/snapshot.d.ts +75 -0
- package/splates-artifact.d.ts +3 -0
- package/splates-creds.d.ts +3 -0
- package/splates-dev.d.ts +22 -0
- package/splates-flags.d.ts +34 -0
- package/splates-lane.d.ts +3 -0
- package/splates-projects.d.ts +3 -0
- package/splates-setup.d.ts +17 -0
- package/splates-slots.d.ts +3 -0
- package/splates-todo.d.ts +3 -0
- package/splates-tunnel.d.ts +3 -0
- package/splates-worker.d.ts +3 -0
- package/splates.d.ts +28 -0
- package/stats.d.ts +186 -0
- package/supervise.d.ts +50 -0
- package/system-changes.d.ts +67 -0
- package/system.d.ts +28 -0
- package/systems.d.ts +119 -0
- package/systems.js +21 -0
- package/table.d.ts +5 -0
- package/task-log.d.ts +35 -0
- package/task-ports.d.ts +25 -0
- package/tell.d.ts +47 -0
- package/todo-edit.d.ts +60 -0
- package/todo-file.d.ts +6 -0
- package/todo-lanes.d.ts +82 -0
- package/todo-list.d.ts +26 -0
- package/todo-take.d.ts +27 -0
- package/todo.d.ts +146 -0
- package/todos.d.ts +157 -0
- package/tool-calls.d.ts +18 -0
- package/tunnel-provider.d.ts +37 -0
- package/tunnel-provider.js +0 -0
- package/tunnel-remove.d.ts +28 -0
- package/tunnel-setup.d.ts +104 -0
- package/unix-worker-listener.d.ts +23 -0
- package/unix-worker-socket.d.ts +30 -0
- package/update.d.ts +29 -0
- package/update.js +10 -0
- package/vocabulary.d.ts +9 -0
- package/wait.d.ts +36 -0
- package/watch.d.ts +46 -0
- package/watched.d.ts +43 -0
- package/websocket-worker-socket.d.ts +18 -0
- package/worker-call-host.d.ts +51 -0
- package/worker-channel.d.ts +83 -0
- package/worker-connection.d.ts +24 -0
- package/worker-daemon.d.ts +64 -0
- package/worker-git.d.ts +18 -0
- package/worker-list.d.ts +49 -0
- package/worker-machine.d.ts +34 -0
- package/worker-port-host.d.ts +21 -0
- package/worker-process-host.d.ts +29 -0
- package/worker-protocol.d.ts +104 -0
- package/worker-pty-host.d.ts +34 -0
- package/worker-registry.d.ts +68 -0
- package/worker-replay.d.ts +25 -0
- package/worker-run.d.ts +20 -0
- package/worker-session.d.ts +189 -0
- package/worker-socket.d.ts +15 -0
- package/worktree-service.d.ts +113 -0
- package/worktree.d.ts +232 -0
package/needs.d.ts
ADDED
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import { Duration } from "webappwiz/time";
|
|
2
|
+
import type { ConversationState } from "./conversations.js";
|
|
3
|
+
import { type Question } from "./plan.js";
|
|
4
|
+
import type { Details } from "./show.js";
|
|
5
|
+
/**
|
|
6
|
+
* What an agent needs from the person, by how much it costs to leave it:
|
|
7
|
+
* `waiting` has stopped on them, `assuming` goes ahead on a guess an answer
|
|
8
|
+
* may overturn, `working` needs nothing yet, and `idle` is not doing anything.
|
|
9
|
+
*/
|
|
10
|
+
export type Need = {
|
|
11
|
+
kind: "waiting";
|
|
12
|
+
why: Why;
|
|
13
|
+
/**
|
|
14
|
+
* What to act on: the ask, what a review asks you to look at, the
|
|
15
|
+
* first open question, or the failure.
|
|
16
|
+
*/
|
|
17
|
+
subject: string;
|
|
18
|
+
/** When it stopped, where that is known. */
|
|
19
|
+
since: string | null;
|
|
20
|
+
/** The task's open questions, none for a task-less conversation. */
|
|
21
|
+
questions: Question[];
|
|
22
|
+
/** The agent handed out by this one it waits for, lifted onto it. */
|
|
23
|
+
via?: string;
|
|
24
|
+
} | {
|
|
25
|
+
kind: "assuming";
|
|
26
|
+
/** The first open question. */
|
|
27
|
+
subject: string;
|
|
28
|
+
questions: Question[];
|
|
29
|
+
/** The agent handed out by this one whose questions it relays. */
|
|
30
|
+
via?: string;
|
|
31
|
+
} | {
|
|
32
|
+
kind: "working";
|
|
33
|
+
/** The next step under `## Next`, else the Goal's first line. */
|
|
34
|
+
subject: string | null;
|
|
35
|
+
} | {
|
|
36
|
+
kind: "idle";
|
|
37
|
+
};
|
|
38
|
+
/** One agent the page shows: a conversation, its task, or both. */
|
|
39
|
+
export interface Needing {
|
|
40
|
+
conversation: ConversationState | null;
|
|
41
|
+
task: Details | null;
|
|
42
|
+
need: Need;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Every listed conversation, and every live task no listed conversation runs
|
|
46
|
+
* in (an external agent, run outside the page) and none is about to, with
|
|
47
|
+
* what each needs: those waiting first,
|
|
48
|
+
* oldest stop first, then those assuming, most open questions first, then the
|
|
49
|
+
* rest in the order given.
|
|
50
|
+
*/
|
|
51
|
+
export declare function needs({ tasks, conversations, }: {
|
|
52
|
+
tasks: Details[];
|
|
53
|
+
conversations: ConversationState[];
|
|
54
|
+
}): Needing[];
|
|
55
|
+
/**
|
|
56
|
+
* Why an agent waits: a live ACP ask (a permission or a form), a review it
|
|
57
|
+
* escalated for, any other escalation, open questions it ended its turn on,
|
|
58
|
+
* a failure, or for a task, no agent left on it (see `abandoned`).
|
|
59
|
+
*/
|
|
60
|
+
export type Why = "ask" | "review" | "escalated" | "questions" | "failed" | "abandoned";
|
|
61
|
+
/**
|
|
62
|
+
* Every live task no listed conversation runs in, an external agent's, with
|
|
63
|
+
* what it needs, before `answeredThrough`. One handed to an agent shows once
|
|
64
|
+
* its conversation starts.
|
|
65
|
+
*/
|
|
66
|
+
export declare function externals(tasks: Details[], conversations: ConversationState[]): Needing[];
|
|
67
|
+
/** What a task no listed conversation runs in needs: see `externals`. */
|
|
68
|
+
export declare function needOfExternal(task: Details, conversations: ConversationState[]): Need;
|
|
69
|
+
/**
|
|
70
|
+
* Whether no agent is left on an external task, for certain: the page
|
|
71
|
+
* conversation whose agent last took it is archived, or gone with the oldest
|
|
72
|
+
* archived ones, and no agent outside the page has taken it since. What it
|
|
73
|
+
* says of it, and since when; null while an agent may yet be on it. A
|
|
74
|
+
* conversation listed on another task may still have a subagent on this
|
|
75
|
+
* one, so only going quiet tells of it.
|
|
76
|
+
*/
|
|
77
|
+
export declare function abandoned(task: Details, conversations: ConversationState[]): {
|
|
78
|
+
subject: string;
|
|
79
|
+
since: string | null;
|
|
80
|
+
} | null;
|
|
81
|
+
/**
|
|
82
|
+
* How long an external agent's task goes without a sign of it at work before
|
|
83
|
+
* it shows as quiet: long enough for a test run or a long think.
|
|
84
|
+
*/
|
|
85
|
+
export declare const QUIET_AFTER: Duration;
|
|
86
|
+
/**
|
|
87
|
+
* When an external agent's task last showed a sign of its agent at work, once
|
|
88
|
+
* that is `QUIET_AFTER` ago at `now`; null while it has lately, or nothing
|
|
89
|
+
* says. Only an agent taken to be at work goes quiet: one that waits on the
|
|
90
|
+
* person is still for a reason.
|
|
91
|
+
*/
|
|
92
|
+
export declare function quietSince({ task, need }: Pick<Needing, "task" | "need">, now: number): string | null;
|
|
93
|
+
/**
|
|
94
|
+
* What one agent needs, from its conversation (null for an agent the page
|
|
95
|
+
* does not run) and the task it is in (null for the main tree).
|
|
96
|
+
*/
|
|
97
|
+
export declare function need(task: Details | null, conversation: ConversationState | null): Need;
|
|
98
|
+
/**
|
|
99
|
+
* `found` with each agent that answers to another conversation waiting on
|
|
100
|
+
* that one rather than on the person: only the person answers its asks, so
|
|
101
|
+
* one waits on that one's row, where they show, whatever it is doing; its
|
|
102
|
+
* escalations reach the person through that one's reports, so one waits on
|
|
103
|
+
* that one's row once it is idle, having relayed it, naming the agent, and
|
|
104
|
+
* while it works on regardless, that one goes ahead with them owed, as an
|
|
105
|
+
* assuming agent does. A failure stays the agent's own, since nothing tells
|
|
106
|
+
* that one of it.
|
|
107
|
+
*/
|
|
108
|
+
export declare function answeredThrough(found: Needing[], conversations: ConversationState[]): Needing[];
|
|
109
|
+
/**
|
|
110
|
+
* The conversation an agent answers to, rather than to the person, while the
|
|
111
|
+
* page holds it: the one that handed its conversation the task, or for an
|
|
112
|
+
* external agent, such as a subagent its harness started, the listed one
|
|
113
|
+
* whose agent added its task.
|
|
114
|
+
*/
|
|
115
|
+
export declare function answersTo({ conversation, task }: Pick<Needing, "conversation" | "task">, conversations: readonly ConversationState[]): ConversationState | null;
|
package/notices.d.ts
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import type { Needing } from "./needs.js";
|
|
2
|
+
/** Something a row did worth telling the person about, away from the page. */
|
|
3
|
+
export interface Notice {
|
|
4
|
+
row: Needing;
|
|
5
|
+
title: string;
|
|
6
|
+
body: string;
|
|
7
|
+
}
|
|
8
|
+
/** Which notices the person asked for, as the page's Notifications settings say. */
|
|
9
|
+
export interface Wants {
|
|
10
|
+
waiting: boolean;
|
|
11
|
+
finished: boolean;
|
|
12
|
+
quiet: boolean;
|
|
13
|
+
/** Minutes a running agent goes without a word before it counts as quiet. */
|
|
14
|
+
quietAfter: number;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Tells what changed in the rows since the last look worth notifying of,
|
|
18
|
+
* the same on the page and on the server, which pushes it to a phone the
|
|
19
|
+
* page cannot run on once it leaves the front.
|
|
20
|
+
*/
|
|
21
|
+
export declare class Notices {
|
|
22
|
+
/** By row, what the last look saw; null before the first. */
|
|
23
|
+
private seen;
|
|
24
|
+
/**
|
|
25
|
+
* Compares `rows`, named by `name`, with the last look at `now`, and
|
|
26
|
+
* returns what changed worth telling, of the kinds `wants` asks for: a
|
|
27
|
+
* row that came to wait, a conversation that finished its turn, and one
|
|
28
|
+
* running with no word for the quiet time. The first look tells nothing,
|
|
29
|
+
* since it has nothing to compare.
|
|
30
|
+
*/
|
|
31
|
+
look(rows: Needing[], name: (row: Needing) => string, now: number, wants: Wants): Notice[];
|
|
32
|
+
}
|
|
33
|
+
/** What tells `row` apart from the others, in a notification and its click. */
|
|
34
|
+
export declare function keyOf(row: Needing): string;
|
|
35
|
+
/**
|
|
36
|
+
* The first line of `markdown` with its marks taken out, cut to `length`:
|
|
37
|
+
* a notification shows plain text, and a phone only a line or so of it.
|
|
38
|
+
*/
|
|
39
|
+
export declare function plain(markdown: string, length: number): string;
|
package/offered.d.ts
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import type { Fs } from "webappwiz/system";
|
|
2
|
+
import type { Conversation } from "./conversation.js";
|
|
3
|
+
import type { Setting } from "./conversations.js";
|
|
4
|
+
/**
|
|
5
|
+
* The agent settings offered across projects, with defaults changed only by
|
|
6
|
+
* user selections. Session reports can refresh available options without
|
|
7
|
+
* replacing the values the person picked.
|
|
8
|
+
*/
|
|
9
|
+
export declare class Offered {
|
|
10
|
+
/** `~/.splates/offered.json`, or a test's own. */
|
|
11
|
+
readonly path: string;
|
|
12
|
+
private readonly deps;
|
|
13
|
+
/** Read once, then kept: this process is the one writing it. */
|
|
14
|
+
private known;
|
|
15
|
+
/** Set when a newer splates wrote the file, which this one leaves alone. */
|
|
16
|
+
private newer;
|
|
17
|
+
/** Writes one after another, so none is lost to another. */
|
|
18
|
+
private writing;
|
|
19
|
+
constructor(
|
|
20
|
+
/** `~/.splates/offered.json`, or a test's own. */
|
|
21
|
+
path: string, deps: {
|
|
22
|
+
fs: Fs;
|
|
23
|
+
});
|
|
24
|
+
/** Every agent's settings, by its id; none for one never started. */
|
|
25
|
+
all(): Promise<Record<string, Setting[]>>;
|
|
26
|
+
/**
|
|
27
|
+
* Keeps `settings` as what `agent`'s sessions offer from now on, or, with
|
|
28
|
+
* `preserveChoices`, refreshes options while keeping existing default values.
|
|
29
|
+
*/
|
|
30
|
+
remember(agent: string, settings: Setting[], { preserveChoices }?: {
|
|
31
|
+
preserveChoices?: boolean;
|
|
32
|
+
}): Promise<void>;
|
|
33
|
+
/** Saves only settings the person selected, leaving other defaults alone. */
|
|
34
|
+
choose(agent: string, settings: Setting[], ids: string[]): Promise<void>;
|
|
35
|
+
/** Tracks capabilities separately from explicit choices, including the opening form. */
|
|
36
|
+
track(conversation: Conversation, changed: () => void, picks?: Record<string, string>): void;
|
|
37
|
+
private read;
|
|
38
|
+
private write;
|
|
39
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import type * as acp from "@agentclientprotocol/sdk";
|
|
2
|
+
import type { ConversationState } from "./conversation-state.js";
|
|
3
|
+
/** Observations, never a quota estimate or evidence of an invoice. */
|
|
4
|
+
export interface OpenCodeUsage {
|
|
5
|
+
turns: ObservedTurn[];
|
|
6
|
+
costAt: string | null;
|
|
7
|
+
retry: {
|
|
8
|
+
attempt: number | null;
|
|
9
|
+
nextRetryAt: string | null;
|
|
10
|
+
message: string;
|
|
11
|
+
type: string | null;
|
|
12
|
+
status: number | null;
|
|
13
|
+
} | null;
|
|
14
|
+
}
|
|
15
|
+
/** Null means absent or invalid, including in logs predating instrumentation. */
|
|
16
|
+
export interface ObservedTurn {
|
|
17
|
+
at: string;
|
|
18
|
+
until: string | null;
|
|
19
|
+
firstText: string | null;
|
|
20
|
+
requested: string | null;
|
|
21
|
+
confirmed: string | null;
|
|
22
|
+
cwd: string | null;
|
|
23
|
+
/** ACP prompt response; per turn, parent session only. */
|
|
24
|
+
tokens: {
|
|
25
|
+
input: number | null;
|
|
26
|
+
output: number | null;
|
|
27
|
+
cachedRead: number | null;
|
|
28
|
+
cachedWrite: number | null;
|
|
29
|
+
} | null;
|
|
30
|
+
}
|
|
31
|
+
export declare function metric(value: unknown): number | null;
|
|
32
|
+
/** End exactly once, including cancellation, failure and worker reattachment. */
|
|
33
|
+
export declare function finishObservation(state: ConversationState, at: string | null): void;
|
|
34
|
+
/** Keep only documented retry fields; provider response bodies are not diagnostics. */
|
|
35
|
+
export declare function safeOpenCodeUpdate(update: acp.SessionUpdate): acp.SessionUpdate;
|
|
36
|
+
/** Snapshot fields independently; optional cache data is not evidence of zero. */
|
|
37
|
+
export declare function observeTokens(state: ConversationState, usage: acp.Usage): void;
|
package/outcomes.d.ts
ADDED
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import type { Fs } from "webappwiz/system";
|
|
2
|
+
import type { Device } from "./conversation-state.js";
|
|
3
|
+
import type { Finding } from "./findings.js";
|
|
4
|
+
import type { Decision } from "./plan.js";
|
|
5
|
+
import { type TaskUsage } from "./task-log.js";
|
|
6
|
+
import type { DiffSize, MergeFailure, RemoveReason } from "./worktree.js";
|
|
7
|
+
/**
|
|
8
|
+
* Every task that has ended on this machine, across projects, in
|
|
9
|
+
* `~/.splates/outcomes.jsonl`, oldest first. Unlike the journal it is never
|
|
10
|
+
* trimmed: a trend needs months of it, and a line per task stays small.
|
|
11
|
+
*/
|
|
12
|
+
export declare class Outcomes {
|
|
13
|
+
/** `~/.splates/outcomes.jsonl`, or a test's own. */
|
|
14
|
+
readonly path: string;
|
|
15
|
+
private readonly fs;
|
|
16
|
+
constructor(
|
|
17
|
+
/** `~/.splates/outcomes.jsonl`, or a test's own. */
|
|
18
|
+
path: string, fs: Fs);
|
|
19
|
+
/**
|
|
20
|
+
* Beside `path`, the usage of the turns tasks ended in, which `splates
|
|
21
|
+
* merge` writes its line too early to see. Apart from `path`, so splates
|
|
22
|
+
* versions that read only that never mistake one for a task.
|
|
23
|
+
*/
|
|
24
|
+
get turnsPath(): string;
|
|
25
|
+
record(outcome: Outcome): Promise<void>;
|
|
26
|
+
list(): Promise<Outcome[]>;
|
|
27
|
+
/**
|
|
28
|
+
* Credits the task that `conversation`, logged at `log`, ended last in
|
|
29
|
+
* its turn from `since` to `until` with what the rest of that turn used,
|
|
30
|
+
* once the turn has ended and said it. Several ended in one turn: the
|
|
31
|
+
* last one's is what the turn finished on.
|
|
32
|
+
*/
|
|
33
|
+
creditTurn(conversation: string, log: string, since: string, until: string): Promise<void>;
|
|
34
|
+
private get dir();
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* How one task ended, written as it goes. Its record goes with it, so this is
|
|
38
|
+
* what is left to tell whether tasks are getting easier to land over time.
|
|
39
|
+
*/
|
|
40
|
+
export interface Outcome {
|
|
41
|
+
/** The main tree of the repository the task was in. */
|
|
42
|
+
project: string;
|
|
43
|
+
task: string;
|
|
44
|
+
/** Where it landed or would have: trunk, or `task/<parent>` for a part. */
|
|
45
|
+
base: string;
|
|
46
|
+
ended: "merged" | "removed";
|
|
47
|
+
/** When it was added, as an ISO timestamp. */
|
|
48
|
+
startedAt: string;
|
|
49
|
+
/** When it was merged or removed, as an ISO timestamp. */
|
|
50
|
+
endedAt: string;
|
|
51
|
+
/** How many times it was handed to a person with questions. */
|
|
52
|
+
questionRounds: number;
|
|
53
|
+
/** How many times it was handed to a person to approve. */
|
|
54
|
+
reviewRounds: number;
|
|
55
|
+
/** Merges that failed on a conflict, the gate, or a base that would not move. */
|
|
56
|
+
failedMerges: number;
|
|
57
|
+
/** `failedMerges` by why each failed. Absent from lines written before it was kept. */
|
|
58
|
+
failedMergesBy?: Partial<Record<MergeFailure, number>>;
|
|
59
|
+
/** The questions its plan asked under `## Blocked`. Absent from older lines. */
|
|
60
|
+
questionsAsked?: number;
|
|
61
|
+
/** Of those, the ones that offered a `(chosen)` pick and were answered with a choice. */
|
|
62
|
+
picksAsked?: number;
|
|
63
|
+
/** Of `picksAsked`, those answered with another choice than the agent's. */
|
|
64
|
+
picksOverturned?: number;
|
|
65
|
+
/** Of `picksAsked`, those answered with the agent's choice but with words added. */
|
|
66
|
+
picksAmended?: number;
|
|
67
|
+
/** The calls its plan made without asking, under `## Assumptions` or challenged out of it. Absent from older lines. */
|
|
68
|
+
assumptionsMade?: number;
|
|
69
|
+
/** Of `assumptionsMade`, those the person challenged. */
|
|
70
|
+
assumptionsChallenged?: number;
|
|
71
|
+
/**
|
|
72
|
+
* Each call its plan made, asked or assumed, with its size and what became
|
|
73
|
+
* of it. Absent from older lines, whose calls the counts above alone keep.
|
|
74
|
+
*/
|
|
75
|
+
decisions?: Decision[];
|
|
76
|
+
/** The systems its changed files fall in, by name. Absent from older lines. */
|
|
77
|
+
systems?: string[];
|
|
78
|
+
/** How long it waited on a person, escalated, in milliseconds. Absent from older lines. */
|
|
79
|
+
waitedMs?: number;
|
|
80
|
+
/** Why it was removed, when `splates remove --reason` said; null when merged or unsaid. */
|
|
81
|
+
removedFor?: RemoveReason | null;
|
|
82
|
+
/** For a merge, each commit's message it landed, oldest first. Absent from older lines. */
|
|
83
|
+
commits?: string[];
|
|
84
|
+
/**
|
|
85
|
+
* How many times the person spoke to its conversation from each layout of
|
|
86
|
+
* the page while it ran. Absent from older lines.
|
|
87
|
+
*/
|
|
88
|
+
promptsFrom?: Partial<Record<Device, number>>;
|
|
89
|
+
/**
|
|
90
|
+
* What its own turns used, not the rest of its conversation's, the turn it
|
|
91
|
+
* ended in added from `turnsPath` once `splates server` saw it end. Absent from
|
|
92
|
+
* older lines, for a task with no conversation log to read, and, as read,
|
|
93
|
+
* for one with no tokens out, which never kept the turns that did its work.
|
|
94
|
+
*/
|
|
95
|
+
usage?: TaskUsage;
|
|
96
|
+
/** How long its agent worked, its turns summed, in milliseconds. Absent as `usage` is. */
|
|
97
|
+
workedMs?: number;
|
|
98
|
+
/** What it landed, or for a removed task, what its branch held. Absent from older lines. */
|
|
99
|
+
size?: DiffSize;
|
|
100
|
+
/** What went worse than it could have. Absent from older lines, never read as none. */
|
|
101
|
+
findings?: Finding[];
|
|
102
|
+
/** The `splates server` conversation that ended it; null for an external agent. */
|
|
103
|
+
conversation: string | null;
|
|
104
|
+
/** The agent `splates add --agent` handed it to, if any. */
|
|
105
|
+
agent: string | null;
|
|
106
|
+
/** The model it was handed over with, if any. */
|
|
107
|
+
model: string | null;
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* How many prompts the person said from each layout in the conversation
|
|
111
|
+
* logged at `log`, from `since` to `until`: a conversation can outlive the
|
|
112
|
+
* task, or come to it already under way.
|
|
113
|
+
*/
|
|
114
|
+
export declare function promptsFrom(log: string, fs: Fs, since: string, until: string): Promise<Partial<Record<Device, number>>>;
|
package/package.json
CHANGED
|
@@ -1,6 +1,75 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
2
|
+
"name": "@stringsync/splates",
|
|
3
|
+
"version": "0.0.45",
|
|
4
|
+
"description": "Runs several AI coding agents on one repository at once, each in its own git worktree",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"author": "stringsync LLC",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "git+https://github.com/stringsync/splates.git",
|
|
10
|
+
"directory": "packages/splates"
|
|
11
|
+
},
|
|
12
|
+
"type": "module",
|
|
13
|
+
"imports": {
|
|
14
|
+
"#dev/*": "./dev/*"
|
|
15
|
+
},
|
|
16
|
+
"engines": {
|
|
17
|
+
"bun": ">=1.3"
|
|
18
|
+
},
|
|
19
|
+
"publishConfig": {
|
|
20
|
+
"access": "public"
|
|
21
|
+
},
|
|
22
|
+
"dependencies": {
|
|
23
|
+
"@agentclientprotocol/sdk": "^1.7.0",
|
|
24
|
+
"webappwiz": "^0.0.45",
|
|
25
|
+
"zod": "^4.4.3"
|
|
26
|
+
},
|
|
27
|
+
"main": "./index.js",
|
|
28
|
+
"types": "./index.d.ts",
|
|
29
|
+
"exports": {
|
|
30
|
+
".": {
|
|
31
|
+
"types": "./index.d.ts",
|
|
32
|
+
"default": "./index.js"
|
|
33
|
+
},
|
|
34
|
+
"./asked": {
|
|
35
|
+
"types": "./asked.d.ts",
|
|
36
|
+
"default": "./asked.js"
|
|
37
|
+
},
|
|
38
|
+
"./probe-runtime": {
|
|
39
|
+
"types": "./probe-runtime.d.ts",
|
|
40
|
+
"default": "./probe-runtime.js"
|
|
41
|
+
},
|
|
42
|
+
"./testing/agent": {
|
|
43
|
+
"types": "./fake-agent.d.ts",
|
|
44
|
+
"default": "./fake-agent.js"
|
|
45
|
+
},
|
|
46
|
+
"./config": {
|
|
47
|
+
"types": "./config.d.ts",
|
|
48
|
+
"default": "./config.js"
|
|
49
|
+
},
|
|
50
|
+
"./heavy": {
|
|
51
|
+
"types": "./heavy.d.ts",
|
|
52
|
+
"default": "./heavy.js"
|
|
53
|
+
},
|
|
54
|
+
"./skill-checks": {
|
|
55
|
+
"types": "./skill-checks.d.ts",
|
|
56
|
+
"default": "./skill-checks.js"
|
|
57
|
+
},
|
|
58
|
+
"./systems": {
|
|
59
|
+
"types": "./systems.d.ts",
|
|
60
|
+
"default": "./systems.js"
|
|
61
|
+
},
|
|
62
|
+
"./tunnel-provider": {
|
|
63
|
+
"types": "./tunnel-provider.d.ts",
|
|
64
|
+
"default": "./tunnel-provider.js"
|
|
65
|
+
},
|
|
66
|
+
"./update": {
|
|
67
|
+
"types": "./update.d.ts",
|
|
68
|
+
"default": "./update.js"
|
|
69
|
+
}
|
|
70
|
+
},
|
|
71
|
+
"bin": {
|
|
72
|
+
"splates": "./index.js",
|
|
73
|
+
"arbor": "./index.js"
|
|
74
|
+
}
|
|
75
|
+
}
|
package/path.d.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { Logger } from "webappwiz/log";
|
|
2
|
+
import type { WorktreeService } from "./worktree-service.js";
|
|
3
|
+
/**
|
|
4
|
+
* Where a task lives, or (with no task) the main tree. Nothing but the path
|
|
5
|
+
* on stdout, so it composes: `cd "$(splates path)"`, `zed -a "$(splates path x)"`.
|
|
6
|
+
* Moving between trees is `cd` and nothing else, and the main tree is the one
|
|
7
|
+
* path a process standing in a worktree cannot otherwise name: git's
|
|
8
|
+
* `--show-toplevel` hands back the worktree it is already in.
|
|
9
|
+
*/
|
|
10
|
+
export declare function path({ service, log }: {
|
|
11
|
+
service: WorktreeService;
|
|
12
|
+
log: Logger;
|
|
13
|
+
}, task?: string): Promise<void>;
|
package/plan.d.ts
ADDED
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
import type { Fs } from "webappwiz/system";
|
|
2
|
+
/** The plan each task keeps at its worktree root, excluded from git. */
|
|
3
|
+
export declare const PLAN_FILE = "SPLATES.md";
|
|
4
|
+
/** Where tasks keep their plans: each worktree's `SPLATES.md`, read through `fs`. */
|
|
5
|
+
export declare class Plans {
|
|
6
|
+
private readonly fs;
|
|
7
|
+
constructor(fs: Fs);
|
|
8
|
+
/**
|
|
9
|
+
* The plan in worktree `tree`, or null for none: an agent still on arbor's
|
|
10
|
+
* skill keeps it as `ARBOR.md`, read when there is no `SPLATES.md`.
|
|
11
|
+
*/
|
|
12
|
+
read(tree: string): Promise<string | null>;
|
|
13
|
+
/**
|
|
14
|
+
* Keeps plans out of git in every worktree of the repository whose shared
|
|
15
|
+
* `.git` is `gitDir`, leaving the repo's own .gitignore alone.
|
|
16
|
+
*/
|
|
17
|
+
exclude(gitDir: string): Promise<void>;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* The one step under `## Next` a fresh task's `SPLATES.md` starts with, asking
|
|
21
|
+
* its agent to plan, which no one should read as the work under way.
|
|
22
|
+
*/
|
|
23
|
+
export declare const STUB_STEP = "fill in Goal and list the steps here as `- [ ]` items";
|
|
24
|
+
/**
|
|
25
|
+
* What an `SPLATES.md` says its task is for: the first line under `## Goal`, or
|
|
26
|
+
* null when it says nothing yet. One line, since it sits beside other tasks'
|
|
27
|
+
* in `splates list --files`.
|
|
28
|
+
*/
|
|
29
|
+
export declare function goalLine(text: string): string | null;
|
|
30
|
+
/**
|
|
31
|
+
* What an `SPLATES.md` says done means: all of `## Goal`, as markdown, or ""
|
|
32
|
+
* when it says nothing yet.
|
|
33
|
+
*/
|
|
34
|
+
export declare function goalOf(text: string): string;
|
|
35
|
+
/**
|
|
36
|
+
* One `- [ ] 9.` item under `## Blocked`: something only a person can do.
|
|
37
|
+
* The item's line is its subject; lines indented under it are its body, and
|
|
38
|
+
* `- (a) ...`, `- [a] ...` or `- a. ...` lines among them are the answers it
|
|
39
|
+
* offers.
|
|
40
|
+
*/
|
|
41
|
+
export interface Question {
|
|
42
|
+
/** As the plan numbers it, `9`: the name a reply goes by. */
|
|
43
|
+
number: string;
|
|
44
|
+
/** Checked off, which the agent does once it has acted on the reply. */
|
|
45
|
+
done: boolean;
|
|
46
|
+
/** The item's own line, without its checkbox, number, size or reply. */
|
|
47
|
+
text: string;
|
|
48
|
+
/**
|
|
49
|
+
* How far the call reaches, from the `(large)` that leads its line, one of
|
|
50
|
+
* `SIZES` as the skill writes it; null when it has none.
|
|
51
|
+
*/
|
|
52
|
+
size: string | null;
|
|
53
|
+
/**
|
|
54
|
+
* The markdown indented under it, dedented, choices left out: detail,
|
|
55
|
+
* code blocks, `` images. Empty when there is none.
|
|
56
|
+
*/
|
|
57
|
+
body: string;
|
|
58
|
+
/** Whatever follows ` → `, or null when nobody has answered yet. */
|
|
59
|
+
reply: string | null;
|
|
60
|
+
/**
|
|
61
|
+
* What a person added once the reply was read, oldest first: each an
|
|
62
|
+
* indented `→ ` line under the question.
|
|
63
|
+
*/
|
|
64
|
+
followUps: string[];
|
|
65
|
+
/**
|
|
66
|
+
* The answers it offers, in order. Empty for a question answered in words
|
|
67
|
+
* alone. A reply can always add words to its picks, or answer in words
|
|
68
|
+
* instead.
|
|
69
|
+
*/
|
|
70
|
+
choices: Choice[];
|
|
71
|
+
/**
|
|
72
|
+
* `one` for `- (a)` choices, at most one of which a reply picks; `any` for
|
|
73
|
+
* `- [a]` choices, where it picks all that apply; `order` for `- a.`
|
|
74
|
+
* choices, which a reply puts in order, every one of them, as `b, a, c`.
|
|
75
|
+
* Null without choices.
|
|
76
|
+
*/
|
|
77
|
+
pick: "one" | "any" | "order" | null;
|
|
78
|
+
}
|
|
79
|
+
/** One answer a question offers: `- (b) Migrate on next login`. */
|
|
80
|
+
export interface Choice {
|
|
81
|
+
/** The letter it goes by: `b`. */
|
|
82
|
+
key: string;
|
|
83
|
+
/** What it says, without the `(chosen)` that may end it. */
|
|
84
|
+
text: string;
|
|
85
|
+
/**
|
|
86
|
+
* The markdown indented under it, dedented: most often the screenshot of
|
|
87
|
+
* what it would look like. Empty when there is none.
|
|
88
|
+
*/
|
|
89
|
+
body: string;
|
|
90
|
+
/**
|
|
91
|
+
* Why the agent would go with it, or not: a `Why:` line under it, without
|
|
92
|
+
* the label, kept out of `body`. The page folds
|
|
93
|
+
* it away until asked. Empty when there is none.
|
|
94
|
+
*/
|
|
95
|
+
why: string;
|
|
96
|
+
/**
|
|
97
|
+
* Marked `(chosen)`: what the agent went with while it waits for the reply,
|
|
98
|
+
* which picks nothing for the person.
|
|
99
|
+
*/
|
|
100
|
+
chosen: boolean;
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* How far a call reaches, smallest first, as the skill defines each: small
|
|
104
|
+
* stays local and is cheap to redo, medium shapes a feature or spans
|
|
105
|
+
* systems, large is hard to undo or outward-facing. The one place the scheme
|
|
106
|
+
* lives: outcomes keep each call's size as the word it was written with, so
|
|
107
|
+
* a word dropped from here still reads back from older outcomes.
|
|
108
|
+
*/
|
|
109
|
+
export declare const SIZES: readonly ["small", "medium", "large"];
|
|
110
|
+
/** `text` without the size that leads it, and that size, or null. */
|
|
111
|
+
export declare function sized(text: string): {
|
|
112
|
+
text: string;
|
|
113
|
+
size: string | null;
|
|
114
|
+
};
|
|
115
|
+
/**
|
|
116
|
+
* Every numbered item under `## Blocked`, open or checked off, each with the
|
|
117
|
+
* indented lines under it. The reply is read off the item's own line: an
|
|
118
|
+
* answer is one line after the arrow, which the agent writes in from the
|
|
119
|
+
* user's reply in chat.
|
|
120
|
+
*/
|
|
121
|
+
export declare function questions(text: string): Question[];
|
|
122
|
+
/**
|
|
123
|
+
* Every numbered item under `## Assumptions`: a call the agent made without
|
|
124
|
+
* asking, written as a question is, its `(chosen)` choice the one it took.
|
|
125
|
+
* Numbered in the same sequence as `## Blocked`, since a challenged one moves
|
|
126
|
+
* there under its number. None of them hold up a merge.
|
|
127
|
+
*/
|
|
128
|
+
export declare function assumptions(text: string): Question[];
|
|
129
|
+
/**
|
|
130
|
+
* Adds what `line` offers to `asked`, saying whether it did: an indented
|
|
131
|
+
* `- (a) text` picks one, `- [a] text` picks any, and `- a. text` is put in
|
|
132
|
+
* order, and a line indented past a choice's dash, such as its screenshot,
|
|
133
|
+
* belongs to that choice. The first choice says which for the question. The
|
|
134
|
+
* same in a plan and in a conversation, which `asked.ts` reads with this.
|
|
135
|
+
*/
|
|
136
|
+
export declare function offers(asked: Pick<Question, "choices" | "pick">, line: string): boolean;
|
|
137
|
+
/** `asked` with `body` as its own, and each choice's dedented. */
|
|
138
|
+
export declare function settled(asked: Question, body: string[]): Question;
|
|
139
|
+
/** Lines with the indent they all share taken off, blank ends trimmed. */
|
|
140
|
+
export declare function dedent(lines: string[]): string;
|
|
141
|
+
/**
|
|
142
|
+
* How the person met the agent's picks under `## Blocked`: the questions
|
|
143
|
+
* asked, those that offered a `(chosen)` choice and were answered with a
|
|
144
|
+
* choice, and of those, the ones answered with another, and the ones answered
|
|
145
|
+
* with the agent's choice but with words added, in the reply or a follow-up.
|
|
146
|
+
* A moot question, or one answered in words alone, is asked but picks nothing.
|
|
147
|
+
*/
|
|
148
|
+
export declare function picks(text: string): {
|
|
149
|
+
asked: number;
|
|
150
|
+
picked: number;
|
|
151
|
+
overturned: number;
|
|
152
|
+
amended: number;
|
|
153
|
+
};
|
|
154
|
+
/**
|
|
155
|
+
* One call a plan made, as an outcome keeps it: enough to count how the
|
|
156
|
+
* agent's recommendations fare by size, and to size it again by its line if
|
|
157
|
+
* the scheme changes.
|
|
158
|
+
*/
|
|
159
|
+
export interface Decision {
|
|
160
|
+
/** As the plan numbers it. */
|
|
161
|
+
number: string;
|
|
162
|
+
/** The item's line, without its size. */
|
|
163
|
+
text: string;
|
|
164
|
+
/** The word its line was sized with, or null for none. */
|
|
165
|
+
size: string | null;
|
|
166
|
+
/** Put to the person under `## Blocked`, or made without asking. */
|
|
167
|
+
how: "asked" | "assumed";
|
|
168
|
+
/**
|
|
169
|
+
* What became of the agent's recommendation: an assumption left alone is
|
|
170
|
+
* kept; a pick taken as it was, kept; taken with words added, amended;
|
|
171
|
+
* answered with another choice, overturned; an assumption the person
|
|
172
|
+
* challenged, challenged. Null for a question with no pick to meet, or
|
|
173
|
+
* one never answered with a choice.
|
|
174
|
+
*/
|
|
175
|
+
ended: "kept" | "amended" | "overturned" | "challenged" | null;
|
|
176
|
+
}
|
|
177
|
+
/** Every call in the plan `text`, asked and assumed, in the order numbered. */
|
|
178
|
+
export declare function decisions(text: string): Decision[];
|
|
179
|
+
/**
|
|
180
|
+
* How many calls the agent made without asking, and how many of them the
|
|
181
|
+
* person challenged. A challenged one moves to `## Blocked` under its number
|
|
182
|
+
* with a reply starting `challenged:`, so it counts in both.
|
|
183
|
+
*/
|
|
184
|
+
export declare function assumptionCounts(text: string): {
|
|
185
|
+
made: number;
|
|
186
|
+
challenged: number;
|
|
187
|
+
};
|
|
188
|
+
/** What still stands between a task and trunk, as its plan tells it. */
|
|
189
|
+
export interface Unfinished {
|
|
190
|
+
/** Each unchecked question under `## Blocked`, by number: `["2", "4"]`. */
|
|
191
|
+
questions: string[];
|
|
192
|
+
/** Each unchecked step under `## Next`, as written. */
|
|
193
|
+
steps: string[];
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* The questions and steps a plan leaves unchecked. Nothing in either means the
|
|
197
|
+
* task is ready to merge: `splates merge` lands it, and `splates escalate --review`
|
|
198
|
+
* asks a person to look first. A task with no plan has nothing left.
|
|
199
|
+
*/
|
|
200
|
+
export declare function unfinished(text: string): Unfinished;
|
|
201
|
+
/** Whether {@link unfinished} found nothing left. */
|
|
202
|
+
export declare function ready({ questions, steps }: Unfinished): boolean;
|
|
203
|
+
/** What {@link unfinished} found, as a clause: `questions 1, 2 unchecked under ## Blocked`. */
|
|
204
|
+
export declare function whatIsLeft({ questions, steps }: Unfinished): string;
|
|
205
|
+
/**
|
|
206
|
+
* The plan with a new open question at the end of `## Blocked`, the section
|
|
207
|
+
* made if missing, numbered after the highest there or under
|
|
208
|
+
* `## Assumptions`. Returns the plan and the number it went by.
|
|
209
|
+
*/
|
|
210
|
+
export declare function withQuestion(text: string, subject: string, body?: string): {
|
|
211
|
+
plan: string;
|
|
212
|
+
number: string;
|
|
213
|
+
};
|
|
214
|
+
/**
|
|
215
|
+
* A question's number however a person typed it: `9`, `9.`, `Q9` and `q9:`
|
|
216
|
+
* all mean `9`. Null for anything that is not a number at all.
|
|
217
|
+
*/
|
|
218
|
+
export declare function questionNumber(raw: string): string | null;
|
|
219
|
+
export interface PlanOptions {
|
|
220
|
+
/** The task name the title is expected to match. */
|
|
221
|
+
task: string;
|
|
222
|
+
/**
|
|
223
|
+
* Whether the task has escalated, which makes `## Blocked` required unless
|
|
224
|
+
* it escalated for a review.
|
|
225
|
+
*/
|
|
226
|
+
escalated?: boolean;
|
|
227
|
+
/** Whether the escalation asks only to approve merging. */
|
|
228
|
+
review?: boolean;
|
|
229
|
+
}
|
|
230
|
+
/**
|
|
231
|
+
* Every way a task's `SPLATES.md` departs from the shape the agent skill
|
|
232
|
+
* prescribes, phrased for the agent that wrote it. Advisory only: a resumable
|
|
233
|
+
* plan is the point, and a malformed one still beats none, so nothing here
|
|
234
|
+
* blocks a merge.
|
|
235
|
+
*/
|
|
236
|
+
export declare function checkPlan(text: string, { task, escalated, review }: PlanOptions): string[];
|