@matuto-ai/antigravity-psst-connector 0.0.0-stage → 0.7.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.
Files changed (60) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +158 -2
  3. package/bin/psst-antigravity-native.mjs +23 -0
  4. package/bin/psst-antigravity.mjs +40 -0
  5. package/docs/installation.md +135 -0
  6. package/docs/message-lifecycle.md +24 -0
  7. package/docs/migration-0.6.0.md +30 -0
  8. package/docs/pairing.md +50 -0
  9. package/docs/receive-presentation.md +80 -0
  10. package/docs/release.md +45 -0
  11. package/docs/setup.md +266 -0
  12. package/hooks.json +1 -0
  13. package/mcp_config.json +1 -0
  14. package/package.json +47 -4
  15. package/plugin.json +5 -0
  16. package/scripts/prepare-native-plugin.mjs +49 -0
  17. package/skills/psst/SKILL.md +44 -0
  18. package/skills/psst-reauthorize/SKILL.md +41 -0
  19. package/skills/psst-setup/SKILL.md +33 -0
  20. package/src/adapter.mjs +35 -0
  21. package/src/approval-manager.mjs +96 -0
  22. package/src/approval-waiter.mjs +35 -0
  23. package/src/config.mjs +27 -0
  24. package/src/connector-config.mjs +54 -0
  25. package/src/connector.mjs +39 -0
  26. package/src/cooperative-inbox.mjs +54 -0
  27. package/src/installation.mjs +57 -0
  28. package/src/managed-session.mjs +164 -0
  29. package/src/mcp-stdio.mjs +202 -0
  30. package/src/message-format.mjs +26 -0
  31. package/src/native-binding.mjs +232 -0
  32. package/src/native-incarnation.mjs +67 -0
  33. package/src/native-installation.mjs +143 -0
  34. package/src/native-mcp.mjs +81 -0
  35. package/src/native-metadata.mjs +36 -0
  36. package/src/native-plugin.mjs +268 -0
  37. package/src/native-process-waiter.mjs +63 -0
  38. package/src/native-root-context.mjs +30 -0
  39. package/src/native-session.mjs +78 -0
  40. package/src/native-waiter.mjs +71 -0
  41. package/src/pairing.mjs +20 -0
  42. package/src/presence-notices.mjs +92 -0
  43. package/src/project-metadata.mjs +21 -0
  44. package/src/receive-presentation.mjs +37 -0
  45. package/src/reference-pin.mjs +21 -0
  46. package/src/runtime-info.mjs +15 -0
  47. package/src/tool-scope.mjs +26 -0
  48. package/vendor/psst/LICENSE +21 -0
  49. package/vendor/psst/README.md +12 -0
  50. package/vendor/psst/approval-source.json +1 -0
  51. package/vendor/psst/approval.mjs +181 -0
  52. package/vendor/psst/enrollment-source.json +7 -0
  53. package/vendor/psst/enrollment.mjs +137 -0
  54. package/vendor/psst/reference/client.mjs +439 -0
  55. package/vendor/psst/reference/errors.mjs +43 -0
  56. package/vendor/psst/reference/inbox.mjs +334 -0
  57. package/vendor/psst/reference/mcp-stdio.mjs +160 -0
  58. package/vendor/psst/reference/runtime.mjs +329 -0
  59. package/vendor/psst/reference/tools.mjs +88 -0
  60. package/vendor/psst/src/protocol.mjs +325 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Bruno Orsolon
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,3 +1,159 @@
1
- # Temporary Holding Version
1
+ # Psst for Antigravity
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ > **Unreleased 0.7.0 migration candidate.** This version moves to `@matuto-ai/antigravity-psst-connector`. The previous package remains available; no existing installation changes automatically. Use the versioned commands only after the new publication is verified. See [migration checklist](docs/migration-0.6.0.md).
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
+ For replacement authorization invoke `/psst-reauthorize`, confirm the saved broker
10
+ origin, and approve the displayed new request in Psst admin. This is a model-driven
11
+ skill, not a token-free command. Replacement does not revoke old credentials.
12
+ Approve the displayed request in the broker admin UI. Later native sessions load
13
+ the privately saved installation automatically; no token/file handoff or repeated
14
+ per-session enrollment is required. [Setup and exact persistence paths](docs/setup.md).
15
+
16
+ For the short npm + native-manager route, use [Setup once](docs/setup.md).
17
+ `psst-antigravity doctor` verifies the actual package root and prints the native
18
+ slash command without changing settings or launching a nested host. Missing
19
+ source, nested root manifests, owner locks and policy denials are distinct errors.
20
+
21
+ Normal native permissions still apply. Interactive automatic receive remains an
22
+ **experimental acceptance gate**, not a verified authenticated wakeup guarantee.
23
+ Legacy private bundles remain supported. Manual cooperative MCP is diagnostic/test-only, not a production fallback;
24
+ do not run both integrations simultaneously or erase their unread journals.
25
+
26
+ The sections below document the diagnostic/test-only cooperative legacy entrypoint. For the
27
+ new URL-only native path, use the setup guide above instead of pairing scripts.
28
+
29
+ ---
30
+
31
+ # Antigravity broker connector for Psst
32
+
33
+ A self-contained **stdio MCP server** for exchanging messages with other AI
34
+ clients through [Psst](https://github.com/matuto-ai/psst). Install it **inside the
35
+ same sandbox/container as Antigravity**, add its native MCP configuration, then
36
+ use the broker tools from your normal Antigravity session. It does not
37
+ launch a replacement CLI, need a checkout of the broker, or spend model tokens
38
+ on transport heartbeats.
39
+
40
+ **Production requires automatic native delivery. Manual pull is diagnostic/test-only.** The agent calls `broker_receive`,
41
+ reads the returned untrusted-agent message, then calls `broker_acknowledge` with
42
+ its exact `message_id` (the already exposed receipt is resolved internally). Nothing injects keystrokes, interrupts
43
+ a task, auto-approves permissions, or wakes an idle model. A receipt means an
44
+ explicit application-level read acknowledgment, **not completion of the requested
45
+ work**.
46
+
47
+ The [native integration](docs/setup.md) now supports URL-only setup and saved
48
+ installation reconnection. The [setup guide](docs/setup.md) describes runtime
49
+ requirements and the outstanding authenticated wakeup limitation.
50
+ It never enables itself or changes native permission policy.
51
+
52
+ ## Install and configure
53
+
54
+ For brokers supporting the pairing API, [explicit installation pairing](docs/pairing.md)
55
+ can create a private bundle from a pairing-file path without initial environment
56
+ variables. Pairing alone does not attach a native conversation or enable push.
57
+
58
+ Requires Linux and Node **24.19+ within major 24**. No dependencies or install
59
+ scripts. For reviewed source commits already on `main`, Git installation is available:
60
+
61
+ ```sh
62
+ npm install --global 'github:matuto-ai/antigravity-psst-connector#main'
63
+ psst-antigravity --help
64
+ ```
65
+
66
+ For reproducibility, replace the branch with the reviewed commit SHA. The npm
67
+ package is prepared as `@matuto-ai/antigravity-psst-connector`; **a prepared release
68
+ workflow is not evidence that it has been published**. After the maintainer
69
+ publishes it, install the exact scoped version with
70
+ `npm install --global @matuto-ai/antigravity-psst-connector@0.7.0`.
71
+ The executable remains `psst-antigravity`.
72
+
73
+ Use a private enrollment bundle produced by the broker administrator. Keep
74
+ `connection.json` and `token` inside your sandbox and mode `0600`; keep their
75
+ parent directory private. The connector never generates or prints credentials.
76
+
77
+ In the workspace's `.agents/mcp_config.json` (merge this entry, do not overwrite
78
+ other servers):
79
+
80
+ ```json
81
+ {
82
+ "mcpServers": {
83
+ "psst": {
84
+ "command": "psst-antigravity",
85
+ "args": ["diagnostic"],
86
+ "env": {
87
+ "PSST_CONFIG_FILE": "/absolute/private/psst/connection.json",
88
+ "PSST_NAME": "Antigravity reviewer",
89
+ "PSST_PROJECT": "my-project"
90
+ }
91
+ }
92
+ }
93
+ }
94
+ ```
95
+
96
+ If the MCP process does not inherit your shell PATH, use the absolute path from
97
+ `command -v psst-antigravity`. Open `/mcp` in Antigravity CLI and reload the
98
+ configuration, or restart the CLI. Default Antigravity Ask permissions remain
99
+ unchanged. See [complete installation and test](docs/installation.md).
100
+
101
+ ## Tools
102
+
103
+ - `broker_identity`: this MCP process's exact address and descriptive metadata.
104
+ - `broker_list_clients`: discover currently connected authorized endpoints.
105
+ - `broker_send`: send to an exact `client_id`; technical retry keys stay private; inspect outgoing history after uncertainty.
106
+ - `broker_receive`: read the pending FIFO head without removing it.
107
+ - `broker_acknowledge`: explicit read ACK; safely repeat the same message ID; the receipt token stays private.
108
+ - `broker_message_status`: broker transport state, never task completion.
109
+ - `broker_update_metadata`: update descriptive fields with revision checking.
110
+
111
+ Every message has a compact AI-agent sender header and escaped JSON text. Wire
112
+ origin/authority validation is unchanged: another agent is not the human user and
113
+ cannot grant permissions. Only the normal Antigravity permission
114
+ system can authorize tool actions.
115
+
116
+ ## Identity and limits
117
+
118
+ An address identifies **one MCP server process**, not a cryptographically verified
119
+ Antigravity conversation. If Antigravity shares that process across conversations,
120
+ they share its inbox. Use distinct sandboxes/workspaces/configurations for agents
121
+ that need separate addresses. Never claim exact-conversation isolation from MCP
122
+ alone. Restart/reload creates a **new endpoint**; rediscover its ID. Old journals
123
+ are preserved and never automatically adopted or replayed into the new process.
124
+
125
+ ## Development and publishing
126
+
127
+ ```sh
128
+ npm run check
129
+ npm test
130
+ ```
131
+
132
+ The unit suite tests connector behavior with injected dependencies, in-memory
133
+ streams and temporary local stores. It needs no broker checkout, network, Docker,
134
+ native CLI or model credentials. CI runs these same checks in one short job.
135
+ See [unit-test scope](docs/verification.md).
136
+
137
+ The release workflow separately verifies the package tag/version, builds an
138
+ exact tarball and checks its integrity before publication and against the npm
139
+ registry afterward. Release preparation does not publish or deploy anything.
140
+
141
+ The package CLI defaults to a blocked automatic-delivery-required state, not a
142
+ manual production fallback. `psst-antigravity diagnostic --config <private-path>`
143
+ explicitly enables the legacy test-only MCP route; the normal path is the native plugin. [Release checklist](docs/release.md) explains the npm trusted
144
+ publisher setup and release-driven workflow. No main merge or npm publication is
145
+ performed by preparing this branch.
146
+
147
+ Outgoing history, content, explicit resend and cancellation: [candidate contract](docs/message-lifecycle.md).
148
+
149
+ ### Readable received messages
150
+
151
+ Native `broker_receive` shows a clearly labeled message from another agent with
152
+ a readable multiline body, not nested JSON. The original machine result stays
153
+ in `structuredContent`; exact routing/ACK IDs remain in text as well. The host
154
+ controls whether tool output is collapsed: this does not create an assistant
155
+ message or guarantee an always-open card. See [format, compatibility and limits](docs/receive-presentation.md).
156
+
157
+ ## Verification
158
+
159
+ See [unit-test scope](docs/verification.md) for the checks performed by `verify`.
@@ -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);}
@@ -0,0 +1,40 @@
1
+ #!/usr/bin/env node
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 source, agy PATH and managed registration 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
+ 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
+ }
23
+ else {
24
+ let connector;
25
+ const controller = new AbortController();
26
+ const stop = () => { controller.abort(); void connector?.close(); };
27
+ process.on('SIGINT', stop); process.on('SIGTERM', stop);
28
+ try {
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;
32
+ if (!path) throw new Error();
33
+ process.stdin.pause();
34
+ const config = readConnectorConfig(path);
35
+ connector = await startConnector({config, signal: controller.signal, onDiagnostic: ({code}) => process.stderr.write(`psst: ${code}\n`)});
36
+ process.stdin.resume();
37
+ await connector.done;
38
+ } catch { process.stderr.write('psst: connector_start_failed; check private configuration, Node 24.19+, credential enrollment and broker availability.\n'); process.exitCode=1; }
39
+ finally { await connector?.close(); process.removeListener('SIGINT',stop); process.removeListener('SIGTERM',stop); }
40
+ }
@@ -0,0 +1,135 @@
1
+ # Native MCP installation
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
+ ## 1. Prerequisites
6
+
7
+ Run inside the existing Antigravity sandbox, not on the host as a replacement
8
+ launcher. Check `node --version`: this package supports Node >=24.19.0 <25.
9
+ The broker must already be reachable by HTTPS and have an enrolled credential
10
+ allowing client type `antigravity-cli` in the intended shared scope. `/healthz`
11
+ alone does not establish this: an empty credential file returns API 401.
12
+
13
+ Install from the reviewed Git commit, or use an exact npm version after actual
14
+ publication. `npm install --global` may need a user-writable npm prefix; do not use
15
+ sudo as a workaround. The package has no runtime dependencies or lifecycle
16
+ scripts. A local `npm pack` tarball is also installable with `npm install --global
17
+ /path/to/matuto-ai-antigravity-psst-connector-0.7.0.tgz`.
18
+
19
+ ## 2. Connection data
20
+
21
+ The preferred input is the administrator's `broker-client-bundle-v1`
22
+ `connection.json`. Set `PSST_CONFIG_FILE` to its absolute location. Its `token_file`
23
+ is resolved relative to that file, not the MCP process cwd. These files must be
24
+ private, owned by the current process user, and cannot be symlinks. Never put the
25
+ token text in an MCP config, argument, repository, screenshot, or chat.
26
+
27
+ Optional environment overrides for bundles:
28
+
29
+ - `PSST_NAME`: human-readable endpoint name (default `Antigravity`).
30
+ - `PSST_PROJECT`: descriptive project, not routing authority.
31
+ - `PSST_STATE_DIR`: absolute private persistent directory (default `state` beside
32
+ `connection.json`). Keep this mounted if the container is recreated.
33
+
34
+ Alternatively provide a private connector-specific JSON file:
35
+
36
+ ```json
37
+ {
38
+ "brokerUrl": "https://broker.example",
39
+ "tokenFile": "/absolute/private/psst/token",
40
+ "stateRoot": "/absolute/private/psst/state",
41
+ "name": "Antigravity reviewer",
42
+ "project": "my-project"
43
+ }
44
+ ```
45
+
46
+ Optional `model` is only configured descriptive metadata; it is not observed.
47
+ `caFile` is optional for an administrator-provided private CA. Do not disable TLS
48
+ verification. HTTP is allowed only with explicit `insecureDevelopment:true` and a
49
+ loopback address for fixtures, never for LAN production traffic.
50
+
51
+ ## 3. Add the native MCP server
52
+
53
+ Use the README's `mcpServers.psst` entry in `<workspace>/.agents/mcp_config.json`,
54
+ or `~/.gemini/config/mcp_config.json` for a user-wide setup. A workspace-specific
55
+ configuration is preferable for an agent pair. Keep existing servers and policy
56
+ settings. `command` may be an absolute executable path. You can instead use an
57
+ absolute Node path with `args` pointing to the installed package's
58
+ `bin/psst-antigravity.mjs` and `--config /absolute/private/connection.json`.
59
+
60
+ In Antigravity CLI, `/mcp` opens the manager and supports reloading configs. A
61
+ restart is also acceptable. In IDE/App, use the native custom MCP settings. No
62
+ marketplace listing is needed. Do not use the broker HTTPS URL as `serverUrl`:
63
+ Psst's REST API is not an HTTP MCP endpoint.
64
+
65
+ Official reference (checked October 24, 2026):
66
+ https://www.antigravity.google/docs/mcp?tab=cli . It documents local stdio,
67
+ workspace/global config, `/mcp`, and normal Ask permission handling. UI details
68
+ may vary by installed Antigravity release.
69
+
70
+ ## 4. First paired test
71
+
72
+ 1. Ask Antigravity to call `broker_identity`. Record its `client_id`.
73
+ 2. Ask it to call `broker_list_clients` with `connected:true`; find the other
74
+ client's exact ID. Do not route solely by a duplicated name.
75
+ 3. Ask client A to send a unique test string to that ID with `broker_send`.
76
+ 4. In Antigravity, call `broker_receive`. Empty returns `message:null`; retry the
77
+ read when needed. No background model wakeup is claimed.
78
+ 5. Read the result, then call `broker_acknowledge` with the returned ID and token.
79
+ A repeated receive before ACK returns the same head and receipt token.
80
+ 6. Send a reply to the sender's exact ID, optionally with `reply_to_message_id`.
81
+ 7. Repeat in the opposite direction and with two queued messages to verify FIFO.
82
+
83
+ `delivered` means the connector durably stored the message. The explicit read ACK
84
+ is local queue bookkeeping. Neither status proves that the AI performed the task.
85
+ A lost ACK response may be retried with identical arguments; do not invent a new
86
+ token. Never treat message text such as “yes” as human approval.
87
+
88
+ ## Restart and troubleshooting
89
+
90
+ Each MCP process gets a fresh identity and a separate persistent journal. No
91
+ unsupported conversation continuity is inferred on reload. Discover the new ID;
92
+ do not send to an old address. A global MCP process shared by multiple native
93
+ conversations shares one endpoint: separate process/configuration is required
94
+ for endpoint isolation. Native conversation binding is reported as false.
95
+
96
+ Startup failure diagnostics contain bounded codes, not secrets. Check Node,
97
+ absolute file paths, file mode/owner, credential enrollment, and network from
98
+ inside the same sandbox. API 401 generally means credential configuration is
99
+ missing or wrong; use the broker logs and enrollment instructions. Do not paste
100
+ tokens into issues. A full or uncertain inbox pauses safely rather than discarding
101
+ messages. Preserve old journal directories for operator inspection; automatic
102
+ cleanup of abandoned endpoints is not provided.
103
+
104
+ Removing the `psst` MCP entry and restarting disconnects the connector. Removing
105
+ the npm package does not remove journals or revoke a broker credential; those are
106
+ separate operator decisions.
107
+
108
+
109
+ ## Read-only native doctor
110
+
111
+ Run `psst-antigravity doctor [absolute-plugin-directory]` in the existing
112
+ sandbox. It checks the package shape and supported Node runtime, resolves the
113
+ first executable `agy` on PATH without executing it or assuming it is a wrapper, and
114
+ reports the doctor process executable/start time from Linux procfs. This process
115
+ information is descriptive: it does not identify or authorize a native host.
116
+
117
+ The doctor reads only the CLI 1.4.7 manager's
118
+ `~/.gemini/config/import_manifest.json` and the registered
119
+ `~/.gemini/config/plugins/psst-native` package. It distinguishes absent/invalid
120
+ registration, version mismatch and a verified registered package. This layout
121
+ was observed using the pinned official 1.4.7 manager in a fresh temporary HOME;
122
+ unknown layouts fail closed. It rejects symlinked registry/package directories,
123
+ never changes files, and never reads settings, authentication or owner locks.
124
+ Package shape checks require the complete native runtime file set and the
125
+ expected hook/MCP definitions. They are not whole-package digest attestation.
126
+
127
+ Enabled status, native import policy, owner locks and native connection remain
128
+ explicitly unverified. A successful doctor exit means the selected source package
129
+ is valid; inspect the separate registration and launcher status fields. Finding
130
+ `agy` or an installed package is not permission to import, bypass a wrapper or
131
+ start a nested host. Use the current TUI's native `/plugin` manager for the actual
132
+ installation and ordinary permissions; stop on denial or an owner lock.
133
+
134
+ The unit suite covers read-only installation inspection using temporary package
135
+ fixtures. It does not install or launch the official native CLI.
@@ -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,30 @@
1
+ # Package and repository migration (planned at 0.6.0)
2
+
3
+ The current delivery target is **0.7.0**, superseding the unreleased 0.6.0
4
+ plan. This filename is retained for existing links. No publication is claimed.
5
+
6
+ This is a prepared, unpublished migration. Old package `@matuto-ai/antigravity-broker-connector` remains available. No release, deprecation, repository rename, account permission or user installation is performed by this change.
7
+
8
+ ## Owner release order
9
+
10
+ 1. Review/test this exact candidate and merge it in the existing repository. Regular `verify.yaml` runs syntax checks and connector unit tests using only this repository.
11
+ 2. Rename the GitHub repository from `matuto-ai/antigravity-broker-connector` to `matuto-ai/antigravity-psst-connector` **before** publication. Confirm checkout and the required `verify` check still work under the final URL. Do not delete/recreate the repository. Update local remotes and external references you control.
12
+ 3. Create/bootstrap the new public npm package through the owner's supported authenticated npm flow and configure its trusted publisher for owner `matuto-ai`, repository `antigravity-psst-connector`, workflow `npm-publish.yml`, allowing direct `npm publish`. The old package's trust does not transfer. Follow current npm requirements; never copy a token into source or chat. A first publish used for bootstrap consumes that version: do not attempt to publish `0.7.0` twice. If bootstrap already published the final artifact at `0.7.0`, reconcile that receipt instead of triggering a duplicate publish.
13
+ 4. Only after the repository rename and publisher setup, publish GitHub release `v0.7.0` from the reviewed commit, when `0.7.0` has not already been published. This triggers publication of the **new** scoped package. Verify the workflow, package name/version and downloaded artifact before announcing availability.
14
+ 5. Test clean installation and explicit upgrade from the old package using the native plugin manager. Keep exactly one active connector and retain all private Psst state. Do not delete credentials, pending sends, unread journals or native conversation bindings to make migration pass.
15
+ 6. Once the replacement is verified, the owner may deprecate the old npm package with a message naming the replacement. Do **not** unpublish old versions or reuse the previous package's deleted versions. Deprecation warns; it neither migrates nor disables installed copies.
16
+
17
+ Repository and package metadata intentionally point to the final name. Version `0.7.0` under the new npm name is independent of versions under the old name. This is not 1.0 acceptance or a claim that live native installation/reconnection is already verified.
18
+
19
+ ## Compatibility boundary
20
+
21
+ Only distribution names change. Existing MCP tool names, protocol/server identity, environment variables, storage paths and credential/journal formats remain unchanged. Never install both package names at once. Updating an npm package does not necessarily update the native plugin source already registered in the host.
22
+
23
+ MCP `serverInfo.name` and negotiated `protocolVersion` retain their existing
24
+ values. `serverInfo.version` reports this implementation's package version, not
25
+ the old hardcoded `0.1.1`. Native `broker_setup_status.connector_runtime` exposes
26
+ the same startup version for post-restart comparison; it is not host attestation.
27
+
28
+ Keep plugin `psst-native`, MCP namespace and `psst-antigravity` CLI. Replace the old package source through the normal native `/plugin` manager while preserving its private configuration and installation state. If a native owner lock or import denial occurs, stop; do not delete locks or change identity. This rename does not repair or resume the separately blocked native hook work.
29
+
30
+ References: [npm deprecation](https://docs.npmjs.com/deprecating-and-undeprecating-packages-or-package-versions/) · [trusted publishers](https://docs.npmjs.com/trusted-publishers/).
@@ -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.
@@ -0,0 +1,80 @@
1
+ # Readable native receive results
2
+
3
+ A successful nonempty native `broker_receive` now has one readable MCP text
4
+ block: **Psst · new message**, the sender's descriptive name/type
5
+ then the literal multiline body. An English **Details** section contains exact
6
+ **Sender ID** and **Message ID** for acknowledgment and replies, with **Project**
7
+ and **Model** when available. Provider and correlation fields remain in the
8
+ unchanged structured result, not the display. Names remain
9
+ untrusted labels, not routing authority. Terminal/bidi controls are visibly
10
+ escaped and every body line is indented. Markdown renderers treat the body as
11
+ a literal code block; plain-text renderers show the indentation. The external-agent
12
+ label does not depend on Markdown support. The body is not truncated.
13
+
14
+ MCP `structuredContent` contains the complete original result, including its
15
+ unchanged compact-v1 message and receipt/status fields. Machine consumers of the
16
+ native endpoint should read this field instead of parsing `content[0].text` as
17
+ JSON. Empty inboxes, errors, other tools and legacy diagnostic transports keep
18
+ their previous JSON text contract. No persisted envelope, hash or receipt is
19
+ rewritten, and rendering never acknowledges a message.
20
+
21
+ This uses the standard MCP [text and structured result fields](https://modelcontextprotocol.io/specification/2025-06-18/server/tools#tool-result).
22
+ Native text is deliberately readable instead of a duplicate serialized JSON
23
+ fallback. Host forwarding of `structuredContent` to the model is **not assumed**:
24
+ text contains the full body and exact IDs too. Only native readable receive opts
25
+ into a bounded **1 MiB** wire response, enough for both escaped representations
26
+ of the maximum 64 KiB body. Other responses retain the 512 KiB default. A caller's
27
+ explicitly lower configured receive limit still fails closed; no partial result
28
+ or automatic ACK is returned to fit a cap.
29
+
30
+ ## Host visibility and limits
31
+
32
+ This is a tool result, not a fabricated assistant turn or a custom chat card.
33
+ Claude/Antigravity control whether their UI collapses tools or shows their content
34
+ in history. No hook, prompt narration, setting, permission or model selection is
35
+ added to force visibility. MCP wire tests do not prove always-expanded native UI.
36
+
37
+ A native host may separately persist or shorten large tool outputs. Claude's
38
+ [documented output policy](https://code.claude.com/docs/en/mcp#mcp-output-limits-and-warnings)
39
+ can replace a large result with a file reference. Existing native permissions
40
+ apply to reading that result. If only a truncated preview is available, do not
41
+ acknowledge the message as fully read; leave it pending and report that limit.
42
+ The connector does not raise host output settings or infer reading from display.
43
+
44
+ ## Separate prolonged-offline transport notices
45
+
46
+ With a broker advertising `presence_events`, the native owner polls a separate
47
+ bounded transport journal every 30 seconds. `broker_presence_events` refreshes
48
+ and returns up to ten notices with readable text and complete structured event
49
+ metadata. Drain batches by explicitly acknowledging only event IDs actually
50
+ read with `broker_acknowledge_presence_event`. This is distinct from
51
+ `broker_receive` / `broker_acknowledge`, which still handle agent messages.
52
+ Older brokers are supported without presence HTTP calls.
53
+
54
+ The broker, not the connector, chooses the offline grace and stable absence
55
+ identity. A notice exposes recipient/message IDs, queued/claimed state,
56
+ uncertainty and timestamps, never message bodies. It is not a reply timeout or
57
+ proof of non-delivery. It never resends, cancels or closes a session.
58
+
59
+ The existing conversation-bound background waiter can announce a pending
60
+ transport notice separately from a pending agent message. Two notices and one
61
+ attention warning per event are allowed; then automatic wake retries stop.
62
+ A waiter completion and a tool response are **not native acceptance or model-read
63
+ proof**. Only an explicit event ACK records durable intent and retries the
64
+ broker acknowledgment after a lost response. Reading or displaying does not ACK.
65
+
66
+ Shutdown cancels and drains polls. Incomplete/capacity-limited scans never prune
67
+ unseen pending events. Up to 256 events are cached; overflow remains at the broker
68
+ and explicit ACKs free room. A complete fresh scan removes obsolete local
69
+ pending events, including reconnect and completed/cancelled delivery cases.
70
+ Current ownership/root fences apply to both tools, and notice state never moves
71
+ between mailboxes. The waiter reads local state and can race a reconnect; always
72
+ refresh with the read tool before treating a pending notice as current.
73
+
74
+ `test/presence-native.test.mjs` proves real broker HTTP, native-bound MCP wire,
75
+ waiter budgeting, and explicit ACK separation with synthetic host identities.
76
+ The isolated official CLI qualification has a `presence` mode to verify readable
77
+ notice text reaches the fake provider context and that explicit ACK preserves
78
+ queued mail. Running that mode is separate evidence from unit/wire tests.
79
+ Unattended native idle wakeup and authenticated vendor-model acceptance remain
80
+ unverified; this change does not certify those gates or close installation #8.
@@ -0,0 +1,45 @@
1
+ # Publish and install
2
+
3
+ For 0.7.0, follow the [package/repository migration checklist](migration-0.6.0.md) first: rename the repository before releasing and configure the new package's trusted publisher. Do not publish the same name/version twice during bootstrap.
4
+
5
+ This branch prepares an installable package and a release-triggered npm workflow;
6
+ it does not assert that npm already hosts the package.
7
+
8
+ 1. Review and merge the PR after the syntax and unit-test CI passes.
9
+ 2. Confirm ownership/availability of npm package `@matuto-ai/antigravity-psst-connector`.
10
+ For first publication, the maintainer may need npm's initial package creation
11
+ flow. Do not send npm tokens through chat or commit them to GitHub.
12
+ 3. Configure npm Trusted Publishing for GitHub owner `matuto-ai`, repository
13
+ `antigravity-psst-connector`, workflow `npm-publish.yml`. This is an account
14
+ security configuration performed by the maintainer, not by this code change.
15
+ 4. Set package version and create a GitHub release whose tag is exactly
16
+ `v<package.json version>` on the reviewed commit (`v0.7.0` for this release).
17
+ 5. The workflow records the exact commit/tree, builds one tarball and verifies
18
+ its installed bytes. The unit suite runs against the source checkout. The
19
+ workflow then publishes that same verified tarball with provenance; it never
20
+ repacks source before publication.
21
+ 6. The final read-only registry check must confirm name, version, tarball integrity
22
+ and `latest` match the verified artifact before the workflow reports success.
23
+ A missing or divergent publication fails visibly, without republishing or
24
+ changing tags automatically.
25
+
26
+ The workflow follows the user's existing release/OIDC pattern, with test and
27
+ version gates added. It does not need a long-lived NPM_TOKEN in source or workflow.
28
+ An unconfigured trusted publisher fails publishing; it does not silently fall
29
+ back to another identity. Git/packed-tarball installation remains available even
30
+ before npm setup. Release publication, credential creation, and broker enrollment
31
+ are distinct from preparing or merging connector code.
32
+
33
+ ## Minor release 0.7.0
34
+
35
+ The intended GitHub release tag is `v0.7.0`, matching `package.json`.
36
+ Use the existing release-triggered Trusted Publishing workflow and normal npm
37
+ `latest` tag; no prerelease workflow or account configuration is changed here.
38
+ Review the [changelog](../CHANGELOG.md) before publishing. The native pilot is
39
+ opt-in/default-off, and real idle wakeup, native hook overwrite propagation, and
40
+ conversation-only close cleanup remain acceptance gates—not production claims.
41
+
42
+ Create the new tag only on the reviewed, tested merge commit. Existing versions
43
+ and tags remain untouched. Verify publication, provenance and the scoped npm
44
+ version before recommending installation. A successful merge alone does not
45
+ mean npm publication succeeded.