@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.
Files changed (124) hide show
  1. package/docs/PLATFORM_RUNTIME_EVENTS.md +48 -0
  2. package/docs/RELEASES.md +7 -7
  3. package/docs/SOURCE_ARCHITECTURE.md +58 -0
  4. package/docs/TEST_TIERS.md +26 -0
  5. package/migrations/runtime/0001_cli_runtime.sql +298 -0
  6. package/package.json +28 -7
  7. package/packages/agentsam-repository/README.md +15 -0
  8. package/packages/agentsam-repository/package.json +25 -0
  9. package/packages/agentsam-repository/src/contracts.js +113 -0
  10. package/packages/agentsam-repository/src/index.js +3 -0
  11. package/{src/lib → packages/agentsam-repository/src}/merkle/cloudflare-persistence.js +14 -24
  12. package/{src/lib → packages/agentsam-repository/src}/merkle/index.js +1 -0
  13. package/{src/lib → packages/agentsam-repository/src}/merkle/persistence.js +6 -4
  14. package/{src/lib → packages/agentsam-repository/src}/merkle/policy.js +1 -0
  15. package/packages/agentsam-repository/test/contracts.test.mjs +40 -0
  16. package/packages/agentsam-repository/test/git-context.test.mjs +24 -0
  17. package/{test/merkle.test.mjs → packages/agentsam-repository/test/merkle-core.test.mjs} +2 -32
  18. package/{test → packages/agentsam-repository/test}/merkle-persistence.test.mjs +11 -6
  19. package/packages/identity/package.json +1 -1
  20. package/protocol/COMPANY_REPOSITORY_GRAPH_V1.md +91 -0
  21. package/protocol/MERKLE_PERSISTENCE_V1.md +2 -0
  22. package/protocol/MERKLE_PERSISTENCE_V2.md +40 -0
  23. package/protocol/repository/repository-contract.schema.json +24 -0
  24. package/protocol/repository/repository-dependency.schema.json +24 -0
  25. package/protocol/repository/repository-identity.schema.json +17 -0
  26. package/protocol/rpc/v1/common.proto +16 -0
  27. package/protocol/rpc/v1/errors.proto +35 -0
  28. package/protocol/rpc/v1/knowledge.proto +77 -0
  29. package/services/knowledge/package-lock.json +333 -0
  30. package/services/knowledge/package.json +5 -1
  31. package/src/agent/responses-runner.js +63 -35
  32. package/src/capabilities/repository-snapshot.js +3 -3
  33. package/src/cli.js +23 -6
  34. package/src/commands/context-economics.js +17 -2
  35. package/src/commands/context.js +1 -1
  36. package/src/commands/db.js +20 -3
  37. package/src/commands/env.js +90 -0
  38. package/src/commands/knowledge.js +12 -4
  39. package/src/commands/merkle-persist.js +30 -11
  40. package/src/commands/merkle.js +1 -1
  41. package/src/commands/models.js +123 -65
  42. package/src/commands/ollama.js +26 -0
  43. package/src/commands/preferences.js +53 -26
  44. package/src/commands/shell.js +236 -48
  45. package/src/errors/contract.js +236 -0
  46. package/src/errors/index.js +14 -0
  47. package/src/index.js +13 -1
  48. package/src/knowledge/service/auth.js +13 -0
  49. package/src/knowledge/service/grpc-client.js +115 -0
  50. package/src/knowledge/service/grpc-codec.js +237 -0
  51. package/src/knowledge/service/grpc-server.js +83 -0
  52. package/src/knowledge/service/job-engine.js +248 -0
  53. package/src/knowledge/service/server.js +87 -135
  54. package/src/knowledge/source.js +1 -1
  55. package/src/lib/cli-preferences.js +31 -4
  56. package/src/lib/deploy-receipt/index.js +2 -2
  57. package/src/lib/knowledge-docker.js +6 -3
  58. package/src/lib/local-sessions.js +23 -2
  59. package/src/lib/local-status.js +1 -1
  60. package/src/lib/project-config.js +1 -1
  61. package/src/lib/provider-credentials.js +105 -5
  62. package/src/lib/slash-commands.js +4 -3
  63. package/src/local/migrations.js +93 -0
  64. package/src/local/runtime-store.js +141 -0
  65. package/src/local/sqlite.js +2 -0
  66. package/src/local-pty/server.js +113 -51
  67. package/src/models/discovery.js +292 -0
  68. package/src/providers/anthropic-messages.js +192 -0
  69. package/src/providers/cloudflare-chat.js +183 -0
  70. package/src/providers/factory.js +69 -0
  71. package/src/providers/gemini-generate-content.js +208 -0
  72. package/src/providers/index.js +5 -0
  73. package/src/providers/ollama-chat.js +148 -0
  74. package/src/providers/openai-responses.js +226 -75
  75. package/src/repository/index.js +14 -2
  76. package/src/rpc/generated/common_grpc_pb.js +1 -0
  77. package/src/rpc/generated/common_pb.js +536 -0
  78. package/src/rpc/generated/errors_grpc_pb.js +1 -0
  79. package/src/rpc/generated/errors_pb.js +482 -0
  80. package/src/rpc/generated/knowledge_grpc_pb.js +135 -0
  81. package/src/rpc/generated/knowledge_pb.js +2168 -0
  82. package/src/rpc/generated/package.json +3 -0
  83. package/src/security/trust-boundary.js +2 -2
  84. package/src/telemetry/events.js +4 -1
  85. package/src/ui/cli/activity.js +76 -0
  86. package/src/ui/cli/compaction.js +15 -0
  87. package/src/ui/cli/footer.js +39 -0
  88. package/src/ui/cli/help.js +192 -0
  89. package/src/ui/cli/plan.js +20 -0
  90. package/src/ui/cli/runtime-events.js +110 -0
  91. package/src/ui/cli/waiting.js +16 -0
  92. package/src/ui/merkle/render.js +1 -1
  93. package/test/cli/preferences-runtime.test.mjs +11 -0
  94. package/test/cli/runtime-ui.test.mjs +74 -0
  95. package/test/error-diagnostics.test.mjs +57 -1
  96. package/test/fixtures/knowledge-rpc-worker.mjs +16 -0
  97. package/test/integration/cli-help.test.mjs +37 -0
  98. package/test/integration/knowledge-rpc.test.mjs +112 -0
  99. package/test/integration/merkle-cli.test.mjs +61 -0
  100. package/test/integration/merkle-persistence-identity.test.mjs +48 -0
  101. package/test/integration/provider-env-cli.test.mjs +49 -0
  102. package/test/integration/provider-factory.test.mjs +197 -0
  103. package/test/integration/repository-company-graph.test.mjs +90 -0
  104. package/test/integration/runtime-migrations.test.mjs +82 -0
  105. package/test/knowledge-service.test.mjs +5 -0
  106. package/test/knowledge.test.mjs +16 -0
  107. package/test/live/terminal-transport.live.test.mjs +24 -0
  108. package/test/local-sessions.test.mjs +7 -1
  109. package/test/models.test.mjs +101 -4
  110. package/test/ollama.test.mjs +21 -0
  111. package/test/portable-context.test.mjs +1 -1
  112. package/test/provider-credentials.test.mjs +45 -1
  113. package/test/release-hygiene.test.mjs +13 -5
  114. package/test/responses-runner.test.mjs +3 -1
  115. package/test/shell.test.mjs +50 -8
  116. package/test/terminal/local-pty.mock.test.mjs +151 -0
  117. /package/{src/lib → packages/agentsam-repository/src}/git-context.js +0 -0
  118. /package/{src/lib → packages/agentsam-repository/src}/merkle/diff.js +0 -0
  119. /package/{src/lib → packages/agentsam-repository/src}/merkle/filemeta.js +0 -0
  120. /package/{src/lib → packages/agentsam-repository/src}/merkle/git-ignore.js +0 -0
  121. /package/{src/lib → packages/agentsam-repository/src}/merkle/hash.js +0 -0
  122. /package/{src/lib → packages/agentsam-repository/src}/merkle/semantic.js +0 -0
  123. /package/{src/lib → packages/agentsam-repository/src}/merkle/snapshot.js +0 -0
  124. /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
+ });