@hasna/assistants 1.1.78 → 1.1.80
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/config/settings.json +7 -0
- package/dist/index.js +542 -115
- package/dist/index.js.map +17 -16
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -293,6 +293,18 @@ function deepMerge(base, override) {
|
|
|
293
293
|
}
|
|
294
294
|
|
|
295
295
|
// packages/core/src/config.ts
|
|
296
|
+
var exports_config = {};
|
|
297
|
+
__export(exports_config, {
|
|
298
|
+
loadSystemPrompt: () => loadSystemPrompt,
|
|
299
|
+
loadHooksConfig: () => loadHooksConfig,
|
|
300
|
+
loadConfig: () => loadConfig,
|
|
301
|
+
getTempFolder: () => getTempFolder,
|
|
302
|
+
getProjectDataDir: () => getProjectDataDir,
|
|
303
|
+
getProjectConfigDir: () => getProjectConfigDir,
|
|
304
|
+
getConfigPath: () => getConfigPath,
|
|
305
|
+
getConfigDir: () => getConfigDir,
|
|
306
|
+
ensureConfigDir: () => ensureConfigDir
|
|
307
|
+
});
|
|
296
308
|
import { join } from "path";
|
|
297
309
|
import { homedir } from "os";
|
|
298
310
|
function mergeConnectorsConfig(base, override) {
|
|
@@ -380,6 +392,28 @@ function migrateConfigKeys(config) {
|
|
|
380
392
|
}
|
|
381
393
|
return config;
|
|
382
394
|
}
|
|
395
|
+
async function loadHooksConfig(cwd = process.cwd(), baseDir) {
|
|
396
|
+
const hooks = {};
|
|
397
|
+
const userHooksPath = getConfigPath("hooks.json", baseDir);
|
|
398
|
+
const userHooks = await loadJsonFile(userHooksPath);
|
|
399
|
+
if (userHooks?.hooks) {
|
|
400
|
+
mergeHooks(hooks, userHooks.hooks);
|
|
401
|
+
}
|
|
402
|
+
const projectHooksPath = join(getProjectConfigDir(cwd), "hooks.json");
|
|
403
|
+
const projectHooks = await loadJsonFile(projectHooksPath);
|
|
404
|
+
if (projectHooks?.hooks) {
|
|
405
|
+
mergeHooks(hooks, projectHooks.hooks);
|
|
406
|
+
}
|
|
407
|
+
return hooks;
|
|
408
|
+
}
|
|
409
|
+
function mergeHooks(target, source) {
|
|
410
|
+
for (const [event, matchers] of Object.entries(source)) {
|
|
411
|
+
if (!target[event]) {
|
|
412
|
+
target[event] = [];
|
|
413
|
+
}
|
|
414
|
+
target[event].push(...matchers);
|
|
415
|
+
}
|
|
416
|
+
}
|
|
383
417
|
async function loadJsonFile(path) {
|
|
384
418
|
try {
|
|
385
419
|
if (!hasRuntime()) {
|
|
@@ -417,6 +451,9 @@ async function ensureConfigDir(sessionId, baseDir) {
|
|
|
417
451
|
}
|
|
418
452
|
await Promise.all(dirs);
|
|
419
453
|
}
|
|
454
|
+
function getTempFolder(sessionId, baseDir) {
|
|
455
|
+
return join(baseDir || getConfigDir(), "temp", sessionId);
|
|
456
|
+
}
|
|
420
457
|
async function loadSystemPrompt(cwd = process.cwd(), baseDir) {
|
|
421
458
|
const prompts = [];
|
|
422
459
|
const globalPromptPath = getConfigPath("ASSISTANTS.md", baseDir);
|
|
@@ -712,7 +749,15 @@ var init_config = __esm(async () => {
|
|
|
712
749
|
},
|
|
713
750
|
mode: "placeholder"
|
|
714
751
|
}
|
|
715
|
-
}
|
|
752
|
+
},
|
|
753
|
+
workspace: {
|
|
754
|
+
mode: "sandbox",
|
|
755
|
+
customPath: null
|
|
756
|
+
},
|
|
757
|
+
permissions: {
|
|
758
|
+
bash: "readonly"
|
|
759
|
+
},
|
|
760
|
+
backgroundModel: "claude-haiku-4-5-20251001"
|
|
716
761
|
};
|
|
717
762
|
});
|
|
718
763
|
|
|
@@ -24692,7 +24737,7 @@ var init_bash = __esm(async () => {
|
|
|
24692
24737
|
BashTool = class BashTool {
|
|
24693
24738
|
static tool = {
|
|
24694
24739
|
name: "bash",
|
|
24695
|
-
description:
|
|
24740
|
+
description: 'Execute a shell command. Permission level is controlled by permissions.bash in config: "none" (disabled), "readonly" (default \u2014 ls, cat, grep, find, git status/log/diff, pwd, which, echo), or "readwrite" (broader commands, destructive ops still blocked).',
|
|
24696
24741
|
parameters: {
|
|
24697
24742
|
type: "object",
|
|
24698
24743
|
properties: {
|
|
@@ -24810,6 +24855,86 @@ var init_bash = __esm(async () => {
|
|
|
24810
24855
|
/^connect-[a-z0-9._-]+$/i,
|
|
24811
24856
|
/^@hasna\/[a-z0-9._-]+$/i
|
|
24812
24857
|
];
|
|
24858
|
+
static READWRITE_ALLOWED_COMMANDS = [
|
|
24859
|
+
"mkdir",
|
|
24860
|
+
"touch",
|
|
24861
|
+
"cp",
|
|
24862
|
+
"mv",
|
|
24863
|
+
"ln",
|
|
24864
|
+
"tee",
|
|
24865
|
+
"sed",
|
|
24866
|
+
"awk",
|
|
24867
|
+
"tar",
|
|
24868
|
+
"zip",
|
|
24869
|
+
"unzip",
|
|
24870
|
+
"gzip",
|
|
24871
|
+
"gunzip",
|
|
24872
|
+
"bzip2",
|
|
24873
|
+
"bunzip2",
|
|
24874
|
+
"git add",
|
|
24875
|
+
"git commit",
|
|
24876
|
+
"git push",
|
|
24877
|
+
"git pull",
|
|
24878
|
+
"git checkout",
|
|
24879
|
+
"git switch",
|
|
24880
|
+
"git merge",
|
|
24881
|
+
"git rebase",
|
|
24882
|
+
"git stash",
|
|
24883
|
+
"git cherry-pick",
|
|
24884
|
+
"git revert",
|
|
24885
|
+
"git reset",
|
|
24886
|
+
"git restore",
|
|
24887
|
+
"git init",
|
|
24888
|
+
"git clone",
|
|
24889
|
+
"git fetch",
|
|
24890
|
+
"git branch",
|
|
24891
|
+
"npm",
|
|
24892
|
+
"pnpm",
|
|
24893
|
+
"yarn",
|
|
24894
|
+
"bun",
|
|
24895
|
+
"pip",
|
|
24896
|
+
"pip3",
|
|
24897
|
+
"make",
|
|
24898
|
+
"cmake",
|
|
24899
|
+
"kill",
|
|
24900
|
+
"pkill",
|
|
24901
|
+
"chmod",
|
|
24902
|
+
"chown",
|
|
24903
|
+
"docker",
|
|
24904
|
+
"node",
|
|
24905
|
+
"bun",
|
|
24906
|
+
"npx",
|
|
24907
|
+
"bunx",
|
|
24908
|
+
"tsx",
|
|
24909
|
+
"ts-node",
|
|
24910
|
+
"python",
|
|
24911
|
+
"python3",
|
|
24912
|
+
"rm",
|
|
24913
|
+
"rmdir"
|
|
24914
|
+
];
|
|
24915
|
+
static READWRITE_BLOCKED_PATTERNS = [
|
|
24916
|
+
/\brm\s+(-[a-zA-Z]*f[a-zA-Z]*\s+)?(-[a-zA-Z]*r[a-zA-Z]*\s+)?(\/|~\/?\s|\.\.\/)/,
|
|
24917
|
+
/\brm\s+(-[a-zA-Z]*r[a-zA-Z]*\s+)?(-[a-zA-Z]*f[a-zA-Z]*\s+)?(\/|~\/?\s|\.\.\/)/,
|
|
24918
|
+
/\brm\s+-rf\s+\/(?!\S)/,
|
|
24919
|
+
/\brm\s+-rf\s+~\/?(?:\s|$)/,
|
|
24920
|
+
/\bmkfs\b/,
|
|
24921
|
+
/\bdd\b/,
|
|
24922
|
+
/\bfdisk\b/,
|
|
24923
|
+
/\bparted\b/,
|
|
24924
|
+
/\bsudo\b/,
|
|
24925
|
+
/\bsu\b/,
|
|
24926
|
+
/\bdoas\b/,
|
|
24927
|
+
/\bchmod\s+777\b/,
|
|
24928
|
+
/curl.*\|\s*(bash|sh)/,
|
|
24929
|
+
/wget.*\|\s*(bash|sh)/,
|
|
24930
|
+
/\bnc\s+-l/,
|
|
24931
|
+
/\bnetcat\s+-l/,
|
|
24932
|
+
/\bvim?\b/,
|
|
24933
|
+
/\bnano\b/,
|
|
24934
|
+
/\bemacs\b/,
|
|
24935
|
+
/:\(\)\s*\{/,
|
|
24936
|
+
/\bfork\s*bomb/i
|
|
24937
|
+
];
|
|
24813
24938
|
static getBunGlobalInstallInfo(command) {
|
|
24814
24939
|
const parts = this.splitCommandByOperators(command);
|
|
24815
24940
|
if (parts.length !== 1) {
|
|
@@ -25045,16 +25170,22 @@ var init_bash = __esm(async () => {
|
|
|
25045
25170
|
let allowEnv = true;
|
|
25046
25171
|
let allowAll = false;
|
|
25047
25172
|
let allowPackageInstall = false;
|
|
25173
|
+
let bashPermission = "readonly";
|
|
25048
25174
|
try {
|
|
25049
25175
|
const config = await loadConfig(cwd);
|
|
25050
25176
|
const bashConfig = config.validation?.perTool?.bash;
|
|
25051
25177
|
allowEnv = bashConfig?.allowEnv ?? true;
|
|
25052
25178
|
allowAll = bashConfig?.allowAll ?? false;
|
|
25053
25179
|
allowPackageInstall = bashConfig?.allowPackageInstall ?? false;
|
|
25180
|
+
bashPermission = config.permissions?.bash ?? "readonly";
|
|
25054
25181
|
} catch {
|
|
25055
25182
|
allowEnv = true;
|
|
25056
25183
|
allowAll = false;
|
|
25057
25184
|
allowPackageInstall = false;
|
|
25185
|
+
bashPermission = "readonly";
|
|
25186
|
+
}
|
|
25187
|
+
if (bashPermission === "none") {
|
|
25188
|
+
throw toolPermissionDenied("bash", 'Bash is disabled. Change permissions.bash in config to "readonly" or "readwrite" to enable.', input);
|
|
25058
25189
|
}
|
|
25059
25190
|
const baseCommand = command.replace(/\s*2>&1\s*/g, " ").trim();
|
|
25060
25191
|
const baseTrimmed = baseCommand.toLowerCase();
|
|
@@ -25079,7 +25210,8 @@ var init_bash = __esm(async () => {
|
|
|
25079
25210
|
throw toolPermissionDenied("bash", securityCheck.reason || "Blocked command", input);
|
|
25080
25211
|
}
|
|
25081
25212
|
if (!allowAll && !allowGlobalInstall) {
|
|
25082
|
-
|
|
25213
|
+
const blockedPatterns = bashPermission === "readwrite" ? this.READWRITE_BLOCKED_PATTERNS : this.BLOCKED_PATTERNS;
|
|
25214
|
+
for (const pattern of blockedPatterns) {
|
|
25083
25215
|
if (pattern.test(commandSansQuotes)) {
|
|
25084
25216
|
getSecurityLogger().log({
|
|
25085
25217
|
eventType: "blocked_command",
|
|
@@ -25091,7 +25223,8 @@ var init_bash = __esm(async () => {
|
|
|
25091
25223
|
},
|
|
25092
25224
|
sessionId: input.sessionId || "unknown"
|
|
25093
25225
|
});
|
|
25094
|
-
|
|
25226
|
+
const modeLabel = bashPermission === "readwrite" ? "readwrite" : "readonly";
|
|
25227
|
+
throw toolPermissionDenied("bash", `Blocked: command is not allowed in ${modeLabel} mode. ${bashPermission === "readonly" ? "Only read-only commands are permitted (ls, cat, grep, find, git status/log/diff, etc.)." : "Destructive operations (rm -rf /, mkfs, dd, sudo, etc.) are blocked even in readwrite mode."}`, input);
|
|
25095
25228
|
}
|
|
25096
25229
|
}
|
|
25097
25230
|
}
|
|
@@ -25111,7 +25244,10 @@ var init_bash = __esm(async () => {
|
|
|
25111
25244
|
throw toolPermissionDenied("bash", "Command not allowed: env/printenv disabled by config.", input);
|
|
25112
25245
|
}
|
|
25113
25246
|
if (!allowAll && !allowGlobalInstall) {
|
|
25114
|
-
|
|
25247
|
+
let allowlist = allowEnv ? this.ALLOWED_COMMANDS : this.ALLOWED_COMMANDS.filter((allowed) => allowed !== "env" && allowed !== "printenv");
|
|
25248
|
+
if (bashPermission === "readwrite") {
|
|
25249
|
+
allowlist = [...allowlist, ...this.READWRITE_ALLOWED_COMMANDS];
|
|
25250
|
+
}
|
|
25115
25251
|
const isAllowed = this.areAllCommandPartsAllowed(commandForChecks, allowlist);
|
|
25116
25252
|
if (!isAllowed) {
|
|
25117
25253
|
getSecurityLogger().log({
|
|
@@ -25124,7 +25260,8 @@ var init_bash = __esm(async () => {
|
|
|
25124
25260
|
},
|
|
25125
25261
|
sessionId: input.sessionId || "unknown"
|
|
25126
25262
|
});
|
|
25127
|
-
|
|
25263
|
+
const modeLabel = bashPermission === "readwrite" ? "readwrite" : "readonly";
|
|
25264
|
+
throw toolPermissionDenied("bash", `Blocked: command is not allowed in ${modeLabel} mode. ${bashPermission === "readonly" ? "Permitted commands: cat, head, tail, ls, find, grep, wc, file, stat, pwd, which, echo, curl, git status/log/diff/branch/show, connect-*" : "The command is not in the readwrite allowlist. Destructive system operations remain blocked."}`, input);
|
|
25128
25265
|
}
|
|
25129
25266
|
const ssrfCheck = await this.validateCurlSsrf(commandForChecks);
|
|
25130
25267
|
if (!ssrfCheck.valid) {
|
|
@@ -25400,7 +25537,23 @@ function isInScriptsFolder(path2, cwd, sessionId) {
|
|
|
25400
25537
|
return true;
|
|
25401
25538
|
return resolved.startsWith(`${scriptsFolder}${sep}`);
|
|
25402
25539
|
}
|
|
25403
|
-
|
|
25540
|
+
function isDangerousPath(resolvedPath) {
|
|
25541
|
+
const parts = resolvedPath.split(sep);
|
|
25542
|
+
for (const dir of DANGEROUS_DIRS) {
|
|
25543
|
+
if (parts.includes(dir)) {
|
|
25544
|
+
return `Writing to '${dir}' is not allowed for safety reasons`;
|
|
25545
|
+
}
|
|
25546
|
+
}
|
|
25547
|
+
return null;
|
|
25548
|
+
}
|
|
25549
|
+
function isWithinDir(filePath, rootDir) {
|
|
25550
|
+
const resolvedFile = resolve4(filePath);
|
|
25551
|
+
const resolvedRoot = resolve4(rootDir);
|
|
25552
|
+
if (resolvedFile === resolvedRoot)
|
|
25553
|
+
return true;
|
|
25554
|
+
return resolvedFile.startsWith(`${resolvedRoot}${sep}`);
|
|
25555
|
+
}
|
|
25556
|
+
var currentSessionId = "default", currentWorkspaceConfig, DANGEROUS_DIRS, FilesystemTools;
|
|
25404
25557
|
var init_filesystem = __esm(async () => {
|
|
25405
25558
|
init_errors();
|
|
25406
25559
|
init_paths();
|
|
@@ -25411,6 +25564,17 @@ var init_filesystem = __esm(async () => {
|
|
|
25411
25564
|
init_runtime(),
|
|
25412
25565
|
init_logger()
|
|
25413
25566
|
]);
|
|
25567
|
+
currentWorkspaceConfig = { mode: "sandbox", customPath: null };
|
|
25568
|
+
DANGEROUS_DIRS = [
|
|
25569
|
+
"node_modules",
|
|
25570
|
+
".git",
|
|
25571
|
+
".svn",
|
|
25572
|
+
".hg",
|
|
25573
|
+
".DS_Store",
|
|
25574
|
+
"__pycache__",
|
|
25575
|
+
".env",
|
|
25576
|
+
".venv"
|
|
25577
|
+
];
|
|
25414
25578
|
FilesystemTools = class FilesystemTools {
|
|
25415
25579
|
static resolveInputPath(baseCwd, inputPath) {
|
|
25416
25580
|
const envHome = process.env.HOME || process.env.USERPROFILE;
|
|
@@ -25423,10 +25587,13 @@ var init_filesystem = __esm(async () => {
|
|
|
25423
25587
|
}
|
|
25424
25588
|
return resolve4(baseCwd, inputPath);
|
|
25425
25589
|
}
|
|
25426
|
-
static registerAll(registry, sessionId) {
|
|
25590
|
+
static registerAll(registry, sessionId, workspaceConfig) {
|
|
25427
25591
|
if (sessionId) {
|
|
25428
25592
|
currentSessionId = sessionId;
|
|
25429
25593
|
}
|
|
25594
|
+
if (workspaceConfig) {
|
|
25595
|
+
currentWorkspaceConfig = workspaceConfig;
|
|
25596
|
+
}
|
|
25430
25597
|
registry.register(this.readTool, this.readExecutor);
|
|
25431
25598
|
registry.register(this.writeTool, this.writeExecutor);
|
|
25432
25599
|
registry.register(this.globTool, this.globExecutor);
|
|
@@ -25608,17 +25775,17 @@ var init_filesystem = __esm(async () => {
|
|
|
25608
25775
|
};
|
|
25609
25776
|
static writeTool = {
|
|
25610
25777
|
name: "write",
|
|
25611
|
-
description:
|
|
25778
|
+
description: 'Write content to a file. Behavior depends on workspace.mode in config: "sandbox" (default) restricts writes to .assistants-data/scripts/{session}/, "project" allows writing anywhere in the project directory, "custom" allows writing to a configured custom path. Dangerous directories (node_modules, .git, etc.) are always blocked.',
|
|
25612
25779
|
parameters: {
|
|
25613
25780
|
type: "object",
|
|
25614
25781
|
properties: {
|
|
25615
25782
|
filename: {
|
|
25616
25783
|
type: "string",
|
|
25617
|
-
description: "The filename to write to
|
|
25784
|
+
description: "The filename to write to. In sandbox mode, saved in the project scripts folder. In project/custom mode, can be a relative or absolute path within the workspace."
|
|
25618
25785
|
},
|
|
25619
25786
|
path: {
|
|
25620
25787
|
type: "string",
|
|
25621
|
-
description: "Alias for filename
|
|
25788
|
+
description: "Alias for filename"
|
|
25622
25789
|
},
|
|
25623
25790
|
content: {
|
|
25624
25791
|
type: "string",
|
|
@@ -25650,7 +25817,6 @@ var init_filesystem = __esm(async () => {
|
|
|
25650
25817
|
suggestion: "Provide string content to write."
|
|
25651
25818
|
});
|
|
25652
25819
|
}
|
|
25653
|
-
const scriptsFolder = getScriptsFolder(baseCwd, input.sessionId);
|
|
25654
25820
|
if (!filename || !filename.trim()) {
|
|
25655
25821
|
throw new ToolExecutionError("Filename or path is required", {
|
|
25656
25822
|
toolName: "write",
|
|
@@ -25661,20 +25827,83 @@ var init_filesystem = __esm(async () => {
|
|
|
25661
25827
|
suggestion: "Provide a filename and try again."
|
|
25662
25828
|
});
|
|
25663
25829
|
}
|
|
25664
|
-
const
|
|
25665
|
-
|
|
25666
|
-
|
|
25667
|
-
|
|
25830
|
+
const mode = currentWorkspaceConfig.mode || "sandbox";
|
|
25831
|
+
let resolvedPath;
|
|
25832
|
+
let allowedRoot;
|
|
25833
|
+
if (mode === "sandbox") {
|
|
25834
|
+
const scriptsFolder = getScriptsFolder(baseCwd, input.sessionId);
|
|
25835
|
+
const sanitizedFilename = filename.replace(/\.\.[/\\]/g, "").replace(/\.\./g, "").replace(/^[/\\]+/, "");
|
|
25836
|
+
resolvedPath = join14(scriptsFolder, sanitizedFilename);
|
|
25837
|
+
allowedRoot = scriptsFolder;
|
|
25838
|
+
if (!isInScriptsFolder(resolvedPath, baseCwd, input.sessionId)) {
|
|
25839
|
+
throw new ToolExecutionError(`Cannot write outside scripts folder. Files are saved to ${scriptsFolder}`, {
|
|
25840
|
+
toolName: "write",
|
|
25841
|
+
toolInput: input,
|
|
25842
|
+
code: ErrorCodes.TOOL_PERMISSION_DENIED,
|
|
25843
|
+
recoverable: false,
|
|
25844
|
+
retryable: false,
|
|
25845
|
+
suggestion: "Write only within the project scripts folder."
|
|
25846
|
+
});
|
|
25847
|
+
}
|
|
25848
|
+
} else if (mode === "project") {
|
|
25849
|
+
resolvedPath = FilesystemTools.resolveInputPath(baseCwd, filename);
|
|
25850
|
+
allowedRoot = resolve4(baseCwd);
|
|
25851
|
+
if (!isWithinDir(resolvedPath, allowedRoot)) {
|
|
25852
|
+
throw new ToolExecutionError(`Cannot write outside the project directory (${allowedRoot}). Use workspace.mode "custom" with a customPath to write elsewhere.`, {
|
|
25853
|
+
toolName: "write",
|
|
25854
|
+
toolInput: input,
|
|
25855
|
+
code: ErrorCodes.TOOL_PERMISSION_DENIED,
|
|
25856
|
+
recoverable: false,
|
|
25857
|
+
retryable: false,
|
|
25858
|
+
suggestion: "Provide a path within the project directory."
|
|
25859
|
+
});
|
|
25860
|
+
}
|
|
25861
|
+
} else if (mode === "custom") {
|
|
25862
|
+
const customPath = currentWorkspaceConfig.customPath;
|
|
25863
|
+
if (!customPath) {
|
|
25864
|
+
throw new ToolExecutionError('Workspace mode is "custom" but no customPath is configured. Set workspace.customPath in your config.', {
|
|
25865
|
+
toolName: "write",
|
|
25866
|
+
toolInput: input,
|
|
25867
|
+
code: ErrorCodes.TOOL_EXECUTION_FAILED,
|
|
25868
|
+
recoverable: false,
|
|
25869
|
+
retryable: false,
|
|
25870
|
+
suggestion: "Set workspace.customPath to an absolute path in config."
|
|
25871
|
+
});
|
|
25872
|
+
}
|
|
25873
|
+
allowedRoot = resolve4(customPath);
|
|
25874
|
+
resolvedPath = FilesystemTools.resolveInputPath(allowedRoot, filename);
|
|
25875
|
+
if (!isWithinDir(resolvedPath, allowedRoot)) {
|
|
25876
|
+
throw new ToolExecutionError(`Cannot write outside the custom workspace (${allowedRoot}).`, {
|
|
25877
|
+
toolName: "write",
|
|
25878
|
+
toolInput: input,
|
|
25879
|
+
code: ErrorCodes.TOOL_PERMISSION_DENIED,
|
|
25880
|
+
recoverable: false,
|
|
25881
|
+
retryable: false,
|
|
25882
|
+
suggestion: `Provide a path within ${allowedRoot}.`
|
|
25883
|
+
});
|
|
25884
|
+
}
|
|
25885
|
+
} else {
|
|
25886
|
+
throw new ToolExecutionError(`Unknown workspace mode: "${mode}". Valid modes: sandbox, project, custom.`, {
|
|
25887
|
+
toolName: "write",
|
|
25888
|
+
toolInput: input,
|
|
25889
|
+
code: ErrorCodes.VALIDATION_OUT_OF_RANGE,
|
|
25890
|
+
recoverable: false,
|
|
25891
|
+
retryable: false
|
|
25892
|
+
});
|
|
25893
|
+
}
|
|
25894
|
+
const dangerousReason = isDangerousPath(resolvedPath);
|
|
25895
|
+
if (dangerousReason) {
|
|
25896
|
+
throw new ToolExecutionError(dangerousReason, {
|
|
25668
25897
|
toolName: "write",
|
|
25669
25898
|
toolInput: input,
|
|
25670
25899
|
code: ErrorCodes.TOOL_PERMISSION_DENIED,
|
|
25671
25900
|
recoverable: false,
|
|
25672
25901
|
retryable: false,
|
|
25673
|
-
suggestion: "
|
|
25902
|
+
suggestion: "Choose a different target path that avoids system directories."
|
|
25674
25903
|
});
|
|
25675
25904
|
}
|
|
25676
25905
|
try {
|
|
25677
|
-
const validated = await validatePath(
|
|
25906
|
+
const validated = await validatePath(resolvedPath, { allowSymlinks: false, allowedPaths: [allowedRoot] });
|
|
25678
25907
|
if (!validated.valid) {
|
|
25679
25908
|
throw new ToolExecutionError(validated.error || "Invalid path", {
|
|
25680
25909
|
toolName: "write",
|
|
@@ -25682,7 +25911,7 @@ var init_filesystem = __esm(async () => {
|
|
|
25682
25911
|
code: ErrorCodes.VALIDATION_OUT_OF_RANGE,
|
|
25683
25912
|
recoverable: false,
|
|
25684
25913
|
retryable: false,
|
|
25685
|
-
suggestion:
|
|
25914
|
+
suggestion: `Write only within the allowed workspace (${allowedRoot}).`
|
|
25686
25915
|
});
|
|
25687
25916
|
}
|
|
25688
25917
|
const safety = await isPathSafe(validated.resolved, "write", { cwd: baseCwd });
|
|
@@ -100744,6 +100973,7 @@ class BuiltinCommands {
|
|
|
100744
100973
|
loader.register(this.ordersCommand());
|
|
100745
100974
|
loader.register(this.tasksCommand());
|
|
100746
100975
|
loader.register(this.setupCommand());
|
|
100976
|
+
loader.register(this.scriptsCommand());
|
|
100747
100977
|
loader.register(this.exitCommand());
|
|
100748
100978
|
loader.register(this.diffCommand());
|
|
100749
100979
|
loader.register(this.undoCommand());
|
|
@@ -109573,6 +109803,73 @@ Not a git repository or git not available.
|
|
|
109573
109803
|
}
|
|
109574
109804
|
};
|
|
109575
109805
|
}
|
|
109806
|
+
scriptsCommand() {
|
|
109807
|
+
return {
|
|
109808
|
+
name: "scripts",
|
|
109809
|
+
description: "List generated files in the sandbox folder",
|
|
109810
|
+
builtin: true,
|
|
109811
|
+
selfHandled: true,
|
|
109812
|
+
content: "",
|
|
109813
|
+
handler: async (_args, context) => {
|
|
109814
|
+
const { getProjectDataDir: getDataDir } = await init_config().then(() => exports_config);
|
|
109815
|
+
const { readdirSync: readdirSync9, statSync: statSync6 } = await import("fs");
|
|
109816
|
+
const scriptsRoot = join26(getDataDir(context.cwd), "scripts", context.sessionId);
|
|
109817
|
+
let entries = [];
|
|
109818
|
+
const walk = (dir, prefix) => {
|
|
109819
|
+
let items;
|
|
109820
|
+
try {
|
|
109821
|
+
items = readdirSync9(dir);
|
|
109822
|
+
} catch {
|
|
109823
|
+
return;
|
|
109824
|
+
}
|
|
109825
|
+
for (const item of items) {
|
|
109826
|
+
const fullPath = join26(dir, item);
|
|
109827
|
+
try {
|
|
109828
|
+
const stat5 = statSync6(fullPath);
|
|
109829
|
+
if (stat5.isDirectory()) {
|
|
109830
|
+
walk(fullPath, prefix ? `${prefix}/${item}` : item);
|
|
109831
|
+
} else {
|
|
109832
|
+
entries.push({
|
|
109833
|
+
relativePath: prefix ? `${prefix}/${item}` : item,
|
|
109834
|
+
size: stat5.size
|
|
109835
|
+
});
|
|
109836
|
+
}
|
|
109837
|
+
} catch {}
|
|
109838
|
+
}
|
|
109839
|
+
};
|
|
109840
|
+
walk(scriptsRoot, "");
|
|
109841
|
+
if (entries.length === 0) {
|
|
109842
|
+
context.emit("text", `
|
|
109843
|
+
No generated files yet.
|
|
109844
|
+
`);
|
|
109845
|
+
context.emit("done");
|
|
109846
|
+
return { handled: true };
|
|
109847
|
+
}
|
|
109848
|
+
const formatSize2 = (bytes) => {
|
|
109849
|
+
if (bytes < 1024)
|
|
109850
|
+
return `${bytes} B`;
|
|
109851
|
+
if (bytes < 1048576)
|
|
109852
|
+
return `${(bytes / 1024).toFixed(1)} KB`;
|
|
109853
|
+
return `${(bytes / 1048576).toFixed(1)} MB`;
|
|
109854
|
+
};
|
|
109855
|
+
let message = `
|
|
109856
|
+
**Generated Files** (${entries.length})
|
|
109857
|
+
`;
|
|
109858
|
+
message += `\uD83D\uDCC2 ${scriptsRoot}
|
|
109859
|
+
|
|
109860
|
+
`;
|
|
109861
|
+
for (const entry of entries) {
|
|
109862
|
+
message += ` ${entry.relativePath} (${formatSize2(entry.size)})
|
|
109863
|
+
`;
|
|
109864
|
+
}
|
|
109865
|
+
message += `
|
|
109866
|
+
`;
|
|
109867
|
+
context.emit("text", message);
|
|
109868
|
+
context.emit("done");
|
|
109869
|
+
return { handled: true };
|
|
109870
|
+
}
|
|
109871
|
+
};
|
|
109872
|
+
}
|
|
109576
109873
|
undoCommand() {
|
|
109577
109874
|
return {
|
|
109578
109875
|
name: "undo",
|
|
@@ -109673,7 +109970,7 @@ Not a git repository or git not available.
|
|
|
109673
109970
|
context.setProjectContext(projectContext);
|
|
109674
109971
|
}
|
|
109675
109972
|
}
|
|
109676
|
-
var VERSION2 = "1.1.
|
|
109973
|
+
var VERSION2 = "1.1.80";
|
|
109677
109974
|
var init_builtin = __esm(async () => {
|
|
109678
109975
|
init_src2();
|
|
109679
109976
|
init_context3();
|
|
@@ -114884,7 +115181,35 @@ function findRecoverableSessions(staleThresholdMs = 120000, maxAgeMs = 24 * 60 *
|
|
|
114884
115181
|
timestamp: row.timestamp
|
|
114885
115182
|
};
|
|
114886
115183
|
let messageCount = 0;
|
|
115184
|
+
let lastMessage = null;
|
|
115185
|
+
let model = null;
|
|
115186
|
+
let label = null;
|
|
114887
115187
|
const cwd = context.cwd || process.cwd();
|
|
115188
|
+
try {
|
|
115189
|
+
const persisted = db.query("SELECT label, assistant_id FROM persisted_sessions WHERE id = ?").get(row.session_id);
|
|
115190
|
+
if (persisted?.label) {
|
|
115191
|
+
label = persisted.label;
|
|
115192
|
+
}
|
|
115193
|
+
if (persisted?.assistant_id) {
|
|
115194
|
+
try {
|
|
115195
|
+
const assistant = db.query("SELECT model FROM assistants_config WHERE id = ?").get(persisted.assistant_id);
|
|
115196
|
+
if (assistant?.model) {
|
|
115197
|
+
model = assistant.model;
|
|
115198
|
+
}
|
|
115199
|
+
} catch {}
|
|
115200
|
+
}
|
|
115201
|
+
} catch {}
|
|
115202
|
+
try {
|
|
115203
|
+
const countRow = db.query("SELECT COUNT(*) as cnt FROM session_messages WHERE session_id = ?").get(row.session_id);
|
|
115204
|
+
if (countRow) {
|
|
115205
|
+
messageCount = countRow.cnt;
|
|
115206
|
+
}
|
|
115207
|
+
const lastMsgRow = db.query("SELECT content FROM session_messages WHERE session_id = ? AND role = ? ORDER BY timestamp DESC LIMIT 1").get(row.session_id, "user");
|
|
115208
|
+
if (lastMsgRow?.content) {
|
|
115209
|
+
const text5 = lastMsgRow.content.trim();
|
|
115210
|
+
lastMessage = text5.length > 80 ? text5.slice(0, 77) + "..." : text5;
|
|
115211
|
+
}
|
|
115212
|
+
} catch {}
|
|
114888
115213
|
recoverableSessions.push({
|
|
114889
115214
|
sessionId: row.session_id,
|
|
114890
115215
|
heartbeat,
|
|
@@ -114892,7 +115217,10 @@ function findRecoverableSessions(staleThresholdMs = 120000, maxAgeMs = 24 * 60 *
|
|
|
114892
115217
|
sessionPath: "",
|
|
114893
115218
|
cwd,
|
|
114894
115219
|
lastActivity: new Date(heartbeat.lastActivity || heartbeat.timestamp),
|
|
114895
|
-
messageCount
|
|
115220
|
+
messageCount,
|
|
115221
|
+
lastMessage,
|
|
115222
|
+
model,
|
|
115223
|
+
label
|
|
114896
115224
|
});
|
|
114897
115225
|
} catch {
|
|
114898
115226
|
continue;
|
|
@@ -195423,7 +195751,8 @@ class EmbeddedClient {
|
|
|
195423
195751
|
success: !result.isError,
|
|
195424
195752
|
resultLength: result.content.length
|
|
195425
195753
|
});
|
|
195426
|
-
}
|
|
195754
|
+
},
|
|
195755
|
+
onSessionLabel: options2?.onSessionLabel
|
|
195427
195756
|
});
|
|
195428
195757
|
}
|
|
195429
195758
|
async initialize() {
|
|
@@ -200965,6 +201294,38 @@ var init_contacts = __esm(async () => {
|
|
|
200965
201294
|
]);
|
|
200966
201295
|
});
|
|
200967
201296
|
|
|
201297
|
+
// packages/core/src/sessions/auto-name.ts
|
|
201298
|
+
async function generateSessionName(userMessage, options2 = {}) {
|
|
201299
|
+
const apiKey = options2.apiKey || process.env.ANTHROPIC_API_KEY;
|
|
201300
|
+
if (!apiKey) {
|
|
201301
|
+
throw new Error("ANTHROPIC_API_KEY required for session auto-naming");
|
|
201302
|
+
}
|
|
201303
|
+
const client = new Anthropic({ apiKey });
|
|
201304
|
+
const model = options2.model || DEFAULT_BACKGROUND_MODEL;
|
|
201305
|
+
const truncated = userMessage.length > 500 ? userMessage.slice(0, 500) + "..." : userMessage;
|
|
201306
|
+
const response = await client.messages.create({
|
|
201307
|
+
model,
|
|
201308
|
+
max_tokens: 30,
|
|
201309
|
+
messages: [
|
|
201310
|
+
{
|
|
201311
|
+
role: "user",
|
|
201312
|
+
content: `Generate a 3-5 word title for this conversation. User asked: ${truncated}
|
|
201313
|
+
|
|
201314
|
+
Reply with ONLY the title, no quotes.`
|
|
201315
|
+
}
|
|
201316
|
+
]
|
|
201317
|
+
});
|
|
201318
|
+
const block = response.content[0];
|
|
201319
|
+
if (block.type === "text") {
|
|
201320
|
+
return block.text.replace(/^["']|["']$/g, "").trim();
|
|
201321
|
+
}
|
|
201322
|
+
return "Untitled Session";
|
|
201323
|
+
}
|
|
201324
|
+
var DEFAULT_BACKGROUND_MODEL = "claude-haiku-4-5-20251001";
|
|
201325
|
+
var init_auto_name = __esm(() => {
|
|
201326
|
+
init_sdk();
|
|
201327
|
+
});
|
|
201328
|
+
|
|
200968
201329
|
// packages/core/src/sessions/store.ts
|
|
200969
201330
|
function rowToSession2(row) {
|
|
200970
201331
|
return {
|
|
@@ -201062,7 +201423,15 @@ class SessionRegistry {
|
|
|
201062
201423
|
assistantId: options2.assistantId,
|
|
201063
201424
|
backend: options2.backend,
|
|
201064
201425
|
basePath: this.basePath,
|
|
201065
|
-
workspaceId: this.workspaceId ?? undefined
|
|
201426
|
+
workspaceId: this.workspaceId ?? undefined,
|
|
201427
|
+
onSessionLabel: (sessionId, label) => {
|
|
201428
|
+
const session = this.sessions.get(sessionId);
|
|
201429
|
+
if (session && !session.label) {
|
|
201430
|
+
session.label = label;
|
|
201431
|
+
session.updatedAt = Date.now();
|
|
201432
|
+
this.persistSession(session);
|
|
201433
|
+
}
|
|
201434
|
+
}
|
|
201066
201435
|
};
|
|
201067
201436
|
const client = this.clientFactory(options2.cwd, clientOptions);
|
|
201068
201437
|
await client.initialize();
|
|
@@ -201595,6 +201964,7 @@ var init_tools15 = __esm(() => {
|
|
|
201595
201964
|
|
|
201596
201965
|
// packages/core/src/sessions/index.ts
|
|
201597
201966
|
var init_sessions3 = __esm(async () => {
|
|
201967
|
+
init_auto_name();
|
|
201598
201968
|
init_tools15();
|
|
201599
201969
|
await __promiseAll([
|
|
201600
201970
|
init_verification(),
|
|
@@ -210611,6 +210981,7 @@ var init_loop = __esm(async () => {
|
|
|
210611
210981
|
init_limits();
|
|
210612
210982
|
init_llm_response();
|
|
210613
210983
|
init_manager3();
|
|
210984
|
+
init_auto_name();
|
|
210614
210985
|
init_self_awareness();
|
|
210615
210986
|
init_memory2();
|
|
210616
210987
|
init_agents();
|
|
@@ -210772,6 +211143,8 @@ var init_loop = __esm(async () => {
|
|
|
210772
211143
|
onToolEnd;
|
|
210773
211144
|
onTokenUsage;
|
|
210774
211145
|
onBudgetWarning;
|
|
211146
|
+
onSessionLabel;
|
|
211147
|
+
sessionAutoNamed = false;
|
|
210775
211148
|
constructor(options2 = {}) {
|
|
210776
211149
|
this.storageDir = options2.storageDir ?? getConfigDir();
|
|
210777
211150
|
this.workspaceId = options2.workspaceId ?? null;
|
|
@@ -210805,6 +211178,7 @@ var init_loop = __esm(async () => {
|
|
|
210805
211178
|
this.onToolEnd = options2.onToolEnd;
|
|
210806
211179
|
this.onTokenUsage = options2.onTokenUsage;
|
|
210807
211180
|
this.onBudgetWarning = options2.onBudgetWarning;
|
|
211181
|
+
this.onSessionLabel = options2.onSessionLabel;
|
|
210808
211182
|
this.budgetConfig = options2.budgetConfig || null;
|
|
210809
211183
|
this.guardrailsConfig = options2.guardrailsConfig || null;
|
|
210810
211184
|
this.onGuardrailsViolation = options2.onGuardrailsViolation;
|
|
@@ -210928,7 +211302,7 @@ var init_loop = __esm(async () => {
|
|
|
210928
211302
|
this.contextManager = new ContextManager(this.contextConfig, summarizer, tokenCounter);
|
|
210929
211303
|
}
|
|
210930
211304
|
this.toolRegistry.register(BashTool.tool, BashTool.executor);
|
|
210931
|
-
FilesystemTools.registerAll(this.toolRegistry, this.sessionId);
|
|
211305
|
+
FilesystemTools.registerAll(this.toolRegistry, this.sessionId, this.config.workspace);
|
|
210932
211306
|
WebTools.registerAll(this.toolRegistry);
|
|
210933
211307
|
ImageTools.registerAll(this.toolRegistry);
|
|
210934
211308
|
AudioTools.registerAll(this.toolRegistry);
|
|
@@ -211465,6 +211839,13 @@ You are running in **autonomous mode**. You manage your own wakeup schedule.
|
|
|
211465
211839
|
const messages = this.context.getMessages().slice(beforeCount);
|
|
211466
211840
|
const lastAssistant = [...messages].reverse().find((msg) => msg.role === "assistant");
|
|
211467
211841
|
const summary = lastAssistant?.content?.trim();
|
|
211842
|
+
if (!this.sessionAutoNamed && this.onSessionLabel && source === "user") {
|
|
211843
|
+
this.sessionAutoNamed = true;
|
|
211844
|
+
const bgModel = this.config?.backgroundModel;
|
|
211845
|
+
generateSessionName(userMessage, { model: bgModel }).then((label) => {
|
|
211846
|
+
this.onSessionLabel?.(this.sessionId, label);
|
|
211847
|
+
}).catch(() => {});
|
|
211848
|
+
}
|
|
211468
211849
|
return { ok: true, summary: summary ? summary.slice(0, 200) : undefined };
|
|
211469
211850
|
} catch (error4) {
|
|
211470
211851
|
const message = error4 instanceof Error ? error4.message : String(error4);
|
|
@@ -215367,6 +215748,7 @@ __export(exports_src3, {
|
|
|
215367
215748
|
getActiveWorkspaceId: () => getActiveWorkspaceId,
|
|
215368
215749
|
generateWebhookSecret: () => generateWebhookSecret,
|
|
215369
215750
|
generateWebhookId: () => generateWebhookId,
|
|
215751
|
+
generateSessionName: () => generateSessionName,
|
|
215370
215752
|
generateEventId: () => generateEventId,
|
|
215371
215753
|
generateDeliveryId: () => generateDeliveryId,
|
|
215372
215754
|
formatRelativeTime: () => formatRelativeTime,
|
|
@@ -215728,6 +216110,7 @@ var init_src3 = __esm(async () => {
|
|
|
215728
216110
|
init_anthropic();
|
|
215729
216111
|
init_openai2();
|
|
215730
216112
|
init_models2();
|
|
216113
|
+
init_auto_name();
|
|
215731
216114
|
await __promiseAll([
|
|
215732
216115
|
init_runtime(),
|
|
215733
216116
|
init_database(),
|
|
@@ -260823,6 +261206,7 @@ function SessionSelector({
|
|
|
260823
261206
|
const time3 = formatSessionTime(session.updatedAt);
|
|
260824
261207
|
const path7 = formatPath(session.cwd);
|
|
260825
261208
|
const processing = session.isProcessing ? " (processing)" : "";
|
|
261209
|
+
const displayName = session.label || path7;
|
|
260826
261210
|
return /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Box_default, {
|
|
260827
261211
|
children: /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Text, {
|
|
260828
261212
|
inverse: isSelected,
|
|
@@ -260835,7 +261219,7 @@ function SessionSelector({
|
|
|
260835
261219
|
". ",
|
|
260836
261220
|
time3,
|
|
260837
261221
|
" ",
|
|
260838
|
-
|
|
261222
|
+
displayName,
|
|
260839
261223
|
processing
|
|
260840
261224
|
]
|
|
260841
261225
|
}, undefined, true, undefined, this)
|
|
@@ -261749,32 +262133,51 @@ function RecoveryPanel({ sessions, onRecover, onStartFresh }) {
|
|
|
261749
262133
|
}, undefined, false, undefined, this),
|
|
261750
262134
|
visibleSessions.map(({ session, originalIndex }) => {
|
|
261751
262135
|
const isSelected = originalIndex === selectedSessionIndex;
|
|
261752
|
-
const stateLabel = getStateLabel(session.heartbeat.state);
|
|
261753
262136
|
const timeAgo = formatTimeAgo3(session.lastActivity);
|
|
261754
262137
|
const cwdDisplay = truncatePath(session.cwd, 30);
|
|
261755
|
-
const
|
|
262138
|
+
const displayName = session.label || cwdDisplay;
|
|
262139
|
+
const msgCount = session.messageCount > 0 ? `${session.messageCount} msgs` : "";
|
|
262140
|
+
const modelName = session.model || "";
|
|
262141
|
+
const meta = [msgCount, modelName].filter(Boolean).join(", ");
|
|
261756
262142
|
return /* @__PURE__ */ jsx_dev_runtime14.jsxDEV(Box_default, {
|
|
262143
|
+
flexDirection: "column",
|
|
261757
262144
|
paddingY: 0,
|
|
261758
|
-
children:
|
|
261759
|
-
|
|
261760
|
-
|
|
261761
|
-
|
|
261762
|
-
|
|
261763
|
-
|
|
261764
|
-
|
|
261765
|
-
|
|
261766
|
-
|
|
261767
|
-
|
|
261768
|
-
|
|
261769
|
-
|
|
261770
|
-
|
|
261771
|
-
|
|
261772
|
-
|
|
261773
|
-
|
|
261774
|
-
|
|
261775
|
-
|
|
261776
|
-
|
|
261777
|
-
|
|
262145
|
+
children: [
|
|
262146
|
+
/* @__PURE__ */ jsx_dev_runtime14.jsxDEV(Text, {
|
|
262147
|
+
inverse: isSelected,
|
|
262148
|
+
children: [
|
|
262149
|
+
isSelected ? "\u25B6" : " ",
|
|
262150
|
+
" ",
|
|
262151
|
+
displayName,
|
|
262152
|
+
" ",
|
|
262153
|
+
/* @__PURE__ */ jsx_dev_runtime14.jsxDEV(Text, {
|
|
262154
|
+
dimColor: true,
|
|
262155
|
+
children: [
|
|
262156
|
+
"(",
|
|
262157
|
+
timeAgo,
|
|
262158
|
+
")"
|
|
262159
|
+
]
|
|
262160
|
+
}, undefined, true, undefined, this),
|
|
262161
|
+
meta ? /* @__PURE__ */ jsx_dev_runtime14.jsxDEV(Text, {
|
|
262162
|
+
dimColor: true,
|
|
262163
|
+
children: [
|
|
262164
|
+
" \u2014 ",
|
|
262165
|
+
meta
|
|
262166
|
+
]
|
|
262167
|
+
}, undefined, true, undefined, this) : null
|
|
262168
|
+
]
|
|
262169
|
+
}, undefined, true, undefined, this),
|
|
262170
|
+
session.lastMessage && /* @__PURE__ */ jsx_dev_runtime14.jsxDEV(Text, {
|
|
262171
|
+
dimColor: true,
|
|
262172
|
+
children: [
|
|
262173
|
+
" ",
|
|
262174
|
+
"\u2018",
|
|
262175
|
+
session.lastMessage,
|
|
262176
|
+
"\u2019"
|
|
262177
|
+
]
|
|
262178
|
+
}, undefined, true, undefined, this)
|
|
262179
|
+
]
|
|
262180
|
+
}, session.sessionId, true, undefined, this);
|
|
261778
262181
|
}),
|
|
261779
262182
|
showDownArrow && /* @__PURE__ */ jsx_dev_runtime14.jsxDEV(Box_default, {
|
|
261780
262183
|
children: /* @__PURE__ */ jsx_dev_runtime14.jsxDEV(Text, {
|
|
@@ -261788,33 +262191,49 @@ function RecoveryPanel({ sessions, onRecover, onStartFresh }) {
|
|
|
261788
262191
|
}, undefined, false, undefined, this)
|
|
261789
262192
|
]
|
|
261790
262193
|
}, undefined, true, undefined, this),
|
|
261791
|
-
selectedSessionIndex >= 0 && selectedSessionIndex < sessions.length &&
|
|
261792
|
-
|
|
261793
|
-
|
|
261794
|
-
|
|
261795
|
-
|
|
261796
|
-
|
|
261797
|
-
|
|
261798
|
-
|
|
261799
|
-
|
|
261800
|
-
|
|
261801
|
-
|
|
261802
|
-
|
|
261803
|
-
|
|
261804
|
-
|
|
261805
|
-
|
|
261806
|
-
|
|
261807
|
-
|
|
261808
|
-
|
|
261809
|
-
|
|
261810
|
-
|
|
261811
|
-
|
|
261812
|
-
|
|
261813
|
-
|
|
261814
|
-
|
|
261815
|
-
|
|
261816
|
-
|
|
261817
|
-
|
|
262194
|
+
selectedSessionIndex >= 0 && selectedSessionIndex < sessions.length && (() => {
|
|
262195
|
+
const s5 = sessions[selectedSessionIndex];
|
|
262196
|
+
const details = [
|
|
262197
|
+
formatTimeAgo3(s5.lastActivity),
|
|
262198
|
+
getStateLabel(s5.heartbeat.state),
|
|
262199
|
+
s5.messageCount > 0 ? `${s5.messageCount} messages` : null,
|
|
262200
|
+
s5.model || null
|
|
262201
|
+
].filter(Boolean).join(" \xB7 ");
|
|
262202
|
+
return /* @__PURE__ */ jsx_dev_runtime14.jsxDEV(Box_default, {
|
|
262203
|
+
flexDirection: "column",
|
|
262204
|
+
marginBottom: 1,
|
|
262205
|
+
children: [
|
|
262206
|
+
/* @__PURE__ */ jsx_dev_runtime14.jsxDEV(Text, {
|
|
262207
|
+
dimColor: true,
|
|
262208
|
+
children: "Selected:"
|
|
262209
|
+
}, undefined, false, undefined, this),
|
|
262210
|
+
/* @__PURE__ */ jsx_dev_runtime14.jsxDEV(Text, {
|
|
262211
|
+
children: [
|
|
262212
|
+
" ",
|
|
262213
|
+
/* @__PURE__ */ jsx_dev_runtime14.jsxDEV(Text, {
|
|
262214
|
+
color: "cyan",
|
|
262215
|
+
children: s5.cwd
|
|
262216
|
+
}, undefined, false, undefined, this)
|
|
262217
|
+
]
|
|
262218
|
+
}, undefined, true, undefined, this),
|
|
262219
|
+
/* @__PURE__ */ jsx_dev_runtime14.jsxDEV(Text, {
|
|
262220
|
+
children: [
|
|
262221
|
+
" ",
|
|
262222
|
+
details
|
|
262223
|
+
]
|
|
262224
|
+
}, undefined, true, undefined, this),
|
|
262225
|
+
s5.lastMessage && /* @__PURE__ */ jsx_dev_runtime14.jsxDEV(Text, {
|
|
262226
|
+
dimColor: true,
|
|
262227
|
+
children: [
|
|
262228
|
+
" Last: ",
|
|
262229
|
+
"\u2018",
|
|
262230
|
+
s5.lastMessage,
|
|
262231
|
+
"\u2019"
|
|
262232
|
+
]
|
|
262233
|
+
}, undefined, true, undefined, this)
|
|
262234
|
+
]
|
|
262235
|
+
}, undefined, true, undefined, this);
|
|
262236
|
+
})(),
|
|
261818
262237
|
/* @__PURE__ */ jsx_dev_runtime14.jsxDEV(Box_default, {
|
|
261819
262238
|
children: /* @__PURE__ */ jsx_dev_runtime14.jsxDEV(Text, {
|
|
261820
262239
|
dimColor: true,
|
|
@@ -292705,7 +293124,8 @@ ${msg.body || msg.preview}`);
|
|
|
292705
293124
|
const isThinking = isProcessing && !currentResponse && !currentToolCall && toolCallEntries.length === 0;
|
|
292706
293125
|
return /* @__PURE__ */ jsx_dev_runtime51.jsxDEV(Box_default, {
|
|
292707
293126
|
flexDirection: "column",
|
|
292708
|
-
|
|
293127
|
+
height: rows,
|
|
293128
|
+
paddingX: 1,
|
|
292709
293129
|
children: [
|
|
292710
293130
|
showWelcome && /* @__PURE__ */ jsx_dev_runtime51.jsxDEV(WelcomeBanner, {
|
|
292711
293131
|
version: version4 ?? "unknown",
|
|
@@ -292724,45 +293144,52 @@ ${msg.body || msg.preview}`);
|
|
|
292724
293144
|
]
|
|
292725
293145
|
}, undefined, true, undefined, this)
|
|
292726
293146
|
}, undefined, false, undefined, this),
|
|
292727
|
-
/* @__PURE__ */ jsx_dev_runtime51.jsxDEV(
|
|
292728
|
-
|
|
292729
|
-
|
|
292730
|
-
|
|
292731
|
-
currentResponse: undefined,
|
|
292732
|
-
streamingMessages: [],
|
|
292733
|
-
currentToolCall: undefined,
|
|
292734
|
-
lastToolResult: undefined,
|
|
292735
|
-
activityLog: [],
|
|
292736
|
-
queuedMessageIds,
|
|
292737
|
-
verboseTools
|
|
292738
|
-
}, message.id, false, undefined, this)
|
|
292739
|
-
}, staticResetKey, false, undefined, this),
|
|
292740
|
-
showDynamicPanel && /* @__PURE__ */ jsx_dev_runtime51.jsxDEV(jsx_dev_runtime51.Fragment, {
|
|
293147
|
+
/* @__PURE__ */ jsx_dev_runtime51.jsxDEV(Box_default, {
|
|
293148
|
+
flexDirection: "column",
|
|
293149
|
+
flexGrow: 1,
|
|
293150
|
+
overflowY: "hidden",
|
|
292741
293151
|
children: [
|
|
292742
|
-
|
|
292743
|
-
|
|
292744
|
-
children: /* @__PURE__ */ jsx_dev_runtime51.jsxDEV(
|
|
292745
|
-
|
|
292746
|
-
|
|
292747
|
-
|
|
292748
|
-
|
|
292749
|
-
|
|
292750
|
-
|
|
292751
|
-
|
|
292752
|
-
|
|
292753
|
-
|
|
292754
|
-
|
|
292755
|
-
|
|
292756
|
-
|
|
292757
|
-
|
|
292758
|
-
|
|
292759
|
-
|
|
292760
|
-
|
|
292761
|
-
|
|
292762
|
-
|
|
292763
|
-
|
|
292764
|
-
|
|
292765
|
-
|
|
293152
|
+
/* @__PURE__ */ jsx_dev_runtime51.jsxDEV(Static, {
|
|
293153
|
+
items: staticMessages,
|
|
293154
|
+
children: (message) => /* @__PURE__ */ jsx_dev_runtime51.jsxDEV(Messages5, {
|
|
293155
|
+
messages: [message],
|
|
293156
|
+
currentResponse: undefined,
|
|
293157
|
+
streamingMessages: [],
|
|
293158
|
+
currentToolCall: undefined,
|
|
293159
|
+
lastToolResult: undefined,
|
|
293160
|
+
activityLog: [],
|
|
293161
|
+
queuedMessageIds,
|
|
293162
|
+
verboseTools
|
|
293163
|
+
}, message.id, false, undefined, this)
|
|
293164
|
+
}, staticResetKey, false, undefined, this),
|
|
293165
|
+
showDynamicPanel && /* @__PURE__ */ jsx_dev_runtime51.jsxDEV(jsx_dev_runtime51.Fragment, {
|
|
293166
|
+
children: [
|
|
293167
|
+
isProcessing && streamingTrimmed && /* @__PURE__ */ jsx_dev_runtime51.jsxDEV(Box_default, {
|
|
293168
|
+
marginBottom: 1,
|
|
293169
|
+
children: /* @__PURE__ */ jsx_dev_runtime51.jsxDEV(Text, {
|
|
293170
|
+
dimColor: true,
|
|
293171
|
+
children: "\u22EF showing latest output"
|
|
293172
|
+
}, undefined, false, undefined, this)
|
|
293173
|
+
}, undefined, false, undefined, this),
|
|
293174
|
+
isProcessing && activityTrim.trimmed && /* @__PURE__ */ jsx_dev_runtime51.jsxDEV(Box_default, {
|
|
293175
|
+
marginBottom: 1,
|
|
293176
|
+
children: /* @__PURE__ */ jsx_dev_runtime51.jsxDEV(Text, {
|
|
293177
|
+
dimColor: true,
|
|
293178
|
+
children: "\u22EF showing latest activity"
|
|
293179
|
+
}, undefined, false, undefined, this)
|
|
293180
|
+
}, undefined, false, undefined, this),
|
|
293181
|
+
/* @__PURE__ */ jsx_dev_runtime51.jsxDEV(Messages5, {
|
|
293182
|
+
messages: [],
|
|
293183
|
+
currentResponse: undefined,
|
|
293184
|
+
streamingMessages: combinedStreamingMessages,
|
|
293185
|
+
currentToolCall: undefined,
|
|
293186
|
+
lastToolResult: undefined,
|
|
293187
|
+
activityLog: isProcessing ? activityTrim.entries : [],
|
|
293188
|
+
queuedMessageIds,
|
|
293189
|
+
verboseTools
|
|
293190
|
+
}, "streaming", false, undefined, this)
|
|
293191
|
+
]
|
|
293192
|
+
}, undefined, true, undefined, this)
|
|
292766
293193
|
]
|
|
292767
293194
|
}, undefined, true, undefined, this),
|
|
292768
293195
|
askUserState && activeAskQuestion && !interviewState && /* @__PURE__ */ jsx_dev_runtime51.jsxDEV(AskUserPanel, {
|
|
@@ -293335,7 +293762,7 @@ process.on("unhandledRejection", (reason) => {
|
|
|
293335
293762
|
cleanup();
|
|
293336
293763
|
process.exit(1);
|
|
293337
293764
|
});
|
|
293338
|
-
var VERSION4 = "1.1.
|
|
293765
|
+
var VERSION4 = "1.1.80";
|
|
293339
293766
|
var SYNC_START = "\x1B[?2026h";
|
|
293340
293767
|
var SYNC_END = "\x1B[?2026l";
|
|
293341
293768
|
function enableSynchronizedOutput() {
|
|
@@ -293480,4 +293907,4 @@ export {
|
|
|
293480
293907
|
main
|
|
293481
293908
|
};
|
|
293482
293909
|
|
|
293483
|
-
//# debugId=
|
|
293910
|
+
//# debugId=5648E49F1CE1903A64756E2164756E21
|