toolroll 0.9.17 → 0.9.18
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 +11 -0
- package/dist/browser/workspace.js +14 -14
- package/dist/browser-workspace.d.ts +2 -0
- package/dist/chat-decide.d.ts +203 -0
- package/dist/chat-decide.js +554 -0
- package/dist/chat-delivery-state.d.ts +5 -0
- package/dist/chat-delivery.js +32 -1
- package/dist/chat-quiet.d.ts +4 -1
- package/dist/chat-quiet.js +6 -2
- package/dist/desktop-update.d.ts +1 -1
- package/dist/discord-api.d.ts +2 -0
- package/dist/discord-api.js +3 -1
- package/dist/discord-chat.js +17 -3
- package/dist/modes.d.ts +6 -0
- package/dist/modes.js +6 -0
- package/dist/operate.js +18 -8
- package/dist/project-delete.js +3 -0
- package/dist/result-shots.d.ts +51 -0
- package/dist/result-shots.js +119 -0
- package/dist/serve.js +23 -21
- package/dist/slack-chat.js +18 -4
- package/dist/store.d.ts +24 -0
- package/dist/store.js +119 -7
- package/dist/teams-chat.js +5 -0
- package/dist/telegram-mate.d.ts +10 -0
- package/dist/telegram.d.ts +5 -3
- package/dist/telegram.js +226 -20
- package/package.json +1 -1
|
@@ -225,6 +225,8 @@ export type BrowserSettingsView = {
|
|
|
225
225
|
chat?: {
|
|
226
226
|
mode: 'quiet' | 'all';
|
|
227
227
|
digestAt: string | null;
|
|
228
|
+
/** Whether a result's saved screenshots follow its chat message: off, the first one, or up to 4. */
|
|
229
|
+
screenshots?: 'off' | 'first' | 'all';
|
|
228
230
|
/** Each project this person can see; a muted one sends no pings but stays in Tasks and the digest. */
|
|
229
231
|
projects?: {
|
|
230
232
|
repo: string;
|
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
import { type ModeTerms } from "./modes.js";
|
|
2
|
+
import { type VerifiedApprover } from "./principal.js";
|
|
3
|
+
import type { Scope } from "./scope.js";
|
|
4
|
+
import type { Store } from "./store.js";
|
|
5
|
+
/** The tokens live in chat_decide_action and the open "What should change?" in chat_decide_prompt (store.ts). */
|
|
6
|
+
export type DecideAct = "accept" | "changes" | "retry" | "approve" | "not-now" | "merge";
|
|
7
|
+
export type DecideTarget = {
|
|
8
|
+
kind: "result";
|
|
9
|
+
taskId: string;
|
|
10
|
+
run: number;
|
|
11
|
+
} | {
|
|
12
|
+
kind: "failed";
|
|
13
|
+
taskId: string;
|
|
14
|
+
} | {
|
|
15
|
+
kind: "plan";
|
|
16
|
+
taskId: string;
|
|
17
|
+
} | {
|
|
18
|
+
kind: "merge";
|
|
19
|
+
taskId: string;
|
|
20
|
+
run: number;
|
|
21
|
+
};
|
|
22
|
+
export type DecideChannel = "telegram" | "slack" | "discord" | "teams";
|
|
23
|
+
/** Who is tapping, where: one paired person's binding on one channel, and the chat the card is in. */
|
|
24
|
+
export type DecideSeat = {
|
|
25
|
+
channel: DecideChannel;
|
|
26
|
+
binding: number;
|
|
27
|
+
chat: string;
|
|
28
|
+
approver: string;
|
|
29
|
+
generation: number;
|
|
30
|
+
};
|
|
31
|
+
export type DecideLink = {
|
|
32
|
+
label: string;
|
|
33
|
+
path: string;
|
|
34
|
+
};
|
|
35
|
+
/** A button as a channel draws it: an act (its token) or a link to the console. */
|
|
36
|
+
export type DecideButton = {
|
|
37
|
+
label: string;
|
|
38
|
+
token: string;
|
|
39
|
+
} | {
|
|
40
|
+
label: string;
|
|
41
|
+
link: DecideLink;
|
|
42
|
+
};
|
|
43
|
+
/** The words, said once. */
|
|
44
|
+
export declare const DECIDE_LABELS: {
|
|
45
|
+
readonly accept: "Accept and finish";
|
|
46
|
+
readonly changes: "Request changes";
|
|
47
|
+
readonly retry: "Retry";
|
|
48
|
+
readonly approve: "Approve & start";
|
|
49
|
+
readonly "not-now": "Not now";
|
|
50
|
+
readonly merge: "Merge";
|
|
51
|
+
readonly look: "Look first";
|
|
52
|
+
readonly edit: "Edit";
|
|
53
|
+
readonly yes: "Yes";
|
|
54
|
+
readonly cancel: "Cancel";
|
|
55
|
+
};
|
|
56
|
+
export declare const WHAT_SHOULD_CHANGE = "What should change?";
|
|
57
|
+
type ActSpec = {
|
|
58
|
+
act: DecideAct;
|
|
59
|
+
run: number | null;
|
|
60
|
+
digest: string;
|
|
61
|
+
};
|
|
62
|
+
/** What a card offers: an optional replacement text (the plan card) and rows of acts and links. */
|
|
63
|
+
export type DecideOffer = {
|
|
64
|
+
text: string | null;
|
|
65
|
+
rows: Array<Array<ActSpec | DecideLink>>;
|
|
66
|
+
};
|
|
67
|
+
/** The live mode on this repository, when it lets this person's chat approve: the term signed, by them. */
|
|
68
|
+
export declare function chatApproveMode(store: Store, repo: string | null, approver: string, now: Date): {
|
|
69
|
+
ok: true;
|
|
70
|
+
digest: string;
|
|
71
|
+
terms: ModeTerms;
|
|
72
|
+
} | {
|
|
73
|
+
ok: false;
|
|
74
|
+
why: string;
|
|
75
|
+
};
|
|
76
|
+
/** What a plan's yes allows an agent to do, in a few plain words (the approval sheet's "You're allowing"). */
|
|
77
|
+
export declare function permissionPlainWords(profile: Scope["profile"] | null | undefined): string | null;
|
|
78
|
+
/** A plan this person's chat may approve now: the term, the plan's exact bytes, and none of the reasons it must open
|
|
79
|
+
* Toolroll instead. `digest` binds the scope and the plan document the card shows. */
|
|
80
|
+
export declare function planInChat(store: Store, taskId: string, approver: string, now: Date, root?: string): {
|
|
81
|
+
ok: true;
|
|
82
|
+
modeDigest: string;
|
|
83
|
+
digest: string;
|
|
84
|
+
scope: Scope;
|
|
85
|
+
} | {
|
|
86
|
+
ok: false;
|
|
87
|
+
why: string;
|
|
88
|
+
};
|
|
89
|
+
/** A ready pull request this person's chat may merge now, bound to the exact commit. */
|
|
90
|
+
export declare function mergeInChat(store: Store, taskId: string, run: number, approver: string, now: Date): {
|
|
91
|
+
ok: true;
|
|
92
|
+
modeDigest: string;
|
|
93
|
+
head: string;
|
|
94
|
+
} | {
|
|
95
|
+
ok: false;
|
|
96
|
+
why: string;
|
|
97
|
+
};
|
|
98
|
+
/** The plan card: title, goal in two lines, what changes, done when, and what the yes allows. */
|
|
99
|
+
export declare function planCardText(store: Store, taskId: string, scope: Scope, root?: string): string;
|
|
100
|
+
/** The acts a card about this target can take in chat right now, or null when none can (the card keeps its own
|
|
101
|
+
* link). Reads only; nothing is minted. */
|
|
102
|
+
export declare function decideOffer(store: Store, target: DecideTarget, who: VerifiedApprover, now: Date, root?: string): DecideOffer | null;
|
|
103
|
+
/** One fingerprint of what the card offers, without its tokens: a repaint with the same offer keeps its buttons. */
|
|
104
|
+
export declare function offerFingerprint(offer: DecideOffer): string;
|
|
105
|
+
/** The card's buttons, minted now (message unknown until it is sent: `placeDecideTokens` puts them on it). */
|
|
106
|
+
export declare function mintDecideButtons(store: Store, seat: DecideSeat, target: DecideTarget, offer: DecideOffer, now: Date, message?: string | null): {
|
|
107
|
+
rows: DecideButton[][];
|
|
108
|
+
tokens: string[];
|
|
109
|
+
};
|
|
110
|
+
/** Put freshly minted tokens on the message they ride: a tap on any other message proves itself stale. */
|
|
111
|
+
export declare function placeDecideTokens(store: Store, tokens: readonly string[], message: string): void;
|
|
112
|
+
/** Every live button on one message stops working: the card was repainted, or one of its acts was taken. */
|
|
113
|
+
export declare function retireDecideTokens(store: Store, channel: DecideChannel, chat: string, message: string, now: Date): void;
|
|
114
|
+
/** Buttons minted for a send or an edit that didn't land: they never act. */
|
|
115
|
+
export declare function dropDecideTokens(store: Store, tokens: readonly string[], now: Date): void;
|
|
116
|
+
/** Whether a message still carries a button that acts (an offer, or an armed Yes or Cancel): a card whose acts were
|
|
117
|
+
* all spent, as by Not now, needs fresh ones. */
|
|
118
|
+
export declare function hasLiveDecideTokens(store: Store, channel: DecideChannel, chat: string, message: string, now: Date): boolean;
|
|
119
|
+
export declare function isDecideToken(store: Store, token: string): boolean;
|
|
120
|
+
export type DecideTapOutcome = {
|
|
121
|
+
ack: string;
|
|
122
|
+
/** The card repainted: its text and buttons now. */
|
|
123
|
+
edit?: {
|
|
124
|
+
text: string;
|
|
125
|
+
rows: DecideButton[][];
|
|
126
|
+
tokens: string[];
|
|
127
|
+
};
|
|
128
|
+
/** Ask "What should change?": the person's next message is the feedback. `id` names the prompt, so the channel can
|
|
129
|
+
* record the message it sent (a reply to anything else is not the feedback). */
|
|
130
|
+
prompt?: {
|
|
131
|
+
id: number;
|
|
132
|
+
text: string;
|
|
133
|
+
};
|
|
134
|
+
/** Merge after the transaction (GitHub is a network call); the card says "Merging…" until it lands, and
|
|
135
|
+
* `recordChatMerge` ledgers how it went. */
|
|
136
|
+
merge?: ChatMerge;
|
|
137
|
+
ignored?: boolean;
|
|
138
|
+
};
|
|
139
|
+
/** A merge approved in chat, waiting on GitHub: what its ledger line names once the answer is back. */
|
|
140
|
+
export type ChatMerge = {
|
|
141
|
+
runId: number;
|
|
142
|
+
taskId: string;
|
|
143
|
+
by: string;
|
|
144
|
+
repo: string;
|
|
145
|
+
via: string;
|
|
146
|
+
};
|
|
147
|
+
/** The links a card keeps once its acts are spent or stale: where to look, never a token. */
|
|
148
|
+
export declare function linksFor(target: DecideTarget): DecideButton[][];
|
|
149
|
+
/**
|
|
150
|
+
* One tap on a decide button, inside the caller's transaction. Null: not this module's token. The seat must be the
|
|
151
|
+
* token's own (person, chat, message); a spent, expired or foreign button acts on nothing.
|
|
152
|
+
*/
|
|
153
|
+
export declare function applyDecideTap(store: Store, seat: DecideSeat, input: {
|
|
154
|
+
token: string;
|
|
155
|
+
message: string;
|
|
156
|
+
shown: string;
|
|
157
|
+
repos: readonly string[];
|
|
158
|
+
root?: string;
|
|
159
|
+
now: Date;
|
|
160
|
+
}): DecideTapOutcome | null;
|
|
161
|
+
/** A chat merge's second ledger line, after the GitHub call: merged, or failed and why (its approval is the first). */
|
|
162
|
+
export declare function recordChatMerge(store: Store, merge: ChatMerge, result: {
|
|
163
|
+
ok: true;
|
|
164
|
+
} | {
|
|
165
|
+
ok: false;
|
|
166
|
+
message: string;
|
|
167
|
+
}, now: Date): void;
|
|
168
|
+
/** What the card says once the merge came back. */
|
|
169
|
+
export declare function mergedText(shown: string, result: {
|
|
170
|
+
ok: true;
|
|
171
|
+
} | {
|
|
172
|
+
ok: false;
|
|
173
|
+
message: string;
|
|
174
|
+
}): string;
|
|
175
|
+
export type DecidePrompt = {
|
|
176
|
+
id: number;
|
|
177
|
+
taskId: string;
|
|
178
|
+
run: number;
|
|
179
|
+
digest: string;
|
|
180
|
+
message: string | null;
|
|
181
|
+
};
|
|
182
|
+
/** One open "What should change?" per person and chat: a newer one replaces it. */
|
|
183
|
+
export declare function openDecidePrompt(store: Store, seat: DecideSeat, taskId: string, run: number, digest: string, now: Date): number;
|
|
184
|
+
/** The message that asked "What should change?", once it was sent. */
|
|
185
|
+
export declare function placeDecidePrompt(store: Store, id: number, message: string): void;
|
|
186
|
+
export declare function openPromptFor(store: Store, seat: Pick<DecideSeat, "channel" | "binding" | "chat">, now: Date): DecidePrompt | null;
|
|
187
|
+
/** Whether this message answers the prompt: the person's next message, unless it replies to some other message. */
|
|
188
|
+
export declare function answersPrompt(prompt: DecidePrompt, replyTo: string | null): boolean;
|
|
189
|
+
/** The person's message after "What should change?": a revision of the exact result, with these words as its
|
|
190
|
+
* feedback, through the result page's own service. Says what was sent, once. */
|
|
191
|
+
export declare function applyDecideFeedback(store: Store, seat: DecideSeat, prompt: DecidePrompt, text: string, repos: readonly string[], root: string | undefined, now: Date): {
|
|
192
|
+
said: string;
|
|
193
|
+
link: DecideLink | null;
|
|
194
|
+
};
|
|
195
|
+
/** The link a card keeps when it can't act in chat: a plan's is Review & start, where the password step lives. */
|
|
196
|
+
export declare function decideFallbackLink(target: DecideTarget | null): DecideLink | null;
|
|
197
|
+
/** Which card a pushed notification is, from its recorded kind and task — never from its words. */
|
|
198
|
+
export declare function decideTargetOf(row: {
|
|
199
|
+
kind: string;
|
|
200
|
+
taskId: string | null;
|
|
201
|
+
run: number | null;
|
|
202
|
+
}): DecideTarget | null;
|
|
203
|
+
export {};
|