@cluesmith/codev 3.0.3 → 3.0.6

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 (140) hide show
  1. package/dashboard-dist/assets/{index-Dn9zmcKp.js → index-CR-uu485.js} +29 -29
  2. package/dashboard-dist/assets/index-CR-uu485.js.map +1 -0
  3. package/dashboard-dist/assets/{index-BWYZtvwm.css → index-nCeIzV_d.css} +1 -1
  4. package/dashboard-dist/index.html +2 -2
  5. package/dist/agent-farm/cli.d.ts.map +1 -1
  6. package/dist/agent-farm/cli.js +16 -1
  7. package/dist/agent-farm/cli.js.map +1 -1
  8. package/dist/agent-farm/commands/cleanup.js +13 -0
  9. package/dist/agent-farm/commands/cleanup.js.map +1 -1
  10. package/dist/agent-farm/commands/dev.d.ts.map +1 -1
  11. package/dist/agent-farm/commands/dev.js +10 -3
  12. package/dist/agent-farm/commands/dev.js.map +1 -1
  13. package/dist/agent-farm/commands/spawn-worktree.d.ts +12 -3
  14. package/dist/agent-farm/commands/spawn-worktree.d.ts.map +1 -1
  15. package/dist/agent-farm/commands/spawn-worktree.js +17 -6
  16. package/dist/agent-farm/commands/spawn-worktree.js.map +1 -1
  17. package/dist/agent-farm/commands/spawn.d.ts.map +1 -1
  18. package/dist/agent-farm/commands/spawn.js +82 -36
  19. package/dist/agent-farm/commands/spawn.js.map +1 -1
  20. package/dist/agent-farm/commands/stop.d.ts.map +1 -1
  21. package/dist/agent-farm/commands/stop.js +15 -8
  22. package/dist/agent-farm/commands/stop.js.map +1 -1
  23. package/dist/agent-farm/commands/workspace-add-architect.d.ts +18 -0
  24. package/dist/agent-farm/commands/workspace-add-architect.d.ts.map +1 -0
  25. package/dist/agent-farm/commands/workspace-add-architect.js +54 -0
  26. package/dist/agent-farm/commands/workspace-add-architect.js.map +1 -0
  27. package/dist/agent-farm/db/index.d.ts.map +1 -1
  28. package/dist/agent-farm/db/index.js +88 -1
  29. package/dist/agent-farm/db/index.js.map +1 -1
  30. package/dist/agent-farm/db/migrate.js +2 -2
  31. package/dist/agent-farm/db/migrate.js.map +1 -1
  32. package/dist/agent-farm/db/schema.d.ts +1 -1
  33. package/dist/agent-farm/db/schema.d.ts.map +1 -1
  34. package/dist/agent-farm/db/schema.js +4 -3
  35. package/dist/agent-farm/db/schema.js.map +1 -1
  36. package/dist/agent-farm/db/types.d.ts +7 -2
  37. package/dist/agent-farm/db/types.d.ts.map +1 -1
  38. package/dist/agent-farm/db/types.js +2 -0
  39. package/dist/agent-farm/db/types.js.map +1 -1
  40. package/dist/agent-farm/servers/analytics.d.ts.map +1 -1
  41. package/dist/agent-farm/servers/analytics.js +1 -0
  42. package/dist/agent-farm/servers/analytics.js.map +1 -1
  43. package/dist/agent-farm/servers/overview.d.ts +25 -3
  44. package/dist/agent-farm/servers/overview.d.ts.map +1 -1
  45. package/dist/agent-farm/servers/overview.js +72 -10
  46. package/dist/agent-farm/servers/overview.js.map +1 -1
  47. package/dist/agent-farm/servers/tower-instances.d.ts +18 -0
  48. package/dist/agent-farm/servers/tower-instances.d.ts.map +1 -1
  49. package/dist/agent-farm/servers/tower-instances.js +260 -16
  50. package/dist/agent-farm/servers/tower-instances.js.map +1 -1
  51. package/dist/agent-farm/servers/tower-messages.d.ts +10 -1
  52. package/dist/agent-farm/servers/tower-messages.d.ts.map +1 -1
  53. package/dist/agent-farm/servers/tower-messages.js +137 -7
  54. package/dist/agent-farm/servers/tower-messages.js.map +1 -1
  55. package/dist/agent-farm/servers/tower-routes.d.ts.map +1 -1
  56. package/dist/agent-farm/servers/tower-routes.js +124 -20
  57. package/dist/agent-farm/servers/tower-routes.js.map +1 -1
  58. package/dist/agent-farm/servers/tower-terminals.d.ts.map +1 -1
  59. package/dist/agent-farm/servers/tower-terminals.js +58 -28
  60. package/dist/agent-farm/servers/tower-terminals.js.map +1 -1
  61. package/dist/agent-farm/servers/tower-tunnel.d.ts.map +1 -1
  62. package/dist/agent-farm/servers/tower-tunnel.js +3 -2
  63. package/dist/agent-farm/servers/tower-tunnel.js.map +1 -1
  64. package/dist/agent-farm/servers/tower-types.d.ts +9 -2
  65. package/dist/agent-farm/servers/tower-types.d.ts.map +1 -1
  66. package/dist/agent-farm/state.d.ts +50 -4
  67. package/dist/agent-farm/state.d.ts.map +1 -1
  68. package/dist/agent-farm/state.js +118 -12
  69. package/dist/agent-farm/state.js.map +1 -1
  70. package/dist/agent-farm/types.d.ts +3 -1
  71. package/dist/agent-farm/types.d.ts.map +1 -1
  72. package/dist/agent-farm/utils/agent-names.d.ts.map +1 -1
  73. package/dist/agent-farm/utils/agent-names.js +3 -0
  74. package/dist/agent-farm/utils/agent-names.js.map +1 -1
  75. package/dist/agent-farm/utils/architect-name.d.ts +37 -0
  76. package/dist/agent-farm/utils/architect-name.d.ts.map +1 -0
  77. package/dist/agent-farm/utils/architect-name.js +63 -0
  78. package/dist/agent-farm/utils/architect-name.js.map +1 -0
  79. package/dist/agent-farm/utils/git.d.ts +29 -0
  80. package/dist/agent-farm/utils/git.d.ts.map +1 -0
  81. package/dist/agent-farm/utils/git.js +38 -0
  82. package/dist/agent-farm/utils/git.js.map +1 -0
  83. package/dist/cli.js +1 -1
  84. package/dist/cli.js.map +1 -1
  85. package/dist/commands/consult/index.d.ts.map +1 -1
  86. package/dist/commands/consult/index.js +2 -0
  87. package/dist/commands/consult/index.js.map +1 -1
  88. package/dist/commands/porch/artifacts.d.ts +23 -1
  89. package/dist/commands/porch/artifacts.d.ts.map +1 -1
  90. package/dist/commands/porch/artifacts.js +51 -62
  91. package/dist/commands/porch/artifacts.js.map +1 -1
  92. package/dist/commands/porch/index.d.ts +23 -2
  93. package/dist/commands/porch/index.d.ts.map +1 -1
  94. package/dist/commands/porch/index.js +83 -4
  95. package/dist/commands/porch/index.js.map +1 -1
  96. package/dist/commands/porch/notify.d.ts +27 -5
  97. package/dist/commands/porch/notify.d.ts.map +1 -1
  98. package/dist/commands/porch/notify.js +23 -12
  99. package/dist/commands/porch/notify.js.map +1 -1
  100. package/dist/commands/porch/state.d.ts +1 -1
  101. package/dist/commands/porch/state.d.ts.map +1 -1
  102. package/dist/commands/porch/state.js +8 -6
  103. package/dist/commands/porch/state.js.map +1 -1
  104. package/dist/lib/github.d.ts +8 -0
  105. package/dist/lib/github.d.ts.map +1 -1
  106. package/dist/lib/github.js +29 -2
  107. package/dist/lib/github.js.map +1 -1
  108. package/dist/lib/team-github.d.ts +4 -0
  109. package/dist/lib/team-github.d.ts.map +1 -1
  110. package/dist/lib/team-github.js +14 -3
  111. package/dist/lib/team-github.js.map +1 -1
  112. package/package.json +5 -5
  113. package/skeleton/protocols/air/builder-prompt.md +6 -0
  114. package/skeleton/protocols/air/consult-types/impl-review.md +6 -0
  115. package/skeleton/protocols/air/consult-types/pr-review.md +6 -0
  116. package/skeleton/protocols/air/prompts/implement.md +6 -0
  117. package/skeleton/protocols/air/protocol.md +4 -0
  118. package/skeleton/protocols/aspir/builder-prompt.md +19 -3
  119. package/skeleton/protocols/aspir/consult-types/plan-review.md +6 -0
  120. package/skeleton/protocols/aspir/consult-types/spec-review.md +6 -0
  121. package/skeleton/protocols/aspir/prompts/specify.md +6 -0
  122. package/skeleton/protocols/aspir/protocol.md +4 -0
  123. package/skeleton/protocols/bugfix/consult-types/impl-review.md +44 -37
  124. package/skeleton/protocols/bugfix/consult-types/pr-review.md +65 -40
  125. package/skeleton/protocols/pir/builder-prompt.md +92 -0
  126. package/skeleton/protocols/pir/consult-types/impl-review.md +78 -0
  127. package/skeleton/protocols/pir/consult-types/pr-review.md +65 -0
  128. package/skeleton/protocols/pir/prompts/implement.md +156 -0
  129. package/skeleton/protocols/pir/prompts/plan.md +133 -0
  130. package/skeleton/protocols/pir/prompts/review.md +261 -0
  131. package/skeleton/protocols/pir/protocol.json +125 -0
  132. package/skeleton/protocols/pir/protocol.md +204 -0
  133. package/skeleton/protocols/spir/builder-prompt.md +19 -3
  134. package/skeleton/protocols/spir/consult-types/plan-review.md +6 -0
  135. package/skeleton/protocols/spir/consult-types/spec-review.md +6 -0
  136. package/skeleton/protocols/spir/prompts/specify.md +6 -0
  137. package/skeleton/protocols/spir/protocol.md +4 -0
  138. package/skeleton/templates/AGENTS.md +24 -0
  139. package/skeleton/templates/CLAUDE.md +24 -0
  140. package/dashboard-dist/assets/index-Dn9zmcKp.js.map +0 -1
@@ -9,6 +9,24 @@
9
9
  import path from 'node:path';
10
10
  import { parseAddress, stripLeadingZeros } from '../utils/agent-names.js';
11
11
  import { getWorkspaceTerminals } from './tower-terminals.js';
12
+ import { lookupBuilderSpawningArchitect } from '../state.js';
13
+ import { DEFAULT_ARCHITECT_NAME } from '../utils/architect-name.js';
14
+ // ============================================================================
15
+ // Spec 755 error messages — exported as constants so producer and asserter
16
+ // share a single source of truth. Tests assert these texts verbatim; changing
17
+ // the wording without updating both sides will break the build.
18
+ // ============================================================================
19
+ export function legacyBuilderErrorMessage(builderId, registered) {
20
+ const names = registered.length ? registered.join(', ') : '<none>';
21
+ return `legacy builder ${builderId} has no spawning-architect identity and no 'main' architect is registered (registered: ${names})`;
22
+ }
23
+ export function architectGoneErrorMessage(builderId, missingArchitect, registered) {
24
+ const names = registered.length ? registered.join(', ') : '<none>';
25
+ return `builder ${builderId} was spawned by architect ${missingArchitect}, which is no longer registered, and no 'main' architect is registered (registered: ${names})`;
26
+ }
27
+ export function addressSpoofingErrorMessage(builderId) {
28
+ return `builder ${builderId} may only address its own spawning architect`;
29
+ }
12
30
  /** Active WebSocket subscribers for the message bus. */
13
31
  const messageSubscribers = new Set();
14
32
  /**
@@ -50,11 +68,17 @@ export function getSubscriberCount() {
50
68
  * - Exact match (case-insensitive) first, then tail match
51
69
  * - Multiple tail matches → AMBIGUOUS error
52
70
  *
71
+ * Spec 755: when `sender` is supplied and refers to a builder, sender-affinity
72
+ * routing applies to `architect` and `architect:<name>` targets. Non-builder
73
+ * senders see the legacy main-first behavior, unchanged.
74
+ *
53
75
  * @param target - Address string: "agent" or "project:agent"
54
76
  * @param fallbackWorkspace - Workspace path when no project: prefix is given
77
+ * @param sender - Optional sender identity (a builder ID or 'architect').
78
+ * Enables affinity-aware architect routing per Spec 755.
55
79
  * @returns ResolveResult on success, ResolveError on failure
56
80
  */
57
- export function resolveTarget(target, fallbackWorkspace) {
81
+ export function resolveTarget(target, fallbackWorkspace, sender) {
58
82
  const { project, agent } = parseAddress(target);
59
83
  // Validate: empty or whitespace-only agent is a malformed address
60
84
  if (!agent || !agent.trim()) {
@@ -63,6 +87,20 @@ export function resolveTarget(target, fallbackWorkspace) {
63
87
  message: 'Malformed address: agent name is empty.',
64
88
  };
65
89
  }
90
+ // Spec 755: `architect:<name>` is a per-architect address WITHIN the
91
+ // current workspace, not a `project:agent` cross-workspace address.
92
+ // parseAddress can't distinguish them (the grammar is overloaded), so we
93
+ // intercept here. The resolver below applies the spoofing check when
94
+ // sender is a builder.
95
+ if (project && project.toLowerCase() === 'architect') {
96
+ if (!fallbackWorkspace) {
97
+ return {
98
+ code: 'NO_CONTEXT',
99
+ message: 'Cannot resolve architect:<name> address without workspace context.',
100
+ };
101
+ }
102
+ return resolveArchitectByName(agent, fallbackWorkspace, sender);
103
+ }
66
104
  // Determine the workspace path
67
105
  let workspacePath;
68
106
  if (project) {
@@ -81,7 +119,43 @@ export function resolveTarget(target, fallbackWorkspace) {
81
119
  workspacePath = fallbackWorkspace;
82
120
  }
83
121
  // Resolve agent within the workspace
84
- return resolveAgentInWorkspace(agent, workspacePath);
122
+ return resolveAgentInWorkspace(agent, workspacePath, sender);
123
+ }
124
+ /**
125
+ * Resolve `architect:<name>` to a terminal ID within the given workspace.
126
+ *
127
+ * Spec 755 enforcement when sender is a builder:
128
+ * - If the builder's `spawned_by_architect` matches `<name>`: allowed.
129
+ * - If it doesn't match: rejected with the spoofing error.
130
+ * Non-builder senders may address any architect by name.
131
+ */
132
+ function resolveArchitectByName(name, workspacePath, sender) {
133
+ const allWorkspaces = getWorkspaceTerminals();
134
+ const entry = allWorkspaces.get(workspacePath);
135
+ if (!entry) {
136
+ return {
137
+ code: 'NOT_FOUND',
138
+ message: `Workspace '${workspacePath}' has no registered terminals.`,
139
+ };
140
+ }
141
+ // Spoofing check: builder senders can only address their own architect.
142
+ if (sender) {
143
+ const spawningArchitect = lookupBuilderSpawningArchitect(sender, workspacePath);
144
+ if (spawningArchitect !== undefined && spawningArchitect !== name) {
145
+ return {
146
+ code: 'NOT_FOUND',
147
+ message: addressSpoofingErrorMessage(sender),
148
+ };
149
+ }
150
+ }
151
+ const terminalId = entry.architects.get(name);
152
+ if (!terminalId) {
153
+ return {
154
+ code: 'NOT_FOUND',
155
+ message: `Architect '${name}' not found in workspace '${path.basename(workspacePath)}'.`,
156
+ };
157
+ }
158
+ return { terminalId, workspacePath, agent: name };
85
159
  }
86
160
  /**
87
161
  * Find a workspace path by matching the basename of registered workspace paths.
@@ -111,9 +185,23 @@ function findWorkspaceByBasename(projectName) {
111
185
  /**
112
186
  * Resolve an agent name to a terminal ID within a specific workspace.
113
187
  *
114
- * Checks architect first, then builders by exact match, then builders by tail match.
188
+ * Checks architect first (with Spec 755 affinity-aware routing when `sender`
189
+ * is a builder), then builders by exact match, then builders by tail match.
190
+ *
191
+ * Spec 755 architect resolution:
192
+ * - Fast path: single-architect workspace with name 'main' — return that
193
+ * terminal directly. Identical to today's behavior; avoids the state.db
194
+ * read entirely for the common case.
195
+ * - Builder sender, target 'architect': look up the builder's
196
+ * spawnedByArchitect. If that architect is registered, route there.
197
+ * Otherwise fall back to 'main', else error with the spec-mandated
198
+ * legacy-builder / architect-gone messages.
199
+ * - Builder sender, target 'architect:<name>': allowed only if <name>
200
+ * matches the sender's spawnedByArchitect. Otherwise rejected (spoofing).
201
+ * - Non-builder sender (or no sender), target 'architect': route to 'main'
202
+ * (or first registered if 'main' is absent). Unchanged from today.
115
203
  */
116
- function resolveAgentInWorkspace(agent, workspacePath) {
204
+ function resolveAgentInWorkspace(agent, workspacePath, sender) {
117
205
  const allWorkspaces = getWorkspaceTerminals();
118
206
  const entry = allWorkspaces.get(workspacePath);
119
207
  if (!entry) {
@@ -122,16 +210,58 @@ function resolveAgentInWorkspace(agent, workspacePath) {
122
210
  message: `Workspace '${workspacePath}' has no registered terminals.`,
123
211
  };
124
212
  }
125
- // Check architect
213
+ // Check architect (Spec 755 affinity-aware path).
126
214
  if (agent === 'architect' || agent === 'arch') {
127
- if (!entry.architect) {
215
+ if (entry.architects.size === 0) {
128
216
  return {
129
217
  code: 'NOT_FOUND',
130
218
  message: `No architect terminal found in workspace '${path.basename(workspacePath)}'.`,
131
219
  };
132
220
  }
133
- return { terminalId: entry.architect, workspacePath, agent: 'architect' };
221
+ // Single-architect fast path: most workspaces have only 'main'.
222
+ // Identical answer to the full resolution path, but skips the state.db
223
+ // read entirely. Guarantees latency parity for solo-architect users.
224
+ if (entry.architects.size === 1 && entry.architects.has(DEFAULT_ARCHITECT_NAME)) {
225
+ const terminalId = entry.architects.get(DEFAULT_ARCHITECT_NAME);
226
+ return { terminalId, workspacePath, agent: 'architect' };
227
+ }
228
+ // Builder-context detection via state.db row presence. Three-valued
229
+ // result distinguishes "builder with explicit name" / "legacy builder"
230
+ // / "not a builder" — see lookupBuilderSpawningArchitect.
231
+ const spawningArchitect = sender ? lookupBuilderSpawningArchitect(sender, workspacePath) : undefined;
232
+ if (spawningArchitect !== undefined && sender) {
233
+ // Sender is a builder.
234
+ if (spawningArchitect === null) {
235
+ // Legacy builder: row exists, spawnedByArchitect is null. Route to
236
+ // 'main' if present; else fail with the spec's verbatim message.
237
+ const main = entry.architects.get(DEFAULT_ARCHITECT_NAME);
238
+ if (main)
239
+ return { terminalId: main, workspacePath, agent: 'architect' };
240
+ return {
241
+ code: 'NOT_FOUND',
242
+ message: legacyBuilderErrorMessage(sender, [...entry.architects.keys()]),
243
+ };
244
+ }
245
+ // Builder has an explicit spawning architect.
246
+ const target = entry.architects.get(spawningArchitect);
247
+ if (target)
248
+ return { terminalId: target, workspacePath, agent: 'architect' };
249
+ // Architect-gone fallback: route to 'main' if present; else fail.
250
+ const main = entry.architects.get(DEFAULT_ARCHITECT_NAME);
251
+ if (main)
252
+ return { terminalId: main, workspacePath, agent: 'architect' };
253
+ return {
254
+ code: 'NOT_FOUND',
255
+ message: architectGoneErrorMessage(sender, spawningArchitect, [...entry.architects.keys()]),
256
+ };
257
+ }
258
+ // Non-builder sender (or no sender): 'main' first, then first registered.
259
+ const terminalId = entry.architects.get(DEFAULT_ARCHITECT_NAME) ?? entry.architects.values().next().value;
260
+ return { terminalId, workspacePath, agent: 'architect' };
134
261
  }
262
+ // `architect:<name>` addressing is handled earlier in resolveTarget via
263
+ // resolveArchitectByName. Reaching this point means the agent is a plain
264
+ // workspace-local name (builder/shell), so we fall through to those.
135
265
  // Check builders — exact match (case-insensitive)
136
266
  for (const [builderId, terminalId] of entry.builders) {
137
267
  if (builderId.toLowerCase() === agent) {
@@ -1 +1 @@
1
- {"version":3,"file":"tower-messages.js","sourceRoot":"","sources":["../../../src/agent-farm/servers/tower-messages.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"tower-messages.js","sourceRoot":"","sources":["../../../src/agent-farm/servers/tower-messages.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"tower-routes.d.ts","sourceRoot":"","sources":["../../../src/agent-farm/servers/tower-routes.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,IAAI,MAAM,WAAW,CAAC;AAa7B,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mCAAmC,CAAC;AAIxE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAmElD,gFAAgF;AAChF,wBAAgB,eAAe,CAAC,GAAG,EAAE,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,GAAG,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK,IAAI,GAAG,IAAI,CAMtG;AAED,sGAAsG;AACtG,wBAAgB,cAAc,IAAI,IAAI,CAErC;AAMD,MAAM,WAAW,YAAY;IAC3B,GAAG,EAAE,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,GAAG,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IACjE,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,kBAAkB,EAAE,MAAM,CAAC;IAC3B,iBAAiB,EAAE,OAAO,CAAC;IAC3B,kBAAkB,EAAE,MAAM,cAAc,GAAG,IAAI,CAAC;IAChD,qBAAqB,EAAE,CAAC,YAAY,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAC;IACjH,YAAY,EAAE,CAAC,MAAM,EAAE,SAAS,KAAK,IAAI,CAAC;IAC1C,eAAe,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;CACvC;AAsCD,wBAAsB,aAAa,CACjC,GAAG,EAAE,IAAI,CAAC,eAAe,EACzB,GAAG,EAAE,IAAI,CAAC,cAAc,EACxB,GAAG,EAAE,YAAY,GAChB,OAAO,CAAC,IAAI,CAAC,CA6Ef"}
1
+ {"version":3,"file":"tower-routes.d.ts","sourceRoot":"","sources":["../../../src/agent-farm/servers/tower-routes.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,IAAI,MAAM,WAAW,CAAC;AAa7B,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mCAAmC,CAAC;AAIxE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAqElD,gFAAgF;AAChF,wBAAgB,eAAe,CAAC,GAAG,EAAE,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,GAAG,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK,IAAI,GAAG,IAAI,CAMtG;AAED,sGAAsG;AACtG,wBAAgB,cAAc,IAAI,IAAI,CAErC;AAMD,MAAM,WAAW,YAAY;IAC3B,GAAG,EAAE,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,GAAG,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IACjE,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,kBAAkB,EAAE,MAAM,CAAC;IAC3B,iBAAiB,EAAE,OAAO,CAAC;IAC3B,kBAAkB,EAAE,MAAM,cAAc,GAAG,IAAI,CAAC;IAChD,qBAAqB,EAAE,CAAC,YAAY,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAC;IACjH,YAAY,EAAE,CAAC,MAAM,EAAE,SAAS,KAAK,IAAI,CAAC;IAC1C,eAAe,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;CACvC;AAuCD,wBAAsB,aAAa,CACjC,GAAG,EAAE,IAAI,CAAC,eAAe,EACzB,GAAG,EAAE,IAAI,CAAC,cAAc,EACxB,GAAG,EAAE,YAAY,GAChB,OAAO,CAAC,IAAI,CAAC,CAmFf"}
@@ -32,8 +32,9 @@ import { resolveTarget, broadcastMessage, isResolveError } from './tower-message
32
32
  import { formatArchitectMessage, formatBuilderMessage } from '../utils/message-format.js';
33
33
  import { SendBuffer } from './send-buffer.js';
34
34
  import { writeMessageToSession } from './message-write.js';
35
- import { getKnownWorkspacePaths, getInstances, getDirectorySuggestions, launchInstance, killTerminalWithShellper, stopInstance, } from './tower-instances.js';
35
+ import { getKnownWorkspacePaths, getInstances, getDirectorySuggestions, launchInstance, killTerminalWithShellper, stopInstance, addArchitect, } from './tower-instances.js';
36
36
  import { OverviewCache } from './overview.js';
37
+ import { fetchIssue } from '../../lib/github.js';
37
38
  import { computeAnalytics } from './analytics.js';
38
39
  import { getAllTasks, executeTask, getTaskId } from './tower-cron.js';
39
40
  import { getGlobalDb } from '../db/index.js';
@@ -66,6 +67,7 @@ const ROUTES = {
66
67
  'GET /api/terminals': (_req, res) => handleTerminalList(res),
67
68
  'GET /api/status': (_req, res) => handleStatus(res),
68
69
  'GET /api/overview': (_req, res, url) => handleOverview(res, url),
70
+ 'GET /api/issue': (_req, res, url) => handleIssueView(res, url),
69
71
  'GET /api/analytics': (_req, res, url) => handleAnalytics(res, url),
70
72
  'POST /api/overview/refresh': (_req, res, _url, ctx) => handleOverviewRefresh(res, ctx),
71
73
  'GET /api/events': (req, res, _url, ctx) => handleSSEEvents(req, res, ctx),
@@ -124,6 +126,11 @@ export async function handleRequest(req, res, ctx) {
124
126
  if (workspaceApiMatch) {
125
127
  return await handleWorkspaceAction(req, res, ctx, workspaceApiMatch);
126
128
  }
129
+ // Workspace API: /api/workspaces/:encodedPath/architects (Spec 755 — multi-architect)
130
+ const architectsMatch = url.pathname.match(/^\/api\/workspaces\/([^/]+)\/architects$/);
131
+ if (architectsMatch) {
132
+ return await handleAddArchitect(req, res, architectsMatch);
133
+ }
127
134
  // Terminal-specific routes: /api/terminals/:id/* (Spec 0090 Phase 2)
128
135
  const terminalRouteMatch = url.pathname.match(/^\/api\/terminals\/([^/]+)(\/.*)?$/);
129
136
  if (terminalRouteMatch) {
@@ -176,6 +183,54 @@ async function handleListWorkspaces(res) {
176
183
  res.writeHead(200, { 'Content-Type': 'application/json' });
177
184
  res.end(JSON.stringify({ workspaces }));
178
185
  }
186
+ /**
187
+ * POST /api/workspaces/:encodedPath/architects (Spec 755)
188
+ * Body: { name?: string }
189
+ * Adds a named architect terminal to an active workspace.
190
+ * Returns 200 { success: true, name, terminalId } on success,
191
+ * 400 / 404 with { success: false, error } otherwise.
192
+ */
193
+ async function handleAddArchitect(req, res, match) {
194
+ if (req.method !== 'POST') {
195
+ res.writeHead(405, { 'Content-Type': 'application/json' });
196
+ res.end(JSON.stringify({ error: 'Method not allowed' }));
197
+ return;
198
+ }
199
+ const [, encodedPath] = match;
200
+ let workspacePath;
201
+ try {
202
+ workspacePath = decodeWorkspacePath(encodedPath);
203
+ if (!workspacePath || (!workspacePath.startsWith('/') && !/^[A-Za-z]:[\\/]/.test(workspacePath))) {
204
+ throw new Error('Invalid path');
205
+ }
206
+ workspacePath = normalizeWorkspacePath(workspacePath);
207
+ }
208
+ catch {
209
+ res.writeHead(400, { 'Content-Type': 'application/json' });
210
+ res.end(JSON.stringify({ error: 'Invalid workspace path encoding' }));
211
+ return;
212
+ }
213
+ let body;
214
+ try {
215
+ body = (await parseJsonBody(req));
216
+ }
217
+ catch {
218
+ res.writeHead(400, { 'Content-Type': 'application/json' });
219
+ res.end(JSON.stringify({ error: 'Invalid JSON body' }));
220
+ return;
221
+ }
222
+ const result = await addArchitect(workspacePath, body.name);
223
+ if (result.success) {
224
+ res.writeHead(200, { 'Content-Type': 'application/json' });
225
+ res.end(JSON.stringify({ success: true, name: result.name, terminalId: result.terminalId }));
226
+ }
227
+ else {
228
+ // Distinguish "workspace not active" (404) from validation errors (400).
229
+ const status = result.error?.includes('not running') ? 404 : 400;
230
+ res.writeHead(status, { 'Content-Type': 'application/json' });
231
+ res.end(JSON.stringify({ success: false, error: result.error }));
232
+ }
233
+ }
179
234
  async function handleWorkspaceAction(req, res, ctx, match) {
180
235
  const [, encodedPath, action] = match;
181
236
  let workspacePath;
@@ -549,6 +604,30 @@ async function handleOverview(res, url, workspaceOverride) {
549
604
  res.writeHead(200, { 'Content-Type': 'application/json' });
550
605
  res.end(JSON.stringify(data));
551
606
  }
607
+ async function handleIssueView(res, url) {
608
+ // Workspace resolution mirrors handleOverview: ?workspace= param, else
609
+ // the first known non-builder workspace path.
610
+ let workspaceRoot = url.searchParams.get('workspace');
611
+ if (!workspaceRoot) {
612
+ const knownPaths = getKnownWorkspacePaths();
613
+ workspaceRoot = knownPaths.find(p => !p.includes('/.builders/')) || null;
614
+ }
615
+ const number = url.searchParams.get('number');
616
+ if (!workspaceRoot || !number) {
617
+ res.writeHead(400, { 'Content-Type': 'application/json' });
618
+ res.end(JSON.stringify({ error: 'Missing workspace or number' }));
619
+ return;
620
+ }
621
+ // Routes through the `issue-view` forge concept (forge-agnostic).
622
+ const issue = await fetchIssue(number, { cwd: workspaceRoot });
623
+ if (!issue) {
624
+ res.writeHead(404, { 'Content-Type': 'application/json' });
625
+ res.end(JSON.stringify({ error: `Issue #${number} not found or forge unavailable` }));
626
+ return;
627
+ }
628
+ res.writeHead(200, { 'Content-Type': 'application/json' });
629
+ res.end(JSON.stringify(issue));
630
+ }
552
631
  function handleOverviewRefresh(res, ctx) {
553
632
  overviewCache.invalidate();
554
633
  // Bugfix #388: Broadcast SSE event so all connected dashboard clients
@@ -659,8 +738,10 @@ async function handleSend(req, res, ctx) {
659
738
  const raw = options.raw === true;
660
739
  const noEnter = options.noEnter === true;
661
740
  const interrupt = options.interrupt === true;
662
- // Resolve the target address to a terminal ID
663
- const result = resolveTarget(to, workspace);
741
+ // Resolve the target address to a terminal ID.
742
+ // Spec 755: pass `from` so architect resolution is sender-affinity-aware
743
+ // when the sender is a builder. Non-builder senders see unchanged behavior.
744
+ const result = resolveTarget(to, workspace, from);
664
745
  if (isResolveError(result)) {
665
746
  const statusCode = result.code === 'AMBIGUOUS' ? 409
666
747
  : result.code === 'NO_CONTEXT' ? 400
@@ -1120,8 +1201,11 @@ async function handleWorkspaceState(res, workspacePath) {
1120
1201
  // entry — see getRehydratedTerminalsEntry doc.
1121
1202
  const entry = await getRehydratedTerminalsEntry(workspacePath);
1122
1203
  const manager = getTerminalManager();
1204
+ // Spec 761: type as DashboardState directly to prevent inline-literal drift.
1205
+ // ArchitectState.name (Spec 761) carries the architect's stable identity.
1123
1206
  const state = {
1124
1207
  architect: null,
1208
+ architects: [],
1125
1209
  builders: [],
1126
1210
  utils: [],
1127
1211
  annotations: [],
@@ -1135,18 +1219,32 @@ async function handleWorkspaceState(res, workspacePath) {
1135
1219
  } })(),
1136
1220
  teamEnabled: await hasTeam(path.join(workspacePath, 'codev', 'team')),
1137
1221
  };
1138
- // Add architect if exists
1139
- if (entry.architect) {
1140
- const session = manager.getSession(entry.architect);
1141
- if (session) {
1142
- state.architect = {
1143
- port: 0,
1144
- pid: session.pid || 0,
1145
- terminalId: entry.architect,
1146
- persistent: isSessionPersistent(entry.architect, session),
1147
- };
1148
- }
1222
+ // Spec 761: build the architects collection from entry.architects.
1223
+ // - Skip entries whose session is unavailable (race / stale registration).
1224
+ // - Move 'main' to index 0 when present so consumers can rely on
1225
+ // architects[0] as the default architect.
1226
+ // Spec 755: the scalar `state.architect` is preserved as a backward-compat
1227
+ // pointer to the same default architect (architects[0] when present).
1228
+ const collectedArchitects = [];
1229
+ for (const [architectName, terminalId] of entry.architects) {
1230
+ const session = manager.getSession(terminalId);
1231
+ if (!session)
1232
+ continue;
1233
+ collectedArchitects.push({
1234
+ name: architectName,
1235
+ port: 0,
1236
+ pid: session.pid || 0,
1237
+ terminalId,
1238
+ persistent: isSessionPersistent(terminalId, session),
1239
+ });
1149
1240
  }
1241
+ const mainIdx = collectedArchitects.findIndex(a => a.name === 'main');
1242
+ if (mainIdx > 0) {
1243
+ const [mainEntry] = collectedArchitects.splice(mainIdx, 1);
1244
+ collectedArchitects.unshift(mainEntry);
1245
+ }
1246
+ state.architects = collectedArchitects;
1247
+ state.architect = collectedArchitects[0] ?? null;
1150
1248
  // Add shells from refreshed cache
1151
1249
  for (const [shellId, terminalId] of entry.shells) {
1152
1250
  const session = manager.getSession(terminalId);
@@ -1506,9 +1604,14 @@ async function handleWorkspaceTabDelete(res, ctx, workspacePath, tabId) {
1506
1604
  }
1507
1605
  }
1508
1606
  else if (tabId === 'architect') {
1509
- terminalId = entry.architect;
1510
- if (terminalId) {
1511
- entry.architect = undefined;
1607
+ // Spec 755: tabId 'architect' targets the architect surfaced by /api/state
1608
+ // — prefer 'main', else the first registered.
1609
+ const name = entry.architects.has('main')
1610
+ ? 'main'
1611
+ : entry.architects.keys().next().value;
1612
+ if (name) {
1613
+ terminalId = entry.architects.get(name);
1614
+ entry.architects.delete(name);
1512
1615
  }
1513
1616
  }
1514
1617
  if (terminalId) {
@@ -1527,9 +1630,10 @@ async function handleWorkspaceTabDelete(res, ctx, workspacePath, tabId) {
1527
1630
  async function handleWorkspaceStopAll(res, workspacePath) {
1528
1631
  const entry = getWorkspaceTerminalsEntry(workspacePath);
1529
1632
  const manager = getTerminalManager();
1530
- // Kill all terminals (disable shellper auto-restart if applicable)
1531
- if (entry.architect) {
1532
- await killTerminalWithShellper(manager, entry.architect);
1633
+ // Kill all terminals (disable shellper auto-restart if applicable).
1634
+ // Spec 755: iterate all named architects, not just the singleton.
1635
+ for (const terminalId of entry.architects.values()) {
1636
+ await killTerminalWithShellper(manager, terminalId);
1533
1637
  }
1534
1638
  for (const terminalId of entry.shells.values()) {
1535
1639
  await killTerminalWithShellper(manager, terminalId);