@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
|
@@ -2,13 +2,13 @@
|
|
|
2
2
|
* Permission Overlay
|
|
3
3
|
*
|
|
4
4
|
* Modal overlay for tool permission requests.
|
|
5
|
-
*
|
|
5
|
+
* Renders inline above the footer using InlineOverlay base class.
|
|
6
6
|
*/
|
|
7
7
|
import chalk from 'chalk';
|
|
8
|
-
import * as terminal from './terminal.js';
|
|
9
8
|
import { getStyles } from '../themes/index.js';
|
|
9
|
+
import { InlineOverlay } from './base/inline-overlay.js';
|
|
10
10
|
// =============================================================================
|
|
11
|
-
// Helpers
|
|
11
|
+
// Helpers (unchanged from original)
|
|
12
12
|
// =============================================================================
|
|
13
13
|
/**
|
|
14
14
|
* Format a value for display, handling nested structures
|
|
@@ -16,7 +16,6 @@ import { getStyles } from '../themes/index.js';
|
|
|
16
16
|
*/
|
|
17
17
|
function formatValue(value, maxLen) {
|
|
18
18
|
if (typeof value === 'string') {
|
|
19
|
-
// Replace all newlines with ↵ to prevent multi-line rendering
|
|
20
19
|
const singleLine = value.replace(/\r?\n|\r/g, '↵');
|
|
21
20
|
return singleLine.length > maxLen ? singleLine.slice(0, maxLen) + '...' : singleLine;
|
|
22
21
|
}
|
|
@@ -26,18 +25,19 @@ function formatValue(value, maxLen) {
|
|
|
26
25
|
if (Array.isArray(value)) {
|
|
27
26
|
if (value.length === 0)
|
|
28
27
|
return '[]';
|
|
29
|
-
// Show array contents briefly
|
|
30
28
|
const items = value.slice(0, 3).map((item) => {
|
|
31
29
|
if (typeof item === 'object' && item !== null) {
|
|
32
|
-
// For objects in array, show key highlights
|
|
33
30
|
const obj = item;
|
|
34
31
|
const keys = Object.keys(obj);
|
|
35
32
|
if (keys.length === 0)
|
|
36
33
|
return '{}';
|
|
37
|
-
const preview = keys
|
|
34
|
+
const preview = keys
|
|
35
|
+
.slice(0, 2)
|
|
36
|
+
.map((k) => {
|
|
38
37
|
const v = obj[k];
|
|
39
38
|
return `${k}: ${formatValue(v, 20)}`;
|
|
40
|
-
})
|
|
39
|
+
})
|
|
40
|
+
.join(', ');
|
|
41
41
|
return `{${preview}${keys.length > 2 ? ', ...' : ''}}`;
|
|
42
42
|
}
|
|
43
43
|
return formatValue(item, 20);
|
|
@@ -51,21 +51,20 @@ function formatValue(value, maxLen) {
|
|
|
51
51
|
const keys = Object.keys(obj);
|
|
52
52
|
if (keys.length === 0)
|
|
53
53
|
return '{}';
|
|
54
|
-
const preview = keys
|
|
54
|
+
const preview = keys
|
|
55
|
+
.slice(0, 3)
|
|
56
|
+
.map((k) => `${k}: ${formatValue(obj[k], 15)}`)
|
|
57
|
+
.join(', ');
|
|
55
58
|
return keys.length > 3 ? `{${preview}, ...}` : `{${preview}}`;
|
|
56
59
|
}
|
|
57
60
|
return String(value);
|
|
58
61
|
}
|
|
59
62
|
/**
|
|
60
63
|
* Format tool args for display.
|
|
61
|
-
* - For bash commands: show the command prominently
|
|
62
|
-
* - For file operations: show the path
|
|
63
|
-
* - For backlog operations: show action and details clearly
|
|
64
|
-
* - Strip JSON syntax for readability
|
|
65
64
|
*/
|
|
66
65
|
function formatArgs(toolName, args, maxWidth) {
|
|
67
66
|
const lines = [];
|
|
68
|
-
// Special handling for bash commands
|
|
67
|
+
// Special handling for bash commands
|
|
69
68
|
if (toolName === 'bash' && typeof args.command === 'string') {
|
|
70
69
|
const cmd = args.command;
|
|
71
70
|
const prefix = 'Command: ';
|
|
@@ -76,51 +75,13 @@ function formatArgs(toolName, args, maxWidth) {
|
|
|
76
75
|
else {
|
|
77
76
|
lines.push(prefix);
|
|
78
77
|
const maxCmdLength = availableWidth * 3;
|
|
79
|
-
const truncatedCmd = cmd.length > maxCmdLength
|
|
80
|
-
? cmd.slice(0, maxCmdLength) + '...'
|
|
81
|
-
: cmd;
|
|
78
|
+
const truncatedCmd = cmd.length > maxCmdLength ? cmd.slice(0, maxCmdLength) + '...' : cmd;
|
|
82
79
|
lines.push(' ' + truncatedCmd);
|
|
83
80
|
}
|
|
84
81
|
return lines;
|
|
85
82
|
}
|
|
86
|
-
//
|
|
87
|
-
|
|
88
|
-
const action = args.action;
|
|
89
|
-
if (action) {
|
|
90
|
-
lines.push(`Action: ${action}`);
|
|
91
|
-
}
|
|
92
|
-
// For updates, show what's being changed
|
|
93
|
-
if (action === 'update' && args.id) {
|
|
94
|
-
lines.push(`Item: ${typeof args.id === 'string' ? args.id : JSON.stringify(args.id)}`);
|
|
95
|
-
if (args.updates && typeof args.updates === 'object') {
|
|
96
|
-
const updates = args.updates;
|
|
97
|
-
const changes = Object.entries(updates)
|
|
98
|
-
.map(([k, v]) => `${k} → ${formatValue(v, 25)}`)
|
|
99
|
-
.join(', ');
|
|
100
|
-
const maxChangesWidth = maxWidth - 14;
|
|
101
|
-
lines.push(`Changes: ${changes.length > maxChangesWidth ? changes.slice(0, maxChangesWidth - 3) + '...' : changes}`);
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
// For add, show what's being added
|
|
105
|
-
if (action === 'add' && args.item && typeof args.item === 'object') {
|
|
106
|
-
const item = args.item;
|
|
107
|
-
if (item.id)
|
|
108
|
-
lines.push(`ID: ${typeof item.id === 'string' ? item.id : JSON.stringify(item.id)}`);
|
|
109
|
-
if (item.title) {
|
|
110
|
-
const maxTitleLen = maxWidth - 12;
|
|
111
|
-
const titleStr = formatValue(item.title, maxTitleLen);
|
|
112
|
-
lines.push(`Title: ${titleStr}`);
|
|
113
|
-
}
|
|
114
|
-
if (item.type)
|
|
115
|
-
lines.push(`Type: ${typeof item.type === 'string' ? item.type : JSON.stringify(item.type)}`);
|
|
116
|
-
}
|
|
117
|
-
// For delete, show what's being removed
|
|
118
|
-
if (action === 'delete' && args.id) {
|
|
119
|
-
lines.push(`Deleting: ${typeof args.id === 'string' ? args.id : JSON.stringify(args.id)}`);
|
|
120
|
-
}
|
|
121
|
-
return lines;
|
|
122
|
-
}
|
|
123
|
-
// Special handling for edit tool - show what's being changed
|
|
83
|
+
// Note: backlog_write special handling removed - tool deprecated in favor of workitem_* tools
|
|
84
|
+
// Special handling for edit tool
|
|
124
85
|
if (toolName === 'edit') {
|
|
125
86
|
const path = args.path ?? args.file_path ?? args.filePath;
|
|
126
87
|
if (typeof path === 'string') {
|
|
@@ -131,24 +92,23 @@ function formatArgs(toolName, args, maxWidth) {
|
|
|
131
92
|
const oldText = args.old_text ?? args.oldText ?? args.old_string ?? args.oldString;
|
|
132
93
|
const newText = args.new_text ?? args.newText ?? args.new_string ?? args.newString;
|
|
133
94
|
if (typeof oldText === 'string' && typeof newText === 'string') {
|
|
134
|
-
const maxPreview = maxWidth - 8;
|
|
95
|
+
const maxPreview = maxWidth - 8;
|
|
135
96
|
lines.push(`- ${formatValue(oldText, maxPreview)}`);
|
|
136
97
|
lines.push(`+ ${formatValue(newText, maxPreview)}`);
|
|
137
98
|
}
|
|
138
99
|
return lines;
|
|
139
100
|
}
|
|
140
|
-
// Special handling for write_file
|
|
101
|
+
// Special handling for write_file
|
|
141
102
|
if (toolName === 'write_file') {
|
|
142
103
|
const path = args.path ?? args.file_path ?? args.filePath;
|
|
143
104
|
if (typeof path === 'string') {
|
|
144
|
-
const maxPathLen = maxWidth - 10;
|
|
105
|
+
const maxPathLen = maxWidth - 10;
|
|
145
106
|
const truncPath = path.length > maxPathLen ? '...' + path.slice(-(maxPathLen - 3)) : path;
|
|
146
107
|
lines.push(`File: ${truncPath}`);
|
|
147
108
|
}
|
|
148
109
|
const content = args.content;
|
|
149
110
|
if (typeof content === 'string') {
|
|
150
|
-
const maxContentLen = maxWidth - 15;
|
|
151
|
-
// Use formatValue to handle newline replacement
|
|
111
|
+
const maxContentLen = maxWidth - 15;
|
|
152
112
|
lines.push(`Content: ${formatValue(content, maxContentLen)}`);
|
|
153
113
|
}
|
|
154
114
|
return lines;
|
|
@@ -160,14 +120,13 @@ function formatArgs(toolName, args, maxWidth) {
|
|
|
160
120
|
const truncPath = path.length > maxPathLen ? '...' + path.slice(-(maxPathLen - 3)) : path;
|
|
161
121
|
lines.push('Path: ' + truncPath);
|
|
162
122
|
}
|
|
163
|
-
// Show other args
|
|
123
|
+
// Show other args
|
|
164
124
|
const skipKeys = ['path', 'file_path', 'filePath', 'command'];
|
|
165
125
|
for (const [key, value] of Object.entries(args)) {
|
|
166
126
|
if (skipKeys.includes(key))
|
|
167
127
|
continue;
|
|
168
128
|
const valueStr = formatValue(value, maxWidth - key.length - 6);
|
|
169
129
|
const line = `${key}: ${valueStr}`;
|
|
170
|
-
// Truncate if too long
|
|
171
130
|
if (line.length > maxWidth - 4) {
|
|
172
131
|
lines.push(line.slice(0, maxWidth - 7) + '...');
|
|
173
132
|
}
|
|
@@ -186,16 +145,13 @@ function formatArgsForDetail(toolName, args, maxWidth) {
|
|
|
186
145
|
lines.push('');
|
|
187
146
|
for (const [key, value] of Object.entries(args)) {
|
|
188
147
|
if (typeof value === 'string') {
|
|
189
|
-
// For strings, show full content with word wrapping
|
|
190
148
|
lines.push(`${key}:`);
|
|
191
|
-
// Split by newlines first, then wrap each line
|
|
192
149
|
const valueLines = value.split(/\r?\n/);
|
|
193
150
|
for (const valueLine of valueLines) {
|
|
194
151
|
if (valueLine.length <= maxWidth - 4) {
|
|
195
152
|
lines.push(` ${valueLine}`);
|
|
196
153
|
}
|
|
197
154
|
else {
|
|
198
|
-
// Word wrap long lines
|
|
199
155
|
let remaining = valueLine;
|
|
200
156
|
while (remaining.length > 0) {
|
|
201
157
|
const chunk = remaining.slice(0, maxWidth - 4);
|
|
@@ -238,160 +194,181 @@ function formatArgsForDetail(toolName, args, maxWidth) {
|
|
|
238
194
|
}
|
|
239
195
|
return lines;
|
|
240
196
|
}
|
|
241
|
-
// Fixed height for detail view
|
|
197
|
+
// Fixed height for detail view
|
|
242
198
|
const DETAIL_VIEW_CONTENT_LINES = 15;
|
|
243
|
-
//
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
if (previousLineCount > 0) {
|
|
252
|
-
terminal.clearLinesAbove(previousLineCount);
|
|
199
|
+
// =============================================================================
|
|
200
|
+
// Permission Overlay Class
|
|
201
|
+
// =============================================================================
|
|
202
|
+
class PermissionOverlayImpl extends InlineOverlay {
|
|
203
|
+
options;
|
|
204
|
+
constructor(options) {
|
|
205
|
+
super();
|
|
206
|
+
this.options = options;
|
|
253
207
|
}
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
// Fixed visible area
|
|
262
|
-
state.visibleLines = DETAIL_VIEW_CONTENT_LINES;
|
|
263
|
-
state.totalLines = contentLines.length;
|
|
264
|
-
// Show content with scroll
|
|
265
|
-
const endLine = Math.min(state.scrollOffset + state.visibleLines, contentLines.length);
|
|
266
|
-
for (let i = state.scrollOffset; i < endLine; i++) {
|
|
267
|
-
const line = contentLines[i];
|
|
268
|
-
// Truncate to prevent wrapping
|
|
269
|
-
const safeLine = line.length > cols - 4 ? line.slice(0, cols - 7) + '...' : line;
|
|
270
|
-
lines.push(' ' + safeLine);
|
|
208
|
+
getInitialState() {
|
|
209
|
+
return {
|
|
210
|
+
selectedIndex: 0, // Default to "Yes"
|
|
211
|
+
showingDetail: false,
|
|
212
|
+
detailScrollOffset: 0,
|
|
213
|
+
detailContentLines: [],
|
|
214
|
+
};
|
|
271
215
|
}
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
216
|
+
render() {
|
|
217
|
+
if (this.state.showingDetail) {
|
|
218
|
+
return this.renderDetailView();
|
|
219
|
+
}
|
|
220
|
+
return this.renderMainView();
|
|
276
221
|
}
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
const isEscape = data.length === 1 && data[0] === 0x1b;
|
|
306
|
-
const isUpArrow = data.length === 3 && data[0] === 0x1b && data[1] === 0x5b && data[2] === 0x41;
|
|
307
|
-
const isDownArrow = data.length === 3 && data[0] === 0x1b && data[1] === 0x5b && data[2] === 0x42;
|
|
308
|
-
const isPageUp = data.length === 4 && data[0] === 0x1b && data[1] === 0x5b && data[2] === 0x35 && data[3] === 0x7e;
|
|
309
|
-
const isPageDown = data.length === 4 && data[0] === 0x1b && data[1] === 0x5b && data[2] === 0x36 && data[3] === 0x7e;
|
|
310
|
-
const key = data.toString().toLowerCase();
|
|
311
|
-
// q or Escape = go back
|
|
312
|
-
if (key === 'q' || isEscape) {
|
|
313
|
-
process.stdin.removeListener('data', handleData);
|
|
314
|
-
// Clear the detail view before returning
|
|
315
|
-
terminal.clearLinesAbove(lineCount);
|
|
316
|
-
resolve(lineCount);
|
|
317
|
-
return;
|
|
318
|
-
}
|
|
319
|
-
// Scroll up
|
|
320
|
-
if (isUpArrow) {
|
|
321
|
-
state.scrollOffset = Math.max(0, state.scrollOffset - 1);
|
|
322
|
-
}
|
|
323
|
-
else if (isPageUp) {
|
|
324
|
-
state.scrollOffset = Math.max(0, state.scrollOffset - state.visibleLines);
|
|
325
|
-
}
|
|
326
|
-
// Scroll down
|
|
327
|
-
else if (isDownArrow) {
|
|
328
|
-
const maxOffset = Math.max(0, state.totalLines - state.visibleLines);
|
|
329
|
-
state.scrollOffset = Math.min(maxOffset, state.scrollOffset + 1);
|
|
222
|
+
renderMainView() {
|
|
223
|
+
const s = getStyles();
|
|
224
|
+
const lines = [];
|
|
225
|
+
const cols = this.getTerminalWidth();
|
|
226
|
+
const border = s.muted('─'.repeat(Math.max(1, cols - 1)));
|
|
227
|
+
// Header
|
|
228
|
+
lines.push(border);
|
|
229
|
+
lines.push(' ' + s.warning('⚠') + ' ' + chalk.bold('Permission Required'));
|
|
230
|
+
lines.push('');
|
|
231
|
+
// Tool info
|
|
232
|
+
lines.push(' Tool: ' + s.primary(this.options.toolName));
|
|
233
|
+
// Format and display args
|
|
234
|
+
const maxArgWidth = cols - 6;
|
|
235
|
+
const argLines = formatArgs(this.options.toolName, this.options.args, maxArgWidth);
|
|
236
|
+
for (const argLine of argLines) {
|
|
237
|
+
const safeArg = argLine.length > maxArgWidth ? argLine.slice(0, maxArgWidth - 3) + '...' : argLine;
|
|
238
|
+
lines.push(' ' + s.muted(safeArg));
|
|
239
|
+
}
|
|
240
|
+
lines.push('');
|
|
241
|
+
// Options
|
|
242
|
+
const optionLabels = ['Yes, allow this', 'No, deny', 'Always allow this tool'];
|
|
243
|
+
const optionKeys = ['y', 'n', 'a'];
|
|
244
|
+
for (let i = 0; i < optionLabels.length; i++) {
|
|
245
|
+
const isCursor = this.state.selectedIndex === i;
|
|
246
|
+
const prefix = isCursor ? ' ❯ ' : ' ';
|
|
247
|
+
const key = `[${optionKeys[i]}] `;
|
|
248
|
+
if (isCursor) {
|
|
249
|
+
lines.push(s.primary(prefix + key + optionLabels[i]));
|
|
330
250
|
}
|
|
331
|
-
else
|
|
332
|
-
|
|
333
|
-
state.scrollOffset = Math.min(maxOffset, state.scrollOffset + state.visibleLines);
|
|
251
|
+
else {
|
|
252
|
+
lines.push(s.muted(prefix + key + optionLabels[i]));
|
|
334
253
|
}
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
// =============================================================================
|
|
342
|
-
// Rendering
|
|
343
|
-
// =============================================================================
|
|
344
|
-
function render(options, state, previousLineCount = 0, targetLineCount = 0) {
|
|
345
|
-
const s = getStyles();
|
|
346
|
-
const lines = [];
|
|
347
|
-
const cols = terminal.getTerminalWidth();
|
|
348
|
-
const border = s.muted('─'.repeat(Math.max(1, cols - 1)));
|
|
349
|
-
// Clear previous render
|
|
350
|
-
if (previousLineCount > 0) {
|
|
351
|
-
terminal.clearLinesAbove(previousLineCount);
|
|
254
|
+
}
|
|
255
|
+
// Footer
|
|
256
|
+
lines.push('');
|
|
257
|
+
lines.push(s.muted(' ↑↓ Navigate · Enter Select · y/n/a Quick select · ') + s.primary('d') + s.muted(' Details'));
|
|
258
|
+
lines.push(border);
|
|
259
|
+
return lines;
|
|
352
260
|
}
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
const
|
|
366
|
-
|
|
261
|
+
renderDetailView() {
|
|
262
|
+
const s = getStyles();
|
|
263
|
+
const cols = this.getTerminalWidth();
|
|
264
|
+
const lines = [];
|
|
265
|
+
const border = s.muted('─'.repeat(Math.max(1, cols - 1)));
|
|
266
|
+
// Header
|
|
267
|
+
lines.push(border);
|
|
268
|
+
lines.push(' ' + s.warning('⚠') + ' ' + chalk.bold('Permission Details') + s.muted(` (${this.options.toolName})`));
|
|
269
|
+
lines.push(border);
|
|
270
|
+
lines.push('');
|
|
271
|
+
// Content with scroll
|
|
272
|
+
const contentLines = this.state.detailContentLines;
|
|
273
|
+
const visibleLines = DETAIL_VIEW_CONTENT_LINES;
|
|
274
|
+
const endLine = Math.min(this.state.detailScrollOffset + visibleLines, contentLines.length);
|
|
275
|
+
for (let i = this.state.detailScrollOffset; i < endLine; i++) {
|
|
276
|
+
const line = contentLines[i];
|
|
277
|
+
const safeLine = line.length > cols - 4 ? line.slice(0, cols - 7) + '...' : line;
|
|
278
|
+
lines.push(' ' + safeLine);
|
|
279
|
+
}
|
|
280
|
+
// Pad to fixed height
|
|
281
|
+
const renderedLines = endLine - this.state.detailScrollOffset;
|
|
282
|
+
for (let i = renderedLines; i < DETAIL_VIEW_CONTENT_LINES; i++) {
|
|
283
|
+
lines.push('');
|
|
284
|
+
}
|
|
285
|
+
// Footer with scroll indicator
|
|
286
|
+
lines.push('');
|
|
287
|
+
const scrollInfo = contentLines.length > visibleLines
|
|
288
|
+
? s.muted(` [${String(this.state.detailScrollOffset + 1)}-${String(endLine)}/${String(contentLines.length)}]`)
|
|
289
|
+
: '';
|
|
290
|
+
lines.push(border);
|
|
291
|
+
lines.push(s.muted(' ↑↓/PgUp/PgDn Scroll · q/Esc Back') + scrollInfo);
|
|
292
|
+
return lines;
|
|
367
293
|
}
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
const optionKeys = ['y', 'n', 'a'];
|
|
372
|
-
for (let i = 0; i < optionLabels.length; i++) {
|
|
373
|
-
const isCursor = state.selectedIndex === i;
|
|
374
|
-
const prefix = isCursor ? ' ❯ ' : ' ';
|
|
375
|
-
const key = `[${optionKeys[i]}] `;
|
|
376
|
-
if (isCursor) {
|
|
377
|
-
lines.push(s.primary(prefix + key + optionLabels[i]));
|
|
294
|
+
handleKey(data) {
|
|
295
|
+
if (this.state.showingDetail) {
|
|
296
|
+
return this.handleDetailKey(data);
|
|
378
297
|
}
|
|
379
|
-
|
|
380
|
-
|
|
298
|
+
return this.handleMainKey(data);
|
|
299
|
+
}
|
|
300
|
+
handleMainKey(data) {
|
|
301
|
+
// Escape or Ctrl+C = deny
|
|
302
|
+
if (this.isEscapeKey(data) || this.isCtrlCKey(data)) {
|
|
303
|
+
return { type: 'close', result: 'deny' };
|
|
304
|
+
}
|
|
305
|
+
// Quick keys
|
|
306
|
+
const key = data.toString().toLowerCase();
|
|
307
|
+
if (key === 'y') {
|
|
308
|
+
return { type: 'close', result: 'allow' };
|
|
309
|
+
}
|
|
310
|
+
if (key === 'n') {
|
|
311
|
+
return { type: 'close', result: 'deny' };
|
|
312
|
+
}
|
|
313
|
+
if (key === 'a') {
|
|
314
|
+
return { type: 'close', result: 'allow-always' };
|
|
315
|
+
}
|
|
316
|
+
if (key === 'd') {
|
|
317
|
+
// Switch to detail view
|
|
318
|
+
const cols = this.getTerminalWidth();
|
|
319
|
+
this.state.showingDetail = true;
|
|
320
|
+
this.state.detailScrollOffset = 0;
|
|
321
|
+
this.state.detailContentLines = formatArgsForDetail(this.options.toolName, this.options.args, cols - 4);
|
|
322
|
+
return { type: 'continue' };
|
|
381
323
|
}
|
|
324
|
+
// Arrow navigation
|
|
325
|
+
if (this.isUpArrowKey(data)) {
|
|
326
|
+
this.state.selectedIndex = Math.max(0, this.state.selectedIndex - 1);
|
|
327
|
+
}
|
|
328
|
+
else if (this.isDownArrowKey(data)) {
|
|
329
|
+
this.state.selectedIndex = Math.min(2, this.state.selectedIndex + 1);
|
|
330
|
+
}
|
|
331
|
+
else if (this.isEnterKey(data)) {
|
|
332
|
+
const results = ['allow', 'deny', 'allow-always'];
|
|
333
|
+
return { type: 'close', result: results[this.state.selectedIndex] };
|
|
334
|
+
}
|
|
335
|
+
return { type: 'continue' };
|
|
382
336
|
}
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
337
|
+
handleDetailKey(data) {
|
|
338
|
+
const key = data.toString().toLowerCase();
|
|
339
|
+
const isPageUp = data.length === 4 && data[0] === 0x1b && data[1] === 0x5b && data[2] === 0x35 && data[3] === 0x7e;
|
|
340
|
+
const isPageDown = data.length === 4 && data[0] === 0x1b && data[1] === 0x5b && data[2] === 0x36 && data[3] === 0x7e;
|
|
341
|
+
// q or Escape = go back to main view
|
|
342
|
+
if (key === 'q' || this.isEscapeKey(data)) {
|
|
343
|
+
this.state.showingDetail = false;
|
|
344
|
+
return { type: 'continue' };
|
|
345
|
+
}
|
|
346
|
+
// Scroll
|
|
347
|
+
const visibleLines = DETAIL_VIEW_CONTENT_LINES;
|
|
348
|
+
const maxOffset = Math.max(0, this.state.detailContentLines.length - visibleLines);
|
|
349
|
+
if (this.isUpArrowKey(data)) {
|
|
350
|
+
this.state.detailScrollOffset = Math.max(0, this.state.detailScrollOffset - 1);
|
|
351
|
+
}
|
|
352
|
+
else if (isPageUp) {
|
|
353
|
+
this.state.detailScrollOffset = Math.max(0, this.state.detailScrollOffset - visibleLines);
|
|
354
|
+
}
|
|
355
|
+
else if (this.isDownArrowKey(data)) {
|
|
356
|
+
this.state.detailScrollOffset = Math.min(maxOffset, this.state.detailScrollOffset + 1);
|
|
357
|
+
}
|
|
358
|
+
else if (isPageDown) {
|
|
359
|
+
this.state.detailScrollOffset = Math.min(maxOffset, this.state.detailScrollOffset + visibleLines);
|
|
360
|
+
}
|
|
361
|
+
return { type: 'continue' };
|
|
362
|
+
}
|
|
363
|
+
getCleanupSummary(result) {
|
|
364
|
+
const s = getStyles();
|
|
365
|
+
const resultText = result === 'allow'
|
|
366
|
+
? s.success('Allowed')
|
|
367
|
+
: result === 'allow-always'
|
|
368
|
+
? s.primary('Always allowed')
|
|
369
|
+
: s.error('Denied');
|
|
370
|
+
return s.muted(`Permission: ${resultText}`);
|
|
391
371
|
}
|
|
392
|
-
// Render all lines
|
|
393
|
-
terminal.write(lines.join('\n'));
|
|
394
|
-
return lines.length;
|
|
395
372
|
}
|
|
396
373
|
// =============================================================================
|
|
397
374
|
// Main Export
|
|
@@ -400,95 +377,6 @@ function render(options, state, previousLineCount = 0, targetLineCount = 0) {
|
|
|
400
377
|
* Show the permission overlay
|
|
401
378
|
*/
|
|
402
379
|
export async function showPermissionOverlay(options) {
|
|
403
|
-
const
|
|
404
|
-
|
|
405
|
-
};
|
|
406
|
-
let lineCount = 0;
|
|
407
|
-
let maxLineCount = 0;
|
|
408
|
-
// NOTE: Footer is already paused by the caller (index.ts handler calls sharedState.pauseFooter)
|
|
409
|
-
// Do NOT call pauseForOverlay() here - it causes double-pause issues
|
|
410
|
-
// Ensure we start from a fresh line
|
|
411
|
-
terminal.writeLine('');
|
|
412
|
-
terminal.hideCursor();
|
|
413
|
-
const wasRawMode = process.stdin.isRaw;
|
|
414
|
-
terminal.enableRawMode();
|
|
415
|
-
// Initial render
|
|
416
|
-
lineCount = render(options, state, 0);
|
|
417
|
-
maxLineCount = Math.max(maxLineCount, lineCount);
|
|
418
|
-
return new Promise((resolve) => {
|
|
419
|
-
const cleanup = (result) => {
|
|
420
|
-
terminal.clearLinesAbove(maxLineCount);
|
|
421
|
-
// Show result summary
|
|
422
|
-
const s = getStyles();
|
|
423
|
-
const resultText = result === 'allow'
|
|
424
|
-
? s.success('Allowed')
|
|
425
|
-
: result === 'allow-always'
|
|
426
|
-
? s.primary('Always allowed')
|
|
427
|
-
: s.error('Denied');
|
|
428
|
-
terminal.writeLine(s.muted(`Permission: ${resultText}`));
|
|
429
|
-
terminal.writeLine(''); // Blank line for separation
|
|
430
|
-
terminal.showCursor();
|
|
431
|
-
if (!wasRawMode) {
|
|
432
|
-
terminal.disableRawMode();
|
|
433
|
-
}
|
|
434
|
-
process.stdin.removeListener('data', handleData);
|
|
435
|
-
resolve(result);
|
|
436
|
-
};
|
|
437
|
-
const handleData = (data) => {
|
|
438
|
-
const isEscape = data.length === 1 && data[0] === 0x1b;
|
|
439
|
-
const isUpArrow = data.length === 3 && data[0] === 0x1b && data[1] === 0x5b && data[2] === 0x41;
|
|
440
|
-
const isDownArrow = data.length === 3 && data[0] === 0x1b && data[1] === 0x5b && data[2] === 0x42;
|
|
441
|
-
const isCtrlC = data.length === 1 && data[0] === 0x03;
|
|
442
|
-
const isEnter = data.length === 1 && (data[0] === 0x0d || data[0] === 0x0a);
|
|
443
|
-
// Ctrl+C or Escape = deny
|
|
444
|
-
if (isCtrlC || isEscape) {
|
|
445
|
-
cleanup('deny');
|
|
446
|
-
return;
|
|
447
|
-
}
|
|
448
|
-
// Quick keys
|
|
449
|
-
const key = data.toString().toLowerCase();
|
|
450
|
-
if (key === 'y') {
|
|
451
|
-
cleanup('allow');
|
|
452
|
-
return;
|
|
453
|
-
}
|
|
454
|
-
if (key === 'n') {
|
|
455
|
-
cleanup('deny');
|
|
456
|
-
return;
|
|
457
|
-
}
|
|
458
|
-
if (key === 'a') {
|
|
459
|
-
cleanup('allow-always');
|
|
460
|
-
return;
|
|
461
|
-
}
|
|
462
|
-
if (key === 'd') {
|
|
463
|
-
// Show detail view, then return to permission overlay
|
|
464
|
-
process.stdin.removeListener('data', handleData);
|
|
465
|
-
// First clear the current permission overlay
|
|
466
|
-
terminal.clearLinesAbove(maxLineCount);
|
|
467
|
-
void showDetailView(options).then(() => {
|
|
468
|
-
// Detail view already cleared itself, just re-render permission overlay
|
|
469
|
-
lineCount = render(options, state, 0);
|
|
470
|
-
maxLineCount = lineCount;
|
|
471
|
-
process.stdin.on('data', handleData);
|
|
472
|
-
});
|
|
473
|
-
return;
|
|
474
|
-
}
|
|
475
|
-
// Arrow navigation
|
|
476
|
-
if (isUpArrow) {
|
|
477
|
-
state.selectedIndex = Math.max(0, state.selectedIndex - 1);
|
|
478
|
-
}
|
|
479
|
-
else if (isDownArrow) {
|
|
480
|
-
state.selectedIndex = Math.min(2, state.selectedIndex + 1);
|
|
481
|
-
}
|
|
482
|
-
else if (isEnter) {
|
|
483
|
-
// Select based on current index
|
|
484
|
-
const results = ['allow', 'deny', 'allow-always'];
|
|
485
|
-
cleanup(results[state.selectedIndex]);
|
|
486
|
-
return;
|
|
487
|
-
}
|
|
488
|
-
// Re-render
|
|
489
|
-
lineCount = render(options, state, maxLineCount, maxLineCount);
|
|
490
|
-
maxLineCount = Math.max(maxLineCount, lineCount);
|
|
491
|
-
};
|
|
492
|
-
process.stdin.on('data', handleData);
|
|
493
|
-
});
|
|
380
|
+
const overlay = new PermissionOverlayImpl(options);
|
|
381
|
+
return overlay.show();
|
|
494
382
|
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Projects Overlay
|
|
3
|
+
*
|
|
4
|
+
* Interactive overlay for viewing and managing projects.
|
|
5
|
+
* Uses TabbedListOverlay for consistent tabbed list behavior.
|
|
6
|
+
*
|
|
7
|
+
* Features:
|
|
8
|
+
* - Tabbed filtering by status (All, Active, Paused, Completed, Archived)
|
|
9
|
+
* - Paginated list with search
|
|
10
|
+
* - Project detail preview
|
|
11
|
+
* - Archive/Restore workflow
|
|
12
|
+
* - Delete workflow with path validation
|
|
13
|
+
* - Keyboard navigation (vim-style + arrows)
|
|
14
|
+
*/
|
|
15
|
+
export interface ProjectsOverlayResult {
|
|
16
|
+
action: 'cancel' | 'open-workflow';
|
|
17
|
+
projectId?: number;
|
|
18
|
+
}
|
|
19
|
+
export declare function showProjectsOverlay(): Promise<ProjectsOverlayResult>;
|