@mirrowel/opencode-openshare 0.3.0-dev.4 → 0.3.0-dev.6

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 CHANGED
@@ -1,8 +1,28 @@
1
1
  # Open(code)Share plugin (`@mirrowel/opencode-openshare`)
2
2
 
3
- The opencode side of [Open(code)Share](../README.md) — session sharing for
3
+ The opencode side of [Open(code)Share](../README.md) - session sharing for
4
4
  OpenCode v1 and v2, self-hosted on your own worker.
5
5
 
6
+ **This package is only the plugin.** It captures and uploads sessions, but a
7
+ share needs a backend to upload to. OpenShare ships as four parts that
8
+ version and release together:
9
+
10
+ | Part | What it does | Where to get it |
11
+ |---|---|---|
12
+ | **This plugin** | hooks into opencode, syncs sessions | this npm package |
13
+ | **Worker** | the Cloudflare backend - stores shares, serves the viewer | deploy from the repo: `share-worker/` (3-command setup, see the repo README) |
14
+ | **Server** | self-hosted alternative to the worker - one Bun process, SQLite, Docker image | repo `share-server/` |
15
+ | **Viewer** | the share page - ships inside the worker/server assets; nothing to install separately | repo `share-viewer/` (embedded automatically) |
16
+
17
+ The repo also builds **offline snapshots** - a single self-contained HTML
18
+ file of any share, generated by the viewer's download button or the
19
+ `osh-snapshot` CLI - so a shared link keeps working even with no backend at
20
+ all.
21
+
22
+ Everything lives in one repository: **https://github.com/Mirrowel/openshare**
23
+ (clone it, or browse the [README](https://github.com/Mirrowel/openshare#readme)
24
+ for the full picture - deployment, configuration, and the viewer tour).
25
+
6
26
  Every plugin config key, its file chain, and the cross-package config surface are inventoried in [../CONFIGURATION.md](../CONFIGURATION.md).
7
27
 
8
28
  ## Artifacts
@@ -37,7 +57,9 @@ itself):
37
57
  opencode plugin add @mirrowel/opencode-openshare
38
58
  ```
39
59
 
40
- Restart opencode; `/share` and `/openshare` appear in the TUI.
60
+ Restart opencode; `/share` and `/openshare` appear in the TUI. The
61
+ settings dialog's title carries the running plugin's version (read from
62
+ its own package manifest at runtime).
41
63
 
42
64
  Then configure. For an npm install the durable config file is the
43
65
  **settings home** (`~/.config/opencode/openshare.config.json` — also
package/dist/config.d.ts CHANGED
@@ -62,6 +62,9 @@ export declare const DEFAULTS: ShareConfig;
62
62
  /** Directory of this module file (bundled standalone: the single file's
63
63
  * directory; package: dist/). */
64
64
  export declare function moduleDir(): string;
65
+ /** Version of the running plugin, from the package it was loaded from.
66
+ * "?" outside a package (single-file CI bundle with no sibling manifest). */
67
+ export declare function pluginVersion(): string;
65
68
  /** Nearest ancestor (starting at `start`) containing package.json. */
66
69
  export declare function packageRoot(start: string): string;
67
70
  /** Config file search paths for a plugin living at `pluginDir`.
package/dist/config.js CHANGED
@@ -51,6 +51,17 @@ const LOCAL_NAME = "openshare.local.json";
51
51
  export function moduleDir() {
52
52
  return dirname(fileURLToPath(import.meta.pathname ?? import.meta.url));
53
53
  }
54
+ /** Version of the running plugin, from the package it was loaded from.
55
+ * "?" outside a package (single-file CI bundle with no sibling manifest). */
56
+ export function pluginVersion() {
57
+ try {
58
+ const pkg = JSON.parse(readFileSync(join(packageRoot(moduleDir()), "package.json"), "utf8"));
59
+ return pkg.version ?? "?";
60
+ }
61
+ catch {
62
+ return "?";
63
+ }
64
+ }
54
65
  /** Nearest ancestor (starting at `start`) containing package.json. */
55
66
  export function packageRoot(start) {
56
67
  let current = start;
package/dist/settings.js CHANGED
@@ -4,7 +4,7 @@
4
4
  // run on the v1 TUI and the v2 dialog bridge.
5
5
  //
6
6
  // Sections: Connection, Sharing, Read auth, Advanced, This session.
7
- import { configSourceMap, moduleDir, writeCandidates } from "./config.js";
7
+ import { configSourceMap, moduleDir, pluginVersion, writeCandidates } from "./config.js";
8
8
  import { adminClient, adminTokenFor, currentConfig, deleteServerEntry, disconnectAtServer, enrollAtServer, fmtHours, parseTtlHours, hostOf, isConfigured, normServerUrl, probeAuthMode, probeWorker, patchSessionBinding, patchShareOpts, readBinding, readBindings, resolveRoot, rotateAtServer, runUnshareFlow, saveConfig, saveServerEntry, meClient, serverEntries, setShareOpts, shareWithConsent, workerDeleteShare, } from "./share-flow.js";
9
9
  import { DIALOG_WIDTH_COLUMNS, kvHeightPercentOf, kvWidthOf, nextDialogWidth, UI_HEIGHT_PERCENT_KV, UI_WIDTH_KV, clampHeightPercent } from "./ui-prefs.js";
10
10
  /** description suffix: `[from <source>]` when a key is overridden by a
@@ -1452,7 +1452,7 @@ export async function settingsDialog(host, startAtSession, startGroup) {
1452
1452
  help: group.help,
1453
1453
  }));
1454
1454
  options.push({ title: dirty ? "Save & exit" : "Exit", value: "action:exit", description: dirty ? `Write ${writeTarget.path}` : "No changes" });
1455
- const choice = await showSelect(host.ui, { title: "OpenShare settings", options });
1455
+ const choice = await showSelect(host.ui, { title: `OpenShare v${pluginVersion()} · settings`, options });
1456
1456
  if (choice === undefined || choice === "action:exit") {
1457
1457
  if (dirty) {
1458
1458
  const saved = saveConfig(cfg, writeTarget.path);
package/dist/tui.js CHANGED
@@ -36,6 +36,14 @@ var LOCAL_NAME = "openshare.local.json";
36
36
  function moduleDir() {
37
37
  return dirname(fileURLToPath(import.meta.pathname ?? import.meta.url));
38
38
  }
39
+ function pluginVersion() {
40
+ try {
41
+ const pkg = JSON.parse(readFileSync(join(packageRoot(moduleDir()), "package.json"), "utf8"));
42
+ return pkg.version ?? "?";
43
+ } catch {
44
+ return "?";
45
+ }
46
+ }
39
47
  function packageRoot(start) {
40
48
  let current = start;
41
49
  for (let guard = 0;guard < 16; guard++) {
@@ -2540,7 +2548,7 @@ Stored in the host's preference store \u2014 per machine, not the config file.`
2540
2548
  help: group.help
2541
2549
  }));
2542
2550
  options.push({ title: dirty ? "Save & exit" : "Exit", value: "action:exit", description: dirty ? `Write ${writeTarget.path}` : "No changes" });
2543
- const choice = await showSelect(host.ui, { title: "OpenShare settings", options });
2551
+ const choice = await showSelect(host.ui, { title: `OpenShare v${pluginVersion()} \xB7 settings`, options });
2544
2552
  if (choice === undefined || choice === "action:exit") {
2545
2553
  if (dirty) {
2546
2554
  const saved = saveConfig(cfg, writeTarget.path);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mirrowel/opencode-openshare",
3
- "version": "0.3.0-dev.4",
3
+ "version": "0.3.0-dev.6",
4
4
  "type": "module",
5
5
  "description": "Open(code)Share — re:share: self-hosted session sharing for opencode. Server plugin (single file or package), optional TUI for interactive opt-in sharing.",
6
6
  "license": "MIT",
@@ -64,10 +64,9 @@
64
64
  "build:tui": "bun scripts/build-tui.mjs",
65
65
  "build:standalone": "bun scripts/build-standalone.mjs",
66
66
  "typecheck": "tsc --noEmit",
67
- "ci": "npm run release:intent:check && npm run ci:package",
67
+ "ci": "npm run ci:package",
68
68
  "ci:package": "npm run typecheck && npm run build && npm run pack:dry-run",
69
- "release:intent": "node scripts/set-release-intent.mjs",
70
- "release:intent:check": "node scripts/check-release-intent.mjs",
69
+ "prepare": "node ../.github/scripts/install-hooks.mjs",
71
70
  "pack:dry-run": "node scripts/pack-dry-run.mjs",
72
71
  "test:regression": "node scripts/regression-tests.mjs",
73
72
  "prepublishOnly": "npm run typecheck && npm run build",
package/src/config.ts CHANGED
@@ -115,9 +115,19 @@ export function moduleDir(): string {
115
115
  return dirname(fileURLToPath((import.meta as { pathname?: string }).pathname ?? import.meta.url))
116
116
  }
117
117
 
118
+ /** Version of the running plugin, from the package it was loaded from.
119
+ * "?" outside a package (single-file CI bundle with no sibling manifest). */
120
+ export function pluginVersion(): string {
121
+ try {
122
+ const pkg = JSON.parse(readFileSync(join(packageRoot(moduleDir()), "package.json"), "utf8")) as { version?: string }
123
+ return pkg.version ?? "?"
124
+ } catch {
125
+ return "?"
126
+ }
127
+ }
128
+
118
129
  /** Nearest ancestor (starting at `start`) containing package.json. */
119
- export function packageRoot(start: string): string {
120
- let current = start
130
+ export function packageRoot(start: string): string { let current = start
121
131
  for (let guard = 0; guard < 16; guard++) {
122
132
  if (existsSync(join(current, "package.json"))) return current
123
133
  const parent = dirname(current)
package/src/settings.ts CHANGED
@@ -5,7 +5,7 @@
5
5
  //
6
6
  // Sections: Connection, Sharing, Read auth, Advanced, This session.
7
7
 
8
- import { configSourceMap, moduleDir, writeCandidates, type ShareConfig, type WriteCandidate } from "./config.js"
8
+ import { configSourceMap, moduleDir, pluginVersion, writeCandidates, type ShareConfig, type WriteCandidate } from "./config.js"
9
9
  import {
10
10
  adminClient,
11
11
  adminTokenFor,
@@ -1462,7 +1462,7 @@ export async function settingsDialog(host: ShareHostApi, startAtSession?: string
1462
1462
  }))
1463
1463
  options.push({ title: dirty ? "Save & exit" : "Exit", value: "action:exit", description: dirty ? `Write ${writeTarget.path}` : "No changes" })
1464
1464
 
1465
- const choice = await showSelect(host.ui, { title: "OpenShare settings", options })
1465
+ const choice = await showSelect(host.ui, { title: `OpenShare v${pluginVersion()} · settings`, options })
1466
1466
  if (choice === undefined || choice === "action:exit") {
1467
1467
  if (dirty) {
1468
1468
  const saved = saveConfig(cfg, writeTarget.path)