@wrongstack/core 0.8.2 → 0.8.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.
package/dist/index.js CHANGED
@@ -3965,11 +3965,11 @@ function validateAgainstSchema(value, schema) {
3965
3965
  walk2(value, schema, "", errors);
3966
3966
  return { ok: errors.length === 0, errors };
3967
3967
  }
3968
- function walk2(value, schema, path26, errors) {
3968
+ function walk2(value, schema, path27, errors) {
3969
3969
  if (schema.enum !== void 0) {
3970
3970
  if (!schema.enum.some((e) => deepEqual(e, value))) {
3971
3971
  errors.push({
3972
- path: path26 || "<root>",
3972
+ path: path27 || "<root>",
3973
3973
  message: `expected one of ${JSON.stringify(schema.enum)}, got ${JSON.stringify(value)}`
3974
3974
  });
3975
3975
  return;
@@ -3978,7 +3978,7 @@ function walk2(value, schema, path26, errors) {
3978
3978
  if (typeof schema.type === "string") {
3979
3979
  if (!checkType(value, schema.type)) {
3980
3980
  errors.push({
3981
- path: path26 || "<root>",
3981
+ path: path27 || "<root>",
3982
3982
  message: `expected ${schema.type}, got ${describeType(value)}`
3983
3983
  });
3984
3984
  return;
@@ -3988,19 +3988,19 @@ function walk2(value, schema, path26, errors) {
3988
3988
  const obj = value;
3989
3989
  for (const req of schema.required ?? []) {
3990
3990
  if (!(req in obj)) {
3991
- errors.push({ path: joinPath(path26, req), message: "required property missing" });
3991
+ errors.push({ path: joinPath(path27, req), message: "required property missing" });
3992
3992
  }
3993
3993
  }
3994
3994
  if (schema.properties) {
3995
3995
  for (const [key, subSchema] of Object.entries(schema.properties)) {
3996
3996
  if (key in obj) {
3997
- walk2(obj[key], subSchema, joinPath(path26, key), errors);
3997
+ walk2(obj[key], subSchema, joinPath(path27, key), errors);
3998
3998
  }
3999
3999
  }
4000
4000
  }
4001
4001
  }
4002
4002
  if (schema.type === "array" && Array.isArray(value) && schema.items) {
4003
- value.forEach((item, i) => walk2(item, schema.items, `${path26}[${i}]`, errors));
4003
+ value.forEach((item, i) => walk2(item, schema.items, `${path27}[${i}]`, errors));
4004
4004
  }
4005
4005
  }
4006
4006
  function checkType(value, type) {
@@ -7303,12 +7303,18 @@ var AutoCompactionMiddleware = class _AutoCompactionMiddleware {
7303
7303
  failureMode;
7304
7304
  policyProvider;
7305
7305
  /**
7306
- * Overhead factor applied to the rough message-token estimate to produce a
7307
- * figure comparable to the real API request size (system prompt + tool defs).
7308
- * Without this factor, raw message tokens undercount real load by 15-50% in
7309
- * short conversations, causing premature compaction triggers.
7306
+ * Calibration factor applied to the estimator output. The estimator is now
7307
+ * expected to already include messages + system prompt + tool definitions
7308
+ * (see `estimateRequestTokens.total`), so no overhead boost is needed. Kept
7309
+ * as a constant so a future calibration against real provider tokenization
7310
+ * (BPE vs the chars/3.5 rough estimator) can dial this without touching the
7311
+ * threshold-check math.
7312
+ *
7313
+ * Historical note: was 1.3 when the estimator only counted messages — that
7314
+ * double-counted system+tools once the estimator was upgraded, firing
7315
+ * compaction ~30% earlier than intended (e.g. real 56% load showed as 73%).
7310
7316
  */
7311
- static OVERHEAD_FACTOR = 1.3;
7317
+ static OVERHEAD_FACTOR = 1;
7312
7318
  /**
7313
7319
  * Once a compaction attempt reduces nothing (preserveK protects everything,
7314
7320
  * no oversized tool_results remain to elide), retrying on every iteration
@@ -8255,8 +8261,8 @@ ${recentJournal}` : "No prior iterations.",
8255
8261
  await saveGoal(this.goalPath, abandoned);
8256
8262
  }
8257
8263
  try {
8258
- const { unlink: unlink10 } = await import('fs/promises');
8259
- await unlink10(this.goalPath);
8264
+ const { unlink: unlink11 } = await import('fs/promises');
8265
+ await unlink11(this.goalPath);
8260
8266
  } catch {
8261
8267
  }
8262
8268
  this.opts.onEternalStop?.();
@@ -15508,10 +15514,10 @@ var AISpecBuilder = class {
15508
15514
  async saveSession() {
15509
15515
  if (!this.sessionPath) return;
15510
15516
  try {
15511
- const fsp16 = await import('fs/promises');
15512
- const path26 = await import('path');
15517
+ const fsp17 = await import('fs/promises');
15518
+ const path27 = await import('path');
15513
15519
  const { atomicWrite: atomicWrite2 } = await Promise.resolve().then(() => (init_atomic_write(), atomic_write_exports));
15514
- await fsp16.mkdir(path26.dirname(this.sessionPath), { recursive: true });
15520
+ await fsp17.mkdir(path27.dirname(this.sessionPath), { recursive: true });
15515
15521
  await atomicWrite2(this.sessionPath, JSON.stringify(this.session, null, 2));
15516
15522
  } catch {
15517
15523
  }
@@ -15520,8 +15526,8 @@ var AISpecBuilder = class {
15520
15526
  async loadSession() {
15521
15527
  if (!this.sessionPath) return false;
15522
15528
  try {
15523
- const fsp16 = await import('fs/promises');
15524
- const raw = await fsp16.readFile(this.sessionPath, "utf8");
15529
+ const fsp17 = await import('fs/promises');
15530
+ const raw = await fsp17.readFile(this.sessionPath, "utf8");
15525
15531
  const loaded = JSON.parse(raw);
15526
15532
  if (loaded?.id && loaded?.phase && loaded?.title) {
15527
15533
  this.session = loaded;
@@ -15535,8 +15541,8 @@ var AISpecBuilder = class {
15535
15541
  async deleteSession() {
15536
15542
  if (!this.sessionPath) return;
15537
15543
  try {
15538
- const fsp16 = await import('fs/promises');
15539
- await fsp16.unlink(this.sessionPath);
15544
+ const fsp17 = await import('fs/promises');
15545
+ await fsp17.unlink(this.sessionPath);
15540
15546
  } catch {
15541
15547
  }
15542
15548
  }
@@ -16221,15 +16227,15 @@ function computeCriticalPath(graph, topoOrder, blockedByMap) {
16221
16227
  maxId = id;
16222
16228
  }
16223
16229
  }
16224
- const path26 = [];
16230
+ const path27 = [];
16225
16231
  let current = maxId;
16226
16232
  const visited = /* @__PURE__ */ new Set();
16227
16233
  while (current && !visited.has(current)) {
16228
16234
  visited.add(current);
16229
- path26.unshift(current);
16235
+ path27.unshift(current);
16230
16236
  current = prev.get(current) ?? null;
16231
16237
  }
16232
- return path26;
16238
+ return path27;
16233
16239
  }
16234
16240
  function computeParallelGroups(graph, blockedByMap) {
16235
16241
  const groups = [];
@@ -17209,7 +17215,7 @@ async function startMetricsServer(opts) {
17209
17215
  const tls = opts.tls;
17210
17216
  const useHttps = !!(tls?.cert && tls?.key);
17211
17217
  const host = opts.host ?? "127.0.0.1";
17212
- const path26 = opts.path ?? "/metrics";
17218
+ const path27 = opts.path ?? "/metrics";
17213
17219
  const healthPath = opts.healthPath ?? "/healthz";
17214
17220
  const healthRegistry = opts.healthRegistry;
17215
17221
  const listener = (req, res) => {
@@ -17219,7 +17225,7 @@ async function startMetricsServer(opts) {
17219
17225
  return;
17220
17226
  }
17221
17227
  const url = req.url.split("?")[0];
17222
- if (url === path26) {
17228
+ if (url === path27) {
17223
17229
  let body;
17224
17230
  try {
17225
17231
  body = renderPrometheus(opts.sink.snapshot());
@@ -17283,7 +17289,7 @@ async function startMetricsServer(opts) {
17283
17289
  const protocol = useHttps ? "https" : "http";
17284
17290
  return {
17285
17291
  port: boundPort,
17286
- url: `${protocol}://${host}:${boundPort}${path26}`,
17292
+ url: `${protocol}://${host}:${boundPort}${path27}`,
17287
17293
  close: () => new Promise((resolve6, reject) => {
17288
17294
  server.close((err) => err ? reject(err) : resolve6());
17289
17295
  })
@@ -19403,8 +19409,8 @@ var ReportGenerator = class {
19403
19409
  try {
19404
19410
  await stat(this.options.outputDir);
19405
19411
  } catch {
19406
- const { mkdir: mkdir11 } = await import('fs/promises');
19407
- await mkdir11(this.options.outputDir, { recursive: true });
19412
+ const { mkdir: mkdir12 } = await import('fs/promises');
19413
+ await mkdir12(this.options.outputDir, { recursive: true });
19408
19414
  }
19409
19415
  }
19410
19416
  generateMarkdown(result) {
@@ -20326,16 +20332,16 @@ Use \`/security report <number>\` to view a specific report.` };
20326
20332
  }
20327
20333
  const index = Number.parseInt(reportId, 10) - 1;
20328
20334
  if (!Number.isNaN(index) && reports[index]) {
20329
- const { readFile: readFile30 } = await import('fs/promises');
20330
- const content = await readFile30(join(reportsDir, reports[index]), "utf-8");
20335
+ const { readFile: readFile31 } = await import('fs/promises');
20336
+ const content = await readFile31(join(reportsDir, reports[index]), "utf-8");
20331
20337
  return { message: `# Security Report
20332
20338
 
20333
20339
  ${content}` };
20334
20340
  }
20335
20341
  const match = reports.find((r) => r.includes(reportId));
20336
20342
  if (match) {
20337
- const { readFile: readFile30 } = await import('fs/promises');
20338
- const content = await readFile30(join(reportsDir, match), "utf-8");
20343
+ const { readFile: readFile31 } = await import('fs/promises');
20344
+ const content = await readFile31(join(reportsDir, match), "utf-8");
20339
20345
  return { message: `# Security Report
20340
20346
 
20341
20347
  ${content}` };
@@ -23261,6 +23267,863 @@ function wrapApiForCapabilityCheck(plugin, api, log, enforce = false) {
23261
23267
  });
23262
23268
  }
23263
23269
 
23264
- export { AGENTS_BY_PHASE, AGENT_CATALOG, AISpecBuilder, ALL_AGENT_DEFINITIONS, ALL_FLEET_AGENTS, AUDIT_LOG_AGENT, Agent, AgentError, AutoApprovePermissionPolicy, AutoCompactionMiddleware, AutoExecutor, AutonomousRunner, BUG_HUNTER_AGENT, BudgetExceededError, CONTEXT_WINDOW_MODES, ConfigError, ConfigMigrationError, Container, Context, ConversationState, DEFAULT_CONFIG_MIGRATIONS, DEFAULT_CONTEXT_CONFIG, DEFAULT_CONTEXT_WINDOW_MODE_ID, DEFAULT_DIRECTOR_PREAMBLE, DEFAULT_DISPATCH_ROLE, DEFAULT_MAX_ITERATIONS, DEFAULT_MODES, DEFAULT_RECOVERY_STRATEGIES, DEFAULT_SPEC_TEMPLATE, DEFAULT_SUBAGENT_BASELINE, DEFAULT_TOOLS_CONFIG, DefaultAttachmentStore, DefaultConfigLoader, DefaultConfigStore, DefaultErrorHandler, DefaultHealthRegistry, DefaultLogger, DefaultMemoryStore, DefaultModeStore, DefaultModelsRegistry, DefaultMultiAgentCoordinator, DefaultPathResolver, DefaultPermissionPolicy, DefaultPluginAPI, DefaultProviderRunner, DefaultRetryPolicy, DefaultSecretScrubber, DefaultSecretVault, DefaultSessionReader, DefaultSessionRewinder, DefaultSessionStore, DefaultSkillLoader, DefaultSystemPromptBuilder, DefaultTaskStore, DefaultTokenCounter, Director, DirectorStateCheckpoint, DoneConditionChecker, ERROR_CODES, EternalAutonomyEngine, EventBus, ExtensionRegistry, FLEET_ROSTER, FLEET_ROSTER_BUDGETS, FleetBus, FleetManager, FleetSpawnBudgetError, FleetUsageAggregator, FsError, GitignoreUpdater, HybridCompactor, InMemoryAgentBridge, InMemoryBridgeTransport, InMemoryMetricsSink, InputBuilder, IntelligentCompactor, KERNEL_API_VERSION, LAYER_1_IDENTITY, LLMSelector, MAX_JOURNAL_ENTRIES, NULL_FLEET_BUS, NoopMetricsSink, NoopTracer, OTelTracer, PROMETHEUS_CONTENT_TYPE, ParallelEternalEngine, Pipeline, PluginError, ProviderError, ProviderRegistry, QueueStore, REFACTOR_PLANNER_AGENT, RecoveryLock, ReportGenerator, RunController, SECURITY_SCANNER_AGENT, SPEC_TEMPLATES, ScopedEventBus, SddParallelRun, SddTaskDecomposer, SecurityScanner, SecurityScannerOrchestrator, SelectiveCompactor, SessionAnalyzer, SessionError, SkillGenerator, SkillInstaller, SkillManifestStore, SlashCommandRegistry, SpecDrivenDev, SpecParser, SpecStore, SpecVersioning, SubagentBudget, TOKENS, TaskFlow, TaskGenerator, TaskGraphStore, TaskTracker, TechStackDetector, ToolError, ToolExecutor, ToolRegistry, WrongStackError, addPlanItem, allServers, analyzeCriticalPath, appendJournal, applyRosterBudget, asBlocks, asText, atomicWrite, attachAutoExtend, attachPlanCheckpoint, attachTodosCheckpoint, awsServer, blockServer, braveSearchServer, buildBtwBlock, buildChildEnv, buildGoalPreamble, buildOtlpMetricsRequest, buildOtlpTracesRequest, buildRecoveryStrategies, classifyFamily, clearPlan, color, compileGlob, compileUserRegex, composeDirectorPrompt, composeSubagentPrompt, computeTaskProgress, consumeBtwNotes, context7Server, contextManagerTool, createAutoExecutor, createContextManagerTool, createDefaultPipelines, createDelegateTool, createMcpControlTool, createMessage, createSecuritySlashCommand, createToolOutputSerializer, decryptConfigSecrets, defaultGitignoreUpdater, defaultOrchestrator, defaultReportGenerator, defaultSecurityScanner, defaultSkillGenerator, defaultTechStackDetector, deriveTodosFromPlanItem, detectNewlineStyle, dispatchAgent, downloadGitHubTarball, emptyGoal, emptyPlan, encryptConfigSecrets, ensureDir, estimateRequestTokens, estimateTextTokens, estimateToolDefTokens, estimateToolInputTokens, estimateToolResultTokens, everArtServer, extractRunEnv, filesystemServer, findCriticalPath, formatContextWindowModeList, formatGoal, formatPlan, formatPlanTemplates, formatTodosList, getAgentDefinition, getContextWindowMode, getPlanTemplate, getTemplate, githubServer, goalFilePath, googleMapsServer, isAgentError, isConfigError, isContextWindowModeId, isFsError, isImageBlock, isPluginError, isSessionError, isTextBlock, isThinkingBlock, isToolError, isToolResultBlock, isToolUseBlock, isWrongStackError, listContextWindowModes, listPlanTemplates, listTemplates, loadDirectorState, loadGoal, loadPlan, loadPlugins, loadProjectModes, loadTodosCheckpoint, loadUserModes, makeAgentSubagentRunner, makeAutonomyPromptContributor, makeContinueToNextIterationTool, makeDirectorSessionFactory, makeLLMClassifier, matchAny, matchGlob, migratePlaintextSecrets, miniMaxVisionServer, normalizeToLf, parseContinueDirective, parseSkillRef, pendingBtwCount, projectHash, removePlanItem, renderProgress, renderPrometheus, renderSpecAnalysis, renderTaskGraph, renderTaskList, repairToolUseAdjacency, resolveContextWindowPolicy, resolveWstackPaths, rewriteConfigEncrypted, rosterSummaryFromConfigs, runConfigMigrations, safeParse, safeStringify, sanitizeJsonString, saveGoal, savePlan, saveTodosCheckpoint, scoreAgents, securitySlashCommand, sentinelServer, setBtwNote, setPlanItemStatus, slackServer, startMetricsServer, startOtlpMetricsExporter, startOtlpTraceExporter, stripAnsi, summarizeUsage, templateToMarkdown, toStyle, toWrongStackError, topologicalSort, unifiedDiff, unloadPlugins, validateAgainstSchema, wireMetricsToEvents, wrapAsState, zaiVisionServer };
23270
+ // src/autophase/phase-graph-builder.ts
23271
+ var PhaseGraphBuilder = class _PhaseGraphBuilder {
23272
+ constructor(opts) {
23273
+ this.opts = opts;
23274
+ }
23275
+ opts;
23276
+ async build() {
23277
+ const graphId = crypto.randomUUID();
23278
+ const phases = /* @__PURE__ */ new Map();
23279
+ const phaseIds = [];
23280
+ for (let i = 0; i < this.opts.phases.length; i++) {
23281
+ const tmpl = this.opts.phases[i];
23282
+ const phaseId = crypto.randomUUID();
23283
+ phaseIds.push(phaseId);
23284
+ const store = new DefaultTaskStore();
23285
+ const tracker = new TaskTracker({ store });
23286
+ const taskGraph = await tracker.createGraph(phaseId, `${tmpl.name} Tasks`);
23287
+ if (tmpl.taskTemplates && tmpl.taskTemplates.length > 0) {
23288
+ for (const tt of tmpl.taskTemplates) {
23289
+ tracker.addNode({
23290
+ title: tt.title,
23291
+ description: tt.description,
23292
+ type: tt.type,
23293
+ priority: tt.priority,
23294
+ status: "pending",
23295
+ estimateHours: tt.estimateHours,
23296
+ tags: tt.tags ?? []
23297
+ });
23298
+ }
23299
+ }
23300
+ const phase = {
23301
+ id: phaseId,
23302
+ name: tmpl.name,
23303
+ description: tmpl.description,
23304
+ status: "pending",
23305
+ taskGraph,
23306
+ dependsOn: i > 0 ? [phaseIds[i - 1]] : [],
23307
+ nextPhases: i < this.opts.phases.length - 1 ? [phaseIds[i + 1]] : [],
23308
+ parallelizable: tmpl.parallelizable,
23309
+ priority: tmpl.priority,
23310
+ estimateHours: tmpl.estimateHours,
23311
+ assignedAgents: [],
23312
+ createdAt: Date.now(),
23313
+ updatedAt: Date.now()
23314
+ };
23315
+ phases.set(phaseId, phase);
23316
+ }
23317
+ const phaseArray = Array.from(phases.values());
23318
+ for (let i = 0; i < phaseArray.length; i++) {
23319
+ const phase = phaseArray[i];
23320
+ phase.nextPhases = i < phaseArray.length - 1 ? [phaseArray[i + 1].id] : [];
23321
+ phase.dependsOn = i > 0 ? [phaseArray[i - 1].id] : [];
23322
+ }
23323
+ const graph = {
23324
+ id: graphId,
23325
+ title: this.opts.title,
23326
+ description: this.opts.description ?? "",
23327
+ phases,
23328
+ rootPhaseIds: phaseIds.length > 0 ? [phaseIds[0]] : [],
23329
+ activePhaseIds: [],
23330
+ completedPhaseIds: [],
23331
+ failedPhaseIds: [],
23332
+ autonomous: this.opts.autonomous ?? true,
23333
+ stopOnComplete: true,
23334
+ createdAt: Date.now(),
23335
+ updatedAt: Date.now()
23336
+ };
23337
+ return graph;
23338
+ }
23339
+ /**
23340
+ * Var olan bir TaskGraph'tan fazlar oluştur.
23341
+ * Task'ları priority/type göre gruplayarak fazlara ayırır.
23342
+ */
23343
+ static fromTaskGraph(taskGraph, options) {
23344
+ const tasksPerPhase = options.tasksPerPhase ?? 5;
23345
+ const nodes = Array.from(taskGraph.nodes.values());
23346
+ const sorted = [...nodes].sort((a, b) => {
23347
+ const prioOrder = { critical: 0, high: 1, medium: 2, low: 3 };
23348
+ return (prioOrder[a.priority] ?? 4) - (prioOrder[b.priority] ?? 4);
23349
+ });
23350
+ const groups = [];
23351
+ for (let i = 0; i < sorted.length; i += tasksPerPhase) {
23352
+ groups.push(sorted.slice(i, i + tasksPerPhase));
23353
+ }
23354
+ const phaseTemplates = groups.map((group, idx) => {
23355
+ const hasCritical = group.some((t2) => t2.priority === "critical");
23356
+ const totalHours = group.reduce((sum, t2) => sum + (t2.estimateHours ?? 2), 0);
23357
+ return {
23358
+ name: `Phase ${idx + 1}: ${group[0]?.title.slice(0, 30) ?? "Tasks"}`,
23359
+ description: group.map((t2) => t2.title).join(", "),
23360
+ priority: hasCritical ? "critical" : "high",
23361
+ estimateHours: totalHours,
23362
+ parallelizable: false,
23363
+ taskTemplates: group.map((t2) => ({
23364
+ title: t2.title,
23365
+ description: t2.description,
23366
+ type: t2.type,
23367
+ priority: t2.priority,
23368
+ estimateHours: t2.estimateHours ?? 2,
23369
+ tags: t2.tags ?? []
23370
+ }))
23371
+ };
23372
+ });
23373
+ const builder = new _PhaseGraphBuilder({
23374
+ ...options,
23375
+ phases: phaseTemplates
23376
+ });
23377
+ return builder.build();
23378
+ }
23379
+ };
23380
+
23381
+ // src/autophase/phase-orchestrator.ts
23382
+ var PhaseOrchestrator = class {
23383
+ graph;
23384
+ ctx;
23385
+ opts;
23386
+ events;
23387
+ stopped = false;
23388
+ paused = false;
23389
+ runningPhases = /* @__PURE__ */ new Set();
23390
+ tickInterval = null;
23391
+ constructor(opts) {
23392
+ this.graph = opts.graph;
23393
+ this.ctx = opts.ctx;
23394
+ this.events = opts.events ?? this.createNoopEventBus();
23395
+ this.opts = {
23396
+ maxConcurrentPhases: opts.maxConcurrentPhases ?? 1,
23397
+ maxConcurrentTasks: opts.maxConcurrentTasks ?? 2,
23398
+ maxRetries: opts.maxRetries ?? 2,
23399
+ autonomous: opts.autonomous ?? true,
23400
+ phaseDelayMs: opts.phaseDelayMs ?? 0,
23401
+ stopOnFailure: opts.stopOnFailure ?? true,
23402
+ events: this.events
23403
+ };
23404
+ }
23405
+ // ─── Lifecycle ────────────────────────────────────────────────────────────
23406
+ /**
23407
+ * Tüm faz akışını başlat.
23408
+ * Autonomous mode'da: kök faz(lar)ı başlatır, bitince sonrakini otomatik başlatır.
23409
+ */
23410
+ async start() {
23411
+ this.stopped = false;
23412
+ this.paused = false;
23413
+ this.graph.startedAt = Date.now();
23414
+ this.graph.updatedAt = Date.now();
23415
+ let readyPhases = this.getReadyPhases();
23416
+ while (readyPhases.length > 0 && !this.stopped) {
23417
+ const batch = readyPhases.slice(0, this.opts.maxConcurrentPhases);
23418
+ await Promise.all(batch.map((p) => this.startPhase(p)));
23419
+ readyPhases = this.getReadyPhases().filter(
23420
+ (p) => !this.runningPhases.has(p.id) && p.status !== "completed" && p.status !== "failed"
23421
+ );
23422
+ }
23423
+ if (this.opts.autonomous) {
23424
+ this.tickInterval = setInterval(() => this.tick(), 1e3);
23425
+ }
23426
+ }
23427
+ /** Duraklat — aktif fazlar çalışmaya devam eder ama yeni faz başlamaz */
23428
+ pause() {
23429
+ this.paused = true;
23430
+ }
23431
+ /** Devam et — yeni fazlar başlayabilir */
23432
+ resume() {
23433
+ this.paused = false;
23434
+ void this.tick();
23435
+ }
23436
+ /** Tamamen durdur — aktif fazlar da durdurulur */
23437
+ stop() {
23438
+ this.stopped = true;
23439
+ if (this.tickInterval) {
23440
+ clearInterval(this.tickInterval);
23441
+ this.tickInterval = null;
23442
+ }
23443
+ for (const phaseId of this.runningPhases) {
23444
+ const phase = this.graph.phases.get(phaseId);
23445
+ if (phase) {
23446
+ this.updatePhaseStatus(phase, "paused");
23447
+ }
23448
+ }
23449
+ }
23450
+ // ─── Tick Loop (Autonomous) ───────────────────────────────────────────────
23451
+ async tick() {
23452
+ if (this.stopped || this.paused) return;
23453
+ const active = this.getActivePhases();
23454
+ const ready = this.getReadyPhases();
23455
+ this.emit("autonomous.tick", {
23456
+ activePhases: active.map((p) => p.id),
23457
+ queuedPhases: ready.map((p) => p.id)
23458
+ });
23459
+ this.ctx.onTick?.({ activePhases: active, readyPhases: ready });
23460
+ const availableSlots = this.opts.maxConcurrentPhases - active.length;
23461
+ if (availableSlots > 0 && ready.length > 0) {
23462
+ for (const phase of ready.slice(0, availableSlots)) {
23463
+ await this.startPhase(phase);
23464
+ }
23465
+ }
23466
+ if (this.isComplete()) {
23467
+ this.onGraphComplete();
23468
+ return;
23469
+ }
23470
+ if (this.opts.stopOnFailure && this.graph.failedPhaseIds.length > 0) {
23471
+ const failedPhase = this.graph.phases.get(this.graph.failedPhaseIds[0]);
23472
+ if (failedPhase) {
23473
+ this.onGraphFailed(failedPhase);
23474
+ }
23475
+ return;
23476
+ }
23477
+ }
23478
+ // ─── Phase Execution ──────────────────────────────────────────────────────
23479
+ async startPhase(phase) {
23480
+ if (phase.status !== "pending" && phase.status !== "ready") return;
23481
+ this.updatePhaseStatus(phase, "running");
23482
+ phase.startedAt = Date.now();
23483
+ this.runningPhases.add(phase.id);
23484
+ this.graph.activePhaseIds.push(phase.id);
23485
+ this.emit("phase.started", { phaseId: phase.id, name: phase.name });
23486
+ try {
23487
+ await this.executePhaseTasks(phase);
23488
+ const failedTasks = this.getFailedTaskCount(phase);
23489
+ const completedTasks = this.getCompletedTaskCount(phase);
23490
+ this.emit("phase.allTasksDone", {
23491
+ phaseId: phase.id,
23492
+ completed: completedTasks,
23493
+ failed: failedTasks
23494
+ });
23495
+ if (failedTasks > 0 && this.opts.stopOnFailure) {
23496
+ this.updatePhaseStatus(phase, "failed");
23497
+ phase.completedAt = Date.now();
23498
+ phase.actualDurationMs = Date.now() - (phase.startedAt ?? Date.now());
23499
+ this.runningPhases.delete(phase.id);
23500
+ this.emit("phase.failed", {
23501
+ phaseId: phase.id,
23502
+ name: phase.name,
23503
+ error: `${failedTasks} task(s) failed`
23504
+ });
23505
+ this.ctx.onPhaseFail?.(phase, new Error(`${failedTasks} task(s) failed`));
23506
+ } else {
23507
+ this.updatePhaseStatus(phase, "completed");
23508
+ phase.completedAt = Date.now();
23509
+ phase.actualDurationMs = Date.now() - (phase.startedAt ?? Date.now());
23510
+ this.runningPhases.delete(phase.id);
23511
+ this.graph.completedPhaseIds.push(phase.id);
23512
+ this.emit("phase.completed", {
23513
+ phaseId: phase.id,
23514
+ name: phase.name,
23515
+ durationMs: phase.actualDurationMs
23516
+ });
23517
+ this.ctx.onPhaseComplete?.(phase);
23518
+ }
23519
+ } catch (error) {
23520
+ this.updatePhaseStatus(phase, "failed");
23521
+ phase.completedAt = Date.now();
23522
+ phase.actualDurationMs = Date.now() - (phase.startedAt ?? Date.now());
23523
+ this.runningPhases.delete(phase.id);
23524
+ this.graph.failedPhaseIds.push(phase.id);
23525
+ this.emit("phase.failed", {
23526
+ phaseId: phase.id,
23527
+ name: phase.name,
23528
+ error: error instanceof Error ? error.message : String(error)
23529
+ });
23530
+ this.ctx.onPhaseFail?.(phase, error instanceof Error ? error : new Error(String(error)));
23531
+ }
23532
+ }
23533
+ async executePhaseTasks(phase) {
23534
+ phase.taskGraph;
23535
+ const pendingTasks = this.getExecutableTasks(phase);
23536
+ while (pendingTasks.length > 0 && !this.stopped) {
23537
+ const batch = pendingTasks.splice(0, this.opts.maxConcurrentTasks);
23538
+ const results = await Promise.allSettled(
23539
+ batch.map((task) => this.executeSingleTask(task, phase))
23540
+ );
23541
+ for (let i = 0; i < results.length; i++) {
23542
+ const result = results[i];
23543
+ const task = batch[i];
23544
+ if (!result || !task) continue;
23545
+ if (result.status === "fulfilled") {
23546
+ this.markTaskCompleted(phase, task);
23547
+ } else {
23548
+ this.markTaskFailed(phase, task, result.reason);
23549
+ }
23550
+ }
23551
+ const newReady = this.getExecutableTasks(phase);
23552
+ pendingTasks.length = 0;
23553
+ pendingTasks.push(...newReady);
23554
+ }
23555
+ }
23556
+ async executeSingleTask(task, phase) {
23557
+ const tracker = this.getTrackerForPhase(phase);
23558
+ tracker.updateNodeStatus(task.id, "in_progress");
23559
+ return this.ctx.executeTask(task, phase.id);
23560
+ }
23561
+ markTaskCompleted(phase, task) {
23562
+ const tracker = this.getTrackerForPhase(phase);
23563
+ tracker.updateNodeStatus(task.id, "completed");
23564
+ this.emit("phase.taskCompleted", {
23565
+ phaseId: phase.id,
23566
+ taskId: task.id,
23567
+ taskTitle: task.title
23568
+ });
23569
+ }
23570
+ markTaskFailed(phase, task, error) {
23571
+ const tracker = this.getTrackerForPhase(phase);
23572
+ tracker.updateNodeStatus(task.id, "failed", error instanceof Error ? error.message : String(error));
23573
+ this.emit("phase.taskFailed", {
23574
+ phaseId: phase.id,
23575
+ taskId: task.id,
23576
+ taskTitle: task.title,
23577
+ error: error instanceof Error ? error.message : String(error)
23578
+ });
23579
+ }
23580
+ // ─── Helpers ──────────────────────────────────────────────────────────────
23581
+ getReadyPhases() {
23582
+ const ready = [];
23583
+ for (const phase of this.graph.phases.values()) {
23584
+ if (phase.status !== "pending") continue;
23585
+ const depsDone = phase.dependsOn.every((depId) => {
23586
+ const dep = this.graph.phases.get(depId);
23587
+ return dep?.status === "completed" || dep?.status === "skipped";
23588
+ });
23589
+ if (depsDone) {
23590
+ ready.push(phase);
23591
+ }
23592
+ }
23593
+ const prioOrder = { critical: 0, high: 1, medium: 2, low: 3 };
23594
+ ready.sort((a, b) => (prioOrder[a.priority] ?? 4) - (prioOrder[b.priority] ?? 4));
23595
+ return ready;
23596
+ }
23597
+ getActivePhases() {
23598
+ return Array.from(this.graph.phases.values()).filter((p) => p.status === "running");
23599
+ }
23600
+ getExecutableTasks(phase) {
23601
+ const tracker = this.getTrackerForPhase(phase);
23602
+ return tracker.getAllNodes({ status: ["pending", "blocked"] }).filter((n) => n.status === "pending" && tracker.canStart(n.id)).sort((a, b) => {
23603
+ const priorityOrder = { critical: 0, high: 1, medium: 2, low: 3 };
23604
+ return (priorityOrder[a.priority] ?? 4) - (priorityOrder[b.priority] ?? 4);
23605
+ });
23606
+ }
23607
+ getTrackerForPhase(phase) {
23608
+ const store = new DefaultTaskStore();
23609
+ const tracker = new TaskTracker({ store });
23610
+ tracker.graph = phase.taskGraph;
23611
+ return tracker;
23612
+ }
23613
+ getFailedTaskCount(phase) {
23614
+ const tracker = this.getTrackerForPhase(phase);
23615
+ return tracker.getAllNodes({ status: ["failed"] }).length;
23616
+ }
23617
+ getCompletedTaskCount(phase) {
23618
+ const tracker = this.getTrackerForPhase(phase);
23619
+ return tracker.getAllNodes({ status: ["completed"] }).length;
23620
+ }
23621
+ updatePhaseStatus(phase, status) {
23622
+ const from = phase.status;
23623
+ phase.status = status;
23624
+ phase.updatedAt = Date.now();
23625
+ this.graph.updatedAt = Date.now();
23626
+ this.emit("phase.statusChange", { phaseId: phase.id, from, to: status });
23627
+ }
23628
+ isComplete() {
23629
+ const allPhases = Array.from(this.graph.phases.values());
23630
+ return allPhases.every(
23631
+ (p) => p.status === "completed" || p.status === "skipped" || p.status === "failed"
23632
+ );
23633
+ }
23634
+ onGraphComplete() {
23635
+ this.graph.completedAt = Date.now();
23636
+ const durationMs = this.graph.completedAt - (this.graph.startedAt ?? this.graph.completedAt);
23637
+ this.emit("graph.completed", { graphId: this.graph.id, durationMs });
23638
+ this.stop();
23639
+ }
23640
+ onGraphFailed(failedPhase) {
23641
+ this.emit("graph.failed", {
23642
+ graphId: this.graph.id,
23643
+ failedPhaseId: failedPhase.id,
23644
+ error: `Phase "${failedPhase.name}" failed`
23645
+ });
23646
+ this.stop();
23647
+ }
23648
+ // ─── Progress ─────────────────────────────────────────────────────────────
23649
+ getProgress() {
23650
+ const phases = Array.from(this.graph.phases.values());
23651
+ let pending = 0, ready = 0, running = 0, paused = 0, completed = 0, failed = 0, skipped = 0;
23652
+ let totalTasks = 0, completedTasks = 0, failedTasks = 0, estimatedHours = 0, actualHours = 0;
23653
+ for (const p of phases) {
23654
+ switch (p.status) {
23655
+ case "pending":
23656
+ pending++;
23657
+ break;
23658
+ case "ready":
23659
+ ready++;
23660
+ break;
23661
+ case "running":
23662
+ running++;
23663
+ break;
23664
+ case "paused":
23665
+ paused++;
23666
+ break;
23667
+ case "completed":
23668
+ completed++;
23669
+ break;
23670
+ case "failed":
23671
+ failed++;
23672
+ break;
23673
+ case "skipped":
23674
+ skipped++;
23675
+ break;
23676
+ }
23677
+ estimatedHours += p.estimateHours;
23678
+ if (p.actualDurationMs) actualHours += p.actualDurationMs / 36e5;
23679
+ const tracker = this.getTrackerForPhase(p);
23680
+ const progress = tracker.getProgress();
23681
+ totalTasks += progress.total;
23682
+ completedTasks += progress.completed;
23683
+ failedTasks += progress.failed;
23684
+ }
23685
+ const totalPhases = phases.length;
23686
+ const done = completed + skipped;
23687
+ return {
23688
+ totalPhases,
23689
+ pending,
23690
+ ready,
23691
+ running,
23692
+ paused,
23693
+ completed,
23694
+ failed,
23695
+ skipped,
23696
+ percentComplete: totalPhases > 0 ? Math.round(done / totalPhases * 100) : 0,
23697
+ totalTasks,
23698
+ completedTasks,
23699
+ failedTasks,
23700
+ estimatedHours,
23701
+ actualHours
23702
+ };
23703
+ }
23704
+ getGraph() {
23705
+ return this.graph;
23706
+ }
23707
+ isRunning() {
23708
+ return !this.stopped && this.runningPhases.size > 0;
23709
+ }
23710
+ isPaused() {
23711
+ return this.paused;
23712
+ }
23713
+ // ─── Agent Assignment ─────────────────────────────────────────────────────
23714
+ assignAgent(phaseId, agentId) {
23715
+ const phase = this.graph.phases.get(phaseId);
23716
+ if (!phase) return;
23717
+ if (!phase.assignedAgents.includes(agentId)) {
23718
+ phase.assignedAgents.push(agentId);
23719
+ this.emit("agent.assigned", { phaseId, agentId });
23720
+ }
23721
+ }
23722
+ releaseAgent(phaseId, agentId) {
23723
+ const phase = this.graph.phases.get(phaseId);
23724
+ if (!phase) return;
23725
+ phase.assignedAgents = phase.assignedAgents.filter((id) => id !== agentId);
23726
+ this.emit("agent.released", { phaseId, agentId });
23727
+ }
23728
+ // ─── Events ───────────────────────────────────────────────────────────────
23729
+ emit(event, payload) {
23730
+ this.events.emit(event, payload);
23731
+ }
23732
+ createNoopEventBus() {
23733
+ return {
23734
+ emit: () => {
23735
+ },
23736
+ on: () => {
23737
+ },
23738
+ off: () => {
23739
+ },
23740
+ once: () => {
23741
+ },
23742
+ listeners: /* @__PURE__ */ new Map(),
23743
+ wildcards: /* @__PURE__ */ new Set(),
23744
+ setLogger: () => {
23745
+ },
23746
+ onAny: () => {
23747
+ },
23748
+ offAny: () => {
23749
+ },
23750
+ emitAsync: async () => [],
23751
+ waitFor: async () => {
23752
+ }
23753
+ };
23754
+ }
23755
+ };
23756
+
23757
+ // src/autophase/auto-phase-runner.ts
23758
+ var AutoPhaseRunner = class {
23759
+ graph = null;
23760
+ orchestrator = null;
23761
+ opts;
23762
+ progressInterval = null;
23763
+ constructor(opts) {
23764
+ this.opts = opts;
23765
+ }
23766
+ async start() {
23767
+ const builder = new PhaseGraphBuilder({
23768
+ title: this.opts.title,
23769
+ description: this.opts.description,
23770
+ phases: this.opts.phases,
23771
+ autonomous: this.opts.autonomous,
23772
+ stopOnFailure: this.opts.stopOnFailure
23773
+ });
23774
+ this.graph = await builder.build();
23775
+ const ctx = {
23776
+ executeTask: this.opts.executeTask,
23777
+ onPhaseComplete: (phase) => {
23778
+ this.opts.onPhaseComplete?.(phase);
23779
+ },
23780
+ onPhaseFail: (phase, error) => {
23781
+ this.opts.onPhaseFail?.(phase, error);
23782
+ },
23783
+ onTick: (tickCtx) => {
23784
+ this.opts.onTick?.(tickCtx);
23785
+ }
23786
+ };
23787
+ this.orchestrator = new PhaseOrchestrator({
23788
+ graph: this.graph,
23789
+ ctx,
23790
+ maxConcurrentPhases: this.opts.maxConcurrentPhases,
23791
+ maxConcurrentTasks: this.opts.maxConcurrentTasks,
23792
+ maxRetries: this.opts.maxRetries,
23793
+ autonomous: this.opts.autonomous,
23794
+ phaseDelayMs: this.opts.phaseDelayMs,
23795
+ stopOnFailure: this.opts.stopOnFailure,
23796
+ events: this.opts.events
23797
+ });
23798
+ if (this.opts.onProgress) {
23799
+ this.progressInterval = setInterval(() => {
23800
+ const progress = this.orchestrator.getProgress();
23801
+ this.opts.onProgress(progress);
23802
+ }, 2e3);
23803
+ }
23804
+ const events = this.opts.events;
23805
+ if (events) {
23806
+ events.on(
23807
+ "graph.completed",
23808
+ (payload) => {
23809
+ const p = payload;
23810
+ if (this.graph && p.graphId === this.graph.id) {
23811
+ this.opts.onComplete?.(this.graph);
23812
+ this.cleanup();
23813
+ }
23814
+ }
23815
+ );
23816
+ events.on(
23817
+ "graph.failed",
23818
+ (payload) => {
23819
+ const p = payload;
23820
+ if (this.graph && p.graphId === this.graph.id) {
23821
+ const failedPhase = this.graph.phases.get(p.failedPhaseId);
23822
+ if (failedPhase) {
23823
+ this.opts.onFail?.(this.graph, failedPhase, new Error(p.error));
23824
+ }
23825
+ this.cleanup();
23826
+ }
23827
+ }
23828
+ );
23829
+ }
23830
+ await this.orchestrator.start();
23831
+ return this.graph;
23832
+ }
23833
+ pause() {
23834
+ this.orchestrator?.pause();
23835
+ }
23836
+ resume() {
23837
+ this.orchestrator?.resume();
23838
+ }
23839
+ stop() {
23840
+ this.orchestrator?.stop();
23841
+ this.cleanup();
23842
+ }
23843
+ getProgress() {
23844
+ return this.orchestrator?.getProgress() ?? null;
23845
+ }
23846
+ getGraph() {
23847
+ return this.graph;
23848
+ }
23849
+ isRunning() {
23850
+ return this.orchestrator?.isRunning() ?? false;
23851
+ }
23852
+ isPaused() {
23853
+ return this.orchestrator?.isPaused() ?? false;
23854
+ }
23855
+ assignAgent(phaseId, agentId) {
23856
+ this.orchestrator?.assignAgent(phaseId, agentId);
23857
+ }
23858
+ releaseAgent(phaseId, agentId) {
23859
+ this.orchestrator?.releaseAgent(phaseId, agentId);
23860
+ }
23861
+ cleanup() {
23862
+ if (this.progressInterval) {
23863
+ clearInterval(this.progressInterval);
23864
+ this.progressInterval = null;
23865
+ }
23866
+ }
23867
+ };
23868
+ async function createAutoPhaseFromTaskGraph(taskGraph, options) {
23869
+ const graph = await PhaseGraphBuilder.fromTaskGraph(taskGraph, {
23870
+ title: options.title ?? taskGraph.title,
23871
+ tasksPerPhase: options.tasksPerPhase
23872
+ });
23873
+ const phases = Array.from(graph.phases.values()).map((p) => ({
23874
+ name: p.name,
23875
+ description: p.description,
23876
+ priority: p.priority,
23877
+ estimateHours: p.estimateHours,
23878
+ parallelizable: p.parallelizable
23879
+ }));
23880
+ return new AutoPhaseRunner({
23881
+ ...options,
23882
+ title: options.title ?? taskGraph.title,
23883
+ phases
23884
+ });
23885
+ }
23886
+ var PhaseStore = class {
23887
+ baseDir;
23888
+ constructor(opts) {
23889
+ this.baseDir = opts.baseDir;
23890
+ }
23891
+ async save(graph) {
23892
+ const filePath = this.getFilePath(graph.id);
23893
+ await fsp2.mkdir(path6.dirname(filePath), { recursive: true });
23894
+ const serialized = this.serializeGraph(graph);
23895
+ await fsp2.writeFile(filePath, JSON.stringify(serialized, null, 2), "utf8");
23896
+ }
23897
+ async load(graphId) {
23898
+ const filePath = this.getFilePath(graphId);
23899
+ try {
23900
+ const raw = await fsp2.readFile(filePath, "utf8");
23901
+ const serialized = JSON.parse(raw);
23902
+ return this.deserializeGraph(serialized);
23903
+ } catch {
23904
+ return null;
23905
+ }
23906
+ }
23907
+ async delete(graphId) {
23908
+ const filePath = this.getFilePath(graphId);
23909
+ try {
23910
+ await fsp2.unlink(filePath);
23911
+ } catch {
23912
+ }
23913
+ }
23914
+ async list() {
23915
+ try {
23916
+ const entries = await fsp2.readdir(this.baseDir, { withFileTypes: true });
23917
+ const graphs = [];
23918
+ for (const entry of entries) {
23919
+ if (!entry.isFile() || !entry.name.endsWith(".json")) continue;
23920
+ try {
23921
+ const raw = await fsp2.readFile(path6.join(this.baseDir, entry.name), "utf8");
23922
+ const serialized = JSON.parse(raw);
23923
+ const done = serialized.completedPhaseIds.length;
23924
+ const total = serialized.phases.length;
23925
+ graphs.push({
23926
+ id: serialized.id,
23927
+ title: serialized.title,
23928
+ updatedAt: serialized.updatedAt,
23929
+ status: done === total ? "completed" : done > 0 ? "in_progress" : "pending"
23930
+ });
23931
+ } catch {
23932
+ }
23933
+ }
23934
+ return graphs.sort((a, b) => b.updatedAt - a.updatedAt);
23935
+ } catch {
23936
+ return [];
23937
+ }
23938
+ }
23939
+ getFilePath(graphId) {
23940
+ return path6.join(this.baseDir, `${graphId}.json`);
23941
+ }
23942
+ serializeGraph(graph) {
23943
+ return {
23944
+ id: graph.id,
23945
+ title: graph.title,
23946
+ description: graph.description,
23947
+ phases: Array.from(graph.phases.values()).map((p) => this.serializePhase(p)),
23948
+ rootPhaseIds: graph.rootPhaseIds,
23949
+ activePhaseIds: graph.activePhaseIds,
23950
+ completedPhaseIds: graph.completedPhaseIds,
23951
+ failedPhaseIds: graph.failedPhaseIds,
23952
+ autonomous: graph.autonomous,
23953
+ stopOnComplete: graph.stopOnComplete,
23954
+ createdAt: graph.createdAt,
23955
+ updatedAt: graph.updatedAt,
23956
+ startedAt: graph.startedAt,
23957
+ completedAt: graph.completedAt
23958
+ };
23959
+ }
23960
+ serializePhase(phase) {
23961
+ return {
23962
+ id: phase.id,
23963
+ name: phase.name,
23964
+ description: phase.description,
23965
+ status: phase.status,
23966
+ taskGraph: this.serializeTaskGraph(phase.taskGraph),
23967
+ dependsOn: phase.dependsOn,
23968
+ nextPhases: phase.nextPhases,
23969
+ parallelizable: phase.parallelizable,
23970
+ priority: phase.priority,
23971
+ estimateHours: phase.estimateHours,
23972
+ actualDurationMs: phase.actualDurationMs,
23973
+ startedAt: phase.startedAt,
23974
+ completedAt: phase.completedAt,
23975
+ assignedAgents: phase.assignedAgents,
23976
+ metadata: phase.metadata,
23977
+ createdAt: phase.createdAt,
23978
+ updatedAt: phase.updatedAt
23979
+ };
23980
+ }
23981
+ serializeTaskGraph(graph) {
23982
+ return {
23983
+ id: graph.id,
23984
+ specId: graph.specId,
23985
+ title: graph.title,
23986
+ nodes: Array.from(graph.nodes.values()).map((n) => this.serializeTaskNode(n)),
23987
+ edges: graph.edges,
23988
+ rootNodes: graph.rootNodes,
23989
+ createdAt: graph.createdAt,
23990
+ updatedAt: graph.updatedAt
23991
+ };
23992
+ }
23993
+ serializeTaskNode(node) {
23994
+ return { ...node };
23995
+ }
23996
+ deserializeGraph(serialized) {
23997
+ const phases = /* @__PURE__ */ new Map();
23998
+ for (const sp of serialized.phases) {
23999
+ phases.set(sp.id, this.deserializePhase(sp));
24000
+ }
24001
+ return {
24002
+ id: serialized.id,
24003
+ title: serialized.title,
24004
+ description: serialized.description,
24005
+ phases,
24006
+ rootPhaseIds: serialized.rootPhaseIds,
24007
+ activePhaseIds: serialized.activePhaseIds,
24008
+ completedPhaseIds: serialized.completedPhaseIds,
24009
+ failedPhaseIds: serialized.failedPhaseIds,
24010
+ autonomous: serialized.autonomous,
24011
+ stopOnComplete: serialized.stopOnComplete,
24012
+ createdAt: serialized.createdAt,
24013
+ updatedAt: serialized.updatedAt,
24014
+ startedAt: serialized.startedAt,
24015
+ completedAt: serialized.completedAt
24016
+ };
24017
+ }
24018
+ deserializePhase(serialized) {
24019
+ return {
24020
+ id: serialized.id,
24021
+ name: serialized.name,
24022
+ description: serialized.description,
24023
+ status: serialized.status,
24024
+ taskGraph: this.deserializeTaskGraph(serialized.taskGraph),
24025
+ dependsOn: serialized.dependsOn,
24026
+ nextPhases: serialized.nextPhases,
24027
+ parallelizable: serialized.parallelizable,
24028
+ priority: serialized.priority,
24029
+ estimateHours: serialized.estimateHours,
24030
+ actualDurationMs: serialized.actualDurationMs,
24031
+ startedAt: serialized.startedAt,
24032
+ completedAt: serialized.completedAt,
24033
+ assignedAgents: serialized.assignedAgents,
24034
+ metadata: serialized.metadata,
24035
+ createdAt: serialized.createdAt,
24036
+ updatedAt: serialized.updatedAt
24037
+ };
24038
+ }
24039
+ deserializeTaskGraph(serialized) {
24040
+ const nodes = /* @__PURE__ */ new Map();
24041
+ for (const sn of serialized.nodes) {
24042
+ nodes.set(sn.id, sn);
24043
+ }
24044
+ return {
24045
+ id: serialized.id,
24046
+ specId: serialized.specId,
24047
+ title: serialized.title,
24048
+ nodes,
24049
+ edges: serialized.edges,
24050
+ rootNodes: serialized.rootNodes,
24051
+ createdAt: serialized.createdAt,
24052
+ updatedAt: serialized.updatedAt
24053
+ };
24054
+ }
24055
+ };
24056
+
24057
+ // src/autophase/checkpoint.ts
24058
+ var CheckpointManager = class {
24059
+ store;
24060
+ maxCheckpoints;
24061
+ checkpoints = /* @__PURE__ */ new Map();
24062
+ constructor(opts) {
24063
+ this.store = opts.store;
24064
+ this.maxCheckpoints = opts.maxCheckpoints ?? 10;
24065
+ }
24066
+ async saveCheckpoint(graph, label) {
24067
+ await this.store.save(graph);
24068
+ const activePhase = Array.from(graph.phases.values()).find(
24069
+ (p) => p.status === "running" || p.status === "paused"
24070
+ );
24071
+ const checkpoint = {
24072
+ id: crypto.randomUUID(),
24073
+ graphId: graph.id,
24074
+ phaseId: activePhase?.id ?? graph.rootPhaseIds[0] ?? "",
24075
+ phaseStatus: activePhase?.status ?? "pending",
24076
+ taskStatuses: activePhase ? Array.from(activePhase.taskGraph.nodes.values()).map((t2) => ({
24077
+ taskId: t2.id,
24078
+ status: t2.status,
24079
+ title: t2.title
24080
+ })) : [],
24081
+ timestamp: Date.now(),
24082
+ label
24083
+ };
24084
+ this.checkpoints.set(checkpoint.id, checkpoint);
24085
+ this.pruneCheckpoints();
24086
+ return checkpoint;
24087
+ }
24088
+ async restoreCheckpoint(checkpointId) {
24089
+ const checkpoint = this.checkpoints.get(checkpointId);
24090
+ if (!checkpoint) return null;
24091
+ const graph = await this.store.load(checkpoint.graphId);
24092
+ if (!graph) return null;
24093
+ const phase = graph.phases.get(checkpoint.phaseId);
24094
+ if (phase) {
24095
+ phase.status = checkpoint.phaseStatus;
24096
+ phase.updatedAt = Date.now();
24097
+ for (const ts of checkpoint.taskStatuses) {
24098
+ const task = phase.taskGraph.nodes.get(ts.taskId);
24099
+ if (task) {
24100
+ task.status = ts.status;
24101
+ task.updatedAt = Date.now();
24102
+ }
24103
+ }
24104
+ }
24105
+ graph.updatedAt = Date.now();
24106
+ return graph;
24107
+ }
24108
+ listCheckpoints(graphId) {
24109
+ const all = Array.from(this.checkpoints.values());
24110
+ const filtered = graphId ? all.filter((c) => c.graphId === graphId) : all;
24111
+ return filtered.sort((a, b) => b.timestamp - a.timestamp);
24112
+ }
24113
+ deleteCheckpoint(checkpointId) {
24114
+ return this.checkpoints.delete(checkpointId);
24115
+ }
24116
+ pruneCheckpoints() {
24117
+ const all = Array.from(this.checkpoints.values()).sort(
24118
+ (a, b) => a.timestamp - b.timestamp
24119
+ );
24120
+ while (all.length > this.maxCheckpoints) {
24121
+ const oldest = all.shift();
24122
+ if (oldest) this.checkpoints.delete(oldest.id);
24123
+ }
24124
+ }
24125
+ };
24126
+
24127
+ export { AGENTS_BY_PHASE, AGENT_CATALOG, AISpecBuilder, ALL_AGENT_DEFINITIONS, ALL_FLEET_AGENTS, AUDIT_LOG_AGENT, Agent, AgentError, AutoApprovePermissionPolicy, AutoCompactionMiddleware, AutoExecutor, AutoPhaseRunner, AutonomousRunner, BUG_HUNTER_AGENT, BudgetExceededError, CONTEXT_WINDOW_MODES, CheckpointManager, ConfigError, ConfigMigrationError, Container, Context, ConversationState, DEFAULT_CONFIG_MIGRATIONS, DEFAULT_CONTEXT_CONFIG, DEFAULT_CONTEXT_WINDOW_MODE_ID, DEFAULT_DIRECTOR_PREAMBLE, DEFAULT_DISPATCH_ROLE, DEFAULT_MAX_ITERATIONS, DEFAULT_MODES, DEFAULT_RECOVERY_STRATEGIES, DEFAULT_SPEC_TEMPLATE, DEFAULT_SUBAGENT_BASELINE, DEFAULT_TOOLS_CONFIG, DefaultAttachmentStore, DefaultConfigLoader, DefaultConfigStore, DefaultErrorHandler, DefaultHealthRegistry, DefaultLogger, DefaultMemoryStore, DefaultModeStore, DefaultModelsRegistry, DefaultMultiAgentCoordinator, DefaultPathResolver, DefaultPermissionPolicy, DefaultPluginAPI, DefaultProviderRunner, DefaultRetryPolicy, DefaultSecretScrubber, DefaultSecretVault, DefaultSessionReader, DefaultSessionRewinder, DefaultSessionStore, DefaultSkillLoader, DefaultSystemPromptBuilder, DefaultTaskStore, DefaultTokenCounter, Director, DirectorStateCheckpoint, DoneConditionChecker, ERROR_CODES, EternalAutonomyEngine, EventBus, ExtensionRegistry, FLEET_ROSTER, FLEET_ROSTER_BUDGETS, FleetBus, FleetManager, FleetSpawnBudgetError, FleetUsageAggregator, FsError, GitignoreUpdater, HybridCompactor, InMemoryAgentBridge, InMemoryBridgeTransport, InMemoryMetricsSink, InputBuilder, IntelligentCompactor, KERNEL_API_VERSION, LAYER_1_IDENTITY, LLMSelector, MAX_JOURNAL_ENTRIES, NULL_FLEET_BUS, NoopMetricsSink, NoopTracer, OTelTracer, PROMETHEUS_CONTENT_TYPE, ParallelEternalEngine, PhaseGraphBuilder, PhaseOrchestrator, PhaseStore, Pipeline, PluginError, ProviderError, ProviderRegistry, QueueStore, REFACTOR_PLANNER_AGENT, RecoveryLock, ReportGenerator, RunController, SECURITY_SCANNER_AGENT, SPEC_TEMPLATES, ScopedEventBus, SddParallelRun, SddTaskDecomposer, SecurityScanner, SecurityScannerOrchestrator, SelectiveCompactor, SessionAnalyzer, SessionError, SkillGenerator, SkillInstaller, SkillManifestStore, SlashCommandRegistry, SpecDrivenDev, SpecParser, SpecStore, SpecVersioning, SubagentBudget, TOKENS, TaskFlow, TaskGenerator, TaskGraphStore, TaskTracker, TechStackDetector, ToolError, ToolExecutor, ToolRegistry, WrongStackError, addPlanItem, allServers, analyzeCriticalPath, appendJournal, applyRosterBudget, asBlocks, asText, atomicWrite, attachAutoExtend, attachPlanCheckpoint, attachTodosCheckpoint, awsServer, blockServer, braveSearchServer, buildBtwBlock, buildChildEnv, buildGoalPreamble, buildOtlpMetricsRequest, buildOtlpTracesRequest, buildRecoveryStrategies, classifyFamily, clearPlan, color, compileGlob, compileUserRegex, composeDirectorPrompt, composeSubagentPrompt, computeTaskProgress, consumeBtwNotes, context7Server, contextManagerTool, createAutoExecutor, createAutoPhaseFromTaskGraph, createContextManagerTool, createDefaultPipelines, createDelegateTool, createMcpControlTool, createMessage, createSecuritySlashCommand, createToolOutputSerializer, decryptConfigSecrets, defaultGitignoreUpdater, defaultOrchestrator, defaultReportGenerator, defaultSecurityScanner, defaultSkillGenerator, defaultTechStackDetector, deriveTodosFromPlanItem, detectNewlineStyle, dispatchAgent, downloadGitHubTarball, emptyGoal, emptyPlan, encryptConfigSecrets, ensureDir, estimateRequestTokens, estimateTextTokens, estimateToolDefTokens, estimateToolInputTokens, estimateToolResultTokens, everArtServer, extractRunEnv, filesystemServer, findCriticalPath, formatContextWindowModeList, formatGoal, formatPlan, formatPlanTemplates, formatTodosList, getAgentDefinition, getContextWindowMode, getPlanTemplate, getTemplate, githubServer, goalFilePath, googleMapsServer, isAgentError, isConfigError, isContextWindowModeId, isFsError, isImageBlock, isPluginError, isSessionError, isTextBlock, isThinkingBlock, isToolError, isToolResultBlock, isToolUseBlock, isWrongStackError, listContextWindowModes, listPlanTemplates, listTemplates, loadDirectorState, loadGoal, loadPlan, loadPlugins, loadProjectModes, loadTodosCheckpoint, loadUserModes, makeAgentSubagentRunner, makeAutonomyPromptContributor, makeContinueToNextIterationTool, makeDirectorSessionFactory, makeLLMClassifier, matchAny, matchGlob, migratePlaintextSecrets, miniMaxVisionServer, normalizeToLf, parseContinueDirective, parseSkillRef, pendingBtwCount, projectHash, removePlanItem, renderProgress, renderPrometheus, renderSpecAnalysis, renderTaskGraph, renderTaskList, repairToolUseAdjacency, resolveContextWindowPolicy, resolveWstackPaths, rewriteConfigEncrypted, rosterSummaryFromConfigs, runConfigMigrations, safeParse, safeStringify, sanitizeJsonString, saveGoal, savePlan, saveTodosCheckpoint, scoreAgents, securitySlashCommand, sentinelServer, setBtwNote, setPlanItemStatus, slackServer, startMetricsServer, startOtlpMetricsExporter, startOtlpTraceExporter, stripAnsi, summarizeUsage, templateToMarkdown, toStyle, toWrongStackError, topologicalSort, unifiedDiff, unloadPlugins, validateAgainstSchema, wireMetricsToEvents, wrapAsState, zaiVisionServer };
23265
24128
  //# sourceMappingURL=index.js.map
23266
24129
  //# sourceMappingURL=index.js.map