@i14ks/ccv 0.16.2 → 0.16.3
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/bundle/ccv.mjs +87 -6
- package/package.json +1 -1
- package/web/assets/{codemirror-CMssNlj1.js → codemirror-CkgU8c7a.js} +1 -1
- package/web/assets/{index-k2hhaMZJ.js → index--DhZrg25.js} +1 -1
- package/web/assets/{index-DMeJ3xy0.js → index-B0NcQgiZ.js} +1 -1
- package/web/assets/{index-BpOx8-W2.js → index-BC7TmL8M.js} +1 -1
- package/web/assets/{index-CrUrevEN.js → index-BFwSwibX.js} +1 -1
- package/web/assets/{index-HnPp_JMB.js → index-Bhx7H3mC.js} +1 -1
- package/web/assets/{index-DhS8IelO.js → index-CNQ0551W.js} +1 -1
- package/web/assets/{index-DPVHF0JV.js → index-CQqNgFvZ.js} +1 -1
- package/web/assets/{index-CMsLxeb-.js → index-CstcrxY-.js} +1 -1
- package/web/assets/{index-hzfPIc5t.js → index-DHVISfG-.js} +1 -1
- package/web/assets/{index-DbZeX0xl.js → index-DaRnRpPz.js} +1 -1
- package/web/assets/{index-BbaEOHHE.js → index-DfGVckBo.js} +1 -1
- package/web/assets/{index-BDlE7XrJ.js → index-DlOju0OY.js} +65 -65
- package/web/assets/{index-4OYhLb6v.js → index-DoqmNDN4.js} +1 -1
- package/web/assets/{index-B20zmSkd.js → index-Dv0cw76Z.js} +1 -1
- package/web/assets/{index-kRQFCBLi.js → index-DvhOZOas.js} +1 -1
- package/web/assets/{index-umqVrxlG.js → index-GT_NZ0qK.js} +1 -1
- package/web/assets/{index-PkTbpJ8b.js → index-OuSuAczZ.js} +1 -1
- package/web/assets/{index-B8wBlTJK.js → index-P6m4z84O.js} +1 -1
- package/web/assets/{index-DyY1FCgf.js → index-gmvISUqO.js} +1 -1
- package/web/assets/{index-CMpPRV85.js → index-s7Wcfj5F.js} +1 -1
- package/web/assets/index-tvzk50nQ.css +1 -0
- package/web/index.html +2 -2
- package/web/assets/index-CPM-bl8z.css +0 -1
package/bundle/ccv.mjs
CHANGED
|
@@ -5344,6 +5344,16 @@ import { mkdir as mkdir7, readFile as readFile9, writeFile as writeFile8 } from
|
|
|
5344
5344
|
import path14 from "node:path";
|
|
5345
5345
|
var SessionPins = class {
|
|
5346
5346
|
#pinned = /* @__PURE__ */ new Map();
|
|
5347
|
+
/**
|
|
5348
|
+
* Куда закрепление ушло с id, под которым его больше нет.
|
|
5349
|
+
*
|
|
5350
|
+
* Закрепление — место одной линии работы, а не одной сессии: оно переезжает
|
|
5351
|
+
* на дисковый id, на id после `/clear`, на сессию, продолженную из
|
|
5352
|
+
* хэндоффа. Хэндофф же остаётся у сессии, с которой оно давно ушло, и
|
|
5353
|
+
* продолжить из него могут позже — без следа хост не нашёл бы, у кого
|
|
5354
|
+
* закрепление сейчас, и новая сессия осталась бы вне панели.
|
|
5355
|
+
*/
|
|
5356
|
+
#moved = /* @__PURE__ */ new Map();
|
|
5347
5357
|
#storePath;
|
|
5348
5358
|
constructor(dataDir) {
|
|
5349
5359
|
this.#storePath = path14.join(dataDir, "session-pins.json");
|
|
@@ -5353,8 +5363,10 @@ var SessionPins = class {
|
|
|
5353
5363
|
const raw = await readFile9(this.#storePath, "utf8");
|
|
5354
5364
|
const parsed = JSON.parse(raw);
|
|
5355
5365
|
this.#pinned = new Map(Object.entries(parsed.pinned ?? {}).filter(([, r]) => isRecord2(r)));
|
|
5366
|
+
this.#moved = new Map(Object.entries(parsed.moved ?? {}).filter(([, to]) => typeof to === "string"));
|
|
5356
5367
|
} catch {
|
|
5357
5368
|
this.#pinned = /* @__PURE__ */ new Map();
|
|
5369
|
+
this.#moved = /* @__PURE__ */ new Map();
|
|
5358
5370
|
}
|
|
5359
5371
|
}
|
|
5360
5372
|
find(sessionId) {
|
|
@@ -5363,6 +5375,22 @@ var SessionPins = class {
|
|
|
5363
5375
|
has(sessionId) {
|
|
5364
5376
|
return this.#pinned.has(sessionId);
|
|
5365
5377
|
}
|
|
5378
|
+
/**
|
|
5379
|
+
* У кого сейчас закрепление, когда-то бывшее на `sessionId`: сам этот id,
|
|
5380
|
+
* если оно ещё на нём, иначе — конец следа переездов. `undefined` — оно
|
|
5381
|
+
* никуда не вело или его с тех пор сняли.
|
|
5382
|
+
*/
|
|
5383
|
+
holder(sessionId) {
|
|
5384
|
+
const seen = /* @__PURE__ */ new Set();
|
|
5385
|
+
let current = sessionId;
|
|
5386
|
+
while (current !== void 0 && !seen.has(current)) {
|
|
5387
|
+
if (this.#pinned.has(current))
|
|
5388
|
+
return current;
|
|
5389
|
+
seen.add(current);
|
|
5390
|
+
current = this.#moved.get(current);
|
|
5391
|
+
}
|
|
5392
|
+
return void 0;
|
|
5393
|
+
}
|
|
5366
5394
|
/** Проекты, в которых есть хоть что-то закреплённое, — по ним собирается панель. */
|
|
5367
5395
|
workspaceIds() {
|
|
5368
5396
|
return [...new Set([...this.#pinned.values()].map((r) => r.workspaceId))];
|
|
@@ -5406,6 +5434,7 @@ var SessionPins = class {
|
|
|
5406
5434
|
this.#pinned.delete(fromId);
|
|
5407
5435
|
if (!this.#pinned.has(toId))
|
|
5408
5436
|
this.#pinned.set(toId, record);
|
|
5437
|
+
this.#moved.set(fromId, toId);
|
|
5409
5438
|
await this.#persist();
|
|
5410
5439
|
return true;
|
|
5411
5440
|
}
|
|
@@ -5418,6 +5447,10 @@ var SessionPins = class {
|
|
|
5418
5447
|
* иначе прежняя так и останется в панели. Время берётся у первой найденной
|
|
5419
5448
|
* записи — новая встаёт ровно на место прежней, а не в конец панели.
|
|
5420
5449
|
* Возвращает `true`, если прежняя была закреплена.
|
|
5450
|
+
*
|
|
5451
|
+
* Закрепление могло уйти с прежней дальше (см. `holder`) — тогда в
|
|
5452
|
+
* `fromIds` называют и нынешнего держателя: след с каждого из них теперь
|
|
5453
|
+
* ведёт на `toId`.
|
|
5421
5454
|
*/
|
|
5422
5455
|
async transfer(fromIds, toId) {
|
|
5423
5456
|
let record;
|
|
@@ -5428,6 +5461,9 @@ var SessionPins = class {
|
|
|
5428
5461
|
if (!record)
|
|
5429
5462
|
return false;
|
|
5430
5463
|
this.#pinned.set(toId, record);
|
|
5464
|
+
for (const id of fromIds)
|
|
5465
|
+
if (id !== toId)
|
|
5466
|
+
this.#moved.set(id, toId);
|
|
5431
5467
|
await this.#persist();
|
|
5432
5468
|
return true;
|
|
5433
5469
|
}
|
|
@@ -5451,7 +5487,14 @@ var SessionPins = class {
|
|
|
5451
5487
|
return changed;
|
|
5452
5488
|
}
|
|
5453
5489
|
async #persist() {
|
|
5454
|
-
const
|
|
5490
|
+
for (const id of [...this.#moved.keys()]) {
|
|
5491
|
+
if (this.holder(id) === void 0)
|
|
5492
|
+
this.#moved.delete(id);
|
|
5493
|
+
}
|
|
5494
|
+
const file = {
|
|
5495
|
+
pinned: Object.fromEntries(this.#pinned),
|
|
5496
|
+
...this.#moved.size > 0 ? { moved: Object.fromEntries(this.#moved) } : {}
|
|
5497
|
+
};
|
|
5455
5498
|
await mkdir7(path14.dirname(this.#storePath), { recursive: true });
|
|
5456
5499
|
await writeFile8(this.#storePath, JSON.stringify(file, null, 2), "utf8");
|
|
5457
5500
|
}
|
|
@@ -8517,8 +8560,30 @@ var HostServer = class {
|
|
|
8517
8560
|
session.start();
|
|
8518
8561
|
this.#sendLive();
|
|
8519
8562
|
this.#send(socket, { type: "session.summary", session: session.summary() });
|
|
8520
|
-
if (frame.continuesFrom)
|
|
8521
|
-
|
|
8563
|
+
if (!frame.continuesFrom)
|
|
8564
|
+
return;
|
|
8565
|
+
await this.#carryPin(workspace.id, frame.continuesFrom, session.id);
|
|
8566
|
+
if (frame.fromHandoff)
|
|
8567
|
+
await this.#markHandoffContinued(frame.continuesFrom);
|
|
8568
|
+
}
|
|
8569
|
+
/**
|
|
8570
|
+
* Отметить хэндофф продолженным — и сказать об этом всем окнам. Он остаётся
|
|
8571
|
+
* лежать у прежней сессии, пока его не скроют, и без отметки её баннер звал
|
|
8572
|
+
* бы продолжить ещё раз так же настойчиво, как в первый: уже с места, с
|
|
8573
|
+
* которого работа давно ушла.
|
|
8574
|
+
*/
|
|
8575
|
+
async #markHandoffContinued(sessionId) {
|
|
8576
|
+
const handoff = await this.#handoffs.get(sessionId);
|
|
8577
|
+
if (!handoff)
|
|
8578
|
+
return;
|
|
8579
|
+
const continued = { ...handoff, continuedAt: Date.now() };
|
|
8580
|
+
try {
|
|
8581
|
+
await this.#handoffs.save(continued);
|
|
8582
|
+
} catch (error) {
|
|
8583
|
+
console.error("[handoff]", error instanceof Error ? error.message : String(error));
|
|
8584
|
+
return;
|
|
8585
|
+
}
|
|
8586
|
+
this.#broadcast({ type: "handoff.state", sessionId, handoff: continued });
|
|
8522
8587
|
}
|
|
8523
8588
|
/**
|
|
8524
8589
|
* «Продолжить в новой сессии» из хэндоффа: закрепление прежней сессии
|
|
@@ -8530,13 +8595,29 @@ var HostServer = class {
|
|
|
8530
8595
|
* на него запись переедет сама, как у любой свежей закреплённой (см.
|
|
8531
8596
|
* `#wire`). У прежней снимаем оба id — она может быть ещё жива, и тогда
|
|
8532
8597
|
* закрепление записано и под её uuid (см. `case 'session.pin'`).
|
|
8598
|
+
*
|
|
8599
|
+
* Закрепление могло уйти с прежней раньше — её уже продолжали, и хэндофф с
|
|
8600
|
+
* тех пор лежит у неё без дела. Тогда оно у потомка той же линии работы, и
|
|
8601
|
+
* новая сессия занимает место у него (см. `SessionPins.holder`): иначе
|
|
8602
|
+
* продолжение из старого хэндоффа оставляло бы в панели прежнюю строку, а
|
|
8603
|
+
* новую — вне её.
|
|
8533
8604
|
*/
|
|
8534
8605
|
async #carryPin(workspaceId, fromId, toId) {
|
|
8535
|
-
const
|
|
8606
|
+
const ids = /* @__PURE__ */ new Set([fromId]);
|
|
8607
|
+
const holder = this.#pins.holder(fromId);
|
|
8608
|
+
if (holder && holder !== toId)
|
|
8609
|
+
ids.add(holder);
|
|
8536
8610
|
for (const live of this.#sessions.values()) {
|
|
8537
|
-
if (live.id
|
|
8538
|
-
|
|
8611
|
+
if (live.id === toId)
|
|
8612
|
+
continue;
|
|
8613
|
+
const diskId = live.claudeSessionId;
|
|
8614
|
+
if (!ids.has(live.id) && !(diskId && ids.has(diskId)))
|
|
8615
|
+
continue;
|
|
8616
|
+
ids.add(live.id);
|
|
8617
|
+
if (diskId)
|
|
8618
|
+
ids.add(diskId);
|
|
8539
8619
|
}
|
|
8620
|
+
const fromIds = [...ids];
|
|
8540
8621
|
if (!await this.#pins.transfer(fromIds, toId))
|
|
8541
8622
|
return;
|
|
8542
8623
|
for (const id of fromIds)
|
package/package.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{s as r,H as a}from"./index-
|
|
1
|
+
import{s as r,H as a}from"./index-DHVISfG-.js";import{E as e}from"./index-891wE-Rj.js";import{t as o}from"./index-DlOju0OY.js";import"./index-BHot-lnj.js";const m=e.theme({"&":{height:"100%",color:"var(--text)",backgroundColor:"var(--bg)",fontSize:"13px"},".cm-scroller":{fontFamily:"var(--mono)",lineHeight:"1.6"},".cm-content":{caretColor:"var(--accent)"},".cm-cursor, .cm-dropCursor":{borderLeftColor:"var(--accent)"},"&.cm-focused .cm-selectionBackground, .cm-selectionBackground, .cm-content ::selection":{backgroundColor:"var(--cm-selection)"},".cm-gutters":{backgroundColor:"var(--bg)",color:"var(--muted)",borderRight:"1px solid var(--border-soft)"},".cm-activeLineGutter":{backgroundColor:"var(--surface-2)",color:"var(--text-2)"},".cm-activeLine":{backgroundColor:"var(--cm-active)"},".cm-selectionMatch":{backgroundColor:"var(--cm-match)"},"&.cm-focused .cm-matchingBracket":{backgroundColor:"var(--cm-match)",outline:"1px solid var(--accent-line)"},".cm-foldPlaceholder":{backgroundColor:"var(--surface-2)",border:"1px solid var(--border)",color:"var(--muted)"},".cm-panels":{backgroundColor:"var(--surface)",color:"var(--text)",border:"1px solid var(--border)"},".cm-panels input, .cm-panels button, .cm-panels select":{fontFamily:"var(--sans)",fontSize:"12px",background:"var(--surface-2)",color:"var(--text)",border:"1px solid var(--border)",borderRadius:"6px",padding:"3px 6px"},".cm-searchMatch":{backgroundColor:"var(--cm-match)"},".cm-searchMatch.cm-searchMatch-selected":{backgroundColor:"var(--accent-soft)"},".cm-tooltip":{background:"var(--surface)",border:"1px solid var(--border)",borderRadius:"8px",boxShadow:"var(--shadow-md)",color:"var(--text)"},".cm-tooltip-autocomplete ul li[aria-selected]":{background:"var(--surface-2)",color:"var(--text)"}}),i=r(a.define([{tag:[o.keyword,o.modifier,o.controlKeyword,o.moduleKeyword],color:"var(--cm-key)"},{tag:[o.name,o.deleted,o.character,o.macroName],color:"var(--text)"},{tag:[o.propertyName],color:"var(--cm-prop)"},{tag:[o.function(o.variableName),o.labelName],color:"var(--cm-fn)"},{tag:[o.color,o.constant(o.name),o.standard(o.name),o.bool],color:"var(--cm-const)"},{tag:[o.definition(o.name),o.separator],color:"var(--text)"},{tag:[o.typeName,o.className,o.changed,o.annotation,o.self,o.namespace],color:"var(--cm-type)"},{tag:[o.number,o.integer,o.float],color:"var(--cm-num)"},{tag:[o.string,o.special(o.string),o.regexp],color:"var(--cm-str)"},{tag:[o.operator,o.operatorKeyword,o.escape],color:"var(--cm-op)"},{tag:[o.meta,o.comment],color:"var(--cm-comment)",fontStyle:"italic"},{tag:o.strong,fontWeight:"650"},{tag:o.emphasis,fontStyle:"italic"},{tag:o.strikethrough,textDecoration:"line-through"},{tag:o.link,color:"var(--cm-str)",textDecoration:"underline"},{tag:o.heading,fontWeight:"650",color:"var(--cm-key)"},{tag:o.invalid,color:"var(--danger)"}]));export{i as editorHighlight,m as editorTheme};
|