@hasna/oldpal 0.4.0 → 0.5.0
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 +18 -3
- package/dist/index.js +830 -244
- package/dist/index.js.map +17 -15
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -20451,10 +20451,10 @@ __export(exports_anthropic, {
|
|
|
20451
20451
|
AnthropicClient: () => AnthropicClient
|
|
20452
20452
|
});
|
|
20453
20453
|
import { readFileSync as readFileSync2, existsSync as existsSync5 } from "fs";
|
|
20454
|
-
import { homedir as
|
|
20454
|
+
import { homedir as homedir7 } from "os";
|
|
20455
20455
|
import { join as join7 } from "path";
|
|
20456
20456
|
function loadApiKeyFromSecrets() {
|
|
20457
|
-
const secretsPath = join7(
|
|
20457
|
+
const secretsPath = join7(homedir7(), ".secrets");
|
|
20458
20458
|
if (existsSync5(secretsPath)) {
|
|
20459
20459
|
try {
|
|
20460
20460
|
const content = readFileSync2(secretsPath, "utf-8");
|
|
@@ -28328,6 +28328,25 @@ var getInstance = (stdout, createInstance) => {
|
|
|
28328
28328
|
};
|
|
28329
28329
|
// node_modules/.pnpm/ink@5.2.1_@types+react@18.3.27_react-devtools-core@4.28.5_react@18.3.1/node_modules/ink/build/components/Static.js
|
|
28330
28330
|
var import_react11 = __toESM(require_react(), 1);
|
|
28331
|
+
function Static(props) {
|
|
28332
|
+
const { items, children: render2, style: customStyle } = props;
|
|
28333
|
+
const [index, setIndex] = import_react11.useState(0);
|
|
28334
|
+
const itemsToRender = import_react11.useMemo(() => {
|
|
28335
|
+
return items.slice(index);
|
|
28336
|
+
}, [items, index]);
|
|
28337
|
+
import_react11.useLayoutEffect(() => {
|
|
28338
|
+
setIndex(items.length);
|
|
28339
|
+
}, [items.length]);
|
|
28340
|
+
const children = itemsToRender.map((item, itemIndex) => {
|
|
28341
|
+
return render2(item, index + itemIndex);
|
|
28342
|
+
});
|
|
28343
|
+
const style = import_react11.useMemo(() => ({
|
|
28344
|
+
position: "absolute",
|
|
28345
|
+
flexDirection: "column",
|
|
28346
|
+
...customStyle
|
|
28347
|
+
}), [customStyle]);
|
|
28348
|
+
return import_react11.default.createElement("ink-box", { internal_static: true, style }, children);
|
|
28349
|
+
}
|
|
28331
28350
|
// node_modules/.pnpm/ink@5.2.1_@types+react@18.3.27_react-devtools-core@4.28.5_react@18.3.1/node_modules/ink/build/components/Transform.js
|
|
28332
28351
|
var import_react12 = __toESM(require_react(), 1);
|
|
28333
28352
|
// node_modules/.pnpm/ink@5.2.1_@types+react@18.3.27_react-devtools-core@4.28.5_react@18.3.1/node_modules/ink/build/components/Newline.js
|
|
@@ -28594,7 +28613,7 @@ var import_react20 = __toESM(require_react(), 1);
|
|
|
28594
28613
|
// node_modules/.pnpm/ink@5.2.1_@types+react@18.3.27_react-devtools-core@4.28.5_react@18.3.1/node_modules/ink/build/hooks/use-focus-manager.js
|
|
28595
28614
|
var import_react21 = __toESM(require_react(), 1);
|
|
28596
28615
|
// packages/terminal/src/components/App.tsx
|
|
28597
|
-
var
|
|
28616
|
+
var import_react27 = __toESM(require_react(), 1);
|
|
28598
28617
|
// packages/shared/src/utils.ts
|
|
28599
28618
|
import { randomUUID } from "crypto";
|
|
28600
28619
|
function generateId() {
|
|
@@ -28973,13 +28992,13 @@ class ConnectorBridge {
|
|
|
28973
28992
|
class BashTool {
|
|
28974
28993
|
static tool = {
|
|
28975
28994
|
name: "bash",
|
|
28976
|
-
description: "Execute a shell command.
|
|
28995
|
+
description: "Execute a shell command. RESTRICTED to read-only operations: ls, cat, grep, find, git status/log/diff, pwd, which, echo. Cannot modify files, install packages, or run destructive commands.",
|
|
28977
28996
|
parameters: {
|
|
28978
28997
|
type: "object",
|
|
28979
28998
|
properties: {
|
|
28980
28999
|
command: {
|
|
28981
29000
|
type: "string",
|
|
28982
|
-
description: "The shell command to execute"
|
|
29001
|
+
description: "The shell command to execute (read-only commands only)"
|
|
28983
29002
|
},
|
|
28984
29003
|
cwd: {
|
|
28985
29004
|
type: "string",
|
|
@@ -28987,29 +29006,111 @@ class BashTool {
|
|
|
28987
29006
|
},
|
|
28988
29007
|
timeout: {
|
|
28989
29008
|
type: "number",
|
|
28990
|
-
description: "Timeout in milliseconds (default:
|
|
29009
|
+
description: "Timeout in milliseconds (default: 30000)"
|
|
28991
29010
|
}
|
|
28992
29011
|
},
|
|
28993
29012
|
required: ["command"]
|
|
28994
29013
|
}
|
|
28995
29014
|
};
|
|
29015
|
+
static ALLOWED_COMMANDS = [
|
|
29016
|
+
"cat",
|
|
29017
|
+
"head",
|
|
29018
|
+
"tail",
|
|
29019
|
+
"less",
|
|
29020
|
+
"more",
|
|
29021
|
+
"ls",
|
|
29022
|
+
"tree",
|
|
29023
|
+
"find",
|
|
29024
|
+
"locate",
|
|
29025
|
+
"grep",
|
|
29026
|
+
"rg",
|
|
29027
|
+
"ag",
|
|
29028
|
+
"ack",
|
|
29029
|
+
"wc",
|
|
29030
|
+
"file",
|
|
29031
|
+
"stat",
|
|
29032
|
+
"du",
|
|
29033
|
+
"df",
|
|
29034
|
+
"pwd",
|
|
29035
|
+
"whoami",
|
|
29036
|
+
"date",
|
|
29037
|
+
"which",
|
|
29038
|
+
"where",
|
|
29039
|
+
"type",
|
|
29040
|
+
"env",
|
|
29041
|
+
"printenv",
|
|
29042
|
+
"echo",
|
|
29043
|
+
"git status",
|
|
29044
|
+
"git log",
|
|
29045
|
+
"git diff",
|
|
29046
|
+
"git branch",
|
|
29047
|
+
"git show",
|
|
29048
|
+
"git remote",
|
|
29049
|
+
"git tag",
|
|
29050
|
+
"connect-",
|
|
29051
|
+
"node --version",
|
|
29052
|
+
"bun --version",
|
|
29053
|
+
"npm --version",
|
|
29054
|
+
"pnpm --version"
|
|
29055
|
+
];
|
|
29056
|
+
static BLOCKED_PATTERNS = [
|
|
29057
|
+
/\brm\b/,
|
|
29058
|
+
/\brmdir\b/,
|
|
29059
|
+
/\bunlink\b/,
|
|
29060
|
+
/\bmv\b/,
|
|
29061
|
+
/\bcp\b/,
|
|
29062
|
+
/\bchmod\b/,
|
|
29063
|
+
/\bchown\b/,
|
|
29064
|
+
/\bchgrp\b/,
|
|
29065
|
+
/\bsudo\b/,
|
|
29066
|
+
/\bsu\b/,
|
|
29067
|
+
/\bdoas\b/,
|
|
29068
|
+
/\bnpm\s+(install|i|add|ci)\b/,
|
|
29069
|
+
/\bpnpm\s+(install|i|add)\b/,
|
|
29070
|
+
/\byarn\s+(install|add)\b/,
|
|
29071
|
+
/\bbun\s+(install|add|i)\b/,
|
|
29072
|
+
/\bpip\s+install\b/,
|
|
29073
|
+
/\bpip3\s+install\b/,
|
|
29074
|
+
/\bbrew\s+install\b/,
|
|
29075
|
+
/\bapt\s+install\b/,
|
|
29076
|
+
/\bapt-get\s+install\b/,
|
|
29077
|
+
/\bgit\s+(push|commit|checkout|reset|rebase|merge|pull|stash|cherry-pick|revert)\b/,
|
|
29078
|
+
/\bgit\s+add\b/,
|
|
29079
|
+
/\|\s*(bash|sh|zsh|fish)\b/,
|
|
29080
|
+
/curl.*\|\s*(bash|sh)/,
|
|
29081
|
+
/wget.*\|\s*(bash|sh)/,
|
|
29082
|
+
/>\s*[^|]/,
|
|
29083
|
+
/>>/,
|
|
29084
|
+
/\bkill\b/,
|
|
29085
|
+
/\bpkill\b/,
|
|
29086
|
+
/\bkillall\b/,
|
|
29087
|
+
/\bmkfs\b/,
|
|
29088
|
+
/\bdd\b/,
|
|
29089
|
+
/\bfdisk\b/,
|
|
29090
|
+
/\bparted\b/,
|
|
29091
|
+
/\bnc\s+-l/,
|
|
29092
|
+
/\bnetcat\s+-l/,
|
|
29093
|
+
/\bvim?\b/,
|
|
29094
|
+
/\bnano\b/,
|
|
29095
|
+
/\bemacs\b/,
|
|
29096
|
+
/\bmake\b/,
|
|
29097
|
+
/\bcmake\b/,
|
|
29098
|
+
/\bdocker\s+(run|exec|build|push)\b/
|
|
29099
|
+
];
|
|
28996
29100
|
static executor = async (input) => {
|
|
28997
29101
|
const command = input.command;
|
|
28998
29102
|
const cwd2 = input.cwd || process.cwd();
|
|
28999
|
-
const timeout = input.timeout ||
|
|
29000
|
-
const
|
|
29001
|
-
/rm\s+-rf\s+[\/~]/i,
|
|
29002
|
-
/rm\s+-rf\s+\*/i,
|
|
29003
|
-
/mkfs/i,
|
|
29004
|
-
/dd\s+if=/i,
|
|
29005
|
-
/>\s*\/dev\/sd/i,
|
|
29006
|
-
/chmod\s+-R\s+777\s+\//i
|
|
29007
|
-
];
|
|
29008
|
-
for (const pattern of dangerousPatterns) {
|
|
29103
|
+
const timeout = input.timeout || 30000;
|
|
29104
|
+
for (const pattern of this.BLOCKED_PATTERNS) {
|
|
29009
29105
|
if (pattern.test(command)) {
|
|
29010
|
-
return `Error: This command
|
|
29106
|
+
return `Error: This command is not allowed. Only read-only commands are permitted (ls, cat, grep, find, git status/log/diff, etc.)`;
|
|
29011
29107
|
}
|
|
29012
29108
|
}
|
|
29109
|
+
const commandTrimmed = command.trim().toLowerCase();
|
|
29110
|
+
const isAllowed = this.ALLOWED_COMMANDS.some((allowed) => commandTrimmed.startsWith(allowed.toLowerCase()));
|
|
29111
|
+
if (!isAllowed) {
|
|
29112
|
+
return `Error: Command not in allowed list. Permitted commands: cat, head, tail, ls, find, grep, wc, file, stat, pwd, which, echo, git status/log/diff/branch/show, connect-*`;
|
|
29113
|
+
}
|
|
29013
29114
|
try {
|
|
29014
29115
|
const proc = Bun.spawn(["bash", "-c", command], {
|
|
29015
29116
|
cwd: cwd2,
|
|
@@ -29038,15 +29139,31 @@ ${stderr || stdout}`.trim();
|
|
|
29038
29139
|
|
|
29039
29140
|
// packages/core/src/tools/filesystem.ts
|
|
29040
29141
|
import { join as join2, resolve, dirname } from "path";
|
|
29142
|
+
import { homedir as homedir2 } from "os";
|
|
29041
29143
|
var {Glob } = globalThis.Bun;
|
|
29144
|
+
var currentSessionId = "default";
|
|
29145
|
+
function getTempFolder() {
|
|
29146
|
+
return join2(homedir2(), ".oldpal", "temp", currentSessionId);
|
|
29147
|
+
}
|
|
29148
|
+
function isInTempFolder(path) {
|
|
29149
|
+
const tempFolder = getTempFolder();
|
|
29150
|
+
const resolved = resolve(path);
|
|
29151
|
+
return resolved.startsWith(tempFolder);
|
|
29152
|
+
}
|
|
29042
29153
|
|
|
29043
29154
|
class FilesystemTools {
|
|
29044
|
-
static registerAll(registry) {
|
|
29155
|
+
static registerAll(registry, sessionId) {
|
|
29156
|
+
if (sessionId) {
|
|
29157
|
+
currentSessionId = sessionId;
|
|
29158
|
+
}
|
|
29045
29159
|
registry.register(this.readTool, this.readExecutor);
|
|
29046
29160
|
registry.register(this.writeTool, this.writeExecutor);
|
|
29047
29161
|
registry.register(this.globTool, this.globExecutor);
|
|
29048
29162
|
registry.register(this.grepTool, this.grepExecutor);
|
|
29049
29163
|
}
|
|
29164
|
+
static setSessionId(sessionId) {
|
|
29165
|
+
currentSessionId = sessionId;
|
|
29166
|
+
}
|
|
29050
29167
|
static readTool = {
|
|
29051
29168
|
name: "read",
|
|
29052
29169
|
description: "Read the contents of a file",
|
|
@@ -29093,30 +29210,38 @@ class FilesystemTools {
|
|
|
29093
29210
|
};
|
|
29094
29211
|
static writeTool = {
|
|
29095
29212
|
name: "write",
|
|
29096
|
-
description: "Write content to a file
|
|
29213
|
+
description: "Write content to a file. RESTRICTED: Can only write to ~/.oldpal/temp/{session}/ folder. Provide just the filename and it will be saved to the temp folder.",
|
|
29097
29214
|
parameters: {
|
|
29098
29215
|
type: "object",
|
|
29099
29216
|
properties: {
|
|
29100
|
-
|
|
29217
|
+
filename: {
|
|
29101
29218
|
type: "string",
|
|
29102
|
-
description: "The
|
|
29219
|
+
description: "The filename to write to (will be saved in temp folder)"
|
|
29103
29220
|
},
|
|
29104
29221
|
content: {
|
|
29105
29222
|
type: "string",
|
|
29106
29223
|
description: "The content to write"
|
|
29107
29224
|
}
|
|
29108
29225
|
},
|
|
29109
|
-
required: ["
|
|
29226
|
+
required: ["filename", "content"]
|
|
29110
29227
|
}
|
|
29111
29228
|
};
|
|
29112
29229
|
static writeExecutor = async (input) => {
|
|
29113
|
-
const
|
|
29230
|
+
const filename = input.filename || input.path;
|
|
29114
29231
|
const content = input.content;
|
|
29232
|
+
const tempFolder = getTempFolder();
|
|
29233
|
+
const sanitizedFilename = filename.replace(/\.\./g, "").replace(/^\/+/, "");
|
|
29234
|
+
const path = join2(tempFolder, sanitizedFilename);
|
|
29235
|
+
if (!isInTempFolder(path)) {
|
|
29236
|
+
return `Error: Cannot write outside temp folder. Files are saved to ${tempFolder}`;
|
|
29237
|
+
}
|
|
29115
29238
|
try {
|
|
29116
29239
|
const dir = dirname(path);
|
|
29117
29240
|
await Bun.$`mkdir -p ${dir}`.quiet();
|
|
29118
29241
|
await Bun.write(path, content);
|
|
29119
|
-
return `Successfully wrote ${content.length} characters to ${path}
|
|
29242
|
+
return `Successfully wrote ${content.length} characters to ${path}
|
|
29243
|
+
|
|
29244
|
+
You can review and copy this file to your project if needed.`;
|
|
29120
29245
|
} catch (error) {
|
|
29121
29246
|
return `Error: ${error instanceof Error ? error.message : String(error)}`;
|
|
29122
29247
|
}
|
|
@@ -29506,11 +29631,11 @@ class WebTools {
|
|
|
29506
29631
|
import { existsSync as existsSync2, writeFileSync, unlinkSync } from "fs";
|
|
29507
29632
|
import { tmpdir } from "os";
|
|
29508
29633
|
import { join as join3 } from "path";
|
|
29509
|
-
import { homedir as
|
|
29634
|
+
import { homedir as homedir3 } from "os";
|
|
29510
29635
|
async function getViuPath() {
|
|
29511
29636
|
const locations = [
|
|
29512
29637
|
"viu",
|
|
29513
|
-
join3(
|
|
29638
|
+
join3(homedir3(), ".cargo", "bin", "viu"),
|
|
29514
29639
|
"/usr/local/bin/viu",
|
|
29515
29640
|
"/opt/homebrew/bin/viu"
|
|
29516
29641
|
];
|
|
@@ -29621,12 +29746,12 @@ class ImageTools {
|
|
|
29621
29746
|
|
|
29622
29747
|
// packages/core/src/skills/loader.ts
|
|
29623
29748
|
import { join as join4 } from "path";
|
|
29624
|
-
import { homedir as
|
|
29749
|
+
import { homedir as homedir4 } from "os";
|
|
29625
29750
|
var {Glob: Glob2 } = globalThis.Bun;
|
|
29626
29751
|
class SkillLoader {
|
|
29627
29752
|
skills = new Map;
|
|
29628
29753
|
async loadAll(projectDir = process.cwd()) {
|
|
29629
|
-
const userSkillsDir = join4(
|
|
29754
|
+
const userSkillsDir = join4(homedir4(), ".oldpal", "skills");
|
|
29630
29755
|
await this.loadFromDirectory(userSkillsDir);
|
|
29631
29756
|
const projectSkillsDir = join4(projectDir, ".oldpal", "skills");
|
|
29632
29757
|
await this.loadFromDirectory(projectSkillsDir);
|
|
@@ -29743,7 +29868,8 @@ ARGUMENTS: ${args.join(" ")}`;
|
|
|
29743
29868
|
const fullMatch = match[0];
|
|
29744
29869
|
const command = match[1];
|
|
29745
29870
|
try {
|
|
29746
|
-
const
|
|
29871
|
+
const fullCommand = `cd ${skillDir} && ${command}`;
|
|
29872
|
+
const output = await Bun.$`sh -c ${fullCommand}`.quiet().text();
|
|
29747
29873
|
result = result.replace(fullMatch, output.trim());
|
|
29748
29874
|
} catch (error) {
|
|
29749
29875
|
const errorMsg = error instanceof Error ? error.message : String(error);
|
|
@@ -29921,7 +30047,7 @@ class HookExecutor {
|
|
|
29921
30047
|
// packages/core/src/commands/loader.ts
|
|
29922
30048
|
import { existsSync as existsSync3, readdirSync, statSync } from "fs";
|
|
29923
30049
|
import { join as join5, basename, extname } from "path";
|
|
29924
|
-
import { homedir as
|
|
30050
|
+
import { homedir as homedir5 } from "os";
|
|
29925
30051
|
|
|
29926
30052
|
class CommandLoader {
|
|
29927
30053
|
commands = new Map;
|
|
@@ -29931,7 +30057,7 @@ class CommandLoader {
|
|
|
29931
30057
|
}
|
|
29932
30058
|
async loadAll() {
|
|
29933
30059
|
this.commands.clear();
|
|
29934
|
-
const globalDir = join5(
|
|
30060
|
+
const globalDir = join5(homedir5(), ".oldpal", "commands");
|
|
29935
30061
|
await this.loadFromDirectory(globalDir, "global");
|
|
29936
30062
|
const projectDir = join5(this.cwd, ".oldpal", "commands");
|
|
29937
30063
|
await this.loadFromDirectory(projectDir, "project");
|
|
@@ -30120,7 +30246,7 @@ ${stderr}`;
|
|
|
30120
30246
|
}
|
|
30121
30247
|
// packages/core/src/commands/builtin.ts
|
|
30122
30248
|
import { join as join6 } from "path";
|
|
30123
|
-
import { homedir as
|
|
30249
|
+
import { homedir as homedir6 } from "os";
|
|
30124
30250
|
import { existsSync as existsSync4, mkdirSync, writeFileSync as writeFileSync2 } from "fs";
|
|
30125
30251
|
|
|
30126
30252
|
class BuiltinCommands {
|
|
@@ -30134,6 +30260,7 @@ class BuiltinCommands {
|
|
|
30134
30260
|
loader.register(this.helpCommand(loader));
|
|
30135
30261
|
loader.register(this.clearCommand());
|
|
30136
30262
|
loader.register(this.newCommand());
|
|
30263
|
+
loader.register(this.sessionCommand());
|
|
30137
30264
|
loader.register(this.statusCommand());
|
|
30138
30265
|
loader.register(this.tokensCommand());
|
|
30139
30266
|
loader.register(this.compactCommand());
|
|
@@ -30256,6 +30383,29 @@ class BuiltinCommands {
|
|
|
30256
30383
|
}
|
|
30257
30384
|
};
|
|
30258
30385
|
}
|
|
30386
|
+
sessionCommand() {
|
|
30387
|
+
return {
|
|
30388
|
+
name: "session",
|
|
30389
|
+
description: "List sessions or switch to a session by number",
|
|
30390
|
+
builtin: true,
|
|
30391
|
+
selfHandled: true,
|
|
30392
|
+
content: "",
|
|
30393
|
+
handler: async (args, context) => {
|
|
30394
|
+
const arg = args.trim();
|
|
30395
|
+
if (arg === "new") {
|
|
30396
|
+
context.emit("done");
|
|
30397
|
+
return { handled: true, sessionAction: "new" };
|
|
30398
|
+
}
|
|
30399
|
+
const num = parseInt(arg, 10);
|
|
30400
|
+
if (!isNaN(num) && num > 0) {
|
|
30401
|
+
context.emit("done");
|
|
30402
|
+
return { handled: true, sessionAction: "switch", sessionNumber: num };
|
|
30403
|
+
}
|
|
30404
|
+
context.emit("done");
|
|
30405
|
+
return { handled: true, sessionAction: "list" };
|
|
30406
|
+
}
|
|
30407
|
+
};
|
|
30408
|
+
}
|
|
30259
30409
|
tokensCommand() {
|
|
30260
30410
|
return {
|
|
30261
30411
|
name: "tokens",
|
|
@@ -30407,7 +30557,7 @@ Format the summary as a brief bullet-point list. This summary will replace the c
|
|
|
30407
30557
|
handler: async (args, context) => {
|
|
30408
30558
|
const configPaths = [
|
|
30409
30559
|
join6(context.cwd, ".oldpal", "config.json"),
|
|
30410
|
-
join6(
|
|
30560
|
+
join6(homedir6(), ".oldpal", "config.json")
|
|
30411
30561
|
];
|
|
30412
30562
|
let message = `
|
|
30413
30563
|
**Configuration**
|
|
@@ -30425,7 +30575,7 @@ Format the summary as a brief bullet-point list. This summary will replace the c
|
|
|
30425
30575
|
`;
|
|
30426
30576
|
message += ` - Project: ${join6(context.cwd, ".oldpal", "commands")}
|
|
30427
30577
|
`;
|
|
30428
|
-
message += ` - Global: ${join6(
|
|
30578
|
+
message += ` - Global: ${join6(homedir6(), ".oldpal", "commands")}
|
|
30429
30579
|
`;
|
|
30430
30580
|
context.emit("text", message);
|
|
30431
30581
|
context.emit("done");
|
|
@@ -30647,7 +30797,7 @@ async function createLLMClient(config) {
|
|
|
30647
30797
|
|
|
30648
30798
|
// packages/core/src/config.ts
|
|
30649
30799
|
import { join as join8 } from "path";
|
|
30650
|
-
import { homedir as
|
|
30800
|
+
import { homedir as homedir8 } from "os";
|
|
30651
30801
|
var DEFAULT_CONFIG = {
|
|
30652
30802
|
llm: {
|
|
30653
30803
|
provider: "anthropic",
|
|
@@ -30677,7 +30827,7 @@ var DEFAULT_CONFIG = {
|
|
|
30677
30827
|
]
|
|
30678
30828
|
};
|
|
30679
30829
|
function getConfigDir() {
|
|
30680
|
-
return join8(
|
|
30830
|
+
return join8(homedir8(), ".oldpal");
|
|
30681
30831
|
}
|
|
30682
30832
|
function getConfigPath(filename) {
|
|
30683
30833
|
return join8(getConfigDir(), filename);
|
|
@@ -30749,14 +30899,19 @@ async function loadJsonFile(path) {
|
|
|
30749
30899
|
return null;
|
|
30750
30900
|
}
|
|
30751
30901
|
}
|
|
30752
|
-
async function ensureConfigDir() {
|
|
30902
|
+
async function ensureConfigDir(sessionId) {
|
|
30753
30903
|
const { mkdir } = await import("fs/promises");
|
|
30754
30904
|
const configDir = getConfigDir();
|
|
30755
|
-
|
|
30905
|
+
const dirs = [
|
|
30756
30906
|
mkdir(configDir, { recursive: true }),
|
|
30757
30907
|
mkdir(join8(configDir, "sessions"), { recursive: true }),
|
|
30758
|
-
mkdir(join8(configDir, "skills"), { recursive: true })
|
|
30759
|
-
|
|
30908
|
+
mkdir(join8(configDir, "skills"), { recursive: true }),
|
|
30909
|
+
mkdir(join8(configDir, "temp"), { recursive: true })
|
|
30910
|
+
];
|
|
30911
|
+
if (sessionId) {
|
|
30912
|
+
dirs.push(mkdir(join8(configDir, "temp", sessionId), { recursive: true }));
|
|
30913
|
+
}
|
|
30914
|
+
await Promise.all(dirs);
|
|
30760
30915
|
}
|
|
30761
30916
|
async function loadSystemPrompt(cwd2 = process.cwd()) {
|
|
30762
30917
|
const prompts = [];
|
|
@@ -30834,7 +30989,7 @@ class AgentLoop {
|
|
|
30834
30989
|
async initialize() {
|
|
30835
30990
|
const [config] = await Promise.all([
|
|
30836
30991
|
loadConfig(this.cwd),
|
|
30837
|
-
ensureConfigDir()
|
|
30992
|
+
ensureConfigDir(this.sessionId)
|
|
30838
30993
|
]);
|
|
30839
30994
|
this.config = config;
|
|
30840
30995
|
const [, , , hooksConfig, systemPrompt] = await Promise.all([
|
|
@@ -30848,7 +31003,7 @@ class AgentLoop {
|
|
|
30848
31003
|
this.commandLoader.loadAll()
|
|
30849
31004
|
]);
|
|
30850
31005
|
this.toolRegistry.register(BashTool.tool, BashTool.executor);
|
|
30851
|
-
FilesystemTools.registerAll(this.toolRegistry);
|
|
31006
|
+
FilesystemTools.registerAll(this.toolRegistry, this.sessionId);
|
|
30852
31007
|
WebTools.registerAll(this.toolRegistry);
|
|
30853
31008
|
ImageTools.registerAll(this.toolRegistry);
|
|
30854
31009
|
this.connectorBridge.registerAll(this.toolRegistry);
|
|
@@ -31060,7 +31215,7 @@ init_anthropic();
|
|
|
31060
31215
|
// packages/core/src/logger.ts
|
|
31061
31216
|
import { existsSync as existsSync6, mkdirSync as mkdirSync2, appendFileSync } from "fs";
|
|
31062
31217
|
import { join as join9 } from "path";
|
|
31063
|
-
import { homedir as
|
|
31218
|
+
import { homedir as homedir9 } from "os";
|
|
31064
31219
|
|
|
31065
31220
|
class Logger {
|
|
31066
31221
|
logDir;
|
|
@@ -31068,7 +31223,7 @@ class Logger {
|
|
|
31068
31223
|
sessionId;
|
|
31069
31224
|
constructor(sessionId) {
|
|
31070
31225
|
this.sessionId = sessionId;
|
|
31071
|
-
this.logDir = join9(
|
|
31226
|
+
this.logDir = join9(homedir9(), ".oldpal", "logs");
|
|
31072
31227
|
this.ensureDir(this.logDir);
|
|
31073
31228
|
const date = new Date().toISOString().split("T")[0];
|
|
31074
31229
|
this.logFile = join9(this.logDir, `${date}.log`);
|
|
@@ -31114,7 +31269,7 @@ class SessionStorage {
|
|
|
31114
31269
|
sessionId;
|
|
31115
31270
|
constructor(sessionId) {
|
|
31116
31271
|
this.sessionId = sessionId;
|
|
31117
|
-
this.sessionsDir = join9(
|
|
31272
|
+
this.sessionsDir = join9(homedir9(), ".oldpal", "sessions");
|
|
31118
31273
|
this.ensureDir(this.sessionsDir);
|
|
31119
31274
|
this.sessionFile = join9(this.sessionsDir, `${sessionId}.json`);
|
|
31120
31275
|
}
|
|
@@ -31133,7 +31288,7 @@ class SessionStorage {
|
|
|
31133
31288
|
}
|
|
31134
31289
|
}
|
|
31135
31290
|
function initOldpalDir() {
|
|
31136
|
-
const baseDir = join9(
|
|
31291
|
+
const baseDir = join9(homedir9(), ".oldpal");
|
|
31137
31292
|
const dirs = [
|
|
31138
31293
|
baseDir,
|
|
31139
31294
|
join9(baseDir, "sessions"),
|
|
@@ -31293,6 +31448,153 @@ class EmbeddedClient {
|
|
|
31293
31448
|
this.messages = [];
|
|
31294
31449
|
this.logger.info("Conversation cleared");
|
|
31295
31450
|
}
|
|
31451
|
+
getCwd() {
|
|
31452
|
+
return this.cwd;
|
|
31453
|
+
}
|
|
31454
|
+
getStartedAt() {
|
|
31455
|
+
return this.startedAt;
|
|
31456
|
+
}
|
|
31457
|
+
getMessages() {
|
|
31458
|
+
return [...this.messages];
|
|
31459
|
+
}
|
|
31460
|
+
}
|
|
31461
|
+
// packages/core/src/sessions/registry.ts
|
|
31462
|
+
class SessionRegistry {
|
|
31463
|
+
sessions = new Map;
|
|
31464
|
+
activeSessionId = null;
|
|
31465
|
+
chunkBuffers = new Map;
|
|
31466
|
+
chunkCallbacks = [];
|
|
31467
|
+
errorCallbacks = [];
|
|
31468
|
+
async createSession(cwd2) {
|
|
31469
|
+
const client = new EmbeddedClient(cwd2);
|
|
31470
|
+
await client.initialize();
|
|
31471
|
+
const sessionInfo = {
|
|
31472
|
+
id: client.getSessionId(),
|
|
31473
|
+
cwd: cwd2,
|
|
31474
|
+
startedAt: Date.now(),
|
|
31475
|
+
updatedAt: Date.now(),
|
|
31476
|
+
isProcessing: false,
|
|
31477
|
+
client
|
|
31478
|
+
};
|
|
31479
|
+
client.onChunk((chunk) => {
|
|
31480
|
+
this.handleChunk(sessionInfo.id, chunk);
|
|
31481
|
+
});
|
|
31482
|
+
client.onError((error) => {
|
|
31483
|
+
if (this.activeSessionId === sessionInfo.id) {
|
|
31484
|
+
for (const callback of this.errorCallbacks) {
|
|
31485
|
+
callback(error);
|
|
31486
|
+
}
|
|
31487
|
+
}
|
|
31488
|
+
});
|
|
31489
|
+
this.sessions.set(sessionInfo.id, sessionInfo);
|
|
31490
|
+
this.chunkBuffers.set(sessionInfo.id, []);
|
|
31491
|
+
if (this.activeSessionId === null) {
|
|
31492
|
+
this.activeSessionId = sessionInfo.id;
|
|
31493
|
+
}
|
|
31494
|
+
return sessionInfo;
|
|
31495
|
+
}
|
|
31496
|
+
handleChunk(sessionId, chunk) {
|
|
31497
|
+
const session = this.sessions.get(sessionId);
|
|
31498
|
+
if (session) {
|
|
31499
|
+
session.updatedAt = Date.now();
|
|
31500
|
+
if (chunk.type === "done") {
|
|
31501
|
+
session.isProcessing = false;
|
|
31502
|
+
}
|
|
31503
|
+
}
|
|
31504
|
+
if (sessionId === this.activeSessionId) {
|
|
31505
|
+
for (const callback of this.chunkCallbacks) {
|
|
31506
|
+
callback(chunk);
|
|
31507
|
+
}
|
|
31508
|
+
} else {
|
|
31509
|
+
const buffer = this.chunkBuffers.get(sessionId);
|
|
31510
|
+
if (buffer) {
|
|
31511
|
+
buffer.push(chunk);
|
|
31512
|
+
}
|
|
31513
|
+
}
|
|
31514
|
+
}
|
|
31515
|
+
async switchSession(id) {
|
|
31516
|
+
if (!this.sessions.has(id)) {
|
|
31517
|
+
throw new Error(`Session ${id} not found`);
|
|
31518
|
+
}
|
|
31519
|
+
if (this.activeSessionId === id) {
|
|
31520
|
+
return;
|
|
31521
|
+
}
|
|
31522
|
+
this.activeSessionId = id;
|
|
31523
|
+
const buffer = this.chunkBuffers.get(id);
|
|
31524
|
+
if (buffer && buffer.length > 0) {
|
|
31525
|
+
for (const chunk of buffer) {
|
|
31526
|
+
for (const callback of this.chunkCallbacks) {
|
|
31527
|
+
callback(chunk);
|
|
31528
|
+
}
|
|
31529
|
+
}
|
|
31530
|
+
this.chunkBuffers.set(id, []);
|
|
31531
|
+
}
|
|
31532
|
+
}
|
|
31533
|
+
listSessions() {
|
|
31534
|
+
return Array.from(this.sessions.values()).sort((a, b) => b.updatedAt - a.updatedAt);
|
|
31535
|
+
}
|
|
31536
|
+
getActiveSession() {
|
|
31537
|
+
if (!this.activeSessionId)
|
|
31538
|
+
return null;
|
|
31539
|
+
return this.sessions.get(this.activeSessionId) || null;
|
|
31540
|
+
}
|
|
31541
|
+
getActiveSessionId() {
|
|
31542
|
+
return this.activeSessionId;
|
|
31543
|
+
}
|
|
31544
|
+
getSession(id) {
|
|
31545
|
+
return this.sessions.get(id) || null;
|
|
31546
|
+
}
|
|
31547
|
+
getSessionIndex(id) {
|
|
31548
|
+
const sessions = this.listSessions();
|
|
31549
|
+
return sessions.findIndex((s) => s.id === id) + 1;
|
|
31550
|
+
}
|
|
31551
|
+
getSessionCount() {
|
|
31552
|
+
return this.sessions.size;
|
|
31553
|
+
}
|
|
31554
|
+
closeSession(id) {
|
|
31555
|
+
const session = this.sessions.get(id);
|
|
31556
|
+
if (session) {
|
|
31557
|
+
session.client.disconnect();
|
|
31558
|
+
this.sessions.delete(id);
|
|
31559
|
+
this.chunkBuffers.delete(id);
|
|
31560
|
+
if (this.activeSessionId === id) {
|
|
31561
|
+
const remaining = this.listSessions();
|
|
31562
|
+
this.activeSessionId = remaining.length > 0 ? remaining[0].id : null;
|
|
31563
|
+
}
|
|
31564
|
+
}
|
|
31565
|
+
}
|
|
31566
|
+
closeAll() {
|
|
31567
|
+
for (const session of this.sessions.values()) {
|
|
31568
|
+
session.client.disconnect();
|
|
31569
|
+
}
|
|
31570
|
+
this.sessions.clear();
|
|
31571
|
+
this.chunkBuffers.clear();
|
|
31572
|
+
this.activeSessionId = null;
|
|
31573
|
+
}
|
|
31574
|
+
onChunk(callback) {
|
|
31575
|
+
this.chunkCallbacks.push(callback);
|
|
31576
|
+
}
|
|
31577
|
+
onError(callback) {
|
|
31578
|
+
this.errorCallbacks.push(callback);
|
|
31579
|
+
}
|
|
31580
|
+
setProcessing(id, isProcessing) {
|
|
31581
|
+
const session = this.sessions.get(id);
|
|
31582
|
+
if (session) {
|
|
31583
|
+
session.isProcessing = isProcessing;
|
|
31584
|
+
session.updatedAt = Date.now();
|
|
31585
|
+
}
|
|
31586
|
+
}
|
|
31587
|
+
hasProcessingSession() {
|
|
31588
|
+
for (const session of this.sessions.values()) {
|
|
31589
|
+
if (session.isProcessing) {
|
|
31590
|
+
return true;
|
|
31591
|
+
}
|
|
31592
|
+
}
|
|
31593
|
+
return false;
|
|
31594
|
+
}
|
|
31595
|
+
getBackgroundProcessingSessions() {
|
|
31596
|
+
return Array.from(this.sessions.values()).filter((s) => s.isProcessing && s.id !== this.activeSessionId);
|
|
31597
|
+
}
|
|
31296
31598
|
}
|
|
31297
31599
|
// packages/terminal/src/components/Input.tsx
|
|
31298
31600
|
var import_react23 = __toESM(require_react(), 1);
|
|
@@ -31579,19 +31881,28 @@ function Messages4({
|
|
|
31579
31881
|
const startIndex = Math.max(0, endIndex - maxVisible);
|
|
31580
31882
|
const visibleMessages = messages.slice(startIndex, endIndex);
|
|
31581
31883
|
const groupedMessages = groupConsecutiveToolMessages(visibleMessages);
|
|
31884
|
+
const historicalItems = groupedMessages.map((group) => {
|
|
31885
|
+
if (group.type === "single") {
|
|
31886
|
+
return { id: group.message.id, group };
|
|
31887
|
+
}
|
|
31888
|
+
return { id: group.messages[0].id, group };
|
|
31889
|
+
});
|
|
31582
31890
|
return /* @__PURE__ */ jsx_dev_runtime3.jsxDEV(Box_default, {
|
|
31583
31891
|
flexDirection: "column",
|
|
31584
31892
|
children: [
|
|
31585
|
-
|
|
31586
|
-
|
|
31587
|
-
|
|
31588
|
-
|
|
31589
|
-
|
|
31590
|
-
|
|
31591
|
-
|
|
31592
|
-
|
|
31593
|
-
|
|
31594
|
-
|
|
31893
|
+
/* @__PURE__ */ jsx_dev_runtime3.jsxDEV(Static, {
|
|
31894
|
+
items: historicalItems,
|
|
31895
|
+
children: (item) => {
|
|
31896
|
+
if (item.group.type === "single") {
|
|
31897
|
+
return /* @__PURE__ */ jsx_dev_runtime3.jsxDEV(MessageBubble, {
|
|
31898
|
+
message: item.group.message
|
|
31899
|
+
}, item.id, false, undefined, this);
|
|
31900
|
+
}
|
|
31901
|
+
return /* @__PURE__ */ jsx_dev_runtime3.jsxDEV(CombinedToolMessage, {
|
|
31902
|
+
messages: item.group.messages
|
|
31903
|
+
}, item.id, false, undefined, this);
|
|
31904
|
+
}
|
|
31905
|
+
}, undefined, false, undefined, this),
|
|
31595
31906
|
activityLog.map((entry) => {
|
|
31596
31907
|
if (entry.type === "text" && entry.content) {
|
|
31597
31908
|
return /* @__PURE__ */ jsx_dev_runtime3.jsxDEV(Box_default, {
|
|
@@ -31861,26 +32172,47 @@ function truncate(text, maxLength) {
|
|
|
31861
32172
|
|
|
31862
32173
|
// packages/terminal/src/components/Status.tsx
|
|
31863
32174
|
var jsx_dev_runtime4 = __toESM(require_jsx_dev_runtime(), 1);
|
|
31864
|
-
function Status({
|
|
32175
|
+
function Status({
|
|
32176
|
+
isProcessing,
|
|
32177
|
+
cwd: cwd2,
|
|
32178
|
+
queueLength = 0,
|
|
32179
|
+
tokenUsage,
|
|
32180
|
+
sessionIndex,
|
|
32181
|
+
sessionCount,
|
|
32182
|
+
backgroundProcessingCount = 0
|
|
32183
|
+
}) {
|
|
31865
32184
|
let contextInfo = "";
|
|
31866
32185
|
if (tokenUsage && tokenUsage.maxContextTokens > 0) {
|
|
31867
32186
|
const percent = Math.round(tokenUsage.totalTokens / tokenUsage.maxContextTokens * 100);
|
|
31868
|
-
contextInfo = `${percent}% context
|
|
32187
|
+
contextInfo = `${percent}% context`;
|
|
31869
32188
|
}
|
|
32189
|
+
const sessionInfo = sessionIndex && sessionCount ? `Session ${sessionIndex}/${sessionCount}` : "";
|
|
32190
|
+
const bgIndicator = backgroundProcessingCount > 0 ? ` (${backgroundProcessingCount} processing)` : "";
|
|
31870
32191
|
return /* @__PURE__ */ jsx_dev_runtime4.jsxDEV(Box_default, {
|
|
31871
32192
|
marginTop: 1,
|
|
31872
32193
|
justifyContent: "space-between",
|
|
31873
32194
|
children: [
|
|
31874
32195
|
/* @__PURE__ */ jsx_dev_runtime4.jsxDEV(Text, {
|
|
31875
32196
|
dimColor: true,
|
|
31876
|
-
children:
|
|
31877
|
-
|
|
32197
|
+
children: [
|
|
32198
|
+
"/help for commands",
|
|
32199
|
+
sessionCount && sessionCount > 1 ? " | Ctrl+S sessions" : ""
|
|
32200
|
+
]
|
|
32201
|
+
}, undefined, true, undefined, this),
|
|
31878
32202
|
/* @__PURE__ */ jsx_dev_runtime4.jsxDEV(Box_default, {
|
|
31879
32203
|
children: [
|
|
31880
32204
|
isProcessing && /* @__PURE__ */ jsx_dev_runtime4.jsxDEV(Text, {
|
|
31881
32205
|
dimColor: true,
|
|
31882
32206
|
children: "esc to stop \xB7 "
|
|
31883
32207
|
}, undefined, false, undefined, this),
|
|
32208
|
+
sessionInfo && /* @__PURE__ */ jsx_dev_runtime4.jsxDEV(Text, {
|
|
32209
|
+
dimColor: true,
|
|
32210
|
+
children: [
|
|
32211
|
+
sessionInfo,
|
|
32212
|
+
bgIndicator,
|
|
32213
|
+
contextInfo ? " \xB7 " : ""
|
|
32214
|
+
]
|
|
32215
|
+
}, undefined, true, undefined, this),
|
|
31884
32216
|
contextInfo && /* @__PURE__ */ jsx_dev_runtime4.jsxDEV(Text, {
|
|
31885
32217
|
dimColor: true,
|
|
31886
32218
|
children: contextInfo
|
|
@@ -32079,8 +32411,131 @@ function WelcomeBanner({ version, model, directory }) {
|
|
|
32079
32411
|
}, undefined, true, undefined, this);
|
|
32080
32412
|
}
|
|
32081
32413
|
|
|
32082
|
-
// packages/terminal/src/components/
|
|
32414
|
+
// packages/terminal/src/components/SessionSelector.tsx
|
|
32415
|
+
var import_react26 = __toESM(require_react(), 1);
|
|
32083
32416
|
var jsx_dev_runtime8 = __toESM(require_jsx_dev_runtime(), 1);
|
|
32417
|
+
function formatSessionTime(timestamp) {
|
|
32418
|
+
const date = new Date(timestamp);
|
|
32419
|
+
const now2 = new Date;
|
|
32420
|
+
const isToday = date.toDateString() === now2.toDateString();
|
|
32421
|
+
if (isToday) {
|
|
32422
|
+
return date.toLocaleTimeString("en-US", {
|
|
32423
|
+
hour: "numeric",
|
|
32424
|
+
minute: "2-digit",
|
|
32425
|
+
hour12: true
|
|
32426
|
+
}).toLowerCase();
|
|
32427
|
+
}
|
|
32428
|
+
return date.toLocaleDateString("en-US", {
|
|
32429
|
+
month: "short",
|
|
32430
|
+
day: "numeric",
|
|
32431
|
+
hour: "numeric",
|
|
32432
|
+
minute: "2-digit",
|
|
32433
|
+
hour12: true
|
|
32434
|
+
}).toLowerCase();
|
|
32435
|
+
}
|
|
32436
|
+
function formatPath(cwd2) {
|
|
32437
|
+
const home = process.env.HOME || "";
|
|
32438
|
+
if (cwd2.startsWith(home)) {
|
|
32439
|
+
return "~" + cwd2.slice(home.length);
|
|
32440
|
+
}
|
|
32441
|
+
return cwd2;
|
|
32442
|
+
}
|
|
32443
|
+
function SessionSelector({
|
|
32444
|
+
sessions,
|
|
32445
|
+
activeSessionId,
|
|
32446
|
+
onSelect,
|
|
32447
|
+
onNew,
|
|
32448
|
+
onCancel
|
|
32449
|
+
}) {
|
|
32450
|
+
const [selectedIndex, setSelectedIndex] = import_react26.useState(0);
|
|
32451
|
+
use_input_default((input, key) => {
|
|
32452
|
+
if (key.escape) {
|
|
32453
|
+
onCancel();
|
|
32454
|
+
return;
|
|
32455
|
+
}
|
|
32456
|
+
if (key.return) {
|
|
32457
|
+
if (selectedIndex === sessions.length) {
|
|
32458
|
+
onNew();
|
|
32459
|
+
} else {
|
|
32460
|
+
onSelect(sessions[selectedIndex].id);
|
|
32461
|
+
}
|
|
32462
|
+
return;
|
|
32463
|
+
}
|
|
32464
|
+
if (key.upArrow) {
|
|
32465
|
+
setSelectedIndex((prev) => Math.max(0, prev - 1));
|
|
32466
|
+
}
|
|
32467
|
+
if (key.downArrow) {
|
|
32468
|
+
setSelectedIndex((prev) => Math.min(sessions.length, prev + 1));
|
|
32469
|
+
}
|
|
32470
|
+
const num = parseInt(input, 10);
|
|
32471
|
+
if (!isNaN(num) && num >= 1 && num <= sessions.length) {
|
|
32472
|
+
onSelect(sessions[num - 1].id);
|
|
32473
|
+
}
|
|
32474
|
+
if (input === "n") {
|
|
32475
|
+
onNew();
|
|
32476
|
+
}
|
|
32477
|
+
});
|
|
32478
|
+
return /* @__PURE__ */ jsx_dev_runtime8.jsxDEV(Box_default, {
|
|
32479
|
+
flexDirection: "column",
|
|
32480
|
+
paddingY: 1,
|
|
32481
|
+
children: [
|
|
32482
|
+
/* @__PURE__ */ jsx_dev_runtime8.jsxDEV(Box_default, {
|
|
32483
|
+
marginBottom: 1,
|
|
32484
|
+
children: /* @__PURE__ */ jsx_dev_runtime8.jsxDEV(Text, {
|
|
32485
|
+
bold: true,
|
|
32486
|
+
children: "Sessions"
|
|
32487
|
+
}, undefined, false, undefined, this)
|
|
32488
|
+
}, undefined, false, undefined, this),
|
|
32489
|
+
sessions.map((session, index) => {
|
|
32490
|
+
const isActive = session.id === activeSessionId;
|
|
32491
|
+
const isSelected = index === selectedIndex;
|
|
32492
|
+
const prefix = isActive ? "[*]" : " ";
|
|
32493
|
+
const time = formatSessionTime(session.updatedAt);
|
|
32494
|
+
const path = formatPath(session.cwd);
|
|
32495
|
+
const processing = session.isProcessing ? " (processing)" : "";
|
|
32496
|
+
return /* @__PURE__ */ jsx_dev_runtime8.jsxDEV(Box_default, {
|
|
32497
|
+
children: /* @__PURE__ */ jsx_dev_runtime8.jsxDEV(Text, {
|
|
32498
|
+
inverse: isSelected,
|
|
32499
|
+
color: isActive ? "green" : undefined,
|
|
32500
|
+
dimColor: !isSelected && !isActive,
|
|
32501
|
+
children: [
|
|
32502
|
+
prefix,
|
|
32503
|
+
" ",
|
|
32504
|
+
index + 1,
|
|
32505
|
+
". ",
|
|
32506
|
+
time,
|
|
32507
|
+
" ",
|
|
32508
|
+
path,
|
|
32509
|
+
processing
|
|
32510
|
+
]
|
|
32511
|
+
}, undefined, true, undefined, this)
|
|
32512
|
+
}, session.id, false, undefined, this);
|
|
32513
|
+
}),
|
|
32514
|
+
/* @__PURE__ */ jsx_dev_runtime8.jsxDEV(Box_default, {
|
|
32515
|
+
marginTop: 1,
|
|
32516
|
+
children: /* @__PURE__ */ jsx_dev_runtime8.jsxDEV(Text, {
|
|
32517
|
+
inverse: selectedIndex === sessions.length,
|
|
32518
|
+
dimColor: selectedIndex !== sessions.length,
|
|
32519
|
+
children: "+ New session (n)"
|
|
32520
|
+
}, undefined, false, undefined, this)
|
|
32521
|
+
}, undefined, false, undefined, this),
|
|
32522
|
+
/* @__PURE__ */ jsx_dev_runtime8.jsxDEV(Box_default, {
|
|
32523
|
+
marginTop: 1,
|
|
32524
|
+
children: /* @__PURE__ */ jsx_dev_runtime8.jsxDEV(Text, {
|
|
32525
|
+
dimColor: true,
|
|
32526
|
+
children: [
|
|
32527
|
+
"Enter to select | Esc to cancel | 1-",
|
|
32528
|
+
sessions.length,
|
|
32529
|
+
" to switch | n for new"
|
|
32530
|
+
]
|
|
32531
|
+
}, undefined, true, undefined, this)
|
|
32532
|
+
}, undefined, false, undefined, this)
|
|
32533
|
+
]
|
|
32534
|
+
}, undefined, true, undefined, this);
|
|
32535
|
+
}
|
|
32536
|
+
|
|
32537
|
+
// packages/terminal/src/components/App.tsx
|
|
32538
|
+
var jsx_dev_runtime9 = __toESM(require_jsx_dev_runtime(), 1);
|
|
32084
32539
|
function formatToolName(toolCall) {
|
|
32085
32540
|
const { name, input } = toolCall;
|
|
32086
32541
|
switch (name) {
|
|
@@ -32107,27 +32562,183 @@ function formatToolName(toolCall) {
|
|
|
32107
32562
|
}
|
|
32108
32563
|
function App2({ cwd: cwd2 }) {
|
|
32109
32564
|
const { exit } = use_app_default();
|
|
32110
|
-
const [
|
|
32111
|
-
const
|
|
32112
|
-
const [
|
|
32113
|
-
const [
|
|
32114
|
-
const [
|
|
32115
|
-
const
|
|
32116
|
-
const [
|
|
32117
|
-
const [
|
|
32118
|
-
const [
|
|
32119
|
-
const [
|
|
32120
|
-
const [
|
|
32121
|
-
const [
|
|
32122
|
-
const [
|
|
32123
|
-
const [
|
|
32124
|
-
const [
|
|
32125
|
-
const
|
|
32126
|
-
const
|
|
32127
|
-
const
|
|
32128
|
-
const
|
|
32129
|
-
const
|
|
32130
|
-
|
|
32565
|
+
const [registry2] = import_react27.useState(() => new SessionRegistry);
|
|
32566
|
+
const registryRef = import_react27.useRef(registry2);
|
|
32567
|
+
const [activeSessionId, setActiveSessionId] = import_react27.useState(null);
|
|
32568
|
+
const [isInitializing, setIsInitializing] = import_react27.useState(true);
|
|
32569
|
+
const [showSessionSelector, setShowSessionSelector] = import_react27.useState(false);
|
|
32570
|
+
const sessionUIStates = import_react27.useRef(new Map);
|
|
32571
|
+
const [messages, setMessages] = import_react27.useState([]);
|
|
32572
|
+
const [currentResponse, setCurrentResponse] = import_react27.useState("");
|
|
32573
|
+
const [currentToolCall, setCurrentToolCall] = import_react27.useState();
|
|
32574
|
+
const [isProcessing, setIsProcessing] = import_react27.useState(false);
|
|
32575
|
+
const [error, setError] = import_react27.useState(null);
|
|
32576
|
+
const [messageQueue, setMessageQueue] = import_react27.useState([]);
|
|
32577
|
+
const [activityLog, setActivityLog] = import_react27.useState([]);
|
|
32578
|
+
const [tokenUsage, setTokenUsage] = import_react27.useState();
|
|
32579
|
+
const [processingStartTime, setProcessingStartTime] = import_react27.useState();
|
|
32580
|
+
const [currentTurnTokens, setCurrentTurnTokens] = import_react27.useState(0);
|
|
32581
|
+
const [scrollOffset, setScrollOffset] = import_react27.useState(0);
|
|
32582
|
+
const [autoScroll, setAutoScroll] = import_react27.useState(true);
|
|
32583
|
+
const responseRef = import_react27.useRef("");
|
|
32584
|
+
const toolCallsRef = import_react27.useRef([]);
|
|
32585
|
+
const toolResultsRef = import_react27.useRef([]);
|
|
32586
|
+
const activityLogRef = import_react27.useRef([]);
|
|
32587
|
+
const saveCurrentSessionState = import_react27.useCallback(() => {
|
|
32588
|
+
if (activeSessionId) {
|
|
32589
|
+
sessionUIStates.current.set(activeSessionId, {
|
|
32590
|
+
messages,
|
|
32591
|
+
currentResponse: responseRef.current,
|
|
32592
|
+
activityLog: activityLogRef.current,
|
|
32593
|
+
tokenUsage,
|
|
32594
|
+
processingStartTime,
|
|
32595
|
+
currentTurnTokens,
|
|
32596
|
+
messageQueue,
|
|
32597
|
+
error
|
|
32598
|
+
});
|
|
32599
|
+
}
|
|
32600
|
+
}, [activeSessionId, messages, tokenUsage, processingStartTime, currentTurnTokens, messageQueue, error]);
|
|
32601
|
+
const loadSessionState = import_react27.useCallback((sessionId) => {
|
|
32602
|
+
const state = sessionUIStates.current.get(sessionId);
|
|
32603
|
+
if (state) {
|
|
32604
|
+
setMessages(state.messages);
|
|
32605
|
+
setCurrentResponse(state.currentResponse);
|
|
32606
|
+
responseRef.current = state.currentResponse;
|
|
32607
|
+
setActivityLog(state.activityLog);
|
|
32608
|
+
activityLogRef.current = state.activityLog;
|
|
32609
|
+
setTokenUsage(state.tokenUsage);
|
|
32610
|
+
setProcessingStartTime(state.processingStartTime);
|
|
32611
|
+
setCurrentTurnTokens(state.currentTurnTokens);
|
|
32612
|
+
setMessageQueue(state.messageQueue);
|
|
32613
|
+
setError(state.error);
|
|
32614
|
+
} else {
|
|
32615
|
+
setMessages([]);
|
|
32616
|
+
setCurrentResponse("");
|
|
32617
|
+
responseRef.current = "";
|
|
32618
|
+
setActivityLog([]);
|
|
32619
|
+
activityLogRef.current = [];
|
|
32620
|
+
setTokenUsage(undefined);
|
|
32621
|
+
setProcessingStartTime(undefined);
|
|
32622
|
+
setCurrentTurnTokens(0);
|
|
32623
|
+
setMessageQueue([]);
|
|
32624
|
+
setError(null);
|
|
32625
|
+
}
|
|
32626
|
+
setScrollOffset(0);
|
|
32627
|
+
setAutoScroll(true);
|
|
32628
|
+
}, []);
|
|
32629
|
+
const handleChunk = import_react27.useCallback((chunk) => {
|
|
32630
|
+
if (chunk.type === "text" && chunk.content) {
|
|
32631
|
+
responseRef.current += chunk.content;
|
|
32632
|
+
setCurrentResponse(responseRef.current);
|
|
32633
|
+
} else if (chunk.type === "tool_use" && chunk.toolCall) {
|
|
32634
|
+
if (responseRef.current.trim()) {
|
|
32635
|
+
const textEntry = {
|
|
32636
|
+
id: generateId(),
|
|
32637
|
+
type: "text",
|
|
32638
|
+
content: responseRef.current,
|
|
32639
|
+
timestamp: now()
|
|
32640
|
+
};
|
|
32641
|
+
activityLogRef.current = [...activityLogRef.current, textEntry];
|
|
32642
|
+
setActivityLog(activityLogRef.current);
|
|
32643
|
+
setCurrentResponse("");
|
|
32644
|
+
responseRef.current = "";
|
|
32645
|
+
}
|
|
32646
|
+
toolCallsRef.current.push(chunk.toolCall);
|
|
32647
|
+
const toolEntry = {
|
|
32648
|
+
id: generateId(),
|
|
32649
|
+
type: "tool_call",
|
|
32650
|
+
toolCall: chunk.toolCall,
|
|
32651
|
+
timestamp: now()
|
|
32652
|
+
};
|
|
32653
|
+
activityLogRef.current = [...activityLogRef.current, toolEntry];
|
|
32654
|
+
setActivityLog(activityLogRef.current);
|
|
32655
|
+
setCurrentToolCall(chunk.toolCall);
|
|
32656
|
+
} else if (chunk.type === "tool_result" && chunk.toolResult) {
|
|
32657
|
+
toolResultsRef.current.push(chunk.toolResult);
|
|
32658
|
+
const resultEntry = {
|
|
32659
|
+
id: generateId(),
|
|
32660
|
+
type: "tool_result",
|
|
32661
|
+
toolResult: chunk.toolResult,
|
|
32662
|
+
timestamp: now()
|
|
32663
|
+
};
|
|
32664
|
+
activityLogRef.current = [...activityLogRef.current, resultEntry];
|
|
32665
|
+
setActivityLog(activityLogRef.current);
|
|
32666
|
+
setCurrentToolCall(undefined);
|
|
32667
|
+
} else if (chunk.type === "error" && chunk.error) {
|
|
32668
|
+
setError(chunk.error);
|
|
32669
|
+
setIsProcessing(false);
|
|
32670
|
+
} else if (chunk.type === "exit") {
|
|
32671
|
+
registry2.closeAll();
|
|
32672
|
+
exit();
|
|
32673
|
+
} else if (chunk.type === "usage" && chunk.usage) {
|
|
32674
|
+
setTokenUsage(chunk.usage);
|
|
32675
|
+
setCurrentTurnTokens((prev) => prev + (chunk.usage?.outputTokens || 0));
|
|
32676
|
+
} else if (chunk.type === "done") {
|
|
32677
|
+
if (responseRef.current.trim()) {
|
|
32678
|
+
const textEntry = {
|
|
32679
|
+
id: generateId(),
|
|
32680
|
+
type: "text",
|
|
32681
|
+
content: responseRef.current,
|
|
32682
|
+
timestamp: now()
|
|
32683
|
+
};
|
|
32684
|
+
activityLogRef.current = [...activityLogRef.current, textEntry];
|
|
32685
|
+
}
|
|
32686
|
+
const fullContent = activityLogRef.current.filter((e) => e.type === "text").map((e) => e.content).join(`
|
|
32687
|
+
`) + (responseRef.current ? `
|
|
32688
|
+
` + responseRef.current : "");
|
|
32689
|
+
if (fullContent.trim() || toolCallsRef.current.length > 0) {
|
|
32690
|
+
setMessages((prev) => [
|
|
32691
|
+
...prev,
|
|
32692
|
+
{
|
|
32693
|
+
id: generateId(),
|
|
32694
|
+
role: "assistant",
|
|
32695
|
+
content: fullContent.trim(),
|
|
32696
|
+
timestamp: now(),
|
|
32697
|
+
toolCalls: toolCallsRef.current.length > 0 ? [...toolCallsRef.current] : undefined,
|
|
32698
|
+
toolResults: toolResultsRef.current.length > 0 ? [...toolResultsRef.current] : undefined
|
|
32699
|
+
}
|
|
32700
|
+
]);
|
|
32701
|
+
}
|
|
32702
|
+
setCurrentResponse("");
|
|
32703
|
+
responseRef.current = "";
|
|
32704
|
+
toolCallsRef.current = [];
|
|
32705
|
+
toolResultsRef.current = [];
|
|
32706
|
+
setCurrentToolCall(undefined);
|
|
32707
|
+
setActivityLog([]);
|
|
32708
|
+
activityLogRef.current = [];
|
|
32709
|
+
setProcessingStartTime(undefined);
|
|
32710
|
+
setCurrentTurnTokens(0);
|
|
32711
|
+
setIsProcessing(false);
|
|
32712
|
+
const activeSession2 = registry2.getActiveSession();
|
|
32713
|
+
if (activeSession2) {
|
|
32714
|
+
setTokenUsage(activeSession2.client.getTokenUsage());
|
|
32715
|
+
}
|
|
32716
|
+
}
|
|
32717
|
+
}, [registry2, exit]);
|
|
32718
|
+
import_react27.useEffect(() => {
|
|
32719
|
+
const initSession = async () => {
|
|
32720
|
+
try {
|
|
32721
|
+
registry2.onChunk(handleChunk);
|
|
32722
|
+
registry2.onError((err) => {
|
|
32723
|
+
setError(err.message);
|
|
32724
|
+
setIsProcessing(false);
|
|
32725
|
+
});
|
|
32726
|
+
const session = await registry2.createSession(cwd2);
|
|
32727
|
+
setActiveSessionId(session.id);
|
|
32728
|
+
setIsInitializing(false);
|
|
32729
|
+
} catch (err) {
|
|
32730
|
+
setError(err instanceof Error ? err.message : String(err));
|
|
32731
|
+
setIsInitializing(false);
|
|
32732
|
+
}
|
|
32733
|
+
};
|
|
32734
|
+
initSession();
|
|
32735
|
+
return () => {
|
|
32736
|
+
registry2.closeAll();
|
|
32737
|
+
};
|
|
32738
|
+
}, [cwd2, registry2, handleChunk]);
|
|
32739
|
+
const processQueue = import_react27.useCallback(async () => {
|
|
32740
|
+
const activeSession2 = registryRef.current.getActiveSession();
|
|
32741
|
+
if (!activeSession2 || messageQueue.length === 0)
|
|
32131
32742
|
return;
|
|
32132
32743
|
const nextMessage = messageQueue[0];
|
|
32133
32744
|
setMessageQueue((prev) => prev.slice(1));
|
|
@@ -32144,129 +32755,20 @@ function App2({ cwd: cwd2 }) {
|
|
|
32144
32755
|
toolResultsRef.current = [];
|
|
32145
32756
|
setError(null);
|
|
32146
32757
|
setCurrentToolCall(undefined);
|
|
32147
|
-
setLastToolResult(undefined);
|
|
32148
32758
|
setActivityLog([]);
|
|
32759
|
+
activityLogRef.current = [];
|
|
32149
32760
|
setProcessingStartTime(Date.now());
|
|
32150
32761
|
setCurrentTurnTokens(0);
|
|
32151
32762
|
setIsProcessing(true);
|
|
32152
|
-
|
|
32763
|
+
registryRef.current.setProcessing(activeSession2.id, true);
|
|
32764
|
+
await activeSession2.client.send(nextMessage);
|
|
32153
32765
|
}, [messageQueue]);
|
|
32154
|
-
|
|
32155
|
-
const initClient = async () => {
|
|
32156
|
-
try {
|
|
32157
|
-
const newClient = new EmbeddedClient(cwd2);
|
|
32158
|
-
clientRef.current = newClient;
|
|
32159
|
-
newClient.onChunk((chunk) => {
|
|
32160
|
-
if (chunk.type === "text" && chunk.content) {
|
|
32161
|
-
responseRef.current += chunk.content;
|
|
32162
|
-
setCurrentResponse(responseRef.current);
|
|
32163
|
-
} else if (chunk.type === "tool_use" && chunk.toolCall) {
|
|
32164
|
-
if (responseRef.current.trim()) {
|
|
32165
|
-
setActivityLog((prev) => [
|
|
32166
|
-
...prev,
|
|
32167
|
-
{
|
|
32168
|
-
id: generateId(),
|
|
32169
|
-
type: "text",
|
|
32170
|
-
content: responseRef.current,
|
|
32171
|
-
timestamp: now()
|
|
32172
|
-
}
|
|
32173
|
-
]);
|
|
32174
|
-
setCurrentResponse("");
|
|
32175
|
-
responseRef.current = "";
|
|
32176
|
-
}
|
|
32177
|
-
toolCallsRef.current.push(chunk.toolCall);
|
|
32178
|
-
setActivityLog((prev) => [
|
|
32179
|
-
...prev,
|
|
32180
|
-
{
|
|
32181
|
-
id: generateId(),
|
|
32182
|
-
type: "tool_call",
|
|
32183
|
-
toolCall: chunk.toolCall,
|
|
32184
|
-
timestamp: now()
|
|
32185
|
-
}
|
|
32186
|
-
]);
|
|
32187
|
-
setCurrentToolCall(chunk.toolCall);
|
|
32188
|
-
} else if (chunk.type === "tool_result" && chunk.toolResult) {
|
|
32189
|
-
toolResultsRef.current.push(chunk.toolResult);
|
|
32190
|
-
setActivityLog((prev) => [
|
|
32191
|
-
...prev,
|
|
32192
|
-
{
|
|
32193
|
-
id: generateId(),
|
|
32194
|
-
type: "tool_result",
|
|
32195
|
-
toolResult: chunk.toolResult,
|
|
32196
|
-
timestamp: now()
|
|
32197
|
-
}
|
|
32198
|
-
]);
|
|
32199
|
-
setCurrentToolCall(undefined);
|
|
32200
|
-
} else if (chunk.type === "error" && chunk.error) {
|
|
32201
|
-
setError(chunk.error);
|
|
32202
|
-
setIsProcessing(false);
|
|
32203
|
-
} else if (chunk.type === "exit") {
|
|
32204
|
-
exit();
|
|
32205
|
-
} else if (chunk.type === "usage" && chunk.usage) {
|
|
32206
|
-
setTokenUsage(chunk.usage);
|
|
32207
|
-
setCurrentTurnTokens((prev) => prev + (chunk.usage?.outputTokens || 0));
|
|
32208
|
-
} else if (chunk.type === "done") {
|
|
32209
|
-
if (responseRef.current.trim()) {
|
|
32210
|
-
setActivityLog((prev) => [
|
|
32211
|
-
...prev,
|
|
32212
|
-
{
|
|
32213
|
-
id: generateId(),
|
|
32214
|
-
type: "text",
|
|
32215
|
-
content: responseRef.current,
|
|
32216
|
-
timestamp: now()
|
|
32217
|
-
}
|
|
32218
|
-
]);
|
|
32219
|
-
}
|
|
32220
|
-
const fullContent = activityLog.filter((e) => e.type === "text").map((e) => e.content).join(`
|
|
32221
|
-
`) + (responseRef.current ? `
|
|
32222
|
-
` + responseRef.current : "");
|
|
32223
|
-
if (fullContent.trim() || toolCallsRef.current.length > 0) {
|
|
32224
|
-
setMessages((prev) => [
|
|
32225
|
-
...prev,
|
|
32226
|
-
{
|
|
32227
|
-
id: generateId(),
|
|
32228
|
-
role: "assistant",
|
|
32229
|
-
content: fullContent.trim(),
|
|
32230
|
-
timestamp: now(),
|
|
32231
|
-
toolCalls: toolCallsRef.current.length > 0 ? [...toolCallsRef.current] : undefined,
|
|
32232
|
-
toolResults: toolResultsRef.current.length > 0 ? [...toolResultsRef.current] : undefined
|
|
32233
|
-
}
|
|
32234
|
-
]);
|
|
32235
|
-
}
|
|
32236
|
-
setCurrentResponse("");
|
|
32237
|
-
responseRef.current = "";
|
|
32238
|
-
toolCallsRef.current = [];
|
|
32239
|
-
toolResultsRef.current = [];
|
|
32240
|
-
setCurrentToolCall(undefined);
|
|
32241
|
-
setActivityLog([]);
|
|
32242
|
-
setProcessingStartTime(undefined);
|
|
32243
|
-
setCurrentTurnTokens(0);
|
|
32244
|
-
setIsProcessing(false);
|
|
32245
|
-
if (newClient) {
|
|
32246
|
-
setTokenUsage(newClient.getTokenUsage());
|
|
32247
|
-
}
|
|
32248
|
-
}
|
|
32249
|
-
});
|
|
32250
|
-
newClient.onError((err) => {
|
|
32251
|
-
setError(err.message);
|
|
32252
|
-
setIsProcessing(false);
|
|
32253
|
-
});
|
|
32254
|
-
await newClient.initialize();
|
|
32255
|
-
setClient(newClient);
|
|
32256
|
-
setIsInitializing(false);
|
|
32257
|
-
} catch (err) {
|
|
32258
|
-
setError(err instanceof Error ? err.message : String(err));
|
|
32259
|
-
setIsInitializing(false);
|
|
32260
|
-
}
|
|
32261
|
-
};
|
|
32262
|
-
initClient();
|
|
32263
|
-
}, [cwd2]);
|
|
32264
|
-
import_react26.useEffect(() => {
|
|
32766
|
+
import_react27.useEffect(() => {
|
|
32265
32767
|
if (!isProcessing && messageQueue.length > 0) {
|
|
32266
32768
|
processQueue();
|
|
32267
32769
|
}
|
|
32268
32770
|
}, [isProcessing, messageQueue.length, processQueue]);
|
|
32269
|
-
|
|
32771
|
+
import_react27.useEffect(() => {
|
|
32270
32772
|
if (autoScroll) {
|
|
32271
32773
|
setScrollOffset(0);
|
|
32272
32774
|
}
|
|
@@ -32274,10 +32776,48 @@ function App2({ cwd: cwd2 }) {
|
|
|
32274
32776
|
const baseMaxVisible = 10;
|
|
32275
32777
|
const toolCallsHeight = isProcessing ? Math.min(toolCallsRef.current.length, 5) : 0;
|
|
32276
32778
|
const maxVisibleMessages = Math.max(3, baseMaxVisible - toolCallsHeight);
|
|
32779
|
+
const sessions = registry2.listSessions();
|
|
32780
|
+
const activeSession = registry2.getActiveSession();
|
|
32781
|
+
const sessionIndex = activeSessionId ? registry2.getSessionIndex(activeSessionId) : 0;
|
|
32782
|
+
const sessionCount = registry2.getSessionCount();
|
|
32783
|
+
const backgroundProcessingCount = registry2.getBackgroundProcessingSessions().length;
|
|
32784
|
+
const handleSessionSwitch = import_react27.useCallback(async (sessionId) => {
|
|
32785
|
+
if (sessionId === activeSessionId) {
|
|
32786
|
+
setShowSessionSelector(false);
|
|
32787
|
+
return;
|
|
32788
|
+
}
|
|
32789
|
+
saveCurrentSessionState();
|
|
32790
|
+
await registry2.switchSession(sessionId);
|
|
32791
|
+
setActiveSessionId(sessionId);
|
|
32792
|
+
loadSessionState(sessionId);
|
|
32793
|
+
const session = registry2.getSession(sessionId);
|
|
32794
|
+
if (session) {
|
|
32795
|
+
setIsProcessing(session.isProcessing);
|
|
32796
|
+
}
|
|
32797
|
+
setShowSessionSelector(false);
|
|
32798
|
+
}, [activeSessionId, registry2, saveCurrentSessionState, loadSessionState]);
|
|
32799
|
+
const handleNewSession = import_react27.useCallback(async () => {
|
|
32800
|
+
saveCurrentSessionState();
|
|
32801
|
+
const newSession = await registry2.createSession(cwd2);
|
|
32802
|
+
await registry2.switchSession(newSession.id);
|
|
32803
|
+
setActiveSessionId(newSession.id);
|
|
32804
|
+
loadSessionState(newSession.id);
|
|
32805
|
+
setIsProcessing(false);
|
|
32806
|
+
setShowSessionSelector(false);
|
|
32807
|
+
}, [cwd2, registry2, saveCurrentSessionState, loadSessionState]);
|
|
32277
32808
|
use_input_default((input, key) => {
|
|
32809
|
+
if (showSessionSelector) {
|
|
32810
|
+
return;
|
|
32811
|
+
}
|
|
32812
|
+
if (key.ctrl && input === "s") {
|
|
32813
|
+
if (sessions.length > 0) {
|
|
32814
|
+
setShowSessionSelector(true);
|
|
32815
|
+
}
|
|
32816
|
+
return;
|
|
32817
|
+
}
|
|
32278
32818
|
if (key.ctrl && input === "c") {
|
|
32279
|
-
if (isProcessing &&
|
|
32280
|
-
client.stop();
|
|
32819
|
+
if (isProcessing && activeSession) {
|
|
32820
|
+
activeSession.client.stop();
|
|
32281
32821
|
if (responseRef.current) {
|
|
32282
32822
|
setMessages((prev) => [
|
|
32283
32823
|
...prev,
|
|
@@ -32295,27 +32835,30 @@ function App2({ cwd: cwd2 }) {
|
|
|
32295
32835
|
}
|
|
32296
32836
|
setIsProcessing(false);
|
|
32297
32837
|
} else {
|
|
32838
|
+
registry2.closeAll();
|
|
32298
32839
|
exit();
|
|
32299
32840
|
}
|
|
32300
32841
|
}
|
|
32301
|
-
if (key.escape
|
|
32302
|
-
|
|
32303
|
-
|
|
32304
|
-
|
|
32305
|
-
|
|
32306
|
-
|
|
32307
|
-
|
|
32308
|
-
|
|
32309
|
-
|
|
32842
|
+
if (key.escape) {
|
|
32843
|
+
if (isProcessing && activeSession) {
|
|
32844
|
+
activeSession.client.stop();
|
|
32845
|
+
if (responseRef.current) {
|
|
32846
|
+
setMessages((prev) => [
|
|
32847
|
+
...prev,
|
|
32848
|
+
{
|
|
32849
|
+
id: generateId(),
|
|
32850
|
+
role: "assistant",
|
|
32851
|
+
content: responseRef.current + `
|
|
32310
32852
|
|
|
32311
32853
|
[stopped]`,
|
|
32312
|
-
|
|
32313
|
-
|
|
32314
|
-
|
|
32315
|
-
|
|
32316
|
-
|
|
32854
|
+
timestamp: now()
|
|
32855
|
+
}
|
|
32856
|
+
]);
|
|
32857
|
+
setCurrentResponse("");
|
|
32858
|
+
responseRef.current = "";
|
|
32859
|
+
}
|
|
32860
|
+
setIsProcessing(false);
|
|
32317
32861
|
}
|
|
32318
|
-
setIsProcessing(false);
|
|
32319
32862
|
}
|
|
32320
32863
|
if (key.pageUp || key.shift && key.upArrow) {
|
|
32321
32864
|
setScrollOffset((prev) => {
|
|
@@ -32344,16 +32887,30 @@ function App2({ cwd: cwd2 }) {
|
|
|
32344
32887
|
setAutoScroll(true);
|
|
32345
32888
|
}
|
|
32346
32889
|
});
|
|
32347
|
-
const handleSubmit =
|
|
32348
|
-
if (!
|
|
32890
|
+
const handleSubmit = import_react27.useCallback(async (input, mode = "normal") => {
|
|
32891
|
+
if (!activeSession || !input.trim())
|
|
32349
32892
|
return;
|
|
32350
32893
|
const trimmedInput = input.trim();
|
|
32894
|
+
if (trimmedInput.startsWith("/session")) {
|
|
32895
|
+
const arg = trimmedInput.slice(8).trim();
|
|
32896
|
+
if (arg === "new") {
|
|
32897
|
+
await handleNewSession();
|
|
32898
|
+
return;
|
|
32899
|
+
}
|
|
32900
|
+
const num = parseInt(arg, 10);
|
|
32901
|
+
if (!isNaN(num) && num > 0 && num <= sessions.length) {
|
|
32902
|
+
await handleSessionSwitch(sessions[num - 1].id);
|
|
32903
|
+
return;
|
|
32904
|
+
}
|
|
32905
|
+
setShowSessionSelector(true);
|
|
32906
|
+
return;
|
|
32907
|
+
}
|
|
32351
32908
|
if (mode === "queue" || isProcessing && mode === "normal") {
|
|
32352
32909
|
setMessageQueue((prev) => [...prev, trimmedInput]);
|
|
32353
32910
|
return;
|
|
32354
32911
|
}
|
|
32355
32912
|
if (mode === "interrupt" && isProcessing) {
|
|
32356
|
-
client.stop();
|
|
32913
|
+
activeSession.client.stop();
|
|
32357
32914
|
if (responseRef.current) {
|
|
32358
32915
|
setMessages((prev) => [
|
|
32359
32916
|
...prev,
|
|
@@ -32385,39 +32942,65 @@ function App2({ cwd: cwd2 }) {
|
|
|
32385
32942
|
toolResultsRef.current = [];
|
|
32386
32943
|
setError(null);
|
|
32387
32944
|
setCurrentToolCall(undefined);
|
|
32388
|
-
setLastToolResult(undefined);
|
|
32389
32945
|
setActivityLog([]);
|
|
32946
|
+
activityLogRef.current = [];
|
|
32390
32947
|
setProcessingStartTime(Date.now());
|
|
32391
32948
|
setCurrentTurnTokens(0);
|
|
32392
32949
|
setIsProcessing(true);
|
|
32393
|
-
|
|
32394
|
-
|
|
32950
|
+
registry2.setProcessing(activeSession.id, true);
|
|
32951
|
+
await activeSession.client.send(trimmedInput);
|
|
32952
|
+
}, [activeSession, isProcessing, registry2, sessions, handleNewSession, handleSessionSwitch]);
|
|
32395
32953
|
if (isInitializing) {
|
|
32396
|
-
return /* @__PURE__ */
|
|
32954
|
+
return /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Box_default, {
|
|
32397
32955
|
flexDirection: "column",
|
|
32398
32956
|
padding: 1,
|
|
32399
|
-
children: /* @__PURE__ */
|
|
32957
|
+
children: /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Spinner2, {
|
|
32400
32958
|
label: "Initializing..."
|
|
32401
32959
|
}, undefined, false, undefined, this)
|
|
32402
32960
|
}, undefined, false, undefined, this);
|
|
32403
32961
|
}
|
|
32962
|
+
if (showSessionSelector) {
|
|
32963
|
+
return /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Box_default, {
|
|
32964
|
+
flexDirection: "column",
|
|
32965
|
+
padding: 1,
|
|
32966
|
+
children: /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(SessionSelector, {
|
|
32967
|
+
sessions,
|
|
32968
|
+
activeSessionId,
|
|
32969
|
+
onSelect: handleSessionSwitch,
|
|
32970
|
+
onNew: handleNewSession,
|
|
32971
|
+
onCancel: () => setShowSessionSelector(false)
|
|
32972
|
+
}, undefined, false, undefined, this)
|
|
32973
|
+
}, undefined, false, undefined, this);
|
|
32974
|
+
}
|
|
32404
32975
|
const toolCallEntries = activityLog.filter((e) => e.type === "tool_call" && e.toolCall).map((e) => {
|
|
32405
32976
|
const result = activityLog.find((r) => r.type === "tool_result" && r.toolResult?.toolCallId === e.toolCall?.id)?.toolResult;
|
|
32406
32977
|
return { toolCall: e.toolCall, result };
|
|
32407
32978
|
});
|
|
32408
32979
|
const isThinking = isProcessing && !currentResponse && !currentToolCall && toolCallEntries.length === 0;
|
|
32409
32980
|
const showWelcome = messages.length === 0 && !isProcessing;
|
|
32410
|
-
return /* @__PURE__ */
|
|
32981
|
+
return /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Box_default, {
|
|
32411
32982
|
flexDirection: "column",
|
|
32412
32983
|
padding: 1,
|
|
32413
32984
|
children: [
|
|
32414
|
-
showWelcome && /* @__PURE__ */
|
|
32415
|
-
version: "0.4.
|
|
32416
|
-
model: "claude-4
|
|
32417
|
-
directory: cwd2
|
|
32985
|
+
showWelcome && /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(WelcomeBanner, {
|
|
32986
|
+
version: "0.4.1",
|
|
32987
|
+
model: "claude-sonnet-4",
|
|
32988
|
+
directory: activeSession?.cwd || cwd2
|
|
32418
32989
|
}, undefined, false, undefined, this),
|
|
32419
|
-
|
|
32420
|
-
|
|
32990
|
+
backgroundProcessingCount > 0 && /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Box_default, {
|
|
32991
|
+
marginBottom: 1,
|
|
32992
|
+
children: /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Text, {
|
|
32993
|
+
color: "yellow",
|
|
32994
|
+
children: [
|
|
32995
|
+
backgroundProcessingCount,
|
|
32996
|
+
" session",
|
|
32997
|
+
backgroundProcessingCount > 1 ? "s" : "",
|
|
32998
|
+
" processing in background (Ctrl+S to switch)"
|
|
32999
|
+
]
|
|
33000
|
+
}, undefined, true, undefined, this)
|
|
33001
|
+
}, undefined, false, undefined, this),
|
|
33002
|
+
scrollOffset > 0 && /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Box_default, {
|
|
33003
|
+
children: /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Text, {
|
|
32421
33004
|
dimColor: true,
|
|
32422
33005
|
children: [
|
|
32423
33006
|
"\u2191 ",
|
|
@@ -32426,7 +33009,7 @@ function App2({ cwd: cwd2 }) {
|
|
|
32426
33009
|
]
|
|
32427
33010
|
}, undefined, true, undefined, this)
|
|
32428
33011
|
}, undefined, false, undefined, this),
|
|
32429
|
-
/* @__PURE__ */
|
|
33012
|
+
/* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Messages4, {
|
|
32430
33013
|
messages,
|
|
32431
33014
|
currentResponse: isProcessing ? currentResponse : undefined,
|
|
32432
33015
|
currentToolCall: undefined,
|
|
@@ -32435,9 +33018,9 @@ function App2({ cwd: cwd2 }) {
|
|
|
32435
33018
|
scrollOffset,
|
|
32436
33019
|
maxVisible: maxVisibleMessages
|
|
32437
33020
|
}, undefined, false, undefined, this),
|
|
32438
|
-
isProcessing && toolCallEntries.length > 0 && /* @__PURE__ */
|
|
33021
|
+
isProcessing && toolCallEntries.length > 0 && /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Box_default, {
|
|
32439
33022
|
marginY: 1,
|
|
32440
|
-
children: /* @__PURE__ */
|
|
33023
|
+
children: /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Text, {
|
|
32441
33024
|
dimColor: true,
|
|
32442
33025
|
children: [
|
|
32443
33026
|
"\u2699 ",
|
|
@@ -32450,9 +33033,9 @@ function App2({ cwd: cwd2 }) {
|
|
|
32450
33033
|
]
|
|
32451
33034
|
}, undefined, true, undefined, this)
|
|
32452
33035
|
}, undefined, false, undefined, this),
|
|
32453
|
-
messageQueue.length > 0 && /* @__PURE__ */
|
|
33036
|
+
messageQueue.length > 0 && /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Box_default, {
|
|
32454
33037
|
marginY: 1,
|
|
32455
|
-
children: /* @__PURE__ */
|
|
33038
|
+
children: /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Text, {
|
|
32456
33039
|
dimColor: true,
|
|
32457
33040
|
children: [
|
|
32458
33041
|
messageQueue.length,
|
|
@@ -32462,9 +33045,9 @@ function App2({ cwd: cwd2 }) {
|
|
|
32462
33045
|
]
|
|
32463
33046
|
}, undefined, true, undefined, this)
|
|
32464
33047
|
}, undefined, false, undefined, this),
|
|
32465
|
-
error && /* @__PURE__ */
|
|
33048
|
+
error && /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Box_default, {
|
|
32466
33049
|
marginY: 1,
|
|
32467
|
-
children: /* @__PURE__ */
|
|
33050
|
+
children: /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Text, {
|
|
32468
33051
|
color: "red",
|
|
32469
33052
|
children: [
|
|
32470
33053
|
"Error: ",
|
|
@@ -32472,29 +33055,32 @@ function App2({ cwd: cwd2 }) {
|
|
|
32472
33055
|
]
|
|
32473
33056
|
}, undefined, true, undefined, this)
|
|
32474
33057
|
}, undefined, false, undefined, this),
|
|
32475
|
-
/* @__PURE__ */
|
|
33058
|
+
/* @__PURE__ */ jsx_dev_runtime9.jsxDEV(ProcessingIndicator, {
|
|
32476
33059
|
isProcessing,
|
|
32477
33060
|
startTime: processingStartTime,
|
|
32478
33061
|
tokenCount: currentTurnTokens,
|
|
32479
33062
|
isThinking
|
|
32480
33063
|
}, undefined, false, undefined, this),
|
|
32481
|
-
/* @__PURE__ */
|
|
33064
|
+
/* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Input, {
|
|
32482
33065
|
onSubmit: handleSubmit,
|
|
32483
33066
|
isProcessing,
|
|
32484
33067
|
queueLength: messageQueue.length
|
|
32485
33068
|
}, undefined, false, undefined, this),
|
|
32486
|
-
/* @__PURE__ */
|
|
33069
|
+
/* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Status, {
|
|
32487
33070
|
isProcessing,
|
|
32488
|
-
cwd: cwd2,
|
|
33071
|
+
cwd: activeSession?.cwd || cwd2,
|
|
32489
33072
|
queueLength: messageQueue.length,
|
|
32490
|
-
tokenUsage
|
|
33073
|
+
tokenUsage,
|
|
33074
|
+
sessionIndex,
|
|
33075
|
+
sessionCount,
|
|
33076
|
+
backgroundProcessingCount
|
|
32491
33077
|
}, undefined, false, undefined, this)
|
|
32492
33078
|
]
|
|
32493
33079
|
}, undefined, true, undefined, this);
|
|
32494
33080
|
}
|
|
32495
33081
|
|
|
32496
33082
|
// packages/terminal/src/index.tsx
|
|
32497
|
-
var
|
|
33083
|
+
var jsx_dev_runtime10 = __toESM(require_jsx_dev_runtime(), 1);
|
|
32498
33084
|
var args = process.argv.slice(2);
|
|
32499
33085
|
var options = {
|
|
32500
33086
|
cwd: process.cwd(),
|
|
@@ -32502,7 +33088,7 @@ var options = {
|
|
|
32502
33088
|
help: args.includes("--help") || args.includes("-h")
|
|
32503
33089
|
};
|
|
32504
33090
|
if (options.version) {
|
|
32505
|
-
console.log("oldpal v0.4.
|
|
33091
|
+
console.log("oldpal v0.4.1");
|
|
32506
33092
|
process.exit(0);
|
|
32507
33093
|
}
|
|
32508
33094
|
if (options.help) {
|
|
@@ -32526,11 +33112,11 @@ In interactive mode:
|
|
|
32526
33112
|
`);
|
|
32527
33113
|
process.exit(0);
|
|
32528
33114
|
}
|
|
32529
|
-
var { waitUntilExit } = render_default(/* @__PURE__ */
|
|
33115
|
+
var { waitUntilExit } = render_default(/* @__PURE__ */ jsx_dev_runtime10.jsxDEV(App2, {
|
|
32530
33116
|
cwd: options.cwd
|
|
32531
33117
|
}, undefined, false, undefined, this));
|
|
32532
33118
|
waitUntilExit().then(() => {
|
|
32533
33119
|
process.exit(0);
|
|
32534
33120
|
});
|
|
32535
33121
|
|
|
32536
|
-
//# debugId=
|
|
33122
|
+
//# debugId=E37514F436BDCDD964756E2164756E21
|