saving-token 0.1.0 → 1.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 +62 -30
- package/bin/saving-token.cjs +8 -3
- package/package.json +1 -1
- package/skills/saving-token/SKILL.md +12 -5
- package/skills/saving-token/assets/claude/saving-token-writer.md.template +2 -1
- package/skills/saving-token/assets/codex/saving-token-writer.toml.template +2 -1
- package/skills/saving-token/assets/cursor/saving-token-writer.md.template +2 -1
- package/skills/saving-token/scripts/setup.sh +175 -24
package/README.md
CHANGED
|
@@ -1,46 +1,81 @@
|
|
|
1
1
|
# saving-token
|
|
2
2
|
|
|
3
|
-
A native writer makes file changes; the
|
|
3
|
+
A native writer makes file changes; the host directs and reviews. The writer
|
|
4
|
+
model is selected during setup, while the host model and global defaults stay
|
|
5
|
+
unchanged.
|
|
4
6
|
|
|
5
|
-
Inspired by [karpathy-guidelines](https://github.com/multica-ai/andrej-karpathy-skills).
|
|
7
|
+
Inspired by [karpathy-guidelines](https://github.com/multica-ai/andrej-karpathy-skills).
|
|
8
|
+
|
|
9
|
+
The writer is used only when the host model is stronger; otherwise the host
|
|
10
|
+
works directly.
|
|
6
11
|
|
|
7
12
|
## Install
|
|
8
13
|
|
|
9
|
-
###
|
|
14
|
+
### Interactive setup
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
bash skills/saving-token/scripts/setup.sh
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
Use **Up/Down** and **Enter** to choose the platform, writer model, optional
|
|
21
|
+
reasoning effort, and final action. Press **Esc** to cancel. The final menu
|
|
22
|
+
starts on **Cancel**. Model entries are suggestions only; availability is not
|
|
23
|
+
checked. The effort menu includes the host default and values accepted by the
|
|
24
|
+
target; account and model support still depend on the host.
|
|
25
|
+
|
|
26
|
+
The model menu has no free-text entry. Use `--model` for a custom model ID or
|
|
27
|
+
for non-interactive setup:
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
bash skills/saving-token/scripts/setup.sh \
|
|
31
|
+
--target codex --model '<model-id>' --yes
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
`--target` and `--model` are required without a terminal. Add
|
|
35
|
+
`--reasoning-effort <effort>` when supported by the selected model. `--yes`
|
|
36
|
+
approves the displayed installation and replacements; it never chooses a
|
|
37
|
+
model. Rerun setup to change the writer. Extra files in an existing Skill
|
|
38
|
+
directory are preserved.
|
|
10
39
|
|
|
11
|
-
|
|
40
|
+
### npm wrapper
|
|
41
|
+
|
|
42
|
+
After publication, run:
|
|
12
43
|
|
|
13
44
|
```bash
|
|
14
45
|
npx saving-token@latest install --agent codex
|
|
15
46
|
```
|
|
16
47
|
|
|
17
|
-
|
|
48
|
+
The wrapper supports `install --agent codex` and keeps the interactive menus.
|
|
49
|
+
Use the Bash script directly for `--target`, `--model`, `--reasoning-effort`,
|
|
50
|
+
or `--yes`.
|
|
18
51
|
|
|
19
|
-
|
|
52
|
+
To refresh only the suggested models in an existing Codex installation, run:
|
|
20
53
|
|
|
21
54
|
```bash
|
|
22
|
-
|
|
55
|
+
npx saving-token@latest update-models --agent codex
|
|
23
56
|
```
|
|
24
57
|
|
|
25
|
-
|
|
58
|
+
It changes no writer configuration and shows no setup menus. Use the Bash
|
|
59
|
+
script with `--update-models --target claude` or `cursor` for those platforms.
|
|
60
|
+
|
|
61
|
+
### Installed paths
|
|
26
62
|
|
|
27
|
-
| Platform | Skill
|
|
63
|
+
| Platform | Skill | Writer configuration |
|
|
28
64
|
|---|---|---|
|
|
29
65
|
| Codex | `${CODEX_HOME:-~/.codex}/skills/saving-token/` | `${CODEX_HOME:-~/.codex}/agents/saving-token-writer.toml` |
|
|
30
66
|
| Claude Code | `~/.claude/skills/saving-token/` | `~/.claude/agents/saving-token-writer.md` |
|
|
31
67
|
| Cursor | `~/.cursor/skills/saving-token/` | `~/.cursor/agents/saving-token-writer.md` |
|
|
32
68
|
|
|
33
|
-
Restart the host, then invoke `$saving-token` in Codex or `/saving-token` in
|
|
69
|
+
Restart the host, then invoke `$saving-token` in Codex or `/saving-token` in
|
|
70
|
+
standalone Claude Code and Cursor. A generated configuration does not prove
|
|
71
|
+
runtime routing; verify the model in exposed task metadata when available.
|
|
72
|
+
Claude Code and Cursor may substitute a model under account or administrator
|
|
73
|
+
policy.
|
|
34
74
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
```
|
|
40
|
-
|
|
41
|
-
`--target` and `--model` are required without a terminal. Add `--reasoning-effort <effort>` only if supported by the selected model. Explicit `--model` skips the menu; `--yes` approves installation and displayed replacements, without choosing a model.
|
|
42
|
-
|
|
43
|
-
Rerun setup to change the writer model. Existing distributed Skill files and the writer configuration are replaced after confirmation; extra files in the Skill directory are preserved. Setup also works from the installed Skill's `scripts/setup.sh`.
|
|
75
|
+
The writer implements and verifies delegated changes. The host personally
|
|
76
|
+
reviews the actual changes and verification evidence against the requirements,
|
|
77
|
+
sends defects back to the same writer for fixes and re-review, and announces
|
|
78
|
+
completion only after review passes.
|
|
44
79
|
|
|
45
80
|
## Claude Code plugin
|
|
46
81
|
|
|
@@ -49,15 +84,12 @@ Rerun setup to change the writer model. Existing distributed Skill files and the
|
|
|
49
84
|
/plugin install saving-token@saving-token
|
|
50
85
|
```
|
|
51
86
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
- [`skills/saving-token/SKILL.md`](skills/saving-token/SKILL.md): canonical delegation and review rules.
|
|
57
|
-
- `skills/saving-token/scripts/setup.sh` and `assets/`: standalone installer and native agent templates.
|
|
58
|
-
- `agents/` and `.claude-plugin/`: Claude plugin writer and marketplace metadata.
|
|
59
|
-
- `AGENTS.md`, `CLAUDE.md`, [`CURSOR.md`](CURSOR.md), and `.cursor/rules/`: repository adapters that point to the Skill.
|
|
60
|
-
|
|
61
|
-
Other hosts can read the Skill or `AGENTS.md`, but delegation requires writable native subagents and independent model configuration. Without those capabilities, support is instruction-only.
|
|
87
|
+
The plugin collects `writer_model` through its configuration and leaves effort
|
|
88
|
+
to the host. Invoke `/saving-token:saving-token`; its writer is
|
|
89
|
+
`saving-token:saving-token-writer`. Use either the plugin or standalone setup.
|
|
62
90
|
|
|
63
|
-
Official references: [Codex subagents](https://developers.openai.com/codex/subagents),
|
|
91
|
+
Official references: [Codex subagents](https://developers.openai.com/codex/subagents),
|
|
92
|
+
[Claude subagents](https://code.claude.com/docs/en/sub-agents),
|
|
93
|
+
[Claude plugins](https://code.claude.com/docs/en/plugins-reference),
|
|
94
|
+
[Cursor subagents](https://cursor.com/docs/subagents), and
|
|
95
|
+
[Agent Skills](https://agentskills.io/specification).
|
package/bin/saving-token.cjs
CHANGED
|
@@ -8,11 +8,11 @@ const args = process.argv.slice(2);
|
|
|
8
8
|
|
|
9
9
|
if (
|
|
10
10
|
args.length !== 3 ||
|
|
11
|
-
args[0]
|
|
11
|
+
!['install', 'update-models'].includes(args[0]) ||
|
|
12
12
|
args[1] !== '--agent' ||
|
|
13
13
|
args[2] !== 'codex'
|
|
14
14
|
) {
|
|
15
|
-
console.error('Usage: saving-token install --agent codex');
|
|
15
|
+
console.error('Usage: saving-token <install|update-models> --agent codex');
|
|
16
16
|
process.exit(1);
|
|
17
17
|
}
|
|
18
18
|
|
|
@@ -24,7 +24,12 @@ const setupPath = path.join(
|
|
|
24
24
|
'scripts',
|
|
25
25
|
'setup.sh'
|
|
26
26
|
);
|
|
27
|
-
const
|
|
27
|
+
const setupArgs = [setupPath, '--target', 'codex'];
|
|
28
|
+
if (args[0] === 'update-models') {
|
|
29
|
+
setupArgs.push('--update-models');
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
const result = spawnSync('bash', setupArgs, {
|
|
28
33
|
stdio: 'inherit'
|
|
29
34
|
});
|
|
30
35
|
|
package/package.json
CHANGED
|
@@ -18,24 +18,31 @@ If your identity is `saving-token-writer` or `saving-token:saving-token-writer`,
|
|
|
18
18
|
- If a writable native writer or independent model configuration is unavailable, report instruction-only compatibility and ask before implementing directly.
|
|
19
19
|
- Configuration is not runtime proof. Check exposed model metadata and disclose mismatches; never silently substitute a model yourself. Claude Code and Cursor may apply host-level fallback.
|
|
20
20
|
|
|
21
|
+
## Model gate
|
|
22
|
+
|
|
23
|
+
- Delegate only when the current host model is stronger than the configured writer model.
|
|
24
|
+
- If the comparison is unknown, do not delegate; the parent completes the task directly under normal authorization.
|
|
25
|
+
|
|
21
26
|
## Delegate
|
|
22
27
|
|
|
23
28
|
- Delegate every file write, including edits, deletions, documents, temporary scripts, and formatting.
|
|
24
29
|
- Give goals and acceptance criteria, not implementation text to paste. Prefer file paths and issue locations over copied source or conversation history.
|
|
25
30
|
- Batch related changes into one scoped task and reuse the writer for revisions.
|
|
26
31
|
- The writer follows project rules and authorization boundaries, preserves user edits, implements directly, and runs relevant checks.
|
|
32
|
+
- Put exact focused commands in `Verify`; the writer runs them with the change.
|
|
33
|
+
- For slow E2E or independent confirmation, use a verification-only native subagent. It must not modify files and returns commands, exit codes, result counts when available, and code failures or environmental blockers.
|
|
27
34
|
|
|
28
35
|
```text
|
|
29
36
|
Goal: <expected behavior>
|
|
30
|
-
Scope: <paths; prohibited changes>
|
|
31
|
-
Verify: <
|
|
32
|
-
Return: changed paths;
|
|
37
|
+
Scope: <paths; prohibited changes; or verification-only, no file changes>
|
|
38
|
+
Verify: <exact commands>
|
|
39
|
+
Return: changed paths; commands, exit codes, result counts when available; code failures or environmental blockers.
|
|
33
40
|
```
|
|
34
41
|
|
|
35
42
|
## Accept
|
|
36
43
|
|
|
37
|
-
-
|
|
38
|
-
-
|
|
44
|
+
- After the writer finishes, the host must personally review the actual diff, new files, and verification evidence against the requirements, never relying on the writer's summary alone; send any defects to the same writer for fixes and re-review, and announce completion only after the review passes.
|
|
45
|
+
- Stop and report blockers or repeated failures without progress.
|
|
39
46
|
- Report the outcome, verification, and material routing uncertainty concisely. Keep full logs in files when needed.
|
|
40
47
|
|
|
41
48
|
Delegation aims to reduce parent-context output; a second context and retries can increase total token usage.
|
|
@@ -12,4 +12,5 @@ disallowedTools:
|
|
|
12
12
|
Implement directly. Never delegate or invoke another subagent.
|
|
13
13
|
Follow project rules and authorization boundaries, and preserve existing user edits.
|
|
14
14
|
Make only the requested changes and run the requested checks.
|
|
15
|
-
|
|
15
|
+
For verification-only work, do not modify files.
|
|
16
|
+
Return changed paths; commands, exit codes, result counts when available; and code failures or environmental blockers only.
|
|
@@ -7,5 +7,6 @@ developer_instructions = """
|
|
|
7
7
|
Implement directly. Do not delegate further.
|
|
8
8
|
Follow project rules and preserve existing user edits.
|
|
9
9
|
Run the requested checks.
|
|
10
|
-
|
|
10
|
+
For verification-only work, do not modify files.
|
|
11
|
+
Return changed paths; commands, exit codes, result counts when available; and code failures or environmental blockers only.
|
|
11
12
|
"""
|
|
@@ -11,4 +11,5 @@ is_background: false
|
|
|
11
11
|
Implement directly. Never delegate or invoke another subagent.
|
|
12
12
|
Follow project rules and authorization boundaries, and preserve existing user edits.
|
|
13
13
|
Make only the requested changes and run the requested checks.
|
|
14
|
-
|
|
14
|
+
For verification-only work, do not modify files.
|
|
15
|
+
Return changed paths; commands, exit codes, result counts when available; and code failures or environmental blockers only.
|
|
@@ -3,16 +3,102 @@ set -euo pipefail
|
|
|
3
3
|
|
|
4
4
|
fail() { printf 'Error: %s\n' "$*" >&2; exit 1; }
|
|
5
5
|
|
|
6
|
+
cursor_hidden=false
|
|
7
|
+
terminal_state=''
|
|
8
|
+
restore_cursor() {
|
|
9
|
+
if [[ "$cursor_hidden" == true ]]; then
|
|
10
|
+
printf '\033[?25h'
|
|
11
|
+
cursor_hidden=false
|
|
12
|
+
fi
|
|
13
|
+
if [[ -n "$terminal_state" ]]; then
|
|
14
|
+
stty "$terminal_state" 2>/dev/null || stty echo
|
|
15
|
+
terminal_state=''
|
|
16
|
+
fi
|
|
17
|
+
}
|
|
18
|
+
trap restore_cursor EXIT
|
|
19
|
+
trap 'exit 130' INT TERM
|
|
20
|
+
|
|
21
|
+
choose_menu() {
|
|
22
|
+
local prompt=$1
|
|
23
|
+
shift
|
|
24
|
+
local -a labels values
|
|
25
|
+
local entry label value key sequence
|
|
26
|
+
local selected=0 rendered=false line_count
|
|
27
|
+
MENU_RESULT=''
|
|
28
|
+
|
|
29
|
+
for entry in "$@"; do
|
|
30
|
+
label=${entry%%|*}
|
|
31
|
+
value=${entry#*|}
|
|
32
|
+
labels[${#labels[@]}]=$label
|
|
33
|
+
values[${#values[@]}]=$value
|
|
34
|
+
done
|
|
35
|
+
line_count=$(( ${#labels[@]} + 1 ))
|
|
36
|
+
terminal_state=$(stty -g)
|
|
37
|
+
stty -echo
|
|
38
|
+
printf '\033[?25l'
|
|
39
|
+
cursor_hidden=true
|
|
40
|
+
|
|
41
|
+
while :; do
|
|
42
|
+
if [[ "$rendered" == true ]]; then
|
|
43
|
+
printf '\033[%sA' "$line_count"
|
|
44
|
+
fi
|
|
45
|
+
printf '\033[2K\r%s (Up/Down, Enter to select, Esc to cancel)\n' "$prompt"
|
|
46
|
+
for entry in "${!labels[@]}"; do
|
|
47
|
+
printf '\033[2K\r'
|
|
48
|
+
if [[ "$entry" -eq "$selected" ]]; then
|
|
49
|
+
printf '> %s\n' "${labels[$entry]}"
|
|
50
|
+
else
|
|
51
|
+
printf ' %s\n' "${labels[$entry]}"
|
|
52
|
+
fi
|
|
53
|
+
done
|
|
54
|
+
rendered=true
|
|
55
|
+
|
|
56
|
+
if ! IFS= read -r -s -n 1 key; then
|
|
57
|
+
restore_cursor
|
|
58
|
+
return 2
|
|
59
|
+
fi
|
|
60
|
+
case "$key" in
|
|
61
|
+
''|$'\n'|$'\r')
|
|
62
|
+
MENU_RESULT=${values[$selected]}
|
|
63
|
+
restore_cursor
|
|
64
|
+
printf '\n'
|
|
65
|
+
return 0
|
|
66
|
+
;;
|
|
67
|
+
$'\033')
|
|
68
|
+
if IFS= read -r -s -n 2 -t 1 sequence; then
|
|
69
|
+
case "$sequence" in
|
|
70
|
+
'[A') selected=$(( (selected + ${#labels[@]} - 1) % ${#labels[@]} )) ;;
|
|
71
|
+
'[B') selected=$(( (selected + 1) % ${#labels[@]} )) ;;
|
|
72
|
+
*) restore_cursor; printf '\n'; return 1 ;;
|
|
73
|
+
esac
|
|
74
|
+
else
|
|
75
|
+
restore_cursor
|
|
76
|
+
printf '\n'
|
|
77
|
+
return 1
|
|
78
|
+
fi
|
|
79
|
+
;;
|
|
80
|
+
esac
|
|
81
|
+
done
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
cancel_install() {
|
|
85
|
+
printf 'Installation cancelled; no files were changed.\n'
|
|
86
|
+
exit 0
|
|
87
|
+
}
|
|
88
|
+
|
|
6
89
|
usage() {
|
|
7
90
|
cat <<'HELP'
|
|
8
91
|
Usage: setup.sh [--target codex|claude|cursor] [--model ID]
|
|
9
92
|
[--reasoning-effort EFFORT] [--yes]
|
|
93
|
+
setup.sh --update-models --target codex|claude|cursor
|
|
10
94
|
|
|
11
|
-
|
|
95
|
+
Use Up/Down and Enter to choose a platform, model, effort, and confirmation.
|
|
96
|
+
Esc cancels before any files are changed.
|
|
12
97
|
--target PLATFORM Prompted when omitted; required without a terminal.
|
|
13
98
|
--model ID Skip the model menu; required without a terminal.
|
|
14
99
|
--reasoning-effort EFFORT Optional. Omit to use the host's default behavior.
|
|
15
100
|
--yes Approve installation and displayed replacements.
|
|
101
|
+
--update-models Update only model suggestions in an installed Skill.
|
|
16
102
|
-h, --help Show this help.
|
|
17
103
|
|
|
18
104
|
Model suggestions are not an account availability check. Use only models and
|
|
@@ -28,6 +114,7 @@ reasoning_effort=''
|
|
|
28
114
|
model_was_set=false
|
|
29
115
|
effort_was_set=false
|
|
30
116
|
assume_yes=false
|
|
117
|
+
update_models=false
|
|
31
118
|
|
|
32
119
|
while [[ $# -gt 0 ]]; do
|
|
33
120
|
case "$1" in
|
|
@@ -40,16 +127,24 @@ while [[ $# -gt 0 ]]; do
|
|
|
40
127
|
esac
|
|
41
128
|
shift 2 ;;
|
|
42
129
|
--yes) assume_yes=true; shift ;;
|
|
130
|
+
--update-models) update_models=true; shift ;;
|
|
43
131
|
-h|--help) usage; exit 0 ;;
|
|
44
132
|
*) fail "Unknown option: $1" ;;
|
|
45
133
|
esac
|
|
46
134
|
done
|
|
47
135
|
|
|
48
136
|
[[ -n "${HOME:-}" ]] || fail 'HOME is not set.'
|
|
137
|
+
if [[ "$update_models" == true ]]; then
|
|
138
|
+
[[ -n "$target" ]] || fail 'Pass --target with --update-models.'
|
|
139
|
+
[[ "$model_was_set" == false && "$effort_was_set" == false && "$assume_yes" == false ]] || fail '--update-models cannot be combined with --model, --reasoning-effort, or --yes.'
|
|
140
|
+
fi
|
|
49
141
|
if [[ -z "$target" ]]; then
|
|
50
142
|
[[ -t 0 ]] || fail 'Pass --target in non-interactive use.'
|
|
51
|
-
|
|
52
|
-
|
|
143
|
+
if choose_menu 'Choose a platform:' 'Codex|codex' 'Claude Code|claude' 'Cursor|cursor'; then
|
|
144
|
+
target=$MENU_RESULT
|
|
145
|
+
else
|
|
146
|
+
cancel_install
|
|
147
|
+
fi
|
|
53
148
|
fi
|
|
54
149
|
|
|
55
150
|
case "$target" in
|
|
@@ -58,37 +153,75 @@ case "$target" in
|
|
|
58
153
|
skill_target="$codex_home/skills/saving-token"
|
|
59
154
|
agent_dir="$codex_home/agents"
|
|
60
155
|
agent_file='saving-token-writer.toml'
|
|
61
|
-
models=(gpt-
|
|
156
|
+
models=(gpt-6-luna gpt-6-sol gpt-6-astra)
|
|
62
157
|
;;
|
|
63
158
|
claude)
|
|
64
159
|
skill_target="$HOME/.claude/skills/saving-token"
|
|
65
160
|
agent_dir="$HOME/.claude/agents"
|
|
66
161
|
agent_file='saving-token-writer.md'
|
|
67
|
-
models=(haiku sonnet opus)
|
|
162
|
+
models=(claude-haiku-4-5-20251001 claude-sonnet-5 claude-opus-5-5 claude-fable-5-1)
|
|
68
163
|
;;
|
|
69
164
|
cursor)
|
|
70
165
|
skill_target="$HOME/.cursor/skills/saving-token"
|
|
71
166
|
agent_dir="$HOME/.cursor/agents"
|
|
72
167
|
agent_file='saving-token-writer.md'
|
|
73
|
-
models=(composer-2.5 gpt-5.6-sol)
|
|
168
|
+
models=(composer-2.5 gpt-5.6-luna gpt-5.6-terra gpt-5.6-sol claude-sonnet-5 claude-opus-5-5 claude-fable-5-1)
|
|
74
169
|
;;
|
|
75
170
|
*) fail "Unsupported target '$target'. Expected codex, claude, or cursor." ;;
|
|
76
171
|
esac
|
|
77
172
|
|
|
173
|
+
update_installed_model_suggestions() {
|
|
174
|
+
local installed_setup temporary_setup model_line
|
|
175
|
+
|
|
176
|
+
installed_setup="$skill_target/scripts/setup.sh"
|
|
177
|
+
[[ -f "$installed_setup" ]] || fail "No installed Skill script found at $installed_setup. Run install first."
|
|
178
|
+
|
|
179
|
+
model_line=" models=(${models[*]})"
|
|
180
|
+
|
|
181
|
+
temporary_setup="$(mktemp "$(dirname -- "$installed_setup")/.saving-token-setup.XXXXXX")"
|
|
182
|
+
cp -p "$installed_setup" "$temporary_setup"
|
|
183
|
+
if ! awk -v target="$target" -v model_line="$model_line" '
|
|
184
|
+
$0 == " " target ")" { in_target = 1; print; next }
|
|
185
|
+
in_target && $0 == " ;;" { in_target = 0; print; next }
|
|
186
|
+
in_target && $0 ~ /^ models=\([^)]*\)$/ {
|
|
187
|
+
replacements++
|
|
188
|
+
print model_line
|
|
189
|
+
next
|
|
190
|
+
}
|
|
191
|
+
{ print }
|
|
192
|
+
END { exit replacements == 1 ? 0 : 1 }
|
|
193
|
+
' "$installed_setup" > "$temporary_setup"; then
|
|
194
|
+
rm -f "$temporary_setup"
|
|
195
|
+
fail "Could not find one model list for $target in $installed_setup. Run install to refresh the Skill."
|
|
196
|
+
fi
|
|
197
|
+
if ! bash -n "$temporary_setup"; then
|
|
198
|
+
rm -f "$temporary_setup"
|
|
199
|
+
fail 'Updated Skill script failed syntax validation.'
|
|
200
|
+
fi
|
|
201
|
+
if cmp -s "$installed_setup" "$temporary_setup"; then
|
|
202
|
+
rm -f "$temporary_setup"
|
|
203
|
+
printf 'Model suggestions for %s are already current.\n' "$target"
|
|
204
|
+
return
|
|
205
|
+
fi
|
|
206
|
+
|
|
207
|
+
mv -f "$temporary_setup" "$installed_setup"
|
|
208
|
+
printf 'Updated model suggestions for %s in %s. Writer configuration was not changed.\n' "$target" "$installed_setup"
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
if [[ "$update_models" == true ]]; then
|
|
212
|
+
update_installed_model_suggestions
|
|
213
|
+
exit 0
|
|
214
|
+
fi
|
|
215
|
+
|
|
78
216
|
if [[ "$model_was_set" != true ]]; then
|
|
79
217
|
[[ -t 0 ]] || fail 'Pass --model in non-interactive use.'
|
|
80
|
-
|
|
81
|
-
for
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
[1-3])
|
|
88
|
-
[[ "$choice" -le "${#models[@]}" ]] || fail 'Invalid model selection.'
|
|
89
|
-
writer_model=${models[$((choice - 1))]} ;;
|
|
90
|
-
*) fail 'Choose a listed number, c, or q; no model is selected by default.' ;;
|
|
91
|
-
esac
|
|
218
|
+
model_options=()
|
|
219
|
+
for model in "${models[@]}"; do model_options[${#model_options[@]}]="$model|$model"; done
|
|
220
|
+
if choose_menu 'Choose a writer model:' "${model_options[@]}"; then
|
|
221
|
+
writer_model=$MENU_RESULT
|
|
222
|
+
else
|
|
223
|
+
cancel_install
|
|
224
|
+
fi
|
|
92
225
|
fi
|
|
93
226
|
[[ "$writer_model" =~ ^[a-zA-Z0-9][a-zA-Z0-9._:/-]*$ ]] || fail 'Model ID must be nonempty, without whitespace or parameters; use letters, digits, ., _, :, /, or -.'
|
|
94
227
|
|
|
@@ -97,7 +230,24 @@ case "$writer_model" in
|
|
|
97
230
|
esac
|
|
98
231
|
|
|
99
232
|
if [[ "$effort_was_set" != true && "$assume_yes" != true && -t 0 ]]; then
|
|
100
|
-
|
|
233
|
+
effort_options=('Use host default (omit)|')
|
|
234
|
+
case "$target" in
|
|
235
|
+
codex) effort_options+=(
|
|
236
|
+
'none|none' 'minimal|minimal' 'low|low' 'medium|medium' 'high|high'
|
|
237
|
+
'xhigh|xhigh' 'max|max' 'ultra|ultra'
|
|
238
|
+
) ;;
|
|
239
|
+
claude) effort_options+=(
|
|
240
|
+
'low|low' 'medium|medium' 'high|high' 'xhigh|xhigh' 'max|max'
|
|
241
|
+
) ;;
|
|
242
|
+
cursor) effort_options+=(
|
|
243
|
+
'low|low' 'medium|medium' 'high|high' 'xhigh|xhigh' 'max|max' 'ultra|ultra'
|
|
244
|
+
) ;;
|
|
245
|
+
esac
|
|
246
|
+
if choose_menu 'Choose reasoning effort (model support may vary):' "${effort_options[@]}"; then
|
|
247
|
+
reasoning_effort=$MENU_RESULT
|
|
248
|
+
else
|
|
249
|
+
cancel_install
|
|
250
|
+
fi
|
|
101
251
|
fi
|
|
102
252
|
case "$reasoning_effort" in
|
|
103
253
|
''|none|minimal|low|medium|high|xhigh|max|ultra) ;;
|
|
@@ -135,11 +285,12 @@ fi
|
|
|
135
285
|
[[ ! -e "$agent_target" ]] || printf 'Existing writer configuration will be replaced.\n'
|
|
136
286
|
|
|
137
287
|
if [[ "$assume_yes" != true ]]; then
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
288
|
+
[[ -t 0 ]] || fail 'Pass --yes in non-interactive use.'
|
|
289
|
+
if choose_menu 'Install this configuration?' 'Cancel|no' 'Install|yes'; then
|
|
290
|
+
[[ "$MENU_RESULT" == yes ]] || cancel_install
|
|
291
|
+
else
|
|
292
|
+
cancel_install
|
|
293
|
+
fi
|
|
143
294
|
else
|
|
144
295
|
printf 'Install this configuration? yes (--yes)\n'
|
|
145
296
|
fi
|