@stringsync/splates 0.0.47 → 0.0.51

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/README.md CHANGED
@@ -13,6 +13,10 @@ Run it in your repository and commit what it writes: the splates skill, which it
13
13
  installs with [`skills`](https://skills.sh) from this release's tag into
14
14
  `.agents/skills` for Codex and most agents, linked from `.claude/skills` for
15
15
  Claude Code, and `skills-lock.json`. `splates update` moves it to a newer release.
16
+ A release that keeps its records under `.git/splates` differently moves them
17
+ over as `splates server` starts, or as `splates update` runs, backing them up
18
+ first and putting them back if a step fails; the page then shows what failed,
19
+ with a way to retry or to start an agent that fixes it.
16
20
  Without splates, `bunx skills add stringsync/splates#v<release> --skill splates`
17
21
  installs the same skill. From then on, your agents start each change with
18
22
  `splates add` and land it with `splates merge`.
@@ -42,9 +46,19 @@ and is absent from the published CLI.
42
46
  removes the worktree. A conflict or a failing check goes back to the agent that
43
47
  made the change, which fixes it and merges again. A check that writes a JUnit
44
48
  XML report to `$SPLATES_TEST_REPORT` (`bun test --reporter=junit
45
- --reporter-outfile="$SPLATES_TEST_REPORT"`) gets a todo for each test slower
49
+ --reporter-outfile="$SPLATES_TEST_REPORT"`) queues a task for each test slower
46
50
  than 5 seconds.
47
51
 
52
+ **Project notes.** Keep durable conventions, decisions and other project context
53
+ as short Markdown files in `notes/`, one thing per file, edited in place.
54
+ Each starts with frontmatter such as `description: Why releases use explicit exports`
55
+ between `---` lines. `splates notes` prints those descriptions in filename
56
+ order, one per line; a missing directory prints nothing successfully. Read
57
+ the files directly or search them with `rg`. Set `notesDir: "docs/context"`
58
+ in `splates.config.ts` to move the directory, relative to the checkout root
59
+ or to an absolute path. Notes change through tasks, just as code does.
60
+ Keep sensitive information out of them.
61
+
48
62
  **Heavy jobs.** Hooks (`postCheckout`, `postRewrite`, `preMerge`) run in one
49
63
  of the machine's heavy-job slots, two by default (`SPLATES_HEAVY_JOBS` sets
50
64
  how many), so several agents testing at once queue rather than run the
@@ -53,7 +67,7 @@ heavy, such as a test suite an agent runs mid-task, in a slot too.
53
67
 
54
68
  **Pushing.** With `remote: "origin"` in `splates.config.ts`, each task's
55
69
  branch goes to that remote as `splates/<task>`: after every commit an agent
56
- makes under `splates server`, at `splates checkpoint`, escalation and handoff,
70
+ makes under `splates server`, at `splates checkpoint` and handoff,
57
71
  and it is deleted once the task merges or is removed. `splates checkpoint`
58
72
  commits uncommitted work first, as a `WIP: checkpoint` commit squashed before
59
73
  merging. A branch that tracks `SPLATES.md` is never pushed or merged. With the
@@ -107,10 +121,10 @@ step checked against GitHub:
107
121
 
108
122
  4. `github-push`: add `remote: "origin"` to `splates.config.ts` and merge it.
109
123
 
110
- **Escalating.** When an agent needs you (a decision, access, a review, or
111
- merges that keep failing), it runs `splates escalate`: it stops, leaves its
112
- worktree as it is, and writes down its questions. You answer, and it picks up
113
- where it left off.
124
+ **Questions.** When an agent needs you (a decision, access, a review, or
125
+ merges that keep failing), it writes its questions under `## Blocked` in the
126
+ task's `SPLATES.md`, asks them in its reply and ends its turn, leaving its
127
+ worktree as it is. You answer, and it picks up where it left off.
114
128
 
115
129
  ## The harness
116
130
 
@@ -239,9 +253,26 @@ serving on this machine.
239
253
 
240
254
  ### Worker providers
241
255
 
242
- To have splates make workers when agents queue for want of a slot, give
243
- `splates.config.ts`, in the repo `splates server` starts in, a
244
- `workerProvider`, any object that implements `WorkerProvider`:
256
+ To have splates make workers when agents queue for want of a slot, name the
257
+ cloud account to make them in as `splates.config.ts`'s `cloud`, in the repo
258
+ `splates server` starts in:
259
+
260
+ ```ts
261
+ import { AwsCloud } from "@stringsync/splates-server/cloud";
262
+ import type { ConfigFile } from "@stringsync/splates-server/config";
263
+
264
+ export default { cloud: new AwsCloud() } satisfies ConfigFile;
265
+ ```
266
+
267
+ `AwsCloud` comes with splates, signed with the AWS CLI's sign-in or the
268
+ instance role. Another is a class that implements
269
+ `CloudProvider` from `@stringsync/splates-server/cloud`: making, listing and
270
+ deleting tagged machines, snapshots, SSH keys and firewalls through the
271
+ cloud's API, with its machine types and prices. splates makes both the
272
+ workers and the coordinator's box (`splates server deploy`) over it.
273
+
274
+ For machines that are not a cloud's, give it a `workerProvider` instead, any
275
+ object that implements `WorkerProvider`:
245
276
 
246
277
  ```ts
247
278
  import type { ConfigFile } from "@stringsync/splates-server/config";
@@ -387,6 +418,18 @@ test was run. See [the experiment plan](../../designs/opencode-acp.md) for opt-i
387
418
  provider restrictions, and the separate paid-overflow control. Fixture checks
388
419
  never establish account entitlement or remaining quota.
389
420
 
421
+ ### Task cost at API list price
422
+
423
+ Claude says what each session would cost at API rates, and a task's cost is
424
+ that. Codex says no cost, and OpenCode's is its plan's, so for those two splates
425
+ prices each turn's tokens at the public API list price of the model it ran on,
426
+ from [models.dev](https://models.dev), the catalog OpenCode prices models by.
427
+ It keeps a copy in `~/.splates/prices.json`, fetched again once a day, and
428
+ prices a turn at a model's long-context rate once the turn's context passed it.
429
+ The merged card marks such a cost "at API list price". It is an estimate: a
430
+ turn cut short before the agent said its tokens counts nothing, and OpenCode's
431
+ counts leave out its subagents.
432
+
390
433
  ### OpenCode experiment usage
391
434
 
392
435
  OpenCode's Usage popover shows the last dispatched requested/confirmed full model
@@ -395,7 +438,9 @@ counts. Missing fields read **Unknown**, including optional cache counts. Report
395
438
  USD cost is a cumulative session observation, separate from unknown additional
396
439
  charges; it is not a subscription invoice. Quota and mixed-model remaining
397
440
  allowance stay unknown: consult OpenCode Console and keep **Use balance** disabled.
398
- Legacy task cost/token aggregates exclude these differently scoped observations.
441
+ A task's cost on its merged card and the Stats page prices these per-turn tokens
442
+ at each confirmed model's API list price instead, as it does Codex's (see Task
443
+ cost at API list price).
399
444
 
400
445
  See [the manual comparison recipe](../../designs/opencode-acp.md#354-implementation-and-manual-comparison-record)
401
446
  for identical baseline files, a results worksheet, provenance and the authorization
package/flags.d.ts CHANGED
@@ -3,7 +3,7 @@ import type { Repository } from "@stringsync/splates-server/records";
3
3
  import type { SplatesDeps } from "@stringsync/splates-server/server";
4
4
  import { SavedTunnel } from "@stringsync/splates-server/tunnel";
5
5
  import { z } from "zod";
6
- /** A place in the todo list, 1 at the top; absent leaves it to the command. */
6
+ /** A place in the queue, 1 at the top; absent leaves it to the command. */
7
7
  export declare const position: z.ZodOptional<z.ZodCoercedNumber<unknown>>;
8
8
  /**
9
9
  * The agent `--agent`, `--model` and `--effort` name off the roster:
@@ -28,10 +28,10 @@ export declare function offeredOf({ ps, fs }: SplatesDeps): Offered;
28
28
  export declare function slotTunnelsOf({ ps, fs, secrets, }: SplatesDeps): SavedTunnel[];
29
29
  /** `--lane 3`, `new` or `none` as a lane; absent leaves it to the command. */
30
30
  export declare function laneIn(raw: string): number | "new" | null | undefined;
31
- /** `--todo 3,5` as ids, refusing anything that is not one. */
32
- export declare function todoIds(raw: string): number[];
31
+ /** `--task 3,5` as task numbers, refusing anything that is not one. */
32
+ export declare function taskIds(raw: string): number[];
33
33
  /**
34
34
  * Which task a command that takes no task name is about, so the journal can
35
- * name it. `merge` and `escalate` read it off the current branch.
35
+ * name it. `merge` reads it off the current branch.
36
36
  */
37
37
  export declare function here({ service, git, ps, project, }: SplatesDeps & Repository): Promise<string | null>;
package/hook.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ import type { SplatesDeps } from "@stringsync/splates-server/server";
2
+ /** `splates hook`, which the root cli mounts beside `splates queue`. */
3
+ export declare const splatesHook: import("webappwiz/cmd").Cli<SplatesDeps, SplatesDeps>;