toolroll 0.9.85 → 0.9.87
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 +83 -0
- package/dist/agent-fence.d.ts +6 -2
- package/dist/agent-fence.js +3 -2
- package/dist/agents-board.d.ts +12 -0
- package/dist/agents-board.js +26 -0
- package/dist/approval-rules-ui.d.ts +4 -1
- package/dist/approval-rules-ui.js +31 -15
- package/dist/assignment-ui.js +1 -1
- package/dist/assignment.js +4 -3
- package/dist/backup-ui.d.ts +5 -4
- package/dist/backup-ui.js +65 -32
- package/dist/browser/terminal.css +1 -1
- package/dist/browser/terminal.js +57 -54
- package/dist/browser/workspace.css +2 -2
- package/dist/browser/workspace.js +35 -68
- package/dist/browser-crew.js +1 -1
- package/dist/browser-workspace.d.ts +363 -177
- package/dist/browser-workspace.js +10 -9
- package/dist/chat-actions.d.ts +11 -1
- package/dist/chat-actions.js +53 -1
- package/dist/chat-channel.js +1 -0
- package/dist/chat-controls.d.ts +1 -1
- package/dist/chat-controls.js +1 -1
- package/dist/chat-quiet.js +3 -2
- package/dist/chat-settings-page.d.ts +29 -9
- package/dist/chat-settings-page.js +59 -28
- package/dist/check-levels-ui.d.ts +2 -1
- package/dist/check-levels-ui.js +67 -58
- 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/cli.d.ts +43 -0
- package/dist/contracts/cli.js +4 -0
- package/dist/contracts/console-api.d.ts +4 -1
- package/dist/contracts/console-api.js +4 -1
- 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 +21 -0
- package/dist/contracts/lead-tools.js +2 -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/coordinator.js +1 -0
- package/dist/credentials-ui.d.ts +5 -3
- package/dist/credentials-ui.js +58 -31
- package/dist/deploy-gate.js +4 -0
- package/dist/design/kit.css +685 -0
- package/dist/design/kit.d.ts +208 -0
- package/dist/design/kit.js +177 -0
- package/dist/design/tokens.css +19 -1
- package/dist/discord-settings.js +8 -4
- package/dist/dispatch.d.ts +3 -0
- package/dist/dispatch.js +4 -1
- package/dist/export-ui.d.ts +6 -4
- package/dist/export-ui.js +18 -8
- package/dist/flow-browser.d.ts +103 -0
- package/dist/flow-browser.js +204 -0
- package/dist/flow-changed.d.ts +14 -0
- package/dist/flow-changed.js +53 -0
- 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-gallery-ui.d.ts +41 -4
- package/dist/flow-gallery-ui.js +95 -63
- 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-starters-ui.d.ts +3 -9
- package/dist/flow-starters-ui.js +12 -23
- package/dist/flow-steps.d.ts +9 -1
- package/dist/flow-steps.js +55 -5
- package/dist/flow-triggers.js +55 -0
- package/dist/flow-unattended-words.d.ts +20 -0
- package/dist/flow-unattended-words.js +24 -0
- package/dist/flow-unattended.d.ts +9 -5
- package/dist/flow-unattended.js +45 -23
- package/dist/flows-cli.d.ts +19 -0
- package/dist/flows-cli.js +54 -5
- package/dist/flows-ui.d.ts +12 -6
- package/dist/flows-ui.js +152 -32
- package/dist/flows.js +5 -2
- package/dist/integrations-ui.d.ts +6 -4
- package/dist/integrations-ui.js +34 -40
- package/dist/integrations.d.ts +2 -2
- package/dist/integrations.js +4 -4
- package/dist/kits-ui.d.ts +8 -10
- package/dist/kits-ui.js +29 -33
- package/dist/kits.js +1 -1
- package/dist/knowledge-ui.js +76 -19
- package/dist/lead-tools.js +35 -6
- package/dist/lead-voice.js +16 -5
- package/dist/ledger-view.d.ts +2 -0
- package/dist/ledger-view.js +41 -38
- package/dist/models-ui.d.ts +8 -3
- package/dist/models-ui.js +82 -59
- package/dist/monitoring-ui.d.ts +4 -2
- package/dist/monitoring-ui.js +44 -13
- package/dist/needs-you.d.ts +1 -1
- package/dist/needs-you.js +8 -0
- package/dist/operate-remote-arguments.js +1 -0
- package/dist/operate-remote.js +1 -1
- package/dist/operate.d.ts +1 -1
- package/dist/operate.js +249 -6
- package/dist/passwordless.d.ts +1 -1
- package/dist/passwordless.js +1 -1
- package/dist/people-audit-ui.d.ts +2 -1
- package/dist/people-audit-ui.js +25 -23
- package/dist/policy-ui.d.ts +3 -2
- package/dist/policy-ui.js +27 -21
- package/dist/policy.d.ts +3 -0
- package/dist/policy.js +14 -1
- package/dist/project-delete-ui.d.ts +4 -2
- package/dist/project-delete-ui.js +135 -126
- package/dist/project-delete.js +7 -3
- package/dist/project-knowledge.d.ts +10 -10
- package/dist/publish.d.ts +11 -0
- package/dist/publish.js +16 -3
- package/dist/pull-request-flow.js +35 -4
- package/dist/pull-request-ui.d.ts +2 -1
- package/dist/pull-request-ui.js +39 -28
- package/dist/recipe-ui.d.ts +4 -2
- package/dist/recipe-ui.js +14 -4
- package/dist/release-adapters.d.ts +3 -0
- package/dist/release-adapters.js +22 -2
- package/dist/release-cli.js +81 -9
- package/dist/release.d.ts +21 -0
- package/dist/release.js +40 -4
- package/dist/releases.js +1 -1
- package/dist/request-budget-ui.d.ts +4 -2
- package/dist/request-budget-ui.js +30 -19
- package/dist/result-follow-ups.js +4 -0
- package/dist/retention-ui.d.ts +4 -3
- package/dist/retention-ui.js +15 -12
- package/dist/scope.d.ts +8 -0
- package/dist/scope.js +13 -0
- package/dist/serve.d.ts +0 -1
- package/dist/serve.js +51 -7
- package/dist/server/agents-computers.d.ts +9 -0
- package/dist/server/agents-computers.js +67 -0
- package/dist/server/chat.js +20 -18
- package/dist/server/chrome.d.ts +1 -1
- package/dist/server/chrome.js +19 -9
- package/dist/server/console.css +31 -2
- package/dist/server/flows.js +79 -36
- package/dist/server/home.d.ts +35 -0
- package/dist/server/home.js +104 -0
- package/dist/server/http.d.ts +3 -0
- package/dist/server/http.js +5 -0
- package/dist/server/kit-standalone.d.ts +22 -0
- package/dist/server/kit-standalone.js +69 -0
- package/dist/server/kit.d.ts +405 -0
- package/dist/server/kit.js +361 -0
- package/dist/server/pages.d.ts +2 -1
- package/dist/server/pages.js +213 -174
- package/dist/server/people-tokens.js +26 -85
- package/dist/server/render-history.d.ts +51 -0
- package/dist/server/render-history.js +228 -0
- package/dist/server/render-new-task.d.ts +29 -0
- package/dist/server/render-new-task.js +96 -0
- package/dist/server/render-next.d.ts +63 -0
- package/dist/server/render-next.js +109 -0
- package/dist/server/render-pages.d.ts +35 -190
- package/dist/server/render-pages.js +154 -563
- package/dist/server/render-people.d.ts +24 -3
- package/dist/server/render-people.js +93 -72
- package/dist/server/render-projects.d.ts +103 -0
- package/dist/server/render-projects.js +247 -0
- package/dist/server/render-results.d.ts +5 -24
- package/dist/server/render-results.js +48 -185
- package/dist/server/render-settings.d.ts +5 -74
- package/dist/server/render-settings.js +102 -493
- package/dist/server/render-tasks.d.ts +43 -5
- package/dist/server/render-tasks.js +131 -91
- package/dist/server/route-table.js +31 -5
- package/dist/server/settings.js +276 -255
- package/dist/server/task-views.d.ts +8 -0
- package/dist/server/task-views.js +90 -2
- package/dist/server/tasks.d.ts +18 -0
- package/dist/server/tasks.js +148 -41
- package/dist/server/terminals.js +1 -1
- package/dist/server/welcome.d.ts +22 -0
- package/dist/server/welcome.js +69 -0
- package/dist/settings-groups-ui.d.ts +279 -0
- package/dist/settings-groups-ui.js +615 -0
- package/dist/settings-kit.d.ts +42 -6
- package/dist/settings-kit.js +69 -7
- package/dist/settings-proofs.js +1 -0
- package/dist/setup-guide.d.ts +2 -2
- package/dist/skills-ui.js +59 -7
- package/dist/slack-settings.js +12 -5
- package/dist/spend-ui.d.ts +45 -26
- package/dist/spend-ui.js +124 -56
- package/dist/sso-ui.d.ts +5 -2
- package/dist/sso-ui.js +63 -31
- package/dist/storage-ui.d.ts +3 -2
- package/dist/storage-ui.js +56 -50
- package/dist/store.d.ts +182 -5
- package/dist/store.js +512 -38
- package/dist/surface.js +23 -3
- 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/teams-settings.d.ts +2 -1
- package/dist/teams-settings.js +24 -41
- package/dist/telegram-settings.d.ts +0 -4
- package/dist/telegram-settings.js +52 -25
- package/dist/tidy.d.ts +130 -0
- package/dist/tidy.js +503 -0
- package/dist/toolroll-update-ui.d.ts +8 -4
- package/dist/toolroll-update-ui.js +55 -45
- package/dist/tools-ui.d.ts +5 -3
- package/dist/tools-ui.js +107 -42
- package/dist/work-index.d.ts +24 -0
- package/dist/work-index.js +56 -30
- package/dist/workspace-ui.d.ts +1 -1
- package/dist/workspace-ui.js +8 -4
- package/package.json +1 -1
|
@@ -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([]);
|
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/credentials-ui.d.ts
CHANGED
|
@@ -5,7 +5,9 @@
|
|
|
5
5
|
*/
|
|
6
6
|
import type { ApiTokenRow, WebSessionRow } from "./store.js";
|
|
7
7
|
import { type Html } from "./html.js";
|
|
8
|
-
|
|
8
|
+
/** The old card look; the page is built from the kit now (src/server/kit.ts), so nothing is left to style. Kept for
|
|
9
|
+
* chrome.ts, which still concatenates it. */
|
|
10
|
+
export declare const CREDENTIALS_CSS = "";
|
|
9
11
|
/** "Chrome on macOS", from a user agent, for a person to recognise a session. */
|
|
10
12
|
export declare function deviceWords(agent: string | null): string;
|
|
11
13
|
export type CredentialsView = {
|
|
@@ -23,9 +25,9 @@ export type CredentialsView = {
|
|
|
23
25
|
section: Html;
|
|
24
26
|
};
|
|
25
27
|
};
|
|
26
|
-
export declare function credentialsHtml(view: CredentialsView,
|
|
28
|
+
export declare function credentialsHtml(view: CredentialsView, outcome: {
|
|
27
29
|
said?: string | null;
|
|
28
30
|
problem?: string | null;
|
|
29
31
|
}): Html;
|
|
30
|
-
/** The token, once
|
|
32
|
+
/** The token, once, on a page with no script: selectable text, what it may do, and where to revoke it. */
|
|
31
33
|
export declare function tokenShownHtml(name: string, token: string, access: "read" | "act", expiresAt: string): Html;
|
package/dist/credentials-ui.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { daysLeft, expiryNoticeDue, TOKEN_DAYS, tokenLive } from "./api-tokens.js";
|
|
2
2
|
import { projectName } from "./project.js";
|
|
3
|
-
import { html, postForm } from "./html.js";
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
3
|
+
import { html, joinHtml, postForm } from "./html.js";
|
|
4
|
+
import { acts, btn, chip, disclose, formRow, infoLine, input, note, notice, select, settingsRecord, settingsSection } from "./server/kit.js";
|
|
5
|
+
import { kitSectionForm } from "./settings-kit.js";
|
|
6
|
+
import { settingsSubPage } from "./settings-groups-ui.js";
|
|
7
|
+
/** The old card look; the page is built from the kit now (src/server/kit.ts), so nothing is left to style. Kept for
|
|
8
|
+
* chrome.ts, which still concatenates it. */
|
|
9
|
+
export const CREDENTIALS_CSS = "";
|
|
10
10
|
/** "Chrome on macOS", from a user agent, for a person to recognise a session. */
|
|
11
11
|
export function deviceWords(agent) {
|
|
12
12
|
if (agent === null || agent === "")
|
|
@@ -22,38 +22,65 @@ const when = (value, now) => {
|
|
|
22
22
|
const minutes = Math.round((now - at) / 60_000);
|
|
23
23
|
return minutes < 1 ? "just now" : minutes < 60 ? `${minutes} min ago` : minutes < 60 * 24 ? `${Math.round(minutes / 60)} h ago` : new Date(at).toISOString().slice(0, 10);
|
|
24
24
|
};
|
|
25
|
-
export function credentialsHtml(view,
|
|
26
|
-
|
|
27
|
-
const
|
|
28
|
-
const
|
|
29
|
-
const
|
|
30
|
-
<p class="meta">${one.ssoAt === null ? "Password" : "Identity provider"} · ${one.address ?? "unknown address"} · active ${when(one.lastSeen, view.now)} · signed in ${when(one.createdAt, view.now)}</p></div>\
|
|
31
|
-
${one.here ? "" : post({ action: "end-session", session: one.idHash }, "Sign out")}</div>`)}</div>`;
|
|
25
|
+
export function credentialsHtml(view, outcome) {
|
|
26
|
+
// An act on this page (sign out, revoke): one button, nothing to prove (the proof row covers only making a token).
|
|
27
|
+
const act = (fields, label, variant = "outline") => postForm("/settings/sessions", btn(label, { sm: true, type: "submit", variant }), { hidden: { ...fields, ...(view.everyone ? { everyone: "1" } : {}) } });
|
|
28
|
+
const answer = outcome.problem ? notice(outcome.problem) : outcome.said ? infoLine(outcome.said) : "";
|
|
29
|
+
const toggle = view.canSeeEveryone ? btn(view.everyone ? "Show only mine" : "Show everyone’s", { sm: true, variant: "ghost", href: `/settings/sessions${view.everyone ? "" : "?everyone=1"}` }) : undefined;
|
|
32
30
|
const others = view.sessions.filter(one => !one.here && one.account === view.who).length;
|
|
33
|
-
const endOthers = others > 0 && !view.everyone ?
|
|
31
|
+
const endOthers = others > 0 && !view.everyone ? acts(act({ action: "end-others" }, `Sign out everywhere else (${others})`)) : "";
|
|
32
|
+
const sessions = settingsSection({ id: "signed-in", title: "Signed in", ...(toggle ? { right: toggle } : {}),
|
|
33
|
+
body: joinHtml([
|
|
34
|
+
view.sessions.length === 0 ? note("No one else is signed in.") : joinHtml(view.sessions.map(one => settingsRecord({
|
|
35
|
+
title: html `${view.everyone ? html `<b>${one.account}</b> · ` : ""}${deviceWords(one.agent)}${one.here ? html ` ${chip("This browser", "")}` : ""}`,
|
|
36
|
+
sub: `${one.ssoAt === null ? "Password" : "Identity provider"} · ${one.address ?? "unknown address"} · signed in ${when(one.createdAt, view.now)}`,
|
|
37
|
+
when: `Active ${when(one.lastSeen, view.now)}`,
|
|
38
|
+
action: one.here ? "" : act({ action: "end-session", session: one.idHash }, "Sign out"),
|
|
39
|
+
attrs: { "data-session": one.idHash.slice(0, 12) },
|
|
40
|
+
}))),
|
|
41
|
+
endOthers,
|
|
42
|
+
]) });
|
|
34
43
|
const live = view.tokens.filter(one => tokenLive(one, view.now));
|
|
35
|
-
// v111: its projects, and one state: when it stops (soon, said once
|
|
44
|
+
// v111: its projects, and one state: when it stops (soon, said once) or, once replaced, when it ends.
|
|
36
45
|
const ends = (one) => {
|
|
37
46
|
if (one.replacedBy !== null && one.overlapUntil !== null)
|
|
38
|
-
return
|
|
47
|
+
return `Replaced · stops ${one.overlapUntil.slice(11, 16)} UTC`;
|
|
39
48
|
if (expiryNoticeDue(one, view.now) === null)
|
|
40
|
-
return
|
|
49
|
+
return `Expires ${one.expiresAt.slice(0, 10)}`;
|
|
41
50
|
const days = daysLeft(one.expiresAt, view.now);
|
|
42
|
-
return
|
|
51
|
+
return `Expires ${days <= 1 ? "within a day" : `in ${days} days`}`;
|
|
43
52
|
};
|
|
44
53
|
const scope = (one) => one.projects === null ? "All projects" : one.projects.length === 0 ? "No projects" : one.projects.map(repo => projectName(repo)).join(", ");
|
|
45
|
-
const
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
+
const create = disclose("New API token", kitSectionForm({ proof: "sessions-token", action: "/settings/sessions", id: "token-form", native: true, hidden: { action: "create-token" },
|
|
55
|
+
save: { label: "Make the token" }, confirm: "Make an API token",
|
|
56
|
+
body: joinHtml([
|
|
57
|
+
formRow("Name", "So you can tell it apart later.", input({ id: "token-name", name: "name", attrs: { maxlength: 60, required: true, placeholder: "for example: CI", autocomplete: "off" } })),
|
|
58
|
+
formRow("It can", null, select({ id: "token-access", name: "access", label: "It can", current: "read",
|
|
59
|
+
items: [["read", "Read (tasks, results, the ledger)"], ["act", "Act as you (file and manage work; never approve)"]] })),
|
|
60
|
+
formRow("Expires in", null, select({ id: "token-days", name: "days", label: "Expires in", current: "90", items: TOKEN_DAYS.map(days => [String(days), `${days} days`]) })),
|
|
61
|
+
note("Making a token is a new way in, so it always asks for your password. The token is shown once, on the next page."),
|
|
62
|
+
]) }), live.length === 0);
|
|
63
|
+
const tokens = settingsSection({ id: "api-tokens", title: "API tokens",
|
|
64
|
+
lead: html `For scripts and CI: send <code class="k-mono">Authorization: Bearer <token></code>. A token can’t approve anything.`,
|
|
65
|
+
body: joinHtml([
|
|
66
|
+
live.length === 0 ? note("No API tokens.") : joinHtml(live.map(one => settingsRecord({
|
|
67
|
+
title: html `${view.everyone ? html `<b>${one.account}</b> · ` : ""}${one.name}`,
|
|
68
|
+
sub: `${one.access === "act" ? "Can act" : "Read only"} · ${scope(one)} · ${ends(one)}${view.limits === undefined ? "" : ` · ${view.limits.note(one)}`}`,
|
|
69
|
+
when: `Last used ${when(one.lastUsedAt, view.now)}`,
|
|
70
|
+
action: act({ action: "revoke-token", token: one.id }, "Revoke", "danger"),
|
|
71
|
+
attrs: { "data-token": one.id },
|
|
72
|
+
}))),
|
|
73
|
+
view.everyone ? "" : create,
|
|
74
|
+
]) });
|
|
75
|
+
return joinHtml([answer, sessions, tokens, view.limits?.section ?? ""]);
|
|
54
76
|
}
|
|
55
|
-
/** The token, once
|
|
77
|
+
/** The token, once, on a page with no script: selectable text, what it may do, and where to revoke it. */
|
|
56
78
|
export function tokenShownHtml(name, token, access, expiresAt) {
|
|
57
|
-
return
|
|
58
|
-
|
|
79
|
+
return settingsSubPage("access", "API token", settingsSection({ id: "token-shown", title: `${name} · shown once, so copy it now`,
|
|
80
|
+
lead: "Only a hash is kept, so this page is the only time you’ll see it.",
|
|
81
|
+
body: joinHtml([
|
|
82
|
+
html `<p class="k-secret-val">${token}</p>`,
|
|
83
|
+
note(`${access === "act" ? "It acts as you and never approves" : "It reads"} until ${expiresAt.slice(0, 10)}. Revoke it any time on Sessions and tokens.`),
|
|
84
|
+
acts(btn("Back to Sessions and tokens", { sm: true, href: "/settings/sessions" })),
|
|
85
|
+
]) }));
|
|
59
86
|
}
|
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)
|