@compilr-dev/sdk 0.27.0 → 0.28.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.
@@ -115,20 +115,53 @@ The delegated agent runs independently and returns results to the coordinator.`,
115
115
  },
116
116
  // ── Skills ──────────────────────────────────────────────────────────────
117
117
  {
118
- id: 'skills-overview',
119
- title: 'Skills Overview',
120
- keywords: ['skills', 'slash', 'command', '/'],
121
- content: `Skills are pre-built prompts that guide the agent through specific workflows.
118
+ id: 'macros-overview',
119
+ title: 'Macros Overview',
120
+ keywords: ['macros', 'macro', 'skills', 'slash', 'command', '/'],
121
+ content: `Macros are pre-built prompts that guide the agent through specific workflows. You
122
+ invoke one; it expands into a message.
122
123
 
123
- Use them by typing / followed by the skill name (e.g., /design, /build).
124
+ Use them by typing / followed by the macro name (e.g., /design, /build).
124
125
 
125
- Skills vary by project type. Software projects have: /design, /sketch, /prd, /architecture, /scaffold, /build, /refine, /session-notes.
126
+ Macros vary by project type. Software projects have: /design, /sketch, /prd, /architecture, /scaffold, /build, /refine, /session-notes.
126
127
 
127
128
  Research projects have: /research-scaffold, /outline, /literature-review, /draft-section, /peer-review.
128
129
 
129
130
  Business projects have: /business-vision, /market-analysis, /competitor-analysis, /financial-model, /pitch-outline, /business-review.
130
131
 
131
- Skills can be combined with your own instructions: type /design then add context.`,
132
+ Macros can be combined with your own instructions: type /design then add context.
133
+
134
+ **Macros are not Skills.** A macro is text YOU trigger. A Skill is a capability the MODEL
135
+ chooses from a catalogue and loads when it decides it is relevant — see "Skills". They were
136
+ called the same thing until recently, which is why older notes use "skill" for both.`,
137
+ },
138
+ {
139
+ id: 'skills',
140
+ title: 'Skills — Capabilities the Model Chooses',
141
+ keywords: ['skill', 'skills', 'SKILL.md', 'anthropic', 'agent skills', 'catalogue', 'grant'],
142
+ content: `A Skill is a capability the MODEL picks up when it decides the work calls for it —
143
+ not something you type.
144
+
145
+ Each agent is shown a CATALOGUE: one line per skill, name and description only. When the agent
146
+ judges a skill relevant it loads the body then, and not before, so an unused skill costs a line
147
+ of context rather than a document.
148
+
149
+ **Where they live**
150
+ - User scope: ~/.compilr-dev/skills/<name>/SKILL.md — personal, every project
151
+ - Project scope: <project>/.compilr/skills/<name>/SKILL.md — shared via version control
152
+
153
+ The format is Anthropic's Agent Skills format: YAML frontmatter (name, description) and a
154
+ markdown body. We read the frontmatter and the body; bundled references/, scripts/, templates/
155
+ and assets/ are not read yet.
156
+
157
+ **Granting them per agent**
158
+ In the agent editor's Skills section, tick the skills an agent may choose from. An agent you have
159
+ never restricted may choose any installed skill; once you save a selection it is limited to
160
+ exactly what is ticked, and an empty selection grants none.
161
+
162
+ **Skills are not macros.** A macro (/design, /build) is text YOU trigger. A skill is something
163
+ the model reaches for on its own. A skill you install is also typeable as a slash command, so one
164
+ folder can serve both purposes — see "Custom Skills".`,
132
165
  },
133
166
  {
134
167
  id: 'custom-skills',
@@ -157,8 +190,8 @@ A folder with a SKILL.md file containing YAML frontmatter (name, description) an
157
190
 
158
191
  **Desktop:** The Agents panel has a Skills section showing custom skills. Click the maximize button to open the SkillsView tab with full management (create, fork, bind/unbind, enable/disable, delete). Click a skill name to view/edit in the code editor.
159
192
 
160
- **Forking SDK skills:**
161
- You cannot override built-in skills directly. Instead, fork them: this creates a copy with your changes. Then bind a slash command to your fork (e.g., /design → design-acme). The capability bundle still loads based on the command name.
193
+ **Forking shipped macros:**
194
+ You cannot override a shipped macro directly — its name is reserved, so creating one is refused. Fork it instead: that copies it, and you edit the copy. Then bind a slash command to your fork (e.g., /design → design-acme).
162
195
 
163
196
  **Bindings:**
164
197
  Bindings remap slash commands to custom skills. Example: bind /design to your forked design-acme skill. When you type /design, it uses your custom prompt instead of the SDK version. Use the Bindings tab/section to manage them.
@@ -31,7 +31,7 @@ export const canvasMacro = defineSkill({
31
31
  - **carousel** — multiple slide "sheets"; author each slide as a top-level \`<section data-sheet>…</section>\`.
32
32
  - **board** — an infinite 2D coordinate space of absolutely-positioned node cards + inline-SVG connectors (mind-map / diagram / UI sketch). Wrap in \`<div data-board style="position:relative;width:Wpx;height:Hpx">\`.
33
33
 
34
- **Once you've picked the type, consult its craft guide for the design rules that make it good** — the \`infographic\` skill (hierarchy, grid, stat tiles, restrained color, correct charts), the \`carousel\` skill (one idea per slide, narrative arc, consistent master layout, 16:9 discipline), or the \`board\` skill (declared coordinate space, absolutely-positioned node cards, inline-SVG connectors, clustering). This general skill covers the mechanics (tools, structure, theme, Tweaks); the per-type skill covers the craft.
34
+ **Once you've picked the type, consult its craft guide for the design rules that make it good** — the \`infographic\` macro (hierarchy, grid, stat tiles, restrained color, correct charts), the \`carousel\` macro (one idea per slide, narrative arc, consistent master layout, 16:9 discipline), or the \`board\` macro (declared coordinate space, absolutely-positioned node cards, inline-SVG connectors, clustering). This general macro covers the mechanics (tools, structure, theme, Tweaks); the per-type macro covers the craft.
35
35
 
36
36
  ## STEPS
37
37
 
@@ -89,7 +89,7 @@ stored and what the markup actually uses.
89
89
  - Do NOT include \`<html>\`, \`<head>\`, \`<meta>\`, \`<!doctype>\`, or your own CSP — the host injects the sandbox and CSP. Just the body content + a \`<style>\` and optional \`<script>\`.
90
90
  - The sandbox is \`allow-scripts\` with NO same-origin and CSP \`default-src 'none'; script-src 'unsafe-inline'; style-src 'unsafe-inline'; img-src data: blob:\`. So: inline \`<style>\`/\`<script>\` only, no external fonts/CSS/JS/network, no remote images (use inline SVG or data: URIs).
91
91
  - **Match the app theme by default.** The host injects its live theme palette as CSS variables you MUST use instead of hardcoded colors: \`var(--canvas-bg)\` (page background), \`var(--canvas-fg)\` (text), \`var(--canvas-accent)\` and \`var(--canvas-secondary)\` (highlights), \`var(--canvas-muted)\` (secondary text), \`var(--canvas-border)\` (lines), \`var(--canvas-card)\` (raised surfaces). Only hardcode specific colors when the user explicitly asks for a particular palette or brand.
92
- - **Background — infographic & carousel: always set it EXPLICITLY to \`var(--canvas-bg)\`** on your outermost wrapper (and each \`<section data-sheet>\` for a carousel). Do NOT use \`background: transparent\` and do NOT hardcode a fixed color like \`#0a0a0a\`: transparent looks fine in-app but **exports to PDF/HTML on WHITE**, and a fixed color ignores the theme. **EXCEPTION — infinite board: do the OPPOSITE.** Keep the \`data-board\` root **transparent** (do not fill it) — the host paints a dot-grid backdrop that must show through, and filling it turns the infinite surface into a finite rectangle. On a board you style only the node cards; the space between them stays transparent. (See the \`board\` skill.)
92
+ - **Background — infographic & carousel: always set it EXPLICITLY to \`var(--canvas-bg)\`** on your outermost wrapper (and each \`<section data-sheet>\` for a carousel). Do NOT use \`background: transparent\` and do NOT hardcode a fixed color like \`#0a0a0a\`: transparent looks fine in-app but **exports to PDF/HTML on WHITE**, and a fixed color ignores the theme. **EXCEPTION — infinite board: do the OPPOSITE.** Keep the \`data-board\` root **transparent** (do not fill it) — the host paints a dot-grid backdrop that must show through, and filling it turns the infinite surface into a finite rectangle. On a board you style only the node cards; the space between them stays transparent. (See the \`board\` macro.)
93
93
  - Make it look intentional: a clear grid, strong type scale, generous spacing. Use \`var(--canvas-accent)\` sparingly for emphasis. Prefer inline SVG for shapes/charts/icons (fill/stroke with the theme vars).
94
94
  - For a **carousel**, wrap each slide in \`<section data-sheet>…</section>\` — a natural unit to add one per \`canvas_edit\` append.
95
95
 
@@ -201,7 +201,7 @@ export const infographicMacro = defineSkill({
201
201
  - Inline **SVG**, filled/stroked with the theme vars, a consistent stroke width. No emoji as primary iconography.
202
202
 
203
203
  ## Before you finish
204
- - Set the background explicitly to \`var(--canvas-bg)\` (see the canvas skill's export note).
204
+ - Set the background explicitly to \`var(--canvas-bg)\` (see the canvas macro's export note).
205
205
  - Add 2–4 **bound** Tweaks (accent color, headline size, a section toggle) — declared AND referenced in the HTML.
206
206
 
207
207
  ## Anti-patterns (fix on sight)
@@ -242,7 +242,7 @@ Structure the sequence like a story, not a list:
242
242
  - The same card/grid system reused slide to slide.
243
243
 
244
244
  ## Before you finish
245
- - Set \`background: var(--canvas-bg)\` on EACH \`<section data-sheet>\` (see the canvas skill's export note — transparent slides export white).
245
+ - Set \`background: var(--canvas-bg)\` on EACH \`<section data-sheet>\` (see the canvas macro's export note — transparent slides export white).
246
246
  - Add 2–4 **bound** Tweaks (accent color, title size, a toggle for footer/page numbers).
247
247
 
248
248
  ## Anti-patterns (fix on sight)
@@ -335,7 +335,7 @@ export const canvasStylesMacro = defineSkill({
335
335
  prompt: `The STYLE CATALOGUE for canvases — pick a coherent visual aesthetic instead of defaulting to the flat theme look. Design guidance; author with the canvas tools (see the \`canvas\` skill for mechanics). Applies to **infographic** and **carousel** (a board is a diagram surface — keep it theme-flat unless asked).
336
336
 
337
337
  ## How to use it
338
- - **Offer during the brief, don't over-ask.** In the canvas skill's Step 1, if the user hasn't named a style, include a SHORT aesthetic menu (2–4 fitting options from below) in the SAME \`propose_alternatives\`/\`ask_user\` round — never a separate interview. If they said "surprise me / your call", just pick the one that best fits the content and build.
338
+ - **Offer during the brief, don't over-ask.** In the canvas macro's Step 1, if the user hasn't named a style, include a SHORT aesthetic menu (2–4 fitting options from below) in the SAME \`propose_alternatives\`/\`ask_user\` round — never a separate interview. If they said "surprise me / your call", just pick the one that best fits the content and build.
339
339
  - **A style is a SYSTEM, not a trick.** Surfaces, borders, shadows, type, spacing, and accent all move together. Apply the whole recipe — half a recipe reads as a mistake.
340
340
 
341
341
  ## Hard constraints (every style — the sandbox is strict)
@@ -1,44 +1,78 @@
1
1
  /**
2
2
  * What a host actually SENDS when a user invokes a macro.
3
3
  *
4
- * ⚠️ THE TWO HOSTS SENT DIFFERENT THINGS FOR THE SAME COMMAND. `/design` in the CLI wrapped the
5
- * macro's prompt in ~20 lines of project context — do not scan the filesystem, the cwd is not the
6
- * project, save work items with `workitem_add` and documents with `project_document_add` rather
7
- * than writing files — while Desktop sent the prompt alone. Same name, same macro, materially
8
- * different instructions, so the same request produced an agent that interviewed you and filled
9
- * the backlog in one host and an agent that went looking for source files in the other.
4
+ * ⚠️ THE TWO HOSTS SENT DIFFERENT THINGS FOR THE SAME COMMAND. The CLI wrapped each of these
5
+ * macros in project context — do not scan the filesystem, the cwd is not the project, save work
6
+ * items with `workitem_add` and documents with `project_document_add` rather than writing files —
7
+ * while Desktop sent the prompt alone. Same names, same macros, materially different
8
+ * instructions, so the same request produced an agent that interviewed you and filled the backlog
9
+ * in one host and an agent that went looking for source files in the other.
10
10
  *
11
- * The prompt is shared data; what surrounds it was not. It is now.
11
+ * The prompts were always shared data; what surrounded them was not. It is now.
12
12
  *
13
- * This composes the MESSAGE only. The tool-gap preamble (`macroToolGap`) stays a separate,
14
- * host-applied prepend because it depends on which AGENT is being addressed, which is a thing
15
- * only the host knows.
13
+ * ⚠️ THE TEXT IS TRANSCRIBED, NOT REWRITTEN. Every block below was generated from the CLI's own
14
+ * template and asserted byte-identical to what it sent before the move, because a single reworded
15
+ * line here is a silent behaviour change in both hosts at once.
16
16
  *
17
- * Spec: project-docs/00-requirements/compilr-dev-sdk/macros-rename.md
17
+ * This composes the MESSAGE only. The tool-gap preamble (`macroToolGap`) stays a separate,
18
+ * host-applied prepend: it depends on which AGENT is addressed, which only the host knows.
18
19
  */
19
- /** What the host knows about the project a macro is being invoked against. */
20
+ /** What the host knows about the project a macro is invoked against. */
20
21
  export interface MacroProjectContext {
21
22
  id: string | number;
22
23
  name: string;
24
+ /** Absolute path on disk. `build` and `scaffold` write files and need it. */
25
+ path?: string;
26
+ }
27
+ /** A backlog item, for `build`. */
28
+ export interface MacroWorkItem {
29
+ itemId: string;
30
+ type: string;
31
+ priority: string;
32
+ title: string;
33
+ description?: string;
23
34
  }
24
35
  export interface MacroInvocationContext {
25
- /** Absent when no project is selected; the context block is then omitted. */
36
+ /** Absent when no project is selected; the context block is then omitted entirely. */
26
37
  project?: MacroProjectContext;
38
+ /** `prd` — the section the user named, if any. */
39
+ section?: string;
40
+ /** `session-notes` — the title the user gave, if any. */
41
+ noteTitle?: string;
42
+ /** `architecture` — the document type chosen, and how to name it back to the user. */
43
+ architecture?: {
44
+ docType: string;
45
+ displayType?: string;
46
+ };
47
+ /** `refine` — the item id, when refining one item rather than the whole backlog. */
48
+ refineItemId?: string;
49
+ /** `build` — the item to implement. Without it there is nothing to build. */
50
+ workItem?: MacroWorkItem;
51
+ /**
52
+ * `scaffold` — `factoryContext` is a pre-rendered block the host supplies because only it
53
+ * knows the Application Model's state; `isFactory` picks the closing instruction.
54
+ */
55
+ scaffold?: {
56
+ factoryContext?: string;
57
+ isFactory?: boolean;
58
+ };
27
59
  }
28
60
  export interface MacroInvocation {
29
61
  /** The text to send to the agent. */
30
62
  message: string;
31
- /** The text to show the user in the transcript, in place of the full message. */
63
+ /** The short line to show the user in place of the full message. */
32
64
  displayMessage: string;
33
65
  }
34
66
  /**
35
67
  * Compose the message for a macro invocation.
36
68
  *
37
- * A macro with no wrapper sends its prompt unchanged — that is the common case and stays the
38
- * default, so adding a macro does not require touching this file.
69
+ * A macro with no wrapper sends its prompt unchanged — the common case, and the default, so
70
+ * adding a macro needs no edit here. A macro WITH a wrapper falls back to the bare prompt when
71
+ * the host cannot supply what the wrapper names: better a plain prompt than one asserting a
72
+ * project, an item or a path that is not there.
39
73
  *
40
74
  * @param macroName the macro being invoked, e.g. `design`
41
75
  * @param prompt the macro's resolved prompt text
42
- * @param ctx what the host knows; an absent project omits the context block
76
+ * @param ctx what the host knows
43
77
  */
44
78
  export declare function buildMacroInvocation(macroName: string, prompt: string, ctx?: MacroInvocationContext): MacroInvocation;
@@ -1,26 +1,21 @@
1
1
  /**
2
2
  * What a host actually SENDS when a user invokes a macro.
3
3
  *
4
- * ⚠️ THE TWO HOSTS SENT DIFFERENT THINGS FOR THE SAME COMMAND. `/design` in the CLI wrapped the
5
- * macro's prompt in ~20 lines of project context — do not scan the filesystem, the cwd is not the
6
- * project, save work items with `workitem_add` and documents with `project_document_add` rather
7
- * than writing files — while Desktop sent the prompt alone. Same name, same macro, materially
8
- * different instructions, so the same request produced an agent that interviewed you and filled
9
- * the backlog in one host and an agent that went looking for source files in the other.
4
+ * ⚠️ THE TWO HOSTS SENT DIFFERENT THINGS FOR THE SAME COMMAND. The CLI wrapped each of these
5
+ * macros in project context — do not scan the filesystem, the cwd is not the project, save work
6
+ * items with `workitem_add` and documents with `project_document_add` rather than writing files —
7
+ * while Desktop sent the prompt alone. Same names, same macros, materially different
8
+ * instructions, so the same request produced an agent that interviewed you and filled the backlog
9
+ * in one host and an agent that went looking for source files in the other.
10
10
  *
11
- * The prompt is shared data; what surrounds it was not. It is now.
11
+ * The prompts were always shared data; what surrounded them was not. It is now.
12
12
  *
13
- * This composes the MESSAGE only. The tool-gap preamble (`macroToolGap`) stays a separate,
14
- * host-applied prepend because it depends on which AGENT is being addressed, which is a thing
15
- * only the host knows.
13
+ * ⚠️ THE TEXT IS TRANSCRIBED, NOT REWRITTEN. Every block below was generated from the CLI's own
14
+ * template and asserted byte-identical to what it sent before the move, because a single reworded
15
+ * line here is a silent behaviour change in both hosts at once.
16
16
  *
17
- * Spec: project-docs/00-requirements/compilr-dev-sdk/macros-rename.md
18
- */
19
- /**
20
- * ⚠️ "A NEW PROJECT" IS ASSERTED, NOT DETECTED, AND THAT IS DELIBERATE. `/design` is the
21
- * from-scratch macro — `/refine` is the one for a backlog that already exists — so invoking it
22
- * states the intent. Deriving it instead (counting work items, say) would make the prompt depend
23
- * on database state at send time, and be wrong the moment someone re-runs /design to redesign.
17
+ * This composes the MESSAGE only. The tool-gap preamble (`macroToolGap`) stays a separate,
18
+ * host-applied prepend: it depends on which AGENT is addressed, which only the host knows.
24
19
  */
25
20
  function designContext(project) {
26
21
  return `I want to design my project and create the backlog.
@@ -42,22 +37,250 @@ Save all documents and backlog items using the database - do NOT write files dir
42
37
  }
43
38
  const DESIGN_CLOSER = 'Please start by using todo_write to track the design phases, then begin with Phase 1: Vision. ' +
44
39
  'Use the ask_user tool to gather information efficiently.';
40
+ function sketchMessage(p, prompt) {
41
+ return `I want to quickly outline my project.
42
+
43
+ ## PROJECT CONTEXT (IMPORTANT)
44
+ - Project Name: ${p.name} (ID: ${String(p.id)})
45
+ - This is a NEW project being designed from scratch
46
+ - Do NOT scan the filesystem - the current directory is NOT the project
47
+ - Do NOT use detect_project, glob, read_file, or ls tools
48
+ - Focus ONLY on gathering requirements via ask_user questions
49
+
50
+ ## DOCUMENT STORAGE (CRITICAL)
51
+ Save all documents and backlog items using the database - do NOT write files directly.
52
+ - For backlog items: \`workitem_add({ type: "feature", title: "...", description: "..." })\`
53
+ - For documents: \`project_document_add({ doc_type: "prd", title: "...", content: "..." })\`
54
+ - Do NOT use write_file or edit tools for documentation
55
+
56
+ ${prompt}
57
+
58
+ Please start by asking me about the type of application I'm building using the ask_user_simple tool.`;
59
+ }
60
+ function refineMessage(p, prompt, userIntent, agentInstructions) {
61
+ return `${userIntent}
62
+
63
+ ## PROJECT CONTEXT (IMPORTANT)
64
+ - Project Name: ${p.name} (ID: ${String(p.id)})
65
+ - Do NOT scan the filesystem - the current directory is NOT the project
66
+ - Do NOT use detect_project, glob, read_file, or ls tools
67
+ - Use ONLY database tools to access project data
68
+
69
+ ## DOCUMENT STORAGE (CRITICAL)
70
+ Use database tools for all updates - do NOT write files directly.
71
+ - Use \`workitem_query\` to read items
72
+ - Use \`workitem_update\` to modify items
73
+ - Do NOT use write_file or edit tools
74
+
75
+ ${prompt}
76
+
77
+ ${agentInstructions}`;
78
+ }
79
+ function buildMessage(p, prompt, item) {
80
+ return `I want to implement backlog item ${item.itemId}: "${item.title}".
81
+
82
+ ## PROJECT CONTEXT (CRITICAL)
83
+ - Project Name: ${p.name} (ID: ${String(p.id)})
84
+ - **Project Directory: ${p.path ?? ''}**
85
+ - ALL files MUST be created/modified in this directory
86
+
87
+ ## WORK ITEM DETAILS
88
+ - Item ID: ${item.itemId}
89
+ - Type: ${item.type}
90
+ - Priority: ${item.priority}
91
+ - Description: ${item.description ?? 'No description provided'}
92
+
93
+ ## TOOL RESTRICTIONS (CRITICAL)
94
+ - Do NOT use detect_project or find_project_root
95
+ - Do NOT scan filesystem to detect project type
96
+ - The project path above is the ONLY source of truth for where to create/modify files
97
+ - Use \`project_document_get\` to read PRD and architecture docs from the database
98
+ - Use \`workitem_query\` to read related backlog items from the database
99
+ - Use \`workitem_update\` to update the item status when done
100
+
101
+ ## FILE OPERATIONS (CRITICAL)
102
+ When creating or modifying files:
103
+ - Use absolute paths starting with: ${p.path ?? ''}/
104
+ - Example: write_file({ path: "${p.path ?? ''}/src/index.ts", ... })
105
+ - NEVER use relative paths
106
+ - IGNORE the current working directory (cwd) - it may be different from the project!
107
+ - The user may have started the CLI from a different folder
108
+
109
+ ${prompt}
110
+
111
+ Please start by:
112
+ 1. Using todo_write to plan the implementation steps
113
+ 2. Reading project documents from the database (project_document_list, project_document_get)
114
+ 3. Updating the work item status to 'in_progress' using workitem_update
115
+ 4. Implementing the feature
116
+ 5. Updating the work item status to 'completed' when done`;
117
+ }
118
+ function sessionNotesMessage(p, prompt, titleInstruction) {
119
+ return `I want to create a session note capturing what we've done.
120
+
121
+ ## PROJECT CONTEXT
122
+ - Project Name: ${p.name} (ID: ${String(p.id)})
123
+
124
+ ## DOCUMENT STORAGE (CRITICAL)
125
+ Save session notes using the database - do NOT write files directly.
126
+ - Tool: \`project_document_add({ doc_type: "session-note", title: "...", content: "..." })\`
127
+ - The database is the source of truth for all project documents
128
+ - Do NOT use write_file or edit tools for documentation
129
+
130
+ ${prompt}
131
+
132
+ ${titleInstruction}
133
+
134
+ Review the conversation context to understand what was accomplished, then create the session note.`;
135
+ }
136
+ function prdMessage(p, prompt, sectionInstruction) {
137
+ return `I want to update the Product Requirements Document.
138
+
139
+ ## DOCUMENT STORAGE (CRITICAL)
140
+ Save PRD updates using the database - do NOT write files directly.
141
+ - Project: ${p.name} (ID: ${String(p.id)})
142
+ - Tool: \`project_document_add({ doc_type: "prd", title: "Product Requirements Document", content: "..." })\`
143
+ - The database is the source of truth for all project documents
144
+ - Do NOT use write_file or edit tools for documentation
145
+
146
+ ${prompt}
147
+
148
+ ${sectionInstruction}
149
+
150
+ Start by reading the existing PRD from the database using project_document_get({ doc_type: "prd" }). If no document exists yet, create a new one.`;
151
+ }
152
+ function architectureMessage(p, prompt, arch) {
153
+ return `I want to create architecture documentation.
154
+
155
+ ## DOCUMENT STORAGE (CRITICAL)
156
+ Save architecture documentation using the database - do NOT write files directly.
157
+ - Project: ${p.name} (ID: ${String(p.id)})
158
+ - Tool: \`project_document_add({ doc_type: "architecture", title: "...", content: "..." })\`
159
+ - The database is the source of truth for all project documents
160
+ - Do NOT use write_file or edit tools for documentation
161
+
162
+ ${prompt}
163
+
164
+ Please start by using project_document_list to find any existing PRD, and workitem_query to understand the project backlog. Then use ask_user to gather the information needed for this ${arch.docType} document.`;
165
+ }
166
+ function scaffoldMessage(p, prompt, factoryContext, closingInstruction) {
167
+ return `I want to create the project scaffold/foundation.
168
+
169
+ ## PROJECT CONTEXT (CRITICAL)
170
+ - Project Name: ${p.name} (ID: ${String(p.id)})
171
+ - **Project Directory: ${p.path ?? ''}**
172
+ - ALL files MUST be created in this directory
173
+ ${factoryContext}
174
+ ## TOOL RESTRICTIONS (CRITICAL)
175
+ - Do NOT use detect_project or find_project_root
176
+ - Do NOT scan filesystem to detect project type
177
+ - The project path above is the ONLY source of truth for where to create files
178
+ - Use \`project_document_get\` to read PRD and architecture docs from the database
179
+ - Use \`workitem_query\` to read backlog items from the database
180
+
181
+ ## FILE CREATION (CRITICAL)
182
+ When creating files:
183
+ - Use absolute paths starting with: ${p.path ?? ''}/
184
+ - Example: write_file({ path: "${p.path ?? ''}/package.json", ... })
185
+ - NEVER use relative paths
186
+ - IGNORE the current working directory (cwd) - it may be different from the project!
187
+ - The user may have started the CLI from a different folder
188
+
189
+ ${prompt}
190
+
191
+ ${closingInstruction}`;
192
+ }
45
193
  /**
46
194
  * Compose the message for a macro invocation.
47
195
  *
48
- * A macro with no wrapper sends its prompt unchanged — that is the common case and stays the
49
- * default, so adding a macro does not require touching this file.
196
+ * A macro with no wrapper sends its prompt unchanged — the common case, and the default, so
197
+ * adding a macro needs no edit here. A macro WITH a wrapper falls back to the bare prompt when
198
+ * the host cannot supply what the wrapper names: better a plain prompt than one asserting a
199
+ * project, an item or a path that is not there.
50
200
  *
51
201
  * @param macroName the macro being invoked, e.g. `design`
52
202
  * @param prompt the macro's resolved prompt text
53
- * @param ctx what the host knows; an absent project omits the context block
203
+ * @param ctx what the host knows
54
204
  */
55
205
  export function buildMacroInvocation(macroName, prompt, ctx = {}) {
56
- if (macroName === 'design' && ctx.project) {
57
- return {
58
- message: `${designContext(ctx.project)}\n${prompt}\n\n${DESIGN_CLOSER}`,
59
- displayMessage: 'Start the design process for my project.',
60
- };
206
+ const p = ctx.project;
207
+ if (!p)
208
+ return { message: prompt, displayMessage: `/${macroName}` };
209
+ switch (macroName) {
210
+ case 'design':
211
+ return {
212
+ message: `${designContext(p)}\n${prompt}\n\n${DESIGN_CLOSER}`,
213
+ displayMessage: 'Start the design process for my project.',
214
+ };
215
+ case 'sketch':
216
+ return { message: sketchMessage(p, prompt), displayMessage: 'Quick project outline.' };
217
+ case 'refine':
218
+ case 'refine-item': {
219
+ // Bound to a local so the narrowing survives into the template literals.
220
+ const itemId = ctx.refineItemId;
221
+ const userIntent = itemId !== undefined
222
+ ? `I want to refine backlog item ${itemId}.`
223
+ : 'I want to refine my project requirements.';
224
+ const agentInstructions = itemId !== undefined
225
+ ? `Please use workitem_query to find item "${itemId}", then guide me through refining it using workitem_update.`
226
+ : "Please start by using workitem_query with limit:10 to get an overview, then ask me what I'd like to focus on using ask_user_simple.";
227
+ return {
228
+ message: refineMessage(p, prompt, userIntent, agentInstructions),
229
+ displayMessage: userIntent,
230
+ };
231
+ }
232
+ case 'build': {
233
+ // Nothing to build without an item, and the whole wrapper is about one.
234
+ if (!ctx.workItem)
235
+ return { message: prompt, displayMessage: `/${macroName}` };
236
+ return {
237
+ message: buildMessage(p, prompt, ctx.workItem),
238
+ displayMessage: `Build ${ctx.workItem.itemId}: ${ctx.workItem.title}`,
239
+ };
240
+ }
241
+ case 'session-notes': {
242
+ const titleInstruction = ctx.noteTitle
243
+ ? `The session title is: "${ctx.noteTitle}"`
244
+ : 'Please ask me for a title using ask_user_simple, or generate one from the session summary.';
245
+ return {
246
+ message: sessionNotesMessage(p, prompt, titleInstruction),
247
+ displayMessage: ctx.noteTitle
248
+ ? `Create session note: "${ctx.noteTitle}"`
249
+ : 'Create a session note for this session.',
250
+ };
251
+ }
252
+ case 'prd': {
253
+ const valid = ['vision', 'scope', 'technical', 'success'];
254
+ const section = ctx.section ?? '';
255
+ const sectionInstruction = valid.includes(section)
256
+ ? `The user wants to update the "${section}" section specifically.`
257
+ : 'Ask the user which section they want to update using ask_user_simple.';
258
+ return {
259
+ message: prdMessage(p, prompt, sectionInstruction),
260
+ displayMessage: section
261
+ ? `Update PRD: ${section} section`
262
+ : 'Update the Product Requirements Document',
263
+ };
264
+ }
265
+ case 'architecture': {
266
+ if (!ctx.architecture)
267
+ return { message: prompt, displayMessage: `/${macroName}` };
268
+ return {
269
+ message: architectureMessage(p, prompt, ctx.architecture),
270
+ displayMessage: `Create ${ctx.architecture.displayType ?? ctx.architecture.docType} documentation.`,
271
+ };
272
+ }
273
+ case 'scaffold':
274
+ case 'factory-scaffold': {
275
+ const closingInstruction = macroName === 'factory-scaffold' || ctx.scaffold?.isFactory
276
+ ? 'Start by checking the Application Model with app_model_get. If no model exists, read the PRD with project_document_get and build the model incrementally using app_model_update. Then generate with factory_scaffold.'
277
+ : 'Start by reading the project documents from the database using project_document_list and project_document_get. Then create a plan with todo_write before generating files.';
278
+ return {
279
+ message: scaffoldMessage(p, prompt, ctx.scaffold?.factoryContext ?? '', closingInstruction),
280
+ displayMessage: 'Create project scaffold.',
281
+ };
282
+ }
283
+ default:
284
+ return { message: prompt, displayMessage: `/${macroName}` };
61
285
  }
62
- return { message: prompt, displayMessage: `/${macroName}` };
63
286
  }
@@ -18,9 +18,9 @@ export const designMacro = defineSkill({
18
18
  - Need to create initial backlog
19
19
 
20
20
  ## When NOT to Use
21
- - Project already has requirements → use refine skill
22
- - Quick project outline needed → use sketch skill
23
- - Just need to update PRD → use prd skill
21
+ - Project already has requirements → tell the user to run /refine
22
+ - Quick project outline needed → tell the user to run /sketch
23
+ - Just need to update PRD → tell the user to run /prd
24
24
 
25
25
  ## PHASES
26
26
 
@@ -104,9 +104,9 @@ export const refineMacro = defineSkill({
104
104
  - Adding missing items to backlog
105
105
 
106
106
  ## When NOT to Use
107
- - No backlog exists yet → use design skill
108
- - Quick outline needed → use sketch skill
109
- - Refining single item → use refine-item skill
107
+ - No backlog exists yet → tell the user to run /design
108
+ - Quick outline needed → tell the user to run /sketch
109
+ - Refining single item → tell the user to run /refine-item
110
110
 
111
111
  ## STARTUP
112
112
 
@@ -182,9 +182,9 @@ export const sketchMacro = defineSkill({
182
182
  - Initial brainstorming session
183
183
 
184
184
  ## When NOT to Use
185
- - Detailed requirements needed → use design skill
186
- - Project already has backlog → use refine skill
187
- - Single item focus → use refine-item skill
185
+ - Detailed requirements needed → tell the user to run /design
186
+ - Project already has backlog → tell the user to run /refine
187
+ - Single item focus → tell the user to run /refine-item
188
188
 
189
189
  STEPS:
190
190
  1. Use todo_write with 6 tasks (one per question)
@@ -221,9 +221,9 @@ export const refineItemMacro = defineSkill({
221
221
  - Changing priority of specific item
222
222
 
223
223
  ## When NOT to Use
224
- - Multiple items need refinement → use refine skill
225
- - No items exist yet → use design or sketch skill
226
- - Ready to implement → use build skill
224
+ - Multiple items need refinement → tell the user to run /refine
225
+ - No items exist yet → tell the user to run /design or /sketch
226
+ - Ready to implement → tell the user to run /build
227
227
 
228
228
  ## STARTUP
229
229
 
@@ -290,9 +290,9 @@ export const architectureMacro = defineSkill({
290
290
  - Recording technical decisions
291
291
 
292
292
  ## When NOT to Use
293
- - Need product requirements → use design or prd skill
294
- - Need to implement features → use build skill
295
- - Just want to understand existing code → use explain skill
293
+ - Need product requirements → tell the user to run /design or /prd
294
+ - Need to implement features → tell the user to run /build
295
+ - Just want to understand existing code → tell the user to run /explain
296
296
 
297
297
  ## DOCUMENT TYPE: {{doc_type}}
298
298
  {{#if custom_topic}}Custom Topic: {{custom_topic}}{{/if}}
@@ -434,9 +434,9 @@ export const prdMacro = defineSkill({
434
434
  - Refining vision or scope
435
435
 
436
436
  ## When NOT to Use
437
- - No PRD exists yet → use design skill first
438
- - Need architecture docs → use architecture skill
439
- - Need session summary → use session-notes skill
437
+ - No PRD exists yet → tell the user to run /design first
438
+ - Need architecture docs → tell the user to run /architecture
439
+ - Need session summary → tell the user to run /session-notes
440
440
 
441
441
  ## STARTUP
442
442
 
@@ -519,8 +519,8 @@ export const sessionNotesMacro = defineSkill({
519
519
  - Need to capture decisions for future reference
520
520
 
521
521
  ## When NOT to Use
522
- - Need product requirements → use prd skill
523
- - Need architecture docs → use architecture skill
522
+ - Need product requirements → tell the user to run /prd
523
+ - Need architecture docs → tell the user to run /architecture
524
524
  - In the middle of active work
525
525
 
526
526
  ## STARTUP
@@ -614,10 +614,10 @@ export const buildMacro = defineSkill({
614
614
  - Ready to write code for a feature
615
615
 
616
616
  ## When NOT to Use
617
- - Item is too vague → use refine-item skill first
618
- - No backlog exists → use design or sketch skill
619
- - Just exploring code → use code-navigation skill
620
- - Need to fix a bug → use debug skill
617
+ - Item is too vague → tell the user to run /refine-item first
618
+ - No backlog exists → tell the user to run /design or /sketch
619
+ - Just exploring code → tell the user to run /code-navigation
620
+ - Need to fix a bug → tell the user to run /debug
621
621
 
622
622
  ## CRITICAL: PROJECT DIRECTORY
623
623
 
@@ -711,9 +711,9 @@ export const scaffoldMacro = defineSkill({
711
711
  - Need basic project structure
712
712
 
713
713
  ## When NOT to Use
714
- - Project already has structure → use build skill
715
- - Need requirements first → use design skill
716
- - Modifying existing project → use appropriate skill
714
+ - Project already has structure → tell the user to run /build
715
+ - Need requirements first → tell the user to run /design
716
+ - Modifying existing project → tell the user to run /appropriate
717
717
 
718
718
  ## FACTORY CHECK (TRY THIS FIRST)
719
719
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@compilr-dev/sdk",
3
- "version": "0.27.0",
3
+ "version": "0.28.0",
4
4
  "description": "Universal agent runtime for building AI-powered applications",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",