@saadnvd1/agent-os 0.3.694 → 0.3.698
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/app/api/peer/ping/route.ts +10 -0
- package/components/Settings/NoApprovalsSection.tsx +1 -1
- package/lib/__fixtures__/connect-transport.ts +93 -0
- package/lib/__fixtures__/peer-machine.ts +45 -0
- package/lib/__fixtures__/peer-rpc.ts +224 -0
- package/lib/approvals/enable.ts +1 -21
- package/lib/approvals/no-approvals.ts +1 -1
- package/lib/db/migrations/20261020T1258_peer_links.ts +49 -0
- package/lib/db/migrations/20261020T1345_peer_nonces.ts +18 -0
- package/lib/db/types.ts +2 -0
- package/lib/hosts/index.ts +28 -7
- package/lib/hosts/peer-socket.ts +3 -1
- package/lib/hosts/read-capped-bytes.ts +23 -0
- package/lib/hosts/remote-api.ts +112 -41
- package/lib/models/plan-step.ts +5 -13
- package/lib/peer/allowlist.ts +136 -0
- package/lib/peer/audit.ts +144 -0
- package/lib/peer/client.ts +188 -0
- package/lib/peer/envelope.ts +424 -0
- package/lib/peer/internal.ts +22 -0
- package/lib/peer/keys.ts +122 -0
- package/lib/peer/links.ts +96 -0
- package/lib/peer/nonce-store.ts +23 -0
- package/lib/peer/replay.ts +81 -0
- package/lib/peer/rpc-intake.ts +229 -0
- package/lib/peer/rpc-server.ts +351 -0
- package/lib/security/auth.ts +42 -5
- package/lib/security/gate.ts +35 -12
- package/lib/security/route-guard.ts +3 -1
- package/lib/session-artifacts/peer.ts +12 -1
- package/lib/tasks/contract/authorize.ts +4 -0
- package/lib/tasks/contract/plan.ts +1 -14
- package/lib/worktree-sweep/testTemp.ts +3 -0
- package/package.json +1 -1
- package/scripts/install-deps +6 -1
- package/scripts/lib/commands.sh +1 -1
- package/scripts/lib/wsl.test.ts +51 -1
- package/server.ts +18 -0
package/scripts/lib/wsl.test.ts
CHANGED
|
@@ -33,6 +33,12 @@ const TOOLS = [
|
|
|
33
33
|
"id",
|
|
34
34
|
];
|
|
35
35
|
|
|
36
|
+
// Bash 4+ (Linux, CI) fails `set -e` on `((n++))` at 0; macOS's 3.2 doesn't.
|
|
37
|
+
const BASH =
|
|
38
|
+
["/opt/homebrew/bin/bash", "/usr/local/bin/bash", "/bin/bash"].find(
|
|
39
|
+
existsSync
|
|
40
|
+
) ?? "/bin/bash";
|
|
41
|
+
|
|
36
42
|
let dir: string;
|
|
37
43
|
|
|
38
44
|
function fake(name: string, body: string) {
|
|
@@ -48,7 +54,7 @@ function run(
|
|
|
48
54
|
) {
|
|
49
55
|
writeFileSync(join(dir, "osrelease"), osrelease);
|
|
50
56
|
return spawnSync(
|
|
51
|
-
|
|
57
|
+
BASH,
|
|
52
58
|
[
|
|
53
59
|
"-euo",
|
|
54
60
|
"pipefail",
|
|
@@ -313,3 +319,47 @@ describe("installing prerequisites", () => {
|
|
|
313
319
|
expect(r.stdout).not.toContain("Prerequisites installed");
|
|
314
320
|
});
|
|
315
321
|
});
|
|
322
|
+
|
|
323
|
+
describe("cmd_stop", () => {
|
|
324
|
+
// `ps` reports the server alive for the first `alive` checks, then gone.
|
|
325
|
+
// A server that takes a moment to exit used to trip `((count++))` (status 1
|
|
326
|
+
// at 0) under `set -e`, so stop exited 1 after the server had stopped.
|
|
327
|
+
const stop = (alive: number) => {
|
|
328
|
+
mkdirSync(join(dir, "home"), { recursive: true });
|
|
329
|
+
fake(
|
|
330
|
+
"ps",
|
|
331
|
+
`n=$(cat "${dir}/ps-count" 2>/dev/null || echo 0); echo $((n + 1)) > "${dir}/ps-count"; [ "$n" -lt ${alive} ]`
|
|
332
|
+
);
|
|
333
|
+
fake("sleep", "exit 0");
|
|
334
|
+
return run(
|
|
335
|
+
`AGENT_OS_HOME="${dir}/home"; PID_FILE="$AGENT_OS_HOME/agent-os.pid"; echo $$ > "$PID_FILE"; kill() { return 0; }; cmd_stop`,
|
|
336
|
+
""
|
|
337
|
+
);
|
|
338
|
+
};
|
|
339
|
+
|
|
340
|
+
it("returns 0 when the server exits after a few checks", () => {
|
|
341
|
+
const r = stop(3);
|
|
342
|
+
expect(r.status).toBe(0);
|
|
343
|
+
expect(r.stdout).toContain("AgentOS stopped");
|
|
344
|
+
expect(existsSync(join(dir, "home", "agent-os.pid"))).toBe(false);
|
|
345
|
+
});
|
|
346
|
+
|
|
347
|
+
it("force kills and still returns 0 when it outlives the timeout", () => {
|
|
348
|
+
const r = stop(1000);
|
|
349
|
+
expect(r.status).toBe(0);
|
|
350
|
+
expect(r.stdout).toContain("Force killing");
|
|
351
|
+
});
|
|
352
|
+
|
|
353
|
+
it("has no bare ((x++)) in scripts/lib: it returns 1 at 0 under set -e", () => {
|
|
354
|
+
for (const f of [
|
|
355
|
+
"commands.sh",
|
|
356
|
+
"common.sh",
|
|
357
|
+
"machine.sh",
|
|
358
|
+
"prerequisites.sh",
|
|
359
|
+
]) {
|
|
360
|
+
expect(readFileSync(join(LIB, f), "utf8"), f).not.toMatch(
|
|
361
|
+
/^\s*\(\(\s*\w+(\+\+|--)\s*\)\)\s*$/m
|
|
362
|
+
);
|
|
363
|
+
}
|
|
364
|
+
});
|
|
365
|
+
});
|
package/server.ts
CHANGED
|
@@ -47,6 +47,7 @@ import {
|
|
|
47
47
|
refuseNextInternal,
|
|
48
48
|
} from "./lib/security/next-internals";
|
|
49
49
|
import { lanEnabled } from "./lib/security/network-settings";
|
|
50
|
+
import { handlePeerRpc, isPeerRpc, rpcDeps } from "./lib/peer/rpc-server";
|
|
50
51
|
import { startConnect } from "./lib/connect/serve";
|
|
51
52
|
import { serverPort } from "./lib/connect/config";
|
|
52
53
|
import { startUpdateChecks, updateChecksEnabled } from "./lib/updates/check";
|
|
@@ -150,6 +151,7 @@ app.prepare().then(async () => {
|
|
|
150
151
|
.map((h) => h.trim().toLowerCase())
|
|
151
152
|
.filter(Boolean);
|
|
152
153
|
const auth = authPolicy();
|
|
154
|
+
const peerRpc = rpcDeps(port);
|
|
153
155
|
const header = (v: string | string[] | undefined) =>
|
|
154
156
|
Array.isArray(v) ? v[0] : v;
|
|
155
157
|
|
|
@@ -177,6 +179,22 @@ app.prepare().then(async () => {
|
|
|
177
179
|
if (refuseNextInternal(req, res)) return;
|
|
178
180
|
if (!gateRequest(req, res, auth)) return;
|
|
179
181
|
if (demo && !gateDemoRequest(req, res)) return;
|
|
182
|
+
// A linked machine's envelope: verified, then re-issued to loopback.
|
|
183
|
+
if (isPeerRpc(req)) {
|
|
184
|
+
if (demo) {
|
|
185
|
+
res.statusCode = 404;
|
|
186
|
+
res.end();
|
|
187
|
+
return;
|
|
188
|
+
}
|
|
189
|
+
try {
|
|
190
|
+
await handlePeerRpc(req, res, peerRpc);
|
|
191
|
+
} catch (err) {
|
|
192
|
+
console.error("peer rpc failed:", err);
|
|
193
|
+
if (!res.headersSent) res.statusCode = 500;
|
|
194
|
+
res.end();
|
|
195
|
+
}
|
|
196
|
+
return;
|
|
197
|
+
}
|
|
180
198
|
try {
|
|
181
199
|
await compressJson(req, res);
|
|
182
200
|
const parsedUrl = parse(req.url!, true);
|