@gluecharm-lab/easyspecs-cli 0.0.22 → 0.0.24

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.
package/dist/main.cjs CHANGED
@@ -11012,6 +11012,228 @@ function assertAgentsDirExists(agentsDir) {
11012
11012
  }
11013
11013
  }
11014
11014
 
11015
+ // src/config/easyspecsConfigJson.ts
11016
+ var DEFAULT_MAX_CONCURRENT_AI = 45;
11017
+ var DEFAULT_CONTEXT_ANALYZED_STATUS_TIMEOUT_MS = 15e3;
11018
+ function mergeEasyspecsConfigDefaults(defaults, partial) {
11019
+ if (!partial) {
11020
+ return defaults;
11021
+ }
11022
+ const esInRaw = partial.easyspecs ?? {};
11023
+ const legacyProjectId = esInRaw.applicationId;
11024
+ const { applicationId: _omitLegacyApplicationIdKey, ...esIn } = esInRaw;
11025
+ void _omitLegacyApplicationIdKey;
11026
+ const defEs = defaults.easyspecs;
11027
+ const factoryMerged = mergeEasyspecsFactoryBlock(defEs.factory, esIn.factory);
11028
+ const workstationsMerged = mergeEasyspecsWorkstationsBlock(defEs.workstations, esIn.workstations);
11029
+ const pipelinesMerged = mergeEasyspecsPipelinesBlock(defEs.pipelines, esIn.pipelines);
11030
+ const mergedEs = {
11031
+ ...defEs,
11032
+ ...esIn,
11033
+ deploymentEnvironment: esIn.deploymentEnvironment ?? defEs.deploymentEnvironment,
11034
+ apiBaseUrl: esIn.apiBaseUrl ?? defEs.apiBaseUrl,
11035
+ easyspecsProjectId: esIn.easyspecsProjectId !== void 0 ? esIn.easyspecsProjectId : legacyProjectId !== void 0 ? legacyProjectId : defEs.easyspecsProjectId,
11036
+ defaultGitRemoteUrl: esIn.defaultGitRemoteUrl !== void 0 ? esIn.defaultGitRemoteUrl : defEs.defaultGitRemoteUrl,
11037
+ cliSessionPath: esIn.cliSessionPath !== void 0 ? esIn.cliSessionPath : defEs.cliSessionPath,
11038
+ openCode: { ...defEs.openCode, ...esIn.openCode },
11039
+ analysis: mergeAnalysisBlock(
11040
+ defEs.analysis ?? { promoteContextToWorkspace: true },
11041
+ esIn.analysis
11042
+ ),
11043
+ orchestration: { ...defEs.orchestration, ...esIn.orchestration },
11044
+ openCodeRuntime: mergeOpenCodeRuntime(defEs.openCodeRuntime, esIn.openCodeRuntime),
11045
+ diagnose: mergeDiagnoseBlock(defEs.diagnose, esIn.diagnose),
11046
+ upload: { ...defEs.upload, ...esIn.upload },
11047
+ macro: { ...defEs.macro, ...esIn.macro },
11048
+ ...factoryMerged ? { factory: factoryMerged } : {},
11049
+ ...workstationsMerged ? { workstations: workstationsMerged } : {},
11050
+ ...pipelinesMerged ? { pipelines: pipelinesMerged } : {},
11051
+ cli: { ...defEs.cli, ...esIn.cli },
11052
+ auth: mergeAuthBlock(defEs.auth, esIn.auth)
11053
+ };
11054
+ const easyspecs = {
11055
+ ...mergedEs,
11056
+ analysis: normalizeAnalysisWithFactoryCloud(mergedEs.analysis, mergedEs.factory)
11057
+ };
11058
+ return {
11059
+ schemaVersion: partial.schemaVersion ?? defaults.schemaVersion,
11060
+ easyspecs
11061
+ };
11062
+ }
11063
+ function mergeDiagnoseBlock(base, over) {
11064
+ if (!over) {
11065
+ return { ...base };
11066
+ }
11067
+ const zBase = base.zeroReference ?? { maxPercentNonReferenced: null };
11068
+ const zOver = over.zeroReference;
11069
+ const cBase = base.coordinationDuplicates ?? { strict: true };
11070
+ const cOver = over.coordinationDuplicates;
11071
+ return {
11072
+ zeroReference: {
11073
+ maxPercentNonReferenced: zOver?.maxPercentNonReferenced !== void 0 ? zOver.maxPercentNonReferenced : zBase.maxPercentNonReferenced ?? null
11074
+ },
11075
+ coordinationDuplicates: {
11076
+ strict: cOver?.strict !== void 0 ? cOver.strict : cBase.strict !== false
11077
+ }
11078
+ };
11079
+ }
11080
+ function mergeAuthBlock(base, over) {
11081
+ if (!over) {
11082
+ return { ...base };
11083
+ }
11084
+ return {
11085
+ ciLogin: { ...base.ciLogin, ...over.ciLogin }
11086
+ };
11087
+ }
11088
+ function mergeAnalysisBlock(base, over) {
11089
+ if (!over || Object.keys(over).length === 0) {
11090
+ return { ...base };
11091
+ }
11092
+ const merged = {
11093
+ ...base,
11094
+ ...over
11095
+ };
11096
+ if (base.ace || over.ace) {
11097
+ merged.ace = { ...base.ace, ...over.ace };
11098
+ }
11099
+ return merged;
11100
+ }
11101
+ function mergeEasyspecsFactoryBlock(base, over) {
11102
+ if (!base && !over) {
11103
+ return void 0;
11104
+ }
11105
+ const b = base ?? {};
11106
+ const o = over ?? {};
11107
+ const updateContext = b.updateContext || o.updateContext ? { ...b.updateContext ?? {}, ...o.updateContext ?? {} } : void 0;
11108
+ const out = {
11109
+ ...b,
11110
+ ...o,
11111
+ backoff: { ...b.backoff ?? {}, ...o.backoff ?? {} },
11112
+ ...updateContext ? { updateContext } : {}
11113
+ };
11114
+ const backoffKeys = Object.keys(out.backoff ?? {});
11115
+ const topKeys = Object.keys(out).filter((k) => k !== "backoff");
11116
+ if (topKeys.length === 0 && backoffKeys.length === 0) {
11117
+ return void 0;
11118
+ }
11119
+ return out;
11120
+ }
11121
+ function mergeEasyspecsWorkstationsBlock(base, over) {
11122
+ if (!base && !over) {
11123
+ return void 0;
11124
+ }
11125
+ const out = { ...base ?? {}, ...over ?? {} };
11126
+ return Object.keys(out).length > 0 ? out : void 0;
11127
+ }
11128
+ function mergeEasyspecsPipelinesBlock(base, over) {
11129
+ if (!base && !over) {
11130
+ return void 0;
11131
+ }
11132
+ const b = base ?? {};
11133
+ const o = over ?? {};
11134
+ const out = {
11135
+ ...b,
11136
+ ...o,
11137
+ upload: { ...b.upload ?? {}, ...o.upload ?? {} }
11138
+ };
11139
+ const uploadKeys = Object.keys(out.upload ?? {});
11140
+ const topKeys = Object.keys(out).filter((k) => k !== "upload");
11141
+ if (topKeys.length === 0 && uploadKeys.length === 0) {
11142
+ return void 0;
11143
+ }
11144
+ return out;
11145
+ }
11146
+ function normalizeAnalysisWithFactoryCloud(analysis, factory) {
11147
+ if (!factory || factory.cloudContextAnalyzed === void 0 && factory.cloudContextAnalyzedAt === void 0) {
11148
+ return analysis;
11149
+ }
11150
+ return mergeAnalysisBlock(analysis, {
11151
+ ...factory.cloudContextAnalyzed !== void 0 ? { cloudContextAnalyzed: factory.cloudContextAnalyzed } : {},
11152
+ ...factory.cloudContextAnalyzedAt !== void 0 ? { cloudContextAnalyzedAt: factory.cloudContextAnalyzedAt } : {}
11153
+ });
11154
+ }
11155
+ function mergeOpenCodeRuntime(base, over) {
11156
+ if (!over && !base) {
11157
+ return void 0;
11158
+ }
11159
+ const b = base ?? {};
11160
+ const o = over ?? {};
11161
+ return {
11162
+ ...b,
11163
+ ...o,
11164
+ executable: o.executable ?? b.executable,
11165
+ skipCredentialsCheck: o.skipCredentialsCheck ?? b.skipCredentialsCheck,
11166
+ credentialsPath: o.credentialsPath !== void 0 ? o.credentialsPath : b.credentialsPath,
11167
+ providers: { ...b.providers, ...o.providers },
11168
+ run: { ...b.run, ...o.run },
11169
+ coordinationRepairs: { ...b.coordinationRepairs, ...o.coordinationRepairs },
11170
+ pool: { ...b.pool, ...o.pool },
11171
+ projectConfigOverlay: b.projectConfigOverlay || o.projectConfigOverlay ? { ...b.projectConfigOverlay ?? {}, ...o.projectConfigOverlay ?? {} } : void 0
11172
+ };
11173
+ }
11174
+ function getDefaultEasyspecsConfig() {
11175
+ const openCodeRuntime = {
11176
+ executable: "opencode",
11177
+ skipCredentialsCheck: false,
11178
+ credentialsPath: ".opencode/auth.json",
11179
+ providers: {},
11180
+ run: {
11181
+ argvTemplate: [
11182
+ "run",
11183
+ "--agent",
11184
+ "{agentId}",
11185
+ "Execute the task described in the attached EasySpecs prompt file.",
11186
+ "-f",
11187
+ "{promptFile}"
11188
+ ],
11189
+ timeoutMs: 6e5
11190
+ },
11191
+ coordinationRepairs: {
11192
+ listJsonSchemaRepairAttempts: 1,
11193
+ markdownEvidenceRepairAttempts: 2,
11194
+ markdownOpenQuestionIterations: 5
11195
+ },
11196
+ /** Pool cap defaults in {@link mergeEasyspecsCliSettings} (`?? 30`); omit here so `workstations.maxConcurrentAi` is not overridden by merged `pool`. */
11197
+ pool: {},
11198
+ projectConfigOverlay: {}
11199
+ };
11200
+ return {
11201
+ schemaVersion: 2,
11202
+ easyspecs: {
11203
+ deploymentEnvironment: "production",
11204
+ apiBaseUrl: PRODUCTION_SYSTEM_MANAGER_URL,
11205
+ easyspecsProjectId: "",
11206
+ defaultGitRemoteUrl: "",
11207
+ cliSessionPath: "",
11208
+ openCode: {
11209
+ executable: "opencode",
11210
+ skipCredentialsCheck: false
11211
+ },
11212
+ workstations: {
11213
+ maxConcurrentAi: DEFAULT_MAX_CONCURRENT_AI
11214
+ },
11215
+ analysis: {
11216
+ promoteContextToWorkspace: true,
11217
+ cloudContextAnalyzed: false,
11218
+ cloudContextAnalyzedAt: null
11219
+ },
11220
+ orchestration: {},
11221
+ openCodeRuntime,
11222
+ diagnose: {
11223
+ zeroReference: { maxPercentNonReferenced: null },
11224
+ coordinationDuplicates: { strict: true }
11225
+ },
11226
+ upload: {
11227
+ contextDirectory: "",
11228
+ fetchContextAnalyzedInCloud: true
11229
+ },
11230
+ macro: { debug: false },
11231
+ cli: { bundledResourcesRoot: "" },
11232
+ auth: { ciLogin: {} }
11233
+ }
11234
+ };
11235
+ }
11236
+
11015
11237
  // src/config/openCodeProviderEnv.ts
11016
11238
  var path3 = __toESM(require("node:path"));
11017
11239
  var PROVIDER_TO_ENV = {
@@ -11187,7 +11409,7 @@ function mergeEasyspecsCliSettings(cfg, overrides = {}) {
11187
11409
  const listJsonSchemaRepairAttempts = rt?.coordinationRepairs?.listJsonSchemaRepairAttempts ?? readEasyspecsMergedSetting(cfg.easyspecs, "easyspecs.workstations.coordinationListRepairAttempts") ?? 1;
11188
11410
  const markdownEvidenceRepairAttempts = rt?.coordinationRepairs?.markdownEvidenceRepairAttempts ?? readEasyspecsMergedSetting(cfg.easyspecs, "easyspecs.workstations.detailMarkdownRepairAttempts") ?? 2;
11189
11411
  const markdownOpenQuestionIterations = rt?.coordinationRepairs?.markdownOpenQuestionIterations ?? readEasyspecsMergedSetting(cfg.easyspecs, "easyspecs.workstations.openQuestionIterations") ?? 5;
11190
- const maxConcurrentOpenCodeAgents = overrides.maxConcurrentOpenCodeAgents ?? readEasyspecsMergedSetting(cfg.easyspecs, "easyspecs.workstations.maxConcurrentAi") ?? rt?.pool?.maxConcurrentAgents ?? 30;
11412
+ const maxConcurrentOpenCodeAgents = overrides.maxConcurrentOpenCodeAgents ?? readEasyspecsMergedSetting(cfg.easyspecs, "easyspecs.workstations.maxConcurrentAi") ?? rt?.pool?.maxConcurrentAgents ?? DEFAULT_MAX_CONCURRENT_AI;
11191
11413
  const promoteContextToWorkspace = overrides.promote === false ? false : overrides.promote === true ? true : analysis.promoteContextToWorkspace !== false;
11192
11414
  let maxOuter = overrides.maxOuterIterationsPerPhase ?? readEasyspecsMergedSetting(cfg.easyspecs, "easyspecs.factory.maxOuterIterationsPerPipeline") ?? orch.maxOuterIterationsPerPhase ?? 0;
11193
11415
  if (ci && maxOuter === 0) {
@@ -11315,224 +11537,6 @@ function readAceOfflineLearnAfterSameSessionTraceFromEasySpecsSettingsFile(works
11315
11537
  return typeof v === "boolean" ? v : void 0;
11316
11538
  }
11317
11539
 
11318
- // src/config/easyspecsConfigJson.ts
11319
- var DEFAULT_CONTEXT_ANALYZED_STATUS_TIMEOUT_MS = 15e3;
11320
- function mergeEasyspecsConfigDefaults(defaults, partial) {
11321
- if (!partial) {
11322
- return defaults;
11323
- }
11324
- const esInRaw = partial.easyspecs ?? {};
11325
- const legacyProjectId = esInRaw.applicationId;
11326
- const { applicationId: _omitLegacyApplicationIdKey, ...esIn } = esInRaw;
11327
- void _omitLegacyApplicationIdKey;
11328
- const defEs = defaults.easyspecs;
11329
- const factoryMerged = mergeEasyspecsFactoryBlock(defEs.factory, esIn.factory);
11330
- const workstationsMerged = mergeEasyspecsWorkstationsBlock(defEs.workstations, esIn.workstations);
11331
- const pipelinesMerged = mergeEasyspecsPipelinesBlock(defEs.pipelines, esIn.pipelines);
11332
- const mergedEs = {
11333
- ...defEs,
11334
- ...esIn,
11335
- deploymentEnvironment: esIn.deploymentEnvironment ?? defEs.deploymentEnvironment,
11336
- apiBaseUrl: esIn.apiBaseUrl ?? defEs.apiBaseUrl,
11337
- easyspecsProjectId: esIn.easyspecsProjectId !== void 0 ? esIn.easyspecsProjectId : legacyProjectId !== void 0 ? legacyProjectId : defEs.easyspecsProjectId,
11338
- defaultGitRemoteUrl: esIn.defaultGitRemoteUrl !== void 0 ? esIn.defaultGitRemoteUrl : defEs.defaultGitRemoteUrl,
11339
- cliSessionPath: esIn.cliSessionPath !== void 0 ? esIn.cliSessionPath : defEs.cliSessionPath,
11340
- openCode: { ...defEs.openCode, ...esIn.openCode },
11341
- analysis: mergeAnalysisBlock(
11342
- defEs.analysis ?? { promoteContextToWorkspace: true },
11343
- esIn.analysis
11344
- ),
11345
- orchestration: { ...defEs.orchestration, ...esIn.orchestration },
11346
- openCodeRuntime: mergeOpenCodeRuntime(defEs.openCodeRuntime, esIn.openCodeRuntime),
11347
- diagnose: mergeDiagnoseBlock(defEs.diagnose, esIn.diagnose),
11348
- upload: { ...defEs.upload, ...esIn.upload },
11349
- macro: { ...defEs.macro, ...esIn.macro },
11350
- ...factoryMerged ? { factory: factoryMerged } : {},
11351
- ...workstationsMerged ? { workstations: workstationsMerged } : {},
11352
- ...pipelinesMerged ? { pipelines: pipelinesMerged } : {},
11353
- cli: { ...defEs.cli, ...esIn.cli },
11354
- auth: mergeAuthBlock(defEs.auth, esIn.auth)
11355
- };
11356
- const easyspecs = {
11357
- ...mergedEs,
11358
- analysis: normalizeAnalysisWithFactoryCloud(mergedEs.analysis, mergedEs.factory)
11359
- };
11360
- return {
11361
- schemaVersion: partial.schemaVersion ?? defaults.schemaVersion,
11362
- easyspecs
11363
- };
11364
- }
11365
- function mergeDiagnoseBlock(base, over) {
11366
- if (!over) {
11367
- return { ...base };
11368
- }
11369
- const zBase = base.zeroReference ?? { maxPercentNonReferenced: null };
11370
- const zOver = over.zeroReference;
11371
- const cBase = base.coordinationDuplicates ?? { strict: true };
11372
- const cOver = over.coordinationDuplicates;
11373
- return {
11374
- zeroReference: {
11375
- maxPercentNonReferenced: zOver?.maxPercentNonReferenced !== void 0 ? zOver.maxPercentNonReferenced : zBase.maxPercentNonReferenced ?? null
11376
- },
11377
- coordinationDuplicates: {
11378
- strict: cOver?.strict !== void 0 ? cOver.strict : cBase.strict !== false
11379
- }
11380
- };
11381
- }
11382
- function mergeAuthBlock(base, over) {
11383
- if (!over) {
11384
- return { ...base };
11385
- }
11386
- return {
11387
- ciLogin: { ...base.ciLogin, ...over.ciLogin }
11388
- };
11389
- }
11390
- function mergeAnalysisBlock(base, over) {
11391
- if (!over || Object.keys(over).length === 0) {
11392
- return { ...base };
11393
- }
11394
- const merged = {
11395
- ...base,
11396
- ...over
11397
- };
11398
- if (base.ace || over.ace) {
11399
- merged.ace = { ...base.ace, ...over.ace };
11400
- }
11401
- return merged;
11402
- }
11403
- function mergeEasyspecsFactoryBlock(base, over) {
11404
- if (!base && !over) {
11405
- return void 0;
11406
- }
11407
- const b = base ?? {};
11408
- const o = over ?? {};
11409
- const updateContext = b.updateContext || o.updateContext ? { ...b.updateContext ?? {}, ...o.updateContext ?? {} } : void 0;
11410
- const out = {
11411
- ...b,
11412
- ...o,
11413
- backoff: { ...b.backoff ?? {}, ...o.backoff ?? {} },
11414
- ...updateContext ? { updateContext } : {}
11415
- };
11416
- const backoffKeys = Object.keys(out.backoff ?? {});
11417
- const topKeys = Object.keys(out).filter((k) => k !== "backoff");
11418
- if (topKeys.length === 0 && backoffKeys.length === 0) {
11419
- return void 0;
11420
- }
11421
- return out;
11422
- }
11423
- function mergeEasyspecsWorkstationsBlock(base, over) {
11424
- if (!base && !over) {
11425
- return void 0;
11426
- }
11427
- const out = { ...base ?? {}, ...over ?? {} };
11428
- return Object.keys(out).length > 0 ? out : void 0;
11429
- }
11430
- function mergeEasyspecsPipelinesBlock(base, over) {
11431
- if (!base && !over) {
11432
- return void 0;
11433
- }
11434
- const b = base ?? {};
11435
- const o = over ?? {};
11436
- const out = {
11437
- ...b,
11438
- ...o,
11439
- upload: { ...b.upload ?? {}, ...o.upload ?? {} }
11440
- };
11441
- const uploadKeys = Object.keys(out.upload ?? {});
11442
- const topKeys = Object.keys(out).filter((k) => k !== "upload");
11443
- if (topKeys.length === 0 && uploadKeys.length === 0) {
11444
- return void 0;
11445
- }
11446
- return out;
11447
- }
11448
- function normalizeAnalysisWithFactoryCloud(analysis, factory) {
11449
- if (!factory || factory.cloudContextAnalyzed === void 0 && factory.cloudContextAnalyzedAt === void 0) {
11450
- return analysis;
11451
- }
11452
- return mergeAnalysisBlock(analysis, {
11453
- ...factory.cloudContextAnalyzed !== void 0 ? { cloudContextAnalyzed: factory.cloudContextAnalyzed } : {},
11454
- ...factory.cloudContextAnalyzedAt !== void 0 ? { cloudContextAnalyzedAt: factory.cloudContextAnalyzedAt } : {}
11455
- });
11456
- }
11457
- function mergeOpenCodeRuntime(base, over) {
11458
- if (!over && !base) {
11459
- return void 0;
11460
- }
11461
- const b = base ?? {};
11462
- const o = over ?? {};
11463
- return {
11464
- ...b,
11465
- ...o,
11466
- executable: o.executable ?? b.executable,
11467
- skipCredentialsCheck: o.skipCredentialsCheck ?? b.skipCredentialsCheck,
11468
- credentialsPath: o.credentialsPath !== void 0 ? o.credentialsPath : b.credentialsPath,
11469
- providers: { ...b.providers, ...o.providers },
11470
- run: { ...b.run, ...o.run },
11471
- coordinationRepairs: { ...b.coordinationRepairs, ...o.coordinationRepairs },
11472
- pool: { ...b.pool, ...o.pool },
11473
- projectConfigOverlay: b.projectConfigOverlay || o.projectConfigOverlay ? { ...b.projectConfigOverlay ?? {}, ...o.projectConfigOverlay ?? {} } : void 0
11474
- };
11475
- }
11476
- function getDefaultEasyspecsConfig() {
11477
- const openCodeRuntime = {
11478
- executable: "opencode",
11479
- skipCredentialsCheck: false,
11480
- credentialsPath: ".opencode/auth.json",
11481
- providers: {},
11482
- run: {
11483
- argvTemplate: [
11484
- "run",
11485
- "--agent",
11486
- "{agentId}",
11487
- "Execute the task described in the attached EasySpecs prompt file.",
11488
- "-f",
11489
- "{promptFile}"
11490
- ],
11491
- timeoutMs: 6e5
11492
- },
11493
- coordinationRepairs: {
11494
- listJsonSchemaRepairAttempts: 1,
11495
- markdownEvidenceRepairAttempts: 2,
11496
- markdownOpenQuestionIterations: 5
11497
- },
11498
- /** Pool cap defaults in {@link mergeEasyspecsCliSettings} (`?? 30`); omit here so `workstations.maxConcurrentAi` is not overridden by merged `pool`. */
11499
- pool: {},
11500
- projectConfigOverlay: {}
11501
- };
11502
- return {
11503
- schemaVersion: 2,
11504
- easyspecs: {
11505
- deploymentEnvironment: "production",
11506
- apiBaseUrl: PRODUCTION_SYSTEM_MANAGER_URL,
11507
- easyspecsProjectId: "",
11508
- defaultGitRemoteUrl: "",
11509
- cliSessionPath: "",
11510
- openCode: {
11511
- executable: "opencode",
11512
- skipCredentialsCheck: false
11513
- },
11514
- analysis: {
11515
- promoteContextToWorkspace: true,
11516
- cloudContextAnalyzed: false,
11517
- cloudContextAnalyzedAt: null
11518
- },
11519
- orchestration: {},
11520
- openCodeRuntime,
11521
- diagnose: {
11522
- zeroReference: { maxPercentNonReferenced: null },
11523
- coordinationDuplicates: { strict: true }
11524
- },
11525
- upload: {
11526
- contextDirectory: "",
11527
- fetchContextAnalyzedInCloud: true
11528
- },
11529
- macro: { debug: false },
11530
- cli: { bundledResourcesRoot: "" },
11531
- auth: { ciLogin: {} }
11532
- }
11533
- };
11534
- }
11535
-
11536
11540
  // src/config/validateEasyspecsConfigSrs46.ts
11537
11541
  var fs5 = __toESM(require("node:fs"));
11538
11542
  var path6 = __toESM(require("node:path"));
@@ -13847,6 +13851,7 @@ var path21 = __toESM(require("path"));
13847
13851
 
13848
13852
  // src/opencodeCli.ts
13849
13853
  var import_child_process = require("child_process");
13854
+ var import_node_events = require("node:events");
13850
13855
 
13851
13856
  // src/analysis/openCodeSessionStewardship.ts
13852
13857
  var TITLE_MAX_LEN = 80;
@@ -13971,6 +13976,7 @@ function logOpenCodeSessionFollowUpStart(diagnosticLog, p) {
13971
13976
  }
13972
13977
 
13973
13978
  // src/opencodeCli.ts
13979
+ var SHARED_OPEN_CODE_ABORT_LISTENER_BUDGET = 512;
13974
13980
  var USE_SHELL = process.platform === "win32";
13975
13981
  function resolveExecutable(executable) {
13976
13982
  const t = executable?.trim();
@@ -14171,6 +14177,9 @@ ${truncateForDiag(outBody, DIAG_STDOUT_MAX)}`);
14171
14177
  }
14172
14178
  };
14173
14179
  if (sig) {
14180
+ if ((0, import_node_events.getMaxListeners)(sig) < SHARED_OPEN_CODE_ABORT_LISTENER_BUDGET) {
14181
+ (0, import_node_events.setMaxListeners)(SHARED_OPEN_CODE_ABORT_LISTENER_BUDGET, sig);
14182
+ }
14174
14183
  onAbort = () => {
14175
14184
  child.kill("SIGTERM");
14176
14185
  settle(
@@ -19940,7 +19949,7 @@ function slugOrFallback3(row2) {
19940
19949
  }
19941
19950
  function clampConcurrency(n) {
19942
19951
  if (!Number.isFinite(n)) {
19943
- return 30;
19952
+ return DEFAULT_MAX_CONCURRENT_AI;
19944
19953
  }
19945
19954
  return Math.min(64, Math.max(1, Math.floor(n)));
19946
19955
  }
@@ -20563,11 +20572,13 @@ async function drainWorkstationPool(p) {
20563
20572
  void persist();
20564
20573
  pump();
20565
20574
  };
20575
+ let poolAbortListenerRegistered = false;
20566
20576
  if (abortSignal) {
20567
20577
  if (abortSignal.aborted) {
20568
20578
  onPipelineAbort();
20569
20579
  } else {
20570
- abortSignal.addEventListener("abort", onPipelineAbort, { once: true });
20580
+ abortSignal.addEventListener("abort", onPipelineAbort);
20581
+ poolAbortListenerRegistered = true;
20571
20582
  }
20572
20583
  }
20573
20584
  const runOne = async (id) => {
@@ -20639,29 +20650,35 @@ async function drainWorkstationPool(p) {
20639
20650
  await p.onItemComplete?.(id);
20640
20651
  pump();
20641
20652
  };
20642
- while (true) {
20643
- while (fifo.length > 0 && active < maxC && !abortSignal?.aborted) {
20644
- const id = fifo.shift();
20645
- const it = byId.get(id);
20646
- if (!it || it.status !== "pending" || !parentsDone(it, byId)) {
20647
- continue;
20653
+ try {
20654
+ while (true) {
20655
+ while (fifo.length > 0 && active < maxC && !abortSignal?.aborted) {
20656
+ const id = fifo.shift();
20657
+ const it = byId.get(id);
20658
+ if (!it || it.status !== "pending" || !parentsDone(it, byId)) {
20659
+ continue;
20660
+ }
20661
+ active += 1;
20662
+ void runOne(id);
20648
20663
  }
20649
- active += 1;
20650
- void runOne(id);
20651
- }
20652
- const pendingOrRunning = active > 0 || [...byId.values()].some((v) => v.status === "pending") || fifo.length > 0;
20653
- if (!pendingOrRunning) {
20654
- break;
20655
- }
20656
- if (abortSignal?.aborted) {
20657
- if (active === 0) {
20664
+ const pendingOrRunning = active > 0 || [...byId.values()].some((v) => v.status === "pending") || fifo.length > 0;
20665
+ if (!pendingOrRunning) {
20658
20666
  break;
20659
20667
  }
20660
- await waitTurn();
20661
- continue;
20668
+ if (abortSignal?.aborted) {
20669
+ if (active === 0) {
20670
+ break;
20671
+ }
20672
+ await waitTurn();
20673
+ continue;
20674
+ }
20675
+ if (fifo.length === 0 || active >= maxC) {
20676
+ await waitTurn();
20677
+ }
20662
20678
  }
20663
- if (fifo.length === 0 || active >= maxC) {
20664
- await waitTurn();
20679
+ } finally {
20680
+ if (poolAbortListenerRegistered && abortSignal) {
20681
+ abortSignal.removeEventListener("abort", onPipelineAbort);
20665
20682
  }
20666
20683
  }
20667
20684
  return { cancelled: abortSignal?.aborted === true, skippedWorkItemIds };
@@ -27045,7 +27062,7 @@ function listPendingAceTraceFiles(contextDir2, worktreeRoot) {
27045
27062
  var path58 = __toESM(require("path"));
27046
27063
  function clampConcurrency2(n) {
27047
27064
  if (!Number.isFinite(n)) {
27048
- return 30;
27065
+ return DEFAULT_MAX_CONCURRENT_AI;
27049
27066
  }
27050
27067
  return Math.min(64, Math.max(1, Math.floor(n)));
27051
27068
  }
@@ -27070,11 +27087,13 @@ async function runAceAutoLearnPool(p) {
27070
27087
  fifo.length = 0;
27071
27088
  pump();
27072
27089
  };
27090
+ let poolAbortListenerRegistered = false;
27073
27091
  if (abortSignal) {
27074
27092
  if (abortSignal.aborted) {
27075
27093
  onPipelineAbort();
27076
27094
  } else {
27077
- abortSignal.addEventListener("abort", onPipelineAbort, { once: true });
27095
+ abortSignal.addEventListener("abort", onPipelineAbort);
27096
+ poolAbortListenerRegistered = true;
27078
27097
  }
27079
27098
  }
27080
27099
  const traceRel = (abs) => path58.relative(contextDir2, abs).split(path58.sep).join("/");
@@ -27099,25 +27118,31 @@ async function runAceAutoLearnPool(p) {
27099
27118
  p.log?.(`[ace] ace auto-learn: finished ${rel} ok=${r.ok}`);
27100
27119
  pump();
27101
27120
  };
27102
- while (true) {
27103
- while (fifo.length > 0 && active < maxC && !abortSignal?.aborted) {
27104
- const traceAbs = fifo.shift();
27105
- active += 1;
27106
- void runOne(traceAbs);
27107
- }
27108
- const pendingOrRunning = active > 0 || fifo.length > 0;
27109
- if (!pendingOrRunning) {
27110
- break;
27111
- }
27112
- if (abortSignal?.aborted) {
27113
- if (active === 0) {
27121
+ try {
27122
+ while (true) {
27123
+ while (fifo.length > 0 && active < maxC && !abortSignal?.aborted) {
27124
+ const traceAbs = fifo.shift();
27125
+ active += 1;
27126
+ void runOne(traceAbs);
27127
+ }
27128
+ const pendingOrRunning = active > 0 || fifo.length > 0;
27129
+ if (!pendingOrRunning) {
27114
27130
  break;
27115
27131
  }
27116
- await waitTurn();
27117
- continue;
27132
+ if (abortSignal?.aborted) {
27133
+ if (active === 0) {
27134
+ break;
27135
+ }
27136
+ await waitTurn();
27137
+ continue;
27138
+ }
27139
+ if (fifo.length === 0 || active >= maxC) {
27140
+ await waitTurn();
27141
+ }
27118
27142
  }
27119
- if (fifo.length === 0 || active >= maxC) {
27120
- await waitTurn();
27143
+ } finally {
27144
+ if (poolAbortListenerRegistered && abortSignal) {
27145
+ abortSignal.removeEventListener("abort", onPipelineAbort);
27121
27146
  }
27122
27147
  }
27123
27148
  return { cancelled: abortSignal?.aborted === true, completed, failed };
@@ -27586,7 +27611,7 @@ function formatCliStderrLine(line, useAnsi) {
27586
27611
  }
27587
27612
 
27588
27613
  // src/cli/main.ts
27589
- var PKG_VERSION = "0.0.22";
27614
+ var PKG_VERSION = "0.0.24";
27590
27615
  function isNonEmptyFactoryFailureArray(x) {
27591
27616
  if (!Array.isArray(x) || x.length === 0) {
27592
27617
  return false;