@mirrowel/opencode-openshare 0.2.1 → 0.3.0-dev.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/README.md +46 -26
- package/ci/README.md +30 -14
- package/ci/openshare.js +440 -61
- package/dist/binding-queue.js +2 -2
- package/dist/commands.js +8 -8
- package/dist/config.d.ts +34 -14
- package/dist/config.js +108 -33
- package/dist/contract.d.ts +5 -5
- package/dist/contract.js +5 -5
- package/dist/core.d.ts +12 -1
- package/dist/core.js +359 -138
- package/dist/dialogs.d.ts +9 -10
- package/dist/dialogs.js +25 -28
- package/dist/redact.d.ts +46 -0
- package/dist/redact.js +130 -0
- package/dist/settings.d.ts +10 -7
- package/dist/settings.js +136 -54
- package/dist/share-flow.d.ts +30 -6
- package/dist/share-flow.js +73 -18
- package/dist/tui.js +251 -59
- package/dist/ui-prefs.js +6 -6
- package/dist/v2-server.js +5 -6
- package/package.json +1 -1
- package/src/binding-queue.ts +2 -2
- package/src/commands.ts +8 -8
- package/src/config.ts +112 -29
- package/src/contract.ts +5 -5
- package/src/core.ts +339 -137
- package/src/dialogs.tsx +29 -32
- package/src/redact.ts +134 -0
- package/src/settings.ts +132 -52
- package/src/share-flow.ts +76 -20
- package/src/sidebar.tsx +7 -7
- package/src/tui.tsx +22 -24
- package/src/ui-prefs.ts +6 -6
- package/src/v2-server.ts +5 -6
package/README.md
CHANGED
|
@@ -14,8 +14,9 @@ Every plugin config key, its file chain, and the cross-package config surface ar
|
|
|
14
14
|
| `ci/openshare.js` | single-file, zero-dependency bundle of the same engine (committed; rebuilt by `npm run build`) | all-mode **by default** — it declares no TUI entry, but an explicit `shareMode` in config/env still wins |
|
|
15
15
|
|
|
16
16
|
All three are behavior-identical where they overlap — `npm run
|
|
17
|
-
test:regression`
|
|
18
|
-
|
|
17
|
+
test:regression` drives the single file and the package entry through
|
|
18
|
+
the same real lifecycle (a local worker, a mock provider, a real
|
|
19
|
+
`opencode serve`) and diffs the resulting share data.
|
|
19
20
|
|
|
20
21
|
## Install
|
|
21
22
|
|
|
@@ -61,12 +62,26 @@ spec `"file:///…/openshare/share-plugin"` in both config files (run
|
|
|
61
62
|
no build at all: [`ci/openshare.js`](ci/README.md), committed ready to
|
|
62
63
|
use.
|
|
63
64
|
|
|
64
|
-
**
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
65
|
+
**Server-held config sets**: set `configSet` (or
|
|
66
|
+
`OPENSHARE_CONFIG_SET`) to pick a named set provisioned on your server
|
|
67
|
+
token - the server applies its auth/TTL at create (nothing sensitive in
|
|
68
|
+
the repo), and suggests modelLabel/shareMode which the plugin adopts once
|
|
69
|
+
per boot when you haven't set them locally.
|
|
70
|
+
|
|
71
|
+
**Identity is never assumed**: with no token configured the plugin does
|
|
72
|
+
NOT silently enroll. A configured `code` IS expressed
|
|
73
|
+
intent — the engine enrolls with it headlessly (the CI shape). Without
|
|
74
|
+
one: public servers share **anonymously** (ownerless shares under the
|
|
75
|
+
server's global anonymous caps), private servers refuse with guidance.
|
|
76
|
+
Onboarding happens through the ask-once TUI flow — `/share` first run
|
|
77
|
+
or `/openshare` → Servers → Connect to a server offers "Onboard (get an
|
|
78
|
+
account)" vs "Stay anonymous" (with the differences explained), detects
|
|
79
|
+
whether a code is needed, and only then prompts for one; the outcome is
|
|
80
|
+
remembered per server (token = onboarded, `anonymous` flag = declined,
|
|
81
|
+
onboard later via the server menu's Enroll now). The enrolled token
|
|
82
|
+
persists to `~/.config/opencode/openshare.config.json` — enroll once per
|
|
83
|
+
server, then it just works. A revoked token re-enrolls the same way
|
|
84
|
+
(code configured / codeless server); if enrollment is impossible the
|
|
70
85
|
plugin says so on stderr and stops — no retry storms.
|
|
71
86
|
|
|
72
87
|
## Share modes
|
|
@@ -80,7 +95,7 @@ No selfwiring: which parts you install IS the switch.
|
|
|
80
95
|
|
|
81
96
|
Manual mode stores the opt-in in session metadata:
|
|
82
97
|
`metadata.openshare = { v: 2, enabled: true, opts? }` with per-session
|
|
83
|
-
overrides (`
|
|
98
|
+
overrides (`ttlHours`, `authLogin`, `authPassword`, `modelLabel`). The
|
|
84
99
|
per-server binding map (`servers: {url: {id, secret, rev, url}}`) is
|
|
85
100
|
written next to it — legacy flat bindings migrate at read. The key is
|
|
86
101
|
stripped from everything synced and never reaches viewers.
|
|
@@ -89,6 +104,19 @@ On OpenCode v2: the package declaring its `tui` entrypoint is the presence
|
|
|
89
104
|
signal (the v2 host auto-loads it); the single file declares none and
|
|
90
105
|
stays all-mode.
|
|
91
106
|
|
|
107
|
+
## Trust controls (config)
|
|
108
|
+
|
|
109
|
+
Client-side redaction runs at the engine's single enqueue choke point
|
|
110
|
+
(backfill and live events both), so stripped secrets never reach a
|
|
111
|
+
queue, spool or wire:
|
|
112
|
+
|
|
113
|
+
- `redact.patterns` — extra regexes (strings) redacted beside the built-in
|
|
114
|
+
detectors on UNGATED shares only (a gated share is already
|
|
115
|
+
login-private): GitHub/AWS/Slack/Google key shapes, `sk-` keys, Bearer
|
|
116
|
+
tokens, PEM private-key blocks, `.env`-shaped assignments and
|
|
117
|
+
connection-string passwords, replaced with `[redacted:<kind>]`. The
|
|
118
|
+
consent dialog previews counts and the first hits.
|
|
119
|
+
|
|
92
120
|
## TUI
|
|
93
121
|
|
|
94
122
|
- `/share` — share the session (explicit consent on EVERY creation —
|
|
@@ -96,12 +124,13 @@ stays all-mode.
|
|
|
96
124
|
session, shares the whole family. Already shared → the session menu,
|
|
97
125
|
identical to `/openshare → This session`: copy links (per server, or
|
|
98
126
|
all), stop sharing — delete or leave a snapshot, per-server stop on
|
|
99
|
-
multi-server shares —, share to another server, session TTL
|
|
127
|
+
multi-server shares —, share to another server, session TTL, read
|
|
100
128
|
auth. A credential conflict opens the collision dialog (copy debug
|
|
101
129
|
info / share on a new share / don't share).
|
|
102
130
|
- `/openshare` — grouped settings (compact root with live summaries →
|
|
103
131
|
focused submenus): This session (share/stop — delete or leave a
|
|
104
|
-
snapshot —, TTL override, session read auth),
|
|
132
|
+
snapshot —, TTL override, session read auth),
|
|
133
|
+
**Servers** (connection
|
|
105
134
|
AND membership: legacy pair, connect, enroll, rotate, get-a-user-token
|
|
106
135
|
for root holders, disconnect, per-server **admin panel** — users,
|
|
107
136
|
tokens, codes, shares, purge —, test, remove), Sharing (share mode +
|
|
@@ -126,7 +155,7 @@ stays all-mode.
|
|
|
126
155
|
npm install
|
|
127
156
|
npm run build # tsc -> dist/ + bun bundle -> ci/openshare.js (Bun on PATH)
|
|
128
157
|
npm run typecheck
|
|
129
|
-
npm run test # full matrix via the parallel driver (~
|
|
158
|
+
npm run test # full matrix via the parallel driver (~2.5 min)
|
|
130
159
|
npm run test:quick # everyday gate (~90s): parity + manual core + TUI + v2 + auth
|
|
131
160
|
```
|
|
132
161
|
|
|
@@ -135,20 +164,11 @@ watchdogged, port-swept, and drives real `opencode serve` instances with
|
|
|
135
164
|
a mock OpenAI-compatible provider — except where noted). The canonical
|
|
136
165
|
suite table — what each covers, including the big/backends scale suites —
|
|
137
166
|
lives in [`../DEVELOPMENT.md`](../DEVELOPMENT.md#test-suites); the
|
|
138
|
-
commands:
|
|
139
|
-
|
|
140
|
-
- `test:
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
timers, turn sockets, all-mode gating).
|
|
144
|
-
- `test:tui-flow` — share/manager flows, config write targets, enrollment,
|
|
145
|
-
admin console, gone detection.
|
|
146
|
-
- `test:v2` — the v2 adapter against a scripted mock v2 host.
|
|
147
|
-
- `test:auth` / `test:server-auth` — the identity contract (52 checks)
|
|
148
|
-
against the Cloudflare worker and the Bun backend.
|
|
149
|
-
- `test:enroll` / `test:server-enroll`, `test:fanout`, `test:big` /
|
|
150
|
-
`test:server-big` — enrollment lifecycle, multi-server fan-out,
|
|
151
|
-
big-session scale (both backends).
|
|
167
|
+
everyday commands:
|
|
168
|
+
|
|
169
|
+
- `test:quick` — the everyday gate: parity + manual core + TUI + v2 + auth.
|
|
170
|
+
- `test:auth` / `test:server-auth` — the identity contract against the
|
|
171
|
+
Cloudflare worker and the Bun backend.
|
|
152
172
|
- `test:cli`, `node scripts/npm-e2e.mjs` — real `opencode run` / the
|
|
153
173
|
published npm package — on demand only.
|
|
154
174
|
|
package/ci/README.md
CHANGED
|
@@ -31,10 +31,22 @@ README's [Configuration](../../README.md#configuration)):
|
|
|
31
31
|
|
|
32
32
|
```
|
|
33
33
|
OPENSHARE_WORKER_URL=https://your-host
|
|
34
|
-
OPENSHARE_CREATE_TOKEN
|
|
34
|
+
OPENSHARE_CREATE_TOKEN=: # legacy: root token
|
|
35
35
|
OPENSHARE_URL_FILE=share-urls.txt # each share URL appended + stderr line
|
|
36
36
|
```
|
|
37
37
|
|
|
38
|
+
CI conveniences:
|
|
39
|
+
|
|
40
|
+
- `OPENSHARE_CONFIG_JSON` - the whole config as one env var (same keys as
|
|
41
|
+
the config file), when mounting a file is awkward. A specific
|
|
42
|
+
`OPENSHARE_*` var still wins over it.
|
|
43
|
+
- `OPENSHARE_URL_FILE_FORMAT=json` - urlFile lines become
|
|
44
|
+
`{"id":"…","url":"…","status":"…","gated":false}` objects, one per
|
|
45
|
+
line, so workflow steps read fields instead of parsing URLs.
|
|
46
|
+
- `meta` in the config stamps free-form labels (env-interpolated, e.g.
|
|
47
|
+
`"branch": "${GITHUB_REF_NAME}"`) onto every share - visible in the
|
|
48
|
+
server's admin shares listing.
|
|
49
|
+
|
|
38
50
|
```jsonc
|
|
39
51
|
// openshare.config.json — enrollment shape (no root token needed)
|
|
40
52
|
{
|
|
@@ -44,22 +56,26 @@ OPENSHARE_URL_FILE=share-urls.txt # each share URL appended + stderr line
|
|
|
44
56
|
}
|
|
45
57
|
```
|
|
46
58
|
|
|
47
|
-
With no token held
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
59
|
+
With no token held the bundle never silently enrolls: a configured
|
|
60
|
+
`code` enrolls with it headlessly (the CI shape — each code use is one
|
|
61
|
+
enrollment); without one, public servers share anonymously (ownerless
|
|
62
|
+
shares under the server's global anonymous caps) and private servers
|
|
63
|
+
refuse with guidance. When enrollment does run, the token persists to
|
|
64
|
+
`~/.config/opencode/openshare.config.json` — enroll once, then every
|
|
65
|
+
run just shares. A revoked token re-enrolls the same way (code
|
|
66
|
+
configured / codeless server); if enrollment is impossible the error
|
|
67
|
+
lands on stderr and sharing stops (no retry storms).
|
|
53
68
|
|
|
54
69
|
**Ephemeral runners** (GitHub-hosted, containers): do NOT enroll through
|
|
55
70
|
a code - each fresh machine would burn one activation. Ask the hoster
|
|
56
|
-
for a pre-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
`
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
71
|
+
for a pre-registered token and pass it via `OPENSHARE_CREATE_TOKEN`
|
|
72
|
+
(or the config's token field); registered tokens skip enrollment
|
|
73
|
+
entirely and never expire on their own. A **scoped** token
|
|
74
|
+
(`POST /api/token {"kind":"scoped"}`, minted by any full token) is the
|
|
75
|
+
right credential here: it creates within its limits, reaches only the
|
|
76
|
+
shares it created, and revoking it never freezes the owner's account.
|
|
77
|
+
Point `OPENCODE_CONFIG_DIR` (or mount) the settings home at a cached
|
|
78
|
+
path only if you want the token persisted; env alone is enough.
|
|
63
79
|
|
|
64
80
|
The bundle also supports **fan-out**: multiple `active` servers in the
|
|
65
81
|
`servers` group each get the session (one urlFile line per server).
|