@mquan/portal 0.0.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 +168 -0
- package/dist/src/api.d.ts +5 -0
- package/dist/src/api.js +357 -0
- package/dist/src/api.js.map +1 -0
- package/dist/src/cli.d.ts +17 -0
- package/dist/src/cli.js +618 -0
- package/dist/src/cli.js.map +1 -0
- package/dist/src/daemon-lifecycle.d.ts +24 -0
- package/dist/src/daemon-lifecycle.js +107 -0
- package/dist/src/daemon-lifecycle.js.map +1 -0
- package/dist/src/daemon.d.ts +17 -0
- package/dist/src/daemon.js +90 -0
- package/dist/src/daemon.js.map +1 -0
- package/dist/src/doctor.d.ts +14 -0
- package/dist/src/doctor.js +51 -0
- package/dist/src/doctor.js.map +1 -0
- package/dist/src/entrypoint.d.ts +2 -0
- package/dist/src/entrypoint.js +14 -0
- package/dist/src/entrypoint.js.map +1 -0
- package/dist/src/index.d.ts +5 -0
- package/dist/src/index.js +5 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/launch.d.ts +41 -0
- package/dist/src/launch.js +186 -0
- package/dist/src/launch.js.map +1 -0
- package/dist/src/mcp.d.ts +9 -0
- package/dist/src/mcp.js +132 -0
- package/dist/src/mcp.js.map +1 -0
- package/dist/src/network/client.d.ts +67 -0
- package/dist/src/network/client.js +540 -0
- package/dist/src/network/client.js.map +1 -0
- package/dist/src/network/coordinator.d.ts +83 -0
- package/dist/src/network/coordinator.js +225 -0
- package/dist/src/network/coordinator.js.map +1 -0
- package/dist/src/network/protocol.d.ts +1352 -0
- package/dist/src/network/protocol.js +360 -0
- package/dist/src/network/protocol.js.map +1 -0
- package/dist/src/network/server.d.ts +28 -0
- package/dist/src/network/server.js +474 -0
- package/dist/src/network/server.js.map +1 -0
- package/dist/src/network/tasks.d.ts +65 -0
- package/dist/src/network/tasks.js +276 -0
- package/dist/src/network/tasks.js.map +1 -0
- package/dist/src/portal-index.d.ts +21 -0
- package/dist/src/portal-index.js +140 -0
- package/dist/src/portal-index.js.map +1 -0
- package/dist/src/provider/claude-managed.d.ts +34 -0
- package/dist/src/provider/claude-managed.js +125 -0
- package/dist/src/provider/claude-managed.js.map +1 -0
- package/dist/src/provider/claude.d.ts +24 -0
- package/dist/src/provider/claude.js +114 -0
- package/dist/src/provider/claude.js.map +1 -0
- package/dist/src/provider/codex/app-server-client.d.ts +43 -0
- package/dist/src/provider/codex/app-server-client.js +143 -0
- package/dist/src/provider/codex/app-server-client.js.map +1 -0
- package/dist/src/provider/codex/index.d.ts +3 -0
- package/dist/src/provider/codex/index.js +4 -0
- package/dist/src/provider/codex/index.js.map +1 -0
- package/dist/src/provider/codex/managed-runner.d.ts +12 -0
- package/dist/src/provider/codex/managed-runner.js +162 -0
- package/dist/src/provider/codex/managed-runner.js.map +1 -0
- package/dist/src/provider/codex/probe.d.ts +2 -0
- package/dist/src/provider/codex/probe.js +33 -0
- package/dist/src/provider/codex/probe.js.map +1 -0
- package/dist/src/provider/codex/protocol.d.ts +193 -0
- package/dist/src/provider/codex/protocol.js +10 -0
- package/dist/src/provider/codex/protocol.js.map +1 -0
- package/dist/src/provider/codex/provider.d.ts +35 -0
- package/dist/src/provider/codex/provider.js +289 -0
- package/dist/src/provider/codex/provider.js.map +1 -0
- package/dist/src/provider/codex/remote-app-server.d.ts +16 -0
- package/dist/src/provider/codex/remote-app-server.js +80 -0
- package/dist/src/provider/codex/remote-app-server.js.map +1 -0
- package/dist/src/provider/codex/websocket-client.d.ts +40 -0
- package/dist/src/provider/codex/websocket-client.js +174 -0
- package/dist/src/provider/codex/websocket-client.js.map +1 -0
- package/dist/src/provider/types.d.ts +35 -0
- package/dist/src/provider/types.js +2 -0
- package/dist/src/provider/types.js.map +1 -0
- package/dist/src/recall/embedding.d.ts +28 -0
- package/dist/src/recall/embedding.js +142 -0
- package/dist/src/recall/embedding.js.map +1 -0
- package/dist/src/recall/types.d.ts +35 -0
- package/dist/src/recall/types.js +2 -0
- package/dist/src/recall/types.js.map +1 -0
- package/dist/src/rpc/client.d.ts +6 -0
- package/dist/src/rpc/client.js +58 -0
- package/dist/src/rpc/client.js.map +1 -0
- package/dist/src/rpc/protocol.d.ts +21 -0
- package/dist/src/rpc/protocol.js +11 -0
- package/dist/src/rpc/protocol.js.map +1 -0
- package/dist/src/rpc/server.d.ts +12 -0
- package/dist/src/rpc/server.js +154 -0
- package/dist/src/rpc/server.js.map +1 -0
- package/dist/src/runtime/paths.d.ts +8 -0
- package/dist/src/runtime/paths.js +18 -0
- package/dist/src/runtime/paths.js.map +1 -0
- package/dist/src/service.d.ts +127 -0
- package/dist/src/service.js +637 -0
- package/dist/src/service.js.map +1 -0
- package/dist/src/session-profile.d.ts +39 -0
- package/dist/src/session-profile.js +186 -0
- package/dist/src/session-profile.js.map +1 -0
- package/dist/src/storage/database.d.ts +9 -0
- package/dist/src/storage/database.js +354 -0
- package/dist/src/storage/database.js.map +1 -0
- package/dist/src/storage/repository.d.ts +275 -0
- package/dist/src/storage/repository.js +1291 -0
- package/dist/src/storage/repository.js.map +1 -0
- package/dist/src/version.d.ts +1 -0
- package/dist/src/version.js +2 -0
- package/dist/src/version.js.map +1 -0
- package/docs/architecture-plan.md +191 -0
- package/docs/mvp-plan.md +111 -0
- package/docs/remote-demo.md +346 -0
- package/package.json +47 -0
|
@@ -0,0 +1,346 @@
|
|
|
1
|
+
# Remote agent collaboration demo
|
|
2
|
+
|
|
3
|
+
Status: implemented locally; public packaging and tunnel validation deferred
|
|
4
|
+
Updated: 2026-09-05
|
|
5
|
+
|
|
6
|
+
## Goal
|
|
7
|
+
|
|
8
|
+
Demonstrate two people on different computers starting Portal-managed Codex
|
|
9
|
+
agents, discovering one another through a temporary public endpoint, agreeing
|
|
10
|
+
on a task, working independently in parallel, and exchanging progress and
|
|
11
|
+
results without either person copying messages between sessions.
|
|
12
|
+
|
|
13
|
+
Target host experience after distribution and tunnel setup:
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
npx -y @mquan/portal@demo serve --listen 127.0.0.1:8787
|
|
17
|
+
ngrok http 8787
|
|
18
|
+
|
|
19
|
+
npx -y @mquan/portal@demo codex \
|
|
20
|
+
--agent kai \
|
|
21
|
+
--server wss://abc.ngrok.app/ws
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
Friend:
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
npx -y @mquan/portal@demo codex \
|
|
28
|
+
--agent leo \
|
|
29
|
+
--server wss://abc.ngrok.app/ws
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
The demo package is published under the `demo` dist-tag so it cannot replace a
|
|
33
|
+
future stable `latest` release. Tunnel-provider automation remains deferred.
|
|
34
|
+
|
|
35
|
+
## Demo contract
|
|
36
|
+
|
|
37
|
+
1. `portal serve` runs an in-memory registry and WebSocket message relay on the
|
|
38
|
+
host computer. It binds to loopback and is exposed through an HTTPS tunnel
|
|
39
|
+
that supports WebSocket upgrades.
|
|
40
|
+
2. `portal codex --agent <name> --server <url>` lazily initializes Portal,
|
|
41
|
+
starts or connects to the local daemon, launches a Portal-managed Codex
|
|
42
|
+
session, and advertises only that session to the specified server.
|
|
43
|
+
3. An agent can list or search live agents connected to the same server.
|
|
44
|
+
Discovery is server-wide for this demo. Names are not reserved or verified;
|
|
45
|
+
ambiguous names return candidates and perform no action.
|
|
46
|
+
4. An agent can send a non-blocking task offer to a discovered agent. The
|
|
47
|
+
target sees a new attributed Codex turn automatically and can accept or
|
|
48
|
+
decline it.
|
|
49
|
+
5. An accepted task runs under the target Codex session's existing sandbox and
|
|
50
|
+
approval policy. Both agents can continue working independently and send
|
|
51
|
+
task-scoped updates.
|
|
52
|
+
6. Completion, failure, questions, and progress are routed back into the peer
|
|
53
|
+
session as new turns. No inbox polling or human message relay is required.
|
|
54
|
+
|
|
55
|
+
This demo does not require Git or a shared filesystem. Tasks may produce a
|
|
56
|
+
textual answer, tool result, file summary, URL, patch, commit, or any other
|
|
57
|
+
artifact reference the agents agree to exchange.
|
|
58
|
+
|
|
59
|
+
## Architecture
|
|
60
|
+
|
|
61
|
+
```text
|
|
62
|
+
host Codex friend Codex
|
|
63
|
+
| |
|
|
64
|
+
managed runner managed runner
|
|
65
|
+
| |
|
|
66
|
+
host portald friend portald
|
|
67
|
+
| |
|
|
68
|
+
+------ outbound WebSocket ----+---- WebSocket ---+
|
|
69
|
+
|
|
|
70
|
+
ngrok HTTPS tunnel
|
|
71
|
+
|
|
|
72
|
+
local `portal serve` process
|
|
73
|
+
registry | presence | relay
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
Both daemons initiate outbound connections, so the friend does not expose an
|
|
77
|
+
inbound port. Messages remain relayed through the server for this phase. P2P,
|
|
78
|
+
STUN, TURN, and direct connection negotiation add no value to the demo and are
|
|
79
|
+
deferred.
|
|
80
|
+
|
|
81
|
+
The daemon owns remote connections and multiplexes its managed sessions over
|
|
82
|
+
them. Connections are keyed by normalized server URL so sessions may join
|
|
83
|
+
different demo servers without interfering with one another.
|
|
84
|
+
|
|
85
|
+
## Server behavior
|
|
86
|
+
|
|
87
|
+
`portal serve` provides:
|
|
88
|
+
|
|
89
|
+
- `GET /health` for tunnel and operator diagnostics;
|
|
90
|
+
- `WS /ws` for presence, discovery, task events, and acknowledgements;
|
|
91
|
+
- an in-memory connection table;
|
|
92
|
+
- an in-memory live-agent registry with renewable leases; and
|
|
93
|
+
- envelope routing between currently connected clients.
|
|
94
|
+
|
|
95
|
+
Initial protocol operations:
|
|
96
|
+
|
|
97
|
+
```text
|
|
98
|
+
client.hello
|
|
99
|
+
agent.register
|
|
100
|
+
agent.renew
|
|
101
|
+
agent.unregister
|
|
102
|
+
agent.discover
|
|
103
|
+
envelope.send
|
|
104
|
+
envelope.acknowledge
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
An advertised agent record contains only bounded metadata:
|
|
108
|
+
|
|
109
|
+
```json
|
|
110
|
+
{
|
|
111
|
+
"routeId": "route_a81d",
|
|
112
|
+
"sessionId": "ps_56d0",
|
|
113
|
+
"agentName": "leo",
|
|
114
|
+
"provider": "codex",
|
|
115
|
+
"description": "Implementation coding agent",
|
|
116
|
+
"capabilities": ["message", "task"],
|
|
117
|
+
"state": "available",
|
|
118
|
+
"expiresAt": "2026-09-05T20:01:00Z"
|
|
119
|
+
}
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
The server never receives transcripts, absolute filesystem paths, environment
|
|
123
|
+
variables, process details, or historical session inventory. A disconnected
|
|
124
|
+
agent disappears after its presence lease expires. Server restart clears all
|
|
125
|
+
connections and registrations.
|
|
126
|
+
|
|
127
|
+
## Collaboration flow
|
|
128
|
+
|
|
129
|
+
```text
|
|
130
|
+
discover -> offer -> accept/decline -> progress/questions -> complete/fail
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
The initiator uses a non-blocking delegation tool. This is separate from the
|
|
134
|
+
current blocking `portal.send` behavior so the initiating agent can keep
|
|
135
|
+
working while its peer runs.
|
|
136
|
+
|
|
137
|
+
A task has a globally unique ID, sender and target routes, objective, optional
|
|
138
|
+
context and expected result, timestamps, expiry, and a correlated event
|
|
139
|
+
stream. The minimum state machine is:
|
|
140
|
+
|
|
141
|
+
```text
|
|
142
|
+
offered ----> accepted ----> running ----> completed
|
|
143
|
+
| |
|
|
144
|
+
+-------> declined +-------> failed
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
Starting a remote task creates a visible turn in the target Codex session. The
|
|
148
|
+
target calls an MCP action to accept or decline. Acceptance is immediately
|
|
149
|
+
sent back to the initiator; it does not wait for the target turn to finish.
|
|
150
|
+
Progress, questions, and final results are durable in each local Portal
|
|
151
|
+
database and are delivered to a managed session when it is ready for another
|
|
152
|
+
turn. Portal never starts two concurrent turns in the same Codex session.
|
|
153
|
+
|
|
154
|
+
## Trust boundary for the demo
|
|
155
|
+
|
|
156
|
+
There are no accounts, verified identities, signing keys, relationship records,
|
|
157
|
+
or authorization grants. Agent names and installation identifiers are
|
|
158
|
+
self-asserted. The tunnel URL is an ephemeral demo-room address, not a security
|
|
159
|
+
credential.
|
|
160
|
+
|
|
161
|
+
Every remote agent and event must therefore be labeled `unauthenticated` in
|
|
162
|
+
tool results and injected turns. Only sessions explicitly launched with both
|
|
163
|
+
`--agent` and `--server` are remotely advertised. Vendor sandbox and approval
|
|
164
|
+
settings remain unchanged, and Portal never auto-approves a tool action.
|
|
165
|
+
|
|
166
|
+
Anyone who learns the tunnel URL can discover agents, impersonate a name, and
|
|
167
|
+
send task offers. The server must not be used with sensitive sessions or left
|
|
168
|
+
running after the demonstration. These constraints are acceptable only for a
|
|
169
|
+
controlled validation and must block production positioning.
|
|
170
|
+
|
|
171
|
+
## Milestones
|
|
172
|
+
|
|
173
|
+
### M0: Protocol and process contract
|
|
174
|
+
|
|
175
|
+
Status: complete.
|
|
176
|
+
|
|
177
|
+
Define versioned schemas for presence, discovery, envelopes, task events, and
|
|
178
|
+
acknowledgements. Define limits for names, descriptions, message size, task
|
|
179
|
+
expiry, heartbeat interval, and protocol mismatch errors. Add a transport
|
|
180
|
+
interface so the local message service does not depend directly on WebSocket
|
|
181
|
+
implementation details.
|
|
182
|
+
|
|
183
|
+
Checkpoint:
|
|
184
|
+
|
|
185
|
+
- protocol fixtures round-trip through validation;
|
|
186
|
+
- unknown versions and malformed or oversized messages are rejected;
|
|
187
|
+
- a documented compatibility rule determines whether two versions may talk;
|
|
188
|
+
- existing local messaging tests remain unchanged and pass.
|
|
189
|
+
|
|
190
|
+
### M1: Local registry and WebSocket relay
|
|
191
|
+
|
|
192
|
+
Status: complete.
|
|
193
|
+
|
|
194
|
+
Add `portal serve --listen <address>`. Implement the health endpoint,
|
|
195
|
+
WebSocket lifecycle, live presence leases, discovery queries, envelope
|
|
196
|
+
forwarding, and delivery acknowledgements. Keep all network state in memory.
|
|
197
|
+
|
|
198
|
+
Checkpoint:
|
|
199
|
+
|
|
200
|
+
- two test clients connect to the local server;
|
|
201
|
+
- one registers `leo`, the other discovers it;
|
|
202
|
+
- disconnect or missed heartbeats removes `leo` within the lease window;
|
|
203
|
+
- duplicate names return both candidates;
|
|
204
|
+
- an envelope is delivered once and acknowledged;
|
|
205
|
+
- the server binds to `127.0.0.1` by default.
|
|
206
|
+
|
|
207
|
+
### M2: Daemon remote presence and discovery
|
|
208
|
+
|
|
209
|
+
Status: complete for explicitly advertised managed Codex sessions.
|
|
210
|
+
|
|
211
|
+
Teach `portald` to open and reuse connections keyed by server URL. Associate a
|
|
212
|
+
managed session with its selected server, publish it after the real Codex
|
|
213
|
+
session ID is known, renew its lease, and unregister it on exit. Merge remote
|
|
214
|
+
results into a new MCP discovery tool without treating them as local indexed
|
|
215
|
+
sessions.
|
|
216
|
+
|
|
217
|
+
Checkpoint:
|
|
218
|
+
|
|
219
|
+
- two daemons connected to one local server discover each other's advertised
|
|
220
|
+
sessions;
|
|
221
|
+
- unadvertised observed and historical sessions never leave the machine;
|
|
222
|
+
- exact unique names resolve and ambiguous names do not send;
|
|
223
|
+
- tunnel interruption produces a visible unavailable state and reconnects;
|
|
224
|
+
- sessions connected to different server URLs remain isolated.
|
|
225
|
+
|
|
226
|
+
### M3: Remote invitation and visible delivery
|
|
227
|
+
|
|
228
|
+
Status: complete.
|
|
229
|
+
|
|
230
|
+
Route a remote task offer through the server and import it into the target's
|
|
231
|
+
existing managed-runner queue. Represent the sender as an explicit remote,
|
|
232
|
+
unauthenticated peer rather than a locally observed vendor session. Preserve
|
|
233
|
+
event IDs, attribution, correlation, expiry, and idempotency across the relay.
|
|
234
|
+
|
|
235
|
+
Checkpoint:
|
|
236
|
+
|
|
237
|
+
- agent A sends an offer to agent B on another daemon;
|
|
238
|
+
- B receives a visible attributed Codex turn without checking an inbox;
|
|
239
|
+
- replaying an event does not create a second turn;
|
|
240
|
+
- invalid, expired, unknown-target, and disconnected-target deliveries fail
|
|
241
|
+
clearly;
|
|
242
|
+
- the target transcript and MCP result both say the sender is unauthenticated.
|
|
243
|
+
|
|
244
|
+
### M4: Asynchronous task agreement and collaboration
|
|
245
|
+
|
|
246
|
+
Status: complete for managed Codex sessions.
|
|
247
|
+
|
|
248
|
+
Add non-blocking task delegation and task-scoped event tools. Support offer,
|
|
249
|
+
accept, decline, progress, question, completion, and failure. Update managed
|
|
250
|
+
agent instructions so a target explicitly accepts or declines before acting,
|
|
251
|
+
and so results automatically return to the initiating session.
|
|
252
|
+
|
|
253
|
+
Checkpoint:
|
|
254
|
+
|
|
255
|
+
- A delegates to B and continues its own turn without waiting for B;
|
|
256
|
+
- B accepts and A automatically sees the acceptance;
|
|
257
|
+
- both agents execute work concurrently;
|
|
258
|
+
- B sends a question or progress update and receives A's response;
|
|
259
|
+
- B completes and A automatically receives the correlated result;
|
|
260
|
+
- no session receives simultaneous Codex turns;
|
|
261
|
+
- failure and disconnect leave an inspectable terminal or retryable state.
|
|
262
|
+
|
|
263
|
+
### M5: Single-command local UX
|
|
264
|
+
|
|
265
|
+
Status: implemented; clean-tarball validation is complete, publication remains deferred.
|
|
266
|
+
|
|
267
|
+
Make `portal codex` lazily initialize local state and start a compatible
|
|
268
|
+
daemon. Add `--agent` and `--server`, with `--server` taking precedence over an
|
|
269
|
+
environment variable or stored default. Keep `portal run codex` temporarily as
|
|
270
|
+
a compatibility alias. Validate the packaged layout locally without publishing
|
|
271
|
+
it.
|
|
272
|
+
|
|
273
|
+
Checkpoint:
|
|
274
|
+
|
|
275
|
+
- `npm pack` installs and runs in a clean temporary directory;
|
|
276
|
+
- the packed tarball installs and `portal codex --agent leo --server <url>`
|
|
277
|
+
works from a clean temporary environment;
|
|
278
|
+
- a stale daemon is detected through a version handshake and restarted safely;
|
|
279
|
+
- Portal flags are not forwarded to Codex, while arguments after `--` are;
|
|
280
|
+
- exiting Codex unregisters the advertised agent and cleans up its lease.
|
|
281
|
+
|
|
282
|
+
### M6: Two-machine demonstration
|
|
283
|
+
|
|
284
|
+
Status: two isolated local daemons pass; physical two-Mac/tunnel validation remains deferred.
|
|
285
|
+
|
|
286
|
+
First run two isolated Portal daemons and managed-agent fixtures against the
|
|
287
|
+
local server. Once a tunnel provider and package distribution are selected,
|
|
288
|
+
repeat the same protocol flow across two Macs without changing the application
|
|
289
|
+
protocol. Execute a task that requires negotiation, parallel work, at least one
|
|
290
|
+
progress exchange, and a returned result.
|
|
291
|
+
|
|
292
|
+
Checkpoint:
|
|
293
|
+
|
|
294
|
+
- the local two-daemon flow passes before tunnel or npm publication work;
|
|
295
|
+
- later, the friend uses only the supplied single command after installing
|
|
296
|
+
Codex;
|
|
297
|
+
- the initiating agent discovers the friend's agent without a session ID;
|
|
298
|
+
- both users visibly see offer, acceptance, progress, and completion;
|
|
299
|
+
- the agents collaborate without either user relaying text;
|
|
300
|
+
- logs correlate every hop by task and event ID;
|
|
301
|
+
- the demo succeeds twice from a fresh server process.
|
|
302
|
+
|
|
303
|
+
## Execution order
|
|
304
|
+
|
|
305
|
+
M0 is the integration boundary. After it lands, the M1 server and most of the
|
|
306
|
+
M2 daemon connection work can proceed in parallel. M3 joins those paths. M4
|
|
307
|
+
depends on reliable remote delivery, and M5 should package the behavior only
|
|
308
|
+
after the protocol is stable. M6 is the release gate.
|
|
309
|
+
|
|
310
|
+
```text
|
|
311
|
+
M0 ---> M1 ---+
|
|
312
|
+
\ +---> M3 ---> M4 ---> M5 ---> M6
|
|
313
|
+
+---> M2 --+
|
|
314
|
+
```
|
|
315
|
+
|
|
316
|
+
## Reuse from the local MVP
|
|
317
|
+
|
|
318
|
+
- user-only daemon and JSON-RPC control plane;
|
|
319
|
+
- SQLite persistence;
|
|
320
|
+
- Portal-managed Codex app-server and runner;
|
|
321
|
+
- automatic visible-turn delivery;
|
|
322
|
+
- session profiles and ambiguity-safe resolution;
|
|
323
|
+
- MCP injection and session credentials;
|
|
324
|
+
- message IDs, reply correlation, idempotency, rate limits, and receipts; and
|
|
325
|
+
- captured Codex answers and bounded tool-result summaries.
|
|
326
|
+
|
|
327
|
+
The remote path extends these components but does not expose the local RPC
|
|
328
|
+
socket or local session credential to the network.
|
|
329
|
+
|
|
330
|
+
## Not in scope
|
|
331
|
+
|
|
332
|
+
- production authentication, authorization, invitations, blocking, or abuse
|
|
333
|
+
controls;
|
|
334
|
+
- durable public names, accounts, or a production nameserver;
|
|
335
|
+
- offline remote delivery or persistence in the relay;
|
|
336
|
+
- public deployment of the Portal server;
|
|
337
|
+
- npm publication and package-name selection;
|
|
338
|
+
- tunnel-provider selection and tunnel setup automation;
|
|
339
|
+
- end-to-end encryption;
|
|
340
|
+
- peer-to-peer transport, WebRTC, STUN, or TURN;
|
|
341
|
+
- remote transcript recall;
|
|
342
|
+
- automatic artifact synchronization or Git workflows;
|
|
343
|
+
- Claude or unmanaged Codex active delivery;
|
|
344
|
+
- browser, desktop, and Slack sessions;
|
|
345
|
+
- a Portal-owned autonomous supervisor agent; and
|
|
346
|
+
- production availability, scaling, federation, or multi-region operation.
|
package/package.json
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@mquan/portal",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"description": "Local cross-agent session awareness, recall, and messaging",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"bin": {
|
|
7
|
+
"portal": "./dist/src/cli.js",
|
|
8
|
+
"portal-mcp": "./dist/src/mcp.js"
|
|
9
|
+
},
|
|
10
|
+
"files": [
|
|
11
|
+
"dist/src",
|
|
12
|
+
"docs",
|
|
13
|
+
"README.md"
|
|
14
|
+
],
|
|
15
|
+
"engines": {
|
|
16
|
+
"node": ">=22.13"
|
|
17
|
+
},
|
|
18
|
+
"publishConfig": {
|
|
19
|
+
"access": "public",
|
|
20
|
+
"tag": "demo"
|
|
21
|
+
},
|
|
22
|
+
"scripts": {
|
|
23
|
+
"build": "tsc -p tsconfig.json",
|
|
24
|
+
"check": "tsc -p tsconfig.json --noEmit",
|
|
25
|
+
"dev": "node --import tsx src/cli.ts",
|
|
26
|
+
"mcp": "node --import tsx src/mcp.ts",
|
|
27
|
+
"probe:codex": "node --import tsx src/provider/codex/probe.ts",
|
|
28
|
+
"test": "node --import tsx --test test/**/*.test.ts",
|
|
29
|
+
"probe:claude": "PORTAL_REAL_CLAUDE_PROBE=1 node --import tsx --test test/claude-provider.real.test.ts",
|
|
30
|
+
"prepack": "npm run check && npm test && npm run build"
|
|
31
|
+
},
|
|
32
|
+
"dependencies": {
|
|
33
|
+
"@anthropic-ai/claude-agent-sdk": "0.3.251",
|
|
34
|
+
"@modelcontextprotocol/sdk": "1.30.0",
|
|
35
|
+
"ws": "^8.21.3",
|
|
36
|
+
"zod": "4.5.4"
|
|
37
|
+
},
|
|
38
|
+
"devDependencies": {
|
|
39
|
+
"@types/node": "latest",
|
|
40
|
+
"@types/ws": "^8.18.1",
|
|
41
|
+
"tsx": "latest",
|
|
42
|
+
"typescript": "latest"
|
|
43
|
+
},
|
|
44
|
+
"overrides": {
|
|
45
|
+
"qs": "6.16.0"
|
|
46
|
+
}
|
|
47
|
+
}
|