claude-cli-advanced-starter-pack 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.
Files changed (67) hide show
  1. package/LICENSE +21 -0
  2. package/OVERVIEW.md +597 -0
  3. package/README.md +439 -0
  4. package/bin/gtask.js +282 -0
  5. package/bin/postinstall.js +53 -0
  6. package/package.json +69 -0
  7. package/src/agents/phase-dev-templates.js +1011 -0
  8. package/src/agents/templates.js +668 -0
  9. package/src/analysis/checklist-parser.js +414 -0
  10. package/src/analysis/codebase.js +481 -0
  11. package/src/cli/menu.js +958 -0
  12. package/src/commands/claude-audit.js +1482 -0
  13. package/src/commands/claude-settings.js +2243 -0
  14. package/src/commands/create-agent.js +681 -0
  15. package/src/commands/create-command.js +337 -0
  16. package/src/commands/create-hook.js +262 -0
  17. package/src/commands/create-phase-dev/codebase-analyzer.js +813 -0
  18. package/src/commands/create-phase-dev/documentation-generator.js +352 -0
  19. package/src/commands/create-phase-dev/post-completion.js +404 -0
  20. package/src/commands/create-phase-dev/scale-calculator.js +344 -0
  21. package/src/commands/create-phase-dev/wizard.js +492 -0
  22. package/src/commands/create-phase-dev.js +481 -0
  23. package/src/commands/create-skill.js +313 -0
  24. package/src/commands/create.js +446 -0
  25. package/src/commands/decompose.js +392 -0
  26. package/src/commands/detect-tech-stack.js +768 -0
  27. package/src/commands/explore-mcp/claude-md-updater.js +252 -0
  28. package/src/commands/explore-mcp/mcp-installer.js +346 -0
  29. package/src/commands/explore-mcp/mcp-registry.js +438 -0
  30. package/src/commands/explore-mcp.js +638 -0
  31. package/src/commands/gtask-init.js +641 -0
  32. package/src/commands/help.js +128 -0
  33. package/src/commands/init.js +1890 -0
  34. package/src/commands/install.js +250 -0
  35. package/src/commands/list.js +116 -0
  36. package/src/commands/roadmap.js +750 -0
  37. package/src/commands/setup-wizard.js +482 -0
  38. package/src/commands/setup.js +351 -0
  39. package/src/commands/sync.js +534 -0
  40. package/src/commands/test-run.js +456 -0
  41. package/src/commands/test-setup.js +456 -0
  42. package/src/commands/validate.js +67 -0
  43. package/src/config/tech-stack.defaults.json +182 -0
  44. package/src/config/tech-stack.schema.json +502 -0
  45. package/src/github/client.js +359 -0
  46. package/src/index.js +84 -0
  47. package/src/templates/claude-command.js +244 -0
  48. package/src/templates/issue-body.js +284 -0
  49. package/src/testing/config.js +411 -0
  50. package/src/utils/template-engine.js +398 -0
  51. package/src/utils/validate-templates.js +223 -0
  52. package/src/utils.js +396 -0
  53. package/templates/commands/ccasp-setup.template.md +113 -0
  54. package/templates/commands/context-audit.template.md +97 -0
  55. package/templates/commands/create-task-list.template.md +382 -0
  56. package/templates/commands/deploy-full.template.md +261 -0
  57. package/templates/commands/github-task-start.template.md +99 -0
  58. package/templates/commands/github-update.template.md +69 -0
  59. package/templates/commands/happy-start.template.md +117 -0
  60. package/templates/commands/phase-track.template.md +142 -0
  61. package/templates/commands/tunnel-start.template.md +127 -0
  62. package/templates/commands/tunnel-stop.template.md +106 -0
  63. package/templates/hooks/context-guardian.template.js +173 -0
  64. package/templates/hooks/deployment-orchestrator.template.js +219 -0
  65. package/templates/hooks/github-progress-hook.template.js +197 -0
  66. package/templates/hooks/happy-checkpoint-manager.template.js +222 -0
  67. package/templates/hooks/phase-dev-enforcer.template.js +183 -0
package/src/utils.js ADDED
@@ -0,0 +1,396 @@
1
+ /**
2
+ * Utility functions for GitHub Task Kit
3
+ */
4
+
5
+ import { execSync, exec } from 'child_process';
6
+ import { readFileSync, writeFileSync, existsSync, mkdirSync } from 'fs';
7
+ import { join, dirname } from 'path';
8
+ import { fileURLToPath } from 'url';
9
+ import chalk from 'chalk';
10
+ import ora from 'ora';
11
+
12
+ const __filename = fileURLToPath(import.meta.url);
13
+ const __dirname = dirname(__filename);
14
+
15
+ /**
16
+ * Get package version
17
+ */
18
+ export function getVersion() {
19
+ try {
20
+ const pkgPath = join(__dirname, '..', 'package.json');
21
+ const pkg = JSON.parse(readFileSync(pkgPath, 'utf8'));
22
+ return pkg.version;
23
+ } catch {
24
+ return '1.0.0';
25
+ }
26
+ }
27
+
28
+ /**
29
+ * Check if a command exists
30
+ */
31
+ export function commandExists(cmd) {
32
+ try {
33
+ execSync(`${process.platform === 'win32' ? 'where' : 'which'} ${cmd}`, {
34
+ stdio: 'ignore',
35
+ });
36
+ return true;
37
+ } catch {
38
+ return false;
39
+ }
40
+ }
41
+
42
+ /**
43
+ * Execute a shell command and return output
44
+ */
45
+ export function execCommand(cmd, options = {}) {
46
+ try {
47
+ const result = execSync(cmd, {
48
+ encoding: 'utf8',
49
+ maxBuffer: 10 * 1024 * 1024,
50
+ ...options,
51
+ });
52
+ return { success: true, output: result.trim() };
53
+ } catch (error) {
54
+ return {
55
+ success: false,
56
+ error: error.message,
57
+ output: error.stdout?.toString() || '',
58
+ stderr: error.stderr?.toString() || '',
59
+ };
60
+ }
61
+ }
62
+
63
+ /**
64
+ * Execute command with promise
65
+ */
66
+ export function execAsync(cmd, options = {}) {
67
+ return new Promise((resolve, reject) => {
68
+ exec(
69
+ cmd,
70
+ {
71
+ encoding: 'utf8',
72
+ maxBuffer: 10 * 1024 * 1024,
73
+ ...options,
74
+ },
75
+ (error, stdout, stderr) => {
76
+ if (error) {
77
+ reject({ error, stdout, stderr });
78
+ } else {
79
+ resolve({ stdout: stdout.trim(), stderr: stderr.trim() });
80
+ }
81
+ }
82
+ );
83
+ });
84
+ }
85
+
86
+ /**
87
+ * Check all prerequisites before running
88
+ */
89
+ export async function checkPrerequisites() {
90
+ const spinner = ora('Checking prerequisites...').start();
91
+ const issues = [];
92
+
93
+ // Check gh CLI
94
+ if (!commandExists('gh')) {
95
+ issues.push({
96
+ name: 'GitHub CLI (gh)',
97
+ message: 'Install from https://cli.github.com/',
98
+ fatal: true,
99
+ });
100
+ } else {
101
+ // Check gh version
102
+ const { output } = execCommand('gh --version');
103
+ const versionMatch = output.match(/gh version ([\d.]+)/);
104
+ if (versionMatch) {
105
+ const version = versionMatch[1];
106
+ const [major, minor] = version.split('.').map(Number);
107
+ if (major < 2 || (major === 2 && minor < 40)) {
108
+ issues.push({
109
+ name: 'GitHub CLI version',
110
+ message: `Current: ${version}, Required: 2.40+. Run: gh upgrade`,
111
+ fatal: false,
112
+ });
113
+ }
114
+ }
115
+ }
116
+
117
+ // Check jq
118
+ if (!commandExists('jq')) {
119
+ issues.push({
120
+ name: 'jq (JSON processor)',
121
+ message:
122
+ 'Install: brew install jq (macOS) | apt install jq (Linux) | scoop install jq (Windows)',
123
+ fatal: true,
124
+ });
125
+ }
126
+
127
+ // Check gh auth
128
+ if (commandExists('gh')) {
129
+ const authResult = execCommand('gh auth status');
130
+ if (!authResult.success) {
131
+ issues.push({
132
+ name: 'GitHub authentication',
133
+ message: 'Run: gh auth login',
134
+ fatal: true,
135
+ });
136
+ }
137
+ }
138
+
139
+ if (issues.length > 0) {
140
+ spinner.fail('Prerequisites check failed');
141
+ console.log('');
142
+
143
+ for (const issue of issues) {
144
+ const icon = issue.fatal ? chalk.red('✗') : chalk.yellow('⚠');
145
+ console.log(` ${icon} ${chalk.bold(issue.name)}`);
146
+ console.log(` ${chalk.dim(issue.message)}`);
147
+ }
148
+
149
+ const hasFatal = issues.some((i) => i.fatal);
150
+ if (hasFatal) {
151
+ console.log('');
152
+ console.log(
153
+ chalk.red('Please fix the issues above before continuing.')
154
+ );
155
+ process.exit(1);
156
+ }
157
+
158
+ console.log('');
159
+ } else {
160
+ spinner.succeed('Prerequisites check passed');
161
+ }
162
+ }
163
+
164
+ /**
165
+ * Load configuration from file (async)
166
+ */
167
+ export async function loadConfig() {
168
+ const yaml = await import('yaml');
169
+ const configPaths = [
170
+ join(process.cwd(), '.gtaskrc'),
171
+ join(process.cwd(), '.gtaskrc.yaml'),
172
+ join(process.cwd(), '.gtaskrc.json'),
173
+ join(process.env.HOME || process.env.USERPROFILE || '', '.gtaskrc'),
174
+ join(process.env.HOME || process.env.USERPROFILE || '', '.gtaskrc.yaml'),
175
+ join(process.env.HOME || process.env.USERPROFILE || '', '.gtaskrc.json'),
176
+ ];
177
+
178
+ for (const configPath of configPaths) {
179
+ if (existsSync(configPath)) {
180
+ try {
181
+ const content = readFileSync(configPath, 'utf8');
182
+ if (configPath.endsWith('.json')) {
183
+ return { config: JSON.parse(content), path: configPath };
184
+ } else {
185
+ // YAML parsing
186
+ return { config: yaml.parse(content), path: configPath };
187
+ }
188
+ } catch (error) {
189
+ console.warn(
190
+ chalk.yellow(`Warning: Could not parse config at ${configPath}`)
191
+ );
192
+ }
193
+ }
194
+ }
195
+
196
+ return { config: null, path: null };
197
+ }
198
+
199
+ /**
200
+ * Load config synchronously (for initial checks)
201
+ */
202
+ export function loadConfigSync() {
203
+ const configPaths = [
204
+ join(process.cwd(), '.gtaskrc'),
205
+ join(process.cwd(), '.gtaskrc.yaml'),
206
+ join(process.cwd(), '.gtaskrc.json'),
207
+ join(process.env.HOME || process.env.USERPROFILE || '', '.gtaskrc'),
208
+ join(process.env.HOME || process.env.USERPROFILE || '', '.gtaskrc.yaml'),
209
+ join(process.env.HOME || process.env.USERPROFILE || '', '.gtaskrc.json'),
210
+ ];
211
+
212
+ for (const configPath of configPaths) {
213
+ if (existsSync(configPath)) {
214
+ try {
215
+ const content = readFileSync(configPath, 'utf8');
216
+ if (configPath.endsWith('.json')) {
217
+ return { config: JSON.parse(content), path: configPath };
218
+ } else {
219
+ // Simple YAML-like parsing for basic configs
220
+ const config = {};
221
+ let currentSection = config;
222
+ const lines = content.split('\n');
223
+
224
+ for (const line of lines) {
225
+ const trimmed = line.trim();
226
+ if (!trimmed || trimmed.startsWith('#')) continue;
227
+
228
+ const indent = line.length - line.trimStart().length;
229
+ const match = trimmed.match(/^([^:]+):\s*(.*)$/);
230
+
231
+ if (match) {
232
+ const [, key, value] = match;
233
+ if (value) {
234
+ currentSection[key.trim()] = value.trim().replace(/^["']|["']$/g, '');
235
+ } else {
236
+ currentSection[key.trim()] = {};
237
+ currentSection = currentSection[key.trim()];
238
+ }
239
+ }
240
+ }
241
+
242
+ return { config, path: configPath };
243
+ }
244
+ } catch (error) {
245
+ // Skip invalid configs
246
+ }
247
+ }
248
+ }
249
+
250
+ return { config: null, path: null };
251
+ }
252
+
253
+ /**
254
+ * Check if config exists and is valid
255
+ */
256
+ export function hasValidConfig() {
257
+ const { config } = loadConfigSync();
258
+ return config && config.project_board && config.project_board.owner;
259
+ }
260
+
261
+ /**
262
+ * Format a box around text
263
+ */
264
+ export function box(text, options = {}) {
265
+ const { padding = 1, borderColor = 'cyan' } = options;
266
+ const lines = text.split('\n');
267
+ const maxWidth = Math.max(...lines.map((l) => l.length));
268
+ const paddedWidth = maxWidth + padding * 2;
269
+
270
+ const top = '╔' + '═'.repeat(paddedWidth) + '╗';
271
+ const bottom = '╚' + '═'.repeat(paddedWidth) + '╝';
272
+ const empty = '║' + ' '.repeat(paddedWidth) + '║';
273
+
274
+ const content = lines.map((line) => {
275
+ const padded = line.padEnd(maxWidth);
276
+ return '║' + ' '.repeat(padding) + padded + ' '.repeat(padding) + '║';
277
+ });
278
+
279
+ const result = [
280
+ top,
281
+ ...Array(padding).fill(empty),
282
+ ...content,
283
+ ...Array(padding).fill(empty),
284
+ bottom,
285
+ ].join('\n');
286
+
287
+ return chalk[borderColor](result);
288
+ }
289
+
290
+ /**
291
+ * Truncate string with ellipsis
292
+ */
293
+ export function truncate(str, maxLength) {
294
+ if (str.length <= maxLength) return str;
295
+ return str.slice(0, maxLength - 3) + '...';
296
+ }
297
+
298
+ /**
299
+ * Get current working directory name
300
+ */
301
+ export function getCurrentProjectName() {
302
+ return process.cwd().split(/[/\\]/).pop();
303
+ }
304
+
305
+ /**
306
+ * Get the path to tech-stack.json
307
+ */
308
+ export function getTechStackPath() {
309
+ const paths = [
310
+ join(process.cwd(), '.claude', 'config', 'tech-stack.json'),
311
+ join(process.cwd(), '.claude', 'tech-stack.json'),
312
+ ];
313
+
314
+ for (const p of paths) {
315
+ if (existsSync(p)) {
316
+ return p;
317
+ }
318
+ }
319
+
320
+ // Return default path (even if it doesn't exist yet)
321
+ return paths[0];
322
+ }
323
+
324
+ /**
325
+ * Load tech-stack.json configuration
326
+ * @returns {object} Tech stack configuration or default empty object
327
+ */
328
+ export function loadTechStack() {
329
+ const techStackPath = getTechStackPath();
330
+
331
+ if (existsSync(techStackPath)) {
332
+ try {
333
+ const content = readFileSync(techStackPath, 'utf8');
334
+ return JSON.parse(content);
335
+ } catch (error) {
336
+ console.warn(chalk.yellow(`Warning: Could not parse tech-stack.json: ${error.message}`));
337
+ return getDefaultTechStack();
338
+ }
339
+ }
340
+
341
+ return getDefaultTechStack();
342
+ }
343
+
344
+ /**
345
+ * Save tech-stack.json configuration
346
+ * @param {object} techStack - Tech stack configuration to save
347
+ */
348
+ export function saveTechStack(techStack) {
349
+ const techStackPath = getTechStackPath();
350
+ const configDir = dirname(techStackPath);
351
+
352
+ // Ensure directory exists
353
+ if (!existsSync(configDir)) {
354
+ mkdirSync(configDir, { recursive: true });
355
+ }
356
+
357
+ // Update version timestamp
358
+ techStack._lastModified = new Date().toISOString();
359
+
360
+ writeFileSync(techStackPath, JSON.stringify(techStack, null, 2), 'utf8');
361
+ }
362
+
363
+ /**
364
+ * Get default tech stack configuration
365
+ */
366
+ export function getDefaultTechStack() {
367
+ return {
368
+ version: '2.0.0',
369
+ project: {
370
+ name: getCurrentProjectName(),
371
+ description: '',
372
+ rootPath: '.',
373
+ },
374
+ frontend: {},
375
+ backend: {},
376
+ database: {},
377
+ deployment: {
378
+ frontend: { platform: 'none' },
379
+ backend: { platform: 'none' },
380
+ },
381
+ devEnvironment: {
382
+ tunnel: { service: 'none' },
383
+ },
384
+ testing: {},
385
+ versionControl: {
386
+ provider: 'github',
387
+ projectBoard: { type: 'none' },
388
+ },
389
+ tokenManagement: { enabled: false },
390
+ happyMode: { enabled: false },
391
+ agents: { enabled: true },
392
+ phasedDevelopment: { enabled: true },
393
+ hooks: { enabled: true },
394
+ _pendingConfiguration: [],
395
+ };
396
+ }
@@ -0,0 +1,113 @@
1
+ ---
2
+ description: CCASP Setup Wizard - vibe-code friendly project configuration
3
+ model: haiku
4
+ ---
5
+
6
+ # /ccasp-setup - Claude CLI Advanced Starter Pack Setup
7
+
8
+ Interactive setup wizard for Claude Code CLI enhancement.
9
+
10
+ ## Quick Options
11
+
12
+ Reply with a **number** or **letter** to select:
13
+
14
+ | # | Action | Description |
15
+ |---|--------|-------------|
16
+ | **1** | Quick Start | Auto-detect stack + init .claude |
17
+ | **2** | Full Setup | All features with customization |
18
+ | **3** | GitHub | Connect project board |
19
+ | **4** | Audit | Check existing CLAUDE.md |
20
+ | **5** | Enhance | Generate/improve CLAUDE.md |
21
+ | **6** | Detect | Show detected tech stack |
22
+ | **7** | Templates | Browse available items |
23
+
24
+ ## Feature Presets
25
+
26
+ | Letter | Preset | Features |
27
+ |--------|--------|----------|
28
+ | **A** | Minimal | Menu + help only |
29
+ | **B** | Standard | Essential + GitHub + testing |
30
+ | **C** | Full | Everything including agents |
31
+ | **D** | Custom | Pick individual features |
32
+
33
+ ## Instructions for Claude
34
+
35
+ When this command is invoked:
36
+
37
+ 1. **Show welcome message** with current project status:
38
+ - Does `.claude/` exist?
39
+ - Does `CLAUDE.md` exist?
40
+ - Is tech stack detected?
41
+
42
+ 2. **Present the quick options menu** (shown above)
43
+
44
+ 3. **Handle user selection**:
45
+ - If user types a number (1-7), execute that action
46
+ - If user types a letter (A-D), apply that preset
47
+ - If user types a feature name, toggle that feature
48
+
49
+ 4. **For Quick Start (1)**:
50
+ - Run tech stack detection
51
+ - Show detected stack summary
52
+ - Ask for preset selection (A-D)
53
+ - Initialize `.claude/` folder
54
+ - Offer to generate CLAUDE.md
55
+
56
+ 5. **For Audit (4) or Enhance (5)**:
57
+ - Load existing CLAUDE.md if present
58
+ - Analyze against Anthropic best practices
59
+ - Suggest improvements or generate new content
60
+
61
+ 6. **IMPORTANT - Session Restart Reminder**:
62
+ After ANY action that modifies `.claude/` or `CLAUDE.md`, display:
63
+ ```
64
+ ⚠️ RESTART REQUIRED
65
+
66
+ Changes to .claude/ require a new Claude Code session.
67
+
68
+ To apply changes:
69
+ 1. Exit this session (Ctrl+C or /exit)
70
+ 2. Restart: claude or claude .
71
+ 3. New commands will be available
72
+ ```
73
+
74
+ Actions requiring restart: 1, 2, 3, 5
75
+ Actions NOT requiring restart: 4 (audit), 6 (detect), 7 (templates)
76
+
77
+ ## Vibe-Code Design Principles
78
+
79
+ This wizard is designed for mobile/remote use:
80
+ - **Single character inputs** - Just type "1" or "A"
81
+ - **No long text entry** - All options via selection
82
+ - **Progressive disclosure** - Don't overwhelm
83
+ - **Defaults that work** - Standard preset is recommended
84
+
85
+ ## Terminal Alternative
86
+
87
+ If running outside Claude Code CLI:
88
+
89
+ ```bash
90
+ # Run setup wizard
91
+ npx ccasp wizard
92
+
93
+ # Quick commands
94
+ npx ccasp init # Initialize .claude folder
95
+ npx ccasp detect-stack # Detect tech stack
96
+ npx ccasp claude-audit # Audit CLAUDE.md
97
+ ```
98
+
99
+ ## Available Features
100
+
101
+ | Feature | Description |
102
+ |---------|-------------|
103
+ | `essential` | Menu, help commands |
104
+ | `github` | GitHub Project Board integration |
105
+ | `testing` | Test framework + Ralph Loop |
106
+ | `deployment` | Deploy commands (Cloudflare, Railway) |
107
+ | `agents` | L1/L2/L3 agent hierarchy |
108
+ | `hooks` | Pre/Post tool enforcement |
109
+ | `phasedDev` | Phased development plans |
110
+
111
+ ---
112
+
113
+ *Part of Claude CLI Advanced Starter Pack*
@@ -0,0 +1,97 @@
1
+ ---
2
+ description: Audit and analyze current context token usage
3
+ model: haiku
4
+ ---
5
+
6
+ # /context-audit - Token Budget Audit
7
+
8
+ Analyze current session context and token usage against budget thresholds.
9
+
10
+ {{#if tokenManagement.enabled}}
11
+
12
+ ## Configuration
13
+
14
+ | Setting | Value |
15
+ |---------|-------|
16
+ | Daily Budget | {{tokenManagement.dailyBudget}} tokens |
17
+ | Compact Threshold | {{tokenManagement.thresholds.compact}} ({{#if tokenManagement.dailyBudget}}~{{tokenManagement.dailyBudget * tokenManagement.thresholds.compact}} tokens{{/if}}) |
18
+ | Archive Threshold | {{tokenManagement.thresholds.archive}} ({{#if tokenManagement.dailyBudget}}~{{tokenManagement.dailyBudget * tokenManagement.thresholds.archive}} tokens{{/if}}) |
19
+ | Respawn Threshold | {{tokenManagement.thresholds.respawn}} ({{#if tokenManagement.dailyBudget}}~{{tokenManagement.dailyBudget * tokenManagement.thresholds.respawn}} tokens{{/if}}) |
20
+ | Tracking File | {{tokenManagement.trackingFile}} |
21
+
22
+ ## Audit Actions
23
+
24
+ ### 1. Context Size Analysis
25
+ - Count total messages in conversation
26
+ - Estimate token usage per message type
27
+ - Identify largest context consumers
28
+
29
+ ### 2. Compaction Opportunities
30
+ - Identify verbose tool outputs that could be summarized
31
+ - Find duplicate information in context
32
+ - Suggest messages that could be archived
33
+
34
+ ### 3. Budget Status
35
+ - Current usage vs daily budget
36
+ - Time remaining in budget period
37
+ - Projected usage based on current rate
38
+
39
+ ## Recommendations by Threshold
40
+
41
+ ### At Compact Threshold ({{tokenManagement.thresholds.compact}})
42
+ - Summarize verbose tool outputs
43
+ - Remove intermediate exploration results
44
+ - Keep only essential context
45
+
46
+ ### At Archive Threshold ({{tokenManagement.thresholds.archive}})
47
+ - Archive current session to `.claude/docs/sessions/`
48
+ - Create summary of accomplishments
49
+ - Start new session with essential context only
50
+
51
+ ### At Respawn Threshold ({{tokenManagement.thresholds.respawn}})
52
+ - Force session restart
53
+ - Save all progress to files
54
+ - Create handoff document for new session
55
+
56
+ ## Instructions for Claude
57
+
58
+ When this command is invoked:
59
+
60
+ 1. **Analyze Context**
61
+ - Estimate current token usage
62
+ - Calculate percentage of daily budget used
63
+
64
+ 2. **Generate Report**
65
+ ```
66
+ Token Budget Audit
67
+ ─────────────────────
68
+ Estimated Usage: X tokens (Y% of budget)
69
+ Status: [OK | COMPACT | ARCHIVE | RESPAWN]
70
+
71
+ Top Context Consumers:
72
+ 1. Tool outputs: ~X tokens
73
+ 2. Code blocks: ~X tokens
74
+ 3. Conversation: ~X tokens
75
+ ```
76
+
77
+ 3. **Provide Recommendations**
78
+ - If below compact threshold: Continue normally
79
+ - If at compact threshold: Suggest compaction strategies
80
+ - If at archive threshold: Offer to archive session
81
+ - If at respawn threshold: Initiate respawn protocol
82
+
83
+ {{else}}
84
+
85
+ ## Token Management Disabled
86
+
87
+ Token budget management is not enabled for this project.
88
+
89
+ To enable:
90
+ 1. Run `/menu` → Project Settings → Token Management
91
+ 2. Or manually set `tokenManagement.enabled: true` in tech-stack.json
92
+
93
+ {{/if}}
94
+
95
+ ---
96
+
97
+ *Generated from tech-stack.json template*