claude-code-modes 0.4.0 → 0.4.1
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 +6 -21
- package/package.json +1 -1
- package/prompts/base/actions.md +1 -1
- package/src/args.ts +16 -1
- package/src/build-info.ts +1 -1
- package/src/build-prompt.ts +4 -1
- package/src/cli.ts +4 -1
- package/src/embedded-prompts.ts +1 -1
- package/src/env.ts +80 -12
- package/src/types.ts +8 -0
- package/src/usage.ts +2 -0
package/README.md
CHANGED
|
@@ -147,11 +147,10 @@ prompts/
|
|
|
147
147
|
chill/ Alternative base (emotion-research-informed, leaner)
|
|
148
148
|
flow/ Alternative base (chill's calm + restored engagement)
|
|
149
149
|
axis/ Behavioral prompts organized by three axes
|
|
150
|
-
style/ Writing styles (declaudified)
|
|
151
150
|
modifiers/ Behavioral layers (bold, debug, methodical, director, readonly, context-pacing, speak-plain, tdd, muse, flow, playful)
|
|
152
151
|
```
|
|
153
152
|
|
|
154
|
-
Each base has a `base.json` manifest — a flat JSON array declaring fragment order with `"axes"` and `"modifiers"` as reserved insertion points. The standard base is validated against Claude Code **v2.1.
|
|
153
|
+
Each base has a `base.json` manifest — a flat JSON array declaring fragment order with `"axes"` and `"modifiers"` as reserved insertion points. The standard base is validated against Claude Code **v2.1.217**.
|
|
155
154
|
|
|
156
155
|
The behavioral layer is composed from three independent axes — **agency** (how much initiative), **quality** (what code standard), and **scope** (how far beyond the request). Presets are just named combinations of these three values.
|
|
157
156
|
|
|
@@ -186,15 +185,6 @@ claude-mode create --quality ./team-quality.md # Use a custom quality fragme
|
|
|
186
185
|
claude-mode create --quality team-standard # Resolve from config
|
|
187
186
|
```
|
|
188
187
|
|
|
189
|
-
Set a writing style — a single fragment that shapes how Claude writes to you (answers, summaries, commit messages), independent of the behavioral axes:
|
|
190
|
-
|
|
191
|
-
```bash
|
|
192
|
-
claude-mode create --style declaudified # Built-in: lead with the answer, cut filler and stock phrases
|
|
193
|
-
claude-mode create --style ./house-style.md # Or a custom fragment / config-defined name
|
|
194
|
-
```
|
|
195
|
-
|
|
196
|
-
No style is applied unless you pass `--style`, set `defaultStyle` in config, or use a preset that declares one.
|
|
197
|
-
|
|
198
188
|
Add modifiers:
|
|
199
189
|
|
|
200
190
|
```bash
|
|
@@ -208,9 +198,12 @@ claude-mode create --append-system-prompt "Use Rust, not TypeScript"
|
|
|
208
198
|
Pass flags through to Claude Code:
|
|
209
199
|
|
|
210
200
|
```bash
|
|
211
|
-
claude-mode create --
|
|
201
|
+
claude-mode create --model sonnet # model choice also lands in the prompt's environment info
|
|
202
|
+
claude-mode create -- --verbose # anything after -- goes to claude verbatim
|
|
212
203
|
```
|
|
213
204
|
|
|
205
|
+
The environment section of the assembled prompt reports the model claude will actually run: from `--model` (before or after `--`), else the `ANTHROPIC_MODEL` env var, else Claude settings files (`.claude/settings.local.json`, `.claude/settings.json`, `~/.claude/settings.json`), else the newest known model.
|
|
206
|
+
|
|
214
207
|
Debug the assembled prompt:
|
|
215
208
|
|
|
216
209
|
```bash
|
|
@@ -259,9 +252,6 @@ Example `.claude-mode.json`:
|
|
|
259
252
|
"modifiers": {
|
|
260
253
|
"team-rules": "./prompts/team-rules.md"
|
|
261
254
|
},
|
|
262
|
-
"styles": {
|
|
263
|
-
"house": "./prompts/house-style.md"
|
|
264
|
-
},
|
|
265
255
|
"axes": {
|
|
266
256
|
"quality": {
|
|
267
257
|
"team-standard": "./prompts/team-quality.md"
|
|
@@ -272,7 +262,6 @@ Example `.claude-mode.json`:
|
|
|
272
262
|
"agency": "collaborative",
|
|
273
263
|
"quality": "team-standard",
|
|
274
264
|
"scope": "adjacent",
|
|
275
|
-
"style": "house",
|
|
276
265
|
"modifiers": ["team-rules"]
|
|
277
266
|
}
|
|
278
267
|
}
|
|
@@ -281,15 +270,13 @@ Example `.claude-mode.json`:
|
|
|
281
270
|
|
|
282
271
|
- **`defaultModifiers`** — always applied to every invocation (no flag needed)
|
|
283
272
|
- **`modifiers`** — named modifiers referencing markdown files
|
|
284
|
-
- **`styles`** — named writing styles referencing markdown files
|
|
285
273
|
- **`axes`** — custom axis values (replace built-in fragments)
|
|
286
274
|
- **`presets`** — named presets composing built-in and custom values
|
|
287
275
|
|
|
288
|
-
Config also supports bases
|
|
276
|
+
Config also supports bases:
|
|
289
277
|
|
|
290
278
|
- **`defaultBase`** — base to use when `--base` isn't specified
|
|
291
279
|
- **`bases`** — named bases referencing directories with `base.json` manifests
|
|
292
|
-
- **`defaultStyle`** — style to apply when `--style` isn't specified
|
|
293
280
|
|
|
294
281
|
Config searches `.claude-mode.json` in the current directory first, then `~/.config/claude-mode/config.json` as a global fallback. All commands accept `--global` to target the global config.
|
|
295
282
|
|
|
@@ -302,8 +289,6 @@ claude-mode config add-default <name-or-path> # Add to defaultModifiers
|
|
|
302
289
|
claude-mode config remove-default <name> # Remove from defaultModifiers
|
|
303
290
|
claude-mode config add-modifier <name> <path> # Register named modifier
|
|
304
291
|
claude-mode config remove-modifier <name> # Unregister named modifier
|
|
305
|
-
claude-mode config add-style <name> <path> # Register named style
|
|
306
|
-
claude-mode config remove-style <name> # Unregister named style
|
|
307
292
|
claude-mode config add-axis <axis> <name> <path> # Register custom axis value
|
|
308
293
|
claude-mode config remove-axis <axis> <name> # Unregister custom axis value
|
|
309
294
|
claude-mode config add-preset <name> [flags] # Create custom preset
|
package/package.json
CHANGED
package/prompts/base/actions.md
CHANGED
|
@@ -8,4 +8,4 @@ Examples of the kind of risky actions that warrant user confirmation:
|
|
|
8
8
|
- Actions visible to others or that affect shared state: pushing code, creating/closing/commenting on PRs or issues, sending messages (Slack, email, GitHub), posting to external services, modifying shared infrastructure or permissions
|
|
9
9
|
- Uploading content to third-party web tools (diagram renderers, pastebins, gists) publishes it - consider whether it could be sensitive before sending, since it may be cached or indexed even if later deleted.
|
|
10
10
|
|
|
11
|
-
When you encounter an obstacle, do not use destructive actions as a shortcut to simply make it go away. For instance, try to identify root causes and fix underlying issues rather than bypassing safety checks (e.g. --no-verify). If you discover unexpected state like unfamiliar files, branches, or configuration, investigate before deleting or overwriting, as it may represent the user's in-progress work. If you're unsure whether the user would want something kept, prefer a reversible step (move it aside, rename it, or stash it) over deleting; files you created yourself this session (scratch outputs, experiment intermediates) are yours to clean up freely. For example, typically resolve merge conflicts rather than discarding changes; similarly, if a lock file exists, investigate what process holds it rather than deleting it. In a git repository, run `git status` before any command that could discard uncommitted work (git checkout/restore/reset/clean, rm -rf on a repo path, restoring from a snapshot), and stash (with `-u` for untracked) or commit anything you find first. In short: only take risky actions carefully, and when in doubt, ask before acting. Follow both the spirit and letter of these instructions - measure twice, cut once.
|
|
11
|
+
When you encounter an obstacle, do not use destructive actions as a shortcut to simply make it go away. For instance, try to identify root causes and fix underlying issues rather than bypassing safety checks (e.g. --no-verify). If you discover unexpected state like unfamiliar files, branches, or configuration, investigate before deleting or overwriting, as it may represent the user's in-progress work. If you're unsure whether the user would want something kept, prefer a reversible step (move it aside, rename it, or stash it) over deleting; files you created yourself this session (scratch outputs, experiment intermediates) are yours to clean up freely. For example, typically resolve merge conflicts rather than discarding changes; similarly, if a lock file exists, investigate what process holds it rather than deleting it. In a git repository, run `git status` before any command that could discard uncommitted work (git checkout/restore/reset/clean, rm -rf on a repo path, restoring from a snapshot), and stash (with `-u` for untracked) or commit anything you find first. And when staging or committing: review what's included (`git status` after a broad `git add`), and if you see anything suspicious that might reveal secrets — even if the filename looks innocuous — double-check the file's contents before pushing. In short: only take risky actions carefully, and when in doubt, ask before acting. Follow both the spirit and letter of these instructions - measure twice, cut once.
|
package/src/args.ts
CHANGED
|
@@ -18,10 +18,22 @@ export interface ParsedArgs {
|
|
|
18
18
|
forwarded: {
|
|
19
19
|
appendSystemPrompt?: string;
|
|
20
20
|
appendSystemPromptFile?: string;
|
|
21
|
+
model?: string;
|
|
21
22
|
};
|
|
23
|
+
/** Model claude will run — from --model, or peeked from after `--`; drives env detection */
|
|
24
|
+
modelHint: string | null;
|
|
22
25
|
passthroughArgs: string[];
|
|
23
26
|
}
|
|
24
27
|
|
|
28
|
+
// After `--` everything is passed verbatim, but the model choice still shapes
|
|
29
|
+
// the environment section — peek without disturbing the passthrough list
|
|
30
|
+
function peekModelAfterDashDash(args: string[]): string | null {
|
|
31
|
+
const flagIdx = args.indexOf("--model");
|
|
32
|
+
if (flagIdx >= 0 && flagIdx + 1 < args.length) return args[flagIdx + 1];
|
|
33
|
+
const inline = args.find((arg) => arg.startsWith("--model="));
|
|
34
|
+
return inline ? inline.slice("--model=".length) : null;
|
|
35
|
+
}
|
|
36
|
+
|
|
25
37
|
export function parseCliArgs(argv: string[]): ParsedArgs {
|
|
26
38
|
// Split at -- separator
|
|
27
39
|
const dashDashIdx = argv.indexOf("--");
|
|
@@ -42,6 +54,7 @@ export function parseCliArgs(argv: string[]): ParsedArgs {
|
|
|
42
54
|
"context-pacing": { type: "boolean" },
|
|
43
55
|
"append-system-prompt": { type: "string" },
|
|
44
56
|
"append-system-prompt-file": { type: "string" },
|
|
57
|
+
model: { type: "string" },
|
|
45
58
|
"system-prompt": { type: "string" },
|
|
46
59
|
"system-prompt-file": { type: "string" },
|
|
47
60
|
help: { type: "boolean" },
|
|
@@ -81,7 +94,7 @@ export function parseCliArgs(argv: string[]): ParsedArgs {
|
|
|
81
94
|
// Collect unknown flags for passthrough
|
|
82
95
|
const knownFlags = new Set([
|
|
83
96
|
"base", "agency", "quality", "scope", "style", "modifier", "readonly", "print", "context-pacing",
|
|
84
|
-
"append-system-prompt", "append-system-prompt-file",
|
|
97
|
+
"append-system-prompt", "append-system-prompt-file", "model",
|
|
85
98
|
"system-prompt", "system-prompt-file", "help", "version",
|
|
86
99
|
]);
|
|
87
100
|
const unknownPassthrough: string[] = [];
|
|
@@ -115,7 +128,9 @@ export function parseCliArgs(argv: string[]): ParsedArgs {
|
|
|
115
128
|
forwarded: {
|
|
116
129
|
appendSystemPrompt: values["append-system-prompt"] as string | undefined,
|
|
117
130
|
appendSystemPromptFile: values["append-system-prompt-file"] as string | undefined,
|
|
131
|
+
model: values.model as string | undefined,
|
|
118
132
|
},
|
|
133
|
+
modelHint: (values.model as string | undefined) ?? peekModelAfterDashDash(afterDashDash),
|
|
119
134
|
passthroughArgs,
|
|
120
135
|
};
|
|
121
136
|
}
|
package/src/build-info.ts
CHANGED
package/src/build-prompt.ts
CHANGED
|
@@ -98,7 +98,7 @@ function main(): void {
|
|
|
98
98
|
}
|
|
99
99
|
|
|
100
100
|
// Detect environment and build template vars
|
|
101
|
-
const env = detectEnv();
|
|
101
|
+
const env = detectEnv(parsed.modelHint);
|
|
102
102
|
const templateVars = buildTemplateVars(env);
|
|
103
103
|
|
|
104
104
|
// Assemble the prompt
|
|
@@ -127,6 +127,9 @@ function main(): void {
|
|
|
127
127
|
if (parsed.forwarded.appendSystemPromptFile) {
|
|
128
128
|
claudeArgs.push("--append-system-prompt-file", parsed.forwarded.appendSystemPromptFile);
|
|
129
129
|
}
|
|
130
|
+
if (parsed.forwarded.model) {
|
|
131
|
+
claudeArgs.push("--model", parsed.forwarded.model);
|
|
132
|
+
}
|
|
130
133
|
|
|
131
134
|
// Add passthrough args
|
|
132
135
|
claudeArgs.push(...parsed.passthroughArgs);
|
package/src/cli.ts
CHANGED
|
@@ -119,7 +119,7 @@ async function main(): Promise<void> {
|
|
|
119
119
|
}
|
|
120
120
|
|
|
121
121
|
// Detect environment and build template vars
|
|
122
|
-
const env = detectEnv();
|
|
122
|
+
const env = detectEnv(parsed.modelHint);
|
|
123
123
|
const templateVars = buildTemplateVars(env);
|
|
124
124
|
|
|
125
125
|
// Assemble the prompt
|
|
@@ -150,6 +150,9 @@ async function main(): Promise<void> {
|
|
|
150
150
|
if (parsed.forwarded.appendSystemPromptFile) {
|
|
151
151
|
claudeArgs.push("--append-system-prompt-file", parsed.forwarded.appendSystemPromptFile);
|
|
152
152
|
}
|
|
153
|
+
if (parsed.forwarded.model) {
|
|
154
|
+
claudeArgs.push("--model", parsed.forwarded.model);
|
|
155
|
+
}
|
|
153
156
|
|
|
154
157
|
// Add passthrough args
|
|
155
158
|
claudeArgs.push(...parsed.passthroughArgs);
|
package/src/embedded-prompts.ts
CHANGED
|
@@ -45,7 +45,7 @@ Examples of the kind of risky actions that warrant user confirmation:
|
|
|
45
45
|
- Actions visible to others or that affect shared state: pushing code, creating/closing/commenting on PRs or issues, sending messages (Slack, email, GitHub), posting to external services, modifying shared infrastructure or permissions
|
|
46
46
|
- Uploading content to third-party web tools (diagram renderers, pastebins, gists) publishes it - consider whether it could be sensitive before sending, since it may be cached or indexed even if later deleted.
|
|
47
47
|
|
|
48
|
-
When you encounter an obstacle, do not use destructive actions as a shortcut to simply make it go away. For instance, try to identify root causes and fix underlying issues rather than bypassing safety checks (e.g. --no-verify). If you discover unexpected state like unfamiliar files, branches, or configuration, investigate before deleting or overwriting, as it may represent the user's in-progress work. If you're unsure whether the user would want something kept, prefer a reversible step (move it aside, rename it, or stash it) over deleting; files you created yourself this session (scratch outputs, experiment intermediates) are yours to clean up freely. For example, typically resolve merge conflicts rather than discarding changes; similarly, if a lock file exists, investigate what process holds it rather than deleting it. In a git repository, run \`git status\` before any command that could discard uncommitted work (git checkout/restore/reset/clean, rm -rf on a repo path, restoring from a snapshot), and stash (with \`-u\` for untracked) or commit anything you find first. In short: only take risky actions carefully, and when in doubt, ask before acting. Follow both the spirit and letter of these instructions - measure twice, cut once.
|
|
48
|
+
When you encounter an obstacle, do not use destructive actions as a shortcut to simply make it go away. For instance, try to identify root causes and fix underlying issues rather than bypassing safety checks (e.g. --no-verify). If you discover unexpected state like unfamiliar files, branches, or configuration, investigate before deleting or overwriting, as it may represent the user's in-progress work. If you're unsure whether the user would want something kept, prefer a reversible step (move it aside, rename it, or stash it) over deleting; files you created yourself this session (scratch outputs, experiment intermediates) are yours to clean up freely. For example, typically resolve merge conflicts rather than discarding changes; similarly, if a lock file exists, investigate what process holds it rather than deleting it. In a git repository, run \`git status\` before any command that could discard uncommitted work (git checkout/restore/reset/clean, rm -rf on a repo path, restoring from a snapshot), and stash (with \`-u\` for untracked) or commit anything you find first. And when staging or committing: review what's included (\`git status\` after a broad \`git add\`), and if you see anything suspicious that might reveal secrets — even if the filename looks innocuous — double-check the file's contents before pushing. In short: only take risky actions carefully, and when in doubt, ask before acting. Follow both the spirit and letter of these instructions - measure twice, cut once.
|
|
49
49
|
`,
|
|
50
50
|
"base/tools.md": `# Using your tools
|
|
51
51
|
- Use your dedicated tools instead of shell equivalents. Read works better than cat or grep. Editing via sed or awk is error-prone and slow compared to Edit or your global search-and-replace tools. Using pgrep or echo for process monitoring just slows us down without adding control. Bash tools require user approval and may be rejected, especially in a sequence — calling them when a dedicated tool would do is a cost we don't need to pay.
|
package/src/env.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { execSync } from "node:child_process";
|
|
2
|
-
import {
|
|
3
|
-
import
|
|
2
|
+
import { readFileSync } from "node:fs";
|
|
3
|
+
import { homedir } from "node:os";
|
|
4
|
+
import { basename, join } from "node:path";
|
|
5
|
+
import type { EnvInfo, ModelInfo, TemplateVars } from "./types.js";
|
|
4
6
|
|
|
5
7
|
function exec(command: string): string | null {
|
|
6
8
|
try {
|
|
@@ -18,7 +20,77 @@ function exec(command: string): string | null {
|
|
|
18
20
|
}
|
|
19
21
|
}
|
|
20
22
|
|
|
21
|
-
|
|
23
|
+
// Model metadata table extracted from the Claude Code binary — update when Claude Code updates.
|
|
24
|
+
// Extraction: grep the native binary for `{id:"claude-...,display_name:...,knowledge_cutoff:...`
|
|
25
|
+
const MODEL_TABLE: readonly ModelInfo[] = [
|
|
26
|
+
{ id: "claude-fable-5", name: "Fable 5", cutoff: "January 2026" },
|
|
27
|
+
{ id: "claude-mythos-5", name: "Mythos 5", cutoff: "January 2026" },
|
|
28
|
+
{ id: "claude-opus-4-8", name: "Opus 4.8", cutoff: "January 2026" },
|
|
29
|
+
{ id: "claude-opus-4-7", name: "Opus 4.7", cutoff: "January 2026" },
|
|
30
|
+
{ id: "claude-opus-4-6", name: "Opus 4.6", cutoff: "May 2025" },
|
|
31
|
+
{ id: "claude-opus-4-5", name: "Opus 4.5", cutoff: "May 2025" },
|
|
32
|
+
{ id: "claude-opus-4-1", name: "Opus 4.1", cutoff: "January 2025" },
|
|
33
|
+
{ id: "claude-opus-4-0", name: "Opus 4", cutoff: "January 2025" },
|
|
34
|
+
{ id: "claude-sonnet-5", name: "Sonnet 5", cutoff: "January 2026" },
|
|
35
|
+
{ id: "claude-sonnet-4-6", name: "Sonnet 4.6", cutoff: "August 2025" },
|
|
36
|
+
{ id: "claude-sonnet-4-5", name: "Sonnet 4.5", cutoff: "January 2025" },
|
|
37
|
+
{ id: "claude-sonnet-4-0", name: "Sonnet 4", cutoff: "January 2025" },
|
|
38
|
+
{ id: "claude-haiku-4-5", name: "Haiku 4.5", cutoff: "February 2025" },
|
|
39
|
+
] as const;
|
|
40
|
+
|
|
41
|
+
// Aliases resolve to the newest model of the family; opusplan executes on opus
|
|
42
|
+
const MODEL_ALIASES: Record<string, string> = {
|
|
43
|
+
opus: "claude-opus-4-8",
|
|
44
|
+
opusplan: "claude-opus-4-8",
|
|
45
|
+
sonnet: "claude-sonnet-5",
|
|
46
|
+
haiku: "claude-haiku-4-5",
|
|
47
|
+
fable: "claude-fable-5",
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
const DEFAULT_MODEL: ModelInfo = MODEL_TABLE[0];
|
|
51
|
+
|
|
52
|
+
export function resolveModel(raw: string | null | undefined): ModelInfo {
|
|
53
|
+
if (!raw || raw === "default") return DEFAULT_MODEL;
|
|
54
|
+
|
|
55
|
+
const has1m = raw.endsWith("[1m]");
|
|
56
|
+
const base = has1m ? raw.slice(0, -"[1m]".length) : raw;
|
|
57
|
+
const id = MODEL_ALIASES[base] ?? base;
|
|
58
|
+
|
|
59
|
+
// Exact id first, then dated variants like claude-haiku-4-5-20251001
|
|
60
|
+
const entry =
|
|
61
|
+
MODEL_TABLE.find((m) => m.id === id) ?? MODEL_TABLE.find((m) => id.startsWith(`${m.id}-`));
|
|
62
|
+
if (!entry) {
|
|
63
|
+
// Unknown model — likely newer than the table; surface the id as the name
|
|
64
|
+
// and keep the newest known cutoff rather than inventing one
|
|
65
|
+
return { name: id, id: has1m ? `${id}[1m]` : id, cutoff: DEFAULT_MODEL.cutoff };
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
return {
|
|
69
|
+
name: has1m ? `${entry.name} (1M context)` : entry.name,
|
|
70
|
+
id: has1m ? `${id}[1m]` : id,
|
|
71
|
+
cutoff: entry.cutoff,
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// Claude Code reads its model setting from these files, most specific first
|
|
76
|
+
function readConfiguredModel(cwd: string): string | null {
|
|
77
|
+
const candidates = [
|
|
78
|
+
join(cwd, ".claude", "settings.local.json"),
|
|
79
|
+
join(cwd, ".claude", "settings.json"),
|
|
80
|
+
join(homedir(), ".claude", "settings.json"),
|
|
81
|
+
];
|
|
82
|
+
for (const path of candidates) {
|
|
83
|
+
try {
|
|
84
|
+
const settings = JSON.parse(readFileSync(path, "utf8"));
|
|
85
|
+
if (typeof settings.model === "string" && settings.model !== "") return settings.model;
|
|
86
|
+
} catch {
|
|
87
|
+
// Missing or malformed settings file — try the next candidate
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
return null;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
export function detectEnv(modelArg?: string | null): EnvInfo {
|
|
22
94
|
const cwd = process.cwd();
|
|
23
95
|
const isGit = exec("git rev-parse --is-inside-work-tree") === "true";
|
|
24
96
|
|
|
@@ -39,15 +111,11 @@ export function detectEnv(): EnvInfo {
|
|
|
39
111
|
const platform = exec("uname -s")?.toLowerCase() ?? "unknown";
|
|
40
112
|
const shell = basename(process.env.SHELL || "bash");
|
|
41
113
|
const osVersion = exec("uname -sr") ?? "unknown";
|
|
114
|
+
const model = resolveModel(modelArg ?? process.env.ANTHROPIC_MODEL ?? readConfiguredModel(cwd));
|
|
42
115
|
|
|
43
|
-
return { cwd, isGit, isWorktree, gitBranch, gitStatus, gitLog, platform, shell, osVersion };
|
|
116
|
+
return { cwd, isGit, isWorktree, gitBranch, gitStatus, gitLog, platform, shell, osVersion, model };
|
|
44
117
|
}
|
|
45
118
|
|
|
46
|
-
// Hardcoded model info — update when Claude Code updates
|
|
47
|
-
const MODEL_NAME = "Fable 5";
|
|
48
|
-
const MODEL_ID = "claude-fable-5";
|
|
49
|
-
const KNOWLEDGE_CUTOFF = "January 2026";
|
|
50
|
-
|
|
51
119
|
export function buildTemplateVars(env: EnvInfo): TemplateVars {
|
|
52
120
|
let gitStatusBlock = "";
|
|
53
121
|
if (env.isGit) {
|
|
@@ -73,9 +141,9 @@ export function buildTemplateVars(env: EnvInfo): TemplateVars {
|
|
|
73
141
|
PLATFORM: env.platform,
|
|
74
142
|
SHELL: env.shell,
|
|
75
143
|
OS_VERSION: env.osVersion,
|
|
76
|
-
MODEL_NAME,
|
|
77
|
-
MODEL_ID,
|
|
78
|
-
KNOWLEDGE_CUTOFF,
|
|
144
|
+
MODEL_NAME: env.model.name,
|
|
145
|
+
MODEL_ID: env.model.id,
|
|
146
|
+
KNOWLEDGE_CUTOFF: env.model.cutoff,
|
|
79
147
|
GIT_STATUS: gitStatusBlock,
|
|
80
148
|
WORKTREE_NOTICE: worktreeNotice,
|
|
81
149
|
};
|
package/src/types.ts
CHANGED
|
@@ -80,6 +80,13 @@ export interface ModeConfig {
|
|
|
80
80
|
modifiers: string[]; // ordered list of modifier fragment paths (embedded keys or absolute paths)
|
|
81
81
|
}
|
|
82
82
|
|
|
83
|
+
/** Resolved model metadata for env.md substitution */
|
|
84
|
+
export interface ModelInfo {
|
|
85
|
+
name: string;
|
|
86
|
+
id: string;
|
|
87
|
+
cutoff: string;
|
|
88
|
+
}
|
|
89
|
+
|
|
83
90
|
export interface EnvInfo {
|
|
84
91
|
cwd: string;
|
|
85
92
|
isGit: boolean;
|
|
@@ -90,6 +97,7 @@ export interface EnvInfo {
|
|
|
90
97
|
platform: string;
|
|
91
98
|
shell: string;
|
|
92
99
|
osVersion: string;
|
|
100
|
+
model: ModelInfo;
|
|
93
101
|
}
|
|
94
102
|
|
|
95
103
|
/** Template variables for env.md substitution */
|
package/src/usage.ts
CHANGED
|
@@ -56,6 +56,8 @@ Modifiers:
|
|
|
56
56
|
Forwarded to claude:
|
|
57
57
|
--append-system-prompt <text>
|
|
58
58
|
--append-system-prompt-file <path>
|
|
59
|
+
--model <alias|id> Also sets the model info in the prompt's environment section.
|
|
60
|
+
Without --model, model info comes from ANTHROPIC_MODEL or Claude settings files.
|
|
59
61
|
|
|
60
62
|
Config: .claude-mode.json (project) or ~/.config/claude-mode/config.json (global)
|
|
61
63
|
|