@webappwiz/arbor 0.0.28 → 0.0.30
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/AGENTS.md +7 -0
- package/README.md +34 -12
- package/add.test.ts +125 -0
- package/add.ts +192 -0
- package/age.ts +11 -0
- package/arbor.test.ts +145 -0
- package/arbor.ts +429 -0
- package/assets.d.ts +9 -0
- package/attachments.ts +87 -0
- package/build.ts +98 -0
- package/claim.test.ts +89 -0
- package/claim.ts +73 -0
- package/components.json +21 -0
- package/config.ts +58 -0
- package/dev/api.ts +120 -0
- package/dev/app.test.tsx +645 -0
- package/dev/app.tsx +80 -0
- package/dev/assets.ts +16 -0
- package/dev/build/main.txt +68 -0
- package/dev/build/shell.txt +21 -0
- package/dev/build/styles.txt +2263 -0
- package/dev/components/ui/badge.tsx +51 -0
- package/dev/components/ui/button.tsx +57 -0
- package/dev/components/ui/dialog.tsx +154 -0
- package/dev/components/ui/empty.tsx +100 -0
- package/dev/components/ui/input-group.tsx +155 -0
- package/dev/components/ui/input.tsx +19 -0
- package/dev/components/ui/progress.tsx +80 -0
- package/dev/components/ui/textarea.tsx +17 -0
- package/dev/components/ui/toast.tsx +227 -0
- package/dev/feed.ts +69 -0
- package/dev/files.tsx +191 -0
- package/dev/index.html +21 -0
- package/dev/lib/utils.ts +7 -0
- package/dev/main.tsx +22 -0
- package/dev/markdown.test.tsx +133 -0
- package/dev/markdown.tsx +124 -0
- package/dev/mentions.tsx +319 -0
- package/dev/shadcn.css +649 -0
- package/dev/styles.css +107 -0
- package/dev/tags.tsx +44 -0
- package/dev/tasks.tsx +151 -0
- package/dev/todos.tsx +759 -0
- package/dev.test.ts +439 -0
- package/dev.ts +386 -0
- package/e2e.test.ts +256 -0
- package/escalate.test.ts +76 -0
- package/escalate.ts +112 -0
- package/exit.test.ts +71 -0
- package/exit.ts +74 -0
- package/git.ts +294 -0
- package/index.ts +9 -0
- package/journal.ts +89 -0
- package/list.test.ts +82 -0
- package/list.ts +137 -0
- package/load-config.test.ts +121 -0
- package/load-config.ts +62 -0
- package/log.test.ts +65 -0
- package/log.ts +40 -0
- package/merge.test.ts +332 -0
- package/merge.ts +283 -0
- package/package.json +32 -15
- package/path.test.ts +35 -0
- package/path.ts +38 -0
- package/plan.test.ts +318 -0
- package/plan.ts +302 -0
- package/progress.test.ts +54 -0
- package/progress.ts +31 -0
- package/remove.test.ts +68 -0
- package/remove.ts +88 -0
- package/repository.ts +83 -0
- package/retry.test.ts +43 -0
- package/retry.ts +48 -0
- package/shell.ts +44 -0
- package/show.test.ts +91 -0
- package/show.ts +151 -0
- package/snapshot.test.ts +33 -0
- package/snapshot.ts +84 -0
- package/table.ts +20 -0
- package/testing.ts +229 -0
- package/todo.test.ts +490 -0
- package/todo.ts +834 -0
- package/wait.test.ts +61 -0
- package/wait.ts +77 -0
- package/worktree-service.test.ts +158 -0
- package/worktree-service.ts +193 -0
- package/worktree.ts +239 -0
- package/add.d.ts +0 -23
- package/age.d.ts +0 -2
- package/arbor.d.ts +0 -11
- package/attachments.d.ts +0 -36
- package/claim.d.ts +0 -11
- package/config.d.ts +0 -55
- package/config.js +0 -7
- package/dev/assets.d.ts +0 -11
- package/dev.d.ts +0 -47
- package/escalate.d.ts +0 -28
- package/exit.d.ts +0 -42
- package/git.d.ts +0 -77
- package/index.d.ts +0 -2
- package/index.js +0 -4669
- package/journal.d.ts +0 -29
- package/list.d.ts +0 -18
- package/load-config.d.ts +0 -15
- package/log.d.ts +0 -14
- package/merge.d.ts +0 -24
- package/path.d.ts +0 -13
- package/plan.d.ts +0 -83
- package/remove.d.ts +0 -19
- package/repository.d.ts +0 -25
- package/retry.d.ts +0 -17
- package/shell.d.ts +0 -17
- package/show.d.ts +0 -53
- package/snapshot.d.ts +0 -31
- package/table.d.ts +0 -5
- package/todo.d.ts +0 -230
- package/wait.d.ts +0 -22
- package/worktree-service.d.ts +0 -51
- package/worktree.d.ts +0 -95
package/journal.d.ts
DELETED
|
@@ -1,29 +0,0 @@
|
|
|
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
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
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
DELETED
|
@@ -1,15 +0,0 @@
|
|
|
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
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
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
DELETED
|
@@ -1,24 +0,0 @@
|
|
|
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/path.d.ts
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
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
DELETED
|
@@ -1,83 +0,0 @@
|
|
|
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
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
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
DELETED
|
@@ -1,25 +0,0 @@
|
|
|
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
DELETED
|
@@ -1,17 +0,0 @@
|
|
|
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
DELETED
|
@@ -1,17 +0,0 @@
|
|
|
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
DELETED
|
@@ -1,53 +0,0 @@
|
|
|
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
DELETED
|
@@ -1,31 +0,0 @@
|
|
|
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
|
-
/** Past this age a todo is offered for removal rather than recommended. */
|
|
13
|
-
todoStalenessMs: number;
|
|
14
|
-
todos: TodoState[];
|
|
15
|
-
tasks: Details[];
|
|
16
|
-
}
|
|
17
|
-
/**
|
|
18
|
-
* Reads the whole repo the way the CLI's read commands do. Takes no lease, so
|
|
19
|
-
* the page can sit open on a live tree without disturbing the agent in it.
|
|
20
|
-
*/
|
|
21
|
-
export declare function snapshot({ service, todos, fs, }: {
|
|
22
|
-
service: WorktreeService;
|
|
23
|
-
todos: Todos;
|
|
24
|
-
fs: Fs;
|
|
25
|
-
}): Promise<Snapshot>;
|
|
26
|
-
/**
|
|
27
|
-
* What the page is actually showing, minus the fields that move on their own.
|
|
28
|
-
* `age` ticks every minute, and hashing it would push to every open page for
|
|
29
|
-
* nothing.
|
|
30
|
-
*/
|
|
31
|
-
export declare function fingerprint({ todos, tasks }: Snapshot): string;
|
package/table.d.ts
DELETED
package/todo.d.ts
DELETED
|
@@ -1,230 +0,0 @@
|
|
|
1
|
-
import { type IdProvider } from "webappwiz/id";
|
|
2
|
-
import { type Logger } from "webappwiz/log";
|
|
3
|
-
import { type Fs, type Lock, type Ps } from "webappwiz/system";
|
|
4
|
-
import { type Attachment, Attachments } from "./attachments.js";
|
|
5
|
-
/** What a todo is on disk: one file apiece, so two agents never rewrite one. */
|
|
6
|
-
export interface TodoState {
|
|
7
|
-
id: number;
|
|
8
|
-
/** What is left to do, in a line. */
|
|
9
|
-
subject: string;
|
|
10
|
-
/** Whatever more there is to say about it, or empty when the line is enough. */
|
|
11
|
-
text: string;
|
|
12
|
-
/** Where it stands in the list, 1 at the top: the one to pick up first. */
|
|
13
|
-
position: number;
|
|
14
|
-
/** The task it came up in, or null when a person added it from the main tree. */
|
|
15
|
-
from: string | null;
|
|
16
|
-
createdAt: string;
|
|
17
|
-
/** The task working on it now, or null while it waits to be picked up. */
|
|
18
|
-
takenBy: string | null;
|
|
19
|
-
/** Absolute paths of the files attached, in `todos/<id>/`. */
|
|
20
|
-
files: string[];
|
|
21
|
-
}
|
|
22
|
-
/** A todo's words, place or files changed: new ones added, some of the old kept. */
|
|
23
|
-
export interface TodoChange {
|
|
24
|
-
/** A new line; the old one stays when this is absent. */
|
|
25
|
-
subject?: string;
|
|
26
|
-
/** New detail, empty for none; the old stays when this is absent. */
|
|
27
|
-
text?: string;
|
|
28
|
-
/** Where to move it in the list; it stays put when this is absent. */
|
|
29
|
-
position?: number;
|
|
30
|
-
/** Files to add. */
|
|
31
|
-
files?: Attachment[];
|
|
32
|
-
/** The paths of the files it has now to keep; absent keeps them all. */
|
|
33
|
-
keep?: string[];
|
|
34
|
-
}
|
|
35
|
-
/** What a new todo has besides its subject, all of it optional. */
|
|
36
|
-
export interface TodoNew {
|
|
37
|
-
/** Whatever more there is to say about it. */
|
|
38
|
-
text?: string;
|
|
39
|
-
files?: Attachment[];
|
|
40
|
-
/** Where it goes in the list, pushing those from there down; the bottom by default. */
|
|
41
|
-
position?: number;
|
|
42
|
-
}
|
|
43
|
-
/**
|
|
44
|
-
* Work deferred for later: what an agent notes when something outside its
|
|
45
|
-
* task comes up, so it can move on instead of growing the task. Kept under the
|
|
46
|
-
* shared `.git`, so every worktree sees a new one at once, with nothing to
|
|
47
|
-
* commit and nothing to merge.
|
|
48
|
-
*/
|
|
49
|
-
export declare class Todo {
|
|
50
|
-
private readonly todos;
|
|
51
|
-
readonly state: TodoState;
|
|
52
|
-
constructor(todos: Todos, state: TodoState);
|
|
53
|
-
get id(): number;
|
|
54
|
-
get subject(): string;
|
|
55
|
-
get text(): string;
|
|
56
|
-
get position(): number;
|
|
57
|
-
get from(): string | null;
|
|
58
|
-
get takenBy(): string | null;
|
|
59
|
-
get createdAt(): Date;
|
|
60
|
-
/** How long it has waited, in milliseconds. */
|
|
61
|
-
get waited(): number;
|
|
62
|
-
/** Marks it as the work of `task`, refusing one another task already has. */
|
|
63
|
-
take(task: string): Promise<Todo>;
|
|
64
|
-
/** Puts it back on the list, as when the task that took it is removed. */
|
|
65
|
-
release(): Promise<Todo>;
|
|
66
|
-
get files(): string[];
|
|
67
|
-
get attachments(): Attachments;
|
|
68
|
-
/**
|
|
69
|
-
* Says what is left to do in other words, with other files, or higher or
|
|
70
|
-
* lower in the list, keeping its id and history.
|
|
71
|
-
*/
|
|
72
|
-
update({ subject, text, position, files, keep, }: TodoChange): Promise<Todo>;
|
|
73
|
-
remove(): Promise<void>;
|
|
74
|
-
}
|
|
75
|
-
/** What `Todos` is stored through; the real filesystem by default. */
|
|
76
|
-
export interface TodosOptions {
|
|
77
|
-
fs?: Fs;
|
|
78
|
-
/** Names stored files apart; a test counts. */
|
|
79
|
-
ids?: IdProvider;
|
|
80
|
-
}
|
|
81
|
-
/** Every todo in the repo, one JSON file each under `.git/arbor/todos`. */
|
|
82
|
-
export declare class Todos {
|
|
83
|
-
readonly dir: string;
|
|
84
|
-
/**
|
|
85
|
-
* Held while numbering a new todo, so two agents never share an id, and
|
|
86
|
-
* while writing one, so a move renumbering the rest never loses to a
|
|
87
|
-
* write of a position it just changed.
|
|
88
|
-
*/
|
|
89
|
-
private readonly lock;
|
|
90
|
-
private readonly fs;
|
|
91
|
-
private readonly ids;
|
|
92
|
-
constructor(dir: string,
|
|
93
|
-
/**
|
|
94
|
-
* Held while numbering a new todo, so two agents never share an id, and
|
|
95
|
-
* while writing one, so a move renumbering the rest never loses to a
|
|
96
|
-
* write of a position it just changed.
|
|
97
|
-
*/
|
|
98
|
-
lock: Lock, opts?: TodosOptions);
|
|
99
|
-
/** Where a todo's files live, beside its record. */
|
|
100
|
-
attachments(id: number): Attachments;
|
|
101
|
-
/** Whether `path` is a file some todo holds, and not a way out of here. */
|
|
102
|
-
owns(path: string): boolean;
|
|
103
|
-
add(subject: string, from: string | null, { text, files, position }?: TodoNew): Promise<Todo>;
|
|
104
|
-
/**
|
|
105
|
-
* Top of the list first. A file that will not parse is skipped rather than
|
|
106
|
-
* fatal, and positions are counted again from 1 as they are read, so a
|
|
107
|
-
* gap or a tie left by a crash, or a todo saved before they had any (it
|
|
108
|
-
* goes below those that do, oldest first), never shows.
|
|
109
|
-
*/
|
|
110
|
-
all(): Promise<Todo[]>;
|
|
111
|
-
find(id: number): Promise<Todo>;
|
|
112
|
-
/** The todos `task` has taken; what a merge or remove settles. */
|
|
113
|
-
takenBy(task: string): Promise<Todo[]>;
|
|
114
|
-
/**
|
|
115
|
-
* Puts a todo at `position`, 1 at the top, past the bottom meaning the
|
|
116
|
-
* bottom, and numbers the rest around it.
|
|
117
|
-
*/
|
|
118
|
-
move(id: number, position: number): Promise<Todo>;
|
|
119
|
-
/**
|
|
120
|
-
* @internal Rewrites one todo as it stands on disk now, under the lock, so
|
|
121
|
-
* a change to its words or who has it never undoes a move made meanwhile.
|
|
122
|
-
*/
|
|
123
|
-
revise(id: number, change: (state: TodoState) => TodoState): Promise<Todo>;
|
|
124
|
-
/** @internal Writes one todo. Rename makes the swap atomic for readers. */
|
|
125
|
-
save(state: TodoState): Promise<Todo>;
|
|
126
|
-
/** @internal Removes one, moving those below it up to close the gap. */
|
|
127
|
-
delete(id: number): Promise<void>;
|
|
128
|
-
private locked;
|
|
129
|
-
/** One todo as it stands on disk; call it under the lock. */
|
|
130
|
-
private state;
|
|
131
|
-
/**
|
|
132
|
-
* Slots `state` in at `position` among the rest and saves whichever moved.
|
|
133
|
-
* Call it under the lock.
|
|
134
|
-
*/
|
|
135
|
-
private place;
|
|
136
|
-
/** Every todo in list order, with the positions it has on disk. */
|
|
137
|
-
private stored;
|
|
138
|
-
/** Saves each todo in `order` whose position on disk is not its place there. */
|
|
139
|
-
private renumber;
|
|
140
|
-
private path;
|
|
141
|
-
private lastId;
|
|
142
|
-
private read;
|
|
143
|
-
}
|
|
144
|
-
/** What a finished task should be followed by, and what should just go. */
|
|
145
|
-
export interface Recommendation {
|
|
146
|
-
/** The todo to pick up next, or null when there is nothing fresh left. */
|
|
147
|
-
next: Todo | null;
|
|
148
|
-
/** Todos left waiting so long they probably no longer apply. */
|
|
149
|
-
stale: Todo[];
|
|
150
|
-
}
|
|
151
|
-
/**
|
|
152
|
-
* Which todo to take up after `task`: one that came up in it first, since
|
|
153
|
-
* whoever just finished it knows that context best, then the open one highest
|
|
154
|
-
* on the list, which is how whoever keeps the list says what matters most.
|
|
155
|
-
* Todos past `staleness` are never recommended, only offered for removal.
|
|
156
|
-
*/
|
|
157
|
-
export declare function recommend(todos: Todos, task: string | null, staleness: number): Promise<Recommendation>;
|
|
158
|
-
/** The lines `merge` ends with, or none when there is nothing to say. */
|
|
159
|
-
export declare function recommendation({ next, stale }: Recommendation): string[];
|
|
160
|
-
export interface TodoListOptions {
|
|
161
|
-
/** Print the todos as JSON instead of a table. */
|
|
162
|
-
json?: boolean;
|
|
163
|
-
}
|
|
164
|
-
export interface TodoFileOptions {
|
|
165
|
-
/** Files to attach, relative to the current directory or absolute. */
|
|
166
|
-
files?: string[];
|
|
167
|
-
}
|
|
168
|
-
export interface TodoAddOptions extends TodoFileOptions {
|
|
169
|
-
/** Whatever more there is to say than the subject. */
|
|
170
|
-
text?: string;
|
|
171
|
-
/** Where it goes in the list, 1 at the top; the bottom by default. */
|
|
172
|
-
position?: number;
|
|
173
|
-
}
|
|
174
|
-
export declare function todoAdd(deps: {
|
|
175
|
-
todos: Todos;
|
|
176
|
-
log: Logger;
|
|
177
|
-
fs: Fs;
|
|
178
|
-
ps: Ps;
|
|
179
|
-
}, subject: string, from: string | null, { text, files, position }?: TodoAddOptions): Promise<Todo>;
|
|
180
|
-
export declare function todoList({ todos, log }: {
|
|
181
|
-
todos: Todos;
|
|
182
|
-
log: Logger;
|
|
183
|
-
}, { json }?: TodoListOptions): Promise<void>;
|
|
184
|
-
export interface TodoShowOptions {
|
|
185
|
-
/** Print the todo as JSON instead of prose. */
|
|
186
|
-
json?: boolean;
|
|
187
|
-
}
|
|
188
|
-
/** One todo in full: what `todo list` shows of it, its files, and its detail. */
|
|
189
|
-
export declare function todoShow({ todos, log }: {
|
|
190
|
-
todos: Todos;
|
|
191
|
-
log: Logger;
|
|
192
|
-
}, id: number, { json }?: TodoShowOptions): Promise<void>;
|
|
193
|
-
export interface TodoUpdateOptions extends TodoFileOptions {
|
|
194
|
-
/** A new line; the old one stays when this is absent or empty. */
|
|
195
|
-
subject?: string;
|
|
196
|
-
/** New detail; the old stays when this is absent or empty. */
|
|
197
|
-
text?: string;
|
|
198
|
-
/** Where to move it in the list, 1 at the top; it stays put when absent. */
|
|
199
|
-
position?: number;
|
|
200
|
-
/** Attached files to drop, by path or by the name they were stored under. */
|
|
201
|
-
removeFiles?: string[];
|
|
202
|
-
}
|
|
203
|
-
export declare function todoUpdate(deps: {
|
|
204
|
-
todos: Todos;
|
|
205
|
-
log: Logger;
|
|
206
|
-
fs: Fs;
|
|
207
|
-
ps: Ps;
|
|
208
|
-
}, id: number, { subject, text, position, files, removeFiles, }?: TodoUpdateOptions): Promise<Todo>;
|
|
209
|
-
/**
|
|
210
|
-
* Takes up todos for `task` after it started, as when one turns out to be
|
|
211
|
-
* part of the work. Every id is checked before any is taken, so one that is
|
|
212
|
-
* gone or another task's refuses them all.
|
|
213
|
-
*/
|
|
214
|
-
export declare function todoTake({ todos, log }: {
|
|
215
|
-
todos: Todos;
|
|
216
|
-
log: Logger;
|
|
217
|
-
}, ids: number[], task: string | null): Promise<Todo[]>;
|
|
218
|
-
/**
|
|
219
|
-
* Puts todos back on the list, as when a task is landing without finishing
|
|
220
|
-
* them: say what is left with `arbor todo update` first. From a worktree it
|
|
221
|
-
* gives back only its own task's todos.
|
|
222
|
-
*/
|
|
223
|
-
export declare function todoRelease({ todos, log }: {
|
|
224
|
-
todos: Todos;
|
|
225
|
-
log: Logger;
|
|
226
|
-
}, ids: number[], task: string | null): Promise<Todo[]>;
|
|
227
|
-
export declare function todoRemove({ todos, log }: {
|
|
228
|
-
todos: Todos;
|
|
229
|
-
log: Logger;
|
|
230
|
-
}, id: number): Promise<void>;
|
package/wait.d.ts
DELETED
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
import { type Logger } from "webappwiz/log";
|
|
2
|
-
import { Duration } from "webappwiz/time";
|
|
3
|
-
import type { WorktreeService } from "./worktree-service.js";
|
|
4
|
-
/** How long `wait` gives a task before handing the wait back to its caller. */
|
|
5
|
-
export declare const DEFAULT_TIMEOUT: Duration;
|
|
6
|
-
export interface WaitOptions {
|
|
7
|
-
/** How long to wait before giving up. */
|
|
8
|
-
timeout?: Duration;
|
|
9
|
-
/** How long between reads of the record; the default suits a human's patience. */
|
|
10
|
-
poll?: Duration;
|
|
11
|
-
}
|
|
12
|
-
/**
|
|
13
|
-
* Blocks until a task stops moving: merged or removed (both leave the name
|
|
14
|
-
* `removed`), escalated to a human, or broken. Waiting is for the agent whose
|
|
15
|
-
* own work overlaps this one's and would rather rebase onto the result than
|
|
16
|
-
* against it, which is why the timeout is short enough to come back and think
|
|
17
|
-
* again rather than block a session for an afternoon.
|
|
18
|
-
*/
|
|
19
|
-
export declare function wait({ service, log }: {
|
|
20
|
-
service: WorktreeService;
|
|
21
|
-
log: Logger;
|
|
22
|
-
}, task: string, { timeout, poll }?: WaitOptions): Promise<void>;
|