wtf-p 0.2.0 → 0.4.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 +24 -2
- package/bin/commands/doctor.js +100 -0
- package/bin/commands/install-logic.js +231 -0
- package/bin/commands/list.js +88 -0
- package/bin/commands/status.js +85 -0
- package/bin/commands/update.js +50 -0
- package/bin/install.js +78 -629
- 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/citation-fetcher.js +299 -0
- package/bin/lib/citation-ranker.js +133 -0
- package/bin/lib/manifest.js +59 -0
- package/bin/lib/scholar-lookup.js +188 -0
- package/bin/lib/semantic-scholar.js +184 -0
- package/bin/lib/utils.js +37 -17
- package/bin/lib/wcn-compiler.js +226 -0
- package/bin/uninstall.js +51 -17
- package/core/write-the-f-paper/templates/posters/basic.md +34 -0
- package/core/write-the-f-paper/templates/slides/basic.md +31 -0
- package/package.json +12 -4
- package/vendors/claude/.claude-plugin/plugin.json +12 -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/citation-retriever.md +31 -0
- package/{commands → vendors/claude/commands}/wtfp/analyze-bib.md +41 -52
- package/{commands → vendors/claude/commands}/wtfp/check-refs.md +11 -9
- package/vendors/claude/commands/wtfp/create-poster.md +42 -0
- package/vendors/claude/commands/wtfp/create-slides.md +41 -0
- package/{commands → vendors/claude/commands}/wtfp/help.md +3 -0
- package/{commands → vendors/claude/commands}/wtfp/new-paper.md +42 -81
- package/{commands → vendors/claude/commands}/wtfp/research-gap.md +3 -4
- package/vendors/claude/mcp/research-server/package.json +13 -0
- package/vendors/claude/mcp/research-server/src/index.js +133 -0
- package/vendors/claude/skills/wtfp/echarts/SKILL.md +47 -0
- package/vendors/claude/skills/wtfp/marp/SKILL.md +49 -0
- /package/{write-the-f-paper → core/write-the-f-paper}/references/checkpoints.md +0 -0
- /package/{write-the-f-paper → core/write-the-f-paper}/references/continuation-format.md +0 -0
- /package/{write-the-f-paper → core/write-the-f-paper}/references/git-integration.md +0 -0
- /package/{write-the-f-paper → core/write-the-f-paper}/references/github-contrib.md +0 -0
- /package/{write-the-f-paper → core/write-the-f-paper}/references/imrad-structure.md +0 -0
- /package/{write-the-f-paper → core/write-the-f-paper}/references/length-estimation.md +0 -0
- /package/{write-the-f-paper → core/write-the-f-paper}/references/plan-format.md +0 -0
- /package/{write-the-f-paper → core/write-the-f-paper}/references/principles.md +0 -0
- /package/{write-the-f-paper → core/write-the-f-paper}/references/questioning.md +0 -0
- /package/{write-the-f-paper → core/write-the-f-paper}/references/research-pitfalls.md +0 -0
- /package/{write-the-f-paper → core/write-the-f-paper}/templates/config.json +0 -0
- /package/{write-the-f-paper → core/write-the-f-paper}/templates/context.md +0 -0
- /package/{write-the-f-paper → core/write-the-f-paper}/templates/continue-here.md +0 -0
- /package/{write-the-f-paper → core/write-the-f-paper}/templates/data-inventory.md +0 -0
- /package/{write-the-f-paper → core/write-the-f-paper}/templates/discovery.md +0 -0
- /package/{write-the-f-paper → core/write-the-f-paper}/templates/issues.md +0 -0
- /package/{write-the-f-paper → core/write-the-f-paper}/templates/manuscript.md +0 -0
- /package/{write-the-f-paper → core/write-the-f-paper}/templates/narrative-arc.md +0 -0
- /package/{write-the-f-paper → core/write-the-f-paper}/templates/outline.md +0 -0
- /package/{write-the-f-paper → core/write-the-f-paper}/templates/phase-prompt.md +0 -0
- /package/{write-the-f-paper → core/write-the-f-paper}/templates/prior-drafts.md +0 -0
- /package/{write-the-f-paper → core/write-the-f-paper}/templates/project-context/argument-structure.md +0 -0
- /package/{write-the-f-paper → core/write-the-f-paper}/templates/project-context/bibliography.md +0 -0
- /package/{write-the-f-paper → core/write-the-f-paper}/templates/project-context/gaps.md +0 -0
- /package/{write-the-f-paper → core/write-the-f-paper}/templates/project-context/imrad.md +0 -0
- /package/{write-the-f-paper → core/write-the-f-paper}/templates/project-context/peer-review.md +0 -0
- /package/{write-the-f-paper → core/write-the-f-paper}/templates/project-context/style-guide.md +0 -0
- /package/{write-the-f-paper → core/write-the-f-paper}/templates/project-context/tools.md +0 -0
- /package/{write-the-f-paper → core/write-the-f-paper}/templates/project.md +0 -0
- /package/{write-the-f-paper → core/write-the-f-paper}/templates/research.md +0 -0
- /package/{write-the-f-paper → core/write-the-f-paper}/templates/review-comments.md +0 -0
- /package/{write-the-f-paper → core/write-the-f-paper}/templates/revision-issues.md +0 -0
- /package/{write-the-f-paper → core/write-the-f-paper}/templates/roadmap.md +0 -0
- /package/{write-the-f-paper → core/write-the-f-paper}/templates/section-archive.md +0 -0
- /package/{write-the-f-paper → core/write-the-f-paper}/templates/section-context.md +0 -0
- /package/{write-the-f-paper → core/write-the-f-paper}/templates/section.md +0 -0
- /package/{write-the-f-paper → core/write-the-f-paper}/templates/state.md +0 -0
- /package/{write-the-f-paper → core/write-the-f-paper}/templates/summary.md +0 -0
- /package/{write-the-f-paper → core/write-the-f-paper}/venues/acm-cs.yaml +0 -0
- /package/{write-the-f-paper → core/write-the-f-paper}/venues/arxiv-ml.yaml +0 -0
- /package/{write-the-f-paper → core/write-the-f-paper}/venues/ieee-cs.yaml +0 -0
- /package/{write-the-f-paper → core/write-the-f-paper}/venues/nature.yaml +0 -0
- /package/{write-the-f-paper → core/write-the-f-paper}/venues/thesis-chapter.yaml +0 -0
- /package/{write-the-f-paper → core/write-the-f-paper}/workflows/create-outline.md +0 -0
- /package/{write-the-f-paper → core/write-the-f-paper}/workflows/create-outline.wcn.md +0 -0
- /package/{write-the-f-paper → core/write-the-f-paper}/workflows/discuss-section.md +0 -0
- /package/{write-the-f-paper → core/write-the-f-paper}/workflows/discuss-section.wcn.md +0 -0
- /package/{write-the-f-paper → core/write-the-f-paper}/workflows/execute-section.md +0 -0
- /package/{write-the-f-paper → core/write-the-f-paper}/workflows/execute-section.wcn.md +0 -0
- /package/{write-the-f-paper → core/write-the-f-paper}/workflows/list-assumptions.md +0 -0
- /package/{write-the-f-paper → core/write-the-f-paper}/workflows/list-assumptions.wcn.md +0 -0
- /package/{write-the-f-paper → core/write-the-f-paper}/workflows/lit-review-phase.md +0 -0
- /package/{write-the-f-paper → core/write-the-f-paper}/workflows/lit-review-phase.wcn.md +0 -0
- /package/{write-the-f-paper → core/write-the-f-paper}/workflows/map-project.md +0 -0
- /package/{write-the-f-paper → core/write-the-f-paper}/workflows/map-project.wcn.md +0 -0
- /package/{write-the-f-paper → core/write-the-f-paper}/workflows/plan-section.md +0 -0
- /package/{write-the-f-paper → core/write-the-f-paper}/workflows/plan-section.wcn.md +0 -0
- /package/{write-the-f-paper → core/write-the-f-paper}/workflows/research-gap.md +0 -0
- /package/{write-the-f-paper → core/write-the-f-paper}/workflows/research-gap.wcn.md +0 -0
- /package/{write-the-f-paper → core/write-the-f-paper}/workflows/resume-paper.md +0 -0
- /package/{write-the-f-paper → core/write-the-f-paper}/workflows/resume-paper.wcn.md +0 -0
- /package/{write-the-f-paper → core/write-the-f-paper}/workflows/review-section.md +0 -0
- /package/{write-the-f-paper → core/write-the-f-paper}/workflows/review-section.wcn.md +0 -0
- /package/{write-the-f-paper → core/write-the-f-paper}/workflows/submit-draft.md +0 -0
- /package/{write-the-f-paper → core/write-the-f-paper}/workflows/submit-draft.wcn.md +0 -0
- /package/{write-the-f-paper → core/write-the-f-paper}/workflows/transition.md +0 -0
- /package/{write-the-f-paper → core/write-the-f-paper}/workflows/transition.wcn.md +0 -0
- /package/{commands → vendors/claude/commands}/wtfp/contribute.md +0 -0
- /package/{commands → vendors/claude/commands}/wtfp/create-outline.md +0 -0
- /package/{commands → vendors/claude/commands}/wtfp/discuss-section.md +0 -0
- /package/{commands → vendors/claude/commands}/wtfp/export-latex.md +0 -0
- /package/{commands → vendors/claude/commands}/wtfp/insert-section.md +0 -0
- /package/{commands → vendors/claude/commands}/wtfp/list-assumptions.md +0 -0
- /package/{commands → vendors/claude/commands}/wtfp/map-project.md +0 -0
- /package/{commands → vendors/claude/commands}/wtfp/pause-writing.md +0 -0
- /package/{commands → vendors/claude/commands}/wtfp/plan-revision.md +0 -0
- /package/{commands → vendors/claude/commands}/wtfp/plan-section.md +0 -0
- /package/{commands → vendors/claude/commands}/wtfp/polish-prose.md +0 -0
- /package/{commands → vendors/claude/commands}/wtfp/progress.md +0 -0
- /package/{commands → vendors/claude/commands}/wtfp/remove-section.md +0 -0
- /package/{commands → vendors/claude/commands}/wtfp/report-bug.md +0 -0
- /package/{commands → vendors/claude/commands}/wtfp/request-feature.md +0 -0
- /package/{commands → vendors/claude/commands}/wtfp/resume-writing.md +0 -0
- /package/{commands → vendors/claude/commands}/wtfp/review-section.md +0 -0
- /package/{commands → vendors/claude/commands}/wtfp/submit-milestone.md +0 -0
- /package/{commands → vendors/claude/commands}/wtfp/write-section.md +0 -0
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WCN Compiler (Workflow Compression Notation)
|
|
3
|
+
* A robust, state-machine based compiler for converting Verbose Markdown to Compressed WCN.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
const FLUFF_PATTERNS = [
|
|
7
|
+
/This ensures[^.]*\./g,
|
|
8
|
+
/This is important[^.]*\./g,
|
|
9
|
+
/Note that[^.]*\./g,
|
|
10
|
+
/Keep in mind[^.]*\./g,
|
|
11
|
+
/Remember that[^.]*\./g,
|
|
12
|
+
/As mentioned[^.]*\./g,
|
|
13
|
+
/It is important to[^.]*\./g,
|
|
14
|
+
];
|
|
15
|
+
|
|
16
|
+
class WCNCompiler {
|
|
17
|
+
constructor() {
|
|
18
|
+
this.lines = [];
|
|
19
|
+
this.output = [];
|
|
20
|
+
this.state = 'ROOT'; // ROOT, STEP, BASH
|
|
21
|
+
this.context = {};
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
compile(markdown) {
|
|
25
|
+
// 1. Pre-process: Remove fluff and normalize
|
|
26
|
+
let cleanMd = markdown;
|
|
27
|
+
FLUFF_PATTERNS.forEach(p => cleanMd = cleanMd.replace(p, ''));
|
|
28
|
+
|
|
29
|
+
this.lines = cleanMd.split('\n');
|
|
30
|
+
this.output = [];
|
|
31
|
+
this.state = 'ROOT';
|
|
32
|
+
|
|
33
|
+
// 2. Parse Line by Line
|
|
34
|
+
for (let i = 0; i < this.lines.length; i++) {
|
|
35
|
+
const line = this.lines[i].trim();
|
|
36
|
+
this.processLine(line, i);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// 3. Post-process: Clean up excessive newlines
|
|
40
|
+
return this.output.join('\n').replace(/\n{3,}/g, '\n\n').trim();
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
processLine(line, index) {
|
|
44
|
+
// Handle State Transitions
|
|
45
|
+
if (this.state === 'ROOT') {
|
|
46
|
+
if (line.startsWith('<step')) {
|
|
47
|
+
this.enterStep(line);
|
|
48
|
+
} else if (line.startsWith('<context>')) {
|
|
49
|
+
this.enterContext();
|
|
50
|
+
} else if (line.startsWith('**If') && line.endsWith(':**')) {
|
|
51
|
+
// Handle standalone conditionals (outside steps, rare but possible)
|
|
52
|
+
this.parseConditional(line, index);
|
|
53
|
+
} else if (line.startsWith('**Route')) {
|
|
54
|
+
this.parseRoute(line, index);
|
|
55
|
+
} else if (!line.startsWith('</')) {
|
|
56
|
+
// Pass through other content, but minimal
|
|
57
|
+
// We generally skip prose outside steps in WCN unless it's structural
|
|
58
|
+
if (line.startsWith('#') || line.startsWith('---')) {
|
|
59
|
+
this.output.push(line);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
} else if (this.state === 'STEP') {
|
|
63
|
+
if (line.startsWith('</step>')) {
|
|
64
|
+
this.exitStep();
|
|
65
|
+
} else if (line.startsWith('```bash')) {
|
|
66
|
+
this.state = 'BASH';
|
|
67
|
+
} else if (line.startsWith('**If') && line.endsWith(':**')) {
|
|
68
|
+
this.parseConditional(line, index);
|
|
69
|
+
} else if (line.toLowerCase().startsWith('parse and internalize:')) {
|
|
70
|
+
this.parseParseBlock(index);
|
|
71
|
+
} else if (line.trim().startsWith('- ') || line.trim().startsWith('* ')) {
|
|
72
|
+
// Capture bullet points as instructions
|
|
73
|
+
this.output.push(line.trim());
|
|
74
|
+
} else if (line.trim().startsWith('**') && !line.includes('If')) {
|
|
75
|
+
// Capture bold instructions
|
|
76
|
+
this.output.push(line.trim());
|
|
77
|
+
}
|
|
78
|
+
} else if (this.state === 'BASH') {
|
|
79
|
+
if (line.startsWith('```')) {
|
|
80
|
+
this.state = 'STEP';
|
|
81
|
+
} else {
|
|
82
|
+
// Capture bash command (first line usually sufficient for WCN)
|
|
83
|
+
if (line && !line.startsWith('#')) {
|
|
84
|
+
this.output.push(`RUN: ${line}`);
|
|
85
|
+
// Skip rest of bash block for WCN brevity?
|
|
86
|
+
// Current logic captures all commands. Let's capture all.
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
enterStep(line) {
|
|
93
|
+
this.state = 'STEP';
|
|
94
|
+
// Parse attributes: name="foo" priority="bar"
|
|
95
|
+
const nameMatch = line.match(/name="([^"]+)"/);
|
|
96
|
+
const priorityMatch = line.match(/priority="([^"]+)"/);
|
|
97
|
+
|
|
98
|
+
const name = nameMatch ? nameMatch[1] : 'unknown';
|
|
99
|
+
const pAttr = priorityMatch ? ` p=${priorityMatch[1] === 'first' ? '1' : priorityMatch[1]}` : '';
|
|
100
|
+
|
|
101
|
+
this.output.push(`[step:${name}${pAttr}]`);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
exitStep() {
|
|
105
|
+
this.output.push('[/step]');
|
|
106
|
+
this.state = 'ROOT';
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
enterContext() {
|
|
110
|
+
// Context is usually multiline, handled by looking ahead or buffering
|
|
111
|
+
// For simplicity, we'll scan ahead here since we have full lines access
|
|
112
|
+
// But sticking to line-by-line:
|
|
113
|
+
// Actually, Regex is better for Context blocks as they are simple <context>...</context>
|
|
114
|
+
// Let's defer this to a specialized Regex pass *before* line processing?
|
|
115
|
+
// Or just look ahead now.
|
|
116
|
+
// Let's skip for now and rely on a pre-pass replacement for Context, similar to current tool.
|
|
117
|
+
// Why? Because Context is global metadata, usually at top.
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
parseConditional(line, index) {
|
|
121
|
+
// **If mode="yolo":**
|
|
122
|
+
const condition = line.replace(/\*\*If\s+/, '').replace(/:\*\*/, '').trim().replace(/["']/g, '');
|
|
123
|
+
|
|
124
|
+
// Look ahead for the action
|
|
125
|
+
// Usually the next line or the line after
|
|
126
|
+
let action = '';
|
|
127
|
+
for (let i = 1; i < 5; i++) {
|
|
128
|
+
const next = this.lines[index + i];
|
|
129
|
+
if (next && next.trim()) {
|
|
130
|
+
action = next.trim();
|
|
131
|
+
break;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
if (action) {
|
|
136
|
+
// Simplify action text
|
|
137
|
+
if (action.length > 50) action = action.substring(0, 47) + '...';
|
|
138
|
+
this.output.push(`IF ${condition} → ${action}`);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
parseParseBlock(index) {
|
|
143
|
+
// Parse and internalize:
|
|
144
|
+
// - Item 1
|
|
145
|
+
// - Item 2
|
|
146
|
+
const fields = [];
|
|
147
|
+
for (let i = 1; i < 10; i++) {
|
|
148
|
+
const next = this.lines[index + i];
|
|
149
|
+
if (!next || (!next.trim().startsWith('-') && !next.trim().startsWith('*'))) break;
|
|
150
|
+
|
|
151
|
+
const field = next.replace(/^[-*]\s+/, '').trim().split(' ')[0].toLowerCase().replace(/\s+/g, '_');
|
|
152
|
+
fields.push(field);
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
if (fields.length > 0) {
|
|
156
|
+
this.output.push(`PARSE: ${fields.join(', ')}`);
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
parseRoute(line, index) {
|
|
161
|
+
// **Route A: Title**
|
|
162
|
+
const match = line.match(/\*\*Route\s+([A-Z]):\s*([^*]+)\*\*/);
|
|
163
|
+
if (!match) return;
|
|
164
|
+
|
|
165
|
+
// We need to buffer the route table
|
|
166
|
+
// This is hard to do line-by-line without buffering.
|
|
167
|
+
// Let's assume we handle Routes via Regex pre-pass like the original,
|
|
168
|
+
// OR we detect the start of a route block and switch state.
|
|
169
|
+
// Given the complexity, let's stick to the Regex for Routes/Modes/Context
|
|
170
|
+
// and use State Machine for the detailed STEP logic which is where the fragility usually is.
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* Hybrid Compiler:
|
|
176
|
+
* 1. Uses Regex for high-level blocks (Context, Routes, Modes)
|
|
177
|
+
* 2. Uses State Machine for Steps (the most complex part)
|
|
178
|
+
*/
|
|
179
|
+
function compile(markdown) {
|
|
180
|
+
let result = markdown;
|
|
181
|
+
|
|
182
|
+
// 1. Remove fluff
|
|
183
|
+
FLUFF_PATTERNS.forEach(p => result = result.replace(p, ''));
|
|
184
|
+
|
|
185
|
+
// 2. Compress Context (Regex is fine here)
|
|
186
|
+
result = result.replace(/<context>\s*([\s\S]*?)<\/context>/g, (match, content) => {
|
|
187
|
+
const files = content.match(/@[^\s\n]+/g) || [];
|
|
188
|
+
if (files.length === 0) return '';
|
|
189
|
+
const simplified = files.map(f => f.replace('@.planning/', ''));
|
|
190
|
+
return `@context{${simplified.join(',')}}`;
|
|
191
|
+
});
|
|
192
|
+
|
|
193
|
+
// 3. Compress Routes (Regex is fine here)
|
|
194
|
+
const routes = [];
|
|
195
|
+
result = result.replace(/\*\*Route\s+([A-Z]):\s*([^*]+)\*\*\s*([\s\S]*?)(?=\*\*Route|<step|$)/g, (match, id, title, content) => {
|
|
196
|
+
// Extract next step logic
|
|
197
|
+
const nextMatch = content.match(/\`\/wtfp:([^`]+)\`/);
|
|
198
|
+
const next = nextMatch ? `/wtfp:${nextMatch[1]}` : 'continue';
|
|
199
|
+
routes.push(` ${title.trim().toLowerCase().replace(/\s+/g, '_')} → "${title.trim()}" → ${next}`);
|
|
200
|
+
return '';
|
|
201
|
+
});
|
|
202
|
+
if (routes.length > 0) {
|
|
203
|
+
result = result + '\n\nROUTE{condition → output → next}:\n' + routes.join('\n');
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
// 4. Compress Modes (Regex is fine here)
|
|
207
|
+
const modes = [];
|
|
208
|
+
result = result.replace(/\*\*If\s+mode="([^"]+)":\*\*\s*\n((?:[-*]\s+[^\n]+\n?)+)/g, (match, mode, items) => {
|
|
209
|
+
const itemList = items.split('\n').filter(l => l.trim()).map(l => l.replace(/^[-*]\s+/, '').trim());
|
|
210
|
+
modes.push(` ${mode} | ${itemList[0] || ''}`);
|
|
211
|
+
return '';
|
|
212
|
+
});
|
|
213
|
+
if (modes.length > 0) {
|
|
214
|
+
result = 'MODE{name,action}:\n' + modes.join('\n') + '\n\n' + result;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
// 5. Compress Steps using State Machine (The Core Logic)
|
|
218
|
+
const compiler = new WCNCompiler();
|
|
219
|
+
// We only run the compiler on the text that remains (which should be mostly steps)
|
|
220
|
+
// But wait, the compiler expects full text to find steps.
|
|
221
|
+
// Let's pass the text to the compiler, but the compiler only outputs Step blocks and structural elements.
|
|
222
|
+
|
|
223
|
+
return compiler.compile(result);
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
module.exports = { compile, WCNCompiler };
|
package/bin/uninstall.js
CHANGED
|
@@ -102,7 +102,9 @@ if (hasHelp) {
|
|
|
102
102
|
|
|
103
103
|
${c.yellow('What gets removed:')}
|
|
104
104
|
${c.dim('commands/wtfp/')} - WTF-P slash commands
|
|
105
|
-
${c.dim('write-the-f-paper/')} - WTF-P
|
|
105
|
+
${c.dim('write-the-f-paper/')} - WTF-P workflows
|
|
106
|
+
${c.dim('skills/wtfp/')} - WTF-P skills
|
|
107
|
+
${c.dim('.claude-plugin/')} - Plugin manifest
|
|
106
108
|
${c.dim('.wtfp-version')} - Version tracking file
|
|
107
109
|
|
|
108
110
|
${c.yellow('What stays intact:')}
|
|
@@ -200,9 +202,9 @@ async function uninstall(isGlobal) {
|
|
|
200
202
|
|
|
201
203
|
// Detect installation
|
|
202
204
|
const installed = detectInstallation(claudeDir);
|
|
203
|
-
const totalFiles = installed.commandFiles.length + installed.skillFiles.length;
|
|
205
|
+
const totalFiles = installed.commandFiles.length + installed.workflowFiles.length + installed.skillFiles.length;
|
|
204
206
|
|
|
205
|
-
if (!installed.hasCommands && !installed.
|
|
207
|
+
if (!installed.hasCommands && !installed.hasWorkflows && !installed.hasSkills) {
|
|
206
208
|
out.log(` ${c.yellow('No WTF-P installation found in ' + locationLabel)}\n`);
|
|
207
209
|
|
|
208
210
|
// Check for backups if requested
|
|
@@ -252,13 +254,21 @@ async function uninstall(isGlobal) {
|
|
|
252
254
|
out.log(` ${c.yellow('Found WTF-P installation:')}\n`);
|
|
253
255
|
|
|
254
256
|
const commandsDir = path.join(claudeDir, 'commands', 'wtfp');
|
|
255
|
-
const
|
|
257
|
+
const workflowsDir = path.join(claudeDir, 'write-the-f-paper');
|
|
258
|
+
const skillsDir = path.join(claudeDir, 'skills', 'wtfp');
|
|
259
|
+
const pluginDir = path.join(claudeDir, '.claude-plugin');
|
|
256
260
|
|
|
257
261
|
if (installed.hasCommands) {
|
|
258
262
|
out.log(` ${c.cyan('commands/wtfp/')} (${installed.commandFiles.length} files)`);
|
|
259
263
|
}
|
|
260
|
-
if (installed.
|
|
261
|
-
out.log(` ${c.cyan('write-the-f-paper/')} (${installed.
|
|
264
|
+
if (installed.hasWorkflows) {
|
|
265
|
+
out.log(` ${c.cyan('write-the-f-paper/')} (${installed.workflowFiles.length} files)`);
|
|
266
|
+
}
|
|
267
|
+
if (installed.hasSkills) {
|
|
268
|
+
out.log(` ${c.cyan('skills/wtfp/')} (${installed.skillFiles.length} files)`);
|
|
269
|
+
}
|
|
270
|
+
if (fs.existsSync(pluginDir)) {
|
|
271
|
+
out.log(` ${c.cyan('.claude-plugin/')} (manifest)`);
|
|
262
272
|
}
|
|
263
273
|
if (installed.version) {
|
|
264
274
|
out.log(` ${c.cyan(VERSION_FILE)} (version tracking)`);
|
|
@@ -304,12 +314,16 @@ async function uninstall(isGlobal) {
|
|
|
304
314
|
fs.mkdirSync(backupDir, { recursive: true });
|
|
305
315
|
|
|
306
316
|
if (installed.hasCommands) {
|
|
307
|
-
|
|
308
|
-
|
|
317
|
+
copyDir(commandsDir, path.join(backupDir, 'commands', 'wtfp'));
|
|
318
|
+
}
|
|
319
|
+
if (installed.hasWorkflows) {
|
|
320
|
+
copyDir(workflowsDir, path.join(backupDir, 'write-the-f-paper'));
|
|
309
321
|
}
|
|
310
|
-
if (installed.
|
|
311
|
-
|
|
312
|
-
|
|
322
|
+
if (installed.hasSkills) {
|
|
323
|
+
copyDir(skillsDir, path.join(backupDir, 'skills', 'wtfp'));
|
|
324
|
+
}
|
|
325
|
+
if (fs.existsSync(pluginDir)) {
|
|
326
|
+
copyDir(pluginDir, path.join(backupDir, '.claude-plugin'));
|
|
313
327
|
}
|
|
314
328
|
|
|
315
329
|
const backupLabel = backupDir.replace(os.homedir(), '~').replace(process.cwd(), '.');
|
|
@@ -332,11 +346,31 @@ async function uninstall(isGlobal) {
|
|
|
332
346
|
}
|
|
333
347
|
}
|
|
334
348
|
|
|
335
|
-
if (installed.
|
|
336
|
-
removeDir(
|
|
349
|
+
if (installed.hasWorkflows) {
|
|
350
|
+
removeDir(workflowsDir);
|
|
337
351
|
out.log(` ${c.red('-')} ${c.dim('write-the-f-paper/')}`);
|
|
338
352
|
}
|
|
339
353
|
|
|
354
|
+
if (installed.hasSkills) {
|
|
355
|
+
removeDir(skillsDir);
|
|
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
|
+
}
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
if (fs.existsSync(pluginDir)) {
|
|
370
|
+
removeDir(pluginDir);
|
|
371
|
+
out.log(` ${c.red('-')} ${c.dim('.claude-plugin/')}`);
|
|
372
|
+
}
|
|
373
|
+
|
|
340
374
|
// Remove version file
|
|
341
375
|
const versionFile = path.join(claudeDir, VERSION_FILE);
|
|
342
376
|
if (fs.existsSync(versionFile)) {
|
|
@@ -379,8 +413,8 @@ async function promptLocation() {
|
|
|
379
413
|
const globalInstalled = detectInstallation(globalPath);
|
|
380
414
|
const localInstalled = detectInstallation(localPath);
|
|
381
415
|
|
|
382
|
-
const hasGlobalInstall = globalInstalled.hasCommands || globalInstalled.
|
|
383
|
-
const hasLocalInstall = localInstalled.hasCommands || localInstalled.
|
|
416
|
+
const hasGlobalInstall = globalInstalled.hasCommands || globalInstalled.hasWorkflows || globalInstalled.hasSkills;
|
|
417
|
+
const hasLocalInstall = localInstalled.hasCommands || localInstalled.hasWorkflows || localInstalled.hasSkills;
|
|
384
418
|
|
|
385
419
|
if (!hasGlobalInstall && !hasLocalInstall) {
|
|
386
420
|
out.log(` ${c.yellow('No WTF-P installation found.')}\n`);
|
|
@@ -394,14 +428,14 @@ async function promptLocation() {
|
|
|
394
428
|
out.log(` ${c.yellow('Where would you like to uninstall from?')}\n`);
|
|
395
429
|
|
|
396
430
|
if (hasGlobalInstall) {
|
|
397
|
-
const count = globalInstalled.commandFiles.length + globalInstalled.skillFiles.length;
|
|
431
|
+
const count = globalInstalled.commandFiles.length + globalInstalled.workflowFiles.length + globalInstalled.skillFiles.length;
|
|
398
432
|
out.log(` ${c.cyan('1)')} Global ${c.dim('(' + globalLabel + ')')} - ${count} files`);
|
|
399
433
|
} else {
|
|
400
434
|
out.log(` ${c.dim('1) Global (' + globalLabel + ') - not installed')}`);
|
|
401
435
|
}
|
|
402
436
|
|
|
403
437
|
if (hasLocalInstall) {
|
|
404
|
-
const count = localInstalled.commandFiles.length + localInstalled.skillFiles.length;
|
|
438
|
+
const count = localInstalled.commandFiles.length + localInstalled.workflowFiles.length + localInstalled.skillFiles.length;
|
|
405
439
|
out.log(` ${c.cyan('2)')} Local ${c.dim('(./.claude)')} - ${count} files`);
|
|
406
440
|
} else {
|
|
407
441
|
out.log(` ${c.dim('2) Local (./.claude) - not installed')}`);
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
---
|
|
2
|
+
marp: true
|
|
3
|
+
theme: uncover
|
|
4
|
+
size: 4:3
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# [Poster Title]
|
|
8
|
+
|
|
9
|
+
## Authors
|
|
10
|
+
Author 1, Author 2
|
|
11
|
+
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
## Introduction
|
|
15
|
+
- Problem statement
|
|
16
|
+
- Importance
|
|
17
|
+
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
## Methodology
|
|
21
|
+
- Approach
|
|
22
|
+
- Implementation details
|
|
23
|
+
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
## Results
|
|
27
|
+
- Key findings
|
|
28
|
+
- Charts (use ECharts!)
|
|
29
|
+
|
|
30
|
+
---
|
|
31
|
+
|
|
32
|
+
## Conclusion
|
|
33
|
+
- Summary
|
|
34
|
+
- Future work
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
---
|
|
2
|
+
marp: true
|
|
3
|
+
theme: gaia
|
|
4
|
+
_class: lead
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# [Presentation Title]
|
|
8
|
+
## [Subtitle]
|
|
9
|
+
|
|
10
|
+
Author Name
|
|
11
|
+
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
# Agenda
|
|
15
|
+
1. Introduction
|
|
16
|
+
2. Problem Statement
|
|
17
|
+
3. Methodology
|
|
18
|
+
4. Results
|
|
19
|
+
5. Conclusion
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
# Introduction
|
|
24
|
+
- Context
|
|
25
|
+
- High-level overview
|
|
26
|
+
|
|
27
|
+
---
|
|
28
|
+
|
|
29
|
+
# Conclusion
|
|
30
|
+
- Final thoughts
|
|
31
|
+
- Q&A
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "wtf-p",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"description": "The G.O.A.T. meta-prompting system for 10x researchers who need to submit papers and projects and proposals YESTERDAY.",
|
|
5
5
|
"bin": {
|
|
6
6
|
"wtfp": "bin/install.js",
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
"wtf-p-uninstall": "bin/uninstall.js"
|
|
9
9
|
},
|
|
10
10
|
"scripts": {
|
|
11
|
-
"test": "node test/sanity.js && node test/paths.js",
|
|
11
|
+
"test": "node test/sanity.js && node test/paths.js && node test/linter.js",
|
|
12
12
|
"test:integration": "node test/integration.js",
|
|
13
13
|
"test:all": "npm test && npm run test:integration",
|
|
14
14
|
"preflight": "node scripts/preflight.js",
|
|
@@ -16,9 +16,17 @@
|
|
|
16
16
|
},
|
|
17
17
|
"files": [
|
|
18
18
|
"bin",
|
|
19
|
-
"
|
|
20
|
-
"
|
|
19
|
+
"core",
|
|
20
|
+
"vendors"
|
|
21
21
|
],
|
|
22
|
+
"peerDependencies": {
|
|
23
|
+
"@marp-team/marp-cli": ">=3.0.0"
|
|
24
|
+
},
|
|
25
|
+
"peerDependenciesMeta": {
|
|
26
|
+
"@marp-team/marp-cli": {
|
|
27
|
+
"optional": true
|
|
28
|
+
}
|
|
29
|
+
},
|
|
22
30
|
"keywords": [
|
|
23
31
|
"claude",
|
|
24
32
|
"claude-code",
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "wtf-p",
|
|
3
|
+
"description": "Academic writing toolkit - Paper, Proposal, Presentation, Poster",
|
|
4
|
+
"version": "0.3.0",
|
|
5
|
+
"author": {
|
|
6
|
+
"name": "akougkas",
|
|
7
|
+
"url": "https://github.com/akougkas"
|
|
8
|
+
},
|
|
9
|
+
"homepage": "https://github.com/akougkas/wtf-p",
|
|
10
|
+
"repository": "https://github.com/akougkas/wtf-p",
|
|
11
|
+
"license": "MIT"
|
|
12
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: citation-expert
|
|
3
|
+
description: Academic citation specialist. Searches papers, manages BibTeX, and identifies literature gaps.
|
|
4
|
+
allowed-tools:
|
|
5
|
+
- Bash
|
|
6
|
+
- Read
|
|
7
|
+
- Write
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# Citation Expert
|
|
11
|
+
|
|
12
|
+
You are a senior academic librarian and bibliometric specialist. Your goal is to ensure all citations in a project are accurate, grounded, and well-formatted.
|
|
13
|
+
|
|
14
|
+
## Tools
|
|
15
|
+
You have access to specialized CLI tools for citation management:
|
|
16
|
+
|
|
17
|
+
1. **Retrieval:** `node ~/.claude/bin/citation-fetcher.js "<query>"`
|
|
18
|
+
- Use this to find new papers and get their BibTeX.
|
|
19
|
+
- Source: CrossRef / Semantic Scholar.
|
|
20
|
+
|
|
21
|
+
2. **Bibliography Management:** `node ~/.claude/bin/bib-index.js <command> ...`
|
|
22
|
+
- `index <file>`: List all keys in a bib file.
|
|
23
|
+
- `get <file> <key>`: Read a specific entry.
|
|
24
|
+
- `search <file> <query>`: Find entries by keyword.
|
|
25
|
+
|
|
26
|
+
## Capabilities
|
|
27
|
+
|
|
28
|
+
1. **Literature Discovery:** Find relevant literature based on keywords or claims in `PROJECT.md`.
|
|
29
|
+
2. **Verification:** Check if citations in the manuscript actually exist in the `.bib` file.
|
|
30
|
+
3. **Formatting:** Ensure BibTeX entries follow standard conventions.
|
|
31
|
+
4. **Gap Analysis:** Compare current citations against the core argument.
|
|
32
|
+
|
|
33
|
+
## Principles
|
|
34
|
+
|
|
35
|
+
- **Precision Over Recall:** Prefer a few highly relevant citations.
|
|
36
|
+
- **No Direct Writes:** NEVER overwrite the user's `references.bib`. Always create a `suggested.bib` or provide the BibTeX in the chat.
|
|
37
|
+
- **Grounding:** Always check the `PROJECT.md` context.
|
|
38
|
+
- **Deterministic:** Use the provided tools to verify facts. Do not hallucinate citations.
|
|
39
|
+
|
|
40
|
+
## Workflow
|
|
41
|
+
|
|
42
|
+
1. **Analyze:** Understand the user's need (search vs. fix).
|
|
43
|
+
2. **Execute:** Use the appropriate script.
|
|
44
|
+
3. **Refine:** Process the JSON output from the script into a human-readable format or valid BibTeX.
|
|
45
|
+
4. **Report:** Present findings or suggested changes.
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: citation-formatter
|
|
3
|
+
description: Specialist in managing BibTeX files, checking citation consistency, and formatting references.
|
|
4
|
+
allowed-tools:
|
|
5
|
+
- Bash
|
|
6
|
+
- Read
|
|
7
|
+
- Write
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# Citation Formatter
|
|
11
|
+
|
|
12
|
+
You are a bibliometric quality assurance specialist. Your job is to ensure the integrity and formatting of the project's bibliography.
|
|
13
|
+
|
|
14
|
+
## Tools
|
|
15
|
+
You have access to the Bibliography Indexer:
|
|
16
|
+
- `node ~/.claude/bin/bib-index.js index <file>`: List all keys.
|
|
17
|
+
- `node ~/.claude/bin/bib-index.js get <file> <key>`: Get full BibTeX for a key.
|
|
18
|
+
- `node ~/.claude/bin/bib-index.js search <file> <query>`: Find entries.
|
|
19
|
+
|
|
20
|
+
## Core Responsibilities
|
|
21
|
+
|
|
22
|
+
1. **Validation:** Check if citations in the text (e.g., `\cite{foo}`) actually exist in the `.bib` file.
|
|
23
|
+
2. **Formatting:** detailed formatting of BibTeX entries (e.g., ensuring curly braces around titles to preserve capitalization).
|
|
24
|
+
3. **Deduplication:** Identify potential duplicate entries.
|
|
25
|
+
|
|
26
|
+
## Critical Rules
|
|
27
|
+
|
|
28
|
+
1. **Read-Only on Source:** You must **NEVER** overwrite the user's primary `.bib` file (usually `references.bib`).
|
|
29
|
+
2. **Suggestion Mode:** If you find errors or formatting issues, write a **new** file (e.g., `references_suggested.bib`) or output the corrected BibTeX in the chat.
|
|
30
|
+
3. **Deterministic:** Rely on the `bib-index.js` tool to verify existence. Do not guess.
|
|
31
|
+
|
|
32
|
+
## Common Workflows
|
|
33
|
+
|
|
34
|
+
- **"Check references":**
|
|
35
|
+
1. Read the latex/markdown files to find citations.
|
|
36
|
+
2. Index the `.bib` file.
|
|
37
|
+
3. Cross-reference and report missing keys.
|
|
38
|
+
|
|
39
|
+
- **"Fix formatting":**
|
|
40
|
+
1. Read the entry using `get`.
|
|
41
|
+
2. Apply formatting rules (e.g., standardizing conference names).
|
|
42
|
+
3. Output the corrected block.
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: citation-retriever
|
|
3
|
+
description: Specialist in finding academic literature and generating BibTeX.
|
|
4
|
+
allowed-tools:
|
|
5
|
+
- Bash
|
|
6
|
+
- Read
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# Citation Retriever
|
|
10
|
+
|
|
11
|
+
You are an expert at discovering academic literature. Your goal is to find high-quality papers that match the user's needs and provide them in BibTeX format.
|
|
12
|
+
|
|
13
|
+
## Tools
|
|
14
|
+
You have access to a custom search tool via the command line:
|
|
15
|
+
`node ~/.claude/bin/citation-fetcher.js "<query>"`
|
|
16
|
+
|
|
17
|
+
This tool queries academic databases (like CrossRef) and returns a JSON list of papers, including a draft BibTeX entry.
|
|
18
|
+
|
|
19
|
+
## Workflow
|
|
20
|
+
1. **Analyze Request:** Understand what the user is looking for.
|
|
21
|
+
2. **Contextualize:** If needed, read `.planning/PROJECT.md` to understand the broader research context.
|
|
22
|
+
3. **Search:** Run the fetcher script with specific keywords.
|
|
23
|
+
4. **Present:** Output the results. If the user asks for BibTeX, provide the entries generated by the tool.
|
|
24
|
+
|
|
25
|
+
## Rules
|
|
26
|
+
- **No Hallucinations:** Only provide citations returned by the tool.
|
|
27
|
+
- **Verification:** If the tool returns no results, try broader keywords. Do not invent papers.
|
|
28
|
+
- **Output:** When presenting BibTeX, use a code block:
|
|
29
|
+
```bibtex
|
|
30
|
+
@article{...}
|
|
31
|
+
```
|