@mirrowel/opencode-openshare 0.0.0-stage → 0.1.1
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/LICENSE +21 -0
- package/README.md +181 -2
- package/ci/README.md +56 -0
- package/ci/openshare.config.json +10 -0
- package/ci/openshare.js +2270 -0
- package/dist/commands.d.ts +7 -0
- package/dist/commands.js +440 -0
- package/dist/config.d.ts +138 -0
- package/dist/config.js +524 -0
- package/dist/core.d.ts +117 -0
- package/dist/core.js +1944 -0
- package/dist/dialogs.d.ts +94 -0
- package/dist/dialogs.js +725 -0
- package/dist/server.d.ts +64 -0
- package/dist/server.js +30 -0
- package/dist/settings.d.ts +24 -0
- package/dist/settings.js +1226 -0
- package/dist/share-flow.d.ts +287 -0
- package/dist/share-flow.js +516 -0
- package/dist/sidebar.d.ts +19 -0
- package/dist/sidebar.js +144 -0
- package/dist/tui-host.d.ts +158 -0
- package/dist/tui-host.js +6 -0
- package/dist/tui.d.ts +17 -0
- package/dist/tui.js +4719 -0
- package/dist/ui-prefs.d.ts +16 -0
- package/dist/ui-prefs.js +27 -0
- package/dist/v2-server.d.ts +81 -0
- package/dist/v2-server.js +402 -0
- package/dist/v2-tui.d.ts +24 -0
- package/dist/v2-tui.js +313 -0
- package/dist/v2-types.d.ts +134 -0
- package/dist/v2-types.js +8 -0
- package/openshare.config.json +16 -0
- package/package.json +98 -4
- package/src/banner.txt +25 -0
- package/src/commands.ts +452 -0
- package/src/config.ts +524 -0
- package/src/core.ts +1997 -0
- package/src/dialogs.tsx +971 -0
- package/src/server.ts +47 -0
- package/src/settings.ts +1239 -0
- package/src/share-flow.ts +551 -0
- package/src/sidebar.tsx +187 -0
- package/src/tui-host.ts +134 -0
- package/src/tui.tsx +318 -0
- package/src/ui-prefs.ts +36 -0
- package/src/v2-server.ts +438 -0
- package/src/v2-tui.ts +315 -0
- package/src/v2-types.ts +102 -0
- package/tsconfig.json +18 -0
|
@@ -0,0 +1,287 @@
|
|
|
1
|
+
import { saveServerEntry, deleteServerEntry, type ShareConfig, type ServerEntry } from "./config.js";
|
|
2
|
+
import type { ClientApi, SessionInfo, SessionOpts } from "./core.js";
|
|
3
|
+
import type { ShareHostApi } from "./tui-host.js";
|
|
4
|
+
export type SessionBinding = {
|
|
5
|
+
id: string;
|
|
6
|
+
secret: string;
|
|
7
|
+
rev: number;
|
|
8
|
+
url: string;
|
|
9
|
+
enabled?: boolean;
|
|
10
|
+
opts?: SessionOpts;
|
|
11
|
+
};
|
|
12
|
+
export declare const CONSENT_KV_KEY = "openshare_consent";
|
|
13
|
+
export declare function pluginConfigPaths(baseDir?: string): string[];
|
|
14
|
+
export declare function currentConfig(baseDir?: string): ShareConfig;
|
|
15
|
+
/** Writes the config file. Target rule (owner-directed): the global
|
|
16
|
+
* settings home by default, or an explicit existing file chosen in the
|
|
17
|
+
* TUI — NEVER "first existing in the read chain" (that wrote TUI edits
|
|
18
|
+
* into the tracked adjacent template, live-caught). $comment and foreign
|
|
19
|
+
* keys preserved. */
|
|
20
|
+
export declare function saveConfig(cfg: ShareConfig, target?: string, baseDir?: string): {
|
|
21
|
+
path: string;
|
|
22
|
+
} | undefined;
|
|
23
|
+
export declare function isConfigured(cfg: ShareConfig): boolean;
|
|
24
|
+
/** The resolved active server (url + entry), for the TUI server rows. */
|
|
25
|
+
export declare function activeServer(cfg?: ShareConfig): {
|
|
26
|
+
url: string;
|
|
27
|
+
token: string;
|
|
28
|
+
entry: ServerEntry;
|
|
29
|
+
} | undefined;
|
|
30
|
+
export declare function serverEntries(cfg?: ShareConfig): Array<{
|
|
31
|
+
url: string;
|
|
32
|
+
entry: ServerEntry;
|
|
33
|
+
active: boolean;
|
|
34
|
+
}>;
|
|
35
|
+
export { saveServerEntry, deleteServerEntry };
|
|
36
|
+
/** All live per-server bindings from a v2 (or legacy v1) metadata record. */
|
|
37
|
+
export declare function bindingsOf(info: SessionInfo | undefined): Array<SessionBinding & {
|
|
38
|
+
server: string;
|
|
39
|
+
collided?: string;
|
|
40
|
+
}>;
|
|
41
|
+
/** Read every live binding for a session (fan-out aware). */
|
|
42
|
+
export declare function readBindings(client: ClientApi | undefined, sid: string): Promise<Array<SessionBinding & {
|
|
43
|
+
server: string;
|
|
44
|
+
collided?: string;
|
|
45
|
+
}>>;
|
|
46
|
+
export declare function hostOf(url: string): string;
|
|
47
|
+
/** Mutate metadata.openshare.servers[url] through a patcher (TUI per-
|
|
48
|
+
* server actions: opt-out entries, collision resolution). Reads-modifies-
|
|
49
|
+
* writes the whole metadata to keep foreign keys intact. */
|
|
50
|
+
export declare function patchSessionBinding(client: ClientApi | undefined, sid: string, mutator: (servers: Record<string, unknown>, binding: Record<string, unknown>) => void): Promise<boolean>;
|
|
51
|
+
/** The display/primary binding: the active server's entry when bound
|
|
52
|
+
* there, else the first live entry (single-server configs are unchanged). */
|
|
53
|
+
export declare function bindingOf(info: SessionInfo | undefined): SessionBinding | undefined;
|
|
54
|
+
/** Walks parentID up to the root session (the share owns the whole tree). */
|
|
55
|
+
export declare function resolveRoot(client: ClientApi | undefined, sid: string): Promise<string>;
|
|
56
|
+
export declare function readBinding(client: ClientApi | undefined, sid: string): Promise<SessionBinding | undefined>;
|
|
57
|
+
/** Sets metadata.openshare = { ...existing(v2 structure preserved),
|
|
58
|
+
* enabled: true, opts? }. The per-server binding entries are the ENGINE's
|
|
59
|
+
* to manage; the flag just opts the session in. */
|
|
60
|
+
export declare function setShareFlag(client: ClientApi | undefined, sid: string, opts?: SessionOpts): Promise<boolean>;
|
|
61
|
+
export declare function clearShareFlag(client: ClientApi | undefined, sid: string): Promise<boolean>;
|
|
62
|
+
export declare function workerDeleteShare(workerUrl: string, id: string, secret: string): Promise<boolean>;
|
|
63
|
+
/** Health probe for the settings dialog's connection test. */
|
|
64
|
+
export declare function probeWorker(workerUrl: string): Promise<{
|
|
65
|
+
ok: boolean;
|
|
66
|
+
detail: string;
|
|
67
|
+
}>;
|
|
68
|
+
/** Share liveness probe — the "session says shared but the link is dead"
|
|
69
|
+
* case (purged, TTL-expired, or deleted while the binding stayed in
|
|
70
|
+
* session metadata). GET /data answers 404 {status:"gone"} BEFORE the
|
|
71
|
+
* read-auth gate, so this is a credential-free existence check that
|
|
72
|
+
* works identically on the CF worker and the Bun server. Network errors
|
|
73
|
+
* return "unknown" — never auto-disable on unknown. */
|
|
74
|
+
export declare function verifyShare(workerUrl: string, shareId: string): Promise<"live" | "gone" | "unknown">;
|
|
75
|
+
/** Remove the binding entries for shares that no longer exist server-side
|
|
76
|
+
* (the auto-disable half of gone detection). Entries are deleted outright —
|
|
77
|
+
* not optedOut — so a later prompt in the session can create a fresh share. */
|
|
78
|
+
export declare function clearGoneBindingEntries(host: ShareHostApi, root: string, servers: string[]): Promise<boolean>;
|
|
79
|
+
export declare function normServerUrl(url: string): string;
|
|
80
|
+
/** /health probe including the auth mode (public enrolls anyone). */
|
|
81
|
+
export declare function probeAuthMode(workerUrl: string): Promise<{
|
|
82
|
+
ok: boolean;
|
|
83
|
+
mode?: "public" | "private";
|
|
84
|
+
detail: string;
|
|
85
|
+
}>;
|
|
86
|
+
export declare function enrollAtServer(workerUrl: string, code: string): Promise<{
|
|
87
|
+
ok: boolean;
|
|
88
|
+
token?: string;
|
|
89
|
+
userId?: string;
|
|
90
|
+
label?: string;
|
|
91
|
+
error?: string;
|
|
92
|
+
}>;
|
|
93
|
+
export declare function rotateAtServer(workerUrl: string, token: string): Promise<{
|
|
94
|
+
ok: boolean;
|
|
95
|
+
token?: string;
|
|
96
|
+
error?: string;
|
|
97
|
+
}>;
|
|
98
|
+
export declare function disconnectAtServer(workerUrl: string, token: string): Promise<{
|
|
99
|
+
ok: boolean;
|
|
100
|
+
error?: string;
|
|
101
|
+
}>;
|
|
102
|
+
export type AdminUser = {
|
|
103
|
+
id: string;
|
|
104
|
+
label: string;
|
|
105
|
+
createdAt: number;
|
|
106
|
+
frozen: boolean;
|
|
107
|
+
shares: number;
|
|
108
|
+
tokens: number;
|
|
109
|
+
tokensActive: number;
|
|
110
|
+
};
|
|
111
|
+
export type AdminToken = {
|
|
112
|
+
id: string;
|
|
113
|
+
userId: string;
|
|
114
|
+
label: string;
|
|
115
|
+
limits: Record<string, number>;
|
|
116
|
+
createdAt: number;
|
|
117
|
+
lastUsedAt: number;
|
|
118
|
+
expiresAt: number;
|
|
119
|
+
revoked: boolean;
|
|
120
|
+
};
|
|
121
|
+
export type AdminCode = {
|
|
122
|
+
id: string;
|
|
123
|
+
label: string;
|
|
124
|
+
activationsLeft: number;
|
|
125
|
+
used: number;
|
|
126
|
+
createdAt: number;
|
|
127
|
+
expiresAt: number;
|
|
128
|
+
disabled: boolean;
|
|
129
|
+
};
|
|
130
|
+
export type AdminShare = {
|
|
131
|
+
id: string;
|
|
132
|
+
createdAt: number;
|
|
133
|
+
sessionID?: string;
|
|
134
|
+
ownerId?: string | null;
|
|
135
|
+
};
|
|
136
|
+
/** Thin typed client for the worker's /api/admin surface. `token` must be
|
|
137
|
+
* the server's root CREATE_TOKEN (user osk_ tokens get 403). */
|
|
138
|
+
export declare function adminClient(workerUrl: string, token: string): {
|
|
139
|
+
users: () => Promise<{
|
|
140
|
+
ok: boolean;
|
|
141
|
+
status: number;
|
|
142
|
+
data?: {
|
|
143
|
+
users: AdminUser[];
|
|
144
|
+
} | undefined;
|
|
145
|
+
error?: string;
|
|
146
|
+
}>;
|
|
147
|
+
createUser: (label: string) => Promise<{
|
|
148
|
+
ok: boolean;
|
|
149
|
+
status: number;
|
|
150
|
+
data?: {
|
|
151
|
+
userId: string;
|
|
152
|
+
label: string;
|
|
153
|
+
} | undefined;
|
|
154
|
+
error?: string;
|
|
155
|
+
}>;
|
|
156
|
+
freeze: (userId: string) => Promise<{
|
|
157
|
+
ok: boolean;
|
|
158
|
+
status: number;
|
|
159
|
+
data?: {
|
|
160
|
+
frozen: boolean;
|
|
161
|
+
shares: number;
|
|
162
|
+
} | undefined;
|
|
163
|
+
error?: string;
|
|
164
|
+
}>;
|
|
165
|
+
unfreeze: (userId: string) => Promise<{
|
|
166
|
+
ok: boolean;
|
|
167
|
+
status: number;
|
|
168
|
+
data?: {
|
|
169
|
+
frozen: boolean;
|
|
170
|
+
shares: number;
|
|
171
|
+
} | undefined;
|
|
172
|
+
error?: string;
|
|
173
|
+
}>;
|
|
174
|
+
deleteUser: (userId: string, mode: "freeze" | "delete") => Promise<{
|
|
175
|
+
ok: boolean;
|
|
176
|
+
status: number;
|
|
177
|
+
data?: {
|
|
178
|
+
mode: string;
|
|
179
|
+
shares: number;
|
|
180
|
+
} | undefined;
|
|
181
|
+
error?: string;
|
|
182
|
+
}>;
|
|
183
|
+
tokens: () => Promise<{
|
|
184
|
+
ok: boolean;
|
|
185
|
+
status: number;
|
|
186
|
+
data?: {
|
|
187
|
+
tokens: AdminToken[];
|
|
188
|
+
} | undefined;
|
|
189
|
+
error?: string;
|
|
190
|
+
}>;
|
|
191
|
+
mintToken: (userId: string, label?: string, limits?: Record<string, number>) => Promise<{
|
|
192
|
+
ok: boolean;
|
|
193
|
+
status: number;
|
|
194
|
+
data?: {
|
|
195
|
+
token: string;
|
|
196
|
+
id: string;
|
|
197
|
+
} | undefined;
|
|
198
|
+
error?: string;
|
|
199
|
+
}>;
|
|
200
|
+
revokeToken: (tokenId: string) => Promise<{
|
|
201
|
+
ok: boolean;
|
|
202
|
+
status: number;
|
|
203
|
+
data?: unknown;
|
|
204
|
+
error?: string;
|
|
205
|
+
}>;
|
|
206
|
+
codes: () => Promise<{
|
|
207
|
+
ok: boolean;
|
|
208
|
+
status: number;
|
|
209
|
+
data?: {
|
|
210
|
+
codes: AdminCode[];
|
|
211
|
+
} | undefined;
|
|
212
|
+
error?: string;
|
|
213
|
+
}>;
|
|
214
|
+
createCode: (label: string, activations: number) => Promise<{
|
|
215
|
+
ok: boolean;
|
|
216
|
+
status: number;
|
|
217
|
+
data?: {
|
|
218
|
+
code: string;
|
|
219
|
+
id: string;
|
|
220
|
+
activationsLeft: number;
|
|
221
|
+
} | undefined;
|
|
222
|
+
error?: string;
|
|
223
|
+
}>;
|
|
224
|
+
disableCode: (codeId: string) => Promise<{
|
|
225
|
+
ok: boolean;
|
|
226
|
+
status: number;
|
|
227
|
+
data?: unknown;
|
|
228
|
+
error?: string;
|
|
229
|
+
}>;
|
|
230
|
+
shares: () => Promise<{
|
|
231
|
+
ok: boolean;
|
|
232
|
+
status: number;
|
|
233
|
+
data?: {
|
|
234
|
+
shares: AdminShare[];
|
|
235
|
+
} | undefined;
|
|
236
|
+
error?: string;
|
|
237
|
+
}>;
|
|
238
|
+
deleteShare: (shareId: string) => Promise<{
|
|
239
|
+
ok: boolean;
|
|
240
|
+
status: number;
|
|
241
|
+
data?: unknown;
|
|
242
|
+
error?: string;
|
|
243
|
+
}>;
|
|
244
|
+
reassign: (shareId: string, userId: string) => Promise<{
|
|
245
|
+
ok: boolean;
|
|
246
|
+
status: number;
|
|
247
|
+
data?: unknown;
|
|
248
|
+
error?: string;
|
|
249
|
+
}>;
|
|
250
|
+
purge: () => Promise<{
|
|
251
|
+
ok: boolean;
|
|
252
|
+
status: number;
|
|
253
|
+
data?: {
|
|
254
|
+
removed: number;
|
|
255
|
+
} | undefined;
|
|
256
|
+
error?: string;
|
|
257
|
+
}>;
|
|
258
|
+
health: () => Promise<{
|
|
259
|
+
ok: boolean;
|
|
260
|
+
status: number;
|
|
261
|
+
data?: {
|
|
262
|
+
ok: boolean;
|
|
263
|
+
service: string;
|
|
264
|
+
policy: Record<string, unknown>;
|
|
265
|
+
auth: {
|
|
266
|
+
mode: string;
|
|
267
|
+
};
|
|
268
|
+
} | undefined;
|
|
269
|
+
error?: string;
|
|
270
|
+
}>;
|
|
271
|
+
};
|
|
272
|
+
/** Resolve the admin credential for a server: the entry's adminToken, the
|
|
273
|
+
* legacy createToken (when it points at this server), or prompt. */
|
|
274
|
+
export declare function adminTokenFor(url: string, cfg?: ShareConfig): string;
|
|
275
|
+
/** Waits for the server plugin to publish the binding URL (poll; robust on
|
|
276
|
+
* both hosts). Resolves the binding, or undefined on timeout. */
|
|
277
|
+
export declare function waitForBinding(client: ClientApi | undefined, sid: string, timeoutMs?: number): Promise<SessionBinding | undefined>;
|
|
278
|
+
export type FlowResult = {
|
|
279
|
+
ok: boolean;
|
|
280
|
+
message: string;
|
|
281
|
+
url?: string;
|
|
282
|
+
unconfigured?: boolean;
|
|
283
|
+
};
|
|
284
|
+
export declare function runShareFlow(host: ShareHostApi, sessionID: string | undefined): Promise<FlowResult>;
|
|
285
|
+
/** Post-consent share: set the flag, wait for the URL, copy it. */
|
|
286
|
+
export declare function confirmShare(host: ShareHostApi, rootSessionID: string): Promise<FlowResult>;
|
|
287
|
+
export declare function runUnshareFlow(host: ShareHostApi, sessionID: string | undefined): Promise<FlowResult>;
|