totemlayer 0.1.30 → 0.1.37
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 +57 -260
- package/bin/agent-profile.mjs +10 -1
- package/bin/agent-runner.mjs +26 -1
- package/bin/agent-setup.mjs +5 -1
- package/bin/automatic-runtime.mjs +113 -21
- package/bin/codex-chat-bridge.mjs +259 -67
- package/bin/codex-chat-readiness.mjs +321 -0
- package/bin/connected-agent-service.mjs +2 -2
- package/bin/local-mcp.mjs +42 -6
- package/bin/mcp-approval-review.mjs +156 -0
- package/bin/mcp-identity-binding.mjs +52 -0
- package/bin/mcp-install.mjs +196 -28
- package/bin/mcp-runtime.mjs +169 -0
- package/bin/mcp.mjs +153 -21
- package/bin/network-runtime.mjs +13 -4
- package/bin/runtime-installation.mjs +9 -5
- package/bin/sdk/types.d.ts +32 -0
- package/bin/totem.mjs +2 -2
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -1,306 +1,103 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Totem CLI
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
action-level authorization. The package contains the CLI and local MCP server;
|
|
5
|
-
it does not include the TotemLayer web application or server source.
|
|
3
|
+
Connect your agent to Totem, exchange messages, coordinate approved work, and verify protected actions.
|
|
6
4
|
|
|
7
|
-
##
|
|
5
|
+
## Connect any MCP client
|
|
8
6
|
|
|
9
|
-
|
|
7
|
+
Totem works with any MCP client supporting Streamable HTTP or stdio. Keep your current AI app and model.
|
|
10
8
|
|
|
11
|
-
|
|
12
|
-
npx --yes --package=totemlayer@0.1.30 totem install
|
|
13
|
-
```
|
|
14
|
-
|
|
15
|
-
The installer includes the automatic listener, opens a one-time Totem sign-in, and saves the approved connection privately. Choose your agent in the browser. You do not need to create or copy a connection key or run a separate start command. This explicitly runs Totem setup even when npm dependency install scripts are disabled. The listener is saved in private storage and does not depend on the npx cache. On headless hosts, use `npx --yes --package=totemlayer@0.1.30 totem login --device-login --no-browser` and open its printed connection link on your own device.
|
|
9
|
+
For a hosted connection, add these settings to your client's MCP configuration:
|
|
16
10
|
|
|
17
|
-
|
|
11
|
+
- Name: Totem
|
|
12
|
+
- Server URL: `https://totemlayer.com/mcp`
|
|
13
|
+
- Transport: Streamable HTTP
|
|
14
|
+
- Authentication: OAuth sign-in, or a Bearer Network connection key stored in your client's secret store
|
|
18
15
|
|
|
19
|
-
|
|
16
|
+
The hosted connection needs no local installation. Sign in to Totem, select your agent, and approve the connection.
|
|
20
17
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
The listener runs independently of the terminal, restarts after failure, and resumes after login on macOS, Linux user-service hosts, and Windows. On headless hosts without a service manager, it starts a background supervisor. A destroyed host still needs persistent private storage or its environment's secret provisioning; an installed listener cannot keep a destroyed host alive.
|
|
24
|
-
|
|
25
|
-
If an executor fails, Totem keeps a redacted error privately on that computer. Retrieve it with `npx --yes --package=totemlayer@0.1.30 totem diagnose --json`; no separate diagnostic download is needed. If no error has been saved yet, Windows runs the check through the installed task account. `--fresh` requests a new check, and `--profile YOUR_AGENT_UUID` selects a connection when more than one is installed. The diagnostic does not clear recovery journals or restart the existing listener.
|
|
18
|
+
For a local stdio connection, install the CLI with Node.js 22.14 or newer:
|
|
26
19
|
|
|
27
20
|
```sh
|
|
28
|
-
|
|
29
|
-
npx --yes --package=totemlayer@0.1.30 totem stop --profile YOUR_AGENT_UUID
|
|
30
|
-
npx --yes --package=totemlayer@0.1.30 totem start --profile YOUR_AGENT_UUID --background
|
|
21
|
+
npm install --global --ignore-scripts https://totemlayer.com/downloads/totemlayer-0.1.37.tgz
|
|
31
22
|
```
|
|
32
23
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
For custom executors, set `TOTEM_PROVIDER=command` with `TOTEM_AGENT_COMMAND` and JSON `TOTEM_AGENT_COMMAND_ARGS`, or `TOTEM_PROVIDER=http` with `TOTEM_AGENT_URL` and optional `TOTEM_AGENT_TOKEN_ENV`, before installing or running `npx --yes --package=totemlayer@0.1.30 totem login`. Provider credentials remain separate from Totem credentials. Local model selection can be pinned with `TOTEM_MODEL`.
|
|
36
|
-
|
|
37
|
-
The background service preserves custom `CODEX_HOME` and `CLAUDE_CONFIG_DIR` paths and saved proxy settings across upgrades. An explicitly empty environment setting clears its saved value.
|
|
38
|
-
|
|
39
|
-
Content screening uses local rules by default. To add your own local AI classifier, set both `TOTEM_INSPECTOR_URL` (a numeric loopback `/chat/completions` endpoint) and `TOTEM_INSPECTOR_MODEL` before installation. These settings persist in the background service; unavailable or malformed classifier responses block processing. Screening does not grant permission for an action, and no filter guarantees detection of every malicious instruction.
|
|
40
|
-
|
|
41
|
-
Advanced setup still accepts a private `--key-file`, explicit provider and repository roots. It saves the connection, starts supervised execution, and installs managed MCP for Codex/Claude by default. `--no-start` and `--no-mcp` provide explicit opt-outs. Existing configuration changes require `--replace` where appropriate. Restart your AI app and call `totem_get_identity` to verify MCP; actual worker state is reported separately by `npx --yes --package=totemlayer@0.1.30 totem status`.
|
|
42
|
-
|
|
43
|
-
The package contains the CLI, local MCP server, and provider-independent worker. It does not distribute the private web application. Other languages can use the [HTTPS API](https://totemlayer.com/api/v1/openapi.json). The included TotemLayer CLI Use License permits unmodified use with TotemLayer-compatible services.
|
|
44
|
-
|
|
45
|
-
## Activity and approval notifications
|
|
24
|
+
Save your agent's connection key in a private file. Protect it with mode 0600 on macOS/Linux or your user's filesystem ACL on Windows. Configure these fields in your client's MCP settings:
|
|
46
25
|
|
|
47
|
-
|
|
26
|
+
- Command: `totem` (use its absolute executable path if needed)
|
|
27
|
+
- Arguments: `mcp`
|
|
28
|
+
- Environment: `TOTEM_BASE_URL=https://totemlayer.com`
|
|
29
|
+
- Environment: `TOTEM_NETWORK_API_KEY_FILE=/absolute/path/to/your-agent.key`
|
|
48
30
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
## Before the first production request
|
|
52
|
-
|
|
53
|
-
Each participating company completes its one-time setup at
|
|
54
|
-
[totemlayer.com](https://totemlayer.com):
|
|
55
|
-
|
|
56
|
-
1. Verify the organization and establish an accepted company relationship.
|
|
57
|
-
2. Register the presenting and receiving agents.
|
|
58
|
-
3. Issue a live, recipient-bound credential for the permitted action.
|
|
59
|
-
4. In **Developer Settings**, create a `credential.verify` key bound to the
|
|
60
|
-
receiving agent and a separate `credential.present` key bound to the
|
|
61
|
-
presenting agent.
|
|
62
|
-
5. Copy each raw key when it is shown and store it in that company's secret
|
|
63
|
-
manager. TotemLayer does not display the raw key again.
|
|
64
|
-
|
|
65
|
-
Never place keys, nonces, credentials, or presentation tokens in command-line
|
|
66
|
-
arguments. The CLI reads keys from environment variables and reads proof
|
|
67
|
-
artifacts from files or standard input.
|
|
68
|
-
|
|
69
|
-
## Production handshake
|
|
70
|
-
|
|
71
|
-
Assume `request.json` contains the exact business request that the receiving
|
|
72
|
-
company may process.
|
|
73
|
-
|
|
74
|
-
Receiver — create a five-minute challenge:
|
|
75
|
-
|
|
76
|
-
```bash
|
|
77
|
-
export TOTEM_URL="https://totemlayer.com"
|
|
78
|
-
export TOTEM_API_KEY="$VERIFIER_KEY"
|
|
79
|
-
|
|
80
|
-
npx --yes --package=totemlayer@0.1.30 totem challenge \
|
|
81
|
-
--presenter-agent "$PRESENTER_AGENT_ID" \
|
|
82
|
-
--action quote.request \
|
|
83
|
-
--request-file request.json \
|
|
84
|
-
--idempotency-key verify-request-001 \
|
|
85
|
-
--json > challenge.json
|
|
86
|
-
```
|
|
31
|
+
Use the actual private key-file path on that host. Keep the CLI installed. Run `totem mcp install generic --key-file /absolute/path/to/your-agent.key` for a JSON example that leaves existing client settings untouched. Adapt the configuration wrapper to your client's schema.
|
|
87
32
|
|
|
88
|
-
|
|
89
|
-
presenting workload over the companies' existing authenticated business
|
|
90
|
-
channel. Do not replace the original with a file returned by the presenter.
|
|
33
|
+
Reload the client if needed, discover the available tools, and call `totem_get_identity`. Check the agent address, organization, and environment before reporting a successful connection.
|
|
91
34
|
|
|
92
|
-
|
|
35
|
+
## Automatic listener setup
|
|
93
36
|
|
|
94
|
-
|
|
95
|
-
export TOTEM_AGENT_API_KEY="$PRESENTER_KEY"
|
|
37
|
+
Run the guided installer on the host where your agent will execute work:
|
|
96
38
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
--challenge-file challenge.json \
|
|
100
|
-
--json > presentation.json
|
|
39
|
+
```sh
|
|
40
|
+
npx --yes --package=https://totemlayer.com/downloads/totemlayer-0.1.37.tgz totem install
|
|
101
41
|
```
|
|
102
42
|
|
|
103
|
-
|
|
43
|
+
The installer opens Totem sign-in and saves the approved connection privately. It checks your configured agent runtime, configures supported clients, and starts the listener when an authorized executor is available. The supervised listener is enabled by default for this setup and starts when you sign in to the computer on hosts with a supported user service manager. It recovers after a process exit and retries temporary connection failures. An explicit stop stays paused across restarts.
|
|
104
44
|
|
|
105
|
-
|
|
106
|
-
export TOTEM_API_KEY="$VERIFIER_KEY"
|
|
45
|
+
For manual setup, use `totem mcp install` with a supported client and the private key file; see `totem mcp install --help` for client-specific options. Where existing-chat delivery is supported, select the actual chat explicitly; no other chat is inferred from a shared identity. `--no-start` keeps that MCP entry tools-only across reconnects. Generic configuration examples and hosted HTTP connections cannot install a listener on a remote computer.
|
|
107
46
|
|
|
108
|
-
|
|
109
|
-
--challenge-file challenge.json \
|
|
110
|
-
--presentation-file presentation.json \
|
|
111
|
-
--request-file request.json \
|
|
112
|
-
--json
|
|
113
|
-
```
|
|
47
|
+
For a host without a browser:
|
|
114
48
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
the server response—that would defeat the independent check. Act on the same
|
|
118
|
-
immutable bytes, or hash them again immediately before taking the business
|
|
119
|
-
action, because an approval never authorizes different bytes.
|
|
120
|
-
The CLI rejects a local challenge/request mismatch before consuming the proof.
|
|
121
|
-
If returned approval evidence later fails its complete binding check, treat the
|
|
122
|
-
proof as consumed and create a new challenge and presentation.
|
|
123
|
-
|
|
124
|
-
An application may use `--request-digest <sha256>` instead of
|
|
125
|
-
`--request-file` when it computes that digest from receiver-owned immutable
|
|
126
|
-
bytes. Never take the expected digest from a presenter or from TotemLayer's
|
|
127
|
-
approval response.
|
|
128
|
-
|
|
129
|
-
### Windows PowerShell
|
|
130
|
-
|
|
131
|
-
PowerShell uses a backtick for line continuation. `Set-Content -Encoding UTF8`
|
|
132
|
-
also avoids the shell-dependent native redirection encoding used by Windows
|
|
133
|
-
PowerShell 5.1. The CLI accepts both UTF-8 BOM and UTF-16LE BOM artifacts for
|
|
134
|
-
compatibility.
|
|
135
|
-
|
|
136
|
-
```powershell
|
|
137
|
-
$env:TOTEM_URL = "https://totemlayer.com"
|
|
138
|
-
$env:TOTEM_API_KEY = $env:VERIFIER_KEY
|
|
139
|
-
|
|
140
|
-
npx --yes --package=totemlayer@0.1.30 totem challenge `
|
|
141
|
-
--presenter-agent $env:PRESENTER_AGENT_ID `
|
|
142
|
-
--action quote.request `
|
|
143
|
-
--request-file request.json `
|
|
144
|
-
--idempotency-key verify-request-001 `
|
|
145
|
-
--json | Set-Content -Encoding UTF8 challenge.json
|
|
146
|
-
|
|
147
|
-
$env:TOTEM_AGENT_API_KEY = $env:PRESENTER_KEY
|
|
148
|
-
|
|
149
|
-
npx --yes --package=totemlayer@0.1.30 totem present `
|
|
150
|
-
--credential-id $env:CREDENTIAL_ID `
|
|
151
|
-
--challenge-file challenge.json `
|
|
152
|
-
--json | Set-Content -Encoding UTF8 presentation.json
|
|
153
|
-
|
|
154
|
-
$env:TOTEM_API_KEY = $env:VERIFIER_KEY
|
|
155
|
-
|
|
156
|
-
npx --yes --package=totemlayer@0.1.30 totem verify `
|
|
157
|
-
--challenge-file challenge.json `
|
|
158
|
-
--presentation-file presentation.json `
|
|
159
|
-
--request-file request.json `
|
|
160
|
-
--json
|
|
49
|
+
```sh
|
|
50
|
+
npx --yes --package=https://totemlayer.com/downloads/totemlayer-0.1.37.tgz totem login --device-login --no-browser
|
|
161
51
|
```
|
|
162
52
|
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
- `0` — approved or the requested operation completed.
|
|
166
|
-
- `2` — server policy rejection, expiration, or replay.
|
|
167
|
-
- `1` — invalid input or local binding, network failure, or protocol/operational error.
|
|
168
|
-
|
|
169
|
-
## Procurement sandbox
|
|
170
|
-
|
|
171
|
-
`npx --yes --package=totemlayer@0.1.30 totem rfq` is a sandbox and self-hosted demonstration command. It is not
|
|
172
|
-
enabled on the production `totemlayer.com` service. Point `TOTEM_URL` at a
|
|
173
|
-
TotemLayer deployment with the procurement demo enabled and use an
|
|
174
|
-
`operator.rfq.execute` key.
|
|
175
|
-
|
|
176
|
-
## Compatibility
|
|
177
|
-
|
|
178
|
-
The package also installs the legacy `agenttrust` executable and accepts the
|
|
179
|
-
legacy `AGENTTRUST_*` environment-variable aliases. New integrations should use
|
|
180
|
-
`totem` and `TOTEM_*`.
|
|
181
|
-
|
|
182
|
-
## Agent messaging and code collaboration
|
|
183
|
-
|
|
184
|
-
The local build includes `npx --yes --package=totemlayer@0.1.30 totem network` and the Totem MCP server. Run
|
|
185
|
-
`npx --yes --package=totemlayer@0.1.30 totem network --help` for the full command list. Two owners can each connect
|
|
186
|
-
their own Codex or Claude client to Totem MCP and opt into `npx --yes --package=totemlayer@0.1.30 totem network work`
|
|
187
|
-
for one exact peer and one Git checkout. Then one chat request can create a
|
|
188
|
-
shared coding task; the listeners pick up the peer's work and later replies in
|
|
189
|
-
each owner's own AI account. They do not share model or GitHub credentials.
|
|
190
|
-
|
|
191
|
-
The listener runs a separate local CLI session; it does not wake or reuse a
|
|
192
|
-
closed desktop chat. Both owners must give their own Git account access to the
|
|
193
|
-
repository and keep their local listener running. Run `npx --yes --package=totemlayer@0.1.30 totem network --help`
|
|
194
|
-
for setup requirements and security boundaries.
|
|
53
|
+
Open the printed link on your own device and compare the connection code. Preserve existing MCP entries; inspect conflicts before replacing them. If an executor is unavailable, the saved connection remains available while you complete runtime setup.
|
|
195
54
|
|
|
196
|
-
##
|
|
55
|
+
## Check or pause your listener
|
|
197
56
|
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
After installing the CLI and saving your own agent key in a
|
|
201
|
-
private file, let Totem add the local MCP connection to Codex or Claude Code:
|
|
57
|
+
After a global installation:
|
|
202
58
|
|
|
203
59
|
```sh
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
```
|
|
209
|
-
|
|
210
|
-
The installer checks the file permissions, configures a user-level `totem-local`
|
|
211
|
-
stdio server using the installed CLI, and refuses to overwrite an existing MCP
|
|
212
|
-
entry. It passes the **file path**, never the key value, to the AI client.
|
|
213
|
-
Restart the AI app and ask it to call `totem_get_identity`. The CLI package must
|
|
214
|
-
remain installed for the MCP connection to run. On macOS/Linux the key file
|
|
215
|
-
must not be readable by other users (`chmod 600` works). Run
|
|
216
|
-
`npx --yes --package=totemlayer@0.1.30 totem mcp install --help` for options, including a custom server name.
|
|
217
|
-
|
|
218
|
-
The installer is included from 0.1.3 onward. Version 0.1.4 supports native
|
|
219
|
-
Windows MCP setup and on-device approval on Windows and Linux as well as macOS.
|
|
220
|
-
This one-time MCP connection does not itself enable automatic task handoff. In a
|
|
221
|
-
clean clone, ask the AI app to call `totem_preview_local_collaboration`, check
|
|
222
|
-
the exact peer/repository/base commit, then call owner-approved
|
|
223
|
-
`totem_enable_local_collaboration`. On Linux, the desktop approval uses
|
|
224
|
-
`zenity` or `kdialog`; headless sessions still use the explicit
|
|
225
|
-
`npx --yes --package=totemlayer@0.1.30 totem network work` listener. Each owner can check or stop the listener from
|
|
226
|
-
the same chat. On Windows, run both Codex and Totem in the same environment
|
|
227
|
-
(native Windows or WSL2); the native approval dialog is for Windows desktop
|
|
228
|
-
sessions. A Windows key file must be protected by its owner's filesystem ACL.
|
|
229
|
-
|
|
230
|
-
### Hosted MCP and manual configuration
|
|
231
|
-
|
|
232
|
-
The hosted MCP endpoint requires no CLI installation. Create an agent connection key, save it as
|
|
233
|
-
`TOTEM_NETWORK_API_KEY` in the AI application's environment, and connect to:
|
|
234
|
-
|
|
235
|
-
```text
|
|
236
|
-
https://totemlayer.com/mcp
|
|
60
|
+
totem status --profile YOUR_AGENT_UUID
|
|
61
|
+
totem stop --profile YOUR_AGENT_UUID
|
|
62
|
+
totem start --profile YOUR_AGENT_UUID --background
|
|
63
|
+
totem diagnose --json
|
|
237
64
|
```
|
|
238
65
|
|
|
239
|
-
|
|
66
|
+
Check the observed receive, wake, and reply results. Stop pauses automatic processing until you start it again. The host must stay awake and online. Upgrades retain saved connections and recovery records. Hosted Context processing is temporarily paused.
|
|
240
67
|
|
|
241
|
-
|
|
242
|
-
codex mcp add totem --url https://totemlayer.com/mcp \
|
|
243
|
-
--bearer-token-env-var TOTEM_NETWORK_API_KEY
|
|
244
|
-
```
|
|
68
|
+
Connection acceptance and action execution have separate limits. An informed **Accept & start listener** action can enable text replies for that connection; it does not grant access to files, Missions, or arbitrary tools. An explicitly authorized general runtime can process the work its owner permits. Coding work also needs a tool-enabled agent session and approved repository access.
|
|
245
69
|
|
|
246
|
-
|
|
247
|
-
agent-scoped credential to discover agents, exchange durable messages, read conversations,
|
|
248
|
-
acknowledge work, and manage tasks:
|
|
70
|
+
Each owner chooses **Ask me** or **Full access** in Totem Permissions. Connection restrictions and exact, single-use dispatch checks still apply. Reading a message or notification grants no execution permission.
|
|
249
71
|
|
|
250
|
-
|
|
251
|
-
export TOTEM_BASE_URL=http://localhost:3413
|
|
252
|
-
export TOTEM_NETWORK_API_KEY_FILE="$HOME/.totem-agent-key"
|
|
253
|
-
npx --yes --package=totemlayer@0.1.30 totem mcp
|
|
254
|
-
```
|
|
72
|
+
## Messages and work
|
|
255
73
|
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
```json
|
|
259
|
-
{
|
|
260
|
-
"mcpServers": {
|
|
261
|
-
"totem": {
|
|
262
|
-
"command": "npx",
|
|
263
|
-
"args": ["--yes", "--package=totemlayer@0.1.30", "totem", "mcp"],
|
|
264
|
-
"env": {
|
|
265
|
-
"TOTEM_BASE_URL": "http://localhost:3413",
|
|
266
|
-
"TOTEM_NETWORK_API_KEY_FILE": "/absolute/path/to/private-agent.key"
|
|
267
|
-
}
|
|
268
|
-
}
|
|
269
|
-
}
|
|
270
|
-
}
|
|
271
|
-
```
|
|
74
|
+
Use `totem_get_activity` to read messages, approval decisions, and work updates. Keep the activity and message cursors separately, and use `totem_wait_for_activity` while your agent is active. Inspect full conversations and task details before acting. Messages wait in Totem when an agent is offline; a saved assignment or delivery receipt does not prove that work ran. Task details now report saved retries, stopped delivery, and missing listener setup. An existing-chat listener can continue substantive replies for a current, authorized unfinished task. It rechecks task participants and state before sending, uses a stable reply key on retries, and stops task continuation after a terminal state. Acknowledgements alone do not trigger reply loops.
|
|
272
75
|
|
|
273
|
-
|
|
274
|
-
`0600`. Sender identity always comes from this key. MCP tool input cannot override it. The server
|
|
275
|
-
uses stdio and writes protocol messages only to stdout; operational errors go to stderr.
|
|
76
|
+
Local and hosted MCP tool arguments may contain at most 10,000 combined object members and array entries, including nested values. Larger inputs are rejected before the tool runs. Existing text, attachment, and request-size limits still apply.
|
|
276
77
|
|
|
277
|
-
|
|
278
|
-
export TOTEM_BASE_URL=http://localhost:3413
|
|
279
|
-
export TOTEM_NETWORK_API_KEY_FILE="$HOME/.totem-agent-key" # chmod 600 this file
|
|
280
|
-
npx --yes --package=totemlayer@0.1.30 totem network me --json
|
|
281
|
-
npx --yes --package=totemlayer@0.1.30 totem network run --provider qwen-local --qwen-url http://127.0.0.1:8087/v1 --model qwen3.5-9b
|
|
282
|
-
```
|
|
78
|
+
For pending incoming requests, these tools ask compatible MCP clients to display a native owner-review notification. The notification opens the authenticated receiving-owner review in Totem. Accepting the notification never approves an action; the owner must inspect and approve or deny the exact request. Full access requests that are already approved do not prompt. Clients without MCP elicitation support receive the same logs and an owner-review link.
|
|
283
79
|
|
|
284
|
-
|
|
80
|
+
A hosted HTTP MCP connection needs an active harness turn to read activity; it cannot install a service on the laptop. Supported local client installers also prepare the identity-bound listener by default. Reconnecting local MCP repairs an existing enabled listener, but never changes a saved chat binding, credentials or owner pause. On hosts that support existing-chat delivery, that chat needs an explicitly bound listener profile. Its readiness check queues a bounded challenge and requires a callback from that exact chat using its existing tools and identity. A queued message or app-opening request alone never reports readiness. Closed-app behavior must be verified on the receiving host; an unavailable callback leaves the listener blocked. The host must remain awake and online.
|
|
285
81
|
|
|
286
|
-
|
|
82
|
+
Follow the owner's instructions before sending messages, sharing code, or delegating Missions. For collaboration, agree on the repository, base commit, separate branches, file scopes, and acceptance criteria. Report the resulting commit and validation evidence.
|
|
287
83
|
|
|
288
|
-
|
|
289
|
-
`prepack`. The MCP server uses the declared Model Context Protocol and Zod runtime dependencies;
|
|
290
|
-
installation automatically configures the listener; use `TOTEM_AUTO_START=0` for CI. See
|
|
291
|
-
`docs/network/agent-runtime.md` in the source repository for the full adoption guide and local
|
|
292
|
-
package installation steps.
|
|
84
|
+
If a peer lacks a tool or a session with file/build access, use `totem_request_tool_setup` with the exact tool, required capabilities, and reason. Package requests also need a fixed version and vendor or registry URL. The request follows the receiving owner's permission mode and appears in their approval activity. It does not install software, enable terminal access, replace credentials, or prove that a host can run the work. Keep the task blocked until the receiving agent verifies its tools and reports the result. A peer cannot expand another owner's host permissions.
|
|
293
85
|
|
|
294
|
-
|
|
86
|
+
Guided connections bind the intended agent and environment into MCP settings. The server checks the key's actual identity before tools and resource reads. Existing unbound or conflicting entries are preserved for an exact-entry repair. For manual stdio configuration, set `TOTEM_EXPECTED_AGENT_ID` and `TOTEM_EXPECTED_ENVIRONMENT`, or pass `--agent-id` and `--environment` to `totem mcp install`.
|
|
295
87
|
|
|
296
|
-
|
|
88
|
+
## Protected actions
|
|
297
89
|
|
|
298
|
-
|
|
90
|
+
Use `totem --help`, `totem challenge --help`, `totem present --help`, and `totem verify --help` for command details. Protected actions use separate receiver and presenter credentials with the required scopes. Bind verification to the exact request before execution, and inspect uncertain outcomes before retrying.
|
|
299
91
|
|
|
300
|
-
|
|
92
|
+
Keep keys, nonces, credentials, and presentation tokens out of chat, URLs, source control, logs, and command-line arguments. Supply secrets through private files or environment settings. Share only redacted diagnostics with support.
|
|
301
93
|
|
|
302
|
-
|
|
94
|
+
## Guides
|
|
303
95
|
|
|
304
|
-
|
|
96
|
+
- [Totem setup](https://totemlayer.com/setup.md)
|
|
97
|
+
- [MCP connection guide](https://totemlayer.com/docs/mcp)
|
|
98
|
+
- [Send your first message](https://totemlayer.com/docs/quickstart)
|
|
99
|
+
- [Totem CLI](https://totemlayer.com/docs/sdk)
|
|
100
|
+
- [Action authorization](https://totemlayer.com/docs/authentication)
|
|
101
|
+
- [Security controls and limits](https://totemlayer.com/docs/security)
|
|
305
102
|
|
|
306
|
-
|
|
103
|
+
The included Totem CLI Use License permits unmodified use with Totem-compatible services.
|
package/bin/agent-profile.mjs
CHANGED
|
@@ -7,6 +7,7 @@ import { dirname, isAbsolute, join, parse, resolve, sep } from "node:path";
|
|
|
7
7
|
import { localModelEndpoint } from "./local-model-provider.mjs";
|
|
8
8
|
import { isExternalModelProvider, validateModelAdapter } from "./model-adapter.mjs";
|
|
9
9
|
import { repositoryIdFromRemote } from "./repository.mjs";
|
|
10
|
+
import { privateWrite } from "./runtime-installation.mjs";
|
|
10
11
|
|
|
11
12
|
const UUID = /^[a-f0-9]{8}(?:-[a-f0-9]{4}){3}-[a-f0-9]{12}$/;
|
|
12
13
|
const KEY = /^tn_(test|live)_[A-Za-z0-9_-]{43}$/;
|
|
@@ -413,6 +414,7 @@ export async function saveAgentProfile(profileName = "default", input, credentia
|
|
|
413
414
|
const settings = await normalizedSettings(input, directory);
|
|
414
415
|
credentialValue(credential, settings.environment);
|
|
415
416
|
if (options.replace !== undefined && typeof options.replace !== "boolean") fail();
|
|
417
|
+
if (options.automatic !== undefined && options.automatic !== false) fail();
|
|
416
418
|
await directories(directory, privateRoot, true);
|
|
417
419
|
lockPath = join(directory, "profile.lock");
|
|
418
420
|
try {
|
|
@@ -442,7 +444,11 @@ export async function saveAgentProfile(profileName = "default", input, credentia
|
|
|
442
444
|
const unchanged =
|
|
443
445
|
JSON.stringify(existing.settings) === JSON.stringify(settings) &&
|
|
444
446
|
(await readAgentCredential(existing.profile)) === credential;
|
|
445
|
-
if (unchanged)
|
|
447
|
+
if (unchanged) {
|
|
448
|
+
if (options.automatic === false)
|
|
449
|
+
await privateWrite(join(settings.stateDirectory, "automatic.json"), { enabled: false });
|
|
450
|
+
return existing.profile;
|
|
451
|
+
}
|
|
446
452
|
if (!options.replace) fail("AGENT_PROFILE_EXISTS");
|
|
447
453
|
// Shared with initial runner registration. Never orphan a live old identity or
|
|
448
454
|
// silently change local repository permissions underneath an active session.
|
|
@@ -479,6 +485,9 @@ export async function saveAgentProfile(profileName = "default", input, credentia
|
|
|
479
485
|
if (error.code !== "ENOENT") throw error;
|
|
480
486
|
}
|
|
481
487
|
}
|
|
488
|
+
// Publish explicit opt-out before the manifest becomes visible to the supervisor.
|
|
489
|
+
if (options.automatic === false)
|
|
490
|
+
await privateWrite(join(settings.stateDirectory, "automatic.json"), { enabled: false });
|
|
482
491
|
// The manifest is the only commit point. Previous private key generations are retained.
|
|
483
492
|
await rename(temporary, join(directory, "profile.json"));
|
|
484
493
|
temporary = undefined;
|
package/bin/agent-runner.mjs
CHANGED
|
@@ -226,12 +226,20 @@ export async function readAgentRuntimeStatus(profile, { isAlive = alive, now = D
|
|
|
226
226
|
const fresh = now() - Date.parse(record.updatedAt) <= 30_000;
|
|
227
227
|
return {
|
|
228
228
|
running: Boolean(running),
|
|
229
|
-
|
|
229
|
+
receiveWakeReplyVerified: Boolean(
|
|
230
230
|
running &&
|
|
231
231
|
fresh &&
|
|
232
232
|
record.ready === true &&
|
|
233
233
|
!["reconnecting", "starting", "failed", "stopped"].includes(record.phase),
|
|
234
234
|
),
|
|
235
|
+
executorMode: profile.codexThreadId ? "existing_owner_chat" : "configured_adapter",
|
|
236
|
+
hostToolsVerified: false,
|
|
237
|
+
ready: Boolean(
|
|
238
|
+
running &&
|
|
239
|
+
fresh &&
|
|
240
|
+
record.ready === true &&
|
|
241
|
+
!["blocked", "reconnecting", "starting", "failed", "stopped"].includes(record.phase),
|
|
242
|
+
),
|
|
235
243
|
phase: running
|
|
236
244
|
? fresh
|
|
237
245
|
? record.phase
|
|
@@ -573,6 +581,23 @@ export async function agentStartMain(args, options = {}) {
|
|
|
573
581
|
setTimeout(resolve, Math.min(250, Math.max(1, deadline - Date.now()))),
|
|
574
582
|
);
|
|
575
583
|
const state = await readAgentRuntimeStatus(profile);
|
|
584
|
+
if (
|
|
585
|
+
profile.provider === "codex" &&
|
|
586
|
+
UUID.test(profile.codexThreadId ?? "") &&
|
|
587
|
+
state.running &&
|
|
588
|
+
state.phase === "starting"
|
|
589
|
+
) {
|
|
590
|
+
// The selected chat must receive and answer the probe itself. Waiting
|
|
591
|
+
// here can occupy that very chat until the shorter startup timer stops
|
|
592
|
+
// the listener. Leave its bounded readiness check running instead.
|
|
593
|
+
report({
|
|
594
|
+
...state,
|
|
595
|
+
ready: false,
|
|
596
|
+
message:
|
|
597
|
+
"Listener started. Waiting for the selected chat to confirm readiness. Use totem status to check the result.",
|
|
598
|
+
});
|
|
599
|
+
return 0;
|
|
600
|
+
}
|
|
576
601
|
if (state.running && ["connected", "working", "waiting", "blocked"].includes(state.phase)) {
|
|
577
602
|
report({
|
|
578
603
|
...state,
|
package/bin/agent-setup.mjs
CHANGED
|
@@ -464,7 +464,11 @@ export async function agentSetupMain(args, options = {}) {
|
|
|
464
464
|
...(codexThreadId === undefined ? {} : { codexThreadId }),
|
|
465
465
|
},
|
|
466
466
|
key,
|
|
467
|
-
{
|
|
467
|
+
{
|
|
468
|
+
environment: io.env,
|
|
469
|
+
replace: flags.replace === true,
|
|
470
|
+
...(flags["no-start"] ? { automatic: false } : {}),
|
|
471
|
+
},
|
|
468
472
|
);
|
|
469
473
|
} catch (error) {
|
|
470
474
|
if (error?.code === "AGENT_PROFILE_RUNNING")
|