Sign In

@sapiom/agent-core

Package Overview
Dependencies
Maintainers
4
Versions
27
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@sapiom/agent-core - npm Package Compare versions

Comparing version
0.10.6
to
0.10.7
+51
-0
CHANGELOG.md
# @sapiom/orchestration-core
## 0.10.7
### Patch Changes
- f21f6a6: Windows: sessions create and deliver their prompt, the canvas refreshes, and nothing pops a console window
The desktop app was unusable on Windows — every `POST /api/sessions` answered
`500 {"error":"internal error"}`, and when a session did start, its first
prompt never reached the agent. Root-caused on a real machine and fixed
end to end.
- **Sessions.** Claude Code's own native auto-updater had renamed the running
`claude.exe` to `claude.exe.old.<ts>` inside the app-managed npm prefix and
never written the replacement, so every spawn failed while `doctor` (which
shells `where`) still reported the agent present. Boot now verifies the
agent actually spawns, repairs the managed install when it doesn't, and sets
`DISABLE_AUTOUPDATER` for installs the app owns. The refusal itself names
the situation instead of "target could not be determined".
- **The first prompt.** It is held until the session reports ready, which only
happens when the generated `SessionStart` hook POSTs back — and Claude Code
runs hooks through Git Bash on Windows, which cannot resolve a `.cmd`, so
the desktop's `node.cmd`-only shims meant the hook never ran. The host now
ships npm's extensionless sh shim too, a 20s hook-timeout fallback rescues a
session whose hook chain is broken (gated on Claude's blocking-prompt
screens so it can never answer a trust dialog), `emit.cjs` gets budgets a
cold loopback survives (SessionStart only — the other hooks block the
agent), and multi-line prompts are paste-wrapped under ConPTY, which hides
the bracketed-paste announcement.
- **Console windows.** The `sapiom-dev` MCP server was launched via `npx`,
whose `cmd.exe` sat on screen as a persistent blank window; closing it
killed the server and every later tool call hung. The app now installs
`@sapiom/mcp` into its own prefix and launches it through the app binary
(GUI subsystem — no console can exist), and every `child_process` call
across the harness, agent-core, the MCP and the desktop passes
`windowsHide`.
- **Canvas.** `fs.watch` reports native separators, so the watcher's
POSIX-literal comparison never matched on Windows and `canvas.reload` was
never published — every canvas hot-reload was silently dead there (the
"Preparing your agent" placeholder outliving a finished install was the
visible symptom).
- **Diagnosis.** 500s now carry the real message (and errno) instead of
"internal error", the desktop tees its main-process log to
`<userData>/logs/main.log`, and spawn failures map to actionable 4xx.
- **Also:** Git is provisioned from git-for-windows' checksum-pinned MinGit
when a Windows machine has none (template clone and deploy shell out to a
real `git`); client-supplied `cwd` is normalized server-side and the SPA's
path helpers understand both separators; gateway requests time out instead
of hanging an MCP tool call for minutes; and the updater falls back to
HTTP/1.1, names a GitHub 429 for what it is, and bounds every path that can
reach GitHub.
## 0.10.6

@@ -4,0 +55,0 @@

+1
-0

@@ -61,2 +61,3 @@ "use strict";

stdio: ["ignore", "pipe", "pipe"],
windowsHide: true,
});

@@ -63,0 +64,0 @@ return null;

@@ -32,2 +32,3 @@ "use strict";

body: body === undefined ? undefined : JSON.stringify(body),
signal: AbortSignal.timeout(REQUEST_TIMEOUT_MS),
});

@@ -38,3 +39,9 @@ }

}
const text = await res.text();
let text;
try {
text = await res.text();
}
catch (err) {
throw networkError(url, err);
}
const data = text ? safeParse(text) : undefined;

@@ -98,3 +105,11 @@ if (!res.ok) {

}
const REQUEST_TIMEOUT_MS = 60000;
function networkError(url, err) {
if (err instanceof Error && err.name === 'TimeoutError') {
return new errors_js_1.AgentOperationError({
code: 'NETWORK',
message: `Request to ${url} timed out after ${REQUEST_TIMEOUT_MS / 1000}s.`,
hint: 'Is this machine able to reach the Sapiom API (firewall/proxy)? Try again once connectivity is confirmed.',
});
}
return new errors_js_1.AgentOperationError({

@@ -101,0 +116,0 @@ code: 'NETWORK',

@@ -10,2 +10,11 @@ "use strict";

const errors_js_1 = require("./errors.js");
function gitMissingError(err) {
if (err?.code !== "ENOENT")
return null;
return new errors_js_1.AgentOperationError({
code: "GIT_NOT_INSTALLED",
message: "git is not installed (or not on PATH).",
hint: "Install Git from https://git-scm.com/downloads, then retry. On Windows, install “Git for Windows” with default options and restart the app so the new PATH is picked up.",
});
}
function git(args, cwd) {

@@ -17,5 +26,9 @@ try {

stdio: ["ignore", "pipe", "pipe"],
windowsHide: true,
}).trim();
}
catch (err) {
const missing = gitMissingError(err);
if (missing)
throw missing;
const raw = err.stderr?.toString().trim();

@@ -35,2 +48,3 @@ const hint = redactCredentials(raw || (err instanceof Error ? err.message : String(err)));

stdio: "ignore",
windowsHide: true,
});

@@ -46,3 +60,3 @@ }

try {
(0, node_child_process_1.execFileSync)("git", ["rev-parse", "HEAD"], { cwd: dir, stdio: "ignore" });
(0, node_child_process_1.execFileSync)("git", ["rev-parse", "HEAD"], { cwd: dir, stdio: "ignore", windowsHide: true });
}

@@ -73,5 +87,8 @@ catch {

targetDir,
], { cwd, stdio: ["ignore", "pipe", "pipe"], encoding: "utf8" });
], { cwd, stdio: ["ignore", "pipe", "pipe"], encoding: "utf8", windowsHide: true });
}
catch (err) {
const missing = gitMissingError(err);
if (missing)
throw missing;
const stderr = err.stderr?.toString();

@@ -78,0 +95,0 @@ const raw = stderr?.trim() || (err instanceof Error ? err.message : String(err));

@@ -16,2 +16,3 @@ "use strict";

maxBuffer: MAX_BUFFER_BYTES,
windowsHide: true,
});

@@ -18,0 +19,0 @@ return true;

+1
-1

@@ -151,3 +151,3 @@ "use strict";

try {
(0, node_child_process_1.execFileSync)("git", args, { cwd: dir, stdio: "ignore" });
(0, node_child_process_1.execFileSync)("git", args, { cwd: dir, stdio: "ignore", windowsHide: true });
return true;

@@ -154,0 +154,0 @@ }

@@ -20,2 +20,3 @@ import { execFileSync } from "node:child_process";

stdio: ["ignore", "pipe", "pipe"],
windowsHide: true,
});

@@ -22,0 +23,0 @@ return null;

@@ -28,2 +28,3 @@ import { AgentOperationError } from './errors.js';

body: body === undefined ? undefined : JSON.stringify(body),
signal: AbortSignal.timeout(REQUEST_TIMEOUT_MS),
});

@@ -34,3 +35,9 @@ }

}
const text = await res.text();
let text;
try {
text = await res.text();
}
catch (err) {
throw networkError(url, err);
}
const data = text ? safeParse(text) : undefined;

@@ -93,3 +100,11 @@ if (!res.ok) {

}
const REQUEST_TIMEOUT_MS = 60000;
function networkError(url, err) {
if (err instanceof Error && err.name === 'TimeoutError') {
return new AgentOperationError({
code: 'NETWORK',
message: `Request to ${url} timed out after ${REQUEST_TIMEOUT_MS / 1000}s.`,
hint: 'Is this machine able to reach the Sapiom API (firewall/proxy)? Try again once connectivity is confirmed.',
});
}
return new AgentOperationError({

@@ -96,0 +111,0 @@ code: 'NETWORK',

import { execFileSync } from "node:child_process";
import { AgentOperationError } from "./errors.js";
function gitMissingError(err) {
if (err?.code !== "ENOENT")
return null;
return new AgentOperationError({
code: "GIT_NOT_INSTALLED",
message: "git is not installed (or not on PATH).",
hint: "Install Git from https://git-scm.com/downloads, then retry. On Windows, install “Git for Windows” with default options and restart the app so the new PATH is picked up.",
});
}
function git(args, cwd) {

@@ -9,5 +18,9 @@ try {

stdio: ["ignore", "pipe", "pipe"],
windowsHide: true,
}).trim();
}
catch (err) {
const missing = gitMissingError(err);
if (missing)
throw missing;
const raw = err.stderr?.toString().trim();

@@ -27,2 +40,3 @@ const hint = redactCredentials(raw || (err instanceof Error ? err.message : String(err)));

stdio: "ignore",
windowsHide: true,
});

@@ -38,3 +52,3 @@ }

try {
execFileSync("git", ["rev-parse", "HEAD"], { cwd: dir, stdio: "ignore" });
execFileSync("git", ["rev-parse", "HEAD"], { cwd: dir, stdio: "ignore", windowsHide: true });
}

@@ -65,5 +79,8 @@ catch {

targetDir,
], { cwd, stdio: ["ignore", "pipe", "pipe"], encoding: "utf8" });
], { cwd, stdio: ["ignore", "pipe", "pipe"], encoding: "utf8", windowsHide: true });
}
catch (err) {
const missing = gitMissingError(err);
if (missing)
throw missing;
const stderr = err.stderr?.toString();

@@ -70,0 +87,0 @@ const raw = stderr?.trim() || (err instanceof Error ? err.message : String(err));

@@ -13,2 +13,3 @@ import { execFile } from "node:child_process";

maxBuffer: MAX_BUFFER_BYTES,
windowsHide: true,
});

@@ -15,0 +16,0 @@ return true;

@@ -140,3 +140,3 @@ import { execFileSync } from "node:child_process";

try {
execFileSync("git", args, { cwd: dir, stdio: "ignore" });
execFileSync("git", args, { cwd: dir, stdio: "ignore", windowsHide: true });
return true;

@@ -143,0 +143,0 @@ }

{
"name": "@sapiom/agent-core",
"version": "0.10.6",
"version": "0.10.7",
"description": "Pure, stateless core functions for scaffolding, validating, and operating Sapiom agents — shared by the CLI and MCP packages.",

@@ -5,0 +5,0 @@ "license": "MIT",

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet