@xzzpig/pi-starline 0.5.0 → 0.5.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.
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# Fork release notes
|
|
2
|
+
|
|
3
|
+
## 0.5.1 — Release candidate
|
|
4
|
+
|
|
5
|
+
- Recognize the optional `@xzzpig/transcript-expand-target.v1` contract for group summary clicks. Invalid or absent providers fall back to the existing component resolver; no new mandatory package dependency or default-setting change.
|
|
6
|
+
- Add `build:types` and `prepack` to include `dist/public.d.ts` alongside the extension sources.
|
|
7
|
+
- Keep historical upstream/fork release notes in `CHANGELOG.md`; this fork-only file records the new compatibility release without expanding upstream documentation edits.
|
|
8
|
+
|
|
9
|
+
Validated host: Pi 1.1.0. Native drag-selection acceptance and OpenSpec archival are release gates, not implied by a successful package build.
|
package/README.md
CHANGED
|
@@ -227,3 +227,26 @@ Inspired by:
|
|
|
227
227
|
## License
|
|
228
228
|
|
|
229
229
|
MIT
|
|
230
|
+
|
|
231
|
+
## Compatibility: explicit expand targets (fork-only)
|
|
232
|
+
|
|
233
|
+
This fork's click-to-expand resolution (`mouse/tool-box.ts`) checks an
|
|
234
|
+
optional, versioned **explicit expand-target protocol** before its own
|
|
235
|
+
`setExpanded`/hint logic:
|
|
236
|
+
|
|
237
|
+
- Providers publish a resolver on a component instance under
|
|
238
|
+
`Symbol.for("@xzzpig/transcript-expand-target.v1")` with
|
|
239
|
+
`{ version: 1, resolveLocalTarget(localRow, width) }`. The consumer is
|
|
240
|
+
`mouse/explicit-expand-target.ts` (fork-only file).
|
|
241
|
+
- Today the only provider is
|
|
242
|
+
[`@xzzpig/pi-group-collapse`](../pi-group-collapse): its group summaries
|
|
243
|
+
resolve to the independent group object, so clicking a summary toggles
|
|
244
|
+
the group instead of the tool that carries it.
|
|
245
|
+
- Without a provider nothing changes: no published protocol, a wrong
|
|
246
|
+
version, a non-callable resolver, a thrown resolution, or an invalid
|
|
247
|
+
resolved shape all fall through to the existing resolution. Installing
|
|
248
|
+
the provider is never required, and load order in either direction
|
|
249
|
+
works (the resolver is read per click, not cached).
|
|
250
|
+
- Drag selection, double-click word selection, hyperlinks, wheel, and
|
|
251
|
+
overlay behavior are unaffected; the explicit target only answers for
|
|
252
|
+
the specific local rows it owns.
|
package/dist/public.d.ts
ADDED
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Fork-only consumer for the versioned explicit expand-target protocol
|
|
3
|
+
* (`@xzzpig/transcript-expand-target.v1`).
|
|
4
|
+
*
|
|
5
|
+
* Providers (pi-group-collapse today) publish a resolver on the component
|
|
6
|
+
* instance that draws a group summary. Starline checks that resolver for
|
|
7
|
+
* the component's *local* row before its own `setExpanded`/hint logic, so a
|
|
8
|
+
* click on a summary toggles the group object instead of the first tool
|
|
9
|
+
* inside it.
|
|
10
|
+
*
|
|
11
|
+
* The contract is defensive by requirement (see the mouse-api spec):
|
|
12
|
+
* no published protocol, a wrong version, a non-callable resolver, a
|
|
13
|
+
* thrown resolution, or an invalid resolved shape all fall back to the
|
|
14
|
+
* existing component path — installing the provider is never required and
|
|
15
|
+
* a broken provider cannot break clicks that used to work.
|
|
16
|
+
*
|
|
17
|
+
* This module deliberately depends on nothing: the symbol key is its only
|
|
18
|
+
* tie to the provider, so Starline keeps working with the provider absent,
|
|
19
|
+
* and any number of providers can publish the same key.
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
/** The shared protocol key; `Symbol.for` so every copy in the process agrees. */
|
|
23
|
+
export const EXPAND_TARGET_KEY = Symbol.for("@xzzpig/transcript-expand-target.v1");
|
|
24
|
+
|
|
25
|
+
/** The slice of the protocol Starline reads. */
|
|
26
|
+
type ExpandTargetProtocol = {
|
|
27
|
+
version: 1;
|
|
28
|
+
resolveLocalTarget: (localRow: number, width: number) => unknown;
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
/** The resolved target, validated before use. */
|
|
32
|
+
export type ExplicitExpandTarget = {
|
|
33
|
+
component: { setExpanded(expanded: boolean): void };
|
|
34
|
+
expanded: boolean;
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Resolve an explicit expand target for a component's local row, or
|
|
39
|
+
* undefined when there is no provider, no hit, or anything invalid.
|
|
40
|
+
*/
|
|
41
|
+
export function explicitExpandTargetAt(
|
|
42
|
+
component: unknown,
|
|
43
|
+
localRow: number,
|
|
44
|
+
width: number,
|
|
45
|
+
): ExplicitExpandTarget | undefined {
|
|
46
|
+
if (typeof component !== "object" || component === null) return undefined;
|
|
47
|
+
let protocol: unknown;
|
|
48
|
+
try {
|
|
49
|
+
protocol = (component as Record<PropertyKey, unknown>)[EXPAND_TARGET_KEY];
|
|
50
|
+
} catch {
|
|
51
|
+
return undefined;
|
|
52
|
+
}
|
|
53
|
+
if (
|
|
54
|
+
typeof protocol !== "object" ||
|
|
55
|
+
protocol === null ||
|
|
56
|
+
(protocol as ExpandTargetProtocol).version !== 1 ||
|
|
57
|
+
typeof (protocol as ExpandTargetProtocol).resolveLocalTarget !== "function"
|
|
58
|
+
) {
|
|
59
|
+
return undefined;
|
|
60
|
+
}
|
|
61
|
+
let resolved: unknown;
|
|
62
|
+
try {
|
|
63
|
+
resolved = (protocol as ExpandTargetProtocol).resolveLocalTarget(localRow, width);
|
|
64
|
+
} catch {
|
|
65
|
+
return undefined;
|
|
66
|
+
}
|
|
67
|
+
if (
|
|
68
|
+
typeof resolved !== "object" ||
|
|
69
|
+
resolved === null ||
|
|
70
|
+
typeof (resolved as ExplicitExpandTarget).expanded !== "boolean"
|
|
71
|
+
) {
|
|
72
|
+
return undefined;
|
|
73
|
+
}
|
|
74
|
+
const target = resolved as {
|
|
75
|
+
component?: { setExpanded?: unknown };
|
|
76
|
+
expanded: boolean;
|
|
77
|
+
};
|
|
78
|
+
if (
|
|
79
|
+
typeof target.component !== "object" ||
|
|
80
|
+
target.component === null ||
|
|
81
|
+
typeof target.component.setExpanded !== "function"
|
|
82
|
+
) {
|
|
83
|
+
return undefined;
|
|
84
|
+
}
|
|
85
|
+
return {
|
|
86
|
+
component: target.component as { setExpanded(expanded: boolean): void },
|
|
87
|
+
expanded: target.expanded,
|
|
88
|
+
};
|
|
89
|
+
}
|
|
@@ -87,6 +87,7 @@
|
|
|
87
87
|
|
|
88
88
|
import { stripTerminalSequences } from "@earendil-works/pi-tui";
|
|
89
89
|
import { createComponentTree, isComponentLike, isExpandableComponent } from "./component-tree";
|
|
90
|
+
import { explicitExpandTargetAt } from "./explicit-expand-target";
|
|
90
91
|
import { type BoxLike, boxesAt, scrollContentLinesFor, scrollContentOrigin } from "./hit-test";
|
|
91
92
|
import { keyTextFor } from "./key-text";
|
|
92
93
|
|
|
@@ -242,6 +243,9 @@ export function expandTargetAt(
|
|
|
242
243
|
|
|
243
244
|
for (let index = path.length - 1; index >= 0; index--) {
|
|
244
245
|
const span = path[index];
|
|
246
|
+
// Fork seam: a versioned explicit target on this component's local row wins over the component's own expand state, so a group summary toggles its group instead of the tool carrying it. No provider, wrong version, or invalid shape falls through untouched.
|
|
247
|
+
const explicit = explicitExpandTargetAt(span.component, row - span.start, origin.rect.width);
|
|
248
|
+
if (explicit) return { component: explicit.component, expanded: explicit.expanded };
|
|
245
249
|
if (!isExpandableComponent(span.component)) continue;
|
|
246
250
|
const component = span.component as ExpandableComponent;
|
|
247
251
|
// The hint is matched against this component's own rendered row, not
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@xzzpig/pi-starline",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.1",
|
|
4
4
|
"description": "A Starship-inspired statusline and Opencode-style TUI for Pi.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -20,12 +20,14 @@
|
|
|
20
20
|
"tui"
|
|
21
21
|
],
|
|
22
22
|
"files": [
|
|
23
|
-
"extensions"
|
|
23
|
+
"extensions",
|
|
24
|
+
"dist",
|
|
25
|
+
"FORK-CHANGELOG.md"
|
|
24
26
|
],
|
|
25
27
|
"peerDependencies": {
|
|
26
|
-
"@earendil-works/pi-ai": ">=0.
|
|
27
|
-
"@earendil-works/pi-coding-agent": ">=0.
|
|
28
|
-
"@earendil-works/pi-tui": ">=0.
|
|
28
|
+
"@earendil-works/pi-ai": ">=1.0.0 <2",
|
|
29
|
+
"@earendil-works/pi-coding-agent": ">=1.0.0 <2",
|
|
30
|
+
"@earendil-works/pi-tui": ">=1.0.0 <2",
|
|
29
31
|
"@xzzpig/pi-mouse-events": ">=0.2.0 <3"
|
|
30
32
|
},
|
|
31
33
|
"pi": {
|
|
@@ -39,10 +41,12 @@
|
|
|
39
41
|
},
|
|
40
42
|
"devDependencies": {
|
|
41
43
|
"@biomejs/biome": "^2.5.0",
|
|
42
|
-
"@earendil-works/pi-ai": "
|
|
43
|
-
"@earendil-works/pi-coding-agent": "
|
|
44
|
-
"@earendil-works/pi-tui": "
|
|
44
|
+
"@earendil-works/pi-ai": "1.1.0",
|
|
45
|
+
"@earendil-works/pi-coding-agent": "1.1.0",
|
|
46
|
+
"@earendil-works/pi-tui": "1.1.0",
|
|
45
47
|
"@types/node": "^26.0.0",
|
|
48
|
+
"rollup": "^4.62.2",
|
|
49
|
+
"rollup-plugin-dts": "^6.4.1",
|
|
46
50
|
"typescript": "^7.0.2",
|
|
47
51
|
"vitest": "^4.1.8",
|
|
48
52
|
"@xzzpig/pi-mouse-events": "0.2.0"
|
|
@@ -55,6 +59,7 @@
|
|
|
55
59
|
"scripts": {
|
|
56
60
|
"lint": "biome check .",
|
|
57
61
|
"typecheck": "tsc --noEmit",
|
|
62
|
+
"build:types": "rollup -c rollup.dts.config.mjs && biome format --write dist/public.d.ts",
|
|
58
63
|
"test": "vitest run",
|
|
59
64
|
"pi:dev": "${PI_BIN:-/opt/homebrew/bin/pi} --no-extensions -e ./extensions/starline/index.ts",
|
|
60
65
|
"pi:install-local": "${PI_BIN:-/opt/homebrew/bin/pi} install ./ -l",
|