@gurulu/cli 0.4.6 → 1.0.0

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 (180) hide show
  1. package/LICENSE +92 -0
  2. package/README.md +35 -106
  3. package/dist/bin.d.ts +3 -0
  4. package/dist/bin.d.ts.map +1 -0
  5. package/dist/bin.js +25410 -0
  6. package/dist/commands/auth.d.ts +23 -20
  7. package/dist/commands/auth.d.ts.map +1 -0
  8. package/dist/commands/doctor.d.ts +20 -6
  9. package/dist/commands/doctor.d.ts.map +1 -0
  10. package/dist/commands/init.d.ts +25 -11
  11. package/dist/commands/init.d.ts.map +1 -0
  12. package/dist/commands/pull.d.ts +13 -0
  13. package/dist/commands/pull.d.ts.map +1 -0
  14. package/dist/commands/push.d.ts +40 -0
  15. package/dist/commands/push.d.ts.map +1 -0
  16. package/dist/commands/validate.d.ts +36 -0
  17. package/dist/commands/validate.d.ts.map +1 -0
  18. package/dist/index.d.ts +4 -1
  19. package/dist/index.d.ts.map +1 -0
  20. package/dist/index.js +24985 -853
  21. package/dist/lib/api.d.ts +139 -0
  22. package/dist/lib/api.d.ts.map +1 -0
  23. package/dist/lib/codegen.d.ts +4 -0
  24. package/dist/lib/codegen.d.ts.map +1 -0
  25. package/dist/lib/config.d.ts +43 -0
  26. package/dist/lib/config.d.ts.map +1 -0
  27. package/package.json +40 -20
  28. package/bin/gurulu.js +0 -2
  29. package/dist/api-client.d.ts +0 -33
  30. package/dist/api-client.js +0 -175
  31. package/dist/commands/add-server.d.ts +0 -9
  32. package/dist/commands/add-server.js +0 -162
  33. package/dist/commands/alerts.d.ts +0 -27
  34. package/dist/commands/alerts.js +0 -309
  35. package/dist/commands/api-keys.d.ts +0 -20
  36. package/dist/commands/api-keys.js +0 -130
  37. package/dist/commands/attribution.d.ts +0 -22
  38. package/dist/commands/attribution.js +0 -111
  39. package/dist/commands/audiences.d.ts +0 -23
  40. package/dist/commands/audiences.js +0 -243
  41. package/dist/commands/audit.d.ts +0 -20
  42. package/dist/commands/audit.js +0 -130
  43. package/dist/commands/auth.js +0 -249
  44. package/dist/commands/chat.d.ts +0 -18
  45. package/dist/commands/chat.js +0 -117
  46. package/dist/commands/config.d.ts +0 -10
  47. package/dist/commands/config.js +0 -92
  48. package/dist/commands/consent.d.ts +0 -27
  49. package/dist/commands/consent.js +0 -233
  50. package/dist/commands/conversion-paths.d.ts +0 -19
  51. package/dist/commands/conversion-paths.js +0 -55
  52. package/dist/commands/db.d.ts +0 -25
  53. package/dist/commands/db.js +0 -330
  54. package/dist/commands/destinations.d.ts +0 -20
  55. package/dist/commands/destinations.js +0 -191
  56. package/dist/commands/doctor.js +0 -360
  57. package/dist/commands/errors.d.ts +0 -27
  58. package/dist/commands/errors.js +0 -121
  59. package/dist/commands/events.d.ts +0 -33
  60. package/dist/commands/events.js +0 -349
  61. package/dist/commands/experiments.d.ts +0 -22
  62. package/dist/commands/experiments.js +0 -264
  63. package/dist/commands/funnels.d.ts +0 -17
  64. package/dist/commands/funnels.js +0 -203
  65. package/dist/commands/goals.d.ts +0 -18
  66. package/dist/commands/goals.js +0 -214
  67. package/dist/commands/heatmap.d.ts +0 -27
  68. package/dist/commands/heatmap.js +0 -112
  69. package/dist/commands/identity.d.ts +0 -29
  70. package/dist/commands/identity.js +0 -328
  71. package/dist/commands/init.js +0 -215
  72. package/dist/commands/insights.d.ts +0 -10
  73. package/dist/commands/insights.js +0 -65
  74. package/dist/commands/install.d.ts +0 -259
  75. package/dist/commands/install.js +0 -1590
  76. package/dist/commands/login.d.ts +0 -20
  77. package/dist/commands/login.js +0 -170
  78. package/dist/commands/logout.d.ts +0 -10
  79. package/dist/commands/logout.js +0 -41
  80. package/dist/commands/playground.d.ts +0 -11
  81. package/dist/commands/playground.js +0 -47
  82. package/dist/commands/releases.d.ts +0 -17
  83. package/dist/commands/releases.js +0 -54
  84. package/dist/commands/replay.d.ts +0 -18
  85. package/dist/commands/replay.js +0 -64
  86. package/dist/commands/secrets.d.ts +0 -19
  87. package/dist/commands/secrets.js +0 -145
  88. package/dist/commands/sites.d.ts +0 -18
  89. package/dist/commands/sites.js +0 -139
  90. package/dist/commands/skad.d.ts +0 -18
  91. package/dist/commands/skad.js +0 -53
  92. package/dist/commands/sourcemap.d.ts +0 -33
  93. package/dist/commands/sourcemap.js +0 -204
  94. package/dist/commands/status.d.ts +0 -7
  95. package/dist/commands/status.js +0 -136
  96. package/dist/commands/upgrade.d.ts +0 -21
  97. package/dist/commands/upgrade.js +0 -183
  98. package/dist/commands/warehouse.d.ts +0 -20
  99. package/dist/commands/warehouse.js +0 -65
  100. package/dist/commands/warehouses.d.ts +0 -17
  101. package/dist/commands/warehouses.js +0 -182
  102. package/dist/commands/watch.d.ts +0 -45
  103. package/dist/commands/watch.js +0 -258
  104. package/dist/commands/whoami.d.ts +0 -9
  105. package/dist/commands/whoami.js +0 -50
  106. package/dist/config.d.ts +0 -75
  107. package/dist/config.js +0 -329
  108. package/dist/frameworks/detect.d.ts +0 -8
  109. package/dist/frameworks/detect.js +0 -444
  110. package/dist/install-intent-proposal.d.ts +0 -99
  111. package/dist/install-intent-proposal.js +0 -202
  112. package/dist/utils/api.d.ts +0 -20
  113. package/dist/utils/api.js +0 -47
  114. package/dist/utils/config.d.ts +0 -13
  115. package/dist/utils/config.js +0 -30
  116. package/dist/utils/confirm.d.ts +0 -17
  117. package/dist/utils/confirm.js +0 -40
  118. package/dist/utils/dry-run.d.ts +0 -20
  119. package/dist/utils/dry-run.js +0 -67
  120. package/dist/utils/from-file.d.ts +0 -9
  121. package/dist/utils/from-file.js +0 -72
  122. package/dist/utils/redact.d.ts +0 -14
  123. package/dist/utils/redact.js +0 -48
  124. package/dist/utils/ui.d.ts +0 -14
  125. package/dist/utils/ui.js +0 -59
  126. package/scripts/.gitkeep +0 -0
  127. package/scripts/README-gurulu-agentic-install.md +0 -114
  128. package/scripts/README-gurulu-scan.md +0 -98
  129. package/scripts/audit-cli-scopes.mjs +0 -204
  130. package/scripts/backfill-tenant-id.mjs +0 -172
  131. package/scripts/backfill-tenant-links.ts +0 -252
  132. package/scripts/backup-clickhouse.sh +0 -27
  133. package/scripts/backup-postgres.sh +0 -19
  134. package/scripts/bootstrap-runtime-schema.mjs +0 -87
  135. package/scripts/bootstrap-stripe.mjs +0 -158
  136. package/scripts/gurulu-agentic-install.lib.cjs +0 -762
  137. package/scripts/gurulu-agentic-install.mjs +0 -623
  138. package/scripts/gurulu-scan.lib.cjs +0 -1509
  139. package/scripts/gurulu-scan.mjs +0 -91
  140. package/scripts/gurulu-verify-install.lib.cjs +0 -334
  141. package/scripts/gurulu-verify-install.mjs +0 -59
  142. package/scripts/init-ssl.sh +0 -26
  143. package/scripts/migrate-flow-graph-enums.sh +0 -86
  144. package/scripts/monitor-disk.sh +0 -24
  145. package/scripts/patches/astro.patch.cjs +0 -74
  146. package/scripts/patches/auto-instrument/ast-helper.cjs +0 -480
  147. package/scripts/patches/auto-instrument/astro.cjs +0 -273
  148. package/scripts/patches/auto-instrument/express.cjs +0 -383
  149. package/scripts/patches/auto-instrument/fastify.cjs +0 -262
  150. package/scripts/patches/auto-instrument/hono.cjs +0 -392
  151. package/scripts/patches/auto-instrument/index.cjs +0 -80
  152. package/scripts/patches/auto-instrument/nestjs.cjs +0 -286
  153. package/scripts/patches/auto-instrument/nextjs-app-router.cjs +0 -345
  154. package/scripts/patches/auto-instrument/nextjs-pages.cjs +0 -361
  155. package/scripts/patches/auto-instrument/remix.cjs +0 -168
  156. package/scripts/patches/auto-instrument/sdk-helper-map.cjs +0 -241
  157. package/scripts/patches/auto-instrument/singleton-helper.cjs +0 -193
  158. package/scripts/patches/auto-instrument/sveltekit.cjs +0 -161
  159. package/scripts/patches/auto-instrument/vite-react.cjs +0 -37
  160. package/scripts/patches/auto-instrument/vue.cjs +0 -196
  161. package/scripts/patches/express.patch.cjs +0 -99
  162. package/scripts/patches/fastify.patch.cjs +0 -108
  163. package/scripts/patches/index.cjs +0 -300
  164. package/scripts/patches/nestjs.patch.cjs +0 -112
  165. package/scripts/patches/nextjs-app-router.patch.cjs +0 -97
  166. package/scripts/patches/nextjs-pages.patch.cjs +0 -97
  167. package/scripts/patches/remix.patch.cjs +0 -75
  168. package/scripts/patches/sveltekit.patch.cjs +0 -72
  169. package/scripts/patches/vite-react.patch.cjs +0 -73
  170. package/scripts/patches/vue.patch.cjs +0 -82
  171. package/scripts/renew-ssl.sh +0 -14
  172. package/scripts/resolve-migration.sh +0 -23
  173. package/scripts/seed-cli-dev-keys.mjs +0 -130
  174. package/scripts/seed-test-data.mjs +0 -391
  175. package/scripts/spike-browserless.ts +0 -65
  176. package/scripts/tenant-pivot-consistency-check.mjs +0 -205
  177. package/scripts/tenant-pivot-phase-3-cleanup.lib.cjs +0 -258
  178. package/scripts/tenant-pivot-phase-3-cleanup.mjs +0 -98
  179. package/scripts/test-identity-resolution.ts +0 -804
  180. package/scripts/validate-gurulu-schemas.mjs +0 -79
@@ -1,258 +0,0 @@
1
- // tenant-pivot-phase-3-cleanup.lib.cjs — destructive-cleanup logic for the
2
- // Phase 18 A4 tenant pivot phase 3 migration (drop `site_id` column).
3
- //
4
- // CommonJS so it can be `require()`-d by both the ESM CLI wrapper
5
- // (`scripts/tenant-pivot-phase-3-cleanup.mjs`) and the ts-jest test
6
- // (`tests/scripts-tenant-pivot-phase-3-cleanup.test.ts`). See the README
7
- // header in the .mjs wrapper for the operator-facing contract.
8
- //
9
- // IMPORTANT: This module exposes pure helpers and a CLI orchestrator. None of
10
- // it self-executes. The `.mjs` wrapper is the only thing with a top-level
11
- // `runCli()` call, gated on `import.meta.url === process.argv[1]`.
12
-
13
- 'use strict';
14
-
15
- const fs = require('node:fs').promises;
16
- const path = require('node:path');
17
- const readline = require('node:readline');
18
-
19
- // ---------------------------------------------------------------------------
20
- // Constants
21
- // ---------------------------------------------------------------------------
22
-
23
- // Every analytics table that still carries `site_id` after Phase 18 A4. See
24
- // docker/clickhouse/init/01_schema.sql for the canonical column definitions.
25
- // ORDER MATTERS for the dry-run output but not for execution.
26
- const AFFECTED_TABLES = [
27
- 'events_raw',
28
- 'flow_session_events',
29
- 'journey_events',
30
- 'cross_property_journeys',
31
- 'inferred_events',
32
- ];
33
-
34
- const LOG_PATH_DEFAULT = path.resolve(process.cwd(), 'logs', 'tenant-pivot-phase-3.log');
35
-
36
- // ---------------------------------------------------------------------------
37
- // Pure helpers
38
- // ---------------------------------------------------------------------------
39
-
40
- function buildDropColumnSql(table) {
41
- if (!table || typeof table !== 'string') {
42
- throw new Error('buildDropColumnSql: table is required');
43
- }
44
- // ClickHouse ALTER TABLE DROP COLUMN is implemented as a mutation on the
45
- // affected parts. Destructive and irreversible without a backup.
46
- return `ALTER TABLE ${table} DROP COLUMN IF EXISTS site_id`;
47
- }
48
-
49
- function buildRowCountSql(table) {
50
- return `SELECT count() AS c FROM ${table}`;
51
- }
52
-
53
- function parseArgs(argv) {
54
- const args = { apply: false, help: false, noConfirm: false };
55
- for (let i = 2; i < argv.length; i++) {
56
- const a = argv[i];
57
- if (a === '--apply') args.apply = true;
58
- else if (a === '--no-confirm') args.noConfirm = true;
59
- else if (a === '--help' || a === '-h') args.help = true;
60
- }
61
- return args;
62
- }
63
-
64
- function printHelp(out) {
65
- const log = out || console.log;
66
- log(
67
- [
68
- '',
69
- 'Usage: node scripts/tenant-pivot-phase-3-cleanup.mjs [--apply] [--no-confirm]',
70
- '',
71
- ' (default) DRY-RUN. Prints SQL + row counts. Touches nothing.',
72
- ' --apply Actually execute ALTER TABLE DROP COLUMN. Requires',
73
- ' an interactive `yes` confirmation from a human operator.',
74
- ' --no-confirm Skip the readline prompt (still requires --apply). For',
75
- ' automated test harnesses only — do NOT use in prod.',
76
- '',
77
- '⚠ This is a DESTRUCTIVE migration. Take a ClickHouse backup first.',
78
- '',
79
- ].join('\n'),
80
- );
81
- }
82
-
83
- // Real ClickHouse HTTP client — unit tests inject a stub via the runCli
84
- // `queryFn` parameter so this is never actually invoked under jest.
85
- async function clickhouseQuery(query, params = {}) {
86
- const CLICKHOUSE_URL = process.env.CLICKHOUSE_URL || 'http://localhost:8123';
87
- const CLICKHOUSE_DB = process.env.CLICKHOUSE_DATABASE || 'gurulu';
88
- const url = new URL(CLICKHOUSE_URL);
89
- url.searchParams.set('database', CLICKHOUSE_DB);
90
- url.searchParams.set('default_format', 'JSON');
91
- for (const [k, v] of Object.entries(params)) {
92
- url.searchParams.set(`param_${k}`, String(v));
93
- }
94
- const res = await fetch(url.toString(), {
95
- method: 'POST',
96
- body: query,
97
- headers: { 'Content-Type': 'text/plain' },
98
- });
99
- if (!res.ok) {
100
- throw new Error(`ClickHouse error ${res.status}: ${await res.text()}`);
101
- }
102
- return res.json();
103
- }
104
-
105
- async function safeRowCount(table, queryFn) {
106
- const fn = queryFn || clickhouseQuery;
107
- try {
108
- const res = await fn(buildRowCountSql(table));
109
- const row = (res && res.data && res.data[0]) || {};
110
- return Number(row.c != null ? row.c : (row.count != null ? row.count : 0));
111
- } catch (_err) {
112
- return null;
113
- }
114
- }
115
-
116
- async function buildPlan(queryFn) {
117
- const plan = [];
118
- for (const table of AFFECTED_TABLES) {
119
- const rowCount = await safeRowCount(table, queryFn);
120
- plan.push({ table, rowCount, sql: buildDropColumnSql(table) });
121
- }
122
- return plan;
123
- }
124
-
125
- function renderPlan(plan, mode) {
126
- const lines = [];
127
- lines.push(`# tenant-pivot-phase-3-cleanup mode=${mode} ts=${new Date().toISOString()}`);
128
- lines.push('');
129
- lines.push('Affected tables:');
130
- for (const step of plan) {
131
- const rc =
132
- step.rowCount === null || step.rowCount === undefined
133
- ? '(unknown)'
134
- : Number(step.rowCount).toLocaleString();
135
- lines.push(` • ${step.table} rows=${rc}`);
136
- lines.push(` ${step.sql}`);
137
- }
138
- lines.push('');
139
- return lines.join('\n');
140
- }
141
-
142
- async function appendLog(block, logPath) {
143
- const target = logPath || LOG_PATH_DEFAULT;
144
- await fs.mkdir(path.dirname(target), { recursive: true });
145
- await fs.appendFile(target, block + '\n', 'utf8');
146
- }
147
-
148
- // Interactive confirmation prompt. Defaults to a real readline interface;
149
- // tests inject `promptFn` to avoid touching stdin.
150
- async function confirmDestructive(promptFn) {
151
- const ask =
152
- promptFn ||
153
- function defaultAsk(q) {
154
- return new Promise((resolve) => {
155
- const rl = readline.createInterface({
156
- input: process.stdin,
157
- output: process.stdout,
158
- });
159
- rl.question(q, (ans) => {
160
- rl.close();
161
- resolve(ans);
162
- });
163
- });
164
- };
165
- const answer = await ask(
166
- '\n⚠ About to DROP COLUMN site_id from production analytics tables. Type "yes" to proceed: ',
167
- );
168
- return String(answer || '').trim().toLowerCase() === 'yes';
169
- }
170
-
171
- // ---------------------------------------------------------------------------
172
- // CLI orchestrator
173
- // ---------------------------------------------------------------------------
174
-
175
- async function runCli(opts) {
176
- const o = opts || {};
177
- const argv = o.argv || process.argv;
178
- const queryFn = o.queryFn || clickhouseQuery;
179
- const promptFn = o.promptFn;
180
- const log = o.log || console.log;
181
- const errorLog = o.errorLog || console.error;
182
- const logPath = o.logPath || LOG_PATH_DEFAULT;
183
-
184
- const args = parseArgs(argv);
185
- if (args.help) {
186
- printHelp(log);
187
- return { ok: true, mode: 'help' };
188
- }
189
-
190
- const mode = args.apply ? 'APPLY' : 'DRY-RUN';
191
- log(`[phase-3-cleanup] mode=${mode}`);
192
- log('[phase-3-cleanup] ⚠ This script is destructive. See the README header.');
193
-
194
- const plan = await buildPlan(queryFn);
195
- const rendered = renderPlan(plan, mode);
196
- log(rendered);
197
- try {
198
- await appendLog(rendered, logPath);
199
- } catch (err) {
200
- errorLog('[phase-3-cleanup] WARNING: failed to write migration log:', err);
201
- }
202
-
203
- if (!args.apply) {
204
- log('[phase-3-cleanup] dry-run complete. Re-run with --apply to actually drop columns.');
205
- return { ok: true, mode: 'dry-run', plan };
206
- }
207
-
208
- // --apply path: require either an interactive `yes` or the explicit
209
- // --no-confirm test-only flag.
210
- if (!args.noConfirm) {
211
- const confirmed = await confirmDestructive(promptFn);
212
- if (!confirmed) {
213
- errorLog('[phase-3-cleanup] confirmation declined; nothing was changed.');
214
- return { ok: false, mode: 'apply', reason: 'declined' };
215
- }
216
- } else {
217
- log('[phase-3-cleanup] --no-confirm set: skipping interactive prompt (test mode).');
218
- }
219
-
220
- const executed = [];
221
- for (const step of plan) {
222
- log(`[phase-3-cleanup] APPLY ${step.table}`);
223
- log(` ${step.sql}`);
224
- try {
225
- await queryFn(step.sql);
226
- executed.push(Object.assign({}, step, { status: 'ok' }));
227
- } catch (err) {
228
- errorLog(`[phase-3-cleanup] FAILED on ${step.table}:`, err);
229
- executed.push(Object.assign({}, step, { status: 'error', error: String(err) }));
230
- break;
231
- }
232
- }
233
-
234
- await appendLog(
235
- `# applied ts=${new Date().toISOString()}\n` +
236
- executed.map((s) => ` ${s.status} ${s.table} :: ${s.sql}`).join('\n') +
237
- '\n',
238
- logPath,
239
- );
240
-
241
- return { ok: executed.every((s) => s.status === 'ok'), mode: 'apply', executed };
242
- }
243
-
244
- module.exports = {
245
- AFFECTED_TABLES,
246
- LOG_PATH_DEFAULT,
247
- buildDropColumnSql,
248
- buildRowCountSql,
249
- parseArgs,
250
- printHelp,
251
- clickhouseQuery,
252
- safeRowCount,
253
- buildPlan,
254
- renderPlan,
255
- appendLog,
256
- confirmDestructive,
257
- runCli,
258
- };
@@ -1,98 +0,0 @@
1
- #!/usr/bin/env node
2
- /**
3
- * ============================================================================
4
- * README — DO NOT RUN AUTOMATICALLY. EVER.
5
- * ============================================================================
6
- *
7
- * Phase 18 A4 — Tenant pivot phase 3 cleanup script.
8
- *
9
- * This is a DESTRUCTIVE migration tool. It exists so an operator can, when
10
- * they are ready, drop the obsolete `site_id` column from the ClickHouse
11
- * analytics tables now that the tenant-first read path (Phase 18 A4) and
12
- * the tenant-first write path (Phase 17 B1) are both in production.
13
- *
14
- * ⚠ This script must NEVER be invoked by CI, pre-commit, deploy hooks,
15
- * ⚠ cron, AI agents, or anything other than a human operator who has
16
- * ⚠ taken a verified ClickHouse backup and read PHASE-18-ROADMAP.md §A4.
17
- *
18
- * Default behaviour (no flags) is a SAFE DRY-RUN: it prints exactly the
19
- * ALTER TABLE statements it would execute, fetches a current row count for
20
- * every affected table, and writes a markdown-friendly migration log to
21
- * `logs/tenant-pivot-phase-3.log`. It does NOT touch ClickHouse beyond the
22
- * read-only `SELECT count()` queries.
23
- *
24
- * Passing `--apply` is the only way to actually run the destructive ALTER
25
- * TABLE DROP COLUMN statements. The `--apply` path additionally requires an
26
- * interactive `yes` typed at a confirmation prompt so an operator cannot
27
- * fat-finger it from shell history.
28
- *
29
- * Affected tables (every analytics table that still carries `site_id` after
30
- * Phase 18 A4 — see docker/clickhouse/init/01_schema.sql for the canonical
31
- * list):
32
- *
33
- * • events_raw — primary fact table
34
- * • flow_session_events — per-session ordered event tape
35
- * • journey_events — cross-property event timeline (Phase 13)
36
- * • cross_property_journeys — aggregated journey rollup (Phase 13)
37
- * • inferred_events — server-derived event sink
38
- *
39
- * Usage:
40
- *
41
- * node scripts/tenant-pivot-phase-3-cleanup.mjs # dry-run (default)
42
- * node scripts/tenant-pivot-phase-3-cleanup.mjs --apply # interactive destructive run
43
- * node scripts/tenant-pivot-phase-3-cleanup.mjs --apply --no-confirm # test harness only
44
- *
45
- * Env:
46
- * CLICKHOUSE_URL (default http://localhost:8123)
47
- * CLICKHOUSE_DATABASE (default gurulu)
48
- *
49
- * The detection / orchestration logic lives in
50
- * `scripts/tenant-pivot-phase-3-cleanup.lib.cjs` so it can be reused by the
51
- * ts-jest test suite via `require()`. This wrapper exposes the same API as
52
- * an ESM module and, when invoked directly, runs the CLI.
53
- *
54
- * IMPORTANT: Do not modify this script to auto-run. Do not add it to any
55
- * workflow. The whole point of the human-in-the-loop confirmation is to
56
- * guarantee an operator chose to drop the column.
57
- * ============================================================================
58
- */
59
-
60
- import { createRequire } from 'node:module';
61
- import { fileURLToPath } from 'node:url';
62
-
63
- const require = createRequire(import.meta.url);
64
- const lib = require('./tenant-pivot-phase-3-cleanup.lib.cjs');
65
-
66
- export const AFFECTED_TABLES = lib.AFFECTED_TABLES;
67
- export const buildDropColumnSql = lib.buildDropColumnSql;
68
- export const buildRowCountSql = lib.buildRowCountSql;
69
- export const parseArgs = lib.parseArgs;
70
- export const printHelp = lib.printHelp;
71
- export const safeRowCount = lib.safeRowCount;
72
- export const buildPlan = lib.buildPlan;
73
- export const renderPlan = lib.renderPlan;
74
- export const appendLog = lib.appendLog;
75
- export const confirmDestructive = lib.confirmDestructive;
76
- export const runCli = lib.runCli;
77
-
78
- // CLI entry — only auto-runs when invoked directly via `node ...mjs`, not
79
- // when imported by another module.
80
- const isMain = (() => {
81
- try {
82
- return fileURLToPath(import.meta.url) === process.argv[1];
83
- } catch {
84
- return false;
85
- }
86
- })();
87
-
88
- if (isMain) {
89
- lib.runCli().then(
90
- (r) => {
91
- if (!r.ok) process.exitCode = 1;
92
- },
93
- (err) => {
94
- console.error('[phase-3-cleanup] fatal:', err);
95
- process.exitCode = 1;
96
- },
97
- );
98
- }