@compilr-dev/agents 0.2.1 → 0.3.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.
@@ -0,0 +1,64 @@
1
+ /**
2
+ * Ask User Simple Tool - Single question with simple string options
3
+ *
4
+ * A simplified version of ask_user for single questions with string options.
5
+ * Preferred over ask_user when you only need to ask one simple question.
6
+ *
7
+ * Features:
8
+ * - Single question
9
+ * - Simple string options (no value/label distinction)
10
+ * - Default value support
11
+ * - Factory function for custom implementations
12
+ */
13
+ import type { Tool } from '../types.js';
14
+ /**
15
+ * Input parameters for ask_user_simple tool
16
+ */
17
+ export interface AskUserSimpleInput {
18
+ /** The question to ask */
19
+ question: string;
20
+ /** Simple string options to choose from */
21
+ options: string[];
22
+ /** Default value if user skips (optional) */
23
+ default?: string;
24
+ }
25
+ /**
26
+ * Result from ask_user_simple tool
27
+ */
28
+ export interface AskUserSimpleResult {
29
+ /** The selected answer */
30
+ answer: string;
31
+ /** Whether the default was used */
32
+ usedDefault?: boolean;
33
+ }
34
+ /**
35
+ * Options for creating custom ask_user_simple tool
36
+ */
37
+ export interface AskUserSimpleToolOptions {
38
+ /**
39
+ * Custom handler for asking the question.
40
+ * If not provided, uses readline-based implementation.
41
+ */
42
+ onAsk?: (question: string, options: string[], defaultValue?: string) => Promise<AskUserSimpleResult>;
43
+ }
44
+ /**
45
+ * Default ask_user_simple tool using readline for basic CLI interaction.
46
+ * Use createAskUserSimpleTool() for custom implementations.
47
+ */
48
+ export declare const askUserSimpleTool: Tool<AskUserSimpleInput>;
49
+ /**
50
+ * Create a custom ask_user_simple tool with your own UI implementation.
51
+ *
52
+ * @example
53
+ * ```typescript
54
+ * const customAskSimple = createAskUserSimpleTool({
55
+ * onAsk: async (question, options, defaultValue) => {
56
+ * // Show fancy UI overlay
57
+ * const overlay = new AskUserSimpleOverlay({ question, options, defaultValue });
58
+ * return await ui.showOverlay(overlay);
59
+ * }
60
+ * });
61
+ * agent.registerTool(customAskSimple);
62
+ * ```
63
+ */
64
+ export declare function createAskUserSimpleTool(options?: AskUserSimpleToolOptions): Tool<AskUserSimpleInput>;
@@ -0,0 +1,149 @@
1
+ /**
2
+ * Ask User Simple Tool - Single question with simple string options
3
+ *
4
+ * A simplified version of ask_user for single questions with string options.
5
+ * Preferred over ask_user when you only need to ask one simple question.
6
+ *
7
+ * Features:
8
+ * - Single question
9
+ * - Simple string options (no value/label distinction)
10
+ * - Default value support
11
+ * - Factory function for custom implementations
12
+ */
13
+ /* eslint-disable no-console -- Intentional console output for fallback CLI prompts */
14
+ import * as readline from 'readline';
15
+ import { defineTool, createSuccessResult, createErrorResult } from '../define.js';
16
+ // =============================================================================
17
+ // Default Implementation (readline-based)
18
+ // =============================================================================
19
+ async function askSimpleWithReadline(question, options, defaultValue) {
20
+ const rl = readline.createInterface({
21
+ input: process.stdin,
22
+ output: process.stdout,
23
+ });
24
+ return new Promise((resolve) => {
25
+ // Print question and options
26
+ console.log(`\n${question}`);
27
+ options.forEach((opt, i) => {
28
+ console.log(` ${String(i + 1)}. ${opt}`);
29
+ });
30
+ if (defaultValue) {
31
+ console.log(` (Press Enter for default: ${defaultValue})`);
32
+ }
33
+ rl.question('Choice: ', (answer) => {
34
+ rl.close();
35
+ const trimmed = answer.trim();
36
+ // Empty input - use default or first option
37
+ if (!trimmed) {
38
+ if (defaultValue) {
39
+ resolve({ answer: defaultValue, usedDefault: true });
40
+ }
41
+ else {
42
+ resolve({ answer: options[0], usedDefault: true });
43
+ }
44
+ return;
45
+ }
46
+ // Try to parse as number
47
+ const idx = parseInt(trimmed, 10) - 1;
48
+ if (idx >= 0 && idx < options.length) {
49
+ resolve({ answer: options[idx] });
50
+ return;
51
+ }
52
+ // Try to match option text (case-insensitive)
53
+ const lowerInput = trimmed.toLowerCase();
54
+ const matched = options.find((opt) => opt.toLowerCase() === lowerInput);
55
+ if (matched) {
56
+ resolve({ answer: matched });
57
+ return;
58
+ }
59
+ // No match - use default or first option
60
+ if (defaultValue) {
61
+ resolve({ answer: defaultValue, usedDefault: true });
62
+ }
63
+ else {
64
+ resolve({ answer: options[0], usedDefault: true });
65
+ }
66
+ });
67
+ });
68
+ }
69
+ // =============================================================================
70
+ // Tool Definition
71
+ // =============================================================================
72
+ /**
73
+ * Default ask_user_simple tool using readline for basic CLI interaction.
74
+ * Use createAskUserSimpleTool() for custom implementations.
75
+ */
76
+ export const askUserSimpleTool = defineTool({
77
+ name: 'ask_user_simple',
78
+ description: 'Ask a single simple question with string options. ' +
79
+ 'Use this instead of ask_user when you only need one question. ' +
80
+ 'Provide 2-4 clear, concise options. ' +
81
+ 'The user can select by number or by typing the option text.',
82
+ inputSchema: {
83
+ type: 'object',
84
+ properties: {
85
+ question: {
86
+ type: 'string',
87
+ description: 'The question to ask the user',
88
+ },
89
+ options: {
90
+ type: 'array',
91
+ description: 'Available options (2-4 options)',
92
+ minItems: 2,
93
+ maxItems: 4,
94
+ items: {
95
+ type: 'string',
96
+ },
97
+ },
98
+ default: {
99
+ type: 'string',
100
+ description: 'Default value if user skips',
101
+ },
102
+ },
103
+ required: ['question', 'options'],
104
+ },
105
+ execute: async (input) => {
106
+ try {
107
+ const result = await askSimpleWithReadline(input.question, input.options, input.default);
108
+ return createSuccessResult(result);
109
+ }
110
+ catch (error) {
111
+ return createErrorResult(error instanceof Error ? error.message : String(error));
112
+ }
113
+ },
114
+ });
115
+ // =============================================================================
116
+ // Factory Function
117
+ // =============================================================================
118
+ /**
119
+ * Create a custom ask_user_simple tool with your own UI implementation.
120
+ *
121
+ * @example
122
+ * ```typescript
123
+ * const customAskSimple = createAskUserSimpleTool({
124
+ * onAsk: async (question, options, defaultValue) => {
125
+ * // Show fancy UI overlay
126
+ * const overlay = new AskUserSimpleOverlay({ question, options, defaultValue });
127
+ * return await ui.showOverlay(overlay);
128
+ * }
129
+ * });
130
+ * agent.registerTool(customAskSimple);
131
+ * ```
132
+ */
133
+ export function createAskUserSimpleTool(options = {}) {
134
+ const handler = options.onAsk ?? askSimpleWithReadline;
135
+ return defineTool({
136
+ name: 'ask_user_simple',
137
+ description: askUserSimpleTool.definition.description,
138
+ inputSchema: askUserSimpleTool.definition.inputSchema,
139
+ execute: async (input) => {
140
+ try {
141
+ const result = await handler(input.question, input.options, input.default);
142
+ return createSuccessResult(result);
143
+ }
144
+ catch (error) {
145
+ return createErrorResult(error instanceof Error ? error.message : String(error));
146
+ }
147
+ },
148
+ });
149
+ }
@@ -0,0 +1,85 @@
1
+ /**
2
+ * Ask User Tool - Gather input from user via questions with options
3
+ *
4
+ * This tool allows the agent to ask the user questions with predefined options.
5
+ * The default implementation uses Node.js readline for basic CLI interaction.
6
+ * Consumers (like CLI apps) can override with custom UI implementations.
7
+ *
8
+ * Features:
9
+ * - Multiple questions in a single call
10
+ * - Options with labels, values, and descriptions
11
+ * - Multi-select support
12
+ * - Factory function for custom implementations
13
+ */
14
+ import type { Tool } from '../types.js';
15
+ /**
16
+ * A single option for a question
17
+ */
18
+ export interface AskUserOption {
19
+ /** Display text for the option */
20
+ label: string;
21
+ /** Value returned when this option is selected */
22
+ value: string;
23
+ /** Optional description/explanation */
24
+ description?: string;
25
+ }
26
+ /**
27
+ * A question to ask the user
28
+ */
29
+ export interface AskUserQuestion {
30
+ /** Unique identifier for this question */
31
+ id: string;
32
+ /** The question text */
33
+ question: string;
34
+ /** Available options to choose from */
35
+ options: AskUserOption[];
36
+ /** Allow multiple selections (default: false) */
37
+ multiSelect?: boolean;
38
+ }
39
+ /**
40
+ * Input parameters for ask_user tool
41
+ */
42
+ export interface AskUserInput {
43
+ /** Questions to ask the user (1-4 questions) */
44
+ questions: AskUserQuestion[];
45
+ }
46
+ /**
47
+ * Result from ask_user tool
48
+ */
49
+ export interface AskUserResult {
50
+ /** Answers keyed by question ID */
51
+ answers: Record<string, string | string[]>;
52
+ /** Question IDs that were skipped */
53
+ skipped: string[];
54
+ }
55
+ /**
56
+ * Options for creating custom ask_user tool
57
+ */
58
+ export interface AskUserToolOptions {
59
+ /**
60
+ * Custom handler for asking questions.
61
+ * If not provided, uses readline-based implementation.
62
+ */
63
+ onAsk?: (questions: AskUserQuestion[]) => Promise<AskUserResult>;
64
+ }
65
+ /**
66
+ * Default ask_user tool using readline for basic CLI interaction.
67
+ * Use createAskUserTool() for custom implementations.
68
+ */
69
+ export declare const askUserTool: Tool<AskUserInput>;
70
+ /**
71
+ * Create a custom ask_user tool with your own UI implementation.
72
+ *
73
+ * @example
74
+ * ```typescript
75
+ * const customAskUser = createAskUserTool({
76
+ * onAsk: async (questions) => {
77
+ * // Show fancy UI overlay
78
+ * const overlay = new AskUserOverlay({ questions });
79
+ * return await ui.showOverlay(overlay);
80
+ * }
81
+ * });
82
+ * agent.registerTool(customAskUser);
83
+ * ```
84
+ */
85
+ export declare function createAskUserTool(options?: AskUserToolOptions): Tool<AskUserInput>;
@@ -0,0 +1,195 @@
1
+ /**
2
+ * Ask User Tool - Gather input from user via questions with options
3
+ *
4
+ * This tool allows the agent to ask the user questions with predefined options.
5
+ * The default implementation uses Node.js readline for basic CLI interaction.
6
+ * Consumers (like CLI apps) can override with custom UI implementations.
7
+ *
8
+ * Features:
9
+ * - Multiple questions in a single call
10
+ * - Options with labels, values, and descriptions
11
+ * - Multi-select support
12
+ * - Factory function for custom implementations
13
+ */
14
+ /* eslint-disable no-console -- Intentional console output for fallback CLI prompts */
15
+ import * as readline from 'readline';
16
+ import { defineTool, createSuccessResult, createErrorResult } from '../define.js';
17
+ // =============================================================================
18
+ // Default Implementation (readline-based)
19
+ // =============================================================================
20
+ async function askWithReadline(questions) {
21
+ const rl = readline.createInterface({
22
+ input: process.stdin,
23
+ output: process.stdout,
24
+ });
25
+ const askQuestion = (prompt) => {
26
+ return new Promise((resolve) => {
27
+ rl.question(prompt, (answer) => {
28
+ resolve(answer);
29
+ });
30
+ });
31
+ };
32
+ const answers = {};
33
+ const skipped = [];
34
+ try {
35
+ for (const q of questions) {
36
+ // Print question
37
+ console.log(`\n${q.question}`);
38
+ // Print options
39
+ q.options.forEach((opt, i) => {
40
+ const desc = opt.description ? ` - ${opt.description}` : '';
41
+ console.log(` ${String(i + 1)}. ${opt.label}${desc}`);
42
+ });
43
+ if (q.multiSelect) {
44
+ console.log(' (Enter numbers separated by commas, or press Enter to skip)');
45
+ }
46
+ // Get answer
47
+ const prompt = q.multiSelect ? 'Choices: ' : 'Choice: ';
48
+ const answer = await askQuestion(prompt);
49
+ if (!answer.trim()) {
50
+ skipped.push(q.id);
51
+ continue;
52
+ }
53
+ if (q.multiSelect) {
54
+ // Parse comma-separated numbers
55
+ const indices = answer
56
+ .split(',')
57
+ .map((s) => parseInt(s.trim(), 10) - 1)
58
+ .filter((i) => i >= 0 && i < q.options.length);
59
+ if (indices.length > 0) {
60
+ answers[q.id] = indices.map((i) => q.options[i].value);
61
+ }
62
+ else {
63
+ skipped.push(q.id);
64
+ }
65
+ }
66
+ else {
67
+ // Single selection
68
+ const idx = parseInt(answer.trim(), 10) - 1;
69
+ if (idx >= 0 && idx < q.options.length) {
70
+ answers[q.id] = q.options[idx].value;
71
+ }
72
+ else {
73
+ // Invalid input - try to use as raw value or skip
74
+ skipped.push(q.id);
75
+ }
76
+ }
77
+ }
78
+ }
79
+ finally {
80
+ rl.close();
81
+ }
82
+ return { answers, skipped };
83
+ }
84
+ // =============================================================================
85
+ // Tool Definition
86
+ // =============================================================================
87
+ /**
88
+ * Default ask_user tool using readline for basic CLI interaction.
89
+ * Use createAskUserTool() for custom implementations.
90
+ */
91
+ export const askUserTool = defineTool({
92
+ name: 'ask_user',
93
+ description: 'Ask the user one or more questions with predefined options. ' +
94
+ 'Use this to gather preferences, make decisions, or get user input during workflows. ' +
95
+ 'Each question should have 2-4 clear options. ' +
96
+ 'Prefer ask_user_simple for single simple questions.',
97
+ inputSchema: {
98
+ type: 'object',
99
+ properties: {
100
+ questions: {
101
+ type: 'array',
102
+ description: 'Questions to ask (1-4 questions)',
103
+ minItems: 1,
104
+ maxItems: 4,
105
+ items: {
106
+ type: 'object',
107
+ properties: {
108
+ id: {
109
+ type: 'string',
110
+ description: 'Unique identifier for this question',
111
+ },
112
+ question: {
113
+ type: 'string',
114
+ description: 'The question text to display',
115
+ },
116
+ options: {
117
+ type: 'array',
118
+ description: 'Available options (2-4 options)',
119
+ minItems: 2,
120
+ maxItems: 4,
121
+ items: {
122
+ type: 'object',
123
+ properties: {
124
+ label: {
125
+ type: 'string',
126
+ description: 'Display text for this option',
127
+ },
128
+ value: {
129
+ type: 'string',
130
+ description: 'Value returned when selected',
131
+ },
132
+ description: {
133
+ type: 'string',
134
+ description: 'Optional explanation of this option',
135
+ },
136
+ },
137
+ required: ['label', 'value'],
138
+ },
139
+ },
140
+ multiSelect: {
141
+ type: 'boolean',
142
+ description: 'Allow selecting multiple options',
143
+ },
144
+ },
145
+ required: ['id', 'question', 'options'],
146
+ },
147
+ },
148
+ },
149
+ required: ['questions'],
150
+ },
151
+ execute: async (input) => {
152
+ try {
153
+ const result = await askWithReadline(input.questions);
154
+ return createSuccessResult(result);
155
+ }
156
+ catch (error) {
157
+ return createErrorResult(error instanceof Error ? error.message : String(error));
158
+ }
159
+ },
160
+ });
161
+ // =============================================================================
162
+ // Factory Function
163
+ // =============================================================================
164
+ /**
165
+ * Create a custom ask_user tool with your own UI implementation.
166
+ *
167
+ * @example
168
+ * ```typescript
169
+ * const customAskUser = createAskUserTool({
170
+ * onAsk: async (questions) => {
171
+ * // Show fancy UI overlay
172
+ * const overlay = new AskUserOverlay({ questions });
173
+ * return await ui.showOverlay(overlay);
174
+ * }
175
+ * });
176
+ * agent.registerTool(customAskUser);
177
+ * ```
178
+ */
179
+ export function createAskUserTool(options = {}) {
180
+ const handler = options.onAsk ?? askWithReadline;
181
+ return defineTool({
182
+ name: 'ask_user',
183
+ description: askUserTool.definition.description,
184
+ inputSchema: askUserTool.definition.inputSchema,
185
+ execute: async (input) => {
186
+ try {
187
+ const result = await handler(input.questions);
188
+ return createSuccessResult(result);
189
+ }
190
+ catch (error) {
191
+ return createErrorResult(error instanceof Error ? error.message : String(error));
192
+ }
193
+ },
194
+ });
195
+ }
@@ -0,0 +1,121 @@
1
+ /**
2
+ * Backlog Tools - File-based project backlog management
3
+ *
4
+ * Provides backlog_read and backlog_write tools for managing project backlogs.
5
+ * Uses a JSON file stored in .compilr/backlog.json (or backlog.json in project root).
6
+ *
7
+ * Features:
8
+ * - Read with filters (status, type, search, limit)
9
+ * - Write/update individual items or full backlog
10
+ * - Support for common item types (feature, bug, chore, spike)
11
+ * - Priority levels (critical, high, medium, low)
12
+ */
13
+ import type { Tool } from '../types.js';
14
+ /**
15
+ * Status of a backlog item
16
+ */
17
+ export type BacklogStatus = 'backlog' | 'in-progress' | 'done' | 'blocked';
18
+ /**
19
+ * Type of backlog item
20
+ */
21
+ export type BacklogItemType = 'feature' | 'bug' | 'chore' | 'spike';
22
+ /**
23
+ * Priority level
24
+ */
25
+ export type BacklogPriority = 'critical' | 'high' | 'medium' | 'low';
26
+ /**
27
+ * A backlog item
28
+ */
29
+ export interface BacklogItem {
30
+ /** Unique identifier (e.g., "FEAT-001", "BUG-002") */
31
+ id: string;
32
+ /** Type of item */
33
+ type: BacklogItemType;
34
+ /** Short title */
35
+ title: string;
36
+ /** Detailed description (optional) */
37
+ description?: string;
38
+ /** Current status */
39
+ status: BacklogStatus;
40
+ /** Priority level (optional, defaults to medium) */
41
+ priority?: BacklogPriority;
42
+ /** Acceptance criteria (optional) */
43
+ acceptanceCriteria?: string[];
44
+ /** Dependencies on other items (optional) */
45
+ dependencies?: string[];
46
+ /** Labels/tags (optional) */
47
+ labels?: string[];
48
+ /** Created timestamp */
49
+ createdAt?: string;
50
+ /** Last updated timestamp */
51
+ updatedAt?: string;
52
+ }
53
+ /**
54
+ * Input parameters for backlog_read tool
55
+ */
56
+ export interface BacklogReadInput {
57
+ /** Get a specific item by ID */
58
+ id?: string;
59
+ /** Filter by status */
60
+ status?: BacklogStatus;
61
+ /** Filter by type */
62
+ type?: BacklogItemType;
63
+ /** Search in title and description */
64
+ search?: string;
65
+ /** Filter by priority */
66
+ priority?: BacklogPriority;
67
+ /** Maximum items to return (default: 20) */
68
+ limit?: number;
69
+ }
70
+ /**
71
+ * Result from backlog_read
72
+ */
73
+ export interface BacklogReadResult {
74
+ items: BacklogItem[];
75
+ total: number;
76
+ filtered: number;
77
+ }
78
+ /**
79
+ * Input parameters for backlog_write tool
80
+ */
81
+ export interface BacklogWriteInput {
82
+ /** Action to perform */
83
+ action: 'add' | 'update' | 'delete' | 'replace';
84
+ /** Item to add or update (required for add/update) */
85
+ item?: Partial<BacklogItem>;
86
+ /** Item ID to delete (required for delete) */
87
+ deleteId?: string;
88
+ /** Full list of items (required for replace action) */
89
+ items?: BacklogItem[];
90
+ }
91
+ /**
92
+ * Result from backlog_write
93
+ */
94
+ export interface BacklogWriteResult {
95
+ success: boolean;
96
+ action: string;
97
+ itemId?: string;
98
+ itemCount?: number;
99
+ }
100
+ /**
101
+ * Read backlog items with optional filters
102
+ */
103
+ export declare const backlogReadTool: Tool<BacklogReadInput>;
104
+ /**
105
+ * Write/update backlog items
106
+ */
107
+ export declare const backlogWriteTool: Tool<BacklogWriteInput>;
108
+ /**
109
+ * Options for creating custom backlog tools
110
+ */
111
+ export interface BacklogToolOptions {
112
+ /** Custom base path for backlog file */
113
+ basePath?: string;
114
+ }
115
+ /**
116
+ * Create backlog tools with custom options
117
+ */
118
+ export declare function createBacklogTools(_options?: BacklogToolOptions): {
119
+ backlogRead: Tool<BacklogReadInput>;
120
+ backlogWrite: Tool<BacklogWriteInput>;
121
+ };