@anhlp/alp-protocol 0.0.0-stage → 0.10.0
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/README.md +6 -2
- package/dist/connection.d.ts +9 -0
- package/dist/connection.js +0 -0
- package/dist/dto.d.ts +36 -0
- package/dist/dto.js +0 -0
- package/dist/events.d.ts +217 -0
- package/dist/events.js +0 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +2 -0
- package/dist/public.d.ts +1 -0
- package/dist/public.js +2 -0
- package/dist/rpc.d.ts +28 -0
- package/dist/rpc.js +0 -0
- package/dist/session.d.ts +134 -0
- package/dist/session.js +0 -0
- package/dist/wire.d.ts +19 -0
- package/dist/wire.js +28 -0
- package/fixtures/ipc-v1.jsonl +4 -0
- package/package.json +100 -4
- package/schema/ipc-v1.json +1054 -0
- package/schema/methods-v1.json +1550 -0
- package/src/connection.ts +9 -0
- package/src/dto.ts +41 -0
- package/src/events.ts +120 -0
- package/src/index.ts +6 -0
- package/src/public.js +2 -0
- package/src/rpc.ts +6 -0
- package/src/session.ts +94 -0
- package/src/wire.js +19 -0
package/README.md
CHANGED
|
@@ -1,3 +1,7 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @anhlp/alp-protocol
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Stable JSON-RPC v1, portable session/event DTOs, JSON Schema and fixtures.
|
|
4
|
+
|
|
5
|
+
Build: `npm run build --workspace=@anhlp/alp-protocol`. Test: `npm run test --workspace=@anhlp/alp-protocol`.
|
|
6
|
+
|
|
7
|
+
Public imports use the package root and its explicitly exported subpaths. See [architecture, provider extension, compatibility and release instructions](../../docs/modular-monorepo.md).
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { Envelope } from './events.js';
|
|
2
|
+
export type DaemonConnection = {
|
|
3
|
+
request<T = any>(method: string, params?: unknown): Promise<T>;
|
|
4
|
+
onEvent(listener: (envelope: Envelope) => void): () => void;
|
|
5
|
+
onClose(listener: (error: Error) => void): () => void;
|
|
6
|
+
close(): void;
|
|
7
|
+
/** True once the connection is gone; socket clients report it, in-process ones may not. */
|
|
8
|
+
readonly closed?: boolean;
|
|
9
|
+
};
|
|
File without changes
|
package/dist/dto.d.ts
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
export type RuntimeKind = 'codex' | 'claude' | 'acp' | 'antigravity';
|
|
2
|
+
export type MailKind = 'question' | 'answer' | 'note' | 'steer' | 'result' | 'stalled' | 'board' | 'checkin';
|
|
3
|
+
export type MailEvent = {
|
|
4
|
+
id: string;
|
|
5
|
+
kind: MailKind;
|
|
6
|
+
from: string;
|
|
7
|
+
assignment: string;
|
|
8
|
+
body?: string;
|
|
9
|
+
replyTo?: string;
|
|
10
|
+
result?: Record<string, unknown>;
|
|
11
|
+
redelivered?: boolean;
|
|
12
|
+
/** Informational; never steers or wakes a session by itself. */
|
|
13
|
+
passive?: boolean;
|
|
14
|
+
/** Delivered between turns, never steered into a running one or taken by alp_wait. */
|
|
15
|
+
defer?: boolean;
|
|
16
|
+
/** Turn that received the event; acknowledged when that turn completes. */
|
|
17
|
+
deliveredTurn?: string;
|
|
18
|
+
};
|
|
19
|
+
export type PinKind = 'claim' | 'decision' | 'finding';
|
|
20
|
+
export type Pin = {
|
|
21
|
+
id: string;
|
|
22
|
+
/** The project root the board belongs to. */
|
|
23
|
+
project: string;
|
|
24
|
+
kind: PinKind;
|
|
25
|
+
body: string;
|
|
26
|
+
/** Project-relative files or directories, or absolute paths in an external write root; required for claims. */
|
|
27
|
+
paths?: string[];
|
|
28
|
+
agent: string;
|
|
29
|
+
sessionId: string;
|
|
30
|
+
rootId: string;
|
|
31
|
+
at: string;
|
|
32
|
+
/** When a claim ended, or any pin was taken down. */
|
|
33
|
+
released?: string;
|
|
34
|
+
/** The task the claiming assignment works on. */
|
|
35
|
+
task?: string;
|
|
36
|
+
};
|
package/dist/dto.js
ADDED
|
File without changes
|
package/dist/events.d.ts
ADDED
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
import type { RuntimeKind, MailEvent, Pin } from './dto.js';
|
|
2
|
+
/** Provider-neutral session events (plans/reference/ALPD.md §4). Viewers project them; the runtime never imports a viewer. */
|
|
3
|
+
export type AlpError = {
|
|
4
|
+
message: string;
|
|
5
|
+
};
|
|
6
|
+
export type TimelineItem = {
|
|
7
|
+
kind: 'user_message';
|
|
8
|
+
id: string;
|
|
9
|
+
text: string;
|
|
10
|
+
clientMessageId?: string;
|
|
11
|
+
} | {
|
|
12
|
+
kind: 'assistant_message';
|
|
13
|
+
id: string;
|
|
14
|
+
text: string;
|
|
15
|
+
}
|
|
16
|
+
/** Something about ALP as a whole the user should see, such as a usage limit or a pause (ALPD §29). */
|
|
17
|
+
| {
|
|
18
|
+
kind: 'notice';
|
|
19
|
+
id: string;
|
|
20
|
+
level: 'info' | 'warning' | 'error';
|
|
21
|
+
text: string;
|
|
22
|
+
}
|
|
23
|
+
/** The runtime compacting the session's context (ALPD §57). */
|
|
24
|
+
| {
|
|
25
|
+
kind: 'compaction';
|
|
26
|
+
id: string;
|
|
27
|
+
status: 'running' | 'completed' | 'failed';
|
|
28
|
+
trigger?: 'auto' | 'manual';
|
|
29
|
+
preTokens?: number;
|
|
30
|
+
postTokens?: number;
|
|
31
|
+
}
|
|
32
|
+
/** The tasks a root's tree created or worked on (plans/reference/ALPD.md §21). */
|
|
33
|
+
| {
|
|
34
|
+
kind: 'todo';
|
|
35
|
+
id: string;
|
|
36
|
+
items: Array<{
|
|
37
|
+
id: string;
|
|
38
|
+
text: string;
|
|
39
|
+
status: 'pending' | 'in_progress' | 'completed';
|
|
40
|
+
}>;
|
|
41
|
+
} | {
|
|
42
|
+
kind: 'tool_call';
|
|
43
|
+
id: string;
|
|
44
|
+
callId: string;
|
|
45
|
+
name: string;
|
|
46
|
+
status: 'running' | 'completed' | 'failed';
|
|
47
|
+
error?: string;
|
|
48
|
+
detail: {
|
|
49
|
+
type: 'shell';
|
|
50
|
+
command: string;
|
|
51
|
+
cwd?: string;
|
|
52
|
+
output: string;
|
|
53
|
+
exitCode?: number | null;
|
|
54
|
+
} | {
|
|
55
|
+
type: 'unknown';
|
|
56
|
+
input: unknown;
|
|
57
|
+
output: unknown;
|
|
58
|
+
};
|
|
59
|
+
};
|
|
60
|
+
export type SessionSnapshot = {
|
|
61
|
+
id: string;
|
|
62
|
+
projectRoot: string;
|
|
63
|
+
agent: string;
|
|
64
|
+
runtime: RuntimeKind;
|
|
65
|
+
model: string;
|
|
66
|
+
mode: string;
|
|
67
|
+
thinking: string;
|
|
68
|
+
workflow: {
|
|
69
|
+
mode: string;
|
|
70
|
+
maxPeers: number;
|
|
71
|
+
supervisor: boolean;
|
|
72
|
+
};
|
|
73
|
+
/** The label of the session's team, such as Phở (ALPD §42); absent for a custom graph. */
|
|
74
|
+
teamLabel?: string;
|
|
75
|
+
threadId: string;
|
|
76
|
+
/** The native thread is kept and the session can be resumed. */
|
|
77
|
+
persistent: boolean;
|
|
78
|
+
parentId?: string;
|
|
79
|
+
/** The requester's tool call that started this assignment. */
|
|
80
|
+
toolCallId?: string;
|
|
81
|
+
activeTurnId?: string;
|
|
82
|
+
/** A turn, an assignment, a child, or undelivered mail keeps the session working. */
|
|
83
|
+
busy: boolean;
|
|
84
|
+
/** Why a usage limit or a pause parked this assignment (ALPD §29). */
|
|
85
|
+
parked?: string;
|
|
86
|
+
/** A digest of the instructions the session runs with (ALPD §34). */
|
|
87
|
+
instructionsSha?: string;
|
|
88
|
+
};
|
|
89
|
+
export type AssignmentSnapshot = {
|
|
90
|
+
id: string;
|
|
91
|
+
agent: string;
|
|
92
|
+
mode: string;
|
|
93
|
+
status: string;
|
|
94
|
+
startedAt: string;
|
|
95
|
+
/** An isolated assignment's branch and working directory. */
|
|
96
|
+
worktree?: {
|
|
97
|
+
branch: string;
|
|
98
|
+
path: string;
|
|
99
|
+
};
|
|
100
|
+
};
|
|
101
|
+
/** runtime: a turn the native runtime started by itself, such as Claude after a background task ended. */
|
|
102
|
+
export type TurnOrigin = 'user' | 'wake' | 'assignment' | 'runtime';
|
|
103
|
+
/** A question an agent asked the user with alp_ask to: "user". */
|
|
104
|
+
export type UserQuestion = {
|
|
105
|
+
id: string;
|
|
106
|
+
sessionId: string;
|
|
107
|
+
rootId: string;
|
|
108
|
+
agent: string;
|
|
109
|
+
body: string;
|
|
110
|
+
options?: string[];
|
|
111
|
+
askedAt: string;
|
|
112
|
+
};
|
|
113
|
+
export type SessionState = 'running' | 'waiting' | 'waiting_parent' | 'waiting_user' | 'idle';
|
|
114
|
+
/** A live tree at one moment, for dashboards (plans/reference/ALPD.md §17). */
|
|
115
|
+
export type TreeStatus = {
|
|
116
|
+
rootId: string;
|
|
117
|
+
sessions: Array<SessionSnapshot & {
|
|
118
|
+
state: SessionState;
|
|
119
|
+
idleMs: number;
|
|
120
|
+
workdir: string;
|
|
121
|
+
unreadMail: number;
|
|
122
|
+
}>;
|
|
123
|
+
assignments: Array<AssignmentSnapshot & {
|
|
124
|
+
requester: string;
|
|
125
|
+
isolation: 'shared' | 'worktree';
|
|
126
|
+
idleMs: number;
|
|
127
|
+
}>;
|
|
128
|
+
questions: UserQuestion[];
|
|
129
|
+
/** Finished worktree assignments waiting for alp_merge or alp_discard. */
|
|
130
|
+
worktrees: Array<{
|
|
131
|
+
assignmentId: string;
|
|
132
|
+
requester: string;
|
|
133
|
+
agent: string;
|
|
134
|
+
branch: string;
|
|
135
|
+
files: string[];
|
|
136
|
+
stat: string;
|
|
137
|
+
}>;
|
|
138
|
+
leases: Array<{
|
|
139
|
+
checkout: string;
|
|
140
|
+
assignmentId: string;
|
|
141
|
+
agent: string;
|
|
142
|
+
}>;
|
|
143
|
+
/** Live claims on the project board held by this tree's sessions. */
|
|
144
|
+
claims: Pin[];
|
|
145
|
+
};
|
|
146
|
+
export type AlpEvent = {
|
|
147
|
+
type: 'session.opened';
|
|
148
|
+
session: SessionSnapshot;
|
|
149
|
+
cwd: string;
|
|
150
|
+
effective: {
|
|
151
|
+
model: string;
|
|
152
|
+
thinking: string;
|
|
153
|
+
};
|
|
154
|
+
} | {
|
|
155
|
+
type: 'session.ready';
|
|
156
|
+
} | {
|
|
157
|
+
type: 'session.updated';
|
|
158
|
+
session: SessionSnapshot;
|
|
159
|
+
} | {
|
|
160
|
+
type: 'session.closed';
|
|
161
|
+
} | {
|
|
162
|
+
type: 'session.failed';
|
|
163
|
+
error: AlpError;
|
|
164
|
+
} | {
|
|
165
|
+
type: 'prompt.accepted';
|
|
166
|
+
clientMessageId: string;
|
|
167
|
+
result: 'turn' | 'steer';
|
|
168
|
+
turnId: string;
|
|
169
|
+
} | {
|
|
170
|
+
type: 'prompt.failed';
|
|
171
|
+
clientMessageId: string;
|
|
172
|
+
error: AlpError;
|
|
173
|
+
} | {
|
|
174
|
+
type: 'turn.started';
|
|
175
|
+
turnId: string;
|
|
176
|
+
origin: TurnOrigin;
|
|
177
|
+
} | {
|
|
178
|
+
type: 'turn.ended';
|
|
179
|
+
turnId: string;
|
|
180
|
+
state: 'completed' | 'failed' | 'canceled';
|
|
181
|
+
error?: AlpError;
|
|
182
|
+
} | {
|
|
183
|
+
type: 'item';
|
|
184
|
+
item: TimelineItem;
|
|
185
|
+
} | {
|
|
186
|
+
type: 'mail';
|
|
187
|
+
mail: Omit<MailEvent, 'passive' | 'deliveredTurn'>;
|
|
188
|
+
} | {
|
|
189
|
+
type: 'assignment';
|
|
190
|
+
assignment: AssignmentSnapshot;
|
|
191
|
+
} | {
|
|
192
|
+
type: 'question';
|
|
193
|
+
question: UserQuestion;
|
|
194
|
+
} | {
|
|
195
|
+
type: 'question.resolved';
|
|
196
|
+
questionId: string;
|
|
197
|
+
outcome: 'answered' | 'dismissed' | 'timeout' | 'canceled';
|
|
198
|
+
answer?: string;
|
|
199
|
+
}
|
|
200
|
+
/** Emitted on the session that pinned it (plans/reference/ALPD.md §18). */
|
|
201
|
+
| {
|
|
202
|
+
type: 'pin';
|
|
203
|
+
pin: Pin;
|
|
204
|
+
} | {
|
|
205
|
+
type: 'unpin';
|
|
206
|
+
pinId: string;
|
|
207
|
+
reason: 'unpinned' | 'session_ended';
|
|
208
|
+
};
|
|
209
|
+
export type Envelope = {
|
|
210
|
+
sessionId: string;
|
|
211
|
+
/** Random per runtime instance; a cursor from another epoch is stale. */
|
|
212
|
+
epoch: string;
|
|
213
|
+
/** Strictly increasing per session. */
|
|
214
|
+
seq: number;
|
|
215
|
+
ts: string;
|
|
216
|
+
event: AlpEvent;
|
|
217
|
+
};
|
package/dist/events.js
ADDED
|
File without changes
|
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
package/dist/public.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./wire.js";
|
package/dist/public.js
ADDED
package/dist/rpc.d.ts
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/** Portable JSON-RPC structures; implementations and provider SDKs stay outside protocol. */
|
|
2
|
+
export type RpcId = string | number | null;
|
|
3
|
+
export type RpcErrorData = {
|
|
4
|
+
code: number;
|
|
5
|
+
message: string;
|
|
6
|
+
data?: unknown;
|
|
7
|
+
};
|
|
8
|
+
export type RpcRequest = {
|
|
9
|
+
jsonrpc: '2.0';
|
|
10
|
+
id?: RpcId;
|
|
11
|
+
method: string;
|
|
12
|
+
params?: Record<string, unknown>;
|
|
13
|
+
};
|
|
14
|
+
export type RpcResponse = {
|
|
15
|
+
jsonrpc: '2.0';
|
|
16
|
+
id: RpcId;
|
|
17
|
+
} & ({
|
|
18
|
+
result: unknown;
|
|
19
|
+
error?: never;
|
|
20
|
+
} | {
|
|
21
|
+
error: RpcErrorData;
|
|
22
|
+
result?: never;
|
|
23
|
+
});
|
|
24
|
+
export type EventNotification = {
|
|
25
|
+
jsonrpc: '2.0';
|
|
26
|
+
method: 'event';
|
|
27
|
+
params: import('./events.js').Envelope;
|
|
28
|
+
};
|
package/dist/rpc.js
ADDED
|
File without changes
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
import type { RuntimeKind } from './dto.js';
|
|
2
|
+
import type { SessionSnapshot } from './events.js';
|
|
3
|
+
/** MCP servers a client adds to the agent's own; the agent's names win no collisions. */
|
|
4
|
+
export type HostMcpServer = {
|
|
5
|
+
type: 'stdio';
|
|
6
|
+
command: string;
|
|
7
|
+
args?: string[];
|
|
8
|
+
env?: Record<string, string>;
|
|
9
|
+
} | {
|
|
10
|
+
type: 'http' | 'sse';
|
|
11
|
+
url: string;
|
|
12
|
+
headers?: Record<string, string>;
|
|
13
|
+
};
|
|
14
|
+
/** What a client asks for; resolveSession turns it into a launchable session. */
|
|
15
|
+
export type SessionSpec = {
|
|
16
|
+
cwd: string;
|
|
17
|
+
agent?: string;
|
|
18
|
+
/** Workflow selected for a new session; omitted uses settings or the restored snapshot. */
|
|
19
|
+
workflow?: string;
|
|
20
|
+
/** Native model, or runtime-prefixed (`codex:`/`claude:`, or `acp:<provider>[/<model>]`) to also choose the runtime. */
|
|
21
|
+
model?: string;
|
|
22
|
+
mode?: string;
|
|
23
|
+
thinking?: string;
|
|
24
|
+
systemPrompt?: string;
|
|
25
|
+
env?: Record<string, string>;
|
|
26
|
+
mcpServers?: Record<string, HostMcpServer>;
|
|
27
|
+
/** Keep the native thread so the session can be resumed. */
|
|
28
|
+
persist?: boolean;
|
|
29
|
+
/** Keep the native thread on disk though the session cannot be resumed: an assignment, which alp_recall may question later. */
|
|
30
|
+
keepThread?: boolean;
|
|
31
|
+
restore?: {
|
|
32
|
+
agent: string;
|
|
33
|
+
threadId: string;
|
|
34
|
+
runtime?: string;
|
|
35
|
+
model?: string;
|
|
36
|
+
workflow?: {
|
|
37
|
+
mode: string;
|
|
38
|
+
maxPeers: number;
|
|
39
|
+
supervisor?: boolean;
|
|
40
|
+
};
|
|
41
|
+
};
|
|
42
|
+
/** Where the native harness works, when not the project root: an assignment's git worktree. ALP files are still read from cwd. */
|
|
43
|
+
workdir?: string;
|
|
44
|
+
/** Explicit shared-assignment write scope; workdir points here while ALP uses cwd for its project. */
|
|
45
|
+
writeRoot?: string;
|
|
46
|
+
/** The workdir is a disposable copy the session may write, though its mode is read-only for the requester's tree. */
|
|
47
|
+
copy?: boolean;
|
|
48
|
+
/** The requester's directory the copy mirrors. */
|
|
49
|
+
copyOf?: string;
|
|
50
|
+
};
|
|
51
|
+
export type OpenOptions = {
|
|
52
|
+
history?: 'replay' | 'skip';
|
|
53
|
+
/** False when the client cannot show child sessions; delegation is then refused in this tree. */
|
|
54
|
+
delegation?: boolean;
|
|
55
|
+
};
|
|
56
|
+
export type PromptContent = Array<{
|
|
57
|
+
type: string;
|
|
58
|
+
text?: string;
|
|
59
|
+
}>;
|
|
60
|
+
export type PromptInput = {
|
|
61
|
+
clientMessageId: string;
|
|
62
|
+
/** auto starts a turn; steer adds to the running one. */
|
|
63
|
+
delivery: 'auto' | 'steer';
|
|
64
|
+
content: PromptContent;
|
|
65
|
+
};
|
|
66
|
+
/** A root before it opens: the team and main it would run with, for viewers that let the user choose first (ALPD §60). */
|
|
67
|
+
export type SessionPreview = {
|
|
68
|
+
teams: Array<{
|
|
69
|
+
id: string;
|
|
70
|
+
label: string;
|
|
71
|
+
description?: string;
|
|
72
|
+
}>;
|
|
73
|
+
/** The team the spec selects, else settings' workflow.mode, else Phở. */
|
|
74
|
+
team: string;
|
|
75
|
+
teamLabel?: string;
|
|
76
|
+
agent: string;
|
|
77
|
+
runtime: RuntimeKind;
|
|
78
|
+
model: string;
|
|
79
|
+
mode: string;
|
|
80
|
+
thinking: string;
|
|
81
|
+
};
|
|
82
|
+
/** What became of one assignment an earlier alpd left running. */
|
|
83
|
+
export type RecoveryOutcome = {
|
|
84
|
+
assignmentId: string;
|
|
85
|
+
agent: string;
|
|
86
|
+
outcome: 'resumed' | 'parked' | 'failed';
|
|
87
|
+
error?: string;
|
|
88
|
+
};
|
|
89
|
+
export type Pause = {
|
|
90
|
+
since: string;
|
|
91
|
+
by: string;
|
|
92
|
+
reason: string;
|
|
93
|
+
resetsAt?: string; /** When alpd last asked the runtime about the limit (ALPD §58). */
|
|
94
|
+
checkedAt?: string;
|
|
95
|
+
};
|
|
96
|
+
export type PauseState = {
|
|
97
|
+
all?: Pause;
|
|
98
|
+
runtimes: Partial<Record<RuntimeKind, Pause>>;
|
|
99
|
+
parked: Array<{
|
|
100
|
+
assignmentId: string;
|
|
101
|
+
agent: string;
|
|
102
|
+
runtime: RuntimeKind;
|
|
103
|
+
rootId: string;
|
|
104
|
+
reason: string;
|
|
105
|
+
since: string;
|
|
106
|
+
}>;
|
|
107
|
+
};
|
|
108
|
+
export type RecallAnswer = {
|
|
109
|
+
assignmentId: string;
|
|
110
|
+
agent: string;
|
|
111
|
+
taskId?: string;
|
|
112
|
+
finishedAt: string;
|
|
113
|
+
answer: string;
|
|
114
|
+
};
|
|
115
|
+
/** A session's lifecycle as alpd records it; neutral, so viewers and integrations share one union. */
|
|
116
|
+
export type SessionStatus = 'initializing' | 'idle' | 'running' | 'error' | 'closed';
|
|
117
|
+
/** The last failure recorded for a session (daemon store `SessionRecord.lastError`). */
|
|
118
|
+
export type SessionError = {
|
|
119
|
+
code?: string;
|
|
120
|
+
message: string;
|
|
121
|
+
};
|
|
122
|
+
/**
|
|
123
|
+
* A session as clients list it: its last snapshot plus lifecycle (ALPD §18). This is the portable
|
|
124
|
+
* shape served by `session.list`; the daemon and every viewer agree on it, so it is the same type
|
|
125
|
+
* the daemon's store and server use rather than a lossy summary.
|
|
126
|
+
*/
|
|
127
|
+
export type SessionSummary = SessionSnapshot & {
|
|
128
|
+
status: SessionStatus;
|
|
129
|
+
title?: string;
|
|
130
|
+
archived?: boolean;
|
|
131
|
+
lastError?: SessionError;
|
|
132
|
+
createdAt?: string;
|
|
133
|
+
updatedAt?: string;
|
|
134
|
+
};
|
package/dist/session.js
ADDED
|
File without changes
|
package/dist/wire.d.ts
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/** UTF-8 socket writers use one newline-terminated JSON value per frame. @param {unknown} value */
|
|
2
|
+
export function encodeFrame(value: unknown): string;
|
|
3
|
+
/** Parse one complete frame. Buffering and failure handling belong to the socket owner. @param {string} line @returns {unknown} */
|
|
4
|
+
export function decodeFrame(line: string): unknown;
|
|
5
|
+
/** Wire protocol of alpd (plans/reference/ALPD.md §3). Bump only for incompatible changes. */
|
|
6
|
+
export const PROTOCOL_VERSION: 1;
|
|
7
|
+
export const MAX_FRAME: number;
|
|
8
|
+
export class AlpRpcError extends Error {
|
|
9
|
+
constructor(error: any);
|
|
10
|
+
code: any;
|
|
11
|
+
data: any;
|
|
12
|
+
}
|
|
13
|
+
export const ERROR: Readonly<{
|
|
14
|
+
failed: 1000;
|
|
15
|
+
notFound: 1001;
|
|
16
|
+
conflict: 1004;
|
|
17
|
+
protocol: 1006;
|
|
18
|
+
}>;
|
|
19
|
+
export const RPC_METHODS: readonly string[];
|
package/dist/wire.js
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
// packages/protocol/src/wire.js
|
|
2
|
+
var PROTOCOL_VERSION = 1;
|
|
3
|
+
var MAX_FRAME = 16 * 1024 * 1024;
|
|
4
|
+
var AlpRpcError = class extends Error {
|
|
5
|
+
constructor(error) {
|
|
6
|
+
super(error?.message ?? "ALP daemon request failed");
|
|
7
|
+
this.code = error?.code;
|
|
8
|
+
this.data = error?.data;
|
|
9
|
+
}
|
|
10
|
+
};
|
|
11
|
+
var ERROR = Object.freeze({ failed: 1e3, notFound: 1001, conflict: 1004, protocol: 1006 });
|
|
12
|
+
var RPC_METHODS = Object.freeze(["assignment.recall", "board.list", "catalog.get", "daemon.hello", "daemon.pause", "daemon.pauses", "daemon.resume", "daemon.shutdown", "daemon.status", "daemon.usage", "extension.register", "extension.unregister", "question.answer", "question.list", "session.archive", "session.attach", "session.close", "session.configure", "session.create", "session.get", "session.interrupt", "session.list", "session.log", "session.message", "session.preview", "session.prompt", "session.release", "session.rename", "session.status"]);
|
|
13
|
+
function encodeFrame(value) {
|
|
14
|
+
return `${JSON.stringify(value)}
|
|
15
|
+
`;
|
|
16
|
+
}
|
|
17
|
+
function decodeFrame(line) {
|
|
18
|
+
return JSON.parse(line);
|
|
19
|
+
}
|
|
20
|
+
export {
|
|
21
|
+
AlpRpcError,
|
|
22
|
+
ERROR,
|
|
23
|
+
MAX_FRAME,
|
|
24
|
+
PROTOCOL_VERSION,
|
|
25
|
+
RPC_METHODS,
|
|
26
|
+
decodeFrame,
|
|
27
|
+
encodeFrame
|
|
28
|
+
};
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
{"jsonrpc":"2.0","id":1,"method":"daemon.hello","params":{"protocolVersion":1,"client":{"name":"fixture","version":"0.9.5"}}}
|
|
2
|
+
{"jsonrpc":"2.0","id":1,"result":{"protocolVersion":1}}
|
|
3
|
+
{"jsonrpc":"2.0","method":"event","params":{"sessionId":"ses_fixture","epoch":"fixture-epoch","seq":1,"ts":"2026-10-14T00:00:00.000Z","event":{"type":"session.ready"}}}
|
|
4
|
+
{"jsonrpc":"2.0","id":2,"error":{"code":1001,"message":"No session ses_fixture"}}
|
package/package.json
CHANGED
|
@@ -1,6 +1,102 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@anhlp/alp-protocol",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"
|
|
5
|
-
"description": "
|
|
6
|
-
|
|
3
|
+
"version": "0.10.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"description": "ALP protocol module",
|
|
6
|
+
"files": [
|
|
7
|
+
"src",
|
|
8
|
+
"dist",
|
|
9
|
+
"schema",
|
|
10
|
+
"fixtures"
|
|
11
|
+
],
|
|
12
|
+
"exports": {
|
|
13
|
+
"./connection": {
|
|
14
|
+
"alp-source": {
|
|
15
|
+
"types": "./src/connection.ts",
|
|
16
|
+
"default": "./src/connection.ts"
|
|
17
|
+
},
|
|
18
|
+
"types": "./dist/connection.d.ts",
|
|
19
|
+
"default": "./dist/connection.js"
|
|
20
|
+
},
|
|
21
|
+
"./dto": {
|
|
22
|
+
"alp-source": {
|
|
23
|
+
"types": "./src/dto.ts",
|
|
24
|
+
"default": "./src/dto.ts"
|
|
25
|
+
},
|
|
26
|
+
"types": "./dist/dto.d.ts",
|
|
27
|
+
"default": "./dist/dto.js"
|
|
28
|
+
},
|
|
29
|
+
"./events": {
|
|
30
|
+
"alp-source": {
|
|
31
|
+
"types": "./src/events.ts",
|
|
32
|
+
"default": "./src/events.ts"
|
|
33
|
+
},
|
|
34
|
+
"types": "./dist/events.d.ts",
|
|
35
|
+
"default": "./dist/events.js"
|
|
36
|
+
},
|
|
37
|
+
"./index": {
|
|
38
|
+
"alp-source": {
|
|
39
|
+
"types": "./src/index.ts",
|
|
40
|
+
"default": "./src/index.ts"
|
|
41
|
+
},
|
|
42
|
+
"types": "./dist/index.d.ts",
|
|
43
|
+
"default": "./src/public.js"
|
|
44
|
+
},
|
|
45
|
+
".": {
|
|
46
|
+
"alp-source": {
|
|
47
|
+
"types": "./src/index.ts",
|
|
48
|
+
"default": "./src/index.ts"
|
|
49
|
+
},
|
|
50
|
+
"types": "./dist/index.d.ts",
|
|
51
|
+
"default": "./src/public.js"
|
|
52
|
+
},
|
|
53
|
+
"./wire": {
|
|
54
|
+
"alp-source": {
|
|
55
|
+
"types": "./src/wire.js",
|
|
56
|
+
"default": "./src/wire.js"
|
|
57
|
+
},
|
|
58
|
+
"types": "./dist/wire.d.ts",
|
|
59
|
+
"default": "./src/wire.js"
|
|
60
|
+
},
|
|
61
|
+
"./schema": {
|
|
62
|
+
"default": "./schema/ipc-v1.json"
|
|
63
|
+
},
|
|
64
|
+
"./session": {
|
|
65
|
+
"alp-source": {
|
|
66
|
+
"types": "./src/session.ts",
|
|
67
|
+
"default": "./src/session.ts"
|
|
68
|
+
},
|
|
69
|
+
"types": "./dist/session.d.ts",
|
|
70
|
+
"default": "./dist/session.js"
|
|
71
|
+
},
|
|
72
|
+
"./rpc": {
|
|
73
|
+
"alp-source": {
|
|
74
|
+
"types": "./src/rpc.ts",
|
|
75
|
+
"default": "./src/rpc.ts"
|
|
76
|
+
},
|
|
77
|
+
"types": "./dist/rpc.d.ts",
|
|
78
|
+
"default": "./dist/rpc.js"
|
|
79
|
+
}
|
|
80
|
+
},
|
|
81
|
+
"engines": {
|
|
82
|
+
"node": ">=20"
|
|
83
|
+
},
|
|
84
|
+
"dependencies": {},
|
|
85
|
+
"scripts": {
|
|
86
|
+
"build": "node ../../scripts/build-workspace.mjs protocol",
|
|
87
|
+
"test": "node ../../scripts/test-package.mjs protocol",
|
|
88
|
+
"prepack": "npm run build"
|
|
89
|
+
},
|
|
90
|
+
"publishConfig": {
|
|
91
|
+
"access": "public",
|
|
92
|
+
"registry": "https://registry.npmjs.org/"
|
|
93
|
+
},
|
|
94
|
+
"repository": {
|
|
95
|
+
"type": "git",
|
|
96
|
+
"url": "git+https://github.com/phucanh08/alp-paseo.git",
|
|
97
|
+
"directory": "packages/protocol"
|
|
98
|
+
},
|
|
99
|
+
"devDependencies": {
|
|
100
|
+
"ajv": "8.17.1"
|
|
101
|
+
}
|
|
102
|
+
}
|