toolroll 0.9.82 → 0.9.84

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 (92) hide show
  1. package/CHANGELOG.md +41 -0
  2. package/README.md +4 -3
  3. package/dist/assignment-ui.js +5 -1
  4. package/dist/browser/workspace.css +1 -1
  5. package/dist/browser/workspace.js +22 -22
  6. package/dist/browser-crew.js +5 -1
  7. package/dist/browser-workspace.d.ts +7 -0
  8. package/dist/contracts/console-api.d.ts +2 -1
  9. package/dist/contracts/console-api.js +5 -1
  10. package/dist/control-setup.d.ts +9 -0
  11. package/dist/control-setup.js +31 -4
  12. package/dist/control-ui.d.ts +7 -1
  13. package/dist/control-ui.js +3 -2
  14. package/dist/dispatch.d.ts +15 -0
  15. package/dist/dispatch.js +26 -4
  16. package/dist/first-run.d.ts +5 -2
  17. package/dist/first-run.js +13 -2
  18. package/dist/first-tasks-child.d.ts +1 -0
  19. package/dist/first-tasks-child.js +11 -0
  20. package/dist/folder-look.d.ts +110 -0
  21. package/dist/folder-look.js +306 -0
  22. package/dist/guides.js +4 -3
  23. package/dist/learning-child.d.ts +1 -0
  24. package/dist/learning-child.js +34 -0
  25. package/dist/learning-look.d.ts +25 -0
  26. package/dist/learning-look.js +72 -0
  27. package/dist/model-catalog.d.ts +5 -0
  28. package/dist/model-catalog.js +11 -2
  29. package/dist/model-choices.d.ts +188 -0
  30. package/dist/model-choices.js +405 -0
  31. package/dist/model-names.d.ts +6 -0
  32. package/dist/model-names.js +34 -0
  33. package/dist/models-ui.d.ts +69 -5
  34. package/dist/models-ui.js +53 -10
  35. package/dist/needs-you.d.ts +8 -0
  36. package/dist/needs-you.js +8 -0
  37. package/dist/operate.d.ts +53 -0
  38. package/dist/operate.js +277 -49
  39. package/dist/project-admission.d.ts +4 -1
  40. package/dist/project-admission.js +23 -2
  41. package/dist/project-identity.d.ts +44 -0
  42. package/dist/project-identity.js +153 -0
  43. package/dist/project-knowledge.d.ts +6 -6
  44. package/dist/project-tools.d.ts +4 -1
  45. package/dist/project-tools.js +7 -2
  46. package/dist/project.d.ts +4 -1
  47. package/dist/project.js +11 -4
  48. package/dist/repos.d.ts +7 -0
  49. package/dist/repos.js +57 -0
  50. package/dist/serve.js +91 -17
  51. package/dist/server/chat.js +5 -4
  52. package/dist/server/chrome.d.ts +3 -0
  53. package/dist/server/chrome.js +5 -2
  54. package/dist/server/console.css +5 -2
  55. package/dist/server/flows.js +13 -3
  56. package/dist/server/guards.d.ts +4 -0
  57. package/dist/server/guards.js +12 -3
  58. package/dist/server/http.d.ts +12 -0
  59. package/dist/server/http.js +9 -0
  60. package/dist/server/pages.js +102 -92
  61. package/dist/server/people-tokens.js +40 -20
  62. package/dist/server/render-pages.d.ts +12 -16
  63. package/dist/server/render-pages.js +30 -69
  64. package/dist/server/render-people.d.ts +14 -2
  65. package/dist/server/render-people.js +35 -12
  66. package/dist/server/render-settings.js +1 -0
  67. package/dist/server/render-tasks.js +7 -14
  68. package/dist/server/request-context.d.ts +2 -0
  69. package/dist/server/route-table.js +8 -1
  70. package/dist/server/runtime.d.ts +4 -0
  71. package/dist/server/runtime.js +1 -0
  72. package/dist/server/settings.d.ts +58 -1
  73. package/dist/server/settings.js +211 -71
  74. package/dist/server/signup-gate.d.ts +9 -0
  75. package/dist/server/signup-gate.js +40 -0
  76. package/dist/server/tasks.js +19 -5
  77. package/dist/settings-kit-script.d.ts +21 -0
  78. package/dist/settings-kit-script.js +67 -0
  79. package/dist/settings-kit.d.ts +137 -0
  80. package/dist/settings-kit.js +186 -0
  81. package/dist/settings-proofs.d.ts +64 -0
  82. package/dist/settings-proofs.js +101 -0
  83. package/dist/setup-guide.js +4 -2
  84. package/dist/spend-report.d.ts +87 -0
  85. package/dist/spend-report.js +265 -0
  86. package/dist/spend-ui.d.ts +29 -8
  87. package/dist/spend-ui.js +74 -39
  88. package/dist/task-sizing.d.ts +5 -3
  89. package/dist/task-sizing.js +4 -4
  90. package/dist/up-processes.d.ts +13 -0
  91. package/dist/up-processes.js +6 -2
  92. package/package.json +1 -1
@@ -30,8 +30,8 @@ import {} from "./phase-routing.js";
30
30
  import { ALL_CREDENTIAL_ENV } from "./provider.js";
31
31
  /** The classifier's whole budget, from asking to answer. */
32
32
  export const SIZING_BUDGET_MS = 5_000;
33
- /** The model `claude -p` sizes with: small and fast. */
34
- export const SIZING_CLAUDE_MODEL = "haiku";
33
+ /** The model `claude -p` sizes with: small and fast, by its exact id (an alias would float to whatever is newest). */
34
+ export const SIZING_CLAUDE_MODEL = "claude-haiku-5-5";
35
35
  /** Structural or broad work — the description signal planning has always read. */
36
36
  export const SUBSTANTIAL_WORK = /\b(?:architecture|end[- ]to[- ]end|migrat(?:e|ion)|moderni[sz]e|redesign|refactor|rework|workflow|navigation|accessibility|responsive|performance|security|unif(?:y|ied)|multi[- ](?:step|project|service))\b/i;
37
37
  /** The description's own signals: several paths, a long description, or
@@ -55,12 +55,12 @@ function answerOf(value) {
55
55
  const read = readSizeAnswer(value);
56
56
  return read.ok ? read.value : null;
57
57
  }
58
- const SIZE_MEANS = {
58
+ export const SIZE_MEANS = {
59
59
  small: "a contained change a fast model can make directly: copy, a style, a config value, one small function, one or two files",
60
60
  medium: "ordinary feature or fix work across a few files that benefits from the everyday model",
61
61
  large: "broad or structural work: many files, a new subsystem, a redesign or refactor, cross-cutting behaviour",
62
62
  };
63
- const RISKY_MEANS = "Could a mistake here lose data, break security, sign-in, payments or permissions, change a database schema or migration, or be hard to undo?";
63
+ export const RISKY_MEANS = "Could a mistake here lose data, break security, sign-in, payments or permissions, change a database schema or migration, or be hard to undo?";
64
64
  /** What the classifier reads: the task as data, bounded, keys blanked. */
65
65
  export function sizingText(input) {
66
66
  return [
@@ -26,6 +26,14 @@ export type UpWorkerConfig = {
26
26
  terminal: boolean;
27
27
  /** How long a start waits for a predecessor's watch lease to expire (a crashed worker's, after a restart). */
28
28
  leaseWaitMs: number;
29
+ /** Saved projects this start couldn't reach (a folder that didn't answer, a drive not connected): looked at again
30
+ * while it runs, and connected once they answer, on the same saved-list authority the start had. */
31
+ deferredRepos?: string[];
32
+ /** Each of those lines' removal count when this start read the saved list: a different count at binding means it was
33
+ * removed since (even if saved again), and the start's authority for it is gone. */
34
+ deferredGenerations?: Record<string, number>;
35
+ /** The saved line each of `repos` was proved from: a project stays while its line is saved, whatever else answers. */
36
+ repoLines?: Record<string, string[]>;
29
37
  };
30
38
  export type UpRoleStart = {
31
39
  type: "start";
@@ -67,6 +75,11 @@ export type RoleToParent = {
67
75
  } | {
68
76
  type: "repos";
69
77
  repos: string[];
78
+ }
79
+ /** The saved projects the worker still holds start authority for (it only ever shrinks: connected or removed). */
80
+ | {
81
+ type: "deferred";
82
+ repos: string[];
70
83
  } | {
71
84
  type: "failed";
72
85
  reason: "port-busy" | "start";
@@ -53,6 +53,7 @@ export function roleMessage(value, role) {
53
53
  return { type: "ready", role, build: value["build"], pid: value["pid"], url: value["url"], port: value["port"] };
54
54
  case "log": return text(value["line"]) ? { type: "log", line: value["line"] } : null;
55
55
  case "repos": return role === "worker" && texts(value["repos"]) ? { type: "repos", repos: [...value["repos"]] } : null;
56
+ case "deferred": return role === "worker" && texts(value["repos"]) ? { type: "deferred", repos: [...value["repos"]] } : null;
56
57
  case "failed": return (value["reason"] === "port-busy" || value["reason"] === "start") && text(value["detail"]) ? { type: "failed", reason: value["reason"], detail: value["detail"] } : null;
57
58
  case "fatal": return text(value["detail"]) ? { type: "fatal", detail: value["detail"] } : null;
58
59
  case "sign-in-link": return role === "console" && whole(value["id"]) && orNull(value["link"], (one) => nonEmpty(one, 2_048)) ? { type: "sign-in-link", id: value["id"], link: value["link"] } : null;
@@ -78,12 +79,15 @@ export function startMessage(value) {
78
79
  return { ...base, role: "console", config: config };
79
80
  }
80
81
  if (value["role"] === "worker") {
81
- const keys = ["runner", "token", "repos", "pinnedRepos", "projectRoots", "registryPath", "pool", "forMs", "publicUrl", "stopGraceMs", "verbose", "terminal", "leaseWaitMs"];
82
+ const keys = ["runner", "token", "repos", "pinnedRepos", "projectRoots", "registryPath", "pool", "forMs", "publicUrl", "stopGraceMs", "verbose", "terminal", "leaseWaitMs", "deferredRepos", "deferredGenerations", "repoLines"];
82
83
  if (Object.keys(config).some(key => !keys.includes(key)))
83
84
  return null;
84
85
  if (!nonEmpty(config["runner"], 256) || !nonEmpty(config["token"], 1_024) || !texts(config["repos"]) || !texts(config["pinnedRepos"]) || !texts(config["projectRoots"]) ||
85
86
  !nonEmpty(config["registryPath"], 4_096) || !nonEmpty(config["pool"], 4_096) || !orNull(config["forMs"], (one) => whole(one, 1)) ||
86
- !orNull(config["publicUrl"], (one) => nonEmpty(one, 2_048)) || !whole(config["stopGraceMs"], 0) || typeof config["verbose"] !== "boolean" || typeof config["terminal"] !== "boolean" || !whole(config["leaseWaitMs"], 0))
87
+ !orNull(config["publicUrl"], (one) => nonEmpty(one, 2_048)) || !whole(config["stopGraceMs"], 0) || typeof config["verbose"] !== "boolean" || typeof config["terminal"] !== "boolean" || !whole(config["leaseWaitMs"], 0) ||
88
+ (config["deferredRepos"] !== undefined && !texts(config["deferredRepos"])) ||
89
+ (config["deferredGenerations"] !== undefined && !(isObject(config["deferredGenerations"]) && Object.values(config["deferredGenerations"]).every(one => whole(one, -1, Number.MAX_SAFE_INTEGER)))) ||
90
+ (config["repoLines"] !== undefined && !(isObject(config["repoLines"]) && Object.values(config["repoLines"]).every(one => texts(one)))))
87
91
  return null;
88
92
  return { ...base, role: "worker", config: config };
89
93
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "toolroll",
3
- "version": "0.9.82",
3
+ "version": "0.9.84",
4
4
  "description": "A control plane for unattended coding agents — queue tasks, walk away, come back to pull requests. Agents build in leased worktrees, never touch your default branch, and interrupt you only for decisions that need a human.",
5
5
  "directories": {
6
6
  "doc": "docs"