tailii-host 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +51 -0
- package/dist/apnsConfigStore.d.ts +22 -0
- package/dist/apnsConfigStore.js +50 -0
- package/dist/apnsConfigStore.js.map +1 -0
- package/dist/apnsJwtProvider.d.ts +50 -0
- package/dist/apnsJwtProvider.js +158 -0
- package/dist/apnsJwtProvider.js.map +1 -0
- package/dist/apnsSender.d.ts +69 -0
- package/dist/apnsSender.js +155 -0
- package/dist/apnsSender.js.map +1 -0
- package/dist/approvalPushNotifier.d.ts +100 -0
- package/dist/approvalPushNotifier.js +236 -0
- package/dist/approvalPushNotifier.js.map +1 -0
- package/dist/broker.d.ts +24 -0
- package/dist/broker.js +197 -0
- package/dist/broker.js.map +1 -0
- package/dist/chatTailController.d.ts +87 -0
- package/dist/chatTailController.js +292 -0
- package/dist/chatTailController.js.map +1 -0
- package/dist/claudeSessionStore.d.ts +15 -0
- package/dist/claudeSessionStore.js +201 -0
- package/dist/claudeSessionStore.js.map +1 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +53 -0
- package/dist/cli.js.map +1 -0
- package/dist/codexRolloutTailer.d.ts +56 -0
- package/dist/codexRolloutTailer.js +303 -0
- package/dist/codexRolloutTailer.js.map +1 -0
- package/dist/codexSessionStore.d.ts +23 -0
- package/dist/codexSessionStore.js +274 -0
- package/dist/codexSessionStore.js.map +1 -0
- package/dist/codexUsage.d.ts +16 -0
- package/dist/codexUsage.js +144 -0
- package/dist/codexUsage.js.map +1 -0
- package/dist/deviceTokenStore.d.ts +38 -0
- package/dist/deviceTokenStore.js +73 -0
- package/dist/deviceTokenStore.js.map +1 -0
- package/dist/dirLister.d.ts +9 -0
- package/dist/dirLister.js +98 -0
- package/dist/dirLister.js.map +1 -0
- package/dist/doctor.d.ts +36 -0
- package/dist/doctor.js +162 -0
- package/dist/doctor.js.map +1 -0
- package/dist/engine.d.ts +85 -0
- package/dist/engine.js +962 -0
- package/dist/engine.js.map +1 -0
- package/dist/hook.d.ts +67 -0
- package/dist/hook.js +511 -0
- package/dist/hook.js.map +1 -0
- package/dist/hookSettings.d.ts +40 -0
- package/dist/hookSettings.js +128 -0
- package/dist/hookSettings.js.map +1 -0
- package/dist/idleReaper.d.ts +13 -0
- package/dist/idleReaper.js +30 -0
- package/dist/idleReaper.js.map +1 -0
- package/dist/imageService.d.ts +53 -0
- package/dist/imageService.js +280 -0
- package/dist/imageService.js.map +1 -0
- package/dist/kick.d.ts +8 -0
- package/dist/kick.js +60 -0
- package/dist/kick.js.map +1 -0
- package/dist/launch.d.ts +107 -0
- package/dist/launch.js +396 -0
- package/dist/launch.js.map +1 -0
- package/dist/legacyHomeMigration.d.ts +1 -0
- package/dist/legacyHomeMigration.js +23 -0
- package/dist/legacyHomeMigration.js.map +1 -0
- package/dist/lineWriter.d.ts +9 -0
- package/dist/lineWriter.js +19 -0
- package/dist/lineWriter.js.map +1 -0
- package/dist/mdnsAdvertiser.d.ts +46 -0
- package/dist/mdnsAdvertiser.js +268 -0
- package/dist/mdnsAdvertiser.js.map +1 -0
- package/dist/observationLog.d.ts +54 -0
- package/dist/observationLog.js +108 -0
- package/dist/observationLog.js.map +1 -0
- package/dist/pairingCode.d.ts +60 -0
- package/dist/pairingCode.js +282 -0
- package/dist/pairingCode.js.map +1 -0
- package/dist/paths.d.ts +13 -0
- package/dist/paths.js +46 -0
- package/dist/paths.js.map +1 -0
- package/dist/permissionMode.d.ts +8 -0
- package/dist/permissionMode.js +32 -0
- package/dist/permissionMode.js.map +1 -0
- package/dist/planUsageFetcher.d.ts +35 -0
- package/dist/planUsageFetcher.js +172 -0
- package/dist/planUsageFetcher.js.map +1 -0
- package/dist/protocol.d.ts +329 -0
- package/dist/protocol.js +544 -0
- package/dist/protocol.js.map +1 -0
- package/dist/pushTokenCommand.d.ts +9 -0
- package/dist/pushTokenCommand.js +85 -0
- package/dist/pushTokenCommand.js.map +1 -0
- package/dist/pushTypes.d.ts +41 -0
- package/dist/pushTypes.js +68 -0
- package/dist/pushTypes.js.map +1 -0
- package/dist/sendLog.d.ts +14 -0
- package/dist/sendLog.js +64 -0
- package/dist/sendLog.js.map +1 -0
- package/dist/sessionActivityProvider.d.ts +7 -0
- package/dist/sessionActivityProvider.js +44 -0
- package/dist/sessionActivityProvider.js.map +1 -0
- package/dist/sessionIdleTracker.d.ts +19 -0
- package/dist/sessionIdleTracker.js +42 -0
- package/dist/sessionIdleTracker.js.map +1 -0
- package/dist/sessionListService.d.ts +27 -0
- package/dist/sessionListService.js +85 -0
- package/dist/sessionListService.js.map +1 -0
- package/dist/sessionMetadataStore.d.ts +33 -0
- package/dist/sessionMetadataStore.js +122 -0
- package/dist/sessionMetadataStore.js.map +1 -0
- package/dist/sessionSearch.d.ts +29 -0
- package/dist/sessionSearch.js +139 -0
- package/dist/sessionSearch.js.map +1 -0
- package/dist/setup.d.ts +83 -0
- package/dist/setup.js +412 -0
- package/dist/setup.js.map +1 -0
- package/dist/sleep.d.ts +4 -0
- package/dist/sleep.js +25 -0
- package/dist/sleep.js.map +1 -0
- package/dist/socketPath.d.ts +12 -0
- package/dist/socketPath.js +51 -0
- package/dist/socketPath.js.map +1 -0
- package/dist/subagentTailer.d.ts +15 -0
- package/dist/subagentTailer.js +399 -0
- package/dist/subagentTailer.js.map +1 -0
- package/dist/tmux.d.ts +62 -0
- package/dist/tmux.js +163 -0
- package/dist/tmux.js.map +1 -0
- package/dist/transcriptTailer.d.ts +61 -0
- package/dist/transcriptTailer.js +606 -0
- package/dist/transcriptTailer.js.map +1 -0
- package/dist/usageAggregator.d.ts +12 -0
- package/dist/usageAggregator.js +55 -0
- package/dist/usageAggregator.js.map +1 -0
- package/dist/version.d.ts +10 -0
- package/dist/version.js +45 -0
- package/dist/version.js.map +1 -0
- package/package.json +50 -0
|
@@ -0,0 +1,282 @@
|
|
|
1
|
+
// pairingCode.ts
|
|
2
|
+
// tailii-host (TS host) — pairing-code v1 responder protocol.
|
|
3
|
+
import * as crypto from "node:crypto";
|
|
4
|
+
const X25519_SPKI_PREFIX = Buffer.from("302a300506032b656e032100", "hex");
|
|
5
|
+
const PROTOCOL_VERSION = 1;
|
|
6
|
+
const INFO_SAS = "pocketclaude-pair-v1 sas";
|
|
7
|
+
const INFO_CONFIRM = "pocketclaude-pair-v1 confirm";
|
|
8
|
+
const INFO_DATA = "pocketclaude-pair-v1 data";
|
|
9
|
+
const INITIATOR_CONFIRM_MESSAGE = "pocketclaude-pair-v1 initiator-confirm";
|
|
10
|
+
const DEFAULT_STEP_TIMEOUT_MS = 30_000;
|
|
11
|
+
export function rawX25519PublicKeyToKeyObject(raw32) {
|
|
12
|
+
if (raw32.length !== 32)
|
|
13
|
+
throw new Error("x25519 public key must be 32 bytes");
|
|
14
|
+
return crypto.createPublicKey({ key: Buffer.concat([X25519_SPKI_PREFIX, raw32]), format: "der", type: "spki" });
|
|
15
|
+
}
|
|
16
|
+
export function x25519PublicKeyObjectToRaw(publicKey) {
|
|
17
|
+
const der = publicKey.export({ type: "spki", format: "der" });
|
|
18
|
+
const bytes = Buffer.isBuffer(der) ? der : Buffer.from(der);
|
|
19
|
+
if (bytes.length !== X25519_SPKI_PREFIX.length + 32)
|
|
20
|
+
throw new Error("unexpected x25519 SPKI length");
|
|
21
|
+
if (!bytes.subarray(0, X25519_SPKI_PREFIX.length).equals(X25519_SPKI_PREFIX)) {
|
|
22
|
+
throw new Error("unexpected x25519 SPKI prefix");
|
|
23
|
+
}
|
|
24
|
+
return Buffer.from(bytes.subarray(X25519_SPKI_PREFIX.length));
|
|
25
|
+
}
|
|
26
|
+
export function hkdfSha256(ikm, salt, info, length) {
|
|
27
|
+
return Buffer.from(crypto.hkdfSync("sha256", ikm, salt, Buffer.from(info, "utf8"), length));
|
|
28
|
+
}
|
|
29
|
+
export function deriveSASCode(kSas4) {
|
|
30
|
+
if (kSas4.length !== 4)
|
|
31
|
+
throw new Error("SAS key must be 4 bytes");
|
|
32
|
+
return String(kSas4.readUInt32BE(0) % 1_000_000).padStart(6, "0");
|
|
33
|
+
}
|
|
34
|
+
export function pairingTranscriptSalt(commit32, responderPubRaw32, initiatorPubRaw32) {
|
|
35
|
+
if (commit32.length !== 32 || responderPubRaw32.length !== 32 || initiatorPubRaw32.length !== 32) {
|
|
36
|
+
throw new Error("pairing transcript fields must be 32 bytes");
|
|
37
|
+
}
|
|
38
|
+
return crypto.createHash("sha256").update(commit32).update(responderPubRaw32).update(initiatorPubRaw32).digest();
|
|
39
|
+
}
|
|
40
|
+
export function derivePairingKeys(sharedSecret32, commit32, responderPubRaw32, initiatorPubRaw32) {
|
|
41
|
+
if (sharedSecret32.length !== 32)
|
|
42
|
+
throw new Error("x25519 shared secret must be 32 bytes");
|
|
43
|
+
const salt = pairingTranscriptSalt(commit32, responderPubRaw32, initiatorPubRaw32);
|
|
44
|
+
const kSas = hkdfSha256(sharedSecret32, salt, INFO_SAS, 4);
|
|
45
|
+
return {
|
|
46
|
+
salt,
|
|
47
|
+
sasCode: deriveSASCode(kSas),
|
|
48
|
+
confirmKey: hkdfSha256(sharedSecret32, salt, INFO_CONFIRM, 32),
|
|
49
|
+
dataKey: hkdfSha256(sharedSecret32, salt, INFO_DATA, 32),
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
export function computeInitiatorConfirmMac(confirmKey32) {
|
|
53
|
+
if (confirmKey32.length !== 32)
|
|
54
|
+
throw new Error("confirm key must be 32 bytes");
|
|
55
|
+
return crypto.createHmac("sha256", confirmKey32).update(INITIATOR_CONFIRM_MESSAGE, "utf8").digest();
|
|
56
|
+
}
|
|
57
|
+
export function encodePairingMessage(message) {
|
|
58
|
+
return JSON.stringify(message);
|
|
59
|
+
}
|
|
60
|
+
export function parsePairingMessage(line) {
|
|
61
|
+
let value;
|
|
62
|
+
try {
|
|
63
|
+
value = JSON.parse(line);
|
|
64
|
+
}
|
|
65
|
+
catch {
|
|
66
|
+
return null;
|
|
67
|
+
}
|
|
68
|
+
if (!isRecord(value) || typeof value.t !== "string")
|
|
69
|
+
return null;
|
|
70
|
+
switch (value.t) {
|
|
71
|
+
case "hello":
|
|
72
|
+
if (value.v !== PROTOCOL_VERSION || typeof value.commit !== "string")
|
|
73
|
+
return null;
|
|
74
|
+
return { t: "hello", v: PROTOCOL_VERSION, commit: value.commit };
|
|
75
|
+
case "server_key":
|
|
76
|
+
if (value.v !== PROTOCOL_VERSION || typeof value.epk !== "string")
|
|
77
|
+
return null;
|
|
78
|
+
return { t: "server_key", v: PROTOCOL_VERSION, epk: value.epk };
|
|
79
|
+
case "reveal":
|
|
80
|
+
if (typeof value.epk !== "string")
|
|
81
|
+
return null;
|
|
82
|
+
return { t: "reveal", epk: value.epk };
|
|
83
|
+
case "confirm":
|
|
84
|
+
if (typeof value.mac !== "string")
|
|
85
|
+
return null;
|
|
86
|
+
return { t: "confirm", mac: value.mac };
|
|
87
|
+
case "payload":
|
|
88
|
+
if (typeof value.iv !== "string" || typeof value.ct !== "string" || typeof value.tag !== "string")
|
|
89
|
+
return null;
|
|
90
|
+
return { t: "payload", iv: value.iv, ct: value.ct, tag: value.tag };
|
|
91
|
+
default:
|
|
92
|
+
return null;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
export function decodeBase64Field(value, expectedLength) {
|
|
96
|
+
if (!/^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/.test(value))
|
|
97
|
+
return null;
|
|
98
|
+
const decoded = Buffer.from(value, "base64");
|
|
99
|
+
if (decoded.length !== expectedLength)
|
|
100
|
+
return null;
|
|
101
|
+
if (decoded.toString("base64") !== value)
|
|
102
|
+
return null;
|
|
103
|
+
return decoded;
|
|
104
|
+
}
|
|
105
|
+
export function encryptPayload(dataKey32, plaintext, randomBytes) {
|
|
106
|
+
if (dataKey32.length !== 32)
|
|
107
|
+
throw new Error("data key must be 32 bytes");
|
|
108
|
+
const iv = randomBytes(12);
|
|
109
|
+
if (iv.length !== 12)
|
|
110
|
+
throw new Error("AEAD IV must be 12 bytes");
|
|
111
|
+
const cipher = crypto.createCipheriv("aes-256-gcm", dataKey32, iv);
|
|
112
|
+
const ciphertext = Buffer.concat([cipher.update(plaintext), cipher.final()]);
|
|
113
|
+
return { iv, ciphertext, tag: cipher.getAuthTag() };
|
|
114
|
+
}
|
|
115
|
+
export function decryptPayload(dataKey32, iv12, ciphertext, tag16) {
|
|
116
|
+
if (dataKey32.length !== 32 || iv12.length !== 12 || tag16.length !== 16) {
|
|
117
|
+
throw new Error("invalid AES-256-GCM input length");
|
|
118
|
+
}
|
|
119
|
+
const decipher = crypto.createDecipheriv("aes-256-gcm", dataKey32, iv12);
|
|
120
|
+
decipher.setAuthTag(tag16);
|
|
121
|
+
return Buffer.concat([decipher.update(ciphertext), decipher.final()]);
|
|
122
|
+
}
|
|
123
|
+
export async function runPairingResponder(stream, deps) {
|
|
124
|
+
const timeoutMs = deps.timeoutMs ?? DEFAULT_STEP_TIMEOUT_MS;
|
|
125
|
+
const randomBytes = deps.randomBytes ?? crypto.randomBytes;
|
|
126
|
+
const reader = new PairingLineReader(stream.readable);
|
|
127
|
+
try {
|
|
128
|
+
const helloLine = await reader.readLine(timeoutMs);
|
|
129
|
+
if (helloLine === null)
|
|
130
|
+
return abort(stream, reader, "timeout");
|
|
131
|
+
const hello = parsePairingMessage(helloLine);
|
|
132
|
+
if (hello?.t !== "hello")
|
|
133
|
+
return abort(stream, reader, "invalid hello");
|
|
134
|
+
const commit = decodeBase64Field(hello.commit, 32);
|
|
135
|
+
if (commit === null)
|
|
136
|
+
return abort(stream, reader, "invalid commit");
|
|
137
|
+
const responderKeypair = crypto.generateKeyPairSync("x25519");
|
|
138
|
+
const responderPubRaw = x25519PublicKeyObjectToRaw(responderKeypair.publicKey);
|
|
139
|
+
writeMessage(stream.writable, { t: "server_key", v: PROTOCOL_VERSION, epk: responderPubRaw.toString("base64") });
|
|
140
|
+
const revealLine = await reader.readLine(timeoutMs);
|
|
141
|
+
if (revealLine === null)
|
|
142
|
+
return abort(stream, reader, "timeout");
|
|
143
|
+
const reveal = parsePairingMessage(revealLine);
|
|
144
|
+
if (reveal?.t !== "reveal")
|
|
145
|
+
return abort(stream, reader, "invalid reveal");
|
|
146
|
+
const initiatorPubRaw = decodeBase64Field(reveal.epk, 32);
|
|
147
|
+
if (initiatorPubRaw === null)
|
|
148
|
+
return abort(stream, reader, "invalid initiator key");
|
|
149
|
+
const expectedCommit = crypto.createHash("sha256").update(initiatorPubRaw).digest();
|
|
150
|
+
if (!safeEqual32(expectedCommit, commit))
|
|
151
|
+
return abort(stream, reader, "commitment mismatch");
|
|
152
|
+
const initiatorPub = rawX25519PublicKeyToKeyObject(initiatorPubRaw);
|
|
153
|
+
const sharedSecret = crypto.diffieHellman({ privateKey: responderKeypair.privateKey, publicKey: initiatorPub });
|
|
154
|
+
const keys = derivePairingKeys(sharedSecret, commit, responderPubRaw, initiatorPubRaw);
|
|
155
|
+
deps.displaySAS(keys.sasCode);
|
|
156
|
+
const confirmLine = await reader.readLine(timeoutMs);
|
|
157
|
+
if (confirmLine === null)
|
|
158
|
+
return abort(stream, reader, "timeout");
|
|
159
|
+
const confirm = parsePairingMessage(confirmLine);
|
|
160
|
+
if (confirm?.t !== "confirm")
|
|
161
|
+
return abort(stream, reader, "invalid confirm");
|
|
162
|
+
const receivedMac = decodeBase64Field(confirm.mac, 32);
|
|
163
|
+
if (receivedMac === null)
|
|
164
|
+
return abort(stream, reader, "invalid confirm mac");
|
|
165
|
+
const expectedMac = computeInitiatorConfirmMac(keys.confirmKey);
|
|
166
|
+
if (!safeEqual32(receivedMac, expectedMac))
|
|
167
|
+
return abort(stream, reader, "confirm mac mismatch");
|
|
168
|
+
const encrypted = encryptPayload(keys.dataKey, Buffer.from(deps.payloadJSON, "utf8"), randomBytes);
|
|
169
|
+
writeMessage(stream.writable, {
|
|
170
|
+
t: "payload",
|
|
171
|
+
iv: encrypted.iv.toString("base64"),
|
|
172
|
+
ct: encrypted.ciphertext.toString("base64"),
|
|
173
|
+
tag: encrypted.tag.toString("base64"),
|
|
174
|
+
});
|
|
175
|
+
endWritable(stream.writable);
|
|
176
|
+
reader.dispose();
|
|
177
|
+
return { status: "paired" };
|
|
178
|
+
}
|
|
179
|
+
catch {
|
|
180
|
+
return abort(stream, reader, "aborted");
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
function writeMessage(writable, message) {
|
|
184
|
+
writable.write(encodePairingMessage(message) + "\n");
|
|
185
|
+
}
|
|
186
|
+
function safeEqual32(a, b) {
|
|
187
|
+
return a.length === 32 && b.length === 32 && crypto.timingSafeEqual(a, b);
|
|
188
|
+
}
|
|
189
|
+
function abort(stream, reader, reason) {
|
|
190
|
+
reader.dispose();
|
|
191
|
+
destroyWritable(stream.writable);
|
|
192
|
+
destroyReadable(stream.readable);
|
|
193
|
+
return { status: "aborted", reason };
|
|
194
|
+
}
|
|
195
|
+
function endWritable(writable) {
|
|
196
|
+
if ("end" in writable && typeof writable.end === "function")
|
|
197
|
+
writable.end();
|
|
198
|
+
}
|
|
199
|
+
function destroyWritable(writable) {
|
|
200
|
+
if ("destroy" in writable && typeof writable.destroy === "function")
|
|
201
|
+
writable.destroy();
|
|
202
|
+
else
|
|
203
|
+
endWritable(writable);
|
|
204
|
+
}
|
|
205
|
+
function destroyReadable(readable) {
|
|
206
|
+
if ("destroy" in readable && typeof readable.destroy === "function")
|
|
207
|
+
readable.destroy();
|
|
208
|
+
}
|
|
209
|
+
function isRecord(value) {
|
|
210
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
211
|
+
}
|
|
212
|
+
class PairingLineReader {
|
|
213
|
+
readable;
|
|
214
|
+
buffer = Buffer.alloc(0);
|
|
215
|
+
lines = [];
|
|
216
|
+
ended = false;
|
|
217
|
+
waiter = null;
|
|
218
|
+
constructor(readable) {
|
|
219
|
+
this.readable = readable;
|
|
220
|
+
readable.on("data", this.onData);
|
|
221
|
+
readable.once("end", this.onEnd);
|
|
222
|
+
readable.once("close", this.onEnd);
|
|
223
|
+
readable.once("error", this.onEnd);
|
|
224
|
+
}
|
|
225
|
+
readLine(timeoutMs) {
|
|
226
|
+
const queued = this.lines.shift();
|
|
227
|
+
if (queued !== undefined)
|
|
228
|
+
return Promise.resolve(queued);
|
|
229
|
+
if (this.ended)
|
|
230
|
+
return Promise.resolve(null);
|
|
231
|
+
return new Promise((resolve) => {
|
|
232
|
+
const timer = setTimeout(() => {
|
|
233
|
+
if (this.waiter === onLine)
|
|
234
|
+
this.waiter = null;
|
|
235
|
+
resolve(null);
|
|
236
|
+
}, timeoutMs);
|
|
237
|
+
const onLine = (line) => {
|
|
238
|
+
clearTimeout(timer);
|
|
239
|
+
resolve(line);
|
|
240
|
+
};
|
|
241
|
+
this.waiter = onLine;
|
|
242
|
+
});
|
|
243
|
+
}
|
|
244
|
+
dispose() {
|
|
245
|
+
this.readable.off("data", this.onData);
|
|
246
|
+
this.readable.off("end", this.onEnd);
|
|
247
|
+
this.readable.off("close", this.onEnd);
|
|
248
|
+
this.readable.off("error", this.onEnd);
|
|
249
|
+
this.waiter = null;
|
|
250
|
+
}
|
|
251
|
+
onData = (chunk) => {
|
|
252
|
+
this.buffer = this.buffer.length === 0 ? chunk : Buffer.concat([this.buffer, chunk]);
|
|
253
|
+
let line;
|
|
254
|
+
while ((line = this.shiftLine()) !== null) {
|
|
255
|
+
if (this.waiter !== null) {
|
|
256
|
+
const waiter = this.waiter;
|
|
257
|
+
this.waiter = null;
|
|
258
|
+
waiter(line);
|
|
259
|
+
}
|
|
260
|
+
else {
|
|
261
|
+
this.lines.push(line);
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
};
|
|
265
|
+
onEnd = () => {
|
|
266
|
+
this.ended = true;
|
|
267
|
+
if (this.waiter !== null) {
|
|
268
|
+
const waiter = this.waiter;
|
|
269
|
+
this.waiter = null;
|
|
270
|
+
waiter(null);
|
|
271
|
+
}
|
|
272
|
+
};
|
|
273
|
+
shiftLine() {
|
|
274
|
+
const idx = this.buffer.indexOf(0x0a);
|
|
275
|
+
if (idx < 0)
|
|
276
|
+
return null;
|
|
277
|
+
const line = this.buffer.subarray(0, idx).toString("utf8");
|
|
278
|
+
this.buffer = this.buffer.subarray(idx + 1);
|
|
279
|
+
return line;
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
//# sourceMappingURL=pairingCode.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pairingCode.js","sourceRoot":"","sources":["../src/pairingCode.ts"],"names":[],"mappings":"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"}
|
package/dist/paths.d.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/** `~/…` を展開しつつ字句正準化した絶対パスを返す(Swift standardizedFileURL 相当)。 */
|
|
2
|
+
export declare function standardize(p: string): string;
|
|
3
|
+
/** 先頭 `~` をホームディレクトリへ展開する。 */
|
|
4
|
+
export declare function expandTilde(p: string): string;
|
|
5
|
+
/**
|
|
6
|
+
* あるパスが baseDir 自身または baseDir 配下かを lexical(`..` 畳み込み後)に判定する。
|
|
7
|
+
* symlink 実体は追わず字句正準化のみで containment を判定する(Swift 版 isInsideBase と同一)。
|
|
8
|
+
*/
|
|
9
|
+
export declare function isInsideBase(p: string, base: string): boolean;
|
|
10
|
+
/** ディレクトリを `0700` で作成する(既存ならそのまま)。存在するがファイルなら例外。 */
|
|
11
|
+
export declare function ensureDirectory0700(dir: string): void;
|
|
12
|
+
/** シンボリックリンクを解決した canonical パス(解決不能時は字句正準化のみ)。 */
|
|
13
|
+
export declare function canonicalPath(p: string): string;
|
package/dist/paths.js
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
// paths.ts
|
|
2
|
+
// tailii (TS host) — パス関連の共有ヘルパ(Swift 版 Launch.swift の isInsideBase ほか)
|
|
3
|
+
import * as os from "node:os";
|
|
4
|
+
import * as path from "node:path";
|
|
5
|
+
import * as fs from "node:fs";
|
|
6
|
+
/** `~/…` を展開しつつ字句正準化した絶対パスを返す(Swift standardizedFileURL 相当)。 */
|
|
7
|
+
export function standardize(p) {
|
|
8
|
+
return path.normalize(path.resolve(expandTilde(p)));
|
|
9
|
+
}
|
|
10
|
+
/** 先頭 `~` をホームディレクトリへ展開する。 */
|
|
11
|
+
export function expandTilde(p) {
|
|
12
|
+
if (p === "~")
|
|
13
|
+
return os.homedir();
|
|
14
|
+
if (p.startsWith("~/"))
|
|
15
|
+
return path.join(os.homedir(), p.slice(2));
|
|
16
|
+
return p;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* あるパスが baseDir 自身または baseDir 配下かを lexical(`..` 畳み込み後)に判定する。
|
|
20
|
+
* symlink 実体は追わず字句正準化のみで containment を判定する(Swift 版 isInsideBase と同一)。
|
|
21
|
+
*/
|
|
22
|
+
export function isInsideBase(p, base) {
|
|
23
|
+
const pp = standardize(p);
|
|
24
|
+
const bb = standardize(base);
|
|
25
|
+
return pp === bb || pp.startsWith(bb + "/");
|
|
26
|
+
}
|
|
27
|
+
/** ディレクトリを `0700` で作成する(既存ならそのまま)。存在するがファイルなら例外。 */
|
|
28
|
+
export function ensureDirectory0700(dir) {
|
|
29
|
+
if (fs.existsSync(dir)) {
|
|
30
|
+
if (!fs.statSync(dir).isDirectory()) {
|
|
31
|
+
throw new Error(`パスが存在するがディレクトリではない: ${dir}`);
|
|
32
|
+
}
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
fs.mkdirSync(dir, { recursive: true, mode: 0o700 });
|
|
36
|
+
}
|
|
37
|
+
/** シンボリックリンクを解決した canonical パス(解決不能時は字句正準化のみ)。 */
|
|
38
|
+
export function canonicalPath(p) {
|
|
39
|
+
try {
|
|
40
|
+
return fs.realpathSync.native(standardize(p));
|
|
41
|
+
}
|
|
42
|
+
catch {
|
|
43
|
+
return standardize(p);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=paths.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"paths.js","sourceRoot":"","sources":["../src/paths.ts"],"names":[],"mappings":"AAAA,WAAW;AACX,wEAAwE;AAExE,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAE9B,gEAAgE;AAChE,MAAM,UAAU,WAAW,CAAC,CAAS;IACnC,OAAO,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACtD,CAAC;AAED,8BAA8B;AAC9B,MAAM,UAAU,WAAW,CAAC,CAAS;IACnC,IAAI,CAAC,KAAK,GAAG;QAAE,OAAO,EAAE,CAAC,OAAO,EAAE,CAAC;IACnC,IAAI,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IACnE,OAAO,CAAC,CAAC;AACX,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,YAAY,CAAC,CAAS,EAAE,IAAY;IAClD,MAAM,EAAE,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC;IAC1B,MAAM,EAAE,GAAG,WAAW,CAAC,IAAI,CAAC,CAAC;IAC7B,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,UAAU,CAAC,EAAE,GAAG,GAAG,CAAC,CAAC;AAC9C,CAAC;AAED,oDAAoD;AACpD,MAAM,UAAU,mBAAmB,CAAC,GAAW;IAC7C,IAAI,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QACvB,IAAI,CAAC,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC;YACpC,MAAM,IAAI,KAAK,CAAC,uBAAuB,GAAG,EAAE,CAAC,CAAC;QAChD,CAAC;QACD,OAAO;IACT,CAAC;IACD,EAAE,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;AACtD,CAAC;AAED,kDAAkD;AAClD,MAAM,UAAU,aAAa,CAAC,CAAS;IACrC,IAAI,CAAC;QACH,OAAO,EAAE,CAAC,YAAY,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC;IAChD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,WAAW,CAAC,CAAC,CAAC,CAAC;IACxB,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/** プロトコルで扱うモード値。 */
|
|
2
|
+
export declare const KNOWN_MODES: readonly ["default", "acceptEdits", "plan", "auto"];
|
|
3
|
+
/**
|
|
4
|
+
* pane 表示テキストから現在の permission mode を判定する(純ロジック)。
|
|
5
|
+
* モードマーカーは入力欄直下のステータス行に出るため、誤検知を避けて末尾4行のみを見る。
|
|
6
|
+
* ダイアログ表示中はモード行が消えるため、判定不能として null を返す。
|
|
7
|
+
*/
|
|
8
|
+
export declare function parsePermissionMode(paneText: string): string | null;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
// permissionMode.ts
|
|
2
|
+
// tailii (TS host) — Claude Code TUI の permission mode 判定(mode-picker)
|
|
3
|
+
// Swift 版 PermissionMode.swift の移植。
|
|
4
|
+
// TUI は Shift+Tab(BTab)で default → acceptEdits → plan → auto → default … を循環する。
|
|
5
|
+
/** プロトコルで扱うモード値。 */
|
|
6
|
+
export const KNOWN_MODES = ["default", "acceptEdits", "plan", "auto"];
|
|
7
|
+
/**
|
|
8
|
+
* pane 表示テキストから現在の permission mode を判定する(純ロジック)。
|
|
9
|
+
* モードマーカーは入力欄直下のステータス行に出るため、誤検知を避けて末尾4行のみを見る。
|
|
10
|
+
* ダイアログ表示中はモード行が消えるため、判定不能として null を返す。
|
|
11
|
+
*/
|
|
12
|
+
export function parsePermissionMode(paneText) {
|
|
13
|
+
const tailLines = paneText
|
|
14
|
+
.split("\n")
|
|
15
|
+
.filter((line) => line.length > 0)
|
|
16
|
+
.slice(-4);
|
|
17
|
+
const tail = tailLines.join("\n");
|
|
18
|
+
if (tail.includes("accept edits on"))
|
|
19
|
+
return "acceptEdits";
|
|
20
|
+
if (tail.includes("plan mode on"))
|
|
21
|
+
return "plan";
|
|
22
|
+
if (tail.includes("auto mode on"))
|
|
23
|
+
return "auto";
|
|
24
|
+
if (tailLines.some((line) => line.includes("to select") ||
|
|
25
|
+
line.includes("to navigate") ||
|
|
26
|
+
line.includes("to confirm") ||
|
|
27
|
+
line.includes("to cancel"))) {
|
|
28
|
+
return null;
|
|
29
|
+
}
|
|
30
|
+
return "default";
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=permissionMode.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"permissionMode.js","sourceRoot":"","sources":["../src/permissionMode.ts"],"names":[],"mappings":"AAAA,oBAAoB;AACpB,uEAAuE;AACvE,oCAAoC;AACpC,gFAAgF;AAEhF,oBAAoB;AACpB,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,SAAS,EAAE,aAAa,EAAE,MAAM,EAAE,MAAM,CAAU,CAAC;AAE/E;;;;GAIG;AACH,MAAM,UAAU,mBAAmB,CAAC,QAAgB;IAClD,MAAM,SAAS,GAAG,QAAQ;SACvB,KAAK,CAAC,IAAI,CAAC;SACX,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC;SACjC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IACb,MAAM,IAAI,GAAG,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAClC,IAAI,IAAI,CAAC,QAAQ,CAAC,iBAAiB,CAAC;QAAE,OAAO,aAAa,CAAC;IAC3D,IAAI,IAAI,CAAC,QAAQ,CAAC,cAAc,CAAC;QAAE,OAAO,MAAM,CAAC;IACjD,IAAI,IAAI,CAAC,QAAQ,CAAC,cAAc,CAAC;QAAE,OAAO,MAAM,CAAC;IACjD,IACE,SAAS,CAAC,IAAI,CACZ,CAAC,IAAI,EAAE,EAAE,CACP,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC;QAC1B,IAAI,CAAC,QAAQ,CAAC,aAAa,CAAC;QAC5B,IAAI,CAAC,QAAQ,CAAC,YAAY,CAAC;QAC3B,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,CAC7B,EACD,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/** プラン使用状況(5時間枠/7日枠/上位モデル週間枠の使用率とリセット時刻)。 */
|
|
2
|
+
export interface PlanUsage {
|
|
3
|
+
fiveHourUtilization: number | null;
|
|
4
|
+
fiveHourResetsAt: string | null;
|
|
5
|
+
sevenDayUtilization: number | null;
|
|
6
|
+
sevenDayResetsAt: string | null;
|
|
7
|
+
sevenDayFableUtilization: number | null;
|
|
8
|
+
sevenDayFableResetsAt: string | null;
|
|
9
|
+
}
|
|
10
|
+
/** 使用量 API のエンドポイント(Claude Code 本体・statusline ツールと同じ)。 */
|
|
11
|
+
export declare const PLAN_USAGE_ENDPOINT = "https://api.anthropic.com/api/oauth/usage";
|
|
12
|
+
/** トークン候補(値と有効期限 ms epoch)。 */
|
|
13
|
+
export interface Credential {
|
|
14
|
+
token: string;
|
|
15
|
+
expiresAtMs: number | null;
|
|
16
|
+
}
|
|
17
|
+
/** engine へ注入するフェッチャの型(テストは () => null を注入する)。 */
|
|
18
|
+
export type PlanUsageProvider = () => Promise<PlanUsage | null>;
|
|
19
|
+
/** プラン使用状況を取得する(ベストエフォート・timeout 付き)。 */
|
|
20
|
+
export declare function fetchPlanUsage(timeoutSeconds?: number): Promise<PlanUsage | null>;
|
|
21
|
+
/**
|
|
22
|
+
* 使用量 API 応答をパースする(形式は寛容に読む)。
|
|
23
|
+
* トップレベルキー(seven_day_fable → seven_day_mythos → seven_day_opus)を試した後、
|
|
24
|
+
* `limits[]` の `kind == "weekly_scoped"` エントリにフォールバックする(2026-07 実測の現行形式)。
|
|
25
|
+
*/
|
|
26
|
+
export declare function parsePlanUsage(raw: unknown): PlanUsage | null;
|
|
27
|
+
/**
|
|
28
|
+
* Claude Code が保存した OAuth アクセストークンの候補を試行順に返す。
|
|
29
|
+
* Keychain → file の順に集め、期限内のものを先に試す(全滅時は期限切れも最後に試す)。
|
|
30
|
+
*/
|
|
31
|
+
export declare function loadAccessTokenCandidates(now?: Date): Promise<string[]>;
|
|
32
|
+
/** 候補の試行順を決める(純ロジック, TESTABLE)。期限内を元の順で先に、期限切れを後に、重複除去。 */
|
|
33
|
+
export declare function orderCandidates(candidates: Credential[], nowMs: number): string[];
|
|
34
|
+
/** 認証情報 JSON(`{"claudeAiOauth":{"accessToken":…,"expiresAt":<ms>}}`)から候補を取り出す。 */
|
|
35
|
+
export declare function extractCredential(json: string): Credential | null;
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
// planUsageFetcher.ts
|
|
2
|
+
// tailii (TS host) — プラン使用状況の取得(Claude Code OAuth 使用量 API)
|
|
3
|
+
// Swift 版 PlanUsageFetcher.swift の移植。
|
|
4
|
+
// 認証は Mac 上の Claude Code が保存した OAuth トークン(Keychain → file の順、期限切れは後回し)。
|
|
5
|
+
// 取得不能・オフラインは null(usage 応答の plan 系フィールドは省略 = ベストエフォート)。
|
|
6
|
+
// 秘密の扱い: アクセストークンは本プロセス内でのみ使い、ログ・チャネルへは載せない。
|
|
7
|
+
import { execFile } from "node:child_process";
|
|
8
|
+
import * as fs from "node:fs";
|
|
9
|
+
import * as os from "node:os";
|
|
10
|
+
import * as path from "node:path";
|
|
11
|
+
/** 使用量 API のエンドポイント(Claude Code 本体・statusline ツールと同じ)。 */
|
|
12
|
+
export const PLAN_USAGE_ENDPOINT = "https://api.anthropic.com/api/oauth/usage";
|
|
13
|
+
/** プラン使用状況を取得する(ベストエフォート・timeout 付き)。 */
|
|
14
|
+
export async function fetchPlanUsage(timeoutSeconds = 5) {
|
|
15
|
+
for (const token of await loadAccessTokenCandidates()) {
|
|
16
|
+
const usage = await fetchOnce(token, timeoutSeconds);
|
|
17
|
+
if (usage !== null)
|
|
18
|
+
return usage;
|
|
19
|
+
}
|
|
20
|
+
return null;
|
|
21
|
+
}
|
|
22
|
+
/** 単一トークンで使用量 API を1回叩く。非 200・タイムアウトは null。 */
|
|
23
|
+
async function fetchOnce(token, timeoutSeconds) {
|
|
24
|
+
try {
|
|
25
|
+
const response = await fetch(PLAN_USAGE_ENDPOINT, {
|
|
26
|
+
method: "GET",
|
|
27
|
+
headers: {
|
|
28
|
+
Authorization: `Bearer ${token}`,
|
|
29
|
+
// OAuth 経由の Claude Code API に必要な beta ヘッダ(公式クライアントと同じ)。
|
|
30
|
+
"anthropic-beta": "oauth-2025-04-20",
|
|
31
|
+
},
|
|
32
|
+
signal: AbortSignal.timeout(timeoutSeconds * 1000),
|
|
33
|
+
});
|
|
34
|
+
if (response.status !== 200)
|
|
35
|
+
return null;
|
|
36
|
+
return parsePlanUsage((await response.json()));
|
|
37
|
+
}
|
|
38
|
+
catch {
|
|
39
|
+
return null;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* 使用量 API 応答をパースする(形式は寛容に読む)。
|
|
44
|
+
* トップレベルキー(seven_day_fable → seven_day_mythos → seven_day_opus)を試した後、
|
|
45
|
+
* `limits[]` の `kind == "weekly_scoped"` エントリにフォールバックする(2026-07 実測の現行形式)。
|
|
46
|
+
*/
|
|
47
|
+
export function parsePlanUsage(raw) {
|
|
48
|
+
if (typeof raw !== "object" || raw === null)
|
|
49
|
+
return null;
|
|
50
|
+
const obj = raw;
|
|
51
|
+
const window = (key) => {
|
|
52
|
+
const w = obj[key];
|
|
53
|
+
if (typeof w !== "object" || w === null)
|
|
54
|
+
return [null, null];
|
|
55
|
+
const rec = w;
|
|
56
|
+
const pct = roundedPercent(rec["utilization"]);
|
|
57
|
+
const resetsAt = typeof rec["resets_at"] === "string" ? rec["resets_at"] : null;
|
|
58
|
+
return [pct, resetsAt];
|
|
59
|
+
};
|
|
60
|
+
const five = window("five_hour");
|
|
61
|
+
const seven = window("seven_day");
|
|
62
|
+
let fable = [null, null];
|
|
63
|
+
for (const key of ["seven_day_fable", "seven_day_mythos", "seven_day_opus"]) {
|
|
64
|
+
const w = window(key);
|
|
65
|
+
if (w[0] !== null) {
|
|
66
|
+
fable = w;
|
|
67
|
+
break;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
if (fable[0] === null && Array.isArray(obj["limits"])) {
|
|
71
|
+
for (const limit of obj["limits"]) {
|
|
72
|
+
if (typeof limit !== "object" || limit === null)
|
|
73
|
+
continue;
|
|
74
|
+
const rec = limit;
|
|
75
|
+
if (rec["kind"] !== "weekly_scoped")
|
|
76
|
+
continue;
|
|
77
|
+
const pct = roundedPercent(rec["percent"]);
|
|
78
|
+
if (pct !== null) {
|
|
79
|
+
fable = [pct, typeof rec["resets_at"] === "string" ? rec["resets_at"] : null];
|
|
80
|
+
break;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
if (five[0] === null && seven[0] === null && fable[0] === null)
|
|
85
|
+
return null;
|
|
86
|
+
return {
|
|
87
|
+
fiveHourUtilization: five[0],
|
|
88
|
+
fiveHourResetsAt: five[1],
|
|
89
|
+
sevenDayUtilization: seven[0],
|
|
90
|
+
sevenDayResetsAt: seven[1],
|
|
91
|
+
sevenDayFableUtilization: fable[0],
|
|
92
|
+
sevenDayFableResetsAt: fable[1],
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
function roundedPercent(raw) {
|
|
96
|
+
return typeof raw === "number" && Number.isFinite(raw) ? Math.round(raw) : null;
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Claude Code が保存した OAuth アクセストークンの候補を試行順に返す。
|
|
100
|
+
* Keychain → file の順に集め、期限内のものを先に試す(全滅時は期限切れも最後に試す)。
|
|
101
|
+
*/
|
|
102
|
+
export async function loadAccessTokenCandidates(now = new Date()) {
|
|
103
|
+
const candidates = [];
|
|
104
|
+
const keychain = await credentialFromKeychain();
|
|
105
|
+
if (keychain)
|
|
106
|
+
candidates.push(keychain);
|
|
107
|
+
const file = credentialFromFile();
|
|
108
|
+
if (file)
|
|
109
|
+
candidates.push(file);
|
|
110
|
+
return orderCandidates(candidates, now.getTime());
|
|
111
|
+
}
|
|
112
|
+
/** 候補の試行順を決める(純ロジック, TESTABLE)。期限内を元の順で先に、期限切れを後に、重複除去。 */
|
|
113
|
+
export function orderCandidates(candidates, nowMs) {
|
|
114
|
+
const valid = candidates.filter((c) => (c.expiresAtMs ?? Number.POSITIVE_INFINITY) > nowMs);
|
|
115
|
+
const expired = candidates.filter((c) => (c.expiresAtMs ?? Number.POSITIVE_INFINITY) <= nowMs);
|
|
116
|
+
const seen = new Set();
|
|
117
|
+
const result = [];
|
|
118
|
+
for (const c of [...valid, ...expired]) {
|
|
119
|
+
if (!seen.has(c.token)) {
|
|
120
|
+
seen.add(c.token);
|
|
121
|
+
result.push(c.token);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
return result;
|
|
125
|
+
}
|
|
126
|
+
/** `~/.claude/.credentials.json` から候補を読む。 */
|
|
127
|
+
function credentialFromFile() {
|
|
128
|
+
try {
|
|
129
|
+
const raw = fs.readFileSync(path.join(os.homedir(), ".claude", ".credentials.json"), "utf8");
|
|
130
|
+
return extractCredential(raw);
|
|
131
|
+
}
|
|
132
|
+
catch {
|
|
133
|
+
return null;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
/** macOS Keychain("Claude Code-credentials")から候補を読む。 */
|
|
137
|
+
function credentialFromKeychain() {
|
|
138
|
+
return new Promise((resolve) => {
|
|
139
|
+
execFile("/usr/bin/security", ["find-generic-password", "-s", "Claude Code-credentials", "-w"], (error, stdout) => {
|
|
140
|
+
if (error) {
|
|
141
|
+
resolve(null);
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
144
|
+
resolve(extractCredential(String(stdout)));
|
|
145
|
+
});
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
/** 認証情報 JSON(`{"claudeAiOauth":{"accessToken":…,"expiresAt":<ms>}}`)から候補を取り出す。 */
|
|
149
|
+
export function extractCredential(json) {
|
|
150
|
+
let raw;
|
|
151
|
+
try {
|
|
152
|
+
raw = JSON.parse(json.trim());
|
|
153
|
+
}
|
|
154
|
+
catch {
|
|
155
|
+
return null;
|
|
156
|
+
}
|
|
157
|
+
if (typeof raw !== "object" || raw === null)
|
|
158
|
+
return null;
|
|
159
|
+
const oauth = raw["claudeAiOauth"];
|
|
160
|
+
if (typeof oauth !== "object" || oauth === null)
|
|
161
|
+
return null;
|
|
162
|
+
const rec = oauth;
|
|
163
|
+
const token = rec["accessToken"];
|
|
164
|
+
if (typeof token !== "string" || token.length === 0)
|
|
165
|
+
return null;
|
|
166
|
+
const expiresAt = rec["expiresAt"];
|
|
167
|
+
return {
|
|
168
|
+
token,
|
|
169
|
+
expiresAtMs: typeof expiresAt === "number" && Number.isFinite(expiresAt) ? expiresAt : null,
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
//# sourceMappingURL=planUsageFetcher.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"planUsageFetcher.js","sourceRoot":"","sources":["../src/planUsageFetcher.ts"],"names":[],"mappings":"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"}
|