charness 0.0.0-stage → 3.1.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/.env.example +88 -0
- package/DEVELOPMENT.md +110 -0
- package/LICENSE +21 -0
- package/MIGRATION_1_TO_2.md +24 -0
- package/README.md +1196 -2
- package/dist/accessControl.d.ts +71 -0
- package/dist/accessControl.d.ts.map +1 -0
- package/dist/accessControl.js +108 -0
- package/dist/accessControl.js.map +1 -0
- package/dist/adapters/adapterEventRouting.d.ts +51 -0
- package/dist/adapters/adapterEventRouting.d.ts.map +1 -0
- package/dist/adapters/adapterEventRouting.js +74 -0
- package/dist/adapters/adapterEventRouting.js.map +1 -0
- package/dist/adapters/adapterNames.d.ts +19 -0
- package/dist/adapters/adapterNames.d.ts.map +1 -0
- package/dist/adapters/adapterNames.js +25 -0
- package/dist/adapters/adapterNames.js.map +1 -0
- package/dist/adapters/claudeCliAdapter.d.ts +1351 -0
- package/dist/adapters/claudeCliAdapter.d.ts.map +1 -0
- package/dist/adapters/claudeCliAdapter.js +4239 -0
- package/dist/adapters/claudeCliAdapter.js.map +1 -0
- package/dist/adapters/claudeConfigDir.d.ts +40 -0
- package/dist/adapters/claudeConfigDir.d.ts.map +1 -0
- package/dist/adapters/claudeConfigDir.js +3 -0
- package/dist/adapters/claudeConfigDir.js.map +1 -0
- package/dist/adapters/claudeJsonStreamAdapter.d.ts +580 -0
- package/dist/adapters/claudeJsonStreamAdapter.d.ts.map +1 -0
- package/dist/adapters/claudeJsonStreamAdapter.js +1891 -0
- package/dist/adapters/claudeJsonStreamAdapter.js.map +1 -0
- package/dist/adapters/claudePlatformFlags.d.ts +35 -0
- package/dist/adapters/claudePlatformFlags.d.ts.map +1 -0
- package/dist/adapters/claudePlatformFlags.js +46 -0
- package/dist/adapters/claudePlatformFlags.js.map +1 -0
- package/dist/adapters/createAdapter.d.ts +260 -0
- package/dist/adapters/createAdapter.d.ts.map +1 -0
- package/dist/adapters/createAdapter.js +512 -0
- package/dist/adapters/createAdapter.js.map +1 -0
- package/dist/adapters/openCodeAdapter.d.ts +1469 -0
- package/dist/adapters/openCodeAdapter.d.ts.map +1 -0
- package/dist/adapters/openCodeAdapter.js +4623 -0
- package/dist/adapters/openCodeAdapter.js.map +1 -0
- package/dist/adapters/sessionLaunchDefaults.d.ts +28 -0
- package/dist/adapters/sessionLaunchDefaults.d.ts.map +1 -0
- package/dist/adapters/sessionLaunchDefaults.js +15 -0
- package/dist/adapters/sessionLaunchDefaults.js.map +1 -0
- package/dist/adapters/terminalAdapter.d.ts +68 -0
- package/dist/adapters/terminalAdapter.d.ts.map +1 -0
- package/dist/adapters/terminalAdapter.js +371 -0
- package/dist/adapters/terminalAdapter.js.map +1 -0
- package/dist/agentLogin/agentLogin.d.ts +44 -0
- package/dist/agentLogin/agentLogin.d.ts.map +1 -0
- package/dist/agentLogin/agentLogin.js +530 -0
- package/dist/agentLogin/agentLogin.js.map +1 -0
- package/dist/agentTrigger.d.ts +28 -0
- package/dist/agentTrigger.d.ts.map +1 -0
- package/dist/agentTrigger.js +53 -0
- package/dist/agentTrigger.js.map +1 -0
- package/dist/apiErrorRetry.d.ts +214 -0
- package/dist/apiErrorRetry.d.ts.map +1 -0
- package/dist/apiErrorRetry.js +382 -0
- package/dist/apiErrorRetry.js.map +1 -0
- package/dist/apiRetryKick.d.ts +157 -0
- package/dist/apiRetryKick.d.ts.map +1 -0
- package/dist/apiRetryKick.js +174 -0
- package/dist/apiRetryKick.js.map +1 -0
- package/dist/bootClassifier.d.ts +46 -0
- package/dist/bootClassifier.d.ts.map +1 -0
- package/dist/bootClassifier.js +43 -0
- package/dist/bootClassifier.js.map +1 -0
- package/dist/bot.d.ts +207 -0
- package/dist/bot.d.ts.map +1 -0
- package/dist/bot.js +11226 -0
- package/dist/bot.js.map +1 -0
- package/dist/botFileStorage.d.ts +60 -0
- package/dist/botFileStorage.d.ts.map +1 -0
- package/dist/botFileStorage.js +205 -0
- package/dist/botFileStorage.js.map +1 -0
- package/dist/cli/applyDnsFix.d.ts +7 -0
- package/dist/cli/applyDnsFix.d.ts.map +1 -0
- package/dist/cli/applyDnsFix.js +46 -0
- package/dist/cli/applyDnsFix.js.map +1 -0
- package/dist/cli/bot.d.ts +27 -0
- package/dist/cli/bot.d.ts.map +1 -0
- package/dist/cli/bot.js +98 -0
- package/dist/cli/bot.js.map +1 -0
- package/dist/cli/botEntry.d.ts +3 -0
- package/dist/cli/botEntry.d.ts.map +1 -0
- package/dist/cli/botEntry.js +11 -0
- package/dist/cli/botEntry.js.map +1 -0
- package/dist/cli/claudeProfiles.d.ts +42 -0
- package/dist/cli/claudeProfiles.d.ts.map +1 -0
- package/dist/cli/claudeProfiles.js +106 -0
- package/dist/cli/claudeProfiles.js.map +1 -0
- package/dist/cli/connectorGuards.d.ts +31 -0
- package/dist/cli/connectorGuards.d.ts.map +1 -0
- package/dist/cli/connectorGuards.js +159 -0
- package/dist/cli/connectorGuards.js.map +1 -0
- package/dist/cli/envLoader.d.ts +34 -0
- package/dist/cli/envLoader.d.ts.map +1 -0
- package/dist/cli/envLoader.js +132 -0
- package/dist/cli/envLoader.js.map +1 -0
- package/dist/cli/hot.d.ts +82 -0
- package/dist/cli/hot.d.ts.map +1 -0
- package/dist/cli/hot.js +323 -0
- package/dist/cli/hot.js.map +1 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +140 -0
- package/dist/cli.js.map +1 -0
- package/dist/connectors/jira/adf.d.ts +74 -0
- package/dist/connectors/jira/adf.d.ts.map +1 -0
- package/dist/connectors/jira/adf.js +412 -0
- package/dist/connectors/jira/adf.js.map +1 -0
- package/dist/connectors/jira/agentBinaries.d.ts +14 -0
- package/dist/connectors/jira/agentBinaries.d.ts.map +1 -0
- package/dist/connectors/jira/agentBinaries.js +75 -0
- package/dist/connectors/jira/agentBinaries.js.map +1 -0
- package/dist/connectors/jira/answerSink.d.ts +59 -0
- package/dist/connectors/jira/answerSink.d.ts.map +1 -0
- package/dist/connectors/jira/answerSink.js +234 -0
- package/dist/connectors/jira/answerSink.js.map +1 -0
- package/dist/connectors/jira/attachmentDownload.d.ts +41 -0
- package/dist/connectors/jira/attachmentDownload.d.ts.map +1 -0
- package/dist/connectors/jira/attachmentDownload.js +92 -0
- package/dist/connectors/jira/attachmentDownload.js.map +1 -0
- package/dist/connectors/jira/attachmentTool.d.ts +50 -0
- package/dist/connectors/jira/attachmentTool.d.ts.map +1 -0
- package/dist/connectors/jira/attachmentTool.js +166 -0
- package/dist/connectors/jira/attachmentTool.js.map +1 -0
- package/dist/connectors/jira/client.d.ts +522 -0
- package/dist/connectors/jira/client.d.ts.map +1 -0
- package/dist/connectors/jira/client.js +491 -0
- package/dist/connectors/jira/client.js.map +1 -0
- package/dist/connectors/jira/config.d.ts +104 -0
- package/dist/connectors/jira/config.d.ts.map +1 -0
- package/dist/connectors/jira/config.js +323 -0
- package/dist/connectors/jira/config.js.map +1 -0
- package/dist/connectors/jira/configFile.d.ts +10 -0
- package/dist/connectors/jira/configFile.d.ts.map +1 -0
- package/dist/connectors/jira/configFile.js +50 -0
- package/dist/connectors/jira/configFile.js.map +1 -0
- package/dist/connectors/jira/connector.d.ts +71 -0
- package/dist/connectors/jira/connector.d.ts.map +1 -0
- package/dist/connectors/jira/connector.js +312 -0
- package/dist/connectors/jira/connector.js.map +1 -0
- package/dist/connectors/jira/contextLedger.d.ts +60 -0
- package/dist/connectors/jira/contextLedger.d.ts.map +1 -0
- package/dist/connectors/jira/contextLedger.js +196 -0
- package/dist/connectors/jira/contextLedger.js.map +1 -0
- package/dist/connectors/jira/contextPreamble.d.ts +18 -0
- package/dist/connectors/jira/contextPreamble.d.ts.map +1 -0
- package/dist/connectors/jira/contextPreamble.js +31 -0
- package/dist/connectors/jira/contextPreamble.js.map +1 -0
- package/dist/connectors/jira/inbound.d.ts +141 -0
- package/dist/connectors/jira/inbound.d.ts.map +1 -0
- package/dist/connectors/jira/inbound.js +331 -0
- package/dist/connectors/jira/inbound.js.map +1 -0
- package/dist/connectors/jira/issueBlocks.d.ts +74 -0
- package/dist/connectors/jira/issueBlocks.d.ts.map +1 -0
- package/dist/connectors/jira/issueBlocks.js +257 -0
- package/dist/connectors/jira/issueBlocks.js.map +1 -0
- package/dist/connectors/jira/issueContext.d.ts +31 -0
- package/dist/connectors/jira/issueContext.d.ts.map +1 -0
- package/dist/connectors/jira/issueContext.js +70 -0
- package/dist/connectors/jira/issueContext.js.map +1 -0
- package/dist/connectors/jira/issueDelta.d.ts +38 -0
- package/dist/connectors/jira/issueDelta.d.ts.map +1 -0
- package/dist/connectors/jira/issueDelta.js +59 -0
- package/dist/connectors/jira/issueDelta.js.map +1 -0
- package/dist/connectors/jira/mediaPlaceholders.d.ts +22 -0
- package/dist/connectors/jira/mediaPlaceholders.d.ts.map +1 -0
- package/dist/connectors/jira/mediaPlaceholders.js +105 -0
- package/dist/connectors/jira/mediaPlaceholders.js.map +1 -0
- package/dist/connectors/jira/outbound.d.ts +6 -0
- package/dist/connectors/jira/outbound.d.ts.map +1 -0
- package/dist/connectors/jira/outbound.js +38 -0
- package/dist/connectors/jira/outbound.js.map +1 -0
- package/dist/connectors/jira/prompt.d.ts +39 -0
- package/dist/connectors/jira/prompt.d.ts.map +1 -0
- package/dist/connectors/jira/prompt.js +102 -0
- package/dist/connectors/jira/prompt.js.map +1 -0
- package/dist/connectors/jira/promptSpill.d.ts +50 -0
- package/dist/connectors/jira/promptSpill.d.ts.map +1 -0
- package/dist/connectors/jira/promptSpill.js +157 -0
- package/dist/connectors/jira/promptSpill.js.map +1 -0
- package/dist/connectors/jira/promptText.d.ts +7 -0
- package/dist/connectors/jira/promptText.d.ts.map +1 -0
- package/dist/connectors/jira/promptText.js +26 -0
- package/dist/connectors/jira/promptText.js.map +1 -0
- package/dist/connectors/jira/sessionKeyCodec.d.ts +18 -0
- package/dist/connectors/jira/sessionKeyCodec.d.ts.map +1 -0
- package/dist/connectors/jira/sessionKeyCodec.js +106 -0
- package/dist/connectors/jira/sessionKeyCodec.js.map +1 -0
- package/dist/connectors/jira/trigger.d.ts +54 -0
- package/dist/connectors/jira/trigger.d.ts.map +1 -0
- package/dist/connectors/jira/trigger.js +101 -0
- package/dist/connectors/jira/trigger.js.map +1 -0
- package/dist/connectors/jira/triggerLog.d.ts +53 -0
- package/dist/connectors/jira/triggerLog.d.ts.map +1 -0
- package/dist/connectors/jira/triggerLog.js +78 -0
- package/dist/connectors/jira/triggerLog.js.map +1 -0
- package/dist/connectors/jira/trustedGroup.d.ts +54 -0
- package/dist/connectors/jira/trustedGroup.d.ts.map +1 -0
- package/dist/connectors/jira/trustedGroup.js +98 -0
- package/dist/connectors/jira/trustedGroup.js.map +1 -0
- package/dist/connectors/jira/unconfirmedPosts.d.ts +58 -0
- package/dist/connectors/jira/unconfirmedPosts.d.ts.map +1 -0
- package/dist/connectors/jira/unconfirmedPosts.js +105 -0
- package/dist/connectors/jira/unconfirmedPosts.js.map +1 -0
- package/dist/connectors/telegram/answerSink.d.ts +46 -0
- package/dist/connectors/telegram/answerSink.d.ts.map +1 -0
- package/dist/connectors/telegram/answerSink.js +71 -0
- package/dist/connectors/telegram/answerSink.js.map +1 -0
- package/dist/connectors/telegram/commands/autoContinueLimits.d.ts +34 -0
- package/dist/connectors/telegram/commands/autoContinueLimits.d.ts.map +1 -0
- package/dist/connectors/telegram/commands/autoContinueLimits.js +112 -0
- package/dist/connectors/telegram/commands/autoContinueLimits.js.map +1 -0
- package/dist/connectors/telegram/commands/botCore.d.ts +46 -0
- package/dist/connectors/telegram/commands/botCore.d.ts.map +1 -0
- package/dist/connectors/telegram/commands/botCore.js +3 -0
- package/dist/connectors/telegram/commands/botCore.js.map +1 -0
- package/dist/connectors/telegram/commands/callbackMessage.d.ts +12 -0
- package/dist/connectors/telegram/commands/callbackMessage.d.ts.map +1 -0
- package/dist/connectors/telegram/commands/callbackMessage.js +13 -0
- package/dist/connectors/telegram/commands/callbackMessage.js.map +1 -0
- package/dist/connectors/telegram/commands/claudeAccounts.d.ts +58 -0
- package/dist/connectors/telegram/commands/claudeAccounts.d.ts.map +1 -0
- package/dist/connectors/telegram/commands/claudeAccounts.js +591 -0
- package/dist/connectors/telegram/commands/claudeAccounts.js.map +1 -0
- package/dist/connectors/telegram/commands/compaction.d.ts +47 -0
- package/dist/connectors/telegram/commands/compaction.d.ts.map +1 -0
- package/dist/connectors/telegram/commands/compaction.js +868 -0
- package/dist/connectors/telegram/commands/compaction.js.map +1 -0
- package/dist/connectors/telegram/commands/displayModes.d.ts +13 -0
- package/dist/connectors/telegram/commands/displayModes.d.ts.map +1 -0
- package/dist/connectors/telegram/commands/displayModes.js +335 -0
- package/dist/connectors/telegram/commands/displayModes.js.map +1 -0
- package/dist/connectors/telegram/commands/fallbackChain.d.ts +49 -0
- package/dist/connectors/telegram/commands/fallbackChain.d.ts.map +1 -0
- package/dist/connectors/telegram/commands/fallbackChain.js +624 -0
- package/dist/connectors/telegram/commands/fallbackChain.js.map +1 -0
- package/dist/connectors/telegram/commands/modelProviders.d.ts +117 -0
- package/dist/connectors/telegram/commands/modelProviders.d.ts.map +1 -0
- package/dist/connectors/telegram/commands/modelProviders.js +966 -0
- package/dist/connectors/telegram/commands/modelProviders.js.map +1 -0
- package/dist/connectors/telegram/commands/reminders.d.ts +54 -0
- package/dist/connectors/telegram/commands/reminders.d.ts.map +1 -0
- package/dist/connectors/telegram/commands/reminders.js +624 -0
- package/dist/connectors/telegram/commands/reminders.js.map +1 -0
- package/dist/connectors/telegram/fileIntake.d.ts +166 -0
- package/dist/connectors/telegram/fileIntake.d.ts.map +1 -0
- package/dist/connectors/telegram/fileIntake.js +304 -0
- package/dist/connectors/telegram/fileIntake.js.map +1 -0
- package/dist/connectors/telegram/fileSendGateway.d.ts +57 -0
- package/dist/connectors/telegram/fileSendGateway.d.ts.map +1 -0
- package/dist/connectors/telegram/fileSendGateway.js +221 -0
- package/dist/connectors/telegram/fileSendGateway.js.map +1 -0
- package/dist/connectors/telegram/foreignKeyFallbacks.d.ts +52 -0
- package/dist/connectors/telegram/foreignKeyFallbacks.d.ts.map +1 -0
- package/dist/connectors/telegram/foreignKeyFallbacks.js +71 -0
- package/dist/connectors/telegram/foreignKeyFallbacks.js.map +1 -0
- package/dist/connectors/telegram/inbound.d.ts +131 -0
- package/dist/connectors/telegram/inbound.d.ts.map +1 -0
- package/dist/connectors/telegram/inbound.js +278 -0
- package/dist/connectors/telegram/inbound.js.map +1 -0
- package/dist/connectors/telegram/languagePicker.d.ts +32 -0
- package/dist/connectors/telegram/languagePicker.d.ts.map +1 -0
- package/dist/connectors/telegram/languagePicker.js +55 -0
- package/dist/connectors/telegram/languagePicker.js.map +1 -0
- package/dist/connectors/telegram/messageSplit.d.ts +62 -0
- package/dist/connectors/telegram/messageSplit.d.ts.map +1 -0
- package/dist/connectors/telegram/messageSplit.js +119 -0
- package/dist/connectors/telegram/messageSplit.js.map +1 -0
- package/dist/connectors/telegram/outbound.d.ts +62 -0
- package/dist/connectors/telegram/outbound.d.ts.map +1 -0
- package/dist/connectors/telegram/outbound.js +116 -0
- package/dist/connectors/telegram/outbound.js.map +1 -0
- package/dist/connectors/telegram/output/createOutputTransport.d.ts +34 -0
- package/dist/connectors/telegram/output/createOutputTransport.d.ts.map +1 -0
- package/dist/connectors/telegram/output/createOutputTransport.js +77 -0
- package/dist/connectors/telegram/output/createOutputTransport.js.map +1 -0
- package/dist/connectors/telegram/output/dmOutputTransport.d.ts +47 -0
- package/dist/connectors/telegram/output/dmOutputTransport.d.ts.map +1 -0
- package/dist/connectors/telegram/output/dmOutputTransport.js +412 -0
- package/dist/connectors/telegram/output/dmOutputTransport.js.map +1 -0
- package/dist/connectors/telegram/outputBacklogGlue.d.ts +38 -0
- package/dist/connectors/telegram/outputBacklogGlue.d.ts.map +1 -0
- package/dist/connectors/telegram/outputBacklogGlue.js +49 -0
- package/dist/connectors/telegram/outputBacklogGlue.js.map +1 -0
- package/dist/connectors/telegram/outputFlushPlan.d.ts +93 -0
- package/dist/connectors/telegram/outputFlushPlan.d.ts.map +1 -0
- package/dist/connectors/telegram/outputFlushPlan.js +120 -0
- package/dist/connectors/telegram/outputFlushPlan.js.map +1 -0
- package/dist/connectors/telegram/questionKeyboards.d.ts +30 -0
- package/dist/connectors/telegram/questionKeyboards.d.ts.map +1 -0
- package/dist/connectors/telegram/questionKeyboards.js +37 -0
- package/dist/connectors/telegram/questionKeyboards.js.map +1 -0
- package/dist/connectors/telegram/renderAgentHtml.d.ts +27 -0
- package/dist/connectors/telegram/renderAgentHtml.d.ts.map +1 -0
- package/dist/connectors/telegram/renderAgentHtml.js +97 -0
- package/dist/connectors/telegram/renderAgentHtml.js.map +1 -0
- package/dist/connectors/telegram/sessionKeyCodec.d.ts +28 -0
- package/dist/connectors/telegram/sessionKeyCodec.d.ts.map +1 -0
- package/dist/connectors/telegram/sessionKeyCodec.js +107 -0
- package/dist/connectors/telegram/sessionKeyCodec.js.map +1 -0
- package/dist/connectors/telegram/telegramCallGuard.d.ts +19 -0
- package/dist/connectors/telegram/telegramCallGuard.d.ts.map +1 -0
- package/dist/connectors/telegram/telegramCallGuard.js +35 -0
- package/dist/connectors/telegram/telegramCallGuard.js.map +1 -0
- package/dist/connectors/telegram/timezonePicker.d.ts +85 -0
- package/dist/connectors/telegram/timezonePicker.d.ts.map +1 -0
- package/dist/connectors/telegram/timezonePicker.js +142 -0
- package/dist/connectors/telegram/timezonePicker.js.map +1 -0
- package/dist/connectors/telegram/updateDispatcher.d.ts +85 -0
- package/dist/connectors/telegram/updateDispatcher.d.ts.map +1 -0
- package/dist/connectors/telegram/updateDispatcher.js +159 -0
- package/dist/connectors/telegram/updateDispatcher.js.map +1 -0
- package/dist/connectors/test/connector.d.ts +52 -0
- package/dist/connectors/test/connector.d.ts.map +1 -0
- package/dist/connectors/test/connector.js +143 -0
- package/dist/connectors/test/connector.js.map +1 -0
- package/dist/connectors/test/sessionKeyCodec.d.ts +25 -0
- package/dist/connectors/test/sessionKeyCodec.d.ts.map +1 -0
- package/dist/connectors/test/sessionKeyCodec.js +50 -0
- package/dist/connectors/test/sessionKeyCodec.js.map +1 -0
- package/dist/diagLog.d.ts +6 -0
- package/dist/diagLog.d.ts.map +1 -0
- package/dist/diagLog.js +58 -0
- package/dist/diagLog.js.map +1 -0
- package/dist/effortLevels.d.ts +68 -0
- package/dist/effortLevels.d.ts.map +1 -0
- package/dist/effortLevels.js +114 -0
- package/dist/effortLevels.js.map +1 -0
- package/dist/folderName.d.ts +42 -0
- package/dist/folderName.d.ts.map +1 -0
- package/dist/folderName.js +51 -0
- package/dist/folderName.js.map +1 -0
- package/dist/i18n/de.d.ts +2 -0
- package/dist/i18n/de.d.ts.map +1 -0
- package/dist/i18n/de.js +665 -0
- package/dist/i18n/de.js.map +1 -0
- package/dist/i18n/en.d.ts +7 -0
- package/dist/i18n/en.d.ts.map +1 -0
- package/dist/i18n/en.js +694 -0
- package/dist/i18n/en.js.map +1 -0
- package/dist/i18n/es.d.ts +2 -0
- package/dist/i18n/es.d.ts.map +1 -0
- package/dist/i18n/es.js +665 -0
- package/dist/i18n/es.js.map +1 -0
- package/dist/i18n/fr.d.ts +2 -0
- package/dist/i18n/fr.d.ts.map +1 -0
- package/dist/i18n/fr.js +665 -0
- package/dist/i18n/fr.js.map +1 -0
- package/dist/i18n/hi.d.ts +2 -0
- package/dist/i18n/hi.d.ts.map +1 -0
- package/dist/i18n/hi.js +665 -0
- package/dist/i18n/hi.js.map +1 -0
- package/dist/i18n/ja.d.ts +2 -0
- package/dist/i18n/ja.d.ts.map +1 -0
- package/dist/i18n/ja.js +665 -0
- package/dist/i18n/ja.js.map +1 -0
- package/dist/i18n/ka.d.ts +2 -0
- package/dist/i18n/ka.d.ts.map +1 -0
- package/dist/i18n/ka.js +665 -0
- package/dist/i18n/ka.js.map +1 -0
- package/dist/i18n/pt.d.ts +2 -0
- package/dist/i18n/pt.d.ts.map +1 -0
- package/dist/i18n/pt.js +665 -0
- package/dist/i18n/pt.js.map +1 -0
- package/dist/i18n/ru.d.ts +6 -0
- package/dist/i18n/ru.d.ts.map +1 -0
- package/dist/i18n/ru.js +668 -0
- package/dist/i18n/ru.js.map +1 -0
- package/dist/i18n/uk.d.ts +8 -0
- package/dist/i18n/uk.d.ts.map +1 -0
- package/dist/i18n/uk.js +670 -0
- package/dist/i18n/uk.js.map +1 -0
- package/dist/i18n/uz.d.ts +2 -0
- package/dist/i18n/uz.d.ts.map +1 -0
- package/dist/i18n/uz.js +665 -0
- package/dist/i18n/uz.js.map +1 -0
- package/dist/i18n/zh.d.ts +2 -0
- package/dist/i18n/zh.d.ts.map +1 -0
- package/dist/i18n/zh.js +665 -0
- package/dist/i18n/zh.js.map +1 -0
- package/dist/i18n.d.ts +115 -0
- package/dist/i18n.d.ts.map +1 -0
- package/dist/i18n.js +233 -0
- package/dist/i18n.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +10 -0
- package/dist/index.js.map +1 -0
- package/dist/installManager.d.ts +99 -0
- package/dist/installManager.d.ts.map +1 -0
- package/dist/installManager.js +943 -0
- package/dist/installManager.js.map +1 -0
- package/dist/instanceLock.d.ts +161 -0
- package/dist/instanceLock.d.ts.map +1 -0
- package/dist/instanceLock.js +388 -0
- package/dist/instanceLock.js.map +1 -0
- package/dist/mcpConfig.d.ts +76 -0
- package/dist/mcpConfig.d.ts.map +1 -0
- package/dist/mcpConfig.js +270 -0
- package/dist/mcpConfig.js.map +1 -0
- package/dist/openCodeOpenQuestion.d.ts +44 -0
- package/dist/openCodeOpenQuestion.d.ts.map +1 -0
- package/dist/openCodeOpenQuestion.js +64 -0
- package/dist/openCodeOpenQuestion.js.map +1 -0
- package/dist/openCodeQuestionFlow.d.ts +105 -0
- package/dist/openCodeQuestionFlow.d.ts.map +1 -0
- package/dist/openCodeQuestionFlow.js +143 -0
- package/dist/openCodeQuestionFlow.js.map +1 -0
- package/dist/openCodeSessionRouting.d.ts +133 -0
- package/dist/openCodeSessionRouting.d.ts.map +1 -0
- package/dist/openCodeSessionRouting.js +253 -0
- package/dist/openCodeSessionRouting.js.map +1 -0
- package/dist/openCodeSessionTitle.d.ts +50 -0
- package/dist/openCodeSessionTitle.d.ts.map +1 -0
- package/dist/openCodeSessionTitle.js +84 -0
- package/dist/openCodeSessionTitle.js.map +1 -0
- package/dist/outputTrace.d.ts +108 -0
- package/dist/outputTrace.d.ts.map +1 -0
- package/dist/outputTrace.js +430 -0
- package/dist/outputTrace.js.map +1 -0
- package/dist/pendingQuestionRepost.d.ts +47 -0
- package/dist/pendingQuestionRepost.d.ts.map +1 -0
- package/dist/pendingQuestionRepost.js +29 -0
- package/dist/pendingQuestionRepost.js.map +1 -0
- package/dist/pinnedStatus.d.ts +52 -0
- package/dist/pinnedStatus.d.ts.map +1 -0
- package/dist/pinnedStatus.js +36 -0
- package/dist/pinnedStatus.js.map +1 -0
- package/dist/platform/answerSink.d.ts +93 -0
- package/dist/platform/answerSink.d.ts.map +1 -0
- package/dist/platform/answerSink.js +31 -0
- package/dist/platform/answerSink.js.map +1 -0
- package/dist/platform/capabilityFallback.d.ts +39 -0
- package/dist/platform/capabilityFallback.d.ts.map +1 -0
- package/dist/platform/capabilityFallback.js +55 -0
- package/dist/platform/capabilityFallback.js.map +1 -0
- package/dist/platform/commandRouter.d.ts +51 -0
- package/dist/platform/commandRouter.d.ts.map +1 -0
- package/dist/platform/commandRouter.js +53 -0
- package/dist/platform/commandRouter.js.map +1 -0
- package/dist/platform/connectorSet.d.ts +39 -0
- package/dist/platform/connectorSet.d.ts.map +1 -0
- package/dist/platform/connectorSet.js +55 -0
- package/dist/platform/connectorSet.js.map +1 -0
- package/dist/platform/inbound.d.ts +147 -0
- package/dist/platform/inbound.d.ts.map +1 -0
- package/dist/platform/inbound.js +18 -0
- package/dist/platform/inbound.js.map +1 -0
- package/dist/platform/outbound.d.ts +225 -0
- package/dist/platform/outbound.d.ts.map +1 -0
- package/dist/platform/outbound.js +30 -0
- package/dist/platform/outbound.js.map +1 -0
- package/dist/platform/unservedStateGuard.d.ts +27 -0
- package/dist/platform/unservedStateGuard.d.ts.map +1 -0
- package/dist/platform/unservedStateGuard.js +42 -0
- package/dist/platform/unservedStateGuard.js.map +1 -0
- package/dist/postToSession.d.ts +94 -0
- package/dist/postToSession.d.ts.map +1 -0
- package/dist/postToSession.js +56 -0
- package/dist/postToSession.js.map +1 -0
- package/dist/progressLine.d.ts +180 -0
- package/dist/progressLine.d.ts.map +1 -0
- package/dist/progressLine.js +293 -0
- package/dist/progressLine.js.map +1 -0
- package/dist/rateLimiter.d.ts +246 -0
- package/dist/rateLimiter.d.ts.map +1 -0
- package/dist/rateLimiter.js +555 -0
- package/dist/rateLimiter.js.map +1 -0
- package/dist/requests/answerRequest.d.ts +57 -0
- package/dist/requests/answerRequest.d.ts.map +1 -0
- package/dist/requests/answerRequest.js +96 -0
- package/dist/requests/answerRequest.js.map +1 -0
- package/dist/requests/answerTail.d.ts +83 -0
- package/dist/requests/answerTail.d.ts.map +1 -0
- package/dist/requests/answerTail.js +102 -0
- package/dist/requests/answerTail.js.map +1 -0
- package/dist/requests/limitWaitAnswer.d.ts +87 -0
- package/dist/requests/limitWaitAnswer.d.ts.map +1 -0
- package/dist/requests/limitWaitAnswer.js +83 -0
- package/dist/requests/limitWaitAnswer.js.map +1 -0
- package/dist/requests/requestGroup.d.ts +44 -0
- package/dist/requests/requestGroup.d.ts.map +1 -0
- package/dist/requests/requestGroup.js +63 -0
- package/dist/requests/requestGroup.js.map +1 -0
- package/dist/requests/requestHeader.d.ts +70 -0
- package/dist/requests/requestHeader.d.ts.map +1 -0
- package/dist/requests/requestHeader.js +83 -0
- package/dist/requests/requestHeader.js.map +1 -0
- package/dist/requests/requestLedger.d.ts +217 -0
- package/dist/requests/requestLedger.d.ts.map +1 -0
- package/dist/requests/requestLedger.js +468 -0
- package/dist/requests/requestLedger.js.map +1 -0
- package/dist/requests/sessionTurnProbe.d.ts +52 -0
- package/dist/requests/sessionTurnProbe.d.ts.map +1 -0
- package/dist/requests/sessionTurnProbe.js +29 -0
- package/dist/requests/sessionTurnProbe.js.map +1 -0
- package/dist/requests/types.d.ts +181 -0
- package/dist/requests/types.d.ts.map +1 -0
- package/dist/requests/types.js +9 -0
- package/dist/requests/types.js.map +1 -0
- package/dist/requests/wakeUpEngine.d.ts +160 -0
- package/dist/requests/wakeUpEngine.d.ts.map +1 -0
- package/dist/requests/wakeUpEngine.js +399 -0
- package/dist/requests/wakeUpEngine.js.map +1 -0
- package/dist/requests/wakeUpRules.d.ts +151 -0
- package/dist/requests/wakeUpRules.d.ts.map +1 -0
- package/dist/requests/wakeUpRules.js +167 -0
- package/dist/requests/wakeUpRules.js.map +1 -0
- package/dist/resumeContext.d.ts +87 -0
- package/dist/resumeContext.d.ts.map +1 -0
- package/dist/resumeContext.js +114 -0
- package/dist/resumeContext.js.map +1 -0
- package/dist/scheduler/checkRun.d.ts +95 -0
- package/dist/scheduler/checkRun.d.ts.map +1 -0
- package/dist/scheduler/checkRun.js +172 -0
- package/dist/scheduler/checkRun.js.map +1 -0
- package/dist/scheduler/delivery.d.ts +99 -0
- package/dist/scheduler/delivery.d.ts.map +1 -0
- package/dist/scheduler/delivery.js +212 -0
- package/dist/scheduler/delivery.js.map +1 -0
- package/dist/scheduler/deliveryKind.d.ts +29 -0
- package/dist/scheduler/deliveryKind.d.ts.map +1 -0
- package/dist/scheduler/deliveryKind.js +39 -0
- package/dist/scheduler/deliveryKind.js.map +1 -0
- package/dist/scheduler/directoryThreads.d.ts +19 -0
- package/dist/scheduler/directoryThreads.d.ts.map +1 -0
- package/dist/scheduler/directoryThreads.js +28 -0
- package/dist/scheduler/directoryThreads.js.map +1 -0
- package/dist/scheduler/engine.d.ts +77 -0
- package/dist/scheduler/engine.d.ts.map +1 -0
- package/dist/scheduler/engine.js +337 -0
- package/dist/scheduler/engine.js.map +1 -0
- package/dist/scheduler/injection.d.ts +102 -0
- package/dist/scheduler/injection.d.ts.map +1 -0
- package/dist/scheduler/injection.js +122 -0
- package/dist/scheduler/injection.js.map +1 -0
- package/dist/scheduler/mcpBoot.d.ts +65 -0
- package/dist/scheduler/mcpBoot.d.ts.map +1 -0
- package/dist/scheduler/mcpBoot.js +60 -0
- package/dist/scheduler/mcpBoot.js.map +1 -0
- package/dist/scheduler/mcpSurface.d.ts +363 -0
- package/dist/scheduler/mcpSurface.d.ts.map +1 -0
- package/dist/scheduler/mcpSurface.js +1297 -0
- package/dist/scheduler/mcpSurface.js.map +1 -0
- package/dist/scheduler/rebindResume.d.ts +27 -0
- package/dist/scheduler/rebindResume.d.ts.map +1 -0
- package/dist/scheduler/rebindResume.js +17 -0
- package/dist/scheduler/rebindResume.js.map +1 -0
- package/dist/scheduler/recurrence.d.ts +58 -0
- package/dist/scheduler/recurrence.d.ts.map +1 -0
- package/dist/scheduler/recurrence.js +210 -0
- package/dist/scheduler/recurrence.js.map +1 -0
- package/dist/scheduler/runLedger.d.ts +59 -0
- package/dist/scheduler/runLedger.d.ts.map +1 -0
- package/dist/scheduler/runLedger.js +54 -0
- package/dist/scheduler/runLedger.js.map +1 -0
- package/dist/scheduler/store.d.ts +97 -0
- package/dist/scheduler/store.d.ts.map +1 -0
- package/dist/scheduler/store.js +124 -0
- package/dist/scheduler/store.js.map +1 -0
- package/dist/scheduler/timezoneRecompute.d.ts +61 -0
- package/dist/scheduler/timezoneRecompute.d.ts.map +1 -0
- package/dist/scheduler/timezoneRecompute.js +46 -0
- package/dist/scheduler/timezoneRecompute.js.map +1 -0
- package/dist/scheduler/types.d.ts +139 -0
- package/dist/scheduler/types.d.ts.map +1 -0
- package/dist/scheduler/types.js +8 -0
- package/dist/scheduler/types.js.map +1 -0
- package/dist/sendErrorClassifier.d.ts +45 -0
- package/dist/sendErrorClassifier.d.ts.map +1 -0
- package/dist/sendErrorClassifier.js +65 -0
- package/dist/sendErrorClassifier.js.map +1 -0
- package/dist/sessionKey.d.ts +136 -0
- package/dist/sessionKey.d.ts.map +1 -0
- package/dist/sessionKey.js +153 -0
- package/dist/sessionKey.js.map +1 -0
- package/dist/sessionPick.d.ts +42 -0
- package/dist/sessionPick.d.ts.map +1 -0
- package/dist/sessionPick.js +39 -0
- package/dist/sessionPick.js.map +1 -0
- package/dist/shutdown.d.ts +126 -0
- package/dist/shutdown.d.ts.map +1 -0
- package/dist/shutdown.js +164 -0
- package/dist/shutdown.js.map +1 -0
- package/dist/startupPromptBuffer.d.ts +85 -0
- package/dist/startupPromptBuffer.d.ts.map +1 -0
- package/dist/startupPromptBuffer.js +123 -0
- package/dist/startupPromptBuffer.js.map +1 -0
- package/dist/state.d.ts +1416 -0
- package/dist/state.d.ts.map +1 -0
- package/dist/state.js +2128 -0
- package/dist/state.js.map +1 -0
- package/dist/threadContextPreamble.d.ts +89 -0
- package/dist/threadContextPreamble.d.ts.map +1 -0
- package/dist/threadContextPreamble.js +102 -0
- package/dist/threadContextPreamble.js.map +1 -0
- package/dist/threadRouting.d.ts +164 -0
- package/dist/threadRouting.d.ts.map +1 -0
- package/dist/threadRouting.js +182 -0
- package/dist/threadRouting.js.map +1 -0
- package/dist/types.d.ts +1022 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +3 -0
- package/dist/types.js.map +1 -0
- package/dist/utils/abortableFifo.d.ts +10 -0
- package/dist/utils/abortableFifo.d.ts.map +1 -0
- package/dist/utils/abortableFifo.js +55 -0
- package/dist/utils/abortableFifo.js.map +1 -0
- package/dist/utils/adoptedToolList.d.ts +27 -0
- package/dist/utils/adoptedToolList.d.ts.map +1 -0
- package/dist/utils/adoptedToolList.js +22 -0
- package/dist/utils/adoptedToolList.js.map +1 -0
- package/dist/utils/agentEnvironment.d.ts +42 -0
- package/dist/utils/agentEnvironment.d.ts.map +1 -0
- package/dist/utils/agentEnvironment.js +122 -0
- package/dist/utils/agentEnvironment.js.map +1 -0
- package/dist/utils/ansiClean.d.ts +11 -0
- package/dist/utils/ansiClean.d.ts.map +1 -0
- package/dist/utils/ansiClean.js +139 -0
- package/dist/utils/ansiClean.js.map +1 -0
- package/dist/utils/autoContinueOnLimit.d.ts +56 -0
- package/dist/utils/autoContinueOnLimit.d.ts.map +1 -0
- package/dist/utils/autoContinueOnLimit.js +79 -0
- package/dist/utils/autoContinueOnLimit.js.map +1 -0
- package/dist/utils/canonicalPathContainment.d.ts +7 -0
- package/dist/utils/canonicalPathContainment.d.ts.map +1 -0
- package/dist/utils/canonicalPathContainment.js +48 -0
- package/dist/utils/canonicalPathContainment.js.map +1 -0
- package/dist/utils/claudeAccountPickerPlan.d.ts +85 -0
- package/dist/utils/claudeAccountPickerPlan.d.ts.map +1 -0
- package/dist/utils/claudeAccountPickerPlan.js +123 -0
- package/dist/utils/claudeAccountPickerPlan.js.map +1 -0
- package/dist/utils/claudeAuthLogin.d.ts +71 -0
- package/dist/utils/claudeAuthLogin.d.ts.map +1 -0
- package/dist/utils/claudeAuthLogin.js +93 -0
- package/dist/utils/claudeAuthLogin.js.map +1 -0
- package/dist/utils/claudeChunkClassifier.d.ts +97 -0
- package/dist/utils/claudeChunkClassifier.d.ts.map +1 -0
- package/dist/utils/claudeChunkClassifier.js +254 -0
- package/dist/utils/claudeChunkClassifier.js.map +1 -0
- package/dist/utils/claudeCodeVersion.d.ts +31 -0
- package/dist/utils/claudeCodeVersion.d.ts.map +1 -0
- package/dist/utils/claudeCodeVersion.js +62 -0
- package/dist/utils/claudeCodeVersion.js.map +1 -0
- package/dist/utils/claudeCompactHook.d.ts +64 -0
- package/dist/utils/claudeCompactHook.d.ts.map +1 -0
- package/dist/utils/claudeCompactHook.js +98 -0
- package/dist/utils/claudeCompactHook.js.map +1 -0
- package/dist/utils/claudeLimitSwitch.d.ts +40 -0
- package/dist/utils/claudeLimitSwitch.d.ts.map +1 -0
- package/dist/utils/claudeLimitSwitch.js +54 -0
- package/dist/utils/claudeLimitSwitch.js.map +1 -0
- package/dist/utils/claudeLivenessAction.d.ts +208 -0
- package/dist/utils/claudeLivenessAction.d.ts.map +1 -0
- package/dist/utils/claudeLivenessAction.js +135 -0
- package/dist/utils/claudeLivenessAction.js.map +1 -0
- package/dist/utils/claudeMcpHeal.d.ts +92 -0
- package/dist/utils/claudeMcpHeal.d.ts.map +1 -0
- package/dist/utils/claudeMcpHeal.js +91 -0
- package/dist/utils/claudeMcpHeal.js.map +1 -0
- package/dist/utils/claudeProfileUsageLines.d.ts +15 -0
- package/dist/utils/claudeProfileUsageLines.d.ts.map +1 -0
- package/dist/utils/claudeProfileUsageLines.js +42 -0
- package/dist/utils/claudeProfileUsageLines.js.map +1 -0
- package/dist/utils/claudeProfiles.d.ts +117 -0
- package/dist/utils/claudeProfiles.d.ts.map +1 -0
- package/dist/utils/claudeProfiles.js +285 -0
- package/dist/utils/claudeProfiles.js.map +1 -0
- package/dist/utils/claudeRelayRouting.d.ts +86 -0
- package/dist/utils/claudeRelayRouting.d.ts.map +1 -0
- package/dist/utils/claudeRelayRouting.js +159 -0
- package/dist/utils/claudeRelayRouting.js.map +1 -0
- package/dist/utils/claudeRuntimeInfo.d.ts +26 -0
- package/dist/utils/claudeRuntimeInfo.d.ts.map +1 -0
- package/dist/utils/claudeRuntimeInfo.js +151 -0
- package/dist/utils/claudeRuntimeInfo.js.map +1 -0
- package/dist/utils/claudeScrapeShapes.d.ts +256 -0
- package/dist/utils/claudeScrapeShapes.d.ts.map +1 -0
- package/dist/utils/claudeScrapeShapes.js +290 -0
- package/dist/utils/claudeScrapeShapes.js.map +1 -0
- package/dist/utils/claudeSessionTitle.d.ts +27 -0
- package/dist/utils/claudeSessionTitle.d.ts.map +1 -0
- package/dist/utils/claudeSessionTitle.js +90 -0
- package/dist/utils/claudeSessionTitle.js.map +1 -0
- package/dist/utils/claudeStreamJson.d.ts +214 -0
- package/dist/utils/claudeStreamJson.d.ts.map +1 -0
- package/dist/utils/claudeStreamJson.js +364 -0
- package/dist/utils/claudeStreamJson.js.map +1 -0
- package/dist/utils/claudeSubagentTail.d.ts +93 -0
- package/dist/utils/claudeSubagentTail.d.ts.map +1 -0
- package/dist/utils/claudeSubagentTail.js +136 -0
- package/dist/utils/claudeSubagentTail.js.map +1 -0
- package/dist/utils/claudeUsage.d.ts +209 -0
- package/dist/utils/claudeUsage.d.ts.map +1 -0
- package/dist/utils/claudeUsage.js +413 -0
- package/dist/utils/claudeUsage.js.map +1 -0
- package/dist/utils/claudeUsageRefresher.d.ts +44 -0
- package/dist/utils/claudeUsageRefresher.d.ts.map +1 -0
- package/dist/utils/claudeUsageRefresher.js +95 -0
- package/dist/utils/claudeUsageRefresher.js.map +1 -0
- package/dist/utils/clearThreadOutputQueues.d.ts +43 -0
- package/dist/utils/clearThreadOutputQueues.d.ts.map +1 -0
- package/dist/utils/clearThreadOutputQueues.js +39 -0
- package/dist/utils/clearThreadOutputQueues.js.map +1 -0
- package/dist/utils/compactCommandRoute.d.ts +45 -0
- package/dist/utils/compactCommandRoute.d.ts.map +1 -0
- package/dist/utils/compactCommandRoute.js +36 -0
- package/dist/utils/compactCommandRoute.js.map +1 -0
- package/dist/utils/compactOnIdle.d.ts +329 -0
- package/dist/utils/compactOnIdle.d.ts.map +1 -0
- package/dist/utils/compactOnIdle.js +379 -0
- package/dist/utils/compactOnIdle.js.map +1 -0
- package/dist/utils/consoleFileTap.d.ts +51 -0
- package/dist/utils/consoleFileTap.d.ts.map +1 -0
- package/dist/utils/consoleFileTap.js +86 -0
- package/dist/utils/consoleFileTap.js.map +1 -0
- package/dist/utils/displayVerbosity.d.ts +44 -0
- package/dist/utils/displayVerbosity.d.ts.map +1 -0
- package/dist/utils/displayVerbosity.js +75 -0
- package/dist/utils/displayVerbosity.js.map +1 -0
- package/dist/utils/download.d.ts +72 -0
- package/dist/utils/download.d.ts.map +1 -0
- package/dist/utils/download.js +216 -0
- package/dist/utils/download.js.map +1 -0
- package/dist/utils/draftFinalize.d.ts +110 -0
- package/dist/utils/draftFinalize.d.ts.map +1 -0
- package/dist/utils/draftFinalize.js +100 -0
- package/dist/utils/draftFinalize.js.map +1 -0
- package/dist/utils/draftId.d.ts +36 -0
- package/dist/utils/draftId.d.ts.map +1 -0
- package/dist/utils/draftId.js +46 -0
- package/dist/utils/draftId.js.map +1 -0
- package/dist/utils/draftPacer.d.ts +72 -0
- package/dist/utils/draftPacer.d.ts.map +1 -0
- package/dist/utils/draftPacer.js +53 -0
- package/dist/utils/draftPacer.js.map +1 -0
- package/dist/utils/effortStartupKeystroke.d.ts +20 -0
- package/dist/utils/effortStartupKeystroke.d.ts.map +1 -0
- package/dist/utils/effortStartupKeystroke.js +28 -0
- package/dist/utils/effortStartupKeystroke.js.map +1 -0
- package/dist/utils/ensureSessionPlan.d.ts +70 -0
- package/dist/utils/ensureSessionPlan.d.ts.map +1 -0
- package/dist/utils/ensureSessionPlan.js +54 -0
- package/dist/utils/ensureSessionPlan.js.map +1 -0
- package/dist/utils/fallbackBridge.d.ts +32 -0
- package/dist/utils/fallbackBridge.d.ts.map +1 -0
- package/dist/utils/fallbackBridge.js +62 -0
- package/dist/utils/fallbackBridge.js.map +1 -0
- package/dist/utils/fallbackChain.d.ts +299 -0
- package/dist/utils/fallbackChain.d.ts.map +1 -0
- package/dist/utils/fallbackChain.js +542 -0
- package/dist/utils/fallbackChain.js.map +1 -0
- package/dist/utils/fileSendPlan.d.ts +217 -0
- package/dist/utils/fileSendPlan.d.ts.map +1 -0
- package/dist/utils/fileSendPlan.js +291 -0
- package/dist/utils/fileSendPlan.js.map +1 -0
- package/dist/utils/fileSendService.d.ts +94 -0
- package/dist/utils/fileSendService.d.ts.map +1 -0
- package/dist/utils/fileSendService.js +387 -0
- package/dist/utils/fileSendService.js.map +1 -0
- package/dist/utils/groupFinalizePlan.d.ts +38 -0
- package/dist/utils/groupFinalizePlan.d.ts.map +1 -0
- package/dist/utils/groupFinalizePlan.js +35 -0
- package/dist/utils/groupFinalizePlan.js.map +1 -0
- package/dist/utils/identicalOutputGuard.d.ts +83 -0
- package/dist/utils/identicalOutputGuard.d.ts.map +1 -0
- package/dist/utils/identicalOutputGuard.js +99 -0
- package/dist/utils/identicalOutputGuard.js.map +1 -0
- package/dist/utils/isoTimestamp.d.ts +16 -0
- package/dist/utils/isoTimestamp.d.ts.map +1 -0
- package/dist/utils/isoTimestamp.js +34 -0
- package/dist/utils/isoTimestamp.js.map +1 -0
- package/dist/utils/jsonStreamBusyWatchdog.d.ts +130 -0
- package/dist/utils/jsonStreamBusyWatchdog.d.ts.map +1 -0
- package/dist/utils/jsonStreamBusyWatchdog.js +122 -0
- package/dist/utils/jsonStreamBusyWatchdog.js.map +1 -0
- package/dist/utils/jsonStreamHost.d.ts +238 -0
- package/dist/utils/jsonStreamHost.d.ts.map +1 -0
- package/dist/utils/jsonStreamHost.js +438 -0
- package/dist/utils/jsonStreamHost.js.map +1 -0
- package/dist/utils/keyedTransitionQueue.d.ts +18 -0
- package/dist/utils/keyedTransitionQueue.d.ts.map +1 -0
- package/dist/utils/keyedTransitionQueue.js +34 -0
- package/dist/utils/keyedTransitionQueue.js.map +1 -0
- package/dist/utils/limitEpisodeRecovery.d.ts +92 -0
- package/dist/utils/limitEpisodeRecovery.d.ts.map +1 -0
- package/dist/utils/limitEpisodeRecovery.js +133 -0
- package/dist/utils/limitEpisodeRecovery.js.map +1 -0
- package/dist/utils/limitHeldPromptQueue.d.ts +48 -0
- package/dist/utils/limitHeldPromptQueue.d.ts.map +1 -0
- package/dist/utils/limitHeldPromptQueue.js +59 -0
- package/dist/utils/limitHeldPromptQueue.js.map +1 -0
- package/dist/utils/limitHeldPrompts.d.ts +58 -0
- package/dist/utils/limitHeldPrompts.d.ts.map +1 -0
- package/dist/utils/limitHeldPrompts.js +65 -0
- package/dist/utils/limitHeldPrompts.js.map +1 -0
- package/dist/utils/linkPreviewSuppression.d.ts +18 -0
- package/dist/utils/linkPreviewSuppression.d.ts.map +1 -0
- package/dist/utils/linkPreviewSuppression.js +37 -0
- package/dist/utils/linkPreviewSuppression.js.map +1 -0
- package/dist/utils/localClock.d.ts +15 -0
- package/dist/utils/localClock.d.ts.map +1 -0
- package/dist/utils/localClock.js +29 -0
- package/dist/utils/localClock.js.map +1 -0
- package/dist/utils/markdownTableRender.d.ts +83 -0
- package/dist/utils/markdownTableRender.d.ts.map +1 -0
- package/dist/utils/markdownTableRender.js +298 -0
- package/dist/utils/markdownTableRender.js.map +1 -0
- package/dist/utils/mediaGroupCollector.d.ts +51 -0
- package/dist/utils/mediaGroupCollector.d.ts.map +1 -0
- package/dist/utils/mediaGroupCollector.js +90 -0
- package/dist/utils/mediaGroupCollector.js.map +1 -0
- package/dist/utils/messageSendService.d.ts +136 -0
- package/dist/utils/messageSendService.d.ts.map +1 -0
- package/dist/utils/messageSendService.js +165 -0
- package/dist/utils/messageSendService.js.map +1 -0
- package/dist/utils/minutesOverride.d.ts +7 -0
- package/dist/utils/minutesOverride.d.ts.map +1 -0
- package/dist/utils/minutesOverride.js +16 -0
- package/dist/utils/minutesOverride.js.map +1 -0
- package/dist/utils/modelPickerPlan.d.ts +119 -0
- package/dist/utils/modelPickerPlan.d.ts.map +1 -0
- package/dist/utils/modelPickerPlan.js +171 -0
- package/dist/utils/modelPickerPlan.js.map +1 -0
- package/dist/utils/modelRecentPlan.d.ts +56 -0
- package/dist/utils/modelRecentPlan.d.ts.map +1 -0
- package/dist/utils/modelRecentPlan.js +107 -0
- package/dist/utils/modelRecentPlan.js.map +1 -0
- package/dist/utils/modelSetReplyDecision.d.ts +67 -0
- package/dist/utils/modelSetReplyDecision.d.ts.map +1 -0
- package/dist/utils/modelSetReplyDecision.js +27 -0
- package/dist/utils/modelSetReplyDecision.js.map +1 -0
- package/dist/utils/openCodeAuthLogin.d.ts +181 -0
- package/dist/utils/openCodeAuthLogin.d.ts.map +1 -0
- package/dist/utils/openCodeAuthLogin.js +393 -0
- package/dist/utils/openCodeAuthLogin.js.map +1 -0
- package/dist/utils/openCodeCompactPlugin.d.ts +81 -0
- package/dist/utils/openCodeCompactPlugin.d.ts.map +1 -0
- package/dist/utils/openCodeCompactPlugin.js +146 -0
- package/dist/utils/openCodeCompactPlugin.js.map +1 -0
- package/dist/utils/openCodeTurnActivity.d.ts +67 -0
- package/dist/utils/openCodeTurnActivity.d.ts.map +1 -0
- package/dist/utils/openCodeTurnActivity.js +27 -0
- package/dist/utils/openCodeTurnActivity.js.map +1 -0
- package/dist/utils/outputDebounce.d.ts +24 -0
- package/dist/utils/outputDebounce.d.ts.map +1 -0
- package/dist/utils/outputDebounce.js +30 -0
- package/dist/utils/outputDebounce.js.map +1 -0
- package/dist/utils/outputFlushTiming.d.ts +54 -0
- package/dist/utils/outputFlushTiming.d.ts.map +1 -0
- package/dist/utils/outputFlushTiming.js +48 -0
- package/dist/utils/outputFlushTiming.js.map +1 -0
- package/dist/utils/paginateList.d.ts +25 -0
- package/dist/utils/paginateList.d.ts.map +1 -0
- package/dist/utils/paginateList.js +32 -0
- package/dist/utils/paginateList.js.map +1 -0
- package/dist/utils/paneDiff.d.ts +55 -0
- package/dist/utils/paneDiff.d.ts.map +1 -0
- package/dist/utils/paneDiff.js +88 -0
- package/dist/utils/paneDiff.js.map +1 -0
- package/dist/utils/paneResizeGuard.d.ts +69 -0
- package/dist/utils/paneResizeGuard.d.ts.map +1 -0
- package/dist/utils/paneResizeGuard.js +91 -0
- package/dist/utils/paneResizeGuard.js.map +1 -0
- package/dist/utils/persistAdapterSessionIds.d.ts +39 -0
- package/dist/utils/persistAdapterSessionIds.d.ts.map +1 -0
- package/dist/utils/persistAdapterSessionIds.js +28 -0
- package/dist/utils/persistAdapterSessionIds.js.map +1 -0
- package/dist/utils/pinnedBannerSkipDecision.d.ts +44 -0
- package/dist/utils/pinnedBannerSkipDecision.d.ts.map +1 -0
- package/dist/utils/pinnedBannerSkipDecision.js +20 -0
- package/dist/utils/pinnedBannerSkipDecision.js.map +1 -0
- package/dist/utils/pollBackoff.d.ts +45 -0
- package/dist/utils/pollBackoff.d.ts.map +1 -0
- package/dist/utils/pollBackoff.js +44 -0
- package/dist/utils/pollBackoff.js.map +1 -0
- package/dist/utils/promptDelivery.d.ts +46 -0
- package/dist/utils/promptDelivery.d.ts.map +1 -0
- package/dist/utils/promptDelivery.js +49 -0
- package/dist/utils/promptDelivery.js.map +1 -0
- package/dist/utils/providerDisconnectPlan.d.ts +82 -0
- package/dist/utils/providerDisconnectPlan.d.ts.map +1 -0
- package/dist/utils/providerDisconnectPlan.js +110 -0
- package/dist/utils/providerDisconnectPlan.js.map +1 -0
- package/dist/utils/rateLimitLog.d.ts +48 -0
- package/dist/utils/rateLimitLog.d.ts.map +1 -0
- package/dist/utils/rateLimitLog.js +43 -0
- package/dist/utils/rateLimitLog.js.map +1 -0
- package/dist/utils/recentRelayWindow.d.ts +165 -0
- package/dist/utils/recentRelayWindow.d.ts.map +1 -0
- package/dist/utils/recentRelayWindow.js +284 -0
- package/dist/utils/recentRelayWindow.js.map +1 -0
- package/dist/utils/recvPreviewRedaction.d.ts +23 -0
- package/dist/utils/recvPreviewRedaction.d.ts.map +1 -0
- package/dist/utils/recvPreviewRedaction.js +39 -0
- package/dist/utils/recvPreviewRedaction.js.map +1 -0
- package/dist/utils/reminderFlow.d.ts +148 -0
- package/dist/utils/reminderFlow.d.ts.map +1 -0
- package/dist/utils/reminderFlow.js +122 -0
- package/dist/utils/reminderFlow.js.map +1 -0
- package/dist/utils/reminderScheduleText.d.ts +87 -0
- package/dist/utils/reminderScheduleText.d.ts.map +1 -0
- package/dist/utils/reminderScheduleText.js +135 -0
- package/dist/utils/reminderScheduleText.js.map +1 -0
- package/dist/utils/reminderWizard.d.ts +710 -0
- package/dist/utils/reminderWizard.d.ts.map +1 -0
- package/dist/utils/reminderWizard.js +1164 -0
- package/dist/utils/reminderWizard.js.map +1 -0
- package/dist/utils/replyQuote.d.ts +111 -0
- package/dist/utils/replyQuote.d.ts.map +1 -0
- package/dist/utils/replyQuote.js +122 -0
- package/dist/utils/replyQuote.js.map +1 -0
- package/dist/utils/resolveBinary.d.ts +25 -0
- package/dist/utils/resolveBinary.d.ts.map +1 -0
- package/dist/utils/resolveBinary.js +99 -0
- package/dist/utils/resolveBinary.js.map +1 -0
- package/dist/utils/retryAfterHeader.d.ts +7 -0
- package/dist/utils/retryAfterHeader.d.ts.map +1 -0
- package/dist/utils/retryAfterHeader.js +17 -0
- package/dist/utils/retryAfterHeader.js.map +1 -0
- package/dist/utils/rotatingJsonlFile.d.ts +40 -0
- package/dist/utils/rotatingJsonlFile.d.ts.map +1 -0
- package/dist/utils/rotatingJsonlFile.js +106 -0
- package/dist/utils/rotatingJsonlFile.js.map +1 -0
- package/dist/utils/rotatingLogFile.d.ts +25 -0
- package/dist/utils/rotatingLogFile.d.ts.map +1 -0
- package/dist/utils/rotatingLogFile.js +74 -0
- package/dist/utils/rotatingLogFile.js.map +1 -0
- package/dist/utils/sendRateTracker.d.ts +59 -0
- package/dist/utils/sendRateTracker.d.ts.map +1 -0
- package/dist/utils/sendRateTracker.js +144 -0
- package/dist/utils/sendRateTracker.js.map +1 -0
- package/dist/utils/serialQueue.d.ts +5 -0
- package/dist/utils/serialQueue.d.ts.map +1 -0
- package/dist/utils/serialQueue.js +14 -0
- package/dist/utils/serialQueue.js.map +1 -0
- package/dist/utils/sseStreamLifecycle.d.ts +32 -0
- package/dist/utils/sseStreamLifecycle.d.ts.map +1 -0
- package/dist/utils/sseStreamLifecycle.js +41 -0
- package/dist/utils/sseStreamLifecycle.js.map +1 -0
- package/dist/utils/startupReadiness.d.ts +119 -0
- package/dist/utils/startupReadiness.d.ts.map +1 -0
- package/dist/utils/startupReadiness.js +148 -0
- package/dist/utils/startupReadiness.js.map +1 -0
- package/dist/utils/statusFlushDecision.d.ts +18 -0
- package/dist/utils/statusFlushDecision.d.ts.map +1 -0
- package/dist/utils/statusFlushDecision.js +53 -0
- package/dist/utils/statusFlushDecision.js.map +1 -0
- package/dist/utils/subagentRender.d.ts +52 -0
- package/dist/utils/subagentRender.d.ts.map +1 -0
- package/dist/utils/subagentRender.js +66 -0
- package/dist/utils/subagentRender.js.map +1 -0
- package/dist/utils/subagentStatusRender.d.ts +90 -0
- package/dist/utils/subagentStatusRender.d.ts.map +1 -0
- package/dist/utils/subagentStatusRender.js +124 -0
- package/dist/utils/subagentStatusRender.js.map +1 -0
- package/dist/utils/telegramError.d.ts +2 -0
- package/dist/utils/telegramError.d.ts.map +1 -0
- package/dist/utils/telegramError.js +16 -0
- package/dist/utils/telegramError.js.map +1 -0
- package/dist/utils/terminalEmitPlan.d.ts +74 -0
- package/dist/utils/terminalEmitPlan.d.ts.map +1 -0
- package/dist/utils/terminalEmitPlan.js +86 -0
- package/dist/utils/terminalEmitPlan.js.map +1 -0
- package/dist/utils/thinkingRender.d.ts +74 -0
- package/dist/utils/thinkingRender.d.ts.map +1 -0
- package/dist/utils/thinkingRender.js +85 -0
- package/dist/utils/thinkingRender.js.map +1 -0
- package/dist/utils/threadStatusReport.d.ts +79 -0
- package/dist/utils/threadStatusReport.d.ts.map +1 -0
- package/dist/utils/threadStatusReport.js +88 -0
- package/dist/utils/threadStatusReport.js.map +1 -0
- package/dist/utils/threadToggle.d.ts +29 -0
- package/dist/utils/threadToggle.d.ts.map +1 -0
- package/dist/utils/threadToggle.js +39 -0
- package/dist/utils/threadToggle.js.map +1 -0
- package/dist/utils/timezone.d.ts +125 -0
- package/dist/utils/timezone.d.ts.map +1 -0
- package/dist/utils/timezone.js +278 -0
- package/dist/utils/timezone.js.map +1 -0
- package/dist/utils/tmuxExec.d.ts +61 -0
- package/dist/utils/tmuxExec.d.ts.map +1 -0
- package/dist/utils/tmuxExec.js +109 -0
- package/dist/utils/tmuxExec.js.map +1 -0
- package/dist/utils/tmuxSessionName.d.ts +34 -0
- package/dist/utils/tmuxSessionName.d.ts.map +1 -0
- package/dist/utils/tmuxSessionName.js +51 -0
- package/dist/utils/tmuxSessionName.js.map +1 -0
- package/dist/utils/toolResultRender.d.ts +61 -0
- package/dist/utils/toolResultRender.d.ts.map +1 -0
- package/dist/utils/toolResultRender.js +62 -0
- package/dist/utils/toolResultRender.js.map +1 -0
- package/dist/utils/topicRequest.d.ts +61 -0
- package/dist/utils/topicRequest.d.ts.map +1 -0
- package/dist/utils/topicRequest.js +68 -0
- package/dist/utils/topicRequest.js.map +1 -0
- package/dist/utils/topicView.d.ts +55 -0
- package/dist/utils/topicView.d.ts.map +1 -0
- package/dist/utils/topicView.js +56 -0
- package/dist/utils/topicView.js.map +1 -0
- package/dist/utils/transcribeAudio.d.ts +89 -0
- package/dist/utils/transcribeAudio.d.ts.map +1 -0
- package/dist/utils/transcribeAudio.js +249 -0
- package/dist/utils/transcribeAudio.js.map +1 -0
- package/dist/utils/transientFrames.d.ts +52 -0
- package/dist/utils/transientFrames.d.ts.map +1 -0
- package/dist/utils/transientFrames.js +41 -0
- package/dist/utils/transientFrames.js.map +1 -0
- package/dist/utils/typingActive.d.ts +35 -0
- package/dist/utils/typingActive.d.ts.map +1 -0
- package/dist/utils/typingActive.js +22 -0
- package/dist/utils/typingActive.js.map +1 -0
- package/dist/utils/typingLoopBackstop.d.ts +64 -0
- package/dist/utils/typingLoopBackstop.d.ts.map +1 -0
- package/dist/utils/typingLoopBackstop.js +68 -0
- package/dist/utils/typingLoopBackstop.js.map +1 -0
- package/dist/utils/verbosityRender.d.ts +18 -0
- package/dist/utils/verbosityRender.d.ts.map +1 -0
- package/dist/utils/verbosityRender.js +17 -0
- package/dist/utils/verbosityRender.js.map +1 -0
- package/dist/utils/wedgeRecovery.d.ts +57 -0
- package/dist/utils/wedgeRecovery.d.ts.map +1 -0
- package/dist/utils/wedgeRecovery.js +24 -0
- package/dist/utils/wedgeRecovery.js.map +1 -0
- package/dist/utils.d.ts +30 -0
- package/dist/utils.d.ts.map +1 -0
- package/dist/utils.js +61 -0
- package/dist/utils.js.map +1 -0
- package/dist/validation.d.ts +113 -0
- package/dist/validation.d.ts.map +1 -0
- package/dist/validation.js +226 -0
- package/dist/validation.js.map +1 -0
- package/dist/voiceQueue.d.ts +7 -0
- package/dist/voiceQueue.d.ts.map +1 -0
- package/dist/voiceQueue.js +33 -0
- package/dist/voiceQueue.js.map +1 -0
- package/examples/.env.example +17 -0
- package/examples/docker-compose.yml +36 -0
- package/package.json +83 -4
|
@@ -0,0 +1,1351 @@
|
|
|
1
|
+
import { EventEmitter } from 'events';
|
|
2
|
+
import type { AgentAdapter, AgentRuntimeInfo, AgentSession, ClaudeSurveyOption, DisplayPrefsReader, ReattachRecap, RecentTurn, ResumeSessionOptions, SeenWatermark, SeenWatermarkWriter, SendInputOptions, ThreadLocaleReader } from '../types';
|
|
3
|
+
import type { SessionKey } from '../sessionKey';
|
|
4
|
+
import type { ClaudeConfigDirReader } from './claudeConfigDir';
|
|
5
|
+
import { type ToolResultKind } from '../utils/claudeScrapeShapes';
|
|
6
|
+
import { type SerialQueue } from '../utils/serialQueue';
|
|
7
|
+
import { tmuxAsync } from '../utils/tmuxExec';
|
|
8
|
+
import { convertAnsiToMarkdown, cleanOutput } from '../utils/ansiClean';
|
|
9
|
+
import { getNewPaneContent, type NewPaneContent } from '../utils/paneDiff';
|
|
10
|
+
import { type SubagentTailState } from '../utils/claudeSubagentTail';
|
|
11
|
+
import { type RecentRelayWindow } from '../utils/recentRelayWindow';
|
|
12
|
+
import { type ClaudeChunkContext } from '../utils/claudeChunkClassifier';
|
|
13
|
+
/**
|
|
14
|
+
* @description Per-thread Claude CLI session state.
|
|
15
|
+
*
|
|
16
|
+
* One tmux session is spawned per `SessionKey`. The tmux session name embeds
|
|
17
|
+
* both `chatId` and `threadId` so multiple threads sharing the same `workDir`
|
|
18
|
+
* stay fully isolated (plan §10.2, D8).
|
|
19
|
+
*/
|
|
20
|
+
export interface ClaudeSession {
|
|
21
|
+
key: SessionKey;
|
|
22
|
+
workDir: string;
|
|
23
|
+
sessionName: string;
|
|
24
|
+
/** UUID we pass via `--session-id` (or, on resume, via `--resume`). */
|
|
25
|
+
claudeSessionId: string;
|
|
26
|
+
/** The `CLAUDE_CONFIG_DIR` the pane's claude runs with (its account profile); `null` = the default profile. */
|
|
27
|
+
configDir: string | null;
|
|
28
|
+
queue: SerialQueue;
|
|
29
|
+
pollTimer: NodeJS.Timeout | null;
|
|
30
|
+
lastContent: string;
|
|
31
|
+
isActive: boolean;
|
|
32
|
+
handledAutoEnter: boolean;
|
|
33
|
+
handledAutoAccept: boolean;
|
|
34
|
+
/**
|
|
35
|
+
* One-shot guard for the auto-retry `apiError` emit. Armed when the terminal
|
|
36
|
+
* `API Error:` line first classifies as retryable, reset by the same
|
|
37
|
+
* `newPart.length > 50` rule as the sibling `handled*` flags — so a later,
|
|
38
|
+
* distinct error in the same session re-arms, but a static error frame
|
|
39
|
+
* doesn't re-emit on every poll.
|
|
40
|
+
*/
|
|
41
|
+
handledApiError: boolean;
|
|
42
|
+
/** Normalized text of last emitted status (for deduplication of spinner updates) */
|
|
43
|
+
lastStatusText: string;
|
|
44
|
+
/**
|
|
45
|
+
* The last text the bot typed into this session via {@link ClaudeCliAdapter.sendInput}
|
|
46
|
+
* (the preamble-glued prompt, a `/c continue` nudge, a buffered replay — every
|
|
47
|
+
* typed path). Used by the CONTENT-based echo gate (S1): Claude echoes typed
|
|
48
|
+
* input back in the pane, and when that echo carries no `❯` (a wrapped row, the
|
|
49
|
+
* `[Telegram thread context]` preamble, a voice-transcript tail) the shape-only
|
|
50
|
+
* {@link checkIsInputEchoFrame} misses it and it leaks into the topic. Empty
|
|
51
|
+
* until the first send.
|
|
52
|
+
*/
|
|
53
|
+
lastForwardedText: string;
|
|
54
|
+
/**
|
|
55
|
+
* Epoch ms of the last {@link lastForwardedText} capture. The content echo gate
|
|
56
|
+
* only fires within a short window after a send (the echo appears right at
|
|
57
|
+
* submit), so a much later real reply that coincidentally repeats prompt words
|
|
58
|
+
* is never suppressed.
|
|
59
|
+
*/
|
|
60
|
+
lastForwardedTextAt: number;
|
|
61
|
+
/**
|
|
62
|
+
* Signature of the last emitted interactive-question block (the option-label
|
|
63
|
+
* set, ignoring which option is highlighted). Moving the `❯` cursor repaints
|
|
64
|
+
* the whole box every keystroke; comparing signatures lets us deliver the
|
|
65
|
+
* question once and suppress the cursor-move repaints. Cleared when real
|
|
66
|
+
* prose follows (the question is over). See {@link extractClaudeQuestion}.
|
|
67
|
+
*/
|
|
68
|
+
lastQuestionSignature: string;
|
|
69
|
+
/**
|
|
70
|
+
* Consecutive poll diffs (while a question is pending) in which
|
|
71
|
+
* {@link extractClaudeQuestion} found NO selector on screen. The selector
|
|
72
|
+
* repaints constantly, so a single scrape can momentarily fail to match while
|
|
73
|
+
* it is still up; resolving the question (emit `questionGone`) on that lone
|
|
74
|
+
* null both unpins prematurely AND re-emits a duplicate question + notification
|
|
75
|
+
* the next poll (the signature was cleared). We only treat the question as gone
|
|
76
|
+
* after it has been absent for {@link questionAbsentPollThreshold} consecutive
|
|
77
|
+
* diffs. Reset to 0 on any detection.
|
|
78
|
+
*/
|
|
79
|
+
questionAbsentPolls: number;
|
|
80
|
+
/**
|
|
81
|
+
* Signature of the last AUTO-DISMISSED Claude CLI bare-digit survey (header +
|
|
82
|
+
* option digits/labels). Same de-dup mechanism as
|
|
83
|
+
* {@link lastQuestionSignature}: the survey repaints every poll while on
|
|
84
|
+
* screen, so comparing signatures sends the dismiss keystroke exactly once.
|
|
85
|
+
* Cleared when the survey leaves the pane, so a genuinely new survey later is
|
|
86
|
+
* re-dismissed. Drives {@link checkShouldDismissSurvey}. See
|
|
87
|
+
* {@link extractClaudeSurvey}.
|
|
88
|
+
*/
|
|
89
|
+
lastSurveySignature: string;
|
|
90
|
+
/**
|
|
91
|
+
* Handles for the auto-Enter / auto-Accept `setTimeout`s. Audit S9 / #10:
|
|
92
|
+
* the callbacks used to fire 300–400 ms after detection regardless of
|
|
93
|
+
* whether the session was still alive; on rapid stop/start the keystroke
|
|
94
|
+
* would land in a different invocation (e.g. auto-accepting a permission
|
|
95
|
+
* prompt belonging to a replacement session). Cleared on `stopSession`;
|
|
96
|
+
* callbacks also re-check `session.isActive` before issuing tmux keys.
|
|
97
|
+
*/
|
|
98
|
+
autoEnterTimer: NodeJS.Timeout | null;
|
|
99
|
+
autoAcceptOuterTimer: NodeJS.Timeout | null;
|
|
100
|
+
autoAcceptInnerTimer: NodeJS.Timeout | null;
|
|
101
|
+
/**
|
|
102
|
+
* Re-entrancy guard for `pollOutput`. Audit S9 / #37: a `tmux capture-pane`
|
|
103
|
+
* under load can take longer than the 300 ms poll interval, and the next
|
|
104
|
+
* `setInterval` tick would fire before the previous one finished, leading
|
|
105
|
+
* to duplicate `output` emissions. With self-rescheduling `setTimeout`
|
|
106
|
+
* and this flag we serialise polls; ticks that overlap with an in-flight
|
|
107
|
+
* one are skipped silently.
|
|
108
|
+
*/
|
|
109
|
+
isPolling: boolean;
|
|
110
|
+
/**
|
|
111
|
+
* Tool-result kind still open at the end of the last emitted poll, threaded
|
|
112
|
+
* into the next poll so a slow command's orphan output (whose `● Bash(…)`
|
|
113
|
+
* header was suppressed by the line-set diff) is still fenced (B2). See
|
|
114
|
+
* {@link fenceToolResultBodies}.
|
|
115
|
+
*/
|
|
116
|
+
openToolKind: ToolResultKind | null;
|
|
117
|
+
/**
|
|
118
|
+
* Resume flood-suppression mode. On `--resume`, Claude repaints the ENTIRE
|
|
119
|
+
* restored transcript into the pane over several polls; relaying that diff
|
|
120
|
+
* would dump hours of old conversation into the topic. While seeding we
|
|
121
|
+
* advance the baseline (`lastContent`) every poll but emit NOTHING, so once
|
|
122
|
+
* the pane stops growing the baseline equals the full restored transcript
|
|
123
|
+
* and later diffs are genuine new output. The short last-3-turn context block
|
|
124
|
+
* is posted separately (read from the `.jsonl`). The auto-Enter / auto-Accept
|
|
125
|
+
* machinery KEEPS running during seeding — we suppress conversation text, not
|
|
126
|
+
* lifecycle. See {@link getResumeSeedDecision}.
|
|
127
|
+
*/
|
|
128
|
+
resumeSeeding: boolean;
|
|
129
|
+
/** Polls elapsed in {@link resumeSeeding} mode — drives the stable/cap exit. */
|
|
130
|
+
resumeSeedPolls: number;
|
|
131
|
+
/** Pane content seen on the previous seeding poll, for the "unchanged across 2 polls" exit. */
|
|
132
|
+
resumeSeedPrevContent: string;
|
|
133
|
+
/**
|
|
134
|
+
* Raw `capture-pane` text from the previous poll. When the new capture is
|
|
135
|
+
* byte-identical we skip `cleanOutput` entirely (S1) — identical raw ⇒
|
|
136
|
+
* identical cleaned content, so the ~15-regex parse is pure wasted work on
|
|
137
|
+
* an idle pane. Reset wherever {@link lastContent} resets.
|
|
138
|
+
*/
|
|
139
|
+
lastRawCapture: string;
|
|
140
|
+
/**
|
|
141
|
+
* Current poll delay in ms (S2 adaptive backoff). Starts at
|
|
142
|
+
* {@link basePollIntervalMs}; {@link getNextPollDelay} grows it toward
|
|
143
|
+
* {@link maxPollIntervalMs} while the pane stays unchanged and snaps it back
|
|
144
|
+
* to base on any change or explicit write (see {@link resetPollCadence}).
|
|
145
|
+
*/
|
|
146
|
+
currentPollDelayMs: number;
|
|
147
|
+
/** Consecutive unchanged polls — drives {@link getNextPollDelay}'s backoff. */
|
|
148
|
+
unchangedPollStreak: number;
|
|
149
|
+
/**
|
|
150
|
+
* Epoch ms of the last poll whose raw `capture-pane` DIFFERED from the
|
|
151
|
+
* previous one (i.e. the TUI pane actually changed). Drives the bot's
|
|
152
|
+
* pane-static idle net via {@link ClaudeCliAdapter.getMsSincePaneChange}: a
|
|
153
|
+
* genuinely working agent repaints the pane every second (animated spinner +
|
|
154
|
+
* the TUI's own elapsed timer), so a long gap since the last change means the
|
|
155
|
+
* agent is idle even if the footer busy signal is stuck. Seeded to "now" at
|
|
156
|
+
* session creation / adopt so a fresh session never reads as instantly stale.
|
|
157
|
+
*/
|
|
158
|
+
lastContentChangeAt: number;
|
|
159
|
+
/**
|
|
160
|
+
* S7 one-shot: the stored `/effort` level to re-type ONCE the TUI input box
|
|
161
|
+
* first appears, so a fresh spawn doesn't inherit claude's GLOBAL effort
|
|
162
|
+
* state (possibly set in another topic). Set at spawn from the per-thread
|
|
163
|
+
* pref ({@link applyStoredEffortOnSpawn}); `null` when no pref or already
|
|
164
|
+
* applied. Consumed by the first poll that sees a ready prompt
|
|
165
|
+
* ({@link checkIsClaudePromptReady}), BEFORE the bot replays buffered prompts
|
|
166
|
+
* onto the same serial tmux queue. NOT set on adopt/reattach (that claude
|
|
167
|
+
* process kept its in-TUI effort and may be mid-turn).
|
|
168
|
+
*/
|
|
169
|
+
pendingEffortReapply: string | null;
|
|
170
|
+
/**
|
|
171
|
+
* Last transcript byte size persisted as the seen-{@link SeenWatermark} for
|
|
172
|
+
* this session (in-memory monotonic high-water mark). The poll loop advances
|
|
173
|
+
* the watermark to the current transcript EOF on EVERY idle+ready poll (not
|
|
174
|
+
* just the single busy→ready edge), but writes only when EOF actually grew —
|
|
175
|
+
* this field is the comparison anchor. `undefined` until the first advance,
|
|
176
|
+
* treated as `-1` (the first idle poll always writes). Fresh per session object
|
|
177
|
+
* (start / resume / adopt); correctness across a restart is protected by the
|
|
178
|
+
* recap's PRE-adopt watermark snapshot, not by seeding this from disk. Lets a
|
|
179
|
+
* bot restart count the assistant turns produced while it was down, and — vs
|
|
180
|
+
* the old edge-only gate — corrects a premature mid-turn idle advance and
|
|
181
|
+
* catches a final assistant line flushed just after the turn ends. See
|
|
182
|
+
* {@link checkShouldAdvanceWatermark} / {@link ClaudeCliAdapter.advanceClaudeWatermarkIfGrown}.
|
|
183
|
+
*/
|
|
184
|
+
lastWatermarkOffset?: number;
|
|
185
|
+
/**
|
|
186
|
+
* Long-horizon dedup of lines already RELAYED to this topic (incident
|
|
187
|
+
* 2026-06-10: a TUI re-render of an hours-old ~1400-line diff re-relayed as
|
|
188
|
+
* a ~12-message flood — {@link getNewPaneContent} only knows the previous
|
|
189
|
+
* capture, so a redraw of old scrollback looks "new" to it). The poll loop
|
|
190
|
+
* filters every diff chunk through this window before emitting and records
|
|
191
|
+
* a chunk ONLY when it was emitted as permanent output (status frames roll
|
|
192
|
+
* in place; questions/surveys carry their own signature de-dup). Fresh per
|
|
193
|
+
* session object (start / resume / adopt), dies with the session on stop,
|
|
194
|
+
* and reset again when resume seeding ends — the window must start empty
|
|
195
|
+
* AFTER the restored transcript was swallowed. See
|
|
196
|
+
* `utils/recentRelayWindow.ts` for the locked drop-over-resend tradeoff.
|
|
197
|
+
*/
|
|
198
|
+
recentRelayWindow: RecentRelayWindow;
|
|
199
|
+
/**
|
|
200
|
+
* Sub-agent transcript tail state (`/subagent full` on Claude, plan
|
|
201
|
+
* 2026-06-11 S3). The poll loop scans
|
|
202
|
+
* `<projectsRoot>/<slug>/<claudeSessionId>/subagents/` every tick and feeds
|
|
203
|
+
* file sizes / appended bytes into the pure `claudeSubagentTail` helpers;
|
|
204
|
+
* this holds the per-file byte offsets + partial-line carries. Fresh per
|
|
205
|
+
* session object (start / resume / adopt all flow through `createSession`),
|
|
206
|
+
* so the helper's first-scan EOF seeding kills backlog replay on
|
|
207
|
+
* resume/adopt — see {@link ClaudeCliAdapter.scanSubagentTranscripts}.
|
|
208
|
+
*/
|
|
209
|
+
subagentTail: SubagentTailState;
|
|
210
|
+
/**
|
|
211
|
+
* Cross-poll classifier context for the verbosity relay (S4). A tool body /
|
|
212
|
+
* thinking block / sub-agent panel can span the boundary between two scraped
|
|
213
|
+
* chunks (Claude redraws the whole pane each poll; the diff emits only NEW
|
|
214
|
+
* lines, so a slow command's body arrives in a later poll without its
|
|
215
|
+
* header). {@link classifyClaudeChunk} threads this so the later chunk still
|
|
216
|
+
* tags those orphan lines correctly. Fresh per session object (start /
|
|
217
|
+
* resume / adopt all flow through `createSession`).
|
|
218
|
+
*/
|
|
219
|
+
chunkContext: ClaudeChunkContext;
|
|
220
|
+
/**
|
|
221
|
+
* Last known pane size (`<width>x<height>`, e.g. `300x50`) from the per-poll
|
|
222
|
+
* `#{pane_width}x#{pane_height}` query; `null` until the first successful
|
|
223
|
+
* read. A CHANGE means tmux re-wrapped the whole scrollback (an interactive
|
|
224
|
+
* `tmux attach`/detach resizes the window — live incident 2026-07-02)
|
|
225
|
+
* and the poll's giant line-SET diff is repaint, not output. See
|
|
226
|
+
* {@link getPaneResizeGuardDecision}.
|
|
227
|
+
*/
|
|
228
|
+
lastPaneSize: string | null;
|
|
229
|
+
/**
|
|
230
|
+
* Whether the session is swallowing a resize repaint: baseline advances
|
|
231
|
+
* every poll but NOTHING is emitted, until a poll sees the capture unchanged
|
|
232
|
+
* (or the settle cap fires). Same suppress-and-advance shape as
|
|
233
|
+
* {@link resumeSeeding}, but for pane-size changes.
|
|
234
|
+
*/
|
|
235
|
+
isResizeSettling: boolean;
|
|
236
|
+
/** Consecutive suppressed polls spent in {@link isResizeSettling} — drives the cap. */
|
|
237
|
+
resizeSettlePolls: number;
|
|
238
|
+
/**
|
|
239
|
+
* Streaming-table stabilizer state (live incident 2026-06-11, plan
|
|
240
|
+
* `2026-06-11-claude-wide-table-content-loss`). A wide markdown table re-flows
|
|
241
|
+
* its column widths as longer cells stream in; the line-SET diff treats each
|
|
242
|
+
* intermediate layout as "new" and would ship the table once per layout (empty
|
|
243
|
+
* skeleton → 1 row → full), with the final full frame often dropped under the
|
|
244
|
+
* coalescer's debounce / a 429. We hold the table back until it settles, then
|
|
245
|
+
* emit the complete version once. `null` = no table currently held. Reset at
|
|
246
|
+
* the same lifecycle points as {@link recentRelayWindow} (fresh per session
|
|
247
|
+
* object via `createSession`, and on the resume-seed exit). See
|
|
248
|
+
* {@link getTableStabilizationDecision}.
|
|
249
|
+
*/
|
|
250
|
+
streamingTable: StreamingTableState | null;
|
|
251
|
+
}
|
|
252
|
+
export declare function loadEffortPrefs(): Record<string, string>;
|
|
253
|
+
export declare function saveEffortPref(key: SessionKey, level: string): void;
|
|
254
|
+
/**
|
|
255
|
+
* @description Tmux session name for a `SessionKey`.
|
|
256
|
+
*
|
|
257
|
+
* Format: `claude-<chatId>-<threadId>`. Negative chat ids (forum supergroups
|
|
258
|
+
* are negative) keep their minus sign — tmux session names accept it. The
|
|
259
|
+
* format is `parse`-able back to `SessionKey` via {@link parseTmuxSessionName}.
|
|
260
|
+
*/
|
|
261
|
+
declare function buildTmuxSessionName(key: SessionKey): string;
|
|
262
|
+
/**
|
|
263
|
+
* @description Inverse of {@link buildTmuxSessionName}. Returns `null` for
|
|
264
|
+
* names that don't match our format (e.g. unrelated tmux sessions a user
|
|
265
|
+
* started by hand).
|
|
266
|
+
*
|
|
267
|
+
* Carefully handles negative chat ids: `claude--1001234-42` is `chatId=-1001234, threadId=42`.
|
|
268
|
+
*/
|
|
269
|
+
declare function parseTmuxSessionName(name: string): SessionKey | null;
|
|
270
|
+
/**
|
|
271
|
+
* @description Validate a UUID-shaped session id before it ever reaches a
|
|
272
|
+
* tmux command line. Defence-in-depth (audit S1): even though we now route
|
|
273
|
+
* every tmux call through argv (no shell interpolation), the UUID is later
|
|
274
|
+
* concatenated into the `shell-command` we hand to `tmux new-session`,
|
|
275
|
+
* which tmux execs via `$SHELL -c`. If a non-UUID value ever sneaks in
|
|
276
|
+
* (corrupted state.json, future user-facing `/resume <id>`), it would land
|
|
277
|
+
* in that shell. Rejecting up front keeps the surface tight.
|
|
278
|
+
*/
|
|
279
|
+
export declare function checkIsValidUuid(s: string): boolean;
|
|
280
|
+
/**
|
|
281
|
+
* @description The `env CLAUDE_CONFIG_DIR=<dir>` argv prefix of a pane whose
|
|
282
|
+
* conversation uses a non-default account profile; empty for the default
|
|
283
|
+
* (`utils/claudeProfiles.ts`). Quoted with the rest of the argv by the caller.
|
|
284
|
+
*/
|
|
285
|
+
export declare function buildConfigDirEnvPrefix(configDir: string | null): string[];
|
|
286
|
+
/**
|
|
287
|
+
* @description Pure parser — pulls a `--session-id <uuid>` value out of a
|
|
288
|
+
* claude command line. Lives outside the adapter class so it can be
|
|
289
|
+
* unit-tested without booting tmux. Quoting in the input is flexible
|
|
290
|
+
* because `pane_start_command` can come back as `--session-id 'uuid'`,
|
|
291
|
+
* `--session-id "uuid"`, `--session-id=uuid`, or just `--session-id uuid`,
|
|
292
|
+
* depending on how the original shell-command was assembled. Returns the
|
|
293
|
+
* lowercase UUID, or `null` if no valid UUID is found.
|
|
294
|
+
*/
|
|
295
|
+
export declare function parseClaudeSessionIdFromCommand(cmd: string): string | null;
|
|
296
|
+
export { tmuxAsync };
|
|
297
|
+
export { convertAnsiToMarkdown, cleanOutput };
|
|
298
|
+
/**
|
|
299
|
+
* @description Check if output consists only of transient status lines (spinners, progress).
|
|
300
|
+
* Uses generic heuristics instead of hardcoded spinner chars/words,
|
|
301
|
+
* because Claude CLI can change its TUI symbols and wording at any time.
|
|
302
|
+
*
|
|
303
|
+
* Key insight: real Claude content is substantial (> 200 chars, multi-sentence).
|
|
304
|
+
* Status/progress is short, has few lines, and contains indicators like … or time/token stats.
|
|
305
|
+
*/
|
|
306
|
+
export declare function checkIsStatusOutput(text: string): boolean;
|
|
307
|
+
/**
|
|
308
|
+
* @description A single interactive question Claude scraped from the pane,
|
|
309
|
+
* rendered for durable delivery.
|
|
310
|
+
*/
|
|
311
|
+
export interface ClaudeQuestion {
|
|
312
|
+
/**
|
|
313
|
+
* Header + every numbered option (highlighted one kept), each followed by
|
|
314
|
+
* its indented description sub-line(s) when the TUI shows any, ready to send.
|
|
315
|
+
*/
|
|
316
|
+
text: string;
|
|
317
|
+
/**
|
|
318
|
+
* Stable across cursor moves — the option-label set, ignoring which option
|
|
319
|
+
* is currently highlighted. Two `❯`-cursor positions over the same options
|
|
320
|
+
* yield the same signature, so the bot delivers the question once.
|
|
321
|
+
*/
|
|
322
|
+
signature: string;
|
|
323
|
+
}
|
|
324
|
+
/**
|
|
325
|
+
* @description Detect + extract the active interactive question/choice block
|
|
326
|
+
* from the FULL Claude pane, returning a durable rendering and a
|
|
327
|
+
* cursor-invariant signature, or `null` when the pane isn't confidently
|
|
328
|
+
* showing a question.
|
|
329
|
+
*
|
|
330
|
+
* Operates on the whole pane (not a poll diff) on purpose: moving the `❯`
|
|
331
|
+
* cursor repaints only the two changed option lines, so a signature taken
|
|
332
|
+
* from the diff would be a partial option set and wouldn't match the full
|
|
333
|
+
* box — the de-dup would fail and every keystroke would re-spam the thread.
|
|
334
|
+
* Reading the full option group makes the signature stable across cursor
|
|
335
|
+
* moves. We take the LAST option group (the active prompt sits at the bottom
|
|
336
|
+
* of the pane) and the header line(s) just above it.
|
|
337
|
+
*
|
|
338
|
+
* Conservative (plan §2026-05-30 / S2): requires a `❯` cursor on an option
|
|
339
|
+
* OR an "Enter to select"-style hint right below the group — a plain numbered
|
|
340
|
+
* list in prose has neither, so it returns `null` and falls through to the
|
|
341
|
+
* normal output path. The `❯`-highlighted option text is preserved (the old
|
|
342
|
+
* `stripTuiElements` path discarded every `^❯` line, losing the selection).
|
|
343
|
+
*
|
|
344
|
+
* Two layouts (plan §2026-06-09 question-ux / S4):
|
|
345
|
+
* - single-column — options with optional indented description sub-lines,
|
|
346
|
+
* which are ATTACHED to their option in the rendering (S1: previously
|
|
347
|
+
* discarded);
|
|
348
|
+
* - side-by-side (options WITH `preview` content) — each option line carries
|
|
349
|
+
* a right-hand preview-box fragment that is CUT off; the preview body is
|
|
350
|
+
* deliberately NOT relayed (Telegram gets labels + descriptions, the
|
|
351
|
+
* preview is a TUI-only nicety). See {@link PREVIEW_BOX_GLYPH_CLASS} and
|
|
352
|
+
* {@link HIGHLIGHTED_OPTION_BOLD_ARTIFACT_REGEX} for the live bug both
|
|
353
|
+
* rules close.
|
|
354
|
+
*/
|
|
355
|
+
export declare function extractClaudeQuestion(text: string): ClaudeQuestion | null;
|
|
356
|
+
/** Whether `text` is confidently showing an interactive question/choice block. */
|
|
357
|
+
export declare function checkIsClaudeQuestionBlock(text: string): boolean;
|
|
358
|
+
/**
|
|
359
|
+
* @description Classify a user reply sent WHILE a selector is on screen. A
|
|
360
|
+
* "control" reply is meant to drive the selector in place — a bare option
|
|
361
|
+
* number (1–2 digits) or a single `y`/`n` — so it must be typed straight into
|
|
362
|
+
* the TUI with no Escape. Anything else (a sentence, a new instruction) is a
|
|
363
|
+
* free-form message: the bot first sends Escape to cancel the selector, then
|
|
364
|
+
* forwards it as a fresh turn. Kept pure + exported so the routing decision is
|
|
365
|
+
* unit-testable without a live tmux session.
|
|
366
|
+
*/
|
|
367
|
+
export declare function checkIsSelectorControlReply(text: string): boolean;
|
|
368
|
+
/**
|
|
369
|
+
* @description A Claude CLI bare-digit survey scraped from the pane, ready for
|
|
370
|
+
* answerable delivery. Distinct from {@link ClaudeQuestion} (a real
|
|
371
|
+
* AskUserQuestion box): a survey is a fixed-shape one-keystroke prompt.
|
|
372
|
+
*/
|
|
373
|
+
export interface ClaudeSurvey {
|
|
374
|
+
/** Header line, e.g. `How is Claude doing this session?`. */
|
|
375
|
+
header: string;
|
|
376
|
+
/** Options parsed from the inline `N: Label` row, in display order. */
|
|
377
|
+
options: ClaudeSurveyOption[];
|
|
378
|
+
/**
|
|
379
|
+
* Stable signature derived ONLY from header + option digits/labels — NOTHING
|
|
380
|
+
* volatile (no spinner glyph, no elapsed time, no surrounding pane). So the
|
|
381
|
+
* same survey across polls yields an identical signature → the bot emits it
|
|
382
|
+
* exactly once (mirrors {@link ClaudeQuestion.signature}).
|
|
383
|
+
*/
|
|
384
|
+
signature: string;
|
|
385
|
+
}
|
|
386
|
+
/**
|
|
387
|
+
* @description AIRTIGHT detector for the Claude CLI bare-digit survey. Returns
|
|
388
|
+
* a survey ONLY when BOTH hold:
|
|
389
|
+
*
|
|
390
|
+
* 1. Some line, after stripping an optional leading `● ` bullet, matches
|
|
391
|
+
* {@link CLAUDE_SURVEY_HEADER_REGEX} ANCHORED start-to-end (the WHOLE
|
|
392
|
+
* line) — so a header quoted mid-sentence is rejected.
|
|
393
|
+
* 2. The IMMEDIATELY-FOLLOWING non-empty line is an inline option row
|
|
394
|
+
* ({@link CLAUDE_SURVEY_OPTION_ROW_REGEX}) parsing to ≥2 options.
|
|
395
|
+
*
|
|
396
|
+
* Kept fully SEPARATE from {@link extractClaudeQuestion} (the per-line
|
|
397
|
+
* AskUserQuestion selector): this is a lighter fixed-shape prompt. The
|
|
398
|
+
* signature is header + the option digits/labels only (no volatile chrome), so
|
|
399
|
+
* the same survey across polls de-dups to a single emit.
|
|
400
|
+
*/
|
|
401
|
+
export declare function extractClaudeSurvey(text: string): ClaudeSurvey | null;
|
|
402
|
+
/** Whether `text` is confidently showing a Claude CLI bare-digit survey. */
|
|
403
|
+
export declare function checkIsClaudeSurvey(text: string): boolean;
|
|
404
|
+
/**
|
|
405
|
+
* @description Whether the poll loop should AUTO-DISMISS the survey on screen
|
|
406
|
+
* this poll (S4). True only when a survey is present AND its signature differs
|
|
407
|
+
* from the one we last dismissed — the survey repaints every poll, so the
|
|
408
|
+
* signature dedup makes us send the dismiss keystroke exactly ONCE per
|
|
409
|
+
* appearance, and re-dismiss a genuinely new survey later (the caller clears the
|
|
410
|
+
* stored signature when the survey leaves the pane). Pure + exported so the
|
|
411
|
+
* once-per-appearance rule is unit-testable without a live session.
|
|
412
|
+
*/
|
|
413
|
+
export declare function checkShouldDismissSurvey(surveySignature: string | null, lastDismissedSignature: string): boolean;
|
|
414
|
+
/**
|
|
415
|
+
* @description Drop the survey's header + option-row lines from a relay chunk
|
|
416
|
+
* (S4) so the auto-dismissed survey's chrome never leaks into the topic — those
|
|
417
|
+
* lines match no tool/spinner/chrome rule and would otherwise classify as prose
|
|
418
|
+
* and post as a stray message. The CALLER gates this on a survey actually being
|
|
419
|
+
* detected on the pane this poll, so a legitimate "1: Yes 2: No" list in normal
|
|
420
|
+
* agent output is never stripped. Pure + exported for unit testing.
|
|
421
|
+
*/
|
|
422
|
+
export declare function stripSurveyChromeLines(text: string): string;
|
|
423
|
+
/**
|
|
424
|
+
* @description One ordered tmux send-keys step the adapter will enqueue for a
|
|
425
|
+
* {@link ClaudeCliAdapter.sendInput} call. Extracted as a pure plan so the
|
|
426
|
+
* "no Enter" decision is unit-testable WITHOUT a live tmux session.
|
|
427
|
+
*
|
|
428
|
+
* - `literal` — `send-keys -l <input>` (the typed text, literal bytes);
|
|
429
|
+
* - `instantEnter` — `send-keys Enter` immediately (short control reply);
|
|
430
|
+
* - `slashEnter` — `send-keys Enter` deferred so the slash-popup settles;
|
|
431
|
+
* - `verifiedEnter` — `send-keys Enter` deferred past the paste-aggregation
|
|
432
|
+
* window, plus a post-Enter unsubmitted re-check (a plain prompt).
|
|
433
|
+
*/
|
|
434
|
+
export type ClaudeSendKeyStep = 'literal' | 'instantEnter' | 'slashEnter' | 'verifiedEnter';
|
|
435
|
+
/**
|
|
436
|
+
* @description Pure plan of the tmux send-keys steps for one `sendInput` call.
|
|
437
|
+
*
|
|
438
|
+
* Mirrors the three historical Enter branches (bare slash command → deferred
|
|
439
|
+
* Enter; short control reply → instant Enter; plain prompt → paste-race
|
|
440
|
+
* deferred Enter + verification). When `appendEnter === false` ONLY the literal
|
|
441
|
+
* keystrokes are sent — every Enter branch is skipped (for a keystroke that
|
|
442
|
+
* auto-submits on its own). `appendEnter` defaults to `true`, so every existing
|
|
443
|
+
* caller's plan is byte-for-byte unchanged.
|
|
444
|
+
*/
|
|
445
|
+
export declare function getClaudeSendKeysPlan(input: string, appendEnter: boolean): ClaudeSendKeyStep[];
|
|
446
|
+
/** Where a Claude text reply should be routed while a prompt may be on screen. */
|
|
447
|
+
export type ClaudeReplyRoute = 'selector' | 'loginPaste' | 'prompt';
|
|
448
|
+
/**
|
|
449
|
+
* @description Decide how to route a user TEXT reply for a Claude thread,
|
|
450
|
+
* given which interactive prompts are currently pending. Pure so the
|
|
451
|
+
* precedence is unit-testable.
|
|
452
|
+
*
|
|
453
|
+
* Precedence (a real AskUserQuestion always wins):
|
|
454
|
+
* 1. A selector (AskUserQuestion) pending + a bare control reply
|
|
455
|
+
* (digit / y / n) → `'selector'` (drive the menu in place).
|
|
456
|
+
* 2. Else the `/login` "Paste code here" box is on screen → `'loginPaste'`:
|
|
457
|
+
* the OAuth code is a long free-form string, so route it VERBATIM into
|
|
458
|
+
* the box (see {@link checkIsClaudeLoginPaste}). Without this it falls to
|
|
459
|
+
* `'prompt'`, whose Escape cancels the login flow and whose preamble
|
|
460
|
+
* corrupts the code (live bug: "login can't be done via the bot").
|
|
461
|
+
* 3. Else → `'prompt'` (a fresh turn; free-form prose breaks out of any
|
|
462
|
+
* pending prompt, mirroring the existing selector break-out behavior).
|
|
463
|
+
*
|
|
464
|
+
* Claude's native session SURVEY is NOT routed here: the adapter auto-dismisses
|
|
465
|
+
* it (Escape) and never surfaces it to the user, so a bare digit typed during a
|
|
466
|
+
* survey window falls through to `'prompt'` (or `'selector'` when a real
|
|
467
|
+
* question is also up) — never silently dropped.
|
|
468
|
+
*/
|
|
469
|
+
export declare function getClaudeReplyRoute(input: {
|
|
470
|
+
isQuestionPending: boolean;
|
|
471
|
+
isLoginPastePending: boolean;
|
|
472
|
+
text: string;
|
|
473
|
+
}): ClaudeReplyRoute;
|
|
474
|
+
export declare function checkIsClaudeLoginPaste(paneText: string): boolean;
|
|
475
|
+
/**
|
|
476
|
+
* @description Per-session state for the streaming-table stabilizer (live
|
|
477
|
+
* incident 2026-06-11, plan `2026-06-11-claude-wide-table-content-loss`): the
|
|
478
|
+
* sharp-corner table block currently being held back, and how many polls it has
|
|
479
|
+
* been held. Held back because a wide markdown table RE-FLOWS its column widths
|
|
480
|
+
* as longer cells stream in, so every border/row line is byte-distinct between
|
|
481
|
+
* layouts → {@link getNewPaneContent} (line-SET diff) classifies the whole table
|
|
482
|
+
* "new" each poll and it would otherwise ship once per intermediate layout
|
|
483
|
+
* (empty skeleton → 1 row → full). We withhold the table until it settles, then
|
|
484
|
+
* emit the complete version exactly once.
|
|
485
|
+
*/
|
|
486
|
+
interface StreamingTableState {
|
|
487
|
+
/** The full last-contiguous sharp-table block text seen on the previous poll. */
|
|
488
|
+
block: string;
|
|
489
|
+
/** Consecutive polls this table has been held without settling — runaway guard. */
|
|
490
|
+
heldPolls: number;
|
|
491
|
+
}
|
|
492
|
+
/**
|
|
493
|
+
* @description The action {@link getTableStabilizationDecision} tells the poll
|
|
494
|
+
* loop to take for a re-flowing sharp-corner table.
|
|
495
|
+
*
|
|
496
|
+
* - `none` — no table in flux; emit the poll's delta as usual.
|
|
497
|
+
* - `hold` — the table is still laying out; mask its lines out of this poll's
|
|
498
|
+
* delta ({@link maskSharpTableLines}) so no intermediate frame ships,
|
|
499
|
+
* and carry `nextStreamingTable` forward.
|
|
500
|
+
* - `emit` — the table is DONE (prose follows it / the turn went idle / the
|
|
501
|
+
* safety cap fired); emit `block` once via the normal fence path and
|
|
502
|
+
* clear the held state.
|
|
503
|
+
*/
|
|
504
|
+
interface TableStabilizationDecision {
|
|
505
|
+
kind: 'none' | 'hold' | 'emit';
|
|
506
|
+
/** The complete table block to emit, set only for `kind: 'emit'`. */
|
|
507
|
+
block: string | null;
|
|
508
|
+
/** Held state to store back on the session (null clears it). */
|
|
509
|
+
nextStreamingTable: StreamingTableState | null;
|
|
510
|
+
}
|
|
511
|
+
/**
|
|
512
|
+
* @description Find the LAST contiguous sharp-corner (markdown) table block in a
|
|
513
|
+
* full pane snapshot, or `null` when none is present. Returns the raw block text
|
|
514
|
+
* so the stabilizer can compare it across polls. Pure + exported for unit tests.
|
|
515
|
+
*/
|
|
516
|
+
export declare function getLastSharpTableBlock(content: string): string | null;
|
|
517
|
+
/**
|
|
518
|
+
* @description Whether any REAL prose line follows the last sharp-corner table in
|
|
519
|
+
* the pane — the "the table is done, content moved past it" signal the stabilizer
|
|
520
|
+
* uses to emit the held table BEFORE that trailing prose (preserving order).
|
|
521
|
+
*
|
|
522
|
+
* Deliberately CONSERVATIVE (errs toward `false`): a line after the table counts
|
|
523
|
+
* as content only when it is none of the recognised non-content shapes —
|
|
524
|
+
* blank/whitespace, another sharp-table line, TUI chrome
|
|
525
|
+
* ({@link checkIsClaudeChromeLine} — covers the `❯ …` input box and its `───`
|
|
526
|
+
* rules, box-drawing borders, the `⏵⏵ bypass permissions…` footer, nav hints),
|
|
527
|
+
* any progress/spinner/sub-agent frame ({@link checkIsProgressChunk} per line),
|
|
528
|
+
* a live spinner tick ({@link SPINNER_TICK_RE}), a `✻ … for Ns` post-thinking
|
|
529
|
+
* trailer ({@link POST_THINKING_TRAILER_RE}), or a `Thinking for Ns…` header
|
|
530
|
+
* ({@link THINKING_HEADER_RE}). Reuses the SAME predicates the relay already
|
|
531
|
+
* trusts as chrome — it never invents a looser matcher — so it cannot
|
|
532
|
+
* false-positive on the input box / spinner / trailers (the failure mode that
|
|
533
|
+
* would emit a table prematurely). The turn-idle signal and the hold safety cap
|
|
534
|
+
* are the backstops when this stays `false`. Pure + exported for unit tests.
|
|
535
|
+
*/
|
|
536
|
+
export declare function checkHasContentAfterLastSharpTable(content: string): boolean;
|
|
537
|
+
/**
|
|
538
|
+
* @description Drop every sharp-corner table line from a poll's delta text so a
|
|
539
|
+
* mid-layout table frame never ships while the stabilizer is holding the table.
|
|
540
|
+
* Only table-shaped lines are removed — surrounding prose streams as usual.
|
|
541
|
+
* Pure + exported for unit tests.
|
|
542
|
+
*/
|
|
543
|
+
export declare function maskSharpTableLines(deltaText: string): string;
|
|
544
|
+
/**
|
|
545
|
+
* @description Decide what the poll loop does with a re-flowing sharp-corner
|
|
546
|
+
* table. A held table is emitted ONLY when the turn is genuinely DONE — never on
|
|
547
|
+
* a mere "byte-stable for one poll", because Claude streams a table in stages and
|
|
548
|
+
* briefly PAUSES at an intermediate row count (e.g. 4 rows), which is byte-stable
|
|
549
|
+
* across a poll yet not the final table. The old "stable one poll → emit" rule
|
|
550
|
+
* shipped that 4-row intermediate, then the table grew to 6 rows and shipped
|
|
551
|
+
* again → the topic got two tables (live incident 2026-06-15). Pure + exported
|
|
552
|
+
* for unit tests. Rules, in order:
|
|
553
|
+
*
|
|
554
|
+
* 1. no table in the pane: flush whatever was held, once (table scrolled away /
|
|
555
|
+
* message moved on); else no-op.
|
|
556
|
+
* 2. real PROSE now follows the table (`hasContentAfterTable`) AND the table's
|
|
557
|
+
* width has settled (`sameBlock` — byte-stable since the previous poll) → the
|
|
558
|
+
* table is done; emit it BEFORE that trailing prose (the poll loop withholds
|
|
559
|
+
* the prose this tick), so ordering is table-then-prose. A table still
|
|
560
|
+
* re-flowing wider while prose is already on the pane HOLDS instead — only the
|
|
561
|
+
* settled width ships (live flood 2026-07-04).
|
|
562
|
+
* 3. the turn is IDLE (`isTurnIdle`) → emit promptly (covers a table-only
|
|
563
|
+
* answer, which never gets trailing prose).
|
|
564
|
+
* 4. otherwise HOLD — update the held block and advance `heldPolls` only while
|
|
565
|
+
* the block is unchanged (a changed/new block resets the counter); past
|
|
566
|
+
* {@link maxTableHoldPolls} force-emit so a never-settling pane can't swallow
|
|
567
|
+
* the table forever. A still-busy table is held even when byte-identical
|
|
568
|
+
* across polls — that is exactly the mid-stream pause.
|
|
569
|
+
*/
|
|
570
|
+
export declare function getTableStabilizationDecision(input: {
|
|
571
|
+
currentTable: string | null;
|
|
572
|
+
streamingTable: StreamingTableState | null;
|
|
573
|
+
hasContentAfterTable: boolean;
|
|
574
|
+
isTurnIdle: boolean;
|
|
575
|
+
}): TableStabilizationDecision;
|
|
576
|
+
/**
|
|
577
|
+
* @description Merge two same-language fenced blocks separated by NOTHING but
|
|
578
|
+
* blank line(s) into one continuous fence (#14). One logical tool output that
|
|
579
|
+
* {@link fenceToolResultBodies} split into multiple `getFenced` runs renders as
|
|
580
|
+
* two adjacent `<pre>` ({@link FENCE_REGEX} makes one per fence) — visually two
|
|
581
|
+
* boxes for one output. A NON-blank line between the fences (a `● Bash(…)`
|
|
582
|
+
* header, prose) BLOCKS the merge, so DIFFERENT tool calls stay separate; only
|
|
583
|
+
* blank-separated same-language fences are joined, keeping one blank inside.
|
|
584
|
+
* Languages must match (or both be empty) so a plain output block and a `ts`
|
|
585
|
+
* block are never fused.
|
|
586
|
+
*/
|
|
587
|
+
export declare function mergeAdjacentFences(lines: string[]): string[];
|
|
588
|
+
/**
|
|
589
|
+
* @description Strip Claude TUI chrome from a pane diff and fence tool-result
|
|
590
|
+
* bodies, returning the cleaned text AND the tool-result kind still open at the
|
|
591
|
+
* end of the chunk. The caller (`pollOutput`) threads `toolKind` back in as the
|
|
592
|
+
* next poll's `incomingKind` so a slow command's orphan output is fenced (B2).
|
|
593
|
+
*/
|
|
594
|
+
export declare function stripTuiElementsWithContext(text: string, incomingKind?: ToolResultKind | null): {
|
|
595
|
+
text: string;
|
|
596
|
+
toolKind: ToolResultKind | null;
|
|
597
|
+
};
|
|
598
|
+
/**
|
|
599
|
+
* @description Strip Claude TUI chrome and fence tool-result bodies (B2),
|
|
600
|
+
* returning just the cleaned text. Thin wrapper over
|
|
601
|
+
* {@link stripTuiElementsWithContext} for call sites (and tests) that don't
|
|
602
|
+
* thread the cross-poll tool kind.
|
|
603
|
+
*/
|
|
604
|
+
export declare function stripTuiElements(text: string, incomingKind?: ToolResultKind | null): string;
|
|
605
|
+
/**
|
|
606
|
+
* @description Turn an absolute workDir into Claude's transcript-folder slug.
|
|
607
|
+
*
|
|
608
|
+
* Claude stores per-project transcripts under
|
|
609
|
+
* `~/.claude/projects/<slug>/<sessionUuid>.jsonl`, where the slug is the
|
|
610
|
+
* absolute path with every non-alphanumeric character replaced by `-`
|
|
611
|
+
* (e.g. `/home/user/src/telegramCode` → `-home-user-src-telegramCode`).
|
|
612
|
+
*
|
|
613
|
+
* The slug encoding is undocumented and could drift across Claude versions,
|
|
614
|
+
* so it is used only to *locate* the candidate folder — the authoritative
|
|
615
|
+
* correctness gate is the `recordedCwd === workDir` filter in
|
|
616
|
+
* {@link listClaudeSessionsForWorkDir}.
|
|
617
|
+
*/
|
|
618
|
+
export declare function getClaudeProjectSlug(workDir: string): string;
|
|
619
|
+
/**
|
|
620
|
+
* @description Root of Claude's on-disk transcript store
|
|
621
|
+
* (`~/.claude/projects`). Single source for every path built from it —
|
|
622
|
+
* session listing, resume-context reads, and the sub-agent transcript scan.
|
|
623
|
+
*/
|
|
624
|
+
export declare function getClaudeProjectsRoot(): string;
|
|
625
|
+
/**
|
|
626
|
+
* @description Absolute path of ONE session's transcript
|
|
627
|
+
* (`<projectsRoot>/<slug>/<sessionId>.jsonl`).
|
|
628
|
+
*
|
|
629
|
+
* Single source for the layout: both Claude backends resolve it for the
|
|
630
|
+
* watermark advance, the runtime-info read, the resume-context turns, and the
|
|
631
|
+
* reattach recap — a hand-built copy in any of them would silently read nothing
|
|
632
|
+
* if the layout ever drifts.
|
|
633
|
+
*/
|
|
634
|
+
export declare function getClaudeTranscriptPath(workDir: string, sessionId: string): string;
|
|
635
|
+
/**
|
|
636
|
+
* @description Read the last `limit` conversational turns (user/assistant
|
|
637
|
+
* messages with renderable text, oldest→newest) from a Claude `.jsonl`
|
|
638
|
+
* transcript, for the resume context block.
|
|
639
|
+
*
|
|
640
|
+
* Exported and pure (filesystem-only) so it is unit-testable against a temp
|
|
641
|
+
* `.jsonl`. Streams the whole file via {@link parseClaudeTurnLine}, keeping only
|
|
642
|
+
* the last `limit` in a rolling window so a huge transcript stays cheap.
|
|
643
|
+
* Tolerates a half-written trailing line; a missing/unreadable file → `[]`.
|
|
644
|
+
*/
|
|
645
|
+
export declare function readRecentClaudeTurns(filePath: string, limit: number): RecentTurn[];
|
|
646
|
+
/**
|
|
647
|
+
* @description Combined transcript read for the silent-reattach recap: ONE
|
|
648
|
+
* `fs.readFileSync` yields BOTH the missed-message count and the recap turn
|
|
649
|
+
* body, so the transcript is not read twice.
|
|
650
|
+
*
|
|
651
|
+
* - `missedCount` — renderable `type:'assistant'` turns appended AFTER byte
|
|
652
|
+
* `offset` (the seen-watermark = transcript size at the last turn end), counted
|
|
653
|
+
* over the `[offset, EOF)` byte tail. A torn leading line (offset mid-record)
|
|
654
|
+
* fails to parse and is skipped. `offset >= size` → `0` (nothing appended /
|
|
655
|
+
* transcript truncated or rewritten smaller).
|
|
656
|
+
* - `turns` — the last `limit` renderable turns of the WHOLE session (NOT just
|
|
657
|
+
* the missed region), identical to {@link readRecentClaudeTurns}.
|
|
658
|
+
* - `headOffset` — the transcript's CURRENT byte size (`buffer.length`), i.e.
|
|
659
|
+
* the watermark value meaning "everything currently on disk is accounted for".
|
|
660
|
+
* The reattach recap advances the persisted watermark to it for idempotency.
|
|
661
|
+
* Absent on an unreadable file (head unknown → the caller omits the watermark).
|
|
662
|
+
*
|
|
663
|
+
* Exported and pure (filesystem-only) so it is unit-testable. `fs.readFileSync`
|
|
664
|
+
* reads the whole file in one call (it handles short reads internally), so a
|
|
665
|
+
* large `[offset, EOF)` tail never loses its last lines to a partial `read` —
|
|
666
|
+
* the silent undercount a manual `Buffer.alloc` + `fs.readSync` would hit on
|
|
667
|
+
* exactly the long-downtime case this feature targets. A missing/unreadable
|
|
668
|
+
* file → `{ missedCount: 0, turns: [] }` (no `headOffset`).
|
|
669
|
+
*/
|
|
670
|
+
export declare function readClaudeReattachTranscript(filePath: string, offset: number, limit: number): {
|
|
671
|
+
missedCount: number;
|
|
672
|
+
turns: RecentTurn[];
|
|
673
|
+
headOffset?: number;
|
|
674
|
+
};
|
|
675
|
+
/**
|
|
676
|
+
* @description List resumable Claude sessions for a workDir by reading the
|
|
677
|
+
* real `~/.claude/projects/<slug>/*.jsonl` transcripts.
|
|
678
|
+
*
|
|
679
|
+
* Exported and pure (filesystem-only, no tmux/adapter boot) so it can be
|
|
680
|
+
* unit-tested against a temp `projectsRoot`. Steps:
|
|
681
|
+
*
|
|
682
|
+
* 1. Resolve `<projectsRoot>/<slug>`; if missing → `[]`.
|
|
683
|
+
* 2. Take the {@link sessionsParseLimit} most-recently-modified `.jsonl`.
|
|
684
|
+
* 3. Parse each; KEEP only files whose recorded cwd === `workDir`
|
|
685
|
+
* (the load-bearing correctness gate — slug collisions / version drift).
|
|
686
|
+
* 4. id = filename stem, MUST pass {@link checkIsValidUuid} (else skip).
|
|
687
|
+
* 5. title = summaryTitle ?? firstMeaningfulPrompt ?? id (trimmed, capped).
|
|
688
|
+
* `summaryTitle` is legacy (current Claude no longer writes it); the
|
|
689
|
+
* primary source is the first REAL prompt topic
|
|
690
|
+
* ({@link getSessionTitleCandidate}) — preamble/marker stripped, tooling
|
|
691
|
+
* noise skipped — NOT the last (often noise) prompt. A session with no
|
|
692
|
+
* meaningful prompt (all turns were command echoes / noise) falls back to
|
|
693
|
+
* the bare id. updatedAt = file mtime; createdAt = first timestamp ?? mtime.
|
|
694
|
+
*
|
|
695
|
+
* Result is newest-first by mtime.
|
|
696
|
+
*/
|
|
697
|
+
export declare function listClaudeSessionsForWorkDir(projectsRoot: string, workDir: string): AgentSession[];
|
|
698
|
+
/**
|
|
699
|
+
* @description Whether `input` is a bare slash command (matches
|
|
700
|
+
* {@link BARE_SLASH_COMMAND_RE} after trimming). Exported so the
|
|
701
|
+
* popup-settle decision is unit-testable without a live tmux session.
|
|
702
|
+
*/
|
|
703
|
+
export declare function checkIsBareSlashCommand(input: string): boolean;
|
|
704
|
+
/**
|
|
705
|
+
* @description Whether Claude is mid-turn, judged from a captured pane. A
|
|
706
|
+
* selector/permission prompt shows `Esc to cancel`, NOT `esc to interrupt`, so
|
|
707
|
+
* it reads as idle here (correct — we only wait out a running turn). Only the
|
|
708
|
+
* footer tail is inspected ({@link CLAUDE_BUSY_FOOTER_TAIL_LINES}) and the hint
|
|
709
|
+
* must carry footer chrome ({@link CLAUDE_BUSY_FOOTER_RE}), so scrollback prose
|
|
710
|
+
* mentioning the phrase can't false-positive. Exported so the busy detection is
|
|
711
|
+
* unit-testable without a live tmux session.
|
|
712
|
+
*/
|
|
713
|
+
export declare function checkIsClaudeBusy(paneText: string): boolean;
|
|
714
|
+
/**
|
|
715
|
+
* @description Sync, in-memory "is this session mid-turn?" decision for the
|
|
716
|
+
* scheduler's wait-for-idle loop ({@link AgentAdapter.checkIsBusy}). Reuses the
|
|
717
|
+
* SAME pane predicate {@link interruptAndWaitIdle} polls
|
|
718
|
+
* ({@link checkIsClaudeBusy} on the `esc to interrupt` footer), evaluated
|
|
719
|
+
* against the session's last CLEANED pane content instead of a fresh `tmux`
|
|
720
|
+
* call — so it stays synchronous and adds no tmux load. The cleaned text is
|
|
721
|
+
* load-bearing: the raw `-e` capture carries ANSI/SGR runs that can split the
|
|
722
|
+
* footer marker mid-word and make the regex miss (the predicate's other
|
|
723
|
+
* callers read plain no-`-e` captures for the same reason). A dead/missing
|
|
724
|
+
* session is never busy. Exported pure so the gate is unit-testable without a
|
|
725
|
+
* live session.
|
|
726
|
+
*/
|
|
727
|
+
export declare function checkIsClaudeSessionBusy(args: {
|
|
728
|
+
isActive: boolean;
|
|
729
|
+
lastContent: string;
|
|
730
|
+
}): boolean;
|
|
731
|
+
/**
|
|
732
|
+
* @description Whether a cleaned output frame is nothing but the TUI input box
|
|
733
|
+
* echoing typed text (`❯ <draft>`). The poll can catch the input row between
|
|
734
|
+
* the literal-text keystrokes and the deferred submit Enter (B5 window), and
|
|
735
|
+
* that draft echo is pure noise in Telegram — the user already sees their own
|
|
736
|
+
* message (B7).
|
|
737
|
+
*
|
|
738
|
+
* A frame is an echo when its FIRST non-empty line starts with `❯` AND no line
|
|
739
|
+
* carries a content marker (`●`, `⎿`, or a ``` ``` ``` fence). The old
|
|
740
|
+
* predicate required EVERY line to start with `❯`, but a long draft wraps in
|
|
741
|
+
* the input box so only the first row carries `❯` and the continuation rows are
|
|
742
|
+
* plain — those frames leaked into the topic (B7b). Anchoring on the first line
|
|
743
|
+
* + a content-marker veto keeps a `❯` inside real tool output (e.g. a pane
|
|
744
|
+
* capture printed by a Bash command) classified as content, not an echo.
|
|
745
|
+
*
|
|
746
|
+
* MAINTENANCE — Claude Code's TUI rendering drifts between versions, back and
|
|
747
|
+
* forth (the prompt glyph, the echo indentation, the content markers — e.g. the
|
|
748
|
+
* `●`→`⏺` bullet change noted in `utils/claudeScrapeShapes.ts`). This detector
|
|
749
|
+
* must tolerate ALL known formatting variants, not assume the current one: when
|
|
750
|
+
* an echo starts leaking into the topic, WIDEN the predicate to also cover the
|
|
751
|
+
* new shape (keep the old variants), don't swap one shape for another.
|
|
752
|
+
*/
|
|
753
|
+
export declare function checkIsInputEchoFrame(frameText: string): boolean;
|
|
754
|
+
/**
|
|
755
|
+
* @description CONTENT-based echo gate (S1), complementing the shape-only
|
|
756
|
+
* {@link checkIsInputEchoFrame}. The bot types the user's prompt into the Claude
|
|
757
|
+
* TUI and Claude echoes it back in the pane; when that echo carries NO `❯`
|
|
758
|
+
* (a wrapped continuation row, the `[Telegram thread context]` preamble, or the
|
|
759
|
+
* tail of a long voice transcript) the shape gate misses it and it leaks into
|
|
760
|
+
* the topic as a ghost "bot message" (live 2026-06-28).
|
|
761
|
+
*
|
|
762
|
+
* A cleaned frame is the user's own echo when EITHER:
|
|
763
|
+
* - it carries the deterministic thread-context preamble signature (the
|
|
764
|
+
* `[Telegram thread context]` header — the agent never emits that itself), OR
|
|
765
|
+
* - its normalized text is a contiguous slice of the normalized forwarded text
|
|
766
|
+
* (a prefix, suffix, or interior run) of at least
|
|
767
|
+
* {@link claudeEchoMinMatchChars} — i.e. the whole frame is nothing but a
|
|
768
|
+
* chunk of what we just typed.
|
|
769
|
+
*
|
|
770
|
+
* The containment DIRECTION is load-bearing: the FRAME must be contained in the
|
|
771
|
+
* forwarded text, never the reverse — so a genuine reply that QUOTES part of the
|
|
772
|
+
* prompt and then adds an answer is NOT a substring of the prompt and is kept.
|
|
773
|
+
* The caller additionally gates this on a short post-forward time window.
|
|
774
|
+
*
|
|
775
|
+
* WIDENED (live 2026-07-06): the poll can catch the just-submitted
|
|
776
|
+
* echo's wrapped row GLUED to the new turn's first spinner tick in ONE frame
|
|
777
|
+
* (`<echo row>\n\n* Twisting…`). The glued chrome is not part of the forwarded
|
|
778
|
+
* text, so whole-frame containment failed and the row leaked as a permanent
|
|
779
|
+
* message. When the whole frame misses, transient-shaped lines (per-line
|
|
780
|
+
* {@link checkIsStatusOutput}) are dropped and the remaining content is
|
|
781
|
+
* re-tested — only a frame whose real content is nothing but a slice of the
|
|
782
|
+
* forwarded text is suppressed, so an answer glued to a spinner is still kept.
|
|
783
|
+
*
|
|
784
|
+
* Pure + exported so every observed echo variant is unit-testable. MAINTENANCE:
|
|
785
|
+
* like {@link checkIsInputEchoFrame}, WIDEN (never swap) when a new echo shape
|
|
786
|
+
* leaks — keep the old variants.
|
|
787
|
+
*/
|
|
788
|
+
export declare function checkIsForwardedEcho(frameText: string, forwardedText: string): boolean;
|
|
789
|
+
/**
|
|
790
|
+
* @description Whether a captured pane looks like the typed prompt is still
|
|
791
|
+
* sitting UNSUBMITTED in Claude's live input box (the B5 paste-race symptom).
|
|
792
|
+
*
|
|
793
|
+
* Submission predicate (the load-bearing "did it submit?" check): a prompt has
|
|
794
|
+
* submitted iff EITHER Claude went busy (`esc to interrupt` in the footer — the
|
|
795
|
+
* turn started) OR the live input box at the bottom is empty (`❯ ` with no
|
|
796
|
+
* text — Claude consumed the input and is idle again, e.g. a fast/no-op turn).
|
|
797
|
+
* It looks UNSUBMITTED only when Claude is idle AND the last `❯`-led input row
|
|
798
|
+
* still carries the typed text. We deliberately key on the LAST `❯` line: a
|
|
799
|
+
* SUBMITTED prompt echoes as a `❯ <text>` user-turn block in scrollback, but
|
|
800
|
+
* the live input box below it is the final `❯` line and is empty — so matching
|
|
801
|
+
* the last one ignores the harmless scrollback echo.
|
|
802
|
+
*
|
|
803
|
+
* Tradeoff (locked in plan B5): if a single verification capture is ambiguous
|
|
804
|
+
* we err toward reporting unsubmitted and let the caller retry Enter once — a
|
|
805
|
+
* duplicate Enter on an already-submitted prompt is a harmless no-op in the
|
|
806
|
+
* Claude TUI (submits an empty input = ignored), whereas a missed submit silently
|
|
807
|
+
* loses the user's message.
|
|
808
|
+
*
|
|
809
|
+
* Exported so the predicate is unit-testable without a live tmux session.
|
|
810
|
+
*/
|
|
811
|
+
export declare function checkLooksUnsubmitted(paneText: string, typedText: string): boolean;
|
|
812
|
+
/**
|
|
813
|
+
* @description Find the ONE line in a scraped pane that is a terminal
|
|
814
|
+
* provider / auth error, or `null` if none. `content` is `cleanOutput(raw)`,
|
|
815
|
+
* which RETAINS the `⎿` result marker. Three accepted shapes:
|
|
816
|
+
* a) `API Error: …` at line start — the classic provider row
|
|
817
|
+
* (`API Error: … (not your usage limit) · Rate limited`).
|
|
818
|
+
* b) a `⎿` result row that also contains `API Error:`
|
|
819
|
+
* (`⎿ overloaded · API Error: 429` — the render the old start-anchored gate
|
|
820
|
+
* MISSED, which is why a `⎿`-prefixed rate-limit never auto-retried).
|
|
821
|
+
* c) a `⎿` result row whose content LEADS with an auth phrase
|
|
822
|
+
* (`⎿ Not logged in · Please run /login` — the logged-out render).
|
|
823
|
+
* d) a row whose content LEADS with a usage/session-limit phrase AND reads like
|
|
824
|
+
* an error ({@link CLAUDE_LIMIT_ROW_SHAPE_RE}) — `You've hit your session
|
|
825
|
+
* limit · resets 10:50pm (UTC)` carries no `API Error:` marker at all, so
|
|
826
|
+
* (a)–(c) all missed it.
|
|
827
|
+
* FALSE-POSITIVE GUARD: prose never starts a line with the `⎿` glyph nor with
|
|
828
|
+
* `API Error:`. But TOOL results (Bash/Read/Grep output) ARE rendered by the TUI
|
|
829
|
+
* under a `⎿` marker, so a result row that QUOTES an auth phrase deeper in the
|
|
830
|
+
* line (the agent grepping the bot's own logs/source, or a `gh`/`npm` "not
|
|
831
|
+
* logged in" line) would fire case (c) if we matched the phrase anywhere. So (c)
|
|
832
|
+
* — and (d), for the same reason — anchor the phrase to the row START: a real
|
|
833
|
+
* error row leads with it; a quote embeds it after other text (live 2026-07-03).
|
|
834
|
+
* The returned line is fed VERBATIM to
|
|
835
|
+
* {@link classifyAgentApiError}. Exported for unit testing without a live tmux
|
|
836
|
+
* pane.
|
|
837
|
+
*/
|
|
838
|
+
export declare function getClaudeAgentErrorLine(content: string): string | null;
|
|
839
|
+
/**
|
|
840
|
+
* @description Whether a captured pane shows the Claude TUI has finished
|
|
841
|
+
* booting and is ready to accept a typed slash command (S7 readiness signal).
|
|
842
|
+
*
|
|
843
|
+
* Ready means: the live input box `❯` is on screen AND no boot-time lifecycle
|
|
844
|
+
* gate is still up — neither the "Press Enter to continue" / login gate nor the
|
|
845
|
+
* bypass-permissions warning, both of which `handleAutoLifecycle` dismisses
|
|
846
|
+
* over the next polls. We do NOT require idle: a fresh spawn is idle, and
|
|
847
|
+
* gating on "not busy" would only delay the re-apply past the box first
|
|
848
|
+
* appearing. Keeping the predicate to "input box up, no lifecycle gate" matches
|
|
849
|
+
* the single observable moment the box first accepts keys. Exported for unit
|
|
850
|
+
* testing without a live tmux pane.
|
|
851
|
+
*/
|
|
852
|
+
export declare function checkIsClaudePromptReady(paneText: string): boolean;
|
|
853
|
+
/**
|
|
854
|
+
* @description Pure decision for the seen-watermark advance: persist the
|
|
855
|
+
* transcript's current EOF as "relayed live up to here" whenever the input box
|
|
856
|
+
* is ready AND the file grew past the last persisted offset — busy or idle.
|
|
857
|
+
*
|
|
858
|
+
* S7 dropped the old `!isBusy` gate. A live Claude adapter relays the pane on
|
|
859
|
+
* EVERY poll, so EOF-on-growth already means "shown up to here" mid-turn, not
|
|
860
|
+
* only at turn end; the old idle-only advance left the watermark at the previous
|
|
861
|
+
* turn end all through a multi-message turn, so a mid-turn restart re-counted
|
|
862
|
+
* every already-relayed message as a false "missed N" (live 2026-07-04). The
|
|
863
|
+
* `isReady` gate stays (don't advance before the box is up / while a boot or
|
|
864
|
+
* lifecycle gate is on screen — that isn't a settled relay), and the growth
|
|
865
|
+
* guard (`eof > lastOffset`) stays so idle metadata rewrites cost no write and a
|
|
866
|
+
* smaller rewrite never rewinds the monotonic anchor. `isBusy` is accepted so
|
|
867
|
+
* the caller passes the poll's busy flag and the truth table documents that busy
|
|
868
|
+
* no longer blocks; it is intentionally unread.
|
|
869
|
+
*
|
|
870
|
+
* Exported so the truth table is unit-testable without a live tmux;
|
|
871
|
+
* {@link ClaudeCliAdapter.advanceClaudeWatermarkIfGrown} is the thin fs+writer
|
|
872
|
+
* wrapper. Callers pass `lastOffset = session.lastWatermarkOffset ?? -1` so a
|
|
873
|
+
* never-advanced session writes on its first ready poll.
|
|
874
|
+
*/
|
|
875
|
+
export declare function checkShouldAdvanceWatermark(args: {
|
|
876
|
+
isBusy: boolean;
|
|
877
|
+
isReady: boolean;
|
|
878
|
+
eof: number;
|
|
879
|
+
lastOffset: number;
|
|
880
|
+
}): boolean;
|
|
881
|
+
/**
|
|
882
|
+
* @description Whether Claude is doing work that must NOT be interrupted: a
|
|
883
|
+
* running sub-agent (Escape would kill the child) or an in-flight compaction
|
|
884
|
+
* (Escape would abort it and lose the summary). In these states the caller
|
|
885
|
+
* forwards the prompt without Escape so it queues behind the current turn and
|
|
886
|
+
* runs once the work finishes. Exported for unit testing without a live tmux.
|
|
887
|
+
*/
|
|
888
|
+
export declare function checkIsClaudeUninterruptible(paneText: string): boolean;
|
|
889
|
+
export { getNewPaneContent, type NewPaneContent };
|
|
890
|
+
/**
|
|
891
|
+
* @description Input snapshot of one resume-seeding poll, fed to
|
|
892
|
+
* {@link getResumeSeedDecision}.
|
|
893
|
+
*/
|
|
894
|
+
export interface ResumeSeedState {
|
|
895
|
+
/** Cleaned pane content captured on THIS poll. */
|
|
896
|
+
content: string;
|
|
897
|
+
/** Cleaned pane content captured on the PREVIOUS poll (empty before the first). */
|
|
898
|
+
prevContent: string;
|
|
899
|
+
/** Number of polls already spent in seeding mode (0 on the first seeding poll). */
|
|
900
|
+
polls: number;
|
|
901
|
+
}
|
|
902
|
+
/**
|
|
903
|
+
* @description Decide whether to stay in resume flood-suppression mode or exit.
|
|
904
|
+
*
|
|
905
|
+
* While `keepSeeding` is true, `pollOutput` advances the baseline but emits no
|
|
906
|
+
* conversation text, so the entire restored transcript Claude repaints on
|
|
907
|
+
* `--resume` is swallowed instead of dumped into the topic. We exit (and let
|
|
908
|
+
* the NEXT poll's diff be genuine new output) when either:
|
|
909
|
+
*
|
|
910
|
+
* - the pane is non-empty AND unchanged across two consecutive polls (the
|
|
911
|
+
* restored transcript finished painting — the common case), or
|
|
912
|
+
* - the hard cap {@link resumeSeedMaxPolls} is hit (paint stuttered forever;
|
|
913
|
+
* force-exit so a session can never be wedged into permanent silence).
|
|
914
|
+
*
|
|
915
|
+
* Pure + exported so the swallow → exit-on-stable → emit-new transition is
|
|
916
|
+
* unit-testable without a live tmux pane.
|
|
917
|
+
*/
|
|
918
|
+
export declare function getResumeSeedDecision(state: ResumeSeedState): {
|
|
919
|
+
keepSeeding: boolean;
|
|
920
|
+
};
|
|
921
|
+
export declare class ClaudeCliAdapter extends EventEmitter implements AgentAdapter {
|
|
922
|
+
readonly name = "claude";
|
|
923
|
+
readonly label = "Claude Code";
|
|
924
|
+
readonly outputsDeltas = true;
|
|
925
|
+
readonly selfGreetsOnStart = true;
|
|
926
|
+
/**
|
|
927
|
+
* Map of serialised `SessionKey` (`"<chatId>:<threadId>"`) → live session.
|
|
928
|
+
* Keyed by string rather than `SessionKey` object so map lookups work — JS
|
|
929
|
+
* Map compares object identity, not structural equality.
|
|
930
|
+
*/
|
|
931
|
+
private sessions;
|
|
932
|
+
/**
|
|
933
|
+
* Per-thread display-prefs reader, injected by the bot at boot via
|
|
934
|
+
* `createAdapter.registerDisplayPrefsReader` (S4; same idiom as the OpenCode
|
|
935
|
+
* adapter). Consulted on the poll hot path: the relay branches each chunk's
|
|
936
|
+
* tool / panel segments on `toolResults` (S4), and the transcript scan
|
|
937
|
+
* fast-forwards (non-`full` `subagent`) or streams (`full`). `null` until
|
|
938
|
+
* wired → reads fall back to all-fields-`minimal`.
|
|
939
|
+
*/
|
|
940
|
+
private displayPrefsReader;
|
|
941
|
+
private claudeConfigDirReader;
|
|
942
|
+
setClaudeConfigDirReader(reader: ClaudeConfigDirReader): void;
|
|
943
|
+
/** The config directory the conversation's next pane must start with (its account profile). */
|
|
944
|
+
private resolveConfigDir;
|
|
945
|
+
/** The `CLAUDE_CONFIG_DIR` the live pane runs with (`null` = default profile); `undefined` without a live session. */
|
|
946
|
+
getSessionClaudeConfigDir(key: SessionKey): string | null | undefined;
|
|
947
|
+
/** @description Inject the per-thread display-prefs reader (see the field's JSDoc). */
|
|
948
|
+
setDisplayPrefsReader(reader: DisplayPrefsReader): void;
|
|
949
|
+
/** Per-thread locale reader, injected at boot via `createAdapter.registerThreadLocaleReader`. */
|
|
950
|
+
private threadLocaleReader;
|
|
951
|
+
/** @description Inject the per-thread locale reader (for adapter-side `t(...)` calls). */
|
|
952
|
+
setThreadLocaleReader(reader: ThreadLocaleReader): void;
|
|
953
|
+
/** @description Run `fn` inside the thread's locale context so `t(...)` resolves correctly. */
|
|
954
|
+
private tl;
|
|
955
|
+
/**
|
|
956
|
+
* Per-thread seen-watermark writer, injected by the bot at boot via
|
|
957
|
+
* `createAdapter.registerSeenWatermarkWriter`. Called on every idle+ready poll
|
|
958
|
+
* whose transcript EOF grew past the last persisted offset (via
|
|
959
|
+
* {@link ClaudeCliAdapter.advanceClaudeWatermarkIfGrown}) to persist the new
|
|
960
|
+
* EOF. `null` until wired → {@link advanceSeenWatermark} is a no-op.
|
|
961
|
+
*/
|
|
962
|
+
private seenWatermarkWriter;
|
|
963
|
+
/** @description Inject the per-thread seen-watermark writer (see the field's JSDoc). */
|
|
964
|
+
setSeenWatermarkWriter(writer: SeenWatermarkWriter): void;
|
|
965
|
+
/** @description Advance the persisted seen-watermark for `key` (no-op until the
|
|
966
|
+
* writer is wired). */
|
|
967
|
+
private advanceSeenWatermark;
|
|
968
|
+
/**
|
|
969
|
+
* @description Advance the seen-watermark to the transcript's current EOF when
|
|
970
|
+
* the input box is ready and the file grew since the last write (S7) — the
|
|
971
|
+
* fs+writer wrapper around {@link checkShouldAdvanceWatermark}. Called every
|
|
972
|
+
* non-seeding poll with the poll's `isBusy` / `isReady`; it early-returns only
|
|
973
|
+
* on a NOT-ready poll BEFORE the `fs.stat` (a boot / lifecycle-gate frame isn't
|
|
974
|
+
* a settled relay). S7 dropped the busy early-return so a BUSY-but-ready poll
|
|
975
|
+
* mid-turn advances too — the pane is relayed every poll, so tracking EOF as it
|
|
976
|
+
* grows keeps the watermark at "relayed up to here" instead of stranding it at
|
|
977
|
+
* the previous turn end (the mid-turn false-"missed N" fix). It still writes
|
|
978
|
+
* only when EOF actually grew — so idle metadata churn (Claude rewrites
|
|
979
|
+
* `last-prompt`/`mode`/… for hours) costs no more than one bounded write per
|
|
980
|
+
* real growth, and a smaller rewrite never rewinds the in-memory anchor
|
|
981
|
+
* (monotonic). Best-effort — a transcript not yet on disk (UUID just born)
|
|
982
|
+
* leaves the watermark where it was, the next poll re-tries. The path resolves
|
|
983
|
+
* the same way {@link getRecentTurns} / {@link getReattachRecap} do.
|
|
984
|
+
*/
|
|
985
|
+
private advanceClaudeWatermarkIfGrown;
|
|
986
|
+
/** @description Resolve the thread's full display prefs, defaulting every
|
|
987
|
+
* field to `minimal` for any read before the bot wires the reader at boot. */
|
|
988
|
+
private getDisplayPrefs;
|
|
989
|
+
/** @description Resolve the thread's `/subagent` mode (consulted by the
|
|
990
|
+
* transcript-tail scan), via the full prefs reader. */
|
|
991
|
+
private getSubagentMode;
|
|
992
|
+
private createSession;
|
|
993
|
+
private enqueueTmux;
|
|
994
|
+
private enqueueTmuxBestEffort;
|
|
995
|
+
private stopSessionInternal;
|
|
996
|
+
/**
|
|
997
|
+
* @description Schedule the next `pollOutput` for a session. Audit S9 /
|
|
998
|
+
* #37: replaces `setInterval` so a slow `tmux capture-pane` cannot
|
|
999
|
+
* cause overlapping invocations. The handle is stored back on
|
|
1000
|
+
* `session.pollTimer` so `stopSession` can cancel the next tick.
|
|
1001
|
+
*/
|
|
1002
|
+
private schedulePoll;
|
|
1003
|
+
/**
|
|
1004
|
+
* @description Per-poll-tick scan of the session's on-disk sub-agent
|
|
1005
|
+
* transcripts (`/subagent` on Claude, plan 2026-06-11 S3). Claude writes
|
|
1006
|
+
* each Task-tool child transcript to
|
|
1007
|
+
* `<projectsRoot>/<slug>/<claudeSessionId>/subagents/agent-<agentId>.jsonl`;
|
|
1008
|
+
* the pure `claudeSubagentTail` helpers own all decisions — first-scan EOF
|
|
1009
|
+
* seeding (no backlog replay on resume/adopt), compact-mode fast-forward
|
|
1010
|
+
* without reading, and assistant-text-block extraction (child thinking /
|
|
1011
|
+
* tool_use never rendered). In `full` mode every appended text block is
|
|
1012
|
+
* emitted as a marked output (`meta.isSubagent`) which the bot renders as a
|
|
1013
|
+
* standalone "🤖 ⤷" message outside the parent's continuation chain.
|
|
1014
|
+
*
|
|
1015
|
+
* A missing dir (`ENOENT` — no sub-agent yet, or an older claude version)
|
|
1016
|
+
* short-circuits cheaply but still runs the empty scan, so the first-scan
|
|
1017
|
+
* flag flips and a transcript created later streams from byte 0. Any other
|
|
1018
|
+
* error is logged and swallowed here — this method must never reject, or
|
|
1019
|
+
* the rejection would escape `schedulePoll`'s void'd poll chain.
|
|
1020
|
+
*/
|
|
1021
|
+
private scanSubagentTranscripts;
|
|
1022
|
+
/**
|
|
1023
|
+
* @description Snap a session's poll cadence back to base (S2). Called on
|
|
1024
|
+
* every explicit write (keystroke / signal) and on session start/resume so a
|
|
1025
|
+
* fresh prompt never waits up to {@link maxPollIntervalMs} for the next
|
|
1026
|
+
* capture — user-visible latency after a write must stay at base cadence.
|
|
1027
|
+
*
|
|
1028
|
+
* If a poll timer is already pending we re-arm it at the base delay so the
|
|
1029
|
+
* backed-off idle timer can't keep the next capture far in the future. The
|
|
1030
|
+
* existing {@link ClaudeSession.isPolling} guard is respected: a poll already
|
|
1031
|
+
* in flight will reschedule itself from the (now reset) delay, so we never
|
|
1032
|
+
* double-poll.
|
|
1033
|
+
*/
|
|
1034
|
+
private resetPollCadence;
|
|
1035
|
+
startSession(key: SessionKey, workDir: string, args?: string, sessionId?: string): Promise<void>;
|
|
1036
|
+
stopSession(key: SessionKey): void;
|
|
1037
|
+
checkIsActive(key: SessionKey): boolean;
|
|
1038
|
+
checkIsBusy(key: SessionKey): boolean;
|
|
1039
|
+
getRuntimeInfo(key: SessionKey): Promise<AgentRuntimeInfo>;
|
|
1040
|
+
/**
|
|
1041
|
+
* @description Ms since the TUI pane last actually changed (raw `capture-pane`
|
|
1042
|
+
* differed), or `null` when there is no live session for this thread. Feeds
|
|
1043
|
+
* the bot's S2 pane-static idle net: a genuinely working agent repaints the
|
|
1044
|
+
* pane every second, so a large value means the agent is idle even if the
|
|
1045
|
+
* footer busy signal is stuck. `null` is never treated as idle.
|
|
1046
|
+
*/
|
|
1047
|
+
getMsSincePaneChange(key: SessionKey): number | null;
|
|
1048
|
+
sendInput(key: SessionKey, input: string, options?: SendInputOptions): void;
|
|
1049
|
+
/**
|
|
1050
|
+
* @description Post-Enter verification for a plain prompt (B5). After a short
|
|
1051
|
+
* settle, capture the pane through the session queue and — if the prompt still
|
|
1052
|
+
* looks unsubmitted (see {@link checkLooksUnsubmitted}) — re-send Enter exactly
|
|
1053
|
+
* ONCE. No further retries: a duplicate Enter on an already-submitted prompt is
|
|
1054
|
+
* a harmless no-op, but an unbounded retry loop on a genuinely-stuck pane would
|
|
1055
|
+
* spam keystrokes. Same staleness guards as the deferred Enter.
|
|
1056
|
+
*/
|
|
1057
|
+
private scheduleEnterVerification;
|
|
1058
|
+
sendSignal(key: SessionKey, signal: string): void;
|
|
1059
|
+
sendEnter(key: SessionKey): void;
|
|
1060
|
+
sendArrow(key: SessionKey, direction: 'Up' | 'Down'): void;
|
|
1061
|
+
sendTab(key: SessionKey): void;
|
|
1062
|
+
/**
|
|
1063
|
+
* @description S4: auto-dismiss the native Claude session-feedback survey by
|
|
1064
|
+
* sending a single Escape into the pane (Escape clears the survey overlay the
|
|
1065
|
+
* same way it dismisses a selector). Fire-and-forget through the session queue,
|
|
1066
|
+
* like {@link sendEscape}; the caller's {@link checkShouldDismissSurvey}
|
|
1067
|
+
* signature dedup guarantees it fires once per appearance. Never surfaced to
|
|
1068
|
+
* the topic — the survey must not occupy input / disrupt the scrape.
|
|
1069
|
+
*/
|
|
1070
|
+
private dismissClaudeSurvey;
|
|
1071
|
+
sendEscape(key: SessionKey): void;
|
|
1072
|
+
/**
|
|
1073
|
+
* @description Interrupt the current turn, then wait until Claude is
|
|
1074
|
+
* actually idle before resolving, so the caller can type a fresh prompt
|
|
1075
|
+
* without it being queued behind the running turn.
|
|
1076
|
+
*
|
|
1077
|
+
* Sends a single Escape — which both cancels an on-screen selector AND
|
|
1078
|
+
* breaks Claude out of the "busy" state — then polls the pane footer until
|
|
1079
|
+
* the `esc to interrupt` hint clears. A fixed post-Escape delay was
|
|
1080
|
+
* unreliable: heavy extended-thinking turns take longer than the old 120 ms
|
|
1081
|
+
* to tear down, so the prompt landed while Claude was still busy and got
|
|
1082
|
+
* queued (the "voice message arrives before the interrupt, then the agent
|
|
1083
|
+
* waits" bug). On timeout we forward anyway rather than drop the message.
|
|
1084
|
+
*
|
|
1085
|
+
* Exception: if Claude is running a sub-agent or compacting context, we do
|
|
1086
|
+
* NOT interrupt — Escape would kill the child / abort the compaction. We
|
|
1087
|
+
* return without Escape so the caller's prompt queues behind the current
|
|
1088
|
+
* turn and runs once that work finishes.
|
|
1089
|
+
*/
|
|
1090
|
+
interruptAndWaitIdle(key: SessionKey): Promise<void>;
|
|
1091
|
+
/**
|
|
1092
|
+
* @description Whether a selector is currently on screen. Backed by the same
|
|
1093
|
+
* `lastQuestionSignature` the output pump sets when it scrapes a question
|
|
1094
|
+
* block (see the `extractClaudeQuestion` call in the poll loop) — non-empty
|
|
1095
|
+
* means a question is being shown and awaiting an answer.
|
|
1096
|
+
*/
|
|
1097
|
+
isQuestionPending(key: SessionKey): boolean;
|
|
1098
|
+
/**
|
|
1099
|
+
* @description Whether Claude's `/login` OAuth "paste the code" box is on
|
|
1100
|
+
* screen right now, read live off the last captured pane ({@link checkIsClaudeLoginPaste}).
|
|
1101
|
+
* No signature/de-dup is needed — nothing is emitted; this only answers
|
|
1102
|
+
* "should the next text reply be typed verbatim into the paste box?" when a
|
|
1103
|
+
* message arrives, so the bot skips the prompt path (Escape + preamble) that
|
|
1104
|
+
* would otherwise cancel the login and corrupt the code.
|
|
1105
|
+
*/
|
|
1106
|
+
isLoginPastePending(key: SessionKey): boolean;
|
|
1107
|
+
/**
|
|
1108
|
+
* @description For Claude CLI, model switching is done via the /model slash command.
|
|
1109
|
+
* Sends "/model <modelId>" as input to the tmux session. Returns `null`
|
|
1110
|
+
* on success (best-effort: claude doesn't ack the change synchronously).
|
|
1111
|
+
* Audit S10 / #39: unified signature with OpenCode adapter.
|
|
1112
|
+
*
|
|
1113
|
+
* Unlike OpenCode, Claude has NO model-pref persistence — model switching is
|
|
1114
|
+
* a TUI keystroke with no on-disk pref to replay at next start. So with no
|
|
1115
|
+
* active session there is nothing to do but refuse, otherwise `sendInput`
|
|
1116
|
+
* silently no-ops and the caller would report a false "model set" success
|
|
1117
|
+
* (reachable today via the ungated numeric-pick path).
|
|
1118
|
+
*/
|
|
1119
|
+
setModel(key: SessionKey, modelId: string): Promise<string | null>;
|
|
1120
|
+
getCurrentModel(_key: SessionKey): string | null;
|
|
1121
|
+
/**
|
|
1122
|
+
* @description Set the reasoning effort for this thread by typing claude's
|
|
1123
|
+
* native `/effort <level>` slash command into the running TUI.
|
|
1124
|
+
*
|
|
1125
|
+
* Plan 2026-05-30-effort-command / S3, D2/D6:
|
|
1126
|
+
*
|
|
1127
|
+
* - **Validation** is against the canonical Claude set (`getClaudeAvailableLevels`),
|
|
1128
|
+
* not per-model: the adapter can't read claude's live model after a
|
|
1129
|
+
* `/model` switch (`getCurrentModel` returns `null`), so we trust claude
|
|
1130
|
+
* to clamp an unsupported level for the actual model down to its nearest
|
|
1131
|
+
* supported one. Caller already filtered against the same canonical list
|
|
1132
|
+
* when building the picker.
|
|
1133
|
+
* - **Apply** is best-effort via {@link sendInput} (the keystroke path used
|
|
1134
|
+
* by `setModel`). Returns `null` immediately — claude's TUI doesn't
|
|
1135
|
+
* acknowledge the change synchronously and we don't poll-and-wait for it.
|
|
1136
|
+
* - **Persist** to the per-thread prefs file so the banner / `/effort`
|
|
1137
|
+
* picker survives a bot restart (claude's own settings.json is global).
|
|
1138
|
+
*
|
|
1139
|
+
* Returns a short notice instead of `null` when the session isn't running
|
|
1140
|
+
* (we still persist the choice so the next /claude picks it up in the
|
|
1141
|
+
* banner; live apply happens once the agent actually exists).
|
|
1142
|
+
*/
|
|
1143
|
+
setEffort(key: SessionKey, level: string): Promise<string | null>;
|
|
1144
|
+
/**
|
|
1145
|
+
* @description Last bot-set effort for this thread, or `null` if none.
|
|
1146
|
+
*
|
|
1147
|
+
* Reads from the on-disk prefs file (not an in-memory cache): the file is
|
|
1148
|
+
* tiny and the read happens only on menu / banner refresh paths, so a
|
|
1149
|
+
* cache would just be drift surface. Whatever claude itself stores in
|
|
1150
|
+
* its global `settings.json` is invisible to us by design (D2).
|
|
1151
|
+
*/
|
|
1152
|
+
getEffort(key: SessionKey): string | null;
|
|
1153
|
+
/**
|
|
1154
|
+
* @description ARM the thread's stored `/effort` choice for re-apply on a
|
|
1155
|
+
* FRESH TUI spawn (S7) — deferred, not typed immediately. claude persists
|
|
1156
|
+
* effort GLOBALLY in its own settings.json, so a fresh `startSession` /
|
|
1157
|
+
* `resumeSession` would otherwise inherit the last globally-set level —
|
|
1158
|
+
* possibly chosen in another topic.
|
|
1159
|
+
*
|
|
1160
|
+
* Timing is the whole point: a fresh tmux session returns the instant
|
|
1161
|
+
* `new-session` succeeds, while the claude TUI is still painting its boot
|
|
1162
|
+
* banner — typing into it then interleaves keystrokes with the paint and the
|
|
1163
|
+
* command sits unsubmitted (live bug 2026-06-05). So we do NOT type here; we
|
|
1164
|
+
* stash the level on `session.pendingEffortReapply` and let the poll loop
|
|
1165
|
+
* consume it the FIRST time the pane shows a ready input box
|
|
1166
|
+
* ({@link checkIsClaudePromptReady}). That readiness moment is strictly after
|
|
1167
|
+
* the banner paints and strictly before the box can echo a buffered prompt,
|
|
1168
|
+
* giving the required ordering (effort BEFORE buffered prompts) via the same
|
|
1169
|
+
* serial tmux queue.
|
|
1170
|
+
*
|
|
1171
|
+
* Called at the END of `startSession` / `resumeSession`. NOT called from
|
|
1172
|
+
* `adoptExistingTmuxSession` — that claude process survived the restart with
|
|
1173
|
+
* its in-TUI effort intact and may be mid-turn, so re-applying would be both
|
|
1174
|
+
* unnecessary and risk interleaving with a running stream.
|
|
1175
|
+
*
|
|
1176
|
+
* No stored pref → the bot's default (`defaultEffortLevel` = xhigh) is armed
|
|
1177
|
+
* instead of claude's own default, so a no-pref spawn types `/effort xhigh`
|
|
1178
|
+
* (claude clamps per model — same as a manual `/effort` or an explicit pref).
|
|
1179
|
+
* An explicit per-thread pref still wins and is armed verbatim.
|
|
1180
|
+
*/
|
|
1181
|
+
private applyStoredEffortOnSpawn;
|
|
1182
|
+
/**
|
|
1183
|
+
* @description S7 consumption point: once the poll loop sees the TUI input
|
|
1184
|
+
* box is up and no boot gate is left, type the armed `/effort <level>` ONCE
|
|
1185
|
+
* and clear the pending flag (one-shot, can't fire twice). Reuses the exact
|
|
1186
|
+
* keystroke path a manual `/effort` uses ({@link sendInput} with its
|
|
1187
|
+
* bare-slash deferred-Enter handling) so there is no duplicate keystroke
|
|
1188
|
+
* logic. Enqueuing onto the session's serial tmux queue at this ready moment
|
|
1189
|
+
* guarantees the keystroke lands in a usable input box (not the boot paint)
|
|
1190
|
+
* and ahead of any buffered prompt the bot replays onto the same queue.
|
|
1191
|
+
*/
|
|
1192
|
+
private consumePendingEffortReapply;
|
|
1193
|
+
/**
|
|
1194
|
+
* @description Effort levels offered by the `/effort` picker for Claude.
|
|
1195
|
+
*
|
|
1196
|
+
* Returns the canonical set unconditionally (plan D2). The `key` argument
|
|
1197
|
+
* is accepted for interface symmetry with OpenCode (whose set depends on
|
|
1198
|
+
* the per-thread current model) but is intentionally unused here.
|
|
1199
|
+
*/
|
|
1200
|
+
getAvailableEffortLevels(_key: SessionKey): Promise<string[]>;
|
|
1201
|
+
getFullOutput(key: SessionKey, lines?: number): string | null;
|
|
1202
|
+
/**
|
|
1203
|
+
* @description Expose the Claude `--session-id` UUID for a live session.
|
|
1204
|
+
* The bot calls this right after `startSession()` so the UUID can be
|
|
1205
|
+
* persisted in state.json and reused on later resumes (plan §13.1, D14).
|
|
1206
|
+
*/
|
|
1207
|
+
getClaudeSessionId(key: SessionKey): string | null;
|
|
1208
|
+
getSessions(_key: SessionKey, workDir: string): Promise<AgentSession[]>;
|
|
1209
|
+
/**
|
|
1210
|
+
* @description Read the last `limit` conversational turns of a resumable
|
|
1211
|
+
* Claude session for the resume context block. Resolves the same
|
|
1212
|
+
* `~/.claude/projects/<slug>/<sessionId>.jsonl` path the session listing uses
|
|
1213
|
+
* (`key` is unused — Claude scopes transcripts by folder, not by thread) and
|
|
1214
|
+
* delegates to the pure {@link readRecentClaudeTurns}. A missing transcript
|
|
1215
|
+
* (unknown / pruned UUID) yields `[]`, so the caller posts no context block.
|
|
1216
|
+
*/
|
|
1217
|
+
getRecentTurns(_key: SessionKey, workDir: string, sessionId: string, limit: number): Promise<RecentTurn[]>;
|
|
1218
|
+
/**
|
|
1219
|
+
* @description Assemble the silent-reattach recap for Claude from the on-disk
|
|
1220
|
+
* transcript via ONE {@link readClaudeReattachTranscript} read: the
|
|
1221
|
+
* missed-message count is the assistant turns appended after the watermark
|
|
1222
|
+
* byte offset, the body is the last {@link resumeContextTurnLimit} turns, and
|
|
1223
|
+
* `isActive` is the best-effort in-memory busy flag (the just-adopted session
|
|
1224
|
+
* seeds `lastContent` from the current pane, so an `esc to interrupt` footer
|
|
1225
|
+
* reads as still-working). The offset is trusted only when the watermark's
|
|
1226
|
+
* `sessionId` matches the session being recapped — a stale watermark from a
|
|
1227
|
+
* different session (`/new`, `/sessions` resume keep the agent row) is treated
|
|
1228
|
+
* as unknown. A `null`/mismatched/offset-less watermark yields
|
|
1229
|
+
* `isWatermarkKnown: false` and `missedCount: 0` (the fallback recap), while
|
|
1230
|
+
* the body still shows the last turns.
|
|
1231
|
+
*/
|
|
1232
|
+
getReattachRecap(key: SessionKey, workDir: string, sessionId: string, watermark: SeenWatermark | null): Promise<ReattachRecap>;
|
|
1233
|
+
/**
|
|
1234
|
+
* @description Resume a Claude session by UUID.
|
|
1235
|
+
*
|
|
1236
|
+
* Two fixes vs. the legacy implementation:
|
|
1237
|
+
*
|
|
1238
|
+
* 1. **Required `workDir`.** The old `resumeSession` fell back to
|
|
1239
|
+
* `process.env.WORK_DIR || '/workspace'`, which is wrong as soon as the
|
|
1240
|
+
* bot manages multiple folders. The bot now passes the correct workDir
|
|
1241
|
+
* from the thread binding.
|
|
1242
|
+
*
|
|
1243
|
+
* 2. **Use `--resume <uuid>` instead of `--resume` with no argument.** The
|
|
1244
|
+
* no-arg form opens an interactive picker that can't be driven from a
|
|
1245
|
+
* headless tmux pane, which manifested as a silent hang (see plan
|
|
1246
|
+
* §13.1, fix to claudeCliAdapter.ts:455). If Claude can't find the UUID
|
|
1247
|
+
* (history pruned, different machine), it just starts a new session;
|
|
1248
|
+
* we surface that to the user (T8 in plan §16.3).
|
|
1249
|
+
*/
|
|
1250
|
+
resumeSession(key: SessionKey, workDir: string, sessionId: string, options?: ResumeSessionOptions): Promise<void>;
|
|
1251
|
+
/**
|
|
1252
|
+
* @description Pick up tmux sessions that outlived the bot process.
|
|
1253
|
+
*
|
|
1254
|
+
* Called by `bot.ts` on startup, BEFORE `bot.launch()`. Scans
|
|
1255
|
+
* `tmux list-sessions` for names matching our `claude-<chatId>-<threadId>`
|
|
1256
|
+
* convention. For each match, returns the parsed key + tmux session name —
|
|
1257
|
+
* the bot then decides which ones to re-adopt (must have a live binding in
|
|
1258
|
+
* state.json) and which are orphans to garbage-collect (plan §10.2 / §13.19, E1).
|
|
1259
|
+
*
|
|
1260
|
+
* This method does NOT itself adopt sessions: it has no knowledge of state.json
|
|
1261
|
+
* or which sessions are still bound. The actual re-attach is done by the bot
|
|
1262
|
+
* calling {@link adoptExistingTmuxSession} for each key it wants to keep.
|
|
1263
|
+
*
|
|
1264
|
+
* Returns an empty array if tmux isn't installed or no matching sessions exist.
|
|
1265
|
+
*/
|
|
1266
|
+
listExistingTmuxSessions(): Promise<Array<{
|
|
1267
|
+
key: SessionKey;
|
|
1268
|
+
sessionName: string;
|
|
1269
|
+
}>>;
|
|
1270
|
+
/**
|
|
1271
|
+
* @description Recover the `--session-id <uuid>` flag from a live tmux
|
|
1272
|
+
* session's start command.
|
|
1273
|
+
*
|
|
1274
|
+
* Used by the bot's reattach loop to reconcile state with reality when
|
|
1275
|
+
* `state.agents[key]` is missing a `claudeSessionId` (or names a
|
|
1276
|
+
* different adapter) but a `claude-<chatId>-<threadId>` tmux session is
|
|
1277
|
+
* still running. Previously such cases were treated as orphans and the
|
|
1278
|
+
* tmux session was killed, throwing away the user's live work.
|
|
1279
|
+
*
|
|
1280
|
+
* Implementation: read `pane_start_command` for the session's first
|
|
1281
|
+
* pane and parse the UUID out via {@link parseClaudeSessionIdFromCommand}.
|
|
1282
|
+
* `pane_start_command` survives across restarts because tmux keeps the
|
|
1283
|
+
* original command line for the pane.
|
|
1284
|
+
*
|
|
1285
|
+
* Returns `null` if no UUID can be recovered (caller falls back to
|
|
1286
|
+
* killing the session as an orphan).
|
|
1287
|
+
*/
|
|
1288
|
+
recoverSessionIdFromTmux(sessionName: string): Promise<string | null>;
|
|
1289
|
+
/**
|
|
1290
|
+
* @description Adopt a tmux session that survived a bot restart.
|
|
1291
|
+
*
|
|
1292
|
+
* The bot calls this after `listExistingTmuxSessions()` for each
|
|
1293
|
+
* `(key, sessionName)` pair it wants to keep alive. Restores the in-memory
|
|
1294
|
+
* `ClaudeSession` and resumes polling so output flows back to Telegram.
|
|
1295
|
+
*
|
|
1296
|
+
* `workDir` and `claudeSessionId` come from state.json (the bot keeps a
|
|
1297
|
+
* binding `(key → subdir, claudeSessionId)`). If we ever lose them, the
|
|
1298
|
+
* caller should kill the tmux session as an orphan instead.
|
|
1299
|
+
*
|
|
1300
|
+
* Returns `true` on success, `false` if the tmux session disappeared between
|
|
1301
|
+
* the `list` call and now (race with manual `tmux kill-session`).
|
|
1302
|
+
*/
|
|
1303
|
+
adoptExistingTmuxSession(key: SessionKey, sessionName: string, workDir: string, claudeSessionId: string): Promise<boolean>;
|
|
1304
|
+
/**
|
|
1305
|
+
* @description Kill a tmux session by name without touching adapter state.
|
|
1306
|
+
*
|
|
1307
|
+
* The bot uses this on startup to garbage-collect orphan tmux sessions
|
|
1308
|
+
* (`claude-<chatId>-<threadId>` names with no corresponding binding in
|
|
1309
|
+
* state.json). See plan §10.2 / §13.19.
|
|
1310
|
+
*/
|
|
1311
|
+
killOrphanTmuxSession(sessionName: string): Promise<void>;
|
|
1312
|
+
static parseTmuxSessionName: typeof parseTmuxSessionName;
|
|
1313
|
+
static buildTmuxSessionName: typeof buildTmuxSessionName;
|
|
1314
|
+
private probeSessionAlive;
|
|
1315
|
+
private pollOutput;
|
|
1316
|
+
/**
|
|
1317
|
+
* @description Emit a settled streaming table (S1) as ONE fenced `output`.
|
|
1318
|
+
*
|
|
1319
|
+
* Routes the held block through the SAME fence path as the inline table path
|
|
1320
|
+
* ({@link stripTuiElementsWithContext} fences a sharp-corner table) so the
|
|
1321
|
+
* `<pre>` rendering is byte-identical to today — only the TIMING/dedup change.
|
|
1322
|
+
* Records the raw block in {@link RecentRelayWindow} in the PANE-line domain
|
|
1323
|
+
* (pre-strip) so a later full repaint of the same table is suppressed by the
|
|
1324
|
+
* existing re-render dedup, exactly like the normal permanent-output path.
|
|
1325
|
+
* Emitted with `startsNewParagraph: true` — a table is its own visual block,
|
|
1326
|
+
* so it must not glue onto preceding prose in the append/draft join.
|
|
1327
|
+
*/
|
|
1328
|
+
private emitStabilizedTable;
|
|
1329
|
+
/**
|
|
1330
|
+
* @description Auto-handle the two lifecycle prompts Claude can show — the
|
|
1331
|
+
* "Press Enter to continue" gate and the bypass-permissions warning — by
|
|
1332
|
+
* issuing the matching keystrokes. Extracted from {@link pollOutput} so the
|
|
1333
|
+
* resume-seeding path (which suppresses conversation TEXT) can still drive
|
|
1334
|
+
* these prompts; suppression must hide chatter, not the lifecycle.
|
|
1335
|
+
*
|
|
1336
|
+
* Also the detection seam for a terminal provider error / logged-out row
|
|
1337
|
+
* ({@link getClaudeAgentErrorLine}: `API Error: …`, `⎿ … · API Error: …`, or
|
|
1338
|
+
* `⎿ … Please run /login`): when it first classifies, emit one `apiError`
|
|
1339
|
+
* event — the trigger for the auto-retry (transient / usageLimit) OR the
|
|
1340
|
+
* surfaced logged-out notice (auth). Detection scans the NEW pane delta only
|
|
1341
|
+
* (never the full pane / arbitrary conversation text), so a recognized error
|
|
1342
|
+
* row fires exactly once — when it first renders.
|
|
1343
|
+
*
|
|
1344
|
+
* A large new chunk (`newPart.length > 50`) means real conversation moved on,
|
|
1345
|
+
* so the one-shot `handled*` guards are reset to re-arm for a later prompt.
|
|
1346
|
+
*/
|
|
1347
|
+
private handleAutoLifecycle;
|
|
1348
|
+
private checkNeedsAutoEnter;
|
|
1349
|
+
private checkNeedsAutoAccept;
|
|
1350
|
+
}
|
|
1351
|
+
//# sourceMappingURL=claudeCliAdapter.d.ts.map
|