@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 +32 -3
- package/bin/psst-antigravity-native.mjs +23 -0
- package/bin/psst-antigravity.mjs +6 -1
- package/docs/native-acceptance.md +58 -0
- package/docs/native-pilot.md +187 -0
- package/docs/pairing.md +48 -0
- package/docs/release.md +13 -10
- package/docs/setup.md +124 -0
- package/hooks.json +1 -0
- package/mcp_config.json +1 -0
- package/package.json +15 -4
- package/plugin.json +1 -0
- package/scripts/prepare-native-plugin.mjs +49 -0
- package/skills/psst/SKILL.md +20 -0
- package/skills/psst-setup/SKILL.md +22 -0
- package/src/approval-manager.mjs +68 -0
- package/src/approval-waiter.mjs +28 -0
- package/src/connector-config.mjs +10 -3
- package/src/installation.mjs +27 -0
- package/src/mcp-stdio.mjs +5 -4
- package/src/native-binding.mjs +135 -0
- package/src/native-plugin.mjs +177 -0
- package/src/native-process-waiter.mjs +55 -0
- package/src/native-session.mjs +48 -0
- package/src/native-waiter.mjs +71 -0
- package/src/pairing.mjs +20 -0
- package/vendor/psst/README.md +6 -0
- package/vendor/psst/approval-source.json +1 -0
- package/vendor/psst/approval.mjs +181 -0
- package/vendor/psst/enrollment-source.json +7 -0
- package/vendor/psst/enrollment.mjs +137 -0
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
|
-
**
|
|
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.
|
|
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.
|
|
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);}
|
package/bin/psst-antigravity.mjs
CHANGED
|
@@ -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
|
-
|
|
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.
|
package/docs/pairing.md
ADDED
|
@@ -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 (
|
|
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.
|
|
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
|
-
##
|
|
27
|
+
## Minor release 0.2.0
|
|
28
28
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
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
|
-
|
|
36
|
-
|
|
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}]}]}}
|
package/mcp_config.json
ADDED
|
@@ -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.
|
|
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": "
|
|
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/
|
|
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."}
|