@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
package/dist/index.js
CHANGED
|
@@ -9,26 +9,31 @@ process.env.FORCE_COLOR = '3';
|
|
|
9
9
|
* A terminal-based REPL for interacting with AI agents.
|
|
10
10
|
*/
|
|
11
11
|
import { createAgent } from './agent.js';
|
|
12
|
-
import {
|
|
12
|
+
import { ReplV2 } from './repl-v2.js';
|
|
13
|
+
import * as fs from 'fs';
|
|
13
14
|
import * as diff from './ui/diff.js';
|
|
14
15
|
import * as terminal from './ui/terminal.js';
|
|
15
16
|
import { getStyles } from './themes/index.js';
|
|
16
|
-
import { getDefaultProvider, getDefaultModel as getDefaultModelSetting } from './settings/index.js';
|
|
17
|
+
import { getDefaultProvider, getDefaultModel as getDefaultModelSetting, getProjectStartupMode, getLastProjectId } from './settings/index.js';
|
|
17
18
|
import { showAskUserOverlay } from './ui/ask-user-overlay.js';
|
|
18
19
|
import { showAskUserSimpleOverlay } from './ui/ask-user-simple-overlay.js';
|
|
19
20
|
import { showPermissionOverlay } from './ui/permission-overlay.js';
|
|
20
21
|
import { showIterationLimitOverlay } from './ui/iteration-limit-overlay.js';
|
|
22
|
+
import { showGuardrailOverlay } from './ui/guardrail-overlay.js';
|
|
21
23
|
import { showKeysOverlay } from './ui/keys-overlay.js';
|
|
24
|
+
import { projectRepository, workItemRepository } from './db/repositories/index.js';
|
|
25
|
+
import { setActiveProject } from './tools/project-db.js';
|
|
26
|
+
import { getFullGuidedPrompt, shouldInjectGuidedContext, } from './workflow/index.js';
|
|
22
27
|
import { hasApiKey, settingsProviderToCredentialKey } from './utils/credentials.js';
|
|
23
|
-
import { printLogo } from './ui/conversation.js';
|
|
24
28
|
import { loadProjectMemory, formatBytes, getSizeCategory } from './utils/project-memory.js';
|
|
29
|
+
import { getGlobalAnchorManager, getAnchorManager } from './anchors/index.js';
|
|
25
30
|
import { registerAskUserHandler, registerAskUserSimpleHandler, setOverlayActive, } from './shared-handlers.js';
|
|
26
31
|
import chalk from 'chalk';
|
|
27
32
|
const sharedState = { mode: 'normal', pendingSuggestion: null };
|
|
28
33
|
// =============================================================================
|
|
29
34
|
// Version
|
|
30
35
|
// =============================================================================
|
|
31
|
-
const VERSION = '0.0
|
|
36
|
+
const VERSION = '0.4.0';
|
|
32
37
|
function parseArgs() {
|
|
33
38
|
const args = process.argv.slice(2);
|
|
34
39
|
const options = {};
|
|
@@ -83,8 +88,6 @@ Examples:
|
|
|
83
88
|
// =============================================================================
|
|
84
89
|
async function main() {
|
|
85
90
|
const options = parseArgs();
|
|
86
|
-
// Show logo immediately on startup
|
|
87
|
-
printLogo(VERSION);
|
|
88
91
|
// Resolve provider: CLI arg > settings > auto-detect
|
|
89
92
|
const settingsProvider = getDefaultProvider();
|
|
90
93
|
const provider = options.provider
|
|
@@ -136,13 +139,146 @@ async function main() {
|
|
|
136
139
|
}
|
|
137
140
|
projectContext = projectMemory.content;
|
|
138
141
|
}
|
|
142
|
+
// ==========================================================================
|
|
143
|
+
// Load guided mode context from database (if project uses guided mode)
|
|
144
|
+
// ==========================================================================
|
|
145
|
+
let guidedModeContext;
|
|
146
|
+
// Determine which project to load based on projectStartup setting
|
|
147
|
+
const projectStartupMode = getProjectStartupMode();
|
|
148
|
+
let dbProject = null;
|
|
149
|
+
if (projectStartupMode === 'last') {
|
|
150
|
+
// Try to load the last opened project
|
|
151
|
+
const lastProjectId = getLastProjectId();
|
|
152
|
+
if (lastProjectId !== null) {
|
|
153
|
+
dbProject = projectRepository.getById(lastProjectId);
|
|
154
|
+
// If last project no longer exists (deleted), don't auto-load any project
|
|
155
|
+
}
|
|
156
|
+
// If no lastProjectId remembered, don't auto-load any project
|
|
157
|
+
}
|
|
158
|
+
// else projectStartupMode === 'off': don't auto-load any project
|
|
159
|
+
if (dbProject) {
|
|
160
|
+
// Set as active project for tools to use
|
|
161
|
+
setActiveProject({ id: dbProject.id, name: dbProject.name, displayName: dbProject.displayName, path: dbProject.path });
|
|
162
|
+
// If in guided mode, generate context
|
|
163
|
+
if (shouldInjectGuidedContext(dbProject)) {
|
|
164
|
+
// Get work item counts
|
|
165
|
+
const statusCounts = workItemRepository.getStatusCounts(dbProject.id);
|
|
166
|
+
// Get current work item if set
|
|
167
|
+
let currentItem = null;
|
|
168
|
+
if (dbProject.currentItemId) {
|
|
169
|
+
currentItem = workItemRepository.getByItemId(dbProject.id, dbProject.currentItemId);
|
|
170
|
+
}
|
|
171
|
+
else {
|
|
172
|
+
// Look for any in-progress item
|
|
173
|
+
const inProgressItems = workItemRepository.query({
|
|
174
|
+
project_id: dbProject.id,
|
|
175
|
+
status: 'in_progress',
|
|
176
|
+
limit: 1,
|
|
177
|
+
});
|
|
178
|
+
if (inProgressItems.items.length > 0) {
|
|
179
|
+
currentItem = inProgressItems.items[0];
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
// Generate guided mode context
|
|
183
|
+
const contextOptions = {
|
|
184
|
+
project: dbProject,
|
|
185
|
+
currentItem,
|
|
186
|
+
backlogCount: statusCounts.backlog,
|
|
187
|
+
inProgressCount: statusCounts.in_progress,
|
|
188
|
+
completedCount: statusCounts.completed,
|
|
189
|
+
};
|
|
190
|
+
guidedModeContext = getFullGuidedPrompt(contextOptions);
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
// ==========================================================================
|
|
194
|
+
// Load persisted anchors (critical info that survives compaction)
|
|
195
|
+
// ==========================================================================
|
|
196
|
+
// Load global anchors (always)
|
|
197
|
+
const globalAnchors = getGlobalAnchorManager().getAll({ scope: 'persistent' });
|
|
198
|
+
// Load project-specific anchors (if in a tracked project)
|
|
199
|
+
const projectAnchors = dbProject
|
|
200
|
+
? getAnchorManager(String(dbProject.id)).getAll({ scope: 'persistent' })
|
|
201
|
+
: [];
|
|
202
|
+
// Combine into persistedAnchors array for agent
|
|
203
|
+
const persistedAnchors = [
|
|
204
|
+
...globalAnchors.map((a) => ({
|
|
205
|
+
id: a.id,
|
|
206
|
+
content: a.content,
|
|
207
|
+
priority: a.priority,
|
|
208
|
+
scope: a.scope,
|
|
209
|
+
tags: a.tags,
|
|
210
|
+
})),
|
|
211
|
+
...projectAnchors.map((a) => ({
|
|
212
|
+
id: a.id,
|
|
213
|
+
content: a.content,
|
|
214
|
+
priority: a.priority,
|
|
215
|
+
scope: a.scope,
|
|
216
|
+
tags: a.tags,
|
|
217
|
+
projectId: String(dbProject?.id),
|
|
218
|
+
})),
|
|
219
|
+
];
|
|
220
|
+
// ==========================================================================
|
|
221
|
+
// Create handlers and agent BEFORE menu (so menu can access agent info)
|
|
222
|
+
// ==========================================================================
|
|
139
223
|
// Create permission handler that respects mode state
|
|
140
224
|
const onPermissionRequest = async (request) => {
|
|
141
225
|
// Auto-accept mode: allow everything without prompting
|
|
142
226
|
if (sharedState.mode === 'auto-accept') {
|
|
143
227
|
return true;
|
|
144
228
|
}
|
|
145
|
-
//
|
|
229
|
+
// V2 mode: use TerminalUI overlay system
|
|
230
|
+
if (sharedState.showPermissionOverlayV2) {
|
|
231
|
+
// Flush any accumulated text BEFORE showing the permission overlay
|
|
232
|
+
// This ensures agent's "I'll help you..." text appears before the permission prompt
|
|
233
|
+
sharedState.flushTextBuffer?.();
|
|
234
|
+
// For edit operations, pre-render diff lines for the overlay
|
|
235
|
+
let diffLines;
|
|
236
|
+
if (request.toolName === 'edit') {
|
|
237
|
+
// DEBUG: Write to file to see field names (temporary)
|
|
238
|
+
fs.appendFileSync('/tmp/compilr-debug.log', `[${new Date().toISOString()}] edit request.input: ${JSON.stringify(request.input)}\n`);
|
|
239
|
+
const filePath = ((typeof request.input.filePath === 'string' ? request.input.filePath : null) ||
|
|
240
|
+
(typeof request.input.file_path === 'string' ? request.input.file_path : null) ||
|
|
241
|
+
(typeof request.input.path === 'string' ? request.input.path : null) || '');
|
|
242
|
+
const oldText = ((typeof request.input.oldString === 'string' ? request.input.oldString : null) ||
|
|
243
|
+
(typeof request.input.old_string === 'string' ? request.input.old_string : null) ||
|
|
244
|
+
(typeof request.input.old_text === 'string' ? request.input.old_text : null) || '');
|
|
245
|
+
const newText = ((typeof request.input.newString === 'string' ? request.input.newString : null) ||
|
|
246
|
+
(typeof request.input.new_string === 'string' ? request.input.new_string : null) ||
|
|
247
|
+
(typeof request.input.new_text === 'string' ? request.input.new_text : null) || '');
|
|
248
|
+
const replaceAll = Boolean(request.input.replaceAll);
|
|
249
|
+
// DEBUG: Log extracted values
|
|
250
|
+
fs.appendFileSync('/tmp/compilr-debug.log', ` filePath: "${filePath}", oldText len: ${String(oldText.length)}, newText len: ${String(newText.length)}, replaceAll: ${String(replaceAll)}\n`);
|
|
251
|
+
if (filePath && oldText && newText) {
|
|
252
|
+
const editDiff = diff.generateEditDiff(filePath, oldText, newText, replaceAll);
|
|
253
|
+
fs.appendFileSync('/tmp/compilr-debug.log', ` editDiff: ${editDiff ? `${String(editDiff.lines.length)} lines` : 'null'}\n`);
|
|
254
|
+
if (editDiff) {
|
|
255
|
+
const s = getStyles();
|
|
256
|
+
diffLines = [
|
|
257
|
+
s.warning('● ') + chalk.bold(`Edit(${filePath.split('/').pop() ?? 'unknown'})`),
|
|
258
|
+
diff.formatDiffHeader(filePath, editDiff.additions, editDiff.removals),
|
|
259
|
+
...editDiff.lines,
|
|
260
|
+
];
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
const result = await sharedState.showPermissionOverlayV2({
|
|
265
|
+
toolName: request.toolName,
|
|
266
|
+
args: request.input,
|
|
267
|
+
description: request.description,
|
|
268
|
+
diffLines,
|
|
269
|
+
});
|
|
270
|
+
// Handle result
|
|
271
|
+
if (result === 'allow-always') {
|
|
272
|
+
sharedState.grantSession?.(request.toolName);
|
|
273
|
+
sharedState.setMode?.('auto-accept');
|
|
274
|
+
}
|
|
275
|
+
// null result means cancelled, treat as deny
|
|
276
|
+
return result !== null && result !== 'deny';
|
|
277
|
+
}
|
|
278
|
+
// Legacy mode: show permission prompt with manual footer coordination
|
|
279
|
+
// Flush any accumulated text BEFORE showing the permission overlay
|
|
280
|
+
// This ensures agent's "I'll help you..." text appears before the permission prompt
|
|
281
|
+
sharedState.flushTextBuffer?.();
|
|
146
282
|
// Pause footer to prevent interference with the overlay
|
|
147
283
|
sharedState.pauseFooter?.();
|
|
148
284
|
// Set overlay active flag so REPL buffers any text output
|
|
@@ -204,8 +340,20 @@ async function main() {
|
|
|
204
340
|
};
|
|
205
341
|
// Register ask_user handler that coordinates with footer
|
|
206
342
|
registerAskUserHandler(async (input) => {
|
|
207
|
-
//
|
|
343
|
+
// Wait for event loop to process any pending tool_end events
|
|
344
|
+
await new Promise((resolve) => setImmediate(resolve));
|
|
345
|
+
// Flush any accumulated text BEFORE showing the overlay
|
|
346
|
+
sharedState.flushTextBuffer?.();
|
|
347
|
+
// V2 mode: use TerminalUI overlay system
|
|
348
|
+
if (sharedState.showAskUserOverlayV2) {
|
|
349
|
+
return sharedState.showAskUserOverlayV2({
|
|
350
|
+
questions: input.questions,
|
|
351
|
+
context: input.context,
|
|
352
|
+
});
|
|
353
|
+
}
|
|
354
|
+
// Legacy mode: pause footer and use InlineOverlay
|
|
208
355
|
sharedState.pauseFooter?.();
|
|
356
|
+
setOverlayActive(true);
|
|
209
357
|
try {
|
|
210
358
|
// Show the overlay and get answers
|
|
211
359
|
const result = await showAskUserOverlay({
|
|
@@ -215,14 +363,28 @@ async function main() {
|
|
|
215
363
|
return result;
|
|
216
364
|
}
|
|
217
365
|
finally {
|
|
218
|
-
//
|
|
366
|
+
// Clear overlay active flag and resume footer
|
|
367
|
+
setOverlayActive(false);
|
|
219
368
|
sharedState.resumeFooter?.();
|
|
220
369
|
}
|
|
221
370
|
});
|
|
222
371
|
// Register ask_user_simple handler for smaller models (flat schema)
|
|
223
372
|
registerAskUserSimpleHandler(async (input) => {
|
|
224
|
-
//
|
|
373
|
+
// Wait for event loop to process any pending tool_end events
|
|
374
|
+
await new Promise((resolve) => setImmediate(resolve));
|
|
375
|
+
// Flush any accumulated text BEFORE showing the overlay
|
|
376
|
+
sharedState.flushTextBuffer?.();
|
|
377
|
+
// V2 mode: use TerminalUI overlay system
|
|
378
|
+
if (sharedState.showAskUserSimpleOverlayV2) {
|
|
379
|
+
return sharedState.showAskUserSimpleOverlayV2({
|
|
380
|
+
question: input.question,
|
|
381
|
+
options: input.options,
|
|
382
|
+
allowCustom: input.allowCustom,
|
|
383
|
+
});
|
|
384
|
+
}
|
|
385
|
+
// Legacy mode: pause footer and use InlineOverlay
|
|
225
386
|
sharedState.pauseFooter?.();
|
|
387
|
+
setOverlayActive(true);
|
|
226
388
|
try {
|
|
227
389
|
// Show the simple overlay and get answer
|
|
228
390
|
const result = await showAskUserSimpleOverlay({
|
|
@@ -233,13 +395,30 @@ async function main() {
|
|
|
233
395
|
return result;
|
|
234
396
|
}
|
|
235
397
|
finally {
|
|
236
|
-
//
|
|
398
|
+
// Clear overlay active flag and resume footer
|
|
399
|
+
setOverlayActive(false);
|
|
237
400
|
sharedState.resumeFooter?.();
|
|
238
401
|
}
|
|
239
402
|
});
|
|
240
403
|
// Create iteration limit handler that shows overlay
|
|
241
404
|
const onIterationLimitReached = async (context) => {
|
|
242
|
-
//
|
|
405
|
+
// Wait for event loop to process any pending tool_end events
|
|
406
|
+
await new Promise((resolve) => setImmediate(resolve));
|
|
407
|
+
// Flush any accumulated text BEFORE showing the overlay
|
|
408
|
+
sharedState.flushTextBuffer?.();
|
|
409
|
+
// V2 mode: use TerminalUI overlay system
|
|
410
|
+
if (sharedState.showIterationLimitOverlayV2) {
|
|
411
|
+
const result = await sharedState.showIterationLimitOverlayV2({
|
|
412
|
+
iteration: context.iteration,
|
|
413
|
+
maxIterations: context.maxIterations,
|
|
414
|
+
toolCallCount: context.toolCallCount,
|
|
415
|
+
});
|
|
416
|
+
if (result.continue) {
|
|
417
|
+
return result.additionalIterations;
|
|
418
|
+
}
|
|
419
|
+
return false;
|
|
420
|
+
}
|
|
421
|
+
// Legacy mode: pause footer and use InlineOverlay
|
|
243
422
|
sharedState.pauseFooter?.();
|
|
244
423
|
setOverlayActive(true);
|
|
245
424
|
try {
|
|
@@ -259,6 +438,38 @@ async function main() {
|
|
|
259
438
|
sharedState.resumeFooter?.();
|
|
260
439
|
}
|
|
261
440
|
};
|
|
441
|
+
// Create guardrail confirmation handler (for risky operations that need approval)
|
|
442
|
+
const onGuardrailTriggered = async (result, context) => {
|
|
443
|
+
// Wait for event loop to process any pending events
|
|
444
|
+
await new Promise((resolve) => setImmediate(resolve));
|
|
445
|
+
// Flush any accumulated text BEFORE showing the overlay
|
|
446
|
+
sharedState.flushTextBuffer?.();
|
|
447
|
+
const overlayOptions = {
|
|
448
|
+
name: result.guardrail?.name ?? 'Unknown Guardrail',
|
|
449
|
+
message: result.guardrail?.message ?? 'This operation requires confirmation.',
|
|
450
|
+
action: result.guardrail?.action ?? 'confirm',
|
|
451
|
+
toolName: context.toolName,
|
|
452
|
+
matchedInput: result.match ?? context.inputString,
|
|
453
|
+
category: result.guardrail?.tags?.[0],
|
|
454
|
+
};
|
|
455
|
+
// V2 mode: use TerminalUI overlay system
|
|
456
|
+
if (sharedState.showGuardrailOverlayV2) {
|
|
457
|
+
const overlayResult = await sharedState.showGuardrailOverlayV2(overlayOptions);
|
|
458
|
+
return overlayResult.approved;
|
|
459
|
+
}
|
|
460
|
+
// Legacy mode: pause footer and use InlineOverlay
|
|
461
|
+
sharedState.pauseFooter?.();
|
|
462
|
+
setOverlayActive(true);
|
|
463
|
+
try {
|
|
464
|
+
const overlayResult = await showGuardrailOverlay(overlayOptions);
|
|
465
|
+
return overlayResult.approved;
|
|
466
|
+
}
|
|
467
|
+
finally {
|
|
468
|
+
// Clear overlay active flag and resume footer
|
|
469
|
+
setOverlayActive(false);
|
|
470
|
+
sharedState.resumeFooter?.();
|
|
471
|
+
}
|
|
472
|
+
};
|
|
262
473
|
// Create agent with permission handler and suggestion callback
|
|
263
474
|
const agent = createAgent({
|
|
264
475
|
provider,
|
|
@@ -271,46 +482,94 @@ async function main() {
|
|
|
271
482
|
sharedState.pendingSuggestion = event.action;
|
|
272
483
|
},
|
|
273
484
|
projectContext,
|
|
485
|
+
guidedModeContext,
|
|
486
|
+
// Anchors - library handles re-injection on every LLM call
|
|
487
|
+
enableAnchors: true,
|
|
488
|
+
persistedAnchors: persistedAnchors.length > 0 ? persistedAnchors : undefined,
|
|
489
|
+
// Guardrails - 15 built-in safety patterns for risky operations
|
|
490
|
+
// Warnings are emitted as 'guardrail_warning' events and handled by REPL
|
|
491
|
+
enableGuardrails: true,
|
|
492
|
+
onGuardrailTriggered,
|
|
493
|
+
// Subagent tracking callbacks (forwarded to footer via sharedState)
|
|
494
|
+
// Now using toolUseId for direct correlation (no more FIFO matching)
|
|
495
|
+
onSubagentStart: (toolUseId, agentType, description) => {
|
|
496
|
+
sharedState.onSubagentStart?.(toolUseId, agentType, description);
|
|
497
|
+
},
|
|
498
|
+
onSubagentEnd: (toolUseId, success, tokenCount, error) => {
|
|
499
|
+
sharedState.onSubagentEnd?.(toolUseId, success, tokenCount, error);
|
|
500
|
+
},
|
|
501
|
+
onSubagentToolUse: (toolUseId, toolName, summary) => {
|
|
502
|
+
sharedState.onSubagentToolUse?.(toolUseId, toolName, summary);
|
|
503
|
+
},
|
|
504
|
+
// Receive function to clear subagent tracking between runs
|
|
505
|
+
onSubagentTrackingReady: (clearTracking) => {
|
|
506
|
+
sharedState.clearSubagentTracking = clearTracking;
|
|
507
|
+
},
|
|
274
508
|
});
|
|
275
509
|
// Bind grantSession for the permission handler to use
|
|
276
510
|
sharedState.grantSession = (toolName) => {
|
|
277
511
|
agent.grantSessionPermission(toolName);
|
|
278
512
|
};
|
|
279
|
-
//
|
|
280
|
-
// Create and run REPL
|
|
281
|
-
|
|
513
|
+
// ==========================================================================
|
|
514
|
+
// Create and run REPL
|
|
515
|
+
// ==========================================================================
|
|
516
|
+
const replV2 = new ReplV2({
|
|
282
517
|
agent,
|
|
283
518
|
model,
|
|
284
519
|
provider,
|
|
285
520
|
version: VERSION,
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
521
|
+
projectName: dbProject?.displayName ?? process.cwd().split('/').pop(),
|
|
522
|
+
// Set up V2 permission overlay callback when UI is ready
|
|
523
|
+
onUIReady: (showOverlay) => {
|
|
524
|
+
sharedState.showPermissionOverlayV2 = showOverlay;
|
|
525
|
+
},
|
|
526
|
+
// Set up text buffer flush callback for V2 mode
|
|
527
|
+
onTextBufferReady: (flushTextBuffer) => {
|
|
528
|
+
sharedState.flushTextBuffer = flushTextBuffer;
|
|
529
|
+
},
|
|
530
|
+
// Set up ask_user_simple V2 overlay callback
|
|
531
|
+
onAskUserSimpleReady: (showOverlay) => {
|
|
532
|
+
sharedState.showAskUserSimpleOverlayV2 = showOverlay;
|
|
533
|
+
},
|
|
534
|
+
// Set up guardrail V2 overlay callback
|
|
535
|
+
onGuardrailReady: (showOverlay) => {
|
|
536
|
+
sharedState.showGuardrailOverlayV2 = showOverlay;
|
|
289
537
|
},
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
sharedState.
|
|
538
|
+
// Set up ask_user V2 overlay callback
|
|
539
|
+
onAskUserReady: (showOverlay) => {
|
|
540
|
+
sharedState.showAskUserOverlayV2 = showOverlay;
|
|
541
|
+
},
|
|
542
|
+
// Set up iteration_limit V2 overlay callback
|
|
543
|
+
onIterationLimitReady: (showOverlay) => {
|
|
544
|
+
sharedState.showIterationLimitOverlayV2 = showOverlay;
|
|
545
|
+
},
|
|
546
|
+
// Set up subagent tracking callbacks for LiveRegion rendering
|
|
547
|
+
onSubagentReady: (callbacks) => {
|
|
548
|
+
sharedState.onSubagentStart = callbacks.onStart;
|
|
549
|
+
sharedState.onSubagentToolUse = callbacks.onToolUse;
|
|
550
|
+
sharedState.onSubagentEnd = callbacks.onEnd;
|
|
551
|
+
},
|
|
552
|
+
// Pass function to clear agent.ts subagent tracking between runs
|
|
553
|
+
clearSubagentTracking: sharedState.clearSubagentTracking,
|
|
554
|
+
// Set up suggestion callback when UI is ready
|
|
555
|
+
onSuggestionReady: (setSuggestion) => {
|
|
293
556
|
sharedState.setSuggestion = setSuggestion;
|
|
294
557
|
},
|
|
558
|
+
// Apply pending suggestions when agent finishes
|
|
295
559
|
onAgentFinish: () => {
|
|
296
|
-
// Apply any pending suggestion now that agent has finished
|
|
297
560
|
if (sharedState.pendingSuggestion) {
|
|
298
561
|
sharedState.setSuggestion?.(sharedState.pendingSuggestion);
|
|
299
562
|
sharedState.pendingSuggestion = null;
|
|
300
563
|
}
|
|
301
564
|
},
|
|
302
565
|
});
|
|
303
|
-
// Bind setMode for the permission handler to use
|
|
304
|
-
sharedState.setMode = (mode) => {
|
|
305
|
-
repl.setMode(mode);
|
|
306
|
-
};
|
|
307
566
|
// Handle Ctrl+C gracefully
|
|
308
567
|
process.on('SIGINT', () => {
|
|
309
|
-
|
|
568
|
+
replV2.stop();
|
|
310
569
|
process.exit(0);
|
|
311
570
|
});
|
|
312
|
-
|
|
313
|
-
|
|
571
|
+
replV2.start();
|
|
572
|
+
// REPL V2 runs in event loop - the ReplV2 manages its own lifecycle
|
|
314
573
|
}
|
|
315
574
|
// =============================================================================
|
|
316
575
|
// Provider Detection
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Input Handlers - Process special input prefixes
|
|
3
|
+
*
|
|
4
|
+
* Handles input that doesn't go to the agent, like:
|
|
5
|
+
* - "#" prefix for memory notes (persistent anchors)
|
|
6
|
+
*/
|
|
7
|
+
export { isMemoryInput, handleMemoryInput, type MemoryHandlerContext } from './memory-handler.js';
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Memory Handler - Process "# note" input prefix
|
|
3
|
+
*
|
|
4
|
+
* Creates persistent anchors from user input prefixed with "#".
|
|
5
|
+
* Auto-detects priority based on keywords in the note.
|
|
6
|
+
*/
|
|
7
|
+
import type { Agent } from '@compilr-dev/agents';
|
|
8
|
+
import type { Footer } from '../ui/footer.js';
|
|
9
|
+
export interface MemoryHandlerContext {
|
|
10
|
+
agent: Agent;
|
|
11
|
+
footer: Footer;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Check if input is a memory note (starts with #)
|
|
15
|
+
*/
|
|
16
|
+
export declare function isMemoryInput(input: string): boolean;
|
|
17
|
+
/**
|
|
18
|
+
* Handle memory note input ("# note text")
|
|
19
|
+
*
|
|
20
|
+
* Creates a persistent anchor from the note, stored either globally or
|
|
21
|
+
* in the current project if one is active.
|
|
22
|
+
*
|
|
23
|
+
* @param input - The full input string (including # prefix)
|
|
24
|
+
* @param ctx - Handler context with agent and footer
|
|
25
|
+
*/
|
|
26
|
+
export declare function handleMemoryInput(input: string, ctx: MemoryHandlerContext): void;
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Memory Handler - Process "# note" input prefix
|
|
3
|
+
*
|
|
4
|
+
* Creates persistent anchors from user input prefixed with "#".
|
|
5
|
+
* Auto-detects priority based on keywords in the note.
|
|
6
|
+
*/
|
|
7
|
+
import { addAnchor } from '../anchors/index.js';
|
|
8
|
+
import { getActiveProject } from '../tools/project-db.js';
|
|
9
|
+
import * as conversation from '../ui/conversation.js';
|
|
10
|
+
import * as terminal from '../ui/terminal.js';
|
|
11
|
+
// =============================================================================
|
|
12
|
+
// Handler
|
|
13
|
+
// =============================================================================
|
|
14
|
+
/**
|
|
15
|
+
* Check if input is a memory note (starts with #)
|
|
16
|
+
*/
|
|
17
|
+
export function isMemoryInput(input) {
|
|
18
|
+
return input.startsWith('#') && input.length > 1 && input.slice(1).trim().length > 0;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Handle memory note input ("# note text")
|
|
22
|
+
*
|
|
23
|
+
* Creates a persistent anchor from the note, stored either globally or
|
|
24
|
+
* in the current project if one is active.
|
|
25
|
+
*
|
|
26
|
+
* @param input - The full input string (including # prefix)
|
|
27
|
+
* @param ctx - Handler context with agent and footer
|
|
28
|
+
*/
|
|
29
|
+
export function handleMemoryInput(input, ctx) {
|
|
30
|
+
const note = input.slice(1).trim();
|
|
31
|
+
// Get active project to determine scope
|
|
32
|
+
const activeProject = getActiveProject();
|
|
33
|
+
const projectId = activeProject?.id;
|
|
34
|
+
// Determine priority based on keywords
|
|
35
|
+
let priority = 'info';
|
|
36
|
+
const lowerNote = note.toLowerCase();
|
|
37
|
+
if (lowerNote.includes('never') || lowerNote.includes('always') || lowerNote.includes('must')) {
|
|
38
|
+
priority = 'safety';
|
|
39
|
+
}
|
|
40
|
+
if (lowerNote.includes('critical') || lowerNote.includes('important')) {
|
|
41
|
+
priority = 'critical';
|
|
42
|
+
}
|
|
43
|
+
// Create the anchor (persisted to file)
|
|
44
|
+
const anchor = addAnchor({
|
|
45
|
+
content: note,
|
|
46
|
+
priority,
|
|
47
|
+
scope: 'persistent',
|
|
48
|
+
projectId: projectId?.toString(),
|
|
49
|
+
tags: ['user-note'],
|
|
50
|
+
});
|
|
51
|
+
// Show confirmation
|
|
52
|
+
ctx.footer.clearForOutput();
|
|
53
|
+
const scope = activeProject ? `project "${activeProject.displayName || activeProject.name}"` : 'global';
|
|
54
|
+
const priorityLabel = priority === 'info' ? '' : ` (${priority})`;
|
|
55
|
+
conversation.printSuccess(`Saved${priorityLabel}: "${note.length > 50 ? note.slice(0, 47) + '...' : note}" → ${scope}`);
|
|
56
|
+
terminal.writeLine('');
|
|
57
|
+
ctx.footer.forceRender();
|
|
58
|
+
// Also add to agent's anchor manager if enabled (for current session)
|
|
59
|
+
if (ctx.agent.getAnchorManager()) {
|
|
60
|
+
ctx.agent.addAnchor({
|
|
61
|
+
id: anchor.id,
|
|
62
|
+
content: note,
|
|
63
|
+
priority,
|
|
64
|
+
scope: 'persistent',
|
|
65
|
+
tags: ['user-note'],
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* REPL Helper Functions
|
|
3
|
+
*
|
|
4
|
+
* Standalone utility functions extracted from repl.ts to reduce file size
|
|
5
|
+
* and improve maintainability. These functions support the REPL but don't
|
|
6
|
+
* depend on REPL instance state.
|
|
7
|
+
*/
|
|
8
|
+
import type { BacklogItem } from './tools/backlog.js';
|
|
9
|
+
/**
|
|
10
|
+
* Keyword patterns for tool selection based on user input.
|
|
11
|
+
* Maps tool names to keywords that suggest the tool should be used.
|
|
12
|
+
*/
|
|
13
|
+
export declare const TOOL_KEYWORDS: Record<string, string[]>;
|
|
14
|
+
/**
|
|
15
|
+
* Select relevant tool names based on user input intent.
|
|
16
|
+
* Returns all tools if input is short or a question.
|
|
17
|
+
*/
|
|
18
|
+
export declare function selectToolNamesByIntent(input: string, allToolNames: string[]): string[];
|
|
19
|
+
/**
|
|
20
|
+
* Priority order for sorting backlog items (most important first).
|
|
21
|
+
*/
|
|
22
|
+
export declare const PRIORITY_ORDER: string[];
|
|
23
|
+
/**
|
|
24
|
+
* Result of detecting a compilr project structure.
|
|
25
|
+
*/
|
|
26
|
+
export interface CompilrProjectInfo {
|
|
27
|
+
found: boolean;
|
|
28
|
+
backlogPath: string | null;
|
|
29
|
+
projectPath: string | null;
|
|
30
|
+
docsPath: string | null;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Detect if we're in a compilr project (has .compilr folder or -docs sibling).
|
|
34
|
+
* Returns project path from config.json if available.
|
|
35
|
+
*/
|
|
36
|
+
export declare function detectCompilrProject(): CompilrProjectInfo;
|
|
37
|
+
/**
|
|
38
|
+
* Check if backlog has any items using the shared parser.
|
|
39
|
+
*/
|
|
40
|
+
export declare function hasBacklogItems(backlogPath: string | null): boolean;
|
|
41
|
+
/**
|
|
42
|
+
* Get skill prompt by name from builtinSkills or codingSkills.
|
|
43
|
+
*/
|
|
44
|
+
export declare function getSkillPrompt(name: string): string | null;
|
|
45
|
+
/**
|
|
46
|
+
* Select the best backlog item to build.
|
|
47
|
+
* If requestedId is provided, finds that specific item.
|
|
48
|
+
* Otherwise, auto-picks the highest priority 📋 item.
|
|
49
|
+
*/
|
|
50
|
+
export declare function selectBuildItem(items: BacklogItem[], requestedId?: string): BacklogItem | null;
|
|
51
|
+
/**
|
|
52
|
+
* Find dependency IDs mentioned in item title/description.
|
|
53
|
+
* Looks for patterns like "depends on REQ-001", "blocked by BUG-002", etc.
|
|
54
|
+
*/
|
|
55
|
+
export declare function findDependencies(item: BacklogItem): string[];
|
|
56
|
+
/**
|
|
57
|
+
* Get list of dependencies that are not yet completed.
|
|
58
|
+
*/
|
|
59
|
+
export declare function getUnmetDependencies(item: BacklogItem, allItems: BacklogItem[]): BacklogItem[];
|
|
60
|
+
/**
|
|
61
|
+
* Check if the project has a code foundation (src/, package.json, etc.)
|
|
62
|
+
*/
|
|
63
|
+
export declare function hasProjectFoundation(): boolean;
|