@kimbho/kimbho-cli 0.1.25 → 0.1.28
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 +219 -59
- package/dist/index.cjs.map +2 -2
- package/package.json +1 -1
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.
|
|
12721
|
+
version: "0.1.28",
|
|
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:
|
|
13083
|
+
maxConcurrentTasks: 3,
|
|
13084
13084
|
policy: {
|
|
13085
13085
|
sandboxMode: "workspace-write",
|
|
13086
13086
|
canSpawnSubagents: true,
|
|
13087
|
-
maxSubagentDepth:
|
|
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:
|
|
13113
|
+
maxConcurrentTasks: 3,
|
|
13114
13114
|
policy: {
|
|
13115
13115
|
sandboxMode: "workspace-write",
|
|
13116
13116
|
canSpawnSubagents: true,
|
|
13117
|
-
maxSubagentDepth:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
13195
|
+
maxSubagentDepth: 2
|
|
13196
13196
|
}
|
|
13197
13197
|
},
|
|
13198
13198
|
"test-debugger": {
|
|
@@ -33341,17 +33341,6 @@ function inferFallbackActionFromResponse(raw, task, request, allowedTools) {
|
|
|
33341
33341
|
};
|
|
33342
33342
|
}
|
|
33343
33343
|
}
|
|
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
33344
|
if (!allowedTools.includes("file.write")) {
|
|
33356
33345
|
return null;
|
|
33357
33346
|
}
|
|
@@ -35036,6 +35025,26 @@ function buildSummary(shape, goal) {
|
|
|
35036
35025
|
}
|
|
35037
35026
|
return `Deliver "${goal}" through structured analysis, implementation, and verification milestones.`;
|
|
35038
35027
|
}
|
|
35028
|
+
function buildPlanningSeedSummary(goal) {
|
|
35029
|
+
return `Create the best executable task graph for "${goal}" with dynamically chosen milestones, task count, and verification.`;
|
|
35030
|
+
}
|
|
35031
|
+
function planningSeedMilestone() {
|
|
35032
|
+
return {
|
|
35033
|
+
id: "m1-planning-seed",
|
|
35034
|
+
title: "Planning Seed",
|
|
35035
|
+
objective: "Schema-valid placeholder context for the planner model. Replace this seed with a real executable plan.",
|
|
35036
|
+
tasks: [
|
|
35037
|
+
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", [], [
|
|
35038
|
+
"The final plan removes the placeholder task.",
|
|
35039
|
+
"The final plan contains executable tasks with explicit dependencies and verification."
|
|
35040
|
+
], [
|
|
35041
|
+
"Executable task graph"
|
|
35042
|
+
], [
|
|
35043
|
+
"."
|
|
35044
|
+
], "low")
|
|
35045
|
+
]
|
|
35046
|
+
};
|
|
35047
|
+
}
|
|
35039
35048
|
function createPlan(input) {
|
|
35040
35049
|
const request = PlanRequestSchema.parse({
|
|
35041
35050
|
...input,
|
|
@@ -35065,6 +35074,33 @@ function createPlan(input) {
|
|
|
35065
35074
|
]
|
|
35066
35075
|
});
|
|
35067
35076
|
}
|
|
35077
|
+
function createPlanningSeed(input) {
|
|
35078
|
+
const request = PlanRequestSchema.parse({
|
|
35079
|
+
...input,
|
|
35080
|
+
goal: normalizeGoal(input.goal)
|
|
35081
|
+
});
|
|
35082
|
+
const shape = inferProjectShape(request.goal);
|
|
35083
|
+
return KimbhoPlanSchema.parse({
|
|
35084
|
+
goal: request.goal,
|
|
35085
|
+
generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
35086
|
+
summary: buildPlanningSeedSummary(request.goal),
|
|
35087
|
+
repoStrategy: {
|
|
35088
|
+
mode: request.workspaceState === "empty" ? "greenfield" : "existing-repo",
|
|
35089
|
+
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."
|
|
35090
|
+
},
|
|
35091
|
+
assumptions: deriveAssumptions(shape, request),
|
|
35092
|
+
openQuestions: deriveOpenQuestions(shape),
|
|
35093
|
+
milestones: [
|
|
35094
|
+
planningSeedMilestone()
|
|
35095
|
+
],
|
|
35096
|
+
verificationChecklist: deriveVerificationChecklist(shape),
|
|
35097
|
+
executionNotes: [
|
|
35098
|
+
"Replace the placeholder seed milestone with the real execution graph.",
|
|
35099
|
+
"Choose milestone count, task count, and dependencies dynamically from the goal.",
|
|
35100
|
+
"Keep deterministic fallback available only if model planning fails."
|
|
35101
|
+
]
|
|
35102
|
+
});
|
|
35103
|
+
}
|
|
35068
35104
|
|
|
35069
35105
|
// ../planner/dist/model-planner.js
|
|
35070
35106
|
var DEFAULT_PLANNER_TEMPERATURE = 0.1;
|
|
@@ -35148,8 +35184,8 @@ function buildPlannerSystemPrompt() {
|
|
|
35148
35184
|
"You are Kimbho's planner brain.",
|
|
35149
35185
|
"Return one JSON object only. Do not use markdown fences or prose outside the JSON.",
|
|
35150
35186
|
"The JSON must satisfy the KimbhoPlan schema used by Kimbho's runtime.",
|
|
35151
|
-
"
|
|
35152
|
-
"Keep task ids
|
|
35187
|
+
"For initial planning, choose the milestone count, task count, and task graph shape that best fits the request instead of mirroring the fallback plan.",
|
|
35188
|
+
"Keep task ids machine-friendly and stable within the returned plan.",
|
|
35153
35189
|
"Use only these agent roles:",
|
|
35154
35190
|
"- session-orchestrator",
|
|
35155
35191
|
"- repo-analyst",
|
|
@@ -35180,8 +35216,9 @@ ${request.constraints.map((constraint) => `- ${constraint}`).join("\n")}` : "",
|
|
|
35180
35216
|
"Seed plan JSON:",
|
|
35181
35217
|
JSON.stringify(seedPlan, null, 2),
|
|
35182
35218
|
"Instructions:",
|
|
35183
|
-
"-
|
|
35184
|
-
"-
|
|
35219
|
+
"- Use the seed plan only as a fallback reference, not as a task-count template.",
|
|
35220
|
+
"- Produce the best executable plan for this goal, choosing milestone count and task count dynamically.",
|
|
35221
|
+
"- You may replace the seed task ids for the initial plan if a different graph is materially better.",
|
|
35185
35222
|
"- Keep the plan concise, practical, and tool-executable."
|
|
35186
35223
|
].filter(Boolean).join("\n\n");
|
|
35187
35224
|
}
|
|
@@ -35205,7 +35242,7 @@ ${request.constraints.map((constraint) => `- ${constraint}`).join("\n")}` : "",
|
|
|
35205
35242
|
"- Adjust milestone wording, task descriptions, acceptance criteria, files, and dependencies only when the repo evidence justifies it."
|
|
35206
35243
|
].filter(Boolean).join("\n\n");
|
|
35207
35244
|
}
|
|
35208
|
-
async function generatePlannerPlan(request, seedPlan, invocation, userPrompt, preserveStatusesFrom) {
|
|
35245
|
+
async function generatePlannerPlan(request, seedPlan, fallbackPlan, invocation, userPrompt, preserveStatusesFrom, requireStableTaskIds = true) {
|
|
35209
35246
|
try {
|
|
35210
35247
|
const response = await invocation.generate({
|
|
35211
35248
|
systemPrompt: buildPlannerSystemPrompt(),
|
|
@@ -35215,7 +35252,7 @@ async function generatePlannerPlan(request, seedPlan, invocation, userPrompt, pr
|
|
|
35215
35252
|
});
|
|
35216
35253
|
const parsed = extractJsonObjectish(response.text, "planner response");
|
|
35217
35254
|
const candidatePlan = KimbhoPlanSchema.parse(parsed);
|
|
35218
|
-
const normalized = normalizeCandidatePlan(request,
|
|
35255
|
+
const normalized = normalizeCandidatePlan(request, fallbackPlan, candidatePlan, requireStableTaskIds, preserveStatusesFrom);
|
|
35219
35256
|
return {
|
|
35220
35257
|
plan: normalized,
|
|
35221
35258
|
source: "model",
|
|
@@ -35229,7 +35266,7 @@ async function generatePlannerPlan(request, seedPlan, invocation, userPrompt, pr
|
|
|
35229
35266
|
};
|
|
35230
35267
|
} catch (error2) {
|
|
35231
35268
|
return {
|
|
35232
|
-
plan: preserveStatusesFrom ? preserveTaskStatuses(preserveStatusesFrom,
|
|
35269
|
+
plan: preserveStatusesFrom ? preserveTaskStatuses(preserveStatusesFrom, fallbackPlan) : fallbackPlan,
|
|
35233
35270
|
source: "fallback",
|
|
35234
35271
|
warning: summarizeStructuredOutputError("Planner", error2),
|
|
35235
35272
|
...invocation.modelLabel ? {
|
|
@@ -35239,18 +35276,19 @@ async function generatePlannerPlan(request, seedPlan, invocation, userPrompt, pr
|
|
|
35239
35276
|
}
|
|
35240
35277
|
}
|
|
35241
35278
|
async function createPlanWithModel(request, invocation) {
|
|
35242
|
-
const
|
|
35243
|
-
|
|
35279
|
+
const fallbackPlan = createPlan(request);
|
|
35280
|
+
const seedPlan = createPlanningSeed(request);
|
|
35281
|
+
return generatePlannerPlan(request, seedPlan, fallbackPlan, invocation, buildInitialPlannerPrompt(request, seedPlan), void 0, false);
|
|
35244
35282
|
}
|
|
35245
35283
|
async function revisePlanWithModel(request, currentPlan, repoSummary, invocation) {
|
|
35246
|
-
return generatePlannerPlan(request, currentPlan, invocation, buildReplanPrompt(request, currentPlan, repoSummary), currentPlan);
|
|
35284
|
+
return generatePlannerPlan(request, currentPlan, currentPlan, invocation, buildReplanPrompt(request, currentPlan, repoSummary), currentPlan);
|
|
35247
35285
|
}
|
|
35248
35286
|
|
|
35249
35287
|
// ../planner/dist/task-expander.js
|
|
35250
35288
|
var DEFAULT_EXPANDER_TEMPERATURE = 0.1;
|
|
35251
35289
|
var DEFAULT_EXPANDER_MAX_TOKENS = 1600;
|
|
35252
35290
|
var MAX_EXPANSION_CONTEXT_CHARS = 6e3;
|
|
35253
|
-
var MAX_EXPANDED_SUBTASKS =
|
|
35291
|
+
var MAX_EXPANDED_SUBTASKS = 6;
|
|
35254
35292
|
var ExpansionCandidateTaskSchema = external_exports.object({
|
|
35255
35293
|
id: external_exports.string().min(1).optional(),
|
|
35256
35294
|
title: external_exports.string().min(1),
|
|
@@ -35310,7 +35348,7 @@ function createEntrySubtask(task, suffix, title, description) {
|
|
|
35310
35348
|
};
|
|
35311
35349
|
}
|
|
35312
35350
|
function fallbackExpandedTasks(task) {
|
|
35313
|
-
if ((task.swarmDepth ?? 0) >=
|
|
35351
|
+
if ((task.swarmDepth ?? 0) >= 2) {
|
|
35314
35352
|
return null;
|
|
35315
35353
|
}
|
|
35316
35354
|
if (task.agentRole === "frontend-specialist" && task.type === "implementation") {
|
|
@@ -35326,10 +35364,24 @@ function fallbackExpandedTasks(task) {
|
|
|
35326
35364
|
]
|
|
35327
35365
|
},
|
|
35328
35366
|
{
|
|
35329
|
-
...createEntrySubtask(task, "
|
|
35367
|
+
...createEntrySubtask(task, "interaction", `Design ${task.title.toLowerCase()} interaction and motion`, `Define animation, scroll behavior, and interaction states once the content structure is clear.`),
|
|
35330
35368
|
dependsOn: [
|
|
35331
35369
|
`${task.id}-content`
|
|
35332
35370
|
],
|
|
35371
|
+
acceptanceCriteria: [
|
|
35372
|
+
"Interaction patterns and motion direction are explicit.",
|
|
35373
|
+
"Primary calls to action and navigation states feel intentional."
|
|
35374
|
+
],
|
|
35375
|
+
outputs: [
|
|
35376
|
+
"Interaction and motion direction"
|
|
35377
|
+
]
|
|
35378
|
+
},
|
|
35379
|
+
{
|
|
35380
|
+
...createEntrySubtask(task, "polish", `Polish ${task.title.toLowerCase()} visuals and responsiveness`, `Refine styling, responsiveness, and interaction details after the content structure is in place.`),
|
|
35381
|
+
dependsOn: [
|
|
35382
|
+
`${task.id}-content`,
|
|
35383
|
+
`${task.id}-interaction`
|
|
35384
|
+
],
|
|
35333
35385
|
acceptanceCriteria: [
|
|
35334
35386
|
...task.acceptanceCriteria,
|
|
35335
35387
|
"Responsive behavior and visual polish are verified."
|
|
@@ -35532,9 +35584,10 @@ function buildExpansionPrompt(request, plan, task, repoSummary) {
|
|
|
35532
35584
|
"Repo context:",
|
|
35533
35585
|
truncate2(repoSummary),
|
|
35534
35586
|
"Instructions:",
|
|
35535
|
-
|
|
35587
|
+
`- Replace the target task with 2-${MAX_EXPANDED_SUBTASKS} narrower subtasks.`,
|
|
35536
35588
|
"- Preserve the target task's overall intent, but make execution more parallel-friendly when safe.",
|
|
35537
35589
|
"- Keep dependencies explicit and machine-valid.",
|
|
35590
|
+
"- Prefer at least 3 subtasks for broad frontend or product-surface work when the task can be split safely.",
|
|
35538
35591
|
"- Prefer roles like frontend-specialist, backend-specialist, database-specialist, infra-specialist, reviewer, and test-debugger when they fit."
|
|
35539
35592
|
].join("\n\n");
|
|
35540
35593
|
}
|
|
@@ -35551,7 +35604,7 @@ ${task.acceptanceCriteria.map((criterion) => `- ${criterion}`).join("\n") || "-
|
|
|
35551
35604
|
].filter(Boolean).join("\n\n");
|
|
35552
35605
|
}
|
|
35553
35606
|
function shouldExpandTask(task) {
|
|
35554
|
-
if ((task.swarmDepth ?? 0) >=
|
|
35607
|
+
if ((task.swarmDepth ?? 0) >= 2) {
|
|
35555
35608
|
return false;
|
|
35556
35609
|
}
|
|
35557
35610
|
if (task.type !== "implementation") {
|
|
@@ -36673,9 +36726,6 @@ function shouldDelegateTask(task, request) {
|
|
|
36673
36726
|
if (!canSpawnSubagents) {
|
|
36674
36727
|
return false;
|
|
36675
36728
|
}
|
|
36676
|
-
if ((looksLikeVisualAdjustmentGoal(request.goal) || looksLikePageExpansionGoal(request.goal)) && isStaticSiteTask(task, request)) {
|
|
36677
|
-
return false;
|
|
36678
|
-
}
|
|
36679
36729
|
return (task.swarmDepth ?? 0) < maxSubagentDepth && task.type === "implementation" && ![
|
|
36680
36730
|
"repo-analyst",
|
|
36681
36731
|
"planner",
|
|
@@ -36714,6 +36764,20 @@ function createDefaultDelegationPlan(task, request) {
|
|
|
36714
36764
|
"Structured page/content update"
|
|
36715
36765
|
]
|
|
36716
36766
|
},
|
|
36767
|
+
{
|
|
36768
|
+
id: "interaction-designer",
|
|
36769
|
+
label: "interaction-designer",
|
|
36770
|
+
agentRole: "frontend-specialist",
|
|
36771
|
+
description: "Own motion design, interaction states, scroll behavior, and narrative pacing.",
|
|
36772
|
+
instructions: "Focus on animation, interaction states, scroll rhythm, and motion hierarchy. Keep motion purposeful and aligned with the requested design direction.",
|
|
36773
|
+
acceptanceCriteria: [
|
|
36774
|
+
"Interaction patterns and motion choices are explicit.",
|
|
36775
|
+
"The page has a coherent motion system without distracting from the content."
|
|
36776
|
+
],
|
|
36777
|
+
outputs: [
|
|
36778
|
+
"Interaction and motion design update"
|
|
36779
|
+
]
|
|
36780
|
+
},
|
|
36717
36781
|
{
|
|
36718
36782
|
id: "visual-polisher",
|
|
36719
36783
|
label: "visual-polisher",
|
|
@@ -37323,8 +37387,8 @@ var ExecutionOrchestrator = class {
|
|
|
37323
37387
|
let pendingApprovals = [
|
|
37324
37388
|
...session.pendingApprovals
|
|
37325
37389
|
];
|
|
37326
|
-
const maxAutoTasks = options.maxAutoTasks ??
|
|
37327
|
-
const maxParallelTasks = Math.max(1, options.maxParallelTasks ??
|
|
37390
|
+
const maxAutoTasks = options.maxAutoTasks ?? 4;
|
|
37391
|
+
const maxParallelTasks = Math.max(1, options.maxParallelTasks ?? 4);
|
|
37328
37392
|
let executedTasks = 0;
|
|
37329
37393
|
for (const approval of session.pendingApprovals) {
|
|
37330
37394
|
const decision = decisionByApprovalId.get(approval.id);
|
|
@@ -37640,7 +37704,8 @@ var ExecutionOrchestrator = class {
|
|
|
37640
37704
|
}
|
|
37641
37705
|
const profile = AGENT_CATALOG[task.agentRole];
|
|
37642
37706
|
const currentRoleCount = roleCounts.get(task.agentRole) ?? 0;
|
|
37643
|
-
|
|
37707
|
+
const effectiveConcurrency = Math.max(profile.maxConcurrentTasks, task.agentRole === "frontend-specialist" || task.agentRole === "backend-specialist" ? 3 : profile.maxConcurrentTasks);
|
|
37708
|
+
if (currentRoleCount >= effectiveConcurrency) {
|
|
37644
37709
|
continue;
|
|
37645
37710
|
}
|
|
37646
37711
|
selected.push(task);
|
|
@@ -37660,9 +37725,6 @@ var ExecutionOrchestrator = class {
|
|
|
37660
37725
|
if (task.agentRole === "planner") {
|
|
37661
37726
|
return this.executePlannerTask(sessionId, task, request, plan, emitProgress);
|
|
37662
37727
|
}
|
|
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
37728
|
if (request.workspaceState === "existing" && looksLikeStaticLandingGoal(request.goal) && task.type === "verification") {
|
|
37667
37729
|
return this.executeDeterministicVerificationTask(sessionId, task, request, emitProgress, options.signal);
|
|
37668
37730
|
}
|
|
@@ -39693,7 +39755,7 @@ async function executePromptByIntent(cwd, input, options = {}) {
|
|
|
39693
39755
|
}
|
|
39694
39756
|
return executeRunPrompt(cwd, input, options.outputFormat ?? "json", {
|
|
39695
39757
|
ephemeral: options.ephemeral ?? false,
|
|
39696
|
-
maxAutoTasks: options.maxAutoTasks ??
|
|
39758
|
+
maxAutoTasks: options.maxAutoTasks ?? 4,
|
|
39697
39759
|
maxAgentSteps: options.maxAgentSteps ?? 8,
|
|
39698
39760
|
maxRepairAttempts: options.maxRepairAttempts ?? 2,
|
|
39699
39761
|
...options.sessionId ? {
|
|
@@ -39714,7 +39776,7 @@ function createExecCommand() {
|
|
|
39714
39776
|
], []).option("--image <pathOrUrl>", "Attach an image to the prompt", (value, previous = []) => [
|
|
39715
39777
|
...previous,
|
|
39716
39778
|
value
|
|
39717
|
-
], []).option("--max-auto-tasks <count>", "Maximum ready tasks to auto-execute", parseCount,
|
|
39779
|
+
], []).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
39780
|
const cwd = import_node_process5.default.cwd();
|
|
39719
39781
|
const format = options.json ? "json" : options.outputFormat;
|
|
39720
39782
|
const agentSelection = await resolveAgentSelection(cwd, {
|
|
@@ -42190,7 +42252,7 @@ async function resolveSourceSession(cwd, sessionId, last = false, search) {
|
|
|
42190
42252
|
return loadSessionById(sessionId, cwd);
|
|
42191
42253
|
}
|
|
42192
42254
|
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,
|
|
42255
|
+
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
42256
|
const cwd = import_node_process12.default.cwd();
|
|
42195
42257
|
if (options.list) {
|
|
42196
42258
|
const sessions = options.search ? await searchSessions(options.search, cwd) : await listSessions(cwd);
|
|
@@ -43360,7 +43422,7 @@ function parseCount4(value) {
|
|
|
43360
43422
|
return parsed;
|
|
43361
43423
|
}
|
|
43362
43424
|
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,
|
|
43425
|
+
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
43426
|
const cwd = import_node_process23.default.cwd();
|
|
43365
43427
|
const firstSearchMatch = options.search ? (await searchSessions(options.search, cwd, 1)).at(0) ?? null : null;
|
|
43366
43428
|
if (options.list) {
|
|
@@ -43439,7 +43501,7 @@ function createRunCommand() {
|
|
|
43439
43501
|
"Explicit execution constraint; can be provided multiple times",
|
|
43440
43502
|
(value, previous = []) => [...previous, value],
|
|
43441
43503
|
[]
|
|
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,
|
|
43504
|
+
).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
43505
|
const cwd = import_node_process24.default.cwd();
|
|
43444
43506
|
const orchestrator = new ExecutionOrchestrator();
|
|
43445
43507
|
const agentSelection = await resolveAgentSelection(cwd, {
|
|
@@ -44084,6 +44146,11 @@ function shouldAutoStartApprovedRuns(runtime) {
|
|
|
44084
44146
|
const approvalMode = resolveRuntimeOverrideApprovalMode(runtime);
|
|
44085
44147
|
return approvalMode === "auto" || approvalMode === "dontAsk" || approvalMode === "acceptEdits" || approvalMode === "bypassPermissions";
|
|
44086
44148
|
}
|
|
44149
|
+
function shouldAutoStartProposal(runtime, proposal) {
|
|
44150
|
+
return Boolean(
|
|
44151
|
+
proposal && shouldAutoStartApprovedRuns(runtime) && !planRequiresOperatorReview(proposal.plan)
|
|
44152
|
+
);
|
|
44153
|
+
}
|
|
44087
44154
|
function resolveShellMaxAutoTasks(runtime) {
|
|
44088
44155
|
return shouldAutoStartApprovedRuns(runtime) ? UNBOUNDED_MAX_AUTO_TASKS : DEFAULT_MAX_AUTO_TASKS;
|
|
44089
44156
|
}
|
|
@@ -44681,6 +44748,21 @@ function pickStatusLabel(message) {
|
|
|
44681
44748
|
function pickIdleStatusLabel(seed) {
|
|
44682
44749
|
return IDLE_STATUS_LABELS[hashString(seed) % IDLE_STATUS_LABELS.length];
|
|
44683
44750
|
}
|
|
44751
|
+
function statusLabelForToolStart(event) {
|
|
44752
|
+
if (event.toolId === "shell.exec" || event.toolId === "tests.run") {
|
|
44753
|
+
const command = typeof event.input?.command === "string" ? event.input.command.trim().toLowerCase() : "";
|
|
44754
|
+
if (command.includes("build") || command.includes("lint") || command.includes("test")) {
|
|
44755
|
+
return "verifying";
|
|
44756
|
+
}
|
|
44757
|
+
if (command.includes("dev") || command.includes("start")) {
|
|
44758
|
+
return "serving";
|
|
44759
|
+
}
|
|
44760
|
+
if (command.length > 0) {
|
|
44761
|
+
return pickStatusLabel(command);
|
|
44762
|
+
}
|
|
44763
|
+
}
|
|
44764
|
+
return pickStatusLabel(event.reason ?? event.toolId);
|
|
44765
|
+
}
|
|
44684
44766
|
function statusLabelForEvent(event) {
|
|
44685
44767
|
switch (event.type) {
|
|
44686
44768
|
case "task-note":
|
|
@@ -44688,7 +44770,7 @@ function statusLabelForEvent(event) {
|
|
|
44688
44770
|
case "task-started":
|
|
44689
44771
|
return pickStatusLabel(event.task.title);
|
|
44690
44772
|
case "tool-started":
|
|
44691
|
-
return
|
|
44773
|
+
return statusLabelForToolStart(event);
|
|
44692
44774
|
case "model-usage":
|
|
44693
44775
|
return "thinking";
|
|
44694
44776
|
case "approval-requested":
|
|
@@ -44798,14 +44880,67 @@ function renderShellPlanSummary(plan) {
|
|
|
44798
44880
|
}
|
|
44799
44881
|
return lines;
|
|
44800
44882
|
}
|
|
44883
|
+
function inferRecommendedPlanAnswer(question, plan) {
|
|
44884
|
+
const lower = question.toLowerCase();
|
|
44885
|
+
const goal = plan.goal.toLowerCase();
|
|
44886
|
+
if (lower.includes("brand voice") || lower.includes("visual direction")) {
|
|
44887
|
+
if (goal.includes("blog") || goal.includes("post")) {
|
|
44888
|
+
return "Use a premium editorial direction: clean typography, strong whitespace, restrained motion, and a polished reading-first layout.";
|
|
44889
|
+
}
|
|
44890
|
+
return "Use a restrained premium product direction: crisp typography, strong whitespace, subtle motion, and a clear call to action.";
|
|
44891
|
+
}
|
|
44892
|
+
if (lower.includes("which sections")) {
|
|
44893
|
+
if (goal.includes("blog") || goal.includes("post")) {
|
|
44894
|
+
return "Start with navigation, hero, featured posts, topic/category grid, newsletter CTA, and a compact footer.";
|
|
44895
|
+
}
|
|
44896
|
+
return "Start with navigation, hero, key benefits, proof/examples, primary CTA, and footer.";
|
|
44897
|
+
}
|
|
44898
|
+
if (lower.includes("primary call to action")) {
|
|
44899
|
+
if (goal.includes("blog") || goal.includes("post")) {
|
|
44900
|
+
return "Drive readers to featured posts first, with newsletter signup as the secondary CTA.";
|
|
44901
|
+
}
|
|
44902
|
+
return "Drive the main product action with one clear primary CTA and keep secondary actions minimal.";
|
|
44903
|
+
}
|
|
44904
|
+
if (lower.includes("which stack") || lower.includes("deployment target")) {
|
|
44905
|
+
return "Stay with the current repo stack and existing deployment shape unless the user asks for a migration.";
|
|
44906
|
+
}
|
|
44907
|
+
if (lower.includes("authentication model")) {
|
|
44908
|
+
return "Assume no authentication in the first version unless the request explicitly needs gated user flows.";
|
|
44909
|
+
}
|
|
44910
|
+
if (lower.includes("external services") || lower.includes("apis")) {
|
|
44911
|
+
return "Assume no new external integrations beyond what already exists in the repository.";
|
|
44912
|
+
}
|
|
44913
|
+
return "Proceed with the most pragmatic default that preserves the current repo and keeps the first version focused.";
|
|
44914
|
+
}
|
|
44915
|
+
function extractPlanReviewPrompts(plan) {
|
|
44916
|
+
return plan.openQuestions.slice(0, 3).map((question) => ({
|
|
44917
|
+
question,
|
|
44918
|
+
recommendation: inferRecommendedPlanAnswer(question, plan)
|
|
44919
|
+
}));
|
|
44920
|
+
}
|
|
44921
|
+
function planRequiresOperatorReview(plan) {
|
|
44922
|
+
return extractPlanReviewPrompts(plan).length > 0;
|
|
44923
|
+
}
|
|
44801
44924
|
function renderPendingRunProposal(proposal, options = {}) {
|
|
44925
|
+
const reviewPrompts = extractPlanReviewPrompts(proposal.plan);
|
|
44926
|
+
const requiresReview = reviewPrompts.length > 0;
|
|
44802
44927
|
const lines = [
|
|
44803
44928
|
`${color(BOLD, proposal.source === "queued" ? "Queued Plan Ready" : "Ready To Run")}`,
|
|
44804
|
-
...renderShellPlanSummary(proposal.plan)
|
|
44805
|
-
"",
|
|
44806
|
-
color(DIM, `saved plan: ${proposal.planPath}`),
|
|
44807
|
-
options.autoStart ? color(DIM, "next: auto-starting in the current permission mode") : "next: /approve to start, /run revise <feedback> to adjust, /run cancel to drop it"
|
|
44929
|
+
...renderShellPlanSummary(proposal.plan)
|
|
44808
44930
|
];
|
|
44931
|
+
if (requiresReview) {
|
|
44932
|
+
lines.push("");
|
|
44933
|
+
lines.push(color(BOLD, "Recommended Defaults"));
|
|
44934
|
+
for (const prompt of reviewPrompts) {
|
|
44935
|
+
lines.push(`\u2022 ${prompt.question}`);
|
|
44936
|
+
lines.push(color(DIM, ` recommended: ${prompt.recommendation}`));
|
|
44937
|
+
}
|
|
44938
|
+
}
|
|
44939
|
+
lines.push("");
|
|
44940
|
+
lines.push(color(DIM, `saved plan: ${proposal.planPath}`));
|
|
44941
|
+
lines.push(
|
|
44942
|
+
requiresReview ? "next: /run approve to accept the recommended defaults, /run revise <feedback> to adjust, /run cancel to drop it" : options.autoStart ? color(DIM, "next: auto-starting in the current permission mode") : "next: /approve to start, /run revise <feedback> to adjust, /run cancel to drop it"
|
|
44943
|
+
);
|
|
44809
44944
|
if (proposal.source === "queued") {
|
|
44810
44945
|
lines.splice(1, 0, color(DIM, "The next queued request has been planned and is waiting for your approval."));
|
|
44811
44946
|
}
|
|
@@ -44903,6 +45038,24 @@ function renderConciseProgress(board, startedAt) {
|
|
|
44903
45038
|
] : []
|
|
44904
45039
|
];
|
|
44905
45040
|
}
|
|
45041
|
+
function summarizeToolStart(event) {
|
|
45042
|
+
if (event.toolId === "shell.exec" || event.toolId === "tests.run") {
|
|
45043
|
+
const command = typeof event.input?.command === "string" ? event.input.command.trim() : "";
|
|
45044
|
+
if (command) {
|
|
45045
|
+
return `Running ${shortenMiddle(command, 90)}`;
|
|
45046
|
+
}
|
|
45047
|
+
}
|
|
45048
|
+
if (event.toolId === "http.fetch" && typeof event.input?.url === "string") {
|
|
45049
|
+
return `Checking ${shortenMiddle(event.input.url, 90)}`;
|
|
45050
|
+
}
|
|
45051
|
+
if (event.toolId === "process.start" && typeof event.input?.command === "string") {
|
|
45052
|
+
return `Starting ${shortenMiddle(event.input.command, 90)}`;
|
|
45053
|
+
}
|
|
45054
|
+
if (event.toolId === "browser.open" && typeof event.input?.url === "string") {
|
|
45055
|
+
return `Opening ${shortenMiddle(event.input.url, 90)}`;
|
|
45056
|
+
}
|
|
45057
|
+
return null;
|
|
45058
|
+
}
|
|
44906
45059
|
function renderLiveExecutionEvent(event, board, startedAt) {
|
|
44907
45060
|
switch (event.type) {
|
|
44908
45061
|
case "task-started":
|
|
@@ -44918,6 +45071,13 @@ function renderLiveExecutionEvent(event, board, startedAt) {
|
|
|
44918
45071
|
)} ${simplifyExecutionSummary(event.summary) || event.taskId}`,
|
|
44919
45072
|
...renderConciseProgress(board, startedAt)
|
|
44920
45073
|
];
|
|
45074
|
+
case "tool-started": {
|
|
45075
|
+
const summary = summarizeToolStart(event);
|
|
45076
|
+
return summary ? [
|
|
45077
|
+
`${color(DIM, "working")} ${summary}`,
|
|
45078
|
+
...renderConciseProgress(board, startedAt)
|
|
45079
|
+
] : [];
|
|
45080
|
+
}
|
|
44921
45081
|
case "task-note":
|
|
44922
45082
|
return isUserVisibleTaskNote(event.message) ? [
|
|
44923
45083
|
`${color(DIM, "note")} ${simplifyTaskNote(event.message)}`
|
|
@@ -45096,7 +45256,7 @@ async function drainQueuedWork(runtime) {
|
|
|
45096
45256
|
source: "queued"
|
|
45097
45257
|
});
|
|
45098
45258
|
runtime.currentCwd = nextCwd;
|
|
45099
|
-
if (
|
|
45259
|
+
if (shouldAutoStartProposal(runtime, runtime.pendingRunProposal)) {
|
|
45100
45260
|
console.log(color(DIM, "Auto-starting queued request in the current permission mode."));
|
|
45101
45261
|
startPendingRunExecution(runtime);
|
|
45102
45262
|
}
|
|
@@ -45269,7 +45429,7 @@ async function prepareRunProposal(cwd, goal, runtime, options = {}) {
|
|
|
45269
45429
|
console.log(renderPendingRunProposal(
|
|
45270
45430
|
runtime.pendingRunProposal,
|
|
45271
45431
|
{
|
|
45272
|
-
autoStart:
|
|
45432
|
+
autoStart: shouldAutoStartProposal(runtime, runtime.pendingRunProposal)
|
|
45273
45433
|
}
|
|
45274
45434
|
).join("\n"));
|
|
45275
45435
|
return request.cwd;
|
|
@@ -46679,7 +46839,7 @@ async function handleShellCommand(cwd, input, state, runtime, execute) {
|
|
|
46679
46839
|
const nextCwd = await prepareRunProposal(cwd, trimmed, runtime, {
|
|
46680
46840
|
source: "direct"
|
|
46681
46841
|
});
|
|
46682
|
-
if (
|
|
46842
|
+
if (shouldAutoStartProposal(runtime, runtime.pendingRunProposal)) {
|
|
46683
46843
|
console.log(color(DIM, "Auto-starting in the current permission mode."));
|
|
46684
46844
|
startPendingRunExecution(runtime);
|
|
46685
46845
|
}
|
|
@@ -46809,7 +46969,7 @@ async function handleShellCommand(cwd, input, state, runtime, execute) {
|
|
|
46809
46969
|
console.log(renderPendingRunProposal(
|
|
46810
46970
|
runtime.pendingRunProposal,
|
|
46811
46971
|
{
|
|
46812
|
-
autoStart:
|
|
46972
|
+
autoStart: shouldAutoStartProposal(runtime, runtime.pendingRunProposal)
|
|
46813
46973
|
}
|
|
46814
46974
|
).join("\n"));
|
|
46815
46975
|
return cwd;
|
|
@@ -46846,7 +47006,7 @@ async function handleShellCommand(cwd, input, state, runtime, execute) {
|
|
|
46846
47006
|
const nextCwd = await prepareRunProposal(cwd, goal, runtime, {
|
|
46847
47007
|
source: "direct"
|
|
46848
47008
|
});
|
|
46849
|
-
if (
|
|
47009
|
+
if (shouldAutoStartProposal(runtime, runtime.pendingRunProposal)) {
|
|
46850
47010
|
console.log(color(DIM, "Auto-starting in the current permission mode."));
|
|
46851
47011
|
startPendingRunExecution(runtime);
|
|
46852
47012
|
}
|