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
|
@@ -18,6 +18,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
18
18
|
exports.getSessionTitleLine = getSessionTitleLine;
|
|
19
19
|
exports.getSessionTitleCandidate = getSessionTitleCandidate;
|
|
20
20
|
const threadContextPreamble_1 = require("../threadContextPreamble");
|
|
21
|
+
const claudeUserEntry_1 = require("./claudeUserEntry");
|
|
21
22
|
/**
|
|
22
23
|
* @description Leading `[Scheduled run "<name>"]` marker a scheduled run glues
|
|
23
24
|
* ahead of its prompt (see `scheduler/delivery.ts`). Anchored + single `\n`,
|
|
@@ -25,22 +26,14 @@ const threadContextPreamble_1 = require("../threadContextPreamble");
|
|
|
25
26
|
*/
|
|
26
27
|
const scheduledRunMarkerRe = /^\[Scheduled run "[^"]*"\]\n/;
|
|
27
28
|
/**
|
|
28
|
-
* @description Prompt prefixes that mark a stored user turn as bot
|
|
29
|
-
*
|
|
30
|
-
*
|
|
29
|
+
* @description Prompt prefixes that mark a stored user turn as bot-generated rather than a real topic — never a
|
|
30
|
+
* session title, though the turn is a real message. Matched after the preamble/marker is stripped and whitespace
|
|
31
|
+
* collapsed. (What the CLI itself injects is told apart by `classifyClaudeUserEntry`.)
|
|
31
32
|
*/
|
|
32
33
|
const noisePromptPrefixes = [
|
|
33
34
|
'[Telegram thread context]', // a preamble with no prompt after it (strip failed)
|
|
34
35
|
'[Telegram file]',
|
|
35
36
|
'[Telegram album]',
|
|
36
|
-
'[Request interrupted',
|
|
37
|
-
'<local-command-', // stdout / stderr / caveat wrappers around a slash command
|
|
38
|
-
'<command-',
|
|
39
|
-
'<task-notification>',
|
|
40
|
-
'<system-reminder>',
|
|
41
|
-
'<tool-use-',
|
|
42
|
-
'Base directory for this skill:',
|
|
43
|
-
'Caveat: The messages below',
|
|
44
37
|
];
|
|
45
38
|
/**
|
|
46
39
|
* @description Whole-prompt values that are follow-up chatter, never a topic:
|
|
@@ -51,7 +44,10 @@ const noiseExactPrompts = new Set([
|
|
|
51
44
|
'да', 'нет', 'ага', 'угу', 'давай', 'да, давай', 'да, давай.',
|
|
52
45
|
'commit', 'commit.', 'push', 'пуш', 'коммить', 'коммит', 'обнови my',
|
|
53
46
|
]);
|
|
54
|
-
/**
|
|
47
|
+
/**
|
|
48
|
+
* Effort / model slash-command stdout that lost its `<local-command-*>` wrapper. Not a topic, but a message somebody
|
|
49
|
+
* may type ("Set model to … in the config"), so only the titles skip it.
|
|
50
|
+
*/
|
|
55
51
|
const commandEchoRe = /^set (effort level|model) /i;
|
|
56
52
|
/**
|
|
57
53
|
* @description Strip the bot's service wrappers (thread-context preamble first —
|
|
@@ -77,10 +73,14 @@ function checkIsNoisePrompt(line) {
|
|
|
77
73
|
}
|
|
78
74
|
/**
|
|
79
75
|
* @description A session-title candidate from ONE stored prompt: the stripped
|
|
80
|
-
* single-line topic, or `null` when the prompt is empty
|
|
76
|
+
* single-line topic, or `null` when the prompt is empty, a slash command run in
|
|
77
|
+
* the CLI, text the CLI injected, or other tooling noise.
|
|
81
78
|
*/
|
|
82
79
|
function getSessionTitleCandidate(rawPrompt) {
|
|
83
|
-
const
|
|
80
|
+
const entry = (0, claudeUserEntry_1.classifyClaudeUserEntry)(rawPrompt);
|
|
81
|
+
if (entry.kind !== 'message')
|
|
82
|
+
return null;
|
|
83
|
+
const line = getSessionTitleLine(entry.text);
|
|
84
84
|
if (!line)
|
|
85
85
|
return null;
|
|
86
86
|
if (checkIsNoisePrompt(line))
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"claudeSessionTitle.js","sourceRoot":"","sources":["../../src/utils/claudeSessionTitle.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;GAcG;;
|
|
1
|
+
{"version":3,"file":"claudeSessionTitle.js","sourceRoot":"","sources":["../../src/utils/claudeSessionTitle.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;GAcG;;AA4CH,kDAKC;AAgBD,4DAOC;AAtED,oEAAsE;AACtE,uDAA4D;AAE5D;;;;GAIG;AACH,MAAM,oBAAoB,GAAG,8BAA8B,CAAC;AAE5D;;;;GAIG;AACH,MAAM,mBAAmB,GAAG;IAC1B,2BAA2B,EAAE,oDAAoD;IACjF,iBAAiB;IACjB,kBAAkB;CACnB,CAAC;AAEF;;;GAGG;AACH,MAAM,iBAAiB,GAAG,IAAI,GAAG,CAAC;IAChC,KAAK,EAAE,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,UAAU;IACvE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,WAAW,EAAE,YAAY;IAC7D,QAAQ,EAAE,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,QAAQ,EAAE,WAAW;CACrE,CAAC,CAAC;AAEH;;;GAGG;AACH,MAAM,aAAa,GAAG,6BAA6B,CAAC;AAEpD;;;;GAIG;AACH,SAAgB,mBAAmB,CAAC,SAAiB;IACnD,IAAI,IAAI,GAAG,SAAS,CAAC,IAAI,EAAE,CAAC;IAC5B,IAAI,GAAG,IAAA,kDAA0B,EAAC,IAAI,CAAC,CAAC;IACxC,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,oBAAoB,EAAE,EAAE,CAAC,CAAC;IAC9C,OAAO,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;AAC1C,CAAC;AAED,wFAAwF;AACxF,SAAS,kBAAkB,CAAC,IAAY;IACtC,MAAM,KAAK,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;IACjC,IAAI,iBAAiB,CAAC,GAAG,CAAC,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IAC9C,IAAI,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC,CAAC,gCAAgC;IACrE,IAAI,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC;IAC1C,OAAO,mBAAmB,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC;AACrE,CAAC;AAED;;;;GAIG;AACH,SAAgB,wBAAwB,CAAC,SAAiB;IACxD,MAAM,KAAK,GAAG,IAAA,yCAAuB,EAAC,SAAS,CAAC,CAAC;IACjD,IAAI,KAAK,CAAC,IAAI,KAAK,SAAS;QAAE,OAAO,IAAI,CAAC;IAC1C,MAAM,IAAI,GAAG,mBAAmB,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC7C,IAAI,CAAC,IAAI;QAAE,OAAO,IAAI,CAAC;IACvB,IAAI,kBAAkB,CAAC,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC;IAC1C,OAAO,IAAI,CAAC;AACd,CAAC"}
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @description Per-profile Claude USAGE — how much of each subscription window an account profile
|
|
3
|
-
* (`utils/claudeProfiles.ts`) has used, and which profile a
|
|
3
|
+
* (`utils/claudeProfiles.ts`) has used, and which profile a process should run on: a NEW agent goes to the
|
|
4
|
+
* account whose weekly window resets soonest (spend first what burns soonest), a WARM session stays on the
|
|
5
|
+
* account it worked on ({@link getClaudeLaunchPick}).
|
|
4
6
|
*
|
|
5
7
|
* Two sources feed one snapshot per profile (`ClaudeProfileRecord.usage`):
|
|
6
8
|
* - the OAuth usage endpoint (`GET https://api.anthropic.com/api/oauth/usage`, the profile's own access
|
|
@@ -184,7 +186,8 @@ export interface ClaudeProfileReportEntry {
|
|
|
184
186
|
subscriptionType: string | null;
|
|
185
187
|
/**
|
|
186
188
|
* `api`: billed per request to a Claude Console organization's API credits — no windows, so no headroom figure, and
|
|
187
|
-
* NEVER
|
|
189
|
+
* NEVER picked for a NEW agent (it would look inexhaustible and spend money); only a warm session already on it stays.
|
|
190
|
+
* `null`: a subscription not recorded as such.
|
|
188
191
|
*/
|
|
189
192
|
billing: ClaudeProfileBilling | null;
|
|
190
193
|
/** `null` when never probed. */
|
|
@@ -195,29 +198,106 @@ export interface ClaudeProfileReportEntry {
|
|
|
195
198
|
limitedUntil: string | null;
|
|
196
199
|
/** When its prepaid API credits were found used up (`null`: not marked). */
|
|
197
200
|
creditExhaustedAt: string | null;
|
|
198
|
-
/** Signed in, not limited, its API credits not used up, and not at 100 % on a window the model drains. */
|
|
201
|
+
/** Signed in, not limited, its API credits not used up, and not at 100 % on a window the model drains — by the figures AS RECORDED. */
|
|
199
202
|
isEligible: boolean;
|
|
200
|
-
/** `100 − max(relevant percent)`; `null` when the usage is unknown. */
|
|
203
|
+
/** `100 − max(relevant percent)`; `null` when the usage is unknown. Informational: the pick ranks by reset, not by headroom. */
|
|
201
204
|
headroomPercent: number | null;
|
|
205
|
+
/** The profile {@link getClaudeLaunchPick} chose (the figures read as of now). */
|
|
202
206
|
isRecommended: boolean;
|
|
203
207
|
}
|
|
204
208
|
export interface ClaudeProfilesReport {
|
|
205
209
|
model: string | null;
|
|
206
|
-
/** The windows the
|
|
210
|
+
/** The windows the pick looked at for `model`. */
|
|
207
211
|
relevantBuckets: ClaudeUsageBucketKind[];
|
|
208
|
-
/** The
|
|
212
|
+
/** The profile a process of `model` should run on (see {@link getClaudeLaunchPick}); `null` when none is usable. */
|
|
209
213
|
recommended: string | null;
|
|
214
|
+
/** Why `recommended` is what it is. */
|
|
215
|
+
pickReason: ClaudeLaunchPickReason;
|
|
216
|
+
/** With nothing usable: the account and instant that frees up first, so a resume can be scheduled for it. */
|
|
217
|
+
nextAvailable: ClaudeNextAvailable | null;
|
|
210
218
|
profiles: ClaudeProfileReportEntry[];
|
|
211
219
|
}
|
|
220
|
+
/** A new agent never starts on an account whose five-hour window is already this full: it would hit the limit within minutes. */
|
|
221
|
+
export declare const claudeLaunchSessionCeilingPercent = 90;
|
|
222
|
+
/** Two weekly resets closer than this count as the same moment (the endpoint's instants carry sub-second jitter); the five-hour percent then decides. */
|
|
223
|
+
export declare const claudeLaunchResetTieMs = 60000;
|
|
224
|
+
export declare const claudeWeeklyWindowMs: number;
|
|
225
|
+
export declare const claudeSessionWindowMs: number;
|
|
212
226
|
/**
|
|
213
|
-
*
|
|
214
|
-
*
|
|
215
|
-
*
|
|
216
|
-
* total of the relevant percentages). The first SUBSCRIPTION in that order is `recommended`: an account billed to API
|
|
217
|
-
* credits has no windows — it would rank as unknown headroom forever — and a child launched on it spends money, so
|
|
218
|
-
* it is listed (eligible or not) but never recommended. The entries keep the input order.
|
|
227
|
+
* `warm`: the session stays on its account; `movedFromLimited`: it was stopped by a limit and goes elsewhere;
|
|
228
|
+
* `movedFromUnavailable`: its account can no longer run (signed out, marked limited, out of credits, a window full) and it
|
|
229
|
+
* goes elsewhere; `soonestWeeklyReset`: a new agent; `none`: nothing is usable.
|
|
219
230
|
*/
|
|
220
|
-
export
|
|
231
|
+
export type ClaudeLaunchPickReason = 'warm' | 'movedFromLimited' | 'movedFromUnavailable' | 'soonestWeeklyReset' | 'none';
|
|
232
|
+
/** The account that frees up first and the ISO instant it does. */
|
|
233
|
+
export interface ClaudeNextAvailable {
|
|
234
|
+
profile: string;
|
|
235
|
+
at: string;
|
|
236
|
+
}
|
|
237
|
+
export interface ClaudeLaunchPick {
|
|
238
|
+
pick: string | null;
|
|
239
|
+
reason: ClaudeLaunchPickReason;
|
|
240
|
+
nextAvailable: ClaudeNextAvailable | null;
|
|
241
|
+
}
|
|
242
|
+
/** What the pick needs besides the profiles, the model and the clock. */
|
|
243
|
+
export interface ClaudeLaunchPickOptions {
|
|
244
|
+
/** The account a WARM session last ran on; absent for a new agent (an unknown name counts as absent). */
|
|
245
|
+
currentProfile?: string | null;
|
|
246
|
+
/** The session broke off on a usage limit of `currentProfile`: it is left out of this answer whatever the figures say. */
|
|
247
|
+
isStoppedByLimit?: boolean;
|
|
248
|
+
/** Accounts the operator switched off in the `/limits` list (every rung disabled): never picked for a new agent. */
|
|
249
|
+
excludedNames?: ReadonlySet<string>;
|
|
250
|
+
}
|
|
251
|
+
/**
|
|
252
|
+
* @description Whether a NEW agent of `model` may start on the profile now: a subscription account that is eligible by the
|
|
253
|
+
* figures as of `nowMs` and whose five-hour window is below {@link claudeLaunchSessionCeilingPercent}. Switching it off
|
|
254
|
+
* in the `/limits` list is the caller's filter.
|
|
255
|
+
*/
|
|
256
|
+
export declare function checkIsClaudeProfileLaunchable(profile: ClaudeProfileUsageView, model: string | null, nowMs: number): boolean;
|
|
257
|
+
/**
|
|
258
|
+
* @description The profiles in the order a launch of `model` prefers them: the soonest weekly reset first (the figures as of
|
|
259
|
+
* `nowMs`: a passed reset rolled forward), an unknown reset after every known one, no snapshot last. Resets within
|
|
260
|
+
* {@link claudeLaunchResetTieMs} of the group's first count as one moment, ordered by the lower five-hour percent, then by
|
|
261
|
+
* input order. Pure ordering: the caller filters who may be picked at all. Shared by the report's pick and the bot's
|
|
262
|
+
* own topic switch (`claudeLimitSwitch.ts`) — ONE ranking.
|
|
263
|
+
*/
|
|
264
|
+
export declare function sortClaudeProfilesByLaunchRank<T extends ClaudeProfileUsageView>(profiles: readonly T[], model: string | null, nowMs: number): T[];
|
|
265
|
+
/**
|
|
266
|
+
* @description The account a process of `model` should run on.
|
|
267
|
+
*
|
|
268
|
+
* NEW agent (no `currentProfile`): of the USABLE accounts — subscription, signed in, not marked limited, not out of API
|
|
269
|
+
* credits, not switched off (`excludedNames`), every weekly window the model drains below 100 % and the five-hour window
|
|
270
|
+
* below {@link claudeLaunchSessionCeilingPercent} — the one whose weekly window resets soonest
|
|
271
|
+
* ({@link sortClaudeProfilesByLaunchRank}): spend first what burns first, and move to a farther reset only when the
|
|
272
|
+
* five-hour window is exhausted. Fable's own window at 100 % takes only Fable out.
|
|
273
|
+
*
|
|
274
|
+
* WARM session (`currentProfile` known): it stays on that account unless the account is signed out, marked limited, out
|
|
275
|
+
* of API credits or at 100 % on a window the model drains — the ceiling does not apply, and an API-billed account the
|
|
276
|
+
* session already works on is kept (the spend was approved). `isStoppedByLimit` takes `currentProfile` out of the answer
|
|
277
|
+
* whatever the figures say (they may lag the limit); the rest follows the new-agent rule, and the reason says the
|
|
278
|
+
* session moved (`movedFromLimited`, or `movedFromUnavailable` when the account could no longer run by its own figures).
|
|
279
|
+
*
|
|
280
|
+
* Nothing usable → `pick: null` and {@link ClaudeLaunchPick.nextAvailable}.
|
|
281
|
+
*/
|
|
282
|
+
export declare function getClaudeLaunchPick(input: ClaudeLaunchPickOptions & {
|
|
283
|
+
profiles: readonly ClaudeProfileUsageView[];
|
|
284
|
+
model: string | null;
|
|
285
|
+
nowMs: number;
|
|
286
|
+
}): ClaudeLaunchPick;
|
|
287
|
+
/**
|
|
288
|
+
* @description The pick in words, for the first line of the `claude_profiles` answer and the CLI: why the account was chosen
|
|
289
|
+
* (`stays on the warm account`, `moved: <name> stopped on a limit` / `can no longer run`, `soonest weekly reset`), or that nothing is usable
|
|
290
|
+
* and which account frees up when. `currentProfile` is the account the caller passed for a resumed session.
|
|
291
|
+
*/
|
|
292
|
+
export declare function describeClaudeLaunchOutcome(report: Pick<ClaudeProfilesReport, 'pickReason' | 'nextAvailable'>, currentProfile: string | null): string;
|
|
293
|
+
/**
|
|
294
|
+
* @description The report of every profile for a launch of `model`, with the pick of {@link getClaudeLaunchPick}
|
|
295
|
+
* (`options`: the warm account, the limit stop, the switched-off accounts). `isEligible` is the strict reading — signed in,
|
|
296
|
+
* not marked limited, its API credits not used up, not at 100 % on a relevant window as recorded — which the explicit
|
|
297
|
+
* fallback chain's availability reads; `recommended` is the pick, an account billed to API credits only when a warm
|
|
298
|
+
* session already runs on it. The entries keep the input order.
|
|
299
|
+
*/
|
|
300
|
+
export declare function buildClaudeProfilesReport(profiles: readonly ClaudeProfileUsageView[], model: string | null, nowMs: number, options?: ClaudeLaunchPickOptions): ClaudeProfilesReport;
|
|
221
301
|
/**
|
|
222
302
|
* @description The ranking's view of every profile off the registry: `default` (its hidden record, when the
|
|
223
303
|
* bot has written one) first, then the added profiles in creation order. Shared by the bot (live state) and
|
|
@@ -228,8 +308,8 @@ export declare function buildClaudeProfileUsageViews(input: {
|
|
|
228
308
|
/** Every record, the hidden `default` one included (`StateStore.getClaudeProfileInfo` / the raw file). */
|
|
229
309
|
records: Readonly<Record<string, ClaudeProfileRecord>>;
|
|
230
310
|
}): ClaudeProfileUsageView[];
|
|
231
|
-
/** The profile registry
|
|
232
|
-
export declare function
|
|
311
|
+
/** The profile registry out of a `state.json` already read (`stateFile.ts`): entries without a creation time are dropped. */
|
|
312
|
+
export declare function getClaudeProfileRecordsFromState(stateFile: Readonly<Record<string, unknown>>): Readonly<Record<string, ClaudeProfileRecord>>;
|
|
233
313
|
/**
|
|
234
314
|
* @description A reset instant for a human, in the instance zone: `16:00` when it is today there, `Sat 00:00`
|
|
235
315
|
* within the week, `17.10 00:00` beyond. The weekday is English on purpose (a three-letter token every locale
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"claudeUsage.d.ts","sourceRoot":"","sources":["../../src/utils/claudeUsage.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"claudeUsage.d.ts","sourceRoot":"","sources":["../../src/utils/claudeUsage.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
/**
|
|
3
3
|
* @description Per-profile Claude USAGE — how much of each subscription window an account profile
|
|
4
|
-
* (`utils/claudeProfiles.ts`) has used, and which profile a
|
|
4
|
+
* (`utils/claudeProfiles.ts`) has used, and which profile a process should run on: a NEW agent goes to the
|
|
5
|
+
* account whose weekly window resets soonest (spend first what burns soonest), a WARM session stays on the
|
|
6
|
+
* account it worked on ({@link getClaudeLaunchPick}).
|
|
5
7
|
*
|
|
6
8
|
* Two sources feed one snapshot per profile (`ClaudeProfileRecord.usage`):
|
|
7
9
|
* - the OAuth usage endpoint (`GET https://api.anthropic.com/api/oauth/usage`, the profile's own access
|
|
@@ -52,7 +54,7 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
52
54
|
};
|
|
53
55
|
})();
|
|
54
56
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
55
|
-
exports.englishRelativeResetWords = exports.claudeUsageBucketKinds = exports.claudeUsageFetchTimeoutMs = exports.claudeUsageEndpoint = void 0;
|
|
57
|
+
exports.englishRelativeResetWords = exports.claudeSessionWindowMs = exports.claudeWeeklyWindowMs = exports.claudeLaunchResetTieMs = exports.claudeLaunchSessionCeilingPercent = exports.claudeUsageBucketKinds = exports.claudeUsageFetchTimeoutMs = exports.claudeUsageEndpoint = void 0;
|
|
56
58
|
exports.readClaudeOAuthToken = readClaudeOAuthToken;
|
|
57
59
|
exports.checkIsClaudeTokenExpired = checkIsClaudeTokenExpired;
|
|
58
60
|
exports.fetchUsageBuckets = fetchUsageBuckets;
|
|
@@ -68,9 +70,13 @@ exports.getRelevantClaudeUsageKinds = getRelevantClaudeUsageKinds;
|
|
|
68
70
|
exports.checkHasHeadroomForClaudeModel = checkHasHeadroomForClaudeModel;
|
|
69
71
|
exports.checkIsClaudeUsageExhausted = checkIsClaudeUsageExhausted;
|
|
70
72
|
exports.checkIsClaudeModelClearOfLimit = checkIsClaudeModelClearOfLimit;
|
|
73
|
+
exports.checkIsClaudeProfileLaunchable = checkIsClaudeProfileLaunchable;
|
|
74
|
+
exports.sortClaudeProfilesByLaunchRank = sortClaudeProfilesByLaunchRank;
|
|
75
|
+
exports.getClaudeLaunchPick = getClaudeLaunchPick;
|
|
76
|
+
exports.describeClaudeLaunchOutcome = describeClaudeLaunchOutcome;
|
|
71
77
|
exports.buildClaudeProfilesReport = buildClaudeProfilesReport;
|
|
72
78
|
exports.buildClaudeProfileUsageViews = buildClaudeProfileUsageViews;
|
|
73
|
-
exports.
|
|
79
|
+
exports.getClaudeProfileRecordsFromState = getClaudeProfileRecordsFromState;
|
|
74
80
|
exports.formatClaudeUsageResetAt = formatClaudeUsageResetAt;
|
|
75
81
|
exports.formatClaudeUsageRelativeReset = formatClaudeUsageRelativeReset;
|
|
76
82
|
exports.formatClaudeUsageBucket = formatClaudeUsageBucket;
|
|
@@ -299,23 +305,235 @@ function checkIsClaudeModelClearOfLimit(usage, limitedModel, pickedModel) {
|
|
|
299
305
|
}
|
|
300
306
|
return checkHasHeadroomForClaudeModel(usage, pickedModel);
|
|
301
307
|
}
|
|
308
|
+
// ── the launch pick ──
|
|
309
|
+
/** A new agent never starts on an account whose five-hour window is already this full: it would hit the limit within minutes. */
|
|
310
|
+
exports.claudeLaunchSessionCeilingPercent = 90;
|
|
311
|
+
/** Two weekly resets closer than this count as the same moment (the endpoint's instants carry sub-second jitter); the five-hour percent then decides. */
|
|
312
|
+
exports.claudeLaunchResetTieMs = 60_000;
|
|
313
|
+
exports.claudeWeeklyWindowMs = 7 * 24 * 3_600_000;
|
|
314
|
+
exports.claudeSessionWindowMs = 5 * 3_600_000;
|
|
302
315
|
/**
|
|
303
|
-
*
|
|
304
|
-
* (`
|
|
305
|
-
*
|
|
306
|
-
* total of the relevant percentages). The first SUBSCRIPTION in that order is `recommended`: an account billed to API
|
|
307
|
-
* credits has no windows — it would rank as unknown headroom forever — and a child launched on it spends money, so
|
|
308
|
-
* it is listed (eligible or not) but never recommended. The entries keep the input order.
|
|
316
|
+
* The account itself can run: signed in, not marked limited, its API credits not used up, and none of the windows
|
|
317
|
+
* the model drains (`relevantBuckets`, read by the caller) at 100 %. The one hard-eligibility rule of the report's
|
|
318
|
+
* `isEligible` (figures as recorded) and of the launch pick (figures as of now).
|
|
309
319
|
*/
|
|
310
|
-
function
|
|
320
|
+
function checkIsClaudeProfileEligible(profile, relevantBuckets, nowMs) {
|
|
321
|
+
const isLimited = profile.limitedUntil !== null && Date.parse(profile.limitedUntil) > nowMs;
|
|
322
|
+
return profile.loggedIn !== false && !isLimited && profile.creditExhaustedAt === null && relevantBuckets.every((bucket) => bucket.percent < 100);
|
|
323
|
+
}
|
|
324
|
+
/** The reset instant in epoch ms; `NaN` when the bucket names none. */
|
|
325
|
+
function getBucketResetMs(bucket) {
|
|
326
|
+
return bucket.resetsAt === null ? Number.NaN : Date.parse(bucket.resetsAt);
|
|
327
|
+
}
|
|
328
|
+
function getRelevantClaudeUsageBuckets(usage, model) {
|
|
329
|
+
return getRelevantClaudeUsageKinds(model)
|
|
330
|
+
.map((kind) => getClaudeUsageBucket(usage, kind))
|
|
331
|
+
.filter((bucket) => bucket !== null);
|
|
332
|
+
}
|
|
333
|
+
/**
|
|
334
|
+
* A bucket as it stands at `nowMs`: a window whose reset instant has passed since the figure was read is empty again
|
|
335
|
+
* (0 %) and resets one window length per elapsed period later. A bucket without a usable reset stays as read.
|
|
336
|
+
*/
|
|
337
|
+
function readClaudeBucketAsOf(bucket, nowMs) {
|
|
338
|
+
const resetMs = getBucketResetMs(bucket);
|
|
339
|
+
if (!Number.isFinite(resetMs) || resetMs > nowMs)
|
|
340
|
+
return bucket;
|
|
341
|
+
const windowMs = bucket.kind === 'session' ? exports.claudeSessionWindowMs : exports.claudeWeeklyWindowMs;
|
|
342
|
+
const rolledMs = resetMs + (Math.floor((nowMs - resetMs) / windowMs) + 1) * windowMs;
|
|
343
|
+
return { ...bucket, percent: 0, resetsAt: new Date(rolledMs).toISOString() };
|
|
344
|
+
}
|
|
345
|
+
function getRelevantClaudeBucketsAsOf(profile, model, nowMs) {
|
|
346
|
+
return getRelevantClaudeUsageBuckets(profile.usage, model).map((bucket) => readClaudeBucketAsOf(bucket, nowMs));
|
|
347
|
+
}
|
|
348
|
+
/**
|
|
349
|
+
* @description Whether a NEW agent of `model` may start on the profile now: a subscription account that is eligible by the
|
|
350
|
+
* figures as of `nowMs` and whose five-hour window is below {@link claudeLaunchSessionCeilingPercent}. Switching it off
|
|
351
|
+
* in the `/limits` list is the caller's filter.
|
|
352
|
+
*/
|
|
353
|
+
function checkIsClaudeProfileLaunchable(profile, model, nowMs) {
|
|
354
|
+
if (profile.billing === 'api')
|
|
355
|
+
return false;
|
|
356
|
+
const buckets = getRelevantClaudeBucketsAsOf(profile, model, nowMs);
|
|
357
|
+
if (!checkIsClaudeProfileEligible(profile, buckets, nowMs))
|
|
358
|
+
return false;
|
|
359
|
+
const session = buckets.find((bucket) => bucket.kind === 'session');
|
|
360
|
+
return session === undefined || session.percent < exports.claudeLaunchSessionCeilingPercent;
|
|
361
|
+
}
|
|
362
|
+
/** 0: a known weekly reset; 1: a snapshot without one; 2: no snapshot at all. */
|
|
363
|
+
function getRankTier(key) {
|
|
364
|
+
if (key.weeklyResetMs !== null)
|
|
365
|
+
return 0;
|
|
366
|
+
return key.hasUsage ? 1 : 2;
|
|
367
|
+
}
|
|
368
|
+
function compareRankKeysBySession(a, b) {
|
|
369
|
+
const aSession = a.sessionPercent ?? Number.POSITIVE_INFINITY;
|
|
370
|
+
const bSession = b.sessionPercent ?? Number.POSITIVE_INFINITY;
|
|
371
|
+
if (aSession !== bSession)
|
|
372
|
+
return aSession < bSession ? -1 : 1;
|
|
373
|
+
return a.index - b.index;
|
|
374
|
+
}
|
|
375
|
+
/**
|
|
376
|
+
* @description The profiles in the order a launch of `model` prefers them: the soonest weekly reset first (the figures as of
|
|
377
|
+
* `nowMs`: a passed reset rolled forward), an unknown reset after every known one, no snapshot last. Resets within
|
|
378
|
+
* {@link claudeLaunchResetTieMs} of the group's first count as one moment, ordered by the lower five-hour percent, then by
|
|
379
|
+
* input order. Pure ordering: the caller filters who may be picked at all. Shared by the report's pick and the bot's
|
|
380
|
+
* own topic switch (`claudeLimitSwitch.ts`) — ONE ranking.
|
|
381
|
+
*/
|
|
382
|
+
function sortClaudeProfilesByLaunchRank(profiles, model, nowMs) {
|
|
383
|
+
const keys = profiles.map((profile, index) => {
|
|
384
|
+
const buckets = getRelevantClaudeBucketsAsOf(profile, model, nowMs);
|
|
385
|
+
const resets = buckets
|
|
386
|
+
.filter((bucket) => bucket.kind !== 'session')
|
|
387
|
+
.map(getBucketResetMs)
|
|
388
|
+
.filter((resetMs) => Number.isFinite(resetMs));
|
|
389
|
+
return {
|
|
390
|
+
profile,
|
|
391
|
+
index,
|
|
392
|
+
weeklyResetMs: resets.length === 0 ? null : Math.min(...resets),
|
|
393
|
+
sessionPercent: buckets.find((bucket) => bucket.kind === 'session')?.percent ?? null,
|
|
394
|
+
hasUsage: (profile.usage?.buckets.length ?? 0) > 0,
|
|
395
|
+
};
|
|
396
|
+
});
|
|
397
|
+
keys.sort((a, b) => getRankTier(a) - getRankTier(b) || (a.weeklyResetMs ?? 0) - (b.weeklyResetMs ?? 0) || a.index - b.index);
|
|
398
|
+
// A tie group is anchored at its first member, so the rule is a partition, not a comparator that could contradict itself.
|
|
399
|
+
const ordered = [];
|
|
400
|
+
let group = [];
|
|
401
|
+
const flushGroup = () => {
|
|
402
|
+
ordered.push(...group.sort(compareRankKeysBySession).map((key) => key.profile));
|
|
403
|
+
group = [];
|
|
404
|
+
};
|
|
405
|
+
for (const key of keys) {
|
|
406
|
+
const anchor = group[0];
|
|
407
|
+
const isTied = anchor !== undefined
|
|
408
|
+
&& getRankTier(anchor) === getRankTier(key)
|
|
409
|
+
&& (key.weeklyResetMs === null || anchor.weeklyResetMs === null || key.weeklyResetMs - anchor.weeklyResetMs <= exports.claudeLaunchResetTieMs);
|
|
410
|
+
if (anchor !== undefined && !isTied)
|
|
411
|
+
flushGroup();
|
|
412
|
+
group.push(key);
|
|
413
|
+
}
|
|
414
|
+
flushGroup();
|
|
415
|
+
return ordered;
|
|
416
|
+
}
|
|
417
|
+
/**
|
|
418
|
+
* The instant the profile becomes usable for a new agent once every blocker clears: its limited mark, a weekly window the
|
|
419
|
+
* model drains at 100 %, a five-hour window at the launch ceiling (each at its reset, figures as of now). `nowMs` when
|
|
420
|
+
* nothing blocks it; `null` when a blocker names no reset (nobody can tell when it frees up).
|
|
421
|
+
*/
|
|
422
|
+
function getClaudeProfileFreeAtMs(profile, model, nowMs) {
|
|
423
|
+
let freeAtMs = nowMs;
|
|
424
|
+
const limitedUntilMs = profile.limitedUntil === null ? Number.NaN : Date.parse(profile.limitedUntil);
|
|
425
|
+
if (Number.isFinite(limitedUntilMs) && limitedUntilMs > nowMs)
|
|
426
|
+
freeAtMs = limitedUntilMs;
|
|
427
|
+
for (const bucket of getRelevantClaudeBucketsAsOf(profile, model, nowMs)) {
|
|
428
|
+
const ceilingPercent = bucket.kind === 'session' ? exports.claudeLaunchSessionCeilingPercent : 100;
|
|
429
|
+
if (bucket.percent < ceilingPercent)
|
|
430
|
+
continue;
|
|
431
|
+
const resetMs = getBucketResetMs(bucket);
|
|
432
|
+
if (!Number.isFinite(resetMs))
|
|
433
|
+
return null;
|
|
434
|
+
freeAtMs = Math.max(freeAtMs, resetMs);
|
|
435
|
+
}
|
|
436
|
+
return freeAtMs;
|
|
437
|
+
}
|
|
438
|
+
/** When the profile's five-hour window resets (as of `nowMs`); `null` when the snapshot has none or names no reset. */
|
|
439
|
+
function getSessionResetMs(profile, nowMs) {
|
|
440
|
+
const session = getClaudeUsageBucket(profile.usage, 'session');
|
|
441
|
+
const resetMs = session === null ? Number.NaN : getBucketResetMs(readClaudeBucketAsOf(session, nowMs));
|
|
442
|
+
return Number.isFinite(resetMs) ? resetMs : null;
|
|
443
|
+
}
|
|
444
|
+
/**
|
|
445
|
+
* The subscription account that frees up first, when nothing is usable now; `null` when no account names a time. The
|
|
446
|
+
* account a limit just stopped (`stoppedName`) may show no blocker at all — its figures lag the limit — and is then
|
|
447
|
+
* taken to free up when its five-hour window resets, so a single account is never left without a time to come back.
|
|
448
|
+
*/
|
|
449
|
+
function getClaudeNextAvailable(profiles, model, nowMs, excludedNames, stoppedName) {
|
|
450
|
+
let next = null;
|
|
451
|
+
for (const profile of profiles) {
|
|
452
|
+
// These never come back at a known time: switched off, signed out, API-billed, out of credits.
|
|
453
|
+
if (excludedNames.has(profile.name) || profile.loggedIn === false || profile.billing === 'api' || profile.creditExhaustedAt !== null)
|
|
454
|
+
continue;
|
|
455
|
+
let freeAtMs = getClaudeProfileFreeAtMs(profile, model, nowMs);
|
|
456
|
+
// The limit stopped this account, yet its figures show no blocker, so nothing says WHICH limit it was (a weekly window
|
|
457
|
+
// the usage endpoint has not caught up with, or the five-hour one). The five-hour reset is a guess — the earliest it
|
|
458
|
+
// could be free. A wrong guess just hits the limit again on the resume and asks again: at most about one try per five hours.
|
|
459
|
+
if (profile.name === stoppedName && freeAtMs !== null && freeAtMs <= nowMs)
|
|
460
|
+
freeAtMs = getSessionResetMs(profile, nowMs);
|
|
461
|
+
if (freeAtMs === null || freeAtMs <= nowMs)
|
|
462
|
+
continue;
|
|
463
|
+
if (next === null || freeAtMs < next.atMs)
|
|
464
|
+
next = { profile: profile.name, atMs: freeAtMs };
|
|
465
|
+
}
|
|
466
|
+
return next === null ? null : { profile: next.profile, at: new Date(next.atMs).toISOString() };
|
|
467
|
+
}
|
|
468
|
+
/**
|
|
469
|
+
* @description The account a process of `model` should run on.
|
|
470
|
+
*
|
|
471
|
+
* NEW agent (no `currentProfile`): of the USABLE accounts — subscription, signed in, not marked limited, not out of API
|
|
472
|
+
* credits, not switched off (`excludedNames`), every weekly window the model drains below 100 % and the five-hour window
|
|
473
|
+
* below {@link claudeLaunchSessionCeilingPercent} — the one whose weekly window resets soonest
|
|
474
|
+
* ({@link sortClaudeProfilesByLaunchRank}): spend first what burns first, and move to a farther reset only when the
|
|
475
|
+
* five-hour window is exhausted. Fable's own window at 100 % takes only Fable out.
|
|
476
|
+
*
|
|
477
|
+
* WARM session (`currentProfile` known): it stays on that account unless the account is signed out, marked limited, out
|
|
478
|
+
* of API credits or at 100 % on a window the model drains — the ceiling does not apply, and an API-billed account the
|
|
479
|
+
* session already works on is kept (the spend was approved). `isStoppedByLimit` takes `currentProfile` out of the answer
|
|
480
|
+
* whatever the figures say (they may lag the limit); the rest follows the new-agent rule, and the reason says the
|
|
481
|
+
* session moved (`movedFromLimited`, or `movedFromUnavailable` when the account could no longer run by its own figures).
|
|
482
|
+
*
|
|
483
|
+
* Nothing usable → `pick: null` and {@link ClaudeLaunchPick.nextAvailable}.
|
|
484
|
+
*/
|
|
485
|
+
function getClaudeLaunchPick(input) {
|
|
486
|
+
const excludedNames = input.excludedNames ?? new Set();
|
|
487
|
+
const current = input.currentProfile ? input.profiles.find((profile) => profile.name === input.currentProfile) : undefined;
|
|
488
|
+
const isStopped = current !== undefined && input.isStoppedByLimit === true;
|
|
489
|
+
if (current && !isStopped
|
|
490
|
+
&& checkIsClaudeProfileEligible(current, getRelevantClaudeBucketsAsOf(current, input.model, input.nowMs), input.nowMs)) {
|
|
491
|
+
return { pick: current.name, reason: 'warm', nextAvailable: null };
|
|
492
|
+
}
|
|
493
|
+
const movedFrom = current?.name ?? null;
|
|
494
|
+
const usable = input.profiles.filter((profile) => profile.name !== movedFrom
|
|
495
|
+
&& !excludedNames.has(profile.name)
|
|
496
|
+
&& checkIsClaudeProfileLaunchable(profile, input.model, input.nowMs));
|
|
497
|
+
const [first] = sortClaudeProfilesByLaunchRank(usable, input.model, input.nowMs);
|
|
498
|
+
if (first) {
|
|
499
|
+
const reason = movedFrom === null ? 'soonestWeeklyReset' : isStopped ? 'movedFromLimited' : 'movedFromUnavailable';
|
|
500
|
+
return { pick: first.name, reason, nextAvailable: null };
|
|
501
|
+
}
|
|
502
|
+
return { pick: null, reason: 'none', nextAvailable: getClaudeNextAvailable(input.profiles, input.model, input.nowMs, excludedNames, isStopped ? movedFrom : null) };
|
|
503
|
+
}
|
|
504
|
+
/**
|
|
505
|
+
* @description The pick in words, for the first line of the `claude_profiles` answer and the CLI: why the account was chosen
|
|
506
|
+
* (`stays on the warm account`, `moved: <name> stopped on a limit` / `can no longer run`, `soonest weekly reset`), or that nothing is usable
|
|
507
|
+
* and which account frees up when. `currentProfile` is the account the caller passed for a resumed session.
|
|
508
|
+
*/
|
|
509
|
+
function describeClaudeLaunchOutcome(report, currentProfile) {
|
|
510
|
+
switch (report.pickReason) {
|
|
511
|
+
case 'warm':
|
|
512
|
+
return 'stays on the warm account';
|
|
513
|
+
case 'movedFromLimited':
|
|
514
|
+
return `moved: ${currentProfile ?? 'the warm account'} stopped on a limit`;
|
|
515
|
+
case 'movedFromUnavailable':
|
|
516
|
+
return `moved: ${currentProfile ?? 'the warm account'} can no longer run`;
|
|
517
|
+
case 'soonestWeeklyReset':
|
|
518
|
+
return 'soonest weekly reset';
|
|
519
|
+
case 'none':
|
|
520
|
+
return report.nextAvailable === null
|
|
521
|
+
? 'none usable — no account names a time it frees up'
|
|
522
|
+
: `none usable — next: ${report.nextAvailable.profile} at ${report.nextAvailable.at}`;
|
|
523
|
+
}
|
|
524
|
+
}
|
|
525
|
+
/**
|
|
526
|
+
* @description The report of every profile for a launch of `model`, with the pick of {@link getClaudeLaunchPick}
|
|
527
|
+
* (`options`: the warm account, the limit stop, the switched-off accounts). `isEligible` is the strict reading — signed in,
|
|
528
|
+
* not marked limited, its API credits not used up, not at 100 % on a relevant window as recorded — which the explicit
|
|
529
|
+
* fallback chain's availability reads; `recommended` is the pick, an account billed to API credits only when a warm
|
|
530
|
+
* session already runs on it. The entries keep the input order.
|
|
531
|
+
*/
|
|
532
|
+
function buildClaudeProfilesReport(profiles, model, nowMs, options = {}) {
|
|
311
533
|
const relevantBuckets = getRelevantClaudeUsageKinds(model);
|
|
312
534
|
const entries = profiles.map((profile) => {
|
|
313
|
-
const relevant =
|
|
314
|
-
.map((kind) => getClaudeUsageBucket(profile.usage, kind))
|
|
315
|
-
.filter((bucket) => bucket !== null);
|
|
535
|
+
const relevant = getRelevantClaudeUsageBuckets(profile.usage, model);
|
|
316
536
|
const maxPercent = relevant.length === 0 ? null : Math.max(...relevant.map((bucket) => bucket.percent));
|
|
317
|
-
const isLimited = profile.limitedUntil !== null && Date.parse(profile.limitedUntil) > nowMs;
|
|
318
|
-
const isEligible = profile.loggedIn !== false && !isLimited && profile.creditExhaustedAt === null && (maxPercent === null || maxPercent < 100);
|
|
319
537
|
return {
|
|
320
538
|
name: profile.name,
|
|
321
539
|
configDir: profile.configDir,
|
|
@@ -329,28 +547,16 @@ function buildClaudeProfilesReport(profiles, model, nowMs) {
|
|
|
329
547
|
isUsageStale: profile.usage?.isStale === true,
|
|
330
548
|
limitedUntil: profile.limitedUntil,
|
|
331
549
|
creditExhaustedAt: profile.creditExhaustedAt,
|
|
332
|
-
isEligible,
|
|
550
|
+
isEligible: checkIsClaudeProfileEligible(profile, relevant, nowMs),
|
|
333
551
|
headroomPercent: maxPercent === null ? null : 100 - maxPercent,
|
|
334
552
|
isRecommended: false,
|
|
335
553
|
};
|
|
336
554
|
});
|
|
337
|
-
const
|
|
338
|
-
|
|
339
|
-
.sort((a, b) => {
|
|
340
|
-
if (a.headroomPercent === null || b.headroomPercent === null) {
|
|
341
|
-
return (a.headroomPercent === null ? 1 : 0) - (b.headroomPercent === null ? 1 : 0);
|
|
342
|
-
}
|
|
343
|
-
if (a.headroomPercent !== b.headroomPercent)
|
|
344
|
-
return b.headroomPercent - a.headroomPercent;
|
|
345
|
-
return sumRelevantPercent(a, relevantBuckets) - sumRelevantPercent(b, relevantBuckets);
|
|
346
|
-
});
|
|
347
|
-
const recommended = ranked[0] ?? null;
|
|
555
|
+
const launch = getClaudeLaunchPick({ ...options, profiles, model, nowMs });
|
|
556
|
+
const recommended = entries.find((entry) => entry.name === launch.pick);
|
|
348
557
|
if (recommended)
|
|
349
558
|
recommended.isRecommended = true;
|
|
350
|
-
return { model, relevantBuckets, recommended:
|
|
351
|
-
}
|
|
352
|
-
function sumRelevantPercent(entry, kinds) {
|
|
353
|
-
return entry.buckets.filter((bucket) => kinds.includes(bucket.kind)).reduce((sum, bucket) => sum + bucket.percent, 0);
|
|
559
|
+
return { model, relevantBuckets, recommended: launch.pick, pickReason: launch.reason, nextAvailable: launch.nextAvailable, profiles: entries };
|
|
354
560
|
}
|
|
355
561
|
/**
|
|
356
562
|
* @description The ranking's view of every profile off the registry: `default` (its hidden record, when the
|
|
@@ -377,16 +583,10 @@ function buildClaudeProfileUsageViews(input) {
|
|
|
377
583
|
.sort(([, a], [, b]) => a.createdAt.localeCompare(b.createdAt));
|
|
378
584
|
return [...(isDefaultRemoved ? [] : [toView('default', input.records.default)]), ...added.map(([name, record]) => toView(name, record))];
|
|
379
585
|
}
|
|
380
|
-
/** The profile registry
|
|
381
|
-
function
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
parsed = JSON.parse(fs.readFileSync(path.join(dataDir, 'state.json'), 'utf8'));
|
|
385
|
-
}
|
|
386
|
-
catch {
|
|
387
|
-
return {};
|
|
388
|
-
}
|
|
389
|
-
const records = checkIsRecord(parsed) && checkIsRecord(parsed.claudeProfiles) ? parsed.claudeProfiles : {};
|
|
586
|
+
/** The profile registry out of a `state.json` already read (`stateFile.ts`): entries without a creation time are dropped. */
|
|
587
|
+
function getClaudeProfileRecordsFromState(stateFile) {
|
|
588
|
+
const registry = stateFile.claudeProfiles;
|
|
589
|
+
const records = checkIsRecord(registry) ? registry : {};
|
|
390
590
|
const result = {};
|
|
391
591
|
for (const [name, record] of Object.entries(records)) {
|
|
392
592
|
if (checkIsRecord(record) && typeof record.createdAt === 'string')
|