@kirkchinese/dsh-citeciter 0.5.0 → 0.6.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 (32) hide show
  1. package/README.md +63 -71
  2. package/README.zh.md +63 -71
  3. package/lib/client.js +420 -283
  4. package/lib/index.js +47 -40
  5. package/lib/{typert-common-DKqYKnRO.js → typert-common-C6yTitXx.js} +1 -1
  6. package/lib/typert.host.js +2 -2
  7. package/lib/typert.remote-client.js +1 -1
  8. package/lib/types/client/companion-controller.d.ts +5 -2
  9. package/lib/types/client/components/BlackboardWorkspace.d.ts +7 -5
  10. package/lib/types/client/components/CiteCiterSettings.d.ts +12 -7
  11. package/lib/types/client/components/CitePanel.d.ts +9 -5
  12. package/lib/types/client/components/DocumentReader.d.ts +6 -3
  13. package/lib/types/client/components/QuestionCard.d.ts +2 -2
  14. package/lib/types/client/components/SelectionMenu.d.ts +9 -5
  15. package/lib/types/client/components/UpdateNotice.d.ts +6 -3
  16. package/lib/types/client/copy.d.ts +6 -0
  17. package/lib/types/client/dock-geometry.d.ts +23 -0
  18. package/lib/types/client/entries.d.ts +3 -2
  19. package/lib/types/client/host-dock.d.ts +18 -0
  20. package/lib/types/client/reader-controller.d.ts +1 -1
  21. package/lib/types/client/selection.d.ts +1 -1
  22. package/lib/types/client/types.d.ts +1 -1
  23. package/lib/types/client/update-controller.d.ts +5 -3
  24. package/lib/types/client/view-actions.d.ts +26 -0
  25. package/lib/types/index.d.ts +1 -1
  26. package/lib/types/observer.d.ts +2 -1
  27. package/lib/types/topic-runtime.d.ts +4 -4
  28. package/lib/types/typert-common.d.ts +1 -0
  29. package/lib/types/typert.host.d.ts +2 -0
  30. package/lib/types/update.d.ts +1 -0
  31. package/lib/{update-u9-6c_qp.js → update-C0K5ekMg.js} +2 -1
  32. package/package.json +83 -78
package/lib/index.js CHANGED
@@ -1,6 +1,5 @@
1
- import { E as boardBatchSchema, T as applyBoardOps, _ as documentSummarySchema, a as CITECITER_SETTINGS_NAMESPACE, b as toolEvidenceClaimSchema, c as canonicalCitationIdentity, d as citationSelectionClaimSchema, f as citeCiterRequestSchema, g as documentEvidenceClaimSchema, h as documentContentSchema, i as CITATION_CONTEXT_NAME, l as citationDraftSchema, m as citeCiterSettingsSchema, n as updateCheckErrorCodeSchema, o as DEFAULT_CITECITER_SETTINGS, r as updateCheckResponseSchema, s as TUTOR_SECTION_NAME, t as UpdateChecker, v as parseTopicMetadataFile, w as EMPTY_BOARD_STATE, x as topicMetadataSchema, y as renderCitationContext } from "./update-u9-6c_qp.js";
1
+ import { E as boardBatchSchema, T as applyBoardOps, _ as documentSummarySchema, a as CITECITER_SETTINGS_NAMESPACE, b as toolEvidenceClaimSchema, c as canonicalCitationIdentity, d as citationSelectionClaimSchema, f as citeCiterRequestSchema, g as documentEvidenceClaimSchema, h as documentContentSchema, i as CITATION_CONTEXT_NAME, l as citationDraftSchema, m as citeCiterSettingsSchema, n as updateCheckErrorCodeSchema, o as DEFAULT_CITECITER_SETTINGS, r as updateCheckResponseSchema, s as TUTOR_SECTION_NAME, t as UpdateChecker, v as parseTopicMetadataFile, w as EMPTY_BOARD_STATE, x as topicMetadataSchema, y as renderCitationContext } from "./update-C0K5ekMg.js";
2
2
  import { Context, Service } from "@deepseek-ai/cordis";
3
- import { settingsNamespace } from "@deepseek-ai/dsh-settings";
4
3
  import { Remote, TypertRemoteService } from "@deepseek-ai/dsh-typert-protocol";
5
4
  import z from "@deepseek-ai/schemastery";
6
5
  import { createHash, randomUUID } from "node:crypto";
@@ -10,9 +9,10 @@ import AgentRegistry, { installModelSelection } from "@deepseek-ai/dsh-agent";
10
9
  import AgentLoop from "@deepseek-ai/dsh-agent-loop";
11
10
  import { dshHomePath } from "@deepseek-ai/dsh-home-paths";
12
11
  import { BlockAssembler, MessageId, ReasoningEffortId, createUserMessage, freezeMessage } from "@deepseek-ai/dsh-llm";
13
- import { effectiveSandboxMode, setSandboxMode } from "@deepseek-ai/dsh-sandbox-policy";
14
- import SessionStore, { SESSION_FORMAT_VERSION, SessionId, foldRequestHeader, snapshotJsonValue } from "@deepseek-ai/dsh-session";
12
+ import SandboxPolicyService, { setSandboxMode } from "@deepseek-ai/dsh-sandbox-policy";
13
+ import SessionStore, { SESSION_FORMAT_VERSION, SessionId, SessionLogOffset, foldRequestHeader } from "@deepseek-ai/dsh-session";
15
14
  import JsonlSessionPersistence from "@deepseek-ai/dsh-session-persistence-jsonl";
15
+ import SessionProjectionRegistry from "@deepseek-ai/dsh-session-projection";
16
16
  import SessionTitleService, { SessionTitleProviderId, foldSessionTitle } from "@deepseek-ai/dsh-session-title";
17
17
  import { generateSessionTitleWithLlm, resolveSessionTitleLlmConfig } from "@deepseek-ai/dsh-session-title-llm";
18
18
  import SystemPrompt from "@deepseek-ai/dsh-system-prompt";
@@ -22,6 +22,7 @@ import * as ToolFsSearch from "@deepseek-ai/dsh-tool-fs-search";
22
22
  import ToolRuntime, { defineTool } from "@deepseek-ai/dsh-tools";
23
23
  import UserQuestionService, { UserQuestionError } from "@deepseek-ai/dsh-user-questions";
24
24
  import { z as z$1 } from "zod";
25
+ import { snapshotJsonValue } from "@deepseek-ai/dsh-util-values";
25
26
  //#region \0rolldown/runtime.js
26
27
  var __defProp = Object.defineProperty;
27
28
  var __exportAll = (all, no_symbols) => {
@@ -15343,9 +15344,7 @@ const BLACKBOARD_APPLY_PARAMETERS = { ops: {
15343
15344
  } };
15344
15345
  /** Select the first human question added after a Topic's inherited seed. */
15345
15346
  function selectTopicTitleMessage(request) {
15346
- const seedLength = request.session.header.seedLength ?? 0;
15347
- const seedBoundary = request.session.events[seedLength - 1]?.seq ?? -1;
15348
- const first = request.messages.find((message) => message.seq > seedBoundary);
15347
+ const first = request.messages.find((message) => message.seq >= request.session.inheritedEventCount);
15349
15348
  if (first === void 0) throw new Error("CiteCiter title generation requires one post-seed user question");
15350
15349
  return first;
15351
15350
  }
@@ -15447,6 +15446,7 @@ const topicDeletionMarkerSchema = z$1.object({
15447
15446
  version: z$1.number().int().nonnegative(),
15448
15447
  id: z$1.string().min(1),
15449
15448
  createdAt: z$1.number().int().nonnegative(),
15449
+ isSeeded: z$1.boolean().default(false),
15450
15450
  cwd: z$1.string().optional()
15451
15451
  }).strict()
15452
15452
  }).strict();
@@ -15554,6 +15554,7 @@ var TopicIndex = class {
15554
15554
  version: sessionHeader.version,
15555
15555
  id: sessionHeader.id,
15556
15556
  createdAt: sessionHeader.createdAt,
15557
+ isSeeded: sessionHeader.isSeeded,
15557
15558
  ...sessionHeader.cwd === void 0 ? {} : { cwd: sessionHeader.cwd }
15558
15559
  }
15559
15560
  };
@@ -15673,7 +15674,7 @@ function latestObservedSeq(events) {
15673
15674
  function topicMessages(log) {
15674
15675
  const messages = [];
15675
15676
  const toolIndexes = /* @__PURE__ */ new Map();
15676
- const start = log.header.seedLength ?? 0;
15677
+ const start = log.inheritedEventCount;
15677
15678
  let partial = null;
15678
15679
  let error = null;
15679
15680
  const attemptByTurn = /* @__PURE__ */ new Map();
@@ -15813,7 +15814,7 @@ function projectBoardFromLog(log) {
15813
15814
  let state = EMPTY_BOARD_STATE;
15814
15815
  let revision = 0;
15815
15816
  let invalid = 0;
15816
- const start = log.header.seedLength ?? 0;
15817
+ const start = log.inheritedEventCount;
15817
15818
  for (const event of log.events.slice(start)) {
15818
15819
  if (event.type === "tool/call" && event.data.name === "blackboard_apply") {
15819
15820
  calls.set(String(event.data.callId), event.data.arguments);
@@ -15850,7 +15851,7 @@ function projectBoardFromLog(log) {
15850
15851
  * @returns the first post-seed question, or `null` when it has not been committed.
15851
15852
  */
15852
15853
  function firstPostSeedUserQuestion(log) {
15853
- for (const event of log.events.slice(log.header.seedLength ?? 0)) {
15854
+ for (const event of log.events.slice(log.inheritedEventCount)) {
15854
15855
  if (event.type !== "user/message" || event.data.source.kind !== "user") continue;
15855
15856
  const text = textBlocks(event.data.content, "text");
15856
15857
  if (text !== "") return text;
@@ -15867,7 +15868,7 @@ function pendingPostSeedUserMessages(log) {
15867
15868
  "next-turn": [],
15868
15869
  "next-step": []
15869
15870
  };
15870
- for (const event of log.events.slice(log.header.seedLength ?? 0)) {
15871
+ for (const event of log.events.slice(log.inheritedEventCount)) {
15871
15872
  if (event.type !== "agent/inbox/spliced") continue;
15872
15873
  pending[event.data.target].splice(event.data.start, event.data.removedCount ?? 0, ...event.data.inserted);
15873
15874
  }
@@ -15886,7 +15887,7 @@ function postSeedUserQuestionById(log, messageId) {
15886
15887
  return pending === void 0 ? null : textBlocks(pending.content, "text");
15887
15888
  }
15888
15889
  function committedPostSeedUserQuestionById(log, messageId) {
15889
- for (const event of log.events.slice(log.header.seedLength ?? 0)) {
15890
+ for (const event of log.events.slice(log.inheritedEventCount)) {
15890
15891
  if (event.type !== "user/message" || event.data.source.kind !== "user" || String(event.data.id) !== messageId) continue;
15891
15892
  return textBlocks(event.data.content, "text");
15892
15893
  }
@@ -16016,8 +16017,6 @@ var TopicRuntime = class {
16016
16017
  releaseLlm;
16017
16018
  releaseFs;
16018
16019
  releaseSubprocess;
16019
- releaseSandboxPolicy;
16020
- releaseQuestionProvider;
16021
16020
  hasSourceFiles = false;
16022
16021
  closed = false;
16023
16022
  /** @param host - owning DSH context. @param settings - current user preferences. */
@@ -16156,14 +16155,14 @@ var TopicRuntime = class {
16156
16155
  this.releaseLlm = this.runtime.provide("llm", this.host.llm);
16157
16156
  const sourceFs = this.host.get("fs");
16158
16157
  const sourceSubprocess = this.host.get("subprocess");
16159
- const sandboxPolicy = this.host.get("sandboxPolicy");
16160
- if (sourceFs !== void 0 && sourceSubprocess !== void 0 && sandboxPolicy !== void 0) {
16158
+ if (sourceFs !== void 0 && sourceSubprocess !== void 0) {
16161
16159
  this.releaseFs = this.runtime.provide("fs", sourceFs);
16162
16160
  this.releaseSubprocess = this.runtime.provide("subprocess", sourceSubprocess);
16163
- this.releaseSandboxPolicy = this.runtime.provide("sandboxPolicy", sandboxPolicy);
16164
16161
  this.hasSourceFiles = true;
16165
16162
  }
16166
16163
  this.fibers.push(await this.runtime.plugin(SessionStore));
16164
+ this.fibers.push(await this.runtime.plugin(SessionProjectionRegistry));
16165
+ this.fibers.push(await this.runtime.plugin(SandboxPolicyService, { mode: "read-only" }));
16167
16166
  this.fibers.push(await this.runtime.plugin(AgentRegistry));
16168
16167
  this.fibers.push(await this.runtime.plugin(SystemPrompt, {
16169
16168
  includeHarnessIdentity: true,
@@ -16171,7 +16170,6 @@ var TopicRuntime = class {
16171
16170
  }));
16172
16171
  this.fibers.push(await this.runtime.plugin(ToolRuntime, { mode: "native" }));
16173
16172
  this.fibers.push(await this.runtime.plugin(UserQuestionService));
16174
- this.releaseQuestionProvider = this.runtime.userQuestions.registerProvider({ ask: (request) => this.askUser(request) });
16175
16173
  this.fibers.push(await this.runtime.plugin(ToolAskUser));
16176
16174
  if (this.hasSourceFiles) {
16177
16175
  this.fibers.push(await this.runtime.plugin(ToolFs, {}));
@@ -16218,12 +16216,6 @@ var TopicRuntime = class {
16218
16216
  }
16219
16217
  async releaseOwnedRuntime() {
16220
16218
  const failures = [];
16221
- try {
16222
- this.releaseQuestionProvider?.();
16223
- } catch (error) {
16224
- failures.push(error);
16225
- }
16226
- this.releaseQuestionProvider = void 0;
16227
16219
  for (const pending of this.pendingQuestions.values()) {
16228
16220
  pending.signal?.removeEventListener("abort", pending.onAbort);
16229
16221
  pending.reject(new UserQuestionError(CITECITER_SHUTTING_DOWN, "ASK_ABORTED"));
@@ -16256,7 +16248,6 @@ var TopicRuntime = class {
16256
16248
  this.titleRefreshes.clear();
16257
16249
  this.opening.clear();
16258
16250
  for (const release of [
16259
- this.releaseSandboxPolicy,
16260
16251
  this.releaseSubprocess,
16261
16252
  this.releaseFs,
16262
16253
  this.releaseLlm
@@ -16265,7 +16256,6 @@ var TopicRuntime = class {
16265
16256
  } catch (error) {
16266
16257
  failures.push(error);
16267
16258
  }
16268
- this.releaseSandboxPolicy = void 0;
16269
16259
  this.releaseFs = void 0;
16270
16260
  this.releaseSubprocess = void 0;
16271
16261
  this.releaseLlm = void 0;
@@ -16454,10 +16444,11 @@ var TopicRuntime = class {
16454
16444
  sessionId: SessionId(metadata.sessionId),
16455
16445
  ...metadata.mode === "exact-fork" ? {
16456
16446
  seed,
16447
+ inheritedEventCount: SessionLogOffset(seed.length),
16457
16448
  meta: {
16458
16449
  ...metadata.sourceCwd === "" ? {} : { cwd: metadata.sourceCwd },
16459
16450
  parentSession: SessionId(metadata.sourceSessionId),
16460
- seedLength: seed.length
16451
+ isSeeded: true
16461
16452
  }
16462
16453
  } : metadata.sourceCwd === "" ? {} : { meta: { cwd: metadata.sourceCwd } },
16463
16454
  agentOptions: {
@@ -16475,7 +16466,7 @@ var TopicRuntime = class {
16475
16466
  this.handles.set(metadata.sessionId, handle);
16476
16467
  return handle;
16477
16468
  }
16478
- setupAgent(agentCtx, metadata) {
16469
+ async setupAgent(agentCtx, metadata) {
16479
16470
  const agent = agentCtx.agent;
16480
16471
  if (agent === void 0) throw new Error("CiteCiter Topic setup has no scoped Agent");
16481
16472
  const selection = metadataModelSelection(metadata);
@@ -16518,14 +16509,21 @@ var TopicRuntime = class {
16518
16509
  });
16519
16510
  agentCtx.on("agent/request", async (_request, next) => {
16520
16511
  const current = await next();
16521
- if (foldRequestHeader(agent.session.events) !== void 0) return current;
16512
+ if (agent.session.requestHeader() !== void 0) return current;
16522
16513
  return {
16523
16514
  ...current,
16524
16515
  ...metadata.modelConfig.temperature === void 0 ? {} : { temperature: metadata.modelConfig.temperature },
16525
16516
  ...metadata.modelConfig.stop === void 0 ? {} : { stop: [...metadata.modelConfig.stop] }
16526
16517
  };
16527
16518
  });
16528
- if (effectiveSandboxMode(agent.session.events) !== "read-only") setSandboxMode(agent.session, "read-only");
16519
+ await agentCtx.plugin({
16520
+ name: "citeciter-topic-policy",
16521
+ inject: ["sandboxPolicy"],
16522
+ apply(policyCtx) {
16523
+ if (policyCtx.sandboxPolicy.overrideOf(agent.session) !== "read-only") setSandboxMode(agent.session, "read-only");
16524
+ }
16525
+ });
16526
+ agentCtx.on("user-questions/request", (request) => this.askUser(request));
16529
16527
  }
16530
16528
  globTool() {
16531
16529
  return defineTool({
@@ -16659,7 +16657,8 @@ var TopicRuntime = class {
16659
16657
  if (session === void 0) throw new Error("blackboard_apply requires a Topic Session");
16660
16658
  const current = projectBoardFromLog({
16661
16659
  header: session.header,
16662
- events: session.events
16660
+ events: session.snapshotEvents(),
16661
+ inheritedEventCount: session.inheritedEventCount
16663
16662
  });
16664
16663
  applyBoardOps(new Map(current.elements.map((element) => [element.id, element])), ops);
16665
16664
  return { applied: ops.length };
@@ -16923,13 +16922,13 @@ var TopicRuntime = class {
16923
16922
  exec.signal.throwIfAborted();
16924
16923
  sourceAvailable = false;
16925
16924
  const agent = agentCtx.agent;
16926
- if (metadata.mode !== "exact-fork" || agent === void 0 || agent.session.header.seedLength === void 0) {
16925
+ if (metadata.mode !== "exact-fork" || agent === void 0 || !agent.session.header.isSeeded) {
16927
16926
  await this.rememberSourceAvailability(metadata, false);
16928
16927
  throw error;
16929
16928
  }
16930
16929
  source = {
16931
16930
  session: { id: SessionId(metadata.sourceSessionId) },
16932
- events: agent.session.events.slice(0, agent.session.header.seedLength)
16931
+ events: agent.session.snapshotEvents(SessionLogOffset(0), agent.session.inheritedEventCount)
16933
16932
  };
16934
16933
  }
16935
16934
  exec.signal.throwIfAborted();
@@ -17238,16 +17237,17 @@ var TopicRuntime = class {
17238
17237
  cleanup
17239
17238
  };
17240
17239
  }
17241
- /** Await rc.2 JSONL retirement without populating its prepared-session cache. */
17240
+ /** Await JSONL retirement without populating its prepared-session cache. */
17242
17241
  async readRetiredSessionHeader(metadata, signal) {
17243
17242
  try {
17244
- return (await this.runtime.sessionPersistence.readFrom(SessionId(metadata.sessionId), 0, signal)).meta;
17243
+ return (await this.runtime.sessionPersistence.readFrom(SessionId(metadata.sessionId), SessionLogOffset(0), signal)).meta;
17245
17244
  } catch (error) {
17246
17245
  if (!(error instanceof Error) || error.message !== `session "${metadata.sessionId}" not found`) throw error;
17247
17246
  return {
17248
17247
  version: SESSION_FORMAT_VERSION,
17249
17248
  id: SessionId(metadata.sessionId),
17250
17249
  createdAt: metadata.createdAt,
17250
+ isSeeded: metadata.mode === "exact-fork",
17251
17251
  ...metadata.sourceCwd === "" ? {} : { cwd: metadata.sourceCwd }
17252
17252
  };
17253
17253
  }
@@ -17469,13 +17469,15 @@ var TopicRuntime = class {
17469
17469
  const live = this.handles.get(metadata.sessionId)?.agent.session;
17470
17470
  if (live !== void 0) return {
17471
17471
  header: live.header,
17472
- events: live.events
17472
+ events: live.snapshotEvents(),
17473
+ inheritedEventCount: live.inheritedEventCount
17473
17474
  };
17474
17475
  const inspection = await this.runtime.sessionPersistence.inspect(SessionId(metadata.sessionId), signal);
17475
17476
  if (signal !== void 0) this.assertOpen(signal);
17476
17477
  return {
17477
17478
  header: inspection.meta,
17478
- events: inspection.events
17479
+ events: inspection.events,
17480
+ inheritedEventCount: inspection.inheritedEventCount
17479
17481
  };
17480
17482
  }
17481
17483
  scheduleSourceAvailabilityCheck(metadata) {
@@ -17556,7 +17558,7 @@ var TopicRuntime = class {
17556
17558
  }
17557
17559
  scheduleExactTitleRefresh(metadata, log) {
17558
17560
  if (this.closed || metadata.mode !== "exact-fork" || this.titleRefreshAttempted.has(metadata.sessionId) || this.handles.get(metadata.sessionId)?.agent.status === "running") return;
17559
- const postSeed = log.events.slice(log.header.seedLength ?? 0);
17561
+ const postSeed = log.events.slice(log.inheritedEventCount);
17560
17562
  if (!postSeed.some((event) => event.type === "request/header") || !postSeed.some((event) => event.type === "assistant/message")) return;
17561
17563
  this.titleRefreshAttempted.add(metadata.sessionId);
17562
17564
  const refresh = this.queueTopicAdmission(metadata.sessionId, async () => {
@@ -17632,7 +17634,7 @@ const inject = [
17632
17634
  "subprocess"
17633
17635
  ];
17634
17636
  /** Host settings identity shared with the browser settings scope. */
17635
- const CITECITER_SETTINGS_NS = settingsNamespace(CITECITER_SETTINGS_NAMESPACE);
17637
+ const CITECITER_SETTINGS_NS = CITECITER_SETTINGS_NAMESPACE;
17636
17638
  /** Native settings schema for new Topics and the companion panel. */
17637
17639
  const CITECITER_SETTINGS_SCHEMA = z.object({
17638
17640
  defaultMode: z.union(["observer", "exact-when-available"]).default(DEFAULT_CITECITER_SETTINGS.defaultMode),
@@ -17761,7 +17763,12 @@ let CiteCiterHost = (() => {
17761
17763
  }
17762
17764
  /** Check npm for an installable stable version without changing this installation. */
17763
17765
  async checkUpdate(signal) {
17764
- return this.updates.check(signal);
17766
+ const result = await this.updates.check(signal);
17767
+ const desktop = this.ctx.get("desktopProfiles");
17768
+ return result.kind === "success" && desktop !== void 0 ? {
17769
+ ...result,
17770
+ profile: desktop.current.name
17771
+ } : result;
17765
17772
  }
17766
17773
  };
17767
17774
  })();
@@ -1,4 +1,4 @@
1
- import { f as citeCiterRequestSchema, p as citeCiterResponseSchema, r as updateCheckResponseSchema } from "./update-u9-6c_qp.js";
1
+ import { f as citeCiterRequestSchema, p as citeCiterResponseSchema, r as updateCheckResponseSchema } from "./update-C0K5ekMg.js";
2
2
  //#region lib/types/typert-common.js
3
3
  /** Strict root-scoped Topic command shared by Host and browser manifests. */
4
4
  const citeCiterRequestDescriptor = {
@@ -1,5 +1,5 @@
1
- import { C as topicSummarySchema, S as topicSnapshotSchema, f as citeCiterRequestSchema, l as citationDraftSchema, p as citeCiterResponseSchema, r as updateCheckResponseSchema, u as citationRecordSchema } from "./update-u9-6c_qp.js";
2
- import { n as updateCheckDescriptor, t as citeCiterRequestDescriptor } from "./typert-common-DKqYKnRO.js";
1
+ import { C as topicSummarySchema, S as topicSnapshotSchema, f as citeCiterRequestSchema, l as citationDraftSchema, p as citeCiterResponseSchema, r as updateCheckResponseSchema, u as citationRecordSchema } from "./update-C0K5ekMg.js";
2
+ import { n as updateCheckDescriptor, t as citeCiterRequestDescriptor } from "./typert-common-C6yTitXx.js";
3
3
  //#region lib/types/typert.host.js
4
4
  /** Handwritten strict Host contribution matching the single Remote decorator. */
5
5
  const TYPERT = {
@@ -1,4 +1,4 @@
1
- import { n as updateCheckDescriptor, t as citeCiterRequestDescriptor } from "./typert-common-DKqYKnRO.js";
1
+ import { n as updateCheckDescriptor, t as citeCiterRequestDescriptor } from "./typert-common-C6yTitXx.js";
2
2
  //#region lib/types/typert.remote-client.js
3
3
  /** Browser contribution mounted by the CiteCiter Client fiber. */
4
4
  const TYPERT_REMOTE = {
@@ -1,4 +1,7 @@
1
- import { type ISessions, type SessionId, type SettingsScope, type SnapshotStore } from '@deepseek-ai/dsh-client-runtime/client';
1
+ import type { SessionId } from '@deepseek-ai/dsh-session/types';
2
+ import type { SettingsScope } from '@deepseek-ai/dsh-client-ui-settings/client';
3
+ import type { SnapshotStore } from '@deepseek-ai/dsh-client-store';
4
+ import type { ChatSnapshot } from '@deepseek-ai/dsh-client-ui-chat/client';
2
5
  import type { RemoteResult } from '@deepseek-ai/dsh-typert-protocol';
3
6
  import { type CiteCiterRequest, type CiteCiterResponse, type CiteCiterSettings, type ProviderOption, type QuestionAnswer, type TopicScenario, type TopicSnapshot, type TopicSummary } from '../topic.ts';
4
7
  import { type CreateMode, type DocumentClaimIntent } from './request-guard.ts';
@@ -56,4 +59,4 @@ export interface CompanionFace {
56
59
  /** Initial browser snapshot for the root-scoped CiteCiter controller. */
57
60
  export declare const INITIAL_COMPANION_SNAPSHOT: CompanionSnapshot;
58
61
  /** Bind private Topic Remote calls to one browser snapshot and polling lifecycle. */
59
- export declare function createCompanionController(sessions: ISessions, settingsScope: SettingsScope<CiteCiterSettings>, request: RemoteRequest, onAutoOpen: () => void, store: SnapshotStore<CompanionSnapshot>): CompanionFace;
62
+ export declare function createCompanionController(readChat: (sessionId: SessionId) => ChatSnapshot | undefined, settingsScope: SettingsScope<CiteCiterSettings>, request: RemoteRequest, onAutoOpen: () => void, store: SnapshotStore<CompanionSnapshot>): CompanionFace;
@@ -1,10 +1,12 @@
1
+ import type { SnapshotSelectorHook } from '@deepseek-ai/dsh-client-store';
2
+ import type { CompanionSnapshot } from '../companion-controller.ts';
3
+ import type { CompanionActions, OverlayActions } from '../view-actions.ts';
1
4
  import type { ConvViewProps } from '@deepseek-ai/dsh-client-ui-conversation/client';
2
- import type { CompanionFace } from '../companion-controller.ts';
3
- import type { CiteBus } from '../types.ts';
4
5
  /** Additional faces owned by CiteCiter's conversation-view registration. */
5
6
  export interface BlackboardWorkspaceInjected {
6
- readonly companion: CompanionFace;
7
- readonly bus: CiteBus;
7
+ readonly useCompanion: SnapshotSelectorHook<CompanionSnapshot>;
8
+ readonly companion: CompanionActions;
9
+ readonly bus: OverlayActions;
8
10
  readonly openPanel: () => void;
9
11
  }
10
12
  export type BlackboardWorkspaceProps = ConvViewProps & BlackboardWorkspaceInjected;
@@ -13,4 +15,4 @@ export type BlackboardWorkspaceProps = ConvViewProps & BlackboardWorkspaceInject
13
15
  * @param props - active DSH conversation identity and CiteCiter browser faces.
14
16
  * @returns the matching Topic board or a source-specific empty state.
15
17
  */
16
- export declare function BlackboardWorkspace({ sessionId, companion, bus, openPanel }: BlackboardWorkspaceProps): import("react").JSX.Element;
18
+ export declare function BlackboardWorkspace({ useCompanion, sessionId, companion, bus, openPanel }: BlackboardWorkspaceProps): import("react").JSX.Element;
@@ -1,11 +1,16 @@
1
+ import type { SnapshotSelectorHook } from '@deepseek-ai/dsh-client-store';
2
+ import type { UpdateNoticeSnapshot } from '../update-controller.ts';
3
+ import type { SettingsDocumentSnapshot } from '../settings-document.ts';
4
+ import type { CompanionSnapshot } from '../companion-controller.ts';
5
+ import type { CompanionActions, UpdateActions, SettingsDocumentActions } from '../view-actions.ts';
1
6
  import type { SettingsSectionOwnerProps } from '@deepseek-ai/dsh-client-ui-settings/client';
2
- import type { CompanionFace } from '../companion-controller.ts';
3
- import type { SettingsDocumentController } from '../settings-document.ts';
4
- import type { UpdateController } from '../update-controller.ts';
5
7
  export interface CiteCiterSettingsProps extends SettingsSectionOwnerProps {
6
- readonly companion: CompanionFace;
7
- readonly settingsDocument: SettingsDocumentController;
8
- readonly updateController: UpdateController;
8
+ readonly useCompanion: SnapshotSelectorHook<CompanionSnapshot>;
9
+ readonly useDocument: SnapshotSelectorHook<SettingsDocumentSnapshot>;
10
+ readonly useUpdate: SnapshotSelectorHook<UpdateNoticeSnapshot>;
11
+ readonly companion: CompanionActions;
12
+ readonly settingsDocument: SettingsDocumentActions;
13
+ readonly updateController: UpdateActions;
9
14
  }
10
15
  /** Native DSH settings page for CiteCiter-owned preferences. */
11
- export declare function CiteCiterSettings({ companion, settingsDocument, updateController }: CiteCiterSettingsProps): import("react").JSX.Element;
16
+ export declare function CiteCiterSettings({ useCompanion, useDocument, useUpdate, companion, settingsDocument, updateController }: CiteCiterSettingsProps): import("react").JSX.Element;
@@ -1,8 +1,12 @@
1
- import type { CompanionFace } from '../companion-controller.ts';
2
- import type { CiteBus } from '../types.ts';
1
+ import type { SnapshotSelectorHook } from '@deepseek-ai/dsh-client-store';
2
+ import type { CiteOverlaySnapshot } from '../types.ts';
3
+ import type { CompanionSnapshot } from '../companion-controller.ts';
4
+ import type { CompanionActions, OverlayActions } from '../view-actions.ts';
3
5
  export interface CitePanelProps {
4
- readonly bus: CiteBus;
5
- readonly companion: CompanionFace;
6
+ readonly useCompanion: SnapshotSelectorHook<CompanionSnapshot>;
7
+ readonly useOverlay: SnapshotSelectorHook<CiteOverlaySnapshot>;
8
+ readonly bus: OverlayActions;
9
+ readonly companion: CompanionActions;
6
10
  readonly closePanel: () => void;
7
11
  readonly reportParseError: (messageId: string) => void;
8
12
  }
@@ -11,4 +15,4 @@ export interface CitePanelProps {
11
15
  * @param props - shared panel bus, Topic controller, and host callbacks.
12
16
  * @returns the responsive Topic dock and its dialogs, or null while closed.
13
17
  */
14
- export declare function CitePanel({ bus, companion, closePanel, reportParseError }: CitePanelProps): import("react").JSX.Element | null;
18
+ export declare function CitePanel({ useCompanion, useOverlay, bus, companion, closePanel, reportParseError }: CitePanelProps): import("react").JSX.Element | null;
@@ -1,5 +1,8 @@
1
- import type { ReaderFace } from '../reader-controller.ts';
1
+ import type { SnapshotSelectorHook } from '@deepseek-ai/dsh-client-store';
2
+ import type { ReaderSnapshot } from '../reader-controller.ts';
3
+ import type { ReaderActions } from '../view-actions.ts';
2
4
  /** Reader shell-overlay entry: compact trigger plus the document library panel. */
3
- export declare function DocumentReader({ reader }: {
4
- readonly reader: ReaderFace;
5
+ export declare function DocumentReader({ reader, useReader }: {
6
+ readonly reader: ReaderActions;
7
+ readonly useReader: SnapshotSelectorHook<ReaderSnapshot>;
5
8
  }): import("react").JSX.Element;
@@ -1,7 +1,7 @@
1
- import type { CompanionFace } from '../companion-controller.ts';
1
+ import type { CompanionActions } from '../view-actions.ts';
2
2
  import type { PendingQuestion } from '../../topic.ts';
3
3
  export interface QuestionCardProps {
4
- readonly companion: CompanionFace;
4
+ readonly companion: CompanionActions;
5
5
  readonly pending: PendingQuestion;
6
6
  }
7
7
  /** Collect one standard DSH ask_user_question answer batch inside the private Topic. */
@@ -1,8 +1,12 @@
1
- import type { CompanionFace } from '../companion-controller.ts';
2
- import type { CiteBus } from '../types.ts';
1
+ import type { SnapshotSelectorHook } from '@deepseek-ai/dsh-client-store';
2
+ import type { CiteOverlaySnapshot } from '../types.ts';
3
+ import type { CompanionSnapshot } from '../companion-controller.ts';
4
+ import type { CompanionActions, OverlayActions } from '../view-actions.ts';
3
5
  export interface SelectionMenuProps {
4
- readonly bus: CiteBus;
5
- readonly companion: CompanionFace;
6
+ readonly useCompanion: SnapshotSelectorHook<CompanionSnapshot>;
7
+ readonly useOverlay: SnapshotSelectorHook<CiteOverlaySnapshot>;
8
+ readonly bus: OverlayActions;
9
+ readonly companion: CompanionActions;
6
10
  readonly openPanel: () => void;
7
11
  }
8
12
  /**
@@ -10,4 +14,4 @@ export interface SelectionMenuProps {
10
14
  * @param props - shared selection state and Topic actions.
11
15
  * @returns the contextual creation popover and companion launcher.
12
16
  */
13
- export declare function SelectionMenu({ bus, companion, openPanel }: SelectionMenuProps): import("react").JSX.Element;
17
+ export declare function SelectionMenu({ useCompanion, useOverlay, bus, companion, openPanel }: SelectionMenuProps): import("react").JSX.Element;
@@ -1,11 +1,14 @@
1
- import { type UpdateController } from '../update-controller.ts';
1
+ import type { SnapshotSelectorHook } from '@deepseek-ai/dsh-client-store';
2
+ import type { UpdateNoticeSnapshot } from '../update-controller.ts';
3
+ import type { UpdateActions } from '../view-actions.ts';
2
4
  /** Injected owner of the root-scoped update state. */
3
5
  export interface UpdateNoticeProps {
4
- readonly updateController: UpdateController;
6
+ readonly useUpdate: SnapshotSelectorHook<UpdateNoticeSnapshot>;
7
+ readonly updateController: UpdateActions;
5
8
  }
6
9
  /**
7
10
  * Render the non-modal Web update notice in the frame-wide overlay.
8
11
  * @param props - root-scoped update actions and observable state.
9
12
  * @returns the available-version card, or no surface while current or suppressed.
10
13
  */
11
- export declare function UpdateNotice({ updateController }: UpdateNoticeProps): import("react").JSX.Element | null;
14
+ export declare function UpdateNotice({ useUpdate, updateController }: UpdateNoticeProps): import("react").JSX.Element | null;
@@ -0,0 +1,6 @@
1
+ /** Chinese presentation copy owned by CiteCiter, including shared primitive chrome. */
2
+ import type { JsonTreeLabels, MarkdownLabels } from '@deepseek-ai/dsh-client-ui-primitives';
3
+ /** Localized labels supplied to the Cordis-free Markdown renderer. */
4
+ export declare const markdownLabels: MarkdownLabels;
5
+ /** Localized labels supplied to the Cordis-free JSON inspector. */
6
+ export declare const jsonTreeLabels: JsonTreeLabels;
@@ -0,0 +1,23 @@
1
+ /** Space allocation for the learning panel inside the host content viewport. */
2
+ export interface DockViewport {
3
+ readonly width: number;
4
+ readonly height: number;
5
+ readonly sidebar: number;
6
+ readonly details: number;
7
+ readonly caption: number;
8
+ readonly percent: number;
9
+ }
10
+ /** The host keeps its conversation and details visible in both arrangements. */
11
+ export interface DockGeometry {
12
+ readonly mode: 'columns' | 'rows';
13
+ readonly width: number;
14
+ readonly height: number;
15
+ readonly top: number;
16
+ }
17
+ /**
18
+ * Reserve a separate column, or a bottom row when two readable columns cannot fit.
19
+ * CSS pixels already account for browser zoom and Windows display scaling.
20
+ * @param viewport - measured host dimensions and the saved width preference.
21
+ * @returns panel dimensions within the host, excluding its native caption.
22
+ */
23
+ export declare function resolveDockGeometry(viewport: DockViewport): DockGeometry;
@@ -4,11 +4,12 @@
4
4
  * Entries run in registration order; the first claim wins and is allowed to
5
5
  * prevent the native context menu.
6
6
  */
7
- import type { ISessions, SessionId } from '@deepseek-ai/dsh-client-runtime/client';
7
+ import type { SessionId } from '@deepseek-ai/dsh-session/types';
8
+ import type { ChatSnapshot } from '@deepseek-ai/dsh-client-ui-chat/client';
8
9
  import type { CiteSelection } from './types.ts';
9
10
  /** Live browser facts an entry needs to resolve one selection. */
10
11
  export interface CiteCiterEntryContext {
11
- readonly sessions: ISessions;
12
+ readonly readChat: (sessionId: SessionId) => ChatSnapshot | undefined;
12
13
  readonly sourceSessionId: SessionId;
13
14
  }
14
15
  /** One Citer entry point: probe, capture, and claim a selection from the DOM. */
@@ -0,0 +1,18 @@
1
+ /** Isolated, disposable layout adapter for DSH rc.1 and Desktop 2.0.5 frames. */
2
+ import { type RefObject } from 'react';
3
+ import { type DockGeometry } from './dock-geometry.ts';
4
+ /**
5
+ * Locate the frame owning the public shell.overlay contribution.
6
+ * @param panel - mounted learning panel.
7
+ * @returns its immediate frame, or null before mounting.
8
+ */
9
+ export declare function findContainingFrame(panel: HTMLElement | null): HTMLElement | null;
10
+ /**
11
+ * Reserve host space without rewriting the host's saved columns or hiding details.
12
+ * Unknown frame structures receive no DOM changes. All owned styles disappear on close.
13
+ * @param panel - mounted panel reference.
14
+ * @param open - whether space should be reserved.
15
+ * @param percent - user's preferred fraction of the content viewport.
16
+ * @returns measured panel placement; null when the host frame is unsupported.
17
+ */
18
+ export declare function useHostDock(panel: RefObject<HTMLElement | null>, open: boolean, percent: number): DockGeometry | null;
@@ -29,5 +29,5 @@ type RemoteRequest = (request: CiteCiterRequest, signal: AbortSignal) => Promise
29
29
  /** Initial Reader snapshot. */
30
30
  export declare function createInitialReaderSnapshot(): ReaderSnapshot;
31
31
  /** Bind the Reader store to the CiteCiter Remote and the companion Topic creator. */
32
- export declare function createReaderController(request: RemoteRequest, companion: CompanionFace, store?: import("@deepseek-ai/dsh-client-runtime/client").SnapshotStore<ReaderSnapshot>): ReaderFace;
32
+ export declare function createReaderController(request: RemoteRequest, companion: CompanionFace, store?: import("@deepseek-ai/dsh-client-store").SnapshotStore<ReaderSnapshot>): ReaderFace;
33
33
  export {};
@@ -1,4 +1,4 @@
1
- import type { SessionId } from '@deepseek-ai/dsh-client-runtime/client';
1
+ import type { SessionId } from '@deepseek-ai/dsh-session/types';
2
2
  import type { CiteSelection } from './types.ts';
3
3
  /**
4
4
  * Resolve the current DOM selection into a CiteSelection.
@@ -1,4 +1,4 @@
1
- import type { SessionId } from '@deepseek-ai/dsh-client-runtime/client';
1
+ import type { SessionId } from '@deepseek-ai/dsh-session/types';
2
2
  import type { ToolEvidenceProjection } from '../evidence-text.ts';
3
3
  /** One right-click selection inside a rendered assistant model call. */
4
4
  export interface AssistantCiteSelection {
@@ -1,10 +1,12 @@
1
- import { type SettingsScope, type SnapshotStore } from '@deepseek-ai/dsh-client-runtime/client';
1
+ import type { SettingsScope } from '@deepseek-ai/dsh-client-ui-settings/client';
2
+ import type { SnapshotStore } from '@deepseek-ai/dsh-client-store';
2
3
  import type { CiteCiterSettings } from '../topic.ts';
3
4
  type UpdateStorage = Pick<Storage, 'getItem' | 'setItem' | 'removeItem'>;
4
5
  /** One newer package version returned by the validated Host check. */
5
6
  export interface AvailableUpdate {
6
7
  readonly currentVersion: string;
7
8
  readonly latestVersion: string;
9
+ readonly profile?: string;
8
10
  }
9
11
  /** Observable state shared by the update card and settings page. */
10
12
  export interface UpdateNoticeSnapshot {
@@ -52,6 +54,6 @@ export declare function createUpdateBrowserEnvironment(): UpdateBrowserEnvironme
52
54
  * @returns the root-scoped update controller.
53
55
  */
54
56
  export declare function createUpdateController(settings: SettingsScope<CiteCiterSettings>, checkUpdate: CheckUpdate, store: SnapshotStore<UpdateNoticeSnapshot>, environment?: UpdateBrowserEnvironment, reportCheckError?: (error: unknown) => void): UpdateController;
55
- /** @param version - validated latest package version. @returns the command shown and copied by the Web notice. */
56
- export declare function citeCiterUpdateCommand(version: string): string;
57
+ /** @param version - validated latest package version. @param profile - active Desktop profile, or Web default. @returns the command shown and copied by the notice. */
58
+ export declare function citeCiterUpdateCommand(version: string, profile?: string): string;
57
59
  export {};
@@ -0,0 +1,26 @@
1
+ /** Plain UI callbacks; subscriptions and disposal remain with the Client plugin. */
2
+ import type { CompanionFace } from './companion-controller.ts';
3
+ import type { ReaderFace } from './reader-controller.ts';
4
+ import type { SettingsDocumentController } from './settings-document.ts';
5
+ import type { CiteBus } from './types.ts';
6
+ import type { UpdateController } from './update-controller.ts';
7
+ /** Callbacks the Topic view may invoke. */
8
+ export type CompanionActions = Omit<CompanionFace, 'getSnapshot' | 'subscribe' | 'dispose'>;
9
+ /** Callbacks the document view may invoke. */
10
+ export type ReaderActions = Omit<ReaderFace, 'getSnapshot' | 'subscribe' | 'dispose'>;
11
+ /** Callbacks the settings view may invoke. */
12
+ export type SettingsDocumentActions = Omit<SettingsDocumentController, 'getSnapshot' | 'subscribe' | 'dispose'>;
13
+ /** Callbacks the update view may invoke. */
14
+ export type UpdateActions = Omit<UpdateController, 'getSnapshot' | 'subscribe' | 'dispose'>;
15
+ /** Overlay events used by rendered components. */
16
+ export type OverlayActions = Pick<CiteBus, 'setMenuSelection' | 'setPanelOpen' | 'requestBoardCitation' | 'clearBoardCitation'>;
17
+ /**
18
+ * Remove lifecycle and subscription methods from a plain controller's view props.
19
+ * @param controller - Client-owned controller with arrow-function callbacks.
20
+ * @returns callbacks separate from the observable supplied to inject.hooks.
21
+ */
22
+ export declare function viewActions<T extends {
23
+ getSnapshot(): unknown;
24
+ subscribe(listener: () => void): () => void;
25
+ dispose(): Promise<void>;
26
+ }>(controller: T): Omit<T, 'getSnapshot' | 'subscribe' | 'dispose'>;
@@ -9,7 +9,7 @@ export declare const name = "@kirkchinese/dsh-citeciter";
9
9
  /** Services required by the private Topic runtime. */
10
10
  export declare const inject: readonly ["llm", "sessionQuery", "subprocess"];
11
11
  /** Host settings identity shared with the browser settings scope. */
12
- export declare const CITECITER_SETTINGS_NS: import("@deepseek-ai/dsh-settings").SettingsNamespace;
12
+ export declare const CITECITER_SETTINGS_NS: "citeciter";
13
13
  /** Native settings schema for new Topics and the companion panel. */
14
14
  export declare const CITECITER_SETTINGS_SCHEMA: z<object>;
15
15
  /** Root-scoped Remote service owning one isolated DSH runtime. */