deepline 0.3.293 → 0.3.295
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/bundling-sources/sdk/src/compat.ts +35 -7
- package/dist/bundling-sources/sdk/src/release.ts +1 -1
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/postgres-pool.ts +269 -267
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/postgres.ts +3 -4
- package/dist/bundling-sources/shared_libs/play-runtime/tool-http-errors.ts +14 -1
- package/dist/cli/auth-EDTRERZP.mjs +31 -0
- package/dist/cli/auth-TDHKB277.js +31 -0
- package/dist/cli/billing-ELIDPILY.js +1749 -0
- package/dist/cli/billing-EXGXJVAU.mjs +1749 -0
- package/dist/cli/chunk-2S5Y3TZP.js +5688 -0
- package/dist/cli/chunk-3KC45UVF.js +150 -0
- package/dist/cli/chunk-3XX5TEA4.js +15 -0
- package/dist/cli/chunk-4MBOJQPL.mjs +0 -0
- package/dist/cli/chunk-4NEFYBF7.js +2240 -0
- package/dist/cli/chunk-5JLQPVNX.js +3056 -0
- package/dist/cli/chunk-5KDKFHZI.js +1269 -0
- package/dist/cli/chunk-6A3TJUWC.js +76 -0
- package/dist/cli/chunk-6O5YZOVN.mjs +890 -0
- package/dist/cli/chunk-7P5AA3SN.js +344 -0
- package/dist/cli/chunk-AYHLUHE5.js +52 -0
- package/dist/cli/chunk-CBVIJSHF.mjs +560 -0
- package/dist/cli/chunk-CFVVCN4A.js +735 -0
- package/dist/cli/chunk-COGTRVWW.js +30 -0
- package/dist/cli/chunk-D4AZUZO4.js +190 -0
- package/dist/cli/chunk-DLIRSHV6.mjs +28 -0
- package/dist/cli/chunk-EACVZI6N.mjs +1995 -0
- package/dist/cli/chunk-EDWJY6T4.mjs +3056 -0
- package/dist/cli/chunk-EXMLR72R.mjs +0 -0
- package/dist/cli/chunk-F35VOIQL.js +890 -0
- package/dist/cli/chunk-GAMFK2ZP.mjs +148 -0
- package/dist/cli/chunk-GHRQQPW2.mjs +2240 -0
- package/dist/cli/chunk-GONRLVV3.js +3440 -0
- package/dist/cli/chunk-GVUJJJ5G.mjs +76 -0
- package/dist/cli/chunk-H7HIDGZ7.mjs +150 -0
- package/dist/cli/chunk-HUZXWOSK.mjs +503 -0
- package/dist/cli/chunk-I5YZLGMG.js +1 -0
- package/dist/cli/chunk-ITOFSXIU.mjs +15 -0
- package/dist/cli/chunk-J5NA2TTX.js +503 -0
- package/dist/cli/chunk-JCS5TPNY.mjs +3440 -0
- package/dist/cli/chunk-JNNOCMQY.js +47 -0
- package/dist/cli/chunk-KRD6H754.mjs +30 -0
- package/dist/cli/chunk-LA46MMTL.js +560 -0
- package/dist/cli/chunk-LDWT7RJK.mjs +190 -0
- package/dist/cli/chunk-M2V26OR5.js +499 -0
- package/dist/cli/chunk-MIMASXO4.mjs +389 -0
- package/dist/cli/chunk-MROPCKW2.mjs +190 -0
- package/dist/cli/chunk-NXDRDJ4K.js +389 -0
- package/dist/cli/chunk-NXGCO4JB.mjs +344 -0
- package/dist/cli/chunk-OG64RBAC.js +6 -0
- package/dist/cli/chunk-OQYEC4GL.mjs +34 -0
- package/dist/cli/chunk-OWJZUE3Y.mjs +103 -0
- package/dist/cli/chunk-SDK3ZA2C.js +103 -0
- package/dist/cli/chunk-SFLARO4Y.mjs +47 -0
- package/dist/cli/chunk-SVIIIYIQ.js +923 -0
- package/dist/cli/chunk-TAC3JIFE.mjs +354 -0
- package/dist/cli/chunk-U3PI7HBM.js +34 -0
- package/dist/cli/chunk-UFS752TU.mjs +52 -0
- package/dist/cli/chunk-UI37DQE7.mjs +499 -0
- package/dist/cli/chunk-UNEMDKXN.js +1 -0
- package/dist/cli/chunk-WB6Z2Q44.mjs +1622 -0
- package/dist/cli/chunk-WJYPBHTE.js +148 -0
- package/dist/cli/chunk-WOHBA5PV.js +354 -0
- package/dist/cli/chunk-WQICC2B3.js +190 -0
- package/dist/cli/chunk-WZYKRD7T.mjs +6 -0
- package/dist/cli/chunk-XL2FO6CW.mjs +5688 -0
- package/dist/cli/chunk-XNYIZMNQ.js +28 -0
- package/dist/cli/chunk-XRK2TZT5.js +1995 -0
- package/dist/cli/chunk-YJYPL5OK.mjs +1269 -0
- package/dist/cli/chunk-YWNDYCXR.mjs +735 -0
- package/dist/cli/chunk-YWWAF7KZ.mjs +923 -0
- package/dist/cli/chunk-ZDO3TO3M.js +1622 -0
- package/dist/cli/client-4JVOYVC5.js +20 -0
- package/dist/cli/client-EEN2IJN2.mjs +20 -0
- package/dist/cli/csv-BOHBEP2I.mjs +585 -0
- package/dist/cli/csv-S5NYRUEX.js +585 -0
- package/dist/cli/db-CLODWCOB.mjs +486 -0
- package/dist/cli/db-F6PKFOOV.js +486 -0
- package/dist/cli/executions-5TQAKLJU.js +28 -0
- package/dist/cli/executions-MAKW6QOY.mjs +28 -0
- package/dist/cli/feedback-GV4QJFEN.js +107 -0
- package/dist/cli/feedback-XY24TW7H.mjs +107 -0
- package/dist/cli/getting-started.js +18 -76
- package/dist/cli/getting-started.mjs +10 -37
- package/dist/cli/git-6S2C22T5.js +23 -0
- package/dist/cli/git-OZLBD5HH.mjs +23 -0
- package/dist/cli/index.js +291 -54294
- package/dist/cli/index.mjs +209 -54352
- package/dist/cli/legacy-noops-LLCGDPQE.js +157 -0
- package/dist/cli/legacy-noops-TYH3TW2D.mjs +157 -0
- package/dist/cli/monitors-CABMB4DW.js +3251 -0
- package/dist/cli/monitors-TTD55HMK.mjs +3251 -0
- package/dist/cli/org-MSF3RG76.js +849 -0
- package/dist/cli/org-SFJ77MWY.mjs +849 -0
- package/dist/cli/play-NXHJSCKL.mjs +18439 -0
- package/dist/cli/play-OKSFNNO4.js +18439 -0
- package/dist/cli/providers-QC2ERERL.js +95 -0
- package/dist/cli/providers-TIIAZEUA.mjs +95 -0
- package/dist/cli/proxy-env-EBANZHPV.js +161 -0
- package/dist/cli/proxy-env-M4ZHXHRL.mjs +161 -0
- package/dist/cli/quickstart-ICANHLMI.js +69 -0
- package/dist/cli/quickstart-KWUOP3FI.mjs +69 -0
- package/dist/cli/search-U5H2FDOO.mjs +18 -0
- package/dist/cli/search-XQRQOLWS.js +18 -0
- package/dist/cli/secrets-3J6YTWFA.mjs +400 -0
- package/dist/cli/secrets-YNMNZNOM.js +400 -0
- package/dist/cli/sessions-CLEES4L6.mjs +15 -0
- package/dist/cli/sessions-J6VR47FG.js +15 -0
- package/dist/cli/settings-EEKZMTY4.js +846 -0
- package/dist/cli/settings-UVLOQZRH.mjs +846 -0
- package/dist/cli/setup-DLMDXPGJ.mjs +1257 -0
- package/dist/cli/setup-HC4Q7QM4.js +1257 -0
- package/dist/cli/skills-33PHFBSB.mjs +28 -0
- package/dist/cli/skills-LFRY3KPX.js +28 -0
- package/dist/cli/tools-3COEPKML.mjs +2955 -0
- package/dist/cli/tools-QXEVCN45.js +2955 -0
- package/dist/cli/update-LSAC4FF5.mjs +28 -0
- package/dist/cli/update-NXHSPYXA.js +28 -0
- package/dist/cli/workflow-7S44OECF.mjs +1936 -0
- package/dist/cli/workflow-QPZWYSZE.js +1936 -0
- package/dist/helpers.js +6 -32
- package/dist/helpers.mjs +2 -0
- package/dist/index.js +1972 -12825
- package/dist/index.mjs +1910 -12672
- package/dist/install-integrity.json +110 -0
- package/dist/monitor-fleet-contract.js +31 -730
- package/dist/monitor-fleet-contract.mjs +18 -667
- package/dist/monitor-input-contract.js +10 -390
- package/dist/monitor-input-contract.mjs +7 -348
- package/dist/plays/bundle-play-file.mjs +13 -5178
- package/dist/plays/csv-data-input.js +5 -3132
- package/dist/plays/csv-data-input.mjs +5 -3105
- package/dist/plays/run-request.js +56 -664
- package/dist/plays/run-request.mjs +30 -588
- package/dist/release.d.mts +1 -1
- package/dist/release.d.ts +1 -1
- package/dist/release.js +5 -212
- package/dist/release.mjs +5 -185
- package/package.json +1 -1
|
@@ -0,0 +1,585 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
var _chunkF35VOIQLjs = require('./chunk-F35VOIQL.js');
|
|
8
|
+
require('./chunk-XRK2TZT5.js');
|
|
9
|
+
require('./chunk-XNYIZMNQ.js');
|
|
10
|
+
require('./chunk-D4AZUZO4.js');
|
|
11
|
+
require('./chunk-7P5AA3SN.js');
|
|
12
|
+
require('./chunk-OG64RBAC.js');
|
|
13
|
+
require('./chunk-COGTRVWW.js');
|
|
14
|
+
|
|
15
|
+
// src/cli/commands/csv.ts
|
|
16
|
+
var _commander = require('commander');
|
|
17
|
+
var _child_process = require('child_process');
|
|
18
|
+
var _crypto = require('crypto');
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
var _fs = require('fs');
|
|
28
|
+
var _os = require('os');
|
|
29
|
+
var _path = require('path');
|
|
30
|
+
function parseRowRange(raw) {
|
|
31
|
+
const source = _optionalChain([raw, 'optionalAccess', _ => _.trim, 'call', _2 => _2()]) || "0:19";
|
|
32
|
+
const [startRaw, endRaw] = source.split(":", 2);
|
|
33
|
+
const start = Number.parseInt(_nullishCoalesce(startRaw, () => ( "")), 10);
|
|
34
|
+
const end = Number.parseInt(_nullishCoalesce(endRaw, () => ( "")), 10);
|
|
35
|
+
if (!Number.isFinite(start) || !Number.isFinite(end) || start < 0 || end < start) {
|
|
36
|
+
throw new Error(
|
|
37
|
+
`Invalid --rows value: ${source} (expected start:end, e.g. 0:19).`
|
|
38
|
+
);
|
|
39
|
+
}
|
|
40
|
+
return [start, end];
|
|
41
|
+
}
|
|
42
|
+
function selectRows(rows, start, end) {
|
|
43
|
+
return rows.slice(start, end + 1);
|
|
44
|
+
}
|
|
45
|
+
function selectColumns(rows, rawColumns, rawExcludeColumns, availableColumns) {
|
|
46
|
+
const parseNames = (raw, flag) => {
|
|
47
|
+
if (raw === void 0) return null;
|
|
48
|
+
const names = raw.split(",").map((part) => part.trim());
|
|
49
|
+
if (names.some((name) => !name)) {
|
|
50
|
+
throw new Error(
|
|
51
|
+
`Invalid ${flag} value: provide comma-separated column names.`
|
|
52
|
+
);
|
|
53
|
+
}
|
|
54
|
+
const missing = names.filter((name) => !availableColumns.includes(name));
|
|
55
|
+
if (missing.length > 0) {
|
|
56
|
+
throw new Error(`Unknown ${flag} value(s): ${missing.join(", ")}.`);
|
|
57
|
+
}
|
|
58
|
+
return [...new Set(names)];
|
|
59
|
+
};
|
|
60
|
+
const included = _nullishCoalesce(parseNames(rawColumns, "--columns"), () => ( availableColumns));
|
|
61
|
+
const excluded = new Set(
|
|
62
|
+
_nullishCoalesce(parseNames(rawExcludeColumns, "--exclude-columns"), () => ( []))
|
|
63
|
+
);
|
|
64
|
+
const requested = included.filter((name) => !excluded.has(name));
|
|
65
|
+
if (requested.length === 0 && availableColumns.length > 0) {
|
|
66
|
+
throw new Error("No columns remain after --columns and --exclude-columns.");
|
|
67
|
+
}
|
|
68
|
+
return {
|
|
69
|
+
columns: requested,
|
|
70
|
+
rows: rows.map((row) => {
|
|
71
|
+
const next = {};
|
|
72
|
+
for (const column of requested) next[column] = _nullishCoalesce(row[column], () => ( ""));
|
|
73
|
+
return next;
|
|
74
|
+
})
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
function summarizeColumns(rows, columns) {
|
|
78
|
+
return columns.map((column) => {
|
|
79
|
+
let missing = 0;
|
|
80
|
+
const counts = /* @__PURE__ */ new Map();
|
|
81
|
+
for (const row of rows) {
|
|
82
|
+
const value = _nullishCoalesce(row[column], () => ( ""));
|
|
83
|
+
if (!value.trim()) {
|
|
84
|
+
missing += 1;
|
|
85
|
+
} else {
|
|
86
|
+
counts.set(value, (_nullishCoalesce(counts.get(value), () => ( 0))) + 1);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
const present = rows.length - missing;
|
|
90
|
+
const ranked = [...counts.entries()].sort((a, b) => b[1] - a[1]);
|
|
91
|
+
const top = counts.size < present ? ranked.slice(0, 3) : [];
|
|
92
|
+
const topCount = top.reduce((sum, [, count]) => sum + count, 0);
|
|
93
|
+
return {
|
|
94
|
+
column,
|
|
95
|
+
present,
|
|
96
|
+
missing,
|
|
97
|
+
present_percent: rows.length ? Math.round(present / rows.length * 100) : 0,
|
|
98
|
+
unique: counts.size,
|
|
99
|
+
top_values: top.map(([value, count]) => ({
|
|
100
|
+
value,
|
|
101
|
+
count,
|
|
102
|
+
percent: rows.length ? Math.round(count / rows.length * 100) : 0
|
|
103
|
+
})),
|
|
104
|
+
other_count: top.length > 0 ? present - topCount : 0
|
|
105
|
+
};
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
function summaryDisplayRows(summaries) {
|
|
109
|
+
return summaries.map((summary) => ({
|
|
110
|
+
column: summary.column,
|
|
111
|
+
present: String(summary.present),
|
|
112
|
+
missing: String(summary.missing),
|
|
113
|
+
present_percent: `${summary.present_percent}%`,
|
|
114
|
+
unique: String(summary.unique),
|
|
115
|
+
top_values: summary.top_values.map(({ value, count, percent }) => `${value}: ${count} (${percent}%)`).join(", "),
|
|
116
|
+
other_count: String(summary.other_count)
|
|
117
|
+
}));
|
|
118
|
+
}
|
|
119
|
+
function renderTable(rows, totalRows, verbose, footer = `showing ${rows.length} row(s) of ${totalRows}`) {
|
|
120
|
+
const columns = Object.keys(_nullishCoalesce(rows[0], () => ( {})));
|
|
121
|
+
if (columns.length === 0) return "No rows.";
|
|
122
|
+
const widths = Object.fromEntries(
|
|
123
|
+
columns.map((column) => [
|
|
124
|
+
column,
|
|
125
|
+
Math.max(
|
|
126
|
+
column.length,
|
|
127
|
+
...rows.map((row) => {
|
|
128
|
+
const value = _nullishCoalesce(row[column], () => ( ""));
|
|
129
|
+
return (verbose ? value : _chunkF35VOIQLjs.clip.call(void 0, value, 42)).length;
|
|
130
|
+
})
|
|
131
|
+
)
|
|
132
|
+
])
|
|
133
|
+
);
|
|
134
|
+
const header = columns.map((column) => column.padEnd(widths[column])).join(" | ");
|
|
135
|
+
const divider = columns.map((column) => "-".repeat(widths[column])).join("-+-");
|
|
136
|
+
const body = rows.map(
|
|
137
|
+
(row) => columns.map((column) => {
|
|
138
|
+
const raw = _nullishCoalesce(row[column], () => ( ""));
|
|
139
|
+
const display = verbose ? raw : _chunkF35VOIQLjs.clip.call(void 0, raw, 42);
|
|
140
|
+
return display.padEnd(widths[column]);
|
|
141
|
+
}).join(" | ")
|
|
142
|
+
);
|
|
143
|
+
return [header, divider, ...body, "", footer].join("\n");
|
|
144
|
+
}
|
|
145
|
+
async function handleCsvShow(path, options, command) {
|
|
146
|
+
if (path !== void 0 && options.csv !== void 0) {
|
|
147
|
+
command.error(
|
|
148
|
+
"Specify one CSV path: deepline csv show <path>. Do not combine it with --csv.",
|
|
149
|
+
{ exitCode: 2 }
|
|
150
|
+
);
|
|
151
|
+
}
|
|
152
|
+
const csvPath = _nullishCoalesce(path, () => ( options.csv));
|
|
153
|
+
if (!csvPath) {
|
|
154
|
+
command.error(
|
|
155
|
+
"Missing CSV path. Usage: deepline csv show <path> [options]",
|
|
156
|
+
{ exitCode: 2 }
|
|
157
|
+
);
|
|
158
|
+
}
|
|
159
|
+
const allRows = _chunkF35VOIQLjs.readCsvRows.call(void 0, csvPath);
|
|
160
|
+
const [rowStart, rowEnd] = parseRowRange(options.rows);
|
|
161
|
+
const rows = options.summary && options.rows === void 0 ? allRows : selectRows(allRows, rowStart, rowEnd);
|
|
162
|
+
const { rows: selected, columns } = selectColumns(
|
|
163
|
+
rows,
|
|
164
|
+
options.columns,
|
|
165
|
+
options.excludeColumns,
|
|
166
|
+
Object.keys(_nullishCoalesce(allRows[0], () => ( {})))
|
|
167
|
+
);
|
|
168
|
+
const format = _nullishCoalesce(options.format, () => ( "json"));
|
|
169
|
+
if (options.summary) {
|
|
170
|
+
const summaries = summarizeColumns(selected, columns);
|
|
171
|
+
if (format === "json") {
|
|
172
|
+
_chunkF35VOIQLjs.printJson.call(void 0, {
|
|
173
|
+
rows: summaries,
|
|
174
|
+
total_rows: selected.length,
|
|
175
|
+
source_total_rows: allRows.length
|
|
176
|
+
});
|
|
177
|
+
return;
|
|
178
|
+
}
|
|
179
|
+
const displayRows = summaryDisplayRows(summaries);
|
|
180
|
+
if (format === "csv") {
|
|
181
|
+
process.stdout.write(_chunkF35VOIQLjs.csvStringFromRows.call(void 0, displayRows));
|
|
182
|
+
return;
|
|
183
|
+
}
|
|
184
|
+
process.stdout.write(
|
|
185
|
+
`${renderTable(
|
|
186
|
+
displayRows,
|
|
187
|
+
selected.length,
|
|
188
|
+
Boolean(options.verbose),
|
|
189
|
+
`summarized ${summaries.length} column(s) across ${selected.length} row(s) of ${allRows.length}`
|
|
190
|
+
)}
|
|
191
|
+
`
|
|
192
|
+
);
|
|
193
|
+
return;
|
|
194
|
+
}
|
|
195
|
+
if (format === "json") {
|
|
196
|
+
_chunkF35VOIQLjs.printJson.call(void 0, {
|
|
197
|
+
rows: selected.map((row, index) => ({ __row: rowStart + index, ...row }))
|
|
198
|
+
});
|
|
199
|
+
return;
|
|
200
|
+
}
|
|
201
|
+
if (format === "csv") {
|
|
202
|
+
const columns2 = Object.keys(_nullishCoalesce(selected[0], () => ( {})));
|
|
203
|
+
process.stdout.write(`${columns2.join(",")}
|
|
204
|
+
`);
|
|
205
|
+
for (const row of selected) {
|
|
206
|
+
process.stdout.write(
|
|
207
|
+
`${columns2.map((column) => JSON.stringify(_nullishCoalesce(row[column], () => ( "")))).join(",")}
|
|
208
|
+
`
|
|
209
|
+
);
|
|
210
|
+
}
|
|
211
|
+
return;
|
|
212
|
+
}
|
|
213
|
+
process.stdout.write(
|
|
214
|
+
`${renderTable(selected, allRows.length, Boolean(options.verbose))}
|
|
215
|
+
`
|
|
216
|
+
);
|
|
217
|
+
}
|
|
218
|
+
function csvRenderStatePath() {
|
|
219
|
+
return _path.join.call(void 0, _os.homedir.call(void 0, ), ".local", "deepline", "runtime", "csv-render.json");
|
|
220
|
+
}
|
|
221
|
+
function csvRenderLogPath() {
|
|
222
|
+
return _path.join.call(void 0, _os.homedir.call(void 0, ), ".local", "deepline", "runtime", "csv-render.log");
|
|
223
|
+
}
|
|
224
|
+
function ensureCsvRenderStateDir() {
|
|
225
|
+
_fs.mkdirSync.call(void 0, _path.join.call(void 0, _os.homedir.call(void 0, ), ".local", "deepline", "runtime"), {
|
|
226
|
+
recursive: true
|
|
227
|
+
});
|
|
228
|
+
}
|
|
229
|
+
function readCsvRenderState() {
|
|
230
|
+
try {
|
|
231
|
+
const parsed = JSON.parse(_fs.readFileSync.call(void 0, csvRenderStatePath(), "utf8"));
|
|
232
|
+
return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : {};
|
|
233
|
+
} catch (e) {
|
|
234
|
+
return {};
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
function writeCsvRenderState(state) {
|
|
238
|
+
ensureCsvRenderStateDir();
|
|
239
|
+
_fs.writeFileSync.call(void 0, csvRenderStatePath(), `${JSON.stringify(state, null, 2)}
|
|
240
|
+
`);
|
|
241
|
+
}
|
|
242
|
+
function parseCsvRenderPort(raw) {
|
|
243
|
+
const value = Number.parseInt(String(_nullishCoalesce(raw, () => ( "4174"))).replace(/^:/, ""), 10);
|
|
244
|
+
if (!Number.isInteger(value) || value <= 0 || value > 65535) {
|
|
245
|
+
throw new Error(`Invalid --port value: ${_nullishCoalesce(raw, () => ( ""))}`);
|
|
246
|
+
}
|
|
247
|
+
return value;
|
|
248
|
+
}
|
|
249
|
+
function processAlive(pid) {
|
|
250
|
+
if (!Number.isInteger(pid) || pid <= 0) {
|
|
251
|
+
return false;
|
|
252
|
+
}
|
|
253
|
+
try {
|
|
254
|
+
process.kill(pid, 0);
|
|
255
|
+
return true;
|
|
256
|
+
} catch (e2) {
|
|
257
|
+
return false;
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
function isOwnedCsvRenderHealth(health, state) {
|
|
261
|
+
return Boolean(_optionalChain([health, 'optionalAccess', _3 => _3.ok])) && Number.isInteger(state.pid) && _optionalChain([health, 'optionalAccess', _4 => _4.pid]) === state.pid && Boolean(state.token) && _optionalChain([health, 'optionalAccess', _5 => _5.token]) === state.token;
|
|
262
|
+
}
|
|
263
|
+
async function fetchCsvRenderHealth(url) {
|
|
264
|
+
try {
|
|
265
|
+
const response = await fetch(`${url}/health`);
|
|
266
|
+
if (!response.ok) {
|
|
267
|
+
return null;
|
|
268
|
+
}
|
|
269
|
+
const parsed = await response.json();
|
|
270
|
+
return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : null;
|
|
271
|
+
} catch (e3) {
|
|
272
|
+
return null;
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
async function waitForRenderHealth(url, state) {
|
|
276
|
+
const deadline = Date.now() + 15e3;
|
|
277
|
+
while (Date.now() < deadline) {
|
|
278
|
+
if (isOwnedCsvRenderHealth(await fetchCsvRenderHealth(url), state)) {
|
|
279
|
+
return true;
|
|
280
|
+
}
|
|
281
|
+
if (state.pid && !processAlive(state.pid)) {
|
|
282
|
+
return false;
|
|
283
|
+
}
|
|
284
|
+
await new Promise((resolveDelay) => setTimeout(resolveDelay, 100));
|
|
285
|
+
}
|
|
286
|
+
return false;
|
|
287
|
+
}
|
|
288
|
+
async function waitForRenderStopped(url) {
|
|
289
|
+
const deadline = Date.now() + 2e3;
|
|
290
|
+
while (Date.now() < deadline) {
|
|
291
|
+
try {
|
|
292
|
+
await fetch(`${url}/health`);
|
|
293
|
+
} catch (e4) {
|
|
294
|
+
return;
|
|
295
|
+
}
|
|
296
|
+
await new Promise((resolveDelay) => setTimeout(resolveDelay, 100));
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
var CSV_RENDER_SERVER_SOURCE = String.raw`
|
|
300
|
+
const http = require('node:http');
|
|
301
|
+
const fs = require('node:fs');
|
|
302
|
+
const path = require('node:path');
|
|
303
|
+
|
|
304
|
+
const port = Number.parseInt(process.env.DEEPLINE_CSV_RENDER_PORT || '4174', 10);
|
|
305
|
+
const csvPath = process.env.DEEPLINE_CSV_RENDER_CSV || '';
|
|
306
|
+
const token = process.env.DEEPLINE_CSV_RENDER_TOKEN || '';
|
|
307
|
+
|
|
308
|
+
function send(res, status, contentType, body) {
|
|
309
|
+
res.writeHead(status, {
|
|
310
|
+
'content-type': contentType,
|
|
311
|
+
'cache-control': 'no-store',
|
|
312
|
+
});
|
|
313
|
+
res.end(body);
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
function readCsvText() {
|
|
317
|
+
if (!csvPath) return '';
|
|
318
|
+
try {
|
|
319
|
+
return fs.readFileSync(csvPath, 'utf8');
|
|
320
|
+
} catch (error) {
|
|
321
|
+
return 'Unable to read CSV: ' + (error && error.message ? error.message : String(error));
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
const server = http.createServer((req, res) => {
|
|
326
|
+
const url = new URL(req.url || '/', 'http://127.0.0.1:' + port);
|
|
327
|
+
if (url.pathname === '/health') {
|
|
328
|
+
send(res, 200, 'application/json', JSON.stringify({ ok: true, pid: process.pid, csvPath, token }));
|
|
329
|
+
return;
|
|
330
|
+
}
|
|
331
|
+
if (url.pathname === '/csv.txt') {
|
|
332
|
+
send(res, 200, 'text/plain; charset=utf-8', readCsvText());
|
|
333
|
+
return;
|
|
334
|
+
}
|
|
335
|
+
if (url.pathname === '/csv.json') {
|
|
336
|
+
send(res, 200, 'application/json', JSON.stringify({ csvPath, text: readCsvText() }));
|
|
337
|
+
return;
|
|
338
|
+
}
|
|
339
|
+
const title = csvPath ? path.basename(csvPath) : 'CSV renderer';
|
|
340
|
+
const escapedTitle = title.replace(/[&<>"]/g, (ch) => ({ '&': '&', '<': '<', '>': '>', '"': '"' }[ch]));
|
|
341
|
+
const escapedCsv = readCsvText().replace(/[&<>]/g, (ch) => ({ '&': '&', '<': '<', '>': '>' }[ch]));
|
|
342
|
+
send(res, 200, 'text/html; charset=utf-8', '<!doctype html><html><head><meta charset="utf-8"><title>' + escapedTitle + '</title><style>body{font:14px system-ui,sans-serif;margin:24px}pre{white-space:pre-wrap;border:1px solid #ddd;padding:16px;border-radius:8px}</style></head><body><h1>' + escapedTitle + '</h1><pre>' + escapedCsv + '</pre></body></html>');
|
|
343
|
+
});
|
|
344
|
+
|
|
345
|
+
server.listen(port, '127.0.0.1');
|
|
346
|
+
server.on('error', (error) => {
|
|
347
|
+
console.error(error && error.stack ? error.stack : error);
|
|
348
|
+
process.exit(1);
|
|
349
|
+
});
|
|
350
|
+
process.on('SIGTERM', () => server.close(() => process.exit(0)));
|
|
351
|
+
process.on('SIGINT', () => server.close(() => process.exit(0)));
|
|
352
|
+
`;
|
|
353
|
+
async function openBrowser(url) {
|
|
354
|
+
const opener = process.platform === "darwin" ? "open" : process.platform === "win32" ? "cmd" : "xdg-open";
|
|
355
|
+
const args = process.platform === "win32" ? ["/c", "start", "", url] : [url];
|
|
356
|
+
const child = _child_process.spawn.call(void 0, opener, args, { detached: true, stdio: "ignore" });
|
|
357
|
+
child.on("error", () => {
|
|
358
|
+
});
|
|
359
|
+
child.unref();
|
|
360
|
+
}
|
|
361
|
+
async function handleCsvRenderStart(options) {
|
|
362
|
+
const port = parseCsvRenderPort(options.port);
|
|
363
|
+
const csvPath = options.csv ? _path.resolve.call(void 0, options.csv) : "";
|
|
364
|
+
if (csvPath && !_fs.existsSync.call(void 0, csvPath)) {
|
|
365
|
+
throw new Error(`CSV not found: ${csvPath}`);
|
|
366
|
+
}
|
|
367
|
+
const url = `http://127.0.0.1:${port}`;
|
|
368
|
+
const existing = readCsvRenderState();
|
|
369
|
+
if (processAlive(existing.pid) && existing.url) {
|
|
370
|
+
const existingOwned = isOwnedCsvRenderHealth(
|
|
371
|
+
await fetchCsvRenderHealth(existing.url),
|
|
372
|
+
existing
|
|
373
|
+
);
|
|
374
|
+
const sameUrl = existing.url === url;
|
|
375
|
+
const sameCsv = !csvPath || existing.csvPath === csvPath;
|
|
376
|
+
if (existingOwned && (!sameUrl || !sameCsv)) {
|
|
377
|
+
try {
|
|
378
|
+
process.kill(existing.pid, "SIGTERM");
|
|
379
|
+
} catch (e5) {
|
|
380
|
+
}
|
|
381
|
+
await waitForRenderStopped(existing.url);
|
|
382
|
+
if (processAlive(existing.pid)) {
|
|
383
|
+
try {
|
|
384
|
+
process.kill(existing.pid, "SIGKILL");
|
|
385
|
+
} catch (e6) {
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
_fs.rmSync.call(void 0, csvRenderStatePath(), { force: true });
|
|
389
|
+
} else if (existingOwned) {
|
|
390
|
+
process.stdout.write(
|
|
391
|
+
"CSV render is already running; reusing current process.\n"
|
|
392
|
+
);
|
|
393
|
+
process.stdout.write(`Render URL: ${existing.url}
|
|
394
|
+
`);
|
|
395
|
+
if (options.open) {
|
|
396
|
+
await openBrowser(existing.url);
|
|
397
|
+
}
|
|
398
|
+
return;
|
|
399
|
+
} else {
|
|
400
|
+
_fs.rmSync.call(void 0, csvRenderStatePath(), { force: true });
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
ensureCsvRenderStateDir();
|
|
404
|
+
const logPath = csvRenderLogPath();
|
|
405
|
+
const logFd = _fs.openSync.call(void 0, logPath, "w");
|
|
406
|
+
const token = _crypto.randomUUID.call(void 0, );
|
|
407
|
+
const child = _child_process.spawn.call(void 0, process.execPath, ["-e", CSV_RENDER_SERVER_SOURCE], {
|
|
408
|
+
detached: true,
|
|
409
|
+
stdio: ["ignore", logFd, logFd],
|
|
410
|
+
env: {
|
|
411
|
+
...process.env,
|
|
412
|
+
DEEPLINE_CSV_RENDER_PORT: String(port),
|
|
413
|
+
DEEPLINE_CSV_RENDER_CSV: csvPath,
|
|
414
|
+
DEEPLINE_CSV_RENDER_TOKEN: token
|
|
415
|
+
}
|
|
416
|
+
});
|
|
417
|
+
_fs.closeSync.call(void 0, logFd);
|
|
418
|
+
child.unref();
|
|
419
|
+
const state = {
|
|
420
|
+
pid: _nullishCoalesce(child.pid, () => ( null)),
|
|
421
|
+
port,
|
|
422
|
+
url,
|
|
423
|
+
csvPath,
|
|
424
|
+
logPath,
|
|
425
|
+
startedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
426
|
+
token
|
|
427
|
+
};
|
|
428
|
+
const started = await waitForRenderHealth(url, state);
|
|
429
|
+
if (!started) {
|
|
430
|
+
if (processAlive(child.pid)) {
|
|
431
|
+
process.kill(child.pid, "SIGTERM");
|
|
432
|
+
}
|
|
433
|
+
let detail = "";
|
|
434
|
+
try {
|
|
435
|
+
const log = _fs.readFileSync.call(void 0, logPath, "utf8").trim();
|
|
436
|
+
if (log) {
|
|
437
|
+
detail = `
|
|
438
|
+
CSV render log:
|
|
439
|
+
${_chunkF35VOIQLjs.clip.call(void 0, log, 2e3)}`;
|
|
440
|
+
}
|
|
441
|
+
} catch (e7) {
|
|
442
|
+
}
|
|
443
|
+
throw new Error(
|
|
444
|
+
`Timed out waiting for CSV render to start at ${url}.${detail}`
|
|
445
|
+
);
|
|
446
|
+
}
|
|
447
|
+
writeCsvRenderState(state);
|
|
448
|
+
_fs.writeFileSync.call(void 0,
|
|
449
|
+
logPath,
|
|
450
|
+
`CSV render started at ${state.startedAt} on ${url}
|
|
451
|
+
`
|
|
452
|
+
);
|
|
453
|
+
process.stdout.write("CSV render is running.\n");
|
|
454
|
+
process.stdout.write(`Render PID: ${child.pid}
|
|
455
|
+
`);
|
|
456
|
+
process.stdout.write(`Render URL: ${url}
|
|
457
|
+
`);
|
|
458
|
+
if (options.open) {
|
|
459
|
+
await openBrowser(url);
|
|
460
|
+
}
|
|
461
|
+
}
|
|
462
|
+
async function handleCsvRenderStatus(options) {
|
|
463
|
+
const state = readCsvRenderState();
|
|
464
|
+
const processExists = processAlive(state.pid);
|
|
465
|
+
const url = _nullishCoalesce(state.url, () => ( ""));
|
|
466
|
+
let health = "unknown";
|
|
467
|
+
let owned = false;
|
|
468
|
+
if (processExists && url) {
|
|
469
|
+
const renderHealth = await fetchCsvRenderHealth(url);
|
|
470
|
+
owned = isOwnedCsvRenderHealth(renderHealth, state);
|
|
471
|
+
health = owned ? "healthy" : "unhealthy";
|
|
472
|
+
}
|
|
473
|
+
const status = processExists && owned ? "running" : processExists ? "unhealthy" : "stopped";
|
|
474
|
+
const payload = {
|
|
475
|
+
status,
|
|
476
|
+
pid: owned ? state.pid : null,
|
|
477
|
+
process_alive: owned,
|
|
478
|
+
url,
|
|
479
|
+
log_path: _nullishCoalesce(state.logPath, () => ( "")),
|
|
480
|
+
mode: "background",
|
|
481
|
+
started_at: owned ? _nullishCoalesce(state.startedAt, () => ( "")) : "",
|
|
482
|
+
health_status: health,
|
|
483
|
+
health_checked_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
484
|
+
stale_cleaned: true
|
|
485
|
+
};
|
|
486
|
+
const lines = [`Render Status: ${payload.status}`];
|
|
487
|
+
if (payload.pid) lines.push(`Render PID: ${payload.pid}`);
|
|
488
|
+
if (payload.url) lines.push(`Render URL: ${payload.url}`);
|
|
489
|
+
lines.push(`Render Health: ${payload.health_status}`);
|
|
490
|
+
_chunkF35VOIQLjs.printCommandEnvelope.call(void 0, payload, {
|
|
491
|
+
json: options.json,
|
|
492
|
+
text: `${lines.join("\n")}
|
|
493
|
+
`
|
|
494
|
+
});
|
|
495
|
+
}
|
|
496
|
+
function terminateRenderProcess(pid) {
|
|
497
|
+
try {
|
|
498
|
+
process.kill(pid, "SIGTERM");
|
|
499
|
+
} catch (e8) {
|
|
500
|
+
return false;
|
|
501
|
+
}
|
|
502
|
+
return true;
|
|
503
|
+
}
|
|
504
|
+
async function handleCsvRenderStop(options) {
|
|
505
|
+
const state = readCsvRenderState();
|
|
506
|
+
const stopped = [];
|
|
507
|
+
const failed = [];
|
|
508
|
+
const owned = processAlive(state.pid) && Boolean(state.url) && isOwnedCsvRenderHealth(await fetchCsvRenderHealth(state.url), state);
|
|
509
|
+
if (owned && processAlive(state.pid)) {
|
|
510
|
+
if (terminateRenderProcess(state.pid)) {
|
|
511
|
+
stopped.push(state.pid);
|
|
512
|
+
} else {
|
|
513
|
+
failed.push(state.pid);
|
|
514
|
+
}
|
|
515
|
+
}
|
|
516
|
+
_fs.rmSync.call(void 0, csvRenderStatePath(), { force: true });
|
|
517
|
+
const payload = {
|
|
518
|
+
ok: failed.length === 0,
|
|
519
|
+
stopped_count: stopped.length,
|
|
520
|
+
failed_count: failed.length,
|
|
521
|
+
stopped_pids: stopped,
|
|
522
|
+
failed_pids: failed
|
|
523
|
+
};
|
|
524
|
+
const text = stopped.length > 0 ? `Stopped CSV render process(es): ${stopped.join(" ")}
|
|
525
|
+
` : "No running CSV render process found.\n";
|
|
526
|
+
_chunkF35VOIQLjs.printCommandEnvelope.call(void 0, payload, { json: options.json, text });
|
|
527
|
+
}
|
|
528
|
+
async function handleCsvRender(action, options) {
|
|
529
|
+
const normalized = _nullishCoalesce(action, () => ( "start"));
|
|
530
|
+
if (normalized === "start") {
|
|
531
|
+
await handleCsvRenderStart(options);
|
|
532
|
+
return;
|
|
533
|
+
}
|
|
534
|
+
if (normalized === "status") {
|
|
535
|
+
await handleCsvRenderStatus(options);
|
|
536
|
+
return;
|
|
537
|
+
}
|
|
538
|
+
if (normalized === "stop") {
|
|
539
|
+
await handleCsvRenderStop(options);
|
|
540
|
+
return;
|
|
541
|
+
}
|
|
542
|
+
throw new Error(`Unknown csv render action: ${normalized}`);
|
|
543
|
+
}
|
|
544
|
+
function registerCsvCommands(program) {
|
|
545
|
+
const csv = program.command("csv").description("Inspect local CSV files.").addHelpText(
|
|
546
|
+
"after",
|
|
547
|
+
`
|
|
548
|
+
Notes:
|
|
549
|
+
Local-only inspection helpers. These commands do not upload CSV files or call
|
|
550
|
+
Deepline APIs.
|
|
551
|
+
|
|
552
|
+
Examples:
|
|
553
|
+
deepline csv show leads.csv --rows 0:10 --format table
|
|
554
|
+
deepline csv show leads.csv --summary
|
|
555
|
+
`
|
|
556
|
+
);
|
|
557
|
+
csv.command("show").argument("[path]", "Input CSV path").usage("<path> [options]").allowExcessArguments(false).description("Display rows from a CSV file in json, csv, or table form.").addHelpText(
|
|
558
|
+
"after",
|
|
559
|
+
`
|
|
560
|
+
Notes:
|
|
561
|
+
Reads a local CSV path. By default, rows show 0:19 (first 20 rows), while
|
|
562
|
+
--summary analyzes the whole file. An explicit --rows start:end range applies
|
|
563
|
+
to either mode. Column selection and --format apply to both; JSON is default.
|
|
564
|
+
|
|
565
|
+
Examples:
|
|
566
|
+
deepline csv show leads.csv
|
|
567
|
+
deepline csv show leads.csv --rows 20:39 --columns name,email --format table
|
|
568
|
+
deepline csv show leads.csv --exclude-columns raw_response,attempts --format table
|
|
569
|
+
deepline csv show leads.csv --summary
|
|
570
|
+
`
|
|
571
|
+
).addOption(
|
|
572
|
+
new (0, _commander.Option)("--csv <path>", "Input CSV path (legacy alias)").hideHelp()
|
|
573
|
+
).option("--format <format>", "Output format: json, csv, or table", "json").option(
|
|
574
|
+
"--rows <range>",
|
|
575
|
+
"Inclusive row range start:end (show defaults to 0:19)"
|
|
576
|
+
).option("--columns <names>", "Comma-separated column names to include").option("--exclude-columns <names>", "Comma-separated column names to omit").option(
|
|
577
|
+
"--summary",
|
|
578
|
+
"Summarize selected columns as one row per column; defaults to all rows"
|
|
579
|
+
).option("--verbose", "Do not truncate long values in table output").action(handleCsvShow);
|
|
580
|
+
const render = csv.command("render").description("Start, inspect, or stop a local CSV renderer.").argument("[action]", "start, status, or stop", "start").option("--port <port>", "Local renderer port.", "4174").option("--csv <path>", "CSV path to display.").option("--open", "Open the renderer in a browser.").option("--json", "Emit JSON for status/stop.").action(handleCsvRender);
|
|
581
|
+
render.showHelpAfterError();
|
|
582
|
+
}
|
|
583
|
+
|
|
584
|
+
|
|
585
|
+
exports.registerCsvCommands = registerCsvCommands;
|