@i14ks/ccv 0.21.0 → 0.22.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.
Files changed (26) hide show
  1. package/bundle/ccv.mjs +155 -0
  2. package/package.json +1 -1
  3. package/web/assets/{codemirror-B6QVSqxx.js → codemirror-BVRIW86g.js} +1 -1
  4. package/web/assets/{index-DdFPrUTi.js → index-5z-WKiE2.js} +1 -1
  5. package/web/assets/{index-0l0v5ZjK.js → index-A6KnUhy4.js} +1 -1
  6. package/web/assets/{index-CCRhGn6u.js → index-B54sB01B.js} +1 -1
  7. package/web/assets/{index-BYERpa5Q.js → index-B5EnmuL9.js} +1 -1
  8. package/web/assets/{index-CqM8bKzd.js → index-BOTbHjsh.js} +1 -1
  9. package/web/assets/{index-B8GLobgh.js → index-BRDMJVs_.js} +1 -1
  10. package/web/assets/{index-1VuadINO.js → index-BSbB9pNN.js} +1 -1
  11. package/web/assets/{index-Zo5hIeFa.js → index-BTHa3RWC.js} +1 -1
  12. package/web/assets/{index-oOWAdIqY.js → index-BUtKkXYx.js} +1 -1
  13. package/web/assets/{index-C5hGXrTC.js → index-C4RL1RRN.js} +1 -1
  14. package/web/assets/{index-B9qDsSjC.js → index-CEtwcv2R.js} +1 -1
  15. package/web/assets/{index-DmwQZoSG.js → index-CHk-wT2e.js} +1 -1
  16. package/web/assets/{index-BwuRWAfa.js → index-CftAsWDp.js} +1 -1
  17. package/web/assets/{index-Bf6VCb0a.js → index-Cj3tIh2i.js} +1 -1
  18. package/web/assets/{index-Cgi4XmXk.js → index-CwbKEdO4.js} +1 -1
  19. package/web/assets/{index-BlPPlrvg.js → index-DcOycRyY.js} +1 -1
  20. package/web/assets/{index-BqED4I4f.js → index-DiFzORZa.js} +1 -1
  21. package/web/assets/{index-rsg6TYOk.js → index-DqNX5AfU.js} +1 -1
  22. package/web/assets/index-L8M_w2e-.js +134 -0
  23. package/web/assets/{index-CTe-duo7.js → index-iBO43oLF.js} +1 -1
  24. package/web/assets/{index-Dv13T8ko.css → index-xoxa8R94.css} +1 -1
  25. package/web/index.html +2 -2
  26. package/web/assets/index-3BSpF-Pn.js +0 -134
package/bundle/ccv.mjs CHANGED
@@ -2154,6 +2154,41 @@ var ClaudeSession = class extends EventEmitter {
2154
2154
  throw new Error("\u0421\u0435\u0441\u0441\u0438\u044F \u0435\u0449\u0451 \u043D\u0435 \u0437\u0430\u043F\u0443\u0449\u0435\u043D\u0430");
2155
2155
  await this.#query.reconnectMcpServer(name);
2156
2156
  }
2157
+ /**
2158
+ * Начать OAuth-вход сервера в `needs-auth`.
2159
+ *
2160
+ * `mcpAuthenticate` есть в `Query`, но не в `sdk.d.ts` — отсюда приведение.
2161
+ * CLI сам слушает колбэк на `localhost` и сам переподключает сервер после
2162
+ * входа; нам отдаёт только ссылку. Без `redirectUri` — тогда CLI выбирает
2163
+ * локальный колбэк, единственный, что работает без своего домена.
2164
+ */
2165
+ async authenticateMcpServer(name) {
2166
+ if (!this.#query)
2167
+ throw new Error("\u0421\u0435\u0441\u0441\u0438\u044F \u0435\u0449\u0451 \u043D\u0435 \u0437\u0430\u043F\u0443\u0449\u0435\u043D\u0430");
2168
+ const q = this.#query;
2169
+ if (typeof q.mcpAuthenticate !== "function") {
2170
+ throw new Error("\u042D\u0442\u0430 \u0432\u0435\u0440\u0441\u0438\u044F Agent SDK \u043D\u0435 \u0443\u043C\u0435\u0435\u0442 \u0430\u0432\u0442\u043E\u0440\u0438\u0437\u043E\u0432\u0430\u0442\u044C MCP-\u0441\u0435\u0440\u0432\u0435\u0440\u044B");
2171
+ }
2172
+ const response = await q.mcpAuthenticate(name) ?? {};
2173
+ return {
2174
+ url: typeof response.authUrl === "string" ? response.authUrl : "",
2175
+ requiresUserAction: response.requiresUserAction === true,
2176
+ callbackExpected: response.callbackExpected === true
2177
+ };
2178
+ }
2179
+ /**
2180
+ * Отдать CLI адрес редиректа, вставленный руками, — когда браузер не на этой
2181
+ * машине и до `localhost` хоста не достучался. Резолвится после входа.
2182
+ */
2183
+ async submitMcpOAuthCallback(name, callbackUrl) {
2184
+ if (!this.#query)
2185
+ throw new Error("\u0421\u0435\u0441\u0441\u0438\u044F \u0435\u0449\u0451 \u043D\u0435 \u0437\u0430\u043F\u0443\u0449\u0435\u043D\u0430");
2186
+ const q = this.#query;
2187
+ if (typeof q.mcpSubmitOAuthCallbackUrl !== "function") {
2188
+ throw new Error("\u042D\u0442\u0430 \u0432\u0435\u0440\u0441\u0438\u044F Agent SDK \u043D\u0435 \u0443\u043C\u0435\u0435\u0442 \u0430\u0432\u0442\u043E\u0440\u0438\u0437\u043E\u0432\u0430\u0442\u044C MCP-\u0441\u0435\u0440\u0432\u0435\u0440\u044B");
2189
+ }
2190
+ await q.mcpSubmitOAuthCallbackUrl(name, callbackUrl);
2191
+ }
2157
2192
  /** Включить или выключить сервер — тот же обход слэш-команды, что выше. */
2158
2193
  async toggleMcpServer(name, enabled) {
2159
2194
  if (!this.#query)
@@ -3647,6 +3682,12 @@ Attached image${paths.length > 1 ? "s" : ""} (view them with your file viewing t
3647
3682
  async toggleMcpServer(_name, _enabled) {
3648
3683
  throw new Error("MCP-\u0441\u0435\u0440\u0432\u0435\u0440\u044B Antigravity \u043D\u0430\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u044E\u0442\u0441\u044F \u0432 \u0441\u0430\u043C\u043E\u043C agy (`agy mcp`)");
3649
3684
  }
3685
+ async authenticateMcpServer(_name) {
3686
+ throw new Error("MCP-\u0441\u0435\u0440\u0432\u0435\u0440\u044B Antigravity \u043D\u0430\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u044E\u0442\u0441\u044F \u0432 \u0441\u0430\u043C\u043E\u043C agy (`agy mcp`)");
3687
+ }
3688
+ async submitMcpOAuthCallback(_name, _callbackUrl) {
3689
+ throw new Error("MCP-\u0441\u0435\u0440\u0432\u0435\u0440\u044B Antigravity \u043D\u0430\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u044E\u0442\u0441\u044F \u0432 \u0441\u0430\u043C\u043E\u043C agy (`agy mcp`)");
3690
+ }
3650
3691
  setTitle(title) {
3651
3692
  this.#record.title = title;
3652
3693
  this.#titleIsDefault = false;
@@ -7506,6 +7547,8 @@ var FINDER_TITLE = "\xB7 \u043F\u043E\u0438\u0441\u043A \u043F\u0440\u043E\u0435
7506
7547
  var HISTORY_PAGE = 250;
7507
7548
  var HISTORY_PAGE_MAX = 500;
7508
7549
  var AUTO_STOP_SWEEP_MS = 30 * 1e3;
7550
+ var MCP_AUTH_POLL_MS = 2 * 1e3;
7551
+ var MCP_AUTH_TIMEOUT_MS = 10 * 60 * 1e3;
7509
7552
  var BUSY_STATES2 = /* @__PURE__ */ new Set([
7510
7553
  "running",
7511
7554
  "waiting_permission",
@@ -7521,6 +7564,8 @@ var HostServer = class {
7521
7564
  #settings;
7522
7565
  #finder;
7523
7566
  #sessions = /* @__PURE__ */ new Map();
7567
+ /** Опросы статуса для идущих OAuth-входов MCP, ключ — сессия и сервер. */
7568
+ #mcpAuthWatch = /* @__PURE__ */ new Map();
7524
7569
  #antigravity;
7525
7570
  /** Боковые сессии («вопрос на полях») по id родителя — не больше одной на разговор. */
7526
7571
  #sides = /* @__PURE__ */ new Map();
@@ -8182,6 +8227,56 @@ var HostServer = class {
8182
8227
  await this.#sendMcpList(frame.sessionId);
8183
8228
  return;
8184
8229
  }
8230
+ case "mcp.auth": {
8231
+ const session = this.#requireSession(frame.sessionId);
8232
+ const { name } = frame;
8233
+ const base = { name, url: "", callbackExpected: false, done: false };
8234
+ try {
8235
+ const start = await session.authenticateMcpServer(name);
8236
+ this.#broadcast({
8237
+ type: "mcp.auth",
8238
+ sessionId: frame.sessionId,
8239
+ state: {
8240
+ ...base,
8241
+ active: true,
8242
+ url: start.requiresUserAction ? start.url : "",
8243
+ callbackExpected: start.callbackExpected,
8244
+ error: null
8245
+ }
8246
+ });
8247
+ this.#watchMcpAuth(frame.sessionId, name);
8248
+ } catch (error) {
8249
+ const message = error instanceof Error ? error.message : String(error);
8250
+ this.#broadcast({
8251
+ type: "mcp.auth",
8252
+ sessionId: frame.sessionId,
8253
+ state: { ...base, active: false, error: message }
8254
+ });
8255
+ this.#reportOperation(frame.sessionId, "mcp", false, message);
8256
+ }
8257
+ return;
8258
+ }
8259
+ case "mcp.auth_callback": {
8260
+ const session = this.#requireSession(frame.sessionId);
8261
+ try {
8262
+ await session.submitMcpOAuthCallback(frame.name, frame.callbackUrl.trim());
8263
+ } catch (error) {
8264
+ const message = error instanceof Error ? error.message : String(error);
8265
+ this.#broadcast({
8266
+ type: "mcp.auth",
8267
+ sessionId: frame.sessionId,
8268
+ state: {
8269
+ name: frame.name,
8270
+ active: true,
8271
+ url: "",
8272
+ callbackExpected: true,
8273
+ done: false,
8274
+ error: message
8275
+ }
8276
+ });
8277
+ }
8278
+ return;
8279
+ }
8185
8280
  case "plugin.list":
8186
8281
  await this.#sendPluginList(frame.sessionId);
8187
8282
  return;
@@ -8629,6 +8724,66 @@ var HostServer = class {
8629
8724
  this.#reportOperation(sessionId, "plugin", ok, message);
8630
8725
  await this.#sendPluginList(sessionId);
8631
8726
  }
8727
+ /**
8728
+ * Дождаться, пока сервер выйдет из `needs-auth`.
8729
+ *
8730
+ * О конце входа CLI не сообщает ничем: после колбэка он молча меняет токены
8731
+ * и переподключает сервер у себя. Остаётся спрашивать статус, пока не
8732
+ * изменится, — недолго, потому что вход человек либо проходит за минуты,
8733
+ * либо бросает.
8734
+ */
8735
+ #watchMcpAuth(sessionId, name) {
8736
+ const key = `${sessionId}/${name}`;
8737
+ clearInterval(this.#mcpAuthWatch.get(key));
8738
+ const startedAt = Date.now();
8739
+ const finish = () => {
8740
+ clearInterval(this.#mcpAuthWatch.get(key));
8741
+ this.#mcpAuthWatch.delete(key);
8742
+ };
8743
+ const timer = setInterval(() => {
8744
+ void (async () => {
8745
+ const session = this.#sessions.get(sessionId);
8746
+ if (!session)
8747
+ return finish();
8748
+ if (Date.now() - startedAt > MCP_AUTH_TIMEOUT_MS) {
8749
+ finish();
8750
+ this.#broadcast({
8751
+ type: "mcp.auth",
8752
+ sessionId,
8753
+ state: {
8754
+ name,
8755
+ active: false,
8756
+ url: "",
8757
+ callbackExpected: false,
8758
+ done: false,
8759
+ error: "\u0412\u0445\u043E\u0434 \u043D\u0435 \u0437\u0430\u0432\u0435\u0440\u0448\u0451\u043D \u2014 \u0438\u0441\u0442\u0435\u043A\u043B\u043E \u0432\u0440\u0435\u043C\u044F \u043E\u0436\u0438\u0434\u0430\u043D\u0438\u044F"
8760
+ }
8761
+ });
8762
+ return;
8763
+ }
8764
+ const status = (await session.mcpServerStatus()).find((s) => s.name === name)?.status;
8765
+ if (status === "needs-auth" || status === "pending")
8766
+ return;
8767
+ finish();
8768
+ const ok = status === "connected";
8769
+ this.#broadcast({
8770
+ type: "mcp.auth",
8771
+ sessionId,
8772
+ state: {
8773
+ name,
8774
+ active: false,
8775
+ url: "",
8776
+ callbackExpected: false,
8777
+ done: ok,
8778
+ error: ok ? null : `\u0421\u0435\u0440\u0432\u0435\u0440 \xAB${name}\xBB \u043F\u043E\u0441\u043B\u0435 \u0432\u0445\u043E\u0434\u0430 \u0432 \u0441\u0442\u0430\u0442\u0443\u0441\u0435 ${status ?? "\u043D\u0435\u0438\u0437\u0432\u0435\u0441\u0442\u043D\u043E"}`
8779
+ }
8780
+ });
8781
+ this.#reportOperation(sessionId, "mcp", ok, ok ? `\u0421\u0435\u0440\u0432\u0435\u0440 \xAB${name}\xBB \u0430\u0432\u0442\u043E\u0440\u0438\u0437\u043E\u0432\u0430\u043D \u0438 \u043F\u043E\u0434\u043A\u043B\u044E\u0447\u0451\u043D` : `\u0421\u0435\u0440\u0432\u0435\u0440 \xAB${name}\xBB \u043D\u0435 \u043F\u043E\u0434\u043A\u043B\u044E\u0447\u0438\u043B\u0441\u044F \u043F\u043E\u0441\u043B\u0435 \u0432\u0445\u043E\u0434\u0430`);
8782
+ await this.#sendMcpList(sessionId);
8783
+ })().catch(() => finish());
8784
+ }, MCP_AUTH_POLL_MS);
8785
+ this.#mcpAuthWatch.set(key, timer);
8786
+ }
8632
8787
  #reportOperation(sessionId, scope, ok, message) {
8633
8788
  this.#broadcast({ type: "operation.result", sessionId, result: { scope, ok, message } });
8634
8789
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@i14ks/ccv",
3
- "version": "0.21.0",
3
+ "version": "0.22.0",
4
4
  "license": "UNLICENSED",
5
5
  "description": "GUI для Claude Code: сессии агента в каталогах проектов, дерево файлов и редактор рядом с разговором.",
6
6
  "homepage": "https://claudevisual.com",
@@ -1 +1 @@
1
- import{s as r,H as a}from"./index-Zo5hIeFa.js";import{E as e}from"./index-891wE-Rj.js";import{t as o}from"./index-3BSpF-Pn.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};
1
+ import{s as r,H as a}from"./index-BTHa3RWC.js";import{E as e}from"./index-891wE-Rj.js";import{t as o}from"./index-L8M_w2e-.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};