charness 3.6.1 → 3.7.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/CHANGELOG.md +267 -0
- package/DEVELOPMENT.md +31 -5
- package/MIGRATION_RENAME_TO_CHARNESS.md +3 -2
- package/README.md +84 -782
- package/SETUP.md +37 -10
- package/agent-plugin/.claude-plugin/plugin.json +7 -0
- package/agent-plugin/README.md +35 -0
- package/agent-plugin/skills/charness-delegate-claude/SKILL.md +85 -0
- package/agent-plugin/skills/charness-delegate-claude/summarize-events.py +90 -0
- package/agent-plugin/skills/charness-delegate-opencode/SKILL.md +68 -0
- package/agent-plugin/skills/charness-manager/SKILL.md +152 -0
- package/dist/adapters/adapterNames.d.ts +6 -0
- package/dist/adapters/adapterNames.d.ts.map +1 -1
- package/dist/adapters/adapterNames.js +8 -2
- package/dist/adapters/adapterNames.js.map +1 -1
- package/dist/adapters/claudeCliAdapter.d.ts +8 -0
- package/dist/adapters/claudeCliAdapter.d.ts.map +1 -1
- package/dist/adapters/claudeCliAdapter.js +42 -5
- package/dist/adapters/claudeCliAdapter.js.map +1 -1
- package/dist/adapters/claudeJsonStreamAdapter.d.ts +10 -9
- package/dist/adapters/claudeJsonStreamAdapter.d.ts.map +1 -1
- package/dist/adapters/claudeJsonStreamAdapter.js +53 -55
- package/dist/adapters/claudeJsonStreamAdapter.js.map +1 -1
- package/dist/adapters/createAdapter.d.ts +8 -0
- package/dist/adapters/createAdapter.d.ts.map +1 -1
- package/dist/adapters/createAdapter.js +14 -2
- package/dist/adapters/createAdapter.js.map +1 -1
- package/dist/adapters/openCodeAdapter.d.ts +43 -6
- package/dist/adapters/openCodeAdapter.d.ts.map +1 -1
- package/dist/adapters/openCodeAdapter.js +95 -6
- package/dist/adapters/openCodeAdapter.js.map +1 -1
- package/dist/agentLogin/agentLogin.d.ts +1 -1
- package/dist/agentLogin/agentLogin.d.ts.map +1 -1
- package/dist/apiRetryKick.d.ts +4 -3
- package/dist/apiRetryKick.d.ts.map +1 -1
- package/dist/apiRetryKick.js +16 -9
- package/dist/apiRetryKick.js.map +1 -1
- package/dist/bot.d.ts.map +1 -1
- package/dist/bot.js +1313 -381
- package/dist/bot.js.map +1 -1
- package/dist/cli/claudeProfiles.d.ts +11 -6
- package/dist/cli/claudeProfiles.d.ts.map +1 -1
- package/dist/cli/claudeProfiles.js +50 -22
- package/dist/cli/claudeProfiles.js.map +1 -1
- package/dist/cli/hot.d.ts +5 -0
- package/dist/cli/hot.d.ts.map +1 -1
- package/dist/cli/hot.js +71 -25
- package/dist/cli/hot.js.map +1 -1
- package/dist/cli/tscWatchGuard.d.ts +95 -0
- package/dist/cli/tscWatchGuard.d.ts.map +1 -0
- package/dist/cli/tscWatchGuard.js +295 -0
- package/dist/cli/tscWatchGuard.js.map +1 -0
- package/dist/cli.js +12 -1
- package/dist/cli.js.map +1 -1
- package/dist/connectors/jira/answerSink.d.ts +10 -0
- package/dist/connectors/jira/answerSink.d.ts.map +1 -1
- package/dist/connectors/jira/answerSink.js +13 -0
- package/dist/connectors/jira/answerSink.js.map +1 -1
- package/dist/connectors/jira/config.d.ts +2 -0
- package/dist/connectors/jira/config.d.ts.map +1 -1
- package/dist/connectors/jira/config.js +9 -1
- package/dist/connectors/jira/config.js.map +1 -1
- package/dist/connectors/jira/connector.d.ts +11 -1
- package/dist/connectors/jira/connector.d.ts.map +1 -1
- package/dist/connectors/jira/connector.js +7 -0
- package/dist/connectors/jira/connector.js.map +1 -1
- package/dist/connectors/jira/inbound.d.ts +27 -4
- package/dist/connectors/jira/inbound.d.ts.map +1 -1
- package/dist/connectors/jira/inbound.js +69 -8
- package/dist/connectors/jira/inbound.js.map +1 -1
- package/dist/connectors/jira/issueBlocks.d.ts +5 -0
- package/dist/connectors/jira/issueBlocks.d.ts.map +1 -1
- package/dist/connectors/jira/issueBlocks.js +11 -0
- package/dist/connectors/jira/issueBlocks.js.map +1 -1
- package/dist/connectors/telegram/bindPicker.d.ts +5 -0
- package/dist/connectors/telegram/bindPicker.d.ts.map +1 -1
- package/dist/connectors/telegram/bindPicker.js +18 -1
- package/dist/connectors/telegram/bindPicker.js.map +1 -1
- package/dist/connectors/telegram/bindPickerClaims.d.ts +46 -0
- package/dist/connectors/telegram/bindPickerClaims.d.ts.map +1 -0
- package/dist/connectors/telegram/bindPickerClaims.js +83 -0
- package/dist/connectors/telegram/bindPickerClaims.js.map +1 -0
- package/dist/connectors/telegram/bindSweep.d.ts +32 -0
- package/dist/connectors/telegram/bindSweep.d.ts.map +1 -0
- package/dist/connectors/telegram/bindSweep.js +47 -0
- package/dist/connectors/telegram/bindSweep.js.map +1 -0
- package/dist/connectors/telegram/bindingWelcome.d.ts +23 -0
- package/dist/connectors/telegram/bindingWelcome.d.ts.map +1 -0
- package/dist/connectors/telegram/bindingWelcome.js +26 -0
- package/dist/connectors/telegram/bindingWelcome.js.map +1 -0
- package/dist/connectors/telegram/botApiConnection.d.ts +74 -0
- package/dist/connectors/telegram/botApiConnection.d.ts.map +1 -0
- package/dist/connectors/telegram/botApiConnection.js +201 -0
- package/dist/connectors/telegram/botApiConnection.js.map +1 -0
- package/dist/connectors/telegram/commands/botCore.d.ts +8 -2
- package/dist/connectors/telegram/commands/botCore.d.ts.map +1 -1
- package/dist/connectors/telegram/commands/botSkills.d.ts +21 -0
- package/dist/connectors/telegram/commands/botSkills.d.ts.map +1 -0
- package/dist/connectors/telegram/commands/botSkills.js +133 -0
- package/dist/connectors/telegram/commands/botSkills.js.map +1 -0
- package/dist/connectors/telegram/commands/callbackMessage.d.ts +5 -0
- package/dist/connectors/telegram/commands/callbackMessage.d.ts.map +1 -1
- package/dist/connectors/telegram/commands/callbackMessage.js +9 -0
- package/dist/connectors/telegram/commands/callbackMessage.js.map +1 -1
- package/dist/connectors/telegram/commands/compaction.d.ts +65 -3
- package/dist/connectors/telegram/commands/compaction.d.ts.map +1 -1
- package/dist/connectors/telegram/commands/compaction.js +512 -94
- package/dist/connectors/telegram/commands/compaction.js.map +1 -1
- package/dist/connectors/telegram/commands/displayModes.d.ts +1 -1
- package/dist/connectors/telegram/commands/displayModes.d.ts.map +1 -1
- package/dist/connectors/telegram/commands/displayModes.js +6 -18
- package/dist/connectors/telegram/commands/displayModes.js.map +1 -1
- package/dist/connectors/telegram/commands/fallbackChain.js +5 -5
- package/dist/connectors/telegram/commands/fallbackChain.js.map +1 -1
- package/dist/connectors/telegram/commands/reminders.d.ts +1 -1
- package/dist/connectors/telegram/commands/reminders.d.ts.map +1 -1
- package/dist/connectors/telegram/commands/reminders.js +4 -15
- package/dist/connectors/telegram/commands/reminders.js.map +1 -1
- package/dist/connectors/telegram/commands/selfUpdate.d.ts.map +1 -1
- package/dist/connectors/telegram/commands/selfUpdate.js +1 -11
- package/dist/connectors/telegram/commands/selfUpdate.js.map +1 -1
- package/dist/connectors/telegram/commands/taskAgents.d.ts +22 -0
- package/dist/connectors/telegram/commands/taskAgents.d.ts.map +1 -0
- package/dist/connectors/telegram/commands/taskAgents.js +104 -0
- package/dist/connectors/telegram/commands/taskAgents.js.map +1 -0
- package/dist/connectors/telegram/commands/todo.d.ts +82 -0
- package/dist/connectors/telegram/commands/todo.d.ts.map +1 -0
- package/dist/connectors/telegram/commands/todo.js +384 -0
- package/dist/connectors/telegram/commands/todo.js.map +1 -0
- package/dist/connectors/telegram/commands/topicCommand.d.ts +6 -2
- package/dist/connectors/telegram/commands/topicCommand.d.ts.map +1 -1
- package/dist/connectors/telegram/commands/topicCommand.js +6 -9
- package/dist/connectors/telegram/commands/topicCommand.js.map +1 -1
- package/dist/connectors/telegram/openBindMessages.d.ts +45 -0
- package/dist/connectors/telegram/openBindMessages.d.ts.map +1 -0
- package/dist/connectors/telegram/openBindMessages.js +67 -0
- package/dist/connectors/telegram/openBindMessages.js.map +1 -0
- package/dist/connectors/telegram/outputFlushPlan.d.ts +49 -0
- package/dist/connectors/telegram/outputFlushPlan.d.ts.map +1 -1
- package/dist/connectors/telegram/outputFlushPlan.js +46 -0
- package/dist/connectors/telegram/outputFlushPlan.js.map +1 -1
- package/dist/connectors/telegram/pendingTopicName.d.ts +26 -0
- package/dist/connectors/telegram/pendingTopicName.d.ts.map +1 -0
- package/dist/connectors/telegram/pendingTopicName.js +27 -0
- package/dist/connectors/telegram/pendingTopicName.js.map +1 -0
- package/dist/connectors/test/connector.d.ts.map +1 -1
- package/dist/connectors/test/connector.js +6 -1
- package/dist/connectors/test/connector.js.map +1 -1
- package/dist/i18n/de.d.ts.map +1 -1
- package/dist/i18n/de.js +90 -7
- package/dist/i18n/de.js.map +1 -1
- package/dist/i18n/en.d.ts.map +1 -1
- package/dist/i18n/en.js +90 -7
- package/dist/i18n/en.js.map +1 -1
- package/dist/i18n/es.d.ts.map +1 -1
- package/dist/i18n/es.js +90 -7
- package/dist/i18n/es.js.map +1 -1
- package/dist/i18n/fr.d.ts.map +1 -1
- package/dist/i18n/fr.js +90 -7
- package/dist/i18n/fr.js.map +1 -1
- package/dist/i18n/hi.d.ts.map +1 -1
- package/dist/i18n/hi.js +90 -7
- package/dist/i18n/hi.js.map +1 -1
- package/dist/i18n/ja.d.ts.map +1 -1
- package/dist/i18n/ja.js +90 -7
- package/dist/i18n/ja.js.map +1 -1
- package/dist/i18n/ka.d.ts.map +1 -1
- package/dist/i18n/ka.js +90 -7
- package/dist/i18n/ka.js.map +1 -1
- package/dist/i18n/pt.d.ts.map +1 -1
- package/dist/i18n/pt.js +90 -7
- package/dist/i18n/pt.js.map +1 -1
- package/dist/i18n/ru.d.ts.map +1 -1
- package/dist/i18n/ru.js +90 -7
- package/dist/i18n/ru.js.map +1 -1
- package/dist/i18n/uk.d.ts.map +1 -1
- package/dist/i18n/uk.js +90 -7
- package/dist/i18n/uk.js.map +1 -1
- package/dist/i18n/uz.d.ts.map +1 -1
- package/dist/i18n/uz.js +90 -7
- package/dist/i18n/uz.js.map +1 -1
- package/dist/i18n/zh.d.ts.map +1 -1
- package/dist/i18n/zh.js +90 -7
- package/dist/i18n/zh.js.map +1 -1
- package/dist/i18n.d.ts +1 -1
- package/dist/i18n.js +1 -1
- package/dist/installManager.d.ts +13 -0
- package/dist/installManager.d.ts.map +1 -1
- package/dist/installManager.js +38 -4
- package/dist/installManager.js.map +1 -1
- package/dist/instanceSettings.d.ts +40 -1
- package/dist/instanceSettings.d.ts.map +1 -1
- package/dist/instanceSettings.js +105 -26
- package/dist/instanceSettings.js.map +1 -1
- package/dist/openCodeQuestionFlow.d.ts +30 -0
- package/dist/openCodeQuestionFlow.d.ts.map +1 -1
- package/dist/openCodeQuestionFlow.js +43 -0
- package/dist/openCodeQuestionFlow.js.map +1 -1
- package/dist/postToSession.d.ts +20 -5
- package/dist/postToSession.d.ts.map +1 -1
- package/dist/postToSession.js +38 -7
- package/dist/postToSession.js.map +1 -1
- package/dist/remoteRun/cliArgs.d.ts +73 -0
- package/dist/remoteRun/cliArgs.d.ts.map +1 -0
- package/dist/remoteRun/cliArgs.js +197 -0
- package/dist/remoteRun/cliArgs.js.map +1 -0
- package/dist/remoteRun/commands.d.ts +56 -0
- package/dist/remoteRun/commands.d.ts.map +1 -0
- package/dist/remoteRun/commands.js +306 -0
- package/dist/remoteRun/commands.js.map +1 -0
- package/dist/remoteRun/depsPlan.d.ts +16 -0
- package/dist/remoteRun/depsPlan.d.ts.map +1 -0
- package/dist/remoteRun/depsPlan.js +82 -0
- package/dist/remoteRun/depsPlan.js.map +1 -0
- package/dist/remoteRun/exitCodes.d.ts +34 -0
- package/dist/remoteRun/exitCodes.d.ts.map +1 -0
- package/dist/remoteRun/exitCodes.js +38 -0
- package/dist/remoteRun/exitCodes.js.map +1 -0
- package/dist/remoteRun/foreground.d.ts +29 -0
- package/dist/remoteRun/foreground.d.ts.map +1 -0
- package/dist/remoteRun/foreground.js +159 -0
- package/dist/remoteRun/foreground.js.map +1 -0
- package/dist/remoteRun/interrupts.d.ts +17 -0
- package/dist/remoteRun/interrupts.d.ts.map +1 -0
- package/dist/remoteRun/interrupts.js +41 -0
- package/dist/remoteRun/interrupts.js.map +1 -0
- package/dist/remoteRun/jobFiles.d.ts +31 -0
- package/dist/remoteRun/jobFiles.d.ts.map +1 -0
- package/dist/remoteRun/jobFiles.js +84 -0
- package/dist/remoteRun/jobFiles.js.map +1 -0
- package/dist/remoteRun/jobFormat.d.ts +16 -0
- package/dist/remoteRun/jobFormat.d.ts.map +1 -0
- package/dist/remoteRun/jobFormat.js +130 -0
- package/dist/remoteRun/jobFormat.js.map +1 -0
- package/dist/remoteRun/jobId.d.ts +15 -0
- package/dist/remoteRun/jobId.d.ts.map +1 -0
- package/dist/remoteRun/jobId.js +85 -0
- package/dist/remoteRun/jobId.js.map +1 -0
- package/dist/remoteRun/jobMeta.d.ts +18 -0
- package/dist/remoteRun/jobMeta.d.ts.map +1 -0
- package/dist/remoteRun/jobMeta.js +33 -0
- package/dist/remoteRun/jobMeta.js.map +1 -0
- package/dist/remoteRun/jobQuery.d.ts +12 -0
- package/dist/remoteRun/jobQuery.d.ts.map +1 -0
- package/dist/remoteRun/jobQuery.js +22 -0
- package/dist/remoteRun/jobQuery.js.map +1 -0
- package/dist/remoteRun/jobRecords.d.ts +22 -0
- package/dist/remoteRun/jobRecords.d.ts.map +1 -0
- package/dist/remoteRun/jobRecords.js +145 -0
- package/dist/remoteRun/jobRecords.js.map +1 -0
- package/dist/remoteRun/jobState.d.ts +62 -0
- package/dist/remoteRun/jobState.d.ts.map +1 -0
- package/dist/remoteRun/jobState.js +132 -0
- package/dist/remoteRun/jobState.js.map +1 -0
- package/dist/remoteRun/leaseTiming.d.ts +18 -0
- package/dist/remoteRun/leaseTiming.d.ts.map +1 -0
- package/dist/remoteRun/leaseTiming.js +43 -0
- package/dist/remoteRun/leaseTiming.js.map +1 -0
- package/dist/remoteRun/output.d.ts +35 -0
- package/dist/remoteRun/output.d.ts.map +1 -0
- package/dist/remoteRun/output.js +82 -0
- package/dist/remoteRun/output.js.map +1 -0
- package/dist/remoteRun/pathPatterns.d.ts +33 -0
- package/dist/remoteRun/pathPatterns.d.ts.map +1 -0
- package/dist/remoteRun/pathPatterns.js +115 -0
- package/dist/remoteRun/pathPatterns.js.map +1 -0
- package/dist/remoteRun/probe.d.ts +56 -0
- package/dist/remoteRun/probe.d.ts.map +1 -0
- package/dist/remoteRun/probe.js +123 -0
- package/dist/remoteRun/probe.js.map +1 -0
- package/dist/remoteRun/project.d.ts +26 -0
- package/dist/remoteRun/project.d.ts.map +1 -0
- package/dist/remoteRun/project.js +159 -0
- package/dist/remoteRun/project.js.map +1 -0
- package/dist/remoteRun/projectConfig.d.ts +38 -0
- package/dist/remoteRun/projectConfig.d.ts.map +1 -0
- package/dist/remoteRun/projectConfig.js +87 -0
- package/dist/remoteRun/projectConfig.js.map +1 -0
- package/dist/remoteRun/remoteRunCli.d.ts +15 -0
- package/dist/remoteRun/remoteRunCli.d.ts.map +1 -0
- package/dist/remoteRun/remoteRunCli.js +144 -0
- package/dist/remoteRun/remoteRunCli.js.map +1 -0
- package/dist/remoteRun/remoteRunError.d.ts +14 -0
- package/dist/remoteRun/remoteRunError.d.ts.map +1 -0
- package/dist/remoteRun/remoteRunError.js +28 -0
- package/dist/remoteRun/remoteRunError.js.map +1 -0
- package/dist/remoteRun/rsync.d.ts +17 -0
- package/dist/remoteRun/rsync.d.ts.map +1 -0
- package/dist/remoteRun/rsync.js +39 -0
- package/dist/remoteRun/rsync.js.map +1 -0
- package/dist/remoteRun/runnerClient.d.ts +50 -0
- package/dist/remoteRun/runnerClient.d.ts.map +1 -0
- package/dist/remoteRun/runnerClient.js +139 -0
- package/dist/remoteRun/runnerClient.js.map +1 -0
- package/dist/remoteRun/runners.d.ts +57 -0
- package/dist/remoteRun/runners.d.ts.map +1 -0
- package/dist/remoteRun/runners.js +181 -0
- package/dist/remoteRun/runners.js.map +1 -0
- package/dist/remoteRun/runnersConfig.d.ts +44 -0
- package/dist/remoteRun/runnersConfig.d.ts.map +1 -0
- package/dist/remoteRun/runnersConfig.js +107 -0
- package/dist/remoteRun/runnersConfig.js.map +1 -0
- package/dist/remoteRun/safeCopy.d.ts +31 -0
- package/dist/remoteRun/safeCopy.d.ts.map +1 -0
- package/dist/remoteRun/safeCopy.js +137 -0
- package/dist/remoteRun/safeCopy.js.map +1 -0
- package/dist/remoteRun/sendPlan.d.ts +67 -0
- package/dist/remoteRun/sendPlan.d.ts.map +1 -0
- package/dist/remoteRun/sendPlan.js +139 -0
- package/dist/remoteRun/sendPlan.js.map +1 -0
- package/dist/remoteRun/ssh.d.ts +62 -0
- package/dist/remoteRun/ssh.d.ts.map +1 -0
- package/dist/remoteRun/ssh.js +202 -0
- package/dist/remoteRun/ssh.js.map +1 -0
- package/dist/remoteRun/submit.d.ts +29 -0
- package/dist/remoteRun/submit.d.ts.map +1 -0
- package/dist/remoteRun/submit.js +142 -0
- package/dist/remoteRun/submit.js.map +1 -0
- package/dist/requests/answerRequest.d.ts +5 -0
- package/dist/requests/answerRequest.d.ts.map +1 -1
- package/dist/requests/answerRequest.js +16 -1
- package/dist/requests/answerRequest.js.map +1 -1
- package/dist/requests/requestLedger.d.ts +13 -0
- package/dist/requests/requestLedger.d.ts.map +1 -1
- package/dist/requests/requestLedger.js +9 -0
- package/dist/requests/requestLedger.js.map +1 -1
- package/dist/requests/topicRequestSettle.d.ts +30 -0
- package/dist/requests/topicRequestSettle.d.ts.map +1 -0
- package/dist/requests/topicRequestSettle.js +23 -0
- package/dist/requests/topicRequestSettle.js.map +1 -0
- package/dist/requests/wakeUpEngine.d.ts +4 -0
- package/dist/requests/wakeUpEngine.d.ts.map +1 -1
- package/dist/requests/wakeUpEngine.js +5 -1
- package/dist/requests/wakeUpEngine.js.map +1 -1
- package/dist/scheduler/delivery.d.ts +2 -0
- package/dist/scheduler/delivery.d.ts.map +1 -1
- package/dist/scheduler/delivery.js +8 -4
- package/dist/scheduler/delivery.js.map +1 -1
- package/dist/scheduler/mcpSurface.d.ts +59 -10
- package/dist/scheduler/mcpSurface.d.ts.map +1 -1
- package/dist/scheduler/mcpSurface.js +276 -79
- package/dist/scheduler/mcpSurface.js.map +1 -1
- package/dist/scheduler/recurrence.d.ts +5 -0
- package/dist/scheduler/recurrence.d.ts.map +1 -1
- package/dist/scheduler/recurrence.js +12 -2
- package/dist/scheduler/recurrence.js.map +1 -1
- package/dist/scheduler/strictToolInput.d.ts +45 -0
- package/dist/scheduler/strictToolInput.d.ts.map +1 -0
- package/dist/scheduler/strictToolInput.js +155 -0
- package/dist/scheduler/strictToolInput.js.map +1 -0
- package/dist/scheduler/types.d.ts +5 -0
- package/dist/scheduler/types.d.ts.map +1 -1
- package/dist/scheduler/workerWatch.d.ts +23 -0
- package/dist/scheduler/workerWatch.d.ts.map +1 -0
- package/dist/scheduler/workerWatch.js +26 -0
- package/dist/scheduler/workerWatch.js.map +1 -0
- package/dist/selfUpdate/emittedSource.d.ts +11 -0
- package/dist/selfUpdate/emittedSource.d.ts.map +1 -0
- package/dist/selfUpdate/emittedSource.js +24 -0
- package/dist/selfUpdate/emittedSource.js.map +1 -0
- package/dist/selfUpdate/gitSource.d.ts +0 -6
- package/dist/selfUpdate/gitSource.d.ts.map +1 -1
- package/dist/selfUpdate/gitSource.js +2 -18
- package/dist/selfUpdate/gitSource.js.map +1 -1
- package/dist/selfUpdate/updatePending.d.ts +1 -1
- package/dist/sendErrorClassifier.d.ts +10 -0
- package/dist/sendErrorClassifier.d.ts.map +1 -1
- package/dist/sendErrorClassifier.js +22 -0
- package/dist/sendErrorClassifier.js.map +1 -1
- package/dist/state.d.ts +78 -7
- package/dist/state.d.ts.map +1 -1
- package/dist/state.js +125 -8
- package/dist/state.js.map +1 -1
- package/dist/stateFile.d.ts +9 -0
- package/dist/stateFile.d.ts.map +1 -0
- package/dist/stateFile.js +57 -0
- package/dist/stateFile.js.map +1 -0
- package/dist/stt/sttInstall.d.ts +7 -3
- package/dist/stt/sttInstall.d.ts.map +1 -1
- package/dist/stt/sttInstall.js +8 -4
- package/dist/stt/sttInstall.js.map +1 -1
- package/dist/stt/sttSettings.d.ts +2 -1
- package/dist/stt/sttSettings.d.ts.map +1 -1
- package/dist/stt/sttSettings.js +3 -2
- package/dist/stt/sttSettings.js.map +1 -1
- package/dist/stt/transcribeChain.js +2 -0
- package/dist/stt/transcribeChain.js.map +1 -1
- package/dist/testTimings.d.ts +13 -3
- package/dist/testTimings.d.ts.map +1 -1
- package/dist/testTimings.js +26 -2
- package/dist/testTimings.js.map +1 -1
- package/dist/todos/board.d.ts +83 -0
- package/dist/todos/board.d.ts.map +1 -0
- package/dist/todos/board.js +227 -0
- package/dist/todos/board.js.map +1 -0
- package/dist/todos/format.d.ts +33 -0
- package/dist/todos/format.d.ts.map +1 -0
- package/dist/todos/format.js +90 -0
- package/dist/todos/format.js.map +1 -0
- package/dist/todos/merge.d.ts +46 -0
- package/dist/todos/merge.d.ts.map +1 -0
- package/dist/todos/merge.js +137 -0
- package/dist/todos/merge.js.map +1 -0
- package/dist/todos/midTurn.d.ts +75 -0
- package/dist/todos/midTurn.d.ts.map +1 -0
- package/dist/todos/midTurn.js +214 -0
- package/dist/todos/midTurn.js.map +1 -0
- package/dist/todos/nag.d.ts +85 -0
- package/dist/todos/nag.d.ts.map +1 -0
- package/dist/todos/nag.js +103 -0
- package/dist/todos/nag.js.map +1 -0
- package/dist/todos/order.d.ts +25 -0
- package/dist/todos/order.d.ts.map +1 -0
- package/dist/todos/order.js +61 -0
- package/dist/todos/order.js.map +1 -0
- package/dist/todos/projects.d.ts +102 -0
- package/dist/todos/projects.d.ts.map +1 -0
- package/dist/todos/projects.js +342 -0
- package/dist/todos/projects.js.map +1 -0
- package/dist/todos/registry.d.ts +64 -0
- package/dist/todos/registry.d.ts.map +1 -0
- package/dist/todos/registry.js +116 -0
- package/dist/todos/registry.js.map +1 -0
- package/dist/todos/reminderEngine.d.ts +78 -0
- package/dist/todos/reminderEngine.d.ts.map +1 -0
- package/dist/todos/reminderEngine.js +162 -0
- package/dist/todos/reminderEngine.js.map +1 -0
- package/dist/todos/store.d.ts +34 -0
- package/dist/todos/store.d.ts.map +1 -0
- package/dist/todos/store.js +208 -0
- package/dist/todos/store.js.map +1 -0
- package/dist/todos/tools.d.ts +26 -0
- package/dist/todos/tools.d.ts.map +1 -0
- package/dist/todos/tools.js +25 -0
- package/dist/todos/tools.js.map +1 -0
- package/dist/todos/types.d.ts +85 -0
- package/dist/todos/types.d.ts.map +1 -0
- package/dist/todos/types.js +30 -0
- package/dist/todos/types.js.map +1 -0
- package/dist/trackers/taskAgentLimit.d.ts +58 -0
- package/dist/trackers/taskAgentLimit.d.ts.map +1 -0
- package/dist/trackers/taskAgentLimit.js +62 -0
- package/dist/trackers/taskAgentLimit.js.map +1 -0
- package/dist/trackers/taskAgentSlots.d.ts +109 -0
- package/dist/trackers/taskAgentSlots.d.ts.map +1 -0
- package/dist/trackers/taskAgentSlots.js +227 -0
- package/dist/trackers/taskAgentSlots.js.map +1 -0
- package/dist/trackers/types.d.ts +14 -0
- package/dist/trackers/types.d.ts.map +1 -0
- package/dist/trackers/types.js +3 -0
- package/dist/trackers/types.js.map +1 -0
- package/dist/types.d.ts +80 -4
- package/dist/types.d.ts.map +1 -1
- package/dist/utils/adoptReplayGate.d.ts +16 -0
- package/dist/utils/adoptReplayGate.d.ts.map +1 -0
- package/dist/utils/adoptReplayGate.js +35 -0
- package/dist/utils/adoptReplayGate.js.map +1 -0
- package/dist/utils/agentPlugin.d.ts +113 -0
- package/dist/utils/agentPlugin.d.ts.map +1 -0
- package/dist/utils/agentPlugin.js +192 -0
- package/dist/utils/agentPlugin.js.map +1 -0
- package/dist/utils/autoContinueOnLimit.d.ts +7 -4
- package/dist/utils/autoContinueOnLimit.d.ts.map +1 -1
- package/dist/utils/autoContinueOnLimit.js +8 -5
- package/dist/utils/autoContinueOnLimit.js.map +1 -1
- package/dist/utils/botSkills.d.ts +62 -0
- package/dist/utils/botSkills.d.ts.map +1 -0
- package/dist/utils/botSkills.js +53 -0
- package/dist/utils/botSkills.js.map +1 -0
- package/dist/utils/botSkillsSetting.d.ts +7 -0
- package/dist/utils/botSkillsSetting.d.ts.map +1 -0
- package/dist/utils/botSkillsSetting.js +9 -0
- package/dist/utils/botSkillsSetting.js.map +1 -0
- package/dist/utils/claudeCodeVersion.d.ts +7 -0
- package/dist/utils/claudeCodeVersion.d.ts.map +1 -1
- package/dist/utils/claudeCodeVersion.js +14 -1
- package/dist/utils/claudeCodeVersion.js.map +1 -1
- package/dist/utils/claudeCompactHook.d.ts +33 -15
- package/dist/utils/claudeCompactHook.d.ts.map +1 -1
- package/dist/utils/claudeCompactHook.js +36 -17
- package/dist/utils/claudeCompactHook.js.map +1 -1
- package/dist/utils/claudeCompactSummary.d.ts +15 -0
- package/dist/utils/claudeCompactSummary.d.ts.map +1 -0
- package/dist/utils/claudeCompactSummary.js +96 -0
- package/dist/utils/claudeCompactSummary.js.map +1 -0
- package/dist/utils/claudeLimitSwitch.d.ts +11 -9
- package/dist/utils/claudeLimitSwitch.d.ts.map +1 -1
- package/dist/utils/claudeLimitSwitch.js +18 -16
- package/dist/utils/claudeLimitSwitch.js.map +1 -1
- package/dist/utils/claudeProfiles.d.ts +5 -0
- package/dist/utils/claudeProfiles.d.ts.map +1 -1
- package/dist/utils/claudeProfiles.js +14 -0
- package/dist/utils/claudeProfiles.js.map +1 -1
- package/dist/utils/claudeSessionTitle.d.ts +2 -1
- package/dist/utils/claudeSessionTitle.d.ts.map +1 -1
- package/dist/utils/claudeSessionTitle.js +14 -14
- package/dist/utils/claudeSessionTitle.js.map +1 -1
- package/dist/utils/claudeUsage.d.ts +95 -15
- package/dist/utils/claudeUsage.d.ts.map +1 -1
- package/dist/utils/claudeUsage.js +241 -41
- package/dist/utils/claudeUsage.js.map +1 -1
- package/dist/utils/claudeUsageRefresher.d.ts +10 -0
- package/dist/utils/claudeUsageRefresher.d.ts.map +1 -1
- package/dist/utils/claudeUsageRefresher.js +11 -0
- package/dist/utils/claudeUsageRefresher.js.map +1 -1
- package/dist/utils/claudeUserEntry.d.ts +50 -0
- package/dist/utils/claudeUserEntry.d.ts.map +1 -0
- package/dist/utils/claudeUserEntry.js +120 -0
- package/dist/utils/claudeUserEntry.js.map +1 -0
- package/dist/utils/clearThreadOutputQueues.d.ts +4 -3
- package/dist/utils/clearThreadOutputQueues.d.ts.map +1 -1
- package/dist/utils/clearThreadOutputQueues.js +1 -1
- package/dist/utils/clearThreadOutputQueues.js.map +1 -1
- package/dist/utils/compactOnIdle.d.ts +33 -13
- package/dist/utils/compactOnIdle.d.ts.map +1 -1
- package/dist/utils/compactOnIdle.js +35 -15
- package/dist/utils/compactOnIdle.js.map +1 -1
- package/dist/utils/fallbackBridge.d.ts +5 -0
- package/dist/utils/fallbackBridge.d.ts.map +1 -1
- package/dist/utils/fallbackBridge.js +19 -3
- package/dist/utils/fallbackBridge.js.map +1 -1
- package/dist/utils/fallbackChain.d.ts +9 -3
- package/dist/utils/fallbackChain.d.ts.map +1 -1
- package/dist/utils/fallbackChain.js +21 -3
- package/dist/utils/fallbackChain.js.map +1 -1
- package/dist/utils/fileSendPlan.d.ts +6 -0
- package/dist/utils/fileSendPlan.d.ts.map +1 -1
- package/dist/utils/fileSendPlan.js +11 -0
- package/dist/utils/fileSendPlan.js.map +1 -1
- package/dist/utils/fileSendService.d.ts +7 -1
- package/dist/utils/fileSendService.d.ts.map +1 -1
- package/dist/utils/fileSendService.js +6 -2
- package/dist/utils/fileSendService.js.map +1 -1
- package/dist/utils/groupFinalizePlan.d.ts +8 -10
- package/dist/utils/groupFinalizePlan.d.ts.map +1 -1
- package/dist/utils/groupFinalizePlan.js +8 -12
- package/dist/utils/groupFinalizePlan.js.map +1 -1
- package/dist/utils/jsonStreamHost.d.ts +13 -0
- package/dist/utils/jsonStreamHost.d.ts.map +1 -1
- package/dist/utils/jsonStreamHost.js +13 -0
- package/dist/utils/jsonStreamHost.js.map +1 -1
- package/dist/utils/messageSendService.d.ts +5 -3
- package/dist/utils/messageSendService.d.ts.map +1 -1
- package/dist/utils/messageSendService.js +12 -5
- package/dist/utils/messageSendService.js.map +1 -1
- package/dist/utils/openCodeCompactPlugin.d.ts +39 -14
- package/dist/utils/openCodeCompactPlugin.d.ts.map +1 -1
- package/dist/utils/openCodeCompactPlugin.js +106 -38
- package/dist/utils/openCodeCompactPlugin.js.map +1 -1
- package/dist/utils/promptDelivery.d.ts +29 -12
- package/dist/utils/promptDelivery.d.ts.map +1 -1
- package/dist/utils/promptDelivery.js +13 -5
- package/dist/utils/promptDelivery.js.map +1 -1
- package/dist/utils/sentKindsSummary.d.ts +10 -0
- package/dist/utils/sentKindsSummary.d.ts.map +1 -0
- package/dist/utils/sentKindsSummary.js +18 -0
- package/dist/utils/sentKindsSummary.js.map +1 -0
- package/dist/utils/telegramError.d.ts +6 -0
- package/dist/utils/telegramError.d.ts.map +1 -1
- package/dist/utils/telegramError.js +12 -0
- package/dist/utils/telegramError.js.map +1 -1
- package/dist/utils/topicView.d.ts +1 -1
- package/dist/utils/topicView.js +1 -1
- package/dist/utils/transcribeAudio.d.ts +10 -0
- package/dist/utils/transcribeAudio.d.ts.map +1 -1
- package/dist/utils/transcribeAudio.js +22 -3
- package/dist/utils/transcribeAudio.js.map +1 -1
- package/dist/utils/transcriptErrorTime.d.ts +8 -0
- package/dist/utils/transcriptErrorTime.d.ts.map +1 -0
- package/dist/utils/transcriptErrorTime.js +56 -0
- package/dist/utils/transcriptErrorTime.js.map +1 -0
- package/dist/utils/wedgeRecovery.d.ts +2 -0
- package/dist/utils/wedgeRecovery.d.ts.map +1 -1
- package/dist/utils/wedgeRecovery.js +1 -1
- package/dist/utils/wedgeRecovery.js.map +1 -1
- package/package.json +11 -3
- package/remoteRun/runner.sh +1242 -0
- package/stt/gigaam_sidecar.py +555 -50
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,273 @@
|
|
|
2
2
|
|
|
3
3
|
## Unreleased
|
|
4
4
|
|
|
5
|
+
## 3.7.0 — 2026-11-01
|
|
6
|
+
|
|
7
|
+
**The answers of `send_messages_to_user` and `send_file_to_user` now say what was sent, per kind — «Delivered 3 messages: 1 text, 2 documents.», «Sent 3 files: 1 photo, 2 documents.» — so an agent can see when a file did not go out as the kind it meant.**
|
|
8
|
+
Before, they only counted («Delivered 3 messages to the topic», «Sent 3 file(s) to the topic»), so a batch of images that arrived as plain text or as documents read as a full success.
|
|
9
|
+
Now the answer names what landed — texts, photos, videos, animations, documents — taken from what Telegram was actually asked to render: a photo sent with `as_file`, one over the photo size limit, or one in an album that fell back to documents is counted as a document.
|
|
10
|
+
|
|
11
|
+
**An agent that misnames a field when it calls one of the bot's tools now gets an error that says which field and what to write — attachments no longer vanish unseen.**
|
|
12
|
+
Before, a key the tool does not know was dropped silently: an agent that sent three images to `send_messages_to_user` as `{text, filePath}` (the field is `path`) had them posted as three text-only messages, and the tool still answered «Delivered 3 messages».
|
|
13
|
+
Now every bot tool refuses a key it does not list, at the top of a call or inside an item, and answers with the key, the nearest allowed one («unknown key `filePath` — did you mean `path`?») and the allowed keys; nothing is sent. `send_file_to_user` called with `path` instead of `paths` is told the same.
|
|
14
|
+
|
|
15
|
+
**Agents can now send heavy commands — test suites, builds, emulator runs — to another machine with `charness remote-run`, and get the output, the exit code and the result files back as if the command had run here.**
|
|
16
|
+
Before, everything an agent ran landed on the one machine the bot lives on, so a long test suite or an emulator run could take most of its CPU and memory for an hour while other agents waited on it.
|
|
17
|
+
Now you list machines you reach by ssh in `~/.config/charness/runners.json` (set up by hand: an account of its own, `rsync`, Pueue — see `docs/remote-run.md`), and an agent runs `charness remote-run yarn test` (or `--bg` plus `wait` for a long run): the project is synced there (tracked and untracked files, never what `.gitignore` names, never secret-looking files unless `.remote-run` says so), the command runs in a copy, its output streams back, and an interrupt, a timeout or a lost connection stops the whole remote job.
|
|
18
|
+
`charness remote-run runners` shows each machine's CPU, memory, disk, load and what it can do (Android, iOS, Docker, Playwright); `ls`, `status`, `logs`, `wait`, `kill`, `fetch` and `exec` manage the jobs. Two runs of one project queue on the runner, each against the files as they were when it was started.
|
|
19
|
+
Agents (Telegram topics and Jira issues alike) are told about it only while at least one runner is listed; without one nothing changes.
|
|
20
|
+
|
|
21
|
+
**A message no longer gets lost when Telegram has closed the connection the bot was about to reuse — it is sent again, once, on a fresh connection.**
|
|
22
|
+
Before, the bot kept its connections to Telegram open and reused them; when Telegram had closed an idle one a moment earlier (most often while the bot was starved of CPU), the next send failed with «socket hang up» and was dropped — a notice or a reply simply never appeared in the topic.
|
|
23
|
+
Now a send that fails this way — at once, before Telegram has started to answer — is retried once on a new connection, the answer to a button tap and the edit of a picker included. It is not retried after a timeout, once Telegram has begun to answer, when the connection broke only after a while, or on a connection that was new anyway, and a file the agent sends is not retried this way (it keeps its own delivery rules). If Telegram did take the message and the connection broke before a single byte of its answer, the retry cannot tell that from a closed connection and could post the message twice; that is rare.
|
|
24
|
+
The bot also closes a connection that sat unused for 30 seconds itself, long before Telegram would, so an ordinary pause between two messages does not meet a closed one. When it retries, the bot log says «pooled connection was closed by the server».
|
|
25
|
+
|
|
26
|
+
**Stopping every agent from General is typed `/quitall` — the «only available in the General topic» refusal now says so, in all 12 languages.**
|
|
27
|
+
Before, that refusal (and the docs) told you to use `/quit-all`, but Telegram ends a command at the hyphen, so `/quit-all` reached the bot as plain `/quit` and stopped only the one topic's agent, not all of them.
|
|
28
|
+
The refusal and the docs now name `/quitall`, the spelling the command menu lists; the command itself is unchanged.
|
|
29
|
+
|
|
30
|
+
**A question the agent asks now stays in the topic however it ends: answered, it shows your answer in place of the buttons; left alone, a note says it was not answered.**
|
|
31
|
+
Before, answering replaced the whole question with a short «✅ header: answer», walking away from it (another message, `/esc`) replaced it with «❌ Question cancelled», and re-posting or re-asking a question deleted the first message — so what the agent had asked was gone from the topic.
|
|
32
|
+
Now the message is never deleted: it keeps the question and its options, with «✅ Answer: …», «❌ Not answered» or «↓ Asked again below» under them, also when the question is re-asked after the idle compaction, when you leave the folder, or its agent is gone.
|
|
33
|
+
A question that waits through a long stream of the agent's output is put at the bottom again each time: the first message stays as the record and the newest copy is the live one, the copies in between are removed — also across a bot restart.
|
|
34
|
+
A bot restart in the middle of an idle compaction asks the question again when its conversation can still be resumed, instead of leaving it «Not answered» though you never had the chance to answer.
|
|
35
|
+
The pin works as before: one notification when the question comes, removed when it ends. The details are in `docs/commands.md`, «The agent's questions».
|
|
36
|
+
|
|
37
|
+
**Typing or saying «claude» (or `клод`) to start the agent now opens the same backend `/claude` does — json-stream by default, or the one the topic picked — not the deprecated tmux one.**
|
|
38
|
+
Before, a start phrase — in a text message or a voice note — handed the bare name `claude` on, which is the tmux backend's own name, so the phrase quietly
|
|
39
|
+
started the frozen tmux backend while `/claude` and the ▶️ Claude button opened the topic's backend. All three now open the same backend;
|
|
40
|
+
`opencode` and `terminal` are unchanged, and a topic that picked the tmux backend with `/claude_mode` still gets it.
|
|
41
|
+
|
|
42
|
+
**Binding a topic to a folder now leaves ONE message in the topic — the full welcome with the folder's facts and the start buttons — whichever way it happens.**
|
|
43
|
+
Before, a bind also posted extra messages that stayed in the topic as plainer copies of the same news: picking a folder with `/bind` (typed, tapped
|
|
44
|
+
in the picker or «create new folder») added a short «📁 Bound to `x`. Run /claude or /opencode.» just before the welcome, a topic the bot bound by
|
|
45
|
+
itself because its name matches a folder got a separate 👋 «auto-bound» greeting, a folder other topics already use got a separate ⚠️ warning, and
|
|
46
|
+
«create new folder» given the name of an existing folder added a «Folder already exists» note.
|
|
47
|
+
Now only the welcome is posted: a row in it says the bot bound the topic because its name matches the folder, another says the folder was there
|
|
48
|
+
already, and another names the topics that already use the folder — also when the bot bound the topic by itself. A topic is named there by the name
|
|
49
|
+
the bot saw it made with (or an admin renamed it to), else by a link that opens it; the name a non-admin gave a topic is not kept on its binding, since
|
|
50
|
+
the agent's thread context would repeat it. Only topics of the SAME chat are named: topics of other chats the bot serves (another group, a private chat) are
|
|
51
|
+
only counted, «+2 more» (a topic of this chat that has no name and no link to show is counted too), so one chat never learns what another calls its topics. A folder that does not exist still just gets its reason. When a topic is bound again, or leaves its folder, the buttons of its previous welcome (▶️ Claude, ▶️ OpenCode, 📋 Resume) are removed: they act on the topic's CURRENT folder, whatever the old message says, so an old welcome can no longer start an agent from a folder the topic has left. `/topic`'s «create new folder» still tells the topic
|
|
52
|
+
you typed the name in that the folder existed.
|
|
53
|
+
The `/bind` picker is now one-shot: once a folder is bound through it (a tap or «create new folder»), or «Leave current dir» is used, the picker message
|
|
54
|
+
is deleted — its «not bound, pick from the list» text would no longer be true — so an old tap cannot rebind the topic, and a second tap landing while the
|
|
55
|
+
first is still binding (on a folder, «create new folder» or «Leave current dir») is told «This picker was already used.» instead of binding or unbinding
|
|
56
|
+
twice; a refused pick, paging and the create-folder prompt leave it in place, and a tap whose answer reaches Telegram too late still does what it asked. Pickers the bot closes after a bind are refused at once, even those it could not delete (the bot keeps that in memory: after a restart a picker that still has its buttons works again), and a typed folder name that arrives while a tap holds the picker is told so instead of being dropped.
|
|
57
|
+
A «create new folder» wait ends with the bind or the leave that follows it, so the next plain message is never taken for a folder name, and its «send the folder
|
|
58
|
+
name» prompt is deleted with the bind (a refused name keeps it). Every plain message in an unbound topic posts a new folder picker, so a bind or a leave — by a tap,
|
|
59
|
+
a typed `/bind <folder>` or the bot's own auto-bind — deletes ALL the pickers still open in that topic, not only the tapped one: no stale one is left to rebind it.
|
|
60
|
+
When the bot binds a non-admin's topic on an admin's first message there, a plain message is answered by the welcome alone, without the extra «bound, run /claude» hint, and a
|
|
61
|
+
start phrase like `claude` still starts the agent; the topic is then stored under the matched folder's own name, never under the member's spelling. The
|
|
62
|
+
removed texts are gone from all 12 languages, the new rows and the toast are in all 12.
|
|
63
|
+
A topic you create whose name matches no folder now remembers that name for 24 hours: the folder picker you bind it through keeps it (the «also used by» row of a
|
|
64
|
+
later topic on that folder names it), and if a folder with that name appears meanwhile, your next message in the topic binds it by itself.
|
|
65
|
+
|
|
66
|
+
**`/task_agents` in General sets how many task agents may work at once — a number from the picker or any number you type.**
|
|
67
|
+
It opens a one-shot picker (5 / 10 / 15 / 20 / 30 / No limit, the value in force marked ✓) whose tap turns it into its confirmation;
|
|
68
|
+
`/task_agents 12` sets any whole number from 1 to 100, and `0` or `off` means no limit (a number over 100, a decimal or a word is refused with the
|
|
69
|
+
range). The screen names where the value comes from — set in General, `settings.json`, or the built-in default — and, on an instance that serves
|
|
70
|
+
Jira, how many agents work now and how many wait. General's own value beats `settings.json`'s once it is set, and a higher number starts the issues waiting for a slot at once; in a topic the command only reports
|
|
71
|
+
the value and says it is changed in General. The texts are in all 12 languages. General's `/help` also names it, and escapes the underscores of
|
|
72
|
+
its command names, so a pair of them can no longer be read as italics.
|
|
73
|
+
|
|
74
|
+
**The agents that work on Jira issues now run under ONE cap for the whole bot — 5 at once by default — and an issue over it waits in a queue and starts by itself.**
|
|
75
|
+
Before, every issue handed to the AI account started its agent at once, with nothing limiting how many ran together. Now the number of
|
|
76
|
+
tracker task agents working at the same time is capped for all projects together: `"taskAgents": { "maxConcurrent": 5 }` in
|
|
77
|
+
`settings.json` (`0` = no limit, 100 the most; read without a restart; nothing set means 5, so an instance gets the cap with this update).
|
|
78
|
+
An agent takes a slot when its issue is handed over and gives it back when it hands the issue back (a question or the final answer), when its
|
|
79
|
+
request is cancelled, or when the wake-up engine gave up on it and handed the issue back; an issue with several hand-overs open still holds one
|
|
80
|
+
slot, and an @-mention (answer only) never takes one or waits. An issue over the cap gets ONE short comment — «⏳ The AI is working on 5 tasks at
|
|
81
|
+
once, its limit, so this issue is queued (2 issues are ahead of it). It starts by itself when a slot frees up» — and stays assigned to the AI. The
|
|
82
|
+
waiting issues are one first-in-first-out list for the whole bot, kept in `state.json` so a restart keeps the order; the first one starts the
|
|
83
|
+
moment a slot frees — an agent hands its issue back, a request is cancelled, the wake-up engine gives up on one, or the cap is raised with
|
|
84
|
+
`/task_agents` — because the Jira poll then runs at once instead of at its next interval (a raise made by editing `settings.json` is noticed when
|
|
85
|
+
the bot next reads the file, at the latest at the next poll). An issue moved away from the AI while it waits leaves the list; an issue whose
|
|
86
|
+
start fails (its text cannot be read, say) keeps its place but no longer holds up the ones behind it, and after three failed starts in a row it
|
|
87
|
+
moves to the end of the list. A lower cap never stops an agent that is already working. A mistyped `taskAgents` is logged once as
|
|
88
|
+
`[Settings] settings.json taskAgents.maxConcurrent: …` and the built-in 5 applies.
|
|
89
|
+
|
|
90
|
+
**The "↩️ Resumed — last 3 messages" preview no longer shows what Claude Code records for itself: a `/compact` you ran there shows as just `/compact`.**
|
|
91
|
+
Before, resuming a conversation whose last entries were a command run in Claude Code itself printed the raw `<local-command-caveat>`,
|
|
92
|
+
`<command-name>… <command-args>…` (with the whole, often very long, argument text) and `<local-command-stdout>` entries as if they were your
|
|
93
|
+
messages, and a skill loaded in the last turn flooded the topic with its whole text. Now a command shows as its name only (a `!` shell command as
|
|
94
|
+
`!ls`), and the entries Claude Code flags as its own are left out — the summary a compaction leaves, a loaded skill's text, the caveat before a
|
|
95
|
+
command, image notes, messages from another session — as is an entry that is only a command's output, a reminder or a task notification. The
|
|
96
|
+
entries left out do not count: the preview still shows the last three real messages. A message of yours is shown whole, also when it pastes or
|
|
97
|
+
mentions one of these tags; only a `<system-reminder>` block that a hook appended to it is cut. The same goes for the recap after a bot restart
|
|
98
|
+
and for the titles in the `/sessions` list. When a limit moves a topic to another agent, the summary of the conversation's earlier compaction
|
|
99
|
+
(Claude topics) is handed over as context, labelled as such, and never as something you said.
|
|
100
|
+
|
|
101
|
+
**The skills Charness gives its agents can now be switched off — `/bot_skills` in General for the whole instance, in a topic for that topic only.**
|
|
102
|
+
A deployment whose workspace instructions name skills of their own (a Jira-only instance, say) no longer has to live with the bot's
|
|
103
|
+
`charness-manager` and delegate skills beside them, nor with the hint in the bot MCP's instructions to load the manager. `/bot_skills` opens a
|
|
104
|
+
one-shot picker: in General On / Off for the instance, in a topic On / Off / «As in General» with the current choice marked; a tap turns the picker
|
|
105
|
+
into its confirmation (the texts are in all 12 languages). An instance without General sets the default with `"botSkills": "on" | "off"` in
|
|
106
|
+
`settings.json` (read without a restart; General's own choice beats it once made; nothing set means ON, exactly as before). With the switch off a
|
|
107
|
+
Claude conversation starts and resumes without the bot's skills folder, and the hint is gone from its instructions (the worker-watch recipe in
|
|
108
|
+
`schedule_create` stays: it is a tool fact, not a skill). A running agent keeps its skills until its next start (the idle stop and resume, a new
|
|
109
|
+
session or a model change). OpenCode has one server for every topic, so only the instance value counts there: the server is replaced at the
|
|
110
|
+
bot's next start, once nothing works in it, by one started without (or, when turned back on, with) the skills folder — a `settings.json` that says
|
|
111
|
+
`off` is followed already by the server the hot supervisor starts first — and a topic's own choice changes only its hint — its screen says the listed skills stay, that the hint changes when the OpenCode server next restarts and that the
|
|
112
|
+
OpenCode topics of one folder share it. General's screen names where the value comes from (set in General, `settings.json`, or the built-in
|
|
113
|
+
default). A mistyped `botSkills` is logged once as `[Settings] settings.json botSkills: …`
|
|
114
|
+
and ON applies.
|
|
115
|
+
|
|
116
|
+
**The tmux backend for Claude Code is now marked deprecated: it is frozen and no longer developed, and `/claude_mode` says so.**
|
|
117
|
+
Before, nothing told you that, so you could pick a backend that gets no new features. The `/claude_mode` picker now shows it as
|
|
118
|
+
«🖥 tmux (deprecated)» with a line pointing to the recommended json-stream backend, the same hint follows a switch to it, `/status`
|
|
119
|
+
flags a topic that runs on it, and the command's menu text says «tmux (deprecated)». Nothing else changes: it stays selectable, a topic
|
|
120
|
+
already on it keeps working exactly as before and nothing is migrated for you. The texts are in all 12 languages.
|
|
121
|
+
|
|
122
|
+
**The local speech recognition (GigaAM) now recognises a voice message to its last second also when it is an MP3, an M4A or two OGG files joined into one.**
|
|
123
|
+
Before, an MP3 without a length header (a cut-out stream, or a variable-bitrate file) was read for only its first seconds — 6.7 s of a 40 s
|
|
124
|
+
file — the second half of two OGG files joined into one was dropped, and an M4A (AAC) was refused, so the next engine in your list
|
|
125
|
+
answered it or nothing did. Telegram's usual OGG/Opus voice notes are read exactly as before. The three formats are now decoded with
|
|
126
|
+
`av` (ffmpeg's libraries) in the engine's private Python environment: after this update the local engine re-installs itself once (about
|
|
127
|
+
a minute and a ~35 MB download, ~100 MB more disk; the model is not downloaded again, progress shows in General), and a voice sent
|
|
128
|
+
meanwhile goes to the next engine in your list.
|
|
129
|
+
|
|
130
|
+
**Every compaction summary now ends with a numbered checklist of what the agent does next, and its first item is to load the skills it had loaded.**
|
|
131
|
+
After a compaction the continuing session often skipped reloading its skills and worked without them. The checklist is now asked for on every path:
|
|
132
|
+
the idle compaction, `/compact`, the compaction the agent arms itself (`compact_conversation`), and the one the agent CLI or OpenCode runs by
|
|
133
|
+
itself when the context overflows. Item 1 is «load these skills» with their exact names (no such item when none was loaded), then the next steps the
|
|
134
|
+
summary already records, in order — none invented. The list is the last thing in the summary; where the idle compaction asks for the closing
|
|
135
|
+
«where we stopped» section, it is that section's last part. An OpenCode server that was already running gets the new text too: the plugin file in
|
|
136
|
+
OpenCode's plugin folder now carries a hash of its text in its name (`charness-compaction-<hash>.js`), so at the bot's next start a project folder
|
|
137
|
+
whose instance loaded an older text is recreated (when nothing runs in it; a working one is retried at the next start) and the older copies of the
|
|
138
|
+
file are removed.
|
|
139
|
+
|
|
140
|
+
**A usage-limit resume that finds its session gone no longer says «resumed» right before «no session».** When the bot restarted while a
|
|
141
|
+
topic waited for a limit's reset and the conversation was ended in the same moment, the topic read the pinned «work resumed» notice and
|
|
142
|
+
then «no session». The «resumed» notice now goes out only after a session took the "continue" prompt.
|
|
143
|
+
|
|
144
|
+
**A hot-mode bot no longer keeps running the old build after a big update because its TypeScript watcher went blind.** After a pull of
|
|
145
|
+
dozens of commits followed by a dependency install, the watcher could miss the changed files (the operating system drops file-change
|
|
146
|
+
events when too many arrive while the compiler is busy): it then reported errors that did not exist, or a clean build that emitted
|
|
147
|
+
nothing, `touch tsconfig.json` did not help and only a full service restart did, while the bot kept serving the old code without a
|
|
148
|
+
word. The hot supervisor now compares the watcher with the sources every 30 s and, when a source stays a minute newer than the build,
|
|
149
|
+
restarts the watcher alone (when it reports errors, only after a fresh compile finds none) — the bot, its agents and the supervisor
|
|
150
|
+
stay up, and the update reaches the worker like any other.
|
|
151
|
+
|
|
152
|
+
**Switching to the next entry of the fallback list on a usage limit is now ON by default, also with a single signed-in account.** The
|
|
153
|
+
«🔁 Auto switch» setting of `/limits_autoswitch` used to start OFF, so a limit stranded the work on the limit notice until someone
|
|
154
|
+
tapped «Switch to …» even when another entry had room. Now a topic that hits a limit moves by itself to the first entry of the list
|
|
155
|
+
with room — another Claude account, or an OpenCode provider and model, which hands the conversation over to a different agent in
|
|
156
|
+
compacted form. With one account and no list there is nothing to move to, so the bot waits for the reset as before, and an account
|
|
157
|
+
or an entry added later is used from the first limit on. An instance where you turned it OFF (in General or for one topic) keeps
|
|
158
|
+
your choice; if you do not want conversations handed to OpenCode by themselves, turn it OFF or leave OpenCode out of the list.
|
|
159
|
+
|
|
160
|
+
**Agents now get Charness's own orchestration skills.** Every agent session the bot starts — Claude Code in a topic or a Jira
|
|
161
|
+
conversation (the stream and the tmux backend) and OpenCode — gets the bot's skills: `charness-manager` for driving work
|
|
162
|
+
through detached workers with the bot's own tools, and `charness-delegate-claude` / `charness-delegate-opencode` for
|
|
163
|
+
launching, watching and resuming those workers (Claude Code lists them as `charness:charness-manager`, …). The manager
|
|
164
|
+
watches every worker with a bot check that fires when the worker exits OR stops writing for 45 minutes — a check that only
|
|
165
|
+
asks whether the process is alive never fires on a hung worker. Its alert pins silently, since a worker that simply finished
|
|
166
|
+
fires it too, and cancelling a watchdog check (`schedule_cancel`) unpins the alerts it pinned. A user or project skill of the same kind stays as it is, a Claude
|
|
167
|
+
Code older than 2.0.25 (which has no `--plugin-dir`) starts without them, the operator's own sessions outside the bot do not
|
|
168
|
+
get these skills, and an `OPENCODE_CONFIG_DIR` the operator set is kept (its
|
|
169
|
+
OpenCode topics then go without them). An OpenCode server the bot runs that an earlier version started is replaced at the bot's
|
|
170
|
+
next start once nothing works in it; a server the bot does not own is left as it is.
|
|
171
|
+
|
|
172
|
+
**A `/claude` sent right after `/quit` no longer loses its new session at start.** The ended session killed its tmux session a
|
|
173
|
+
second time, by name and without waiting, after the stop had killed it already; on a busy host that second kill could run once
|
|
174
|
+
the new session had created its own tmux session of the same name, and the start then failed with "the CLI exited before its
|
|
175
|
+
initialize handshake". An explicit stop kills the tmux session once. And `/quit` now says «stopped» only when the session is
|
|
176
|
+
stopped: a `/claude` sent on that reply used to be told "already running", and then nothing ran.
|
|
177
|
+
|
|
178
|
+
**A prompt that waited for the agent's running turn is no longer lost when the process is stopped right after that turn.** A Jira
|
|
179
|
+
hand-over or a scheduled run that arrived while the agent was still working was written to the process the per-turn stop had
|
|
180
|
+
just ended and dropped; the agent got it only minutes later, as a whole re-post. The prompt now makes sure the conversation is
|
|
181
|
+
awake again before it is sent, so the agent reads it once, as it was built.
|
|
182
|
+
|
|
183
|
+
**A usage-limit switch no longer prompts the agent twice.** Moving a limited topic to another model or account re-spawns the
|
|
184
|
+
session for a few seconds; a reminder for the interrupted request could land in that gap on top of the "continue" prompt the
|
|
185
|
+
move sends, and the agent answered twice (one answer's streamed text was lost). The request is no longer reminded while the
|
|
186
|
+
move is under way.
|
|
187
|
+
|
|
188
|
+
**A new turn's text no longer lands inside the previous turn's message.** When the Telegram API was slow, the previous turn's
|
|
189
|
+
last text could finish sending after the next prompt had gone to the agent, and the next turn's first text was then appended
|
|
190
|
+
to that message by an edit instead of starting its own. The "new message" mark now belongs to the first text queued after it,
|
|
191
|
+
and text still waiting when your next prompt goes out is no longer pulled into the new reply's message.
|
|
192
|
+
|
|
193
|
+
**The text a turn streamed before it failed now arrives before the error notice, and a restart no longer repeats an error already handled.**
|
|
194
|
+
A turn that ended on an error (a usage limit, an API error, an interrupt) kept its last text in the answer batch while the notice
|
|
195
|
+
went out at once: the text showed up below the limit notice, the switch offer and the usage board, and a bot restart in that
|
|
196
|
+
moment replayed the turn together with its error — a second notice or error line for a limit that was already announced, or a lost
|
|
197
|
+
auto-retry. The turn's text is now sent first, and the bot saves where it stopped reading at the end of the turn, as it does for
|
|
198
|
+
a turn that succeeded.
|
|
199
|
+
|
|
200
|
+
**A message sent right after a bot restart no longer mixes with a turn that was running when the bot went down.** The restarted
|
|
201
|
+
bot reads what the agent wrote while it was down a moment after it starts; a prompt that reached the agent before that (the
|
|
202
|
+
bot's own resume after a usage limit, a scheduled run, your message) reset the reply the replayed text still belonged to, so the
|
|
203
|
+
old turn's text could end up inside the new reply's message, and an error of the old turn took the new turn's place — shown as
|
|
204
|
+
a plain "Claude error" line and not retried. A prompt now waits for that replay (at most 30 s) before it is sent; if the agent is gone
|
|
205
|
+
when the wait ends, the topic says so and the request the message opened is closed, instead of the bot later asking the agent about
|
|
206
|
+
an answer it never started.
|
|
207
|
+
|
|
208
|
+
**A usage limit that stopped the agent while the bot was down is now handled once after the restart.** The restarted bot found the
|
|
209
|
+
limit error twice — once when it checked the agent's log at start (it resumes the topic at once when the window is over), and
|
|
210
|
+
once more when it read what the agent wrote during the downtime. The second copy was handled as a fresh limit: the topic got a
|
|
211
|
+
"Usage limit reached" notice for a window that was already over (for a reset written as a clock time, a wait of up to a day),
|
|
212
|
+
a second "work resumed" message, and the agent a second "Continue" prompt and a second turn. The first one now owns the
|
|
213
|
+
episode and the replayed copy is left out.
|
|
214
|
+
|
|
215
|
+
**A bot restart in the middle of a per-turn topic's turn no longer wipes that turn's working files.** The cleanup at start took the
|
|
216
|
+
running agent of a per-turn topic for a leftover and deleted its output log and pipes while the agent was still working, so the bot
|
|
217
|
+
could neither read the rest of the turn nor write to the agent: the answer never reached the topic. The daily cleanup did the same to
|
|
218
|
+
a turn that happened to be running then. The cleanup now knows both Claude lifecycles.
|
|
219
|
+
|
|
220
|
+
**After a restart, a usage limit that ended a turn while the bot was down no longer keeps the account marked limited for a day.** When the
|
|
221
|
+
restarted bot read that limit error from what the agent wrote during the downtime, it worked out a reset named by its clock
|
|
222
|
+
("resets 10:20am") from the moment it read the error, not from the moment the error happened: a window that had closed half an
|
|
223
|
+
hour before was taken as closing tomorrow, and the account stayed limited — shown so on `/limits`, passed over by the account
|
|
224
|
+
switch — for up to a day. The reset is now worked out from the time the agent's transcript recorded the error.
|
|
225
|
+
|
|
226
|
+
**A working agent now hears of another topic's todo change in the middle of its turn.** Claude gets the project
|
|
227
|
+
board's changes with the result of its next tool call (a `PostToolUse` hook in the settings file the bot starts every
|
|
228
|
+
Claude session with), OpenCode as a queued message it reads between steps; an idle or sleeping agent is never woken
|
|
229
|
+
for it.
|
|
230
|
+
|
|
231
|
+
**The agents of one repository now see each other's todo lists.** Topics on checkouts or worktrees of the same git
|
|
232
|
+
repository form a project, and every prompt an agent gets carries the project board — the whole of it on a fresh
|
|
233
|
+
context, later only what changed in the other topics — as does its own `todo_update`; another topic's change never
|
|
234
|
+
wakes an agent. `/todo` → Project ▸ joins another topic's project or keeps an own one, `/todo` in General lists every
|
|
235
|
+
project, and Jira conversations share a board with the topics on the repositories their `jira.json` project lists in
|
|
236
|
+
the new `repos` key.
|
|
237
|
+
|
|
238
|
+
**An agent that works for an hour without updating its todo list is reminded to.** The next prompt it gets carries
|
|
239
|
+
one line; an agent that keeps working on its own gets a short prompt of its own at the end of a turn — never into a
|
|
240
|
+
running turn, a sleeping session, an unanswered request, a usage limit or an account billed to API credits — and the
|
|
241
|
+
bot falls silent after two ignored reminders. `/todo` in General → Settings turns the lists off or sets the interval
|
|
242
|
+
(off, 30 min, 1 h, 2 h, 4 h); an instance without General sets `todo` in `settings.json`.
|
|
243
|
+
|
|
244
|
+
**Agents publish what they work on, and `/todo` shows it.** Every topic's agent now keeps a short published todo list
|
|
245
|
+
— in work, the queue in order, done — through a new bot tool, adding an item before it starts a task and closing it
|
|
246
|
+
when it is done; `/todo` in a topic shows the list. It belongs to the topic, so `/new`, `/quit`, a backend switch and
|
|
247
|
+
a restart keep it, and a final answer while the list still shows unfinished work reminds the agent to update it. Jira
|
|
248
|
+
conversations publish the same way.
|
|
249
|
+
|
|
250
|
+
**Voice notes with pauses no longer lose phrases.** The local recognition (GigaAM) now cuts every voice at its pauses and
|
|
251
|
+
recognises the parts separately, so a phrase said after a pause is no longer dropped or merged into the previous one
|
|
252
|
+
(for example, "…купи хлеб? … и ещё молоко" could come out as just "…купи хлеб"). Nothing is cut away: the parts cover the whole
|
|
253
|
+
voice. After this update the local engine re-installs itself once (about a minute, the model is not downloaded again, the
|
|
254
|
+
progress shows in General); a voice sent meanwhile goes to the next engine in your list, or, with no other engine, the bot
|
|
255
|
+
asks you to send it again when the engine is ready.
|
|
256
|
+
|
|
257
|
+
**Voice notes from different topics are transcribed in the order they were sent.** The local recognition used to let
|
|
258
|
+
a short voice jump ahead of a longer one sent before it from another topic; now each voice waits its turn, and the bot
|
|
259
|
+
waits for it as long as its turn takes instead of giving up after the time its own length needs. A voice the bot has
|
|
260
|
+
stopped waiting for is no longer recognised in vain.
|
|
261
|
+
|
|
262
|
+
**Agents now launch workers on the Claude account whose weekly limit resets soonest, keep a resumed worker on its own account, and move a worker stopped by a limit to another account at once.**
|
|
263
|
+
Before, a worker (or a topic whose account hit its limit, with no `/limits_autoswitch` list) went to the account with the most room left, so an account about to
|
|
264
|
+
expire its week unused sat idle while the one with a fresh week took the work. Now a new worker starts on the usable account that resets its weekly window
|
|
265
|
+
first (an account whose five-hour window is at 90 % or more waits; Fable's own window takes out only Fable), a resumed worker stays on the account it
|
|
266
|
+
ran on, and one that broke off on a usage limit is resumed on another account straight away instead of waiting. When no account is usable the answer says
|
|
267
|
+
which one frees up first and when, so the manager schedules a single resume for that moment; when no account can say when it frees up, the manager asks you
|
|
268
|
+
and tries again in about half an hour. An account switched off in `/limits_autoswitch` is never picked
|
|
269
|
+
for a new worker, and one billed to API credits never is either. `charness claude-profiles` takes `--current <name>` and `--stopped-by-limit` for the same,
|
|
270
|
+
and a topic stopped by a limit with no list of its own now moves to the account that resets soonest rather than the roomiest.
|
|
271
|
+
|
|
5
272
|
## 3.6.1 — 2026-10-26
|
|
6
273
|
|
|
7
274
|
**An agent @-mentioned on a Jira issue that is already assigned to it no longer asks to be assigned.** When the issue
|
package/DEVELOPMENT.md
CHANGED
|
@@ -13,7 +13,7 @@ The per-topic folder layout is in [SETUP.md](SETUP.md) under
|
|
|
13
13
|
Routing key is `(chatId, threadId)` everywhere. Per-thread state lives in
|
|
14
14
|
`${DATA_DIR}/state.json` (atomic writes with `fsync`, archived on
|
|
15
15
|
corruption). Bot-owned tmux sessions are named per backend —
|
|
16
|
-
`claude-<chatId>-<threadId>` (Claude tmux-scrape), `cjson-…` (the Claude
|
|
16
|
+
`claude-<chatId>-<threadId>` (Claude tmux-scrape, deprecated), `cjson-…` (the Claude
|
|
17
17
|
json-stream host process), `term-…` (terminal) — see
|
|
18
18
|
`src/utils/tmuxSessionName.ts`; opencode sessions are keyed by the same
|
|
19
19
|
`<chatId>:<threadId>` string. Two topics on the same folder stay independent.
|
|
@@ -27,7 +27,7 @@ tracker or Teams surface means adding a directory under `src/connectors/`, not
|
|
|
27
27
|
editing the core.
|
|
28
28
|
|
|
29
29
|
```
|
|
30
|
-
Telegram <-> connectors/telegram/ <-> bot.ts <-> AgentAdapter <-> { Claude CLI (tmux scrape) |
|
|
30
|
+
Telegram <-> connectors/telegram/ <-> bot.ts <-> AgentAdapter <-> { Claude CLI (tmux scrape, deprecated) |
|
|
31
31
|
inbound.ts (core) │ Claude CLI (stream-json) |
|
|
32
32
|
outbound.ts + output/ │ │ OpenCode (HTTP+SSE) |
|
|
33
33
|
sessionKeyCodec.ts │ │ Terminal ($SHELL in tmux) }
|
|
@@ -104,6 +104,17 @@ keep when touching the restart path:
|
|
|
104
104
|
sends `SIGUSR2` — only when pid and start token match. The supervisor stops `tsc -w` and nodemon, leaves the OpenCode
|
|
105
105
|
server and the speech sidecar alone and `execve`s `cli.js hot`. A supervisor that predates this has no record and is
|
|
106
106
|
never signalled (an unhandled `SIGUSR2` kills a process).
|
|
107
|
+
- **The hot supervisor guards its watcher** (`cli/tscWatchGuard.ts`). `tsc -w` learns of a changed source only from file-system
|
|
108
|
+
events, and a burst — a pull of dozens of commits, then `yarn install` — overflows the inotify queue (`max_queued_events`,
|
|
109
|
+
16384) while the compiler is busy: the dropped events leave the watcher with the OLD text of the files it missed (errors where an
|
|
110
|
+
old definition meets new callers, or a clean report that emitted nothing); `touch tsconfig.json` re-reads none of them, only a
|
|
111
|
+
new `tsc -w` does, and the worker keeps running the old build. Every 30 s the supervisor compares the idle watcher with the
|
|
112
|
+
tree: a compiled source (`selfUpdate/emittedSource.ts`) a minute newer than its `dist/` output is a missed change — with "0
|
|
113
|
+
errors" the WATCHER (not the supervisor, not the worker) is restarted at once, with errors a one-shot `tsc --noEmit` decides
|
|
114
|
+
(clean there = the watcher is wrong). At most 3 restarts an hour, then it only says so; and a set of sources a restarted watcher still
|
|
115
|
+
leaves newer than their output (a modification time in the future, a path `tsconfig.json` excludes that `emittedSource.ts` does not know —
|
|
116
|
+
`emittedSource.test.ts` keeps the two lists equal) is reported once and not restarted for again. The flow `selfUpdateHotE2e` freezes the
|
|
117
|
+
real `tsc -w`, overflows the queue and replaces a source: the change must still reach `dist/`.
|
|
107
118
|
- **`update-pending.json` is written BEFORE the switch**; every boot counts itself in (`cli/bot.ts`, once the instance lock is held and before the bot
|
|
108
119
|
module is imported), the boot after two unconfirmed ones rolls back, the running bot confirms 60 s after launch.
|
|
109
120
|
|
|
@@ -139,6 +150,18 @@ To run your checkout as the global `charness` command instead of the npm package
|
|
|
139
150
|
without re-installing; `npm install -g .` installs a copy instead. Configuration and launch are as in
|
|
140
151
|
[SETUP.md](SETUP.md).
|
|
141
152
|
|
|
153
|
+
`yarn test:unit` also runs the STT sidecar's Python tests (`sttSidecarPython.test.ts` → `stt/test_gigaam_sidecar.py`,
|
|
154
|
+
no model needed). They want **`uv`** (an ephemeral environment with numpy and the pinned soundfile and av; the first run
|
|
155
|
+
downloads them, so it needs the network once) or a **`python3` that has numpy, soundfile and av**. Without either, or when
|
|
156
|
+
`uv` cannot reach the package index, a local run skips that test and says why; CI (`CI=true`, uv installed by the
|
|
157
|
+
workflow) fails instead.
|
|
158
|
+
|
|
159
|
+
The `charness remote-run` flow (two files that run side by side, each with a runner of its own — `remoteRunE2e.test.ts`, `remoteRunLifecycleE2e.test.ts`; the shared helpers are `remoteRunE2e/remoteRunFlowHarness.ts`) drives the built CLI against a throwaway loopback `sshd` (no root), `rsync` and a
|
|
160
|
+
private **Pueue** in temp dirs. It wants `sshd` (`openssh-server`), `ssh`, `rsync`, `pueue` / `pueued` 4.x on `PATH` and `yarn build`;
|
|
161
|
+
a local run without them is skipped with the reason, CI (`CI=true`) installs them (the workflow pins Pueue by checksum) and fails
|
|
162
|
+
without. A flow that is killed or times out cannot leave daemons behind: `remoteRunE2e/remoteRunFlowSweep.ts` ends what names its
|
|
163
|
+
layout, from the teardown, from a detached reaper and at the next start.
|
|
164
|
+
|
|
142
165
|
Node applies `--test-timeout` to a whole test FILE (a `describe`'s own `timeout` cannot extend it), so a file that
|
|
143
166
|
hangs or leaves a process alive fails by name when its limit passes, instead of hanging the run. A long-running
|
|
144
167
|
flow file must be named `*E2e.test.ts` to get the flows' limit; `live/*Live.test.ts` is run directly (CLAUDE.md).
|
|
@@ -148,10 +171,13 @@ not with the runner's bare timeout. Run one flow directly with `--test-timeout=<
|
|
|
148
171
|
|
|
149
172
|
A flow does not wait out the production windows in real time: its env file sets `CHARNESS_TEST_TIMINGS`, a JSON object
|
|
150
173
|
of named overrides (`src/testTimings.ts`: `telegramSendIntervalMs` — the global send pacer's 2 s, `jiraPollIntervalMs` —
|
|
151
|
-
below the 10 s floor of `jira.json`, `
|
|
152
|
-
minutes, `limitProbeDelayMs` — the two-minute probe of an unconfirmed usage limit, `stateSaveDebounceMs` — `state.json`'s
|
|
174
|
+
below the 10 s floor of `jira.json`, `requestTurnPollMs` — the wake-up engine's 10 s poll of the turns it watches,
|
|
175
|
+
`requestSweepIntervalMs` and `requestFirstPostRetryDelayMs` — the wake-up engine's minutes, `limitProbeDelayMs` — the two-minute probe of an unconfirmed usage limit, `stateSaveDebounceMs` — `state.json`'s
|
|
153
176
|
500 ms save debounce, `openCodeServerUpBudgetMs` — the OpenCode server's 60 s of retries, `backgroundHoldMaxMs` — the 6 h the
|
|
154
|
-
agent's own pending work holds a json-stream process
|
|
177
|
+
agent's own pending work holds a json-stream process, `todoReminderPollMs` and `todoReminderIntervalMs` — the todo
|
|
178
|
+
reminder's 10 s poll and the interval `settings.json` sets, `scheduleMinFireIntervalMs` — the 5 min minimum between cron fires, `bindPickerClaimLimit` — how many `/bind` picker claims are kept (a count: 200), `tscWatchCheckIntervalMs` and `tscWatchStaleGraceMs` — the
|
|
179
|
+
hot supervisor's 30 s check of its `tsc -w` and the minute a source may stay newer than its output; the supervisor reads these two, the bot the rest).
|
|
180
|
+
It is the ONE test-only timing seam,
|
|
155
181
|
never a setting: unset, every window is the production one; a value may only shorten its window (each key is capped at its
|
|
156
182
|
production value); set, the boot prints `[test-timings] … overrides active`, and
|
|
157
183
|
an unknown key or a bad value stops the start naming it.
|
|
@@ -20,7 +20,7 @@ start the bot renames the config and data dirs itself, see [Automatic migration]
|
|
|
20
20
|
| `~/.telegramCode` — the default `DATA_DIR` | `~/.charness` | used while `~/.charness` does not exist (or holds no `state.json` while the old dir does); an explicit `DATA_DIR` is never touched |
|
|
21
21
|
| `TELEGRAMCODE_HOT_RELOAD`, `TELEGRAMCODE_OPENCODE_PROCESS_FILE` | `CHARNESS_HOT_RELOAD`, `CHARNESS_OPENCODE_PROCESS_FILE` | read when the new one is unset; `charness hot` sets both |
|
|
22
22
|
| MCP header `x-telegramcode-mcp-client-id` | `x-charness-mcp-client-id` | the bot's MCP server accepts both |
|
|
23
|
-
| OpenCode plugin `telegramcode-compaction.js` (id `telegramcode-compaction`) | `charness-compaction
|
|
23
|
+
| OpenCode plugin `telegramcode-compaction.js` (id `telegramcode-compaction`) | `charness-compaction-<hash>.js` (id `charness-compaction`; the hash is of the plugin's text) | the old file is removed when the new one is installed |
|
|
24
24
|
| Docker image `telegramcode`, service `telegramcode`, container `telegramcode-main` | `charness`, `charness`, `charness-main` | a container of the old image keeps running as it is |
|
|
25
25
|
| `/opt/telegramcode`, `/home/telegramcode`, `/srv/telegramcode/…` (Docker mounts and host paths) | `/opt/charness`, `/home/charness`, `/srv/charness/…` | the new image's entrypoint accepts the old mount points |
|
|
26
26
|
| `telegramcode-restart-bot` | `charness-restart-bot` | the old name is a link in the new image and says so |
|
|
@@ -130,4 +130,5 @@ you next rebuild the image:
|
|
|
130
130
|
- `[deprecated] TELEGRAMCODE_HOT_RELOAD … the running charness hot supervisor still sets it`: restart the
|
|
131
131
|
supervisor (above).
|
|
132
132
|
- The OpenCode compaction plugin is reinstalled under its new name and the old file is deleted; a folder whose
|
|
133
|
-
OpenCode instance already loaded the old plugin
|
|
133
|
+
OpenCode instance already loaded the old plugin is recreated at the bot's next start when nothing runs in it
|
|
134
|
+
(a working one keeps the old plugin until a later start finds it idle).
|