@gh-symphony/cli 0.1.2 → 0.1.4

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.
@@ -1,11 +1,11 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  workflow_init_default
4
- } from "./chunk-WM2B6BJ7.js";
4
+ } from "./chunk-RHLUIMBN.js";
5
5
  import {
6
6
  fetchGithubProjectIssueByRepositoryAndNumber,
7
7
  inspectManagedProjectSelection
8
- } from "./chunk-DLZAJXZL.js";
8
+ } from "./chunk-YIARPBOR.js";
9
9
  import {
10
10
  GitHubApiError,
11
11
  createClient,
@@ -18,7 +18,7 @@ import {
18
18
  buildPromptVariables,
19
19
  parseWorkflowMarkdown,
20
20
  renderPrompt
21
- } from "./chunk-GPRCOJDJ.js";
21
+ } from "./chunk-EWTMSDCE.js";
22
22
 
23
23
  // src/commands/workflow.ts
24
24
  import { readFile } from "fs/promises";
@@ -15,7 +15,7 @@ import {
15
15
  formatClaudePreflightText,
16
16
  resolveClaudeCommandBinary,
17
17
  runClaudePreflight
18
- } from "./chunk-GPRCOJDJ.js";
18
+ } from "./chunk-EWTMSDCE.js";
19
19
 
20
20
  // src/mapping/smart-defaults.ts
21
21
  var ROLE_PATTERNS = [
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  DEFAULT_WORKFLOW_LIFECYCLE
4
- } from "./chunk-GPRCOJDJ.js";
4
+ } from "./chunk-EWTMSDCE.js";
5
5
  import {
6
6
  loadGlobalConfig,
7
7
  loadProjectConfig
@@ -3,13 +3,13 @@ import {
3
3
  parseIssueReference,
4
4
  readGitHubProjectBinding,
5
5
  renderIssueWorkflowPreview
6
- } from "./chunk-B4ZJMAZL.js";
7
- import "./chunk-WM2B6BJ7.js";
6
+ } from "./chunk-HT3FAJAO.js";
7
+ import "./chunk-RHLUIMBN.js";
8
8
  import {
9
9
  fetchGithubProjectIssueByRepositoryAndNumber,
10
10
  fetchGithubProjectIssues,
11
11
  inspectManagedProjectSelection
12
- } from "./chunk-DLZAJXZL.js";
12
+ } from "./chunk-YIARPBOR.js";
13
13
  import {
14
14
  resolveRuntimeRoot
15
15
  } from "./chunk-6I753NYO.js";
@@ -34,7 +34,7 @@ import {
34
34
  resolveClaudeCommandBinary,
35
35
  resolveRuntimeCommandBinary,
36
36
  runClaudePreflight
37
- } from "./chunk-GPRCOJDJ.js";
37
+ } from "./chunk-EWTMSDCE.js";
38
38
  import "./chunk-WOVNN5NW.js";
39
39
 
40
40
  // src/commands/doctor.ts
package/dist/index.js CHANGED
@@ -414,13 +414,13 @@ function createRemovedCommandHandler(message) {
414
414
 
415
415
  // src/index.ts
416
416
  var COMMANDS = {
417
- workflow: () => import("./workflow-26QNZZWH.js"),
418
- setup: () => import("./setup-XNHHRBGU.js"),
419
- doctor: () => import("./doctor-EEPNFCGF.js"),
420
- upgrade: () => import("./upgrade-NS53EO2B.js"),
421
- repo: () => import("./repo-RX4OK7XH.js"),
417
+ workflow: () => import("./workflow-WSXHMO5B.js"),
418
+ setup: () => import("./setup-UJC2WYHQ.js"),
419
+ doctor: () => import("./doctor-I32MANQ4.js"),
420
+ upgrade: () => import("./upgrade-XYHCUGHT.js"),
421
+ repo: () => import("./repo-IH6UWE4H.js"),
422
422
  config: () => import("./config-cmd-2ADPUYWA.js"),
423
- version: () => import("./version-2RHFZ5CI.js")
423
+ version: () => import("./version-B2AYYGLM.js")
424
424
  };
425
425
  function addGlobalOptions(command) {
426
426
  return command.option("--config <dir>", "Config directory").addOption(new Option("--config-dir <dir>").hideHelp()).option("-v, --verbose", "Enable verbose output").option("--json", "Output in JSON format").option("--no-color", "Disable color output");
@@ -14,17 +14,17 @@ import {
14
14
  stripAnsi,
15
15
  yellow
16
16
  } from "./chunk-MVRF7BES.js";
17
- import "./chunk-VFHMHHZW.js";
17
+ import "./chunk-E7OCBNB2.js";
18
18
  import {
19
19
  initRepoRuntime,
20
20
  parseRepoRuntimeFlags
21
- } from "./chunk-GHVDABFO.js";
21
+ } from "./chunk-DW63WPRE.js";
22
22
  import {
23
23
  findGithubProjectIssue,
24
24
  handleMissingManagedProjectConfig,
25
25
  resolveManagedProjectConfig,
26
26
  resolveTrackerAdapter
27
- } from "./chunk-DLZAJXZL.js";
27
+ } from "./chunk-YIARPBOR.js";
28
28
  import {
29
29
  resolveRepoRuntimeRoot,
30
30
  resolveRuntimeRoot
@@ -34,6 +34,7 @@ import {
34
34
  getGhToken
35
35
  } from "./chunk-Z3NZOPLZ.js";
36
36
  import {
37
+ DEFAULT_LINEAR_GRAPHQL_URL,
37
38
  DEFAULT_MAX_FAILURE_RETRIES,
38
39
  DEFAULT_WORKFLOW_LIFECYCLE,
39
40
  WorkflowConfigStore,
@@ -56,13 +57,14 @@ import {
56
57
  parseRecentEvents,
57
58
  readEnvFile,
58
59
  readJsonFile,
60
+ redactObservabilitySecrets,
59
61
  renderPrompt,
60
62
  resolveIssueWorkspaceDirectory,
61
63
  resolveWorkflowRuntimeCommand,
62
64
  resolveWorkflowRuntimeTimeouts,
63
65
  safeReadDir,
64
66
  scheduleRetryAt
65
- } from "./chunk-GPRCOJDJ.js";
67
+ } from "./chunk-EWTMSDCE.js";
66
68
  import {
67
69
  daemonPidPath,
68
70
  httpStatusPath,
@@ -778,10 +780,7 @@ var OrchestratorFsStore = class {
778
780
  );
779
781
  }
780
782
  async saveProjectStatus(status) {
781
- await writeJsonFile2(
782
- join3(this.projectDir(), "status.json"),
783
- status
784
- );
783
+ await writeJsonFile2(join3(this.projectDir(), "status.json"), status);
785
784
  }
786
785
  async loadProjectStatus(projectId) {
787
786
  return await readJsonFile(
@@ -811,11 +810,12 @@ var OrchestratorFsStore = class {
811
810
  async saveRun(run) {
812
811
  await writeJsonFile2(
813
812
  join3(this.runDir(run.runId, run.projectId), "run.json"),
814
- run
813
+ redactObservabilitySecrets(run)
815
814
  );
816
815
  }
817
816
  async appendRunEvent(runId, event) {
818
- const resolvedProjectId = "projectId" in event && typeof event.projectId === "string" ? event.projectId : void 0;
817
+ const redactedEvent = redactObservabilitySecrets(event);
818
+ const resolvedProjectId = "projectId" in redactedEvent && typeof redactedEvent.projectId === "string" ? redactedEvent.projectId : void 0;
819
819
  const runDirectory = resolvedProjectId !== void 0 ? this.runDir(runId, resolvedProjectId) : await this.findRunDir(runId);
820
820
  if (!runDirectory) {
821
821
  throw new Error(
@@ -824,7 +824,7 @@ var OrchestratorFsStore = class {
824
824
  }
825
825
  const path = join3(runDirectory, "events.ndjson");
826
826
  const resolvedPath = resolve2(path);
827
- const serializedEvent = JSON.stringify(event) + "\n";
827
+ const serializedEvent = JSON.stringify(redactedEvent) + "\n";
828
828
  await mkdir2(dirname(path), { recursive: true });
829
829
  await appendFile(path, serializedEvent, {
830
830
  encoding: "utf8",
@@ -1076,9 +1076,341 @@ var fileTrackerAdapter = {
1076
1076
  }
1077
1077
  };
1078
1078
 
1079
+ // ../tracker-linear/src/orchestrator-adapter.ts
1080
+ var DEFAULT_LINEAR_GRAPHQL_URL2 = DEFAULT_LINEAR_GRAPHQL_URL;
1081
+ var DEFAULT_PAGE_SIZE = 50;
1082
+ var LINEAR_IDENTIFIER_PATTERN = /^[A-Z][A-Z0-9]*-\d+$/;
1083
+ var LINEAR_ISSUE_FIELDS = (
1084
+ /* GraphQL */
1085
+ `
1086
+ nodes {
1087
+ id
1088
+ identifier
1089
+ number
1090
+ title
1091
+ description
1092
+ priority
1093
+ url
1094
+ createdAt
1095
+ updatedAt
1096
+ state {
1097
+ name
1098
+ }
1099
+ labels {
1100
+ nodes {
1101
+ name
1102
+ }
1103
+ }
1104
+ relations {
1105
+ nodes {
1106
+ type
1107
+ relatedIssue {
1108
+ id
1109
+ identifier
1110
+ state {
1111
+ name
1112
+ }
1113
+ }
1114
+ }
1115
+ }
1116
+ }
1117
+ pageInfo {
1118
+ hasNextPage
1119
+ endCursor
1120
+ }
1121
+ `
1122
+ );
1123
+ var LINEAR_ISSUES_BY_STATES_QUERY = (
1124
+ /* GraphQL */
1125
+ `
1126
+ query SymphonyLinearIssues(
1127
+ $projectSlug: String!
1128
+ $stateNames: [String!]!
1129
+ $first: Int!
1130
+ $after: String
1131
+ ) {
1132
+ issues(
1133
+ first: $first
1134
+ after: $after
1135
+ filter: {
1136
+ project: { slugId: { eq: $projectSlug } }
1137
+ state: { name: { in: $stateNames } }
1138
+ }
1139
+ ) {
1140
+ ${LINEAR_ISSUE_FIELDS}
1141
+ }
1142
+ }
1143
+ `
1144
+ );
1145
+ var LINEAR_ISSUES_BY_IDS_QUERY = (
1146
+ /* GraphQL */
1147
+ `
1148
+ query SymphonyLinearIssueStates(
1149
+ $projectSlug: String!
1150
+ $issueIds: [ID!]!
1151
+ $first: Int!
1152
+ $after: String
1153
+ ) {
1154
+ issues(
1155
+ first: $first
1156
+ after: $after
1157
+ filter: {
1158
+ project: { slugId: { eq: $projectSlug } }
1159
+ id: { in: $issueIds }
1160
+ }
1161
+ ) {
1162
+ ${LINEAR_ISSUE_FIELDS}
1163
+ }
1164
+ }
1165
+ `
1166
+ );
1167
+ var linearTrackerAdapter = {
1168
+ async listIssues(project, dependencies = {}) {
1169
+ return listLinearIssues(
1170
+ project,
1171
+ project.tracker.settings?.activeStates,
1172
+ dependencies
1173
+ );
1174
+ },
1175
+ async listIssuesByStates(project, states, dependencies = {}) {
1176
+ if (states.length === 0) {
1177
+ return [];
1178
+ }
1179
+ return listLinearIssues(project, states, dependencies);
1180
+ },
1181
+ async fetchIssueStatesByIds(project, issueIds, dependencies = {}) {
1182
+ if (issueIds.length === 0) {
1183
+ return [];
1184
+ }
1185
+ return listLinearIssues(project, void 0, dependencies, issueIds);
1186
+ },
1187
+ buildWorkerEnvironment(project, issue) {
1188
+ return {
1189
+ LINEAR_GRAPHQL_URL: resolveLinearEndpoint(project.tracker),
1190
+ LINEAR_ISSUE_ID: issue.id,
1191
+ LINEAR_ISSUE_IDENTIFIER: issue.identifier,
1192
+ SYMPHONY_TRACKER_KIND: "linear"
1193
+ };
1194
+ },
1195
+ reviveIssue(project, run) {
1196
+ const revivedIdentifier = reviveLinearIdentifier(run.issueIdentifier);
1197
+ return {
1198
+ id: run.issueId,
1199
+ identifier: revivedIdentifier,
1200
+ number: parseLinearIssueNumberOrZero(revivedIdentifier),
1201
+ title: run.issueTitle ?? run.issueIdentifier,
1202
+ description: null,
1203
+ priority: null,
1204
+ state: run.issueState,
1205
+ branchName: null,
1206
+ url: null,
1207
+ labels: [],
1208
+ blockedBy: [],
1209
+ createdAt: null,
1210
+ updatedAt: null,
1211
+ repository: project.repository,
1212
+ tracker: {
1213
+ adapter: "linear",
1214
+ bindingId: project.tracker.bindingId,
1215
+ itemId: run.issueId
1216
+ },
1217
+ metadata: {}
1218
+ };
1219
+ }
1220
+ };
1221
+ async function listLinearIssues(project, stateNamesInput, dependencies, issueIds) {
1222
+ const config = resolveLinearTrackerConfig(project, dependencies);
1223
+ const client = createLinearGraphqlClient(config, dependencies.fetchImpl);
1224
+ const stateNames = readStringArray(stateNamesInput);
1225
+ if (!issueIds && (!stateNames || stateNames.length === 0)) {
1226
+ throw new Error(
1227
+ 'Tracker adapter "linear" requires at least one active state name in the "activeStates" setting.'
1228
+ );
1229
+ }
1230
+ const nodes = await fetchPaginatedLinearIssues(client, {
1231
+ projectSlug: config.projectSlug,
1232
+ stateNames,
1233
+ issueIds: issueIds ? [...issueIds] : void 0,
1234
+ pageSize: config.pageSize
1235
+ });
1236
+ return nodes.map(
1237
+ (node) => normalizeLinearIssue(project, config.projectSlug, node)
1238
+ );
1239
+ }
1240
+ async function fetchPaginatedLinearIssues(client, input) {
1241
+ const issues = [];
1242
+ let after = null;
1243
+ do {
1244
+ const query = input.issueIds ? LINEAR_ISSUES_BY_IDS_QUERY : LINEAR_ISSUES_BY_STATES_QUERY;
1245
+ const response = await client(
1246
+ query,
1247
+ {
1248
+ projectSlug: input.projectSlug,
1249
+ ...input.issueIds ? { issueIds: input.issueIds } : { stateNames: input.stateNames ?? [] },
1250
+ first: input.pageSize,
1251
+ after
1252
+ }
1253
+ );
1254
+ const connection = response.issues;
1255
+ issues.push(...connection?.nodes ?? []);
1256
+ after = connection?.pageInfo?.hasNextPage ? connection.pageInfo.endCursor ?? null : null;
1257
+ } while (after);
1258
+ return issues;
1259
+ }
1260
+ function normalizeLinearIssue(project, projectSlug, issue) {
1261
+ const id = requireString(issue.id, "Linear issue id");
1262
+ const identifier = sanitizeLinearIdentifier(
1263
+ requireString(issue.identifier, "Linear issue identifier")
1264
+ );
1265
+ const state = requireString(issue.state?.name, "Linear issue state name");
1266
+ return {
1267
+ id,
1268
+ identifier,
1269
+ number: typeof issue.number === "number" ? issue.number : parseLinearIssueNumber(identifier),
1270
+ title: issue.title ?? identifier,
1271
+ description: issue.description ?? null,
1272
+ priority: typeof issue.priority === "number" ? issue.priority : null,
1273
+ state,
1274
+ branchName: null,
1275
+ url: issue.url ?? null,
1276
+ labels: (issue.labels?.nodes ?? []).map((label) => label.name).filter((label) => typeof label === "string"),
1277
+ blockedBy: (issue.relations?.nodes ?? []).filter((relation) => relation.type === "blocks").map((relation) => ({
1278
+ id: relation.relatedIssue?.id ?? null,
1279
+ identifier: typeof relation.relatedIssue?.identifier === "string" ? sanitizeLinearIdentifier(relation.relatedIssue.identifier) : null,
1280
+ state: relation.relatedIssue?.state?.name ?? null
1281
+ })),
1282
+ createdAt: issue.createdAt ?? null,
1283
+ updatedAt: issue.updatedAt ?? null,
1284
+ repository: project.repository,
1285
+ tracker: {
1286
+ adapter: "linear",
1287
+ bindingId: project.tracker.bindingId,
1288
+ itemId: id
1289
+ },
1290
+ metadata: {
1291
+ projectSlug
1292
+ }
1293
+ };
1294
+ }
1295
+ function createLinearGraphqlClient(config, fetchImpl = fetch) {
1296
+ return async (query, variables) => {
1297
+ const response = await fetchImpl(config.endpoint, {
1298
+ method: "POST",
1299
+ headers: {
1300
+ "Content-Type": "application/json",
1301
+ Authorization: config.token
1302
+ },
1303
+ body: JSON.stringify({ query, variables })
1304
+ });
1305
+ if (!response.ok) {
1306
+ throw new Error(
1307
+ `Linear GraphQL request failed with HTTP ${response.status}.`
1308
+ );
1309
+ }
1310
+ const payload = await response.json();
1311
+ if (payload.errors?.length) {
1312
+ const message = payload.errors.map((error) => error.message).filter(Boolean).join("; ") || "Unknown Linear GraphQL error";
1313
+ throw new Error(`Linear GraphQL request failed: ${message}`);
1314
+ }
1315
+ if (!payload.data) {
1316
+ throw new Error("Linear GraphQL response did not include data.");
1317
+ }
1318
+ return payload.data;
1319
+ };
1320
+ }
1321
+ function resolveLinearTrackerConfig(project, dependencies) {
1322
+ const projectSlug = readRequiredSetting(project.tracker, "projectSlug");
1323
+ const token = dependencies.token ?? process.env.LINEAR_API_KEY;
1324
+ if (!token) {
1325
+ throw new Error("LINEAR_API_KEY environment variable is required.");
1326
+ }
1327
+ return {
1328
+ endpoint: resolveLinearEndpoint(project.tracker),
1329
+ pageSize: readPositiveIntegerSetting(project.tracker, "pageSize") ?? DEFAULT_PAGE_SIZE,
1330
+ projectSlug,
1331
+ token
1332
+ };
1333
+ }
1334
+ function resolveLinearEndpoint(tracker) {
1335
+ return tracker.apiUrl?.trim() || DEFAULT_LINEAR_GRAPHQL_URL2;
1336
+ }
1337
+ function readRequiredSetting(tracker, key) {
1338
+ const value = tracker.settings?.[key];
1339
+ if (typeof value !== "string" || value.length === 0) {
1340
+ throw new Error(
1341
+ `Tracker adapter "${tracker.adapter}" requires the "${key}" setting.`
1342
+ );
1343
+ }
1344
+ return value;
1345
+ }
1346
+ function readPositiveIntegerSetting(tracker, key) {
1347
+ const value = tracker.settings?.[key];
1348
+ if (value === void 0) {
1349
+ return void 0;
1350
+ }
1351
+ if (typeof value === "number" && Number.isInteger(value) && value > 0) {
1352
+ return value;
1353
+ }
1354
+ if (typeof value === "string") {
1355
+ const parsed = Number(value);
1356
+ if (Number.isInteger(parsed) && parsed > 0) {
1357
+ return parsed;
1358
+ }
1359
+ }
1360
+ throw new Error(
1361
+ `Tracker adapter "${tracker.adapter}" requires the "${key}" setting to be a positive integer when provided.`
1362
+ );
1363
+ }
1364
+ function readStringArray(value) {
1365
+ if (value === void 0) {
1366
+ return void 0;
1367
+ }
1368
+ if (typeof value === "string") {
1369
+ return value.split(/\r?\n|,/).map((entry) => entry.trim()).filter(Boolean);
1370
+ }
1371
+ if (!Array.isArray(value)) {
1372
+ return void 0;
1373
+ }
1374
+ return value.filter((entry) => typeof entry === "string");
1375
+ }
1376
+ function requireString(value, label) {
1377
+ if (typeof value !== "string" || value.length === 0) {
1378
+ throw new Error(`${label} is required.`);
1379
+ }
1380
+ return value;
1381
+ }
1382
+ function sanitizeLinearIdentifier(identifier) {
1383
+ const sanitized = identifier.trim().toUpperCase();
1384
+ if (!LINEAR_IDENTIFIER_PATTERN.test(sanitized)) {
1385
+ throw new Error(
1386
+ `Linear issue identifier "${identifier}" must match ${LINEAR_IDENTIFIER_PATTERN.source}.`
1387
+ );
1388
+ }
1389
+ return sanitized;
1390
+ }
1391
+ function parseLinearIssueNumber(identifier) {
1392
+ const sanitized = sanitizeLinearIdentifier(identifier);
1393
+ return Number.parseInt(sanitized.split("-").at(-1) ?? "0", 10);
1394
+ }
1395
+ function parseLinearIssueNumberOrZero(identifier) {
1396
+ try {
1397
+ return parseLinearIssueNumber(identifier);
1398
+ } catch {
1399
+ return 0;
1400
+ }
1401
+ }
1402
+ function reviveLinearIdentifier(identifier) {
1403
+ try {
1404
+ return sanitizeLinearIdentifier(identifier);
1405
+ } catch {
1406
+ return identifier;
1407
+ }
1408
+ }
1409
+
1079
1410
  // ../orchestrator/src/tracker-adapters.ts
1080
1411
  var localAdapters = /* @__PURE__ */ new Map([
1081
- ["file", fileTrackerAdapter]
1412
+ ["file", fileTrackerAdapter],
1413
+ ["linear", linearTrackerAdapter]
1082
1414
  ]);
1083
1415
  function resolveTrackerAdapter2(tracker) {
1084
1416
  const local = localAdapters.get(tracker.adapter);
@@ -10,10 +10,10 @@ import {
10
10
  validateStateMapping,
11
11
  writeEcosystem,
12
12
  writeWorkflowPlan
13
- } from "./chunk-WM2B6BJ7.js";
13
+ } from "./chunk-RHLUIMBN.js";
14
14
  import {
15
15
  initRepoRuntime
16
- } from "./chunk-GHVDABFO.js";
16
+ } from "./chunk-DW63WPRE.js";
17
17
  import "./chunk-6I753NYO.js";
18
18
  import {
19
19
  GhAuthError,
@@ -26,7 +26,7 @@ import {
26
26
  listUserProjects,
27
27
  validateToken
28
28
  } from "./chunk-Z3NZOPLZ.js";
29
- import "./chunk-GPRCOJDJ.js";
29
+ import "./chunk-EWTMSDCE.js";
30
30
  import "./chunk-WOVNN5NW.js";
31
31
 
32
32
  // src/commands/setup.ts
@@ -16,8 +16,8 @@ function execFileAsync(file, args, execFileImpl = execFileCallback) {
16
16
  });
17
17
  }
18
18
  function resolveCurrentCliVersion() {
19
- if ("0.1.2".length > 0) {
20
- return "0.1.2";
19
+ if ("0.1.4".length > 0) {
20
+ return "0.1.4";
21
21
  }
22
22
  const pkg = JSON.parse(
23
23
  readFileSync(new URL("../../package.json", import.meta.url), "utf8")
@@ -2,7 +2,7 @@
2
2
 
3
3
  // src/commands/version.ts
4
4
  var handler = async (_args, options) => {
5
- const version = "0.1.2";
5
+ const version = "0.1.4";
6
6
  if (options.json) {
7
7
  process.stdout.write(JSON.stringify({ version }) + "\n");
8
8
  } else {
@@ -6,7 +6,7 @@ import {
6
6
  normalizeCodexRuntimeEvents,
7
7
  prepareCodexRuntimePlan,
8
8
  resolveLocalRuntimeLaunchConfig
9
- } from "./chunk-VFHMHHZW.js";
9
+ } from "./chunk-E7OCBNB2.js";
10
10
  import {
11
11
  DEFAULT_AGENT_INPUT_REQUIRED_REASON,
12
12
  classifySessionExit,
@@ -17,7 +17,7 @@ import {
17
17
  resolveClaudeCommandBinary,
18
18
  resolveWorkflowRuntimeCommand,
19
19
  runClaudePreflight
20
- } from "./chunk-GPRCOJDJ.js";
20
+ } from "./chunk-EWTMSDCE.js";
21
21
 
22
22
  // ../worker/src/index.ts
23
23
  import { spawn as spawn2 } from "child_process";
@@ -297,6 +297,9 @@ function resolveWorkerRuntimeRoute(workflow) {
297
297
  function resolveClaudePreflightAuthMode(workflow) {
298
298
  return workflow.runtime?.isolation.bare === true ? "api-key-required" : "local-or-api-key";
299
299
  }
300
+ function shouldExposeLinearGraphQLTool(workflow, env = process.env) {
301
+ return workflow.tracker.kind === "linear" || env.SYMPHONY_TRACKER_KIND === "linear" || env.SYMPHONY_TRACKER_ADAPTER === "linear";
302
+ }
300
303
 
301
304
  // ../worker/src/thread-resume.ts
302
305
  var DEFAULT_CONTINUATION_GUIDANCE = "Continue working on the issue. Review your progress and complete any remaining tasks.";
@@ -765,6 +768,13 @@ async function startAssignedRun() {
765
768
  }
766
769
  const config = resolveLocalRuntimeLaunchConfig(launcherEnv);
767
770
  config.agentCommand = resolveWorkflowRuntimeCommand(workflow);
771
+ config.enableLinearGraphqlTool = shouldExposeLinearGraphQLTool(
772
+ workflow,
773
+ launcherEnv
774
+ );
775
+ config.linearApiKey = launcherEnv.LINEAR_API_KEY;
776
+ config.linearAuthorization = launcherEnv.LINEAR_AUTHORIZATION;
777
+ config.linearGraphqlUrl = launcherEnv.LINEAR_GRAPHQL_URL;
768
778
  const plan = await prepareCodexRuntimePlan(config);
769
779
  childProcess = launchCodexAppServer(plan);
770
780
  runtimeState.status = "running";
@@ -946,7 +956,15 @@ async function runNonCodexRuntimeAdapterLifecycle(workflow, env) {
946
956
  async function spawnNonCodexRuntimeTurn(adapter, runtimeKind, renderedPrompt, env) {
947
957
  if (runtimeKind === "claude-print") {
948
958
  return await adapter.spawnTurn({
949
- messages: [{ type: "user", text: renderedPrompt }],
959
+ messages: [
960
+ {
961
+ type: "user",
962
+ message: {
963
+ role: "user",
964
+ content: [{ type: "text", text: renderedPrompt }]
965
+ }
966
+ }
967
+ ],
950
968
  cwd: env.WORKING_DIRECTORY,
951
969
  env
952
970
  });
@@ -1007,8 +1025,30 @@ function isNonCodexTurnFailure(result) {
1007
1025
  return result.result !== "success";
1008
1026
  }
1009
1027
  function describeNonCodexTurnFailure(result) {
1028
+ const stderrSummary = extractRuntimeStderrSummary(result);
1029
+ if (stderrSummary) {
1030
+ return result.errorMessage ?? `${result.command} exited with ${result.signal ?? result.exitCode ?? "unknown"}: ${stderrSummary}`;
1031
+ }
1010
1032
  return result.errorMessage ?? `${result.command} exited with ${result.signal ?? result.exitCode ?? "unknown"}`;
1011
1033
  }
1034
+ function extractRuntimeStderrSummary(result) {
1035
+ if ("stderr" in result) {
1036
+ return summarizeRuntimeStderr(result.stderr);
1037
+ }
1038
+ if ("records" in result) {
1039
+ return summarizeRuntimeStderr(
1040
+ result.records.filter((record) => record.stream === "stderr").map((record) => record.line || record.parseError).filter((line) => Boolean(line)).join("\n")
1041
+ );
1042
+ }
1043
+ return null;
1044
+ }
1045
+ function summarizeRuntimeStderr(stderr) {
1046
+ const lines = stderr.split(/\r?\n/).map((line) => line.trim()).filter((line) => line.length > 0);
1047
+ if (lines.length === 0) {
1048
+ return null;
1049
+ }
1050
+ return lines.slice(-3).join(" | ").slice(0, 1e3);
1051
+ }
1012
1052
  async function exitWorkerStartupFailure(message) {
1013
1053
  runtimeState.status = "failed";
1014
1054
  runtimeState.runPhase = "failed";
@@ -6,11 +6,11 @@ import {
6
6
  resetWorkflowCommandDependenciesForTest,
7
7
  setWorkflowCommandDependenciesForTest,
8
8
  workflow_default
9
- } from "./chunk-B4ZJMAZL.js";
10
- import "./chunk-WM2B6BJ7.js";
11
- import "./chunk-DLZAJXZL.js";
9
+ } from "./chunk-HT3FAJAO.js";
10
+ import "./chunk-RHLUIMBN.js";
11
+ import "./chunk-YIARPBOR.js";
12
12
  import "./chunk-Z3NZOPLZ.js";
13
- import "./chunk-GPRCOJDJ.js";
13
+ import "./chunk-EWTMSDCE.js";
14
14
  import "./chunk-WOVNN5NW.js";
15
15
  export {
16
16
  workflow_default as default,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gh-symphony/cli",
3
- "version": "0.1.2",
3
+ "version": "0.1.4",
4
4
  "license": "MIT",
5
5
  "author": "hojinzs",
6
6
  "description": "Interactive CLI for GitHub Symphony orchestration",
@@ -42,12 +42,12 @@
42
42
  "devDependencies": {
43
43
  "tsup": "^8.5.1",
44
44
  "@gh-symphony/core": "0.0.14",
45
- "@gh-symphony/dashboard": "0.0.14",
46
45
  "@gh-symphony/control-plane": "0.0.15",
47
46
  "@gh-symphony/orchestrator": "0.0.14",
47
+ "@gh-symphony/dashboard": "0.0.14",
48
48
  "@gh-symphony/runtime-claude": "0.0.14",
49
- "@gh-symphony/worker": "0.0.14",
50
- "@gh-symphony/tracker-github": "0.0.14"
49
+ "@gh-symphony/tracker-github": "0.0.14",
50
+ "@gh-symphony/worker": "0.0.14"
51
51
  },
52
52
  "scripts": {
53
53
  "build": "tsup",