@drisp/cli 0.7.7 → 0.7.9

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.
@@ -21,6 +21,7 @@ import {
21
21
  LAYOUT_MARKERS,
22
22
  ORCHESTRATOR_LOOP,
23
23
  WAITING_ON_CHILDREN_STOP_REASON,
24
+ budgetTokens,
24
25
  compileWorkflowPlan,
25
26
  createSteerQueue,
26
27
  createWorkflowRunner,
@@ -47,6 +48,7 @@ import {
47
48
  resolveWorkflow,
48
49
  resolveWorkflowManifestPath,
49
50
  resolveWorkflowPlugins,
51
+ runUsage,
50
52
  selectWorkflowCapabilities,
51
53
  serializeRunMemory,
52
54
  sizeClassLimits,
@@ -54,7 +56,7 @@ import {
54
56
  verifyRendered,
55
57
  wakesFreshAfterHandover,
56
58
  workflowRegistryDir
57
- } from "./chunk-HZ6GRLOM.js";
59
+ } from "./chunk-FYXEDUQ6.js";
58
60
  import {
59
61
  __commonJS,
60
62
  __toESM
@@ -12688,7 +12690,7 @@ var RUN_EXIT_CODE = {
12688
12690
  import { existsSync as existsSync4 } from "fs";
12689
12691
  import { link, mkdir as mkdir6, readdir as readdir3, readFile as readFile5, unlink as unlink3, writeFile as writeFile4 } from "fs/promises";
12690
12692
  import { homedir as homedir5 } from "os";
12691
- import { dirname as dirname5, join as join10 } from "path";
12693
+ import { dirname as dirname5, join as join11 } from "path";
12692
12694
 
12693
12695
  // ../../modules/runtime/src/runner-service.ts
12694
12696
  import { execFile } from "child_process";
@@ -12880,7 +12882,7 @@ WantedBy=default.target
12880
12882
  // ../../modules/runtime/src/service.ts
12881
12883
  import { mkdir as mkdir5, readFile as readFile4, unlink as unlink2 } from "fs/promises";
12882
12884
  import { homedir as homedir4 } from "os";
12883
- import { join as join9, resolve as resolve6 } from "path";
12885
+ import { join as join10, resolve as resolve6 } from "path";
12884
12886
 
12885
12887
  // ../../packages/protocol/src/domain.ts
12886
12888
  var RunStatusSchema = external_exports.enum([
@@ -13086,12 +13088,13 @@ function forecastOfCap(declaredCap) {
13086
13088
  }
13087
13089
 
13088
13090
  // ../../packages/protocol/src/v2.ts
13089
- var protocolVersion = { major: 2, minor: 2 };
13091
+ var protocolVersion = { major: 2, minor: 3 };
13090
13092
  var conversationContinuationCapability = "conversation_continuation";
13091
13093
  var abandonedConversationContinuationCapability = "abandoned_conversation_continuation";
13092
13094
  var repositoryAccessCapability = "repository_checkout_v1";
13093
13095
  var workflowInstallCapability = "workflow_install_v1";
13094
13096
  var runDelegationCapability = "run_delegation_v1";
13097
+ var runUsageCapability = "run_usage_v1";
13095
13098
  var runArtifactNameSchema = external_exports.string().regex(/^[a-z][a-z0-9_]{0,63}$/);
13096
13099
  var runArtifactMaxBytes = 64 * 1024;
13097
13100
  var secretEnvironmentSchema = external_exports.record(
@@ -13159,6 +13162,8 @@ var factIdentity = {
13159
13162
  executionRevision: positive,
13160
13163
  emittedAt: timestamp
13161
13164
  };
13165
+ var runUsageSchema = external_exports.strictObject({ counted: sequence, cacheRead: sequence });
13166
+ var reportedUsage = { usage: runUsageSchema.optional() };
13162
13167
  var controlRecordSchema = external_exports.discriminatedUnion("kind", [
13163
13168
  /** Instance-scoped, not tied to a Run: the full replacement inventory of installed Workflows. */
13164
13169
  external_exports.strictObject({ kind: external_exports.literal("workflows.changed"), workflows: installedWorkflowsSchema }),
@@ -13189,7 +13194,8 @@ var controlRecordSchema = external_exports.discriminatedUnion("kind", [
13189
13194
  external_exports.strictObject({ kind: external_exports.literal("local_checkpoint"), checkpointId: id }),
13190
13195
  external_exports.strictObject({ kind: external_exports.literal("portable_checkpoint"), checkpointId: id }),
13191
13196
  external_exports.strictObject({ kind: external_exports.literal("repair_required"), detail: external_exports.string().max(4096) })
13192
- ])
13197
+ ]),
13198
+ ...reportedUsage
13193
13199
  }),
13194
13200
  external_exports.strictObject({
13195
13201
  kind: external_exports.literal("run.finished"),
@@ -13202,8 +13208,14 @@ var controlRecordSchema = external_exports.discriminatedUnion("kind", [
13202
13208
  * Why a Build Run failed, as its close reason (docs/specs/build-orchestrator.md). Sent only for a grant with
13203
13209
  * `parent` or `delegationToken`, which only a Hub that knows this field issues.
13204
13210
  */
13205
- reason: buildCloseReasonSchema.optional()
13211
+ reason: buildCloseReasonSchema.optional(),
13212
+ ...reportedUsage
13206
13213
  }),
13214
+ /**
13215
+ * The usage of a Run while it executes, for a grant marked `reportUsage`. Not an execution fact: it carries no
13216
+ * execution revision, so it never advances, parks or closes the Run, and never wakes its parent.
13217
+ */
13218
+ external_exports.strictObject({ kind: external_exports.literal("run.usage"), runId: id, attemptId: id, ...runUsageSchema.shape }),
13207
13219
  external_exports.strictObject({ kind: external_exports.literal("command.applied"), runId: id, attemptId: id, commandId: id }),
13208
13220
  external_exports.strictObject({
13209
13221
  kind: external_exports.literal("command.rejected"),
@@ -13342,7 +13354,9 @@ var grantSchema = external_exports.strictObject({
13342
13354
  /** This attempt's delegation token: only for a Run started with `delegation`, only to a `run_delegation_v1` Runner. */
13343
13355
  delegationToken: external_exports.string().min(32).max(256).optional(),
13344
13356
  /** Copied from the start intent of a delegated child. */
13345
- parent: runParentSchema.optional()
13357
+ parent: runParentSchema.optional(),
13358
+ /** The runner reports this attempt's usage: set only for a `run_usage_v1` Runner. */
13359
+ reportUsage: external_exports.literal(true).optional()
13346
13360
  });
13347
13361
  var historyRecordSchema = external_exports.strictObject({
13348
13362
  eventId: id,
@@ -13403,7 +13417,13 @@ var runViewSchema = external_exports.object({
13403
13417
  label: external_exports.string().max(160).optional(),
13404
13418
  key: runKeySchema.optional(),
13405
13419
  parent: runParentSchema.optional(),
13406
- delegation: delegationSchema.optional(),
13420
+ /**
13421
+ * Not strict, unlike the start intent's: a Hub keeps more on the Run's delegation (`initialTokenBudget`) than it
13422
+ * shows, and a client never refuses a view for a field it does not read.
13423
+ */
13424
+ delegation: external_exports.object(delegationSchema.shape).optional(),
13425
+ /** The largest cumulative usage the Run's Runner reported; absent until one does (an older Runner never does). */
13426
+ usage: runUsageSchema.optional(),
13407
13427
  /** Resolved by the runner at start; absent until the Run starts and for runners that predate reporting. */
13408
13428
  workflow: workflowIdentitySchema.optional(),
13409
13429
  execution: external_exports.object({
@@ -14528,6 +14548,7 @@ var ExecutionHost = class {
14528
14548
  const outcome = await this.executor.execute(run.grant, this.store, abort.signal);
14529
14549
  if (publish && !abort.signal.aborted && ["completed", "awaiting_attention"].includes(outcome.status))
14530
14550
  await publish(run.grant, abort.signal);
14551
+ const usage = outcome.usage && run.grant.reportUsage ? { usage: outcome.usage } : {};
14531
14552
  this.store.transaction(() => {
14532
14553
  this.store.fact(runId, (identity) => {
14533
14554
  if (outcome.status === "awaiting_attention")
@@ -14546,7 +14567,8 @@ var ExecutionHost = class {
14546
14567
  continuation: {
14547
14568
  kind: this.portableCheckpoints ? "portable_checkpoint" : "local_checkpoint",
14548
14569
  checkpointId: crypto.randomUUID()
14549
- }
14570
+ },
14571
+ ...usage
14550
14572
  };
14551
14573
  return {
14552
14574
  ...identity,
@@ -14558,7 +14580,8 @@ var ExecutionHost = class {
14558
14580
  // resend it forever. Portable checkpoints are configured only on managed Runners.
14559
14581
  ...outcome.workspaceMissing && this.portableCheckpoints && run.grant.spec.repository ? { workspaceUnavailable: true } : {},
14560
14582
  // Only a Hub that issues `parent` or a delegation token knows the field; an older one rejects it.
14561
- ...outcome.reason && (run.grant.parent || run.grant.delegationToken) ? { reason: outcome.reason } : {}
14583
+ ...outcome.reason && (run.grant.parent || run.grant.delegationToken) ? { reason: outcome.reason } : {},
14584
+ ...usage
14562
14585
  };
14563
14586
  });
14564
14587
  if (this.portableCheckpoints && outcome.status !== "awaiting_attention" && !outcome.workspaceMissing)
@@ -14892,9 +14915,18 @@ async function restoreCheckpoint(store, input) {
14892
14915
 
14893
14916
  // ../../modules/runtime/src/software-version.ts
14894
14917
  import "fs";
14895
- var runnerSoftwareVersion = true ? "0.7.7" : JSON.parse(readFileSync2(new URL("../../../apps/cli/package.json", import.meta.url), "utf8")).version;
14918
+ var runnerSoftwareVersion = true ? "0.7.9" : JSON.parse(readFileSync2(new URL("../../../apps/cli/package.json", import.meta.url), "utf8")).version;
14896
14919
 
14897
14920
  // ../../modules/runtime/src/connection.ts
14921
+ var runnerCapabilities = [
14922
+ "local_checkpoint",
14923
+ conversationContinuationCapability,
14924
+ abandonedConversationContinuationCapability,
14925
+ repositoryAccessCapability,
14926
+ workflowInstallCapability,
14927
+ runDelegationCapability,
14928
+ runUsageCapability
14929
+ ];
14898
14930
  var RunnerDisconnectedError = class extends Error {
14899
14931
  constructor() {
14900
14932
  super("runner_disconnected");
@@ -15031,7 +15063,7 @@ var RunnerConnection = class {
15031
15063
  runnerId: store.identity.runnerId,
15032
15064
  installationId: store.identity.installationId,
15033
15065
  softwareVersion: runnerSoftwareVersion,
15034
- capabilities: ["local_checkpoint", conversationContinuationCapability, abandonedConversationContinuationCapability, repositoryAccessCapability, workflowInstallCapability, runDelegationCapability],
15066
+ capabilities: [...runnerCapabilities],
15035
15067
  ...this.options.workflows ? { workflows: this.options.workflows.current() } : {},
15036
15068
  ...this.options.readiness?.current() ? { readiness: this.options.readiness.current() } : {},
15037
15069
  control: {
@@ -20149,8 +20181,8 @@ function sessionStore(store, runId, options = {}) {
20149
20181
 
20150
20182
  // ../../modules/runtime/src/workflow-executor.ts
20151
20183
  import { execFileSync as execFileSync9 } from "child_process";
20152
- import { statSync as statSync3, writeFileSync as writeFileSync4 } from "fs";
20153
- import { join as join8 } from "path";
20184
+ import { statSync as statSync3, writeFileSync as writeFileSync5 } from "fs";
20185
+ import { join as join9 } from "path";
20154
20186
 
20155
20187
  // src/core/build/workspace.ts
20156
20188
  import { execFileSync as execFileSync5 } from "child_process";
@@ -20204,6 +20236,11 @@ var fillSchema = external_exports.strictObject({
20204
20236
  )
20205
20237
  ).min(1).optional(),
20206
20238
  sizeClass: external_exports.enum(["S", "M", "L"]),
20239
+ /**
20240
+ * Who merges the pull request (root ADR-0009): `agent`, the default when absent, or `you`, which makes the Merge
20241
+ * step a Sign-off the member answers in the child's Thread. Filled from the member's words before Start.
20242
+ */
20243
+ merge: external_exports.enum(["agent", "you"]).optional(),
20207
20244
  instructions: external_exports.string().min(1).max(6e3).refine((text) => !TEMPLATE_STRUCTURE.test(text), {
20208
20245
  error: INSTRUCTIONS_MESSAGE
20209
20246
  }),
@@ -20293,6 +20330,8 @@ var issueEntrySchema = external_exports.strictObject({
20293
20330
  mcpServers: external_exports.array(external_exports.string()),
20294
20331
  instructionsSummary: external_exports.string(),
20295
20332
  gates: external_exports.array(external_exports.string()),
20333
+ /** Who merges, from the fill; absent means agents merge (root ADR-0009). */
20334
+ merge: external_exports.enum(["agent", "you"]).optional(),
20296
20335
  workflowName: external_exports.string().max(128)
20297
20336
  });
20298
20337
  var buildPlanSchema = external_exports.strictObject({
@@ -20504,6 +20543,7 @@ function scopeFingerprint(issue) {
20504
20543
  }
20505
20544
 
20506
20545
  // src/core/build/planner.ts
20546
+ var MIXED_MERGE = "The fills disagree on merge. Write the same value in every fill: you when the member asked to merge themselves, else agent.";
20507
20547
  function skipReason(issue, pullRequests) {
20508
20548
  const prs = issue.branchName ? pullRequests[issue.branchName] : void 0;
20509
20549
  if (issue.labels.includes("ready-for-human")) return "ready-for-human";
@@ -20563,7 +20603,8 @@ function shownFromFill(fill) {
20563
20603
  skills: renderedSkills(fill),
20564
20604
  mcpServers: renderedMcpServers(fill),
20565
20605
  instructionsSummary: summarizeInstructions(fill.instructions),
20566
- gates: gateTitles(fill)
20606
+ gates: gateTitles(fill),
20607
+ ...fill.merge ? { merge: fill.merge } : {}
20567
20608
  };
20568
20609
  }
20569
20610
  function blockingGraph(entries) {
@@ -20629,6 +20670,16 @@ function planBuild(context) {
20629
20670
  });
20630
20671
  }
20631
20672
  if (missing.length > 0) return { status: "needs_fills", fills: missing };
20673
+ if (new Set([...fills.values()].map((fill) => fill.merge ?? "agent")).size > 1)
20674
+ return {
20675
+ status: "needs_fills",
20676
+ fills: entries.map(({ identifier, title, url }) => ({
20677
+ identifier,
20678
+ title,
20679
+ url
20680
+ })),
20681
+ reason: MIXED_MERGE
20682
+ };
20632
20683
  const hasSubIssues = new Set(input.issues.map((issue) => issue.parentId));
20633
20684
  const parentOnly = new Set(
20634
20685
  entries.filter(
@@ -20942,7 +20993,8 @@ function validateChildRun(grant, store, paths) {
20942
20993
  if (!verified.ok) throw mismatch(`its ${verified.file} does not re-render from its fill`);
20943
20994
  const shown = approval.plan.entries?.[name];
20944
20995
  const derived = shownFromFill(fill.data);
20945
- if (!shown || !Object.entries(derived).every(([key, value]) => isDeepStrictEqual2(shown[key], value)))
20996
+ const sameMerge = (shown?.merge ?? "agent") === (fill.data.merge ?? "agent");
20997
+ if (!shown || !sameMerge || !Object.entries(derived).every(([key, value]) => isDeepStrictEqual2(shown[key], value)))
20946
20998
  throw mismatch("the plan the member approved showed something else for it");
20947
20999
  return { permissions: renderedPermissions(fill.data) };
20948
21000
  }
@@ -21337,6 +21389,69 @@ function runArtifactEmitter(directory, record, midTurnMinGapMs = MID_TURN_MIN_GA
21337
21389
  };
21338
21390
  }
21339
21391
 
21392
+ // ../../modules/runtime/src/run-usage.ts
21393
+ import { readFileSync as readFileSync5, renameSync, writeFileSync as writeFileSync4 } from "fs";
21394
+ import { join as join8 } from "path";
21395
+ var LIVE_USAGE_MIN_TOKENS = 1e5;
21396
+ var LIVE_USAGE_MIN_INTERVAL_MS = 3e4;
21397
+ function liveUsageReporter(grant, store, read3, now = Date.now) {
21398
+ if (!grant.reportUsage) return () => {
21399
+ };
21400
+ let last = { counted: read3()?.counted ?? 0, at: now() };
21401
+ return () => {
21402
+ const usage = read3();
21403
+ const at = now();
21404
+ if (!usage || usage.counted - last.counted < LIVE_USAGE_MIN_TOKENS || at - last.at < LIVE_USAGE_MIN_INTERVAL_MS)
21405
+ return;
21406
+ const sent = store.transaction(() => {
21407
+ if (store.run(grant.runId).phase !== "executing") return false;
21408
+ store.appendControl({ kind: "run.usage", runId: grant.runId, attemptId: grant.attemptId, ...usage });
21409
+ return true;
21410
+ });
21411
+ if (sent) last = { counted: usage.counted, at };
21412
+ };
21413
+ }
21414
+ var isMark = (value) => {
21415
+ const mark = value;
21416
+ return !!mark && Number.isInteger(mark.index) && typeof mark.title === "string" && typeof mark.tokens === "number" && Number.isFinite(mark.tokens) && mark.tokens >= 0;
21417
+ };
21418
+ var read2 = (path23) => {
21419
+ try {
21420
+ return JSON.parse(readFileSync5(path23, "utf8"));
21421
+ } catch {
21422
+ return void 0;
21423
+ }
21424
+ };
21425
+ function stepUsageRecorder(directory, counted) {
21426
+ const path23 = join8(directory, "usage.json");
21427
+ const stored = read2(path23);
21428
+ const marks = Array.isArray(stored) ? stored.filter(isMark) : [];
21429
+ return ({ closing = false } = {}) => {
21430
+ const step = read2(join8(directory, "step.json"));
21431
+ if (!step || !Number.isInteger(step.index) || typeof step.title !== "string") return;
21432
+ const figure = counted();
21433
+ if (figure === null) return;
21434
+ const last = marks.at(-1);
21435
+ const tokens = Math.max(figure, last?.tokens ?? 0);
21436
+ const sameStep = last?.index === step.index && last?.title === step.title;
21437
+ if (sameStep && !(closing && tokens > last.tokens)) return;
21438
+ marks.push({ index: step.index, title: step.title, tokens });
21439
+ let json = JSON.stringify(marks);
21440
+ if (Buffer.byteLength(json) > ARTIFACT_MAX_BYTES) {
21441
+ for (let i = marks.length - 2; i > 0; i--) {
21442
+ if (marks[i].index === marks[i - 1].index && marks[i].title === marks[i - 1].title) marks.splice(i, 1);
21443
+ }
21444
+ json = JSON.stringify(marks);
21445
+ if (Buffer.byteLength(json) > ARTIFACT_MAX_BYTES) {
21446
+ marks.pop();
21447
+ return;
21448
+ }
21449
+ }
21450
+ writeFileSync4(`${path23}.tmp`, json);
21451
+ renameSync(`${path23}.tmp`, path23);
21452
+ };
21453
+ }
21454
+
21340
21455
  // ../../modules/runtime/src/workflow-executor.ts
21341
21456
  var isBuildCloseReason = (code) => buildCloseReasonSchema.safeParse(code).success;
21342
21457
  var continuationSchema = external_exports.discriminatedUnion("kind", [
@@ -21458,7 +21573,7 @@ function createWorkflowExecutor(dependencies = {}) {
21458
21573
  dependencies.dataDirectory ?? runnerDataDirectory(store.sql.database.name),
21459
21574
  grant.runId
21460
21575
  );
21461
- const emitArtifacts2 = runArtifactEmitter(artifacts, record, (dependencies.artifactIntervalMs ?? 2e3) * 2.5);
21576
+ const emitArtifacts = runArtifactEmitter(artifacts, record, (dependencies.artifactIntervalMs ?? 2e3) * 2.5);
21462
21577
  const loop = bootstrapped.workflow?.loop;
21463
21578
  const childLoop = grant.parent && loop ? { ...loop, maxRunTokens: Math.min(loop.maxRunTokens ?? Infinity, grant.parent.tokenCap) } : loop;
21464
21579
  const config2 = {
@@ -21491,6 +21606,22 @@ function createWorkflowExecutor(dependencies = {}) {
21491
21606
  }
21492
21607
  } : {}
21493
21608
  });
21609
+ const recordUsage = stepUsageRecorder(artifacts, () => {
21610
+ const memory = deserializeRunMemory(view2.getLatestRun()?.runMemoryJson);
21611
+ return memory ? budgetTokens(memory) : null;
21612
+ });
21613
+ const sweepArtifacts2 = (midTurn = false, closing = false) => {
21614
+ try {
21615
+ recordUsage({ closing });
21616
+ } catch {
21617
+ }
21618
+ emitArtifacts(midTurn);
21619
+ };
21620
+ const usage2 = () => {
21621
+ const memory = deserializeRunMemory(view2.getLatestRun()?.runMemoryJson);
21622
+ return memory ? runUsage(memory) : null;
21623
+ };
21624
+ const reportLiveUsage2 = liveUsageReporter(grant, store, usage2, dependencies.now);
21494
21625
  const previous = view2.getLatestRun();
21495
21626
  const predecessor = grant.previousRun ? store.sessionValues(grant.sessionId, "workflow").find((snapshot) => snapshot.id === grant.previousRun.runId) : void 0;
21496
21627
  const adapterResumeSessionId2 = grant.purpose === "resume" ? previous?.adapterSessionId : predecessor?.adapterSessionId;
@@ -21498,12 +21629,12 @@ function createWorkflowExecutor(dependencies = {}) {
21498
21629
  if (continuation?.kind === "answer") {
21499
21630
  const pending2 = pendingApproval(store, grant.runId);
21500
21631
  if (pending2) {
21501
- writeFileSync4(join8(artifacts, "answer.json"), JSON.stringify(continuation.answer));
21632
+ writeFileSync5(join9(artifacts, "answer.json"), JSON.stringify(continuation.answer));
21502
21633
  record(APPROVAL_ANSWERED, { answer: continuation.answer, plan: pending2.plan });
21503
21634
  }
21504
21635
  }
21505
21636
  const guidedPlan = continuation?.kind === "resume" && continuation.guidance?.trim() && pendingApproval(store, grant.runId) ? continuation.guidance : void 0;
21506
- if (guidedPlan !== void 0) writeFileSync4(join8(artifacts, "answer.json"), JSON.stringify(guidedPlan));
21637
+ if (guidedPlan !== void 0) writeFileSync5(join9(artifacts, "answer.json"), JSON.stringify(guidedPlan));
21507
21638
  let storedAnswer2;
21508
21639
  if (continuation?.kind === "answer") {
21509
21640
  const answer = permissionAnswerSchema.safeParse(continuation.answer);
@@ -21534,7 +21665,18 @@ ${JSON.stringify(continuation.answer)}` : grant.spec.prompt;
21534
21665
  Current human request:
21535
21666
  ${prompt2}`;
21536
21667
  }
21537
- return { workingDirectory: workingDirectory2, config: config2, view: view2, adapterResumeSessionId: adapterResumeSessionId2, storedAnswer: storedAnswer2, prompt: prompt2, displayText: displayText2, emitArtifacts: emitArtifacts2 };
21668
+ return {
21669
+ workingDirectory: workingDirectory2,
21670
+ config: config2,
21671
+ view: view2,
21672
+ adapterResumeSessionId: adapterResumeSessionId2,
21673
+ storedAnswer: storedAnswer2,
21674
+ prompt: prompt2,
21675
+ displayText: displayText2,
21676
+ sweepArtifacts: sweepArtifacts2,
21677
+ usage: usage2,
21678
+ reportLiveUsage: reportLiveUsage2
21679
+ };
21538
21680
  };
21539
21681
  let setup2;
21540
21682
  try {
@@ -21546,12 +21688,27 @@ ${prompt2}`;
21546
21688
  if (error instanceof RunSetupError && isBuildCloseReason(error.code)) return { status: "failed", reason: error.code };
21547
21689
  return { status: "failed" };
21548
21690
  }
21549
- const { workingDirectory, config, view, adapterResumeSessionId, storedAnswer, prompt, displayText, emitArtifacts } = setup2;
21691
+ const {
21692
+ workingDirectory,
21693
+ config,
21694
+ view,
21695
+ adapterResumeSessionId,
21696
+ storedAnswer,
21697
+ prompt,
21698
+ displayText,
21699
+ sweepArtifacts,
21700
+ usage,
21701
+ reportLiveUsage
21702
+ } = setup2;
21550
21703
  const queue = createSteerQueue();
21551
21704
  queues.set(grant.runId, queue);
21552
21705
  const sweep = setInterval(() => {
21553
21706
  try {
21554
- emitArtifacts(true);
21707
+ sweepArtifacts(true);
21708
+ } catch {
21709
+ }
21710
+ try {
21711
+ reportLiveUsage();
21555
21712
  } catch {
21556
21713
  }
21557
21714
  }, dependencies.artifactIntervalMs ?? 2e3);
@@ -21587,14 +21744,14 @@ ${prompt2}`;
21587
21744
  }
21588
21745
  });
21589
21746
  },
21590
- onTurnComplete: emitArtifacts,
21747
+ onTurnComplete: () => sweepArtifacts(false, true),
21591
21748
  stdout: { write: () => true },
21592
21749
  stderr: { write: (text) => process.stderr.write(text) },
21593
21750
  json: false
21594
21751
  })).finally(() => {
21595
21752
  queues.delete(grant.runId);
21596
21753
  clearInterval(sweep);
21597
- emitArtifacts();
21754
+ sweepArtifacts(false, true);
21598
21755
  });
21599
21756
  if (!result.workflowOutcome)
21600
21757
  throw new Error(result.failure?.message ?? "Workflow returned no authoritative outcome");
@@ -21621,8 +21778,10 @@ ${prompt2}`;
21621
21778
  runMemoryJson: serializeRunMemory({ ...memory, pendingSteers })
21622
21779
  });
21623
21780
  });
21781
+ const reported = usage();
21782
+ const withUsage = (outcome) => reported ? { ...outcome, usage: reported } : outcome;
21624
21783
  if (status === "awaiting_attention" && !result.workflowOutcome.interruption && result.workflowOutcome.stopReason === WAITING_ON_CHILDREN_STOP_REASON)
21625
- return { status, interruption: { kind: "waiting", message: WAITING_ON_CHILDREN_MESSAGE } };
21784
+ return withUsage({ status, interruption: { kind: "waiting", message: WAITING_ON_CHILDREN_MESSAGE } });
21626
21785
  if (status === "awaiting_attention" && !result.workflowOutcome.interruption && result.workflowOutcome.stopReason === AWAITING_APPROVAL_STOP_REASON) {
21627
21786
  const question = config.workflow?.approvalQuestion;
21628
21787
  if (!question) {
@@ -21630,13 +21789,13 @@ ${prompt2}`;
21630
21789
  code: "approval_question_missing",
21631
21790
  message: "The Journal ended with AWAITING_APPROVAL, but the Workflow has no approvalQuestion."
21632
21791
  });
21633
- return { status: "failed", reason: "approval_question_missing" };
21792
+ return withUsage({ status: "failed", reason: "approval_question_missing" });
21634
21793
  }
21635
21794
  record(APPROVAL_REQUESTED, { question, plan: emittedPlan(store, grant.runId) });
21636
- return { status, interruption: { kind: "question", message: question } };
21795
+ return withUsage({ status, interruption: { kind: "question", message: question } });
21637
21796
  }
21638
21797
  const interruption = status === "awaiting_attention" ? result.workflowOutcome.interruption ?? interruptionFromSuspension(result.workflowOutcome.stopReason) : void 0;
21639
- return {
21798
+ return withUsage({
21640
21799
  status,
21641
21800
  ...interruption ? {
21642
21801
  interruption: {
@@ -21648,7 +21807,7 @@ ${prompt2}`;
21648
21807
  ...interruption.kind === "question" && interruption.requestId ? { requestId: interruption.requestId } : {}
21649
21808
  }
21650
21809
  } : {}
21651
- };
21810
+ });
21652
21811
  }
21653
21812
  };
21654
21813
  }
@@ -21730,8 +21889,8 @@ var runnerConfigSchema = external_exports.object({
21730
21889
  /** The Runner's name in the Team, as Connect recorded it (hostname by default). */
21731
21890
  name: external_exports.string().optional()
21732
21891
  });
21733
- var defaultConfigPath = () => process.env.DRISP_RUNNER_CONFIG ?? join9(homedir4(), ".config", "drisp", "runner-v2.json");
21734
- var expandHome = (value) => resolve6(value.startsWith("~/") ? join9(homedir4(), value.slice(2)) : value);
21892
+ var defaultConfigPath = () => process.env.DRISP_RUNNER_CONFIG ?? join10(homedir4(), ".config", "drisp", "runner-v2.json");
21893
+ var expandHome = (value) => resolve6(value.startsWith("~/") ? join10(homedir4(), value.slice(2)) : value);
21735
21894
  async function readRunnerConfig(path23 = defaultConfigPath()) {
21736
21895
  const config = runnerConfigSchema.parse(JSON.parse(await readFile4(expandHome(path23), "utf8")));
21737
21896
  return { ...config, dataDirectory: expandHome(config.dataDirectory) };
@@ -21740,7 +21899,7 @@ async function startConfiguredRunner(path23 = defaultConfigPath()) {
21740
21899
  const config = await readRunnerConfig(path23);
21741
21900
  await mkdir5(config.dataDirectory, { recursive: true, mode: 448 });
21742
21901
  const store = new ExecutionStore(
21743
- join9(config.dataDirectory, "execution.sqlite"),
21902
+ join10(config.dataDirectory, "execution.sqlite"),
21744
21903
  {
21745
21904
  orgId: config.orgId,
21746
21905
  runnerId: config.runnerId,
@@ -21829,17 +21988,17 @@ async function runConfiguredRunners(paths, abort, { whenAllDisconnected } = {})
21829
21988
  }
21830
21989
 
21831
21990
  // ../../modules/runtime/src/identities.ts
21832
- var runnerConfigDirectory = () => join10(homedir5(), ".config", "drisp");
21833
- var teamIdentityPath = (hub, orgId, directory = runnerConfigDirectory()) => join10(directory, "runners", encodeURIComponent(hub.host), `${encodeURIComponent(orgId)}.json`);
21991
+ var runnerConfigDirectory = () => join11(homedir5(), ".config", "drisp");
21992
+ var teamIdentityPath = (hub, orgId, directory = runnerConfigDirectory()) => join11(directory, "runners", encodeURIComponent(hub.host), `${encodeURIComponent(orgId)}.json`);
21834
21993
  function identityHubOrigin({ endpoint }) {
21835
21994
  const url = new URL(endpoint);
21836
21995
  url.protocol = url.protocol === "wss:" ? "https:" : "http:";
21837
21996
  return url.origin;
21838
21997
  }
21839
- var legacyIdentityPath = (directory) => join10(directory, "runner-v2.json");
21998
+ var legacyIdentityPath = (directory) => join11(directory, "runner-v2.json");
21840
21999
  var overriddenIdentityPath = () => process.env.DRISP_RUNNER_CONFIG;
21841
22000
  async function machineInstallationId(directory = runnerConfigDirectory()) {
21842
- const path23 = join10(directory, "installation-id");
22001
+ const path23 = join11(directory, "installation-id");
21843
22002
  const existing = await readFile5(path23, "utf8").then((text) => text.trim(), () => "");
21844
22003
  if (existing) return existing;
21845
22004
  let installationId = crypto.randomUUID();
@@ -21859,13 +22018,13 @@ async function machineInstallationId(directory = runnerConfigDirectory()) {
21859
22018
  }
21860
22019
  async function runnerIdentities(directory = runnerConfigDirectory()) {
21861
22020
  const override = overriddenIdentityPath();
21862
- const runners = join10(directory, "runners");
21863
- const identityFiles = async (folder) => (await readdir3(folder).catch(() => [])).filter((name) => name.endsWith(".json")).sort().map((name) => join10(folder, name));
22021
+ const runners = join11(directory, "runners");
22022
+ const identityFiles = async (folder) => (await readdir3(folder).catch(() => [])).filter((name) => name.endsWith(".json")).sort().map((name) => join11(folder, name));
21864
22023
  const hubs = (await readdir3(runners, { withFileTypes: true }).catch(() => [])).filter((entry) => entry.isDirectory()).map((entry) => entry.name).sort();
21865
22024
  const paths = override ? [expandHome(override)] : [
21866
22025
  legacyIdentityPath(directory),
21867
22026
  ...await identityFiles(runners),
21868
- ...(await Promise.all(hubs.map((hub) => identityFiles(join10(runners, hub))))).flat()
22027
+ ...(await Promise.all(hubs.map((hub) => identityFiles(join11(runners, hub))))).flat()
21869
22028
  ];
21870
22029
  const present = paths.filter((path23) => existsSync4(path23));
21871
22030
  return Promise.all(present.map(async (path23) => ({ path: path23, config: await readRunnerConfig(path23) })));
@@ -22045,4 +22204,4 @@ export {
22045
22204
  runMachineRunners,
22046
22205
  writeIdentityOnce
22047
22206
  };
22048
- //# sourceMappingURL=chunk-D246FR4I.js.map
22207
+ //# sourceMappingURL=chunk-TWOJJ2JD.js.map
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  runMachineRunners
3
- } from "./chunk-D246FR4I.js";
3
+ } from "./chunk-TWOJJ2JD.js";
4
4
 
5
5
  // src/app/entry/runnerDaemon.ts
6
6
  if (process.argv.includes("--help")) {
@@ -13,4 +13,4 @@ if (process.argv.includes("--help")) {
13
13
  process.exitCode = 1;
14
14
  });
15
15
  }
16
- //# sourceMappingURL=chunk-D5VZT7M3.js.map
16
+ //# sourceMappingURL=chunk-Z5KVWWZU.js.map