saving-token 0.1.0 → 1.0.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 CHANGED
@@ -1,46 +1,69 @@
1
1
  # saving-token
2
2
 
3
- A native writer makes file changes; the parent agent decides and reviews. You choose the writer model during setup. The parent model and global defaults stay unchanged.
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). Delegation aims to reduce parent-context output; extra context and retries can increase total tokens.
7
+ Inspired by [karpathy-guidelines](https://github.com/multica-ai/andrej-karpathy-skills).
6
8
 
7
9
  ## Install
8
10
 
9
- ### Codex via npm (after publication)
11
+ ### Interactive setup
10
12
 
11
- After the package is published to npm, run:
13
+ ```bash
14
+ bash skills/saving-token/scripts/setup.sh
15
+ ```
16
+
17
+ Use **Up/Down** and **Enter** to choose the platform, writer model, optional
18
+ reasoning effort, and final action. Press **Esc** to cancel. The final menu
19
+ starts on **Cancel**. Model entries are suggestions only; availability is not
20
+ checked. The effort menu includes the host default and values accepted by the
21
+ target; account and model support still depend on the host.
22
+
23
+ The model menu has no free-text entry. Use `--model` for a custom model ID or
24
+ for non-interactive setup:
12
25
 
13
26
  ```bash
14
- npx saving-token@latest install --agent codex
27
+ bash skills/saving-token/scripts/setup.sh \
28
+ --target codex --model '<model-id>' --yes
15
29
  ```
16
30
 
17
- This interactively prompts you to choose a writer model and optional reasoning effort, then asks you to confirm installation.
31
+ `--target` and `--model` are required without a terminal. Add
32
+ `--reasoning-effort <effort>` when supported by the selected model. `--yes`
33
+ approves the displayed installation and replacements; it never chooses a
34
+ model. Rerun setup to change the writer. Extra files in an existing Skill
35
+ directory are preserved.
36
+
37
+ ### npm wrapper
18
38
 
19
- ### Manual / multi-platform
39
+ After publication, run:
20
40
 
21
41
  ```bash
22
- bash skills/saving-token/scripts/setup.sh
42
+ npx saving-token@latest install --agent codex
23
43
  ```
24
44
 
25
- Choose **platform → model → optional reasoning effort → confirm**. The model menu offers a few suggestions and a custom ID option, with no default selection. Suggestions do not verify account availability. Leave effort blank to use the host's default behavior.
45
+ The wrapper supports `install --agent codex` and keeps the interactive menus.
46
+ Use the Bash script directly for `--target`, `--model`, `--reasoning-effort`,
47
+ or `--yes`.
26
48
 
27
- | Platform | Skill location | Writer configuration |
49
+ ### Installed paths
50
+
51
+ | Platform | Skill | Writer configuration |
28
52
  |---|---|---|
29
53
  | Codex | `${CODEX_HOME:-~/.codex}/skills/saving-token/` | `${CODEX_HOME:-~/.codex}/agents/saving-token-writer.toml` |
30
54
  | Claude Code | `~/.claude/skills/saving-token/` | `~/.claude/agents/saving-token-writer.md` |
31
55
  | Cursor | `~/.cursor/skills/saving-token/` | `~/.cursor/agents/saving-token-writer.md` |
32
56
 
33
- Restart the host, then invoke `$saving-token` in Codex or `/saving-token` in standalone Claude Code and Cursor. Automatic Skill discovery remains available. Verify the writer model in runtime task metadata when exposed; generated configuration alone does not prove routing. Claude Code and Cursor may substitute a model under account or administrator policy.
34
-
35
- To automate an already approved installation:
36
-
37
- ```bash
38
- bash skills/saving-token/scripts/setup.sh --target codex --model '<model-id>' --yes
39
- ```
57
+ Restart the host, then invoke `$saving-token` in Codex or `/saving-token` in
58
+ standalone Claude Code and Cursor. A generated configuration does not prove
59
+ runtime routing; verify the model in exposed task metadata when available.
60
+ Claude Code and Cursor may substitute a model under account or administrator
61
+ policy.
40
62
 
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`.
63
+ The writer implements and verifies delegated changes. The host personally
64
+ reviews the actual changes and verification evidence against the requirements,
65
+ sends defects back to the same writer for fixes and re-review, and announces
66
+ completion only after review passes.
44
67
 
45
68
  ## Claude Code plugin
46
69
 
@@ -49,15 +72,12 @@ Rerun setup to change the writer model. Existing distributed Skill files and the
49
72
  /plugin install saving-token@saving-token
50
73
  ```
51
74
 
52
- Claude's plugin configuration collects the required `writer_model` as text; it does not use the script's menu. The plugin leaves reasoning effort to the host. Invoke `/saving-token:saving-token`; its writer is `saving-token:saving-token-writer`. Change the model through plugin configuration, then reload the session. Use either the plugin or standalone installation.
53
-
54
- ## Structure
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.
75
+ The plugin collects `writer_model` through its configuration and leaves effort
76
+ to the host. Invoke `/saving-token:saving-token`; its writer is
77
+ `saving-token:saving-token-writer`. Use either the plugin or standalone setup.
62
78
 
63
- Official references: [Codex subagents](https://developers.openai.com/codex/subagents), [Claude subagents](https://code.claude.com/docs/en/sub-agents), [Claude plugins](https://code.claude.com/docs/en/plugins-reference), [Cursor subagents](https://cursor.com/docs/subagents), [Agent Skills](https://agentskills.io/specification).
79
+ Official references: [Codex subagents](https://developers.openai.com/codex/subagents),
80
+ [Claude subagents](https://code.claude.com/docs/en/sub-agents),
81
+ [Claude plugins](https://code.claude.com/docs/en/plugins-reference),
82
+ [Cursor subagents](https://cursor.com/docs/subagents), and
83
+ [Agent Skills](https://agentskills.io/specification).
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "saving-token",
3
- "version": "0.1.0",
3
+ "version": "1.0.0",
4
4
  "bin": {
5
5
  "saving-token": "bin/saving-token.cjs"
6
6
  },
@@ -34,8 +34,8 @@ Return: changed paths; check results; blockers.
34
34
 
35
35
  ## Accept
36
36
 
37
- - Inspect the actual diff, new files, and check evidence; never accept from the writer summary alone.
38
- - Send remaining defects and acceptance conditions to the same writer, then review again. Stop and report blockers or repeated failures without progress.
37
+ - 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.
38
+ - Stop and report blockers or repeated failures without progress.
39
39
  - Report the outcome, verification, and material routing uncertainty concisely. Keep full logs in files when needed.
40
40
 
41
41
  Delegation aims to reduce parent-context output; a second context and retries can increase total token usage.
@@ -3,12 +3,96 @@ 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]
10
93
 
11
- Choose a platform and writer model, preview, then confirm installation.
94
+ Use Up/Down and Enter to choose a platform, model, effort, and confirmation.
95
+ Esc cancels before any files are changed.
12
96
  --target PLATFORM Prompted when omitted; required without a terminal.
13
97
  --model ID Skip the model menu; required without a terminal.
14
98
  --reasoning-effort EFFORT Optional. Omit to use the host's default behavior.
@@ -48,8 +132,11 @@ done
48
132
  [[ -n "${HOME:-}" ]] || fail 'HOME is not set.'
49
133
  if [[ -z "$target" ]]; then
50
134
  [[ -t 0 ]] || fail 'Pass --target in non-interactive use.'
51
- IFS= read -r -p 'Platform: 1) codex 2) claude 3) cursor: ' target || fail 'No platform selected.'
52
- case "$target" in 1) target=codex ;; 2) target=claude ;; 3) target=cursor ;; esac
135
+ if choose_menu 'Choose a platform:' 'Codex|codex' 'Claude Code|claude' 'Cursor|cursor'; then
136
+ target=$MENU_RESULT
137
+ else
138
+ cancel_install
139
+ fi
53
140
  fi
54
141
 
55
142
  case "$target" in
@@ -77,18 +164,13 @@ esac
77
164
 
78
165
  if [[ "$model_was_set" != true ]]; then
79
166
  [[ -t 0 ]] || fail 'Pass --model in non-interactive use.'
80
- printf '\nWriter model suggestions (availability depends on your account):\n'
81
- for i in "${!models[@]}"; do printf ' %s) %s\n' "$((i + 1))" "${models[$i]}"; done
82
- printf ' c) Custom model ID\n q) Cancel\n'
83
- IFS= read -r -p 'Choose a model: ' choice || fail 'No model selected.'
84
- case "$choice" in
85
- q|Q) printf 'Installation cancelled; no files were changed.\n'; exit 0 ;;
86
- c|C) IFS= read -r -p 'Writer model ID: ' writer_model || fail 'No model selected.' ;;
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
167
+ model_options=()
168
+ for model in "${models[@]}"; do model_options[${#model_options[@]}]="$model|$model"; done
169
+ if choose_menu 'Choose a writer model:' "${model_options[@]}"; then
170
+ writer_model=$MENU_RESULT
171
+ else
172
+ cancel_install
173
+ fi
92
174
  fi
93
175
  [[ "$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
176
 
@@ -97,7 +179,24 @@ case "$writer_model" in
97
179
  esac
98
180
 
99
181
  if [[ "$effort_was_set" != true && "$assume_yes" != true && -t 0 ]]; then
100
- IFS= read -r -p 'Reasoning effort (Enter to omit): ' reasoning_effort || fail 'Input cancelled.'
182
+ effort_options=('Use host default (omit)|')
183
+ case "$target" in
184
+ codex) effort_options+=(
185
+ 'none|none' 'minimal|minimal' 'low|low' 'medium|medium' 'high|high'
186
+ 'xhigh|xhigh' 'max|max' 'ultra|ultra'
187
+ ) ;;
188
+ claude) effort_options+=(
189
+ 'low|low' 'medium|medium' 'high|high' 'xhigh|xhigh' 'max|max'
190
+ ) ;;
191
+ cursor) effort_options+=(
192
+ 'low|low' 'medium|medium' 'high|high' 'xhigh|xhigh' 'max|max' 'ultra|ultra'
193
+ ) ;;
194
+ esac
195
+ if choose_menu 'Choose reasoning effort (model support may vary):' "${effort_options[@]}"; then
196
+ reasoning_effort=$MENU_RESULT
197
+ else
198
+ cancel_install
199
+ fi
101
200
  fi
102
201
  case "$reasoning_effort" in
103
202
  ''|none|minimal|low|medium|high|xhigh|max|ultra) ;;
@@ -135,11 +234,12 @@ fi
135
234
  [[ ! -e "$agent_target" ]] || printf 'Existing writer configuration will be replaced.\n'
136
235
 
137
236
  if [[ "$assume_yes" != true ]]; then
138
- IFS= read -r -p 'Install this configuration? [y/N] ' answer || fail 'Confirmation required; use --yes after approval.'
139
- case "$answer" in
140
- y|Y|yes|YES|Yes) ;;
141
- *) printf 'Installation cancelled; no files were changed.\n'; exit 0 ;;
142
- esac
237
+ [[ -t 0 ]] || fail 'Pass --yes in non-interactive use.'
238
+ if choose_menu 'Install this configuration?' 'Cancel|no' 'Install|yes'; then
239
+ [[ "$MENU_RESULT" == yes ]] || cancel_install
240
+ else
241
+ cancel_install
242
+ fi
143
243
  else
144
244
  printf 'Install this configuration? yes (--yes)\n'
145
245
  fi