subconscious-cli 0.3.0 → 0.3.1

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.
@@ -16,7 +16,7 @@
16
16
  # Equivalent manual setup (three pieces):
17
17
  #
18
18
  # 1. Cursor settings → enable "OpenAI API Key Override":
19
- # Base URL: https://your-gateway.example
19
+ # Base URL: https://your-gateway.example/v1
20
20
  # API Key: sk-gw-...
21
21
  #
22
22
  # 2. Write ~/.cursor/hooks.json pointing at the hook script:
@@ -46,28 +46,44 @@ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
46
46
  HOOK_SRC="${SCRIPT_DIR}/hook.sh"
47
47
  HOOKS_TEMPLATE="${SCRIPT_DIR}/hooks.json"
48
48
 
49
- # Load shared env from coding-agents/.env (gitignored) or env.example.
50
- SHARED_ENV="${MBTA_ENV_FILE:-${SCRIPT_DIR}/../.env}"
49
+ # Load shared env from SUBC_ENV_FILE, or a sibling .env / env.example.
50
+ SHARED_ENV="${SUBC_ENV_FILE:-${SCRIPT_DIR}/../.env}"
51
51
  [[ -f "$SHARED_ENV" ]] || SHARED_ENV="${SCRIPT_DIR}/../env.example"
52
52
  if [[ -f "$SHARED_ENV" ]]; then set -a; source "$SHARED_ENV"; set +a; fi
53
53
 
54
54
  GATEWAY_URL="${GATEWAY_URL:-}"
55
55
  API_KEY="${CURSOR_API_KEY:-${API_KEY:-}}"
56
+ MODEL="${MODEL:-subconscious/glm-5.2}"
56
57
  COMMAND="install"
57
58
 
59
+ DEFAULT_SUBCONSCIOUS_MODELS="subconscious/glm-5.2
60
+ subconscious/tim-qwen3.6-27b
61
+ subconscious/deepseek-v4-flash-marathon"
62
+
63
+ SUPPORTED_MODELS=()
64
+ add_supported_model() {
65
+ local model_id="$1"
66
+ for existing in "${SUPPORTED_MODELS[@]:-}"; do
67
+ [[ "$existing" == "$model_id" ]] && return
68
+ done
69
+ SUPPORTED_MODELS+=("$model_id")
70
+ }
71
+ add_supported_model "$MODEL"
72
+ while IFS= read -r model_id; do
73
+ [[ -n "$model_id" ]] && add_supported_model "$model_id"
74
+ done <<< "${SUBCONSCIOUS_MODELS:-$DEFAULT_SUBCONSCIOUS_MODELS}"
75
+
58
76
  usage() {
59
77
  cat <<'EOF'
60
78
  Usage:
61
- install.sh [install] --gateway-url URL --api-key KEY
62
- install.sh uninstall
63
- install.sh status
64
-
65
- `install` is the default subcommand and may be omitted.
79
+ subc cursor install [--gateway-url URL] [--api-key KEY]
80
+ subc cursor uninstall
81
+ subc cursor status
66
82
 
67
83
  Installs Cursor hooks (user-wide under ~/.cursor) that POST to /v1/agent-hooks:
68
84
  conversation_ensure on each prompt submission so the gateway can group
69
85
  Conversations for Cursor traffic, and conversation_compaction on preCompact so
70
- context accounting restarts at the right turn.
86
+ context accounting restarts at the right turn. Existing hook entries are kept.
71
87
 
72
88
  Requires: jq, curl. Restart Cursor after install.
73
89
  EOF
@@ -121,7 +137,7 @@ require_cmds() {
121
137
  write_env() {
122
138
  umask 077
123
139
  cat >"$ENV_FILE" <<EOF
124
- # Generated by ol-runbook/coding-agents/cursor/install.sh — do not commit secrets.
140
+ # Generated by subc — do not commit secrets.
125
141
  export SUBCONSCIOUS_GATEWAY_URL='${GATEWAY_URL}'
126
142
  export SUBCONSCIOUS_API_KEY='${API_KEY}'
127
143
  EOF
@@ -247,7 +263,16 @@ case "$COMMAND" in
247
263
  write_env
248
264
  merge_hooks_json
249
265
  echo "Installed Subconscious Cursor hooks into $CURSOR_DIR"
250
- echo "Restart Cursor to reload hooks.json."
266
+ echo ""
267
+ echo "Finish in Cursor Settings"
268
+ echo " Enable OpenAI API Key Override, then use:"
269
+ echo " Base URL: ${GATEWAY_URL%/}/v1"
270
+ echo " Add the available custom models:"
271
+ for model_id in "${SUPPORTED_MODELS[@]}"; do
272
+ echo " ${model_id}"
273
+ done
274
+ echo " Select ${MODEL} for this profile."
275
+ echo " Paste your Subconscious API key there, then fully restart Cursor."
251
276
  ;;
252
277
  uninstall)
253
278
  uninstall_hooks
@@ -55,8 +55,8 @@ set -euo pipefail
55
55
 
56
56
  SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
57
57
 
58
- # Load shared env from coding-agents/.env (gitignored) or env.example.
59
- SHARED_ENV="${MBTA_ENV_FILE:-${SCRIPT_DIR}/../.env}"
58
+ # Load shared env from SUBC_ENV_FILE, or a sibling .env / env.example.
59
+ SHARED_ENV="${SUBC_ENV_FILE:-${SCRIPT_DIR}/../.env}"
60
60
  [[ -f "$SHARED_ENV" ]] || SHARED_ENV="${SCRIPT_DIR}/../env.example"
61
61
  if [[ -f "$SHARED_ENV" ]]; then set -a; source "$SHARED_ENV"; set +a; fi
62
62
 
@@ -72,23 +72,12 @@ OUTPUT_LIMIT="${OPENCODE_OUTPUT_LIMIT:-65536}"
72
72
  usage() {
73
73
  cat <<'EOF'
74
74
  Usage:
75
- install.sh [install] --gateway-url URL --api-key KEY [--model MODEL]
76
- [--context-limit N] [--output-limit N]
77
- install.sh uninstall
78
- install.sh status
75
+ subc opencode status
76
+ subc opencode uninstall
77
+ subc opencode help
79
78
 
80
- `install` is the default subcommand and may be omitted.
81
-
82
- Writes an opencode.json that points opencode at your Subconscious gateway with
83
- x-subconscious-client: opencode and x-session-affinity/x-session-id session
84
- headers so the gateway can group requests into Conversations.
85
-
86
- Also sets model limit.context / limit.output so OpenCode auto-compaction
87
- respects the gateway window (compaction.auto stays enabled / default), and
88
- installs a plugin that reports compactions so the dashboard can restart context
89
- accounting at the right turn.
90
-
91
- Requires: jq. Restart opencode after install.
79
+ OpenCode is launch-only: subc opencode. Uninstall removes only the Subconscious
80
+ provider, plugin, and env file. It does not delete ~/.opencode/opencode.json.
92
81
  EOF
93
82
  }
94
83
 
@@ -190,35 +179,40 @@ require_cmds() {
190
179
  write_config() {
191
180
  mkdir -p "$OPENCODE_DIR"
192
181
  local base_url="${GATEWAY_URL%/}/v1"
193
- local config
194
- config=$(cat <<EOF
182
+ local provider
183
+ provider=$(cat <<EOF
195
184
  {
196
- "\$schema": "https://opencode.ai/config.json",
197
- "provider": {
198
- "subconscious": {
199
- "npm": "@ai-sdk/openai-compatible",
200
- "name": "Subconscious Gateway",
201
- "options": {
202
- "baseURL": "${base_url}",
203
- "apiKey": "{env:SUBCONSCIOUS_API_KEY}",
204
- "headers": {
205
- "x-subconscious-client": "opencode"
206
- }
207
- },
208
- "models": {${MODELS_JSON}}
185
+ "npm": "@ai-sdk/openai-compatible",
186
+ "name": "Subconscious Gateway",
187
+ "options": {
188
+ "baseURL": "${base_url}",
189
+ "apiKey": "{env:SUBCONSCIOUS_API_KEY}",
190
+ "headers": {
191
+ "x-subconscious-client": "opencode"
209
192
  }
210
193
  },
211
- "model": "subconscious/${MODEL}"
194
+ "models": {${MODELS_JSON}}
212
195
  }
213
196
  EOF
214
197
  )
215
- echo "$config" >"$OPENCODE_CONFIG"
216
- # Also export the API key into the shell env file for interactive sessions. The plugin
217
- # reads the gateway URL from the same file.
198
+ if [[ -f "$OPENCODE_CONFIG" ]]; then
199
+ local tmp
200
+ tmp="$(mktemp)"
201
+ jq --argjson provider "$provider" --arg model "subconscious/${MODEL}" '
202
+ .provider = (.provider // {})
203
+ | .provider.subconscious = $provider
204
+ | .model = $model
205
+ ' "$OPENCODE_CONFIG" >"$tmp"
206
+ mv "$tmp" "$OPENCODE_CONFIG"
207
+ else
208
+ jq -n --argjson provider "$provider" --arg model "subconscious/${MODEL}" \
209
+ '{ "$schema": "https://opencode.ai/config.json", provider: {subconscious: $provider}, model: $model }' \
210
+ >"$OPENCODE_CONFIG"
211
+ fi
218
212
  local env_file="${OPENCODE_DIR}/subconscious.env"
219
213
  umask 077
220
214
  cat >"$env_file" <<EOF
221
- # Generated by ol-runbook/coding-agents/opencode/install.sh — do not commit secrets.
215
+ # Generated by subc — do not commit secrets.
222
216
  export SUBCONSCIOUS_API_KEY='${API_KEY}'
223
217
  export SUBCONSCIOUS_GATEWAY_URL='${GATEWAY_URL%/}'
224
218
  EOF
@@ -235,8 +229,17 @@ write_plugin() {
235
229
  }
236
230
 
237
231
  uninstall_config() {
238
- if [[ -f "$OPENCODE_CONFIG" ]] && grep -q "$MARKER" "$OPENCODE_CONFIG" 2>/dev/null; then
239
- rm -f "$OPENCODE_CONFIG"
232
+ if [[ -f "$OPENCODE_CONFIG" ]]; then
233
+ local tmp
234
+ tmp="$(mktemp)"
235
+ jq '
236
+ del(.provider.subconscious)
237
+ | if ((.model // "") | tostring | startswith("subconscious/")) then del(.model) else . end
238
+ ' "$OPENCODE_CONFIG" >"$tmp"
239
+ mv "$tmp" "$OPENCODE_CONFIG"
240
+ echo "Removed Subconscious provider from $OPENCODE_CONFIG"
241
+ else
242
+ echo "No OpenCode config at $OPENCODE_CONFIG"
240
243
  fi
241
244
  rm -f "${OPENCODE_DIR}/subconscious.env"
242
245
  rm -f "$PLUGIN_FILE"
@@ -279,18 +282,15 @@ case "$COMMAND" in
279
282
  fi
280
283
  write_config
281
284
  write_plugin
282
- echo "Installed Subconscious OpenCode config at $OPENCODE_CONFIG"
285
+ echo "Merged Subconscious OpenCode provider into $OPENCODE_CONFIG"
283
286
  if [[ -f "$PLUGIN_FILE" ]]; then
284
287
  echo "Installed compaction reporting plugin at $PLUGIN_FILE"
285
288
  fi
286
- echo "Source the env file before launching opencode:"
287
- echo " source ${OPENCODE_DIR}/subconscious.env"
288
- echo "Or export SUBCONSCIOUS_API_KEY in your shell profile."
289
- echo "Restart any running opencode sessions."
289
+ echo "Launch OpenCode with: subc opencode"
290
290
  ;;
291
291
  uninstall)
292
292
  uninstall_config
293
- echo "Removed Subconscious OpenCode config from $OPENCODE_DIR"
293
+ echo "Removed Subconscious OpenCode files; left $OPENCODE_CONFIG in place"
294
294
  ;;
295
295
  status)
296
296
  status
@@ -10,7 +10,7 @@
10
10
  # ./run.sh -- auth # pass args through to opencode
11
11
  #
12
12
  # Config: copy ../env.example to ../.env and edit. .env is gitignored.
13
- # All agents share one coding-agents/.env file.
13
+ # Profile env is injected by subc. A sibling .env is only used when SUBC_ENV_FILE is unset.
14
14
  #
15
15
  # Or source it to just export the env:
16
16
  # source run.sh
@@ -19,8 +19,8 @@ set -euo pipefail
19
19
 
20
20
  SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
21
21
 
22
- # Load shared env from coding-agents/.env (gitignored) or env.example.
23
- SHARED_ENV="${MBTA_ENV_FILE:-${SCRIPT_DIR}/../.env}"
22
+ # Load shared env from SUBC_ENV_FILE, or a sibling .env / env.example.
23
+ SHARED_ENV="${SUBC_ENV_FILE:-${SCRIPT_DIR}/../.env}"
24
24
  [[ -f "$SHARED_ENV" ]] || SHARED_ENV="${SCRIPT_DIR}/../env.example"
25
25
  if [[ -f "$SHARED_ENV" ]]; then set -a; source "$SHARED_ENV"; set +a; fi
26
26
 
@@ -91,8 +91,7 @@ fi
91
91
  BASE_URL="${GATEWAY_URL%/}/v1"
92
92
 
93
93
  export SUBCONSCIOUS_API_KEY="$API_KEY"
94
- # Read by the compaction plugin when it is installed. run.sh writes nothing to disk, so
95
- # use install.sh if you want compaction reporting.
94
+ # Compaction reporting needs the plugin on disk; this launch path writes nothing.
96
95
  export SUBCONSCIOUS_GATEWAY_URL="${GATEWAY_URL%/}"
97
96
  export OPENCODE_CONFIG_CONTENT=$(cat <<EOF
98
97
  {"\$schema":"https://opencode.ai/config.json","provider":{"subconscious":{"npm":"@ai-sdk/openai-compatible","name":"Subconscious Gateway","options":{"baseURL":"${BASE_URL}","apiKey":"{env:SUBCONSCIOUS_API_KEY}","headers":{"x-subconscious-client":"opencode"}},"models":{${MODELS_JSON}}}},"model":"subconscious/${MODEL}"}
@@ -49,8 +49,8 @@ set -euo pipefail
49
49
  SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
50
50
  EXTENSION_SRC="${SCRIPT_DIR}/subconscious-compaction.ts"
51
51
 
52
- # Load shared env from coding-agents/.env (gitignored) or env.example.
53
- SHARED_ENV="${MBTA_ENV_FILE:-${SCRIPT_DIR}/../.env}"
52
+ # Load shared env from SUBC_ENV_FILE, or a sibling .env / env.example.
53
+ SHARED_ENV="${SUBC_ENV_FILE:-${SCRIPT_DIR}/../.env}"
54
54
  [[ -f "$SHARED_ENV" ]] || SHARED_ENV="${SCRIPT_DIR}/../env.example"
55
55
  if [[ -f "$SHARED_ENV" ]]; then set -a; source "$SHARED_ENV"; set +a; fi
56
56
 
@@ -64,26 +64,13 @@ MAX_TOKENS="${PI_MAX_TOKENS:-65536}"
64
64
  usage() {
65
65
  cat <<'EOF'
66
66
  Usage:
67
- install.sh [install] --gateway-url URL --api-key KEY [--model MODEL]
67
+ subc pi install [--gateway-url URL] [--api-key KEY] [--model MODEL]
68
68
  [--context-window N] [--max-tokens N]
69
- install.sh uninstall
70
- install.sh status
69
+ subc pi uninstall
70
+ subc pi status
71
71
 
72
- `install` is the default subcommand and may be omitted.
73
-
74
- Writes a models.json that points Pi at your Subconscious gateway with
75
- x-subconscious-client: pi and session-affinity headers enabled so the gateway
76
- can group requests into Conversations.
77
-
78
- Also sets model contextWindow (default 5000000) so Pi auto-compaction
79
- (`contextTokens > contextWindow - reserveTokens`) respects the gateway window,
80
- and installs an extension that reports compactions so the dashboard can restart
81
- context accounting at the right turn.
82
-
83
- Pi does not send session headers by default; this script enables
84
- sendSessionAffinityHeaders with sessionAffinityFormat "openai-nosession"
85
- (sends x-session-affinity without the underscore session_id header that
86
- strict proxies may drop).
72
+ Merges a Subconscious provider into ~/.pi/agent/models.json without replacing
73
+ other providers. Launch Pi with subc pi after install.
87
74
 
88
75
  Requires: jq. Restart Pi after install (or /reload for the extension).
89
76
  EOF
@@ -115,7 +102,7 @@ while [[ $# -gt 0 ]]; do
115
102
  MAX_TOKENS="${2:-}"
116
103
  shift 2
117
104
  ;;
118
- -h|--help)
105
+ -h|--help|help)
119
106
  usage
120
107
  exit 0
121
108
  ;;
@@ -185,29 +172,35 @@ require_cmds() {
185
172
  write_config() {
186
173
  mkdir -p "$PI_DIR"
187
174
  local base_url="${GATEWAY_URL%/}/v1"
188
- local config
189
- config=$(cat <<EOF
175
+ local provider
176
+ provider=$(cat <<EOF
190
177
  {
191
- "providers": {
192
- "subconscious": {
193
- "baseUrl": "${base_url}",
194
- "api": "openai-completions",
195
- "apiKey": "${API_KEY}",
196
- "headers": {
197
- "x-subconscious-client": "pi"
198
- },
199
- "models": [${MODEL_ENTRIES_JSON}]
200
- }
201
- }
178
+ "baseUrl": "${base_url}",
179
+ "api": "openai-completions",
180
+ "apiKey": "${API_KEY}",
181
+ "headers": {
182
+ "x-subconscious-client": "pi"
183
+ },
184
+ "models": [${MODEL_ENTRIES_JSON}]
202
185
  }
203
186
  EOF
204
187
  )
205
- echo "$config" >"$MODELS_JSON"
188
+ if [[ -f "$MODELS_JSON" ]]; then
189
+ local tmp
190
+ tmp="$(mktemp)"
191
+ jq --argjson provider "$provider" '
192
+ .providers = (.providers // {})
193
+ | .providers.subconscious = $provider
194
+ ' "$MODELS_JSON" >"$tmp"
195
+ mv "$tmp" "$MODELS_JSON"
196
+ else
197
+ jq -n --argjson provider "$provider" '{providers: {subconscious: $provider}}' >"$MODELS_JSON"
198
+ fi
206
199
  chmod 600 "$MODELS_JSON"
207
200
 
208
201
  umask 077
209
202
  cat >"$ENV_FILE" <<EOF
210
- # Generated by ol-runbook/coding-agents/pi/install.sh — do not commit secrets.
203
+ # Generated by subc — do not commit secrets.
211
204
  # Loaded by subconscious-compaction.ts if process env is unset.
212
205
  export SUBCONSCIOUS_GATEWAY_URL='${GATEWAY_URL%/}'
213
206
  export SUBCONSCIOUS_API_KEY='${API_KEY}'
@@ -225,11 +218,14 @@ write_extension() {
225
218
  }
226
219
 
227
220
  uninstall_config() {
228
- if [[ -f "$MODELS_JSON" ]] && grep -q "$MARKER" "$MODELS_JSON" 2>/dev/null; then
229
- rm -f "$MODELS_JSON"
230
- echo "Removed $MODELS_JSON"
221
+ if [[ -f "$MODELS_JSON" ]]; then
222
+ local tmp
223
+ tmp="$(mktemp)"
224
+ jq 'del(.providers.subconscious)' "$MODELS_JSON" >"$tmp"
225
+ mv "$tmp" "$MODELS_JSON"
226
+ echo "Removed Subconscious provider from $MODELS_JSON"
231
227
  else
232
- echo "No Subconscious Pi config found at $MODELS_JSON"
228
+ echo "No Pi models.json at $MODELS_JSON"
233
229
  fi
234
230
  rm -f "$EXTENSION_DST" "$ENV_FILE"
235
231
  }
@@ -266,7 +262,7 @@ case "$COMMAND" in
266
262
  fi
267
263
  write_config
268
264
  write_extension
269
- echo "Installed Subconscious Pi config at $MODELS_JSON"
265
+ echo "Merged Subconscious Pi provider into $MODELS_JSON"
270
266
  if [[ -f "$EXTENSION_DST" ]]; then
271
267
  echo "Installed compaction reporting extension at $EXTENSION_DST"
272
268
  fi
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env bash
2
- # Launch Pi with the Subconscious provider configured by `subc setup`.
2
+ # Launch Pi with the Subconscious provider configured by `subc pi install`.
3
3
  # This script is deliberately read-only: it never installs Pi, writes config,
4
4
  # or updates the persistent integration.
5
5
 
@@ -10,7 +10,7 @@ PI_DIR="${PI_CODING_AGENT_DIR:-${HOME}/.pi/agent}"
10
10
  MODELS_JSON="${PI_DIR}/models.json"
11
11
 
12
12
  if [[ ! -f "$MODELS_JSON" ]] || ! grep -q 'x-subconscious-client' "$MODELS_JSON" 2>/dev/null; then
13
- echo "Pi is not configured for Subconscious. Run 'subc setup' first." >&2
13
+ echo "Pi is not configured for Subconscious. Run 'subc pi install' first." >&2
14
14
  exit 1
15
15
  fi
16
16
 
@@ -18,7 +18,7 @@ if command -v jq >/dev/null 2>&1 && ! jq -e \
18
18
  --arg model "$MODEL" \
19
19
  '.providers.subconscious.models[]? | select(.id == $model)' \
20
20
  "$MODELS_JSON" >/dev/null 2>&1; then
21
- echo "Model '$MODEL' is not present in the Pi catalog. Run 'subc setup' to refresh it." >&2
21
+ echo "Model '$MODEL' is not present in the Pi catalog. Run 'subc pi install' to refresh it." >&2
22
22
  exit 1
23
23
  fi
24
24
 
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "subconscious-cli",
3
- "version": "0.3.0",
4
- "description": "CLI for Subconscious — run Claude Code, Codex, OpenCode, Cursor, Copilot, and Pi with ol-runbook integrations",
3
+ "version": "0.3.1",
4
+ "description": "CLI for Subconscious — run Claude Code, Codex, OpenCode, Cursor, Copilot, and Pi",
5
5
  "bin": {
6
6
  "subc": "./bin/cli.js"
7
7
  },