@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 +689 -138
- package/dist/index.js.map +16 -15
- package/package.json +1 -1
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
|
|
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 ${
|
|
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":
|
|
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":
|
|
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":
|
|
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":
|
|
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":
|
|
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 = (
|
|
18784
|
-
if (
|
|
18783
|
+
}, normalizeArch = (arch2) => {
|
|
18784
|
+
if (arch2 === "x32")
|
|
18785
18785
|
return "x32";
|
|
18786
|
-
if (
|
|
18786
|
+
if (arch2 === "x86_64" || arch2 === "x64")
|
|
18787
18787
|
return "x64";
|
|
18788
|
-
if (
|
|
18788
|
+
if (arch2 === "arm")
|
|
18789
18789
|
return "arm";
|
|
18790
|
-
if (
|
|
18790
|
+
if (arch2 === "aarch64" || arch2 === "arm64")
|
|
18791
18791
|
return "arm64";
|
|
18792
|
-
if (
|
|
18793
|
-
return `other:${
|
|
18792
|
+
if (arch2)
|
|
18793
|
+
return `other:${arch2}`;
|
|
18794
18794
|
return "unknown";
|
|
18795
|
-
}, normalizePlatform = (
|
|
18796
|
-
|
|
18797
|
-
if (
|
|
18795
|
+
}, normalizePlatform = (platform3) => {
|
|
18796
|
+
platform3 = platform3.toLowerCase();
|
|
18797
|
+
if (platform3.includes("ios"))
|
|
18798
18798
|
return "iOS";
|
|
18799
|
-
if (
|
|
18799
|
+
if (platform3 === "android")
|
|
18800
18800
|
return "Android";
|
|
18801
|
-
if (
|
|
18801
|
+
if (platform3 === "darwin")
|
|
18802
18802
|
return "MacOS";
|
|
18803
|
-
if (
|
|
18803
|
+
if (platform3 === "win32")
|
|
18804
18804
|
return "Windows";
|
|
18805
|
-
if (
|
|
18805
|
+
if (platform3 === "freebsd")
|
|
18806
18806
|
return "FreeBSD";
|
|
18807
|
-
if (
|
|
18807
|
+
if (platform3 === "openbsd")
|
|
18808
18808
|
return "OpenBSD";
|
|
18809
|
-
if (
|
|
18809
|
+
if (platform3 === "linux")
|
|
18810
18810
|
return "Linux";
|
|
18811
|
-
if (
|
|
18812
|
-
return `Other:${
|
|
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 ? "
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
30478
|
-
|
|
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:
|
|
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
|
-
|
|
31125
|
-
|
|
31126
|
-
|
|
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
|
|
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 (
|
|
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,
|
|
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 &&
|
|
31736
|
-
const selected =
|
|
31737
|
-
|
|
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 (
|
|
31959
|
+
if (autocompleteItems.length > 0) {
|
|
31742
31960
|
if (key.downArrow) {
|
|
31743
|
-
setSelectedIndex((prev) => Math.min(prev + 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
|
-
|
|
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.
|
|
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
|
-
},
|
|
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
|
|
33086
|
-
|
|
33087
|
-
|
|
33088
|
-
|
|
33089
|
-
|
|
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(
|
|
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
|
|
33104
|
-
-v, --version
|
|
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
|
-
|
|
33107
|
-
|
|
33628
|
+
# Stream JSON events
|
|
33629
|
+
oldpal -p "Explain this code" --output-format stream-json
|
|
33108
33630
|
|
|
33109
|
-
|
|
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
|
|
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
|
-
|
|
33117
|
-
|
|
33118
|
-
|
|
33119
|
-
|
|
33120
|
-
|
|
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=
|
|
33674
|
+
//# debugId=34BD21624905F2E764756E2164756E21
|