toolroll 0.9.52 → 0.9.53

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 (146) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/README.md +55 -80
  3. package/dist/agentconfig.d.ts +11 -36
  4. package/dist/agentconfig.js +3 -62
  5. package/dist/approval-policy.d.ts +1 -1
  6. package/dist/approval-policy.js +1 -1
  7. package/dist/board.d.ts +3 -19
  8. package/dist/board.js +4 -42
  9. package/dist/browser/workspace.js +18 -18
  10. package/dist/browser-workspace.d.ts +2 -1
  11. package/dist/builder.d.ts +9 -40
  12. package/dist/builder.js +50 -257
  13. package/dist/chat-actions.js +3 -14
  14. package/dist/chat-controls.d.ts +0 -4
  15. package/dist/chat-controls.js +0 -1
  16. package/dist/chat-decide.js +1 -3
  17. package/dist/chat-delivery.d.ts +0 -2
  18. package/dist/chat-delivery.js +0 -1
  19. package/dist/chat-quiet.js +2 -2
  20. package/dist/chat-task-actions.d.ts +1 -1
  21. package/dist/chat-task-actions.js +0 -2
  22. package/dist/claim.d.ts +79 -244
  23. package/dist/claim.js +688 -1023
  24. package/dist/cli.d.ts +2 -0
  25. package/dist/cli.js +10 -2
  26. package/dist/contracts/cli.d.ts +0 -13
  27. package/dist/contracts/cli.js +0 -2
  28. package/dist/contracts/console-api.d.ts +5 -10
  29. package/dist/contracts/console-api.js +4 -10
  30. package/dist/contracts/flow.d.ts +50 -0
  31. package/dist/contracts/flow.js +26 -1
  32. package/dist/contracts/lead-tools.d.ts +0 -13
  33. package/dist/contracts/lead-tools.js +3 -3
  34. package/dist/contracts/store-json.d.ts +1 -25
  35. package/dist/contracts/store-json.js +3 -13
  36. package/dist/converse.d.ts +1 -11
  37. package/dist/converse.js +6 -38
  38. package/dist/coordinator.d.ts +0 -1
  39. package/dist/coordinator.js +3 -5
  40. package/dist/demo.js +16 -26
  41. package/dist/desktop-update-gate.js +0 -1
  42. package/dist/desktop-update.js +1 -3
  43. package/dist/dispatch.d.ts +1 -1
  44. package/dist/dispatch.js +1 -1
  45. package/dist/dispose.d.ts +2 -3
  46. package/dist/dispose.js +17 -92
  47. package/dist/envelope.js +0 -3
  48. package/dist/exec.d.ts +0 -64
  49. package/dist/exec.js +3 -356
  50. package/dist/exhaustion.d.ts +22 -76
  51. package/dist/exhaustion.js +14 -140
  52. package/dist/export.js +4 -4
  53. package/dist/flow-engine.js +1 -1
  54. package/dist/flow-schedule.d.ts +154 -0
  55. package/dist/flow-schedule.js +321 -0
  56. package/dist/flow-share.js +1 -1
  57. package/dist/flow-triggers.d.ts +6 -1
  58. package/dist/flow-triggers.js +65 -10
  59. package/dist/flows-cli.js +8 -4
  60. package/dist/flows-ui.js +2 -0
  61. package/dist/flows.js +1 -1
  62. package/dist/guides.js +9 -29
  63. package/dist/invoke.d.ts +1 -24
  64. package/dist/invoke.js +17 -259
  65. package/dist/lead-status.js +2 -4
  66. package/dist/lead-voice.js +1 -1
  67. package/dist/mate-doors.d.ts +1 -2
  68. package/dist/mate-doors.js +12 -25
  69. package/dist/mate-tools.d.ts +2 -2
  70. package/dist/mate-tools.js +10 -22
  71. package/dist/modes.d.ts +6 -7
  72. package/dist/modes.js +7 -13
  73. package/dist/operate-remote-arguments.js +2 -6
  74. package/dist/operate-remote.js +6 -7
  75. package/dist/operate.d.ts +0 -6
  76. package/dist/operate.js +222 -2247
  77. package/dist/phase-routing.d.ts +13 -23
  78. package/dist/phase-routing.js +13 -35
  79. package/dist/plan-auto.js +2 -2
  80. package/dist/planner-source.js +2 -1
  81. package/dist/policy.d.ts +1 -4
  82. package/dist/policy.js +0 -8
  83. package/dist/process-recovery-eligibility.js +2 -3
  84. package/dist/project-delete.js +3 -15
  85. package/dist/proposal.d.ts +4 -24
  86. package/dist/proposal.js +3 -88
  87. package/dist/provider-auth.d.ts +3 -3
  88. package/dist/provider-auth.js +4 -6
  89. package/dist/provider.d.ts +11 -25
  90. package/dist/provider.js +4 -36
  91. package/dist/push.js +1 -1
  92. package/dist/recipe-ui.js +6 -6
  93. package/dist/recipes.d.ts +3 -3
  94. package/dist/recipes.js +27 -23
  95. package/dist/run-closeout.d.ts +1 -1
  96. package/dist/run-closeout.js +1 -4
  97. package/dist/scope.d.ts +11 -65
  98. package/dist/scope.js +17 -82
  99. package/dist/serve.js +15 -24
  100. package/dist/server/chat.js +7 -30
  101. package/dist/server/flows.js +11 -10
  102. package/dist/server/guards.js +0 -1
  103. package/dist/server/pages-assets.js +1 -1
  104. package/dist/server/pages.js +0 -2
  105. package/dist/server/people-tokens.js +0 -4
  106. package/dist/server/route-table.d.ts +1 -1
  107. package/dist/server/route-table.js +2 -17
  108. package/dist/server/settings.js +1 -8
  109. package/dist/server/shared.d.ts +28 -212
  110. package/dist/server/shared.js +71 -780
  111. package/dist/server/task-views.js +9 -76
  112. package/dist/server/tasks.d.ts +1 -50
  113. package/dist/server/tasks.js +36 -946
  114. package/dist/setup-guide.d.ts +2 -2
  115. package/dist/slack-chat.d.ts +0 -2
  116. package/dist/slack-chat.js +0 -1
  117. package/dist/store.d.ts +105 -1340
  118. package/dist/store.js +706 -4010
  119. package/dist/surface.js +10 -24
  120. package/dist/task-composer.d.ts +1 -1
  121. package/dist/task-composer.js +1 -1
  122. package/dist/task-control.d.ts +3 -10
  123. package/dist/task-control.js +2 -7
  124. package/dist/teammate-desk.js +1 -1
  125. package/dist/teammates-ui.js +1 -1
  126. package/dist/telegram-mate.d.ts +0 -3
  127. package/dist/telegram-mate.js +0 -1
  128. package/dist/templates.d.ts +11 -7
  129. package/dist/templates.js +12 -9
  130. package/dist/toolroll-update.d.ts +10 -0
  131. package/dist/toolroll-update.js +56 -4
  132. package/dist/work-index.js +2 -6
  133. package/dist/workspace-ui.js +1 -1
  134. package/package.json +1 -1
  135. package/scripts/recovery-canary.mjs +3 -3
  136. package/dist/contest.d.ts +0 -318
  137. package/dist/contest.js +0 -753
  138. package/dist/held.d.ts +0 -150
  139. package/dist/held.js +0 -799
  140. package/dist/liveness.d.ts +0 -30
  141. package/dist/liveness.js +0 -42
  142. package/dist/pricing.d.ts +0 -45
  143. package/dist/pricing.js +0 -77
  144. package/dist/routine.d.ts +0 -228
  145. package/dist/routine.js +0 -764
  146. package/dist/supervisor.mjs +0 -297
@@ -18,14 +18,12 @@ import { openWorkDecisionOf } from "../work-summary.js";
18
18
  import { learningHtml } from "../workspace-ui.js";
19
19
  import { randomBytes } from "node:crypto";
20
20
  import {} from "node:http";
21
- import { agentChoicesFor, INSTALLATION_SCOPE, routeOfTask } from "../agentconfig.js";
21
+ import { agentChoicesFor, routeOfTask } from "../agentconfig.js";
22
22
  import { rulesSummary } from "../approval-rules-ui.js";
23
- import { nonceHashOf } from "../contest.js";
24
23
  import { hasForbiddenControls } from "../decision.js";
25
24
  import { diagnoseTaskDispatch } from "../dispatch.js";
26
25
  import { readVerifiedArtifact, readVerifiedReport } from "../evidence.js";
27
26
  import { computeGaps } from "../gaps.js";
28
- import { modeTermsFromJson } from "../modes.js";
29
27
  import { projectRoute } from "../phase-routing.js";
30
28
  import { milestonesOf, parseExecutionPlanDocument } from "../plan.js";
31
29
  import { contractChangesOf, decodePlanContractRecord, describeContractChanges } from "../planner-source.js";
@@ -34,7 +32,7 @@ import { isRevisionFeedback } from "../result-review.js";
34
32
  import { buildReviewOf } from "../review-switch.js";
35
33
  import { isAlive as runnerAlive } from "../runner.js";
36
34
  import { approvalOf } from "../scope.js";
37
- import { approvalFormDigest, attendedWatchWords, chatResultHref, completionReceiptView, consentDoorOf, decisionsFor, diffFileAnchor, escape, evidenceLinksFor, followUpsFor, oneLineOf, orderChangedFiles, parseReviewDiff, proofBundleView, publicationFactsOf, receiptStatusOf, refuse, resumeCeremonyPage, resumeDigestOf, reviewHref, screen, taskBody, taskChatHref, taskHref, taskPage, withinSignedTouches } from "./shared.js";
35
+ import { approvalFormDigest, nonceHashOf, chatResultHref, completionReceiptView, consentDoorOf, decisionsFor, diffFileAnchor, escape, evidenceLinksFor, followUpsFor, oneLineOf, orderChangedFiles, parseReviewDiff, proofBundleView, publicationFactsOf, receiptStatusOf, refuse, resumeCeremonyPage, resumeDigestOf, reviewHref, screen, taskBody, taskChatHref, taskHref, taskPage, withinSignedTouches } from "./shared.js";
38
36
  import { budgetHoldWords, budgetLabel, monthOf } from "../spend.js";
39
37
  import {} from "../store.js";
40
38
  import { taskControlOf } from "../task-control.js";
@@ -237,12 +235,8 @@ export function createTaskViews(runtime) {
237
235
  // A broken revision brief blocks the whole approval surface (audit
238
236
  // IV-3): no nonce is minted over a batch nobody can verify.
239
237
  const revisionBroken = revision !== null && "problem" in revision;
240
- // A tournament task's yes covers BOTH documents (finding 31): where
241
- // race terms are filed, the digest being shown — and bound by the
242
- // nonce — is the joint fingerprint, never the scope's alone.
243
- const raceTerms = ref === null ? null : runtime.store.activeTournamentTerms(ref.id);
244
238
  const planView = ref === null ? null : planViewOf(ref.id);
245
- const approvalDigest = scope === null ? null : approvalFormDigest(scope.digest, raceTerms?.raceDigest ?? null, planView?.sha256 ?? null);
239
+ const approvalDigest = scope === null ? null : approvalFormDigest(scope.digest, planView?.sha256 ?? null);
246
240
  // The nonce is minted at render, per viewer, bound to the digest being
247
241
  // shown — the browser approval flow starts here and nowhere else.
248
242
  // …and only through an OPEN consent door (v48): an unreadable route,
@@ -325,9 +319,8 @@ export function createTaskViews(runtime) {
325
319
  if (ref === null || found.state !== "queued")
326
320
  return null;
327
321
  // Only work billed to an API key waits on a budget (its approved agent's, or Claude's by default).
328
- const base = runtime.store.approvedChainOf(taskId)?.[0];
329
322
  const hold = runtime.store.budgetGate(now)({ ...runtime.store.budgetSubject(ref.id),
330
- agents: base !== undefined ? [{ provider: base.profile.provider, billing: base.authMode }] : runtime.store.agentsFor([runtime.store.getScope(taskId)?.approvedProfile?.provider ?? "claude"]) });
323
+ agents: runtime.store.agentsFor([runtime.store.getScope(taskId)?.approvedProfile?.provider ?? "claude"]) });
331
324
  if (hold.over === null)
332
325
  return null;
333
326
  return hold.why === "unpriced" ? `${budgetHoldWords(hold, monthOf(now).name)}; this waits until then`
@@ -337,7 +330,7 @@ export function createTaskViews(runtime) {
337
330
  policyHold: (() => {
338
331
  if (ref === null || found.state !== "queued")
339
332
  return null;
340
- const base = runtime.store.approvedChainOf(taskId)?.[0]?.profile ?? runtime.store.getScope(taskId)?.approvedProfile ?? null;
333
+ const base = runtime.store.getScope(taskId)?.approvedProfile ?? null;
341
334
  if (base === null)
342
335
  return null;
343
336
  const verdict = runtime.store.runPolicy(base);
@@ -388,12 +381,6 @@ export function createTaskViews(runtime) {
388
381
  return { label: who.label, filedAgo: ago };
389
382
  })(),
390
383
  holds: ref === null ? [] : runtime.store.activeHolds(ref.id, now),
391
- contest: (() => {
392
- if (ref === null)
393
- return null;
394
- const open = runtime.store.contestNeedingOperator(ref.id);
395
- return open === null ? null : { id: open.id, state: open.state, agents: runtime.store.contestants(open.id).length, kind: open.kind };
396
- })(),
397
384
  claimed: ref === null ? false : runtime.store.hasLiveClaim(ref.id, now),
398
385
  // The chain, both directions of trust: blockers outside the ceiling
399
386
  // are named but wear no state and no link (same redaction the board
@@ -447,7 +434,6 @@ export function createTaskViews(runtime) {
447
434
  position: runtime.store.queuePosition(taskId),
448
435
  mirror: runtime.store.mirrorByTask(taskId),
449
436
  scope,
450
- raceTerms,
451
437
  approvalDigest,
452
438
  // The phase route (v47): one projection for the card, the ceremony,
453
439
  // and the focused chat, with the readiness this task's runners report.
@@ -490,56 +476,6 @@ export function createTaskViews(runtime) {
490
476
  csrf: who.via === "cookie" ? who.session.csrf : "",
491
477
  nonce,
492
478
  problem,
493
- attended: (() => {
494
- if (runtime.restricted() || runtime.options.attended === undefined || ref === null || who.via !== "cookie" || runtime.store.isDemo())
495
- return null;
496
- const open = runtime.store.openAuthorizationFor(ref.id);
497
- if (open !== null) {
498
- const spent = runtime.store.authorizationSpendMicrousd(open.id);
499
- const turnsUsed = open.attemptRun === null ? 0 : runtime.store.sessionTurnsOf(open.attemptRun).length;
500
- const state = attendedWatchWords(open.lastBeatAt, now, open.absoluteExpiry);
501
- return {
502
- canMint: false,
503
- open: {
504
- id: open.id,
505
- state,
506
- expiresAt: open.absoluteExpiry,
507
- turnsUsed,
508
- cap: open.maxSessionTurns,
509
- spentMicrousd: spent,
510
- budgetMicrousd: open.budgetMicrousd,
511
- running: open.attemptRun !== null,
512
- },
513
- };
514
- }
515
- const canMint = scope !== null &&
516
- !approvalOf(scope).approved &&
517
- scope.profileState === "resolved" &&
518
- (scope.profile?.provider ?? "") === "claude" &&
519
- ref.repo !== null &&
520
- runtime.store.activeTournamentTerms(ref.id) === null &&
521
- runtime.store.getTask(taskId)?.state === "queued";
522
- if (!canMint)
523
- return { canMint, open: null };
524
- const pinnedModel = scope?.profile?.provider === "claude" ? scope.profile.model : "";
525
- const configured = ["plan", "build", "repair", "review"]
526
- .map(phase => runtime.store.phaseConfig(INSTALLATION_SCOPE, phase))
527
- .filter((row) => row !== null && row.provider === "claude" && row.model !== null)
528
- .map(row => row.model);
529
- const models = [...new Set([pinnedModel, ...configured])].filter(model => model !== "");
530
- const liveMode = ref.repo === null ? null : runtime.store.activeMode(ref.repo, now);
531
- const modeTerms = liveMode === null ? null : modeTermsFromJson(liveMode.termsJson);
532
- return {
533
- canMint,
534
- mint: {
535
- models,
536
- pinnedModel,
537
- posture: modeTerms?.permissionDefault === "escalated" ? "bypassPermissions" : "auto",
538
- quick: modeTerms?.quickMint === true && liveMode !== null && liveMode.signedBy === who.name,
539
- },
540
- open: null,
541
- };
542
- })(),
543
479
  now,
544
480
  };
545
481
  }
@@ -556,12 +492,10 @@ export function createTaskViews(runtime) {
556
492
  if (routed === null)
557
493
  return null;
558
494
  const live = runtime.store.hasLiveClaim(ref.id, now);
559
- const raced = runtime.store.activeTournamentTerms(ref.id) !== null;
560
495
  const shared = {
561
- riskLevel: ref.riskLevel ?? scope?.riskLevel ?? "routine",
562
496
  overrides: ref.routeOverrides ?? [],
563
- editable: who.role === "approver" && !live && !raced,
564
- editableWhy: who.role !== "approver" ? "your login can watch — choosing agents is an approver's act" : live ? "this task is running — its agents cannot change under a live claim" : raced ? "tournament terms are on file — its lanes decide the agents" : null,
497
+ editable: who.role === "approver" && !live,
498
+ editableWhy: who.role !== "approver" ? "your login can watch — choosing agents is an approver's act" : live ? "this task is running — its agents cannot change under a live claim" : null,
565
499
  replanOnPlanChange: ref.plan === "drafted" && scope !== null && !approvalOf(scope).approved,
566
500
  digest: scope?.digest ?? null,
567
501
  choices: agentChoicesFor(runtime.store, ref.repo, routed.kind === "route" ? routed.route : null),
@@ -587,7 +521,7 @@ export function createTaskViews(runtime) {
587
521
  const ref = runtime.store.lookupRef(taskId);
588
522
  const scope = runtime.store.getScope(taskId);
589
523
  // The focused chat is a lens over the task page's own assembled facts.
590
- // Reusing that projection keeps approval nonces, joint race digests,
524
+ // Reusing that projection keeps approval nonces, joint approval digests,
591
525
  // revision verification, decisions, and result evidence on one source
592
526
  // of truth instead of growing a chat-only lifecycle.
593
527
  const view = who === undefined || family.problem !== null ? null : taskViewData(taskId, who, null, options);
@@ -632,7 +566,6 @@ export function createTaskViews(runtime) {
632
566
  planDocument: view.planDocument,
633
567
  planContract: view.planContract ?? null,
634
568
  deliverable: view.deliverable ?? "branch",
635
- raceTerms: view.raceTerms ?? null,
636
569
  revision: view.revision ?? null,
637
570
  coordinator: view.coordinator ?? null,
638
571
  repairChain: view.repairChain ?? null,
@@ -981,7 +914,7 @@ export function createTaskViews(runtime) {
981
914
  * The review cockpit's projection of ONE completed task (Priority 5):
982
915
  * approved intent from the scope and plan already on file, the result
983
916
  * run's sealed artifacts through the same verified readers the run page
984
- * uses, the stored verdict and matrix, the contest and publication
917
+ * uses, the stored verdict and matrix, the publication
985
918
  * rows. Nothing here is a new record: a manual completion (no run), a
986
919
  * legacy result (no proof verdict), and a broken artifact each read as
987
920
  * exactly what they are. Only the selected result is enriched — the
@@ -1,8 +1,5 @@
1
1
  import type { Registration } from './handler-registry.js';
2
- import { type IncomingMessage, type ServerResponse } from "node:http";
3
- import { buildPickView } from "../contest.js";
4
- import { type FormFieldOf, type FormView } from "../contracts/console-api.js";
5
- import { type AttendedTerms } from "../scope.js";
2
+ import { type ServerResponse } from "node:http";
6
3
  import { type Artifact, type Run, type Store } from "../store.js";
7
4
  import type { HandlerContext } from './handler-context.js';
8
5
  import type { ServerRuntime } from './runtime.js';
@@ -17,10 +14,6 @@ export declare function createTasksHandlers(runtime: ServerRuntime): {
17
14
  body: string;
18
15
  retryAfter?: number;
19
16
  }>;
20
- contestScreen: (response: ServerResponse, who: Who, contestId: number, problem: string | null, status: number) => void;
21
- routineMutation: (response: ServerResponse, who: Who, routineId: number, verb: string, body: FormView<FormFieldOf<"routine">>, now: Date) => void;
22
- attendedBeats: (who: Who, request: IncomingMessage, response: ServerResponse, now: Date) => void;
23
- attendMutation: (response: ServerResponse, who: Who, taskId: string, verb: string, body: FormView<FormFieldOf<"attend">>, now: Date) => Promise<void>;
24
17
  taskMutation: (response: ServerResponse, who: Who, taskId: string, verb: string, posted: URLSearchParams, now: Date) => void;
25
18
  queueRegionFor: (project: string | null, csrf: string, revision: number, now: Date) => string;
26
19
  ciFailingFor: (runId: number | null, prNumber: number | null) => boolean;
@@ -31,7 +24,6 @@ export declare function createTasksHandlers(runtime: ServerRuntime): {
31
24
  decisionEvidence: (response: ServerResponse, decisionId: number, artifactId: number) => void;
32
25
  runEvidence: (response: ServerResponse, runId: number, artifactId: number) => void;
33
26
  sendArtifact: (response: ServerResponse, linked: Artifact) => void;
34
- routinePage: (response: ServerResponse, who: Who, routineId: number, problem: string | null, status: number) => void;
35
27
  peekGuards: (runId: number) => {
36
28
  ok: true;
37
29
  admit: PeekAdmission & {
@@ -42,46 +34,5 @@ export declare function createTasksHandlers(runtime: ServerRuntime): {
42
34
  message: string;
43
35
  final?: boolean;
44
36
  };
45
- contestData: (contestId: number) => {
46
- view: NonNullable<ReturnType<typeof buildPickView>>;
47
- taskId: string;
48
- taskTitle: string;
49
- repo: string | null;
50
- refOrigin: string;
51
- questions: Map<number, number>;
52
- liveRuns: Set<number>;
53
- totalMicrousd: number;
54
- anyUnknown: boolean;
55
- rollups: Map<number, {
56
- costMicrousd: number;
57
- tokensIn: number;
58
- tokensOut: number;
59
- measuredRuns: number;
60
- totalRuns: number;
61
- }>;
62
- } | null;
63
- liveAttendedTerms: (taskId: string, inputs: {
64
- minutes: number;
65
- turns: number;
66
- budgetMicrousd: number;
67
- expiry?: string;
68
- parent?: number;
69
- followup?: string;
70
- model?: string;
71
- posture?: string;
72
- }, now: Date) => Promise<{
73
- ok: true;
74
- terms: AttendedTerms;
75
- } | {
76
- ok: false;
77
- problem: string;
78
- }>;
79
- attendConfirmScreen: (response: ServerResponse, who: Who, terms: AttendedTerms, inputs: {
80
- minutes: number;
81
- turns: number;
82
- budgetMicrousd: number;
83
- model?: string;
84
- posture?: string;
85
- }, digest: string, nonce: string, csrf: string) => void;
86
37
  liveRunIds: (rows: readonly (Pick<Run, "id" | "outcome" | "leaseId" | "taskRef">)[]) => Set<number>;
87
38
  };