@compilr-dev/cli 0.4.0 → 0.5.0
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/README.md +30 -12
- package/dist/agent.d.ts +74 -1
- package/dist/agent.js +259 -76
- package/dist/anchors/index.d.ts +9 -0
- package/dist/anchors/index.js +9 -0
- package/dist/anchors/project-anchors.d.ts +79 -0
- package/dist/anchors/project-anchors.js +202 -0
- package/dist/commands/handler-types.d.ts +68 -0
- package/dist/commands/handler-types.js +8 -0
- package/dist/commands/handlers/agent-commands.d.ts +13 -0
- package/dist/commands/handlers/agent-commands.js +305 -0
- package/dist/commands/handlers/design-commands.d.ts +15 -0
- package/dist/commands/handlers/design-commands.js +334 -0
- package/dist/commands/handlers/index.d.ts +20 -0
- package/dist/commands/handlers/index.js +43 -0
- package/dist/commands/handlers/overlay-commands.d.ts +21 -0
- package/dist/commands/handlers/overlay-commands.js +287 -0
- package/dist/commands/handlers/project-commands.d.ts +11 -0
- package/dist/commands/handlers/project-commands.js +167 -0
- package/dist/commands/handlers/simple-commands.d.ts +19 -0
- package/dist/commands/handlers/simple-commands.js +144 -0
- package/dist/commands/index.d.ts +2 -1
- package/dist/commands/registry.d.ts +50 -0
- package/dist/commands/registry.js +75 -0
- package/dist/commands-v2/handlers/context.d.ts +13 -0
- package/dist/commands-v2/handlers/context.js +348 -0
- package/dist/commands-v2/handlers/core.d.ts +13 -0
- package/dist/commands-v2/handlers/core.js +165 -0
- package/dist/commands-v2/handlers/debug.d.ts +11 -0
- package/dist/commands-v2/handlers/debug.js +159 -0
- package/dist/commands-v2/handlers/index.d.ts +12 -0
- package/dist/commands-v2/handlers/index.js +24 -0
- package/dist/commands-v2/handlers/project.d.ts +22 -0
- package/dist/commands-v2/handlers/project.js +814 -0
- package/dist/commands-v2/handlers/settings.d.ts +15 -0
- package/dist/commands-v2/handlers/settings.js +235 -0
- package/dist/commands-v2/index.d.ts +13 -0
- package/dist/commands-v2/index.js +15 -0
- package/dist/commands-v2/registry.d.ts +37 -0
- package/dist/commands-v2/registry.js +80 -0
- package/dist/commands-v2/types.d.ts +75 -0
- package/dist/commands-v2/types.js +7 -0
- package/dist/commands.js +110 -7
- package/dist/index.js +288 -29
- package/dist/input-handlers/index.d.ts +7 -0
- package/dist/input-handlers/index.js +7 -0
- package/dist/input-handlers/memory-handler.d.ts +26 -0
- package/dist/input-handlers/memory-handler.js +68 -0
- package/dist/repl-helpers.d.ts +63 -0
- package/dist/repl-helpers.js +318 -0
- package/dist/repl-v2.d.ts +155 -0
- package/dist/repl-v2.js +774 -0
- package/dist/repl.d.ts +32 -4
- package/dist/repl.js +250 -977
- package/dist/settings/index.d.ts +23 -0
- package/dist/settings/index.js +48 -0
- package/dist/settings/paths.d.ts +110 -0
- package/dist/settings/paths.js +264 -0
- package/dist/templates/compilr-md.js +7 -4
- package/dist/templates/index.js +3 -4
- package/dist/themes/colors.js +3 -1
- package/dist/themes/registry.d.ts +5 -36
- package/dist/themes/registry.js +11 -95
- package/dist/themes/types.d.ts +3 -38
- package/dist/themes/types.js +2 -2
- package/dist/tools/anchor-tools.d.ts +31 -0
- package/dist/tools/anchor-tools.js +255 -0
- package/dist/tools/backlog-wrappers.d.ts +54 -0
- package/dist/tools/backlog-wrappers.js +338 -0
- package/dist/tools/backlog.js +1 -1
- package/dist/tools/db-tools.d.ts +65 -0
- package/dist/tools/db-tools.js +19 -0
- package/dist/tools/document-db.d.ts +43 -0
- package/dist/tools/document-db.js +220 -0
- package/dist/tools/project-db.d.ts +102 -0
- package/dist/tools/project-db.js +370 -0
- package/dist/tools/workitem-db.d.ts +103 -0
- package/dist/tools/workitem-db.js +549 -0
- package/dist/tools.js +13 -3
- package/dist/ui/agents-overlay-v2.d.ts +43 -0
- package/dist/ui/agents-overlay-v2.js +809 -0
- package/dist/ui/agents-overlay.d.ts +5 -5
- package/dist/ui/agents-overlay.js +782 -420
- package/dist/ui/anchors-overlay.d.ts +12 -0
- package/dist/ui/anchors-overlay.js +775 -0
- package/dist/ui/arch-type-overlay.d.ts +1 -6
- package/dist/ui/arch-type-overlay.js +175 -203
- package/dist/ui/ask-user-overlay-v2.d.ts +26 -0
- package/dist/ui/ask-user-overlay-v2.js +555 -0
- package/dist/ui/ask-user-overlay.d.ts +2 -2
- package/dist/ui/ask-user-overlay.js +443 -535
- package/dist/ui/ask-user-simple-overlay-v2.d.ts +25 -0
- package/dist/ui/ask-user-simple-overlay-v2.js +215 -0
- package/dist/ui/ask-user-simple-overlay.d.ts +2 -2
- package/dist/ui/ask-user-simple-overlay.js +182 -209
- package/dist/ui/backlog-overlay.d.ts +16 -1
- package/dist/ui/backlog-overlay.js +525 -659
- package/dist/ui/base/index.d.ts +26 -0
- package/dist/ui/base/index.js +33 -0
- package/dist/ui/base/inline-overlay-utils.d.ts +217 -0
- package/dist/ui/base/inline-overlay-utils.js +320 -0
- package/dist/ui/base/inline-overlay.d.ts +159 -0
- package/dist/ui/base/inline-overlay.js +257 -0
- package/dist/ui/base/key-utils.d.ts +15 -0
- package/dist/ui/base/key-utils.js +30 -0
- package/dist/ui/base/overlay-base-v2.d.ts +193 -0
- package/dist/ui/base/overlay-base-v2.js +246 -0
- package/dist/ui/base/overlay-base.d.ts +156 -0
- package/dist/ui/base/overlay-base.js +238 -0
- package/dist/ui/base/overlay-lifecycle.d.ts +65 -0
- package/dist/ui/base/overlay-lifecycle.js +159 -0
- package/dist/ui/base/overlay-types.d.ts +185 -0
- package/dist/ui/base/overlay-types.js +7 -0
- package/dist/ui/base/render-utils.d.ts +8 -0
- package/dist/ui/base/render-utils.js +11 -0
- package/dist/ui/base/screen-stack.d.ts +148 -0
- package/dist/ui/base/screen-stack.js +184 -0
- package/dist/ui/base/tabbed-list-overlay-v2.d.ts +103 -0
- package/dist/ui/base/tabbed-list-overlay-v2.js +317 -0
- package/dist/ui/base/tabbed-list-overlay.d.ts +153 -0
- package/dist/ui/base/tabbed-list-overlay.js +369 -0
- package/dist/ui/commands-overlay-v2.d.ts +33 -0
- package/dist/ui/commands-overlay-v2.js +441 -0
- package/dist/ui/commands-overlay.d.ts +7 -2
- package/dist/ui/commands-overlay.js +384 -355
- package/dist/ui/config-overlay.d.ts +5 -4
- package/dist/ui/config-overlay.js +243 -513
- package/dist/ui/conversation.d.ts +75 -4
- package/dist/ui/conversation.js +374 -161
- package/dist/ui/docs-overlay.d.ts +17 -0
- package/dist/ui/docs-overlay.js +303 -0
- package/dist/ui/ephemeral.d.ts +1 -1
- package/dist/ui/ephemeral.js +1 -1
- package/dist/ui/features/index.d.ts +34 -0
- package/dist/ui/features/index.js +34 -0
- package/dist/ui/features/input-feature.d.ts +85 -0
- package/dist/ui/features/input-feature.js +238 -0
- package/dist/ui/features/list-feature.d.ts +155 -0
- package/dist/ui/features/list-feature.js +244 -0
- package/dist/ui/features/pagination-feature.d.ts +154 -0
- package/dist/ui/features/pagination-feature.js +238 -0
- package/dist/ui/features/search-feature.d.ts +148 -0
- package/dist/ui/features/search-feature.js +185 -0
- package/dist/ui/features/tab-feature.d.ts +194 -0
- package/dist/ui/features/tab-feature.js +307 -0
- package/dist/ui/footer-v2.d.ts +222 -0
- package/dist/ui/footer-v2.js +1349 -0
- package/dist/ui/footer.d.ts +107 -0
- package/dist/ui/footer.js +359 -67
- package/dist/ui/guardrail-overlay.d.ts +29 -0
- package/dist/ui/guardrail-overlay.js +145 -0
- package/dist/ui/help-overlay-v2.d.ts +34 -0
- package/dist/ui/help-overlay-v2.js +309 -0
- package/dist/ui/help-overlay.d.ts +16 -0
- package/dist/ui/help-overlay.js +316 -0
- package/dist/ui/index.d.ts +1 -1
- package/dist/ui/index.js +1 -3
- package/dist/ui/init-overlay-v2.d.ts +34 -0
- package/dist/ui/init-overlay-v2.js +600 -0
- package/dist/ui/init-overlay.d.ts +12 -2
- package/dist/ui/init-overlay.js +349 -270
- package/dist/ui/input-prompt-v2.d.ts +1 -0
- package/dist/ui/input-prompt-v2.js +14 -6
- package/dist/ui/input-prompt.d.ts +116 -33
- package/dist/ui/input-prompt.js +536 -337
- package/dist/ui/iteration-limit-overlay-v2.d.ts +21 -0
- package/dist/ui/iteration-limit-overlay-v2.js +114 -0
- package/dist/ui/iteration-limit-overlay.d.ts +2 -2
- package/dist/ui/iteration-limit-overlay.js +92 -128
- package/dist/ui/keys-overlay-v2.d.ts +41 -0
- package/dist/ui/keys-overlay-v2.js +248 -0
- package/dist/ui/keys-overlay.d.ts +1 -0
- package/dist/ui/keys-overlay.js +203 -141
- package/dist/ui/line-utils.d.ts +88 -0
- package/dist/ui/line-utils.js +150 -0
- package/dist/ui/live-region.d.ts +161 -0
- package/dist/ui/live-region.js +387 -0
- package/dist/ui/mascot/expressions.d.ts +32 -0
- package/dist/ui/mascot/expressions.js +213 -0
- package/dist/ui/mascot/index.d.ts +8 -0
- package/dist/ui/mascot/index.js +8 -0
- package/dist/ui/mascot/renderer.d.ts +19 -0
- package/dist/ui/mascot/renderer.js +97 -0
- package/dist/ui/mascot-overlay-v2.d.ts +41 -0
- package/dist/ui/mascot-overlay-v2.js +138 -0
- package/dist/ui/mascot-overlay.d.ts +21 -0
- package/dist/ui/mascot-overlay.js +146 -0
- package/dist/ui/model-overlay-v2.d.ts +49 -0
- package/dist/ui/model-overlay-v2.js +118 -0
- package/dist/ui/model-overlay.d.ts +27 -0
- package/dist/ui/model-overlay.js +221 -0
- package/dist/ui/model-warning-overlay.js +3 -5
- package/dist/ui/new-overlay.d.ts +34 -0
- package/dist/ui/new-overlay.js +604 -0
- package/dist/ui/overlay/impl/agents-overlay-v2.d.ts +45 -0
- package/dist/ui/overlay/impl/agents-overlay-v2.js +825 -0
- package/dist/ui/overlay/impl/anchors-overlay-v2.d.ts +47 -0
- package/dist/ui/overlay/impl/anchors-overlay-v2.js +783 -0
- package/dist/ui/overlay/impl/arch-type-overlay-v2.d.ts +37 -0
- package/dist/ui/overlay/impl/arch-type-overlay-v2.js +240 -0
- package/dist/ui/overlay/impl/ask-user-overlay-v2.d.ts +72 -0
- package/dist/ui/overlay/impl/ask-user-overlay-v2.js +584 -0
- package/dist/ui/overlay/impl/ask-user-simple-overlay-v2.d.ts +46 -0
- package/dist/ui/overlay/impl/ask-user-simple-overlay-v2.js +204 -0
- package/dist/ui/overlay/impl/backlog-overlay-v2.d.ts +49 -0
- package/dist/ui/overlay/impl/backlog-overlay-v2.js +642 -0
- package/dist/ui/overlay/impl/commands-overlay-v2.d.ts +33 -0
- package/dist/ui/overlay/impl/commands-overlay-v2.js +441 -0
- package/dist/ui/overlay/impl/config-overlay-v2.d.ts +100 -0
- package/dist/ui/overlay/impl/config-overlay-v2.js +654 -0
- package/dist/ui/overlay/impl/dashboard-overlay-v2.d.ts +55 -0
- package/dist/ui/overlay/impl/dashboard-overlay-v2.js +359 -0
- package/dist/ui/overlay/impl/docs-overlay-v2.d.ts +45 -0
- package/dist/ui/overlay/impl/docs-overlay-v2.js +114 -0
- package/dist/ui/overlay/impl/document-detail-overlay-v2.d.ts +77 -0
- package/dist/ui/overlay/impl/document-detail-overlay-v2.js +1071 -0
- package/dist/ui/overlay/impl/guardrail-overlay-v2.d.ts +43 -0
- package/dist/ui/overlay/impl/guardrail-overlay-v2.js +114 -0
- package/dist/ui/overlay/impl/help-overlay-v2.d.ts +34 -0
- package/dist/ui/overlay/impl/help-overlay-v2.js +309 -0
- package/dist/ui/overlay/impl/init-overlay-v2.d.ts +77 -0
- package/dist/ui/overlay/impl/init-overlay-v2.js +593 -0
- package/dist/ui/overlay/impl/init-setup-overlay-v2.d.ts +25 -0
- package/dist/ui/overlay/impl/init-setup-overlay-v2.js +97 -0
- package/dist/ui/overlay/impl/iteration-limit-overlay-v2.d.ts +35 -0
- package/dist/ui/overlay/impl/iteration-limit-overlay-v2.js +105 -0
- package/dist/ui/overlay/impl/keys-overlay-v2.d.ts +41 -0
- package/dist/ui/overlay/impl/keys-overlay-v2.js +248 -0
- package/dist/ui/overlay/impl/mascot-overlay-v2.d.ts +41 -0
- package/dist/ui/overlay/impl/mascot-overlay-v2.js +138 -0
- package/dist/ui/overlay/impl/model-overlay-v2.d.ts +49 -0
- package/dist/ui/overlay/impl/model-overlay-v2.js +118 -0
- package/dist/ui/overlay/impl/model-warning-overlay-v2.d.ts +46 -0
- package/dist/ui/overlay/impl/model-warning-overlay-v2.js +132 -0
- package/dist/ui/overlay/impl/new-overlay-v2.d.ts +77 -0
- package/dist/ui/overlay/impl/new-overlay-v2.js +593 -0
- package/dist/ui/overlay/impl/permission-overlay-v2.d.ts +36 -0
- package/dist/ui/overlay/impl/permission-overlay-v2.js +380 -0
- package/dist/ui/overlay/impl/projects-overlay-v2.d.ts +36 -0
- package/dist/ui/overlay/impl/projects-overlay-v2.js +499 -0
- package/dist/ui/overlay/impl/theme-overlay-v2.d.ts +42 -0
- package/dist/ui/overlay/impl/theme-overlay-v2.js +135 -0
- package/dist/ui/overlay/impl/tools-overlay-v2.d.ts +47 -0
- package/dist/ui/overlay/impl/tools-overlay-v2.js +218 -0
- package/dist/ui/overlay/impl/tutorial-overlay-v2.d.ts +31 -0
- package/dist/ui/overlay/impl/tutorial-overlay-v2.js +1035 -0
- package/dist/ui/overlay/impl/workflow-overlay-v2.d.ts +80 -0
- package/dist/ui/overlay/impl/workflow-overlay-v2.js +637 -0
- package/dist/ui/overlay/index.d.ts +33 -0
- package/dist/ui/overlay/index.js +35 -0
- package/dist/ui/overlay/key-utils.d.ts +6 -0
- package/dist/ui/overlay/key-utils.js +6 -0
- package/dist/ui/overlay/overlay-types.d.ts +128 -0
- package/dist/ui/overlay/overlay-types.js +22 -0
- package/dist/ui/overlay/types.d.ts +135 -0
- package/dist/ui/overlay/types.js +22 -0
- package/dist/ui/overlays/help-overlay-v2.d.ts +28 -0
- package/dist/ui/overlays/help-overlay-v2.js +198 -0
- package/dist/ui/overlays/index.d.ts +11 -0
- package/dist/ui/overlays/index.js +11 -0
- package/dist/ui/overlays.d.ts +0 -4
- package/dist/ui/overlays.js +0 -444
- package/dist/ui/permission-overlay-v2.d.ts +36 -0
- package/dist/ui/permission-overlay-v2.js +380 -0
- package/dist/ui/permission-overlay.d.ts +1 -1
- package/dist/ui/permission-overlay.js +186 -298
- package/dist/ui/projects-overlay.d.ts +19 -0
- package/dist/ui/projects-overlay.js +484 -0
- package/dist/ui/providers/types.d.ts +178 -0
- package/dist/ui/providers/types.js +9 -0
- package/dist/ui/render-modes.d.ts +36 -0
- package/dist/ui/render-modes.js +44 -0
- package/dist/ui/startup-menu.d.ts +36 -0
- package/dist/ui/startup-menu.js +236 -0
- package/dist/ui/subagent-renderer.d.ts +117 -0
- package/dist/ui/subagent-renderer.js +334 -0
- package/dist/ui/terminal-codes.d.ts +94 -0
- package/dist/ui/terminal-codes.js +124 -0
- package/dist/ui/terminal-renderer.d.ts +221 -0
- package/dist/ui/terminal-renderer.js +751 -0
- package/dist/ui/terminal-ui.d.ts +463 -0
- package/dist/ui/terminal-ui.js +2296 -0
- package/dist/ui/terminal.d.ts +20 -0
- package/dist/ui/terminal.js +72 -0
- package/dist/ui/theme-overlay-v2.d.ts +42 -0
- package/dist/ui/theme-overlay-v2.js +135 -0
- package/dist/ui/theme-overlay.d.ts +24 -0
- package/dist/ui/theme-overlay.js +127 -0
- package/dist/ui/todo-zone.js +53 -25
- package/dist/ui/tool-formatters.d.ts +16 -0
- package/dist/ui/tool-formatters.js +516 -0
- package/dist/ui/tools-overlay-v2.d.ts +47 -0
- package/dist/ui/tools-overlay-v2.js +218 -0
- package/dist/ui/tools-overlay.d.ts +10 -2
- package/dist/ui/tools-overlay.js +172 -220
- package/dist/ui/tutorial-overlay-v2.d.ts +31 -0
- package/dist/ui/tutorial-overlay-v2.js +1035 -0
- package/dist/ui/tutorial-overlay.d.ts +1 -0
- package/dist/ui/tutorial-overlay.js +400 -302
- package/dist/ui/workflow-overlay.d.ts +22 -0
- package/dist/ui/workflow-overlay.js +636 -0
- package/dist/utils/debug-log.d.ts +28 -0
- package/dist/utils/debug-log.js +57 -0
- package/dist/utils/model-tiers.js +1 -1
- package/dist/utils/path-safety.d.ts +56 -0
- package/dist/utils/path-safety.js +239 -0
- package/dist/workflow/guided-mode-injector.d.ts +42 -0
- package/dist/workflow/guided-mode-injector.js +191 -0
- package/dist/workflow/index.d.ts +8 -0
- package/dist/workflow/index.js +8 -0
- package/dist/workflow/step-criteria.d.ts +62 -0
- package/dist/workflow/step-criteria.js +150 -0
- package/dist/workflow/step-tracker.d.ts +92 -0
- package/dist/workflow/step-tracker.js +141 -0
- package/package.json +12 -5
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Project Anchors - CLI wrapper for @compilr-dev/agents AnchorManager
|
|
3
|
+
*
|
|
4
|
+
* Manages per-project anchor isolation using the library's AnchorManager
|
|
5
|
+
* with project-scoped persistence based on CLI's dataPath configuration.
|
|
6
|
+
*
|
|
7
|
+
* Storage structure:
|
|
8
|
+
* {dataPath}/anchors/
|
|
9
|
+
* ├── global.json # Non-project anchors
|
|
10
|
+
* └── project-{id}.json # Per-project anchors
|
|
11
|
+
*/
|
|
12
|
+
import { AnchorManager } from '@compilr-dev/agents';
|
|
13
|
+
import type { Anchor, AnchorInput, AnchorQueryOptions } from '@compilr-dev/agents';
|
|
14
|
+
export type { Anchor, AnchorInput, AnchorQueryOptions };
|
|
15
|
+
/**
|
|
16
|
+
* Get anchor manager for a project (or global if projectId is null)
|
|
17
|
+
*
|
|
18
|
+
* Creates a new manager if one doesn't exist, using file-based persistence.
|
|
19
|
+
*
|
|
20
|
+
* @param projectId - Project ID, or null for global anchors
|
|
21
|
+
* @returns AnchorManager instance
|
|
22
|
+
*/
|
|
23
|
+
export declare function getAnchorManager(projectId: string | null): AnchorManager;
|
|
24
|
+
/**
|
|
25
|
+
* Get the global anchor manager
|
|
26
|
+
*/
|
|
27
|
+
export declare function getGlobalAnchorManager(): AnchorManager;
|
|
28
|
+
/**
|
|
29
|
+
* Clear all anchors for a project
|
|
30
|
+
*
|
|
31
|
+
* Should be called when a project is deleted.
|
|
32
|
+
*
|
|
33
|
+
* @param projectId - Project ID to clear
|
|
34
|
+
* @returns Number of anchors removed
|
|
35
|
+
*/
|
|
36
|
+
export declare function clearProjectAnchors(projectId: string): number;
|
|
37
|
+
/**
|
|
38
|
+
* Get formatted anchor content for injection into system prompt
|
|
39
|
+
*
|
|
40
|
+
* Combines global anchors with project-specific anchors.
|
|
41
|
+
*
|
|
42
|
+
* @param projectId - Optional project ID to include project anchors
|
|
43
|
+
* @returns Formatted anchor string for system prompt
|
|
44
|
+
*/
|
|
45
|
+
export declare function getFormattedAnchors(projectId?: string): string;
|
|
46
|
+
/**
|
|
47
|
+
* Add an anchor
|
|
48
|
+
*
|
|
49
|
+
* Convenience function that routes to the appropriate manager.
|
|
50
|
+
*
|
|
51
|
+
* @param input - Anchor input with optional projectId
|
|
52
|
+
* @returns Created anchor
|
|
53
|
+
*/
|
|
54
|
+
export declare function addAnchor(input: AnchorInput & {
|
|
55
|
+
projectId?: string;
|
|
56
|
+
}): Anchor;
|
|
57
|
+
/**
|
|
58
|
+
* Get all anchors across all managers
|
|
59
|
+
*
|
|
60
|
+
* @param options - Query options
|
|
61
|
+
* @returns Array of all anchors
|
|
62
|
+
*/
|
|
63
|
+
export declare function getAllAnchors(options?: AnchorQueryOptions): Anchor[];
|
|
64
|
+
/**
|
|
65
|
+
* Get list of project IDs that have anchor files
|
|
66
|
+
*/
|
|
67
|
+
export declare function getProjectsWithAnchors(): string[];
|
|
68
|
+
/**
|
|
69
|
+
* Get anchor statistics
|
|
70
|
+
*/
|
|
71
|
+
export declare function getAnchorStats(): {
|
|
72
|
+
globalCount: number;
|
|
73
|
+
projectCounts: Map<string, number>;
|
|
74
|
+
totalTokens: number;
|
|
75
|
+
};
|
|
76
|
+
/**
|
|
77
|
+
* Clear all cached managers (useful for testing or refresh)
|
|
78
|
+
*/
|
|
79
|
+
export declare function clearManagerCache(): void;
|
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Project Anchors - CLI wrapper for @compilr-dev/agents AnchorManager
|
|
3
|
+
*
|
|
4
|
+
* Manages per-project anchor isolation using the library's AnchorManager
|
|
5
|
+
* with project-scoped persistence based on CLI's dataPath configuration.
|
|
6
|
+
*
|
|
7
|
+
* Storage structure:
|
|
8
|
+
* {dataPath}/anchors/
|
|
9
|
+
* ├── global.json # Non-project anchors
|
|
10
|
+
* └── project-{id}.json # Per-project anchors
|
|
11
|
+
*/
|
|
12
|
+
import * as fs from 'fs';
|
|
13
|
+
import * as path from 'path';
|
|
14
|
+
import { AnchorManager } from '@compilr-dev/agents';
|
|
15
|
+
import { getDataPath } from '../settings/paths.js';
|
|
16
|
+
// =============================================================================
|
|
17
|
+
// State
|
|
18
|
+
// =============================================================================
|
|
19
|
+
/**
|
|
20
|
+
* Cache of anchor managers by project ID (null = global)
|
|
21
|
+
*/
|
|
22
|
+
const managers = new Map();
|
|
23
|
+
// =============================================================================
|
|
24
|
+
// Helpers
|
|
25
|
+
// =============================================================================
|
|
26
|
+
/**
|
|
27
|
+
* Get the anchors directory path
|
|
28
|
+
*/
|
|
29
|
+
function getAnchorsDir() {
|
|
30
|
+
return path.join(getDataPath(), 'anchors');
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Get the persist path for a project (or global)
|
|
34
|
+
*/
|
|
35
|
+
function getPersistPath(projectId) {
|
|
36
|
+
const anchorsDir = getAnchorsDir();
|
|
37
|
+
const filename = projectId ? `project-${projectId}.json` : 'global.json';
|
|
38
|
+
return path.join(anchorsDir, filename);
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Ensure the anchors directory exists
|
|
42
|
+
*/
|
|
43
|
+
function ensureAnchorsDir() {
|
|
44
|
+
const anchorsDir = getAnchorsDir();
|
|
45
|
+
if (!fs.existsSync(anchorsDir)) {
|
|
46
|
+
fs.mkdirSync(anchorsDir, { recursive: true });
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
// =============================================================================
|
|
50
|
+
// Public API
|
|
51
|
+
// =============================================================================
|
|
52
|
+
/**
|
|
53
|
+
* Get anchor manager for a project (or global if projectId is null)
|
|
54
|
+
*
|
|
55
|
+
* Creates a new manager if one doesn't exist, using file-based persistence.
|
|
56
|
+
*
|
|
57
|
+
* @param projectId - Project ID, or null for global anchors
|
|
58
|
+
* @returns AnchorManager instance
|
|
59
|
+
*/
|
|
60
|
+
export function getAnchorManager(projectId) {
|
|
61
|
+
if (managers.has(projectId)) {
|
|
62
|
+
const existing = managers.get(projectId);
|
|
63
|
+
if (existing)
|
|
64
|
+
return existing;
|
|
65
|
+
}
|
|
66
|
+
ensureAnchorsDir();
|
|
67
|
+
const manager = new AnchorManager({
|
|
68
|
+
persistPath: getPersistPath(projectId),
|
|
69
|
+
// Only include default safety anchors for global manager
|
|
70
|
+
includeDefaults: projectId === null,
|
|
71
|
+
maxAnchors: 50,
|
|
72
|
+
maxTokens: 4000,
|
|
73
|
+
});
|
|
74
|
+
managers.set(projectId, manager);
|
|
75
|
+
return manager;
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Get the global anchor manager
|
|
79
|
+
*/
|
|
80
|
+
export function getGlobalAnchorManager() {
|
|
81
|
+
return getAnchorManager(null);
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Clear all anchors for a project
|
|
85
|
+
*
|
|
86
|
+
* Should be called when a project is deleted.
|
|
87
|
+
*
|
|
88
|
+
* @param projectId - Project ID to clear
|
|
89
|
+
* @returns Number of anchors removed
|
|
90
|
+
*/
|
|
91
|
+
export function clearProjectAnchors(projectId) {
|
|
92
|
+
const manager = managers.get(projectId);
|
|
93
|
+
let removed = 0;
|
|
94
|
+
if (manager) {
|
|
95
|
+
removed = manager.clear();
|
|
96
|
+
managers.delete(projectId);
|
|
97
|
+
}
|
|
98
|
+
// Also delete the persistence file
|
|
99
|
+
const filePath = getPersistPath(projectId);
|
|
100
|
+
if (fs.existsSync(filePath)) {
|
|
101
|
+
fs.unlinkSync(filePath);
|
|
102
|
+
}
|
|
103
|
+
return removed;
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Get formatted anchor content for injection into system prompt
|
|
107
|
+
*
|
|
108
|
+
* Combines global anchors with project-specific anchors.
|
|
109
|
+
*
|
|
110
|
+
* @param projectId - Optional project ID to include project anchors
|
|
111
|
+
* @returns Formatted anchor string for system prompt
|
|
112
|
+
*/
|
|
113
|
+
export function getFormattedAnchors(projectId) {
|
|
114
|
+
const parts = [];
|
|
115
|
+
// Get global anchors
|
|
116
|
+
const globalManager = getGlobalAnchorManager();
|
|
117
|
+
const globalFormatted = globalManager.format();
|
|
118
|
+
if (globalFormatted) {
|
|
119
|
+
parts.push(globalFormatted);
|
|
120
|
+
}
|
|
121
|
+
// Get project-specific anchors if project ID provided
|
|
122
|
+
if (projectId) {
|
|
123
|
+
const projectManager = getAnchorManager(projectId);
|
|
124
|
+
const projectFormatted = projectManager.format();
|
|
125
|
+
if (projectFormatted) {
|
|
126
|
+
if (parts.length > 0) {
|
|
127
|
+
parts.push(''); // Empty line separator
|
|
128
|
+
parts.push(`### Project Anchors (${projectId})`);
|
|
129
|
+
}
|
|
130
|
+
parts.push(projectFormatted);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
return parts.join('\n');
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Add an anchor
|
|
137
|
+
*
|
|
138
|
+
* Convenience function that routes to the appropriate manager.
|
|
139
|
+
*
|
|
140
|
+
* @param input - Anchor input with optional projectId
|
|
141
|
+
* @returns Created anchor
|
|
142
|
+
*/
|
|
143
|
+
export function addAnchor(input) {
|
|
144
|
+
const manager = getAnchorManager(input.projectId ?? null);
|
|
145
|
+
return manager.add(input);
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Get all anchors across all managers
|
|
149
|
+
*
|
|
150
|
+
* @param options - Query options
|
|
151
|
+
* @returns Array of all anchors
|
|
152
|
+
*/
|
|
153
|
+
export function getAllAnchors(options) {
|
|
154
|
+
const allAnchors = [];
|
|
155
|
+
for (const manager of managers.values()) {
|
|
156
|
+
allAnchors.push(...manager.getAll(options));
|
|
157
|
+
}
|
|
158
|
+
return allAnchors;
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* Get list of project IDs that have anchor files
|
|
162
|
+
*/
|
|
163
|
+
export function getProjectsWithAnchors() {
|
|
164
|
+
const anchorsDir = getAnchorsDir();
|
|
165
|
+
if (!fs.existsSync(anchorsDir)) {
|
|
166
|
+
return [];
|
|
167
|
+
}
|
|
168
|
+
const files = fs.readdirSync(anchorsDir);
|
|
169
|
+
const projectIds = [];
|
|
170
|
+
for (const file of files) {
|
|
171
|
+
const match = /^project-(.+)\.json$/.exec(file);
|
|
172
|
+
if (match && match[1]) {
|
|
173
|
+
projectIds.push(match[1]);
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
return projectIds;
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* Get anchor statistics
|
|
180
|
+
*/
|
|
181
|
+
export function getAnchorStats() {
|
|
182
|
+
const globalManager = getGlobalAnchorManager();
|
|
183
|
+
const projectCounts = new Map();
|
|
184
|
+
let totalTokens = globalManager.getTotalTokens();
|
|
185
|
+
// Load all project managers to get stats
|
|
186
|
+
for (const projectId of getProjectsWithAnchors()) {
|
|
187
|
+
const manager = getAnchorManager(projectId);
|
|
188
|
+
projectCounts.set(projectId, manager.size);
|
|
189
|
+
totalTokens += manager.getTotalTokens();
|
|
190
|
+
}
|
|
191
|
+
return {
|
|
192
|
+
globalCount: globalManager.size,
|
|
193
|
+
projectCounts,
|
|
194
|
+
totalTokens,
|
|
195
|
+
};
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
* Clear all cached managers (useful for testing or refresh)
|
|
199
|
+
*/
|
|
200
|
+
export function clearManagerCache() {
|
|
201
|
+
managers.clear();
|
|
202
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Command Handler Types
|
|
3
|
+
*
|
|
4
|
+
* Defines the interfaces for the command handler system.
|
|
5
|
+
* Handlers are registered with the command registry and invoked
|
|
6
|
+
* by REPL.handleCommand() when a slash command is entered.
|
|
7
|
+
*/
|
|
8
|
+
import type { Agent } from '@compilr-dev/agents';
|
|
9
|
+
import type { Footer } from '../ui/footer.js';
|
|
10
|
+
import type { REPLState, AgentMode } from '../ui/types.js';
|
|
11
|
+
/**
|
|
12
|
+
* Context passed to command handlers.
|
|
13
|
+
* Contains all dependencies needed to execute commands.
|
|
14
|
+
*/
|
|
15
|
+
export interface CommandContext {
|
|
16
|
+
agent: Agent;
|
|
17
|
+
model: string;
|
|
18
|
+
currentModel: string;
|
|
19
|
+
provider: string;
|
|
20
|
+
version: string;
|
|
21
|
+
footer: Footer;
|
|
22
|
+
state: REPLState;
|
|
23
|
+
startTime: Date;
|
|
24
|
+
sessionInputTokens: number;
|
|
25
|
+
sessionOutputTokens: number;
|
|
26
|
+
sessionRequests: number;
|
|
27
|
+
onModeChange?: (mode: AgentMode) => void;
|
|
28
|
+
setShouldReturnToMenu: (value: boolean) => void;
|
|
29
|
+
processMessage: (message: string, options?: {
|
|
30
|
+
displayMessage?: string;
|
|
31
|
+
}) => Promise<void>;
|
|
32
|
+
handleCommand: (command: string, args: string) => Promise<boolean>;
|
|
33
|
+
setModel: (model: string) => void;
|
|
34
|
+
showTools: () => Promise<void>;
|
|
35
|
+
showTokens: () => void;
|
|
36
|
+
showContext: () => void;
|
|
37
|
+
showStatus: () => void;
|
|
38
|
+
showTodos: () => void;
|
|
39
|
+
handleCompact: () => Promise<void>;
|
|
40
|
+
handleExport: (args: string) => Promise<void>;
|
|
41
|
+
reloadProjectAnchors: (oldProjectId: string | null, newProjectId: string) => void;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Interface for a command handler.
|
|
45
|
+
*/
|
|
46
|
+
export interface CommandHandler {
|
|
47
|
+
/** Primary command name (without leading slash) */
|
|
48
|
+
name: string;
|
|
49
|
+
/** Optional aliases that resolve to this command */
|
|
50
|
+
aliases?: string[];
|
|
51
|
+
/** Short description for help text */
|
|
52
|
+
description: string;
|
|
53
|
+
/**
|
|
54
|
+
* Execute the command.
|
|
55
|
+
*
|
|
56
|
+
* @param args - Arguments passed after the command (e.g., "/build REQ-001" -> "REQ-001")
|
|
57
|
+
* @param ctx - Command context with dependencies
|
|
58
|
+
* @returns true to continue REPL, false to exit
|
|
59
|
+
*/
|
|
60
|
+
execute(args: string, ctx: CommandContext): Promise<boolean>;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Result of executing a command.
|
|
64
|
+
* - true: Command handled successfully, continue REPL
|
|
65
|
+
* - false: Exit REPL (e.g., /exit command)
|
|
66
|
+
* - null: Command not found in registry
|
|
67
|
+
*/
|
|
68
|
+
export type CommandResult = boolean | null;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agent Commands
|
|
3
|
+
*
|
|
4
|
+
* Commands that delegate work to the agent via processMessage:
|
|
5
|
+
* - build, note, prd, scaffold, workflow
|
|
6
|
+
*/
|
|
7
|
+
import type { CommandHandler } from '../handler-types.js';
|
|
8
|
+
export declare const noteCommand: CommandHandler;
|
|
9
|
+
export declare const prdCommand: CommandHandler;
|
|
10
|
+
export declare const workflowCommand: CommandHandler;
|
|
11
|
+
export declare const scaffoldCommand: CommandHandler;
|
|
12
|
+
export declare const buildCommand: CommandHandler;
|
|
13
|
+
export declare const agentCommands: CommandHandler[];
|
|
@@ -0,0 +1,305 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agent Commands
|
|
3
|
+
*
|
|
4
|
+
* Commands that delegate work to the agent via processMessage:
|
|
5
|
+
* - build, note, prd, scaffold, workflow
|
|
6
|
+
*/
|
|
7
|
+
import fs from 'node:fs';
|
|
8
|
+
import * as conversation from '../../ui/conversation.js';
|
|
9
|
+
import { showWorkflowOverlay } from '../../ui/workflow-overlay.js';
|
|
10
|
+
import { findBacklogPath, parseBacklogItems } from '../../tools/backlog.js';
|
|
11
|
+
import { detectCompilrProject, getSkillPrompt, hasProjectFoundation, selectBuildItem, getUnmetDependencies, } from '../../repl-helpers.js';
|
|
12
|
+
// =============================================================================
|
|
13
|
+
// Note Command
|
|
14
|
+
// =============================================================================
|
|
15
|
+
export const noteCommand = {
|
|
16
|
+
name: 'note',
|
|
17
|
+
description: 'Create a session note',
|
|
18
|
+
async execute(args, ctx) {
|
|
19
|
+
// Check if project is initialized
|
|
20
|
+
const noteProject = detectCompilrProject();
|
|
21
|
+
if (!noteProject.found) {
|
|
22
|
+
conversation.printError('No .compilr project found. Run /new first.');
|
|
23
|
+
return true;
|
|
24
|
+
}
|
|
25
|
+
// Get session-notes skill prompt
|
|
26
|
+
const notePrompt = getSkillPrompt('session-notes');
|
|
27
|
+
if (!notePrompt) {
|
|
28
|
+
conversation.printError('Session-notes skill not found.');
|
|
29
|
+
return true;
|
|
30
|
+
}
|
|
31
|
+
// Check for optional title argument
|
|
32
|
+
const noteTitle = args.trim();
|
|
33
|
+
conversation.printInfo('📝 Creating session note...');
|
|
34
|
+
conversation.printInfo('');
|
|
35
|
+
// Resume footer animation before processing message
|
|
36
|
+
ctx.footer.resumeAnimation();
|
|
37
|
+
// Build message based on whether title was provided
|
|
38
|
+
const titleInstruction = noteTitle
|
|
39
|
+
? `The session title is: "${noteTitle}"`
|
|
40
|
+
: 'Please ask me for a title using ask_user_simple, or generate one from the session summary.';
|
|
41
|
+
await ctx.processMessage(`I want to create a session note capturing what we've done.
|
|
42
|
+
|
|
43
|
+
${notePrompt}
|
|
44
|
+
|
|
45
|
+
${titleInstruction}
|
|
46
|
+
|
|
47
|
+
Review the conversation context to understand what was accomplished, then create the session note file.`, {
|
|
48
|
+
displayMessage: noteTitle
|
|
49
|
+
? `Create session note: "${noteTitle}"`
|
|
50
|
+
: 'Create a session note for this session.',
|
|
51
|
+
});
|
|
52
|
+
return true;
|
|
53
|
+
},
|
|
54
|
+
};
|
|
55
|
+
// =============================================================================
|
|
56
|
+
// PRD Command
|
|
57
|
+
// =============================================================================
|
|
58
|
+
export const prdCommand = {
|
|
59
|
+
name: 'prd',
|
|
60
|
+
description: 'Update the Product Requirements Document',
|
|
61
|
+
async execute(args, ctx) {
|
|
62
|
+
// Check if project is initialized
|
|
63
|
+
const prdProject = detectCompilrProject();
|
|
64
|
+
if (!prdProject.found) {
|
|
65
|
+
conversation.printError('No .compilr project found. Run /new first.');
|
|
66
|
+
return true;
|
|
67
|
+
}
|
|
68
|
+
// Get prd skill prompt
|
|
69
|
+
const prdPrompt = getSkillPrompt('prd');
|
|
70
|
+
if (!prdPrompt) {
|
|
71
|
+
conversation.printError('PRD skill not found.');
|
|
72
|
+
return true;
|
|
73
|
+
}
|
|
74
|
+
// Check for optional section argument
|
|
75
|
+
const prdSection = args.trim().toLowerCase();
|
|
76
|
+
const validSections = ['vision', 'scope', 'technical', 'success'];
|
|
77
|
+
const sectionInstruction = validSections.includes(prdSection)
|
|
78
|
+
? `The user wants to update the "${prdSection}" section specifically.`
|
|
79
|
+
: 'Ask the user which section they want to update using ask_user_simple.';
|
|
80
|
+
conversation.printInfo('📄 Opening PRD for updates...');
|
|
81
|
+
conversation.printInfo('');
|
|
82
|
+
// Resume footer animation before processing message
|
|
83
|
+
ctx.footer.resumeAnimation();
|
|
84
|
+
await ctx.processMessage(`I want to update the Product Requirements Document.
|
|
85
|
+
|
|
86
|
+
${prdPrompt}
|
|
87
|
+
|
|
88
|
+
${sectionInstruction}
|
|
89
|
+
|
|
90
|
+
Start by reading the existing PRD.md file to understand current state.`, {
|
|
91
|
+
displayMessage: prdSection
|
|
92
|
+
? `Update PRD: ${prdSection} section`
|
|
93
|
+
: 'Update the Product Requirements Document',
|
|
94
|
+
});
|
|
95
|
+
return true;
|
|
96
|
+
},
|
|
97
|
+
};
|
|
98
|
+
// =============================================================================
|
|
99
|
+
// Workflow Command
|
|
100
|
+
// =============================================================================
|
|
101
|
+
export const workflowCommand = {
|
|
102
|
+
name: 'workflow',
|
|
103
|
+
description: 'Show the workflow overlay',
|
|
104
|
+
async execute(_args, ctx) {
|
|
105
|
+
// Loop: workflow → command → back to workflow → etc.
|
|
106
|
+
// User presses Esc in workflow to exit back to REPL
|
|
107
|
+
let stayInWorkflow = true;
|
|
108
|
+
while (stayInWorkflow) {
|
|
109
|
+
// Result may be undefined if user cancelled with Esc (base overlay casts undefined to TResult)
|
|
110
|
+
const result = await showWorkflowOverlay();
|
|
111
|
+
if (result?.command) {
|
|
112
|
+
// User selected a command from workflow, run it
|
|
113
|
+
await ctx.handleCommand(result.command.slice(1), ''); // Remove leading /, no args
|
|
114
|
+
// After command completes, loop back to workflow
|
|
115
|
+
}
|
|
116
|
+
else {
|
|
117
|
+
// User cancelled workflow (Esc), exit to REPL
|
|
118
|
+
stayInWorkflow = false;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
return true;
|
|
122
|
+
},
|
|
123
|
+
};
|
|
124
|
+
// =============================================================================
|
|
125
|
+
// Scaffold Command
|
|
126
|
+
// =============================================================================
|
|
127
|
+
export const scaffoldCommand = {
|
|
128
|
+
name: 'scaffold',
|
|
129
|
+
description: 'Create project scaffold/foundation',
|
|
130
|
+
async execute(_args, ctx) {
|
|
131
|
+
// Check if project is initialized
|
|
132
|
+
const scaffoldProject = detectCompilrProject();
|
|
133
|
+
if (!scaffoldProject.found) {
|
|
134
|
+
conversation.printError('No .compilr project found. Run /new first.');
|
|
135
|
+
return true;
|
|
136
|
+
}
|
|
137
|
+
// Get project path for context
|
|
138
|
+
const projectPathForScaffold = scaffoldProject.projectPath || process.cwd();
|
|
139
|
+
const scaffoldPathContext = `**IMPORTANT: Project Directory**
|
|
140
|
+
All code files MUST be created in: ${projectPathForScaffold}
|
|
141
|
+
Do NOT create files in the current working directory if it differs from the project path.
|
|
142
|
+
`;
|
|
143
|
+
// Check if foundation already exists
|
|
144
|
+
const foundationExists = hasProjectFoundation();
|
|
145
|
+
if (foundationExists) {
|
|
146
|
+
// Let agent confirm with user
|
|
147
|
+
conversation.printInfo('🔍 Project files detected...');
|
|
148
|
+
conversation.printInfo('');
|
|
149
|
+
ctx.footer.resumeAnimation();
|
|
150
|
+
await ctx.processMessage(`User wants to create a project scaffold, but a foundation may already exist.
|
|
151
|
+
|
|
152
|
+
${scaffoldPathContext}
|
|
153
|
+
|
|
154
|
+
Use detect_project to analyze the current state. Then use ask_user_simple:
|
|
155
|
+
"Project files already exist. What would you like to do?"
|
|
156
|
+
- "Continue anyway (may overwrite)"
|
|
157
|
+
- "Cancel"
|
|
158
|
+
|
|
159
|
+
If continuing, read COMPILR.md and PRD.md for tech stack info, then create the scaffold:
|
|
160
|
+
|
|
161
|
+
${getSkillPrompt('scaffold') ?? ''}`, { displayMessage: 'Create project scaffold (foundation exists).' });
|
|
162
|
+
return true;
|
|
163
|
+
}
|
|
164
|
+
// Get scaffold skill prompt
|
|
165
|
+
const scaffoldPrompt = getSkillPrompt('scaffold');
|
|
166
|
+
if (!scaffoldPrompt) {
|
|
167
|
+
conversation.printError('Scaffold skill not found.');
|
|
168
|
+
return true;
|
|
169
|
+
}
|
|
170
|
+
conversation.printInfo('🏗️ Creating project scaffold...');
|
|
171
|
+
conversation.printInfo('');
|
|
172
|
+
ctx.footer.resumeAnimation();
|
|
173
|
+
await ctx.processMessage(`I want to create the project scaffold (foundation).
|
|
174
|
+
|
|
175
|
+
${scaffoldPathContext}
|
|
176
|
+
|
|
177
|
+
${scaffoldPrompt}
|
|
178
|
+
|
|
179
|
+
Read COMPILR.md and PRD.md first to understand the tech stack, then create the appropriate scaffold.`, { displayMessage: 'Create project scaffold.' });
|
|
180
|
+
return true;
|
|
181
|
+
},
|
|
182
|
+
};
|
|
183
|
+
// =============================================================================
|
|
184
|
+
// Build Command
|
|
185
|
+
// =============================================================================
|
|
186
|
+
export const buildCommand = {
|
|
187
|
+
name: 'build',
|
|
188
|
+
description: 'Build a backlog item',
|
|
189
|
+
async execute(args, ctx) {
|
|
190
|
+
const itemId = args.trim() || undefined;
|
|
191
|
+
// Handle /build scaffold - redirect to scaffold handler
|
|
192
|
+
if (itemId?.toLowerCase() === 'scaffold') {
|
|
193
|
+
return ctx.handleCommand('scaffold', '');
|
|
194
|
+
}
|
|
195
|
+
// Check if project is initialized
|
|
196
|
+
const buildProject = detectCompilrProject();
|
|
197
|
+
if (!buildProject.found) {
|
|
198
|
+
conversation.printError('No .compilr project found. Run /new first.');
|
|
199
|
+
return true;
|
|
200
|
+
}
|
|
201
|
+
// Read backlog using the shared path detection
|
|
202
|
+
const buildBacklogPath = findBacklogPath();
|
|
203
|
+
if (!buildBacklogPath) {
|
|
204
|
+
conversation.printError('No backlog found. Run /design or /sketch first.');
|
|
205
|
+
return true;
|
|
206
|
+
}
|
|
207
|
+
// Parse backlog items
|
|
208
|
+
let buildItems = [];
|
|
209
|
+
try {
|
|
210
|
+
const backlogContent = fs.readFileSync(buildBacklogPath, 'utf-8');
|
|
211
|
+
buildItems = parseBacklogItems(backlogContent);
|
|
212
|
+
}
|
|
213
|
+
catch {
|
|
214
|
+
conversation.printError('Failed to read backlog file.');
|
|
215
|
+
return true;
|
|
216
|
+
}
|
|
217
|
+
if (buildItems.length === 0) {
|
|
218
|
+
conversation.printError('No backlog items found. Run /design or /sketch first.');
|
|
219
|
+
return true;
|
|
220
|
+
}
|
|
221
|
+
// Get project path for context
|
|
222
|
+
const projectPathForBuild = buildProject.projectPath || process.cwd();
|
|
223
|
+
const projectPathContext = `**IMPORTANT: Project Directory**
|
|
224
|
+
All code files MUST be created in: ${projectPathForBuild}
|
|
225
|
+
Do NOT create files in the current working directory if it differs from the project path.
|
|
226
|
+
`;
|
|
227
|
+
// Check foundation
|
|
228
|
+
const foundationExists = hasProjectFoundation();
|
|
229
|
+
if (!foundationExists) {
|
|
230
|
+
// Let agent handle foundation check via skill
|
|
231
|
+
conversation.printInfo('🔍 Checking project foundation...');
|
|
232
|
+
conversation.printInfo('');
|
|
233
|
+
ctx.footer.resumeAnimation();
|
|
234
|
+
await ctx.processMessage(`I want to build a feature from the backlog, but first check if the project has a foundation.
|
|
235
|
+
|
|
236
|
+
${projectPathContext}
|
|
237
|
+
|
|
238
|
+
Use detect_project to check the current state. If there's no code foundation (no src/, no package.json or equivalent), use ask_user_simple to ask:
|
|
239
|
+
"No project foundation detected. Would you like to:"
|
|
240
|
+
- "Create scaffold first (recommended)"
|
|
241
|
+
- "Proceed with feature anyway"
|
|
242
|
+
- "Cancel"
|
|
243
|
+
|
|
244
|
+
If user chooses scaffold, read COMPILR.md and PRD.md for tech stack info, then create the project scaffold following these guidelines:
|
|
245
|
+
|
|
246
|
+
${getSkillPrompt('scaffold') ?? ''}
|
|
247
|
+
|
|
248
|
+
After scaffold is done (or if user chose to proceed anyway), continue with building the feature.`, { displayMessage: 'Check project foundation before building.' });
|
|
249
|
+
return true;
|
|
250
|
+
}
|
|
251
|
+
// Select item
|
|
252
|
+
const item = selectBuildItem(buildItems, itemId);
|
|
253
|
+
if (!item) {
|
|
254
|
+
if (itemId) {
|
|
255
|
+
const existingItem = buildItems.find(i => i.id.toUpperCase() === itemId.toUpperCase());
|
|
256
|
+
if (existingItem) {
|
|
257
|
+
conversation.printError(`Item ${itemId} is already ${existingItem.status === '✅' ? 'completed' : 'in progress'}.`);
|
|
258
|
+
}
|
|
259
|
+
else {
|
|
260
|
+
conversation.printError(`Item ${itemId} not found in backlog.`);
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
else {
|
|
264
|
+
conversation.printInfo('No pending items in backlog. All done! 🎉');
|
|
265
|
+
}
|
|
266
|
+
return true;
|
|
267
|
+
}
|
|
268
|
+
// Check dependencies
|
|
269
|
+
const unmetDeps = getUnmetDependencies(item, buildItems);
|
|
270
|
+
const depsWarning = unmetDeps.length > 0
|
|
271
|
+
? `\n\n**⚠️ UNMET DEPENDENCIES:**\n${unmetDeps.map(d => `- ${d.id}: ${d.title} (${d.status})`).join('\n')}\n\nThese items are not yet completed. Ask user to confirm before proceeding.`
|
|
272
|
+
: '';
|
|
273
|
+
// Get build skill prompt and replace placeholders
|
|
274
|
+
const buildPromptTemplate = getSkillPrompt('build');
|
|
275
|
+
if (!buildPromptTemplate) {
|
|
276
|
+
conversation.printError('Build skill not found.');
|
|
277
|
+
return true;
|
|
278
|
+
}
|
|
279
|
+
const buildPrompt = buildPromptTemplate
|
|
280
|
+
.replace(/\{\{item_id\}\}/g, item.id)
|
|
281
|
+
.replace(/\{\{item_title\}\}/g, item.title)
|
|
282
|
+
.replace(/\{\{item_description\}\}/g, item.description)
|
|
283
|
+
.replace(/\{\{item_type\}\}/g, item.type)
|
|
284
|
+
.replace(/\{\{item_priority\}\}/g, item.priority);
|
|
285
|
+
conversation.printInfo(`🔨 Building ${item.id}: ${item.title}`);
|
|
286
|
+
conversation.printInfo('');
|
|
287
|
+
ctx.footer.resumeAnimation();
|
|
288
|
+
await ctx.processMessage(`I want to implement backlog item ${item.id}.
|
|
289
|
+
|
|
290
|
+
${projectPathContext}
|
|
291
|
+
|
|
292
|
+
${buildPrompt}${depsWarning}`, { displayMessage: `Build ${item.id}: ${item.title}` });
|
|
293
|
+
return true;
|
|
294
|
+
},
|
|
295
|
+
};
|
|
296
|
+
// =============================================================================
|
|
297
|
+
// Export All Agent Commands
|
|
298
|
+
// =============================================================================
|
|
299
|
+
export const agentCommands = [
|
|
300
|
+
buildCommand,
|
|
301
|
+
noteCommand,
|
|
302
|
+
prdCommand,
|
|
303
|
+
scaffoldCommand,
|
|
304
|
+
workflowCommand,
|
|
305
|
+
];
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Design Commands
|
|
3
|
+
*
|
|
4
|
+
* Commands for project design and requirements:
|
|
5
|
+
* - design: Full project design workflow
|
|
6
|
+
* - sketch: Quick project outline
|
|
7
|
+
* - refine: Refine existing requirements
|
|
8
|
+
* - arch: Create architecture documentation
|
|
9
|
+
*/
|
|
10
|
+
import type { CommandHandler } from '../handler-types.js';
|
|
11
|
+
export declare const designCommand: CommandHandler;
|
|
12
|
+
export declare const sketchCommand: CommandHandler;
|
|
13
|
+
export declare const refineCommand: CommandHandler;
|
|
14
|
+
export declare const archCommand: CommandHandler;
|
|
15
|
+
export declare const designCommands: CommandHandler[];
|