@clipboard-health/groundcrew 4.26.0 → 4.26.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 (50) hide show
  1. package/dist/cli.js +2 -2
  2. package/dist/commands/dispatcher.d.ts +2 -2
  3. package/dist/commands/dispatcher.js +19 -19
  4. package/dist/commands/doctor.js +14 -14
  5. package/dist/commands/eligibility.d.ts +19 -19
  6. package/dist/commands/eligibility.d.ts.map +1 -1
  7. package/dist/commands/eligibility.js +21 -21
  8. package/dist/commands/init.d.ts +4 -4
  9. package/dist/commands/init.js +17 -17
  10. package/dist/commands/interruptWorkspace.js +3 -3
  11. package/dist/commands/orchestrator.js +2 -2
  12. package/dist/commands/resumeWorkspace.js +9 -9
  13. package/dist/commands/setupWorkspace.d.ts +1 -1
  14. package/dist/commands/setupWorkspace.js +14 -14
  15. package/dist/commands/status.js +4 -4
  16. package/dist/commands/task.js +8 -8
  17. package/dist/index.d.ts +3 -3
  18. package/dist/index.js +2 -2
  19. package/dist/lib/adapterDefinition.d.ts +1 -1
  20. package/dist/lib/adapters/linear/create.js +1 -1
  21. package/dist/lib/adapters/linear/factory.js +2 -2
  22. package/dist/lib/adapters/linear/fetch.d.ts +6 -6
  23. package/dist/lib/adapters/linear/fetch.js +28 -28
  24. package/dist/lib/adapters/linear/parsing.d.ts +7 -7
  25. package/dist/lib/adapters/linear/parsing.d.ts.map +1 -1
  26. package/dist/lib/adapters/linear/parsing.js +14 -14
  27. package/dist/lib/adapters/shell/factory.js +1 -1
  28. package/dist/lib/adapters/shell/schema.d.ts +3 -3
  29. package/dist/lib/adapters/shell/schema.js +2 -2
  30. package/dist/lib/adapters/todo-txt/normalizer.js +3 -3
  31. package/dist/lib/adapters/todo-txt/source.d.ts.map +1 -1
  32. package/dist/lib/adapters/todo-txt/source.js +5 -7
  33. package/dist/lib/agentLaunch.d.ts +4 -4
  34. package/dist/lib/agentLaunch.js +7 -7
  35. package/dist/lib/cmuxAdapter.js +1 -1
  36. package/dist/lib/config.d.ts +22 -22
  37. package/dist/lib/config.d.ts.map +1 -1
  38. package/dist/lib/config.js +47 -44
  39. package/dist/lib/launchCommand.d.ts +4 -4
  40. package/dist/lib/launchCommand.js +4 -4
  41. package/dist/lib/runState.d.ts +2 -2
  42. package/dist/lib/runState.js +4 -4
  43. package/dist/lib/srtLaunch.d.ts +2 -2
  44. package/dist/lib/taskSource.d.ts +4 -4
  45. package/dist/lib/taskSource.d.ts.map +1 -1
  46. package/dist/lib/taskSource.js +1 -1
  47. package/dist/lib/testing/canonicalFixtures.js +2 -2
  48. package/dist/lib/usage.d.ts +7 -7
  49. package/dist/lib/usage.js +20 -20
  50. package/package.json +1 -1
@@ -35,7 +35,7 @@ async function contextFromLinear(config, task, worktree) {
35
35
  return {
36
36
  task,
37
37
  repository: resolved.repository,
38
- model: resolved.model,
38
+ agent: resolved.agent,
39
39
  worktree,
40
40
  title: resolved.title,
41
41
  description: resolved.description,
@@ -50,7 +50,7 @@ async function contextFromState(config, task, state, worktree) {
50
50
  return {
51
51
  task,
52
52
  repository: state.repository,
53
- model: state.model,
53
+ agent: state.agent,
54
54
  worktree,
55
55
  title: details?.title ?? task.toUpperCase(),
56
56
  description: details?.description ?? "",
@@ -70,7 +70,7 @@ async function buildResumeContext(config, task) {
70
70
  if (state !== undefined) {
71
71
  return await contextFromState(config, task, state, worktree);
72
72
  }
73
- // The cold-resume path resolves repository + model from Linear alone, so it
73
+ // The cold-resume path resolves repository + agent from Linear alone, so it
74
74
  // can't proceed when Linear is disabled. Fail with a clear reason instead of
75
75
  // the cryptic missing-API-key error getLinearClient() would otherwise raise.
76
76
  if (!isLinearEnabled(config)) {
@@ -113,13 +113,13 @@ export async function resumeWorkspace(config, options) {
113
113
  const task = options.task.toLowerCase();
114
114
  await failIfWorkspaceAlreadyLive(config, task);
115
115
  const context = await buildResumeContext(config, task);
116
- const definition = config.models.definitions[context.model];
116
+ const definition = config.agents.definitions[context.agent];
117
117
  if (definition === undefined) {
118
- throw new Error(`Unknown model: ${context.model}`);
118
+ throw new Error(`Unknown agent: ${context.agent}`);
119
119
  }
120
120
  const { runner, sandboxName, ensureReady } = await prepareAgentLaunch({
121
121
  config,
122
- model: context.model,
122
+ agent: context.agent,
123
123
  definition,
124
124
  purpose: "resumes",
125
125
  });
@@ -169,7 +169,7 @@ export async function resumeWorkspace(config, options) {
169
169
  name: task,
170
170
  cwd: context.worktree.dir,
171
171
  command: launchCmd,
172
- model: context.model,
172
+ agent: context.agent,
173
173
  color: definition.color,
174
174
  });
175
175
  }
@@ -187,7 +187,7 @@ export async function resumeWorkspace(config, options) {
187
187
  state: {
188
188
  task,
189
189
  repository: context.repository,
190
- model: context.model,
190
+ agent: context.agent,
191
191
  worktreeDir: context.worktree.dir,
192
192
  branchName: context.worktree.branchName,
193
193
  workspaceName: task,
@@ -196,7 +196,7 @@ export async function resumeWorkspace(config, options) {
196
196
  ...(context.reason === undefined ? {} : { reason: context.reason }),
197
197
  },
198
198
  });
199
- log(`Resumed ${task} in ${context.worktree.dir} (${context.model})`);
199
+ log(`Resumed ${task} in ${context.worktree.dir} (${context.agent})`);
200
200
  }
201
201
  export async function resumeWorkspaceCli(argv) {
202
202
  const config = await loadConfig();
@@ -8,7 +8,7 @@ export interface TaskDetails {
8
8
  export interface SetupWorkspaceOptions {
9
9
  task: string;
10
10
  repository: string;
11
- model: string;
11
+ agent: string;
12
12
  details: TaskDetails;
13
13
  }
14
14
  export interface SetupWorkspaceRunOptions {
@@ -27,15 +27,15 @@ function stagePrompt(input) {
27
27
  });
28
28
  }
29
29
  export async function setupWorkspace(config, options, runOptions = {}) {
30
- const { task, repository, model } = options;
30
+ const { task, repository, agent } = options;
31
31
  const { signal } = runOptions;
32
- const definition = config.models.definitions[model];
32
+ const definition = config.agents.definitions[agent];
33
33
  if (!definition) {
34
- throw new Error(`Unknown model: ${model}`);
34
+ throw new Error(`Unknown agent: ${agent}`);
35
35
  }
36
36
  const { runner, sandboxName, ensureReady } = await prepareAgentLaunch({
37
37
  config,
38
- model,
38
+ agent,
39
39
  definition,
40
40
  purpose: "runs",
41
41
  ...(signal === undefined ? {} : { signal }),
@@ -117,7 +117,7 @@ export async function setupWorkspace(config, options, runOptions = {}) {
117
117
  name: task,
118
118
  cwd: launchDir,
119
119
  command: launchCmd,
120
- model,
120
+ agent,
121
121
  color: definition.color,
122
122
  ...(signal === undefined ? {} : { signal }),
123
123
  });
@@ -125,7 +125,7 @@ export async function setupWorkspace(config, options, runOptions = {}) {
125
125
  config,
126
126
  task,
127
127
  repository,
128
- model,
128
+ agent,
129
129
  worktreeDir: launchDir,
130
130
  branchName,
131
131
  workspaceName: task,
@@ -133,7 +133,7 @@ export async function setupWorkspace(config, options, runOptions = {}) {
133
133
  title: taskDetails.title,
134
134
  ...(taskDetails.url === undefined ? {} : { url: taskDetails.url }),
135
135
  });
136
- log(`${okMark()} "${task}" launched (${model}) worktree ${worktreeName}`);
136
+ log(`${okMark()} "${task}" launched (${agent}) worktree ${worktreeName}`);
137
137
  debug(` Worktree: ${launchDir}`);
138
138
  debug(` Branch: ${branchName}`);
139
139
  if (accessHint !== undefined) {
@@ -146,7 +146,7 @@ export async function setupWorkspace(config, options, runOptions = {}) {
146
146
  config,
147
147
  task,
148
148
  repository,
149
- model,
149
+ agent,
150
150
  worktreeDir: launchDir,
151
151
  branchName,
152
152
  workspaceName: task,
@@ -209,7 +209,7 @@ function recordRunStateBestEffort(arguments_) {
209
209
  state: {
210
210
  task: arguments_.task,
211
211
  repository: arguments_.repository,
212
- model: arguments_.model,
212
+ agent: arguments_.agent,
213
213
  worktreeDir: arguments_.worktreeDir,
214
214
  branchName: arguments_.branchName,
215
215
  workspaceName: arguments_.workspaceName,
@@ -282,19 +282,19 @@ export async function setupWorkspaceCli(task, options = {}) {
282
282
  if (resolved === undefined) {
283
283
  throw new Error(`Task ${task} not found across configured sources.`);
284
284
  }
285
- if (resolved.repository === undefined || resolved.model === undefined) {
286
- throw new Error(`Task ${task} resolved but isn't groundcrew-eligible (missing agent-* label or repository/model).`);
285
+ if (resolved.repository === undefined || resolved.agent === undefined) {
286
+ throw new Error(`Task ${task} resolved but isn't groundcrew-eligible (missing agent-* label or repository/agent).`);
287
287
  }
288
- log(`Resolved ${task}: repository=${resolved.repository}, model=${resolved.model}`);
288
+ log(`Resolved ${task}: repository=${resolved.repository}, agent=${resolved.agent}`);
289
289
  if (options.dryRun === true) {
290
- log(`[dry-run] Would launch ${task} in ${resolved.repository} (${resolved.model})`);
290
+ log(`[dry-run] Would launch ${task} in ${resolved.repository} (${resolved.agent})`);
291
291
  return;
292
292
  }
293
293
  const naturalId = naturalIdFromCanonical(resolved.id);
294
294
  await setupWorkspace(config, {
295
295
  task: naturalId,
296
296
  repository: resolved.repository,
297
- model: resolved.model,
297
+ agent: resolved.agent,
298
298
  details: {
299
299
  title: resolved.title,
300
300
  description: resolved.description,
@@ -81,9 +81,9 @@ function formatRunState(state, flags = []) {
81
81
  return "(none)";
82
82
  }
83
83
  // Only the leading lifecycle token gains the reconciliation flags; the
84
- // `;`-separated detail (model/updated/resumes/reason) is preserved verbatim.
84
+ // `;`-separated detail (agent/updated/resumes/reason) is preserved verbatim.
85
85
  const lifecycle = flags.length === 0 ? state.state : `${state.state} (${flags.join(", ")})`;
86
- const summary = `${lifecycle}; model=${state.model}; updated=${state.updatedAt}; resumes=${state.resumeCount}`;
86
+ const summary = `${lifecycle}; agent=${state.agent}; updated=${state.updatedAt}; resumes=${state.resumeCount}`;
87
87
  const detail = state.reason ?? state.detail;
88
88
  return detail === undefined ? summary : `${summary}; ${detail}`;
89
89
  }
@@ -426,7 +426,7 @@ function writeQueueIssue(issue) {
426
426
  writeOutput(issue.url === undefined ? naturalId : `${naturalId} ${issue.url}`);
427
427
  writeOutput(inventoryField("title", issue.title));
428
428
  writeOutput(inventoryField("repo", issue.repository));
429
- writeOutput(inventoryField("model", issue.model));
429
+ writeOutput(inventoryField("agent", issue.agent));
430
430
  }
431
431
  async function buildBoardForStatus(config) {
432
432
  const sources = await buildSources(sourcesFromConfig(config), { globalConfig: config });
@@ -480,7 +480,7 @@ function writeQueueSections(boardResult) {
480
480
  return;
481
481
  }
482
482
  // Only groundcrew-eligible Todos are dispatchable; non-eligible ones lack
483
- // a repo or model, so `crew run` would skip them.
483
+ // a repo or agent, so `crew run` would skip them.
484
484
  const todos = boardResult.issues.filter(isTodoSourceIssue).filter(isGroundcrewIssue);
485
485
  const ready = todos.filter((i) => !hasOpenBlocker(i));
486
486
  const blocked = todos.filter(hasOpenBlocker);
@@ -1,5 +1,5 @@
1
1
  import { buildSources, sourcesFromConfig } from "../lib/buildSources.js";
2
- import { AGENT_ANY_MODEL, loadConfig } from "../lib/config.js";
2
+ import { AGENT_ANY, loadConfig } from "../lib/config.js";
3
3
  import { naturalIdFromCanonical, } from "../lib/taskSource.js";
4
4
  import { parseSourceFilterArgs, writeOutput } from "../lib/util.js";
5
5
  const TASK_USAGE = `Usage: crew task <subcommand>
@@ -14,7 +14,7 @@ const LIST_USAGE = `Usage: crew task list [options]
14
14
  Options:
15
15
  --source <name> Limit to one source.
16
16
  --status <status> Filter by status. Repeatable.
17
- --agent <name> Filter by agent/model.
17
+ --agent <name> Filter by agent name.
18
18
  --repo <owner/repo> Filter by repository.
19
19
  --blocked Show only blocked tasks.
20
20
  --unblocked Show only unblocked tasks.
@@ -235,7 +235,7 @@ function parseCreateOptions(argv) {
235
235
  }
236
236
  const input = {
237
237
  title,
238
- agent: state.agent ?? AGENT_ANY_MODEL,
238
+ agent: state.agent ?? AGENT_ANY,
239
239
  projects: state.projects,
240
240
  contexts: state.contexts,
241
241
  dependencies: state.dependencies,
@@ -271,7 +271,7 @@ function filterTasks(tasks, options) {
271
271
  filtered = filtered.filter((task) => options.statuses.includes(task.status));
272
272
  }
273
273
  if (options.agent !== undefined) {
274
- filtered = filtered.filter((task) => task.model === options.agent);
274
+ filtered = filtered.filter((task) => task.agent === options.agent);
275
275
  }
276
276
  if (options.repository !== undefined) {
277
277
  filtered = filtered.filter((task) => task.repository === options.repository);
@@ -295,7 +295,7 @@ function printableTask(task) {
295
295
  description: task.description,
296
296
  status: task.status,
297
297
  repository: task.repository,
298
- model: task.model,
298
+ agent: task.agent,
299
299
  assignee: task.assignee,
300
300
  updatedAt: task.updatedAt,
301
301
  blockers: task.blockers,
@@ -318,7 +318,7 @@ function writeTaskTable(tasks) {
318
318
  const rows = tasks.map((task) => ({
319
319
  id: task.id,
320
320
  status: task.status,
321
- agent: task.model ?? "-",
321
+ agent: task.agent ?? "-",
322
322
  repository: task.repository ?? "-",
323
323
  blocked: taskIsBlocked(task) ? "yes" : "no",
324
324
  title: task.title,
@@ -418,8 +418,8 @@ function writeTaskDetails(task) {
418
418
  if (task.repository !== undefined) {
419
419
  writeOutput(`repo: ${task.repository}`);
420
420
  }
421
- if (task.model !== undefined) {
422
- writeOutput(`agent: ${task.model}`);
421
+ if (task.agent !== undefined) {
422
+ writeOutput(`agent: ${task.agent}`);
423
423
  }
424
424
  if (task.url !== undefined) {
425
425
  writeOutput(`url: ${task.url}`);
package/dist/index.d.ts CHANGED
@@ -6,12 +6,12 @@ export { orchestrate, type OrchestratorOptions } from "./commands/orchestrator.t
6
6
  export { resumeWorkspace, type ResumeWorkspaceOptions } from "./commands/resumeWorkspace.ts";
7
7
  export { setupWorkspace, type SetupWorkspaceOptions } from "./commands/setupWorkspace.ts";
8
8
  export { status, type StatusOptions } from "./commands/status.ts";
9
- export type { Config, HookCommands, ModelDefinition, ResolvedConfig, SourceConfig, } from "./lib/config.ts";
9
+ export type { Config, HookCommands, AgentDefinition, ResolvedConfig, SourceConfig, } from "./lib/config.ts";
10
10
  export { loadConfig } from "./lib/config.ts";
11
11
  export { readRunState, recordRunState, removeRunState, runStateDirectory, runStatePath, updateRunState, type RunLifecycleState, type RunState, } from "./lib/runState.ts";
12
12
  export { fetchBlockersForTask, fetchInProgressIssueCount, fetchRawLinearIssue, fetchResolvedIssue, isIssueInProgress, isIssueTodo, isTerminalStateType, isTerminalStatusForBlocker, isTerminalStatusForIssue, type RawLinearIssue, } from "./lib/adapters/linear/fetch.ts";
13
- export { resolveModelFor, resolveRepositoryFor, type ModelResolution, type RepositoryResolution, } from "./lib/adapters/linear/parsing.ts";
14
- export { getUsageByModel, type UsageByModel } from "./lib/usage.ts";
13
+ export { resolveAgentFor, resolveRepositoryFor, type AgentResolution, type RepositoryResolution, } from "./lib/adapters/linear/parsing.ts";
14
+ export { getUsageByAgent, type UsageByAgent } from "./lib/usage.ts";
15
15
  export { type Board, createBoard } from "./lib/board.ts";
16
16
  export { buildSources, buildSourcesWith } from "./lib/buildSources.ts";
17
17
  export type { AdapterContext, AdapterDefinition } from "./lib/adapterDefinition.ts";
package/dist/index.js CHANGED
@@ -9,8 +9,8 @@ export { status } from "./commands/status.js";
9
9
  export { loadConfig } from "./lib/config.js";
10
10
  export { readRunState, recordRunState, removeRunState, runStateDirectory, runStatePath, updateRunState, } from "./lib/runState.js";
11
11
  export { fetchBlockersForTask, fetchInProgressIssueCount, fetchRawLinearIssue, fetchResolvedIssue, isIssueInProgress, isIssueTodo, isTerminalStateType, isTerminalStatusForBlocker, isTerminalStatusForIssue, } from "./lib/adapters/linear/fetch.js";
12
- export { resolveModelFor, resolveRepositoryFor, } from "./lib/adapters/linear/parsing.js";
13
- export { getUsageByModel } from "./lib/usage.js";
12
+ export { resolveAgentFor, resolveRepositoryFor, } from "./lib/adapters/linear/parsing.js";
13
+ export { getUsageByAgent } from "./lib/usage.js";
14
14
  export { createBoard } from "./lib/board.js";
15
15
  export { buildSources, buildSourcesWith } from "./lib/buildSources.js";
16
16
  export { adapterRegistry, buildRegistry, buildSourceConfigSchema, listAdapterDirectories, } from "./lib/adapters/registry.js";
@@ -10,7 +10,7 @@ import type { TaskSource } from "./taskSource.ts";
10
10
  /**
11
11
  * Cross-cutting context every adapter receives at construction time. Holds
12
12
  * the global resolved config so adapters can read shared concerns (the
13
- * `workspace.knownRepositories` list, `models.*` definitions, etc.) without
13
+ * `workspace.knownRepositories` list, `agents.*` definitions, etc.) without
14
14
  * each one duplicating them in its per-source config block.
15
15
  */
16
16
  export interface AdapterContext {
@@ -51,7 +51,7 @@ export async function createLinearIssue(arguments_) {
51
51
  assignee: resolved.assignee,
52
52
  updatedAt: resolved.updatedAt,
53
53
  repository: resolved.repository,
54
- model: resolved.model,
54
+ agent: resolved.agent,
55
55
  teamId: resolved.teamId,
56
56
  blockers: resolved.blockers,
57
57
  hasMoreBlockers: resolved.hasMoreBlockers,
@@ -76,7 +76,7 @@ export function toCanonicalIssue(linearIssue, sourceName, statusNames = DEFAULT_
76
76
  statusNames,
77
77
  }),
78
78
  repository: linearIssue.repository,
79
- model: linearIssue.model,
79
+ agent: linearIssue.agent,
80
80
  assignee: linearIssue.assignee,
81
81
  updatedAt: linearIssue.updatedAt,
82
82
  blockers: linearIssue.blockers.map((b) => toCanonicalBlocker(b, sourceName, statusNames)),
@@ -150,7 +150,7 @@ export function createLinearTaskSource(config, context) {
150
150
  statusNames,
151
151
  }),
152
152
  repository: resolved.repository,
153
- model: resolved.model,
153
+ agent: resolved.agent,
154
154
  assignee: resolved.assignee,
155
155
  updatedAt: resolved.updatedAt,
156
156
  blockers: resolved.blockers.map((b) => toCanonicalBlocker(b, sourceName, statusNames)),
@@ -9,7 +9,7 @@
9
9
  */
10
10
  import type { LinearClient } from "@linear/sdk";
11
11
  import type { ResolvedConfig } from "../../config.ts";
12
- import { type ModelResolution } from "./parsing.ts";
12
+ import { type AgentResolution } from "./parsing.ts";
13
13
  export declare const ISSUES_PAGE_SIZE = 250;
14
14
  export interface Blocker {
15
15
  id: string;
@@ -41,7 +41,7 @@ export interface Issue {
41
41
  */
42
42
  repository: string | undefined;
43
43
  /** Parsed from the `agent-*` label when present, including non-Todo tasks for slot logs. */
44
- model: string | undefined;
44
+ agent: string | undefined;
45
45
  teamId: string;
46
46
  blockers: Blocker[];
47
47
  hasMoreBlockers: boolean;
@@ -56,7 +56,7 @@ export interface Issue {
56
56
  * variant just shapes the adapter's local Linear type.
57
57
  */
58
58
  export type GroundcrewIssue = Issue & {
59
- model: string;
59
+ agent: string;
60
60
  repository: string;
61
61
  };
62
62
  /**
@@ -103,7 +103,7 @@ export interface IssueRelationNode {
103
103
  } | null;
104
104
  } | null;
105
105
  }
106
- export declare function modelForResolution(resolution: Exclude<ModelResolution, {
106
+ export declare function agentForResolution(resolution: Exclude<AgentResolution, {
107
107
  kind: "no-label";
108
108
  }>): string;
109
109
  interface ResolvedIssue {
@@ -111,7 +111,7 @@ interface ResolvedIssue {
111
111
  title: string;
112
112
  description: string;
113
113
  repository: string;
114
- model: string;
114
+ agent: string;
115
115
  teamId: string;
116
116
  stateType: string;
117
117
  status: string;
@@ -168,7 +168,7 @@ export declare function fetchResolvedIssue(arguments_: {
168
168
  config: ResolvedConfig;
169
169
  task: string;
170
170
  }): Promise<ResolvedIssue>;
171
- export declare function warnIfNotEnabledFallback(task: string, modelResolution: ModelResolution, config: ResolvedConfig): void;
171
+ export declare function warnIfNotEnabledFallback(task: string, agentResolution: AgentResolution, config: ResolvedConfig): void;
172
172
  export declare function blockersFromRelations(relations: IssueRelationNode[]): Blocker[];
173
173
  export {};
174
174
  //# sourceMappingURL=fetch.d.ts.map
@@ -9,7 +9,7 @@
9
9
  */
10
10
  import { RepositoryResolutionError } from "../../taskSource.js";
11
11
  import { log, styleWarning } from "../../util.js";
12
- import { AGENT_LABEL_PREFIX, resolveModelFor, resolveRepositoryFor, } from "./parsing.js";
12
+ import { AGENT_LABEL_PREFIX, resolveAgentFor, resolveRepositoryFor, } from "./parsing.js";
13
13
  export const ISSUES_PAGE_SIZE = 250;
14
14
  // `state.type` values surfaced by `fetch()`. `backlog` / `triage` are dropped
15
15
  // at the GraphQL filter; everything else is post-classified by these names.
@@ -134,34 +134,34 @@ async function fetchBoard(client, config) {
134
134
  }));
135
135
  return { timestamp: new Date().toISOString(), issues, parentSkips };
136
136
  }
137
- export function modelForResolution(resolution) {
137
+ export function agentForResolution(resolution) {
138
138
  if (resolution.kind === "matched") {
139
- return resolution.model;
139
+ return resolution.agent;
140
140
  }
141
141
  if (resolution.kind === "not-enabled-fallback") {
142
- return resolution.fallbackModel;
142
+ return resolution.fallbackAgent;
143
143
  }
144
144
  return "any";
145
145
  }
146
146
  function resolveAgentMetadata(arguments_) {
147
- const { task, description, modelResolution, config, isTodo } = arguments_;
147
+ const { task, description, agentResolution, config, isTodo } = arguments_;
148
148
  let repository;
149
- let model;
150
- if (modelResolution.kind === "no-label") {
151
- return { repository, model };
149
+ let agent;
150
+ if (agentResolution.kind === "no-label") {
151
+ return { repository, agent };
152
152
  }
153
- model = modelForResolution(modelResolution);
153
+ agent = agentForResolution(agentResolution);
154
154
  if (isTodo) {
155
155
  const resolution = resolveRepositoryFor({ description, config });
156
156
  if (resolution.kind === "ok") {
157
157
  ({ repository } = resolution);
158
158
  }
159
159
  else {
160
- model = undefined;
160
+ agent = undefined;
161
161
  log(styleWarning(`WARNING: ${task} has an ${AGENT_LABEL_PREFIX}* label but no known repository in its description; skipping dispatch. Add one of workspace.knownRepositories to the description, or remove the ${AGENT_LABEL_PREFIX}* label: ${config.workspace.knownRepositories.join(", ")}`));
162
162
  }
163
163
  }
164
- return { repository, model };
164
+ return { repository, agent };
165
165
  }
166
166
  function buildLinearIssue(input) {
167
167
  return {
@@ -176,7 +176,7 @@ function buildLinearIssue(input) {
176
176
  assignee: input.assigneeName ?? "Unassigned",
177
177
  updatedAt: input.updatedAt,
178
178
  repository: input.repository,
179
- model: input.model,
179
+ agent: input.agent,
180
180
  teamId: input.teamId,
181
181
  url: input.url,
182
182
  priority: input.priority,
@@ -185,13 +185,13 @@ function buildLinearIssue(input) {
185
185
  };
186
186
  }
187
187
  function issueFromNode(node, config) {
188
- const modelResolution = resolveModelFor({ labels: node.labels.nodes, config });
189
- warnIfNotEnabledFallback(node.identifier, modelResolution, config);
190
- const { repository, model } = resolveAgentMetadata({
188
+ const agentResolution = resolveAgentFor({ labels: node.labels.nodes, config });
189
+ warnIfNotEnabledFallback(node.identifier, agentResolution, config);
190
+ const { repository, agent } = resolveAgentMetadata({
191
191
  task: node.identifier,
192
192
  /* v8 ignore next @preserve -- BoardIssues query selects description; the ?? guard normalises a null vs undefined edge */
193
193
  description: node.description ?? undefined,
194
- modelResolution,
194
+ agentResolution,
195
195
  config,
196
196
  isTodo: node.state?.type === "unstarted",
197
197
  });
@@ -210,7 +210,7 @@ function issueFromNode(node, config) {
210
210
  assigneeName: node.assignee?.name,
211
211
  updatedAt: node.updatedAt,
212
212
  repository,
213
- model,
213
+ agent,
214
214
  teamId: node.team?.id ?? "",
215
215
  url: node.url,
216
216
  priority: node.priority,
@@ -365,21 +365,21 @@ export async function fetchResolvedIssue(arguments_) {
365
365
  repositories: config.workspace.knownRepositories,
366
366
  });
367
367
  }
368
- const modelResolution = resolveModelFor({ labels: raw.labels, config });
369
- warnIfNotEnabledFallback(task, modelResolution, config);
370
- let model = config.models.default;
371
- if (modelResolution.kind === "matched") {
372
- ({ model } = modelResolution);
368
+ const agentResolution = resolveAgentFor({ labels: raw.labels, config });
369
+ warnIfNotEnabledFallback(task, agentResolution, config);
370
+ let agent = config.agents.default;
371
+ if (agentResolution.kind === "matched") {
372
+ ({ agent } = agentResolution);
373
373
  }
374
- else if (modelResolution.kind === "not-enabled-fallback") {
375
- model = modelResolution.fallbackModel;
374
+ else if (agentResolution.kind === "not-enabled-fallback") {
375
+ agent = agentResolution.fallbackAgent;
376
376
  }
377
377
  return {
378
378
  uuid: raw.uuid,
379
379
  title: raw.title,
380
380
  description: raw.description,
381
381
  repository: repositoryResolution.repository,
382
- model,
382
+ agent,
383
383
  teamId: raw.teamId,
384
384
  stateType: raw.stateType,
385
385
  status: raw.stateName,
@@ -392,11 +392,11 @@ export async function fetchResolvedIssue(arguments_) {
392
392
  priority: raw.priority,
393
393
  };
394
394
  }
395
- export function warnIfNotEnabledFallback(task, modelResolution, config) {
396
- if (modelResolution.kind !== "not-enabled-fallback") {
395
+ export function warnIfNotEnabledFallback(task, agentResolution, config) {
396
+ if (agentResolution.kind !== "not-enabled-fallback") {
397
397
  return;
398
398
  }
399
- log(`${task.toLowerCase()}: agent-${modelResolution.requestedModel} label refers to a model that is not enabled; falling back to models.default (${config.models.default})`);
399
+ log(`${task.toLowerCase()}: agent-${agentResolution.requestedAgent} label refers to an agent that is not enabled; falling back to agents.default (${config.agents.default})`);
400
400
  }
401
401
  export function blockersFromRelations(relations) {
402
402
  return relations
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Linear adapter — parsing helpers for model/repository resolution from
2
+ * Linear adapter — parsing helpers for agent/repository resolution from
3
3
  * issue labels and descriptions. Extracted from boardSource.ts (Task 10).
4
4
  */
5
5
  import { type ResolvedConfig } from "../../config.ts";
@@ -10,17 +10,17 @@ export type RepositoryResolution = {
10
10
  } | {
11
11
  kind: "missing";
12
12
  };
13
- export type ModelResolution = {
13
+ export type AgentResolution = {
14
14
  kind: "matched";
15
- model: string;
15
+ agent: string;
16
16
  } | {
17
17
  kind: "no-label";
18
18
  } | {
19
19
  kind: "agent-any";
20
20
  } | {
21
21
  kind: "not-enabled-fallback";
22
- requestedModel: string;
23
- fallbackModel: string;
22
+ requestedAgent: string;
23
+ fallbackAgent: string;
24
24
  };
25
25
  export declare function buildRepositoryRegex(config: ResolvedConfig): RegExp;
26
26
  export declare function resolveRepositoryFor(arguments_: {
@@ -34,11 +34,11 @@ interface ParseRepositoryArguments {
34
34
  task: string;
35
35
  }
36
36
  export declare function parseRepository(arguments_: ParseRepositoryArguments): string;
37
- export declare function resolveModelFor(arguments_: {
37
+ export declare function resolveAgentFor(arguments_: {
38
38
  labels: {
39
39
  name: string;
40
40
  }[];
41
41
  config: ResolvedConfig;
42
- }): ModelResolution;
42
+ }): AgentResolution;
43
43
  export {};
44
44
  //# sourceMappingURL=parsing.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"parsing.d.ts","sourceRoot":"","sources":["../../../../src/lib/adapters/linear/parsing.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAA6C,KAAK,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAGjG,eAAO,MAAM,kBAAkB,WAAW,CAAC;AAE3C,MAAM,MAAM,oBAAoB,GAAG;IAAE,IAAI,EAAE,IAAI,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,IAAI,EAAE,SAAS,CAAA;CAAE,CAAC;AAE5F,MAAM,MAAM,eAAe,GACvB;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAClC;IAAE,IAAI,EAAE,UAAU,CAAA;CAAE,GACpB;IAAE,IAAI,EAAE,WAAW,CAAA;CAAE,GACrB;IAAE,IAAI,EAAE,sBAAsB,CAAC;IAAC,cAAc,EAAE,MAAM,CAAC;IAAC,aAAa,EAAE,MAAM,CAAA;CAAE,CAAC;AASpF,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,cAAc,GAAG,MAAM,CAUnE;AAiDD,wBAAgB,oBAAoB,CAAC,UAAU,EAAE;IAC/C,WAAW,EAAE,MAAM,GAAG,SAAS,CAAC;IAChC,MAAM,EAAE,cAAc,CAAC;CACxB,GAAG,oBAAoB,CAuBvB;AAED,UAAU,wBAAwB;IAChC,WAAW,EAAE,MAAM,GAAG,SAAS,CAAC;IAChC,MAAM,EAAE,cAAc,CAAC;IACvB,eAAe,EAAE,MAAM,CAAC;IACxB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,wBAAgB,eAAe,CAAC,UAAU,EAAE,wBAAwB,GAAG,MAAM,CA2B5E;AAkDD,wBAAgB,eAAe,CAAC,UAAU,EAAE;IAC1C,MAAM,EAAE;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAC3B,MAAM,EAAE,cAAc,CAAC;CACxB,GAAG,eAAe,CAiBlB"}
1
+ {"version":3,"file":"parsing.d.ts","sourceRoot":"","sources":["../../../../src/lib/adapters/linear/parsing.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAuC,KAAK,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAG3F,eAAO,MAAM,kBAAkB,WAAW,CAAC;AAE3C,MAAM,MAAM,oBAAoB,GAAG;IAAE,IAAI,EAAE,IAAI,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,IAAI,EAAE,SAAS,CAAA;CAAE,CAAC;AAE5F,MAAM,MAAM,eAAe,GACvB;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAClC;IAAE,IAAI,EAAE,UAAU,CAAA;CAAE,GACpB;IAAE,IAAI,EAAE,WAAW,CAAA;CAAE,GACrB;IAAE,IAAI,EAAE,sBAAsB,CAAC;IAAC,cAAc,EAAE,MAAM,CAAC;IAAC,aAAa,EAAE,MAAM,CAAA;CAAE,CAAC;AASpF,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,cAAc,GAAG,MAAM,CAUnE;AAiDD,wBAAgB,oBAAoB,CAAC,UAAU,EAAE;IAC/C,WAAW,EAAE,MAAM,GAAG,SAAS,CAAC;IAChC,MAAM,EAAE,cAAc,CAAC;CACxB,GAAG,oBAAoB,CAuBvB;AAED,UAAU,wBAAwB;IAChC,WAAW,EAAE,MAAM,GAAG,SAAS,CAAC;IAChC,MAAM,EAAE,cAAc,CAAC;IACvB,eAAe,EAAE,MAAM,CAAC;IACxB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,wBAAgB,eAAe,CAAC,UAAU,EAAE,wBAAwB,GAAG,MAAM,CA2B5E;AAkDD,wBAAgB,eAAe,CAAC,UAAU,EAAE;IAC1C,MAAM,EAAE;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAC3B,MAAM,EAAE,cAAc,CAAC;CACxB,GAAG,eAAe,CAiBlB"}
@@ -1,8 +1,8 @@
1
1
  /**
2
- * Linear adapter — parsing helpers for model/repository resolution from
2
+ * Linear adapter — parsing helpers for agent/repository resolution from
3
3
  * issue labels and descriptions. Extracted from boardSource.ts (Task 10).
4
4
  */
5
- import { AGENT_ANY_MODEL, isBuiltInModelNotEnabled } from "../../config.js";
5
+ import { AGENT_ANY, isBuiltInAgentNotEnabled } from "../../config.js";
6
6
  import { RepositoryResolutionError } from "../../taskSource.js";
7
7
  export const AGENT_LABEL_PREFIX = "agent-";
8
8
  function escapeRegex(value) {
@@ -105,40 +105,40 @@ function parseAgentLabels(labels, config) {
105
105
  let notEnabledFallback;
106
106
  for (const label of agentLabels) {
107
107
  const name = label.name.slice(AGENT_LABEL_PREFIX.length);
108
- if (name === AGENT_ANY_MODEL) {
109
- return { model: AGENT_ANY_MODEL };
108
+ if (name === AGENT_ANY) {
109
+ return { agent: AGENT_ANY };
110
110
  }
111
111
  // Own-property check, not `in`: a label like `agent-toString` or
112
112
  // `agent-__proto__` would otherwise resolve through the prototype chain
113
- // instead of falling back to `models.default`.
114
- if (Object.hasOwn(config.models.definitions, name)) {
115
- return { model: name };
113
+ // instead of falling back to `agents.default`.
114
+ if (Object.hasOwn(config.agents.definitions, name)) {
115
+ return { agent: name };
116
116
  }
117
- if (notEnabledFallback === undefined && isBuiltInModelNotEnabled(config, name)) {
117
+ if (notEnabledFallback === undefined && isBuiltInAgentNotEnabled(config, name)) {
118
118
  notEnabledFallback = name;
119
119
  }
120
120
  }
121
- const fallback = { model: config.models.default };
121
+ const fallback = { agent: config.agents.default };
122
122
  if (notEnabledFallback !== undefined) {
123
123
  fallback.notEnabledFallback = notEnabledFallback;
124
124
  }
125
125
  return fallback;
126
126
  }
127
- export function resolveModelFor(arguments_) {
127
+ export function resolveAgentFor(arguments_) {
128
128
  const { labels, config } = arguments_;
129
129
  const parsed = parseAgentLabels(labels, config);
130
130
  if (parsed === undefined) {
131
131
  return { kind: "no-label" };
132
132
  }
133
- if (parsed.model === AGENT_ANY_MODEL) {
133
+ if (parsed.agent === AGENT_ANY) {
134
134
  return { kind: "agent-any" };
135
135
  }
136
136
  if (parsed.notEnabledFallback !== undefined) {
137
137
  return {
138
138
  kind: "not-enabled-fallback",
139
- requestedModel: parsed.notEnabledFallback,
140
- fallbackModel: parsed.model,
139
+ requestedAgent: parsed.notEnabledFallback,
140
+ fallbackAgent: parsed.agent,
141
141
  };
142
142
  }
143
- return { kind: "matched", model: parsed.model };
143
+ return { kind: "matched", agent: parsed.agent };
144
144
  }
@@ -76,7 +76,7 @@ export function toCanonicalIssue(shellIssue, sourceName) {
76
76
  description: shellIssue.description,
77
77
  status: shellIssue.status,
78
78
  repository: shellIssue.repository ?? undefined,
79
- model: shellIssue.model ?? undefined,
79
+ agent: shellIssue.agent ?? undefined,
80
80
  assignee: shellIssue.assignee,
81
81
  updatedAt: shellIssue.updatedAt,
82
82
  blockers,