subconscious-cli 6.0.0 → 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.
Files changed (76) hide show
  1. package/README.md +135 -2
  2. package/bin/agent-data.js +242 -0
  3. package/bin/agent-help.js +106 -0
  4. package/bin/agent-install.js +354 -0
  5. package/bin/agent-launch.js +199 -0
  6. package/bin/agent-spawn.js +137 -0
  7. package/bin/agents.js +284 -840
  8. package/bin/auth.js +89 -33
  9. package/bin/branding.js +3 -1
  10. package/bin/claude-picker.js +143 -0
  11. package/bin/cli.js +87 -20
  12. package/bin/clipboard-image.js +24 -5
  13. package/bin/colors.js +1 -1
  14. package/bin/feedback.js +71 -21
  15. package/bin/harness-manifest.js +286 -0
  16. package/bin/headless-args.js +35 -0
  17. package/bin/launch-values.js +25 -0
  18. package/bin/model-capabilities.js +12 -8
  19. package/bin/models.js +35 -19
  20. package/bin/native/subc-tui-darwin-amd64 +0 -0
  21. package/bin/native/subc-tui-darwin-arm64 +0 -0
  22. package/bin/native/subc-tui-linux-amd64 +0 -0
  23. package/bin/native/subc-tui-linux-arm64 +0 -0
  24. package/bin/native/subc-tui-windows-amd64.exe +0 -0
  25. package/bin/native/subc-tui-windows-arm64.exe +0 -0
  26. package/bin/opencode-provider.js +48 -5
  27. package/bin/profile-settings.js +129 -0
  28. package/bin/profiles.js +136 -449
  29. package/bin/runbook/README.md +66 -23
  30. package/bin/runbook/claude-code/agent.json +300 -0
  31. package/bin/runbook/claude-code/install.sh +9 -252
  32. package/bin/runbook/codex/agent.json +461 -0
  33. package/bin/runbook/codex/hooks-lib.sh +17 -4
  34. package/bin/runbook/codex/install.sh +0 -4
  35. package/bin/runbook/codex/run.sh +16 -235
  36. package/bin/runbook/copilot/agent.json +185 -0
  37. package/bin/runbook/copilot/install.sh +45 -63
  38. package/bin/runbook/cursor/agent.json +137 -0
  39. package/bin/runbook/cursor/install.sh +8 -35
  40. package/bin/runbook/deepseek-harness/agent.json +163 -0
  41. package/bin/runbook/deepseek-harness/run.sh +20 -59
  42. package/bin/runbook/image-window/index.ts +14 -0
  43. package/bin/runbook/image-window/window.d.ts +19 -0
  44. package/bin/runbook/image-window/window.js +140 -0
  45. package/bin/runbook/lib.sh +41 -0
  46. package/bin/runbook/opencode/agent.json +158 -0
  47. package/bin/runbook/opencode/install.sh +9 -183
  48. package/bin/runbook/opencode/opencode-plugin.d.ts +16 -0
  49. package/bin/runbook/opencode/subconscious-image-window.ts +24 -0
  50. package/bin/runbook/pi/agent.json +216 -0
  51. package/bin/runbook/pi/install.sh +18 -44
  52. package/bin/runbook/pi/run.sh +6 -18
  53. package/bin/runbook/pi/subconscious-compaction.ts +71 -49
  54. package/bin/runbook/shared.json +58 -0
  55. package/bin/runbook/subconscious-code/agent.json +156 -0
  56. package/bin/sessions.js +173 -58
  57. package/bin/tui.js +104 -32
  58. package/bin/update-check.js +54 -21
  59. package/bin/upgrade.js +67 -43
  60. package/bin/usage.js +47 -24
  61. package/bin/windows/agents.js +141 -37
  62. package/bin/windows/common.js +36 -25
  63. package/bin/windows/install.js +116 -34
  64. package/bin/windows/launch.js +260 -77
  65. package/bin/windows/pi-compaction.ts +68 -13
  66. package/bin/windows/process.js +210 -57
  67. package/bin/windows/setup.js +251 -56
  68. package/package.json +9 -4
  69. package/bin/registry.generated.json +0 -406
  70. package/bin/runbook/claude-code/run.sh +0 -254
  71. package/bin/runbook/model-capabilities.generated.sh +0 -9
  72. package/bin/runbook/opencode/provider.sh +0 -93
  73. package/bin/runbook/opencode/run.sh +0 -99
  74. package/bin/runbook/opencode/subconscious-compaction.ts +0 -100
  75. package/bin/runbook/subconscious-code/run.sh +0 -21
  76. package/bin/windows/claude.js +0 -71
@@ -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 setup ─────────────────────────────────
3
- # Point OpenCode at your gateway. Writes a provider config with session headers
4
- # so the gateway can correlate OpenCode requests into Conversations.
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
- # Quick start:
7
- # ./install.sh --gateway-url https://your-gateway.example --api-key sk-gw-...
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
- SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
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
- install|uninstall|status)
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"
@@ -0,0 +1,16 @@
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.
3
+ declare module '@opencode-ai/plugin' {
4
+ type ProviderConfig = {
5
+ options?: Record<string, unknown> & { fetch?: typeof fetch };
6
+ };
7
+ export type Plugin = () => Promise<{
8
+ 'experimental.session.compacting'?: (input: {
9
+ sessionID: string;
10
+ }) => Promise<void>;
11
+ event?: (args: { event: { type: string } }) => Promise<void>;
12
+ config?: (config: {
13
+ provider?: Record<string, ProviderConfig>;
14
+ }) => Promise<void>;
15
+ }>;
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
+ });
@@ -0,0 +1,216 @@
1
+ {
2
+ "id": "pi",
3
+ "command": "pi",
4
+ "aliases": [],
5
+ "name": "Pi",
6
+ "description": "Refresh Pi with the live Subconscious model catalog and launch the active profile model.",
7
+ "protocol": "openai",
8
+ "homepage": "https://pi.dev",
9
+ "install": {
10
+ "commands": null,
11
+ "method": null,
12
+ "package": null,
13
+ "version": null,
14
+ "minimum_version": null,
15
+ "verified": false,
16
+ "note": "No install command is defined; subc expects pi on PATH."
17
+ },
18
+ "runbook": {
19
+ "mode": "launch",
20
+ "script": "run.sh",
21
+ "setup_script": "install.sh",
22
+ "setup_actions": ["install", "status", "uninstall"],
23
+ "after_install": "Start a fresh session with subc pi."
24
+ },
25
+ "help": {
26
+ "usage": "subc [-p NAME] pi [help|install|status|uninstall] [Pi arguments...]",
27
+ "behavior": "Refreshes the persistent Subconscious provider from the live catalog, then launches Pi.",
28
+ "options": [
29
+ ["help", "Show this help"],
30
+ ["install", "Refresh the Subconscious provider without launching Pi"],
31
+ ["status", "Inspect the persistent Pi provider"],
32
+ ["uninstall", "Remove only the Subconscious Pi provider and extension"],
33
+ ["--model MODEL", "Override the profile model for this launch"]
34
+ ],
35
+ "args": ["ARGS...", "Pass arguments directly to Pi"]
36
+ },
37
+ "sessions": { "key": "pi", "portable": true },
38
+ "prerequisites": [
39
+ {
40
+ "command": "jq",
41
+ "needed_for": "install and every launch",
42
+ "required": true
43
+ }
44
+ ],
45
+ "launch": {
46
+ "argv": [
47
+ "pi",
48
+ "--provider",
49
+ "subconscious",
50
+ "--model",
51
+ "{model}",
52
+ "{args}"
53
+ ],
54
+ "headless_argv": [
55
+ "pi",
56
+ "--provider",
57
+ "subconscious",
58
+ "--model",
59
+ "{model}",
60
+ "--print",
61
+ "{args}"
62
+ ],
63
+ "headless_stdin": "{prompt}",
64
+ "headless_platforms": ["darwin", "linux"],
65
+ "resume": ["--session", "{sessionFile}"],
66
+ "handoff": ["{prompt}"],
67
+ "persistent_setup": true,
68
+ "note": "Each launch first runs install.sh install, which rewrites the persistent files below."
69
+ },
70
+ "inputs": [
71
+ {
72
+ "name": "PI_API_KEY",
73
+ "label": "Pi API key",
74
+ "description": "Pi-specific credential override; blank uses API_KEY.",
75
+ "type": "secret"
76
+ },
77
+ {
78
+ "name": "PI_CONTEXT_WINDOW",
79
+ "default": 5000000,
80
+ "label": "Context window",
81
+ "description": "Pi context window used to determine compaction.",
82
+ "type": "integer",
83
+ "min": 1
84
+ },
85
+ {
86
+ "name": "PI_MAX_TOKENS",
87
+ "default": 65536,
88
+ "label": "Maximum output tokens",
89
+ "description": "Maximum output tokens advertised to Pi.",
90
+ "type": "integer",
91
+ "min": 1
92
+ }
93
+ ],
94
+ "env": [],
95
+ "config": [
96
+ {
97
+ "kind": "file",
98
+ "path": "~/.pi/agent/models.json",
99
+ "lifetime": "persistent",
100
+ "value": {
101
+ "providers.subconscious.baseUrl": "{baseUrlV1}",
102
+ "providers.subconscious.api": "openai-completions",
103
+ "providers.subconscious.apiKey": "{apiKey}",
104
+ "providers.subconscious.headers": {
105
+ "x-subconscious-client": "pi"
106
+ },
107
+ "providers.subconscious.models[].contextWindow": "${PI_CONTEXT_WINDOW}",
108
+ "providers.subconscious.models[].maxTokens": "${PI_MAX_TOKENS}",
109
+ "providers.subconscious.models[].compat": {
110
+ "sendSessionAffinityHeaders": true,
111
+ "sessionAffinityFormat": "openai-nosession"
112
+ }
113
+ },
114
+ "description": "Subconscious provider, written by install.sh and merged in; other providers are kept. Mode 600; holds the key in plain text."
115
+ },
116
+ {
117
+ "kind": "file",
118
+ "path": "~/.pi/agent/subconscious.env",
119
+ "lifetime": "persistent",
120
+ "description": "SUBCONSCIOUS_GATEWAY_URL and SUBCONSCIOUS_API_KEY for the compaction extension (mode 600)."
121
+ },
122
+ {
123
+ "kind": "file",
124
+ "path": "~/.pi/agent/extensions/subconscious-compaction.ts",
125
+ "lifetime": "persistent",
126
+ "description": "Compaction reporting extension."
127
+ },
128
+ {
129
+ "kind": "dir",
130
+ "path": "~/.pi/agent/extensions/subconscious-image-window",
131
+ "lifetime": "persistent",
132
+ "description": "Extension that keeps requests to the newest 30 images."
133
+ }
134
+ ],
135
+ "capabilities": {
136
+ "compaction": {
137
+ "default": "on",
138
+ "on": {
139
+ "set_by_subc": true,
140
+ "kind": "config-field",
141
+ "name": "providers.subconscious.models[].contextWindow",
142
+ "value": "${PI_CONTEXT_WINDOW}",
143
+ "verified": false,
144
+ "note": "subc sets contextWindow. That Pi compacts relative to it comes only from the profile setting description.",
145
+ "config": "~/.pi/agent/models.json"
146
+ },
147
+ "off": {
148
+ "set_by_subc": false,
149
+ "kind": "config-field",
150
+ "name": "compaction.enabled",
151
+ "value": false,
152
+ "verified": false,
153
+ "note": "Upstream Pi setting. subc never sets it, and this repo does not confirm its location or behaviour.",
154
+ "config": "Pi settings (location unverified)"
155
+ },
156
+ "threshold": {
157
+ "set_by_subc": true,
158
+ "kind": "config-field",
159
+ "name": "providers.subconscious.models[].contextWindow",
160
+ "value": "${PI_CONTEXT_WINDOW}",
161
+ "verified": false,
162
+ "note": "subc sets contextWindow. That Pi compacts relative to it comes only from the profile setting description. Pi's reserveTokens also moves the trigger; subc never sets it.",
163
+ "semantics": "window",
164
+ "config": "~/.pi/agent/models.json"
165
+ }
166
+ },
167
+ "mcp": {
168
+ "configured_by_subc": false,
169
+ "transports": null,
170
+ "verified": false,
171
+ "note": "subc configures no MCP servers."
172
+ },
173
+ "headers": [
174
+ {
175
+ "name": "x-subconscious-client",
176
+ "value": "pi",
177
+ "on": "model requests",
178
+ "set_by_subc": true,
179
+ "verified": true
180
+ },
181
+ {
182
+ "name": "x-session-affinity",
183
+ "value": "session ID",
184
+ "on": "model requests",
185
+ "set_by_subc": true,
186
+ "verified": false,
187
+ "note": "Enabled by compat.sendSessionAffinityHeaders; the header name comes from an install.sh comment."
188
+ },
189
+ {
190
+ "name": "Authorization",
191
+ "value": "Bearer {apiKey}",
192
+ "on": "extension POSTs to {baseUrl}/v1/agent-hooks",
193
+ "set_by_subc": true,
194
+ "verified": true
195
+ }
196
+ ],
197
+ "hooks": [
198
+ {
199
+ "event": "session_before_compact",
200
+ "posts": "conversation_compaction phase=start",
201
+ "endpoint": "{baseUrl}/v1/agent-hooks",
202
+ "config": "~/.pi/agent/extensions/subconscious-compaction.ts",
203
+ "installed_by": ["launch", "install"],
204
+ "verified": true
205
+ },
206
+ {
207
+ "event": "session_compact",
208
+ "posts": "conversation_compaction phase=end",
209
+ "endpoint": "{baseUrl}/v1/agent-hooks",
210
+ "config": "~/.pi/agent/extensions/subconscious-compaction.ts",
211
+ "installed_by": ["launch", "install"],
212
+ "verified": true
213
+ }
214
+ ]
215
+ }
216
+ }