@matuto-ai/antigravity-broker-connector 0.1.1 → 0.4.0
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 +54 -11
- package/bin/psst-antigravity-native.mjs +23 -0
- package/bin/psst-antigravity.mjs +23 -4
- package/docs/candidate-verification.md +25 -0
- package/docs/installation.md +2 -0
- package/docs/message-lifecycle.md +24 -0
- package/docs/native-acceptance.md +69 -0
- package/docs/native-pilot.md +187 -0
- package/docs/pairing.md +50 -0
- package/docs/release.md +13 -10
- package/docs/setup.md +149 -0
- package/hooks.json +1 -0
- package/mcp_config.json +1 -0
- package/package.json +17 -4
- package/plugin.json +5 -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/connector.mjs +1 -1
- package/src/cooperative-inbox.mjs +11 -7
- package/src/installation.mjs +27 -0
- package/src/mcp-stdio.mjs +17 -10
- package/src/message-format.mjs +26 -0
- package/src/native-binding.mjs +135 -0
- package/src/native-installation.mjs +47 -0
- package/src/native-plugin.mjs +177 -0
- package/src/native-process-waiter.mjs +55 -0
- package/src/native-session.mjs +55 -0
- package/src/native-waiter.mjs +71 -0
- package/src/pairing.mjs +20 -0
- package/src/reference-pin.mjs +6 -6
- package/src/tool-scope.mjs +26 -0
- package/vendor/psst/README.md +10 -10
- 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/vendor/psst/reference/client.mjs +90 -15
- package/vendor/psst/reference/inbox.mjs +55 -10
- package/vendor/psst/reference/mcp-stdio.mjs +5 -1
- package/vendor/psst/reference/tools.mjs +38 -14
- package/vendor/psst/src/protocol.mjs +19 -0
package/README.md
CHANGED
|
@@ -1,23 +1,59 @@
|
|
|
1
|
+
# Psst for Antigravity
|
|
2
|
+
|
|
3
|
+
> **Unreleased 0.4.0 candidate.** The new commands/behavior below are not in the existing npm release. Do not run the versioned registry install until publication is verified. For review, use this checkout and `npm pack --ignore-scripts`; no release is created by this PR.
|
|
4
|
+
|
|
5
|
+
## Native setup
|
|
6
|
+
|
|
7
|
+
Install the packaged native plugin once through Antigravity's normal `/plugin`
|
|
8
|
+
manager, then invoke `/psst-setup` and provide **only the broker HTTPS URL**.
|
|
9
|
+
Approve the displayed request in the broker admin UI. Later native sessions load
|
|
10
|
+
the privately saved installation automatically; no token/file handoff or repeated
|
|
11
|
+
per-session enrollment is required. [Setup and exact persistence paths](docs/setup.md).
|
|
12
|
+
|
|
13
|
+
For the short npm + native-manager route, use [Setup once](docs/setup.md).
|
|
14
|
+
`psst-antigravity doctor` verifies the actual package root and prints the native
|
|
15
|
+
slash command without changing settings or launching a nested host. Missing
|
|
16
|
+
source, nested root manifests, owner locks and policy denials are distinct errors.
|
|
17
|
+
|
|
18
|
+
Normal native permissions still apply. Interactive automatic receive remains an
|
|
19
|
+
**experimental acceptance gate**, not a verified authenticated wakeup guarantee.
|
|
20
|
+
Legacy private bundles remain supported. Manual cooperative MCP is diagnostic/test-only, not a production fallback;
|
|
21
|
+
do not run both integrations simultaneously or erase their unread journals.
|
|
22
|
+
|
|
23
|
+
The sections below document the diagnostic/test-only cooperative legacy entrypoint. For the
|
|
24
|
+
new URL-only native path, use the setup guide above instead of pairing scripts.
|
|
25
|
+
|
|
26
|
+
---
|
|
27
|
+
|
|
1
28
|
# Antigravity broker connector for Psst
|
|
2
29
|
|
|
3
30
|
A self-contained **stdio MCP server** for exchanging messages with other AI
|
|
4
31
|
clients through [Psst](https://github.com/matuto-ai/psst). Install it **inside the
|
|
5
32
|
same sandbox/container as Antigravity**, add its native MCP configuration, then
|
|
6
|
-
use the
|
|
33
|
+
use the broker tools from your normal Antigravity session. It does not
|
|
7
34
|
launch a replacement CLI, need a checkout of the broker, or spend model tokens
|
|
8
35
|
on transport heartbeats.
|
|
9
36
|
|
|
10
|
-
**
|
|
37
|
+
**Production requires automatic native delivery. Manual pull is diagnostic/test-only.** The agent calls `broker_receive`,
|
|
11
38
|
reads the returned untrusted-agent message, then calls `broker_acknowledge` with
|
|
12
|
-
its exact `message_id`
|
|
39
|
+
its exact `message_id` (the already exposed receipt is resolved internally). Nothing injects keystrokes, interrupts
|
|
13
40
|
a task, auto-approves permissions, or wakes an idle model. A receipt means an
|
|
14
41
|
explicit application-level read acknowledgment, **not completion of the requested
|
|
15
42
|
work**.
|
|
16
43
|
|
|
44
|
+
The [native integration](docs/setup.md) now supports URL-only setup and saved
|
|
45
|
+
installation reconnection; [native acceptance evidence](docs/native-acceptance.md)
|
|
46
|
+
separates tested transport/persistence from the outstanding authenticated wake gate.
|
|
47
|
+
It never enables itself or changes native permission policy.
|
|
48
|
+
|
|
17
49
|
## Install and configure
|
|
18
50
|
|
|
51
|
+
For brokers supporting the pairing API, [explicit installation pairing](docs/pairing.md)
|
|
52
|
+
can create a private bundle from a pairing-file path without initial environment
|
|
53
|
+
variables. Pairing alone does not attach a native conversation or enable push.
|
|
54
|
+
|
|
19
55
|
Requires Linux and Node **24.19+ within major 24**. No dependencies or install
|
|
20
|
-
scripts.
|
|
56
|
+
scripts. For reviewed source commits already on `main`, Git installation is available:
|
|
21
57
|
|
|
22
58
|
```sh
|
|
23
59
|
npm install --global 'github:matuto-ai/antigravity-broker-connector#main'
|
|
@@ -28,7 +64,7 @@ For reproducibility, replace the branch with the reviewed commit SHA. The npm
|
|
|
28
64
|
package is prepared as `@matuto-ai/antigravity-broker-connector`; **a prepared release
|
|
29
65
|
workflow is not evidence that it has been published**. After the maintainer
|
|
30
66
|
publishes it, install the exact scoped version with
|
|
31
|
-
`npm install --global @matuto-ai/antigravity-broker-connector@0.
|
|
67
|
+
`npm install --global @matuto-ai/antigravity-broker-connector@0.4.0`.
|
|
32
68
|
The executable remains `psst-antigravity`.
|
|
33
69
|
|
|
34
70
|
Use a private enrollment bundle produced by the broker administrator. Keep
|
|
@@ -43,6 +79,7 @@ other servers):
|
|
|
43
79
|
"mcpServers": {
|
|
44
80
|
"psst": {
|
|
45
81
|
"command": "psst-antigravity",
|
|
82
|
+
"args": ["diagnostic"],
|
|
46
83
|
"env": {
|
|
47
84
|
"PSST_CONFIG_FILE": "/absolute/private/psst/connection.json",
|
|
48
85
|
"PSST_NAME": "Antigravity reviewer",
|
|
@@ -62,14 +99,15 @@ unchanged. See [complete installation and test](docs/installation.md).
|
|
|
62
99
|
|
|
63
100
|
- `broker_identity`: this MCP process's exact address and descriptive metadata.
|
|
64
101
|
- `broker_list_clients`: discover currently connected authorized endpoints.
|
|
65
|
-
- `broker_send`: send to an exact `client_id`;
|
|
102
|
+
- `broker_send`: send to an exact `client_id`; technical retry keys stay private; inspect outgoing history after uncertainty.
|
|
66
103
|
- `broker_receive`: read the pending FIFO head without removing it.
|
|
67
|
-
- `broker_acknowledge`: explicit read ACK; safely repeat the same ID
|
|
104
|
+
- `broker_acknowledge`: explicit read ACK; safely repeat the same message ID; the receipt token stays private.
|
|
68
105
|
- `broker_message_status`: broker transport state, never task completion.
|
|
69
106
|
- `broker_update_metadata`: update descriptive fields with revision checking.
|
|
70
107
|
|
|
71
|
-
Every message
|
|
72
|
-
|
|
108
|
+
Every message has a compact AI-agent sender header and escaped JSON text. Wire
|
|
109
|
+
origin/authority validation is unchanged: another agent is not the human user and
|
|
110
|
+
cannot grant permissions. Only the normal Antigravity permission
|
|
73
111
|
system can authorize tool actions.
|
|
74
112
|
|
|
75
113
|
## Identity and limits
|
|
@@ -99,7 +137,12 @@ and requires the pinned broker checkout alongside this repository. Runtime
|
|
|
99
137
|
installation does not. CI provisions the checkout automatically. The old runner
|
|
100
138
|
is retained for research only: [experimental integration](docs/integration.md).
|
|
101
139
|
|
|
102
|
-
The
|
|
103
|
-
|
|
140
|
+
The package CLI defaults to a blocked automatic-delivery-required state, not a
|
|
141
|
+
manual production fallback. `psst-antigravity diagnostic --config <private-path>`
|
|
142
|
+
explicitly enables the legacy test-only MCP route; the normal path is the native plugin. [Release checklist](docs/release.md) explains the npm trusted
|
|
104
143
|
publisher setup and release-driven workflow. No main merge or npm publication is
|
|
105
144
|
performed by preparing this branch.
|
|
145
|
+
|
|
146
|
+
Outgoing history, content, explicit resend and cancellation: [candidate contract](docs/message-lifecycle.md).
|
|
147
|
+
|
|
148
|
+
[Candidate verification and remaining gates](docs/candidate-verification.md).
|
|
@@ -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,15 +1,34 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
const usage = 'Usage: psst-antigravity --config /absolute/private/config.json\
|
|
2
|
+
import { fileURLToPath } from 'node:url';
|
|
3
|
+
import { inspectNativeInstallation, nativeInstallationError } from '../src/native-installation.mjs';
|
|
4
|
+
const usage = 'Usage: psst-antigravity doctor [absolute-plugin-directory] (read-only native installation check)\n psst-antigravity diagnostic --config /absolute/private/config.json\n psst-antigravity pair --pairing-file /absolute/private/pairing.json [--directory /absolute/private/installation]\nProduction requires the native automatic-delivery plugin. The cooperative stdio MCP server is diagnostic/test-only; it does not launch or inject into Antigravity.\nPair explicitly enrolls this installation; it does not connect or wake a native conversation.\n';
|
|
5
5
|
if (process.argv.length === 3 && ['--help','-h'].includes(process.argv[2])) { process.stdout.write(usage); }
|
|
6
|
+
else if (process.argv[2] === 'doctor') {
|
|
7
|
+
try {
|
|
8
|
+
if (process.argv.length > 4) throw Error('absolute_plugin_directory_required');
|
|
9
|
+
const result = inspectNativeInstallation(process.argv[3] ?? fileURLToPath(new URL('../', import.meta.url)));
|
|
10
|
+
process.stdout.write(JSON.stringify(result, null, 2) + '\n');
|
|
11
|
+
} catch (error) {
|
|
12
|
+
const code = /^[a-z0-9_]+$/.test(error.message) ? error.message : 'inspection_failed';
|
|
13
|
+
process.stderr.write(`psst: ${code}: ${nativeInstallationError(code)}\n`); process.exitCode = 1;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
else if (process.argv[2] === 'pair') {
|
|
17
|
+
try { const { pairingOptions, pairConnector } = await import('../src/pairing.mjs'); process.stdout.write(JSON.stringify(await pairConnector(pairingOptions(process.argv.slice(2)))) + '\n'); }
|
|
18
|
+
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; }
|
|
19
|
+
}
|
|
20
|
+
else if (process.argv[2] !== 'diagnostic') {
|
|
21
|
+
process.stderr.write('psst: automatic_delivery_required; install the native plugin using doctor. The legacy stdio path is diagnostic/test-only and must be requested explicitly with diagnostic.\n'); process.exitCode=2;
|
|
22
|
+
}
|
|
6
23
|
else {
|
|
7
24
|
let connector;
|
|
8
25
|
const controller = new AbortController();
|
|
9
26
|
const stop = () => { controller.abort(); void connector?.close(); };
|
|
10
27
|
process.on('SIGINT', stop); process.on('SIGTERM', stop);
|
|
11
28
|
try {
|
|
12
|
-
const
|
|
29
|
+
const { readConnectorConfig } = await import('../src/connector-config.mjs');
|
|
30
|
+
const { startConnector } = await import('../src/connector.mjs');
|
|
31
|
+
const path = process.argv.length === 5 && process.argv[3] === '--config' ? process.argv[4] : process.argv.length === 3 ? process.env.PSST_CONFIG_FILE : null;
|
|
13
32
|
if (!path) throw new Error();
|
|
14
33
|
process.stdin.pause();
|
|
15
34
|
const config = readConnectorConfig(path);
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# Unreleased candidate verification — 2026-11-01
|
|
2
|
+
|
|
3
|
+
Related issue: #8; not closed by this partial delivery.
|
|
4
|
+
|
|
5
|
+
## Checked locally
|
|
6
|
+
|
|
7
|
+
Syntax passed; full suite 88/91 passed. Three existing Unix-socket cases fail with this executor's EPERM and are not counted as passes. Pack smoke passed.
|
|
8
|
+
|
|
9
|
+
Official Antigravity 1.4.7 validator and isolated native install/list passed with candidate 0.4.0, one MCP server, one hook group and two skills. Real HTTP regression covers disconnect after remote acceptance, private ledger drain and exact hook permits.
|
|
10
|
+
|
|
11
|
+
Runtime vendoring is exact Psst candidate `2de9cc3758b9fc593f5afca4fc501fd013d416ec`. Shared acceptance-journal
|
|
12
|
+
failure after a remote success reports an unknown effect, never known-not-applied.
|
|
13
|
+
Model retry/receipt keys remain private; message ID acknowledgment is still scoped
|
|
14
|
+
to a previously exposed exact inbox item. Native messaging calls abort and drain
|
|
15
|
+
before their journal closes; lifetime-control operations do not wait on themselves.
|
|
16
|
+
|
|
17
|
+
## Not established
|
|
18
|
+
|
|
19
|
+
The three socket cases need a permitted normal runner. Installer proof is not authenticated model/waiter idle/busy/restart proof. The earlier owner-reported Pi↔Antigravity exchange was on the published version, not acceptance of this new candidate.
|
|
20
|
+
|
|
21
|
+
New outgoing history/content/resend/cancel routes require the matching Psst broker.
|
|
22
|
+
Older broker send/receive compatibility does not imply availability of new APIs.
|
|
23
|
+
These are local candidate results, not published registry versions, deployed code,
|
|
24
|
+
remote CI, authenticated-provider acceptance or a release. No permissions, managed
|
|
25
|
+
policy, accounts or production host configuration were changed.
|
package/docs/installation.md
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# Native MCP installation
|
|
2
2
|
|
|
3
|
+
> Legacy diagnostic/test reference only. Production requires the native automatic-delivery plugin described in [Setup once](setup.md). Do not configure manual pull as a production fallback. In the unreleased 0.4.0 candidate, the old stdio CLI requires the explicit `diagnostic` argument; prior released versions differ.
|
|
4
|
+
|
|
3
5
|
## 1. Prerequisites
|
|
4
6
|
|
|
5
7
|
Run inside the existing Antigravity sandbox, not on the host as a replacement
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# Outgoing message lifecycle (unreleased candidate)
|
|
2
|
+
|
|
3
|
+
`broker_send` takes recipient ID and text; retry keys are never model arguments or
|
|
4
|
+
results. `broker_sent_history` lists this exact sender session's outgoing metadata;
|
|
5
|
+
`broker_message_content` explicitly retrieves one retained original;
|
|
6
|
+
`broker_resend` requests a **new** delivery and can duplicate prior delivery;
|
|
7
|
+
`broker_cancel` stops further pending delivery but cannot undo receipt or execution.
|
|
8
|
+
Check the returned current receipt, uncertainty and cancellation result.
|
|
9
|
+
|
|
10
|
+
The connector persists an internal operation before HTTP. Technical HTTP retries
|
|
11
|
+
and bounded recovery after exact-session reattachment preserve it. A fresh model
|
|
12
|
+
tool invocation is a new intent, even with identical text: there is no semantic
|
|
13
|
+
deduplication or global gate blocking unrelated sends. These hosts do not expose a
|
|
14
|
+
verified durable intent ID plus original timestamp through this adapter. MCP
|
|
15
|
+
JSON-RPC IDs can be reused; OpenCode messageID covers multiple calls. Neither is
|
|
16
|
+
misrepresented as durable retry identity. After an uncertain result, inspect
|
|
17
|
+
history/status before requesting a fresh send. Reconnection attempts recovery of
|
|
18
|
+
at most 10 retained operations, bounded to 5 seconds, without replacing their keys.
|
|
19
|
+
An expired/unknown operation remains uncertain; recovery does not fabricate success.
|
|
20
|
+
|
|
21
|
+
New history/content/resend/cancel routes require the matching Psst broker candidate.
|
|
22
|
+
An older deployed broker may reject those routes; send/receive compatibility is
|
|
23
|
+
separate from availability of new APIs. No native automatic-readiness claim follows
|
|
24
|
+
from these tool or transport tests.
|
|
@@ -0,0 +1,69 @@
|
|
|
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.
|
|
59
|
+
|
|
60
|
+
## Owner-reported live test — 2026-11-01
|
|
61
|
+
|
|
62
|
+
The owner installed `psst-native` using the original scoped npm path and reported
|
|
63
|
+
successful bidirectional Pi ↔ Antigravity messaging with model read receipts.
|
|
64
|
+
This is meaningful native connectivity evidence for that tested pair, not an
|
|
65
|
+
independent recording by this test suite or proof of all idle-wake/restart gates.
|
|
66
|
+
Earlier missing-path/parser/owner-lock failures remain installation usability
|
|
67
|
+
findings; the later same-path success means a universal `@` parser limitation
|
|
68
|
+
must not be inferred. The read-only installation doctor now checks the actual
|
|
69
|
+
root and gives the in-session slash command without source copying or policy changes.
|
|
@@ -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,50 @@
|
|
|
1
|
+
# Explicit installation pairing
|
|
2
|
+
|
|
3
|
+
> Legacy diagnostic/test reference only. Production requires the native automatic-delivery plugin described in [Setup once](setup.md). Do not configure manual pull as a production fallback. In the unreleased 0.4.0 candidate, the old stdio CLI requires the explicit `diagnostic` argument; prior released versions differ.
|
|
4
|
+
|
|
5
|
+
This additive command prepares a credential bundle. It **does not connect a
|
|
6
|
+
running Antigravity conversation or enable automatic delivery**. Existing
|
|
7
|
+
`--config` and `PSST_CONFIG_FILE` cooperative MCP configuration remain unchanged.
|
|
8
|
+
The broker must support the reviewed `/v1/enrollments` pairing API; a prepared
|
|
9
|
+
broker change is not evidence that the operator deployed it.
|
|
10
|
+
|
|
11
|
+
The operator provides a short-lived, single-use private pairing file. Place it
|
|
12
|
+
inside the intended sandbox with mode `0600` and a private parent directory.
|
|
13
|
+
Never paste its contents into a model prompt, command argument, URL or log.
|
|
14
|
+
|
|
15
|
+
```sh
|
|
16
|
+
psst-antigravity pair --pairing-file /absolute/private/pairing.json
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
No initial environment variables are required. The default installation directory
|
|
20
|
+
is `~/.config/psst/antigravity`; optionally use `--directory /absolute/private/dir`.
|
|
21
|
+
All paths must be absolute. The helper validates HTTPS origin, client type and
|
|
22
|
+
private file ownership/modes; it creates private retry state before HTTP.
|
|
23
|
+
It generates this installation's bearer token locally and transmits only its
|
|
24
|
+
SHA-256 verifier. The pairing secret is sent only in the HTTPS Authorization
|
|
25
|
+
header. Existing credentials and legacy bundles are not overwritten.
|
|
26
|
+
|
|
27
|
+
Success prints nonsecret JSON including `connectionFile`, `credentialId`,
|
|
28
|
+
`expiresAt` and `connected:false`. Use the returned `connectionFile` as the
|
|
29
|
+
existing MCP entry's `--config` argument. Keep the installation directory: it
|
|
30
|
+
contains the private token and recovery state. A restarted cooperative connector
|
|
31
|
+
still has a fresh process address; pairing does not change that scope.
|
|
32
|
+
|
|
33
|
+
New bundles are explicitly marked with `enrollment_receipt_file:"enrollment.json"`.
|
|
34
|
+
The connector verifies the private sibling receipt against the bundle's origin,
|
|
35
|
+
client type and token hash; missing, corrupt, mismatched or expired receipts fail
|
|
36
|
+
closed. An older connector may reject this new marker: upgrade the connector
|
|
37
|
+
before pairing. Unmarked legacy administrator-generated bundles remain supported.
|
|
38
|
+
|
|
39
|
+
For an uncertain network/storage result, keep the same pairing file and directory
|
|
40
|
+
for an explicit retry: the persisted enrollment ID and token are reused. A new
|
|
41
|
+
pairing grant is required after credential expiry or revocation. An error is not
|
|
42
|
+
proof that the broker failed to store the enrollment. Never delete retry state to
|
|
43
|
+
make an uncertain result look new.
|
|
44
|
+
|
|
45
|
+
The vendored single-file helper is shared with the Psst broker implementation;
|
|
46
|
+
it is separate from the older pinned reference runtime. Its local integrity and
|
|
47
|
+
compatibility are checked by the pairing tests; it makes no native-delivery claim.
|
|
48
|
+
It is pinned to [Psst commit 3e908e7](https://github.com/matuto-ai/psst/blob/3e908e79966d886a02d372c103e31dec6e900c1a/reference/enrollment.mjs)
|
|
49
|
+
from [upstream pairing PR #18](https://github.com/matuto-ai/psst/pull/18).
|
|
50
|
+
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.
|