@danypops/pi-papyrus 0.38.2 → 0.38.4
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.
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { ExtensionCommandContext } from "@earendil-works/pi-coding-agent";
|
|
2
2
|
import { matchesKey, sliceByColumn, truncateToWidth, visibleWidth, wrapTextWithAnsi, type TUI } from "@earendil-works/pi-tui";
|
|
3
|
+
import { buildDetailLines, type DetailField, type DetailSection } from "malevich-tui-components";
|
|
3
4
|
import {
|
|
4
5
|
ARTIFACT_DETAIL_HORIZONTAL_PAN_COLUMNS,
|
|
5
6
|
ARTIFACT_DETAIL_MAX_VISIBLE_LINES,
|
|
@@ -90,12 +91,34 @@ class ArtifactDetailViewport {
|
|
|
90
91
|
{ text: "", wide: false },
|
|
91
92
|
];
|
|
92
93
|
const body = renderMarkdownBody(this.content.body, width, this.activeTheme).map((text) => ({ text, wide: false }));
|
|
93
|
-
|
|
94
|
-
|
|
94
|
+
|
|
95
|
+
// Labels + Metadata are plain field/flat-line shapes -- delegated to malevich's
|
|
96
|
+
// buildDetailLines. The body (markdown-rendered) and relationships (horizontally
|
|
97
|
+
// pannable "wide" lines) stay hand-rolled: buildDetailLines has no concept of
|
|
98
|
+
// either, and forcing them through it would either drop markdown formatting or
|
|
99
|
+
// lose the pan feature.
|
|
100
|
+
const fields: DetailField[] = this.content.labels.length > 0 ? [{ label: "Labels", value: this.content.labels.join(", ") }] : [];
|
|
101
|
+
const sections: DetailSection[] = this.content.metadata.length > 0
|
|
102
|
+
? [{ heading: "Metadata:", lines: this.content.metadata.map((line) => ` ${line}`) }]
|
|
95
103
|
: [];
|
|
96
|
-
const
|
|
97
|
-
?
|
|
104
|
+
const labelsAndMetadata = (fields.length > 0 || sections.length > 0)
|
|
105
|
+
? buildDetailLines(width, {
|
|
106
|
+
fields,
|
|
107
|
+
sections,
|
|
108
|
+
theme: {
|
|
109
|
+
field: (s) => theme.fg("muted", s),
|
|
110
|
+
heading: (s) => theme.fg("muted", s),
|
|
111
|
+
byline: (s) => theme.fg("dim", s),
|
|
112
|
+
body: (s) => theme.fg("text", s),
|
|
113
|
+
line: (s) => theme.fg("dim", s),
|
|
114
|
+
},
|
|
115
|
+
}).map((text) => ({ text, wide: false }))
|
|
98
116
|
: [];
|
|
117
|
+
// buildDetailLines' fields/sections don't insert a leading blank before the
|
|
118
|
+
// first field the way the original hand-rolled labels block did -- add it back
|
|
119
|
+
// when either piece rendered anything, matching the original layout exactly.
|
|
120
|
+
const labelsAndMetadataWithLeadingBlank = fields.length > 0 ? [{ text: "", wide: false }, ...labelsAndMetadata] : labelsAndMetadata;
|
|
121
|
+
|
|
99
122
|
const relationships = this.content.relationships.length > 0
|
|
100
123
|
? [
|
|
101
124
|
{ text: "", wide: false },
|
|
@@ -103,7 +126,7 @@ class ArtifactDetailViewport {
|
|
|
103
126
|
...this.content.relationships.map((text) => ({ text: theme.fg("text", text), wide: true })),
|
|
104
127
|
]
|
|
105
128
|
: [];
|
|
106
|
-
this.lines = [...identity, ...body, ...
|
|
129
|
+
this.lines = [...identity, ...body, ...labelsAndMetadataWithLeadingBlank, ...relationships];
|
|
107
130
|
this.offsetY = Math.min(this.offsetY, Math.max(0, this.lines.length - this.visibleLines));
|
|
108
131
|
}
|
|
109
132
|
}
|
package/extension/src/index.ts
CHANGED
|
@@ -26,7 +26,7 @@ import {
|
|
|
26
26
|
} from "@danypops/papyrus";
|
|
27
27
|
import { formatMetadata } from "./artifact-format.ts";
|
|
28
28
|
import { callService, subscribeTaskPushChannel } from "./service-client.ts";
|
|
29
|
-
import type { PushChannelClient } from "@danypops/
|
|
29
|
+
import type { PushChannelClient } from "@danypops/vehicle-client/daemon-client";
|
|
30
30
|
import { registerDomainTools, resolveNameFields } from "./domain-tools.ts";
|
|
31
31
|
import { registerNotesVehicle } from "./vehicle-notes-client.ts";
|
|
32
32
|
import { BoundedPoll } from "./bounded-poll.ts";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { connectPushChannel, createRetryingClient, type PushChannelClient, type PushChannelState, type RetryingClient } from "@danypops/
|
|
1
|
+
import { connectPushChannel, createRetryingClient, type PushChannelClient, type PushChannelState, type RetryingClient } from "@danypops/vehicle-client/daemon-client";
|
|
2
2
|
import { connectPapyrusClient, resolvePushChannelTarget, resolveVehicleClientTarget, type OperationName, type PapyrusClient, type VehicleClientTarget } from "@danypops/papyrus";
|
|
3
3
|
|
|
4
4
|
type ClientConnector = () => Promise<PapyrusClient>;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { ExtensionCommandContext } from "@earendil-works/pi-coding-agent";
|
|
2
2
|
import { matchesKey, sliceByColumn, truncateToWidth, visibleWidth, wrapTextWithAnsi, type TUI } from "@earendil-works/pi-tui";
|
|
3
|
+
import { buildDetailLines, type DetailField, type DetailSection } from "malevich-tui-components";
|
|
3
4
|
import {
|
|
4
5
|
TASK_DETAIL_HORIZONTAL_PAN_COLUMNS,
|
|
5
6
|
TASK_DETAIL_MAX_VISIBLE_LINES,
|
|
@@ -92,17 +93,32 @@ class TaskDetailViewport {
|
|
|
92
93
|
(text.length === 0 ? [""] : wrapTextWithAnsi(theme.fg(color, text), width)).map((line) => ({ text: line, graph: false }));
|
|
93
94
|
const status = TASK_STATUS_PRESENTATION[this.status as keyof typeof TASK_STATUS_PRESENTATION];
|
|
94
95
|
const headline = status ? theme.fg(status.color, theme.bold(this.content.headline)) : theme.bold(this.content.headline);
|
|
96
|
+
|
|
97
|
+
// Labels + the checklist/gates/metadata/history sections are plain field/flat-line
|
|
98
|
+
// shapes -- delegated to malevich's buildDetailLines. The headline/identity (styled
|
|
99
|
+
// per task status), body (markdown-rendered), and the relationship graph
|
|
100
|
+
// (horizontally pannable "wide" lines) stay hand-rolled: buildDetailLines has no
|
|
101
|
+
// concept of any of those.
|
|
95
102
|
const identity = [
|
|
96
103
|
...wrapTextWithAnsi(headline, width).map((text) => ({ text, graph: false })),
|
|
97
104
|
...wrap(this.content.identity, "muted"),
|
|
98
|
-
...(this.content.labels.length > 0 ? wrap(`Labels: ${this.content.labels.join(", ")}`, "muted") : []),
|
|
99
|
-
{ text: "", graph: false },
|
|
100
105
|
];
|
|
106
|
+
const detailTheme = {
|
|
107
|
+
field: (s: string) => theme.fg("muted", s),
|
|
108
|
+
heading: (s: string) => theme.fg("muted", s),
|
|
109
|
+
byline: (s: string) => theme.fg("dim", s),
|
|
110
|
+
body: (s: string) => theme.fg("text", s),
|
|
111
|
+
line: (s: string) => theme.fg("dim", s),
|
|
112
|
+
};
|
|
113
|
+
const fields: DetailField[] = this.content.labels.length > 0 ? [{ label: "Labels", value: this.content.labels.join(", ") }] : [];
|
|
114
|
+
const labels = fields.length > 0
|
|
115
|
+
? [...buildDetailLines(width, { fields, theme: detailTheme }).map((text) => ({ text, graph: false })), { text: "", graph: false }]
|
|
116
|
+
: [{ text: "", graph: false }];
|
|
101
117
|
const body = renderMarkdownBody(this.content.body, width, this.activeTheme).map((text) => ({ text, graph: false }));
|
|
102
|
-
const sections = this.content.sections.
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
118
|
+
const sections: DetailSection[] = this.content.sections.map((section) => ({ heading: section[0], lines: section.slice(1) }));
|
|
119
|
+
const sectionLines = sections.length > 0
|
|
120
|
+
? buildDetailLines(width, { sections, theme: detailTheme }).map((text) => ({ text, graph: false }))
|
|
121
|
+
: [];
|
|
106
122
|
const relationshipHeader = this.graphLines.length > 0
|
|
107
123
|
? [
|
|
108
124
|
{ text: "", graph: false },
|
|
@@ -112,8 +128,9 @@ class TaskDetailViewport {
|
|
|
112
128
|
: [];
|
|
113
129
|
this.detailLines = [
|
|
114
130
|
...identity,
|
|
131
|
+
...labels,
|
|
115
132
|
...body,
|
|
116
|
-
...
|
|
133
|
+
...sectionLines,
|
|
117
134
|
...relationshipHeader,
|
|
118
135
|
...this.graphLines.map((text) => ({ text: theme.fg("text", text), graph: true })),
|
|
119
136
|
];
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@danypops/pi-papyrus",
|
|
3
|
-
"version": "0.38.
|
|
3
|
+
"version": "0.38.4",
|
|
4
4
|
"description": "Pi host extension for Papyrus: native tools, TUI panels, and context injection over the daemon-backed graph store",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"keywords": ["pi-package"],
|
|
@@ -17,12 +17,13 @@
|
|
|
17
17
|
"typebox": "*"
|
|
18
18
|
},
|
|
19
19
|
"dependencies": {
|
|
20
|
-
"@danypops/
|
|
21
|
-
"@danypops/
|
|
22
|
-
"@danypops/vehicle-
|
|
20
|
+
"@danypops/papyrus": "^0.38.1",
|
|
21
|
+
"@danypops/vehicle-core": "^0.1.1",
|
|
22
|
+
"@danypops/vehicle-server": "^0.1.1",
|
|
23
23
|
"@danypops/vehicle-client": "^0.1.1",
|
|
24
24
|
"@danypops/vehicle-client-pi": "^0.1.5",
|
|
25
|
-
"beautiful-mermaid": "1.1.3"
|
|
25
|
+
"beautiful-mermaid": "1.1.3",
|
|
26
|
+
"malevich-tui-components": "^0.5.0"
|
|
26
27
|
},
|
|
27
28
|
"devDependencies": {
|
|
28
29
|
"@earendil-works/pi-coding-agent": "^0.80.10",
|