subconscious-cli 4.1.0 → 4.1.2

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
@@ -7,7 +7,7 @@ Log in to Subconscious, then run coding agents against the Subconscious gateway.
7
7
  ```bash
8
8
  npm install -g subconscious-cli
9
9
  subc login
10
- subc sc
10
+ subc marathon
11
11
  subc claude
12
12
  ```
13
13
 
@@ -54,7 +54,7 @@ profile; they do not authenticate, install, configure, or launch anything:
54
54
 
55
55
  ```bash
56
56
  subc claude help
57
- subc sc help
57
+ subc marathon help
58
58
  subc codex help
59
59
  subc cursor help
60
60
  subc config help
@@ -69,7 +69,7 @@ gateway environment applied for that process. Arguments pass through as usual:
69
69
 
70
70
  ```bash
71
71
  subc claude --continue
72
- subc sc -- -p "fix the tests"
72
+ subc marathon -- -p "fix the tests"
73
73
  subc codex exec "write a test"
74
74
  subc opencode
75
75
  subc pi
@@ -134,8 +134,8 @@ any preview version pin from the current PowerShell session:
134
134
 
135
135
  ```powershell
136
136
  Remove-Item Env:SC_CODE_VERSION -ErrorAction SilentlyContinue
137
- subc.cmd sc install
138
- subc.cmd sc
137
+ subc.cmd marathon install
138
+ subc.cmd marathon
139
139
  ```
140
140
 
141
141
  The installer requires the selected release's Windows asset and SHA-256
@@ -152,7 +152,7 @@ The packaged integrations live in `cli/bin/runbook`.
152
152
 
153
153
  | Command | Behavior |
154
154
  | --- | --- |
155
- | `subc sc` | Launch Subconscious Code with the active gateway, key, model, and DLR transport |
155
+ | `subc marathon` | Launch Subconscious Code with the active gateway, key, model, and DLR transport |
156
156
  | `subc claude` | Launch Claude Code with the runbook environment, context limits, subagent limits, and OTEL usage reporting |
157
157
  | `subc codex` | Launch Codex with the runbook provider, temporary model catalog, and surgically merged compaction hooks |
158
158
  | `subc opencode` | Launch OpenCode with the runbook provider, client header, and context/output limits |
@@ -195,10 +195,20 @@ to install it before launching. Pi refreshes its Subconscious provider on every
195
195
  `subc pi` launch while preserving all other providers in `models.json`; its
196
196
  executable must already be installed.
197
197
 
198
- `subc sc install` detects the operating system and architecture, then downloads
198
+ `subc marathon install` detects the operating system and architecture, then downloads
199
199
  and checksum-verifies the matching precompiled release from
200
200
  `subconscious-systems/subconscious-code`. Apple Silicon and Intel macOS plus
201
- x86_64 and ARM64 Linux are supported; Cargo is not required.
201
+ x86_64 and ARM64 Linux and Windows x64 are supported; Cargo is not required.
202
+
203
+ Starting with CLI 4.1.1, `subc marathon` is the native agent command. On Windows,
204
+ the installer writes `marathon.exe`, avoiding the system `sc.exe` command.
205
+ `subc sc` remains a compatibility alias but never launches Windows service
206
+ control. Older pinned release binaries are also installed as `marathon.exe`.
207
+ Starting with CLI 4.1.2 and native agent 0.1.6, macOS and Linux also install
208
+ and launch `marathon`. Existing `.sc` settings, sessions, and `SC_*` variables
209
+ are preserved on every platform. Shell behavior is unchanged. Older Unix
210
+ release archives are installed under the new name; existing `sc` files are
211
+ left untouched. `subc sc` remains a compatibility alias on every platform.
202
212
 
203
213
  `subc codex` disables Codex apps and plugin tools for that launch by default so
204
214
  requests remain below the gateway's 128-tool limit. Core coding tools remain
package/bin/agents.js CHANGED
@@ -94,7 +94,7 @@ const AGENTS = registry.agents
94
94
  .filter((agent) => agent.cli !== false)
95
95
  .map((agent) => {
96
96
  const { command, fallback } = resolveInstall(agent.install);
97
- return { ...agent, install: command, installFallback: fallback };
97
+ return { ...agent, bin: agent.binByPlatform?.[process.platform] || agent.bin, install: command, installFallback: fallback };
98
98
  });
99
99
  const BY_ALIAS = new Map();
100
100
  for (const agent of AGENTS) {
@@ -166,14 +166,14 @@ export function parseAgentAction(agent, argv = []) {
166
166
 
167
167
  const AGENT_HELP = {
168
168
  'subconscious-code': {
169
- usage: 'subc [-p NAME] sc [help|install] [Subconscious Code arguments...]',
169
+ usage: 'subc [-p NAME] marathon [help|install] [Marathon arguments...]',
170
170
  behavior:
171
171
  'Launches the native Subconscious coding agent with the selected profile gateway, credential, and model.',
172
172
  options: [
173
173
  ['help', 'Show this help'],
174
174
  ['install', process.platform === 'win32' ? 'Install a verified Windows release, when published upstream' : 'Install the latest precompiled Linux or macOS release'],
175
175
  ['--model MODEL', 'Override the profile model for this launch'],
176
- ['ARGS...', 'Pass arguments directly to Subconscious Code'],
176
+ ['ARGS...', 'Pass arguments directly to Marathon'],
177
177
  ],
178
178
  },
179
179
  'claude-code': {
Binary file
Binary file
Binary file
Binary file
@@ -16,9 +16,10 @@
16
16
  "agents": [
17
17
  {
18
18
  "id": "subconscious-code",
19
- "command": "sc",
20
- "name": "Subconscious Code",
19
+ "command": "marathon",
20
+ "name": "Marathon",
21
21
  "aliases": [
22
+ "sc",
22
23
  "subconscious-code"
23
24
  ],
24
25
  "description": "Launch the native Subconscious coding agent with the active profile, gateway, and model.",
@@ -32,11 +33,11 @@
32
33
  ],
33
34
  "protocol": "openai",
34
35
  "homepage": "https://github.com/subconscious-systems/subconscious-code",
35
- "bin": "sc",
36
+ "bin": "marathon",
36
37
  "install": {
37
- "darwin": "subc sc install",
38
- "linux": "subc sc install",
39
- "win32": "subc sc install"
38
+ "darwin": "subc marathon install",
39
+ "linux": "subc marathon install",
40
+ "win32": "subc marathon install"
40
41
  },
41
42
  "runbook": {
42
43
  "mode": "launch",
@@ -50,7 +51,7 @@
50
51
  ],
51
52
  "setupNeedsAuth": false
52
53
  },
53
- "launch": "sc",
54
+ "launch": "marathon",
54
55
  "env": {
55
56
  "SC_BASE_URL": "{baseUrlV1}",
56
57
  "SC_DLR_URL": "{baseUrl}",
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env bash
2
- # Install a precompiled Subconscious Code release for the current platform.
2
+ # Install a precompiled Marathon release for the current platform.
3
3
 
4
4
  set -euo pipefail
5
5
 
@@ -9,9 +9,9 @@ INSTALL_DIR="${SC_INSTALL_DIR:-${HOME}/.local/bin}"
9
9
 
10
10
  usage() {
11
11
  cat <<'EOF'
12
- Usage: subc sc install
12
+ Usage: subc marathon install
13
13
 
14
- Install the latest Subconscious Code release. Linux downloads and verifies the
14
+ Install the latest Marathon release. Linux downloads and verifies the
15
15
  published static binary. macOS downloads and verifies the matching native binary.
16
16
  EOF
17
17
  }
@@ -23,7 +23,7 @@ case "${1:-install}" in
23
23
  exit 0
24
24
  ;;
25
25
  *)
26
- echo "error: unsupported Subconscious Code setup action: $1" >&2
26
+ echo "error: unsupported Marathon setup action: $1" >&2
27
27
  usage >&2
28
28
  exit 2
29
29
  ;;
@@ -60,8 +60,8 @@ architecture="$(uname -m)"
60
60
  version="$(release_tag || true)"
61
61
 
62
62
  if [[ -z "$version" ]]; then
63
- echo "error: no published Subconscious Code release is available yet" >&2
64
- echo "The release may still be building. Retry subc sc install after it finishes." >&2
63
+ echo "error: no published Marathon release is available yet" >&2
64
+ echo "The release may still be building. Retry subc marathon install after it finishes." >&2
65
65
  exit 1
66
66
  fi
67
67
 
@@ -76,27 +76,51 @@ case "${platform}:${architecture}" in
76
76
  ;;
77
77
  esac
78
78
 
79
- asset="sc-${target}.tar.gz"
79
+ executable="marathon"
80
+ asset="${executable}-${target}.tar.gz"
80
81
  checksum="${asset}.sha256"
81
- work_dir="$(mktemp -d "${TMPDIR:-/tmp}/subc-sc-install.XXXXXX")"
82
+ work_dir="$(mktemp -d "${TMPDIR:-/tmp}/subc-marathon-install.XXXXXX")"
83
+ staging=''
82
84
  cleanup() {
83
- rm -f "$work_dir/$asset" "$work_dir/$checksum" "$work_dir/sc"
85
+ rm -f "$work_dir/$asset" "$work_dir/$checksum" "$work_dir/sc" "$work_dir/marathon"
86
+ if [[ -n "$staging" ]]; then rm -f "$staging"; fi
84
87
  rmdir "$work_dir" 2>/dev/null || true
85
88
  }
86
89
  trap cleanup EXIT HUP INT TERM
87
90
 
88
- echo "Downloading Subconscious Code v${version} for ${target}..."
91
+ echo "Downloading Marathon v${version} for ${target}..."
89
92
  if command -v gh >/dev/null 2>&1 \
90
- && gh release view "v${version}" --repo "$REPOSITORY" >/dev/null 2>&1; then
93
+ && assets="$(gh release view "v${version}" --repo "$REPOSITORY" --json assets --jq '.assets[].name' 2>/dev/null)"; then
94
+ if ! printf '%s\n' "$assets" | grep -Fxq "$asset"; then
95
+ # Pinned legacy releases are still installed as marathon, never as sc.
96
+ executable="sc"
97
+ asset="${executable}-${target}.tar.gz"
98
+ checksum="${asset}.sha256"
99
+ fi
100
+ if ! printf '%s\n' "$assets" | grep -Fxq "$asset" \
101
+ || ! printf '%s\n' "$assets" | grep -Fxq "$checksum"; then
102
+ echo "error: release is missing $asset or $checksum" >&2
103
+ exit 1
104
+ fi
91
105
  gh release download "v${version}" --repo "$REPOSITORY" \
92
106
  --pattern "$asset" --pattern "$checksum" --dir "$work_dir"
93
107
  else
94
108
  command -v curl >/dev/null 2>&1 || {
95
- echo "error: curl is required to download Subconscious Code" >&2
109
+ echo "error: curl is required to download Marathon" >&2
96
110
  exit 1
97
111
  }
98
112
  release_url="${REPOSITORY_URL}/releases/download/v${version}"
99
- curl -fL "${release_url}/${asset}" -o "$work_dir/$asset"
113
+ status="$(curl -sSL -w '%{http_code}' "${release_url}/${asset}" -o "$work_dir/$asset")"
114
+ if [[ "$status" == 404 ]]; then
115
+ rm -f "$work_dir/$asset"
116
+ executable="sc"
117
+ asset="${executable}-${target}.tar.gz"
118
+ checksum="${asset}.sha256"
119
+ curl -fL "${release_url}/${asset}" -o "$work_dir/$asset"
120
+ elif [[ "$status" != 200 ]]; then
121
+ echo "error: Marathon download failed (HTTP $status)" >&2
122
+ exit 1
123
+ fi
100
124
  curl -fL "${release_url}/${checksum}" -o "$work_dir/$checksum"
101
125
  fi
102
126
 
@@ -106,7 +130,7 @@ elif command -v shasum >/dev/null 2>&1; then
106
130
  expected="$(awk '{print $1}' "$work_dir/$checksum")"
107
131
  actual="$(shasum -a 256 "$work_dir/$asset" | awk '{print $1}')"
108
132
  [[ "$actual" == "$expected" ]] || {
109
- echo "error: Subconscious Code checksum verification failed" >&2
133
+ echo "error: Marathon checksum verification failed" >&2
110
134
  exit 1
111
135
  }
112
136
  else
@@ -114,7 +138,17 @@ else
114
138
  exit 1
115
139
  fi
116
140
 
117
- tar -xzf "$work_dir/$asset" -C "$work_dir" sc
141
+ tar -xzf "$work_dir/$asset" -C "$work_dir" "$executable"
142
+ if [[ ! -f "$work_dir/$executable" || -L "$work_dir/$executable" ]]; then
143
+ echo "error: release has no regular root $executable executable" >&2
144
+ exit 1
145
+ fi
118
146
  mkdir -p "$INSTALL_DIR"
119
- install -m 0755 "$work_dir/sc" "$INSTALL_DIR/sc"
120
- echo "Installed Subconscious Code v${version} to $INSTALL_DIR/sc"
147
+ if [[ -d "$INSTALL_DIR/marathon" ]]; then
148
+ echo "error: $INSTALL_DIR/marathon is a directory; refusing to replace it" >&2
149
+ exit 1
150
+ fi
151
+ staging="$(mktemp "$INSTALL_DIR/.marathon.XXXXXX")"
152
+ install -m 0755 "$work_dir/$executable" "$staging"
153
+ mv -f "$staging" "$INSTALL_DIR/marathon"
154
+ echo "Installed Marathon v${version} to $INSTALL_DIR/marathon"
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env bash
2
- # Launch Subconscious Code without changing ~/.sc or project settings.
2
+ # Launch Marathon without changing ~/.sc or project settings.
3
3
 
4
4
  set -euo pipefail
5
5
 
@@ -8,7 +8,7 @@ API_KEY="${SC_API_KEY:-${API_KEY:-}}"
8
8
  MODEL="${MODEL:-subconscious/glm-5.3-marathon}"
9
9
 
10
10
  if [[ -z "$GATEWAY_URL" || -z "$API_KEY" ]]; then
11
- echo "error: GATEWAY_URL and API_KEY are required to launch Subconscious Code" >&2
11
+ echo "error: GATEWAY_URL and API_KEY are required to launch Marathon" >&2
12
12
  exit 1
13
13
  fi
14
14
 
@@ -18,4 +18,4 @@ export SC_DLR_URL="${GATEWAY_URL%/}"
18
18
  export SC_DLR_ENABLED=true
19
19
  export SC_MODEL="$MODEL"
20
20
 
21
- exec sc "$@"
21
+ exec marathon "$@"
package/bin/sessions.js CHANGED
@@ -21,7 +21,7 @@ export const SESSION_HARNESSES = Object.freeze({
21
21
  codex: { name: 'Codex CLI', command: 'codex', portable: true },
22
22
  opencode: { name: 'OpenCode', command: 'opencode', portable: true },
23
23
  pi: { name: 'Pi', command: 'pi', portable: true },
24
- sc: { name: 'Subconscious Code', command: 'sc', portable: false },
24
+ sc: { name: 'Marathon', command: 'marathon', portable: false },
25
25
  });
26
26
 
27
27
  function cleanText(value) {
@@ -592,7 +592,8 @@ export async function sessionsCommand(argv, options = {}) {
592
592
  if (!session) throw new Error(`Session '${key}' was not found. Run subc sessions to refresh the list.`);
593
593
  session = await hydrateSession(session);
594
594
  const harnessIndex = argv.indexOf('--harness');
595
- const targetHarness = harnessIndex >= 0 ? argv[harnessIndex + 1] : session.harness;
595
+ const requestedHarness = harnessIndex >= 0 ? argv[harnessIndex + 1] : session.harness;
596
+ const targetHarness = requestedHarness === 'marathon' ? 'sc' : requestedHarness;
596
597
  const target = SESSION_HARNESSES[targetHarness];
597
598
  if (!target) throw new Error(`Unknown destination harness: ${targetHarness}`);
598
599
 
@@ -21,7 +21,7 @@ export async function runWindowsAgent(agent, argv, dependencies) {
21
21
  ? [path.resolve(environment[agent.runbook.installDirEnv] || path.join(os.homedir(), agent.runbook.installDir))] : [];
22
22
  environment.PATH = windowsPath([...preferredDirs, ...(environment.PATH || '').split(';'), ...windowsBinDirs(environment)]);
23
23
  if (agent.id === 'subconscious-code' && parsed.action === 'install') {
24
- if (args.length) throw new Error('Usage: subc sc install');
24
+ if (args.length) throw new Error('Usage: subc marathon install');
25
25
  return finish(await installWindowsAgent(agent.id, environment));
26
26
  }
27
27
  if (['status', 'uninstall'].includes(parsed.action)) {
@@ -16,7 +16,7 @@ function npmInstall(command) {
16
16
  export function windowsInstallSpec(id, env = process.env) {
17
17
  const install = registry.agents.find(agent => agent.id === id)?.install;
18
18
  const command = typeof install === 'object' ? install.win32 : undefined;
19
- if (id === 'subconscious-code') return { nativeRelease: true, display: 'subc sc install' };
19
+ if (id === 'subconscious-code') return { nativeRelease: true, display: 'subc marathon install' };
20
20
  if (!command) return null; // Never fall back to a Linux installer.
21
21
  if (id === 'claude-code') {
22
22
  const primary = powershellCommand("$ErrorActionPreference = 'Stop'; Invoke-RestMethod 'https://claude.ai/install.ps1' | Invoke-Expression; if (-not $?) { exit 1 }", env);
@@ -30,9 +30,11 @@ export function windowsInstallSpec(id, env = process.env) {
30
30
  export function windowsReleaseAsset(release, arch = process.arch) {
31
31
  const target = { x64: 'x86_64-pc-windows-msvc', arm64: 'aarch64-pc-windows-msvc' }[arch];
32
32
  if (!target) throw new Error(`Subconscious Code does not support Windows architecture ${arch}`);
33
- const names = [`sc-${target}.zip`, `sc-${target}.exe`];
34
- const asset = release.assets?.find(asset => names.includes(asset.name));
35
- if (!asset) throw new Error(`Subconscious Code ${release.tag_name || 'latest'} has no published native Windows ${arch} binary. The CLI can launch an installed sc.exe, but the upstream release must include a Windows build before subc sc install can install it.`);
33
+ // Pinned older releases are installed under the new executable name too.
34
+ // Never resolve or overwrite Windows' own sc.exe.
35
+ const names = [`marathon-${target}.zip`, `marathon-${target}.exe`, `sc-${target}.zip`, `sc-${target}.exe`];
36
+ const asset = names.map(name => release.assets?.find(asset => asset.name === name)).find(Boolean);
37
+ if (!asset) throw new Error(`Marathon ${release.tag_name || 'latest'} has no published native Windows ${arch} binary for subc marathon install.`);
36
38
  const checksum = release.assets.find(candidate => candidate.name === `${asset.name}.sha256`);
37
39
  if (!checksum) throw new Error(`The Windows release is missing ${asset.name}.sha256; refusing an unverified installation.`);
38
40
  return { asset, checksum };
@@ -52,21 +54,22 @@ export async function installWindowsSC(env, { fetchImpl = fetch, run = runWindow
52
54
  if (!response.ok) throw new Error(`Download failed (HTTP ${response.status}): ${asset.name}`);
53
55
  return Buffer.from(await response.arrayBuffer());
54
56
  };
55
- log(`Downloading Subconscious Code ${release.tag_name} for Windows ${arch}...`);
57
+ log(`Downloading Marathon ${release.tag_name} for Windows ${arch}...`);
56
58
  const [binary, checksumText] = await Promise.all([download(asset), download(checksum)]);
57
59
  const expected = checksumText.toString('utf8').trim().split(/\s+/)[0];
58
60
  if (!/^[a-f0-9]{64}$/i.test(expected) || createHash('sha256').update(binary).digest('hex') !== expected.toLowerCase()) throw new Error('Subconscious Code checksum verification failed');
59
61
  const dir = await fs.mkdtemp(path.join(os.tmpdir(), 'subc-sc-install-'));
60
62
  const installDir = path.resolve(env.SC_INSTALL_DIR || path.join(home, '.local', 'bin'));
61
- const destination = path.join(installDir, 'sc.exe');
62
- const staging = path.join(installDir, `sc-${randomUUID()}.tmp`);
63
+ const destination = path.join(installDir, 'marathon.exe');
64
+ const staging = path.join(installDir, `marathon-${randomUUID()}.tmp`);
63
65
  try {
64
- const extracted = path.join(dir, 'sc.exe');
66
+ const extracted = path.join(dir, 'marathon.exe');
65
67
  if (asset.name.endsWith('.zip')) {
66
68
  const archive = path.join(dir, 'release.zip');
67
69
  await fs.writeFile(archive, binary, { flag: 'wx' });
68
70
  // Extract only the exact root executable. No archive-controlled paths.
69
- const spec = powershellCommand("$ErrorActionPreference = 'Stop'; Add-Type -AssemblyName System.IO.Compression.FileSystem; $z = [IO.Compression.ZipFile]::OpenRead($env:SUBC_ARCHIVE); try { $e = $z.GetEntry('sc.exe'); if ($null -eq $e) { throw 'Archive has no root sc.exe' }; [IO.Compression.ZipFileExtensions]::ExtractToFile($e, $env:SUBC_EXTRACTED, $false) } finally { $z.Dispose() }", { ...env, SUBC_ARCHIVE: archive, SUBC_EXTRACTED: extracted });
71
+ const executable = asset.name.startsWith('marathon-') ? 'marathon.exe' : 'sc.exe';
72
+ const spec = powershellCommand("$ErrorActionPreference = 'Stop'; Add-Type -AssemblyName System.IO.Compression.FileSystem; $z = [IO.Compression.ZipFile]::OpenRead($env:SUBC_ARCHIVE); try { $e = $z.GetEntry($env:SUBC_EXECUTABLE); if ($null -eq $e) { throw 'Archive has no expected root executable' }; [IO.Compression.ZipFileExtensions]::ExtractToFile($e, $env:SUBC_EXTRACTED, $false) } finally { $z.Dispose() }", { ...env, SUBC_ARCHIVE: archive, SUBC_EXTRACTED: extracted, SUBC_EXECUTABLE: executable });
70
73
  if (await run(spec.command, spec.args, { env: spec.env })) throw new Error('Could not extract the Windows release');
71
74
  } else await fs.writeFile(extracted, binary, { flag: 'wx' });
72
75
  const magic = (await fs.readFile(extracted)).subarray(0, 2).toString('ascii');
@@ -74,7 +77,7 @@ export async function installWindowsSC(env, { fetchImpl = fetch, run = runWindow
74
77
  await fs.mkdir(installDir, { recursive: true });
75
78
  await fs.copyFile(extracted, staging);
76
79
  await fs.rename(staging, destination);
77
- log(`Installed ${destination}. Run subc sc to launch it.`);
80
+ log(`Installed ${destination}. Run subc marathon to launch it.`);
78
81
  return 0;
79
82
  } finally {
80
83
  await fs.rm(staging, { force: true });
@@ -19,7 +19,7 @@ export async function windowsLaunch(id, argv, env, { tempRoot = os.tmpdir() } =
19
19
  const { model, base, key } = connection(env, keyName);
20
20
  const childEnv = { ...env, SUBCONSCIOUS_API_KEY: key, SUBCONSCIOUS_GATEWAY_URL: base };
21
21
  if (id === 'subconscious-code') {
22
- return { command: 'sc', args: argv, env: { ...childEnv, SC_API_KEY: key, SC_BASE_URL: `${base}/v1`, SC_DLR_URL: base, SC_DLR_ENABLED: 'true', SC_MODEL: model } };
22
+ return { command: 'marathon', args: argv, env: { ...childEnv, SC_API_KEY: key, SC_BASE_URL: `${base}/v1`, SC_DLR_URL: base, SC_DLR_ENABLED: 'true', SC_MODEL: model } };
23
23
  }
24
24
  if (id === 'pi') return { command: 'pi', args: ['--provider', 'subconscious', '--model', model, ...argv], env: childEnv };
25
25
  if (id === 'opencode') {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "subconscious-cli",
3
- "version": "4.1.0",
3
+ "version": "4.1.2",
4
4
  "description": "CLI for Subconscious — run Subconscious Code, Claude Code, Codex, OpenCode, DeepSeek Harness, Cursor, Copilot, and Pi",
5
5
  "bin": {
6
6
  "subc": "bin/cli.js"