@rallycry/conveyor-agent 10.13.11 → 10.13.13

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.
@@ -2354,6 +2354,11 @@ var AskUserQuestionRequestSchema = z3.object({
2354
2354
  requestId: z3.string().min(1),
2355
2355
  questions: z3.array(AgentQuestionSchema).min(1)
2356
2356
  });
2357
+ var PostAgentMessageRequestSchema = z3.object({
2358
+ sessionId: z3.string().min(1),
2359
+ content: z3.string(),
2360
+ milestone: z3.enum(["plan_ready", "implementation_complete", "blocked"]).optional()
2361
+ });
2357
2362
  var EmitAgentEventRequestSchema = z3.object({
2358
2363
  sessionId: z3.string(),
2359
2364
  events: z3.array(AgentEventSchema).max(500)
@@ -2602,6 +2607,17 @@ var QueryProjectGcpLogsRequestSchema = z4.object({
2602
2607
  limit: z4.number().int().min(1).max(200).optional().default(50),
2603
2608
  pageToken: z4.string().max(4096).optional()
2604
2609
  });
2610
+ var QueryProjectGrafanaLogsRequestSchema = z4.object({
2611
+ projectId: z4.string(),
2612
+ env: z4.enum(["prod", "dev"]).optional(),
2613
+ services: z4.array(z4.string().min(1).max(200)).max(25).optional(),
2614
+ level: z4.enum(["debug", "info", "warn", "error", "fatal"]).optional(),
2615
+ search: z4.string().max(256).optional(),
2616
+ logql: z4.string().max(2e3).optional(),
2617
+ startTime: z4.string().optional(),
2618
+ endTime: z4.string().optional(),
2619
+ limit: z4.number().int().min(1).max(200).optional().default(50)
2620
+ });
2605
2621
  var StartProjectBuildRequestSchema = z4.object({
2606
2622
  projectId: z4.string(),
2607
2623
  taskId: z4.string(),
@@ -2646,6 +2662,13 @@ var StartAdhocSessionRequestSchema = z4.object({
2646
2662
  mode: z4.enum(["adhoc", "pm"]).optional(),
2647
2663
  /** Base branch to check out (defaults to the project's dev branch). */
2648
2664
  branch: z4.string().max(300).optional(),
2665
+ /**
2666
+ * Server-assembled instructions the pod's TUI auto-submits once on first boot
2667
+ * (headless kickoff). Used by the onboarding "Set it up for me" flow to seed a
2668
+ * setup-driver prompt; the session stays watchable/interactive in the Sessions
2669
+ * view. `ensureAdhocWorkspace` persists it and clears it after first submit.
2670
+ */
2671
+ initialPrompt: z4.string().max(2e4).optional(),
2649
2672
  requestingUserId: z4.string().optional()
2650
2673
  });
2651
2674
  var StopAdhocSessionRequestSchema = z4.object({
@@ -4449,6 +4472,22 @@ async function readRaw(path3) {
4449
4472
  return null;
4450
4473
  }
4451
4474
  }
4475
+ function classifyTuiAuth(input) {
4476
+ if (!input.isCloud) return "ready";
4477
+ if (input.hasOauthToken || input.hasApiKey || input.credsHasAccessToken) return "ready";
4478
+ return "no-credential";
4479
+ }
4480
+ async function resolveTuiAuthReadiness(env = process.env, readIdentity = readCredentialsIdentity) {
4481
+ const isCloud = isConveyorCloudEnv(env);
4482
+ const credsHasAccessToken = isCloud ? Boolean((await readIdentity())?.accessToken) : false;
4483
+ const status = classifyTuiAuth({
4484
+ isCloud,
4485
+ hasOauthToken: Boolean(env.CLAUDE_CODE_OAUTH_TOKEN),
4486
+ hasApiKey: Boolean(env.ANTHROPIC_API_KEY),
4487
+ credsHasAccessToken
4488
+ });
4489
+ return { ready: status === "ready", status };
4490
+ }
4452
4491
  async function readCredentialsIdentity() {
4453
4492
  const parsed = parseClaudeAiOauth(await readRaw(claudeCredentialsPath()));
4454
4493
  if (!parsed) return null;
@@ -5133,6 +5172,39 @@ var PtySession = class {
5133
5172
  writeStdin(text) {
5134
5173
  this.pty?.write(text);
5135
5174
  }
5175
+ /**
5176
+ * Inject a follow-up message into the CURRENTLY-RUNNING turn by pasting it into
5177
+ * the live TUI input, exactly as a human typing mid-turn would — the CLI queues
5178
+ * it and picks it up at the next turn boundary. Unlike beginTurn this does NOT
5179
+ * reset per-turn state, allocate a new queue, or re-arm the abort listener: the
5180
+ * in-flight turn (and its transcript stream) keeps flowing, so the injected
5181
+ * message and its response ride the SAME event pipeline. Returns false when
5182
+ * there is no live, actively-draining turn to inject into — parked/idle
5183
+ * (activeQueue === null), torn down, exited, or a raw-terminal TUI that gives
5184
+ * us no trusted signal that a turn is running — so the caller falls back to the
5185
+ * abort+respawn supersede path.
5186
+ */
5187
+ injectIntoRunningTurn(text) {
5188
+ if (!this.pty || this._toreDown || this.exited) return false;
5189
+ if (this.activeQueue === null) return false;
5190
+ if (!this.adapter.capabilities.structuredEvents) return false;
5191
+ if (!text.trim()) return false;
5192
+ void this.submitLivePrompt(text);
5193
+ return true;
5194
+ }
5195
+ /**
5196
+ * Paste + submit a prompt into the live pty WITHOUT any turn bookkeeping.
5197
+ * Mirrors deliverPrompt's submit path (bracketed paste, then a separate Enter
5198
+ * after a settle window) but never arms the submit nudge — the running turn is
5199
+ * already producing transcript records, so re-pressing Enter would risk
5200
+ * accepting an unrelated mid-turn dialog. Fire-and-forget.
5201
+ */
5202
+ async submitLivePrompt(text) {
5203
+ this.writeStdin(this.adapter.encodePromptBytes(text));
5204
+ await sleep(resolveSubmitSettleMs());
5205
+ if (this._toreDown || this.exited) return;
5206
+ this.writeStdin("\r");
5207
+ }
5136
5208
  /** Apply a relayed resize to the live pty (reconciled dims from the server). */
5137
5209
  resizePty(cols, rows) {
5138
5210
  if (cols <= 0 || rows <= 0) return;
@@ -5544,6 +5616,9 @@ var PtyHarness = class _PtyHarness {
5544
5616
  endedTimer = null;
5545
5617
  /** Passive-activity subscriber, re-attached to whichever session is parked. */
5546
5618
  passiveHandler = null;
5619
+ /** Once-per-session guard so the "no Claude credential" notice isn't re-posted
5620
+ * on every respawn (a fresh spawn happens on each fingerprint/lineage flip). */
5621
+ authNoticeSent = false;
5547
5622
  /**
5548
5623
  * Wiggle the live pty's size so the CLI repaints its whole screen. No-op on
5549
5624
  * the SDK harness. Falls back to the parked session so an API reconnect while
@@ -5552,6 +5627,30 @@ var PtyHarness = class _PtyHarness {
5552
5627
  forceRepaint() {
5553
5628
  (this.activeSession ?? this.parked)?.forceRepaint();
5554
5629
  }
5630
+ /** Actionable message posted to the card when a spawn will park at the Claude
5631
+ * sign-in screen. Kept as a constant so the harness stays free of i18n deps. */
5632
+ static AUTH_NOT_READY_MESSAGE = "\u26A0\uFE0F This pod started the Claude Code TUI with no Claude credential, so it is parked on the sign-in screen and can't make progress. This usually means there is no usable Claude subscription token or API key configured for this project/assignee. Add or repair the Claude credential in project settings, then restart the session.";
5633
+ /**
5634
+ * Best-effort: if the TUI is about to spawn with no usable credential, post a
5635
+ * one-time diagnostic through the relay bridge. Never throws — a readiness
5636
+ * probe must not block or fail a spawn.
5637
+ */
5638
+ async warnIfAuthNotReady() {
5639
+ if (this.authNoticeSent || !this.bridge?.notifyAuthNotReady) return;
5640
+ try {
5641
+ const readiness = await resolveTuiAuthReadiness();
5642
+ if (readiness.ready) return;
5643
+ this.authNoticeSent = true;
5644
+ this.bridge.notifyAuthNotReady(_PtyHarness.AUTH_NOT_READY_MESSAGE);
5645
+ _PtyHarness.log.warn(
5646
+ "Claude TUI spawning with no usable credential \u2014 parked at sign-in screen"
5647
+ );
5648
+ } catch (err) {
5649
+ _PtyHarness.log.warn("auth-readiness probe failed", {
5650
+ error: err instanceof Error ? err.message : String(err)
5651
+ });
5652
+ }
5653
+ }
5555
5654
  async *executeQuery(opts) {
5556
5655
  const want = opts.resume ?? opts.options.resume;
5557
5656
  const fingerprint = this.fingerprintOf(opts.options);
@@ -5573,6 +5672,9 @@ var PtyHarness = class _PtyHarness {
5573
5672
  await ensureUsableClaudeConfigHome(opts.options.cwd, _PtyHarness.log);
5574
5673
  }
5575
5674
  await this.adapter.prepareEnvironment({ cwd: opts.options.cwd });
5675
+ if (this.adapter.capabilities.structuredEvents) {
5676
+ await this.warnIfAuthNotReady();
5677
+ }
5576
5678
  session.onExit(() => this.handleSessionExit(session));
5577
5679
  await session.start();
5578
5680
  }
@@ -5583,6 +5685,15 @@ var PtyHarness = class _PtyHarness {
5583
5685
  * query running" (a human typed into the idle Connected-TUI). Attaches to the
5584
5686
  * currently-parked session and to any session parked later.
5585
5687
  */
5688
+ /**
5689
+ * PTY-only: inject a follow-up message into the turn currently streaming
5690
+ * events (the active session), so the runner can add to a running turn without
5691
+ * aborting + respawning. Returns false when no turn is active (idle/parked) or
5692
+ * the paste couldn't be delivered — the caller supersedes instead.
5693
+ */
5694
+ injectIntoRunningTurn(text) {
5695
+ return this.activeSession?.injectIntoRunningTurn(text) ?? false;
5696
+ }
5586
5697
  onPassiveActivity(handler) {
5587
5698
  this.passiveHandler = handler;
5588
5699
  const unsubParked = this.parked?.onPassiveActivity(handler);
@@ -6362,6 +6473,18 @@ function buildPlanDocumentationSection(context) {
6362
6473
  `- Identification auto-fills title, story points, and icon with quick AI guesses. After exploring, refine the title and story points with update_task_properties if they look like placeholders. Icons are automatic \u2014 never set them.`
6363
6474
  ];
6364
6475
  }
6476
+ function buildNoPrWhenNoCodeSection(baseBranch) {
6477
+ const base = baseBranch ?? "dev";
6478
+ return [
6479
+ ``,
6480
+ `### A PR is NOT required \u2014 only open one for actual code changes`,
6481
+ `\`create_pull_request\` is for tasks that change code in the repo. Many tasks don't: support requests, config/credential help, answering a question, investigations, or research whose deliverable is an answer or a file rather than a diff.`,
6482
+ `- If you finish the work with NO code changes (an empty \`git diff ${base}..HEAD\`), do NOT open a PR. An empty or throwaway PR just to "complete" the workflow is wrong \u2014 a human then has to close it.`,
6483
+ `- Deliver the result where it belongs: post the answer/config/findings with \`post_to_chat\`, and attach any files the user should keep with \`upload_attachment\`.`,
6484
+ `- Then complete the card directly with \`force_update_task_status("Complete")\` \u2014 there is no PR or review step for a no-code task.`,
6485
+ `- When in doubt, check \`git diff ${base}..HEAD\`: a real diff means open a PR; no diff means finish in chat and mark Complete.`
6486
+ ];
6487
+ }
6365
6488
  function buildExplorationMethodology() {
6366
6489
  return [
6367
6490
  ``,
@@ -6484,7 +6607,7 @@ function buildAutoPrompt(context, runnerMode) {
6484
6607
  `If no children exist yet, break the work down now: save a parent-level plan with update_task_plan, then create child tasks with create_subtask (each with a detailed plan).`,
6485
6608
  `Child task status lifecycle: Open \u2192 InProgress \u2192 ReviewPR \u2192 ReviewDev \u2192 Complete.`,
6486
6609
  `Set child ordering with \`dependsOn\` (sibling ids/slugs) on \`create_subtask\` \u2014 explicit metadata the pack runner schedules off, not order described in plan text. Independent children get none and run in parallel.`
6487
- ] : [],
6610
+ ] : buildNoPrWhenNoCodeSection(context?.baseBranch),
6488
6611
  ``,
6489
6612
  `### Autonomous Guidelines:`,
6490
6613
  `- Make decisions independently \u2014 do not ask the team for approval at each step`,
@@ -6494,37 +6617,40 @@ function buildAutoPrompt(context, runnerMode) {
6494
6617
  if (context) parts.push(...buildPropertyInstructions(context, runnerMode));
6495
6618
  return parts.join("\n");
6496
6619
  }
6620
+ function buildBuildingPrompt(context) {
6621
+ const parts = [
6622
+ `
6623
+ ## Mode: Building`,
6624
+ `You are in Building mode \u2014 executing the plan.`,
6625
+ `- You have full coding access (read, write, edit, bash, git)`,
6626
+ `- Safety rules: no destructive operations, use --force-with-lease instead of --force`,
6627
+ ...context?.isParentTask ? [
6628
+ `- You are a parent task. Use \`list_subtasks\`, \`start_child_cloud_build\`, and subtask management tools to coordinate children.`,
6629
+ `- Do NOT implement code directly \u2014 fire child builds and review their work.`,
6630
+ `- Goal: coordinate child task execution and ensure all children complete successfully`
6631
+ ] : [
6632
+ `- If this is a leaf task (no children): execute the plan directly`,
6633
+ `- Goal: implement the plan, run scoped verification, open a PR when done`,
6634
+ ``,
6635
+ `### Pre-PR Verification Checklist`,
6636
+ `CI runs the FULL suite (lint, typecheck, all test shards) on every PR \u2014 do not duplicate it locally. Before calling \`mcp__conveyor__create_pull_request\`, scope verification to your diff:`,
6637
+ `1. \`bun run check\` \u2014 lint + typecheck (fast; run whenever you changed code)`,
6638
+ `2. \`bun run test:affected\` \u2014 runs only the tests your diff can affect (docs-only diffs run nothing; apps/api diffs run unit tests only since CI covers the int shards; shared/db diffs escalate to the full suite automatically)`,
6639
+ `Docs/markdown/.claude-only changes need NO local gates \u2014 open the PR and let CI validate.`,
6640
+ `If a gate fails, fix it before opening the PR. Do NOT open PRs with known failing gates. Never run the full \`bun run test\` for a diff confined to one package.`,
6641
+ `For refactors: also run \`git diff ${context?.baseBranch ?? "dev"}..HEAD\` and confirm the public API surface (exports, function signatures) has no unintended breaking changes.`,
6642
+ ...buildNoPrWhenNoCodeSection(context?.baseBranch),
6643
+ ...context?.isAuto || !context?.plan?.trim() ? buildPlanDocumentationSection(context) : []
6644
+ ]
6645
+ ];
6646
+ return parts.join("\n");
6647
+ }
6497
6648
  function buildModePrompt(agentMode, context, runnerMode) {
6498
6649
  switch (agentMode) {
6499
6650
  case "discovery":
6500
6651
  return buildDiscoveryPrompt(context, runnerMode);
6501
- case "building": {
6502
- const parts = [
6503
- `
6504
- ## Mode: Building`,
6505
- `You are in Building mode \u2014 executing the plan.`,
6506
- `- You have full coding access (read, write, edit, bash, git)`,
6507
- `- Safety rules: no destructive operations, use --force-with-lease instead of --force`,
6508
- ...context?.isParentTask ? [
6509
- `- You are a parent task. Use \`list_subtasks\`, \`start_child_cloud_build\`, and subtask management tools to coordinate children.`,
6510
- `- Do NOT implement code directly \u2014 fire child builds and review their work.`,
6511
- `- Goal: coordinate child task execution and ensure all children complete successfully`
6512
- ] : [
6513
- `- If this is a leaf task (no children): execute the plan directly`,
6514
- `- Goal: implement the plan, run scoped verification, open a PR when done`,
6515
- ``,
6516
- `### Pre-PR Verification Checklist`,
6517
- `CI runs the FULL suite (lint, typecheck, all test shards) on every PR \u2014 do not duplicate it locally. Before calling \`mcp__conveyor__create_pull_request\`, scope verification to your diff:`,
6518
- `1. \`bun run check\` \u2014 lint + typecheck (fast; run whenever you changed code)`,
6519
- `2. \`bun run test:affected\` \u2014 runs only the tests your diff can affect (docs-only diffs run nothing; apps/api diffs run unit tests only since CI covers the int shards; shared/db diffs escalate to the full suite automatically)`,
6520
- `Docs/markdown/.claude-only changes need NO local gates \u2014 open the PR and let CI validate.`,
6521
- `If a gate fails, fix it before opening the PR. Do NOT open PRs with known failing gates. Never run the full \`bun run test\` for a diff confined to one package.`,
6522
- `For refactors: also run \`git diff ${context?.baseBranch ?? "dev"}..HEAD\` and confirm the public API surface (exports, function signatures) has no unintended breaking changes.`,
6523
- ...context?.isAuto || !context?.plan?.trim() ? buildPlanDocumentationSection(context) : []
6524
- ]
6525
- ];
6526
- return parts.join("\n");
6527
- }
6652
+ case "building":
6653
+ return buildBuildingPrompt(context);
6528
6654
  case "review":
6529
6655
  return buildReviewPrompt(context);
6530
6656
  case "auto":
@@ -9643,7 +9769,7 @@ async function runSdkQuery(host, context, followUpContent, promptDeliveryOverrid
9643
9769
  await runFollowUpQuery(host, context, options, resume, followUpContent);
9644
9770
  return;
9645
9771
  }
9646
- if (isDiscoveryLike && promptDelivery !== "prefill") {
9772
+ if (isDiscoveryLike && (resume || host.harnessKind !== "pty")) {
9647
9773
  return;
9648
9774
  }
9649
9775
  await runInitialQuery(host, context, options, resume, promptDelivery);
@@ -9986,6 +10112,7 @@ function buildPtyBridge(connection) {
9986
10112
  sendOutput: (data, dims) => connection.sendPtyOutput(data, dims),
9987
10113
  sendChatEvent: (event) => connection.sendPtyChatEvent(event),
9988
10114
  sendEnded: () => connection.sendPtyEnded(),
10115
+ notifyAuthNotReady: (detail) => connection.postChatMessage(detail),
9989
10116
  onInput: (handler) => connection.onPtyInput(handler),
9990
10117
  onResize: (handler) => connection.onPtyResize(handler)
9991
10118
  };
@@ -10056,6 +10183,16 @@ var QueryBridge = class {
10056
10183
  resume() {
10057
10184
  this._stopped = false;
10058
10185
  }
10186
+ /**
10187
+ * Inject a follow-up message into the turn currently running under the harness
10188
+ * (PTY keep-alive) instead of aborting it. Returns true when the harness fed
10189
+ * the message into the live TUI; false when there is no running turn to inject
10190
+ * into or the harness has no live terminal (SDK) — the caller then supersedes
10191
+ * via stop() + respawn.
10192
+ */
10193
+ injectIntoRunningTurn(content) {
10194
+ return this.harness.injectIntoRunningTurn?.(content) ?? false;
10195
+ }
10059
10196
  /**
10060
10197
  * Tear down any parked/active CLI process the harness is keeping alive between
10061
10198
  * turns (PTY keep-alive). Called by SessionRunner on stop/shutdown so the
@@ -11411,13 +11548,36 @@ var SessionRunner = class _SessionRunner {
11411
11548
  const resolve = this.inputResolver;
11412
11549
  this.inputResolver = null;
11413
11550
  resolve(msg);
11414
- } else {
11415
- this.pendingMessages.push(msg);
11416
- if (this._state === "running" || this._state === "waiting_for_input") {
11417
- this.queryBridge?.stop();
11418
- }
11551
+ return;
11552
+ }
11553
+ if (this._state === "running" && this.canInjectIntoRunningTurn(msg) && this.queryBridge?.injectIntoRunningTurn(msg.content)) {
11554
+ void this.callbacks.onEvent({
11555
+ type: "user_message",
11556
+ content: msg.content,
11557
+ userId: msg.userId
11558
+ });
11559
+ return;
11560
+ }
11561
+ this.pendingMessages.push(msg);
11562
+ if (this._state === "running" || this._state === "waiting_for_input") {
11563
+ this.queryBridge?.stop();
11419
11564
  }
11420
11565
  }
11566
+ /**
11567
+ * Whether a mid-turn message may be pasted into the live running TUI rather
11568
+ * than superseding the turn. Restricted to genuine same-mode user follow-ups:
11569
+ * a pending mode restart, an empty body, a prefill hint, or any non-"user"
11570
+ * source (mode_change / pty_passive / system / ci_failure / review_trigger)
11571
+ * must take the abort+respawn path — a mode/fingerprint change needs a fresh
11572
+ * spawn, and a prefill must park unsubmitted for the human.
11573
+ */
11574
+ canInjectIntoRunningTurn(msg) {
11575
+ if (this.mode.pendingModeRestart) return false;
11576
+ if (!msg.content.trim()) return false;
11577
+ if (msg.delivery === "prefill") return false;
11578
+ if (msg.source && msg.source !== "user") return false;
11579
+ return true;
11580
+ }
11421
11581
  // ── Query execution with abort handling ────────────────────────────
11422
11582
  /** Run queryBridge.execute, swallowing abort errors from stop/softStop. */
11423
11583
  async executeQuery(followUpContent, promptDelivery) {
@@ -11934,4 +12094,4 @@ export {
11934
12094
  loadConveyorConfig,
11935
12095
  unshallowRepo
11936
12096
  };
11937
- //# sourceMappingURL=chunk-DJPSNHVJ.js.map
12097
+ //# sourceMappingURL=chunk-TB5SQIGX.js.map