@matuto-ai/antigravity-broker-connector 0.1.1 → 0.3.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
@@ -1,3 +1,23 @@
1
+ # Psst for Antigravity
2
+
3
+ ## Native setup (0.3.1 source candidate)
4
+
5
+ Install the packaged native plugin once through Antigravity's normal `/plugin`
6
+ manager, then invoke `psst-setup` and provide **only the broker HTTPS URL**.
7
+ Approve the displayed request in the broker admin UI. Later native sessions load
8
+ the privately saved installation automatically; no token/file handoff or repeated
9
+ per-session enrollment is required. [Setup and exact persistence paths](docs/setup.md).
10
+
11
+ Normal native permissions still apply. Interactive automatic receive remains an
12
+ **experimental acceptance gate**, not a verified authenticated wakeup guarantee.
13
+ Existing cooperative MCP installations and legacy private bundles remain supported;
14
+ do not run both integrations simultaneously or erase their unread journals.
15
+
16
+ The sections below document the existing cooperative/legacy entrypoint. For the
17
+ new URL-only native path, use the setup guide above instead of pairing scripts.
18
+
19
+ ---
20
+
1
21
  # Antigravity broker connector for Psst
2
22
 
3
23
  A self-contained **stdio MCP server** for exchanging messages with other AI
@@ -7,17 +27,26 @@ use the seven broker tools from your normal Antigravity session. It does not
7
27
  launch a replacement CLI, need a checkout of the broker, or spend model tokens
8
28
  on transport heartbeats.
9
29
 
10
- **Current delivery mode: cooperative pull.** The agent calls `broker_receive`,
30
+ **Default delivery mode: cooperative pull.** The agent calls `broker_receive`,
11
31
  reads the returned untrusted-agent message, then calls `broker_acknowledge` with
12
32
  its exact `message_id` and `receipt_token`. Nothing injects keystrokes, interrupts
13
33
  a task, auto-approves permissions, or wakes an idle model. A receipt means an
14
34
  explicit application-level read acknowledgment, **not completion of the requested
15
35
  work**.
16
36
 
37
+ The [native integration](docs/setup.md) now supports URL-only setup and saved
38
+ installation reconnection; [native acceptance evidence](docs/native-acceptance.md)
39
+ separates tested transport/persistence from the outstanding authenticated wake gate.
40
+ It never enables itself or changes native permission policy.
41
+
17
42
  ## Install and configure
18
43
 
44
+ For brokers supporting the pairing API, [explicit installation pairing](docs/pairing.md)
45
+ can create a private bundle from a pairing-file path without initial environment
46
+ variables. Pairing alone does not attach a native conversation or enable push.
47
+
19
48
  Requires Linux and Node **24.19+ within major 24**. No dependencies or install
20
- scripts. After this naming PR merges, Git install from `main` works before an npm release is available:
49
+ scripts. For reviewed source commits already on `main`, Git installation is available:
21
50
 
22
51
  ```sh
23
52
  npm install --global 'github:matuto-ai/antigravity-broker-connector#main'
@@ -28,7 +57,7 @@ For reproducibility, replace the branch with the reviewed commit SHA. The npm
28
57
  package is prepared as `@matuto-ai/antigravity-broker-connector`; **a prepared release
29
58
  workflow is not evidence that it has been published**. After the maintainer
30
59
  publishes it, install the exact scoped version with
31
- `npm install --global @matuto-ai/antigravity-broker-connector@0.1.1`.
60
+ `npm install --global @matuto-ai/antigravity-broker-connector@0.3.1`.
32
61
  The executable remains `psst-antigravity`.
33
62
 
34
63
  Use a private enrollment bundle produced by the broker administrator. Keep
@@ -0,0 +1,23 @@
1
+ #!/usr/bin/env node
2
+ // Explicit experimental entrypoint. Never selected by the released MCP command.
3
+ import { serveNativePlugin, handleNativeHook } from '../src/native-plugin.mjs';
4
+ import { waitApproval } from '../src/approval-waiter.mjs';
5
+ import { waitNativeProcess } from '../src/native-process-waiter.mjs';
6
+ const controller=new AbortController();
7
+ const stop=()=>controller.abort();process.on('SIGINT',stop);process.on('SIGTERM',stop);
8
+ try {
9
+ const [mode,...args]=process.argv.slice(2);
10
+ if(mode==='serve'&&args.length===1&&args[0]==='--experimental-native') {
11
+ const server=await serveNativePlugin({signal:controller.signal});await server.done;
12
+ } else if(mode==='hook'&&(args.length===0||(args.length===1&&args[0]==='observe'))) {
13
+ let text='';for await(const c of process.stdin){text+=c;if(Buffer.byteLength(text)>128*1024)throw Error();}
14
+ let output;
15
+ try{output=handleNativeHook(JSON.parse(text),{observe:args[0]==='observe'});}
16
+ catch{output={decision:'deny',reason:'Psst native binding is unavailable. No automatic approval or unbound broker call is permitted.'};}
17
+ process.stdout.write(JSON.stringify(output)+'\n');
18
+ } else if(mode==='wait-approval'&&args.length===2){process.stdout.write(await waitApproval({directory:args[0],permit:args[1],signal:controller.signal})+'\n');
19
+ } else if(mode==='wait'&&args.length===2) {
20
+ process.stdout.write(await waitNativeProcess({directory:args[0],permit:args[1],signal:controller.signal})+'\n');
21
+ } else throw Error();
22
+ } catch {process.stderr.write('psst: experimental_native_unavailable; do not automatically retry a failed waiter or uncertain broker operation.\n');process.exitCode=1;}
23
+ finally{process.removeListener('SIGINT',stop);process.removeListener('SIGTERM',stop);}
@@ -1,8 +1,13 @@
1
1
  #!/usr/bin/env node
2
2
  import { readConnectorConfig } from '../src/connector-config.mjs';
3
3
  import { startConnector } from '../src/connector.mjs';
4
- const usage = 'Usage: psst-antigravity --config /absolute/private/config.json\nRuns a cooperative stdio MCP server; does not launch or inject into Antigravity.\n';
4
+ import { pairingOptions, pairConnector } from '../src/pairing.mjs';
5
+ const usage = 'Usage: psst-antigravity --config /absolute/private/config.json\n psst-antigravity pair --pairing-file /absolute/private/pairing.json [--directory /absolute/private/installation]\nRuns a cooperative stdio MCP server; does not launch or inject into Antigravity.\nPair explicitly enrolls this installation; it does not connect or wake a native conversation.\n';
5
6
  if (process.argv.length === 3 && ['--help','-h'].includes(process.argv[2])) { process.stdout.write(usage); }
7
+ else if (process.argv[2] === 'pair') {
8
+ try { process.stdout.write(JSON.stringify(await pairConnector(pairingOptions(process.argv.slice(2)))) + '\n'); }
9
+ catch { process.stderr.write('psst: pairing_failed; keep the same private pairing file and installation directory for a safe retry. No native session was connected.\n'); process.exitCode = 1; }
10
+ }
6
11
  else {
7
12
  let connector;
8
13
  const controller = new AbortController();
@@ -0,0 +1,58 @@
1
+ # Native automatic-arrival evidence — 2026-10-26
2
+
3
+ ## Supported mechanism
4
+
5
+ The official [hook/tool contract](https://www.antigravity.google/docs/hooks)
6
+ exposes `run_command` background tasks and native conversation IDs. Hooks occur
7
+ at existing execution boundaries; they are not themselves an idle wake API.
8
+ The [schedule documentation](https://www.antigravity.google/docs/commands/schedule)
9
+ explicitly explains that a matching background-task completion message wakes
10
+ its conversation. Psst uses that event-driven completion route, NOT recurring
11
+ model calls or schedule polling. One permitted native waiter waits for local
12
+ inbox state and exits with a fixed notice; the native host owns notification
13
+ insertion and subsequent model invocation. The agent then receives and explicitly
14
+ acknowledges the FIFO message. A completion notice alone is neither model-read
15
+ nor task success.
16
+
17
+ ## Reproduced here
18
+
19
+ `bash scripts/validate-official-native.sh` downloads the pinned official Google
20
+ 1.4.7 binary, checks SHA512, uses an isolated HOME, validates the complete plugin
21
+ with `--strict`, installs it and lists it. Current result: one MCP server, one
22
+ hook group, two skills, zero findings. The actual validator identified that
23
+ hooks do not receive PLUGIN_ROOT; packaged hooks now use its documented plugin
24
+ working directory. No permission override is installed.
25
+
26
+ The native waiter tests prove one owner, one-use permits, request/conversation
27
+ fencing, bounded per-head notices and unchanged pending journals. Real HTTPS
28
+ approval tests exercise the actual broker/admin UI and frozen helper. They use
29
+ synthetic native identities and do NOT establish authenticated vendor wakeup.
30
+
31
+ A fresh actual interactive CLI launch stopped at its Google OAuth / Google Cloud
32
+ project sign-in chooser. No sign-in choice, account, Terms acceptance or model
33
+ call was made. Earlier headless MCP permission denial remains a failure gate,
34
+ not an invitation to use skip-permission flags. Current environment also denies
35
+ Unix socket binding; those three existing tests remain enabled for Linux CI.
36
+
37
+ ## Reproducible authenticated acceptance (still required)
38
+
39
+ In an already authenticated, authorized native CLI, install this reviewed plugin
40
+ and complete URL setup/admin approval once. Allow only the plugin's exact MCP
41
+ and waiter operations if the native host asks. End the turn with its native
42
+ waiter armed. From a second session send two distinct benign messages, serially.
43
+ Without typing another prompt, verify each genuine native completion event,
44
+ `broker_receive`, correct message content and explicit `broker_acknowledge`, then
45
+ re-arming. Repeat while busy, reject a permission prompt, disconnect, close the
46
+ native host and restart with the installation directory retained. Verify no
47
+ human-permission inference from message text and no duplicate model processing.
48
+ Stop on a native denial; do not alter authorization to force this test through.
49
+
50
+ The first-conversation-per-CLI-host fence is deliberate: concurrent independent
51
+ hosts work; switching conversations inside one host is not certified. A documented
52
+ conversation-only close event has not been established, so host exit/disconnect
53
+ is the verified cleanup boundary. Do not advertise all native acceptance gates
54
+ as complete until those observations are recorded.
55
+
56
+ The native task arguments are taken from the installed host's schema. The plugin
57
+ asks only for `CommandLine` and `WaitMsBeforeAsync=500`; it does not invent an
58
+ `IsDaemon` argument or request persistent/background permission overrides.
@@ -0,0 +1,187 @@
1
+ > Historical0.2.0 pilot evidence and limitations. The0.3.0 source candidate adds
2
+ > packaged URL-only setup, durable installation selection and GET-only pending
3
+ > recovery; see [current setup](setup.md). Historical disconnected-only/fresh-mailbox
4
+ > statements below describe0.2.0, not the new persistence implementation. Actual
5
+ > authenticated native wakeup and conversation-only cleanup remain unverified.
6
+
7
+ # Native CLI delivery pilot (not enabled)
8
+
9
+ The default connector remains cooperative MCP. This pilot is **not certified
10
+ production automatic delivery**, and is not installed or activated by package startup.
11
+
12
+ ## Verified capability and remaining gate (2026-10-25)
13
+
14
+ The official Antigravity CLI 1.4.7 binary was downloaded from the distribution
15
+ manifest referenced by Google's installer and checked against its SHA-512.
16
+ `--version`, `--help`, and offline plugin validation are available. An isolated
17
+ local fake Gemini provider completed a real headless CLI turn with no account
18
+ credential or paid model request. This proves neither subscription authentication
19
+ nor automatic delivery into an existing interactive conversation.
20
+
21
+ The runtime's actual `run_command` tool schema says a command continuing in the
22
+ background produces a completion notification. It accepts `CommandLine`,
23
+ `WaitMsBeforeAsync` (500–10000), `toolSummary`, and optional `IsDaemon`. These
24
+ fields differ from some website examples; use the installed runtime schema.
25
+ An interactive test stopped at fresh-profile Terms of Service / Data Use
26
+ onboarding, without accepting it. Existing-user TUI wakeup remains untested.
27
+
28
+ An independent headless fixture observed the real native process contract:
29
+ plugin MCP runs directly under the CLI with `PLUGIN_ROOT` but no conversation
30
+ environment variable; hooks run through `sh`, with
31
+ `ANTIGRAVITY_CONVERSATION_ID` matching their stdin `conversationId`. The tested
32
+ `nativeHookContext` implementation verified the same host PID/start time/boot ID
33
+ and executable for real SessionStart and PreInvocation hooks. Lazy MCP calls use
34
+ `call_mcp_tool` with `ServerName`, `ToolName` and `Arguments`; plugin server names
35
+ were prefixed with the plugin name. PreToolUse observed this wrapper correctly.
36
+
37
+ The attempted MCP call was denied by native headless permission policy, which
38
+ cannot prompt. No allow rules, auto-approval or permission-skip flags were added;
39
+ the MCP tool did not execute. Therefore actual `overwrite` propagation to MCP
40
+ and interactive idle wake remain acceptance gates, not verified successes.
41
+
42
+ Official references:
43
+ - [Native plugins](https://www.antigravity.google/docs/plugins): CLI plugin
44
+ installation while running; packaged skills, hooks, and MCP configuration.
45
+ - [Hooks](https://www.antigravity.google/docs/hooks): native `conversationId`,
46
+ `PreToolUse.overwrite`, and `PreInvocation` context steps.
47
+ - [Scheduling](https://www.antigravity.google/docs/commands/schedule): a matching
48
+ background task completion is a wakeup; no periodic scheduler is proposed here.
49
+ - [Sidecars](https://www.antigravity.google/docs/sidecars): documented
50
+ `agentapi send-message` support is App-only, not a CLI capability claim.
51
+ - [CLI installation](https://www.antigravity.google/docs/getting-started).
52
+
53
+ ## Intended flow, requiring native proof
54
+
55
+ 1. Install the native plugin in the running CLI. Startup stays disconnected;
56
+ neither environment variables nor credentials are required to load it.
57
+ 2. An explicit connect skill accepts only a private pairing-file **path**, never
58
+ a secret in conversation text. The shared enrollment helper creates one
59
+ installation credential; each native conversation receives a fresh address.
60
+ 3. Native hooks bind broker calls to their actual conversation, not to a
61
+ model-supplied ID. A one-use opaque routing ticket must bind conversation,
62
+ incarnation, tool arguments and expiry. Hook `overwrite` may attach this
63
+ ticket; `allow` must still delegate to normal permission policy. MCP hook
64
+ matching and argument overwrite need runtime proof before this is enabled.
65
+ 4. After connect, the model arms one native background waiter. Transport receives
66
+ without model-token polling. A durable pending inbox event completes the task
67
+ with a fixed notice, not message content. Native completion should wake the
68
+ owning conversation; the model receives, explicitly acknowledges reading,
69
+ and re-arms automatically. The human does not call receive.
70
+ 5. Disconnect cancels transport/waiters. Reconnect uses bounded transport backoff;
71
+ lost notices retain pending data. An expired credential requires re-pairing.
72
+
73
+ `src/native-waiter.mjs` is the tested event-driven waiter primitive. The separate
74
+ experimental adapter uses the same durable inbox and explicit receipt boundary.
75
+ It does not change the default MCP-process singleton. A
76
+ successful notice does not advance the FIFO, create a read receipt, or prove
77
+ the requested action succeeded. No terminal input injection, permission override,
78
+ infinite Stop-hook continuation, or model-polling cron is an acceptable substitute.
79
+
80
+ `src/native-binding.mjs` is the second gated primitive: a first-conversation fence
81
+ and small private SQLite invocation-permit store. A verified hook issues an
82
+ opaque, one-use, 30-second permit for exact tool arguments; MCP must consume it
83
+ atomically before acting. At most 32 unexpired permits are retained, containing
84
+ the raw short-lived nonce and argument hashes, not message bodies or broker/pairing
85
+ credentials. Missing hooks, modified arguments,
86
+ wrong session/host, expiration and replay fail closed. Uncertain commit/rollback
87
+ fences that handle; a closed host invalidates permits and cancels its waiter.
88
+ It is not a general multiplexing service and is not loaded by the released CLI.
89
+
90
+ This protects the native integration boundary under the assumption that the
91
+ installed hook code and private connector state are intact. **It is not a
92
+ cryptographic boundary against hostile code with the same OS UID and filesystem
93
+ access.** Native permission policy remains authoritative. `allow` only delegates
94
+ to that policy; it must never be replaced by `auto_approve` or permission overrides.
95
+
96
+ ## Minimum native acceptance test
97
+
98
+ ### Runnable experimental connector
99
+
100
+ The code now includes a separately gated native entrypoint and plugin generator.
101
+ From a checkout, generate it with:
102
+
103
+ ```sh
104
+ node scripts/prepare-native-plugin.mjs /absolute/new/psst-native --experimental-native
105
+ agy plugin validate /absolute/new/psst-native --strict --json
106
+ ```
107
+
108
+ The packaged generator command is `psst-antigravity-native-plugin` with the same
109
+ arguments. Neither command installs the plugin or edits a live CLI profile.
110
+ The generated plugin uses absolute executable paths from this installation;
111
+ keep that installation available inside the same sandbox. Its native MCP server
112
+ starts disconnected without credentials or initial environment variables.
113
+
114
+ After explicitly installing the generated directory in an already-onboarded CLI,
115
+ invoke its `psst-connect` skill with a private pairing-file or connection-file
116
+ path. The hook stamps the real conversation; connect creates a fresh broker
117
+ session, recipient discovery uses `broker_list_clients`, and the skill arms the
118
+ returned waiter command under normal native permissions. The waiter exits only
119
+ on durable pending data, cancellation, owner loss or an attention condition;
120
+ background completion is the proposed native wakeup. The model reads and ACKs,
121
+ then re-arms without a human receive command. Errors/denials stop automatic
122
+ retries. Two notices per head are allowed, followed by one attention notice;
123
+ subsequent waits for the same unacknowledged head stay silent. This budget is
124
+ persisted and never consumes the message.
125
+
126
+ Only the first explicitly connected conversation in a native CLI process is
127
+ supported. A different conversation requires a fresh CLI host. One kernel-held
128
+ MCP-owner lock prevents concurrent owners. MCP EOF invalidates its permits and
129
+ waiter but preserves the verified native host's first-conversation fence. A
130
+ restart under the same host starts disconnected; a new explicit connect creates
131
+ a fresh mailbox, never silently adopts the old one. Owner-incarnation checks
132
+ reject old hooks and permits. Disconnect cancels the waiter and transport, while retaining the
133
+ private installation credential; a new connect creates a fresh session address.
134
+ Re-pairing creates a separate private credential directory. Expiry or terminal
135
+ broker authentication failure stops transport and marks the connection unavailable.
136
+ There is no documented CLI ConversationClosed/SessionEnd hook. `Stop`/`fullyIdle`
137
+ is not treated as session closure because it also describes normal idle work.
138
+ Immediate deregistration when a conversation alone is deleted while its host
139
+ remains alive is therefore not certified; explicit disconnect or closing that
140
+ CLI host is the supported boundary. The live test must inspect task cancellation
141
+ in that case, rather than inferring it from a generic idle observation.
142
+
143
+ Deterministic adapter tests run the actual HTTP broker transport, durable inbox,
144
+ hook-decision/permit boundary, external waiter, FIFO receive/ACK, and disconnect
145
+ races. Official CLI 1.4.7 strict validation recognizes the generated plugin's
146
+ one MCP server, one hook configuration and one skill with no findings. These
147
+ tests still do not prove native permission acceptance, hook-overwrite delivery,
148
+ or interactive idle wakeup. Those remain the explicit user-owned CLI gate.
149
+ The official CLI also loaded this actual generated plugin in a disposable
150
+ headless fake-provider run: native discovery exposed `psst-native_psst` and
151
+ `broker_connect`, hooks initialized, and the server remained disconnected with
152
+ no client/inbox until EOF. No broker tool was requested in that test.
153
+
154
+ ### Disposable wakeup-only fixture
155
+
156
+ The disposable first-stage proof plugin can be generated without installing it:
157
+
158
+ ```sh
159
+ node scripts/prepare-native-proof.mjs /absolute/new/proof-plugin
160
+ agy plugin validate /absolute/new/proof-plugin --strict --json
161
+ ```
162
+
163
+ The official CLI 1.4.7 validator returned no findings for the generated manifest,
164
+ one hook and one skill. In an already-onboarded test CLI, explicitly install that
165
+ directory using `/plugin install /absolute/new/proof-plugin` and invoke its
166
+ `psst-native-proof` skill. It prints the separate synthetic signal command. After
167
+ the agent ends its turn, execute that command from the same sandbox. Success is
168
+ an unsolicited `PSST_NATIVE_WAKE_OBSERVED` response in the owning conversation.
169
+ This first stage has no broker or ACK and is not the full acceptance test below.
170
+ It never changes permission policy, sends terminal input, or invokes a timer.
171
+
172
+ Use an already-onboarded CLI in the intended sandbox, with explicit permission
173
+ for the disposable test commands. No production credentials are necessary for
174
+ the wakeup proof. The pilot adapter must be reviewed before this test:
175
+
176
+ 1. Load a local proof plugin; verify hooks and skills in `/hooks` and `/plugin`.
177
+ 2. Start a finite event waiter using native `run_command` (`WaitMsBeforeAsync:500`,
178
+ `IsDaemon:false`). End the model turn without polling or scheduling.
179
+ 3. From the disposable fixture, commit one synthetic pending inbox item.
180
+ 4. Without another human prompt, verify the same conversation gets a completion
181
+ notice, invokes receive and explicit ACK, then arms another waiter exactly once.
182
+ 5. Repeat while the model is busy; exercise two conversations, disconnect, lost
183
+ notice, and restart. No cross-conversation delivery or implicit read ACK.
184
+
185
+ Record CLI version, native tool/hook observations and the resulting transcript
186
+ events (not hidden reasoning or secrets). Until this passes, automatic CLI
187
+ delivery remains a gated pilot, not a completed production feature.
@@ -0,0 +1,48 @@
1
+ # Explicit installation pairing
2
+
3
+ This additive command prepares a credential bundle. It **does not connect a
4
+ running Antigravity conversation or enable automatic delivery**. Existing
5
+ `--config` and `PSST_CONFIG_FILE` cooperative MCP configuration remain unchanged.
6
+ The broker must support the reviewed `/v1/enrollments` pairing API; a prepared
7
+ broker change is not evidence that the operator deployed it.
8
+
9
+ The operator provides a short-lived, single-use private pairing file. Place it
10
+ inside the intended sandbox with mode `0600` and a private parent directory.
11
+ Never paste its contents into a model prompt, command argument, URL or log.
12
+
13
+ ```sh
14
+ psst-antigravity pair --pairing-file /absolute/private/pairing.json
15
+ ```
16
+
17
+ No initial environment variables are required. The default installation directory
18
+ is `~/.config/psst/antigravity`; optionally use `--directory /absolute/private/dir`.
19
+ All paths must be absolute. The helper validates HTTPS origin, client type and
20
+ private file ownership/modes; it creates private retry state before HTTP.
21
+ It generates this installation's bearer token locally and transmits only its
22
+ SHA-256 verifier. The pairing secret is sent only in the HTTPS Authorization
23
+ header. Existing credentials and legacy bundles are not overwritten.
24
+
25
+ Success prints nonsecret JSON including `connectionFile`, `credentialId`,
26
+ `expiresAt` and `connected:false`. Use the returned `connectionFile` as the
27
+ existing MCP entry's `--config` argument. Keep the installation directory: it
28
+ contains the private token and recovery state. A restarted cooperative connector
29
+ still has a fresh process address; pairing does not change that scope.
30
+
31
+ New bundles are explicitly marked with `enrollment_receipt_file:"enrollment.json"`.
32
+ The connector verifies the private sibling receipt against the bundle's origin,
33
+ client type and token hash; missing, corrupt, mismatched or expired receipts fail
34
+ closed. An older connector may reject this new marker: upgrade the connector
35
+ before pairing. Unmarked legacy administrator-generated bundles remain supported.
36
+
37
+ For an uncertain network/storage result, keep the same pairing file and directory
38
+ for an explicit retry: the persisted enrollment ID and token are reused. A new
39
+ pairing grant is required after credential expiry or revocation. An error is not
40
+ proof that the broker failed to store the enrollment. Never delete retry state to
41
+ make an uncertain result look new.
42
+
43
+ The vendored single-file helper is shared with the Psst broker implementation;
44
+ it is separate from the older pinned reference runtime. Its local integrity and
45
+ compatibility are checked by the pairing tests; it makes no native-delivery claim.
46
+ It is pinned to [Psst commit 3e908e7](https://github.com/matuto-ai/psst/blob/3e908e79966d886a02d372c103e31dec6e900c1a/reference/enrollment.mjs)
47
+ from [upstream pairing PR #18](https://github.com/matuto-ai/psst/pull/18).
48
+ That source reference does not imply the upstream PR is merged or deployed.
package/docs/release.md CHANGED
@@ -11,10 +11,10 @@ it does not assert that npm already hosts the package.
11
11
  `antigravity-broker-connector`, workflow `npm-publish.yml`. This is an account
12
12
  security configuration performed by the maintainer, not by this code change.
13
13
  4. Set package version and create a GitHub release whose tag is exactly
14
- `v<package.json version>` on the reviewed commit (next `v0.1.1`).
14
+ `v<package.json version>` on the reviewed commit (`v0.2.0` for this release).
15
15
  5. The workflow runs syntax checks, all tests, and an isolated tarball install;
16
16
  only then it runs `npm publish --access public --provenance --ignore-scripts`.
17
- 6. Verify the workflow result and `npm view @matuto-ai/antigravity-broker-connector@0.1.1`
17
+ 6. Verify the workflow result and `npm view @matuto-ai/antigravity-broker-connector@0.2.0`
18
18
  before advertising the npm install command.
19
19
 
20
20
  The workflow follows the user's existing release/OIDC pattern, with test and
@@ -24,13 +24,16 @@ back to another identity. Git/packed-tarball installation remains available even
24
24
  before npm setup. Release publication, credential creation, and broker enrollment
25
25
  are distinct from preparing or merging connector code.
26
26
 
27
- ## Patch release
27
+ ## Minor release 0.2.0
28
28
 
29
- This PR prepares `0.1.1`; the intended GitHub release tag is `v0.1.1`.
30
- After review and merge, the maintainer can publish that release from the merged
31
- commit to exercise npm Trusted Publishing. This code change does not itself
32
- create a tag, release, or npm publication. Verify the workflow succeeds and the
33
- scoped npm version exists before recommending it for installation.
29
+ The intended GitHub release tag is `v0.2.0`, matching `package.json`.
30
+ Use the existing release-triggered Trusted Publishing workflow and normal npm
31
+ `latest` tag; no prerelease workflow or account configuration is changed here.
32
+ Review the [changelog](../CHANGELOG.md) before publishing. The native pilot is
33
+ opt-in/default-off, and real idle wakeup, native hook overwrite propagation, and
34
+ conversation-only close cleanup remain acceptance gates—not production claims.
34
35
 
35
- Existing `0.1.0` npm packages and old GitHub tags remain untouched. Do not reuse
36
- or move an old release tag; the new tag must exactly match the package version.
36
+ Create the new tag only on the reviewed, tested merge commit. Existing versions
37
+ and tags remain untouched. Verify publication, provenance and the scoped npm
38
+ version before recommending installation. A successful merge alone does not
39
+ mean npm publication succeeded.
package/docs/setup.md ADDED
@@ -0,0 +1,124 @@
1
+ # Setup once from Antigravity
2
+
3
+ Install the packaged native plugin once with the ordinary native plugin manager.
4
+ Its directory now includes `plugin.json`, hooks, MCP configuration and skills;
5
+ no generated pairing file or per-window operator script is the primary path.
6
+ Node 24.19+ within major 24 must already be available inside the same sandbox. Do not run
7
+ the old cooperative MCP configuration alongside the native plugin: each would
8
+ otherwise own a separate address. Existing cooperative installations continue to
9
+ work unchanged; switching integrations does not erase their unread journals.
10
+
11
+ One-time package bootstrap, **after this version is released**:
12
+
13
+ ```sh
14
+ npm install --prefix "$HOME/.local/share/psst-antigravity" --ignore-scripts \
15
+ @matuto-ai/antigravity-broker-connector@0.3.1
16
+ ```
17
+
18
+ Then use the native `/plugin install` command with the absolute installed folder
19
+ `$HOME/.local/share/psst-antigravity/node_modules/@matuto-ai/antigravity-broker-connector`
20
+ (expand HOME to its real path). A preinstalled sandbox does this once in bootstrap,
21
+ not for each session. The official native manager copies the package's plugin
22
+ files into its managed plugin directory. No global Node change is required.
23
+
24
+ 1. In Antigravity invoke `psst-setup`; provide only the HTTPS broker URL.
25
+ 2. The administrator approves the displayed request ID in the broker's login-form
26
+ UI. There is no token/password to paste into the conversation.
27
+ 3. The plugin saves approved installation selection privately. Later native
28
+ sessions load it automatically, each with a separate conversation mailbox.
29
+
30
+ Normal startup never creates an enrollment request or rotates a key. A durable
31
+ previously requested pending enrollment may be resumed using GET-only polling;
32
+ closing before approval and reopening afterwards does not require another setup.
33
+ Unknown/network outcomes retain the same local request/token. Denial, expiry,
34
+ revocation or corrupt state needs explicit attention, never automatic replacement.
35
+ Explicit setup again requests replacement while keeping the old working selection
36
+ until the candidate attaches and the selection compare-and-swap commits.
37
+
38
+ ## Persistence/bootstrap contract
39
+
40
+ Default installation root:
41
+ `~/.gemini/antigravity-cli/psst/installation`
42
+
43
+ Override: `PSST_ANTIGRAVITY_INSTALLATION_DIR=/absolute/private/persistent/path`.
44
+ Bootstrap may share/mount this directory at the SAME absolute path across local
45
+ containers of the same trusted OS user. Do not share across untrusted users or
46
+ use NFS; private SQLite kernel ownership and atomic local renames are required.
47
+ The directory is 0700, private JSON/token files 0600. `selected.json` contains only
48
+ the approved bundle path, credential ID, request ID and revision; `pending.json`
49
+ contains nonsecret broker/request intent and cancellation state. The vendored
50
+ helper stores candidate secrets and approved bundles in `approvals/` beneath it.
51
+ Never print/copy those credentials into chat or logs.
52
+
53
+ Native journals are beneath the approved bundle's `state/native-<hash>` directory,
54
+ partitioned by broker, verified credential and native conversation ID. Preserving
55
+ the installation root therefore preserves authorization AND independent pending
56
+ mailboxes. A new native conversation gets a new address; reopening the exact
57
+ native conversation can resume its address/journal, with a single kernel owner.
58
+ A different approved credential never silently adopts its predecessor's inbox.
59
+ Do not delete old directories on replacement or upgrade.
60
+
61
+ Transient host bindings/waiter ownership remain separate under
62
+ `~/.config/psst/antigravity/native`; do not mount/share this directory between
63
+ containers. The reviewed sandbox archive a7f63e8 (`agents/agy/config.sh`) mounts
64
+ `projects/<project>/agy/<identity>/gemini` at `/home/node/.gemini` and uses an
65
+ `agy-shell-gemini` volume for shell state. The default installation root is
66
+ therefore persistent per project/identity in that archived layout. To share one
67
+ Psst installation across projects, bootstrap can mount only a dedicated private
68
+ `$CONFIG_DIR/psst/antigravity/installation` at `/home/node/.config/psst-installation`
69
+ and set `PSST_ANTIGRAVITY_INSTALLATION_DIR` to that path. Do NOT share entire
70
+ `.gemini` conversation databases or the provider keyring. The archived native
71
+ policy rejects plugin/MCP imports; enabling this plugin needs a separately
72
+ reviewed bootstrap exception, never an adapter bypass. No bootstrap file was
73
+ changed by this connector. Actual user mounts have not been inspected; these paths are the
74
+ connector contract, not a claim about an existing deployment.
75
+
76
+ `broker_disconnect` stops this host's transport and locally cancels pending setup
77
+ resumption; `broker_cancel_setup` leaves existing approved transport intact.
78
+ Neither revokes server authorization. Admin UI revocation is separate. Pending
79
+ messages are retained; broker presence can remain until lease expiry.
80
+
81
+ ## Native capability and acceptance limits
82
+
83
+ The primary setup interface is a native skill asking for a single nonsecret URL
84
+ and an MCP tool whose only setup field is `broker_url`; no private secret form is
85
+ needed. SessionStart/PreInvocation hooks provide verified native context and can
86
+ load approved state. PreToolUse permits remain one-use and exact-conversation,
87
+ and `allow` continues to delegate to ordinary native permissions.
88
+
89
+ Only the first conversation in one CLI host is supported by the conservative
90
+ root/subagent fence. Independent CLI hosts may share installation authorization;
91
+ they do not share conversation identities. Switching to another conversation
92
+ inside the same host is rejected rather than borrowing the first one's mailbox.
93
+ No reliable CLI ConversationClosed/SessionEnd hook was established. Closing a
94
+ host is observed, but deleting only its conversation is still a cleanup gate.
95
+
96
+ The background command waiter uses supported native completion notifications;
97
+ it does not scrape terminals, simulate keys, force permission approval or run a
98
+ model polling loop. The model arms the approval/inbox waiter under normal native
99
+ permissions, then reads and explicitly acknowledges received AGENT data. Writing
100
+ a notice or recording broker delivery does NOT establish model processing or
101
+ successful task execution. Real authenticated interactive idle wakeup remains
102
+ unverified; previous headless permission denial was not bypassed. The native
103
+ route remains experimental, not a certified production automatic-receive claim.
104
+
105
+ Sources: https://www.antigravity.google/docs/plugins and
106
+ https://www.antigravity.google/docs/hooks (checked2026-10-26).
107
+
108
+ ### Targeted bootstrap review checklist (not applied)
109
+
110
+ Keep `agy-policy.py` rejection of arbitrary project/global integrations. The
111
+ narrow addition would allow exactly the reviewed `psst-native` plugin under the
112
+ native manager's installation directory, with a pinned package/digest and its
113
+ known `plugin.json`, `hooks.json`, `mcp_config.json`, two skills and runtime files.
114
+ Validate every plugin path as a regular, non-symlink image-managed file; reject
115
+ additional plugins, servers, hook commands, custom providers and unknown registry
116
+ entries. Permit only the plugin's Node executable/serve command and exact native
117
+ hook entrypoints; do not enable all MCP servers or add permission-skip options.
118
+ The native manager's own registry/import-manifest formats must be inspected and
119
+ allowlisted narrowly as part of that separate bootstrap review. Mount only the
120
+ private installation directory described above; keep native host bindings and
121
+ provider auth separate. Test both the permitted exact plugin and malicious
122
+ extra/symlink/modified-command cases against the real archived policy before a
123
+ user deploys the revised sandbox. This is an integration specification, not a
124
+ claim that the existing archived security policy already permits the connector.
package/hooks.json ADDED
@@ -0,0 +1 @@
1
+ {"psst-native-binding": {"SessionStart": [{"type": "command", "command": "node ./bin/psst-antigravity-native.mjs hook observe", "timeout": 5}], "PreInvocation": [{"type": "command", "command": "node ./bin/psst-antigravity-native.mjs hook observe", "timeout": 5}], "PreToolUse": [{"matcher": "call_mcp_tool|run_command", "hooks": [{"type": "command", "command": "node ./bin/psst-antigravity-native.mjs hook", "timeout": 5}]}]}}
@@ -0,0 +1 @@
1
+ {"mcpServers": {"psst": {"command": "node", "args": ["./bin/psst-antigravity-native.mjs", "serve", "--experimental-native"]}}}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@matuto-ai/antigravity-broker-connector",
3
- "version": "0.1.1",
3
+ "version": "0.3.1",
4
4
  "type": "module",
5
5
  "engines": {
6
6
  "node": ">=24.19.0 <25"
@@ -11,16 +11,27 @@
11
11
  "test:pack": "node scripts/pack-smoke.mjs"
12
12
  },
13
13
  "license": "MIT",
14
- "description": "Cooperative stdio MCP connector between Antigravity and the Psst agent message broker.",
14
+ "description": "Native Antigravity Psst setup and conversation messaging with private administrator-approved installation credentials.",
15
15
  "bin": {
16
- "psst-antigravity": "bin/psst-antigravity.mjs"
16
+ "psst-antigravity": "bin/psst-antigravity.mjs",
17
+ "psst-antigravity-native-plugin": "scripts/prepare-native-plugin.mjs"
17
18
  },
18
19
  "files": [
19
20
  "bin/psst-antigravity.mjs",
21
+ "bin/psst-antigravity-native.mjs",
22
+ "scripts/prepare-native-plugin.mjs",
20
23
  "src/**/*.mjs",
21
24
  "vendor/psst/**",
22
25
  "docs/installation.md",
23
- "docs/release.md"
26
+ "docs/pairing.md",
27
+ "docs/native-pilot.md",
28
+ "docs/release.md",
29
+ "plugin.json",
30
+ "mcp_config.json",
31
+ "hooks.json",
32
+ "skills/**",
33
+ "docs/setup.md",
34
+ "docs/native-acceptance.md"
24
35
  ],
25
36
  "repository": {
26
37
  "type": "git",
package/plugin.json ADDED
@@ -0,0 +1 @@
1
+ {"name":"psst-native","version":"0.3.1","description":"Psst URL-only setup and native conversation messaging; automatic native wakeup remains experimental."}