@agent-relay/factory 0.0.0 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (235) hide show
  1. package/README.md +182 -23
  2. package/bin/factory.mjs +7 -0
  3. package/dist/cli/fleet.d.ts +81 -0
  4. package/dist/cli/fleet.d.ts.map +1 -0
  5. package/dist/cli/fleet.js +571 -0
  6. package/dist/cli/fleet.js.map +1 -0
  7. package/dist/config/schema.d.ts +1313 -0
  8. package/dist/config/schema.d.ts.map +1 -0
  9. package/dist/config/schema.js +320 -0
  10. package/dist/config/schema.js.map +1 -0
  11. package/dist/constants/linear.d.ts +6 -0
  12. package/dist/constants/linear.d.ts.map +1 -0
  13. package/dist/constants/linear.js +21 -0
  14. package/dist/constants/linear.js.map +1 -0
  15. package/dist/constants/slack.d.ts +3 -0
  16. package/dist/constants/slack.d.ts.map +1 -0
  17. package/dist/constants/slack.js +3 -0
  18. package/dist/constants/slack.js.map +1 -0
  19. package/dist/dispatch/templates.d.ts +52 -0
  20. package/dist/dispatch/templates.d.ts.map +1 -0
  21. package/dist/dispatch/templates.js +118 -0
  22. package/dist/dispatch/templates.js.map +1 -0
  23. package/dist/fleet/create-fleet.d.ts +14 -0
  24. package/dist/fleet/create-fleet.d.ts.map +1 -0
  25. package/dist/fleet/create-fleet.js +15 -0
  26. package/dist/fleet/create-fleet.js.map +1 -0
  27. package/dist/fleet/ensure-relay-broker.d.ts +24 -0
  28. package/dist/fleet/ensure-relay-broker.d.ts.map +1 -0
  29. package/dist/fleet/ensure-relay-broker.js +56 -0
  30. package/dist/fleet/ensure-relay-broker.js.map +1 -0
  31. package/dist/fleet/internal-fleet-client.d.ts +90 -0
  32. package/dist/fleet/internal-fleet-client.d.ts.map +1 -0
  33. package/dist/fleet/internal-fleet-client.js +602 -0
  34. package/dist/fleet/internal-fleet-client.js.map +1 -0
  35. package/dist/fleet/relay-fleet-client.d.ts +105 -0
  36. package/dist/fleet/relay-fleet-client.d.ts.map +1 -0
  37. package/dist/fleet/relay-fleet-client.js +509 -0
  38. package/dist/fleet/relay-fleet-client.js.map +1 -0
  39. package/dist/github/index.d.ts +5 -0
  40. package/dist/github/index.d.ts.map +1 -0
  41. package/dist/github/index.js +3 -0
  42. package/dist/github/index.js.map +1 -0
  43. package/dist/github/merge-gate.d.ts +47 -0
  44. package/dist/github/merge-gate.d.ts.map +1 -0
  45. package/dist/github/merge-gate.js +147 -0
  46. package/dist/github/merge-gate.js.map +1 -0
  47. package/dist/github/probe-closer.d.ts +15 -0
  48. package/dist/github/probe-closer.d.ts.map +1 -0
  49. package/dist/github/probe-closer.js +67 -0
  50. package/dist/github/probe-closer.js.map +1 -0
  51. package/dist/index.d.ts +36 -0
  52. package/dist/index.d.ts.map +1 -0
  53. package/dist/index.js +20 -0
  54. package/dist/index.js.map +1 -0
  55. package/dist/issue-key-match.d.ts +3 -0
  56. package/dist/issue-key-match.d.ts.map +1 -0
  57. package/dist/issue-key-match.js +22 -0
  58. package/dist/issue-key-match.js.map +1 -0
  59. package/dist/linear/state-resolver.d.ts +26 -0
  60. package/dist/linear/state-resolver.d.ts.map +1 -0
  61. package/dist/linear/state-resolver.js +285 -0
  62. package/dist/linear/state-resolver.js.map +1 -0
  63. package/dist/mount/local-mount-preflight.d.ts +9 -0
  64. package/dist/mount/local-mount-preflight.d.ts.map +1 -0
  65. package/dist/mount/local-mount-preflight.js +149 -0
  66. package/dist/mount/local-mount-preflight.js.map +1 -0
  67. package/dist/mount/relayfile-binary.d.ts +9 -0
  68. package/dist/mount/relayfile-binary.d.ts.map +1 -0
  69. package/dist/mount/relayfile-binary.js +177 -0
  70. package/dist/mount/relayfile-binary.js.map +1 -0
  71. package/dist/mount/relayfile-cloud-mount-client.d.ts +123 -0
  72. package/dist/mount/relayfile-cloud-mount-client.d.ts.map +1 -0
  73. package/dist/mount/relayfile-cloud-mount-client.js +427 -0
  74. package/dist/mount/relayfile-cloud-mount-client.js.map +1 -0
  75. package/dist/node/factory-node.d.ts +59 -0
  76. package/dist/node/factory-node.d.ts.map +1 -0
  77. package/dist/node/factory-node.js +351 -0
  78. package/dist/node/factory-node.js.map +1 -0
  79. package/dist/node/factory.node.d.ts +3 -0
  80. package/dist/node/factory.node.d.ts.map +1 -0
  81. package/dist/node/factory.node.js +5 -0
  82. package/dist/node/factory.node.js.map +1 -0
  83. package/dist/orchestrator/batch-tracker.d.ts +42 -0
  84. package/dist/orchestrator/batch-tracker.d.ts.map +1 -0
  85. package/dist/orchestrator/batch-tracker.js +125 -0
  86. package/dist/orchestrator/batch-tracker.js.map +1 -0
  87. package/dist/orchestrator/factory.d.ts +58 -0
  88. package/dist/orchestrator/factory.d.ts.map +1 -0
  89. package/dist/orchestrator/factory.js +4372 -0
  90. package/dist/orchestrator/factory.js.map +1 -0
  91. package/dist/orchestrator/index.d.ts +5 -0
  92. package/dist/orchestrator/index.d.ts.map +1 -0
  93. package/dist/orchestrator/index.js +4 -0
  94. package/dist/orchestrator/index.js.map +1 -0
  95. package/dist/orchestrator/process-identity.d.ts +23 -0
  96. package/dist/orchestrator/process-identity.d.ts.map +1 -0
  97. package/dist/orchestrator/process-identity.js +122 -0
  98. package/dist/orchestrator/process-identity.js.map +1 -0
  99. package/dist/orchestrator/reaper.d.ts +60 -0
  100. package/dist/orchestrator/reaper.d.ts.map +1 -0
  101. package/dist/orchestrator/reaper.js +293 -0
  102. package/dist/orchestrator/reaper.js.map +1 -0
  103. package/dist/ports/fleet.d.ts +101 -0
  104. package/dist/ports/fleet.d.ts.map +1 -0
  105. package/dist/ports/fleet.js +2 -0
  106. package/dist/ports/fleet.js.map +1 -0
  107. package/dist/ports/index.d.ts +5 -0
  108. package/dist/ports/index.d.ts.map +1 -0
  109. package/dist/ports/index.js +2 -0
  110. package/dist/ports/index.js.map +1 -0
  111. package/dist/ports/mount.d.ts +56 -0
  112. package/dist/ports/mount.d.ts.map +1 -0
  113. package/dist/ports/mount.js +2 -0
  114. package/dist/ports/mount.js.map +1 -0
  115. package/dist/ports/state.d.ts +61 -0
  116. package/dist/ports/state.d.ts.map +1 -0
  117. package/dist/ports/state.js +2 -0
  118. package/dist/ports/state.js.map +1 -0
  119. package/dist/ports/system.d.ts +15 -0
  120. package/dist/ports/system.d.ts.map +1 -0
  121. package/dist/ports/system.js +2 -0
  122. package/dist/ports/system.js.map +1 -0
  123. package/dist/ports/writeback.d.ts +25 -0
  124. package/dist/ports/writeback.d.ts.map +1 -0
  125. package/dist/ports/writeback.js +2 -0
  126. package/dist/ports/writeback.js.map +1 -0
  127. package/dist/safety/factory-scope.d.ts +16 -0
  128. package/dist/safety/factory-scope.d.ts.map +1 -0
  129. package/dist/safety/factory-scope.js +107 -0
  130. package/dist/safety/factory-scope.js.map +1 -0
  131. package/dist/state/in-memory-state-store.d.ts +31 -0
  132. package/dist/state/in-memory-state-store.d.ts.map +1 -0
  133. package/dist/state/in-memory-state-store.js +115 -0
  134. package/dist/state/in-memory-state-store.js.map +1 -0
  135. package/dist/state/index.d.ts +3 -0
  136. package/dist/state/index.d.ts.map +1 -0
  137. package/dist/state/index.js +2 -0
  138. package/dist/state/index.js.map +1 -0
  139. package/dist/state/store.d.ts +29 -0
  140. package/dist/state/store.d.ts.map +1 -0
  141. package/dist/state/store.js +26 -0
  142. package/dist/state/store.js.map +1 -0
  143. package/dist/subscriptions/common.d.ts +7 -0
  144. package/dist/subscriptions/common.d.ts.map +1 -0
  145. package/dist/subscriptions/common.js +59 -0
  146. package/dist/subscriptions/common.js.map +1 -0
  147. package/dist/subscriptions/event-client.d.ts +40 -0
  148. package/dist/subscriptions/event-client.d.ts.map +1 -0
  149. package/dist/subscriptions/event-client.js +234 -0
  150. package/dist/subscriptions/event-client.js.map +1 -0
  151. package/dist/subscriptions/globs.d.ts +5 -0
  152. package/dist/subscriptions/globs.d.ts.map +1 -0
  153. package/dist/subscriptions/globs.js +50 -0
  154. package/dist/subscriptions/globs.js.map +1 -0
  155. package/dist/subscriptions/index.d.ts +8 -0
  156. package/dist/subscriptions/index.d.ts.map +1 -0
  157. package/dist/subscriptions/index.js +5 -0
  158. package/dist/subscriptions/index.js.map +1 -0
  159. package/dist/subscriptions/linear-filter.d.ts +26 -0
  160. package/dist/subscriptions/linear-filter.d.ts.map +1 -0
  161. package/dist/subscriptions/linear-filter.js +143 -0
  162. package/dist/subscriptions/linear-filter.js.map +1 -0
  163. package/dist/subscriptions/specs.d.ts +44 -0
  164. package/dist/subscriptions/specs.d.ts.map +1 -0
  165. package/dist/subscriptions/specs.js +195 -0
  166. package/dist/subscriptions/specs.js.map +1 -0
  167. package/dist/testing/fakes.d.ts +114 -0
  168. package/dist/testing/fakes.d.ts.map +1 -0
  169. package/dist/testing/fakes.js +219 -0
  170. package/dist/testing/fakes.js.map +1 -0
  171. package/dist/testing/index.d.ts +2 -0
  172. package/dist/testing/index.d.ts.map +1 -0
  173. package/dist/testing/index.js +2 -0
  174. package/dist/testing/index.js.map +1 -0
  175. package/dist/triage/heuristic.d.ts +42 -0
  176. package/dist/triage/heuristic.d.ts.map +1 -0
  177. package/dist/triage/heuristic.js +326 -0
  178. package/dist/triage/heuristic.js.map +1 -0
  179. package/dist/triage/index.d.ts +7 -0
  180. package/dist/triage/index.d.ts.map +1 -0
  181. package/dist/triage/index.js +5 -0
  182. package/dist/triage/index.js.map +1 -0
  183. package/dist/triage/llm.d.ts +11 -0
  184. package/dist/triage/llm.d.ts.map +1 -0
  185. package/dist/triage/llm.js +48 -0
  186. package/dist/triage/llm.js.map +1 -0
  187. package/dist/triage/schema.d.ts +344 -0
  188. package/dist/triage/schema.d.ts.map +1 -0
  189. package/dist/triage/schema.js +37 -0
  190. package/dist/triage/schema.js.map +1 -0
  191. package/dist/triage/tiered.d.ts +8 -0
  192. package/dist/triage/tiered.d.ts.map +1 -0
  193. package/dist/triage/tiered.js +47 -0
  194. package/dist/triage/tiered.js.map +1 -0
  195. package/dist/types.d.ts +212 -0
  196. package/dist/types.d.ts.map +1 -0
  197. package/dist/types.js +2 -0
  198. package/dist/types.js.map +1 -0
  199. package/dist/webhook/handler.d.ts +22 -0
  200. package/dist/webhook/handler.d.ts.map +1 -0
  201. package/dist/webhook/handler.js +57 -0
  202. package/dist/webhook/handler.js.map +1 -0
  203. package/dist/webhook/index.d.ts +5 -0
  204. package/dist/webhook/index.d.ts.map +1 -0
  205. package/dist/webhook/index.js +3 -0
  206. package/dist/webhook/index.js.map +1 -0
  207. package/dist/webhook/registrar.d.ts +16 -0
  208. package/dist/webhook/registrar.d.ts.map +1 -0
  209. package/dist/webhook/registrar.js +50 -0
  210. package/dist/webhook/registrar.js.map +1 -0
  211. package/dist/writeback/github.d.ts +6 -0
  212. package/dist/writeback/github.d.ts.map +1 -0
  213. package/dist/writeback/github.js +48 -0
  214. package/dist/writeback/github.js.map +1 -0
  215. package/dist/writeback/index.d.ts +6 -0
  216. package/dist/writeback/index.d.ts.map +1 -0
  217. package/dist/writeback/index.js +4 -0
  218. package/dist/writeback/index.js.map +1 -0
  219. package/dist/writeback/linear.d.ts +41 -0
  220. package/dist/writeback/linear.d.ts.map +1 -0
  221. package/dist/writeback/linear.js +286 -0
  222. package/dist/writeback/linear.js.map +1 -0
  223. package/dist/writeback/shared.d.ts +7 -0
  224. package/dist/writeback/shared.d.ts.map +1 -0
  225. package/dist/writeback/shared.js +29 -0
  226. package/dist/writeback/shared.js.map +1 -0
  227. package/dist/writeback/slack.d.ts +16 -0
  228. package/dist/writeback/slack.d.ts.map +1 -0
  229. package/dist/writeback/slack.js +104 -0
  230. package/dist/writeback/slack.js.map +1 -0
  231. package/package.json +54 -9
  232. package/scripts/com.agentrelay.factory-canary.plist.example +53 -0
  233. package/scripts/factory-canary.sh +89 -0
  234. package/index.d.ts +0 -2
  235. package/index.js +0 -7
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../src/config/schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAKvB,eAAO,MAAM,mBAAmB,sFAMtB,CAAA;AACV,MAAM,MAAM,gBAAgB,GAAG,CAAC,OAAO,mBAAmB,CAAC,CAAC,MAAM,CAAC,CAAA;AAgLnE,eAAO,MAAM,qBAAqB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAAgF,CAAA;AAClH,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAAsE,CAAA;AACnG,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAA4E,CAAA;AA4G5G,MAAM,WAAW,mBAAmB;IAClC,eAAe,EAAE,eAAe,CAAA;IAChC,UAAU,EAAE,UAAU,CAAA;IACtB,aAAa,EAAE,aAAa,CAAA;CAC7B;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,OAAO,GAAG,mBAAmB,CAgBrE;AAuDD,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAAA;AACnE,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAA;AACzD,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAA"}
@@ -0,0 +1,320 @@
1
+ import { z } from 'zod';
2
+ // The five workflow-state roles the factory drives an issue through. Each is
3
+ // configured either by name (config.linear.states.<role>, resolved to a
4
+ // workspace UUID at startup) or by explicit UUID (config.stateIds.<role>).
5
+ export const FACTORY_STATE_ROLES = [
6
+ 'readyForAgent',
7
+ 'agentImplementing',
8
+ 'inPlanning',
9
+ 'done',
10
+ 'humanReview',
11
+ ];
12
+ // A mapping from factory roles to a team's workflow-state NAMES (e.g.
13
+ // readyForAgent -> "Ready for Agent", or "To Do" for a team that names it
14
+ // differently). All optional: unset roles fall back to global/explicit config.
15
+ const linearRoleNamesSchema = z.object({
16
+ readyForAgent: z.string().optional(),
17
+ agentImplementing: z.string().optional(),
18
+ inPlanning: z.string().optional(),
19
+ done: z.string().optional(),
20
+ humanReview: z.string().optional(),
21
+ }).default({});
22
+ const subscriptionSchema = z.object({
23
+ teams: z.array(z.string()).default([]),
24
+ projects: z.array(z.string()).default([]),
25
+ labels: z.array(z.string()).default([]),
26
+ assignees: z.array(z.string()).default([]),
27
+ }).default({});
28
+ const liveSubscriptionSchema = z.object({
29
+ transport: z.enum(['subscribe-and-poll', 'subscribe', 'poll']).default('subscribe-and-poll'),
30
+ pollIntervalMs: z.number().int().min(50).default(5_000),
31
+ eventLimit: z.number().int().min(1).max(1_000).default(1_000),
32
+ replaySkewMarginMs: z.number().int().min(0).default(60_000),
33
+ }).default({});
34
+ const dispatchSchema = z.object({
35
+ errorCooldownMs: z.number().int().min(0).default(60_000),
36
+ maxAttempts: z.number().int().min(1).max(5).default(2),
37
+ }).default({});
38
+ const loopSchema = z.object({
39
+ maxIterations: z.number().int().min(1).max(5).default(3),
40
+ maxConsecutiveFailures: z.number().int().min(1).max(5).default(3),
41
+ heartbeatPath: z.string().min(1).default('/tmp/factory-run/factory-loop-heartbeat.json'),
42
+ registryPath: z.string().min(1).default('/tmp/factory-run/factory-loop-registry.json'),
43
+ heartbeatStaleMs: z.number().int().min(1_000).default(60_000),
44
+ }).default({});
45
+ const triageSchema = z.object({
46
+ maxImplementers: z.number().int().min(1).max(6).default(2),
47
+ }).default({});
48
+ const workspaceReposSchema = z.object({
49
+ // Compact, single-source repo config. Most setups only need these: `names`
50
+ // is the label/repo list, and byLabel + clonePaths + subscription.labels are
51
+ // derived from them at parse time (see the transform below).
52
+ // byLabel[name] = overrides[name] ?? `${org}/${name}`
53
+ // clonePaths[repo] = `${cloneRoot}/${repoName}`
54
+ org: z.string().optional(),
55
+ names: z.array(z.string()).optional(),
56
+ overrides: z.record(z.string(), z.string()).default({}),
57
+ // Explicit forms remain supported as an escape hatch and are merged over the
58
+ // derived maps (explicit entries win). byLabel is optional now that it can be
59
+ // derived from `names`.
60
+ byLabel: z.record(z.string(), z.string()).default({}),
61
+ byProject: z.record(z.string(), z.string()).default({}),
62
+ keywordRules: z.array(z.object({ pattern: z.string(), repo: z.string() })).default([]),
63
+ default: z.string().optional(),
64
+ // Legacy/node-local repo checkout inputs accepted by the composed schema.
65
+ // WorkspaceConfig strips them; FactoryConfig uses them to preserve #369.
66
+ cloneRoot: z.string().optional(),
67
+ clonePaths: z.record(z.string(), z.string()).default({}),
68
+ });
69
+ const modelsSchema = z.object({
70
+ implementer: z.string().optional(),
71
+ reviewer: z.string().optional(),
72
+ triage: z.string().optional(),
73
+ // The PR babysitter defaults to sonnet — it shepherds an already-open PR
74
+ // (CI/conflicts/comments) rather than authoring from scratch, so the
75
+ // mid-tier model is the deliberate default rather than the implementer/
76
+ // reviewer's unset (inherit) behavior.
77
+ babysitter: z.string().default('sonnet'),
78
+ }).default({});
79
+ const slackSchema = z.object({
80
+ channel: z.string(),
81
+ style: z.literal('threaded-summarized').default('threaded-summarized'),
82
+ botUserId: z.string().default('U0B2596R7EZ'),
83
+ staleAfterMs: z.number().int().min(1_000).default(10 * 60_000),
84
+ }).optional();
85
+ const babysitterSchema = z.object({
86
+ enabled: z.boolean().default(false),
87
+ }).default({});
88
+ // The factory owns its workflow-state NAME conventions; consumers (e.g. pear)
89
+ // don't hand-configure them. These names let the factory resolve a role from a
90
+ // synced record that carries state.name but no state.id (sparse-sync fallback).
91
+ // A workspace that names states differently can override via config.
92
+ const DEFAULT_LINEAR_STATE_NAMES = {
93
+ readyForAgent: 'Ready for Agent',
94
+ agentImplementing: 'Agent Implementing',
95
+ done: 'Done',
96
+ inPlanning: 'In Planning',
97
+ humanReview: 'In Human Review',
98
+ };
99
+ const linearSchema = z.object({
100
+ states: linearRoleNamesSchema.default(DEFAULT_LINEAR_STATE_NAMES),
101
+ statesByTeam: z.record(z.string(), linearRoleNamesSchema).default({}),
102
+ }).default({ states: DEFAULT_LINEAR_STATE_NAMES, statesByTeam: {} });
103
+ const stateIdsSchema = z.object({
104
+ readyForAgent: z.string().optional(),
105
+ agentImplementing: z.string().optional(),
106
+ done: z.string().optional(),
107
+ inPlanning: z.string().optional(),
108
+ humanReview: z.string().optional(),
109
+ }).default({});
110
+ const safetySchema = z.object({
111
+ requireTitlePrefix: z.string().min(1).default('[factory-e2e]'),
112
+ requireLabel: z.string().default('factory'),
113
+ requireTeamKey: z.string().min(1).default('AR'),
114
+ }).default({});
115
+ const WorkspaceConfigObjectSchema = z.object({
116
+ // Optional. When omitted, the CLI derives the workspace from the cloud session
117
+ // via `resolveActiveWorkspace()` (returns the active `relayfileWorkspaceId`),
118
+ // falling back to the SDK's built-in default. Set it only to pin a non-active
119
+ // workspace. See resolveFactoryWorkspace() in relayfile-cloud-mount-client.ts.
120
+ workspaceId: z.string().optional(),
121
+ subscription: subscriptionSchema,
122
+ liveSubscription: liveSubscriptionSchema,
123
+ dispatch: dispatchSchema,
124
+ loop: loopSchema,
125
+ triage: triageSchema,
126
+ repos: workspaceReposSchema,
127
+ batchSize: z.number().int().min(1).max(5).default(5),
128
+ models: modelsSchema,
129
+ slack: slackSchema,
130
+ mergePolicy: z.enum(['never', 'on-green-with-review']).default('never'),
131
+ // Opt-in PR babysitter. When enabled, a sonnet agent is spawned once the
132
+ // implementer's PR opens (webhook-driven, see the orchestrator) and shepherds
133
+ // it — addressing review comments, resolving conflicts, and fixing CI — until
134
+ // it is green, then transitions the issue to the `human-review` terminal state
135
+ // instead of jumping straight to `done`. Default off preserves the legacy
136
+ // PR-open -> done behavior.
137
+ babysitter: babysitterSchema,
138
+ // Which Linear state an issue lands in once the agents finish and the PR is
139
+ // open. `human-review` parks it for operator review (Done is reserved for the
140
+ // actual merge); `done` is the legacy behavior. Only honored when the
141
+ // `humanReview` role resolves to a state — otherwise it falls back to `done`.
142
+ terminalState: z.enum(['done', 'human-review']).default('human-review'),
143
+ // Dynamic, workspace-agnostic Linear configuration. Nothing about state names
144
+ // or UUIDs is hardcoded — customers map the factory's semantic roles to
145
+ // whatever their teams call those states, and the names are resolved to UUIDs
146
+ // at startup against /linear/states (see resolveFactoryStates).
147
+ //
148
+ // `states` is the workspace-wide default mapping; `statesByTeam.<TEAM>`
149
+ // overrides individual roles for teams that name their states differently
150
+ // (resolution per issue uses the issue's team, falling back to `states`).
151
+ linear: linearSchema,
152
+ // Explicit workflow-state UUIDs. Lowest-precedence fallback / single-team
153
+ // escape hatch for setups that prefer pinning ids over name resolution; any
154
+ // role resolved by name (per-team or global) takes precedence. Populated in
155
+ // place once resolution runs, so the orchestrator always sees concrete UUIDs.
156
+ stateIds: stateIdsSchema,
157
+ safety: safetySchema,
158
+ });
159
+ const NodeConfigObjectSchema = z.object({
160
+ workspaceId: z.string().optional(),
161
+ capabilities: z.array(z.string()).default([]),
162
+ cloneRoot: z.string().optional(),
163
+ clonePaths: z.record(z.string(), z.string()).default({}),
164
+ dryRun: z.boolean().default(false),
165
+ factoryLoopHeartbeatPath: z.string().min(1).optional(),
166
+ factoryLoopRegistryPath: z.string().min(1).optional(),
167
+ });
168
+ const FactoryConfigObjectSchema = WorkspaceConfigObjectSchema.merge(NodeConfigObjectSchema);
169
+ export const WorkspaceConfigSchema = WorkspaceConfigObjectSchema.transform((cfg) => normalizeWorkspaceConfig(cfg));
170
+ export const NodeConfigSchema = NodeConfigObjectSchema.transform((cfg) => normalizeNodeConfig(cfg));
171
+ export const FactoryConfigSchema = FactoryConfigObjectSchema.transform((cfg) => normalizeFactoryConfig(cfg));
172
+ function normalizeWorkspaceConfig(cfg) {
173
+ const resolved = resolveRepos(cfg.repos, cfg.repos.cloneRoot);
174
+ const labels = resolveSubscriptionLabels(cfg.subscription.labels, cfg.repos.names ?? []);
175
+ const { cloneRoot: _legacyCloneRoot, clonePaths: _legacyClonePaths, ...repos } = cfg.repos;
176
+ return {
177
+ ...cfg,
178
+ subscription: { ...cfg.subscription, labels },
179
+ repos: {
180
+ ...repos,
181
+ byLabel: resolved.byLabel,
182
+ byProject: resolved.byProject,
183
+ keywordRules: resolved.keywordRules,
184
+ ...(resolved.defaultRepo !== undefined ? { default: resolved.defaultRepo } : {}),
185
+ },
186
+ };
187
+ }
188
+ function normalizeNodeConfig(cfg) {
189
+ return {
190
+ ...cfg,
191
+ factoryLoopHeartbeatPath: cfg.factoryLoopHeartbeatPath,
192
+ factoryLoopRegistryPath: cfg.factoryLoopRegistryPath,
193
+ };
194
+ }
195
+ function normalizeFactoryConfig(cfg) {
196
+ const cloneRoot = cfg.cloneRoot ?? cfg.repos.cloneRoot;
197
+ const explicitClonePaths = {
198
+ ...cfg.repos.clonePaths,
199
+ ...cfg.clonePaths,
200
+ };
201
+ const resolved = resolveRepos(cfg.repos, cloneRoot, explicitClonePaths);
202
+ const labels = resolveSubscriptionLabels(cfg.subscription.labels, cfg.repos.names ?? []);
203
+ const heartbeatPath = cfg.factoryLoopHeartbeatPath ?? cfg.loop.heartbeatPath;
204
+ const registryPath = cfg.factoryLoopRegistryPath ?? cfg.loop.registryPath;
205
+ return {
206
+ ...cfg,
207
+ cloneRoot,
208
+ clonePaths: resolved.clonePaths,
209
+ factoryLoopHeartbeatPath: heartbeatPath,
210
+ factoryLoopRegistryPath: registryPath,
211
+ subscription: { ...cfg.subscription, labels },
212
+ loop: {
213
+ ...cfg.loop,
214
+ heartbeatPath,
215
+ registryPath,
216
+ },
217
+ repos: {
218
+ byLabel: resolved.byLabel,
219
+ byProject: resolved.byProject,
220
+ keywordRules: resolved.keywordRules,
221
+ clonePaths: resolved.clonePaths,
222
+ ...(resolved.defaultRepo !== undefined ? { default: resolved.defaultRepo } : {}),
223
+ },
224
+ };
225
+ }
226
+ function resolveRepos(repos, cloneRoot, explicitClonePaths = repos.clonePaths) {
227
+ const { org, names, overrides, byLabel, byProject, keywordRules, default: defaultRepo } = repos;
228
+ const repoNames = names ?? [];
229
+ // Derive byLabel from `names` (label === repo name): overrides[name] wins,
230
+ // else `${org}/${name}` when an org is set, else the bare name. Explicit
231
+ // byLabel entries are merged last so they always win.
232
+ const derivedByLabel = {};
233
+ for (const name of repoNames) {
234
+ derivedByLabel[name] = overrides[name] ?? (org ? `${org}/${name}` : name);
235
+ }
236
+ const resolvedByLabel = { ...derivedByLabel, ...byLabel };
237
+ // Derive clonePaths as `${cloneRoot}/${repoName}` for every routed repo.
238
+ // Explicit clonePaths entries win.
239
+ const derivedClonePaths = {};
240
+ if (cloneRoot) {
241
+ const root = cloneRoot.replace(/\/+$/u, '');
242
+ for (const repo of Object.values(resolvedByLabel)) {
243
+ const repoName = repo.includes('/') ? repo.slice(repo.lastIndexOf('/') + 1) : repo;
244
+ derivedClonePaths[repo] = `${root}/${repoName}`;
245
+ }
246
+ }
247
+ const resolvedClonePaths = { ...derivedClonePaths, ...explicitClonePaths };
248
+ return {
249
+ byLabel: resolvedByLabel,
250
+ byProject,
251
+ keywordRules,
252
+ clonePaths: resolvedClonePaths,
253
+ defaultRepo,
254
+ };
255
+ }
256
+ function resolveSubscriptionLabels(labels, repoNames) {
257
+ return labels.length > 0 ? labels : repoNames;
258
+ }
259
+ export function loadFactoryConfig(input) {
260
+ const record = asConfigRecord(input);
261
+ const hasSplit = Object.prototype.hasOwnProperty.call(record, 'workspaceConfig') ||
262
+ Object.prototype.hasOwnProperty.call(record, 'nodeConfig');
263
+ if (hasSplit) {
264
+ if (!Object.prototype.hasOwnProperty.call(record, 'workspaceConfig')) {
265
+ throw new Error('split factory config requires workspaceConfig');
266
+ }
267
+ if (!Object.prototype.hasOwnProperty.call(record, 'nodeConfig')) {
268
+ throw new Error('split factory config requires nodeConfig');
269
+ }
270
+ return normalizeLoadedConfig(combineSplitConfigInput(record.workspaceConfig, record.nodeConfig));
271
+ }
272
+ return normalizeLoadedConfig(record.factoryConfig ?? input);
273
+ }
274
+ function normalizeLoadedConfig(input) {
275
+ const factoryConfig = FactoryConfigSchema.parse(input);
276
+ const workspaceConfig = WorkspaceConfigSchema.parse(factoryConfig);
277
+ const nodeConfig = NodeConfigSchema.parse({
278
+ workspaceId: factoryConfig.workspaceId,
279
+ capabilities: factoryConfig.capabilities,
280
+ cloneRoot: factoryConfig.cloneRoot,
281
+ clonePaths: factoryConfig.clonePaths,
282
+ dryRun: factoryConfig.dryRun,
283
+ factoryLoopHeartbeatPath: factoryConfig.loop.heartbeatPath,
284
+ factoryLoopRegistryPath: factoryConfig.loop.registryPath,
285
+ });
286
+ return { workspaceConfig, nodeConfig, factoryConfig };
287
+ }
288
+ function combineSplitConfigInput(workspaceInput, nodeInput) {
289
+ const workspace = asConfigRecord(workspaceInput);
290
+ const node = asConfigRecord(nodeInput);
291
+ const workspaceRepos = asOptionalConfigRecord(workspace.repos);
292
+ assertCompatibleWorkspaceIds(workspace.workspaceId, node.workspaceId);
293
+ return {
294
+ ...workspace,
295
+ ...node,
296
+ repos: {
297
+ ...workspaceRepos,
298
+ cloneRoot: node.cloneRoot ?? workspaceRepos.cloneRoot,
299
+ clonePaths: node.clonePaths ?? workspaceRepos.clonePaths,
300
+ },
301
+ };
302
+ }
303
+ function assertCompatibleWorkspaceIds(workspaceId, nodeWorkspaceId) {
304
+ if (typeof workspaceId === 'string' &&
305
+ typeof nodeWorkspaceId === 'string' &&
306
+ workspaceId !== nodeWorkspaceId) {
307
+ throw new Error(`split factory config workspaceId mismatch: workspaceConfig=${workspaceId} nodeConfig=${nodeWorkspaceId}`);
308
+ }
309
+ }
310
+ function asConfigRecord(value) {
311
+ if (value && typeof value === 'object' && !Array.isArray(value))
312
+ return value;
313
+ throw new Error('factory config must be a JSON object');
314
+ }
315
+ function asOptionalConfigRecord(value) {
316
+ if (value === undefined)
317
+ return {};
318
+ return asConfigRecord(value);
319
+ }
320
+ //# sourceMappingURL=schema.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema.js","sourceRoot":"","sources":["../../src/config/schema.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ export declare const linearIssuePath: (key: string, uuid: string) => string;
2
+ export declare const linearByStatePath: (slug: string) => string;
3
+ export declare const linearByIdPath: (key: string) => string;
4
+ export declare const linearByUuidPath: (uuid: string) => string;
5
+ export declare const linearCommentPath: (issuePath: string, name: string) => string;
6
+ //# sourceMappingURL=linear.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"linear.d.ts","sourceRoot":"","sources":["../../src/constants/linear.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,eAAe,GAAI,KAAK,MAAM,EAAE,MAAM,MAAM,WAA0C,CAAA;AAEnG,eAAO,MAAM,iBAAiB,GAAI,MAAM,MAAM,WAAuC,CAAA;AAMrF,eAAO,MAAM,cAAc,GAAI,KAAK,MAAM,WAAuC,CAAA;AAEjF,eAAO,MAAM,gBAAgB,GAAI,MAAM,MAAM,WAA0C,CAAA;AAOvF,eAAO,MAAM,iBAAiB,GAAI,WAAW,MAAM,EAAE,MAAM,MAAM,WAGhE,CAAA"}
@@ -0,0 +1,21 @@
1
+ // Workflow-state UUIDs are NOT hardcoded — they differ per workspace/team and
2
+ // are resolved at runtime from /linear/states by name (see resolveFactoryStates)
3
+ // or pinned explicitly via config.stateIds.
4
+ export const linearIssuePath = (key, uuid) => `/linear/issues/${key}__${uuid}.json`;
5
+ export const linearByStatePath = (slug) => `/linear/issues/by-state/${slug}/`;
6
+ // Canonical record aliases. The active-issues sync writes the full issue body
7
+ // to these stable lookup paths while the primary <key>__<uuid>.json path may
8
+ // hold only a change-event STUB. The factory reads these when the primary
9
+ // parses empty (see readLinearIssueWithCanonicalFallback).
10
+ export const linearByIdPath = (key) => `/linear/issues/by-id/${key}.json`;
11
+ export const linearByUuidPath = (uuid) => `/linear/issues/by-uuid/${uuid}.json`;
12
+ // Comment writeback must be nested under its issue — the relayfile cloud
13
+ // writeback executor only accepts /linear/issues/<issueRef>/comments/<draft>.json
14
+ // (top-level /linear/comments/<name>.json is rejected as "unsupported Linear
15
+ // writeback path"). issuePath is /linear/issues/<key>__<uuid>.json, so the
16
+ // issueRef segment is its basename.
17
+ export const linearCommentPath = (issuePath, name) => {
18
+ const issueRef = issuePath.replace(/^\/linear\/issues\//u, '').replace(/\.json$/u, '');
19
+ return `/linear/issues/${issueRef}/comments/${name}.json`;
20
+ };
21
+ //# sourceMappingURL=linear.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"linear.js","sourceRoot":"","sources":["../../src/constants/linear.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAC9E,iFAAiF;AACjF,4CAA4C;AAE5C,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,GAAW,EAAE,IAAY,EAAE,EAAE,CAAC,kBAAkB,GAAG,KAAK,IAAI,OAAO,CAAA;AAEnG,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,IAAY,EAAE,EAAE,CAAC,2BAA2B,IAAI,GAAG,CAAA;AAErF,8EAA8E;AAC9E,6EAA6E;AAC7E,0EAA0E;AAC1E,2DAA2D;AAC3D,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,GAAW,EAAE,EAAE,CAAC,wBAAwB,GAAG,OAAO,CAAA;AAEjF,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,IAAY,EAAE,EAAE,CAAC,0BAA0B,IAAI,OAAO,CAAA;AAEvF,yEAAyE;AACzE,kFAAkF;AAClF,6EAA6E;AAC7E,2EAA2E;AAC3E,oCAAoC;AACpC,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,SAAiB,EAAE,IAAY,EAAE,EAAE;IACnE,MAAM,QAAQ,GAAG,SAAS,CAAC,OAAO,CAAC,sBAAsB,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAA;IACtF,OAAO,kBAAkB,QAAQ,aAAa,IAAI,OAAO,CAAA;AAC3D,CAAC,CAAA"}
@@ -0,0 +1,3 @@
1
+ export declare const slackMessagePath: (channelDir: string, clientId: string) => string;
2
+ export declare const slackReplyPath: (channelDir: string, parentTs: string, clientId: string) => string;
3
+ //# sourceMappingURL=slack.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"slack.d.ts","sourceRoot":"","sources":["../../src/constants/slack.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,gBAAgB,GAAI,YAAY,MAAM,EAAE,UAAU,MAAM,WACV,CAAA;AAE3D,eAAO,MAAM,cAAc,GAAI,YAAY,MAAM,EAAE,UAAU,MAAM,EAAE,UAAU,MAAM,WACN,CAAA"}
@@ -0,0 +1,3 @@
1
+ export const slackMessagePath = (channelDir, clientId) => `/slack/channels/${channelDir}/messages/${clientId}.json`;
2
+ export const slackReplyPath = (channelDir, parentTs, clientId) => `/slack/channels/${channelDir}/messages/${parentTs}/replies/${clientId}.json`;
3
+ //# sourceMappingURL=slack.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"slack.js","sourceRoot":"","sources":["../../src/constants/slack.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,UAAkB,EAAE,QAAgB,EAAE,EAAE,CACvE,mBAAmB,UAAU,aAAa,QAAQ,OAAO,CAAA;AAE3D,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,UAAkB,EAAE,QAAgB,EAAE,QAAgB,EAAE,EAAE,CACvF,mBAAmB,UAAU,aAAa,QAAQ,YAAY,QAAQ,OAAO,CAAA"}
@@ -0,0 +1,52 @@
1
+ import type { FactoryConfig } from '../config/schema.js';
2
+ import type { AgentSpec } from '../ports/fleet.js';
3
+ export interface TemplateIssue {
4
+ key: string;
5
+ title: string;
6
+ description: string;
7
+ }
8
+ export interface TemplateRoute {
9
+ repo: string;
10
+ clonePath?: string;
11
+ rationale?: string;
12
+ }
13
+ export interface TemplatePr {
14
+ number: number;
15
+ url?: string;
16
+ }
17
+ export interface RenderAgentTaskInput {
18
+ issue: TemplateIssue;
19
+ route: TemplateRoute;
20
+ role: AgentSpec['role'];
21
+ config: Pick<FactoryConfig, 'mergePolicy' | 'terminalState'>;
22
+ reviewerName: string;
23
+ implementerNames?: string[];
24
+ /** The already-open PR the babysitter shepherds. Only used for the babysitter role. */
25
+ pr?: TemplatePr;
26
+ slackDispatchThread?: {
27
+ channel: string;
28
+ threadId: string;
29
+ /**
30
+ * Absolute path to the .integrations mount root the agent can write to. The
31
+ * agent runs in its repo clonePath, NOT the daemon's cwd where .integrations
32
+ * lives, so a bare relative `.integrations/...` path is unreachable — the
33
+ * writeback path must be absolute.
34
+ */
35
+ mountRoot: string;
36
+ };
37
+ /** Pre-rendered writeback instructions for connected integrations. */
38
+ integrationInstructions?: string;
39
+ /**
40
+ * Absolute path to the .integrations mount root. The agent runs in its repo
41
+ * clonePath, not the daemon cwd where .integrations lives, so every
42
+ * `.integrations/...` reference (github reads, slack writes) must be absolute.
43
+ * Falls back to the bare relative root when absent (e.g. tests).
44
+ */
45
+ integrationsMountRoot?: string;
46
+ }
47
+ export declare function renderAgentTask(input: RenderAgentTaskInput): string;
48
+ export declare function agentSpecWithRenderedTask(spec: Omit<AgentSpec, 'task'> & {
49
+ task?: string;
50
+ }, input: RenderAgentTaskInput): AgentSpec;
51
+ export declare function mergePolicyLine(policy: FactoryConfig['mergePolicy']): string;
52
+ //# sourceMappingURL=templates.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"templates.d.ts","sourceRoot":"","sources":["../../src/dispatch/templates.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAA;AACrD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAE/C,MAAM,WAAW,aAAa;IAC5B,GAAG,EAAE,MAAM,CAAA;IACX,KAAK,EAAE,MAAM,CAAA;IACb,WAAW,EAAE,MAAM,CAAA;CACpB;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAA;IACZ,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,MAAM,CAAA;IACd,GAAG,CAAC,EAAE,MAAM,CAAA;CACb;AAED,MAAM,WAAW,oBAAoB;IACnC,KAAK,EAAE,aAAa,CAAA;IACpB,KAAK,EAAE,aAAa,CAAA;IACpB,IAAI,EAAE,SAAS,CAAC,MAAM,CAAC,CAAA;IACvB,MAAM,EAAE,IAAI,CAAC,aAAa,EAAE,aAAa,GAAG,eAAe,CAAC,CAAA;IAC5D,YAAY,EAAE,MAAM,CAAA;IACpB,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAA;IAC3B,uFAAuF;IACvF,EAAE,CAAC,EAAE,UAAU,CAAA;IACf,mBAAmB,CAAC,EAAE;QACpB,OAAO,EAAE,MAAM,CAAA;QACf,QAAQ,EAAE,MAAM,CAAA;QAChB;;;;;WAKG;QACH,SAAS,EAAE,MAAM,CAAA;KAClB,CAAA;IACD,sEAAsE;IACtE,uBAAuB,CAAC,EAAE,MAAM,CAAA;IAChC;;;;;OAKG;IACH,qBAAqB,CAAC,EAAE,MAAM,CAAA;CAC/B;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,oBAAoB,GAAG,MAAM,CA0GnE;AAED,wBAAgB,yBAAyB,CACvC,IAAI,EAAE,IAAI,CAAC,SAAS,EAAE,MAAM,CAAC,GAAG;IAAE,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,EACjD,KAAK,EAAE,oBAAoB,GAC1B,SAAS,CAKX;AAED,wBAAgB,eAAe,CAAC,MAAM,EAAE,aAAa,CAAC,aAAa,CAAC,GAAG,MAAM,CAM5E"}
@@ -0,0 +1,118 @@
1
+ export function renderAgentTask(input) {
2
+ const repo = normalizeRepo(input.route.repo);
3
+ // Absolute mount root for every .integrations reference (the agent's cwd is
4
+ // its repo clone, where a relative .integrations/... does not resolve).
5
+ const mountRoot = input.integrationsMountRoot ?? '.integrations';
6
+ const cloneInstruction = input.route.clonePath
7
+ ? `Repo path: ${input.route.clonePath}`
8
+ : `Clone/worktree: clone AgentWorkforce/${repo} and work in your own isolated git worktree before editing.`;
9
+ const implementers = input.implementerNames?.length ? input.implementerNames.join(', ') : 'the implementer(s)';
10
+ const header = [
11
+ `GitHub repo: AgentWorkforce/${repo}`,
12
+ cloneInstruction,
13
+ `Linear issue: ${input.issue.key} - ${input.issue.title}`,
14
+ 'Full Linear issue description:',
15
+ input.issue.description,
16
+ ];
17
+ const common = [
18
+ ...header,
19
+ '',
20
+ 'Create a branch for this issue before editing.',
21
+ 'Commit the implementation and tests.',
22
+ 'Push the branch to origin.',
23
+ 'Open a PR targeting `main` when done.',
24
+ 'Use `gh pr create --base main` and report the PR URL.',
25
+ `DM the reviewer \`${input.reviewerName}\` when the PR is ready.`,
26
+ 'If blocked and you need human input, write to the .integrations mount path so the factory can relay it to the issue thread.',
27
+ 'DM `broker` when fully done.',
28
+ 'Do NOT auto-merge.',
29
+ mergePolicyLine(input.config.mergePolicy),
30
+ ];
31
+ const questionInstructions = input.slackDispatchThread
32
+ ? [
33
+ '',
34
+ 'If you are blocked or need a human answer mid-task, write your question to this issue\'s Slack dispatch thread via the .integrations mount.',
35
+ // Absolute path: the agent runs in its repo clone, not the daemon cwd
36
+ // where .integrations lives, so a relative path would be unreachable.
37
+ `Write path: ${input.slackDispatchThread.mountRoot}/slack/channels/${input.slackDispatchThread.channel}/messages/${input.slackDispatchThread.threadId.replaceAll('.', '_')}/replies/question.json`,
38
+ 'Write a JSON object with a "text" field containing your question.',
39
+ 'The human\'s reply will be delivered to you as an `<integration-event>` system message injected into your session — wait for it, do not poll.',
40
+ 'Continue with safe reversible work while waiting for a reply.',
41
+ ]
42
+ : [];
43
+ if (input.role === 'babysitter') {
44
+ const prRef = input.pr
45
+ ? `PR #${input.pr.number}${input.pr.url ? ` (${input.pr.url})` : ''}`
46
+ : 'the open PR for this issue';
47
+ const chatLine = input.slackDispatchThread
48
+ ? `You can also use this issue's Slack dispatch thread to discuss the PR with the human (status, trade-offs, open questions) — proactively write via ${mountRoot}/slack if it would help.`
49
+ : 'If a human can be reached, proactively offer to discuss the PR (status, trade-offs, open questions) via the .integrations writeback path.';
50
+ // Match the prompt to where the issue actually lands so the babysitter is not
51
+ // told to "stop at Human Review" while the factory is configured to finish at
52
+ // Done (and possibly auto-merge under on-green-with-review).
53
+ const humanReview = input.config.terminalState === 'human-review';
54
+ const destination = humanReview ? 'Human Review' : 'Done';
55
+ const jobLine = humanReview
56
+ ? 'Your job: drive this PR to genuinely green and correct against the Linear issue spec above, then hand it to a human for review. Do NOT merge it yourself.'
57
+ : 'Your job: drive this PR to genuinely green and correct against the Linear issue spec above so the factory can finish it. Do NOT merge it yourself.';
58
+ const finishLine = humanReview
59
+ ? 'Do NOT auto-merge; stop at Human Review — a human owns the merge.'
60
+ : input.config.mergePolicy === 'on-green-with-review'
61
+ ? 'Do NOT merge it yourself; the factory runs the guarded merge gate once you signal ready.'
62
+ : 'Do NOT merge it yourself; the factory moves the issue to Done once you signal ready.';
63
+ return [
64
+ ...header,
65
+ '',
66
+ `You are the PR babysitter for ${input.issue.key}. A PR is already open: ${prRef}.`,
67
+ jobLine,
68
+ 'Unlike a conservative reviewer, you SHOULD fix things directly and aggressively — you hold the original issue spec as the definition of done, and you have the rest of the dispatched team to draw on.',
69
+ `Read the PR diff, CI checks, and review threads via ${mountRoot}/github/repos.`,
70
+ 'Address every review comment for real — make substantive code changes when the feedback calls for it, not just lint/format touch-ups.',
71
+ 'Resolve any merge conflicts: rebase onto the base branch and reconcile using judgment anchored in the issue spec; never weaken tests or flip safety defaults just to force a merge.',
72
+ 'Fix failing CI — change the code and tests as needed until the checks pass. A red check is not done.',
73
+ `Coordinate the team when it helps: DM the implementer(s) (${implementers}) or the reviewer \`${input.reviewerName}\` to delegate or pull context. Prefer fixing it yourself; loop them in when you are stuck or it is clearly their area.`,
74
+ 'Commit and push your fixes to the PR branch.',
75
+ chatLine,
76
+ `When the PR is green — no failing CI, no merge conflicts, every review comment addressed — DM \`factory\` with \`[factory-pr-ready] ${input.issue.key}\` so the factory can move the issue to ${destination}.`,
77
+ 'DM `broker` when fully done.',
78
+ finishLine,
79
+ mergePolicyLine(input.config.mergePolicy),
80
+ ...questionInstructions,
81
+ ...(input.integrationInstructions ? ['', input.integrationInstructions] : []),
82
+ ].join('\n');
83
+ }
84
+ if (input.role === 'reviewer') {
85
+ return [
86
+ ...common,
87
+ ...questionInstructions,
88
+ '',
89
+ `Wait for a DM from the implementer(s): ${implementers}.`,
90
+ `Read the PR diff via ${mountRoot}/github/repos.`,
91
+ 'Post review comments via the GitHub writeback path.',
92
+ 'DM the implementer with specific feedback if changes needed, or approve if good.',
93
+ 'DM `broker` when the review cycle is complete.',
94
+ ...(input.integrationInstructions ? ['', input.integrationInstructions] : []),
95
+ ].join('\n');
96
+ }
97
+ return [
98
+ ...common,
99
+ ...questionInstructions,
100
+ ...(input.integrationInstructions ? ['', input.integrationInstructions] : []),
101
+ ].join('\n');
102
+ }
103
+ export function agentSpecWithRenderedTask(spec, input) {
104
+ return {
105
+ ...spec,
106
+ task: renderAgentTask(input),
107
+ };
108
+ }
109
+ export function mergePolicyLine(policy) {
110
+ if (policy === 'on-green-with-review') {
111
+ return 'Merge policy: on-green-with-review - do not merge until checks are green and review approval is present.';
112
+ }
113
+ return 'Merge policy: never - open the PR for human review and approval; never merge it yourself.';
114
+ }
115
+ function normalizeRepo(repo) {
116
+ return repo.startsWith('AgentWorkforce/') ? repo.slice('AgentWorkforce/'.length) : repo;
117
+ }
118
+ //# sourceMappingURL=templates.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"templates.js","sourceRoot":"","sources":["../../src/dispatch/templates.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ import { InternalFleetClient, type HarnessDriverClientLike } from './internal-fleet-client.js';
2
+ import { RelayFleetClient } from './relay-fleet-client.js';
3
+ export type FleetBackend = 'internal' | 'relay';
4
+ export interface CreateFleetOptions {
5
+ backend?: FleetBackend;
6
+ cwd?: string;
7
+ connectionPath?: string;
8
+ }
9
+ export interface CreateFleetDeps {
10
+ harnessClient?: HarnessDriverClientLike;
11
+ ownsBroker?: boolean;
12
+ }
13
+ export declare function createFleet(options?: CreateFleetOptions, deps?: CreateFleetDeps): InternalFleetClient | RelayFleetClient;
14
+ //# sourceMappingURL=create-fleet.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create-fleet.d.ts","sourceRoot":"","sources":["../../src/fleet/create-fleet.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,KAAK,uBAAuB,EAAE,MAAM,yBAAyB,CAAA;AAC3F,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAA;AAEvD,MAAM,MAAM,YAAY,GAAG,UAAU,GAAG,OAAO,CAAA;AAE/C,MAAM,WAAW,kBAAkB;IACjC,OAAO,CAAC,EAAE,YAAY,CAAA;IACtB,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,cAAc,CAAC,EAAE,MAAM,CAAA;CACxB;AAED,MAAM,WAAW,eAAe;IAC9B,aAAa,CAAC,EAAE,uBAAuB,CAAA;IAGvC,UAAU,CAAC,EAAE,OAAO,CAAA;CACrB;AAED,wBAAgB,WAAW,CAAC,OAAO,GAAE,kBAAuB,EAAE,IAAI,GAAE,eAAoB,0CAavF"}
@@ -0,0 +1,15 @@
1
+ import { InternalFleetClient } from './internal-fleet-client.js';
2
+ import { RelayFleetClient } from './relay-fleet-client.js';
3
+ export function createFleet(options = {}, deps = {}) {
4
+ const backend = options.backend ?? 'internal';
5
+ if (backend === 'relay') {
6
+ return new RelayFleetClient();
7
+ }
8
+ return new InternalFleetClient({
9
+ client: deps.harnessClient,
10
+ ownsBroker: deps.ownsBroker,
11
+ cwd: options.cwd,
12
+ connectionPath: options.connectionPath,
13
+ });
14
+ }
15
+ //# sourceMappingURL=create-fleet.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create-fleet.js","sourceRoot":"","sources":["../../src/fleet/create-fleet.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAgC,MAAM,yBAAyB,CAAA;AAC3F,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAA;AAiBvD,MAAM,UAAU,WAAW,CAAC,UAA8B,EAAE,EAAE,OAAwB,EAAE;IACtF,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,IAAI,UAAU,CAAA;IAE7C,IAAI,OAAO,KAAK,OAAO,EAAE,CAAC;QACxB,OAAO,IAAI,gBAAgB,EAAE,CAAA;IAC/B,CAAC;IAED,OAAO,IAAI,mBAAmB,CAAC;QAC7B,MAAM,EAAE,IAAI,CAAC,aAAa;QAC1B,UAAU,EAAE,IAAI,CAAC,UAAU;QAC3B,GAAG,EAAE,OAAO,CAAC,GAAG;QAChB,cAAc,EAAE,OAAO,CAAC,cAAc;KACvC,CAAC,CAAA;AACJ,CAAC"}