toolroll 0.9.84 → 0.9.86
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 +66 -0
- package/README.md +94 -1193
- package/dist/agent-fence.d.ts +9 -5
- package/dist/agent-fence.js +6 -5
- package/dist/agent-onboard.d.ts +2 -0
- package/dist/agent-onboard.js +3 -0
- package/dist/assignment.js +4 -3
- package/dist/browser/workspace.css +1 -1
- package/dist/browser/workspace.js +33 -31
- package/dist/browser-workspace.d.ts +45 -0
- package/dist/chat-actions.d.ts +11 -1
- package/dist/chat-actions.js +53 -1
- package/dist/chat-channel.d.ts +10 -1
- package/dist/chat-channel.js +36 -5
- package/dist/chat-decide.d.ts +16 -4
- package/dist/chat-decide.js +239 -31
- package/dist/chat-messages.d.ts +5 -0
- package/dist/chat-messages.js +1 -1
- package/dist/chat-quiet.js +6 -4
- package/dist/chat-review.d.ts +4 -0
- package/dist/chat-review.js +13 -4
- package/dist/chat-terms.d.ts +9 -0
- package/dist/chat-terms.js +46 -0
- package/dist/claim.d.ts +3 -0
- package/dist/claim.js +4 -1
- package/dist/contracts/chat-actions.d.ts +9 -0
- package/dist/contracts/chat-actions.js +3 -0
- package/dist/contracts/console-api.d.ts +6 -2
- package/dist/contracts/console-api.js +6 -2
- package/dist/contracts/flow-propose.d.ts +4 -1
- package/dist/contracts/flow-propose.js +1 -1
- package/dist/contracts/flow.d.ts +41 -0
- package/dist/contracts/flow.js +4 -2
- package/dist/contracts/lead-tools.d.ts +51 -0
- package/dist/contracts/lead-tools.js +5 -0
- package/dist/contracts/store-json.d.ts +2 -0
- package/dist/contracts/trigger-payloads.d.ts +20 -0
- package/dist/contracts/trigger-payloads.js +4 -0
- package/dist/contracts/youiyoux-request.d.ts +248 -0
- package/dist/contracts/youiyoux-request.js +152 -0
- package/dist/coordinator.js +1 -0
- package/dist/deploy-gate.js +4 -0
- package/dist/dispatch.d.ts +3 -0
- package/dist/dispatch.js +4 -1
- package/dist/flow-browser.d.ts +103 -0
- package/dist/flow-browser.js +204 -0
- package/dist/flow-cadence.d.ts +8 -2
- package/dist/flow-cadence.js +16 -3
- package/dist/flow-card-task.d.ts +9 -0
- package/dist/flow-card-task.js +15 -6
- package/dist/flow-code.d.ts +5 -1
- package/dist/flow-code.js +4 -1
- package/dist/flow-engine.js +16 -0
- package/dist/flow-live.js +9 -1
- package/dist/flow-pull-request.js +15 -7
- package/dist/flow-share.js +3 -1
- package/dist/flow-steps.d.ts +9 -1
- package/dist/flow-steps.js +55 -5
- package/dist/flow-triggers.js +55 -0
- package/dist/flows-cli.d.ts +19 -0
- package/dist/flows-cli.js +47 -2
- package/dist/flows-ui.js +11 -2
- package/dist/flows.js +5 -2
- package/dist/integrations-ui.js +9 -4
- package/dist/integrations.d.ts +9 -1
- package/dist/integrations.js +43 -2
- package/dist/landed-cleanup.d.ts +4 -0
- package/dist/landed-cleanup.js +3 -2
- package/dist/lead-capabilities.js +2 -1
- package/dist/lead-cli.js +3 -1
- package/dist/lead-tools.d.ts +2 -0
- package/dist/lead-tools.js +65 -10
- package/dist/lead-voice.js +16 -5
- package/dist/lead.d.ts +2 -0
- package/dist/lead.js +3 -3
- package/dist/operate.d.ts +2 -3
- package/dist/operate.js +226 -21
- package/dist/project-activity.d.ts +20 -0
- package/dist/project-activity.js +23 -0
- package/dist/project-cli.d.ts +1 -0
- package/dist/project-cli.js +36 -19
- package/dist/project-delete.js +7 -3
- package/dist/project-knowledge.d.ts +3 -3
- package/dist/project-outcomes.d.ts +119 -0
- package/dist/project-outcomes.js +79 -0
- package/dist/pull-request-flow.js +35 -4
- package/dist/result-actions.d.ts +4 -0
- package/dist/result-actions.js +41 -9
- package/dist/result-follow-ups.js +4 -0
- package/dist/result-review.d.ts +9 -0
- package/dist/result-review.js +45 -5
- package/dist/scope.d.ts +5 -0
- package/dist/scope.js +7 -0
- package/dist/server/chat.js +4 -2
- package/dist/server/console.css +41 -0
- package/dist/server/flows.js +15 -0
- package/dist/server/pages.js +11 -1
- package/dist/server/render-chat.js +3 -2
- package/dist/server/render-pages.d.ts +15 -2
- package/dist/server/render-pages.js +52 -4
- package/dist/server/render-results.d.ts +2 -0
- package/dist/server/render-results.js +20 -7
- package/dist/server/render-tasks.d.ts +9 -0
- package/dist/server/render-tasks.js +32 -11
- package/dist/server/route-table.js +12 -0
- package/dist/server/settings.js +18 -1
- package/dist/server/task-views.js +11 -0
- package/dist/server/tasks.d.ts +10 -0
- package/dist/server/tasks.js +95 -7
- package/dist/settings-proofs.js +1 -0
- package/dist/store.d.ts +116 -5
- package/dist/store.js +385 -24
- package/dist/surface.js +18 -2
- package/dist/task-archive.d.ts +10 -0
- package/dist/task-archive.js +16 -0
- package/dist/task-control.d.ts +1 -1
- package/dist/task-source.d.ts +13 -1
- package/dist/task-source.js +17 -1
- package/dist/telegram-lead.js +7 -5
- package/dist/telegram.js +1 -1
- package/dist/tidy.d.ts +130 -0
- package/dist/tidy.js +503 -0
- package/dist/toolroll-update.js +2 -2
- package/dist/webhooks.d.ts +6 -0
- package/dist/webhooks.js +25 -0
- package/dist/work-index.d.ts +28 -0
- package/dist/work-index.js +82 -28
- package/dist/workspace-ui.d.ts +1 -1
- package/dist/workspace-ui.js +3 -2
- package/dist/youiyoux-intake.d.ts +234 -0
- package/dist/youiyoux-intake.js +908 -0
- package/package.json +11 -8
|
@@ -168,6 +168,8 @@ declare const STORE_COLUMN_VALUES: {
|
|
|
168
168
|
operation: z.ZodEnum<{
|
|
169
169
|
decision_record: "decision_record";
|
|
170
170
|
decision_retire: "decision_retire";
|
|
171
|
+
flow_browser: "flow_browser";
|
|
172
|
+
flow_browser_off: "flow_browser_off";
|
|
171
173
|
flow_card_add: "flow_card_add";
|
|
172
174
|
flow_card_approve: "flow_card_approve";
|
|
173
175
|
flow_card_assign: "flow_card_assign";
|
|
@@ -45,6 +45,11 @@ export declare const githubRunSchema: z.ZodCatch<z.ZodObject<{
|
|
|
45
45
|
display_title: z.ZodCatch<z.ZodOptional<z.ZodString>>;
|
|
46
46
|
created_at: z.ZodCatch<z.ZodOptional<z.ZodString>>;
|
|
47
47
|
html_url: z.ZodCatch<z.ZodOptional<z.ZodString>>;
|
|
48
|
+
id: z.ZodCatch<z.ZodOptional<z.ZodNumber>>;
|
|
49
|
+
event: z.ZodCatch<z.ZodOptional<z.ZodString>>;
|
|
50
|
+
head_repository: z.ZodCatch<z.ZodOptional<z.ZodObject<{
|
|
51
|
+
full_name: z.ZodCatch<z.ZodOptional<z.ZodString>>;
|
|
52
|
+
}, z.core.$strip>>>;
|
|
48
53
|
}, z.core.$strip>>;
|
|
49
54
|
/** `repos/:repo/issues` and `repos/:repo/pulls`: a list (anything else reads as an empty one). */
|
|
50
55
|
export declare const githubIssueListSchema: z.ZodCatch<z.ZodArray<z.ZodCatch<z.ZodObject<{
|
|
@@ -111,6 +116,11 @@ export declare const githubRunListSchema: z.ZodCatch<z.ZodObject<{
|
|
|
111
116
|
display_title: z.ZodCatch<z.ZodOptional<z.ZodString>>;
|
|
112
117
|
created_at: z.ZodCatch<z.ZodOptional<z.ZodString>>;
|
|
113
118
|
html_url: z.ZodCatch<z.ZodOptional<z.ZodString>>;
|
|
119
|
+
id: z.ZodCatch<z.ZodOptional<z.ZodNumber>>;
|
|
120
|
+
event: z.ZodCatch<z.ZodOptional<z.ZodString>>;
|
|
121
|
+
head_repository: z.ZodCatch<z.ZodOptional<z.ZodObject<{
|
|
122
|
+
full_name: z.ZodCatch<z.ZodOptional<z.ZodString>>;
|
|
123
|
+
}, z.core.$strip>>>;
|
|
114
124
|
}, z.core.$strip>>>>>;
|
|
115
125
|
}, z.core.$strip>>;
|
|
116
126
|
/** A signed GitHub webhook event (`issues`, `pull_request`, `workflow_run`; a `ping` reads as an empty one). */
|
|
@@ -176,6 +186,11 @@ export declare const githubEventSchema: z.ZodCatch<z.ZodObject<{
|
|
|
176
186
|
display_title: z.ZodCatch<z.ZodOptional<z.ZodString>>;
|
|
177
187
|
created_at: z.ZodCatch<z.ZodOptional<z.ZodString>>;
|
|
178
188
|
html_url: z.ZodCatch<z.ZodOptional<z.ZodString>>;
|
|
189
|
+
id: z.ZodCatch<z.ZodOptional<z.ZodNumber>>;
|
|
190
|
+
event: z.ZodCatch<z.ZodOptional<z.ZodString>>;
|
|
191
|
+
head_repository: z.ZodCatch<z.ZodOptional<z.ZodObject<{
|
|
192
|
+
full_name: z.ZodCatch<z.ZodOptional<z.ZodString>>;
|
|
193
|
+
}, z.core.$strip>>>;
|
|
179
194
|
}, z.core.$strip>>>;
|
|
180
195
|
}, z.core.$strip>>;
|
|
181
196
|
/** A Linear issue, from the GraphQL query (`labels { nodes }`) or a webhook's `data` (`labels` as a list). */
|
|
@@ -353,6 +368,11 @@ export declare const readGithubRunList: (raw: unknown) => {
|
|
|
353
368
|
display_title?: string | undefined;
|
|
354
369
|
created_at?: string | undefined;
|
|
355
370
|
html_url?: string | undefined;
|
|
371
|
+
id?: number | undefined;
|
|
372
|
+
event?: string | undefined;
|
|
373
|
+
head_repository?: {
|
|
374
|
+
full_name?: string | undefined;
|
|
375
|
+
} | undefined;
|
|
356
376
|
}[] | undefined;
|
|
357
377
|
};
|
|
358
378
|
export declare const readGithubEvent: (raw: unknown) => GithubEvent;
|
|
@@ -42,6 +42,10 @@ export const githubRunSchema = z.object({
|
|
|
42
42
|
display_title: text,
|
|
43
43
|
created_at: text,
|
|
44
44
|
html_url: text,
|
|
45
|
+
/** Read by tidy's CI observations (task-tidy.md): which run, why it ran, and whose repository its commit is in. */
|
|
46
|
+
id: loose(z.number()),
|
|
47
|
+
event: text,
|
|
48
|
+
head_repository: loose(z.object({ full_name: text })),
|
|
45
49
|
}).catch({});
|
|
46
50
|
/** `repos/:repo/issues` and `repos/:repo/pulls`: a list (anything else reads as an empty one). */
|
|
47
51
|
export const githubIssueListSchema = z.array(githubIssueSchema).catch([]);
|
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A youiyoux request as Toolroll reads it (youiyoux-intake.ts): the published `youi.request/v1` schema (youiyoux's
|
|
3
|
+
* schema/youi.request.schema.json), held to its own limits, and the `youi.proposal/v1` options file an options request's
|
|
4
|
+
* agent writes (schema/youi.proposal.schema.json). Unknown keys are allowed, as the published schemas allow them;
|
|
5
|
+
* everything Toolroll reads is checked here, and every string is outside text all the same.
|
|
6
|
+
*/
|
|
7
|
+
import { z } from "zod";
|
|
8
|
+
import { type ContractResult } from "./contract.js";
|
|
9
|
+
export declare const REQUEST_ID: RegExp;
|
|
10
|
+
/** An options file's id: `p-` and the same 10 hex as the options request it answers. */
|
|
11
|
+
export declare const PROPOSAL_ID: RegExp;
|
|
12
|
+
/** The provenance every task filed from a request carries (task_ref.filed_via): immutable, and the seal reads it. */
|
|
13
|
+
export declare const YOUIYOUX_FILED_VIA = "youiyoux";
|
|
14
|
+
/** The one chat card a pass's filings make for a project (youiyoux-intake.ts), drawn by chat-decide.ts: the new tasks,
|
|
15
|
+
* Approve all and each one's own Approve and Open. */
|
|
16
|
+
export declare const YOUIYOUX_CARD_KIND = "youiyoux-requests";
|
|
17
|
+
/** Where a person sees and approves everything waiting on them in the console (flow-triggers.ts NEEDS_YOU_HREF). */
|
|
18
|
+
export declare const YOUIYOUX_HOME_PATH = "/work?view=needs-you";
|
|
19
|
+
export declare const YOUIYOUX_EVIDENCE: readonly ["screenshot", "check", "changed-path", "manual-review"];
|
|
20
|
+
/** What an options request offers its agent: the one file to write (`.youi/proposals/<proposal>.json`), the props an
|
|
21
|
+
* option may set (enum values from `values`), and whether it may give the component new text. */
|
|
22
|
+
export declare const youiyouxOfferSchema: z.ZodObject<{
|
|
23
|
+
proposal: z.ZodString;
|
|
24
|
+
file: z.ZodString;
|
|
25
|
+
choices: z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
26
|
+
type: z.ZodEnum<{
|
|
27
|
+
boolean: "boolean";
|
|
28
|
+
enum: "enum";
|
|
29
|
+
number: "number";
|
|
30
|
+
string: "string";
|
|
31
|
+
}>;
|
|
32
|
+
values: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
33
|
+
default: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean]>>;
|
|
34
|
+
}, z.core.$strip>>;
|
|
35
|
+
text: z.ZodBoolean;
|
|
36
|
+
}, z.core.$strip>;
|
|
37
|
+
export type YouiyouxOffer = z.infer<typeof youiyouxOfferSchema>;
|
|
38
|
+
export declare const youiyouxTaskSchema: z.ZodObject<{
|
|
39
|
+
title: z.ZodString;
|
|
40
|
+
goal: z.ZodString;
|
|
41
|
+
touches: z.ZodArray<z.ZodString>;
|
|
42
|
+
touchesKnown: z.ZodBoolean;
|
|
43
|
+
why: z.ZodOptional<z.ZodString>;
|
|
44
|
+
not: z.ZodArray<z.ZodString>;
|
|
45
|
+
acceptance: z.ZodArray<z.ZodObject<{
|
|
46
|
+
statement: z.ZodString;
|
|
47
|
+
evidence: z.ZodArray<z.ZodEnum<{
|
|
48
|
+
"changed-path": "changed-path";
|
|
49
|
+
check: "check";
|
|
50
|
+
"manual-review": "manual-review";
|
|
51
|
+
screenshot: "screenshot";
|
|
52
|
+
}>>;
|
|
53
|
+
}, z.core.$strip>>;
|
|
54
|
+
offer: z.ZodOptional<z.ZodObject<{
|
|
55
|
+
proposal: z.ZodString;
|
|
56
|
+
file: z.ZodString;
|
|
57
|
+
choices: z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
58
|
+
type: z.ZodEnum<{
|
|
59
|
+
boolean: "boolean";
|
|
60
|
+
enum: "enum";
|
|
61
|
+
number: "number";
|
|
62
|
+
string: "string";
|
|
63
|
+
}>;
|
|
64
|
+
values: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
65
|
+
default: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean]>>;
|
|
66
|
+
}, z.core.$strip>>;
|
|
67
|
+
text: z.ZodBoolean;
|
|
68
|
+
}, z.core.$strip>>;
|
|
69
|
+
}, z.core.$strip>;
|
|
70
|
+
export declare const youiyouxRequestSchema: z.ZodObject<{
|
|
71
|
+
schema: z.ZodLiteral<"youi.request/v1">;
|
|
72
|
+
id: z.ZodString;
|
|
73
|
+
project: z.ZodString;
|
|
74
|
+
kind: z.ZodEnum<{
|
|
75
|
+
change: "change";
|
|
76
|
+
comment: "comment";
|
|
77
|
+
options: "options";
|
|
78
|
+
}>;
|
|
79
|
+
status: z.ZodEnum<{
|
|
80
|
+
addressed: "addressed";
|
|
81
|
+
closed: "closed";
|
|
82
|
+
open: "open";
|
|
83
|
+
}>;
|
|
84
|
+
body: z.ZodString;
|
|
85
|
+
author: z.ZodObject<{
|
|
86
|
+
kind: z.ZodEnum<{
|
|
87
|
+
agent: "agent";
|
|
88
|
+
person: "person";
|
|
89
|
+
}>;
|
|
90
|
+
name: z.ZodString;
|
|
91
|
+
}, z.core.$strip>;
|
|
92
|
+
createdAt: z.ZodString;
|
|
93
|
+
updatedAt: z.ZodString;
|
|
94
|
+
target: z.ZodObject<{
|
|
95
|
+
route: z.ZodString;
|
|
96
|
+
scope: z.ZodEnum<{
|
|
97
|
+
element: "element";
|
|
98
|
+
here: "here";
|
|
99
|
+
}>;
|
|
100
|
+
name: z.ZodString;
|
|
101
|
+
file: z.ZodOptional<z.ZodString>;
|
|
102
|
+
line: z.ZodOptional<z.ZodInt>;
|
|
103
|
+
}, z.core.$strip>;
|
|
104
|
+
task: z.ZodOptional<z.ZodObject<{
|
|
105
|
+
title: z.ZodString;
|
|
106
|
+
goal: z.ZodString;
|
|
107
|
+
touches: z.ZodArray<z.ZodString>;
|
|
108
|
+
touchesKnown: z.ZodBoolean;
|
|
109
|
+
why: z.ZodOptional<z.ZodString>;
|
|
110
|
+
not: z.ZodArray<z.ZodString>;
|
|
111
|
+
acceptance: z.ZodArray<z.ZodObject<{
|
|
112
|
+
statement: z.ZodString;
|
|
113
|
+
evidence: z.ZodArray<z.ZodEnum<{
|
|
114
|
+
"changed-path": "changed-path";
|
|
115
|
+
check: "check";
|
|
116
|
+
"manual-review": "manual-review";
|
|
117
|
+
screenshot: "screenshot";
|
|
118
|
+
}>>;
|
|
119
|
+
}, z.core.$strip>>;
|
|
120
|
+
offer: z.ZodOptional<z.ZodObject<{
|
|
121
|
+
proposal: z.ZodString;
|
|
122
|
+
file: z.ZodString;
|
|
123
|
+
choices: z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
124
|
+
type: z.ZodEnum<{
|
|
125
|
+
boolean: "boolean";
|
|
126
|
+
enum: "enum";
|
|
127
|
+
number: "number";
|
|
128
|
+
string: "string";
|
|
129
|
+
}>;
|
|
130
|
+
values: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
131
|
+
default: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean]>>;
|
|
132
|
+
}, z.core.$strip>>;
|
|
133
|
+
text: z.ZodBoolean;
|
|
134
|
+
}, z.core.$strip>>;
|
|
135
|
+
}, z.core.$strip>>;
|
|
136
|
+
thread: z.ZodArray<z.ZodUnknown>;
|
|
137
|
+
}, z.core.$strip>;
|
|
138
|
+
export type YouiyouxRequest = z.infer<typeof youiyouxRequestSchema>;
|
|
139
|
+
export type YouiyouxTask = z.infer<typeof youiyouxTaskSchema>;
|
|
140
|
+
export declare function readYouiyouxRequest(raw: unknown): ContractResult<YouiyouxRequest>;
|
|
141
|
+
/** The one file an options request's agent may write: `.youi/proposals/p-<the request's hex>.json`. */
|
|
142
|
+
export declare const proposalIdOf: (request: string) => string;
|
|
143
|
+
export declare const proposalFileOf: (proposal: string) => string;
|
|
144
|
+
/** Why an options request can't be filed as youiyoux's contract has it, or null: it carries a task with an offer whose
|
|
145
|
+
* proposal is `p-<its own hex>`, whose file is that proposal's, and the task may touch that one file and nothing else. */
|
|
146
|
+
export declare function optionsProblem(request: YouiyouxRequest): string | null;
|
|
147
|
+
export declare const PROPOSAL_STATUSES: readonly ["open", "chosen", "dismissed"];
|
|
148
|
+
export declare const youiyouxProposalSchema: z.ZodObject<{
|
|
149
|
+
$schema: z.ZodOptional<z.ZodString>;
|
|
150
|
+
schema: z.ZodLiteral<"youi.proposal/v1">;
|
|
151
|
+
id: z.ZodString;
|
|
152
|
+
project: z.ZodString;
|
|
153
|
+
route: z.ZodString;
|
|
154
|
+
target: z.ZodObject<{
|
|
155
|
+
name: z.ZodString;
|
|
156
|
+
element: z.ZodOptional<z.ZodString>;
|
|
157
|
+
file: z.ZodOptional<z.ZodString>;
|
|
158
|
+
line: z.ZodOptional<z.ZodInt>;
|
|
159
|
+
column: z.ZodOptional<z.ZodInt>;
|
|
160
|
+
box: z.ZodObject<{
|
|
161
|
+
x: z.ZodNumber;
|
|
162
|
+
y: z.ZodNumber;
|
|
163
|
+
width: z.ZodNumber;
|
|
164
|
+
height: z.ZodNumber;
|
|
165
|
+
}, z.core.$strip>;
|
|
166
|
+
page: z.ZodOptional<z.ZodObject<{
|
|
167
|
+
width: z.ZodNumber;
|
|
168
|
+
height: z.ZodNumber;
|
|
169
|
+
}, z.core.$strip>>;
|
|
170
|
+
}, z.core.$strip>;
|
|
171
|
+
ask: z.ZodString;
|
|
172
|
+
author: z.ZodObject<{
|
|
173
|
+
kind: z.ZodEnum<{
|
|
174
|
+
agent: "agent";
|
|
175
|
+
person: "person";
|
|
176
|
+
}>;
|
|
177
|
+
name: z.ZodString;
|
|
178
|
+
}, z.core.$strip>;
|
|
179
|
+
createdAt: z.ZodString;
|
|
180
|
+
updatedAt: z.ZodString;
|
|
181
|
+
options: z.ZodArray<z.ZodObject<{
|
|
182
|
+
id: z.ZodEnum<{
|
|
183
|
+
a: "a";
|
|
184
|
+
b: "b";
|
|
185
|
+
c: "c";
|
|
186
|
+
d: "d";
|
|
187
|
+
}>;
|
|
188
|
+
label: z.ZodString;
|
|
189
|
+
why: z.ZodString;
|
|
190
|
+
set: z.ZodArray<z.ZodObject<{
|
|
191
|
+
prop: z.ZodString;
|
|
192
|
+
value: z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean]>;
|
|
193
|
+
}, z.core.$strip>>;
|
|
194
|
+
text: z.ZodNullable<z.ZodString>;
|
|
195
|
+
}, z.core.$strip>>;
|
|
196
|
+
status: z.ZodEnum<{
|
|
197
|
+
chosen: "chosen";
|
|
198
|
+
dismissed: "dismissed";
|
|
199
|
+
open: "open";
|
|
200
|
+
}>;
|
|
201
|
+
choice: z.ZodOptional<z.ZodEnum<{
|
|
202
|
+
a: "a";
|
|
203
|
+
b: "b";
|
|
204
|
+
c: "c";
|
|
205
|
+
d: "d";
|
|
206
|
+
}>>;
|
|
207
|
+
decidedBy: z.ZodOptional<z.ZodObject<{
|
|
208
|
+
kind: z.ZodEnum<{
|
|
209
|
+
agent: "agent";
|
|
210
|
+
person: "person";
|
|
211
|
+
}>;
|
|
212
|
+
name: z.ZodString;
|
|
213
|
+
}, z.core.$strip>>;
|
|
214
|
+
decidedAt: z.ZodOptional<z.ZodString>;
|
|
215
|
+
request: z.ZodOptional<z.ZodString>;
|
|
216
|
+
for: z.ZodString;
|
|
217
|
+
}, z.core.$strip>;
|
|
218
|
+
export type YouiyouxProposal = z.infer<typeof youiyouxProposalSchema>;
|
|
219
|
+
export declare function readYouiyouxProposal(raw: unknown): ContractResult<YouiyouxProposal>;
|
|
220
|
+
/** What Toolroll writes beside a request (`youi.request-task/v1`): the task it became, how that task stands, and, when
|
|
221
|
+
* the console has an address, the task's link and `home`, where a person sees and approves all waiting work. */
|
|
222
|
+
export declare const YOUIYOUX_TASK_STATUSES: readonly ["queued", "needs-you", "building", "ready", "done", "failed", "stopped"];
|
|
223
|
+
export type YouiyouxTaskStatus = (typeof YOUIYOUX_TASK_STATUSES)[number];
|
|
224
|
+
/** A link youiyoux opens: http or https, at most 2,000 characters, with no user name or password in it. */
|
|
225
|
+
export declare const youiyouxLinkSchema: z.ZodString;
|
|
226
|
+
export declare const youiyouxRequestTaskSchema: z.ZodObject<{
|
|
227
|
+
schema: z.ZodLiteral<"youi.request-task/v1">;
|
|
228
|
+
request: z.ZodString;
|
|
229
|
+
runner: z.ZodLiteral<"Toolroll">;
|
|
230
|
+
task: z.ZodObject<{
|
|
231
|
+
id: z.ZodString;
|
|
232
|
+
url: z.ZodNullable<z.ZodString>;
|
|
233
|
+
}, z.core.$strict>;
|
|
234
|
+
home: z.ZodOptional<z.ZodString>;
|
|
235
|
+
status: z.ZodEnum<{
|
|
236
|
+
building: "building";
|
|
237
|
+
done: "done";
|
|
238
|
+
failed: "failed";
|
|
239
|
+
"needs-you": "needs-you";
|
|
240
|
+
queued: "queued";
|
|
241
|
+
ready: "ready";
|
|
242
|
+
stopped: "stopped";
|
|
243
|
+
}>;
|
|
244
|
+
detail: z.ZodString;
|
|
245
|
+
updatedAt: z.ZodString;
|
|
246
|
+
}, z.core.$strict>;
|
|
247
|
+
export type YouiyouxRequestTask = z.infer<typeof youiyouxRequestTaskSchema>;
|
|
248
|
+
export declare function readYouiyouxRequestTask(raw: unknown): ContractResult<YouiyouxRequestTask>;
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A youiyoux request as Toolroll reads it (youiyoux-intake.ts): the published `youi.request/v1` schema (youiyoux's
|
|
3
|
+
* schema/youi.request.schema.json), held to its own limits, and the `youi.proposal/v1` options file an options request's
|
|
4
|
+
* agent writes (schema/youi.proposal.schema.json). Unknown keys are allowed, as the published schemas allow them;
|
|
5
|
+
* everything Toolroll reads is checked here, and every string is outside text all the same.
|
|
6
|
+
*/
|
|
7
|
+
import { z } from "zod";
|
|
8
|
+
import { parseContract } from "./contract.js";
|
|
9
|
+
export const REQUEST_ID = /^r-[0-9a-f]{10}$/;
|
|
10
|
+
/** An options file's id: `p-` and the same 10 hex as the options request it answers. */
|
|
11
|
+
export const PROPOSAL_ID = /^p-[0-9a-f]{10}$/;
|
|
12
|
+
/** The provenance every task filed from a request carries (task_ref.filed_via): immutable, and the seal reads it. */
|
|
13
|
+
export const YOUIYOUX_FILED_VIA = "youiyoux";
|
|
14
|
+
/** The one chat card a pass's filings make for a project (youiyoux-intake.ts), drawn by chat-decide.ts: the new tasks,
|
|
15
|
+
* Approve all and each one's own Approve and Open. */
|
|
16
|
+
export const YOUIYOUX_CARD_KIND = "youiyoux-requests";
|
|
17
|
+
/** Where a person sees and approves everything waiting on them in the console (flow-triggers.ts NEEDS_YOU_HREF). */
|
|
18
|
+
export const YOUIYOUX_HOME_PATH = "/work?view=needs-you";
|
|
19
|
+
const text = (max) => z.string().min(1).max(max);
|
|
20
|
+
const who = z.object({ kind: z.enum(["person", "agent"]), name: text(100) });
|
|
21
|
+
// The published schema's date-time: an ISO timestamp with a zone.
|
|
22
|
+
const when = z.string().max(40).regex(/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d+)?(?:Z|[+-]\d{2}:\d{2})$/);
|
|
23
|
+
export const YOUIYOUX_EVIDENCE = ["screenshot", "check", "changed-path", "manual-review"];
|
|
24
|
+
/** A component prop as youiyoux names one: what an option may set. */
|
|
25
|
+
const PROP = /^[A-Za-z_$][\w$]{0,63}$/;
|
|
26
|
+
const value = z.union([z.string().max(2000), z.number().finite(), z.boolean()]);
|
|
27
|
+
/** What an options request offers its agent: the one file to write (`.youi/proposals/<proposal>.json`), the props an
|
|
28
|
+
* option may set (enum values from `values`), and whether it may give the component new text. */
|
|
29
|
+
export const youiyouxOfferSchema = z.object({
|
|
30
|
+
proposal: z.string().regex(PROPOSAL_ID),
|
|
31
|
+
file: text(500),
|
|
32
|
+
choices: z.record(z.string().regex(PROP), z.object({
|
|
33
|
+
type: z.enum(["enum", "string", "boolean", "number"]),
|
|
34
|
+
values: z.array(text(200)).max(100).optional(),
|
|
35
|
+
default: value.optional(),
|
|
36
|
+
})).refine(choices => Object.keys(choices).length <= 50, "at most 50 props"),
|
|
37
|
+
text: z.boolean(),
|
|
38
|
+
});
|
|
39
|
+
export const youiyouxTaskSchema = z.object({
|
|
40
|
+
title: text(120),
|
|
41
|
+
goal: text(4000),
|
|
42
|
+
touches: z.array(text(500)).max(50),
|
|
43
|
+
touchesKnown: z.boolean(),
|
|
44
|
+
why: text(500).optional(),
|
|
45
|
+
not: z.array(text(300)).max(10),
|
|
46
|
+
acceptance: z.array(z.object({ statement: text(300), evidence: z.array(z.enum(YOUIYOUX_EVIDENCE)).min(1) })).min(1).max(10),
|
|
47
|
+
/** An options request's: what its agent writes (optionsProblem holds it to the request). */
|
|
48
|
+
offer: youiyouxOfferSchema.optional(),
|
|
49
|
+
});
|
|
50
|
+
export const youiyouxRequestSchema = z.object({
|
|
51
|
+
schema: z.literal("youi.request/v1"),
|
|
52
|
+
id: z.string().regex(REQUEST_ID),
|
|
53
|
+
project: text(200),
|
|
54
|
+
kind: z.enum(["comment", "change", "options"]),
|
|
55
|
+
status: z.enum(["open", "addressed", "closed"]),
|
|
56
|
+
body: text(4000),
|
|
57
|
+
author: who,
|
|
58
|
+
createdAt: when,
|
|
59
|
+
updatedAt: when,
|
|
60
|
+
// Where the person pointed: the page, the component, and (when youiyoux knew it) the file and line that draw it.
|
|
61
|
+
target: z.object({ route: text(300), scope: z.enum(["here", "element"]), name: text(200), file: text(500).optional(), line: z.int().positive().max(Number.MAX_SAFE_INTEGER).optional() }),
|
|
62
|
+
task: youiyouxTaskSchema.optional(),
|
|
63
|
+
thread: z.array(z.unknown()).max(500),
|
|
64
|
+
});
|
|
65
|
+
export function readYouiyouxRequest(raw) {
|
|
66
|
+
return parseContract(youiyouxRequestSchema, raw);
|
|
67
|
+
}
|
|
68
|
+
/** The one file an options request's agent may write: `.youi/proposals/p-<the request's hex>.json`. */
|
|
69
|
+
export const proposalIdOf = (request) => `p-${request.slice(2)}`;
|
|
70
|
+
export const proposalFileOf = (proposal) => `.youi/proposals/${proposal}.json`;
|
|
71
|
+
/** Why an options request can't be filed as youiyoux's contract has it, or null: it carries a task with an offer whose
|
|
72
|
+
* proposal is `p-<its own hex>`, whose file is that proposal's, and the task may touch that one file and nothing else. */
|
|
73
|
+
export function optionsProblem(request) {
|
|
74
|
+
if (request.kind !== "options")
|
|
75
|
+
return null;
|
|
76
|
+
const offer = request.task?.offer;
|
|
77
|
+
if (request.task === undefined || offer === undefined)
|
|
78
|
+
return "it asks for options with no offer";
|
|
79
|
+
const proposal = proposalIdOf(request.id);
|
|
80
|
+
if (offer.proposal !== proposal)
|
|
81
|
+
return `its offer is for ${offer.proposal}, not ${proposal}`;
|
|
82
|
+
if (offer.file !== proposalFileOf(proposal))
|
|
83
|
+
return `its offer's file isn't ${proposalFileOf(proposal)}`;
|
|
84
|
+
if (!request.task.touchesKnown || request.task.touches.length !== 1 || request.task.touches[0] !== offer.file)
|
|
85
|
+
return "its task may touch more than its options file";
|
|
86
|
+
return null;
|
|
87
|
+
}
|
|
88
|
+
/** `youi.proposal/v1`: the options an agent puts on youiyoux's Screens canvas (youiyoux's packages/core/src/proposals.ts,
|
|
89
|
+
* mirrored). Toolroll checks only the shape and what it reads; youiyoux checks each option against the component's
|
|
90
|
+
* contract when it reads the file. */
|
|
91
|
+
const OPTION_IDS = ["a", "b", "c", "d"];
|
|
92
|
+
export const PROPOSAL_STATUSES = ["open", "chosen", "dismissed"];
|
|
93
|
+
export const youiyouxProposalSchema = z.object({
|
|
94
|
+
$schema: z.string().max(500).optional(),
|
|
95
|
+
schema: z.literal("youi.proposal/v1"),
|
|
96
|
+
id: z.string().regex(PROPOSAL_ID),
|
|
97
|
+
project: text(200),
|
|
98
|
+
route: text(300),
|
|
99
|
+
target: z.object({
|
|
100
|
+
name: text(200), element: text(200).optional(), file: text(500).optional(),
|
|
101
|
+
line: z.int().positive().max(Number.MAX_SAFE_INTEGER).optional(), column: z.int().nonnegative().max(Number.MAX_SAFE_INTEGER).optional(),
|
|
102
|
+
box: z.object({ x: z.number().finite(), y: z.number().finite(), width: z.number().finite().nonnegative(), height: z.number().finite().nonnegative() }),
|
|
103
|
+
page: z.object({ width: z.number().finite().positive(), height: z.number().finite().positive() }).optional(),
|
|
104
|
+
}),
|
|
105
|
+
ask: text(1000),
|
|
106
|
+
author: who,
|
|
107
|
+
createdAt: when,
|
|
108
|
+
updatedAt: when,
|
|
109
|
+
options: z.array(z.object({
|
|
110
|
+
id: z.enum(OPTION_IDS),
|
|
111
|
+
label: text(60),
|
|
112
|
+
why: text(500),
|
|
113
|
+
set: z.array(z.object({ prop: z.string().regex(PROP), value })).max(20),
|
|
114
|
+
text: text(2000).nullable(),
|
|
115
|
+
}).refine(option => option.set.length > 0 || option.text !== null, "an option changes a prop or the text")).min(2).max(4),
|
|
116
|
+
status: z.enum(PROPOSAL_STATUSES),
|
|
117
|
+
choice: z.enum(OPTION_IDS).optional(),
|
|
118
|
+
decidedBy: who.optional(),
|
|
119
|
+
decidedAt: when.optional(),
|
|
120
|
+
request: z.string().regex(REQUEST_ID).optional(),
|
|
121
|
+
for: z.string().regex(REQUEST_ID),
|
|
122
|
+
}).refine(doc => new Set(doc.options.map(option => option.id)).size === doc.options.length, "each option has its own letter")
|
|
123
|
+
.refine(doc => doc.choice === undefined || doc.options.some(option => option.id === doc.choice), "the choice is one of its options");
|
|
124
|
+
export function readYouiyouxProposal(raw) {
|
|
125
|
+
return parseContract(youiyouxProposalSchema, raw);
|
|
126
|
+
}
|
|
127
|
+
/** What Toolroll writes beside a request (`youi.request-task/v1`): the task it became, how that task stands, and, when
|
|
128
|
+
* the console has an address, the task's link and `home`, where a person sees and approves all waiting work. */
|
|
129
|
+
export const YOUIYOUX_TASK_STATUSES = ["queued", "needs-you", "building", "ready", "done", "failed", "stopped"];
|
|
130
|
+
/** A link youiyoux opens: http or https, at most 2,000 characters, with no user name or password in it. */
|
|
131
|
+
export const youiyouxLinkSchema = z.string().max(2000).refine(value => {
|
|
132
|
+
try {
|
|
133
|
+
const url = new URL(value);
|
|
134
|
+
return (url.protocol === "http:" || url.protocol === "https:") && url.username === "" && url.password === "";
|
|
135
|
+
}
|
|
136
|
+
catch {
|
|
137
|
+
return false;
|
|
138
|
+
}
|
|
139
|
+
}, "an http or https address with no credentials");
|
|
140
|
+
export const youiyouxRequestTaskSchema = z.strictObject({
|
|
141
|
+
schema: z.literal("youi.request-task/v1"),
|
|
142
|
+
request: z.string().regex(REQUEST_ID),
|
|
143
|
+
runner: z.literal("Toolroll"),
|
|
144
|
+
task: z.strictObject({ id: z.string().min(1).max(120), url: youiyouxLinkSchema.nullable() }),
|
|
145
|
+
home: youiyouxLinkSchema.optional(),
|
|
146
|
+
status: z.enum(YOUIYOUX_TASK_STATUSES),
|
|
147
|
+
detail: z.string().max(200),
|
|
148
|
+
updatedAt: when,
|
|
149
|
+
});
|
|
150
|
+
export function readYouiyouxRequestTask(raw) {
|
|
151
|
+
return parseContract(youiyouxRequestTaskSchema, raw);
|
|
152
|
+
}
|
package/dist/coordinator.js
CHANGED
|
@@ -326,6 +326,7 @@ export function listTasksFor(store, who, filter, now) {
|
|
|
326
326
|
FROM task_ref JOIN task ON task.id = task_ref.external_id AND task_ref.backend = 'built-in'
|
|
327
327
|
WHERE task_ref.repo IN (${sql})
|
|
328
328
|
AND (? IS NULL OR task.state = ?)
|
|
329
|
+
AND NOT EXISTS (SELECT 1 FROM task_archive WHERE task_archive.task_ref = task_ref.id)
|
|
329
330
|
AND task_ref.id > ?
|
|
330
331
|
ORDER BY task_ref.id LIMIT ?`)
|
|
331
332
|
.all(now.toISOString(), ...args, filter.state ?? null, filter.state ?? null, filter.cursor ?? 0, limit + 1);
|
package/dist/deploy-gate.js
CHANGED
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
import { assignmentOf } from "./assignment.js";
|
|
9
9
|
import { liveReleaseOf, personApprovalOf, releaseApprovalOf } from "./scope.js";
|
|
10
10
|
import { verificationEvidence } from "./verification-evidence.js";
|
|
11
|
+
import { refArchived } from "./task-archive.js";
|
|
11
12
|
import { releaseCiRunningOf } from "./release-ci-hold.js";
|
|
12
13
|
import { nightlyDebtHold } from "./nightly-github.js";
|
|
13
14
|
/** Whether run `runId` is a deployable candidate now, read only from the plane's records and this runtime's code. */
|
|
@@ -29,6 +30,9 @@ export function deploymentGate(store, input) {
|
|
|
29
30
|
return refuse(`Run ${input.runId} is not a built candidate at ${head.slice(0, 7)}.`);
|
|
30
31
|
if (scope === null || scope.approvedDigest !== scope.digest || scope.digest !== run.scopeDigest)
|
|
31
32
|
return refuse("The run's signed scope is no longer the approved one.");
|
|
33
|
+
// A put-away task (v145, task-tidy.md) deploys nothing: restore it first.
|
|
34
|
+
if (refArchived(store, run.taskRef))
|
|
35
|
+
return refuse("This task is put away. Restore it before deploying.");
|
|
32
36
|
// A person may approve during CI, including a release without carry terms. Every deployment road must wait
|
|
33
37
|
// for the plane's exact-head observation, not only the release coordinator's polling loop.
|
|
34
38
|
if (releaseCiRunningOf(store, ref.externalId) !== null)
|
package/dist/dispatch.d.ts
CHANGED
|
@@ -26,6 +26,9 @@ export type TaskReadinessBlocker = {
|
|
|
26
26
|
blockerId: string;
|
|
27
27
|
blockerState: TaskState;
|
|
28
28
|
message: string;
|
|
29
|
+
} | {
|
|
30
|
+
code: "archived";
|
|
31
|
+
message: string;
|
|
29
32
|
};
|
|
30
33
|
export type DispatchAction = "open-result" | "retry-task" | "place-task" | "write-scope" | "select-agent" | "approve-scope" | "answer-decision" | "unhold" | "inspect-hold" | "repair-dependency" | "repair-capability" | "start-worker"
|
|
31
34
|
/** v50: ask for the bounded explicit review retry (`task review <run>`
|
package/dist/dispatch.js
CHANGED
|
@@ -16,7 +16,7 @@ import { REVIEW_TOKENS, resultStatusOf, reviewFactsOf } from "./workspace-ui.js"
|
|
|
16
16
|
import { replacedWords } from "./task-status.js";
|
|
17
17
|
import { failedAttemptSentence, latestFinishedAttempt } from "./needs-you.js";
|
|
18
18
|
import { buildReviewOf } from "./review-switch.js";
|
|
19
|
-
import { BUILT_IN, parseCapabilityKey } from "./store.js";
|
|
19
|
+
import { BUILT_IN, refArchived, parseCapabilityKey } from "./store.js";
|
|
20
20
|
export const DEFAULT_MAX_OPEN_DECISIONS = 5;
|
|
21
21
|
/**
|
|
22
22
|
* Task state, active holds, and unfinished dependencies in the exact order
|
|
@@ -33,6 +33,9 @@ export function taskReadinessBlocker(store, taskRef, now) {
|
|
|
33
33
|
.get(BUILT_IN, taskRef);
|
|
34
34
|
if (task === undefined)
|
|
35
35
|
return { code: "unknown-task", message: "no such task" };
|
|
36
|
+
// A put-away task (v145) never dispatches, whatever its state: restore it first.
|
|
37
|
+
if (refArchived(store, taskRef))
|
|
38
|
+
return { code: "archived", message: "put away" };
|
|
36
39
|
const state = String(task["state"]);
|
|
37
40
|
if (state !== "queued")
|
|
38
41
|
return { code: "state", state, message: `state is ${state}, not queued` };
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import { type FlowDefinition } from "./flows.js";
|
|
2
|
+
import type { FlowRow, FlowScriptRow, Store } from "./store.js";
|
|
3
|
+
/** v144: each approval of browser use, live or ended. `digest` is browserApprovalDigest of what was approved. Additive only. */
|
|
4
|
+
export declare const FLOW_BROWSER_SCHEMA = "\nCREATE TABLE IF NOT EXISTS flow_browser_grant (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n flow INTEGER NOT NULL,\n repo TEXT NOT NULL,\n flow_revision INTEGER NOT NULL,\n flow_digest TEXT NOT NULL,\n digest TEXT NOT NULL,\n zones_json TEXT NOT NULL,\n signed_by TEXT NOT NULL,\n signed_at TEXT NOT NULL,\n proof TEXT NOT NULL,\n revoked_at TEXT,\n revoked_by TEXT\n);\nCREATE UNIQUE INDEX IF NOT EXISTS flow_browser_live ON flow_browser_grant (flow) WHERE revoked_at IS NULL;\n";
|
|
5
|
+
/** One zone an approval covers: the zone, and the script it runs (name, version and content digest). */
|
|
6
|
+
export type BrowserZone = {
|
|
7
|
+
zone: string;
|
|
8
|
+
script: string;
|
|
9
|
+
version: number;
|
|
10
|
+
digest: string;
|
|
11
|
+
};
|
|
12
|
+
/** Everything an approval is about: the flow, its project, the drawing (revision and digest) and every browser zone. */
|
|
13
|
+
export type BrowserTerms = {
|
|
14
|
+
flow: number;
|
|
15
|
+
repo: string;
|
|
16
|
+
revision: number;
|
|
17
|
+
flowDigest: string;
|
|
18
|
+
zones: BrowserZone[];
|
|
19
|
+
};
|
|
20
|
+
export type FlowBrowserGrant = BrowserTerms & {
|
|
21
|
+
id: number;
|
|
22
|
+
digest: string;
|
|
23
|
+
signedBy: string;
|
|
24
|
+
signedAt: string;
|
|
25
|
+
proof: string;
|
|
26
|
+
};
|
|
27
|
+
/** The approval's digest: domain-separated over the whole of its terms, so a changed flow, drawing, revision or any
|
|
28
|
+
* covered script (a restored one is a new version) is a different approval. */
|
|
29
|
+
export declare function browserApprovalDigest(terms: BrowserTerms): string;
|
|
30
|
+
/** The flow's script zones that say they start a browser, each with the script it runs now; null when one's script is
|
|
31
|
+
* missing, waiting for approval, or runs a project file (an approval seals the script's own text, never a file the
|
|
32
|
+
* project can change). */
|
|
33
|
+
export declare function browserZonesOf(store: Store, flow: FlowRow, definition: FlowDefinition): BrowserZone[] | null;
|
|
34
|
+
/** What an approval of this flow would be about now, read from the store; null when it can't be approved. */
|
|
35
|
+
export declare function browserTermsOf(store: Store, flow: FlowRow): BrowserTerms | null;
|
|
36
|
+
/** The flow's live approval, as recorded (whether it still stands is browserStanding's question). */
|
|
37
|
+
export declare function liveBrowserGrant(store: Store, flowId: number): FlowBrowserGrant | null;
|
|
38
|
+
/**
|
|
39
|
+
* Whether `zone` of this flow may start a browser now. `run`, when given, is what the caller is about to run — the
|
|
40
|
+
* drawing it read and the very script object it hands the launch — and the answer is about exactly that. The live
|
|
41
|
+
* approval stands only when its digest is the approval this flow would be now (same flow, project, drawing revision and
|
|
42
|
+
* digest, and every browser zone's script name, version and digest), it was a person's, and its signer is still an
|
|
43
|
+
* approver who reaches the project; `run`'s drawing must be that drawing and its script that zone's script. Anything
|
|
44
|
+
* unreadable, changed or mismatched is a no, with the plain words a card waits with.
|
|
45
|
+
*/
|
|
46
|
+
export declare function browserStanding(store: Store, flowId: number, zone: string, run?: {
|
|
47
|
+
definition: FlowDefinition;
|
|
48
|
+
script: FlowScriptRow;
|
|
49
|
+
}): {
|
|
50
|
+
allowed: true;
|
|
51
|
+
} | {
|
|
52
|
+
allowed: false;
|
|
53
|
+
said: string;
|
|
54
|
+
};
|
|
55
|
+
/** What approving means, in words the person reads before they give their password. */
|
|
56
|
+
export declare function browserTerms(zones: readonly BrowserZone[]): string[];
|
|
57
|
+
/**
|
|
58
|
+
* Approve browser use for the flow as it stands. `proof` is the signer's credential method, proved by the caller just
|
|
59
|
+
* now; only a person's counts (a lead's or remote run's token is refused), from an approver who reaches the project.
|
|
60
|
+
* Re-reads the flow, its zones and scripts in the one transaction that writes; `sawDigest` (required) is the approval
|
|
61
|
+
* (browserApprovalDigest: drawing and scripts) the person read, and anything else is refused. Replaces any live one.
|
|
62
|
+
*/
|
|
63
|
+
export declare function signFlowBrowser(store: Store, input: {
|
|
64
|
+
flow: number;
|
|
65
|
+
signer: string;
|
|
66
|
+
proof: string | null;
|
|
67
|
+
sawDigest: string;
|
|
68
|
+
/** The console and chat: the signer's account must still be this generation (the session that proved it) and reach every project. */
|
|
69
|
+
console?: {
|
|
70
|
+
generation: number;
|
|
71
|
+
};
|
|
72
|
+
}, now: Date): {
|
|
73
|
+
ok: true;
|
|
74
|
+
grant: FlowBrowserGrant;
|
|
75
|
+
} | {
|
|
76
|
+
ok: false;
|
|
77
|
+
message: string;
|
|
78
|
+
};
|
|
79
|
+
/** Any approver on the project ends it, with no password: lowering authority. False when there was none. */
|
|
80
|
+
export declare function revokeFlowBrowser(store: Store, flowId: number, by: string, now: Date): boolean;
|
|
81
|
+
/** What the flow page, `flows show` and chat say about browser use: null when no zone says it starts a browser. */
|
|
82
|
+
export type BrowserView = {
|
|
83
|
+
/** allowed: the approval stands now; ended: there is one, but it no longer stands; none: no one has approved. */
|
|
84
|
+
status: "allowed" | "ended" | "none";
|
|
85
|
+
/** The one line every surface shows. */
|
|
86
|
+
words: string;
|
|
87
|
+
signedBy: string | null;
|
|
88
|
+
signedAt: string | null;
|
|
89
|
+
/** The browser zones as they stand now, each with its title. Empty while one can't be approved (see `problem`). */
|
|
90
|
+
zones: (BrowserZone & {
|
|
91
|
+
title: string;
|
|
92
|
+
})[];
|
|
93
|
+
/** What approving means (browserTerms), and the approval digest the step-up must carry back. */
|
|
94
|
+
terms: string[];
|
|
95
|
+
digest: string | null;
|
|
96
|
+
/** Why it can't be approved as it stands, or null. */
|
|
97
|
+
problem: string | null;
|
|
98
|
+
};
|
|
99
|
+
/**
|
|
100
|
+
* Browser use for one flow, read from the store (no writes: page visits call it). Whether it is allowed is exactly
|
|
101
|
+
* browserStanding's answer for the flow's browser zones; the rest only says why in plain words.
|
|
102
|
+
*/
|
|
103
|
+
export declare function browserViewOf(store: Store, flow: FlowRow): BrowserView | null;
|