subconscious-cli 6.0.1 → 6.1.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.
- package/README.md +119 -0
- package/bin/agent-data.js +242 -0
- package/bin/agent-help.js +106 -0
- package/bin/agent-install.js +354 -0
- package/bin/agent-launch.js +199 -0
- package/bin/agent-spawn.js +137 -0
- package/bin/agents.js +236 -932
- package/bin/auth.js +9 -1
- package/bin/claude-picker.js +143 -0
- package/bin/cli.js +60 -1
- package/bin/clipboard-image.js +2 -0
- package/bin/feedback.js +14 -3
- package/bin/harness-manifest.js +286 -0
- package/bin/headless-args.js +35 -0
- package/bin/launch-values.js +25 -0
- package/bin/model-capabilities.js +10 -9
- package/bin/models.js +13 -13
- package/bin/native/subc-tui-darwin-amd64 +0 -0
- package/bin/native/subc-tui-darwin-arm64 +0 -0
- package/bin/native/subc-tui-linux-amd64 +0 -0
- package/bin/native/subc-tui-linux-arm64 +0 -0
- package/bin/native/subc-tui-windows-amd64.exe +0 -0
- package/bin/native/subc-tui-windows-arm64.exe +0 -0
- package/bin/opencode-provider.js +21 -0
- package/bin/profile-settings.js +129 -0
- package/bin/profiles.js +29 -424
- package/bin/runbook/README.md +66 -23
- package/bin/runbook/claude-code/agent.json +300 -0
- package/bin/runbook/claude-code/install.sh +9 -252
- package/bin/runbook/codex/agent.json +461 -0
- package/bin/runbook/codex/hooks-lib.sh +17 -4
- package/bin/runbook/codex/install.sh +0 -4
- package/bin/runbook/codex/run.sh +16 -235
- package/bin/runbook/copilot/agent.json +185 -0
- package/bin/runbook/copilot/install.sh +45 -63
- package/bin/runbook/cursor/agent.json +137 -0
- package/bin/runbook/cursor/install.sh +8 -35
- package/bin/runbook/deepseek-harness/agent.json +163 -0
- package/bin/runbook/deepseek-harness/run.sh +20 -59
- package/bin/runbook/image-window/index.ts +14 -0
- package/bin/runbook/image-window/window.d.ts +19 -0
- package/bin/runbook/image-window/window.js +140 -0
- package/bin/runbook/lib.sh +41 -0
- package/bin/runbook/opencode/agent.json +158 -0
- package/bin/runbook/opencode/install.sh +9 -183
- package/bin/runbook/opencode/opencode-plugin.d.ts +10 -3
- package/bin/runbook/opencode/subconscious-image-window.ts +24 -0
- package/bin/runbook/pi/agent.json +216 -0
- package/bin/runbook/pi/install.sh +18 -44
- package/bin/runbook/pi/run.sh +6 -18
- package/bin/runbook/pi/subconscious-compaction.ts +3 -1
- package/bin/runbook/shared.json +58 -0
- package/bin/runbook/subconscious-code/agent.json +156 -0
- package/bin/sessions.js +52 -22
- package/bin/tui.js +13 -0
- package/bin/update-check.js +5 -1
- package/bin/upgrade.js +24 -31
- package/bin/usage.js +21 -10
- package/bin/windows/agents.js +18 -17
- package/bin/windows/common.js +2 -28
- package/bin/windows/install.js +11 -17
- package/bin/windows/launch.js +252 -231
- package/bin/windows/process.js +12 -1
- package/bin/windows/setup.js +29 -9
- package/package.json +2 -3
- package/bin/registry.generated.json +0 -406
- package/bin/runbook/claude-code/run.sh +0 -254
- package/bin/runbook/model-capabilities.generated.sh +0 -9
- package/bin/runbook/opencode/provider.sh +0 -93
- package/bin/runbook/opencode/run.sh +0 -99
- package/bin/runbook/opencode/subconscious-compaction.ts +0 -100
- package/bin/runbook/subconscious-code/run.sh +0 -21
- package/bin/windows/claude.js +0 -100
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# shellcheck shell=bash
|
|
2
|
+
# subc sets every value a runbook reads, so a runbook declares no defaults
|
|
3
|
+
# of its own.
|
|
4
|
+
|
|
5
|
+
# Exact IDs only: similarly named models do not inherit capabilities.
|
|
6
|
+
subc_model_supports_vision() {
|
|
7
|
+
local model
|
|
8
|
+
while IFS= read -r model; do
|
|
9
|
+
[[ -n "$model" && "$model" == "${1:-}" ]] && return 0
|
|
10
|
+
done <<< "${SUBC_VISION_MODELS:-}"
|
|
11
|
+
return 1
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
# Replace this shell with the agent argv subc built:
|
|
15
|
+
# subc_exec [PLACEHOLDER VALUE]... -- ARGV...
|
|
16
|
+
# Only the first SUBC_TEMPLATE_WORDS words came from the agent's argv
|
|
17
|
+
# template; passed-through arguments and the prompt after them are never
|
|
18
|
+
# rewritten, whatever they contain.
|
|
19
|
+
subc_exec() {
|
|
20
|
+
local names=() values=() argv=() word index=0 i
|
|
21
|
+
while [[ $# -gt 0 && "$1" != "--" ]]; do
|
|
22
|
+
names+=("$1")
|
|
23
|
+
values+=("$2")
|
|
24
|
+
shift 2
|
|
25
|
+
done
|
|
26
|
+
shift
|
|
27
|
+
local limit="${SUBC_TEMPLATE_WORDS:-0}"
|
|
28
|
+
unset SUBC_TEMPLATE_WORDS SUBC_MODEL_IDS SUBC_VISION_MODELS
|
|
29
|
+
for word in "$@"; do
|
|
30
|
+
if [[ "$index" -lt "$limit" ]]; then
|
|
31
|
+
for ((i = 0; i < ${#names[@]}; i++)); do
|
|
32
|
+
if [[ "$word" == *"${names[i]}"* ]]; then
|
|
33
|
+
word="${word%%"${names[i]}"*}${values[i]}${word#*"${names[i]}"}"
|
|
34
|
+
fi
|
|
35
|
+
done
|
|
36
|
+
fi
|
|
37
|
+
argv+=("$word")
|
|
38
|
+
index=$((index + 1))
|
|
39
|
+
done
|
|
40
|
+
exec "${argv[@]}"
|
|
41
|
+
}
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "opencode",
|
|
3
|
+
"command": "opencode",
|
|
4
|
+
"aliases": ["open-code"],
|
|
5
|
+
"name": "OpenCode",
|
|
6
|
+
"description": "Run OpenCode on your hosted Subconscious model with the Subconscious provider and context settings.",
|
|
7
|
+
"protocol": "openai",
|
|
8
|
+
"homepage": "https://opencode.ai",
|
|
9
|
+
"install": {
|
|
10
|
+
"commands": {
|
|
11
|
+
"darwin": "npm i -g {package}",
|
|
12
|
+
"linux": "npm i -g {package}",
|
|
13
|
+
"win32": "npm i -g {package}"
|
|
14
|
+
},
|
|
15
|
+
"method": "npm",
|
|
16
|
+
"package": "opencode-ai",
|
|
17
|
+
"version": null,
|
|
18
|
+
"channel": "latest (unpinned)",
|
|
19
|
+
"install_dir": "~/.opencode/bin",
|
|
20
|
+
"minimum_version": null,
|
|
21
|
+
"verified": true
|
|
22
|
+
},
|
|
23
|
+
"runbook": {
|
|
24
|
+
"mode": "launch",
|
|
25
|
+
"setup_script": "install.sh",
|
|
26
|
+
"setup_actions": ["status", "uninstall"]
|
|
27
|
+
},
|
|
28
|
+
"help": {
|
|
29
|
+
"usage": "subc [-p NAME] opencode [help|status|uninstall] [OpenCode arguments...]",
|
|
30
|
+
"behavior": "Launches OpenCode with an ephemeral provider containing every Subconscious model. Persistent files are leftover-only: subc opencode uninstall.",
|
|
31
|
+
"options": [
|
|
32
|
+
["help", "Show this help"],
|
|
33
|
+
["status", "Inspect leftover OpenCode Subconscious config"],
|
|
34
|
+
[
|
|
35
|
+
"uninstall",
|
|
36
|
+
"Remove only the Subconscious OpenCode provider and plugin"
|
|
37
|
+
],
|
|
38
|
+
["--model MODEL", "Override the profile model for this launch"]
|
|
39
|
+
],
|
|
40
|
+
"args": ["ARGS...", "Pass arguments directly to OpenCode"]
|
|
41
|
+
},
|
|
42
|
+
"sessions": { "key": "opencode", "portable": true },
|
|
43
|
+
"prerequisites": [],
|
|
44
|
+
"launch": {
|
|
45
|
+
"argv": ["opencode", "{args}"],
|
|
46
|
+
"headless_argv": ["opencode", "run", "{args}"],
|
|
47
|
+
"headless_stdin": "{prompt}",
|
|
48
|
+
"headless_platforms": ["darwin", "linux"],
|
|
49
|
+
"resume": ["--session", "{sessionId}"],
|
|
50
|
+
"handoff": ["--prompt", "{prompt}"],
|
|
51
|
+
"persistent_setup": false
|
|
52
|
+
},
|
|
53
|
+
"inputs": [
|
|
54
|
+
{
|
|
55
|
+
"name": "OPENCODE_API_KEY",
|
|
56
|
+
"label": "OpenCode API key",
|
|
57
|
+
"description": "OpenCode-specific credential override; blank uses API_KEY.",
|
|
58
|
+
"type": "secret"
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
"name": "OPENCODE_CONTEXT_LIMIT",
|
|
62
|
+
"default": 5000000,
|
|
63
|
+
"label": "Context limit",
|
|
64
|
+
"description": "OpenCode provider context limit used for compaction.",
|
|
65
|
+
"type": "integer",
|
|
66
|
+
"min": 1
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
"name": "OPENCODE_OUTPUT_LIMIT",
|
|
70
|
+
"default": 65536,
|
|
71
|
+
"label": "Output limit",
|
|
72
|
+
"description": "Maximum output tokens advertised to OpenCode.",
|
|
73
|
+
"type": "integer",
|
|
74
|
+
"min": 1
|
|
75
|
+
}
|
|
76
|
+
],
|
|
77
|
+
"env": [
|
|
78
|
+
{
|
|
79
|
+
"name": "SUBCONSCIOUS_API_KEY",
|
|
80
|
+
"value": "{apiKey}",
|
|
81
|
+
"description": "Credential, referenced as {env:SUBCONSCIOUS_API_KEY} in the provider config."
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
"name": "SUBCONSCIOUS_GATEWAY_URL",
|
|
85
|
+
"value": "{baseUrl}",
|
|
86
|
+
"description": "Gateway origin for the compaction plugin, when one is installed."
|
|
87
|
+
},
|
|
88
|
+
{
|
|
89
|
+
"name": "OPENCODE_CONFIG_CONTENT",
|
|
90
|
+
"value": "{opencodeConfig}",
|
|
91
|
+
"description": "Whole OpenCode config for this launch; see the config entry. Nothing is written to disk."
|
|
92
|
+
}
|
|
93
|
+
],
|
|
94
|
+
"config": [
|
|
95
|
+
{
|
|
96
|
+
"kind": "env-json",
|
|
97
|
+
"name": "OPENCODE_CONFIG_CONTENT",
|
|
98
|
+
"lifetime": "launch",
|
|
99
|
+
"value": "{opencodeConfig}",
|
|
100
|
+
"description": "Provider, models, limits and image-window plugin, built for every catalog model."
|
|
101
|
+
},
|
|
102
|
+
{
|
|
103
|
+
"kind": "file",
|
|
104
|
+
"path": "~/.config/opencode/plugins/subconscious-compaction.ts",
|
|
105
|
+
"lifetime": "legacy",
|
|
106
|
+
"description": "Compaction plugin from older persistent setup. Launch never writes it; subc opencode uninstall removes it."
|
|
107
|
+
}
|
|
108
|
+
],
|
|
109
|
+
"capabilities": {
|
|
110
|
+
"compaction": {
|
|
111
|
+
"default": "on",
|
|
112
|
+
"on": {
|
|
113
|
+
"set_by_subc": true,
|
|
114
|
+
"kind": "config-field",
|
|
115
|
+
"name": "provider.subconscious.models.<id>.limit.context",
|
|
116
|
+
"value": "${OPENCODE_CONTEXT_LIMIT}",
|
|
117
|
+
"verified": false,
|
|
118
|
+
"note": "subc sets limit.context. That auto-compaction keys off it comes only from an install.sh comment and the profile setting description.",
|
|
119
|
+
"config": "OPENCODE_CONFIG_CONTENT"
|
|
120
|
+
},
|
|
121
|
+
"off": {
|
|
122
|
+
"set_by_subc": false,
|
|
123
|
+
"kind": "config-field",
|
|
124
|
+
"name": "compaction.auto",
|
|
125
|
+
"value": false,
|
|
126
|
+
"verified": false,
|
|
127
|
+
"note": "Upstream OpenCode setting. subc never sets it, and this repo does not confirm its name or behaviour.",
|
|
128
|
+
"config": "OpenCode config"
|
|
129
|
+
},
|
|
130
|
+
"threshold": {
|
|
131
|
+
"set_by_subc": true,
|
|
132
|
+
"kind": "config-field",
|
|
133
|
+
"name": "provider.subconscious.models.<id>.limit.context",
|
|
134
|
+
"value": "${OPENCODE_CONTEXT_LIMIT}",
|
|
135
|
+
"verified": false,
|
|
136
|
+
"semantics": "window",
|
|
137
|
+
"config": "OPENCODE_CONFIG_CONTENT",
|
|
138
|
+
"note": "subc sets limit.context. That auto-compaction keys off it comes only from an install.sh comment and the profile setting description."
|
|
139
|
+
}
|
|
140
|
+
},
|
|
141
|
+
"mcp": {
|
|
142
|
+
"configured_by_subc": false,
|
|
143
|
+
"transports": null,
|
|
144
|
+
"verified": false,
|
|
145
|
+
"note": "OPENCODE_CONFIG_CONTENT carries no mcp block. Whether OpenCode merges user MCP config with it is not confirmed here."
|
|
146
|
+
},
|
|
147
|
+
"headers": [
|
|
148
|
+
{
|
|
149
|
+
"name": "x-subconscious-client",
|
|
150
|
+
"value": "opencode",
|
|
151
|
+
"on": "model requests",
|
|
152
|
+
"set_by_subc": true,
|
|
153
|
+
"verified": true
|
|
154
|
+
}
|
|
155
|
+
],
|
|
156
|
+
"hooks": []
|
|
157
|
+
}
|
|
158
|
+
}
|
|
@@ -1,75 +1,17 @@
|
|
|
1
1
|
#!/usr/bin/env bash
|
|
2
|
-
# ── Subconscious API Gateway — OpenCode
|
|
3
|
-
#
|
|
4
|
-
#
|
|
2
|
+
# ── Subconscious API Gateway — OpenCode leftovers ─────────────────────────────
|
|
3
|
+
# OpenCode is launch-only: `subc opencode` passes the provider config in
|
|
4
|
+
# OPENCODE_CONFIG_CONTENT and writes nothing. Older persistent setups wrote a
|
|
5
|
+
# provider into ~/.opencode/opencode.json, an env file, and a compaction
|
|
6
|
+
# plugin; this script reports and removes those.
|
|
5
7
|
#
|
|
6
|
-
#
|
|
7
|
-
#
|
|
8
|
-
# ./install.sh status # show current config
|
|
9
|
-
# ./install.sh uninstall # revert to default opencode config
|
|
10
|
-
#
|
|
11
|
-
# Writes ~/.opencode/opencode.json (user config). Does not touch project-level
|
|
12
|
-
# opencode.json files. Restart opencode after install.
|
|
13
|
-
#
|
|
14
|
-
# ── What this does under the hood ────────────────────────────────────────────
|
|
15
|
-
# Equivalent manual setup (writes ~/.opencode/opencode.json + env var):
|
|
16
|
-
#
|
|
17
|
-
# export SUBCONSCIOUS_API_KEY=sk-gw-...
|
|
18
|
-
# cat > ~/.opencode/opencode.json <<'EOF'
|
|
19
|
-
# {
|
|
20
|
-
# "$schema": "https://opencode.ai/config.json",
|
|
21
|
-
# "provider": {
|
|
22
|
-
# "subconscious": {
|
|
23
|
-
# "npm": "@ai-sdk/openai-compatible",
|
|
24
|
-
# "name": "Subconscious Gateway",
|
|
25
|
-
# "options": {
|
|
26
|
-
# "baseURL": "https://your-gateway.example/v1",
|
|
27
|
-
# "apiKey": "{env:SUBCONSCIOUS_API_KEY}",
|
|
28
|
-
# "headers": { "x-subconscious-client": "opencode" }
|
|
29
|
-
# },
|
|
30
|
-
# "models": {
|
|
31
|
-
# "subconscious/glm-5.3-marathon": {
|
|
32
|
-
# "name": "subconscious/glm-5.3-marathon",
|
|
33
|
-
# "tools": true,
|
|
34
|
-
# "limit": { "context": 5000000, "output": 65536 }
|
|
35
|
-
# }
|
|
36
|
-
# }
|
|
37
|
-
# }
|
|
38
|
-
# },
|
|
39
|
-
# "model": "subconscious/subconscious/glm-5.3-marathon"
|
|
40
|
-
# }
|
|
41
|
-
# EOF
|
|
42
|
-
# opencode
|
|
43
|
-
#
|
|
44
|
-
# The x-subconscious-client header tells the gateway to classify traffic as
|
|
45
|
-
# OpenCode. OpenCode also sends native x-session-affinity / x-session-id
|
|
46
|
-
# headers for conversation correlation. Model limit.context drives auto
|
|
47
|
-
# compaction (default on); custom providers do not inherit models.dev limits.
|
|
48
|
-
#
|
|
49
|
-
# Also installs a plugin that reports compactions to the gateway. OpenCode
|
|
50
|
-
# summarizes through the configured provider, so without it the gateway counts
|
|
51
|
-
# that summarization as a normal main-thread turn.
|
|
8
|
+
# subc opencode status
|
|
9
|
+
# subc opencode uninstall
|
|
52
10
|
# ─────────────────────────────────────────────────────────────────────────────
|
|
53
11
|
|
|
54
12
|
set -euo pipefail
|
|
55
13
|
|
|
56
|
-
|
|
57
|
-
source "${SCRIPT_DIR}/../model-capabilities.generated.sh"
|
|
58
|
-
source "${SCRIPT_DIR}/provider.sh"
|
|
59
|
-
|
|
60
|
-
# Load shared env from SUBC_ENV_FILE, or a sibling .env / env.example.
|
|
61
|
-
SHARED_ENV="${SUBC_ENV_FILE:-${SCRIPT_DIR}/../.env}"
|
|
62
|
-
[[ -f "$SHARED_ENV" ]] || SHARED_ENV="${SCRIPT_DIR}/../env.example"
|
|
63
|
-
if [[ -f "$SHARED_ENV" ]]; then set -a; source "$SHARED_ENV"; set +a; fi
|
|
64
|
-
|
|
65
|
-
COMMAND="install"
|
|
66
|
-
GATEWAY_URL="${GATEWAY_URL:-}"
|
|
67
|
-
API_KEY="${OPENCODE_API_KEY:-${API_KEY:-}}"
|
|
68
|
-
MODEL="${MODEL:-subconscious/glm-5.3-marathon}"
|
|
69
|
-
# OpenCode auto-compaction uses model limit.context. Custom openai-compatible
|
|
70
|
-
# providers do not get that from baseURL/models.dev; set it explicitly.
|
|
71
|
-
CONTEXT_LIMIT="${OPENCODE_CONTEXT_LIMIT:-5000000}"
|
|
72
|
-
OUTPUT_LIMIT="${OPENCODE_OUTPUT_LIMIT:-65536}"
|
|
14
|
+
COMMAND="status"
|
|
73
15
|
|
|
74
16
|
usage() {
|
|
75
17
|
cat <<'EOF'
|
|
@@ -85,30 +27,10 @@ EOF
|
|
|
85
27
|
|
|
86
28
|
while [[ $# -gt 0 ]]; do
|
|
87
29
|
case "$1" in
|
|
88
|
-
|
|
30
|
+
uninstall|status)
|
|
89
31
|
COMMAND="$1"
|
|
90
32
|
shift
|
|
91
33
|
;;
|
|
92
|
-
--gateway-url)
|
|
93
|
-
GATEWAY_URL="${2:-}"
|
|
94
|
-
shift 2
|
|
95
|
-
;;
|
|
96
|
-
--api-key)
|
|
97
|
-
API_KEY="${2:-}"
|
|
98
|
-
shift 2
|
|
99
|
-
;;
|
|
100
|
-
--model)
|
|
101
|
-
MODEL="${2:-}"
|
|
102
|
-
shift 2
|
|
103
|
-
;;
|
|
104
|
-
--context-limit)
|
|
105
|
-
CONTEXT_LIMIT="${2:-}"
|
|
106
|
-
shift 2
|
|
107
|
-
;;
|
|
108
|
-
--output-limit)
|
|
109
|
-
OUTPUT_LIMIT="${2:-}"
|
|
110
|
-
shift 2
|
|
111
|
-
;;
|
|
112
34
|
-h|--help)
|
|
113
35
|
usage
|
|
114
36
|
exit 0
|
|
@@ -121,35 +43,6 @@ while [[ $# -gt 0 ]]; do
|
|
|
121
43
|
esac
|
|
122
44
|
done
|
|
123
45
|
|
|
124
|
-
DEFAULT_SUBCONSCIOUS_MODELS="subconscious/glm-5.3-marathon
|
|
125
|
-
subconscious/glm-5.2
|
|
126
|
-
subconscious/tim-qwen3.6-27b
|
|
127
|
-
subconscious/deepseek-v4-flash-marathon
|
|
128
|
-
subconscious/deepseek-v4.1-flash-marathon"
|
|
129
|
-
SUPPORTED_MODELS=()
|
|
130
|
-
|
|
131
|
-
add_supported_model() {
|
|
132
|
-
local model_id="$1" existing
|
|
133
|
-
[[ -n "$model_id" ]] || return 0
|
|
134
|
-
if [[ ! "$model_id" =~ ^[-A-Za-z0-9._:/+]+$ ]]; then
|
|
135
|
-
echo "error: invalid model id: $model_id" >&2
|
|
136
|
-
exit 1
|
|
137
|
-
fi
|
|
138
|
-
if [[ "${#SUPPORTED_MODELS[@]}" -gt 0 ]]; then
|
|
139
|
-
for existing in "${SUPPORTED_MODELS[@]}"; do
|
|
140
|
-
[[ "$existing" == "$model_id" ]] && return 0
|
|
141
|
-
done
|
|
142
|
-
fi
|
|
143
|
-
SUPPORTED_MODELS+=("$model_id")
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
add_supported_model "$MODEL"
|
|
147
|
-
while IFS= read -r model_id; do
|
|
148
|
-
add_supported_model "$model_id"
|
|
149
|
-
done <<< "${SUBCONSCIOUS_MODELS:-$DEFAULT_SUBCONSCIOUS_MODELS}"
|
|
150
|
-
|
|
151
|
-
subc_opencode_build_models_json
|
|
152
|
-
|
|
153
46
|
OPENCODE_DIR="${HOME}/.opencode"
|
|
154
47
|
OPENCODE_CONFIG="${OPENCODE_DIR}/opencode.json"
|
|
155
48
|
MARKER='x-subconscious-client'
|
|
@@ -157,59 +50,6 @@ MARKER='x-subconscious-client'
|
|
|
157
50
|
# config path above. Docs: https://opencode.ai/docs/plugins/
|
|
158
51
|
PLUGIN_DIR="${XDG_CONFIG_HOME:-${HOME}/.config}/opencode/plugins"
|
|
159
52
|
PLUGIN_FILE="${PLUGIN_DIR}/subconscious-compaction.ts"
|
|
160
|
-
PLUGIN_SOURCE="${SCRIPT_DIR}/subconscious-compaction.ts"
|
|
161
|
-
|
|
162
|
-
require_cmds() {
|
|
163
|
-
local missing=0
|
|
164
|
-
for c in jq; do
|
|
165
|
-
if ! command -v "$c" >/dev/null 2>&1; then
|
|
166
|
-
echo "missing required command: $c" >&2
|
|
167
|
-
missing=1
|
|
168
|
-
fi
|
|
169
|
-
done
|
|
170
|
-
if [[ "$missing" -ne 0 ]]; then
|
|
171
|
-
exit 1
|
|
172
|
-
fi
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
write_config() {
|
|
176
|
-
mkdir -p "$OPENCODE_DIR"
|
|
177
|
-
local base_url="${GATEWAY_URL%/}/v1"
|
|
178
|
-
local provider selected_model
|
|
179
|
-
provider="$(subc_opencode_build_provider_json "$base_url")"
|
|
180
|
-
selected_model="${SUBC_OPENCODE_PROVIDER_ID}/${MODEL}"
|
|
181
|
-
if [[ -f "$OPENCODE_CONFIG" ]]; then
|
|
182
|
-
local tmp
|
|
183
|
-
tmp="$(mktemp)"
|
|
184
|
-
jq --argjson provider "$provider" --arg model "$selected_model" --arg provider_id "$SUBC_OPENCODE_PROVIDER_ID" '
|
|
185
|
-
.provider = (.provider // {})
|
|
186
|
-
| .provider[$provider_id] = $provider
|
|
187
|
-
| .model = $model
|
|
188
|
-
' "$OPENCODE_CONFIG" >"$tmp"
|
|
189
|
-
mv "$tmp" "$OPENCODE_CONFIG"
|
|
190
|
-
else
|
|
191
|
-
jq -n --argjson provider "$provider" --arg model "$selected_model" --arg provider_id "$SUBC_OPENCODE_PROVIDER_ID" \
|
|
192
|
-
'{ "$schema": "https://opencode.ai/config.json", provider: {($provider_id): $provider}, model: $model }' \
|
|
193
|
-
>"$OPENCODE_CONFIG"
|
|
194
|
-
fi
|
|
195
|
-
local env_file="${OPENCODE_DIR}/subconscious.env"
|
|
196
|
-
umask 077
|
|
197
|
-
cat >"$env_file" <<EOF
|
|
198
|
-
# Generated by subc — do not commit secrets.
|
|
199
|
-
export SUBCONSCIOUS_API_KEY='${API_KEY}'
|
|
200
|
-
export SUBCONSCIOUS_GATEWAY_URL='${GATEWAY_URL%/}'
|
|
201
|
-
EOF
|
|
202
|
-
chmod 600 "$env_file"
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
write_plugin() {
|
|
206
|
-
if [[ ! -f "$PLUGIN_SOURCE" ]]; then
|
|
207
|
-
echo "warning: ${PLUGIN_SOURCE} missing; skipping compaction plugin" >&2
|
|
208
|
-
return
|
|
209
|
-
fi
|
|
210
|
-
mkdir -p "$PLUGIN_DIR"
|
|
211
|
-
cp "$PLUGIN_SOURCE" "$PLUGIN_FILE"
|
|
212
|
-
}
|
|
213
53
|
|
|
214
54
|
uninstall_config() {
|
|
215
55
|
if [[ -f "$OPENCODE_CONFIG" ]]; then
|
|
@@ -257,20 +97,6 @@ status() {
|
|
|
257
97
|
}
|
|
258
98
|
|
|
259
99
|
case "$COMMAND" in
|
|
260
|
-
install)
|
|
261
|
-
require_cmds
|
|
262
|
-
if [[ -z "$GATEWAY_URL" || -z "$API_KEY" ]]; then
|
|
263
|
-
echo "--gateway-url and --api-key are required for install" >&2
|
|
264
|
-
exit 1
|
|
265
|
-
fi
|
|
266
|
-
write_config
|
|
267
|
-
write_plugin
|
|
268
|
-
echo "Merged Subconscious OpenCode provider into $OPENCODE_CONFIG"
|
|
269
|
-
if [[ -f "$PLUGIN_FILE" ]]; then
|
|
270
|
-
echo "Installed compaction reporting plugin at $PLUGIN_FILE"
|
|
271
|
-
fi
|
|
272
|
-
echo "Launch OpenCode with: subc opencode"
|
|
273
|
-
;;
|
|
274
100
|
uninstall)
|
|
275
101
|
uninstall_config
|
|
276
102
|
echo "Removed Subconscious OpenCode files; left $OPENCODE_CONFIG in place"
|
|
@@ -1,9 +1,16 @@
|
|
|
1
|
-
// OpenCode loads
|
|
1
|
+
// OpenCode loads these plugins. The host package is not a dependency of the CLI,
|
|
2
|
+
// so only the hooks our plugins use are declared.
|
|
2
3
|
declare module '@opencode-ai/plugin' {
|
|
4
|
+
type ProviderConfig = {
|
|
5
|
+
options?: Record<string, unknown> & { fetch?: typeof fetch };
|
|
6
|
+
};
|
|
3
7
|
export type Plugin = () => Promise<{
|
|
4
|
-
'experimental.session.compacting'
|
|
8
|
+
'experimental.session.compacting'?: (input: {
|
|
5
9
|
sessionID: string;
|
|
6
10
|
}) => Promise<void>;
|
|
7
|
-
event
|
|
11
|
+
event?: (args: { event: { type: string } }) => Promise<void>;
|
|
12
|
+
config?: (config: {
|
|
13
|
+
provider?: Record<string, ProviderConfig>;
|
|
14
|
+
}) => Promise<void>;
|
|
8
15
|
}>;
|
|
9
16
|
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Keep OpenCode's requests to Subconscious at the newest 30 images.
|
|
3
|
+
*
|
|
4
|
+
* OpenCode resends every screenshot on every turn, so a long session's upload
|
|
5
|
+
* grows until the gateway refuses it. This gives the `subconscious` provider a
|
|
6
|
+
* fetch that trims the request body before it leaves (bin/runbook/image-window),
|
|
7
|
+
* the same rule the gateway applies, so Subconscious Cache still reuses the
|
|
8
|
+
* rest. OpenCode reads provider settings after plugins' config hooks run, so a
|
|
9
|
+
* function set here becomes the provider's fetch.
|
|
10
|
+
*
|
|
11
|
+
* Loaded by path from the launch config; nothing is written to disk.
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
import type { Plugin } from '@opencode-ai/plugin';
|
|
15
|
+
import { windowFetch } from '../image-window/window.js';
|
|
16
|
+
|
|
17
|
+
export const SubconsciousImageWindow: Plugin = async () => ({
|
|
18
|
+
config: async (config) => {
|
|
19
|
+
const provider = config.provider?.subconscious;
|
|
20
|
+
if (!provider) return;
|
|
21
|
+
const base = provider.options?.fetch ?? fetch;
|
|
22
|
+
provider.options = { ...provider.options, fetch: windowFetch(base) };
|
|
23
|
+
},
|
|
24
|
+
});
|