@vybestack/llxprt-code 0.10.0 → 0.11.0-nightly.260728.ffaa8d5d7

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 (126) hide show
  1. package/package.json +13 -13
  2. package/src/commands/mcp/add.ts +8 -4
  3. package/src/config/cliArgParser.ts +2 -0
  4. package/src/config/config.ts +2 -0
  5. package/src/config/configBuilder.ts +3 -0
  6. package/src/config/configError.ts +23 -0
  7. package/src/config/extensions/extensionEnablement.ts +62 -1
  8. package/src/config/interactiveContext.ts +2 -1
  9. package/src/config/intermediateConfig.ts +4 -0
  10. package/src/config/keyBindings.ts +29 -3
  11. package/src/config/policy.ts +7 -1
  12. package/src/config/postConfigRuntime.ts +20 -14
  13. package/src/config/settings-schema/schema-ui.ts +9 -0
  14. package/src/config/settingsLoader.ts +21 -17
  15. package/src/config/settingsSchema.ts +2 -2
  16. package/src/config/trustedFolders.ts +275 -58
  17. package/src/config/yargsOptions.ts +7 -0
  18. package/src/generated/git-commit.json +1 -1
  19. package/src/nonInteractiveCli.ts +1 -0
  20. package/src/nonInteractiveCliSupport.ts +171 -51
  21. package/src/runtime/interactiveToolScheduler.ts +6 -6
  22. package/src/services/BuiltinCommandLoader.ts +33 -25
  23. package/src/services/FileCommandLoader.ts +34 -7
  24. package/src/test-utils/async.ts +20 -0
  25. package/src/test-utils/render.tsx +10 -1
  26. package/src/ui/App.tsx +17 -10
  27. package/src/ui/AppContainerRuntime.tsx +7 -9
  28. package/src/ui/cliUiRuntime.ts +28 -0
  29. package/src/ui/commands/authCommand.ts +240 -3
  30. package/src/ui/commands/compressCommand.ts +9 -1
  31. package/src/ui/commands/directoryCommand.tsx +1 -1
  32. package/src/ui/commands/logoutCommand.ts +2 -2
  33. package/src/ui/commands/permissionsCommand.ts +77 -20
  34. package/src/ui/commands/policiesCommand.ts +6 -1
  35. package/src/ui/commands/quotaCommand.ts +501 -0
  36. package/src/ui/commands/statsCommand.ts +2 -2
  37. package/src/ui/commands/statsQuota.ts +1 -1
  38. package/src/ui/commands/subagentCommand.ts +59 -27
  39. package/src/ui/components/AuthDialog.tsx +3 -3
  40. package/src/ui/components/Composer.tsx +1 -0
  41. package/src/ui/components/DialogManager.tsx +9 -2
  42. package/src/ui/components/FolderTrustDialog.tsx +71 -60
  43. package/src/ui/components/PermissionsModifyTrustDialog.tsx +211 -146
  44. package/src/ui/components/ProfileCreateWizard/constants.ts +13 -1
  45. package/src/ui/components/QueuedMessagesPanel.tsx +388 -0
  46. package/src/ui/components/inputPromptHooks.ts +2 -0
  47. package/src/ui/components/inputPromptKeyHandlers.ts +14 -0
  48. package/src/ui/components/inputPromptTypes.ts +6 -0
  49. package/src/ui/components/messages/AiMessage.tsx +24 -12
  50. package/src/ui/components/messages/ToolMessage.tsx +26 -40
  51. package/src/ui/containers/AppContainer/builders/buildUIActions.ts +3 -1
  52. package/src/ui/containers/AppContainer/builders/buildUIState.ts +5 -4
  53. package/src/ui/containers/AppContainer/hooks/useAppBootstrap.ts +3 -33
  54. package/src/ui/containers/AppContainer/hooks/useAppDialogs.ts +2 -14
  55. package/src/ui/containers/AppContainer/hooks/useAppInput.ts +31 -25
  56. package/src/ui/containers/AppContainer/hooks/useAppLayout.ts +90 -60
  57. package/src/ui/containers/AppContainer/hooks/useDisplayPreferences.ts +10 -0
  58. package/src/ui/containers/AppContainer/hooks/useInputHandling.ts +3 -17
  59. package/src/ui/containers/AppContainer/hooks/useKeybindings.ts +51 -38
  60. package/src/ui/containers/AppContainer/hooks/useSteer.ts +51 -0
  61. package/src/ui/contexts/KeypressContext.tsx +13 -2
  62. package/src/ui/contexts/ShellCommandDisplayContext.tsx +103 -0
  63. package/src/ui/contexts/TodoContext.tsx +0 -13
  64. package/src/ui/contexts/TodoProvider.tsx +1 -34
  65. package/src/ui/contexts/UIActionsContext.tsx +2 -1
  66. package/src/ui/contexts/UIStateContext.tsx +3 -2
  67. package/src/ui/hooks/agentStream/streamUtils.ts +0 -24
  68. package/src/ui/hooks/agentStream/thoughtState.ts +110 -30
  69. package/src/ui/hooks/agentStream/types.ts +1 -0
  70. package/src/ui/hooks/agentStream/useAgentEventStream.ts +8 -17
  71. package/src/ui/hooks/agentStream/useAgentStream.ts +2 -2
  72. package/src/ui/hooks/agentStream/useAgentStreamLifecycle.ts +4 -5
  73. package/src/ui/hooks/agentStream/useAgentStreamOrchestration.ts +12 -5
  74. package/src/ui/hooks/agentStream/useQueuedSubmissions.ts +99 -0
  75. package/src/ui/hooks/agentStream/useStreamEventHandlers.ts +4 -13
  76. package/src/ui/hooks/agentStream/useStreamState.ts +60 -41
  77. package/src/ui/hooks/agentStream/useSubmitQuery.ts +284 -59
  78. package/src/ui/hooks/slashCommandProcessorSupport.ts +4 -0
  79. package/src/ui/hooks/useAgentStream-test-helpers.ts +1 -0
  80. package/src/ui/hooks/useAutoAcceptIndicator.ts +13 -0
  81. package/src/ui/hooks/useFolderTrust.ts +118 -81
  82. package/src/ui/hooks/useGitBranchName.ts +79 -33
  83. package/src/ui/hooks/useIdeTrustListener.ts +5 -19
  84. package/src/ui/hooks/usePermissionsModifyTrust.ts +223 -85
  85. package/src/ui/hooks/useReactToolScheduler.ts +13 -17
  86. package/src/ui/hooks/useTodoPausePreserver.ts +0 -55
  87. package/src/ui/layouts/DefaultAppLayout.tsx +2 -0
  88. package/src/ui/layouts/DefaultAppLayoutHelpers.tsx +37 -162
  89. package/src/ui/layouts/InlineContent.tsx +198 -0
  90. package/src/ui/trustDialogHelpers.ts +190 -0
  91. package/src/utils/cleanup-state.ts +115 -0
  92. package/src/utils/cleanup.ts +32 -34
  93. package/src/utils/sandbox-containers.ts +183 -53
  94. package/src/utils/sandbox-exec.ts +9 -3
  95. package/src/zed-integration/acp-terminal-shell-host.ts +112 -0
  96. package/src/zed-integration/acp-types.ts +35 -0
  97. package/src/zed-integration/fileSystemService.ts +1 -1
  98. package/src/zed-integration/runZedIntegration.ts +142 -0
  99. package/src/zed-integration/zed-agent-event-handler.ts +179 -0
  100. package/src/zed-integration/zed-agent-setup.ts +43 -0
  101. package/src/zed-integration/zed-command-registry.ts +167 -0
  102. package/src/zed-integration/zed-config-options.ts +280 -0
  103. package/src/zed-integration/zed-content-utils.ts +2 -2
  104. package/src/zed-integration/zed-helpers.ts +132 -0
  105. package/src/zed-integration/zed-initialize.ts +64 -0
  106. package/src/zed-integration/zed-plan-update.ts +20 -0
  107. package/src/zed-integration/zed-prompt-command.ts +77 -0
  108. package/src/zed-integration/zed-session-config.ts +119 -0
  109. package/src/zed-integration/zed-session-errors.ts +337 -0
  110. package/src/zed-integration/zed-session-events.ts +216 -0
  111. package/src/zed-integration/zed-session-info.ts +255 -0
  112. package/src/zed-integration/zed-session-lifecycle.ts +186 -0
  113. package/src/zed-integration/zed-session-listing.ts +153 -0
  114. package/src/zed-integration/zed-session-loader.ts +193 -0
  115. package/src/zed-integration/zed-session-pagination.ts +240 -0
  116. package/src/zed-integration/zed-session-replay.ts +564 -0
  117. package/src/zed-integration/zed-stream-batcher.ts +236 -0
  118. package/src/zed-integration/zed-terminal-manager.ts +416 -0
  119. package/src/zed-integration/zed-terminal-setup.ts +72 -0
  120. package/src/zed-integration/zed-test-helpers.ts +349 -4
  121. package/src/zed-integration/zed-tool-handler.ts +47 -5
  122. package/src/zed-integration/zedIntegration.ts +538 -587
  123. package/src/services/todo-continuation/todoContinuationService.ts +0 -610
  124. package/src/ui/containers/AppContainer/hooks/useIdeRestartHotkey.ts +0 -33
  125. package/src/ui/containers/AppContainer/hooks/useTodoContinuationFlow.ts +0 -160
  126. package/src/ui/hooks/useTodoContinuation.ts +0 -299
@@ -1,610 +0,0 @@
1
- /**
2
- * @license
3
- * Copyright 2025 Vybestack LLC
4
- * SPDX-License-Identifier: Apache-2.0
5
- */
6
-
7
- import type { Config, Todo } from '@vybestack/llxprt-code-core';
8
-
9
- /**
10
- * Test mock config interface for unit tests
11
- */
12
- interface MockConfig {
13
- continuationEnabled?: boolean;
14
- }
15
-
16
- type ContinuationConfig = Config | MockConfig | null | undefined;
17
-
18
- interface ConfigWithEphemeralSettings {
19
- getEphemeralSetting(key: string): unknown;
20
- }
21
-
22
- /**
23
- * Type guard to check if config has continuation enabled property (test mock)
24
- */
25
- function isMockConfig(config: unknown): config is MockConfig {
26
- return (
27
- typeof config === 'object' &&
28
- config !== null &&
29
- 'continuationEnabled' in config
30
- );
31
- }
32
-
33
- function hasEphemeralSettings(
34
- config: unknown,
35
- ): config is ConfigWithEphemeralSettings {
36
- return (
37
- typeof config === 'object' &&
38
- config !== null &&
39
- 'getEphemeralSetting' in config &&
40
- typeof config.getEphemeralSetting === 'function'
41
- );
42
- }
43
-
44
- function getContinuationEnabled(config: ContinuationConfig): unknown {
45
- if (config === null || config === undefined) {
46
- return true;
47
- }
48
-
49
- if (isMockConfig(config)) {
50
- return config.continuationEnabled;
51
- }
52
-
53
- if (hasEphemeralSettings(config)) {
54
- return config.getEphemeralSetting('todo-continuation');
55
- }
56
-
57
- return true;
58
- }
59
-
60
- /**
61
- * Configuration for generating continuation prompts
62
- */
63
- export interface ContinuationPromptConfig {
64
- readonly taskDescription: string;
65
- readonly isYoloMode: boolean;
66
- readonly attemptCount?: number;
67
- readonly previousFailure?: string;
68
- }
69
-
70
- /**
71
- * Context information for evaluating continuation conditions
72
- */
73
- export interface ContinuationContext {
74
- readonly todos: readonly Todo[];
75
- readonly hadToolCalls: boolean;
76
- readonly isResponding: boolean;
77
- readonly config: Config;
78
- readonly currentState: ContinuationState;
79
- readonly todoPaused?: boolean;
80
- }
81
-
82
- /**
83
- * Result of evaluating continuation conditions
84
- */
85
- export interface ContinuationEvaluation {
86
- readonly shouldContinue: boolean;
87
- readonly reason: string;
88
- readonly activeTodo?: Todo;
89
- readonly conditions: ConditionSet;
90
- }
91
-
92
- /**
93
- * State tracking for continuation attempts
94
- */
95
- export interface ContinuationState {
96
- isActive: boolean;
97
- attemptCount: number;
98
- taskDescription?: string;
99
- lastPromptTime?: Date;
100
- }
101
-
102
- /**
103
- * Set of conditions evaluated for continuation
104
- */
105
- export interface ConditionSet {
106
- readonly hasActiveTodos: boolean;
107
- readonly noToolCallsMade: boolean;
108
- readonly continuationEnabled: boolean;
109
- readonly notCurrentlyContinuing: boolean;
110
- readonly withinAttemptLimits: boolean;
111
- readonly withinTimeConstraints: boolean;
112
- readonly todoPaused: boolean;
113
- }
114
-
115
- /**
116
- * Template structure for continuation prompts
117
- */
118
- export interface ContinuationPromptTemplates {
119
- readonly standard: {
120
- readonly base: string;
121
- readonly retry: string;
122
- };
123
- readonly yolo: {
124
- readonly base: string;
125
- readonly retry: string;
126
- readonly urgent: string;
127
- };
128
- }
129
-
130
- /**
131
- * Service responsible for generating continuation prompts and managing continuation logic
132
- */
133
- export class TodoContinuationService {
134
- private static readonly MAX_CONTINUATION_ATTEMPTS = 3;
135
- private static readonly MIN_CONTINUATION_INTERVAL_MS = 1000;
136
- // Future enhancement: Add timeout functionality
137
- // private static readonly CONTINUATION_TIMEOUT_MS = 30000;
138
- private static readonly MAX_TASK_DESCRIPTION_LENGTH = 200;
139
- // Matches a leading list marker (-, *, or +) with trailing spaces. The
140
- // pattern is passed to RegExp via an identifier so it is not a static literal
141
- // flagged by sonarjs/regular-expr.
142
- private static readonly LIST_MARKER_PATTERN = '^[-*+]\\s*';
143
- private static readonly LIST_MARKER_REGEX = new RegExp(
144
- TodoContinuationService.LIST_MARKER_PATTERN,
145
- );
146
-
147
- /**
148
- * Generates a continuation prompt based on the provided configuration
149
- * @param config Configuration for prompt generation
150
- * @returns Formatted continuation prompt string
151
- */
152
- generateContinuationPrompt(
153
- config: ContinuationPromptConfig | null | undefined,
154
- ): string {
155
- if (config === null || config === undefined) {
156
- throw new Error('Configuration is required');
157
- }
158
-
159
- const taskDescription = this.truncateTaskDescription(
160
- config.taskDescription,
161
- );
162
-
163
- if (config.isYoloMode) {
164
- return this.generateYoloModePrompt(
165
- taskDescription,
166
- config.attemptCount,
167
- config.previousFailure,
168
- );
169
- }
170
- return this.generateStandardPrompt(
171
- taskDescription,
172
- config.attemptCount,
173
- config.previousFailure,
174
- );
175
- }
176
-
177
- /**
178
- * Evaluates whether continuation should occur based on current conditions
179
- * @param context Current continuation context
180
- * @returns Evaluation result with decision and reasoning
181
- */
182
- checkContinuationConditions(
183
- context: ContinuationContext | null | undefined,
184
- ): ContinuationEvaluation {
185
- if (context === null || context === undefined) {
186
- throw new Error('Context is required');
187
- }
188
-
189
- const conditions = this.evaluateAllConditions(context);
190
-
191
- // Check each condition and provide specific feedback
192
- if (!conditions.continuationEnabled) {
193
- return {
194
- shouldContinue: false,
195
- reason: 'Todo continuation is disabled in ephemeral settings',
196
- conditions,
197
- };
198
- }
199
-
200
- if (!conditions.hasActiveTodos) {
201
- return {
202
- shouldContinue: false,
203
- reason: 'No active todos found (pending or in_progress)',
204
- conditions,
205
- };
206
- }
207
-
208
- if (context.todoPaused === true) {
209
- return {
210
- shouldContinue: false,
211
- reason: 'Todo continuation paused by todo_pause tool',
212
- conditions,
213
- };
214
- }
215
-
216
- if (!conditions.noToolCallsMade) {
217
- return {
218
- shouldContinue: false,
219
- reason: 'Tool calls were made during stream - no continuation needed',
220
- conditions,
221
- };
222
- }
223
-
224
- if (!conditions.notCurrentlyContinuing) {
225
- return {
226
- shouldContinue: false,
227
- reason: 'Already continuing task',
228
- conditions,
229
- };
230
- }
231
-
232
- if (!conditions.withinAttemptLimits) {
233
- return {
234
- shouldContinue: false,
235
- reason: 'Continuation attempt limit reached',
236
- conditions,
237
- };
238
- }
239
-
240
- if (!conditions.withinTimeConstraints) {
241
- return {
242
- shouldContinue: false,
243
- reason: 'Time constraint violated - too soon since last attempt',
244
- conditions,
245
- };
246
- }
247
-
248
- // Find the active task to continue
249
- const activeTodo = this.findBestActiveTodo(context.todos);
250
- if (!activeTodo) {
251
- return {
252
- shouldContinue: false,
253
- reason: 'No suitable active todo found',
254
- conditions,
255
- };
256
- }
257
-
258
- // All conditions met
259
- return {
260
- shouldContinue: true,
261
- reason: 'Active todo found and all continuation conditions satisfied',
262
- conditions,
263
- activeTodo,
264
- };
265
- }
266
-
267
- /**
268
- * Formats a task item's content into a task description
269
- * @param taskItem Task item to format
270
- * @returns Formatted task description string
271
- */
272
- formatTaskDescription(taskItem: Todo | null | undefined): string {
273
- if (
274
- taskItem === null ||
275
- taskItem === undefined ||
276
- taskItem.content.length === 0
277
- ) {
278
- return 'Complete task';
279
- }
280
-
281
- let description = taskItem.content.trim();
282
-
283
- if (description.length === 0) {
284
- return 'Complete task';
285
- }
286
-
287
- // Clean up formatting
288
- // Static regex for whitespace normalization - no dynamic parts
289
-
290
- description = description.replace(/\s+/g, ' '); // Normalize whitespace
291
- description = description.replace(
292
- TodoContinuationService.LIST_MARKER_REGEX,
293
- '',
294
- ); // Remove list markers
295
-
296
- // Truncate if too long
297
- if (
298
- description.length > TodoContinuationService.MAX_TASK_DESCRIPTION_LENGTH
299
- ) {
300
- description =
301
- description.substring(
302
- 0,
303
- TodoContinuationService.MAX_TASK_DESCRIPTION_LENGTH - 3,
304
- ) + '...';
305
- }
306
-
307
- return description;
308
- }
309
-
310
- /**
311
- * Checks if continuation should be allowed based on configuration and state
312
- * @param config Application configuration
313
- * @param state Current continuation state
314
- * @returns Whether continuation is allowed
315
- */
316
- shouldAllowContinuation(
317
- config: ContinuationConfig,
318
- state: ContinuationState,
319
- ): boolean {
320
- // Check ephemeral setting safely
321
- const continuationEnabled = getContinuationEnabled(config);
322
-
323
- if (continuationEnabled === false) {
324
- return false;
325
- }
326
-
327
- // Check attempt limits
328
- if (
329
- state.attemptCount >= TodoContinuationService.MAX_CONTINUATION_ATTEMPTS
330
- ) {
331
- return false;
332
- }
333
-
334
- // Check time constraints
335
- if (state.lastPromptTime !== undefined) {
336
- const timeSinceLastPrompt = Date.now() - state.lastPromptTime.getTime();
337
- if (
338
- timeSinceLastPrompt <
339
- TodoContinuationService.MIN_CONTINUATION_INTERVAL_MS
340
- ) {
341
- return false;
342
- }
343
- }
344
-
345
- return true;
346
- }
347
-
348
- /**
349
- * Creates a new, empty continuation state
350
- * @returns Initial continuation state
351
- */
352
- createContinuationState(): ContinuationState {
353
- return {
354
- isActive: false,
355
- attemptCount: 0,
356
- taskDescription: undefined,
357
- lastPromptTime: undefined,
358
- };
359
- }
360
-
361
- // Additional method mentioned in requirements but not in original pseudocode
362
- /**
363
- * Checks whether continuation should occur based on settings, todos, and tool calls
364
- * @param settings Application settings/config
365
- * @param hasActiveTodos Whether there are active todos
366
- * @param hasToolCalls Whether tool calls were made
367
- * @returns Whether continuation should proceed
368
- */
369
- shouldContinue(
370
- settings: ContinuationConfig,
371
- hasActiveTodos: boolean,
372
- hasToolCalls: boolean,
373
- ): boolean {
374
- // Don't continue if tool calls were made
375
- if (hasToolCalls) {
376
- return false;
377
- }
378
-
379
- // Don't continue if no active todos
380
- if (!hasActiveTodos) {
381
- return false;
382
- }
383
-
384
- // Check if continuation is enabled safely
385
- const continuationEnabled = getContinuationEnabled(settings);
386
-
387
- return continuationEnabled !== false;
388
- }
389
-
390
- // Additional method mentioned in requirements but not in original pseudocode
391
- /**
392
- * Formats a prompt for task description and YOLO mode
393
- * @param taskDescription Description of the task to continue
394
- * @param isYoloMode Whether YOLO mode is enabled
395
- * @returns Formatted prompt string
396
- */
397
- formatPrompt(taskDescription: string, isYoloMode: boolean): string {
398
- const truncatedDescription = this.truncateTaskDescription(taskDescription);
399
-
400
- if (isYoloMode) {
401
- return this.generateYoloModePrompt(truncatedDescription);
402
- }
403
- return this.generateStandardPrompt(truncatedDescription);
404
- }
405
-
406
- /**
407
- * Private method to truncate task descriptions to acceptable length
408
- * @param description Task description to truncate
409
- * @returns Truncated description
410
- */
411
- private truncateTaskDescription(description: string): string {
412
- if (!description || description.length === 0) {
413
- return 'Complete task';
414
- }
415
-
416
- if (
417
- description.length <= TodoContinuationService.MAX_TASK_DESCRIPTION_LENGTH
418
- ) {
419
- return description;
420
- }
421
-
422
- // Try to truncate at word boundary
423
- const truncated = description.substring(
424
- 0,
425
- TodoContinuationService.MAX_TASK_DESCRIPTION_LENGTH,
426
- );
427
- const lastSpaceIndex = truncated.lastIndexOf(' ');
428
-
429
- if (
430
- lastSpaceIndex >
431
- TodoContinuationService.MAX_TASK_DESCRIPTION_LENGTH * 0.8
432
- ) {
433
- // Good word boundary found
434
- return truncated.substring(0, lastSpaceIndex) + '...';
435
- }
436
- // No good word boundary, hard truncate
437
- return (
438
- truncated.substring(
439
- 0,
440
- TodoContinuationService.MAX_TASK_DESCRIPTION_LENGTH - 3,
441
- ) + '...'
442
- );
443
- }
444
-
445
- /**
446
- * Private method to generate standard continuation prompt
447
- * @param taskDescription Task description
448
- * @param attemptCount Optional attempt count
449
- * @returns Standard prompt string
450
- */
451
- private generateStandardPrompt(
452
- taskDescription: string,
453
- attemptCount?: number,
454
- previousFailure?: string,
455
- ): string {
456
- const basePrompt = [
457
- 'You have an active task that needs completion:',
458
- `'${taskDescription}'`,
459
- '',
460
- "Continue working on this task. Call todo_pause('reason') ONLY if there's an error preventing you from continuing.",
461
- '',
462
- 'Remember to:',
463
- '- Focus on the specific task described',
464
- '- Make concrete progress toward completion',
465
- '- Update the task status when appropriate',
466
- '- Use todo_pause() if you encounter blockers',
467
- ].join('\n');
468
-
469
- let result = basePrompt;
470
-
471
- if (previousFailure !== undefined && previousFailure.length > 0) {
472
- result += `\n\nPrevious failure information: ${previousFailure}`;
473
- }
474
-
475
- if (attemptCount !== undefined && attemptCount > 1) {
476
- const retryNote = `\n\nNote: This is continuation attempt #${attemptCount}. Please make sure to take concrete action.`;
477
- result += retryNote;
478
- }
479
-
480
- return result;
481
- }
482
-
483
- /**
484
- * Private method to generate YOLO mode continuation prompt
485
- * @param taskDescription Task description
486
- * @param attemptCount Optional attempt count
487
- * @returns YOLO mode prompt string
488
- */
489
- private generateYoloModePrompt(
490
- taskDescription: string,
491
- attemptCount?: number,
492
- previousFailure?: string,
493
- ): string {
494
- const basePrompt = [
495
- 'CONTINUE TASK IMMEDIATELY:',
496
- `'${taskDescription}'`,
497
- '',
498
- "You MUST continue working on this task. Call todo_pause('reason') ONLY if there's an error preventing you from proceeding.",
499
- '',
500
- 'YOLO MODE - Take action now:',
501
- '- Execute the task without asking for confirmation',
502
- '- Make concrete progress immediately',
503
- '- Only pause if there are actual blocking errors',
504
- '- Update task status when complete',
505
- ].join('\n');
506
-
507
- let result = basePrompt;
508
-
509
- if (previousFailure !== undefined && previousFailure.length > 0) {
510
- result += `\n\nPrevious failure information: ${previousFailure}`;
511
- }
512
-
513
- if (attemptCount !== undefined && attemptCount > 1) {
514
- const urgentRetry = `\n\nATTEMPT #${attemptCount} - YOU MUST TAKE ACTION NOW. No more analysis, proceed with execution.`;
515
- result += urgentRetry;
516
- }
517
-
518
- return result;
519
- }
520
-
521
- /**
522
- * Private method to evaluate all continuation conditions
523
- * @param context Continuation context
524
- * @returns Evaluated condition set
525
- */
526
- private evaluateAllConditions(context: ContinuationContext): ConditionSet {
527
- // Safely get ephemeral setting with fallback
528
- const continuationSetting = getContinuationEnabled(context.config);
529
-
530
- const hasActiveTodos = this.hasAnyActiveTodos(context.todos);
531
- const todoPaused = context.todoPaused === true;
532
- const hadBlockingToolCalls =
533
- context.hadToolCalls && (todoPaused || !hasActiveTodos);
534
-
535
- return {
536
- hasActiveTodos,
537
- noToolCallsMade: !hadBlockingToolCalls,
538
- continuationEnabled: continuationSetting !== false,
539
- notCurrentlyContinuing: !context.currentState.isActive,
540
- withinAttemptLimits:
541
- context.currentState.attemptCount <
542
- TodoContinuationService.MAX_CONTINUATION_ATTEMPTS,
543
- withinTimeConstraints: this.checkTimeConstraints(
544
- context.currentState.lastPromptTime,
545
- ),
546
- todoPaused,
547
- };
548
- }
549
-
550
- /**
551
- * Private method to check if there are any active todos
552
- * @param todos Array of todos to check
553
- * @returns Whether active todos exist
554
- */
555
- private hasAnyActiveTodos(todos: readonly Todo[]): boolean {
556
- return todos.some(
557
- (todo) => todo.status === 'pending' || todo.status === 'in_progress',
558
- );
559
- }
560
-
561
- /**
562
- * Private method to find the best active task to continue
563
- * @param todos Array of tasks to search
564
- * @returns Best active task or undefined
565
- */
566
- private findBestActiveTodo(todos: readonly Todo[]): Todo | undefined {
567
- // First: Find in_progress todos (should be max 1)
568
- const inProgressTodos = todos.filter(
569
- (todo) => todo.status === 'in_progress',
570
- );
571
- if (inProgressTodos.length > 0) {
572
- return inProgressTodos[0];
573
- }
574
-
575
- // Second: Find pending todos, sort alphabetically by content
576
- const pendingTodos = todos.filter((todo) => todo.status === 'pending');
577
- if (pendingTodos.length > 0) {
578
- // Sort alphabetically by content
579
- pendingTodos.sort((a, b) => a.content.localeCompare(b.content));
580
- return pendingTodos[0];
581
- }
582
-
583
- return undefined;
584
- }
585
-
586
- /**
587
- * Private method to check time constraints for continuation
588
- * @param lastPromptTime Time of last continuation prompt
589
- * @returns Whether time constraints are satisfied
590
- */
591
- private checkTimeConstraints(lastPromptTime?: Date): boolean {
592
- if (lastPromptTime === undefined) {
593
- return true; // No previous attempt, allowed
594
- }
595
-
596
- const timeSinceLastPrompt = Date.now() - lastPromptTime.getTime();
597
- return (
598
- timeSinceLastPrompt >=
599
- TodoContinuationService.MIN_CONTINUATION_INTERVAL_MS
600
- );
601
- }
602
- }
603
-
604
- /**
605
- * Factory function to create a new TodoContinuationService instance
606
- * @returns New service instance
607
- */
608
- export function createTodoContinuationService(): TodoContinuationService {
609
- return new TodoContinuationService();
610
- }
@@ -1,33 +0,0 @@
1
- /**
2
- * @license
3
- * Copyright 2025 Vybestack LLC
4
- * SPDX-License-Identifier: Apache-2.0
5
- */
6
-
7
- import process from 'node:process';
8
- import { useKeypress } from '../../../hooks/useKeypress.js';
9
-
10
- interface UseIdeRestartHotkeyParams {
11
- isActive: boolean;
12
- }
13
-
14
- /**
15
- * @hook useIdeRestartHotkey
16
- * @description Exits process when restart prompt is active and user presses R
17
- * @inputs isActive
18
- * @outputs void
19
- * @sideEffects Registers keypress handler
20
- * @cleanup useKeypress handles cleanup
21
- */
22
- export function useIdeRestartHotkey({
23
- isActive,
24
- }: UseIdeRestartHotkeyParams): void {
25
- useKeypress(
26
- (key) => {
27
- if (key.name === 'r' || key.name === 'R') {
28
- process.exit(0);
29
- }
30
- },
31
- { isActive },
32
- );
33
- }