@actions-json/bridge 0.1.120 → 0.1.122

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,34 +1,37 @@
1
1
  # @actions-json/bridge
2
2
 
3
3
  Run the [actions.json](https://yaniv256.github.io/actions.json/) MCP bridge with
4
- `npx` — no Rust toolchain required. On first run this downloads the prebuilt
5
- `actions-json-mcp` binary for your platform from the GitHub release, caches it,
6
- and runs it. The primitive dictionary (browser-control tool catalog) is bundled,
7
- so you don't pass `--actions`.
4
+ `npx` — no Rust toolchain, no setup. On first run it downloads the prebuilt
5
+ `actions-json-mcp` binary for your platform, bundles the primitive dictionary
6
+ (so you don't pass `--actions`), and scaffolds a storage workspace at
7
+ `~/.actions-json/storage` (so you don't pass `--storage-root`).
8
8
 
9
9
  ## Usage
10
10
 
11
11
  ```bash
12
- npx @actions-json/bridge mcp --storage-root /path/to/.storage
12
+ npx @actions-json/bridge mcp
13
13
  ```
14
14
 
15
- Register it with a coding agent — for Claude Code:
15
+ Register it with a coding agent — Claude Code:
16
16
 
17
17
  ```bash
18
- claude mcp add actions-json -- \
19
- npx -y @actions-json/bridge mcp --storage-root /path/to/.storage
18
+ claude mcp add actions-json -- npx -y @actions-json/bridge mcp
20
19
  ```
21
20
 
22
- For Codex:
21
+ Codex:
23
22
 
24
23
  ```bash
25
- codex mcp add actions-json -- \
26
- npx -y @actions-json/bridge mcp --storage-root /path/to/.storage
24
+ codex mcp add actions-json -- npx -y @actions-json/bridge mcp
27
25
  ```
28
26
 
29
- All arguments after the binary pass straight through to `actions-json-mcp`. To
30
- use a custom primitive dictionary, pass your own `--actions <file>` and the
31
- bundled default is skipped. See
27
+ Overrides (the defaults are skipped when you pass your own):
28
+
29
+ - `--storage-root <dir>` — use a different storage workspace. Or set
30
+ `ACTIONS_JSON_STORAGE`.
31
+ - `--actions <file>` — use a custom primitive dictionary instead of the bundled
32
+ one.
33
+
34
+ All arguments after the binary pass straight through to `actions-json-mcp`. See
32
35
  [Getting Started](https://yaniv256.github.io/actions.json/getting-started.html).
33
36
 
34
37
  ## Platforms
package/bin/cli.js CHANGED
@@ -9,6 +9,7 @@
9
9
  const path = require('node:path');
10
10
  const { spawn } = require('node:child_process');
11
11
  const { ensureBinary } = require('../lib/install');
12
+ const { ensureStorageRoot } = require('../lib/storage');
12
13
 
13
14
  // The primitive dictionary (browser-control tool catalog) ships with this
14
15
  // package — it's a fixed runtime file, not user config. When the caller runs a
@@ -17,13 +18,25 @@ const { ensureBinary } = require('../lib/install');
17
18
  const BUNDLED_ACTIONS = path.join(__dirname, '..', 'dictionary', 'overlay.actions.json');
18
19
  const SUBCOMMANDS_NEEDING_ACTIONS = new Set(['mcp', 'serve']);
19
20
 
20
- function withDefaultActions(args) {
21
- const sub = args[0];
22
- if (!SUBCOMMANDS_NEEDING_ACTIONS.has(sub)) return args;
23
- if (args.includes('--actions')) return args;
24
- if (args.includes('--help') || args.includes('-h')) return args;
25
- // Insert right after the subcommand.
26
- return [args[0], '--actions', BUNDLED_ACTIONS, ...args.slice(1)];
21
+ function isRunSubcommand(args) {
22
+ return SUBCOMMANDS_NEEDING_ACTIONS.has(args[0]) &&
23
+ !args.includes('--help') && !args.includes('-h');
24
+ }
25
+
26
+ // Inject defaults the user shouldn't have to specify: the bundled primitive
27
+ // dictionary (--actions) and a default storage root (--storage-root). Both
28
+ // are skipped if the user passed their own.
29
+ function withDefaults(args) {
30
+ if (!isRunSubcommand(args)) return args;
31
+ const out = [args[0]];
32
+ if (!args.includes('--actions')) {
33
+ out.push('--actions', BUNDLED_ACTIONS);
34
+ }
35
+ if (!args.includes('--storage-root')) {
36
+ out.push('--storage-root', ensureStorageRoot());
37
+ }
38
+ out.push(...args.slice(1));
39
+ return out;
27
40
  }
28
41
 
29
42
  async function main() {
@@ -36,7 +49,7 @@ async function main() {
36
49
  return;
37
50
  }
38
51
 
39
- const args = withDefaultActions(process.argv.slice(2));
52
+ const args = withDefaults(process.argv.slice(2));
40
53
  const child = spawn(bin, args, { stdio: 'inherit' });
41
54
 
42
55
  // Forward termination signals so the bridge shuts down cleanly.
package/lib/storage.js ADDED
@@ -0,0 +1,55 @@
1
+ 'use strict';
2
+
3
+ const fs = require('node:fs');
4
+ const os = require('node:os');
5
+ const path = require('node:path');
6
+
7
+ // Default storage location when the caller doesn't pass --storage-root.
8
+ // Lives in the user's home dir (not cwd) so it resolves no matter where the
9
+ // coding agent launches the bridge.
10
+ function defaultStorageRoot() {
11
+ return (
12
+ process.env.ACTIONS_JSON_STORAGE ||
13
+ path.join(os.homedir(), '.actions-json', 'storage')
14
+ );
15
+ }
16
+
17
+ const TEMPLATE_DIR = path.join(__dirname, '..', 'template');
18
+
19
+ // Recursively copy the template, skipping the .gitkeep placeholders (they only
20
+ // exist to ship empty dirs inside the package/repo).
21
+ function copyTemplate(src, dst) {
22
+ fs.mkdirSync(dst, { recursive: true });
23
+ for (const entry of fs.readdirSync(src, { withFileTypes: true })) {
24
+ if (entry.name === '.gitkeep') continue;
25
+ const s = path.join(src, entry.name);
26
+ const d = path.join(dst, entry.name);
27
+ if (entry.isDirectory()) {
28
+ copyTemplate(s, d);
29
+ } else {
30
+ fs.copyFileSync(s, d);
31
+ }
32
+ }
33
+ }
34
+
35
+ // Ensure the storage root exists; create it from the bundled template on
36
+ // first run. Returns the absolute path. Never overwrites existing storage.
37
+ function ensureStorageRoot(root) {
38
+ const target = root || defaultStorageRoot();
39
+ if (!fs.existsSync(target)) {
40
+ fs.mkdirSync(path.dirname(target), { recursive: true });
41
+ copyTemplate(TEMPLATE_DIR, target);
42
+ // Recreate the empty scope dirs that .gitkeep stood in for.
43
+ for (const p of [
44
+ ['scopes', 'private', 'sites'],
45
+ ['scopes', 'public', 'sites'],
46
+ ['scopes', 'shared'],
47
+ ]) {
48
+ fs.mkdirSync(path.join(target, ...p), { recursive: true });
49
+ }
50
+ process.stderr.write(`Created actions.json storage at ${target}\n`);
51
+ }
52
+ return path.resolve(target);
53
+ }
54
+
55
+ module.exports = { ensureStorageRoot, defaultStorageRoot };
package/package.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "@actions-json/bridge",
3
- "version": "0.1.120",
3
+ "version": "0.1.122",
4
4
  "bridgeBinaryVersion": "0.1.119",
5
- "description": "Run the actions.json MCP bridge with npx — no Rust toolchain required. Downloads the prebuilt actions-json-mcp binary for your platform, bundles the primitive dictionary, and runs it.",
5
+ "description": "Run the actions.json MCP bridge with npx — no Rust toolchain required. Downloads the prebuilt actions-json-mcp binary, bundles the primitive dictionary, and creates your storage workspace on first run.",
6
6
  "license": "MIT",
7
7
  "repository": {
8
8
  "type": "git",
@@ -17,6 +17,7 @@
17
17
  "bin/",
18
18
  "lib/",
19
19
  "dictionary/",
20
+ "template/",
20
21
  "README.md"
21
22
  ],
22
23
  "engines": {
@@ -0,0 +1,74 @@
1
+ # actions.json storage
2
+
3
+ This **is** your `actions.json.storage` workspace — operational, not an example.
4
+ The bridge created it on first run (default: `~/.actions-json/storage`) and reads
5
+ and writes here as your agent browses. Your browsing memory, observations, and
6
+ action maps live in these folders.
7
+
8
+ ## Scopes
9
+
10
+ Storage is organized by visibility. Each scope is a folder under `scopes/`; the
11
+ runtime discovers site maps under `scopes/<scope>/sites/<host>/`.
12
+
13
+ | Scope | What goes here | Git |
14
+ |---|---|---|
15
+ | `private/` | Your owner-only browsing memory, observations, run logs, and unreviewed maps. | Local by default. Opt in: back it with your own **private** repo to sync across your machines and agents. |
16
+ | `public/` | Reviewed, redacted maps **you publish** openly. | Opt in: point it at your own public repo. |
17
+ | `shared/<name>/` | Maps shared with a specific collaborator, **and** maps you pull **from** a source. | Opt in: one git remote per source. |
18
+
19
+ `private` and `public` are set up. Add `shared/<name>/` when you need it.
20
+
21
+ ## Versioning a scope
22
+
23
+ Each scope is an ordinary folder, local until you choose to version it. Turn one
24
+ into a git repo when you want to sync or share it.
25
+
26
+ **Sync your private memory across machines** — back `scopes/private/` with your
27
+ own **private** repo so the same browsing memory follows your agent everywhere:
28
+
29
+ ```bash
30
+ cd ~/.actions-json/storage/scopes/private
31
+ git init && git add . && git commit -m "my private actions.json memory"
32
+ git remote add origin https://github.com/<you>/<your-private-storage>.git # private!
33
+ git push -u origin main
34
+ # on another machine: clone it into scopes/private instead of git init
35
+ ```
36
+
37
+ This stays private — it is your repo, set to private. It only ever leaves your
38
+ machine if you point it at a remote, and `public`/`shared` promotion still
39
+ requires explicit review.
40
+
41
+ **Publish your public maps** — make `scopes/public/` your own public repo:
42
+
43
+ ```bash
44
+ cd ~/.actions-json/storage/scopes/public
45
+ git init && git add . && git commit -m "my public actions.json maps"
46
+ git remote add origin https://github.com/<you>/<your-public-storage>.git
47
+ git push -u origin main
48
+ ```
49
+
50
+ **Pull the official map library** — vendor maps *from* a source into a shared
51
+ scope (the runtime discovers maps under `scopes/shared/<name>/`):
52
+
53
+ ```bash
54
+ cd ~/.actions-json/storage/scopes/shared
55
+ git clone https://github.com/yaniv256/actions.json.storage.public.git actions-json
56
+ # maps now resolve from scopes/shared/actions-json/sites/<host>/
57
+ ```
58
+
59
+ Pulling from someone else's library uses the **shared** scope (inbound), not
60
+ `public` (which is for what *you* publish). Keep that boundary clear.
61
+
62
+ ## Layout
63
+
64
+ ```text
65
+ storage.json Root manifest — which scopes are mounted
66
+ scopes/
67
+ private/
68
+ scope.json Private scope manifest
69
+ sites/<host>/ Per-site maps, observations, overlays (local; sync via a private repo)
70
+ public/
71
+ scope.json Public scope manifest
72
+ sites/<host>/ Reviewed, redacted maps you publish
73
+ shared/<name>/ Add per-collaborator or per-source as needed
74
+ ```
@@ -0,0 +1,17 @@
1
+ {
2
+ "protocol": "actions.json.storage.scope",
3
+ "version": "0.1.0",
4
+ "scope": "private",
5
+ "parent": "actions.json.storage",
6
+ "owner": {
7
+ "type": "person",
8
+ "id": "you"
9
+ },
10
+ "visibility": "private",
11
+ "default_policy": {
12
+ "observations": "store_freely",
13
+ "runs": "store_freely",
14
+ "overlays": "store_freely",
15
+ "action_maps": "draft_until_reviewed"
16
+ }
17
+ }
File without changes
@@ -0,0 +1,17 @@
1
+ {
2
+ "protocol": "actions.json.storage.scope",
3
+ "version": "0.1.0",
4
+ "scope": "public",
5
+ "parent": "actions.json.storage",
6
+ "owner": {
7
+ "type": "person",
8
+ "id": "you"
9
+ },
10
+ "visibility": "public",
11
+ "default_policy": {
12
+ "observations": "do_not_store_raw_private_observations",
13
+ "reports": "reviewed_public_artifact",
14
+ "action_maps": "reviewed_and_redacted",
15
+ "promotion": "review_required"
16
+ }
17
+ }
File without changes
File without changes
@@ -0,0 +1,33 @@
1
+ {
2
+ "protocol": "actions.json.storage",
3
+ "version": "0.1.0",
4
+ "owner": {
5
+ "type": "person",
6
+ "id": "you"
7
+ },
8
+ "visibility": "root-private",
9
+ "default_mount": "private",
10
+ "mounts": {
11
+ "private": {
12
+ "path": "scopes/private",
13
+ "mount_type": "local",
14
+ "visibility": "private",
15
+ "default": true,
16
+ "description": "Your owner-only browsing memory, observations, overlays, run logs, item indexes, and unreviewed action maps. Local by default; point it at your own private repo to sync the same memory across your machines and agents."
17
+ },
18
+ "public": {
19
+ "path": "scopes/public",
20
+ "mount_type": "local",
21
+ "visibility": "public",
22
+ "description": "Reviewed, redacted maps you publish openly. Point this at your own public repo when you want to share."
23
+ }
24
+ },
25
+ "default_policy": {
26
+ "observations": "write_to_private_scope",
27
+ "item_indexes": "write_to_private_scope",
28
+ "runs": "write_to_private_scope",
29
+ "overlays": "write_to_private_scope",
30
+ "action_maps": "reviewed_change_in_scope",
31
+ "promotion": "review_required"
32
+ }
33
+ }