@jun133/kitty 0.0.8 → 0.0.9
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/README.md +59 -20
- package/dist/App-6FETP3LH.mjs +521 -0
- package/dist/chunk-3KMC6H5K.mjs +2701 -0
- package/dist/chunk-4BN45TQG.mjs +654 -0
- package/dist/chunk-6NJJLOY3.mjs +2129 -0
- package/dist/chunk-DFDOKON5.mjs +530 -0
- package/dist/chunk-ELBEXOR7.mjs +10020 -0
- package/dist/chunk-YSWK3BGL.mjs +84 -0
- package/dist/cli.js +1321 -655
- package/dist/cli.js.map +1 -1
- package/dist/interactive-KLW4JL7R.mjs +340 -0
- package/dist/oneShot-YHDMPFQM.mjs +54 -0
- package/dist/session-XKWJHRVY.mjs +66 -0
- package/dist/tui.mjs +728 -0
- package/package.json +8 -2
package/dist/cli.js
CHANGED
|
@@ -40,7 +40,7 @@ var init_package = __esm({
|
|
|
40
40
|
"package.json"() {
|
|
41
41
|
package_default = {
|
|
42
42
|
name: "@jun133/kitty",
|
|
43
|
-
version: "0.0.
|
|
43
|
+
version: "0.0.9",
|
|
44
44
|
description: "Agent",
|
|
45
45
|
license: "MIT",
|
|
46
46
|
keywords: [
|
|
@@ -64,7 +64,7 @@ var init_package = __esm({
|
|
|
64
64
|
node: ">=20.0.0"
|
|
65
65
|
},
|
|
66
66
|
scripts: {
|
|
67
|
-
build: "tsup src/cli.ts --format cjs --platform node --target node20 --outDir dist --clean --sourcemap",
|
|
67
|
+
build: "tsup src/cli.ts --format cjs --platform node --target node20 --outDir dist --clean --sourcemap && tsup src/tui.ts --format esm --platform node --target node20 --outDir dist --clean=false --external typescript",
|
|
68
68
|
check: "npm run typecheck && npm run build",
|
|
69
69
|
dev: "tsx src/cli.ts",
|
|
70
70
|
"test:build": `node -e "require('node:fs').rmSync('.test-build', { recursive: true, force: true })" && tsc -p tsconfig.tests.json`,
|
|
@@ -83,12 +83,18 @@ var init_package = __esm({
|
|
|
83
83
|
execa: "^9.6.0",
|
|
84
84
|
"fast-glob": "^3.3.3",
|
|
85
85
|
figlet: "^1.11.0",
|
|
86
|
+
ink: "^7.1.0",
|
|
87
|
+
marked: "^15.0.7",
|
|
86
88
|
openai: "^6.4.0",
|
|
89
|
+
react: "^19.2.7",
|
|
90
|
+
"string-width": "^8.2.1",
|
|
91
|
+
"wrap-ansi": "^10.0.0",
|
|
87
92
|
ws: "^8.21.0"
|
|
88
93
|
},
|
|
89
94
|
devDependencies: {
|
|
90
95
|
"@types/better-sqlite3": "^7.6.13",
|
|
91
96
|
"@types/node": "^24.5.2",
|
|
97
|
+
"@types/react": "^19.2.17",
|
|
92
98
|
"@types/ws": "^8.18.1",
|
|
93
99
|
tsup: "^8.5.0",
|
|
94
100
|
tsx: "^4.20.5",
|
|
@@ -1128,6 +1134,13 @@ var init_wakeSignals = __esm({
|
|
|
1128
1134
|
});
|
|
1129
1135
|
|
|
1130
1136
|
// src/control/ledger.ts
|
|
1137
|
+
var ledger_exports = {};
|
|
1138
|
+
__export(ledger_exports, {
|
|
1139
|
+
ControlPlaneLedger: () => ControlPlaneLedger,
|
|
1140
|
+
ExecutionLedgerRepo: () => ExecutionLedgerRepo,
|
|
1141
|
+
TaskLifecycleLedgerRepo: () => TaskLifecycleLedgerRepo,
|
|
1142
|
+
WakeSignalLedgerRepo: () => WakeSignalLedgerRepo
|
|
1143
|
+
});
|
|
1131
1144
|
var import_better_sqlite3, import_node_fs2, ControlPlaneLedger;
|
|
1132
1145
|
var init_ledger = __esm({
|
|
1133
1146
|
"src/control/ledger.ts"() {
|
|
@@ -5911,6 +5924,12 @@ var init_envKeys = __esm({
|
|
|
5911
5924
|
});
|
|
5912
5925
|
|
|
5913
5926
|
// src/agent/prompt/format.ts
|
|
5927
|
+
var format_exports = {};
|
|
5928
|
+
__export(format_exports, {
|
|
5929
|
+
formatPromptBlock: () => formatPromptBlock,
|
|
5930
|
+
joinBlocks: () => joinBlocks,
|
|
5931
|
+
renderPromptLayers: () => renderPromptLayers
|
|
5932
|
+
});
|
|
5914
5933
|
function formatPromptBlock(title, content) {
|
|
5915
5934
|
return `${title}:
|
|
5916
5935
|
${content}`;
|
|
@@ -8682,7 +8701,22 @@ function readContextBudget(value, sessionPath) {
|
|
|
8682
8701
|
compressionMode,
|
|
8683
8702
|
compressionReason: readRequiredString(record, "compressionReason", sessionPath, "contextBudget"),
|
|
8684
8703
|
sources: readContextBudgetSources(record.sources, sessionPath),
|
|
8685
|
-
promptHotspots: readContextBudgetHotspots(record.promptHotspots, sessionPath)
|
|
8704
|
+
promptHotspots: readContextBudgetHotspots(record.promptHotspots, sessionPath),
|
|
8705
|
+
cacheLayout: readContextCacheLayout(record.cacheLayout, sessionPath)
|
|
8706
|
+
};
|
|
8707
|
+
}
|
|
8708
|
+
function readContextCacheLayout(value, sessionPath) {
|
|
8709
|
+
if (value === void 0) {
|
|
8710
|
+
return void 0;
|
|
8711
|
+
}
|
|
8712
|
+
const record = expectRecord(value, sessionPath, "contextBudget.cacheLayout");
|
|
8713
|
+
return {
|
|
8714
|
+
stablePrefixFingerprint: readRequiredString(record, "stablePrefixFingerprint", sessionPath, "contextBudget.cacheLayout"),
|
|
8715
|
+
volatileTailFingerprint: readRequiredString(record, "volatileTailFingerprint", sessionPath, "contextBudget.cacheLayout"),
|
|
8716
|
+
stablePrefixChars: readRequiredNumber(record, "stablePrefixChars", sessionPath, "contextBudget.cacheLayout"),
|
|
8717
|
+
volatileTailChars: readRequiredNumber(record, "volatileTailChars", sessionPath, "contextBudget.cacheLayout"),
|
|
8718
|
+
stableSources: readStringArray(record.stableSources, sessionPath, "contextBudget.cacheLayout.stableSources"),
|
|
8719
|
+
volatileSources: readStringArray(record.volatileSources, sessionPath, "contextBudget.cacheLayout.volatileSources")
|
|
8686
8720
|
};
|
|
8687
8721
|
}
|
|
8688
8722
|
function readContextBudgetSources(value, sessionPath) {
|
|
@@ -8724,6 +8758,17 @@ function readContextBudgetHotspots(value, sessionPath) {
|
|
|
8724
8758
|
};
|
|
8725
8759
|
});
|
|
8726
8760
|
}
|
|
8761
|
+
function readStringArray(value, sessionPath, scope) {
|
|
8762
|
+
if (!Array.isArray(value)) {
|
|
8763
|
+
throw createSessionCorruptError(sessionPath, `${scope} must be an array`);
|
|
8764
|
+
}
|
|
8765
|
+
return value.map((entry, index) => {
|
|
8766
|
+
if (typeof entry !== "string") {
|
|
8767
|
+
throw createSessionCorruptError(sessionPath, `${scope}[${index}] must be a string`);
|
|
8768
|
+
}
|
|
8769
|
+
return entry;
|
|
8770
|
+
});
|
|
8771
|
+
}
|
|
8727
8772
|
function readMessage(value, index, sessionPath) {
|
|
8728
8773
|
const record = expectRecord(value, sessionPath, `messages[${index}]`);
|
|
8729
8774
|
const role = readRequiredString(record, "role", sessionPath, `messages[${index}]`);
|
|
@@ -9881,6 +9926,222 @@ var init_projectContext = __esm({
|
|
|
9881
9926
|
}
|
|
9882
9927
|
});
|
|
9883
9928
|
|
|
9929
|
+
// src/runtime/scene.ts
|
|
9930
|
+
function buildRuntimeScene(status) {
|
|
9931
|
+
const executions = status.executions.active.map(buildExecutionScene);
|
|
9932
|
+
const blockedExecutions = executions.filter((execution) => execution.risk === "blocked");
|
|
9933
|
+
const watchExecutions = executions.filter((execution) => execution.risk === "watch");
|
|
9934
|
+
const activeBackground = executions.filter((execution) => execution.kind === "background");
|
|
9935
|
+
const blockedBackground = activeBackground.filter((execution) => execution.risk !== "none");
|
|
9936
|
+
return {
|
|
9937
|
+
headline: buildHeadline(status, blockedExecutions, watchExecutions),
|
|
9938
|
+
focus: readFocus(status),
|
|
9939
|
+
nextAction: readNextAction(status, blockedExecutions, watchExecutions),
|
|
9940
|
+
blocked: readBlocked(blockedExecutions),
|
|
9941
|
+
cost: readCost(status),
|
|
9942
|
+
recovery: readRecovery(status, executions),
|
|
9943
|
+
skills: {
|
|
9944
|
+
ready: status.skills.ready,
|
|
9945
|
+
total: status.skills.total,
|
|
9946
|
+
nextAction: readSkillsNextAction(status)
|
|
9947
|
+
},
|
|
9948
|
+
memory: {
|
|
9949
|
+
assets: status.memory.assets.length,
|
|
9950
|
+
latestSessionMemory: Boolean(status.sessions.latest?.hasMemory),
|
|
9951
|
+
nextAction: readMemoryNextAction(status)
|
|
9952
|
+
},
|
|
9953
|
+
background: {
|
|
9954
|
+
active: activeBackground.length,
|
|
9955
|
+
blocked: blockedBackground.length,
|
|
9956
|
+
nextAction: readBackgroundNextAction(activeBackground)
|
|
9957
|
+
},
|
|
9958
|
+
executions
|
|
9959
|
+
};
|
|
9960
|
+
}
|
|
9961
|
+
function buildExecutionScene(execution) {
|
|
9962
|
+
const risk = readExecutionRisk(execution);
|
|
9963
|
+
return {
|
|
9964
|
+
id: execution.id,
|
|
9965
|
+
kind: execution.kind,
|
|
9966
|
+
status: execution.status,
|
|
9967
|
+
health: execution.health?.message ?? `Execution is ${execution.status}.`,
|
|
9968
|
+
risk,
|
|
9969
|
+
summary: readExecutionSummary(execution),
|
|
9970
|
+
nextAction: readExecutionNextAction(execution, risk),
|
|
9971
|
+
lastOutput: execution.outputPreview ? truncateText2(execution.outputPreview, 160) : void 0
|
|
9972
|
+
};
|
|
9973
|
+
}
|
|
9974
|
+
function buildHeadline(status, blockedExecutions, watchExecutions) {
|
|
9975
|
+
if (!status.sessions.latest) {
|
|
9976
|
+
return "No active session yet.";
|
|
9977
|
+
}
|
|
9978
|
+
if (blockedExecutions.length > 0) {
|
|
9979
|
+
return `${blockedExecutions.length} execution(s) need attention.`;
|
|
9980
|
+
}
|
|
9981
|
+
if (watchExecutions.length > 0) {
|
|
9982
|
+
return `${watchExecutions.length} execution(s) should be watched.`;
|
|
9983
|
+
}
|
|
9984
|
+
if (status.executions.active.length > 0) {
|
|
9985
|
+
return `${status.executions.active.length} execution(s) are running.`;
|
|
9986
|
+
}
|
|
9987
|
+
return "Ready to continue the latest session.";
|
|
9988
|
+
}
|
|
9989
|
+
function readFocus(status) {
|
|
9990
|
+
const focus = status.sessions.latest?.focus;
|
|
9991
|
+
if (focus) {
|
|
9992
|
+
return truncateText2(focus, 120);
|
|
9993
|
+
}
|
|
9994
|
+
const title = status.sessions.latest?.title;
|
|
9995
|
+
if (title) {
|
|
9996
|
+
return truncateText2(title, 120);
|
|
9997
|
+
}
|
|
9998
|
+
return "none";
|
|
9999
|
+
}
|
|
10000
|
+
function readNextAction(status, blockedExecutions, watchExecutions) {
|
|
10001
|
+
const urgent = blockedExecutions[0] ?? watchExecutions[0];
|
|
10002
|
+
if (urgent) {
|
|
10003
|
+
return urgent.nextAction;
|
|
10004
|
+
}
|
|
10005
|
+
if (status.executions.active.length > 0) {
|
|
10006
|
+
return "Let active work finish, or inspect it with `kitty status` / `kitty background`.";
|
|
10007
|
+
}
|
|
10008
|
+
if (!status.sessions.latest) {
|
|
10009
|
+
return "Start a session with `kitty`.";
|
|
10010
|
+
}
|
|
10011
|
+
return "Continue from the current session focus.";
|
|
10012
|
+
}
|
|
10013
|
+
function readBlocked(blockedExecutions) {
|
|
10014
|
+
if (blockedExecutions.length === 0) {
|
|
10015
|
+
return "no";
|
|
10016
|
+
}
|
|
10017
|
+
return blockedExecutions.slice(0, 3).map((execution) => `${execution.kind} ${execution.id}: ${execution.health}`).join(" | ");
|
|
10018
|
+
}
|
|
10019
|
+
function readCost(status) {
|
|
10020
|
+
const budget = status.sessions.latest?.contextBudget;
|
|
10021
|
+
const latest = status.modelRequests.recent[0];
|
|
10022
|
+
const budgetText = budget ? `${Math.round(budget.usageRatio * 100)}% context${budget.compressed ? ", compressed" : ""}` : "context unknown";
|
|
10023
|
+
const layout = budget?.cacheLayout;
|
|
10024
|
+
const layoutText = layout ? `stable ${readStableRatio(layout.stablePrefixChars, layout.volatileTailChars)}` : "cache layout unknown";
|
|
10025
|
+
const usageText = latest?.usage ? readUsageCost(latest.usage) : latest ? "provider usage unavailable" : "no model request yet";
|
|
10026
|
+
return `${budgetText}; ${layoutText}; ${usageText}`;
|
|
10027
|
+
}
|
|
10028
|
+
function readStableRatio(stableChars, volatileChars) {
|
|
10029
|
+
const total = stableChars + volatileChars;
|
|
10030
|
+
return total > 0 ? `${Math.round(stableChars / total * 100)}%` : "unknown";
|
|
10031
|
+
}
|
|
10032
|
+
function readUsageCost(usage) {
|
|
10033
|
+
const cached = usage.cacheHitTokens ?? usage.cacheReadTokens;
|
|
10034
|
+
const hitRate = usage.cacheHitRate === void 0 ? void 0 : `${Math.round(usage.cacheHitRate * 100)}% hit`;
|
|
10035
|
+
return [
|
|
10036
|
+
usage.totalTokens === void 0 ? void 0 : `${usage.totalTokens} tokens`,
|
|
10037
|
+
cached === void 0 ? "cache unknown" : `${cached} cached`,
|
|
10038
|
+
hitRate
|
|
10039
|
+
].filter(Boolean).join(", ");
|
|
10040
|
+
}
|
|
10041
|
+
function readRecovery(status, executions) {
|
|
10042
|
+
const risky = executions.filter((execution) => execution.risk !== "none").length;
|
|
10043
|
+
if (risky > 0) {
|
|
10044
|
+
return `${risky} execution(s) need recovery attention.`;
|
|
10045
|
+
}
|
|
10046
|
+
if (status.wakeSignals.recent.length > 0) {
|
|
10047
|
+
return `${status.wakeSignals.recent.length} wake signal(s) recorded.`;
|
|
10048
|
+
}
|
|
10049
|
+
return "no recovery action needed";
|
|
10050
|
+
}
|
|
10051
|
+
function readSkillsNextAction(status) {
|
|
10052
|
+
if (status.skills.total === 0) {
|
|
10053
|
+
return "No runtime skills discovered.";
|
|
10054
|
+
}
|
|
10055
|
+
if (status.skills.needsAttention.length > 0) {
|
|
10056
|
+
return "Inspect skill issues before relying on those skills.";
|
|
10057
|
+
}
|
|
10058
|
+
return "Skills are ready; load full skill content only when needed.";
|
|
10059
|
+
}
|
|
10060
|
+
function readMemoryNextAction(status) {
|
|
10061
|
+
if (!status.sessions.latest) {
|
|
10062
|
+
return "No session memory yet.";
|
|
10063
|
+
}
|
|
10064
|
+
if (!status.sessions.latest.hasMemory && status.memory.assets.length === 0) {
|
|
10065
|
+
return "Continue the session until useful memory is saved.";
|
|
10066
|
+
}
|
|
10067
|
+
if (!status.sessions.latest.hasMemory && status.memory.assets.length > 0) {
|
|
10068
|
+
return "Review memory assets when prior evidence is needed.";
|
|
10069
|
+
}
|
|
10070
|
+
return "Session memory is available; use assets only when needed.";
|
|
10071
|
+
}
|
|
10072
|
+
function readBackgroundNextAction(backgrounds) {
|
|
10073
|
+
if (backgrounds.length === 0) {
|
|
10074
|
+
return "No active background work.";
|
|
10075
|
+
}
|
|
10076
|
+
const blocked = backgrounds.find((execution) => execution.risk === "blocked");
|
|
10077
|
+
if (blocked) {
|
|
10078
|
+
return blocked.nextAction;
|
|
10079
|
+
}
|
|
10080
|
+
const watch = backgrounds.find((execution) => execution.risk === "watch");
|
|
10081
|
+
if (watch) {
|
|
10082
|
+
return watch.nextAction;
|
|
10083
|
+
}
|
|
10084
|
+
return "Background work is running; wait or inspect latest output.";
|
|
10085
|
+
}
|
|
10086
|
+
function readExecutionRisk(execution) {
|
|
10087
|
+
switch (execution.health?.state) {
|
|
10088
|
+
case "deadline_passed":
|
|
10089
|
+
case "stale":
|
|
10090
|
+
return "blocked";
|
|
10091
|
+
case "no_output":
|
|
10092
|
+
return "watch";
|
|
10093
|
+
case "running":
|
|
10094
|
+
case "settled":
|
|
10095
|
+
case void 0:
|
|
10096
|
+
return "none";
|
|
10097
|
+
}
|
|
10098
|
+
}
|
|
10099
|
+
function readExecutionSummary(execution) {
|
|
10100
|
+
if (execution.assignment?.objective) {
|
|
10101
|
+
return truncateText2(execution.assignment.objective, 120);
|
|
10102
|
+
}
|
|
10103
|
+
if (execution.summary) {
|
|
10104
|
+
return truncateText2(execution.summary, 120);
|
|
10105
|
+
}
|
|
10106
|
+
if (execution.command) {
|
|
10107
|
+
return truncateText2(execution.command, 120);
|
|
10108
|
+
}
|
|
10109
|
+
return `${execution.kind} execution`;
|
|
10110
|
+
}
|
|
10111
|
+
function readExecutionNextAction(execution, risk) {
|
|
10112
|
+
if (execution.kind === "background") {
|
|
10113
|
+
if (risk === "blocked") {
|
|
10114
|
+
return `Inspect or stop with \`kitty background stop ${execution.id}\`.`;
|
|
10115
|
+
}
|
|
10116
|
+
if (risk === "watch") {
|
|
10117
|
+
return `Wait for first output or inspect with \`kitty background wait ${execution.id}\`.`;
|
|
10118
|
+
}
|
|
10119
|
+
return `Inspect with \`kitty background wait ${execution.id}\` if you need the result now.`;
|
|
10120
|
+
}
|
|
10121
|
+
if (risk === "blocked") {
|
|
10122
|
+
return `Inspect execution ${execution.id} in status before continuing.`;
|
|
10123
|
+
}
|
|
10124
|
+
if (risk === "watch") {
|
|
10125
|
+
return `Watch execution ${execution.id} for output or deadline.`;
|
|
10126
|
+
}
|
|
10127
|
+
if (execution.waitPolicy === "block_lead_until_complete") {
|
|
10128
|
+
return "Lead should wait for this execution to finish.";
|
|
10129
|
+
}
|
|
10130
|
+
return "Execution is active.";
|
|
10131
|
+
}
|
|
10132
|
+
function truncateText2(value, maxChars) {
|
|
10133
|
+
const normalized = value.replace(/\s+/g, " ").trim();
|
|
10134
|
+
if (normalized.length <= maxChars) {
|
|
10135
|
+
return normalized;
|
|
10136
|
+
}
|
|
10137
|
+
return `${normalized.slice(0, Math.max(0, maxChars - 3))}...`;
|
|
10138
|
+
}
|
|
10139
|
+
var init_scene = __esm({
|
|
10140
|
+
"src/runtime/scene.ts"() {
|
|
10141
|
+
"use strict";
|
|
10142
|
+
}
|
|
10143
|
+
});
|
|
10144
|
+
|
|
9884
10145
|
// src/runtime/status.ts
|
|
9885
10146
|
var status_exports = {};
|
|
9886
10147
|
__export(status_exports, {
|
|
@@ -9901,7 +10162,7 @@ async function buildRuntimeStatus(rootDir) {
|
|
|
9901
10162
|
]);
|
|
9902
10163
|
const sessions = sessionRead.sessions.map(summarizeSession);
|
|
9903
10164
|
const taskLifecycle = sessions[0] ? readTaskLifecycleStatus(paths.rootDir, sessions[0].id) : void 0;
|
|
9904
|
-
|
|
10165
|
+
const statusWithoutScene = {
|
|
9905
10166
|
rootDir: paths.rootDir,
|
|
9906
10167
|
stateDir: paths.kittyDir,
|
|
9907
10168
|
sessions: {
|
|
@@ -9922,6 +10183,10 @@ async function buildRuntimeStatus(rootDir) {
|
|
|
9922
10183
|
executions: control.executions,
|
|
9923
10184
|
wakeSignals: control.wakeSignals
|
|
9924
10185
|
};
|
|
10186
|
+
return {
|
|
10187
|
+
...statusWithoutScene,
|
|
10188
|
+
scene: buildRuntimeScene(statusWithoutScene)
|
|
10189
|
+
};
|
|
9925
10190
|
}
|
|
9926
10191
|
function summarizeProjectMap2(projectMap) {
|
|
9927
10192
|
return {
|
|
@@ -10101,6 +10366,7 @@ var init_status = __esm({
|
|
|
10101
10366
|
init_memory2();
|
|
10102
10367
|
init_projectContext();
|
|
10103
10368
|
init_executionSummary();
|
|
10369
|
+
init_scene();
|
|
10104
10370
|
init_store3();
|
|
10105
10371
|
DEFAULT_RECENT_LIMIT = 10;
|
|
10106
10372
|
}
|
|
@@ -12157,6 +12423,252 @@ var init_initialConfig = __esm({
|
|
|
12157
12423
|
}
|
|
12158
12424
|
});
|
|
12159
12425
|
|
|
12426
|
+
// src/cli/commands/runtimeStatusPresenter.ts
|
|
12427
|
+
var runtimeStatusPresenter_exports = {};
|
|
12428
|
+
__export(runtimeStatusPresenter_exports, {
|
|
12429
|
+
formatRuntimeStatusText: () => formatRuntimeStatusText
|
|
12430
|
+
});
|
|
12431
|
+
function formatRuntimeStatusText(status) {
|
|
12432
|
+
const lines = [];
|
|
12433
|
+
lines.push(`Project: ${status.rootDir}`);
|
|
12434
|
+
lines.push(`State: ${status.stateDir}`);
|
|
12435
|
+
lines.push("");
|
|
12436
|
+
lines.push("Scene:");
|
|
12437
|
+
lines.push(`- Now: ${status.scene.headline}`);
|
|
12438
|
+
lines.push(`- Focus: ${status.scene.focus}`);
|
|
12439
|
+
lines.push(`- Next: ${status.scene.nextAction}`);
|
|
12440
|
+
lines.push(`- Blocked: ${status.scene.blocked}`);
|
|
12441
|
+
lines.push(`- Background: ${status.scene.background.active} active / ${status.scene.background.blocked} need attention`);
|
|
12442
|
+
lines.push(`- Background next: ${status.scene.background.nextAction}`);
|
|
12443
|
+
lines.push(`- Skills: ${status.scene.skills.ready}/${status.scene.skills.total} ready; ${status.scene.skills.nextAction}`);
|
|
12444
|
+
lines.push(`- Memory: ${status.scene.memory.assets} asset(s), session=${status.scene.memory.latestSessionMemory ? "yes" : "no"}; ${status.scene.memory.nextAction}`);
|
|
12445
|
+
lines.push(`- Cost: ${status.scene.cost}`);
|
|
12446
|
+
lines.push(`- Recovery: ${status.scene.recovery}`);
|
|
12447
|
+
lines.push("");
|
|
12448
|
+
lines.push("Current workspace:");
|
|
12449
|
+
lines.push(`- Focus: ${status.scene.focus}`);
|
|
12450
|
+
lines.push(`- Session: ${readSessionLine(status)}`);
|
|
12451
|
+
lines.push(`- Next: ${status.scene.nextAction}`);
|
|
12452
|
+
lines.push(`- Blocked: ${status.scene.blocked}`);
|
|
12453
|
+
lines.push(`- Context budget: ${readContextBudgetLine(status)}`);
|
|
12454
|
+
lines.push(`- Workset: ${status.sessions.latest?.workset ? `${status.sessions.latest.workset.total} file(s)` : "none"}`);
|
|
12455
|
+
lines.push(`- Memory: ${status.memory.assets.length > 0 ? `${status.memory.assets.length} asset(s)` : "none"}`);
|
|
12456
|
+
lines.push(`- Skills: ${status.skills.ready}/${status.skills.total} ready`);
|
|
12457
|
+
lines.push(`- Model cache: ${readModelCacheLine(status)}`);
|
|
12458
|
+
lines.push(`- Project map: ${status.projectMap ? "ready" : "missing"}`);
|
|
12459
|
+
lines.push(`- Executions: ${status.executions.active.length} active / ${status.executions.total} total`);
|
|
12460
|
+
lines.push(`- Wake signals: ${status.wakeSignals.recent.length}`);
|
|
12461
|
+
if (status.taskLifecycle) {
|
|
12462
|
+
lines.push("");
|
|
12463
|
+
lines.push("Task lifecycle:");
|
|
12464
|
+
lines.push([
|
|
12465
|
+
status.taskLifecycle.stage,
|
|
12466
|
+
status.taskLifecycle.reason ? `reason=${status.taskLifecycle.reason}` : void 0,
|
|
12467
|
+
status.taskLifecycle.updatedAt
|
|
12468
|
+
].filter(Boolean).join(" "));
|
|
12469
|
+
}
|
|
12470
|
+
if (status.sessions.latest) {
|
|
12471
|
+
lines.push("");
|
|
12472
|
+
lines.push("Latest session:");
|
|
12473
|
+
lines.push([
|
|
12474
|
+
status.sessions.latest.id,
|
|
12475
|
+
status.sessions.latest.title ?? "(untitled)",
|
|
12476
|
+
`messages=${status.sessions.latest.messageCount}`,
|
|
12477
|
+
status.sessions.latest.hasMemory ? "memory=yes" : "memory=no"
|
|
12478
|
+
].join(" "));
|
|
12479
|
+
}
|
|
12480
|
+
if (status.projectMap) {
|
|
12481
|
+
lines.push("");
|
|
12482
|
+
lines.push("Project map:");
|
|
12483
|
+
lines.push([
|
|
12484
|
+
`dirs=${status.projectMap.topLevelDirectories.slice(0, 6).join(", ") || "none"}`,
|
|
12485
|
+
`scripts=${status.projectMap.packageScripts.slice(0, 6).join(", ") || "none"}`,
|
|
12486
|
+
`tests=${status.projectMap.testDirectories.slice(0, 4).join(", ") || "none"}`,
|
|
12487
|
+
status.projectMap.git.available ? `git=${status.projectMap.git.hasChanges ? "changed" : "clean"}` : "git=unavailable"
|
|
12488
|
+
].join(" "));
|
|
12489
|
+
}
|
|
12490
|
+
if (status.sessions.latest?.workset?.files.length) {
|
|
12491
|
+
lines.push("");
|
|
12492
|
+
lines.push("Workset:");
|
|
12493
|
+
for (const file of status.sessions.latest.workset.files) {
|
|
12494
|
+
lines.push([
|
|
12495
|
+
file.path,
|
|
12496
|
+
`read=${file.readCount}`,
|
|
12497
|
+
`changed=${file.changedCount}`,
|
|
12498
|
+
`last=${file.lastTool}`,
|
|
12499
|
+
file.lastChangeId ? `change=${file.lastChangeId}` : void 0,
|
|
12500
|
+
file.reason ? `reason=${file.reason}` : void 0
|
|
12501
|
+
].filter(Boolean).join(" "));
|
|
12502
|
+
}
|
|
12503
|
+
}
|
|
12504
|
+
if (status.sessions.latest?.contextBudget?.promptHotspots.length) {
|
|
12505
|
+
lines.push("");
|
|
12506
|
+
lines.push("Context budget hotspots:");
|
|
12507
|
+
for (const hotspot of status.sessions.latest.contextBudget.promptHotspots.slice(0, 3)) {
|
|
12508
|
+
lines.push([
|
|
12509
|
+
hotspot.layer,
|
|
12510
|
+
hotspot.title,
|
|
12511
|
+
`chars=${hotspot.chars}`,
|
|
12512
|
+
`lines=${hotspot.lines}`
|
|
12513
|
+
].join(" "));
|
|
12514
|
+
}
|
|
12515
|
+
}
|
|
12516
|
+
if (status.sessions.latest?.contextBudget?.sources.length) {
|
|
12517
|
+
lines.push("");
|
|
12518
|
+
lines.push("Context budget sources:");
|
|
12519
|
+
for (const source of status.sessions.latest.contextBudget.sources) {
|
|
12520
|
+
lines.push([
|
|
12521
|
+
source.name,
|
|
12522
|
+
`chars=${source.chars}`,
|
|
12523
|
+
source.messages === void 0 ? void 0 : `messages=${source.messages}`
|
|
12524
|
+
].filter(Boolean).join(" "));
|
|
12525
|
+
}
|
|
12526
|
+
}
|
|
12527
|
+
if (status.sessions.latest?.contextBudget?.cacheLayout) {
|
|
12528
|
+
const layout = status.sessions.latest.contextBudget.cacheLayout;
|
|
12529
|
+
const totalChars = layout.stablePrefixChars + layout.volatileTailChars;
|
|
12530
|
+
const stableRatio = totalChars > 0 ? `${Math.round(layout.stablePrefixChars / totalChars * 100)}%` : "unknown";
|
|
12531
|
+
lines.push("");
|
|
12532
|
+
lines.push("Cache layout:");
|
|
12533
|
+
lines.push([
|
|
12534
|
+
`stable=${layout.stablePrefixFingerprint}`,
|
|
12535
|
+
`stableChars=${layout.stablePrefixChars}`,
|
|
12536
|
+
`tail=${layout.volatileTailFingerprint}`,
|
|
12537
|
+
`tailChars=${layout.volatileTailChars}`,
|
|
12538
|
+
`stableRatio=${stableRatio}`
|
|
12539
|
+
].join(" "));
|
|
12540
|
+
lines.push([
|
|
12541
|
+
`stableSources=${layout.stableSources.join(",") || "none"}`,
|
|
12542
|
+
`volatileSources=${layout.volatileSources.join(",") || "none"}`
|
|
12543
|
+
].join(" "));
|
|
12544
|
+
}
|
|
12545
|
+
if (status.modelRequests.recent.length > 0) {
|
|
12546
|
+
lines.push("");
|
|
12547
|
+
lines.push("Recent model requests:");
|
|
12548
|
+
for (const request of status.modelRequests.recent.slice(0, 5)) {
|
|
12549
|
+
lines.push([
|
|
12550
|
+
request.model ?? "unknown-model",
|
|
12551
|
+
request.provider ? `provider=${request.provider}` : void 0,
|
|
12552
|
+
request.durationMs === void 0 ? void 0 : `duration=${request.durationMs}ms`,
|
|
12553
|
+
request.usage ? formatUsage(request.usage) : "usage=unavailable"
|
|
12554
|
+
].filter(Boolean).join(" "));
|
|
12555
|
+
}
|
|
12556
|
+
}
|
|
12557
|
+
if (status.executions.active.length > 0) {
|
|
12558
|
+
lines.push("");
|
|
12559
|
+
lines.push("Active executions:");
|
|
12560
|
+
for (const execution of status.scene.executions) {
|
|
12561
|
+
lines.push([
|
|
12562
|
+
execution.id,
|
|
12563
|
+
execution.kind,
|
|
12564
|
+
execution.status,
|
|
12565
|
+
`risk=${execution.risk}`,
|
|
12566
|
+
`summary=${truncateCliValue(execution.summary, 80)}`,
|
|
12567
|
+
`next=${execution.nextAction}`
|
|
12568
|
+
].filter(Boolean).join(" "));
|
|
12569
|
+
if (execution.lastOutput) {
|
|
12570
|
+
lines.push(` lastOutput=${execution.lastOutput}`);
|
|
12571
|
+
}
|
|
12572
|
+
}
|
|
12573
|
+
}
|
|
12574
|
+
if (status.executions.recent.length > 0) {
|
|
12575
|
+
lines.push("");
|
|
12576
|
+
lines.push("Recent executions:");
|
|
12577
|
+
for (const execution of status.executions.recent.slice(0, 5)) {
|
|
12578
|
+
lines.push([
|
|
12579
|
+
execution.id,
|
|
12580
|
+
execution.kind,
|
|
12581
|
+
execution.status,
|
|
12582
|
+
execution.actorName ? `actor=${execution.actorName}` : void 0,
|
|
12583
|
+
execution.summary ? truncateCliValue(execution.summary, 80) : void 0,
|
|
12584
|
+
execution.assignment?.expectedOutput ? `expected=${truncateCliValue(execution.assignment.expectedOutput, 60)}` : void 0
|
|
12585
|
+
].filter(Boolean).join(" "));
|
|
12586
|
+
}
|
|
12587
|
+
}
|
|
12588
|
+
if (status.memory.assets.length > 0) {
|
|
12589
|
+
lines.push("");
|
|
12590
|
+
lines.push("Memory:");
|
|
12591
|
+
for (const memory of status.memory.assets.slice(0, 5)) {
|
|
12592
|
+
lines.push([
|
|
12593
|
+
memory.id,
|
|
12594
|
+
memory.kind,
|
|
12595
|
+
`bytes=${memory.size}`,
|
|
12596
|
+
memory.evidenceRefs.length > 0 ? `evidence=${memory.evidenceRefs.join(",")}` : void 0,
|
|
12597
|
+
memory.path
|
|
12598
|
+
].filter(Boolean).join(" "));
|
|
12599
|
+
}
|
|
12600
|
+
}
|
|
12601
|
+
if (status.skills.needsAttention.length > 0) {
|
|
12602
|
+
lines.push("");
|
|
12603
|
+
lines.push("Skills needing attention:");
|
|
12604
|
+
for (const skill of status.skills.needsAttention) {
|
|
12605
|
+
lines.push([
|
|
12606
|
+
skill.name,
|
|
12607
|
+
skill.path,
|
|
12608
|
+
`resources=${skill.resources}`,
|
|
12609
|
+
`dependencies=${skill.dependencies}`,
|
|
12610
|
+
skill.issues.length > 0 ? `issues=${skill.issues.join("; ")}` : void 0
|
|
12611
|
+
].filter(Boolean).join(" "));
|
|
12612
|
+
}
|
|
12613
|
+
}
|
|
12614
|
+
return `${lines.join("\n")}
|
|
12615
|
+
`;
|
|
12616
|
+
}
|
|
12617
|
+
function readSessionLine(status) {
|
|
12618
|
+
if (!status.sessions.latest) {
|
|
12619
|
+
return "none";
|
|
12620
|
+
}
|
|
12621
|
+
return `${status.sessions.latest.id} (${status.sessions.latest.messageCount} message(s))`;
|
|
12622
|
+
}
|
|
12623
|
+
function readContextBudgetLine(status) {
|
|
12624
|
+
const budget = status.sessions.latest?.contextBudget;
|
|
12625
|
+
if (!budget) {
|
|
12626
|
+
return "none";
|
|
12627
|
+
}
|
|
12628
|
+
const percent = Math.round(budget.usageRatio * 100);
|
|
12629
|
+
return [
|
|
12630
|
+
`${budget.estimatedChars}/${budget.limitChars} chars`,
|
|
12631
|
+
`${percent}%`,
|
|
12632
|
+
budget.compressed ? `compressed=${budget.compressionMode}` : "compressed=no",
|
|
12633
|
+
`reason=${budget.compressionReason}`
|
|
12634
|
+
].join(" ");
|
|
12635
|
+
}
|
|
12636
|
+
function readModelCacheLine(status) {
|
|
12637
|
+
const latest = status.modelRequests.recent[0];
|
|
12638
|
+
if (!latest) {
|
|
12639
|
+
return "none";
|
|
12640
|
+
}
|
|
12641
|
+
if (!latest.usage) {
|
|
12642
|
+
return latest.usageAvailable ? "usage unavailable" : "usage unavailable from provider";
|
|
12643
|
+
}
|
|
12644
|
+
const cacheTokens = latest.usage.cacheHitTokens ?? latest.usage.cacheReadTokens;
|
|
12645
|
+
const missTokens = latest.usage.cacheMissTokens;
|
|
12646
|
+
const rate = latest.usage.cacheHitRate === void 0 ? void 0 : `${Math.round(latest.usage.cacheHitRate * 100)}%`;
|
|
12647
|
+
return [
|
|
12648
|
+
cacheTokens === void 0 ? "cached=unknown" : `cached=${cacheTokens}`,
|
|
12649
|
+
missTokens === void 0 ? void 0 : `miss=${missTokens}`,
|
|
12650
|
+
rate ? `hit=${rate}` : void 0
|
|
12651
|
+
].filter(Boolean).join(" ");
|
|
12652
|
+
}
|
|
12653
|
+
function formatUsage(usage) {
|
|
12654
|
+
return [
|
|
12655
|
+
usage.inputTokens === void 0 ? void 0 : `input=${usage.inputTokens}`,
|
|
12656
|
+
usage.outputTokens === void 0 ? void 0 : `output=${usage.outputTokens}`,
|
|
12657
|
+
usage.reasoningTokens === void 0 ? void 0 : `reasoning=${usage.reasoningTokens}`,
|
|
12658
|
+
usage.cacheHitTokens === void 0 ? void 0 : `cacheHit=${usage.cacheHitTokens}`,
|
|
12659
|
+
usage.cacheReadTokens === void 0 ? void 0 : `cacheRead=${usage.cacheReadTokens}`,
|
|
12660
|
+
usage.cacheCreationTokens === void 0 ? void 0 : `cacheWrite=${usage.cacheCreationTokens}`,
|
|
12661
|
+
usage.cacheMissTokens === void 0 ? void 0 : `cacheMiss=${usage.cacheMissTokens}`,
|
|
12662
|
+
usage.cacheHitRate === void 0 ? void 0 : `hit=${Math.round(usage.cacheHitRate * 100)}%`
|
|
12663
|
+
].filter(Boolean).join(" ");
|
|
12664
|
+
}
|
|
12665
|
+
var init_runtimeStatusPresenter = __esm({
|
|
12666
|
+
"src/cli/commands/runtimeStatusPresenter.ts"() {
|
|
12667
|
+
"use strict";
|
|
12668
|
+
init_cliValues();
|
|
12669
|
+
}
|
|
12670
|
+
});
|
|
12671
|
+
|
|
12160
12672
|
// src/agent/turn/persistence.ts
|
|
12161
12673
|
async function initializeTurnSession(session, input, sessionStore, source = "external") {
|
|
12162
12674
|
const appended = await sessionStore.appendMessages(session, [
|
|
@@ -226726,14 +227238,6 @@ function createWebInputPort(wss) {
|
|
|
226726
227238
|
pendingResolve = resolve;
|
|
226727
227239
|
});
|
|
226728
227240
|
},
|
|
226729
|
-
readMultiline(_promptLabel) {
|
|
226730
|
-
return this.readInput(_promptLabel).then((result) => {
|
|
226731
|
-
if (result.kind === "submit") {
|
|
226732
|
-
return { kind: "submit", value: result.value };
|
|
226733
|
-
}
|
|
226734
|
-
return { kind: "cancel" };
|
|
226735
|
-
});
|
|
226736
|
-
},
|
|
226737
227241
|
bindInterrupt(handler) {
|
|
226738
227242
|
interruptHandlers.add(handler);
|
|
226739
227243
|
return () => {
|
|
@@ -227231,6 +227735,9 @@ var init_lifecycle2 = __esm({
|
|
|
227231
227735
|
function listEvaluationChecks() {
|
|
227232
227736
|
return [...EVALUATION_CHECK_IDS];
|
|
227233
227737
|
}
|
|
227738
|
+
function listEvaluationScenarios() {
|
|
227739
|
+
return [...EVALUATION_SCENARIOS];
|
|
227740
|
+
}
|
|
227234
227741
|
async function runEvaluationCheck(id, rootDir) {
|
|
227235
227742
|
try {
|
|
227236
227743
|
switch (id) {
|
|
@@ -227267,6 +227774,9 @@ async function runEvaluationCheck(id, rootDir) {
|
|
|
227267
227774
|
case "cache-economy-ready": {
|
|
227268
227775
|
return await runCacheEconomyCheck(id);
|
|
227269
227776
|
}
|
|
227777
|
+
case "production-scene-ready": {
|
|
227778
|
+
return await runProductionSceneCheck(id, rootDir);
|
|
227779
|
+
}
|
|
227270
227780
|
case "host-turn-boundary-runs": {
|
|
227271
227781
|
return await runHostTurnBoundaryCheck(id, rootDir);
|
|
227272
227782
|
}
|
|
@@ -227291,6 +227801,7 @@ async function runCacheEconomyCheck(id) {
|
|
|
227291
227801
|
const { resolveProviderCachePolicy: resolveProviderCachePolicy2 } = await Promise.resolve().then(() => (init_cachePolicy(), cachePolicy_exports));
|
|
227292
227802
|
const { buildCompressedContextRequest: buildCompressedContextRequest2 } = await Promise.resolve().then(() => (init_builder(), builder_exports));
|
|
227293
227803
|
const { buildContextRuntimePromptLayers: buildContextRuntimePromptLayers2 } = await Promise.resolve().then(() => (init_prompt3(), prompt_exports));
|
|
227804
|
+
const { renderPromptLayers: renderPromptLayers2 } = await Promise.resolve().then(() => (init_format(), format_exports));
|
|
227294
227805
|
const { getInitialRuntimeConfig: getInitialRuntimeConfig2 } = await Promise.resolve().then(() => (init_initialConfig(), initialConfig_exports));
|
|
227295
227806
|
const { getAppPaths: getAppPaths2 } = await Promise.resolve().then(() => (init_paths(), paths_exports));
|
|
227296
227807
|
const { resolveTelegramRuntimeConfig: resolveTelegramRuntimeConfig2 } = await Promise.resolve().then(() => (init_hosts(), hosts_exports));
|
|
@@ -227326,7 +227837,7 @@ async function runCacheEconomyCheck(id) {
|
|
|
227326
227837
|
instructionText: "",
|
|
227327
227838
|
instructionTruncated: false,
|
|
227328
227839
|
ignoreRules: [],
|
|
227329
|
-
skills: []
|
|
227840
|
+
skills: [buildCostSkillFixture()]
|
|
227330
227841
|
};
|
|
227331
227842
|
const firstPrompt = buildContextRuntimePromptLayers2({
|
|
227332
227843
|
cwd: process.cwd(),
|
|
@@ -227382,18 +227893,37 @@ async function runCacheEconomyCheck(id) {
|
|
|
227382
227893
|
};
|
|
227383
227894
|
const first = buildCompressedContextRequest2(
|
|
227384
227895
|
firstPrompt,
|
|
227385
|
-
[
|
|
227896
|
+
[
|
|
227897
|
+
{ role: "user", content: "first", createdAt: "2026-06-16T00:00:00.000Z" },
|
|
227898
|
+
{ role: "tool", name: "bash", content: `large output ${"x".repeat(2e4)}`, createdAt: "2026-06-16T00:00:01.000Z" }
|
|
227899
|
+
],
|
|
227386
227900
|
requestConfig
|
|
227387
227901
|
);
|
|
227388
227902
|
const second = buildCompressedContextRequest2(
|
|
227389
227903
|
secondPrompt,
|
|
227390
227904
|
[
|
|
227391
227905
|
{ role: "user", content: "first", createdAt: "2026-06-16T00:00:00.000Z" },
|
|
227906
|
+
{ role: "tool", name: "bash", content: `large output ${"x".repeat(2e4)}`, createdAt: "2026-06-16T00:00:01.000Z" },
|
|
227392
227907
|
{ role: "user", content: "second", createdAt: "2026-06-16T00:01:00.000Z" }
|
|
227393
227908
|
],
|
|
227394
227909
|
requestConfig
|
|
227395
227910
|
);
|
|
227396
|
-
|
|
227911
|
+
const compactedLargeOutput = buildCompressedContextRequest2(
|
|
227912
|
+
firstPrompt,
|
|
227913
|
+
[
|
|
227914
|
+
{ role: "user", content: "large output", createdAt: "2026-06-16T00:00:00.000Z" },
|
|
227915
|
+
{ role: "tool", name: "bash", content: `large output ${"x".repeat(2e4)}`, createdAt: "2026-06-16T00:00:01.000Z" },
|
|
227916
|
+
{ role: "user", content: "continue", createdAt: "2026-06-16T00:00:02.000Z" }
|
|
227917
|
+
],
|
|
227918
|
+
{
|
|
227919
|
+
contextWindowMessages: 3,
|
|
227920
|
+
model: "gpt-5.5",
|
|
227921
|
+
maxContextChars: 8e3,
|
|
227922
|
+
contextSummaryChars: 600
|
|
227923
|
+
}
|
|
227924
|
+
);
|
|
227925
|
+
const renderedPrompt = renderPromptLayers2(firstPrompt);
|
|
227926
|
+
if (deepSeek?.cacheHitRate !== 0.8 || openai?.cacheReadTokens !== 960 || !policy.promptCacheKey || first.cacheLayout?.stablePrefixFingerprint !== second.cacheLayout?.stablePrefixFingerprint || first.cacheLayout?.volatileTailFingerprint === second.cacheLayout?.volatileTailFingerprint || renderedPrompt.includes("FULL_SKILL_BODY_MUST_NOT_ENTER_DEFAULT_CONTEXT") || !renderedPrompt.includes("cost-skill") || (compactedLargeOutput.cacheLayout?.volatileTailChars ?? Number.POSITIVE_INFINITY) >= 2e4) {
|
|
227397
227927
|
return {
|
|
227398
227928
|
id,
|
|
227399
227929
|
status: "failed",
|
|
@@ -227402,9 +227932,141 @@ async function runCacheEconomyCheck(id) {
|
|
|
227402
227932
|
}
|
|
227403
227933
|
return passed(
|
|
227404
227934
|
id,
|
|
227405
|
-
`cache economy ready: deepseekHit=${deepSeek?.cacheHitRate}, openaiCached=${openai?.cacheReadTokens}, stablePrefix=${first.cacheLayout?.stablePrefixFingerprint ?? "unknown"}`
|
|
227935
|
+
`cache economy ready: deepseekHit=${deepSeek?.cacheHitRate}, openaiCached=${openai?.cacheReadTokens}, stablePrefix=${first.cacheLayout?.stablePrefixFingerprint ?? "unknown"}, stableChars=${first.cacheLayout?.stablePrefixChars ?? 0}, compactedTailChars=${compactedLargeOutput.cacheLayout?.volatileTailChars ?? 0}, skillIndex=only`
|
|
227406
227936
|
);
|
|
227407
227937
|
}
|
|
227938
|
+
async function runProductionSceneCheck(id, rootDir) {
|
|
227939
|
+
const { buildRuntimeStatus: buildRuntimeStatus2 } = await Promise.resolve().then(() => (init_status(), status_exports));
|
|
227940
|
+
const { formatRuntimeStatusText: formatRuntimeStatusText2 } = await Promise.resolve().then(() => (init_runtimeStatusPresenter(), runtimeStatusPresenter_exports));
|
|
227941
|
+
const { ControlPlaneLedger: ControlPlaneLedger2 } = await Promise.resolve().then(() => (init_ledger(), ledger_exports));
|
|
227942
|
+
const { SessionStore: SessionStore2 } = await Promise.resolve().then(() => (init_store3(), store_exports2));
|
|
227943
|
+
const workspace = await prepareCheckWorkspace(rootDir, "production-scene");
|
|
227944
|
+
await import_promises33.default.mkdir(import_node_path46.default.join(workspace, "skills", "scene-skill"), { recursive: true });
|
|
227945
|
+
await import_promises33.default.writeFile(
|
|
227946
|
+
import_node_path46.default.join(workspace, "skills", "scene-skill", "SKILL.md"),
|
|
227947
|
+
[
|
|
227948
|
+
"---",
|
|
227949
|
+
"name: scene-skill",
|
|
227950
|
+
"description: Checks production scene readiness.",
|
|
227951
|
+
"requires: node",
|
|
227952
|
+
"---",
|
|
227953
|
+
"Use when validating production runtime scene."
|
|
227954
|
+
].join("\n"),
|
|
227955
|
+
"utf8"
|
|
227956
|
+
);
|
|
227957
|
+
const sessionStore = new SessionStore2(import_node_path46.default.join(workspace, ".kitty", "sessions"), {
|
|
227958
|
+
memorySessionsDir: import_node_path46.default.join(workspace, ".kitty", "memory", "sessions")
|
|
227959
|
+
});
|
|
227960
|
+
const session = await sessionStore.save({
|
|
227961
|
+
...await sessionStore.create(workspace),
|
|
227962
|
+
title: "Production scene check",
|
|
227963
|
+
sessionMemory: {
|
|
227964
|
+
version: 1,
|
|
227965
|
+
summary: "User needs production runtime visibility.",
|
|
227966
|
+
updatedAt: "2026-06-18T00:00:00.000Z"
|
|
227967
|
+
},
|
|
227968
|
+
contextBudget: {
|
|
227969
|
+
version: 1,
|
|
227970
|
+
limitChars: 1e5,
|
|
227971
|
+
estimatedChars: 5e4,
|
|
227972
|
+
remainingChars: 5e4,
|
|
227973
|
+
usageRatio: 0.5,
|
|
227974
|
+
compressed: false,
|
|
227975
|
+
compressionMode: "none",
|
|
227976
|
+
compressionReason: "within_budget",
|
|
227977
|
+
sources: [{ name: "nearFieldConversation", chars: 2e4, messages: 4 }],
|
|
227978
|
+
promptHotspots: [],
|
|
227979
|
+
cacheLayout: {
|
|
227980
|
+
stablePrefixFingerprint: "scene-stable",
|
|
227981
|
+
volatileTailFingerprint: "scene-tail",
|
|
227982
|
+
stablePrefixChars: 3e4,
|
|
227983
|
+
volatileTailChars: 2e4,
|
|
227984
|
+
stableSources: ["staticPrompt"],
|
|
227985
|
+
volatileSources: ["runtimeFacts", "nearFieldConversation"]
|
|
227986
|
+
}
|
|
227987
|
+
}
|
|
227988
|
+
});
|
|
227989
|
+
const eventsDir = import_node_path46.default.join(workspace, ".kitty", "observability", "events");
|
|
227990
|
+
await import_promises33.default.mkdir(eventsDir, { recursive: true });
|
|
227991
|
+
await import_promises33.default.writeFile(
|
|
227992
|
+
import_node_path46.default.join(eventsDir, "2026-06-18.jsonl"),
|
|
227993
|
+
JSON.stringify({
|
|
227994
|
+
version: 1,
|
|
227995
|
+
timestamp: "2026-06-18T00:00:00.000Z",
|
|
227996
|
+
event: "model.request",
|
|
227997
|
+
status: "completed",
|
|
227998
|
+
model: "gpt-5.5",
|
|
227999
|
+
durationMs: 123,
|
|
228000
|
+
details: {
|
|
228001
|
+
provider: "openai",
|
|
228002
|
+
usageAvailable: true,
|
|
228003
|
+
usage: {
|
|
228004
|
+
totalTokens: 1e3,
|
|
228005
|
+
cacheReadTokens: 700,
|
|
228006
|
+
cacheMissTokens: 300,
|
|
228007
|
+
cacheHitRate: 0.7
|
|
228008
|
+
}
|
|
228009
|
+
}
|
|
228010
|
+
}) + "\n",
|
|
228011
|
+
"utf8"
|
|
228012
|
+
);
|
|
228013
|
+
const ledger = new ControlPlaneLedger2(workspace);
|
|
228014
|
+
try {
|
|
228015
|
+
ledger.executions.create({
|
|
228016
|
+
kind: "background",
|
|
228017
|
+
status: "running",
|
|
228018
|
+
command: "long production task",
|
|
228019
|
+
cwd: workspace,
|
|
228020
|
+
requestedBy: "lead",
|
|
228021
|
+
pid: process.pid,
|
|
228022
|
+
sessionId: session.id
|
|
228023
|
+
});
|
|
228024
|
+
} finally {
|
|
228025
|
+
ledger.close();
|
|
228026
|
+
}
|
|
228027
|
+
const status = await buildRuntimeStatus2(workspace);
|
|
228028
|
+
const text = formatRuntimeStatusText2(status);
|
|
228029
|
+
if (status.scene.background.active !== 1 || status.scene.background.blocked !== 1 || !status.scene.cost.includes("1000 tokens") || !status.scene.cost.includes("700 cached") || status.scene.skills.ready < 1 || status.scene.memory.assets < 1 || !status.scene.memory.latestSessionMemory || status.skills.ready < 1 || status.memory.assets.length < 1 || !text.includes("Scene:") || !text.includes("Background next:") || !text.includes("Cost:")) {
|
|
228030
|
+
return {
|
|
228031
|
+
id,
|
|
228032
|
+
status: "failed",
|
|
228033
|
+
fact: `production scene incomplete: background=${status.scene.background.active}/${status.scene.background.blocked}, skills=${status.skills.ready}/${status.skills.total}, memory=${status.memory.assets.length}, cost=${status.scene.cost}`
|
|
228034
|
+
};
|
|
228035
|
+
}
|
|
228036
|
+
return passed(
|
|
228037
|
+
id,
|
|
228038
|
+
`production scene ready: background=${status.scene.background.active}/${status.scene.background.blocked}, skills=${status.skills.ready}/${status.skills.total}, memory=${status.memory.assets.length}, cost=${status.scene.cost}`
|
|
228039
|
+
);
|
|
228040
|
+
}
|
|
228041
|
+
function buildCostSkillFixture() {
|
|
228042
|
+
return {
|
|
228043
|
+
name: "cost-skill",
|
|
228044
|
+
description: "Loaded only when needed.",
|
|
228045
|
+
path: "skills/cost-skill/SKILL.md",
|
|
228046
|
+
absolutePath: "skills/cost-skill/SKILL.md",
|
|
228047
|
+
body: "FULL_SKILL_BODY_MUST_NOT_ENTER_DEFAULT_CONTEXT",
|
|
228048
|
+
dependencies: [],
|
|
228049
|
+
resources: [{
|
|
228050
|
+
path: "references/cost.md",
|
|
228051
|
+
size: 1e5,
|
|
228052
|
+
kind: "references"
|
|
228053
|
+
}],
|
|
228054
|
+
health: {
|
|
228055
|
+
status: "ready",
|
|
228056
|
+
bodyPresent: true,
|
|
228057
|
+
resourceCount: 1,
|
|
228058
|
+
dependencyCount: 0,
|
|
228059
|
+
resourceGroups: {
|
|
228060
|
+
references: 1,
|
|
228061
|
+
scripts: 0,
|
|
228062
|
+
examples: 0,
|
|
228063
|
+
assets: 0,
|
|
228064
|
+
other: 0
|
|
228065
|
+
},
|
|
228066
|
+
issues: []
|
|
228067
|
+
}
|
|
228068
|
+
};
|
|
228069
|
+
}
|
|
227408
228070
|
async function runHostTurnBoundaryCheck(id, rootDir) {
|
|
227409
228071
|
const { runHostTurn: runHostTurn2 } = await Promise.resolve().then(() => (init_turn2(), turn_exports));
|
|
227410
228072
|
const { SessionEventStore: SessionEventStore2 } = await Promise.resolve().then(() => (init_events(), events_exports));
|
|
@@ -227602,7 +228264,7 @@ async function closeWebSocketServer(wss) {
|
|
|
227602
228264
|
});
|
|
227603
228265
|
});
|
|
227604
228266
|
}
|
|
227605
|
-
var import_promises33, import_node_path46, import_node_events, import_ws, EVALUATION_CHECK_IDS;
|
|
228267
|
+
var import_promises33, import_node_path46, import_node_events, import_ws, EVALUATION_CHECK_IDS, EVALUATION_SCENARIOS;
|
|
227606
228268
|
var init_checks = __esm({
|
|
227607
228269
|
"src/evaluation/checks.ts"() {
|
|
227608
228270
|
"use strict";
|
|
@@ -227619,10 +228281,79 @@ var init_checks = __esm({
|
|
|
227619
228281
|
"skill-packages-readable",
|
|
227620
228282
|
"config-preflight-readable",
|
|
227621
228283
|
"cache-economy-ready",
|
|
228284
|
+
"production-scene-ready",
|
|
227622
228285
|
"host-turn-boundary-runs",
|
|
227623
228286
|
"remote-entrypoints-available",
|
|
227624
228287
|
"recovery-drills-pass"
|
|
227625
228288
|
];
|
|
228289
|
+
EVALUATION_SCENARIOS = [
|
|
228290
|
+
{
|
|
228291
|
+
id: "runtime-status-builds",
|
|
228292
|
+
title: "\u5F53\u524D\u73B0\u573A\u53EF\u5BA1\u9605",
|
|
228293
|
+
userPath: "\u7528\u6237\u8FD0\u884C `kitty status` \u65F6\uFF0C\u53EF\u4EE5\u770B\u5230 session\u3001context\u3001memory\u3001skills\u3001execution \u548C cache \u7684\u5F53\u524D\u4E8B\u5B9E\u3002",
|
|
228294
|
+
evidence: "\u6784\u5EFA runtime status\uFF0C\u5E76\u786E\u8BA4 sessions / executions \u7B49\u73B0\u573A\u6458\u8981\u53EF\u7528\u3002"
|
|
228295
|
+
},
|
|
228296
|
+
{
|
|
228297
|
+
id: "project-map-builds",
|
|
228298
|
+
title: "\u8FDB\u5165\u4ED3\u5E93\u80FD\u5FEB\u901F\u5B9A\u5411",
|
|
228299
|
+
userPath: "\u7528\u6237\u628A Kitty \u6253\u5F00\u5728\u4E00\u4E2A\u4ED3\u5E93\u91CC\uFF0C\u6A21\u578B\u80FD\u770B\u5230\u76EE\u5F55\u3001\u5165\u53E3\u3001\u811A\u672C\u3001\u6D4B\u8BD5\u3001\u9879\u76EE\u6587\u6863\u548C git \u4E8B\u5B9E\u3002",
|
|
228300
|
+
evidence: "\u6784\u5EFA project map\uFF0C\u5E76\u786E\u8BA4\u76EE\u5F55\u3001\u811A\u672C\u548C\u4ED3\u5E93\u4E8B\u5B9E\u53EF\u8BFB\u3002"
|
|
228301
|
+
},
|
|
228302
|
+
{
|
|
228303
|
+
id: "memory-assets-readable",
|
|
228304
|
+
title: "\u8BB0\u5FC6\u8D44\u4EA7\u53EF\u5BA1\u9605",
|
|
228305
|
+
userPath: "\u7528\u6237\u53EF\u4EE5\u67E5\u770B session/project/user/evidence memory\uFF0C\u4E0D\u9760\u9690\u85CF\u4E0A\u4E0B\u6587\u731C\u5386\u53F2\u3002",
|
|
228306
|
+
evidence: "\u679A\u4E3E runtime memory assets\uFF0C\u5E76\u786E\u8BA4\u8D44\u4EA7\u7D22\u5F15\u53EF\u8BFB\u3002"
|
|
228307
|
+
},
|
|
228308
|
+
{
|
|
228309
|
+
id: "extension-surface-current",
|
|
228310
|
+
title: "\u5DE5\u5177\u9762\u53EA\u66B4\u9732\u5F53\u524D\u80FD\u529B",
|
|
228311
|
+
userPath: "\u9ED8\u8BA4 agent \u6253\u5F00\u5F53\u524D\u771F\u5B9E extensions\uFF0C\u4E0D\u590D\u6D3B\u5DF2\u5220\u9664\u80FD\u529B\u3002",
|
|
228312
|
+
evidence: "\u8BFB\u53D6 extension registry\uFF0C\u5E76\u786E\u8BA4\u9ED8\u8BA4\u542F\u7528\u9762\u6765\u81EA\u5F53\u524D\u5B9A\u4E49\u3002"
|
|
228313
|
+
},
|
|
228314
|
+
{
|
|
228315
|
+
id: "skill-packages-readable",
|
|
228316
|
+
title: "\u65B9\u6CD5\u5305\u6309\u9700\u53EF\u7528",
|
|
228317
|
+
userPath: "\u6A21\u578B\u80FD\u5148\u770B\u5230 skill \u7D22\u5F15\uFF0C\u5FC5\u8981\u65F6\u518D\u52A0\u8F7D\u6B63\u6587\u3001\u8D44\u6E90\u6216\u811A\u672C\u3002",
|
|
228318
|
+
evidence: "\u52A0\u8F7D project context\uFF0C\u5E76\u786E\u8BA4 runtime skills \u53EF\u53D1\u73B0\u3002"
|
|
228319
|
+
},
|
|
228320
|
+
{
|
|
228321
|
+
id: "config-preflight-readable",
|
|
228322
|
+
title: "\u9996\u6B21\u914D\u7F6E\u8DEF\u5F84\u6E05\u695A",
|
|
228323
|
+
userPath: "\u7528\u6237\u8FD0\u884C `kitty init` / `kitty doctor` \u540E\uFF0C\u80FD\u77E5\u9053 `.kitty/.env` \u662F\u5426\u5B8C\u6574\u3001\u4E0B\u4E00\u6B65\u8865\u4EC0\u4E48\u3002",
|
|
228324
|
+
evidence: "\u6267\u884C config preflight\uFF0C\u5E76\u786E\u8BA4\u672C\u5730\u6A21\u677F\u548C env contract \u53EF\u68C0\u67E5\u3002"
|
|
228325
|
+
},
|
|
228326
|
+
{
|
|
228327
|
+
id: "cache-economy-ready",
|
|
228328
|
+
title: "\u6210\u672C\u4E8B\u5B9E\u53EF\u5BA1\u9605",
|
|
228329
|
+
userPath: "\u7528\u6237\u80FD\u770B\u5230 provider usage\u3001cache hit/miss\u3001\u7A33\u5B9A\u524D\u7F00\u548C\u6309\u9700 skill \u8FB9\u754C\uFF0C\u800C\u4E0D\u662F\u53EA\u770B\u5230 token \u603B\u6570\u3002",
|
|
228330
|
+
evidence: "\u9A8C\u8BC1 usage \u5F52\u4E00\u5316\u3001provider cache policy\u3001stable/volatile prompt fingerprint\u3001skill index boundary \u548C\u5927\u8F93\u51FA\u538B\u7F29\u3002"
|
|
228331
|
+
},
|
|
228332
|
+
{
|
|
228333
|
+
id: "production-scene-ready",
|
|
228334
|
+
title: "\u751F\u4EA7\u73B0\u573A\u4E00\u773C\u53EF\u8BFB",
|
|
228335
|
+
userPath: "\u7528\u6237\u8FD0\u884C `kitty status` \u6216 `kitty background` \u65F6\uFF0C\u80FD\u770B\u5230\u5F53\u524D\u73B0\u573A\u3001\u540E\u53F0\u98CE\u9669\u3001\u4E0B\u4E00\u6B65\u3001\u6062\u590D\u72B6\u6001\u3001\u6210\u672C\u3001skill \u548C memory \u53EF\u5BA1\u9605\u6027\u3002",
|
|
228336
|
+
evidence: "\u6784\u5EFA\u5E26 session\u3001memory\u3001cache\u3001skill\u3001background \u548C provider usage \u7684 runtime scene\uFF0C\u5E76\u786E\u8BA4 scene \u4E0E CLI \u6587\u672C\u90FD\u66B4\u9732\u5173\u952E\u4E8B\u5B9E\u3002"
|
|
228337
|
+
},
|
|
228338
|
+
{
|
|
228339
|
+
id: "host-turn-boundary-runs",
|
|
228340
|
+
title: "\u4E00\u6B21 agent turn \u6709\u660E\u786E\u8FB9\u754C",
|
|
228341
|
+
userPath: "\u7528\u6237\u53D1\u8D77\u4E00\u6B21\u4EFB\u52A1\u540E\uFF0Chost \u80FD\u8BB0\u5F55 turn \u5F00\u59CB\u3001\u5B8C\u6210\u3001\u5931\u8D25\u6216\u4E2D\u65AD\uFF0C\u4E0D\u628A\u5185\u90E8\u4E8B\u5B9E\u5199\u6210\u7528\u6237\u610F\u56FE\u3002",
|
|
228342
|
+
evidence: "\u7528\u5047 turn \u8DD1 host boundary\uFF0C\u5E76\u786E\u8BA4 session events \u95ED\u73AF\u3002"
|
|
228343
|
+
},
|
|
228344
|
+
{
|
|
228345
|
+
id: "remote-entrypoints-available",
|
|
228346
|
+
title: "\u8FDC\u7A0B\u5165\u53E3\u590D\u7528\u540C\u4E00\u4E3B\u5E72",
|
|
228347
|
+
userPath: "Web / Telegram \u5165\u53E3\u80FD\u63A5\u5165\u540C\u4E00 turn \u8F93\u5165\uFF0C\u4E0D\u5206\u88C2\u6210\u53E6\u4E00\u5957 agent\u3002",
|
|
228348
|
+
evidence: "\u9A8C\u8BC1 web input port\u3001HTML shell \u548C Telegram file turn input \u53EF\u7528\u3002"
|
|
228349
|
+
},
|
|
228350
|
+
{
|
|
228351
|
+
id: "recovery-drills-pass",
|
|
228352
|
+
title: "\u540E\u53F0\u548C\u5B50\u6267\u884C\u53EF\u6062\u590D",
|
|
228353
|
+
userPath: "background \u6216 subagent \u5361\u4F4F\u3001\u6D88\u5931\u3001\u8D85\u65F6\u540E\uFF0CKitty \u80FD reconcile\u3001\u6682\u505C\u7B49\u5F85\u6216\u7EC8\u6B62\u73B0\u573A\u3002",
|
|
228354
|
+
evidence: "\u6F14\u7EC3 stale background\u3001expired lead-wait subagent\u3001running process termination \u548C runtime status\u3002"
|
|
228355
|
+
}
|
|
228356
|
+
];
|
|
227626
228357
|
}
|
|
227627
228358
|
});
|
|
227628
228359
|
|
|
@@ -227645,22 +228376,25 @@ var init_harness = __esm({
|
|
|
227645
228376
|
|
|
227646
228377
|
// src/cli/commands/evaluation.ts
|
|
227647
228378
|
function registerEvaluationCommand(program, options = {}) {
|
|
227648
|
-
program.command("eval").description("List or run
|
|
227649
|
-
const
|
|
228379
|
+
program.command("eval").description("List or run product acceptance scenarios.").option("--json", "Print structured JSON.").option("--run", "Run all local evaluation checks.").action(async (commandOptions) => {
|
|
228380
|
+
const scenarios = listEvaluationScenarios();
|
|
227650
228381
|
const result = commandOptions.run ? await runEvaluationChecks(options.getCwd?.() ?? process.cwd()) : void 0;
|
|
227651
228382
|
if (commandOptions.json) {
|
|
227652
|
-
writeStdoutLine(JSON.stringify({
|
|
228383
|
+
writeStdoutLine(JSON.stringify({ scenarios, result }, null, 2));
|
|
227653
228384
|
return;
|
|
227654
228385
|
}
|
|
227655
|
-
writeStdoutLine(commandOptions.run ? "Evaluation
|
|
227656
|
-
for (const
|
|
227657
|
-
writeStdoutLine(`- ${
|
|
228386
|
+
writeStdoutLine(commandOptions.run ? "Evaluation scenarios run:" : "Evaluation scenarios:");
|
|
228387
|
+
for (const scenario of scenarios) {
|
|
228388
|
+
writeStdoutLine(`- ${scenario.id}: ${scenario.title}`);
|
|
228389
|
+
writeStdoutLine(` \u7528\u6237\u8DEF\u5F84: ${scenario.userPath}`);
|
|
228390
|
+
writeStdoutLine(` \u673A\u5668\u8BC1\u636E: ${scenario.evidence}`);
|
|
227658
228391
|
}
|
|
227659
228392
|
if (result) {
|
|
227660
228393
|
writeStdoutLine("");
|
|
227661
228394
|
writeStdoutLine(`Status: ${result.status}`);
|
|
227662
228395
|
for (const check of result.checks) {
|
|
227663
|
-
|
|
228396
|
+
const scenario = scenarios.find((item) => item.id === check.id);
|
|
228397
|
+
writeStdoutLine(`${check.status} ${check.id}${scenario ? ` ${scenario.title}` : ""}: ${check.fact}${check.error ? ` (${check.error})` : ""}`);
|
|
227664
228398
|
}
|
|
227665
228399
|
}
|
|
227666
228400
|
});
|
|
@@ -227734,57 +228468,7 @@ var init_session2 = __esm({
|
|
|
227734
228468
|
}
|
|
227735
228469
|
});
|
|
227736
228470
|
|
|
227737
|
-
// src/
|
|
227738
|
-
async function selectCliSession(options) {
|
|
227739
|
-
const sessions = await options.sessionStore.list(options.limit ?? DEFAULT_SESSION_PICKER_LIMIT);
|
|
227740
|
-
if (sessions.length === 0) {
|
|
227741
|
-
return {
|
|
227742
|
-
session: await createHostSession(options.sessionStore, options.cwd),
|
|
227743
|
-
cwd: options.cwd
|
|
227744
|
-
};
|
|
227745
|
-
}
|
|
227746
|
-
const io = resolveSessionPickerIo(options.io);
|
|
227747
|
-
renderSessionPicker({
|
|
227748
|
-
sessions,
|
|
227749
|
-
io,
|
|
227750
|
-
now: io.now()
|
|
227751
|
-
});
|
|
227752
|
-
while (true) {
|
|
227753
|
-
const answer = await io.readChoice("\u9009\u62E9\u4F1A\u8BDD\uFF08\u8F93\u5165\u7F16\u53F7\uFF0C0 \u65B0\u5EFA\uFF09: ");
|
|
227754
|
-
if (answer === null) {
|
|
227755
|
-
return null;
|
|
227756
|
-
}
|
|
227757
|
-
const selected = parseSessionPickerChoice(answer, sessions.length);
|
|
227758
|
-
if (selected.kind === "new") {
|
|
227759
|
-
return {
|
|
227760
|
-
session: await createHostSession(options.sessionStore, options.cwd),
|
|
227761
|
-
cwd: options.cwd
|
|
227762
|
-
};
|
|
227763
|
-
}
|
|
227764
|
-
if (selected.kind === "existing") {
|
|
227765
|
-
const session = sessions[selected.index];
|
|
227766
|
-
if (!session) {
|
|
227767
|
-
io.writeLine("\u65E0\u6548\u9009\u62E9\uFF0C\u8BF7\u91CD\u65B0\u8F93\u5165\u3002");
|
|
227768
|
-
continue;
|
|
227769
|
-
}
|
|
227770
|
-
return {
|
|
227771
|
-
session,
|
|
227772
|
-
cwd: options.cwdOverridden ? options.cwd : session.cwd
|
|
227773
|
-
};
|
|
227774
|
-
}
|
|
227775
|
-
io.writeLine("\u65E0\u6548\u9009\u62E9\uFF0C\u8BF7\u8F93\u5165\u5217\u8868\u7F16\u53F7\uFF0C\u6216\u8F93\u5165 0 \u65B0\u5EFA\u4F1A\u8BDD\u3002");
|
|
227776
|
-
}
|
|
227777
|
-
}
|
|
227778
|
-
function renderSessionPicker(options) {
|
|
227779
|
-
options.io.writeLine("\u6700\u8FD1\u4F1A\u8BDD");
|
|
227780
|
-
options.io.writeLine("0. \u65B0\u5EFA\u4F1A\u8BDD");
|
|
227781
|
-
options.sessions.forEach((session, index) => {
|
|
227782
|
-
options.io.writeLine(
|
|
227783
|
-
`${index + 1}. ${formatSessionPickerTitle(session)} ${formatRelativeSessionTime(session.updatedAt, options.now)}`
|
|
227784
|
-
);
|
|
227785
|
-
});
|
|
227786
|
-
options.io.writeLine();
|
|
227787
|
-
}
|
|
228471
|
+
// src/session/picker.ts
|
|
227788
228472
|
function parseSessionPickerChoice(input, sessionCount) {
|
|
227789
228473
|
const trimmed = input.trim();
|
|
227790
228474
|
if (trimmed === "") {
|
|
@@ -227842,6 +228526,63 @@ function truncateDisplayTitle(title) {
|
|
|
227842
228526
|
const maxChars = 36;
|
|
227843
228527
|
return chars.length > maxChars ? `${chars.slice(0, maxChars).join("")}...` : title;
|
|
227844
228528
|
}
|
|
228529
|
+
var init_picker = __esm({
|
|
228530
|
+
"src/session/picker.ts"() {
|
|
228531
|
+
"use strict";
|
|
228532
|
+
}
|
|
228533
|
+
});
|
|
228534
|
+
|
|
228535
|
+
// src/cli/commands/sessionPicker.ts
|
|
228536
|
+
async function selectCliSession(options) {
|
|
228537
|
+
const sessions = await options.sessionStore.list(options.limit ?? DEFAULT_SESSION_PICKER_LIMIT);
|
|
228538
|
+
if (sessions.length === 0) {
|
|
228539
|
+
return {
|
|
228540
|
+
session: await createHostSession(options.sessionStore, options.cwd),
|
|
228541
|
+
cwd: options.cwd
|
|
228542
|
+
};
|
|
228543
|
+
}
|
|
228544
|
+
const io = resolveSessionPickerIo(options.io);
|
|
228545
|
+
renderSessionPicker({
|
|
228546
|
+
sessions,
|
|
228547
|
+
io,
|
|
228548
|
+
now: io.now()
|
|
228549
|
+
});
|
|
228550
|
+
while (true) {
|
|
228551
|
+
const answer = await io.readChoice("\u9009\u62E9\u4F1A\u8BDD\uFF08\u8F93\u5165\u7F16\u53F7\uFF0C0 \u65B0\u5EFA\uFF09: ");
|
|
228552
|
+
if (answer === null) {
|
|
228553
|
+
return null;
|
|
228554
|
+
}
|
|
228555
|
+
const selected = parseSessionPickerChoice(answer, sessions.length);
|
|
228556
|
+
if (selected.kind === "new") {
|
|
228557
|
+
return {
|
|
228558
|
+
session: await createHostSession(options.sessionStore, options.cwd),
|
|
228559
|
+
cwd: options.cwd
|
|
228560
|
+
};
|
|
228561
|
+
}
|
|
228562
|
+
if (selected.kind === "existing") {
|
|
228563
|
+
const session = sessions[selected.index];
|
|
228564
|
+
if (!session) {
|
|
228565
|
+
io.writeLine("\u65E0\u6548\u9009\u62E9\uFF0C\u8BF7\u91CD\u65B0\u8F93\u5165\u3002");
|
|
228566
|
+
continue;
|
|
228567
|
+
}
|
|
228568
|
+
return {
|
|
228569
|
+
session,
|
|
228570
|
+
cwd: options.cwdOverridden ? options.cwd : session.cwd
|
|
228571
|
+
};
|
|
228572
|
+
}
|
|
228573
|
+
io.writeLine("\u65E0\u6548\u9009\u62E9\uFF0C\u8BF7\u8F93\u5165\u5217\u8868\u7F16\u53F7\uFF0C\u6216\u8F93\u5165 0 \u65B0\u5EFA\u4F1A\u8BDD\u3002");
|
|
228574
|
+
}
|
|
228575
|
+
}
|
|
228576
|
+
function renderSessionPicker(options) {
|
|
228577
|
+
options.io.writeLine("\u6700\u8FD1\u4F1A\u8BDD");
|
|
228578
|
+
options.io.writeLine("0. \u65B0\u5EFA\u4F1A\u8BDD");
|
|
228579
|
+
options.sessions.forEach((session, index) => {
|
|
228580
|
+
options.io.writeLine(
|
|
228581
|
+
`${index + 1}. ${formatSessionPickerTitle(session)} ${formatRelativeSessionTime(session.updatedAt, options.now)}`
|
|
228582
|
+
);
|
|
228583
|
+
});
|
|
228584
|
+
options.io.writeLine();
|
|
228585
|
+
}
|
|
227845
228586
|
function resolveSessionPickerIo(io) {
|
|
227846
228587
|
return {
|
|
227847
228588
|
writeLine: io?.writeLine ?? ((text = "") => writeStdoutLine(text)),
|
|
@@ -227873,6 +228614,8 @@ var init_sessionPicker = __esm({
|
|
|
227873
228614
|
import_node_process2 = __toESM(require("process"));
|
|
227874
228615
|
init_stdio();
|
|
227875
228616
|
init_session2();
|
|
228617
|
+
init_picker();
|
|
228618
|
+
init_picker();
|
|
227876
228619
|
DEFAULT_SESSION_PICKER_LIMIT = 10;
|
|
227877
228620
|
}
|
|
227878
228621
|
});
|
|
@@ -227944,6 +228687,218 @@ var init_exitGuard = __esm({
|
|
|
227944
228687
|
}
|
|
227945
228688
|
});
|
|
227946
228689
|
|
|
228690
|
+
// src/cli/commands/background.ts
|
|
228691
|
+
function registerBackgroundCommand(program, options) {
|
|
228692
|
+
const command = program.command("background").description("Inspect, wait for, or stop background executions.");
|
|
228693
|
+
command.argument("[action]", "Optional action: list, wait, stop").argument("[id]", "Background execution id for wait or stop").option("--json", "Print structured JSON.").option("--timeout-ms <ms>", "Wait timeout in milliseconds.", (value) => Number.parseInt(value, 10), 6e4).action(async (action, id, commandOptions) => {
|
|
228694
|
+
const runtime = await options.resolveRuntime(options.getCliOverrides());
|
|
228695
|
+
const normalizedAction = action ?? "list";
|
|
228696
|
+
if (normalizedAction === "list") {
|
|
228697
|
+
const executions = new BackgroundExecutionStore(runtime.stateRootDir).listAll().map(summarizeExecution).sort((left, right) => right.updatedAt.localeCompare(left.updatedAt));
|
|
228698
|
+
printBackgroundExecutions(executions, Boolean(commandOptions.json));
|
|
228699
|
+
return;
|
|
228700
|
+
}
|
|
228701
|
+
if (!id) {
|
|
228702
|
+
throw new Error(`background ${normalizedAction} requires an execution id.`);
|
|
228703
|
+
}
|
|
228704
|
+
if (normalizedAction === "wait") {
|
|
228705
|
+
const execution = summarizeExecution(await waitForBackgroundExecution({
|
|
228706
|
+
rootDir: runtime.stateRootDir,
|
|
228707
|
+
id,
|
|
228708
|
+
timeoutMs: commandOptions.timeoutMs
|
|
228709
|
+
}));
|
|
228710
|
+
printBackgroundExecutions([execution], Boolean(commandOptions.json));
|
|
228711
|
+
return;
|
|
228712
|
+
}
|
|
228713
|
+
if (normalizedAction === "stop") {
|
|
228714
|
+
const execution = terminateBackgroundExecution(runtime.stateRootDir, id);
|
|
228715
|
+
await waitForRegisteredBackgroundProcess(id);
|
|
228716
|
+
printBackgroundExecutions([summarizeExecution(execution)], Boolean(commandOptions.json));
|
|
228717
|
+
return;
|
|
228718
|
+
}
|
|
228719
|
+
throw new Error(`Unknown background action: ${normalizedAction}. Use list, wait, or stop.`);
|
|
228720
|
+
});
|
|
228721
|
+
}
|
|
228722
|
+
function printBackgroundExecutions(executions, json) {
|
|
228723
|
+
if (json) {
|
|
228724
|
+
writeStdoutLine(JSON.stringify({ executions }, null, 2));
|
|
228725
|
+
return;
|
|
228726
|
+
}
|
|
228727
|
+
if (executions.length === 0) {
|
|
228728
|
+
ui.info("No background executions recorded.");
|
|
228729
|
+
return;
|
|
228730
|
+
}
|
|
228731
|
+
for (const execution of executions) {
|
|
228732
|
+
writeStdoutLine(formatBackgroundExecution(execution));
|
|
228733
|
+
}
|
|
228734
|
+
}
|
|
228735
|
+
function formatBackgroundExecution(execution) {
|
|
228736
|
+
const scene = buildExecutionScene(execution);
|
|
228737
|
+
return [
|
|
228738
|
+
execution.id,
|
|
228739
|
+
execution.status,
|
|
228740
|
+
`risk=${scene.risk}`,
|
|
228741
|
+
execution.pid === void 0 ? void 0 : `pid=${execution.pid}`,
|
|
228742
|
+
`health=${truncateCliValue(scene.health, 90)}`,
|
|
228743
|
+
execution.deadlineAt ? `deadline=${execution.deadlineAt}` : void 0,
|
|
228744
|
+
`summary=${truncateCliValue(scene.summary, 90)}`,
|
|
228745
|
+
`next=${scene.nextAction}`,
|
|
228746
|
+
scene.lastOutput ? `lastOutput=${truncateCliValue(scene.lastOutput, 120)}` : void 0
|
|
228747
|
+
].filter(Boolean).join(" ");
|
|
228748
|
+
}
|
|
228749
|
+
var init_background3 = __esm({
|
|
228750
|
+
"src/cli/commands/background.ts"() {
|
|
228751
|
+
"use strict";
|
|
228752
|
+
init_background();
|
|
228753
|
+
init_executionSummary();
|
|
228754
|
+
init_scene();
|
|
228755
|
+
init_console();
|
|
228756
|
+
init_stdio();
|
|
228757
|
+
init_cliValues();
|
|
228758
|
+
}
|
|
228759
|
+
});
|
|
228760
|
+
|
|
228761
|
+
// src/cli/commands/memory.ts
|
|
228762
|
+
function registerMemoryCommand(program, options) {
|
|
228763
|
+
program.command("memory").description("List readable runtime memory assets.").argument("[memoryId]", "Optional runtime memory asset id to read.").option("--delete", "Delete the selected runtime memory asset.").option("--append-to-skill <skillName>", "Append the selected memory asset to a runtime skill references/ file.").option("--create <kind>", "Create a project, user, or evidence memory asset.").option("--title <title>", "Title for --create.").option("--content <content>", "Content for --create.").option("--evidence <refs>", "Comma-separated evidence refs for --create.").option("--scope <scope>", "Scope metadata for --create.").option("--tags <tags>", "Comma-separated tags for --create.").option("--file <fileName>", "Target file name for --append-to-skill.").option("-q, --query <query>", "Search runtime memory assets.").option("--json", "Print structured JSON.").action(async (memoryId, commandOptions) => {
|
|
228764
|
+
const runtime = await options.resolveRuntime(options.getCliOverrides());
|
|
228765
|
+
if (commandOptions.create) {
|
|
228766
|
+
await handleMemoryCreate(runtime.cwd, commandOptions);
|
|
228767
|
+
return;
|
|
228768
|
+
}
|
|
228769
|
+
if (memoryId) {
|
|
228770
|
+
await handleSelectedMemory(runtime.cwd, memoryId, commandOptions);
|
|
228771
|
+
return;
|
|
228772
|
+
}
|
|
228773
|
+
if (commandOptions.query) {
|
|
228774
|
+
await handleMemorySearch(runtime.cwd, commandOptions.query, commandOptions.json === true);
|
|
228775
|
+
return;
|
|
228776
|
+
}
|
|
228777
|
+
await handleMemoryList(runtime.cwd, commandOptions.json === true);
|
|
228778
|
+
});
|
|
228779
|
+
}
|
|
228780
|
+
async function handleMemoryCreate(cwd, options) {
|
|
228781
|
+
const kind = parseWritableMemoryKind(options.create);
|
|
228782
|
+
if (!options.title?.trim()) {
|
|
228783
|
+
throw new Error("--title is required when creating a memory asset.");
|
|
228784
|
+
}
|
|
228785
|
+
if (!options.content?.trim()) {
|
|
228786
|
+
throw new Error("--content is required when creating a memory asset.");
|
|
228787
|
+
}
|
|
228788
|
+
const created = await createRuntimeMemoryAsset({
|
|
228789
|
+
rootDir: cwd,
|
|
228790
|
+
kind,
|
|
228791
|
+
title: options.title,
|
|
228792
|
+
content: options.content,
|
|
228793
|
+
evidenceRefs: parseCsvOption(options.evidence),
|
|
228794
|
+
scope: options.scope,
|
|
228795
|
+
tags: parseCsvOption(options.tags),
|
|
228796
|
+
fileName: options.file
|
|
228797
|
+
});
|
|
228798
|
+
if (options.json) {
|
|
228799
|
+
writeStdoutLine(JSON.stringify({ created }, null, 2));
|
|
228800
|
+
return;
|
|
228801
|
+
}
|
|
228802
|
+
ui.success(`Created memory asset ${created.id}`);
|
|
228803
|
+
writeStdoutLine(created.path);
|
|
228804
|
+
}
|
|
228805
|
+
async function handleSelectedMemory(cwd, memoryId, options) {
|
|
228806
|
+
if (options.appendToSkill) {
|
|
228807
|
+
const appended = await appendRuntimeMemoryAssetToSkillReference({
|
|
228808
|
+
rootDir: cwd,
|
|
228809
|
+
memoryId,
|
|
228810
|
+
skillName: options.appendToSkill,
|
|
228811
|
+
fileName: options.file
|
|
228812
|
+
});
|
|
228813
|
+
if (options.json) {
|
|
228814
|
+
writeStdoutLine(JSON.stringify({ appended }, null, 2));
|
|
228815
|
+
return;
|
|
228816
|
+
}
|
|
228817
|
+
ui.success(`Appended memory asset ${memoryId} to skill ${options.appendToSkill}`);
|
|
228818
|
+
writeStdoutLine(appended.path);
|
|
228819
|
+
return;
|
|
228820
|
+
}
|
|
228821
|
+
if (options.delete) {
|
|
228822
|
+
const deleted = await deleteRuntimeMemoryAsset(cwd, memoryId);
|
|
228823
|
+
if (options.json) {
|
|
228824
|
+
writeStdoutLine(JSON.stringify({ deleted }, null, 2));
|
|
228825
|
+
return;
|
|
228826
|
+
}
|
|
228827
|
+
ui.success(`Deleted memory asset ${deleted.id}`);
|
|
228828
|
+
writeStdoutLine(deleted.path);
|
|
228829
|
+
return;
|
|
228830
|
+
}
|
|
228831
|
+
const memory = await readRuntimeMemoryAsset(cwd, memoryId);
|
|
228832
|
+
if (options.json) {
|
|
228833
|
+
writeStdoutLine(JSON.stringify(memory, null, 2));
|
|
228834
|
+
return;
|
|
228835
|
+
}
|
|
228836
|
+
writeStdoutLine(memory.content.trimEnd());
|
|
228837
|
+
}
|
|
228838
|
+
async function handleMemorySearch(cwd, query, json) {
|
|
228839
|
+
const results = await searchRuntimeMemoryAssets(cwd, query);
|
|
228840
|
+
if (json) {
|
|
228841
|
+
writeStdoutLine(JSON.stringify({ query, results }, null, 2));
|
|
228842
|
+
return;
|
|
228843
|
+
}
|
|
228844
|
+
if (results.length === 0) {
|
|
228845
|
+
ui.info("No matching runtime memory assets.");
|
|
228846
|
+
return;
|
|
228847
|
+
}
|
|
228848
|
+
for (const result of results) {
|
|
228849
|
+
writeStdoutLine(`${result.id} score=${result.score} ${result.path}`);
|
|
228850
|
+
for (const match of result.matches) {
|
|
228851
|
+
writeStdoutLine(` ${match}`);
|
|
228852
|
+
}
|
|
228853
|
+
}
|
|
228854
|
+
}
|
|
228855
|
+
function parseWritableMemoryKind(value) {
|
|
228856
|
+
if (value === "project" || value === "user" || value === "evidence") {
|
|
228857
|
+
return value;
|
|
228858
|
+
}
|
|
228859
|
+
throw new Error("--create must be one of: project, user, evidence.");
|
|
228860
|
+
}
|
|
228861
|
+
function parseCsvOption(value) {
|
|
228862
|
+
return (value ?? "").split(",").map((item) => item.trim()).filter(Boolean);
|
|
228863
|
+
}
|
|
228864
|
+
async function readMemoryListForCli(cwd) {
|
|
228865
|
+
return (await buildRuntimeStatus(cwd)).memory;
|
|
228866
|
+
}
|
|
228867
|
+
function formatMemoryListForCli(memory) {
|
|
228868
|
+
if (memory.assets.length === 0) {
|
|
228869
|
+
return "No runtime memory assets yet.";
|
|
228870
|
+
}
|
|
228871
|
+
return memory.assets.map((asset) => [
|
|
228872
|
+
asset.id,
|
|
228873
|
+
asset.kind,
|
|
228874
|
+
asset.updatedAt ?? "",
|
|
228875
|
+
`bytes=${asset.size}`,
|
|
228876
|
+
asset.evidenceRefs.length > 0 ? `evidence=${asset.evidenceRefs.join(",")}` : void 0,
|
|
228877
|
+
asset.path
|
|
228878
|
+
].filter(Boolean).join(" ")).join("\n");
|
|
228879
|
+
}
|
|
228880
|
+
async function handleMemoryList(cwd, json) {
|
|
228881
|
+
const memory = await readMemoryListForCli(cwd);
|
|
228882
|
+
if (json) {
|
|
228883
|
+
writeStdoutLine(JSON.stringify(memory, null, 2));
|
|
228884
|
+
return;
|
|
228885
|
+
}
|
|
228886
|
+
if (memory.assets.length === 0) {
|
|
228887
|
+
ui.info("No runtime memory assets yet.");
|
|
228888
|
+
return;
|
|
228889
|
+
}
|
|
228890
|
+
writeStdoutLine(formatMemoryListForCli(memory));
|
|
228891
|
+
}
|
|
228892
|
+
var init_memory3 = __esm({
|
|
228893
|
+
"src/cli/commands/memory.ts"() {
|
|
228894
|
+
"use strict";
|
|
228895
|
+
init_status();
|
|
228896
|
+
init_memory2();
|
|
228897
|
+
init_console();
|
|
228898
|
+
init_stdio();
|
|
228899
|
+
}
|
|
228900
|
+
});
|
|
228901
|
+
|
|
227947
228902
|
// src/project/resetSupport.ts
|
|
227948
228903
|
async function waitForRemovedPaths(paths, attempts = 20, delayMs = 50) {
|
|
227949
228904
|
for (let attempt = 0; attempt < attempts; attempt += 1) {
|
|
@@ -228132,7 +229087,7 @@ function normalizeLocalCommand(input) {
|
|
|
228132
229087
|
return LOCAL_COMMAND_BY_ALIAS.get(input.trim().toLowerCase());
|
|
228133
229088
|
}
|
|
228134
229089
|
function getLocalCommandDefinition(id) {
|
|
228135
|
-
const definition =
|
|
229090
|
+
const definition = ALL_LOCAL_COMMAND_DEFINITIONS.find((item) => item.id === id);
|
|
228136
229091
|
if (!definition) {
|
|
228137
229092
|
throw new Error(`Unknown local command: ${id}`);
|
|
228138
229093
|
}
|
|
@@ -228142,50 +229097,164 @@ function formatLocalCommandHelpLine(id) {
|
|
|
228142
229097
|
const definition = getLocalCommandDefinition(id);
|
|
228143
229098
|
return `${definition.helpLabel.padEnd(12)} ${definition.helpText}`;
|
|
228144
229099
|
}
|
|
228145
|
-
|
|
229100
|
+
function formatLocalCommandHelp() {
|
|
229101
|
+
return [
|
|
229102
|
+
"Slash commands:",
|
|
229103
|
+
...ALL_LOCAL_COMMAND_DEFINITIONS.map((definition) => formatLocalCommandHelpLine(definition.id)),
|
|
229104
|
+
"",
|
|
229105
|
+
"Any other input is sent directly to kitty."
|
|
229106
|
+
].join("\n");
|
|
229107
|
+
}
|
|
229108
|
+
function listIntroLocalCommands() {
|
|
229109
|
+
return ALL_LOCAL_COMMAND_DEFINITIONS.filter((definition) => definition.showInIntro);
|
|
229110
|
+
}
|
|
229111
|
+
var LOCAL_COMMAND_DEFINITIONS, ALL_LOCAL_COMMAND_DEFINITIONS, LOCAL_COMMAND_BY_ALIAS;
|
|
228146
229112
|
var init_localCommandDefinitions = __esm({
|
|
228147
229113
|
"src/interaction/localCommandDefinitions.ts"() {
|
|
228148
229114
|
"use strict";
|
|
228149
229115
|
LOCAL_COMMAND_DEFINITIONS = [
|
|
228150
229116
|
{
|
|
228151
229117
|
id: "exit",
|
|
229118
|
+
category: "system",
|
|
228152
229119
|
aliases: ["q", "quit", "exit", "/q", "/quit", "/exit"],
|
|
229120
|
+
slashName: "exit",
|
|
229121
|
+
description: "Exit the session",
|
|
228153
229122
|
helpLabel: "quit",
|
|
228154
|
-
helpText: "Exit the session"
|
|
229123
|
+
helpText: "Exit the session",
|
|
229124
|
+
showInIntro: true
|
|
228155
229125
|
},
|
|
228156
229126
|
{
|
|
228157
229127
|
id: "reset",
|
|
229128
|
+
category: "project",
|
|
228158
229129
|
aliases: ["reset", "/reset"],
|
|
229130
|
+
slashName: "reset",
|
|
229131
|
+
description: "Clear current project runtime state and exit",
|
|
228159
229132
|
helpLabel: "/reset",
|
|
228160
|
-
helpText: "Clear current project runtime state and exit"
|
|
229133
|
+
helpText: "Clear current project runtime state and exit",
|
|
229134
|
+
showInIntro: true
|
|
228161
229135
|
},
|
|
228162
229136
|
{
|
|
228163
229137
|
id: "help",
|
|
229138
|
+
category: "system",
|
|
228164
229139
|
aliases: ["/help"],
|
|
229140
|
+
slashName: "help",
|
|
229141
|
+
description: "Show slash commands",
|
|
228165
229142
|
helpLabel: "/help",
|
|
228166
|
-
helpText: "Show
|
|
229143
|
+
helpText: "Show slash commands",
|
|
229144
|
+
showInIntro: true
|
|
228167
229145
|
},
|
|
228168
229146
|
{
|
|
228169
229147
|
id: "session",
|
|
229148
|
+
category: "session",
|
|
228170
229149
|
aliases: ["/session"],
|
|
229150
|
+
slashName: "session",
|
|
229151
|
+
description: "Show current session ID",
|
|
228171
229152
|
helpLabel: "/session",
|
|
228172
229153
|
helpText: "Show current session ID"
|
|
228173
229154
|
},
|
|
229155
|
+
{
|
|
229156
|
+
id: "sessions",
|
|
229157
|
+
category: "session",
|
|
229158
|
+
aliases: ["/sessions", "/resume", "/continue"],
|
|
229159
|
+
slashName: "sessions",
|
|
229160
|
+
description: "List recent sessions",
|
|
229161
|
+
helpLabel: "/sessions",
|
|
229162
|
+
helpText: "List recent sessions"
|
|
229163
|
+
},
|
|
228174
229164
|
{
|
|
228175
229165
|
id: "config",
|
|
229166
|
+
category: "project",
|
|
228176
229167
|
aliases: ["/config"],
|
|
229168
|
+
slashName: "config",
|
|
229169
|
+
description: "Show current runtime config",
|
|
228177
229170
|
helpLabel: "/config",
|
|
228178
229171
|
helpText: "Show current runtime config"
|
|
228179
229172
|
},
|
|
228180
229173
|
{
|
|
228181
|
-
id: "
|
|
228182
|
-
|
|
228183
|
-
|
|
228184
|
-
|
|
229174
|
+
id: "status",
|
|
229175
|
+
category: "runtime",
|
|
229176
|
+
aliases: ["/status"],
|
|
229177
|
+
slashName: "status",
|
|
229178
|
+
description: "Show current project scene",
|
|
229179
|
+
helpLabel: "/status",
|
|
229180
|
+
helpText: "Show current project scene"
|
|
229181
|
+
},
|
|
229182
|
+
{
|
|
229183
|
+
id: "background",
|
|
229184
|
+
category: "runtime",
|
|
229185
|
+
aliases: ["/background", "/bg"],
|
|
229186
|
+
slashName: "background",
|
|
229187
|
+
description: "Show background task scene",
|
|
229188
|
+
helpLabel: "/background",
|
|
229189
|
+
helpText: "Show background task scene"
|
|
229190
|
+
},
|
|
229191
|
+
{
|
|
229192
|
+
id: "events",
|
|
229193
|
+
category: "runtime",
|
|
229194
|
+
aliases: ["/events"],
|
|
229195
|
+
slashName: "events",
|
|
229196
|
+
description: "Show recent session events",
|
|
229197
|
+
helpLabel: "/events",
|
|
229198
|
+
helpText: "Show recent session events"
|
|
229199
|
+
},
|
|
229200
|
+
{
|
|
229201
|
+
id: "memory",
|
|
229202
|
+
category: "runtime",
|
|
229203
|
+
aliases: ["/memory"],
|
|
229204
|
+
slashName: "memory",
|
|
229205
|
+
description: "List runtime memory assets",
|
|
229206
|
+
helpLabel: "/memory",
|
|
229207
|
+
helpText: "List runtime memory assets"
|
|
229208
|
+
},
|
|
229209
|
+
{
|
|
229210
|
+
id: "skills",
|
|
229211
|
+
category: "runtime",
|
|
229212
|
+
aliases: ["/skills"],
|
|
229213
|
+
slashName: "skills",
|
|
229214
|
+
description: "List runtime skills",
|
|
229215
|
+
helpLabel: "/skills",
|
|
229216
|
+
helpText: "List runtime skills"
|
|
229217
|
+
},
|
|
229218
|
+
{
|
|
229219
|
+
id: "doctor",
|
|
229220
|
+
category: "project",
|
|
229221
|
+
aliases: ["/doctor"],
|
|
229222
|
+
slashName: "doctor",
|
|
229223
|
+
description: "Run local setup preflight",
|
|
229224
|
+
helpLabel: "/doctor",
|
|
229225
|
+
helpText: "Run local setup preflight"
|
|
229226
|
+
},
|
|
229227
|
+
{
|
|
229228
|
+
id: "copy",
|
|
229229
|
+
category: "session",
|
|
229230
|
+
aliases: ["/copy"],
|
|
229231
|
+
slashName: "copy",
|
|
229232
|
+
description: "Print current session transcript",
|
|
229233
|
+
helpLabel: "/copy",
|
|
229234
|
+
helpText: "Print current session transcript"
|
|
229235
|
+
},
|
|
229236
|
+
{
|
|
229237
|
+
id: "export",
|
|
229238
|
+
category: "session",
|
|
229239
|
+
aliases: ["/export"],
|
|
229240
|
+
slashName: "export",
|
|
229241
|
+
description: "Print current session snapshot JSON",
|
|
229242
|
+
helpLabel: "/export",
|
|
229243
|
+
helpText: "Print current session snapshot JSON"
|
|
229244
|
+
},
|
|
229245
|
+
{
|
|
229246
|
+
id: "clear",
|
|
229247
|
+
category: "session",
|
|
229248
|
+
aliases: ["/clear"],
|
|
229249
|
+
slashName: "clear",
|
|
229250
|
+
description: "Clear the current prompt in UI shells",
|
|
229251
|
+
helpLabel: "/clear",
|
|
229252
|
+
helpText: "Clear the current prompt in UI shells"
|
|
228185
229253
|
}
|
|
228186
229254
|
];
|
|
229255
|
+
ALL_LOCAL_COMMAND_DEFINITIONS = LOCAL_COMMAND_DEFINITIONS;
|
|
228187
229256
|
LOCAL_COMMAND_BY_ALIAS = new Map(
|
|
228188
|
-
|
|
229257
|
+
ALL_LOCAL_COMMAND_DEFINITIONS.flatMap(
|
|
228189
229258
|
(definition) => definition.aliases.map((alias) => [alias, definition.id])
|
|
228190
229259
|
)
|
|
228191
229260
|
);
|
|
@@ -228211,23 +229280,9 @@ async function handleLocalCommand(input, context, output) {
|
|
|
228211
229280
|
return "quit";
|
|
228212
229281
|
}
|
|
228213
229282
|
if (command === "help") {
|
|
228214
|
-
output.plain(
|
|
228215
|
-
[
|
|
228216
|
-
formatLocalCommandHelpLine("help"),
|
|
228217
|
-
formatLocalCommandHelpLine("session"),
|
|
228218
|
-
formatLocalCommandHelpLine("config"),
|
|
228219
|
-
formatLocalCommandHelpLine("multiline"),
|
|
228220
|
-
formatLocalCommandHelpLine("reset"),
|
|
228221
|
-
formatLocalCommandHelpLine("exit"),
|
|
228222
|
-
"",
|
|
228223
|
-
"Any other input is sent directly to kitty."
|
|
228224
|
-
].join("\n")
|
|
228225
|
-
);
|
|
229283
|
+
output.plain(formatLocalCommandHelp());
|
|
228226
229284
|
return "handled";
|
|
228227
229285
|
}
|
|
228228
|
-
if (command === "multiline") {
|
|
228229
|
-
return "multiline";
|
|
228230
|
-
}
|
|
228231
229286
|
if (command === "session") {
|
|
228232
229287
|
output.info(`Current session: ${context.session.id}`);
|
|
228233
229288
|
return "handled";
|
|
@@ -228236,12 +229291,108 @@ async function handleLocalCommand(input, context, output) {
|
|
|
228236
229291
|
output.info(`model=${context.config.model} baseUrl=${context.config.baseUrl}`);
|
|
228237
229292
|
return "handled";
|
|
228238
229293
|
}
|
|
229294
|
+
if (command === "status") {
|
|
229295
|
+
output.plain(formatRuntimeStatusText(await buildRuntimeStatus(await resolveLocalStateRootDir(context))).trimEnd());
|
|
229296
|
+
return "handled";
|
|
229297
|
+
}
|
|
229298
|
+
if (command === "background") {
|
|
229299
|
+
output.plain(await formatBackgroundExecutionsForLocalCommand(context));
|
|
229300
|
+
return "handled";
|
|
229301
|
+
}
|
|
229302
|
+
if (command === "memory") {
|
|
229303
|
+
output.plain(formatMemoryListForCli(await readMemoryListForCli(await resolveLocalStateRootDir(context))));
|
|
229304
|
+
return "handled";
|
|
229305
|
+
}
|
|
229306
|
+
if (command === "skills") {
|
|
229307
|
+
output.plain(formatSkillsForLocalCommand(await buildRuntimeStatus(await resolveLocalStateRootDir(context))));
|
|
229308
|
+
return "handled";
|
|
229309
|
+
}
|
|
229310
|
+
if (command === "events") {
|
|
229311
|
+
const stateRootDir = await resolveLocalStateRootDir(context);
|
|
229312
|
+
output.plain(formatSessionEventsForCli(await readSessionEventsForCli({
|
|
229313
|
+
cwd: stateRootDir,
|
|
229314
|
+
paths: getAppPaths(stateRootDir),
|
|
229315
|
+
sessionId: context.session.id,
|
|
229316
|
+
limit: 20
|
|
229317
|
+
})));
|
|
229318
|
+
return "handled";
|
|
229319
|
+
}
|
|
229320
|
+
if (command === "doctor") {
|
|
229321
|
+
output.plain(formatConfigPreflightReport(await inspectConfigPreflight(context.cwd)).join("\n"));
|
|
229322
|
+
return "handled";
|
|
229323
|
+
}
|
|
229324
|
+
if (command === "sessions") {
|
|
229325
|
+
output.plain(await formatSessionsForLocalCommand(context));
|
|
229326
|
+
return "handled";
|
|
229327
|
+
}
|
|
229328
|
+
if (command === "copy") {
|
|
229329
|
+
output.plain(formatSessionTranscript(context.session));
|
|
229330
|
+
return "handled";
|
|
229331
|
+
}
|
|
229332
|
+
if (command === "export") {
|
|
229333
|
+
output.plain(JSON.stringify(context.session, null, 2));
|
|
229334
|
+
return "handled";
|
|
229335
|
+
}
|
|
229336
|
+
if (command === "clear") {
|
|
229337
|
+
output.info("Current prompt cleared.");
|
|
229338
|
+
return "handled";
|
|
229339
|
+
}
|
|
228239
229340
|
return "continue";
|
|
228240
229341
|
}
|
|
229342
|
+
async function formatBackgroundExecutionsForLocalCommand(context) {
|
|
229343
|
+
const stateRootDir = await resolveLocalStateRootDir(context);
|
|
229344
|
+
const store = new BackgroundExecutionStore(stateRootDir);
|
|
229345
|
+
const executions = store.listAll().map(summarizeExecution).sort((left, right) => right.updatedAt.localeCompare(left.updatedAt));
|
|
229346
|
+
if (executions.length === 0) {
|
|
229347
|
+
return "No background executions recorded.";
|
|
229348
|
+
}
|
|
229349
|
+
return executions.map(formatBackgroundExecution).join("\n");
|
|
229350
|
+
}
|
|
229351
|
+
async function resolveLocalStateRootDir(context) {
|
|
229352
|
+
return context.stateRootDir ?? (await resolveProjectRoots(context.cwd)).stateRootDir;
|
|
229353
|
+
}
|
|
229354
|
+
function formatSkillsForLocalCommand(status) {
|
|
229355
|
+
if (status.skills.total === 0) {
|
|
229356
|
+
return "No runtime skills discovered.";
|
|
229357
|
+
}
|
|
229358
|
+
return [
|
|
229359
|
+
`skills: ${status.skills.ready}/${status.skills.total} ready`,
|
|
229360
|
+
...status.skills.needsAttention.map((skill) => `${skill.name} status=${skill.status} issues=${skill.issues.join("; ") || "none"}`)
|
|
229361
|
+
].join("\n");
|
|
229362
|
+
}
|
|
229363
|
+
async function formatSessionsForLocalCommand(context) {
|
|
229364
|
+
const sessions = await (context.sessionStore?.list(10) ?? []);
|
|
229365
|
+
if (sessions.length === 0) {
|
|
229366
|
+
return "No saved sessions yet.";
|
|
229367
|
+
}
|
|
229368
|
+
return sessions.map((session) => [
|
|
229369
|
+
session.id === context.session.id ? "*" : " ",
|
|
229370
|
+
session.id,
|
|
229371
|
+
session.updatedAt,
|
|
229372
|
+
session.title ?? "(untitled)",
|
|
229373
|
+
`messages=${session.messageCount}`
|
|
229374
|
+
].join(" ")).join("\n");
|
|
229375
|
+
}
|
|
229376
|
+
function formatSessionTranscript(session) {
|
|
229377
|
+
if (session.messages.length === 0) {
|
|
229378
|
+
return "Current session has no messages yet.";
|
|
229379
|
+
}
|
|
229380
|
+
return session.messages.map((message) => `${message.role}: ${message.content}`).join("\n\n");
|
|
229381
|
+
}
|
|
228241
229382
|
var init_localCommands = __esm({
|
|
228242
229383
|
"src/interaction/localCommands.ts"() {
|
|
228243
229384
|
"use strict";
|
|
229385
|
+
init_background();
|
|
229386
|
+
init_background3();
|
|
229387
|
+
init_preflight();
|
|
229388
|
+
init_memory3();
|
|
229389
|
+
init_runtimeStatusPresenter();
|
|
229390
|
+
init_events3();
|
|
229391
|
+
init_paths();
|
|
229392
|
+
init_repoRoots();
|
|
228244
229393
|
init_reset();
|
|
229394
|
+
init_status();
|
|
229395
|
+
init_executionSummary();
|
|
228245
229396
|
init_localCommandDefinitions();
|
|
228246
229397
|
}
|
|
228247
229398
|
});
|
|
@@ -228311,7 +229462,8 @@ var init_sessionDriver = __esm({
|
|
|
228311
229462
|
{
|
|
228312
229463
|
cwd: this.options.cwd,
|
|
228313
229464
|
session: this.session,
|
|
228314
|
-
config: this.options.config
|
|
229465
|
+
config: this.options.config,
|
|
229466
|
+
sessionStore: this.options.sessionStore
|
|
228315
229467
|
},
|
|
228316
229468
|
this.options.shell.output
|
|
228317
229469
|
);
|
|
@@ -228323,8 +229475,6 @@ var init_sessionDriver = __esm({
|
|
|
228323
229475
|
await this.runTurn(input);
|
|
228324
229476
|
} else if (localCommandResult === "quit") {
|
|
228325
229477
|
return this.handleQuitRequest();
|
|
228326
|
-
} else if (localCommandResult === "multiline") {
|
|
228327
|
-
await this.handleMultilineInput();
|
|
228328
229478
|
}
|
|
228329
229479
|
return localCommandResult;
|
|
228330
229480
|
}
|
|
@@ -228366,25 +229516,6 @@ var init_sessionDriver = __esm({
|
|
|
228366
229516
|
return "handled";
|
|
228367
229517
|
}
|
|
228368
229518
|
}
|
|
228369
|
-
async handleMultilineInput() {
|
|
228370
|
-
this.options.shell.output.info("Entered multiline mode. Use ::end to submit or ::cancel to cancel.\n");
|
|
228371
|
-
const multiline = await this.options.shell.input.readMultiline("\u2026 ");
|
|
228372
|
-
if (multiline.kind === "cancel") {
|
|
228373
|
-
this.options.shell.output.warn("Cancelled multiline input.\n");
|
|
228374
|
-
return;
|
|
228375
|
-
}
|
|
228376
|
-
if (multiline.kind === "closed") {
|
|
228377
|
-
await this.terminateRunningProcessesForForcedExit("Input closed during multiline mode. Stopping running processes before exit.");
|
|
228378
|
-
this.exitRequested = true;
|
|
228379
|
-
return;
|
|
228380
|
-
}
|
|
228381
|
-
const value = multiline.value.trim();
|
|
228382
|
-
if (!value) {
|
|
228383
|
-
this.options.shell.output.warn("Multiline input was empty, nothing was sent.\n");
|
|
228384
|
-
return;
|
|
228385
|
-
}
|
|
228386
|
-
await this.runTurn(value);
|
|
228387
|
-
}
|
|
228388
229519
|
handleInterrupt() {
|
|
228389
229520
|
if (this.turnInFlight && this.turnAbortController && !this.turnAbortController.signal.aborted) {
|
|
228390
229521
|
this.turnAbortController.abort();
|
|
@@ -228477,6 +229608,7 @@ var init_sessionDriver = __esm({
|
|
|
228477
229608
|
runTurn: this.options.runTurn
|
|
228478
229609
|
});
|
|
228479
229610
|
this.session = outcome.session;
|
|
229611
|
+
this.options.onSessionUpdated?.(this.session);
|
|
228480
229612
|
if (outcome.status === "aborted") {
|
|
228481
229613
|
turnDisplay.flush();
|
|
228482
229614
|
this.options.shell.output.warn(outcome.errorMessage ?? "Turn interrupted. You can keep chatting.");
|
|
@@ -229334,17 +230466,6 @@ function mirrorInput(input, writer) {
|
|
|
229334
230466
|
const result = await input.readInput(promptLabel);
|
|
229335
230467
|
if (result.kind === "submit") {
|
|
229336
230468
|
writer.write(`${promptLabel ?? "> "}${result.value}
|
|
229337
|
-
`);
|
|
229338
|
-
}
|
|
229339
|
-
return result;
|
|
229340
|
-
},
|
|
229341
|
-
async readMultiline(promptLabel) {
|
|
229342
|
-
const result = await input.readMultiline(promptLabel);
|
|
229343
|
-
if (result.kind === "submit") {
|
|
229344
|
-
writer.write(`${promptLabel ?? "... "}${result.value}
|
|
229345
|
-
`);
|
|
229346
|
-
} else if (result.kind === "cancel") {
|
|
229347
|
-
writer.write(`${promptLabel ?? "... "}::cancel
|
|
229348
230469
|
`);
|
|
229349
230470
|
}
|
|
229350
230471
|
return result;
|
|
@@ -229392,7 +230513,7 @@ var init_terminalLog = __esm({
|
|
|
229392
230513
|
}
|
|
229393
230514
|
});
|
|
229394
230515
|
|
|
229395
|
-
// src/shell/
|
|
230516
|
+
// src/shell/banner.ts
|
|
229396
230517
|
function renderKittyBanner() {
|
|
229397
230518
|
return import_figlet.default.textSync("kitty agent", {
|
|
229398
230519
|
font: KITTY_WORDMARK_FONT,
|
|
@@ -229402,6 +230523,16 @@ function renderKittyBanner() {
|
|
|
229402
230523
|
whitespaceBreak: false
|
|
229403
230524
|
}).trimEnd();
|
|
229404
230525
|
}
|
|
230526
|
+
var import_figlet, KITTY_WORDMARK_FONT;
|
|
230527
|
+
var init_banner = __esm({
|
|
230528
|
+
"src/shell/banner.ts"() {
|
|
230529
|
+
"use strict";
|
|
230530
|
+
import_figlet = __toESM(require("figlet"));
|
|
230531
|
+
KITTY_WORDMARK_FONT = "ANSI Shadow";
|
|
230532
|
+
}
|
|
230533
|
+
});
|
|
230534
|
+
|
|
230535
|
+
// src/shell/cli/intro.ts
|
|
229405
230536
|
function writeCliInteractiveIntro(options) {
|
|
229406
230537
|
options.output.plain(import_chalk4.default.bold(import_chalk4.default.greenBright(renderKittyBanner())));
|
|
229407
230538
|
options.output.dim(`session: ${options.session.id}`);
|
|
@@ -229410,21 +230541,18 @@ function writeCliInteractiveIntro(options) {
|
|
|
229410
230541
|
options.output.dim(`Tools: ${options.toolsLabel}`);
|
|
229411
230542
|
}
|
|
229412
230543
|
options.output.dim("Commands:");
|
|
229413
|
-
|
|
229414
|
-
|
|
229415
|
-
|
|
229416
|
-
options.output.dim(
|
|
229417
|
-
|
|
229418
|
-
|
|
229419
|
-
}
|
|
229420
|
-
var import_chalk4, import_figlet, KITTY_WORDMARK_FONT;
|
|
230544
|
+
for (const command of listIntroLocalCommands()) {
|
|
230545
|
+
options.output.dim(formatLocalCommandHelpLine(command.id));
|
|
230546
|
+
}
|
|
230547
|
+
options.output.dim("");
|
|
230548
|
+
}
|
|
230549
|
+
var import_chalk4;
|
|
229421
230550
|
var init_intro = __esm({
|
|
229422
230551
|
"src/shell/cli/intro.ts"() {
|
|
229423
230552
|
"use strict";
|
|
229424
230553
|
import_chalk4 = __toESM(require("chalk"));
|
|
229425
|
-
import_figlet = __toESM(require("figlet"));
|
|
229426
230554
|
init_localCommandDefinitions();
|
|
229427
|
-
|
|
230555
|
+
init_banner();
|
|
229428
230556
|
}
|
|
229429
230557
|
});
|
|
229430
230558
|
|
|
@@ -229499,58 +230627,6 @@ async function readPersistentInput(promptLabel, onInterrupt) {
|
|
|
229499
230627
|
rl.prompt();
|
|
229500
230628
|
});
|
|
229501
230629
|
}
|
|
229502
|
-
async function readMultilineInput(onInterrupt, promptLabel = "\u2026 ") {
|
|
229503
|
-
return new Promise((resolve) => {
|
|
229504
|
-
const rl = import_node_readline.default.createInterface({
|
|
229505
|
-
input: import_node_process4.default.stdin,
|
|
229506
|
-
output: import_node_process4.default.stdout,
|
|
229507
|
-
terminal: true
|
|
229508
|
-
});
|
|
229509
|
-
const lines = [];
|
|
229510
|
-
let settled = false;
|
|
229511
|
-
const cleanup = () => {
|
|
229512
|
-
rl.removeAllListeners("line");
|
|
229513
|
-
rl.removeAllListeners("close");
|
|
229514
|
-
rl.removeAllListeners("SIGINT");
|
|
229515
|
-
};
|
|
229516
|
-
const finish = (value) => {
|
|
229517
|
-
if (settled) {
|
|
229518
|
-
return;
|
|
229519
|
-
}
|
|
229520
|
-
settled = true;
|
|
229521
|
-
cleanup();
|
|
229522
|
-
rl.close();
|
|
229523
|
-
resolve(value);
|
|
229524
|
-
};
|
|
229525
|
-
rl.on("line", (line) => {
|
|
229526
|
-
const trimmed = line.trim();
|
|
229527
|
-
if (trimmed === "::end") {
|
|
229528
|
-
finish({ kind: "submit", value: lines.join("\n") });
|
|
229529
|
-
return;
|
|
229530
|
-
}
|
|
229531
|
-
if (trimmed === "::cancel") {
|
|
229532
|
-
finish({ kind: "cancel" });
|
|
229533
|
-
return;
|
|
229534
|
-
}
|
|
229535
|
-
lines.push(line);
|
|
229536
|
-
rl.prompt();
|
|
229537
|
-
});
|
|
229538
|
-
rl.on("SIGINT", () => {
|
|
229539
|
-
onInterrupt();
|
|
229540
|
-
rl.prompt();
|
|
229541
|
-
});
|
|
229542
|
-
rl.on("close", () => {
|
|
229543
|
-
if (settled) {
|
|
229544
|
-
return;
|
|
229545
|
-
}
|
|
229546
|
-
settled = true;
|
|
229547
|
-
cleanup();
|
|
229548
|
-
resolve({ kind: "eof" });
|
|
229549
|
-
});
|
|
229550
|
-
rl.setPrompt(promptLabel);
|
|
229551
|
-
rl.prompt();
|
|
229552
|
-
});
|
|
229553
|
-
}
|
|
229554
230630
|
function createReadlineInputPort() {
|
|
229555
230631
|
const listeners = /* @__PURE__ */ new Set();
|
|
229556
230632
|
let releaseProcessInterrupt = null;
|
|
@@ -229583,13 +230659,6 @@ function createReadlineInputPort() {
|
|
|
229583
230659
|
const value = await readPersistentInput(promptLabel, notifyInterrupt);
|
|
229584
230660
|
return value === null ? { kind: "closed" } : { kind: "submit", value };
|
|
229585
230661
|
},
|
|
229586
|
-
async readMultiline(promptLabel = "\u2026 ") {
|
|
229587
|
-
const result = await readMultilineInput(notifyInterrupt, promptLabel);
|
|
229588
|
-
if (result.kind === "eof") {
|
|
229589
|
-
return { kind: "closed" };
|
|
229590
|
-
}
|
|
229591
|
-
return result;
|
|
229592
|
-
},
|
|
229593
230662
|
bindInterrupt(handler) {
|
|
229594
230663
|
listeners.add(handler);
|
|
229595
230664
|
ensureProcessInterruptBinding();
|
|
@@ -230081,7 +231150,7 @@ function registerEventsCommand(program, options) {
|
|
|
230081
231150
|
return;
|
|
230082
231151
|
}
|
|
230083
231152
|
for (const event of result.events) {
|
|
230084
|
-
writeStdoutLine(
|
|
231153
|
+
writeStdoutLine(formatSessionEventForCli(event));
|
|
230085
231154
|
}
|
|
230086
231155
|
});
|
|
230087
231156
|
}
|
|
@@ -230099,7 +231168,16 @@ async function readSessionEventsForCli(input) {
|
|
|
230099
231168
|
events: await new SessionEventStore(input.paths.eventsDir).list(session.id, input.limit)
|
|
230100
231169
|
};
|
|
230101
231170
|
}
|
|
230102
|
-
function
|
|
231171
|
+
function formatSessionEventsForCli(result) {
|
|
231172
|
+
if (!result.sessionId) {
|
|
231173
|
+
return "No saved sessions yet.";
|
|
231174
|
+
}
|
|
231175
|
+
if (result.events.length === 0) {
|
|
231176
|
+
return `No events recorded for session ${result.sessionId}.`;
|
|
231177
|
+
}
|
|
231178
|
+
return result.events.map(formatSessionEventForCli).join("\n");
|
|
231179
|
+
}
|
|
231180
|
+
function formatSessionEventForCli(event) {
|
|
230103
231181
|
const parts = [
|
|
230104
231182
|
event.createdAt,
|
|
230105
231183
|
event.type,
|
|
@@ -230124,382 +231202,6 @@ var init_events3 = __esm({
|
|
|
230124
231202
|
}
|
|
230125
231203
|
});
|
|
230126
231204
|
|
|
230127
|
-
// src/cli/commands/memory.ts
|
|
230128
|
-
function registerMemoryCommand(program, options) {
|
|
230129
|
-
program.command("memory").description("List readable runtime memory assets.").argument("[memoryId]", "Optional runtime memory asset id to read.").option("--delete", "Delete the selected runtime memory asset.").option("--append-to-skill <skillName>", "Append the selected memory asset to a runtime skill references/ file.").option("--create <kind>", "Create a project, user, or evidence memory asset.").option("--title <title>", "Title for --create.").option("--content <content>", "Content for --create.").option("--evidence <refs>", "Comma-separated evidence refs for --create.").option("--scope <scope>", "Scope metadata for --create.").option("--tags <tags>", "Comma-separated tags for --create.").option("--file <fileName>", "Target file name for --append-to-skill.").option("-q, --query <query>", "Search runtime memory assets.").option("--json", "Print structured JSON.").action(async (memoryId, commandOptions) => {
|
|
230130
|
-
const runtime = await options.resolveRuntime(options.getCliOverrides());
|
|
230131
|
-
if (commandOptions.create) {
|
|
230132
|
-
await handleMemoryCreate(runtime.cwd, commandOptions);
|
|
230133
|
-
return;
|
|
230134
|
-
}
|
|
230135
|
-
if (memoryId) {
|
|
230136
|
-
await handleSelectedMemory(runtime.cwd, memoryId, commandOptions);
|
|
230137
|
-
return;
|
|
230138
|
-
}
|
|
230139
|
-
if (commandOptions.query) {
|
|
230140
|
-
await handleMemorySearch(runtime.cwd, commandOptions.query, commandOptions.json === true);
|
|
230141
|
-
return;
|
|
230142
|
-
}
|
|
230143
|
-
await handleMemoryList(runtime.cwd, commandOptions.json === true);
|
|
230144
|
-
});
|
|
230145
|
-
}
|
|
230146
|
-
async function handleMemoryCreate(cwd, options) {
|
|
230147
|
-
const kind = parseWritableMemoryKind(options.create);
|
|
230148
|
-
if (!options.title?.trim()) {
|
|
230149
|
-
throw new Error("--title is required when creating a memory asset.");
|
|
230150
|
-
}
|
|
230151
|
-
if (!options.content?.trim()) {
|
|
230152
|
-
throw new Error("--content is required when creating a memory asset.");
|
|
230153
|
-
}
|
|
230154
|
-
const created = await createRuntimeMemoryAsset({
|
|
230155
|
-
rootDir: cwd,
|
|
230156
|
-
kind,
|
|
230157
|
-
title: options.title,
|
|
230158
|
-
content: options.content,
|
|
230159
|
-
evidenceRefs: parseCsvOption(options.evidence),
|
|
230160
|
-
scope: options.scope,
|
|
230161
|
-
tags: parseCsvOption(options.tags),
|
|
230162
|
-
fileName: options.file
|
|
230163
|
-
});
|
|
230164
|
-
if (options.json) {
|
|
230165
|
-
writeStdoutLine(JSON.stringify({ created }, null, 2));
|
|
230166
|
-
return;
|
|
230167
|
-
}
|
|
230168
|
-
ui.success(`Created memory asset ${created.id}`);
|
|
230169
|
-
writeStdoutLine(created.path);
|
|
230170
|
-
}
|
|
230171
|
-
async function handleSelectedMemory(cwd, memoryId, options) {
|
|
230172
|
-
if (options.appendToSkill) {
|
|
230173
|
-
const appended = await appendRuntimeMemoryAssetToSkillReference({
|
|
230174
|
-
rootDir: cwd,
|
|
230175
|
-
memoryId,
|
|
230176
|
-
skillName: options.appendToSkill,
|
|
230177
|
-
fileName: options.file
|
|
230178
|
-
});
|
|
230179
|
-
if (options.json) {
|
|
230180
|
-
writeStdoutLine(JSON.stringify({ appended }, null, 2));
|
|
230181
|
-
return;
|
|
230182
|
-
}
|
|
230183
|
-
ui.success(`Appended memory asset ${memoryId} to skill ${options.appendToSkill}`);
|
|
230184
|
-
writeStdoutLine(appended.path);
|
|
230185
|
-
return;
|
|
230186
|
-
}
|
|
230187
|
-
if (options.delete) {
|
|
230188
|
-
const deleted = await deleteRuntimeMemoryAsset(cwd, memoryId);
|
|
230189
|
-
if (options.json) {
|
|
230190
|
-
writeStdoutLine(JSON.stringify({ deleted }, null, 2));
|
|
230191
|
-
return;
|
|
230192
|
-
}
|
|
230193
|
-
ui.success(`Deleted memory asset ${deleted.id}`);
|
|
230194
|
-
writeStdoutLine(deleted.path);
|
|
230195
|
-
return;
|
|
230196
|
-
}
|
|
230197
|
-
const memory = await readRuntimeMemoryAsset(cwd, memoryId);
|
|
230198
|
-
if (options.json) {
|
|
230199
|
-
writeStdoutLine(JSON.stringify(memory, null, 2));
|
|
230200
|
-
return;
|
|
230201
|
-
}
|
|
230202
|
-
writeStdoutLine(memory.content.trimEnd());
|
|
230203
|
-
}
|
|
230204
|
-
async function handleMemorySearch(cwd, query, json) {
|
|
230205
|
-
const results = await searchRuntimeMemoryAssets(cwd, query);
|
|
230206
|
-
if (json) {
|
|
230207
|
-
writeStdoutLine(JSON.stringify({ query, results }, null, 2));
|
|
230208
|
-
return;
|
|
230209
|
-
}
|
|
230210
|
-
if (results.length === 0) {
|
|
230211
|
-
ui.info("No matching runtime memory assets.");
|
|
230212
|
-
return;
|
|
230213
|
-
}
|
|
230214
|
-
for (const result of results) {
|
|
230215
|
-
writeStdoutLine(`${result.id} score=${result.score} ${result.path}`);
|
|
230216
|
-
for (const match of result.matches) {
|
|
230217
|
-
writeStdoutLine(` ${match}`);
|
|
230218
|
-
}
|
|
230219
|
-
}
|
|
230220
|
-
}
|
|
230221
|
-
function parseWritableMemoryKind(value) {
|
|
230222
|
-
if (value === "project" || value === "user" || value === "evidence") {
|
|
230223
|
-
return value;
|
|
230224
|
-
}
|
|
230225
|
-
throw new Error("--create must be one of: project, user, evidence.");
|
|
230226
|
-
}
|
|
230227
|
-
function parseCsvOption(value) {
|
|
230228
|
-
return (value ?? "").split(",").map((item) => item.trim()).filter(Boolean);
|
|
230229
|
-
}
|
|
230230
|
-
async function handleMemoryList(cwd, json) {
|
|
230231
|
-
const status = await buildRuntimeStatus(cwd);
|
|
230232
|
-
if (json) {
|
|
230233
|
-
writeStdoutLine(JSON.stringify(status.memory, null, 2));
|
|
230234
|
-
return;
|
|
230235
|
-
}
|
|
230236
|
-
if (status.memory.assets.length === 0) {
|
|
230237
|
-
ui.info("No runtime memory assets yet.");
|
|
230238
|
-
return;
|
|
230239
|
-
}
|
|
230240
|
-
for (const memory of status.memory.assets) {
|
|
230241
|
-
writeStdoutLine([
|
|
230242
|
-
memory.id,
|
|
230243
|
-
memory.kind,
|
|
230244
|
-
memory.updatedAt ?? "",
|
|
230245
|
-
`bytes=${memory.size}`,
|
|
230246
|
-
memory.evidenceRefs.length > 0 ? `evidence=${memory.evidenceRefs.join(",")}` : void 0,
|
|
230247
|
-
memory.path
|
|
230248
|
-
].filter(Boolean).join(" "));
|
|
230249
|
-
}
|
|
230250
|
-
}
|
|
230251
|
-
var init_memory3 = __esm({
|
|
230252
|
-
"src/cli/commands/memory.ts"() {
|
|
230253
|
-
"use strict";
|
|
230254
|
-
init_status();
|
|
230255
|
-
init_memory2();
|
|
230256
|
-
init_console();
|
|
230257
|
-
init_stdio();
|
|
230258
|
-
}
|
|
230259
|
-
});
|
|
230260
|
-
|
|
230261
|
-
// src/cli/commands/runtimeStatusPresenter.ts
|
|
230262
|
-
function formatRuntimeStatusText(status) {
|
|
230263
|
-
const lines = [];
|
|
230264
|
-
lines.push(`Project: ${status.rootDir}`);
|
|
230265
|
-
lines.push(`State: ${status.stateDir}`);
|
|
230266
|
-
lines.push("");
|
|
230267
|
-
lines.push("Current workspace:");
|
|
230268
|
-
lines.push(`- Focus: ${readFocus(status)}`);
|
|
230269
|
-
lines.push(`- Session: ${readSessionLine(status)}`);
|
|
230270
|
-
lines.push(`- Next: ${readNextStep(status)}`);
|
|
230271
|
-
lines.push(`- Blocked: ${readBlockedLine(status)}`);
|
|
230272
|
-
lines.push(`- Context budget: ${readContextBudgetLine(status)}`);
|
|
230273
|
-
lines.push(`- Workset: ${status.sessions.latest?.workset ? `${status.sessions.latest.workset.total} file(s)` : "none"}`);
|
|
230274
|
-
lines.push(`- Memory: ${status.memory.assets.length > 0 ? `${status.memory.assets.length} asset(s)` : "none"}`);
|
|
230275
|
-
lines.push(`- Skills: ${status.skills.ready}/${status.skills.total} ready`);
|
|
230276
|
-
lines.push(`- Model cache: ${readModelCacheLine(status)}`);
|
|
230277
|
-
lines.push(`- Project map: ${status.projectMap ? "ready" : "missing"}`);
|
|
230278
|
-
lines.push(`- Executions: ${status.executions.active.length} active / ${status.executions.total} total`);
|
|
230279
|
-
lines.push(`- Wake signals: ${status.wakeSignals.recent.length}`);
|
|
230280
|
-
if (status.taskLifecycle) {
|
|
230281
|
-
lines.push("");
|
|
230282
|
-
lines.push("Task lifecycle:");
|
|
230283
|
-
lines.push([
|
|
230284
|
-
status.taskLifecycle.stage,
|
|
230285
|
-
status.taskLifecycle.reason ? `reason=${status.taskLifecycle.reason}` : void 0,
|
|
230286
|
-
status.taskLifecycle.updatedAt
|
|
230287
|
-
].filter(Boolean).join(" "));
|
|
230288
|
-
}
|
|
230289
|
-
if (status.sessions.latest) {
|
|
230290
|
-
lines.push("");
|
|
230291
|
-
lines.push("Latest session:");
|
|
230292
|
-
lines.push([
|
|
230293
|
-
status.sessions.latest.id,
|
|
230294
|
-
status.sessions.latest.title ?? "(untitled)",
|
|
230295
|
-
`messages=${status.sessions.latest.messageCount}`,
|
|
230296
|
-
status.sessions.latest.hasMemory ? "memory=yes" : "memory=no"
|
|
230297
|
-
].join(" "));
|
|
230298
|
-
}
|
|
230299
|
-
if (status.projectMap) {
|
|
230300
|
-
lines.push("");
|
|
230301
|
-
lines.push("Project map:");
|
|
230302
|
-
lines.push([
|
|
230303
|
-
`dirs=${status.projectMap.topLevelDirectories.slice(0, 6).join(", ") || "none"}`,
|
|
230304
|
-
`scripts=${status.projectMap.packageScripts.slice(0, 6).join(", ") || "none"}`,
|
|
230305
|
-
`tests=${status.projectMap.testDirectories.slice(0, 4).join(", ") || "none"}`,
|
|
230306
|
-
status.projectMap.git.available ? `git=${status.projectMap.git.hasChanges ? "changed" : "clean"}` : "git=unavailable"
|
|
230307
|
-
].join(" "));
|
|
230308
|
-
}
|
|
230309
|
-
if (status.sessions.latest?.workset?.files.length) {
|
|
230310
|
-
lines.push("");
|
|
230311
|
-
lines.push("Workset:");
|
|
230312
|
-
for (const file of status.sessions.latest.workset.files) {
|
|
230313
|
-
lines.push([
|
|
230314
|
-
file.path,
|
|
230315
|
-
`read=${file.readCount}`,
|
|
230316
|
-
`changed=${file.changedCount}`,
|
|
230317
|
-
`last=${file.lastTool}`,
|
|
230318
|
-
file.lastChangeId ? `change=${file.lastChangeId}` : void 0,
|
|
230319
|
-
file.reason ? `reason=${file.reason}` : void 0
|
|
230320
|
-
].filter(Boolean).join(" "));
|
|
230321
|
-
}
|
|
230322
|
-
}
|
|
230323
|
-
if (status.sessions.latest?.contextBudget?.promptHotspots.length) {
|
|
230324
|
-
lines.push("");
|
|
230325
|
-
lines.push("Context budget hotspots:");
|
|
230326
|
-
for (const hotspot of status.sessions.latest.contextBudget.promptHotspots.slice(0, 3)) {
|
|
230327
|
-
lines.push([
|
|
230328
|
-
hotspot.layer,
|
|
230329
|
-
hotspot.title,
|
|
230330
|
-
`chars=${hotspot.chars}`,
|
|
230331
|
-
`lines=${hotspot.lines}`
|
|
230332
|
-
].join(" "));
|
|
230333
|
-
}
|
|
230334
|
-
}
|
|
230335
|
-
if (status.sessions.latest?.contextBudget?.sources.length) {
|
|
230336
|
-
lines.push("");
|
|
230337
|
-
lines.push("Context budget sources:");
|
|
230338
|
-
for (const source of status.sessions.latest.contextBudget.sources) {
|
|
230339
|
-
lines.push([
|
|
230340
|
-
source.name,
|
|
230341
|
-
`chars=${source.chars}`,
|
|
230342
|
-
source.messages === void 0 ? void 0 : `messages=${source.messages}`
|
|
230343
|
-
].filter(Boolean).join(" "));
|
|
230344
|
-
}
|
|
230345
|
-
}
|
|
230346
|
-
if (status.sessions.latest?.contextBudget?.cacheLayout) {
|
|
230347
|
-
const layout = status.sessions.latest.contextBudget.cacheLayout;
|
|
230348
|
-
lines.push("");
|
|
230349
|
-
lines.push("Cache layout:");
|
|
230350
|
-
lines.push([
|
|
230351
|
-
`stable=${layout.stablePrefixFingerprint}`,
|
|
230352
|
-
`stableChars=${layout.stablePrefixChars}`,
|
|
230353
|
-
`tail=${layout.volatileTailFingerprint}`,
|
|
230354
|
-
`tailChars=${layout.volatileTailChars}`
|
|
230355
|
-
].join(" "));
|
|
230356
|
-
}
|
|
230357
|
-
if (status.modelRequests.recent.length > 0) {
|
|
230358
|
-
lines.push("");
|
|
230359
|
-
lines.push("Recent model requests:");
|
|
230360
|
-
for (const request of status.modelRequests.recent.slice(0, 5)) {
|
|
230361
|
-
lines.push([
|
|
230362
|
-
request.model ?? "unknown-model",
|
|
230363
|
-
request.provider ? `provider=${request.provider}` : void 0,
|
|
230364
|
-
request.durationMs === void 0 ? void 0 : `duration=${request.durationMs}ms`,
|
|
230365
|
-
request.usage ? formatUsage(request.usage) : "usage=unavailable"
|
|
230366
|
-
].filter(Boolean).join(" "));
|
|
230367
|
-
}
|
|
230368
|
-
}
|
|
230369
|
-
if (status.executions.active.length > 0) {
|
|
230370
|
-
lines.push("");
|
|
230371
|
-
lines.push("Active executions:");
|
|
230372
|
-
for (const execution of status.executions.active) {
|
|
230373
|
-
lines.push([
|
|
230374
|
-
execution.id,
|
|
230375
|
-
execution.kind,
|
|
230376
|
-
execution.status,
|
|
230377
|
-
execution.actorName ? `actor=${execution.actorName}` : void 0,
|
|
230378
|
-
execution.waitPolicy ? `wait=${execution.waitPolicy}` : void 0,
|
|
230379
|
-
execution.health ? `health=${execution.health.state}` : void 0,
|
|
230380
|
-
execution.deadlineAt ? `deadline=${execution.deadlineAt}` : void 0,
|
|
230381
|
-
execution.assignment?.objective ? `objective=${truncateCliValue(execution.assignment.objective, 60)}` : void 0
|
|
230382
|
-
].filter(Boolean).join(" "));
|
|
230383
|
-
}
|
|
230384
|
-
}
|
|
230385
|
-
if (status.executions.recent.length > 0) {
|
|
230386
|
-
lines.push("");
|
|
230387
|
-
lines.push("Recent executions:");
|
|
230388
|
-
for (const execution of status.executions.recent.slice(0, 5)) {
|
|
230389
|
-
lines.push([
|
|
230390
|
-
execution.id,
|
|
230391
|
-
execution.kind,
|
|
230392
|
-
execution.status,
|
|
230393
|
-
execution.actorName ? `actor=${execution.actorName}` : void 0,
|
|
230394
|
-
execution.summary ? truncateCliValue(execution.summary, 80) : void 0,
|
|
230395
|
-
execution.assignment?.expectedOutput ? `expected=${truncateCliValue(execution.assignment.expectedOutput, 60)}` : void 0
|
|
230396
|
-
].filter(Boolean).join(" "));
|
|
230397
|
-
}
|
|
230398
|
-
}
|
|
230399
|
-
if (status.memory.assets.length > 0) {
|
|
230400
|
-
lines.push("");
|
|
230401
|
-
lines.push("Memory:");
|
|
230402
|
-
for (const memory of status.memory.assets.slice(0, 5)) {
|
|
230403
|
-
lines.push([
|
|
230404
|
-
memory.id,
|
|
230405
|
-
memory.kind,
|
|
230406
|
-
`bytes=${memory.size}`,
|
|
230407
|
-
memory.evidenceRefs.length > 0 ? `evidence=${memory.evidenceRefs.join(",")}` : void 0,
|
|
230408
|
-
memory.path
|
|
230409
|
-
].filter(Boolean).join(" "));
|
|
230410
|
-
}
|
|
230411
|
-
}
|
|
230412
|
-
if (status.skills.needsAttention.length > 0) {
|
|
230413
|
-
lines.push("");
|
|
230414
|
-
lines.push("Skills needing attention:");
|
|
230415
|
-
for (const skill of status.skills.needsAttention) {
|
|
230416
|
-
lines.push([
|
|
230417
|
-
skill.name,
|
|
230418
|
-
skill.path,
|
|
230419
|
-
`resources=${skill.resources}`,
|
|
230420
|
-
`dependencies=${skill.dependencies}`,
|
|
230421
|
-
skill.issues.length > 0 ? `issues=${skill.issues.join("; ")}` : void 0
|
|
230422
|
-
].filter(Boolean).join(" "));
|
|
230423
|
-
}
|
|
230424
|
-
}
|
|
230425
|
-
return `${lines.join("\n")}
|
|
230426
|
-
`;
|
|
230427
|
-
}
|
|
230428
|
-
function readFocus(status) {
|
|
230429
|
-
const focus = status.sessions.latest?.focus;
|
|
230430
|
-
return focus ? truncateCliValue(focus, 100) : "none";
|
|
230431
|
-
}
|
|
230432
|
-
function readSessionLine(status) {
|
|
230433
|
-
if (!status.sessions.latest) {
|
|
230434
|
-
return "none";
|
|
230435
|
-
}
|
|
230436
|
-
return `${status.sessions.latest.id} (${status.sessions.latest.messageCount} message(s))`;
|
|
230437
|
-
}
|
|
230438
|
-
function readNextStep(status) {
|
|
230439
|
-
if (status.executions.active.length > 0) {
|
|
230440
|
-
return "Wait for active execution results or inspect them with status/tools.";
|
|
230441
|
-
}
|
|
230442
|
-
if (!status.sessions.latest) {
|
|
230443
|
-
return "Start a session with `kitty` or run a prompt.";
|
|
230444
|
-
}
|
|
230445
|
-
return "Continue from the current session focus.";
|
|
230446
|
-
}
|
|
230447
|
-
function readBlockedLine(status) {
|
|
230448
|
-
const unhealthy = status.executions.active.find(
|
|
230449
|
-
(execution) => execution.health?.state === "stale" || execution.health?.state === "deadline_passed"
|
|
230450
|
-
);
|
|
230451
|
-
if (unhealthy) {
|
|
230452
|
-
return `${unhealthy.kind} ${unhealthy.id}: ${unhealthy.health?.message}`;
|
|
230453
|
-
}
|
|
230454
|
-
return "no";
|
|
230455
|
-
}
|
|
230456
|
-
function readContextBudgetLine(status) {
|
|
230457
|
-
const budget = status.sessions.latest?.contextBudget;
|
|
230458
|
-
if (!budget) {
|
|
230459
|
-
return "none";
|
|
230460
|
-
}
|
|
230461
|
-
const percent = Math.round(budget.usageRatio * 100);
|
|
230462
|
-
return [
|
|
230463
|
-
`${budget.estimatedChars}/${budget.limitChars} chars`,
|
|
230464
|
-
`${percent}%`,
|
|
230465
|
-
budget.compressed ? `compressed=${budget.compressionMode}` : "compressed=no",
|
|
230466
|
-
`reason=${budget.compressionReason}`
|
|
230467
|
-
].join(" ");
|
|
230468
|
-
}
|
|
230469
|
-
function readModelCacheLine(status) {
|
|
230470
|
-
const latest = status.modelRequests.recent[0];
|
|
230471
|
-
if (!latest) {
|
|
230472
|
-
return "none";
|
|
230473
|
-
}
|
|
230474
|
-
if (!latest.usage) {
|
|
230475
|
-
return "usage unavailable";
|
|
230476
|
-
}
|
|
230477
|
-
const cacheTokens = latest.usage.cacheHitTokens ?? latest.usage.cacheReadTokens;
|
|
230478
|
-
const rate = latest.usage.cacheHitRate === void 0 ? void 0 : `${Math.round(latest.usage.cacheHitRate * 100)}%`;
|
|
230479
|
-
return [
|
|
230480
|
-
cacheTokens === void 0 ? "cached=unknown" : `cached=${cacheTokens}`,
|
|
230481
|
-
rate ? `hit=${rate}` : void 0
|
|
230482
|
-
].filter(Boolean).join(" ");
|
|
230483
|
-
}
|
|
230484
|
-
function formatUsage(usage) {
|
|
230485
|
-
return [
|
|
230486
|
-
usage.inputTokens === void 0 ? void 0 : `input=${usage.inputTokens}`,
|
|
230487
|
-
usage.outputTokens === void 0 ? void 0 : `output=${usage.outputTokens}`,
|
|
230488
|
-
usage.reasoningTokens === void 0 ? void 0 : `reasoning=${usage.reasoningTokens}`,
|
|
230489
|
-
usage.cacheHitTokens === void 0 ? void 0 : `cacheHit=${usage.cacheHitTokens}`,
|
|
230490
|
-
usage.cacheReadTokens === void 0 ? void 0 : `cacheRead=${usage.cacheReadTokens}`,
|
|
230491
|
-
usage.cacheCreationTokens === void 0 ? void 0 : `cacheWrite=${usage.cacheCreationTokens}`,
|
|
230492
|
-
usage.cacheMissTokens === void 0 ? void 0 : `cacheMiss=${usage.cacheMissTokens}`,
|
|
230493
|
-
usage.cacheHitRate === void 0 ? void 0 : `hit=${Math.round(usage.cacheHitRate * 100)}%`
|
|
230494
|
-
].filter(Boolean).join(" ");
|
|
230495
|
-
}
|
|
230496
|
-
var init_runtimeStatusPresenter = __esm({
|
|
230497
|
-
"src/cli/commands/runtimeStatusPresenter.ts"() {
|
|
230498
|
-
"use strict";
|
|
230499
|
-
init_cliValues();
|
|
230500
|
-
}
|
|
230501
|
-
});
|
|
230502
|
-
|
|
230503
231205
|
// src/cli/commands/runtimeStatus.ts
|
|
230504
231206
|
function registerRuntimeStatusCommand(program, options) {
|
|
230505
231207
|
program.command("status").description("Show the current project runtime status.").option("--json", "Print structured JSON.").action(async (commandOptions) => {
|
|
@@ -230814,74 +231516,6 @@ var init_agent = __esm({
|
|
|
230814
231516
|
}
|
|
230815
231517
|
});
|
|
230816
231518
|
|
|
230817
|
-
// src/cli/commands/background.ts
|
|
230818
|
-
function registerBackgroundCommand(program, options) {
|
|
230819
|
-
const command = program.command("background").description("Inspect, wait for, or stop background executions.");
|
|
230820
|
-
command.argument("[action]", "Optional action: list, wait, stop").argument("[id]", "Background execution id for wait or stop").option("--json", "Print structured JSON.").option("--timeout-ms <ms>", "Wait timeout in milliseconds.", (value) => Number.parseInt(value, 10), 6e4).action(async (action, id, commandOptions) => {
|
|
230821
|
-
const runtime = await options.resolveRuntime(options.getCliOverrides());
|
|
230822
|
-
const normalizedAction = action ?? "list";
|
|
230823
|
-
if (normalizedAction === "list") {
|
|
230824
|
-
const executions = new BackgroundExecutionStore(runtime.stateRootDir).listAll().map(summarizeExecution).sort((left, right) => right.updatedAt.localeCompare(left.updatedAt));
|
|
230825
|
-
printBackgroundExecutions(executions, Boolean(commandOptions.json));
|
|
230826
|
-
return;
|
|
230827
|
-
}
|
|
230828
|
-
if (!id) {
|
|
230829
|
-
throw new Error(`background ${normalizedAction} requires an execution id.`);
|
|
230830
|
-
}
|
|
230831
|
-
if (normalizedAction === "wait") {
|
|
230832
|
-
const execution = summarizeExecution(await waitForBackgroundExecution({
|
|
230833
|
-
rootDir: runtime.stateRootDir,
|
|
230834
|
-
id,
|
|
230835
|
-
timeoutMs: commandOptions.timeoutMs
|
|
230836
|
-
}));
|
|
230837
|
-
printBackgroundExecutions([execution], Boolean(commandOptions.json));
|
|
230838
|
-
return;
|
|
230839
|
-
}
|
|
230840
|
-
if (normalizedAction === "stop") {
|
|
230841
|
-
const execution = terminateBackgroundExecution(runtime.stateRootDir, id);
|
|
230842
|
-
await waitForRegisteredBackgroundProcess(id);
|
|
230843
|
-
printBackgroundExecutions([summarizeExecution(execution)], Boolean(commandOptions.json));
|
|
230844
|
-
return;
|
|
230845
|
-
}
|
|
230846
|
-
throw new Error(`Unknown background action: ${normalizedAction}. Use list, wait, or stop.`);
|
|
230847
|
-
});
|
|
230848
|
-
}
|
|
230849
|
-
function printBackgroundExecutions(executions, json) {
|
|
230850
|
-
if (json) {
|
|
230851
|
-
writeStdoutLine(JSON.stringify({ executions }, null, 2));
|
|
230852
|
-
return;
|
|
230853
|
-
}
|
|
230854
|
-
if (executions.length === 0) {
|
|
230855
|
-
ui.info("No background executions recorded.");
|
|
230856
|
-
return;
|
|
230857
|
-
}
|
|
230858
|
-
for (const execution of executions) {
|
|
230859
|
-
writeStdoutLine(formatBackgroundExecution(execution));
|
|
230860
|
-
}
|
|
230861
|
-
}
|
|
230862
|
-
function formatBackgroundExecution(execution) {
|
|
230863
|
-
return [
|
|
230864
|
-
execution.id,
|
|
230865
|
-
execution.status,
|
|
230866
|
-
execution.pid === void 0 ? void 0 : `pid=${execution.pid}`,
|
|
230867
|
-
execution.health ? `health=${execution.health.state}` : void 0,
|
|
230868
|
-
execution.deadlineAt ? `deadline=${execution.deadlineAt}` : void 0,
|
|
230869
|
-
execution.command ? `cmd=${truncateCliValue(execution.command, 70)}` : void 0,
|
|
230870
|
-
execution.summary ? `summary=${truncateCliValue(execution.summary, 90)}` : void 0,
|
|
230871
|
-
execution.outputPreview ? `output=${truncateCliValue(execution.outputPreview, 120)}` : void 0
|
|
230872
|
-
].filter(Boolean).join(" ");
|
|
230873
|
-
}
|
|
230874
|
-
var init_background3 = __esm({
|
|
230875
|
-
"src/cli/commands/background.ts"() {
|
|
230876
|
-
"use strict";
|
|
230877
|
-
init_background();
|
|
230878
|
-
init_executionSummary();
|
|
230879
|
-
init_console();
|
|
230880
|
-
init_stdio();
|
|
230881
|
-
init_cliValues();
|
|
230882
|
-
}
|
|
230883
|
-
});
|
|
230884
|
-
|
|
230885
231519
|
// src/cli/commands/session.ts
|
|
230886
231520
|
function registerSessionCommands(program, options) {
|
|
230887
231521
|
program.argument("[prompt...]", "Start a new session with a one-shot prompt. Without a prompt, opens interactive chat.").action(async (promptParts) => {
|
|
@@ -231839,7 +232473,6 @@ var init_helpText_zh = __esm({
|
|
|
231839
232473
|
"/stop Stop the current Telegram task without shutting down the bot service",
|
|
231840
232474
|
"/session Show the session ID bound to this Telegram chat",
|
|
231841
232475
|
"/config Show current runtime configuration",
|
|
231842
|
-
"/multi Telegram does not support interactive multiline mode; send the full message directly",
|
|
231843
232476
|
"",
|
|
231844
232477
|
"File usage:",
|
|
231845
232478
|
"- Send files directly to the private chat. Kitty downloads them and attaches them to the current session.",
|
|
@@ -232286,11 +232919,6 @@ async function runTelegramTurn(options) {
|
|
|
232286
232919
|
options.markQueuedTurnStarted(options.message.peerKey);
|
|
232287
232920
|
return;
|
|
232288
232921
|
}
|
|
232289
|
-
if (localCommandResult === "multiline") {
|
|
232290
|
-
options.markQueuedTurnStarted(options.message.peerKey);
|
|
232291
|
-
output.warn("Telegram does not support interactive multiline mode. Send the full message directly.");
|
|
232292
|
-
return;
|
|
232293
|
-
}
|
|
232294
232922
|
}
|
|
232295
232923
|
const display = new TelegramTurnDisplay({
|
|
232296
232924
|
chatId: options.message.chatId,
|
|
@@ -233417,6 +234045,39 @@ var init_web2 = __esm({
|
|
|
233417
234045
|
}
|
|
233418
234046
|
});
|
|
233419
234047
|
|
|
234048
|
+
// src/cli/commands/tui.ts
|
|
234049
|
+
function registerTuiCommand(program, dependencies) {
|
|
234050
|
+
program.command("tui").description("Start the Ink terminal UI.").action(async () => {
|
|
234051
|
+
if (!process.stdin.isTTY || !process.stdout.isTTY) {
|
|
234052
|
+
throw new Error("kitty tui requires an interactive TTY.");
|
|
234053
|
+
}
|
|
234054
|
+
const runtime = await dependencies.resolveRuntime(dependencies.getCliOverrides());
|
|
234055
|
+
const sessionStore = await createSessionStore(runtime.paths.sessionsDir);
|
|
234056
|
+
const { startTuiChat } = await loadTuiEntrypoint();
|
|
234057
|
+
await startTuiChat({
|
|
234058
|
+
cwd: runtime.cwd,
|
|
234059
|
+
cwdOverridden: Boolean(runtime.overrides.cwd),
|
|
234060
|
+
config: runtime.config,
|
|
234061
|
+
sessionStore
|
|
234062
|
+
});
|
|
234063
|
+
});
|
|
234064
|
+
}
|
|
234065
|
+
async function loadTuiEntrypoint() {
|
|
234066
|
+
try {
|
|
234067
|
+
return await import(new URL("./tui.mjs", (0, import_node_url.pathToFileURL)(__filename)).href);
|
|
234068
|
+
} catch (error) {
|
|
234069
|
+
throw new Error(`TUI entrypoint is unavailable. Run npm.cmd run build and try again. Cause: ${error instanceof Error ? error.message : String(error)}`);
|
|
234070
|
+
}
|
|
234071
|
+
}
|
|
234072
|
+
var import_node_url;
|
|
234073
|
+
var init_tui = __esm({
|
|
234074
|
+
"src/cli/commands/tui.ts"() {
|
|
234075
|
+
"use strict";
|
|
234076
|
+
import_node_url = require("url");
|
|
234077
|
+
init_sessionHelpers();
|
|
234078
|
+
}
|
|
234079
|
+
});
|
|
234080
|
+
|
|
233420
234081
|
// src/cli/program.ts
|
|
233421
234082
|
var program_exports = {};
|
|
233422
234083
|
__export(program_exports, {
|
|
@@ -233491,6 +234152,10 @@ function buildCliProgram(dependencies = {}) {
|
|
|
233491
234152
|
getCliOverrides,
|
|
233492
234153
|
resolveRuntime
|
|
233493
234154
|
});
|
|
234155
|
+
registerTuiCommand(program, {
|
|
234156
|
+
getCliOverrides,
|
|
234157
|
+
resolveRuntime
|
|
234158
|
+
});
|
|
233494
234159
|
return program;
|
|
233495
234160
|
}
|
|
233496
234161
|
var import_commander;
|
|
@@ -233513,6 +234178,7 @@ var init_program = __esm({
|
|
|
233513
234178
|
init_stdio();
|
|
233514
234179
|
init_cli();
|
|
233515
234180
|
init_web2();
|
|
234181
|
+
init_tui();
|
|
233516
234182
|
}
|
|
233517
234183
|
});
|
|
233518
234184
|
|