@compilr-dev/cli 0.8.10 → 0.9.1

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.
Files changed (32) hide show
  1. package/CHANGELOG.md +35 -0
  2. package/dist/agent.d.ts +9 -0
  3. package/dist/agent.js +1 -0
  4. package/dist/commands-v2/handlers/project.js +88 -229
  5. package/dist/commands-v2/handlers/skill.js +10 -6
  6. package/dist/commands-v2/handlers/team.d.ts +19 -1
  7. package/dist/commands-v2/handlers/team.js +178 -3
  8. package/dist/compilr-diff-companion.vsix +0 -0
  9. package/dist/index.js +55 -3
  10. package/dist/multi-agent/agent-edit.d.ts +75 -0
  11. package/dist/multi-agent/agent-edit.js +84 -0
  12. package/dist/multi-agent/capability-loader.d.ts +15 -5
  13. package/dist/multi-agent/capability-loader.js +18 -8
  14. package/dist/multi-agent/custom-agents.d.ts +12 -0
  15. package/dist/multi-agent/custom-agents.js +22 -1
  16. package/dist/repl-helpers.d.ts +6 -1
  17. package/dist/repl-helpers.js +14 -7
  18. package/dist/repl-v2.d.ts +10 -0
  19. package/dist/repl-v2.js +43 -2
  20. package/dist/ui/overlay/impl/agent-edit-overlay-v2.d.ts +105 -0
  21. package/dist/ui/overlay/impl/agent-edit-overlay-v2.js +364 -0
  22. package/dist/ui/overlay/impl/custom-agent-form-overlay-v2.d.ts +1 -8
  23. package/dist/ui/overlay/impl/custom-agent-form-overlay-v2.js +16 -120
  24. package/dist/ui/overlay/impl/project-edit-overlay-v2.d.ts +2 -1
  25. package/dist/ui/overlay/impl/project-edit-overlay-v2.js +26 -19
  26. package/dist/ui/overlay/impl/skills-overlay-v2.d.ts +42 -2
  27. package/dist/ui/overlay/impl/skills-overlay-v2.js +238 -185
  28. package/dist/ui/overlay/impl/team-overlay-v2.d.ts +1 -2
  29. package/dist/ui/overlay/impl/team-overlay-v2.js +6 -9
  30. package/dist/ui/terminal-types.d.ts +8 -0
  31. package/dist/utils/model-tiers.js +5 -0
  32. package/package.json +2 -2
package/CHANGELOG.md CHANGED
@@ -12,6 +12,41 @@ and this project follows [Semantic Versioning](https://semver.org/spec/v2.0.0.ht
12
12
 
13
13
  ## [Unreleased]
14
14
 
15
+ ## [0.9.0] — 2026-09-20
16
+
17
+ The published package had fallen a long way behind `main`: `0.8.10` on npm still
18
+ declared `@compilr-dev/sdk ^0.18.11`. This release carries twenty commits of work that
19
+ had been committed but never shipped.
20
+
21
+ ### Changed
22
+ - **Skills and macros are now separate things, and the CLI says so.** A *macro* is a
23
+ shipped prompt you type (`/design`, `/prd`); a *skill* is a `SKILL.md` folder a model
24
+ chooses for itself. Every symbol, message and screen that conflated them has been
25
+ renamed — including the eight "skill not found" errors, which now say macro.
26
+ - **`/skill` lost its Built-in tab.** It listed macros inside a manager for skills.
27
+ Forking a built-in moved to where creating begins: `n` → *from a command*, with the
28
+ same searchable list. Bindings are unchanged and still editable.
29
+ - **`Space` in `/skill` now writes the two Anthropic fields** (`disable-model-invocation`,
30
+ `user-invocable`) instead of a non-standard `enabled` key, and removes `enabled` from
31
+ any file it touches. A skill shelved in the Desktop app previously read as *live* in
32
+ the terminal — the list and the resolver disagreed in front of you.
33
+ - **Project editing gained five fields** — docs path, language, framework, package
34
+ manager and runtime — matching what the Desktop app edits. Both hosts now write through
35
+ one shared mapping.
36
+ - **An emptied field clears the value.** It previously meant "leave alone", so a git
37
+ remote could be set from the CLI but never removed.
38
+
39
+ ### Added
40
+ - Each agent is given the skills it may choose, rather than all of them.
41
+ - An agent is warned when a macro needs tools it does not have.
42
+
43
+ ### Fixed
44
+ - The seven wrapped macros compose their message through the SDK, so the CLI and the
45
+ Desktop app send a command the same way instead of drifting apart.
46
+
47
+ ---
48
+
49
+
15
50
  ## [0.6.2] — 2026-04-25
16
51
 
17
52
  ### Fixed
package/dist/agent.d.ts CHANGED
@@ -8,6 +8,7 @@
8
8
  import { Agent } from '@compilr-dev/sdk';
9
9
  import type { AgentEvent, Tool, GuardrailTriggeredHandler } from '@compilr-dev/sdk';
10
10
  import type { PermissionHandler } from '@compilr-dev/agents';
11
+ import type { CustomSkill } from '@compilr-dev/sdk';
11
12
  import type { EpisodeRecorder } from './episodes/index.js';
12
13
  /**
13
14
  * Supported providers (re-exported from models/provider-types)
@@ -96,6 +97,14 @@ export interface AgentOptions {
96
97
  toolFilter?: string[];
97
98
  /** MCP tools from external MCP servers */
98
99
  mcpTools?: Tool[];
100
+ /**
101
+ * Skills this agent may CHOOSE, already filtered for eligibility by the caller.
102
+ *
103
+ * Distinct from the slash commands a user types: the SDK turns these into an "Available
104
+ * Skills" catalogue (descriptions only) plus a `load_skill` tool. Filtering happens at the
105
+ * call site because only it knows which agent is being built — see `resolveSkillsForTeamAgent`.
106
+ */
107
+ skills?: CustomSkill[];
99
108
  /** Episode recorder for work history tracking */
100
109
  episodeRecorder?: EpisodeRecorder;
101
110
  }
package/dist/agent.js CHANGED
@@ -310,6 +310,7 @@ export function createAgent(options = {}) {
310
310
  // so the agent calls into the CLI's existing terminal overlays
311
311
  // (showAskUserOverlayV2 / showAskUserSimpleOverlayV2) plus the
312
312
  // background-agent question-routing path.
313
+ skills: options.skills,
313
314
  capabilities: (options.enableMetaTools && !options.minimal && !options.noTools)
314
315
  ? {
315
316
  enabled: true,
@@ -10,14 +10,14 @@ import { setCurrentProject, getCurrentProject } from '../../tools/project-db.js'
10
10
  import { getSkillPrompt } from '../../repl-helpers.js';
11
11
  import { getModelTier, modelMeetsTier } from '../../utils/model-tiers.js';
12
12
  import { getCurrentProjectIdForTracking, handleProjectSwitch, saveCurrentTeam } from './session.js';
13
- import { loadCapabilitiesForSkill } from '../../multi-agent/capability-loader.js';
14
- import { normalizeRoleName } from '@compilr-dev/sdk';
13
+ import { loadCapabilitiesForMacro } from '../../multi-agent/capability-loader.js';
14
+ import { normalizeRoleName, buildMacroInvocation } from '@compilr-dev/sdk';
15
15
  /**
16
16
  * Load capabilities for a skill and warn about forbidden packs.
17
17
  * Called before queuing a skill-driven agent message.
18
18
  */
19
- function loadSkillCapabilities(skillName, ctx) {
20
- const result = loadCapabilitiesForSkill(skillName);
19
+ function loadMacroCapabilities(skillName, ctx) {
20
+ const result = loadCapabilitiesForMacro(skillName);
21
21
  if (!result)
22
22
  return; // No capability loading active or no requirements
23
23
  if (result.forbidden.length > 0) {
@@ -417,37 +417,28 @@ export const designCommand = {
417
417
  }
418
418
  }
419
419
  // Load capabilities for the design skill
420
- loadSkillCapabilities('design', ctx);
420
+ loadMacroCapabilities('design', ctx);
421
421
  // Get design skill prompt
422
422
  const designPrompt = getSkillPrompt('design');
423
423
  if (!designPrompt) {
424
- ctx.ui.print({ type: 'error', message: 'Design skill not found.' });
424
+ ctx.ui.print({ type: 'error', message: 'Design macro not found.' });
425
425
  return true;
426
426
  }
427
- // Build full message for agent with project context
428
- const fullMessage = `I want to design my project and create the backlog.
429
-
430
- ## PROJECT CONTEXT (IMPORTANT)
431
- - Project Name: ${currentProject.name} (ID: ${String(currentProject.id)})
432
- - This is a NEW project being designed from scratch
433
- - Do NOT scan the filesystem - the current directory is NOT the project
434
- - Do NOT use detect_project, glob, read_file, or ls tools
435
- - Focus ONLY on gathering requirements via ask_user questions
436
-
437
- ## DOCUMENT STORAGE (CRITICAL)
438
- Save all documents and backlog items using the database - do NOT write files directly.
439
- - For backlog items: \`workitem_add({ type: "feature", title: "...", description: "...", priority: "high" })\`
440
- - For documents: \`project_document_add({ doc_type: "prd", title: "...", content: "..." })\`
441
- - The database is the source of truth for all project documents
442
- - Do NOT use write_file or edit tools for documentation
443
-
444
- ${designPrompt}
445
-
446
- Please start by using todo_write to track the design phases, then begin with Phase 1: Vision. Use the ask_user tool to gather information efficiently.`;
427
+ /*
428
+ ⚠️ COMPOSED IN THE SDK, NOT HERE. This block used to be ~20 lines of project context written
429
+ inline — and Desktop's /design sent the macro prompt with none of it, so the same command
430
+ produced an agent that interviewed you and filled the backlog here, and one that went
431
+ looking for source files there. The text is unchanged; it just lives where both hosts reach
432
+ it. Byte-identical output is asserted in the SDK's macro-invocation tests.
433
+ */
434
+ const invocation = buildMacroInvocation('design', designPrompt, {
435
+ project: { id: currentProject.id, name: currentProject.name },
436
+ });
447
437
  // Queue message for agent
448
438
  ctx.queueAgentMessage({
449
- message: fullMessage,
450
- displayMessage: 'Start the design process for my project.',
439
+ macro: 'design',
440
+ message: invocation.message,
441
+ displayMessage: invocation.displayMessage,
451
442
  });
452
443
  return true;
453
444
  },
@@ -468,36 +459,20 @@ export const sketchCommand = {
468
459
  return Promise.resolve(true);
469
460
  }
470
461
  // Load capabilities for the sketch skill
471
- loadSkillCapabilities('sketch', ctx);
462
+ loadMacroCapabilities('sketch', ctx);
472
463
  // Get sketch skill prompt
473
464
  const sketchPrompt = getSkillPrompt('sketch');
474
465
  if (!sketchPrompt) {
475
- ctx.ui.print({ type: 'error', message: 'Sketch skill not found.' });
466
+ ctx.ui.print({ type: 'error', message: 'Sketch macro not found.' });
476
467
  return Promise.resolve(true);
477
468
  }
478
- // Build full message for agent with project context
479
- const fullMessage = `I want to quickly outline my project.
480
-
481
- ## PROJECT CONTEXT (IMPORTANT)
482
- - Project Name: ${currentProject.name} (ID: ${String(currentProject.id)})
483
- - This is a NEW project being designed from scratch
484
- - Do NOT scan the filesystem - the current directory is NOT the project
485
- - Do NOT use detect_project, glob, read_file, or ls tools
486
- - Focus ONLY on gathering requirements via ask_user questions
487
-
488
- ## DOCUMENT STORAGE (CRITICAL)
489
- Save all documents and backlog items using the database - do NOT write files directly.
490
- - For backlog items: \`workitem_add({ type: "feature", title: "...", description: "..." })\`
491
- - For documents: \`project_document_add({ doc_type: "prd", title: "...", content: "..." })\`
492
- - Do NOT use write_file or edit tools for documentation
493
-
494
- ${sketchPrompt}
495
-
496
- Please start by asking me about the type of application I'm building using the ask_user_simple tool.`;
497
- // Queue message for agent
469
+ const invocation = buildMacroInvocation('sketch', sketchPrompt, {
470
+ project: { id: currentProject.id, name: currentProject.name },
471
+ });
498
472
  ctx.queueAgentMessage({
499
- message: fullMessage,
500
- displayMessage: 'Quick project outline.',
473
+ macro: 'sketch',
474
+ message: invocation.message,
475
+ displayMessage: invocation.displayMessage,
501
476
  });
502
477
  return Promise.resolve(true);
503
478
  },
@@ -561,40 +536,20 @@ export const refineCommand = {
561
536
  }
562
537
  // Get appropriate skill prompt and load capabilities
563
538
  const skillName = isFocusedRefine ? 'refine-item' : 'refine';
564
- loadSkillCapabilities(skillName, ctx);
539
+ loadMacroCapabilities(skillName, ctx);
565
540
  const refinePrompt = getSkillPrompt(skillName);
566
541
  if (!refinePrompt) {
567
- ctx.ui.print({ type: 'error', message: `${skillName} skill not found.` });
542
+ ctx.ui.print({ type: 'error', message: `${skillName} macro not found.` });
568
543
  return true;
569
544
  }
570
- // Build message based on mode
571
- const userIntent = isFocusedRefine
572
- ? `I want to refine backlog item ${itemId}.`
573
- : 'I want to refine my project requirements.';
574
- const agentInstructions = isFocusedRefine
575
- ? `Please use workitem_query to find item "${itemId}", then guide me through refining it using workitem_update.`
576
- : '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.';
577
- const fullMessage = `${userIntent}
578
-
579
- ## PROJECT CONTEXT (IMPORTANT)
580
- - Project Name: ${currentProject.name} (ID: ${String(currentProject.id)})
581
- - Do NOT scan the filesystem - the current directory is NOT the project
582
- - Do NOT use detect_project, glob, read_file, or ls tools
583
- - Use ONLY database tools to access project data
584
-
585
- ## DOCUMENT STORAGE (CRITICAL)
586
- Use database tools for all updates - do NOT write files directly.
587
- - Use \`workitem_query\` to read items
588
- - Use \`workitem_update\` to modify items
589
- - Do NOT use write_file or edit tools
590
-
591
- ${refinePrompt}
592
-
593
- ${agentInstructions}`;
594
- // Queue message for agent
545
+ const invocation = buildMacroInvocation(skillName, refinePrompt, {
546
+ project: { id: currentProject.id, name: currentProject.name },
547
+ refineItemId: isFocusedRefine ? itemId : undefined,
548
+ });
595
549
  ctx.queueAgentMessage({
596
- message: fullMessage,
597
- displayMessage: userIntent,
550
+ macro: skillName,
551
+ message: invocation.message,
552
+ displayMessage: invocation.displayMessage,
598
553
  });
599
554
  return true;
600
555
  },
@@ -692,10 +647,10 @@ export const buildCommand = {
692
647
  }
693
648
  }
694
649
  // Load capabilities and get build skill prompt
695
- loadSkillCapabilities('build', ctx);
650
+ loadMacroCapabilities('build', ctx);
696
651
  let buildPrompt = getSkillPrompt('build');
697
652
  if (!buildPrompt) {
698
- ctx.ui.print({ type: 'error', message: 'Build skill not found.' });
653
+ ctx.ui.print({ type: 'error', message: 'Build macro not found.' });
699
654
  return true;
700
655
  }
701
656
  // Replace {{projectPath}} and item placeholders with actual values
@@ -706,48 +661,20 @@ export const buildCommand = {
706
661
  .replace(/\{\{item_type\}\}/g, selectedItem.type)
707
662
  .replace(/\{\{item_priority\}\}/g, selectedItem.priority)
708
663
  .replace(/\{\{item_description\}\}/g, selectedItem.description ?? 'No description provided');
709
- // Build full message for agent with explicit project path context
710
- const fullMessage = `I want to implement backlog item ${selectedItem.itemId}: "${selectedItem.title}".
711
-
712
- ## PROJECT CONTEXT (CRITICAL)
713
- - Project Name: ${currentProject.name} (ID: ${String(currentProject.id)})
714
- - **Project Directory: ${currentProject.path}**
715
- - ALL files MUST be created/modified in this directory
716
-
717
- ## WORK ITEM DETAILS
718
- - Item ID: ${selectedItem.itemId}
719
- - Type: ${selectedItem.type}
720
- - Priority: ${selectedItem.priority}
721
- - Description: ${selectedItem.description ?? 'No description provided'}
722
-
723
- ## TOOL RESTRICTIONS (CRITICAL)
724
- - Do NOT use detect_project or find_project_root
725
- - Do NOT scan filesystem to detect project type
726
- - The project path above is the ONLY source of truth for where to create/modify files
727
- - Use \`project_document_get\` to read PRD and architecture docs from the database
728
- - Use \`workitem_query\` to read related backlog items from the database
729
- - Use \`workitem_update\` to update the item status when done
730
-
731
- ## FILE OPERATIONS (CRITICAL)
732
- When creating or modifying files:
733
- - Use absolute paths starting with: ${currentProject.path}/
734
- - Example: write_file({ path: "${currentProject.path}/src/index.ts", ... })
735
- - NEVER use relative paths
736
- - IGNORE the current working directory (cwd) - it may be different from the project!
737
- - The user may have started the CLI from a different folder
738
-
739
- ${buildPrompt}
740
-
741
- Please start by:
742
- 1. Using todo_write to plan the implementation steps
743
- 2. Reading project documents from the database (project_document_list, project_document_get)
744
- 3. Updating the work item status to 'in_progress' using workitem_update
745
- 4. Implementing the feature
746
- 5. Updating the work item status to 'completed' when done`;
747
- // Queue message for agent
664
+ const invocation = buildMacroInvocation('build', buildPrompt, {
665
+ project: { id: currentProject.id, name: currentProject.name, path: currentProject.path },
666
+ workItem: {
667
+ itemId: selectedItem.itemId,
668
+ type: selectedItem.type,
669
+ priority: selectedItem.priority,
670
+ title: selectedItem.title,
671
+ description: selectedItem.description ?? undefined,
672
+ },
673
+ });
748
674
  ctx.queueAgentMessage({
749
- message: fullMessage,
750
- displayMessage: `Build ${selectedItem.itemId}: ${selectedItem.title}`,
675
+ macro: 'build',
676
+ message: invocation.message,
677
+ displayMessage: invocation.displayMessage,
751
678
  });
752
679
  return true;
753
680
  },
@@ -771,41 +698,22 @@ export const noteCommand = {
771
698
  return Promise.resolve(true);
772
699
  }
773
700
  // Load capabilities and get session-notes skill prompt
774
- loadSkillCapabilities('session-notes', ctx);
701
+ loadMacroCapabilities('session-notes', ctx);
775
702
  const notePrompt = getSkillPrompt('session-notes');
776
703
  if (!notePrompt) {
777
- ctx.ui.print({ type: 'error', message: 'Session-notes skill not found.' });
704
+ ctx.ui.print({ type: 'error', message: 'Session-notes macro not found.' });
778
705
  return Promise.resolve(true);
779
706
  }
780
707
  // Check for optional title argument
781
708
  const noteTitle = args.trim();
782
- // Build title instruction based on whether title was provided
783
- const titleInstruction = noteTitle
784
- ? `The session title is: "${noteTitle}"`
785
- : 'Please ask me for a title using ask_user_simple, or generate one from the session summary.';
786
- // Build full message for agent
787
- const fullMessage = `I want to create a session note capturing what we've done.
788
-
789
- ## PROJECT CONTEXT
790
- - Project Name: ${currentProject.name} (ID: ${String(currentProject.id)})
791
-
792
- ## DOCUMENT STORAGE (CRITICAL)
793
- Save session notes using the database - do NOT write files directly.
794
- - Tool: \`project_document_add({ doc_type: "session-note", title: "...", content: "..." })\`
795
- - The database is the source of truth for all project documents
796
- - Do NOT use write_file or edit tools for documentation
797
-
798
- ${notePrompt}
799
-
800
- ${titleInstruction}
801
-
802
- Review the conversation context to understand what was accomplished, then create the session note.`;
803
- // Queue message for agent
709
+ const invocation = buildMacroInvocation('session-notes', notePrompt, {
710
+ project: { id: currentProject.id, name: currentProject.name },
711
+ noteTitle: noteTitle || undefined,
712
+ });
804
713
  ctx.queueAgentMessage({
805
- message: fullMessage,
806
- displayMessage: noteTitle
807
- ? `Create session note: "${noteTitle}"`
808
- : 'Create a session note for this session.',
714
+ macro: 'session-notes',
715
+ message: invocation.message,
716
+ displayMessage: invocation.displayMessage,
809
717
  });
810
718
  return Promise.resolve(true);
811
719
  },
@@ -830,39 +738,22 @@ export const prdCommand = {
830
738
  return Promise.resolve(true);
831
739
  }
832
740
  // Load capabilities and get PRD skill prompt
833
- loadSkillCapabilities('prd', ctx);
741
+ loadMacroCapabilities('prd', ctx);
834
742
  const prdPrompt = getSkillPrompt('prd');
835
743
  if (!prdPrompt) {
836
- ctx.ui.print({ type: 'error', message: 'PRD skill not found.' });
744
+ ctx.ui.print({ type: 'error', message: 'PRD macro not found.' });
837
745
  return Promise.resolve(true);
838
746
  }
839
747
  // Check for optional section argument
840
748
  const section = args.trim().toLowerCase();
841
- const validSections = ['vision', 'scope', 'technical', 'success'];
842
- const sectionInstruction = validSections.includes(section)
843
- ? `The user wants to update the "${section}" section specifically.`
844
- : 'Ask the user which section they want to update using ask_user_simple.';
845
- // Build full message for agent with project context
846
- const fullMessage = `I want to update the Product Requirements Document.
847
-
848
- ## DOCUMENT STORAGE (CRITICAL)
849
- Save PRD updates using the database - do NOT write files directly.
850
- - Project: ${currentProject.name} (ID: ${String(currentProject.id)})
851
- - Tool: \`project_document_add({ doc_type: "prd", title: "Product Requirements Document", content: "..." })\`
852
- - The database is the source of truth for all project documents
853
- - Do NOT use write_file or edit tools for documentation
854
-
855
- ${prdPrompt}
856
-
857
- ${sectionInstruction}
858
-
859
- 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.`;
860
- // Queue message for agent
749
+ const invocation = buildMacroInvocation('prd', prdPrompt, {
750
+ project: { id: currentProject.id, name: currentProject.name },
751
+ section: section || undefined,
752
+ });
861
753
  ctx.queueAgentMessage({
862
- message: fullMessage,
863
- displayMessage: section
864
- ? `Update PRD: ${section} section`
865
- : 'Update the Product Requirements Document',
754
+ macro: 'prd',
755
+ message: invocation.message,
756
+ displayMessage: invocation.displayMessage,
866
757
  });
867
758
  return Promise.resolve(true);
868
759
  },
@@ -956,46 +847,23 @@ export const scaffoldCommand = {
956
847
  skillName = 'scaffold';
957
848
  }
958
849
  // Load capability packs for this skill
959
- loadSkillCapabilities(skillName, ctx);
850
+ loadMacroCapabilities(skillName, ctx);
960
851
  // Get skill prompt and replace path placeholder
961
852
  let scaffoldPrompt = getSkillPrompt(skillName);
962
853
  if (!scaffoldPrompt) {
963
- ctx.ui.print({ type: 'error', message: `${skillName} skill not found.` });
854
+ ctx.ui.print({ type: 'error', message: `${skillName} macro not found.` });
964
855
  return true;
965
856
  }
966
857
  scaffoldPrompt = scaffoldPrompt.replace(/\{\{projectPath\}\}/g, currentProject.path);
967
- const closingInstruction = skillName === 'factory-scaffold'
968
- ? '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.'
969
- : '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.';
970
- // Build full message for agent with explicit project path context
971
- const fullMessage = `I want to create the project scaffold/foundation.
972
-
973
- ## PROJECT CONTEXT (CRITICAL)
974
- - Project Name: ${currentProject.name} (ID: ${String(currentProject.id)})
975
- - **Project Directory: ${currentProject.path}**
976
- - ALL files MUST be created in this directory
977
- ${factoryContext}
978
- ## TOOL RESTRICTIONS (CRITICAL)
979
- - Do NOT use detect_project or find_project_root
980
- - Do NOT scan filesystem to detect project type
981
- - The project path above is the ONLY source of truth for where to create files
982
- - Use \`project_document_get\` to read PRD and architecture docs from the database
983
- - Use \`workitem_query\` to read backlog items from the database
984
-
985
- ## FILE CREATION (CRITICAL)
986
- When creating files:
987
- - Use absolute paths starting with: ${currentProject.path}/
988
- - Example: write_file({ path: "${currentProject.path}/package.json", ... })
989
- - NEVER use relative paths
990
- - IGNORE the current working directory (cwd) - it may be different from the project!
991
- - The user may have started the CLI from a different folder
992
-
993
- ${scaffoldPrompt}
994
-
995
- ${closingInstruction}`;
996
- // Queue message for agent
858
+ const invocation = buildMacroInvocation(skillName, scaffoldPrompt, {
859
+ project: { id: currentProject.id, name: currentProject.name, path: currentProject.path },
860
+ scaffold: { factoryContext, isFactory: skillName === 'factory-scaffold' },
861
+ });
997
862
  ctx.queueAgentMessage({
998
- message: fullMessage,
863
+ macro: skillName,
864
+ message: invocation.message,
865
+ // ⚠️ The CLI's own line, not the SDK's: it distinguishes three cases from app-model state
866
+ // that only this host has looked up. The MESSAGE is shared; this label is presentation.
999
867
  displayMessage: hasAppModel
1000
868
  ? 'Generate project from Application Model.'
1001
869
  : prdMentionsEntities
@@ -1038,10 +906,10 @@ export const archCommand = {
1038
906
  return true;
1039
907
  }
1040
908
  // Load capabilities and get architecture skill prompt
1041
- loadSkillCapabilities('architecture', ctx);
909
+ loadMacroCapabilities('architecture', ctx);
1042
910
  const archPrompt = getSkillPrompt('architecture');
1043
911
  if (!archPrompt) {
1044
- ctx.ui.print({ type: 'error', message: 'Architecture skill not found.' });
912
+ ctx.ui.print({ type: 'error', message: 'Architecture macro not found.' });
1045
913
  return true;
1046
914
  }
1047
915
  // Build the document type description for display
@@ -1059,23 +927,14 @@ export const archCommand = {
1059
927
  const finalPrompt = archPrompt
1060
928
  .replace('{{doc_type}}', archChoice.type)
1061
929
  .replace('{{#if custom_topic}}Custom Topic: {{custom_topic}}{{/if}}', archChoice.customTopic ? `Custom Topic: ${archChoice.customTopic}` : '');
1062
- // Build full message for agent with project context
1063
- const fullMessage = `I want to create architecture documentation.
1064
-
1065
- ## DOCUMENT STORAGE (CRITICAL)
1066
- Save architecture documentation using the database - do NOT write files directly.
1067
- - Project: ${currentProject.name} (ID: ${String(currentProject.id)})
1068
- - Tool: \`project_document_add({ doc_type: "architecture", title: "...", content: "..." })\`
1069
- - The database is the source of truth for all project documents
1070
- - Do NOT use write_file or edit tools for documentation
1071
-
1072
- ${finalPrompt}
1073
-
1074
- 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 ${archChoice.type} document.`;
1075
- // Queue message for agent
930
+ const invocation = buildMacroInvocation('architecture', finalPrompt, {
931
+ project: { id: currentProject.id, name: currentProject.name },
932
+ architecture: { docType: archChoice.type, displayType },
933
+ });
1076
934
  ctx.queueAgentMessage({
1077
- message: fullMessage,
1078
- displayMessage: `Create ${displayType} documentation.`,
935
+ macro: 'architecture',
936
+ message: invocation.message,
937
+ displayMessage: invocation.displayMessage,
1079
938
  });
1080
939
  return true;
1081
940
  },
@@ -7,29 +7,30 @@
7
7
  * Spec: project-docs/00-requirements/compilr-dev-cli/skills-overlay-spec.md
8
8
  */
9
9
  import { promises as fs } from 'node:fs';
10
+ import { getCliSkillSources } from '../../repl-helpers.js';
10
11
  import { SkillsOverlayV2 } from '../../ui/overlay/impl/skills-overlay-v2.js';
11
12
  import { SkillDetailOverlayV2 } from '../../ui/overlay/impl/skill-detail-overlay-v2.js';
12
13
  import { getCurrentProject } from '../../tools/project-db.js';
13
14
  const skillCommand = {
14
15
  name: 'skill',
15
16
  aliases: ['skills'],
16
- description: 'Manage custom and built-in skills',
17
+ description: 'Manage your skills and their slash-command bindings',
17
18
  details: 'Browse, create, edit, and manage user-authored skills. Skills are ' +
18
19
  'folders with SKILL.md (Anthropic Agent Skills format). Custom skills ' +
19
- 'can be scoped to a project or user. Built-in SDK skills are read-only.',
20
+ 'can be scoped to a project or user. Built-in commands are not skills ' +
21
+ 'and are not listed here — fork one from "New skill → from a command".',
20
22
  examples: [
21
23
  { code: '/skill', description: 'Open Skills overlay' },
22
24
  { code: '/skills', description: 'Alias for /skill' },
23
25
  ],
24
26
  interactions: [
25
- '←→ Switch tabs (Custom / Built-in)',
27
+ '←→ Switch tabs (Custom / Bindings)',
26
28
  '↑↓ or j/k Navigate skills',
27
29
  'Enter Open skill (view/edit/diff)',
28
- 'n Create new skill',
29
- 'f Fork SDK skill',
30
+ 'n Create new skill (blank, or forked from a command)',
30
31
  'b Bind slash command',
31
32
  'u Unbind slash command',
32
- 'Space Enable/disable skill',
33
+ 'Space Shelve / restore (writes the two Anthropic switches)',
33
34
  'd Delete skill',
34
35
  'r Rename skill',
35
36
  '/ Search skills',
@@ -39,6 +40,9 @@ const skillCommand = {
39
40
  const project = getCurrentProject();
40
41
  const overlay = new SkillsOverlayV2({
41
42
  projectPath: project?.path ?? undefined,
43
+ // The same sources the resolver gets, so what this overlay LISTS and what
44
+ // getSkillPrompt will RUN cannot disagree.
45
+ skillSources: getCliSkillSources(),
42
46
  onOpenDetail: async (filePath, skillName, scope, forkedFrom, boundCommands) => {
43
47
  const content = await fs.readFile(filePath, 'utf-8');
44
48
  const detail = new SkillDetailOverlayV2({
@@ -3,7 +3,25 @@
3
3
  *
4
4
  * Commands for managing multi-agent teams.
5
5
  */
6
- import type { CommandHandlerV2 } from '../types.js';
6
+ import type { CommandHandlerV2, CommandContextV2 } from '../types.js';
7
+ import type { AgentTeam } from '../../multi-agent/index.js';
7
8
  export declare const teamCommand: CommandHandlerV2;
9
+ /**
10
+ * Edit an existing team agent.
11
+ *
12
+ * ⚠️ THE INSTRUCTIONS FIELD IS NOT THE SAME FIELD FOR BOTH AGENT KINDS, and reading the
13
+ * wrong one moves the user's data. A custom agent's live `systemPromptAddition` is the
14
+ * whole GENERATED prompt ("You are a X specialized in Y. …"), not the instructions the
15
+ * user typed — those live on the `CustomAgentDefinition` on disk. So:
16
+ *
17
+ * custom agent → read/write `CustomAgentDefinition.systemPromptAddition`, then
18
+ * regenerate the live prompt around it
19
+ * role agent → read/write the live `TeamAgent.systemPromptAddition`, which for that
20
+ * kind genuinely IS free text
21
+ *
22
+ * Loading one and saving the other is an asymmetric round trip: it does not look like a
23
+ * bug until the data has already moved.
24
+ */
25
+ export declare function handleEditAgent(ctx: CommandContextV2, team: AgentTeam, agentId: string): Promise<void>;
8
26
  export declare const artifactCommand: CommandHandlerV2;
9
27
  export declare const teamCommands: CommandHandlerV2[];