@inneranimalmedia/agentsam-sdk 2.6.0 → 2.6.1
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/docs/PLATFORM_RUNTIME_EVENTS.md +48 -0
- package/docs/RELEASES.md +7 -7
- package/docs/SOURCE_ARCHITECTURE.md +58 -0
- package/docs/TEST_TIERS.md +26 -0
- package/migrations/runtime/0001_cli_runtime.sql +298 -0
- package/package.json +28 -7
- package/packages/agentsam-repository/README.md +15 -0
- package/packages/agentsam-repository/package.json +25 -0
- package/packages/agentsam-repository/src/contracts.js +113 -0
- package/packages/agentsam-repository/src/index.js +3 -0
- package/{src/lib → packages/agentsam-repository/src}/merkle/cloudflare-persistence.js +14 -24
- package/{src/lib → packages/agentsam-repository/src}/merkle/index.js +1 -0
- package/{src/lib → packages/agentsam-repository/src}/merkle/persistence.js +6 -4
- package/{src/lib → packages/agentsam-repository/src}/merkle/policy.js +1 -0
- package/packages/agentsam-repository/test/contracts.test.mjs +40 -0
- package/packages/agentsam-repository/test/git-context.test.mjs +24 -0
- package/{test/merkle.test.mjs → packages/agentsam-repository/test/merkle-core.test.mjs} +2 -32
- package/{test → packages/agentsam-repository/test}/merkle-persistence.test.mjs +11 -6
- package/packages/identity/package.json +1 -1
- package/protocol/COMPANY_REPOSITORY_GRAPH_V1.md +91 -0
- package/protocol/MERKLE_PERSISTENCE_V1.md +2 -0
- package/protocol/MERKLE_PERSISTENCE_V2.md +40 -0
- package/protocol/repository/repository-contract.schema.json +24 -0
- package/protocol/repository/repository-dependency.schema.json +24 -0
- package/protocol/repository/repository-identity.schema.json +17 -0
- package/protocol/rpc/v1/common.proto +16 -0
- package/protocol/rpc/v1/errors.proto +35 -0
- package/protocol/rpc/v1/knowledge.proto +77 -0
- package/services/knowledge/package-lock.json +333 -0
- package/services/knowledge/package.json +5 -1
- package/src/agent/responses-runner.js +63 -35
- package/src/capabilities/repository-snapshot.js +3 -3
- package/src/cli.js +23 -6
- package/src/commands/context-economics.js +17 -2
- package/src/commands/context.js +1 -1
- package/src/commands/db.js +20 -3
- package/src/commands/env.js +90 -0
- package/src/commands/knowledge.js +12 -4
- package/src/commands/merkle-persist.js +30 -11
- package/src/commands/merkle.js +1 -1
- package/src/commands/models.js +123 -65
- package/src/commands/ollama.js +26 -0
- package/src/commands/preferences.js +53 -26
- package/src/commands/shell.js +236 -48
- package/src/errors/contract.js +236 -0
- package/src/errors/index.js +14 -0
- package/src/index.js +13 -1
- package/src/knowledge/service/auth.js +13 -0
- package/src/knowledge/service/grpc-client.js +115 -0
- package/src/knowledge/service/grpc-codec.js +237 -0
- package/src/knowledge/service/grpc-server.js +83 -0
- package/src/knowledge/service/job-engine.js +248 -0
- package/src/knowledge/service/server.js +87 -135
- package/src/knowledge/source.js +1 -1
- package/src/lib/cli-preferences.js +31 -4
- package/src/lib/deploy-receipt/index.js +2 -2
- package/src/lib/knowledge-docker.js +6 -3
- package/src/lib/local-sessions.js +23 -2
- package/src/lib/local-status.js +1 -1
- package/src/lib/project-config.js +1 -1
- package/src/lib/provider-credentials.js +105 -5
- package/src/lib/slash-commands.js +4 -3
- package/src/local/migrations.js +93 -0
- package/src/local/runtime-store.js +141 -0
- package/src/local/sqlite.js +2 -0
- package/src/local-pty/server.js +113 -51
- package/src/models/discovery.js +292 -0
- package/src/providers/anthropic-messages.js +192 -0
- package/src/providers/cloudflare-chat.js +183 -0
- package/src/providers/factory.js +69 -0
- package/src/providers/gemini-generate-content.js +208 -0
- package/src/providers/index.js +5 -0
- package/src/providers/ollama-chat.js +148 -0
- package/src/providers/openai-responses.js +226 -75
- package/src/repository/index.js +14 -2
- package/src/rpc/generated/common_grpc_pb.js +1 -0
- package/src/rpc/generated/common_pb.js +536 -0
- package/src/rpc/generated/errors_grpc_pb.js +1 -0
- package/src/rpc/generated/errors_pb.js +482 -0
- package/src/rpc/generated/knowledge_grpc_pb.js +135 -0
- package/src/rpc/generated/knowledge_pb.js +2168 -0
- package/src/rpc/generated/package.json +3 -0
- package/src/security/trust-boundary.js +2 -2
- package/src/telemetry/events.js +4 -1
- package/src/ui/cli/activity.js +76 -0
- package/src/ui/cli/compaction.js +15 -0
- package/src/ui/cli/footer.js +39 -0
- package/src/ui/cli/help.js +192 -0
- package/src/ui/cli/plan.js +20 -0
- package/src/ui/cli/runtime-events.js +110 -0
- package/src/ui/cli/waiting.js +16 -0
- package/src/ui/merkle/render.js +1 -1
- package/test/cli/preferences-runtime.test.mjs +11 -0
- package/test/cli/runtime-ui.test.mjs +74 -0
- package/test/error-diagnostics.test.mjs +57 -1
- package/test/fixtures/knowledge-rpc-worker.mjs +16 -0
- package/test/integration/cli-help.test.mjs +37 -0
- package/test/integration/knowledge-rpc.test.mjs +112 -0
- package/test/integration/merkle-cli.test.mjs +61 -0
- package/test/integration/merkle-persistence-identity.test.mjs +48 -0
- package/test/integration/provider-env-cli.test.mjs +49 -0
- package/test/integration/provider-factory.test.mjs +197 -0
- package/test/integration/repository-company-graph.test.mjs +90 -0
- package/test/integration/runtime-migrations.test.mjs +82 -0
- package/test/knowledge-service.test.mjs +5 -0
- package/test/knowledge.test.mjs +16 -0
- package/test/live/terminal-transport.live.test.mjs +24 -0
- package/test/local-sessions.test.mjs +7 -1
- package/test/models.test.mjs +101 -4
- package/test/ollama.test.mjs +21 -0
- package/test/portable-context.test.mjs +1 -1
- package/test/provider-credentials.test.mjs +45 -1
- package/test/release-hygiene.test.mjs +13 -5
- package/test/responses-runner.test.mjs +3 -1
- package/test/shell.test.mjs +50 -8
- package/test/terminal/local-pty.mock.test.mjs +151 -0
- /package/{src/lib → packages/agentsam-repository/src}/git-context.js +0 -0
- /package/{src/lib → packages/agentsam-repository/src}/merkle/diff.js +0 -0
- /package/{src/lib → packages/agentsam-repository/src}/merkle/filemeta.js +0 -0
- /package/{src/lib → packages/agentsam-repository/src}/merkle/git-ignore.js +0 -0
- /package/{src/lib → packages/agentsam-repository/src}/merkle/hash.js +0 -0
- /package/{src/lib → packages/agentsam-repository/src}/merkle/semantic.js +0 -0
- /package/{src/lib → packages/agentsam-repository/src}/merkle/snapshot.js +0 -0
- /package/{src/lib → packages/agentsam-repository/src}/merkle/tree.js +0 -0
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
import assert from 'node:assert/strict';
|
|
2
|
+
import { EventEmitter } from 'node:events';
|
|
3
|
+
import fs from 'node:fs';
|
|
4
|
+
import os from 'node:os';
|
|
5
|
+
import path from 'node:path';
|
|
6
|
+
import test from 'node:test';
|
|
7
|
+
import { pathToFileURL } from 'node:url';
|
|
8
|
+
import {
|
|
9
|
+
attachLocalPtySession,
|
|
10
|
+
ensureNodePtySpawnHelperExecutable,
|
|
11
|
+
startLocalPtyServer,
|
|
12
|
+
} from '../../src/local-pty/server.js';
|
|
13
|
+
|
|
14
|
+
function fakeTransports() {
|
|
15
|
+
const writes = [];
|
|
16
|
+
const resizes = [];
|
|
17
|
+
let killed = 0;
|
|
18
|
+
let dataHandler = null;
|
|
19
|
+
let exitHandler = null;
|
|
20
|
+
|
|
21
|
+
const pty = {
|
|
22
|
+
spawn(shell, args, options) {
|
|
23
|
+
assert.equal(Array.isArray(args), true);
|
|
24
|
+
assert.equal(options.env.AGENTSAM_LOCAL_PTY, '1');
|
|
25
|
+
return {
|
|
26
|
+
write(value) { writes.push(value); },
|
|
27
|
+
resize(cols, rows) { resizes.push([cols, rows]); },
|
|
28
|
+
kill() { killed += 1; },
|
|
29
|
+
onData(fn) { dataHandler = fn; },
|
|
30
|
+
onExit(fn) { exitHandler = fn; },
|
|
31
|
+
};
|
|
32
|
+
},
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
class FakeWs extends EventEmitter {
|
|
36
|
+
OPEN = 1;
|
|
37
|
+
readyState = 1;
|
|
38
|
+
sent = [];
|
|
39
|
+
send(value) { this.sent.push(String(value)); }
|
|
40
|
+
close() {
|
|
41
|
+
if (this.readyState !== this.OPEN) return;
|
|
42
|
+
this.readyState = 3;
|
|
43
|
+
this.emit('close');
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const ws = new FakeWs();
|
|
48
|
+
return {
|
|
49
|
+
pty,
|
|
50
|
+
ws,
|
|
51
|
+
writes,
|
|
52
|
+
resizes,
|
|
53
|
+
killed: () => killed,
|
|
54
|
+
emitData(value) { dataHandler?.(value); },
|
|
55
|
+
emitExit() { exitHandler?.(); },
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
test('macOS node-pty helper is made executable before runtime import', (t) => {
|
|
60
|
+
const root = fs.mkdtempSync(path.join(os.tmpdir(), 'agentsam-node-pty-helper-'));
|
|
61
|
+
t.after(() => fs.rmSync(root, { recursive: true, force: true }));
|
|
62
|
+
const libDir = path.join(root, 'lib');
|
|
63
|
+
const helperDir = path.join(root, 'prebuilds', 'darwin-arm64');
|
|
64
|
+
fs.mkdirSync(libDir, { recursive: true });
|
|
65
|
+
fs.mkdirSync(helperDir, { recursive: true });
|
|
66
|
+
fs.writeFileSync(path.join(libDir, 'index.js'), '');
|
|
67
|
+
const helper = path.join(helperDir, 'spawn-helper');
|
|
68
|
+
fs.writeFileSync(helper, 'fake');
|
|
69
|
+
fs.chmodSync(helper, 0o644);
|
|
70
|
+
|
|
71
|
+
const result = ensureNodePtySpawnHelperExecutable({
|
|
72
|
+
platform: 'darwin',
|
|
73
|
+
arch: 'arm64',
|
|
74
|
+
resolveModule: () => pathToFileURL(path.join(libDir, 'index.js')).href,
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
assert.equal(result.checked, true);
|
|
78
|
+
assert.equal(result.changed, true);
|
|
79
|
+
assert.equal(result.path, helper);
|
|
80
|
+
assert.notEqual(fs.statSync(helper).mode & 0o111, 0);
|
|
81
|
+
|
|
82
|
+
const second = ensureNodePtySpawnHelperExecutable({
|
|
83
|
+
platform: 'darwin',
|
|
84
|
+
arch: 'arm64',
|
|
85
|
+
resolveModule: () => pathToFileURL(path.join(libDir, 'index.js')).href,
|
|
86
|
+
});
|
|
87
|
+
assert.equal(second.changed, false);
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
test('local PTY wire protocol is release-testable entirely in memory', () => {
|
|
91
|
+
const transport = fakeTransports();
|
|
92
|
+
const session = attachLocalPtySession({
|
|
93
|
+
ws: transport.ws,
|
|
94
|
+
pty: transport.pty,
|
|
95
|
+
shell: '/bin/test-shell',
|
|
96
|
+
cwd: '/tmp/test-project',
|
|
97
|
+
cols: 80,
|
|
98
|
+
rows: 24,
|
|
99
|
+
env: {},
|
|
100
|
+
sessionId: 'local_test',
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
assert.equal(session.session_id, 'local_test');
|
|
104
|
+
assert.deepEqual(JSON.parse(transport.ws.sent[0]), {
|
|
105
|
+
type: 'session_id',
|
|
106
|
+
session_id: 'local_test',
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
transport.ws.emit('message', Buffer.from(JSON.stringify({ type: 'resize', cols: 120, rows: 40 })));
|
|
110
|
+
transport.ws.emit('message', Buffer.from(JSON.stringify({ type: 'slash', line: '/pwd' })));
|
|
111
|
+
transport.ws.emit('message', Buffer.from('raw input'));
|
|
112
|
+
|
|
113
|
+
assert.deepEqual(transport.resizes, [[120, 40]]);
|
|
114
|
+
assert.deepEqual(transport.writes, ['/pwd\r', 'raw input']);
|
|
115
|
+
|
|
116
|
+
transport.emitData('terminal output');
|
|
117
|
+
assert.equal(transport.ws.sent.at(-1), 'terminal output');
|
|
118
|
+
|
|
119
|
+
transport.ws.close();
|
|
120
|
+
assert.equal(transport.killed(), 1);
|
|
121
|
+
|
|
122
|
+
// Cleanup is idempotent even when transport error/close paths race.
|
|
123
|
+
transport.ws.emit('error', new Error('synthetic transport close'));
|
|
124
|
+
session.cleanup();
|
|
125
|
+
assert.equal(transport.killed(), 1);
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
test('local PTY server health check uses an ephemeral local port and no ExecOS tunnel', async () => {
|
|
129
|
+
const transport = fakeTransports();
|
|
130
|
+
const server = await startLocalPtyServer({
|
|
131
|
+
cwd: process.cwd(),
|
|
132
|
+
host: '127.0.0.1',
|
|
133
|
+
port: 0,
|
|
134
|
+
pty: transport.pty,
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
try {
|
|
138
|
+
const health = await fetch(server.healthUrl);
|
|
139
|
+
assert.equal(health.status, 200);
|
|
140
|
+
const body = await health.json();
|
|
141
|
+
assert.equal(body.ok, true);
|
|
142
|
+
assert.equal(body.service, 'agentsam-local-pty');
|
|
143
|
+
assert.equal(body.port, server.port);
|
|
144
|
+
assert.equal(server.port > 0, true);
|
|
145
|
+
} finally {
|
|
146
|
+
await server.close();
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
// No WebSocket session was opened, so the PTY process was never spawned.
|
|
150
|
+
assert.equal(transport.killed(), 0);
|
|
151
|
+
});
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|