subconscious-cli 6.0.1 → 6.2.0

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.
Files changed (73) hide show
  1. package/README.md +167 -43
  2. package/bin/agent-data.js +278 -0
  3. package/bin/agent-help.js +114 -0
  4. package/bin/agent-install.js +238 -0
  5. package/bin/agent-launch.js +199 -0
  6. package/bin/agent-spawn.js +137 -0
  7. package/bin/agents.js +236 -931
  8. package/bin/auth.js +9 -1
  9. package/bin/claude-picker.js +143 -0
  10. package/bin/cli.js +62 -2
  11. package/bin/clipboard-image.js +2 -0
  12. package/bin/feedback.js +14 -3
  13. package/bin/harness-manifest.js +286 -0
  14. package/bin/headless-args.js +35 -0
  15. package/bin/launch-values.js +25 -0
  16. package/bin/model-capabilities.js +10 -9
  17. package/bin/models.js +25 -13
  18. package/bin/native/subc-tui-darwin-amd64 +0 -0
  19. package/bin/native/subc-tui-darwin-arm64 +0 -0
  20. package/bin/native/subc-tui-linux-amd64 +0 -0
  21. package/bin/native/subc-tui-linux-arm64 +0 -0
  22. package/bin/native/subc-tui-windows-amd64.exe +0 -0
  23. package/bin/native/subc-tui-windows-arm64.exe +0 -0
  24. package/bin/opencode-provider.js +21 -0
  25. package/bin/profile-settings.js +129 -0
  26. package/bin/profiles.js +29 -424
  27. package/bin/runbook/README.md +77 -23
  28. package/bin/runbook/claude-code/agent.json +300 -0
  29. package/bin/runbook/claude-code/install.sh +9 -252
  30. package/bin/runbook/codex/agent.json +462 -0
  31. package/bin/runbook/codex/hooks-lib.sh +17 -4
  32. package/bin/runbook/codex/install.sh +0 -4
  33. package/bin/runbook/codex/run.sh +16 -235
  34. package/bin/runbook/copilot/agent.json +186 -0
  35. package/bin/runbook/copilot/install.sh +45 -63
  36. package/bin/runbook/cursor/agent.json +138 -0
  37. package/bin/runbook/cursor/install.sh +8 -35
  38. package/bin/runbook/deepseek-harness/agent.json +164 -0
  39. package/bin/runbook/deepseek-harness/run.sh +20 -59
  40. package/bin/runbook/image-window/index.ts +14 -0
  41. package/bin/runbook/image-window/window.d.ts +19 -0
  42. package/bin/runbook/image-window/window.js +140 -0
  43. package/bin/runbook/lib.sh +41 -0
  44. package/bin/runbook/opencode/agent.json +159 -0
  45. package/bin/runbook/opencode/install.sh +9 -183
  46. package/bin/runbook/opencode/opencode-plugin.d.ts +10 -3
  47. package/bin/runbook/opencode/subconscious-image-window.ts +24 -0
  48. package/bin/runbook/pi/agent.json +217 -0
  49. package/bin/runbook/pi/install.sh +18 -44
  50. package/bin/runbook/pi/run.sh +6 -18
  51. package/bin/runbook/pi/subconscious-compaction.ts +3 -1
  52. package/bin/runbook/shared.json +57 -0
  53. package/bin/sessions.js +53 -48
  54. package/bin/tui.js +13 -0
  55. package/bin/update-check.js +35 -1
  56. package/bin/upgrade.js +27 -34
  57. package/bin/usage.js +21 -10
  58. package/bin/windows/agents.js +28 -60
  59. package/bin/windows/common.js +2 -28
  60. package/bin/windows/launch.js +252 -231
  61. package/bin/windows/process.js +12 -1
  62. package/bin/windows/setup.js +29 -9
  63. package/package.json +2 -4
  64. package/bin/registry.generated.json +0 -406
  65. package/bin/runbook/claude-code/run.sh +0 -254
  66. package/bin/runbook/model-capabilities.generated.sh +0 -9
  67. package/bin/runbook/opencode/provider.sh +0 -93
  68. package/bin/runbook/opencode/run.sh +0 -99
  69. package/bin/runbook/opencode/subconscious-compaction.ts +0 -100
  70. package/bin/runbook/subconscious-code/install.sh +0 -154
  71. package/bin/runbook/subconscious-code/run.sh +0 -21
  72. package/bin/windows/claude.js +0 -100
  73. package/bin/windows/install.js +0 -188
@@ -1,93 +0,0 @@
1
- #!/usr/bin/env bash
2
- # Shared OpenCode provider metadata for subc launch and install paths.
3
-
4
- # OpenCode groups /models entries by provider.name. Keep this stable and human
5
- # readable.
6
- SUBC_OPENCODE_PROVIDER_ID="subconscious"
7
- SUBC_OPENCODE_PROVIDER_NAME="Subconscious Gateway"
8
-
9
- subc_opencode_model_display_name() {
10
- local slug="${1:-}"
11
- slug="${slug#subconscious/}"
12
- echo "$slug" | awk -F '[-_]' '
13
- function format_token(token, lower) {
14
- lower = tolower(token)
15
- if (lower ~ /^(gpt|oss|api|gguf|ggml|nomic|vl|it|mlx)$/) return toupper(token)
16
- if (token ~ /^[0-9]+[bBkKmMgG]$/) return toupper(token)
17
- if (token ~ /^[qQ][0-9]+$/) return toupper(token)
18
- if (token ~ /^[0-9]+\.[0-9]+/) return token
19
- if (token ~ /^[A-Za-z][0-9]+[A-Za-z]$/ || token ~ /^[0-9]+[A-Za-z]$/) return toupper(token)
20
- return toupper(substr(token, 1, 1)) tolower(substr(token, 2))
21
- }
22
- {
23
- out = ""
24
- for (i = 1; i <= NF; i++) {
25
- if ($i == "") continue
26
- out = out (out == "" ? "" : " ") format_token($i)
27
- }
28
- print out
29
- }
30
- '
31
- }
32
-
33
- subc_opencode_build_whitelist_json() {
34
- local model_id
35
- WHITELIST_JSON=""
36
- for model_id in "${SUPPORTED_MODELS[@]}"; do
37
- if [[ -n "$WHITELIST_JSON" ]]; then
38
- WHITELIST_JSON="${WHITELIST_JSON},\"${model_id}\""
39
- else
40
- WHITELIST_JSON="\"${model_id}\""
41
- fi
42
- done
43
- WHITELIST_JSON="[${WHITELIST_JSON}]"
44
- }
45
-
46
- subc_opencode_build_models_json() {
47
- local model_id display_name vision_fields model_json
48
- MODELS_JSON=""
49
- for model_id in "${SUPPORTED_MODELS[@]}"; do
50
- display_name="$(subc_opencode_model_display_name "$model_id")"
51
- vision_fields=""
52
- if subc_model_supports_vision "$model_id"; then
53
- vision_fields=',"attachment":true,"modalities":{"input":["text","image"],"output":["text"]}'
54
- fi
55
- model_json="\"${model_id}\":{\"name\":\"${display_name}\",\"tools\":true,\"limit\":{\"context\":${CONTEXT_LIMIT},\"output\":${OUTPUT_LIMIT}}${vision_fields}}"
56
- if [[ -n "$MODELS_JSON" ]]; then
57
- MODELS_JSON="${MODELS_JSON},${model_json}"
58
- else
59
- MODELS_JSON="$model_json"
60
- fi
61
- done
62
- subc_opencode_build_whitelist_json
63
- }
64
-
65
- subc_opencode_build_config_json() {
66
- local base_url="${1:?base url required}"
67
- local model="${2:?model required}"
68
- cat <<EOF
69
- {"\$schema":"https://opencode.ai/config.json","disabled_providers":["subconscious-cli"],"provider":{"${SUBC_OPENCODE_PROVIDER_ID}":{"npm":"@ai-sdk/openai-compatible","name":"${SUBC_OPENCODE_PROVIDER_NAME}","whitelist":${WHITELIST_JSON},"options":{"baseURL":"${base_url}","apiKey":"{env:SUBCONSCIOUS_API_KEY}","headers":{"x-subconscious-client":"opencode"},"modelsDiscovery":{"enabled":false}},"models":{${MODELS_JSON}}}},"model":"${SUBC_OPENCODE_PROVIDER_ID}/${model}"}
70
- EOF
71
- }
72
-
73
- subc_opencode_build_provider_json() {
74
- local base_url="${1:?base url required}"
75
- cat <<EOF
76
- {
77
- "npm": "@ai-sdk/openai-compatible",
78
- "name": "${SUBC_OPENCODE_PROVIDER_NAME}",
79
- "whitelist": ${WHITELIST_JSON},
80
- "options": {
81
- "baseURL": "${base_url}",
82
- "apiKey": "{env:SUBCONSCIOUS_API_KEY}",
83
- "headers": {
84
- "x-subconscious-client": "opencode"
85
- },
86
- "modelsDiscovery": {
87
- "enabled": false
88
- }
89
- },
90
- "models": {${MODELS_JSON}}
91
- }
92
- EOF
93
- }
@@ -1,99 +0,0 @@
1
- #!/usr/bin/env bash
2
- # Point OpenCode at the Subconscious gateway — ephemerally.
3
- #
4
- # Exports SUBCONSCIOUS_API_KEY and OPENCODE_CONFIG_CONTENT as env vars so
5
- # nothing is written to ~/.opencode/opencode.json. OpenCode reads the
6
- # config from the OPENCODE_CONFIG_CONTENT env var at startup.
7
- #
8
- # Usage:
9
- # ./run.sh # uses GATEWAY_URL/API_KEY from ../.env
10
- # ./run.sh -- auth # pass args through to opencode
11
- #
12
- # Config: copy ../env.example to ../.env and edit. .env is gitignored.
13
- # Profile env is injected by subc. A sibling .env is only used when SUBC_ENV_FILE is unset.
14
- #
15
- # Or source it to just export the env:
16
- # source run.sh
17
-
18
- set -euo pipefail
19
-
20
- SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
21
- source "${SCRIPT_DIR}/../model-capabilities.generated.sh"
22
- source "${SCRIPT_DIR}/provider.sh"
23
-
24
- # Load shared env from SUBC_ENV_FILE, or a sibling .env / env.example.
25
- SHARED_ENV="${SUBC_ENV_FILE:-${SCRIPT_DIR}/../.env}"
26
- [[ -f "$SHARED_ENV" ]] || SHARED_ENV="${SCRIPT_DIR}/../env.example"
27
- if [[ -f "$SHARED_ENV" ]]; then set -a; source "$SHARED_ENV"; set +a; fi
28
-
29
- GATEWAY_URL="${GATEWAY_URL:-}"
30
- API_KEY="${OPENCODE_API_KEY:-${API_KEY:-}}"
31
- MODEL="${MODEL:-subconscious/glm-5.3-marathon}"
32
- CONTEXT_LIMIT="${OPENCODE_CONTEXT_LIMIT:-5000000}"
33
- OUTPUT_LIMIT="${OPENCODE_OUTPUT_LIMIT:-65536}"
34
-
35
- DEFAULT_SUBCONSCIOUS_MODELS="subconscious/glm-5.3-marathon
36
- subconscious/glm-5.2
37
- subconscious/tim-qwen3.6-27b
38
- subconscious/deepseek-v4-flash-marathon
39
- subconscious/deepseek-v4.1-flash-marathon"
40
- SUPPORTED_MODELS=()
41
-
42
- add_supported_model() {
43
- local model_id="$1" existing
44
- [[ -n "$model_id" ]] || return 0
45
- if [[ ! "$model_id" =~ ^[-A-Za-z0-9._:/+]+$ ]]; then
46
- echo "error: invalid model id: $model_id" >&2
47
- exit 1
48
- fi
49
- if [[ "${#SUPPORTED_MODELS[@]}" -gt 0 ]]; then
50
- for existing in "${SUPPORTED_MODELS[@]}"; do
51
- [[ "$existing" == "$model_id" ]] && return 0
52
- done
53
- fi
54
- SUPPORTED_MODELS+=("$model_id")
55
- }
56
-
57
- add_supported_model "$MODEL"
58
- while IFS= read -r model_id; do
59
- add_supported_model "$model_id"
60
- done <<< "${SUBCONSCIOUS_MODELS:-$DEFAULT_SUBCONSCIOUS_MODELS}"
61
-
62
- subc_opencode_build_models_json
63
-
64
- if [[ -z "$GATEWAY_URL" || -z "$API_KEY" ]]; then
65
- echo "error: GATEWAY_URL and API_KEY must be set in ../.env" >&2
66
- exit 1
67
- fi
68
-
69
- # Parse args (only when executed, not sourced)
70
- PASSTHRU=()
71
- if [[ "${BASH_SOURCE[0]:-$0}" == "${0}" ]]; then
72
- while [[ $# -gt 0 ]]; do
73
- case "$1" in
74
- --)
75
- shift
76
- PASSTHRU+=("$@")
77
- break
78
- ;;
79
- *)
80
- PASSTHRU+=("$1")
81
- shift
82
- ;;
83
- esac
84
- done
85
- fi
86
-
87
- BASE_URL="${GATEWAY_URL%/}/v1"
88
-
89
- export SUBCONSCIOUS_API_KEY="$API_KEY"
90
- # Compaction reporting needs the plugin on disk; this launch path writes nothing.
91
- export SUBCONSCIOUS_GATEWAY_URL="${GATEWAY_URL%/}"
92
- export OPENCODE_CONFIG_CONTENT="$(subc_opencode_build_config_json "$BASE_URL" "$MODEL")"
93
-
94
- # If sourced, just export env and return.
95
- if [[ "${BASH_SOURCE[0]:-$0}" != "${0}" ]]; then
96
- return 0 2>/dev/null || true
97
- fi
98
-
99
- exec opencode ${PASSTHRU[@]+"${PASSTHRU[@]}"}
@@ -1,100 +0,0 @@
1
- /**
2
- * Report OpenCode compactions to the Subconscious API Gateway.
3
- *
4
- * Why this exists: OpenCode summarizes by issuing an ordinary completion through the
5
- * configured provider, which is the gateway, carrying the same session headers as every
6
- * other turn. Without a signal the gateway would count that summarization as the largest
7
- * main-thread turn of the conversation, inflating peak context and the traditional
8
- * comparison at exactly the turn where accuracy matters most.
9
- *
10
- * Two callbacks bracket it:
11
- * experimental.session.compacting -> phase "start" (awaited, so it is ordered before
12
- * the summarization request reaches the gateway)
13
- * session.compacted event -> phase "end"
14
- *
15
- * Requests between them are the compaction. `sessionID` is the same value OpenCode sends
16
- * as x-session-affinity / x-session-id, which is already the gateway's grouping key, so
17
- * no fingerprinting is involved.
18
- *
19
- * Fail open: a gateway that is down or slow must never disturb a coding session.
20
- *
21
- * Install: copy to ~/.config/opencode/plugins/ (global) or .opencode/plugins/ (project).
22
- * `opencode/install.sh` does this for you.
23
- */
24
-
25
- import type { Plugin } from '@opencode-ai/plugin';
26
-
27
- const TIMEOUT_MS = 2000;
28
-
29
- function gatewayUrl(): string | undefined {
30
- const raw = process.env.SUBCONSCIOUS_GATEWAY_URL ?? process.env.GATEWAY_URL;
31
- return raw ? raw.replace(/\/+$/, '') : undefined;
32
- }
33
-
34
- function apiKey(): string | undefined {
35
- return process.env.SUBCONSCIOUS_API_KEY ?? process.env.API_KEY;
36
- }
37
-
38
- async function report(
39
- sessionID: string,
40
- phase: 'start' | 'end',
41
- hookEventName: string,
42
- ): Promise<void> {
43
- const url = gatewayUrl();
44
- const key = apiKey();
45
- if (!url || !key || !sessionID) return;
46
-
47
- // Idempotency key for this one event. It must be unique per compaction but stable for
48
- // a redelivery of this same POST, so it is derived from the wall clock rather than any
49
- // in-process counter: a counter resets when OpenCode restarts, and a resumed session
50
- // compacting again would then reuse a key the gateway has already seen and silently
51
- // drop the signal. Computed once here, before the request, so a transport-level retry
52
- // carries the identical body.
53
- const dedupeKey = `${sessionID}:${phase}:${Date.now()}`;
54
-
55
- const controller = new AbortController();
56
- const timer = setTimeout(() => controller.abort(), TIMEOUT_MS);
57
- try {
58
- await fetch(`${url}/v1/agent-hooks`, {
59
- method: 'POST',
60
- headers: {
61
- 'content-type': 'application/json',
62
- authorization: `Bearer ${key}`,
63
- 'x-subconscious-client': 'opencode',
64
- },
65
- body: JSON.stringify({
66
- event: 'conversation_compaction',
67
- conversation_id: sessionID,
68
- phase,
69
- hook_event_name: hookEventName,
70
- dedupe_key: dedupeKey,
71
- }),
72
- signal: controller.signal,
73
- });
74
- } catch {
75
- // Fail open on timeout, offline gateway, or auth failure.
76
- } finally {
77
- clearTimeout(timer);
78
- }
79
- }
80
-
81
- export const SubconsciousCompaction: Plugin = async () => {
82
- return {
83
- 'experimental.session.compacting': async (input) => {
84
- // Deliberately does not touch `output`: mutating `context` would change the
85
- // customer's compaction prompt, and setting `prompt` would replace it entirely.
86
- await report(input.sessionID, 'start', 'session.compacting');
87
- },
88
- event: async ({ event }) => {
89
- if (event.type === 'session.compacted') {
90
- const sessionID = (event as { properties?: { sessionID?: string } })
91
- .properties?.sessionID;
92
- if (sessionID) {
93
- // No shared id with the matching `start` is needed: the gateway pairs a start
94
- // with the next end by server-stamped time, not by key.
95
- await report(sessionID, 'end', 'session.compacted');
96
- }
97
- }
98
- },
99
- };
100
- };
@@ -1,154 +0,0 @@
1
- #!/usr/bin/env bash
2
- # Install a precompiled Marathon release for the current platform.
3
-
4
- set -euo pipefail
5
-
6
- REPOSITORY="subconscious-systems/subconscious-code"
7
- REPOSITORY_URL="https://github.com/${REPOSITORY}"
8
- INSTALL_DIR="${SC_INSTALL_DIR:-${HOME}/.local/bin}"
9
-
10
- usage() {
11
- cat <<'EOF'
12
- Usage: subc marathon install
13
-
14
- Install the latest Marathon release. Linux downloads and verifies the
15
- published static binary. macOS downloads and verifies the matching native binary.
16
- EOF
17
- }
18
-
19
- case "${1:-install}" in
20
- install) ;;
21
- help|-h|--help)
22
- usage
23
- exit 0
24
- ;;
25
- *)
26
- echo "error: unsupported Marathon setup action: $1" >&2
27
- usage >&2
28
- exit 2
29
- ;;
30
- esac
31
-
32
- release_tag() {
33
- if [[ -n "${SC_CODE_VERSION:-}" ]]; then
34
- printf '%s\n' "${SC_CODE_VERSION#v}"
35
- return
36
- fi
37
- if command -v gh >/dev/null 2>&1; then
38
- local tag
39
- tag="$(gh release view --repo "$REPOSITORY" --json tagName --jq '.tagName' 2>/dev/null || true)"
40
- if [[ -n "$tag" ]]; then
41
- printf '%s\n' "${tag#v}"
42
- return
43
- fi
44
- fi
45
- if command -v curl >/dev/null 2>&1; then
46
- local tag
47
- tag="$(curl -fsSL "https://api.github.com/repos/${REPOSITORY}/releases/latest" 2>/dev/null \
48
- | sed -n 's/.*"tag_name"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/p' \
49
- | head -n 1 || true)"
50
- if [[ -n "$tag" ]]; then
51
- printf '%s\n' "${tag#v}"
52
- return
53
- fi
54
- fi
55
- return 1
56
- }
57
-
58
- platform="$(uname -s)"
59
- architecture="$(uname -m)"
60
- version="$(release_tag || true)"
61
-
62
- if [[ -z "$version" ]]; then
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
- exit 1
66
- fi
67
-
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" ;;
73
- *)
74
- echo "error: unsupported platform or architecture: ${platform} ${architecture}" >&2
75
- exit 1
76
- ;;
77
- esac
78
-
79
- executable="marathon"
80
- asset="${executable}-${target}.tar.gz"
81
- checksum="${asset}.sha256"
82
- work_dir="$(mktemp -d "${TMPDIR:-/tmp}/subc-marathon-install.XXXXXX")"
83
- staging=''
84
- cleanup() {
85
- rm -f "$work_dir/$asset" "$work_dir/$checksum" "$work_dir/sc" "$work_dir/marathon"
86
- if [[ -n "$staging" ]]; then rm -f "$staging"; fi
87
- rmdir "$work_dir" 2>/dev/null || true
88
- }
89
- trap cleanup EXIT HUP INT TERM
90
-
91
- echo "Downloading Marathon v${version} for ${target}..."
92
- if command -v gh >/dev/null 2>&1 \
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
105
- gh release download "v${version}" --repo "$REPOSITORY" \
106
- --pattern "$asset" --pattern "$checksum" --dir "$work_dir"
107
- else
108
- command -v curl >/dev/null 2>&1 || {
109
- echo "error: curl is required to download Marathon" >&2
110
- exit 1
111
- }
112
- release_url="${REPOSITORY_URL}/releases/download/v${version}"
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
124
- curl -fL "${release_url}/${checksum}" -o "$work_dir/$checksum"
125
- fi
126
-
127
- if command -v sha256sum >/dev/null 2>&1; then
128
- (cd "$work_dir" && sha256sum --check "$checksum")
129
- elif command -v shasum >/dev/null 2>&1; then
130
- expected="$(awk '{print $1}' "$work_dir/$checksum")"
131
- actual="$(shasum -a 256 "$work_dir/$asset" | awk '{print $1}')"
132
- [[ "$actual" == "$expected" ]] || {
133
- echo "error: Marathon checksum verification failed" >&2
134
- exit 1
135
- }
136
- else
137
- echo "error: sha256sum or shasum is required to verify the download" >&2
138
- exit 1
139
- fi
140
-
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
146
- mkdir -p "$INSTALL_DIR"
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,21 +0,0 @@
1
- #!/usr/bin/env bash
2
- # Launch Marathon without changing ~/.sc or project settings.
3
-
4
- set -euo pipefail
5
-
6
- GATEWAY_URL="${GATEWAY_URL:-}"
7
- API_KEY="${SC_API_KEY:-${API_KEY:-}}"
8
- MODEL="${MODEL:-subconscious/glm-5.3-marathon}"
9
-
10
- if [[ -z "$GATEWAY_URL" || -z "$API_KEY" ]]; then
11
- echo "error: GATEWAY_URL and API_KEY are required to launch Marathon" >&2
12
- exit 1
13
- fi
14
-
15
- export SC_API_KEY="$API_KEY"
16
- export SC_BASE_URL="${GATEWAY_URL%/}/v1"
17
- export SC_DLR_URL="${GATEWAY_URL%/}"
18
- export SC_DLR_ENABLED=true
19
- export SC_MODEL="$MODEL"
20
-
21
- exec marathon "$@"
@@ -1,100 +0,0 @@
1
- // Windows-only equivalent of the existing Claude shell launch.
2
- import { readFileSync } from 'node:fs';
3
- import { resolvedModelSetting } from '../profiles.js';
4
- import { parseOptions, positiveInteger } from './common.js';
5
-
6
- const DEFAULTS = JSON.parse(
7
- readFileSync(new URL('../registry.generated.json', import.meta.url), 'utf8'),
8
- ).defaults;
9
- function claudePickerSettings(models) {
10
- return {
11
- availableModels: models,
12
- modelPicker: {
13
- replaceBuiltInOptions: true,
14
- options: models.map((model) => ({
15
- model,
16
- label: model,
17
- description: `Subconscious model ${model}`,
18
- })),
19
- },
20
- };
21
- }
22
-
23
- export function claudeNativeLaunch(argv, environment) {
24
- const { options, rest: passthrough } = parseOptions(argv, {
25
- '--gateway-url': 1,
26
- '--api-key': 1,
27
- '--model': 1,
28
- '--compact-window': 1,
29
- '--max-context-tokens': 1,
30
- });
31
- const gatewayUrl =
32
- options['--gateway-url'] || environment.GATEWAY_URL?.trim() || '';
33
- const apiKey =
34
- options['--api-key'] ||
35
- environment.CLAUDE_CODE_API_KEY?.trim() ||
36
- environment.API_KEY?.trim() ||
37
- '';
38
- const model =
39
- options['--model'] || environment.MODEL?.trim() || DEFAULTS.model;
40
- const compactWindow =
41
- options['--compact-window'] ||
42
- environment.CLAUDE_CODE_AUTO_COMPACT_WINDOW?.trim() ||
43
- environment.COMPACT_WINDOW?.trim() ||
44
- '1000000';
45
- const maxContextTokens =
46
- options['--max-context-tokens'] ||
47
- environment.CLAUDE_CODE_MAX_CONTEXT_TOKENS?.trim() ||
48
- environment.MAX_CONTEXT_TOKENS?.trim() ||
49
- '3000000';
50
-
51
- if (!gatewayUrl || !apiKey) {
52
- throw new Error(
53
- 'GATEWAY_URL and API_KEY are required to launch Claude Code',
54
- );
55
- }
56
- positiveInteger(compactWindow, 'compact-window');
57
- positiveInteger(maxContextTokens, 'max-context-tokens');
58
-
59
- const effectiveGatewayUrl =
60
- environment.CLAUDE_GATEWAY_URL?.trim() || gatewayUrl;
61
- const subagentModel =
62
- resolvedModelSetting(environment.CLAUDE_CODE_SUBAGENT_MODEL) || model;
63
- const settings =
64
- environment.SUBC_CLAUDE_SETTINGS?.trim() ||
65
- JSON.stringify(claudePickerSettings([model], model));
66
- const withoutTrailingSlash = effectiveGatewayUrl.replace(/\/+$/, '');
67
- const env = {
68
- ...environment,
69
- ANTHROPIC_BASE_URL: effectiveGatewayUrl,
70
- ANTHROPIC_AUTH_TOKEN: apiKey,
71
- ANTHROPIC_MODEL: environment.ANTHROPIC_MODEL?.trim() || model,
72
- ANTHROPIC_SMALL_FAST_MODEL:
73
- environment.ANTHROPIC_SMALL_FAST_MODEL?.trim() || model,
74
- CLAUDE_CODE_ENABLE_GATEWAY_MODEL_DISCOVERY:
75
- environment.CLAUDE_CODE_ENABLE_GATEWAY_MODEL_DISCOVERY?.trim() || '0',
76
- CLAUDE_CODE_SUBAGENT_MODEL: subagentModel,
77
- CLAUDE_CODE_MAX_CONCURRENT_SUBAGENTS:
78
- environment.MAX_CONCURRENT_SUBAGENTS?.trim() || '4',
79
- CLAUDE_CODE_MAX_SUBAGENT_SPAWN_DEPTH:
80
- environment.MAX_SUBAGENT_SPAWN_DEPTH?.trim() || '1',
81
- CLAUDE_CODE_AUTO_COMPACT_WINDOW: compactWindow,
82
- CLAUDE_CODE_MAX_CONTEXT_TOKENS: maxContextTokens,
83
- CLAUDE_CODE_ENABLE_TELEMETRY:
84
- environment.CLAUDE_CODE_ENABLE_TELEMETRY?.trim() || '1',
85
- CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC:
86
- environment.CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC?.trim() || '1',
87
- ENABLE_CLAUDEAI_MCP_SERVERS: 'false',
88
- OTEL_LOGS_EXPORTER: environment.OTEL_LOGS_EXPORTER?.trim() || 'otlp',
89
- OTEL_EXPORTER_OTLP_PROTOCOL:
90
- environment.OTEL_EXPORTER_OTLP_PROTOCOL?.trim() || 'http/json',
91
- OTEL_EXPORTER_OTLP_LOGS_ENDPOINT: `${withoutTrailingSlash}/v1/logs`,
92
- OTEL_EXPORTER_OTLP_HEADERS: `x-api-key=${apiKey}`,
93
- OTEL_EXPORTER_OTLP_TIMEOUT:
94
- environment.OTEL_EXPORTER_OTLP_TIMEOUT?.trim() || '2000',
95
- OTEL_LOGS_EXPORT_INTERVAL:
96
- environment.OTEL_LOGS_EXPORT_INTERVAL?.trim() || '2000',
97
- };
98
-
99
- return { args: ['--settings', settings, ...passthrough], env };
100
- }