rewritable 0.7.0 → 0.8.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 CHANGED
@@ -31,6 +31,8 @@ rwa edit notes.html --plan plan.json # envelope from a file
31
31
 
32
32
  rwa doc notes.html # print the editable body
33
33
  rwa doc notes.html --json # read + edit-contract, one call
34
+ rwa workspace create research # → research/rwa-index.html
35
+ rwa workspace sync research # refresh the index from sibling rewritables
34
36
 
35
37
  rwa publish notes.html # → a hosted 24h share URL
36
38
  rwa host notes.html --url https://host.example # → {id, token, url} (round-trip editing)
@@ -49,6 +51,7 @@ Pass `--kind <name>` to scaffold a different primary stance at first paint:
49
51
  - `--kind document` (default) — prose container; lens placeholder *"Write, or describe what you want."*
50
52
  - `--kind workflow` — three-stage scaffold (Inbox / In progress / Done); lens placeholder *"Add an item, or describe a stage move."*
51
53
  - `--kind presentation` — prose slide deck (split on `h1`/`h2`); the *Present* toggle renders it as slides at view time without changing the stored text (spec §5.10); lens placeholder *"Add a slide, or describe a change."*
54
+ - `--kind workspace` — directory control center scaffold. Prefer `rwa workspace create <dir>` for real workspaces so the generated manifest is filled from the sibling rewritables on disk.
52
55
  - `--kind skill-host` — hosts permission-gated skills installed from `.rwa-skill.json` files; ships an empty runtime-owned frozen `#rwa-skills` zone the runtime (never the agent) rewrites on install/uninstall; installed skills are reported via `rwa doc`/`ls` as `tool`/`compute` affordances (`provenance:'installed'`). See `docs/specs/re-write-able-actions-spec-v0.8.md` §2.
53
56
 
54
57
  The product-kind taxonomy is documented at `docs/specs/rwa-product-types.md` in the main repo. The substrate runtime is unchanged across kinds — only the `INLINE_DOC` body and lens placeholder vary at emit time.
@@ -180,6 +183,23 @@ rwa ls a.html b.html # …an explicit list
180
183
 
181
184
  `--json` emits an array of rows for an agent — `{file, status, self}` where `status` is `rewritable` (with the full `self-description/1` object), `not_a_rewritable`, or `error` (with a `reason`). The scan is lenient like its namesake: one bad path among many is a row, not a fatal exit, so a completed scan exits `0`. This is how an agent handed a project learns its whole rewritable inventory — and every container's affordances — in a single call.
182
185
 
186
+ ### `rwa workspace create <dir>` / `rwa workspace sync [dir]`
187
+
188
+ Create or refresh a folder-level control center at `<dir>/rwa-index.html`. The index is itself a rewritable of kind `workspace`: it contains editable shared context for the directory (workspace memory, guidelines, examples, open questions), opens as a dashboard of sibling rewritable documents, and carries a frozen `<script id="rwa-workspace" type="application/rwa-workspace+json">` manifest generated from the directory inventory.
189
+
190
+ ```sh
191
+ rwa workspace create notes/
192
+ rwa new notes/project-brief.html
193
+ rwa new notes/research-log.html
194
+ rwa workspace sync notes/
195
+ ```
196
+
197
+ `create` makes the directory if needed and refuses to overwrite an existing `rwa-index.html` unless `--force` is passed. `sync` refreshes an existing index, or creates it if absent, using the current sibling `.html` rewritables in that directory. The scan is non-recursive and skips non-rewritable HTML files plus the index itself. The editable context block is preserved across sync, so notes like blog style guidelines and canonical examples survive inventory refreshes.
198
+
199
+ This first pass is intentionally simple: it does not merge documents, schedule automations, or expand the skill-host runtime. It gives a directory a portable, editable shared brain plus a truthful machine-readable manifest that other rewritables can use as context.
200
+
201
+ When the workspace index is open, it also listens on the runtime bus for same-directory rewritables that are currently open. Those live documents appear under **Open now** and are marked `new since sync` until the next `rwa workspace sync` writes them into the durable manifest. This is live presence only: unopened files still require `sync` because a browser page cannot enumerate arbitrary local directories by itself.
202
+
183
203
  ### `rwa publish <path>`
184
204
 
185
205
  Publish a local rewritable to the hosted share service and get back a URL. A rewritable is already shareable as a file — it's a self-contained `.html` you can email or host anywhere — but `rwa publish` is the one-command path to an *anonymous, hosted* snapshot: create with `rwa new`, edit locally, publish.
@@ -293,7 +313,7 @@ Because the anchors in step 1 are the *same* text step 3 splices against, what t
293
313
  |---|---|
294
314
  | `--force`, `-f` | overwrite the destination if it exists |
295
315
  | `--open`, `-o` | open the resulting file in the default app |
296
- | `--kind <name>` | (`rwa new` only) starter kind: `document` (default), `workflow`, `presentation`, `skill-host` |
316
+ | `--kind <name>` | (`rwa new` only) starter kind: `document` (default), `workflow`, `presentation`, `workspace`, `skill-host` |
297
317
  | `--version` | print version |
298
318
  | `--help`, `-h` | usage |
299
319
 
package/bin/rwa.mjs CHANGED
@@ -12,7 +12,7 @@ Usage:
12
12
  rwa new <name> [path] a bare <name> resolves template-first: clone a cwd
13
13
  file labeled data-rwa-template="<name>" (fresh UUID,
14
14
  label stripped) if one exists; else, if <name> is a
15
- known kind (document/workflow/presentation/skill-host), create
15
+ known kind (document/workflow/presentation/workspace/skill-host), create
16
16
  that built-in kind. So "rwa new presentation" makes a
17
17
  deck, and your own labeled file overrides the builtin.
18
18
  Default out: ./<name>-YYYY-MM-DD.html.
@@ -52,6 +52,12 @@ Usage:
52
52
  to \`rwa doc\`. Non-rewritables are counted, not
53
53
  hidden. With --json, an array of self-description
54
54
  rows. Lenient: a completed scan exits 0.
55
+ rwa workspace create <dir> create a folder-level rwa-index.html control
56
+ center. The index is a rewritable of kind
57
+ workspace, with a frozen manifest generated from
58
+ sibling rewritables in that directory.
59
+ rwa workspace sync [dir] refresh <dir>/rwa-index.html from the current
60
+ sibling rewritable inventory (default: ./).
55
61
  rwa publish <path> publish a local rewritable to the share service
56
62
  and print the hosted URL. POSTs your edited bytes;
57
63
  the hosted snapshot is anonymous, 24h, with a fresh
@@ -84,11 +90,13 @@ Usage:
84
90
 
85
91
  Flags:
86
92
  --kind <name> (new only) starter kind: document (default), workflow,
87
- presentation, or skill-host. 'document' is the canonical prose
93
+ presentation, workspace, or skill-host. 'document' is the canonical prose
88
94
  container. 'workflow' scaffolds three stages (Inbox / In
89
95
  progress / Done). 'presentation' scaffolds a prose deck that the
90
96
  'Present' toggle displays as slides (split on h1/h2) without
91
- changing the stored text. 'skill-host' hosts permission-gated
97
+ changing the stored text. 'workspace' scaffolds a directory
98
+ control center; prefer \`rwa workspace create\` so the manifest
99
+ is filled from disk. 'skill-host' hosts permission-gated
92
100
  skills installed from .rwa-skill.json files (v0.8 actions spec).
93
101
  See docs/specs/rwa-product-types.md.
94
102
  --skin <name> (new only) bake a style preset into the new container:
@@ -606,6 +614,42 @@ function detectProductKind(fileText) {
606
614
  return;
607
615
  }
608
616
 
617
+ // `rwa workspace create <dir>` / `rwa workspace sync [dir]` — a directory
618
+ // control center. The generated rwa-index.html is itself a rewritable, but
619
+ // its manifest is CLI-owned and refreshed from sibling rewritables.
620
+ if (verb === 'workspace') {
621
+ const sub = rest.find(a => !a.startsWith('-'));
622
+ const force = rest.includes('--force') || rest.includes('-f');
623
+ const open = rest.includes('--open') || rest.includes('-o');
624
+ const positionals = rest.filter((a) => !a.startsWith('-'));
625
+ const dirPath = positionals[1] || '.';
626
+ const emitWorkspace = (msg) => { process.stderr.write('rwa workspace: ' + msg + '\n'); };
627
+
628
+ if (!sub || !['create', 'sync'].includes(sub)) {
629
+ emitWorkspace('usage: rwa workspace create <dir> [--force] [--open] | rwa workspace sync [dir] [--open]');
630
+ process.exitCode = 1;
631
+ return;
632
+ }
633
+ if (sub === 'create' && !positionals[1]) {
634
+ emitWorkspace('missing <dir> argument');
635
+ process.exitCode = 1;
636
+ return;
637
+ }
638
+
639
+ const { workspaceCreateCmd, workspaceSyncCmd } = await import('../src/workspace.mjs');
640
+ try {
641
+ const result = sub === 'create'
642
+ ? await workspaceCreateCmd({ dirPath, force, seedCandidates: SEED_CANDIDATES })
643
+ : await workspaceSyncCmd({ dirPath, seedCandidates: SEED_CANDIDATES });
644
+ console.log(`wrote ${relative(process.cwd(), result.indexPath) || result.indexPath} (${result.docs.length} document${result.docs.length === 1 ? '' : 's'})`);
645
+ if (open) await openWithPrefill(result.indexPath);
646
+ } catch (e) {
647
+ emitWorkspace((e && e.message) || String(e));
648
+ process.exitCode = (e && e.exitCode) || 1;
649
+ }
650
+ return;
651
+ }
652
+
609
653
  // `rwa publish <file> [--url <base>] [--json]` — publish a local rewritable
610
654
  // to the service's snapshot endpoint and print the share URL. Thin client
611
655
  // for `POST /publish`; see src/publish.mjs. Intentionally online (the
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rewritable",
3
- "version": "0.7.0",
3
+ "version": "0.8.1",
4
4
  "description": "CLI for re-writeable: emit and import single-file rwa documents.",
5
5
  "type": "module",
6
6
  "bin": {