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,130 @@
1
+ export type StopProjectRefreshInterval = () => void;
2
+
3
+ export type ScheduleProjectRefreshOptions = {
4
+ force?: boolean;
5
+ };
6
+
7
+ export type ProjectRefreshRun = {
8
+ isCurrent: () => boolean;
9
+ };
10
+
11
+ export type ProjectRefreshScheduler<T> = {
12
+ schedule: (target: T, options?: ScheduleProjectRefreshOptions) => void;
13
+ invalidate: () => void;
14
+ stop: () => void;
15
+ };
16
+
17
+ export const PROJECT_REFRESH_THROTTLE_MS = 5_000;
18
+
19
+ export function startProjectRefreshInterval(
20
+ intervalMs: number,
21
+ refresh: () => void,
22
+ ): StopProjectRefreshInterval {
23
+ if (intervalMs <= 0) return () => {};
24
+
25
+ const timer = setInterval(refresh, intervalMs);
26
+ timer.unref?.();
27
+
28
+ return () => clearInterval(timer);
29
+ }
30
+
31
+ export function createProjectRefreshScheduler<T>(
32
+ refresh: (target: T, run: ProjectRefreshRun) => Promise<void>,
33
+ afterRefresh: () => void,
34
+ throttleMs = PROJECT_REFRESH_THROTTLE_MS,
35
+ ): ProjectRefreshScheduler<T> {
36
+ let refreshInFlight = false;
37
+ let refreshPending = false;
38
+ let pendingForce = false;
39
+ let pendingTarget: T | undefined;
40
+ let delayedRefresh: ReturnType<typeof setTimeout> | undefined;
41
+ let lastRefreshStartedAt: number | undefined;
42
+ let generation = 0;
43
+
44
+ const clearDelayedRefresh = () => {
45
+ if (!delayedRefresh) return;
46
+ clearTimeout(delayedRefresh);
47
+ delayedRefresh = undefined;
48
+ };
49
+
50
+ const runRefresh = (
51
+ target: T,
52
+ options: ScheduleProjectRefreshOptions = {},
53
+ ) => {
54
+ clearDelayedRefresh();
55
+ if (refreshInFlight) {
56
+ refreshPending = true;
57
+ pendingForce ||= options.force === true;
58
+ pendingTarget = target;
59
+ return;
60
+ }
61
+
62
+ const currentGeneration = generation;
63
+ const run: ProjectRefreshRun = {
64
+ isCurrent: () => currentGeneration === generation,
65
+ };
66
+ refreshInFlight = true;
67
+ lastRefreshStartedAt = Date.now();
68
+ void refresh(target, run)
69
+ .catch(() => undefined)
70
+ .finally(() => {
71
+ if (currentGeneration !== generation) return;
72
+ refreshInFlight = false;
73
+ afterRefresh();
74
+ if (refreshPending) {
75
+ refreshPending = false;
76
+ const nextForce = pendingForce;
77
+ pendingForce = false;
78
+ const nextTarget = pendingTarget ?? target;
79
+ pendingTarget = undefined;
80
+ schedule(nextTarget, { force: nextForce });
81
+ }
82
+ });
83
+ };
84
+
85
+ const schedule = (target: T, options: ScheduleProjectRefreshOptions = {}) => {
86
+ if (
87
+ options.force ||
88
+ throttleMs <= 0 ||
89
+ lastRefreshStartedAt === undefined
90
+ ) {
91
+ runRefresh(target, options);
92
+ return;
93
+ }
94
+
95
+ const delayMs = Math.max(
96
+ 0,
97
+ throttleMs - (Date.now() - lastRefreshStartedAt),
98
+ );
99
+ if (delayMs === 0) {
100
+ runRefresh(target);
101
+ return;
102
+ }
103
+
104
+ pendingTarget = target;
105
+ if (delayedRefresh) return;
106
+ delayedRefresh = setTimeout(() => {
107
+ delayedRefresh = undefined;
108
+ const nextTarget = pendingTarget ?? target;
109
+ pendingTarget = undefined;
110
+ runRefresh(nextTarget);
111
+ }, delayMs);
112
+ delayedRefresh.unref?.();
113
+ };
114
+
115
+ const invalidate = () => {
116
+ generation += 1;
117
+ clearDelayedRefresh();
118
+ refreshInFlight = false;
119
+ refreshPending = false;
120
+ pendingForce = false;
121
+ pendingTarget = undefined;
122
+ lastRefreshStartedAt = undefined;
123
+ };
124
+
125
+ return {
126
+ schedule,
127
+ invalidate,
128
+ stop: invalidate,
129
+ };
130
+ }
@@ -0,0 +1,60 @@
1
+ import type { GitReadResult } from "./git.ts";
2
+ import { emptyGitStatus } from "./git.ts";
3
+ import type { PackageVersionReadResult } from "./package-version.ts";
4
+ import type { RuntimeReadResult } from "./runtime.ts";
5
+ import type { FooterState } from "./state.ts";
6
+
7
+ /**
8
+ * Apply a project refresh (git + runtime) onto footer state, preserving
9
+ * last-good values on transient errors and clearing on cwd change / not-a-repo.
10
+ *
11
+ * Returns the cwd to store as `previousCwd` for the next refresh.
12
+ */
13
+ export function applyProjectRefreshToState(
14
+ state: FooterState,
15
+ args: {
16
+ cwd: string;
17
+ previousCwd: string | undefined;
18
+ git: GitReadResult;
19
+ runtime: RuntimeReadResult;
20
+ packageVersion?: PackageVersionReadResult;
21
+ },
22
+ ): string {
23
+ const cwdChanged =
24
+ args.previousCwd !== undefined && args.previousCwd !== args.cwd;
25
+
26
+ if (cwdChanged) {
27
+ Object.assign(state, emptyGitStatus());
28
+ state.runtime = undefined;
29
+ state.packageVersion = undefined;
30
+ }
31
+
32
+ if (args.git.kind === "ok") {
33
+ Object.assign(state, args.git.status);
34
+ } else if (args.git.kind === "not_a_repo") {
35
+ Object.assign(state, emptyGitStatus());
36
+ }
37
+ // kind === "error": keep previous git fields (unless cwdChanged already cleared)
38
+
39
+ if (args.runtime.kind === "ok") {
40
+ state.runtime = args.runtime.runtime;
41
+ } else if (cwdChanged && args.runtime.kind === "error") {
42
+ // Already cleared above; keep undefined.
43
+ state.runtime = undefined;
44
+ }
45
+ // error + same cwd: keep previous runtime
46
+
47
+ if (args.packageVersion !== undefined) {
48
+ if (args.packageVersion.kind === "ok") {
49
+ // `null` means "no manifest in this cwd"; clear so the segment disappears
50
+ // even on the same cwd when the user removes their manifest.
51
+ state.packageVersion = args.packageVersion.result ?? undefined;
52
+ } else if (!cwdChanged) {
53
+ // error + same cwd: keep previous packageVersion (last-good semantics)
54
+ } else {
55
+ state.packageVersion = undefined;
56
+ }
57
+ }
58
+
59
+ return args.cwd;
60
+ }
@@ -0,0 +1,183 @@
1
+ export const ZENTUI_PROTOTYPE_PATCH_REGISTRY = Symbol.for(
2
+ "pi-zentui.prototype-patch-registry",
3
+ );
4
+
5
+ type PrototypePatchAdapter =
6
+ | "user-message-render"
7
+ | "user-message-invalidate"
8
+ | "selector-border-render";
9
+
10
+ type PrototypeMethod = (this: unknown, ...args: unknown[]) => unknown;
11
+
12
+ type PatchInvocation = {
13
+ predecessor: PrototypeMethod;
14
+ receiver: unknown;
15
+ args: unknown[];
16
+ };
17
+
18
+ type PatchBehavior = (invocation: PatchInvocation) => unknown;
19
+
20
+ type Registration = {
21
+ token: symbol;
22
+ behavior?: PatchBehavior;
23
+ };
24
+
25
+ type PatchRecord = {
26
+ method: "render" | "invalidate";
27
+ predecessor: PrototypeMethod;
28
+ predecessorDescriptor?: PropertyDescriptor;
29
+ wrapper: PrototypeMethod;
30
+ registration?: Registration;
31
+ };
32
+
33
+ type PatchRegistry = Map<PrototypePatchAdapter, PatchRecord>;
34
+
35
+ type PatchTarget = Record<PropertyKey, unknown>;
36
+
37
+ function existingRegistry(target: PatchTarget): PatchRegistry | undefined {
38
+ const existing = target[ZENTUI_PROTOTYPE_PATCH_REGISTRY];
39
+ return existing instanceof Map ? (existing as PatchRegistry) : undefined;
40
+ }
41
+
42
+ function registryFor(target: PatchTarget): PatchRegistry {
43
+ const existing = existingRegistry(target);
44
+ if (existing) return existing;
45
+ const registry: PatchRegistry = new Map();
46
+ Object.defineProperty(target, ZENTUI_PROTOTYPE_PATCH_REGISTRY, {
47
+ value: registry,
48
+ configurable: true,
49
+ });
50
+ return registry;
51
+ }
52
+
53
+ function deactivateRecord(record: PatchRecord): void {
54
+ if (!record.registration) return;
55
+ record.registration.behavior = undefined;
56
+ record.registration = undefined;
57
+ }
58
+
59
+ function restorePredecessor(target: PatchTarget, record: PatchRecord): void {
60
+ if (target[record.method] !== record.wrapper) return;
61
+ if (record.predecessorDescriptor) {
62
+ Object.defineProperty(target, record.method, record.predecessorDescriptor);
63
+ } else {
64
+ delete target[record.method];
65
+ }
66
+ }
67
+
68
+ function installWrapper(target: PatchTarget, record: PatchRecord): void {
69
+ const descriptor = record.predecessorDescriptor;
70
+ if (descriptor && "value" in descriptor) {
71
+ Object.defineProperty(target, record.method, {
72
+ ...descriptor,
73
+ value: record.wrapper,
74
+ });
75
+ return;
76
+ }
77
+ Object.defineProperty(target, record.method, {
78
+ value: record.wrapper,
79
+ writable: true,
80
+ enumerable: descriptor?.enumerable ?? true,
81
+ configurable: true,
82
+ });
83
+ }
84
+
85
+ function createCleanup(
86
+ target: PatchTarget,
87
+ adapter: PrototypePatchAdapter,
88
+ registry: PatchRegistry,
89
+ record: PatchRecord,
90
+ token: symbol,
91
+ ): () => void {
92
+ let cleaned = false;
93
+ return () => {
94
+ if (cleaned) return;
95
+ cleaned = true;
96
+ if (record.registration?.token !== token) return;
97
+ deactivateRecord(record);
98
+
99
+ const current = registry.get(adapter);
100
+ if (current !== record) return;
101
+ restorePredecessor(target, record);
102
+ registry.delete(adapter);
103
+ if (registry.size === 0) delete target[ZENTUI_PROTOTYPE_PATCH_REGISTRY];
104
+ };
105
+ }
106
+
107
+ export function installPrototypePatch(
108
+ targetValue: object,
109
+ method: "render" | "invalidate",
110
+ adapter: PrototypePatchAdapter,
111
+ behavior: PatchBehavior,
112
+ ): () => void {
113
+ const target = targetValue as PatchTarget;
114
+ const registry = registryFor(target);
115
+ let record = registry.get(adapter);
116
+
117
+ if (
118
+ !(record && record.method === method && target[method] === record.wrapper)
119
+ ) {
120
+ const displacedRecord = record;
121
+ const predecessorDescriptor = Object.getOwnPropertyDescriptor(
122
+ target,
123
+ method,
124
+ );
125
+ const predecessor = target[method];
126
+ if (typeof predecessor !== "function") {
127
+ if (registry.size === 0) delete target[ZENTUI_PROTOTYPE_PATCH_REGISTRY];
128
+ throw new TypeError(
129
+ `Cannot patch ${method}: predecessor is not a function`,
130
+ );
131
+ }
132
+ const nextRecord: PatchRecord = {
133
+ method,
134
+ predecessor: predecessor as PrototypeMethod,
135
+ predecessorDescriptor,
136
+ wrapper: () => undefined,
137
+ };
138
+ const wrapper: PrototypeMethod = function zentuiPrototypeWrapper(
139
+ this: unknown,
140
+ ...args: unknown[]
141
+ ): unknown {
142
+ const activeBehavior = nextRecord.registration?.behavior;
143
+ return activeBehavior
144
+ ? activeBehavior({
145
+ predecessor: nextRecord.predecessor,
146
+ receiver: this,
147
+ args,
148
+ })
149
+ : Reflect.apply(nextRecord.predecessor, this, args);
150
+ };
151
+ nextRecord.wrapper = wrapper;
152
+ try {
153
+ installWrapper(target, nextRecord);
154
+ } catch (error) {
155
+ if (registry.size === 0) delete target[ZENTUI_PROTOTYPE_PATCH_REGISTRY];
156
+ throw error;
157
+ }
158
+ record = nextRecord;
159
+ registry.set(adapter, record);
160
+ if (displacedRecord && displacedRecord !== record)
161
+ deactivateRecord(displacedRecord);
162
+ }
163
+
164
+ const token = Symbol(adapter);
165
+ record.registration = { token, behavior };
166
+ return createCleanup(target, adapter, registry, record, token);
167
+ }
168
+
169
+ export function removePrototypePatch(
170
+ targetValue: object,
171
+ method: "render" | "invalidate",
172
+ adapter: PrototypePatchAdapter,
173
+ ): void {
174
+ const target = targetValue as PatchTarget;
175
+ const registry = existingRegistry(target);
176
+ const record = registry?.get(adapter);
177
+ if (!registry || !record || record.method !== method) return;
178
+
179
+ deactivateRecord(record);
180
+ restorePredecessor(target, record);
181
+ registry.delete(adapter);
182
+ if (registry.size === 0) delete target[ZENTUI_PROTOTYPE_PATCH_REGISTRY];
183
+ }