@agent-relay/factory 0.0.0 → 0.1.1

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 (221) hide show
  1. package/README.md +240 -22
  2. package/bin/factory.mjs +7 -0
  3. package/dist/cli/fleet.d.ts +77 -0
  4. package/dist/cli/fleet.d.ts.map +1 -0
  5. package/dist/cli/fleet.js +500 -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 +309 -0
  10. package/dist/config/schema.js.map +1 -0
  11. package/dist/constants/linear.d.ts +4 -0
  12. package/dist/constants/linear.d.ts.map +1 -0
  13. package/dist/constants/linear.js +15 -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 +36 -0
  20. package/dist/dispatch/templates.d.ts.map +1 -0
  21. package/dist/dispatch/templates.js +110 -0
  22. package/dist/dispatch/templates.js.map +1 -0
  23. package/dist/fleet/create-fleet.d.ts +13 -0
  24. package/dist/fleet/create-fleet.d.ts.map +1 -0
  25. package/dist/fleet/create-fleet.js +14 -0
  26. package/dist/fleet/create-fleet.js.map +1 -0
  27. package/dist/fleet/internal-fleet-client.d.ts +85 -0
  28. package/dist/fleet/internal-fleet-client.d.ts.map +1 -0
  29. package/dist/fleet/internal-fleet-client.js +575 -0
  30. package/dist/fleet/internal-fleet-client.js.map +1 -0
  31. package/dist/fleet/relay-fleet-client.d.ts +28 -0
  32. package/dist/fleet/relay-fleet-client.d.ts.map +1 -0
  33. package/dist/fleet/relay-fleet-client.js +33 -0
  34. package/dist/fleet/relay-fleet-client.js.map +1 -0
  35. package/dist/github/index.d.ts +5 -0
  36. package/dist/github/index.d.ts.map +1 -0
  37. package/dist/github/index.js +3 -0
  38. package/dist/github/index.js.map +1 -0
  39. package/dist/github/merge-gate.d.ts +47 -0
  40. package/dist/github/merge-gate.d.ts.map +1 -0
  41. package/dist/github/merge-gate.js +147 -0
  42. package/dist/github/merge-gate.js.map +1 -0
  43. package/dist/github/probe-closer.d.ts +15 -0
  44. package/dist/github/probe-closer.d.ts.map +1 -0
  45. package/dist/github/probe-closer.js +67 -0
  46. package/dist/github/probe-closer.js.map +1 -0
  47. package/dist/index.d.ts +32 -0
  48. package/dist/index.d.ts.map +1 -0
  49. package/dist/index.js +18 -0
  50. package/dist/index.js.map +1 -0
  51. package/dist/issue-key-match.d.ts +3 -0
  52. package/dist/issue-key-match.d.ts.map +1 -0
  53. package/dist/issue-key-match.js +22 -0
  54. package/dist/issue-key-match.js.map +1 -0
  55. package/dist/linear/state-resolver.d.ts +25 -0
  56. package/dist/linear/state-resolver.d.ts.map +1 -0
  57. package/dist/linear/state-resolver.js +221 -0
  58. package/dist/linear/state-resolver.js.map +1 -0
  59. package/dist/mount/local-mount-preflight.d.ts +8 -0
  60. package/dist/mount/local-mount-preflight.d.ts.map +1 -0
  61. package/dist/mount/local-mount-preflight.js +97 -0
  62. package/dist/mount/local-mount-preflight.js.map +1 -0
  63. package/dist/mount/relayfile-binary.d.ts +7 -0
  64. package/dist/mount/relayfile-binary.d.ts.map +1 -0
  65. package/dist/mount/relayfile-binary.js +143 -0
  66. package/dist/mount/relayfile-binary.js.map +1 -0
  67. package/dist/mount/relayfile-cloud-mount-client.d.ts +123 -0
  68. package/dist/mount/relayfile-cloud-mount-client.d.ts.map +1 -0
  69. package/dist/mount/relayfile-cloud-mount-client.js +427 -0
  70. package/dist/mount/relayfile-cloud-mount-client.js.map +1 -0
  71. package/dist/orchestrator/batch-tracker.d.ts +42 -0
  72. package/dist/orchestrator/batch-tracker.d.ts.map +1 -0
  73. package/dist/orchestrator/batch-tracker.js +125 -0
  74. package/dist/orchestrator/batch-tracker.js.map +1 -0
  75. package/dist/orchestrator/factory.d.ts +55 -0
  76. package/dist/orchestrator/factory.d.ts.map +1 -0
  77. package/dist/orchestrator/factory.js +4018 -0
  78. package/dist/orchestrator/factory.js.map +1 -0
  79. package/dist/orchestrator/index.d.ts +5 -0
  80. package/dist/orchestrator/index.d.ts.map +1 -0
  81. package/dist/orchestrator/index.js +4 -0
  82. package/dist/orchestrator/index.js.map +1 -0
  83. package/dist/orchestrator/process-identity.d.ts +23 -0
  84. package/dist/orchestrator/process-identity.d.ts.map +1 -0
  85. package/dist/orchestrator/process-identity.js +122 -0
  86. package/dist/orchestrator/process-identity.js.map +1 -0
  87. package/dist/orchestrator/reaper.d.ts +60 -0
  88. package/dist/orchestrator/reaper.d.ts.map +1 -0
  89. package/dist/orchestrator/reaper.js +293 -0
  90. package/dist/orchestrator/reaper.js.map +1 -0
  91. package/dist/ports/fleet.d.ts +95 -0
  92. package/dist/ports/fleet.d.ts.map +1 -0
  93. package/dist/ports/fleet.js +2 -0
  94. package/dist/ports/fleet.js.map +1 -0
  95. package/dist/ports/index.d.ts +5 -0
  96. package/dist/ports/index.d.ts.map +1 -0
  97. package/dist/ports/index.js +2 -0
  98. package/dist/ports/index.js.map +1 -0
  99. package/dist/ports/mount.d.ts +56 -0
  100. package/dist/ports/mount.d.ts.map +1 -0
  101. package/dist/ports/mount.js +2 -0
  102. package/dist/ports/mount.js.map +1 -0
  103. package/dist/ports/state.d.ts +61 -0
  104. package/dist/ports/state.d.ts.map +1 -0
  105. package/dist/ports/state.js +2 -0
  106. package/dist/ports/state.js.map +1 -0
  107. package/dist/ports/system.d.ts +15 -0
  108. package/dist/ports/system.d.ts.map +1 -0
  109. package/dist/ports/system.js +2 -0
  110. package/dist/ports/system.js.map +1 -0
  111. package/dist/ports/writeback.d.ts +25 -0
  112. package/dist/ports/writeback.d.ts.map +1 -0
  113. package/dist/ports/writeback.js +2 -0
  114. package/dist/ports/writeback.js.map +1 -0
  115. package/dist/safety/factory-scope.d.ts +16 -0
  116. package/dist/safety/factory-scope.d.ts.map +1 -0
  117. package/dist/safety/factory-scope.js +107 -0
  118. package/dist/safety/factory-scope.js.map +1 -0
  119. package/dist/state/in-memory-state-store.d.ts +31 -0
  120. package/dist/state/in-memory-state-store.d.ts.map +1 -0
  121. package/dist/state/in-memory-state-store.js +115 -0
  122. package/dist/state/in-memory-state-store.js.map +1 -0
  123. package/dist/state/index.d.ts +3 -0
  124. package/dist/state/index.d.ts.map +1 -0
  125. package/dist/state/index.js +2 -0
  126. package/dist/state/index.js.map +1 -0
  127. package/dist/state/store.d.ts +29 -0
  128. package/dist/state/store.d.ts.map +1 -0
  129. package/dist/state/store.js +26 -0
  130. package/dist/state/store.js.map +1 -0
  131. package/dist/subscriptions/common.d.ts +7 -0
  132. package/dist/subscriptions/common.d.ts.map +1 -0
  133. package/dist/subscriptions/common.js +59 -0
  134. package/dist/subscriptions/common.js.map +1 -0
  135. package/dist/subscriptions/event-client.d.ts +40 -0
  136. package/dist/subscriptions/event-client.d.ts.map +1 -0
  137. package/dist/subscriptions/event-client.js +234 -0
  138. package/dist/subscriptions/event-client.js.map +1 -0
  139. package/dist/subscriptions/globs.d.ts +5 -0
  140. package/dist/subscriptions/globs.d.ts.map +1 -0
  141. package/dist/subscriptions/globs.js +50 -0
  142. package/dist/subscriptions/globs.js.map +1 -0
  143. package/dist/subscriptions/index.d.ts +8 -0
  144. package/dist/subscriptions/index.d.ts.map +1 -0
  145. package/dist/subscriptions/index.js +5 -0
  146. package/dist/subscriptions/index.js.map +1 -0
  147. package/dist/subscriptions/linear-filter.d.ts +26 -0
  148. package/dist/subscriptions/linear-filter.d.ts.map +1 -0
  149. package/dist/subscriptions/linear-filter.js +143 -0
  150. package/dist/subscriptions/linear-filter.js.map +1 -0
  151. package/dist/subscriptions/specs.d.ts +44 -0
  152. package/dist/subscriptions/specs.d.ts.map +1 -0
  153. package/dist/subscriptions/specs.js +195 -0
  154. package/dist/subscriptions/specs.js.map +1 -0
  155. package/dist/testing/fakes.d.ts +114 -0
  156. package/dist/testing/fakes.d.ts.map +1 -0
  157. package/dist/testing/fakes.js +219 -0
  158. package/dist/testing/fakes.js.map +1 -0
  159. package/dist/testing/index.d.ts +2 -0
  160. package/dist/testing/index.d.ts.map +1 -0
  161. package/dist/testing/index.js +2 -0
  162. package/dist/testing/index.js.map +1 -0
  163. package/dist/triage/heuristic.d.ts +38 -0
  164. package/dist/triage/heuristic.d.ts.map +1 -0
  165. package/dist/triage/heuristic.js +262 -0
  166. package/dist/triage/heuristic.js.map +1 -0
  167. package/dist/triage/index.d.ts +7 -0
  168. package/dist/triage/index.d.ts.map +1 -0
  169. package/dist/triage/index.js +5 -0
  170. package/dist/triage/index.js.map +1 -0
  171. package/dist/triage/llm.d.ts +11 -0
  172. package/dist/triage/llm.d.ts.map +1 -0
  173. package/dist/triage/llm.js +46 -0
  174. package/dist/triage/llm.js.map +1 -0
  175. package/dist/triage/schema.d.ts +240 -0
  176. package/dist/triage/schema.d.ts.map +1 -0
  177. package/dist/triage/schema.js +34 -0
  178. package/dist/triage/schema.js.map +1 -0
  179. package/dist/triage/tiered.d.ts +8 -0
  180. package/dist/triage/tiered.d.ts.map +1 -0
  181. package/dist/triage/tiered.js +40 -0
  182. package/dist/triage/tiered.js.map +1 -0
  183. package/dist/types.d.ts +211 -0
  184. package/dist/types.d.ts.map +1 -0
  185. package/dist/types.js +2 -0
  186. package/dist/types.js.map +1 -0
  187. package/dist/webhook/handler.d.ts +22 -0
  188. package/dist/webhook/handler.d.ts.map +1 -0
  189. package/dist/webhook/handler.js +57 -0
  190. package/dist/webhook/handler.js.map +1 -0
  191. package/dist/webhook/index.d.ts +5 -0
  192. package/dist/webhook/index.d.ts.map +1 -0
  193. package/dist/webhook/index.js +3 -0
  194. package/dist/webhook/index.js.map +1 -0
  195. package/dist/webhook/registrar.d.ts +16 -0
  196. package/dist/webhook/registrar.d.ts.map +1 -0
  197. package/dist/webhook/registrar.js +50 -0
  198. package/dist/webhook/registrar.js.map +1 -0
  199. package/dist/writeback/github.d.ts +6 -0
  200. package/dist/writeback/github.d.ts.map +1 -0
  201. package/dist/writeback/github.js +48 -0
  202. package/dist/writeback/github.js.map +1 -0
  203. package/dist/writeback/index.d.ts +6 -0
  204. package/dist/writeback/index.d.ts.map +1 -0
  205. package/dist/writeback/index.js +4 -0
  206. package/dist/writeback/index.js.map +1 -0
  207. package/dist/writeback/linear.d.ts +41 -0
  208. package/dist/writeback/linear.d.ts.map +1 -0
  209. package/dist/writeback/linear.js +243 -0
  210. package/dist/writeback/linear.js.map +1 -0
  211. package/dist/writeback/shared.d.ts +7 -0
  212. package/dist/writeback/shared.d.ts.map +1 -0
  213. package/dist/writeback/shared.js +29 -0
  214. package/dist/writeback/shared.js.map +1 -0
  215. package/dist/writeback/slack.d.ts +16 -0
  216. package/dist/writeback/slack.d.ts.map +1 -0
  217. package/dist/writeback/slack.js +104 -0
  218. package/dist/writeback/slack.js.map +1 -0
  219. package/package.json +46 -9
  220. package/index.d.ts +0 -2
  221. 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;AAoKnE,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,309 @@
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
+ const linearSchema = z.object({
89
+ states: linearRoleNamesSchema,
90
+ statesByTeam: z.record(z.string(), linearRoleNamesSchema).default({}),
91
+ }).default({});
92
+ const stateIdsSchema = z.object({
93
+ readyForAgent: z.string().optional(),
94
+ agentImplementing: z.string().optional(),
95
+ done: z.string().optional(),
96
+ inPlanning: z.string().optional(),
97
+ humanReview: z.string().optional(),
98
+ }).default({});
99
+ const safetySchema = z.object({
100
+ requireTitlePrefix: z.string().min(1).default('[factory-e2e]'),
101
+ requireLabel: z.string().default('factory'),
102
+ requireTeamKey: z.string().min(1).default('AR'),
103
+ }).default({});
104
+ const WorkspaceConfigObjectSchema = z.object({
105
+ // Optional. When omitted, the CLI derives the workspace from the cloud session
106
+ // via `resolveActiveWorkspace()` (returns the active `relayfileWorkspaceId`),
107
+ // falling back to the SDK's built-in default. Set it only to pin a non-active
108
+ // workspace. See resolveFactoryWorkspace() in relayfile-cloud-mount-client.ts.
109
+ workspaceId: z.string().optional(),
110
+ subscription: subscriptionSchema,
111
+ liveSubscription: liveSubscriptionSchema,
112
+ dispatch: dispatchSchema,
113
+ loop: loopSchema,
114
+ triage: triageSchema,
115
+ repos: workspaceReposSchema,
116
+ batchSize: z.number().int().min(1).max(5).default(5),
117
+ models: modelsSchema,
118
+ slack: slackSchema,
119
+ mergePolicy: z.enum(['never', 'on-green-with-review']).default('never'),
120
+ // Opt-in PR babysitter. When enabled, a sonnet agent is spawned once the
121
+ // implementer's PR opens (webhook-driven, see the orchestrator) and shepherds
122
+ // it — addressing review comments, resolving conflicts, and fixing CI — until
123
+ // it is green, then transitions the issue to the `human-review` terminal state
124
+ // instead of jumping straight to `done`. Default off preserves the legacy
125
+ // PR-open -> done behavior.
126
+ babysitter: babysitterSchema,
127
+ // Which Linear state an issue lands in once the agents finish and the PR is
128
+ // open. `human-review` parks it for operator review (Done is reserved for the
129
+ // actual merge); `done` is the legacy behavior. Only honored when the
130
+ // `humanReview` role resolves to a state — otherwise it falls back to `done`.
131
+ terminalState: z.enum(['done', 'human-review']).default('human-review'),
132
+ // Dynamic, workspace-agnostic Linear configuration. Nothing about state names
133
+ // or UUIDs is hardcoded — customers map the factory's semantic roles to
134
+ // whatever their teams call those states, and the names are resolved to UUIDs
135
+ // at startup against /linear/states (see resolveFactoryStates).
136
+ //
137
+ // `states` is the workspace-wide default mapping; `statesByTeam.<TEAM>`
138
+ // overrides individual roles for teams that name their states differently
139
+ // (resolution per issue uses the issue's team, falling back to `states`).
140
+ linear: linearSchema,
141
+ // Explicit workflow-state UUIDs. Lowest-precedence fallback / single-team
142
+ // escape hatch for setups that prefer pinning ids over name resolution; any
143
+ // role resolved by name (per-team or global) takes precedence. Populated in
144
+ // place once resolution runs, so the orchestrator always sees concrete UUIDs.
145
+ stateIds: stateIdsSchema,
146
+ safety: safetySchema,
147
+ });
148
+ const NodeConfigObjectSchema = z.object({
149
+ workspaceId: z.string().optional(),
150
+ capabilities: z.array(z.string()).default([]),
151
+ cloneRoot: z.string().optional(),
152
+ clonePaths: z.record(z.string(), z.string()).default({}),
153
+ dryRun: z.boolean().default(false),
154
+ factoryLoopHeartbeatPath: z.string().min(1).optional(),
155
+ factoryLoopRegistryPath: z.string().min(1).optional(),
156
+ });
157
+ const FactoryConfigObjectSchema = WorkspaceConfigObjectSchema.merge(NodeConfigObjectSchema);
158
+ export const WorkspaceConfigSchema = WorkspaceConfigObjectSchema.transform((cfg) => normalizeWorkspaceConfig(cfg));
159
+ export const NodeConfigSchema = NodeConfigObjectSchema.transform((cfg) => normalizeNodeConfig(cfg));
160
+ export const FactoryConfigSchema = FactoryConfigObjectSchema.transform((cfg) => normalizeFactoryConfig(cfg));
161
+ function normalizeWorkspaceConfig(cfg) {
162
+ const resolved = resolveRepos(cfg.repos, cfg.repos.cloneRoot);
163
+ const labels = resolveSubscriptionLabels(cfg.subscription.labels, cfg.repos.names ?? []);
164
+ const { cloneRoot: _legacyCloneRoot, clonePaths: _legacyClonePaths, ...repos } = cfg.repos;
165
+ return {
166
+ ...cfg,
167
+ subscription: { ...cfg.subscription, labels },
168
+ repos: {
169
+ ...repos,
170
+ byLabel: resolved.byLabel,
171
+ byProject: resolved.byProject,
172
+ keywordRules: resolved.keywordRules,
173
+ ...(resolved.defaultRepo !== undefined ? { default: resolved.defaultRepo } : {}),
174
+ },
175
+ };
176
+ }
177
+ function normalizeNodeConfig(cfg) {
178
+ return {
179
+ ...cfg,
180
+ factoryLoopHeartbeatPath: cfg.factoryLoopHeartbeatPath,
181
+ factoryLoopRegistryPath: cfg.factoryLoopRegistryPath,
182
+ };
183
+ }
184
+ function normalizeFactoryConfig(cfg) {
185
+ const cloneRoot = cfg.cloneRoot ?? cfg.repos.cloneRoot;
186
+ const explicitClonePaths = {
187
+ ...cfg.repos.clonePaths,
188
+ ...cfg.clonePaths,
189
+ };
190
+ const resolved = resolveRepos(cfg.repos, cloneRoot, explicitClonePaths);
191
+ const labels = resolveSubscriptionLabels(cfg.subscription.labels, cfg.repos.names ?? []);
192
+ const heartbeatPath = cfg.factoryLoopHeartbeatPath ?? cfg.loop.heartbeatPath;
193
+ const registryPath = cfg.factoryLoopRegistryPath ?? cfg.loop.registryPath;
194
+ return {
195
+ ...cfg,
196
+ cloneRoot,
197
+ clonePaths: resolved.clonePaths,
198
+ factoryLoopHeartbeatPath: heartbeatPath,
199
+ factoryLoopRegistryPath: registryPath,
200
+ subscription: { ...cfg.subscription, labels },
201
+ loop: {
202
+ ...cfg.loop,
203
+ heartbeatPath,
204
+ registryPath,
205
+ },
206
+ repos: {
207
+ byLabel: resolved.byLabel,
208
+ byProject: resolved.byProject,
209
+ keywordRules: resolved.keywordRules,
210
+ clonePaths: resolved.clonePaths,
211
+ ...(resolved.defaultRepo !== undefined ? { default: resolved.defaultRepo } : {}),
212
+ },
213
+ };
214
+ }
215
+ function resolveRepos(repos, cloneRoot, explicitClonePaths = repos.clonePaths) {
216
+ const { org, names, overrides, byLabel, byProject, keywordRules, default: defaultRepo } = repos;
217
+ const repoNames = names ?? [];
218
+ // Derive byLabel from `names` (label === repo name): overrides[name] wins,
219
+ // else `${org}/${name}` when an org is set, else the bare name. Explicit
220
+ // byLabel entries are merged last so they always win.
221
+ const derivedByLabel = {};
222
+ for (const name of repoNames) {
223
+ derivedByLabel[name] = overrides[name] ?? (org ? `${org}/${name}` : name);
224
+ }
225
+ const resolvedByLabel = { ...derivedByLabel, ...byLabel };
226
+ // Derive clonePaths as `${cloneRoot}/${repoName}` for every routed repo.
227
+ // Explicit clonePaths entries win.
228
+ const derivedClonePaths = {};
229
+ if (cloneRoot) {
230
+ const root = cloneRoot.replace(/\/+$/u, '');
231
+ for (const repo of Object.values(resolvedByLabel)) {
232
+ const repoName = repo.includes('/') ? repo.slice(repo.lastIndexOf('/') + 1) : repo;
233
+ derivedClonePaths[repo] = `${root}/${repoName}`;
234
+ }
235
+ }
236
+ const resolvedClonePaths = { ...derivedClonePaths, ...explicitClonePaths };
237
+ return {
238
+ byLabel: resolvedByLabel,
239
+ byProject,
240
+ keywordRules,
241
+ clonePaths: resolvedClonePaths,
242
+ defaultRepo,
243
+ };
244
+ }
245
+ function resolveSubscriptionLabels(labels, repoNames) {
246
+ return labels.length > 0 ? labels : repoNames;
247
+ }
248
+ export function loadFactoryConfig(input) {
249
+ const record = asConfigRecord(input);
250
+ const hasSplit = Object.prototype.hasOwnProperty.call(record, 'workspaceConfig') ||
251
+ Object.prototype.hasOwnProperty.call(record, 'nodeConfig');
252
+ if (hasSplit) {
253
+ if (!Object.prototype.hasOwnProperty.call(record, 'workspaceConfig')) {
254
+ throw new Error('split factory config requires workspaceConfig');
255
+ }
256
+ if (!Object.prototype.hasOwnProperty.call(record, 'nodeConfig')) {
257
+ throw new Error('split factory config requires nodeConfig');
258
+ }
259
+ return normalizeLoadedConfig(combineSplitConfigInput(record.workspaceConfig, record.nodeConfig));
260
+ }
261
+ return normalizeLoadedConfig(record.factoryConfig ?? input);
262
+ }
263
+ function normalizeLoadedConfig(input) {
264
+ const factoryConfig = FactoryConfigSchema.parse(input);
265
+ const workspaceConfig = WorkspaceConfigSchema.parse(factoryConfig);
266
+ const nodeConfig = NodeConfigSchema.parse({
267
+ workspaceId: factoryConfig.workspaceId,
268
+ capabilities: factoryConfig.capabilities,
269
+ cloneRoot: factoryConfig.cloneRoot,
270
+ clonePaths: factoryConfig.clonePaths,
271
+ dryRun: factoryConfig.dryRun,
272
+ factoryLoopHeartbeatPath: factoryConfig.loop.heartbeatPath,
273
+ factoryLoopRegistryPath: factoryConfig.loop.registryPath,
274
+ });
275
+ return { workspaceConfig, nodeConfig, factoryConfig };
276
+ }
277
+ function combineSplitConfigInput(workspaceInput, nodeInput) {
278
+ const workspace = asConfigRecord(workspaceInput);
279
+ const node = asConfigRecord(nodeInput);
280
+ const workspaceRepos = asOptionalConfigRecord(workspace.repos);
281
+ assertCompatibleWorkspaceIds(workspace.workspaceId, node.workspaceId);
282
+ return {
283
+ ...workspace,
284
+ ...node,
285
+ repos: {
286
+ ...workspaceRepos,
287
+ cloneRoot: node.cloneRoot ?? workspaceRepos.cloneRoot,
288
+ clonePaths: node.clonePaths ?? workspaceRepos.clonePaths,
289
+ },
290
+ };
291
+ }
292
+ function assertCompatibleWorkspaceIds(workspaceId, nodeWorkspaceId) {
293
+ if (typeof workspaceId === 'string' &&
294
+ typeof nodeWorkspaceId === 'string' &&
295
+ workspaceId !== nodeWorkspaceId) {
296
+ throw new Error(`split factory config workspaceId mismatch: workspaceConfig=${workspaceId} nodeConfig=${nodeWorkspaceId}`);
297
+ }
298
+ }
299
+ function asConfigRecord(value) {
300
+ if (value && typeof value === 'object' && !Array.isArray(value))
301
+ return value;
302
+ throw new Error('factory config must be a JSON object');
303
+ }
304
+ function asOptionalConfigRecord(value) {
305
+ if (value === undefined)
306
+ return {};
307
+ return asConfigRecord(value);
308
+ }
309
+ //# 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,4 @@
1
+ export declare const linearIssuePath: (key: string, uuid: string) => string;
2
+ export declare const linearByStatePath: (slug: string) => string;
3
+ export declare const linearCommentPath: (issuePath: string, name: string) => string;
4
+ //# 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;AAOrF,eAAO,MAAM,iBAAiB,GAAI,WAAW,MAAM,EAAE,MAAM,MAAM,WAGhE,CAAA"}
@@ -0,0 +1,15 @@
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
+ // Comment writeback must be nested under its issue — the relayfile cloud
7
+ // writeback executor only accepts /linear/issues/<issueRef>/comments/<draft>.json
8
+ // (top-level /linear/comments/<name>.json is rejected as "unsupported Linear
9
+ // writeback path"). issuePath is /linear/issues/<key>__<uuid>.json, so the
10
+ // issueRef segment is its basename.
11
+ export const linearCommentPath = (issuePath, name) => {
12
+ const issueRef = issuePath.replace(/^\/linear\/issues\//u, '').replace(/\.json$/u, '');
13
+ return `/linear/issues/${issueRef}/comments/${name}.json`;
14
+ };
15
+ //# 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,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,36 @@
1
+ import type { FactoryConfig } from '../config/schema';
2
+ import type { AgentSpec } from '../ports/fleet';
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
+ }
31
+ export declare function renderAgentTask(input: RenderAgentTaskInput): string;
32
+ export declare function agentSpecWithRenderedTask(spec: Omit<AgentSpec, 'task'> & {
33
+ task?: string;
34
+ }, input: RenderAgentTaskInput): AgentSpec;
35
+ export declare function mergePolicyLine(policy: FactoryConfig['mergePolicy']): string;
36
+ //# 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;KACjB,CAAA;CACF;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,oBAAoB,GAAG,MAAM,CAkGnE;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,110 @@
1
+ export function renderAgentTask(input) {
2
+ const repo = normalizeRepo(input.route.repo);
3
+ const cloneInstruction = input.route.clonePath
4
+ ? `Repo path: ${input.route.clonePath}`
5
+ : `Clone/worktree: clone AgentWorkforce/${repo} and work in your own isolated git worktree before editing.`;
6
+ const implementers = input.implementerNames?.length ? input.implementerNames.join(', ') : 'the implementer(s)';
7
+ const header = [
8
+ `GitHub repo: AgentWorkforce/${repo}`,
9
+ cloneInstruction,
10
+ `Linear issue: ${input.issue.key} - ${input.issue.title}`,
11
+ 'Full Linear issue description:',
12
+ input.issue.description,
13
+ ];
14
+ const common = [
15
+ ...header,
16
+ '',
17
+ 'Create a branch for this issue before editing.',
18
+ 'Commit the implementation and tests.',
19
+ 'Push the branch to origin.',
20
+ 'Open a PR targeting `main` when done.',
21
+ 'Use `gh pr create --base main` and report the PR URL.',
22
+ `DM the reviewer \`${input.reviewerName}\` when the PR is ready.`,
23
+ 'If blocked and you need human input, DM `factory` with `[factory-needs-input] <your question>` so the factory can relay it to the issue Slack thread.',
24
+ 'DM `broker` when fully done.',
25
+ 'Do NOT auto-merge.',
26
+ mergePolicyLine(input.config.mergePolicy),
27
+ ];
28
+ const questionInstructions = input.slackDispatchThread
29
+ ? [
30
+ '',
31
+ 'If you are blocked or need a human answer mid-task, ask in this issue\'s Slack dispatch thread.',
32
+ `Slack dispatch channel: ${input.slackDispatchThread.channel}`,
33
+ `Slack dispatch thread: ${input.slackDispatchThread.threadId}`,
34
+ 'Prefer the injected Agent Relay MCP thread reply tool when it is available.',
35
+ 'Fallback: DM `factory` with `[factory-needs-input] <your question>` and continue with safe reversible work while waiting.',
36
+ ]
37
+ : [];
38
+ if (input.role === 'babysitter') {
39
+ const prRef = input.pr
40
+ ? `PR #${input.pr.number}${input.pr.url ? ` (${input.pr.url})` : ''}`
41
+ : 'the open PR for this issue';
42
+ const chatLine = input.slackDispatchThread
43
+ ? 'You can also use this issue\'s Slack dispatch thread to discuss the PR with the human (status, trade-offs, open questions) — proactively offer to chat there if it would help.'
44
+ : 'If a human can be reached, proactively offer to discuss the PR (status, trade-offs, open questions) via `[factory-needs-input]`.';
45
+ // Match the prompt to where the issue actually lands so the babysitter is not
46
+ // told to "stop at Human Review" while the factory is configured to finish at
47
+ // Done (and possibly auto-merge under on-green-with-review).
48
+ const humanReview = input.config.terminalState === 'human-review';
49
+ const destination = humanReview ? 'Human Review' : 'Done';
50
+ const jobLine = humanReview
51
+ ? '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.'
52
+ : '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.';
53
+ const finishLine = humanReview
54
+ ? 'Do NOT auto-merge; stop at Human Review — a human owns the merge.'
55
+ : input.config.mergePolicy === 'on-green-with-review'
56
+ ? 'Do NOT merge it yourself; the factory runs the guarded merge gate once you signal ready.'
57
+ : 'Do NOT merge it yourself; the factory moves the issue to Done once you signal ready.';
58
+ return [
59
+ ...header,
60
+ '',
61
+ `You are the PR babysitter for ${input.issue.key}. A PR is already open: ${prRef}.`,
62
+ jobLine,
63
+ '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.',
64
+ 'Read the PR diff, CI checks, and review threads via `.integrations/github/repos`.',
65
+ 'Address every review comment for real — make substantive code changes when the feedback calls for it, not just lint/format touch-ups.',
66
+ '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.',
67
+ 'Fix failing CI — change the code and tests as needed until the checks pass. A red check is not done.',
68
+ `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.`,
69
+ 'Commit and push your fixes to the PR branch.',
70
+ chatLine,
71
+ `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}.`,
72
+ 'DM `broker` when fully done.',
73
+ finishLine,
74
+ mergePolicyLine(input.config.mergePolicy),
75
+ ...questionInstructions,
76
+ ].join('\n');
77
+ }
78
+ if (input.role === 'reviewer') {
79
+ return [
80
+ ...common,
81
+ ...questionInstructions,
82
+ '',
83
+ `Wait for a DM from the implementer(s): ${implementers}.`,
84
+ 'Read the PR diff via `.integrations/github/repos`.',
85
+ 'Post review comments via the GitHub writeback path.',
86
+ 'DM the implementer with specific feedback if changes needed, or approve if good.',
87
+ 'DM `broker` when the review cycle is complete.',
88
+ ].join('\n');
89
+ }
90
+ return [
91
+ ...common,
92
+ ...questionInstructions,
93
+ ].join('\n');
94
+ }
95
+ export function agentSpecWithRenderedTask(spec, input) {
96
+ return {
97
+ ...spec,
98
+ task: renderAgentTask(input),
99
+ };
100
+ }
101
+ export function mergePolicyLine(policy) {
102
+ if (policy === 'on-green-with-review') {
103
+ return 'Merge policy: on-green-with-review - do not merge until checks are green and review approval is present.';
104
+ }
105
+ return 'Merge policy: never - open the PR for human review and approval; never merge it yourself.';
106
+ }
107
+ function normalizeRepo(repo) {
108
+ return repo.startsWith('AgentWorkforce/') ? repo.slice('AgentWorkforce/'.length) : repo;
109
+ }
110
+ //# 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,13 @@
1
+ import { InternalFleetClient, type HarnessDriverClientLike } from './internal-fleet-client';
2
+ import { RelayFleetClient } from './relay-fleet-client';
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
+ }
12
+ export declare function createFleet(options?: CreateFleetOptions, deps?: CreateFleetDeps): InternalFleetClient | RelayFleetClient;
13
+ //# 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;CACxC;AAED,wBAAgB,WAAW,CAAC,OAAO,GAAE,kBAAuB,EAAE,IAAI,GAAE,eAAoB,0CAYvF"}
@@ -0,0 +1,14 @@
1
+ import { InternalFleetClient } from './internal-fleet-client';
2
+ import { RelayFleetClient } from './relay-fleet-client';
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
+ cwd: options.cwd,
11
+ connectionPath: options.connectionPath,
12
+ });
13
+ }
14
+ //# 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;AAcvD,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,GAAG,EAAE,OAAO,CAAC,GAAG;QAChB,cAAc,EAAE,OAAO,CAAC,cAAc;KACvC,CAAC,CAAA;AACJ,CAAC"}