@evanston/plankton 0.3.4 → 0.3.5
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/dist/output.js +67 -8
- package/dist/output.js.map +1 -1
- package/package.json +3 -2
package/dist/output.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { errorResult, } from "@evanston/plankton-core";
|
|
2
|
+
import Table from "cli-table3";
|
|
2
3
|
const fields = [
|
|
3
4
|
"id",
|
|
4
5
|
"name",
|
|
@@ -88,6 +89,14 @@ export function compactResult(operation, data, options) {
|
|
|
88
89
|
}
|
|
89
90
|
return result;
|
|
90
91
|
}
|
|
92
|
+
function safeText(value) {
|
|
93
|
+
// Escape control characters so board data cannot inject terminal sequences.
|
|
94
|
+
return typeof value === "string"
|
|
95
|
+
? JSON.stringify(value)
|
|
96
|
+
.slice(1, -1)
|
|
97
|
+
.replace(/[\u007f-\u009f]/g, (char) => `\\u${char.charCodeAt(0).toString(16).padStart(4, "0")}`)
|
|
98
|
+
: String(value);
|
|
99
|
+
}
|
|
91
100
|
function readable(value, indent = "") {
|
|
92
101
|
if (Array.isArray(value))
|
|
93
102
|
return value.length
|
|
@@ -97,19 +106,69 @@ function readable(value, indent = "") {
|
|
|
97
106
|
return Object.entries(value)
|
|
98
107
|
.map(([key, item]) => {
|
|
99
108
|
if (item && typeof item === "object")
|
|
100
|
-
return `${indent}${key}:\n${readable(item, indent + " ")}`;
|
|
101
|
-
|
|
102
|
-
const text = typeof item === "string"
|
|
103
|
-
? JSON.stringify(item).slice(1, -1)
|
|
104
|
-
: String(item);
|
|
105
|
-
return `${indent}${key}: ${text}`;
|
|
109
|
+
return `${indent}${safeText(key)}:\n${readable(item, indent + " ")}`;
|
|
110
|
+
return `${indent}${safeText(key)}: ${safeText(item)}`;
|
|
106
111
|
})
|
|
107
112
|
.join("\n");
|
|
108
113
|
}
|
|
109
|
-
return `${indent}${
|
|
114
|
+
return `${indent}${safeText(value)}`;
|
|
115
|
+
}
|
|
116
|
+
function heading(key) {
|
|
117
|
+
return safeText(key)
|
|
118
|
+
.replace(/([a-z])([A-Z])/g, "$1 $2")
|
|
119
|
+
.replace(/\bId\b/gi, "ID")
|
|
120
|
+
.replace(/\bIds\b/gi, "IDs")
|
|
121
|
+
.replace(/^url$/i, "URL")
|
|
122
|
+
.replace(/^./, (char) => char.toUpperCase());
|
|
123
|
+
}
|
|
124
|
+
function isRecord(value) {
|
|
125
|
+
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
126
|
+
}
|
|
127
|
+
function detailTable(row, width) {
|
|
128
|
+
const entries = Object.entries(row);
|
|
129
|
+
if (!entries.length)
|
|
130
|
+
return "(none)";
|
|
131
|
+
const fieldWidth = Math.min(Math.max(...entries.map(([key]) => heading(key).length)) + 2, Math.floor((width - 3) / 2));
|
|
132
|
+
const table = new Table({
|
|
133
|
+
colWidths: [fieldWidth, width - fieldWidth - 3],
|
|
134
|
+
wordWrap: true,
|
|
135
|
+
wrapOnWordBoundary: false,
|
|
136
|
+
style: { head: [], border: [] },
|
|
137
|
+
});
|
|
138
|
+
for (const [key, value] of entries)
|
|
139
|
+
table.push([heading(key), readable(value)]);
|
|
140
|
+
return table.toString();
|
|
141
|
+
}
|
|
142
|
+
function collectionTable(rows, width) {
|
|
143
|
+
const keys = [...new Set(rows.flatMap((row) => Object.keys(row)))];
|
|
144
|
+
if (!keys.length)
|
|
145
|
+
return "(none)";
|
|
146
|
+
const table = new Table({
|
|
147
|
+
head: keys.map(heading),
|
|
148
|
+
style: { head: [], border: [] },
|
|
149
|
+
});
|
|
150
|
+
for (const row of rows)
|
|
151
|
+
table.push(keys.map((key) => (key in row ? readable(row[key]) : "")));
|
|
152
|
+
const rendered = table.toString();
|
|
153
|
+
// Wide records stay complete and readable instead of losing fields to truncation.
|
|
154
|
+
return table.width <= width
|
|
155
|
+
? rendered
|
|
156
|
+
: rows.map((row) => detailTable(row, width)).join("\n\n");
|
|
157
|
+
}
|
|
158
|
+
function humanResult(data) {
|
|
159
|
+
const width = Math.max(12, process.stdout.columns || 100);
|
|
160
|
+
return Object.entries(data)
|
|
161
|
+
.map(([key, value]) => {
|
|
162
|
+
if (Array.isArray(value) && value.length && value.every(isRecord))
|
|
163
|
+
return `${heading(key)}\n${collectionTable(value, width)}`;
|
|
164
|
+
if (isRecord(value) && key !== "paging")
|
|
165
|
+
return `${heading(key)}\n${detailTable(value, width)}`;
|
|
166
|
+
return readable({ [key]: value });
|
|
167
|
+
})
|
|
168
|
+
.join("\n\n");
|
|
110
169
|
}
|
|
111
170
|
export function printResult(data, json) {
|
|
112
|
-
console.log(json ? JSON.stringify({ ok: true, data }) :
|
|
171
|
+
console.log(json ? JSON.stringify({ ok: true, data }) : humanResult(data));
|
|
113
172
|
}
|
|
114
173
|
export function printError(error, json) {
|
|
115
174
|
const result = errorResult(error);
|
package/dist/output.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"output.js","sourceRoot":"","sources":["../src/output.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,WAAW,GAKZ,MAAM,yBAAyB,CAAC;
|
|
1
|
+
{"version":3,"file":"output.js","sourceRoot":"","sources":["../src/output.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"author": "Evan Kim",
|
|
3
3
|
"name": "@evanston/plankton",
|
|
4
|
-
"version": "0.3.
|
|
4
|
+
"version": "0.3.5",
|
|
5
5
|
"description": "Planka CLI for people and explicitly invoked agent skills",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"license": "MIT",
|
|
@@ -20,9 +20,10 @@
|
|
|
20
20
|
}
|
|
21
21
|
},
|
|
22
22
|
"dependencies": {
|
|
23
|
+
"@evanston/plankton-core": "^0.3.5",
|
|
23
24
|
"@inquirer/prompts": "^7.10.1",
|
|
24
25
|
"@napi-rs/keyring": "^1.2.0",
|
|
25
|
-
"
|
|
26
|
+
"cli-table3": "^0.6.5",
|
|
26
27
|
"commander": "^14.0.3",
|
|
27
28
|
"playwright": "^1.55.0",
|
|
28
29
|
"zod": "^4.0.0"
|