@kimbho/kimbho-cli 0.1.31 → 0.1.32
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 +384 -19
- 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.32",
|
|
12722
12722
|
description: "Kimbho CLI is a terminal-native coding agent for planning, execution, and verification.",
|
|
12723
12723
|
type: "module",
|
|
12724
12724
|
engines: {
|
|
@@ -42456,7 +42456,13 @@ var CHAT_PREFIXES = [
|
|
|
42456
42456
|
"explain ",
|
|
42457
42457
|
"summarize ",
|
|
42458
42458
|
"review ",
|
|
42459
|
-
"analyze "
|
|
42459
|
+
"analyze ",
|
|
42460
|
+
"tell me ",
|
|
42461
|
+
"describe ",
|
|
42462
|
+
"detail ",
|
|
42463
|
+
"details ",
|
|
42464
|
+
"walk me through ",
|
|
42465
|
+
"help me understand "
|
|
42460
42466
|
];
|
|
42461
42467
|
var PLAN_PREFIXES = [
|
|
42462
42468
|
"plan ",
|
|
@@ -42468,6 +42474,18 @@ var PLAN_PREFIXES = [
|
|
|
42468
42474
|
function looksLikeExecutionRequest(input) {
|
|
42469
42475
|
return /\b(build|create|make|scaffold|implement|fix|refactor|setup|set up|generate|add|change|update|edit|rewrite|restyle|redesign|improve|enhance)\b/.test(input);
|
|
42470
42476
|
}
|
|
42477
|
+
function looksLikeInformationalRequest(input) {
|
|
42478
|
+
if (/\b(tell me|describe|walk me through|help me understand)\b/.test(input)) {
|
|
42479
|
+
return true;
|
|
42480
|
+
}
|
|
42481
|
+
if (/\b(details?|overview|summary|walkthrough|explanation)\b/.test(input) && /\b(project|repo|repository|codebase|workspace|app)\b/.test(input)) {
|
|
42482
|
+
return true;
|
|
42483
|
+
}
|
|
42484
|
+
return /\b(current|this|the)\s+(project|repo|repository|codebase|workspace|app)\b/.test(input) && /\b(details?|overview|summary|about)\b/.test(input);
|
|
42485
|
+
}
|
|
42486
|
+
function looksLikeWorkspaceInfoPrompt(input) {
|
|
42487
|
+
return looksLikeInformationalRequest(input.toLowerCase()) && /\b(project|repo|repository|codebase|workspace|app)\b/.test(input.toLowerCase());
|
|
42488
|
+
}
|
|
42471
42489
|
function stripConversationalLead(input) {
|
|
42472
42490
|
let normalized = input.trim().toLowerCase();
|
|
42473
42491
|
normalized = normalized.replace(/^(hi|hello|hey|yo|sup)\b[!,. ]*/u, "").trim();
|
|
@@ -42495,6 +42513,9 @@ function inferPromptIntent(input) {
|
|
|
42495
42513
|
if (looksLikeExecutionRequest(taskCandidate)) {
|
|
42496
42514
|
return "run";
|
|
42497
42515
|
}
|
|
42516
|
+
if (looksLikeInformationalRequest(taskCandidate)) {
|
|
42517
|
+
return "chat";
|
|
42518
|
+
}
|
|
42498
42519
|
if (normalized.endsWith("?")) {
|
|
42499
42520
|
return "chat";
|
|
42500
42521
|
}
|
|
@@ -50290,6 +50311,138 @@ function renderPendingRunProposal(proposal, options = {}) {
|
|
|
50290
50311
|
}
|
|
50291
50312
|
return lines;
|
|
50292
50313
|
}
|
|
50314
|
+
function buildWorkspaceAnalysisPlan(request, prompt) {
|
|
50315
|
+
const generatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
50316
|
+
return {
|
|
50317
|
+
goal: request.goal,
|
|
50318
|
+
generatedAt,
|
|
50319
|
+
summary: "Read-only multi-agent analysis of the current repository to answer the operator's question with concrete workspace evidence.",
|
|
50320
|
+
repoStrategy: {
|
|
50321
|
+
mode: "existing-repo",
|
|
50322
|
+
reasoning: "This is an analysis-only request about the current workspace, so the agent team should inspect the repo and synthesize findings without editing source files."
|
|
50323
|
+
},
|
|
50324
|
+
assumptions: [
|
|
50325
|
+
"The user wants a grounded explanation of the current repository, not code changes.",
|
|
50326
|
+
"The analysis should stay read-only and avoid modifying product files."
|
|
50327
|
+
],
|
|
50328
|
+
openQuestions: [],
|
|
50329
|
+
milestones: [
|
|
50330
|
+
{
|
|
50331
|
+
id: "m1-repo-survey",
|
|
50332
|
+
title: "Repository Survey",
|
|
50333
|
+
objective: "Inspect the current workspace structure, entrypoints, tooling, and conventions.",
|
|
50334
|
+
tasks: [
|
|
50335
|
+
{
|
|
50336
|
+
id: "t1-repo-analysis",
|
|
50337
|
+
title: "Analyze the current workspace and conventions",
|
|
50338
|
+
description: "Map the repository shape, commands, entrypoints, and constraints before answering the user's question.",
|
|
50339
|
+
type: "analysis",
|
|
50340
|
+
status: "pending",
|
|
50341
|
+
agentRole: "repo-analyst",
|
|
50342
|
+
dependsOn: [],
|
|
50343
|
+
acceptanceCriteria: [
|
|
50344
|
+
"Repository shape and commands are captured.",
|
|
50345
|
+
"Likely entrypoints and major packages are identified."
|
|
50346
|
+
],
|
|
50347
|
+
outputs: [
|
|
50348
|
+
"Repo analysis summary"
|
|
50349
|
+
],
|
|
50350
|
+
filesLikelyTouched: [
|
|
50351
|
+
".",
|
|
50352
|
+
".kimbho/"
|
|
50353
|
+
],
|
|
50354
|
+
riskLevel: "low",
|
|
50355
|
+
sandboxModeOverride: "read-only"
|
|
50356
|
+
},
|
|
50357
|
+
{
|
|
50358
|
+
id: "t2-architecture",
|
|
50359
|
+
title: "Synthesize the architecture and package boundaries",
|
|
50360
|
+
description: "Turn the repository findings into a clear explanation of the system structure and responsibilities.",
|
|
50361
|
+
type: "documentation",
|
|
50362
|
+
status: "pending",
|
|
50363
|
+
agentRole: "planner",
|
|
50364
|
+
dependsOn: [
|
|
50365
|
+
"t1-repo-analysis"
|
|
50366
|
+
],
|
|
50367
|
+
acceptanceCriteria: [
|
|
50368
|
+
"Architecture summary is grounded in repo analysis findings.",
|
|
50369
|
+
"The main packages and responsibilities are explicit."
|
|
50370
|
+
],
|
|
50371
|
+
outputs: [
|
|
50372
|
+
"Architecture brief"
|
|
50373
|
+
],
|
|
50374
|
+
filesLikelyTouched: [
|
|
50375
|
+
".kimbho/"
|
|
50376
|
+
],
|
|
50377
|
+
riskLevel: "low",
|
|
50378
|
+
sandboxModeOverride: "read-only"
|
|
50379
|
+
}
|
|
50380
|
+
]
|
|
50381
|
+
},
|
|
50382
|
+
{
|
|
50383
|
+
id: "m2-answer",
|
|
50384
|
+
title: "Answer",
|
|
50385
|
+
objective: "Review the gathered analysis artifacts and produce the final project explanation.",
|
|
50386
|
+
tasks: [
|
|
50387
|
+
{
|
|
50388
|
+
id: "t3-project-brief",
|
|
50389
|
+
title: "Review the analysis artifacts and prepare the project explanation",
|
|
50390
|
+
description: "Inspect the repo-analysis and architecture artifacts, then summarize the current project in terms that answer the user's question.",
|
|
50391
|
+
type: "documentation",
|
|
50392
|
+
status: "pending",
|
|
50393
|
+
agentRole: "reviewer",
|
|
50394
|
+
dependsOn: [
|
|
50395
|
+
"t1-repo-analysis",
|
|
50396
|
+
"t2-architecture"
|
|
50397
|
+
],
|
|
50398
|
+
acceptanceCriteria: [
|
|
50399
|
+
"The answer addresses the user's question directly.",
|
|
50400
|
+
"The summary is grounded in repository evidence instead of generic assistant chatter."
|
|
50401
|
+
],
|
|
50402
|
+
outputs: [
|
|
50403
|
+
"Project explanation summary"
|
|
50404
|
+
],
|
|
50405
|
+
filesLikelyTouched: [
|
|
50406
|
+
".kimbho/logs/",
|
|
50407
|
+
"kimbho_init.md"
|
|
50408
|
+
],
|
|
50409
|
+
riskLevel: "low",
|
|
50410
|
+
sandboxModeOverride: "read-only",
|
|
50411
|
+
allowedTools: [
|
|
50412
|
+
"file.read",
|
|
50413
|
+
"file.search",
|
|
50414
|
+
"file.list",
|
|
50415
|
+
"repo.index",
|
|
50416
|
+
"repo.query",
|
|
50417
|
+
"git.diff"
|
|
50418
|
+
],
|
|
50419
|
+
deniedTools: [
|
|
50420
|
+
"file.write",
|
|
50421
|
+
"file.patch",
|
|
50422
|
+
"shell.exec"
|
|
50423
|
+
],
|
|
50424
|
+
agentPromptPreamble: [
|
|
50425
|
+
"This is a read-only repository explanation task.",
|
|
50426
|
+
"Do not modify product files, install packages, or run development servers.",
|
|
50427
|
+
`Answer the operator's question: ${prompt}`,
|
|
50428
|
+
"Use the repo-analysis and architecture artifacts plus direct file inspection if needed.",
|
|
50429
|
+
"Finish with a concise but concrete summary of the project, stack, entrypoints, commands, and notable risks or gaps."
|
|
50430
|
+
].join("\n")
|
|
50431
|
+
}
|
|
50432
|
+
]
|
|
50433
|
+
}
|
|
50434
|
+
],
|
|
50435
|
+
verificationChecklist: [
|
|
50436
|
+
"Repo analysis artifacts were captured.",
|
|
50437
|
+
"The architecture summary is grounded in the workspace.",
|
|
50438
|
+
"The final explanation answers the user's question without changing source files."
|
|
50439
|
+
],
|
|
50440
|
+
executionNotes: [
|
|
50441
|
+
"Read-only analysis run triggered directly from a workspace question.",
|
|
50442
|
+
"Prefer repo/file tools and existing memory artifacts over generic assistant responses."
|
|
50443
|
+
]
|
|
50444
|
+
};
|
|
50445
|
+
}
|
|
50293
50446
|
function hasRenderableDiff(toolId, output) {
|
|
50294
50447
|
if (!output || output.trim().length === 0) {
|
|
50295
50448
|
return false;
|
|
@@ -50913,6 +51066,22 @@ async function handleChatPrompt(cwd, prompt, runtime) {
|
|
|
50913
51066
|
maxCharsPerFile: 3e3
|
|
50914
51067
|
});
|
|
50915
51068
|
const skillContext = await resolveActivatedSkillContext(cwd, hydrated.prompt);
|
|
51069
|
+
const workspaceInfoPrompt = looksLikeWorkspaceInfoPrompt(hydrated.prompt);
|
|
51070
|
+
let workspaceOverview = null;
|
|
51071
|
+
if (workspaceInfoPrompt) {
|
|
51072
|
+
const existingOverview = await readMarkdownIfExists(import_node_path33.default.join(cwd, "kimbho_init.md"));
|
|
51073
|
+
if (existingOverview) {
|
|
51074
|
+
workspaceOverview = existingOverview.slice(0, 6e3);
|
|
51075
|
+
} else {
|
|
51076
|
+
try {
|
|
51077
|
+
const generated = await generateProjectInitFile(cwd, "kimbho_init.md");
|
|
51078
|
+
const generatedOverview = await readMarkdownIfExists(generated.outputPath);
|
|
51079
|
+
workspaceOverview = generatedOverview?.slice(0, 6e3) ?? null;
|
|
51080
|
+
} catch {
|
|
51081
|
+
workspaceOverview = null;
|
|
51082
|
+
}
|
|
51083
|
+
}
|
|
51084
|
+
}
|
|
50916
51085
|
const compactionPath = await compactConversationIfNeeded(cwd, runtime, runtime.focusRole);
|
|
50917
51086
|
if (compactionPath) {
|
|
50918
51087
|
console.log(color(DIM, `[compacting] condensed ${runtime.focusRole} chat context -> ${compactionPath}`));
|
|
@@ -50928,27 +51097,34 @@ async function handleChatPrompt(cwd, prompt, runtime) {
|
|
|
50928
51097
|
let result;
|
|
50929
51098
|
const activity = new ShellActivityIndicator(pickIdleStatusLabel(prompt));
|
|
50930
51099
|
activity.start();
|
|
51100
|
+
const systemPromptSections = [
|
|
51101
|
+
brain.settings.promptPreamble,
|
|
51102
|
+
adaptiveMemory.chatSummary.length > 0 ? `Adaptive memory:
|
|
51103
|
+
${adaptiveMemory.chatSummary}` : null,
|
|
51104
|
+
memoryContext.length > 0 ? [
|
|
51105
|
+
"Workspace memory:",
|
|
51106
|
+
...memoryContext.map((record2) => `File: ${record2.filePath}
|
|
51107
|
+
${record2.content}`)
|
|
51108
|
+
].join("\n\n") : null,
|
|
51109
|
+
workspaceOverview ? [
|
|
51110
|
+
"Workspace question handling:",
|
|
51111
|
+
"The user is asking about the current repository. Ground the answer in the workspace context below and do not reply with a generic assistant introduction.",
|
|
51112
|
+
`Workspace overview:
|
|
51113
|
+
${workspaceOverview}`
|
|
51114
|
+
].join("\n\n") : null,
|
|
51115
|
+
skillContext.systemPromptSections.length > 0 ? [
|
|
51116
|
+
"Active skill packs:",
|
|
51117
|
+
...skillContext.systemPromptSections
|
|
51118
|
+
].join("\n\n") : null,
|
|
51119
|
+
runtime.conversationSummaries[runtime.focusRole] ? `Compacted conversation summary:
|
|
51120
|
+
${runtime.conversationSummaries[runtime.focusRole]}` : null
|
|
51121
|
+
].filter((value) => Boolean(value));
|
|
50931
51122
|
try {
|
|
50932
51123
|
result = await brain.client.generateText({
|
|
50933
51124
|
model: brain.model,
|
|
50934
51125
|
messages,
|
|
50935
|
-
...
|
|
50936
|
-
systemPrompt:
|
|
50937
|
-
brain.settings.promptPreamble,
|
|
50938
|
-
adaptiveMemory.chatSummary.length > 0 ? `Adaptive memory:
|
|
50939
|
-
${adaptiveMemory.chatSummary}` : null,
|
|
50940
|
-
memoryContext.length > 0 ? [
|
|
50941
|
-
"Workspace memory:",
|
|
50942
|
-
...memoryContext.map((record2) => `File: ${record2.filePath}
|
|
50943
|
-
${record2.content}`)
|
|
50944
|
-
].join("\n\n") : null,
|
|
50945
|
-
skillContext.systemPromptSections.length > 0 ? [
|
|
50946
|
-
"Active skill packs:",
|
|
50947
|
-
...skillContext.systemPromptSections
|
|
50948
|
-
].join("\n\n") : null,
|
|
50949
|
-
runtime.conversationSummaries[runtime.focusRole] ? `Compacted conversation summary:
|
|
50950
|
-
${runtime.conversationSummaries[runtime.focusRole]}` : null
|
|
50951
|
-
].filter((value) => Boolean(value)).join("\n\n")
|
|
51126
|
+
...systemPromptSections.length > 0 ? {
|
|
51127
|
+
systemPrompt: systemPromptSections.join("\n\n")
|
|
50952
51128
|
} : {},
|
|
50953
51129
|
...typeof brain.settings.temperature === "number" ? {
|
|
50954
51130
|
temperature: brain.settings.temperature
|
|
@@ -51147,6 +51323,174 @@ async function executePendingRunProposal(runtime) {
|
|
|
51147
51323
|
void drainQueuedWork(runtime);
|
|
51148
51324
|
return request.cwd;
|
|
51149
51325
|
}
|
|
51326
|
+
async function synthesizeWorkspaceAnalysisAnswer(cwd, prompt, runtime, snapshot) {
|
|
51327
|
+
const config2 = await loadConfig(cwd);
|
|
51328
|
+
const projectInit = await readMarkdownIfExists(import_node_path33.default.join(cwd, "kimbho_init.md"));
|
|
51329
|
+
const artifactPaths = Array.from(new Set(
|
|
51330
|
+
snapshot.events.flatMap((event) => [
|
|
51331
|
+
...event.artifacts,
|
|
51332
|
+
...event.toolResults.flatMap((toolResult) => toolResult.artifacts)
|
|
51333
|
+
])
|
|
51334
|
+
));
|
|
51335
|
+
const prioritizedArtifacts = artifactPaths.filter((artifactPath) => /repo-analysis|architecture-brief|project-brief|transcript/i.test(import_node_path33.default.basename(artifactPath))).slice(0, 4);
|
|
51336
|
+
const artifactSections = (await Promise.all(
|
|
51337
|
+
prioritizedArtifacts.map(async (artifactPath) => {
|
|
51338
|
+
const content = await readMarkdownIfExists(artifactPath);
|
|
51339
|
+
if (!content) {
|
|
51340
|
+
return null;
|
|
51341
|
+
}
|
|
51342
|
+
return `Artifact: ${artifactPath}
|
|
51343
|
+
${content.slice(0, 4e3)}`;
|
|
51344
|
+
})
|
|
51345
|
+
)).filter((section) => Boolean(section));
|
|
51346
|
+
if (!config2) {
|
|
51347
|
+
return [
|
|
51348
|
+
"Repository analysis completed.",
|
|
51349
|
+
projectInit ? `Current workspace summary:
|
|
51350
|
+
${projectInit.slice(0, 4e3)}` : "Project summary is available in the session artifacts, but no configured model was available to synthesize a narrative answer."
|
|
51351
|
+
].join("\n\n");
|
|
51352
|
+
}
|
|
51353
|
+
const resolver = new BrainResolver(config2, createDefaultBrainProviderRegistry(cwd));
|
|
51354
|
+
const brain = await resolver.resolve(runtime.focusRole);
|
|
51355
|
+
const result = await brain.client.generateText({
|
|
51356
|
+
model: brain.model,
|
|
51357
|
+
systemPrompt: [
|
|
51358
|
+
brain.settings.promptPreamble,
|
|
51359
|
+
"You are summarizing the current repository after a read-only multi-agent analysis session.",
|
|
51360
|
+
"Answer the user's question directly and concretely from the provided workspace evidence.",
|
|
51361
|
+
"Do not greet, do not speak generically about your own capabilities, and do not invent repository details.",
|
|
51362
|
+
"Prefer a crisp project overview with stack, structure, key entrypoints, commands, and notable risks or gaps."
|
|
51363
|
+
].filter(Boolean).join("\n\n"),
|
|
51364
|
+
userPrompt: [
|
|
51365
|
+
`User question: ${prompt}`,
|
|
51366
|
+
projectInit ? `Workspace overview:
|
|
51367
|
+
${projectInit.slice(0, 6e3)}` : null,
|
|
51368
|
+
artifactSections.length > 0 ? artifactSections.join("\n\n") : "No detailed analysis artifacts were available; answer from the workspace overview only."
|
|
51369
|
+
].filter((value) => Boolean(value)).join("\n\n"),
|
|
51370
|
+
...typeof brain.settings.temperature === "number" ? {
|
|
51371
|
+
temperature: brain.settings.temperature
|
|
51372
|
+
} : {},
|
|
51373
|
+
...typeof brain.settings.maxTokens === "number" ? {
|
|
51374
|
+
maxTokens: brain.settings.maxTokens
|
|
51375
|
+
} : {}
|
|
51376
|
+
});
|
|
51377
|
+
return result.text;
|
|
51378
|
+
}
|
|
51379
|
+
async function handleWorkspaceAnalysisPrompt(cwd, prompt, runtime) {
|
|
51380
|
+
const hydrated = await hydratePromptWithMcpResources(cwd, prompt);
|
|
51381
|
+
await recordAdaptiveTextObservation(cwd, hydrated.prompt, "chat");
|
|
51382
|
+
const skillAwareRequest = await preparePlanningRequest({
|
|
51383
|
+
goal: `Analyze the current repository and answer the user's question: ${hydrated.prompt}`,
|
|
51384
|
+
mode: "run",
|
|
51385
|
+
cwd,
|
|
51386
|
+
workspaceState: "existing",
|
|
51387
|
+
constraints: [
|
|
51388
|
+
"Read-only repository analysis only.",
|
|
51389
|
+
"Do not modify source files, install packages, or start development servers.",
|
|
51390
|
+
"Use multiple agents to inspect the workspace and synthesize the answer when helpful."
|
|
51391
|
+
]
|
|
51392
|
+
});
|
|
51393
|
+
const request = skillAwareRequest.request;
|
|
51394
|
+
const plan = buildWorkspaceAnalysisPlan(request, hydrated.prompt);
|
|
51395
|
+
const planPath = await savePlan(plan, request.cwd);
|
|
51396
|
+
const orchestrator = new ExecutionOrchestrator();
|
|
51397
|
+
const initialSnapshot = orchestrator.createSessionSnapshot(
|
|
51398
|
+
orchestrator.buildEnvelope(request, plan)
|
|
51399
|
+
);
|
|
51400
|
+
const startedAt = Date.now();
|
|
51401
|
+
const telemetry = createExecutionTelemetry();
|
|
51402
|
+
const controller = new AbortController();
|
|
51403
|
+
runtime.activeExecution = {
|
|
51404
|
+
controller,
|
|
51405
|
+
label: hydrated.prompt
|
|
51406
|
+
};
|
|
51407
|
+
const liveBoard = createLiveRunBoard(
|
|
51408
|
+
initialSnapshot.id,
|
|
51409
|
+
hydrated.prompt,
|
|
51410
|
+
request,
|
|
51411
|
+
plan,
|
|
51412
|
+
resolveShellMaxAutoTasks(runtime),
|
|
51413
|
+
resolveShellMaxAgentSteps(runtime),
|
|
51414
|
+
DEFAULT_MAX_REPAIR_ATTEMPTS2
|
|
51415
|
+
);
|
|
51416
|
+
const tui = import_node_process35.default.stdout.isTTY ? new ShellExecutionTui(liveBoard, telemetry, startedAt, "analyzing", !runtime.dashboard) : null;
|
|
51417
|
+
const activity = tui ? null : new ShellActivityIndicator("analyzing");
|
|
51418
|
+
if (tui) {
|
|
51419
|
+
tui.start();
|
|
51420
|
+
tui.pushEvent(renderLiveExecutionEvent({
|
|
51421
|
+
type: "task-note",
|
|
51422
|
+
sessionId: initialSnapshot.id,
|
|
51423
|
+
message: "Read-only repository analysis session started."
|
|
51424
|
+
}, liveBoard, startedAt, {
|
|
51425
|
+
includeProgress: false
|
|
51426
|
+
}));
|
|
51427
|
+
} else {
|
|
51428
|
+
console.log(renderRunStartCard(liveBoard));
|
|
51429
|
+
console.log("");
|
|
51430
|
+
activity?.start();
|
|
51431
|
+
}
|
|
51432
|
+
let snapshot;
|
|
51433
|
+
try {
|
|
51434
|
+
snapshot = await orchestrator.continueSession(initialSnapshot, {
|
|
51435
|
+
maxAutoTasks: resolveShellMaxAutoTasks(runtime),
|
|
51436
|
+
maxAgentSteps: resolveShellMaxAgentSteps(runtime),
|
|
51437
|
+
maxRepairAttempts: DEFAULT_MAX_REPAIR_ATTEMPTS2,
|
|
51438
|
+
signal: controller.signal,
|
|
51439
|
+
onProgress: async (event) => {
|
|
51440
|
+
updateLiveRunBoard(liveBoard, event);
|
|
51441
|
+
if (event.type === "tool-started") {
|
|
51442
|
+
telemetry.toolCalls += 1;
|
|
51443
|
+
}
|
|
51444
|
+
if (event.type === "model-usage") {
|
|
51445
|
+
telemetry.modelCalls += 1;
|
|
51446
|
+
telemetry.inputTokens += event.usage?.inputTokens ?? 0;
|
|
51447
|
+
telemetry.outputTokens += event.usage?.outputTokens ?? 0;
|
|
51448
|
+
}
|
|
51449
|
+
if (tui) {
|
|
51450
|
+
tui.updateActivity(statusLabelForEvent(event));
|
|
51451
|
+
tui.pushEvent(renderLiveExecutionEvent(event, liveBoard, startedAt, {
|
|
51452
|
+
includeProgress: false
|
|
51453
|
+
}));
|
|
51454
|
+
} else {
|
|
51455
|
+
activity?.update(statusLabelForEvent(event));
|
|
51456
|
+
activity?.suspend();
|
|
51457
|
+
for (const line of renderLiveExecutionEvent(event, liveBoard, startedAt)) {
|
|
51458
|
+
console.log(line);
|
|
51459
|
+
}
|
|
51460
|
+
activity?.resume();
|
|
51461
|
+
}
|
|
51462
|
+
}
|
|
51463
|
+
});
|
|
51464
|
+
} finally {
|
|
51465
|
+
tui?.stop();
|
|
51466
|
+
activity?.stop();
|
|
51467
|
+
runtime.activeExecution = null;
|
|
51468
|
+
}
|
|
51469
|
+
const sessionPath = await saveSession(snapshot, request.cwd);
|
|
51470
|
+
await recordAdaptiveSessionOutcome(request.cwd, snapshot);
|
|
51471
|
+
runtime.currentCwd = request.cwd;
|
|
51472
|
+
const answer = await synthesizeWorkspaceAnalysisAnswer(request.cwd, hydrated.prompt, runtime, snapshot);
|
|
51473
|
+
const conversation = trimConversation([
|
|
51474
|
+
...getConversation(runtime, runtime.focusRole),
|
|
51475
|
+
{
|
|
51476
|
+
role: "user",
|
|
51477
|
+
content: hydrated.prompt
|
|
51478
|
+
},
|
|
51479
|
+
{
|
|
51480
|
+
role: "assistant",
|
|
51481
|
+
content: answer
|
|
51482
|
+
}
|
|
51483
|
+
]);
|
|
51484
|
+
runtime.conversations[runtime.focusRole] = conversation;
|
|
51485
|
+
console.log("");
|
|
51486
|
+
console.log(color(DIM, `elapsed: ${((Date.now() - startedAt) / 1e3).toFixed(1)}s`));
|
|
51487
|
+
console.log(color(DIM, renderExecutionTelemetry(telemetry, startedAt)));
|
|
51488
|
+
console.log(renderShellSessionSummary(snapshot, planPath, sessionPath));
|
|
51489
|
+
console.log("");
|
|
51490
|
+
console.log(color(DIM, "[analysis answer]"));
|
|
51491
|
+
console.log(renderTerminalMarkdown(answer));
|
|
51492
|
+
void drainQueuedWork(runtime);
|
|
51493
|
+
}
|
|
51150
51494
|
async function resumeGoalExecution(cwd, runtime) {
|
|
51151
51495
|
const session = await loadLatestSession(cwd);
|
|
51152
51496
|
if (!session) {
|
|
@@ -52848,6 +53192,10 @@ async function startPendingRunExecution(cwd, runtime) {
|
|
|
52848
53192
|
console.log(color(DIM, "Waiting on a hook question before starting the plan."));
|
|
52849
53193
|
return;
|
|
52850
53194
|
}
|
|
53195
|
+
if (!proposal) {
|
|
53196
|
+
console.log("No pending run proposal. Start with a build/change request or /run <goal>.");
|
|
53197
|
+
return;
|
|
53198
|
+
}
|
|
52851
53199
|
if (proposal && planRequiresOperatorReview(proposal.plan)) {
|
|
52852
53200
|
await emitShellHookEvent(
|
|
52853
53201
|
proposal.request.cwd,
|
|
@@ -52864,6 +53212,15 @@ async function startPendingRunExecution(cwd, runtime) {
|
|
|
52864
53212
|
}
|
|
52865
53213
|
);
|
|
52866
53214
|
}
|
|
53215
|
+
const confirmedProposal = runtime.pendingRunProposal;
|
|
53216
|
+
if (runtime.pendingHookElicitation) {
|
|
53217
|
+
console.log(color(DIM, "Waiting on a hook question before starting the plan."));
|
|
53218
|
+
return;
|
|
53219
|
+
}
|
|
53220
|
+
if (!confirmedProposal) {
|
|
53221
|
+
console.log(color(DIM, "Pending plan was cleared before execution could start."));
|
|
53222
|
+
return;
|
|
53223
|
+
}
|
|
52867
53224
|
console.log(color(DIM, "Starting the approved plan..."));
|
|
52868
53225
|
void executePendingRunProposal(runtime).catch((error2) => {
|
|
52869
53226
|
console.error(error2 instanceof Error ? error2.message : String(error2));
|
|
@@ -52971,6 +53328,14 @@ async function handleShellCommand(cwd, input, state, runtime, execute) {
|
|
|
52971
53328
|
return cwd;
|
|
52972
53329
|
}
|
|
52973
53330
|
if (!firstToken?.startsWith("/") && !TOP_LEVEL_COMMANDS.has(head) && !head.startsWith("-")) {
|
|
53331
|
+
if (looksLikeWorkspaceInfoPrompt(trimmed)) {
|
|
53332
|
+
if (runtime.activeExecution || runtime.queueDrainPromise || runtime.pendingRunProposal) {
|
|
53333
|
+
queuePlannerRequest(cwd, `Analyze the current repository and answer: ${trimmed}`, runtime, "run");
|
|
53334
|
+
return cwd;
|
|
53335
|
+
}
|
|
53336
|
+
await handleWorkspaceAnalysisPrompt(cwd, trimmed, runtime);
|
|
53337
|
+
return cwd;
|
|
53338
|
+
}
|
|
52974
53339
|
const intent = inferPromptIntent(trimmed);
|
|
52975
53340
|
if (intent === "run") {
|
|
52976
53341
|
if (runtime.activeExecution || runtime.queueDrainPromise || runtime.pendingRunProposal) {
|