@stringsync/splates 0.0.53 → 0.0.55

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 (63) hide show
  1. package/README.md +7 -24
  2. package/artifact.d.ts +3 -0
  3. package/budget.d.ts +3 -0
  4. package/creds.d.ts +3 -0
  5. package/flags.d.ts +37 -0
  6. package/handoff.d.ts +13 -0
  7. package/hook.d.ts +3 -0
  8. package/index.d.ts +2 -0
  9. package/index.js +1844 -0
  10. package/lane.d.ts +3 -0
  11. package/notes.d.ts +4 -0
  12. package/package.json +12 -14
  13. package/projects.d.ts +3 -0
  14. package/queue.d.ts +3 -0
  15. package/replica.d.ts +3 -0
  16. package/runners.d.ts +3 -0
  17. package/server.d.ts +6 -0
  18. package/setup.d.ts +22 -0
  19. package/slots.d.ts +3 -0
  20. package/splates.d.ts +10 -0
  21. package/task.d.ts +3 -0
  22. package/tunnel.d.ts +3 -0
  23. package/waiting.d.ts +3 -0
  24. package/worker.d.ts +3 -0
  25. package/artifact.ts +0 -120
  26. package/budget.ts +0 -117
  27. package/checkout.ts +0 -8
  28. package/creds.test.ts +0 -336
  29. package/creds.ts +0 -144
  30. package/dev/dev.ts +0 -86
  31. package/dev/eval.ts +0 -21
  32. package/dev/fix.ts +0 -63
  33. package/dev/index.ts +0 -1
  34. package/dev/prove.ts +0 -38
  35. package/dev/root.ts +0 -7
  36. package/dev/ship.ts +0 -46
  37. package/dev/test.ts +0 -154
  38. package/e2e.test.ts +0 -472
  39. package/flags.ts +0 -157
  40. package/hook.ts +0 -328
  41. package/index.ts +0 -18
  42. package/infra.ts +0 -107
  43. package/lane.test.ts +0 -29
  44. package/lane.ts +0 -172
  45. package/notes.ts +0 -19
  46. package/projects.test.ts +0 -191
  47. package/projects.ts +0 -37
  48. package/queue.ts +0 -82
  49. package/screenshots/annotate.png +0 -0
  50. package/screenshots/demo.png +0 -0
  51. package/screenshots/parallel.png +0 -0
  52. package/screenshots/questions.png +0 -0
  53. package/server.ts +0 -287
  54. package/setup.ts +0 -233
  55. package/slots.ts +0 -65
  56. package/splates.test.ts +0 -338
  57. package/splates.ts +0 -567
  58. package/task.ts +0 -354
  59. package/tunnel.ts +0 -106
  60. package/wait-journal.test.ts +0 -96
  61. package/waiting.ts +0 -59
  62. package/worker-relay.test.ts +0 -233
  63. package/worker.ts +0 -300
package/lane.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ import type { SplatesDeps } from "@stringsync/splates-server/server";
2
+ /** `splates lane`, which the root cli mounts after `splates task`. */
3
+ export declare const splatesLane: import("webappwiz/cmd").Cli<SplatesDeps, SplatesDeps>;
package/notes.d.ts ADDED
@@ -0,0 +1,4 @@
1
+ import type { Repository } from "@stringsync/splates-server/records";
2
+ import type { SplatesDeps } from "@stringsync/splates-server/server";
3
+ /** Prints the descriptions in this checkout, or the project explicitly named. */
4
+ export declare function notes(ctx: SplatesDeps & Repository): Promise<void>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stringsync/splates",
3
- "version": "0.0.53",
3
+ "version": "0.0.55",
4
4
  "description": "Runs several AI coding agents on one repository at once, each in its own git worktree",
5
5
  "license": "MIT",
6
6
  "author": "stringsync LLC",
@@ -10,14 +10,6 @@
10
10
  "directory": "packages/splates"
11
11
  },
12
12
  "type": "module",
13
- "module": "index.ts",
14
- "bin": {
15
- "splates": "./index.ts",
16
- "arbor": "./index.ts"
17
- },
18
- "exports": {
19
- ".": "./index.ts"
20
- },
21
13
  "engines": {
22
14
  "bun": ">=1.3"
23
15
  },
@@ -25,14 +17,20 @@
25
17
  "access": "public"
26
18
  },
27
19
  "dependencies": {
28
- "@stringsync/splates-server": "workspace:*",
20
+ "@stringsync/splates-server": "^0.0.55",
29
21
  "webappwiz": "0.0.47",
30
22
  "zod": "^4.4.3"
31
23
  },
32
- "devDependencies": {
33
- "@types/bun": "1.3.14"
24
+ "main": "./index.js",
25
+ "types": "./index.d.ts",
26
+ "exports": {
27
+ ".": {
28
+ "types": "./index.d.ts",
29
+ "default": "./index.js"
30
+ }
34
31
  },
35
- "scripts": {
36
- "build": "bun run --cwd ../web build"
32
+ "bin": {
33
+ "splates": "./index.js",
34
+ "arbor": "./index.js"
37
35
  }
38
36
  }
package/projects.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ import type { SplatesDeps } from "@stringsync/splates-server/server";
2
+ /** `splates projects`, which the root cli mounts after `splates lane`. */
3
+ export declare const splatesProjects: import("webappwiz/cmd").Cli<SplatesDeps, SplatesDeps>;
package/queue.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ import type { SplatesDeps } from "@stringsync/splates-server/server";
2
+ /** `splates queue`, which the root cli mounts beside `splates task`. */
3
+ export declare const splatesQueue: import("webappwiz/cmd").Cli<SplatesDeps, SplatesDeps>;
package/replica.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ import type { SplatesDeps } from "@stringsync/splates-server/server";
2
+ /** `splates replica`, which the root cli mounts after `splates budget`. */
3
+ export declare const splatesReplica: import("webappwiz/cmd").Cli<SplatesDeps, SplatesDeps>;
package/runners.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ import { type SplatesDeps } from "@stringsync/splates-server/server";
2
+ /** `splates runners`, which the root cli mounts beside `splates worker`. */
3
+ export declare const splatesRunners: import("webappwiz/cmd").Cli<SplatesDeps, SplatesDeps>;
package/server.d.ts ADDED
@@ -0,0 +1,6 @@
1
+ import { type SplatesDeps } from "@stringsync/splates-server/server";
2
+ /**
3
+ * `splates server`, which the root cli mounts after `splates log`: bare, it
4
+ * runs the server here.
5
+ */
6
+ export declare const splatesServer: import("webappwiz/cmd").Cli<SplatesDeps, SplatesDeps>;
package/setup.d.ts ADDED
@@ -0,0 +1,22 @@
1
+ import type { SplatesDeps } from "@stringsync/splates-server/server";
2
+ import { Setup } from "@stringsync/splates-server/setup";
3
+ /** What `splates setup` was asked for. */
4
+ export interface SetupOptions {
5
+ /** A step's id, or empty for every area's progress. */
6
+ step: string;
7
+ json: boolean;
8
+ skip: boolean;
9
+ unskip: boolean;
10
+ /** Print what undoing the area `step` names would do. */
11
+ undo: boolean;
12
+ }
13
+ /**
14
+ * `splates setup [step]`: progress by area and the one next step, or one step's
15
+ * why and instructions, after skipping or unskipping it when asked.
16
+ */
17
+ export declare function setup(deps: SplatesDeps, opts: SetupOptions): Promise<void>;
18
+ /**
19
+ * This machine's setup, read through `deps`, for the project `--project`
20
+ * names or the repository the working directory is in, if either.
21
+ */
22
+ export declare function setupOf(deps: SplatesDeps): Promise<Setup>;
package/slots.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ import type { SplatesDeps } from "@stringsync/splates-server/server";
2
+ /** `splates slots`, which the root cli mounts after `splates tunnel`. */
3
+ export declare const splatesSlots: import("webappwiz/cmd").Cli<SplatesDeps, SplatesDeps>;
package/splates.d.ts ADDED
@@ -0,0 +1,10 @@
1
+ import type { SplatesDeps } from "@stringsync/splates-server/server";
2
+ /**
3
+ * Splits a leading `--project <slug>`, or `--project=<slug>`, off the
4
+ * arguments, for `run` to be handed as `project`.
5
+ */
6
+ export declare function projectArgs(argv: string[]): {
7
+ project?: string;
8
+ argv: string[];
9
+ };
10
+ export declare const splates: import("webappwiz/cmd").Cli<SplatesDeps, SplatesDeps>;
package/task.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ import type { SplatesDeps } from "@stringsync/splates-server/server";
2
+ /** `splates task`, the queue, which the root cli mounts after the commands for the task you work on. */
3
+ export declare const splatesTask: import("webappwiz/cmd").Cli<SplatesDeps, SplatesDeps>;
package/tunnel.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ import type { SplatesDeps } from "@stringsync/splates-server/server";
2
+ /** `splates tunnel`, which the root cli mounts after `splates lane`. */
3
+ export declare const splatesTunnel: import("webappwiz/cmd").Cli<SplatesDeps, SplatesDeps>;
package/waiting.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ import type { SplatesDeps } from "@stringsync/splates-server/server";
2
+ /** `splates worker queue`, which `splates worker` mounts. */
3
+ export declare const splatesWaiting: import("webappwiz/cmd").Cli<SplatesDeps, SplatesDeps>;
package/worker.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ import type { SplatesDeps } from "@stringsync/splates-server/server";
2
+ /** `splates worker`, which the root cli mounts after `splates slots`. */
3
+ export declare const splatesWorker: import("webappwiz/cmd").Cli<SplatesDeps, SplatesDeps>;
package/artifact.ts DELETED
@@ -1,120 +0,0 @@
1
- import { basename, resolve } from "node:path";
2
- import {
3
- addArtifact,
4
- listArtifacts,
5
- removeArtifact,
6
- } from "@stringsync/splates-server/artifacts";
7
- import { commaList } from "@stringsync/splates-server/comma-list";
8
- import { conversationOf } from "@stringsync/splates-server/conversations";
9
- import { fail } from "@stringsync/splates-server/exit";
10
- import { repository } from "@stringsync/splates-server/records";
11
- import type { SplatesDeps } from "@stringsync/splates-server/server";
12
- import { cli } from "webappwiz/cmd";
13
- import { z } from "zod";
14
- import { here } from "./flags";
15
-
16
- /** `splates artifact`, which the root cli mounts after `splates attach`. */
17
- export const splatesArtifact = cli<SplatesDeps>("artifact").description(
18
- "files your conversation made as its outputs, such as a screenshot, a recording or an HTML page: kept by name for the life of the conversation, whatever task it was made in, and listed on the `splates server` page beside its thread. A file that shows a question or a demo step is no artifact: `splates attach` it. The conversation is $SPLATES_CONVERSATION, or --conversation <id> from an agent outside `splates server`",
19
- );
20
-
21
- const conversation = [
22
- "conversation",
23
- z.string(),
24
- {
25
- default: "",
26
- description:
27
- "conversation id, when not run by an agent `splates server` started",
28
- },
29
- ] as const;
30
-
31
- splatesArtifact
32
- .command("add")
33
- .use(repository({ needs: "own" }))
34
- .description(
35
- "keep files as artifacts of this conversation, each named for its basename, or by --name when there is one; adding a name the conversation holds makes its next version, earlier ones kept until cleanup takes them. Past the project's limit (artifactProjectCapacity), `splates server` first evicts the oldest bytes the project keeps: removed and replaced versions, then what archived conversations show, then what live ones do. Past the file or conversation limit (artifactFileCapacity, artifactConversationCapacity), or the project's when even that would not make room, it stops with `too_large`, changing nothing for that file",
36
- )
37
- .arg("files", z.string(), { description: "files to keep, comma separated" })
38
- .option("name", z.string(), {
39
- default: "",
40
- description: "the artifact's name; for one file only",
41
- })
42
- .option(...conversation)
43
- .action(async (opts, ctx) => {
44
- const paths = commaList(opts.files);
45
- if (paths.length === 0) {
46
- fail("usage", "name the files to keep: nothing was changed");
47
- }
48
- if (opts.name !== "" && paths.length > 1) {
49
- fail("usage", "--name names one file: nothing was changed");
50
- }
51
- const id = await conversationOf(ctx.service, opts.conversation);
52
- const files = await Promise.all(
53
- paths.map(async (given) => {
54
- const path = resolve(ctx.ps.cwd(), given);
55
- const bytes = await ctx.fs.readBytes(path).catch(() => null);
56
- if (bytes === null) {
57
- fail("usage", `cannot read ${path}: nothing was changed`, {
58
- file: path,
59
- });
60
- }
61
- return { name: opts.name || basename(path), bytes };
62
- }),
63
- );
64
- const task = await here(ctx);
65
- for (const file of files) {
66
- await ctx.journal.record(
67
- "artifact add",
68
- task,
69
- () => addArtifact(ctx, id, file),
70
- (added) => ({
71
- name: file.name,
72
- version: added.version,
73
- bytes: added.bytes,
74
- }),
75
- );
76
- }
77
- });
78
-
79
- splatesArtifact
80
- .command("remove")
81
- .use(repository({ needs: "own" }))
82
- .description(
83
- "stop listing the artifact of that name, every version kept until cleanup takes them; adding the name again lists it again",
84
- )
85
- .arg("name", z.string(), { description: "the artifact's name" })
86
- .option(...conversation)
87
- .action(async (opts, ctx) => {
88
- const id = await conversationOf(ctx.service, opts.conversation);
89
- await ctx.journal.record(
90
- "artifact remove",
91
- await here(ctx),
92
- () => removeArtifact(ctx, id, opts.name),
93
- (version) => ({ name: opts.name, version }),
94
- );
95
- });
96
-
97
- splatesArtifact
98
- .command("list")
99
- .use(repository({ needs: "own" }))
100
- .description(
101
- "the artifacts this conversation lists, and their current version",
102
- )
103
- .option(...conversation)
104
- .action(async (opts, ctx) =>
105
- listArtifacts(ctx, await conversationOf(ctx.service, opts.conversation)),
106
- );
107
-
108
- splatesArtifact
109
- .command("show")
110
- .use(repository({ needs: "own" }))
111
- .description("every version of an artifact, and which is current")
112
- .arg("name", z.string(), { description: "the artifact's name" })
113
- .option(...conversation)
114
- .action(async (opts, ctx) =>
115
- listArtifacts(
116
- ctx,
117
- await conversationOf(ctx.service, opts.conversation),
118
- opts.name,
119
- ),
120
- );
package/budget.ts DELETED
@@ -1,117 +0,0 @@
1
- import type { SplatesDeps } from "@stringsync/splates-server/server";
2
- import {
3
- endBudgetRaise,
4
- raiseBudget,
5
- setBudget,
6
- showBudget,
7
- } from "@stringsync/splates-server/workers";
8
- import { cli } from "webappwiz/cmd";
9
- import { z } from "zod";
10
-
11
- const DEV = {
12
- default: "",
13
- description:
14
- "the `splates server` to ask, a URL such as http://localhost:4310; by default the one an agent runs under, from SPLATES_DEV",
15
- };
16
-
17
- const JSON_OPTION = { default: false, description: "emit JSON" };
18
-
19
- const LIMIT = z.enum(["hour", "day", "month"]);
20
-
21
- const LIMIT_ARG = {
22
- description:
23
- "hour, the rate cap on what made workers running at once cost an hour; day; or month",
24
- };
25
-
26
- /** `splates budget`, which the root cli mounts beside `splates worker`. */
27
- export const splatesBudget = cli<SplatesDeps>("budget").description(
28
- "what the workers a `workerProvider` makes may cost, in dollars: a rate cap per hour on those running at once ($0.25/h by default), and limits on a day ($5) and a month ($75). Past the rate cap, or once a day's or month's limit is spent, no worker is made and the queue says why; reaching the day's or month's stops made workers, whose agents stop at their checkpoint. Each warns at 80%, 90% and 100% by Web Push and on the page's header. Spend is an estimate at each type's list price. Agents' own API spend is not counted here",
29
- );
30
-
31
- splatesBudget
32
- .command("show")
33
- .description(
34
- "show each limit: what made workers spent in its window, of how much, and what is left",
35
- )
36
- .option("dev", z.string(), DEV)
37
- .option("json", z.boolean(), JSON_OPTION)
38
- .action((opts, ctx) =>
39
- showBudget({
40
- dev: opts.dev,
41
- json: opts.json,
42
- log: ctx.log,
43
- fs: ctx.fs,
44
- ps: ctx.ps,
45
- send: ctx.fetch,
46
- }),
47
- );
48
-
49
- splatesBudget
50
- .command("set")
51
- .description(
52
- "set a limit, in dollars (dollars an hour for hour), then show the budget",
53
- )
54
- .arg("limit", LIMIT, LIMIT_ARG)
55
- .arg("dollars", z.string(), {
56
- description: "like 5 or 0.25, or `default` to give it back to its default",
57
- })
58
- .option("dev", z.string(), DEV)
59
- .option("json", z.boolean(), JSON_OPTION)
60
- .action((opts, ctx) =>
61
- setBudget({
62
- limit: opts.limit,
63
- dollars: opts.dollars,
64
- dev: opts.dev,
65
- json: opts.json,
66
- log: ctx.log,
67
- fs: ctx.fs,
68
- ps: ctx.ps,
69
- send: ctx.fetch,
70
- }),
71
- );
72
-
73
- splatesBudget
74
- .command("raise")
75
- .description(
76
- "add dollars to a limit for a while, on top of what it is set to, then show the budget",
77
- )
78
- .arg("limit", LIMIT, LIMIT_ARG)
79
- .arg("dollars", z.string(), { description: "how much to add, like 2 or 0.1" })
80
- .option("for", z.string(), {
81
- default: "1d",
82
- description:
83
- "how long it lasts, in hours, days or weeks, like 24h, 1d or 2w",
84
- })
85
- .option("dev", z.string(), DEV)
86
- .option("json", z.boolean(), JSON_OPTION)
87
- .action((opts, ctx) =>
88
- raiseBudget({
89
- limit: opts.limit,
90
- dollars: opts.dollars,
91
- for: opts.for,
92
- dev: opts.dev,
93
- json: opts.json,
94
- log: ctx.log,
95
- fs: ctx.fs,
96
- ps: ctx.ps,
97
- send: ctx.fetch,
98
- }),
99
- );
100
-
101
- splatesBudget
102
- .command("end")
103
- .description("end a raise now, by the number `show` gives it")
104
- .arg("id", z.coerce.number().int(), { description: "the raise's number" })
105
- .option("dev", z.string(), DEV)
106
- .option("json", z.boolean(), JSON_OPTION)
107
- .action((opts, ctx) =>
108
- endBudgetRaise({
109
- id: opts.id,
110
- dev: opts.dev,
111
- json: opts.json,
112
- log: ctx.log,
113
- fs: ctx.fs,
114
- ps: ctx.ps,
115
- send: ctx.fetch,
116
- }),
117
- );
package/checkout.ts DELETED
@@ -1,8 +0,0 @@
1
- // What `bin/splates` runs from a checkout: the published program with `dev`
2
- // mounted, the commands for working on this repository. No `bin` or `exports`
3
- // entry names this file, so a release bundles none of it.
4
- import { mountDev } from "./dev";
5
- import { splates } from "./splates";
6
-
7
- mountDev(splates);
8
- await import("./index");