totemlayer 0.1.11 → 0.1.13

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 CHANGED
@@ -9,7 +9,7 @@ it does not include the TotemLayer web application or server source.
9
9
  Node.js 22.14 or newer is required. Install the current release:
10
10
 
11
11
  ```sh
12
- npm install --global --foreground-scripts https://totemlayer.com/downloads/totemlayer-0.1.11.tgz
12
+ npm install --global --foreground-scripts https://totemlayer.com/downloads/totemlayer-0.1.12.tgz
13
13
  ```
14
14
 
15
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. If installation scripts were disabled, run `totem login` once. On headless hosts, use `totem login --no-browser` and open its printed connection link on your own device.
@@ -529,20 +529,18 @@ export async function agentStartMain(args, options = {}) {
529
529
  await new Promise((resolve) =>
530
530
  setTimeout(resolve, Math.min(250, Math.max(1, deadline - Date.now()))),
531
531
  );
532
- if (failed) break;
533
532
  const state = await readAgentRuntimeStatus(profile);
534
- if (
535
- state.runId === runId &&
536
- state.running &&
537
- ["connected", "working", "waiting", "blocked"].includes(state.phase)
538
- ) {
533
+ if (state.running && ["connected", "working", "waiting", "blocked"].includes(state.phase)) {
539
534
  report({
540
535
  ...state,
541
536
  message:
542
- "Agent started in the background. Use totem status to check its connection and work.",
537
+ state.runId === runId
538
+ ? "Agent started in the background. Use totem status to check its connection and work."
539
+ : "This agent is already running.",
543
540
  });
544
541
  return 0;
545
542
  }
543
+ if (failed) break;
546
544
  if (state.runId === runId && ["failed", "stopped", "interrupted"].includes(state.phase))
547
545
  break;
548
546
  }
@@ -13,6 +13,12 @@ const INHERITED_ENVIRONMENT = new Set(
13
13
  "OPENAI_API_KEY",
14
14
  "ANTHROPIC_API_KEY",
15
15
  "CLAUDE_CODE_OAUTH_TOKEN",
16
+ "HTTP_PROXY",
17
+ "HTTPS_PROXY",
18
+ "ALL_PROXY",
19
+ "NO_PROXY",
20
+ "NODE_USE_ENV_PROXY",
21
+ "NODE_EXTRA_CA_CERTS",
16
22
  "XDG_CONFIG_HOME",
17
23
  "XDG_DATA_HOME",
18
24
  "XDG_RUNTIME_DIR",
@@ -132,8 +132,42 @@ export async function ensureInstalledRuntime(env = process.env) {
132
132
  }
133
133
  const cli = join(runtime, "totem.mjs");
134
134
  const supervisor = join(runtime, "supervisor.mjs");
135
- const launcher = (target) =>
136
- `import{readFile,lstat}from'node:fs/promises';import{join,dirname}from'node:path';import{fileURLToPath,pathToFileURL}from'node:url';const root=dirname(fileURLToPath(import.meta.url));const file=join(root,'current.json');const info=await lstat(file);if(info.isSymbolicLink()||(process.getuid&&info.uid!==process.getuid())||(process.platform!=='win32'&&(info.mode&511)!==384))throw Error('Unsafe runtime installation');process.env.TOTEM_CONFIG_DIR=join(root,'..');const{version}=JSON.parse(await readFile(file,'utf8'));if(!/^\\d+\\.\\d+\\.\\d+$/.test(version))throw Error('Invalid runtime version');await import(pathToFileURL(join(root,'..','runtime-packages',version,'node_modules','totemlayer','bin','${target}')));`;
135
+ const launcher = (target) => `
136
+ import { readFile, lstat } from 'node:fs/promises';
137
+ import { join, dirname } from 'node:path';
138
+ import { fileURLToPath, pathToFileURL } from 'node:url';
139
+ import { spawn } from 'node:child_process';
140
+ const entry = fileURLToPath(import.meta.url);
141
+ const root = dirname(entry);
142
+ const file = join(root, 'current.json');
143
+ const info = await lstat(file);
144
+ if (info.isSymbolicLink() || (process.getuid && info.uid !== process.getuid()) || (process.platform !== 'win32' && (info.mode & 511) !== 384)) throw Error('Unsafe runtime installation');
145
+ const { version } = JSON.parse(await readFile(file, 'utf8'));
146
+ if (!/^\\d+\\.\\d+\\.\\d+$/.test(version)) throw Error('Invalid runtime version');
147
+ const modulePath = join(root, '..', 'runtime-packages', version, 'node_modules', 'totemlayer', 'bin', '${target}');
148
+ if (process.env.TOTEM_RUNTIME_ENV_LOADED === entry) {
149
+ delete process.env.TOTEM_RUNTIME_ENV_LOADED;
150
+ process.env.TOTEM_CONFIG_DIR = join(root, '..');
151
+ await import(pathToFileURL(modulePath));
152
+ } else {
153
+ const { privateRead } = await import(pathToFileURL(join(modulePath, '..', 'runtime-installation.mjs')));
154
+ let environment = { ...process.env };
155
+ for (const name of ['environment.json', 'provider-environment.json']) {
156
+ try { environment = { ...environment, ...await privateRead(join(root, name)) }; }
157
+ catch (error) { if (error.code !== 'ENOENT') throw error; }
158
+ }
159
+ // Node reads proxy opt-in and extra CA configuration at process startup.
160
+ const child = spawn(process.execPath, [entry, ...process.argv.slice(2)], {
161
+ env: { ...environment, TOTEM_CONFIG_DIR: join(root, '..'), TOTEM_RUNTIME_ENV_LOADED: entry },
162
+ stdio: 'inherit',
163
+ });
164
+ for (const signal of ['SIGTERM', 'SIGINT']) process.once(signal, () => child.kill(signal));
165
+ await new Promise((resolve, reject) => {
166
+ child.once('error', reject);
167
+ child.once('exit', (code) => { process.exitCode = code ?? 1; resolve(); });
168
+ });
169
+ }
170
+ `;
137
171
  for (const [path, contents] of [
138
172
  [cli, launcher("totem.mjs")],
139
173
  [supervisor, launcher("automatic-runtime.mjs")],
@@ -216,6 +250,16 @@ export async function installRuntimeService(runtime, env = process.env, options
216
250
  "TOTEM_AGENT_TOKEN_ENV",
217
251
  "TOTEM_AGENT_COMMAND",
218
252
  "TOTEM_AGENT_COMMAND_ARGS",
253
+ "HTTP_PROXY",
254
+ "HTTPS_PROXY",
255
+ "ALL_PROXY",
256
+ "NO_PROXY",
257
+ "http_proxy",
258
+ "https_proxy",
259
+ "all_proxy",
260
+ "no_proxy",
261
+ "NODE_USE_ENV_PROXY",
262
+ "NODE_EXTRA_CA_CERTS",
219
263
  ])
220
264
  if (env[name]) serviceEnv[name] = env[name];
221
265
  await privateWrite(join(runtime.directory, "environment.json"), serviceEnv);
package/bin/totem.mjs CHANGED
@@ -4,7 +4,7 @@ import { createHash, randomUUID } from "node:crypto";
4
4
  import { createReadStream } from "node:fs";
5
5
  import { stripVTControlCharacters } from "node:util";
6
6
 
7
- const CLI_VERSION = "0.1.11";
7
+ const CLI_VERSION = "0.1.13";
8
8
  const DEFAULT_BASE_URL = "https://totemlayer.com";
9
9
  const API_KEY_PATTERN = /^at_(?:live|test)_[A-Za-z0-9_-]{20,}$/;
10
10
  const ACTION_PATTERN = /^[a-z0-9][a-z0-9._:-]*$/;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "totemlayer",
3
- "version": "0.1.11",
3
+ "version": "0.1.13",
4
4
  "description": "Cross-platform CLI for TotemLayer agent identity and authorization",
5
5
  "type": "module",
6
6
  "bin": {