@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/agent.d.ts CHANGED
@@ -100,9 +100,14 @@ export interface AgentOptions {
100
100
  episodeRecorder?: EpisodeRecorder;
101
101
  }
102
102
  /**
103
- * Get permission info for a tool by name.
103
+ * Get permission info for a tool by name from the live agent's effective
104
+ * rules. Returns undefined if the tool has no rule (i.e., implicit allow).
105
+ *
106
+ * Reads from `agent.getPermission()` instead of a static constant so
107
+ * runtime additions (user-configured rules in settings, session-time
108
+ * `setPermissionLevel()` calls) are reflected in the UI.
104
109
  */
105
- export declare function getToolPermissionInfo(toolName: string): {
110
+ export declare function getToolPermissionInfo(agent: Agent, toolName: string): {
106
111
  level: 'once' | 'always' | 'session';
107
112
  description: string;
108
113
  } | undefined;
package/dist/agent.js CHANGED
@@ -6,7 +6,7 @@
6
6
  * assembly, subagent callbacks, and token estimates.
7
7
  */
8
8
  import { log } from './foundation/logger.js';
9
- import { createCompilrAgent, createTaskTool, defaultAgentTypes, TOOL_SETS, BUILTIN_GUARDRAILS, } from '@compilr-dev/sdk';
9
+ import { createCompilrAgent, createTaskTool, defaultAgentTypes, TOOL_SETS, BUILTIN_GUARDRAILS, DEFAULT_DELEGATION_CONFIG, } from '@compilr-dev/sdk';
10
10
  import { isAutoCompactEnabled, isDelegationEnabled, getSetting } from './settings/index.js';
11
11
  import { getApiKey } from './utils/credentials.js';
12
12
  import { getAgentRegistry } from './agents/registry.js';
@@ -17,6 +17,10 @@ import { setStaticEstimates, estimateTokens, estimateJsonTokens, } from './utils
17
17
  import { createFileLockCheckHook, createFileLockAcquireHook } from './multi-agent/file-lock-hook.js';
18
18
  import { getActiveProject } from './tools/project-db.js';
19
19
  import { allDbTools, allFactoryTools } from './tools/db-tools.js';
20
+ import { askUserTool } from './tools/ask-user.js';
21
+ import { askUserSimpleTool } from './tools/ask-user-simple.js';
22
+ import { proposeAlternativesTool } from './tools/propose-alternatives.js';
23
+ import { interactiveFlowTool } from './tools/interactive-flow.js';
20
24
  import { createGuideTool } from '@compilr-dev/sdk';
21
25
  import { CLI_GUIDE_ENTRIES } from './guide/cli-guide-entries.js';
22
26
  const cliGuideTool = createGuideTool({
@@ -71,48 +75,46 @@ function buildPlanModeTools(callbacks) {
71
75
  return [planSubmitTool, planModeExitTool];
72
76
  }
73
77
  /**
74
- * Default permission rules for potentially dangerous operations
78
+ * Permission rules used to live in a local constant here that was a
79
+ * strict subset of `@compilr-dev/sdk`'s `DEFAULT_PERMISSION_RULES`
80
+ * (missing the three read-only `always` rules: read_file, glob, grep).
81
+ * The local copy is gone — CLI now relies on `includeDefaultRules: true`
82
+ * to pick up the SDK's defaults verbatim, so SDK additions automatically
83
+ * apply to CLI without needing a manual sync. Audit TODO-12.
84
+ */
85
+ /**
86
+ * Delegation config for tool result auto-summarization. Spreads the
87
+ * SDK baseline (`DEFAULT_DELEGATION_CONFIG`) and bumps `git_diff` back
88
+ * up to 6000 — CLI prefers keeping larger diffs inline because the
89
+ * terminal UI doesn't have a richer summary affordance. Audit TODO-13.
75
90
  */
76
- const DEFAULT_PERMISSION_RULES = [
77
- { toolName: 'write_file', level: 'once', description: 'Write/create files' },
78
- { toolName: 'edit', level: 'once', description: 'Edit file contents' },
79
- { toolName: 'git_commit', level: 'once', description: 'Create git commit' },
80
- { toolName: 'git_branch', level: 'once', description: 'Create/delete git branches' },
81
- { toolName: 'bash', level: 'once', description: 'Execute shell command' },
82
- { toolName: 'run_tests', level: 'once', description: 'Run test suite' },
83
- { toolName: 'run_lint', level: 'once', description: 'Run linter (may auto-fix)' },
84
- ];
85
- /** Delegation config for tool result auto-summarization */
86
91
  const CLI_DELEGATION_CONFIG = {
87
- enabled: true,
88
- delegationThreshold: 8000,
89
- summaryMaxTokens: 800,
90
- resultTTL: 600_000,
91
- maxStoredResults: 50,
92
- strategy: 'auto',
92
+ ...DEFAULT_DELEGATION_CONFIG,
93
93
  toolOverrides: {
94
- bash: { threshold: 12000 },
95
- grep: { threshold: 4000 },
94
+ ...DEFAULT_DELEGATION_CONFIG.toolOverrides,
96
95
  git_diff: { threshold: 6000 },
97
- get_tool_info: { enabled: false },
98
- list_tools: { enabled: false },
99
- ask_user: { enabled: false },
100
- ask_user_simple: { enabled: false },
101
- todo_read: { enabled: false },
102
96
  },
103
97
  };
104
98
  /**
105
- * Get permission info for a tool by name.
99
+ * Get permission info for a tool by name from the live agent's effective
100
+ * rules. Returns undefined if the tool has no rule (i.e., implicit allow).
101
+ *
102
+ * Reads from `agent.getPermission()` instead of a static constant so
103
+ * runtime additions (user-configured rules in settings, session-time
104
+ * `setPermissionLevel()` calls) are reflected in the UI.
106
105
  */
107
- export function getToolPermissionInfo(toolName) {
108
- const rule = DEFAULT_PERMISSION_RULES.find(r => r.toolName === toolName);
109
- if (rule) {
110
- return {
111
- level: rule.level,
112
- description: rule.description ?? 'Requires approval',
113
- };
114
- }
115
- return undefined;
106
+ export function getToolPermissionInfo(agent, toolName) {
107
+ const rule = agent.getPermission(toolName);
108
+ if (!rule)
109
+ return undefined;
110
+ // PermissionLevel includes 'deny' which the overlay's UI doesn't render;
111
+ // surface only the three actionable levels and drop deny silently.
112
+ if (rule.level === 'deny')
113
+ return undefined;
114
+ return {
115
+ level: rule.level,
116
+ description: rule.description ?? 'Requires approval',
117
+ };
116
118
  }
117
119
  /**
118
120
  * Get information about built-in guardrails.
@@ -261,11 +263,12 @@ export function createAgent(options = {}) {
261
263
  toolTimeoutMs: 120000,
262
264
  enableFileTracking: true,
263
265
  logger: log,
264
- // Permissions
266
+ // Permissions — rules come entirely from the SDK's
267
+ // DEFAULT_PERMISSION_RULES via includeDefaultRules. The CLI used to
268
+ // pass a local subset here; that's gone (audit TODO-12).
265
269
  permissions: options.onPermissionRequest
266
270
  ? options.onPermissionRequest
267
271
  : 'auto',
268
- permissionRules: DEFAULT_PERMISSION_RULES,
269
272
  includeDefaultRules: true,
270
273
  // Iteration limits
271
274
  onIterationLimitReached: options.onIterationLimitReached,
@@ -296,8 +299,13 @@ export function createAgent(options = {}) {
296
299
  }
297
300
  }
298
301
  : undefined,
299
- // Capability loading (replaces CLI's manual meta-tools wiring)
300
- // Platform tools (DB, factory) + MCP + guide + plan mode tools
302
+ // Capability loading (replaces CLI's manual meta-tools wiring).
303
+ // Platform tools (DB, factory) + MCP + guide + plan mode tools, plus
304
+ // the two `interaction` pack tools (audit TODO-7 fix). The handler
305
+ // registry is wired in `index.ts:583` via `registerAskUserHandlers`,
306
+ // so the agent calls into the CLI's existing terminal overlays
307
+ // (showAskUserOverlayV2 / showAskUserSimpleOverlayV2) plus the
308
+ // background-agent question-routing path.
301
309
  capabilities: (options.enableMetaTools && !options.minimal && !options.noTools)
302
310
  ? {
303
311
  enabled: true,
@@ -307,6 +315,10 @@ export function createAgent(options = {}) {
307
315
  ...allFactoryTools,
308
316
  ...(options.mcpTools ?? []),
309
317
  cliGuideTool,
318
+ askUserTool,
319
+ askUserSimpleTool,
320
+ proposeAlternativesTool,
321
+ interactiveFlowTool,
310
322
  ...buildPlanModeTools(options.planModeCallbacks),
311
323
  ],
312
324
  }
@@ -317,6 +329,10 @@ export function createAgent(options = {}) {
317
329
  ...allFactoryTools,
318
330
  ...(options.mcpTools ?? []),
319
331
  cliGuideTool,
332
+ askUserTool,
333
+ askUserSimpleTool,
334
+ proposeAlternativesTool,
335
+ interactiveFlowTool,
320
336
  ...buildPlanModeTools(options.planModeCallbacks),
321
337
  ],
322
338
  },
@@ -9,8 +9,9 @@ import { projectRepository, workItemRepository, documentRepository } from '../..
9
9
  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
- import { getCurrentProjectIdForTracking, handleProjectSwitch } from './session.js';
12
+ import { getCurrentProjectIdForTracking, handleProjectSwitch, saveCurrentTeam } from './session.js';
13
13
  import { loadCapabilitiesForSkill } from '../../multi-agent/capability-loader.js';
14
+ import { normalizeRoleName } from '@compilr-dev/sdk';
14
15
  /**
15
16
  * Load capabilities for a skill and warn about forbidden packs.
16
17
  * Called before queuing a skill-driven agent message.
@@ -85,7 +86,11 @@ export const newCommand = {
85
86
  display_name: displayName,
86
87
  description: result.description,
87
88
  path: result.projectPath,
88
- type: 'general', // TODO: wizard should let user pick project type (web/cli/library/api/research/etc.)
89
+ // For new projects, use the type picked in the /new overlay (Session
90
+ // 219 follow-up — was hardcoded 'general' which broke project-type-
91
+ // aware features like suggestedAgents, project-specific skills, etc.)
92
+ // For imports, fallback to 'general'.
93
+ type: (result.projectTypeId ?? 'general'),
89
94
  workflow_mode: result.workflowMode ?? 'flexible',
90
95
  git_remote: result.gitRemote,
91
96
  // For imports, include detected language and framework
@@ -130,6 +135,64 @@ export const newCommand = {
130
135
  });
131
136
  }
132
137
  ctx.ui.print({ type: 'info', message: 'Fresh team and session started for project.' });
138
+ // Batch-add suggested specialists into the fresh team. This is the
139
+ // CLI counterpart to the Desktop wizard's auto-roster (Session 219).
140
+ // rosterRolesToAdd is resolved by the overlay based on the user's
141
+ // choice at step 7 (auto = all suggestedAgents, custom = toggled
142
+ // subset, skip = empty array). For imports it's undefined.
143
+ const rolesToAdd = result.rosterRolesToAdd ?? [];
144
+ const teamForRoster = switchResult.newTeam ?? ctx.team;
145
+ if (!isImport && rolesToAdd.length > 0 && teamForRoster) {
146
+ const succeeded = [];
147
+ const failed = [];
148
+ // Project-type configs use a mix of longform names ('developer',
149
+ // 'architect', 'technical-writer') and short keys ('qa', 'pm').
150
+ // The SDK's `normalizeRoleName` does the translation in one place
151
+ // — same helper Desktop now uses, so the mapping can't drift.
152
+ for (const original of rolesToAdd) {
153
+ const { role: sdkRole, unknown } = normalizeRoleName(original);
154
+ if (unknown) {
155
+ failed.push({ role: original, reason: 'role not in TeamAgent registry' });
156
+ continue;
157
+ }
158
+ try {
159
+ await teamForRoster.addAgentFromRole(sdkRole);
160
+ succeeded.push(sdkRole);
161
+ }
162
+ catch (agentErr) {
163
+ const msg = agentErr instanceof Error ? agentErr.message : String(agentErr);
164
+ // Suppress "already exists" — fires when the same canonical
165
+ // role appears twice under two names in one suggestedAgents
166
+ // list. The second add is a deliberate no-op, not a failure
167
+ // to report to the user.
168
+ if (!msg.includes('already exists')) {
169
+ failed.push({ role: original, reason: msg });
170
+ }
171
+ }
172
+ }
173
+ if (succeeded.length > 0) {
174
+ ctx.ui.print({
175
+ type: 'success',
176
+ message: `Added ${String(succeeded.length)} specialist${succeeded.length === 1 ? '' : 's'}: ${succeeded.map((r) => '$' + r).join(', ')}`,
177
+ });
178
+ // Persist the freshly populated team so it survives a restart.
179
+ // Without this, the team checkpoint for the new project is
180
+ // empty on disk and the next session opens with $default only.
181
+ // (`/team add` calls saveTeamAndSession after every change; the
182
+ // new-project flow has to do the same here.)
183
+ saveCurrentTeam(teamForRoster);
184
+ }
185
+ if (failed.length > 0) {
186
+ const failedSummary = failed.map((f) => `$${f.role} (${f.reason})`).join(', ');
187
+ ctx.ui.print({ type: 'warning', message: `Skipped ${String(failed.length)} agent(s): ${failedSummary}` });
188
+ }
189
+ }
190
+ else if (!isImport && rolesToAdd.length === 0) {
191
+ ctx.ui.print({
192
+ type: 'info',
193
+ message: 'Skipped team roster setup — only $default in team. Use /team add to add specialists later.',
194
+ });
195
+ }
133
196
  }
134
197
  }
135
198
  catch (dbError) {
@@ -7,7 +7,7 @@ import { ThemeOverlayV2, ModelOverlayV2, ToolsOverlayV2, KeysOverlayV2, MascotOv
7
7
  import { getSetting, getSettings, setSetting, recordUpdateCheck, permissionModeToAgentMode, getVerbosity } from '../../settings/index.js';
8
8
  import { getToolPermissionInfo } from '../../agent.js';
9
9
  import { checkForUpdates, performUpdate } from '../../utils/update-checker.js';
10
- import { getRegisteredMetaTools, TOOL_NAMES, getToolStats } from '../../tools.js';
10
+ import { TOOL_NAMES } from '../../tools.js';
11
11
  // =============================================================================
12
12
  // Theme Command
13
13
  // =============================================================================
@@ -47,16 +47,13 @@ export const configCommand = {
47
47
  // Gather current session info
48
48
  const currentModel = getSetting('defaultModel') || 'unknown';
49
49
  const currentProvider = getSetting('defaultProvider');
50
- // Calculate tool counts from actual tool registry
51
- const toolStats = getToolStats();
52
- const metaTools = getRegisteredMetaTools();
53
- // Agent gets: direct tools + 5 additional tools:
54
- // - list_tools, get_tool_info, use_tool (meta-tool access)
55
- // - task (subagent spawning)
56
- // - suggest (next action suggestions)
57
- const directToolCount = toolStats.directTools + 5;
58
- // metaTools.length is the actual count from the registry
59
- const totalToolCount = directToolCount + metaTools.length;
50
+ // Tool count comes live from the active agent. Post-TODO-15 the
51
+ // CLI no longer carries a parallel meta-registry — tools available
52
+ // via `use_tool()` are owned by the SDK's internal registry and
53
+ // routed transparently. `get_tool_info` is in the direct list so
54
+ // it's already counted here.
55
+ const directTools = ctx.agent?.getToolDefinitions() ?? [];
56
+ const totalToolCount = directTools.length;
60
57
  // Calculate total message count across all team agents if team exists
61
58
  let messageCount = ctx.getHistory?.().length ?? 0;
62
59
  if (ctx.team) {
@@ -71,8 +68,6 @@ export const configCommand = {
71
68
  provider: currentProvider === 'auto' ? 'claude' : currentProvider,
72
69
  cwd: process.cwd(),
73
70
  toolCount: totalToolCount,
74
- directToolCount,
75
- metaToolCount: metaTools.length,
76
71
  hasTeam: ctx.team !== undefined && ctx.team.size > 1,
77
72
  startTime: ctx.startTime ?? new Date(),
78
73
  inputTokens: ctx.sessionInputTokens ?? 0,
@@ -181,19 +176,17 @@ export const toolsCommand = {
181
176
  },
182
177
  };
183
178
  /**
184
- * Get tool definitions from the agent with full parameter and permission info.
185
- * Includes both direct tools and meta-registry tools.
179
+ * Get tool definitions from the live agent with full parameter +
180
+ * permission info. Post-TODO-15 only the agent's direct tools are
181
+ * listed here — tools accessible via `use_tool()` live in the SDK's
182
+ * internal meta-registry which isn't exposed publicly. `get_tool_info`
183
+ * (in the direct list) is the in-agent way to discover them.
186
184
  */
187
185
  function getAgentTools(ctx) {
188
186
  if (!ctx.agent)
189
187
  return getDefaultTools();
190
- // Get direct tools from agent
191
188
  const directTools = ctx.agent.getToolDefinitions();
192
- // Get meta-registry tools
193
- const metaTools = getRegisteredMetaTools();
194
- // Combine and map to ToolInfo format
195
- const allTools = [...directTools, ...metaTools.map(t => t.definition)];
196
- return allTools.map((t) => {
189
+ return directTools.map((t) => {
197
190
  // Extract parameters from inputSchema
198
191
  const parameters = [];
199
192
  const props = t.inputSchema.properties;
@@ -206,8 +199,9 @@ function getAgentTools(ctx) {
206
199
  required: required.includes(name),
207
200
  });
208
201
  }
209
- // Look up permission info
210
- const permissionInfo = getToolPermissionInfo(t.name);
202
+ // Look up permission info from the live agent's effective rules
203
+ // (post-TODO-12 was a static constant before).
204
+ const permissionInfo = ctx.agent ? getToolPermissionInfo(ctx.agent, t.name) : undefined;
211
205
  const permission = permissionInfo
212
206
  ? { level: permissionInfo.level, description: permissionInfo.description }
213
207
  : undefined;
@@ -216,11 +210,9 @@ function getAgentTools(ctx) {
216
210
  if (t.name === 'task' && description.includes('Available agent types:')) {
217
211
  description = description.split('Available agent types:')[0].trim();
218
212
  }
219
- // Mark meta-registry tools (not directly callable, use via use_tool)
220
- const isMeta = metaTools.some(mt => mt.definition.name === t.name);
221
213
  return {
222
214
  name: t.name,
223
- description: isMeta ? `[via use_tool] ${description}` : description,
215
+ description,
224
216
  parameters,
225
217
  permission,
226
218
  };
Binary file
@@ -74,7 +74,7 @@ export interface WorkItemHistoryRecord {
74
74
  changed_by: string | null;
75
75
  changed_at: string;
76
76
  }
77
- export type ProjectType = 'general' | 'web' | 'cli' | 'library' | 'api';
77
+ export type ProjectType = 'general' | 'web' | 'cli' | 'library' | 'api' | 'research' | 'business-plan' | 'content' | 'tech-docs' | 'course' | 'book';
78
78
  export type ProjectStatus = 'active' | 'paused' | 'completed' | 'archived';
79
79
  export type RepoPattern = 'single' | 'two-repo';
80
80
  export type WorkflowMode = 'flexible' | 'guided';
@@ -1,20 +1,20 @@
1
1
  /**
2
2
  * Episodes Module (CLI)
3
3
  *
4
- * Work history tracking with file-based persistence and automatic recording.
4
+ * Thin re-export of the SDK's `episodes` module (moved 2026-06-05 in
5
+ * audit TODO-14) plus the CLI-only "global episode store" singleton
6
+ * that the platform-adapter uses to bridge the agent's IEpisodeService
7
+ * to a concrete `FileEpisodeStore`. Desktop doesn't need the singleton
8
+ * — it wires its store via direct DI on the platform context.
9
+ *
10
+ * For new code, import from `@compilr-dev/sdk` directly.
5
11
  */
6
12
  import type { EpisodeStore } from '@compilr-dev/agents';
7
- export { FileEpisodeStore } from './store.js';
8
- export type { FileEpisodeStoreOptions } from './store.js';
9
- export { EpisodeRecorder } from './recorder.js';
10
- export type { EpisodeRecorderConfig } from './recorder.js';
11
- export { isSignificantWork, extractAffectedFiles, extractLinesChanged } from './significant-work.js';
12
- export { queryWorkAtRisk } from './work-at-risk.js';
13
- export { buildWorkSummaryContent, updateWorkSummaryAnchor } from './work-summary-anchor.js';
14
- export type { WorkSummaryAnchorConfig } from './work-summary-anchor.js';
15
- export type { PendingToolSignal, EpisodeFile } from './types.js';
16
- export type { Effort, WorkEpisode, EffortSignals, EffortWeights, EffortSummary, ProjectWorkSummary, WorkAtRisk, EpisodeStore, } from './types.js';
17
- /** Set the global episode store (called during startup) */
13
+ export { FileEpisodeStore, EpisodeRecorder, isSignificantWork, extractAffectedFiles, extractLinesChanged, queryWorkAtRisk, buildWorkSummaryContent, updateWorkSummaryAnchor, } from '@compilr-dev/sdk';
14
+ export type { FileEpisodeStoreOptions, EpisodeRecorderConfig, WorkSummaryAnchorConfig, PendingToolSignal, EpisodeFile, } from '@compilr-dev/sdk';
15
+ export type { Effort, WorkEpisode, EffortSignals, EffortWeights, EffortSummary, ProjectWorkSummary, WorkAtRisk, EpisodeStore, } from '@compilr-dev/agents';
16
+ /** Set the global episode store (called during startup). */
18
17
  export declare function setGlobalEpisodeStore(store: EpisodeStore): void;
19
- /** Get the global episode store (used by recall_work tool) */
18
+ /** Get the global episode store (used by the platform adapter's
19
+ * IEpisodeService implementation to back the `recall_work` tool). */
20
20
  export declare function getGlobalEpisodeStore(): EpisodeStore | null;
@@ -1,27 +1,26 @@
1
1
  /**
2
2
  * Episodes Module (CLI)
3
3
  *
4
- * Work history tracking with file-based persistence and automatic recording.
4
+ * Thin re-export of the SDK's `episodes` module (moved 2026-06-05 in
5
+ * audit TODO-14) plus the CLI-only "global episode store" singleton
6
+ * that the platform-adapter uses to bridge the agent's IEpisodeService
7
+ * to a concrete `FileEpisodeStore`. Desktop doesn't need the singleton
8
+ * — it wires its store via direct DI on the platform context.
9
+ *
10
+ * For new code, import from `@compilr-dev/sdk` directly.
5
11
  */
6
- // Store
7
- export { FileEpisodeStore } from './store.js';
8
- // Recorder
9
- export { EpisodeRecorder } from './recorder.js';
10
- // Significant work detection
11
- export { isSignificantWork, extractAffectedFiles, extractLinesChanged } from './significant-work.js';
12
- // Work at risk
13
- export { queryWorkAtRisk } from './work-at-risk.js';
14
- // Work summary anchor
15
- export { buildWorkSummaryContent, updateWorkSummaryAnchor } from './work-summary-anchor.js';
12
+ // Store, Recorder, helpers — all moved to SDK
13
+ export { FileEpisodeStore, EpisodeRecorder, isSignificantWork, extractAffectedFiles, extractLinesChanged, queryWorkAtRisk, buildWorkSummaryContent, updateWorkSummaryAnchor, } from '@compilr-dev/sdk';
16
14
  // =============================================================================
17
- // Global Episode Store
15
+ // Global Episode Store (CLI-only)
18
16
  // =============================================================================
19
17
  let _globalStore = null;
20
- /** Set the global episode store (called during startup) */
18
+ /** Set the global episode store (called during startup). */
21
19
  export function setGlobalEpisodeStore(store) {
22
20
  _globalStore = store;
23
21
  }
24
- /** Get the global episode store (used by recall_work tool) */
22
+ /** Get the global episode store (used by the platform adapter's
23
+ * IEpisodeService implementation to back the `recall_work` tool). */
25
24
  export function getGlobalEpisodeStore() {
26
25
  return _globalStore;
27
26
  }
@@ -75,13 +75,65 @@ Saved per project (not session): anchors, team agents, documents.`,
75
75
  {
76
76
  id: 'command-team',
77
77
  title: '/team Command',
78
- keywords: ['/team', 'team', 'agents', 'manage'],
78
+ keywords: ['/team', 'team', 'agents', 'manage', 'roster', 'specialists'],
79
79
  content: `/team — View and manage team agents.
80
80
 
81
81
  Shows all available agents with status and context usage.
82
82
  Tabs: Agents (list) | Context (token usage per agent)
83
83
 
84
- Switch agents: select + Enter, or use $ prefix in REPL ($arch, $pm, $qa).`,
84
+ Switch agents: select + Enter, or use $ prefix in REPL ($arch, $pm, $qa).
85
+
86
+ How agents get into your team:
87
+ - New projects: the /new wizard's Team Roster step (see command-new)
88
+ batch-adds the project type's suggested specialists when you finish.
89
+ Software Development projects come with $dev, $arch, $qa, $pm by
90
+ default; research/business/book types have their own curated teams.
91
+ - Manually after creation: open the Agents tab of /team and pick a role
92
+ to add, or use the Agent Workshop (any tab → '+' from /team).
93
+ - A handoff from another agent: if an agent calls handoff to a role
94
+ that isn't in the team, the team picks it up automatically.
95
+
96
+ To remove an agent: select it in /team and press the delete key. Their
97
+ conversation history is kept in the resume store but won't appear in $ mentions.`,
98
+ },
99
+ {
100
+ id: 'command-new',
101
+ title: '/new Command (Creating a Project)',
102
+ keywords: ['/new', 'new project', 'create project', 'project type', 'wizard', 'roster', 'team', 'tutorial'],
103
+ content: `/new — Create a new project (or import an existing folder).
104
+
105
+ Wizard steps (in order):
106
+
107
+ Step 0 Pick "Start a new project" or "Import existing folder"
108
+ Step 1 Project name (lowercase, alphanumeric + hyphens)
109
+ Step 2 Description (≥10 characters)
110
+ Step 3 Project type
111
+ Step 4 Tech stack (software types only)
112
+ Step 5 Coding standards (software types only)
113
+ Step 6 Git: init? + optional remote URL
114
+ Step 7 Team roster (skipped if the type has no suggested team)
115
+ Step 8 Final confirmation + create
116
+
117
+ Step 3 — Project Type:
118
+ Eight types — Software Development, General Purpose, Research Paper,
119
+ Content & Marketing, Technical Documentation, Book, Business Plan,
120
+ Course. The picked type drives whether steps 4+5 appear (software
121
+ only) and which specialists step 7 suggests. The type also gets
122
+ stored on the project so type-specific skills and action grids
123
+ activate correctly.
124
+
125
+ Step 7 — Team Roster:
126
+ Three options. (1) Add all suggested specialists (recommended, the
127
+ default). (2) Customize selection — toggles each suggested agent
128
+ on/off via Space. (3) Skip — start with just $default and use
129
+ /team add later to add roles manually.
130
+
131
+ For project types without a default team (General Purpose), step 7 is
132
+ skipped automatically.
133
+
134
+ When the wizard finishes, the project is created on disk, registered
135
+ in the database with the correct type, and the chosen specialists are
136
+ spawned into the fresh team. You can see them by running /team.`,
85
137
  },
86
138
  ];
87
139
  // =============================================================================