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
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { type SessionKey } from '../sessionKey';
|
|
2
|
+
import type { TodoBoardChanges } from './board';
|
|
3
|
+
/**
|
|
4
|
+
* @description Mid-turn delivery of the project board (D21, D22): a working agent learns of another topic's change
|
|
5
|
+
* inside its turn, not only at its next prompt.
|
|
6
|
+
*
|
|
7
|
+
* Claude — a `PostToolUse` hook (no matcher) in the launch `--settings` file prints the conversation's INBOX file,
|
|
8
|
+
* `DATA_DIR/todos/inbox/<session id>.json`, after the agent's next tool call: ready hook JSON whose
|
|
9
|
+
* `additionalContext` Claude reads with that tool's result (probed on Claude Code 2.1.310). The hook
|
|
10
|
+
* moves the file before printing it, so a text is delivered once; with no file it prints nothing.
|
|
11
|
+
* OpenCode — a note queued INTO the running turn (`AgentAdapter.queueNoteIntoRunningTurn`: `prompt_async`, read
|
|
12
|
+
* between steps, with nothing of the turn reset), never while a provider retry is waited out.
|
|
13
|
+
*
|
|
14
|
+
* The bot writes the inbox (atomically) only while the session works (busy, its turn not held open) and something
|
|
15
|
+
* changed since the agent last saw it; the changes count as seen once the hook took the file (the next poll finds it
|
|
16
|
+
* gone). A waiting inbox is withdrawn wherever no tool call of the session can take it any more — a turn start the bot
|
|
17
|
+
* makes (that prompt carries the changes itself), a turn's end, a turn held open, the session's start, stop or end —
|
|
18
|
+
* and its changes stay unseen for the next prompt, so the inbox dir is empty between turns. A restart forgets what was
|
|
19
|
+
* written: at worst a change is delivered twice, never lost.
|
|
20
|
+
*/
|
|
21
|
+
/** What opens the note a running OpenCode turn reads (agent-facing English); the board's changes follow it. */
|
|
22
|
+
export declare const todoRunningTurnNoteHeader = "[Todo] Other topics of your project changed their lists while you work. No reply is needed.";
|
|
23
|
+
/** Claude Code caps a hook's `additionalContext`; the text is cut below it. */
|
|
24
|
+
export declare const todoInboxMaxChars = 10000;
|
|
25
|
+
/** @description Where the inboxes live: `DATA_DIR/todos/inbox`. */
|
|
26
|
+
export declare function getTodoInboxDir(dataDir: string): string;
|
|
27
|
+
/**
|
|
28
|
+
* @description The `PostToolUse` hook's shell command. With the inbox dir empty — nearly every tool call — it reads
|
|
29
|
+
* the input whole (the CLI must never write into a closed pipe) and exits; only while an inbox waits does it start
|
|
30
|
+
* `nodePath` (the bot's own, written at every launch) to parse the input ({@link inboxHookScript}). It always exits 0 —
|
|
31
|
+
* a hook failure must never stop the agent's tool.
|
|
32
|
+
*
|
|
33
|
+
* Only the MAIN agent takes the inbox. A sub-agent's tool call fires the hook too, with the SAME `session_id` and an
|
|
34
|
+
* `agent_id` of its own (measured on Claude Code 2.1.310); taken there, the changes would land in the sub-agent's
|
|
35
|
+
* context and count as seen while the main agent never got them.
|
|
36
|
+
*/
|
|
37
|
+
export declare function buildTodoInboxHookCommand(inboxDir: string, nodePath?: string): string;
|
|
38
|
+
/** @description The hook output Claude reads `text` from: `additionalContext` of a `PostToolUse` hook, within the cap. */
|
|
39
|
+
export declare function buildTodoInboxHookOutput(text: string): string;
|
|
40
|
+
/**
|
|
41
|
+
* @name TodoMidTurnDeps
|
|
42
|
+
* @description The board's peek and seen marks, the conversation's live Claude session (`null` = no Claude backend
|
|
43
|
+
* runs it), and the note into a running turn (`false` when the backend takes none, or the turn is not running now).
|
|
44
|
+
*/
|
|
45
|
+
export interface TodoMidTurnDeps {
|
|
46
|
+
board: {
|
|
47
|
+
peekChanges(key: SessionKey): TodoBoardChanges | null;
|
|
48
|
+
markSeenRevisions(key: SessionKey, revisions: Readonly<Record<string, number>>): void;
|
|
49
|
+
};
|
|
50
|
+
inboxDir: string;
|
|
51
|
+
getClaudeSessionId: (key: SessionKey) => string | null;
|
|
52
|
+
postRunningTurnNote: (key: SessionKey, text: string) => Promise<boolean>;
|
|
53
|
+
/** Whether a process runs (the hook that moved an inbox aside, run as the bot's own user); `kill(pid, 0)` by default. */
|
|
54
|
+
checkIsProcessAlive?: (pid: number) => boolean;
|
|
55
|
+
}
|
|
56
|
+
/** @name TodoMidTurn @description What the reminder poll and the prompt choke point call. */
|
|
57
|
+
export interface TodoMidTurn {
|
|
58
|
+
/** The session is busy: deliver what changed since the agent last saw the board, if anything did. */
|
|
59
|
+
deliverIfPending(key: SessionKey): Promise<void>;
|
|
60
|
+
/** Inboxes the hook took since the last look count as seen. */
|
|
61
|
+
reconcile(): void;
|
|
62
|
+
/**
|
|
63
|
+
* No tool call of the session can take its inbox any more (a turn start the bot makes, a turn's end, a turn held
|
|
64
|
+
* open, the session's start, stop or end): a waiting inbox is withdrawn — counted as seen if the hook took it
|
|
65
|
+
* meanwhile — and the copies hooks that are gone moved aside and never removed go with it.
|
|
66
|
+
*/
|
|
67
|
+
discardInbox(key: SessionKey): void;
|
|
68
|
+
/**
|
|
69
|
+
* At boot: every inbox left is withdrawn — this process does not know what it carries, and a session that ended
|
|
70
|
+
* never takes its own. What it carried is still unseen, so the next prompt (or poll) delivers it again.
|
|
71
|
+
*/
|
|
72
|
+
clearInboxes(): void;
|
|
73
|
+
}
|
|
74
|
+
export declare function createTodoMidTurn(deps: TodoMidTurnDeps): TodoMidTurn;
|
|
75
|
+
//# sourceMappingURL=midTurn.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"midTurn.d.ts","sourceRoot":"","sources":["../../src/todos/midTurn.ts"],"names":[],"mappings":"AAEA,OAAO,EAAe,KAAK,UAAU,EAAE,MAAM,eAAe,CAAC;AAI7D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAEhD;;;;;;;;;;;;;;;;;GAiBG;AAEH,+GAA+G;AAC/G,eAAO,MAAM,yBAAyB,gGAAgG,CAAC;AAIvI,+EAA+E;AAC/E,eAAO,MAAM,iBAAiB,QAAS,CAAC;AASxC,mEAAmE;AACnE,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAEvD;AAwBD;;;;;;;;;GASG;AACH,wBAAgB,yBAAyB,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,GAAE,MAAyB,GAAG,MAAM,CAOvG;AAED,0HAA0H;AAC1H,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAI7D;AAED;;;;GAIG;AACH,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE;QACL,WAAW,CAAC,GAAG,EAAE,UAAU,GAAG,gBAAgB,GAAG,IAAI,CAAC;QACtD,iBAAiB,CAAC,GAAG,EAAE,UAAU,EAAE,SAAS,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,GAAG,IAAI,CAAC;KACvF,CAAC;IACF,QAAQ,EAAE,MAAM,CAAC;IACjB,kBAAkB,EAAE,CAAC,GAAG,EAAE,UAAU,KAAK,MAAM,GAAG,IAAI,CAAC;IACvD,mBAAmB,EAAE,CAAC,GAAG,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IACzE,yHAAyH;IACzH,mBAAmB,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC;CAChD;AAGD,6FAA6F;AAC7F,MAAM,WAAW,WAAW;IAC1B,qGAAqG;IACrG,gBAAgB,CAAC,GAAG,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACjD,+DAA+D;IAC/D,SAAS,IAAI,IAAI,CAAC;IAClB;;;;OAIG;IACH,YAAY,CAAC,GAAG,EAAE,UAAU,GAAG,IAAI,CAAC;IACpC;;;OAGG;IACH,YAAY,IAAI,IAAI,CAAC;CACtB;AAeD,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,eAAe,GAAG,WAAW,CA6EpE"}
|
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.todoInboxMaxChars = exports.todoRunningTurnNoteHeader = void 0;
|
|
37
|
+
exports.getTodoInboxDir = getTodoInboxDir;
|
|
38
|
+
exports.buildTodoInboxHookCommand = buildTodoInboxHookCommand;
|
|
39
|
+
exports.buildTodoInboxHookOutput = buildTodoInboxHookOutput;
|
|
40
|
+
exports.createTodoMidTurn = createTodoMidTurn;
|
|
41
|
+
const fs = __importStar(require("fs"));
|
|
42
|
+
const path = __importStar(require("path"));
|
|
43
|
+
const sessionKey_1 = require("../sessionKey");
|
|
44
|
+
const jsonStreamHost_1 = require("../utils/jsonStreamHost");
|
|
45
|
+
const tmuxExec_1 = require("../utils/tmuxExec");
|
|
46
|
+
const store_1 = require("./store");
|
|
47
|
+
/**
|
|
48
|
+
* @description Mid-turn delivery of the project board (D21, D22): a working agent learns of another topic's change
|
|
49
|
+
* inside its turn, not only at its next prompt.
|
|
50
|
+
*
|
|
51
|
+
* Claude — a `PostToolUse` hook (no matcher) in the launch `--settings` file prints the conversation's INBOX file,
|
|
52
|
+
* `DATA_DIR/todos/inbox/<session id>.json`, after the agent's next tool call: ready hook JSON whose
|
|
53
|
+
* `additionalContext` Claude reads with that tool's result (probed on Claude Code 2.1.310). The hook
|
|
54
|
+
* moves the file before printing it, so a text is delivered once; with no file it prints nothing.
|
|
55
|
+
* OpenCode — a note queued INTO the running turn (`AgentAdapter.queueNoteIntoRunningTurn`: `prompt_async`, read
|
|
56
|
+
* between steps, with nothing of the turn reset), never while a provider retry is waited out.
|
|
57
|
+
*
|
|
58
|
+
* The bot writes the inbox (atomically) only while the session works (busy, its turn not held open) and something
|
|
59
|
+
* changed since the agent last saw it; the changes count as seen once the hook took the file (the next poll finds it
|
|
60
|
+
* gone). A waiting inbox is withdrawn wherever no tool call of the session can take it any more — a turn start the bot
|
|
61
|
+
* makes (that prompt carries the changes itself), a turn's end, a turn held open, the session's start, stop or end —
|
|
62
|
+
* and its changes stay unseen for the next prompt, so the inbox dir is empty between turns. A restart forgets what was
|
|
63
|
+
* written: at worst a change is delivered twice, never lost.
|
|
64
|
+
*/
|
|
65
|
+
/** What opens the note a running OpenCode turn reads (agent-facing English); the board's changes follow it. */
|
|
66
|
+
exports.todoRunningTurnNoteHeader = '[Todo] Other topics of your project changed their lists while you work. No reply is needed.';
|
|
67
|
+
/** The inbox directory under the store's. */
|
|
68
|
+
const inboxDirName = 'inbox';
|
|
69
|
+
/** Claude Code caps a hook's `additionalContext`; the text is cut below it. */
|
|
70
|
+
exports.todoInboxMaxChars = 10_000;
|
|
71
|
+
/** A session id names a file: only these characters, so no id can reach outside the inbox. */
|
|
72
|
+
const sessionIdRe = /^[A-Za-z0-9_-]+$/;
|
|
73
|
+
const inboxFileExtension = '.json';
|
|
74
|
+
/** A copy the hook moved aside: `<session id>.json.<the hook's process id>` (never the bot's `….tmp`). */
|
|
75
|
+
const takenCopyNameRe = /^[A-Za-z0-9_-]+\.json\.(\d+)$/;
|
|
76
|
+
/** Private: what the agents work on. */
|
|
77
|
+
const inboxFileMode = 0o600;
|
|
78
|
+
/** @description Where the inboxes live: `DATA_DIR/todos/inbox`. */
|
|
79
|
+
function getTodoInboxDir(dataDir) {
|
|
80
|
+
return path.join((0, store_1.getTodosDir)(dataDir), inboxDirName);
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* The parse of a hook input, run by the bot's own `node` with the inbox dir as its argument: the input's TOP-LEVEL
|
|
84
|
+
* fields alone decide, in whatever order they come — a tool's own input or output naming `agent_id` or `session_id`
|
|
85
|
+
* is never mistaken for them. A sub-agent's call (an `agent_id`) and an id outside {@link sessionIdRe} print nothing;
|
|
86
|
+
* otherwise the session's inbox is moved aside, printed and removed.
|
|
87
|
+
*/
|
|
88
|
+
const inboxHookScript = [
|
|
89
|
+
'const fs = require("fs"), path = require("path");',
|
|
90
|
+
'let text = "";',
|
|
91
|
+
'process.stdin.setEncoding("utf8").on("data", (chunk) => { text += chunk; }).on("end", () => {',
|
|
92
|
+
' try {',
|
|
93
|
+
' const input = JSON.parse(text);',
|
|
94
|
+
' if (input === null || typeof input !== "object" || "agent_id" in input) return;',
|
|
95
|
+
` if (typeof input.session_id !== "string" || !${sessionIdRe.toString()}.test(input.session_id)) return;`,
|
|
96
|
+
` const file = path.join(process.argv[1], input.session_id + "${inboxFileExtension}"), taken = file + "." + process.pid;`,
|
|
97
|
+
' try { fs.renameSync(file, taken); } catch { return; }',
|
|
98
|
+
' process.stdout.write(fs.readFileSync(taken, "utf8"));',
|
|
99
|
+
' fs.rmSync(taken, { force: true });',
|
|
100
|
+
' } catch {}',
|
|
101
|
+
'});',
|
|
102
|
+
].join(' ');
|
|
103
|
+
/**
|
|
104
|
+
* @description The `PostToolUse` hook's shell command. With the inbox dir empty — nearly every tool call — it reads
|
|
105
|
+
* the input whole (the CLI must never write into a closed pipe) and exits; only while an inbox waits does it start
|
|
106
|
+
* `nodePath` (the bot's own, written at every launch) to parse the input ({@link inboxHookScript}). It always exits 0 —
|
|
107
|
+
* a hook failure must never stop the agent's tool.
|
|
108
|
+
*
|
|
109
|
+
* Only the MAIN agent takes the inbox. A sub-agent's tool call fires the hook too, with the SAME `session_id` and an
|
|
110
|
+
* `agent_id` of its own (measured on Claude Code 2.1.310); taken there, the changes would land in the sub-agent's
|
|
111
|
+
* context and count as seen while the main agent never got them.
|
|
112
|
+
*/
|
|
113
|
+
function buildTodoInboxHookCommand(inboxDir, nodePath = process.execPath) {
|
|
114
|
+
const dir = (0, tmuxExec_1.shellSingleQuote)(inboxDir);
|
|
115
|
+
return [
|
|
116
|
+
`[ -n "$(ls -A ${dir} 2>/dev/null)" ] || { cat > /dev/null; exit 0; }`,
|
|
117
|
+
`${(0, tmuxExec_1.shellSingleQuote)(nodePath)} -e ${(0, tmuxExec_1.shellSingleQuote)(inboxHookScript)} ${dir}`,
|
|
118
|
+
'exit 0',
|
|
119
|
+
].join('; ');
|
|
120
|
+
}
|
|
121
|
+
/** @description The hook output Claude reads `text` from: `additionalContext` of a `PostToolUse` hook, within the cap. */
|
|
122
|
+
function buildTodoInboxHookOutput(text) {
|
|
123
|
+
const characters = [...text];
|
|
124
|
+
const fitted = characters.length <= exports.todoInboxMaxChars ? text : `${characters.slice(0, exports.todoInboxMaxChars - 1).join('')}…`;
|
|
125
|
+
return JSON.stringify({ hookSpecificOutput: { hookEventName: 'PostToolUse', additionalContext: fitted } });
|
|
126
|
+
}
|
|
127
|
+
/** @description Whether two revision maps name the same peers at the same revisions. */
|
|
128
|
+
function checkIsSameRevisions(left, right) {
|
|
129
|
+
const leftEntries = Object.entries(left);
|
|
130
|
+
return leftEntries.length === Object.keys(right).length && leftEntries.every(([conversationKey, revision]) => right[conversationKey] === revision);
|
|
131
|
+
}
|
|
132
|
+
function createTodoMidTurn(deps) {
|
|
133
|
+
const { board, inboxDir, getClaudeSessionId, postRunningTurnNote, checkIsProcessAlive = jsonStreamHost_1.checkIsPidAlive } = deps;
|
|
134
|
+
const pendingInboxes = new Map();
|
|
135
|
+
function reconcileOne(conversationKey, pending) {
|
|
136
|
+
if (fs.existsSync(pending.filePath))
|
|
137
|
+
return;
|
|
138
|
+
pendingInboxes.delete(conversationKey);
|
|
139
|
+
board.markSeenRevisions(pending.key, pending.revisions);
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* A copy the hook moved aside and never removed (its `node` ended between the move and the removal) would keep the
|
|
143
|
+
* inbox dir non-empty until boot. Any session's copy goes — but only once the hook that moved it is gone: a live one
|
|
144
|
+
* may be reading it this very moment, and its change already counts as seen.
|
|
145
|
+
*/
|
|
146
|
+
function removeTakenLeftovers() {
|
|
147
|
+
let names;
|
|
148
|
+
try {
|
|
149
|
+
names = fs.readdirSync(inboxDir);
|
|
150
|
+
}
|
|
151
|
+
catch {
|
|
152
|
+
return;
|
|
153
|
+
}
|
|
154
|
+
for (const name of names) {
|
|
155
|
+
const hookPid = takenCopyNameRe.exec(name)?.[1];
|
|
156
|
+
if (hookPid !== undefined && !checkIsProcessAlive(Number(hookPid)))
|
|
157
|
+
fs.rmSync(path.join(inboxDir, name), { force: true });
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
function writeInbox(filePath, text) {
|
|
161
|
+
fs.mkdirSync(path.dirname(filePath), { recursive: true, mode: 0o700 });
|
|
162
|
+
const tempPath = `${filePath}.${process.pid}.tmp`;
|
|
163
|
+
fs.writeFileSync(tempPath, buildTodoInboxHookOutput(text), { mode: inboxFileMode });
|
|
164
|
+
fs.renameSync(tempPath, filePath);
|
|
165
|
+
}
|
|
166
|
+
return {
|
|
167
|
+
async deliverIfPending(key) {
|
|
168
|
+
const conversationKey = (0, sessionKey_1.keyToString)(key);
|
|
169
|
+
const pending = pendingInboxes.get(conversationKey);
|
|
170
|
+
if (pending)
|
|
171
|
+
reconcileOne(conversationKey, pending);
|
|
172
|
+
const changes = board.peekChanges(key);
|
|
173
|
+
if (changes === null)
|
|
174
|
+
return;
|
|
175
|
+
const sessionId = getClaudeSessionId(key);
|
|
176
|
+
if (sessionId === null) {
|
|
177
|
+
// Seen only once the note is in: a refused one (no running turn, a provider retry) waits for the next poll.
|
|
178
|
+
if (await postRunningTurnNote(key, `${exports.todoRunningTurnNoteHeader}\n\n${changes.text}`))
|
|
179
|
+
board.markSeenRevisions(key, changes.revisions);
|
|
180
|
+
return;
|
|
181
|
+
}
|
|
182
|
+
if (!sessionIdRe.test(sessionId))
|
|
183
|
+
return;
|
|
184
|
+
const waiting = pendingInboxes.get(conversationKey);
|
|
185
|
+
// The same changes already wait for the agent's next tool call.
|
|
186
|
+
if (waiting && checkIsSameRevisions(waiting.revisions, changes.revisions))
|
|
187
|
+
return;
|
|
188
|
+
const filePath = path.join(inboxDir, `${sessionId}${inboxFileExtension}`);
|
|
189
|
+
writeInbox(filePath, changes.text);
|
|
190
|
+
pendingInboxes.set(conversationKey, { key, filePath, revisions: changes.revisions });
|
|
191
|
+
},
|
|
192
|
+
reconcile() {
|
|
193
|
+
for (const [conversationKey, pending] of pendingInboxes)
|
|
194
|
+
reconcileOne(conversationKey, pending);
|
|
195
|
+
},
|
|
196
|
+
clearInboxes() {
|
|
197
|
+
pendingInboxes.clear();
|
|
198
|
+
fs.rmSync(inboxDir, { recursive: true, force: true });
|
|
199
|
+
},
|
|
200
|
+
discardInbox(key) {
|
|
201
|
+
removeTakenLeftovers();
|
|
202
|
+
const conversationKey = (0, sessionKey_1.keyToString)(key);
|
|
203
|
+
const pending = pendingInboxes.get(conversationKey);
|
|
204
|
+
if (!pending)
|
|
205
|
+
return;
|
|
206
|
+
reconcileOne(conversationKey, pending);
|
|
207
|
+
if (!pendingInboxes.has(conversationKey))
|
|
208
|
+
return;
|
|
209
|
+
pendingInboxes.delete(conversationKey);
|
|
210
|
+
fs.rmSync(pending.filePath, { force: true });
|
|
211
|
+
},
|
|
212
|
+
};
|
|
213
|
+
}
|
|
214
|
+
//# sourceMappingURL=midTurn.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"midTurn.js","sourceRoot":"","sources":["../../src/todos/midTurn.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @description The staleness reminder of the todo registry (D10–D14), as pure decisions — modelled on
|
|
3
|
+
* `getIdleFireDecision`: every "no" names its reasons, so a log line says why nothing fired.
|
|
4
|
+
*
|
|
5
|
+
* stale = the agent WORKED (its session reported busy) for ≥ the interval since its last `todo_update`; the clock
|
|
6
|
+
* starts at the first turn end after that update, so a topic quiet for days is not reminded on its first turn
|
|
7
|
+
* form a — a reminder line on the next prompt the conversation gets, from any source (no extra turn)
|
|
8
|
+
* form b — a standalone technical prompt at a turn end, only when nothing else would reach the agent and every gate
|
|
9
|
+
* of D12 holds (live, idle, nothing holding the turn, nothing unread, no open request, no answer tail, not
|
|
10
|
+
* limited, not billed to API credits)
|
|
11
|
+
* after 2 reminders in a row with no update the bot stays silent until the agent updates or a person writes
|
|
12
|
+
*/
|
|
13
|
+
/** The reminder interval nobody chose (D10). */
|
|
14
|
+
export declare const todoReminderDefaultMinutes = 60;
|
|
15
|
+
/** The intervals General offers; `0` is "off". */
|
|
16
|
+
export declare const todoReminderOffMinutes = 0;
|
|
17
|
+
export declare const todoReminderMinuteOptions: readonly number[];
|
|
18
|
+
/** After this many reminders in a row with no update the bot stays silent (D13). */
|
|
19
|
+
export declare const todoReminderMaxIgnored = 2;
|
|
20
|
+
/**
|
|
21
|
+
* @name TodoNagState
|
|
22
|
+
* @description The reminder's bookkeeping of a conversation, persisted with its list. `clockStartedAt` = the first
|
|
23
|
+
* turn end after the last update (absent until then); `workedMs` = the busy time since; `ignoredCount` = reminders
|
|
24
|
+
* delivered in a row with no update.
|
|
25
|
+
*/
|
|
26
|
+
export interface TodoNagState {
|
|
27
|
+
clockStartedAt?: number;
|
|
28
|
+
workedMs: number;
|
|
29
|
+
ignoredCount: number;
|
|
30
|
+
lastRemindedAt?: number;
|
|
31
|
+
}
|
|
32
|
+
/** @name TodoReminderSettings @description The instance's settings, defaults filled in (`settings.json` `todo`). */
|
|
33
|
+
export interface TodoReminderSettings {
|
|
34
|
+
isEnabled: boolean;
|
|
35
|
+
/** `0` = the reminder is off. */
|
|
36
|
+
reminderMinutes: number;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* @name TodoStandaloneGate
|
|
40
|
+
* @description What a standalone reminder (form b) needs to hold at a turn end (D12). The first four are the
|
|
41
|
+
* wake-up engine's turn probe.
|
|
42
|
+
*/
|
|
43
|
+
export interface TodoStandaloneGate {
|
|
44
|
+
isActive: boolean;
|
|
45
|
+
isBusy: boolean;
|
|
46
|
+
isTurnEndBlocked: boolean;
|
|
47
|
+
hasUnconsumedInput: boolean | null;
|
|
48
|
+
hasOpenRequest: boolean;
|
|
49
|
+
/** The agent's text after a final answer is being followed (`requests/answerTail.ts`). */
|
|
50
|
+
isAnswerTailFollowed: boolean;
|
|
51
|
+
/** The account or model the conversation runs on is marked limited. */
|
|
52
|
+
isLimited: boolean;
|
|
53
|
+
/** The conversation runs on an account billed to API credits: never spend money unasked. */
|
|
54
|
+
isApiBilled: boolean;
|
|
55
|
+
/** The backend stops the process after every turn (the per-turn lifecycle): the session sleeps now. */
|
|
56
|
+
isStoppingAfterTurn: boolean;
|
|
57
|
+
}
|
|
58
|
+
/** @description What the reminder decided: the text to deliver, or why not. */
|
|
59
|
+
export type TodoReminderDecision = {
|
|
60
|
+
shouldRemind: true;
|
|
61
|
+
} | {
|
|
62
|
+
shouldRemind: false;
|
|
63
|
+
skipReasons: string[];
|
|
64
|
+
};
|
|
65
|
+
/** @description The bookkeeping right after an update: nothing worked, nobody reminded, the clock not started. */
|
|
66
|
+
export declare function createTodoNagState(): TodoNagState;
|
|
67
|
+
/** @description `nag` with `elapsedMs` of busy time added — counted only once the clock started. */
|
|
68
|
+
export declare function getTodoNagStateWithWork(nag: TodoNagState, elapsedMs: number): TodoNagState;
|
|
69
|
+
/** @description `nag` at a turn end: the clock starts at the first one after the update. */
|
|
70
|
+
export declare function getTodoNagStateAtTurnEnd(nag: TodoNagState, nowMs: number): TodoNagState;
|
|
71
|
+
/** @description `nag` after a reminder reached the agent: the work counts afresh, one more ignored until it updates. */
|
|
72
|
+
export declare function getTodoNagStateAfterReminder(nag: TodoNagState, nowMs: number): TodoNagState;
|
|
73
|
+
/** @description `nag` after a person wrote in the conversation: the silence after ignored reminders ends (D13). */
|
|
74
|
+
export declare function getTodoNagStateAfterPersonActivity(nag: TodoNagState): TodoNagState;
|
|
75
|
+
/** @description The interval in ms, or `null` when the reminder is off. `overrideMs` is the test-only timing seam. */
|
|
76
|
+
export declare function getTodoReminderIntervalMs(settings: TodoReminderSettings, overrideMs: number | undefined): number | null;
|
|
77
|
+
/** @description Whether the agent worked the whole interval since its last update (the reminder is due, gates aside). */
|
|
78
|
+
export declare function checkIsTodoNagStale(nag: TodoNagState, intervalMs: number | null): boolean;
|
|
79
|
+
/** @description Form a: whether the next prompt carries the reminder line. */
|
|
80
|
+
export declare function decidePromptTodoReminder(nag: TodoNagState, intervalMs: number | null): TodoReminderDecision;
|
|
81
|
+
/** @description Form b: whether a standalone reminder goes out at this turn end (D12). */
|
|
82
|
+
export declare function decideStandaloneTodoReminder(nag: TodoNagState, intervalMs: number | null, gate: TodoStandaloneGate): TodoReminderDecision;
|
|
83
|
+
/** @description The agent-facing reminder (D14): factual, asks for no text reply. */
|
|
84
|
+
export declare function buildTodoReminderText(lastUpdateAt: number | undefined, nowMs: number): string;
|
|
85
|
+
//# sourceMappingURL=nag.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"nag.d.ts","sourceRoot":"","sources":["../../src/todos/nag.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,gDAAgD;AAChD,eAAO,MAAM,0BAA0B,KAAK,CAAC;AAC7C,kDAAkD;AAClD,eAAO,MAAM,sBAAsB,IAAI,CAAC;AACxC,eAAO,MAAM,yBAAyB,EAAE,SAAS,MAAM,EAA+C,CAAC;AACvG,oFAAoF;AACpF,eAAO,MAAM,sBAAsB,IAAI,CAAC;AAGxC;;;;;GAKG;AACH,MAAM,WAAW,YAAY;IAC3B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,oHAAoH;AACpH,MAAM,WAAW,oBAAoB;IACnC,SAAS,EAAE,OAAO,CAAC;IACnB,iCAAiC;IACjC,eAAe,EAAE,MAAM,CAAC;CACzB;AAED;;;;GAIG;AACH,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,OAAO,CAAC;IAClB,MAAM,EAAE,OAAO,CAAC;IAChB,gBAAgB,EAAE,OAAO,CAAC;IAC1B,kBAAkB,EAAE,OAAO,GAAG,IAAI,CAAC;IACnC,cAAc,EAAE,OAAO,CAAC;IACxB,0FAA0F;IAC1F,oBAAoB,EAAE,OAAO,CAAC;IAC9B,uEAAuE;IACvE,SAAS,EAAE,OAAO,CAAC;IACnB,4FAA4F;IAC5F,WAAW,EAAE,OAAO,CAAC;IACrB,uGAAuG;IACvG,mBAAmB,EAAE,OAAO,CAAC;CAC9B;AAED,+EAA+E;AAC/E,MAAM,MAAM,oBAAoB,GAAG;IAAE,YAAY,EAAE,IAAI,CAAA;CAAE,GAAG;IAAE,YAAY,EAAE,KAAK,CAAC;IAAC,WAAW,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC;AAE3G,kHAAkH;AAClH,wBAAgB,kBAAkB,IAAI,YAAY,CAEjD;AAED,oGAAoG;AACpG,wBAAgB,uBAAuB,CAAC,GAAG,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,GAAG,YAAY,CAG1F;AAED,4FAA4F;AAC5F,wBAAgB,wBAAwB,CAAC,GAAG,EAAE,YAAY,EAAE,KAAK,EAAE,MAAM,GAAG,YAAY,CAEvF;AAED,wHAAwH;AACxH,wBAAgB,4BAA4B,CAAC,GAAG,EAAE,YAAY,EAAE,KAAK,EAAE,MAAM,GAAG,YAAY,CAE3F;AAED,mHAAmH;AACnH,wBAAgB,kCAAkC,CAAC,GAAG,EAAE,YAAY,GAAG,YAAY,CAElF;AAED,sHAAsH;AACtH,wBAAgB,yBAAyB,CAAC,QAAQ,EAAE,oBAAoB,EAAE,UAAU,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,IAAI,CAGvH;AAED,yHAAyH;AACzH,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,GAAG,IAAI,GAAG,OAAO,CAEzF;AAYD,8EAA8E;AAC9E,wBAAgB,wBAAwB,CAAC,GAAG,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,GAAG,IAAI,GAAG,oBAAoB,CAG3G;AAED,0FAA0F;AAC1F,wBAAgB,4BAA4B,CAAC,GAAG,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,GAAG,IAAI,EAAE,IAAI,EAAE,kBAAkB,GAAG,oBAAoB,CAczI;AAED,qFAAqF;AACrF,wBAAgB,qBAAqB,CAAC,YAAY,EAAE,MAAM,GAAG,SAAS,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAK7F"}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* @description The staleness reminder of the todo registry (D10–D14), as pure decisions — modelled on
|
|
4
|
+
* `getIdleFireDecision`: every "no" names its reasons, so a log line says why nothing fired.
|
|
5
|
+
*
|
|
6
|
+
* stale = the agent WORKED (its session reported busy) for ≥ the interval since its last `todo_update`; the clock
|
|
7
|
+
* starts at the first turn end after that update, so a topic quiet for days is not reminded on its first turn
|
|
8
|
+
* form a — a reminder line on the next prompt the conversation gets, from any source (no extra turn)
|
|
9
|
+
* form b — a standalone technical prompt at a turn end, only when nothing else would reach the agent and every gate
|
|
10
|
+
* of D12 holds (live, idle, nothing holding the turn, nothing unread, no open request, no answer tail, not
|
|
11
|
+
* limited, not billed to API credits)
|
|
12
|
+
* after 2 reminders in a row with no update the bot stays silent until the agent updates or a person writes
|
|
13
|
+
*/
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.todoReminderMaxIgnored = exports.todoReminderMinuteOptions = exports.todoReminderOffMinutes = exports.todoReminderDefaultMinutes = void 0;
|
|
16
|
+
exports.createTodoNagState = createTodoNagState;
|
|
17
|
+
exports.getTodoNagStateWithWork = getTodoNagStateWithWork;
|
|
18
|
+
exports.getTodoNagStateAtTurnEnd = getTodoNagStateAtTurnEnd;
|
|
19
|
+
exports.getTodoNagStateAfterReminder = getTodoNagStateAfterReminder;
|
|
20
|
+
exports.getTodoNagStateAfterPersonActivity = getTodoNagStateAfterPersonActivity;
|
|
21
|
+
exports.getTodoReminderIntervalMs = getTodoReminderIntervalMs;
|
|
22
|
+
exports.checkIsTodoNagStale = checkIsTodoNagStale;
|
|
23
|
+
exports.decidePromptTodoReminder = decidePromptTodoReminder;
|
|
24
|
+
exports.decideStandaloneTodoReminder = decideStandaloneTodoReminder;
|
|
25
|
+
exports.buildTodoReminderText = buildTodoReminderText;
|
|
26
|
+
/** The reminder interval nobody chose (D10). */
|
|
27
|
+
exports.todoReminderDefaultMinutes = 60;
|
|
28
|
+
/** The intervals General offers; `0` is "off". */
|
|
29
|
+
exports.todoReminderOffMinutes = 0;
|
|
30
|
+
exports.todoReminderMinuteOptions = [exports.todoReminderOffMinutes, 30, 60, 120, 240];
|
|
31
|
+
/** After this many reminders in a row with no update the bot stays silent (D13). */
|
|
32
|
+
exports.todoReminderMaxIgnored = 2;
|
|
33
|
+
const msPerMinute = 60 * 1000;
|
|
34
|
+
/** @description The bookkeeping right after an update: nothing worked, nobody reminded, the clock not started. */
|
|
35
|
+
function createTodoNagState() {
|
|
36
|
+
return { workedMs: 0, ignoredCount: 0 };
|
|
37
|
+
}
|
|
38
|
+
/** @description `nag` with `elapsedMs` of busy time added — counted only once the clock started. */
|
|
39
|
+
function getTodoNagStateWithWork(nag, elapsedMs) {
|
|
40
|
+
if (nag.clockStartedAt === undefined || elapsedMs <= 0)
|
|
41
|
+
return nag;
|
|
42
|
+
return { ...nag, workedMs: nag.workedMs + elapsedMs };
|
|
43
|
+
}
|
|
44
|
+
/** @description `nag` at a turn end: the clock starts at the first one after the update. */
|
|
45
|
+
function getTodoNagStateAtTurnEnd(nag, nowMs) {
|
|
46
|
+
return nag.clockStartedAt === undefined ? { ...nag, clockStartedAt: nowMs } : nag;
|
|
47
|
+
}
|
|
48
|
+
/** @description `nag` after a reminder reached the agent: the work counts afresh, one more ignored until it updates. */
|
|
49
|
+
function getTodoNagStateAfterReminder(nag, nowMs) {
|
|
50
|
+
return { ...nag, workedMs: 0, ignoredCount: nag.ignoredCount + 1, lastRemindedAt: nowMs };
|
|
51
|
+
}
|
|
52
|
+
/** @description `nag` after a person wrote in the conversation: the silence after ignored reminders ends (D13). */
|
|
53
|
+
function getTodoNagStateAfterPersonActivity(nag) {
|
|
54
|
+
return nag.ignoredCount === 0 ? nag : { ...nag, ignoredCount: 0 };
|
|
55
|
+
}
|
|
56
|
+
/** @description The interval in ms, or `null` when the reminder is off. `overrideMs` is the test-only timing seam. */
|
|
57
|
+
function getTodoReminderIntervalMs(settings, overrideMs) {
|
|
58
|
+
if (!settings.isEnabled || settings.reminderMinutes === exports.todoReminderOffMinutes)
|
|
59
|
+
return null;
|
|
60
|
+
return overrideMs ?? settings.reminderMinutes * msPerMinute;
|
|
61
|
+
}
|
|
62
|
+
/** @description Whether the agent worked the whole interval since its last update (the reminder is due, gates aside). */
|
|
63
|
+
function checkIsTodoNagStale(nag, intervalMs) {
|
|
64
|
+
return intervalMs !== null && nag.clockStartedAt !== undefined && nag.workedMs >= intervalMs;
|
|
65
|
+
}
|
|
66
|
+
/** @description The reasons a list is not due for a reminder in either form (empty = due). */
|
|
67
|
+
function getStaleSkipReasons(nag, intervalMs) {
|
|
68
|
+
return [
|
|
69
|
+
intervalMs === null && 'the reminder is off',
|
|
70
|
+
nag.clockStartedAt === undefined && 'no turn ended since the last update',
|
|
71
|
+
intervalMs !== null && nag.workedMs < intervalMs && `worked ${Math.round(nag.workedMs / 1000)} s of ${Math.round(intervalMs / 1000)} s`,
|
|
72
|
+
nag.ignoredCount >= exports.todoReminderMaxIgnored && `silent after ${exports.todoReminderMaxIgnored} ignored reminders`,
|
|
73
|
+
].filter((reason) => typeof reason === 'string');
|
|
74
|
+
}
|
|
75
|
+
/** @description Form a: whether the next prompt carries the reminder line. */
|
|
76
|
+
function decidePromptTodoReminder(nag, intervalMs) {
|
|
77
|
+
const skipReasons = getStaleSkipReasons(nag, intervalMs);
|
|
78
|
+
return skipReasons.length === 0 ? { shouldRemind: true } : { shouldRemind: false, skipReasons };
|
|
79
|
+
}
|
|
80
|
+
/** @description Form b: whether a standalone reminder goes out at this turn end (D12). */
|
|
81
|
+
function decideStandaloneTodoReminder(nag, intervalMs, gate) {
|
|
82
|
+
const skipReasons = [
|
|
83
|
+
...getStaleSkipReasons(nag, intervalMs),
|
|
84
|
+
!gate.isActive && 'no live session (never woken for it)',
|
|
85
|
+
gate.isStoppingAfterTurn && 'the session sleeps after every turn (never woken for it)',
|
|
86
|
+
gate.isBusy && 'busy',
|
|
87
|
+
gate.isTurnEndBlocked && 'something holds the turn open',
|
|
88
|
+
gate.hasUnconsumedInput === true && 'input not taken in yet',
|
|
89
|
+
gate.hasOpenRequest && 'an open request',
|
|
90
|
+
gate.isAnswerTailFollowed && 'the text after a final answer is followed',
|
|
91
|
+
gate.isLimited && 'the account or model is limited',
|
|
92
|
+
gate.isApiBilled && 'billed to API credits',
|
|
93
|
+
].filter((reason) => typeof reason === 'string');
|
|
94
|
+
return skipReasons.length === 0 ? { shouldRemind: true } : { shouldRemind: false, skipReasons };
|
|
95
|
+
}
|
|
96
|
+
/** @description The agent-facing reminder (D14): factual, asks for no text reply. */
|
|
97
|
+
function buildTodoReminderText(lastUpdateAt, nowMs) {
|
|
98
|
+
const opening = lastUpdateAt === undefined
|
|
99
|
+
? 'You have not published a todo list yet and you have been working.'
|
|
100
|
+
: `Your published todo list was last updated ${Math.max(1, Math.round((nowMs - lastUpdateAt) / msPerMinute))} min ago and you have worked since.`;
|
|
101
|
+
return `[Todo] ${opening} todo_update records in-work / queued / done; with no items it confirms the list is still accurate. No text reply is needed.`;
|
|
102
|
+
}
|
|
103
|
+
//# sourceMappingURL=nag.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"nag.js","sourceRoot":"","sources":["../../src/todos/nag.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { type TodoItem, type TodoPosition } from './types';
|
|
2
|
+
/**
|
|
3
|
+
* @description The ONE total order over a conversation's items (D23): in-work items lead, then the queue in its
|
|
4
|
+
* order, then the closed items by the time they were closed, newest first. The queue order is the order of the open
|
|
5
|
+
* items in the stored array; these helpers read and rearrange it, never a number of their own.
|
|
6
|
+
*/
|
|
7
|
+
/** @description Whether an item is still to be done. */
|
|
8
|
+
export declare function checkIsOpenTodoItem(item: TodoItem): boolean;
|
|
9
|
+
/** @description The in-work items, in their stored order. */
|
|
10
|
+
export declare function getInWorkTodoItems(items: readonly TodoItem[]): TodoItem[];
|
|
11
|
+
/** @description The queue: the queued items, in their stored order — the order the agent takes them in. */
|
|
12
|
+
export declare function getQueuedTodoItems(items: readonly TodoItem[]): TodoItem[];
|
|
13
|
+
/** @description The closed items (done and dropped), the most recently closed first. */
|
|
14
|
+
export declare function getClosedTodoItems(items: readonly TodoItem[]): TodoItem[];
|
|
15
|
+
/** @description The whole list in the total order (D23). */
|
|
16
|
+
export declare function getTodoItemsInOrder(items: readonly TodoItem[]): TodoItem[];
|
|
17
|
+
/** @description `items` with the item `id` moved before (`top`) or after (`bottom`) every open item. */
|
|
18
|
+
export declare function getTodoItemsWithMovedItem(items: readonly TodoItem[], id: string, position: TodoPosition): TodoItem[];
|
|
19
|
+
/**
|
|
20
|
+
* @description `items` with the open ones rearranged: the ids of `orderedIds` first, in that order, then the open
|
|
21
|
+
* items it does not list in their relative order. The closed items keep their places — their order is their close
|
|
22
|
+
* time. Ids that are not open items are ignored (the caller rejects them first).
|
|
23
|
+
*/
|
|
24
|
+
export declare function getTodoItemsInRequestedOrder(items: readonly TodoItem[], orderedIds: readonly string[]): TodoItem[];
|
|
25
|
+
//# sourceMappingURL=order.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"order.d.ts","sourceRoot":"","sources":["../../src/todos/order.ts"],"names":[],"mappings":"AAAA,OAAO,EAAoB,KAAK,QAAQ,EAAE,KAAK,YAAY,EAAE,MAAM,SAAS,CAAC;AAE7E;;;;GAIG;AAEH,wDAAwD;AACxD,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,QAAQ,GAAG,OAAO,CAE3D;AAED,6DAA6D;AAC7D,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,SAAS,QAAQ,EAAE,GAAG,QAAQ,EAAE,CAEzE;AAED,2GAA2G;AAC3G,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,SAAS,QAAQ,EAAE,GAAG,QAAQ,EAAE,CAEzE;AAED,wFAAwF;AACxF,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,SAAS,QAAQ,EAAE,GAAG,QAAQ,EAAE,CAEzE;AAED,4DAA4D;AAC5D,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,SAAS,QAAQ,EAAE,GAAG,QAAQ,EAAE,CAE1E;AAED,wGAAwG;AACxG,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,SAAS,QAAQ,EAAE,EAAE,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,YAAY,GAAG,QAAQ,EAAE,CAQpH;AAED;;;;GAIG;AACH,wBAAgB,4BAA4B,CAAC,KAAK,EAAE,SAAS,QAAQ,EAAE,EAAE,UAAU,EAAE,SAAS,MAAM,EAAE,GAAG,QAAQ,EAAE,CAOlH"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.checkIsOpenTodoItem = checkIsOpenTodoItem;
|
|
4
|
+
exports.getInWorkTodoItems = getInWorkTodoItems;
|
|
5
|
+
exports.getQueuedTodoItems = getQueuedTodoItems;
|
|
6
|
+
exports.getClosedTodoItems = getClosedTodoItems;
|
|
7
|
+
exports.getTodoItemsInOrder = getTodoItemsInOrder;
|
|
8
|
+
exports.getTodoItemsWithMovedItem = getTodoItemsWithMovedItem;
|
|
9
|
+
exports.getTodoItemsInRequestedOrder = getTodoItemsInRequestedOrder;
|
|
10
|
+
const types_1 = require("./types");
|
|
11
|
+
/**
|
|
12
|
+
* @description The ONE total order over a conversation's items (D23): in-work items lead, then the queue in its
|
|
13
|
+
* order, then the closed items by the time they were closed, newest first. The queue order is the order of the open
|
|
14
|
+
* items in the stored array; these helpers read and rearrange it, never a number of their own.
|
|
15
|
+
*/
|
|
16
|
+
/** @description Whether an item is still to be done. */
|
|
17
|
+
function checkIsOpenTodoItem(item) {
|
|
18
|
+
return types_1.openTodoStatuses.includes(item.status);
|
|
19
|
+
}
|
|
20
|
+
/** @description The in-work items, in their stored order. */
|
|
21
|
+
function getInWorkTodoItems(items) {
|
|
22
|
+
return items.filter((item) => item.status === 'inWork');
|
|
23
|
+
}
|
|
24
|
+
/** @description The queue: the queued items, in their stored order — the order the agent takes them in. */
|
|
25
|
+
function getQueuedTodoItems(items) {
|
|
26
|
+
return items.filter((item) => item.status === 'queued');
|
|
27
|
+
}
|
|
28
|
+
/** @description The closed items (done and dropped), the most recently closed first. */
|
|
29
|
+
function getClosedTodoItems(items) {
|
|
30
|
+
return items.filter((item) => !checkIsOpenTodoItem(item)).sort((left, right) => (right.closedAt ?? 0) - (left.closedAt ?? 0));
|
|
31
|
+
}
|
|
32
|
+
/** @description The whole list in the total order (D23). */
|
|
33
|
+
function getTodoItemsInOrder(items) {
|
|
34
|
+
return [...getInWorkTodoItems(items), ...getQueuedTodoItems(items), ...getClosedTodoItems(items)];
|
|
35
|
+
}
|
|
36
|
+
/** @description `items` with the item `id` moved before (`top`) or after (`bottom`) every open item. */
|
|
37
|
+
function getTodoItemsWithMovedItem(items, id, position) {
|
|
38
|
+
const moved = items.find((item) => item.id === id);
|
|
39
|
+
if (!moved)
|
|
40
|
+
return [...items];
|
|
41
|
+
const rest = items.filter((item) => item.id !== id);
|
|
42
|
+
if (position === 'bottom')
|
|
43
|
+
return [...rest, moved];
|
|
44
|
+
const firstOpenIndex = rest.findIndex(checkIsOpenTodoItem);
|
|
45
|
+
const insertAt = firstOpenIndex === -1 ? rest.length : firstOpenIndex;
|
|
46
|
+
return [...rest.slice(0, insertAt), moved, ...rest.slice(insertAt)];
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* @description `items` with the open ones rearranged: the ids of `orderedIds` first, in that order, then the open
|
|
50
|
+
* items it does not list in their relative order. The closed items keep their places — their order is their close
|
|
51
|
+
* time. Ids that are not open items are ignored (the caller rejects them first).
|
|
52
|
+
*/
|
|
53
|
+
function getTodoItemsInRequestedOrder(items, orderedIds) {
|
|
54
|
+
const openItems = items.filter(checkIsOpenTodoItem);
|
|
55
|
+
const listed = orderedIds.flatMap((id) => openItems.filter((item) => item.id === id));
|
|
56
|
+
const unlisted = openItems.filter((item) => !orderedIds.includes(item.id));
|
|
57
|
+
const reordered = [...listed, ...unlisted];
|
|
58
|
+
let nextOpenIndex = 0;
|
|
59
|
+
return items.map((item) => (checkIsOpenTodoItem(item) ? reordered[nextOpenIndex++] : item));
|
|
60
|
+
}
|
|
61
|
+
//# sourceMappingURL=order.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"order.js","sourceRoot":"","sources":["../../src/todos/order.ts"],"names":[],"mappings":"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"}
|