tailii-host 0.1.1 → 0.4.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/README.md +28 -10
- package/dist/{broker.d.ts → approval/broker.d.ts} +9 -5
- package/dist/{broker.js → approval/broker.js} +42 -6
- package/dist/approval/broker.js.map +1 -0
- package/dist/{hook.d.ts → approval/hook.d.ts} +48 -7
- package/dist/{hook.js → approval/hook.js} +359 -50
- package/dist/approval/hook.js.map +1 -0
- package/dist/backend/herdr.d.ts +260 -0
- package/dist/backend/herdr.js +838 -0
- package/dist/backend/herdr.js.map +1 -0
- package/dist/backend/sessionBackend.d.ts +81 -0
- package/dist/backend/sessionBackend.js +114 -0
- package/dist/backend/sessionBackend.js.map +1 -0
- package/dist/backend/tmux.d.ts +125 -0
- package/dist/backend/tmux.js +392 -0
- package/dist/backend/tmux.js.map +1 -0
- package/dist/{chatTailController.d.ts → chat/chatTailController.d.ts} +29 -6
- package/dist/{chatTailController.js → chat/chatTailController.js} +94 -18
- package/dist/chat/chatTailController.js.map +1 -0
- package/dist/{imageService.d.ts → chat/imageService.d.ts} +12 -1
- package/dist/{imageService.js → chat/imageService.js} +39 -11
- package/dist/chat/imageService.js.map +1 -0
- package/dist/chat/remoteQuestionMonitor.d.ts +27 -0
- package/dist/chat/remoteQuestionMonitor.js +128 -0
- package/dist/chat/remoteQuestionMonitor.js.map +1 -0
- package/dist/chat/subagentTailer.d.ts +30 -0
- package/dist/chat/subagentTailer.js +704 -0
- package/dist/chat/subagentTailer.js.map +1 -0
- package/dist/chat/subagentTranscript.d.ts +20 -0
- package/dist/chat/subagentTranscript.js +273 -0
- package/dist/chat/subagentTranscript.js.map +1 -0
- package/dist/{transcriptTailer.d.ts → chat/transcriptTailer.d.ts} +12 -1
- package/dist/{transcriptTailer.js → chat/transcriptTailer.js} +183 -10
- package/dist/chat/transcriptTailer.js.map +1 -0
- package/dist/cli.js +24 -10
- package/dist/cli.js.map +1 -1
- package/dist/codex/codexAccountUsage.d.ts +22 -0
- package/dist/codex/codexAccountUsage.js +128 -0
- package/dist/codex/codexAccountUsage.js.map +1 -0
- package/dist/codex/codexAppServer.d.ts +166 -0
- package/dist/codex/codexAppServer.js +1297 -0
- package/dist/codex/codexAppServer.js.map +1 -0
- package/dist/codex/codexNativeTurnController.d.ts +153 -0
- package/dist/codex/codexNativeTurnController.js +673 -0
- package/dist/codex/codexNativeTurnController.js.map +1 -0
- package/dist/codex/codexRolloutTailer.d.ts +100 -0
- package/dist/codex/codexRolloutTailer.js +568 -0
- package/dist/codex/codexRolloutTailer.js.map +1 -0
- package/dist/{codexSessionStore.d.ts → codex/codexSessionStore.d.ts} +10 -2
- package/dist/{codexSessionStore.js → codex/codexSessionStore.js} +184 -15
- package/dist/codex/codexSessionStore.js.map +1 -0
- package/dist/codex/codexSubagentTracker.d.ts +21 -0
- package/dist/codex/codexSubagentTracker.js +281 -0
- package/dist/codex/codexSubagentTracker.js.map +1 -0
- package/dist/codex/codexToolActivity.d.ts +69 -0
- package/dist/codex/codexToolActivity.js +425 -0
- package/dist/codex/codexToolActivity.js.map +1 -0
- package/dist/{codexUsage.d.ts → codex/codexUsage.d.ts} +1 -1
- package/dist/{codexUsage.js → codex/codexUsage.js} +19 -26
- package/dist/codex/codexUsage.js.map +1 -0
- package/dist/commands/doctor.d.ts +65 -0
- package/dist/commands/doctor.js +425 -0
- package/dist/commands/doctor.js.map +1 -0
- package/dist/{hookSettings.d.ts → commands/hookSettings.d.ts} +14 -1
- package/dist/{hookSettings.js → commands/hookSettings.js} +96 -12
- package/dist/commands/hookSettings.js.map +1 -0
- package/dist/{kick.js → commands/kick.js} +16 -1
- package/dist/commands/kick.js.map +1 -0
- package/dist/{launch.d.ts → commands/launch.d.ts} +67 -5
- package/dist/commands/launch.js +716 -0
- package/dist/commands/launch.js.map +1 -0
- package/dist/commands/legacyHomeMigration.js.map +1 -0
- package/dist/{pairingCode.d.ts → commands/pairingCode.d.ts} +29 -2
- package/dist/{pairingCode.js → commands/pairingCode.js} +120 -11
- package/dist/commands/pairingCode.js.map +1 -0
- package/dist/{pushTokenCommand.d.ts → commands/pushTokenCommand.d.ts} +1 -1
- package/dist/{pushTokenCommand.js → commands/pushTokenCommand.js} +2 -2
- package/dist/commands/pushTokenCommand.js.map +1 -0
- package/dist/commands/selfUpdate.d.ts +71 -0
- package/dist/commands/selfUpdate.js +536 -0
- package/dist/commands/selfUpdate.js.map +1 -0
- package/dist/{setup.d.ts → commands/setup.d.ts} +17 -6
- package/dist/{setup.js → commands/setup.js} +133 -75
- package/dist/commands/setup.js.map +1 -0
- package/dist/engine/context.d.ts +145 -0
- package/dist/engine/context.js +184 -0
- package/dist/engine/context.js.map +1 -0
- package/dist/engine/engine.d.ts +121 -0
- package/dist/engine/engine.js +808 -0
- package/dist/engine/engine.js.map +1 -0
- package/dist/engine/handlers/accountUsage.d.ts +53 -0
- package/dist/engine/handlers/accountUsage.js +203 -0
- package/dist/engine/handlers/accountUsage.js.map +1 -0
- package/dist/engine/handlers/claudeModels.d.ts +2 -0
- package/dist/engine/handlers/claudeModels.js +23 -0
- package/dist/engine/handlers/claudeModels.js.map +1 -0
- package/dist/engine/handlers/codex.d.ts +2 -0
- package/dist/engine/handlers/codex.js +97 -0
- package/dist/engine/handlers/codex.js.map +1 -0
- package/dist/engine/handlers/conversation.d.ts +2 -0
- package/dist/engine/handlers/conversation.js +259 -0
- package/dist/engine/handlers/conversation.js.map +1 -0
- package/dist/engine/handlers/core.d.ts +2 -0
- package/dist/engine/handlers/core.js +66 -0
- package/dist/engine/handlers/core.js.map +1 -0
- package/dist/engine/handlers/git.d.ts +2 -0
- package/dist/engine/handlers/git.js +127 -0
- package/dist/engine/handlers/git.js.map +1 -0
- package/dist/engine/handlers/index.d.ts +2 -0
- package/dist/engine/handlers/index.js +34 -0
- package/dist/engine/handlers/index.js.map +1 -0
- package/dist/engine/handlers/mode.d.ts +2 -0
- package/dist/engine/handlers/mode.js +194 -0
- package/dist/engine/handlers/mode.js.map +1 -0
- package/dist/engine/handlers/officialApps.d.ts +2 -0
- package/dist/engine/handlers/officialApps.js +79 -0
- package/dist/engine/handlers/officialApps.js.map +1 -0
- package/dist/engine/handlers/preview.d.ts +2 -0
- package/dist/engine/handlers/preview.js +59 -0
- package/dist/engine/handlers/preview.js.map +1 -0
- package/dist/engine/handlers/selfUpdate.d.ts +2 -0
- package/dist/engine/handlers/selfUpdate.js +52 -0
- package/dist/engine/handlers/selfUpdate.js.map +1 -0
- package/dist/engine/handlers/session.d.ts +2 -0
- package/dist/engine/handlers/session.js +385 -0
- package/dist/engine/handlers/session.js.map +1 -0
- package/dist/engine/handlers/usage.d.ts +2 -0
- package/dist/engine/handlers/usage.js +96 -0
- package/dist/engine/handlers/usage.js.map +1 -0
- package/dist/engine/handlers/workspace.d.ts +2 -0
- package/dist/engine/handlers/workspace.js +110 -0
- package/dist/engine/handlers/workspace.js.map +1 -0
- package/dist/engine/slashCommands.d.ts +3 -0
- package/dist/engine/slashCommands.js +211 -0
- package/dist/engine/slashCommands.js.map +1 -0
- package/dist/hub/engineRelaySocket.d.ts +58 -0
- package/dist/hub/engineRelaySocket.js +161 -0
- package/dist/hub/engineRelaySocket.js.map +1 -0
- package/dist/hub/hubClient.d.ts +28 -0
- package/dist/hub/hubClient.js +187 -0
- package/dist/hub/hubClient.js.map +1 -0
- package/dist/hub/hubDaemon.d.ts +69 -0
- package/dist/hub/hubDaemon.js +466 -0
- package/dist/hub/hubDaemon.js.map +1 -0
- package/dist/hub/hubProtocol.d.ts +161 -0
- package/dist/hub/hubProtocol.js +379 -0
- package/dist/hub/hubProtocol.js.map +1 -0
- package/dist/hub/panePreviewPump.d.ts +65 -0
- package/dist/hub/panePreviewPump.js +187 -0
- package/dist/hub/panePreviewPump.js.map +1 -0
- package/dist/hub/questionInjection.d.ts +19 -0
- package/dist/hub/questionInjection.js +126 -0
- package/dist/hub/questionInjection.js.map +1 -0
- package/dist/hub/reaper.d.ts +74 -0
- package/dist/hub/reaper.js +333 -0
- package/dist/hub/reaper.js.map +1 -0
- package/dist/hub/sessionHub.d.ts +203 -0
- package/dist/hub/sessionHub.js +1862 -0
- package/dist/hub/sessionHub.js.map +1 -0
- package/dist/protocol/common.d.ts +18 -0
- package/dist/protocol/common.js +78 -0
- package/dist/protocol/common.js.map +1 -0
- package/dist/protocol/decode.d.ts +3 -0
- package/dist/protocol/decode.js +1058 -0
- package/dist/protocol/decode.js.map +1 -0
- package/dist/protocol/encode.d.ts +3 -0
- package/dist/protocol/encode.js +84 -0
- package/dist/protocol/encode.js.map +1 -0
- package/dist/protocol/messages.d.ts +1025 -0
- package/dist/protocol/messages.js +8 -0
- package/dist/protocol/messages.js.map +1 -0
- package/dist/protocol.d.ts +4 -329
- package/dist/protocol.js +13 -531
- package/dist/protocol.js.map +1 -1
- package/dist/push/apnsConfigStore.js.map +1 -0
- package/dist/push/apnsJwtProvider.js.map +1 -0
- package/dist/{apnsSender.js.map → push/apnsSender.js.map} +1 -1
- package/dist/{approvalPushNotifier.js → push/approvalPushNotifier.js} +1 -1
- package/dist/push/approvalPushNotifier.js.map +1 -0
- package/dist/push/deviceTokenStore.js.map +1 -0
- package/dist/{pushTypes.js → push/pushTypes.js} +1 -1
- package/dist/push/pushTypes.js.map +1 -0
- package/dist/push/sendLog.js.map +1 -0
- package/dist/services/accountIdentity.d.ts +44 -0
- package/dist/services/accountIdentity.js +184 -0
- package/dist/services/accountIdentity.js.map +1 -0
- package/dist/services/claudeCredentialRefresh.d.ts +30 -0
- package/dist/services/claudeCredentialRefresh.js +345 -0
- package/dist/services/claudeCredentialRefresh.js.map +1 -0
- package/dist/services/claudeModelCatalog.d.ts +21 -0
- package/dist/services/claudeModelCatalog.js +181 -0
- package/dist/services/claudeModelCatalog.js.map +1 -0
- package/dist/{dirLister.d.ts → services/dirLister.d.ts} +9 -4
- package/dist/services/dirLister.js +169 -0
- package/dist/services/dirLister.js.map +1 -0
- package/dist/services/fileService.d.ts +10 -0
- package/dist/services/fileService.js +123 -0
- package/dist/services/fileService.js.map +1 -0
- package/dist/services/gitService.d.ts +79 -0
- package/dist/services/gitService.js +648 -0
- package/dist/services/gitService.js.map +1 -0
- package/dist/services/hostVersions.d.ts +38 -0
- package/dist/services/hostVersions.js +120 -0
- package/dist/services/hostVersions.js.map +1 -0
- package/dist/services/officialApps.d.ts +148 -0
- package/dist/services/officialApps.js +1079 -0
- package/dist/services/officialApps.js.map +1 -0
- package/dist/services/planUsageFetcher.d.ts +119 -0
- package/dist/services/planUsageFetcher.js +357 -0
- package/dist/services/planUsageFetcher.js.map +1 -0
- package/dist/services/previewServer.d.ts +31 -0
- package/dist/services/previewServer.js +233 -0
- package/dist/services/previewServer.js.map +1 -0
- package/dist/services/quicGateway.d.ts +143 -0
- package/dist/services/quicGateway.js +292 -0
- package/dist/services/quicGateway.js.map +1 -0
- package/dist/services/serveService.d.ts +50 -0
- package/dist/services/serveService.js +302 -0
- package/dist/services/serveService.js.map +1 -0
- package/dist/services/usageAggregator.js.map +1 -0
- package/dist/sessions/claudeSessionStore.d.ts +80 -0
- package/dist/sessions/claudeSessionStore.js +477 -0
- package/dist/sessions/claudeSessionStore.js.map +1 -0
- package/dist/sessions/heartbeat.d.ts +24 -0
- package/dist/sessions/heartbeat.js +86 -0
- package/dist/sessions/heartbeat.js.map +1 -0
- package/dist/sessions/liveSessionJoin.d.ts +20 -0
- package/dist/sessions/liveSessionJoin.js +80 -0
- package/dist/sessions/liveSessionJoin.js.map +1 -0
- package/dist/sessions/sessionActivityProvider.d.ts +14 -0
- package/dist/sessions/sessionActivityProvider.js +57 -0
- package/dist/sessions/sessionActivityProvider.js.map +1 -0
- package/dist/{sessionListService.d.ts → sessions/sessionListService.d.ts} +3 -3
- package/dist/{sessionListService.js → sessions/sessionListService.js} +23 -6
- package/dist/sessions/sessionListService.js.map +1 -0
- package/dist/{sessionMetadataStore.d.ts → sessions/sessionMetadataStore.d.ts} +18 -0
- package/dist/{sessionMetadataStore.js → sessions/sessionMetadataStore.js} +36 -1
- package/dist/sessions/sessionMetadataStore.js.map +1 -0
- package/dist/{sessionSearch.d.ts → sessions/sessionSearch.d.ts} +1 -1
- package/dist/sessions/sessionSearch.js.map +1 -0
- package/dist/shared/hostDisplayName.d.ts +11 -0
- package/dist/shared/hostDisplayName.js +50 -0
- package/dist/shared/hostDisplayName.js.map +1 -0
- package/dist/{lineWriter.d.ts → shared/lineWriter.d.ts} +1 -1
- package/dist/{lineWriter.js → shared/lineWriter.js} +1 -1
- package/dist/shared/lineWriter.js.map +1 -0
- package/dist/{observationLog.js.map → shared/observationLog.js.map} +1 -1
- package/dist/{paths.d.ts → shared/paths.d.ts} +7 -0
- package/dist/{paths.js → shared/paths.js} +9 -0
- package/dist/shared/paths.js.map +1 -0
- package/dist/shared/permissionMode.d.ts +10 -0
- package/dist/shared/permissionMode.js +51 -0
- package/dist/shared/permissionMode.js.map +1 -0
- package/dist/shared/skillInjection.d.ts +9 -0
- package/dist/shared/skillInjection.js +16 -0
- package/dist/shared/skillInjection.js.map +1 -0
- package/dist/shared/sleep.js.map +1 -0
- package/dist/{socketPath.d.ts → shared/socketPath.d.ts} +4 -0
- package/dist/{socketPath.js → shared/socketPath.js} +22 -0
- package/dist/shared/socketPath.js.map +1 -0
- package/dist/shared/version.js.map +1 -0
- package/package.json +13 -7
- package/dist/apnsConfigStore.js.map +0 -1
- package/dist/apnsJwtProvider.js.map +0 -1
- package/dist/approvalPushNotifier.js.map +0 -1
- package/dist/broker.js.map +0 -1
- package/dist/chatTailController.js.map +0 -1
- package/dist/claudeSessionStore.d.ts +0 -15
- package/dist/claudeSessionStore.js +0 -201
- package/dist/claudeSessionStore.js.map +0 -1
- package/dist/codexRolloutTailer.d.ts +0 -56
- package/dist/codexRolloutTailer.js +0 -303
- package/dist/codexRolloutTailer.js.map +0 -1
- package/dist/codexSessionStore.js.map +0 -1
- package/dist/codexUsage.js.map +0 -1
- package/dist/deviceTokenStore.js.map +0 -1
- package/dist/dirLister.js +0 -98
- package/dist/dirLister.js.map +0 -1
- package/dist/doctor.d.ts +0 -36
- package/dist/doctor.js +0 -162
- package/dist/doctor.js.map +0 -1
- package/dist/engine.d.ts +0 -85
- package/dist/engine.js +0 -962
- package/dist/engine.js.map +0 -1
- package/dist/hook.js.map +0 -1
- package/dist/hookSettings.js.map +0 -1
- package/dist/idleReaper.d.ts +0 -13
- package/dist/idleReaper.js +0 -30
- package/dist/idleReaper.js.map +0 -1
- package/dist/imageService.js.map +0 -1
- package/dist/kick.js.map +0 -1
- package/dist/launch.js +0 -396
- package/dist/launch.js.map +0 -1
- package/dist/legacyHomeMigration.js.map +0 -1
- package/dist/lineWriter.js.map +0 -1
- package/dist/mdnsAdvertiser.d.ts +0 -46
- package/dist/mdnsAdvertiser.js +0 -268
- package/dist/mdnsAdvertiser.js.map +0 -1
- package/dist/pairingCode.js.map +0 -1
- package/dist/paths.js.map +0 -1
- package/dist/permissionMode.d.ts +0 -8
- package/dist/permissionMode.js +0 -32
- package/dist/permissionMode.js.map +0 -1
- package/dist/planUsageFetcher.d.ts +0 -35
- package/dist/planUsageFetcher.js +0 -172
- package/dist/planUsageFetcher.js.map +0 -1
- package/dist/pushTokenCommand.js.map +0 -1
- package/dist/pushTypes.js.map +0 -1
- package/dist/sendLog.js.map +0 -1
- package/dist/sessionActivityProvider.d.ts +0 -7
- package/dist/sessionActivityProvider.js +0 -44
- package/dist/sessionActivityProvider.js.map +0 -1
- package/dist/sessionIdleTracker.d.ts +0 -19
- package/dist/sessionIdleTracker.js +0 -42
- package/dist/sessionIdleTracker.js.map +0 -1
- package/dist/sessionListService.js.map +0 -1
- package/dist/sessionMetadataStore.js.map +0 -1
- package/dist/sessionSearch.js.map +0 -1
- package/dist/setup.js.map +0 -1
- package/dist/sleep.js.map +0 -1
- package/dist/socketPath.js.map +0 -1
- package/dist/subagentTailer.d.ts +0 -15
- package/dist/subagentTailer.js +0 -399
- package/dist/subagentTailer.js.map +0 -1
- package/dist/tmux.d.ts +0 -62
- package/dist/tmux.js +0 -163
- package/dist/tmux.js.map +0 -1
- package/dist/transcriptTailer.js.map +0 -1
- package/dist/usageAggregator.js.map +0 -1
- package/dist/version.js.map +0 -1
- /package/dist/{kick.d.ts → commands/kick.d.ts} +0 -0
- /package/dist/{legacyHomeMigration.d.ts → commands/legacyHomeMigration.d.ts} +0 -0
- /package/dist/{legacyHomeMigration.js → commands/legacyHomeMigration.js} +0 -0
- /package/dist/{apnsConfigStore.d.ts → push/apnsConfigStore.d.ts} +0 -0
- /package/dist/{apnsConfigStore.js → push/apnsConfigStore.js} +0 -0
- /package/dist/{apnsJwtProvider.d.ts → push/apnsJwtProvider.d.ts} +0 -0
- /package/dist/{apnsJwtProvider.js → push/apnsJwtProvider.js} +0 -0
- /package/dist/{apnsSender.d.ts → push/apnsSender.d.ts} +0 -0
- /package/dist/{apnsSender.js → push/apnsSender.js} +0 -0
- /package/dist/{approvalPushNotifier.d.ts → push/approvalPushNotifier.d.ts} +0 -0
- /package/dist/{deviceTokenStore.d.ts → push/deviceTokenStore.d.ts} +0 -0
- /package/dist/{deviceTokenStore.js → push/deviceTokenStore.js} +0 -0
- /package/dist/{pushTypes.d.ts → push/pushTypes.d.ts} +0 -0
- /package/dist/{sendLog.d.ts → push/sendLog.d.ts} +0 -0
- /package/dist/{sendLog.js → push/sendLog.js} +0 -0
- /package/dist/{usageAggregator.d.ts → services/usageAggregator.d.ts} +0 -0
- /package/dist/{usageAggregator.js → services/usageAggregator.js} +0 -0
- /package/dist/{sessionSearch.js → sessions/sessionSearch.js} +0 -0
- /package/dist/{observationLog.d.ts → shared/observationLog.d.ts} +0 -0
- /package/dist/{observationLog.js → shared/observationLog.js} +0 -0
- /package/dist/{sleep.d.ts → shared/sleep.d.ts} +0 -0
- /package/dist/{sleep.js → shared/sleep.js} +0 -0
- /package/dist/{version.d.ts → shared/version.d.ts} +0 -0
- /package/dist/{version.js → shared/version.js} +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"approvalPushNotifier.js","sourceRoot":"","sources":["../../src/push/approvalPushNotifier.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deviceTokenStore.js","sourceRoot":"","sources":["../../src/push/deviceTokenStore.ts"],"names":[],"mappings":"AAAA,sBAAsB;AACtB,wCAAwC;AACxC,sCAAsC;AACtC,EAAE;AACF,qEAAqE;AACrE,iEAAiE;AACjE,8DAA8D;AAE9D,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,OAAO,EAAiB,eAAe,EAAE,mBAAmB,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAyBjG;;;;GAIG;AACH,MAAM,OAAO,gBAAgB;IACV,IAAI,CAAS;IAE9B,YAAY,IAAa;QACvB,IAAI,CAAC,IAAI,GAAG,IAAI,IAAI,eAAe,EAAE,CAAC;IACxC,CAAC;IAED,IAAY,OAAO;QACjB,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,mBAAmB,CAAC,CAAC;IACnD,CAAC;IAED,0DAA0D;IAC1D,IAAI;QACF,IAAI,GAAY,CAAC;QACjB,IAAI,CAAC;YACH,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC;QAC1D,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,IAAI,CAAC;QACd,CAAC;QACD,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG,KAAK,IAAI,IAAI,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC;YAAE,OAAO,IAAI,CAAC;QAC/E,MAAM,GAAG,GAAG,GAA8B,CAAC;QAC3C,IACE,OAAO,GAAG,CAAC,OAAO,CAAC,KAAK,QAAQ;YAChC,CAAC,UAAU,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;YAC/B,OAAO,GAAG,CAAC,UAAU,CAAC,KAAK,QAAQ;YACnC,OAAO,GAAG,CAAC,WAAW,CAAC,KAAK,QAAQ,EACpC,CAAC;YACD,OAAO,IAAI,CAAC;QACd,CAAC;QACD,OAAO;YACL,KAAK,EAAE,GAAG,CAAC,OAAO,CAAC;YACnB,WAAW,EAAE,GAAG,CAAC,aAAa,CAAC;YAC/B,QAAQ,EAAE,GAAG,CAAC,UAAU,CAAC;YACzB,SAAS,EAAE,GAAG,CAAC,WAAW,CAAC;SAC5B,CAAC;IACJ,CAAC;IAED,wDAAwD;IACxD,IAAI,CAAC,MAAyB;QAC5B,mBAAmB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC/B,kDAAkD;QAClD,MAAM,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC;YAC7B,QAAQ,EAAE,MAAM,CAAC,QAAQ;YACzB,WAAW,EAAE,MAAM,CAAC,WAAW;YAC/B,KAAK,EAAE,MAAM,CAAC,KAAK;YACnB,SAAS,EAAE,MAAM,CAAC,SAAS;SAC5B,CAAC,CAAC;QACH,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,OAAO,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;QACzD,uDAAuD;QACvD,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;IACpC,CAAC;IAED,sDAAsD;IACtD,MAAM;QACJ,IAAI,CAAC;YACH,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAC1B,CAAC;QAAC,MAAM,CAAC;YACP,uCAAuC;QACzC,CAAC;IACH,CAAC;CACF"}
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
// 秘密(.p8/token)・diff・cwd 本文を payload/ログに載せない(Requirement 6.5, 2.3)。
|
|
6
6
|
import * as os from "node:os";
|
|
7
7
|
import * as path from "node:path";
|
|
8
|
-
import { ensureDirectory0700 } from "
|
|
8
|
+
import { ensureDirectory0700 } from "../shared/paths.js";
|
|
9
9
|
/** 当該環境の APNs ホスト名(token の environment から送信ホストを写像)。 */
|
|
10
10
|
export function apnsSendHost(environment) {
|
|
11
11
|
return environment === "production" ? "api.push.apple.com" : "api.sandbox.push.apple.com";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pushTypes.js","sourceRoot":"","sources":["../../src/push/pushTypes.ts"],"names":[],"mappings":"AAAA,eAAe;AACf,yCAAyC;AACzC,kFAAkF;AAClF,EAAE;AACF,oEAAoE;AAEpE,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAUzD,uDAAuD;AACvD,MAAM,UAAU,YAAY,CAAC,WAAqB;IAChD,OAAO,WAAW,KAAK,YAAY,CAAC,CAAC,CAAC,oBAAoB,CAAC,CAAC,CAAC,4BAA4B,CAAC;AAC5F,CAAC;AAED,gCAAgC;AAChC,MAAM,UAAU,UAAU,CAAC,KAAc;IACvC,OAAO,KAAK,KAAK,YAAY,IAAI,KAAK,KAAK,SAAS,CAAC;AACvD,CAAC;AAeD,0CAA0C;AAC1C,MAAM,UAAU,eAAe,CAAC,CAAY,EAAE,CAAY;IACxD,IAAI,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,IAAI;QAAE,OAAO,KAAK,CAAC;IACpC,IAAI,CAAC,CAAC,IAAI,KAAK,WAAW,IAAI,CAAC,CAAC,IAAI,KAAK,WAAW;QAAE,OAAO,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,MAAM,CAAC;IACnF,IAAI,CAAC,CAAC,IAAI,KAAK,MAAM,IAAI,CAAC,CAAC,IAAI,KAAK,MAAM;QAAE,OAAO,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,MAAM,CAAC;IAClG,OAAO,IAAI,CAAC;AACd,CAAC;AAED,kCAAkC;AAElC,4CAA4C;AAC5C,MAAM,UAAU,eAAe;IAC7B,OAAO,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,MAAM,CAAC,CAAC;AACpD,CAAC;AAED,kDAAkD;AAClD,MAAM,UAAU,mBAAmB,CAAC,IAAY;IAC9C,mBAAmB,CAAC,IAAI,CAAC,CAAC;AAC5B,CAAC;AAED,sBAAsB;AAEtB;;;;;;GAMG;AACH,MAAM,UAAU,eAAe,CAAC,UAAkB,EAAE,IAAY,EAAE,OAAe;IAC/E,MAAM,KAAK,GAAG,EAAE,IAAI,EAAE,GAAG,IAAI,MAAM,OAAO,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC;IAC9D,MAAM,GAAG,GAAG;QACV,KAAK;QACL,oBAAoB,EAAE,gBAAgB;QACtC,KAAK,EAAE,SAAS;QAChB,WAAW,EAAE,OAAO;KACrB,CAAC;IACF,MAAM,IAAI,GAAG,EAAE,UAAU,EAAE,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;IAChD,OAAO,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC;AAC7D,CAAC;AAED,wDAAwD;AACxD,SAAS,QAAQ,CAAC,KAAc;IAC9B,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IACrD,IAAI,KAAK,KAAK,IAAI,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAChD,MAAM,GAAG,GAAG,KAAgC,CAAC;QAC7C,MAAM,MAAM,GAA4B,EAAE,CAAC;QAC3C,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE;YAAE,MAAM,CAAC,GAAG,CAAC,GAAG,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;QAC5E,OAAO,MAAM,CAAC;IAChB,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sendLog.js","sourceRoot":"","sources":["../../src/push/sendLog.ts"],"names":[],"mappings":"AAAA,aAAa;AACb,wCAAwC;AACxC,6BAA6B;AAC7B,EAAE;AACF,2EAA2E;AAC3E,mDAAmD;AACnD,qDAAqD;AAErD,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,OAAO,EAAE,eAAe,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAEtE,8CAA8C;AAC9C,MAAM,OAAO,OAAO;IACD,IAAI,CAAS;IAE9B,YAAY,IAAa;QACvB,IAAI,CAAC,IAAI,GAAG,IAAI,IAAI,eAAe,EAAE,CAAC;IACxC,CAAC;IAED,IAAY,OAAO;QACjB,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,eAAe,CAAC,CAAC;IAC/C,CAAC;IAED,gDAAgD;IAChD,QAAQ,CAAC,OAAe;QACtB,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,CAAC;QACnC,OAAO,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC;IAClD,CAAC;IAED,qCAAqC;IACrC,MAAM,CAAC,OAAe,EAAE,EAAU;QAChC,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;QACxB,GAAG,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC;QAClB,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACjB,CAAC;IAED,4CAA4C;IACpC,IAAI;QACV,IAAI,GAAY,CAAC;QACjB,IAAI,CAAC;YACH,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC;QAC1D,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,EAAE,CAAC;QACZ,CAAC;QACD,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG,KAAK,IAAI,IAAI,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC;YAAE,OAAO,EAAE,CAAC;QAC7E,MAAM,MAAM,GAA2B,EAAE,CAAC;QAC1C,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,GAA8B,CAAC,EAAE,CAAC;YAC1E,IAAI,OAAO,KAAK,KAAK,QAAQ;gBAAE,MAAM,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;QACrD,CAAC;QACD,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,0DAA0D;IAClD,IAAI,CAAC,GAA2B;QACtC,IAAI,CAAC;YACH,mBAAmB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAC/B,MAAM,MAAM,GAA2B,EAAE,CAAC;YAC1C,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE;gBAAE,MAAM,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC,GAAG,CAAE,CAAC;YACnE,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;YACxE,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;QACpC,CAAC;QAAC,MAAM,CAAC;YACP,yBAAyB;QAC3B,CAAC;IACH,CAAC;CACF"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/** 使用量カードへ出すマスク済みアカウント(取れなかった側は省略)。 */
|
|
2
|
+
export interface AccountIdentities {
|
|
3
|
+
claude?: string;
|
|
4
|
+
codex?: string;
|
|
5
|
+
}
|
|
6
|
+
/** engine へ注入するフェッチャの型(テストは固定値を注入する)。 */
|
|
7
|
+
export type AccountIdentityProvider = () => Promise<AccountIdentities>;
|
|
8
|
+
/** `claude auth status --json` に与える timeout(ms)。 */
|
|
9
|
+
export declare const ACCOUNT_IDENTITY_TIMEOUT_MS = 3000;
|
|
10
|
+
/** `~/.codex/auth.json` の読み込み上限(バイト)。異常に大きいファイルは読まない。 */
|
|
11
|
+
export declare const CODEX_AUTH_MAX_BYTES: number;
|
|
12
|
+
/** 子プロセス実行の注入点(テストは実 CLI を起動しない偽 exec を注入する)。 */
|
|
13
|
+
export type AccountExec = (command: string, args: readonly string[], timeoutMs: number) => Promise<string | null>;
|
|
14
|
+
/**
|
|
15
|
+
* email をマスクする(純ロジック, TESTABLE)。`alice@example.com` → `a***@example.com`。
|
|
16
|
+
*
|
|
17
|
+
* local part が空・`@` が無い/複数・domain が空や制御文字入りなど不正形は **undefined**
|
|
18
|
+
* (=「載せない」)。マスクできない値をそのまま出すくらいなら、行ごと出さない。
|
|
19
|
+
*/
|
|
20
|
+
export declare function maskEmail(raw: string | null | undefined): string | undefined;
|
|
21
|
+
/**
|
|
22
|
+
* JWT(id_token)の payload から `email` claim を取り出す(純ロジック, TESTABLE)。
|
|
23
|
+
* 署名は検証しない(表示専用)。形が違えば undefined。
|
|
24
|
+
*/
|
|
25
|
+
export declare function emailFromIdToken(token: unknown): string | undefined;
|
|
26
|
+
/**
|
|
27
|
+
* `claude auth status --json` の出力から email を取り出す(純ロジック, TESTABLE)。
|
|
28
|
+
* `loggedIn: false` は「アカウント無し」なので undefined。
|
|
29
|
+
*/
|
|
30
|
+
export declare function emailFromClaudeAuthStatus(raw: string | null): string | undefined;
|
|
31
|
+
/** `auth.json` 本文から Codex アカウントの email を取り出す(純ロジック, TESTABLE)。 */
|
|
32
|
+
export declare function emailFromCodexAuthJson(raw: string | null): string | undefined;
|
|
33
|
+
export interface CollectAccountIdentitiesOptions {
|
|
34
|
+
exec?: AccountExec;
|
|
35
|
+
/** `~/.codex/auth.json` の本文を返す読み取り(テストは fixture を注入する)。 */
|
|
36
|
+
readCodexAuth?: () => string | null;
|
|
37
|
+
timeoutMs?: number;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* 両 agent のマスク済みアカウントを集める(キャッシュ無し。テストはここを直接叩く)。
|
|
41
|
+
* 取れなかった側は省略する。生 email はここから外へ出ない。
|
|
42
|
+
*/
|
|
43
|
+
export declare function collectAccountIdentities(options?: CollectAccountIdentitiesOptions): Promise<AccountIdentities>;
|
|
44
|
+
export declare function fetchAccountIdentities(): Promise<AccountIdentities>;
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
// accountIdentity.ts
|
|
2
|
+
// tailii (TS host) — 「どのアカウントの使用量か」の表示用 ID(account-usage)
|
|
3
|
+
//
|
|
4
|
+
// 使用量シートの各カードに、ログイン中アカウントを**マスク済み**で 1 行出すための取得層。
|
|
5
|
+
//
|
|
6
|
+
// 秘密の扱い(この層の存在理由):
|
|
7
|
+
// - 生の email はここから外へ出さない。**マスクは host 側で行い、ワイヤーへは
|
|
8
|
+
// `a***@example.com` 形式のマスク済み文字列しか載せない**(ログにも生値を出さない)。
|
|
9
|
+
// - Codex 側は id_token(JWT)を読むが、トークン文字列そのものはワイヤー・ログへ載せない。
|
|
10
|
+
// 署名検証はしない — CLI 自身が管理するローカルファイルの、表示専用の読み取りなので
|
|
11
|
+
// 「改竄されていたら表示が変わるだけ」で済む(mocovia と同じ割り切り)。
|
|
12
|
+
//
|
|
13
|
+
// 取得元:
|
|
14
|
+
// - Claude … `claude auth status --json` の `email`(2.1.220 実測。キーは camelCase で
|
|
15
|
+
// `loggedIn` / `authMethod` / `apiProvider` / `email` / `subscriptionType`)。
|
|
16
|
+
// - Codex … `~/.codex/auth.json` の `tokens.id_token` の claims `email`。
|
|
17
|
+
//
|
|
18
|
+
// アカウント切替はまれなので、hostVersions と同じ**プロセス内キャッシュ**で 1 回だけ取る。
|
|
19
|
+
import { execFile } from "node:child_process";
|
|
20
|
+
import * as fs from "node:fs";
|
|
21
|
+
import * as os from "node:os";
|
|
22
|
+
import * as path from "node:path";
|
|
23
|
+
import { defaultInjectedPath } from "../commands/launch.js";
|
|
24
|
+
/** `claude auth status --json` に与える timeout(ms)。 */
|
|
25
|
+
export const ACCOUNT_IDENTITY_TIMEOUT_MS = 3_000;
|
|
26
|
+
/** `~/.codex/auth.json` の読み込み上限(バイト)。異常に大きいファイルは読まない。 */
|
|
27
|
+
export const CODEX_AUTH_MAX_BYTES = 256 * 1024;
|
|
28
|
+
/**
|
|
29
|
+
* email をマスクする(純ロジック, TESTABLE)。`alice@example.com` → `a***@example.com`。
|
|
30
|
+
*
|
|
31
|
+
* local part が空・`@` が無い/複数・domain が空や制御文字入りなど不正形は **undefined**
|
|
32
|
+
* (=「載せない」)。マスクできない値をそのまま出すくらいなら、行ごと出さない。
|
|
33
|
+
*/
|
|
34
|
+
export function maskEmail(raw) {
|
|
35
|
+
if (typeof raw !== "string")
|
|
36
|
+
return undefined;
|
|
37
|
+
const email = raw.trim();
|
|
38
|
+
const at = email.indexOf("@");
|
|
39
|
+
if (at <= 0)
|
|
40
|
+
return undefined;
|
|
41
|
+
const local = email.slice(0, at);
|
|
42
|
+
const domain = email.slice(at + 1);
|
|
43
|
+
if (domain.length === 0 || domain.length > 128)
|
|
44
|
+
return undefined;
|
|
45
|
+
if (domain.includes("@"))
|
|
46
|
+
return undefined;
|
|
47
|
+
// 制御文字・空白を含む domain は表示に載せない(ログ・UI の汚染防止)。
|
|
48
|
+
if ([...domain].some(isUnsafeLabelChar))
|
|
49
|
+
return undefined;
|
|
50
|
+
const first = [...local][0];
|
|
51
|
+
if (first === undefined)
|
|
52
|
+
return undefined;
|
|
53
|
+
return `${first}***@${domain}`;
|
|
54
|
+
}
|
|
55
|
+
/** domain ラベルに現れてはいけない文字(制御文字・空白)。 */
|
|
56
|
+
function isUnsafeLabelChar(character) {
|
|
57
|
+
const code = character.codePointAt(0) ?? 0;
|
|
58
|
+
return code <= 0x20 || code === 0x7f;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* JWT(id_token)の payload から `email` claim を取り出す(純ロジック, TESTABLE)。
|
|
62
|
+
* 署名は検証しない(表示専用)。形が違えば undefined。
|
|
63
|
+
*/
|
|
64
|
+
export function emailFromIdToken(token) {
|
|
65
|
+
if (typeof token !== "string")
|
|
66
|
+
return undefined;
|
|
67
|
+
const parts = token.split(".");
|
|
68
|
+
if (parts.length !== 3)
|
|
69
|
+
return undefined;
|
|
70
|
+
const payload = parts[1];
|
|
71
|
+
if (payload === undefined || payload.length === 0)
|
|
72
|
+
return undefined;
|
|
73
|
+
try {
|
|
74
|
+
const json = Buffer.from(payload, "base64url").toString("utf8");
|
|
75
|
+
const claims = JSON.parse(json);
|
|
76
|
+
if (typeof claims !== "object" || claims === null)
|
|
77
|
+
return undefined;
|
|
78
|
+
const email = claims["email"];
|
|
79
|
+
return typeof email === "string" && email.length > 0 ? email : undefined;
|
|
80
|
+
}
|
|
81
|
+
catch {
|
|
82
|
+
return undefined;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* `claude auth status --json` の出力から email を取り出す(純ロジック, TESTABLE)。
|
|
87
|
+
* `loggedIn: false` は「アカウント無し」なので undefined。
|
|
88
|
+
*/
|
|
89
|
+
export function emailFromClaudeAuthStatus(raw) {
|
|
90
|
+
if (raw === null)
|
|
91
|
+
return undefined;
|
|
92
|
+
try {
|
|
93
|
+
const parsed = JSON.parse(raw.trim());
|
|
94
|
+
if (typeof parsed !== "object" || parsed === null)
|
|
95
|
+
return undefined;
|
|
96
|
+
const rec = parsed;
|
|
97
|
+
if (rec["loggedIn"] === false)
|
|
98
|
+
return undefined;
|
|
99
|
+
const email = rec["email"];
|
|
100
|
+
return typeof email === "string" && email.length > 0 ? email : undefined;
|
|
101
|
+
}
|
|
102
|
+
catch {
|
|
103
|
+
return undefined;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
/** 既定の exec(PATH を launch と揃え、timeout で必ず戻る)。 */
|
|
107
|
+
const defaultExec = (command, args, timeoutMs) => new Promise((resolve) => {
|
|
108
|
+
execFile(command, [...args], {
|
|
109
|
+
cwd: os.homedir(),
|
|
110
|
+
timeout: timeoutMs,
|
|
111
|
+
maxBuffer: 64 * 1024,
|
|
112
|
+
env: {
|
|
113
|
+
...process.env,
|
|
114
|
+
PATH: [defaultInjectedPath(), process.env["PATH"] ?? ""].filter(Boolean).join(":"),
|
|
115
|
+
},
|
|
116
|
+
}, (error, stdout) => resolve(error ? null : String(stdout)));
|
|
117
|
+
});
|
|
118
|
+
/** `~/.codex/auth.json` を読む既定実装(サイズ上限付き。読めなければ null)。 */
|
|
119
|
+
function readCodexAuthFile(authPath) {
|
|
120
|
+
try {
|
|
121
|
+
const stat = fs.statSync(authPath);
|
|
122
|
+
if (!stat.isFile() || stat.size > CODEX_AUTH_MAX_BYTES)
|
|
123
|
+
return null;
|
|
124
|
+
return fs.readFileSync(authPath, "utf8");
|
|
125
|
+
}
|
|
126
|
+
catch {
|
|
127
|
+
return null;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
/** `auth.json` 本文から Codex アカウントの email を取り出す(純ロジック, TESTABLE)。 */
|
|
131
|
+
export function emailFromCodexAuthJson(raw) {
|
|
132
|
+
if (raw === null)
|
|
133
|
+
return undefined;
|
|
134
|
+
try {
|
|
135
|
+
const parsed = JSON.parse(raw);
|
|
136
|
+
if (typeof parsed !== "object" || parsed === null)
|
|
137
|
+
return undefined;
|
|
138
|
+
const tokens = parsed["tokens"];
|
|
139
|
+
if (typeof tokens !== "object" || tokens === null)
|
|
140
|
+
return undefined;
|
|
141
|
+
return emailFromIdToken(tokens["id_token"]);
|
|
142
|
+
}
|
|
143
|
+
catch {
|
|
144
|
+
return undefined;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* 両 agent のマスク済みアカウントを集める(キャッシュ無し。テストはここを直接叩く)。
|
|
149
|
+
* 取れなかった側は省略する。生 email はここから外へ出ない。
|
|
150
|
+
*/
|
|
151
|
+
export async function collectAccountIdentities(options = {}) {
|
|
152
|
+
const exec = options.exec ?? defaultExec;
|
|
153
|
+
const timeoutMs = options.timeoutMs ?? ACCOUNT_IDENTITY_TIMEOUT_MS;
|
|
154
|
+
const readAuth = options.readCodexAuth ??
|
|
155
|
+
(() => readCodexAuthFile(path.join(os.homedir(), ".codex", "auth.json")));
|
|
156
|
+
const [claudeRaw, codexRaw] = await Promise.all([
|
|
157
|
+
exec("claude", ["auth", "status", "--json"], timeoutMs).catch(() => null),
|
|
158
|
+
Promise.resolve().then(readAuth).catch(() => null),
|
|
159
|
+
]);
|
|
160
|
+
const claude = maskEmail(emailFromClaudeAuthStatus(claudeRaw));
|
|
161
|
+
const codex = maskEmail(emailFromCodexAuthJson(codexRaw));
|
|
162
|
+
return {
|
|
163
|
+
...(claude !== undefined ? { claude } : {}),
|
|
164
|
+
...(codex !== undefined ? { codex } : {}),
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* プロセス内キャッシュ付きの取得(既定の provider)。
|
|
169
|
+
* アカウント切替はまれなので、`claude auth status`(子プロセス)は 1 回だけ走らせる。
|
|
170
|
+
* 片方も取れなかった(空)ときはキャッシュせず、次回また試す。
|
|
171
|
+
*/
|
|
172
|
+
let memo = null;
|
|
173
|
+
export function fetchAccountIdentities() {
|
|
174
|
+
memo ??= collectAccountIdentities().then((value) => {
|
|
175
|
+
if (Object.keys(value).length === 0)
|
|
176
|
+
memo = null;
|
|
177
|
+
return value;
|
|
178
|
+
}, () => {
|
|
179
|
+
memo = null;
|
|
180
|
+
return {};
|
|
181
|
+
});
|
|
182
|
+
return memo;
|
|
183
|
+
}
|
|
184
|
+
//# sourceMappingURL=accountIdentity.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"accountIdentity.js","sourceRoot":"","sources":["../../src/services/accountIdentity.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/** Claude Code の first-party OAuth token endpoint。 */
|
|
2
|
+
export declare const CLAUDE_OAUTH_TOKEN_ENDPOINT = "https://platform.claude.com/v1/oauth/token";
|
|
3
|
+
/** Claude Code first-party OAuth client ID(Claude Code 2.1.220 と同値)。 */
|
|
4
|
+
export declare const CLAUDE_CODE_OAUTH_CLIENT_ID = "9d1c250a-e61b-44d9-88ed-5944d1962f5e";
|
|
5
|
+
/** Claude Code と同じ「期限の5分前から更新対象」の猶予。 */
|
|
6
|
+
export declare const CLAUDE_OAUTH_REFRESH_SKEW_MS: number;
|
|
7
|
+
export interface RefreshedClaudeCredential {
|
|
8
|
+
accessToken: string;
|
|
9
|
+
expiresAtMs: number;
|
|
10
|
+
subscriptionType?: string;
|
|
11
|
+
rateLimitTier?: string;
|
|
12
|
+
}
|
|
13
|
+
export type OAuthTokenRequester = (url: string, init: RequestInit) => Promise<Response>;
|
|
14
|
+
export interface RefreshClaudeCredentialOptions {
|
|
15
|
+
credentialsPath?: string;
|
|
16
|
+
requester?: OAuthTokenRequester;
|
|
17
|
+
now?: () => number;
|
|
18
|
+
timeoutSeconds?: number;
|
|
19
|
+
}
|
|
20
|
+
export declare function defaultClaudeCredentialsPath(): string;
|
|
21
|
+
/** Claude Code と同じ5分猶予で access token の更新要否を判定する。 */
|
|
22
|
+
export declare function shouldRefreshClaudeCredential(expiresAtMs: number | null, nowMs?: number): boolean;
|
|
23
|
+
/**
|
|
24
|
+
* credentials file の refresh token で access token を更新する。
|
|
25
|
+
*
|
|
26
|
+
* Keychain が使える通常環境では呼び出し側が Keychain を正本にする。この関数は
|
|
27
|
+
* Keychain が使えない SSH/headless 環境専用で、成功時だけ同じ credentials file を
|
|
28
|
+
* mode 0600 のまま原子的に更新する。
|
|
29
|
+
*/
|
|
30
|
+
export declare function refreshClaudeCredentialFile(options?: RefreshClaudeCredentialOptions): Promise<RefreshedClaudeCredential | null>;
|
|
@@ -0,0 +1,345 @@
|
|
|
1
|
+
// claudeCredentialRefresh.ts
|
|
2
|
+
// SSH/headless 環境で Claude Code の credentials file を安全に自動更新する。
|
|
3
|
+
//
|
|
4
|
+
// refresh token はローテーションされるため、単純な POST + 上書きは禁止。
|
|
5
|
+
// Claude Code 2.1.220 と同じ 2 つの proper-lockfile 互換ロックを取り、ロック取得後に
|
|
6
|
+
// credentials を再読込してから refresh し、同一ディレクトリ内の一時ファイルから
|
|
7
|
+
// 原子的に置換する。credentials.json 自体は削除しない。
|
|
8
|
+
import * as fs from "node:fs";
|
|
9
|
+
import * as os from "node:os";
|
|
10
|
+
import * as path from "node:path";
|
|
11
|
+
/** Claude Code の first-party OAuth token endpoint。 */
|
|
12
|
+
export const CLAUDE_OAUTH_TOKEN_ENDPOINT = "https://platform.claude.com/v1/oauth/token";
|
|
13
|
+
/** Claude Code first-party OAuth client ID(Claude Code 2.1.220 と同値)。 */
|
|
14
|
+
export const CLAUDE_CODE_OAUTH_CLIENT_ID = "9d1c250a-e61b-44d9-88ed-5944d1962f5e";
|
|
15
|
+
/** Claude Code と同じ「期限の5分前から更新対象」の猶予。 */
|
|
16
|
+
export const CLAUDE_OAUTH_REFRESH_SKEW_MS = 5 * 60 * 1_000;
|
|
17
|
+
const LOCK_STALE_MS = 60_000;
|
|
18
|
+
const LOCK_RETRY_LIMIT = 5;
|
|
19
|
+
export function defaultClaudeCredentialsPath() {
|
|
20
|
+
return path.join(os.homedir(), ".claude", ".credentials.json");
|
|
21
|
+
}
|
|
22
|
+
/** Claude Code と同じ5分猶予で access token の更新要否を判定する。 */
|
|
23
|
+
export function shouldRefreshClaudeCredential(expiresAtMs, nowMs = Date.now()) {
|
|
24
|
+
return expiresAtMs !== null && nowMs + CLAUDE_OAUTH_REFRESH_SKEW_MS >= expiresAtMs;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* credentials file の refresh token で access token を更新する。
|
|
28
|
+
*
|
|
29
|
+
* Keychain が使える通常環境では呼び出し側が Keychain を正本にする。この関数は
|
|
30
|
+
* Keychain が使えない SSH/headless 環境専用で、成功時だけ同じ credentials file を
|
|
31
|
+
* mode 0600 のまま原子的に更新する。
|
|
32
|
+
*/
|
|
33
|
+
export async function refreshClaudeCredentialFile(options = {}) {
|
|
34
|
+
const credentialsPath = options.credentialsPath ?? defaultClaudeCredentialsPath();
|
|
35
|
+
const requester = options.requester ?? ((url, init) => fetch(url, init));
|
|
36
|
+
const now = options.now ?? (() => Date.now());
|
|
37
|
+
const timeoutSeconds = options.timeoutSeconds ?? 5;
|
|
38
|
+
const initial = readCredentials(credentialsPath);
|
|
39
|
+
if (initial === null)
|
|
40
|
+
return null;
|
|
41
|
+
let locks = await acquireOAuthRefreshLocks(path.dirname(credentialsPath));
|
|
42
|
+
if (locks === null)
|
|
43
|
+
return null;
|
|
44
|
+
let stopHeartbeat = startLockHeartbeat(locks);
|
|
45
|
+
try {
|
|
46
|
+
// Claude Code / 別 engine が待機中に更新していれば、その結果を採用して POST しない。
|
|
47
|
+
const current = readCredentials(credentialsPath);
|
|
48
|
+
if (current === null)
|
|
49
|
+
return null;
|
|
50
|
+
if (current.accessToken !== initial.accessToken)
|
|
51
|
+
return toRefreshedCredential(current.oauth);
|
|
52
|
+
if (!ownsAllLocks(locks))
|
|
53
|
+
return null;
|
|
54
|
+
const response = await requester(CLAUDE_OAUTH_TOKEN_ENDPOINT, {
|
|
55
|
+
method: "POST",
|
|
56
|
+
headers: { "Content-Type": "application/json" },
|
|
57
|
+
body: JSON.stringify({
|
|
58
|
+
grant_type: "refresh_token",
|
|
59
|
+
refresh_token: current.refreshToken,
|
|
60
|
+
client_id: current.clientId,
|
|
61
|
+
scope: current.scopes.join(" "),
|
|
62
|
+
}),
|
|
63
|
+
signal: AbortSignal.timeout(timeoutSeconds * 1_000),
|
|
64
|
+
});
|
|
65
|
+
if (response.status !== 200)
|
|
66
|
+
return null;
|
|
67
|
+
const payload = await response.json();
|
|
68
|
+
let mergeBase = current;
|
|
69
|
+
let updated = mergeRefreshResponse(mergeBase, payload, now());
|
|
70
|
+
if (updated === null)
|
|
71
|
+
return null;
|
|
72
|
+
if (!ownsAllLocks(locks)) {
|
|
73
|
+
// refresh token を回した後にロックを失った場合は、そのまま上書きしない。
|
|
74
|
+
// Claude Code と同様に再ロックして credentials を再読込し、兄弟更新を採用するか
|
|
75
|
+
// 同じ refresh token のままなら自分の応答を安全に保存する。
|
|
76
|
+
stopHeartbeat();
|
|
77
|
+
releaseDirectoryLocks(locks);
|
|
78
|
+
const reacquired = await acquireOAuthRefreshLocks(path.dirname(credentialsPath));
|
|
79
|
+
if (reacquired === null)
|
|
80
|
+
return null;
|
|
81
|
+
locks = reacquired;
|
|
82
|
+
stopHeartbeat = startLockHeartbeat(locks);
|
|
83
|
+
const latest = readCredentials(credentialsPath);
|
|
84
|
+
if (latest === null)
|
|
85
|
+
return null;
|
|
86
|
+
if (latest.refreshToken !== current.refreshToken ||
|
|
87
|
+
latest.accessToken !== current.accessToken) {
|
|
88
|
+
return toRefreshedCredential(latest.oauth);
|
|
89
|
+
}
|
|
90
|
+
mergeBase = latest;
|
|
91
|
+
updated = mergeRefreshResponse(mergeBase, payload, now());
|
|
92
|
+
if (updated === null)
|
|
93
|
+
return null;
|
|
94
|
+
}
|
|
95
|
+
if (!ownsAllLocks(locks))
|
|
96
|
+
return null;
|
|
97
|
+
writeCredentialsAtomically(credentialsPath, updated.document);
|
|
98
|
+
return updated.credential;
|
|
99
|
+
}
|
|
100
|
+
catch {
|
|
101
|
+
return null;
|
|
102
|
+
}
|
|
103
|
+
finally {
|
|
104
|
+
stopHeartbeat();
|
|
105
|
+
releaseDirectoryLocks(locks);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
function readCredentials(credentialsPath) {
|
|
109
|
+
let document;
|
|
110
|
+
try {
|
|
111
|
+
document = JSON.parse(fs.readFileSync(credentialsPath, "utf8"));
|
|
112
|
+
}
|
|
113
|
+
catch {
|
|
114
|
+
return null;
|
|
115
|
+
}
|
|
116
|
+
if (typeof document !== "object" || document === null || Array.isArray(document))
|
|
117
|
+
return null;
|
|
118
|
+
const record = document;
|
|
119
|
+
const rawOauth = record["claudeAiOauth"];
|
|
120
|
+
if (typeof rawOauth !== "object" || rawOauth === null || Array.isArray(rawOauth))
|
|
121
|
+
return null;
|
|
122
|
+
const oauth = rawOauth;
|
|
123
|
+
const accessToken = nonEmptyString(oauth.accessToken);
|
|
124
|
+
const refreshToken = nonEmptyString(oauth.refreshToken);
|
|
125
|
+
const scopes = Array.isArray(oauth.scopes)
|
|
126
|
+
? oauth.scopes.filter((scope) => nonEmptyString(scope) !== null)
|
|
127
|
+
: [];
|
|
128
|
+
if (accessToken === null || refreshToken === null || scopes.length === 0)
|
|
129
|
+
return null;
|
|
130
|
+
return {
|
|
131
|
+
document: record,
|
|
132
|
+
oauth,
|
|
133
|
+
accessToken,
|
|
134
|
+
refreshToken,
|
|
135
|
+
scopes,
|
|
136
|
+
clientId: nonEmptyString(oauth.clientId) ?? CLAUDE_CODE_OAUTH_CLIENT_ID,
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
function mergeRefreshResponse(current, payload, nowMs) {
|
|
140
|
+
if (typeof payload !== "object" || payload === null || Array.isArray(payload))
|
|
141
|
+
return null;
|
|
142
|
+
const response = payload;
|
|
143
|
+
const accessToken = nonEmptyString(response["access_token"]);
|
|
144
|
+
const expiresIn = positiveFiniteNumber(response["expires_in"]);
|
|
145
|
+
if (accessToken === null || expiresIn === null)
|
|
146
|
+
return null;
|
|
147
|
+
const refreshToken = nonEmptyString(response["refresh_token"]) ?? current.refreshToken;
|
|
148
|
+
const responseScopes = typeof response["scope"] === "string"
|
|
149
|
+
? response["scope"].split(/\s+/).filter((scope) => scope.length > 0)
|
|
150
|
+
: [];
|
|
151
|
+
const scopes = responseScopes.length > 0 ? responseScopes : current.scopes;
|
|
152
|
+
const expiresAtMs = nowMs + expiresIn * 1_000;
|
|
153
|
+
const refreshExpiresIn = positiveFiniteNumber(response["refresh_token_expires_in"]);
|
|
154
|
+
const oauth = {
|
|
155
|
+
...current.oauth,
|
|
156
|
+
accessToken,
|
|
157
|
+
refreshToken,
|
|
158
|
+
expiresAt: expiresAtMs,
|
|
159
|
+
scopes,
|
|
160
|
+
...(refreshExpiresIn !== null
|
|
161
|
+
? { refreshTokenExpiresAt: nowMs + refreshExpiresIn * 1_000 }
|
|
162
|
+
: {}),
|
|
163
|
+
};
|
|
164
|
+
const document = { ...current.document, claudeAiOauth: oauth };
|
|
165
|
+
return {
|
|
166
|
+
document,
|
|
167
|
+
credential: {
|
|
168
|
+
accessToken,
|
|
169
|
+
expiresAtMs,
|
|
170
|
+
...(nonEmptyString(oauth.subscriptionType) !== null
|
|
171
|
+
? { subscriptionType: nonEmptyString(oauth.subscriptionType) }
|
|
172
|
+
: {}),
|
|
173
|
+
...(nonEmptyString(oauth.rateLimitTier) !== null
|
|
174
|
+
? { rateLimitTier: nonEmptyString(oauth.rateLimitTier) }
|
|
175
|
+
: {}),
|
|
176
|
+
},
|
|
177
|
+
};
|
|
178
|
+
}
|
|
179
|
+
function toRefreshedCredential(oauth) {
|
|
180
|
+
const accessToken = nonEmptyString(oauth.accessToken);
|
|
181
|
+
const expiresAtMs = typeof oauth.expiresAt === "number" && Number.isFinite(oauth.expiresAt)
|
|
182
|
+
? oauth.expiresAt
|
|
183
|
+
: null;
|
|
184
|
+
if (accessToken === null || expiresAtMs === null)
|
|
185
|
+
return null;
|
|
186
|
+
const subscriptionType = nonEmptyString(oauth.subscriptionType);
|
|
187
|
+
const rateLimitTier = nonEmptyString(oauth.rateLimitTier);
|
|
188
|
+
return {
|
|
189
|
+
accessToken,
|
|
190
|
+
expiresAtMs,
|
|
191
|
+
...(subscriptionType !== null ? { subscriptionType } : {}),
|
|
192
|
+
...(rateLimitTier !== null ? { rateLimitTier } : {}),
|
|
193
|
+
};
|
|
194
|
+
}
|
|
195
|
+
function nonEmptyString(value) {
|
|
196
|
+
return typeof value === "string" && value.length > 0 ? value : null;
|
|
197
|
+
}
|
|
198
|
+
function positiveFiniteNumber(value) {
|
|
199
|
+
return typeof value === "number" && Number.isFinite(value) && value > 0 ? value : null;
|
|
200
|
+
}
|
|
201
|
+
/**
|
|
202
|
+
* Claude Code の proper-lockfile 設定と互換のディレクトリロックを同じ順で取る。
|
|
203
|
+
* 新ロック: `<configDir>/.oauth_refresh.lock`
|
|
204
|
+
* legacy ロック: `<real configDir>.lock`
|
|
205
|
+
*/
|
|
206
|
+
async function acquireOAuthRefreshLocks(configDir) {
|
|
207
|
+
try {
|
|
208
|
+
fs.mkdirSync(configDir, { recursive: true, mode: 0o700 });
|
|
209
|
+
}
|
|
210
|
+
catch {
|
|
211
|
+
return null;
|
|
212
|
+
}
|
|
213
|
+
let realConfigDir;
|
|
214
|
+
try {
|
|
215
|
+
realConfigDir = fs.realpathSync(configDir);
|
|
216
|
+
}
|
|
217
|
+
catch {
|
|
218
|
+
realConfigDir = configDir;
|
|
219
|
+
}
|
|
220
|
+
const lockPaths = [
|
|
221
|
+
path.join(configDir, ".oauth_refresh.lock"),
|
|
222
|
+
`${realConfigDir}.lock`,
|
|
223
|
+
];
|
|
224
|
+
for (let attempt = 0; attempt <= LOCK_RETRY_LIMIT; attempt += 1) {
|
|
225
|
+
const held = [];
|
|
226
|
+
let complete = true;
|
|
227
|
+
for (const lockPath of lockPaths) {
|
|
228
|
+
const lock = tryAcquireDirectoryLock(lockPath);
|
|
229
|
+
if (lock === null) {
|
|
230
|
+
complete = false;
|
|
231
|
+
break;
|
|
232
|
+
}
|
|
233
|
+
held.push(lock);
|
|
234
|
+
}
|
|
235
|
+
if (complete)
|
|
236
|
+
return held;
|
|
237
|
+
releaseDirectoryLocks(held);
|
|
238
|
+
if (attempt < LOCK_RETRY_LIMIT) {
|
|
239
|
+
await new Promise((resolve) => {
|
|
240
|
+
setTimeout(resolve, 1_000 + Math.floor(Math.random() * 1_000));
|
|
241
|
+
});
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
return null;
|
|
245
|
+
}
|
|
246
|
+
function tryAcquireDirectoryLock(lockPath) {
|
|
247
|
+
try {
|
|
248
|
+
fs.mkdirSync(lockPath, { mode: 0o700 });
|
|
249
|
+
}
|
|
250
|
+
catch (error) {
|
|
251
|
+
if (error.code !== "EEXIST")
|
|
252
|
+
return null;
|
|
253
|
+
try {
|
|
254
|
+
const stat = fs.statSync(lockPath);
|
|
255
|
+
if (!stat.isDirectory() || Date.now() - stat.mtimeMs <= LOCK_STALE_MS)
|
|
256
|
+
return null;
|
|
257
|
+
fs.rmdirSync(lockPath);
|
|
258
|
+
fs.mkdirSync(lockPath, { mode: 0o700 });
|
|
259
|
+
}
|
|
260
|
+
catch {
|
|
261
|
+
return null;
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
try {
|
|
265
|
+
const stat = fs.statSync(lockPath);
|
|
266
|
+
return { lockPath, dev: stat.dev, ino: stat.ino };
|
|
267
|
+
}
|
|
268
|
+
catch {
|
|
269
|
+
return null;
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
function startLockHeartbeat(locks) {
|
|
273
|
+
const timer = setInterval(() => {
|
|
274
|
+
const now = new Date();
|
|
275
|
+
for (const lock of locks) {
|
|
276
|
+
if (!stillOwnsLock(lock))
|
|
277
|
+
continue;
|
|
278
|
+
try {
|
|
279
|
+
fs.utimesSync(lock.lockPath, now, now);
|
|
280
|
+
}
|
|
281
|
+
catch {
|
|
282
|
+
// ロック喪失は release 側でも inode 照合し、他プロセスのロックを消さない。
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
}, 5_000);
|
|
286
|
+
timer.unref();
|
|
287
|
+
return () => clearInterval(timer);
|
|
288
|
+
}
|
|
289
|
+
function releaseDirectoryLocks(locks) {
|
|
290
|
+
for (const lock of [...locks].reverse()) {
|
|
291
|
+
if (!stillOwnsLock(lock))
|
|
292
|
+
continue;
|
|
293
|
+
try {
|
|
294
|
+
fs.rmdirSync(lock.lockPath);
|
|
295
|
+
}
|
|
296
|
+
catch {
|
|
297
|
+
// 他プロセスによる回収・置換、または非空なら触らない。
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
function stillOwnsLock(lock) {
|
|
302
|
+
try {
|
|
303
|
+
const stat = fs.statSync(lock.lockPath);
|
|
304
|
+
return stat.isDirectory() && stat.dev === lock.dev && stat.ino === lock.ino;
|
|
305
|
+
}
|
|
306
|
+
catch {
|
|
307
|
+
return false;
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
function ownsAllLocks(locks) {
|
|
311
|
+
return locks.length === 2 && locks.every(stillOwnsLock);
|
|
312
|
+
}
|
|
313
|
+
/** mode 0600 の同一ディレクトリ一時ファイルを書き、rename で原子的に置換する。 */
|
|
314
|
+
function writeCredentialsAtomically(credentialsPath, document) {
|
|
315
|
+
const dir = path.dirname(credentialsPath);
|
|
316
|
+
const tempPath = path.join(dir, `.credentials.json.tailii-${process.pid}-${Date.now()}-${Math.random().toString(16).slice(2)}`);
|
|
317
|
+
let fd = null;
|
|
318
|
+
try {
|
|
319
|
+
fd = fs.openSync(tempPath, "wx", 0o600);
|
|
320
|
+
fs.writeFileSync(fd, `${JSON.stringify(document)}\n`, "utf8");
|
|
321
|
+
fs.fsyncSync(fd);
|
|
322
|
+
fs.closeSync(fd);
|
|
323
|
+
fd = null;
|
|
324
|
+
fs.renameSync(tempPath, credentialsPath);
|
|
325
|
+
fs.chmodSync(credentialsPath, 0o600);
|
|
326
|
+
}
|
|
327
|
+
catch (error) {
|
|
328
|
+
if (fd !== null) {
|
|
329
|
+
try {
|
|
330
|
+
fs.closeSync(fd);
|
|
331
|
+
}
|
|
332
|
+
catch {
|
|
333
|
+
// 元のエラーを優先する。
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
try {
|
|
337
|
+
fs.unlinkSync(tempPath);
|
|
338
|
+
}
|
|
339
|
+
catch {
|
|
340
|
+
// rename 済み、または一時ファイル未生成。
|
|
341
|
+
}
|
|
342
|
+
throw error;
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
//# sourceMappingURL=claudeCredentialRefresh.js.map
|