agent-sh 0.12.14 → 0.12.16
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/agent/conversation-state.js +15 -5
- package/dist/agent/tools/pwsh.js +36 -5
- package/dist/executor.js +14 -9
- package/dist/index.js +6 -0
- package/package.json +1 -1
|
@@ -83,11 +83,21 @@ export class ConversationState {
|
|
|
83
83
|
this.eagerNucleateUser(text);
|
|
84
84
|
}
|
|
85
85
|
addAssistantMessage(content, toolCalls, extras) {
|
|
86
|
-
|
|
87
|
-
//
|
|
88
|
-
//
|
|
89
|
-
|
|
90
|
-
|
|
86
|
+
const hasToolCalls = !!toolCalls?.length;
|
|
87
|
+
// Promote reasoning into content on reasoning-only turns; strict
|
|
88
|
+
// providers (DeepSeek native) reject content="" with no tool_calls.
|
|
89
|
+
if (!content && !hasToolCalls) {
|
|
90
|
+
const r = (extras?.reasoning_content ?? extras?.reasoning);
|
|
91
|
+
if (typeof r === "string" && r)
|
|
92
|
+
content = r;
|
|
93
|
+
}
|
|
94
|
+
if (!content && !hasToolCalls)
|
|
95
|
+
return;
|
|
96
|
+
const base = {
|
|
97
|
+
role: "assistant",
|
|
98
|
+
content: hasToolCalls ? (content ?? null) : content,
|
|
99
|
+
};
|
|
100
|
+
if (hasToolCalls) {
|
|
91
101
|
base.tool_calls = toolCalls.map((tc) => ({
|
|
92
102
|
id: tc.id,
|
|
93
103
|
type: "function",
|
package/dist/agent/tools/pwsh.js
CHANGED
|
@@ -1,7 +1,30 @@
|
|
|
1
|
+
import { spawnSync } from "node:child_process";
|
|
1
2
|
import { executeArgv, killSession } from "../../executor.js";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
let cachedPwshPath;
|
|
4
|
+
/** Resolve a usable PowerShell binary, or null if none is on PATH.
|
|
5
|
+
* Prefers PowerShell 7+ (`pwsh`), falls back to Windows PowerShell (`powershell`). */
|
|
6
|
+
function findPwsh() {
|
|
7
|
+
if (cachedPwshPath !== undefined)
|
|
8
|
+
return cachedPwshPath;
|
|
9
|
+
// Prefer PowerShell 7 (pwsh)
|
|
10
|
+
const pwsh = spawnSync("where", ["pwsh"], { encoding: "utf-8" });
|
|
11
|
+
if (pwsh.status === 0) {
|
|
12
|
+
cachedPwshPath = pwsh.stdout.split(/\r?\n/)[0].trim() || null;
|
|
13
|
+
if (cachedPwshPath)
|
|
14
|
+
return cachedPwshPath;
|
|
15
|
+
}
|
|
16
|
+
// Fallback to Windows PowerShell (powershell.exe)
|
|
17
|
+
const ps = spawnSync("where", ["powershell"], { encoding: "utf-8" });
|
|
18
|
+
cachedPwshPath = ps.status === 0 ? ps.stdout.split(/\r?\n/)[0].trim() || null : null;
|
|
19
|
+
return cachedPwshPath;
|
|
20
|
+
}
|
|
21
|
+
/** Return the PowerShell executable name for display purposes. */
|
|
22
|
+
function getPwshDisplayName() {
|
|
23
|
+
const path = findPwsh();
|
|
24
|
+
if (!path)
|
|
25
|
+
return "PowerShell";
|
|
26
|
+
return path.toLowerCase().includes("pwsh") ? "pwsh" : "powershell";
|
|
27
|
+
}
|
|
5
28
|
export function createPwshTool(opts) {
|
|
6
29
|
return {
|
|
7
30
|
name: "pwsh",
|
|
@@ -54,8 +77,16 @@ export function createPwshTool(opts) {
|
|
|
54
77
|
isError: false,
|
|
55
78
|
};
|
|
56
79
|
}
|
|
80
|
+
const pwshPath = findPwsh();
|
|
81
|
+
if (!pwshPath) {
|
|
82
|
+
return {
|
|
83
|
+
content: "PowerShell not found on PATH. Neither pwsh (PowerShell 7+) nor powershell (Windows PowerShell) is available.",
|
|
84
|
+
exitCode: 1,
|
|
85
|
+
isError: true,
|
|
86
|
+
};
|
|
87
|
+
}
|
|
57
88
|
const { session, done } = executeArgv({
|
|
58
|
-
file:
|
|
89
|
+
file: pwshPath,
|
|
59
90
|
args: ["-NoProfile", "-NonInteractive", "-Command", command],
|
|
60
91
|
cwd: opts.getCwd(),
|
|
61
92
|
env: opts.getEnv(),
|
|
@@ -72,7 +103,7 @@ export function createPwshTool(opts) {
|
|
|
72
103
|
}
|
|
73
104
|
if (session.spawnFailed) {
|
|
74
105
|
return {
|
|
75
|
-
content:
|
|
106
|
+
content: `${getPwshDisplayName()} not found on PATH. Install PowerShell 7: winget install Microsoft.PowerShell.`,
|
|
76
107
|
exitCode: 1,
|
|
77
108
|
isError: true,
|
|
78
109
|
};
|
package/dist/executor.js
CHANGED
|
@@ -53,7 +53,8 @@ export function executeCommand(opts) {
|
|
|
53
53
|
stdio: ["ignore", "pipe", "pipe"],
|
|
54
54
|
cwd: opts.cwd,
|
|
55
55
|
env,
|
|
56
|
-
detached:
|
|
56
|
+
detached: process.platform !== "win32",
|
|
57
|
+
windowsHide: true,
|
|
57
58
|
});
|
|
58
59
|
}
|
|
59
60
|
catch (err) {
|
|
@@ -214,12 +215,14 @@ export function killSession(session) {
|
|
|
214
215
|
if (!proc || !proc.pid)
|
|
215
216
|
return () => { };
|
|
216
217
|
// Try process-group kill first (works for executeCommand's detached bash
|
|
217
|
-
// children); fall back to direct kill (executeArgv's non-detached
|
|
218
|
-
// and Windows where negative pids aren't supported).
|
|
219
|
-
|
|
220
|
-
|
|
218
|
+
// children on Unix); fall back to direct kill (executeArgv's non-detached
|
|
219
|
+
// spawn, and Windows where negative pids aren't supported).
|
|
220
|
+
if (process.platform !== "win32") {
|
|
221
|
+
try {
|
|
222
|
+
process.kill(-proc.pid, "SIGTERM");
|
|
223
|
+
}
|
|
224
|
+
catch { }
|
|
221
225
|
}
|
|
222
|
-
catch { }
|
|
223
226
|
try {
|
|
224
227
|
proc.kill("SIGTERM");
|
|
225
228
|
}
|
|
@@ -227,10 +230,12 @@ export function killSession(session) {
|
|
|
227
230
|
let settled = false;
|
|
228
231
|
const fallback = setTimeout(() => {
|
|
229
232
|
if (!settled && !session.done && proc.pid) {
|
|
230
|
-
|
|
231
|
-
|
|
233
|
+
if (process.platform !== "win32") {
|
|
234
|
+
try {
|
|
235
|
+
process.kill(-proc.pid, "SIGKILL");
|
|
236
|
+
}
|
|
237
|
+
catch { }
|
|
232
238
|
}
|
|
233
|
-
catch { }
|
|
234
239
|
try {
|
|
235
240
|
proc.kill("SIGKILL");
|
|
236
241
|
}
|
package/dist/index.js
CHANGED
|
@@ -9,6 +9,7 @@ import { loadExtensions } from "./extension-loader.js";
|
|
|
9
9
|
import { getSettings } from "./settings.js";
|
|
10
10
|
import { discoverSkills } from "./agent/skills.js";
|
|
11
11
|
import { runInit } from "./init.js";
|
|
12
|
+
import { PACKAGE_VERSION } from "./utils/package-version.js";
|
|
12
13
|
/**
|
|
13
14
|
* Capture the user's full shell environment.
|
|
14
15
|
* This picks up env vars exported in .zshrc/.bashrc that the
|
|
@@ -102,6 +103,10 @@ function parseArgs(argv) {
|
|
|
102
103
|
const exts = argv[++i].split(",").map(s => s.trim());
|
|
103
104
|
extensions = extensions ? [...extensions, ...exts] : exts;
|
|
104
105
|
}
|
|
106
|
+
else if (arg === "--version" || arg === "-V") {
|
|
107
|
+
console.log(PACKAGE_VERSION);
|
|
108
|
+
process.exit(0);
|
|
109
|
+
}
|
|
105
110
|
else if (arg === "--help" || arg === "-h") {
|
|
106
111
|
console.log(`agent-sh — a shell-first terminal where AI is one keystroke away
|
|
107
112
|
|
|
@@ -120,6 +125,7 @@ General Options:
|
|
|
120
125
|
--shell <path> Shell to use (default: $SHELL or /bin/bash)
|
|
121
126
|
-e, --extensions Extensions to load (comma-separated, repeatable)
|
|
122
127
|
-h, --help Show this help
|
|
128
|
+
-V, --version Print version and exit
|
|
123
129
|
|
|
124
130
|
Environment Variables:
|
|
125
131
|
OPENAI_API_KEY API key for LLM provider
|