@sigrun/shared 0.1.0 → 0.1.2
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/CHANGELOG.md +9 -0
- package/dist/blocks/format.d.ts +28 -0
- package/dist/blocks/format.js +199 -0
- package/dist/blocks/icons.d.ts +12 -0
- package/dist/blocks/icons.js +64 -0
- package/dist/blocks/index.d.ts +25 -0
- package/dist/blocks/index.js +21 -0
- package/dist/blocks/instance.d.ts +29 -0
- package/dist/blocks/instance.js +51 -0
- package/dist/blocks/lttb.d.ts +16 -0
- package/dist/blocks/lttb.js +67 -0
- package/dist/blocks/ops.d.ts +44 -0
- package/dist/blocks/ops.js +294 -0
- package/dist/blocks/text.d.ts +43 -0
- package/dist/blocks/text.js +790 -0
- package/dist/blocks/transport.d.ts +77 -0
- package/dist/blocks/transport.js +11 -0
- package/dist/blocks/types.d.ts +541 -0
- package/dist/blocks/types.js +17 -0
- package/dist/jobs.d.ts +9 -0
- package/dist/live.d.ts +71 -0
- package/dist/live.js +82 -0
- package/dist/session-meta.d.ts +19 -3
- package/dist/settings.d.ts +7 -0
- package/dist/turns.d.ts +17 -0
- package/dist/turns.js +35 -4
- package/dist/views.d.ts +83 -3
- package/package.json +10 -2
package/dist/live.d.ts
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The `docs["pi.live"]` LiveState narrowing (gateway plan 1, Task 1).
|
|
3
|
+
*
|
|
4
|
+
* `pi.live` is the harness's live-run document — `run` while a generation
|
|
5
|
+
* is in flight, `generation.message` (the committed throttled partial of
|
|
6
|
+
* the response), `tools` (live tool slots), `compactions`, and
|
|
7
|
+
* `compactionFailure` (shape per pi-durable dist/harness/live.d.ts).
|
|
8
|
+
* `ConversationViewBase` types `docs` values as `JsonObject`: named
|
|
9
|
+
* LiveDocs are narrowed by their consumers, and this module is that
|
|
10
|
+
* narrowing for `pi.live` — shared by the webui, the tui and the gateway
|
|
11
|
+
* engine so every reader narrows the doc identically.
|
|
12
|
+
*
|
|
13
|
+
* Purity: a shared wire module — `import type` sibling-only (the purity
|
|
14
|
+
* guard in test/views-purity.test.ts); the runtime functions below are
|
|
15
|
+
* dependency-free so both clients (DOM-only webui, NodeNext tui) and the
|
|
16
|
+
* server read the same doc the same way.
|
|
17
|
+
*/
|
|
18
|
+
import type { ConversationViewBase } from "./views.js";
|
|
19
|
+
/** One live tool slot of `docs["pi.live"]` (the LiveState tools list). */
|
|
20
|
+
export interface LiveToolSlotWire {
|
|
21
|
+
readonly callId: string;
|
|
22
|
+
readonly name: string;
|
|
23
|
+
readonly status: string;
|
|
24
|
+
readonly output?: string;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* The `docs["pi.live"]` LiveState doc, narrowed to what the channels read:
|
|
28
|
+
* `run` (present exactly while busy — the steer field derives from it
|
|
29
|
+
* server-side), `generation.message` (the committed throttled partial of
|
|
30
|
+
* the in-flight response), `tools` (live tool slots), `compactions` (live
|
|
31
|
+
* compaction tasks), `compactionFailure` (the newest failure — a
|
|
32
|
+
* completed compaction clears it; nothing-to-compact or a fault leaves
|
|
33
|
+
* it).
|
|
34
|
+
*/
|
|
35
|
+
export interface LiveDocWire {
|
|
36
|
+
readonly run?: unknown;
|
|
37
|
+
readonly generation?: {
|
|
38
|
+
readonly message?: unknown;
|
|
39
|
+
};
|
|
40
|
+
readonly tools?: readonly LiveToolSlotWire[];
|
|
41
|
+
readonly compactions?: readonly unknown[];
|
|
42
|
+
readonly compactionFailure?: {
|
|
43
|
+
readonly error?: unknown;
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* The view's `pi.live` doc, or undefined when absent (idle and never-run
|
|
48
|
+
* conversations carry no doc). A cast, not a validation: the shape is
|
|
49
|
+
* pinned by the harness writer and the fail-soft reads below absorb
|
|
50
|
+
* drift.
|
|
51
|
+
*/
|
|
52
|
+
export declare function liveDoc(view: ConversationViewBase): LiveDocWire | undefined;
|
|
53
|
+
/** The live tool slots of the view's `pi.live` doc (empty when absent). */
|
|
54
|
+
export declare function liveToolSlots(view: ConversationViewBase): readonly LiveToolSlotWire[];
|
|
55
|
+
/**
|
|
56
|
+
* The in-flight generation's committed partial message, or undefined when
|
|
57
|
+
* idle (or the doc shape is unexpected — fail soft to absent; upstream
|
|
58
|
+
* drift surfaces in the schema fixture first).
|
|
59
|
+
*/
|
|
60
|
+
export declare function liveGenerationPartial(view: ConversationViewBase): object | undefined;
|
|
61
|
+
/**
|
|
62
|
+
* The in-flight generation's visible text: the partial's text blocks
|
|
63
|
+
* (`{type: "text"}`) joined with `""` — thinking and tool-call blocks
|
|
64
|
+
* contribute nothing. `""` when idle or the content is not an array; a
|
|
65
|
+
* string `content` returns as-is.
|
|
66
|
+
*/
|
|
67
|
+
export declare function liveGenerationText(view: ConversationViewBase): string;
|
|
68
|
+
/** How many compaction tasks are live right now (0 = none). */
|
|
69
|
+
export declare function liveCompactions(view: ConversationViewBase): number;
|
|
70
|
+
/** The newest compaction failure's error text, when one is surfaced. */
|
|
71
|
+
export declare function liveCompactionFailure(view: ConversationViewBase): string | undefined;
|
package/dist/live.js
ADDED
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The `docs["pi.live"]` LiveState narrowing (gateway plan 1, Task 1).
|
|
3
|
+
*
|
|
4
|
+
* `pi.live` is the harness's live-run document — `run` while a generation
|
|
5
|
+
* is in flight, `generation.message` (the committed throttled partial of
|
|
6
|
+
* the response), `tools` (live tool slots), `compactions`, and
|
|
7
|
+
* `compactionFailure` (shape per pi-durable dist/harness/live.d.ts).
|
|
8
|
+
* `ConversationViewBase` types `docs` values as `JsonObject`: named
|
|
9
|
+
* LiveDocs are narrowed by their consumers, and this module is that
|
|
10
|
+
* narrowing for `pi.live` — shared by the webui, the tui and the gateway
|
|
11
|
+
* engine so every reader narrows the doc identically.
|
|
12
|
+
*
|
|
13
|
+
* Purity: a shared wire module — `import type` sibling-only (the purity
|
|
14
|
+
* guard in test/views-purity.test.ts); the runtime functions below are
|
|
15
|
+
* dependency-free so both clients (DOM-only webui, NodeNext tui) and the
|
|
16
|
+
* server read the same doc the same way.
|
|
17
|
+
*/
|
|
18
|
+
/**
|
|
19
|
+
* The view's `pi.live` doc, or undefined when absent (idle and never-run
|
|
20
|
+
* conversations carry no doc). A cast, not a validation: the shape is
|
|
21
|
+
* pinned by the harness writer and the fail-soft reads below absorb
|
|
22
|
+
* drift.
|
|
23
|
+
*/
|
|
24
|
+
export function liveDoc(view) {
|
|
25
|
+
// SAFETY: `docs` values are `JsonObject` by wire contract; `pi.live` is
|
|
26
|
+
// the harness's own LiveState document. The cast narrows the wire type,
|
|
27
|
+
// it does not validate — every reader below is fail-soft against drift.
|
|
28
|
+
return view.docs["pi.live"];
|
|
29
|
+
}
|
|
30
|
+
/** The live tool slots of the view's `pi.live` doc (empty when absent). */
|
|
31
|
+
export function liveToolSlots(view) {
|
|
32
|
+
return liveDoc(view)?.tools ?? [];
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* The in-flight generation's committed partial message, or undefined when
|
|
36
|
+
* idle (or the doc shape is unexpected — fail soft to absent; upstream
|
|
37
|
+
* drift surfaces in the schema fixture first).
|
|
38
|
+
*/
|
|
39
|
+
export function liveGenerationPartial(view) {
|
|
40
|
+
const message = liveDoc(view)?.generation?.message;
|
|
41
|
+
if (typeof message !== "object" || message === null)
|
|
42
|
+
return undefined;
|
|
43
|
+
return message;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* The in-flight generation's visible text: the partial's text blocks
|
|
47
|
+
* (`{type: "text"}`) joined with `""` — thinking and tool-call blocks
|
|
48
|
+
* contribute nothing. `""` when idle or the content is not an array; a
|
|
49
|
+
* string `content` returns as-is.
|
|
50
|
+
*/
|
|
51
|
+
export function liveGenerationText(view) {
|
|
52
|
+
const partial = liveGenerationPartial(view);
|
|
53
|
+
if (partial === undefined)
|
|
54
|
+
return "";
|
|
55
|
+
const content = partial.content;
|
|
56
|
+
if (typeof content === "string")
|
|
57
|
+
return content;
|
|
58
|
+
if (!Array.isArray(content))
|
|
59
|
+
return "";
|
|
60
|
+
let text = "";
|
|
61
|
+
for (const block of content) {
|
|
62
|
+
if (typeof block !== "object" || block === null)
|
|
63
|
+
continue;
|
|
64
|
+
const typed = block;
|
|
65
|
+
if (typed.type !== "text" || typeof typed.text !== "string")
|
|
66
|
+
continue;
|
|
67
|
+
text += typed.text;
|
|
68
|
+
}
|
|
69
|
+
return text;
|
|
70
|
+
}
|
|
71
|
+
/** How many compaction tasks are live right now (0 = none). */
|
|
72
|
+
export function liveCompactions(view) {
|
|
73
|
+
return liveDoc(view)?.compactions?.length ?? 0;
|
|
74
|
+
}
|
|
75
|
+
/** The newest compaction failure's error text, when one is surfaced. */
|
|
76
|
+
export function liveCompactionFailure(view) {
|
|
77
|
+
const failure = liveDoc(view)?.compactionFailure;
|
|
78
|
+
if (typeof failure !== "object" || failure === null)
|
|
79
|
+
return undefined;
|
|
80
|
+
const error = failure.error;
|
|
81
|
+
return typeof error === "string" && error !== "" ? error : undefined;
|
|
82
|
+
}
|
package/dist/session-meta.d.ts
CHANGED
|
@@ -25,9 +25,10 @@ export type { Sharing } from "./access.js";
|
|
|
25
25
|
* `invalid_field`.
|
|
26
26
|
*
|
|
27
27
|
* Server-owned fields (`autoName`, `autoNameAttempts`,
|
|
28
|
-
* `lastActivityAt`) are written by host code only
|
|
29
|
-
* auto-namer); they are NOT
|
|
30
|
-
* rejecting them as
|
|
28
|
+
* `lastActivityAt`, `jobId`, `deliver`) are written by host code only
|
|
29
|
+
* (activity.ts, the A2 auto-namer, fire.ts's job stamp); they are NOT
|
|
30
|
+
* patch surface — the strict validator keeps rejecting them as
|
|
31
|
+
* `invalid_field`.
|
|
31
32
|
*/
|
|
32
33
|
/** The per-conversation session metadata (spec §5). */
|
|
33
34
|
export type SessionMeta = {
|
|
@@ -69,6 +70,21 @@ export type SessionMeta = {
|
|
|
69
70
|
* patchable — the strict validator rejects the key as `invalid_field`.
|
|
70
71
|
*/
|
|
71
72
|
lastActivityAt?: string;
|
|
73
|
+
/**
|
|
74
|
+
* Server-owned job stamp (gateway C7, spec §8.0): the id of the job
|
|
75
|
+
* whose fire created this conversation (`fire.ts` writes it inside the
|
|
76
|
+
* creating commit). Never patchable — the strict validator rejects
|
|
77
|
+
* the key as `invalid_field`.
|
|
78
|
+
*/
|
|
79
|
+
jobId?: string;
|
|
80
|
+
/**
|
|
81
|
+
* Server-owned job delivery targets (gateway C7, spec §8.0): the job
|
|
82
|
+
* action's `deliver` array, stamped onto the run conversation by
|
|
83
|
+
* `fire.ts` in the creating commit — the gateway's runSettled delivery
|
|
84
|
+
* reads it to route the answer to chats. Never patchable — the
|
|
85
|
+
* strict validator rejects the key as `invalid_field`.
|
|
86
|
+
*/
|
|
87
|
+
deliver?: string[];
|
|
72
88
|
/**
|
|
73
89
|
* The §5.9 per-resource sharing state; absent = private (owner and
|
|
74
90
|
* superuser only). Patchable by the OWNER or a superuser (403
|
package/dist/settings.d.ts
CHANGED
|
@@ -195,6 +195,13 @@ export interface ServerSettings {
|
|
|
195
195
|
readonly metrics?: {
|
|
196
196
|
readonly public?: boolean;
|
|
197
197
|
};
|
|
198
|
+
/**
|
|
199
|
+
* The development flag (spec §14.2/§14.4): `SIGRUN_DEV` (strict
|
|
200
|
+
* true/false — the spec's `SIGRUN_DEV=1` form reads as true) over this
|
|
201
|
+
* key, default `false`. Surfaces on `GET /v1/meta` (`dev`); gates the
|
|
202
|
+
* U1 blocks gallery, U3's development error bodies, and U4.
|
|
203
|
+
*/
|
|
204
|
+
readonly dev?: boolean;
|
|
198
205
|
/**
|
|
199
206
|
* The backup target — exactly one of the two shapes (mirroring the
|
|
200
207
|
* env rule: `SIGRUN_BACKUP_PATH` XOR `SIGRUN_BACKUP_S3_BUCKET`), plus
|
package/dist/turns.d.ts
CHANGED
|
@@ -78,10 +78,27 @@ export type Turn<E extends TurnEntry> = {
|
|
|
78
78
|
readonly tools: readonly ToolCall[];
|
|
79
79
|
readonly text: string;
|
|
80
80
|
readonly lastEntryId: number;
|
|
81
|
+
/** The turn's blocks in OCCURRENCE order — the chronological
|
|
82
|
+
* view interleaves thinking / tool calls / text exactly as they
|
|
83
|
+
* happened, instead of folding everything under the final text
|
|
84
|
+
* (the grouped view's shape). Text blocks CONSECUTIVE in the
|
|
85
|
+
* stream merge into one segment (multi-block answers read as one). */
|
|
86
|
+
readonly timeline: readonly TimelineEvent[];
|
|
81
87
|
} | {
|
|
82
88
|
readonly kind: "other";
|
|
83
89
|
readonly entry: E;
|
|
84
90
|
};
|
|
91
|
+
/** One chronological segment of an assistant turn. */
|
|
92
|
+
export type TimelineEvent = {
|
|
93
|
+
readonly kind: "thinking";
|
|
94
|
+
readonly text: string;
|
|
95
|
+
} | {
|
|
96
|
+
readonly kind: "tool";
|
|
97
|
+
readonly tool: ToolCall;
|
|
98
|
+
} | {
|
|
99
|
+
readonly kind: "text";
|
|
100
|
+
readonly text: string;
|
|
101
|
+
};
|
|
85
102
|
export declare function groupTurns<E extends TurnEntry>(entries: readonly E[]): Turn<E>[];
|
|
86
103
|
export declare function toolPreview(name: string, args: unknown): string;
|
|
87
104
|
/**
|
package/dist/turns.js
CHANGED
|
@@ -52,6 +52,22 @@ export function groupTurns(entries) {
|
|
|
52
52
|
const flush = () => {
|
|
53
53
|
if (pending === null)
|
|
54
54
|
return;
|
|
55
|
+
// Merge consecutive text segments for the timeline (a multi-block
|
|
56
|
+
// answer reads as one run of prose, not N chopped paragraphs).
|
|
57
|
+
const timeline = [];
|
|
58
|
+
for (const event of pending.timeline) {
|
|
59
|
+
const last = timeline[timeline.length - 1];
|
|
60
|
+
if (event.kind === "text" &&
|
|
61
|
+
last !== undefined &&
|
|
62
|
+
last.kind === "text") {
|
|
63
|
+
timeline[timeline.length - 1] = {
|
|
64
|
+
kind: "text",
|
|
65
|
+
text: `${last.text}\n\n${event.text}`,
|
|
66
|
+
};
|
|
67
|
+
continue;
|
|
68
|
+
}
|
|
69
|
+
timeline.push(event);
|
|
70
|
+
}
|
|
55
71
|
turns.push({
|
|
56
72
|
kind: "assistant",
|
|
57
73
|
entries: pending.entries,
|
|
@@ -59,29 +75,44 @@ export function groupTurns(entries) {
|
|
|
59
75
|
tools: pending.tools,
|
|
60
76
|
text: pending.texts.join("\n\n"),
|
|
61
77
|
lastEntryId: pending.entries[pending.entries.length - 1].id,
|
|
78
|
+
timeline,
|
|
62
79
|
});
|
|
63
80
|
pending = null;
|
|
64
81
|
};
|
|
65
82
|
for (const entry of entries) {
|
|
66
83
|
if (entry.kind === "pi.assistant" || entry.kind === "pi.tool-result") {
|
|
67
|
-
pending ??= {
|
|
84
|
+
pending ??= {
|
|
85
|
+
entries: [],
|
|
86
|
+
thinking: [],
|
|
87
|
+
tools: [],
|
|
88
|
+
texts: [],
|
|
89
|
+
timeline: [],
|
|
90
|
+
};
|
|
68
91
|
pending.entries.push(entry);
|
|
69
92
|
if (entry.kind === "pi.assistant") {
|
|
70
93
|
for (const message of entry.model ?? []) {
|
|
71
94
|
for (const block of blocks(message)) {
|
|
72
95
|
if (block.type === "text" && block.text !== undefined) {
|
|
73
96
|
pending.texts.push(block.text);
|
|
97
|
+
pending.timeline.push({ kind: "text", text: block.text });
|
|
74
98
|
}
|
|
75
|
-
else if (block.type === "thinking" &&
|
|
99
|
+
else if (block.type === "thinking" &&
|
|
100
|
+
block.thinking !== undefined) {
|
|
76
101
|
pending.thinking.push(block.thinking);
|
|
102
|
+
pending.timeline.push({
|
|
103
|
+
kind: "thinking",
|
|
104
|
+
text: block.thinking,
|
|
105
|
+
});
|
|
77
106
|
}
|
|
78
107
|
else if (block.type === "toolCall") {
|
|
79
|
-
|
|
108
|
+
const call = {
|
|
80
109
|
callId: block.id ?? "",
|
|
81
110
|
name: block.name ?? "",
|
|
82
111
|
preview: toolPreview(block.name ?? "", block.arguments),
|
|
83
112
|
isError: false,
|
|
84
|
-
}
|
|
113
|
+
};
|
|
114
|
+
pending.tools.push(call);
|
|
115
|
+
pending.timeline.push({ kind: "tool", tool: call });
|
|
85
116
|
}
|
|
86
117
|
}
|
|
87
118
|
}
|
package/dist/views.d.ts
CHANGED
|
@@ -388,6 +388,8 @@ export type WorkerStatus = {
|
|
|
388
388
|
};
|
|
389
389
|
/** The `GET /v1/meta` payload (spec §5; the health block is Task 9e). */
|
|
390
390
|
export interface MetaResponse {
|
|
391
|
+
/** The sigrun server's own version (the package manifest). */
|
|
392
|
+
readonly version: string;
|
|
391
393
|
readonly harnessVersion: string;
|
|
392
394
|
readonly schemaVersion: string;
|
|
393
395
|
readonly extensions: readonly {
|
|
@@ -400,6 +402,14 @@ export interface MetaResponse {
|
|
|
400
402
|
* worker's first run.
|
|
401
403
|
*/
|
|
402
404
|
readonly workers?: readonly WorkerStatus[];
|
|
405
|
+
/**
|
|
406
|
+
* The declared surfaces (UI-blocks U3 Task 5): the flattened
|
|
407
|
+
* view + panel rows the channels register their rail/panel
|
|
408
|
+
* entries from. Absent when the extension declared none. The
|
|
409
|
+
* meta response carries the DECLARATION (id/title/icon/
|
|
410
|
+
* placement); access filtering is render-time (§6.5).
|
|
411
|
+
*/
|
|
412
|
+
readonly surfaces?: readonly ExtensionSurfaceInfo[];
|
|
403
413
|
}[];
|
|
404
414
|
/**
|
|
405
415
|
* §5 health: pure aggregation over boot-retained §3 producers (spec
|
|
@@ -422,8 +432,15 @@ export interface MetaResponse {
|
|
|
422
432
|
readonly memory: HealthStatus;
|
|
423
433
|
/** Any contributor's §3 producer degraded → "degraded"; empty → "ok". */
|
|
424
434
|
readonly providers: HealthStatus;
|
|
435
|
+
/**
|
|
436
|
+
* The gateway engine's health (gateway C2): present ONLY when an
|
|
437
|
+
* engine loaded (a no-engine deploy reports NO gateway health —
|
|
438
|
+
* degenerate "ok" by absence, never a synthesized field); the
|
|
439
|
+
* wrapped engine health (a throwing `health()` reads "degraded";
|
|
440
|
+
* a rejected `start` latches degraded until restart).
|
|
441
|
+
*/
|
|
442
|
+
readonly gateway?: HealthStatus;
|
|
425
443
|
};
|
|
426
|
-
/**
|
|
427
444
|
/**
|
|
428
445
|
* The auth block (core hardening W1 Task 6, spec §5.7): the effective
|
|
429
446
|
* authenticator list (`ctx.methods` — loopback-derived or explicit) and
|
|
@@ -448,6 +465,13 @@ export interface MetaResponse {
|
|
|
448
465
|
readonly backup: boolean;
|
|
449
466
|
readonly channels: readonly string[];
|
|
450
467
|
};
|
|
468
|
+
/**
|
|
469
|
+
* The development flag (spec §14.2/§14.4): `server.dev` / `SIGRUN_DEV`,
|
|
470
|
+
* default `false`. Gates the U1 blocks gallery, U3's development
|
|
471
|
+
* error bodies (validation errors in `surface_failed` responses) and
|
|
472
|
+
* U4 — a boot constant, like the rest of meta.
|
|
473
|
+
*/
|
|
474
|
+
readonly dev: boolean;
|
|
451
475
|
/**
|
|
452
476
|
* The seam inventory (docs/approval-ux-seams.md): per extension, the
|
|
453
477
|
* interaction kinds / ambient surface keys its factory declared.
|
|
@@ -573,6 +597,23 @@ export interface ExtensionInfo {
|
|
|
573
597
|
readonly workers: readonly WorkerStatus[];
|
|
574
598
|
/** The declared HTTP routes, one `{method, path, auth}` each (W5 Task 2). */
|
|
575
599
|
routes?: readonly ExtensionRouteInfo[];
|
|
600
|
+
/** The declared surfaces, one `{id, title, icon, placement}` each (U3 Task 1); absent when none. */
|
|
601
|
+
surfaces?: readonly ExtensionSurfaceInfo[];
|
|
602
|
+
/**
|
|
603
|
+
* The channel ids this extension contributes (gateway C1, spec §7):
|
|
604
|
+
* present only on rows of extensions whose factory result carried
|
|
605
|
+
* `channels`; unique across every loaded extension (a collision
|
|
606
|
+
* quarantines the later loader). Absent when the extension declared
|
|
607
|
+
* none.
|
|
608
|
+
*/
|
|
609
|
+
readonly channels?: readonly string[];
|
|
610
|
+
/**
|
|
611
|
+
* The inert marker (gateway C2): `"no gateway"` on rows of
|
|
612
|
+
* extensions that contributed `channels` while NO gateway engine
|
|
613
|
+
* loaded — their adapters are inert (nothing drives them; one boot
|
|
614
|
+
* warning says so). Absent everywhere else.
|
|
615
|
+
*/
|
|
616
|
+
readonly inert?: "no gateway";
|
|
576
617
|
/**
|
|
577
618
|
* Built-in extensions (Task 2, pi parity): `true` marks a core-shipped
|
|
578
619
|
* built-in (codemode / MCP / tool search); ABSENT on configured
|
|
@@ -591,6 +632,26 @@ export interface ExtensionRouteInfo {
|
|
|
591
632
|
readonly path: string;
|
|
592
633
|
readonly auth: string;
|
|
593
634
|
}
|
|
635
|
+
/**
|
|
636
|
+
* One `GET /v1/extensions` surface row (UI-blocks U3 Task 1, spec
|
|
637
|
+
* §7.1): the extension-declared views and panels — what the channels'
|
|
638
|
+
* rail (views) and right panel (panels) register from. One row per
|
|
639
|
+
* declared surface, in declaration order (views before panels).
|
|
640
|
+
*/
|
|
641
|
+
export interface ExtensionSurfaceInfo {
|
|
642
|
+
readonly id: string;
|
|
643
|
+
readonly title: string;
|
|
644
|
+
readonly icon: string;
|
|
645
|
+
/** The declared placement; `settings` sections (§13.3) are not in this workstream. */
|
|
646
|
+
readonly placement: "view" | "panel";
|
|
647
|
+
/** The declared refresh cadence (spec §7.1); channels refetch data on
|
|
648
|
+
* this interval while the surface is visible. Absent → no cadence. */
|
|
649
|
+
readonly refreshMs?: number;
|
|
650
|
+
/** §7.3 shared-data flag: a sharedData surface's `since` fetches may
|
|
651
|
+
* answer with `ops` and NO `data` — channels fall back to a full
|
|
652
|
+
* fetch (ops folding is U1). Absent → per-instance data. */
|
|
653
|
+
readonly sharedData?: boolean;
|
|
654
|
+
}
|
|
594
655
|
/** The `GET /v1/extensions` payload (spec §7.7). */
|
|
595
656
|
export interface ExtensionsResponse {
|
|
596
657
|
readonly extensions: readonly ExtensionInfo[];
|
|
@@ -614,7 +675,11 @@ export type { SessionMeta, SessionMetaPatch } from "./session-meta.js";
|
|
|
614
675
|
* The `GET /v1/auth/whoami` payload (core hardening W1 Task 3, spec
|
|
615
676
|
* §5.8): the resolved principal, verbatim. `user` is absent only under
|
|
616
677
|
* the naive empty-method path with no `X-Sigrun-User` header;
|
|
617
|
-
* `service` marks the env service token.
|
|
678
|
+
* `service` marks the env service token. `method` mirrors the extension
|
|
679
|
+
* contract's `Principal.method` (gateway C4b added `"host"` — an
|
|
680
|
+
* in-process host-built principal; no HTTP route ever resolves one, but
|
|
681
|
+
* the two unions stay aligned so the whoami build from a principal can
|
|
682
|
+
* never drift from the wire type).
|
|
618
683
|
*/
|
|
619
684
|
export interface WhoamiResponse {
|
|
620
685
|
readonly user?: string;
|
|
@@ -622,7 +687,7 @@ export interface WhoamiResponse {
|
|
|
622
687
|
readonly email?: string;
|
|
623
688
|
readonly admin: boolean;
|
|
624
689
|
readonly service: boolean;
|
|
625
|
-
readonly method: "none" | "token" | "proxy";
|
|
690
|
+
readonly method: "none" | "token" | "proxy" | "host";
|
|
626
691
|
}
|
|
627
692
|
/**
|
|
628
693
|
* The `GET /v1/onboarding` payload (core hardening W1 Task 4, spec
|
|
@@ -646,12 +711,19 @@ export interface OnboardingState {
|
|
|
646
711
|
* One directory user on the wire (Task 4): the full record — emails are
|
|
647
712
|
* admin-visible material and the routes that serve this type are
|
|
648
713
|
* admin-gated. `createdAt` is epoch ms.
|
|
714
|
+
*
|
|
715
|
+
* `admin` is the STORED flag (the users-admin UI toggles it); the proxy
|
|
716
|
+
* group grant rides separately as `groupAdmin` (gateway C8): effective
|
|
717
|
+
* admin is `admin || groupAdmin === true`, and the last-admin guard
|
|
718
|
+
* counts `admin` alone.
|
|
649
719
|
*/
|
|
650
720
|
export interface UserWire {
|
|
651
721
|
readonly user: string;
|
|
652
722
|
readonly name?: string;
|
|
653
723
|
readonly email?: string;
|
|
654
724
|
readonly admin: boolean;
|
|
725
|
+
/** The persisted proxy-group grant — present only under `adminGroups`. */
|
|
726
|
+
readonly groupAdmin?: boolean;
|
|
655
727
|
readonly createdAt: number;
|
|
656
728
|
readonly source: "proxy" | "invite" | "cli";
|
|
657
729
|
}
|
|
@@ -739,4 +811,12 @@ export type HostEventWire = {
|
|
|
739
811
|
/** W4 Task 4 (§8.4): the changed job's summary, WITHOUT `access` — the events stream computes `accessOf` per principal and adds it before delivery (a hidden job's event is withheld entirely). */
|
|
740
812
|
readonly type: "job.changed";
|
|
741
813
|
readonly job: Omit<JobWire, "access">;
|
|
814
|
+
} | {
|
|
815
|
+
/** UI-blocks U3 Task 4 (spec §7.3): one surface instance changed. `k` is the hashed instance key (sha256(slug + "\0" + id + "\0" + key) hex) — the event NEVER carries params or data (render/data are principal-specific; the watcher refetches as itself). Delivered only to streams in the watcher registry whose stored access is not `"none"`. */
|
|
816
|
+
readonly type: "surface.changed";
|
|
817
|
+
readonly slug: string;
|
|
818
|
+
readonly id: string;
|
|
819
|
+
readonly k: string;
|
|
820
|
+
readonly rev: number;
|
|
821
|
+
readonly treeRev: number;
|
|
742
822
|
};
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sigrun/shared",
|
|
3
|
-
"version": "0.1.
|
|
4
|
-
"description": "sigrun shared leaf package
|
|
3
|
+
"version": "0.1.2",
|
|
4
|
+
"description": "sigrun shared leaf package \u2014 theme tokens, turn/conversation shaping, and the channel wire types (pure leaf, zero dependencies)",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
7
7
|
"./themes": {
|
|
@@ -44,6 +44,10 @@
|
|
|
44
44
|
"types": "./dist/views.d.ts",
|
|
45
45
|
"default": "./dist/views.js"
|
|
46
46
|
},
|
|
47
|
+
"./live": {
|
|
48
|
+
"types": "./dist/live.d.ts",
|
|
49
|
+
"default": "./dist/live.js"
|
|
50
|
+
},
|
|
47
51
|
"./view-delta": {
|
|
48
52
|
"types": "./dist/view-delta.d.ts",
|
|
49
53
|
"default": "./dist/view-delta.js"
|
|
@@ -51,6 +55,10 @@
|
|
|
51
55
|
"./jobs": {
|
|
52
56
|
"types": "./dist/jobs.d.ts",
|
|
53
57
|
"default": "./dist/jobs.js"
|
|
58
|
+
},
|
|
59
|
+
"./blocks": {
|
|
60
|
+
"types": "./dist/blocks/index.d.ts",
|
|
61
|
+
"default": "./dist/blocks/index.js"
|
|
54
62
|
}
|
|
55
63
|
},
|
|
56
64
|
"scripts": {
|