@opencode-cockpit/protocol 0.1.5 → 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/index.js +2 -2
- package/dist/rpc.js +1 -1
- 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.js → shell/params.js} +26 -75
- package/dist/shell/watch.js +37 -0
- package/package.json +3 -3
- package/types/index.d.ts +292 -1
- package/types/rpc.d.ts +1 -1
- package/types/shell/common.d.ts +16 -0
- package/types/{shell.d.ts → shell/contract.d.ts} +306 -241
- 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/dist/index.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { daemonContract } from "./daemon.js";
|
|
2
|
-
import { shellContract, shellEvents } from "./shell.js";
|
|
2
|
+
import { shellContract, shellEvents } from "./shell/index.js";
|
|
3
3
|
export * from "./build.js";
|
|
4
4
|
export * from "./contract.js";
|
|
5
5
|
export * from "./daemon.js";
|
|
6
6
|
export * from "./framing.js";
|
|
7
7
|
export * from "./paths.js";
|
|
8
8
|
export * from "./rpc.js";
|
|
9
|
-
export * as shell from "./shell.js";
|
|
9
|
+
export * as shell from "./shell/index.js";
|
|
10
10
|
|
|
11
11
|
/** Every method the daemon serves. Adding a module means spreading its contract here. */
|
|
12
12
|
export const contract = {
|
package/dist/rpc.js
CHANGED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
|
|
3
|
+
/** Identity and ownership, shared by every shell message. */
|
|
4
|
+
export const ShellId = z.string().regex(/^sh_[a-z2-7]{8}$/, "expected sh_ followed by 8 base32 chars");
|
|
5
|
+
export const Owner = z.object({
|
|
6
|
+
/** Absolute project directory the shell belongs to. */
|
|
7
|
+
project: z.string().min(1),
|
|
8
|
+
/** OpenCode session that started it, when started by an agent. */
|
|
9
|
+
session: z.string().min(1).optional(),
|
|
10
|
+
/** Opaque id of the client instance that started it; used to route notifications to one place. */
|
|
11
|
+
instance: z.string().min(1).optional()
|
|
12
|
+
});
|
|
13
|
+
export const ShellStatus = z.enum(["running", "exited", "killed", "failed"]);
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { method } from "../contract.js";
|
|
3
|
+
import { ShellId } from "./common.js";
|
|
4
|
+
import { ShellInfo } from "./info.js";
|
|
5
|
+
import { AttachParams, ClearParams, IdParams, ListParams, ReadParams, ReadResult, ResizeParams, ScreenResult, StartParams, StopParams, WaitParams, WaitResult, WriteParams } from "./params.js";
|
|
6
|
+
import { WatchParams, WatchRule, WatchStatus } from "./watch.js";
|
|
7
|
+
export const shellContract = {
|
|
8
|
+
"shell.start": method(StartParams, ShellInfo),
|
|
9
|
+
"shell.list": method(ListParams, z.array(ShellInfo)),
|
|
10
|
+
"shell.get": method(IdParams, ShellInfo),
|
|
11
|
+
"shell.read": method(ReadParams, ReadResult),
|
|
12
|
+
"shell.screen": method(IdParams, ScreenResult),
|
|
13
|
+
"shell.write": method(WriteParams, z.object({
|
|
14
|
+
bytes: z.number().int()
|
|
15
|
+
})),
|
|
16
|
+
"shell.resize": method(ResizeParams, z.object({})),
|
|
17
|
+
"shell.wait": method(WaitParams, WaitResult),
|
|
18
|
+
"shell.stop": method(StopParams, ShellInfo),
|
|
19
|
+
"shell.restart": method(IdParams, ShellInfo),
|
|
20
|
+
"shell.remove": method(IdParams, z.object({})),
|
|
21
|
+
"shell.clear": method(ClearParams, z.object({
|
|
22
|
+
removed: z.array(ShellId)
|
|
23
|
+
})),
|
|
24
|
+
"shell.watch": method(WatchParams, ShellInfo),
|
|
25
|
+
"shell.unwatch": method(IdParams, ShellInfo),
|
|
26
|
+
"shell.presets": method(z.object({}).optional(), z.array(z.object({
|
|
27
|
+
name: z.string(),
|
|
28
|
+
match: z.string().optional(),
|
|
29
|
+
rule: WatchRule
|
|
30
|
+
}))),
|
|
31
|
+
"shell.attach": method(AttachParams, z.object({
|
|
32
|
+
offset: z.number().int(),
|
|
33
|
+
replay: z.string()
|
|
34
|
+
})),
|
|
35
|
+
"shell.detach": method(IdParams, z.object({}))
|
|
36
|
+
};
|
|
37
|
+
export const shellEvents = {
|
|
38
|
+
"shell.started": ShellInfo,
|
|
39
|
+
"shell.exited": ShellInfo,
|
|
40
|
+
"shell.removed": z.object({
|
|
41
|
+
id: ShellId
|
|
42
|
+
}),
|
|
43
|
+
"shell.output": z.object({
|
|
44
|
+
id: ShellId,
|
|
45
|
+
offset: z.number().int(),
|
|
46
|
+
data: z.string()
|
|
47
|
+
}),
|
|
48
|
+
/** Emitted only when a watcher's status changes, never per line. */
|
|
49
|
+
"shell.watch": z.object({
|
|
50
|
+
info: ShellInfo,
|
|
51
|
+
previous: WatchStatus,
|
|
52
|
+
current: WatchStatus,
|
|
53
|
+
summary: z.string().optional()
|
|
54
|
+
})
|
|
55
|
+
};
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { Owner, ShellId, ShellStatus } from "./common.js";
|
|
3
|
+
import { WatchState } from "./watch.js";
|
|
4
|
+
export const ShellInfo = z.object({
|
|
5
|
+
id: ShellId,
|
|
6
|
+
title: z.string(),
|
|
7
|
+
command: z.string(),
|
|
8
|
+
args: z.array(z.string()),
|
|
9
|
+
cwd: z.string(),
|
|
10
|
+
owner: Owner,
|
|
11
|
+
status: ShellStatus,
|
|
12
|
+
run: z.number().int().positive(),
|
|
13
|
+
pid: z.number().int().optional(),
|
|
14
|
+
exitCode: z.number().int().optional(),
|
|
15
|
+
signal: z.string().optional(),
|
|
16
|
+
error: z.string().optional(),
|
|
17
|
+
/** Set when a run ends: the last error-looking line of the run, else its last line. */
|
|
18
|
+
summary: z.string().optional(),
|
|
19
|
+
startedAt: z.number(),
|
|
20
|
+
endedAt: z.number().optional(),
|
|
21
|
+
cols: z.number().int(),
|
|
22
|
+
rows: z.number().int(),
|
|
23
|
+
lines: z.object({
|
|
24
|
+
first: z.number().int(),
|
|
25
|
+
last: z.number().int()
|
|
26
|
+
}),
|
|
27
|
+
/** Absolute raw byte offset written so far (for UI attach/replay). */
|
|
28
|
+
bytes: z.number().int(),
|
|
29
|
+
/** Health reported by this shell's watcher, when one is attached. */
|
|
30
|
+
watch: WatchState.optional(),
|
|
31
|
+
/** File this shell's clean log is written to, when logging was requested. */
|
|
32
|
+
logFile: z.string().optional()
|
|
33
|
+
});
|
|
@@ -1,41 +1,6 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
export const Owner = z.object({
|
|
5
|
-
/** Absolute project directory the shell belongs to. */
|
|
6
|
-
project: z.string().min(1),
|
|
7
|
-
/** OpenCode session that started it, when started by an agent. */
|
|
8
|
-
session: z.string().min(1).optional(),
|
|
9
|
-
/** Opaque id of the client instance that started it; used to route notifications to one place. */
|
|
10
|
-
instance: z.string().min(1).optional()
|
|
11
|
-
});
|
|
12
|
-
export const ShellStatus = z.enum(["running", "exited", "killed", "failed"]);
|
|
13
|
-
export const ShellInfo = z.object({
|
|
14
|
-
id: ShellId,
|
|
15
|
-
title: z.string(),
|
|
16
|
-
command: z.string(),
|
|
17
|
-
args: z.array(z.string()),
|
|
18
|
-
cwd: z.string(),
|
|
19
|
-
owner: Owner,
|
|
20
|
-
status: ShellStatus,
|
|
21
|
-
run: z.number().int().positive(),
|
|
22
|
-
pid: z.number().int().optional(),
|
|
23
|
-
exitCode: z.number().int().optional(),
|
|
24
|
-
signal: z.string().optional(),
|
|
25
|
-
error: z.string().optional(),
|
|
26
|
-
/** Set when a run ends: the last error-looking line of the run, else its last line. */
|
|
27
|
-
summary: z.string().optional(),
|
|
28
|
-
startedAt: z.number(),
|
|
29
|
-
endedAt: z.number().optional(),
|
|
30
|
-
cols: z.number().int(),
|
|
31
|
-
rows: z.number().int(),
|
|
32
|
-
lines: z.object({
|
|
33
|
-
first: z.number().int(),
|
|
34
|
-
last: z.number().int()
|
|
35
|
-
}),
|
|
36
|
-
/** Absolute raw byte offset written so far (for UI attach/replay). */
|
|
37
|
-
bytes: z.number().int()
|
|
38
|
-
});
|
|
2
|
+
import { Owner, ShellId, ShellStatus } from "./common.js";
|
|
3
|
+
import { ShellInfo } from "./info.js";
|
|
39
4
|
const Dimension = z.number().int().min(2).max(1000);
|
|
40
5
|
export const StartParams = z.object({
|
|
41
6
|
command: z.string().min(1),
|
|
@@ -46,8 +11,15 @@ export const StartParams = z.object({
|
|
|
46
11
|
cols: Dimension.default(120),
|
|
47
12
|
rows: Dimension.default(32),
|
|
48
13
|
owner: Owner,
|
|
49
|
-
/** Stop the shell automatically after this long. */
|
|
14
|
+
/** Stop the shell automatically after this long, however busy it is. */
|
|
50
15
|
timeoutMs: z.number().int().positive().optional(),
|
|
16
|
+
/**
|
|
17
|
+
* Stop the shell after this much silence. Never a default: a dev server is idle by definition,
|
|
18
|
+
* and killing one for being quiet would be wrong.
|
|
19
|
+
*/
|
|
20
|
+
idleTimeoutMs: z.number().int().positive().optional(),
|
|
21
|
+
/** Also write the clean log to a file, for debugging after the buffer has evicted old lines. */
|
|
22
|
+
logFile: z.boolean().default(false),
|
|
51
23
|
/**
|
|
52
24
|
* Restart a finished shell with the same command, args, cwd, project and session instead of
|
|
53
25
|
* creating a new one. Repeated runs then share one id and one log.
|
|
@@ -94,6 +66,18 @@ export const ReadResult = z.object({
|
|
|
94
66
|
hasMore: z.boolean(),
|
|
95
67
|
status: ShellStatus
|
|
96
68
|
});
|
|
69
|
+
|
|
70
|
+
/** A run of characters sharing one style, so a UI can repaint colour without parsing escapes. */
|
|
71
|
+
export const ScreenRun = z.object({
|
|
72
|
+
text: z.string(),
|
|
73
|
+
/** Resolved "#rrggbb"; absent means the viewer's default foreground. */
|
|
74
|
+
fg: z.string().optional(),
|
|
75
|
+
bg: z.string().optional(),
|
|
76
|
+
bold: z.boolean().optional(),
|
|
77
|
+
dim: z.boolean().optional(),
|
|
78
|
+
italic: z.boolean().optional(),
|
|
79
|
+
underline: z.boolean().optional()
|
|
80
|
+
});
|
|
97
81
|
export const ScreenResult = z.object({
|
|
98
82
|
text: z.string(),
|
|
99
83
|
cols: z.number().int(),
|
|
@@ -101,7 +85,9 @@ export const ScreenResult = z.object({
|
|
|
101
85
|
cursor: z.object({
|
|
102
86
|
x: z.number().int(),
|
|
103
87
|
y: z.number().int()
|
|
104
|
-
})
|
|
88
|
+
}),
|
|
89
|
+
/** The same rows as `text`, carrying colour. */
|
|
90
|
+
styled: z.array(z.array(ScreenRun)).optional()
|
|
105
91
|
});
|
|
106
92
|
export const WriteParams = z.object({
|
|
107
93
|
id: ShellId,
|
|
@@ -143,39 +129,4 @@ export const StopParams = z.object({
|
|
|
143
129
|
export const AttachParams = z.object({
|
|
144
130
|
id: ShellId,
|
|
145
131
|
fromOffset: z.number().int().min(0).optional()
|
|
146
|
-
});
|
|
147
|
-
export const shellContract = {
|
|
148
|
-
"shell.start": method(StartParams, ShellInfo),
|
|
149
|
-
"shell.list": method(ListParams, z.array(ShellInfo)),
|
|
150
|
-
"shell.get": method(IdParams, ShellInfo),
|
|
151
|
-
"shell.read": method(ReadParams, ReadResult),
|
|
152
|
-
"shell.screen": method(IdParams, ScreenResult),
|
|
153
|
-
"shell.write": method(WriteParams, z.object({
|
|
154
|
-
bytes: z.number().int()
|
|
155
|
-
})),
|
|
156
|
-
"shell.resize": method(ResizeParams, z.object({})),
|
|
157
|
-
"shell.wait": method(WaitParams, WaitResult),
|
|
158
|
-
"shell.stop": method(StopParams, ShellInfo),
|
|
159
|
-
"shell.restart": method(IdParams, ShellInfo),
|
|
160
|
-
"shell.remove": method(IdParams, z.object({})),
|
|
161
|
-
"shell.clear": method(ClearParams, z.object({
|
|
162
|
-
removed: z.array(ShellId)
|
|
163
|
-
})),
|
|
164
|
-
"shell.attach": method(AttachParams, z.object({
|
|
165
|
-
offset: z.number().int(),
|
|
166
|
-
replay: z.string()
|
|
167
|
-
})),
|
|
168
|
-
"shell.detach": method(IdParams, z.object({}))
|
|
169
|
-
};
|
|
170
|
-
export const shellEvents = {
|
|
171
|
-
"shell.started": ShellInfo,
|
|
172
|
-
"shell.exited": ShellInfo,
|
|
173
|
-
"shell.removed": z.object({
|
|
174
|
-
id: ShellId
|
|
175
|
-
}),
|
|
176
|
-
"shell.output": z.object({
|
|
177
|
-
id: ShellId,
|
|
178
|
-
offset: z.number().int(),
|
|
179
|
-
data: z.string()
|
|
180
|
-
})
|
|
181
|
-
};
|
|
132
|
+
});
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { ShellId } from "./common.js";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* A watch rule is three regexes over a shell's log, not a parser: `done` marks the end of a run
|
|
6
|
+
* (a compile, a test pass), `fail` and `ok` say how it went. Presets are just named rules, so a
|
|
7
|
+
* new tool is a table entry or a rule in the caller's config — never new code.
|
|
8
|
+
*/
|
|
9
|
+
export const WatchRule = z.object({
|
|
10
|
+
/** A run finished, e.g. "Found 3 errors." Without it, `idleSeconds` ends the run. */
|
|
11
|
+
done: z.string().min(1).max(500).optional(),
|
|
12
|
+
/** Something in this run failed. */
|
|
13
|
+
fail: z.string().min(1).max(500).optional(),
|
|
14
|
+
/** This run was clean; beats `fail` only when `fail` never matched. */
|
|
15
|
+
ok: z.string().min(1).max(500).optional(),
|
|
16
|
+
ignoreCase: z.boolean().optional(),
|
|
17
|
+
/** Treat this much silence as the end of a run when `done` is absent. */
|
|
18
|
+
idleSeconds: z.number().positive().max(3600).optional()
|
|
19
|
+
});
|
|
20
|
+
export const WatchStatus = z.enum(["ok", "fail", "pending", "unknown"]);
|
|
21
|
+
export const WatchState = z.object({
|
|
22
|
+
/** Preset that produced the rule, when one was used. */
|
|
23
|
+
preset: z.string().optional(),
|
|
24
|
+
status: WatchStatus,
|
|
25
|
+
/** Line that decided the current status. */
|
|
26
|
+
summary: z.string().optional(),
|
|
27
|
+
/** Completed runs seen since watching started. */
|
|
28
|
+
runs: z.number().int(),
|
|
29
|
+
/** When the status last changed. */
|
|
30
|
+
since: z.number()
|
|
31
|
+
});
|
|
32
|
+
export const WatchParams = z.object({
|
|
33
|
+
id: ShellId,
|
|
34
|
+
/** Named rule, or "auto" to pick one from the command. Ignored when `rule` is given. */
|
|
35
|
+
preset: z.string().min(1).optional(),
|
|
36
|
+
rule: WatchRule.optional()
|
|
37
|
+
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@opencode-cockpit/protocol",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "Wire protocol, method and event contracts for cockpitd (opencode-cockpit)",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -25,8 +25,8 @@
|
|
|
25
25
|
"default": "./dist/index.js"
|
|
26
26
|
},
|
|
27
27
|
"./shell": {
|
|
28
|
-
"types": "./types/shell.d.ts",
|
|
29
|
-
"default": "./dist/shell.js"
|
|
28
|
+
"types": "./types/shell/index.d.ts",
|
|
29
|
+
"default": "./dist/shell/index.js"
|
|
30
30
|
}
|
|
31
31
|
},
|
|
32
32
|
"files": [
|