toolroll 0.8.1 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (59) hide show
  1. package/CHANGELOG.md +49 -0
  2. package/dist/agent-onboard.d.ts +7 -0
  3. package/dist/agent-onboard.js +23 -5
  4. package/dist/browser/workspace.css +1 -1
  5. package/dist/browser/workspace.js +21 -20
  6. package/dist/browser-workspace.d.ts +10 -0
  7. package/dist/chat-delivery.js +51 -3
  8. package/dist/chat-quiet.d.ts +28 -0
  9. package/dist/chat-quiet.js +161 -0
  10. package/dist/checkout-cleanup.d.ts +84 -0
  11. package/dist/checkout-cleanup.js +245 -0
  12. package/dist/cli.d.ts +1 -1
  13. package/dist/cli.js +3 -0
  14. package/dist/digest-times.d.ts +3 -0
  15. package/dist/digest-times.js +7 -0
  16. package/dist/dispose.js +2 -0
  17. package/dist/export.js +1 -1
  18. package/dist/first-run.d.ts +4 -1
  19. package/dist/first-run.js +2 -1
  20. package/dist/integrations-ui.d.ts +13 -0
  21. package/dist/integrations-ui.js +65 -0
  22. package/dist/integrations.d.ts +113 -0
  23. package/dist/integrations.js +526 -0
  24. package/dist/mcp.js +26 -0
  25. package/dist/operate.d.ts +5 -6
  26. package/dist/operate.js +254 -25
  27. package/dist/project-delete.js +1 -0
  28. package/dist/prompt.d.ts +7 -2
  29. package/dist/prompt.js +36 -7
  30. package/dist/publish.d.ts +11 -0
  31. package/dist/publish.js +9 -2
  32. package/dist/pull-request-flow.d.ts +140 -0
  33. package/dist/pull-request-flow.js +440 -0
  34. package/dist/pull-request-schema.d.ts +5 -0
  35. package/dist/pull-request-schema.js +21 -0
  36. package/dist/pull-request-ui.d.ts +23 -0
  37. package/dist/pull-request-ui.js +55 -0
  38. package/dist/pulls.d.ts +5 -0
  39. package/dist/pulls.js +11 -0
  40. package/dist/serve.d.ts +6 -0
  41. package/dist/serve.js +323 -26
  42. package/dist/setup-guide.d.ts +2 -2
  43. package/dist/storage-ui.d.ts +10 -0
  44. package/dist/storage-ui.js +67 -0
  45. package/dist/storage.d.ts +15 -1
  46. package/dist/storage.js +62 -7
  47. package/dist/store.d.ts +66 -5
  48. package/dist/store.js +160 -19
  49. package/dist/surface.js +2 -0
  50. package/dist/telegram-progress.d.ts +1 -0
  51. package/dist/telegram-progress.js +1 -1
  52. package/dist/telegram.js +95 -15
  53. package/dist/toolroll-update-ui.d.ts +2 -0
  54. package/dist/toolroll-update-ui.js +1 -1
  55. package/dist/toolroll-update.d.ts +26 -6
  56. package/dist/toolroll-update.js +188 -50
  57. package/dist/worktree.d.ts +24 -10
  58. package/dist/worktree.js +84 -44
  59. package/package.json +1 -1
@@ -0,0 +1,55 @@
1
+ const escape = (text) => text.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#39;");
2
+ const METHOD_WORDS = { squash: "Squash and merge", merge: "Merge commit", rebase: "Rebase and merge" };
3
+ export function pullRequestSettingsHtml(view) {
4
+ const hidden = (act) => `<input type="hidden" name="csrf" value="${escape(view.csrf)}"><input type="hidden" name="repo" value="${escape(view.repo)}"><input type="hidden" name="act" value="${act}">`;
5
+ const password = `<label>Password<input type="password" name="password" autocomplete="current-password" required></label>`;
6
+ const notes = [
7
+ view.said === null ? "" : `<p class="notice" role="status">${escape(view.said)}</p>`,
8
+ view.problem === null ? "" : `<p class="problem" role="alert">${escape(view.problem)}</p>`,
9
+ ].join("");
10
+ const head = `<p class="meta">${escape(view.name)} · <span class="mono">${escape(view.repo)}</span></p>${notes}`;
11
+ const publishing = view.publishing;
12
+ if (publishing.on) {
13
+ const status = `<section class="card pr-settings"><p><strong>On</strong> · <span class="mono">${escape(publishing.githubRepo)}</span> into <span class="mono">${escape(publishing.base)}</span></p>` +
14
+ `<p class="meta">${publishing.legacy ? "Every finished build opens a pull request (set up with publish grant)." : "Complete offers “Complete and open a pull request”."} Set up by ${escape(publishing.grantedBy)}.</p></section>`;
15
+ if (!view.canChange)
16
+ return head + status;
17
+ const methods = ["squash", "merge", "rebase"].map(method => `<option value="${method}"${publishing.mergeMethod === method ? " selected" : ""}>${METHOD_WORDS[method]}${method === "squash" ? " (default)" : ""}</option>`).join("");
18
+ return head + status +
19
+ `<form method="post" action="/settings/pull-requests" class="card pr-settings">${hidden("settings")}` +
20
+ `<h2>Merging</h2>` +
21
+ `<label>Merge method<select name="method">${methods}</select></label>` +
22
+ `<label class="row pr-check"><input type="checkbox" name="when-green" value="1"${publishing.mergeWhenGreen ? " checked" : ""}> Merge when checks pass</label>` +
23
+ `<p class="meta">Off by default. When on, a pull request merges by itself once its checks pass on the completed commit. Branches are deleted after merging.</p>` +
24
+ `${password}<button type="submit">Save</button></form>` +
25
+ `<details class="settings-more"><summary>Turn off pull requests</summary>` +
26
+ `<form method="post" action="/settings/pull-requests" class="card pr-settings">${hidden("off")}` +
27
+ `<p class="meta">Nothing more is pushed. Open pull requests stay on GitHub.</p>${password}<button type="submit" class="danger">Turn off</button></form></details>`;
28
+ }
29
+ const check = view.check;
30
+ if (check === null)
31
+ return head + `<section class="card pr-settings"><p><strong>Off</strong></p><p class="meta">An approver can turn on pull requests.</p></section>`;
32
+ if (!check.ok) {
33
+ return head + `<section class="card pr-settings"><p><strong>Can’t turn on yet</strong></p><p>${escape(check.message)}</p>` +
34
+ `<p><a class="button-link" href="/settings/pull-requests?repo=${encodeURIComponent(view.repo)}">Check again</a></p></section>`;
35
+ }
36
+ const plan = check.plan;
37
+ return head +
38
+ `<form method="post" action="/settings/pull-requests" class="card pr-settings">${hidden("on")}` +
39
+ `<input type="hidden" name="github" value="${escape(plan.githubRepo)}"><input type="hidden" name="base" value="${escape(plan.base)}">` +
40
+ `<p><strong>Ready to turn on</strong></p>` +
41
+ `<ul class="pr-terms"><li>Pull requests open on <span class="mono">${escape(plan.githubRepo)}</span> into <span class="mono">${escape(plan.base)}</span>${plan.account === null ? "" : `, as ${escape(plan.account)}`}.</li>` +
42
+ `<li>Complete offers “Complete and open a pull request”, from the exact completed commit.</li>` +
43
+ `<li>Merging squashes and deletes the branch, and always takes your password.</li></ul>` +
44
+ `${password}<button type="submit">Turn on pull requests</button></form>`;
45
+ }
46
+ export const PULL_REQUEST_SETTINGS_CSS = `
47
+ .pr-settings { display: grid; gap: .6rem; max-width: 40rem; }
48
+ .pr-settings p, .pr-settings h2 { margin: 0; }
49
+ .pr-settings label { display: grid; gap: .25rem; }
50
+ .pr-settings label input[type=password], .pr-settings select { min-height: 44px; box-sizing: border-box; width: 100%; }
51
+ .pr-settings .pr-check { display: flex; align-items: center; gap: .5rem; min-height: 44px; }
52
+ .pr-settings button { min-height: 44px; justify-self: start; }
53
+ .pr-terms { margin: 0; padding-left: 1.1rem; display: grid; gap: .25rem; }
54
+ @media (max-width: 480px) { .pr-settings button { justify-self: stretch; } }
55
+ `;
package/dist/pulls.d.ts CHANGED
@@ -92,6 +92,11 @@ export declare function parsePulls(json: string): Pull[] | null;
92
92
  * guard excluded it did exactly what it was written to do.
93
93
  */
94
94
  export declare function summarizeChecks(rollup: unknown): ChecksState;
95
+ /** The checks that finished and did not succeed, by the name GitHub shows, with their details page when one is given. */
96
+ export declare function failingChecks(rollup: unknown): {
97
+ name: string;
98
+ url: string | null;
99
+ }[];
95
100
  /**
96
101
  * Whose move it is.
97
102
  *
package/dist/pulls.js CHANGED
@@ -155,6 +155,17 @@ export function summarizeChecks(rollup) {
155
155
  return "running";
156
156
  return "passing";
157
157
  }
158
+ /** The checks that finished and did not succeed, by the name GitHub shows, with their details page when one is given. */
159
+ export function failingChecks(rollup) {
160
+ if (!Array.isArray(rollup))
161
+ return [];
162
+ return rollup.filter(entry => readCheckState(entry) === "failing").map(entry => {
163
+ const raw = entry;
164
+ const name = readString(raw["name"]) || readString(raw["context"]) || "a check";
165
+ const url = readString(raw["detailsUrl"]) || readString(raw["targetUrl"]);
166
+ return { name, url: url === "" ? null : url };
167
+ });
168
+ }
158
169
  function readCheckState(entry) {
159
170
  if (typeof entry !== "object" || entry === null)
160
171
  return "none";
package/dist/serve.d.ts CHANGED
@@ -2,6 +2,7 @@ import { CodingWorkspace } from './coding-workspace.js';
2
2
  import { type MailSender } from "./flow-actions.js";
3
3
  import { type TriggerIo } from "./flow-triggers.js";
4
4
  import { type AssignmentSnapshot } from './assignment.js';
5
+ import type { PublishExec } from './publish.js';
5
6
  import { type VersionRunner } from "./model-catalog.js";
6
7
  import { type Server } from "node:http";
7
8
  import { type ProofVerdict, type CriterionMatrixRow } from "./proof.js";
@@ -11,6 +12,7 @@ import { run as execRun } from "./exec.js";
11
12
  import { type AgentChoice } from "./agentconfig.js";
12
13
  import { type RouteProjection, type RouteOverride, type RouteStamp, type RiskLevel } from "./phase-routing.js";
13
14
  import { type Phase } from "./provider.js";
15
+ import { type IntegrationIo } from "./integrations.js";
14
16
  import { launchRuntimeUpdate } from "./toolroll-update.js";
15
17
  import type { RevisionLineage } from "./store.js";
16
18
  import type { SubscriptionMateRunner } from "./subscription-chat.js";
@@ -123,6 +125,8 @@ export type ServeOptions = {
123
125
  connectionHome?: string;
124
126
  /** Test seam for Chat's first tasks: the `gh` and `git grep` reads. */
125
127
  firstTaskRunner?: typeof execRun;
128
+ /** Test seam for Settings → Integrations: how its checks reach services (fetch, gh, mail servers). */
129
+ integrationIo?: Partial<IntegrationIo>;
126
130
  modelCatalogFetcher?: typeof fetch;
127
131
  /** Test seams for Settings → Models: CLI version probes and the PATH they search. */
128
132
  modelRunner?: VersionRunner;
@@ -155,6 +159,8 @@ export type ServeOptions = {
155
159
  ghPreview?: typeof previewGithubRepo;
156
160
  ghClone?: typeof cloneGithubRepo;
157
161
  ghList?: typeof listGithubRepos;
162
+ /** Injected by tests: the git and gh calls pull-request setup and Merge make. */
163
+ publishExec?: PublishExec;
158
164
  };
159
165
  export declare function createDecisionServer(options: ServeOptions): Server;
160
166
  /**