team 0.1.2 → 0.2.0
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 +22 -11
- package/dist/approve/approval.js +14 -9
- package/dist/approve/fingerprint.d.ts +14 -2
- package/dist/approve/fingerprint.js +21 -21
- package/dist/budgets/gate.js +7 -2
- package/dist/budgets/readings.d.ts +6 -2
- package/dist/budgets/readings.js +28 -2
- package/dist/budgets/run.js +8 -2
- package/dist/budgets/table.d.ts +2 -0
- package/dist/budgets/table.js +10 -5
- package/dist/cli.d.ts +2 -1
- package/dist/cli.js +8 -5
- package/dist/commands/add.d.ts +0 -1
- package/dist/commands/add.js +7 -5
- package/dist/commands/approve.js +17 -1
- package/dist/commands/doctor.d.ts +15 -1
- package/dist/commands/doctor.js +126 -8
- package/dist/commands/down.d.ts +4 -0
- package/dist/commands/down.js +32 -13
- package/dist/commands/init.d.ts +1 -1
- package/dist/commands/init.js +4 -2
- package/dist/commands/remove.js +5 -2
- package/dist/commands/status.d.ts +2 -0
- package/dist/commands/status.js +19 -1
- package/dist/commands/up.js +3 -1
- package/dist/commands/watch.d.ts +2 -0
- package/dist/commands/watch.js +28 -4
- package/dist/conformance/adapter.d.ts +5 -0
- package/dist/conformance/adapter.js +44 -0
- package/dist/file/check.d.ts +20 -0
- package/dist/file/check.js +112 -0
- package/dist/file/lines.js +13 -2
- package/dist/file/sections/budgets.d.ts +15 -0
- package/dist/file/sections/budgets.js +180 -0
- package/dist/file/sections/coordinator.d.ts +2 -0
- package/dist/file/sections/coordinator.js +11 -0
- package/dist/file/sections/format.d.ts +2 -0
- package/dist/file/sections/format.js +13 -0
- package/dist/file/sections/identity.d.ts +2 -0
- package/dist/file/sections/identity.js +103 -0
- package/dist/file/sections/index.d.ts +9 -0
- package/dist/file/sections/index.js +43 -0
- package/dist/file/sections/lead.d.ts +4 -0
- package/dist/file/sections/lead.js +18 -0
- package/dist/file/sections/limits.d.ts +2 -0
- package/dist/file/sections/limits.js +43 -0
- package/dist/file/sections/machine.d.ts +2 -0
- package/dist/file/sections/machine.js +38 -0
- package/dist/file/sections/operator.d.ts +2 -0
- package/dist/file/sections/operator.js +11 -0
- package/dist/file/sections/project.d.ts +2 -0
- package/dist/file/sections/project.js +13 -0
- package/dist/file/sections/rules.d.ts +2 -0
- package/dist/file/sections/rules.js +9 -0
- package/dist/file/sections/seats.d.ts +7 -0
- package/dist/file/sections/seats.js +161 -0
- package/dist/file/sections/section.d.ts +32 -0
- package/dist/file/sections/section.js +7 -0
- package/dist/file/sections/session.d.ts +2 -0
- package/dist/file/sections/session.js +16 -0
- package/dist/file/sections/tools.d.ts +2 -0
- package/dist/file/sections/tools.js +43 -0
- package/dist/file/sections/trust.d.ts +2 -0
- package/dist/file/sections/trust.js +20 -0
- package/dist/file/sections/units.d.ts +16 -0
- package/dist/file/sections/units.js +8 -0
- package/dist/file/sections/visibility.d.ts +2 -0
- package/dist/file/sections/visibility.js +12 -0
- package/dist/file/sections/watch-checks.d.ts +9 -0
- package/dist/file/sections/watch-checks.js +14 -0
- package/dist/file/sections/watch.d.ts +14 -0
- package/dist/file/sections/watch.js +111 -0
- package/dist/file/sections/workspace.d.ts +4 -0
- package/dist/file/sections/workspace.js +77 -0
- package/dist/file/types.d.ts +1 -0
- package/dist/file/validate.d.ts +4 -12
- package/dist/file/validate.js +45 -688
- package/dist/herdr.d.ts +1 -0
- package/dist/herdr.js +11 -1
- package/dist/launch/agent.js +4 -3
- package/dist/launch/deliver.d.ts +4 -0
- package/dist/launch/deliver.js +151 -8
- package/dist/launch/execute.d.ts +2 -0
- package/dist/launch/execute.js +21 -11
- package/dist/launch/plan.js +16 -2
- package/dist/profiles/antigravity.yaml +12 -2
- package/dist/profiles/claude-code.yaml +21 -6
- package/dist/profiles/codex.yaml +14 -1
- package/dist/profiles/cursor.yaml +45 -5
- package/dist/profiles/overrides.d.ts +67 -0
- package/dist/profiles/overrides.js +190 -0
- package/dist/profiles/profile.d.ts +3 -0
- package/dist/profiles/profile.js +5 -1
- package/dist/state.d.ts +2 -0
- package/dist/status/compare.js +7 -4
- package/dist/store/store.d.ts +5 -0
- package/dist/version.d.ts +1 -0
- package/dist/version.js +7 -0
- package/dist/watch/checks/budget.js +49 -53
- package/dist/watch/dialect.d.ts +6 -1
- package/dist/watch/dialect.js +68 -12
- package/dist/watch/pass.d.ts +8 -1
- package/dist/watch/pass.js +19 -9
- package/dist/watch/screen-core.d.ts +41 -4
- package/dist/watch/screen-core.js +458 -93
- package/dist/watch/screen-data.d.ts +25 -0
- package/dist/watch/screen-file.d.ts +8 -2
- package/dist/watch/screen-file.js +325 -38
- package/dist/watch/screen-profile.d.ts +19 -0
- package/dist/watch/screen-profile.js +1 -0
- package/dist/watch/screen.d.ts +22 -4
- package/dist/watch/screen.js +39 -5
- package/package.json +9 -3
- package/schema/team.schema.json +498 -0
package/dist/watch/pass.js
CHANGED
|
@@ -4,7 +4,8 @@
|
|
|
4
4
|
// handed (RFC 0002 § 4.2).
|
|
5
5
|
import { seatNamed } from "../approve/fingerprint.js";
|
|
6
6
|
import { observe, observeCheck } from "../budgets/readings.js";
|
|
7
|
-
import {
|
|
7
|
+
import { reportedLiveAgent } from "../launch/agent.js";
|
|
8
|
+
import { profileFor, quotaFor as shippedQuota } from "../profiles/profile.js";
|
|
8
9
|
import { figuresOf } from "../profiles/quota.js";
|
|
9
10
|
import { seatModel } from "../status/statusline.js";
|
|
10
11
|
import { ALWAYS_ON, } from "./check.js";
|
|
@@ -52,16 +53,20 @@ function attentionOf(screen, status, quiet) {
|
|
|
52
53
|
}
|
|
53
54
|
// The figures off a seat's own pane: only a composer screen — idle, unsent or working — shows a
|
|
54
55
|
// status row at all, and only that row's line is read. A dialog, a question, a trust screen or an
|
|
55
|
-
// unknown one gives no figures, and neither does a line the seat printed or typed.
|
|
56
|
-
|
|
57
|
-
|
|
56
|
+
// unknown one gives no figures, and neither does a line the seat printed or typed. And only a
|
|
57
|
+
// pane where herdr reports the seat's CLI still running: a shell's last row is a last row by
|
|
58
|
+
// position, not a status row, and a pane herdr could not read gives none either — no figure is
|
|
59
|
+
// invented where the CLI was not seen. (`down` and `remove` read that same null the other way at
|
|
60
|
+
// their departure wait; not knowing must not end a wait.)
|
|
61
|
+
function quotaOf(cli, screen, pane, runs, patterns) {
|
|
62
|
+
if (pane === undefined || !runs)
|
|
58
63
|
return [];
|
|
59
64
|
if (screen.kind !== 'idle' && screen.kind !== 'unsent' && screen.kind !== 'working')
|
|
60
65
|
return [];
|
|
61
|
-
return figuresOf(
|
|
66
|
+
return figuresOf(patterns, statusRow(cli, pane));
|
|
62
67
|
}
|
|
63
68
|
// One pass of the watch. Pure: it reads what it is handed and changes only `memory`.
|
|
64
|
-
export function pass({ team, state, live, machine, now, memory, approval, watch, outcomes = [], budgets = team.budgets, readings: stored = [], }) {
|
|
69
|
+
export function pass({ team, state, live, machine, now, memory, approval, watch, outcomes = [], budgets = team.budgets, readings: stored = [], foreground, readScreen: read = readScreen, quotaFor: patternsOf = shippedQuota, }) {
|
|
65
70
|
const reports = [];
|
|
66
71
|
const current = new Set();
|
|
67
72
|
// Reported when it starts, and again only after it has cleared.
|
|
@@ -130,7 +135,7 @@ export function pass({ team, state, live, machine, now, memory, approval, watch,
|
|
|
130
135
|
}
|
|
131
136
|
known.add(agent.pane);
|
|
132
137
|
const pane = live.screens[agent.pane];
|
|
133
|
-
const screen =
|
|
138
|
+
const screen = read(cli, pane);
|
|
134
139
|
const quiet = agent.status === 'idle' || agent.status === 'done';
|
|
135
140
|
// Working is herdr's word or the screen's: a seat mid-turn is never idle, whatever its
|
|
136
141
|
// status says.
|
|
@@ -157,7 +162,7 @@ export function pass({ team, state, live, machine, now, memory, approval, watch,
|
|
|
157
162
|
cli,
|
|
158
163
|
vendor,
|
|
159
164
|
account,
|
|
160
|
-
quota: quotaOf(cli, screen, pane),
|
|
165
|
+
quota: quotaOf(cli, screen, pane, reportedLiveAgent(foreground?.[agent.pane] ?? null, profileFor(cli)?.processNames ?? []), patternsOf(cli)),
|
|
161
166
|
running: true,
|
|
162
167
|
quiet,
|
|
163
168
|
working,
|
|
@@ -183,6 +188,11 @@ export function pass({ team, state, live, machine, now, memory, approval, watch,
|
|
|
183
188
|
// not move its figure into another account's bucket, where `up` and `add` would count it.
|
|
184
189
|
// Nothing is saved for that seat until the owner approves.
|
|
185
190
|
const drift = new Set((Array.isArray(approval) ? approval : []).map(seatNamed).filter((name) => name !== null));
|
|
191
|
+
for (const [name, recorded] of Object.entries(state.seats)) {
|
|
192
|
+
if (recorded.temporary && drift.has(recorded.temporary.like)) {
|
|
193
|
+
drift.add(name);
|
|
194
|
+
}
|
|
195
|
+
}
|
|
186
196
|
let readings = stored.slice();
|
|
187
197
|
for (const seat of observations) {
|
|
188
198
|
if (!seat.running || drift.has(seat.name))
|
|
@@ -257,7 +267,7 @@ export function pass({ team, state, live, machine, now, memory, approval, watch,
|
|
|
257
267
|
const operator = live.agents.find((agent) => agent.name === team.operator);
|
|
258
268
|
const cli = team.seats.find((seat) => seat.name === team.operator)?.cli ?? '';
|
|
259
269
|
const free = operator !== undefined && (operator.status === 'idle' || operator.status === 'done')
|
|
260
|
-
&&
|
|
270
|
+
&& read(cli, live.screens[operator.pane]).kind === 'idle';
|
|
261
271
|
if (operator && free) {
|
|
262
272
|
nudge = { pane: operator.pane, text: NUDGE_TEXT, pending: memory.pending.slice() };
|
|
263
273
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { Screen } from './screen.ts';
|
|
2
|
-
import type { ScreenData } from './screen-data.ts';
|
|
3
|
-
export type { Composer, FallbackRule, LinePattern, Placeholder, PlaceholderStyle, Rule, ScreenData, Stage } from './screen-data.ts';
|
|
2
|
+
import type { ScreenData, Wrap } from './screen-data.ts';
|
|
3
|
+
export type { Composer, FallbackRule, LinePattern, Placeholder, PlaceholderStyle, Rule, ScreenData, Stage, Wrap } from './screen-data.ts';
|
|
4
|
+
export type { ScreenProfile, ComposerReading } from './screen-profile.ts';
|
|
4
5
|
export type ReadClock = {
|
|
5
6
|
now(): number;
|
|
6
7
|
budgetMs: number;
|
|
@@ -11,10 +12,46 @@ export type ReadClock = {
|
|
|
11
12
|
* typed — is never the row. The caller still has to know the screen is a composer screen.
|
|
12
13
|
*/
|
|
13
14
|
export declare function statusRowOf(data: ScreenData, lines: string[]): string | null;
|
|
15
|
+
export type Fold = {
|
|
16
|
+
count: number;
|
|
17
|
+
rows: string[];
|
|
18
|
+
width: number;
|
|
19
|
+
};
|
|
20
|
+
/** The input box a composer draws for its current text: the first line after the prompt, the
|
|
21
|
+
* continuation rows under it, the column those rows start at (the prompt's own width plus
|
|
22
|
+
* the separator the input row draws), and the profile's wrap rule when a capture shows how
|
|
23
|
+
* the box continues a line onto its next row. */
|
|
24
|
+
export type Box = {
|
|
25
|
+
first: string;
|
|
26
|
+
indent: number;
|
|
27
|
+
rows: string[];
|
|
28
|
+
wrap?: Wrap;
|
|
29
|
+
};
|
|
30
|
+
/**
|
|
31
|
+
* The fold a `two-rules-footer-below` composer's window shows, or null. A marker whose count is
|
|
32
|
+
* zero names no hidden rows to compare against, so it is no fold; it is still a marker, and
|
|
33
|
+
* `foldMarked` catches it.
|
|
34
|
+
*/
|
|
35
|
+
export declare function foldOf(data: ScreenData, lines: string[]): Fold | null;
|
|
36
|
+
/**
|
|
37
|
+
* Whether the window shows a fold marker at all, whatever count it names: a marker claiming zero
|
|
38
|
+
* hidden rows (or a count a fold could not have) is still a box that is not showing the whole
|
|
39
|
+
* text, and it must never be taken for an ordinary unsent box and submitted unverified.
|
|
40
|
+
*/
|
|
41
|
+
export declare function foldMarked(data: ScreenData, lines: string[]): boolean;
|
|
14
42
|
/** `lines` is already the window: the last 20 lines, each trimmed at the end. */
|
|
15
43
|
export declare function classifyLines(data: ScreenData, lines: string[], clock?: ReadClock): Screen;
|
|
16
44
|
/**
|
|
17
|
-
* The composer alone, for a turn that is still running. The
|
|
18
|
-
*
|
|
45
|
+
* The composer alone, for a turn that is still running. The dialog stages and
|
|
46
|
+
* floor must not be overridden by composer readings returning idle or unsent.
|
|
19
47
|
*/
|
|
20
48
|
export declare function composeLines(data: ScreenData, lines: string[], clock?: ReadClock): Screen;
|
|
49
|
+
/**
|
|
50
|
+
* The input box a composer draws for its current text, or null when the composer does not read
|
|
51
|
+
* `unsent`: an idle box holds nothing, and every other shape is not the box. The rows are the
|
|
52
|
+
* ones the mode's own frame delimits — between the prompt row and the box's closing line; the
|
|
53
|
+
* `status-then-one` fallback (the captured completion frame) delimits nothing, so its box is
|
|
54
|
+
* its one input row, the popup rows below it being its filter's to exclude. The caller compares
|
|
55
|
+
* the box to the text it typed; nothing here decides that.
|
|
56
|
+
*/
|
|
57
|
+
export declare function composerBox(data: ScreenData, lines: string[]): Box | null;
|