@ours.network/codex 1.2.0-nightly.1 → 1.2.0-nightly.10

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.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ours",
3
- "version": "1.2.0-nightly.1",
3
+ "version": "1.2.0-nightly.10",
4
4
  "description": "Secure agent-to-agent messaging and explicitly armed live mail wake for Codex CLI.",
5
5
  "author": {
6
6
  "name": "Adapt Toolkit",
package/README.md CHANGED
@@ -51,38 +51,21 @@ The launcher never starts, stops, restarts, or reconfigures the ours daemon. If
51
51
  selected daemon is absent or incompatible, it exits with an error and leaves standard
52
52
  `codex` available.
53
53
 
54
- ## Selecting a daemon
55
-
56
- Multiple daemons may run on one host when each uses a distinct port and state directory.
57
- For network clients, explicit `OURS_CONFIG` takes precedence over the managed
58
- `~/.ours-client/profile.json`. When the managed file exists, ordinary `ours-codex`
59
- launches need no environment override. Invalid or unreadable managed profiles
60
- fail before selecting another daemon. With neither selection, the existing
61
- local-daemon precedence remains:
62
-
63
- 1. `ours-codex --ours-port <port>`
64
- 2. `OURS_PORT`
65
- 3. the config selected by `OURS_CONFIG`
66
- 4. `~/.ours/config.json`
67
- 5. port `3050`
68
-
69
- All MCP, hooks, unread, and watcher calls inherit the same selected profile. Host-profile
70
- traffic goes directly to the selected daemon's authenticated `/mcp` endpoint through the
71
- Codex package; it does not require Docker or an installed `@ours.network/mcp` package.
72
- Example:
54
+ ## Selecting a gateway
55
+
56
+ Every client uses `~/.ours-client/profile.json`; `OURS_CONFIG` can select a complete
57
+ alternate profile. It contains `serverUrl`, `expectedInstanceId`, and `credentialPath`.
58
+ The daemon endpoint is derived as `serverUrl + /daemon`, including gateway path prefixes.
59
+ Missing, unsafe, or invalid profiles fail closed. Remove legacy port/state/token
60
+ selectors; `--ours-port` is rejected. Example after provisioning with `ours-install client`:
73
61
 
74
62
  ```sh
75
- OURS_CONFIG="$HOME/.ours/testing.json" ours-codex --ours-port 4050
63
+ OURS_CONFIG="$HOME/.ours-client/testing.json" ours-codex
76
64
  ```
77
65
 
78
- An operator-provisioned host profile uses the complete
79
- `endpoint`/`expectedInstanceId`/`credentialPath` tuple in the selected file. In this mode,
80
- do not combine the profile with `--ours-port`, `OURS_PORT`, `OURS_API_TOKEN`, or
81
- `OURS_STATE_DIR`. Codex forwards the actual selected path as `OURS_CONFIG` and the optional `OURS_MCP_CONFIG` host
82
- record location; the SDK verifies the expected
83
- daemon instance and rereads `credentialPath` for every request, so an operator token
84
- update takes effect in the running hook and live monitor without a restart or token
85
- snapshot in child process environments.
66
+ MCP, hooks, unread and watcher requests inherit that profile. The SDK verifies the
67
+ instance and rereads the issued credential for each request. Client installation and
68
+ launch never install, start, restart or reconfigure server services.
86
69
 
87
70
  Native ownership is keyed by Codex's actual thread ID. A normal live TUI exit forwards
88
71
  that ID through the same `SessionEnd` input used by the hook. If Codex has not produced
@@ -33,7 +33,7 @@ export function planTomlInstall(text) {
33
33
  }
34
34
 
35
35
  // Render the managed TOML block: the `ours` MCP server pointing at the globally-installed
36
- // daemon proxy (`ours-mcp proxy`). Equivalent to `codex mcp add ours -- ours-mcp proxy`.
36
+ // gateway client (`ours-mcp proxy`). Equivalent to `codex mcp add ours -- ours-mcp proxy`.
37
37
  export function renderTomlBlock() {
38
38
  return `${SENTINEL}
39
39
  # Added by @ours.network/codex install.sh. Remove this whole block to uninstall.
@@ -41,9 +41,9 @@ export function renderTomlBlock() {
41
41
  [mcp_servers.ours]
42
42
  command = "ours-mcp"
43
43
  args = ["proxy"]
44
- # Optional per-server environment overrides go here, e.g.:
44
+ # Optional whole shared gateway profile override:
45
45
  # [mcp_servers.ours.env]
46
- # OURS_PORT = "3050"
46
+ # OURS_CONFIG = "/absolute/private/path/profile.json"
47
47
  ${SENTINEL_END}
48
48
  `;
49
49
  }
@@ -5,14 +5,7 @@
5
5
  // npm i -g @ours.network/codex
6
6
  // ours-codex-install
7
7
  //
8
- // SUPERSEDED BY `ours-install`: the unified `ours-install` is now the single front door for the
9
- // WHOLE stack (ours core + harness plugins + ours-fleet + Telegram). `ours-codex-install` is kept
10
- // as a THIN ALIAS — by default it hands off to `ours-install` when that's available, so an old
11
- // muscle-memory command still lands the user in the current, unified flow. Pass `--codex-only`
12
- // (or set OURS_CODEX_LEGACY=1) to force the legacy Codex-only install below.
13
- //
14
- // Usage:
15
- // ours-codex-install [--codex-only] [--codex-dir DIR] [--skills-dir DIR] [--skip-daemon]
8
+ // Installs client plugin wiring only after shared gateway profile validation.
16
9
  import { spawnSync } from 'node:child_process';
17
10
  import { fileURLToPath } from 'node:url';
18
11
  import { dirname, join } from 'node:path';
@@ -33,38 +26,19 @@ for (let i = 0; i < argv.length; i++) {
33
26
  else { console.error(`ours-codex-install: unknown argument "${a}"`); help(); process.exit(2); }
34
27
  }
35
28
 
36
- // Thin-alias hand-off: unless the caller forced the legacy Codex-only path, run the unified
37
- // `ours-install` if we can find it — on PATH (published), or the monorepo sibling (dev/test).
38
- if (!opts.codexOnly && !process.env.OURS_CODEX_LEGACY) {
39
- const onPath = spawnSync('bash', ['-c', 'command -v ours-install'], { encoding: 'utf8' });
40
- const unified = (onPath.status === 0 && (onPath.stdout || '').trim())
41
- ? { cmd: (onPath.stdout || '').trim(), args: argv }
42
- : (() => {
43
- const sib = join(PKG, '..', 'installer', 'install.mjs');
44
- return existsSync(sib) ? { cmd: process.execPath, args: [sib, ...argv] } : null;
45
- })();
46
- if (unified) {
47
- const r = spawnSync(unified.cmd, unified.args, { stdio: 'inherit', env: process.env });
48
- if (r.error) { console.error(`ours-codex-install: ${r.error.message}`); process.exit(1); }
49
- process.exit(r.status ?? 0);
50
- }
51
- // No unified installer found → fall through to the legacy Codex-only install (still never a dead end).
52
- }
53
-
54
29
  function help() {
55
30
  console.log(`ours-codex-install — set up the ours.network plugin for the OpenAI Codex CLI.
56
31
 
57
32
  ours-codex-install [options]
58
33
 
59
- By default this hands off to the unified \`ours-install\` (the single front door for the whole
60
- stack). Use --codex-only to run the legacy Codex-only install instead. Standard mode uses
34
+ Requires clients and a shared gateway profile provisioned by \`ours-install client\`. Standard mode uses
61
35
  \`codex\`; live mode uses \`ours-codex\`. Live monitoring still requires explicit consent.
62
36
 
63
37
  Options:
64
- --codex-only run the legacy Codex-only install (skip the unified ours-install)
38
+ --codex-only compatibility flag; plugin setup is always client-only
65
39
  --codex-dir <dir> Codex config+AGENTS.md root (default ~/.codex) [--codex-only]
66
40
  --skills-dir <dir> skills root (default ~/.agents/skills — USER scope) [--codex-only]
67
- --skip-daemon do not install/start the ours daemon [--codex-only]
41
+ --skip-daemon compatibility flag; server lifecycle is never changed [--codex-only]
68
42
  -h, --help show this help
69
43
 
70
44
  Idempotent: safe to re-run. Start a new Codex thread after installation and review the
@@ -81,7 +55,6 @@ if (!existsSync(INSTALL)) {
81
55
  const env = { ...process.env };
82
56
  if (opts.codexDir) env.CODEX_DIR = opts.codexDir;
83
57
  if (opts.skillsDir) env.SKILLS_DIR = opts.skillsDir;
84
- if (opts.skipDaemon) env.OURS_INSTALL_SKIP_DAEMON = '1';
85
58
 
86
59
  const res = spawnSync('bash', [INSTALL], { stdio: 'inherit', env });
87
60
  if (res.error) { console.error(`ours-codex-install: ${res.error.message}`); process.exit(1); }
package/bin/proxy.mjs CHANGED
@@ -1,8 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
3
  import { spawn } from 'node:child_process';
4
- import { existsSync, readFileSync } from 'node:fs';
5
- import { homedir } from 'node:os';
4
+ import { existsSync } from 'node:fs';
6
5
  import { dirname, join } from 'node:path';
7
6
  import { fileURLToPath } from 'node:url';
8
7
 
@@ -15,21 +14,6 @@ const here = dirname(fileURLToPath(import.meta.url));
15
14
  const env = { ...process.env };
16
15
 
17
16
  async function main() {
18
- const network = await import('../dist/network-proxy.mjs');
19
- const profile = network.hostProfileFromEnv(env);
20
- if (profile) {
21
- const configPath = env.OURS_MCP_CONFIG || join(env.HOME || homedir(), '.ours-mcp', 'config.json');
22
- const hostRecordRoot = dirname(configPath);
23
- if (sessionEnd) {
24
- const payload = JSON.parse(readFileSync(0, 'utf8') || '{}');
25
- if (typeof payload.session_id !== 'string' || !payload.session_id) throw new Error('SessionEnd requires session_id.');
26
- await network.endNetworkNativeSession({ profile, nativeSessionId: payload.session_id, hostRecordRoot });
27
- return;
28
- }
29
- await network.runNetworkProxy({ profile, hostRecordRoot, env });
30
- return;
31
- }
32
-
33
17
  let cliPath;
34
18
  try { cliPath = require.resolve(spec); } catch { /* try plugin cache layouts */ }
35
19
  if (!cliPath) {