agent-relay-server 0.104.5 → 0.105.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.
- package/docs/openapi.json +141 -1
- package/package.json +2 -2
- package/public/assets/MessageBubble-CHor4Sxp.js +4 -0
- package/public/assets/{MessageBubble-BpiTbbnp.js.map → MessageBubble-CHor4Sxp.js.map} +1 -1
- package/public/assets/{PlanGraphPanel-k8Aa98g5.js → PlanGraphPanel-jHfkQBX6.js} +2 -2
- package/public/assets/{PlanGraphPanel-k8Aa98g5.js.map → PlanGraphPanel-jHfkQBX6.js.map} +1 -1
- package/public/assets/{activity-CxKi5Erb.js → activity-DDXS6LsX.js} +2 -2
- package/public/assets/{activity-CxKi5Erb.js.map → activity-DDXS6LsX.js.map} +1 -1
- package/public/assets/{agent-profiles-DMZXdN6K.js → agent-profiles-Cn8lCTkg.js} +2 -2
- package/public/assets/{agent-profiles-DMZXdN6K.js.map → agent-profiles-Cn8lCTkg.js.map} +1 -1
- package/public/assets/agents-DBTdcFFz.js +2 -0
- package/public/assets/{agents-BrvpH3gn.js.map → agents-DBTdcFFz.js.map} +1 -1
- package/public/assets/{analytics-1fvh-9ok.js → analytics-VximqXQ9.js} +3 -3
- package/public/assets/{analytics-1fvh-9ok.js.map → analytics-VximqXQ9.js.map} +1 -1
- package/public/assets/{automation-BCgX5WOH.js → automation-L9wq4y5F.js} +2 -2
- package/public/assets/{automation-BCgX5WOH.js.map → automation-L9wq4y5F.js.map} +1 -1
- package/public/assets/{badge-BLar6FjP.js → badge-D8fABzMs.js} +2 -2
- package/public/assets/{badge-BLar6FjP.js.map → badge-D8fABzMs.js.map} +1 -1
- package/public/assets/{branch-state-badge-DYA7bU0i.js → branch-state-badge-CcLZ_u86.js} +2 -2
- package/public/assets/{branch-state-badge-DYA7bU0i.js.map → branch-state-badge-CcLZ_u86.js.map} +1 -1
- package/public/assets/{button-BrIB69qd.js → button-KASZcscA.js} +2 -2
- package/public/assets/{button-BrIB69qd.js.map → button-KASZcscA.js.map} +1 -1
- package/public/assets/card-Cds0MWME.js +2 -0
- package/public/assets/{card-lhnFnBoz.js.map → card-Cds0MWME.js.map} +1 -1
- package/public/assets/{channels-CK80oJYG.js → channels-CcSnLzCG.js} +2 -2
- package/public/assets/{channels-CK80oJYG.js.map → channels-CcSnLzCG.js.map} +1 -1
- package/public/assets/{chat-D_2PEz06.js → chat-BzMj_PO6.js} +2 -2
- package/public/assets/{chat-D_2PEz06.js.map → chat-BzMj_PO6.js.map} +1 -1
- package/public/assets/{connectors-ChGyht5m.js → connectors-DbPOlQhL.js} +2 -2
- package/public/assets/{connectors-ChGyht5m.js.map → connectors-DbPOlQhL.js.map} +1 -1
- package/public/assets/copy-button-d9DFNX9v.js +2 -0
- package/public/assets/{copy-button-Cd-LbSbg.js.map → copy-button-d9DFNX9v.js.map} +1 -1
- package/public/assets/{display-D1xB8NJZ.js → display-BWi8DQCp.js} +2 -2
- package/public/assets/display-BWi8DQCp.js.map +1 -0
- package/public/assets/{dist-BnbGIUmi.js → dist-BbUJ1Vht.js} +2 -2
- package/public/assets/{dist-BnbGIUmi.js.map → dist-BbUJ1Vht.js.map} +1 -1
- package/public/assets/{dist-Bp10H3oR.js → dist-BlZvUZZB.js} +2 -2
- package/public/assets/{dist-Bp10H3oR.js.map → dist-BlZvUZZB.js.map} +1 -1
- package/public/assets/{dist-DDUGmmoi.js → dist-BwwlmyBq.js} +2 -2
- package/public/assets/{dist-DDUGmmoi.js.map → dist-BwwlmyBq.js.map} +1 -1
- package/public/assets/dist-CBVZk9U8.js +2 -0
- package/public/assets/{dist-BEzpMqLy.js.map → dist-CBVZk9U8.js.map} +1 -1
- package/public/assets/{dist-B5VvlkhI.js → dist-CgqfdHSt.js} +2 -2
- package/public/assets/{dist-B5VvlkhI.js.map → dist-CgqfdHSt.js.map} +1 -1
- package/public/assets/dist-DC-TqTz2.js +2 -0
- package/public/assets/{dist-30weaXto.js.map → dist-DC-TqTz2.js.map} +1 -1
- package/public/assets/{dist-DZ97OosY.js → dist-DOAjFOS4.js} +2 -2
- package/public/assets/{dist-DZ97OosY.js.map → dist-DOAjFOS4.js.map} +1 -1
- package/public/assets/{dist-BjOBkHHY.js → dist-DTXKbk2K.js} +2 -2
- package/public/assets/{dist-BjOBkHHY.js.map → dist-DTXKbk2K.js.map} +1 -1
- package/public/assets/dist-DreO5AcZ.js +2 -0
- package/public/assets/{dist-Cgy0FmP-.js.map → dist-DreO5AcZ.js.map} +1 -1
- package/public/assets/{dist-CQF3Jiqg.js → dist-DybScJmm.js} +2 -2
- package/public/assets/{dist-CQF3Jiqg.js.map → dist-DybScJmm.js.map} +1 -1
- package/public/assets/{dist-DAl28ejX.js → dist-UhEAFdvZ.js} +2 -2
- package/public/assets/{dist-DAl28ejX.js.map → dist-UhEAFdvZ.js.map} +1 -1
- package/public/assets/{es2015-B8Z9p8oQ.js → es2015-DUjFyjDp.js} +2 -2
- package/public/assets/{es2015-B8Z9p8oQ.js.map → es2015-DUjFyjDp.js.map} +1 -1
- package/public/assets/{formatted-body-impl-BJ4WCF5J.js → formatted-body-impl-CFWHLkCY.js} +2 -2
- package/public/assets/{formatted-body-impl-BJ4WCF5J.js.map → formatted-body-impl-CFWHLkCY.js.map} +1 -1
- package/public/assets/index-BjjzI2LT.css +2 -0
- package/public/assets/{index-CN7QZlMb.js → index-aCfZQ7LY.js} +13 -13
- package/public/assets/index-aCfZQ7LY.js.map +1 -0
- package/public/assets/{input-B_fUHtLD.js → input-CtHfLn1i.js} +2 -2
- package/public/assets/{input-B_fUHtLD.js.map → input-CtHfLn1i.js.map} +1 -1
- package/public/assets/{insights-BCZRV0hX.js → insights-BuPFE0tf.js} +2 -2
- package/public/assets/{insights-BCZRV0hX.js.map → insights-BuPFE0tf.js.map} +1 -1
- package/public/assets/{integrations-C7UGs00U.js → integrations-hkSW8CzM.js} +2 -2
- package/public/assets/{integrations-C7UGs00U.js.map → integrations-hkSW8CzM.js.map} +1 -1
- package/public/assets/{lib-ng6WZYjE.js → lib-l-JkMVR9.js} +2 -2
- package/public/assets/{lib-ng6WZYjE.js.map → lib-l-JkMVR9.js.map} +1 -1
- package/public/assets/{lucide-react-BYZuAhQs.js → lucide-react-C4eXYCwx.js} +2 -2
- package/public/assets/{lucide-react-BYZuAhQs.js.map → lucide-react-C4eXYCwx.js.map} +1 -1
- package/public/assets/{maintenance-ChYno3Fm.js → maintenance-wYwJ7w6h.js} +2 -2
- package/public/assets/{maintenance-ChYno3Fm.js.map → maintenance-wYwJ7w6h.js.map} +1 -1
- package/public/assets/{managed-agents-DjxZQNIR.js → managed-agents-CKaYD93I.js} +4 -4
- package/public/assets/{managed-agents-DjxZQNIR.js.map → managed-agents-CKaYD93I.js.map} +1 -1
- package/public/assets/{markdown-preview-impl-DFa5HF1H.js → markdown-preview-impl-bf4eDQUM.js} +2 -2
- package/public/assets/{markdown-preview-impl-DFa5HF1H.js.map → markdown-preview-impl-bf4eDQUM.js.map} +1 -1
- package/public/assets/memory-DIneEza9.js +2 -0
- package/public/assets/{memory-CTw6kadT.js.map → memory-DIneEza9.js.map} +1 -1
- package/public/assets/{messages-Cjr816D_.js → messages-DP9Vv_wh.js} +2 -2
- package/public/assets/{messages-Cjr816D_.js.map → messages-DP9Vv_wh.js.map} +1 -1
- package/public/assets/{orchestrators-CdmFKA7K.js → orchestrators-CAnKjxdO.js} +2 -2
- package/public/assets/{orchestrators-CdmFKA7K.js.map → orchestrators-CAnKjxdO.js.map} +1 -1
- package/public/assets/{overview-DBOnjfpP.js → overview-B98U3C-y.js} +2 -2
- package/public/assets/{overview-DBOnjfpP.js.map → overview-B98U3C-y.js.map} +1 -1
- package/public/assets/{pairs-BkcdKdF7.js → pairs-DVeeuxhY.js} +2 -2
- package/public/assets/{pairs-BkcdKdF7.js.map → pairs-DVeeuxhY.js.map} +1 -1
- package/public/assets/{projects-ClKbDQB1.js → projects-vt63bwHN.js} +2 -2
- package/public/assets/{projects-ClKbDQB1.js.map → projects-vt63bwHN.js.map} +1 -1
- package/public/assets/prompt-settings-Df-0ZMJ5.js +2 -0
- package/public/assets/prompt-settings-Df-0ZMJ5.js.map +1 -0
- package/public/assets/{react-dom-Dbhs84ug.js → react-dom-BMF4hNzG.js} +2 -2
- package/public/assets/{react-dom-Dbhs84ug.js.map → react-dom-BMF4hNzG.js.map} +1 -1
- package/public/assets/{registry-Bsf3RtOO.js → registry-DlLZyW7_.js} +2 -2
- package/public/assets/{registry-Bsf3RtOO.js.map → registry-DlLZyW7_.js.map} +1 -1
- package/public/assets/{security-Iyu5bhJw.js → security-Bo4Ty3lz.js} +2 -2
- package/public/assets/{security-Iyu5bhJw.js.map → security-Bo4Ty3lz.js.map} +1 -1
- package/public/assets/{select-Bi6tNJDx.js → select-BguZ80M8.js} +2 -2
- package/public/assets/{select-Bi6tNJDx.js.map → select-BguZ80M8.js.map} +1 -1
- package/public/assets/settings-CpX9Xw2j.js +6 -0
- package/public/assets/{settings-CbHp2F9r.js.map → settings-CpX9Xw2j.js.map} +1 -1
- package/public/assets/{store-zeyDiSKE.js → store-DUfrGvOE.js} +3 -3
- package/public/assets/{store-zeyDiSKE.js.map → store-DUfrGvOE.js.map} +1 -1
- package/public/assets/{tasks-CPlf-5Tr.js → tasks-Cg1HXY9l.js} +2 -2
- package/public/assets/{tasks-CPlf-5Tr.js.map → tasks-Cg1HXY9l.js.map} +1 -1
- package/public/assets/{teams-D2uUNhlY.js → teams-BFcYunxB.js} +2 -2
- package/public/assets/{teams-D2uUNhlY.js.map → teams-BFcYunxB.js.map} +1 -1
- package/public/assets/{terminal-viewer-impl-uRzbrlXy.js → terminal-viewer-impl-CF2EBa2K.js} +3 -3
- package/public/assets/{terminal-viewer-impl-uRzbrlXy.js.map → terminal-viewer-impl-CF2EBa2K.js.map} +1 -1
- package/public/assets/types-DorDDvEb.js.map +1 -1
- package/public/assets/{use-keyboard-viewport-D8_NYDkh.js → use-keyboard-viewport-RYMALvu1.js} +2 -2
- package/public/assets/{use-keyboard-viewport-D8_NYDkh.js.map → use-keyboard-viewport-RYMALvu1.js.map} +1 -1
- package/public/assets/user-avatar-D1ffSClz.js +2 -0
- package/public/assets/{user-avatar-GFWMuAGK.js.map → user-avatar-D1ffSClz.js.map} +1 -1
- package/public/assets/{work-queue-B30SNmuq.js → work-queue-DV36cxjp.js} +2 -2
- package/public/assets/{work-queue-B30SNmuq.js.map → work-queue-DV36cxjp.js.map} +1 -1
- package/public/assets/workspaces-CIsQqQby.js +3 -0
- package/public/assets/workspaces-CIsQqQby.js.map +1 -0
- package/public/index.html +22 -22
- package/runner/plugins/claude/.claude-plugin/plugin.json +1 -1
- package/runner/plugins/claude/monitors/relay-monitor.provisioned.mjs +114 -23
- package/runner/plugins/claude/monitors/relay-monitor.ts +2 -2
- package/runner/src/adapter.ts +4 -1
- package/src/agent-lifecycle-events.ts +21 -5
- package/src/automations/reconcile.ts +4 -1
- package/src/branch-landed.ts +22 -4
- package/src/config-store.ts +17 -21
- package/src/context-advisory.ts +10 -3
- package/src/db/index.ts +1 -0
- package/src/db/projects.ts +29 -0
- package/src/db/prompt-templates-schema.ts +20 -0
- package/src/db/prompt-templates.ts +91 -0
- package/src/db/schema.ts +5 -4
- package/src/db/tasks.ts +2 -1
- package/src/db/workspaces.ts +41 -1
- package/src/index.ts +3 -0
- package/src/project-instructions.ts +7 -14
- package/src/prompt-resolver.ts +530 -0
- package/src/prompt-template-defaults-runner.ts +136 -0
- package/src/routes/index.ts +5 -0
- package/src/routes/prompt-templates.ts +60 -0
- package/src/routes/workspaces.ts +4 -3
- package/src/routing-policy-push.ts +4 -1
- package/src/security.ts +3 -0
- package/src/self-resume.ts +8 -15
- package/src/services/prompt-templates.ts +19 -0
- package/src/services/register-agent.ts +2 -0
- package/src/services/spawn-issue-activity.ts +107 -0
- package/src/spawn-targets.ts +3 -11
- package/src/steward.ts +5 -23
- package/src/workspace-auto-merge.ts +19 -2
- package/src/workspace-phase.ts +15 -28
- package/public/assets/MessageBubble-BpiTbbnp.js +0 -4
- package/public/assets/agents-BrvpH3gn.js +0 -2
- package/public/assets/card-lhnFnBoz.js +0 -2
- package/public/assets/copy-button-Cd-LbSbg.js +0 -2
- package/public/assets/display-D1xB8NJZ.js.map +0 -1
- package/public/assets/dist-30weaXto.js +0 -2
- package/public/assets/dist-BEzpMqLy.js +0 -2
- package/public/assets/dist-Cgy0FmP-.js +0 -2
- package/public/assets/index-BMO_Sblt.css +0 -2
- package/public/assets/index-CN7QZlMb.js.map +0 -1
- package/public/assets/memory-CTw6kadT.js +0 -2
- package/public/assets/settings-CbHp2F9r.js +0 -6
- package/public/assets/user-avatar-GFWMuAGK.js +0 -2
- package/public/assets/workspaces-CSpmgbPT.js +0 -3
- package/public/assets/workspaces-CSpmgbPT.js.map +0 -1
|
@@ -0,0 +1,530 @@
|
|
|
1
|
+
import type { SeedTemplate } from "./db/prompt-templates";
|
|
2
|
+
import { getTemplate } from "./db/prompt-templates";
|
|
3
|
+
import { RUNNER_PROMPT_TEMPLATE_DEFAULTS } from "./prompt-template-defaults-runner";
|
|
4
|
+
|
|
5
|
+
function lines(...parts: string[]): string {
|
|
6
|
+
return parts.join("\n");
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
function copySeedTemplate(template: SeedTemplate): SeedTemplate {
|
|
10
|
+
return {
|
|
11
|
+
...template,
|
|
12
|
+
variables: [...template.variables],
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const DEFAULT_PROMPT_TEMPLATES = [
|
|
17
|
+
{
|
|
18
|
+
slug: "profile.coordinator.charter",
|
|
19
|
+
category: "profile",
|
|
20
|
+
title: "Coordinator Charter",
|
|
21
|
+
description: "Built-in coordinator append instruction.",
|
|
22
|
+
template: "Coordination charter: stay at helicopter altitude; delegate implementation to spawned workers; write briefs, maintain the blackboard and plan DAG; coordinate, review, and release; do not drift into mechanical edits when a worker can do them; protect your context for coordination.",
|
|
23
|
+
defaultTemplate: "Coordination charter: stay at helicopter altitude; delegate implementation to spawned workers; write briefs, maintain the blackboard and plan DAG; coordinate, review, and release; do not drift into mechanical edits when a worker can do them; protect your context for coordination.",
|
|
24
|
+
variables: [],
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
slug: "profile.ops-assistant.brief",
|
|
28
|
+
category: "profile",
|
|
29
|
+
title: "Ops Assistant Brief",
|
|
30
|
+
description: "Built-in ops-assistant append instruction.",
|
|
31
|
+
template: lines(
|
|
32
|
+
"Ops-assistant standing brief: execute mechanical operations on your coordinator's behalf: test suites, release commands such as `bun run release`, smoke and verification probes, gates, and host/version/status checks.",
|
|
33
|
+
"When running a self-verifying long script, especially `bun run release` (gates -> CI-watch -> deploy -> host-verify, then one final result), redirect its output to a file rather than letting it stream into your context: `bun run release > /tmp/ar-release.log 2>&1`. Wait for it to exit, then read only the final result with `tail /tmp/ar-release.log`. Never run it with inline streaming output. Do not poll, monitor, tail logs, run parallel status/version checks, or otherwise babysit it while it runs. Trust the script; act only on its final result. This generalizes to any long-running command whose intermediate output you do not need.",
|
|
34
|
+
"Hold and apply session-local ops conventions the coordinator gives you. Report crisp outcomes only: command/gate, pass/fail, commit/version/host evidence, and the next blocker when one exists. Do not dump logs unless asked.",
|
|
35
|
+
"Do not make strategy, design, scope, or release-timing calls. Escalate those decisions to your spawn-parent. Report operational results to your spawn-parent by default and keep their context clean.",
|
|
36
|
+
),
|
|
37
|
+
defaultTemplate: lines(
|
|
38
|
+
"Ops-assistant standing brief: execute mechanical operations on your coordinator's behalf: test suites, release commands such as `bun run release`, smoke and verification probes, gates, and host/version/status checks.",
|
|
39
|
+
"When running a self-verifying long script, especially `bun run release` (gates -> CI-watch -> deploy -> host-verify, then one final result), redirect its output to a file rather than letting it stream into your context: `bun run release > /tmp/ar-release.log 2>&1`. Wait for it to exit, then read only the final result with `tail /tmp/ar-release.log`. Never run it with inline streaming output. Do not poll, monitor, tail logs, run parallel status/version checks, or otherwise babysit it while it runs. Trust the script; act only on its final result. This generalizes to any long-running command whose intermediate output you do not need.",
|
|
40
|
+
"Hold and apply session-local ops conventions the coordinator gives you. Report crisp outcomes only: command/gate, pass/fail, commit/version/host evidence, and the next blocker when one exists. Do not dump logs unless asked.",
|
|
41
|
+
"Do not make strategy, design, scope, or release-timing calls. Escalate those decisions to your spawn-parent. Report operational results to your spawn-parent by default and keep their context clean.",
|
|
42
|
+
),
|
|
43
|
+
variables: [],
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
slug: "profile.worker.system",
|
|
47
|
+
category: "profile",
|
|
48
|
+
title: "Worker System Prompt",
|
|
49
|
+
description: "Built-in worker system prompt. The current tree leaves this empty.",
|
|
50
|
+
template: "",
|
|
51
|
+
defaultTemplate: "",
|
|
52
|
+
variables: [],
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
slug: "spawn.reportup.child",
|
|
56
|
+
category: "spawn",
|
|
57
|
+
title: "Spawned Child Report-Up",
|
|
58
|
+
description: "Instruction appended for spawned child agents.",
|
|
59
|
+
template: lines(
|
|
60
|
+
"Agent Relay report-up:",
|
|
61
|
+
"You are a spawned child agent. Just respond normally when your turn is complete; Relay automatically delivers your final response to your coordinator. Do not call a messaging tool only to report completion.",
|
|
62
|
+
"You have no interactive human at your terminal, so do not use blocking prompts: AskUserQuestion and plan mode/ExitPlanMode will hang with no one to answer. If you need a decision, approval, or clarification, ask your coordinator via Relay and continue once they respond.",
|
|
63
|
+
),
|
|
64
|
+
defaultTemplate: lines(
|
|
65
|
+
"Agent Relay report-up:",
|
|
66
|
+
"You are a spawned child agent. Just respond normally when your turn is complete; Relay automatically delivers your final response to your coordinator. Do not call a messaging tool only to report completion.",
|
|
67
|
+
"You have no interactive human at your terminal, so do not use blocking prompts: AskUserQuestion and plan mode/ExitPlanMode will hang with no one to answer. If you need a decision, approval, or clarification, ask your coordinator via Relay and continue once they respond.",
|
|
68
|
+
),
|
|
69
|
+
variables: [],
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
slug: "spawn.reportup.coordinator",
|
|
73
|
+
category: "spawn",
|
|
74
|
+
title: "Coordinator Child Response Note",
|
|
75
|
+
description: "Instruction appended for spawn-capable coordinators.",
|
|
76
|
+
template: lines(
|
|
77
|
+
"Agent Relay child responses:",
|
|
78
|
+
"When you spawn child agents, their turn-final responses arrive automatically as Relay messages. Do not put report-up instructions or your own agent id in child briefs.",
|
|
79
|
+
),
|
|
80
|
+
defaultTemplate: lines(
|
|
81
|
+
"Agent Relay child responses:",
|
|
82
|
+
"When you spawn child agents, their turn-final responses arrive automatically as Relay messages. Do not put report-up instructions or your own agent id in child briefs.",
|
|
83
|
+
),
|
|
84
|
+
variables: [],
|
|
85
|
+
},
|
|
86
|
+
{
|
|
87
|
+
slug: "steward.prompt",
|
|
88
|
+
category: "steward",
|
|
89
|
+
title: "Steward Prompt",
|
|
90
|
+
description: "Repository steward system prompt.",
|
|
91
|
+
template: lines(
|
|
92
|
+
"You are the autonomous repository steward for {{repoRoot}}.",
|
|
93
|
+
"",
|
|
94
|
+
"Multiple agents work this repo in isolated git worktrees. The relay auto-merges any branch that rebases cleanly — including ones whose base moved on; it hands YOU only what it can't land deterministically: real merge conflicts, or an unknown/ambiguous merge state. Your job is to land that work with no human in the loop whenever you safely can.",
|
|
95
|
+
"",
|
|
96
|
+
"Each workspace belongs to a BRANCH AGENT (the owner who did the work) who in turn has a COORDINATOR (the agent that spawned it and is responsible for the merge landing). Your wake/task message names both — the `ownerAgentId` and the `coordinatorAgentId` — and `agent-relay steward inspect <id>` shows them. When you can't land work yourself, the coordinator is who you escalate to.",
|
|
97
|
+
"",
|
|
98
|
+
"Use the `agent-relay` CLI for EVERY relay interaction — it wraps the relay API and is the supported toolkit, and it already attaches your session token with the right scopes. Do NOT hand-curl the HTTP API (`/api/workspaces`, …): the CLI exists so you never have to. If you ever truly must call the API directly, authenticate with the `X-Agent-Relay-Token: <your session token>` header — NOT `Authorization: Bearer $AGENT_RELAY_TOKEN`; the admin env token is not present in your environment, so Bearer will 401.",
|
|
99
|
+
"Handle ONE workspace at a time — the relay's per-repo merge lease serializes you with any other merger.",
|
|
100
|
+
"",
|
|
101
|
+
"1. See the queue: `agent-relay steward queue` (workspaces in conflict / review_requested / merge_planned for this repo). The wake message(s) also name a `workspaceId`.",
|
|
102
|
+
"2. CLAIM it FIRST: `agent-relay workspace claim --id <id> --purpose steward`. This stops the deterministic auto-merge from racing you while you validate. The claim auto-expires, so a crash never blocks the repo.",
|
|
103
|
+
"3. Understand it: `agent-relay steward inspect <id>` — a diagnostics briefing (the branch agent owner + its coordinator, owner liveness, live git state, ahead/behind, recorded-vs-live branch mismatch, and a recommended action). `agent-relay steward checks <id>` suggests check commands from the changed files.",
|
|
104
|
+
"4. `cd` into the workspace's `worktreePath` and rebase the branch onto its `baseRef` (`git rebase <baseRef>`). Resolve conflicts faithfully — preserve the intent of EVERY side; never silently drop a change. If a conflict needs product judgment you can't make confidently, stop and escalate to the coordinator.",
|
|
105
|
+
"5. Run the repo's checks/tests (the suggested ones, plus the project's documented commands). Fix trivial breakage you caused while rebasing; do not paper over real failures.",
|
|
106
|
+
"6. If green, land it: `agent-relay workspace land --id <id> --strategy rebase-ff`. The relay rebases onto the latest base, fast-forwards, and pushes to origin under the lease. The land consumes your claim.",
|
|
107
|
+
"7. If you must stop without landing, RELEASE the claim so automation can resume: `agent-relay workspace release --id <id>`, then send a clear, specific summary to the workspace's COORDINATOR (the `coordinatorAgentId` from the wake message) — they own the work and can act on it. Reply to the wake message or message that agent id directly.",
|
|
108
|
+
"",
|
|
109
|
+
"Escalate (do NOT merge) when: checks fail and you can't fix them, the conflict resolution is genuinely ambiguous, or anything looks risky. ALWAYS escalate to the branch agent's coordinator (the `coordinatorAgentId` in the wake message). Only if the wake message names NO coordinator, escalate to {{escalationTarget}}. Never force-merge a red branch, never `git push --force` to a shared base, never discard committed work.",
|
|
110
|
+
"",
|
|
111
|
+
"Be terminal-efficient and decisive. When the queue is empty, you're done — you'll be woken again when there's more.",
|
|
112
|
+
),
|
|
113
|
+
defaultTemplate: lines(
|
|
114
|
+
"You are the autonomous repository steward for {{repoRoot}}.",
|
|
115
|
+
"",
|
|
116
|
+
"Multiple agents work this repo in isolated git worktrees. The relay auto-merges any branch that rebases cleanly — including ones whose base moved on; it hands YOU only what it can't land deterministically: real merge conflicts, or an unknown/ambiguous merge state. Your job is to land that work with no human in the loop whenever you safely can.",
|
|
117
|
+
"",
|
|
118
|
+
"Each workspace belongs to a BRANCH AGENT (the owner who did the work) who in turn has a COORDINATOR (the agent that spawned it and is responsible for the merge landing). Your wake/task message names both — the `ownerAgentId` and the `coordinatorAgentId` — and `agent-relay steward inspect <id>` shows them. When you can't land work yourself, the coordinator is who you escalate to.",
|
|
119
|
+
"",
|
|
120
|
+
"Use the `agent-relay` CLI for EVERY relay interaction — it wraps the relay API and is the supported toolkit, and it already attaches your session token with the right scopes. Do NOT hand-curl the HTTP API (`/api/workspaces`, …): the CLI exists so you never have to. If you ever truly must call the API directly, authenticate with the `X-Agent-Relay-Token: <your session token>` header — NOT `Authorization: Bearer $AGENT_RELAY_TOKEN`; the admin env token is not present in your environment, so Bearer will 401.",
|
|
121
|
+
"Handle ONE workspace at a time — the relay's per-repo merge lease serializes you with any other merger.",
|
|
122
|
+
"",
|
|
123
|
+
"1. See the queue: `agent-relay steward queue` (workspaces in conflict / review_requested / merge_planned for this repo). The wake message(s) also name a `workspaceId`.",
|
|
124
|
+
"2. CLAIM it FIRST: `agent-relay workspace claim --id <id> --purpose steward`. This stops the deterministic auto-merge from racing you while you validate. The claim auto-expires, so a crash never blocks the repo.",
|
|
125
|
+
"3. Understand it: `agent-relay steward inspect <id>` — a diagnostics briefing (the branch agent owner + its coordinator, owner liveness, live git state, ahead/behind, recorded-vs-live branch mismatch, and a recommended action). `agent-relay steward checks <id>` suggests check commands from the changed files.",
|
|
126
|
+
"4. `cd` into the workspace's `worktreePath` and rebase the branch onto its `baseRef` (`git rebase <baseRef>`). Resolve conflicts faithfully — preserve the intent of EVERY side; never silently drop a change. If a conflict needs product judgment you can't make confidently, stop and escalate to the coordinator.",
|
|
127
|
+
"5. Run the repo's checks/tests (the suggested ones, plus the project's documented commands). Fix trivial breakage you caused while rebasing; do not paper over real failures.",
|
|
128
|
+
"6. If green, land it: `agent-relay workspace land --id <id> --strategy rebase-ff`. The relay rebases onto the latest base, fast-forwards, and pushes to origin under the lease. The land consumes your claim.",
|
|
129
|
+
"7. If you must stop without landing, RELEASE the claim so automation can resume: `agent-relay workspace release --id <id>`, then send a clear, specific summary to the workspace's COORDINATOR (the `coordinatorAgentId` from the wake message) — they own the work and can act on it. Reply to the wake message or message that agent id directly.",
|
|
130
|
+
"",
|
|
131
|
+
"Escalate (do NOT merge) when: checks fail and you can't fix them, the conflict resolution is genuinely ambiguous, or anything looks risky. ALWAYS escalate to the branch agent's coordinator (the `coordinatorAgentId` in the wake message). Only if the wake message names NO coordinator, escalate to {{escalationTarget}}. Never force-merge a red branch, never `git push --force` to a shared base, never discard committed work.",
|
|
132
|
+
"",
|
|
133
|
+
"Be terminal-efficient and decisive. When the queue is empty, you're done — you'll be woken again when there's more.",
|
|
134
|
+
),
|
|
135
|
+
variables: ["repoRoot", "escalationTarget"],
|
|
136
|
+
},
|
|
137
|
+
{
|
|
138
|
+
slug: "continuation.envelope",
|
|
139
|
+
category: "continuation",
|
|
140
|
+
title: "Continuation Envelope",
|
|
141
|
+
description: "Self-resume continuation text injected after compaction.",
|
|
142
|
+
template: lines(
|
|
143
|
+
"You have been resumed by Agent Relay — generation {{generation}}.",
|
|
144
|
+
"",
|
|
145
|
+
"Objective (verbatim, relay-owned):",
|
|
146
|
+
"{{objective}}",
|
|
147
|
+
"",
|
|
148
|
+
"Ruled-out ledger (append-only):",
|
|
149
|
+
"{{ruledOut}}",
|
|
150
|
+
"",
|
|
151
|
+
"Working state:",
|
|
152
|
+
"{{workingState}}",
|
|
153
|
+
"",
|
|
154
|
+
"Archive refs:",
|
|
155
|
+
"{{archiveRefs}}",
|
|
156
|
+
),
|
|
157
|
+
defaultTemplate: lines(
|
|
158
|
+
"You have been resumed by Agent Relay — generation {{generation}}.",
|
|
159
|
+
"",
|
|
160
|
+
"Objective (verbatim, relay-owned):",
|
|
161
|
+
"{{objective}}",
|
|
162
|
+
"",
|
|
163
|
+
"Ruled-out ledger (append-only):",
|
|
164
|
+
"{{ruledOut}}",
|
|
165
|
+
"",
|
|
166
|
+
"Working state:",
|
|
167
|
+
"{{workingState}}",
|
|
168
|
+
"",
|
|
169
|
+
"Archive refs:",
|
|
170
|
+
"{{archiveRefs}}",
|
|
171
|
+
),
|
|
172
|
+
variables: ["generation", "objective", "ruledOut", "workingState", "archiveRefs"],
|
|
173
|
+
},
|
|
174
|
+
{
|
|
175
|
+
slug: "context.advisory.warn",
|
|
176
|
+
category: "context",
|
|
177
|
+
title: "Context Advisory Warning",
|
|
178
|
+
description: "Warn-stage context advisory body.",
|
|
179
|
+
template: "Context warning: {{tokens}} ({{percent}}). You are approaching the {{threshold}}; if the current task is at a clean seam, prepare to call relay_compact_and_resume before continuing.",
|
|
180
|
+
defaultTemplate: "Context warning: {{tokens}} ({{percent}}). You are approaching the {{threshold}}; if the current task is at a clean seam, prepare to call relay_compact_and_resume before continuing.",
|
|
181
|
+
variables: ["tokens", "percent", "threshold"],
|
|
182
|
+
},
|
|
183
|
+
{
|
|
184
|
+
slug: "context.advisory.compact",
|
|
185
|
+
category: "context",
|
|
186
|
+
title: "Context Advisory Compact",
|
|
187
|
+
description: "Self-compact-stage context advisory body.",
|
|
188
|
+
template: "Context advisory: {{tokens}} ({{percent}}). You are over the {{threshold}}; call relay_compact_and_resume at the next clean seam between tasks or waves, not mid-edit. The {{hardBackstop}} hard backstop may request compaction if usage keeps climbing.",
|
|
189
|
+
defaultTemplate: "Context advisory: {{tokens}} ({{percent}}). You are over the {{threshold}}; call relay_compact_and_resume at the next clean seam between tasks or waves, not mid-edit. The {{hardBackstop}} hard backstop may request compaction if usage keeps climbing.",
|
|
190
|
+
variables: ["tokens", "percent", "threshold", "hardBackstop"],
|
|
191
|
+
},
|
|
192
|
+
{
|
|
193
|
+
slug: "spawn.primer",
|
|
194
|
+
category: "spawn",
|
|
195
|
+
title: "Spawn Primer",
|
|
196
|
+
description: "Eager startup primer for spawn-capable agents.",
|
|
197
|
+
template: lines(
|
|
198
|
+
"You can spawn long-living child agents{{quota}}. Shut your own down with relay_shutdown_agent.",
|
|
199
|
+
"- BEFORE spawning, call relay_spawn_targets: it returns the LIVE matrix of hosts × providers × models × per-model effort, advisory quota burn/penalty metadata, your remaining quota, and named profiles. Don't guess — that tool is the discovery path.",
|
|
200
|
+
"- Default to your OWN host. Only set orchestratorId to spawn onto another host when it runs a provider/model yours doesn't, or the work must run there.",
|
|
201
|
+
"- Prefer a named profile (profile: \"<name>\") over hand-assembling provider+model+effort+approvalMode. Omitting profile applies default-relay; omitting model/effort uses the provider default. Lean to the cheapest provider/model/effort that fits; escalate only for complex work.",
|
|
202
|
+
"- Set spawnRequestId for idempotency so a retried spawn doesn't double-create.",
|
|
203
|
+
"- After spawning, use relay_my_agents for your self-scoped child roster + quota and copy a returned spawnRequestId into relay_shutdown_agent when you need to reap.",
|
|
204
|
+
"- Spawn is fire-and-forget: pass waitForRegistrationMs:0 and keep working — you'll be PUSHED agent.ready when the child is genuinely ready (past onboarding), or agent.spawn_failed / agent.exited otherwise. Don't block-poll.",
|
|
205
|
+
"- Spawned children cannot themselves spawn (no grandchildren).",
|
|
206
|
+
),
|
|
207
|
+
defaultTemplate: lines(
|
|
208
|
+
"You can spawn long-living child agents{{quota}}. Shut your own down with relay_shutdown_agent.",
|
|
209
|
+
"- BEFORE spawning, call relay_spawn_targets: it returns the LIVE matrix of hosts × providers × models × per-model effort, advisory quota burn/penalty metadata, your remaining quota, and named profiles. Don't guess — that tool is the discovery path.",
|
|
210
|
+
"- Default to your OWN host. Only set orchestratorId to spawn onto another host when it runs a provider/model yours doesn't, or the work must run there.",
|
|
211
|
+
"- Prefer a named profile (profile: \"<name>\") over hand-assembling provider+model+effort+approvalMode. Omitting profile applies default-relay; omitting model/effort uses the provider default. Lean to the cheapest provider/model/effort that fits; escalate only for complex work.",
|
|
212
|
+
"- Set spawnRequestId for idempotency so a retried spawn doesn't double-create.",
|
|
213
|
+
"- After spawning, use relay_my_agents for your self-scoped child roster + quota and copy a returned spawnRequestId into relay_shutdown_agent when you need to reap.",
|
|
214
|
+
"- Spawn is fire-and-forget: pass waitForRegistrationMs:0 and keep working — you'll be PUSHED agent.ready when the child is genuinely ready (past onboarding), or agent.spawn_failed / agent.exited otherwise. Don't block-poll.",
|
|
215
|
+
"- Spawned children cannot themselves spawn (no grandchildren).",
|
|
216
|
+
),
|
|
217
|
+
variables: ["quota"],
|
|
218
|
+
},
|
|
219
|
+
{
|
|
220
|
+
slug: "workspace.mcp.instructions",
|
|
221
|
+
category: "workspace",
|
|
222
|
+
title: "Workspace MCP Instructions",
|
|
223
|
+
description: "Mode-tailored MCP initialize primer for isolated worktrees.",
|
|
224
|
+
template: lines(
|
|
225
|
+
"You are in an isolated git worktree on branch {{branch}}, based on {{baseRef}} — NOT the main checkout. {{baseRef}} moves under you as other agents land in parallel; that's expected.",
|
|
226
|
+
"Your shell's working directory is already this worktree — run commands directly without prefixing `cd`.",
|
|
227
|
+
"Changes reach the base via: commit your work, then call `relay_workspace_ready`. Relay rebases onto the latest base, lands, and pushes for you.",
|
|
228
|
+
"Do NOT push, rebase, merge, resolve conflicts, or `cd` into the main checkout — Relay (and a steward, spawned only if a clean auto-merge isn't possible) own all of that.",
|
|
229
|
+
"After `ready` the status is `ready` (a normal, healthy hand-off state, not a stall). Stop your turn and go idle; Relay wakes you with `landed-success` when your branch lands and refreshes, or `landed-failure` if landing fatally fails.",
|
|
230
|
+
"Call `relay_workspace_status` anytime to see where you are and the exact next step.",
|
|
231
|
+
),
|
|
232
|
+
defaultTemplate: lines(
|
|
233
|
+
"You are in an isolated git worktree on branch {{branch}}, based on {{baseRef}} — NOT the main checkout. {{baseRef}} moves under you as other agents land in parallel; that's expected.",
|
|
234
|
+
"Your shell's working directory is already this worktree — run commands directly without prefixing `cd`.",
|
|
235
|
+
"Changes reach the base via: commit your work, then call `relay_workspace_ready`. Relay rebases onto the latest base, lands, and pushes for you.",
|
|
236
|
+
"Do NOT push, rebase, merge, resolve conflicts, or `cd` into the main checkout — Relay (and a steward, spawned only if a clean auto-merge isn't possible) own all of that.",
|
|
237
|
+
"After `ready` the status is `ready` (a normal, healthy hand-off state, not a stall). Stop your turn and go idle; Relay wakes you with `landed-success` when your branch lands and refreshes, or `landed-failure` if landing fatally fails.",
|
|
238
|
+
"Call `relay_workspace_status` anytime to see where you are and the exact next step.",
|
|
239
|
+
),
|
|
240
|
+
variables: ["branch", "baseRef"],
|
|
241
|
+
},
|
|
242
|
+
{
|
|
243
|
+
slug: "workspace.ready.contract",
|
|
244
|
+
category: "workspace",
|
|
245
|
+
title: "Workspace Ready Contract",
|
|
246
|
+
description: "Post-ready contract returned to isolated workspace agents.",
|
|
247
|
+
template: lines(
|
|
248
|
+
"Marked ready. Status is now `{{status}}` — this is the normal, healthy hand-off state, not an escalation.",
|
|
249
|
+
"Relay auto-merges clean rebases roughly every 2 minutes. A steward agent is spawned (after a short delay) ONLY if it can't land deterministically — so no steward appearing means it's working, not stuck.",
|
|
250
|
+
"STOP this turn now and go idle. Do not call `relay_workspace_status wait:true`, `agent-relay workspace status --wait`, or any polling loop after marking ready.",
|
|
251
|
+
"Relay will wake you with `landed-success` when the merge lands and your branch is refreshed, or `landed-failure` if landing fatally fails.",
|
|
252
|
+
"On `landed-success` you'll be on a fresh rebased branch (its name gains a `--N` suffix — expected). Keep working there.",
|
|
253
|
+
"Do NOT merge, push, rebase, resolve conflicts, or `cd` into the main checkout — Relay (and the steward) own all of that.",
|
|
254
|
+
),
|
|
255
|
+
defaultTemplate: lines(
|
|
256
|
+
"Marked ready. Status is now `{{status}}` — this is the normal, healthy hand-off state, not an escalation.",
|
|
257
|
+
"Relay auto-merges clean rebases roughly every 2 minutes. A steward agent is spawned (after a short delay) ONLY if it can't land deterministically — so no steward appearing means it's working, not stuck.",
|
|
258
|
+
"STOP this turn now and go idle. Do not call `relay_workspace_status wait:true`, `agent-relay workspace status --wait`, or any polling loop after marking ready.",
|
|
259
|
+
"Relay will wake you with `landed-success` when the merge lands and your branch is refreshed, or `landed-failure` if landing fatally fails.",
|
|
260
|
+
"On `landed-success` you'll be on a fresh rebased branch (its name gains a `--N` suffix — expected). Keep working there.",
|
|
261
|
+
"Do NOT merge, push, rebase, resolve conflicts, or `cd` into the main checkout — Relay (and the steward) own all of that.",
|
|
262
|
+
),
|
|
263
|
+
variables: ["status"],
|
|
264
|
+
},
|
|
265
|
+
...RUNNER_PROMPT_TEMPLATE_DEFAULTS,
|
|
266
|
+
{
|
|
267
|
+
slug: "notify.agent.ready",
|
|
268
|
+
category: "notify",
|
|
269
|
+
title: "Spawned Agent Ready",
|
|
270
|
+
description: "Notification body sent when a spawned child becomes ready.",
|
|
271
|
+
template: "✅ Your spawned agent {{label}} is ready and idle — send it work with relay_send_message to `{{childId}}`.",
|
|
272
|
+
defaultTemplate: "✅ Your spawned agent {{label}} is ready and idle — send it work with relay_send_message to `{{childId}}`.",
|
|
273
|
+
variables: ["label", "childId"],
|
|
274
|
+
},
|
|
275
|
+
{
|
|
276
|
+
slug: "notify.agent.exited",
|
|
277
|
+
category: "notify",
|
|
278
|
+
title: "Spawned Agent Exited",
|
|
279
|
+
description: "Notification body sent when a spawned child exits after becoming ready.",
|
|
280
|
+
template: "⏹ Your spawned agent {{label}} exited — {{reason}}{{diagnosis}}.",
|
|
281
|
+
defaultTemplate: "⏹ Your spawned agent {{label}} exited — {{reason}}{{diagnosis}}.",
|
|
282
|
+
variables: ["label", "reason", "diagnosis"],
|
|
283
|
+
},
|
|
284
|
+
{
|
|
285
|
+
slug: "notify.agent.never-ready",
|
|
286
|
+
category: "notify",
|
|
287
|
+
title: "Spawned Agent Never Ready",
|
|
288
|
+
description: "Notification body sent when a spawned child dies before becoming ready.",
|
|
289
|
+
template: "❌ Your spawned agent {{label}} went offline before ever becoming ready — {{reason}}{{diagnosis}}. Likely a crash-loop, onboarding gate, or bad launch; call relay_spawn_targets to re-check provider availability before retrying.",
|
|
290
|
+
defaultTemplate: "❌ Your spawned agent {{label}} went offline before ever becoming ready — {{reason}}{{diagnosis}}. Likely a crash-loop, onboarding gate, or bad launch; call relay_spawn_targets to re-check provider availability before retrying.",
|
|
291
|
+
variables: ["label", "reason", "diagnosis"],
|
|
292
|
+
},
|
|
293
|
+
{
|
|
294
|
+
slug: "notify.spawn.failed",
|
|
295
|
+
category: "notify",
|
|
296
|
+
title: "Spawn Failed",
|
|
297
|
+
description: "Notification body sent when a spawn command fails outright.",
|
|
298
|
+
template: "❌ Your spawn request{{spawnRequestId}} failed — {{reason}}. Call relay_spawn_targets to check live provider/host availability before retrying.",
|
|
299
|
+
defaultTemplate: "❌ Your spawn request{{spawnRequestId}} failed — {{reason}}. Call relay_spawn_targets to check live provider/host availability before retrying.",
|
|
300
|
+
variables: ["spawnRequestId", "reason"],
|
|
301
|
+
},
|
|
302
|
+
{
|
|
303
|
+
slug: "notify.spawn.recovered",
|
|
304
|
+
category: "notify",
|
|
305
|
+
title: "Spawn Recovered",
|
|
306
|
+
description: "Correction sent when a spawn-failed report is later superseded by readiness.",
|
|
307
|
+
template: "♻️ Correction: your earlier spawn failure{{spawnRequestId}} was a false alarm — {{label}} actually registered and is ready and idle. Disregard the failure and do NOT retry; send it work with relay_send_message to `{{childId}}`.",
|
|
308
|
+
defaultTemplate: "♻️ Correction: your earlier spawn failure{{spawnRequestId}} was a false alarm — {{label}} actually registered and is ready and idle. Disregard the failure and do NOT retry; send it work with relay_send_message to `{{childId}}`.",
|
|
309
|
+
variables: ["spawnRequestId", "label", "childId"],
|
|
310
|
+
},
|
|
311
|
+
{
|
|
312
|
+
slug: "notify.land.success",
|
|
313
|
+
category: "notify",
|
|
314
|
+
title: "Branch Landed",
|
|
315
|
+
description: "Owner notification body when a branch lands successfully.",
|
|
316
|
+
template: "✅ {{branch}} landed on `{{base}}`{{sha}}.{{publishLabel}}{{continueLabel}}",
|
|
317
|
+
defaultTemplate: "✅ {{branch}} landed on `{{base}}`{{sha}}.{{publishLabel}}{{continueLabel}}",
|
|
318
|
+
variables: ["branch", "base", "sha", "publishLabel", "continueLabel"],
|
|
319
|
+
},
|
|
320
|
+
{
|
|
321
|
+
slug: "notify.land.failure",
|
|
322
|
+
category: "notify",
|
|
323
|
+
title: "Branch Land Failure",
|
|
324
|
+
description: "Owner wake sent when landing fails fatally.",
|
|
325
|
+
template: "❌ {{branch}} did not land on `{{base}}`: {{reason}}. You were woken by `landed-failure`; inspect workspace status before doing more work. Do NOT push, rebase, merge, or touch the main checkout yourself.",
|
|
326
|
+
defaultTemplate: "❌ {{branch}} did not land on `{{base}}`: {{reason}}. You were woken by `landed-failure`; inspect workspace status before doing more work. Do NOT push, rebase, merge, or touch the main checkout yourself.",
|
|
327
|
+
variables: ["branch", "base", "reason"],
|
|
328
|
+
},
|
|
329
|
+
{
|
|
330
|
+
slug: "notify.land.steward-taken",
|
|
331
|
+
category: "notify",
|
|
332
|
+
title: "Steward Took Over Merge",
|
|
333
|
+
description: "Owner-facing notice that a steward took over the merge.",
|
|
334
|
+
template: "🛟 {{branch}} couldn't be auto-merged to `{{base}}` and is now being handled by steward agent `{{stewardId}}`{{reasonLabel}}. The steward will rebase/resolve and land it. Do NOT push, rebase, merge, or touch the main checkout yourself; stay idle until you're woken with the result.",
|
|
335
|
+
defaultTemplate: "🛟 {{branch}} couldn't be auto-merged to `{{base}}` and is now being handled by steward agent `{{stewardId}}`{{reasonLabel}}. The steward will rebase/resolve and land it. Do NOT push, rebase, merge, or touch the main checkout yourself; stay idle until you're woken with the result.",
|
|
336
|
+
variables: ["branch", "base", "stewardId", "reasonLabel"],
|
|
337
|
+
},
|
|
338
|
+
{
|
|
339
|
+
slug: "notify.land.steward-taken.coordinator",
|
|
340
|
+
category: "notify",
|
|
341
|
+
title: "Steward Took Over Merge (Coordinator)",
|
|
342
|
+
description: "Coordinator-facing notice that a steward took over a branch agent's merge.",
|
|
343
|
+
template: "🛟 Your branch agent `{{owner}}`'s merge ({{branch}} → `{{base}}`) couldn't be auto-merged and is now with steward agent `{{stewardId}}`{{reasonLabel}}. The steward will land it or escalate to you if it can't.",
|
|
344
|
+
defaultTemplate: "🛟 Your branch agent `{{owner}}`'s merge ({{branch}} → `{{base}}`) couldn't be auto-merged and is now with steward agent `{{stewardId}}`{{reasonLabel}}. The steward will land it or escalate to you if it can't.",
|
|
345
|
+
variables: ["owner", "branch", "base", "stewardId", "reasonLabel"],
|
|
346
|
+
},
|
|
347
|
+
{
|
|
348
|
+
slug: "workspace.phase.active.headline",
|
|
349
|
+
category: "workspace",
|
|
350
|
+
title: "Workspace Active Headline",
|
|
351
|
+
description: "Workspace status headline for active isolated work.",
|
|
352
|
+
template: "Your isolated branch — work in progress.",
|
|
353
|
+
defaultTemplate: "Your isolated branch — work in progress.",
|
|
354
|
+
variables: [],
|
|
355
|
+
},
|
|
356
|
+
{
|
|
357
|
+
slug: "workspace.phase.active.hint",
|
|
358
|
+
category: "workspace",
|
|
359
|
+
title: "Workspace Active Hint",
|
|
360
|
+
description: "Workspace status hint for active isolated work.",
|
|
361
|
+
template: "Commit your work in this worktree, then mark it ready. Relay rebases onto the latest base, lands, and pushes for you — do NOT push, rebase, or merge yourself, and never touch the main checkout.",
|
|
362
|
+
defaultTemplate: "Commit your work in this worktree, then mark it ready. Relay rebases onto the latest base, lands, and pushes for you — do NOT push, rebase, or merge yourself, and never touch the main checkout.",
|
|
363
|
+
variables: [],
|
|
364
|
+
},
|
|
365
|
+
{
|
|
366
|
+
slug: "workspace.phase.ready.headline",
|
|
367
|
+
category: "workspace",
|
|
368
|
+
title: "Workspace Ready Headline",
|
|
369
|
+
description: "Workspace status headline for healthy handoff states.",
|
|
370
|
+
template: "Handed off — stop this turn and go idle while Relay lands your branch. This is the normal, healthy post-ready state (not an escalation).",
|
|
371
|
+
defaultTemplate: "Handed off — stop this turn and go idle while Relay lands your branch. This is the normal, healthy post-ready state (not an escalation).",
|
|
372
|
+
variables: [],
|
|
373
|
+
},
|
|
374
|
+
{
|
|
375
|
+
slug: "workspace.phase.ready.hint",
|
|
376
|
+
category: "workspace",
|
|
377
|
+
title: "Workspace Ready Hint",
|
|
378
|
+
description: "Workspace status hint for healthy handoff states.",
|
|
379
|
+
template: "No action needed. Stop your turn now; do not poll or wait on the steward queue. Relay will wake you with a `landed-success` notification when the merge lands and your branch is refreshed, or `landed-failure` if landing fatally fails. Do NOT merge, push, resolve anything, or touch the main checkout.",
|
|
380
|
+
defaultTemplate: "No action needed. Stop your turn now; do not poll or wait on the steward queue. Relay will wake you with a `landed-success` notification when the merge lands and your branch is refreshed, or `landed-failure` if landing fatally fails. Do NOT merge, push, resolve anything, or touch the main checkout.",
|
|
381
|
+
variables: [],
|
|
382
|
+
},
|
|
383
|
+
{
|
|
384
|
+
slug: "workspace.phase.merge-planned.headline",
|
|
385
|
+
category: "workspace",
|
|
386
|
+
title: "Workspace Merge Planned Headline",
|
|
387
|
+
description: "Workspace status headline for merge dispatch.",
|
|
388
|
+
template: "Merge dispatched — landing your branch on the base now.",
|
|
389
|
+
defaultTemplate: "Merge dispatched — landing your branch on the base now.",
|
|
390
|
+
variables: [],
|
|
391
|
+
},
|
|
392
|
+
{
|
|
393
|
+
slug: "workspace.phase.merge-planned.hint",
|
|
394
|
+
category: "workspace",
|
|
395
|
+
title: "Workspace Merge Planned Hint",
|
|
396
|
+
description: "Workspace status hint for merge dispatch.",
|
|
397
|
+
template: "No action needed. When it completes you'll be moved onto a fresh rebased branch (the name gains a `--N` suffix — expected) to keep working.",
|
|
398
|
+
defaultTemplate: "No action needed. When it completes you'll be moved onto a fresh rebased branch (the name gains a `--N` suffix — expected) to keep working.",
|
|
399
|
+
variables: [],
|
|
400
|
+
},
|
|
401
|
+
{
|
|
402
|
+
slug: "workspace.phase.conflict.headline",
|
|
403
|
+
category: "workspace",
|
|
404
|
+
title: "Workspace Conflict Headline",
|
|
405
|
+
description: "Workspace status headline when a steward is reconciling a conflict.",
|
|
406
|
+
template: "Auto-merge hit a conflict — a steward agent is reconciling it. Resolving it is NOT your job.",
|
|
407
|
+
defaultTemplate: "Auto-merge hit a conflict — a steward agent is reconciling it. Resolving it is NOT your job.",
|
|
408
|
+
variables: [],
|
|
409
|
+
},
|
|
410
|
+
{
|
|
411
|
+
slug: "workspace.phase.conflict.hint",
|
|
412
|
+
category: "workspace",
|
|
413
|
+
title: "Workspace Conflict Hint",
|
|
414
|
+
description: "Workspace status hint when a steward is reconciling a conflict.",
|
|
415
|
+
template: "Do not resolve the conflict, rebase, merge, or push yourself. The steward rebases and lands it, escalating to the human only if it truly can't. You can keep working or wait for it to land.",
|
|
416
|
+
defaultTemplate: "Do not resolve the conflict, rebase, merge, or push yourself. The steward rebases and lands it, escalating to the human only if it truly can't. You can keep working or wait for it to land.",
|
|
417
|
+
variables: [],
|
|
418
|
+
},
|
|
419
|
+
{
|
|
420
|
+
slug: "workspace.phase.merged.headline",
|
|
421
|
+
category: "workspace",
|
|
422
|
+
title: "Workspace Merged Headline",
|
|
423
|
+
description: "Workspace status headline after a successful land.",
|
|
424
|
+
template: "✅ Landed — your commits are on the base.",
|
|
425
|
+
defaultTemplate: "✅ Landed — your commits are on the base.",
|
|
426
|
+
variables: [],
|
|
427
|
+
},
|
|
428
|
+
{
|
|
429
|
+
slug: "workspace.phase.merged.hint",
|
|
430
|
+
category: "workspace",
|
|
431
|
+
title: "Workspace Merged Hint",
|
|
432
|
+
description: "Workspace status hint after a successful land.",
|
|
433
|
+
template: "A fresh rebased branch is being prepared; you'll continue on it (the branch name gains a `--N` suffix — expected, not an error). Keep working.",
|
|
434
|
+
defaultTemplate: "A fresh rebased branch is being prepared; you'll continue on it (the branch name gains a `--N` suffix — expected, not an error). Keep working.",
|
|
435
|
+
variables: [],
|
|
436
|
+
},
|
|
437
|
+
{
|
|
438
|
+
slug: "workspace.phase.abandoned.headline",
|
|
439
|
+
category: "workspace",
|
|
440
|
+
title: "Workspace Closed Headline",
|
|
441
|
+
description: "Workspace status headline when the worktree is being torn down.",
|
|
442
|
+
template: "This workspace is being torn down.",
|
|
443
|
+
defaultTemplate: "This workspace is being torn down.",
|
|
444
|
+
variables: [],
|
|
445
|
+
},
|
|
446
|
+
{
|
|
447
|
+
slug: "workspace.phase.abandoned.hint",
|
|
448
|
+
category: "workspace",
|
|
449
|
+
title: "Workspace Closed Hint",
|
|
450
|
+
description: "Workspace status hint when the worktree is being torn down.",
|
|
451
|
+
template: "No further branch work happens here. If you still have work to do, the host will spawn you into a fresh workspace.",
|
|
452
|
+
defaultTemplate: "No further branch work happens here. If you still have work to do, the host will spawn you into a fresh workspace.",
|
|
453
|
+
variables: [],
|
|
454
|
+
},
|
|
455
|
+
{
|
|
456
|
+
slug: "steward.wake",
|
|
457
|
+
category: "steward",
|
|
458
|
+
title: "Steward Wake Message",
|
|
459
|
+
description: "Task body sent to the steward when a workspace needs manual landing.",
|
|
460
|
+
template: "Workspace `{{branch}}` (id {{wsId}}) in {{repoRoot}} is {{status}} and could not auto-land ({{reason}}).{{ownerLine}} Claim it first so auto-merge yields: `agent-relay workspace claim --id {{wsId}} --purpose steward`. Inspect: `agent-relay steward inspect {{wsId}}`. Then cd into {{worktreePath}}, rebase onto {{baseRef}}, resolve, run checks, and land: `agent-relay workspace land --id {{wsId}} --strategy rebase-ff` — or `agent-relay workspace release --id {{wsId}}` and escalate if you can't.{{coordinatorLine}}",
|
|
461
|
+
defaultTemplate: "Workspace `{{branch}}` (id {{wsId}}) in {{repoRoot}} is {{status}} and could not auto-land ({{reason}}).{{ownerLine}} Claim it first so auto-merge yields: `agent-relay workspace claim --id {{wsId}} --purpose steward`. Inspect: `agent-relay steward inspect {{wsId}}`. Then cd into {{worktreePath}}, rebase onto {{baseRef}}, resolve, run checks, and land: `agent-relay workspace land --id {{wsId}} --strategy rebase-ff` — or `agent-relay workspace release --id {{wsId}}` and escalate if you can't.{{coordinatorLine}}",
|
|
462
|
+
variables: ["branch", "wsId", "repoRoot", "status", "reason", "ownerLine", "worktreePath", "baseRef", "coordinatorLine"],
|
|
463
|
+
},
|
|
464
|
+
{
|
|
465
|
+
slug: "steward.merge-stall",
|
|
466
|
+
category: "steward",
|
|
467
|
+
title: "Auto-Merge Backoff Notice",
|
|
468
|
+
description: "Notification body when auto-merge backs off after repeated no-progress attempts.",
|
|
469
|
+
template: "Workspace {{branch}} in {{repoRoot}} failed to land {{attempts}}× without progress ({{mergeError}}). Auto-merge has backed off to stop a merge-command loop. Sync `{{baseRef}}` and land manually, or release the workspace.",
|
|
470
|
+
defaultTemplate: "Workspace {{branch}} in {{repoRoot}} failed to land {{attempts}}× without progress ({{mergeError}}). Auto-merge has backed off to stop a merge-command loop. Sync `{{baseRef}}` and land manually, or release the workspace.",
|
|
471
|
+
variables: ["branch", "repoRoot", "attempts", "mergeError", "baseRef"],
|
|
472
|
+
},
|
|
473
|
+
{
|
|
474
|
+
slug: "task.claim.instruction",
|
|
475
|
+
category: "task",
|
|
476
|
+
title: "Task Claim Instruction",
|
|
477
|
+
description: "Footer appended to task message bodies.",
|
|
478
|
+
template: "Claim this task before working it, then update task status when finished.",
|
|
479
|
+
defaultTemplate: "Claim this task before working it, then update task status when finished.",
|
|
480
|
+
variables: [],
|
|
481
|
+
},
|
|
482
|
+
{
|
|
483
|
+
slug: "notify.routing.policy-changed",
|
|
484
|
+
category: "notify",
|
|
485
|
+
title: "Routing Policy Changed",
|
|
486
|
+
description: "Notification body sent to live spawn-capable agents after a routing policy save.",
|
|
487
|
+
template: "🗺 Routing policy updated{{updatedBy}}. Ingest this delta now — spawn routing decisions take effect immediately without respawn. Re-read relay_spawn_targets for live provider/model options.",
|
|
488
|
+
defaultTemplate: "🗺 Routing policy updated{{updatedBy}}. Ingest this delta now — spawn routing decisions take effect immediately without respawn. Re-read relay_spawn_targets for live provider/model options.",
|
|
489
|
+
variables: ["updatedBy"],
|
|
490
|
+
},
|
|
491
|
+
{
|
|
492
|
+
slug: "notify.automation.budget-warning",
|
|
493
|
+
category: "notify",
|
|
494
|
+
title: "Automation Runtime Budget Warning",
|
|
495
|
+
description: "Fallback automation runtime budget warning body.",
|
|
496
|
+
template: "Runtime budget warning: this automation run will be shut down in about {{remainingMinutes}}. Finish current work, commit and push anything worth keeping, then stop cleanly before the deadline.",
|
|
497
|
+
defaultTemplate: "Runtime budget warning: this automation run will be shut down in about {{remainingMinutes}}. Finish current work, commit and push anything worth keeping, then stop cleanly before the deadline.",
|
|
498
|
+
variables: ["remainingMinutes"],
|
|
499
|
+
},
|
|
500
|
+
] as const satisfies readonly SeedTemplate[];
|
|
501
|
+
|
|
502
|
+
export const DEFAULTS = new Map<string, SeedTemplate>(
|
|
503
|
+
DEFAULT_PROMPT_TEMPLATES.map((template) => [template.slug, template]),
|
|
504
|
+
);
|
|
505
|
+
|
|
506
|
+
export function defaultPromptTemplates(): SeedTemplate[] {
|
|
507
|
+
return DEFAULT_PROMPT_TEMPLATES.map(copySeedTemplate);
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
function renderValue(value: string | string[] | undefined): string {
|
|
511
|
+
if (Array.isArray(value)) return value.join("\n");
|
|
512
|
+
return value ?? "";
|
|
513
|
+
}
|
|
514
|
+
|
|
515
|
+
function applyVariables(template: string, vars: Record<string, string | string[]>): string {
|
|
516
|
+
return template.replace(/\{\{(\w+)\}\}/g, (_, key: string) => renderValue(vars[key]));
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
export function renderTemplate(slug: string, vars: Record<string, string | string[]> = {}): string {
|
|
520
|
+
let stored = null;
|
|
521
|
+
try {
|
|
522
|
+
stored = getTemplate(slug);
|
|
523
|
+
} catch {
|
|
524
|
+
stored = null;
|
|
525
|
+
}
|
|
526
|
+
const fallback = DEFAULTS.get(slug);
|
|
527
|
+
const template = stored?.template ?? fallback?.defaultTemplate;
|
|
528
|
+
if (template === undefined) throw new Error(`unknown prompt template slug: ${slug}`);
|
|
529
|
+
return applyVariables(template, vars);
|
|
530
|
+
}
|