@ikenga/contract 0.11.0 → 0.12.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.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/pa-actions.d.ts +35 -0
- package/dist/pa-actions.d.ts.map +1 -1
- package/dist/pa-actions.js.map +1 -1
- package/dist/window.d.ts +128 -0
- package/dist/window.d.ts.map +1 -0
- package/dist/window.js +86 -0
- package/dist/window.js.map +1 -0
- package/package.json +5 -1
- package/src/index.ts +1 -0
- package/src/pa-actions.ts +38 -0
- package/src/window.test.ts +70 -0
- package/src/window.ts +100 -0
package/dist/index.d.ts
CHANGED
|
@@ -8,6 +8,7 @@ export * from './artifact.js';
|
|
|
8
8
|
export * from './registry.js';
|
|
9
9
|
export * from './browser.js';
|
|
10
10
|
export * from './pa-actions.js';
|
|
11
|
+
export * from './window.js';
|
|
11
12
|
/** This package's own version. */
|
|
12
13
|
export declare const CONTRACT_PACKAGE_VERSION: "0.5.0";
|
|
13
14
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,eAAe,CAAC;AAC9B,cAAc,UAAU,CAAC;AACzB,cAAc,iBAAiB,CAAC;AAChC,cAAc,mBAAmB,CAAC;AAClC,cAAc,aAAa,CAAC;AAC5B,cAAc,WAAW,CAAC;AAC1B,cAAc,eAAe,CAAC;AAC9B,cAAc,eAAe,CAAC;AAC9B,cAAc,cAAc,CAAC;AAC7B,cAAc,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,eAAe,CAAC;AAC9B,cAAc,UAAU,CAAC;AACzB,cAAc,iBAAiB,CAAC;AAChC,cAAc,mBAAmB,CAAC;AAClC,cAAc,aAAa,CAAC;AAC5B,cAAc,WAAW,CAAC;AAC1B,cAAc,eAAe,CAAC;AAC9B,cAAc,eAAe,CAAC;AAC9B,cAAc,cAAc,CAAC;AAC7B,cAAc,iBAAiB,CAAC;AAChC,cAAc,aAAa,CAAC;AAE5B,kCAAkC;AAClC,eAAO,MAAM,wBAAwB,EAAG,OAAgB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -8,6 +8,7 @@ export * from './artifact.js';
|
|
|
8
8
|
export * from './registry.js';
|
|
9
9
|
export * from './browser.js';
|
|
10
10
|
export * from './pa-actions.js';
|
|
11
|
+
export * from './window.js';
|
|
11
12
|
/** This package's own version. */
|
|
12
13
|
export const CONTRACT_PACKAGE_VERSION = '0.5.0';
|
|
13
14
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,eAAe,CAAC;AAC9B,cAAc,UAAU,CAAC;AACzB,cAAc,iBAAiB,CAAC;AAChC,cAAc,mBAAmB,CAAC;AAClC,cAAc,aAAa,CAAC;AAC5B,cAAc,WAAW,CAAC;AAC1B,cAAc,eAAe,CAAC;AAC9B,cAAc,eAAe,CAAC;AAC9B,cAAc,cAAc,CAAC;AAC7B,cAAc,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,eAAe,CAAC;AAC9B,cAAc,UAAU,CAAC;AACzB,cAAc,iBAAiB,CAAC;AAChC,cAAc,mBAAmB,CAAC;AAClC,cAAc,aAAa,CAAC;AAC5B,cAAc,WAAW,CAAC;AAC1B,cAAc,eAAe,CAAC;AAC9B,cAAc,eAAe,CAAC;AAC9B,cAAc,cAAc,CAAC;AAC7B,cAAc,iBAAiB,CAAC;AAChC,cAAc,aAAa,CAAC;AAE5B,kCAAkC;AAClC,MAAM,CAAC,MAAM,wBAAwB,GAAG,OAAgB,CAAC"}
|
package/dist/pa-actions.d.ts
CHANGED
|
@@ -27,6 +27,25 @@ export interface DraftSequence {
|
|
|
27
27
|
/** Audience size for this step (e.g. a 388-recipient newsletter section). */
|
|
28
28
|
recipients: number;
|
|
29
29
|
}
|
|
30
|
+
/** One sub-post in an X/Twitter thread (X allows ≤4 images per tweet). */
|
|
31
|
+
export interface ThreadPost {
|
|
32
|
+
text: string;
|
|
33
|
+
/** Per-sub-post media URLs (X allows ≤4 images per tweet). */
|
|
34
|
+
imageUrls?: string[];
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Media block carried on a Buffer DraftItem. `kind` selects the adapter path:
|
|
38
|
+
* - `'single'` — 0–1 image attached to the post body.
|
|
39
|
+
* - `'carousel'` — 2–10 images (IG ≤10, LI ≤9); adapter uses multi-asset upload.
|
|
40
|
+
* - `'thread'` — ordered sub-posts; adapter posts as N linked Buffer posts (≥2, ≤25).
|
|
41
|
+
*/
|
|
42
|
+
export interface SocialMedia {
|
|
43
|
+
kind: 'single' | 'carousel' | 'thread';
|
|
44
|
+
/** single = 0–1 image URL; carousel = 2–10 (platform-dependent). */
|
|
45
|
+
imageUrls?: string[];
|
|
46
|
+
/** thread-kind only: ordered sub-posts (≥2, ≤25). */
|
|
47
|
+
thread?: ThreadPost[];
|
|
48
|
+
}
|
|
30
49
|
/**
|
|
31
50
|
* What an approve-aware action emits per draft — the lean, authoritative
|
|
32
51
|
* producer shape. The shell derives the panel's `PausedDraft` from this via
|
|
@@ -82,6 +101,22 @@ export interface DraftItem {
|
|
|
82
101
|
threadCount?: string;
|
|
83
102
|
/** Explicit section bucket; otherwise derived from `scheduledIso`. */
|
|
84
103
|
section?: string;
|
|
104
|
+
/**
|
|
105
|
+
* Resolved Buffer channel id — company vs personal LinkedIn disambiguated at
|
|
106
|
+
* enqueue time (not in the adapter). Only set for `channel: 'buffer'` drafts.
|
|
107
|
+
*/
|
|
108
|
+
channelId?: string;
|
|
109
|
+
/**
|
|
110
|
+
* First comment text for hashtags / blog URL. Avoids Buffer link-preview
|
|
111
|
+
* attachment errors on LinkedIn. Mapped to `metadata.<platform>.firstComment`.
|
|
112
|
+
*/
|
|
113
|
+
firstComment?: string;
|
|
114
|
+
/**
|
|
115
|
+
* Social media block; selects single / carousel / thread adapter path.
|
|
116
|
+
* Kept in lockstep with `payload.schema.ts` `SocialMedia` Zod schema and
|
|
117
|
+
* the worker mirror in `scripts/cron/lib/channels/types.ts`.
|
|
118
|
+
*/
|
|
119
|
+
media?: SocialMedia;
|
|
85
120
|
}
|
|
86
121
|
/**
|
|
87
122
|
* Partial-success result returned by a `ChannelAdapter.send()` call (DEC-9).
|
package/dist/pa-actions.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pa-actions.d.ts","sourceRoot":"","sources":["../src/pa-actions.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,gFAAgF;AAChF,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG,QAAQ,GAAG,UAAU,GAAG,QAAQ,CAAC;AAErE,qCAAqC;AACrC,eAAO,MAAM,aAAa,EAAE,MAAM,CAAC,YAAY,EAAE,MAAM,CAKtD,CAAC;AAEF,mEAAmE;AACnE,MAAM,WAAW,aAAa;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,6EAA6E;IAC7E,UAAU,EAAE,MAAM,CAAC;CACnB;AAED;;;;;GAKG;AACH,MAAM,WAAW,SAAS;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,8FAA8F;IAC9F,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,YAAY,CAAC;IACtB,2EAA2E;IAC3E,aAAa,EAAE,MAAM,CAAC;IACtB,qDAAqD;IACrD,YAAY,EAAE,MAAM,CAAC;IACrB,2DAA2D;IAC3D,IAAI,CAAC,EAAE,OAAO,CAAC;IACf;;;;OAIG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;;;;OAKG;IACH,cAAc,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IACpD;;;OAGG;IACH,UAAU,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAC7B,gEAAgE;IAChE,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,mFAAmF;IACnF,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,sEAAsE;IACtE,cAAc,EAAE,MAAM,CAAC;IACvB,kGAAkG;IAClG,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,EAAE,aAAa,GAAG,IAAI,CAAC;IAChC,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,sEAAsE;IACtE,OAAO,CAAC,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"pa-actions.d.ts","sourceRoot":"","sources":["../src/pa-actions.ts"],"names":[],"mappings":"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"}
|
package/dist/pa-actions.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pa-actions.js","sourceRoot":"","sources":["../src/pa-actions.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAKH,qCAAqC;AACrC,MAAM,CAAC,MAAM,aAAa,GAAiC;IAC1D,IAAI,EAAE,MAAM;IACZ,MAAM,EAAE,QAAQ;IAChB,QAAQ,EAAE,UAAU;IACpB,MAAM,EAAE,QAAQ;CAChB,CAAC;
|
|
1
|
+
{"version":3,"file":"pa-actions.js","sourceRoot":"","sources":["../src/pa-actions.ts"],"names":[],"mappings":"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"}
|
package/dist/window.d.ts
ADDED
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
/** Envelope + descriptor wire version. Bumped on non-additive change. */
|
|
3
|
+
export declare const WINDOW_CONTRACT_VERSION: 1;
|
|
4
|
+
/**
|
|
5
|
+
* What a window is.
|
|
6
|
+
* - `primary` — the original "main" window (full chrome).
|
|
7
|
+
* - `single-surface` — a thin detached window hosting one surface (Flavor C).
|
|
8
|
+
* - `pane-set` — a torn-off pane group (Flavor A, Phase 2).
|
|
9
|
+
* - `workspace` — a second full workspace window (Flavor B, Phase 3).
|
|
10
|
+
*/
|
|
11
|
+
export declare const WindowKindSchema: z.ZodEnum<["primary", "single-surface", "pane-set", "workspace"]>;
|
|
12
|
+
export type WindowKind = z.infer<typeof WindowKindSchema>;
|
|
13
|
+
export declare const WindowDescriptorSchema: z.ZodObject<{
|
|
14
|
+
/** OS window label. "main" for the primary; "detached-<n>" otherwise. */
|
|
15
|
+
label: z.ZodString;
|
|
16
|
+
kind: z.ZodEnum<["primary", "single-surface", "pane-set", "workspace"]>;
|
|
17
|
+
/** Surface/route ids the window's FE entry mounts. */
|
|
18
|
+
surface_set: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
|
|
19
|
+
/** Project this window is bound to (Flavor B); null = follows primary. */
|
|
20
|
+
project_id: z.ZodDefault<z.ZodNullable<z.ZodString>>;
|
|
21
|
+
/**
|
|
22
|
+
* SQLite `layout_state` partition. A KEY-STRING suffix folded into
|
|
23
|
+
* `scopedKey()` (G-03) — NOT a new column. Usually equals `label`.
|
|
24
|
+
*/
|
|
25
|
+
layout_key: z.ZodString;
|
|
26
|
+
}, "strict", z.ZodTypeAny, {
|
|
27
|
+
label: string;
|
|
28
|
+
kind: "primary" | "single-surface" | "pane-set" | "workspace";
|
|
29
|
+
surface_set: string[];
|
|
30
|
+
project_id: string | null;
|
|
31
|
+
layout_key: string;
|
|
32
|
+
}, {
|
|
33
|
+
label: string;
|
|
34
|
+
kind: "primary" | "single-surface" | "pane-set" | "workspace";
|
|
35
|
+
layout_key: string;
|
|
36
|
+
surface_set?: string[] | undefined;
|
|
37
|
+
project_id?: string | null | undefined;
|
|
38
|
+
}>;
|
|
39
|
+
export type WindowDescriptor = z.infer<typeof WindowDescriptorSchema>;
|
|
40
|
+
/**
|
|
41
|
+
* Where a window event goes. The DEFAULT for streaming/data channels is
|
|
42
|
+
* `broadcast` (every window filters its own subscription); only the channels
|
|
43
|
+
* that race (see WINDOW_TARGETED_CHANNELS) carry `window` targeting.
|
|
44
|
+
*/
|
|
45
|
+
export declare const WindowEventTargetSchema: z.ZodDiscriminatedUnion<"kind", [z.ZodObject<{
|
|
46
|
+
kind: z.ZodLiteral<"broadcast">;
|
|
47
|
+
}, "strict", z.ZodTypeAny, {
|
|
48
|
+
kind: "broadcast";
|
|
49
|
+
}, {
|
|
50
|
+
kind: "broadcast";
|
|
51
|
+
}>, z.ZodObject<{
|
|
52
|
+
kind: z.ZodLiteral<"window">;
|
|
53
|
+
label: z.ZodString;
|
|
54
|
+
}, "strict", z.ZodTypeAny, {
|
|
55
|
+
label: string;
|
|
56
|
+
kind: "window";
|
|
57
|
+
}, {
|
|
58
|
+
label: string;
|
|
59
|
+
kind: "window";
|
|
60
|
+
}>]>;
|
|
61
|
+
export type WindowEventTarget = z.infer<typeof WindowEventTargetSchema>;
|
|
62
|
+
/**
|
|
63
|
+
* The base shape every cross-window event rides. `payload` is opaque at the
|
|
64
|
+
* contract layer (each topic refines it); the envelope itself is what the
|
|
65
|
+
* registry + windows agree on.
|
|
66
|
+
*/
|
|
67
|
+
export declare const WindowEventEnvelopeSchema: z.ZodObject<{
|
|
68
|
+
v: z.ZodLiteral<1>;
|
|
69
|
+
/** Channel name, e.g. "window://opened". */
|
|
70
|
+
topic: z.ZodString;
|
|
71
|
+
/** Emitting window label, or "core" for the Rust core. */
|
|
72
|
+
source_label: z.ZodString;
|
|
73
|
+
target: z.ZodDiscriminatedUnion<"kind", [z.ZodObject<{
|
|
74
|
+
kind: z.ZodLiteral<"broadcast">;
|
|
75
|
+
}, "strict", z.ZodTypeAny, {
|
|
76
|
+
kind: "broadcast";
|
|
77
|
+
}, {
|
|
78
|
+
kind: "broadcast";
|
|
79
|
+
}>, z.ZodObject<{
|
|
80
|
+
kind: z.ZodLiteral<"window">;
|
|
81
|
+
label: z.ZodString;
|
|
82
|
+
}, "strict", z.ZodTypeAny, {
|
|
83
|
+
label: string;
|
|
84
|
+
kind: "window";
|
|
85
|
+
}, {
|
|
86
|
+
label: string;
|
|
87
|
+
kind: "window";
|
|
88
|
+
}>]>;
|
|
89
|
+
payload: z.ZodUnknown;
|
|
90
|
+
}, "strict", z.ZodTypeAny, {
|
|
91
|
+
v: 1;
|
|
92
|
+
topic: string;
|
|
93
|
+
source_label: string;
|
|
94
|
+
target: {
|
|
95
|
+
kind: "broadcast";
|
|
96
|
+
} | {
|
|
97
|
+
label: string;
|
|
98
|
+
kind: "window";
|
|
99
|
+
};
|
|
100
|
+
payload?: unknown;
|
|
101
|
+
}, {
|
|
102
|
+
v: 1;
|
|
103
|
+
topic: string;
|
|
104
|
+
source_label: string;
|
|
105
|
+
target: {
|
|
106
|
+
kind: "broadcast";
|
|
107
|
+
} | {
|
|
108
|
+
label: string;
|
|
109
|
+
kind: "window";
|
|
110
|
+
};
|
|
111
|
+
payload?: unknown;
|
|
112
|
+
}>;
|
|
113
|
+
export type WindowEventEnvelope = z.infer<typeof WindowEventEnvelopeSchema>;
|
|
114
|
+
/** Canonical window-lifecycle channels emitted by the Rust core. */
|
|
115
|
+
export declare const WINDOW_TOPICS: {
|
|
116
|
+
readonly opened: "window://opened";
|
|
117
|
+
readonly closed: "window://closed";
|
|
118
|
+
readonly focusChanged: "window://focus-changed";
|
|
119
|
+
};
|
|
120
|
+
export type WindowTopic = (typeof WINDOW_TOPICS)[keyof typeof WINDOW_TOPICS];
|
|
121
|
+
/**
|
|
122
|
+
* Channels that MUST be window-targeted (`emit_to`) rather than broadcast,
|
|
123
|
+
* because a broadcast races across windows (first-reply-wins / wrong-window).
|
|
124
|
+
* Everything not listed here stays broadcast + per-window topic filtering.
|
|
125
|
+
* (plans/multi-window 03-research-internal: the ~25-channel routing table.)
|
|
126
|
+
*/
|
|
127
|
+
export declare const WINDOW_TARGETED_CHANNELS: readonly ["screenshot://request", "screenshot://shortcut", "projects:active-changed"];
|
|
128
|
+
//# sourceMappingURL=window.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"window.d.ts","sourceRoot":"","sources":["../src/window.ts"],"names":[],"mappings":"AAUA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,yEAAyE;AACzE,eAAO,MAAM,uBAAuB,EAAG,CAAU,CAAC;AAIlD;;;;;;GAMG;AACH,eAAO,MAAM,gBAAgB,mEAK3B,CAAC;AACH,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAE1D,eAAO,MAAM,sBAAsB;IAEjC,yEAAyE;;;IAGzE,sDAAsD;;IAEtD,0EAA0E;;IAE1E;;;OAGG;;;;;;;;;;;;;;EAGK,CAAC;AACX,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,sBAAsB,CAAC,CAAC;AAItE;;;;GAIG;AACH,eAAO,MAAM,uBAAuB;;;;;;;;;;;;;;;IAGlC,CAAC;AACH,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,uBAAuB,CAAC,CAAC;AAExE;;;;GAIG;AACH,eAAO,MAAM,yBAAyB;;IAGpC,4CAA4C;;IAE5C,0DAA0D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAKlD,CAAC;AACX,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,yBAAyB,CAAC,CAAC;AAE5E,oEAAoE;AACpE,eAAO,MAAM,aAAa;;;;CAIhB,CAAC;AACX,MAAM,MAAM,WAAW,GAAG,CAAC,OAAO,aAAa,CAAC,CAAC,MAAM,OAAO,aAAa,CAAC,CAAC;AAE7E;;;;;GAKG;AACH,eAAO,MAAM,wBAAwB,uFAI3B,CAAC"}
|
package/dist/window.js
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
// Multi-window contract — mirrors the Rust source-of-truth in
|
|
2
|
+
// `royalti-io/ikenga` at `src-tauri/src/window/{descriptor,events}.rs`.
|
|
3
|
+
//
|
|
4
|
+
// This is the `G-WINDOW-MODEL` freeze-gate output (plans/multi-window WP-02).
|
|
5
|
+
// It has TWO co-equal halves: the `WindowDescriptor` (what a window IS) and the
|
|
6
|
+
// cross-window event envelope (how windows talk over the shared Rust core).
|
|
7
|
+
// Both are imported by every downstream consumer (the window registry, the thin
|
|
8
|
+
// detached FE entry, Flavor C). Field changes MUST be made in lockstep with the
|
|
9
|
+
// Rust structs; bump WINDOW_CONTRACT_VERSION on any non-additive change.
|
|
10
|
+
import { z } from 'zod';
|
|
11
|
+
/** Envelope + descriptor wire version. Bumped on non-additive change. */
|
|
12
|
+
export const WINDOW_CONTRACT_VERSION = 1;
|
|
13
|
+
// ---------- WindowDescriptor ----------
|
|
14
|
+
/**
|
|
15
|
+
* What a window is.
|
|
16
|
+
* - `primary` — the original "main" window (full chrome).
|
|
17
|
+
* - `single-surface` — a thin detached window hosting one surface (Flavor C).
|
|
18
|
+
* - `pane-set` — a torn-off pane group (Flavor A, Phase 2).
|
|
19
|
+
* - `workspace` — a second full workspace window (Flavor B, Phase 3).
|
|
20
|
+
*/
|
|
21
|
+
export const WindowKindSchema = z.enum([
|
|
22
|
+
'primary',
|
|
23
|
+
'single-surface',
|
|
24
|
+
'pane-set',
|
|
25
|
+
'workspace',
|
|
26
|
+
]);
|
|
27
|
+
export const WindowDescriptorSchema = z
|
|
28
|
+
.object({
|
|
29
|
+
/** OS window label. "main" for the primary; "detached-<n>" otherwise. */
|
|
30
|
+
label: z.string().min(1),
|
|
31
|
+
kind: WindowKindSchema,
|
|
32
|
+
/** Surface/route ids the window's FE entry mounts. */
|
|
33
|
+
surface_set: z.array(z.string()).default([]),
|
|
34
|
+
/** Project this window is bound to (Flavor B); null = follows primary. */
|
|
35
|
+
project_id: z.string().nullable().default(null),
|
|
36
|
+
/**
|
|
37
|
+
* SQLite `layout_state` partition. A KEY-STRING suffix folded into
|
|
38
|
+
* `scopedKey()` (G-03) — NOT a new column. Usually equals `label`.
|
|
39
|
+
*/
|
|
40
|
+
layout_key: z.string().min(1),
|
|
41
|
+
})
|
|
42
|
+
.strict();
|
|
43
|
+
// ---------- Cross-window event envelope ----------
|
|
44
|
+
/**
|
|
45
|
+
* Where a window event goes. The DEFAULT for streaming/data channels is
|
|
46
|
+
* `broadcast` (every window filters its own subscription); only the channels
|
|
47
|
+
* that race (see WINDOW_TARGETED_CHANNELS) carry `window` targeting.
|
|
48
|
+
*/
|
|
49
|
+
export const WindowEventTargetSchema = z.discriminatedUnion('kind', [
|
|
50
|
+
z.object({ kind: z.literal('broadcast') }).strict(),
|
|
51
|
+
z.object({ kind: z.literal('window'), label: z.string().min(1) }).strict(),
|
|
52
|
+
]);
|
|
53
|
+
/**
|
|
54
|
+
* The base shape every cross-window event rides. `payload` is opaque at the
|
|
55
|
+
* contract layer (each topic refines it); the envelope itself is what the
|
|
56
|
+
* registry + windows agree on.
|
|
57
|
+
*/
|
|
58
|
+
export const WindowEventEnvelopeSchema = z
|
|
59
|
+
.object({
|
|
60
|
+
v: z.literal(WINDOW_CONTRACT_VERSION),
|
|
61
|
+
/** Channel name, e.g. "window://opened". */
|
|
62
|
+
topic: z.string().min(1),
|
|
63
|
+
/** Emitting window label, or "core" for the Rust core. */
|
|
64
|
+
source_label: z.string().min(1),
|
|
65
|
+
target: WindowEventTargetSchema,
|
|
66
|
+
payload: z.unknown(),
|
|
67
|
+
})
|
|
68
|
+
.strict();
|
|
69
|
+
/** Canonical window-lifecycle channels emitted by the Rust core. */
|
|
70
|
+
export const WINDOW_TOPICS = {
|
|
71
|
+
opened: 'window://opened',
|
|
72
|
+
closed: 'window://closed',
|
|
73
|
+
focusChanged: 'window://focus-changed',
|
|
74
|
+
};
|
|
75
|
+
/**
|
|
76
|
+
* Channels that MUST be window-targeted (`emit_to`) rather than broadcast,
|
|
77
|
+
* because a broadcast races across windows (first-reply-wins / wrong-window).
|
|
78
|
+
* Everything not listed here stays broadcast + per-window topic filtering.
|
|
79
|
+
* (plans/multi-window 03-research-internal: the ~25-channel routing table.)
|
|
80
|
+
*/
|
|
81
|
+
export const WINDOW_TARGETED_CHANNELS = [
|
|
82
|
+
'screenshot://request',
|
|
83
|
+
'screenshot://shortcut',
|
|
84
|
+
'projects:active-changed',
|
|
85
|
+
];
|
|
86
|
+
//# sourceMappingURL=window.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"window.js","sourceRoot":"","sources":["../src/window.ts"],"names":[],"mappings":"AAAA,8DAA8D;AAC9D,wEAAwE;AACxE,EAAE;AACF,8EAA8E;AAC9E,gFAAgF;AAChF,4EAA4E;AAC5E,gFAAgF;AAChF,gFAAgF;AAChF,yEAAyE;AAEzE,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,yEAAyE;AACzE,MAAM,CAAC,MAAM,uBAAuB,GAAG,CAAU,CAAC;AAElD,yCAAyC;AAEzC;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,CAAC,IAAI,CAAC;IACtC,SAAS;IACT,gBAAgB;IAChB,UAAU;IACV,WAAW;CACX,CAAC,CAAC;AAGH,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAAC;KACrC,MAAM,CAAC;IACP,yEAAyE;IACzE,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IACxB,IAAI,EAAE,gBAAgB;IACtB,sDAAsD;IACtD,WAAW,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC;IAC5C,0EAA0E;IAC1E,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC;IAC/C;;;OAGG;IACH,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;CAC7B,CAAC;KACD,MAAM,EAAE,CAAC;AAGX,oDAAoD;AAEpD;;;;GAIG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAAG,CAAC,CAAC,kBAAkB,CAAC,MAAM,EAAE;IACnE,CAAC,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC,MAAM,EAAE;IACnD,CAAC,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,MAAM,EAAE;CAC1E,CAAC,CAAC;AAGH;;;;GAIG;AACH,MAAM,CAAC,MAAM,yBAAyB,GAAG,CAAC;KACxC,MAAM,CAAC;IACP,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,uBAAuB,CAAC;IACrC,4CAA4C;IAC5C,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IACxB,0DAA0D;IAC1D,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IAC/B,MAAM,EAAE,uBAAuB;IAC/B,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE;CACpB,CAAC;KACD,MAAM,EAAE,CAAC;AAGX,oEAAoE;AACpE,MAAM,CAAC,MAAM,aAAa,GAAG;IAC5B,MAAM,EAAE,iBAAiB;IACzB,MAAM,EAAE,iBAAiB;IACzB,YAAY,EAAE,wBAAwB;CAC7B,CAAC;AAGX;;;;;GAKG;AACH,MAAM,CAAC,MAAM,wBAAwB,GAAG;IACvC,sBAAsB;IACtB,uBAAuB;IACvB,yBAAyB;CAChB,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ikenga/contract",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.12.0",
|
|
4
4
|
"description": "Shared contract for the Ikenga pkg system: manifest schema, RPC types, Engine interface, capability scopes.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"repository": {
|
|
@@ -55,6 +55,10 @@
|
|
|
55
55
|
"./pa-actions": {
|
|
56
56
|
"types": "./dist/pa-actions.d.ts",
|
|
57
57
|
"import": "./dist/pa-actions.js"
|
|
58
|
+
},
|
|
59
|
+
"./window": {
|
|
60
|
+
"types": "./dist/window.d.ts",
|
|
61
|
+
"import": "./dist/window.js"
|
|
58
62
|
}
|
|
59
63
|
},
|
|
60
64
|
"files": [
|
package/src/index.ts
CHANGED
package/src/pa-actions.ts
CHANGED
|
@@ -36,6 +36,27 @@ export interface DraftSequence {
|
|
|
36
36
|
recipients: number;
|
|
37
37
|
}
|
|
38
38
|
|
|
39
|
+
/** One sub-post in an X/Twitter thread (X allows ≤4 images per tweet). */
|
|
40
|
+
export interface ThreadPost {
|
|
41
|
+
text: string;
|
|
42
|
+
/** Per-sub-post media URLs (X allows ≤4 images per tweet). */
|
|
43
|
+
imageUrls?: string[];
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Media block carried on a Buffer DraftItem. `kind` selects the adapter path:
|
|
48
|
+
* - `'single'` — 0–1 image attached to the post body.
|
|
49
|
+
* - `'carousel'` — 2–10 images (IG ≤10, LI ≤9); adapter uses multi-asset upload.
|
|
50
|
+
* - `'thread'` — ordered sub-posts; adapter posts as N linked Buffer posts (≥2, ≤25).
|
|
51
|
+
*/
|
|
52
|
+
export interface SocialMedia {
|
|
53
|
+
kind: 'single' | 'carousel' | 'thread';
|
|
54
|
+
/** single = 0–1 image URL; carousel = 2–10 (platform-dependent). */
|
|
55
|
+
imageUrls?: string[];
|
|
56
|
+
/** thread-kind only: ordered sub-posts (≥2, ≤25). */
|
|
57
|
+
thread?: ThreadPost[];
|
|
58
|
+
}
|
|
59
|
+
|
|
39
60
|
/**
|
|
40
61
|
* What an approve-aware action emits per draft — the lean, authoritative
|
|
41
62
|
* producer shape. The shell derives the panel's `PausedDraft` from this via
|
|
@@ -88,6 +109,23 @@ export interface DraftItem {
|
|
|
88
109
|
threadCount?: string;
|
|
89
110
|
/** Explicit section bucket; otherwise derived from `scheduledIso`. */
|
|
90
111
|
section?: string;
|
|
112
|
+
// ── Buffer / social fields (mirror of payload_json media contract) ──────────
|
|
113
|
+
/**
|
|
114
|
+
* Resolved Buffer channel id — company vs personal LinkedIn disambiguated at
|
|
115
|
+
* enqueue time (not in the adapter). Only set for `channel: 'buffer'` drafts.
|
|
116
|
+
*/
|
|
117
|
+
channelId?: string;
|
|
118
|
+
/**
|
|
119
|
+
* First comment text for hashtags / blog URL. Avoids Buffer link-preview
|
|
120
|
+
* attachment errors on LinkedIn. Mapped to `metadata.<platform>.firstComment`.
|
|
121
|
+
*/
|
|
122
|
+
firstComment?: string;
|
|
123
|
+
/**
|
|
124
|
+
* Social media block; selects single / carousel / thread adapter path.
|
|
125
|
+
* Kept in lockstep with `payload.schema.ts` `SocialMedia` Zod schema and
|
|
126
|
+
* the worker mirror in `scripts/cron/lib/channels/types.ts`.
|
|
127
|
+
*/
|
|
128
|
+
media?: SocialMedia;
|
|
91
129
|
}
|
|
92
130
|
|
|
93
131
|
/**
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import assert from 'node:assert/strict';
|
|
2
|
+
import { test } from 'node:test';
|
|
3
|
+
import {
|
|
4
|
+
WINDOW_CONTRACT_VERSION,
|
|
5
|
+
WindowDescriptorSchema,
|
|
6
|
+
WindowEventEnvelopeSchema,
|
|
7
|
+
} from './window.js';
|
|
8
|
+
|
|
9
|
+
// Canonical wire fixtures — the Rust round-trip test
|
|
10
|
+
// (src-tauri/src/window/descriptor.rs + events.rs) asserts the SAME JSON.
|
|
11
|
+
// If these drift, the lockstep contract is broken.
|
|
12
|
+
|
|
13
|
+
const DESCRIPTOR_FIXTURE = {
|
|
14
|
+
label: 'detached-1',
|
|
15
|
+
kind: 'single-surface',
|
|
16
|
+
surface_set: ['chat'],
|
|
17
|
+
project_id: null,
|
|
18
|
+
layout_key: 'detached-1',
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
const ENVELOPE_FIXTURE = {
|
|
22
|
+
v: 1,
|
|
23
|
+
topic: 'window://opened',
|
|
24
|
+
source_label: 'core',
|
|
25
|
+
target: { kind: 'window', label: 'detached-1' },
|
|
26
|
+
payload: { label: 'detached-1' },
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
test('WindowDescriptor parses the canonical fixture and round-trips', () => {
|
|
30
|
+
const parsed = WindowDescriptorSchema.parse(DESCRIPTOR_FIXTURE);
|
|
31
|
+
assert.deepEqual(parsed, DESCRIPTOR_FIXTURE);
|
|
32
|
+
// re-parse the serialized form (round-trip)
|
|
33
|
+
assert.deepEqual(
|
|
34
|
+
WindowDescriptorSchema.parse(JSON.parse(JSON.stringify(parsed))),
|
|
35
|
+
DESCRIPTOR_FIXTURE,
|
|
36
|
+
);
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
test('WindowDescriptor rejects unknown keys (deny_unknown_fields parity)', () => {
|
|
40
|
+
assert.throws(() =>
|
|
41
|
+
WindowDescriptorSchema.parse({ ...DESCRIPTOR_FIXTURE, rogue: true }),
|
|
42
|
+
);
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
test('WindowDescriptor applies defaults for surface_set/project_id', () => {
|
|
46
|
+
const parsed = WindowDescriptorSchema.parse({
|
|
47
|
+
label: 'main',
|
|
48
|
+
kind: 'primary',
|
|
49
|
+
layout_key: 'main',
|
|
50
|
+
});
|
|
51
|
+
assert.deepEqual(parsed.surface_set, []);
|
|
52
|
+
assert.equal(parsed.project_id, null);
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
test('WindowEventEnvelope parses the canonical fixture and round-trips', () => {
|
|
56
|
+
const parsed = WindowEventEnvelopeSchema.parse(ENVELOPE_FIXTURE);
|
|
57
|
+
assert.equal(parsed.v, WINDOW_CONTRACT_VERSION);
|
|
58
|
+
assert.deepEqual(
|
|
59
|
+
WindowEventEnvelopeSchema.parse(JSON.parse(JSON.stringify(parsed))),
|
|
60
|
+
ENVELOPE_FIXTURE,
|
|
61
|
+
);
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
test('WindowEventTarget broadcast variant parses', () => {
|
|
65
|
+
const parsed = WindowEventEnvelopeSchema.parse({
|
|
66
|
+
...ENVELOPE_FIXTURE,
|
|
67
|
+
target: { kind: 'broadcast' },
|
|
68
|
+
});
|
|
69
|
+
assert.equal(parsed.target.kind, 'broadcast');
|
|
70
|
+
});
|
package/src/window.ts
ADDED
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
// Multi-window contract — mirrors the Rust source-of-truth in
|
|
2
|
+
// `royalti-io/ikenga` at `src-tauri/src/window/{descriptor,events}.rs`.
|
|
3
|
+
//
|
|
4
|
+
// This is the `G-WINDOW-MODEL` freeze-gate output (plans/multi-window WP-02).
|
|
5
|
+
// It has TWO co-equal halves: the `WindowDescriptor` (what a window IS) and the
|
|
6
|
+
// cross-window event envelope (how windows talk over the shared Rust core).
|
|
7
|
+
// Both are imported by every downstream consumer (the window registry, the thin
|
|
8
|
+
// detached FE entry, Flavor C). Field changes MUST be made in lockstep with the
|
|
9
|
+
// Rust structs; bump WINDOW_CONTRACT_VERSION on any non-additive change.
|
|
10
|
+
|
|
11
|
+
import { z } from 'zod';
|
|
12
|
+
|
|
13
|
+
/** Envelope + descriptor wire version. Bumped on non-additive change. */
|
|
14
|
+
export const WINDOW_CONTRACT_VERSION = 1 as const;
|
|
15
|
+
|
|
16
|
+
// ---------- WindowDescriptor ----------
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* What a window is.
|
|
20
|
+
* - `primary` — the original "main" window (full chrome).
|
|
21
|
+
* - `single-surface` — a thin detached window hosting one surface (Flavor C).
|
|
22
|
+
* - `pane-set` — a torn-off pane group (Flavor A, Phase 2).
|
|
23
|
+
* - `workspace` — a second full workspace window (Flavor B, Phase 3).
|
|
24
|
+
*/
|
|
25
|
+
export const WindowKindSchema = z.enum([
|
|
26
|
+
'primary',
|
|
27
|
+
'single-surface',
|
|
28
|
+
'pane-set',
|
|
29
|
+
'workspace',
|
|
30
|
+
]);
|
|
31
|
+
export type WindowKind = z.infer<typeof WindowKindSchema>;
|
|
32
|
+
|
|
33
|
+
export const WindowDescriptorSchema = z
|
|
34
|
+
.object({
|
|
35
|
+
/** OS window label. "main" for the primary; "detached-<n>" otherwise. */
|
|
36
|
+
label: z.string().min(1),
|
|
37
|
+
kind: WindowKindSchema,
|
|
38
|
+
/** Surface/route ids the window's FE entry mounts. */
|
|
39
|
+
surface_set: z.array(z.string()).default([]),
|
|
40
|
+
/** Project this window is bound to (Flavor B); null = follows primary. */
|
|
41
|
+
project_id: z.string().nullable().default(null),
|
|
42
|
+
/**
|
|
43
|
+
* SQLite `layout_state` partition. A KEY-STRING suffix folded into
|
|
44
|
+
* `scopedKey()` (G-03) — NOT a new column. Usually equals `label`.
|
|
45
|
+
*/
|
|
46
|
+
layout_key: z.string().min(1),
|
|
47
|
+
})
|
|
48
|
+
.strict();
|
|
49
|
+
export type WindowDescriptor = z.infer<typeof WindowDescriptorSchema>;
|
|
50
|
+
|
|
51
|
+
// ---------- Cross-window event envelope ----------
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Where a window event goes. The DEFAULT for streaming/data channels is
|
|
55
|
+
* `broadcast` (every window filters its own subscription); only the channels
|
|
56
|
+
* that race (see WINDOW_TARGETED_CHANNELS) carry `window` targeting.
|
|
57
|
+
*/
|
|
58
|
+
export const WindowEventTargetSchema = z.discriminatedUnion('kind', [
|
|
59
|
+
z.object({ kind: z.literal('broadcast') }).strict(),
|
|
60
|
+
z.object({ kind: z.literal('window'), label: z.string().min(1) }).strict(),
|
|
61
|
+
]);
|
|
62
|
+
export type WindowEventTarget = z.infer<typeof WindowEventTargetSchema>;
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* The base shape every cross-window event rides. `payload` is opaque at the
|
|
66
|
+
* contract layer (each topic refines it); the envelope itself is what the
|
|
67
|
+
* registry + windows agree on.
|
|
68
|
+
*/
|
|
69
|
+
export const WindowEventEnvelopeSchema = z
|
|
70
|
+
.object({
|
|
71
|
+
v: z.literal(WINDOW_CONTRACT_VERSION),
|
|
72
|
+
/** Channel name, e.g. "window://opened". */
|
|
73
|
+
topic: z.string().min(1),
|
|
74
|
+
/** Emitting window label, or "core" for the Rust core. */
|
|
75
|
+
source_label: z.string().min(1),
|
|
76
|
+
target: WindowEventTargetSchema,
|
|
77
|
+
payload: z.unknown(),
|
|
78
|
+
})
|
|
79
|
+
.strict();
|
|
80
|
+
export type WindowEventEnvelope = z.infer<typeof WindowEventEnvelopeSchema>;
|
|
81
|
+
|
|
82
|
+
/** Canonical window-lifecycle channels emitted by the Rust core. */
|
|
83
|
+
export const WINDOW_TOPICS = {
|
|
84
|
+
opened: 'window://opened',
|
|
85
|
+
closed: 'window://closed',
|
|
86
|
+
focusChanged: 'window://focus-changed',
|
|
87
|
+
} as const;
|
|
88
|
+
export type WindowTopic = (typeof WINDOW_TOPICS)[keyof typeof WINDOW_TOPICS];
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Channels that MUST be window-targeted (`emit_to`) rather than broadcast,
|
|
92
|
+
* because a broadcast races across windows (first-reply-wins / wrong-window).
|
|
93
|
+
* Everything not listed here stays broadcast + per-window topic filtering.
|
|
94
|
+
* (plans/multi-window 03-research-internal: the ~25-channel routing table.)
|
|
95
|
+
*/
|
|
96
|
+
export const WINDOW_TARGETED_CHANNELS = [
|
|
97
|
+
'screenshot://request',
|
|
98
|
+
'screenshot://shortcut',
|
|
99
|
+
'projects:active-changed',
|
|
100
|
+
] as const;
|