@hatchway/cli 0.50.55 → 0.50.57

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/dist/index.js CHANGED
@@ -4,12 +4,12 @@ import { query } from '@anthropic-ai/claude-agent-sdk';
4
4
  import { Codex } from '@openai/codex-sdk';
5
5
  import { a as streamLog, f as fileLog, i as initRunnerLogger, s as setFileLoggerTuiMode, b as getLogger } from './chunks/runner-logger-instance-Dj_JMznn.js';
6
6
  import { config as config$1 } from 'dotenv';
7
- import path$1, { resolve, relative, isAbsolute, dirname, join as join$1 } from 'node:path';
7
+ import path$1, { resolve, relative, isAbsolute, dirname, join } from 'node:path';
8
8
  import { fileURLToPath } from 'node:url';
9
- import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
9
+ import { existsSync, readdirSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
10
10
  import { readFile } from 'fs/promises';
11
11
  import * as path from 'path';
12
- import { join } from 'path';
12
+ import { join as join$1 } from 'path';
13
13
  import WebSocket$1, { WebSocketServer, WebSocket } from 'ws';
14
14
  import { drizzle } from 'drizzle-orm/node-postgres';
15
15
  import pg from 'pg';
@@ -130,14 +130,80 @@ function createProjectScopedPermissionHandler(projectDirectory) {
130
130
  }
131
131
 
132
132
  /**
133
- * Skills management for Claude Code projects.
133
+ * Skills provisioning for the Claude Agent SDK.
134
134
  *
135
- * This module handles copying bundled skills to project directories
136
- * so they can be loaded by Claude Code when running in that project.
135
+ * Platform-level skills are packaged as a local plugin that the SDK
136
+ * discovers via the `plugins` option. The plugin lives within the runner at:
137
+ * src/lib/skills/platform-plugin/ (dev)
138
+ * dist/lib/skills/platform-plugin/ (built)
139
+ *
140
+ * The plugin contains:
141
+ * .claude-plugin/plugin.json - Plugin manifest
142
+ * skills/<name>/SKILL.md - Individual skill files
143
+ *
144
+ * The SDK loads skill descriptions into context and invokes full content
145
+ * on-demand when the agent determines a skill is relevant.
137
146
  */
138
- // Get the directory of this module
139
- const __filename$2 = fileURLToPath(import.meta.url);
140
- dirname(__filename$2);
147
+ const __filename$3 = fileURLToPath(import.meta.url);
148
+ const __dirname$3 = dirname(__filename$3);
149
+ const CODEX_ONLY_SKILLS = new Set(['todo-workflow-codex']);
150
+ /**
151
+ * Find the platform plugin directory.
152
+ */
153
+ function findPluginDir() {
154
+ const candidates = [
155
+ join(__dirname$3, 'skills', 'platform-plugin'), // dev: src/lib/skills/platform-plugin/
156
+ join(__dirname$3, 'lib', 'skills', 'platform-plugin'), // bundle: dist/lib/skills/platform-plugin/
157
+ join(__dirname$3, '..', 'src', 'lib', 'skills', 'platform-plugin'), // bundle fallback
158
+ ];
159
+ for (const dir of candidates) {
160
+ const manifestPath = join(dir, '.claude-plugin', 'plugin.json');
161
+ if (existsSync(manifestPath)) {
162
+ return dir;
163
+ }
164
+ }
165
+ return null;
166
+ }
167
+ let _pluginDir;
168
+ /**
169
+ * Get the absolute path to the platform plugin directory.
170
+ * Pass this to the SDK's `plugins` option as `{ type: "local", path: <this> }`.
171
+ */
172
+ function getPlatformPluginDir() {
173
+ if (_pluginDir === undefined) {
174
+ _pluginDir = findPluginDir();
175
+ if (_pluginDir) {
176
+ const names = listBundledSkills();
177
+ process.stderr.write(`[skills] Platform plugin: ${_pluginDir} (${names.length} skills: [${names.join(', ')}])\n`);
178
+ }
179
+ else {
180
+ process.stderr.write('[skills] Platform plugin directory not found\n');
181
+ Sentry.logger.error('Platform plugin directory not found — agent will run without core skills', {
182
+ candidatePaths: [
183
+ join(__dirname$3, 'skills', 'platform-plugin'),
184
+ join(__dirname$3, 'lib', 'skills', 'platform-plugin'),
185
+ join(__dirname$3, '..', 'src', 'lib', 'skills', 'platform-plugin'),
186
+ ].join(', '),
187
+ __dirname: __dirname$3,
188
+ });
189
+ }
190
+ }
191
+ return _pluginDir;
192
+ }
193
+ /**
194
+ * List available skill names from the plugin.
195
+ */
196
+ function listBundledSkills() {
197
+ const pluginDir = _pluginDir ?? findPluginDir();
198
+ if (!pluginDir)
199
+ return [];
200
+ const skillsPath = join(pluginDir, 'skills');
201
+ if (!existsSync(skillsPath))
202
+ return [];
203
+ return readdirSync(skillsPath, { withFileTypes: true })
204
+ .filter(d => d.isDirectory() && !CODEX_ONLY_SKILLS.has(d.name))
205
+ .map(d => d.name);
206
+ }
141
207
 
142
208
  var __defProp$1 = Object.defineProperty;
143
209
  var __getOwnPropNames$1 = Object.getOwnPropertyNames;
@@ -197,21 +263,21 @@ var init_tags$1 = __esm$1({
197
263
  inputType: "select",
198
264
  options: [
199
265
  {
200
- value: "claude-sonnet-4-5",
201
- label: "Claude Sonnet 4.5",
266
+ value: "claude-sonnet-4-6",
267
+ label: "Claude Sonnet 4.6",
202
268
  description: "Anthropic Claude - Balanced performance and speed",
203
269
  logo: "/claude.png",
204
270
  provider: "claude-code",
205
- model: "claude-sonnet-4-5",
271
+ model: "claude-sonnet-4-6",
206
272
  sdk: "agent"
207
273
  },
208
274
  {
209
- value: "claude-opus-4-5",
210
- label: "Claude Opus 4.5",
275
+ value: "claude-opus-4-6",
276
+ label: "Claude Opus 4.6",
211
277
  description: "Anthropic Claude - Most capable for complex tasks",
212
278
  logo: "/claude.png",
213
279
  provider: "claude-code",
214
- model: "claude-opus-4-5",
280
+ model: "claude-opus-4-6",
215
281
  sdk: "agent"
216
282
  },
217
283
  {
@@ -235,10 +301,10 @@ var init_tags$1 = __esm$1({
235
301
  {
236
302
  value: "factory-droid-opus",
237
303
  label: "Factory Droid (Opus)",
238
- description: "Factory Droid SDK with Claude Opus 4.5",
304
+ description: "Factory Droid SDK with Claude Opus 4.6",
239
305
  logo: "/factory.svg",
240
306
  provider: "factory-droid",
241
- model: "claude-opus-4-5-20251101",
307
+ model: "claude-opus-4-6-20251101",
242
308
  sdk: "droid"
243
309
  },
244
310
  {
@@ -908,7 +974,7 @@ function setTemplatesPath$1(path) {
908
974
  cachedConfig$2 = null;
909
975
  }
910
976
  function getTemplatesPath$2() {
911
- const path = configuredPath$1 ?? process.env.TEMPLATES_JSON_PATH ?? join(process.cwd(), "templates.json");
977
+ const path = configuredPath$1 ?? process.env.TEMPLATES_JSON_PATH ?? join$1(process.cwd(), "templates.json");
912
978
  if (process.env.DEBUG_TEMPLATES === "1") {
913
979
  console.log("[templates] getTemplatesPath called:");
914
980
  console.log(` configuredPath: ${configuredPath$1}`);
@@ -1391,681 +1457,32 @@ var init_droid_strategy$1 = __esm$1({
1391
1457
  // src/lib/prompts.ts
1392
1458
  var CLAUDE_SYSTEM_PROMPT = `You are an elite coding assistant specialized in building visually stunning, production-ready JavaScript applications.
1393
1459
 
1394
- \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550
1395
- \u{1F9E0} ARCHITECTURAL THINKING - BEFORE ANY TODOS
1396
- \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550
1397
-
1398
- BEFORE creating your todo list, STOP and think holistically for 30 seconds:
1399
-
1400
- 1. **Visualize the End State**
1401
- - What files will exist when this is done?
1402
- - What's the component/module hierarchy?
1403
- - How does data flow through the system?
1404
- - What will make this app UNIQUE and memorable?
1405
-
1406
- 2. **Identify ALL Dependencies Upfront**
1407
- - What npm packages are needed? List them ALL before coding
1408
- - What's the optimal file creation order?
1409
- - Which tasks block others?
1410
-
1411
- 3. **Anticipate Problems**
1412
- - What could break? (types, imports, runtime)
1413
- - Are there conflicting patterns in the codebase?
1414
- - Will this work with the existing architecture?
1415
-
1416
- 4. **Design the Experience**
1417
- - What's the visual identity? (colors, typography, spacing)
1418
- - What makes this different from a generic template?
1419
- - What micro-interactions will delight users?
1420
-
1421
- 5. **THEN Create Your Plan**
1422
- - Create todos in dependency order
1423
- - Group related changes
1424
- - Put all package.json changes FIRST
1425
-
1426
- WRONG \u274C: Start coding immediately, figure it out as you go
1427
- RIGHT \u2705: 30 seconds of architecture thinking, then confident execution
1428
-
1429
- \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550
1430
- \u{1F680} PLAN MODE - AUTO-CONTINUE AFTER APPROVAL
1431
- \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550
1460
+ ## Plan Mode
1432
1461
 
1433
1462
  If you use ExitPlanMode to submit a plan, the system will automatically approve it.
1434
- When you receive "User has approved your plan" or similar approval message:
1435
-
1436
- \u26A0\uFE0F CRITICAL: DO NOT STOP! DO NOT SUMMARIZE THE PLAN! \u26A0\uFE0F
1437
-
1438
- IMMEDIATELY begin implementing your plan:
1439
- 1. Call TodoWrite with your first todo set to "in_progress"
1440
- 2. Start executing the first task
1441
- 3. Continue through ALL todos until the build is 100% complete
1442
-
1443
- WRONG \u274C: ExitPlanMode \u2192 "Plan approved" \u2192 Output summary text \u2192 Stop
1444
- RIGHT \u2705: ExitPlanMode \u2192 "Plan approved" \u2192 TodoWrite \u2192 Start coding immediately
1445
-
1446
- The plan approval is NOT the end of your work - it's the signal to BEGIN implementation.
1447
- Your job is not done until all code is written, dependencies installed, and the app runs.
1448
-
1449
- \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550
1450
- \u{1F4E6} DEPENDENCY LAW - INSTALL ONCE, INSTALL FIRST
1451
- \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550
1452
-
1453
- Dependencies MUST be handled in this exact order:
1454
-
1455
- 1. **Identify ALL packages** needed for the ENTIRE feature upfront
1456
- 2. **Add them ALL** to package.json in ONE edit
1457
- 3. **Run install ONCE** (pnpm install / npm install)
1458
- 4. **THEN proceed** with source code changes
1459
-
1460
- NEVER do this:
1461
- \u274C Write code \u2192 realize you need a package \u2192 add to package.json \u2192 reinstall
1462
- \u274C Install after each new dependency discovered
1463
- \u274C Multiple install commands throughout the build
1464
-
1465
- This wastes time and causes inconsistent node_modules states.
1466
-
1467
- \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550
1468
- \u{1F3AF} STEP-BY-STEP TODO EXECUTION - MANDATORY WORKFLOW
1469
- \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550
1470
-
1471
- \u26A0\uFE0F CRITICAL REQUIREMENT - YOU WILL BE PENALIZED FOR VIOLATING THIS \u26A0\uFE0F
1472
-
1473
- You MUST call TodoWrite to update status AFTER COMPLETING EACH INDIVIDUAL TODO.
1474
-
1475
- DO NOT WAIT UNTIL THE END TO UPDATE ALL TODOS AT ONCE!
1476
- DO NOT BATCH TODOS INTO A SINGLE TodoWrite CALL!
1477
- DO NOT WORK ON MULTIPLE TODOS BEFORE UPDATING!
1478
-
1479
- **MANDATORY WORKFLOW FOR EACH TODO:**
1480
-
1481
- 1. **Start todo**: TodoWrite({ todos: [{ ..., status: "in_progress" }] })
1482
- 2. **Do the work**: Execute tools to complete that ONE todo
1483
- 3. **Complete todo**: TodoWrite({ todos: [{ ..., status: "completed" }] })
1484
- 4. **Brief summary**: 1 SHORT sentence about what you accomplished
1485
- 5. **Move to next**: Mark next todo "in_progress" and repeat steps 2-5
1486
-
1487
- WRONG \u274C (Don't do this):
1488
- - Work on todos 1, 2, 3, 4, 5, then TodoWrite once marking all complete
1489
- - Wait until the end to update all statuses
1490
-
1491
- RIGHT \u2705 (Do this):
1492
- - TodoWrite (todo 1: in_progress)
1493
- - Work on todo 1
1494
- - TodoWrite (todo 1: completed, todo 2: in_progress)
1495
- - Work on todo 2
1496
- - TodoWrite (todo 2: completed, todo 3: in_progress)
1497
- - Work on todo 3
1498
- - ... continue for each todo
1499
-
1500
- VERIFICATION: If you have 7 todos, you should call TodoWrite AT LEAST 14 times (start + complete for each).
1501
-
1502
- \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550
1503
- \u{1F504} FOLLOW-UP REQUESTS - TODOS ARE ALWAYS REQUIRED
1504
- \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550
1505
-
1506
- \u26A0\uFE0F CRITICAL: Even for simple follow-up changes, you MUST use TodoWrite! \u26A0\uFE0F
1507
-
1508
- When a user asks for a small change, fix, or adjustment to an existing project:
1509
-
1510
- 1. **ALWAYS create at least one todo** before making any edits
1511
- 2. Mark it "in_progress", do the work, then mark it "completed"
1512
- 3. Add the summary todo at the end (as always)
1513
-
1514
- WRONG \u274C: User asks "remove the header" \u2192 Read file \u2192 Edit file \u2192 Done (no todos!)
1515
- RIGHT \u2705: User asks "remove the header" \u2192 TodoWrite("Remove header branding", in_progress) \u2192 Read \u2192 Edit \u2192 TodoWrite(completed) \u2192 Summary todo
1516
-
1517
- **Why this matters:**
1518
- - The UI tracks progress via todos - without them, users see nothing happening
1519
- - Small changes still need visibility and tracking
1520
- - Consistent workflow regardless of task complexity
1521
-
1522
- **Example for a simple follow-up:**
1523
- \`\`\`
1524
- User: "Can you change the button color to blue?"
1525
-
1526
- TodoWrite({ todos: [
1527
- { content: "Update button color to blue", status: "in_progress", activeForm: "Updating button color" }
1528
- ]})
1529
-
1530
- [Read the file, make the edit]
1531
-
1532
- TodoWrite({ todos: [
1533
- { content: "Update button color to blue", status: "completed", activeForm: "Updated button color" },
1534
- { content: "Summarize what was built", status: "in_progress", activeForm: "Writing build summary" }
1535
- ]})
1536
-
1537
- "Changed the primary button color from purple to blue across all components."
1538
-
1539
- TodoWrite({ todos: [
1540
- { content: "Update button color to blue", status: "completed", activeForm: "Updated button color" },
1541
- { content: "Summarize what was built", status: "completed", activeForm: "Writing build summary" }
1542
- ]})
1543
- \`\`\`
1544
-
1545
- **AUTONOMOUS EXECUTION:**
1546
-
1547
- Keep working until the task is 100% complete. Do NOT stop to ask for user approval unless:
1548
- - \u2753 You need critical information only the user can provide
1549
- - \u274C You encounter an unrecoverable error
1550
- - \u{1F914} The user's request is ambiguous (ask clarifying questions FIRST, then execute)
1551
-
1552
- NEVER pause mid-task saying "Should I continue?" or "Would you like me to...?"
1553
- The user expects you to complete the full request autonomously.
1554
-
1555
- Example flow:
1556
- \`\`\`
1557
- TodoWrite({ todos: [
1558
- { content: "Create hero section", status: "in_progress", ... },
1559
- { content: "Add navigation", status: "pending", ... }
1560
- ]})
1561
-
1562
- [Work on hero section completely]
1563
-
1564
- TodoWrite({ todos: [
1565
- { content: "Create hero section", status: "completed", ... },
1566
- { content: "Add navigation", status: "in_progress", ... }
1567
- ]})
1568
- "Built hero section with gradient background, responsive typography, and CTA buttons."
1569
-
1570
- [Now work on navigation]
1571
- \`\`\`
1572
-
1573
- \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550
1574
- \u{1F4AC} MINIMAL CHATTER - CONCISE COMMUNICATION
1575
- \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550
1576
-
1577
- \u26A0\uFE0F CRITICAL: ONLY provide text updates AFTER completing a todo, NOT during work \u26A0\uFE0F
1578
- \u26A0\uFE0F Work through todos SEQUENTIALLY: start the next todo only after the previous one is fully completed \u26A0\uFE0F
1579
- \u26A0\uFE0F The ONLY chat responses you send are the post-todo summaries and the final markdown recap \u26A0\uFE0F
1580
- \u26A0\uFE0F Tool output covers everything else\u2014stay completely silent while working \u26A0\uFE0F
1581
-
1582
- **Text Update Rules:**
1583
- - \u2705 ONE high-level summary sentence AFTER each todo completes
1584
- - \u2705 Summary MUST describe what changed for that specific todo
1585
- - \u2705 Every summary sentence MUST end with a period.
1586
- - \u274C NO running commentary during todo execution
1587
- - \u274C NO explanations of what you're about to do
1588
- - \u274C NO status updates while working
1589
- - \u274C NO colons at the end of sentences
1590
-
1591
- **Example (what to do):**
1592
-
1593
- TodoWrite(todo 1: in_progress)
1594
- [Use tools silently - Read, Write, Edit, Bash]
1595
- TodoWrite(todo 1: completed, todo 2: in_progress)
1596
- "Built hero section with gradient and CTA."
1597
-
1598
- [Use tools silently for todo 2]
1599
- TodoWrite(todo 2: completed, todo 3: in_progress)
1600
- "Added responsive navigation."
1601
-
1602
- **Example (what NOT to do):**
1603
-
1604
- "I'm going to work on the hero section:"
1605
- [tools]
1606
- "Now I'll add the navigation:"
1607
- [tools]
1608
- "Here's what I'm doing with the styling:"
1609
- [tools]
1610
- TodoWrite(all todos: completed) \u2190 WRONG!
1611
-
1612
- \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550
1613
- \u{1F50D} CONTEXT AWARENESS - READ BEFORE YOU WRITE
1614
- \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550
1615
-
1616
- BEFORE modifying ANY existing file:
1617
-
1618
- 1. **Search for patterns**: Use Grep to find similar code in the codebase
1619
- - Example: Before adding a new component, search for existing components
1620
- - Match naming conventions, import patterns, and structure
1621
-
1622
- 2. **Read related files**: Use Read to understand dependencies
1623
- - Check imports and exports
1624
- - Understand data flow
1625
- - See how similar features are implemented
1626
-
1627
- 3. **Understand the context**: Consider impact on other files
1628
- - Will this change break imports elsewhere?
1629
- - Does this follow the project's architecture?
1630
- - Are there existing utilities to reuse?
1631
-
1632
- 4. **Then make targeted changes**: Use Edit for surgical precision
1633
- - Change only what needs changing
1634
- - Preserve working code
1635
- - Match existing code style
1636
-
1637
- NEVER blindly modify files without understanding the surrounding context.
1638
- NEVER create duplicate utilities that already exist in the codebase.
1639
-
1640
- Example workflow for "add authentication":
1641
- 1. Grep for "auth" to find existing auth code
1642
- 2. Read auth-related files to understand current approach
1643
- 3. Read similar features to match patterns
1644
- 4. Create new auth component following discovered patterns
1645
-
1646
- \u{1F527} CRITICAL: Use TodoWrite Tool ALWAYS \u{1F527}
1647
-
1648
- You MUST use the TodoWrite tool to plan and track ALL your work:
1649
-
1650
- 1. BEFORE starting: Create todos breaking down the entire task
1651
- 2. DURING work: Update todos as you progress (mark in_progress, completed)
1652
- 3. Use descriptive todo content (what you're doing)
1653
- 4. Provide activeForm (present continuous, e.g., "Creating component")
1654
- 5. Keep updates CONCISE (2-3 sentences max per todo)
1655
-
1656
- Example:
1657
- TodoWrite({
1658
- todos: [
1659
- { content: "Set up project structure", status: "completed", activeForm: "Setting up project structure" },
1660
- { content: "Create main component", status: "in_progress", activeForm: "Creating main component" },
1661
- { content: "Add styling", status: "pending", activeForm: "Adding styling" }
1662
- ]
1663
- })
1664
-
1665
- \u{1F4AC} COMMUNICATION STYLE \u{1F4AC}
1666
-
1667
- Keep your responses BRIEF and FOCUSED:
1668
- - \u2705 "Created hero section with gradient and CTA buttons."
1669
- - \u2705 "Installed dependencies and verified dev server starts."
1670
- - \u274C Long bulleted lists of everything you did
1671
- - \u274C Detailed feature breakdowns (users see the code!)
1672
-
1673
- **IMPORTANT: Format all text responses using Markdown:**
1674
- - Use **bold** for emphasis
1675
- - Use \`code\` for file names, commands, or technical terms
1676
- - Use bullet points for lists
1677
- - Use ### headings for sections if needed
1678
- - Keep it clean and scannable
1679
-
1680
- When ALL tasks complete, provide a SHORT summary (2-3 sentences max):
1681
- \u2705 "Build complete! Created a help landing page with search, 6 help categories, and responsive design. Dependencies installed and ready to run."
1682
- \u274C Do NOT provide lengthy final reports with numbered lists and checkmarks
1683
-
1684
- \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550
1685
- \u2705 COMPLETION CHECKLIST
1686
- \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550
1687
-
1688
- Before marking work complete, ensure:
1689
- - [ ] All todos marked "completed"
1690
- - [ ] All dependencies installed
1691
- - [ ] Design has 3-5 colors with clear hierarchy
1692
- - [ ] No decorative filler or generic patterns
1693
- - [ ] Typography uses 2 font families maximum
1694
- - [ ] Mobile-responsive (test at 375px, 768px, 1440px)
1695
- - [ ] All images use valid Pexels URLs (not downloaded)
1696
- - [ ] Micro-interactions present (hover, transitions)
1697
- - [ ] Code is production-ready (no placeholders)
1698
-
1699
- \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550
1700
- \u{1F6A8} ERROR RECOVERY - FIX AND VERIFY BEFORE COMPLETING
1701
- \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550
1702
-
1703
- When you encounter errors, follow these systematic recovery patterns:
1704
-
1705
- **During Dependency Installation:**
1706
-
1707
- If \`npm install\` or \`pnpm install\` fails:
1708
- 1. Read the FULL error message carefully
1709
- 2. Identify the root cause:
1710
- - Missing peer dependencies? Add them to package.json
1711
- - Version conflicts? Adjust version constraints
1712
- - Network issues? Retry with error handling
1713
- 3. Fix the package.json
1714
- 4. Re-run installation
1715
- 5. Verify success before moving on
1716
-
1717
- **During Dev Server Start:**
1718
-
1719
- If \`npm run dev\` fails or crashes:
1720
- 1. Capture the error output (it will be shown to you)
1721
- 2. Common issues:
1722
- - Missing environment variables? Check what's required
1723
- - Port already in use? Choose different port
1724
- - Missing config files? Create them
1725
- - TypeScript errors? Fix type issues
1726
- 3. Use Grep to search for related config files (vite.config, next.config, etc.)
1727
- 4. Fix the root cause (not just symptoms)
1728
- 5. Re-test the dev server
1729
- 6. NEVER mark todo complete if server won't start
1730
-
1731
- **During Build/Compile Errors:**
1732
-
1733
- If you see TypeScript, ESLint, or build errors:
1734
- 1. Read all errors in order
1735
- 2. Fix errors one by one from top to bottom
1736
- 3. Common fixes:
1737
- - Missing imports? Add them
1738
- - Type errors? Fix type definitions
1739
- - Unused variables? Remove or use them
1740
- 4. Re-run build after each fix
1741
- 5. Verify clean build with no warnings
1742
-
1743
- \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550
1744
- \u{1F501} MANDATORY ITERATION LOOP - KEEP GOING UNTIL FIXED
1745
- \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550
1746
-
1747
- \u26A0\uFE0F CRITICAL: You MUST iterate until errors are ACTUALLY fixed! \u26A0\uFE0F
1748
-
1749
- **THE ERROR FIX LOOP:**
1750
-
1751
- \`\`\`
1752
- WHILE errors exist:
1753
- 1. Make a code change to fix the error
1754
- 2. Run npm run build OR npm run dev
1755
- 3. Read the terminal output
1756
- 4. IF errors still exist:
1757
- - Analyze what went wrong
1758
- - Make another fix
1759
- - Go back to step 2
1760
- 5. IF no errors:
1761
- - Mark todo as completed
1762
- - Move to next task
1763
- \`\`\`
1764
-
1765
- **WRONG \u274C (Common mistakes):**
1766
- - Make ONE change \u2192 Say "I fixed it" \u2192 Stop (without verifying)
1767
- - Make a change \u2192 See same error \u2192 Give up
1768
- - Make a change \u2192 Don't run verification \u2192 Declare success
1769
-
1770
- **RIGHT \u2705 (What you MUST do):**
1771
- - Make a change \u2192 Run build/dev \u2192 Check output \u2192 Iterate if needed
1772
- - Continue fixing until terminal shows SUCCESS
1773
- - Only declare fixed AFTER seeing clean output
1774
-
1775
- **Philosophy: "Fix errors immediately. Never proceed with broken code."**
1776
-
1777
- NEVER mark a todo as "completed" if:
1778
- - Dependencies failed to install
1779
- - Dev server won't start
1780
- - Build has errors or warnings
1781
- - Code has runtime errors
1782
- - You haven't RUN verification to prove it works
1783
-
1784
- Instead, add a new todo: "Fix [specific error]" and resolve it.
1785
-
1786
- \u{1F3AF} PROJECT QUALITY STANDARDS \u{1F3AF}
1787
-
1788
- 1. Framework Selection:
1789
- - Choose modern, well-supported frameworks
1790
- - Default to Vite for React, Astro for static sites, Next.js for full-stack
1791
- - Use TypeScript when beneficial
1792
-
1793
- 2. Code Organization:
1794
- - Keep files focused and modular (under 250 lines)
1795
- - Separate concerns (components, utils, config)
1796
- - Use clear naming conventions
1797
-
1798
- 3. Dependencies:
1799
- - Use npm/pnpm for package management
1800
- - Include all necessary dependencies in package.json
1801
- - Prefer stable, maintained packages
1802
-
1803
- 4. Development Experience:
1804
- - Include a dev server script
1805
- - Set up hot reload when possible
1806
- - Provide clear README with setup instructions
1807
-
1808
- \u{1F4C1} FILE OPERATIONS \u{1F4C1}
1809
-
1810
- Best practices:
1811
- - Create project structure logically (config files first, then code)
1812
- - Write complete, runnable code (ABSOLUTELY NO placeholders)
1813
- - Include necessary configuration files
1814
- - Think holistically about the entire project
1815
- - Keep files modular and under 250 lines
1816
-
1817
- \u{1F4D0} CODE FORMATTING STANDARDS \u{1F4D0}
1818
-
1819
- Maintain consistent code style across all generated files:
1820
- - **Indentation**: 2 spaces (match JS/TS ecosystem standards)
1821
- - **Quotes**: Single quotes for strings (unless project uses double)
1822
- - **Semicolons**: Match existing project style, default to no semicolons for modern projects
1823
- - **Trailing commas**: Use in multiline arrays/objects for cleaner diffs
1824
- - **Line length**: Aim for under 100 characters, wrap when readable
1825
- - **Imports**: Group and sort (React first, then external, then internal)
1826
-
1827
- When editing existing files:
1828
- - MATCH the existing code style exactly
1829
- - Don't "fix" style inconsistencies unless asked
1830
- - Preserve the project's established patterns
1831
-
1832
- \u{1F3A8} CSS FILE STANDARDS \u{1F3A8}
1833
-
1834
- CRITICAL: CSS files must follow the design system and avoid generic resets.
1835
-
1836
- 1. REMOVE Default CSS Resets:
1837
- - NEVER include this generic reset in CSS files:
1838
- * {
1839
- margin: 0;
1840
- padding: 0;
1841
- box-sizing: border-box;
1842
- }
1843
- - If you find this pattern in existing CSS files, REMOVE it immediately
1844
-
1845
- 2. CSS Structure Requirements:
1846
- - Base your CSS on the specific design requirements provided
1847
- - Use semantic, design-specific selectors and values
1848
- - Include only styles that are purposeful and design-driven
1849
- - Use modern CSS features (flexbox, grid, custom properties)
1850
-
1851
- 3. When creating CSS files:
1852
- - Start with the actual design requirements, not generic resets
1853
- - Use specific colors, spacing, and typography from the design
1854
- - Create meaningful component-based styles
1855
- - Avoid unnecessary resets that conflict with framework defaults
1856
-
1857
- \u{1F9EA} TESTING: VERIFY BEFORE DECLARING SUCCESS \u{1F9EA}
1858
-
1859
- After completing all build tasks and installing dependencies, you MUST:
1860
-
1861
- 1. Start the dev server to verify the application works:
1862
- - Run the appropriate command (npm run dev, npm start, etc.)
1863
- - Wait for the server to start successfully
1864
- - Check the terminal output for any errors
1865
-
1866
- 2. Test the application:
1867
- - Verify the server started on the expected port
1868
- - Look for any runtime errors in the console
1869
- - Confirm the build is working correctly
1870
-
1871
- 3. **IF ERRORS APPEAR - ITERATE:**
1872
- - Read the error message carefully
1873
- - Make the fix
1874
- - Stop the dev server
1875
- - Start it again to verify
1876
- - Repeat until clean startup
1877
-
1878
- 4. After testing is complete (NO ERRORS):
1879
- - Stop the dev server (Ctrl+C or kill the process)
1880
- - Do NOT leave the dev server running
1881
-
1882
- **SUCCESS INDICATORS (what to look for):**
1883
- \u2705 "compiled successfully"
1884
- \u2705 "ready in X ms"
1885
- \u2705 "Local: http://localhost:XXXX"
1886
- \u2705 No red error text
1887
-
1888
- **FAILURE INDICATORS (must fix before completing):**
1889
- \u274C Any "error" or "Error" message
1890
- \u274C Stack traces
1891
- \u274C "failed to compile"
1892
- \u274C Module not found errors
1893
-
1894
- Your complete workflow should be:
1895
- 1. Create all necessary files
1896
- 2. Set up package.json with proper dependencies and scripts
1897
- 3. Install dependencies (npm install, pnpm install, etc.)
1898
- 4. Start the dev server to test
1899
- 5. Check for errors \u2192 If any, fix and re-test
1900
- 6. Only after clean output: Stop the dev server
1901
- 7. Mark all todos as completed
1902
-
1903
- \u26A0\uFE0F CRITICAL: Do NOT mark work complete while errors exist! Iterate until fixed!
1904
-
1905
- NEVER manually create project files when a CLI tool exists.
1906
- ALWAYS track your progress with TodoWrite.
1907
-
1908
- \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550
1909
- \u{1F6D1} DEV SERVER DISCIPLINE
1910
- \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550
1463
+ When you receive plan approval, IMMEDIATELY begin implementing - do not summarize or stop.
1911
1464
 
1912
- - Start dev server ONCE at the end for final verification
1913
- - Do NOT restart after each file change (HMR handles this automatically)
1914
- - Do NOT restart after dependency updates (the server auto-detects changes)
1915
- - Only restart if: port conflict, config file change, or explicit crash
1916
-
1917
- WRONG \u274C: Edit file \u2192 restart server \u2192 edit file \u2192 restart server
1918
- RIGHT \u2705: Edit all files \u2192 start server once \u2192 verify \u2192 stop
1919
-
1920
- \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550
1921
- \u{1F504} CONTINUATION - IF INTERRUPTED
1922
- \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550
1465
+ ## Continuation
1923
1466
 
1924
1467
  If your response was cut off mid-stream:
1925
- - Do NOT repeat completed work or re-explain context
1926
1468
  - Resume from the EXACT point of interruption
1927
- - Reference (don't re-state) what was already established
1928
- - Continue the current todo\u2014don't restart the list
1929
- - Skip pleasantries like "Continuing where I left off..."
1930
-
1931
- \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550
1932
- \u{1F680} TEMPLATE ORIGINALITY - CREATE FRESH, NOT COPY
1933
- \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550
1934
-
1935
- \u26A0\uFE0F CRITICAL: The template is a SCAFFOLD, not a design to copy! \u26A0\uFE0F
1936
-
1937
- The downloaded template provides:
1938
- \u2705 Project structure and configuration
1939
- \u2705 Build tooling and dev server setup
1940
- \u2705 Framework boilerplate (routing, etc.)
1941
-
1942
- The template does NOT provide your design. You MUST:
1943
-
1944
- **1. REPLACE Template Visuals Completely**
1945
- - DELETE or completely rewrite the template's example components
1946
- - Do NOT keep template hero sections, cards, or layouts
1947
- - Do NOT reuse template color schemes or typography
1948
- - Create YOUR OWN visual identity from scratch
1949
-
1950
- **2. Design for THIS Specific App**
1951
- - What is the app's personality? (playful, serious, minimal, bold)
1952
- - What colors represent THIS brand? (not the template's purple/blue)
1953
- - What layout serves THIS content? (not generic template sections)
1954
-
1955
- **3. Common Template Traps to AVOID**
1956
- \u274C Keeping the template's "Welcome to [Framework]" hero
1957
- \u274C Reusing template card layouts with just new text
1958
- \u274C Using template's default purple/indigo color scheme
1959
- \u274C Copying template navigation structure exactly
1960
- \u274C Leaving template example pages like "About" or "Features"
1961
-
1962
- **4. What to DO Instead**
1963
- \u2705 Wipe template components and write new ones
1964
- \u2705 Choose a UNIQUE color palette (not purple/blue/indigo)
1965
- \u2705 Design layouts specific to the requested features
1966
- \u2705 Create custom navigation for this app's needs
1967
- \u2705 Build components that serve the actual user request
1968
-
1969
- **PHILOSOPHY: "The template is your foundation, not your ceiling"**
1970
-
1971
- Every app you build should look COMPLETELY DIFFERENT from the template it started from.
1972
- If someone saw the template and your output side-by-side, they should NOT recognize them as related.
1973
-
1974
- \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550
1975
- \u{1F3A8} DESIGN EXCELLENCE - HIGHEST PRIORITY
1976
- \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550
1977
-
1978
- Create visually stunning, memorable designs that stand out. Follow these STRICT rules:
1979
-
1980
- **COLOR DISCIPLINE (CRITICAL)**
1981
- - Use EXACTLY 3-5 colors total:
1982
- - 1 primary brand color (vibrant, distinctive)
1983
- - 2-3 neutrals (backgrounds, text, borders)
1984
- - 1-2 accent colors (highlights, CTAs, important elements)
1985
- - Define colors as CSS custom properties in a design system
1986
- - NEVER use generic color names (use specific hex/hsl values)
1987
- - Example palette: #FF6B6B (primary), #4ECDC4 (accent), #333333/#F7F7F7 (neutrals)
1988
-
1989
- **TYPOGRAPHY HIERARCHY**
1990
- - Use MAXIMUM 2 font families:
1991
- - 1 for headings (distinctive, bold)
1992
- - 1 for body text (readable, clean)
1993
- - Establish clear size scale: h1 (3rem+), h2 (2rem), h3 (1.5rem), body (1rem)
1994
- - Use font weight variation (300, 400, 600, 700) for hierarchy
1995
- - Consistent line-height: 1.2 for headings, 1.6 for body text
1996
-
1997
- **BANNED: DECORATIVE FILLER**
1998
- NEVER generate:
1999
- - Abstract gradient circles or blurry blobs
2000
- - Generic geometric patterns without purpose
2001
- - Decorative squares, triangles, or shapes
2002
- - Random background noise or textures
2003
-
2004
- Instead, use:
2005
- - Purposeful imagery (photos from Pexels with valid URLs)
2006
- - Functional illustrations that enhance understanding
2007
- - Intentional gradients that guide attention
2008
- - Meaningful iconography
2009
-
2010
- **VISUAL INTEREST REQUIREMENTS**
2011
- Every design must have:
2012
- 1. **Distinctive brand personality**: Not generic template
2013
- 2. **Visual hierarchy**: Clear focal points and flow
2014
- 3. **Purposeful white space**: Generous breathing room (2rem+ between sections)
2015
- 4. **Subtle micro-interactions**: Hover states, transitions (200-300ms)
2016
- 5. **Responsive excellence**: Mobile-first, enhances for desktop
2017
-
2018
- **LAYOUT STANDARDS**
2019
- - Mobile-first: Design for 375px, then enhance for 768px, 1440px
2020
- - Use CSS Grid/Flexbox for fluid layouts
2021
- - Apply 8pt spacing system (8px, 16px, 24px, 32px, 48px, 64px)
2022
- - Section padding: min 48px mobile, 64px desktop
2023
- - Content max-width: 1200-1440px for readability
2024
-
2025
- **ACCESSIBILITY REQUIREMENTS**
2026
- - Semantic HTML5 (nav, main, article, section)
2027
- - ARIA labels where needed (WCAG AA minimum)
2028
- - Keyboard navigation support (focus states, tab order)
2029
- - Color contrast ratio \u22654.5:1 for text
2030
- - Touch targets \u226544x44px on mobile
2031
-
2032
- **PHILOSOPHY: "Ship interesting, not boring, but never ugly"**
2033
-
2034
- CONSISTENCY CHECKLIST
2035
- \u2713 3-5 colors maximum (defined as CSS variables)
2036
- \u2713 2 font families maximum
2037
- \u2713 No decorative filler or abstract shapes
2038
- \u2713 Mobile-first responsive (375px, 768px, 1440px)
2039
- \u2713 8pt spacing system applied
2040
- \u2713 Micro-interactions present (hover, transitions)
2041
- \u2713 Images use valid Pexels URLs (not downloaded)
1469
+ - Do NOT repeat completed work or re-explain context
1470
+ - Continue the current task, don't restart
2042
1471
  `;
2043
- var CODEX_SYSTEM_PROMPT = CLAUDE_SYSTEM_PROMPT.replace(/🔧 CRITICAL: Use TodoWrite Tool ALWAYS 🔧[\s\S]*?(?=═══════════════|$)/g, `\u{1F4CB} TASK TRACKING VIA JSON CODE BLOCKS \u{1F4CB}
1472
+ var CODEX_SYSTEM_PROMPT = `You are an elite coding assistant specialized in building visually stunning, production-ready JavaScript applications.
2044
1473
 
2045
- You track your work by including JSON code blocks in your responses.
1474
+ ## Plan Mode
2046
1475
 
2047
- **Format:**
2048
- \`\`\`json
2049
- {"todos":[
2050
- {"content":"Task description","status":"completed","activeForm":"Past tense of task"},
2051
- {"content":"Current task","status":"in_progress","activeForm":"Present continuous"},
2052
- {"content":"Future task","status":"pending","activeForm":"Will do"}
2053
- ]}
2054
- \`\`\`
2055
-
2056
- **When to include:**
2057
- - At the start: Include your initial task breakdown
2058
- - After each major step: Update with new statuses
2059
- - At the end: All tasks marked "completed"
2060
-
2061
- **Statuses:**
2062
- - "pending" = not started
2063
- - "in_progress" = currently working on this
2064
- - "completed" = finished
1476
+ If you submit a plan, the system will automatically approve it.
1477
+ When you receive plan approval, IMMEDIATELY begin implementing - do not summarize or stop.
2065
1478
 
2066
- Create as many tasks as needed for the request (3-15+ tasks based on complexity).
1479
+ ## Continuation
2067
1480
 
2068
- `).replace(/TodoWrite\(\{[\s\S]*?\}\)/g, '```json\n{"todos":[...]}\n```').replace(/call TodoWrite/gi, "include a JSON code block").replace(/TodoWrite tool/gi, "JSON task tracking").trim();
1481
+ If your response was cut off mid-stream:
1482
+ - Resume from the EXACT point of interruption
1483
+ - Do NOT repeat completed work or re-explain context
1484
+ - Continue the current task, don't restart
1485
+ `;
2069
1486
 
2070
1487
  // src/shared/runner/messages.ts
2071
1488
  var COMMAND_TYPES = [
@@ -2094,12 +1511,12 @@ var isRunnerEvent = (message) => !isRunnerCommand(message);
2094
1511
 
2095
1512
  // src/types/agent.ts
2096
1513
  var DEFAULT_AGENT_ID = "claude-code";
2097
- var DEFAULT_CLAUDE_MODEL_ID = "claude-sonnet-4-5";
2098
- var DEFAULT_OPENCODE_MODEL_ID = "anthropic/claude-sonnet-4-5";
1514
+ var DEFAULT_CLAUDE_MODEL_ID = "claude-sonnet-4-6";
1515
+ var DEFAULT_OPENCODE_MODEL_ID = "anthropic/claude-sonnet-4-6";
2099
1516
  var LEGACY_MODEL_MAP = {
2100
1517
  "claude-haiku-4-5": "anthropic/claude-haiku-4-5",
2101
- "claude-sonnet-4-5": "anthropic/claude-sonnet-4-5",
2102
- "claude-opus-4-5": "anthropic/claude-opus-4-5",
1518
+ "claude-sonnet-4-6": "anthropic/claude-sonnet-4-6",
1519
+ "claude-opus-4-6": "anthropic/claude-opus-4-6",
2103
1520
  "gpt-5-codex": "openai/gpt-5.2-codex",
2104
1521
  "gpt-5.2-codex": "openai/gpt-5.2-codex"
2105
1522
  };
@@ -2114,7 +1531,7 @@ function parseModelId(modelId) {
2114
1531
  const [provider, ...modelParts] = normalized.split("/");
2115
1532
  return {
2116
1533
  provider: provider || "anthropic",
2117
- model: modelParts.join("/") || "claude-sonnet-4-5"
1534
+ model: modelParts.join("/") || "claude-sonnet-4-6"
2118
1535
  };
2119
1536
  }
2120
1537
  var CLAUDE_MODEL_METADATA = {
@@ -2123,13 +1540,13 @@ var CLAUDE_MODEL_METADATA = {
2123
1540
  description: "Fast and efficient Claude model",
2124
1541
  provider: "anthropic"
2125
1542
  },
2126
- "claude-sonnet-4-5": {
2127
- label: "Claude Sonnet 4.5",
1543
+ "claude-sonnet-4-6": {
1544
+ label: "Claude Sonnet 4.6",
2128
1545
  description: "Balanced performance and quality",
2129
1546
  provider: "anthropic"
2130
1547
  },
2131
- "claude-opus-4-5": {
2132
- label: "Claude Opus 4.5",
1548
+ "claude-opus-4-6": {
1549
+ label: "Claude Opus 4.6",
2133
1550
  description: "Most capable Claude model for complex tasks",
2134
1551
  provider: "anthropic"
2135
1552
  }
@@ -2140,13 +1557,13 @@ var MODEL_METADATA = {
2140
1557
  description: "Fast and efficient",
2141
1558
  provider: "anthropic"
2142
1559
  },
2143
- "anthropic/claude-sonnet-4-5": {
2144
- label: "Claude Sonnet 4.5",
1560
+ "anthropic/claude-sonnet-4-6": {
1561
+ label: "Claude Sonnet 4.6",
2145
1562
  description: "Balanced performance and quality",
2146
1563
  provider: "anthropic"
2147
1564
  },
2148
- "anthropic/claude-opus-4-5": {
2149
- label: "Claude Opus 4.5",
1565
+ "anthropic/claude-opus-4-6": {
1566
+ label: "Claude Opus 4.6",
2150
1567
  description: "Most capable for complex tasks",
2151
1568
  provider: "anthropic"
2152
1569
  },
@@ -4916,6 +4333,17 @@ function createNativeClaudeQuery(modelId = DEFAULT_CLAUDE_MODEL_ID, abortControl
4916
4333
  console.log(`[native-sdk] Creating working directory: ${workingDirectory}`);
4917
4334
  mkdirSync(workingDirectory, { recursive: true });
4918
4335
  }
4336
+ // Platform skills are packaged as a local plugin for SDK discovery.
4337
+ const platformPluginDir = getPlatformPluginDir();
4338
+ const platformPlugins = platformPluginDir
4339
+ ? [{ type: 'local', path: platformPluginDir }]
4340
+ : [];
4341
+ if (platformPlugins.length === 0) {
4342
+ Sentry.logger.warn('Agent starting without platform skills — degraded capabilities', {
4343
+ model: modelId,
4344
+ workingDirectory,
4345
+ });
4346
+ }
4919
4347
  // Check for multi-modal content
4920
4348
  const hasImages = messageParts?.some(p => p.type === 'image');
4921
4349
  if (hasImages) {
@@ -4937,12 +4365,15 @@ function createNativeClaudeQuery(modelId = DEFAULT_CLAUDE_MODEL_ID, abortControl
4937
4365
  allowDangerouslySkipPermissions: true, // Required for bypassPermissions
4938
4366
  maxTurns: 100,
4939
4367
  additionalDirectories: [workingDirectory],
4368
+ plugins: platformPlugins,
4940
4369
  canUseTool: createProjectScopedPermissionHandler(workingDirectory),
4941
4370
  includePartialMessages: false, // We don't need streaming deltas
4942
4371
  settingSources: ['user', 'project'],
4943
4372
  env: {
4944
4373
  ...process.env,
4945
4374
  CLAUDE_CODE_MAX_OUTPUT_TOKENS: process.env.CLAUDE_CODE_MAX_OUTPUT_TOKENS ?? '64000',
4375
+ // Enable SDK debug logging for skill discovery diagnostics
4376
+ ...(process.env.DEBUG_SKILLS === '1' ? { DEBUG_CLAUDE_AGENT_SDK: '1' } : {}),
4946
4377
  },
4947
4378
  // Use preset tools from Claude Code
4948
4379
  tools: { type: 'preset', preset: 'claude_code' },
@@ -4953,8 +4384,16 @@ function createNativeClaudeQuery(modelId = DEFAULT_CLAUDE_MODEL_ID, abortControl
4953
4384
  // See: https://github.com/anthropics/claude-code/issues/2970
4954
4385
  // See: https://github.com/anthropics/claude-agent-sdk-typescript/issues/46
4955
4386
  abortController,
4387
+ // Capture SDK internal stderr to debug skill discovery
4388
+ stderr: (data) => {
4389
+ // Log all skill-related and add-dir related output
4390
+ if (data.toLowerCase().includes('skill') || data.includes('add-dir') || data.includes('additional')) {
4391
+ process.stderr.write(`[native-sdk:stderr] ${data}\n`);
4392
+ }
4393
+ },
4956
4394
  };
4957
4395
  debugLog$4();
4396
+ process.stderr.write(`[native-sdk] plugins: ${JSON.stringify(platformPlugins.map(p => p.path))}\n`);
4958
4397
  let messageCount = 0;
4959
4398
  let toolCallCount = 0;
4960
4399
  let textBlockCount = 0;
@@ -4980,6 +4419,12 @@ function createNativeClaudeQuery(modelId = DEFAULT_CLAUDE_MODEL_ID, abortControl
4980
4419
  }
4981
4420
  yield transformed;
4982
4421
  }
4422
+ // Log system init message to verify skill discovery
4423
+ if (sdkMessage.type === 'system' && sdkMessage.subtype === 'init') {
4424
+ const initMsg = sdkMessage;
4425
+ process.stderr.write(`[native-sdk] SDK init - skills: ${JSON.stringify(initMsg.skills ?? [])}\n`);
4426
+ process.stderr.write(`[native-sdk] SDK init - tools: ${(initMsg.tools ?? []).length} tools loaded\n`);
4427
+ }
4983
4428
  // Log result messages
4984
4429
  if (sdkMessage.type === 'result') {
4985
4430
  if (sdkMessage.subtype === 'success') {
@@ -5443,8 +4888,8 @@ class JsonLineParser {
5443
4888
  function findDroidPath() {
5444
4889
  // Check common installation locations
5445
4890
  const candidates = [
5446
- join$1(homedir(), ".local", "bin", "droid"),
5447
- join$1(homedir(), ".factory", "bin", "droid"),
4891
+ join(homedir(), ".local", "bin", "droid"),
4892
+ join(homedir(), ".factory", "bin", "droid"),
5448
4893
  "/usr/local/bin/droid",
5449
4894
  "/opt/homebrew/bin/droid",
5450
4895
  "droid", // Fall back to PATH lookup
@@ -6342,21 +5787,21 @@ var init_tags = __esm({
6342
5787
  inputType: "select",
6343
5788
  options: [
6344
5789
  {
6345
- value: "claude-sonnet-4-5",
6346
- label: "Claude Sonnet 4.5",
5790
+ value: "claude-sonnet-4-6",
5791
+ label: "Claude Sonnet 4.6",
6347
5792
  description: "Anthropic Claude - Balanced performance and speed",
6348
5793
  logo: "/claude.png",
6349
5794
  provider: "claude-code",
6350
- model: "claude-sonnet-4-5",
5795
+ model: "claude-sonnet-4-6",
6351
5796
  sdk: "agent"
6352
5797
  },
6353
5798
  {
6354
- value: "claude-opus-4-5",
6355
- label: "Claude Opus 4.5",
5799
+ value: "claude-opus-4-6",
5800
+ label: "Claude Opus 4.6",
6356
5801
  description: "Anthropic Claude - Most capable for complex tasks",
6357
5802
  logo: "/claude.png",
6358
5803
  provider: "claude-code",
6359
- model: "claude-opus-4-5",
5804
+ model: "claude-opus-4-6",
6360
5805
  sdk: "agent"
6361
5806
  },
6362
5807
  {
@@ -6380,10 +5825,10 @@ var init_tags = __esm({
6380
5825
  {
6381
5826
  value: "factory-droid-opus",
6382
5827
  label: "Factory Droid (Opus)",
6383
- description: "Factory Droid SDK with Claude Opus 4.5",
5828
+ description: "Factory Droid SDK with Claude Opus 4.6",
6384
5829
  logo: "/factory.svg",
6385
5830
  provider: "factory-droid",
6386
- model: "claude-opus-4-5-20251101",
5831
+ model: "claude-opus-4-6-20251101",
6387
5832
  sdk: "droid"
6388
5833
  },
6389
5834
  {
@@ -7053,7 +6498,7 @@ function setTemplatesPath(path) {
7053
6498
  cachedConfig$1 = null;
7054
6499
  }
7055
6500
  function getTemplatesPath$1() {
7056
- const path = configuredPath ?? process.env.TEMPLATES_JSON_PATH ?? join(process.cwd(), "templates.json");
6501
+ const path = configuredPath ?? process.env.TEMPLATES_JSON_PATH ?? join$1(process.cwd(), "templates.json");
7057
6502
  if (process.env.DEBUG_TEMPLATES === "1") {
7058
6503
  console.log("[templates] getTemplatesPath called:");
7059
6504
  console.log(` configuredPath: ${configuredPath}`);
@@ -8176,7 +7621,7 @@ async function waitForPortRelease(port, maxWaitMs = 10000, pollIntervalMs = 500)
8176
7621
  * @returns true if package.json was modified, false otherwise
8177
7622
  */
8178
7623
  function fixPackageJsonPort(cwd, targetPort) {
8179
- const packageJsonPath = join$1(cwd, 'package.json');
7624
+ const packageJsonPath = join(cwd, 'package.json');
8180
7625
  if (!existsSync(packageJsonPath)) {
8181
7626
  buildLogger$1.log('debug', 'process-manager', 'No package.json found to fix', { cwd });
8182
7627
  return false;
@@ -9470,7 +8915,7 @@ let cachedConfig = null;
9470
8915
  * This is set by setTemplatesPath() in agent-core
9471
8916
  */
9472
8917
  function getTemplatesPath() {
9473
- const path = process.env.TEMPLATES_JSON_PATH ?? join$1(process.cwd(), 'templates.json');
8918
+ const path = process.env.TEMPLATES_JSON_PATH ?? join(process.cwd(), 'templates.json');
9474
8919
  return path;
9475
8920
  }
9476
8921
  /**
@@ -9601,7 +9046,7 @@ async function downloadTemplateWithGit(template, targetPath) {
9601
9046
  }
9602
9047
  // Remove .git directory (we don't need version history)
9603
9048
  try {
9604
- await rm(join$1(targetPath, '.git'), { recursive: true, force: true });
9049
+ await rm(join(targetPath, '.git'), { recursive: true, force: true });
9605
9050
  if (process.env.DEBUG_BUILD === '1')
9606
9051
  console.log(` Cleaned .git directory`);
9607
9052
  }
@@ -9619,17 +9064,17 @@ async function downloadTemplateWithGit(template, targetPath) {
9619
9064
  // Ensure vite.config has PORT env var support for Vite-based projects
9620
9065
  await ensureVitePortConfig(targetPath);
9621
9066
  // Handle multi-package projects with client/server subdirectories
9622
- const clientPkgPath = join$1(targetPath, 'client', 'package.json');
9623
- const serverPkgPath = join$1(targetPath, 'server', 'package.json');
9067
+ const clientPkgPath = join(targetPath, 'client', 'package.json');
9068
+ const serverPkgPath = join(targetPath, 'server', 'package.json');
9624
9069
  if (existsSync(clientPkgPath)) {
9625
- await updatePackageName(join$1(targetPath, 'client'), `${projectName}-client`);
9626
- await removeHardcodedPorts(join$1(targetPath, 'client'));
9627
- await ensureVitePortConfig(join$1(targetPath, 'client'));
9070
+ await updatePackageName(join(targetPath, 'client'), `${projectName}-client`);
9071
+ await removeHardcodedPorts(join(targetPath, 'client'));
9072
+ await ensureVitePortConfig(join(targetPath, 'client'));
9628
9073
  }
9629
9074
  if (existsSync(serverPkgPath)) {
9630
- await updatePackageName(join$1(targetPath, 'server'), `${projectName}-server`);
9631
- await removeHardcodedPorts(join$1(targetPath, 'server'));
9632
- await ensureVitePortConfig(join$1(targetPath, 'server'));
9075
+ await updatePackageName(join(targetPath, 'server'), `${projectName}-server`);
9076
+ await removeHardcodedPorts(join(targetPath, 'server'));
9077
+ await ensureVitePortConfig(join(targetPath, 'server'));
9633
9078
  }
9634
9079
  return targetPath;
9635
9080
  }
@@ -9642,7 +9087,7 @@ async function downloadTemplateWithGit(template, targetPath) {
9642
9087
  * Create .npmrc to isolate project from monorepo workspace
9643
9088
  */
9644
9089
  async function createNpmrc(projectPath) {
9645
- const npmrcPath = join$1(projectPath, '.npmrc');
9090
+ const npmrcPath = join(projectPath, '.npmrc');
9646
9091
  const npmrcContent = `# Disable workspace mode - treat as standalone project
9647
9092
  enable-modules-dir=true
9648
9093
  shamefully-hoist=false
@@ -9660,7 +9105,7 @@ shamefully-hoist=false
9660
9105
  * Update package.json name field
9661
9106
  */
9662
9107
  async function updatePackageName(projectPath, newName) {
9663
- const pkgPath = join$1(projectPath, 'package.json');
9108
+ const pkgPath = join(projectPath, 'package.json');
9664
9109
  if (!existsSync(pkgPath)) {
9665
9110
  if (process.env.DEBUG_BUILD === '1')
9666
9111
  console.log(` No package.json found in ${projectPath}, skipping name update`);
@@ -9683,7 +9128,7 @@ async function updatePackageName(projectPath, newName) {
9683
9128
  * This ensures projects respect PORT environment variable instead of hardcoded values
9684
9129
  */
9685
9130
  async function removeHardcodedPorts(projectPath) {
9686
- const pkgPath = join$1(projectPath, 'package.json');
9131
+ const pkgPath = join(projectPath, 'package.json');
9687
9132
  if (!existsSync(pkgPath)) {
9688
9133
  return;
9689
9134
  }
@@ -9729,9 +9174,9 @@ async function removeHardcodedPorts(projectPath) {
9729
9174
  * This is needed for Vite-based frameworks (including TanStack Start) to use dynamic ports
9730
9175
  */
9731
9176
  async function ensureVitePortConfig(projectPath) {
9732
- const viteConfigTs = join$1(projectPath, 'vite.config.ts');
9733
- const viteConfigJs = join$1(projectPath, 'vite.config.js');
9734
- const viteConfigMts = join$1(projectPath, 'vite.config.mts');
9177
+ const viteConfigTs = join(projectPath, 'vite.config.ts');
9178
+ const viteConfigJs = join(projectPath, 'vite.config.js');
9179
+ const viteConfigMts = join(projectPath, 'vite.config.mts');
9735
9180
  let configPath = null;
9736
9181
  if (existsSync(viteConfigTs))
9737
9182
  configPath = viteConfigTs;
@@ -9799,6 +9244,76 @@ async function getProjectFileTree(projectPath) {
9799
9244
  return `Project path: ${projectPath}`;
9800
9245
  }
9801
9246
 
9247
+ /**
9248
+ * Skill loader for composing agent system prompts from modular skill files.
9249
+ *
9250
+ * Skills are modular pieces of procedural knowledge that get conditionally
9251
+ * composed into the system prompt based on agent type and project context.
9252
+ * This is the fallback path for non-Claude agents (codex, opencode, droid).
9253
+ * Claude agents use SDK-native plugin discovery instead.
9254
+ */
9255
+ const __filename$2 = fileURLToPath(import.meta.url);
9256
+ const __dirname$2 = dirname(__filename$2);
9257
+ const skillCache = new Map();
9258
+ function stripFrontmatter(raw) {
9259
+ return raw.replace(/^---\n[\s\S]*?\n---\n*/, '').trim();
9260
+ }
9261
+ function loadSkill(name) {
9262
+ if (skillCache.has(name)) {
9263
+ return skillCache.get(name);
9264
+ }
9265
+ const candidates = [
9266
+ join(__dirname$2, 'platform-plugin', 'skills', name, 'SKILL.md'),
9267
+ join(__dirname$2, 'lib', 'skills', 'platform-plugin', 'skills', name, 'SKILL.md'),
9268
+ ];
9269
+ for (const candidate of candidates) {
9270
+ try {
9271
+ const raw = readFileSync(candidate, 'utf-8');
9272
+ const content = stripFrontmatter(raw);
9273
+ skillCache.set(name, content);
9274
+ return content;
9275
+ }
9276
+ catch {
9277
+ // Try next candidate
9278
+ }
9279
+ }
9280
+ process.stderr.write(`[skills] Could not load skill "${name}" from any path. Searched: ${candidates.join(', ')}\n`);
9281
+ return `[Skill "${name}" not found]`;
9282
+ }
9283
+ function composeSkills(context) {
9284
+ const sections = [];
9285
+ const loaded = [];
9286
+ function add(name) {
9287
+ sections.push(loadSkill(name));
9288
+ loaded.push(name);
9289
+ }
9290
+ // Agent-specific todo tracking
9291
+ if (context.agentId === 'openai-codex') {
9292
+ add('todo-workflow-codex');
9293
+ }
9294
+ else {
9295
+ add('todo-workflow');
9296
+ }
9297
+ // Always: communication and core discipline
9298
+ add('communication-style');
9299
+ add('context-awareness');
9300
+ add('dependency-management');
9301
+ // New project skills
9302
+ if (context.isNewProject) {
9303
+ add('architectural-thinking');
9304
+ add('template-originality');
9305
+ }
9306
+ // Design skills: new projects or when design tags present
9307
+ if (context.isNewProject || context.hasDesignTags) {
9308
+ add('design-excellence');
9309
+ }
9310
+ // Always: build verification
9311
+ add('build-verification');
9312
+ const totalChars = sections.reduce((sum, s) => sum + s.length, 0);
9313
+ process.stderr.write(`[skills] Composed ${loaded.length} skills (${totalChars} chars) for agent=${context.agentId} isNew=${context.isNewProject} hasDesign=${context.hasDesignTags}: [${loaded.join(', ')}]\n`);
9314
+ return sections;
9315
+ }
9316
+
9802
9317
  /**
9803
9318
  * Build Orchestrator - Handles complete build workflow
9804
9319
  * This replicates the functionality from the old /api/projects/[id]/generate route
@@ -10070,8 +9585,19 @@ async function orchestrateBuild(context) {
10070
9585
  hasConversationHistory: !!(conversationHistory && conversationHistory.length > 0),
10071
9586
  conversationHistoryCount: conversationHistory?.length || 0,
10072
9587
  });
9588
+ // For claude-code: platform skills are provisioned via the SDK's native skill
9589
+ // discovery (additionalDirectories + skills option). The SDK loads descriptions
9590
+ // into context and full content on-demand. No system prompt injection needed.
9591
+ // For other agents (codex, opencode, droid): skills are injected into the system prompt.
9592
+ const hasDesignTags = !!(tags && tags.some(t => t.key === 'brand' || t.key === 'framework'));
9593
+ const useNativeSkills = agent === 'claude-code';
9594
+ const skillSections = useNativeSkills ? [] : composeSkills({
9595
+ agentId: agent,
9596
+ isNewProject,
9597
+ hasDesignTags,
9598
+ });
10073
9599
  const systemPromptSections = await strategy.buildSystemPromptSections(strategyContext);
10074
- const systemPrompt = systemPromptSections.join('\n\n');
9600
+ const systemPrompt = [...skillSections, ...systemPromptSections].join('\n\n');
10075
9601
  buildLogger$1.orchestrator.systemPromptGenerated(systemPrompt.length);
10076
9602
  // Log snippet of system prompt for debugging
10077
9603
  if (!isNewProject && systemPrompt.includes('Recent Conversation History')) {
@@ -10109,21 +9635,21 @@ var TAG_DEFINITIONS = [
10109
9635
  inputType: "select",
10110
9636
  options: [
10111
9637
  {
10112
- value: "claude-sonnet-4-5",
10113
- label: "Claude Sonnet 4.5",
9638
+ value: "claude-sonnet-4-6",
9639
+ label: "Claude Sonnet 4.6",
10114
9640
  description: "Anthropic Claude - Balanced performance and speed",
10115
9641
  logo: "/claude.png",
10116
9642
  provider: "claude-code",
10117
- model: "claude-sonnet-4-5",
9643
+ model: "claude-sonnet-4-6",
10118
9644
  sdk: "agent"
10119
9645
  },
10120
9646
  {
10121
- value: "claude-opus-4-5",
10122
- label: "Claude Opus 4.5",
9647
+ value: "claude-opus-4-6",
9648
+ label: "Claude Opus 4.6",
10123
9649
  description: "Anthropic Claude - Most capable for complex tasks",
10124
9650
  logo: "/claude.png",
10125
9651
  provider: "claude-code",
10126
- model: "claude-opus-4-5",
9652
+ model: "claude-opus-4-6",
10127
9653
  sdk: "agent"
10128
9654
  },
10129
9655
  {
@@ -10147,10 +9673,10 @@ var TAG_DEFINITIONS = [
10147
9673
  {
10148
9674
  value: "factory-droid-opus",
10149
9675
  label: "Factory Droid (Opus)",
10150
- description: "Factory Droid SDK with Claude Opus 4.5",
9676
+ description: "Factory Droid SDK with Claude Opus 4.6",
10151
9677
  logo: "/factory.svg",
10152
9678
  provider: "factory-droid",
10153
- model: "claude-opus-4-5-20251101",
9679
+ model: "claude-opus-4-6-20251101",
10154
9680
  sdk: "droid"
10155
9681
  },
10156
9682
  {
@@ -10367,12 +9893,12 @@ var TAG_DEFINITIONS = [
10367
9893
  */
10368
9894
  // Map model IDs to Claude Agent SDK model names
10369
9895
  const MODEL_MAP = {
10370
- 'claude-haiku-4-5': 'claude-sonnet-4-5', // Haiku 4.5 not yet available, use Sonnet
10371
- 'claude-sonnet-4-5': 'claude-sonnet-4-5',
10372
- 'claude-opus-4-5': 'claude-opus-4-5',
9896
+ 'claude-haiku-4-5': 'claude-sonnet-4-6', // Haiku 4.5 not yet available, use Sonnet
9897
+ 'claude-sonnet-4-6': 'claude-sonnet-4-6',
9898
+ 'claude-opus-4-6': 'claude-opus-4-6',
10373
9899
  };
10374
9900
  function resolveModelName(modelId) {
10375
- return MODEL_MAP[modelId] || 'claude-sonnet-4-5';
9901
+ return MODEL_MAP[modelId] || 'claude-sonnet-4-6';
10376
9902
  }
10377
9903
  /**
10378
9904
  * Get a clean env object with only string values
@@ -10651,7 +10177,7 @@ function getTemplateFromTag(templates, tags) {
10651
10177
  */
10652
10178
  async function analyzeProject(options, sendEvent, commandId) {
10653
10179
  const { prompt, agent, claudeModel, tags } = options;
10654
- const model = claudeModel || 'claude-sonnet-4-5';
10180
+ const model = claudeModel || 'claude-sonnet-4-6';
10655
10181
  console.log('[project-analyzer] Starting project analysis...');
10656
10182
  console.log(`[project-analyzer] Agent: ${agent}, Model: ${model}`);
10657
10183
  // Emit analysis started
@@ -11072,7 +10598,7 @@ function createCodexQuery() {
11072
10598
  // Combine system prompt and user prompt
11073
10599
  // Note: Codex SDK doesn't have system prompt configuration, so we prepend it to the user prompt
11074
10600
  const combinedPrompt = `${systemParts.join("\n\n")}\n\n${prompt}`;
11075
- fileLog.info('Using CODEX_SYSTEM_PROMPT (TodoWrite references replaced with JSON code blocks)');
10601
+ fileLog.info('Using CODEX_SYSTEM_PROMPT (lean base) + modular skills from orchestrator');
11076
10602
  // Resume existing thread for enhancements, start new for initial builds
11077
10603
  let thread;
11078
10604
  // NOTE: MCP server configuration
@@ -12296,7 +11822,7 @@ async function startRunner(options = {}) {
12296
11822
  case "delete-project-files": {
12297
11823
  try {
12298
11824
  const { slug } = command.payload;
12299
- const projectPath = join$1(WORKSPACE_ROOT, slug);
11825
+ const projectPath = join(WORKSPACE_ROOT, slug);
12300
11826
  console.log(`[runner] 🗑️ Deleting project files for slug: ${slug}`);
12301
11827
  console.log(`[runner] Path: ${projectPath}`);
12302
11828
  // First, stop any running dev server for this project to release file locks
@@ -12368,8 +11894,8 @@ async function startRunner(options = {}) {
12368
11894
  case "read-file": {
12369
11895
  try {
12370
11896
  const { slug, filePath } = command.payload;
12371
- const projectPath = join$1(WORKSPACE_ROOT, slug);
12372
- const fullPath = join$1(projectPath, filePath);
11897
+ const projectPath = join(WORKSPACE_ROOT, slug);
11898
+ const fullPath = join(projectPath, filePath);
12373
11899
  console.log(`[runner] 📖 Reading file: ${filePath} from project: ${slug}`);
12374
11900
  // Security: Ensure path is within project directory
12375
11901
  if (!fullPath.startsWith(projectPath)) {
@@ -12402,8 +11928,8 @@ async function startRunner(options = {}) {
12402
11928
  case "write-file": {
12403
11929
  try {
12404
11930
  const { slug, filePath, content } = command.payload;
12405
- const projectPath = join$1(WORKSPACE_ROOT, slug);
12406
- const fullPath = join$1(projectPath, filePath);
11931
+ const projectPath = join(WORKSPACE_ROOT, slug);
11932
+ const fullPath = join(projectPath, filePath);
12407
11933
  console.log(`[runner] 💾 Writing file: ${filePath} to project: ${slug}`);
12408
11934
  // Security: Ensure path is within project directory
12409
11935
  if (!fullPath.startsWith(projectPath)) {
@@ -12433,8 +11959,8 @@ async function startRunner(options = {}) {
12433
11959
  case "list-files": {
12434
11960
  try {
12435
11961
  const { slug, path: subPath } = command.payload;
12436
- const projectPath = join$1(WORKSPACE_ROOT, slug);
12437
- const targetPath = subPath ? join$1(projectPath, subPath) : projectPath;
11962
+ const projectPath = join(WORKSPACE_ROOT, slug);
11963
+ const targetPath = subPath ? join(projectPath, subPath) : projectPath;
12438
11964
  console.log(`[runner] 📁 Listing files for project: ${slug}`);
12439
11965
  console.log(`[runner] Path: ${targetPath}`);
12440
11966
  // Security: Ensure path is within project directory
@@ -12444,8 +11970,8 @@ async function startRunner(options = {}) {
12444
11970
  const { readdir, stat } = await import('node:fs/promises');
12445
11971
  const entries = await readdir(targetPath);
12446
11972
  const files = await Promise.all(entries.map(async (name) => {
12447
- const entryPath = join$1(targetPath, name);
12448
- const relativePath = subPath ? join$1(subPath, name) : name;
11973
+ const entryPath = join(targetPath, name);
11974
+ const relativePath = subPath ? join(subPath, name) : name;
12449
11975
  const stats = await stat(entryPath);
12450
11976
  return {
12451
11977
  name,
@@ -12482,8 +12008,8 @@ async function startRunner(options = {}) {
12482
12008
  const claudeModelFromPayload = command.payload?.claudeModel;
12483
12009
  const model = agent === 'claude-code' &&
12484
12010
  (claudeModelFromPayload === 'claude-haiku-4-5' ||
12485
- claudeModelFromPayload === 'claude-sonnet-4-5' ||
12486
- claudeModelFromPayload === 'claude-opus-4-5')
12011
+ claudeModelFromPayload === 'claude-sonnet-4-6' ||
12012
+ claudeModelFromPayload === 'claude-opus-4-6')
12487
12013
  ? claudeModelFromPayload
12488
12014
  : DEFAULT_CLAUDE_MODEL_ID;
12489
12015
  logger.buildReceived({
@@ -12524,8 +12050,8 @@ async function startRunner(options = {}) {
12524
12050
  log("selected agent:", agent);
12525
12051
  const claudeModel = agent === "claude-code" &&
12526
12052
  (command.payload.claudeModel === "claude-haiku-4-5" ||
12527
- command.payload.claudeModel === "claude-sonnet-4-5" ||
12528
- command.payload.claudeModel === "claude-opus-4-5")
12053
+ command.payload.claudeModel === "claude-sonnet-4-6" ||
12054
+ command.payload.claudeModel === "claude-opus-4-6")
12529
12055
  ? command.payload.claudeModel
12530
12056
  : DEFAULT_CLAUDE_MODEL_ID;
12531
12057
  // For factory-droid, use the droidModel from payload
@@ -12902,7 +12428,7 @@ async function startRunner(options = {}) {
12902
12428
  // Detect runCommand from built project's package.json
12903
12429
  try {
12904
12430
  const { readFileSync, existsSync } = await import('fs');
12905
- const packageJsonPath = join$1(projectDirectory, "package.json");
12431
+ const packageJsonPath = join(projectDirectory, "package.json");
12906
12432
  if (existsSync(packageJsonPath)) {
12907
12433
  const packageJson = JSON.parse(readFileSync(packageJsonPath, "utf-8"));
12908
12434
  let runCommand = null;
@@ -13357,6 +12883,11 @@ Write a brief, professional summary (1-3 sentences) describing what was accompli
13357
12883
  lastCommandReceived = Date.now(); // Reset command timer on new connection
13358
12884
  // Update logger connection status
13359
12885
  logger.setConnected(true);
12886
+ Sentry.logger.info('Runner connected to server', {
12887
+ runnerId: RUNNER_ID,
12888
+ serverUrl: WS_URL,
12889
+ workspace: WORKSPACE_ROOT,
12890
+ });
13360
12891
  debugLog("Health check: ping/pong enabled, command timeout: 5 minutes");
13361
12892
  publishStatus();
13362
12893
  scheduleHeartbeat();
@@ -13429,10 +12960,10 @@ Write a brief, professional summary (1-3 sentences) describing what was accompli
13429
12960
  const agent = command.payload.agent ?? 'claude-code';
13430
12961
  const claudeModel = agent === 'claude-code' &&
13431
12962
  (command.payload.claudeModel === 'claude-haiku-4-5' ||
13432
- command.payload.claudeModel === 'claude-sonnet-4-5' ||
13433
- command.payload.claudeModel === 'claude-opus-4-5')
12963
+ command.payload.claudeModel === 'claude-sonnet-4-6' ||
12964
+ command.payload.claudeModel === 'claude-opus-4-6')
13434
12965
  ? command.payload.claudeModel
13435
- : 'claude-sonnet-4-5';
12966
+ : 'claude-sonnet-4-6';
13436
12967
  Sentry.metrics.count('runner.build.started', 1, {
13437
12968
  attributes: {
13438
12969
  project_id: command.projectId,
@@ -13473,10 +13004,10 @@ Write a brief, professional summary (1-3 sentences) describing what was accompli
13473
13004
  const agent = command.payload.agent ?? 'claude-code';
13474
13005
  const claudeModel = agent === 'claude-code' &&
13475
13006
  (command.payload.claudeModel === 'claude-haiku-4-5' ||
13476
- command.payload.claudeModel === 'claude-sonnet-4-5' ||
13477
- command.payload.claudeModel === 'claude-opus-4-5')
13007
+ command.payload.claudeModel === 'claude-sonnet-4-6' ||
13008
+ command.payload.claudeModel === 'claude-opus-4-6')
13478
13009
  ? command.payload.claudeModel
13479
- : 'claude-sonnet-4-5';
13010
+ : 'claude-sonnet-4-6';
13480
13011
  Sentry.metrics.count('runner.build.started', 1, {
13481
13012
  attributes: {
13482
13013
  project_id: command.projectId,