@compilr-dev/cli 0.7.4 → 0.7.5

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 (43) hide show
  1. package/dist/agent.d.ts +7 -2
  2. package/dist/agent.js +55 -39
  3. package/dist/commands-v2/handlers/project.js +65 -2
  4. package/dist/commands-v2/handlers/settings.js +18 -26
  5. package/dist/compilr-diff-companion.vsix +0 -0
  6. package/dist/db/schema.d.ts +1 -1
  7. package/dist/episodes/index.d.ts +13 -13
  8. package/dist/episodes/index.js +13 -14
  9. package/dist/guide/cli-guide-entries.js +54 -2
  10. package/dist/handlers/delegation-handlers.js +228 -50
  11. package/dist/handlers/interactive-flow-handlers.d.ts +26 -0
  12. package/dist/handlers/interactive-flow-handlers.js +61 -0
  13. package/dist/handlers/propose-alternatives-handlers.d.ts +36 -0
  14. package/dist/handlers/propose-alternatives-handlers.js +65 -0
  15. package/dist/index.js +13 -2
  16. package/dist/repl-v2.d.ts +66 -0
  17. package/dist/repl-v2.js +382 -53
  18. package/dist/shared-handlers.d.ts +57 -5
  19. package/dist/shared-handlers.js +50 -0
  20. package/dist/tools/consult.d.ts +14 -0
  21. package/dist/tools/consult.js +73 -0
  22. package/dist/tools/delegate.d.ts +12 -6
  23. package/dist/tools/delegate.js +35 -19
  24. package/dist/tools/interactive-flow.d.ts +13 -0
  25. package/dist/tools/interactive-flow.js +19 -0
  26. package/dist/tools/platform-adapter.d.ts +14 -2
  27. package/dist/tools/platform-adapter.js +16 -4
  28. package/dist/tools/propose-alternatives.d.ts +13 -0
  29. package/dist/tools/propose-alternatives.js +19 -0
  30. package/dist/tools.d.ts +22 -98
  31. package/dist/tools.js +27 -382
  32. package/dist/ui/markdown-renderer.js +26 -7
  33. package/dist/ui/overlay/data/tutorials/projects/new-project.js +56 -20
  34. package/dist/ui/overlay/impl/interactive-flow-overlay-v2.d.ts +79 -0
  35. package/dist/ui/overlay/impl/interactive-flow-overlay-v2.js +580 -0
  36. package/dist/ui/overlay/impl/new-overlay-v2.d.ts +32 -0
  37. package/dist/ui/overlay/impl/new-overlay-v2.js +305 -66
  38. package/dist/ui/overlay/impl/propose-alternatives-overlay-v2.d.ts +53 -0
  39. package/dist/ui/overlay/impl/propose-alternatives-overlay-v2.js +326 -0
  40. package/dist/ui/overlay/index.d.ts +2 -0
  41. package/dist/ui/overlay/index.js +2 -0
  42. package/dist/ui/tool-formatters.js +61 -3
  43. package/package.json +2 -2
package/dist/tools.js CHANGED
@@ -1,387 +1,32 @@
1
1
  /**
2
- * Tool Registry Setup
2
+ * Tool Registry Helpers (slim).
3
3
  *
4
- * Configures all available tools from @compilr-dev/sdk
5
- * (which re-exports from @compilr-dev/agents and @compilr-dev/agents-coding).
4
+ * Pre-SDK migration this file owned the full HOT_TOOLS / WARM_TOOLS /
5
+ * DIRECT_TOOLS / META_REGISTRY_TOOLS arrays and a token-saving registry
6
+ * (~15K → ~2K per turn). That optimisation moved to the SDK as the
7
+ * capability-manager direct/meta tier split (`TOOL_GROUPS.<id>.tier`),
8
+ * and `createCompilrAgent({ capabilities: ... })` now handles tool
9
+ * registration end-to-end. See `src/agent.ts` and
10
+ * `@compilr-dev/sdk/src/capabilities/packs.ts`.
6
11
  *
7
- * ARCHITECTURE (Meta-Tools):
8
- * - DIRECT TOOLS: Always available, called by name (most common operations)
9
- * - META-REGISTRY TOOLS: Available via use_tool() (specialized operations)
12
+ * What remains here is the small surface CLI code outside agent.ts still
13
+ * touches:
14
+ * - `todoStore` alias for the SDK's `getDefaultTodoStore()` singleton,
15
+ * read by the footer renderer (see `repl-v2.ts`).
16
+ * - `TOOL_NAMES` / `ToolName` / `getAllToolNames` — re-exported from
17
+ * `./tool-names.js` for convenience.
10
18
  *
11
- * This reduces token overhead from ~15K to ~2K per request.
19
+ * Audit refs: TODO-4 (HOT/WARM cleanup), TODO-15 (deleted the parallel
20
+ * dead MetaToolsRegistry singleton + its setMetaToolFilter /
21
+ * getRegisteredMetaTools / isMetaToolSilent surface — the SDK's
22
+ * per-agent CapabilityManager already handles tool filtering at agent
23
+ * factory time, so the CLI re-exports here were always no-ops).
12
24
  *
13
- * SINGLE SOURCE OF TRUTH:
14
- * Tool names are defined in tool-names.ts (a dependency-free module).
15
- * This file re-exports them for convenience. Import from here or tool-names.ts.
16
- */
17
- // Re-export tool names from the dependency-free module
18
- // This breaks circular dependencies while maintaining a single source of truth
19
- export { TOOL_NAMES, DIRECT_TOOL_NAMES, HOT_TOOL_NAMES, WARM_TOOL_NAMES, META_TOOL_NAMES, META_REGISTRY_TOOL_NAMES, getAllToolNames, } from './tool-names.js';
20
- // =============================================================================
21
- // TOOL IMPORTS
22
- // =============================================================================
23
- import { readFileTool, writeFileTool, createBashTool, bashOutputTool, killShellTool, grepTool, globTool, editTool, createTodoTools, defineTool, } from '@compilr-dev/sdk';
24
- // Create todo tools with shared store (includes claim/handoff)
25
- const todoToolsResult = createTodoTools();
26
- const originalTodoWriteTool = todoToolsResult.todoWrite;
27
- const todoReadTool = todoToolsResult.todoRead;
28
- const todoClaimTool = todoToolsResult.todoClaim;
29
- const todoHandoffTool = todoToolsResult.todoHandoff;
30
- // Explicit type annotation avoids TS2742 when importing createTodoTools via @compilr-dev/sdk
31
- export const todoStore = todoToolsResult.store;
32
- const todoWriteTool = defineTool({
33
- name: 'todo_write',
34
- description: 'Update the SESSION todo list (shown in footer). These are ephemeral tasks for the current session only. ' +
35
- 'For persistent project backlog items, use workitem_* tools instead. ' +
36
- 'Provide the complete list of todos to replace the current list.',
37
- inputSchema: {
38
- type: 'object',
39
- properties: {
40
- todos: {
41
- type: 'array',
42
- description: 'The complete list of todos',
43
- items: {
44
- type: 'object',
45
- properties: {
46
- content: {
47
- type: 'string',
48
- description: 'Task description (imperative form, e.g., "Fix bug in login")',
49
- },
50
- status: {
51
- type: 'string',
52
- enum: ['pending', 'in_progress', 'completed'],
53
- description: 'Task status',
54
- },
55
- activeForm: {
56
- type: 'string',
57
- description: 'Active form (present continuous, e.g., "Fixing bug in login")',
58
- },
59
- priority: {
60
- type: 'number',
61
- description: 'Priority (higher = more important)',
62
- },
63
- owner: {
64
- type: 'string',
65
- description: 'Owner agent ID (e.g., "dev", "pm", "arch"). Omit for unassigned.',
66
- },
67
- blockedBy: {
68
- type: 'array',
69
- items: { type: 'number' },
70
- description: 'Array of 1-based task numbers this task depends on (e.g., [3, 4] means blocked by task #3 and #4)',
71
- },
72
- },
73
- required: ['content', 'status'],
74
- },
75
- },
76
- },
77
- required: ['todos'],
78
- },
79
- execute: async (input) => {
80
- // Normalize todos - accept alternative property names
81
- const normalizedTodos = input.todos.map((todo) => ({
82
- content: (todo.content || todo.title || todo.description || todo.task || todo.text || '').trim(),
83
- status: todo.status,
84
- activeForm: todo.activeForm,
85
- priority: todo.priority,
86
- owner: todo.owner,
87
- blockedBy: todo.blockedBy,
88
- }));
89
- // Filter out empty todos and provide fallback
90
- const validTodos = normalizedTodos.map((todo) => ({
91
- ...todo,
92
- content: todo.content || 'Untitled task',
93
- }));
94
- // Call the original tool with normalized input
95
- const result = await originalTodoWriteTool.execute({ todos: validTodos });
96
- return result;
97
- },
98
- silent: true,
99
- });
100
- // Create bash tool with longer timeout (2 minutes instead of 30 seconds)
101
- const bashTool = createBashTool({
102
- timeout: 120000, // 2 minutes
103
- });
104
- import {
105
- // Git tools (basic)
106
- gitStatusTool, gitDiffTool, gitLogTool, gitCommitTool, gitBranchTool,
107
- // Git tools (advanced)
108
- gitStashTool, gitBlameTool, gitFileHistoryTool,
109
- // Project detection
110
- detectProjectTool, findProjectRootTool,
111
- // Smart runners
112
- runTestsTool, runLintTool, runBuildTool, runFormatTool,
113
- // Code search
114
- findDefinitionTool, findReferencesTool, findTodosTool,
115
- // Dependency analysis
116
- checkOutdatedTool, findVulnerabilitiesTool,
117
- // Testing analysis
118
- analyzeTestCoverageTool,
119
- // Unified analysis (auto-detect language)
120
- getFileStructureTool, getComplexityTool, } from '@compilr-dev/sdk';
121
- // Local tools
122
- import { askUserTool } from './tools/ask-user.js';
123
- import { askUserSimpleTool } from './tools/ask-user-simple.js';
124
- import { delegateTool } from './tools/delegate.js';
125
- import { delegateBackgroundTool } from './tools/delegate-background.js';
126
- import { delegationStatusTool } from './tools/delegation-status.js';
127
- import { handoffTool } from './tools/handoff.js';
128
- import { createGuideTool } from '@compilr-dev/sdk';
129
- import { CLI_GUIDE_ENTRIES } from './guide/cli-guide-entries.js';
130
- const guideTool = createGuideTool({
131
- environment: 'cli',
132
- additionalEntries: CLI_GUIDE_ENTRIES,
133
- });
134
- // DB tools for project, work item, document, plan, backlog, anchor, artifact, and episode management
135
- import { allDbTools, allFactoryTools } from './tools/db-tools.js';
136
- // Meta-tools for dynamic tool loading
137
- import { initializeMetaToolRegistry, generateToolIndex, generateFilteredToolIndex, getMetaToolCount, META_TOOLS_SYSTEM_PROMPT_PREFIX, setMetaToolFilter, getRegisteredMetaTools, createMetaToolFallback, getToolInfoTool, } from './tools/meta-tools.js';
138
- // Re-export for use in agent.ts
139
- export { setMetaToolFilter, getRegisteredMetaTools };
140
- /**
141
- * Check if a tool in the meta-registry is marked as silent.
142
- * Used by the repl to suppress output for warm tools like todo_write/todo_read.
143
- */
144
- export function isMetaToolSilent(name) {
145
- const tools = getRegisteredMetaTools();
146
- const tool = tools.find((t) => t.definition.name === name);
147
- return tool?.silent === true;
148
- }
149
- // =============================================================================
150
- // DIRECT TOOLS - Always available, called by name
151
- // =============================================================================
152
- /**
153
- * Hot tools — used in >50% of turns. Always declared as direct schemas.
154
- * Estimated: ~2,100 tokens for definitions
155
- */
156
- const HOT_TOOLS = [
157
- // File operations (most common)
158
- readFileTool,
159
- writeFileTool,
160
- editTool,
161
- // Shell (very common)
162
- bashTool,
163
- // Search (very common)
164
- globTool,
165
- grepTool,
166
- // User interaction (always needed)
167
- askUserTool,
168
- ];
169
- /**
170
- * Warm tools — used occasionally. In hot-tools mode these move to meta-registry.
171
- * Estimated: ~3,300 tokens for definitions
172
- */
173
- const WARM_TOOLS = [
174
- // Shell management
175
- bashOutputTool,
176
- killShellTool,
177
- // Task tracking
178
- todoWriteTool,
179
- todoReadTool,
180
- todoClaimTool,
181
- todoHandoffTool,
182
- // User interaction (simple variant)
183
- askUserSimpleTool,
184
- // Delegation (coordinator only)
185
- delegateTool,
186
- // Background delegation (coordinator mode)
187
- delegateBackgroundTool,
188
- // Handoff (specialist-to-specialist)
189
- handoffTool,
190
- // CLI documentation
191
- guideTool,
192
- ];
193
- /**
194
- * All direct tools combined (hot + warm).
195
- * Used in legacy mode (no meta-tools) and for backwards compatibility.
196
- */
197
- const DIRECT_TOOLS = [...HOT_TOOLS, ...WARM_TOOLS];
198
- // =============================================================================
199
- // META-REGISTRY TOOLS - Available via use_tool()
200
- // =============================================================================
201
- /**
202
- * Meta-registry tools are specialized tools available via use_tool().
203
- * Instead of declaring their full schemas (~12K tokens), we:
204
- * 1. Add them to a registry
205
- * 2. Generate a tool index for the system prompt (~800 tokens)
206
- * 3. Let the agent call them via use_tool("tool_name", {args})
207
- */
208
- const META_REGISTRY_TOOLS = [
209
- // Git operations (basic)
210
- gitStatusTool,
211
- gitDiffTool,
212
- gitLogTool,
213
- gitCommitTool,
214
- gitBranchTool,
215
- // Git operations (advanced)
216
- gitStashTool,
217
- gitBlameTool,
218
- gitFileHistoryTool,
219
- // Project detection
220
- detectProjectTool,
221
- findProjectRootTool,
222
- // Smart runners
223
- runTestsTool,
224
- runLintTool,
225
- runBuildTool,
226
- runFormatTool,
227
- // Code search (language-agnostic)
228
- findDefinitionTool,
229
- findReferencesTool,
230
- findTodosTool,
231
- // Dependency analysis
232
- checkOutdatedTool,
233
- findVulnerabilitiesTool,
234
- // Testing analysis
235
- analyzeTestCoverageTool,
236
- // Unified analysis (auto-detect language: TS/JS/Python/Go)
237
- getFileStructureTool,
238
- getComplexityTool,
239
- // DB tools (project, workitem, document, plan, backlog, anchor, artifact, episode)
240
- ...allDbTools,
241
- // Factory tools (app_model_get, app_model_update, app_model_validate, factory_scaffold, factory_list_toolkits)
242
- ...allFactoryTools,
243
- // Delegation status (coordinator query)
244
- delegationStatusTool,
245
- ];
246
- // =============================================================================
247
- // LEGACY API (for backwards compatibility)
248
- // =============================================================================
249
- /**
250
- * Creates the tool registry with all available tools.
251
- * Returns tools as-is - the Agent.registerTools() method handles typing.
252
- *
253
- * @deprecated Use createDirectToolRegistry() + initializeMetaTools() instead
254
- */
255
- export function createToolRegistry() {
256
- return [
257
- ...DIRECT_TOOLS,
258
- ...META_REGISTRY_TOOLS,
259
- ];
260
- }
261
- /**
262
- * Returns a minimal set of tools for basic testing.
263
- */
264
- export function createMinimalToolRegistry() {
265
- return [
266
- readFileTool,
267
- writeFileTool,
268
- bashTool,
269
- globTool,
270
- ];
271
- }
272
- // =============================================================================
273
- // META-TOOLS API (new architecture)
274
- // =============================================================================
275
- /**
276
- * Get direct tools that are always available.
277
- * When hotOnly is true, returns only hot tools (7 tools, ~2.1K tokens).
278
- * When false/undefined, returns all direct tools (18 tools, ~5.4K tokens).
279
- */
280
- export function getDirectTools(hotOnly) {
281
- if (hotOnly)
282
- return HOT_TOOLS;
283
- return DIRECT_TOOLS;
284
- }
285
- /**
286
- * Get meta-tools for agent registration.
287
- * Only get_tool_info is kept as a direct tool — use_tool and list_tools
288
- * are no longer needed since the fallback handler routes calls transparently.
289
- */
290
- export function getMetaTools() {
291
- return [getToolInfoTool];
292
- }
293
- /**
294
- * Create a fallback handler for the tool registry.
295
- * When the agent calls a tool not in the direct registry, this handler
296
- * checks the meta-registry and executes it transparently.
297
- *
298
- * Auto-loading of capability packs for filtered tools is handled by the
299
- * shared onFilteredTool callback in meta-tools.ts (covers both use_tool
300
- * and direct fallback paths).
301
- */
302
- export function createToolFallback() {
303
- return createMetaToolFallback();
304
- }
305
- /** Whether hot-tools mode is active (warm tools in meta-registry) */
306
- let hotToolsModeActive = false;
307
- /**
308
- * Check if hot-tools mode is active.
309
- * When true, only hot tools are declared as direct schemas; warm tools are in meta-registry.
310
- */
311
- export function isHotToolsMode() {
312
- return hotToolsModeActive;
313
- }
314
- /**
315
- * Initialize the meta-tool registry with specialized tools.
316
- * When includeWarmTools is true, warm tools are also added to the meta-registry
317
- * (enabling hot-tools mode where only 7 core tools are declared directly).
318
- * Call this once at startup.
319
- */
320
- export function initializeMetaTools(includeWarmTools) {
321
- const tools = includeWarmTools
322
- ? [...WARM_TOOLS, ...META_REGISTRY_TOOLS]
323
- : META_REGISTRY_TOOLS;
324
- initializeMetaToolRegistry(tools);
325
- if (includeWarmTools) {
326
- hotToolsModeActive = true;
327
- }
328
- }
329
- /**
330
- * Get the tool index for the system prompt.
331
- * This lists all meta-registry tools with their signatures.
332
- */
333
- export function getToolIndexForSystemPrompt() {
334
- return META_TOOLS_SYSTEM_PROMPT_PREFIX + generateToolIndex();
335
- }
336
- /**
337
- * Get a filtered tool index for the system prompt.
338
- * Only includes tools whose names are in the given set.
339
- * Used by the capability-aware BeforeLLM hook.
340
- */
341
- export function getFilteredToolIndexForSystemPrompt(activeToolNames) {
342
- return META_TOOLS_SYSTEM_PROMPT_PREFIX + generateFilteredToolIndex(activeToolNames);
343
- }
344
- /**
345
- * Get count of meta-registry tools.
346
- */
347
- export function getMetaToolsCount() {
348
- return getMetaToolCount();
349
- }
350
- /**
351
- * Check if meta-tools mode is enabled.
352
- * Returns true if the meta-tool registry has been initialized.
353
- */
354
- export function isMetaToolsEnabled() {
355
- return getMetaToolCount() > 0;
356
- }
357
- // =============================================================================
358
- // STATISTICS
359
- // =============================================================================
360
- /**
361
- * Get tool statistics for debugging/display.
362
- */
363
- export function getToolStats() {
364
- const hotCount = HOT_TOOLS.length;
365
- const warmCount = WARM_TOOLS.length;
366
- const directCount = hotToolsModeActive ? hotCount : hotCount + warmCount;
367
- const metaCount = hotToolsModeActive
368
- ? META_REGISTRY_TOOLS.length + warmCount
369
- : META_REGISTRY_TOOLS.length;
370
- const totalCount = hotCount + warmCount + META_REGISTRY_TOOLS.length;
371
- // Rough estimates: ~300 tokens per tool definition
372
- const tokensPerTool = 300;
373
- const estimatedDirectTokens = directCount * tokensPerTool;
374
- const estimatedMetaTokens = 1000; // Tool index + meta-tool definitions
375
- const estimatedLegacyTokens = totalCount * tokensPerTool;
376
- return {
377
- directTools: directCount,
378
- hotTools: hotCount,
379
- warmTools: warmCount,
380
- metaRegistryTools: metaCount,
381
- totalTools: totalCount,
382
- estimatedDirectTokens,
383
- estimatedMetaTokens,
384
- estimatedLegacyTokens,
385
- tokenSavings: estimatedLegacyTokens - estimatedDirectTokens - estimatedMetaTokens,
386
- };
387
- }
25
+ * See `project-docs/00-requirements/compilr-dev-sdk/architecture-audit-cli-vs-desktop.md`.
26
+ */
27
+ import { getDefaultTodoStore } from '@compilr-dev/sdk';
28
+ // Tool-name constants — re-exported from the dependency-free module.
29
+ export { TOOL_NAMES, getAllToolNames } from './tool-names.js';
30
+ // Footer + UI reads this; the SDK preset's todo tools write through the
31
+ // same singleton (audit TODO-9).
32
+ export const todoStore = getDefaultTodoStore();
@@ -112,22 +112,40 @@ function reflowText(text, width, gfm) {
112
112
  const fragments = sec.split(/(\u001b\[(?:\d{1,3})(?:;\d{1,3})*m)/g);
113
113
  let column = 0;
114
114
  let currentLine = '';
115
- let lastWasEscape = false;
115
+ // Carries through ANSI fragments so the space-before-word decision for
116
+ // the next text fragment knows whether boundary whitespace existed in
117
+ // the source. Fixes the bug where "the `consult` tool" rendered as
118
+ // "theconsulttool" — the trailing space of "the " and leading space of
119
+ // " tool" were both discarded by the split-on-whitespace, and the old
120
+ // `lastWasEscape` flag suppressed re-inserting them.
121
+ let prevTextEndedWithWs = false;
116
122
  for (const fragment of fragments) {
117
- if (fragment === '') {
118
- lastWasEscape = false;
123
+ if (fragment === '')
119
124
  continue;
120
- }
121
125
  if (!textLength(fragment)) {
126
+ // ANSI escape sequence — append untouched. We deliberately do NOT
127
+ // reset prevTextEndedWithWs here, so the next text fragment can
128
+ // still re-introduce a space across the ANSI boundary if needed.
122
129
  currentLine += fragment;
123
- lastWasEscape = true;
124
130
  continue;
125
131
  }
132
+ // Plain text fragment.
133
+ const startsWithWs = /^[ \t\n]/.test(fragment);
134
+ const endsWithWs = /[ \t\n]$/.test(fragment);
126
135
  const words = fragment.split(/[ \t\n]+/);
136
+ let isFirstWordInFragment = true;
127
137
  for (const word of words) {
128
138
  if (!word)
129
139
  continue;
130
- const addSpace = column !== 0 && !lastWasEscape;
140
+ // Insert a space before this word when column > 0 AND one of:
141
+ // - it's NOT the first word in this fragment (intra-fragment
142
+ // whitespace existed), OR
143
+ // - this fragment had leading whitespace (e.g. " tool" after a
144
+ // closing ANSI), OR
145
+ // - the previous text fragment ended with whitespace (e.g.
146
+ // "the " before an opening ANSI).
147
+ const addSpace = column !== 0 &&
148
+ (!isFirstWordInFragment || startsWithWs || prevTextEndedWithWs);
131
149
  const neededWidth = word.length + (addSpace ? 1 : 0);
132
150
  if (column + neededWidth > width && word.length <= width) {
133
151
  reflowed.push(currentLine);
@@ -160,8 +178,9 @@ function reflowText(text, width, gfm) {
160
178
  currentLine += word;
161
179
  column += word.length;
162
180
  }
163
- lastWasEscape = false;
181
+ isFirstWordInFragment = false;
164
182
  }
183
+ prevTextEndedWithWs = endsWithWs;
165
184
  }
166
185
  if (textLength(currentLine))
167
186
  reflowed.push(currentLine);
@@ -88,24 +88,30 @@ export const newProjectTutorial = (s) => ({
88
88
  '',
89
89
  ],
90
90
  },
91
- // Page 5: Documentation Structure [3/8]
91
+ // Page 5: Project Type [3/8]
92
92
  {
93
- title: 'Documentation Structure',
93
+ title: 'Project Type',
94
94
  lines: [
95
95
  '',
96
96
  ` ${s.primaryBold('Initialize New Project')} ${s.muted('[3/8]')}`,
97
97
  '',
98
- ` ${s.primary('Documentation structure')}`,
98
+ ` ${s.primary('What kind of project are you starting?')}`,
99
99
  '',
100
- ` ${s.primary('>')} 1. Single repo (.compilr/ folder + COMPILR.md in project root)`,
101
- ` 2. Two repos (project/ + project-docs/ separate repositories)`,
102
- '',
103
- ` ${s.muted('Single repo: All files in one repository')}`,
104
- ` ${s.muted('Two repos: Code and docs in separate repositories')}`,
100
+ ` ${s.primary('>')} Software Development ${s.muted('Web apps, APIs, CLIs, libraries')}`,
101
+ ` General Purpose ${s.muted('Blank workspace define your own')}`,
102
+ ` Research Paper ${s.muted('Academic / analytical document')}`,
103
+ ` Content & Marketing ${s.muted('Blog posts, social copy, content')}`,
104
+ ` Technical Documentation ${s.muted('API docs, user guides, tutorials')}`,
105
+ ` Book ${s.muted('Long-form writing, fiction / nonfic')}`,
106
+ ` Business Plan ${s.muted('Vision, market, financials, pitch')}`,
107
+ ` Course ${s.muted('Curriculum, modules, lessons')}`,
105
108
  '',
106
109
  ` ${s.muted('Up/Down Navigate | Enter Select | Esc Back')}`,
107
110
  '',
108
- ` ${s.warning('TIP:')} Single repo is simpler for most projects.`,
111
+ ` ${s.warning('TIP:')} Picking a type tailors the wizard. Software types ask about`,
112
+ ` tech stack + coding standards; non-software types skip those`,
113
+ ` steps. The type also drives the team-roster suggestion two`,
114
+ ` steps from now.`,
109
115
  '',
110
116
  ],
111
117
  },
@@ -178,24 +184,50 @@ export const newProjectTutorial = (s) => ({
178
184
  '',
179
185
  ],
180
186
  },
181
- // Page 9: Workflow Mode [7/8]
187
+ // Page 9: Team Roster [7/8]
182
188
  {
183
- title: 'Workflow Mode',
189
+ title: 'Team Roster',
184
190
  lines: [
185
191
  '',
186
192
  ` ${s.primaryBold('Initialize New Project')} ${s.muted('[7/8]')}`,
187
193
  '',
188
- ` ${s.primary('Workflow mode')}`,
194
+ ` ${s.primary('Team roster')}`,
189
195
  '',
190
- ` ${s.primary('>')} 1. Flexible (user-driven, exploratory) ${s.muted('(recommended)')}`,
191
- ` 2. Guided (structured step-by-step workflow)`,
196
+ ` ${s.muted('Software Development suggests these specialists:')}`,
192
197
  '',
193
- ` ${s.muted('Flexible: Work at your own pace, agent responds to requests')}`,
194
- ` ${s.muted('Guided: Agent suggests next steps, tracks work item progress')}`,
198
+ ` ${s.muted('[▲_▲] Developer Writes and debugs code')}`,
199
+ ` ${s.muted('[◈_◈] Architect System design')}`,
200
+ ` ${s.muted('[◉_◉] QA Testing and quality')}`,
201
+ ` ${s.muted('[▣_▣] PM Project planning')}`,
195
202
  '',
196
- ` ${s.muted('Up/Down Navigate | Enter Select | Esc Back')}`,
203
+ ` ${s.primary('How should we set up the team?')}`,
204
+ '',
205
+ ` ${s.primary('>')} Add all suggested (4) ${s.muted('← recommended')}`,
206
+ ` Customize selection`,
207
+ ` Skip — start with just $default`,
208
+ '',
209
+ ` ${s.muted('Up/Down Navigate | Enter Confirm | Esc Back')}`,
210
+ '',
211
+ ` ${s.secondary('Three options:')}`,
197
212
  '',
198
- ` ${s.warning('TIP:')} Start with Flexible. Switch to Guided anytime via ${s.primary('/workflow')}.`,
213
+ ` ${s.primary('1.')} ${s.primaryBold('Add all suggested')} (default)`,
214
+ ` Specialists are spawned automatically when the project is created.`,
215
+ ` A chat with each agent is ready as soon as you finish.`,
216
+ '',
217
+ ` ${s.primary('2.')} ${s.primaryBold('Customize selection')}`,
218
+ ` Opens a checklist of the suggested agents. Use ${s.primary('Space')} to`,
219
+ ` toggle each one on/off. ${s.primary('Enter')} when done. You can still`,
220
+ ` run ${s.primary('/team add <role>')} later for roles outside the suggestion.`,
221
+ '',
222
+ ` ${s.primary('3.')} ${s.primaryBold('Skip')}`,
223
+ ` The project starts with only ${s.primary('$default')}. Useful for very`,
224
+ ` small projects or when you prefer to add agents one at a time.`,
225
+ '',
226
+ ` For project types with no default team (like General Purpose), this`,
227
+ ` step is skipped automatically.`,
228
+ '',
229
+ ` ${s.warning('TIP:')} If you accidentally skip and want the team back, run`,
230
+ ` ${s.primary('/team add')} for each role you want.`,
199
231
  '',
200
232
  ],
201
233
  },
@@ -209,13 +241,13 @@ export const newProjectTutorial = (s) => ({
209
241
  ` ${s.primary('Ready to create project?')}`,
210
242
  '',
211
243
  ` Project: ${s.primary('my-first-project')}`,
244
+ ` Type: ${s.primary('Software Development')}`,
212
245
  ` Location: ${s.primary('./my-first-project/')}`,
213
- ` Structure: ${s.primary('Single repo')}`,
214
246
  ` Tech: ${s.primary('React + Node.js + PostgreSQL')}`,
215
247
  ` Standards: ${s.primary('TypeScript Strict (recommended)')}`,
216
248
  ` Git: ${s.primary('Yes')}`,
217
249
  ` Remote: ${s.primary('https://github.com/user/my-first-project')}`,
218
- ` Workflow: ${s.primary('Flexible (user-driven, exploratory)')}`,
250
+ ` Team: ${s.primary('4 specialists')} ${s.muted('($dev, $arch, $qa, $pm)')}`,
219
251
  '',
220
252
  ` ${s.primary('>')} Create`,
221
253
  ` Cancel`,
@@ -243,6 +275,10 @@ export const newProjectTutorial = (s) => ({
243
275
  ` ${s.success('✓')} ${s.primary('Git repository')} with initial commit`,
244
276
  ` ${s.muted('Remote configured if you provided a URL')}`,
245
277
  '',
278
+ ` ${s.success('✓')} ${s.primary('Team specialists')} added to the project's team`,
279
+ ` ${s.muted('Based on the type you picked + roster option chosen')}`,
280
+ ` ${s.muted('Run /team to see them')}`,
281
+ '',
246
282
  ` You'll return to the Dashboard with your new project selected.`,
247
283
  '',
248
284
  ],