pi-one-ui 0.1.1

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 (101) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +106 -0
  3. package/extensions/app/config/renderer.ts +452 -0
  4. package/extensions/app/config/shell.ts +2484 -0
  5. package/extensions/app/ownership.ts +18 -0
  6. package/extensions/app/panel.ts +533 -0
  7. package/extensions/app/presets.ts +36 -0
  8. package/extensions/features/agent-summary/core.ts +194 -0
  9. package/extensions/features/agent-summary/index.ts +37 -0
  10. package/extensions/features/compact-thinking.ts +1262 -0
  11. package/extensions/features/context.ts +857 -0
  12. package/extensions/features/reference/index.ts +643 -0
  13. package/extensions/features/reference/session.ts +278 -0
  14. package/extensions/features/reference/subagent.ts +218 -0
  15. package/extensions/features/shell/aliases.ts +28 -0
  16. package/extensions/features/shell/flush-docked-bash.ts +39 -0
  17. package/extensions/features/shell/startup-header.ts +357 -0
  18. package/extensions/features/shell/working-message.ts +226 -0
  19. package/extensions/index.ts +52 -0
  20. package/extensions/shell/accent-rail-editor.ts +112 -0
  21. package/extensions/shell/accent-rail-layout-patch.ts +530 -0
  22. package/extensions/shell/completion-menu.ts +186 -0
  23. package/extensions/shell/editor-metadata-format.ts +287 -0
  24. package/extensions/shell/editor-transfer.ts +73 -0
  25. package/extensions/shell/extension-status.ts +102 -0
  26. package/extensions/shell/footer-format.ts +388 -0
  27. package/extensions/shell/footer-layout.ts +144 -0
  28. package/extensions/shell/footer.ts +1035 -0
  29. package/extensions/shell/format.ts +577 -0
  30. package/extensions/shell/git.ts +434 -0
  31. package/extensions/shell/icons.ts +261 -0
  32. package/extensions/shell/index.ts +1659 -0
  33. package/extensions/shell/interaction-summary.ts +1194 -0
  34. package/extensions/shell/live-context.ts +82 -0
  35. package/extensions/shell/minimalist-editor.ts +548 -0
  36. package/extensions/shell/package-version.ts +675 -0
  37. package/extensions/shell/project-refresh.ts +130 -0
  38. package/extensions/shell/project-state.ts +60 -0
  39. package/extensions/shell/prototype-patch-registry.ts +183 -0
  40. package/extensions/shell/runtime.ts +915 -0
  41. package/extensions/shell/selector-border.ts +109 -0
  42. package/extensions/shell/session-lifecycle.ts +60 -0
  43. package/extensions/shell/settings-command.ts +2144 -0
  44. package/extensions/shell/settings-previews.ts +137 -0
  45. package/extensions/shell/state.ts +83 -0
  46. package/extensions/shell/style.ts +480 -0
  47. package/extensions/shell/telemetry.ts +90 -0
  48. package/extensions/shell/ui.ts +1326 -0
  49. package/extensions/shell/user-message-osc.ts +279 -0
  50. package/extensions/shell/user-message-styles.ts +266 -0
  51. package/extensions/shell/user-message.ts +226 -0
  52. package/extensions/shell/working-line-messages.ts +24 -0
  53. package/extensions/shell/working-line-spinners.ts +54 -0
  54. package/extensions/shell/working-line.ts +1603 -0
  55. package/extensions/tools/ansi-color.ts +44 -0
  56. package/extensions/tools/ansi-text.ts +52 -0
  57. package/extensions/tools/component-tree.ts +37 -0
  58. package/extensions/tools/format.ts +28 -0
  59. package/extensions/tools/fullscreen-detect.ts +11 -0
  60. package/extensions/tools/patch-keys.ts +158 -0
  61. package/extensions/tools/sgr-mouse.ts +59 -0
  62. package/extensions/tools/tool-loading-icon.ts +20 -0
  63. package/extensions/tools/tool-result-sanitize.ts +27 -0
  64. package/extensions/transcript/index.ts +65 -0
  65. package/extensions/transcript/renderer/compact-mode.ts +1443 -0
  66. package/extensions/transcript/renderer/default-mode.ts +735 -0
  67. package/extensions/transcript/renderer/index.ts +286 -0
  68. package/extensions/transcript/renderer/markdown-enhance.ts +325 -0
  69. package/extensions/transcript/renderer/mouse/hover.ts +175 -0
  70. package/extensions/transcript/renderer/mouse/interaction.ts +1016 -0
  71. package/extensions/transcript/renderer/mouse/layout.ts +207 -0
  72. package/extensions/transcript/renderer/mouse/packets.ts +96 -0
  73. package/extensions/transcript/renderer/mouse/scroll.ts +211 -0
  74. package/extensions/transcript/renderer/tool/diff/ATTRIBUTION.md +28 -0
  75. package/extensions/transcript/renderer/tool/diff/ansi-utils.ts +128 -0
  76. package/extensions/transcript/renderer/tool/diff/diff-component.ts +112 -0
  77. package/extensions/transcript/renderer/tool/diff/diff-edit-render.ts +255 -0
  78. package/extensions/transcript/renderer/tool/diff/diff-header.ts +184 -0
  79. package/extensions/transcript/renderer/tool/diff/diff-highlight.ts +131 -0
  80. package/extensions/transcript/renderer/tool/diff/diff-inline.ts +350 -0
  81. package/extensions/transcript/renderer/tool/diff/diff-layout.ts +870 -0
  82. package/extensions/transcript/renderer/tool/diff/diff-limits.ts +189 -0
  83. package/extensions/transcript/renderer/tool/diff/diff-palette.ts +436 -0
  84. package/extensions/transcript/renderer/tool/diff/diff-parse.ts +536 -0
  85. package/extensions/transcript/renderer/tool/diff/diff-presentation.ts +79 -0
  86. package/extensions/transcript/renderer/tool/diff/diff-renderer.ts +29 -0
  87. package/extensions/transcript/renderer/tool/diff/diff-text.ts +57 -0
  88. package/extensions/transcript/renderer/tool/diff/diff-write-render.ts +629 -0
  89. package/extensions/transcript/renderer/tool/diff/index.ts +147 -0
  90. package/extensions/transcript/renderer/tool/diff/line-width-safety.ts +100 -0
  91. package/extensions/transcript/renderer/tool/diff/shiki-highlight.ts +104 -0
  92. package/extensions/transcript/renderer/tool/diff/write-execution.ts +124 -0
  93. package/extensions/transcript/renderer/tool/grouping.ts +619 -0
  94. package/extensions/transcript/renderer/tool/message-display.ts +183 -0
  95. package/extensions/transcript/renderer/tool/names.ts +195 -0
  96. package/extensions/transcript/renderer/tool/result.ts +842 -0
  97. package/extensions/transcript/renderer/tool/show-more-hint.ts +42 -0
  98. package/extensions/transcript/renderer/transcript-refresh.ts +79 -0
  99. package/package.json +58 -0
  100. package/themes/cc-dark.json +91 -0
  101. package/themes/cc-light.json +91 -0
@@ -0,0 +1,42 @@
1
+ /**
2
+ * show-more 提示文本:fullscreen 下鼠标 hover/click 可用,提示 "click to show more";
3
+ * 其他模式(regular 保留终端原生 scrollback、不启用鼠标上报)提示默认展开快捷键。
4
+ *
5
+ * tui 模式由 mouse-interaction 在 renderer 回调中维护;未安装时按 fullscreen 处理,
6
+ * 保证纯渲染测试与既有行为不变。
7
+ */
8
+ import { getKeybindings } from "@earendil-works/pi-tui";
9
+
10
+ let toolTuiFullscreen: boolean | undefined;
11
+
12
+ export function setToolTuiFullscreen(value: boolean): void {
13
+ toolTuiFullscreen = value;
14
+ }
15
+
16
+ export function isToolTuiFullscreen(): boolean {
17
+ return toolTuiFullscreen !== false;
18
+ }
19
+
20
+ function formatKeyPart(part: string): string {
21
+ // 与 pi 内置 keybinding-hints 一致:macOS 上 alt 显示为 option
22
+ return process.platform === "darwin" && part.toLowerCase() === "alt"
23
+ ? "option"
24
+ : part;
25
+ }
26
+
27
+ /** 默认展开快捷键(app.tools.expand)显示文本;未配置时回退 ctrl+o。 */
28
+ export function expandShortcutText(): string {
29
+ const keys = getKeybindings().getKeys("app.tools.expand");
30
+ if (keys.length === 0) return "ctrl+o";
31
+ return keys
32
+ .join("/")
33
+ .split("/")
34
+ .map((part) => part.split("+").map(formatKeyPart).join("+"))
35
+ .join("/");
36
+ }
37
+
38
+ export function showMoreHintText(): string {
39
+ return isToolTuiFullscreen()
40
+ ? "click to show more"
41
+ : `${expandShortcutText()} to show more`;
42
+ }
@@ -0,0 +1,79 @@
1
+ import type { AssistantMessage } from "@earendil-works/pi-ai";
2
+ import {
3
+ AssistantMessageComponent,
4
+ ToolExecutionComponent,
5
+ } from "@earendil-works/pi-coding-agent";
6
+ import { walkComponentTree } from "../../tools/component-tree.ts";
7
+ import {
8
+ COMPACT_MODE_PATCH_KEY,
9
+ patchRegistry,
10
+ } from "../../tools/patch-keys.ts";
11
+
12
+ // pi-coding-agent 类型声明中 AssistantMessageComponent 仅能以 value 形式使用,
13
+ // updateContent/lastMessage 用结构化类型访问。
14
+ type TranscriptComponentInternals = {
15
+ lastMessage?: AssistantMessage;
16
+ updateContent(message: AssistantMessage): void;
17
+ invalidate?(): void;
18
+ };
19
+
20
+ /**
21
+ * 重绘单个已构造的组件:assistant 用最新消息重渲染(compact thinking),
22
+ * tool 强制 updateDisplay(其内容可能仍在旧 shell 容器中)。
23
+ * 不吞异常——由调用方决定如何处理失败。
24
+ */
25
+ export function refreshTranscriptComponent(value: unknown): boolean {
26
+ if (!value || typeof value !== "object") return false;
27
+ if (value instanceof AssistantMessageComponent) {
28
+ const self = value as unknown as TranscriptComponentInternals;
29
+ if (self.lastMessage) self.updateContent(self.lastMessage);
30
+ else self.invalidate?.();
31
+ return true;
32
+ }
33
+ if (value instanceof ToolExecutionComponent) {
34
+ // updateDisplay 是私有方法,但它是 resume 后让内容回到正确
35
+ // shell 容器的唯一入口(原型链已含全局工具渲染补丁)。
36
+ (value as unknown as { updateDisplay(): void }).updateDisplay();
37
+ return true;
38
+ }
39
+ return false;
40
+ }
41
+
42
+ /**
43
+ * 扫描挂载树,重绘所有已构造的 assistant/tool 组件。
44
+ * 用于 reload/resume/compaction 后"pi 用原始原型重建、补丁事后才装"的场景。
45
+ * 遍历 value.children 与 value.getMountedRoots?.()(seen 集合防环),
46
+ * 单个组件失败用 try/catch 隔离,不影响其余组件。
47
+ */
48
+
49
+ /**
50
+ * 补丁链序不变量:compact 模式下 compact-mode 必须位于 compact-thinking
51
+ * 外层(round 摘要才能聚合工具统计)。resume/reload 后若无新消息,
52
+ * message_update 触发的重新认领不会执行,这里在任何重绘前先断言一次。
53
+ * 断言幂等:链序已正确时无操作;mode=on 时也安全(外层走 pass-through)。
54
+ */
55
+ function assertCompactModeOutermost(): void {
56
+ try {
57
+ const patch = patchRegistry.get<{ assertAssistantOwnership?: () => void }>(
58
+ COMPACT_MODE_PATCH_KEY,
59
+ );
60
+ if (patch && typeof patch.assertAssistantOwnership === "function") {
61
+ patch.assertAssistantOwnership();
62
+ }
63
+ } catch {
64
+ // 无 compact-mode 补丁或断言失败时跳过,扫描仍会执行。
65
+ }
66
+ }
67
+
68
+ export function refreshMountedTranscript(tui?: unknown): void {
69
+ if (!tui || typeof (tui as any).getMountedRoots !== "function") return;
70
+ // 先修正链序再重绘:扫描触发 updateContent 时 compact-mode 已在外层。
71
+ assertCompactModeOutermost();
72
+ walkComponentTree(tui, (value: any) => {
73
+ try {
74
+ refreshTranscriptComponent(value);
75
+ } catch {
76
+ // 单个组件失败不阻断其余组件;后续 session_tree/重绘再试。
77
+ }
78
+ });
79
+ }
package/package.json ADDED
@@ -0,0 +1,58 @@
1
+ {
2
+ "name": "pi-one-ui",
3
+ "version": "0.1.1",
4
+ "description": "A single, customizable Pi UI package combining Zentui shell chrome with Claude Code-style transcript rendering.",
5
+ "type": "module",
6
+ "license": "MIT",
7
+ "files": [
8
+ "extensions",
9
+ "themes",
10
+ "README.md",
11
+ "LICENSE"
12
+ ],
13
+ "scripts": {
14
+ "typecheck": "tsc --noEmit",
15
+ "test": "npm run test:node && npm run test:vitest",
16
+ "test:node": "node --test tests/config.test.ts tests/one-ui-integration.test.ts tests/transcript-*.test.ts",
17
+ "format": "biome format --write extensions tests package.json tsconfig.json biome.json",
18
+ "format:check": "biome format extensions tests package.json tsconfig.json biome.json",
19
+ "lint": "biome check extensions/index.ts extensions/app/panel.ts extensions/app/presets.ts package.json tsconfig.json biome.json",
20
+ "test:vitest": "vitest run tests/shell-*.test.ts",
21
+ "verify": "npm run format:check && npm run lint && npm run typecheck && npm test",
22
+ "pack:check": "npm pack --dry-run",
23
+ "pi:dev": "${PI_BIN:-pi} --no-extensions -e ./extensions/index.ts",
24
+ "pi:install-local": "${PI_BIN:-pi} install ./ -l"
25
+ },
26
+ "dependencies": {
27
+ "@shikijs/cli": "^4.0.2",
28
+ "grok-mermaid": "^0.2.2",
29
+ "jiti": "^2.7.0"
30
+ },
31
+ "peerDependencies": {
32
+ "@earendil-works/pi-ai": ">=0.84.0",
33
+ "@earendil-works/pi-coding-agent": ">=0.84.0",
34
+ "@earendil-works/pi-tui": ">=0.84.0"
35
+ },
36
+ "engines": {
37
+ "node": ">=22.19.0"
38
+ },
39
+ "pi": {
40
+ "extensions": [
41
+ "./extensions/index.ts"
42
+ ],
43
+ "themes": [
44
+ "./themes/cc-dark.json",
45
+ "./themes/cc-light.json"
46
+ ],
47
+ "image": "https://raw.githubusercontent.com/minuque/pi-cc-extensions/main/assets/readme/preview.png"
48
+ },
49
+ "devDependencies": {
50
+ "@biomejs/biome": "^2.5.5",
51
+ "@earendil-works/pi-ai": "^0.84.0",
52
+ "@earendil-works/pi-coding-agent": "^0.84.0",
53
+ "@earendil-works/pi-tui": "^0.84.0",
54
+ "@types/node": "^26.1.1",
55
+ "typescript": "^6.0.3",
56
+ "vitest": "^4.1.11"
57
+ }
58
+ }
@@ -0,0 +1,91 @@
1
+ {
2
+ "$schema": "https://raw.githubusercontent.com/earendil-works/pi/main/packages/coding-agent/src/modes/interactive/theme/theme-schema.json",
3
+ "name": "cc-dark",
4
+ "vars": {
5
+ "bg": "#131217",
6
+ "panel": "#1b1922",
7
+ "surface": "#211e2b",
8
+ "surfaceRaised": "#292533",
9
+ "border": "#36313f",
10
+ "borderMuted": "#292631",
11
+ "accent": "#5e9cff",
12
+ "accentBright": "#8ab4ff",
13
+ "purple": "#c084fc",
14
+ "pink": "#f472b6",
15
+ "cyan": "#67e8f9",
16
+ "blue": "#60a5fa",
17
+ "green": "#4ade80",
18
+ "red": "#fb7185",
19
+ "yellow": "#facc15",
20
+ "orange": "#fb923c",
21
+ "text": "#f5f5f5",
22
+ "muted": "#a1a1aa",
23
+ "dim": "#71717a",
24
+ "selectedBg": "#252035",
25
+ "userMessageBg": "#1e1e2e",
26
+ "toolPendingBg": "#1b1924",
27
+ "toolSuccessBg": "#1e1e2e",
28
+ "toolErrorBg": "#2a1b22",
29
+ "customMessageBg": "#211c30"
30
+ },
31
+ "colors": {
32
+ "accent": "accent",
33
+ "border": "border",
34
+ "borderAccent": "accent",
35
+ "borderMuted": "borderMuted",
36
+ "success": "green",
37
+ "error": "red",
38
+ "warning": "yellow",
39
+ "muted": "muted",
40
+ "dim": "dim",
41
+ "text": "text",
42
+ "thinkingText": "muted",
43
+ "selectedBg": "selectedBg",
44
+ "scrollbarThumb": "selectedBg",
45
+ "userMessageBg": "userMessageBg",
46
+ "userMessageText": "text",
47
+ "customMessageBg": "customMessageBg",
48
+ "customMessageText": "text",
49
+ "customMessageLabel": "purple",
50
+ "toolPendingBg": "toolPendingBg",
51
+ "toolSuccessBg": "toolSuccessBg",
52
+ "toolErrorBg": "toolErrorBg",
53
+ "toolTitle": "accentBright",
54
+ "toolOutput": "muted",
55
+ "mdHeading": "accentBright",
56
+ "mdLink": "cyan",
57
+ "mdLinkUrl": "muted",
58
+ "mdCode": "accentBright",
59
+ "mdCodeBlock": "text",
60
+ "mdCodeBlockBorder": "border",
61
+ "mdQuote": "muted",
62
+ "mdQuoteBorder": "accent",
63
+ "mdHr": "borderMuted",
64
+ "mdListBullet": "accent",
65
+ "toolDiffAdded": "green",
66
+ "toolDiffRemoved": "red",
67
+ "toolDiffContext": "muted",
68
+ "syntaxComment": "#6b7280",
69
+ "syntaxKeyword": "pink",
70
+ "syntaxFunction": "accentBright",
71
+ "syntaxVariable": "blue",
72
+ "syntaxString": "green",
73
+ "syntaxNumber": "orange",
74
+ "syntaxType": "cyan",
75
+ "syntaxOperator": "text",
76
+ "syntaxPunctuation": "muted",
77
+ "thinkingOff": "muted",
78
+ "thinkingMinimal": "dim",
79
+ "thinkingLow": "blue",
80
+ "thinkingMedium": "accent",
81
+ "thinkingHigh": "accentBright",
82
+ "thinkingXhigh": "#4db9cd",
83
+ "thinkingMax": "cyan",
84
+ "bashMode": "green"
85
+ },
86
+ "export": {
87
+ "pageBg": "bg",
88
+ "cardBg": "panel",
89
+ "infoBg": "surface"
90
+ }
91
+ }
@@ -0,0 +1,91 @@
1
+ {
2
+ "$schema": "https://raw.githubusercontent.com/earendil-works/pi/main/packages/coding-agent/src/modes/interactive/theme/theme-schema.json",
3
+ "name": "cc-light",
4
+ "vars": {
5
+ "bg": "#f7f7f8",
6
+ "panel": "#ffffff",
7
+ "surface": "#f3f1f7",
8
+ "surfaceRaised": "#ebe8f0",
9
+ "border": "#d4d0db",
10
+ "borderMuted": "#e5e2e9",
11
+ "accent": "#2563eb",
12
+ "accentBright": "#1d4ed8",
13
+ "purple": "#7e22ce",
14
+ "pink": "#be185d",
15
+ "cyan": "#0e7490",
16
+ "blue": "#2563eb",
17
+ "green": "#15803d",
18
+ "red": "#dc2626",
19
+ "yellow": "#a16207",
20
+ "orange": "#c2410c",
21
+ "text": "#242127",
22
+ "muted": "#625f68",
23
+ "dim": "#76717d",
24
+ "selectedBg": "#e3e8f5",
25
+ "userMessageBg": "#f0eef4",
26
+ "toolPendingBg": "#f1f3f9",
27
+ "toolSuccessBg": "#edf7f0",
28
+ "toolErrorBg": "#fceff1",
29
+ "customMessageBg": "#f4effa"
30
+ },
31
+ "colors": {
32
+ "accent": "accent",
33
+ "border": "border",
34
+ "borderAccent": "accent",
35
+ "borderMuted": "borderMuted",
36
+ "success": "green",
37
+ "error": "red",
38
+ "warning": "yellow",
39
+ "muted": "muted",
40
+ "dim": "dim",
41
+ "text": "text",
42
+ "thinkingText": "muted",
43
+ "selectedBg": "selectedBg",
44
+ "scrollbarThumb": "selectedBg",
45
+ "userMessageBg": "userMessageBg",
46
+ "userMessageText": "text",
47
+ "customMessageBg": "customMessageBg",
48
+ "customMessageText": "text",
49
+ "customMessageLabel": "purple",
50
+ "toolPendingBg": "toolPendingBg",
51
+ "toolSuccessBg": "toolSuccessBg",
52
+ "toolErrorBg": "toolErrorBg",
53
+ "toolTitle": "accentBright",
54
+ "toolOutput": "muted",
55
+ "mdHeading": "accentBright",
56
+ "mdLink": "cyan",
57
+ "mdLinkUrl": "muted",
58
+ "mdCode": "accentBright",
59
+ "mdCodeBlock": "text",
60
+ "mdCodeBlockBorder": "border",
61
+ "mdQuote": "muted",
62
+ "mdQuoteBorder": "accent",
63
+ "mdHr": "borderMuted",
64
+ "mdListBullet": "accent",
65
+ "toolDiffAdded": "green",
66
+ "toolDiffRemoved": "red",
67
+ "toolDiffContext": "muted",
68
+ "syntaxComment": "#6b7280",
69
+ "syntaxKeyword": "pink",
70
+ "syntaxFunction": "accentBright",
71
+ "syntaxVariable": "blue",
72
+ "syntaxString": "green",
73
+ "syntaxNumber": "orange",
74
+ "syntaxType": "cyan",
75
+ "syntaxOperator": "text",
76
+ "syntaxPunctuation": "muted",
77
+ "thinkingOff": "muted",
78
+ "thinkingMinimal": "dim",
79
+ "thinkingLow": "blue",
80
+ "thinkingMedium": "accent",
81
+ "thinkingHigh": "accentBright",
82
+ "thinkingXhigh": "#4a8fa3",
83
+ "thinkingMax": "cyan",
84
+ "bashMode": "green"
85
+ },
86
+ "export": {
87
+ "pageBg": "bg",
88
+ "cardBg": "panel",
89
+ "infoBg": "surface"
90
+ }
91
+ }