1---2name: ase-code-craft3description: Craft Source: Use when user wants to "create", "add", or "craft" a new feature from scratch.4---5
6@${CLAUDE_SKILL_DIR}/../../meta/ase-control.md
7@${CLAUDE_SKILL_DIR}/../../meta/ase-skill.md
8@${CLAUDE_SKILL_DIR}/../../meta/ase-dialog.md
9@${CLAUDE_SKILL_DIR}/../../meta/ase-getopt.md
10
11<skill name="ase-code-craft">
12Craft Source Code
13</skill>
14
15<expand name="getopt"
16 arg1="ase-code-craft"
17 arg2="--auto|-a --dry|-d --quick|-Q --next|-n=(none|DONE|EDIT|PREFLIGHT|IMPLEMENT)...">
18 $ARGUMENTS
19</expand>
20
21<if condition="<getopt-option-quick/> is equal `true`">
22The `--quick`/`-Q` flag is a *shorthand alias*: set <getopt-option-auto/>
23to `true`, <getopt-option-dry/> to `true`, and <getopt-option-next/> to
24`IMPLEMENT,DELETE`. Do not output anything.
25</if>
26
27<objective>
28From scratch *craft* the following feature:
29<feature><getopt-arguments/></feature>
30</objective>
31
32@${CLAUDE_SKILL_DIR}/../../meta/ase-format-task.md
33@${CLAUDE_SKILL_DIR}/../../meta/ase-tenets.md
34
35Procedure
36---------
37
38You *MUST* *NOT* call `Edit`, `Write`, `NotebookEdit`, or any
39filesystem-modifying tool during this entire skill. The *only*
40permitted way to persist artifacts is via `ase_task_save(...)`.
41
42<flow>
43
441. <step id="STEP 1: Reason About Feature">
45
46 1. <if condition="
47 <feature/> matches the regexp `^[a-zA-Z][a-zA-Z0-9_-]*$`
48 ">
49 Set <ase-task-id><feature/></ase-task-id> (set task id to feature)
50 and <feature></feature> (set feature empty), call the
51 `ase_task_id(id: "<ase-task-id/>", session: "<ase-session-id/>")` tool
52 from the `ase` MCP server to switch the task, and then only
53 output the following <template/>:
54
55 <template>
56 ⧉ **ASE**: ◉ task: **<ase-task-id/>**, ▶ status: **task given**
57 </template>
58 </if>
59
60 2. <if condition="
61 <feature/> has the format `<id/>: <text/>` AND
62 <id/> matches the regexp `^[a-zA-Z][a-zA-Z0-9_-]*$`
63 ">
64 Set <feature><text/></feature> and
65 <ase-task-id><id/></ase-task-id> and call the `ase_task_id(id:
66 "<ase-task-id/>", session: "<ase-session-id/>")` tool from the
67 `ase` MCP server to implicitly switch the task. Do not output
68 anything.
69 </if>
70
71 3. <if condition="<feature/> is empty">
72 Ask the user interactively, without a special tool, for the
73 initial feature with a single question:
74
75 `**No feature known yet. What is the feature you want to craft?**`
76
77 Then set <feature/> to the response of the user.
78 </if>
79
80 4. <if condition="
81 <ase-task-id/> is equal `default` and
82 <feature/> is not empty
83 ">
84 Set <ase-task-id/> to a unique task id, derived from <feature/>,
85 which consists of two lower-case words concatenated with a
86 `-` character. Then call the `ase_task_id(id: "<ase-task-id/>",
87 session: "<ase-session-id/>")` tool from the `ase` MCP server to
88 implicitly switch the task. Do not output anything.
89 </if>
90
91 5. Report the task and feature with the following <template/>:
92
93 <template>
94 ⧉ **ASE**: ◉ task: **<ase-task-id/>**
95 ⧉ **ASE**: ⇌ feature: **<feature/>**
96 </template>
97
98 6. Figure out what the requested <feature/> to be crafted is about.
99
100 7. Ask the user for clarification if the goal of this crafting is too
101 unclear.
102
103 8. Do not output anything in this step, unless you asked the user.
104
105 </step>
106
1072. <step id="STEP 2: Investigate Code Base">
108
109 1. Check the existing source files for all code which is related to the
110 requested new <feature/>.
111
112 2. Check the architecture of the existing code base to understand the
113 overall structures and dynamics.
114
115 3. Do not output anything in this STEP 2.
116
117 </step>
118
1193. <step id="STEP 3: Internalize Crafting Tenets">
120
121 1. You *MUST* internalize and strictly honor the **GENERIC TENETS**,
122 and the **CRAFTING TENETS** of the **ASE Tenets** when updating
123 in the following. Do not output anything.
124
125 2. Do not output anything in this STEP 3.
126
127 </step>
128
1294. <step id="STEP 4: Choose Feature Crafting Approaches">
130
131 You *MUST* perform the following sub-steps *internally* and *without
132 any output* until and including the recommendation decision. Only
133 sub-steps 4-6 below are allowed to produce output, and only if
134 <getopt-option-auto/> is equal `false`. If <getopt-option-auto/> is
135 equal `true`, *skip* the reporting sub-steps 4-6 entirely (perform
136 no output at all) to speed up processing.
137
138 1. *Propose* corresponding *feature approach*, including optionally,
139 some *alternative* feature approaches. Do *not* output anything
140 in this sub-step.
141
142 2. *Reflect* on and *critique* the proposed approaches by deriving,
143 per approach, a small set of concrete *pros* and *cons*. Do
144 *not* output anything in this sub-step.
145
146 3. Based on the reflection, *decide* which approach to recommend
147 and annotate it with an <annotation/> of
148 ` ⚝ **RECOMMENDATION** ⚝`. All other approaches receive an
149 empty <annotation/>. Do *not* output anything in this sub-step.
150
151 4. Indicate start of reporting by showing the following <template/>:
152
153 <template>
154 <ase-tpl-head title="APPROACHES"/>
155 </template>
156
157 5. Now report each approach with the following <template/>,
158 inlining its pros/cons derived in sub-step 2, and do not output
159 anything else in this step:
160
161 <template>
162 ● **APPROACH A<n/>**<annotation/>: **<summary/>**
163 ○ [...]
164 ⊕ *PRO*: [...]
165 ⊖ *CON*: [...]
166 </template>
167
168 Hints:
169
170 - Give a short one-sentence <summary/> of the feature
171 approach plus *precise* and *ultra brief and concise*
172 feature information. Try to keep the number of bullet points
173 (`○ [...]`) in the range of 1-4.
174
175 6. Indicate end of reporting by showing the following <template/>:
176
177 <template>
178 <ase-tpl-foot title="APPROACHES"/>
179 </template>
180
181 7. <if condition="<getopt-option-auto/> is not equal `true`">
182
183 In the following, you *MUST* *NOT* use your built-in
184 <user-dialog-tool/> tool! Instead, you *MUST* just show a
185 custom dialog according to the expanded `custom-dialog`
186 definition. You *MUST* closely follow this definition.
187
188 Let the user choose the preferred approach A<n/> by raising
189 a question with the following custom dialog, where per
190 approach A<n/>, you determine an ultra brief summary
191 <short-summary/> and then use the answer option `A<n/>:
192 ⚝ **RECOMMENDATION** ⚝ - <short-summary/>` for your
193 recommended approach plus zero or more answer options `A<n/>:
194 <short-summary/>` for all other approaches:
195
196 <expand name="custom-dialog" arg1="--no-other">
197 Select Approach: Select your preferred crafting approach to follow?
198 A<n/>: <short-summary/>
199 [...]
200 </expand>
201
202 </if>
203 <else>
204
205 Set <n/> to the number of the feature approach A<n/> you recommend.
206 Output a hint with the following <template/>:
207
208 <template>
209 ⧉ **ASE**: ◉ task: **<ase-task-id/>**, ▶ status: **auto-chosen approach A<n/>**
210 </template>
211
212 </else>
213
214 </step>
215
2165. <step id="STEP 5: Compose Feature Crafting Plan">
217
218 1. *Compose a feature plan* for the chosen feature A<n/> by
219 closely aligning to the existing architecture and the existing
220 code base. Use the <format/> defined for a task plan and inject
221 the information from feature A<n/> and all derived realization
222 decisions into it. Store the resulting task plan in <content/>.
223
224 If a `CHANGELOG.md` file exists in the project (or in any
225 affected sub-package), the plan *MUST* include, as part of its
226 `## ※ CHANGES` section, an explicit bullet point describing
227 the addition of a corresponding new entry to that `CHANGELOG.md`
228 file, aligned with its existing style and conventions.
229
230 <if condition="<getopt-option-dry/> is equal `true`">
231 You *MUST* completely omit the `## VERIFICATION` section
232 (including its heading and all of its bullet points) from
233 <content/>.
234 </if>
235
236 You *MUST* *NOT* call `Edit`, `Write`, `NotebookEdit`, or any
237 filesystem-modifying tool during this step.
238
239 2. Call the `ase_timestamp(format: "yyyy-LL-dd HH:mm")` tool of the
240 `ase` MCP server and use the `text` field of its response for
241 <timestamp-created/> and <timestamp-modified/> information. Then
242 insert the current <ase-task-id/>, <timestamp-created/>, and
243 <timestamp-modified/> information and calculate the number of
244 words <words/> of <content/>.
245
246 3. You then *MUST* *save* the resulting plan content with the
247 `ase_task_save(id: "<ase-task-id/>", text: "<content/>")`.
248
249 4. Output a hint with the following <template/>:
250
251 <template>
252 ⧉ **ASE**: ◉ task: **<ase-task-id/>**, ✪ plan: **<words/>** words, ▶ status: **plan created**
253 </template>
254
255 5. Directly pass-through control to the next skill:
256
257 Treat <getopt-option-next/> as a comma-separated chronological
258 list of pre-selected next-step tokens. *Peek* the *first* token
259 as <head/> (or `none` if the list is `none`/empty).
260 Set <args>--int-reuse-task</args>.
261
262 1. <if condition="<head/> is equal `DONE`">
263 Consume the head: set <getopt-option-next/> to the remaining
264 tokens (joined back with `,`, or `none` if empty). `DONE`
265 means the freshly composed plan is finalized as-is, so do
266 *not* hand off to `ase-task-edit`. Only output the following
267 <template/> and then *STOP*. Do *not* implement the plan.
268
269 <template>
270 ⧉ **ASE**: ◉ task: **<ase-task-id/>**, ✪ plan: **<words/>** words, ▶ status: **plan finalized -- done**
271 </template>
272 </if>
273
274 2. <elseif condition="<head/> is equal `IMPLEMENT`">
275 Consume the head: set <getopt-option-next/> to the remaining
276 tokens (joined back with `,`, or `none` if empty).
277 <if condition="<getopt-option-next/> is not equal `none`">
278 Set <args><args/> --next <getopt-option-next/></args>
279 </if>
280 Call the tool `Skill(skill: "ase:ase-task-implement", args: "<args/>")`
281 to *implement* the freshly composed plan, bypassing `ase-task-edit`.
282 </elseif>
283
284 3. <elseif condition="<head/> is equal `PREFLIGHT`">
285 Consume the head: set <getopt-option-next/> to the remaining
286 tokens (joined back with `,`, or `none` if empty).
287 <if condition="<getopt-option-next/> is not equal `none`">
288 Set <args><args/> --next <getopt-option-next/></args>
289 </if>
290 Call the tool `Skill(skill: "ase:ase-task-preflight", args: "<args/>")`
291 to *preflight* the freshly composed plan, bypassing `ase-task-edit`.
292 </elseif>
293
294 4. <else>
295 Hand off to `ase-task-edit`.
296 <if condition="<head/> is equal `EDIT`">
297 Consume the head: set <getopt-option-next/> to the remaining
298 tokens (joined back with `,`, or `none` if empty). `EDIT`
299 is this skill's own dispatch token, *not* part of
300 `ase-task-edit`'s `--next` vocabulary, so it must be
301 stripped here rather than forwarded.
302 </if>
303 All remaining tokens are `ase-task-edit`'s own vocabulary
304 and are forwarded verbatim, so `ase-task-edit` consumes its
305 own head itself.
306 <if condition="<getopt-option-next/> is not equal `none`">
307 Set <args><args/> --next <getopt-option-next/></args>
308 </if>
309 Then call the tool `Skill(skill: "ase:ase-task-edit", args: "<args/>")`.
310 </else>
311
312 </step>
313
314</flow>