subconscious-cli 4.0.3 → 4.0.5
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 +17 -7
- package/bin/agents.js +12 -0
- package/bin/branding.js +2 -3
- package/bin/colors.js +9 -0
- package/bin/profiles.js +33 -0
- package/bin/registry.generated.json +30 -0
- package/bin/runbook/README.md +3 -1
- package/bin/runbook/deepseek-harness/run.sh +109 -0
- package/bin/update-check.js +39 -15
- package/package.json +3 -2
package/README.md
CHANGED
|
@@ -21,8 +21,8 @@ never block the requested command. Set `SUBC_DISABLE_UPDATE_CHECK=1` to suppress
|
|
|
21
21
|
the check in offline automation.
|
|
22
22
|
|
|
23
23
|
Login creates both the saved credential and a ready-to-use `default` profile,
|
|
24
|
-
so Claude Code, Codex, and
|
|
25
|
-
and Pi integrations are installed per agent:
|
|
24
|
+
so Claude Code, Codex, OpenCode, and DeepSeek Harness can launch immediately.
|
|
25
|
+
Persistent editor and Pi integrations are installed per agent:
|
|
26
26
|
|
|
27
27
|
```bash
|
|
28
28
|
subc cursor install
|
|
@@ -57,6 +57,7 @@ subc claude --continue
|
|
|
57
57
|
subc codex exec "write a test"
|
|
58
58
|
subc opencode
|
|
59
59
|
subc pi
|
|
60
|
+
subc dsh
|
|
60
61
|
```
|
|
61
62
|
|
|
62
63
|
## Supported agents
|
|
@@ -71,8 +72,9 @@ The packaged integrations live in `cli/bin/runbook`.
|
|
|
71
72
|
| `subc cursor install` | Install/update Cursor conversation and compaction hooks |
|
|
72
73
|
| `subc copilot install` | Install/update the VS Code custom endpoint and Copilot hooks |
|
|
73
74
|
| `subc pi` | Refresh the Pi provider from the live catalog, then launch |
|
|
75
|
+
| `subc dsh` | Launch the DeepSeek Harness Web UI with a temporary provider populated from the live catalog |
|
|
74
76
|
|
|
75
|
-
If Claude Code, Codex, or
|
|
77
|
+
If Claude Code, Codex, OpenCode, or DeepSeek Harness is missing, an interactive terminal offers
|
|
76
78
|
to install it before launching. Pi refreshes its Subconscious provider on every
|
|
77
79
|
`subc pi` launch while preserving all other providers in `models.json`; its
|
|
78
80
|
executable must already be installed.
|
|
@@ -112,6 +114,13 @@ Manage Language Models UI. The install scripts print the relevant next steps.
|
|
|
112
114
|
The runbook scripts require Bash. Cursor, Copilot, Pi, and Codex hook merge
|
|
113
115
|
also require `jq`; Cursor and Copilot also require `curl`.
|
|
114
116
|
|
|
117
|
+
`subc dsh` defaults to the DeepSeek Harness Web UI. It injects an ephemeral
|
|
118
|
+
Cordis overlay containing the active gateway URL, selected model, token limits,
|
|
119
|
+
client header, and every model returned by `/v1/models`; the API key remains in
|
|
120
|
+
the process environment and is never written into the overlay. The temporary
|
|
121
|
+
file is removed when Harness exits, and existing `$DSH_HOME` settings are not
|
|
122
|
+
rewritten. Run a one-shot task with `subc dsh headless "PROMPT"`.
|
|
123
|
+
|
|
115
124
|
## Runbook profiles
|
|
116
125
|
|
|
117
126
|
`subc login` automatically creates:
|
|
@@ -121,8 +130,8 @@ also require `jq`; Cursor and Copilot also require `curl`.
|
|
|
121
130
|
```
|
|
122
131
|
|
|
123
132
|
The file is mode `600` and contains the shared gateway URL, API key, model,
|
|
124
|
-
optional per-agent key overrides, and all Claude/Codex/OpenCode/Pi/Copilot
|
|
125
|
-
context and output settings used by the packaged runbook scripts.
|
|
133
|
+
optional per-agent key overrides, and all Claude/Codex/OpenCode/Pi/Copilot/
|
|
134
|
+
DeepSeek Harness context and output settings used by the packaged runbook scripts.
|
|
126
135
|
|
|
127
136
|
```bash
|
|
128
137
|
subc config # list every profile and its file path
|
|
@@ -186,8 +195,9 @@ export SUBCONSCIOUS_MODEL=subconscious/glm-5.2
|
|
|
186
195
|
```
|
|
187
196
|
|
|
188
197
|
Every launch and install fetches the same live catalog without caching. Codex,
|
|
189
|
-
OpenCode, Pi, Copilot, and
|
|
190
|
-
profile model is listed first only while the gateway still
|
|
198
|
+
OpenCode, Pi, Copilot, Cursor, and DeepSeek Harness receive the complete model
|
|
199
|
+
list. The selected profile model is listed first only while the gateway still
|
|
200
|
+
advertises it.
|
|
191
201
|
OpenCode rebuilds its isolated runtime provider on every `subc opencode` launch,
|
|
192
202
|
so models left in older OpenCode configuration files do not leak into the list.
|
|
193
203
|
If a saved profile default has been removed, launches use the first live model;
|
package/bin/agents.js
CHANGED
|
@@ -232,6 +232,18 @@ const AGENT_HELP = {
|
|
|
232
232
|
['ARGS...', 'Pass arguments directly to Pi'],
|
|
233
233
|
],
|
|
234
234
|
},
|
|
235
|
+
'deepseek-harness': {
|
|
236
|
+
usage: 'subc [-p NAME] dsh [web|headless] [--model MODEL] [Harness arguments...]',
|
|
237
|
+
behavior:
|
|
238
|
+
'Launches DeepSeek Harness with a temporary Subconscious provider containing every live gateway model. Web mode is the default.',
|
|
239
|
+
options: [
|
|
240
|
+
['help', 'Show this help'],
|
|
241
|
+
['web', 'Launch the DeepSeek Harness Web UI (default)'],
|
|
242
|
+
['headless PROMPT', 'Run one headless task and exit'],
|
|
243
|
+
['--model MODEL', 'Set the initial model for new Harness sessions'],
|
|
244
|
+
['ARGS...', 'Pass remaining arguments to the selected Harness mode'],
|
|
245
|
+
],
|
|
246
|
+
},
|
|
235
247
|
};
|
|
236
248
|
|
|
237
249
|
export function isAgentHelpRequest(argv = []) {
|
package/bin/branding.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { colorEnabled } from './colors.js';
|
|
1
|
+
import { BRAND_ORANGE, colorEnabled } from './colors.js';
|
|
2
2
|
|
|
3
3
|
// Pre-rendered from assets/imgs/logo.png as portable, 7-bit ASCII art.
|
|
4
4
|
const LOGO = [
|
|
@@ -20,7 +20,6 @@ const LOGO = [
|
|
|
20
20
|
' ###### #####',
|
|
21
21
|
].join('\n');
|
|
22
22
|
|
|
23
|
-
const ORANGE = '\x1b[38;2;255;92;40m';
|
|
24
23
|
const BOLD = '\x1b[1m';
|
|
25
24
|
const RESET = '\x1b[0m';
|
|
26
25
|
|
|
@@ -34,6 +33,6 @@ export function renderBanner(options = {}) {
|
|
|
34
33
|
// still get the same logo without ANSI styling.
|
|
35
34
|
if (!isTTY || term === 'dumb') return ` ${title}`;
|
|
36
35
|
|
|
37
|
-
const logo = color ? `${
|
|
36
|
+
const logo = color ? `${BRAND_ORANGE}${LOGO}${RESET}` : LOGO;
|
|
38
37
|
return `${logo}\n\n ${title}`;
|
|
39
38
|
}
|
package/bin/colors.js
CHANGED
|
@@ -10,6 +10,11 @@ export const colorEnabled =
|
|
|
10
10
|
(forceColor || process.stdout.isTTY === true);
|
|
11
11
|
|
|
12
12
|
const ansi = (code) => (colorEnabled ? `\x1b[${code}m` : '');
|
|
13
|
+
const rgb = (red, green, blue) =>
|
|
14
|
+
colorEnabled ? `\x1b[38;2;${red};${green};${blue}m` : '';
|
|
15
|
+
const bgRgb = (red, green, blue) =>
|
|
16
|
+
colorEnabled ? `\x1b[48;2;${red};${green};${blue}m` : '';
|
|
17
|
+
export const BRAND_ORANGE = '\x1b[38;2;255;92;40m';
|
|
13
18
|
|
|
14
19
|
export const c = {
|
|
15
20
|
reset: ansi(0),
|
|
@@ -20,6 +25,10 @@ export const c = {
|
|
|
20
25
|
red: ansi(31),
|
|
21
26
|
yellow: ansi(33),
|
|
22
27
|
magenta: ansi(35),
|
|
28
|
+
black: ansi(30),
|
|
29
|
+
orange: colorEnabled ? BRAND_ORANGE : '',
|
|
30
|
+
orangeSoft: rgb(255, 145, 105),
|
|
31
|
+
bgOrange: bgRgb(255, 92, 40),
|
|
23
32
|
underline: ansi(4),
|
|
24
33
|
inverse: ansi(7),
|
|
25
34
|
};
|
package/bin/profiles.js
CHANGED
|
@@ -44,6 +44,7 @@ export const RUNBOOK_DEFAULTS = {
|
|
|
44
44
|
CURSOR_API_KEY: '',
|
|
45
45
|
COPILOT_API_KEY: '',
|
|
46
46
|
PI_API_KEY: '',
|
|
47
|
+
DEEPSEEK_HARNESS_API_KEY: '',
|
|
47
48
|
CLAUDE_CODE_AUTO_COMPACT_WINDOW: '1000000',
|
|
48
49
|
CLAUDE_CODE_MAX_CONTEXT_TOKENS: '3000000',
|
|
49
50
|
MAX_CONCURRENT_SUBAGENTS: '4',
|
|
@@ -57,6 +58,8 @@ export const RUNBOOK_DEFAULTS = {
|
|
|
57
58
|
OPENCODE_OUTPUT_LIMIT: '65536',
|
|
58
59
|
PI_CONTEXT_WINDOW: '5000000',
|
|
59
60
|
PI_MAX_TOKENS: '65536',
|
|
61
|
+
DEEPSEEK_HARNESS_CONTEXT_WINDOW: '5000000',
|
|
62
|
+
DEEPSEEK_HARNESS_MAX_TOKENS: '65536',
|
|
60
63
|
COPILOT_MAX_INPUT_TOKENS: '5000000',
|
|
61
64
|
COPILOT_MAX_OUTPUT_TOKENS: '65536',
|
|
62
65
|
VSCODE_APP: '',
|
|
@@ -238,6 +241,26 @@ const SETTINGS = {
|
|
|
238
241
|
type: 'integer',
|
|
239
242
|
min: 1,
|
|
240
243
|
},
|
|
244
|
+
DEEPSEEK_HARNESS_API_KEY: {
|
|
245
|
+
key: 'DEEPSEEK_HARNESS_API_KEY',
|
|
246
|
+
label: 'DeepSeek Harness API key',
|
|
247
|
+
description: 'DeepSeek Harness credential override; blank uses API_KEY.',
|
|
248
|
+
type: 'secret',
|
|
249
|
+
},
|
|
250
|
+
DEEPSEEK_HARNESS_CONTEXT_WINDOW: {
|
|
251
|
+
key: 'DEEPSEEK_HARNESS_CONTEXT_WINDOW',
|
|
252
|
+
label: 'Context window',
|
|
253
|
+
description: 'Context capacity advertised to DeepSeek Harness.',
|
|
254
|
+
type: 'integer',
|
|
255
|
+
min: 1,
|
|
256
|
+
},
|
|
257
|
+
DEEPSEEK_HARNESS_MAX_TOKENS: {
|
|
258
|
+
key: 'DEEPSEEK_HARNESS_MAX_TOKENS',
|
|
259
|
+
label: 'Maximum output tokens',
|
|
260
|
+
description: 'Output capacity advertised to DeepSeek Harness.',
|
|
261
|
+
type: 'integer',
|
|
262
|
+
min: 1,
|
|
263
|
+
},
|
|
241
264
|
};
|
|
242
265
|
|
|
243
266
|
const AGENT_SETTING_KEYS = {
|
|
@@ -267,6 +290,11 @@ const AGENT_SETTING_KEYS = {
|
|
|
267
290
|
'VSCODE_APP',
|
|
268
291
|
],
|
|
269
292
|
pi: ['PI_API_KEY', 'PI_CONTEXT_WINDOW', 'PI_MAX_TOKENS'],
|
|
293
|
+
'deepseek-harness': [
|
|
294
|
+
'DEEPSEEK_HARNESS_API_KEY',
|
|
295
|
+
'DEEPSEEK_HARNESS_CONTEXT_WINDOW',
|
|
296
|
+
'DEEPSEEK_HARNESS_MAX_TOKENS',
|
|
297
|
+
],
|
|
270
298
|
};
|
|
271
299
|
|
|
272
300
|
const GROUP_KEYS = [
|
|
@@ -313,6 +341,7 @@ OPENCODE_API_KEY={OPENCODE_API_KEY}
|
|
|
313
341
|
CURSOR_API_KEY={CURSOR_API_KEY}
|
|
314
342
|
COPILOT_API_KEY={COPILOT_API_KEY}
|
|
315
343
|
PI_API_KEY={PI_API_KEY}
|
|
344
|
+
DEEPSEEK_HARNESS_API_KEY={DEEPSEEK_HARNESS_API_KEY}
|
|
316
345
|
|
|
317
346
|
# Claude Code
|
|
318
347
|
# Leave CLAUDE_GATEWAY_URL blank to use GATEWAY_URL above.
|
|
@@ -337,6 +366,10 @@ OPENCODE_OUTPUT_LIMIT={OPENCODE_OUTPUT_LIMIT}
|
|
|
337
366
|
PI_CONTEXT_WINDOW={PI_CONTEXT_WINDOW}
|
|
338
367
|
PI_MAX_TOKENS={PI_MAX_TOKENS}
|
|
339
368
|
|
|
369
|
+
# DeepSeek Harness
|
|
370
|
+
DEEPSEEK_HARNESS_CONTEXT_WINDOW={DEEPSEEK_HARNESS_CONTEXT_WINDOW}
|
|
371
|
+
DEEPSEEK_HARNESS_MAX_TOKENS={DEEPSEEK_HARNESS_MAX_TOKENS}
|
|
372
|
+
|
|
340
373
|
# GitHub Copilot
|
|
341
374
|
COPILOT_MAX_INPUT_TOKENS={COPILOT_MAX_INPUT_TOKENS}
|
|
342
375
|
COPILOT_MAX_OUTPUT_TOKENS={COPILOT_MAX_OUTPUT_TOKENS}
|
|
@@ -291,6 +291,36 @@
|
|
|
291
291
|
"uninstall"
|
|
292
292
|
]
|
|
293
293
|
}
|
|
294
|
+
},
|
|
295
|
+
{
|
|
296
|
+
"id": "deepseek-harness",
|
|
297
|
+
"command": "dsh",
|
|
298
|
+
"name": "DeepSeek Harness",
|
|
299
|
+
"aliases": [
|
|
300
|
+
"deepseek-harness",
|
|
301
|
+
"deepseek"
|
|
302
|
+
],
|
|
303
|
+
"description": "Launch DeepSeek Harness with an ephemeral Subconscious provider populated from the live model catalog.",
|
|
304
|
+
"framework": "DeepSeek Harness",
|
|
305
|
+
"language": "shell",
|
|
306
|
+
"category": "coding-agent",
|
|
307
|
+
"tags": [
|
|
308
|
+
"local",
|
|
309
|
+
"web",
|
|
310
|
+
"agents"
|
|
311
|
+
],
|
|
312
|
+
"protocol": "openai",
|
|
313
|
+
"homepage": "https://www.deepseek.com/harness/en/",
|
|
314
|
+
"bin": "dsh",
|
|
315
|
+
"install": {
|
|
316
|
+
"darwin": "npm i -g @deepseek-ai/dsh",
|
|
317
|
+
"linux": "npm i -g @deepseek-ai/dsh",
|
|
318
|
+
"win32": "npm i -g @deepseek-ai/dsh"
|
|
319
|
+
},
|
|
320
|
+
"runbook": {
|
|
321
|
+
"mode": "launch",
|
|
322
|
+
"script": "deepseek-harness/run.sh"
|
|
323
|
+
}
|
|
294
324
|
}
|
|
295
325
|
]
|
|
296
326
|
}
|
package/bin/runbook/README.md
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
# Coding-agent integrations
|
|
2
2
|
|
|
3
3
|
These scripts are part of `subc`. They launch or surgically install Claude Code,
|
|
4
|
-
Codex, OpenCode, Cursor, Copilot, and Pi against the
|
|
4
|
+
Codex, OpenCode, DeepSeek Harness, Cursor, Copilot, and Pi against the
|
|
5
|
+
Subconscious gateway.
|
|
5
6
|
|
|
6
7
|
`subc` reads `~/.subconscious/profiles/<name>.env` and injects those values into
|
|
7
8
|
the scripts, so users do not need a sibling `.env` file. When a script is run
|
|
@@ -15,6 +16,7 @@ Included integrations:
|
|
|
15
16
|
- `cursor/install.sh`, `hook.sh`, and `hooks.json`
|
|
16
17
|
- `copilot/install.sh`, `hook.sh`, and `hooks.json`
|
|
17
18
|
- `pi/install.sh`, `run.sh`, and `subconscious-compaction.ts`
|
|
19
|
+
- `deepseek-harness/run.sh`
|
|
18
20
|
|
|
19
21
|
Each CLI-enabled entry in `agents/registry.json` points here with a `runbook`
|
|
20
22
|
block. Persistent writes are merge/unmerge only: they never replace a user's
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Launch DeepSeek Harness with a temporary Cordis overlay that adds the live
|
|
3
|
+
# Subconscious catalog. The user's DSH settings and profiles are not rewritten.
|
|
4
|
+
|
|
5
|
+
set -euo pipefail
|
|
6
|
+
|
|
7
|
+
GATEWAY_URL="${GATEWAY_URL:-}"
|
|
8
|
+
API_KEY="${DEEPSEEK_HARNESS_API_KEY:-${API_KEY:-}}"
|
|
9
|
+
MODEL="${MODEL:-subconscious/glm-5.2}"
|
|
10
|
+
CONTEXT_WINDOW="${DEEPSEEK_HARNESS_CONTEXT_WINDOW:-5000000}"
|
|
11
|
+
MAX_TOKENS="${DEEPSEEK_HARNESS_MAX_TOKENS:-65536}"
|
|
12
|
+
|
|
13
|
+
DEFAULT_SUBCONSCIOUS_MODELS="subconscious/glm-5.2
|
|
14
|
+
subconscious/tim-qwen3.6-27b
|
|
15
|
+
subconscious/deepseek-v4-flash-marathon"
|
|
16
|
+
|
|
17
|
+
if [[ -z "$GATEWAY_URL" || -z "$API_KEY" ]]; then
|
|
18
|
+
echo "error: GATEWAY_URL and API_KEY are required to launch DeepSeek Harness" >&2
|
|
19
|
+
exit 1
|
|
20
|
+
fi
|
|
21
|
+
if [[ ! "$CONTEXT_WINDOW" =~ ^[1-9][0-9]*$ ]]; then
|
|
22
|
+
echo "error: DEEPSEEK_HARNESS_CONTEXT_WINDOW must be a positive integer" >&2
|
|
23
|
+
exit 1
|
|
24
|
+
fi
|
|
25
|
+
if [[ ! "$MAX_TOKENS" =~ ^[1-9][0-9]*$ ]]; then
|
|
26
|
+
echo "error: DEEPSEEK_HARNESS_MAX_TOKENS must be a positive integer" >&2
|
|
27
|
+
exit 1
|
|
28
|
+
fi
|
|
29
|
+
|
|
30
|
+
SUPPORTED_MODELS=()
|
|
31
|
+
add_supported_model() {
|
|
32
|
+
local model_id="$1" existing
|
|
33
|
+
[[ -n "$model_id" ]] || return 0
|
|
34
|
+
if [[ ! "$model_id" =~ ^[-A-Za-z0-9._:/+]+$ ]]; then
|
|
35
|
+
echo "error: invalid model id: $model_id" >&2
|
|
36
|
+
exit 1
|
|
37
|
+
fi
|
|
38
|
+
if [[ "${#SUPPORTED_MODELS[@]}" -gt 0 ]]; then
|
|
39
|
+
for existing in "${SUPPORTED_MODELS[@]}"; do
|
|
40
|
+
[[ "$existing" == "$model_id" ]] && return 0
|
|
41
|
+
done
|
|
42
|
+
fi
|
|
43
|
+
SUPPORTED_MODELS+=("$model_id")
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
add_supported_model "$MODEL"
|
|
47
|
+
while IFS= read -r model_id; do
|
|
48
|
+
add_supported_model "$model_id"
|
|
49
|
+
done <<< "${SUBCONSCIOUS_MODELS:-$DEFAULT_SUBCONSCIOUS_MODELS}"
|
|
50
|
+
|
|
51
|
+
OVERLAY_DIR="$(mktemp -d "${TMPDIR:-/tmp}/subc-dsh.XXXXXX")"
|
|
52
|
+
OVERLAY_FILE="${OVERLAY_DIR}/subconscious.cordis.yml"
|
|
53
|
+
cleanup() {
|
|
54
|
+
rm -f "$OVERLAY_FILE"
|
|
55
|
+
rmdir "$OVERLAY_DIR" 2>/dev/null || true
|
|
56
|
+
}
|
|
57
|
+
trap cleanup EXIT HUP INT TERM
|
|
58
|
+
|
|
59
|
+
{
|
|
60
|
+
printf '%s\n' \
|
|
61
|
+
'# Generated temporarily by subc. Contains no API key.' \
|
|
62
|
+
'- id: llm-pi-ai' \
|
|
63
|
+
' config:' \
|
|
64
|
+
' providers:' \
|
|
65
|
+
' subconscious:' \
|
|
66
|
+
' apiKeyEnv: SUBCONSCIOUS_API_KEY' \
|
|
67
|
+
' displayName: Subconscious Gateway' \
|
|
68
|
+
' api: openai-completions' \
|
|
69
|
+
' baseURL: !!js process.env.SUBCONSCIOUS_DSH_BASE_URL' \
|
|
70
|
+
' headers:' \
|
|
71
|
+
' x-subconscious-client: deepseek-harness' \
|
|
72
|
+
' compat:' \
|
|
73
|
+
' supportsDeveloperRole: false' \
|
|
74
|
+
' maxTokensField: max_tokens' \
|
|
75
|
+
" defaultContextWindow: ${CONTEXT_WINDOW}" \
|
|
76
|
+
" defaultMaxTokens: ${MAX_TOKENS}" \
|
|
77
|
+
' models:'
|
|
78
|
+
for model_id in "${SUPPORTED_MODELS[@]}"; do
|
|
79
|
+
printf " - id: '%s'\n" "$model_id"
|
|
80
|
+
printf " name: '%s'\n" "$model_id"
|
|
81
|
+
printf " contextWindow: %s\n" "$CONTEXT_WINDOW"
|
|
82
|
+
printf " maxTokens: %s\n" "$MAX_TOKENS"
|
|
83
|
+
done
|
|
84
|
+
printf '%s\n' \
|
|
85
|
+
'- id: agent-default-model' \
|
|
86
|
+
' config:' \
|
|
87
|
+
' provider: subconscious' \
|
|
88
|
+
" model: '${MODEL}'"
|
|
89
|
+
} >"$OVERLAY_FILE"
|
|
90
|
+
chmod 600 "$OVERLAY_FILE"
|
|
91
|
+
|
|
92
|
+
export SUBCONSCIOUS_API_KEY="$API_KEY"
|
|
93
|
+
export SUBCONSCIOUS_DSH_BASE_URL="${GATEWAY_URL%/}/v1"
|
|
94
|
+
|
|
95
|
+
mode="web"
|
|
96
|
+
if [[ "${1:-}" == "web" || "${1:-}" == "headless" ]]; then
|
|
97
|
+
mode="$1"
|
|
98
|
+
shift
|
|
99
|
+
fi
|
|
100
|
+
|
|
101
|
+
set +e
|
|
102
|
+
if [[ "$mode" == "headless" ]]; then
|
|
103
|
+
dsh --profile headless --patch "$OVERLAY_FILE" "$@"
|
|
104
|
+
else
|
|
105
|
+
dsh web --patch "$OVERLAY_FILE" "$@"
|
|
106
|
+
fi
|
|
107
|
+
status=$?
|
|
108
|
+
set -e
|
|
109
|
+
exit "$status"
|
package/bin/update-check.js
CHANGED
|
@@ -1,11 +1,18 @@
|
|
|
1
1
|
import fs from 'node:fs/promises';
|
|
2
2
|
import { spawn } from 'node:child_process';
|
|
3
3
|
import readline from 'node:readline';
|
|
4
|
-
import { c } from './colors.js';
|
|
4
|
+
import { c, colorEnabled } from './colors.js';
|
|
5
5
|
|
|
6
6
|
export const PACKAGE_NAME = 'subconscious-cli';
|
|
7
7
|
export const UPDATE_CHECK_TIMEOUT_MS = 1500;
|
|
8
8
|
const UPDATE_ACTIONS = ['Update now', 'Skip for now'];
|
|
9
|
+
const UPDATE_LOGO = [
|
|
10
|
+
' ● ●',
|
|
11
|
+
' ╲ ╱ ',
|
|
12
|
+
'●─── ╳ ───●',
|
|
13
|
+
' ╱ ╲ ',
|
|
14
|
+
' ● ●',
|
|
15
|
+
];
|
|
9
16
|
|
|
10
17
|
function parseVersion(version) {
|
|
11
18
|
const match = String(version)
|
|
@@ -85,18 +92,32 @@ export async function fetchLatestVersion(options = {}) {
|
|
|
85
92
|
}
|
|
86
93
|
|
|
87
94
|
export function renderUpdateNotice(installedVersion, latestVersion) {
|
|
88
|
-
const
|
|
89
|
-
const
|
|
90
|
-
const
|
|
91
|
-
const
|
|
92
|
-
const
|
|
93
|
-
|
|
95
|
+
const logoWidth = Math.max(...UPDATE_LOGO.map((line) => line.length));
|
|
96
|
+
const textWidth = 24;
|
|
97
|
+
const gap = ' ';
|
|
98
|
+
const innerWidth = logoWidth + gap.length + textWidth + 2;
|
|
99
|
+
const border = `${c.orange}╭${'─'.repeat(innerWidth)}╮${c.reset}`;
|
|
100
|
+
const bottom = `${c.orange}╰${'─'.repeat(innerWidth)}╯${c.reset}`;
|
|
101
|
+
const text = [
|
|
102
|
+
{ raw: 'Subconscious CLI', value: `${c.orange}${c.bold}Subconscious CLI${c.reset}` },
|
|
103
|
+
{ raw: 'Update available', value: `${c.bold}Update available${c.reset}` },
|
|
104
|
+
{ raw: '', value: '' },
|
|
105
|
+
{
|
|
106
|
+
raw: `${installedVersion} → ${latestVersion}`,
|
|
107
|
+
value: `${c.dim}${installedVersion}${c.reset} ${c.orange}→${c.reset} ${c.orange}${c.bold}${latestVersion}${c.reset}`,
|
|
108
|
+
},
|
|
109
|
+
{ raw: '', value: '' },
|
|
110
|
+
];
|
|
111
|
+
const row = (logo, copy) => {
|
|
112
|
+
const logoPadding = ' '.repeat(logoWidth - logo.length);
|
|
113
|
+
const textPadding = ' '.repeat(textWidth - copy.raw.length);
|
|
114
|
+
return `${c.orange}│${c.reset} ${c.orange}${logo}${logoPadding}${c.reset}${gap}${copy.value}${textPadding} ${c.orange}│${c.reset}`;
|
|
115
|
+
};
|
|
94
116
|
|
|
95
117
|
return [
|
|
96
|
-
` ${
|
|
97
|
-
` ${row(
|
|
98
|
-
` ${
|
|
99
|
-
` ${c.yellow}${border}${c.reset}`,
|
|
118
|
+
` ${border}`,
|
|
119
|
+
...UPDATE_LOGO.map((logo, index) => ` ${row(logo, text[index])}`),
|
|
120
|
+
` ${bottom}`,
|
|
100
121
|
].join('\n');
|
|
101
122
|
}
|
|
102
123
|
|
|
@@ -110,11 +131,14 @@ export function renderUpdateOptions(selectedIndex = 0, versions = {}) {
|
|
|
110
131
|
|
|
111
132
|
return UPDATE_ACTIONS.map((label, index) => {
|
|
112
133
|
const active = index === selectedIndex;
|
|
113
|
-
const pointer = active ? `${c.
|
|
134
|
+
const pointer = active ? `${c.orange}›${c.reset}` : ' ';
|
|
135
|
+
const activeStyle = colorEnabled
|
|
136
|
+
? `${c.bgOrange}${c.black}`
|
|
137
|
+
: c.inverse;
|
|
114
138
|
const option = active
|
|
115
|
-
? `${
|
|
139
|
+
? `${activeStyle}${c.bold} ${label} ${c.reset}`
|
|
116
140
|
: ` ${label} `;
|
|
117
|
-
const descriptionStyle = active ? c.
|
|
141
|
+
const descriptionStyle = active ? c.orangeSoft : c.dim;
|
|
118
142
|
return ` ${pointer} ${option}\n ${descriptionStyle}${descriptions[index]}${c.reset}`;
|
|
119
143
|
}).join('\n');
|
|
120
144
|
}
|
|
@@ -132,7 +156,7 @@ export async function selectUpdateAction(options = {}) {
|
|
|
132
156
|
const output = options.output || process.stderr;
|
|
133
157
|
const initiallyRaw = input.isRaw === true;
|
|
134
158
|
let selectedIndex = options.selectedIndex ?? 0;
|
|
135
|
-
const instructions = ` ${c.dim}Use
|
|
159
|
+
const instructions = ` ${c.dim}Use ${c.orange}↑/↓${c.reset}${c.dim} to select • ${c.orange}Enter${c.reset}${c.dim} to confirm${c.reset}`;
|
|
136
160
|
const render = () =>
|
|
137
161
|
`${renderUpdateOptions(selectedIndex, {
|
|
138
162
|
installedVersion: options.installedVersion,
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "subconscious-cli",
|
|
3
|
-
"version": "4.0.
|
|
4
|
-
"description": "CLI for Subconscious — run Claude Code, Codex, OpenCode, Cursor, Copilot, and Pi",
|
|
3
|
+
"version": "4.0.5",
|
|
4
|
+
"description": "CLI for Subconscious — run Claude Code, Codex, OpenCode, DeepSeek Harness, Cursor, Copilot, and Pi",
|
|
5
5
|
"bin": {
|
|
6
6
|
"subc": "bin/cli.js"
|
|
7
7
|
},
|
|
@@ -34,6 +34,7 @@
|
|
|
34
34
|
"cursor",
|
|
35
35
|
"copilot",
|
|
36
36
|
"pi",
|
|
37
|
+
"deepseek-harness",
|
|
37
38
|
"launcher"
|
|
38
39
|
],
|
|
39
40
|
"author": "Subconscious Systems",
|