@webappwiz/arbor 0.0.30 → 0.0.31
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/add.d.ts +23 -0
- package/age.d.ts +2 -0
- package/arbor.d.ts +11 -0
- package/attachments.d.ts +36 -0
- package/claim.d.ts +11 -0
- package/config.d.ts +55 -0
- package/config.js +7 -0
- package/dev/assets.d.ts +11 -0
- package/dev.d.ts +48 -0
- package/escalate.d.ts +28 -0
- package/exit.d.ts +42 -0
- package/git.d.ts +77 -0
- package/index.d.ts +2 -0
- package/index.js +4712 -0
- package/journal.d.ts +29 -0
- package/list.d.ts +18 -0
- package/load-config.d.ts +15 -0
- package/log.d.ts +14 -0
- package/merge.d.ts +24 -0
- package/package.json +15 -32
- package/path.d.ts +13 -0
- package/plan.d.ts +83 -0
- package/remove.d.ts +19 -0
- package/repository.d.ts +25 -0
- package/retry.d.ts +17 -0
- package/shell.d.ts +17 -0
- package/show.d.ts +53 -0
- package/snapshot.d.ts +35 -0
- package/table.d.ts +5 -0
- package/todo.d.ts +264 -0
- package/wait.d.ts +22 -0
- package/worktree-service.d.ts +51 -0
- package/worktree.d.ts +95 -0
- package/AGENTS.md +0 -7
- package/add.test.ts +0 -125
- package/add.ts +0 -192
- package/age.ts +0 -11
- package/arbor.test.ts +0 -145
- package/arbor.ts +0 -429
- package/assets.d.ts +0 -9
- package/attachments.ts +0 -87
- package/build.ts +0 -98
- package/claim.test.ts +0 -89
- package/claim.ts +0 -73
- package/components.json +0 -21
- package/config.ts +0 -58
- package/dev/api.ts +0 -120
- package/dev/app.test.tsx +0 -645
- package/dev/app.tsx +0 -80
- package/dev/assets.ts +0 -16
- package/dev/build/main.txt +0 -68
- package/dev/build/shell.txt +0 -21
- package/dev/build/styles.txt +0 -2263
- package/dev/components/ui/badge.tsx +0 -51
- package/dev/components/ui/button.tsx +0 -57
- package/dev/components/ui/dialog.tsx +0 -154
- package/dev/components/ui/empty.tsx +0 -100
- package/dev/components/ui/input-group.tsx +0 -155
- package/dev/components/ui/input.tsx +0 -19
- package/dev/components/ui/progress.tsx +0 -80
- package/dev/components/ui/textarea.tsx +0 -17
- package/dev/components/ui/toast.tsx +0 -227
- package/dev/feed.ts +0 -69
- package/dev/files.tsx +0 -191
- package/dev/index.html +0 -21
- package/dev/lib/utils.ts +0 -7
- package/dev/main.tsx +0 -22
- package/dev/markdown.test.tsx +0 -133
- package/dev/markdown.tsx +0 -124
- package/dev/mentions.tsx +0 -319
- package/dev/shadcn.css +0 -649
- package/dev/styles.css +0 -107
- package/dev/tags.tsx +0 -44
- package/dev/tasks.tsx +0 -151
- package/dev/todos.tsx +0 -759
- package/dev.test.ts +0 -439
- package/dev.ts +0 -386
- package/e2e.test.ts +0 -256
- package/escalate.test.ts +0 -76
- package/escalate.ts +0 -112
- package/exit.test.ts +0 -71
- package/exit.ts +0 -74
- package/git.ts +0 -294
- package/index.ts +0 -9
- package/journal.ts +0 -89
- package/list.test.ts +0 -82
- package/list.ts +0 -137
- package/load-config.test.ts +0 -121
- package/load-config.ts +0 -62
- package/log.test.ts +0 -65
- package/log.ts +0 -40
- package/merge.test.ts +0 -332
- package/merge.ts +0 -283
- package/path.test.ts +0 -35
- package/path.ts +0 -38
- package/plan.test.ts +0 -318
- package/plan.ts +0 -302
- package/progress.test.ts +0 -54
- package/progress.ts +0 -31
- package/remove.test.ts +0 -68
- package/remove.ts +0 -88
- package/repository.ts +0 -83
- package/retry.test.ts +0 -43
- package/retry.ts +0 -48
- package/shell.ts +0 -44
- package/show.test.ts +0 -91
- package/show.ts +0 -151
- package/snapshot.test.ts +0 -33
- package/snapshot.ts +0 -84
- package/table.ts +0 -20
- package/testing.ts +0 -229
- package/todo.test.ts +0 -490
- package/todo.ts +0 -834
- package/wait.test.ts +0 -61
- package/wait.ts +0 -77
- package/worktree-service.test.ts +0 -158
- package/worktree-service.ts +0 -193
- package/worktree.ts +0 -239
package/journal.d.ts
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { type Fs } from "webappwiz/system";
|
|
2
|
+
/** One thing that was done to a task, and how it went. */
|
|
3
|
+
export interface Entry {
|
|
4
|
+
at: string;
|
|
5
|
+
action: string;
|
|
6
|
+
/** The task it was about, or null when the command names none. */
|
|
7
|
+
task: string | null;
|
|
8
|
+
/** The refusal reason, or null when the command succeeded. */
|
|
9
|
+
reason: string | null;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* What has been done in this repo, oldest first. Entries outlive their tasks:
|
|
13
|
+
* `merge` and `remove` take the record with them, so this is the only thing that
|
|
14
|
+
* remembers a task existed at all.
|
|
15
|
+
*/
|
|
16
|
+
/** What a `Journal` is stored through; the real filesystem by default. */
|
|
17
|
+
export interface JournalOptions {
|
|
18
|
+
fs?: Fs;
|
|
19
|
+
}
|
|
20
|
+
export declare class Journal {
|
|
21
|
+
private readonly path;
|
|
22
|
+
private readonly capacity;
|
|
23
|
+
private readonly fs;
|
|
24
|
+
constructor(path: string, capacity: number, opts?: JournalOptions);
|
|
25
|
+
record<T>(action: string, task: string | null, run: () => Promise<T>): Promise<T>;
|
|
26
|
+
tail(count: number): Promise<Entry[]>;
|
|
27
|
+
private append;
|
|
28
|
+
private entries;
|
|
29
|
+
}
|
package/list.d.ts
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { type Logger } from "webappwiz/log";
|
|
2
|
+
import type { Fs } from "webappwiz/system";
|
|
3
|
+
import type { WorktreeService } from "./worktree-service.js";
|
|
4
|
+
export interface ListOptions {
|
|
5
|
+
/** Print the rows as JSON instead of a table. */
|
|
6
|
+
json?: boolean;
|
|
7
|
+
/**
|
|
8
|
+
* Add each task's changed and planned files, which is what an agent checks
|
|
9
|
+
* its own plan against before starting. Off by default: it costs git calls
|
|
10
|
+
* and a file read per task.
|
|
11
|
+
*/
|
|
12
|
+
files?: boolean;
|
|
13
|
+
}
|
|
14
|
+
export declare function list({ service, log, fs }: {
|
|
15
|
+
service: WorktreeService;
|
|
16
|
+
log: Logger;
|
|
17
|
+
fs: Fs;
|
|
18
|
+
}, { json, files }?: ListOptions): Promise<void>;
|
package/load-config.d.ts
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { type Fs } from "webappwiz/system";
|
|
2
|
+
import type { Config } from "./config.js";
|
|
3
|
+
import { Git } from "./git.js";
|
|
4
|
+
export interface LoadConfigOptions {
|
|
5
|
+
/** What `arbor.config.ts` is looked for through; the real one by default. */
|
|
6
|
+
fs?: Fs;
|
|
7
|
+
/** What the trunk is detected through; the repo's own git by default. */
|
|
8
|
+
git?: Git;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* The settings arbor runs a repo with: what `arbor.config.ts` names, then the
|
|
12
|
+
* branch `origin/HEAD` points at for the trunk, then arbor's own defaults.
|
|
13
|
+
* Throws when the config file is there but cannot be imported.
|
|
14
|
+
*/
|
|
15
|
+
export declare function loadConfig(root: string, opts?: LoadConfigOptions): Promise<Config>;
|
package/log.d.ts
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { type Logger } from "webappwiz/log";
|
|
2
|
+
import type { Journal } from "./journal.js";
|
|
3
|
+
/** Enough to cover a session's worth of work without scrolling. */
|
|
4
|
+
export declare const DEFAULT_COUNT = 20;
|
|
5
|
+
export interface LogOptions {
|
|
6
|
+
/** How many of the most recent entries to show. */
|
|
7
|
+
count?: number;
|
|
8
|
+
/** Print the entries as JSON instead of a table. */
|
|
9
|
+
json?: boolean;
|
|
10
|
+
}
|
|
11
|
+
export declare function log({ journal, log }: {
|
|
12
|
+
journal: Journal;
|
|
13
|
+
log: Logger;
|
|
14
|
+
}, { count, json }?: LogOptions): Promise<void>;
|
package/merge.d.ts
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { type Logger } from "webappwiz/log";
|
|
2
|
+
import type { Fs, Lock } from "webappwiz/system";
|
|
3
|
+
import type { Config } from "./config.js";
|
|
4
|
+
import type { Git } from "./git.js";
|
|
5
|
+
import type { Shell } from "./shell.js";
|
|
6
|
+
import { type Todos } from "./todo.js";
|
|
7
|
+
import type { WorktreeService } from "./worktree-service.js";
|
|
8
|
+
/**
|
|
9
|
+
* Lands the current worktree's branch on its base branch, trunk unless the
|
|
10
|
+
* task was created with `--base`. Never a merge commit: it rebases onto the
|
|
11
|
+
* base, runs the gate there, and fast-forwards the base with
|
|
12
|
+
* `git merge --ff-only`, in whichever worktree has the base checked out.
|
|
13
|
+
* History stays linear.
|
|
14
|
+
*/
|
|
15
|
+
export declare function merge({ service, git, lock, shell, config, log, todos, fs, }: {
|
|
16
|
+
service: WorktreeService;
|
|
17
|
+
git: Git;
|
|
18
|
+
lock: Lock;
|
|
19
|
+
shell: Shell;
|
|
20
|
+
config: Config;
|
|
21
|
+
log: Logger;
|
|
22
|
+
todos: Todos;
|
|
23
|
+
fs: Fs;
|
|
24
|
+
}, cwd: string): Promise<void>;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@webappwiz/arbor",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.31",
|
|
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": "Jared Johnson",
|
|
@@ -10,14 +10,6 @@
|
|
|
10
10
|
"directory": "packages/arbor"
|
|
11
11
|
},
|
|
12
12
|
"type": "module",
|
|
13
|
-
"module": "index.ts",
|
|
14
|
-
"bin": {
|
|
15
|
-
"arbor": "./index.ts"
|
|
16
|
-
},
|
|
17
|
-
"exports": {
|
|
18
|
-
".": "./index.ts",
|
|
19
|
-
"./config": "./config.ts"
|
|
20
|
-
},
|
|
21
13
|
"imports": {
|
|
22
14
|
"#dev/*": "./dev/*"
|
|
23
15
|
},
|
|
@@ -28,31 +20,22 @@
|
|
|
28
20
|
"access": "public"
|
|
29
21
|
},
|
|
30
22
|
"dependencies": {
|
|
31
|
-
"webappwiz": "0.0.
|
|
23
|
+
"webappwiz": "^0.0.31",
|
|
32
24
|
"zod": "^4.4.3"
|
|
33
25
|
},
|
|
34
|
-
"
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
"
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
"
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
"class-variance-authority": "^0.7.1",
|
|
46
|
-
"clsx": "^2.1.1",
|
|
47
|
-
"lucide-react": "^1.49.0",
|
|
48
|
-
"markdown-to-jsx": "^9.10.3",
|
|
49
|
-
"react": "^19.2.8",
|
|
50
|
-
"react-dom": "^19.2.8",
|
|
51
|
-
"tailwind-merge": "^3.7.0",
|
|
52
|
-
"tailwindcss": "^4.3.3",
|
|
53
|
-
"tw-animate-css": "^1.4.0"
|
|
26
|
+
"main": "./index.js",
|
|
27
|
+
"types": "./index.d.ts",
|
|
28
|
+
"exports": {
|
|
29
|
+
".": {
|
|
30
|
+
"types": "./index.d.ts",
|
|
31
|
+
"default": "./index.js"
|
|
32
|
+
},
|
|
33
|
+
"./config": {
|
|
34
|
+
"types": "./config.d.ts",
|
|
35
|
+
"default": "./config.js"
|
|
36
|
+
}
|
|
54
37
|
},
|
|
55
|
-
"
|
|
56
|
-
"
|
|
38
|
+
"bin": {
|
|
39
|
+
"arbor": "./index.js"
|
|
57
40
|
}
|
|
58
41
|
}
|
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 "$(arbor path)"`, `zed -a "$(arbor 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,83 @@
|
|
|
1
|
+
/** The plan each task keeps at its worktree root, excluded from git. */
|
|
2
|
+
export declare const PLAN_FILE = "ARBOR.md";
|
|
3
|
+
/**
|
|
4
|
+
* The paths an `ARBOR.md` says its task will touch: each top-level bullet
|
|
5
|
+
* under `## Files`, taken as written. Prose around the list is left out, and a
|
|
6
|
+
* plan with no such section plans nothing.
|
|
7
|
+
*/
|
|
8
|
+
export declare function plannedFiles(text: string): string[];
|
|
9
|
+
/**
|
|
10
|
+
* One `- [ ] 9.` item under `## Blocked`: something only a person can do.
|
|
11
|
+
* The item's line is its subject; lines indented under it are its body, and
|
|
12
|
+
* `- (a) ...` or `- [a] ...` lines among them are the answers it offers.
|
|
13
|
+
*/
|
|
14
|
+
export interface Question {
|
|
15
|
+
/** As the plan numbers it, `9`: the name a reply goes by. */
|
|
16
|
+
number: string;
|
|
17
|
+
/** Checked off, which the agent does once it has acted on the reply. */
|
|
18
|
+
done: boolean;
|
|
19
|
+
/** The item's own line, without its checkbox, number or reply. */
|
|
20
|
+
text: string;
|
|
21
|
+
/**
|
|
22
|
+
* The markdown indented under it, dedented, choices left out: detail,
|
|
23
|
+
* code blocks, `` images. Empty when there is none.
|
|
24
|
+
*/
|
|
25
|
+
body: string;
|
|
26
|
+
/** Whatever follows ` → `, or null when nobody has answered yet. */
|
|
27
|
+
reply: string | null;
|
|
28
|
+
/**
|
|
29
|
+
* What a person added once the reply was read, oldest first: each an
|
|
30
|
+
* indented `→ ` line under the question.
|
|
31
|
+
*/
|
|
32
|
+
followUps: string[];
|
|
33
|
+
/**
|
|
34
|
+
* The answers it offers, in order. Empty for a question answered in words
|
|
35
|
+
* alone. A reply can always add words to its picks, or answer in words
|
|
36
|
+
* instead.
|
|
37
|
+
*/
|
|
38
|
+
choices: Choice[];
|
|
39
|
+
/**
|
|
40
|
+
* `one` for `- (a)` choices, at most one of which a reply picks; `any` for
|
|
41
|
+
* `- [a]` choices, where it picks all that apply. Null without choices.
|
|
42
|
+
*/
|
|
43
|
+
pick: "one" | "any" | null;
|
|
44
|
+
}
|
|
45
|
+
/** One answer a question offers: `- (b) Migrate on next login`. */
|
|
46
|
+
export interface Choice {
|
|
47
|
+
/** The letter it goes by: `b`. */
|
|
48
|
+
key: string;
|
|
49
|
+
text: string;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Every numbered item under `## Blocked`, open or checked off, each with the
|
|
53
|
+
* indented lines under it. The reply is read off the item's own line: an
|
|
54
|
+
* answer is one line, written by `arbor reply` or by hand after the arrow.
|
|
55
|
+
*/
|
|
56
|
+
export declare function questions(text: string): Question[];
|
|
57
|
+
/**
|
|
58
|
+
* The plan with a new open question at the end of `## Blocked`, the section
|
|
59
|
+
* made if missing, numbered after the highest there. Returns the plan and
|
|
60
|
+
* the number it went by.
|
|
61
|
+
*/
|
|
62
|
+
export declare function withQuestion(text: string, subject: string, body?: string): {
|
|
63
|
+
plan: string;
|
|
64
|
+
number: string;
|
|
65
|
+
};
|
|
66
|
+
/**
|
|
67
|
+
* A question's number however a person typed it: `9`, `9.`, `Q9` and `q9:`
|
|
68
|
+
* all mean `9`. Null for anything that is not a number at all.
|
|
69
|
+
*/
|
|
70
|
+
export declare function questionNumber(raw: string): string | null;
|
|
71
|
+
export interface PlanOptions {
|
|
72
|
+
/** The task name the title is expected to match. */
|
|
73
|
+
task: string;
|
|
74
|
+
/** Whether the task has escalated, which makes `## Blocked` required. */
|
|
75
|
+
escalated?: boolean;
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Every way a task's `ARBOR.md` departs from the shape the agent skill
|
|
79
|
+
* prescribes, phrased for the agent that wrote it. Advisory only: a resumable
|
|
80
|
+
* plan is the point, and a malformed one still beats none, so nothing here
|
|
81
|
+
* blocks a merge.
|
|
82
|
+
*/
|
|
83
|
+
export declare function checkPlan(text: string, { task, escalated }: PlanOptions): string[];
|
package/remove.d.ts
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { type Logger } from "webappwiz/log";
|
|
2
|
+
import type { Todos } from "./todo.js";
|
|
3
|
+
import type { WorktreeService } from "./worktree-service.js";
|
|
4
|
+
export interface RemoveOptions {
|
|
5
|
+
/** Discard the tree even when another agent holds its lease. */
|
|
6
|
+
force?: boolean;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Discards a whole task: `git worktree remove` plus the branch and the
|
|
10
|
+
* record.
|
|
11
|
+
*
|
|
12
|
+
* Throwing a task away and redoing it against current trunk is usually cheaper
|
|
13
|
+
* than a hard rebase, so this is meant to be used freely.
|
|
14
|
+
*/
|
|
15
|
+
export declare function remove({ service, log, todos, }: {
|
|
16
|
+
service: WorktreeService;
|
|
17
|
+
log: Logger;
|
|
18
|
+
todos: Todos;
|
|
19
|
+
}, task: string, { force }?: RemoveOptions): Promise<void>;
|
package/repository.d.ts
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { Deps, Middleware } from "webappwiz/cmd";
|
|
2
|
+
import { type Fs, type Lock } from "webappwiz/system";
|
|
3
|
+
import type { Config } from "./config.js";
|
|
4
|
+
import { Git } from "./git.js";
|
|
5
|
+
import { Journal } from "./journal.js";
|
|
6
|
+
import { Shell } from "./shell.js";
|
|
7
|
+
import { Todos } from "./todo.js";
|
|
8
|
+
import { WorktreeService } from "./worktree-service.js";
|
|
9
|
+
/** What a command gets to work with, once there is a repository to work in. */
|
|
10
|
+
export interface Repository {
|
|
11
|
+
config: Config;
|
|
12
|
+
git: Git;
|
|
13
|
+
service: WorktreeService;
|
|
14
|
+
lock: Lock;
|
|
15
|
+
shell: Shell;
|
|
16
|
+
journal: Journal;
|
|
17
|
+
todos: Todos;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Runs the action against the repository `cwd` sits in, and refuses to run it
|
|
21
|
+
* at all when that is not a repository.
|
|
22
|
+
*/
|
|
23
|
+
export declare function repository<C extends Deps & {
|
|
24
|
+
fs: Fs;
|
|
25
|
+
}>(at?: string): Middleware<C, C & Repository>;
|
package/retry.d.ts
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { type Logger } from "webappwiz/log";
|
|
2
|
+
import type { Config } from "./config.js";
|
|
3
|
+
import type { WorktreeService } from "./worktree-service.js";
|
|
4
|
+
/**
|
|
5
|
+
* The way back from `budget_exhausted`. A task that has spent its merge
|
|
6
|
+
* attempts gets another `mergeRetryCount` of them, instead of `remove` and redo.
|
|
7
|
+
*
|
|
8
|
+
* Only from `escalated`, and deliberately: the budget's whole job is to make an
|
|
9
|
+
* agent stop and hand the task over. An agent that could grant itself more
|
|
10
|
+
* would be back to grinding against a moving trunk forever, so the price of a
|
|
11
|
+
* fresh budget is that a human has looked at the tree first.
|
|
12
|
+
*/
|
|
13
|
+
export declare function retry({ service, config, log, }: {
|
|
14
|
+
service: WorktreeService;
|
|
15
|
+
config: Config;
|
|
16
|
+
log: Logger;
|
|
17
|
+
}, task: string): Promise<void>;
|
package/shell.d.ts
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { type Ps, type SpawnCaptureResult, type SpawnOptions, type SpawnResult } from "webappwiz/system";
|
|
2
|
+
/** What a `Shell` spawns through; the real process by default. */
|
|
3
|
+
export interface ShellOptions {
|
|
4
|
+
ps?: Ps;
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* Runs the commands a repo configures (the lifecycle hooks) as shell strings
|
|
8
|
+
* rather than argv, since that is how a repo writes them.
|
|
9
|
+
*/
|
|
10
|
+
export declare class Shell {
|
|
11
|
+
private readonly ps;
|
|
12
|
+
constructor(opts?: ShellOptions);
|
|
13
|
+
/** Captures output, for commands whose failure has to be reported back. */
|
|
14
|
+
run(command: string, cwd: string, opts?: SpawnOptions): Promise<SpawnCaptureResult>;
|
|
15
|
+
/** Inherits stdio, for commands the agent should watch as they run. */
|
|
16
|
+
stream(command: string, cwd: string, opts?: SpawnOptions): Promise<SpawnResult>;
|
|
17
|
+
}
|
package/show.d.ts
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { type Logger } from "webappwiz/log";
|
|
2
|
+
import { type Fs } from "webappwiz/system";
|
|
3
|
+
import type { Worktree } from "./worktree.js";
|
|
4
|
+
import type { WorktreeService } from "./worktree-service.js";
|
|
5
|
+
export interface Details {
|
|
6
|
+
task: string;
|
|
7
|
+
status: string;
|
|
8
|
+
branch: string;
|
|
9
|
+
base: string;
|
|
10
|
+
worktree: string;
|
|
11
|
+
lease: "held" | "stale" | "none";
|
|
12
|
+
ahead: number | null;
|
|
13
|
+
added: number | null;
|
|
14
|
+
removed: number | null;
|
|
15
|
+
age: string | null;
|
|
16
|
+
escalation: string | null;
|
|
17
|
+
/**
|
|
18
|
+
* While escalated to be approved, the question that asks for it, `4`;
|
|
19
|
+
* null otherwise.
|
|
20
|
+
*/
|
|
21
|
+
review: string | null;
|
|
22
|
+
plan: string | null;
|
|
23
|
+
/** How the `ARBOR.md` departs from the shape the skill prescribes. */
|
|
24
|
+
planProblems: string[];
|
|
25
|
+
}
|
|
26
|
+
export interface ShowOptions {
|
|
27
|
+
/** Print the details as JSON instead of prose. */
|
|
28
|
+
json?: boolean;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* One task in full: what `list` shows for it, plus the `ARBOR.md` its agent
|
|
32
|
+
* left at the worktree root. Reading a tree this way takes no lease, so it
|
|
33
|
+
* cannot knock the agent driving it off its own work.
|
|
34
|
+
*/
|
|
35
|
+
export declare function show({ service, fs, log }: {
|
|
36
|
+
service: WorktreeService;
|
|
37
|
+
fs: Fs;
|
|
38
|
+
log: Logger;
|
|
39
|
+
}, task: string, opts?: ShowOptions): Promise<void>;
|
|
40
|
+
/** Configures how {@link TaskDetails} gathers a task's info. */
|
|
41
|
+
export interface TaskDetailsOptions {
|
|
42
|
+
/** What the worktree is read through; the real filesystem by default. */
|
|
43
|
+
fs?: Fs;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Everything there is to say about one task. Split out so `dev` can render the
|
|
47
|
+
* same fields this prints, rather than assembling its own and drifting.
|
|
48
|
+
*/
|
|
49
|
+
export declare class TaskDetails {
|
|
50
|
+
private readonly fs;
|
|
51
|
+
constructor(opts?: TaskDetailsOptions);
|
|
52
|
+
get(worktree: Worktree): Promise<Details>;
|
|
53
|
+
}
|
package/snapshot.d.ts
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type { Fs } from "webappwiz/system";
|
|
2
|
+
import { type Details } from "./show.js";
|
|
3
|
+
import type { TodoState, Todos } from "./todo.js";
|
|
4
|
+
import type { WorktreeService } from "./worktree-service.js";
|
|
5
|
+
/**
|
|
6
|
+
* Everything one page shows: `todo list`, and `list` and `show` for each
|
|
7
|
+
* task.
|
|
8
|
+
*/
|
|
9
|
+
export interface Snapshot {
|
|
10
|
+
/** The repository's directory name, so a page among many says whose it is. */
|
|
11
|
+
repo: string;
|
|
12
|
+
/** Where the repository sits, with the home directory as `~`. */
|
|
13
|
+
path: string;
|
|
14
|
+
/** Past this age a todo is offered for removal rather than recommended. */
|
|
15
|
+
todoStalenessMs: number;
|
|
16
|
+
todos: TodoState[];
|
|
17
|
+
tasks: Details[];
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Reads the whole repo the way the CLI's read commands do. Takes no lease, so
|
|
21
|
+
* the page can sit open on a live tree without disturbing the agent in it.
|
|
22
|
+
*/
|
|
23
|
+
export declare function snapshot({ service, todos, fs, home, }: {
|
|
24
|
+
service: WorktreeService;
|
|
25
|
+
todos: Todos;
|
|
26
|
+
fs: Fs;
|
|
27
|
+
/** The home directory to show as `~`, when there is one. */
|
|
28
|
+
home?: string;
|
|
29
|
+
}): Promise<Snapshot>;
|
|
30
|
+
/**
|
|
31
|
+
* What the page is actually showing, minus the fields that move on their own.
|
|
32
|
+
* `age` ticks every minute, and hashing it would push to every open page for
|
|
33
|
+
* nothing.
|
|
34
|
+
*/
|
|
35
|
+
export declare function fingerprint({ todos, tasks }: Snapshot): string;
|