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.
- package/README.md +65 -93
- package/bin/agents.js +119 -87
- package/bin/auth.js +25 -7
- package/bin/cli.js +135 -85
- package/bin/profiles.js +129 -199
- package/bin/registry.generated.json +40 -12
- package/bin/runbook/README.md +12 -15
- package/bin/runbook/claude-code/install.sh +18 -44
- package/bin/runbook/claude-code/run.sh +21 -21
- package/bin/runbook/codex/hook.sh +1 -1
- package/bin/runbook/codex/hooks-lib.sh +139 -0
- package/bin/runbook/codex/install.sh +21 -463
- package/bin/runbook/codex/run.sh +7 -23
- package/bin/runbook/copilot/install.sh +9 -8
- package/bin/runbook/cursor/install.sh +36 -11
- package/bin/runbook/opencode/install.sh +46 -46
- package/bin/runbook/opencode/run.sh +4 -5
- package/bin/runbook/pi/install.sh +37 -41
- package/bin/runbook/pi/run.sh +3 -3
- package/package.json +2 -2
|
@@ -1,145 +1,44 @@
|
|
|
1
1
|
#!/usr/bin/env bash
|
|
2
|
-
# ── Subconscious API Gateway — Codex
|
|
3
|
-
#
|
|
4
|
-
#
|
|
2
|
+
# ── Subconscious API Gateway — Codex hooks ────────────────────────────────────
|
|
3
|
+
# Merge Subconscious compaction hooks into ~/.codex/hooks.json without touching
|
|
4
|
+
# ~/.codex/config.toml. Launch Codex with `subc codex`.
|
|
5
5
|
#
|
|
6
|
-
#
|
|
7
|
-
#
|
|
8
|
-
#
|
|
9
|
-
# ./install.sh use -- --resume # pass args through to codex
|
|
10
|
-
#
|
|
11
|
-
# Or source env into your shell:
|
|
12
|
-
# source <(./install.sh env) # load SUBCONSCIOUS_API_KEY
|
|
13
|
-
# source <(./install.sh unset) # remove SUBCONSCIOUS_API_KEY
|
|
14
|
-
#
|
|
15
|
-
# ./install.sh status # show current config
|
|
16
|
-
# ./install.sh uninstall # remove config + env file
|
|
17
|
-
#
|
|
18
|
-
# ── Subagents ─────────────────────────────────────────────────────────────────
|
|
19
|
-
# Subagents are OFF by default. Current Codex releases (>=0.144) wrap subagent
|
|
20
|
-
# tools in a `type: "namespace"` wire format that non-OpenAI providers can't
|
|
21
|
-
# resolve, causing "unsupported call: spawn_agent" errors (upstream #32318,
|
|
22
|
-
# #26977, #17598). The fix (PR #29602) is not yet merged.
|
|
23
|
-
#
|
|
24
|
-
# To use subagents, install the legacy Codex 0.132.0 which uses the older
|
|
25
|
-
# multi-agent v1 config with plain tool names:
|
|
26
|
-
#
|
|
27
|
-
# ./install.sh --subagents --gateway-url ... --api-key ...
|
|
28
|
-
#
|
|
29
|
-
# This pins `codex@0.132.0` and writes the legacy agents config:
|
|
30
|
-
#
|
|
31
|
-
# [features]
|
|
32
|
-
# multi_agent = true
|
|
33
|
-
#
|
|
34
|
-
# [agents]
|
|
35
|
-
# max_threads = 4
|
|
36
|
-
# max_depth = 1
|
|
37
|
-
# interrupt_message = true
|
|
38
|
-
#
|
|
39
|
-
# ── What this does under the hood ────────────────────────────────────────────
|
|
40
|
-
# Equivalent manual setup (writes ~/.codex/config.toml + model catalog + env):
|
|
41
|
-
#
|
|
42
|
-
# export SUBCONSCIOUS_API_KEY=sk-gw-...
|
|
43
|
-
# cat > ~/.codex/model-catalog.json <<'EOF'
|
|
44
|
-
# { "models": [{ ... }] }
|
|
45
|
-
# EOF
|
|
46
|
-
#
|
|
47
|
-
# cat > ~/.codex/config.toml <<'EOF'
|
|
48
|
-
# model = "subconscious/glm-5.2"
|
|
49
|
-
# model_provider = "subconscious"
|
|
50
|
-
# model_catalog_json = "~/.codex/model-catalog.json"
|
|
51
|
-
# web_search = "disabled"
|
|
52
|
-
#
|
|
53
|
-
# [model_providers.subconscious]
|
|
54
|
-
# name = "Subconscious Gateway"
|
|
55
|
-
# base_url = "https://your-gateway.example/v1"
|
|
56
|
-
# wire_api = "responses"
|
|
57
|
-
# env_key = "SUBCONSCIOUS_API_KEY"
|
|
58
|
-
# stream_idle_timeout_ms = 300000
|
|
59
|
-
# EOF
|
|
60
|
-
# codex
|
|
61
|
-
#
|
|
62
|
-
# Codex natively sends thread-id / session-id / x-codex-turn-metadata headers
|
|
63
|
-
# so the gateway can group requests into Conversations.
|
|
64
|
-
#
|
|
65
|
-
# Also installs ~/.codex/hooks.json + hook script that report PreCompact /
|
|
66
|
-
# PostCompact to /v1/agent-hooks so summarization turns (local compaction path
|
|
67
|
-
# for custom providers) are billed as compaction. After install, trust the
|
|
68
|
-
# hooks in Codex with /hooks (or --dangerously-bypass-hook-trust for one-offs).
|
|
69
|
-
# Docs: https://developers.openai.com/codex/hooks
|
|
6
|
+
# subc codex install # merge hooks
|
|
7
|
+
# subc codex status
|
|
8
|
+
# subc codex uninstall # strip only Subconscious hook entries
|
|
70
9
|
# ─────────────────────────────────────────────────────────────────────────────
|
|
71
10
|
|
|
72
11
|
set -euo pipefail
|
|
73
12
|
|
|
74
13
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
75
14
|
HOOK_SRC="${SCRIPT_DIR}/hook.sh"
|
|
76
|
-
HOOKS_TEMPLATE="${SCRIPT_DIR}/hooks.json"
|
|
77
15
|
|
|
78
|
-
|
|
79
|
-
SHARED_ENV="${MBTA_ENV_FILE:-${SCRIPT_DIR}/../.env}"
|
|
16
|
+
SHARED_ENV="${SUBC_ENV_FILE:-${SCRIPT_DIR}/../.env}"
|
|
80
17
|
[[ -f "$SHARED_ENV" ]] || SHARED_ENV="${SCRIPT_DIR}/../env.example"
|
|
81
18
|
if [[ -f "$SHARED_ENV" ]]; then set -a; source "$SHARED_ENV"; set +a; fi
|
|
82
19
|
|
|
20
|
+
# shellcheck source=hooks-lib.sh
|
|
21
|
+
source "${SCRIPT_DIR}/hooks-lib.sh"
|
|
22
|
+
|
|
83
23
|
COMMAND="install"
|
|
84
24
|
GATEWAY_URL="${GATEWAY_URL:-}"
|
|
85
25
|
API_KEY="${CODEX_API_KEY:-${API_KEY:-}}"
|
|
86
|
-
MODEL="${MODEL:-subconscious/glm-5.2}"
|
|
87
|
-
SUBAGENTS=false
|
|
88
|
-
EXTERNAL_TOOLS="${CODEX_EXTERNAL_TOOLS:-false}"
|
|
89
|
-
MAX_CONCURRENT_SUBAGENTS="${MAX_CONCURRENT_SUBAGENTS:-4}"
|
|
90
|
-
CODEX_CONTEXT_WINDOW="${CODEX_CONTEXT_WINDOW:-5000000}"
|
|
91
|
-
# Empty means "same as context window" after CLI/env resolution.
|
|
92
|
-
CODEX_MAX_CONTEXT_WINDOW="${CODEX_MAX_CONTEXT_WINDOW:-}"
|
|
93
|
-
CODEX_AUTO_COMPACT_TOKEN_LIMIT="${CODEX_AUTO_COMPACT_TOKEN_LIMIT:-4500000}"
|
|
94
|
-
CODEX_REASONING_EFFORT="${CODEX_REASONING_EFFORT:-max}"
|
|
95
|
-
|
|
96
|
-
# Codex version that supports the legacy multi-agent v1 config (plain tool names).
|
|
97
|
-
SUBAGENT_CODEX_VERSION="0.132.0"
|
|
98
26
|
|
|
99
27
|
usage() {
|
|
100
28
|
cat <<'EOF'
|
|
101
29
|
Usage:
|
|
102
|
-
install
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
[--auto-compact-token-limit N]
|
|
106
|
-
install.sh use [-- CODEX_ARGS...]
|
|
107
|
-
install.sh env
|
|
108
|
-
install.sh unset
|
|
109
|
-
install.sh uninstall
|
|
110
|
-
install.sh status
|
|
111
|
-
|
|
112
|
-
`install` is the default subcommand and may be omitted.
|
|
113
|
-
|
|
114
|
-
Commands:
|
|
115
|
-
install Write ~/.codex/config.toml + ~/.codex/subconscious.env
|
|
116
|
-
use Source the env file and exec codex (pass -- followed by codex args)
|
|
117
|
-
env Print export lines for sourcing: source <(./install.sh env)
|
|
118
|
-
unset Print unset lines for sourcing: source <(./install.sh unset)
|
|
119
|
-
uninstall Remove the config and env file
|
|
120
|
-
status Show current configuration
|
|
30
|
+
subc codex install [--gateway-url URL] [--api-key KEY]
|
|
31
|
+
subc codex status
|
|
32
|
+
subc codex uninstall
|
|
121
33
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
--api-key KEY Gateway API key (sk-gw-...)
|
|
125
|
-
--model MODEL Model name (default: subconscious/glm-5.2)
|
|
126
|
-
--context-window N Catalog context_window (default: 5000000 / CODEX_CONTEXT_WINDOW)
|
|
127
|
-
--max-context-window N Catalog max_context_window (default: same as context window)
|
|
128
|
-
--auto-compact-token-limit N Catalog auto_compact_token_limit (default: 4500000)
|
|
129
|
-
--reasoning-effort LEVEL Reasoning effort: none, low, medium, high, or max
|
|
130
|
-
(default: max)
|
|
131
|
-
--subagents Enable subagents (pins codex@0.132.0, writes legacy
|
|
132
|
-
multi-agent v1 config with plain tool names)
|
|
133
|
-
--external-tools Enable Codex apps/plugins (off by default to stay
|
|
134
|
-
below the gateway's 128-tool request limit)
|
|
135
|
-
--max-concurrent-subagents N Max concurrent subagent threads (default: 4,
|
|
136
|
-
only used with --subagents)
|
|
34
|
+
Merges Subconscious compaction hooks into ~/.codex/hooks.json. Does not write
|
|
35
|
+
config.toml. Launch Codex with subc codex.
|
|
137
36
|
EOF
|
|
138
37
|
}
|
|
139
38
|
|
|
140
39
|
while [[ $# -gt 0 ]]; do
|
|
141
40
|
case "$1" in
|
|
142
|
-
install|
|
|
41
|
+
install|uninstall|status)
|
|
143
42
|
COMMAND="$1"
|
|
144
43
|
shift
|
|
145
44
|
;;
|
|
@@ -152,38 +51,9 @@ while [[ $# -gt 0 ]]; do
|
|
|
152
51
|
shift 2
|
|
153
52
|
;;
|
|
154
53
|
--model)
|
|
155
|
-
MODEL="${2:-}"
|
|
156
|
-
shift 2
|
|
157
|
-
;;
|
|
158
|
-
--context-window)
|
|
159
|
-
CODEX_CONTEXT_WINDOW="${2:-}"
|
|
160
54
|
shift 2
|
|
161
55
|
;;
|
|
162
|
-
|
|
163
|
-
CODEX_MAX_CONTEXT_WINDOW="${2:-}"
|
|
164
|
-
shift 2
|
|
165
|
-
;;
|
|
166
|
-
--auto-compact-token-limit)
|
|
167
|
-
CODEX_AUTO_COMPACT_TOKEN_LIMIT="${2:-}"
|
|
168
|
-
shift 2
|
|
169
|
-
;;
|
|
170
|
-
--reasoning-effort)
|
|
171
|
-
CODEX_REASONING_EFFORT="${2:-}"
|
|
172
|
-
shift 2
|
|
173
|
-
;;
|
|
174
|
-
--subagents)
|
|
175
|
-
SUBAGENTS=true
|
|
176
|
-
shift
|
|
177
|
-
;;
|
|
178
|
-
--external-tools)
|
|
179
|
-
EXTERNAL_TOOLS=true
|
|
180
|
-
shift
|
|
181
|
-
;;
|
|
182
|
-
--max-concurrent-subagents)
|
|
183
|
-
MAX_CONCURRENT_SUBAGENTS="${2:-}"
|
|
184
|
-
shift 2
|
|
185
|
-
;;
|
|
186
|
-
-h|--help)
|
|
56
|
+
-h|--help|help)
|
|
187
57
|
usage
|
|
188
58
|
exit 0
|
|
189
59
|
;;
|
|
@@ -192,333 +62,21 @@ while [[ $# -gt 0 ]]; do
|
|
|
192
62
|
break
|
|
193
63
|
;;
|
|
194
64
|
*)
|
|
195
|
-
echo "unknown argument: $1" >&2
|
|
65
|
+
echo "unknown argument: $1 (launch options belong on subc codex, not subc codex install)" >&2
|
|
196
66
|
usage >&2
|
|
197
67
|
exit 1
|
|
198
68
|
;;
|
|
199
69
|
esac
|
|
200
70
|
done
|
|
201
71
|
|
|
202
|
-
# Default max_context_window to context_window when unset.
|
|
203
|
-
CODEX_MAX_CONTEXT_WINDOW="${CODEX_MAX_CONTEXT_WINDOW:-${CODEX_CONTEXT_WINDOW}}"
|
|
204
|
-
case "$CODEX_REASONING_EFFORT" in
|
|
205
|
-
none|low|medium|high|max) ;;
|
|
206
|
-
*)
|
|
207
|
-
echo "error: reasoning effort must be one of: none, low, medium, high, max" >&2
|
|
208
|
-
exit 1
|
|
209
|
-
;;
|
|
210
|
-
esac
|
|
211
|
-
|
|
212
|
-
DEFAULT_SUBCONSCIOUS_MODELS="subconscious/glm-5.2
|
|
213
|
-
subconscious/tim-qwen3.6-27b
|
|
214
|
-
subconscious/deepseek-v4-flash-marathon"
|
|
215
|
-
SUPPORTED_MODELS=()
|
|
216
|
-
|
|
217
|
-
add_supported_model() {
|
|
218
|
-
local model_id="$1" existing
|
|
219
|
-
[[ -n "$model_id" ]] || return 0
|
|
220
|
-
if [[ ! "$model_id" =~ ^[-A-Za-z0-9._:/+]+$ ]]; then
|
|
221
|
-
echo "error: invalid model id: $model_id" >&2
|
|
222
|
-
exit 1
|
|
223
|
-
fi
|
|
224
|
-
if [[ "${#SUPPORTED_MODELS[@]}" -gt 0 ]]; then
|
|
225
|
-
for existing in "${SUPPORTED_MODELS[@]}"; do
|
|
226
|
-
[[ "$existing" == "$model_id" ]] && return 0
|
|
227
|
-
done
|
|
228
|
-
fi
|
|
229
|
-
SUPPORTED_MODELS+=("$model_id")
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
# Keep the configured model first while exposing every available model in the
|
|
233
|
-
# persistent Codex catalog. The CLI injects the registry list; this fallback is
|
|
234
|
-
# used when the runbook is invoked directly.
|
|
235
|
-
add_supported_model "$MODEL"
|
|
236
|
-
while IFS= read -r model_id; do
|
|
237
|
-
add_supported_model "$model_id"
|
|
238
|
-
done <<< "${SUBCONSCIOUS_MODELS:-$DEFAULT_SUBCONSCIOUS_MODELS}"
|
|
239
|
-
|
|
240
|
-
write_model_catalog() {
|
|
241
|
-
local catalog_file="$1" model_id index=0
|
|
242
|
-
{
|
|
243
|
-
printf '{\n "models": [\n'
|
|
244
|
-
for model_id in "${SUPPORTED_MODELS[@]}"; do
|
|
245
|
-
if [[ "$index" -gt 0 ]]; then
|
|
246
|
-
printf ',\n'
|
|
247
|
-
fi
|
|
248
|
-
cat <<EOF
|
|
249
|
-
{
|
|
250
|
-
"slug": "${model_id}",
|
|
251
|
-
"display_name": "${model_id}",
|
|
252
|
-
"description": "Subconscious API Gateway model ${model_id}",
|
|
253
|
-
"context_window": ${CODEX_CONTEXT_WINDOW},
|
|
254
|
-
"max_context_window": ${CODEX_MAX_CONTEXT_WINDOW},
|
|
255
|
-
"auto_compact_token_limit": ${CODEX_AUTO_COMPACT_TOKEN_LIMIT},
|
|
256
|
-
"effective_context_window_percent": 95,
|
|
257
|
-
"supported_reasoning_levels": [],
|
|
258
|
-
"shell_type": "shell_command",
|
|
259
|
-
"visibility": "list",
|
|
260
|
-
"supported_in_api": true,
|
|
261
|
-
"priority": 0,
|
|
262
|
-
"availability_nux": null,
|
|
263
|
-
"upgrade": null,
|
|
264
|
-
"base_instructions": "You are Codex, a coding agent.",
|
|
265
|
-
"supports_reasoning_summaries": false,
|
|
266
|
-
"support_verbosity": false,
|
|
267
|
-
"default_verbosity": null,
|
|
268
|
-
"apply_patch_tool_type": "freeform",
|
|
269
|
-
"truncation_policy": { "mode": "tokens", "limit": 10000 },
|
|
270
|
-
"supports_parallel_tool_calls": true,
|
|
271
|
-
"experimental_supported_tools": []
|
|
272
|
-
}
|
|
273
|
-
EOF
|
|
274
|
-
index=$((index + 1))
|
|
275
|
-
done
|
|
276
|
-
printf '\n ]\n}\n'
|
|
277
|
-
} >"$catalog_file"
|
|
278
|
-
}
|
|
279
|
-
|
|
280
|
-
CODEX_DIR="${HOME}/.codex"
|
|
281
|
-
CONFIG_TOML="${CODEX_DIR}/config.toml"
|
|
282
|
-
ENV_FILE="${CODEX_DIR}/subconscious.env"
|
|
283
|
-
HOOKS_ENV_FILE="${CODEX_DIR}/subconscious-hooks.env"
|
|
284
|
-
HOOK_DST="${CODEX_DIR}/subconscious-hook.sh"
|
|
285
|
-
HOOKS_JSON="${CODEX_DIR}/hooks.json"
|
|
286
|
-
CATALOG_FILE="${CODEX_DIR}/model-catalog.json"
|
|
287
|
-
MARKER='model_provider = "subconscious"'
|
|
288
|
-
|
|
289
|
-
write_config() {
|
|
290
|
-
mkdir -p "$CODEX_DIR"
|
|
291
|
-
local base_url="${GATEWAY_URL%/}/v1"
|
|
292
|
-
|
|
293
|
-
# Codex does not load custom model metadata from config.toml — it needs a
|
|
294
|
-
# JSON catalog pointed to by the root-level `model_catalog_json` key.
|
|
295
|
-
# Without this, Codex prints "Model metadata not found" and falls back to
|
|
296
|
-
# degraded defaults. The catalog is a replacement, not a merge, so include
|
|
297
|
-
# the complete Subconscious model list.
|
|
298
|
-
write_model_catalog "$CATALOG_FILE"
|
|
299
|
-
|
|
300
|
-
# Write config.toml. When --subagents is set, write the legacy multi-agent v1
|
|
301
|
-
# config that uses plain tool names (not namespace wrappers), which the model
|
|
302
|
-
# worker can actually resolve. Otherwise, omit the [agents] block entirely so
|
|
303
|
-
# Codex uses its defaults (subagents off for custom providers).
|
|
304
|
-
if [[ "$SUBAGENTS" == "true" ]]; then
|
|
305
|
-
cat >"$CONFIG_TOML" <<EOF
|
|
306
|
-
model = "${MODEL}"
|
|
307
|
-
model_provider = "subconscious"
|
|
308
|
-
model_catalog_json = "${CATALOG_FILE}"
|
|
309
|
-
model_reasoning_effort = "${CODEX_REASONING_EFFORT}"
|
|
310
|
-
web_search = "disabled"
|
|
311
|
-
|
|
312
|
-
[features]
|
|
313
|
-
multi_agent = true
|
|
314
|
-
apps = ${EXTERNAL_TOOLS}
|
|
315
|
-
plugins = ${EXTERNAL_TOOLS}
|
|
316
|
-
|
|
317
|
-
[apps._default]
|
|
318
|
-
enabled = ${EXTERNAL_TOOLS}
|
|
319
|
-
|
|
320
|
-
[agents]
|
|
321
|
-
max_threads = ${MAX_CONCURRENT_SUBAGENTS}
|
|
322
|
-
max_depth = 1
|
|
323
|
-
interrupt_message = true
|
|
324
|
-
|
|
325
|
-
[model_providers.subconscious]
|
|
326
|
-
name = "Subconscious Gateway"
|
|
327
|
-
base_url = "${base_url}"
|
|
328
|
-
wire_api = "responses"
|
|
329
|
-
env_key = "SUBCONSCIOUS_API_KEY"
|
|
330
|
-
stream_idle_timeout_ms = 300000
|
|
331
|
-
EOF
|
|
332
|
-
else
|
|
333
|
-
cat >"$CONFIG_TOML" <<EOF
|
|
334
|
-
model = "${MODEL}"
|
|
335
|
-
model_provider = "subconscious"
|
|
336
|
-
model_catalog_json = "${CATALOG_FILE}"
|
|
337
|
-
model_reasoning_effort = "${CODEX_REASONING_EFFORT}"
|
|
338
|
-
web_search = "disabled"
|
|
339
|
-
|
|
340
|
-
[features]
|
|
341
|
-
apps = ${EXTERNAL_TOOLS}
|
|
342
|
-
plugins = ${EXTERNAL_TOOLS}
|
|
343
|
-
|
|
344
|
-
[apps._default]
|
|
345
|
-
enabled = ${EXTERNAL_TOOLS}
|
|
346
|
-
|
|
347
|
-
[model_providers.subconscious]
|
|
348
|
-
name = "Subconscious Gateway"
|
|
349
|
-
base_url = "${base_url}"
|
|
350
|
-
wire_api = "responses"
|
|
351
|
-
env_key = "SUBCONSCIOUS_API_KEY"
|
|
352
|
-
stream_idle_timeout_ms = 300000
|
|
353
|
-
EOF
|
|
354
|
-
fi
|
|
355
|
-
|
|
356
|
-
umask 077
|
|
357
|
-
cat >"$ENV_FILE" <<EOF
|
|
358
|
-
# Generated by ol-runbook/coding-agents/codex/install.sh — do not commit secrets.
|
|
359
|
-
export SUBCONSCIOUS_API_KEY='${API_KEY}'
|
|
360
|
-
export SUBCONSCIOUS_GATEWAY_URL='${GATEWAY_URL%/}'
|
|
361
|
-
EOF
|
|
362
|
-
chmod 600 "$ENV_FILE"
|
|
363
|
-
|
|
364
|
-
# Separate hooks env so the hook script can source it without depending on
|
|
365
|
-
# whether the CLI process inherited subconscious.env.
|
|
366
|
-
cat >"$HOOKS_ENV_FILE" <<EOF
|
|
367
|
-
# Generated by ol-runbook/coding-agents/codex/install.sh — do not commit secrets.
|
|
368
|
-
export SUBCONSCIOUS_GATEWAY_URL='${GATEWAY_URL%/}'
|
|
369
|
-
export SUBCONSCIOUS_API_KEY='${API_KEY}'
|
|
370
|
-
EOF
|
|
371
|
-
chmod 600 "$HOOKS_ENV_FILE"
|
|
372
|
-
}
|
|
373
|
-
|
|
374
|
-
write_hooks() {
|
|
375
|
-
if [[ ! -f "$HOOK_SRC" || ! -f "$HOOKS_TEMPLATE" ]]; then
|
|
376
|
-
echo "warning: codex hook sources missing; skipping compaction hooks" >&2
|
|
377
|
-
return
|
|
378
|
-
fi
|
|
379
|
-
mkdir -p "$CODEX_DIR"
|
|
380
|
-
cp "$HOOK_SRC" "$HOOK_DST"
|
|
381
|
-
chmod +x "$HOOK_DST"
|
|
382
|
-
sed "s|HOOK_SH_PATH|${HOOK_DST}|g" "$HOOKS_TEMPLATE" >"$HOOKS_JSON"
|
|
383
|
-
}
|
|
384
|
-
|
|
385
|
-
print_env_exports() {
|
|
386
|
-
if [[ ! -f "$ENV_FILE" ]]; then
|
|
387
|
-
echo "env file not found: $ENV_FILE" >&2
|
|
388
|
-
echo "run: ./install.sh --gateway-url URL --api-key KEY" >&2
|
|
389
|
-
return 1
|
|
390
|
-
fi
|
|
391
|
-
cat "$ENV_FILE"
|
|
392
|
-
}
|
|
393
|
-
|
|
394
|
-
print_env_unsets() {
|
|
395
|
-
cat <<'EOF'
|
|
396
|
-
unset SUBCONSCIOUS_API_KEY
|
|
397
|
-
unset SUBCONSCIOUS_GATEWAY_URL
|
|
398
|
-
EOF
|
|
399
|
-
}
|
|
400
|
-
|
|
401
|
-
uninstall_config() {
|
|
402
|
-
if [[ -f "$CONFIG_TOML" ]] && grep -q "$MARKER" "$CONFIG_TOML" 2>/dev/null; then
|
|
403
|
-
rm -f "$CONFIG_TOML"
|
|
404
|
-
echo "Removed $CONFIG_TOML"
|
|
405
|
-
else
|
|
406
|
-
echo "No Subconscious Codex config found at $CONFIG_TOML"
|
|
407
|
-
fi
|
|
408
|
-
rm -f "$ENV_FILE" "$HOOKS_ENV_FILE" "$HOOK_DST" "$HOOKS_JSON"
|
|
409
|
-
if [[ -f "$CATALOG_FILE" ]]; then
|
|
410
|
-
rm -f "$CATALOG_FILE"
|
|
411
|
-
echo "Removed $CATALOG_FILE"
|
|
412
|
-
fi
|
|
413
|
-
}
|
|
414
|
-
|
|
415
|
-
status() {
|
|
416
|
-
echo "scope: user"
|
|
417
|
-
echo "codex dir: $CODEX_DIR"
|
|
418
|
-
echo "config: $CONFIG_TOML"
|
|
419
|
-
if [[ -f "$CONFIG_TOML" ]] && grep -q "$MARKER" "$CONFIG_TOML" 2>/dev/null; then
|
|
420
|
-
echo "status: installed"
|
|
421
|
-
echo "model: $(grep '^model' "$CONFIG_TOML" | head -1 | sed 's/^model = "//;s/"$//')"
|
|
422
|
-
echo "base_url: $(grep 'base_url' "$CONFIG_TOML" | sed 's/^base_url = "//;s/"$//')"
|
|
423
|
-
if grep -q '^\[agents\]' "$CONFIG_TOML" 2>/dev/null; then
|
|
424
|
-
echo "subagents: enabled (legacy multi-agent v1)"
|
|
425
|
-
local maxt
|
|
426
|
-
maxt="$(awk -F' *= *' '/^max_threads *=/{print $2}' "$CONFIG_TOML")"
|
|
427
|
-
echo " max_threads: ${maxt:-?}"
|
|
428
|
-
else
|
|
429
|
-
echo "subagents: disabled (codex defaults)"
|
|
430
|
-
fi
|
|
431
|
-
else
|
|
432
|
-
echo "status: not installed"
|
|
433
|
-
fi
|
|
434
|
-
if [[ -f "$ENV_FILE" ]]; then
|
|
435
|
-
echo "env: $ENV_FILE (present)"
|
|
436
|
-
else
|
|
437
|
-
echo "env: missing"
|
|
438
|
-
fi
|
|
439
|
-
if [[ -f "$HOOKS_JSON" && -x "$HOOK_DST" ]]; then
|
|
440
|
-
echo "compaction hooks: $HOOKS_JSON (installed)"
|
|
441
|
-
else
|
|
442
|
-
echo "compaction hooks: not installed"
|
|
443
|
-
fi
|
|
444
|
-
}
|
|
445
|
-
|
|
446
72
|
case "$COMMAND" in
|
|
447
73
|
install)
|
|
448
|
-
|
|
449
|
-
echo "--gateway-url and --api-key are required for install" >&2
|
|
450
|
-
exit 1
|
|
451
|
-
fi
|
|
452
|
-
write_config
|
|
453
|
-
write_hooks
|
|
454
|
-
echo "Installed Subconscious Codex config at $CONFIG_TOML"
|
|
455
|
-
echo " gateway: $GATEWAY_URL"
|
|
456
|
-
echo " model: $MODEL"
|
|
457
|
-
if [[ -f "$HOOKS_JSON" ]]; then
|
|
458
|
-
echo " compaction hooks: $HOOKS_JSON"
|
|
459
|
-
echo ""
|
|
460
|
-
echo " Trust the new hooks in Codex before they run:"
|
|
461
|
-
echo " open /hooks in the CLI, or pass --dangerously-bypass-hook-trust for one-offs"
|
|
462
|
-
echo " Docs: https://developers.openai.com/codex/hooks"
|
|
463
|
-
fi
|
|
464
|
-
if [[ "$SUBAGENTS" == "true" ]]; then
|
|
465
|
-
echo " subagents: ENABLED (codex@${SUBAGENT_CODEX_VERSION}, max ${MAX_CONCURRENT_SUBAGENTS} threads)"
|
|
466
|
-
echo ""
|
|
467
|
-
echo " NOTE: Subagent mode pins codex@${SUBAGENT_CODEX_VERSION}."
|
|
468
|
-
echo " Install it with: npm install -g @openai/codex@${SUBAGENT_CODEX_VERSION}"
|
|
469
|
-
echo " Then launch with: ./install.sh use"
|
|
470
|
-
else
|
|
471
|
-
echo " subagents: disabled (default for custom providers)"
|
|
472
|
-
fi
|
|
473
|
-
echo ""
|
|
474
|
-
echo "Launch codex:"
|
|
475
|
-
echo " ./install.sh use"
|
|
476
|
-
echo " ./install.sh use -- --resume"
|
|
477
|
-
echo ""
|
|
478
|
-
echo "Or source env into your current shell:"
|
|
479
|
-
echo " source <(./install.sh env)"
|
|
480
|
-
;;
|
|
481
|
-
use)
|
|
482
|
-
if [[ ! -f "$ENV_FILE" ]]; then
|
|
483
|
-
echo "env file not found: $ENV_FILE" >&2
|
|
484
|
-
echo "run: ./install.sh --gateway-url URL --api-key KEY" >&2
|
|
485
|
-
exit 1
|
|
486
|
-
fi
|
|
487
|
-
# shellcheck disable=SC1090
|
|
488
|
-
source "$ENV_FILE"
|
|
489
|
-
# If subagents are enabled, ensure the pinned legacy version is installed.
|
|
490
|
-
if [[ "$SUBAGENTS" == "true" ]]; then
|
|
491
|
-
if ! command -v codex >/dev/null 2>&1; then
|
|
492
|
-
echo "codex CLI not found in PATH" >&2
|
|
493
|
-
echo "Install the pinned subagent version:" >&2
|
|
494
|
-
echo " npm install -g @openai/codex@${SUBAGENT_CODEX_VERSION}" >&2
|
|
495
|
-
exit 1
|
|
496
|
-
fi
|
|
497
|
-
local_version="$(codex --version 2>/dev/null | head -1 | grep -oE '[0-9]+\.[0-9]+\.[0-9]+' || echo "")"
|
|
498
|
-
if [[ "$local_version" != "$SUBAGENT_CODEX_VERSION" ]]; then
|
|
499
|
-
echo "WARNING: codex ${local_version:-unknown} is installed, but subagents need ${SUBAGENT_CODEX_VERSION}." >&2
|
|
500
|
-
echo " npm install -g @openai/codex@${SUBAGENT_CODEX_VERSION}" >&2
|
|
501
|
-
echo " (or remove --subagents from your config to use the latest codex without subagents)" >&2
|
|
502
|
-
fi
|
|
503
|
-
else
|
|
504
|
-
if ! command -v codex >/dev/null 2>&1; then
|
|
505
|
-
echo "codex CLI not found in PATH" >&2
|
|
506
|
-
exit 1
|
|
507
|
-
fi
|
|
508
|
-
fi
|
|
509
|
-
exec codex "$@"
|
|
510
|
-
;;
|
|
511
|
-
env)
|
|
512
|
-
print_env_exports
|
|
513
|
-
;;
|
|
514
|
-
unset)
|
|
515
|
-
print_env_unsets
|
|
74
|
+
codex_ensure_hooks strict
|
|
516
75
|
;;
|
|
517
76
|
uninstall)
|
|
518
|
-
|
|
519
|
-
echo "To unset env in your current shell: source <(./install.sh unset)"
|
|
77
|
+
codex_uninstall_hooks
|
|
520
78
|
;;
|
|
521
79
|
status)
|
|
522
|
-
|
|
80
|
+
codex_hooks_status
|
|
523
81
|
;;
|
|
524
82
|
esac
|
package/bin/runbook/codex/run.sh
CHANGED
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
# ./run.sh --external-tools # include Codex apps/plugins (may exceed gateway tool limits)
|
|
24
24
|
#
|
|
25
25
|
# Config: copy ../env.example to ../.env and edit. .env is gitignored.
|
|
26
|
-
#
|
|
26
|
+
# Profile env is injected by subc. A sibling .env is only used when SUBC_ENV_FILE is unset.
|
|
27
27
|
#
|
|
28
28
|
# Or source it to just export the env:
|
|
29
29
|
# source run.sh
|
|
@@ -32,8 +32,8 @@ set -euo pipefail
|
|
|
32
32
|
|
|
33
33
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
34
34
|
|
|
35
|
-
# Load shared env from
|
|
36
|
-
SHARED_ENV="${
|
|
35
|
+
# Load shared env from SUBC_ENV_FILE, or a sibling .env / env.example.
|
|
36
|
+
SHARED_ENV="${SUBC_ENV_FILE:-${SCRIPT_DIR}/../.env}"
|
|
37
37
|
[[ -f "$SHARED_ENV" ]] || SHARED_ENV="${SCRIPT_DIR}/../env.example"
|
|
38
38
|
if [[ -f "$SHARED_ENV" ]]; then set -a; source "$SHARED_ENV"; set +a; fi
|
|
39
39
|
|
|
@@ -191,27 +191,11 @@ fi
|
|
|
191
191
|
export SUBCONSCIOUS_API_KEY="$API_KEY"
|
|
192
192
|
export SUBCONSCIOUS_GATEWAY_URL="${GATEWAY_URL%/}"
|
|
193
193
|
|
|
194
|
-
#
|
|
195
|
-
# ~/.codex/hooks.json alongside config layers; trust them once via /hooks.
|
|
194
|
+
# Merge compaction hooks without replacing ~/.codex/hooks.json or config.toml.
|
|
196
195
|
HOOK_SRC="${SCRIPT_DIR}/hook.sh"
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
HOOKS_JSON="${CODEX_DIR}/hooks.json"
|
|
201
|
-
HOOKS_ENV_FILE="${CODEX_DIR}/subconscious-hooks.env"
|
|
202
|
-
if [[ -f "$HOOK_SRC" && -f "$HOOKS_TEMPLATE" ]]; then
|
|
203
|
-
mkdir -p "$CODEX_DIR"
|
|
204
|
-
cp "$HOOK_SRC" "$HOOK_DST"
|
|
205
|
-
chmod +x "$HOOK_DST"
|
|
206
|
-
sed "s|HOOK_SH_PATH|${HOOK_DST}|g" "$HOOKS_TEMPLATE" >"$HOOKS_JSON"
|
|
207
|
-
umask 077
|
|
208
|
-
cat >"$HOOKS_ENV_FILE" <<EOF
|
|
209
|
-
# Generated by ol-runbook/coding-agents/codex/run.sh — do not commit secrets.
|
|
210
|
-
export SUBCONSCIOUS_GATEWAY_URL='${GATEWAY_URL%/}'
|
|
211
|
-
export SUBCONSCIOUS_API_KEY='${API_KEY}'
|
|
212
|
-
EOF
|
|
213
|
-
chmod 600 "$HOOKS_ENV_FILE"
|
|
214
|
-
fi
|
|
196
|
+
# shellcheck source=hooks-lib.sh
|
|
197
|
+
source "${SCRIPT_DIR}/hooks-lib.sh"
|
|
198
|
+
codex_ensure_hooks best-effort || true
|
|
215
199
|
|
|
216
200
|
# Write a temp model catalog so Codex doesn't print "model metadata not found".
|
|
217
201
|
# This is the one thing that can't be passed via -c flags.
|
|
@@ -66,8 +66,8 @@ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
|
66
66
|
HOOK_SRC="${SCRIPT_DIR}/hook.sh"
|
|
67
67
|
HOOKS_TEMPLATE="${SCRIPT_DIR}/hooks.json"
|
|
68
68
|
|
|
69
|
-
# Load shared env from
|
|
70
|
-
SHARED_ENV="${
|
|
69
|
+
# Load shared env from SUBC_ENV_FILE, or a sibling .env / env.example.
|
|
70
|
+
SHARED_ENV="${SUBC_ENV_FILE:-${SCRIPT_DIR}/../.env}"
|
|
71
71
|
[[ -f "$SHARED_ENV" ]] || SHARED_ENV="${SCRIPT_DIR}/../env.example"
|
|
72
72
|
if [[ -f "$SHARED_ENV" ]]; then set -a; source "$SHARED_ENV"; set +a; fi
|
|
73
73
|
|
|
@@ -99,9 +99,9 @@ MARKER="subconscious-hook.sh"
|
|
|
99
99
|
usage() {
|
|
100
100
|
cat <<'EOF'
|
|
101
101
|
Usage:
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
102
|
+
subc copilot install [--gateway-url URL] [--api-key KEY] [--model MODEL]
|
|
103
|
+
subc copilot uninstall
|
|
104
|
+
subc copilot status
|
|
105
105
|
|
|
106
106
|
`install` is the default subcommand. It writes a "Subconscious Gateway"
|
|
107
107
|
Custom Endpoint provider into VS Code's user-wide chatLanguageModels.json
|
|
@@ -112,10 +112,10 @@ requires it to be entered through its UI (the script writes a stable
|
|
|
112
112
|
${input:chat.lm.secret.*} reference into chatLanguageModels.json, and you
|
|
113
113
|
paste the key once via Manage Language Models).
|
|
114
114
|
|
|
115
|
-
The API key for the hooks is read from
|
|
115
|
+
The API key for the hooks is read from the profile env or --api-key and
|
|
116
116
|
stored in ~/.copilot/subconscious-hooks.env (mode 600).
|
|
117
117
|
|
|
118
|
-
Reads GATEWAY_URL, API_KEY, and MODEL from the
|
|
118
|
+
Reads GATEWAY_URL, API_KEY, and MODEL from the profile env by
|
|
119
119
|
default. Restart VS Code after install.
|
|
120
120
|
|
|
121
121
|
Options:
|
|
@@ -354,7 +354,7 @@ uninstall_config() {
|
|
|
354
354
|
write_hooks_env() {
|
|
355
355
|
umask 077
|
|
356
356
|
cat >"$ENV_FILE" <<EOF
|
|
357
|
-
# Generated by
|
|
357
|
+
# Generated by subc — do not commit secrets.
|
|
358
358
|
export SUBCONSCIOUS_GATEWAY_URL='${GATEWAY_URL}'
|
|
359
359
|
export SUBCONSCIOUS_API_KEY='${API_KEY}'
|
|
360
360
|
EOF
|
|
@@ -434,6 +434,7 @@ case "$COMMAND" in
|
|
|
434
434
|
USER_DIR="$(detect_vscode_dir)"
|
|
435
435
|
WRITTEN="$(write_config "$USER_DIR")"
|
|
436
436
|
echo "Installed Subconscious Copilot provider into $WRITTEN"
|
|
437
|
+
echo "Gateway base URL: ${GATEWAY_URL%/}/v1"
|
|
437
438
|
install_hook_script
|
|
438
439
|
write_hooks_env
|
|
439
440
|
write_hooks_json
|