@kimbho/kimbho-cli 0.1.26 → 0.1.30

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.cjs CHANGED
@@ -12718,7 +12718,7 @@ function createCompletionRuntimeCommand(program2) {
12718
12718
  // package.json
12719
12719
  var package_default = {
12720
12720
  name: "@kimbho/kimbho-cli",
12721
- version: "0.1.26",
12721
+ version: "0.1.30",
12722
12722
  description: "Kimbho CLI is a terminal-native coding agent for planning, execution, and verification.",
12723
12723
  type: "module",
12724
12724
  engines: {
@@ -13080,11 +13080,11 @@ var AGENT_CATALOG = {
13080
13080
  "Design-system mismatch",
13081
13081
  "Frontend contract drift"
13082
13082
  ],
13083
- maxConcurrentTasks: 2,
13083
+ maxConcurrentTasks: 3,
13084
13084
  policy: {
13085
13085
  sandboxMode: "workspace-write",
13086
13086
  canSpawnSubagents: true,
13087
- maxSubagentDepth: 1
13087
+ maxSubagentDepth: 2
13088
13088
  }
13089
13089
  },
13090
13090
  "backend-specialist": {
@@ -13110,11 +13110,11 @@ var AGENT_CATALOG = {
13110
13110
  "Schema drift",
13111
13111
  "Unclear domain contract"
13112
13112
  ],
13113
- maxConcurrentTasks: 2,
13113
+ maxConcurrentTasks: 3,
13114
13114
  policy: {
13115
13115
  sandboxMode: "workspace-write",
13116
13116
  canSpawnSubagents: true,
13117
- maxSubagentDepth: 1
13117
+ maxSubagentDepth: 2
13118
13118
  }
13119
13119
  },
13120
13120
  "database-specialist": {
@@ -13140,7 +13140,7 @@ var AGENT_CATALOG = {
13140
13140
  "Data-destructive migration",
13141
13141
  "Unclear persistence requirements"
13142
13142
  ],
13143
- maxConcurrentTasks: 1,
13143
+ maxConcurrentTasks: 2,
13144
13144
  policy: {
13145
13145
  sandboxMode: "workspace-write",
13146
13146
  requireApprovalPatterns: [
@@ -13149,7 +13149,7 @@ var AGENT_CATALOG = {
13149
13149
  "\\bdrop\\s+database\\b"
13150
13150
  ],
13151
13151
  canSpawnSubagents: true,
13152
- maxSubagentDepth: 1
13152
+ maxSubagentDepth: 2
13153
13153
  }
13154
13154
  },
13155
13155
  "infra-specialist": {
@@ -13180,7 +13180,7 @@ var AGENT_CATALOG = {
13180
13180
  "Dependency installation",
13181
13181
  "External environment changes"
13182
13182
  ],
13183
- maxConcurrentTasks: 1,
13183
+ maxConcurrentTasks: 2,
13184
13184
  policy: {
13185
13185
  sandboxMode: "workspace-write",
13186
13186
  requireApprovalPatterns: [
@@ -13192,7 +13192,7 @@ var AGENT_CATALOG = {
13192
13192
  "\\bapt(-get)?\\s+install\\b"
13193
13193
  ],
13194
13194
  canSpawnSubagents: true,
13195
- maxSubagentDepth: 1
13195
+ maxSubagentDepth: 2
13196
13196
  }
13197
13197
  },
13198
13198
  "test-debugger": {
@@ -17627,6 +17627,44 @@ var RepoStrategySchema = external_exports.object({
17627
17627
  ]),
17628
17628
  reasoning: external_exports.string().min(1)
17629
17629
  });
17630
+ var TaskExecutionPhaseSchema = external_exports.enum([
17631
+ "survey",
17632
+ "plan-edit",
17633
+ "implement",
17634
+ "verify",
17635
+ "repair",
17636
+ "finalize",
17637
+ "escalate"
17638
+ ]);
17639
+ var TaskVerifierStateSchema = external_exports.object({
17640
+ availableCommands: external_exports.array(external_exports.string().min(1)).default([]),
17641
+ preferredCommands: external_exports.array(external_exports.string().min(1)).default([]),
17642
+ attemptedCommands: external_exports.array(external_exports.string().min(1)).default([]),
17643
+ disabledCommands: external_exports.array(external_exports.string().min(1)).default([]),
17644
+ successfulCommands: external_exports.array(external_exports.string().min(1)).default([]),
17645
+ currentCommand: external_exports.string().min(1).optional(),
17646
+ latestFailureSummary: external_exports.string().min(1).optional(),
17647
+ latestFailureCommand: external_exports.string().min(1).optional(),
17648
+ latestSuccessfulCommand: external_exports.string().min(1).optional(),
17649
+ requiresInteractiveSetup: external_exports.boolean().default(false)
17650
+ });
17651
+ var TaskWorldModelSchema = external_exports.object({
17652
+ phase: TaskExecutionPhaseSchema.default("survey"),
17653
+ targetFiles: external_exports.array(external_exports.string().min(1)).default([]),
17654
+ inspectedFiles: external_exports.array(external_exports.string().min(1)).default([]),
17655
+ changedFiles: external_exports.array(external_exports.string().min(1)).default([]),
17656
+ hypotheses: external_exports.array(external_exports.string().min(1)).default([]),
17657
+ blockers: external_exports.array(external_exports.string().min(1)).default([]),
17658
+ proofPending: external_exports.array(external_exports.string().min(1)).default([]),
17659
+ proofSatisfied: external_exports.array(external_exports.string().min(1)).default([]),
17660
+ recentActions: external_exports.array(external_exports.string().min(1)).default([]),
17661
+ recentCommands: external_exports.array(external_exports.string().min(1)).default([]),
17662
+ nextFocus: external_exports.string().min(1).optional(),
17663
+ sourceEditCount: external_exports.number().int().nonnegative().default(0),
17664
+ validationLoopCount: external_exports.number().int().nonnegative().default(0),
17665
+ verifier: TaskVerifierStateSchema.default({}),
17666
+ lastUpdatedAt: external_exports.string().datetime().optional()
17667
+ });
17630
17668
  var PlanTaskSchema = external_exports.object({
17631
17669
  id: external_exports.string().min(1),
17632
17670
  title: external_exports.string().min(1),
@@ -17662,7 +17700,8 @@ var PlanTaskSchema = external_exports.object({
17662
17700
  teamId: external_exports.string().min(1).optional(),
17663
17701
  teamMemberIds: external_exports.array(external_exports.string()).optional(),
17664
17702
  subagentLabel: external_exports.string().min(1).optional(),
17665
- subagentInstructions: external_exports.string().min(1).optional()
17703
+ subagentInstructions: external_exports.string().min(1).optional(),
17704
+ executionState: TaskWorldModelSchema.optional()
17666
17705
  });
17667
17706
  var PlanMilestoneSchema = external_exports.object({
17668
17707
  id: external_exports.string().min(1),
@@ -18150,6 +18189,103 @@ var LegacyKimbhoConfigSchema = external_exports.object({
18150
18189
  "next-prisma-postgres"
18151
18190
  ])
18152
18191
  });
18192
+ function uniqueModelIds(models) {
18193
+ return Array.from(new Set(models.map((model) => model?.trim()).filter((model) => Boolean(model))));
18194
+ }
18195
+ function providerCandidateModels(provider) {
18196
+ if (!provider) {
18197
+ return [];
18198
+ }
18199
+ return uniqueModelIds([
18200
+ provider.defaultModel,
18201
+ ...provider.models
18202
+ ]);
18203
+ }
18204
+ function estimateModelScale(model) {
18205
+ const matches = Array.from(model.matchAll(/(\d+(?:\.\d+)?)b/gi));
18206
+ if (matches.length === 0) {
18207
+ return 0;
18208
+ }
18209
+ return Math.max(...matches.map((match) => Number.parseFloat(match[1] ?? "0")).filter((value) => Number.isFinite(value)));
18210
+ }
18211
+ function scoreModelForRole(model, role) {
18212
+ const normalized = model.toLowerCase();
18213
+ const scale = estimateModelScale(normalized);
18214
+ let score = 0;
18215
+ if (/gpt-5(?!.*mini)(?!.*nano)/i.test(normalized) || /\bgpt5\b/i.test(normalized)) {
18216
+ score += 160;
18217
+ }
18218
+ if (/\bo3\b|\bo4\b|o4-mini-high/i.test(normalized)) {
18219
+ score += 145;
18220
+ }
18221
+ if (/opus|sonnet|claude-4|claude-3\.7/i.test(normalized)) {
18222
+ score += /opus|claude-4/i.test(normalized) ? 150 : 132;
18223
+ }
18224
+ if (/gpt-4\.1|gpt-4o|deepseek-r1|deepseek-v3|qwq/i.test(normalized)) {
18225
+ score += 122;
18226
+ }
18227
+ if (/qwen.*(?:32b|35b|72b|110b|235b)|llama.*(?:70b|90b|405b)|mixtral/i.test(normalized)) {
18228
+ score += 110;
18229
+ }
18230
+ if (/reason|thinking|r1|o[34]/i.test(normalized)) {
18231
+ score += 20;
18232
+ }
18233
+ if (scale > 0) {
18234
+ score += Math.min(scale, 120) * 0.8;
18235
+ }
18236
+ if (/mini|nano|flash|haiku|small|fast|instant|lite/i.test(normalized)) {
18237
+ score -= 55;
18238
+ }
18239
+ if (/\b(?:3|7|8|9|14)b\b/i.test(normalized)) {
18240
+ score -= 35;
18241
+ }
18242
+ if (/preview|experimental|beta/i.test(normalized)) {
18243
+ score -= 6;
18244
+ }
18245
+ if (role === "fast") {
18246
+ let fastBias = 0;
18247
+ if (/mini|nano|flash|haiku|small|fast|instant|lite/i.test(normalized)) {
18248
+ fastBias += 95;
18249
+ }
18250
+ if (/sonnet|gpt-4o-mini|gpt-5-mini|claude.*haiku/i.test(normalized)) {
18251
+ fastBias += 60;
18252
+ }
18253
+ if (scale >= 32) {
18254
+ fastBias -= 40;
18255
+ } else if (scale > 0 && scale <= 16) {
18256
+ fastBias += 24;
18257
+ }
18258
+ return fastBias + score * 0.2;
18259
+ }
18260
+ if (role === "reviewer") {
18261
+ if (/reason|thinking|r1|\bo3\b|\bo4\b|opus/i.test(normalized)) {
18262
+ score += 24;
18263
+ }
18264
+ if (/mini|flash|haiku/i.test(normalized)) {
18265
+ score -= 10;
18266
+ }
18267
+ }
18268
+ if (role === "planner") {
18269
+ if (/reason|thinking|r1|\bo3\b|\bo4\b|sonnet|opus/i.test(normalized)) {
18270
+ score += 18;
18271
+ }
18272
+ }
18273
+ if (role === "coder") {
18274
+ if (/sonnet|gpt-5|gpt-4\.1|deepseek|qwen|llama/i.test(normalized)) {
18275
+ score += 16;
18276
+ }
18277
+ }
18278
+ return score;
18279
+ }
18280
+ function pickPreferredProviderModel(provider, role) {
18281
+ const candidates = providerCandidateModels(provider);
18282
+ if (candidates.length === 0) {
18283
+ return null;
18284
+ }
18285
+ return [
18286
+ ...candidates
18287
+ ].sort((left, right) => scoreModelForRole(right, role) - scoreModelForRole(left, role))[0] ?? null;
18288
+ }
18153
18289
  function createBrainCatalog(providerId, defaultModel, fastModel) {
18154
18290
  return {
18155
18291
  planner: {
@@ -18229,12 +18365,13 @@ function normalizeConfigInput(raw) {
18229
18365
  const legacy = LegacyKimbhoConfigSchema.safeParse(raw);
18230
18366
  if (legacy.success) {
18231
18367
  const provider = mapLegacyProviderToDefinition(legacy.data.provider);
18232
- const defaultModel = provider.defaultModel ?? "gpt-5";
18368
+ const defaultModel = pickPreferredProviderModel(provider, "planner") ?? provider.defaultModel ?? "gpt-5";
18369
+ const fastModel = pickPreferredProviderModel(provider, "fast") ?? defaultModel;
18233
18370
  return {
18234
18371
  providers: [
18235
18372
  provider
18236
18373
  ],
18237
- brains: createBrainCatalog(provider.id, defaultModel, defaultModel),
18374
+ brains: createBrainCatalog(provider.id, defaultModel, fastModel),
18238
18375
  approvalMode: legacy.data.approvalMode,
18239
18376
  sandboxMode: legacy.data.sandboxMode,
18240
18377
  stackPresets: legacy.data.stackPresets,
@@ -18285,8 +18422,8 @@ function createDefaultConfig(options = {}) {
18285
18422
  baseUrl: "https://api.openai.com/v1",
18286
18423
  defaultModel: "gpt-5"
18287
18424
  });
18288
- const defaultModel = options.defaultModel ?? provider.defaultModel;
18289
- const fastModel = options.fastModel ?? defaultModel;
18425
+ const defaultModel = options.defaultModel ?? pickPreferredProviderModel(provider, "planner") ?? provider.defaultModel;
18426
+ const fastModel = options.fastModel ?? pickPreferredProviderModel(provider, "fast") ?? defaultModel;
18290
18427
  return KimbhoConfigSchema.parse({
18291
18428
  providers: [
18292
18429
  provider
@@ -18765,7 +18902,10 @@ function resolveBrainSettings(config2, role) {
18765
18902
  function resolveBrainModel(config2, role) {
18766
18903
  const settings = resolveBrainSettings(config2, role);
18767
18904
  const provider = findProviderById(config2, settings.providerId);
18768
- return settings.model ?? provider?.defaultModel ?? null;
18905
+ if (settings.model) {
18906
+ return settings.model;
18907
+ }
18908
+ return pickPreferredProviderModel(provider, role) ?? provider?.defaultModel ?? null;
18769
18909
  }
18770
18910
 
18771
18911
  // ../core/dist/session/store.js
@@ -32988,6 +33128,9 @@ function combinePositiveLimit(...values) {
32988
33128
  }
32989
33129
  return Math.min(...filtered);
32990
33130
  }
33131
+ function uniqueStrings2(values) {
33132
+ return Array.from(new Set(values.map((value) => value.trim()).filter((value) => value.length > 0)));
33133
+ }
32991
33134
  function truncateForModel(value) {
32992
33135
  if (!value) {
32993
33136
  return value;
@@ -33077,6 +33220,18 @@ function isReadOnlyShellCommand2(command) {
33077
33220
  "git diff"
33078
33221
  ].some((prefix) => normalized === prefix || normalized.startsWith(prefix));
33079
33222
  }
33223
+ function isShellFileInspectionCommand(command) {
33224
+ const normalized = command.trim().toLowerCase();
33225
+ return [
33226
+ "cat ",
33227
+ "head ",
33228
+ "tail ",
33229
+ "wc ",
33230
+ "sed ",
33231
+ "more ",
33232
+ "less "
33233
+ ].some((prefix) => normalized === prefix || normalized.startsWith(prefix));
33234
+ }
33080
33235
  function isVerificationCommand(command) {
33081
33236
  const normalized = command.trim().toLowerCase();
33082
33237
  return [
@@ -33121,6 +33276,310 @@ function isVerificationAction(action) {
33121
33276
  const command = typeof action.input.command === "string" ? action.input.command : "";
33122
33277
  return command.length > 0 && isVerificationCommand(command);
33123
33278
  }
33279
+ function isRuntimeValidationAction(action) {
33280
+ if (action.type !== "tool") {
33281
+ return false;
33282
+ }
33283
+ if (isVerificationAction(action)) {
33284
+ return true;
33285
+ }
33286
+ return [
33287
+ "process.start",
33288
+ "process.logs",
33289
+ "process.stop",
33290
+ "browser.open",
33291
+ "browser.inspect",
33292
+ "browser.click",
33293
+ "browser.fill",
33294
+ "browser.close",
33295
+ "http.fetch"
33296
+ ].includes(action.tool);
33297
+ }
33298
+ function isShellFileInspectionAction(action) {
33299
+ if (action.type !== "tool" || action.tool !== "shell.exec") {
33300
+ return false;
33301
+ }
33302
+ const command = typeof action.input.command === "string" ? action.input.command : "";
33303
+ return isShellFileInspectionCommand(command);
33304
+ }
33305
+ function isRepoInspectionAction(action) {
33306
+ if (action.type !== "tool") {
33307
+ return false;
33308
+ }
33309
+ return [
33310
+ "file.read",
33311
+ "file.search",
33312
+ "file.list",
33313
+ "repo.index",
33314
+ "repo.query",
33315
+ "git.diff"
33316
+ ].includes(action.tool);
33317
+ }
33318
+ function normalizeWorkspacePath(cwd, value) {
33319
+ const normalized = value.replace(/\\/g, "/").trim();
33320
+ if (normalized.length === 0) {
33321
+ return normalized;
33322
+ }
33323
+ if (!import_node_path14.default.isAbsolute(normalized)) {
33324
+ return normalized.replace(/^\.\//, "");
33325
+ }
33326
+ const relative = import_node_path14.default.relative(cwd, normalized).replace(/\\/g, "/");
33327
+ return relative.length > 0 && !relative.startsWith("..") ? relative : normalized;
33328
+ }
33329
+ async function detectVerificationCommands(cwd) {
33330
+ const commands = [];
33331
+ const packagePath = import_node_path14.default.join(cwd, "package.json");
33332
+ try {
33333
+ await (0, import_promises14.access)(packagePath);
33334
+ const raw = await (0, import_promises14.readFile)(packagePath, "utf8");
33335
+ const parsed = JSON.parse(raw);
33336
+ const scripts = parsed.scripts ?? {};
33337
+ const packageManager = parsed.packageManager?.startsWith("pnpm") ? "pnpm" : parsed.packageManager?.startsWith("yarn") ? "yarn" : parsed.packageManager?.startsWith("bun") ? "bun" : "npm";
33338
+ const renderRun = (script) => {
33339
+ if (packageManager === "yarn") {
33340
+ return `yarn ${script}`;
33341
+ }
33342
+ return `${packageManager} run ${script}`;
33343
+ };
33344
+ if (scripts.typecheck) {
33345
+ commands.push(renderRun("typecheck"));
33346
+ }
33347
+ if (scripts.build) {
33348
+ commands.push(renderRun("build"));
33349
+ }
33350
+ if (scripts.test) {
33351
+ commands.push(renderRun("test"));
33352
+ }
33353
+ if (scripts.lint) {
33354
+ commands.push(renderRun("lint"));
33355
+ }
33356
+ } catch {
33357
+ }
33358
+ if (commands.length === 0) {
33359
+ try {
33360
+ await (0, import_promises14.access)(import_node_path14.default.join(cwd, "tsconfig.json"));
33361
+ commands.push("npx tsc --noEmit");
33362
+ } catch {
33363
+ }
33364
+ }
33365
+ const unique = uniqueStrings2(commands);
33366
+ const preferred = [
33367
+ ...unique.filter((command) => /typecheck|build|test/i.test(command)),
33368
+ ...unique.filter((command) => /lint/i.test(command) && !/typecheck|build|test/i.test(command))
33369
+ ];
33370
+ return {
33371
+ availableCommands: unique,
33372
+ preferredCommands: uniqueStrings2(preferred)
33373
+ };
33374
+ }
33375
+ function createInitialWorldModel(task, request, verifier) {
33376
+ const phase = task.type === "verification" ? "verify" : task.type === "integration" || task.type === "documentation" ? "finalize" : request.workspaceState === "existing" ? "survey" : "implement";
33377
+ return {
33378
+ phase,
33379
+ targetFiles: uniqueStrings2(task.filesLikelyTouched.map((filePath) => normalizeWorkspacePath(request.cwd, filePath))),
33380
+ inspectedFiles: [],
33381
+ changedFiles: [],
33382
+ hypotheses: uniqueStrings2([
33383
+ `Satisfy task acceptance criteria for ${task.id}.`,
33384
+ task.description
33385
+ ]),
33386
+ blockers: [],
33387
+ proofPending: uniqueStrings2(task.acceptanceCriteria),
33388
+ proofSatisfied: [],
33389
+ recentActions: [],
33390
+ recentCommands: [],
33391
+ nextFocus: phase === "verify" ? "Run the preferred verification path and capture proof." : "Inspect the likely source files and determine the minimal safe change.",
33392
+ sourceEditCount: 0,
33393
+ validationLoopCount: 0,
33394
+ verifier: {
33395
+ availableCommands: verifier.availableCommands,
33396
+ preferredCommands: verifier.preferredCommands,
33397
+ attemptedCommands: [],
33398
+ disabledCommands: [],
33399
+ successfulCommands: [],
33400
+ requiresInteractiveSetup: false
33401
+ },
33402
+ lastUpdatedAt: (/* @__PURE__ */ new Date()).toISOString()
33403
+ };
33404
+ }
33405
+ function summarizeWorldModel(worldModel) {
33406
+ return [
33407
+ `phase: ${worldModel.phase}`,
33408
+ `next focus: ${worldModel.nextFocus ?? "(unset)"}`,
33409
+ `target files: ${worldModel.targetFiles.join(", ") || "(none)"}`,
33410
+ `inspected files: ${worldModel.inspectedFiles.join(", ") || "(none)"}`,
33411
+ `changed files: ${worldModel.changedFiles.join(", ") || "(none)"}`,
33412
+ `hypotheses: ${worldModel.hypotheses.join(" | ") || "(none)"}`,
33413
+ `blockers: ${worldModel.blockers.join(" | ") || "(none)"}`,
33414
+ `proof pending: ${worldModel.proofPending.join(" | ") || "(none)"}`,
33415
+ `proof satisfied: ${worldModel.proofSatisfied.join(" | ") || "(none)"}`,
33416
+ `verifier preferred commands: ${worldModel.verifier.preferredCommands.join(", ") || "(none)"}`,
33417
+ `verifier disabled commands: ${worldModel.verifier.disabledCommands.join(", ") || "(none)"}`,
33418
+ `latest verifier failure: ${worldModel.verifier.latestFailureSummary ?? "(none)"}`,
33419
+ `recent actions: ${worldModel.recentActions.join(" | ") || "(none)"}`
33420
+ ].join("\n");
33421
+ }
33422
+ function recordWorldModelAction(worldModel, label, command) {
33423
+ return {
33424
+ ...worldModel,
33425
+ recentActions: uniqueStrings2([
33426
+ ...worldModel.recentActions.slice(-5),
33427
+ label
33428
+ ]).slice(-6),
33429
+ recentCommands: command ? uniqueStrings2([
33430
+ ...worldModel.recentCommands.slice(-5),
33431
+ command
33432
+ ]).slice(-6) : worldModel.recentCommands,
33433
+ lastUpdatedAt: (/* @__PURE__ */ new Date()).toISOString()
33434
+ };
33435
+ }
33436
+ function scoreVerificationCommand(command, worldModel) {
33437
+ const normalized = command.trim().toLowerCase();
33438
+ let score = 0;
33439
+ if (worldModel.phase === "repair" && worldModel.verifier.latestFailureCommand && normalized === worldModel.verifier.latestFailureCommand.trim().toLowerCase()) {
33440
+ score += 80;
33441
+ }
33442
+ if (/typecheck|tsc --noemit|tsc\b/i.test(normalized)) {
33443
+ score += worldModel.proofPending.some((item) => /typescript|compile|type/i.test(item)) ? 70 : 32;
33444
+ }
33445
+ if (/build/i.test(normalized)) {
33446
+ score += worldModel.proofPending.some((item) => /build|compile|render|page|layout|responsive/i.test(item)) ? 68 : 34;
33447
+ }
33448
+ if (/test|vitest|jest/i.test(normalized)) {
33449
+ score += worldModel.proofPending.some((item) => /test|behavior|logic|regression/i.test(item)) ? 74 : 38;
33450
+ }
33451
+ if (/lint|eslint/i.test(normalized)) {
33452
+ score += worldModel.proofPending.some((item) => /lint|style|quality/i.test(item)) ? 54 : 18;
33453
+ }
33454
+ if (/dev|serve|start/i.test(normalized)) {
33455
+ score -= 18;
33456
+ }
33457
+ if (worldModel.verifier.successfulCommands.includes(command)) {
33458
+ score -= 12;
33459
+ }
33460
+ if (worldModel.verifier.disabledCommands.includes(command)) {
33461
+ score -= 1e3;
33462
+ }
33463
+ return score;
33464
+ }
33465
+ function determineNextVerificationCommand(worldModel) {
33466
+ const candidates = uniqueStrings2([
33467
+ ...worldModel.phase === "repair" && worldModel.verifier.latestFailureCommand ? [
33468
+ worldModel.verifier.latestFailureCommand
33469
+ ] : [],
33470
+ ...worldModel.verifier.preferredCommands,
33471
+ ...worldModel.verifier.availableCommands
33472
+ ]).filter((command) => !worldModel.verifier.disabledCommands.includes(command));
33473
+ if (candidates.length === 0) {
33474
+ return null;
33475
+ }
33476
+ return [
33477
+ ...candidates
33478
+ ].sort((left, right) => scoreVerificationCommand(right, worldModel) - scoreVerificationCommand(left, worldModel))[0] ?? null;
33479
+ }
33480
+ function updateProofStateForVerification(worldModel, command, success2) {
33481
+ if (!command || !success2) {
33482
+ return {
33483
+ proofPending: worldModel.proofPending,
33484
+ proofSatisfied: worldModel.proofSatisfied
33485
+ };
33486
+ }
33487
+ const normalized = command.toLowerCase();
33488
+ const satisfiedLabels = [];
33489
+ let proofPending = [
33490
+ ...worldModel.proofPending
33491
+ ];
33492
+ const satisfyMatching = (pattern, fallback) => {
33493
+ const matching = proofPending.filter((item) => pattern.test(item));
33494
+ if (matching.length > 0) {
33495
+ satisfiedLabels.push(...matching);
33496
+ proofPending = proofPending.filter((item) => !pattern.test(item));
33497
+ return;
33498
+ }
33499
+ satisfiedLabels.push(fallback);
33500
+ };
33501
+ if (/typecheck|tsc --noemit|tsc\b/.test(normalized)) {
33502
+ satisfyMatching(/typescript|compile|type/i, `Type safety verified via ${command}`);
33503
+ }
33504
+ if (/build/.test(normalized)) {
33505
+ satisfyMatching(/build|compile|render|page|layout|responsive/i, `Build/render verification passed via ${command}`);
33506
+ }
33507
+ if (/test|vitest|jest/.test(normalized)) {
33508
+ satisfyMatching(/test|behavior|logic|regression/i, `Behavior verified via ${command}`);
33509
+ }
33510
+ if (/lint|eslint/.test(normalized)) {
33511
+ satisfyMatching(/lint|style|quality/i, `Code quality verified via ${command}`);
33512
+ }
33513
+ if (satisfiedLabels.length === 0) {
33514
+ satisfiedLabels.push(`Verified via ${command}`);
33515
+ }
33516
+ return {
33517
+ proofPending: uniqueStrings2(proofPending),
33518
+ proofSatisfied: uniqueStrings2([
33519
+ ...worldModel.proofSatisfied,
33520
+ ...satisfiedLabels
33521
+ ])
33522
+ };
33523
+ }
33524
+ function derivePhaseGuidance(worldModel) {
33525
+ switch (worldModel.phase) {
33526
+ case "survey":
33527
+ return [
33528
+ "Survey likely source files and constraints before making a change.",
33529
+ "Do not spend more than one baseline validation action before a real source edit lands."
33530
+ ];
33531
+ case "plan-edit":
33532
+ case "implement":
33533
+ return [
33534
+ "Make the concrete source change now.",
33535
+ "Use file.patch or file.write against the likely target files before further runtime validation."
33536
+ ];
33537
+ case "verify":
33538
+ return [
33539
+ `Use the strategic verifier next: ${determineNextVerificationCommand(worldModel) ?? "(choose the best non-interactive verifier)"}.`,
33540
+ "Capture proof for the changed behavior before finishing."
33541
+ ];
33542
+ case "repair":
33543
+ return [
33544
+ `Repair the latest failing verifier before rerunning it: ${worldModel.verifier.latestFailureSummary ?? "(missing failure summary)"}.`,
33545
+ "Inspect failure output, edit the relevant source, then rerun the strategic verifier."
33546
+ ];
33547
+ case "finalize":
33548
+ return [
33549
+ "Only finish once the key proof is captured and no blocker remains.",
33550
+ "Use git.diff or one final verifier if you still need confirmation."
33551
+ ];
33552
+ case "escalate":
33553
+ return [
33554
+ "Summarize blockers precisely so the supervisor can reassign or replan."
33555
+ ];
33556
+ }
33557
+ }
33558
+ function deriveSupervisorHints(status, task, worldModel) {
33559
+ const delegatedTask = Boolean(task.parentTaskId);
33560
+ if (status === "completed" && delegatedTask) {
33561
+ return {
33562
+ shouldMergeDelegatedWork: true,
33563
+ shouldReprioritize: true,
33564
+ reason: `Delegated task ${task.id} completed; parent flow may be ready to merge or reprioritize.`
33565
+ };
33566
+ }
33567
+ if (status === "blocked" || status === "handoff" || worldModel.phase === "escalate") {
33568
+ return {
33569
+ shouldReplan: true,
33570
+ shouldReprioritize: delegatedTask,
33571
+ reason: worldModel.blockers[0] ?? `Task ${task.id} needs supervisor intervention.`
33572
+ };
33573
+ }
33574
+ if (delegatedTask && worldModel.phase === "repair") {
33575
+ return {
33576
+ shouldReplan: true,
33577
+ shouldReprioritize: true,
33578
+ reason: `Delegated task ${task.id} is in repair mode and may need reassignment or dependency changes.`
33579
+ };
33580
+ }
33581
+ return void 0;
33582
+ }
33124
33583
  function extractShellCommand(action) {
33125
33584
  if (action.type !== "tool" || action.tool !== "shell.exec") {
33126
33585
  return "";
@@ -33139,7 +33598,7 @@ function isInteractiveVerificationSetupFailure(action, result) {
33139
33598
  ].join("\n").toLowerCase();
33140
33599
  return combined.includes("interactive eslint setup required") || combined.includes("command requires interactive input before it can continue") || command.includes("lint") && combined.includes("how would you like to configure eslint");
33141
33600
  }
33142
- function buildSystemPrompt(agent, task, request, allowedTools, plan, extraInstructions) {
33601
+ function buildSystemPrompt(agent, task, request, allowedTools, worldModel, plan, extraInstructions) {
33143
33602
  const toolShape = allowedTools.join("|");
33144
33603
  const dependencyTasks = plan ? flattenPlanTasks(plan).filter((candidate) => task.dependsOn.includes(candidate.id)) : [];
33145
33604
  const completedTasks = plan ? flattenPlanTasks(plan).filter((candidate) => candidate.status === "completed" && candidate.id !== task.id) : [];
@@ -33153,6 +33612,7 @@ function buildSystemPrompt(agent, task, request, allowedTools, plan, extraInstru
33153
33612
  `Goal: ${request.goal}`,
33154
33613
  `Current task: ${task.id} - ${task.title}`,
33155
33614
  `Task description: ${task.description}`,
33615
+ `Execution phase: ${worldModel.phase}`,
33156
33616
  `Acceptance criteria:`,
33157
33617
  ...task.acceptanceCriteria.map((item) => `- ${item}`),
33158
33618
  `Likely files: ${task.filesLikelyTouched.join(", ") || "(not specified)"}`,
@@ -33162,6 +33622,8 @@ function buildSystemPrompt(agent, task, request, allowedTools, plan, extraInstru
33162
33622
  `Completed tasks in this run: ${completedTasks.length > 0 ? completedTasks.slice(-4).map((candidate) => `${candidate.id}:${candidate.title}`).join(", ") : "(none yet)"}`,
33163
33623
  `Downstream tasks depending on this task: ${downstreamTasks.length > 0 ? downstreamTasks.slice(0, 4).map((candidate) => `${candidate.id}:${candidate.title}`).join(", ") : "(none)"}`,
33164
33624
  `Allowed tools: ${allowedTools.join(", ")}`,
33625
+ `Task world-model:`,
33626
+ summarizeWorldModel(worldModel),
33165
33627
  `Respond with exactly one JSON object and no markdown.`,
33166
33628
  `Tool action shape: {"type":"tool","tool":"${toolShape}","input":{...},"reason":"why this step matters"}`,
33167
33629
  `Finish shape: {"type":"finish","summary":"what was completed and verified"}`,
@@ -33170,6 +33632,7 @@ function buildSystemPrompt(agent, task, request, allowedTools, plan, extraInstru
33170
33632
  `- Use one action per response.`,
33171
33633
  `- Use file.list, file.search, repo.index, and repo.query to explore the workspace before editing.`,
33172
33634
  `- Prefer file.read before editing existing files.`,
33635
+ `- For repo file inspection, prefer file.read, file.search, file.list, repo.query, and git.diff instead of shell.exec cat/head/tail/wc/sed.`,
33173
33636
  `- Use scaffold.generate when the task is clearly greenfield and a known preset fits better than improvising every file by hand.`,
33174
33637
  `- Use file.patch for existing files when possible; use file.write for new files or full replacements.`,
33175
33638
  `- Use git.diff to inspect the current patch after changes when helpful.`,
@@ -33184,6 +33647,7 @@ function buildSystemPrompt(agent, task, request, allowedTools, plan, extraInstru
33184
33647
  `- If a verification command asks for interactive setup or operator input, do not rerun it unchanged. Choose a different non-interactive verifier, or configure that verifier only if the task explicitly requires it.`,
33185
33648
  `- Do not claim success unless the task acceptance criteria are satisfied.`,
33186
33649
  `- If the task is underspecified, make a pragmatic implementation choice and continue.`,
33650
+ ...derivePhaseGuidance(worldModel).map((rule) => `- ${rule}`),
33187
33651
  ...task.subagentInstructions ? [
33188
33652
  `Delegation instructions:`,
33189
33653
  task.subagentInstructions
@@ -33341,17 +33805,6 @@ function inferFallbackActionFromResponse(raw, task, request, allowedTools) {
33341
33805
  };
33342
33806
  }
33343
33807
  }
33344
- if (allowedTools.includes("scaffold.generate") && looksLikeStaticLandingGoal(request.goal) && task.filesLikelyTouched.some((filePath) => filePath === "src/app/page.tsx" || filePath === "src/app/layout.tsx" || filePath === "src/pages/index.tsx" || filePath === "index.html" || filePath === "styles.css")) {
33345
- return {
33346
- type: "tool",
33347
- tool: "scaffold.generate",
33348
- input: {
33349
- goal: request.goal,
33350
- preset: "static-landing"
33351
- },
33352
- reason: "Use the deterministic static-site adapter because the model stayed out of structured mode."
33353
- };
33354
- }
33355
33808
  if (!allowedTools.includes("file.write")) {
33356
33809
  return null;
33357
33810
  }
@@ -33484,6 +33937,8 @@ var AutonomousTaskExecutor = class {
33484
33937
  const brain = await this.resolver.resolve(effectiveBrainRole);
33485
33938
  const allowedTools = resolvedExecutionPolicy.allowedTools;
33486
33939
  const actionSchema = createAgentActionSchema(allowedTools);
33940
+ const verificationCommands = await detectVerificationCommands(request.cwd);
33941
+ let worldModel = task.executionState ?? createInitialWorldModel(task, request, verificationCommands);
33487
33942
  const messages = [
33488
33943
  {
33489
33944
  role: "user",
@@ -33510,11 +33965,13 @@ var AutonomousTaskExecutor = class {
33510
33965
  }
33511
33966
  };
33512
33967
  let changedWorkspace = false;
33968
+ let appliedSourceEdit = false;
33513
33969
  let verifiedAfterLatestChange = false;
33514
33970
  let repairRequiredBeforeVerification = false;
33515
33971
  let repairAppliedSinceFailure = false;
33516
33972
  let verificationFailures = 0;
33517
33973
  let lastVerificationFailure = null;
33974
+ let preEditValidationActions = 0;
33518
33975
  let preservedMessageCount = messages.length;
33519
33976
  let compactedTranscriptEntries = 0;
33520
33977
  let compactionSummary = null;
@@ -33525,6 +33982,26 @@ var AutonomousTaskExecutor = class {
33525
33982
  inputTokens: 0,
33526
33983
  outputTokens: 0
33527
33984
  };
33985
+ const snapshotWorldModel = () => ({
33986
+ ...worldModel,
33987
+ lastUpdatedAt: (/* @__PURE__ */ new Date()).toISOString()
33988
+ });
33989
+ const makeOutcome = (status, summary, extra = {}) => {
33990
+ const currentWorldModel = snapshotWorldModel();
33991
+ const supervisorHints = deriveSupervisorHints(status, task, currentWorldModel);
33992
+ return {
33993
+ status,
33994
+ summary,
33995
+ toolResults,
33996
+ artifacts: Array.from(artifacts),
33997
+ usage: usageTotals,
33998
+ worldModel: currentWorldModel,
33999
+ ...supervisorHints ? {
34000
+ supervisorHints
34001
+ } : {},
34002
+ ...extra
34003
+ };
34004
+ };
33528
34005
  const createToolExecutionContext = (step, approvalReason, operatorApproved = false) => ({
33529
34006
  cwd: request.cwd,
33530
34007
  ...options.signal ? {
@@ -33598,13 +34075,17 @@ var AutonomousTaskExecutor = class {
33598
34075
  });
33599
34076
  const transcriptPath2 = await writeTranscriptArtifact(request.cwd, sessionId, task.id, transcript);
33600
34077
  artifacts.add(transcriptPath2);
33601
- return {
33602
- status: "blocked",
33603
- summary,
33604
- toolResults,
33605
- artifacts: Array.from(artifacts),
33606
- usage: usageTotals
34078
+ worldModel = {
34079
+ ...worldModel,
34080
+ phase: "escalate",
34081
+ blockers: uniqueStrings2([
34082
+ ...worldModel.blockers,
34083
+ summary
34084
+ ]),
34085
+ nextFocus: "Supervisor should replan or reassign this task because a budget was exhausted.",
34086
+ lastUpdatedAt: (/* @__PURE__ */ new Date()).toISOString()
33607
34087
  };
34088
+ return makeOutcome("blocked", summary);
33608
34089
  };
33609
34090
  await emitProgress({
33610
34091
  type: "task-note",
@@ -33633,24 +34114,32 @@ var AutonomousTaskExecutor = class {
33633
34114
  });
33634
34115
  const transcriptPath2 = await writeTranscriptArtifact(request.cwd, sessionId, task.id, transcript);
33635
34116
  artifacts.add(transcriptPath2);
33636
- return {
33637
- status: "blocked",
33638
- summary,
33639
- toolResults,
33640
- artifacts: Array.from(artifacts),
33641
- usage: usageTotals
34117
+ worldModel = {
34118
+ ...worldModel,
34119
+ phase: "escalate",
34120
+ blockers: uniqueStrings2([
34121
+ ...worldModel.blockers,
34122
+ summary
34123
+ ]),
34124
+ nextFocus: "Supervisor should inspect why this task has no executable tools.",
34125
+ lastUpdatedAt: (/* @__PURE__ */ new Date()).toISOString()
33642
34126
  };
34127
+ return makeOutcome("blocked", summary);
33643
34128
  }
33644
34129
  if (resolvedApproval?.decision === "deny") {
33645
34130
  const transcriptPath2 = await writeTranscriptArtifact(request.cwd, sessionId, task.id, transcript);
33646
34131
  artifacts.add(transcriptPath2);
33647
- return {
33648
- status: "blocked",
33649
- summary: `Operator denied approval for ${resolvedApproval.approval.toolId} in ${task.id}.`,
33650
- toolResults,
33651
- artifacts: Array.from(artifacts),
33652
- usage: usageTotals
34132
+ worldModel = {
34133
+ ...worldModel,
34134
+ phase: "escalate",
34135
+ blockers: uniqueStrings2([
34136
+ ...worldModel.blockers,
34137
+ `Operator denied ${resolvedApproval.approval.toolId}.`
34138
+ ]),
34139
+ nextFocus: "Choose a safer path or wait for supervisor replanning after the denied action.",
34140
+ lastUpdatedAt: (/* @__PURE__ */ new Date()).toISOString()
33653
34141
  };
34142
+ return makeOutcome("blocked", `Operator denied approval for ${resolvedApproval.approval.toolId} in ${task.id}.`);
33654
34143
  }
33655
34144
  if (request.workspaceState === "existing") {
33656
34145
  const preflightResults = [];
@@ -33692,6 +34181,18 @@ var AutonomousTaskExecutor = class {
33692
34181
  for (const artifact of result.artifacts) {
33693
34182
  artifacts.add(artifact);
33694
34183
  }
34184
+ if (toolId === "file.read" && result.success && typeof input.path === "string") {
34185
+ worldModel = {
34186
+ ...worldModel,
34187
+ inspectedFiles: uniqueStrings2([
34188
+ ...worldModel.inspectedFiles,
34189
+ normalizeWorkspacePath(request.cwd, input.path)
34190
+ ]),
34191
+ phase: worldModel.phase === "survey" ? "plan-edit" : worldModel.phase,
34192
+ nextFocus: worldModel.phase === "survey" ? "Make the concrete source change in the inspected target files." : worldModel.nextFocus,
34193
+ lastUpdatedAt: (/* @__PURE__ */ new Date()).toISOString()
34194
+ };
34195
+ }
33695
34196
  transcript.push({
33696
34197
  step: 0,
33697
34198
  response: JSON.stringify({
@@ -33791,6 +34292,14 @@ ${truncateForModel(customAgentMemory)}`);
33791
34292
  ].join("\n\n")
33792
34293
  });
33793
34294
  }
34295
+ if (request.workspaceState === "existing" && (task.type === "scaffold" || task.type === "implementation") && worldModel.phase === "survey") {
34296
+ worldModel = {
34297
+ ...worldModel,
34298
+ phase: "plan-edit",
34299
+ nextFocus: "Edit the likely source files before using more verification or browser/runtime checks.",
34300
+ lastUpdatedAt: (/* @__PURE__ */ new Date()).toISOString()
34301
+ };
34302
+ }
33794
34303
  }
33795
34304
  preservedMessageCount = messages.length;
33796
34305
  const runToolAction = async (parsedAction, step, operatorApproved = false) => {
@@ -33852,7 +34361,10 @@ ${truncateForModel(customAgentMemory)}`);
33852
34361
  const applyToolResult = async (parsedAction, result, step, transcriptEntry) => {
33853
34362
  const mutatingAction = isMutatingAction(parsedAction);
33854
34363
  const verificationAction = isVerificationAction(parsedAction);
34364
+ const runtimeValidationAction = isRuntimeValidationAction(parsedAction);
34365
+ const shellCommand = extractShellCommand(parsedAction);
33855
34366
  const interactiveVerificationSetupFailure = verificationAction && !result.success && isInteractiveVerificationSetupFailure(parsedAction, result);
34367
+ worldModel = recordWorldModelAction(worldModel, parsedAction.type === "tool" ? `${parsedAction.tool}${shellCommand ? ` ${shellCommand}` : ""}` : parsedAction.type === "finish" ? "finish" : "block", shellCommand || void 0);
33856
34368
  if (mutatingAction && result.success) {
33857
34369
  changedWorkspace = true;
33858
34370
  verifiedAfterLatestChange = false;
@@ -33860,22 +34372,121 @@ ${truncateForModel(customAgentMemory)}`);
33860
34372
  repairAppliedSinceFailure = true;
33861
34373
  }
33862
34374
  }
34375
+ if (parsedAction.tool === "file.write" || parsedAction.tool === "file.patch") {
34376
+ if (result.success) {
34377
+ appliedSourceEdit = true;
34378
+ preEditValidationActions = 0;
34379
+ worldModel = {
34380
+ ...worldModel,
34381
+ phase: "verify",
34382
+ changedFiles: uniqueStrings2([
34383
+ ...worldModel.changedFiles,
34384
+ ...result.artifacts.map((artifact) => normalizeWorkspacePath(request.cwd, artifact)),
34385
+ ...typeof parsedAction.input.path === "string" ? [
34386
+ normalizeWorkspacePath(request.cwd, parsedAction.input.path)
34387
+ ] : []
34388
+ ]),
34389
+ blockers: [],
34390
+ sourceEditCount: worldModel.sourceEditCount + 1,
34391
+ nextFocus: `Run the strategic verifier next: ${determineNextVerificationCommand(worldModel) ?? "choose the best non-interactive verifier"}.`,
34392
+ lastUpdatedAt: (/* @__PURE__ */ new Date()).toISOString()
34393
+ };
34394
+ }
34395
+ }
34396
+ if (!appliedSourceEdit && runtimeValidationAction) {
34397
+ preEditValidationActions += 1;
34398
+ worldModel = {
34399
+ ...worldModel,
34400
+ validationLoopCount: worldModel.validationLoopCount + 1,
34401
+ nextFocus: "Make a source edit before spending more time on runtime validation.",
34402
+ lastUpdatedAt: (/* @__PURE__ */ new Date()).toISOString()
34403
+ };
34404
+ }
34405
+ if (parsedAction.tool === "file.read" && result.success && typeof parsedAction.input.path === "string") {
34406
+ worldModel = {
34407
+ ...worldModel,
34408
+ inspectedFiles: uniqueStrings2([
34409
+ ...worldModel.inspectedFiles,
34410
+ normalizeWorkspacePath(request.cwd, parsedAction.input.path)
34411
+ ]),
34412
+ phase: worldModel.phase === "survey" ? "plan-edit" : worldModel.phase,
34413
+ nextFocus: worldModel.phase === "survey" ? "Use the inspected files to make the concrete implementation change." : worldModel.nextFocus,
34414
+ lastUpdatedAt: (/* @__PURE__ */ new Date()).toISOString()
34415
+ };
34416
+ }
33863
34417
  if (verificationAction) {
33864
34418
  verifiedAfterLatestChange = result.success;
34419
+ const attemptedCommand = shellCommand || (parsedAction.tool === "tests.run" ? "tests.run" : "");
34420
+ const proofUpdate = updateProofStateForVerification(worldModel, attemptedCommand || void 0, result.success);
34421
+ const verifier = {
34422
+ ...worldModel.verifier,
34423
+ attemptedCommands: attemptedCommand ? uniqueStrings2([
34424
+ ...worldModel.verifier.attemptedCommands,
34425
+ attemptedCommand
34426
+ ]) : worldModel.verifier.attemptedCommands,
34427
+ currentCommand: attemptedCommand || worldModel.verifier.currentCommand,
34428
+ latestFailureSummary: result.success ? void 0 : result.summary,
34429
+ latestFailureCommand: result.success ? void 0 : attemptedCommand || void 0,
34430
+ latestSuccessfulCommand: result.success ? attemptedCommand || worldModel.verifier.latestSuccessfulCommand : worldModel.verifier.latestSuccessfulCommand,
34431
+ successfulCommands: result.success && attemptedCommand ? uniqueStrings2([
34432
+ ...worldModel.verifier.successfulCommands,
34433
+ attemptedCommand
34434
+ ]) : worldModel.verifier.successfulCommands,
34435
+ disabledCommands: interactiveVerificationSetupFailure && attemptedCommand ? uniqueStrings2([
34436
+ ...worldModel.verifier.disabledCommands,
34437
+ attemptedCommand
34438
+ ]) : worldModel.verifier.disabledCommands,
34439
+ requiresInteractiveSetup: interactiveVerificationSetupFailure
34440
+ };
34441
+ worldModel = {
34442
+ ...worldModel,
34443
+ verifier,
34444
+ lastUpdatedAt: (/* @__PURE__ */ new Date()).toISOString()
34445
+ };
33865
34446
  if (result.success) {
33866
34447
  verificationFailures = 0;
33867
34448
  repairRequiredBeforeVerification = false;
33868
34449
  repairAppliedSinceFailure = false;
33869
34450
  lastVerificationFailure = null;
34451
+ worldModel = {
34452
+ ...worldModel,
34453
+ phase: "finalize",
34454
+ validationLoopCount: 0,
34455
+ proofPending: proofUpdate.proofPending,
34456
+ proofSatisfied: proofUpdate.proofSatisfied,
34457
+ nextFocus: "Review the diff and finish if the task acceptance criteria are satisfied.",
34458
+ blockers: [],
34459
+ lastUpdatedAt: (/* @__PURE__ */ new Date()).toISOString()
34460
+ };
33870
34461
  } else if (interactiveVerificationSetupFailure) {
33871
34462
  repairRequiredBeforeVerification = false;
33872
34463
  repairAppliedSinceFailure = false;
33873
34464
  lastVerificationFailure = result;
34465
+ worldModel = {
34466
+ ...worldModel,
34467
+ phase: appliedSourceEdit ? "verify" : "implement",
34468
+ blockers: uniqueStrings2([
34469
+ ...worldModel.blockers.filter((blocker) => !blocker.includes("interactive")),
34470
+ result.summary
34471
+ ]),
34472
+ nextFocus: "Choose a different non-interactive verifier or configure the verifier only if the task truly requires it.",
34473
+ lastUpdatedAt: (/* @__PURE__ */ new Date()).toISOString()
34474
+ };
33874
34475
  } else {
33875
34476
  verificationFailures += 1;
33876
34477
  repairRequiredBeforeVerification = true;
33877
34478
  repairAppliedSinceFailure = false;
33878
34479
  lastVerificationFailure = result;
34480
+ worldModel = {
34481
+ ...worldModel,
34482
+ phase: "repair",
34483
+ blockers: uniqueStrings2([
34484
+ ...worldModel.blockers,
34485
+ result.summary
34486
+ ]),
34487
+ nextFocus: "Repair the latest failing verifier output before running verification again.",
34488
+ lastUpdatedAt: (/* @__PURE__ */ new Date()).toISOString()
34489
+ };
33879
34490
  }
33880
34491
  }
33881
34492
  transcriptEntry.toolResult = result;
@@ -33936,21 +34547,21 @@ ${truncateForModel(customAgentMemory)}`);
33936
34547
  const transcriptPath2 = await writeTranscriptArtifact(request.cwd, sessionId, task.id, transcript);
33937
34548
  artifacts.add(transcriptPath2);
33938
34549
  if (task.agentRole !== "test-debugger") {
33939
- return {
33940
- status: "handoff",
33941
- summary: `Verification failed ${verificationFailures} time${verificationFailures === 1 ? "" : "s"} for ${task.id}; handing off to test-debugger.`,
33942
- toolResults,
33943
- artifacts: Array.from(artifacts),
33944
- usage: usageTotals
34550
+ worldModel = {
34551
+ ...worldModel,
34552
+ phase: "escalate",
34553
+ nextFocus: "Escalate to test-debugger with the latest failing verifier context.",
34554
+ lastUpdatedAt: (/* @__PURE__ */ new Date()).toISOString()
33945
34555
  };
34556
+ return makeOutcome("handoff", `Verification failed ${verificationFailures} time${verificationFailures === 1 ? "" : "s"} for ${task.id}; handing off to test-debugger.`);
33946
34557
  }
33947
- return {
33948
- status: "blocked",
33949
- summary: `Verification failed ${verificationFailures} time${verificationFailures === 1 ? "" : "s"} for ${task.id}; repair budget exhausted.`,
33950
- toolResults,
33951
- artifacts: Array.from(artifacts),
33952
- usage: usageTotals
34558
+ worldModel = {
34559
+ ...worldModel,
34560
+ phase: "escalate",
34561
+ nextFocus: "Debugger repair budget is exhausted; supervisor must replan or accept the blocker.",
34562
+ lastUpdatedAt: (/* @__PURE__ */ new Date()).toISOString()
33953
34563
  };
34564
+ return makeOutcome("blocked", `Verification failed ${verificationFailures} time${verificationFailures === 1 ? "" : "s"} for ${task.id}; repair budget exhausted.`);
33954
34565
  }
33955
34566
  }
33956
34567
  messages.push({
@@ -33994,14 +34605,9 @@ ${truncateForModel(customAgentMemory)}`);
33994
34605
  if (execution.approvalRequest) {
33995
34606
  const transcriptPath2 = await writeTranscriptArtifact(request.cwd, sessionId, task.id, transcript.concat(transcriptEntry));
33996
34607
  artifacts.add(transcriptPath2);
33997
- return {
33998
- status: "awaiting-approval",
33999
- summary: execution.approvalRequest.reason,
34000
- toolResults,
34001
- artifacts: Array.from(artifacts),
34002
- approvalRequest: execution.approvalRequest,
34003
- usage: usageTotals
34004
- };
34608
+ return makeOutcome("awaiting-approval", execution.approvalRequest.reason, {
34609
+ approvalRequest: execution.approvalRequest
34610
+ });
34005
34611
  }
34006
34612
  if (!execution.result) {
34007
34613
  throw new Error("Approved action did not produce a tool result.");
@@ -34018,13 +34624,12 @@ ${truncateForModel(customAgentMemory)}`);
34018
34624
  } catch (error2) {
34019
34625
  const transcriptPath2 = await writeTranscriptArtifact(request.cwd, sessionId, task.id, transcript);
34020
34626
  artifacts.add(transcriptPath2);
34021
- return {
34022
- status: "paused",
34023
- summary: `Execution interrupted by operator during ${task.id}.`,
34024
- toolResults,
34025
- artifacts: Array.from(artifacts),
34026
- usage: usageTotals
34627
+ worldModel = {
34628
+ ...worldModel,
34629
+ nextFocus: "Resume from the current execution state without redoing completed inspection or verification.",
34630
+ lastUpdatedAt: (/* @__PURE__ */ new Date()).toISOString()
34027
34631
  };
34632
+ return makeOutcome("paused", `Execution interrupted by operator during ${task.id}.`);
34028
34633
  }
34029
34634
  await compactExecutionContextIfNeeded(step);
34030
34635
  if (typeof maxModelCalls === "number" && usageTotals.modelCalls >= maxModelCalls) {
@@ -34047,7 +34652,7 @@ ${truncateForModel(customAgentMemory)}`);
34047
34652
  try {
34048
34653
  response = await brain.client.generateText({
34049
34654
  model: brain.model,
34050
- systemPrompt: buildSystemPrompt(effectiveAgent, task, request, allowedTools, options.plan, task.agentPromptPreamble ?? customOverlay?.promptPreamble),
34655
+ systemPrompt: buildSystemPrompt(effectiveAgent, task, request, allowedTools, snapshotWorldModel(), options.plan, task.agentPromptPreamble ?? customOverlay?.promptPreamble),
34051
34656
  messages,
34052
34657
  responseFormat: "json_object",
34053
34658
  ...typeof brain.settings.temperature === "number" ? {
@@ -34065,24 +34670,27 @@ ${truncateForModel(customAgentMemory)}`);
34065
34670
  });
34066
34671
  const transcriptPath2 = await writeTranscriptArtifact(request.cwd, sessionId, task.id, transcript);
34067
34672
  artifacts.add(transcriptPath2);
34068
- return {
34069
- status: "blocked",
34070
- summary: `Model request failed before ${task.id} could choose a safe action: ${error2 instanceof Error ? error2.message : String(error2)}`,
34071
- toolResults,
34072
- artifacts: Array.from(artifacts),
34073
- usage: usageTotals
34673
+ worldModel = {
34674
+ ...worldModel,
34675
+ phase: "escalate",
34676
+ blockers: uniqueStrings2([
34677
+ ...worldModel.blockers,
34678
+ error2 instanceof Error ? error2.message : String(error2)
34679
+ ]),
34680
+ nextFocus: "Supervisor should inspect the model failure or switch to a healthier provider/model.",
34681
+ lastUpdatedAt: (/* @__PURE__ */ new Date()).toISOString()
34074
34682
  };
34683
+ return makeOutcome("blocked", `Model request failed before ${task.id} could choose a safe action: ${error2 instanceof Error ? error2.message : String(error2)}`);
34075
34684
  }
34076
34685
  if (options.signal?.aborted) {
34077
34686
  const transcriptPath2 = await writeTranscriptArtifact(request.cwd, sessionId, task.id, transcript);
34078
34687
  artifacts.add(transcriptPath2);
34079
- return {
34080
- status: "paused",
34081
- summary: `Execution interrupted by operator during ${task.id}.`,
34082
- toolResults,
34083
- artifacts: Array.from(artifacts),
34084
- usage: usageTotals
34688
+ worldModel = {
34689
+ ...worldModel,
34690
+ nextFocus: "Resume from the current execution state without redoing completed inspection or verification.",
34691
+ lastUpdatedAt: (/* @__PURE__ */ new Date()).toISOString()
34085
34692
  };
34693
+ return makeOutcome("paused", `Execution interrupted by operator during ${task.id}.`);
34086
34694
  }
34087
34695
  responseText = response.text;
34088
34696
  usageTotals.modelCalls += 1;
@@ -34145,13 +34753,17 @@ ${truncateForModel(customAgentMemory)}`);
34145
34753
  step,
34146
34754
  message: "Model stayed out of structured mode after multiple retries."
34147
34755
  });
34148
- return {
34149
- status: "blocked",
34150
- summary: `${parseSummary} The task stopped before a safe tool action could be chosen.`,
34151
- toolResults,
34152
- artifacts: Array.from(artifacts),
34153
- usage: usageTotals
34756
+ worldModel = {
34757
+ ...worldModel,
34758
+ phase: "escalate",
34759
+ blockers: uniqueStrings2([
34760
+ ...worldModel.blockers,
34761
+ parseSummary
34762
+ ]),
34763
+ nextFocus: "Supervisor should inspect the unstructured model output and replan or switch models.",
34764
+ lastUpdatedAt: (/* @__PURE__ */ new Date()).toISOString()
34154
34765
  };
34766
+ return makeOutcome("blocked", `${parseSummary} The task stopped before a safe tool action could be chosen.`);
34155
34767
  }
34156
34768
  await emitProgress({
34157
34769
  type: "task-note",
@@ -34185,10 +34797,53 @@ ${truncateForModel(customAgentMemory)}`);
34185
34797
  response: responseText,
34186
34798
  parsedAction
34187
34799
  };
34800
+ const strategicVerifier = determineNextVerificationCommand(worldModel);
34188
34801
  messages.push({
34189
34802
  role: "assistant",
34190
34803
  content: JSON.stringify(parsedAction)
34191
34804
  });
34805
+ if (worldModel.phase === "survey" && parsedAction.type === "tool" && !isRepoInspectionAction(parsedAction)) {
34806
+ transcriptEntry.runtimeNote = "Rejected phase-inconsistent action because survey phase still requires repo inspection.";
34807
+ transcript.push(transcriptEntry);
34808
+ await emitProgress({
34809
+ type: "task-note",
34810
+ sessionId,
34811
+ taskId: task.id,
34812
+ agentRole: task.agentRole,
34813
+ step,
34814
+ message: "Survey phase requires file/repo inspection before implementation or verification."
34815
+ });
34816
+ messages.push({
34817
+ role: "user",
34818
+ content: [
34819
+ "The current execution phase is survey.",
34820
+ "Inspect likely source files and repository context first with file.read, file.search, file.list, repo.index, repo.query, or git.diff.",
34821
+ "Do not jump to runtime validation or edits before you understand the target files."
34822
+ ].join("\n")
34823
+ });
34824
+ continue;
34825
+ }
34826
+ if (worldModel.phase === "verify" && parsedAction.type === "tool" && !isVerificationAction(parsedAction) && !isRepoInspectionAction(parsedAction)) {
34827
+ transcriptEntry.runtimeNote = "Rejected phase-inconsistent action because verify phase requires proof or diff review.";
34828
+ transcript.push(transcriptEntry);
34829
+ await emitProgress({
34830
+ type: "task-note",
34831
+ sessionId,
34832
+ taskId: task.id,
34833
+ agentRole: task.agentRole,
34834
+ step,
34835
+ message: strategicVerifier ? `Verify phase requires proof. Run ${strategicVerifier} or inspect the diff.` : "Verify phase requires proof. Use a non-interactive verifier or inspect the diff."
34836
+ });
34837
+ messages.push({
34838
+ role: "user",
34839
+ content: [
34840
+ "The current execution phase is verify.",
34841
+ strategicVerifier ? `Run the strategic verifier next: ${strategicVerifier}.` : "Run the best non-interactive verifier next.",
34842
+ "Only use diff/inspection actions here if you still need proof context before finishing."
34843
+ ].join("\n")
34844
+ });
34845
+ continue;
34846
+ }
34192
34847
  if (parsedAction.type === "finish") {
34193
34848
  if (changedWorkspace && !verifiedAfterLatestChange) {
34194
34849
  transcriptEntry.runtimeNote = "Finish rejected because code changed without a successful verification step.";
@@ -34205,31 +34860,77 @@ ${truncateForModel(customAgentMemory)}`);
34205
34860
  role: "user",
34206
34861
  content: [
34207
34862
  "You tried to finish after making code changes without a successful verification step.",
34208
- "Run tests.run or a build/lint/test shell command, inspect failures, and only finish after verification passes."
34863
+ strategicVerifier ? `Run the strategic verifier next: ${strategicVerifier}.` : "Run tests.run or a build/lint/test shell command, inspect failures, and only finish after verification passes."
34864
+ ].join("\n")
34865
+ });
34866
+ continue;
34867
+ }
34868
+ if (worldModel.phase !== "finalize") {
34869
+ transcriptEntry.runtimeNote = `Finish rejected because the task is still in ${worldModel.phase} phase.`;
34870
+ transcript.push(transcriptEntry);
34871
+ await emitProgress({
34872
+ type: "task-note",
34873
+ sessionId,
34874
+ taskId: task.id,
34875
+ agentRole: task.agentRole,
34876
+ step,
34877
+ message: `Finish rejected because the task is still in ${worldModel.phase} phase.`
34878
+ });
34879
+ messages.push({
34880
+ role: "user",
34881
+ content: [
34882
+ `The task is still in ${worldModel.phase} phase.`,
34883
+ ...derivePhaseGuidance(worldModel),
34884
+ "Do the next strategic action instead of finishing early."
34885
+ ].join("\n")
34886
+ });
34887
+ continue;
34888
+ }
34889
+ if (worldModel.proofPending.length > 0 && worldModel.proofSatisfied.length === 0) {
34890
+ transcriptEntry.runtimeNote = "Finish rejected because the task still has pending proof and no satisfied verifier evidence.";
34891
+ transcript.push(transcriptEntry);
34892
+ await emitProgress({
34893
+ type: "task-note",
34894
+ sessionId,
34895
+ taskId: task.id,
34896
+ agentRole: task.agentRole,
34897
+ step,
34898
+ message: "Finish rejected because the task still has pending proof requirements."
34899
+ });
34900
+ messages.push({
34901
+ role: "user",
34902
+ content: [
34903
+ "You still owe proof for this task before finishing.",
34904
+ `Pending proof: ${worldModel.proofPending.join(" | ")}`,
34905
+ strategicVerifier ? `Run the strategic verifier next: ${strategicVerifier}.` : "Run the best non-interactive verifier, then finish only after the proof is captured."
34209
34906
  ].join("\n")
34210
34907
  });
34211
34908
  continue;
34212
34909
  }
34213
34910
  const transcriptPath2 = await writeTranscriptArtifact(request.cwd, sessionId, task.id, transcript.concat(transcriptEntry));
34214
34911
  artifacts.add(transcriptPath2);
34215
- return {
34216
- status: "completed",
34217
- summary: parsedAction.summary,
34218
- toolResults,
34219
- artifacts: Array.from(artifacts),
34220
- usage: usageTotals
34912
+ worldModel = {
34913
+ ...worldModel,
34914
+ phase: "finalize",
34915
+ nextFocus: "Task completed.",
34916
+ lastUpdatedAt: (/* @__PURE__ */ new Date()).toISOString()
34221
34917
  };
34918
+ return makeOutcome("completed", parsedAction.summary);
34222
34919
  }
34223
34920
  if (parsedAction.type === "block") {
34224
34921
  const transcriptPath2 = await writeTranscriptArtifact(request.cwd, sessionId, task.id, transcript.concat(transcriptEntry));
34225
34922
  artifacts.add(transcriptPath2);
34226
- return {
34227
- status: "blocked",
34228
- summary: parsedAction.reason,
34229
- toolResults,
34230
- artifacts: Array.from(artifacts),
34231
- usage: usageTotals
34923
+ worldModel = {
34924
+ ...worldModel,
34925
+ phase: "escalate",
34926
+ blockers: uniqueStrings2([
34927
+ ...worldModel.blockers,
34928
+ parsedAction.reason
34929
+ ]),
34930
+ nextFocus: "Supervisor should inspect the reported blocker and adjust the task graph.",
34931
+ lastUpdatedAt: (/* @__PURE__ */ new Date()).toISOString()
34232
34932
  };
34933
+ return makeOutcome("blocked", parsedAction.reason);
34233
34934
  }
34234
34935
  if (!allowedTools.includes(parsedAction.tool)) {
34235
34936
  transcriptEntry.runtimeNote = `Rejected disallowed tool "${parsedAction.tool}" for ${agent.role}.`;
@@ -34274,6 +34975,67 @@ ${truncateForModel(customAgentMemory)}`);
34274
34975
  });
34275
34976
  continue;
34276
34977
  }
34978
+ if (isVerificationAction(parsedAction) && strategicVerifier && extractShellCommand(parsedAction) && extractShellCommand(parsedAction) !== strategicVerifier) {
34979
+ transcriptEntry.runtimeNote = "Verification command rejected because it does not match the current strategic verifier.";
34980
+ transcript.push(transcriptEntry);
34981
+ await emitProgress({
34982
+ type: "task-note",
34983
+ sessionId,
34984
+ taskId: task.id,
34985
+ agentRole: task.agentRole,
34986
+ step,
34987
+ message: `Verification should follow the strategic order. Prefer ${strategicVerifier} next.`
34988
+ });
34989
+ messages.push({
34990
+ role: "user",
34991
+ content: [
34992
+ "Use the strategic verification path instead of picking a random verifier.",
34993
+ `Preferred next verifier: ${strategicVerifier}`
34994
+ ].join("\n")
34995
+ });
34996
+ continue;
34997
+ }
34998
+ if (allowedTools.includes("file.read") && isShellFileInspectionAction(parsedAction)) {
34999
+ transcriptEntry.runtimeNote = "Rejected shell-based file inspection because file.read is available.";
35000
+ transcript.push(transcriptEntry);
35001
+ await emitProgress({
35002
+ type: "task-note",
35003
+ sessionId,
35004
+ taskId: task.id,
35005
+ agentRole: task.agentRole,
35006
+ step,
35007
+ message: "Use file.read or repo/file tools instead of cat/head/wc/sed shell commands for source inspection."
35008
+ });
35009
+ messages.push({
35010
+ role: "user",
35011
+ content: [
35012
+ "Do not use shell.exec for simple repo file inspection when file.read is available.",
35013
+ "Use file.read, file.search, file.list, repo.query, or git.diff instead."
35014
+ ].join("\n")
35015
+ });
35016
+ continue;
35017
+ }
35018
+ if (request.workspaceState === "existing" && (task.type === "scaffold" || task.type === "implementation") && !appliedSourceEdit && isRuntimeValidationAction(parsedAction) && preEditValidationActions >= 1) {
35019
+ transcriptEntry.runtimeNote = "Rejected repeated validation/runtime loop before any source edit.";
35020
+ transcript.push(transcriptEntry);
35021
+ await emitProgress({
35022
+ type: "task-note",
35023
+ sessionId,
35024
+ taskId: task.id,
35025
+ agentRole: task.agentRole,
35026
+ step,
35027
+ message: "Repeated build/dev/browser verification was stopped because no source edit has landed yet."
35028
+ });
35029
+ messages.push({
35030
+ role: "user",
35031
+ content: [
35032
+ "You already used one baseline verification/runtime check before making a source edit.",
35033
+ "Do not keep rerunning build, lint, dev server, browser, or HTTP checks unchanged.",
35034
+ "Inspect likely source files, make a concrete edit with file.patch or file.write, and then validate again."
35035
+ ].join("\n")
35036
+ });
35037
+ continue;
35038
+ }
34277
35039
  const execution = await runToolAction(parsedAction, step);
34278
35040
  if (execution.budgetExceeded) {
34279
35041
  transcriptEntry.runtimeNote = execution.budgetExceeded;
@@ -34284,14 +35046,9 @@ ${truncateForModel(customAgentMemory)}`);
34284
35046
  transcriptEntry.runtimeNote = execution.approvalRequest.reason;
34285
35047
  const transcriptPath2 = await writeTranscriptArtifact(request.cwd, sessionId, task.id, transcript.concat(transcriptEntry));
34286
35048
  artifacts.add(transcriptPath2);
34287
- return {
34288
- status: "awaiting-approval",
34289
- summary: execution.approvalRequest.reason,
34290
- toolResults,
34291
- artifacts: Array.from(artifacts),
34292
- approvalRequest: execution.approvalRequest,
34293
- usage: usageTotals
34294
- };
35049
+ return makeOutcome("awaiting-approval", execution.approvalRequest.reason, {
35050
+ approvalRequest: execution.approvalRequest
35051
+ });
34295
35052
  }
34296
35053
  if (!execution.result) {
34297
35054
  throw new Error(`Tool ${parsedAction.tool} did not return a result.`);
@@ -34311,21 +35068,21 @@ ${truncateForModel(customAgentMemory)}`);
34311
35068
  message: task.agentRole !== "test-debugger" ? `Step budget exhausted after ${maxSteps} steps; handing task to test-debugger.` : `Step budget exhausted after ${maxSteps} steps; debugger escalation exhausted.`
34312
35069
  });
34313
35070
  if (task.agentRole !== "test-debugger") {
34314
- return {
34315
- status: "handoff",
34316
- summary: `Autonomous executor reached the step limit (${maxSteps}) for ${task.id}; handing off to test-debugger.`,
34317
- toolResults,
34318
- artifacts: Array.from(artifacts),
34319
- usage: usageTotals
35071
+ worldModel = {
35072
+ ...worldModel,
35073
+ phase: "escalate",
35074
+ nextFocus: "Hand off the task to test-debugger with the current world-model and transcript.",
35075
+ lastUpdatedAt: (/* @__PURE__ */ new Date()).toISOString()
34320
35076
  };
35077
+ return makeOutcome("handoff", `Autonomous executor reached the step limit (${maxSteps}) for ${task.id}; handing off to test-debugger.`);
34321
35078
  }
34322
- return {
34323
- status: "blocked",
34324
- summary: `Autonomous executor reached the step limit (${maxSteps}) for ${task.id}; debugger escalation exhausted.`,
34325
- toolResults,
34326
- artifacts: Array.from(artifacts),
34327
- usage: usageTotals
35079
+ worldModel = {
35080
+ ...worldModel,
35081
+ phase: "escalate",
35082
+ nextFocus: "Debugger escalation is exhausted; supervisor must replan or accept the blocker.",
35083
+ lastUpdatedAt: (/* @__PURE__ */ new Date()).toISOString()
34328
35084
  };
35085
+ return makeOutcome("blocked", `Autonomous executor reached the step limit (${maxSteps}) for ${task.id}; debugger escalation exhausted.`);
34329
35086
  }
34330
35087
  };
34331
35088
 
@@ -35036,6 +35793,26 @@ function buildSummary(shape, goal) {
35036
35793
  }
35037
35794
  return `Deliver "${goal}" through structured analysis, implementation, and verification milestones.`;
35038
35795
  }
35796
+ function buildPlanningSeedSummary(goal) {
35797
+ return `Create the best executable task graph for "${goal}" with dynamically chosen milestones, task count, and verification.`;
35798
+ }
35799
+ function planningSeedMilestone() {
35800
+ return {
35801
+ id: "m1-planning-seed",
35802
+ title: "Planning Seed",
35803
+ objective: "Schema-valid placeholder context for the planner model. Replace this seed with a real executable plan.",
35804
+ tasks: [
35805
+ buildTask("seed-plan-task", "Replace this planning seed with the real task graph", "This placeholder exists only so the planner model receives a schema-valid example. The final plan should replace it with concrete milestones and executable tasks tailored to the goal.", "planner", "documentation", [], [
35806
+ "The final plan removes the placeholder task.",
35807
+ "The final plan contains executable tasks with explicit dependencies and verification."
35808
+ ], [
35809
+ "Executable task graph"
35810
+ ], [
35811
+ "."
35812
+ ], "low")
35813
+ ]
35814
+ };
35815
+ }
35039
35816
  function createPlan(input) {
35040
35817
  const request = PlanRequestSchema.parse({
35041
35818
  ...input,
@@ -35065,6 +35842,33 @@ function createPlan(input) {
35065
35842
  ]
35066
35843
  });
35067
35844
  }
35845
+ function createPlanningSeed(input) {
35846
+ const request = PlanRequestSchema.parse({
35847
+ ...input,
35848
+ goal: normalizeGoal(input.goal)
35849
+ });
35850
+ const shape = inferProjectShape(request.goal);
35851
+ return KimbhoPlanSchema.parse({
35852
+ goal: request.goal,
35853
+ generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
35854
+ summary: buildPlanningSeedSummary(request.goal),
35855
+ repoStrategy: {
35856
+ mode: request.workspaceState === "empty" ? "greenfield" : "existing-repo",
35857
+ reasoning: request.workspaceState === "empty" ? "No meaningful workspace contents were detected, so the planner can choose an opinionated greenfield graph." : "Existing workspace state should be analyzed and preserved while the planner chooses the execution graph."
35858
+ },
35859
+ assumptions: deriveAssumptions(shape, request),
35860
+ openQuestions: deriveOpenQuestions(shape),
35861
+ milestones: [
35862
+ planningSeedMilestone()
35863
+ ],
35864
+ verificationChecklist: deriveVerificationChecklist(shape),
35865
+ executionNotes: [
35866
+ "Replace the placeholder seed milestone with the real execution graph.",
35867
+ "Choose milestone count, task count, and dependencies dynamically from the goal.",
35868
+ "Keep deterministic fallback available only if model planning fails."
35869
+ ]
35870
+ });
35871
+ }
35068
35872
 
35069
35873
  // ../planner/dist/model-planner.js
35070
35874
  var DEFAULT_PLANNER_TEMPERATURE = 0.1;
@@ -35148,8 +35952,8 @@ function buildPlannerSystemPrompt() {
35148
35952
  "You are Kimbho's planner brain.",
35149
35953
  "Return one JSON object only. Do not use markdown fences or prose outside the JSON.",
35150
35954
  "The JSON must satisfy the KimbhoPlan schema used by Kimbho's runtime.",
35151
- "Prefer refining the provided seed plan instead of inventing a totally different graph.",
35152
- "Keep task ids stable and machine-friendly.",
35955
+ "For initial planning, choose the milestone count, task count, and task graph shape that best fits the request instead of mirroring the fallback plan.",
35956
+ "Keep task ids machine-friendly and stable within the returned plan.",
35153
35957
  "Use only these agent roles:",
35154
35958
  "- session-orchestrator",
35155
35959
  "- repo-analyst",
@@ -35180,8 +35984,9 @@ ${request.constraints.map((constraint) => `- ${constraint}`).join("\n")}` : "",
35180
35984
  "Seed plan JSON:",
35181
35985
  JSON.stringify(seedPlan, null, 2),
35182
35986
  "Instructions:",
35183
- "- Refine the seed plan into the best executable plan for this goal.",
35184
- "- Preserve the seed task ids unless there is a compelling execution reason not to.",
35987
+ "- Use the seed plan only as a fallback reference, not as a task-count template.",
35988
+ "- Produce the best executable plan for this goal, choosing milestone count and task count dynamically.",
35989
+ "- You may replace the seed task ids for the initial plan if a different graph is materially better.",
35185
35990
  "- Keep the plan concise, practical, and tool-executable."
35186
35991
  ].filter(Boolean).join("\n\n");
35187
35992
  }
@@ -35205,7 +36010,7 @@ ${request.constraints.map((constraint) => `- ${constraint}`).join("\n")}` : "",
35205
36010
  "- Adjust milestone wording, task descriptions, acceptance criteria, files, and dependencies only when the repo evidence justifies it."
35206
36011
  ].filter(Boolean).join("\n\n");
35207
36012
  }
35208
- async function generatePlannerPlan(request, seedPlan, invocation, userPrompt, preserveStatusesFrom) {
36013
+ async function generatePlannerPlan(request, seedPlan, fallbackPlan, invocation, userPrompt, preserveStatusesFrom, requireStableTaskIds = true) {
35209
36014
  try {
35210
36015
  const response = await invocation.generate({
35211
36016
  systemPrompt: buildPlannerSystemPrompt(),
@@ -35215,7 +36020,7 @@ async function generatePlannerPlan(request, seedPlan, invocation, userPrompt, pr
35215
36020
  });
35216
36021
  const parsed = extractJsonObjectish(response.text, "planner response");
35217
36022
  const candidatePlan = KimbhoPlanSchema.parse(parsed);
35218
- const normalized = normalizeCandidatePlan(request, seedPlan, candidatePlan, true, preserveStatusesFrom);
36023
+ const normalized = normalizeCandidatePlan(request, fallbackPlan, candidatePlan, requireStableTaskIds, preserveStatusesFrom);
35219
36024
  return {
35220
36025
  plan: normalized,
35221
36026
  source: "model",
@@ -35229,7 +36034,7 @@ async function generatePlannerPlan(request, seedPlan, invocation, userPrompt, pr
35229
36034
  };
35230
36035
  } catch (error2) {
35231
36036
  return {
35232
- plan: preserveStatusesFrom ? preserveTaskStatuses(preserveStatusesFrom, seedPlan) : seedPlan,
36037
+ plan: preserveStatusesFrom ? preserveTaskStatuses(preserveStatusesFrom, fallbackPlan) : fallbackPlan,
35233
36038
  source: "fallback",
35234
36039
  warning: summarizeStructuredOutputError("Planner", error2),
35235
36040
  ...invocation.modelLabel ? {
@@ -35239,18 +36044,19 @@ async function generatePlannerPlan(request, seedPlan, invocation, userPrompt, pr
35239
36044
  }
35240
36045
  }
35241
36046
  async function createPlanWithModel(request, invocation) {
35242
- const seedPlan = createPlan(request);
35243
- return generatePlannerPlan(request, seedPlan, invocation, buildInitialPlannerPrompt(request, seedPlan));
36047
+ const fallbackPlan = createPlan(request);
36048
+ const seedPlan = createPlanningSeed(request);
36049
+ return generatePlannerPlan(request, seedPlan, fallbackPlan, invocation, buildInitialPlannerPrompt(request, seedPlan), void 0, false);
35244
36050
  }
35245
36051
  async function revisePlanWithModel(request, currentPlan, repoSummary, invocation) {
35246
- return generatePlannerPlan(request, currentPlan, invocation, buildReplanPrompt(request, currentPlan, repoSummary), currentPlan);
36052
+ return generatePlannerPlan(request, currentPlan, currentPlan, invocation, buildReplanPrompt(request, currentPlan, repoSummary), currentPlan);
35247
36053
  }
35248
36054
 
35249
36055
  // ../planner/dist/task-expander.js
35250
36056
  var DEFAULT_EXPANDER_TEMPERATURE = 0.1;
35251
36057
  var DEFAULT_EXPANDER_MAX_TOKENS = 1600;
35252
36058
  var MAX_EXPANSION_CONTEXT_CHARS = 6e3;
35253
- var MAX_EXPANDED_SUBTASKS = 4;
36059
+ var MAX_EXPANDED_SUBTASKS = 6;
35254
36060
  var ExpansionCandidateTaskSchema = external_exports.object({
35255
36061
  id: external_exports.string().min(1).optional(),
35256
36062
  title: external_exports.string().min(1),
@@ -35310,7 +36116,7 @@ function createEntrySubtask(task, suffix, title, description) {
35310
36116
  };
35311
36117
  }
35312
36118
  function fallbackExpandedTasks(task) {
35313
- if ((task.swarmDepth ?? 0) >= 1) {
36119
+ if ((task.swarmDepth ?? 0) >= 2) {
35314
36120
  return null;
35315
36121
  }
35316
36122
  if (task.agentRole === "frontend-specialist" && task.type === "implementation") {
@@ -35326,10 +36132,24 @@ function fallbackExpandedTasks(task) {
35326
36132
  ]
35327
36133
  },
35328
36134
  {
35329
- ...createEntrySubtask(task, "polish", `Polish ${task.title.toLowerCase()} visuals and responsiveness`, `Refine styling, responsiveness, and interaction details after the content structure is in place.`),
36135
+ ...createEntrySubtask(task, "interaction", `Design ${task.title.toLowerCase()} interaction and motion`, `Define animation, scroll behavior, and interaction states once the content structure is clear.`),
35330
36136
  dependsOn: [
35331
36137
  `${task.id}-content`
35332
36138
  ],
36139
+ acceptanceCriteria: [
36140
+ "Interaction patterns and motion direction are explicit.",
36141
+ "Primary calls to action and navigation states feel intentional."
36142
+ ],
36143
+ outputs: [
36144
+ "Interaction and motion direction"
36145
+ ]
36146
+ },
36147
+ {
36148
+ ...createEntrySubtask(task, "polish", `Polish ${task.title.toLowerCase()} visuals and responsiveness`, `Refine styling, responsiveness, and interaction details after the content structure is in place.`),
36149
+ dependsOn: [
36150
+ `${task.id}-content`,
36151
+ `${task.id}-interaction`
36152
+ ],
35333
36153
  acceptanceCriteria: [
35334
36154
  ...task.acceptanceCriteria,
35335
36155
  "Responsive behavior and visual polish are verified."
@@ -35532,9 +36352,10 @@ function buildExpansionPrompt(request, plan, task, repoSummary) {
35532
36352
  "Repo context:",
35533
36353
  truncate2(repoSummary),
35534
36354
  "Instructions:",
35535
- "- Replace the target task with 2-4 narrower subtasks.",
36355
+ `- Replace the target task with 2-${MAX_EXPANDED_SUBTASKS} narrower subtasks.`,
35536
36356
  "- Preserve the target task's overall intent, but make execution more parallel-friendly when safe.",
35537
36357
  "- Keep dependencies explicit and machine-valid.",
36358
+ "- Prefer at least 3 subtasks for broad frontend or product-surface work when the task can be split safely.",
35538
36359
  "- Prefer roles like frontend-specialist, backend-specialist, database-specialist, infra-specialist, reviewer, and test-debugger when they fit."
35539
36360
  ].join("\n\n");
35540
36361
  }
@@ -35551,7 +36372,7 @@ ${task.acceptanceCriteria.map((criterion) => `- ${criterion}`).join("\n") || "-
35551
36372
  ].filter(Boolean).join("\n\n");
35552
36373
  }
35553
36374
  function shouldExpandTask(task) {
35554
- if ((task.swarmDepth ?? 0) >= 1) {
36375
+ if ((task.swarmDepth ?? 0) >= 2) {
35555
36376
  return false;
35556
36377
  }
35557
36378
  if (task.type !== "implementation") {
@@ -36625,6 +37446,15 @@ function updateTaskStatus(plan, taskId, status) {
36625
37446
  milestones
36626
37447
  };
36627
37448
  }
37449
+ function updateTaskExecutionState(plan, taskId, executionState) {
37450
+ if (!executionState) {
37451
+ return plan;
37452
+ }
37453
+ return replaceTask(plan, taskId, (task) => ({
37454
+ ...task,
37455
+ executionState
37456
+ }));
37457
+ }
36628
37458
  function replaceTask(plan, taskId, mapper) {
36629
37459
  const milestones = plan.milestones.map((milestone) => ({
36630
37460
  ...milestone,
@@ -36673,9 +37503,6 @@ function shouldDelegateTask(task, request) {
36673
37503
  if (!canSpawnSubagents) {
36674
37504
  return false;
36675
37505
  }
36676
- if ((looksLikeVisualAdjustmentGoal(request.goal) || looksLikePageExpansionGoal(request.goal)) && isStaticSiteTask(task, request)) {
36677
- return false;
36678
- }
36679
37506
  return (task.swarmDepth ?? 0) < maxSubagentDepth && task.type === "implementation" && ![
36680
37507
  "repo-analyst",
36681
37508
  "planner",
@@ -36714,6 +37541,20 @@ function createDefaultDelegationPlan(task, request) {
36714
37541
  "Structured page/content update"
36715
37542
  ]
36716
37543
  },
37544
+ {
37545
+ id: "interaction-designer",
37546
+ label: "interaction-designer",
37547
+ agentRole: "frontend-specialist",
37548
+ description: "Own motion design, interaction states, scroll behavior, and narrative pacing.",
37549
+ instructions: "Focus on animation, interaction states, scroll rhythm, and motion hierarchy. Keep motion purposeful and aligned with the requested design direction.",
37550
+ acceptanceCriteria: [
37551
+ "Interaction patterns and motion choices are explicit.",
37552
+ "The page has a coherent motion system without distracting from the content."
37553
+ ],
37554
+ outputs: [
37555
+ "Interaction and motion design update"
37556
+ ]
37557
+ },
36717
37558
  {
36718
37559
  id: "visual-polisher",
36719
37560
  label: "visual-polisher",
@@ -37048,6 +37889,44 @@ ${result.stderr.slice(0, 1e3)}`);
37048
37889
  return lines.join("\n");
37049
37890
  }).join("\n\n");
37050
37891
  }
37892
+ function renderTaskWorldModelContext(task, outcome) {
37893
+ const worldModel = outcome.worldModel;
37894
+ if (!worldModel) {
37895
+ return [
37896
+ `task: ${task.id}`,
37897
+ `status: ${outcome.status}`,
37898
+ `summary: ${outcome.summary}`
37899
+ ].join("\n");
37900
+ }
37901
+ return [
37902
+ `task: ${task.id}`,
37903
+ `status: ${outcome.status}`,
37904
+ `summary: ${outcome.summary}`,
37905
+ `phase: ${worldModel.phase}`,
37906
+ `next focus: ${worldModel.nextFocus ?? "(unset)"}`,
37907
+ `target files: ${worldModel.targetFiles.join(", ") || "(none)"}`,
37908
+ `inspected files: ${worldModel.inspectedFiles.join(", ") || "(none)"}`,
37909
+ `changed files: ${worldModel.changedFiles.join(", ") || "(none)"}`,
37910
+ `blockers: ${worldModel.blockers.join(" | ") || "(none)"}`,
37911
+ `proof pending: ${worldModel.proofPending.join(" | ") || "(none)"}`,
37912
+ `proof satisfied: ${worldModel.proofSatisfied.join(" | ") || "(none)"}`,
37913
+ `recent actions: ${worldModel.recentActions.join(" | ") || "(none)"}`,
37914
+ `preferred verifiers: ${worldModel.verifier.preferredCommands.join(", ") || "(none)"}`,
37915
+ `latest verifier failure: ${worldModel.verifier.latestFailureSummary ?? "(none)"}`
37916
+ ].join("\n");
37917
+ }
37918
+ function shouldRevisePlanAfterTaskOutcome(task, outcome) {
37919
+ if (task.agentRole === "repo-analyst" || task.agentRole === "planner") {
37920
+ return false;
37921
+ }
37922
+ if (outcome.supervisorHints?.shouldReplan || outcome.supervisorHints?.shouldReprioritize || outcome.supervisorHints?.shouldMergeDelegatedWork) {
37923
+ return true;
37924
+ }
37925
+ if (outcome.status === "blocked" || outcome.status === "handoff") {
37926
+ return true;
37927
+ }
37928
+ return Boolean(task.parentTaskId && outcome.worldModel && (outcome.worldModel.phase === "repair" || outcome.worldModel.phase === "finalize" || outcome.worldModel.blockers.length > 0));
37929
+ }
37051
37930
  function latestRepoAnalysisContext(events) {
37052
37931
  const event = [
37053
37932
  ...events
@@ -37323,8 +38202,8 @@ var ExecutionOrchestrator = class {
37323
38202
  let pendingApprovals = [
37324
38203
  ...session.pendingApprovals
37325
38204
  ];
37326
- const maxAutoTasks = options.maxAutoTasks ?? 2;
37327
- const maxParallelTasks = Math.max(1, options.maxParallelTasks ?? 2);
38205
+ const maxAutoTasks = options.maxAutoTasks ?? 4;
38206
+ const maxParallelTasks = Math.max(1, options.maxParallelTasks ?? 4);
37328
38207
  let executedTasks = 0;
37329
38208
  for (const approval of session.pendingApprovals) {
37330
38209
  const decision = decisionByApprovalId.get(approval.id);
@@ -37485,7 +38364,13 @@ var ExecutionOrchestrator = class {
37485
38364
  let sawApprovalRequest = false;
37486
38365
  for (const batchResult of batchResults) {
37487
38366
  const { task: autoTask, outcome } = batchResult;
37488
- workingPlan = outcome.status === "handoff" ? replaceTask(workingPlan, autoTask.id, () => outcome.handoffTask ?? createDebuggerHandoffTask(autoTask, outcome, this.toolsForAgent("test-debugger").map((tool) => tool.id))) : updateTaskStatus(workingPlan, autoTask.id, outcome.status === "completed" ? "completed" : outcome.status === "blocked" ? "blocked" : "pending");
38367
+ workingPlan = updateTaskExecutionState(workingPlan, autoTask.id, outcome.worldModel);
38368
+ workingPlan = outcome.status === "handoff" ? replaceTask(workingPlan, autoTask.id, () => ({
38369
+ ...outcome.handoffTask ?? createDebuggerHandoffTask(autoTask, outcome, this.toolsForAgent("test-debugger").map((tool) => tool.id)),
38370
+ ...outcome.worldModel ? {
38371
+ executionState: outcome.worldModel
38372
+ } : {}
38373
+ })) : updateTaskStatus(workingPlan, autoTask.id, outcome.status === "completed" ? "completed" : outcome.status === "blocked" ? "blocked" : "pending");
37489
38374
  if (autoTask.agentRole === "repo-analyst" && outcome.status === "completed") {
37490
38375
  const replanned = await this.maybeRevisePlanAfterRepoAnalysis(session.id, session.request, workingPlan, outcome, emitProgress);
37491
38376
  workingPlan = replanned.plan;
@@ -37498,6 +38383,16 @@ var ExecutionOrchestrator = class {
37498
38383
  });
37499
38384
  }
37500
38385
  }
38386
+ const adapted = await this.maybeRevisePlanAfterTaskOutcome(session.id, session.request, workingPlan, autoTask, outcome, emitProgress);
38387
+ workingPlan = adapted.plan;
38388
+ if (adapted.note) {
38389
+ notes = maybeAppendNote(notes, adapted.note);
38390
+ await emitProgress({
38391
+ type: "task-note",
38392
+ sessionId: session.id,
38393
+ message: adapted.note
38394
+ });
38395
+ }
37501
38396
  notes = maybeAppendNote(notes, outcome.summary);
37502
38397
  if (outcome.status === "awaiting-approval" && outcome.approvalRequest) {
37503
38398
  pendingApprovals.push(outcome.approvalRequest);
@@ -37640,7 +38535,8 @@ var ExecutionOrchestrator = class {
37640
38535
  }
37641
38536
  const profile = AGENT_CATALOG[task.agentRole];
37642
38537
  const currentRoleCount = roleCounts.get(task.agentRole) ?? 0;
37643
- if (currentRoleCount >= profile.maxConcurrentTasks) {
38538
+ const effectiveConcurrency = Math.max(profile.maxConcurrentTasks, task.agentRole === "frontend-specialist" || task.agentRole === "backend-specialist" ? 3 : profile.maxConcurrentTasks);
38539
+ if (currentRoleCount >= effectiveConcurrency) {
37644
38540
  continue;
37645
38541
  }
37646
38542
  selected.push(task);
@@ -37660,9 +38556,6 @@ var ExecutionOrchestrator = class {
37660
38556
  if (task.agentRole === "planner") {
37661
38557
  return this.executePlannerTask(sessionId, task, request, plan, emitProgress);
37662
38558
  }
37663
- if (request.workspaceState === "existing" && isStaticSiteTask(task, request) && (task.type === "scaffold" || task.type === "implementation")) {
37664
- return this.executeDeterministicStaticSiteTask(sessionId, task, request, resolvedApproval, options, emitProgress);
37665
- }
37666
38559
  if (request.workspaceState === "existing" && looksLikeStaticLandingGoal(request.goal) && task.type === "verification") {
37667
38560
  return this.executeDeterministicVerificationTask(sessionId, task, request, emitProgress, options.signal);
37668
38561
  }
@@ -38079,6 +38972,12 @@ var ExecutionOrchestrator = class {
38079
38972
  ...outcome.usage ? {
38080
38973
  usage: outcome.usage
38081
38974
  } : {},
38975
+ ...outcome.worldModel ? {
38976
+ worldModel: outcome.worldModel
38977
+ } : {},
38978
+ ...outcome.supervisorHints ? {
38979
+ supervisorHints: outcome.supervisorHints
38980
+ } : {},
38082
38981
  ...integrated.integrationFailed && integrated.conflict && task.agentRole !== "integrator" ? {
38083
38982
  handoffTask: createIntegratorHandoffTask(task, outcome, this.toolsForAgent("integrator").map((tool) => tool.id), integrated.conflict)
38084
38983
  } : {}
@@ -38259,6 +39158,89 @@ var ExecutionOrchestrator = class {
38259
39158
  };
38260
39159
  }
38261
39160
  }
39161
+ async maybeRevisePlanAfterTaskOutcome(sessionId, request, plan, task, outcome, emitProgress) {
39162
+ if (!shouldRevisePlanAfterTaskOutcome(task, outcome)) {
39163
+ return {
39164
+ plan
39165
+ };
39166
+ }
39167
+ const config2 = await loadConfig(request.cwd);
39168
+ if (!config2) {
39169
+ return {
39170
+ plan
39171
+ };
39172
+ }
39173
+ const revisionContext = [
39174
+ "Task outcome context:",
39175
+ renderTaskWorldModelContext(task, outcome),
39176
+ "",
39177
+ "Supervisor hints:",
39178
+ outcome.supervisorHints ? [
39179
+ `- should replan: ${outcome.supervisorHints.shouldReplan ? "yes" : "no"}`,
39180
+ `- should reprioritize: ${outcome.supervisorHints.shouldReprioritize ? "yes" : "no"}`,
39181
+ `- should merge delegated work: ${outcome.supervisorHints.shouldMergeDelegatedWork ? "yes" : "no"}`,
39182
+ `- reason: ${outcome.supervisorHints.reason ?? "(none)"}`
39183
+ ].join("\n") : "- none",
39184
+ "",
39185
+ "Tool evidence:",
39186
+ renderPlannerReplanContext(outcome.toolResults),
39187
+ "",
39188
+ "Planner instructions:",
39189
+ "- Reassign, merge, reorder, or split follow-up tasks if the task outcome suggests the current graph is suboptimal.",
39190
+ "- Preserve completed work, but feel free to adapt pending task order, dependencies, agent roles, or milestone shape.",
39191
+ "- Prefer making parallel work possible when blockers or delegated-worker outcomes reveal an opportunity."
39192
+ ].join("\n");
39193
+ try {
39194
+ const brain = await new BrainResolver(config2, createDefaultBrainProviderRegistry(request.cwd)).resolve("planner");
39195
+ const result = await revisePlanWithModel(request, plan, revisionContext, {
39196
+ modelLabel: `${brain.provider.id}/${brain.model}`,
39197
+ ...typeof brain.settings.temperature === "number" ? {
39198
+ temperature: brain.settings.temperature
39199
+ } : {},
39200
+ ...typeof brain.settings.maxTokens === "number" ? {
39201
+ maxTokens: brain.settings.maxTokens
39202
+ } : {},
39203
+ generate: async (input) => brain.client.generateText({
39204
+ model: brain.model,
39205
+ systemPrompt: [
39206
+ brain.settings.promptPreamble,
39207
+ input.systemPrompt
39208
+ ].filter(Boolean).join("\n\n"),
39209
+ userPrompt: input.userPrompt,
39210
+ responseFormat: "json_object",
39211
+ ...typeof input.temperature === "number" ? {
39212
+ temperature: input.temperature
39213
+ } : {},
39214
+ ...typeof input.maxTokens === "number" ? {
39215
+ maxTokens: input.maxTokens
39216
+ } : {}
39217
+ })
39218
+ });
39219
+ if (result.source === "model") {
39220
+ return {
39221
+ plan: result.plan,
39222
+ note: `Planner brain adapted the active task graph after ${task.id} via ${brain.provider.id}/${brain.model}.`
39223
+ };
39224
+ }
39225
+ return {
39226
+ plan,
39227
+ ...result.warning ? {
39228
+ note: `${result.warning} Keeping the current task graph.`
39229
+ } : {}
39230
+ };
39231
+ } catch (error2) {
39232
+ if (emitProgress) {
39233
+ await emitProgress({
39234
+ type: "task-note",
39235
+ sessionId,
39236
+ message: `Planner task adaptation skipped: ${error2 instanceof Error ? error2.message : String(error2)}`
39237
+ });
39238
+ }
39239
+ return {
39240
+ plan
39241
+ };
39242
+ }
39243
+ }
38262
39244
  async maybeExpandReadyTaskGraph(sessionId, request, plan, events, emitProgress) {
38263
39245
  const envelope = this.buildEnvelope(request, plan, sessionId);
38264
39246
  const candidate = envelope.readyTasks.find((task) => shouldDelegateTask(task, request));
@@ -39693,7 +40675,7 @@ async function executePromptByIntent(cwd, input, options = {}) {
39693
40675
  }
39694
40676
  return executeRunPrompt(cwd, input, options.outputFormat ?? "json", {
39695
40677
  ephemeral: options.ephemeral ?? false,
39696
- maxAutoTasks: options.maxAutoTasks ?? 3,
40678
+ maxAutoTasks: options.maxAutoTasks ?? 4,
39697
40679
  maxAgentSteps: options.maxAgentSteps ?? 8,
39698
40680
  maxRepairAttempts: options.maxRepairAttempts ?? 2,
39699
40681
  ...options.sessionId ? {
@@ -39714,7 +40696,7 @@ function createExecCommand() {
39714
40696
  ], []).option("--image <pathOrUrl>", "Attach an image to the prompt", (value, previous = []) => [
39715
40697
  ...previous,
39716
40698
  value
39717
- ], []).option("--max-auto-tasks <count>", "Maximum ready tasks to auto-execute", parseCount, 3).option("--max-agent-steps <count>", "Maximum tool/model steps per autonomous task", parseCount, 8).option("--max-repair-attempts <count>", "Maximum failed verification cycles per autonomous task", parseCount, 2).action(async (rawPrompt, options) => {
40699
+ ], []).option("--max-auto-tasks <count>", "Maximum ready tasks to auto-execute", parseCount, 4).option("--max-agent-steps <count>", "Maximum tool/model steps per autonomous task", parseCount, 8).option("--max-repair-attempts <count>", "Maximum failed verification cycles per autonomous task", parseCount, 2).action(async (rawPrompt, options) => {
39718
40700
  const cwd = import_node_process5.default.cwd();
39719
40701
  const format = options.json ? "json" : options.outputFormat;
39720
40702
  const agentSelection = await resolveAgentSelection(cwd, {
@@ -42190,7 +43172,7 @@ async function resolveSourceSession(cwd, sessionId, last = false, search) {
42190
43172
  return loadSessionById(sessionId, cwd);
42191
43173
  }
42192
43174
  function createForkCommand() {
42193
- return new Command("fork").description("Fork a saved session into a new session snapshot.").argument("[sessionId]", "Optional session id; defaults to the latest session").option("--last", "Fork the most recent session", false).option("--list", "List recent sessions and exit", false).option("--search <query>", "Filter sessions by id, goal, cwd, or labels").option("--json", "Print the forked snapshot as JSON", false).option("--execute", "Continue auto-executing the forked session", false).option("--max-auto-tasks <count>", "Maximum ready tasks to auto-execute", parseCount3, 3).option("--max-agent-steps <count>", "Maximum tool/model steps per autonomous task", parseCount3, 8).option("--max-repair-attempts <count>", "Maximum failed verification cycles per autonomous task", parseCount3, 2).action(async (sessionId, options) => {
43175
+ return new Command("fork").description("Fork a saved session into a new session snapshot.").argument("[sessionId]", "Optional session id; defaults to the latest session").option("--last", "Fork the most recent session", false).option("--list", "List recent sessions and exit", false).option("--search <query>", "Filter sessions by id, goal, cwd, or labels").option("--json", "Print the forked snapshot as JSON", false).option("--execute", "Continue auto-executing the forked session", false).option("--max-auto-tasks <count>", "Maximum ready tasks to auto-execute", parseCount3, 4).option("--max-agent-steps <count>", "Maximum tool/model steps per autonomous task", parseCount3, 8).option("--max-repair-attempts <count>", "Maximum failed verification cycles per autonomous task", parseCount3, 2).action(async (sessionId, options) => {
42194
43176
  const cwd = import_node_process12.default.cwd();
42195
43177
  if (options.list) {
42196
43178
  const sessions = options.search ? await searchSessions(options.search, cwd) : await listSessions(cwd);
@@ -43360,7 +44342,7 @@ function parseCount4(value) {
43360
44342
  return parsed;
43361
44343
  }
43362
44344
  function createResumeCommand() {
43363
- return new Command("resume").alias("continue").description("Resume the latest saved Kimbho session snapshot.").argument("[sessionId]", "Optional session id; defaults to the latest session").option("--json", "Print the latest session as JSON", false).option("--last", "Resume the most recent session", false).option("--list", "List recent sessions and exit", false).option("--search <query>", "Filter sessions by id, goal, cwd, or labels").option("--execute", "Continue auto-executing the ready-task frontier", false).option("--approve <approvalId>", "Approve a pending action before continuing").option("--deny <approvalId>", "Deny a pending action before continuing").option("--max-auto-tasks <count>", "Maximum ready tasks to auto-execute", parseCount4, 3).option("--max-agent-steps <count>", "Maximum tool/model steps per autonomous task", parseCount4, 8).option("--max-repair-attempts <count>", "Maximum failed verification cycles per autonomous task", parseCount4, 2).action(async (sessionId, options) => {
44345
+ return new Command("resume").alias("continue").description("Resume the latest saved Kimbho session snapshot.").argument("[sessionId]", "Optional session id; defaults to the latest session").option("--json", "Print the latest session as JSON", false).option("--last", "Resume the most recent session", false).option("--list", "List recent sessions and exit", false).option("--search <query>", "Filter sessions by id, goal, cwd, or labels").option("--execute", "Continue auto-executing the ready-task frontier", false).option("--approve <approvalId>", "Approve a pending action before continuing").option("--deny <approvalId>", "Deny a pending action before continuing").option("--max-auto-tasks <count>", "Maximum ready tasks to auto-execute", parseCount4, 4).option("--max-agent-steps <count>", "Maximum tool/model steps per autonomous task", parseCount4, 8).option("--max-repair-attempts <count>", "Maximum failed verification cycles per autonomous task", parseCount4, 2).action(async (sessionId, options) => {
43364
44346
  const cwd = import_node_process23.default.cwd();
43365
44347
  const firstSearchMatch = options.search ? (await searchSessions(options.search, cwd, 1)).at(0) ?? null : null;
43366
44348
  if (options.list) {
@@ -43439,7 +44421,7 @@ function createRunCommand() {
43439
44421
  "Explicit execution constraint; can be provided multiple times",
43440
44422
  (value, previous = []) => [...previous, value],
43441
44423
  []
43442
- ).option("--json", "Print the session snapshot as JSON", false).option("--snapshot-only", "Create the session without auto-executing ready tasks", false).option("--agent <id>", "Prefer one custom or plugin agent id for this session").option("--agents <jsonOrPath>", "Inline agent definitions as JSON or a path to a JSON file").option("--session-id <id>", "Use an explicit session id").option("--ephemeral", "Do not persist plans or sessions for this invocation", false).option("--max-auto-tasks <count>", "Maximum ready tasks to auto-execute", parseCount5, 3).option("--max-agent-steps <count>", "Maximum tool/model steps per autonomous task", parseCount5, 8).option("--max-repair-attempts <count>", "Maximum failed verification cycles per autonomous task", parseCount5, 2).action(async (goal, options) => {
44424
+ ).option("--json", "Print the session snapshot as JSON", false).option("--snapshot-only", "Create the session without auto-executing ready tasks", false).option("--agent <id>", "Prefer one custom or plugin agent id for this session").option("--agents <jsonOrPath>", "Inline agent definitions as JSON or a path to a JSON file").option("--session-id <id>", "Use an explicit session id").option("--ephemeral", "Do not persist plans or sessions for this invocation", false).option("--max-auto-tasks <count>", "Maximum ready tasks to auto-execute", parseCount5, 4).option("--max-agent-steps <count>", "Maximum tool/model steps per autonomous task", parseCount5, 8).option("--max-repair-attempts <count>", "Maximum failed verification cycles per autonomous task", parseCount5, 2).action(async (goal, options) => {
43443
44425
  const cwd = import_node_process24.default.cwd();
43444
44426
  const orchestrator = new ExecutionOrchestrator();
43445
44427
  const agentSelection = await resolveAgentSelection(cwd, {