wtf-p 0.3.0 → 0.5.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 +146 -208
- package/bin/commands/doctor.js +88 -2
- package/bin/commands/install-logic.js +127 -36
- package/bin/commands/status.js +22 -4
- package/bin/commands/update.js +5 -4
- package/bin/install.js +66 -26
- package/bin/lib/analyze-impact.js +105 -0
- package/bin/lib/bib-format.js +161 -0
- package/bin/lib/bib-index.js +104 -0
- package/bin/lib/checkpoint.js +183 -0
- package/bin/lib/citation-fetcher.js +299 -0
- package/bin/lib/citation-ranker.js +133 -0
- package/bin/lib/context-primer.js +214 -0
- package/bin/lib/manifest.js +80 -2
- package/bin/lib/scholar-lookup.js +188 -0
- package/bin/lib/semantic-scholar.js +184 -0
- package/bin/lib/utils.js +22 -1
- package/bin/uninstall.js +270 -111
- package/core/write-the-f-paper/references/agent-model-matrix.md +62 -0
- package/core/write-the-f-paper/references/checkpoints.md +160 -9
- package/core/write-the-f-paper/references/context-fidelity.md +153 -0
- package/core/write-the-f-paper/references/deviation-rules.md +150 -0
- package/core/write-the-f-paper/references/git-integration.md +80 -0
- package/core/write-the-f-paper/references/orchestrator-pattern.md +167 -0
- package/core/write-the-f-paper/references/planning-config.md +135 -0
- package/core/write-the-f-paper/references/ui-brand.md +186 -0
- package/core/write-the-f-paper/templates/UAT.md +80 -0
- package/core/write-the-f-paper/templates/base-prefs.yaml +42 -0
- package/core/write-the-f-paper/templates/config.json +31 -5
- package/core/write-the-f-paper/workflows/create-outline.wcn.md +1 -1
- package/core/write-the-f-paper/workflows/execute-outline.md +163 -0
- package/core/write-the-f-paper/workflows/execute-outline.wcn.md +73 -0
- package/core/write-the-f-paper/workflows/execute-section.wcn.md +141 -169
- package/core/write-the-f-paper/workflows/plan-section.wcn.md +96 -103
- package/core/write-the-f-paper/workflows/research-gap.md +27 -3
- package/core/write-the-f-paper/workflows/research-gap.wcn.md +18 -1
- package/core/write-the-f-paper/workflows/verify-work.md +251 -0
- package/core/write-the-f-paper/workflows/verify-work.wcn.md +74 -0
- package/package.json +19 -7
- package/vendors/claude/.claude-plugin/plugin.json +2 -2
- package/vendors/claude/agents/wtfp/argument-verifier.md +189 -0
- package/vendors/claude/agents/wtfp/citation-expert.md +45 -0
- package/vendors/claude/agents/wtfp/citation-formatter.md +42 -0
- package/vendors/claude/agents/wtfp/coherence-checker.md +167 -0
- package/vendors/claude/agents/wtfp/outliner.md +259 -0
- package/vendors/claude/agents/wtfp/plan-checker.md +249 -0
- package/vendors/claude/agents/wtfp/prose-polisher.md +166 -0
- package/vendors/claude/agents/wtfp/research-synthesizer.md +215 -0
- package/vendors/claude/agents/wtfp/section-planner.md +364 -0
- package/vendors/claude/agents/wtfp/section-reviewer.md +182 -0
- package/vendors/claude/agents/wtfp/section-writer.md +312 -0
- package/vendors/claude/commands/wtfp/add-todo.md +108 -0
- package/vendors/claude/commands/wtfp/analyze-bib.md +60 -249
- package/vendors/claude/commands/wtfp/audit-milestone.md +286 -0
- package/vendors/claude/commands/wtfp/check-refs.md +60 -131
- package/vendors/claude/commands/wtfp/check-todos.md +152 -0
- package/vendors/claude/commands/wtfp/checkpoint.md +105 -0
- package/vendors/claude/commands/wtfp/contribute.md +1 -1
- package/vendors/claude/commands/wtfp/create-outline.md +109 -195
- package/vendors/claude/commands/wtfp/create-poster.md +1 -1
- package/vendors/claude/commands/wtfp/create-slides.md +1 -1
- package/vendors/claude/commands/wtfp/discuss-section.md +1 -1
- package/vendors/claude/commands/wtfp/execute-outline.md +257 -0
- package/vendors/claude/commands/wtfp/export-latex.md +1 -1
- package/vendors/claude/commands/wtfp/help.md +174 -280
- package/vendors/claude/commands/wtfp/insert-section.md +1 -1
- package/vendors/claude/commands/wtfp/list-assumptions.md +1 -1
- package/vendors/claude/commands/wtfp/map-project.md +35 -124
- package/vendors/claude/commands/wtfp/new-paper.md +88 -362
- package/vendors/claude/commands/wtfp/pause-writing.md +1 -1
- package/vendors/claude/commands/wtfp/plan-milestone-gaps.md +255 -0
- package/vendors/claude/commands/wtfp/plan-revision.md +1 -1
- package/vendors/claude/commands/wtfp/plan-section.md +165 -190
- package/vendors/claude/commands/wtfp/polish-prose.md +66 -118
- package/vendors/claude/commands/wtfp/progress.md +82 -254
- package/vendors/claude/commands/wtfp/quick.md +107 -0
- package/vendors/claude/commands/wtfp/remove-section.md +1 -1
- package/vendors/claude/commands/wtfp/report-bug.md +1 -1
- package/vendors/claude/commands/wtfp/request-feature.md +1 -1
- package/vendors/claude/commands/wtfp/research-gap.md +138 -151
- package/vendors/claude/commands/wtfp/resume-writing.md +1 -1
- package/vendors/claude/commands/wtfp/review-section.md +55 -333
- package/vendors/claude/commands/wtfp/settings.md +197 -0
- package/vendors/claude/commands/wtfp/submit-milestone.md +248 -99
- package/vendors/claude/commands/wtfp/update.md +112 -0
- package/vendors/claude/commands/wtfp/verify-work.md +254 -0
- package/vendors/claude/commands/wtfp/write-section.md +144 -180
- package/vendors/claude/mcp/research-server/package.json +13 -0
- package/vendors/claude/mcp/research-server/src/index.js +133 -0
- package/vendors/gemini/agents/wtfp/argument-verifier.md +184 -0
- package/vendors/gemini/agents/wtfp/citation-expert.md +41 -0
- package/vendors/gemini/agents/wtfp/citation-formatter.md +38 -0
- package/vendors/gemini/agents/wtfp/coherence-checker.md +162 -0
- package/vendors/gemini/agents/wtfp/outliner.md +252 -0
- package/vendors/gemini/agents/wtfp/plan-checker.md +244 -0
- package/vendors/gemini/agents/wtfp/prose-polisher.md +158 -0
- package/vendors/gemini/agents/wtfp/research-synthesizer.md +205 -0
- package/vendors/gemini/agents/wtfp/section-planner.md +355 -0
- package/vendors/gemini/agents/wtfp/section-reviewer.md +175 -0
- package/vendors/gemini/agents/wtfp/section-writer.md +304 -0
- package/vendors/gemini/commands/wtfp/add-todo.toml +102 -0
- package/vendors/gemini/commands/wtfp/analyze-bib.toml +126 -0
- package/vendors/gemini/commands/wtfp/audit-milestone.toml +278 -0
- package/vendors/gemini/commands/wtfp/check-refs.toml +123 -0
- package/vendors/gemini/commands/wtfp/check-todos.toml +145 -0
- package/vendors/gemini/commands/wtfp/checkpoint.toml +96 -0
- package/vendors/gemini/commands/wtfp/contribute.toml +269 -0
- package/vendors/gemini/commands/wtfp/create-outline.toml +180 -0
- package/vendors/gemini/commands/wtfp/create-poster.toml +36 -0
- package/vendors/gemini/commands/wtfp/create-slides.toml +35 -0
- package/vendors/gemini/commands/wtfp/discuss-section.toml +62 -0
- package/vendors/gemini/commands/wtfp/execute-outline.toml +247 -0
- package/vendors/gemini/commands/wtfp/export-latex.toml +209 -0
- package/vendors/gemini/commands/wtfp/help.toml +184 -0
- package/vendors/gemini/commands/wtfp/insert-section.toml +123 -0
- package/vendors/gemini/commands/wtfp/list-assumptions.toml +104 -0
- package/vendors/gemini/commands/wtfp/map-project.toml +99 -0
- package/vendors/gemini/commands/wtfp/new-paper.toml +160 -0
- package/vendors/gemini/commands/wtfp/pause-writing.toml +140 -0
- package/vendors/gemini/commands/wtfp/plan-milestone-gaps.toml +249 -0
- package/vendors/gemini/commands/wtfp/plan-revision.toml +171 -0
- package/vendors/gemini/commands/wtfp/plan-section.toml +212 -0
- package/vendors/gemini/commands/wtfp/polish-prose.toml +114 -0
- package/vendors/gemini/commands/wtfp/progress.toml +145 -0
- package/vendors/gemini/commands/wtfp/quick.toml +96 -0
- package/vendors/gemini/commands/wtfp/remove-section.toml +140 -0
- package/vendors/gemini/commands/wtfp/report-bug.toml +126 -0
- package/vendors/gemini/commands/wtfp/request-feature.toml +155 -0
- package/vendors/gemini/commands/wtfp/research-gap.toml +214 -0
- package/vendors/gemini/commands/wtfp/resume-writing.toml +136 -0
- package/vendors/gemini/commands/wtfp/review-section.toml +121 -0
- package/vendors/gemini/commands/wtfp/settings.toml +191 -0
- package/vendors/gemini/commands/wtfp/submit-milestone.toml +351 -0
- package/vendors/gemini/commands/wtfp/update.toml +107 -0
- package/vendors/gemini/commands/wtfp/verify-work.toml +245 -0
- package/vendors/gemini/commands/wtfp/write-section.toml +228 -0
- package/vendors/opencode/agents/wtfp/argument-verifier.md +184 -0
- package/vendors/opencode/agents/wtfp/citation-expert.md +41 -0
- package/vendors/opencode/agents/wtfp/citation-formatter.md +38 -0
- package/vendors/opencode/agents/wtfp/coherence-checker.md +162 -0
- package/vendors/opencode/agents/wtfp/outliner.md +252 -0
- package/vendors/opencode/agents/wtfp/plan-checker.md +244 -0
- package/vendors/opencode/agents/wtfp/prose-polisher.md +158 -0
- package/vendors/opencode/agents/wtfp/research-synthesizer.md +205 -0
- package/vendors/opencode/agents/wtfp/section-planner.md +355 -0
- package/vendors/opencode/agents/wtfp/section-reviewer.md +175 -0
- package/vendors/opencode/agents/wtfp/section-writer.md +304 -0
- package/vendors/opencode/commands/wtfp/add-todo.md +103 -0
- package/vendors/opencode/commands/wtfp/analyze-bib.md +127 -0
- package/vendors/opencode/commands/wtfp/audit-milestone.md +279 -0
- package/vendors/opencode/commands/wtfp/check-refs.md +124 -0
- package/vendors/opencode/commands/wtfp/check-todos.md +146 -0
- package/vendors/opencode/commands/wtfp/checkpoint.md +97 -0
- package/vendors/opencode/commands/wtfp/contribute.md +266 -0
- package/vendors/opencode/commands/wtfp/create-outline.md +181 -0
- package/vendors/opencode/commands/wtfp/create-poster.md +37 -0
- package/vendors/opencode/commands/wtfp/create-slides.md +36 -0
- package/vendors/opencode/commands/wtfp/discuss-section.md +63 -0
- package/vendors/opencode/commands/wtfp/execute-outline.md +248 -0
- package/vendors/opencode/commands/wtfp/export-latex.md +210 -0
- package/vendors/opencode/commands/wtfp/help.md +185 -0
- package/vendors/opencode/commands/wtfp/insert-section.md +124 -0
- package/vendors/opencode/commands/wtfp/list-assumptions.md +105 -0
- package/vendors/opencode/commands/wtfp/map-project.md +100 -0
- package/vendors/opencode/commands/wtfp/new-paper.md +161 -0
- package/vendors/opencode/commands/wtfp/pause-writing.md +141 -0
- package/vendors/opencode/commands/wtfp/plan-milestone-gaps.md +250 -0
- package/vendors/opencode/commands/wtfp/plan-revision.md +174 -0
- package/vendors/opencode/commands/wtfp/plan-section.md +214 -0
- package/vendors/opencode/commands/wtfp/polish-prose.md +115 -0
- package/vendors/opencode/commands/wtfp/progress.md +146 -0
- package/vendors/opencode/commands/wtfp/quick.md +97 -0
- package/vendors/opencode/commands/wtfp/remove-section.md +141 -0
- package/vendors/opencode/commands/wtfp/report-bug.md +127 -0
- package/vendors/opencode/commands/wtfp/request-feature.md +156 -0
- package/vendors/opencode/commands/wtfp/research-gap.md +215 -0
- package/vendors/opencode/commands/wtfp/resume-writing.md +137 -0
- package/vendors/opencode/commands/wtfp/review-section.md +123 -0
- package/vendors/opencode/commands/wtfp/settings.md +192 -0
- package/vendors/opencode/commands/wtfp/submit-milestone.md +352 -0
- package/vendors/opencode/commands/wtfp/update.md +108 -0
- package/vendors/opencode/commands/wtfp/verify-work.md +246 -0
- package/vendors/opencode/commands/wtfp/write-section.md +228 -0
package/bin/uninstall.js
CHANGED
|
@@ -17,6 +17,7 @@ const {
|
|
|
17
17
|
prompt,
|
|
18
18
|
VERSION_FILE
|
|
19
19
|
} = require('./lib/utils');
|
|
20
|
+
const MANIFEST = require('./lib/manifest');
|
|
20
21
|
|
|
21
22
|
// Get version from package.json
|
|
22
23
|
let version = 'unknown';
|
|
@@ -32,6 +33,10 @@ try {
|
|
|
32
33
|
const args = process.argv.slice(2);
|
|
33
34
|
const hasGlobal = args.includes('--global') || args.includes('-g');
|
|
34
35
|
const hasLocal = args.includes('--local') || args.includes('-l');
|
|
36
|
+
const hasClaude = args.includes('--claude');
|
|
37
|
+
const hasGemini = args.includes('--gemini');
|
|
38
|
+
const hasOpenCode = args.includes('--opencode');
|
|
39
|
+
const hasAll = args.includes('--all');
|
|
35
40
|
const hasForce = args.includes('--force') || args.includes('-f');
|
|
36
41
|
const hasBackup = args.includes('--backup') || args.includes('-b');
|
|
37
42
|
const hasDryRun = args.includes('--dry-run') || args.includes('-n');
|
|
@@ -86,54 +91,82 @@ if (!hasQuiet) {
|
|
|
86
91
|
// ============ Help Text ============
|
|
87
92
|
|
|
88
93
|
if (hasHelp) {
|
|
89
|
-
console.log(` ${c.yellow('Usage:')} npx wtf-p
|
|
94
|
+
console.log(` ${c.yellow('Usage:')} npx wtf-p uninstall [options]
|
|
90
95
|
|
|
91
96
|
${c.yellow('Options:')}
|
|
92
|
-
${c.cyan('-g, --global')} Uninstall from
|
|
93
|
-
${c.cyan('-l, --local')} Uninstall from
|
|
94
|
-
${c.cyan('
|
|
97
|
+
${c.cyan('-g, --global')} Uninstall from home directory
|
|
98
|
+
${c.cyan('-l, --local')} Uninstall from current project
|
|
99
|
+
${c.cyan('--claude')} Uninstall from Claude Code
|
|
100
|
+
${c.cyan('--gemini')} Uninstall from Gemini CLI
|
|
101
|
+
${c.cyan('--opencode')} Uninstall from OpenCode
|
|
102
|
+
${c.cyan('--all')} Uninstall from all tools
|
|
103
|
+
${c.cyan('-c, --config-dir <path>')} Uninstall from a custom directory
|
|
95
104
|
${c.cyan('-f, --force')} Skip confirmation prompts
|
|
96
105
|
${c.cyan('-b, --backup')} Backup files before removing
|
|
97
|
-
${c.cyan('-n, --dry-run')}
|
|
98
|
-
${c.cyan('--clean-backups')} Also remove
|
|
106
|
+
${c.cyan('-n, --dry-run')} Preview what would be removed
|
|
107
|
+
${c.cyan('--clean-backups')} Also remove backup files from prior installs
|
|
99
108
|
${c.cyan('--no-color')} Disable colored output
|
|
100
109
|
${c.cyan('-q, --quiet')} Suppress non-essential output
|
|
101
|
-
${c.cyan('-h, --help')} Show this help
|
|
110
|
+
${c.cyan('-h, --help')} Show this help
|
|
102
111
|
|
|
103
112
|
${c.yellow('What gets removed:')}
|
|
104
|
-
${c.dim('commands/wtfp/')}
|
|
105
|
-
${c.dim('write-the-f-paper/')}
|
|
106
|
-
${c.dim('
|
|
107
|
-
${c.dim('
|
|
108
|
-
${c.dim('.
|
|
113
|
+
${c.dim('commands/wtfp/')} Slash commands (/wtfp:*)
|
|
114
|
+
${c.dim('write-the-f-paper/')} Writing system files
|
|
115
|
+
${c.dim('agents/wtfp/')} Agent definitions
|
|
116
|
+
${c.dim('skills/wtfp/')} Skill definitions
|
|
117
|
+
${c.dim('.claude-plugin/')} Plugin manifest
|
|
118
|
+
${c.dim('.wtfp-version')} Version tracking file
|
|
109
119
|
|
|
110
120
|
${c.yellow('What stays intact:')}
|
|
111
|
-
${c.dim('CLAUDE.md')}
|
|
112
|
-
${c.dim('commands/')}
|
|
113
|
-
${c.dim('settings.json')}
|
|
114
|
-
${c.dim('
|
|
121
|
+
${c.dim('CLAUDE.md')} Your personal instructions (never touched)
|
|
122
|
+
${c.dim('commands/')} Other slash commands you added
|
|
123
|
+
${c.dim('settings.json')} Your tool settings
|
|
124
|
+
${c.dim('Everything else')} Nothing outside WTF-P is modified
|
|
115
125
|
|
|
116
126
|
${c.yellow('Examples:')}
|
|
117
|
-
${c.dim('# Interactive uninstall from ~/.claude')}
|
|
118
|
-
npx wtf-p-uninstall --global
|
|
119
|
-
|
|
120
127
|
${c.dim('# Preview what would be removed')}
|
|
121
|
-
npx wtf-p
|
|
128
|
+
npx wtf-p uninstall --global --dry-run
|
|
122
129
|
|
|
123
|
-
${c.dim('# Backup
|
|
124
|
-
npx wtf-p
|
|
130
|
+
${c.dim('# Backup then remove')}
|
|
131
|
+
npx wtf-p uninstall --global --backup
|
|
125
132
|
|
|
126
|
-
${c.dim('#
|
|
127
|
-
npx wtf-p
|
|
133
|
+
${c.dim('# Remove from all tools at once')}
|
|
134
|
+
npx wtf-p uninstall --all
|
|
128
135
|
|
|
129
|
-
${c.dim('#
|
|
130
|
-
npx wtf-p
|
|
136
|
+
${c.dim('# Also clean up leftover backup files')}
|
|
137
|
+
npx wtf-p uninstall --global --clean-backups
|
|
131
138
|
`);
|
|
132
139
|
process.exit(0);
|
|
133
140
|
}
|
|
134
141
|
|
|
135
142
|
// ============ Utilities ============
|
|
136
143
|
|
|
144
|
+
/**
|
|
145
|
+
* Get vendor-specific config directory
|
|
146
|
+
*/
|
|
147
|
+
function getVendorDir(runtime, explicitConfigDir) {
|
|
148
|
+
// Handle 'claude-local' special case
|
|
149
|
+
if (runtime === 'claude-local') {
|
|
150
|
+
return path.join(process.cwd(), '.claude');
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
const vendorConfig = MANIFEST[runtime];
|
|
154
|
+
if (!vendorConfig) {
|
|
155
|
+
return null;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
if (explicitConfigDir) {
|
|
159
|
+
return expandTilde(explicitConfigDir);
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
const envDir = process.env[vendorConfig.configDirEnv];
|
|
163
|
+
if (envDir) {
|
|
164
|
+
return expandTilde(envDir);
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
return path.join(os.homedir(), vendorConfig.defaultDir);
|
|
168
|
+
}
|
|
169
|
+
|
|
137
170
|
/**
|
|
138
171
|
* Generate backup directory path with timestamp
|
|
139
172
|
*/
|
|
@@ -192,28 +225,39 @@ function findBackupFiles(dir, backups = []) {
|
|
|
192
225
|
// ============ Uninstall Logic ============
|
|
193
226
|
|
|
194
227
|
/**
|
|
195
|
-
* Uninstall from the specified
|
|
228
|
+
* Uninstall from the specified runtime
|
|
229
|
+
* @param {string} runtime - 'claude' | 'gemini' | 'opencode' | 'claude-local'
|
|
196
230
|
*/
|
|
197
|
-
async function uninstall(
|
|
198
|
-
const
|
|
199
|
-
const
|
|
231
|
+
async function uninstall(runtime) {
|
|
232
|
+
const isLocal = runtime === 'claude-local';
|
|
233
|
+
const vendorKey = isLocal ? 'claude' : runtime;
|
|
234
|
+
const vendorConfig = MANIFEST[vendorKey];
|
|
235
|
+
|
|
236
|
+
if (!vendorConfig) {
|
|
237
|
+
out.error(`Unknown runtime: ${runtime}`);
|
|
238
|
+
return;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
const targetDir = getVendorDir(runtime, explicitConfigDir);
|
|
242
|
+
const locationLabel = getPathLabel(targetDir, !isLocal);
|
|
200
243
|
|
|
201
244
|
out.log(` Checking ${c.cyan(locationLabel)} for WTF-P installation...\n`);
|
|
202
245
|
|
|
203
246
|
// Detect installation
|
|
204
|
-
const installed = detectInstallation(
|
|
205
|
-
const totalFiles = installed.commandFiles.length + installed.workflowFiles.length + installed.skillFiles.length
|
|
247
|
+
const installed = detectInstallation(targetDir);
|
|
248
|
+
const totalFiles = installed.commandFiles.length + installed.workflowFiles.length + installed.skillFiles.length
|
|
249
|
+
+ (installed.agentFiles || []).length + (installed.mcpFiles || []).length + (installed.binFiles || []).length;
|
|
206
250
|
|
|
207
251
|
if (!installed.hasCommands && !installed.hasWorkflows && !installed.hasSkills) {
|
|
208
252
|
out.log(` ${c.yellow('No WTF-P installation found in ' + locationLabel)}\n`);
|
|
209
253
|
|
|
210
254
|
// Check for backups if requested
|
|
211
255
|
if (hasCleanBackups) {
|
|
212
|
-
const backups = findBackupFiles(
|
|
256
|
+
const backups = findBackupFiles(targetDir);
|
|
213
257
|
if (backups.length > 0) {
|
|
214
258
|
out.log(` Found ${backups.length} backup file(s)/folder(s) to clean:\n`);
|
|
215
259
|
for (const b of backups.slice(0, 10)) {
|
|
216
|
-
out.log(` ${c.dim(b.replace(
|
|
260
|
+
out.log(` ${c.dim(b.replace(targetDir, '.'))}`);
|
|
217
261
|
}
|
|
218
262
|
if (backups.length > 10) {
|
|
219
263
|
out.log(` ${c.dim('... and ' + (backups.length - 10) + ' more')}`);
|
|
@@ -237,7 +281,7 @@ async function uninstall(isGlobal) {
|
|
|
237
281
|
} else {
|
|
238
282
|
fs.unlinkSync(b);
|
|
239
283
|
}
|
|
240
|
-
out.log(` ${c.red('-')} ${c.dim(b.replace(
|
|
284
|
+
out.log(` ${c.red('-')} ${c.dim(b.replace(targetDir, '.'))}`);
|
|
241
285
|
}
|
|
242
286
|
out.log(`\n ${c.green('Cleaned ' + backups.length + ' backup file(s).')}\n`);
|
|
243
287
|
} else {
|
|
@@ -253,10 +297,14 @@ async function uninstall(isGlobal) {
|
|
|
253
297
|
// Show what will be removed
|
|
254
298
|
out.log(` ${c.yellow('Found WTF-P installation:')}\n`);
|
|
255
299
|
|
|
256
|
-
const commandsDir = path.join(
|
|
257
|
-
const workflowsDir = path.join(
|
|
258
|
-
const skillsDir = path.join(
|
|
259
|
-
const
|
|
300
|
+
const commandsDir = path.join(targetDir, 'commands', 'wtfp');
|
|
301
|
+
const workflowsDir = path.join(targetDir, 'write-the-f-paper');
|
|
302
|
+
const skillsDir = path.join(targetDir, 'skills', 'wtfp');
|
|
303
|
+
const agentsDir = path.join(targetDir, 'agents', 'wtfp');
|
|
304
|
+
const mcpDir = path.join(targetDir, 'mcp');
|
|
305
|
+
const binDir = path.join(targetDir, 'bin');
|
|
306
|
+
const pluginDir = path.join(targetDir, '.claude-plugin');
|
|
307
|
+
const wtfpPluginFile = path.join(pluginDir, 'plugin.json');
|
|
260
308
|
|
|
261
309
|
if (installed.hasCommands) {
|
|
262
310
|
out.log(` ${c.cyan('commands/wtfp/')} (${installed.commandFiles.length} files)`);
|
|
@@ -267,8 +315,17 @@ async function uninstall(isGlobal) {
|
|
|
267
315
|
if (installed.hasSkills) {
|
|
268
316
|
out.log(` ${c.cyan('skills/wtfp/')} (${installed.skillFiles.length} files)`);
|
|
269
317
|
}
|
|
270
|
-
if (fs.existsSync(
|
|
271
|
-
out.log(` ${c.cyan('
|
|
318
|
+
if (fs.existsSync(agentsDir)) {
|
|
319
|
+
out.log(` ${c.cyan('agents/wtfp/')} (agent definitions)`);
|
|
320
|
+
}
|
|
321
|
+
if (fs.existsSync(mcpDir)) {
|
|
322
|
+
out.log(` ${c.cyan('mcp/')} (MCP server)`);
|
|
323
|
+
}
|
|
324
|
+
if (fs.existsSync(binDir)) {
|
|
325
|
+
out.log(` ${c.cyan('bin/')} (scripts)`);
|
|
326
|
+
}
|
|
327
|
+
if (fs.existsSync(wtfpPluginFile)) {
|
|
328
|
+
out.log(` ${c.cyan('.claude-plugin/plugin.json')} (WTF-P plugin manifest)`);
|
|
272
329
|
}
|
|
273
330
|
if (installed.version) {
|
|
274
331
|
out.log(` ${c.cyan(VERSION_FILE)} (version tracking)`);
|
|
@@ -278,10 +335,10 @@ async function uninstall(isGlobal) {
|
|
|
278
335
|
// Check for backups to clean
|
|
279
336
|
let backups = [];
|
|
280
337
|
if (hasCleanBackups) {
|
|
281
|
-
const allBackups = findBackupFiles(
|
|
338
|
+
const allBackups = findBackupFiles(targetDir);
|
|
282
339
|
backups = allBackups.filter(b => {
|
|
283
340
|
if (installed.hasCommands && b.startsWith(commandsDir)) return false;
|
|
284
|
-
if (installed.
|
|
341
|
+
if (installed.hasSkills && b.startsWith(skillsDir)) return false;
|
|
285
342
|
return true;
|
|
286
343
|
});
|
|
287
344
|
if (backups.length > 0) {
|
|
@@ -310,69 +367,111 @@ async function uninstall(isGlobal) {
|
|
|
310
367
|
|
|
311
368
|
// Backup if requested
|
|
312
369
|
if (hasBackup) {
|
|
313
|
-
const
|
|
314
|
-
fs.mkdirSync(
|
|
370
|
+
const backupDirPath = getBackupDir(targetDir);
|
|
371
|
+
fs.mkdirSync(backupDirPath, { recursive: true });
|
|
315
372
|
|
|
316
373
|
if (installed.hasCommands) {
|
|
317
|
-
copyDir(commandsDir, path.join(
|
|
374
|
+
copyDir(commandsDir, path.join(backupDirPath, 'commands', 'wtfp'));
|
|
318
375
|
}
|
|
319
376
|
if (installed.hasWorkflows) {
|
|
320
|
-
copyDir(workflowsDir, path.join(
|
|
377
|
+
copyDir(workflowsDir, path.join(backupDirPath, 'write-the-f-paper'));
|
|
321
378
|
}
|
|
322
379
|
if (installed.hasSkills) {
|
|
323
|
-
copyDir(skillsDir, path.join(
|
|
380
|
+
copyDir(skillsDir, path.join(backupDirPath, 'skills', 'wtfp'));
|
|
324
381
|
}
|
|
325
|
-
if (fs.existsSync(
|
|
326
|
-
copyDir(
|
|
382
|
+
if (fs.existsSync(agentsDir)) {
|
|
383
|
+
copyDir(agentsDir, path.join(backupDirPath, 'agents', 'wtfp'));
|
|
384
|
+
}
|
|
385
|
+
if (fs.existsSync(mcpDir)) {
|
|
386
|
+
copyDir(mcpDir, path.join(backupDirPath, 'mcp'));
|
|
387
|
+
}
|
|
388
|
+
if (fs.existsSync(binDir)) {
|
|
389
|
+
copyDir(binDir, path.join(backupDirPath, 'bin'));
|
|
390
|
+
}
|
|
391
|
+
if (fs.existsSync(wtfpPluginFile)) {
|
|
392
|
+
fs.mkdirSync(path.join(backupDirPath, '.claude-plugin'), { recursive: true });
|
|
393
|
+
fs.copyFileSync(wtfpPluginFile, path.join(backupDirPath, '.claude-plugin', 'plugin.json'));
|
|
327
394
|
}
|
|
328
395
|
|
|
329
|
-
const backupLabel =
|
|
396
|
+
const backupLabel = backupDirPath.replace(os.homedir(), '~').replace(process.cwd(), '.');
|
|
330
397
|
out.log(` ${c.cyan('↻')} Backed up to ${c.dim(backupLabel)}\n`);
|
|
331
398
|
}
|
|
332
399
|
|
|
333
|
-
// Remove directories
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
400
|
+
// Remove directories — only WTF-P subdirectories, never parent dirs with user content
|
|
401
|
+
|
|
402
|
+
// Helper: remove a wtfp subdir and clean up empty parent
|
|
403
|
+
function removeWtfpSubdir(subdir, parentDir, label) {
|
|
404
|
+
if (!fs.existsSync(subdir)) return;
|
|
405
|
+
removeDir(subdir);
|
|
406
|
+
out.log(` ${c.red('-')} ${c.dim(label)}`);
|
|
407
|
+
|
|
408
|
+
// Clean up parent only if empty (no user content remains)
|
|
409
|
+
if (parentDir && fs.existsSync(parentDir)) {
|
|
410
|
+
try {
|
|
411
|
+
const remaining = fs.readdirSync(parentDir);
|
|
412
|
+
if (remaining.length === 0) {
|
|
413
|
+
fs.rmdirSync(parentDir);
|
|
414
|
+
out.log(` ${c.red('-')} ${c.dim(path.basename(parentDir) + '/')} ${c.dim('(empty)')}`);
|
|
415
|
+
}
|
|
416
|
+
} catch { /* ignore */ }
|
|
346
417
|
}
|
|
347
418
|
}
|
|
348
419
|
|
|
420
|
+
if (installed.hasCommands) {
|
|
421
|
+
removeWtfpSubdir(commandsDir, path.join(targetDir, 'commands'), 'commands/wtfp/');
|
|
422
|
+
}
|
|
423
|
+
|
|
349
424
|
if (installed.hasWorkflows) {
|
|
350
425
|
removeDir(workflowsDir);
|
|
351
426
|
out.log(` ${c.red('-')} ${c.dim('write-the-f-paper/')}`);
|
|
352
427
|
}
|
|
353
428
|
|
|
354
429
|
if (installed.hasSkills) {
|
|
355
|
-
|
|
356
|
-
out.log(` ${c.red('-')} ${c.dim('skills/wtfp/')}`);
|
|
357
|
-
|
|
358
|
-
// Clean up empty skills dir
|
|
359
|
-
const parentSkillsDir = path.join(claudeDir, 'skills');
|
|
360
|
-
if (fs.existsSync(parentSkillsDir)) {
|
|
361
|
-
const remaining = fs.readdirSync(parentSkillsDir);
|
|
362
|
-
if (remaining.length === 0) {
|
|
363
|
-
fs.rmdirSync(parentSkillsDir);
|
|
364
|
-
out.log(` ${c.red('-')} ${c.dim('skills/')} ${c.dim('(empty)')}`);
|
|
365
|
-
}
|
|
366
|
-
}
|
|
430
|
+
removeWtfpSubdir(skillsDir, path.join(targetDir, 'skills'), 'skills/wtfp/');
|
|
367
431
|
}
|
|
368
432
|
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
433
|
+
// Remove agents/wtfp/ (added in v0.5.0)
|
|
434
|
+
if (fs.existsSync(agentsDir)) {
|
|
435
|
+
removeWtfpSubdir(agentsDir, path.join(targetDir, 'agents'), 'agents/wtfp/');
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
// Remove mcp/ (WTF-P research server)
|
|
439
|
+
if (fs.existsSync(mcpDir)) {
|
|
440
|
+
removeDir(mcpDir);
|
|
441
|
+
out.log(` ${c.red('-')} ${c.dim('mcp/')}`);
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
// Remove bin/ (WTF-P scripts installed to config dir)
|
|
445
|
+
if (fs.existsSync(binDir)) {
|
|
446
|
+
removeDir(binDir);
|
|
447
|
+
out.log(` ${c.red('-')} ${c.dim('bin/')}`);
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
// Remove only WTF-P's plugin.json, not the entire .claude-plugin/ dir
|
|
451
|
+
// (user may have their own plugin configs there)
|
|
452
|
+
if (fs.existsSync(wtfpPluginFile)) {
|
|
453
|
+
try {
|
|
454
|
+
const pluginData = JSON.parse(fs.readFileSync(wtfpPluginFile, 'utf8'));
|
|
455
|
+
if (pluginData.name === 'wtf-p' || pluginData.name === 'write-the-f-paper') {
|
|
456
|
+
fs.unlinkSync(wtfpPluginFile);
|
|
457
|
+
out.log(` ${c.red('-')} ${c.dim('.claude-plugin/plugin.json')}`);
|
|
458
|
+
|
|
459
|
+
// Only remove .claude-plugin/ if empty after our file is gone
|
|
460
|
+
try {
|
|
461
|
+
const remaining = fs.readdirSync(pluginDir);
|
|
462
|
+
if (remaining.length === 0) {
|
|
463
|
+
fs.rmdirSync(pluginDir);
|
|
464
|
+
out.log(` ${c.red('-')} ${c.dim('.claude-plugin/')} ${c.dim('(empty)')}`);
|
|
465
|
+
}
|
|
466
|
+
} catch { /* ignore */ }
|
|
467
|
+
}
|
|
468
|
+
} catch {
|
|
469
|
+
// Can't parse plugin.json — leave it alone for safety
|
|
470
|
+
}
|
|
372
471
|
}
|
|
373
472
|
|
|
374
473
|
// Remove version file
|
|
375
|
-
const versionFile = path.join(
|
|
474
|
+
const versionFile = path.join(targetDir, VERSION_FILE);
|
|
376
475
|
if (fs.existsSync(versionFile)) {
|
|
377
476
|
fs.unlinkSync(versionFile);
|
|
378
477
|
out.log(` ${c.red('-')} ${c.dim(VERSION_FILE)}`);
|
|
@@ -391,35 +490,48 @@ async function uninstall(isGlobal) {
|
|
|
391
490
|
}
|
|
392
491
|
|
|
393
492
|
out.log(`
|
|
394
|
-
${c.green('Done!')} WTF-P has been
|
|
493
|
+
${c.green('Done!')} WTF-P has been removed from ${vendorConfig.name}.
|
|
395
494
|
|
|
396
|
-
${c.dim('Your
|
|
495
|
+
${c.dim('Your personal config files were not touched.')}
|
|
397
496
|
|
|
398
|
-
To reinstall: ${c.cyan('npx wtf-p
|
|
497
|
+
To reinstall later: ${c.cyan('npx wtf-p')}
|
|
399
498
|
`);
|
|
400
499
|
}
|
|
401
500
|
|
|
402
501
|
/**
|
|
403
|
-
* Prompt for uninstall location
|
|
502
|
+
* Prompt for uninstall location - shows all runtimes with installation status
|
|
404
503
|
*/
|
|
405
504
|
async function promptLocation() {
|
|
406
505
|
const rl = createRL();
|
|
407
506
|
|
|
408
|
-
|
|
409
|
-
const
|
|
410
|
-
const
|
|
507
|
+
// Check installations for all runtimes
|
|
508
|
+
const runtimes = Object.keys(MANIFEST);
|
|
509
|
+
const installations = {};
|
|
510
|
+
let anyInstalled = false;
|
|
511
|
+
|
|
512
|
+
for (const runtime of runtimes) {
|
|
513
|
+
const targetDir = getVendorDir(runtime, null);
|
|
514
|
+
const installed = detectInstallation(targetDir);
|
|
515
|
+
const hasInstall = installed.hasCommands || installed.hasWorkflows || installed.hasSkills;
|
|
516
|
+
const count = installed.commandFiles.length + installed.workflowFiles.length + installed.skillFiles.length;
|
|
517
|
+
installations[runtime] = { installed, hasInstall, count, targetDir };
|
|
518
|
+
if (hasInstall) anyInstalled = true;
|
|
519
|
+
}
|
|
411
520
|
|
|
412
|
-
//
|
|
413
|
-
const
|
|
521
|
+
// Also check local .claude
|
|
522
|
+
const localPath = path.join(process.cwd(), '.claude');
|
|
414
523
|
const localInstalled = detectInstallation(localPath);
|
|
415
|
-
|
|
416
|
-
const hasGlobalInstall = globalInstalled.hasCommands || globalInstalled.hasWorkflows || globalInstalled.hasSkills;
|
|
417
524
|
const hasLocalInstall = localInstalled.hasCommands || localInstalled.hasWorkflows || localInstalled.hasSkills;
|
|
525
|
+
const localCount = localInstalled.commandFiles.length + localInstalled.workflowFiles.length + localInstalled.skillFiles.length;
|
|
526
|
+
if (hasLocalInstall) anyInstalled = true;
|
|
418
527
|
|
|
419
|
-
if (!
|
|
528
|
+
if (!anyInstalled) {
|
|
420
529
|
out.log(` ${c.yellow('No WTF-P installation found.')}\n`);
|
|
421
530
|
out.log(` Checked:`);
|
|
422
|
-
|
|
531
|
+
for (const runtime of runtimes) {
|
|
532
|
+
const label = getPathLabel(installations[runtime].targetDir, true);
|
|
533
|
+
out.log(` ${c.dim(label)}`);
|
|
534
|
+
}
|
|
423
535
|
out.log(` ${c.dim('./.claude')}\n`);
|
|
424
536
|
rl.close();
|
|
425
537
|
return;
|
|
@@ -427,38 +539,71 @@ async function promptLocation() {
|
|
|
427
539
|
|
|
428
540
|
out.log(` ${c.yellow('Where would you like to uninstall from?')}\n`);
|
|
429
541
|
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
542
|
+
let optionNum = 1;
|
|
543
|
+
const options = [];
|
|
544
|
+
|
|
545
|
+
// Show runtime options
|
|
546
|
+
for (const runtime of runtimes) {
|
|
547
|
+
const { hasInstall, count, targetDir } = installations[runtime];
|
|
548
|
+
const label = getPathLabel(targetDir, true);
|
|
549
|
+
const vendorName = MANIFEST[runtime].name;
|
|
550
|
+
|
|
551
|
+
if (hasInstall) {
|
|
552
|
+
out.log(` ${c.cyan(optionNum + ')')} ${vendorName} ${c.dim('(' + label + ')')} - ${count} files`);
|
|
553
|
+
options.push({ num: optionNum, runtime });
|
|
554
|
+
} else {
|
|
555
|
+
out.log(` ${c.dim(optionNum + ') ' + vendorName + ' (' + label + ') - not installed')}`);
|
|
556
|
+
}
|
|
557
|
+
optionNum++;
|
|
435
558
|
}
|
|
436
559
|
|
|
560
|
+
// Show local option
|
|
437
561
|
if (hasLocalInstall) {
|
|
438
|
-
|
|
439
|
-
|
|
562
|
+
out.log(` ${c.cyan(optionNum + ')')} Local ${c.dim('(./.claude)')} - ${localCount} files`);
|
|
563
|
+
options.push({ num: optionNum, runtime: 'claude-local' });
|
|
440
564
|
} else {
|
|
441
|
-
out.log(` ${c.dim('
|
|
565
|
+
out.log(` ${c.dim(optionNum + ') Local (./.claude) - not installed')}`);
|
|
442
566
|
}
|
|
567
|
+
optionNum++;
|
|
568
|
+
|
|
569
|
+
// Show "all" option if multiple installations
|
|
570
|
+
const installedCount = options.length;
|
|
571
|
+
if (installedCount > 1) {
|
|
572
|
+
out.log(` ${c.cyan(optionNum + ')')} All installed runtimes`);
|
|
573
|
+
options.push({ num: optionNum, runtime: 'all-installed' });
|
|
574
|
+
}
|
|
575
|
+
|
|
443
576
|
out.log('');
|
|
444
577
|
|
|
445
578
|
const answer = await prompt(rl, ` Choice: `);
|
|
446
579
|
rl.close();
|
|
447
580
|
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
await uninstall(false);
|
|
452
|
-
} else {
|
|
581
|
+
const selected = options.find(o => o.num === parseInt(answer, 10));
|
|
582
|
+
|
|
583
|
+
if (!selected) {
|
|
453
584
|
out.log(`\n ${c.yellow('Invalid choice or no installation at that location.')}\n`);
|
|
585
|
+
return;
|
|
586
|
+
}
|
|
587
|
+
|
|
588
|
+
if (selected.runtime === 'all-installed') {
|
|
589
|
+
// Uninstall from all installed runtimes
|
|
590
|
+
for (const opt of options) {
|
|
591
|
+
if (opt.runtime !== 'all-installed') {
|
|
592
|
+
await uninstall(opt.runtime);
|
|
593
|
+
}
|
|
594
|
+
}
|
|
595
|
+
} else {
|
|
596
|
+
await uninstall(selected.runtime);
|
|
454
597
|
}
|
|
455
598
|
}
|
|
456
599
|
|
|
457
600
|
// ============ Main ============
|
|
458
601
|
|
|
459
602
|
async function main() {
|
|
460
|
-
|
|
461
|
-
|
|
603
|
+
// Validate conflicting flags
|
|
604
|
+
const runtimeFlags = [hasGlobal, hasLocal, hasClaude, hasGemini, hasOpenCode, hasAll].filter(Boolean).length;
|
|
605
|
+
if (runtimeFlags > 1 && !hasAll) {
|
|
606
|
+
out.error('Pick one tool at a time, or use --all to uninstall from everything');
|
|
462
607
|
process.exit(1);
|
|
463
608
|
}
|
|
464
609
|
if (explicitConfigDir && hasLocal) {
|
|
@@ -466,11 +611,25 @@ async function main() {
|
|
|
466
611
|
process.exit(1);
|
|
467
612
|
}
|
|
468
613
|
|
|
469
|
-
|
|
470
|
-
|
|
614
|
+
// Handle --all first
|
|
615
|
+
if (hasAll) {
|
|
616
|
+
for (const runtime of Object.keys(MANIFEST)) {
|
|
617
|
+
await uninstall(runtime);
|
|
618
|
+
}
|
|
619
|
+
return;
|
|
620
|
+
}
|
|
621
|
+
|
|
622
|
+
// Handle specific runtime flags
|
|
623
|
+
if (hasClaude || hasGlobal) {
|
|
624
|
+
await uninstall('claude');
|
|
625
|
+
} else if (hasGemini) {
|
|
626
|
+
await uninstall('gemini');
|
|
627
|
+
} else if (hasOpenCode) {
|
|
628
|
+
await uninstall('opencode');
|
|
471
629
|
} else if (hasLocal) {
|
|
472
|
-
await uninstall(
|
|
630
|
+
await uninstall('claude-local');
|
|
473
631
|
} else {
|
|
632
|
+
// Interactive mode
|
|
474
633
|
await promptLocation();
|
|
475
634
|
}
|
|
476
635
|
}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
# Agent Model Matrix
|
|
2
|
+
|
|
3
|
+
Model assignments per agent across quality/balanced/budget profiles. Resolved at runtime from `.planning/config.json` `model_profile` field.
|
|
4
|
+
|
|
5
|
+
## Lookup Table
|
|
6
|
+
|
|
7
|
+
| Agent | Role | quality | balanced | budget |
|
|
8
|
+
|-------|------|---------|----------|--------|
|
|
9
|
+
| section-planner | Creates PLAN.md with argument decomposition, word budgets, citation planning | opus | opus | sonnet |
|
|
10
|
+
| plan-checker | Pre-write validation of plans (7 dimensions) | sonnet | sonnet | haiku |
|
|
11
|
+
| section-writer | Executes PLAN.md, writes prose, atomic commits | opus | sonnet | sonnet |
|
|
12
|
+
| argument-verifier | Goal-backward verification of written sections | sonnet | sonnet | haiku |
|
|
13
|
+
| section-reviewer | 3-layer verification with reviewer personas | opus | sonnet | haiku |
|
|
14
|
+
| prose-polisher | De-robotize text, voice adjustment, sentence variety | opus | sonnet | haiku |
|
|
15
|
+
| research-synthesizer | Literature discovery, gap analysis, positioning | opus | sonnet | haiku |
|
|
16
|
+
| citation-expert | Search papers, manage BibTeX, identify gaps | sonnet | sonnet | haiku |
|
|
17
|
+
| citation-formatter | BibTeX validation, formatting, deduplication | sonnet | haiku | haiku |
|
|
18
|
+
| citation-retriever | Literature discovery, BibTeX generation | sonnet | haiku | haiku |
|
|
19
|
+
| coherence-checker | Cross-section coherence, argument flow, terminology consistency | sonnet | sonnet | haiku |
|
|
20
|
+
| outliner | Generates outline.md, argument-map.md, narrative-arc.md from PROJECT.md | opus | sonnet | sonnet |
|
|
21
|
+
|
|
22
|
+
## Resolution Pattern
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
MODEL_PROFILE=$(cat .planning/config.json 2>/dev/null | \
|
|
26
|
+
grep -o '"model_profile"[[:space:]]*:[[:space:]]*"[^"]*"' | \
|
|
27
|
+
grep -o '"[^"]*"$' | tr -d '"' || echo "balanced")
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
Default: `balanced` when config missing or field absent.
|
|
31
|
+
|
|
32
|
+
## Orchestrator → Agent Mapping
|
|
33
|
+
|
|
34
|
+
| Orchestrator Command | Primary Agent | Quality Agent |
|
|
35
|
+
|---------------------|---------------|---------------|
|
|
36
|
+
| /wtfp:plan-section | section-planner | plan-checker |
|
|
37
|
+
| /wtfp:write-section | section-writer | argument-verifier |
|
|
38
|
+
| /wtfp:review-section | section-reviewer | — |
|
|
39
|
+
| /wtfp:polish-prose | prose-polisher | — |
|
|
40
|
+
| /wtfp:research-gap | research-synthesizer | — |
|
|
41
|
+
| /wtfp:analyze-bib | citation-expert | — |
|
|
42
|
+
| /wtfp:check-refs | citation-formatter | — |
|
|
43
|
+
| /wtfp:execute-outline | outliner | coherence-checker |
|
|
44
|
+
| /wtfp:create-outline | outliner | — |
|
|
45
|
+
|
|
46
|
+
## Profile Selection Guide
|
|
47
|
+
|
|
48
|
+
**quality** — Use for final drafts, critical sections (introduction, discussion), submission-ready work. Higher token cost, maximum reasoning depth.
|
|
49
|
+
|
|
50
|
+
**balanced** — Default. Good for most drafting, planning, and revision work. Planner stays at opus for argument quality; writer uses sonnet for cost efficiency.
|
|
51
|
+
|
|
52
|
+
**budget** — Use for iterative rough drafts, boilerplate sections (acknowledgments, author contributions), or when iterating rapidly. Significantly lower cost.
|
|
53
|
+
|
|
54
|
+
## Setting Profile
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
# Via config.json
|
|
58
|
+
cat .planning/config.json | jq '.model_profile = "quality"' > tmp && mv tmp .planning/config.json
|
|
59
|
+
|
|
60
|
+
# Via command
|
|
61
|
+
/wtfp:settings → model_profile → quality|balanced|budget
|
|
62
|
+
```
|