centaurus-cli 2.9.3 → 2.9.5

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.
Files changed (110) hide show
  1. package/dist/cli-adapter.d.ts +74 -10
  2. package/dist/cli-adapter.d.ts.map +1 -1
  3. package/dist/cli-adapter.js +898 -244
  4. package/dist/cli-adapter.js.map +1 -1
  5. package/dist/commands/CommandParser.d.ts +1 -1
  6. package/dist/commands/CommandParser.d.ts.map +1 -1
  7. package/dist/commands/CommandParser.js +113 -0
  8. package/dist/commands/CommandParser.js.map +1 -1
  9. package/dist/config/slash-commands.d.ts +2 -0
  10. package/dist/config/slash-commands.d.ts.map +1 -1
  11. package/dist/config/slash-commands.js +28 -0
  12. package/dist/config/slash-commands.js.map +1 -1
  13. package/dist/context/context-manager.d.ts +7 -1
  14. package/dist/context/context-manager.d.ts.map +1 -1
  15. package/dist/context/context-manager.js +14 -1
  16. package/dist/context/context-manager.js.map +1 -1
  17. package/dist/context/handlers/docker-handler.d.ts +11 -0
  18. package/dist/context/handlers/docker-handler.d.ts.map +1 -1
  19. package/dist/context/handlers/docker-handler.js +159 -14
  20. package/dist/context/handlers/docker-handler.js.map +1 -1
  21. package/dist/context/handlers/ssh-handler.d.ts +20 -0
  22. package/dist/context/handlers/ssh-handler.d.ts.map +1 -1
  23. package/dist/context/handlers/ssh-handler.js +129 -1
  24. package/dist/context/handlers/ssh-handler.js.map +1 -1
  25. package/dist/context/subshell-handler.d.ts +15 -0
  26. package/dist/context/subshell-handler.d.ts.map +1 -1
  27. package/dist/index.js +10 -0
  28. package/dist/index.js.map +1 -1
  29. package/dist/services/ai-service-client.d.ts.map +1 -1
  30. package/dist/services/ai-service-client.js +33 -11
  31. package/dist/services/ai-service-client.js.map +1 -1
  32. package/dist/services/api-client.js +1 -1
  33. package/dist/services/api-client.js.map +1 -1
  34. package/dist/services/local-chat-storage.d.ts +3 -1
  35. package/dist/services/local-chat-storage.d.ts.map +1 -1
  36. package/dist/services/local-chat-storage.js +8 -3
  37. package/dist/services/local-chat-storage.js.map +1 -1
  38. package/dist/services/warpify-detector.d.ts +43 -0
  39. package/dist/services/warpify-detector.d.ts.map +1 -0
  40. package/dist/services/warpify-detector.js +203 -0
  41. package/dist/services/warpify-detector.js.map +1 -0
  42. package/dist/services/workflow-storage.d.ts +72 -0
  43. package/dist/services/workflow-storage.d.ts.map +1 -0
  44. package/dist/services/workflow-storage.js +239 -0
  45. package/dist/services/workflow-storage.js.map +1 -0
  46. package/dist/tools/command.d.ts.map +1 -1
  47. package/dist/tools/command.js +106 -38
  48. package/dist/tools/command.js.map +1 -1
  49. package/dist/tools/enter-remote-session.d.ts +13 -0
  50. package/dist/tools/enter-remote-session.d.ts.map +1 -0
  51. package/dist/tools/enter-remote-session.js +226 -0
  52. package/dist/tools/enter-remote-session.js.map +1 -0
  53. package/dist/tools/find-files.d.ts.map +1 -1
  54. package/dist/tools/find-files.js +9 -2
  55. package/dist/tools/find-files.js.map +1 -1
  56. package/dist/tools/grep-search.d.ts +104 -31
  57. package/dist/tools/grep-search.d.ts.map +1 -1
  58. package/dist/tools/grep-search.js +779 -431
  59. package/dist/tools/grep-search.js.map +1 -1
  60. package/dist/tools/workflow-tool.d.ts +11 -0
  61. package/dist/tools/workflow-tool.d.ts.map +1 -0
  62. package/dist/tools/workflow-tool.js +87 -0
  63. package/dist/tools/workflow-tool.js.map +1 -0
  64. package/dist/types/workflow.d.ts +110 -0
  65. package/dist/types/workflow.d.ts.map +1 -0
  66. package/dist/types/workflow.js +8 -0
  67. package/dist/types/workflow.js.map +1 -0
  68. package/dist/ui/components/App.d.ts +10 -1
  69. package/dist/ui/components/App.d.ts.map +1 -1
  70. package/dist/ui/components/App.js +135 -8
  71. package/dist/ui/components/App.js.map +1 -1
  72. package/dist/ui/components/Breadcrumbs.d.ts +4 -3
  73. package/dist/ui/components/Breadcrumbs.d.ts.map +1 -1
  74. package/dist/ui/components/Breadcrumbs.js +80 -54
  75. package/dist/ui/components/Breadcrumbs.js.map +1 -1
  76. package/dist/ui/components/ConnectionStatusMessage.js +2 -2
  77. package/dist/ui/components/ConnectionStatusMessage.js.map +1 -1
  78. package/dist/ui/components/InputBox.d.ts +1 -0
  79. package/dist/ui/components/InputBox.d.ts.map +1 -1
  80. package/dist/ui/components/InputBox.js +226 -19
  81. package/dist/ui/components/InputBox.js.map +1 -1
  82. package/dist/ui/components/InteractiveShell.d.ts +4 -0
  83. package/dist/ui/components/InteractiveShell.d.ts.map +1 -1
  84. package/dist/ui/components/InteractiveShell.js +52 -15
  85. package/dist/ui/components/InteractiveShell.js.map +1 -1
  86. package/dist/ui/components/KeyboardHelp.d.ts.map +1 -1
  87. package/dist/ui/components/KeyboardHelp.js +14 -6
  88. package/dist/ui/components/KeyboardHelp.js.map +1 -1
  89. package/dist/ui/components/ToolExecutionMessage.d.ts.map +1 -1
  90. package/dist/ui/components/ToolExecutionMessage.js +165 -27
  91. package/dist/ui/components/ToolExecutionMessage.js.map +1 -1
  92. package/dist/ui/components/WorkflowCreatorScreen.d.ts +25 -0
  93. package/dist/ui/components/WorkflowCreatorScreen.d.ts.map +1 -0
  94. package/dist/ui/components/WorkflowCreatorScreen.js +164 -0
  95. package/dist/ui/components/WorkflowCreatorScreen.js.map +1 -0
  96. package/dist/utils/ansi-encoder.d.ts.map +1 -1
  97. package/dist/utils/ansi-encoder.js +7 -0
  98. package/dist/utils/ansi-encoder.js.map +1 -1
  99. package/dist/utils/editor-utils.d.ts +9 -0
  100. package/dist/utils/editor-utils.d.ts.map +1 -1
  101. package/dist/utils/editor-utils.js +105 -0
  102. package/dist/utils/editor-utils.js.map +1 -1
  103. package/dist/utils/input-classifier.d.ts.map +1 -1
  104. package/dist/utils/input-classifier.js +2 -1
  105. package/dist/utils/input-classifier.js.map +1 -1
  106. package/dist/utils/terminal-output.d.ts +3 -1
  107. package/dist/utils/terminal-output.d.ts.map +1 -1
  108. package/dist/utils/terminal-output.js +138 -157
  109. package/dist/utils/terminal-output.js.map +1 -1
  110. package/package.json +1 -1
@@ -1,62 +1,88 @@
1
1
  import React from 'react';
2
2
  import { Box, Text } from 'ink';
3
+ // Get abbreviated breadcrumb (just the type) for parent sessions
4
+ const getAbbreviatedBreadcrumb = (context) => {
5
+ const typeColors = {
6
+ ssh: 'cyan',
7
+ wsl: 'yellow',
8
+ docker: 'blue',
9
+ local: 'gray'
10
+ };
11
+ return {
12
+ label: context.type,
13
+ color: typeColors[context.type] || 'cyan'
14
+ };
15
+ };
16
+ // Get full breadcrumb with metadata for the current/active session
17
+ const getContextBreadcrumbs = (context) => {
18
+ // Get breadcrumbs from handler if available
19
+ if (context.handler?.getBreadcrumbs) {
20
+ const crumbs = context.handler.getBreadcrumbs();
21
+ if (crumbs.length > 0)
22
+ return crumbs;
23
+ }
24
+ // Default logic based on type
25
+ const typeColors = {
26
+ ssh: 'cyan',
27
+ wsl: 'yellow',
28
+ docker: 'blue',
29
+ local: 'gray'
30
+ };
31
+ const info = {
32
+ label: context.type,
33
+ color: typeColors[context.type] || 'cyan'
34
+ };
35
+ // Enhance label with metadata
36
+ if (context.type === 'ssh' && context.metadata.username) {
37
+ info.label = `${context.metadata.username}@${context.metadata.hostname || 'host'}`;
38
+ }
39
+ else if (context.type === 'wsl' && context.metadata.distroName) {
40
+ info.label = `wsl:${context.metadata.distroName}`;
41
+ }
42
+ else if (context.type === 'docker' && context.metadata.containerId) {
43
+ info.label = `docker:${context.metadata.containerId.substring(0, 8)}`;
44
+ }
45
+ return [info];
46
+ };
3
47
  /**
4
- * Breadcrumbs component displays the current subshell context
5
- * Shows visual indicators for SSH, WSL, and Docker environments
48
+ * Breadcrumbs component displays the current subshell context stack
49
+ * Shows visual indicators for nested environments relative to local
6
50
  */
7
- export const Breadcrumbs = ({ context }) => {
8
- // Don't show breadcrumbs for local context
9
- if (context.type === 'local') {
10
- return null;
51
+ export const Breadcrumbs = ({ context, stack }) => {
52
+ // Use stack if available, otherwise fallback to single context
53
+ let contexts = stack || (context ? [context] : []);
54
+ // Filter out local context if it's the base of a remote stack (standard case)
55
+ // We only want to show the "remote path"
56
+ if (contexts.length > 1 && contexts[0].type === 'local') {
57
+ contexts = contexts.slice(1);
11
58
  }
12
- // Get breadcrumbs from handler if available
13
- const breadcrumbs = context.handler?.getBreadcrumbs?.() || [];
14
- // If no breadcrumbs from handler, create default ones based on context type
15
- if (breadcrumbs.length === 0) {
16
- const defaultBreadcrumbs = [];
17
- // Add type breadcrumb with appropriate color
18
- const typeColors = {
19
- ssh: 'cyan',
20
- wsl: 'yellow',
21
- docker: 'blue',
22
- };
23
- defaultBreadcrumbs.push({
24
- label: context.type,
25
- color: typeColors[context.type] || 'cyan',
26
- });
27
- // Add hostname/username for SSH
28
- if (context.type === 'ssh' && context.metadata.username && context.metadata.hostname) {
29
- defaultBreadcrumbs.push({
30
- label: `${context.metadata.username}@${context.metadata.hostname}`,
31
- color: 'cyan',
32
- });
33
- }
34
- // Add distribution name for WSL
35
- if (context.type === 'wsl' && context.metadata.distroName) {
36
- defaultBreadcrumbs.push({
37
- label: context.metadata.distroName,
38
- color: 'yellow',
39
- });
40
- }
41
- // Add container ID for Docker
42
- if (context.type === 'docker' && context.metadata.containerId) {
43
- defaultBreadcrumbs.push({
44
- label: context.metadata.containerId.substring(0, 12), // Show first 12 chars like Docker CLI
45
- color: 'blue',
46
- });
47
- }
48
- return (React.createElement(Box, { marginRight: 1 }, defaultBreadcrumbs.map((crumb, i) => (React.createElement(Box, { key: i, marginRight: 1 },
49
- React.createElement(Text, { color: crumb.color || 'cyan', bold: true },
50
- "[",
51
- crumb.label,
52
- "]"))))));
59
+ else if (contexts.length === 1 && contexts[0].type === 'local') {
60
+ // If we're just local, render nothing (InputBox handles CWD)
61
+ return null;
53
62
  }
54
- // Render breadcrumbs from handler
55
- return (React.createElement(Box, { marginRight: 1 }, breadcrumbs.map((crumb, i) => (React.createElement(Box, { key: i, marginRight: 1 },
56
- React.createElement(Text, { color: crumb.color || 'cyan', bold: true },
57
- "[",
58
- crumb.label,
59
- crumb.value ? `: ${crumb.value}` : '',
60
- "]"))))));
63
+ if (contexts.length === 0)
64
+ return null;
65
+ // Determine if this is the last context (current/active session)
66
+ const isLastContext = (ctxIndex) => ctxIndex === contexts.length - 1;
67
+ return (React.createElement(Box, { marginRight: 1 }, contexts.map((ctx, ctxIndex) => {
68
+ // For parent sessions (not the last one), use abbreviated labels
69
+ // For the current/active session (last one), show full details
70
+ const crumbs = isLastContext(ctxIndex)
71
+ ? getContextBreadcrumbs(ctx)
72
+ : [getAbbreviatedBreadcrumb(ctx)];
73
+ return (React.createElement(Box, { key: ctx.sessionId || ctxIndex, flexDirection: "row" },
74
+ ctxIndex > 0 && (React.createElement(Box, { marginX: 1 },
75
+ React.createElement(Text, { color: "gray" }, "\u203A"))),
76
+ crumbs.map((info, crumbIndex) => {
77
+ // Only bold the very last item of the very last context
78
+ const isLast = isLastContext(ctxIndex) && crumbIndex === crumbs.length - 1;
79
+ return (React.createElement(Box, { key: `${ctxIndex}-${crumbIndex}`, flexDirection: "row" },
80
+ crumbIndex > 0 && React.createElement(Box, { width: 1 }),
81
+ React.createElement(Text, { color: info.color || 'cyan', bold: isLast },
82
+ "[",
83
+ info.label,
84
+ "]")));
85
+ })));
86
+ })));
61
87
  };
62
88
  //# sourceMappingURL=Breadcrumbs.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"Breadcrumbs.js","sourceRoot":"","sources":["../../../src/ui/components/Breadcrumbs.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"Breadcrumbs.js","sourceRoot":"","sources":["../../../src/ui/components/Breadcrumbs.tsx"],"names":[],"mappings":"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"}
@@ -21,7 +21,7 @@ export const ConnectionStatusMessage = React.memo(({ status }) => {
21
21
  React.createElement(Text, { color: "#00ccff" },
22
22
  React.createElement(Spinner, { type: "dots" })),
23
23
  React.createElement(Text, { color: "#9945FF" },
24
- " Connecting to ",
24
+ " Tunnelling to ",
25
25
  getTypeLabel(),
26
26
  " environment..."))));
27
27
  }
@@ -31,7 +31,7 @@ export const ConnectionStatusMessage = React.memo(({ status }) => {
31
31
  React.createElement(Box, null,
32
32
  React.createElement(Text, { color: "#00cc66", bold: true }, "\u2713"),
33
33
  React.createElement(Text, { color: "#00cc66" },
34
- " Connected to ",
34
+ " Established Wormhole to ",
35
35
  getTypeLabel(),
36
36
  " environment"),
37
37
  status.connectionString && (React.createElement(Text, { color: "#666666" },
@@ -1 +1 @@
1
- {"version":3,"file":"ConnectionStatusMessage.js","sourceRoot":"","sources":["../../../src/ui/components/ConnectionStatusMessage.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ConnectionStatusMessage.js","sourceRoot":"","sources":["../../../src/ui/components/ConnectionStatusMessage.tsx"],"names":[],"mappings":"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"}
@@ -16,6 +16,7 @@ interface InputBoxProps {
16
16
  onToggleBackgroundMode?: () => void;
17
17
  isActive?: boolean;
18
18
  subshellContext?: SubshellContext;
19
+ subshellContextStack?: SubshellContext[];
19
20
  currentTokens?: number;
20
21
  maxTokens?: number;
21
22
  contextLimitReached?: boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"InputBox.d.ts","sourceRoot":"","sources":["../../../src/ui/components/InputBox.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA+C,MAAM,OAAO,CAAC;AAIpE,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAWzD,OAAO,EAAyC,cAAc,EAAE,MAAM,qCAAqC,CAAC;AAK5G,UAAU,aAAa;IACrB,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,eAAe,CAAC,EAAE,cAAc,EAAE,KAAK,IAAI,CAAC;IACtE,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,cAAc,EAAE,OAAO,CAAC;IACxB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,uBAAuB,CAAC,EAAE,MAAM,CAAC;IACjC,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B,kBAAkB,EAAE,MAAM,IAAI,CAAC;IAC/B,mBAAmB,CAAC,EAAE,MAAM,IAAI,CAAC;IACjC,sBAAsB,CAAC,EAAE,MAAM,IAAI,CAAC;IACpC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,eAAe,CAAC,EAAE,eAAe,CAAC;IAClC,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACxC,kBAAkB,CAAC,EAAE,CAAC,QAAQ,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,KAAK,IAAI,CAAC;IACpE,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,yBAAyB,CAAC,EAAE,MAAM,CAAC;IACnC,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;CAC5B;AA+CD,eAAO,MAAM,QAAQ,EAAE,KAAK,CAAC,EAAE,CAAC,aAAa,CAw9D3C,CAAC"}
1
+ {"version":3,"file":"InputBox.d.ts","sourceRoot":"","sources":["../../../src/ui/components/InputBox.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA+C,MAAM,OAAO,CAAC;AAIpE,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAWzD,OAAO,EAAyC,cAAc,EAAE,MAAM,qCAAqC,CAAC;AAM5G,UAAU,aAAa;IACrB,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,eAAe,CAAC,EAAE,cAAc,EAAE,KAAK,IAAI,CAAC;IACtE,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,cAAc,EAAE,OAAO,CAAC;IACxB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,uBAAuB,CAAC,EAAE,MAAM,CAAC;IACjC,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B,kBAAkB,EAAE,MAAM,IAAI,CAAC;IAC/B,mBAAmB,CAAC,EAAE,MAAM,IAAI,CAAC;IACjC,sBAAsB,CAAC,EAAE,MAAM,IAAI,CAAC;IACpC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,eAAe,CAAC,EAAE,eAAe,CAAC;IAClC,oBAAoB,CAAC,EAAE,eAAe,EAAE,CAAC;IACzC,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACxC,kBAAkB,CAAC,EAAE,CAAC,QAAQ,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,KAAK,IAAI,CAAC;IACpE,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,yBAAyB,CAAC,EAAE,MAAM,CAAC;IACnC,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;CAC5B;AA+CD,eAAO,MAAM,QAAQ,EAAE,KAAK,CAAC,EAAE,CAAC,aAAa,CAoqE3C,CAAC"}
@@ -14,6 +14,7 @@ import { filterCommands } from '../../config/slash-commands.js';
14
14
  import { getClipboardImages } from '../../services/clipboard-service.js';
15
15
  import { useTerminalDimensions, TERMINAL_HEIGHT_CONSTANTS } from '../../hooks/useTerminalDimensions.js';
16
16
  import { AIAutocompleteAgent, AI_AUTOCOMPLETE_DEBOUNCE_MS } from '../../services/ai-autocomplete-agent.js';
17
+ import { workflowStorage } from '../../services/workflow-storage.js';
17
18
  const getVisualLines = (text, width) => {
18
19
  const logicalLines = text.split('\n');
19
20
  const visualLines = [];
@@ -51,7 +52,7 @@ const getVisualLines = (text, width) => {
51
52
  });
52
53
  return visualLines;
53
54
  };
54
- export const InputBox = React.memo(({ onSubmit, placeholder = 'Ask anything...', autoAcceptMode, model, planMode = false, commandMode = false, backgroundMode = false, currentWorkingDirectory, commandHistory = [], onToggleAutoAccept, onToggleCommandMode, onToggleBackgroundMode, isActive = true, subshellContext, currentTokens = 0, maxTokens = 1000000, contextLimitReached = false, isShellRunning = false, backgroundTaskCount = 0, initialValue = '', onValueChange, onSetAutoModeSetup, sessionQuotaExhausted = false, sessionQuotaTimeRemaining = '', subAgentCount = 0, aiAutoSuggestEnabled = false, sessionCommands = [] }) => {
55
+ export const InputBox = React.memo(({ onSubmit, placeholder = 'Ask anything...', autoAcceptMode, model, planMode = false, commandMode = false, backgroundMode = false, currentWorkingDirectory, commandHistory = [], onToggleAutoAccept, onToggleCommandMode, onToggleBackgroundMode, isActive = true, subshellContext, subshellContextStack, currentTokens = 0, maxTokens = 1000000, contextLimitReached = false, isShellRunning = false, backgroundTaskCount = 0, initialValue = '', onValueChange, onSetAutoModeSetup, sessionQuotaExhausted = false, sessionQuotaTimeRemaining = '', subAgentCount = 0, aiAutoSuggestEnabled = false, sessionCommands = [] }) => {
55
56
  // Use initialValue for first mount, but manage state internally after that
56
57
  const [value, setValueInternal] = useState(initialValue);
57
58
  const [cursorOffset, setCursorOffset] = useState(0);
@@ -564,6 +565,68 @@ export const InputBox = React.memo(({ onSubmit, placeholder = 'Ask anything...',
564
565
  setCursorOffset(newValue.length);
565
566
  setSlashAutocompleteVisible(false);
566
567
  }
568
+ else if (value.startsWith('/workflow new ') || value.startsWith('/wf new ')) {
569
+ // We're in workflow new subcommand mode (manual or learn-workflow)
570
+ const prefix = value.startsWith('/workflow new ') ? '/workflow new ' : '/wf new ';
571
+ const newValue = `${prefix}${selected.name}`;
572
+ setValue(newValue);
573
+ setCursorOffset(newValue.length);
574
+ setSlashAutocompleteVisible(false);
575
+ }
576
+ else if (value.startsWith('/workflow ') || value.startsWith('/wf ')) {
577
+ // Check if we're in workflow name selection mode (after run/view/delete)
578
+ const workflowNameMatch = value.match(/^\/(?:workflow|wf)\s+(run|view|delete)\s+/);
579
+ if (workflowNameMatch) {
580
+ // We're selecting a workflow name
581
+ const prefix = value.match(/^\/(?:workflow|wf)\s+(?:run|view|delete)\s+/)?.[0] || '';
582
+ const newValue = `${prefix}${selected.name}`;
583
+ setValue(newValue);
584
+ setCursorOffset(newValue.length);
585
+ setSlashAutocompleteVisible(false);
586
+ }
587
+ else {
588
+ // We're selecting a workflow subcommand
589
+ const prefix = value.startsWith('/workflow ') ? '/workflow ' : '/wf ';
590
+ const newValue = `${prefix}${selected.name} `;
591
+ setValue(newValue);
592
+ setCursorOffset(newValue.length);
593
+ // For run/view/delete, show workflow names immediately
594
+ if (selected.name === 'run' || selected.name === 'view' || selected.name === 'delete') {
595
+ const workflows = workflowStorage.list();
596
+ const matchingWorkflows = workflows
597
+ .slice(0, 10)
598
+ .map(wf => ({
599
+ name: wf.name,
600
+ description: wf.description || `${wf.stepCount} step${wf.stepCount !== 1 ? 's' : ''}`
601
+ }));
602
+ if (matchingWorkflows.length > 0) {
603
+ setSlashAutocompleteCommands(matchingWorkflows);
604
+ setSlashAutocompleteSelectedIndex(0);
605
+ setSlashAutocompleteScrollOffset(0);
606
+ // Keep autocomplete visible
607
+ }
608
+ else {
609
+ setSlashAutocompleteVisible(false);
610
+ }
611
+ }
612
+ else if (selected.name === 'new') {
613
+ // For 'new' subcommand, show manual/learn-workflow options
614
+ const subcommandMatches = filterCommands('workflow new ');
615
+ if (subcommandMatches.length > 0) {
616
+ setSlashAutocompleteCommands(subcommandMatches);
617
+ setSlashAutocompleteSelectedIndex(0);
618
+ setSlashAutocompleteScrollOffset(0);
619
+ // Keep autocomplete visible for next level
620
+ }
621
+ else {
622
+ setSlashAutocompleteVisible(false);
623
+ }
624
+ }
625
+ else {
626
+ setSlashAutocompleteVisible(false);
627
+ }
628
+ }
629
+ }
567
630
  else if (value.startsWith('/settings auto-suggest ')) {
568
631
  // We're selecting an auto-suggest option (on/off)
569
632
  const newValue = `/settings auto-suggest ${selected.name}`;
@@ -683,6 +746,18 @@ export const InputBox = React.memo(({ onSubmit, placeholder = 'Ask anything...',
683
746
  setSlashAutocompleteVisible(false);
684
747
  }
685
748
  }
749
+ else if (selected.name === 'workflow' || selected.name === 'wf') {
750
+ const subcommandMatches = filterCommands('workflow ');
751
+ if (subcommandMatches.length > 0) {
752
+ setSlashAutocompleteCommands(subcommandMatches);
753
+ setSlashAutocompleteSelectedIndex(0);
754
+ setSlashAutocompleteScrollOffset(0);
755
+ // Keep autocomplete visible for subcommands
756
+ }
757
+ else {
758
+ setSlashAutocompleteVisible(false);
759
+ }
760
+ }
686
761
  else {
687
762
  setSlashAutocompleteVisible(false);
688
763
  }
@@ -769,7 +844,10 @@ export const InputBox = React.memo(({ onSubmit, placeholder = 'Ask anything...',
769
844
  }
770
845
  // Alt+V: Paste image from clipboard
771
846
  // Detect Alt+V on Windows/Linux (key.meta is often Alt on Windows in Ink)
772
- const isAltV = (key.meta && input === 'v') || (input === '√'); // '√' is Alt+V on some systems
847
+ // On Mac, we want to support Cmd+V explicitly as requested ("make alt key combinations work with cmd key")
848
+ // Note: Cmd+V is often captured by the terminal for text paste, but if it gets through, we handle it.
849
+ // Option+V on Mac often sends '√', which we also support.
850
+ const isAltV = (key.meta && input === 'v') || (input === '√');
773
851
  if (isAltV && !commandMode) {
774
852
  // Check clipboard for images asynchronously
775
853
  (async () => {
@@ -797,15 +875,13 @@ export const InputBox = React.memo(({ onSubmit, placeholder = 'Ask anything...',
797
875
  })();
798
876
  return;
799
877
  }
800
- // DELETE WORD BACKWARDS - Check this FIRST before standard backspace/delete
801
- // Triggers on any of these conditions:
802
- // 1. Ctrl+W (char code 23) - Standard Unix terminal shortcut
803
- // 2. Meta/Alt + Backspace/Delete - Mac alternative
804
- // 3. Ctrl + Delete - Works on all platforms (Ctrl+Backspace doesn't work on Windows/Ink)
805
- // 4. Windows Ctrl+Del sends char code 127
878
+ // DELETE WORD BACKWARDS
879
+ // 1. Ctrl+W
880
+ // 2. Cmd+Backspace (Mac) - often mapped to delete line, but here we treat key.meta as modifier
881
+ // 3. Alt+Backspace (Windows/Linux)
806
882
  const isDeleteWord = inputCharCode === 23 || // Ctrl+W
807
- (key.meta && (key.backspace || key.delete)) || // Meta/Alt + Backspace/Delete
808
- (key.ctrl && key.delete) || // Ctrl+Delete (NOTE: Ctrl+Backspace not detectable on Windows/Ink)
883
+ (key.meta && (key.backspace || key.delete)) || // Cmd+Backspace (Mac) or Alt+Backspace (Win)
884
+ (key.ctrl && key.delete) || // Ctrl+Delete
809
885
  (isWindows && inputCharCode === 127); // Windows: Ctrl+Del sends char 127
810
886
  if (isDeleteWord) {
811
887
  pushToUndoStack();
@@ -920,6 +996,59 @@ export const InputBox = React.memo(({ onSubmit, placeholder = 'Ask anything...',
920
996
  setSlashAutocompleteVisible(false);
921
997
  }
922
998
  }
999
+ else if (newValue.match(/^\/workflow\s+(run|view|delete)\s+/) ||
1000
+ newValue.match(/^\/wf\s+(run|view|delete)\s+/)) {
1001
+ // Workflow name autocomplete (when user types "/workflow run " or similar)
1002
+ // This MUST come before the /workflow subcommand check since it's more specific
1003
+ const match = newValue.match(/^\/(?:workflow|wf)\s+(?:run|view|delete)\s+(.*)$/);
1004
+ const partialName = match ? match[1].toLowerCase() : '';
1005
+ const workflows = workflowStorage.list();
1006
+ const matchingWorkflows = workflows
1007
+ .filter(wf => wf.name.toLowerCase().includes(partialName))
1008
+ .slice(0, 10)
1009
+ .map(wf => ({
1010
+ name: wf.name,
1011
+ description: wf.description || `${wf.stepCount} step${wf.stepCount !== 1 ? 's' : ''}`
1012
+ }));
1013
+ if (matchingWorkflows.length > 0) {
1014
+ setSlashAutocompleteCommands(matchingWorkflows);
1015
+ setSlashAutocompleteVisible(true);
1016
+ setSlashAutocompleteSelectedIndex(0);
1017
+ setSlashAutocompleteScrollOffset(0);
1018
+ }
1019
+ else {
1020
+ setSlashAutocompleteVisible(false);
1021
+ }
1022
+ }
1023
+ else if (newValue.match(/^\/workflow\s+new\s+/) ||
1024
+ newValue.match(/^\/wf\s+new\s+/)) {
1025
+ // Workflow new subcommand autocomplete (manual, learn-workflow)
1026
+ const fullQuery = newValue.slice(1);
1027
+ const matches = filterCommands(fullQuery);
1028
+ if (matches.length > 0) {
1029
+ setSlashAutocompleteCommands(matches);
1030
+ setSlashAutocompleteVisible(true);
1031
+ setSlashAutocompleteSelectedIndex(0);
1032
+ setSlashAutocompleteScrollOffset(0);
1033
+ }
1034
+ else {
1035
+ setSlashAutocompleteVisible(false);
1036
+ }
1037
+ }
1038
+ else if (newValue.startsWith('/workflow ') || newValue.startsWith('/wf ')) {
1039
+ // Workflow subcommands (when user types "/workflow " or "/wf ")
1040
+ const fullQuery = newValue.slice(1);
1041
+ const matches = filterCommands(fullQuery);
1042
+ if (matches.length > 0) {
1043
+ setSlashAutocompleteCommands(matches);
1044
+ setSlashAutocompleteVisible(true);
1045
+ setSlashAutocompleteSelectedIndex(0);
1046
+ setSlashAutocompleteScrollOffset(0);
1047
+ }
1048
+ else {
1049
+ setSlashAutocompleteVisible(false);
1050
+ }
1051
+ }
923
1052
  else {
924
1053
  setSlashAutocompleteVisible(false);
925
1054
  }
@@ -1324,8 +1453,18 @@ export const InputBox = React.memo(({ onSubmit, placeholder = 'Ask anything...',
1324
1453
  return;
1325
1454
  }
1326
1455
  if (key.leftArrow) {
1327
- if (key.ctrl || key.meta) {
1328
- // Ctrl+Left / Meta+Left (Option+Left): Move word backwards
1456
+ if (isMac && key.meta) {
1457
+ // Mac: Cmd+Left -> Start of line (Home)
1458
+ setCursorOffset(0);
1459
+ return;
1460
+ }
1461
+ if (key.ctrl || (!isMac && key.meta)) {
1462
+ // Ctrl+Left (All) or Alt+Left (Win/Linux): Move word backwards
1463
+ // Note: On Mac, Option+Left is the standard for word back, but Ink doesn't expose 'alt'.
1464
+ // Users can use Ctrl+Left or rely on terminal mapping Option to Meta which effectively makes it key.meta
1465
+ // BUT if key.meta is Cmd on Mac, we map that to Home.
1466
+ // So standard Mac "Option+Left" might not work unless it sends Esc sequence or mapped to Ctrl.
1467
+ // We allow Ctrl+Left for Mac users.
1329
1468
  let newOffset = cursorOffset;
1330
1469
  if (newOffset > 0) {
1331
1470
  // Skip whitespace backwards
@@ -1338,8 +1477,10 @@ export const InputBox = React.memo(({ onSubmit, placeholder = 'Ask anything...',
1338
1477
  }
1339
1478
  setCursorOffset(newOffset);
1340
1479
  }
1480
+ return;
1341
1481
  }
1342
- else if (cursorOffset > 0) {
1482
+ // Standard Left Arrow
1483
+ if (cursorOffset > 0) {
1343
1484
  setCursorOffset(cursorOffset - 1);
1344
1485
  }
1345
1486
  return;
@@ -1347,10 +1488,16 @@ export const InputBox = React.memo(({ onSubmit, placeholder = 'Ask anything...',
1347
1488
  if (key.rightArrow) {
1348
1489
  // Autocomplete Logic (Only at end of line)
1349
1490
  // AI suggestion takes priority over passive suggestion
1491
+ // Autocomplete Logic
1350
1492
  const effectiveSuggestion = aiAutocompleteSuggestion || autocompleteSuggestion;
1351
1493
  if (effectiveSuggestion && cursorOffset === value.length) {
1352
- if (key.ctrl) {
1353
- // Ctrl+Right: Accept FULL suggestion
1494
+ if (key.ctrl || (isMac && key.meta)) {
1495
+ // Ctrl+Right (Win) or Cmd+Right (Mac): Accept FULL suggestion
1496
+ // (Wait, Cmd+Right is usually End of Line on Mac. We should prioritize Navigation over Autocomplete?
1497
+ // Actually, if we are at end of line, End of Line does nothing. So we can use it for accept full?)
1498
+ // Convention: Right Arrow accepts word. Ctrl+Right accepts full?
1499
+ // On Mac, Cmd+Right is End. If at End, it's a no-op for nav.
1500
+ // Let's allow Cmd+Right to accept full IF at end.
1354
1501
  setValue(effectiveSuggestion);
1355
1502
  setCursorOffset(effectiveSuggestion.length);
1356
1503
  setAutocompleteSuggestion(null);
@@ -1360,17 +1507,16 @@ export const InputBox = React.memo(({ onSubmit, placeholder = 'Ask anything...',
1360
1507
  else {
1361
1508
  // Right: Accept NEXT WORD
1362
1509
  const remaining = effectiveSuggestion.slice(value.length);
1363
- // Match next chunk of non-whitespace (including preceding whitespace)
1510
+ // Match next chunk of non-whitespace
1364
1511
  const match = remaining.match(/^(\s*\S+)/);
1365
1512
  if (match) {
1366
1513
  const toAdd = match[0];
1367
1514
  const newValue = value + toAdd;
1368
1515
  setValue(newValue);
1369
1516
  setCursorOffset(newValue.length);
1370
- return;
1517
+ return; // Done
1371
1518
  }
1372
1519
  else if (remaining.length > 0) {
1373
- // Fallback: if only whitespace remains or regex fails, take it all
1374
1520
  const newValue = value + remaining;
1375
1521
  setValue(newValue);
1376
1522
  setCursorOffset(newValue.length);
@@ -1378,6 +1524,29 @@ export const InputBox = React.memo(({ onSubmit, placeholder = 'Ask anything...',
1378
1524
  }
1379
1525
  }
1380
1526
  }
1527
+ // Navigation Logic
1528
+ if (isMac && key.meta) {
1529
+ // Cmd+Right -> End of line
1530
+ setCursorOffset(value.length);
1531
+ return;
1532
+ }
1533
+ if ((!isMac && key.meta) || key.ctrl) {
1534
+ // Alt+Right (Win) or Ctrl+Right: Word Forward
1535
+ // (Note: Ink uses key.meta for Alt on Windows)
1536
+ let newOffset = cursorOffset;
1537
+ if (newOffset < value.length) {
1538
+ // Skip whitespace forwards
1539
+ while (newOffset < value.length && /\s/.test(value[newOffset])) {
1540
+ newOffset++;
1541
+ }
1542
+ // Skip non-whitespace forwards
1543
+ while (newOffset < value.length && !/\s/.test(value[newOffset])) {
1544
+ newOffset++;
1545
+ }
1546
+ setCursorOffset(newOffset);
1547
+ }
1548
+ return;
1549
+ }
1381
1550
  // Navigation Logic (if not completing)
1382
1551
  if (key.ctrl || key.meta) {
1383
1552
  // Ctrl+Right / Meta+Right (Option+Right): Move word forwards
@@ -1537,6 +1706,44 @@ export const InputBox = React.memo(({ onSubmit, placeholder = 'Ask anything...',
1537
1706
  setSlashAutocompleteVisible(false);
1538
1707
  }
1539
1708
  }
1709
+ else if (newValue.match(/^\/workflow\s+(run|view|delete)\s+/) ||
1710
+ newValue.match(/^\/wf\s+(run|view|delete)\s+/)) {
1711
+ // Workflow name autocomplete (when user types "/workflow run " or similar)
1712
+ // This MUST come before the /workflow subcommand check since it's more specific
1713
+ const match = newValue.match(/^\/(?:workflow|wf)\s+(?:run|view|delete)\s+(.*)$/);
1714
+ const partialName = match ? match[1].toLowerCase() : '';
1715
+ const workflows = workflowStorage.list();
1716
+ const matchingWorkflows = workflows
1717
+ .filter(wf => wf.name.toLowerCase().includes(partialName))
1718
+ .slice(0, 10)
1719
+ .map(wf => ({
1720
+ name: wf.name,
1721
+ description: wf.description || `${wf.stepCount} step${wf.stepCount !== 1 ? 's' : ''}`
1722
+ }));
1723
+ if (matchingWorkflows.length > 0) {
1724
+ setSlashAutocompleteCommands(matchingWorkflows);
1725
+ setSlashAutocompleteVisible(true);
1726
+ setSlashAutocompleteSelectedIndex(0);
1727
+ setSlashAutocompleteScrollOffset(0);
1728
+ }
1729
+ else {
1730
+ setSlashAutocompleteVisible(false);
1731
+ }
1732
+ }
1733
+ else if (newValue.startsWith('/workflow ') || newValue.startsWith('/wf ')) {
1734
+ // Workflow subcommands (when user types "/workflow " or "/wf ")
1735
+ const fullQuery = newValue.slice(1); // Remove leading "/", pass "workflow <subquery>" to filterCommands
1736
+ const matches = filterCommands(fullQuery);
1737
+ if (matches.length > 0) {
1738
+ setSlashAutocompleteCommands(matches);
1739
+ setSlashAutocompleteVisible(true);
1740
+ setSlashAutocompleteSelectedIndex(0);
1741
+ setSlashAutocompleteScrollOffset(0);
1742
+ }
1743
+ else {
1744
+ setSlashAutocompleteVisible(false);
1745
+ }
1746
+ }
1540
1747
  else {
1541
1748
  setSlashAutocompleteVisible(false);
1542
1749
  }
@@ -1814,7 +2021,7 @@ export const InputBox = React.memo(({ onSubmit, placeholder = 'Ask anything...',
1814
2021
  "#257aa5ff", paddingX: 1, paddingY: 0, width: "100%" },
1815
2022
  React.createElement(Box, { marginY: 1, justifyContent: "space-between", width: "100%" },
1816
2023
  React.createElement(Box, null,
1817
- subshellContext && subshellContext.type !== 'local' && (React.createElement(Breadcrumbs, { context: subshellContext })),
2024
+ subshellContext && subshellContext.type !== 'local' && (React.createElement(Breadcrumbs, { context: subshellContext, stack: subshellContextStack })),
1818
2025
  React.createElement(Text, { color: "#666666" }, "CWD: "),
1819
2026
  React.createElement(Text, { color: "#00ccff", bold: true }, currentDir)),
1820
2027
  React.createElement(Box, null,