@compilr-dev/cli 0.5.1 → 0.5.3
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/LICENSE +108 -0
- package/README.md +2 -2
- 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.js +8 -6
- package/dist/commands-v2/handlers/context.js +20 -0
- package/dist/commands-v2/handlers/core.js +26 -1
- package/dist/commands-v2/handlers/project.js +88 -12
- package/dist/commands-v2/handlers/reset.js +19 -6
- package/dist/commands-v2/handlers/session.d.ts +5 -1
- package/dist/commands-v2/handlers/session.js +54 -16
- package/dist/commands-v2/types.d.ts +5 -0
- package/dist/compilr-diff-companion.vsix +0 -0
- package/dist/db/repositories/document-repository.js +1 -0
- package/dist/db/schema.d.ts +1 -1
- package/dist/index.js +99 -30
- package/dist/models/providers.d.ts +3 -1
- package/dist/models/providers.js +9 -0
- package/dist/repl-helpers.js +2 -0
- package/dist/repl-v2.d.ts +12 -0
- package/dist/repl-v2.js +27 -11
- package/dist/tool-names.d.ts +9 -0
- package/dist/tool-names.js +36 -0
- package/dist/tools/db-tools.d.ts +6 -1
- package/dist/tools/db-tools.js +6 -2
- package/dist/tools/meta-tools.d.ts +1 -1
- package/dist/tools/platform-adapter.d.ts +6 -0
- package/dist/tools/platform-adapter.js +10 -0
- package/dist/tools.d.ts +14 -4
- package/dist/tools.js +60 -20
- package/dist/ui/constants/labels.js +1 -0
- package/dist/ui/overlay/impl/workflow-overlay-v2.d.ts +1 -0
- package/dist/ui/overlay/impl/workflow-overlay-v2.js +5 -3
- package/dist/ui/terminal-ui.d.ts +7 -7
- package/dist/ui/terminal-ui.js +1 -1
- package/dist/ui/tool-formatters.js +190 -6
- package/dist/ui/turn-metrics.d.ts +10 -10
- package/dist/ui/turn-metrics.js +5 -5
- package/dist/ui/types.d.ts +4 -4
- package/package.json +6 -5
- package/dist/tools/anchor-tools.d.ts +0 -31
- package/dist/tools/anchor-tools.js +0 -255
- package/dist/tools/artifact-tools.d.ts +0 -42
- package/dist/tools/artifact-tools.js +0 -328
- package/dist/tools/backlog-wrappers.d.ts +0 -56
- package/dist/tools/backlog-wrappers.js +0 -353
- package/dist/tools/document-db.d.ts +0 -43
- package/dist/tools/document-db.js +0 -220
- package/dist/tools/plan-tools.d.ts +0 -54
- package/dist/tools/plan-tools.js +0 -338
- package/dist/tools/recall-work-tool.d.ts +0 -18
- package/dist/tools/recall-work-tool.js +0 -82
- package/dist/tools/workitem-db.d.ts +0 -135
- package/dist/tools/workitem-db.js +0 -730
package/dist/tool-names.js
CHANGED
|
@@ -112,6 +112,12 @@ export const TOOL_NAMES = {
|
|
|
112
112
|
ARTIFACT_DELETE: 'artifact_delete',
|
|
113
113
|
// Episode tools (meta-registry)
|
|
114
114
|
RECALL_WORK: 'recall_work',
|
|
115
|
+
// Factory tools (meta-registry)
|
|
116
|
+
APP_MODEL_GET: 'app_model_get',
|
|
117
|
+
APP_MODEL_UPDATE: 'app_model_update',
|
|
118
|
+
APP_MODEL_VALIDATE: 'app_model_validate',
|
|
119
|
+
FACTORY_SCAFFOLD: 'factory_scaffold',
|
|
120
|
+
FACTORY_LIST_TOOLKITS: 'factory_list_toolkits',
|
|
115
121
|
};
|
|
116
122
|
/** Array of all direct tool names (always available) */
|
|
117
123
|
export const DIRECT_TOOL_NAMES = [
|
|
@@ -136,6 +142,30 @@ export const DIRECT_TOOL_NAMES = [
|
|
|
136
142
|
TOOL_NAMES.TASK,
|
|
137
143
|
TOOL_NAMES.SUGGEST,
|
|
138
144
|
];
|
|
145
|
+
/** Hot tools — used in >50% of turns, always declared as direct schemas */
|
|
146
|
+
export const HOT_TOOL_NAMES = [
|
|
147
|
+
TOOL_NAMES.READ_FILE,
|
|
148
|
+
TOOL_NAMES.WRITE_FILE,
|
|
149
|
+
TOOL_NAMES.EDIT,
|
|
150
|
+
TOOL_NAMES.BASH,
|
|
151
|
+
TOOL_NAMES.GREP,
|
|
152
|
+
TOOL_NAMES.GLOB,
|
|
153
|
+
TOOL_NAMES.ASK_USER,
|
|
154
|
+
];
|
|
155
|
+
/** Warm tools — used occasionally, moved to meta-registry in hot-tools mode */
|
|
156
|
+
export const WARM_TOOL_NAMES = [
|
|
157
|
+
TOOL_NAMES.BASH_OUTPUT,
|
|
158
|
+
TOOL_NAMES.KILL_SHELL,
|
|
159
|
+
TOOL_NAMES.TODO_WRITE,
|
|
160
|
+
TOOL_NAMES.TODO_READ,
|
|
161
|
+
TOOL_NAMES.TODO_CLAIM,
|
|
162
|
+
TOOL_NAMES.TODO_HANDOFF,
|
|
163
|
+
TOOL_NAMES.ASK_USER_SIMPLE,
|
|
164
|
+
TOOL_NAMES.DELEGATE,
|
|
165
|
+
TOOL_NAMES.DELEGATE_BACKGROUND,
|
|
166
|
+
TOOL_NAMES.HANDOFF,
|
|
167
|
+
TOOL_NAMES.COMPILR_GUIDE,
|
|
168
|
+
];
|
|
139
169
|
/** Array of all meta-tool names (tool discovery) */
|
|
140
170
|
export const META_TOOL_NAMES = [
|
|
141
171
|
TOOL_NAMES.LIST_TOOLS,
|
|
@@ -217,6 +247,12 @@ export const META_REGISTRY_TOOL_NAMES = [
|
|
|
217
247
|
TOOL_NAMES.RECALL_WORK,
|
|
218
248
|
// Delegation
|
|
219
249
|
TOOL_NAMES.DELEGATION_STATUS,
|
|
250
|
+
// Factory
|
|
251
|
+
TOOL_NAMES.APP_MODEL_GET,
|
|
252
|
+
TOOL_NAMES.APP_MODEL_UPDATE,
|
|
253
|
+
TOOL_NAMES.APP_MODEL_VALIDATE,
|
|
254
|
+
TOOL_NAMES.FACTORY_SCAFFOLD,
|
|
255
|
+
TOOL_NAMES.FACTORY_LIST_TOOLKITS,
|
|
220
256
|
];
|
|
221
257
|
/**
|
|
222
258
|
* Get all tool names as an array.
|
package/dist/tools/db-tools.d.ts
CHANGED
|
@@ -5,8 +5,13 @@
|
|
|
5
5
|
* provided by the SDK via platform-adapter.ts. This file re-exports them
|
|
6
6
|
* along with state management functions still needed by ~15+ CLI files.
|
|
7
7
|
*/
|
|
8
|
+
import { allFactoryTools } from './platform-adapter.js';
|
|
8
9
|
export { getActiveProject, setActiveProject } from './project-db.js';
|
|
9
10
|
/**
|
|
10
|
-
* All database tools combined (
|
|
11
|
+
* All database tools combined (32 tools from SDK)
|
|
11
12
|
*/
|
|
12
13
|
export declare const allDbTools: import("@compilr-dev/agents").Tool<never>[];
|
|
14
|
+
/**
|
|
15
|
+
* All factory tools (5 tools from @compilr-dev/factory)
|
|
16
|
+
*/
|
|
17
|
+
export { allFactoryTools };
|
package/dist/tools/db-tools.js
CHANGED
|
@@ -5,10 +5,14 @@
|
|
|
5
5
|
* provided by the SDK via platform-adapter.ts. This file re-exports them
|
|
6
6
|
* along with state management functions still needed by ~15+ CLI files.
|
|
7
7
|
*/
|
|
8
|
-
import { allPlatformTools } from './platform-adapter.js';
|
|
8
|
+
import { allPlatformTools, allFactoryTools } from './platform-adapter.js';
|
|
9
9
|
// Re-export state management functions (still needed by many CLI files)
|
|
10
10
|
export { getActiveProject, setActiveProject } from './project-db.js';
|
|
11
11
|
/**
|
|
12
|
-
* All database tools combined (
|
|
12
|
+
* All database tools combined (32 tools from SDK)
|
|
13
13
|
*/
|
|
14
14
|
export const allDbTools = allPlatformTools;
|
|
15
|
+
/**
|
|
16
|
+
* All factory tools (5 tools from @compilr-dev/factory)
|
|
17
|
+
*/
|
|
18
|
+
export { allFactoryTools };
|
|
@@ -23,4 +23,4 @@ export declare const getToolInfoTool: Tool<object>;
|
|
|
23
23
|
export declare const useToolTool: Tool<object>;
|
|
24
24
|
export declare const metaTools: Tool<object>[];
|
|
25
25
|
export declare function createMetaToolFallback(): (name: string, input: Record<string, unknown>) => Promise<ToolExecutionResult | null>;
|
|
26
|
-
export declare const META_TOOLS_SYSTEM_PROMPT_PREFIX = "\n## Tool Index (Specialized Tools)\n\nThese tools are called **exactly like direct tools** \u2014 just use the tool name with parameters. No special syntax or wrapper needed. The system routes them automatically.\n\n**IMPORTANT \u2014 These are CLI system tools, NOT your project's backend. Never use localhost/curl to access them.**\n\n**Parameter Rules:**\n- For **zero-parameter calls**: call the tool directly (e.g., `workitem_query()`, `git_status()`).\n- For **calls WITH parameters**: you MUST call `get_tool_info(\"tool_name\")` first to get
|
|
26
|
+
export declare const META_TOOLS_SYSTEM_PROMPT_PREFIX = "\n## Tool Index (Specialized Tools)\n\nThese tools are called **exactly like direct tools** \u2014 just use the tool name with parameters. No special syntax or wrapper needed. The system routes them automatically.\n\n**IMPORTANT \u2014 These are CLI system tools, NOT your project's backend. Never use localhost/curl to access them.**\n\n**Parameter Rules:**\n- For **zero-parameter calls**: call the tool directly (e.g., `workitem_query()`, `git_status()`).\n- For **calls WITH parameters**: you MUST call `get_tool_info(\"tool_name\")` first to get parameter details. The signatures below are summaries only \u2014 do NOT guess parameter structure from them.\n- After a failed tool call, always call `get_tool_info()` before retrying.\n\n";
|
|
@@ -27,3 +27,9 @@
|
|
|
27
27
|
* - 1 episode tool (recall_work)
|
|
28
28
|
*/
|
|
29
29
|
export declare const allPlatformTools: import("@compilr-dev/sdk").Tool<never>[];
|
|
30
|
+
/**
|
|
31
|
+
* All 5 factory tools from @compilr-dev/factory:
|
|
32
|
+
* - 3 model tools (app_model_get, app_model_update, app_model_validate)
|
|
33
|
+
* - 2 factory tools (factory_scaffold, factory_list_toolkits)
|
|
34
|
+
*/
|
|
35
|
+
export declare const allFactoryTools: import("@compilr-dev/sdk").Tool<never>[];
|
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
* - recall-work-tool.ts (1 tool)
|
|
17
17
|
*/
|
|
18
18
|
import { createPlatformTools, } from '@compilr-dev/sdk';
|
|
19
|
+
import { createFactoryTools } from '@compilr-dev/factory';
|
|
19
20
|
import { projectRepository, workItemRepository, documentRepository, planRepository, } from '../db/repositories/index.js';
|
|
20
21
|
import { getCurrentProject, setCurrentProject } from './project-db.js';
|
|
21
22
|
import { awardFirstProject, awardWorkItemCompletion } from '../games/coins.js';
|
|
@@ -392,3 +393,12 @@ const config = {
|
|
|
392
393
|
* - 1 episode tool (recall_work)
|
|
393
394
|
*/
|
|
394
395
|
export const allPlatformTools = createPlatformTools(config);
|
|
396
|
+
/**
|
|
397
|
+
* All 5 factory tools from @compilr-dev/factory:
|
|
398
|
+
* - 3 model tools (app_model_get, app_model_update, app_model_validate)
|
|
399
|
+
* - 2 factory tools (factory_scaffold, factory_list_toolkits)
|
|
400
|
+
*/
|
|
401
|
+
export const allFactoryTools = createFactoryTools({
|
|
402
|
+
context,
|
|
403
|
+
cwd: process.cwd(),
|
|
404
|
+
});
|
package/dist/tools.d.ts
CHANGED
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
* Tool names are defined in tool-names.ts (a dependency-free module).
|
|
15
15
|
* This file re-exports them for convenience. Import from here or tool-names.ts.
|
|
16
16
|
*/
|
|
17
|
-
export { TOOL_NAMES, type ToolName, DIRECT_TOOL_NAMES, META_TOOL_NAMES, META_REGISTRY_TOOL_NAMES, getAllToolNames, } from './tool-names.js';
|
|
17
|
+
export { TOOL_NAMES, type ToolName, DIRECT_TOOL_NAMES, HOT_TOOL_NAMES, WARM_TOOL_NAMES, META_TOOL_NAMES, META_REGISTRY_TOOL_NAMES, getAllToolNames, } from './tool-names.js';
|
|
18
18
|
import { TodoStore, type Tool } from '@compilr-dev/sdk';
|
|
19
19
|
export declare const todoStore: TodoStore;
|
|
20
20
|
import { setMetaToolFilter, getRegisteredMetaTools } from './tools/meta-tools.js';
|
|
@@ -32,9 +32,10 @@ export declare function createToolRegistry(): unknown[];
|
|
|
32
32
|
export declare function createMinimalToolRegistry(): unknown[];
|
|
33
33
|
/**
|
|
34
34
|
* Get direct tools that are always available.
|
|
35
|
-
*
|
|
35
|
+
* When hotOnly is true, returns only hot tools (7 tools, ~2.1K tokens).
|
|
36
|
+
* When false/undefined, returns all direct tools (18 tools, ~5.4K tokens).
|
|
36
37
|
*/
|
|
37
|
-
export declare function getDirectTools(): Tool[];
|
|
38
|
+
export declare function getDirectTools(hotOnly?: boolean): Tool[];
|
|
38
39
|
/**
|
|
39
40
|
* Get meta-tools for agent registration.
|
|
40
41
|
* Only get_tool_info is kept as a direct tool — use_tool and list_tools
|
|
@@ -47,11 +48,18 @@ export declare function getMetaTools(): Tool[];
|
|
|
47
48
|
* checks the meta-registry and executes it transparently.
|
|
48
49
|
*/
|
|
49
50
|
export declare function createToolFallback(): (name: string, input: Record<string, unknown>) => Promise<import('@compilr-dev/sdk').ToolExecutionResult | null>;
|
|
51
|
+
/**
|
|
52
|
+
* Check if hot-tools mode is active.
|
|
53
|
+
* When true, only hot tools are declared as direct schemas; warm tools are in meta-registry.
|
|
54
|
+
*/
|
|
55
|
+
export declare function isHotToolsMode(): boolean;
|
|
50
56
|
/**
|
|
51
57
|
* Initialize the meta-tool registry with specialized tools.
|
|
58
|
+
* When includeWarmTools is true, warm tools are also added to the meta-registry
|
|
59
|
+
* (enabling hot-tools mode where only 7 core tools are declared directly).
|
|
52
60
|
* Call this once at startup.
|
|
53
61
|
*/
|
|
54
|
-
export declare function initializeMetaTools(): void;
|
|
62
|
+
export declare function initializeMetaTools(includeWarmTools?: boolean): void;
|
|
55
63
|
/**
|
|
56
64
|
* Get the tool index for the system prompt.
|
|
57
65
|
* This lists all meta-registry tools with their signatures.
|
|
@@ -71,6 +79,8 @@ export declare function isMetaToolsEnabled(): boolean;
|
|
|
71
79
|
*/
|
|
72
80
|
export declare function getToolStats(): {
|
|
73
81
|
directTools: number;
|
|
82
|
+
hotTools: number;
|
|
83
|
+
warmTools: number;
|
|
74
84
|
metaRegistryTools: number;
|
|
75
85
|
totalTools: number;
|
|
76
86
|
estimatedDirectTokens: number;
|
package/dist/tools.js
CHANGED
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
*/
|
|
17
17
|
// Re-export tool names from the dependency-free module
|
|
18
18
|
// This breaks circular dependencies while maintaining a single source of truth
|
|
19
|
-
export { TOOL_NAMES, DIRECT_TOOL_NAMES, META_TOOL_NAMES, META_REGISTRY_TOOL_NAMES, getAllToolNames, } from './tool-names.js';
|
|
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
20
|
// =============================================================================
|
|
21
21
|
// TOOL IMPORTS
|
|
22
22
|
// =============================================================================
|
|
@@ -127,7 +127,7 @@ import { delegationStatusTool } from './tools/delegation-status.js';
|
|
|
127
127
|
import { handoffTool } from './tools/handoff.js';
|
|
128
128
|
import { guideTool } from './tools/guide-tool.js';
|
|
129
129
|
// DB tools for project, work item, document, plan, backlog, anchor, artifact, and episode management
|
|
130
|
-
import { allDbTools } from './tools/db-tools.js';
|
|
130
|
+
import { allDbTools, allFactoryTools } from './tools/db-tools.js';
|
|
131
131
|
// Meta-tools for dynamic tool loading
|
|
132
132
|
import { initializeMetaToolRegistry, generateToolIndex, getMetaToolCount, META_TOOLS_SYSTEM_PROMPT_PREFIX, setMetaToolFilter, getRegisteredMetaTools, createMetaToolFallback, getToolInfoTool, } from './tools/meta-tools.js';
|
|
133
133
|
// Re-export for use in agent.ts
|
|
@@ -136,29 +136,36 @@ export { setMetaToolFilter, getRegisteredMetaTools };
|
|
|
136
136
|
// DIRECT TOOLS - Always available, called by name
|
|
137
137
|
// =============================================================================
|
|
138
138
|
/**
|
|
139
|
-
*
|
|
140
|
-
*
|
|
141
|
-
* Estimated: ~3,500 tokens for definitions
|
|
139
|
+
* Hot tools — used in >50% of turns. Always declared as direct schemas.
|
|
140
|
+
* Estimated: ~2,100 tokens for definitions
|
|
142
141
|
*/
|
|
143
|
-
const
|
|
142
|
+
const HOT_TOOLS = [
|
|
144
143
|
// File operations (most common)
|
|
145
144
|
readFileTool,
|
|
146
145
|
writeFileTool,
|
|
147
146
|
editTool,
|
|
148
147
|
// Shell (very common)
|
|
149
148
|
bashTool,
|
|
150
|
-
bashOutputTool,
|
|
151
|
-
killShellTool,
|
|
152
149
|
// Search (very common)
|
|
153
150
|
globTool,
|
|
154
151
|
grepTool,
|
|
155
|
-
//
|
|
152
|
+
// User interaction (always needed)
|
|
153
|
+
askUserTool,
|
|
154
|
+
];
|
|
155
|
+
/**
|
|
156
|
+
* Warm tools — used occasionally. In hot-tools mode these move to meta-registry.
|
|
157
|
+
* Estimated: ~3,300 tokens for definitions
|
|
158
|
+
*/
|
|
159
|
+
const WARM_TOOLS = [
|
|
160
|
+
// Shell management
|
|
161
|
+
bashOutputTool,
|
|
162
|
+
killShellTool,
|
|
163
|
+
// Task tracking
|
|
156
164
|
todoWriteTool,
|
|
157
165
|
todoReadTool,
|
|
158
166
|
todoClaimTool,
|
|
159
167
|
todoHandoffTool,
|
|
160
|
-
// User interaction (
|
|
161
|
-
askUserTool,
|
|
168
|
+
// User interaction (simple variant)
|
|
162
169
|
askUserSimpleTool,
|
|
163
170
|
// Delegation (coordinator only)
|
|
164
171
|
delegateTool,
|
|
@@ -166,9 +173,14 @@ const DIRECT_TOOLS = [
|
|
|
166
173
|
delegateBackgroundTool,
|
|
167
174
|
// Handoff (specialist-to-specialist)
|
|
168
175
|
handoffTool,
|
|
169
|
-
// CLI documentation
|
|
176
|
+
// CLI documentation
|
|
170
177
|
guideTool,
|
|
171
178
|
];
|
|
179
|
+
/**
|
|
180
|
+
* All direct tools combined (hot + warm).
|
|
181
|
+
* Used in legacy mode (no meta-tools) and for backwards compatibility.
|
|
182
|
+
*/
|
|
183
|
+
const DIRECT_TOOLS = [...HOT_TOOLS, ...WARM_TOOLS];
|
|
172
184
|
// =============================================================================
|
|
173
185
|
// META-REGISTRY TOOLS - Available via use_tool()
|
|
174
186
|
// =============================================================================
|
|
@@ -212,6 +224,8 @@ const META_REGISTRY_TOOLS = [
|
|
|
212
224
|
getComplexityTool,
|
|
213
225
|
// DB tools (project, workitem, document, plan, backlog, anchor, artifact, episode)
|
|
214
226
|
...allDbTools,
|
|
227
|
+
// Factory tools (app_model_get, app_model_update, app_model_validate, factory_scaffold, factory_list_toolkits)
|
|
228
|
+
...allFactoryTools,
|
|
215
229
|
// Delegation status (coordinator query)
|
|
216
230
|
delegationStatusTool,
|
|
217
231
|
];
|
|
@@ -246,9 +260,12 @@ export function createMinimalToolRegistry() {
|
|
|
246
260
|
// =============================================================================
|
|
247
261
|
/**
|
|
248
262
|
* Get direct tools that are always available.
|
|
249
|
-
*
|
|
263
|
+
* When hotOnly is true, returns only hot tools (7 tools, ~2.1K tokens).
|
|
264
|
+
* When false/undefined, returns all direct tools (18 tools, ~5.4K tokens).
|
|
250
265
|
*/
|
|
251
|
-
export function getDirectTools() {
|
|
266
|
+
export function getDirectTools(hotOnly) {
|
|
267
|
+
if (hotOnly)
|
|
268
|
+
return HOT_TOOLS;
|
|
252
269
|
return DIRECT_TOOLS;
|
|
253
270
|
}
|
|
254
271
|
/**
|
|
@@ -267,12 +284,29 @@ export function getMetaTools() {
|
|
|
267
284
|
export function createToolFallback() {
|
|
268
285
|
return createMetaToolFallback();
|
|
269
286
|
}
|
|
287
|
+
/** Whether hot-tools mode is active (warm tools in meta-registry) */
|
|
288
|
+
let hotToolsModeActive = false;
|
|
289
|
+
/**
|
|
290
|
+
* Check if hot-tools mode is active.
|
|
291
|
+
* When true, only hot tools are declared as direct schemas; warm tools are in meta-registry.
|
|
292
|
+
*/
|
|
293
|
+
export function isHotToolsMode() {
|
|
294
|
+
return hotToolsModeActive;
|
|
295
|
+
}
|
|
270
296
|
/**
|
|
271
297
|
* Initialize the meta-tool registry with specialized tools.
|
|
298
|
+
* When includeWarmTools is true, warm tools are also added to the meta-registry
|
|
299
|
+
* (enabling hot-tools mode where only 7 core tools are declared directly).
|
|
272
300
|
* Call this once at startup.
|
|
273
301
|
*/
|
|
274
|
-
export function initializeMetaTools() {
|
|
275
|
-
|
|
302
|
+
export function initializeMetaTools(includeWarmTools) {
|
|
303
|
+
const tools = includeWarmTools
|
|
304
|
+
? [...WARM_TOOLS, ...META_REGISTRY_TOOLS]
|
|
305
|
+
: META_REGISTRY_TOOLS;
|
|
306
|
+
initializeMetaToolRegistry(tools);
|
|
307
|
+
if (includeWarmTools) {
|
|
308
|
+
hotToolsModeActive = true;
|
|
309
|
+
}
|
|
276
310
|
}
|
|
277
311
|
/**
|
|
278
312
|
* Get the tool index for the system prompt.
|
|
@@ -301,16 +335,22 @@ export function isMetaToolsEnabled() {
|
|
|
301
335
|
* Get tool statistics for debugging/display.
|
|
302
336
|
*/
|
|
303
337
|
export function getToolStats() {
|
|
304
|
-
const
|
|
305
|
-
const
|
|
306
|
-
const
|
|
338
|
+
const hotCount = HOT_TOOLS.length;
|
|
339
|
+
const warmCount = WARM_TOOLS.length;
|
|
340
|
+
const directCount = hotToolsModeActive ? hotCount : hotCount + warmCount;
|
|
341
|
+
const metaCount = hotToolsModeActive
|
|
342
|
+
? META_REGISTRY_TOOLS.length + warmCount
|
|
343
|
+
: META_REGISTRY_TOOLS.length;
|
|
344
|
+
const totalCount = hotCount + warmCount + META_REGISTRY_TOOLS.length;
|
|
307
345
|
// Rough estimates: ~300 tokens per tool definition
|
|
308
346
|
const tokensPerTool = 300;
|
|
309
347
|
const estimatedDirectTokens = directCount * tokensPerTool;
|
|
310
|
-
const estimatedMetaTokens =
|
|
348
|
+
const estimatedMetaTokens = 1000; // Tool index + meta-tool definitions
|
|
311
349
|
const estimatedLegacyTokens = totalCount * tokensPerTool;
|
|
312
350
|
return {
|
|
313
351
|
directTools: directCount,
|
|
352
|
+
hotTools: hotCount,
|
|
353
|
+
warmTools: warmCount,
|
|
314
354
|
metaRegistryTools: metaCount,
|
|
315
355
|
totalTools: totalCount,
|
|
316
356
|
estimatedDirectTokens,
|
|
@@ -53,7 +53,7 @@ const PHASES = [
|
|
|
53
53
|
id: 'scaffold',
|
|
54
54
|
name: 'Scaffold',
|
|
55
55
|
command: '/scaffold',
|
|
56
|
-
description: 'Create project foundation',
|
|
56
|
+
description: 'Create project foundation (auto-generates if model available)',
|
|
57
57
|
isComplete: (_project, stats) => stats.hasScaffold,
|
|
58
58
|
isActive: (_project, stats) => stats.totalItems >= 3 && !stats.hasScaffold,
|
|
59
59
|
},
|
|
@@ -82,6 +82,7 @@ function getProjectStats(project) {
|
|
|
82
82
|
const docs = documentRepository.listByProject(project.id);
|
|
83
83
|
const hasPrd = docs.some(d => d.docType === 'prd');
|
|
84
84
|
const hasArchDocs = docs.some(d => d.docType === 'architecture');
|
|
85
|
+
const hasModel = docs.some(d => d.docType === 'app-model');
|
|
85
86
|
const hasScaffold = items.some(i => i.title.toLowerCase().includes('scaffold') && i.status === 'completed') || project.metadata?.scaffolded === true;
|
|
86
87
|
return {
|
|
87
88
|
totalItems: items.length,
|
|
@@ -90,6 +91,7 @@ function getProjectStats(project) {
|
|
|
90
91
|
hasPrd,
|
|
91
92
|
hasArchDocs,
|
|
92
93
|
hasScaffold,
|
|
94
|
+
hasModel,
|
|
93
95
|
};
|
|
94
96
|
}
|
|
95
97
|
function buildActionsItems(project, stats) {
|
|
@@ -130,9 +132,9 @@ function buildActionsItems(project, stats) {
|
|
|
130
132
|
}
|
|
131
133
|
if (stats.totalItems > 0 && !stats.hasScaffold) {
|
|
132
134
|
actions.push({
|
|
133
|
-
label: 'Scaffold Project',
|
|
135
|
+
label: stats.hasModel ? 'Generate from Model' : 'Scaffold Project',
|
|
134
136
|
command: '/scaffold',
|
|
135
|
-
description: 'Create project foundation',
|
|
137
|
+
description: stats.hasModel ? 'Auto-generate from Application Model' : 'Create project foundation',
|
|
136
138
|
enabled: true,
|
|
137
139
|
});
|
|
138
140
|
}
|
package/dist/ui/terminal-ui.d.ts
CHANGED
|
@@ -103,12 +103,12 @@ export declare class TerminalUI extends EventEmitter {
|
|
|
103
103
|
* Add input/output tokens for live display
|
|
104
104
|
* @param thinkingTokens - Optional thinking tokens (Gemini 2.5+ models)
|
|
105
105
|
* @param cacheReadTokens - Optional cache read tokens (Anthropic/Gemini)
|
|
106
|
-
* @param debugPayload - Optional debug payload sizes (
|
|
106
|
+
* @param debugPayload - Optional debug payload sizes (token estimates)
|
|
107
107
|
*/
|
|
108
108
|
addTokens(inputTokens: number, outputTokens: number, thinkingTokens?: number, cacheReadTokens?: number, debugPayload?: {
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
109
|
+
systemTokens: number;
|
|
110
|
+
contentsTokens: number;
|
|
111
|
+
toolsTokens: number;
|
|
112
112
|
}): void;
|
|
113
113
|
/**
|
|
114
114
|
* Increment tool call counter
|
|
@@ -134,9 +134,9 @@ export declare class TerminalUI extends EventEmitter {
|
|
|
134
134
|
toolCalls: number;
|
|
135
135
|
apiCalls: number;
|
|
136
136
|
debugPayload?: {
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
137
|
+
systemTokens: number;
|
|
138
|
+
contentsTokens: number;
|
|
139
|
+
toolsTokens: number;
|
|
140
140
|
};
|
|
141
141
|
};
|
|
142
142
|
setMode(mode: AgentMode): void;
|
package/dist/ui/terminal-ui.js
CHANGED
|
@@ -339,7 +339,7 @@ export class TerminalUI extends EventEmitter {
|
|
|
339
339
|
* Add input/output tokens for live display
|
|
340
340
|
* @param thinkingTokens - Optional thinking tokens (Gemini 2.5+ models)
|
|
341
341
|
* @param cacheReadTokens - Optional cache read tokens (Anthropic/Gemini)
|
|
342
|
-
* @param debugPayload - Optional debug payload sizes (
|
|
342
|
+
* @param debugPayload - Optional debug payload sizes (token estimates)
|
|
343
343
|
*/
|
|
344
344
|
addTokens(inputTokens, outputTokens, thinkingTokens, cacheReadTokens, debugPayload) {
|
|
345
345
|
this.turnMetrics.addTokens(inputTokens, outputTokens, thinkingTokens, cacheReadTokens, debugPayload);
|
|
@@ -130,6 +130,21 @@ export function formatToolResult(toolName, result) {
|
|
|
130
130
|
else if (toolLower.startsWith('artifact_')) {
|
|
131
131
|
({ content, summary } = formatArtifact(toolLower, innerResult));
|
|
132
132
|
}
|
|
133
|
+
else if (toolLower === 'app_model_get') {
|
|
134
|
+
({ content, summary } = formatAppModelGet(innerResult));
|
|
135
|
+
}
|
|
136
|
+
else if (toolLower === 'app_model_update') {
|
|
137
|
+
({ content, summary } = formatAppModelUpdate(innerResult));
|
|
138
|
+
}
|
|
139
|
+
else if (toolLower === 'app_model_validate') {
|
|
140
|
+
({ content, summary } = formatAppModelValidate(innerResult));
|
|
141
|
+
}
|
|
142
|
+
else if (toolLower === 'factory_scaffold') {
|
|
143
|
+
({ content, summary } = formatFactoryScaffold(innerResult));
|
|
144
|
+
}
|
|
145
|
+
else if (toolLower === 'factory_list_toolkits') {
|
|
146
|
+
({ content, summary } = formatFactoryListToolkits(innerResult));
|
|
147
|
+
}
|
|
133
148
|
else if (toolLower === 'list_tools') {
|
|
134
149
|
({ content, summary } = formatListTools(innerResult));
|
|
135
150
|
}
|
|
@@ -973,14 +988,22 @@ function formatListTools(result) {
|
|
|
973
988
|
return { content: '', summary: count ? `${String(count)} tools available` : 'No tools' };
|
|
974
989
|
}
|
|
975
990
|
function formatGetToolInfo(result) {
|
|
991
|
+
// Compact schema format (SDK 0.1.15+): result is a string like "tool_name(...)\n description"
|
|
992
|
+
if (typeof result === 'string') {
|
|
993
|
+
// Extract tool name from signature line: "tool_name(params...)"
|
|
994
|
+
const parenIdx = result.indexOf('(');
|
|
995
|
+
const toolName = parenIdx > 0 ? result.slice(0, parenIdx) : null;
|
|
996
|
+
if (toolName) {
|
|
997
|
+
return { content: '', summary: `Schema: ${toolName}` };
|
|
998
|
+
}
|
|
999
|
+
return { content: '', summary: result.split('\n')[0].slice(0, 80) };
|
|
1000
|
+
}
|
|
1001
|
+
// Legacy object format: { name, description, parameters }
|
|
976
1002
|
const name = result.name;
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
// First sentence of description
|
|
980
|
-
const firstSentence = description.split('.')[0].slice(0, 60);
|
|
981
|
-
return { content: '', summary: `${name}: ${firstSentence}` };
|
|
1003
|
+
if (name) {
|
|
1004
|
+
return { content: '', summary: `Schema: ${name}` };
|
|
982
1005
|
}
|
|
983
|
-
return { content: '', summary:
|
|
1006
|
+
return { content: '', summary: 'Tool info' };
|
|
984
1007
|
}
|
|
985
1008
|
function formatDelegateBackground(result) {
|
|
986
1009
|
const delegated = result.delegated;
|
|
@@ -1002,6 +1025,167 @@ function formatDelegate(result) {
|
|
|
1002
1025
|
const message = result.message;
|
|
1003
1026
|
return { content: '', summary: message || 'Delegated' };
|
|
1004
1027
|
}
|
|
1028
|
+
// =============================================================================
|
|
1029
|
+
// Factory Tool Formatters
|
|
1030
|
+
// =============================================================================
|
|
1031
|
+
/**
|
|
1032
|
+
* Unwrap the use_tool envelope to get the actual tool result.
|
|
1033
|
+
* use_tool wraps as: { tool, status, message, result: { success, result: actualData } }
|
|
1034
|
+
*/
|
|
1035
|
+
function unwrapToolResult(result) {
|
|
1036
|
+
const inner = result.result;
|
|
1037
|
+
if (inner && typeof inner === 'object' && !Array.isArray(inner)) {
|
|
1038
|
+
const innerObj = inner;
|
|
1039
|
+
// If wrapped by use_tool, the actual data is in innerObj.result
|
|
1040
|
+
if (innerObj.result && typeof innerObj.result === 'object' && !Array.isArray(innerObj.result)) {
|
|
1041
|
+
return innerObj.result;
|
|
1042
|
+
}
|
|
1043
|
+
return innerObj;
|
|
1044
|
+
}
|
|
1045
|
+
return result;
|
|
1046
|
+
}
|
|
1047
|
+
function formatAppModelGet(result) {
|
|
1048
|
+
const data = unwrapToolResult(result);
|
|
1049
|
+
// No model exists
|
|
1050
|
+
if (data.exists === false) {
|
|
1051
|
+
const message = data.message;
|
|
1052
|
+
return { content: '', summary: message || 'No Application Model found' };
|
|
1053
|
+
}
|
|
1054
|
+
// Summary scope
|
|
1055
|
+
if (data.entityCount !== undefined) {
|
|
1056
|
+
const name = data.name || '?';
|
|
1057
|
+
const entityCount = data.entityCount;
|
|
1058
|
+
const toolkit = data.toolkit || '?';
|
|
1059
|
+
const revision = data.revision;
|
|
1060
|
+
const entities = data.entities;
|
|
1061
|
+
const summary = `${name} — ${String(entityCount)} entities, toolkit: ${toolkit}${revision !== undefined ? `, rev ${String(revision)}` : ''}`;
|
|
1062
|
+
const lines = [];
|
|
1063
|
+
if (entities?.length) {
|
|
1064
|
+
for (const e of entities) {
|
|
1065
|
+
const rels = e.relationshipCount > 0 ? `, ${String(e.relationshipCount)} rel` : '';
|
|
1066
|
+
lines.push(` ${e.name} (${String(e.fieldCount)} fields, ${e.views.join('/')})${rels}`);
|
|
1067
|
+
}
|
|
1068
|
+
}
|
|
1069
|
+
const features = data.features;
|
|
1070
|
+
if (features) {
|
|
1071
|
+
const enabled = Object.entries(features).filter(([, v]) => v).map(([k]) => k);
|
|
1072
|
+
if (enabled.length)
|
|
1073
|
+
lines.push(`Features: ${enabled.join(', ')}`);
|
|
1074
|
+
}
|
|
1075
|
+
return { content: lines.join('\n'), summary };
|
|
1076
|
+
}
|
|
1077
|
+
// Single entity scope
|
|
1078
|
+
if (data.entity && typeof data.entity === 'object') {
|
|
1079
|
+
const entity = data.entity;
|
|
1080
|
+
const name = entity.name || '?';
|
|
1081
|
+
const fields = entity.fields;
|
|
1082
|
+
const rels = entity.relationships;
|
|
1083
|
+
const summary = `Entity: ${name} (${String(fields?.length ?? 0)} fields)`;
|
|
1084
|
+
const lines = [];
|
|
1085
|
+
if (fields?.length) {
|
|
1086
|
+
lines.push('Fields:');
|
|
1087
|
+
for (const f of fields)
|
|
1088
|
+
lines.push(` ${f.name}: ${f.type}`);
|
|
1089
|
+
}
|
|
1090
|
+
if (rels?.length) {
|
|
1091
|
+
lines.push('Relationships:');
|
|
1092
|
+
for (const r of rels)
|
|
1093
|
+
lines.push(` ${r.type} → ${r.target}`);
|
|
1094
|
+
}
|
|
1095
|
+
return { content: lines.join('\n'), summary };
|
|
1096
|
+
}
|
|
1097
|
+
// Section scopes (identity, features, layout, theme, techStack)
|
|
1098
|
+
const section = data.identity ?? data.features ?? data.layout ?? data.theme ?? data.techStack;
|
|
1099
|
+
if (section && typeof section === 'object') {
|
|
1100
|
+
const entries = Object.entries(section);
|
|
1101
|
+
const summary = entries.map(([k, v]) => `${k}: ${String(v)}`).join(', ');
|
|
1102
|
+
return { content: '', summary: truncate(summary, 80) };
|
|
1103
|
+
}
|
|
1104
|
+
// Full model fallback
|
|
1105
|
+
const message = data.message;
|
|
1106
|
+
return { content: '', summary: message || 'Application Model' };
|
|
1107
|
+
}
|
|
1108
|
+
function formatAppModelUpdate(result) {
|
|
1109
|
+
const data = unwrapToolResult(result);
|
|
1110
|
+
const op = data.op || '';
|
|
1111
|
+
const revision = data.revision;
|
|
1112
|
+
const message = data.message;
|
|
1113
|
+
const revInfo = revision !== undefined ? ` (rev ${String(revision)})` : '';
|
|
1114
|
+
const summary = message || `${op} applied${revInfo}`;
|
|
1115
|
+
return { content: '', summary: truncate(summary, 80) };
|
|
1116
|
+
}
|
|
1117
|
+
function formatAppModelValidate(result) {
|
|
1118
|
+
const data = unwrapToolResult(result);
|
|
1119
|
+
const valid = data.valid;
|
|
1120
|
+
const errors = data.errors;
|
|
1121
|
+
const revision = data.revision;
|
|
1122
|
+
if (valid) {
|
|
1123
|
+
return { content: '', summary: `Model valid${revision !== undefined ? ` (rev ${String(revision)})` : ''}` };
|
|
1124
|
+
}
|
|
1125
|
+
const errorCount = errors?.length ?? 0;
|
|
1126
|
+
const summary = `${String(errorCount)} validation error(s)`;
|
|
1127
|
+
const lines = errors?.slice(0, 10).map((e) => `${e.path || '?'}: ${e.message || 'error'}`) ?? [];
|
|
1128
|
+
if (errorCount > 10)
|
|
1129
|
+
lines.push(`... and ${String(errorCount - 10)} more`);
|
|
1130
|
+
return { content: lines.join('\n'), summary };
|
|
1131
|
+
}
|
|
1132
|
+
function formatFactoryScaffold(result) {
|
|
1133
|
+
const data = unwrapToolResult(result);
|
|
1134
|
+
const toolkit = data.toolkit || '?';
|
|
1135
|
+
const fileCount = data.fileCount;
|
|
1136
|
+
const files = data.files;
|
|
1137
|
+
const dryRun = data.dryRun;
|
|
1138
|
+
const warnings = data.warnings;
|
|
1139
|
+
const message = data.message;
|
|
1140
|
+
const mode = dryRun ? 'Dry run' : 'Generated';
|
|
1141
|
+
const summary = message || `${mode}: ${String(fileCount ?? 0)} files (${toolkit})`;
|
|
1142
|
+
// Build detailed content with file listing
|
|
1143
|
+
const lines = [];
|
|
1144
|
+
if (files?.length) {
|
|
1145
|
+
// Group files by directory
|
|
1146
|
+
const dirs = new Map();
|
|
1147
|
+
for (const f of files) {
|
|
1148
|
+
const parts = f.split('/');
|
|
1149
|
+
const dir = parts.length > 1 ? parts.slice(0, -1).join('/') : '.';
|
|
1150
|
+
const file = parts[parts.length - 1];
|
|
1151
|
+
const existing = dirs.get(dir);
|
|
1152
|
+
if (existing) {
|
|
1153
|
+
existing.push(file);
|
|
1154
|
+
}
|
|
1155
|
+
else {
|
|
1156
|
+
dirs.set(dir, [file]);
|
|
1157
|
+
}
|
|
1158
|
+
}
|
|
1159
|
+
for (const [dir, dirFiles] of dirs) {
|
|
1160
|
+
lines.push(`${dir}/`);
|
|
1161
|
+
for (const f of dirFiles)
|
|
1162
|
+
lines.push(` ${f}`);
|
|
1163
|
+
}
|
|
1164
|
+
}
|
|
1165
|
+
if (warnings?.length) {
|
|
1166
|
+
lines.push('');
|
|
1167
|
+
lines.push('Warnings:');
|
|
1168
|
+
for (const w of warnings)
|
|
1169
|
+
lines.push(` ! ${w}`);
|
|
1170
|
+
}
|
|
1171
|
+
return { content: lines.join('\n'), summary };
|
|
1172
|
+
}
|
|
1173
|
+
function formatFactoryListToolkits(result) {
|
|
1174
|
+
const data = unwrapToolResult(result);
|
|
1175
|
+
const count = data.count;
|
|
1176
|
+
const toolkits = data.toolkits;
|
|
1177
|
+
if (!toolkits?.length) {
|
|
1178
|
+
return { content: '', summary: 'No toolkits available' };
|
|
1179
|
+
}
|
|
1180
|
+
const summary = `${String(count ?? toolkits.length)} toolkit(s)`;
|
|
1181
|
+
const lines = toolkits.map((t) => {
|
|
1182
|
+
const name = t.name || t.id || '?';
|
|
1183
|
+
const desc = t.description ? ` — ${t.description}` : '';
|
|
1184
|
+
const sections = t.requiredSections?.length ? `\n Requires: ${t.requiredSections.join(', ')}` : '';
|
|
1185
|
+
return `${name}${desc}${sections}`;
|
|
1186
|
+
});
|
|
1187
|
+
return { content: lines.join('\n'), summary };
|
|
1188
|
+
}
|
|
1005
1189
|
function formatGeneric(result) {
|
|
1006
1190
|
const content = typeof result.content === 'string'
|
|
1007
1191
|
? result.content
|