@hasna/oldpal 0.3.9 → 0.4.1

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.
@@ -18,11 +18,26 @@
18
18
  }
19
19
  },
20
20
  "connectors": [
21
- "notion",
22
- "googledrive",
21
+ "anthropic",
22
+ "brandsight",
23
+ "clickbank",
24
+ "cloudflare",
25
+ "discord",
23
26
  "gmail",
24
27
  "googlecalendar",
28
+ "googlecontacts",
29
+ "googledrive",
25
30
  "linear",
26
- "slack"
31
+ "maropost",
32
+ "mercury",
33
+ "mistral",
34
+ "notion",
35
+ "openai",
36
+ "perplexity",
37
+ "sedo",
38
+ "slack",
39
+ "x",
40
+ "xai",
41
+ "zendesk"
27
42
  ]
28
43
  }
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 homedir6 } from "os";
20454
+ import { homedir as homedir7 } from "os";
20455
20455
  import { join as join7 } from "path";
20456
20456
  function loadApiKeyFromSecrets() {
20457
- const secretsPath = join7(homedir6(), ".secrets");
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
@@ -28788,36 +28807,37 @@ import { join } from "path";
28788
28807
 
28789
28808
  class ConnectorBridge {
28790
28809
  connectors = new Map;
28810
+ static cache = new Map;
28791
28811
  async discover(connectorNames) {
28792
- const names = connectorNames || [
28793
- "notion",
28794
- "googledrive",
28795
- "gmail",
28796
- "googlecalendar",
28797
- "googlecontacts",
28798
- "linear",
28799
- "slack",
28800
- "discord",
28801
- "github",
28802
- "x",
28803
- "exa",
28804
- "anthropic",
28805
- "openai",
28806
- "elevenlabs"
28807
- ];
28808
- const results = await Promise.all(names.map(async (name) => {
28809
- const cli = `connect-${name}`;
28810
- try {
28811
- const result = await Bun.$`which ${cli}`.quiet().nothrow();
28812
- if (result.exitCode !== 0)
28812
+ const names = connectorNames || [];
28813
+ if (names.length === 0) {
28814
+ return [];
28815
+ }
28816
+ const uncached = names.filter((n) => !ConnectorBridge.cache.has(n));
28817
+ if (uncached.length > 0) {
28818
+ const results = await Promise.all(uncached.map(async (name) => {
28819
+ const cli = `connect-${name}`;
28820
+ try {
28821
+ const result = await Promise.race([
28822
+ Bun.$`which ${cli}`.quiet().nothrow(),
28823
+ new Promise((_, reject) => setTimeout(() => reject(new Error("timeout")), 500))
28824
+ ]);
28825
+ if (result.exitCode !== 0) {
28826
+ ConnectorBridge.cache.set(name, null);
28827
+ return null;
28828
+ }
28829
+ const connector = this.createMinimalConnector(name, cli);
28830
+ ConnectorBridge.cache.set(name, connector);
28831
+ return connector;
28832
+ } catch {
28833
+ ConnectorBridge.cache.set(name, null);
28813
28834
  return null;
28814
- } catch {
28815
- return null;
28816
- }
28817
- return this.discoverConnector(name, cli);
28818
- }));
28835
+ }
28836
+ }));
28837
+ }
28819
28838
  const discovered = [];
28820
- for (const connector of results) {
28839
+ for (const name of names) {
28840
+ const connector = ConnectorBridge.cache.get(name);
28821
28841
  if (connector) {
28822
28842
  discovered.push(connector);
28823
28843
  this.connectors.set(connector.name, connector);
@@ -28825,6 +28845,20 @@ class ConnectorBridge {
28825
28845
  }
28826
28846
  return discovered;
28827
28847
  }
28848
+ createMinimalConnector(name, cli) {
28849
+ return {
28850
+ name,
28851
+ cli,
28852
+ description: `${name} connector`,
28853
+ commands: [
28854
+ { name: "help", description: "Show available commands", args: [], options: [] }
28855
+ ],
28856
+ auth: {
28857
+ type: "oauth2",
28858
+ statusCommand: `${cli} auth status`
28859
+ }
28860
+ };
28861
+ }
28828
28862
  async discoverConnector(name, cli) {
28829
28863
  try {
28830
28864
  const helpResult = await Bun.$`${cli} --help`.quiet();
@@ -28958,13 +28992,13 @@ class ConnectorBridge {
28958
28992
  class BashTool {
28959
28993
  static tool = {
28960
28994
  name: "bash",
28961
- description: "Execute a shell command. Use for system operations, running scripts, git commands, etc.",
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.",
28962
28996
  parameters: {
28963
28997
  type: "object",
28964
28998
  properties: {
28965
28999
  command: {
28966
29000
  type: "string",
28967
- description: "The shell command to execute"
29001
+ description: "The shell command to execute (read-only commands only)"
28968
29002
  },
28969
29003
  cwd: {
28970
29004
  type: "string",
@@ -28972,29 +29006,111 @@ class BashTool {
28972
29006
  },
28973
29007
  timeout: {
28974
29008
  type: "number",
28975
- description: "Timeout in milliseconds (default: 120000)"
29009
+ description: "Timeout in milliseconds (default: 30000)"
28976
29010
  }
28977
29011
  },
28978
29012
  required: ["command"]
28979
29013
  }
28980
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
+ ];
28981
29100
  static executor = async (input) => {
28982
29101
  const command = input.command;
28983
29102
  const cwd2 = input.cwd || process.cwd();
28984
- const timeout = input.timeout || 120000;
28985
- const dangerousPatterns = [
28986
- /rm\s+-rf\s+[\/~]/i,
28987
- /rm\s+-rf\s+\*/i,
28988
- /mkfs/i,
28989
- /dd\s+if=/i,
28990
- />\s*\/dev\/sd/i,
28991
- /chmod\s+-R\s+777\s+\//i
28992
- ];
28993
- for (const pattern of dangerousPatterns) {
29103
+ const timeout = input.timeout || 30000;
29104
+ for (const pattern of this.BLOCKED_PATTERNS) {
28994
29105
  if (pattern.test(command)) {
28995
- return `Error: This command appears dangerous and was blocked for safety.`;
29106
+ return `Error: This command is not allowed. Only read-only commands are permitted (ls, cat, grep, find, git status/log/diff, etc.)`;
28996
29107
  }
28997
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
+ }
28998
29114
  try {
28999
29115
  const proc = Bun.spawn(["bash", "-c", command], {
29000
29116
  cwd: cwd2,
@@ -29023,15 +29139,31 @@ ${stderr || stdout}`.trim();
29023
29139
 
29024
29140
  // packages/core/src/tools/filesystem.ts
29025
29141
  import { join as join2, resolve, dirname } from "path";
29142
+ import { homedir as homedir2 } from "os";
29026
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
+ }
29027
29153
 
29028
29154
  class FilesystemTools {
29029
- static registerAll(registry) {
29155
+ static registerAll(registry, sessionId) {
29156
+ if (sessionId) {
29157
+ currentSessionId = sessionId;
29158
+ }
29030
29159
  registry.register(this.readTool, this.readExecutor);
29031
29160
  registry.register(this.writeTool, this.writeExecutor);
29032
29161
  registry.register(this.globTool, this.globExecutor);
29033
29162
  registry.register(this.grepTool, this.grepExecutor);
29034
29163
  }
29164
+ static setSessionId(sessionId) {
29165
+ currentSessionId = sessionId;
29166
+ }
29035
29167
  static readTool = {
29036
29168
  name: "read",
29037
29169
  description: "Read the contents of a file",
@@ -29078,30 +29210,38 @@ class FilesystemTools {
29078
29210
  };
29079
29211
  static writeTool = {
29080
29212
  name: "write",
29081
- description: "Write content to a file (creates or overwrites)",
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.",
29082
29214
  parameters: {
29083
29215
  type: "object",
29084
29216
  properties: {
29085
- path: {
29217
+ filename: {
29086
29218
  type: "string",
29087
- description: "The file path to write to"
29219
+ description: "The filename to write to (will be saved in temp folder)"
29088
29220
  },
29089
29221
  content: {
29090
29222
  type: "string",
29091
29223
  description: "The content to write"
29092
29224
  }
29093
29225
  },
29094
- required: ["path", "content"]
29226
+ required: ["filename", "content"]
29095
29227
  }
29096
29228
  };
29097
29229
  static writeExecutor = async (input) => {
29098
- const path = resolve(process.cwd(), input.path);
29230
+ const filename = input.filename || input.path;
29099
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
+ }
29100
29238
  try {
29101
29239
  const dir = dirname(path);
29102
29240
  await Bun.$`mkdir -p ${dir}`.quiet();
29103
29241
  await Bun.write(path, content);
29104
- 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.`;
29105
29245
  } catch (error) {
29106
29246
  return `Error: ${error instanceof Error ? error.message : String(error)}`;
29107
29247
  }
@@ -29491,11 +29631,11 @@ class WebTools {
29491
29631
  import { existsSync as existsSync2, writeFileSync, unlinkSync } from "fs";
29492
29632
  import { tmpdir } from "os";
29493
29633
  import { join as join3 } from "path";
29494
- import { homedir as homedir2 } from "os";
29634
+ import { homedir as homedir3 } from "os";
29495
29635
  async function getViuPath() {
29496
29636
  const locations = [
29497
29637
  "viu",
29498
- join3(homedir2(), ".cargo", "bin", "viu"),
29638
+ join3(homedir3(), ".cargo", "bin", "viu"),
29499
29639
  "/usr/local/bin/viu",
29500
29640
  "/opt/homebrew/bin/viu"
29501
29641
  ];
@@ -29606,12 +29746,12 @@ class ImageTools {
29606
29746
 
29607
29747
  // packages/core/src/skills/loader.ts
29608
29748
  import { join as join4 } from "path";
29609
- import { homedir as homedir3 } from "os";
29749
+ import { homedir as homedir4 } from "os";
29610
29750
  var {Glob: Glob2 } = globalThis.Bun;
29611
29751
  class SkillLoader {
29612
29752
  skills = new Map;
29613
29753
  async loadAll(projectDir = process.cwd()) {
29614
- const userSkillsDir = join4(homedir3(), ".oldpal", "skills");
29754
+ const userSkillsDir = join4(homedir4(), ".oldpal", "skills");
29615
29755
  await this.loadFromDirectory(userSkillsDir);
29616
29756
  const projectSkillsDir = join4(projectDir, ".oldpal", "skills");
29617
29757
  await this.loadFromDirectory(projectSkillsDir);
@@ -29906,7 +30046,7 @@ class HookExecutor {
29906
30046
  // packages/core/src/commands/loader.ts
29907
30047
  import { existsSync as existsSync3, readdirSync, statSync } from "fs";
29908
30048
  import { join as join5, basename, extname } from "path";
29909
- import { homedir as homedir4 } from "os";
30049
+ import { homedir as homedir5 } from "os";
29910
30050
 
29911
30051
  class CommandLoader {
29912
30052
  commands = new Map;
@@ -29916,7 +30056,7 @@ class CommandLoader {
29916
30056
  }
29917
30057
  async loadAll() {
29918
30058
  this.commands.clear();
29919
- const globalDir = join5(homedir4(), ".oldpal", "commands");
30059
+ const globalDir = join5(homedir5(), ".oldpal", "commands");
29920
30060
  await this.loadFromDirectory(globalDir, "global");
29921
30061
  const projectDir = join5(this.cwd, ".oldpal", "commands");
29922
30062
  await this.loadFromDirectory(projectDir, "project");
@@ -30105,7 +30245,7 @@ ${stderr}`;
30105
30245
  }
30106
30246
  // packages/core/src/commands/builtin.ts
30107
30247
  import { join as join6 } from "path";
30108
- import { homedir as homedir5 } from "os";
30248
+ import { homedir as homedir6 } from "os";
30109
30249
  import { existsSync as existsSync4, mkdirSync, writeFileSync as writeFileSync2 } from "fs";
30110
30250
 
30111
30251
  class BuiltinCommands {
@@ -30392,7 +30532,7 @@ Format the summary as a brief bullet-point list. This summary will replace the c
30392
30532
  handler: async (args, context) => {
30393
30533
  const configPaths = [
30394
30534
  join6(context.cwd, ".oldpal", "config.json"),
30395
- join6(homedir5(), ".oldpal", "config.json")
30535
+ join6(homedir6(), ".oldpal", "config.json")
30396
30536
  ];
30397
30537
  let message = `
30398
30538
  **Configuration**
@@ -30410,7 +30550,7 @@ Format the summary as a brief bullet-point list. This summary will replace the c
30410
30550
  `;
30411
30551
  message += ` - Project: ${join6(context.cwd, ".oldpal", "commands")}
30412
30552
  `;
30413
- message += ` - Global: ${join6(homedir5(), ".oldpal", "commands")}
30553
+ message += ` - Global: ${join6(homedir6(), ".oldpal", "commands")}
30414
30554
  `;
30415
30555
  context.emit("text", message);
30416
30556
  context.emit("done");
@@ -30534,11 +30674,11 @@ Cache savings: ~$${cacheSavings.toFixed(4)}
30534
30674
  **Model Information**
30535
30675
 
30536
30676
  `;
30537
- message += `Current model: claude-3-5-sonnet-20241022
30677
+ message += `Current model: claude-sonnet-4-20250514 (Claude 4 Sonnet)
30538
30678
  `;
30539
30679
  message += `Context window: 200,000 tokens
30540
30680
  `;
30541
- message += `Max output: 8,192 tokens
30681
+ message += `Max output: 64,000 tokens
30542
30682
 
30543
30683
  `;
30544
30684
  message += `*Model selection coming in a future update*
@@ -30632,7 +30772,7 @@ async function createLLMClient(config) {
30632
30772
 
30633
30773
  // packages/core/src/config.ts
30634
30774
  import { join as join8 } from "path";
30635
- import { homedir as homedir7 } from "os";
30775
+ import { homedir as homedir8 } from "os";
30636
30776
  var DEFAULT_CONFIG = {
30637
30777
  llm: {
30638
30778
  provider: "anthropic",
@@ -30662,7 +30802,7 @@ var DEFAULT_CONFIG = {
30662
30802
  ]
30663
30803
  };
30664
30804
  function getConfigDir() {
30665
- return join8(homedir7(), ".oldpal");
30805
+ return join8(homedir8(), ".oldpal");
30666
30806
  }
30667
30807
  function getConfigPath(filename) {
30668
30808
  return join8(getConfigDir(), filename);
@@ -30734,14 +30874,19 @@ async function loadJsonFile(path) {
30734
30874
  return null;
30735
30875
  }
30736
30876
  }
30737
- async function ensureConfigDir() {
30877
+ async function ensureConfigDir(sessionId) {
30738
30878
  const { mkdir } = await import("fs/promises");
30739
30879
  const configDir = getConfigDir();
30740
- await Promise.all([
30880
+ const dirs = [
30741
30881
  mkdir(configDir, { recursive: true }),
30742
30882
  mkdir(join8(configDir, "sessions"), { recursive: true }),
30743
- mkdir(join8(configDir, "skills"), { recursive: true })
30744
- ]);
30883
+ mkdir(join8(configDir, "skills"), { recursive: true }),
30884
+ mkdir(join8(configDir, "temp"), { recursive: true })
30885
+ ];
30886
+ if (sessionId) {
30887
+ dirs.push(mkdir(join8(configDir, "temp", sessionId), { recursive: true }));
30888
+ }
30889
+ await Promise.all(dirs);
30745
30890
  }
30746
30891
  async function loadSystemPrompt(cwd2 = process.cwd()) {
30747
30892
  const prompts = [];
@@ -30819,7 +30964,7 @@ class AgentLoop {
30819
30964
  async initialize() {
30820
30965
  const [config] = await Promise.all([
30821
30966
  loadConfig(this.cwd),
30822
- ensureConfigDir()
30967
+ ensureConfigDir(this.sessionId)
30823
30968
  ]);
30824
30969
  this.config = config;
30825
30970
  const [, , , hooksConfig, systemPrompt] = await Promise.all([
@@ -30833,7 +30978,7 @@ class AgentLoop {
30833
30978
  this.commandLoader.loadAll()
30834
30979
  ]);
30835
30980
  this.toolRegistry.register(BashTool.tool, BashTool.executor);
30836
- FilesystemTools.registerAll(this.toolRegistry);
30981
+ FilesystemTools.registerAll(this.toolRegistry, this.sessionId);
30837
30982
  WebTools.registerAll(this.toolRegistry);
30838
30983
  ImageTools.registerAll(this.toolRegistry);
30839
30984
  this.connectorBridge.registerAll(this.toolRegistry);
@@ -31045,7 +31190,7 @@ init_anthropic();
31045
31190
  // packages/core/src/logger.ts
31046
31191
  import { existsSync as existsSync6, mkdirSync as mkdirSync2, appendFileSync } from "fs";
31047
31192
  import { join as join9 } from "path";
31048
- import { homedir as homedir8 } from "os";
31193
+ import { homedir as homedir9 } from "os";
31049
31194
 
31050
31195
  class Logger {
31051
31196
  logDir;
@@ -31053,7 +31198,7 @@ class Logger {
31053
31198
  sessionId;
31054
31199
  constructor(sessionId) {
31055
31200
  this.sessionId = sessionId;
31056
- this.logDir = join9(homedir8(), ".oldpal", "logs");
31201
+ this.logDir = join9(homedir9(), ".oldpal", "logs");
31057
31202
  this.ensureDir(this.logDir);
31058
31203
  const date = new Date().toISOString().split("T")[0];
31059
31204
  this.logFile = join9(this.logDir, `${date}.log`);
@@ -31099,7 +31244,7 @@ class SessionStorage {
31099
31244
  sessionId;
31100
31245
  constructor(sessionId) {
31101
31246
  this.sessionId = sessionId;
31102
- this.sessionsDir = join9(homedir8(), ".oldpal", "sessions");
31247
+ this.sessionsDir = join9(homedir9(), ".oldpal", "sessions");
31103
31248
  this.ensureDir(this.sessionsDir);
31104
31249
  this.sessionFile = join9(this.sessionsDir, `${sessionId}.json`);
31105
31250
  }
@@ -31118,7 +31263,7 @@ class SessionStorage {
31118
31263
  }
31119
31264
  }
31120
31265
  function initOldpalDir() {
31121
- const baseDir = join9(homedir8(), ".oldpal");
31266
+ const baseDir = join9(homedir9(), ".oldpal");
31122
31267
  const dirs = [
31123
31268
  baseDir,
31124
31269
  join9(baseDir, "sessions"),
@@ -31564,19 +31709,28 @@ function Messages4({
31564
31709
  const startIndex = Math.max(0, endIndex - maxVisible);
31565
31710
  const visibleMessages = messages.slice(startIndex, endIndex);
31566
31711
  const groupedMessages = groupConsecutiveToolMessages(visibleMessages);
31712
+ const historicalItems = groupedMessages.map((group) => {
31713
+ if (group.type === "single") {
31714
+ return { id: group.message.id, group };
31715
+ }
31716
+ return { id: group.messages[0].id, group };
31717
+ });
31567
31718
  return /* @__PURE__ */ jsx_dev_runtime3.jsxDEV(Box_default, {
31568
31719
  flexDirection: "column",
31569
31720
  children: [
31570
- groupedMessages.map((group) => {
31571
- if (group.type === "single") {
31572
- return /* @__PURE__ */ jsx_dev_runtime3.jsxDEV(MessageBubble, {
31573
- message: group.message
31574
- }, group.message.id, false, undefined, this);
31575
- }
31576
- return /* @__PURE__ */ jsx_dev_runtime3.jsxDEV(CombinedToolMessage, {
31577
- messages: group.messages
31578
- }, group.messages[0].id, false, undefined, this);
31579
- }),
31721
+ /* @__PURE__ */ jsx_dev_runtime3.jsxDEV(Static, {
31722
+ items: historicalItems,
31723
+ children: (item) => {
31724
+ if (item.group.type === "single") {
31725
+ return /* @__PURE__ */ jsx_dev_runtime3.jsxDEV(MessageBubble, {
31726
+ message: item.group.message
31727
+ }, item.id, false, undefined, this);
31728
+ }
31729
+ return /* @__PURE__ */ jsx_dev_runtime3.jsxDEV(CombinedToolMessage, {
31730
+ messages: item.group.messages
31731
+ }, item.id, false, undefined, this);
31732
+ }
31733
+ }, undefined, false, undefined, this),
31580
31734
  activityLog.map((entry) => {
31581
31735
  if (entry.type === "text" && entry.content) {
31582
31736
  return /* @__PURE__ */ jsx_dev_runtime3.jsxDEV(Box_default, {
@@ -32397,8 +32551,8 @@ function App2({ cwd: cwd2 }) {
32397
32551
  padding: 1,
32398
32552
  children: [
32399
32553
  showWelcome && /* @__PURE__ */ jsx_dev_runtime8.jsxDEV(WelcomeBanner, {
32400
- version: "0.3.9",
32401
- model: "claude-sonnet-4-20250514",
32554
+ version: "0.4.1",
32555
+ model: "claude-sonnet-4",
32402
32556
  directory: cwd2
32403
32557
  }, undefined, false, undefined, this),
32404
32558
  scrollOffset > 0 && /* @__PURE__ */ jsx_dev_runtime8.jsxDEV(Box_default, {
@@ -32487,7 +32641,7 @@ var options = {
32487
32641
  help: args.includes("--help") || args.includes("-h")
32488
32642
  };
32489
32643
  if (options.version) {
32490
- console.log("oldpal v0.3.9");
32644
+ console.log("oldpal v0.4.1");
32491
32645
  process.exit(0);
32492
32646
  }
32493
32647
  if (options.help) {
@@ -32518,4 +32672,4 @@ waitUntilExit().then(() => {
32518
32672
  process.exit(0);
32519
32673
  });
32520
32674
 
32521
- //# debugId=4B7AD4CD51004C7264756E2164756E21
32675
+ //# debugId=165DC707B2BFFF8564756E2164756E21