@justinforfun/redo-skill 0.1.1 → 0.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -16,6 +16,8 @@ The installer supports:
16
16
  - Codex CLI
17
17
  - Claude Code
18
18
 
19
+ The installer detects supported tools on the local machine. Detected tools are selected by default; tools that are not detected are left unselected but can still be chosen. If you choose an undetected tool, the installer asks for confirmation before writing to its default directory.
20
+
19
21
  ## Invocation
20
22
 
21
23
  ```text
@@ -44,6 +46,8 @@ For each technology, `redo` reconstructs:
44
46
  - Candidate options and their costs
45
47
  - Why the chosen design won
46
48
  - Key trade-offs
49
+ - Transferable design patterns in sibling systems
50
+ - Boundary cases and counterexamples
47
51
  - Technical debt introduced
48
52
  - Debt that was later resolved
49
53
  - Pain points that still remain
package/bin/install.js CHANGED
@@ -4,6 +4,7 @@ import fs from 'node:fs/promises';
4
4
  import os from 'node:os';
5
5
  import path from 'node:path';
6
6
  import process from 'node:process';
7
+ import { execFile } from 'node:child_process';
7
8
  import { fileURLToPath } from 'node:url';
8
9
 
9
10
  import chalk from 'chalk';
@@ -28,7 +29,15 @@ const targets = [
28
29
  destination: path.join(os.homedir(), '.agents', 'skills', 'redo')
29
30
  }
30
31
  ],
31
- trigger: '$redo kafka, redo kafka, or select redo from the skill picker'
32
+ trigger: '$redo kafka, redo kafka, or select redo from the skill picker',
33
+ detectors: [
34
+ {
35
+ type: 'path',
36
+ value: path.join(os.homedir(), '.agents'),
37
+ label: '~/.agents'
38
+ }
39
+ ],
40
+ missingReason: 'Codex local skill directory was not detected.'
32
41
  },
33
42
  {
34
43
  id: 'codex-cli',
@@ -41,7 +50,20 @@ const targets = [
41
50
  destination: path.join(process.env.CODEX_HOME || path.join(os.homedir(), '.codex'), 'skills', 'redo')
42
51
  }
43
52
  ],
44
- trigger: '$redo kafka, redo kafka, or /skills then choose redo'
53
+ trigger: '$redo kafka, redo kafka, or /skills then choose redo',
54
+ detectors: [
55
+ {
56
+ type: 'command',
57
+ value: 'codex',
58
+ label: 'codex command'
59
+ },
60
+ {
61
+ type: 'path',
62
+ value: process.env.CODEX_HOME || path.join(os.homedir(), '.codex'),
63
+ label: process.env.CODEX_HOME ? 'CODEX_HOME' : '~/.codex'
64
+ }
65
+ ],
66
+ missingReason: 'codex command and Codex CLI home directory were not detected.'
45
67
  },
46
68
  {
47
69
  id: 'claude-code',
@@ -59,7 +81,20 @@ const targets = [
59
81
  destination: path.join(os.homedir(), '.claude', 'commands', 'redo.md')
60
82
  }
61
83
  ],
62
- trigger: '/redo kafka'
84
+ trigger: '/redo kafka',
85
+ detectors: [
86
+ {
87
+ type: 'command',
88
+ value: 'claude',
89
+ label: 'claude command'
90
+ },
91
+ {
92
+ type: 'path',
93
+ value: path.join(os.homedir(), '.claude'),
94
+ label: '~/.claude'
95
+ }
96
+ ],
97
+ missingReason: 'claude command and Claude Code home directory were not detected.'
63
98
  }
64
99
  ];
65
100
 
@@ -116,21 +151,114 @@ async function ensureSourceSkillExists() {
116
151
  }
117
152
 
118
153
  async function promptTargets() {
154
+ const detectedTargets = await detectTargets();
155
+ const availableTargets = detectedTargets.filter((target) => target.available);
156
+
157
+ if (availableTargets.length === 0) {
158
+ console.log(chalk.yellow('No supported AI tools were detected. Nothing installed.'));
159
+ console.log(chalk.dim('Install Codex, Codex CLI, or Claude Code first, then run this installer again.'));
160
+ return [];
161
+ }
162
+
119
163
  const answers = await inquirer.prompt([
120
164
  {
121
165
  type: 'checkbox',
122
166
  name: 'targetIds',
123
167
  message: 'Select AI tools to install redo for:',
124
- choices: targets.map((target) => ({
125
- name: `${target.name} ${chalk.dim('- ' + target.description)}`,
168
+ choices: detectedTargets.map((target) => ({
169
+ name: formatTargetChoice(target),
126
170
  value: target.id,
127
- checked: true
171
+ checked: target.available,
172
+ disabled: false
128
173
  })),
129
174
  validate: (values) => (values.length > 0 ? true : 'Select at least one tool.')
130
175
  }
131
176
  ]);
132
177
 
133
- return targets.filter((target) => answers.targetIds.includes(target.id));
178
+ const selectedTargets = detectedTargets.filter((target) => answers.targetIds.includes(target.id));
179
+ return promptUndetectedTargetConfirmation(selectedTargets);
180
+ }
181
+
182
+ async function detectTargets() {
183
+ return Promise.all(
184
+ targets.map(async (target) => {
185
+ const detection = await detectTarget(target);
186
+ return {
187
+ ...target,
188
+ ...detection
189
+ };
190
+ })
191
+ );
192
+ }
193
+
194
+ async function detectTarget(target) {
195
+ for (const detector of target.detectors) {
196
+ if (detector.type === 'path' && (await exists(detector.value))) {
197
+ return {
198
+ available: true,
199
+ detectionLabel: detector.label
200
+ };
201
+ }
202
+
203
+ if (detector.type === 'command' && (await commandExists(detector.value))) {
204
+ return {
205
+ available: true,
206
+ detectionLabel: detector.label
207
+ };
208
+ }
209
+ }
210
+
211
+ return {
212
+ available: false,
213
+ detectionLabel: null
214
+ };
215
+ }
216
+
217
+ function formatTargetChoice(target) {
218
+ const description = chalk.dim('- ' + target.description);
219
+
220
+ if (target.available) {
221
+ return `${target.name} ${description} ${chalk.green('(detected: ' + target.detectionLabel + ')')}`;
222
+ }
223
+
224
+ return `${target.name} ${description} ${chalk.yellow('(not detected)')}`;
225
+ }
226
+
227
+ async function commandExists(command) {
228
+ const lookupCommand = process.platform === 'win32' ? 'where' : 'which';
229
+
230
+ return new Promise((resolve) => {
231
+ execFile(lookupCommand, [command], (error) => {
232
+ resolve(!error);
233
+ });
234
+ });
235
+ }
236
+
237
+ async function promptUndetectedTargetConfirmation(selectedTargets) {
238
+ const confirmedTargets = [];
239
+
240
+ for (const target of selectedTargets) {
241
+ if (target.available) {
242
+ confirmedTargets.push(target);
243
+ continue;
244
+ }
245
+
246
+ const destinationSummary = target.tasks.map((task) => task.destination).join(', ');
247
+ const answers = await inquirer.prompt([
248
+ {
249
+ type: 'confirm',
250
+ name: 'installAnyway',
251
+ message: `${target.name} was not detected. Install to ${destinationSummary} anyway?`,
252
+ default: false
253
+ }
254
+ ]);
255
+
256
+ if (answers.installAnyway) {
257
+ confirmedTargets.push(target);
258
+ }
259
+ }
260
+
261
+ return confirmedTargets;
134
262
  }
135
263
 
136
264
  async function promptConflictActions(plan) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@justinforfun/redo-skill",
3
- "version": "0.1.1",
3
+ "version": "0.1.3",
4
4
  "description": "Install the redo skill for Codex, Codex CLI, and Claude Code.",
5
5
  "type": "module",
6
6
  "keywords": [
@@ -16,6 +16,8 @@ The installer supports:
16
16
  - Codex CLI
17
17
  - Claude Code
18
18
 
19
+ The installer detects supported tools on the local machine. Detected tools are selected by default; tools that are not detected are left unselected but can still be chosen. If you choose an undetected tool, the installer asks for confirmation before writing to its default directory.
20
+
19
21
  ## Invocation
20
22
 
21
23
  ```text
@@ -44,6 +46,8 @@ For each technology, `redo` reconstructs:
44
46
  - Candidate options and their costs
45
47
  - Why the chosen design won
46
48
  - Key trade-offs
49
+ - Transferable design patterns in sibling systems
50
+ - Boundary cases and counterexamples
47
51
  - Technical debt introduced
48
52
  - Debt that was later resolved
49
53
  - Pain points that still remain
@@ -36,6 +36,8 @@ redo <topic> [--lang zh|en]
36
36
  - `--lang en` forces English output.
37
37
  - If `--lang` is absent, respond in the user's current conversation language.
38
38
 
39
+ The selected output language applies to the entire answer. Localize every user-facing section name, heading, table label, fixed phrase, and summary label into that language. Do not leak English template labels such as "Stage", "Debt introduced", "One-sentence version", "Transferable Pattern", "Counterexample", or "Sources" unless the user asked for English.
40
+
39
41
  ## Evidence Requirements
40
42
 
41
43
  For real technologies, do not rely only on memory when dates, versions, authorship, current status, or historical claims matter.
@@ -43,7 +45,10 @@ For real technologies, do not rely only on memory when dates, versions, authorsh
43
45
  - If web access is available and the user has not forbidden it, verify with primary or high-authority sources first: official documentation, release notes, RFCs, design docs, papers, project repositories, or authoritative engineering blogs.
44
46
  - If web access is unavailable, blocked, or the user forbids browsing, state clearly that the analysis is not freshly verified from online sources.
45
47
  - Distinguish sourced facts from inference. It is acceptable to infer engineering motivations, but label them as inference when the source does not explicitly say so.
46
- - Prefer fewer, stronger stages over many shallow ones. A good answer usually has 5-9 stages.
48
+ - Prefer primary sources over secondary commentary. Good sources include official docs, release notes, KIPs/RFCs/PEPs/design proposals, original papers, maintainers' posts, and authoritative engineering retrospectives.
49
+ - Research relevant papers separately when the topic has an academic or foundational design lineage. Papers often explain why the original abstraction was plausible, what constraints the designers optimized for, and which trade-offs were known from the beginning. Do not only search release notes and blog posts.
50
+ - Avoid weak secondary sources when primary sources exist. Do not cite SEO summaries, generic tutorials, or casual comparison posts for core historical claims if official design docs, papers, or maintainer explanations are available.
51
+ - Avoid source dumping. Cite the key sources used, and when useful, say which stages they support.
47
52
 
48
53
  ## Output Contract
49
54
 
@@ -51,12 +56,30 @@ Start with a compact orientation:
51
56
 
52
57
  - What the system is.
53
58
  - The central pressure that shaped its evolution.
54
- - The main trade-off theme that appears repeatedly.
59
+ - The one-sentence trade-off theme that appears repeatedly. Make this sharp and reusable, not academic.
55
60
 
56
61
  Then produce the sections below.
57
62
 
58
63
  ### 1. Evolution Stages
59
64
 
65
+ Choose stages by engineering decision pressure, not by release chronology. Causal order is more important than strict release order, but time should generally move forward. If a later concern appears before an earlier release, explain why the causal dependency is being presented that way.
66
+
67
+ For mature infrastructure, databases, runtimes, frameworks, languages, and major tools, a good answer usually has 7-9 stages. Do not compress a major "debt repayment" stage into the debt map if it changed how users operate the system. If you use more than 8 stages, the extra stage must earn its place by explaining a current frontier, current user-facing pain, or important debt repayment that would otherwise be invisible.
68
+
69
+ A stage can be a partial mitigation, not only a new feature. If a prior debt became painful at scale and later received a named fix, protocol change, runtime change, scheduler change, storage change, migration path, or operational redesign, make that fix its own stage. Do not hide it only in the debt map.
70
+
71
+ For mature systems, check whether the stage list covers these arcs where relevant:
72
+
73
+ - Prototype or original abstraction.
74
+ - Reliability and replication/fault tolerance.
75
+ - Coordination, metadata, scheduling, ownership, or state management.
76
+ - Semantics/correctness guarantees.
77
+ - Ecosystem or higher-level abstraction.
78
+ - Major mitigation of a previously introduced operational pain.
79
+ - Scale, cloud-native, elasticity, or operations.
80
+ - Cost/storage/performance pressure.
81
+ - Current unresolved frontier.
82
+
60
83
  For each stage, use this structure:
61
84
 
62
85
  ```markdown
@@ -72,43 +95,118 @@ For each stage, use this structure:
72
95
 
73
96
  **Key trade-off:** <the most important exchange>
74
97
 
75
- **Debt introduced:** <what this choice made harder later>
98
+ **Debt introduced:** D<N> - <what this choice made harder later>
76
99
  ```
77
100
 
78
101
  Stage quality rules:
79
102
 
80
103
  - Every stage must be driven by a concrete constraint, not by a release note.
81
104
  - Every table must contain at least two rejected options and one chosen path.
82
- - Explain why a reasonable engineer would choose the winning path at that time, even if it later caused problems.
105
+ - Keep table cells tight: one cost, one reason, one decision. Avoid long essay cells.
106
+ - The chosen option must say why it was rational under the constraints of that stage, even if it later caused problems.
107
+ - The rejected options must be plausible choices real engineers would have considered.
108
+ - The debt line must create a traceable debt ID such as D1, D2, D3. Reuse these IDs in the debt map.
109
+ - Use clean top-level debt IDs: D1, D2, D3, and so on. If one stage introduces multiple meaningful debts, assign the next clean IDs instead of ad-hoc labels such as D2-4 or D3b.
110
+ - When a stage primarily repays earlier debt, explicitly say which debt IDs it repays and what new debt it introduces.
83
111
  - Avoid hindsight moralizing. The point is to recreate the decision pressure, not to mock past designs.
84
112
 
85
113
  ### 2. Throughline
86
114
 
87
- Summarize the recurring design philosophy in one or two paragraphs. Make it specific to the topic, for example:
115
+ Summarize the recurring design philosophy in one or two paragraphs plus a compact table. Make it specific to the topic, for example:
88
116
 
89
117
  - "Push complexity into the runtime to keep application code simple."
90
118
  - "Preserve backward compatibility even when it complicates internals."
91
119
  - "Use logs as the universal abstraction."
92
120
 
93
- ### 3. Debt Map
121
+ Then add:
94
122
 
95
- Create two tables.
123
+ ```markdown
124
+ | Repeated choice | What it avoided | What it made harder | Outcome |
125
+ |---|---|---|---|
126
+ ```
96
127
 
97
- Resolved debt:
128
+ Use this structure so the section is stable:
98
129
 
99
130
  ```markdown
100
- | Debt | Introduced in | Resolved in | Resolution |
131
+ ## Throughline
132
+
133
+ <one paragraph naming the recurring philosophy>
134
+
135
+ The cost: <one sentence naming the recurring price>
136
+
137
+ | Repeated choice | What it avoided | What it made harder | Outcome |
101
138
  |---|---|---|---|
139
+
140
+ **Design-review sentence:** "<one memorable sentence>"
102
141
  ```
103
142
 
104
- Unresolved debt:
143
+ ### 3. Transferable Pattern and Boundaries
144
+
145
+ After the throughline, add a section that helps the reader generalize the core design idea beyond the topic. This is not a random "similar tools" list. It should identify the reusable engineering philosophy, show where other systems apply the same idea, and show where the idea breaks down.
146
+
147
+ Use this structure:
105
148
 
106
149
  ```markdown
107
- | Pain point | Why it remains hard | Current manifestation |
150
+ ## Transferable Pattern
151
+
152
+ <one paragraph naming the reusable idea, such as "delegate caching to the operating system", "make the log the source of truth", or "push coordination into a control plane">
153
+
154
+ | System | How it uses the same idea | Shared constraint | Different price |
155
+ |---|---|---|---|
156
+ | <system> | <specific mechanism> | <why the same idea fits> | <what this system pays instead> |
157
+ ```
158
+
159
+ Then add a boundary or counterexample table:
160
+
161
+ ```markdown
162
+ ## Where This Pattern Stops
163
+
164
+ | Counterexample | Why the opposite choice is rational | Boundary rule |
108
165
  |---|---|---|
166
+ | <system or system class> | <mechanism-level reason> | <when not to copy the original topic's design> |
109
167
  ```
110
168
 
111
- ### 4. Pain Point Ranking
169
+ Generalization quality rules:
170
+
171
+ - Compare mechanisms, not product categories. "Both rely on OS page cache for immutable segment-like files" is useful; "both are data systems" is not.
172
+ - Include 3-5 sibling systems when there is a real shared principle. If fewer than 3 are defensible, use fewer and explain why.
173
+ - Include at least one counterexample or boundary class when the pattern has a meaningful opposite design. The counterexample should make the original idea clearer, not just criticize another system.
174
+ - Every sibling or counterexample must name the condition that makes the design work or fail: immutable files, append-only logs, random updates, strict transaction control, latency tail sensitivity, memory ownership, coordination scope, compatibility pressure, and so on.
175
+ - Do not imply the original topic's design is universally superior. The goal is "when to copy this idea" and "when not to copy it".
176
+ - For specific comparisons to real systems, verify with primary or high-authority sources when online verification is available.
177
+
178
+ ### 4. Debt Map
179
+
180
+ Create three tables. Use the debt IDs introduced in the stages. A debt is "resolved" only when the original failure mode is structurally removed or no longer a normal user concern. If a later design reduces blast radius, frequency, or operational cost but the pain can still appear, put it under "mitigated", not "resolved".
181
+
182
+ Resolved debt:
183
+
184
+ ```markdown
185
+ | Debt ID | Debt | Introduced in | Resolved in | Resolution |
186
+ |---|---|---|---|---|
187
+ ```
188
+
189
+ Mitigated debt:
190
+
191
+ ```markdown
192
+ | Debt ID | Debt | Introduced in | Mitigated in | What improved | What remains |
193
+ |---|---|---|---|---|---|
194
+ ```
195
+
196
+ Unresolved debt:
197
+
198
+ ```markdown
199
+ | Debt ID | Pain point | Why it remains hard | Current manifestation |
200
+ |---|---|---|---|
201
+ ```
202
+
203
+ Debt map quality rules:
204
+
205
+ - The map must explain "introduced in stage X, resolved or mitigated in stage Y" where applicable.
206
+ - Do not list only abstract categories like "operational complexity". Name the concrete failure mode users feel.
207
+ - Include important unresolved operational pain even if it came from an omitted or secondary stage, but label it clearly.
208
+
209
+ ### 5. Pain Point Ranking
112
210
 
113
211
  Rank the top unresolved problems that users still feel today.
114
212
 
@@ -119,24 +217,99 @@ Rank the top unresolved problems that users still feel today.
119
217
 
120
218
  Use the competitive attack angle only when there is a meaningful comparison. Otherwise write "N/A".
121
219
 
122
- ### 5. Causal Chain
220
+ Ranking quality rules:
221
+
222
+ - Prefer production symptoms over abstract labels: "rebalance storms", "cold-read latency", "schema migration pain", "dependency hell", "slow compile times", "state restore time", "version skew".
223
+ - The one-line explanation should describe what users observe during failure or scale, not just why the architecture is complex.
224
+ - Competitive attack angles should be concrete. Name a class of alternative system or a known competitor only when the comparison is fair.
225
+ - Do not overclaim in competitive comparisons. If an alternative avoids one pain by accepting another trade-off, state that trade-off briefly instead of implying it is strictly better.
226
+ - Phrase attack angles as trade-off-aware comparisons: "X can attack this by doing Y, but pays Z." Avoid claims like "X does not have this problem" unless a primary source or well-established mechanism supports it.
227
+ - If the comparison would be shallow or unfair, write "N/A" rather than forcing a competitor into the table.
228
+
229
+ ### 6. Causal Chain
230
+
231
+ End with a causal chain that makes the evolution memorable. For complex systems, use an ASCII story map rather than a flat paragraph:
232
+
233
+ ```text
234
+ early constraint -> chosen design -> solved problem, but introduced D<N>
235
+ |
236
+ v
237
+ next constraint -> next design -> repaid D<N>, but introduced D<M>
238
+ ```
239
+
240
+ Keep it concise and legible. The best chain should let the reader retell the system's history from memory.
123
241
 
124
- End with a causal chain that makes the evolution memorable:
242
+ Use arrows and vertical continuation when it improves readability:
125
243
 
126
244
  ```text
127
- early constraint -> chosen design -> solved problem -> new debt -> later fix -> remaining pain
245
+ 2011 original constraint -> 2012 design -> solved X, but introduced D1
246
+ |
247
+ v
248
+ 2014 next constraint -> next design -> repaid D1, but introduced D2
249
+ ```
250
+
251
+ After the chain, add a bold one-sentence version:
252
+
253
+ ```markdown
254
+ **One-sentence version:** <the system's repeated pattern and unresolved tension today>
128
255
  ```
129
256
 
130
- Keep it concise and legible.
257
+ This sentence should be conversational, sharp, and technically accurate.
258
+
259
+ ### 7. Sources
260
+
261
+ If online verification was used, end with a short source list. Prefer 6-10 high-signal sources over a long bibliography. Split sources into primary and secondary groups. Use secondary sources only when they add useful synthesis or operational perspective, and keep them to at most two items. Do not use a secondary source for a core mechanism when an official design doc, release note, RFC, KIP, PEP, paper, or maintainer explanation exists.
262
+
263
+ Use this format:
264
+
265
+ ```markdown
266
+ Primary sources:
267
+
268
+ - Foundational papers: <source>
269
+ - Stage 2 replication: <source>
270
+ - Stage 5 correctness semantics: <source>
271
+ - Current pain points: <source>
272
+
273
+ Secondary sources (optional, max 2):
274
+
275
+ - Operational retrospective or synthesis: <source>
276
+ ```
277
+
278
+ Source quality rules:
279
+
280
+ - Every major stage should be supported by at least one primary source when online verification is available.
281
+ - If an important claim is inferred from multiple sources rather than directly stated, mark it as inference in the analysis.
282
+ - Do not cite generic tutorials, SEO summaries, or casual comparison posts for mechanism, history, or version claims.
283
+
284
+ Do not let sources replace reasoning. The main output should remain the decision tree and debt map.
131
285
 
132
286
  ## Style
133
287
 
134
288
  - Write like a senior engineer explaining architecture history to another engineer.
289
+ - Keep the language conversational but precise: sound like a senior engineer explaining the decision in a design review, not like a paper abstract or a marketing article.
290
+ - Prefer memorable engineering phrasing over neutral summaries, but never sacrifice technical accuracy for punchlines.
135
291
  - Prefer concrete mechanisms, failure modes, and operational consequences.
292
+ - Make the answer feel like a decision tree and a debt map, not a neutral research report.
136
293
  - Use direct language. Avoid vague praise such as "powerful", "robust", or "revolutionary" unless immediately explained.
137
294
  - Use Chinese if the user is writing Chinese, English if the user is writing English, unless `--lang` overrides.
138
295
  - If the topic is too broad, choose the core system path and say what you intentionally left out.
139
296
  - If the historical record is uncertain, say so and give the most likely interpretation.
297
+ - Match the output language consistently. For non-English output, translate headings and table labels into the user's language instead of leaking English template labels.
298
+
299
+ ## Quality Gate
300
+
301
+ Before finalizing, check the answer against these questions:
302
+
303
+ - Could a reader infer the system's evolution from stage 1 to today by following only the trade-offs?
304
+ - Did you include major debt repayment stages, not just feature releases?
305
+ - Did you include major partial-mitigation stages when a painful debt later received an important fix?
306
+ - Does every stage have plausible rejected alternatives and a rational chosen path?
307
+ - Are the pain points concrete production symptoms rather than broad categories?
308
+ - Does every resolved or unresolved debt connect back to a stage or debt ID?
309
+ - Is the throughline sharp enough to quote in one sentence?
310
+ - Does the transferable-pattern section show where the core idea works in other systems and where it stops?
311
+ - Are sources high-signal and tied to the claims they support?
312
+ - Is the language of headings, labels, and section names consistent with the user's language?
140
313
 
141
314
  ## Tool-Specific Invocation Notes
142
315