@ash-ai/shared 0.0.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Ash Contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=protocol.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"protocol.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/protocol.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,105 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { encode, decode } from '../index.js';
3
+ describe('protocol', () => {
4
+ describe('encode/decode round-trip', () => {
5
+ it('round-trips a query command', () => {
6
+ const cmd = { cmd: 'query', prompt: 'hello', sessionId: 's1' };
7
+ const decoded = decode(encode(cmd));
8
+ expect(decoded).toEqual(cmd);
9
+ });
10
+ it('round-trips a resume command', () => {
11
+ const cmd = { cmd: 'resume', sessionId: 's1' };
12
+ const decoded = decode(encode(cmd));
13
+ expect(decoded).toEqual(cmd);
14
+ });
15
+ it('round-trips an interrupt command', () => {
16
+ const cmd = { cmd: 'interrupt' };
17
+ const decoded = decode(encode(cmd));
18
+ expect(decoded).toEqual(cmd);
19
+ });
20
+ it('round-trips a shutdown command', () => {
21
+ const cmd = { cmd: 'shutdown' };
22
+ const decoded = decode(encode(cmd));
23
+ expect(decoded).toEqual(cmd);
24
+ });
25
+ it('round-trips a ready event', () => {
26
+ const ev = { ev: 'ready' };
27
+ const decoded = decode(encode(ev));
28
+ expect(decoded).toEqual(ev);
29
+ });
30
+ it('round-trips a message event with SDK data', () => {
31
+ const sdkMessage = {
32
+ type: 'assistant',
33
+ message: { role: 'assistant', content: [{ type: 'text', text: 'hi' }] },
34
+ session_id: 's1',
35
+ };
36
+ const ev = { ev: 'message', data: sdkMessage };
37
+ const decoded = decode(encode(ev));
38
+ expect(decoded.ev).toBe('message');
39
+ expect(decoded).toEqual(ev);
40
+ });
41
+ it('round-trips an error event', () => {
42
+ const ev = { ev: 'error', error: 'something broke' };
43
+ const decoded = decode(encode(ev));
44
+ expect(decoded).toEqual(ev);
45
+ });
46
+ it('round-trips a done event', () => {
47
+ const ev = { ev: 'done', sessionId: 's1' };
48
+ const decoded = decode(encode(ev));
49
+ expect(decoded).toEqual(ev);
50
+ });
51
+ });
52
+ describe('encode', () => {
53
+ it('produces newline-terminated JSON', () => {
54
+ const encoded = encode({ cmd: 'interrupt' });
55
+ expect(encoded).toMatch(/\n$/);
56
+ expect(encoded.split('\n').length).toBe(2); // content + empty after newline
57
+ });
58
+ it('is single-line (no embedded newlines)', () => {
59
+ const ev = { ev: 'message', data: { text: 'line1\nline2' } };
60
+ const encoded = encode(ev);
61
+ const lines = encoded.trimEnd().split('\n');
62
+ expect(lines.length).toBe(1);
63
+ });
64
+ });
65
+ describe('decode', () => {
66
+ it('handles leading/trailing whitespace', () => {
67
+ const cmd = { cmd: 'interrupt' };
68
+ const decoded = decode(' ' + JSON.stringify(cmd) + ' \n');
69
+ expect(decoded).toEqual(cmd);
70
+ });
71
+ it('throws on invalid JSON', () => {
72
+ expect(() => decode('not json')).toThrow();
73
+ });
74
+ it('throws on empty string', () => {
75
+ expect(() => decode('')).toThrow();
76
+ });
77
+ });
78
+ describe('SDK message passthrough', () => {
79
+ it('preserves complex nested SDK message structure', () => {
80
+ const sdkResult = {
81
+ type: 'result',
82
+ subtype: 'success',
83
+ session_id: 'abc-123',
84
+ cost_usd: 0.0042,
85
+ duration_ms: 1500,
86
+ duration_api_ms: 1200,
87
+ is_error: false,
88
+ num_turns: 3,
89
+ result: 'Done!',
90
+ };
91
+ const ev = { ev: 'message', data: sdkResult };
92
+ const decoded = decode(encode(ev));
93
+ expect(decoded.data).toEqual(sdkResult);
94
+ });
95
+ it('preserves unicode in SDK messages', () => {
96
+ const ev = {
97
+ ev: 'message',
98
+ data: { type: 'assistant', content: '你好世界 🌍 émojis' },
99
+ };
100
+ const decoded = decode(encode(ev));
101
+ expect(decoded.data.content).toBe('你好世界 🌍 émojis');
102
+ });
103
+ });
104
+ });
105
+ //# sourceMappingURL=protocol.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"protocol.test.js","sourceRoot":"","sources":["../../src/__tests__/protocol.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=timing.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"timing.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/timing.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,101 @@
1
+ import { describe, it, expect, beforeEach, afterEach } from 'vitest';
2
+ import { startTimer, logTiming, timingEnabled } from '../timing.js';
3
+ describe('timing', () => {
4
+ const originalEnv = process.env.ASH_DEBUG_TIMING;
5
+ afterEach(() => {
6
+ if (originalEnv === undefined) {
7
+ delete process.env.ASH_DEBUG_TIMING;
8
+ }
9
+ else {
10
+ process.env.ASH_DEBUG_TIMING = originalEnv;
11
+ }
12
+ });
13
+ describe('timingEnabled', () => {
14
+ it('returns false when ASH_DEBUG_TIMING is not set', () => {
15
+ delete process.env.ASH_DEBUG_TIMING;
16
+ expect(timingEnabled()).toBe(false);
17
+ });
18
+ it('returns false when ASH_DEBUG_TIMING is "0"', () => {
19
+ process.env.ASH_DEBUG_TIMING = '0';
20
+ expect(timingEnabled()).toBe(false);
21
+ });
22
+ it('returns true when ASH_DEBUG_TIMING is "1"', () => {
23
+ process.env.ASH_DEBUG_TIMING = '1';
24
+ expect(timingEnabled()).toBe(true);
25
+ });
26
+ });
27
+ describe('startTimer', () => {
28
+ it('returns a function', () => {
29
+ const elapsed = startTimer();
30
+ expect(typeof elapsed).toBe('function');
31
+ });
32
+ it('returns elapsed time in milliseconds', () => {
33
+ const elapsed = startTimer();
34
+ // Spin briefly so elapsed > 0
35
+ const start = Date.now();
36
+ while (Date.now() - start < 5) {
37
+ // busy wait ~5ms
38
+ }
39
+ const ms = elapsed();
40
+ expect(ms).toBeGreaterThan(0);
41
+ expect(ms).toBeLessThan(1000); // sanity: less than 1 second
42
+ });
43
+ it('returns increasing values on successive calls', () => {
44
+ const elapsed = startTimer();
45
+ const first = elapsed();
46
+ // Tiny spin
47
+ const start = Date.now();
48
+ while (Date.now() - start < 2) {
49
+ // busy wait
50
+ }
51
+ const second = elapsed();
52
+ expect(second).toBeGreaterThan(first);
53
+ });
54
+ });
55
+ describe('logTiming', () => {
56
+ let stderrWrite;
57
+ const calls = [];
58
+ beforeEach(() => {
59
+ calls.length = 0;
60
+ stderrWrite = process.stderr.write;
61
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
62
+ process.stderr.write = ((chunk) => {
63
+ calls.push(String(chunk));
64
+ return true;
65
+ });
66
+ });
67
+ afterEach(() => {
68
+ process.stderr.write = stderrWrite;
69
+ });
70
+ it('writes JSON line to stderr when enabled', () => {
71
+ process.env.ASH_DEBUG_TIMING = '1';
72
+ const entry = {
73
+ type: 'timing',
74
+ source: 'server',
75
+ sessionId: 's1',
76
+ lookupMs: 0.1,
77
+ timestamp: '2025-01-15T00:00:00.000Z',
78
+ };
79
+ logTiming(entry);
80
+ expect(calls.length).toBe(1);
81
+ const written = calls[0];
82
+ expect(written).toMatch(/\n$/);
83
+ const parsed = JSON.parse(written.trim());
84
+ expect(parsed.type).toBe('timing');
85
+ expect(parsed.source).toBe('server');
86
+ expect(parsed.sessionId).toBe('s1');
87
+ expect(parsed.lookupMs).toBe(0.1);
88
+ });
89
+ it('is a no-op when disabled', () => {
90
+ delete process.env.ASH_DEBUG_TIMING;
91
+ logTiming({
92
+ type: 'timing',
93
+ source: 'bridge',
94
+ sessionId: 's1',
95
+ timestamp: '2025-01-15T00:00:00.000Z',
96
+ });
97
+ expect(calls.length).toBe(0);
98
+ });
99
+ });
100
+ });
101
+ //# sourceMappingURL=timing.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"timing.test.js","sourceRoot":"","sources":["../../src/__tests__/timing.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/types.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,51 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { extractStreamDelta, extractTextFromEvent } from '../types.js';
3
+ describe('extractStreamDelta', () => {
4
+ it('returns text from a text_delta stream event', () => {
5
+ const data = {
6
+ type: 'stream_event',
7
+ event: {
8
+ type: 'content_block_delta',
9
+ index: 0,
10
+ delta: { type: 'text_delta', text: 'Hello' },
11
+ },
12
+ };
13
+ expect(extractStreamDelta(data)).toBe('Hello');
14
+ });
15
+ it('returns null for non-stream_event messages', () => {
16
+ expect(extractStreamDelta({ type: 'assistant', message: { content: [] } })).toBeNull();
17
+ expect(extractStreamDelta({ type: 'result' })).toBeNull();
18
+ });
19
+ it('returns null for stream events that are not content_block_delta', () => {
20
+ expect(extractStreamDelta({ type: 'stream_event', event: { type: 'message_start' } })).toBeNull();
21
+ expect(extractStreamDelta({ type: 'stream_event', event: { type: 'content_block_stop' } })).toBeNull();
22
+ });
23
+ it('returns null for content_block_delta with non-text delta type', () => {
24
+ const data = {
25
+ type: 'stream_event',
26
+ event: {
27
+ type: 'content_block_delta',
28
+ index: 0,
29
+ delta: { type: 'input_json_delta', partial_json: '{"key":' },
30
+ },
31
+ };
32
+ expect(extractStreamDelta(data)).toBeNull();
33
+ });
34
+ });
35
+ describe('extractTextFromEvent', () => {
36
+ it('returns null for stream_event messages', () => {
37
+ const data = {
38
+ type: 'stream_event',
39
+ event: { type: 'content_block_delta', delta: { type: 'text_delta', text: 'hi' } },
40
+ };
41
+ expect(extractTextFromEvent(data)).toBeNull();
42
+ });
43
+ it('returns text from assistant messages', () => {
44
+ const data = {
45
+ type: 'assistant',
46
+ message: { content: [{ type: 'text', text: 'Hello world' }] },
47
+ };
48
+ expect(extractTextFromEvent(data)).toBe('Hello world');
49
+ });
50
+ });
51
+ //# sourceMappingURL=types.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.test.js","sourceRoot":"","sources":["../../src/__tests__/types.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAEvE,QAAQ,CAAC,oBAAoB,EAAE,GAAG,EAAE;IAClC,EAAE,CAAC,6CAA6C,EAAE,GAAG,EAAE;QACrD,MAAM,IAAI,GAAG;YACX,IAAI,EAAE,cAAc;YACpB,KAAK,EAAE;gBACL,IAAI,EAAE,qBAAqB;gBAC3B,KAAK,EAAE,CAAC;gBACR,KAAK,EAAE,EAAE,IAAI,EAAE,YAAY,EAAE,IAAI,EAAE,OAAO,EAAE;aAC7C;SACF,CAAC;QACF,MAAM,CAAC,kBAAkB,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACjD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,4CAA4C,EAAE,GAAG,EAAE;QACpD,MAAM,CAAC,kBAAkB,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC;QACvF,MAAM,CAAC,kBAAkB,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC;IAC5D,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,iEAAiE,EAAE,GAAG,EAAE;QACzE,MAAM,CAAC,kBAAkB,CAAC,EAAE,IAAI,EAAE,cAAc,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,eAAe,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC;QAClG,MAAM,CAAC,kBAAkB,CAAC,EAAE,IAAI,EAAE,cAAc,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,oBAAoB,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC;IACzG,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,+DAA+D,EAAE,GAAG,EAAE;QACvE,MAAM,IAAI,GAAG;YACX,IAAI,EAAE,cAAc;YACpB,KAAK,EAAE;gBACL,IAAI,EAAE,qBAAqB;gBAC3B,KAAK,EAAE,CAAC;gBACR,KAAK,EAAE,EAAE,IAAI,EAAE,kBAAkB,EAAE,YAAY,EAAE,SAAS,EAAE;aAC7D;SACF,CAAC;QACF,MAAM,CAAC,kBAAkB,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC;IAC9C,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,sBAAsB,EAAE,GAAG,EAAE;IACpC,EAAE,CAAC,wCAAwC,EAAE,GAAG,EAAE;QAChD,MAAM,IAAI,GAAG;YACX,IAAI,EAAE,cAAc;YACpB,KAAK,EAAE,EAAE,IAAI,EAAE,qBAAqB,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,YAAY,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE;SAClF,CAAC;QACF,MAAM,CAAC,oBAAoB,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC;IAChD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,sCAAsC,EAAE,GAAG,EAAE;QAC9C,MAAM,IAAI,GAAG;YACX,IAAI,EAAE,WAAW;YACjB,OAAO,EAAE,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,aAAa,EAAE,CAAC,EAAE;SAC9D,CAAC;QACF,MAAM,CAAC,oBAAoB,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;IACzD,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1,31 @@
1
+ export declare const DEFAULT_PORT = 4100;
2
+ export declare const DEFAULT_HOST = "0.0.0.0";
3
+ export declare const DEFAULT_DATA_DIR = "data";
4
+ export declare const SANDBOX_CONNECT_TIMEOUT_MS = 10000;
5
+ export declare const SANDBOX_SHUTDOWN_TIMEOUT_MS = 5000;
6
+ export declare const BRIDGE_READY_TIMEOUT_MS = 10000;
7
+ export declare const INSTALL_SCRIPT_TIMEOUT_MS = 120000;
8
+ export declare const DEFAULT_SANDBOX_LIMITS: {
9
+ readonly memoryMb: 2048;
10
+ readonly cpuPercent: 100;
11
+ readonly diskMb: 1024;
12
+ readonly maxProcesses: 64;
13
+ };
14
+ export declare const DISK_CHECK_INTERVAL_MS = 30000;
15
+ export declare const SSE_WRITE_TIMEOUT_MS = 30000;
16
+ export declare const SANDBOX_DOCKER_IMAGE = "node:20-slim";
17
+ export declare const ASH_CONTAINER_NAME = "ash-server";
18
+ export declare const ASH_DOCKER_IMAGE = "ghcr.io/ash-ai/ash";
19
+ export declare const ASH_DOCKER_TAG = "0.1.0";
20
+ export declare const ASH_DATA_DIR_CONTAINER = "/data";
21
+ export declare const ASH_AGENTS_SUBDIR = "agents";
22
+ export declare const ASH_HEALTH_POLL_INTERVAL_MS = 500;
23
+ export declare const ASH_HEALTH_POLL_TIMEOUT_MS = 30000;
24
+ export declare const DEFAULT_MAX_SANDBOXES = 1000;
25
+ export declare const DEFAULT_IDLE_TIMEOUT_MS: number;
26
+ export declare const IDLE_SWEEP_INTERVAL_MS = 60000;
27
+ export declare const DEFAULT_RUNNER_PORT = 4200;
28
+ export declare const RUNNER_HEARTBEAT_INTERVAL_MS = 10000;
29
+ export declare const RUNNER_LIVENESS_TIMEOUT_MS = 30000;
30
+ export declare const SANDBOX_ENV_ALLOWLIST: readonly ["PATH", "NODE_PATH", "HOME", "LANG", "TERM", "ANTHROPIC_API_KEY", "ASH_DEBUG_TIMING", "ASH_REAL_SDK", "CLAUDE_CODE_EXECUTABLE"];
31
+ //# sourceMappingURL=constants.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,YAAY,OAAO,CAAC;AACjC,eAAO,MAAM,YAAY,YAAY,CAAC;AACtC,eAAO,MAAM,gBAAgB,SAAS,CAAC;AAGvC,eAAO,MAAM,0BAA0B,QAAS,CAAC;AACjD,eAAO,MAAM,2BAA2B,OAAQ,CAAC;AAGjD,eAAO,MAAM,uBAAuB,QAAS,CAAC;AAG9C,eAAO,MAAM,yBAAyB,SAAU,CAAC;AAGjD,eAAO,MAAM,sBAAsB;;;;;CAKzB,CAAC;AAEX,eAAO,MAAM,sBAAsB,QAAS,CAAC;AAG7C,eAAO,MAAM,oBAAoB,QAAS,CAAC;AAG3C,eAAO,MAAM,oBAAoB,iBAAiB,CAAC;AAGnD,eAAO,MAAM,kBAAkB,eAAe,CAAC;AAC/C,eAAO,MAAM,gBAAgB,uBAAuB,CAAC;AACrD,eAAO,MAAM,cAAc,UAAU,CAAC;AACtC,eAAO,MAAM,sBAAsB,UAAU,CAAC;AAC9C,eAAO,MAAM,iBAAiB,WAAW,CAAC;AAC1C,eAAO,MAAM,2BAA2B,MAAM,CAAC;AAC/C,eAAO,MAAM,0BAA0B,QAAS,CAAC;AAGjD,eAAO,MAAM,qBAAqB,OAAO,CAAC;AAC1C,eAAO,MAAM,uBAAuB,QAAiB,CAAC;AACtD,eAAO,MAAM,sBAAsB,QAAS,CAAC;AAG7C,eAAO,MAAM,mBAAmB,OAAO,CAAC;AACxC,eAAO,MAAM,4BAA4B,QAAS,CAAC;AACnD,eAAO,MAAM,0BAA0B,QAAS,CAAC;AAGjD,eAAO,MAAM,qBAAqB,2IAUxB,CAAC"}
@@ -0,0 +1,51 @@
1
+ export const DEFAULT_PORT = 4100;
2
+ export const DEFAULT_HOST = '0.0.0.0';
3
+ export const DEFAULT_DATA_DIR = 'data';
4
+ // Sandbox
5
+ export const SANDBOX_CONNECT_TIMEOUT_MS = 10_000;
6
+ export const SANDBOX_SHUTDOWN_TIMEOUT_MS = 5_000;
7
+ // Bridge
8
+ export const BRIDGE_READY_TIMEOUT_MS = 10_000;
9
+ // Agent setup
10
+ export const INSTALL_SCRIPT_TIMEOUT_MS = 120_000; // 2 min
11
+ // Resource limits
12
+ export const DEFAULT_SANDBOX_LIMITS = {
13
+ memoryMb: 2048,
14
+ cpuPercent: 100,
15
+ diskMb: 1024,
16
+ maxProcesses: 64,
17
+ };
18
+ export const DISK_CHECK_INTERVAL_MS = 30_000;
19
+ // Backpressure
20
+ export const SSE_WRITE_TIMEOUT_MS = 30_000;
21
+ // Docker sandbox image
22
+ export const SANDBOX_DOCKER_IMAGE = 'node:20-slim';
23
+ // Docker lifecycle (ash start/stop)
24
+ export const ASH_CONTAINER_NAME = 'ash-server';
25
+ export const ASH_DOCKER_IMAGE = 'ghcr.io/ash-ai/ash';
26
+ export const ASH_DOCKER_TAG = '0.1.0';
27
+ export const ASH_DATA_DIR_CONTAINER = '/data';
28
+ export const ASH_AGENTS_SUBDIR = 'agents';
29
+ export const ASH_HEALTH_POLL_INTERVAL_MS = 500;
30
+ export const ASH_HEALTH_POLL_TIMEOUT_MS = 30_000;
31
+ // Sandbox pool
32
+ export const DEFAULT_MAX_SANDBOXES = 1000;
33
+ export const DEFAULT_IDLE_TIMEOUT_MS = 30 * 60 * 1000; // 30 min
34
+ export const IDLE_SWEEP_INTERVAL_MS = 60_000; // 1 min
35
+ // Runner (multi-machine mode)
36
+ export const DEFAULT_RUNNER_PORT = 4200;
37
+ export const RUNNER_HEARTBEAT_INTERVAL_MS = 10_000;
38
+ export const RUNNER_LIVENESS_TIMEOUT_MS = 30_000;
39
+ // Env vars allowed into sandbox processes (allowlist — nothing else leaks)
40
+ export const SANDBOX_ENV_ALLOWLIST = [
41
+ 'PATH',
42
+ 'NODE_PATH',
43
+ 'HOME',
44
+ 'LANG',
45
+ 'TERM',
46
+ 'ANTHROPIC_API_KEY',
47
+ 'ASH_DEBUG_TIMING',
48
+ 'ASH_REAL_SDK',
49
+ 'CLAUDE_CODE_EXECUTABLE',
50
+ ];
51
+ //# sourceMappingURL=constants.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.js","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,YAAY,GAAG,IAAI,CAAC;AACjC,MAAM,CAAC,MAAM,YAAY,GAAG,SAAS,CAAC;AACtC,MAAM,CAAC,MAAM,gBAAgB,GAAG,MAAM,CAAC;AAEvC,UAAU;AACV,MAAM,CAAC,MAAM,0BAA0B,GAAG,MAAM,CAAC;AACjD,MAAM,CAAC,MAAM,2BAA2B,GAAG,KAAK,CAAC;AAEjD,SAAS;AACT,MAAM,CAAC,MAAM,uBAAuB,GAAG,MAAM,CAAC;AAE9C,cAAc;AACd,MAAM,CAAC,MAAM,yBAAyB,GAAG,OAAO,CAAC,CAAC,QAAQ;AAE1D,kBAAkB;AAClB,MAAM,CAAC,MAAM,sBAAsB,GAAG;IACpC,QAAQ,EAAE,IAAI;IACd,UAAU,EAAE,GAAG;IACf,MAAM,EAAE,IAAI;IACZ,YAAY,EAAE,EAAE;CACR,CAAC;AAEX,MAAM,CAAC,MAAM,sBAAsB,GAAG,MAAM,CAAC;AAE7C,eAAe;AACf,MAAM,CAAC,MAAM,oBAAoB,GAAG,MAAM,CAAC;AAE3C,uBAAuB;AACvB,MAAM,CAAC,MAAM,oBAAoB,GAAG,cAAc,CAAC;AAEnD,oCAAoC;AACpC,MAAM,CAAC,MAAM,kBAAkB,GAAG,YAAY,CAAC;AAC/C,MAAM,CAAC,MAAM,gBAAgB,GAAG,oBAAoB,CAAC;AACrD,MAAM,CAAC,MAAM,cAAc,GAAG,OAAO,CAAC;AACtC,MAAM,CAAC,MAAM,sBAAsB,GAAG,OAAO,CAAC;AAC9C,MAAM,CAAC,MAAM,iBAAiB,GAAG,QAAQ,CAAC;AAC1C,MAAM,CAAC,MAAM,2BAA2B,GAAG,GAAG,CAAC;AAC/C,MAAM,CAAC,MAAM,0BAA0B,GAAG,MAAM,CAAC;AAEjD,eAAe;AACf,MAAM,CAAC,MAAM,qBAAqB,GAAG,IAAI,CAAC;AAC1C,MAAM,CAAC,MAAM,uBAAuB,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,CAAE,SAAS;AACjE,MAAM,CAAC,MAAM,sBAAsB,GAAG,MAAM,CAAC,CAAY,QAAQ;AAEjE,8BAA8B;AAC9B,MAAM,CAAC,MAAM,mBAAmB,GAAG,IAAI,CAAC;AACxC,MAAM,CAAC,MAAM,4BAA4B,GAAG,MAAM,CAAC;AACnD,MAAM,CAAC,MAAM,0BAA0B,GAAG,MAAM,CAAC;AAEjD,2EAA2E;AAC3E,MAAM,CAAC,MAAM,qBAAqB,GAAG;IACnC,MAAM;IACN,WAAW;IACX,MAAM;IACN,MAAM;IACN,MAAM;IACN,mBAAmB;IACnB,kBAAkB;IAClB,cAAc;IACd,wBAAwB;CAChB,CAAC"}
@@ -0,0 +1,5 @@
1
+ export * from './types.js';
2
+ export * from './protocol.js';
3
+ export * from './constants.js';
4
+ export * from './timing.js';
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,eAAe,CAAC;AAC9B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,aAAa,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,5 @@
1
+ export * from './types.js';
2
+ export * from './protocol.js';
3
+ export * from './constants.js';
4
+ export * from './timing.js';
5
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,eAAe,CAAC;AAC9B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,aAAa,CAAC"}
@@ -0,0 +1,36 @@
1
+ export interface QueryCommand {
2
+ cmd: 'query';
3
+ prompt: string;
4
+ sessionId: string;
5
+ includePartialMessages?: boolean;
6
+ }
7
+ export interface ResumeCommand {
8
+ cmd: 'resume';
9
+ sessionId: string;
10
+ }
11
+ export interface InterruptCommand {
12
+ cmd: 'interrupt';
13
+ }
14
+ export interface ShutdownCommand {
15
+ cmd: 'shutdown';
16
+ }
17
+ export type BridgeCommand = QueryCommand | ResumeCommand | InterruptCommand | ShutdownCommand;
18
+ export interface ReadyEvent {
19
+ ev: 'ready';
20
+ }
21
+ export interface MessageEvent {
22
+ ev: 'message';
23
+ data: unknown;
24
+ }
25
+ export interface ErrorEvent {
26
+ ev: 'error';
27
+ error: string;
28
+ }
29
+ export interface DoneEvent {
30
+ ev: 'done';
31
+ sessionId: string;
32
+ }
33
+ export type BridgeEvent = ReadyEvent | MessageEvent | ErrorEvent | DoneEvent;
34
+ export declare function encode(msg: BridgeCommand | BridgeEvent): string;
35
+ export declare function decode(line: string): BridgeCommand | BridgeEvent;
36
+ //# sourceMappingURL=protocol.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"protocol.d.ts","sourceRoot":"","sources":["../src/protocol.ts"],"names":[],"mappings":"AAWA,MAAM,WAAW,YAAY;IAC3B,GAAG,EAAE,OAAO,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,sBAAsB,CAAC,EAAE,OAAO,CAAC;CAClC;AAED,MAAM,WAAW,aAAa;IAC5B,GAAG,EAAE,QAAQ,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,gBAAgB;IAC/B,GAAG,EAAE,WAAW,CAAC;CAClB;AAED,MAAM,WAAW,eAAe;IAC9B,GAAG,EAAE,UAAU,CAAC;CACjB;AAED,MAAM,MAAM,aAAa,GACrB,YAAY,GACZ,aAAa,GACb,gBAAgB,GAChB,eAAe,CAAC;AAMpB,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,OAAO,CAAC;CACb;AAED,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,SAAS,CAAC;IACd,IAAI,EAAE,OAAO,CAAC;CACf;AAED,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,OAAO,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,SAAS;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,MAAM,WAAW,GACnB,UAAU,GACV,YAAY,GACZ,UAAU,GACV,SAAS,CAAC;AAId,wBAAgB,MAAM,CAAC,GAAG,EAAE,aAAa,GAAG,WAAW,GAAG,MAAM,CAE/D;AAED,wBAAgB,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,aAAa,GAAG,WAAW,CAEhE"}
@@ -0,0 +1,16 @@
1
+ // =============================================================================
2
+ // Bridge protocol: communication between server host and bridge process inside
3
+ // sandbox. Newline-delimited JSON over Unix socket.
4
+ //
5
+ // SDK message passthrough: bridge events carry raw SDK Message objects (from
6
+ // @anthropic-ai/claude-code) as opaque JSON. We do NOT define our own message
7
+ // types — the SDK's types are the contract. See CLAUDE.md principle 8.
8
+ // =============================================================================
9
+ // -- Wire encoding/decoding ---------------------------------------------------
10
+ export function encode(msg) {
11
+ return JSON.stringify(msg) + '\n';
12
+ }
13
+ export function decode(line) {
14
+ return JSON.parse(line.trim());
15
+ }
16
+ //# sourceMappingURL=protocol.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"protocol.js","sourceRoot":"","sources":["../src/protocol.ts"],"names":[],"mappings":"AAAA,gFAAgF;AAChF,+EAA+E;AAC/E,oDAAoD;AACpD,EAAE;AACF,6EAA6E;AAC7E,8EAA8E;AAC9E,uEAAuE;AACvE,gFAAgF;AA2DhF,gFAAgF;AAEhF,MAAM,UAAU,MAAM,CAAC,GAAgC;IACrD,OAAO,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC;AACpC,CAAC;AAED,MAAM,UAAU,MAAM,CAAC,IAAY;IACjC,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;AACjC,CAAC"}
@@ -0,0 +1,23 @@
1
+ export interface TimingEntry {
2
+ type: 'timing';
3
+ source: 'server' | 'bridge';
4
+ sessionId: string;
5
+ [key: string]: unknown;
6
+ timestamp: string;
7
+ }
8
+ /**
9
+ * Returns true when timing instrumentation is enabled.
10
+ */
11
+ export declare function timingEnabled(): boolean;
12
+ /**
13
+ * Returns a function that, when called, returns elapsed milliseconds
14
+ * since `startTimer()` was invoked. Uses `process.hrtime.bigint()` for
15
+ * sub-millisecond precision.
16
+ */
17
+ export declare function startTimer(): () => number;
18
+ /**
19
+ * Writes a TimingEntry as a single JSON line to stderr.
20
+ * No-op if timing is disabled.
21
+ */
22
+ export declare function logTiming(entry: TimingEntry): void;
23
+ //# sourceMappingURL=timing.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"timing.d.ts","sourceRoot":"","sources":["../src/timing.ts"],"names":[],"mappings":"AAMA,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,QAAQ,CAAC;IACf,MAAM,EAAE,QAAQ,GAAG,QAAQ,CAAC;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;IACvB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;GAEG;AACH,wBAAgB,aAAa,IAAI,OAAO,CAEvC;AAED;;;;GAIG;AACH,wBAAgB,UAAU,IAAI,MAAM,MAAM,CAGzC;AAED;;;GAGG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,WAAW,GAAG,IAAI,CAGlD"}
package/dist/timing.js ADDED
@@ -0,0 +1,30 @@
1
+ // =============================================================================
2
+ // Lightweight hot-path timing instrumentation.
3
+ // Gated behind ASH_DEBUG_TIMING=1. Zero overhead when off.
4
+ // Output: one JSON line per message to stderr.
5
+ // =============================================================================
6
+ /**
7
+ * Returns true when timing instrumentation is enabled.
8
+ */
9
+ export function timingEnabled() {
10
+ return process.env.ASH_DEBUG_TIMING === '1';
11
+ }
12
+ /**
13
+ * Returns a function that, when called, returns elapsed milliseconds
14
+ * since `startTimer()` was invoked. Uses `process.hrtime.bigint()` for
15
+ * sub-millisecond precision.
16
+ */
17
+ export function startTimer() {
18
+ const start = process.hrtime.bigint();
19
+ return () => Number(process.hrtime.bigint() - start) / 1_000_000;
20
+ }
21
+ /**
22
+ * Writes a TimingEntry as a single JSON line to stderr.
23
+ * No-op if timing is disabled.
24
+ */
25
+ export function logTiming(entry) {
26
+ if (!timingEnabled())
27
+ return;
28
+ process.stderr.write(JSON.stringify(entry) + '\n');
29
+ }
30
+ //# sourceMappingURL=timing.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"timing.js","sourceRoot":"","sources":["../src/timing.ts"],"names":[],"mappings":"AAAA,gFAAgF;AAChF,+CAA+C;AAC/C,2DAA2D;AAC3D,+CAA+C;AAC/C,gFAAgF;AAUhF;;GAEG;AACH,MAAM,UAAU,aAAa;IAC3B,OAAO,OAAO,CAAC,GAAG,CAAC,gBAAgB,KAAK,GAAG,CAAC;AAC9C,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,UAAU;IACxB,MAAM,KAAK,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC;IACtC,OAAO,GAAG,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,GAAG,KAAK,CAAC,GAAG,SAAS,CAAC;AACnE,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,SAAS,CAAC,KAAkB;IAC1C,IAAI,CAAC,aAAa,EAAE;QAAE,OAAO;IAC7B,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,CAAC;AACrD,CAAC"}
@@ -0,0 +1,149 @@
1
+ export interface Agent {
2
+ name: string;
3
+ version: number;
4
+ path: string;
5
+ createdAt: string;
6
+ updatedAt: string;
7
+ }
8
+ export type SessionStatus = 'starting' | 'active' | 'paused' | 'ended' | 'error';
9
+ export interface Session {
10
+ id: string;
11
+ agentName: string;
12
+ sandboxId: string;
13
+ status: SessionStatus;
14
+ createdAt: string;
15
+ lastActiveAt: string;
16
+ /** Runner that owns this session's sandbox. Null in standalone mode. */
17
+ runnerId?: string | null;
18
+ }
19
+ export type SandboxState = 'cold' | 'warming' | 'warm' | 'waiting' | 'running';
20
+ export interface SandboxInfo {
21
+ id: string;
22
+ pid: number | null;
23
+ state: SandboxState;
24
+ socketPath: string;
25
+ workspaceDir: string;
26
+ createdAt: string;
27
+ }
28
+ export interface SandboxRecord {
29
+ id: string;
30
+ sessionId: string | null;
31
+ agentName: string;
32
+ state: SandboxState;
33
+ workspaceDir: string;
34
+ createdAt: string;
35
+ lastUsedAt: string;
36
+ }
37
+ export interface PoolStats {
38
+ total: number;
39
+ cold: number;
40
+ warming: number;
41
+ warm: number;
42
+ waiting: number;
43
+ running: number;
44
+ maxCapacity: number;
45
+ resumeWarmHits: number;
46
+ resumeColdHits: number;
47
+ }
48
+ export interface SandboxLimits {
49
+ memoryMb: number;
50
+ cpuPercent: number;
51
+ diskMb: number;
52
+ maxProcesses: number;
53
+ }
54
+ export interface FileEntry {
55
+ path: string;
56
+ size: number;
57
+ modifiedAt: string;
58
+ }
59
+ export interface ListFilesResponse {
60
+ files: FileEntry[];
61
+ /** Where the file listing was read from: 'sandbox' (live) or 'snapshot' (persisted). */
62
+ source: 'sandbox' | 'snapshot';
63
+ }
64
+ export interface GetFileResponse {
65
+ path: string;
66
+ content: string;
67
+ size: number;
68
+ source: 'sandbox' | 'snapshot';
69
+ }
70
+ export interface CreateSessionRequest {
71
+ agent: string;
72
+ }
73
+ export interface CreateSessionResponse {
74
+ session: Session;
75
+ }
76
+ export interface SendMessageRequest {
77
+ content: string;
78
+ /** Enable partial message streaming. When true, yields incremental StreamEvent messages with raw API deltas in addition to complete messages. */
79
+ includePartialMessages?: boolean;
80
+ }
81
+ export interface DeployAgentRequest {
82
+ name: string;
83
+ path: string;
84
+ }
85
+ export interface ListAgentsResponse {
86
+ agents: Agent[];
87
+ }
88
+ export interface ListSessionsResponse {
89
+ sessions: Session[];
90
+ }
91
+ export interface HealthResponse {
92
+ status: 'ok';
93
+ activeSessions: number;
94
+ activeSandboxes: number;
95
+ uptime: number;
96
+ pool: PoolStats;
97
+ }
98
+ export interface ApiError {
99
+ error: string;
100
+ statusCode: number;
101
+ }
102
+ export type AshSSEEventType = 'message' | 'error' | 'done';
103
+ export interface AshMessageEvent {
104
+ type: 'message';
105
+ data: Record<string, any>;
106
+ }
107
+ export interface AshErrorEvent {
108
+ type: 'error';
109
+ data: {
110
+ error: string;
111
+ };
112
+ }
113
+ export interface AshDoneEvent {
114
+ type: 'done';
115
+ data: {
116
+ sessionId: string;
117
+ };
118
+ }
119
+ export type AshStreamEvent = AshMessageEvent | AshErrorEvent | AshDoneEvent;
120
+ export type DisplayItemType = 'text' | 'tool_use' | 'tool_result';
121
+ export interface DisplayItem {
122
+ type: DisplayItemType;
123
+ /** For text: the text content. For tool_use: tool name. For tool_result: output. */
124
+ content: string;
125
+ /** Tool name (tool_use and tool_result only) */
126
+ toolName?: string;
127
+ /** Abbreviated tool input (tool_use only) */
128
+ toolInput?: string;
129
+ }
130
+ /**
131
+ * Extract display items from an SDK message event's data.
132
+ * Returns structured items for text, tool use, and tool results.
133
+ * Returns null for messages that shouldn't be displayed (system, result).
134
+ */
135
+ export declare function extractDisplayItems(data: Record<string, any>): DisplayItem[] | null;
136
+ /**
137
+ * Simple text-only extraction for consumers that just want a string.
138
+ * Extracts text content from assistant messages, ignores tools and results.
139
+ */
140
+ export declare function extractTextFromEvent(data: Record<string, any>): string | null;
141
+ /**
142
+ * Extract a text delta from an SDK StreamEvent message.
143
+ * Returns the incremental text chunk from `content_block_delta` events with `text_delta`,
144
+ * or null for any other event type. Use this to build real-time streaming UIs.
145
+ *
146
+ * Only yields values when `includePartialMessages` is enabled on the request.
147
+ */
148
+ export declare function extractStreamDelta(data: Record<string, any>): string | null;
149
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/dist/types.js ADDED
@@ -0,0 +1,87 @@
1
+ // =============================================================================
2
+ // Ash-specific types. These are for orchestration concerns that Ash owns.
3
+ // Conversation/message types come from @anthropic-ai/claude-code — see protocol.ts.
4
+ // =============================================================================
5
+ /**
6
+ * Extract display items from an SDK message event's data.
7
+ * Returns structured items for text, tool use, and tool results.
8
+ * Returns null for messages that shouldn't be displayed (system, result).
9
+ */
10
+ export function extractDisplayItems(data) {
11
+ // Assistant message with content blocks
12
+ if (data.type === 'assistant' && data.message?.content) {
13
+ const content = data.message.content;
14
+ if (!Array.isArray(content))
15
+ return null;
16
+ const items = [];
17
+ for (const block of content) {
18
+ if (block.type === 'text') {
19
+ items.push({ type: 'text', content: block.text });
20
+ }
21
+ else if (block.type === 'tool_use') {
22
+ const inputStr = block.input
23
+ ? Object.entries(block.input)
24
+ .map(([k, v]) => `${k}: ${typeof v === 'string' ? v : JSON.stringify(v)}`)
25
+ .join(', ')
26
+ : '';
27
+ items.push({
28
+ type: 'tool_use',
29
+ content: block.name,
30
+ toolName: block.name,
31
+ toolInput: inputStr.length > 200 ? inputStr.slice(0, 200) + '...' : inputStr,
32
+ });
33
+ }
34
+ }
35
+ return items.length > 0 ? items : null;
36
+ }
37
+ // Tool result message
38
+ if (data.type === 'user' && data.tool_use_result) {
39
+ const r = data.tool_use_result;
40
+ const output = (r.stdout || '') + (r.stderr ? `\n${r.stderr}` : '');
41
+ if (!output.trim())
42
+ return null;
43
+ return [{
44
+ type: 'tool_result',
45
+ content: output.length > 1000 ? output.slice(0, 1000) + '\n...' : output,
46
+ }];
47
+ }
48
+ return null;
49
+ }
50
+ /**
51
+ * Simple text-only extraction for consumers that just want a string.
52
+ * Extracts text content from assistant messages, ignores tools and results.
53
+ */
54
+ export function extractTextFromEvent(data) {
55
+ if (data.type === 'assistant' && data.message?.content) {
56
+ const content = data.message.content;
57
+ if (typeof content === 'string')
58
+ return content;
59
+ if (Array.isArray(content)) {
60
+ const text = content
61
+ .filter((block) => block.type === 'text')
62
+ .map((block) => block.text)
63
+ .join('');
64
+ return text || null;
65
+ }
66
+ }
67
+ return null;
68
+ }
69
+ /**
70
+ * Extract a text delta from an SDK StreamEvent message.
71
+ * Returns the incremental text chunk from `content_block_delta` events with `text_delta`,
72
+ * or null for any other event type. Use this to build real-time streaming UIs.
73
+ *
74
+ * Only yields values when `includePartialMessages` is enabled on the request.
75
+ */
76
+ export function extractStreamDelta(data) {
77
+ if (data.type !== 'stream_event')
78
+ return null;
79
+ const event = data.event;
80
+ if (!event || event.type !== 'content_block_delta')
81
+ return null;
82
+ const delta = event.delta;
83
+ if (!delta || delta.type !== 'text_delta')
84
+ return null;
85
+ return delta.text ?? null;
86
+ }
87
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,32 @@
1
+ {
2
+ "name": "@ash-ai/shared",
3
+ "version": "0.0.1",
4
+ "type": "module",
5
+ "main": "dist/index.js",
6
+ "types": "dist/index.d.ts",
7
+ "exports": {
8
+ ".": {
9
+ "types": "./dist/index.d.ts",
10
+ "default": "./dist/index.js"
11
+ }
12
+ },
13
+ "files": [
14
+ "dist"
15
+ ],
16
+ "publishConfig": {
17
+ "access": "public"
18
+ },
19
+ "repository": {
20
+ "type": "git",
21
+ "url": "https://github.com/ash-ai/ash.git",
22
+ "directory": "packages/shared"
23
+ },
24
+ "license": "MIT",
25
+ "description": "Shared types, protocol, and constants for the Ash agent orchestration system",
26
+ "scripts": {
27
+ "build": "tsc",
28
+ "clean": "rm -rf dist *.tsbuildinfo",
29
+ "typecheck": "tsc --noEmit",
30
+ "test": "vitest run"
31
+ }
32
+ }