@ckelsoe/prompt-architect 3.2.2 → 3.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/.claude-plugin/marketplace.json +3 -3
- package/.claude-plugin/plugin.json +2 -2
- package/CHANGELOG.md +135 -5
- package/MIGRATION.md +1 -1
- package/README.md +32 -47
- package/adapters/README.md +1 -1
- package/adapters/system-prompt.md +115 -59
- package/package.json +5 -4
- package/scripts/install.js +52 -22
- package/scripts/test.js +88 -40
- package/scripts/validate-skill.js +184 -56
- package/skills/prompt-architect/SKILL.md +94 -79
- package/skills/prompt-architect/assets/templates/ape_template.txt +14 -3
- package/skills/prompt-architect/assets/templates/bab_template.txt +23 -10
- package/skills/prompt-architect/assets/templates/broke_template.txt +31 -6
- package/skills/prompt-architect/assets/templates/cai-critique-revise_template.txt +16 -8
- package/skills/prompt-architect/assets/templates/care_template.txt +4 -0
- package/skills/prompt-architect/assets/templates/chain-of-density_template.txt +64 -35
- package/skills/prompt-architect/assets/templates/chain-of-thought_template.txt +8 -0
- package/skills/prompt-architect/assets/templates/co-star_template.txt +8 -0
- package/skills/prompt-architect/assets/templates/crispe_template.txt +6 -0
- package/skills/prompt-architect/assets/templates/ctf_template.txt +8 -0
- package/skills/prompt-architect/assets/templates/devils-advocate_template.txt +7 -0
- package/skills/prompt-architect/assets/templates/hybrid_template.txt +44 -24
- package/skills/prompt-architect/assets/templates/iterative-compression_template.txt +74 -0
- package/skills/prompt-architect/assets/templates/least-to-most_template.txt +4 -0
- package/skills/prompt-architect/assets/templates/plan-and-solve_template.txt +4 -0
- package/skills/prompt-architect/assets/templates/pre-mortem_template.txt +24 -14
- package/skills/prompt-architect/assets/templates/race_template.txt +9 -0
- package/skills/prompt-architect/assets/templates/rcot_template.txt +8 -0
- package/skills/prompt-architect/assets/templates/react_template.txt +38 -16
- package/skills/prompt-architect/assets/templates/rise-ie_template.txt +4 -0
- package/skills/prompt-architect/assets/templates/rise-ix_template.txt +3 -3
- package/skills/prompt-architect/assets/templates/risen_template.txt +7 -0
- package/skills/prompt-architect/assets/templates/rpef_template.txt +16 -11
- package/skills/prompt-architect/assets/templates/rtf_template.txt +9 -0
- package/skills/prompt-architect/assets/templates/skeleton-of-thought_template.txt +18 -10
- package/skills/prompt-architect/assets/templates/step-back_template.txt +4 -0
- package/skills/prompt-architect/assets/templates/tidd-ec_template.txt +54 -31
- package/skills/prompt-architect/assets/templates/tree-of-thought_template.txt +37 -21
- package/skills/prompt-architect/references/frameworks/ape.md +145 -57
- package/skills/prompt-architect/references/frameworks/bab.md +139 -58
- package/skills/prompt-architect/references/frameworks/broke.md +157 -57
- package/skills/prompt-architect/references/frameworks/cai-critique-revise.md +184 -76
- package/skills/prompt-architect/references/frameworks/care.md +67 -36
- package/skills/prompt-architect/references/frameworks/chain-of-density.md +111 -417
- package/skills/prompt-architect/references/frameworks/chain-of-thought.md +45 -19
- package/skills/prompt-architect/references/frameworks/co-star.md +102 -44
- package/skills/prompt-architect/references/frameworks/crispe.md +7 -5
- package/skills/prompt-architect/references/frameworks/ctf.md +75 -37
- package/skills/prompt-architect/references/frameworks/devils-advocate.md +105 -58
- package/skills/prompt-architect/references/frameworks/iterative-compression.md +448 -0
- package/skills/prompt-architect/references/frameworks/least-to-most.md +35 -13
- package/skills/prompt-architect/references/frameworks/plan-and-solve.md +38 -9
- package/skills/prompt-architect/references/frameworks/pre-mortem.md +182 -72
- package/skills/prompt-architect/references/frameworks/race.md +93 -38
- package/skills/prompt-architect/references/frameworks/rcot.md +1 -1
- package/skills/prompt-architect/references/frameworks/react.md +230 -97
- package/skills/prompt-architect/references/frameworks/reverse-role.md +23 -16
- package/skills/prompt-architect/references/frameworks/rise.md +120 -77
- package/skills/prompt-architect/references/frameworks/risen.md +82 -28
- package/skills/prompt-architect/references/frameworks/rpef.md +227 -58
- package/skills/prompt-architect/references/frameworks/rtf.md +4 -2
- package/skills/prompt-architect/references/frameworks/self-refine.md +4 -2
- package/skills/prompt-architect/references/frameworks/skeleton-of-thought.md +68 -22
- package/skills/prompt-architect/references/frameworks/step-back.md +48 -16
- package/skills/prompt-architect/references/frameworks/tidd-ec.md +129 -51
- package/skills/prompt-architect/references/frameworks/tree-of-thought.md +112 -37
- package/skills/prompt-architect/scripts/framework_analyzer.py +0 -807
- package/skills/prompt-architect/scripts/prompt_evaluator.py +0 -336
|
@@ -13,16 +13,30 @@ You are an expert in prompt engineering and systematic application of prompting
|
|
|
13
13
|
|
|
14
14
|
### 1. Initial Assessment
|
|
15
15
|
|
|
16
|
-
When a user provides a prompt to improve,
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
16
|
+
When a user provides a prompt to improve, **score it 1-10 on each of these five dimensions** and report an overall score (the mean, to one decimal place). Always show the scores — they justify the changes you are about to make and give the user a before/after they can feel.
|
|
17
|
+
|
|
18
|
+
| Dimension | What you are scoring |
|
|
19
|
+
|---|---|
|
|
20
|
+
| **Clarity** | Is the goal unambiguous? Penalize vague terms ("thing", "stuff", "something", "maybe"), unresolved pronouns, and an implied-but-unstated objective. |
|
|
21
|
+
| **Specificity** | Are requirements concrete? Reward named entities, quantities, and explicit format/length/style specifications. Penalize prompts so short they cannot carry the detail. |
|
|
22
|
+
| **Context** | Is the necessary background present? Reward stated situation, audience, and rationale ("because", "in order to"). Penalize a bare instruction with no setting. |
|
|
23
|
+
| **Completeness** | Are *what*, *why*, *how*, and *output format* all present? Each missing element costs. |
|
|
24
|
+
| **Structure** | Is it organized for its length? Reward sections, lists, and logical ordering. Penalize run-on sentences and long unbroken prose. |
|
|
25
|
+
|
|
26
|
+
**Rubric anchors** — apply per dimension so scores mean the same thing every time:
|
|
27
|
+
|
|
28
|
+
| Band | Meaning |
|
|
29
|
+
|---|---|
|
|
30
|
+
| **1-3** | Absent or actively harmful. The model would have to guess this dimension entirely. |
|
|
31
|
+
| **4-6** | Present but underspecified. The model can proceed, but will fill gaps with assumptions the user did not choose. |
|
|
32
|
+
| **7-8** | Solid. Enough to produce a good result; refinement would be marginal. |
|
|
33
|
+
| **9-10** | Complete and unambiguous. A competent model has nothing left to infer on this dimension. |
|
|
34
|
+
|
|
35
|
+
Score the prompt *as written*, not as you charitably interpret it — the gap between those two is precisely what the framework will fix. A prompt scoring 7+ across the board often needs no framework at all (see **When NOT to Use Frameworks**).
|
|
22
36
|
|
|
23
37
|
### 2. Intent-Based Framework Selection
|
|
24
38
|
|
|
25
|
-
With
|
|
39
|
+
With 29 frameworks, identify the user's **primary intent** first, then use the discriminating questions within that category.
|
|
26
40
|
|
|
27
41
|
---
|
|
28
42
|
|
|
@@ -64,7 +78,8 @@ With 27 frameworks, identify the user's **primary intent** first, then use the d
|
|
|
64
78
|
|--------|-----------|
|
|
65
79
|
| Rewrite, refactor, convert | **BAB** |
|
|
66
80
|
| Iterative quality improvement | **Self-Refine** |
|
|
67
|
-
|
|
|
81
|
+
| Summarize at fixed length, maximize information | **Chain of Density** |
|
|
82
|
+
| Shorten text toward a target length | **Iterative Compression** |
|
|
68
83
|
| Outline-first then expand sections | **Skeleton of Thought** |
|
|
69
84
|
|
|
70
85
|
---
|
|
@@ -102,6 +117,20 @@ With 27 frameworks, identify the user's **primary intent** first, then use the d
|
|
|
102
117
|
|
|
103
118
|
---
|
|
104
119
|
|
|
120
|
+
#### Combining Frameworks
|
|
121
|
+
|
|
122
|
+
Most prompts need exactly one framework. Combine only when the task genuinely has **two separable phases** — one framework structures the request, a second governs how the output is checked or refined. If you cannot name the two phases, do not combine.
|
|
123
|
+
|
|
124
|
+
| When | Combination | Why |
|
|
125
|
+
|---|---|---|
|
|
126
|
+
| High-stakes content that must survive review | **CO-STAR + Self-Refine** | CO-STAR fixes audience/tone/format; Self-Refine adds a critique-and-revise loop before delivery |
|
|
127
|
+
| Multi-step procedure executed with tools | **RISEN + ReAct** | RISEN specifies the steps and success criteria; ReAct governs the tool-use cycle within each step |
|
|
128
|
+
| Business deliverable with a hostile audience | **BROKE + Devil's Advocate** | BROKE sets objective and key results; Devil's Advocate stress-tests them before they reach a stakeholder |
|
|
129
|
+
|
|
130
|
+
When you combine, state plainly in your analysis which framework owns which phase. Never stack more than two — beyond that the frameworks' instructions start to overlap and contradict, and no single framework clearly owns any phase.
|
|
131
|
+
|
|
132
|
+
---
|
|
133
|
+
|
|
105
134
|
### 3. Framework Quick Reference
|
|
106
135
|
|
|
107
136
|
**Simple:** APE | RTF | CTF
|
|
@@ -109,7 +138,7 @@ With 27 frameworks, identify the user's **primary intent** first, then use the d
|
|
|
109
138
|
**Comprehensive:** CO-STAR | RISEN | TIDD-EC
|
|
110
139
|
**Data:** RISE-IE | RISE-IX
|
|
111
140
|
**Reasoning:** Plan-and-Solve | Chain of Thought | Least-to-Most | Step-Back | Tree of Thought | RCoT
|
|
112
|
-
**Structure/Iteration:** Skeleton of Thought | Chain of Density
|
|
141
|
+
**Structure/Iteration:** Skeleton of Thought | Chain of Density | Iterative Compression
|
|
113
142
|
**Critique/Quality:** Self-Refine | CAI Critique-Revise | Devil's Advocate | Pre-Mortem
|
|
114
143
|
**Meta/Reverse:** RPEF | Reverse Role Prompting
|
|
115
144
|
**Agentic:** ReAct
|
|
@@ -118,56 +147,83 @@ With 27 frameworks, identify the user's **primary intent** first, then use the d
|
|
|
118
147
|
|
|
119
148
|
Ask targeted questions (3-5 at a time) based on identified gaps:
|
|
120
149
|
|
|
121
|
-
**For CO-STAR**:
|
|
122
|
-
**For RISEN**:
|
|
123
|
-
**For RISE-IE**:
|
|
124
|
-
**For RISE-IX**:
|
|
125
|
-
**For TIDD-EC**:
|
|
126
|
-
**For CTF**:
|
|
127
|
-
**For RTF**:
|
|
128
|
-
**For APE**:
|
|
129
|
-
**For BAB**:
|
|
130
|
-
**For RACE**:
|
|
131
|
-
**For CRISPE**:
|
|
132
|
-
**For BROKE**:
|
|
133
|
-
**For CARE**:
|
|
134
|
-
**For Tree of Thought**:
|
|
135
|
-
**For ReAct**:
|
|
136
|
-
**For Skeleton of Thought**:
|
|
137
|
-
**For Step-Back**:
|
|
138
|
-
**For Least-to-Most**:
|
|
139
|
-
**For Plan-and-Solve**:
|
|
140
|
-
**For Chain of Thought**:
|
|
141
|
-
**For Chain of Density**:
|
|
142
|
-
**For
|
|
143
|
-
**For
|
|
144
|
-
**For
|
|
145
|
-
**For
|
|
146
|
-
**For
|
|
147
|
-
**For
|
|
148
|
-
**For
|
|
150
|
+
**For CO-STAR**: Paste the material this is built from if any, the situation and constraints behind it, who the audience is and what you want them to do, the tone and style to write in, the output format and length?
|
|
151
|
+
**For RISEN**: Paste the material the procedure runs on if any, the expertise and methodology to adopt, the steps in order, what must be true when it is done, what is out of scope or must not happen?
|
|
152
|
+
**For RISE-IE**: Paste the actual data to be processed (not a description of it), its format and any quirks to expect, the expertise needed, the processing steps in order, what the output must look like?
|
|
153
|
+
**For RISE-IX**: The expertise to embody, what to create and its core requirements, the workflow steps, paste 2-3 actual samples whose style and format the output should match?
|
|
154
|
+
**For TIDD-EC**: Paste the material this task operates on (the message, document, or dataset itself, not a description of it), what kind of task this is and the background that shapes it, the exact steps in order, what must always be included and what must never happen (state each as a prohibition, not a topic), examples of a good result?
|
|
155
|
+
**For CTF**: Paste the artifact this operates on if you have one, the situation and background around it, the exact task and deliverable, the output format?
|
|
156
|
+
**For RTF**: Paste the material the task applies to if any, the expertise needed, the exact task and deliverable, the output format and length?
|
|
157
|
+
**For APE**: Paste the material the action applies to if any, the one action to perform, why it is needed and who uses the result, what a good result looks like?
|
|
158
|
+
**For BAB**: Paste the actual artifact being transformed, what is wrong with it now, what it should become, what rules govern the transformation?
|
|
159
|
+
**For RACE**: Paste the material the task applies to if any, the role and expertise needed, the action to perform, the situational context and audience, what a successful output looks like?
|
|
160
|
+
**For CRISPE**: The expertise and role to embody, paste the data or style sample it should work from, the background it needs, the exact task and deliverable, the tone and how many variants?
|
|
161
|
+
**For BROKE**: Paste the supporting material or performance data if you have it, the current situation and why this task exists, the role to embody, the specific deliverable and the structure and length the response should have, the measurable business outcome it should move?
|
|
162
|
+
**For CARE**: Paste the source document or draft this works from if any, your situation and why this task exists, the specific ask and deliverable, what must be included and what would make this output wrong or unusable, an example of what good looks like?
|
|
163
|
+
**For Tree of Thought**: The decision or problem and its constraints, paste the evidence the branches must be judged against, the 2-5 distinct approaches to compare, the criteria that decide between them?
|
|
164
|
+
**For ReAct**: Does the environment this runs in actually have callable tools — if not, stop and use Chain of Thought instead, which tools are available and how each is invoked, what end state counts as success, what limits apply and when to stop?
|
|
165
|
+
**For Skeleton of Thought**: The topic or question to outline, paste the document, data, or notes the answer must be drawn from if you have any, who the answer is for and what scope it should cover, how far each point should be expanded (a few sentences, a paragraph, full detail)?
|
|
166
|
+
**For Step-Back**: The specific question you want answered, paste the code, document, or design it is about if any, what higher-level principle or concept governs it?
|
|
167
|
+
**For Least-to-Most**: The full problem in one statement, paste the material the subproblems must reason over, what is the simplest thing that must be answered first, what does the final answer depend on?
|
|
168
|
+
**For Plan-and-Solve**: The problem with every number, unit, and constraint written out, paste the dataset or figures the calculation runs on if any, which values are given and which must be derived?
|
|
169
|
+
**For Chain of Thought**: The problem with all its conditions stated, paste the code, data, or document to reason over if any, what the reasoning steps should be?
|
|
170
|
+
**For Chain of Density**: Paste the full document to summarize, the fixed word budget every summary must hit, how many densification passes (the paper uses 5)?
|
|
171
|
+
**For Iterative Compression**: Paste the content to compress, where it should end up (word count, reading level, single paragraph), what should improve on each pass, how many passes and when to stop?
|
|
172
|
+
**For Self-Refine**: Paste the actual draft to improve, which dimensions the critique should cover (clarity, completeness, tone), what would make this output wrong or unusable?
|
|
173
|
+
**For CAI Critique-Revise**: Paste the actual output to be critiqued, the specific standard it must satisfy stated precisely enough to be checkable, what would make this output wrong or unusable?
|
|
174
|
+
**For Devil's Advocate**: The position, plan, or decision to attack, paste the proposal or memo that sets it out if you have one, which dimensions the attack should cover?
|
|
175
|
+
**For Pre-Mortem**: The project or decision being analyzed with its team, timeline, and goals, paste the plan or proposal document if you have one, how far in the future the imagined failure should be dated?
|
|
176
|
+
**For RCoT**: The question with every condition and constraint written out, paste the document those conditions come from if any, any implicit requirement not yet written into the question (units, deadlines, exclusions, edge cases) that a correct answer must still satisfy?
|
|
177
|
+
**For RPEF**: Paste the actual output sample to reverse-engineer, paste the input that produced it or confirm it is output-only, which details are one-off specifics that should become [PLACEHOLDER] variables?
|
|
178
|
+
**For Reverse Role**: What you want to achieve in one or two sentences, the domain of expertise to consult, questions one at a time or all at once, should it then do the task or synthesize a structured prompt for you to approve?
|
|
179
|
+
|
|
180
|
+
Every set above asks for the user's own material, because a framework that operates on an
|
|
181
|
+
artifact and never asks for it will invent one. Three frameworks are deliberately exempt:
|
|
182
|
+
**ReAct** (its material arrives as live tool output, not pasted text), **Reverse Role** (it
|
|
183
|
+
elicits everything through the interview and its template has no material slot), and
|
|
184
|
+
**RISE-IX** (its samples land in the EXAMPLES slot, which its own question already covers).
|
|
185
|
+
Do not add a material question to those three.
|
|
149
186
|
|
|
150
187
|
### 5. Apply Framework
|
|
151
188
|
|
|
152
189
|
Using gathered information:
|
|
153
190
|
1. Apply the appropriate framework structure from your knowledge of the framework
|
|
154
191
|
2. Map user's information to framework components
|
|
155
|
-
3. Fill missing elements with reasonable defaults
|
|
192
|
+
3. Fill missing elements with reasonable defaults — **with two exceptions, below**
|
|
156
193
|
4. Structure according to framework format
|
|
157
194
|
|
|
195
|
+
**Never default a fact about the user's world.** Their business, metrics, history, policies, staff, customers, data, or constraints are things only they know. A plausible-sounding default here is a fabrication the user may not notice before sending — asserting "our first price increase in three years" in an email to paying customers, or inventing a phone number in a published review reply. Where such a slot is unanswered, emit a visible `[you fill this in: <what is needed>]` placeholder and list every placeholder in your analysis section.
|
|
196
|
+
|
|
197
|
+
**Never soften or drop a prohibition.** If the user said something must not happen, it must survive into the emitted prompt as an explicit "Do not…" or "Never…" instruction. It cannot rely on a section header to carry the negation, because headers are stripped at emission (see step 6).
|
|
198
|
+
|
|
158
199
|
### 6. Present Improvements
|
|
159
200
|
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
201
|
+
Structure your output in this exact order:
|
|
202
|
+
|
|
203
|
+
**A. Analysis section** (comes first):
|
|
204
|
+
- Framework selected and why
|
|
205
|
+
- Changes made and reasoning
|
|
163
206
|
- Framework components applied
|
|
164
|
-
|
|
207
|
+
|
|
208
|
+
**B. Usage instructions** (transition block, immediately before the prompt):
|
|
209
|
+
|
|
210
|
+
> **Your revised prompt is ready.**
|
|
211
|
+
> - **New chat**: Copy the prompt below and paste it as your first message in a new conversation.
|
|
212
|
+
> - **Same chat**: Tell the assistant: *"Use the revised prompt you just provided as a new instruction and execute it."*
|
|
213
|
+
|
|
214
|
+
**C. The revised prompt** (comes last, in a fenced code block):
|
|
215
|
+
- Present as a clean, flat-text block inside triple backticks
|
|
216
|
+
- **No framework section headers** (no "BEFORE:", "BRIDGE:", "CONTEXT:", etc.) — these are scaffolding, not part of the deliverable
|
|
217
|
+
- **No indentation** beyond what the prompt itself genuinely requires
|
|
218
|
+
- **No markdown formatting** inside the block unless the prompt explicitly needs it (e.g., it asks for tables)
|
|
219
|
+
- The user must be able to copy the entire block contents and paste it verbatim with zero editing — the one exception is `[...]` placeholders for material or facts only the user can supply (see step 5). Keep these to a minimum, make each self-explanatory, and name them in the analysis section so the user knows exactly what to fill in before sending.
|
|
220
|
+
- **Nothing after the code block** — the revised prompt must be the absolute last element in the response. No trailing suggestions, tips, or follow-up text after the closing backticks.
|
|
165
221
|
|
|
166
222
|
### 7. Iterate
|
|
167
223
|
|
|
168
224
|
- Confirm improvements align with intent
|
|
169
225
|
- Refine based on feedback
|
|
170
|
-
- Switch or combine frameworks if needed
|
|
226
|
+
- Switch or combine frameworks if needed (see **Combining Frameworks** above)
|
|
171
227
|
- Continue until satisfactory
|
|
172
228
|
|
|
173
229
|
## Key Principles
|
|
@@ -214,25 +270,25 @@ Frameworks add structure — but structure has overhead. Skip them when:
|
|
|
214
270
|
**Improved Prompt** (BAB):
|
|
215
271
|
|
|
216
272
|
```
|
|
217
|
-
BEFORE (current state):
|
|
218
273
|
[Paste the current job posting here]
|
|
219
|
-
|
|
220
|
-
and generic language that doesn't reflect actual team culture.
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
6. Length: same or shorter than original — cut fluff, don't add it
|
|
274
|
+
|
|
275
|
+
The job posting above suffers from corporate-speak, passive voice, overly formal tone, and generic language that doesn't reflect actual team culture.
|
|
276
|
+
|
|
277
|
+
The rewritten version should sound like it was written by engineers, for engineers. Early-career developers should read it and think "I want to work there." It should feel honest, direct, and human — not like legal boilerplate.
|
|
278
|
+
|
|
279
|
+
Follow these rules:
|
|
280
|
+
- Replace all passive constructions with active voice.
|
|
281
|
+
- Convert corporate jargon to plain English (e.g., "leverage" → "use").
|
|
282
|
+
- Add one specific, concrete detail about the team or culture per section.
|
|
283
|
+
- Keep all technical requirements and must-haves verbatim — do not change these.
|
|
284
|
+
- Target reading level: conversational, not academic.
|
|
285
|
+
- Length: same or shorter than the original. Cut fluff, don't add it.
|
|
286
|
+
|
|
287
|
+
Now rewrite the job posting above.
|
|
234
288
|
```
|
|
235
289
|
|
|
290
|
+
Note that the emitted prompt carries no `BEFORE:` / `AFTER:` / `BRIDGE:` headers. The BAB structure shaped what the prompt says; it is not part of what the user receives.
|
|
291
|
+
|
|
236
292
|
## Usage Notes
|
|
237
293
|
|
|
238
294
|
- Always start by analyzing the original prompt
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ckelsoe/prompt-architect",
|
|
3
|
-
"version": "3.
|
|
4
|
-
"description": "Agent skill for analyzing and improving prompts using
|
|
3
|
+
"version": "3.4.0",
|
|
4
|
+
"description": "Agent skill for analyzing and improving prompts using 29 frameworks across 7 intent categories. Works with Claude Code, Gemini CLI, Cursor, Copilot, and 30+ Agent Skills compatible tools.",
|
|
5
5
|
"main": "skills/prompt-architect/SKILL.md",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"claude-code",
|
|
@@ -56,7 +56,7 @@
|
|
|
56
56
|
"prompt-architect": "scripts/install.js"
|
|
57
57
|
},
|
|
58
58
|
"engines": {
|
|
59
|
-
"node": ">=
|
|
59
|
+
"node": ">=20.19.0"
|
|
60
60
|
},
|
|
61
61
|
"files": [
|
|
62
62
|
"skills/",
|
|
@@ -81,7 +81,7 @@
|
|
|
81
81
|
"type": "skill",
|
|
82
82
|
"skillName": "prompt-architect",
|
|
83
83
|
"skillPath": "skills/prompt-architect",
|
|
84
|
-
"version": "3.
|
|
84
|
+
"version": "3.4.0",
|
|
85
85
|
"compatibility": {
|
|
86
86
|
"claudeCode": ">=1.0.0"
|
|
87
87
|
},
|
|
@@ -116,6 +116,7 @@
|
|
|
116
116
|
"ReAct",
|
|
117
117
|
"Chain-of-Thought",
|
|
118
118
|
"Chain-of-Density",
|
|
119
|
+
"Iterative-Compression",
|
|
119
120
|
"Self-Refine",
|
|
120
121
|
"CAI-Critique-Revise",
|
|
121
122
|
"Devils-Advocate",
|
package/scripts/install.js
CHANGED
|
@@ -46,18 +46,24 @@ const AGENTS = [
|
|
|
46
46
|
return true;
|
|
47
47
|
} catch { return false; }
|
|
48
48
|
},
|
|
49
|
-
installPath: () =>
|
|
49
|
+
installPath: (project) => project
|
|
50
|
+
? path.join(process.cwd(), '.gemini', 'skills', SKILL_NAME)
|
|
51
|
+
: path.join(os.homedir(), '.gemini', 'skills', SKILL_NAME),
|
|
50
52
|
format: 'skill',
|
|
51
|
-
hint: () => '~/.gemini/skills/',
|
|
53
|
+
hint: (project) => project ? '.gemini/skills/ (project)' : '~/.gemini/skills/',
|
|
52
54
|
},
|
|
53
55
|
{
|
|
54
56
|
id: 'agents',
|
|
55
57
|
name: 'Agent Skills (universal)',
|
|
56
58
|
detect: () => true, // Always available
|
|
57
59
|
alwaysShow: true,
|
|
58
|
-
installPath: () =>
|
|
60
|
+
installPath: (project) => project
|
|
61
|
+
? path.join(process.cwd(), '.agents', 'skills', SKILL_NAME)
|
|
62
|
+
: path.join(os.homedir(), '.agents', 'skills', SKILL_NAME),
|
|
59
63
|
format: 'skill',
|
|
60
|
-
hint: () =>
|
|
64
|
+
hint: (project) => project
|
|
65
|
+
? '.agents/skills/ (project, 30+ compatible agents)'
|
|
66
|
+
: '~/.agents/skills/ (30+ compatible agents)',
|
|
61
67
|
},
|
|
62
68
|
{
|
|
63
69
|
id: 'windsurf',
|
|
@@ -66,6 +72,7 @@ const AGENTS = [
|
|
|
66
72
|
return fs.existsSync(path.join(process.cwd(), '.windsurfrules')) ||
|
|
67
73
|
fs.existsSync(path.join(os.homedir(), '.windsurf'));
|
|
68
74
|
},
|
|
75
|
+
// .windsurfrules is inherently project-scoped, so --project is a no-op here.
|
|
69
76
|
installPath: () => path.join(process.cwd(), '.windsurfrules'),
|
|
70
77
|
format: 'adapter',
|
|
71
78
|
adapterFile: 'for-windsurf.md',
|
|
@@ -128,12 +135,24 @@ function copyRecursive(src, dest) {
|
|
|
128
135
|
const MARKER_START = '<!-- prompt-architect-start -->';
|
|
129
136
|
const MARKER_END = '<!-- prompt-architect-end -->';
|
|
130
137
|
|
|
131
|
-
function installSkillDir(sourcePath, destPath) {
|
|
138
|
+
function installSkillDir(sourcePath, destPath, force = false) {
|
|
132
139
|
const parentDir = path.dirname(destPath);
|
|
133
140
|
if (!fs.existsSync(parentDir)) fs.mkdirSync(parentDir, { recursive: true });
|
|
134
141
|
|
|
142
|
+
// A symlink here almost always means the user has pointed this path at a
|
|
143
|
+
// working copy they are actively editing. rmSync would silently delete the
|
|
144
|
+
// link, so refuse unless they explicitly opt in with --force.
|
|
145
|
+
let linkStat = null;
|
|
146
|
+
try { linkStat = fs.lstatSync(destPath); } catch { /* does not exist */ }
|
|
147
|
+
if (linkStat && linkStat.isSymbolicLink() && !force) {
|
|
148
|
+
throw new Error(
|
|
149
|
+
`${destPath} is a symlink — refusing to replace it. ` +
|
|
150
|
+
`Remove it first, or re-run with --force if you meant to overwrite.`
|
|
151
|
+
);
|
|
152
|
+
}
|
|
153
|
+
|
|
135
154
|
// Remove existing installation
|
|
136
|
-
if (fs.existsSync(destPath)) fs.rmSync(destPath, { recursive: true, force: true });
|
|
155
|
+
if (fs.existsSync(destPath) || linkStat) fs.rmSync(destPath, { recursive: true, force: true });
|
|
137
156
|
|
|
138
157
|
copyRecursive(sourcePath, destPath);
|
|
139
158
|
|
|
@@ -154,16 +173,19 @@ function installAdapter(adaptersPath, agent, destPath) {
|
|
|
154
173
|
|
|
155
174
|
if (agent.appendMode && fs.existsSync(destPath)) {
|
|
156
175
|
const existing = fs.readFileSync(destPath, 'utf8');
|
|
157
|
-
//
|
|
176
|
+
// Strip every previously-installed block, not just the first — without the
|
|
177
|
+
// `g` flag an older duplicate would survive and accumulate on each run.
|
|
158
178
|
const cleaned = existing.replace(
|
|
159
|
-
new RegExp(`\\n?${escapeRegex(MARKER_START)}[\\s\\S]*?${escapeRegex(MARKER_END)}\\n
|
|
179
|
+
new RegExp(`\\n?${escapeRegex(MARKER_START)}[\\s\\S]*?${escapeRegex(MARKER_END)}\\n?`, 'g'),
|
|
160
180
|
''
|
|
161
181
|
);
|
|
162
182
|
fs.writeFileSync(destPath, cleaned + markedContent, 'utf8');
|
|
163
183
|
} else {
|
|
164
184
|
const parentDir = path.dirname(destPath);
|
|
165
185
|
if (!fs.existsSync(parentDir)) fs.mkdirSync(parentDir, { recursive: true });
|
|
166
|
-
|
|
186
|
+
// Must write the *marked* content — an unmarked first copy is invisible to
|
|
187
|
+
// the strip above and could never be reclaimed on reinstall.
|
|
188
|
+
fs.writeFileSync(destPath, markedContent, 'utf8');
|
|
167
189
|
}
|
|
168
190
|
}
|
|
169
191
|
|
|
@@ -227,15 +249,19 @@ function showHelp() {
|
|
|
227
249
|
Options:
|
|
228
250
|
-a, --all Install to all detected agents
|
|
229
251
|
-p, --project Use project-local paths where applicable
|
|
230
|
-
-f, --force
|
|
252
|
+
-f, --force Also replace a symlinked install path (refused by default)
|
|
231
253
|
-y, --yes Accept defaults (all detected agents)
|
|
232
254
|
-h, --help Show this help
|
|
255
|
+
|
|
256
|
+
Note: installing always overwrites an existing skill directory. --force is
|
|
257
|
+
only needed when the target path is a symlink, which usually means you have
|
|
258
|
+
pointed it at a working copy on purpose.
|
|
233
259
|
`);
|
|
234
260
|
}
|
|
235
261
|
|
|
236
262
|
// ─── Non-Interactive Install ─────────────────────────────────────
|
|
237
263
|
|
|
238
|
-
function installNonInteractive(agentIds, sourcePath, adaptersPath, isProject) {
|
|
264
|
+
function installNonInteractive(agentIds, sourcePath, adaptersPath, isProject, force) {
|
|
239
265
|
const version = getVersion();
|
|
240
266
|
const results = [];
|
|
241
267
|
|
|
@@ -245,7 +271,7 @@ function installNonInteractive(agentIds, sourcePath, adaptersPath, isProject) {
|
|
|
245
271
|
const destPath = agent.installPath(isProject);
|
|
246
272
|
try {
|
|
247
273
|
if (agent.format === 'skill') {
|
|
248
|
-
installSkillDir(sourcePath, destPath);
|
|
274
|
+
installSkillDir(sourcePath, destPath, force);
|
|
249
275
|
} else {
|
|
250
276
|
installAdapter(adaptersPath, agent, destPath);
|
|
251
277
|
}
|
|
@@ -278,7 +304,7 @@ function installNonInteractive(agentIds, sourcePath, adaptersPath, isProject) {
|
|
|
278
304
|
|
|
279
305
|
// ─── Interactive Install ─────────────────────────────────────────
|
|
280
306
|
|
|
281
|
-
async function installInteractive(sourcePath, adaptersPath, isProject) {
|
|
307
|
+
async function installInteractive(sourcePath, adaptersPath, isProject, force) {
|
|
282
308
|
const p = require('@clack/prompts');
|
|
283
309
|
const version = getVersion();
|
|
284
310
|
|
|
@@ -352,7 +378,7 @@ async function installInteractive(sourcePath, adaptersPath, isProject) {
|
|
|
352
378
|
|
|
353
379
|
try {
|
|
354
380
|
if (agent.format === 'skill') {
|
|
355
|
-
installSkillDir(sourcePath, destPath);
|
|
381
|
+
installSkillDir(sourcePath, destPath, force);
|
|
356
382
|
} else {
|
|
357
383
|
installAdapter(adaptersPath, agent, destPath);
|
|
358
384
|
}
|
|
@@ -405,27 +431,27 @@ async function main() {
|
|
|
405
431
|
|
|
406
432
|
// Mode 1: Specific agent flags provided
|
|
407
433
|
if (specificAgents.length > 0) {
|
|
408
|
-
installNonInteractive(specificAgents, sourcePath, adaptersPath, isProject);
|
|
434
|
+
installNonInteractive(specificAgents, sourcePath, adaptersPath, isProject, flags.force);
|
|
409
435
|
return;
|
|
410
436
|
}
|
|
411
437
|
|
|
412
438
|
// Mode 2: --all flag
|
|
413
439
|
if (flags.all) {
|
|
414
440
|
const detected = AGENTS.filter(a => a.detect()).map(a => a.id);
|
|
415
|
-
installNonInteractive(detected, sourcePath, adaptersPath, isProject);
|
|
441
|
+
installNonInteractive(detected, sourcePath, adaptersPath, isProject, flags.force);
|
|
416
442
|
return;
|
|
417
443
|
}
|
|
418
444
|
|
|
419
445
|
// Mode 3: --yes flag (accept defaults = all detected, non-interactive)
|
|
420
446
|
if (flags.yes) {
|
|
421
|
-
const detected = AGENTS.filter(a => a.detect()
|
|
422
|
-
installNonInteractive(detected
|
|
447
|
+
const detected = AGENTS.filter(a => a.detect()).map(a => a.id);
|
|
448
|
+
installNonInteractive(detected, sourcePath, adaptersPath, isProject, flags.force);
|
|
423
449
|
return;
|
|
424
450
|
}
|
|
425
451
|
|
|
426
452
|
// Mode 4: Interactive
|
|
427
453
|
if (isInteractive) {
|
|
428
|
-
await installInteractive(sourcePath, adaptersPath, isProject);
|
|
454
|
+
await installInteractive(sourcePath, adaptersPath, isProject, flags.force);
|
|
429
455
|
return;
|
|
430
456
|
}
|
|
431
457
|
|
|
@@ -435,12 +461,16 @@ async function main() {
|
|
|
435
461
|
const version = getVersion();
|
|
436
462
|
const results = [];
|
|
437
463
|
|
|
438
|
-
|
|
439
|
-
|
|
464
|
+
// Install to every detected agent — this is the path most users hit via the
|
|
465
|
+
// postinstall hook, so restricting it to one agent would silently defeat the
|
|
466
|
+
// package's multi-agent support.
|
|
467
|
+
for (const agent of AGENTS.filter(a => a.detect())) {
|
|
440
468
|
const destPath = agent.installPath(isProject);
|
|
441
469
|
try {
|
|
442
470
|
if (agent.format === 'skill') {
|
|
443
|
-
installSkillDir(sourcePath, destPath);
|
|
471
|
+
installSkillDir(sourcePath, destPath, flags.force);
|
|
472
|
+
} else {
|
|
473
|
+
installAdapter(adaptersPath, agent, destPath);
|
|
444
474
|
}
|
|
445
475
|
results.push({ agent: agent.name, path: destPath, success: true });
|
|
446
476
|
} catch (err) {
|
package/scripts/test.js
CHANGED
|
@@ -63,50 +63,34 @@ test('CHANGELOG.md exists', () => {
|
|
|
63
63
|
if (!fs.existsSync('CHANGELOG.md')) throw new Error('Not found');
|
|
64
64
|
});
|
|
65
65
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
'co-star.md',
|
|
69
|
-
'risen.md',
|
|
70
|
-
'rise.md',
|
|
71
|
-
'tidd-ec.md',
|
|
72
|
-
'rtf.md',
|
|
73
|
-
'chain-of-thought.md',
|
|
74
|
-
'chain-of-density.md',
|
|
75
|
-
];
|
|
76
|
-
frameworks.forEach(f => {
|
|
77
|
-
const fpath = path.join('skills', 'prompt-architect', 'references', 'frameworks', f);
|
|
78
|
-
if (!fs.existsSync(fpath)) {
|
|
79
|
-
throw new Error(`Framework ${f} not found`);
|
|
80
|
-
}
|
|
81
|
-
});
|
|
82
|
-
});
|
|
66
|
+
const FRAMEWORKS_DIR = path.join('skills', 'prompt-architect', 'references', 'frameworks');
|
|
67
|
+
const TEMPLATES_DIR = path.join('skills', 'prompt-architect', 'assets', 'templates');
|
|
83
68
|
|
|
84
|
-
test('
|
|
85
|
-
const
|
|
86
|
-
|
|
87
|
-
'
|
|
88
|
-
|
|
89
|
-
'rise-ix_template.txt',
|
|
90
|
-
'tidd-ec_template.txt',
|
|
91
|
-
'rtf_template.txt',
|
|
92
|
-
'hybrid_template.txt',
|
|
93
|
-
];
|
|
94
|
-
templates.forEach(t => {
|
|
95
|
-
const tpath = path.join('skills', 'prompt-architect', 'assets', 'templates', t);
|
|
96
|
-
if (!fs.existsSync(tpath)) {
|
|
97
|
-
throw new Error(`Template ${t} not found`);
|
|
98
|
-
}
|
|
99
|
-
});
|
|
69
|
+
test('Framework reference docs exist', () => {
|
|
70
|
+
const docs = fs.readdirSync(FRAMEWORKS_DIR).filter(f => f.endsWith('.md'));
|
|
71
|
+
if (docs.length === 0) {
|
|
72
|
+
throw new Error('No framework reference docs found');
|
|
73
|
+
}
|
|
100
74
|
});
|
|
101
75
|
|
|
102
|
-
test('
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
76
|
+
test('Every framework has a template', () => {
|
|
77
|
+
// rise.md defines two independently-selectable frameworks.
|
|
78
|
+
const multi = { 'rise.md': ['rise-ie', 'rise-ix'] };
|
|
79
|
+
const templates = new Set(fs.readdirSync(TEMPLATES_DIR));
|
|
80
|
+
const missing = [];
|
|
81
|
+
|
|
82
|
+
for (const doc of fs.readdirSync(FRAMEWORKS_DIR).filter(f => f.endsWith('.md'))) {
|
|
83
|
+
const slugs = multi[doc] || [doc.replace(/\.md$/, '')];
|
|
84
|
+
for (const slug of slugs) {
|
|
85
|
+
if (!templates.has(`${slug}_template.txt`)) missing.push(`${slug}_template.txt`);
|
|
108
86
|
}
|
|
109
|
-
}
|
|
87
|
+
}
|
|
88
|
+
if (missing.length > 0) {
|
|
89
|
+
throw new Error(`Missing templates: ${missing.join(', ')}`);
|
|
90
|
+
}
|
|
91
|
+
if (!templates.has('hybrid_template.txt')) {
|
|
92
|
+
throw new Error('Missing hybrid_template.txt');
|
|
93
|
+
}
|
|
110
94
|
});
|
|
111
95
|
|
|
112
96
|
test('package.json has required fields', () => {
|
|
@@ -163,6 +147,70 @@ test('All adapter files exist', () => {
|
|
|
163
147
|
});
|
|
164
148
|
});
|
|
165
149
|
|
|
150
|
+
// SKILL.md <-> adapter drift guard.
|
|
151
|
+
// These two files are hand-maintained copies of the same instructions and have
|
|
152
|
+
// drifted before (the adapter was renumbered 1-7 while SKILL.md kept a duplicate
|
|
153
|
+
// step 4). Compare the sections that must stay identical.
|
|
154
|
+
test('Adapter has not drifted from SKILL.md', () => {
|
|
155
|
+
const skill = fs.readFileSync('skills/prompt-architect/SKILL.md', 'utf8');
|
|
156
|
+
const adapter = fs.readFileSync('adapters/system-prompt.md', 'utf8');
|
|
157
|
+
|
|
158
|
+
// 1. Step headings must match in number, order, and title.
|
|
159
|
+
const steps = s => (s.match(/^### \d+\. .+$/gm) || []).map(h => h.trim());
|
|
160
|
+
const skillSteps = steps(skill);
|
|
161
|
+
const adapterSteps = steps(adapter);
|
|
162
|
+
if (skillSteps.join('|') !== adapterSteps.join('|')) {
|
|
163
|
+
throw new Error(
|
|
164
|
+
`Step headings differ.\n SKILL.md: ${JSON.stringify(skillSteps)}\n adapter: ${JSON.stringify(adapterSteps)}`
|
|
165
|
+
);
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
// 2. Step numbers must be a clean 1..N with no duplicates.
|
|
169
|
+
const nums = skillSteps.map(h => parseInt(h.match(/^### (\d+)\./)[1], 10));
|
|
170
|
+
const expected = nums.map((_, i) => i + 1);
|
|
171
|
+
if (nums.join(',') !== expected.join(',')) {
|
|
172
|
+
throw new Error(`Step numbering is not sequential: ${nums.join(',')}`);
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
// 3. The intent-routing framework names must match between the two files.
|
|
176
|
+
const routed = s => [...s.matchAll(/\*\*([A-Za-z][A-Za-z0-9 +'’-]*?)\*\*/g)]
|
|
177
|
+
.map(m => m[1]).filter(n => /^[A-Z]/.test(n));
|
|
178
|
+
const missing = [...new Set(routed(skill))].filter(n => !routed(adapter).includes(n));
|
|
179
|
+
const routingNames = ['CO-STAR', 'RISEN', 'RISE-IE', 'RISE-IX', 'TIDD-EC', 'CTF', 'RTF',
|
|
180
|
+
'APE', 'BAB', 'RACE', 'CRISPE', 'BROKE', 'CARE', 'ReAct', 'RCoT', 'RPEF'];
|
|
181
|
+
const dropped = routingNames.filter(n => skill.includes(n) && !adapter.includes(n));
|
|
182
|
+
if (dropped.length > 0) {
|
|
183
|
+
throw new Error(`Frameworks in SKILL.md but missing from adapter: ${dropped.join(', ')}`);
|
|
184
|
+
}
|
|
185
|
+
void missing;
|
|
186
|
+
|
|
187
|
+
// 4. Load-bearing rules must be present in BOTH files.
|
|
188
|
+
// Checks 1-3 compare only step headings and framework names, so they cannot
|
|
189
|
+
// see prose drift. The adapter shipped without SKILL.md's entire output
|
|
190
|
+
// delivery contract -- the rules that define what the skill actually emits --
|
|
191
|
+
// while this test passed. Any rule that changes the emitted artifact goes here.
|
|
192
|
+
const invariants = [
|
|
193
|
+
'No framework section headers',
|
|
194
|
+
'scaffolding, not part of the deliverable',
|
|
195
|
+
'paste it verbatim with zero editing',
|
|
196
|
+
'the absolute last element in the response',
|
|
197
|
+
'Your revised prompt is ready.',
|
|
198
|
+
'Never stack more than two',
|
|
199
|
+
'Never default a fact about the user',
|
|
200
|
+
'Never soften or drop a prohibition',
|
|
201
|
+
// The worked example must demonstrate the emission rules, not violate them.
|
|
202
|
+
// The adapter previously shipped a BAB example with BEFORE:/AFTER:/BRIDGE: headers.
|
|
203
|
+
'Now rewrite the job posting above.',
|
|
204
|
+
];
|
|
205
|
+
const divergent = invariants.filter(r => skill.includes(r) !== adapter.includes(r));
|
|
206
|
+
if (divergent.length > 0) {
|
|
207
|
+
const detail = divergent
|
|
208
|
+
.map(r => `${JSON.stringify(r)} (SKILL.md: ${skill.includes(r) ? 'yes' : 'NO'}, adapter: ${adapter.includes(r) ? 'yes' : 'NO'})`)
|
|
209
|
+
.join('\n ');
|
|
210
|
+
throw new Error(`Emission-contract rules differ between SKILL.md and the adapter:\n ${detail}`);
|
|
211
|
+
}
|
|
212
|
+
});
|
|
213
|
+
|
|
166
214
|
// Agent Skills compliance tests
|
|
167
215
|
test('SKILL.md has Agent Skills required fields', () => {
|
|
168
216
|
const content = fs.readFileSync('skills/prompt-architect/SKILL.md', 'utf8');
|