@opencode-cockpit/protocol 0.1.4 → 0.2.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/dist/build.js +32 -0
- package/dist/contract.js +6 -0
- package/dist/daemon.js +51 -0
- package/dist/framing.js +27 -0
- package/dist/index.js +19 -0
- package/dist/paths.js +16 -0
- package/dist/rpc.js +53 -0
- package/dist/shell/common.js +13 -0
- package/dist/shell/contract.js +55 -0
- package/dist/shell/index.js +6 -0
- package/dist/shell/info.js +33 -0
- package/dist/shell/params.js +132 -0
- package/dist/shell/watch.js +37 -0
- package/package.json +11 -4
- package/types/build.d.ts +6 -0
- package/{src/contract.ts → types/contract.d.ts} +10 -17
- package/types/daemon.d.ts +80 -0
- package/types/framing.d.ts +10 -0
- package/types/index.d.ts +754 -0
- package/types/paths.d.ts +12 -0
- package/types/rpc.d.ts +63 -0
- package/types/shell/common.d.ts +16 -0
- package/types/shell/contract.d.ts +698 -0
- package/types/shell/index.d.ts +6 -0
- package/types/shell/info.d.ts +48 -0
- package/types/shell/params.d.ts +215 -0
- package/types/shell/watch.d.ts +46 -0
- package/src/build.ts +0 -32
- package/src/daemon.ts +0 -48
- package/src/framing.ts +0 -26
- package/src/index.ts +0 -21
- package/src/paths.ts +0 -25
- package/src/rpc.ts +0 -96
- package/src/shell.ts +0 -187
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export declare const ShellInfo: z.ZodObject<{
|
|
3
|
+
id: z.ZodString;
|
|
4
|
+
title: z.ZodString;
|
|
5
|
+
command: z.ZodString;
|
|
6
|
+
args: z.ZodArray<z.ZodString>;
|
|
7
|
+
cwd: z.ZodString;
|
|
8
|
+
owner: z.ZodObject<{
|
|
9
|
+
project: z.ZodString;
|
|
10
|
+
session: z.ZodOptional<z.ZodString>;
|
|
11
|
+
instance: z.ZodOptional<z.ZodString>;
|
|
12
|
+
}, z.core.$strip>;
|
|
13
|
+
status: z.ZodEnum<{
|
|
14
|
+
exited: "exited";
|
|
15
|
+
failed: "failed";
|
|
16
|
+
killed: "killed";
|
|
17
|
+
running: "running";
|
|
18
|
+
}>;
|
|
19
|
+
run: z.ZodNumber;
|
|
20
|
+
pid: z.ZodOptional<z.ZodNumber>;
|
|
21
|
+
exitCode: z.ZodOptional<z.ZodNumber>;
|
|
22
|
+
signal: z.ZodOptional<z.ZodString>;
|
|
23
|
+
error: z.ZodOptional<z.ZodString>;
|
|
24
|
+
summary: z.ZodOptional<z.ZodString>;
|
|
25
|
+
startedAt: z.ZodNumber;
|
|
26
|
+
endedAt: z.ZodOptional<z.ZodNumber>;
|
|
27
|
+
cols: z.ZodNumber;
|
|
28
|
+
rows: z.ZodNumber;
|
|
29
|
+
lines: z.ZodObject<{
|
|
30
|
+
first: z.ZodNumber;
|
|
31
|
+
last: z.ZodNumber;
|
|
32
|
+
}, z.core.$strip>;
|
|
33
|
+
bytes: z.ZodNumber;
|
|
34
|
+
watch: z.ZodOptional<z.ZodObject<{
|
|
35
|
+
preset: z.ZodOptional<z.ZodString>;
|
|
36
|
+
status: z.ZodEnum<{
|
|
37
|
+
fail: "fail";
|
|
38
|
+
ok: "ok";
|
|
39
|
+
pending: "pending";
|
|
40
|
+
unknown: "unknown";
|
|
41
|
+
}>;
|
|
42
|
+
summary: z.ZodOptional<z.ZodString>;
|
|
43
|
+
runs: z.ZodNumber;
|
|
44
|
+
since: z.ZodNumber;
|
|
45
|
+
}, z.core.$strip>>;
|
|
46
|
+
logFile: z.ZodOptional<z.ZodString>;
|
|
47
|
+
}, z.core.$strip>;
|
|
48
|
+
export type ShellInfo = z.output<typeof ShellInfo>;
|
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export declare const StartParams: z.ZodObject<{
|
|
3
|
+
command: z.ZodString;
|
|
4
|
+
args: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
5
|
+
cwd: z.ZodString;
|
|
6
|
+
env: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
7
|
+
title: z.ZodOptional<z.ZodString>;
|
|
8
|
+
cols: z.ZodDefault<z.ZodNumber>;
|
|
9
|
+
rows: z.ZodDefault<z.ZodNumber>;
|
|
10
|
+
owner: z.ZodObject<{
|
|
11
|
+
project: z.ZodString;
|
|
12
|
+
session: z.ZodOptional<z.ZodString>;
|
|
13
|
+
instance: z.ZodOptional<z.ZodString>;
|
|
14
|
+
}, z.core.$strip>;
|
|
15
|
+
timeoutMs: z.ZodOptional<z.ZodNumber>;
|
|
16
|
+
idleTimeoutMs: z.ZodOptional<z.ZodNumber>;
|
|
17
|
+
logFile: z.ZodDefault<z.ZodBoolean>;
|
|
18
|
+
reuse: z.ZodDefault<z.ZodBoolean>;
|
|
19
|
+
}, z.core.$strip>;
|
|
20
|
+
export declare const ClearParams: z.ZodDefault<z.ZodObject<{
|
|
21
|
+
owner: z.ZodOptional<z.ZodObject<{
|
|
22
|
+
project: z.ZodOptional<z.ZodString>;
|
|
23
|
+
session: z.ZodOptional<z.ZodOptional<z.ZodString>>;
|
|
24
|
+
instance: z.ZodOptional<z.ZodOptional<z.ZodString>>;
|
|
25
|
+
}, z.core.$strip>>;
|
|
26
|
+
finishedBeforeMs: z.ZodOptional<z.ZodNumber>;
|
|
27
|
+
}, z.core.$strip>>;
|
|
28
|
+
export declare const ListParams: z.ZodDefault<z.ZodObject<{
|
|
29
|
+
owner: z.ZodOptional<z.ZodObject<{
|
|
30
|
+
project: z.ZodOptional<z.ZodString>;
|
|
31
|
+
session: z.ZodOptional<z.ZodOptional<z.ZodString>>;
|
|
32
|
+
instance: z.ZodOptional<z.ZodOptional<z.ZodString>>;
|
|
33
|
+
}, z.core.$strip>>;
|
|
34
|
+
includeExited: z.ZodDefault<z.ZodBoolean>;
|
|
35
|
+
}, z.core.$strip>>;
|
|
36
|
+
export declare const IdParams: z.ZodObject<{
|
|
37
|
+
id: z.ZodString;
|
|
38
|
+
}, z.core.$strip>;
|
|
39
|
+
export declare const LogLine: z.ZodObject<{
|
|
40
|
+
n: z.ZodNumber;
|
|
41
|
+
text: z.ZodString;
|
|
42
|
+
}, z.core.$strip>;
|
|
43
|
+
export declare const ReadParams: z.ZodObject<{
|
|
44
|
+
id: z.ZodString;
|
|
45
|
+
after: z.ZodOptional<z.ZodNumber>;
|
|
46
|
+
tail: z.ZodDefault<z.ZodNumber>;
|
|
47
|
+
limit: z.ZodDefault<z.ZodNumber>;
|
|
48
|
+
grep: z.ZodOptional<z.ZodString>;
|
|
49
|
+
ignoreCase: z.ZodDefault<z.ZodBoolean>;
|
|
50
|
+
}, z.core.$strip>;
|
|
51
|
+
export declare const ReadResult: z.ZodObject<{
|
|
52
|
+
lines: z.ZodArray<z.ZodObject<{
|
|
53
|
+
n: z.ZodNumber;
|
|
54
|
+
text: z.ZodString;
|
|
55
|
+
}, z.core.$strip>>;
|
|
56
|
+
firstLine: z.ZodNumber;
|
|
57
|
+
lastLine: z.ZodNumber;
|
|
58
|
+
nextCursor: z.ZodNumber;
|
|
59
|
+
truncated: z.ZodBoolean;
|
|
60
|
+
hasMore: z.ZodBoolean;
|
|
61
|
+
status: z.ZodEnum<{
|
|
62
|
+
exited: "exited";
|
|
63
|
+
failed: "failed";
|
|
64
|
+
killed: "killed";
|
|
65
|
+
running: "running";
|
|
66
|
+
}>;
|
|
67
|
+
}, z.core.$strip>;
|
|
68
|
+
/** A run of characters sharing one style, so a UI can repaint colour without parsing escapes. */
|
|
69
|
+
export declare const ScreenRun: z.ZodObject<{
|
|
70
|
+
text: z.ZodString;
|
|
71
|
+
fg: z.ZodOptional<z.ZodString>;
|
|
72
|
+
bg: z.ZodOptional<z.ZodString>;
|
|
73
|
+
bold: z.ZodOptional<z.ZodBoolean>;
|
|
74
|
+
dim: z.ZodOptional<z.ZodBoolean>;
|
|
75
|
+
italic: z.ZodOptional<z.ZodBoolean>;
|
|
76
|
+
underline: z.ZodOptional<z.ZodBoolean>;
|
|
77
|
+
}, z.core.$strip>;
|
|
78
|
+
export declare const ScreenResult: z.ZodObject<{
|
|
79
|
+
text: z.ZodString;
|
|
80
|
+
cols: z.ZodNumber;
|
|
81
|
+
rows: z.ZodNumber;
|
|
82
|
+
cursor: z.ZodObject<{
|
|
83
|
+
x: z.ZodNumber;
|
|
84
|
+
y: z.ZodNumber;
|
|
85
|
+
}, z.core.$strip>;
|
|
86
|
+
styled: z.ZodOptional<z.ZodArray<z.ZodArray<z.ZodObject<{
|
|
87
|
+
text: z.ZodString;
|
|
88
|
+
fg: z.ZodOptional<z.ZodString>;
|
|
89
|
+
bg: z.ZodOptional<z.ZodString>;
|
|
90
|
+
bold: z.ZodOptional<z.ZodBoolean>;
|
|
91
|
+
dim: z.ZodOptional<z.ZodBoolean>;
|
|
92
|
+
italic: z.ZodOptional<z.ZodBoolean>;
|
|
93
|
+
underline: z.ZodOptional<z.ZodBoolean>;
|
|
94
|
+
}, z.core.$strip>>>>;
|
|
95
|
+
}, z.core.$strip>;
|
|
96
|
+
export declare const WriteParams: z.ZodObject<{
|
|
97
|
+
id: z.ZodString;
|
|
98
|
+
data: z.ZodString;
|
|
99
|
+
}, z.core.$strip>;
|
|
100
|
+
export declare const ResizeParams: z.ZodObject<{
|
|
101
|
+
id: z.ZodString;
|
|
102
|
+
cols: z.ZodNumber;
|
|
103
|
+
rows: z.ZodNumber;
|
|
104
|
+
}, z.core.$strip>;
|
|
105
|
+
export declare const WaitUntil: z.ZodObject<{
|
|
106
|
+
pattern: z.ZodOptional<z.ZodString>;
|
|
107
|
+
ignoreCase: z.ZodOptional<z.ZodBoolean>;
|
|
108
|
+
exit: z.ZodOptional<z.ZodBoolean>;
|
|
109
|
+
idleMs: z.ZodOptional<z.ZodNumber>;
|
|
110
|
+
port: z.ZodOptional<z.ZodNumber>;
|
|
111
|
+
host: z.ZodOptional<z.ZodString>;
|
|
112
|
+
}, z.core.$strip>;
|
|
113
|
+
export declare const WaitParams: z.ZodObject<{
|
|
114
|
+
id: z.ZodString;
|
|
115
|
+
until: z.ZodObject<{
|
|
116
|
+
pattern: z.ZodOptional<z.ZodString>;
|
|
117
|
+
ignoreCase: z.ZodOptional<z.ZodBoolean>;
|
|
118
|
+
exit: z.ZodOptional<z.ZodBoolean>;
|
|
119
|
+
idleMs: z.ZodOptional<z.ZodNumber>;
|
|
120
|
+
port: z.ZodOptional<z.ZodNumber>;
|
|
121
|
+
host: z.ZodOptional<z.ZodString>;
|
|
122
|
+
}, z.core.$strip>;
|
|
123
|
+
timeoutMs: z.ZodNumber;
|
|
124
|
+
after: z.ZodOptional<z.ZodNumber>;
|
|
125
|
+
}, z.core.$strip>;
|
|
126
|
+
export declare const WaitReason: z.ZodEnum<{
|
|
127
|
+
exit: "exit";
|
|
128
|
+
idle: "idle";
|
|
129
|
+
pattern: "pattern";
|
|
130
|
+
port: "port";
|
|
131
|
+
timeout: "timeout";
|
|
132
|
+
}>;
|
|
133
|
+
export declare const WaitResult: z.ZodObject<{
|
|
134
|
+
reason: z.ZodEnum<{
|
|
135
|
+
exit: "exit";
|
|
136
|
+
idle: "idle";
|
|
137
|
+
pattern: "pattern";
|
|
138
|
+
port: "port";
|
|
139
|
+
timeout: "timeout";
|
|
140
|
+
}>;
|
|
141
|
+
match: z.ZodOptional<z.ZodObject<{
|
|
142
|
+
n: z.ZodNumber;
|
|
143
|
+
text: z.ZodString;
|
|
144
|
+
}, z.core.$strip>>;
|
|
145
|
+
info: z.ZodObject<{
|
|
146
|
+
id: z.ZodString;
|
|
147
|
+
title: z.ZodString;
|
|
148
|
+
command: z.ZodString;
|
|
149
|
+
args: z.ZodArray<z.ZodString>;
|
|
150
|
+
cwd: z.ZodString;
|
|
151
|
+
owner: z.ZodObject<{
|
|
152
|
+
project: z.ZodString;
|
|
153
|
+
session: z.ZodOptional<z.ZodString>;
|
|
154
|
+
instance: z.ZodOptional<z.ZodString>;
|
|
155
|
+
}, z.core.$strip>;
|
|
156
|
+
status: z.ZodEnum<{
|
|
157
|
+
exited: "exited";
|
|
158
|
+
failed: "failed";
|
|
159
|
+
killed: "killed";
|
|
160
|
+
running: "running";
|
|
161
|
+
}>;
|
|
162
|
+
run: z.ZodNumber;
|
|
163
|
+
pid: z.ZodOptional<z.ZodNumber>;
|
|
164
|
+
exitCode: z.ZodOptional<z.ZodNumber>;
|
|
165
|
+
signal: z.ZodOptional<z.ZodString>;
|
|
166
|
+
error: z.ZodOptional<z.ZodString>;
|
|
167
|
+
summary: z.ZodOptional<z.ZodString>;
|
|
168
|
+
startedAt: z.ZodNumber;
|
|
169
|
+
endedAt: z.ZodOptional<z.ZodNumber>;
|
|
170
|
+
cols: z.ZodNumber;
|
|
171
|
+
rows: z.ZodNumber;
|
|
172
|
+
lines: z.ZodObject<{
|
|
173
|
+
first: z.ZodNumber;
|
|
174
|
+
last: z.ZodNumber;
|
|
175
|
+
}, z.core.$strip>;
|
|
176
|
+
bytes: z.ZodNumber;
|
|
177
|
+
watch: z.ZodOptional<z.ZodObject<{
|
|
178
|
+
preset: z.ZodOptional<z.ZodString>;
|
|
179
|
+
status: z.ZodEnum<{
|
|
180
|
+
fail: "fail";
|
|
181
|
+
ok: "ok";
|
|
182
|
+
pending: "pending";
|
|
183
|
+
unknown: "unknown";
|
|
184
|
+
}>;
|
|
185
|
+
summary: z.ZodOptional<z.ZodString>;
|
|
186
|
+
runs: z.ZodNumber;
|
|
187
|
+
since: z.ZodNumber;
|
|
188
|
+
}, z.core.$strip>>;
|
|
189
|
+
logFile: z.ZodOptional<z.ZodString>;
|
|
190
|
+
}, z.core.$strip>;
|
|
191
|
+
}, z.core.$strip>;
|
|
192
|
+
export declare const StopParams: z.ZodObject<{
|
|
193
|
+
id: z.ZodString;
|
|
194
|
+
signal: z.ZodDefault<z.ZodEnum<{
|
|
195
|
+
SIGHUP: "SIGHUP";
|
|
196
|
+
SIGINT: "SIGINT";
|
|
197
|
+
SIGKILL: "SIGKILL";
|
|
198
|
+
SIGTERM: "SIGTERM";
|
|
199
|
+
}>>;
|
|
200
|
+
graceMs: z.ZodDefault<z.ZodNumber>;
|
|
201
|
+
}, z.core.$strip>;
|
|
202
|
+
export declare const AttachParams: z.ZodObject<{
|
|
203
|
+
id: z.ZodString;
|
|
204
|
+
fromOffset: z.ZodOptional<z.ZodNumber>;
|
|
205
|
+
}, z.core.$strip>;
|
|
206
|
+
export type StartParams = z.output<typeof StartParams>;
|
|
207
|
+
export type ReadParams = z.output<typeof ReadParams>;
|
|
208
|
+
export type ReadResult = z.output<typeof ReadResult>;
|
|
209
|
+
export type ScreenResult = z.output<typeof ScreenResult>;
|
|
210
|
+
export type ScreenRun = z.output<typeof ScreenRun>;
|
|
211
|
+
export type WaitParams = z.output<typeof WaitParams>;
|
|
212
|
+
export type WaitResult = z.output<typeof WaitResult>;
|
|
213
|
+
export type WaitReason = z.output<typeof WaitReason>;
|
|
214
|
+
export type StopParams = z.output<typeof StopParams>;
|
|
215
|
+
export type LogLine = z.output<typeof LogLine>;
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
/**
|
|
3
|
+
* A watch rule is three regexes over a shell's log, not a parser: `done` marks the end of a run
|
|
4
|
+
* (a compile, a test pass), `fail` and `ok` say how it went. Presets are just named rules, so a
|
|
5
|
+
* new tool is a table entry or a rule in the caller's config — never new code.
|
|
6
|
+
*/
|
|
7
|
+
export declare const WatchRule: z.ZodObject<{
|
|
8
|
+
done: z.ZodOptional<z.ZodString>;
|
|
9
|
+
fail: z.ZodOptional<z.ZodString>;
|
|
10
|
+
ok: z.ZodOptional<z.ZodString>;
|
|
11
|
+
ignoreCase: z.ZodOptional<z.ZodBoolean>;
|
|
12
|
+
idleSeconds: z.ZodOptional<z.ZodNumber>;
|
|
13
|
+
}, z.core.$strip>;
|
|
14
|
+
export declare const WatchStatus: z.ZodEnum<{
|
|
15
|
+
fail: "fail";
|
|
16
|
+
ok: "ok";
|
|
17
|
+
pending: "pending";
|
|
18
|
+
unknown: "unknown";
|
|
19
|
+
}>;
|
|
20
|
+
export declare const WatchState: z.ZodObject<{
|
|
21
|
+
preset: z.ZodOptional<z.ZodString>;
|
|
22
|
+
status: z.ZodEnum<{
|
|
23
|
+
fail: "fail";
|
|
24
|
+
ok: "ok";
|
|
25
|
+
pending: "pending";
|
|
26
|
+
unknown: "unknown";
|
|
27
|
+
}>;
|
|
28
|
+
summary: z.ZodOptional<z.ZodString>;
|
|
29
|
+
runs: z.ZodNumber;
|
|
30
|
+
since: z.ZodNumber;
|
|
31
|
+
}, z.core.$strip>;
|
|
32
|
+
export declare const WatchParams: z.ZodObject<{
|
|
33
|
+
id: z.ZodString;
|
|
34
|
+
preset: z.ZodOptional<z.ZodString>;
|
|
35
|
+
rule: z.ZodOptional<z.ZodObject<{
|
|
36
|
+
done: z.ZodOptional<z.ZodString>;
|
|
37
|
+
fail: z.ZodOptional<z.ZodString>;
|
|
38
|
+
ok: z.ZodOptional<z.ZodString>;
|
|
39
|
+
ignoreCase: z.ZodOptional<z.ZodBoolean>;
|
|
40
|
+
idleSeconds: z.ZodOptional<z.ZodNumber>;
|
|
41
|
+
}, z.core.$strip>>;
|
|
42
|
+
}, z.core.$strip>;
|
|
43
|
+
export type WatchRule = z.output<typeof WatchRule>;
|
|
44
|
+
export type WatchState = z.output<typeof WatchState>;
|
|
45
|
+
export type WatchStatus = z.output<typeof WatchStatus>;
|
|
46
|
+
export type WatchParams = z.output<typeof WatchParams>;
|
package/src/build.ts
DELETED
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
import { createHash } from "node:crypto"
|
|
2
|
-
import { readdirSync, readFileSync, statSync } from "node:fs"
|
|
3
|
-
import { dirname, join, relative } from "node:path"
|
|
4
|
-
|
|
5
|
-
const SOURCE = /\.(ts|tsx|js|mjs|json)$/
|
|
6
|
-
const SKIP = new Set(["node_modules", "test", "dist"])
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* Identity of the daemon code that `entry` would run: a hash of every source file in the entry's
|
|
10
|
-
* package (its `src` directory, or the entry file itself when bundled). Daemon and client compute
|
|
11
|
-
* it the same way, so a client can tell when a running daemon was started from different code.
|
|
12
|
-
*/
|
|
13
|
-
export function daemonBuildId(entry: string, version: string): string {
|
|
14
|
-
const hash = createHash("sha256").update(version)
|
|
15
|
-
const root = dirname(entry)
|
|
16
|
-
const files = /[\\/]src$/.test(root) ? walk(root) : [entry]
|
|
17
|
-
for (const file of files.sort()) {
|
|
18
|
-
hash.update(relative(root, file)).update("\0").update(readFileSync(file)).update("\0")
|
|
19
|
-
}
|
|
20
|
-
return `${version}+${hash.digest("hex").slice(0, 12)}`
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
function walk(dir: string): string[] {
|
|
24
|
-
const out: string[] = []
|
|
25
|
-
for (const name of readdirSync(dir)) {
|
|
26
|
-
if (SKIP.has(name)) continue
|
|
27
|
-
const path = join(dir, name)
|
|
28
|
-
if (statSync(path).isDirectory()) out.push(...walk(path))
|
|
29
|
-
else if (SOURCE.test(name)) out.push(path)
|
|
30
|
-
}
|
|
31
|
-
return out
|
|
32
|
-
}
|
package/src/daemon.ts
DELETED
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
import { z } from "zod"
|
|
2
|
-
import { method } from "./contract.ts"
|
|
3
|
-
|
|
4
|
-
export const ClientInfo = z.object({
|
|
5
|
-
name: z.string().min(1),
|
|
6
|
-
version: z.string().min(1),
|
|
7
|
-
pid: z.number().int().optional(),
|
|
8
|
-
})
|
|
9
|
-
|
|
10
|
-
export const Version = z.object({ major: z.number().int(), minor: z.number().int() })
|
|
11
|
-
|
|
12
|
-
export const HelloResult = z.object({
|
|
13
|
-
daemonVersion: z.string(),
|
|
14
|
-
/** Content identity of the running daemon code (see daemonBuildId). */
|
|
15
|
-
build: z.string().optional(),
|
|
16
|
-
protocol: Version,
|
|
17
|
-
modules: z.array(z.string()),
|
|
18
|
-
pid: z.number().int(),
|
|
19
|
-
startedAt: z.number(),
|
|
20
|
-
})
|
|
21
|
-
|
|
22
|
-
export const StatusResult = z.object({
|
|
23
|
-
pid: z.number().int(),
|
|
24
|
-
uptimeMs: z.number(),
|
|
25
|
-
clients: z.number().int(),
|
|
26
|
-
modules: z.array(z.object({ name: z.string(), busy: z.boolean() })),
|
|
27
|
-
})
|
|
28
|
-
|
|
29
|
-
export const daemonContract = {
|
|
30
|
-
"daemon.hello": method(z.object({ client: ClientInfo, protocol: Version }), HelloResult),
|
|
31
|
-
"daemon.status": method(z.object({}).optional(), StatusResult),
|
|
32
|
-
"daemon.shutdown": method(
|
|
33
|
-
z.object({ force: z.boolean().optional() }).optional(),
|
|
34
|
-
z.object({ accepted: z.boolean() }),
|
|
35
|
-
),
|
|
36
|
-
"events.subscribe": method(
|
|
37
|
-
z.object({ topics: z.array(z.string().min(1)).min(1) }),
|
|
38
|
-
z.object({ topics: z.array(z.string()) }),
|
|
39
|
-
),
|
|
40
|
-
"events.unsubscribe": method(
|
|
41
|
-
z.object({ topics: z.array(z.string().min(1)).min(1) }),
|
|
42
|
-
z.object({ topics: z.array(z.string()) }),
|
|
43
|
-
),
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
export type HelloResult = z.output<typeof HelloResult>
|
|
47
|
-
export type StatusResult = z.output<typeof StatusResult>
|
|
48
|
-
export type ClientInfo = z.output<typeof ClientInfo>
|
package/src/framing.ts
DELETED
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
/** NDJSON framing shared by daemon and client. */
|
|
2
|
-
|
|
3
|
-
const encoder = new TextEncoder()
|
|
4
|
-
|
|
5
|
-
export function encodeFrame(message: unknown): Uint8Array {
|
|
6
|
-
return encoder.encode(`${JSON.stringify(message)}\n`)
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
/** Accumulates chunks and yields complete lines. Bounded to protect against runaway peers. */
|
|
10
|
-
export class LineDecoder {
|
|
11
|
-
private readonly decoder = new TextDecoder()
|
|
12
|
-
private pending = ""
|
|
13
|
-
|
|
14
|
-
constructor(private readonly maxLineBytes = 16 * 1024 * 1024) {}
|
|
15
|
-
|
|
16
|
-
push(chunk: Uint8Array): string[] {
|
|
17
|
-
this.pending += this.decoder.decode(chunk, { stream: true })
|
|
18
|
-
const parts = this.pending.split("\n")
|
|
19
|
-
this.pending = parts.pop() ?? ""
|
|
20
|
-
if (this.pending.length > this.maxLineBytes) {
|
|
21
|
-
this.pending = ""
|
|
22
|
-
throw new Error(`frame exceeds ${this.maxLineBytes} bytes`)
|
|
23
|
-
}
|
|
24
|
-
return parts.filter((line) => line.length > 0)
|
|
25
|
-
}
|
|
26
|
-
}
|
package/src/index.ts
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
import type { EventContract } from "./contract.ts"
|
|
2
|
-
import { daemonContract } from "./daemon.ts"
|
|
3
|
-
import { shellContract, shellEvents } from "./shell.ts"
|
|
4
|
-
|
|
5
|
-
export * from "./build.ts"
|
|
6
|
-
export * from "./contract.ts"
|
|
7
|
-
export * from "./daemon.ts"
|
|
8
|
-
export * from "./framing.ts"
|
|
9
|
-
export * from "./paths.ts"
|
|
10
|
-
export * from "./rpc.ts"
|
|
11
|
-
export * as shell from "./shell.ts"
|
|
12
|
-
|
|
13
|
-
/** Every method the daemon serves. Adding a module means spreading its contract here. */
|
|
14
|
-
export const contract = { ...daemonContract, ...shellContract }
|
|
15
|
-
export type Methods = typeof contract
|
|
16
|
-
export type MethodName = keyof Methods
|
|
17
|
-
|
|
18
|
-
/** Every event topic the daemon emits. */
|
|
19
|
-
export const events = { ...shellEvents } satisfies EventContract
|
|
20
|
-
export type Events = typeof events
|
|
21
|
-
export type Topic = keyof Events
|
package/src/paths.ts
DELETED
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
import { homedir } from "node:os"
|
|
2
|
-
import { join } from "node:path"
|
|
3
|
-
|
|
4
|
-
export interface CockpitPaths {
|
|
5
|
-
home: string
|
|
6
|
-
socket: string
|
|
7
|
-
pidFile: string
|
|
8
|
-
lockFile: string
|
|
9
|
-
logFile: string
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* Filesystem layout shared by daemon and clients. Pure: creates nothing.
|
|
14
|
-
* Kept short because unix socket paths are limited to 104 bytes on macOS.
|
|
15
|
-
*/
|
|
16
|
-
export function resolvePaths(env: Record<string, string | undefined> = process.env): CockpitPaths {
|
|
17
|
-
const home = env.COCKPIT_HOME ?? join(env.XDG_CACHE_HOME ?? join(homedir(), ".cache"), "opencode-cockpit")
|
|
18
|
-
return {
|
|
19
|
-
home,
|
|
20
|
-
socket: join(home, "cockpitd.sock"),
|
|
21
|
-
pidFile: join(home, "cockpitd.pid"),
|
|
22
|
-
lockFile: join(home, "spawn.lock"),
|
|
23
|
-
logFile: join(home, "cockpitd.log"),
|
|
24
|
-
}
|
|
25
|
-
}
|
package/src/rpc.ts
DELETED
|
@@ -1,96 +0,0 @@
|
|
|
1
|
-
/** Wire envelope: JSON-RPC 2.0, one JSON object per line (ADR 0002). */
|
|
2
|
-
|
|
3
|
-
/** Bump MAJOR on breaking changes to methods, events or framing. */
|
|
4
|
-
export const PROTOCOL_VERSION = { major: 1, minor: 1 } as const
|
|
5
|
-
|
|
6
|
-
export type RequestId = number | string
|
|
7
|
-
|
|
8
|
-
export interface RpcRequest {
|
|
9
|
-
jsonrpc: "2.0"
|
|
10
|
-
id: RequestId
|
|
11
|
-
method: string
|
|
12
|
-
params?: unknown
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
export interface RpcNotification {
|
|
16
|
-
jsonrpc: "2.0"
|
|
17
|
-
method: string
|
|
18
|
-
params?: unknown
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
export interface RpcSuccess {
|
|
22
|
-
jsonrpc: "2.0"
|
|
23
|
-
id: RequestId
|
|
24
|
-
result: unknown
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
export interface RpcFailure {
|
|
28
|
-
jsonrpc: "2.0"
|
|
29
|
-
id: RequestId | null
|
|
30
|
-
error: RpcErrorShape
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
export type RpcMessage = RpcRequest | RpcNotification | RpcSuccess | RpcFailure
|
|
34
|
-
|
|
35
|
-
export interface RpcErrorShape {
|
|
36
|
-
code: number
|
|
37
|
-
message: string
|
|
38
|
-
data?: unknown
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
export const ErrorCode = {
|
|
42
|
-
ParseError: -32700,
|
|
43
|
-
InvalidRequest: -32600,
|
|
44
|
-
MethodNotFound: -32601,
|
|
45
|
-
InvalidParams: -32602,
|
|
46
|
-
InternalError: -32603,
|
|
47
|
-
// Application range
|
|
48
|
-
NotFound: -32001,
|
|
49
|
-
InvalidState: -32002,
|
|
50
|
-
ProtocolMismatch: -32003,
|
|
51
|
-
SpawnFailed: -32004,
|
|
52
|
-
ShuttingDown: -32005,
|
|
53
|
-
} as const
|
|
54
|
-
|
|
55
|
-
export type ErrorCodeValue = (typeof ErrorCode)[keyof typeof ErrorCode]
|
|
56
|
-
|
|
57
|
-
export class RpcError extends Error {
|
|
58
|
-
constructor(
|
|
59
|
-
readonly code: number,
|
|
60
|
-
message: string,
|
|
61
|
-
readonly data?: unknown,
|
|
62
|
-
) {
|
|
63
|
-
super(message)
|
|
64
|
-
this.name = "RpcError"
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
toShape(): RpcErrorShape {
|
|
68
|
-
return this.data === undefined
|
|
69
|
-
? { code: this.code, message: this.message }
|
|
70
|
-
: { code: this.code, message: this.message, data: this.data }
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
static from(shape: RpcErrorShape): RpcError {
|
|
74
|
-
return new RpcError(shape.code, shape.message, shape.data)
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
/** Method name for daemon → client notifications. */
|
|
79
|
-
export const EVENT_METHOD = "event"
|
|
80
|
-
|
|
81
|
-
export interface EventEnvelope<T extends string = string, D = unknown> {
|
|
82
|
-
topic: T
|
|
83
|
-
data: D
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
export function isRequest(msg: RpcMessage): msg is RpcRequest {
|
|
87
|
-
return "method" in msg && "id" in msg && msg.id !== undefined
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
export function isNotification(msg: RpcMessage): msg is RpcNotification {
|
|
91
|
-
return "method" in msg && !("id" in msg)
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
export function isResponse(msg: RpcMessage): msg is RpcSuccess | RpcFailure {
|
|
95
|
-
return !("method" in msg) && ("result" in msg || "error" in msg)
|
|
96
|
-
}
|