@usebitl/cli 0.1.9 → 0.1.10
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/adapters/dist/core.mjs
CHANGED
|
@@ -467,7 +467,7 @@ function readCloudConfig(home = bitlHome()) {
|
|
|
467
467
|
}
|
|
468
468
|
}
|
|
469
469
|
function clientVersionHeader() {
|
|
470
|
-
const v = "0.1.
|
|
470
|
+
const v = "0.1.10";
|
|
471
471
|
return v ? { "x-bitl-client": v } : {};
|
|
472
472
|
}
|
|
473
473
|
function resolveTarget(home = bitlHome()) {
|
|
@@ -506,20 +506,22 @@ function gitBranch(cwd) {
|
|
|
506
506
|
});
|
|
507
507
|
});
|
|
508
508
|
}
|
|
509
|
-
async function
|
|
509
|
+
async function titleFromTranscript(path) {
|
|
510
510
|
try {
|
|
511
511
|
if ((await stat2(path)).size > MAX_TRANSCRIPT_BYTES2) return void 0;
|
|
512
512
|
const text = await readFile2(path, "utf8");
|
|
513
|
-
let
|
|
513
|
+
let aiTitle;
|
|
514
|
+
let customTitle;
|
|
514
515
|
for (const line of text.split("\n")) {
|
|
515
|
-
if (!line.includes('"ai-title"')) continue;
|
|
516
|
+
if (!line.includes('"ai-title"') && !line.includes('"custom-title"')) continue;
|
|
516
517
|
try {
|
|
517
518
|
const rec = JSON.parse(line);
|
|
518
|
-
if (rec.type === "ai-title" && rec.aiTitle)
|
|
519
|
+
if (rec.type === "ai-title" && rec.aiTitle) aiTitle = rec.aiTitle;
|
|
520
|
+
if (rec.type === "custom-title" && rec.customTitle?.trim()) customTitle = rec.customTitle.trim();
|
|
519
521
|
} catch {
|
|
520
522
|
}
|
|
521
523
|
}
|
|
522
|
-
return
|
|
524
|
+
return customTitle ?? aiTitle;
|
|
523
525
|
} catch {
|
|
524
526
|
return void 0;
|
|
525
527
|
}
|
|
@@ -555,7 +557,7 @@ async function enrichEvent(e) {
|
|
|
555
557
|
}
|
|
556
558
|
if (e.source === "claude-code" && e.transcriptPath && (e.type === "prompt" || e.type === "turn_end")) {
|
|
557
559
|
tasks.push(
|
|
558
|
-
|
|
560
|
+
titleFromTranscript(e.transcriptPath).then((title) => {
|
|
559
561
|
if (title) extra.aiTitle = title;
|
|
560
562
|
})
|
|
561
563
|
);
|
|
@@ -20060,7 +20060,7 @@ function removeCloudLogin(home = bitlHome()) {
|
|
|
20060
20060
|
rmSync(cloudKeyPath(home), { force: true });
|
|
20061
20061
|
}
|
|
20062
20062
|
function clientVersionHeader() {
|
|
20063
|
-
const v = "0.1.
|
|
20063
|
+
const v = "0.1.10";
|
|
20064
20064
|
return v ? { "x-bitl-client": v } : {};
|
|
20065
20065
|
}
|
|
20066
20066
|
function resolveTarget(home = bitlHome()) {
|
|
@@ -20117,7 +20117,7 @@ async function latestVersion(home, now) {
|
|
|
20117
20117
|
return latest;
|
|
20118
20118
|
}
|
|
20119
20119
|
var updateCommand = (install = process.env.BITL_INSTALL) => install === "npx" ? "npx @usebitl/cli@latest start" : "npm i -g @usebitl/cli";
|
|
20120
|
-
async function checkCliUpdate(current = "0.1.
|
|
20120
|
+
async function checkCliUpdate(current = "0.1.10", opts = {}) {
|
|
20121
20121
|
if (!current || process.env.BITL_NO_UPDATE_CHECK === "1") return void 0;
|
|
20122
20122
|
const latest = await latestVersion(opts.home ?? bitlHome(), opts.now ?? Date.now());
|
|
20123
20123
|
if (!latest || compareVersions(latest, current) <= 0) return void 0;
|
package/dist/cli.mjs
CHANGED
|
@@ -21,7 +21,7 @@ import {
|
|
|
21
21
|
unwrapMasterKey,
|
|
22
22
|
verifyPublicKey,
|
|
23
23
|
wrapMasterKey
|
|
24
|
-
} from "./chunks/chunk-
|
|
24
|
+
} from "./chunks/chunk-FQXPEVHB.mjs";
|
|
25
25
|
|
|
26
26
|
// ../src/index.ts
|
|
27
27
|
import { homedir as homedir2 } from "node:os";
|
|
@@ -451,7 +451,7 @@ async function logout() {
|
|
|
451
451
|
}
|
|
452
452
|
|
|
453
453
|
// ../src/update.ts
|
|
454
|
-
async function updateNotice(current = "0.1.
|
|
454
|
+
async function updateNotice(current = "0.1.10") {
|
|
455
455
|
const u = await checkCliUpdate(current);
|
|
456
456
|
return u && `${t("update.available", { ...u })}
|
|
457
457
|
${t("update.changelog")}`;
|
|
@@ -605,7 +605,7 @@ async function main(argv) {
|
|
|
605
605
|
if (String(typeof warning === "string" ? warning : warning.message).startsWith("SQLite is an experimental feature")) return;
|
|
606
606
|
emitWarning(warning, ...rest2);
|
|
607
607
|
});
|
|
608
|
-
const { startServer } = await import("./chunks/src-
|
|
608
|
+
const { startServer } = await import("./chunks/src-NKVNQ2RI.mjs");
|
|
609
609
|
await startServer();
|
|
610
610
|
console.log(t("start.pair", { url: localPairUrl() }));
|
|
611
611
|
return;
|
package/package.json
CHANGED
package/web/sw.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
(function(){var e=/^s1\.[A-Za-z0-9_-]{87}\.[A-Za-z0-9_-]{16}\.[A-Za-z0-9_-]+$/,t=()=>globalThis.crypto.subtle,n=new TextEncoder,r=new TextDecoder(`utf-8`,{fatal:!0});function i(e){let t=``;for(let n of e)t+=String.fromCharCode(n);return btoa(t).replace(/\+/g,`-`).replace(/\//g,`_`).replace(/=+$/,``)}function a(e){if(!/^[A-Za-z0-9_-]*$/.test(e))throw Error(`invalid base64url`);let t=atob(e.replace(/-/g,`+`).replace(/_/g,`/`)+`=`.repeat((4-e.length%4)%4));return Uint8Array.from(t,e=>e.charCodeAt(0))}function o(e){let t=e.length-1;for(;t>=0&&e[t]===0;)t--;if(t<0||e[t]!==128)throw Error(`invalid padding`);return e.subarray(0,t)}async function s(e,i,s){if(i.startsWith(`s1.`)){if(!e.inbox)throw Error(`no inbox key`);return u(e.inbox,i,s)}let c=i.split(`.`);if(c.length!==4||c[0]!==`v1`)throw Error(`unknown format`);if(c[1]!==e.kid)throw Error(`different key`);let l=await t().decrypt({name:`AES-GCM`,iv:a(c[2]),additionalData:n.encode(s)},e.enc,a(c[3]));return r.decode(o(new Uint8Array(l)))}var c={name:`ECDH`,namedCurve:`P-256`};async function l(e,r,i){let a=await t().importKey(`raw`,e,`HKDF`,!1,[`deriveKey`]);return t().deriveKey({name:`HKDF`,hash:`SHA-256`,salt:new Uint8Array(r),info:n.encode(`bitl/v1/inbox`)},a,{name:`AES-GCM`,length:256},!1,[i])}async function u(i,s,u){let d=s.split(`.`);if(d.length!==4||!e.test(s))throw Error(`unknown format`);let f=a(d[1]),p=await t().importKey(`raw`,f,c,!1,[]),m=await t().deriveBits({name:`ECDH`,public:p},i,256),h=await t().decrypt({name:`AES-GCM`,iv:a(d[2]),additionalData:n.encode(u)},await l(m,f,`decrypt`),a(d[3]));return r.decode(o(new Uint8Array(h)))}var d=e=>`approval:${e}`;async function f(e,t,n){let r=JSON.parse(await s(e,n,d(t)));if(typeof r?.tool!=`string`||typeof r.summary!=`string`)throw Error(`invalid approval request`);return r}var p=new WeakMap;function m(e){let t=p.get(e);return t||(t=globalThis.crypto.subtle.importKey(`raw`,e.master,`HKDF`,!1,[`deriveKey`]).then(e=>globalThis.crypto.subtle.deriveKey({name:`HKDF`,hash:`SHA-256`,salt:new Uint8Array,info:new TextEncoder().encode(`bitl/v1/approve`)},e,{name:`HMAC`,hash:`SHA-256`,length:256},!1,[`sign`,`verify`])),p.set(e,t)),t}var h=(e,t)=>new TextEncoder().encode(`bitl/approval/v1\n${e}\n${t}`);async function g(e,t,n){let r=await globalThis.crypto.subtle.sign(`HMAC`,await m(e),h(t,n));return i(new Uint8Array(r))}new TextEncoder;var _=`bitl-
|
|
1
|
+
(function(){var e=/^s1\.[A-Za-z0-9_-]{87}\.[A-Za-z0-9_-]{16}\.[A-Za-z0-9_-]+$/,t=()=>globalThis.crypto.subtle,n=new TextEncoder,r=new TextDecoder(`utf-8`,{fatal:!0});function i(e){let t=``;for(let n of e)t+=String.fromCharCode(n);return btoa(t).replace(/\+/g,`-`).replace(/\//g,`_`).replace(/=+$/,``)}function a(e){if(!/^[A-Za-z0-9_-]*$/.test(e))throw Error(`invalid base64url`);let t=atob(e.replace(/-/g,`+`).replace(/_/g,`/`)+`=`.repeat((4-e.length%4)%4));return Uint8Array.from(t,e=>e.charCodeAt(0))}function o(e){let t=e.length-1;for(;t>=0&&e[t]===0;)t--;if(t<0||e[t]!==128)throw Error(`invalid padding`);return e.subarray(0,t)}async function s(e,i,s){if(i.startsWith(`s1.`)){if(!e.inbox)throw Error(`no inbox key`);return u(e.inbox,i,s)}let c=i.split(`.`);if(c.length!==4||c[0]!==`v1`)throw Error(`unknown format`);if(c[1]!==e.kid)throw Error(`different key`);let l=await t().decrypt({name:`AES-GCM`,iv:a(c[2]),additionalData:n.encode(s)},e.enc,a(c[3]));return r.decode(o(new Uint8Array(l)))}var c={name:`ECDH`,namedCurve:`P-256`};async function l(e,r,i){let a=await t().importKey(`raw`,e,`HKDF`,!1,[`deriveKey`]);return t().deriveKey({name:`HKDF`,hash:`SHA-256`,salt:new Uint8Array(r),info:n.encode(`bitl/v1/inbox`)},a,{name:`AES-GCM`,length:256},!1,[i])}async function u(i,s,u){let d=s.split(`.`);if(d.length!==4||!e.test(s))throw Error(`unknown format`);let f=a(d[1]),p=await t().importKey(`raw`,f,c,!1,[]),m=await t().deriveBits({name:`ECDH`,public:p},i,256),h=await t().decrypt({name:`AES-GCM`,iv:a(d[2]),additionalData:n.encode(u)},await l(m,f,`decrypt`),a(d[3]));return r.decode(o(new Uint8Array(h)))}var d=e=>`approval:${e}`;async function f(e,t,n){let r=JSON.parse(await s(e,n,d(t)));if(typeof r?.tool!=`string`||typeof r.summary!=`string`)throw Error(`invalid approval request`);return r}var p=new WeakMap;function m(e){let t=p.get(e);return t||(t=globalThis.crypto.subtle.importKey(`raw`,e.master,`HKDF`,!1,[`deriveKey`]).then(e=>globalThis.crypto.subtle.deriveKey({name:`HKDF`,hash:`SHA-256`,salt:new Uint8Array,info:new TextEncoder().encode(`bitl/v1/approve`)},e,{name:`HMAC`,hash:`SHA-256`,length:256},!1,[`sign`,`verify`])),p.set(e,t)),t}var h=(e,t)=>new TextEncoder().encode(`bitl/approval/v1\n${e}\n${t}`);async function g(e,t,n){let r=await globalThis.crypto.subtle.sign(`HMAC`,await m(e),h(t,n));return i(new Uint8Array(r))}new TextEncoder;var _=`bitl-mv9juty3`;self.addEventListener(`install`,e=>{e.waitUntil(caches.open(_).then(e=>e.addAll([`/app`,`/manifest.webmanifest`,`/icon-192.png`])).then(()=>self.skipWaiting()))}),self.addEventListener(`activate`,e=>{e.waitUntil(caches.keys().then(e=>Promise.all(e.filter(e=>e.startsWith(`bitl-`)&&e!==_).map(e=>caches.delete(e)))).then(()=>self.clients.claim()))}),self.addEventListener(`fetch`,e=>{let t=e.request;if(t.method!==`GET`)return;let n=new URL(t.url);if(!(n.origin!==self.location.origin||n.pathname.startsWith(`/api/`))){if(t.mode===`navigate`){e.respondWith(fetch(t).then(e=>(e.ok&&caches.open(_).then(t=>t.put(n.pathname,e.clone())),e)).catch(async()=>await caches.match(n.pathname)??await caches.match(`/app`)??Response.error()));return}n.pathname.startsWith(`/assets/`)&&e.respondWith(caches.match(t).then(e=>e??fetch(t).then(e=>(e.ok&&caches.open(_).then(n=>n.put(t,e.clone())),e))))}});function v(){return new Promise(e=>{let t=indexedDB.open(`bitl`,1);t.onupgradeneeded=()=>t.result.createObjectStore(`keys`),t.onerror=()=>e(null),t.onsuccess=()=>{let n=t.result;try{let t=n.transaction(`keys`,`readonly`).objectStore(`keys`).get(`content`);t.onsuccess=()=>e(t.result??null),t.onerror=()=>e(null)}catch{e(null)}finally{n.close()}}})}var y={ko:{headline:{permission:`권한 승인이 필요해요`,question:`질문에 답해주세요`,plan:`계획 승인이 필요해요`,elicitation:`입력이 필요해요`,input:`입력이 필요해요`},waiting:`나를 기다리고 있어요`,error:`오류로 멈췄어요`,oneWaiting:`작업 1건이 나를 기다리고 있어요`,settled:{allow:`✓ 허용됨`,deny:`✕ 거부됨`,cancelled:`터미널에서 답했어요`,expired:`시간이 지나 터미널로 넘어갔어요`},settledTitle:`승인 요청 끝남`,settledOther:`끝났어요`,approval:`승인 요청`,approvalLocked:`🔒 이 기기의 키로 요청 내용을 열 수 없어요. 눌러서 확인하세요.`,allow:`허용`,deny:`거부`,failNoKey:`이 기기에 키가 없어 답할 수 없어요. 앱을 열어 확인하세요.`,failNetwork:`보내지 못했어요 (네트워크). 앱을 열어 다시 답하세요.`,failSettled:`이미 다른 곳에서 답했거나 PC 가 터미널에서 승인하기로 했어요.`,failGone:`요청이 끝났어요 (시간이 지남).`},en:{headline:{permission:`Needs your permission`,question:`Has a question for you`,plan:`Needs plan approval`,elicitation:`Needs your input`,input:`Needs your input`},waiting:`Waiting for you`,error:`Stopped with an error`,oneWaiting:`1 task is waiting for you`,settled:{allow:`✓ Allowed`,deny:`✕ Denied`,cancelled:`Answered in the terminal`,expired:`Timed out — moved to the terminal`},settledTitle:`Approval request ended`,settledOther:`Ended`,approval:`Approval request`,approvalLocked:`🔒 This device’s key can’t decrypt the request. Tap to check.`,allow:`Allow`,deny:`Deny`,failNoKey:`No key on this device, so it can’t answer. Open the app to check.`,failNetwork:`Couldn’t send (network). Open the app and answer again.`,failSettled:`Already answered elsewhere, or the PC chose to approve in the terminal.`,failGone:`The request has ended (timed out).`}};async function b(){try{let e=await(await caches.open(`bitl.prefs`)).match(`/lang`),t=e?await e.text():``;if(t===`ko`||t===`en`)return y[t]}catch{}return self.navigator.language.toLowerCase().startsWith(`ko`)?y.ko:y.en}var x=e=>`approval:${e}`;async function S(e){let t=x(e.id),n=await b();await self.registration.showNotification(n.settledTitle,{body:n.settled[e.status]??n.settledOther,icon:`/icon-192.png`,badge:`/badge-96.png`,tag:t,silent:!0,data:{key:e.key}}),await new Promise(e=>setTimeout(e,4e3));for(let e of await self.registration.getNotifications({tag:t}))e.close()}async function C(e){let t=await v(),n=e.request;if(!n){let t=await fetch(`/api/approvals/${encodeURIComponent(e.id)}`).catch(()=>null);n=t?.ok?(await t.json()).request:void 0}let r=t&&n?await f(t,e.id,n).catch(()=>void 0):void 0;for(let t of await self.registration.getNotifications({tag:e.key}))t.close();let i=await b();await self.registration.showNotification(r?.project?`${r.project} · ${i.approval}`:i.approval,{body:r?[r.summary,r.description].filter(Boolean).join(`
|
|
2
2
|
`):i.approvalLocked,icon:`/icon-192.png`,badge:`/badge-96.png`,tag:x(e.id),data:{key:e.key,approvalId:e.id,readable:!!r},requireInteraction:!0,actions:r?[{action:`allow`,title:i.allow},{action:`deny`,title:i.deny}]:[{action:`deny`,title:i.deny}]})}async function w(e,t,n){let[r,i]=await Promise.all([v(),b()]),a=t=>self.registration.showNotification(i.approval,{body:t,icon:`/icon-192.png`,badge:`/badge-96.png`,tag:x(e),data:{key:n}});if(!r)return a(i.failNoKey);let o=await fetch(`/api/approvals/${encodeURIComponent(e)}/decide`,{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify({decision:t,sig:await g(r,e,t)})}).catch(()=>null);if(!o)return a(i.failNetwork);if(o.status===409)return a(i.failSettled);if(!o.ok)return a(i.failGone)}async function T(e){if(e&&`kind`in e&&e.kind===`approval`)return C(e);if(e&&`kind`in e&&e.kind===`approval-settled`)return S(e);let t=e,n=await b();if(t&&(await self.registration.getNotifications()).some(e=>e.data?.approvalId&&e.data.key===t.key))return;if(!t||t.v!==1){await self.registration.showNotification(`BITL`,{body:n.oneWaiting,icon:`/icon-192.png`,tag:`bitl`});return}let r=await v(),i=async e=>r&&e?s(r,e,t.key).catch(()=>void 0):void 0,[a,o,c,l]=await Promise.all([i(t.sealed.title),i(t.sealed.activity),i(t.sealed.project),i(t.sealed.message)]),u=t.status===`error`?n.error:n.headline[t.reason??``]??n.waiting,d=(e,t)=>e.length>t?`${e.slice(0,t-1)}…`:e,f=[o??l,a&&a!==o?a:void 0].filter(Boolean).map(e=>d(e,140));await self.registration.showNotification(c?`${c} · ${u}`:u,{body:f.length?f.join(`
|
|
3
3
|
`):n.oneWaiting,icon:`/icon-192.png`,badge:`/badge-96.png`,tag:t.key,data:{key:t.key},renotify:!0}),await self.navigator.setAppBadge?.(t.attention).catch(()=>{})}self.addEventListener(`push`,e=>{let t=null;try{t=e.data?.json()??null}catch{}e.waitUntil(T(t))}),self.addEventListener(`notificationclick`,e=>{e.notification.close();let t=e.notification.data,n=t?.key;if(t?.approvalId&&(e.action===`allow`||e.action===`deny`)){e.waitUntil(w(t.approvalId,e.action,n));return}let r=n?`/app#s=${encodeURIComponent(n)}`:`/app`;e.waitUntil((async()=>{let e=(await self.clients.matchAll({type:`window`,includeUncontrolled:!0})).find(e=>new URL(e.url).origin===self.location.origin);if(e){await e.focus(),e.postMessage({type:`open-session`,key:n});return}await self.clients.openWindow(r)})())})})();
|