@agimon-ai/doompi-author 0.0.1-alpha.40 → 0.0.1-alpha.41

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/README.md CHANGED
@@ -12,6 +12,7 @@ Author is a session-scoped minor mode. Its three tools remain registered for the
12
12
 
13
13
  Catalog tokens rotate whenever capabilities change. Document-backed tools remain targetable from the main conversation while the canvas is open; live viewport grid operations require a visible tab. Closed canvases can be reopened by path and alias. Viewport document content is untrusted data, never agent instructions.
14
14
 
15
+ Unsent annotations belong to their document and leave the canvas once a send is accepted; the dock's request log keeps the request for the open document. Messages typed in an Author file tab carry `Author document: <path> (canvas <alias>)` as referenced context. Slash commands are sent unchanged.
15
16
  The package declares session API, cockpit client, and web hub entries. Each canvas has an isolated ownership lease and catalog token; stale bindings and cross-canvas tokens are rejected. Without the host session API socket and token, catalog operations fail as unavailable.
16
17
 
17
18
  ## Public API
@@ -2108,6 +2108,8 @@ function AuthorPanel({ sessionId, activeMinorModes, submitCapture, statuses, ren
2108
2108
  const workspace = useStore(authorWorkspace.store, (state) => sessionId === null ? void 0 : state.sessions[sessionId]);
2109
2109
  const grid = useStore(authorGrid.store, (state) => sessionId === null ? void 0 : state.sessions[sessionId]);
2110
2110
  const focused = documents.find((document) => document.path === workspace?.focusedDocument?.path);
2111
+ const focusedPath = workspace?.focusedDocument?.path;
2112
+ const requests = (workspace?.requests ?? []).filter((request) => focusedPath === void 0 || request.documentPath === focusedPath);
2111
2113
  const activity = sessionId === null ? null : renderSessionActivity?.() ?? null;
2112
2114
  if (!activeMinorModes?.includes("author")) return null;
2113
2115
  return /* @__PURE__ */ jsxs("section", {
@@ -2161,7 +2163,7 @@ function AuthorPanel({ sessionId, activeMinorModes, submitCapture, statuses, ren
2161
2163
  }, focused.path)
2162
2164
  })
2163
2165
  ] }) : null,
2164
- /* @__PURE__ */ jsx(AuthorRequestLog, { requests: workspace?.requests ?? [] })
2166
+ /* @__PURE__ */ jsx(AuthorRequestLog, { requests })
2165
2167
  ]
2166
2168
  })
2167
2169
  }), activity === null ? null : /* @__PURE__ */ jsx("footer", {
@@ -2704,7 +2706,7 @@ function mutationTool(sessionId, path, kind) {
2704
2706
  execute: async (input, signal) => {
2705
2707
  const value = inputRecord(input);
2706
2708
  const regionId = requiredString(value, "regionId");
2707
- const request = authorSessionWorkspace(sessionId).requests.find((candidate) => (candidate.pendingRegions ?? candidate.regions).some((item) => item.id === regionId) && candidate.status === "REQUESTED");
2709
+ const request = authorSessionWorkspace(sessionId).requests.find((candidate) => candidate.documentPath === path && candidate.status === "REQUESTED" && (candidate.pendingRegions ?? candidate.regions).some((item) => item.id === regionId));
2708
2710
  if (request !== void 0) updateAuthorRequest(sessionId, request.id, (current) => ({
2709
2711
  ...current,
2710
2712
  status: "CHANGING",
@@ -3880,17 +3882,12 @@ function tabId(path) {
3880
3882
  for (const char of normalizeAuthorPath(path)) hash = Math.imul(hash ^ char.charCodeAt(0), 16777619);
3881
3883
  return `author-file-${(hash >>> 0).toString(36)}`;
3882
3884
  }
3885
+ /** Unsent annotations only. Sent ones live in the request log, not on the canvas. */
3883
3886
  function displayedAuthorRegions(workspace) {
3884
- const draftRegions = workspace?.regions ?? [];
3885
- if (draftRegions.length > 0) return draftRegions.map((region, index) => ({
3887
+ return (workspace?.regions ?? []).map((region, index) => ({
3886
3888
  ordinal: index + 1,
3887
3889
  region
3888
3890
  }));
3889
- const activeRequest = workspace?.requests.slice().reverse().find((request) => request.status === "REQUESTED" || request.status === "CHANGING");
3890
- return (activeRequest?.pendingRegions ?? []).map((region) => ({
3891
- ordinal: Math.max(1, (activeRequest?.regions.findIndex((original) => original.id === region.id) ?? 0) + 1),
3892
- region
3893
- }));
3894
3891
  }
3895
3892
  function AuthorDocumentPanel(props) {
3896
3893
  if (!props.activeMinorModes?.includes("author")) {
@@ -3983,7 +3980,8 @@ function ActiveAuthorDocumentPanel(props) {
3983
3980
  }
3984
3981
  };
3985
3982
  const gridVisible = autonomousVoiceGridVisible(statuses);
3986
- const displayedRegions = displayedAuthorRegions(workspace);
3983
+ const focusedWorkspace = workspace?.focusedDocument?.path === document.path ? workspace : void 0;
3984
+ const displayedRegions = displayedAuthorRegions(focusedWorkspace);
3987
3985
  const displayedPreviewAnnotations = displayedRegions.flatMap(({ ordinal, region }) => {
3988
3986
  if (region.anchor.kind === "story-preview-rect") return [{
3989
3987
  ordinal,
@@ -4014,7 +4012,7 @@ function ActiveAuthorDocumentPanel(props) {
4014
4012
  document,
4015
4013
  activeTool,
4016
4014
  displayedRegions,
4017
- pendingCandidate: workspace?.candidate !== void 0,
4015
+ pendingCandidate: focusedWorkspace?.candidate !== void 0,
4018
4016
  seekRequest: workspace?.videoSeekRequest
4019
4017
  }, document.path);
4020
4018
  return /* @__PURE__ */ jsxs("section", {
@@ -4092,7 +4090,7 @@ function ActiveAuthorDocumentPanel(props) {
4092
4090
  source: previewSource,
4093
4091
  activeTool: activeTool === "crop" ? "select" : activeTool,
4094
4092
  displayedAnnotations: displayedPreviewAnnotations,
4095
- pendingCandidate: workspace?.candidate !== void 0,
4093
+ pendingCandidate: focusedWorkspace?.candidate !== void 0,
4096
4094
  onAnnotationCandidate: (candidate) => {
4097
4095
  setAuthorStoryPreview(sessionId, document.path, candidate.preview);
4098
4096
  setAuthorRegionCandidate(sessionId, {
@@ -4122,7 +4120,7 @@ function ActiveAuthorDocumentPanel(props) {
4122
4120
  visible: gridVisible
4123
4121
  })]
4124
4122
  }),
4125
- workspace !== void 0 && [
4123
+ focusedWorkspace !== void 0 && [
4126
4124
  "image",
4127
4125
  "pdf",
4128
4126
  "video",
@@ -4132,7 +4130,7 @@ function ActiveAuthorDocumentPanel(props) {
4132
4130
  children: /* @__PURE__ */ jsx(AuthorFeedbackControls, {
4133
4131
  sessionId,
4134
4132
  document,
4135
- workspace,
4133
+ workspace: focusedWorkspace,
4136
4134
  submitCapture: props.submitCapture
4137
4135
  })
4138
4136
  }) : null
@@ -4145,6 +4143,19 @@ function authorFileTab(path, preferredAlias) {
4145
4143
  id: tabId(normalized),
4146
4144
  label: preferredAlias === void 0 ? normalized.split("/").at(-1) ?? normalized : `${preferredAlias} · ${normalized.split("/").at(-1) ?? normalized}`,
4147
4145
  retainComposer: true,
4146
+ composerContext(sessionId) {
4147
+ const key = authorDocumentKey(sessionId, normalized);
4148
+ const documentPath = canvasPaths.state[key] ?? normalized;
4149
+ const alias = canvasAliases.state[key];
4150
+ const name = documentPath.split("/").at(-1) ?? documentPath;
4151
+ return {
4152
+ kind: "author-document",
4153
+ source: "author",
4154
+ id: documentPath,
4155
+ label: alias === void 0 ? name : `${alias} · ${name}`,
4156
+ content: `Author document: ${documentPath}${alias === void 0 ? "" : ` (canvas ${alias})`}`
4157
+ };
4158
+ },
4148
4159
  onOpen(sessionId) {
4149
4160
  const key = authorDocumentKey(sessionId, normalized);
4150
4161
  const controller = new AbortController();