toolroll 0.9.59 → 0.9.61
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/CHANGELOG.md +26 -0
- package/README.md +8 -6
- package/dist/agent-board.d.ts +208 -0
- package/dist/agent-board.js +454 -0
- package/dist/agent-fence.d.ts +19 -0
- package/dist/agent-fence.js +100 -8
- package/dist/agent-pulse.d.ts +43 -0
- package/dist/agent-pulse.js +214 -0
- package/dist/agent-turns.d.ts +52 -0
- package/dist/agent-turns.js +137 -0
- package/dist/agents-board.d.ts +101 -0
- package/dist/agents-board.js +225 -0
- package/dist/assignment-adapters.d.ts +2 -1
- package/dist/assignment-adapters.js +1 -1
- package/dist/assignment-delivery.d.ts +16 -0
- package/dist/assignment-delivery.js +54 -28
- package/dist/assignment-status.d.ts +14 -5
- package/dist/assignment-status.js +70 -39
- package/dist/assignment.d.ts +10 -2
- package/dist/assignment.js +21 -14
- package/dist/bin.js +11 -2
- package/dist/brief-fence.d.ts +9 -0
- package/dist/brief-fence.js +22 -0
- package/dist/browser/workspace.css +2 -2
- package/dist/browser/workspace.js +29 -25
- package/dist/browser-crew.js +2 -0
- package/dist/browser-workspace.d.ts +79 -1
- package/dist/browser-workspace.js +1 -0
- package/dist/builder.d.ts +8 -0
- package/dist/builder.js +178 -29
- package/dist/chat-channel.js +10 -1
- package/dist/chat-core.d.ts +6 -0
- package/dist/chat-core.js +8 -0
- package/dist/chat-delivery.js +22 -0
- package/dist/chat-messages.js +8 -1
- package/dist/chat-quiet.js +1 -0
- package/dist/chat-voice.d.ts +2 -0
- package/dist/chat-voice.js +2 -0
- package/dist/checkout-cleanup.d.ts +3 -0
- package/dist/checkout-cleanup.js +11 -2
- package/dist/cli-fast.d.ts +8 -0
- package/dist/cli-fast.js +18 -0
- package/dist/cli-help.d.ts +5 -0
- package/dist/cli-help.js +91 -0
- package/dist/cli.d.ts +6 -5
- package/dist/cli.js +17 -96
- package/dist/contracts/console-api.d.ts +3 -1
- package/dist/contracts/console-api.js +5 -1
- package/dist/contracts/lead-tools.d.ts +16 -2
- package/dist/contracts/lead-tools.js +5 -1
- package/dist/design/tokens.css +234 -0
- package/dist/desktop-update.d.ts +1 -1
- package/dist/discord.js +2 -1
- package/dist/evidence-pack.js +1 -1
- package/dist/evidence.d.ts +28 -0
- package/dist/evidence.js +87 -17
- package/dist/exec.d.ts +32 -0
- package/dist/exec.js +229 -10
- package/dist/flow-actions.js +2 -1
- package/dist/guides.js +14 -11
- package/dist/invoke.js +110 -18
- package/dist/landed-cleanup.d.ts +157 -0
- package/dist/landed-cleanup.js +707 -0
- package/dist/lead-cli.js +22 -19
- package/dist/lead-contract.js +1 -1
- package/dist/lead-doors.js +49 -2
- package/dist/lead-follow.d.ts +2 -0
- package/dist/lead-follow.js +138 -88
- package/dist/lead-tools.js +48 -8
- package/dist/live-input.d.ts +68 -0
- package/dist/live-input.js +254 -0
- package/dist/live.d.ts +1 -1
- package/dist/live.js +4 -2
- package/dist/mailbox.js +3 -2
- package/dist/maintenance.d.ts +2 -0
- package/dist/maintenance.js +5 -2
- package/dist/mcp-core.js +1 -1
- package/dist/operate-remote-arguments.js +5 -1
- package/dist/operate-remote.js +1 -1
- package/dist/operate.d.ts +1 -1
- package/dist/operate.js +201 -19
- package/dist/orphan-sweep.d.ts +2 -0
- package/dist/orphan-sweep.js +5 -3
- package/dist/project-delete-ui.d.ts +11 -0
- package/dist/project-delete-ui.js +29 -2
- package/dist/project-tools.d.ts +7 -11
- package/dist/project-tools.js +13 -37
- package/dist/provider.d.ts +73 -8
- package/dist/provider.js +87 -17
- package/dist/result-completion.d.ts +7 -0
- package/dist/result-completion.js +9 -0
- package/dist/runner.d.ts +4 -2
- package/dist/runner.js +3 -3
- package/dist/serve.js +22 -3
- package/dist/server/chrome.d.ts +6 -3
- package/dist/server/chrome.js +8 -4
- package/dist/server/console.css +9 -64
- package/dist/server/live.d.ts +3 -0
- package/dist/server/live.js +35 -2
- package/dist/server/pages.js +59 -35
- package/dist/server/render-chat.js +14 -2
- package/dist/server/render-tasks.d.ts +14 -2
- package/dist/server/render-tasks.js +38 -20
- package/dist/server/route-table.js +4 -1
- package/dist/server/settings.js +2 -1
- package/dist/server/task-views.js +10 -0
- package/dist/server/tasks.js +63 -0
- package/dist/shared-deps.d.ts +9 -4
- package/dist/shared-deps.js +89 -13
- package/dist/slack-socket.d.ts +12 -0
- package/dist/slack-socket.js +29 -0
- package/dist/slack.d.ts +0 -7
- package/dist/slack.js +2 -24
- package/dist/staged-runtimes.d.ts +16 -4
- package/dist/staged-runtimes.js +160 -38
- package/dist/steer-live.d.ts +19 -0
- package/dist/steer-live.js +93 -0
- package/dist/steer-mailbox.d.ts +39 -0
- package/dist/steer-mailbox.js +207 -0
- package/dist/steer-status.d.ts +25 -0
- package/dist/steer-status.js +44 -0
- package/dist/storage-sweep-child.d.ts +1 -0
- package/dist/storage-sweep-child.js +76 -0
- package/dist/storage-sweep-process.d.ts +41 -0
- package/dist/storage-sweep-process.js +187 -0
- package/dist/storage-sweep.d.ts +30 -6
- package/dist/storage-sweep.js +214 -28
- package/dist/storage-ui.d.ts +2 -0
- package/dist/storage-ui.js +16 -4
- package/dist/storage.d.ts +6 -0
- package/dist/storage.js +35 -0
- package/dist/store.d.ts +202 -2
- package/dist/store.js +440 -13
- package/dist/surface.js +5 -3
- package/dist/sweep-gate.d.ts +10 -0
- package/dist/sweep-gate.js +18 -0
- package/dist/sweep-quarantine.d.ts +28 -0
- package/dist/sweep-quarantine.js +153 -0
- package/dist/task-status.d.ts +2 -0
- package/dist/task-status.js +5 -1
- package/dist/team-updates.js +3 -3
- package/dist/test-temp.d.ts +6 -3
- package/dist/test-temp.js +15 -9
- package/dist/toolroll-update.js +15 -2
- package/dist/work-index.d.ts +1 -0
- package/dist/work-index.js +32 -12
- package/dist/work-summary.d.ts +2 -2
- package/dist/workspace-revision.js +3 -1
- package/dist/worktree.d.ts +3 -1
- package/dist/worktree.js +93 -10
- package/package.json +21 -21
- package/scripts/provider-canary.mjs +235 -147
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
/* @generated by youi from the Signal design language v1.0.0. Do not edit: change the tokens in design-language and run `youi sync`. */
|
|
2
|
+
/* Built with Terrazzo (DTCG 2025.10 resolver). */
|
|
3
|
+
:root {
|
|
4
|
+
color-scheme: light;
|
|
5
|
+
--so-accent: #171717;
|
|
6
|
+
--so-accent-hover: #383838;
|
|
7
|
+
--so-accent-text: #171717;
|
|
8
|
+
--so-attention: var(--so-signal);
|
|
9
|
+
--so-attention-soft: var(--so-signal-soft);
|
|
10
|
+
--so-code-bg: #fafafa;
|
|
11
|
+
/* Vermilion: failure and irreversible acts. */
|
|
12
|
+
--so-danger: #c4320a;
|
|
13
|
+
--so-danger-soft: #feebe7;
|
|
14
|
+
--so-ease-out: cubic-bezier(0.23, 1, 0.32, 1);
|
|
15
|
+
--so-font-mono: "Geist Mono", ui-monospace, "SF Mono", "SFMono-Regular", "Menlo", "Consolas", monospace;
|
|
16
|
+
--so-font-sans: "Geist", ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;
|
|
17
|
+
/* Frame Grey: the frame the sidebar sits on, and the page background of server pages. */
|
|
18
|
+
--so-ground: #efefef;
|
|
19
|
+
/* Live Blue: something is running right now. */
|
|
20
|
+
--so-info: #0d74ce;
|
|
21
|
+
--so-info-soft: #e6f4fe;
|
|
22
|
+
/* Ink: all body text, and the colour of every act: primary buttons, the New task button, switches and radio cards when on. */
|
|
23
|
+
--so-ink: #171717;
|
|
24
|
+
/* Control Line: the boundary of fields, the composer, and the switch track when off. */
|
|
25
|
+
--so-input-line: #d4d4d4;
|
|
26
|
+
/* Hairline: every divider. */
|
|
27
|
+
--so-line: #e6e6e6;
|
|
28
|
+
--so-live: #0d74ce;
|
|
29
|
+
/* Muted: meta lines, fact keys, ghost buttons, placeholders, idle tab counts. */
|
|
30
|
+
--so-muted: #666666;
|
|
31
|
+
--so-nav-current: #ffffff;
|
|
32
|
+
--so-nav-current-ink: #171717;
|
|
33
|
+
--so-nav-hover: #e4e4e4;
|
|
34
|
+
/* Nav Ink: idle sidebar rows and their hover fill on the frame. */
|
|
35
|
+
--so-nav-ink: #525252;
|
|
36
|
+
--so-neutral-ink: #525252;
|
|
37
|
+
/* Neutral Badge: the badge for anything that is a fact and not a claim on the person, such as queued, running or built today in a project peek, or a count in a fold. */
|
|
38
|
+
--so-neutral-soft: #f0f0f0;
|
|
39
|
+
--so-on-accent: #ffffff;
|
|
40
|
+
--so-on-attention: var(--so-on-signal);
|
|
41
|
+
--so-on-signal: #ffffff;
|
|
42
|
+
--so-overlay: rgb(0 0 0 / .32);
|
|
43
|
+
/* Paper: every sheet, card, field, menu and dialog. */
|
|
44
|
+
--so-paper: #ffffff;
|
|
45
|
+
--so-phone-block: 14px;
|
|
46
|
+
--so-phone-card: 12px;
|
|
47
|
+
--so-phone-gap: 12px;
|
|
48
|
+
--so-phone-gutter: 16px;
|
|
49
|
+
--so-phone-row: 8px;
|
|
50
|
+
--so-pill-shadow: 0px 0px 0px 1px rgb(0 0 0 / .06), 0px 1px 2px 0px rgb(0 0 0 / .06);
|
|
51
|
+
--so-radius-badge: 5px;
|
|
52
|
+
--so-radius-card: 10px;
|
|
53
|
+
--so-radius-full: 9999px;
|
|
54
|
+
--so-radius-md: 8px;
|
|
55
|
+
--so-radius-sheet: 12px;
|
|
56
|
+
--so-radius-sm: 6px;
|
|
57
|
+
/* Raised: segmented-tab tracks, notices, row hover fills, and the muted well behind a "next step" block or a neutral problem line. */
|
|
58
|
+
--so-raised: #f5f5f5;
|
|
59
|
+
--so-scroll: #cfcfcf;
|
|
60
|
+
/* Selection: text selection highlight, with ink text on it. */
|
|
61
|
+
--so-selection: #d4d4d4;
|
|
62
|
+
--so-shadow-overlay: 0px 0px 0px 1px rgb(0 0 0 / .08), 0px 24px 48px -12px rgb(0 0 0 / .22);
|
|
63
|
+
--so-sheet-shadow: 0px 0px 0px 1px rgb(0 0 0 / .06), 0px 1px 2px 0px rgb(0 0 0 / .04), 0px 4px 12px -6px rgb(0 0 0 / .06);
|
|
64
|
+
--so-sidebar: #efefef;
|
|
65
|
+
/* Ink accent: the default accent, used for what waits on a person. */
|
|
66
|
+
--so-signal: #171717;
|
|
67
|
+
--so-signal-hover: #383838;
|
|
68
|
+
/* Ink wash: the fill behind attention badge text and the 3px focus halo around a focused field or composer — one step stronger than the neutral badge fill, so a waiting badge still reads first. */
|
|
69
|
+
--so-signal-soft: #e8e8e8;
|
|
70
|
+
/* Soft: hover fills on outline and ghost buttons, menu items and suggestions. */
|
|
71
|
+
--so-soft: #f2f2f2;
|
|
72
|
+
--so-space-2xl: 24px;
|
|
73
|
+
--so-space-3xl: 28px;
|
|
74
|
+
--so-space-lg: 16px;
|
|
75
|
+
--so-space-md: 12px;
|
|
76
|
+
--so-space-sm: 8px;
|
|
77
|
+
--so-space-xl: 20px;
|
|
78
|
+
--so-space-xs: 4px;
|
|
79
|
+
/* Built Green: done and passed, used for "Checks passed", "Open now" and a finished live step. */
|
|
80
|
+
--so-success: #218358;
|
|
81
|
+
--so-success-soft: #e6f6eb;
|
|
82
|
+
--so-typography-badge: var(--so-typography-badge-font-weight) var(--so-typography-badge-font-size)/var(--so-typography-badge-line-height) var(--so-typography-badge-font-family);
|
|
83
|
+
--so-typography-badge-font-family: var(--so-font-sans);
|
|
84
|
+
--so-typography-badge-font-size: 11.5px;
|
|
85
|
+
--so-typography-badge-font-weight: 500;
|
|
86
|
+
--so-typography-badge-line-height: 1.5652;
|
|
87
|
+
--so-typography-body: var(--so-typography-body-font-weight) var(--so-typography-body-font-size)/var(--so-typography-body-line-height) var(--so-typography-body-font-family);
|
|
88
|
+
--so-typography-body-font-family: var(--so-font-sans);
|
|
89
|
+
--so-typography-body-font-size: 13px;
|
|
90
|
+
--so-typography-body-font-weight: 400;
|
|
91
|
+
--so-typography-body-line-height: 1.5;
|
|
92
|
+
--so-typography-body-reading: var(--so-typography-body-reading-font-weight) var(--so-typography-body-reading-font-size)/var(--so-typography-body-reading-line-height) var(--so-typography-body-reading-font-family);
|
|
93
|
+
--so-typography-body-reading-font-family: var(--so-font-sans);
|
|
94
|
+
--so-typography-body-reading-font-size: 14px;
|
|
95
|
+
--so-typography-body-reading-font-weight: 400;
|
|
96
|
+
--so-typography-body-reading-line-height: 1.7;
|
|
97
|
+
--so-typography-caption: var(--so-typography-caption-font-weight) var(--so-typography-caption-font-size)/var(--so-typography-caption-line-height) var(--so-typography-caption-font-family);
|
|
98
|
+
--so-typography-caption-font-family: var(--so-font-sans);
|
|
99
|
+
--so-typography-caption-font-size: 12px;
|
|
100
|
+
--so-typography-caption-font-weight: 500;
|
|
101
|
+
--so-typography-caption-line-height: 1.5;
|
|
102
|
+
--so-typography-display: var(--so-typography-display-font-weight) var(--so-typography-display-font-size)/var(--so-typography-display-line-height) var(--so-typography-display-font-family);
|
|
103
|
+
--so-typography-display-font-family: var(--so-font-sans);
|
|
104
|
+
--so-typography-display-font-size: 26px;
|
|
105
|
+
--so-typography-display-font-weight: 600;
|
|
106
|
+
--so-typography-display-letter-spacing: -0.65px;
|
|
107
|
+
--so-typography-display-line-height: 1.25;
|
|
108
|
+
--so-typography-headline: var(--so-typography-headline-font-weight) var(--so-typography-headline-font-size)/var(--so-typography-headline-line-height) var(--so-typography-headline-font-family);
|
|
109
|
+
--so-typography-headline-font-family: var(--so-font-sans);
|
|
110
|
+
--so-typography-headline-font-size: 18px;
|
|
111
|
+
--so-typography-headline-font-weight: 600;
|
|
112
|
+
--so-typography-headline-line-height: 1.375;
|
|
113
|
+
--so-typography-label: var(--so-typography-label-font-weight) var(--so-typography-label-font-size)/var(--so-typography-label-line-height) var(--so-typography-label-font-family);
|
|
114
|
+
--so-typography-label-font-family: var(--so-font-sans);
|
|
115
|
+
--so-typography-label-font-size: 13px;
|
|
116
|
+
--so-typography-label-font-weight: 500;
|
|
117
|
+
--so-typography-label-line-height: 1.2;
|
|
118
|
+
--so-typography-mono: var(--so-typography-mono-font-weight) var(--so-typography-mono-font-size)/var(--so-typography-mono-line-height) var(--so-typography-mono-font-family);
|
|
119
|
+
--so-typography-mono-count: var(--so-typography-mono-count-font-weight) var(--so-typography-mono-count-font-size)/var(--so-typography-mono-count-line-height) var(--so-typography-mono-count-font-family);
|
|
120
|
+
--so-typography-mono-count-font-family: var(--so-font-mono);
|
|
121
|
+
--so-typography-mono-count-font-size: 11px;
|
|
122
|
+
--so-typography-mono-count-font-weight: 500;
|
|
123
|
+
--so-typography-mono-count-line-height: 1;
|
|
124
|
+
--so-typography-mono-font-family: var(--so-font-mono);
|
|
125
|
+
--so-typography-mono-font-size: 12px;
|
|
126
|
+
--so-typography-mono-font-weight: 400;
|
|
127
|
+
--so-typography-mono-line-height: 1.5;
|
|
128
|
+
--so-typography-title: var(--so-typography-title-font-weight) var(--so-typography-title-font-size)/var(--so-typography-title-line-height) var(--so-typography-title-font-family);
|
|
129
|
+
--so-typography-title-font-family: var(--so-font-sans);
|
|
130
|
+
--so-typography-title-font-size: 15px;
|
|
131
|
+
--so-typography-title-font-weight: 600;
|
|
132
|
+
--so-typography-title-letter-spacing: -0.15px;
|
|
133
|
+
--so-typography-title-line-height: 1.4;
|
|
134
|
+
--so-typography-title-sm: var(--so-typography-title-sm-font-weight) var(--so-typography-title-sm-font-size)/var(--so-typography-title-sm-line-height) var(--so-typography-title-sm-font-family);
|
|
135
|
+
--so-typography-title-sm-font-family: var(--so-font-sans);
|
|
136
|
+
--so-typography-title-sm-font-size: 14px;
|
|
137
|
+
--so-typography-title-sm-font-weight: 600;
|
|
138
|
+
--so-typography-title-sm-letter-spacing: -0.14px;
|
|
139
|
+
--so-typography-title-sm-line-height: 1.3;
|
|
140
|
+
--so-user-bubble: #f2f2f2;
|
|
141
|
+
/* Amber: setup trouble and caution. */
|
|
142
|
+
--so-warning: #ab6400;
|
|
143
|
+
--so-warning-soft: #fff4d5;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
@media (prefers-color-scheme: dark) {
|
|
147
|
+
:root:not([data-theme="light"]) {
|
|
148
|
+
color-scheme: dark;
|
|
149
|
+
--so-accent: #ededed;
|
|
150
|
+
--so-accent-hover: #ffffff;
|
|
151
|
+
--so-accent-text: #ededed;
|
|
152
|
+
--so-code-bg: #111111;
|
|
153
|
+
--so-danger: #ff977d;
|
|
154
|
+
--so-danger-soft: rgb(255 151 125 / .12);
|
|
155
|
+
--so-ground: #0b0b0b;
|
|
156
|
+
--so-info: #70b8ff;
|
|
157
|
+
--so-info-soft: rgb(112 184 255 / .12);
|
|
158
|
+
--so-ink: #ededed;
|
|
159
|
+
--so-input-line: #363636;
|
|
160
|
+
--so-line: #262626;
|
|
161
|
+
--so-live: #70b8ff;
|
|
162
|
+
--so-muted: #a1a1a1;
|
|
163
|
+
--so-nav-current: #1f1f1f;
|
|
164
|
+
--so-nav-current-ink: #ededed;
|
|
165
|
+
--so-nav-hover: #171717;
|
|
166
|
+
--so-nav-ink: #a1a1a1;
|
|
167
|
+
--so-neutral-ink: #b4b4b4;
|
|
168
|
+
--so-neutral-soft: #1f1f1f;
|
|
169
|
+
--so-on-accent: #0a0a0a;
|
|
170
|
+
--so-on-signal: #0a0a0a;
|
|
171
|
+
--so-overlay: rgb(0 0 0 / .6);
|
|
172
|
+
--so-paper: #161616;
|
|
173
|
+
--so-pill-shadow: 0px 0px 0px 1px #2a2a2a, 0px 1px 2px 0px rgb(0 0 0 / .5);
|
|
174
|
+
--so-raised: #1c1c1c;
|
|
175
|
+
--so-scroll: #333333;
|
|
176
|
+
--so-selection: #3a3a3a;
|
|
177
|
+
--so-shadow-overlay: 0px 0px 0px 1px #2e2e2e, 0px 24px 48px -12px rgb(0 0 0 / .7);
|
|
178
|
+
--so-sheet-shadow: 0px 0px 0px 1px #262626, 0px 1px 2px 0px rgb(0 0 0 / .4);
|
|
179
|
+
--so-sidebar: #0b0b0b;
|
|
180
|
+
--so-signal: #ededed;
|
|
181
|
+
--so-signal-hover: #ffffff;
|
|
182
|
+
--so-signal-soft: #2e2e2e;
|
|
183
|
+
--so-soft: #1f1f1f;
|
|
184
|
+
--so-success: #3dd68c;
|
|
185
|
+
--so-success-soft: rgb(61 214 140 / .12);
|
|
186
|
+
--so-user-bubble: #202020;
|
|
187
|
+
--so-warning: #ffca16;
|
|
188
|
+
--so-warning-soft: rgb(255 202 22 / .12);
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
:root[data-theme="dark"] {
|
|
193
|
+
color-scheme: dark;
|
|
194
|
+
--so-accent: #ededed;
|
|
195
|
+
--so-accent-hover: #ffffff;
|
|
196
|
+
--so-accent-text: #ededed;
|
|
197
|
+
--so-code-bg: #111111;
|
|
198
|
+
--so-danger: #ff977d;
|
|
199
|
+
--so-danger-soft: rgb(255 151 125 / .12);
|
|
200
|
+
--so-ground: #0b0b0b;
|
|
201
|
+
--so-info: #70b8ff;
|
|
202
|
+
--so-info-soft: rgb(112 184 255 / .12);
|
|
203
|
+
--so-ink: #ededed;
|
|
204
|
+
--so-input-line: #363636;
|
|
205
|
+
--so-line: #262626;
|
|
206
|
+
--so-live: #70b8ff;
|
|
207
|
+
--so-muted: #a1a1a1;
|
|
208
|
+
--so-nav-current: #1f1f1f;
|
|
209
|
+
--so-nav-current-ink: #ededed;
|
|
210
|
+
--so-nav-hover: #171717;
|
|
211
|
+
--so-nav-ink: #a1a1a1;
|
|
212
|
+
--so-neutral-ink: #b4b4b4;
|
|
213
|
+
--so-neutral-soft: #1f1f1f;
|
|
214
|
+
--so-on-accent: #0a0a0a;
|
|
215
|
+
--so-on-signal: #0a0a0a;
|
|
216
|
+
--so-overlay: rgb(0 0 0 / .6);
|
|
217
|
+
--so-paper: #161616;
|
|
218
|
+
--so-pill-shadow: 0px 0px 0px 1px #2a2a2a, 0px 1px 2px 0px rgb(0 0 0 / .5);
|
|
219
|
+
--so-raised: #1c1c1c;
|
|
220
|
+
--so-scroll: #333333;
|
|
221
|
+
--so-selection: #3a3a3a;
|
|
222
|
+
--so-shadow-overlay: 0px 0px 0px 1px #2e2e2e, 0px 24px 48px -12px rgb(0 0 0 / .7);
|
|
223
|
+
--so-sheet-shadow: 0px 0px 0px 1px #262626, 0px 1px 2px 0px rgb(0 0 0 / .4);
|
|
224
|
+
--so-sidebar: #0b0b0b;
|
|
225
|
+
--so-signal: #ededed;
|
|
226
|
+
--so-signal-hover: #ffffff;
|
|
227
|
+
--so-signal-soft: #2e2e2e;
|
|
228
|
+
--so-soft: #1f1f1f;
|
|
229
|
+
--so-success: #3dd68c;
|
|
230
|
+
--so-success-soft: rgb(61 214 140 / .12);
|
|
231
|
+
--so-user-bubble: #202020;
|
|
232
|
+
--so-warning: #ffca16;
|
|
233
|
+
--so-warning-soft: rgb(255 202 22 / .12);
|
|
234
|
+
}
|
package/dist/desktop-update.d.ts
CHANGED
|
@@ -94,7 +94,6 @@ export declare function prepareDesktopUpdate(stateDir: string, installed: string
|
|
|
94
94
|
export declare function sqliteLock(file: string, busyTimeoutMs?: number): DatabaseSync | null;
|
|
95
95
|
export declare const installationLock: (j: UpdateJournal) => DatabaseSync | null;
|
|
96
96
|
export declare function desktopUpdateStatus(stateDir: string): {
|
|
97
|
-
version?: never;
|
|
98
97
|
active: boolean;
|
|
99
98
|
phase: string;
|
|
100
99
|
detail: string;
|
|
@@ -108,6 +107,7 @@ export declare function desktopUpdateStatus(stateDir: string): {
|
|
|
108
107
|
wasRunning?: never;
|
|
109
108
|
backupPath?: never;
|
|
110
109
|
updateId?: never;
|
|
110
|
+
version?: never;
|
|
111
111
|
buildId?: never;
|
|
112
112
|
workDir?: never;
|
|
113
113
|
} | {
|
package/dist/discord.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
/** A single leased Discord Gateway connection, hosted by the ordinary worker. */
|
|
2
2
|
import { randomBytes } from "node:crypto";
|
|
3
3
|
import { setTimeout as sleep } from "node:timers/promises";
|
|
4
|
-
import { Client, GatewayIntentBits, Partials } from "discord.js";
|
|
5
4
|
import { loadDiscordCredentials, discordApi, object, discordId, } from "./discord-api.js";
|
|
6
5
|
import { ChatState, chatHash } from "./chat-delivery-state.js";
|
|
7
6
|
import { receiveDiscord, processDiscordEvent, deliverDiscordPart, planDiscordNotifications, planDiscordRooms, } from "./discord-chat.js";
|
|
@@ -39,6 +38,8 @@ export async function followDiscord(options) {
|
|
|
39
38
|
};
|
|
40
39
|
const problem = (message) => state.setProblem(credentials.installation, owner, message);
|
|
41
40
|
const api = discordApi(credentials.botToken);
|
|
41
|
+
// The SDK loads once Discord is set up, not with every command that could host the follower.
|
|
42
|
+
const { Client, GatewayIntentBits, Partials } = await import("discord.js");
|
|
42
43
|
const client = new Client({
|
|
43
44
|
// Guild messages and their content are needed for rooms; the Message
|
|
44
45
|
// Content intent must be enabled for the app in Discord's developer portal.
|
package/dist/evidence-pack.js
CHANGED
|
@@ -84,7 +84,7 @@ export function evidencePack(store, taskId, access, who, now, evidenceRoot, chec
|
|
|
84
84
|
result: receipt === null ? null : {
|
|
85
85
|
runId: receipt.runId, base: receipt.base, head: receipt.head, kind: receipt.completionKind,
|
|
86
86
|
checks: { status: receipt.checks.status, command: receipt.checks.command, exitCode: receipt.checks.exitCode, detail: receipt.checks.detail },
|
|
87
|
-
completedBy: assignment?.completion?.actor ?? null, completedAt: assignment?.completion?.at ?? null, caveats: receipt.caveats,
|
|
87
|
+
completedBy: assignment?.completion?.landed !== undefined ? `Toolroll, automatically: ${assignment.completion.landed}` : assignment?.completion?.actor ?? null, completedAt: assignment?.completion?.at ?? null, caveats: receipt.caveats,
|
|
88
88
|
publication: assignment?.publication ?? null,
|
|
89
89
|
},
|
|
90
90
|
totals: { runs: allRuns.length, costUsd: Math.round(sum(run => run.costUsd) * 1e6) / 1e6, tokensIn: sum(run => run.tokensIn), tokensOut: sum(run => run.tokensOut) },
|
package/dist/evidence.d.ts
CHANGED
|
@@ -47,6 +47,13 @@ export declare const PROGRESS_PREFIX = "STANDING-ORDERS-PROGRESS-";
|
|
|
47
47
|
* (adaptive execution plans): a terminal file like park or proof, written
|
|
48
48
|
* at most once, read once at settlement. */
|
|
49
49
|
export declare const PROPOSAL_PREFIX = "STANDING-ORDERS-PROPOSAL-";
|
|
50
|
+
/** The running build's steering mailbox: a FOLDER, not a file. The pulse
|
|
51
|
+
* writes each operator note into it as NNN.json (a temp name, then a
|
|
52
|
+
* rename); the agent acknowledges a note by moving it into `handled/`. */
|
|
53
|
+
export declare const STEER_PREFIX = "STANDING-ORDERS-STEER-";
|
|
54
|
+
/** The running build's status file (Agents board): JSON lines the agent appends
|
|
55
|
+
* (working, needs-decision, blocked, done), read forward by the pulse. */
|
|
56
|
+
export declare const STATUS_PREFIX = "STANDING-ORDERS-STATUS-";
|
|
50
57
|
export declare const MAILBOX_SUFFIX = ".json";
|
|
51
58
|
/** v105: left in a run's evidence folder when the retention setting removed its files (retention.ts). */
|
|
52
59
|
export declare const RETENTION_NOTE = "REMOVED-BY-RETENTION";
|
|
@@ -78,6 +85,14 @@ export declare function looksLikeMailbox(name: string): boolean;
|
|
|
78
85
|
* The pre-rename NIGHTORDERS- prefix stays recognized here — a worktree cut
|
|
79
86
|
* down before 2026-08-13 may still hold one, and cleanup has no vintage. */
|
|
80
87
|
export declare function looksLikeProtocolFile(name: string): boolean;
|
|
88
|
+
/** A steering mailbox folder, or anything in it, as a directory listing or
|
|
89
|
+
* `git status` names it: an untracked folder is reported with a trailing
|
|
90
|
+
* slash, or file by file where a repository shows every untracked file. */
|
|
91
|
+
export declare function looksLikeSteerFolder(name: string): boolean;
|
|
92
|
+
/** An agent status file (Agents board), by its exact nonce-shaped name. */
|
|
93
|
+
export declare function looksLikeStatusFile(name: string): boolean;
|
|
94
|
+
export declare function statusFileName(): string;
|
|
95
|
+
export declare function steerFolderName(): string;
|
|
81
96
|
export declare function handoffName(): string;
|
|
82
97
|
export declare function planFileName(): string;
|
|
83
98
|
/** The build's optional proof manifest (Priority 2), named exactly like
|
|
@@ -208,6 +223,19 @@ export declare function readVerifiedArtifact(root: string, artifact: Artifact):
|
|
|
208
223
|
ok: false;
|
|
209
224
|
problem: string;
|
|
210
225
|
};
|
|
226
|
+
/**
|
|
227
|
+
* Whether an artifact's bytes still verify, without returning them. Status
|
|
228
|
+
* sweeps ask this of every artifact of every run, so a file proved earlier and
|
|
229
|
+
* not touched since (same artifact row, device, inode, size, mtime and ctime
|
|
230
|
+
* on the descriptor just opened) costs an fstat, not a re-read and SHA-256.
|
|
231
|
+
* Every path check still runs on each call; a changed or new file is hashed.
|
|
232
|
+
*/
|
|
233
|
+
export declare function verifyArtifact(root: string, artifact: Artifact): {
|
|
234
|
+
ok: true;
|
|
235
|
+
} | {
|
|
236
|
+
ok: false;
|
|
237
|
+
problem: string;
|
|
238
|
+
};
|
|
211
239
|
/** The file alone, no row — quarantines use this; they belong to no live run. */
|
|
212
240
|
export declare function writeEvidenceFile(root: string, runId: number, name: string, content: Buffer): string;
|
|
213
241
|
/**
|
package/dist/evidence.js
CHANGED
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
* store holds keys relative to that root, never absolute paths.
|
|
15
15
|
*/
|
|
16
16
|
import { createHash, randomBytes } from "node:crypto";
|
|
17
|
-
import { closeSync, existsSync, constants, fstatSync, mkdirSync, openSync, readdirSync, readSync, realpathSync, unlinkSync, writeFileSync, } from "node:fs";
|
|
17
|
+
import { closeSync, existsSync, constants, fstatSync, mkdirSync, openSync, readdirSync, readSync, realpathSync, rmSync, unlinkSync, writeFileSync, } from "node:fs";
|
|
18
18
|
import { join, sep } from "node:path";
|
|
19
19
|
import { namedPath } from "./names.js";
|
|
20
20
|
import { LIMITS } from "./decision.js";
|
|
@@ -50,6 +50,13 @@ export const PROGRESS_PREFIX = "STANDING-ORDERS-PROGRESS-";
|
|
|
50
50
|
* (adaptive execution plans): a terminal file like park or proof, written
|
|
51
51
|
* at most once, read once at settlement. */
|
|
52
52
|
export const PROPOSAL_PREFIX = "STANDING-ORDERS-PROPOSAL-";
|
|
53
|
+
/** The running build's steering mailbox: a FOLDER, not a file. The pulse
|
|
54
|
+
* writes each operator note into it as NNN.json (a temp name, then a
|
|
55
|
+
* rename); the agent acknowledges a note by moving it into `handled/`. */
|
|
56
|
+
export const STEER_PREFIX = "STANDING-ORDERS-STEER-";
|
|
57
|
+
/** The running build's status file (Agents board): JSON lines the agent appends
|
|
58
|
+
* (working, needs-decision, blocked, done), read forward by the pulse. */
|
|
59
|
+
export const STATUS_PREFIX = "STANDING-ORDERS-STATUS-";
|
|
53
60
|
export const MAILBOX_SUFFIX = ".json";
|
|
54
61
|
/** v105: left in a run's evidence folder when the retention setting removed its files (retention.ts). */
|
|
55
62
|
export const RETENTION_NOTE = "REMOVED-BY-RETENTION";
|
|
@@ -128,6 +135,8 @@ export function looksLikeMailbox(name) {
|
|
|
128
135
|
* The pre-rename NIGHTORDERS- prefix stays recognized here — a worktree cut
|
|
129
136
|
* down before 2026-08-13 may still hold one, and cleanup has no vintage. */
|
|
130
137
|
export function looksLikeProtocolFile(name) {
|
|
138
|
+
if (looksLikeSteerFolder(name) || looksLikeStatusFile(name))
|
|
139
|
+
return true;
|
|
131
140
|
return ((name.startsWith(MAILBOX_PREFIX) ||
|
|
132
141
|
name.startsWith(HANDOFF_PREFIX) ||
|
|
133
142
|
name.startsWith(PLAN_PREFIX) ||
|
|
@@ -141,6 +150,22 @@ export function looksLikeProtocolFile(name) {
|
|
|
141
150
|
name.startsWith("NIGHTORDERS-")) &&
|
|
142
151
|
name.endsWith(MAILBOX_SUFFIX));
|
|
143
152
|
}
|
|
153
|
+
/** A steering mailbox folder, or anything in it, as a directory listing or
|
|
154
|
+
* `git status` names it: an untracked folder is reported with a trailing
|
|
155
|
+
* slash, or file by file where a repository shows every untracked file. */
|
|
156
|
+
export function looksLikeSteerFolder(name) {
|
|
157
|
+
return /^STANDING-ORDERS-STEER-[0-9a-f]{16}(?:\/.*)?$/.test(name);
|
|
158
|
+
}
|
|
159
|
+
/** An agent status file (Agents board), by its exact nonce-shaped name. */
|
|
160
|
+
export function looksLikeStatusFile(name) {
|
|
161
|
+
return /^STANDING-ORDERS-STATUS-[0-9a-f]{16}\.jsonl$/.test(name);
|
|
162
|
+
}
|
|
163
|
+
export function statusFileName() {
|
|
164
|
+
return `${STATUS_PREFIX}${randomBytes(8).toString("hex")}.jsonl`;
|
|
165
|
+
}
|
|
166
|
+
export function steerFolderName() {
|
|
167
|
+
return `${STEER_PREFIX}${randomBytes(8).toString("hex")}`;
|
|
168
|
+
}
|
|
144
169
|
export function handoffName() {
|
|
145
170
|
return `${HANDOFF_PREFIX}${randomBytes(8).toString("hex")}${MAILBOX_SUFFIX}`;
|
|
146
171
|
}
|
|
@@ -412,6 +437,29 @@ export function storeEvidence(store, root, runId, kind, name, content, capture,
|
|
|
412
437
|
// Recovery uses this read boundary for retained receipts and handoffs: inspecting
|
|
413
438
|
// bytes must never reseal a missing artifact or turn a saved failure into a pass.
|
|
414
439
|
export function readVerifiedArtifact(root, artifact) {
|
|
440
|
+
return withArtifactFile(root, artifact, readAndHash);
|
|
441
|
+
}
|
|
442
|
+
/**
|
|
443
|
+
* Whether an artifact's bytes still verify, without returning them. Status
|
|
444
|
+
* sweeps ask this of every artifact of every run, so a file proved earlier and
|
|
445
|
+
* not touched since (same artifact row, device, inode, size, mtime and ctime
|
|
446
|
+
* on the descriptor just opened) costs an fstat, not a re-read and SHA-256.
|
|
447
|
+
* Every path check still runs on each call; a changed or new file is hashed.
|
|
448
|
+
*/
|
|
449
|
+
export function verifyArtifact(root, artifact) {
|
|
450
|
+
return withArtifactFile(root, artifact, (fd, stat, memoKey) => {
|
|
451
|
+
if (VERIFIED_FILES.get(memoKey) === fileIdentity(artifact, stat))
|
|
452
|
+
return { ok: true };
|
|
453
|
+
const read = readAndHash(fd, stat, memoKey, artifact);
|
|
454
|
+
return read.ok ? { ok: true } : read;
|
|
455
|
+
});
|
|
456
|
+
}
|
|
457
|
+
/** Files proved by an earlier read, keyed by artifact and resolved path. Bounded; the oldest proof is forgotten first. */
|
|
458
|
+
const VERIFIED_FILES = new Map();
|
|
459
|
+
const VERIFIED_FILES_LIMIT = 20_000;
|
|
460
|
+
const fileIdentity = (artifact, stat) => [artifact.sha256, artifact.bytesStored, stat.dev, stat.ino, stat.size, stat.mtimeNs, stat.ctimeNs].join(":");
|
|
461
|
+
/** The checks both readers share, on the descriptor `use` then reads. */
|
|
462
|
+
function withArtifactFile(root, artifact, use) {
|
|
415
463
|
const segments = artifact.key.split("/");
|
|
416
464
|
const wellFormed = segments.length > 0 &&
|
|
417
465
|
segments.every(segment => segment.length > 0 &&
|
|
@@ -447,32 +495,40 @@ export function readVerifiedArtifact(root, artifact) {
|
|
|
447
495
|
return { ok: false, problem: "cannot open the file without following a link" };
|
|
448
496
|
}
|
|
449
497
|
try {
|
|
450
|
-
const stat = fstatSync(fd);
|
|
498
|
+
const stat = fstatSync(fd, { bigint: true });
|
|
451
499
|
if (!stat.isFile())
|
|
452
500
|
return { ok: false, problem: "not a regular file" };
|
|
453
501
|
if (Number(stat.size) !== artifact.bytesStored) {
|
|
454
502
|
return { ok: false, problem: "the file's size no longer matches its record" };
|
|
455
503
|
}
|
|
456
|
-
|
|
457
|
-
let offset = 0;
|
|
458
|
-
while (offset < buffer.length) {
|
|
459
|
-
const read = readSync(fd, buffer, offset, buffer.length - offset, offset);
|
|
460
|
-
if (read <= 0)
|
|
461
|
-
break;
|
|
462
|
-
offset += read;
|
|
463
|
-
}
|
|
464
|
-
if (offset !== buffer.length)
|
|
465
|
-
return { ok: false, problem: "the file ended early" };
|
|
466
|
-
const digest = createHash("sha256").update(buffer).digest("hex");
|
|
467
|
-
if (digest !== artifact.sha256) {
|
|
468
|
-
return { ok: false, problem: "the file no longer hashes to its record" };
|
|
469
|
-
}
|
|
470
|
-
return { ok: true, content: buffer };
|
|
504
|
+
return use(fd, stat, `${artifact.id}\0${resolved}`, artifact);
|
|
471
505
|
}
|
|
472
506
|
finally {
|
|
473
507
|
closeSync(fd);
|
|
474
508
|
}
|
|
475
509
|
}
|
|
510
|
+
/** Read the whole file from the open descriptor; only bytes matching the row's SHA-256 leave, and only they are remembered as proved. */
|
|
511
|
+
function readAndHash(fd, stat, memoKey, artifact) {
|
|
512
|
+
VERIFIED_FILES.delete(memoKey);
|
|
513
|
+
const buffer = Buffer.alloc(artifact.bytesStored);
|
|
514
|
+
let offset = 0;
|
|
515
|
+
while (offset < buffer.length) {
|
|
516
|
+
const read = readSync(fd, buffer, offset, buffer.length - offset, offset);
|
|
517
|
+
if (read <= 0)
|
|
518
|
+
break;
|
|
519
|
+
offset += read;
|
|
520
|
+
}
|
|
521
|
+
if (offset !== buffer.length)
|
|
522
|
+
return { ok: false, problem: "the file ended early" };
|
|
523
|
+
const digest = createHash("sha256").update(buffer).digest("hex");
|
|
524
|
+
if (digest !== artifact.sha256) {
|
|
525
|
+
return { ok: false, problem: "the file no longer hashes to its record" };
|
|
526
|
+
}
|
|
527
|
+
if (VERIFIED_FILES.size >= VERIFIED_FILES_LIMIT)
|
|
528
|
+
VERIFIED_FILES.delete(VERIFIED_FILES.keys().next().value);
|
|
529
|
+
VERIFIED_FILES.set(memoKey, fileIdentity(artifact, stat));
|
|
530
|
+
return { ok: true, content: buffer };
|
|
531
|
+
}
|
|
476
532
|
/** The file alone, no row — quarantines use this; they belong to no live run. */
|
|
477
533
|
export function writeEvidenceFile(root, runId, name, content) {
|
|
478
534
|
const dir = join(root, String(runId));
|
|
@@ -502,6 +558,20 @@ export function quarantineMailboxes(worktree, root, runId) {
|
|
|
502
558
|
if (!looksLikeProtocolFile(name))
|
|
503
559
|
continue;
|
|
504
560
|
const path = join(worktree, name);
|
|
561
|
+
// An earlier attempt's steering folder holds copies of notes the
|
|
562
|
+
// database already keeps: removed whole (a symlink is removed, never
|
|
563
|
+
// followed), never quarantined. So is its status file: the database
|
|
564
|
+
// already read every line it will ever need.
|
|
565
|
+
if (looksLikeSteerFolder(name) || looksLikeStatusFile(name)) {
|
|
566
|
+
try {
|
|
567
|
+
rmSync(path, { recursive: true, force: true });
|
|
568
|
+
swept.push(name);
|
|
569
|
+
}
|
|
570
|
+
catch {
|
|
571
|
+
// Its name carries an old nonce; nothing reads it again.
|
|
572
|
+
}
|
|
573
|
+
continue;
|
|
574
|
+
}
|
|
505
575
|
if (root !== null && runId !== null) {
|
|
506
576
|
const read = readMailbox(path);
|
|
507
577
|
if (read.ok) {
|
package/dist/exec.d.ts
CHANGED
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
import { type ProcessTreeObserver } from "./process-tree.js";
|
|
10
10
|
import { type ContainmentBackendId } from "./containment.js";
|
|
11
11
|
import type { Store } from "./store.js";
|
|
12
|
+
import type { LiveInput } from "./live-input.js";
|
|
12
13
|
export type ExecResult = {
|
|
13
14
|
/** Process exit code, or one of the synthetic codes below. */
|
|
14
15
|
code: number;
|
|
@@ -112,6 +113,15 @@ export type RunOptions = ProcessTreeObserver & {
|
|
|
112
113
|
* currently only the streaming transport can deliver this early).
|
|
113
114
|
*/
|
|
114
115
|
onSessionId?: (id: string) => void;
|
|
116
|
+
/**
|
|
117
|
+
* Live input (live-input.ts): a Claude transport that declares `streamInput`
|
|
118
|
+
* keeps stdin piped and open, hands it to this session, and shows it every
|
|
119
|
+
* stdout event. The session sends the brief first and decides when stdin
|
|
120
|
+
* closes; the run then ends with the process, and the LAST primary result
|
|
121
|
+
* is the accounting envelope (one result per turn), with every main
|
|
122
|
+
* result's usage and turns added up (cumulativeLiveResult).
|
|
123
|
+
*/
|
|
124
|
+
liveInput?: LiveInput;
|
|
115
125
|
/** Fires once the child exists, with its pid (the process-group id when
|
|
116
126
|
* processGroup is set) — the slot ledger records it (v14 finding 26). */
|
|
117
127
|
onSpawn?: (pid: number) => void;
|
|
@@ -202,6 +212,17 @@ export declare function run(file: string, args: readonly string[], options?: Run
|
|
|
202
212
|
* worst useful case while remaining a hard, per-event memory boundary.
|
|
203
213
|
*/
|
|
204
214
|
export declare const JSONL_EVENT_HARD_CAP: number;
|
|
215
|
+
/**
|
|
216
|
+
* The accounting an oversized Claude result still carries, read by a bounded scan of its kept prefix and tail: the
|
|
217
|
+
* session's running `total_cost_usd`, its `usage` and `num_turns`, and whether it is a main result at all (an
|
|
218
|
+
* `origin` naming anything but a person makes it a background task's). Anything unreadable or seen twice is absent.
|
|
219
|
+
*/
|
|
220
|
+
export declare function scanOversizedClaudeResult(prefix: Buffer, tail: Buffer | undefined): {
|
|
221
|
+
primary: boolean;
|
|
222
|
+
account: Record<string, unknown>;
|
|
223
|
+
};
|
|
224
|
+
/** Marks a Claude result whose session cost could not be read: the gateway charges the run's dollar cap instead. */
|
|
225
|
+
export declare const CLAUDE_COST_UNKNOWN = "standing_orders_cost_unknown";
|
|
205
226
|
export declare function runStreamJsonl(file: string, args: readonly string[], options?: RunOptions): Promise<ExecResult>;
|
|
206
227
|
/**
|
|
207
228
|
* The streaming transport for gemini's stream-json dialect (Phase 3 D1/A7).
|
|
@@ -225,4 +246,15 @@ export declare function runStreamJsonl(file: string, args: readonly string[], op
|
|
|
225
246
|
* semantics match `runStreamJsonl`.
|
|
226
247
|
*/
|
|
227
248
|
export declare function runGeminiStreamJsonl(file: string, args: readonly string[], options?: RunOptions): Promise<ExecResult>;
|
|
249
|
+
/**
|
|
250
|
+
* A live session's account so far (one main result per turn, checked on Claude Code 2.1.290): the latest result's
|
|
251
|
+
* session, ending, words and cost — `total_cost_usd` is already the session's running total — with the usage token
|
|
252
|
+
* fields and `num_turns`, which count only their own message, added up across every main result. A field that is not
|
|
253
|
+
* a non-negative number adds nothing.
|
|
254
|
+
*/
|
|
255
|
+
export declare function cumulativeLiveResult(previous: Record<string, unknown>, latest: Record<string, unknown>): Record<string, unknown>;
|
|
256
|
+
/** This transport can keep stdin open for a live session (RunOptions.liveInput). */
|
|
257
|
+
export declare const STREAM_INPUT: unique symbol;
|
|
258
|
+
/** Whether a runner declares it keeps stdin open for a live session; an injected runner opts in by carrying the mark. */
|
|
259
|
+
export declare const streamsInput: (runner: unknown) => boolean;
|
|
228
260
|
export declare function runClaudeStreamJsonl(file: string, args: readonly string[], options?: RunOptions): Promise<ExecResult>;
|