subconscious-cli 4.0.15 → 4.0.16

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
@@ -95,10 +95,10 @@ to install it before launching. Pi refreshes its Subconscious provider on every
95
95
  `subc pi` launch while preserving all other providers in `models.json`; its
96
96
  executable must already be installed.
97
97
 
98
- `subc sc install` downloads and checksum-verifies the latest static Linux release
99
- from `subconscious-systems/subconscious-code`. The upstream release currently
100
- publishes x86_64 and ARM64 Linux assets. On macOS, the installer uses Cargo to
101
- build the tagged release until Darwin assets are published.
98
+ `subc sc install` detects the operating system and architecture, then downloads
99
+ and checksum-verifies the matching precompiled release from
100
+ `subconscious-systems/subconscious-code`. Apple Silicon and Intel macOS plus
101
+ x86_64 and ARM64 Linux are supported; Cargo is not required.
102
102
 
103
103
  `subc codex` disables Codex apps and plugin tools for that launch by default so
104
104
  requests remain below the gateway's 128-tool limit. Core coding tools remain
package/bin/agents.js CHANGED
@@ -170,7 +170,7 @@ const AGENT_HELP = {
170
170
  'Launches the native Subconscious coding agent with the selected profile gateway, credential, and model.',
171
171
  options: [
172
172
  ['help', 'Show this help'],
173
- ['install', 'Install the latest Linux release, or build from source on macOS'],
173
+ ['install', 'Install the latest precompiled Linux or macOS release'],
174
174
  ['--model MODEL', 'Override the profile model for this launch'],
175
175
  ['ARGS...', 'Pass arguments directly to Subconscious Code'],
176
176
  ],
@@ -431,6 +431,20 @@ function candidateBinDirs() {
431
431
  return [...new Set(dirs.filter(Boolean))];
432
432
  }
433
433
 
434
+ /** Resolve an agent-managed binary directory declared by the registry. */
435
+ export function preferredBinDirsForAgent(
436
+ agent,
437
+ environment = process.env,
438
+ home = os.homedir(),
439
+ ) {
440
+ const envName = agent.runbook?.installDirEnv;
441
+ const configured = envName ? environment[envName]?.trim() : '';
442
+ if (configured) return [path.resolve(configured)];
443
+
444
+ const installDir = agent.runbook?.installDir?.trim();
445
+ return installDir ? [path.resolve(home, installDir)] : [];
446
+ }
447
+
434
448
  /** Executable extensions to probe (Windows uses PATHEXT). */
435
449
  function binExts() {
436
450
  return process.platform === 'win32'
@@ -443,9 +457,9 @@ function binExts() {
443
457
  * containing the executable if found, otherwise null. Searching the candidate
444
458
  * dirs lets us find binaries installed this session that aren't on PATH yet.
445
459
  */
446
- async function resolveBinPath(bin) {
460
+ async function resolveBinPath(bin, preferredDirs = []) {
447
461
  const pathDirs = (process.env.PATH || '').split(path.delimiter).filter(Boolean);
448
- const dirs = [...pathDirs, ...candidateBinDirs()];
462
+ const dirs = [...new Set([...preferredDirs, ...pathDirs, ...candidateBinDirs()])];
449
463
  const exts = binExts();
450
464
  for (const dir of dirs) {
451
465
  for (const ext of exts) {
@@ -465,11 +479,24 @@ async function resolveBinPath(bin) {
465
479
  * Build a PATH string with `extraDirs` prepended (deduped against PATH).
466
480
  * Returns the augmented PATH value for use in a child env.
467
481
  */
468
- function augmentPath(extraDirs) {
469
- const current = (process.env.PATH || '').split(path.delimiter).filter(Boolean);
482
+ export function augmentPath(
483
+ extraDirs,
484
+ preferredDir,
485
+ currentPath = process.env.PATH || '',
486
+ ) {
487
+ const current = currentPath.split(path.delimiter).filter(Boolean);
470
488
  const seen = new Set(current);
471
- const prepend = extraDirs.filter((d) => d && !seen.has(d));
472
- return [...prepend, ...current].join(path.delimiter);
489
+ const prepend = extraDirs.filter(
490
+ (dir, index) =>
491
+ dir &&
492
+ dir !== preferredDir &&
493
+ !seen.has(dir) &&
494
+ extraDirs.indexOf(dir) === index,
495
+ );
496
+ const remaining = current.filter((dir) => dir !== preferredDir);
497
+ return [...(preferredDir ? [preferredDir] : []), ...prepend, ...remaining].join(
498
+ path.delimiter,
499
+ );
473
500
  }
474
501
 
475
502
  /** Ask a yes/no question on the TTY. Empty answer counts as yes. */
@@ -529,7 +556,8 @@ function printInstallCommands(agent) {
529
556
  * success. May exit the process on failure or when manual action is needed.
530
557
  */
531
558
  async function ensureInstalled(agent) {
532
- const existing = await resolveBinPath(agent.bin);
559
+ const preferredDirs = preferredBinDirsForAgent(agent);
560
+ const existing = await resolveBinPath(agent.bin, preferredDirs);
533
561
  if (existing) return existing;
534
562
 
535
563
  // Agents without an installer are launch-only. Their setup integration may
@@ -580,7 +608,7 @@ async function ensureInstalled(agent) {
580
608
 
581
609
  // PATH hardening: the freshly-installed binary is often not on the current
582
610
  // process's PATH. Re-resolve against PATH + candidate dirs.
583
- const found = await resolveBinPath(agent.bin);
611
+ const found = await resolveBinPath(agent.bin, preferredDirs);
584
612
  if (found) return found;
585
613
 
586
614
  console.error(
@@ -605,7 +633,13 @@ export function readClaudeVersion(bin, binDir, options = {}) {
605
633
  const stdout = execFile(bin, ['--version'], {
606
634
  encoding: 'utf-8',
607
635
  stdio: ['ignore', 'pipe', 'pipe'],
608
- env: { ...process.env, PATH: augmentPath([binDir, ...candidateBinDirs()].filter(Boolean)) },
636
+ env: {
637
+ ...process.env,
638
+ PATH: augmentPath(
639
+ [binDir, ...candidateBinDirs()].filter(Boolean),
640
+ binDir,
641
+ ),
642
+ },
609
643
  timeout: options.timeoutMs ?? 3000,
610
644
  });
611
645
  return parseClaudeVersion(typeof stdout === 'string' ? stdout : stdout?.toString?.());
@@ -852,7 +886,7 @@ export function runbookEnv(
852
886
  }
853
887
  : {}),
854
888
  SUBC_ENV_FILE: os.devNull,
855
- PATH: augmentPath(extraDirs),
889
+ PATH: augmentPath(extraDirs, binDir),
856
890
  },
857
891
  picker,
858
892
  models,
@@ -1005,7 +1039,7 @@ export async function runAgent(agent, argv, options = {}) {
1005
1039
  ...envMap,
1006
1040
  ...(profile?.values || {}),
1007
1041
  ...process.env,
1008
- PATH: augmentPath(extraDirs),
1042
+ PATH: augmentPath(extraDirs, binDir),
1009
1043
  };
1010
1044
  const args = [...launchArgs, ...rest];
1011
1045
 
Binary file
Binary file
Binary file
Binary file
@@ -33,15 +33,16 @@
33
33
  "homepage": "https://github.com/subconscious-systems/subconscious-code",
34
34
  "bin": "sc",
35
35
  "install": {
36
- "darwin": "cargo install --locked --git https://github.com/subconscious-systems/subconscious-code --bin sc rc-cli",
37
- "linux": "subc sc install",
38
- "fallback": "cargo install --locked --git https://github.com/subconscious-systems/subconscious-code --bin sc rc-cli"
36
+ "darwin": "subc sc install",
37
+ "linux": "subc sc install"
39
38
  },
40
39
  "runbook": {
41
40
  "mode": "launch",
42
41
  "script": "subconscious-code/run.sh",
43
42
  "setupScript": "subconscious-code/install.sh",
44
43
  "binaryInstallScript": "subconscious-code/install.sh",
44
+ "installDirEnv": "SC_INSTALL_DIR",
45
+ "installDir": ".local/bin",
45
46
  "setupActions": [
46
47
  "install"
47
48
  ],
@@ -1,6 +1,5 @@
1
1
  #!/usr/bin/env bash
2
- # Install Subconscious Code. Tagged releases currently contain static Linux
3
- # binaries; macOS builds from the tagged source until Darwin assets are added.
2
+ # Install a precompiled Subconscious Code release for the current platform.
4
3
 
5
4
  set -euo pipefail
6
5
 
@@ -13,7 +12,7 @@ usage() {
13
12
  Usage: subc sc install
14
13
 
15
14
  Install the latest Subconscious Code release. Linux downloads and verifies the
16
- published static binary. macOS builds the release from source with Cargo.
15
+ published static binary. macOS downloads and verifies the matching native binary.
17
16
  EOF
18
17
  }
19
18
 
@@ -56,49 +55,23 @@ release_tag() {
56
55
  return 1
57
56
  }
58
57
 
59
- install_from_source() {
60
- if ! command -v cargo >/dev/null 2>&1; then
61
- echo "error: macOS installation currently requires Cargo (Rust 1.89 or newer)" >&2
62
- echo "Install Rust from https://rustup.rs, then run: subc sc install" >&2
63
- exit 1
64
- fi
65
-
66
- local version="${1:-}"
67
- local args=(install --locked --git "$REPOSITORY_URL" --bin sc)
68
- if [[ -n "$version" ]]; then
69
- args+=(--tag "v${version}")
70
- echo "Building Subconscious Code v${version} from source..."
71
- else
72
- echo "No published release is visible yet; building Subconscious Code from the default branch..."
73
- fi
74
- args+=(rc-cli)
75
- CARGO_NET_GIT_FETCH_WITH_CLI=true cargo "${args[@]}"
76
- }
77
-
78
58
  platform="$(uname -s)"
59
+ architecture="$(uname -m)"
79
60
  version="$(release_tag || true)"
80
61
 
81
- if [[ "$platform" == "Darwin" ]]; then
82
- install_from_source "$version"
83
- exit 0
84
- fi
85
-
86
- if [[ "$platform" != "Linux" ]]; then
87
- echo "error: Subconscious Code automatic installation supports Linux and macOS" >&2
88
- exit 1
89
- fi
90
-
91
62
  if [[ -z "$version" ]]; then
92
63
  echo "error: no published Subconscious Code release is available yet" >&2
93
64
  echo "The release may still be building. Retry subc sc install after it finishes." >&2
94
65
  exit 1
95
66
  fi
96
67
 
97
- case "$(uname -m)" in
98
- x86_64|amd64) target="x86_64-unknown-linux-musl" ;;
99
- aarch64|arm64) target="aarch64-unknown-linux-musl" ;;
68
+ case "${platform}:${architecture}" in
69
+ Darwin:arm64) target="aarch64-apple-darwin" ;;
70
+ Darwin:x86_64) target="x86_64-apple-darwin" ;;
71
+ Linux:aarch64|Linux:arm64) target="aarch64-unknown-linux-musl" ;;
72
+ Linux:x86_64|Linux:amd64) target="x86_64-unknown-linux-musl" ;;
100
73
  *)
101
- echo "error: unsupported Linux architecture: $(uname -m)" >&2
74
+ echo "error: unsupported platform or architecture: ${platform} ${architecture}" >&2
102
75
  exit 1
103
76
  ;;
104
77
  esac
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "subconscious-cli",
3
- "version": "4.0.15",
3
+ "version": "4.0.16",
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"