@compilr-dev/cli 0.5.14 → 0.5.16
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/.tsbuildinfo.app +1 -1
- package/dist/.tsbuildinfo.data +1 -1
- package/dist/.tsbuildinfo.domain +1 -1
- package/dist/.tsbuildinfo.foundation +1 -1
- package/dist/agent.d.ts +4 -0
- package/dist/agent.js +29 -155
- package/dist/commands-v2/handlers/reset.js +9 -0
- package/dist/commands-v2/handlers/session.d.ts +2 -2
- package/dist/commands-v2/handlers/session.js +10 -10
- package/dist/compilr-diff-companion.vsix +0 -0
- package/dist/input-handlers/memory-handler.js +3 -3
- package/dist/repl-v2.js +6 -6
- package/dist/shared-handlers.d.ts +2 -32
- package/dist/tools/ask-user-simple.d.ts +4 -15
- package/dist/tools/ask-user-simple.js +10 -82
- package/dist/tools/ask-user.d.ts +5 -28
- package/dist/tools/ask-user.js +10 -109
- package/dist/tools/db-tools.d.ts +1 -1
- package/dist/tools/platform-adapter.d.ts +1 -1
- package/package.json +3 -3
package/dist/agent.d.ts
CHANGED
|
@@ -194,6 +194,10 @@ export declare function getBuiltinGuardrailInfo(): Array<{
|
|
|
194
194
|
action: 'warn' | 'confirm' | 'block';
|
|
195
195
|
category: string;
|
|
196
196
|
}>;
|
|
197
|
+
/**
|
|
198
|
+
* Derive profile group IDs from a tool filter (array of tool names).
|
|
199
|
+
* A group is included if any of its tools are in the filter.
|
|
200
|
+
*/
|
|
197
201
|
/**
|
|
198
202
|
* Creates an Agent instance configured with all tools.
|
|
199
203
|
*/
|
package/dist/agent.js
CHANGED
|
@@ -5,11 +5,11 @@
|
|
|
5
5
|
* ClaudeProvider, OllamaProvider, OpenAIProvider, or GeminiProvider
|
|
6
6
|
* and available tools.
|
|
7
7
|
*/
|
|
8
|
-
import { Agent, ContextManager, DEFAULT_CONTEXT_CONFIG, createTaskTool, createSuggestTool, defaultAgentTypes, TOOL_SETS, BUILTIN_GUARDRAILS, createProviderFromType, CapabilityManager, CAPABILITY_PACKS, GIT_SAFETY_MODULE, PLATFORM_TOOL_HINTS_MODULE, FACTORY_TOOL_HINTS_MODULE, TOOL_USAGE_META_MODULE, createLoadCapabilityTool,
|
|
8
|
+
import { Agent, ContextManager, DEFAULT_CONTEXT_CONFIG, createTaskTool, createSuggestTool, defaultAgentTypes, TOOL_SETS, BUILTIN_GUARDRAILS, createProviderFromType, CapabilityManager, CapabilityContext, CAPABILITY_PACKS, GIT_SAFETY_MODULE, PLATFORM_TOOL_HINTS_MODULE, FACTORY_TOOL_HINTS_MODULE, TOOL_USAGE_META_MODULE, createLoadCapabilityTool, createCapabilityHook, resolveProfileGroups, resolveUpfrontGroups, } from '@compilr-dev/sdk';
|
|
9
9
|
import { isAutoCompactEnabled, isDelegationEnabled, getSetting } from './settings/index.js';
|
|
10
10
|
import { getApiKey } from './utils/credentials.js';
|
|
11
11
|
import { createToolRegistry, createMinimalToolRegistry, getDirectTools, getMetaTools, initializeMetaTools, getToolIndexForSystemPrompt, getFilteredToolIndexForSystemPrompt, getToolStats, setMetaToolFilter, createToolFallback, getRegisteredMetaTools, } from './tools.js';
|
|
12
|
-
|
|
12
|
+
// TOOL_GROUPS no longer needed — profile resolution moved to SDK
|
|
13
13
|
import { setCapabilityManager } from './multi-agent/capability-loader.js';
|
|
14
14
|
import { getAgentRegistry } from './agents/registry.js';
|
|
15
15
|
import { SystemPromptBuilder } from './system-prompt/index.js';
|
|
@@ -135,144 +135,9 @@ function createProvider(options) {
|
|
|
135
135
|
* Derive profile group IDs from a tool filter (array of tool names).
|
|
136
136
|
* A group is included if any of its tools are in the filter.
|
|
137
137
|
*/
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
for (const [groupId, group] of Object.entries(TOOL_GROUPS)) {
|
|
142
|
-
if (group.tools.some((t) => toolSet.has(t))) {
|
|
143
|
-
groups.push(groupId);
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
|
-
return groups;
|
|
147
|
-
}
|
|
148
|
-
/**
|
|
149
|
-
* Scan recent messages for "Tool not found: X" errors and auto-load
|
|
150
|
-
* the corresponding capability packs (max 2 per turn, loadable only).
|
|
151
|
-
* Also detects forbidden tool access for handoff suggestions.
|
|
152
|
-
*/
|
|
153
|
-
function autoDetectCapabilities(manager, messages) {
|
|
154
|
-
const MAX_AUTO_LOADS = 2;
|
|
155
|
-
const result = { loaded: [], forbidden: [] };
|
|
156
|
-
const toolNotFoundPattern = /Tool not found: (\w+)/;
|
|
157
|
-
// Find the most recent user message (contains the last turn's tool results)
|
|
158
|
-
for (let i = messages.length - 1; i >= 0; i--) {
|
|
159
|
-
const msg = messages[i];
|
|
160
|
-
if (msg.role !== 'user' || typeof msg.content === 'string')
|
|
161
|
-
continue;
|
|
162
|
-
// Scan this message's tool_result blocks for "Tool not found" errors
|
|
163
|
-
for (const block of msg.content) {
|
|
164
|
-
if (block.type !== 'tool_result' || !block.isError || !block.content)
|
|
165
|
-
continue;
|
|
166
|
-
const match = toolNotFoundPattern.exec(block.content);
|
|
167
|
-
if (!match)
|
|
168
|
-
continue;
|
|
169
|
-
const toolName = match[1];
|
|
170
|
-
const packId = manager.findPackForTool(toolName);
|
|
171
|
-
if (!packId || manager.isLoaded(packId))
|
|
172
|
-
continue;
|
|
173
|
-
const tier = manager.getTier(packId);
|
|
174
|
-
if (tier === 'loadable' && result.loaded.length < MAX_AUTO_LOADS) {
|
|
175
|
-
manager.load(packId, 'auto-detect');
|
|
176
|
-
result.loaded.push(packId);
|
|
177
|
-
}
|
|
178
|
-
else if (tier === 'forbidden') {
|
|
179
|
-
result.forbidden.push({
|
|
180
|
-
toolName,
|
|
181
|
-
packId,
|
|
182
|
-
suggestedAgent: manager.getSuggestedAgent(packId),
|
|
183
|
-
});
|
|
184
|
-
}
|
|
185
|
-
}
|
|
186
|
-
// Only scan the most recent user message
|
|
187
|
-
break;
|
|
188
|
-
}
|
|
189
|
-
return result;
|
|
190
|
-
}
|
|
191
|
-
function createCapabilityHook(manager, basePrompt, orphanTools) {
|
|
192
|
-
return (ctx) => {
|
|
193
|
-
// Auto-detect capability needs from tool failures (safety net)
|
|
194
|
-
let forbiddenHints = [];
|
|
195
|
-
if (manager.hasLoadablePacks() || ctx.messages.length > 1) {
|
|
196
|
-
const detected = autoDetectCapabilities(manager, ctx.messages);
|
|
197
|
-
// Generate handoff suggestions for forbidden tool access
|
|
198
|
-
if (detected.forbidden.length > 0) {
|
|
199
|
-
forbiddenHints = detected.forbidden.map((f) => {
|
|
200
|
-
const agentHint = f.suggestedAgent
|
|
201
|
-
? ` Consider using handoff("${f.suggestedAgent}", "Need ${f.packId} access for ${f.toolName}").`
|
|
202
|
-
: '';
|
|
203
|
-
return `[System] Tool "${f.toolName}" requires ${f.packId} capability which is outside your tool profile.${agentHint}`;
|
|
204
|
-
});
|
|
205
|
-
}
|
|
206
|
-
}
|
|
207
|
-
const activeToolNames = manager.getActiveToolNames();
|
|
208
|
-
const activeModuleIds = manager.getActivePromptModuleIds();
|
|
209
|
-
// Include orphan tools (not in any capability pack) — always visible
|
|
210
|
-
const allActiveTools = [...activeToolNames, ...orphanTools];
|
|
211
|
-
// Update meta-tool filter for this turn
|
|
212
|
-
setMetaToolFilter(allActiveTools);
|
|
213
|
-
// Build dynamic system prompt sections
|
|
214
|
-
const dynamicSections = [];
|
|
215
|
-
// Meta-tools protocol (how to use get_tool_info/use_tool)
|
|
216
|
-
dynamicSections.push(TOOL_USAGE_META_MODULE.content);
|
|
217
|
-
// Conditional modules based on loaded capability packs
|
|
218
|
-
if (activeModuleIds.has('git-safety')) {
|
|
219
|
-
dynamicSections.push(GIT_SAFETY_MODULE.content);
|
|
220
|
-
}
|
|
221
|
-
if (activeModuleIds.has('platform-tool-hints')) {
|
|
222
|
-
dynamicSections.push(PLATFORM_TOOL_HINTS_MODULE.content);
|
|
223
|
-
}
|
|
224
|
-
if (activeModuleIds.has('factory-tool-hints')) {
|
|
225
|
-
dynamicSections.push(FACTORY_TOOL_HINTS_MODULE.content);
|
|
226
|
-
}
|
|
227
|
-
// Prompt snippets from loaded packs
|
|
228
|
-
const snippets = manager.getActivePromptSnippets();
|
|
229
|
-
if (snippets.length > 0) {
|
|
230
|
-
dynamicSections.push('## Active Tool Capabilities\n' + snippets.join('\n'));
|
|
231
|
-
}
|
|
232
|
-
// Filtered tool index (only loaded tools)
|
|
233
|
-
const filteredIndex = getFilteredToolIndexForSystemPrompt(allActiveTools);
|
|
234
|
-
dynamicSections.push(filteredIndex);
|
|
235
|
-
// Capability catalog (if loadable packs remain)
|
|
236
|
-
if (manager.hasLoadablePacks()) {
|
|
237
|
-
const catalog = manager.getCatalog();
|
|
238
|
-
const catalogSection = generateCapabilityCatalog(catalog, manager.getLoadedPackIds());
|
|
239
|
-
if (catalogSection) {
|
|
240
|
-
dynamicSections.push(catalogSection);
|
|
241
|
-
}
|
|
242
|
-
}
|
|
243
|
-
// Preserve anchors from the current system prompt.
|
|
244
|
-
// The agents library injects anchors into systemContent BEFORE this hook runs.
|
|
245
|
-
// We must extract and re-append them, since we rebuild the prompt from basePrompt.
|
|
246
|
-
let anchorsBlock = '';
|
|
247
|
-
const anchorMarker = '## Active Anchors (Critical Information)';
|
|
248
|
-
const anchorIdx = ctx.systemPrompt.indexOf(anchorMarker);
|
|
249
|
-
if (anchorIdx > 0) {
|
|
250
|
-
// Find the preceding "---\n\n" separator
|
|
251
|
-
const separatorBefore = ctx.systemPrompt.lastIndexOf('---', anchorIdx);
|
|
252
|
-
const startIdx = separatorBefore > 0 ? separatorBefore : anchorIdx;
|
|
253
|
-
// Find the end: either the next "---" after the anchor block, or end of string
|
|
254
|
-
const afterAnchor = ctx.systemPrompt.indexOf('\n\n---\n\n', anchorIdx);
|
|
255
|
-
if (afterAnchor > 0) {
|
|
256
|
-
// Anchors are followed by more content (e.g., role ending) — extract just the anchor block
|
|
257
|
-
anchorsBlock = '\n\n' + ctx.systemPrompt.substring(startIdx, afterAnchor + 7); // include trailing "---\n\n"
|
|
258
|
-
}
|
|
259
|
-
else {
|
|
260
|
-
// Anchors are at the end of the prompt
|
|
261
|
-
anchorsBlock = '\n\n' + ctx.systemPrompt.substring(startIdx);
|
|
262
|
-
}
|
|
263
|
-
}
|
|
264
|
-
const hookResult = {
|
|
265
|
-
systemPrompt: basePrompt + '\n\n' + dynamicSections.join('\n\n') + anchorsBlock,
|
|
266
|
-
};
|
|
267
|
-
// Inject forbidden boundary messages (handoff suggestions)
|
|
268
|
-
if (forbiddenHints.length > 0) {
|
|
269
|
-
const hintContent = forbiddenHints.join('\n');
|
|
270
|
-
const hintMessage = { role: 'user', content: hintContent };
|
|
271
|
-
hookResult.messages = [...ctx.messages, hintMessage];
|
|
272
|
-
}
|
|
273
|
-
return hookResult;
|
|
274
|
-
};
|
|
275
|
-
}
|
|
138
|
+
// getProfileGroupsFromToolFilter → replaced by resolveProfileGroups from SDK
|
|
139
|
+
// autoDetectCapabilities → replaced by autoDetectCapabilities from SDK
|
|
140
|
+
// createCapabilityHook → replaced by createCapabilityHook + CapabilityContext from SDK
|
|
276
141
|
/**
|
|
277
142
|
* Creates an Agent instance configured with all tools.
|
|
278
143
|
*/
|
|
@@ -322,17 +187,14 @@ export function createAgent(options = {}) {
|
|
|
322
187
|
// tools and prompt modules are active per-turn.
|
|
323
188
|
// ==========================================================================
|
|
324
189
|
let capabilityManager;
|
|
190
|
+
let capabilityContext;
|
|
325
191
|
let orphanToolNames = [];
|
|
326
192
|
if (useMetaTools) {
|
|
327
|
-
//
|
|
193
|
+
// Use SDK's profile resolver instead of local implementation
|
|
328
194
|
const profileGroups = options.toolFilter
|
|
329
|
-
?
|
|
195
|
+
? resolveProfileGroups(options.toolFilter)
|
|
330
196
|
: Object.keys(CAPABILITY_PACKS);
|
|
331
|
-
|
|
332
|
-
const upfrontGroupIds = Object.entries(TOOL_GROUPS)
|
|
333
|
-
.filter(([, group]) => group.tier === 'direct')
|
|
334
|
-
.map(([id]) => id)
|
|
335
|
-
.filter((id) => profileGroups.includes(id));
|
|
197
|
+
const upfrontGroupIds = resolveUpfrontGroups(profileGroups);
|
|
336
198
|
capabilityManager = new CapabilityManager({
|
|
337
199
|
profileGroups,
|
|
338
200
|
packs: CAPABILITY_PACKS,
|
|
@@ -341,7 +203,6 @@ export function createAgent(options = {}) {
|
|
|
341
203
|
// Expose the capability manager for slash command handlers (Phase 3)
|
|
342
204
|
setCapabilityManager(capabilityManager);
|
|
343
205
|
// Compute orphan tools (meta-registry tools not in any capability pack)
|
|
344
|
-
// These are always visible regardless of which packs are loaded.
|
|
345
206
|
const packedTools = new Set();
|
|
346
207
|
for (const pack of Object.values(CAPABILITY_PACKS)) {
|
|
347
208
|
for (const tool of pack.tools) {
|
|
@@ -352,8 +213,13 @@ export function createAgent(options = {}) {
|
|
|
352
213
|
orphanToolNames = registered
|
|
353
214
|
.map((t) => t.definition.name)
|
|
354
215
|
.filter((name) => !packedTools.has(name));
|
|
355
|
-
//
|
|
356
|
-
|
|
216
|
+
// Create capability context (SDK) for filter sync + auto-load callback
|
|
217
|
+
capabilityContext = new CapabilityContext({
|
|
218
|
+
manager: capabilityManager,
|
|
219
|
+
orphanTools: orphanToolNames,
|
|
220
|
+
onFilterUpdate: (allowed) => { setMetaToolFilter(allowed); },
|
|
221
|
+
});
|
|
222
|
+
capabilityContext.syncFilter();
|
|
357
223
|
// Log stats (unless quiet mode)
|
|
358
224
|
if (!options.quiet) {
|
|
359
225
|
const stats = getToolStats();
|
|
@@ -506,9 +372,17 @@ ${options.systemPromptAddition}
|
|
|
506
372
|
messages.splice(1, 0, { role: 'user', content: hint });
|
|
507
373
|
return { messages };
|
|
508
374
|
},
|
|
509
|
-
// Capability-aware system prompt assembly (with auto-detection
|
|
510
|
-
...(
|
|
511
|
-
? [createCapabilityHook(
|
|
375
|
+
// Capability-aware system prompt assembly (SDK hook with auto-detection)
|
|
376
|
+
...(capabilityContext && baseSystemPrompt
|
|
377
|
+
? [createCapabilityHook(capabilityContext, baseSystemPrompt, {
|
|
378
|
+
staticSections: [TOOL_USAGE_META_MODULE.content],
|
|
379
|
+
conditionalModules: [
|
|
380
|
+
{ content: GIT_SAFETY_MODULE.content, whenModuleActive: ['git-safety'] },
|
|
381
|
+
{ content: PLATFORM_TOOL_HINTS_MODULE.content, whenModuleActive: ['platform-tool-hints'] },
|
|
382
|
+
{ content: FACTORY_TOOL_HINTS_MODULE.content, whenModuleActive: ['factory-tool-hints'] },
|
|
383
|
+
],
|
|
384
|
+
getToolIndex: (allowedNames) => getFilteredToolIndexForSystemPrompt(allowedNames),
|
|
385
|
+
})]
|
|
512
386
|
: []),
|
|
513
387
|
],
|
|
514
388
|
beforeTool: [createFileLockCheckHook(getActiveProject)],
|
|
@@ -518,10 +392,10 @@ ${options.systemPromptAddition}
|
|
|
518
392
|
],
|
|
519
393
|
},
|
|
520
394
|
});
|
|
521
|
-
// Load persisted anchors into the agent's
|
|
395
|
+
// Load persisted anchors into the agent's pin manager
|
|
522
396
|
if (options.enableAnchors && options.persistedAnchors) {
|
|
523
397
|
for (const anchor of options.persistedAnchors) {
|
|
524
|
-
agent.
|
|
398
|
+
agent.addPin({
|
|
525
399
|
id: anchor.id,
|
|
526
400
|
content: anchor.content,
|
|
527
401
|
priority: anchor.priority,
|
|
@@ -103,6 +103,15 @@ export const resetCommand = {
|
|
|
103
103
|
ctx.restoreAgent(freshAgent);
|
|
104
104
|
if (ctx.team) {
|
|
105
105
|
ctx.team.setDefaultAgent(freshAgent);
|
|
106
|
+
// Re-inject team roster pin into the fresh agent so it knows about teammates
|
|
107
|
+
if (ctx.team.sharedContext.hasTeamRoster() && freshAgent.hasPins()) {
|
|
108
|
+
freshAgent.addPin({
|
|
109
|
+
id: 'team-roster',
|
|
110
|
+
content: ctx.team.sharedContext.formatTeamRoster(),
|
|
111
|
+
priority: 'info',
|
|
112
|
+
scope: 'session',
|
|
113
|
+
});
|
|
114
|
+
}
|
|
106
115
|
}
|
|
107
116
|
}
|
|
108
117
|
catch {
|
|
@@ -93,8 +93,8 @@ export declare function handleProjectSwitch(oldProjectId: number | null, agent:
|
|
|
93
93
|
turnCount?: number;
|
|
94
94
|
}) => Promise<unknown>;
|
|
95
95
|
clearHistory: () => unknown;
|
|
96
|
-
|
|
97
|
-
|
|
96
|
+
clearPins?: (options?: AnchorClearOptions) => number;
|
|
97
|
+
addPin?: (input: {
|
|
98
98
|
id?: string;
|
|
99
99
|
content: string;
|
|
100
100
|
priority: AnchorPriority;
|
|
@@ -440,11 +440,11 @@ export async function handleProjectSwitch(oldProjectId, agent, teamOptions, agen
|
|
|
440
440
|
await agentOptions.updateProjectState?.(newProjectId);
|
|
441
441
|
// 2. Create fresh default agent with new project's system prompt
|
|
442
442
|
newAgent = await agentOptions.agentFactory({});
|
|
443
|
-
// 3. Transfer anchors to the NEW agent
|
|
444
|
-
newAgent.
|
|
443
|
+
// 3. Transfer anchors to the NEW agent's pin manager
|
|
444
|
+
newAgent.clearPins({ scope: 'persistent' });
|
|
445
445
|
const newAnchors = await getProjectAnchors(newProjectId);
|
|
446
446
|
for (const anchor of newAnchors) {
|
|
447
|
-
newAgent.
|
|
447
|
+
newAgent.addPin({
|
|
448
448
|
id: anchor.id,
|
|
449
449
|
content: anchor.content,
|
|
450
450
|
priority: anchor.priority,
|
|
@@ -465,12 +465,12 @@ export async function handleProjectSwitch(oldProjectId, agent, teamOptions, agen
|
|
|
465
465
|
// If no new agent was created, update the old agent as before
|
|
466
466
|
if (!newAgent) {
|
|
467
467
|
try {
|
|
468
|
-
// Update old agent's
|
|
469
|
-
if (agent?.
|
|
470
|
-
agent.
|
|
468
|
+
// Update old agent's pins
|
|
469
|
+
if (agent?.clearPins && agent.addPin) {
|
|
470
|
+
agent.clearPins({ scope: 'persistent' });
|
|
471
471
|
const newAnchors = await getProjectAnchors(newProjectId);
|
|
472
472
|
for (const anchor of newAnchors) {
|
|
473
|
-
agent.
|
|
473
|
+
agent.addPin({
|
|
474
474
|
id: anchor.id,
|
|
475
475
|
content: anchor.content,
|
|
476
476
|
priority: anchor.priority,
|
|
@@ -731,9 +731,9 @@ export const resumeCommand = {
|
|
|
731
731
|
path: activeProject.path,
|
|
732
732
|
});
|
|
733
733
|
}
|
|
734
|
-
// Set team roster
|
|
735
|
-
if (persistedTeam.sharedContext.hasTeamRoster() && ctx.agent?.
|
|
736
|
-
ctx.agent.
|
|
734
|
+
// Set team roster pin
|
|
735
|
+
if (persistedTeam.sharedContext.hasTeamRoster() && ctx.agent?.hasPins()) {
|
|
736
|
+
ctx.agent.addPin({
|
|
737
737
|
id: 'team-roster',
|
|
738
738
|
content: persistedTeam.sharedContext.formatTeamRoster(),
|
|
739
739
|
priority: 'info',
|
|
Binary file
|
|
@@ -56,9 +56,9 @@ export function handleMemoryInput(input, ctx) {
|
|
|
56
56
|
conversation.printSuccess(`Saved${priorityLabel}: "${truncate(note, 50)}" → ${scope}`);
|
|
57
57
|
terminal.writeLine('');
|
|
58
58
|
ctx.footer.forceRender();
|
|
59
|
-
// Also add to agent's
|
|
60
|
-
if (ctx.agent.
|
|
61
|
-
ctx.agent.
|
|
59
|
+
// Also add to agent's pin manager if enabled (for current session)
|
|
60
|
+
if (ctx.agent.getPinManager()) {
|
|
61
|
+
ctx.agent.addPin({
|
|
62
62
|
id: anchor.id,
|
|
63
63
|
content: note,
|
|
64
64
|
priority,
|
package/dist/repl-v2.js
CHANGED
|
@@ -1181,9 +1181,9 @@ export class ReplV2 {
|
|
|
1181
1181
|
path: activeProject.path,
|
|
1182
1182
|
});
|
|
1183
1183
|
}
|
|
1184
|
-
// Set team roster as
|
|
1185
|
-
if (persistedTeam.sharedContext.hasTeamRoster() && currentAgent?.
|
|
1186
|
-
currentAgent.
|
|
1184
|
+
// Set team roster as pin on the default agent
|
|
1185
|
+
if (persistedTeam.sharedContext.hasTeamRoster() && currentAgent?.hasPins()) {
|
|
1186
|
+
currentAgent.addPin({
|
|
1187
1187
|
id: 'team-roster',
|
|
1188
1188
|
content: persistedTeam.sharedContext.formatTeamRoster(),
|
|
1189
1189
|
priority: 'info',
|
|
@@ -2122,9 +2122,9 @@ export class ReplV2 {
|
|
|
2122
2122
|
const priorityLabel = priority === 'info' ? '' : ` (${priority})`;
|
|
2123
2123
|
const truncatedNote = truncate(note, 50);
|
|
2124
2124
|
this.ui.print({ type: 'success', message: `Saved${priorityLabel}: "${truncatedNote}" → ${scope}` });
|
|
2125
|
-
// Also add to agent's
|
|
2126
|
-
if (this.agent?.
|
|
2127
|
-
this.agent.
|
|
2125
|
+
// Also add to agent's pin manager if enabled (for current session)
|
|
2126
|
+
if (this.agent?.getPinManager()) {
|
|
2127
|
+
this.agent.addPin({
|
|
2128
2128
|
id: anchor.id,
|
|
2129
2129
|
content: note,
|
|
2130
2130
|
priority,
|
|
@@ -5,38 +5,8 @@
|
|
|
5
5
|
* accessible from tools but are set up at the application level.
|
|
6
6
|
* This avoids circular imports between index.ts and tool modules.
|
|
7
7
|
*/
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
header: string;
|
|
11
|
-
question: string;
|
|
12
|
-
options?: string[];
|
|
13
|
-
allowCustom?: boolean;
|
|
14
|
-
multiSelect?: boolean;
|
|
15
|
-
}
|
|
16
|
-
export interface AskUserInput {
|
|
17
|
-
questions: AskUserQuestion[];
|
|
18
|
-
context?: string;
|
|
19
|
-
}
|
|
20
|
-
export interface AskUserResult {
|
|
21
|
-
answers: Record<string, string | string[]>;
|
|
22
|
-
skipped: string[];
|
|
23
|
-
}
|
|
24
|
-
export type AskUserHandler = (input: AskUserInput) => Promise<AskUserResult>;
|
|
25
|
-
export interface AskUserSimpleInput {
|
|
26
|
-
/** The question text */
|
|
27
|
-
question: string;
|
|
28
|
-
/** Predefined options (optional, max 5) */
|
|
29
|
-
options?: string[];
|
|
30
|
-
/** Allow free-text input (default: true) */
|
|
31
|
-
allowCustom?: boolean;
|
|
32
|
-
}
|
|
33
|
-
export interface AskUserSimpleResult {
|
|
34
|
-
/** User's answer */
|
|
35
|
-
answer: string;
|
|
36
|
-
/** True if user skipped the question */
|
|
37
|
-
skipped: boolean;
|
|
38
|
-
}
|
|
39
|
-
export type AskUserSimpleHandler = (input: AskUserSimpleInput) => Promise<AskUserSimpleResult>;
|
|
8
|
+
import type { AskUserHandler, AskUserSimpleHandler } from '@compilr-dev/sdk';
|
|
9
|
+
export type { AskUserQuestion, AskUserInput, AskUserResult, AskUserHandler, AskUserSimpleInput, AskUserSimpleResult, AskUserSimpleHandler, } from '@compilr-dev/sdk';
|
|
40
10
|
/**
|
|
41
11
|
* Register the ask_user handler. Called during app initialization.
|
|
42
12
|
*/
|
|
@@ -1,19 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Ask User Simple Tool
|
|
2
|
+
* Ask User Simple Tool — CLI wrapper around SDK factory
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
* models like Haiku, Flash, and GPT-4o-mini to generate correctly.
|
|
7
|
-
*
|
|
8
|
-
* Used by /sketch command for quick project outlines.
|
|
4
|
+
* Uses getAskUserSimpleHandler() from shared-handlers.ts which coordinates
|
|
5
|
+
* with the terminal footer (pause/resume) and shows the overlay.
|
|
9
6
|
*/
|
|
10
|
-
|
|
11
|
-
/** The question text */
|
|
12
|
-
question: string;
|
|
13
|
-
/** Predefined options (optional, max 5) */
|
|
14
|
-
options?: string[];
|
|
15
|
-
/** Allow free-text input (default: true) */
|
|
16
|
-
allowCustom?: boolean;
|
|
17
|
-
}
|
|
7
|
+
import { type AskUserSimpleInput } from '@compilr-dev/sdk';
|
|
18
8
|
export declare const askUserSimpleTool: import("@compilr-dev/sdk").Tool<AskUserSimpleInput>;
|
|
19
|
-
export {};
|
|
@@ -1,87 +1,15 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Ask User Simple Tool
|
|
2
|
+
* Ask User Simple Tool — CLI wrapper around SDK factory
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
* models like Haiku, Flash, and GPT-4o-mini to generate correctly.
|
|
7
|
-
*
|
|
8
|
-
* Used by /sketch command for quick project outlines.
|
|
4
|
+
* Uses getAskUserSimpleHandler() from shared-handlers.ts which coordinates
|
|
5
|
+
* with the terminal footer (pause/resume) and shows the overlay.
|
|
9
6
|
*/
|
|
10
|
-
import {
|
|
7
|
+
import { createAskUserSimpleTool } from '@compilr-dev/sdk';
|
|
11
8
|
import { getAskUserSimpleHandler } from '../shared-handlers.js';
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
'Provide optional predefined choices or allow free-text input. ' +
|
|
19
|
-
'Use this for simple question flows - one question at a time. ' +
|
|
20
|
-
'Best suited for /sketch command and smaller models.',
|
|
21
|
-
inputSchema: {
|
|
22
|
-
type: 'object',
|
|
23
|
-
properties: {
|
|
24
|
-
question: {
|
|
25
|
-
type: 'string',
|
|
26
|
-
description: 'The question to ask the user',
|
|
27
|
-
},
|
|
28
|
-
options: {
|
|
29
|
-
type: 'array',
|
|
30
|
-
description: 'Predefined options for the user to choose from (max 5)',
|
|
31
|
-
items: { type: 'string' },
|
|
32
|
-
maxItems: 5,
|
|
33
|
-
},
|
|
34
|
-
allowCustom: {
|
|
35
|
-
type: 'boolean',
|
|
36
|
-
description: 'Allow free-text input in addition to options (default: true)',
|
|
37
|
-
},
|
|
38
|
-
},
|
|
39
|
-
required: ['question'],
|
|
40
|
-
},
|
|
41
|
-
execute: async (input) => {
|
|
42
|
-
try {
|
|
43
|
-
// Validate input
|
|
44
|
-
if (!input.question || input.question.trim().length === 0) {
|
|
45
|
-
return {
|
|
46
|
-
success: false,
|
|
47
|
-
error: 'Question text is required',
|
|
48
|
-
};
|
|
49
|
-
}
|
|
50
|
-
if (input.options && input.options.length > 5) {
|
|
51
|
-
return {
|
|
52
|
-
success: false,
|
|
53
|
-
error: 'Maximum 5 options allowed',
|
|
54
|
-
};
|
|
55
|
-
}
|
|
56
|
-
// Get the handler from shared-handlers
|
|
57
|
-
const askUserSimpleHandler = getAskUserSimpleHandler();
|
|
58
|
-
if (!askUserSimpleHandler) {
|
|
59
|
-
return {
|
|
60
|
-
success: false,
|
|
61
|
-
error: 'ask_user_simple handler not initialized. This tool requires the CLI context.',
|
|
62
|
-
};
|
|
63
|
-
}
|
|
64
|
-
// Show the overlay via the handler (which pauses footer)
|
|
65
|
-
const result = await askUserSimpleHandler({
|
|
66
|
-
question: input.question,
|
|
67
|
-
options: input.options,
|
|
68
|
-
allowCustom: input.allowCustom,
|
|
69
|
-
});
|
|
70
|
-
const output = {
|
|
71
|
-
answer: result.answer,
|
|
72
|
-
skipped: result.skipped,
|
|
73
|
-
};
|
|
74
|
-
return {
|
|
75
|
-
success: true,
|
|
76
|
-
result: output,
|
|
77
|
-
};
|
|
78
|
-
}
|
|
79
|
-
catch (err) {
|
|
80
|
-
return {
|
|
81
|
-
success: false,
|
|
82
|
-
error: `Failed to ask user: ${err instanceof Error ? err.message : String(err)}`,
|
|
83
|
-
};
|
|
84
|
-
}
|
|
85
|
-
},
|
|
86
|
-
silent: true,
|
|
9
|
+
export const askUserSimpleTool = createAskUserSimpleTool(async (input) => {
|
|
10
|
+
const handler = getAskUserSimpleHandler();
|
|
11
|
+
if (!handler) {
|
|
12
|
+
throw new Error('ask_user_simple handler not initialized. This tool requires the CLI context.');
|
|
13
|
+
}
|
|
14
|
+
return handler(input);
|
|
87
15
|
});
|
package/dist/tools/ask-user.d.ts
CHANGED
|
@@ -1,32 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Ask User Tool
|
|
2
|
+
* Ask User Tool — CLI wrapper around SDK factory
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
* Note: This tool uses a callback pattern to coordinate with the footer.
|
|
8
|
-
* The actual overlay is shown via getAskUserHandler() from shared-handlers.ts
|
|
9
|
-
* which is registered during app initialization and properly pauses the footer.
|
|
4
|
+
* Uses getAskUserHandler() from shared-handlers.ts which coordinates
|
|
5
|
+
* with the terminal footer (pause/resume) and shows the overlay.
|
|
10
6
|
*/
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
id: string;
|
|
14
|
-
/** Short label for tab display (e.g., "App Type", "Users") - max 12 chars */
|
|
15
|
-
header: string;
|
|
16
|
-
/** The question text */
|
|
17
|
-
question: string;
|
|
18
|
-
/** Predefined options (optional) */
|
|
19
|
-
options?: string[];
|
|
20
|
-
/** Allow free-text input (default: true) */
|
|
21
|
-
allowCustom?: boolean;
|
|
22
|
-
/** Allow multiple selections (default: false) */
|
|
23
|
-
multiSelect?: boolean;
|
|
24
|
-
}
|
|
25
|
-
interface AskUserInput {
|
|
26
|
-
/** 1-5 questions to ask */
|
|
27
|
-
questions: AskUserQuestion[];
|
|
28
|
-
/** Optional context shown above questions */
|
|
29
|
-
context?: string;
|
|
30
|
-
}
|
|
7
|
+
import { type AskUserInput } from '@compilr-dev/sdk';
|
|
8
|
+
export type { AskUserQuestion } from '@compilr-dev/sdk';
|
|
31
9
|
export declare const askUserTool: import("@compilr-dev/sdk").Tool<AskUserInput>;
|
|
32
|
-
export {};
|