@pactor-app/chat 1.17.0 → 1.18.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.
package/README.md CHANGED
@@ -136,7 +136,7 @@ body:
136
136
  ```
137
137
 
138
138
  - **菜单**:`menu: ChatMenuItem[]`(`key / label / icon? / badge? / disabled? / group?`)驱动内建侧栏;`icon` 为字符串名,映射内置 lucide 子集(plus / chat / history / settings / star / search / user / folder),未知名渲染占位圆点不抛错;`group` 渲染分组标题行;`activeMenuKey` 为受控 prop,典型用法是 `${state.x}` 绑定 + `events.onMenuSelect` 调 `setState` 闭环;disabled 项不触发 `onMenuSelect`。
139
- - **Header 三层**:`title` 标量 → `headerExtra?: DslNode | ReactNode`(标题右侧槽)→ `header?: DslNode | ReactNode`(整体替换内建 header);`showHeader: false` 关闭。header 渲染为全宽容器(产物面板 host / with-header 包裹层)的直接子级,不随对话列限宽——产物面板调宽时保持通栏。DslNode 槽仅在页面运行时(DslRenderer)上下文内经 `useRenderer().renderChildren` 渲染;纯 React 场景传 ReactNode,误传 DslNode 时告警并跳过(不抛错)。
139
+ - **Header 三层**:`title` 标量 → `headerExtra?: DslNode | ReactNode`(标题右侧槽)→ `header?: DslNode | ReactNode`(整体替换内建 header);`showHeader: false` 关闭。header 收进产物面板 host 的 `__main` 左列(header + 对话区纵向堆叠):面板打开时与对话区同宽、不覆盖面板上方(面板独占右列全高),面板关闭时随 `__main` 通栏;均不随对话列限宽。DslNode 槽仅在页面运行时(DslRenderer)上下文内经 `useRenderer().renderChildren` 渲染;纯 React 场景传 ReactNode,误传 DslNode 时告警并跳过(不抛错)。
140
140
  - **侧栏槽**:`sidebar?: DslNode | ReactNode` 提供时整体替代内建菜单侧栏(仍以 AppShell 承载)。
141
141
  - **产出物面板**:`artifact` / `panelOpen` 受控 props(典型 `${state.x}` 绑定),事件 `onArtifact`(part 就绪)/ `onOpenArtifact`(卡片打开)/ `onOpenArtifactList`(卡片区"查看所有产物",典型接法 `setState panelOpen=true`,面板自动定位产物目录视图)/ `onPanelClose` / `onSelectArtifact`(下拉 / 目录列表切换,典型接法 `setState artifact=${event.artifact}`);多产物清单由组合层自动从消息流归集,无需 DSL 接线;自定义预览经 `ChatServicesProvider` 注入 `artifactViewers`(函数不进 DSL)。详见上文 `<ArtifactPanel>` 与 `examples/chat/src/chat.page.yaml`。
142
142
  - **React 直连**:`<ChatServicesProvider>` + `<Chat>` 同样可直接作为 React 组件使用(events 即普通函数 props:`onSend?(text)` / `onMenuSelect?(key, item)`)。`createChatWorkspace` 工厂保留为兼容路径,内部已改为 provider + 同一组合逻辑(`ChatComposition`),行为不变。
package/dist/index.cjs CHANGED
@@ -2008,14 +2008,14 @@ function ArtifactPanel({
2008
2008
  if (!panel) {
2009
2009
  return;
2010
2010
  }
2011
- const hostRect = panel.parentElement?.getBoundingClientRect();
2012
- const hostWidth = hostRect !== void 0 && hostRect.width > 0 ? hostRect.width : window.innerWidth;
2013
- const maxWidth = hostWidth * 2 / 3;
2014
2011
  const startWidth = panel.getBoundingClientRect().width;
2015
2012
  const startX = event.clientX;
2016
2013
  const prevUserSelect = document.body.style.userSelect;
2017
2014
  document.body.style.userSelect = "none";
2018
2015
  const onMove = (moveEvent) => {
2016
+ const hostRect = panel.parentElement?.getBoundingClientRect();
2017
+ const hostWidth = hostRect !== void 0 && hostRect.width > 0 ? hostRect.width : window.innerWidth;
2018
+ const maxWidth = hostWidth * 2 / 3;
2019
2019
  const next = startWidth + (startX - moveEvent.clientX);
2020
2020
  setWidth(Math.round(Math.min(Math.max(next, 480), maxWidth)));
2021
2021
  };
@@ -4510,38 +4510,38 @@ function ChatComposition({
4510
4510
  main
4511
4511
  ] }) : main;
4512
4512
  }
4513
- return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "pactor-chat-inspector-host", children: [
4514
- workspaceHeader,
4515
- /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "pactor-chat-inspector-host__row", children: [
4516
- main,
4517
- effectivePanelOpen ? /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(import_jsx_runtime18.Fragment, { children: [
4518
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
4519
- "div",
4520
- {
4521
- className: "pactor-chat-inspector__scrim",
4522
- "aria-hidden": true,
4523
- onClick: handlePanelClose
4524
- }
4525
- ),
4526
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
4527
- ArtifactPanel,
4528
- {
4529
- artifact: effectiveArtifact,
4530
- artifacts: effectiveArtifacts,
4531
- activeArtifactId: effectiveArtifact?.id,
4532
- onSelectArtifact: handleSelectArtifact,
4533
- inspector,
4534
- onClose: handlePanelClose,
4535
- safeRegistry: services.safeRegistry,
4536
- user: services.user,
4537
- artifactViewers: services.artifactViewers,
4538
- viewRequest: listViewRequest,
4539
- onViewRequestConsumed: () => setListViewRequest(null)
4540
- }
4541
- )
4542
- ] }) : null
4543
- ] })
4544
- ] });
4513
+ return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { className: "pactor-chat-inspector-host", children: /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "pactor-chat-inspector-host__row", children: [
4514
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "pactor-chat-inspector-host__main", children: [
4515
+ workspaceHeader,
4516
+ main
4517
+ ] }),
4518
+ effectivePanelOpen ? /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(import_jsx_runtime18.Fragment, { children: [
4519
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
4520
+ "div",
4521
+ {
4522
+ className: "pactor-chat-inspector__scrim",
4523
+ "aria-hidden": true,
4524
+ onClick: handlePanelClose
4525
+ }
4526
+ ),
4527
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
4528
+ ArtifactPanel,
4529
+ {
4530
+ artifact: effectiveArtifact,
4531
+ artifacts: effectiveArtifacts,
4532
+ activeArtifactId: effectiveArtifact?.id,
4533
+ onSelectArtifact: handleSelectArtifact,
4534
+ inspector,
4535
+ onClose: handlePanelClose,
4536
+ safeRegistry: services.safeRegistry,
4537
+ user: services.user,
4538
+ artifactViewers: services.artifactViewers,
4539
+ viewRequest: listViewRequest,
4540
+ onViewRequestConsumed: () => setListViewRequest(null)
4541
+ }
4542
+ )
4543
+ ] }) : null
4544
+ ] }) });
4545
4545
  }
4546
4546
 
4547
4547
  // src/chat-services.tsx
package/dist/index.js CHANGED
@@ -1943,14 +1943,14 @@ function ArtifactPanel({
1943
1943
  if (!panel) {
1944
1944
  return;
1945
1945
  }
1946
- const hostRect = panel.parentElement?.getBoundingClientRect();
1947
- const hostWidth = hostRect !== void 0 && hostRect.width > 0 ? hostRect.width : window.innerWidth;
1948
- const maxWidth = hostWidth * 2 / 3;
1949
1946
  const startWidth = panel.getBoundingClientRect().width;
1950
1947
  const startX = event.clientX;
1951
1948
  const prevUserSelect = document.body.style.userSelect;
1952
1949
  document.body.style.userSelect = "none";
1953
1950
  const onMove = (moveEvent) => {
1951
+ const hostRect = panel.parentElement?.getBoundingClientRect();
1952
+ const hostWidth = hostRect !== void 0 && hostRect.width > 0 ? hostRect.width : window.innerWidth;
1953
+ const maxWidth = hostWidth * 2 / 3;
1954
1954
  const next = startWidth + (startX - moveEvent.clientX);
1955
1955
  setWidth(Math.round(Math.min(Math.max(next, 480), maxWidth)));
1956
1956
  };
@@ -4450,38 +4450,38 @@ function ChatComposition({
4450
4450
  main
4451
4451
  ] }) : main;
4452
4452
  }
4453
- return /* @__PURE__ */ jsxs14("div", { className: "pactor-chat-inspector-host", children: [
4454
- workspaceHeader,
4455
- /* @__PURE__ */ jsxs14("div", { className: "pactor-chat-inspector-host__row", children: [
4456
- main,
4457
- effectivePanelOpen ? /* @__PURE__ */ jsxs14(Fragment9, { children: [
4458
- /* @__PURE__ */ jsx18(
4459
- "div",
4460
- {
4461
- className: "pactor-chat-inspector__scrim",
4462
- "aria-hidden": true,
4463
- onClick: handlePanelClose
4464
- }
4465
- ),
4466
- /* @__PURE__ */ jsx18(
4467
- ArtifactPanel,
4468
- {
4469
- artifact: effectiveArtifact,
4470
- artifacts: effectiveArtifacts,
4471
- activeArtifactId: effectiveArtifact?.id,
4472
- onSelectArtifact: handleSelectArtifact,
4473
- inspector,
4474
- onClose: handlePanelClose,
4475
- safeRegistry: services.safeRegistry,
4476
- user: services.user,
4477
- artifactViewers: services.artifactViewers,
4478
- viewRequest: listViewRequest,
4479
- onViewRequestConsumed: () => setListViewRequest(null)
4480
- }
4481
- )
4482
- ] }) : null
4483
- ] })
4484
- ] });
4453
+ return /* @__PURE__ */ jsx18("div", { className: "pactor-chat-inspector-host", children: /* @__PURE__ */ jsxs14("div", { className: "pactor-chat-inspector-host__row", children: [
4454
+ /* @__PURE__ */ jsxs14("div", { className: "pactor-chat-inspector-host__main", children: [
4455
+ workspaceHeader,
4456
+ main
4457
+ ] }),
4458
+ effectivePanelOpen ? /* @__PURE__ */ jsxs14(Fragment9, { children: [
4459
+ /* @__PURE__ */ jsx18(
4460
+ "div",
4461
+ {
4462
+ className: "pactor-chat-inspector__scrim",
4463
+ "aria-hidden": true,
4464
+ onClick: handlePanelClose
4465
+ }
4466
+ ),
4467
+ /* @__PURE__ */ jsx18(
4468
+ ArtifactPanel,
4469
+ {
4470
+ artifact: effectiveArtifact,
4471
+ artifacts: effectiveArtifacts,
4472
+ activeArtifactId: effectiveArtifact?.id,
4473
+ onSelectArtifact: handleSelectArtifact,
4474
+ inspector,
4475
+ onClose: handlePanelClose,
4476
+ safeRegistry: services.safeRegistry,
4477
+ user: services.user,
4478
+ artifactViewers: services.artifactViewers,
4479
+ viewRequest: listViewRequest,
4480
+ onViewRequestConsumed: () => setListViewRequest(null)
4481
+ }
4482
+ )
4483
+ ] }) : null
4484
+ ] }) });
4485
4485
  }
4486
4486
 
4487
4487
  // src/chat-services.tsx
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pactor-app/chat",
3
- "version": "1.17.0",
3
+ "version": "1.18.0",
4
4
  "description": "Pactor chat: AI message rendering protocol (message model, streaming reducer, safe registry, capability action) and chat runtime view (ChatView / MessageBubble / PartRenderer / Composer / chat layout)",
5
5
  "keywords": [
6
6
  "pactor",
@@ -49,11 +49,11 @@
49
49
  "access": "public"
50
50
  },
51
51
  "dependencies": {
52
- "@pactor-app/core": "1.17.0",
53
- "@pactor-app/runtime": "1.17.0",
54
- "@pactor-app/markdown": "1.17.0",
55
- "@pactor-app/permission": "1.17.0",
56
- "@pactor-app/ui": "1.17.0"
52
+ "@pactor-app/core": "1.18.0",
53
+ "@pactor-app/permission": "1.18.0",
54
+ "@pactor-app/markdown": "1.18.0",
55
+ "@pactor-app/runtime": "1.18.0",
56
+ "@pactor-app/ui": "1.18.0"
57
57
  },
58
58
  "peerDependencies": {
59
59
  "react": ">=18"
package/styles.css CHANGED
@@ -221,7 +221,8 @@
221
221
  /* ------------------------------------------------------------
222
222
  * ChatWorkspace(spec: chat-dsl-page):createChatWorkspace 工厂
223
223
  * 返回组件的外层容器 = 对话列(ChatView);工作区头部(header)
224
- * 上移为全宽容器的直接子级,不随对话列限宽。
224
+ * 收进面板 host 的 __main 左列——面板打开时与对话区同宽(不覆盖
225
+ * 面板上方),面板关闭时随 __main 通栏;不随对话列限宽。
225
226
  * ------------------------------------------------------------ */
226
227
 
227
228
  .pactor-chat-workspace {
@@ -357,9 +358,9 @@
357
358
  * 面板关闭 / 未配置时不渲染 DOM(组合层保证)。
358
359
  * ------------------------------------------------------------ */
359
360
 
360
- /* 面板打开时的容器:header 通栏(host 直接子级)+ 行内容器
361
- * (workspace / AppShell 与面板 flex 并排);host 在 shell content
362
- * 内撑满剩余高度与宽度 */
361
+ /* 面板打开时的容器:行内容器 __row 承载左右两列——__main 左列
362
+ * (header + 对话区,同宽;header 不覆盖面板上方)与面板右列
363
+ * (独占全高);host 在 shell content 内撑满剩余高度与宽度 */
363
364
  .pactor-chat-inspector-host {
364
365
  display: flex;
365
366
  flex-direction: column;
@@ -370,8 +371,8 @@
370
371
  background: var(--pactor-chat-bg);
371
372
  }
372
373
 
373
- /* host 行内容器:对话列与面板的 flex 行(gutter 契约挂在行上——
374
- * host padding 会同时作用于通栏 header) */
374
+ /* host 行内容器:__main 左列与面板的 flex 行(gutter 契约挂在行上——
375
+ * __main 内的 header / 对话列共享行 padding 的左 gutter) */
375
376
  .pactor-chat-inspector-host__row {
376
377
  display: flex;
377
378
  flex: 1;
@@ -379,15 +380,20 @@
379
380
  min-height: 0;
380
381
  }
381
382
 
382
- /* 面板打开时行内直子:AppShell 填满剩余空间;workspace 只缩不伸,
383
- * 宽度受 --pactor-chat-content-width 限宽,margin auto 在剩余空间内居中 */
384
- .pactor-chat-inspector-host__row > .pactor-chat-shell {
383
+ /* __main 左列:header + 主区(AppShell / workspace)纵向堆叠,
384
+ * 宽度 = 行宽减去面板宽(面板打开时 header 与对话区同宽) */
385
+ .pactor-chat-inspector-host__main {
386
+ display: flex;
387
+ flex-direction: column;
385
388
  flex: 1;
386
389
  min-width: 0;
390
+ min-height: 0;
387
391
  }
388
392
 
389
- .pactor-chat-inspector-host__row > .pactor-chat-workspace {
390
- flex: 0 1 auto;
393
+ .pactor-chat-inspector-host__main > .pactor-chat-shell,
394
+ .pactor-chat-inspector-host__main > .pactor-chat-workspace {
395
+ flex: 1;
396
+ min-height: 0;
391
397
  min-width: 0;
392
398
  }
393
399
 
@@ -408,8 +414,11 @@
408
414
  position: relative;
409
415
  display: flex;
410
416
  flex-direction: column;
411
- /* 默认宽对齐对话列;上限 host 宽 2/3(与拖拽夹取一致),下限 min-width 令牌 */
417
+ /* 默认宽对齐对话列;上限 host 宽 2/3(与拖拽夹取一致),下限 min-width 令牌。
418
+ * max-width 是拖拽 inline 宽度的硬兜底:inline width 不能覆盖 max-width,
419
+ * 拖拽夹取偏差 / 拖拽后窗口尺寸变化时面板也不会突破 2/3 上限 */
412
420
  width: min(var(--pactor-chat-inspector-width), calc(100% * 2 / 3));
421
+ max-width: calc(100% * 2 / 3);
413
422
  min-width: var(--pactor-chat-inspector-min-width);
414
423
  flex-shrink: 0;
415
424
  border-left: 1px solid var(--pactor-chat-border);
@@ -627,8 +636,10 @@
627
636
  right: 0;
628
637
  z-index: 50;
629
638
  box-shadow: var(--pactor-chat-shadow-composer);
630
- /* 抽屉形态:宽度不超出视口,下限令牌不适用 */
639
+ /* 抽屉形态:宽度不超出视口,下限令牌不适用;
640
+ * max-width 兜底拖拽残留的 inline 宽度(桌面拖拽后切窄屏) */
631
641
  width: min(var(--pactor-chat-inspector-width), 92vw);
642
+ max-width: 92vw;
632
643
  min-width: 0;
633
644
  }
634
645
 
@@ -889,7 +900,7 @@
889
900
  display: flex;
890
901
  flex-direction: column;
891
902
  gap: 16px;
892
- padding: 24px 2px 4px;
903
+ padding: 24px 2px;
893
904
  scrollbar-width: thin;
894
905
  scrollbar-color: var(--pactor-chat-border) transparent;
895
906
  -webkit-mask-image: linear-gradient(
@@ -1065,8 +1076,6 @@
1065
1076
  .pactor-chat-message__actions {
1066
1077
  display: flex;
1067
1078
  gap: 4px;
1068
-
1069
- opacity: 0;
1070
1079
  transition: opacity 0.15s ease;
1071
1080
  }
1072
1081
 
@@ -1090,7 +1099,6 @@
1090
1099
  .pactor-chat-message__time {
1091
1100
  flex-shrink: 0;
1092
1101
  color: var(--pactor-chat-muted-fg);
1093
- font-size: 11px;
1094
1102
  line-height: 18px;
1095
1103
  }
1096
1104