@hasna/oldpal 0.5.4 → 0.6.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -17702,7 +17702,7 @@ var require_stack_utils = __commonJS((exports, module) => {
17702
17702
  });
17703
17703
 
17704
17704
  // node_modules/.bun/@anthropic-ai+sdk@0.32.1/node_modules/@anthropic-ai/sdk/version.mjs
17705
- var VERSION = "0.32.1";
17705
+ var VERSION2 = "0.32.1";
17706
17706
 
17707
17707
  // node_modules/.bun/@anthropic-ai+sdk@0.32.1/node_modules/@anthropic-ai/sdk/_shims/registry.mjs
17708
17708
  function setShims(shims, options = { auto: false }) {
@@ -18651,7 +18651,7 @@ class APIClient {
18651
18651
  return sleepSeconds * jitter * 1000;
18652
18652
  }
18653
18653
  getUserAgent() {
18654
- return `${this.constructor.name}/JS ${VERSION}`;
18654
+ return `${this.constructor.name}/JS ${VERSION2}`;
18655
18655
  }
18656
18656
  }
18657
18657
  function getBrowserInfo() {
@@ -18734,7 +18734,7 @@ var __classPrivateFieldSet = function(receiver, state, value, kind2, f) {
18734
18734
  if (typeof Deno !== "undefined" && Deno.build != null) {
18735
18735
  return {
18736
18736
  "X-Stainless-Lang": "js",
18737
- "X-Stainless-Package-Version": VERSION,
18737
+ "X-Stainless-Package-Version": VERSION2,
18738
18738
  "X-Stainless-OS": normalizePlatform(Deno.build.os),
18739
18739
  "X-Stainless-Arch": normalizeArch(Deno.build.arch),
18740
18740
  "X-Stainless-Runtime": "deno",
@@ -18744,7 +18744,7 @@ var __classPrivateFieldSet = function(receiver, state, value, kind2, f) {
18744
18744
  if (typeof EdgeRuntime !== "undefined") {
18745
18745
  return {
18746
18746
  "X-Stainless-Lang": "js",
18747
- "X-Stainless-Package-Version": VERSION,
18747
+ "X-Stainless-Package-Version": VERSION2,
18748
18748
  "X-Stainless-OS": "Unknown",
18749
18749
  "X-Stainless-Arch": `other:${EdgeRuntime}`,
18750
18750
  "X-Stainless-Runtime": "edge",
@@ -18754,7 +18754,7 @@ var __classPrivateFieldSet = function(receiver, state, value, kind2, f) {
18754
18754
  if (Object.prototype.toString.call(typeof process !== "undefined" ? process : 0) === "[object process]") {
18755
18755
  return {
18756
18756
  "X-Stainless-Lang": "js",
18757
- "X-Stainless-Package-Version": VERSION,
18757
+ "X-Stainless-Package-Version": VERSION2,
18758
18758
  "X-Stainless-OS": normalizePlatform(process.platform),
18759
18759
  "X-Stainless-Arch": normalizeArch(process.arch),
18760
18760
  "X-Stainless-Runtime": "node",
@@ -18765,7 +18765,7 @@ var __classPrivateFieldSet = function(receiver, state, value, kind2, f) {
18765
18765
  if (browserInfo) {
18766
18766
  return {
18767
18767
  "X-Stainless-Lang": "js",
18768
- "X-Stainless-Package-Version": VERSION,
18768
+ "X-Stainless-Package-Version": VERSION2,
18769
18769
  "X-Stainless-OS": "Unknown",
18770
18770
  "X-Stainless-Arch": "unknown",
18771
18771
  "X-Stainless-Runtime": `browser:${browserInfo.browser}`,
@@ -18774,42 +18774,42 @@ var __classPrivateFieldSet = function(receiver, state, value, kind2, f) {
18774
18774
  }
18775
18775
  return {
18776
18776
  "X-Stainless-Lang": "js",
18777
- "X-Stainless-Package-Version": VERSION,
18777
+ "X-Stainless-Package-Version": VERSION2,
18778
18778
  "X-Stainless-OS": "Unknown",
18779
18779
  "X-Stainless-Arch": "unknown",
18780
18780
  "X-Stainless-Runtime": "unknown",
18781
18781
  "X-Stainless-Runtime-Version": "unknown"
18782
18782
  };
18783
- }, normalizeArch = (arch) => {
18784
- if (arch === "x32")
18783
+ }, normalizeArch = (arch2) => {
18784
+ if (arch2 === "x32")
18785
18785
  return "x32";
18786
- if (arch === "x86_64" || arch === "x64")
18786
+ if (arch2 === "x86_64" || arch2 === "x64")
18787
18787
  return "x64";
18788
- if (arch === "arm")
18788
+ if (arch2 === "arm")
18789
18789
  return "arm";
18790
- if (arch === "aarch64" || arch === "arm64")
18790
+ if (arch2 === "aarch64" || arch2 === "arm64")
18791
18791
  return "arm64";
18792
- if (arch)
18793
- return `other:${arch}`;
18792
+ if (arch2)
18793
+ return `other:${arch2}`;
18794
18794
  return "unknown";
18795
- }, normalizePlatform = (platform2) => {
18796
- platform2 = platform2.toLowerCase();
18797
- if (platform2.includes("ios"))
18795
+ }, normalizePlatform = (platform3) => {
18796
+ platform3 = platform3.toLowerCase();
18797
+ if (platform3.includes("ios"))
18798
18798
  return "iOS";
18799
- if (platform2 === "android")
18799
+ if (platform3 === "android")
18800
18800
  return "Android";
18801
- if (platform2 === "darwin")
18801
+ if (platform3 === "darwin")
18802
18802
  return "MacOS";
18803
- if (platform2 === "win32")
18803
+ if (platform3 === "win32")
18804
18804
  return "Windows";
18805
- if (platform2 === "freebsd")
18805
+ if (platform3 === "freebsd")
18806
18806
  return "FreeBSD";
18807
- if (platform2 === "openbsd")
18807
+ if (platform3 === "openbsd")
18808
18808
  return "OpenBSD";
18809
- if (platform2 === "linux")
18809
+ if (platform3 === "linux")
18810
18810
  return "Linux";
18811
- if (platform2)
18812
- return `Other:${platform2}`;
18811
+ if (platform3)
18812
+ return `Other:${platform3}`;
18813
18813
  return "Unknown";
18814
18814
  }, _platformHeaders, getPlatformHeaders = () => {
18815
18815
  return _platformHeaders ?? (_platformHeaders = getPlatformProperties());
@@ -20530,10 +20530,34 @@ class AnthropicClient {
20530
20530
  currentToolCall = null;
20531
20531
  toolInputJson = "";
20532
20532
  }
20533
+ } else if (event.type === "message_delta") {
20534
+ if (event.usage) {
20535
+ yield {
20536
+ type: "usage",
20537
+ usage: {
20538
+ inputTokens: 0,
20539
+ outputTokens: event.usage.output_tokens || 0,
20540
+ totalTokens: event.usage.output_tokens || 0,
20541
+ maxContextTokens: 200000
20542
+ }
20543
+ };
20544
+ }
20533
20545
  } else if (event.type === "message_stop") {
20534
20546
  yield { type: "done" };
20535
20547
  }
20536
20548
  }
20549
+ const finalMessage = await stream.finalMessage();
20550
+ if (finalMessage.usage) {
20551
+ yield {
20552
+ type: "usage",
20553
+ usage: {
20554
+ inputTokens: finalMessage.usage.input_tokens,
20555
+ outputTokens: finalMessage.usage.output_tokens,
20556
+ totalTokens: finalMessage.usage.input_tokens + finalMessage.usage.output_tokens,
20557
+ maxContextTokens: 200000
20558
+ }
20559
+ };
20560
+ }
20537
20561
  } catch (error) {
20538
20562
  yield {
20539
20563
  type: "error",
@@ -29316,7 +29340,7 @@ You can review and copy this file to your project if needed.`;
29316
29340
  const globPattern = input.glob || "**/*";
29317
29341
  const caseSensitive = input.caseSensitive || false;
29318
29342
  try {
29319
- const flags = caseSensitive ? "g" : "gi";
29343
+ const flags = caseSensitive ? "" : "i";
29320
29344
  const regex2 = new RegExp(pattern, flags);
29321
29345
  const results = [];
29322
29346
  const glob = new Glob(globPattern);
@@ -29868,7 +29892,7 @@ ARGUMENTS: ${args.join(" ")}`;
29868
29892
  const fullMatch = match[0];
29869
29893
  const command = match[1];
29870
29894
  try {
29871
- const fullCommand = `cd ${skillDir} && ${command}`;
29895
+ const fullCommand = `cd "${skillDir}" && ${command}`;
29872
29896
  const output = await Bun.$`sh -c ${fullCommand}`.quiet().text();
29873
29897
  result = result.replace(fullMatch, output.trim());
29874
29898
  } catch (error) {
@@ -30246,8 +30270,9 @@ ${stderr}`;
30246
30270
  }
30247
30271
  // packages/core/src/commands/builtin.ts
30248
30272
  import { join as join6 } from "path";
30249
- import { homedir as homedir6 } from "os";
30273
+ import { homedir as homedir6, platform as platform2, release, arch } from "os";
30250
30274
  import { existsSync as existsSync4, mkdirSync, writeFileSync as writeFileSync2 } from "fs";
30275
+ var VERSION = "0.6.2";
30251
30276
 
30252
30277
  class BuiltinCommands {
30253
30278
  tokenUsage = {
@@ -30273,6 +30298,7 @@ class BuiltinCommands {
30273
30298
  loader.register(this.bugCommand());
30274
30299
  loader.register(this.prCommand());
30275
30300
  loader.register(this.reviewCommand());
30301
+ loader.register(this.feedbackCommand());
30276
30302
  loader.register(this.exitCommand());
30277
30303
  }
30278
30304
  updateTokenUsage(usage) {
@@ -30450,33 +30476,25 @@ class BuiltinCommands {
30450
30476
  **Available Skills**
30451
30477
 
30452
30478
  `;
30453
- message += `Skills are invoked with /skill-name [arguments]
30479
+ message += `Skills are invoked with $skill-name [arguments] or /skill-name [arguments]
30454
30480
 
30455
30481
  `;
30456
- message += `**Built-in Skills:**
30457
- `;
30458
- message += ` /brainstorm - Generate ideas on a topic
30459
- `;
30460
- message += ` /draft - Draft content (emails, docs, etc.)
30482
+ if (context.skills.length === 0) {
30483
+ message += `No skills loaded.
30461
30484
  `;
30462
- message += ` /research - Research a topic
30463
- `;
30464
- message += ` /summarize - Summarize text or content
30465
- `;
30466
- message += `
30467
- **Connector Skills:**
30468
- `;
30469
- message += ` /calendar - Manage calendar events
30470
- `;
30471
- message += ` /email - Read and send emails
30472
- `;
30473
- message += ` /notes - Manage notes (Notion)
30485
+ message += `
30486
+ Add skills to ~/.oldpal/skills/ or .oldpal/skills/
30474
30487
  `;
30475
- message += ` /search - Search the web
30488
+ } else {
30489
+ for (const skill of context.skills) {
30490
+ const hint = skill.argumentHint ? ` ${skill.argumentHint}` : "";
30491
+ message += ` $${skill.name}${hint} - ${skill.description}
30476
30492
  `;
30477
- message += `
30478
- Custom skills can be added in .oldpal/skills/
30493
+ }
30494
+ message += `
30495
+ ${context.skills.length} skill(s) available.
30479
30496
  `;
30497
+ }
30480
30498
  context.emit("text", message);
30481
30499
  context.emit("done");
30482
30500
  return { handled: true };
@@ -30785,6 +30803,130 @@ Check for:
30785
30803
  If there are staged changes, review those. Otherwise, ask what to review.`
30786
30804
  };
30787
30805
  }
30806
+ feedbackCommand() {
30807
+ return {
30808
+ name: "feedback",
30809
+ description: "Submit feedback or report an issue on GitHub",
30810
+ builtin: true,
30811
+ selfHandled: true,
30812
+ content: "",
30813
+ handler: async (args, context) => {
30814
+ const feedbackType = args.trim().toLowerCase();
30815
+ const systemInfo = {
30816
+ version: VERSION,
30817
+ platform: platform2(),
30818
+ release: release(),
30819
+ arch: arch(),
30820
+ nodeVersion: process.version,
30821
+ bunVersion: typeof Bun !== "undefined" ? Bun.version : "N/A"
30822
+ };
30823
+ const repoUrl = "https://github.com/hasna/oldpal";
30824
+ const issueBody = `## Description
30825
+
30826
+ <!-- Describe the issue or feedback here -->
30827
+
30828
+ ## Steps to Reproduce (if bug)
30829
+
30830
+ 1.
30831
+ 2.
30832
+ 3.
30833
+
30834
+ ## Expected Behavior
30835
+
30836
+ <!-- What did you expect to happen? -->
30837
+
30838
+ ## Actual Behavior
30839
+
30840
+ <!-- What actually happened? -->
30841
+
30842
+ ## System Information
30843
+
30844
+ - **oldpal version**: ${systemInfo.version}
30845
+ - **Platform**: ${systemInfo.platform} ${systemInfo.release} (${systemInfo.arch})
30846
+ - **Bun version**: ${systemInfo.bunVersion}
30847
+ - **Node version**: ${systemInfo.nodeVersion}
30848
+
30849
+ ## Additional Context
30850
+
30851
+ <!-- Add any other context about the problem here -->
30852
+ `;
30853
+ let issueTitle = "";
30854
+ let labels = "";
30855
+ if (feedbackType === "bug" || feedbackType === "issue") {
30856
+ issueTitle = "[Bug] ";
30857
+ labels = "bug";
30858
+ } else if (feedbackType === "feature" || feedbackType === "request") {
30859
+ issueTitle = "[Feature Request] ";
30860
+ labels = "enhancement";
30861
+ } else {
30862
+ issueTitle = "[Feedback] ";
30863
+ labels = "feedback";
30864
+ }
30865
+ const issueUrl = new URL(`${repoUrl}/issues/new`);
30866
+ issueUrl.searchParams.set("title", issueTitle);
30867
+ issueUrl.searchParams.set("body", issueBody);
30868
+ if (labels) {
30869
+ issueUrl.searchParams.set("labels", labels);
30870
+ }
30871
+ let finalUrl = issueUrl.toString();
30872
+ if (finalUrl.length > 8000) {
30873
+ const shortBody = `## Description
30874
+
30875
+ <!-- Describe the issue or feedback here -->
30876
+
30877
+ ## System Information
30878
+
30879
+ - **oldpal version**: ${systemInfo.version}
30880
+ - **Platform**: ${systemInfo.platform} (${systemInfo.arch})
30881
+ - **Bun version**: ${systemInfo.bunVersion}
30882
+ `;
30883
+ const shortUrl = new URL(`${repoUrl}/issues/new`);
30884
+ shortUrl.searchParams.set("title", issueTitle);
30885
+ shortUrl.searchParams.set("body", shortBody);
30886
+ if (labels) {
30887
+ shortUrl.searchParams.set("labels", labels);
30888
+ }
30889
+ finalUrl = shortUrl.toString();
30890
+ }
30891
+ try {
30892
+ const openCmd = platform2() === "darwin" ? "open" : platform2() === "win32" ? "start" : "xdg-open";
30893
+ await Bun.$`${openCmd} ${finalUrl}`.quiet();
30894
+ let message = `
30895
+ **Opening GitHub to submit feedback...**
30896
+
30897
+ `;
30898
+ message += `A browser window should open with a pre-filled issue template.
30899
+ `;
30900
+ message += `Please fill in the details and submit.
30901
+
30902
+ `;
30903
+ message += `If the browser doesn't open, visit:
30904
+ ${repoUrl}/issues/new
30905
+ `;
30906
+ context.emit("text", message);
30907
+ } catch {
30908
+ let message = `
30909
+ **Submit Feedback**
30910
+
30911
+ `;
30912
+ message += `Please visit: ${repoUrl}/issues/new
30913
+
30914
+ `;
30915
+ message += `**System Information:**
30916
+ `;
30917
+ message += `- oldpal version: ${systemInfo.version}
30918
+ `;
30919
+ message += `- Platform: ${systemInfo.platform} ${systemInfo.release}
30920
+ `;
30921
+ message += `- Bun version: ${systemInfo.bunVersion}
30922
+ `;
30923
+ context.emit("text", message);
30924
+ }
30925
+ context.emit("done");
30926
+ return { handled: true };
30927
+ }
30928
+ };
30929
+ }
30788
30930
  }
30789
30931
  // packages/core/src/llm/client.ts
30790
30932
  async function createLLMClient(config) {
@@ -30964,6 +31106,7 @@ class AgentLoop {
30964
31106
  sessionId;
30965
31107
  isRunning = false;
30966
31108
  shouldStop = false;
31109
+ systemPrompt = null;
30967
31110
  onChunk;
30968
31111
  onToolStart;
30969
31112
  onToolEnd;
@@ -31010,6 +31153,7 @@ class AgentLoop {
31010
31153
  this.builtinCommands.registerAll(this.commandLoader);
31011
31154
  this.hookLoader.load(hooksConfig);
31012
31155
  if (systemPrompt) {
31156
+ this.systemPrompt = systemPrompt;
31013
31157
  this.context.addSystemMessage(systemPrompt);
31014
31158
  }
31015
31159
  await this.hookExecutor.execute(this.hookLoader.getHooks("SessionStart"), {
@@ -31043,6 +31187,9 @@ class AgentLoop {
31043
31187
  if (commandResult.handled) {
31044
31188
  if (commandResult.clearConversation) {
31045
31189
  this.context = new AgentContext;
31190
+ if (this.systemPrompt) {
31191
+ this.context.addSystemMessage(this.systemPrompt);
31192
+ }
31046
31193
  }
31047
31194
  if (commandResult.exit) {
31048
31195
  this.emit({ type: "exit" });
@@ -31081,6 +31228,8 @@ class AgentLoop {
31081
31228
  responseText += chunk.content;
31082
31229
  } else if (chunk.type === "tool_use" && chunk.toolCall) {
31083
31230
  toolCalls.push(chunk.toolCall);
31231
+ } else if (chunk.type === "usage" && chunk.usage) {
31232
+ this.updateTokenUsage(chunk.usage);
31084
31233
  } else if (chunk.type === "error") {
31085
31234
  return;
31086
31235
  }
@@ -31103,13 +31252,13 @@ class AgentLoop {
31103
31252
  const results = [];
31104
31253
  for (const toolCall of toolCalls) {
31105
31254
  const preHookResult = await this.hookExecutor.execute(this.hookLoader.getHooks("PreToolUse"), {
31106
- session_id: generateId(),
31255
+ session_id: this.sessionId,
31107
31256
  hook_event_name: "PreToolUse",
31108
31257
  cwd: this.cwd,
31109
31258
  tool_name: toolCall.name,
31110
31259
  tool_input: toolCall.input
31111
31260
  });
31112
- if (preHookResult?.permissionDecision === "deny") {
31261
+ if (preHookResult?.continue === false || preHookResult?.permissionDecision === "deny") {
31113
31262
  results.push({
31114
31263
  toolCallId: toolCall.id,
31115
31264
  content: `Tool call denied: ${preHookResult.stopReason || "Blocked by hook"}`,
@@ -31121,9 +31270,10 @@ class AgentLoop {
31121
31270
  const result = await this.toolRegistry.execute(toolCall);
31122
31271
  this.onToolEnd?.(toolCall, result);
31123
31272
  this.emit({ type: "tool_result", toolResult: result });
31124
- await this.hookExecutor.execute(this.hookLoader.getHooks("PostToolUse"), {
31125
- session_id: generateId(),
31126
- hook_event_name: "PostToolUse",
31273
+ const hookEvent = result.isError ? "PostToolUseFailure" : "PostToolUse";
31274
+ await this.hookExecutor.execute(this.hookLoader.getHooks(hookEvent), {
31275
+ session_id: this.sessionId,
31276
+ hook_event_name: hookEvent,
31127
31277
  cwd: this.cwd,
31128
31278
  tool_name: toolCall.name,
31129
31279
  tool_input: toolCall.input,
@@ -31139,6 +31289,11 @@ class AgentLoop {
31139
31289
  sessionId: this.sessionId,
31140
31290
  messages: this.context.getMessages(),
31141
31291
  tools: this.toolRegistry.getTools(),
31292
+ skills: this.skillLoader.getSkills().map((s) => ({
31293
+ name: s.name,
31294
+ description: s.description || "",
31295
+ argumentHint: s.argumentHint
31296
+ })),
31142
31297
  clearMessages: () => {
31143
31298
  this.context = new AgentContext;
31144
31299
  },
@@ -31213,7 +31368,7 @@ class AgentLoop {
31213
31368
  init_anthropic();
31214
31369
 
31215
31370
  // packages/core/src/logger.ts
31216
- import { existsSync as existsSync6, mkdirSync as mkdirSync2, appendFileSync } from "fs";
31371
+ import { existsSync as existsSync6, mkdirSync as mkdirSync2, appendFileSync, readdirSync as readdirSync2, readFileSync as readFileSync3 } from "fs";
31217
31372
  import { join as join9 } from "path";
31218
31373
  import { homedir as homedir9 } from "os";
31219
31374
 
@@ -31286,6 +31441,55 @@ class SessionStorage {
31286
31441
  getSessionId() {
31287
31442
  return this.sessionId;
31288
31443
  }
31444
+ load() {
31445
+ try {
31446
+ if (!existsSync6(this.sessionFile))
31447
+ return null;
31448
+ const content = Bun.file(this.sessionFile).text();
31449
+ return JSON.parse(content);
31450
+ } catch {
31451
+ return null;
31452
+ }
31453
+ }
31454
+ static listSessions() {
31455
+ const sessionsDir = join9(homedir9(), ".oldpal", "sessions");
31456
+ if (!existsSync6(sessionsDir))
31457
+ return [];
31458
+ const sessions = [];
31459
+ const files = readdirSync2(sessionsDir);
31460
+ for (const file of files) {
31461
+ if (!file.endsWith(".json"))
31462
+ continue;
31463
+ try {
31464
+ const filePath = join9(sessionsDir, file);
31465
+ const stat = Bun.file(filePath);
31466
+ const content = JSON.parse(readFileSync3(filePath, "utf-8"));
31467
+ sessions.push({
31468
+ id: file.replace(".json", ""),
31469
+ cwd: content.cwd,
31470
+ startedAt: content.startedAt,
31471
+ updatedAt: content.updatedAt,
31472
+ messageCount: content.messages?.length || 0
31473
+ });
31474
+ } catch {}
31475
+ }
31476
+ return sessions.sort((a, b) => new Date(b.updatedAt).getTime() - new Date(a.updatedAt).getTime());
31477
+ }
31478
+ static getLatestSession() {
31479
+ const sessions = SessionStorage.listSessions();
31480
+ return sessions[0] || null;
31481
+ }
31482
+ static loadSession(sessionId) {
31483
+ const sessionsDir = join9(homedir9(), ".oldpal", "sessions");
31484
+ const sessionFile = join9(sessionsDir, `${sessionId}.json`);
31485
+ try {
31486
+ if (!existsSync6(sessionFile))
31487
+ return null;
31488
+ return JSON.parse(readFileSync3(sessionFile, "utf-8"));
31489
+ } catch {
31490
+ return null;
31491
+ }
31492
+ }
31289
31493
  }
31290
31494
  function initOldpalDir() {
31291
31495
  const baseDir = join9(homedir9(), ".oldpal");
@@ -31330,12 +31534,6 @@ class EmbeddedClient {
31330
31534
  },
31331
31535
  onToolStart: (toolCall) => {
31332
31536
  this.logger.info("Tool started", { tool: toolCall.name, input: toolCall.input });
31333
- for (const callback of this.chunkCallbacks) {
31334
- callback({
31335
- type: "tool_use",
31336
- toolCall
31337
- });
31338
- }
31339
31537
  },
31340
31538
  onToolEnd: (toolCall, result) => {
31341
31539
  this.logger.info("Tool completed", {
@@ -31708,9 +31906,10 @@ var COMMANDS = [
31708
31906
  { name: "/bug", description: "analyze and fix a bug" },
31709
31907
  { name: "/pr", description: "create a pull request" },
31710
31908
  { name: "/review", description: "review code changes" },
31909
+ { name: "/feedback", description: "submit feedback on GitHub" },
31711
31910
  { name: "/exit", description: "exit oldpal" }
31712
31911
  ];
31713
- function Input({ onSubmit, isProcessing, queueLength = 0, commands }) {
31912
+ function Input({ onSubmit, isProcessing, queueLength = 0, commands, skills = [] }) {
31714
31913
  const [value, setValue] = import_react23.useState("");
31715
31914
  const [selectedIndex, setSelectedIndex] = import_react23.useState(0);
31716
31915
  const allCommands = import_react23.useMemo(() => {
@@ -31724,23 +31923,42 @@ function Input({ onSubmit, isProcessing, queueLength = 0, commands }) {
31724
31923
  }
31725
31924
  return merged.sort((a, b) => a.name.localeCompare(b.name));
31726
31925
  }, [commands]);
31727
- const showAutocomplete = value.startsWith("/") && !value.includes(" ");
31926
+ const autocompleteMode = import_react23.useMemo(() => {
31927
+ if (value.startsWith("$") && !value.includes(" ")) {
31928
+ return "skill";
31929
+ }
31930
+ if (value.startsWith("/") && !value.includes(" ")) {
31931
+ return "command";
31932
+ }
31933
+ return null;
31934
+ }, [value]);
31728
31935
  const filteredCommands = import_react23.useMemo(() => {
31729
- if (!showAutocomplete)
31936
+ if (autocompleteMode !== "command")
31730
31937
  return [];
31731
31938
  const search = value.toLowerCase();
31732
31939
  return allCommands.filter((cmd) => cmd.name.toLowerCase().startsWith(search));
31733
- }, [value, showAutocomplete, allCommands]);
31940
+ }, [value, autocompleteMode, allCommands]);
31941
+ const filteredSkills = import_react23.useMemo(() => {
31942
+ if (autocompleteMode !== "skill")
31943
+ return [];
31944
+ const search = value.slice(1).toLowerCase();
31945
+ return skills.filter((skill) => skill.name.toLowerCase().startsWith(search));
31946
+ }, [value, autocompleteMode, skills]);
31947
+ const autocompleteItems = autocompleteMode === "skill" ? filteredSkills : filteredCommands;
31734
31948
  use_input_default((input, key) => {
31735
- if (key.tab && showAutocomplete && filteredCommands.length > 0) {
31736
- const selected = filteredCommands[selectedIndex] || filteredCommands[0];
31737
- setValue(selected.name + " ");
31949
+ if (key.tab && autocompleteItems.length > 0) {
31950
+ const selected = autocompleteItems[selectedIndex] || autocompleteItems[0];
31951
+ if (autocompleteMode === "skill") {
31952
+ setValue("$" + selected.name + " ");
31953
+ } else {
31954
+ setValue(selected.name + " ");
31955
+ }
31738
31956
  setSelectedIndex(0);
31739
31957
  return;
31740
31958
  }
31741
- if (showAutocomplete && filteredCommands.length > 0) {
31959
+ if (autocompleteItems.length > 0) {
31742
31960
  if (key.downArrow) {
31743
- setSelectedIndex((prev) => Math.min(prev + 1, filteredCommands.length - 1));
31961
+ setSelectedIndex((prev) => Math.min(prev + 1, autocompleteItems.length - 1));
31744
31962
  return;
31745
31963
  }
31746
31964
  if (key.upArrow) {
@@ -31781,37 +31999,29 @@ function Input({ onSubmit, isProcessing, queueLength = 0, commands }) {
31781
31999
  prompt = "\u22EF";
31782
32000
  placeholder = queueLength > 0 ? "Type to queue another..." : "Type to queue (Enter) or interrupt (Shift+Enter)...";
31783
32001
  }
32002
+ const truncateDescription = (desc, maxLen = 60) => {
32003
+ if (desc.length <= maxLen)
32004
+ return desc;
32005
+ return desc.slice(0, maxLen - 3) + "...";
32006
+ };
32007
+ const maxVisible = 8;
32008
+ const getVisibleItems = (items) => {
32009
+ if (items.length <= maxVisible) {
32010
+ return { items, startIndex: 0 };
32011
+ }
32012
+ let startIndex = Math.max(0, selectedIndex - Math.floor(maxVisible / 2));
32013
+ startIndex = Math.min(startIndex, items.length - maxVisible);
32014
+ return {
32015
+ items: items.slice(startIndex, startIndex + maxVisible),
32016
+ startIndex
32017
+ };
32018
+ };
32019
+ const visibleSkills = getVisibleItems(filteredSkills);
32020
+ const visibleCommands = getVisibleItems(filteredCommands);
31784
32021
  return /* @__PURE__ */ jsx_dev_runtime.jsxDEV(Box_default, {
31785
32022
  flexDirection: "column",
31786
32023
  marginTop: 1,
31787
32024
  children: [
31788
- showAutocomplete && filteredCommands.length > 0 && /* @__PURE__ */ jsx_dev_runtime.jsxDEV(Box_default, {
31789
- flexDirection: "column",
31790
- marginBottom: 1,
31791
- marginLeft: 2,
31792
- children: [
31793
- filteredCommands.slice(0, 8).map((cmd, i) => /* @__PURE__ */ jsx_dev_runtime.jsxDEV(Box_default, {
31794
- children: [
31795
- /* @__PURE__ */ jsx_dev_runtime.jsxDEV(Text, {
31796
- color: i === selectedIndex ? "cyan" : undefined,
31797
- children: cmd.name.padEnd(16)
31798
- }, undefined, false, undefined, this),
31799
- /* @__PURE__ */ jsx_dev_runtime.jsxDEV(Text, {
31800
- dimColor: i !== selectedIndex,
31801
- children: cmd.description
31802
- }, undefined, false, undefined, this)
31803
- ]
31804
- }, cmd.name, true, undefined, this)),
31805
- filteredCommands.length > 8 && /* @__PURE__ */ jsx_dev_runtime.jsxDEV(Text, {
31806
- dimColor: true,
31807
- children: [
31808
- " ...and ",
31809
- filteredCommands.length - 8,
31810
- " more"
31811
- ]
31812
- }, undefined, true, undefined, this)
31813
- ]
31814
- }, undefined, true, undefined, this),
31815
32025
  /* @__PURE__ */ jsx_dev_runtime.jsxDEV(Box_default, {
31816
32026
  children: [
31817
32027
  /* @__PURE__ */ jsx_dev_runtime.jsxDEV(Text, {
@@ -31828,6 +32038,88 @@ function Input({ onSubmit, isProcessing, queueLength = 0, commands }) {
31828
32038
  placeholder
31829
32039
  }, undefined, false, undefined, this)
31830
32040
  ]
32041
+ }, undefined, true, undefined, this),
32042
+ autocompleteMode === "skill" && filteredSkills.length > 0 && /* @__PURE__ */ jsx_dev_runtime.jsxDEV(Box_default, {
32043
+ flexDirection: "column",
32044
+ marginTop: 1,
32045
+ marginLeft: 2,
32046
+ children: [
32047
+ visibleSkills.startIndex > 0 && /* @__PURE__ */ jsx_dev_runtime.jsxDEV(Text, {
32048
+ dimColor: true,
32049
+ children: [
32050
+ " \u2191 ",
32051
+ visibleSkills.startIndex,
32052
+ " more above"
32053
+ ]
32054
+ }, undefined, true, undefined, this),
32055
+ visibleSkills.items.map((skill, i) => {
32056
+ const actualIndex = visibleSkills.startIndex + i;
32057
+ return /* @__PURE__ */ jsx_dev_runtime.jsxDEV(Box_default, {
32058
+ children: [
32059
+ /* @__PURE__ */ jsx_dev_runtime.jsxDEV(Text, {
32060
+ color: actualIndex === selectedIndex ? "cyan" : "#5fb3a1",
32061
+ children: [
32062
+ actualIndex === selectedIndex ? "\u25B8 " : " ",
32063
+ skill.name.padEnd(18)
32064
+ ]
32065
+ }, undefined, true, undefined, this),
32066
+ /* @__PURE__ */ jsx_dev_runtime.jsxDEV(Text, {
32067
+ dimColor: actualIndex !== selectedIndex,
32068
+ children: truncateDescription(skill.description)
32069
+ }, undefined, false, undefined, this)
32070
+ ]
32071
+ }, skill.name, true, undefined, this);
32072
+ }),
32073
+ visibleSkills.startIndex + maxVisible < filteredSkills.length && /* @__PURE__ */ jsx_dev_runtime.jsxDEV(Text, {
32074
+ dimColor: true,
32075
+ children: [
32076
+ " \u2193 ",
32077
+ filteredSkills.length - visibleSkills.startIndex - maxVisible,
32078
+ " more below"
32079
+ ]
32080
+ }, undefined, true, undefined, this)
32081
+ ]
32082
+ }, undefined, true, undefined, this),
32083
+ autocompleteMode === "command" && filteredCommands.length > 0 && /* @__PURE__ */ jsx_dev_runtime.jsxDEV(Box_default, {
32084
+ flexDirection: "column",
32085
+ marginTop: 1,
32086
+ marginLeft: 2,
32087
+ children: [
32088
+ visibleCommands.startIndex > 0 && /* @__PURE__ */ jsx_dev_runtime.jsxDEV(Text, {
32089
+ dimColor: true,
32090
+ children: [
32091
+ " \u2191 ",
32092
+ visibleCommands.startIndex,
32093
+ " more above"
32094
+ ]
32095
+ }, undefined, true, undefined, this),
32096
+ visibleCommands.items.map((cmd, i) => {
32097
+ const actualIndex = visibleCommands.startIndex + i;
32098
+ return /* @__PURE__ */ jsx_dev_runtime.jsxDEV(Box_default, {
32099
+ children: [
32100
+ /* @__PURE__ */ jsx_dev_runtime.jsxDEV(Text, {
32101
+ color: actualIndex === selectedIndex ? "cyan" : undefined,
32102
+ children: [
32103
+ actualIndex === selectedIndex ? "\u25B8 " : " ",
32104
+ cmd.name.padEnd(14)
32105
+ ]
32106
+ }, undefined, true, undefined, this),
32107
+ /* @__PURE__ */ jsx_dev_runtime.jsxDEV(Text, {
32108
+ dimColor: actualIndex !== selectedIndex,
32109
+ children: cmd.description
32110
+ }, undefined, false, undefined, this)
32111
+ ]
32112
+ }, cmd.name, true, undefined, this);
32113
+ }),
32114
+ visibleCommands.startIndex + maxVisible < filteredCommands.length && /* @__PURE__ */ jsx_dev_runtime.jsxDEV(Text, {
32115
+ dimColor: true,
32116
+ children: [
32117
+ " \u2193 ",
32118
+ filteredCommands.length - visibleCommands.startIndex - maxVisible,
32119
+ " more below"
32120
+ ]
32121
+ }, undefined, true, undefined, this)
32122
+ ]
31831
32123
  }, undefined, true, undefined, this)
31832
32124
  ]
31833
32125
  }, undefined, true, undefined, this);
@@ -32450,6 +32742,10 @@ function SessionSelector({
32450
32742
  }) {
32451
32743
  const [selectedIndex, setSelectedIndex] = import_react26.useState(0);
32452
32744
  use_input_default((input, key) => {
32745
+ if (input === "n" || input === "N") {
32746
+ onNew();
32747
+ return;
32748
+ }
32453
32749
  if (key.escape) {
32454
32750
  onCancel();
32455
32751
  return;
@@ -32464,16 +32760,16 @@ function SessionSelector({
32464
32760
  }
32465
32761
  if (key.upArrow) {
32466
32762
  setSelectedIndex((prev) => Math.max(0, prev - 1));
32763
+ return;
32467
32764
  }
32468
32765
  if (key.downArrow) {
32469
32766
  setSelectedIndex((prev) => Math.min(sessions.length, prev + 1));
32767
+ return;
32470
32768
  }
32471
32769
  const num = parseInt(input, 10);
32472
32770
  if (!isNaN(num) && num >= 1 && num <= sessions.length) {
32473
32771
  onSelect(sessions[num - 1].id);
32474
- }
32475
- if (input === "n") {
32476
- onNew();
32772
+ return;
32477
32773
  }
32478
32774
  });
32479
32775
  return /* @__PURE__ */ jsx_dev_runtime8.jsxDEV(Box_default, {
@@ -32581,6 +32877,7 @@ function App2({ cwd: cwd2 }) {
32581
32877
  const [currentTurnTokens, setCurrentTurnTokens] = import_react27.useState(0);
32582
32878
  const [scrollOffset, setScrollOffset] = import_react27.useState(0);
32583
32879
  const [autoScroll, setAutoScroll] = import_react27.useState(true);
32880
+ const [skills, setSkills] = import_react27.useState([]);
32584
32881
  const responseRef = import_react27.useRef("");
32585
32882
  const toolCallsRef = import_react27.useRef([]);
32586
32883
  const toolResultsRef = import_react27.useRef([]);
@@ -32726,6 +33023,12 @@ function App2({ cwd: cwd2 }) {
32726
33023
  });
32727
33024
  const session = await registry2.createSession(cwd2);
32728
33025
  setActiveSessionId(session.id);
33026
+ const loadedSkills = await session.client.getSkills();
33027
+ setSkills(loadedSkills.map((s) => ({
33028
+ name: s.name,
33029
+ description: s.description || "",
33030
+ argumentHint: s.argumentHint
33031
+ })));
32729
33032
  setIsInitializing(false);
32730
33033
  } catch (err) {
32731
33034
  setError(err instanceof Error ? err.message : String(err));
@@ -32783,33 +33086,33 @@ function App2({ cwd: cwd2 }) {
32783
33086
  const sessionCount = registry2.getSessionCount();
32784
33087
  const backgroundProcessingCount = registry2.getBackgroundProcessingSessions().length;
32785
33088
  const handleSessionSwitch = import_react27.useCallback(async (sessionId) => {
33089
+ setShowSessionSelector(false);
32786
33090
  if (sessionId === activeSessionId) {
32787
- setShowSessionSelector(false);
32788
33091
  return;
32789
33092
  }
32790
33093
  saveCurrentSessionState();
32791
- await registry2.switchSession(sessionId);
32792
- setActiveSessionId(sessionId);
32793
33094
  loadSessionState(sessionId);
32794
33095
  const session = registry2.getSession(sessionId);
32795
33096
  if (session) {
32796
33097
  setIsProcessing(session.isProcessing);
32797
33098
  }
32798
- setShowSessionSelector(false);
33099
+ await registry2.switchSession(sessionId);
33100
+ setActiveSessionId(sessionId);
32799
33101
  }, [activeSessionId, registry2, saveCurrentSessionState, loadSessionState]);
32800
33102
  const handleNewSession = import_react27.useCallback(async () => {
32801
- saveCurrentSessionState();
32802
- const newSession = await registry2.createSession(cwd2);
32803
- await registry2.switchSession(newSession.id);
32804
- setActiveSessionId(newSession.id);
32805
- loadSessionState(newSession.id);
32806
- setIsProcessing(false);
32807
33103
  setShowSessionSelector(false);
33104
+ try {
33105
+ saveCurrentSessionState();
33106
+ const newSession = await registry2.createSession(cwd2);
33107
+ loadSessionState(newSession.id);
33108
+ setIsProcessing(false);
33109
+ await registry2.switchSession(newSession.id);
33110
+ setActiveSessionId(newSession.id);
33111
+ } catch (err) {
33112
+ setError(err instanceof Error ? err.message : "Failed to create session");
33113
+ }
32808
33114
  }, [cwd2, registry2, saveCurrentSessionState, loadSessionState]);
32809
33115
  use_input_default((input, key) => {
32810
- if (showSessionSelector) {
32811
- return;
32812
- }
32813
33116
  if (key.ctrl && input === "s") {
32814
33117
  if (sessions.length > 0) {
32815
33118
  setShowSessionSelector(true);
@@ -32887,11 +33190,15 @@ function App2({ cwd: cwd2 }) {
32887
33190
  setScrollOffset(0);
32888
33191
  setAutoScroll(true);
32889
33192
  }
32890
- });
33193
+ }, { isActive: !showSessionSelector });
32891
33194
  const handleSubmit = import_react27.useCallback(async (input, mode = "normal") => {
32892
33195
  if (!activeSession || !input.trim())
32893
33196
  return;
32894
33197
  const trimmedInput = input.trim();
33198
+ if (trimmedInput.startsWith("$")) {
33199
+ const skillInput = "/" + trimmedInput.slice(1);
33200
+ return handleSubmit(skillInput, mode);
33201
+ }
32895
33202
  if (trimmedInput.startsWith("/session")) {
32896
33203
  const arg = trimmedInput.slice(8).trim();
32897
33204
  if (arg === "new") {
@@ -32984,7 +33291,7 @@ function App2({ cwd: cwd2 }) {
32984
33291
  padding: 1,
32985
33292
  children: [
32986
33293
  showWelcome && /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(WelcomeBanner, {
32987
- version: "0.5.3",
33294
+ version: "0.6.0",
32988
33295
  model: "claude-sonnet-4",
32989
33296
  directory: activeSession?.cwd || cwd2
32990
33297
  }, undefined, false, undefined, this),
@@ -33018,7 +33325,7 @@ function App2({ cwd: cwd2 }) {
33018
33325
  activityLog: isProcessing ? activityLog.filter((e) => e.type === "text") : [],
33019
33326
  scrollOffset,
33020
33327
  maxVisible: maxVisibleMessages
33021
- }, undefined, false, undefined, this),
33328
+ }, activeSessionId || "default", false, undefined, this),
33022
33329
  isProcessing && toolCallEntries.length > 0 && /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Box_default, {
33023
33330
  marginY: 1,
33024
33331
  children: /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Text, {
@@ -33065,7 +33372,8 @@ function App2({ cwd: cwd2 }) {
33065
33372
  /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Input, {
33066
33373
  onSubmit: handleSubmit,
33067
33374
  isProcessing,
33068
- queueLength: messageQueue.length
33375
+ queueLength: messageQueue.length,
33376
+ skills
33069
33377
  }, undefined, false, undefined, this),
33070
33378
  /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Status, {
33071
33379
  isProcessing,
@@ -33080,16 +33388,212 @@ function App2({ cwd: cwd2 }) {
33080
33388
  }, undefined, true, undefined, this);
33081
33389
  }
33082
33390
 
33391
+ // packages/terminal/src/headless.ts
33392
+ async function runHeadless(options) {
33393
+ const {
33394
+ prompt,
33395
+ cwd: cwd2,
33396
+ outputFormat,
33397
+ jsonSchema
33398
+ } = options;
33399
+ const client = new EmbeddedClient(cwd2);
33400
+ let result = "";
33401
+ const toolCalls = [];
33402
+ let hadError = false;
33403
+ let errorMessage = "";
33404
+ client.onChunk((chunk) => {
33405
+ if (outputFormat === "stream-json") {
33406
+ const event = formatStreamEvent(chunk);
33407
+ if (event) {
33408
+ process.stdout.write(JSON.stringify(event) + `
33409
+ `);
33410
+ }
33411
+ }
33412
+ if (chunk.type === "text" && chunk.content) {
33413
+ result += chunk.content;
33414
+ if (outputFormat === "text") {
33415
+ process.stdout.write(chunk.content);
33416
+ }
33417
+ }
33418
+ if (chunk.type === "tool_use" && chunk.toolCall) {
33419
+ toolCalls.push({
33420
+ name: chunk.toolCall.name,
33421
+ input: chunk.toolCall.input
33422
+ });
33423
+ }
33424
+ if (chunk.type === "error" && chunk.error) {
33425
+ hadError = true;
33426
+ errorMessage = chunk.error;
33427
+ }
33428
+ });
33429
+ client.onError((error) => {
33430
+ hadError = true;
33431
+ errorMessage = error.message;
33432
+ if (outputFormat === "json") {
33433
+ console.error(JSON.stringify({ error: error.message }));
33434
+ } else {
33435
+ console.error(`Error: ${error.message}`);
33436
+ }
33437
+ });
33438
+ await client.initialize();
33439
+ let message = prompt;
33440
+ if (jsonSchema) {
33441
+ message = `${prompt}
33442
+
33443
+ IMPORTANT: Your response MUST be valid JSON conforming to this schema:
33444
+ ${jsonSchema}`;
33445
+ }
33446
+ await client.send(message);
33447
+ if (outputFormat === "json") {
33448
+ const output = {
33449
+ result: result.trim(),
33450
+ session_id: client.getSessionId(),
33451
+ usage: client.getTokenUsage(),
33452
+ tool_calls: toolCalls.length > 0 ? toolCalls : undefined
33453
+ };
33454
+ if (jsonSchema) {
33455
+ try {
33456
+ output.structured_output = JSON.parse(result.trim());
33457
+ } catch {}
33458
+ }
33459
+ console.log(JSON.stringify(output, null, 2));
33460
+ } else if (outputFormat === "text") {
33461
+ if (result && !result.endsWith(`
33462
+ `)) {
33463
+ process.stdout.write(`
33464
+ `);
33465
+ }
33466
+ }
33467
+ client.disconnect();
33468
+ if (hadError) {
33469
+ process.exit(1);
33470
+ }
33471
+ }
33472
+ function formatStreamEvent(chunk) {
33473
+ const timestamp = Date.now();
33474
+ switch (chunk.type) {
33475
+ case "text":
33476
+ return {
33477
+ type: "text_delta",
33478
+ text: chunk.content,
33479
+ timestamp
33480
+ };
33481
+ case "tool_use":
33482
+ return {
33483
+ type: "tool_use",
33484
+ tool_call: {
33485
+ id: chunk.toolCall?.id,
33486
+ name: chunk.toolCall?.name,
33487
+ input: chunk.toolCall?.input
33488
+ },
33489
+ timestamp
33490
+ };
33491
+ case "tool_result":
33492
+ return {
33493
+ type: "tool_result",
33494
+ tool_result: {
33495
+ tool_call_id: chunk.toolResult?.toolCallId,
33496
+ content: chunk.toolResult?.content,
33497
+ is_error: chunk.toolResult?.isError
33498
+ },
33499
+ timestamp
33500
+ };
33501
+ case "usage":
33502
+ return {
33503
+ type: "usage",
33504
+ usage: chunk.usage,
33505
+ timestamp
33506
+ };
33507
+ case "error":
33508
+ return {
33509
+ type: "error",
33510
+ error: chunk.error,
33511
+ timestamp
33512
+ };
33513
+ case "done":
33514
+ return {
33515
+ type: "done",
33516
+ timestamp
33517
+ };
33518
+ default:
33519
+ return null;
33520
+ }
33521
+ }
33522
+
33083
33523
  // packages/terminal/src/index.tsx
33084
33524
  var jsx_dev_runtime10 = __toESM(require_jsx_dev_runtime(), 1);
33085
- var args = process.argv.slice(2);
33086
- var options = {
33087
- cwd: process.cwd(),
33088
- version: args.includes("--version") || args.includes("-v"),
33089
- help: args.includes("--help") || args.includes("-h")
33090
- };
33525
+ var VERSION3 = "0.6.2";
33526
+ function parseArgs(argv) {
33527
+ const args = argv.slice(2);
33528
+ const options = {
33529
+ cwd: process.cwd(),
33530
+ version: false,
33531
+ help: false,
33532
+ print: null,
33533
+ outputFormat: "text",
33534
+ allowedTools: [],
33535
+ systemPrompt: null,
33536
+ jsonSchema: null,
33537
+ continue: false,
33538
+ resume: null
33539
+ };
33540
+ for (let i = 0;i < args.length; i++) {
33541
+ const arg = args[i];
33542
+ if (arg === "--version" || arg === "-v") {
33543
+ options.version = true;
33544
+ continue;
33545
+ }
33546
+ if (arg === "--help" || arg === "-h") {
33547
+ options.help = true;
33548
+ continue;
33549
+ }
33550
+ if (arg === "--print" || arg === "-p") {
33551
+ options.print = args[++i] || "";
33552
+ continue;
33553
+ }
33554
+ if (arg === "--output-format") {
33555
+ const format = args[++i];
33556
+ if (format === "text" || format === "json" || format === "stream-json") {
33557
+ options.outputFormat = format;
33558
+ }
33559
+ continue;
33560
+ }
33561
+ if (arg === "--allowed-tools" || arg === "--allowedTools") {
33562
+ const tools = args[++i];
33563
+ if (tools) {
33564
+ options.allowedTools = tools.split(",").map((t) => t.trim());
33565
+ }
33566
+ continue;
33567
+ }
33568
+ if (arg === "--system-prompt") {
33569
+ options.systemPrompt = args[++i] || null;
33570
+ continue;
33571
+ }
33572
+ if (arg === "--json-schema") {
33573
+ options.jsonSchema = args[++i] || null;
33574
+ continue;
33575
+ }
33576
+ if (arg === "--continue" || arg === "-c") {
33577
+ options.continue = true;
33578
+ continue;
33579
+ }
33580
+ if (arg === "--resume" || arg === "-r") {
33581
+ options.resume = args[++i] || null;
33582
+ continue;
33583
+ }
33584
+ if (arg === "--cwd") {
33585
+ options.cwd = args[++i] || process.cwd();
33586
+ continue;
33587
+ }
33588
+ if (options.print === "" && !arg.startsWith("-")) {
33589
+ options.print = arg;
33590
+ }
33591
+ }
33592
+ return options;
33593
+ }
33594
+ var options = parseArgs(process.argv);
33091
33595
  if (options.version) {
33092
- console.log("oldpal v0.5.3");
33596
+ console.log(`oldpal v${VERSION3}`);
33093
33597
  process.exit(0);
33094
33598
  }
33095
33599
  if (options.help) {
@@ -33097,27 +33601,74 @@ if (options.help) {
33097
33601
  oldpal - Your personal AI assistant
33098
33602
 
33099
33603
  Usage:
33100
- oldpal [options]
33604
+ oldpal [options] Start interactive mode
33605
+ oldpal -p "<prompt>" [options] Run in headless mode
33101
33606
 
33102
33607
  Options:
33103
- -h, --help Show this help message
33104
- -v, --version Show version number
33608
+ -h, --help Show this help message
33609
+ -v, --version Show version number
33610
+
33611
+ Headless Mode:
33612
+ -p, --print <prompt> Run non-interactively with the given prompt
33613
+ --output-format <format> Output format: text (default), json, stream-json
33614
+ --allowed-tools <tools> Comma-separated tools to auto-approve (e.g., "Read,Edit,Bash")
33615
+ --system-prompt <prompt> Custom system prompt
33616
+ --json-schema <schema> JSON Schema for structured output (use with --output-format json)
33617
+ -c, --continue Continue the most recent conversation
33618
+ -r, --resume <session_id> Resume a specific session by ID
33619
+ --cwd <path> Set working directory
33620
+
33621
+ Examples:
33622
+ # Ask a question
33623
+ oldpal -p "What does the auth module do?"
33624
+
33625
+ # Run with JSON output
33626
+ oldpal -p "Summarize this project" --output-format json
33105
33627
 
33106
- Commands:
33107
- (none) Start interactive mode
33628
+ # Stream JSON events
33629
+ oldpal -p "Explain this code" --output-format stream-json
33108
33630
 
33109
- In interactive mode:
33631
+ # Auto-approve tools
33632
+ oldpal -p "Fix the bug in auth.py" --allowed-tools "Read,Edit,Bash"
33633
+
33634
+ # Get structured output
33635
+ oldpal -p "List all functions" --output-format json --json-schema '{"type":"array","items":{"type":"string"}}'
33636
+
33637
+ # Continue conversation
33638
+ oldpal -p "What else can you tell me?" --continue
33639
+
33640
+ Interactive Mode:
33110
33641
  - Type your message and press Enter to send
33111
- - Use /skill-name to invoke a skill
33642
+ - Use $skill-name to invoke a skill
33643
+ - Use /command for built-in commands
33644
+ - Press Ctrl+S to switch sessions
33112
33645
  - Press Ctrl+C to exit
33113
33646
  `);
33114
33647
  process.exit(0);
33115
33648
  }
33116
- var { waitUntilExit } = render_default(/* @__PURE__ */ jsx_dev_runtime10.jsxDEV(App2, {
33117
- cwd: options.cwd
33118
- }, undefined, false, undefined, this));
33119
- waitUntilExit().then(() => {
33120
- process.exit(0);
33121
- });
33649
+ if (options.print !== null) {
33650
+ if (!options.print.trim()) {
33651
+ console.error("Error: Prompt is required with -p/--print flag");
33652
+ process.exit(1);
33653
+ }
33654
+ runHeadless({
33655
+ prompt: options.print,
33656
+ cwd: options.cwd,
33657
+ outputFormat: options.outputFormat,
33658
+ allowedTools: options.allowedTools.length > 0 ? options.allowedTools : undefined,
33659
+ systemPrompt: options.systemPrompt || undefined,
33660
+ jsonSchema: options.jsonSchema || undefined
33661
+ }).catch((error) => {
33662
+ console.error("Error:", error.message);
33663
+ process.exit(1);
33664
+ });
33665
+ } else {
33666
+ const { waitUntilExit } = render_default(/* @__PURE__ */ jsx_dev_runtime10.jsxDEV(App2, {
33667
+ cwd: options.cwd
33668
+ }, undefined, false, undefined, this));
33669
+ waitUntilExit().then(() => {
33670
+ process.exit(0);
33671
+ });
33672
+ }
33122
33673
 
33123
- //# debugId=F56E791D31BE043564756E2164756E21
33674
+ //# debugId=34BD21624905F2E764756E2164756E21