@aopslab/domain-cli-docman 0.1.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.
package/dist/main.js ADDED
@@ -0,0 +1,1524 @@
1
+ #!/usr/bin/env node
2
+ import './env-bootstrap.js';
3
+ import { DEFAULT_TENANT_AS_UUID_STRING, sanitizeUrl } from '@aopslab/xf-core';
4
+ import { createDocmanCliCommandSurface } from './command-surface.js';
5
+ import { DEFAULT_DOCMAN_SCOPE_ID, applyDocmanRuntimeEnv, getDefaultDocmanSqlitePath, getDefaultDocmanSqliteRepoUrl, inferDocmanRepoDialect, readDocmanCliStoredConfig, resolveDocmanRuntimeConfig, writeDocmanCliStoredConfig, } from './config-host.js';
6
+ import { applyDocmanPgSchema } from '@aopslab/domain-pg-bootstrap-docman';
7
+ import { buildDocmanHostRegistrationManifest } from './host-registration.js';
8
+ import { ensureDocmanSqliteSchemaReady } from './sqlite-bootstrap.js';
9
+ import { existsSync, readFileSync } from 'node:fs';
10
+ import os from 'node:os';
11
+ import { resolve } from 'node:path';
12
+ const AOPS_CONFIG_FILENAME = 'aops.config.json';
13
+ const HOST_CONFIG_FILENAME = 'host.config.json';
14
+ const DIRECT_OPERATION_COMMANDS = new Set(['op', 'operation', 'run']);
15
+ const RESERVED_NON_OPERATION_COMMANDS = new Set(['help', 'tools', 'ops', 'manifest', 'tool', 'invoke', 'config', 'init', 'setup']);
16
+ const GENERATED_OPERATION_JSON_ARGS = new Set(['input', 'data', 'patch', 'filter', 'options', 'config']);
17
+ const HOST_CONFIG_ENV_KEYS = ['DOCMAN_CLI_HOST_CONFIG_PATH', 'HOST_NODE_CONFIG'];
18
+ const DOCMAN_ENV_SANITIZE_KEYS = [
19
+ 'TENANT_ID',
20
+ 'DOCMAN_SCOPE_ID',
21
+ 'AOPS_PG_URL',
22
+ 'DOCMAN_REPO_URL',
23
+ 'DOCMAN_PG_URL',
24
+ 'DOCMAN_SQLITE_URL',
25
+ 'DOCUMENT_REPO_URL',
26
+ 'DOCUMENT_GROUP_REPO_URL',
27
+ 'DOCUMENT_VERSION_REPO_URL',
28
+ 'SECTION_REPO_URL',
29
+ 'PAGE_REPO_URL',
30
+ 'PAGE_VERSION_REPO_URL',
31
+ 'DOCUMENT_SECTION_LINK_REPO_URL',
32
+ 'SECTION_PAGE_LINK_REPO_URL',
33
+ 'SNIPPET_REPO_URL',
34
+ 'PAGE_SNIPPET_LINK_REPO_URL',
35
+ 'EMBED_REPO_URL',
36
+ 'PAGE_EMBED_LINK_REPO_URL',
37
+ ];
38
+ let docmanCliRuntimeModulesPromise = null;
39
+ let docmanHostRuntimePromise = null;
40
+ let docmanCliPackageVersionCache = null;
41
+ async function getDocmanCliRuntimeModules() {
42
+ if (docmanCliRuntimeModulesPromise)
43
+ return docmanCliRuntimeModulesPromise;
44
+ docmanCliRuntimeModulesPromise = (async () => {
45
+ const [tooling, hostPlugin] = await Promise.all([
46
+ import('@aopslab/domain-tooling-docman'),
47
+ import('@aopslab/domain-host-plugin-docman'),
48
+ ]);
49
+ return { tooling, hostPlugin };
50
+ })();
51
+ return docmanCliRuntimeModulesPromise;
52
+ }
53
+ function normalizeOptionKey(raw) {
54
+ return raw.trim().replace(/^--+/, '').toLowerCase();
55
+ }
56
+ function pushOptionValue(target, key, value) {
57
+ const existing = target[key];
58
+ if (existing === undefined) {
59
+ target[key] = value;
60
+ return;
61
+ }
62
+ if (Array.isArray(existing)) {
63
+ existing.push(String(value));
64
+ target[key] = existing;
65
+ return;
66
+ }
67
+ target[key] = [String(existing), String(value)];
68
+ }
69
+ function parseArgv(argv) {
70
+ const positionals = [];
71
+ const options = {};
72
+ for (let index = 0; index < argv.length; index += 1) {
73
+ const token = argv[index];
74
+ if (token === '--')
75
+ continue;
76
+ if (!token.startsWith('--')) {
77
+ positionals.push(token);
78
+ continue;
79
+ }
80
+ const eqAt = token.indexOf('=');
81
+ if (eqAt > -1) {
82
+ const key = normalizeOptionKey(token.slice(0, eqAt));
83
+ const value = token.slice(eqAt + 1);
84
+ pushOptionValue(options, key, value);
85
+ continue;
86
+ }
87
+ const key = normalizeOptionKey(token);
88
+ const next = argv[index + 1];
89
+ if (!next || next.startsWith('--')) {
90
+ pushOptionValue(options, key, true);
91
+ continue;
92
+ }
93
+ pushOptionValue(options, key, next);
94
+ index += 1;
95
+ }
96
+ return { positionals, options };
97
+ }
98
+ function getOptionValue(parsed, key) {
99
+ return parsed.options[key];
100
+ }
101
+ function getStringOption(parsed, key) {
102
+ const value = getOptionValue(parsed, key);
103
+ if (Array.isArray(value)) {
104
+ const last = value[value.length - 1];
105
+ return String(last).trim() || undefined;
106
+ }
107
+ if (value === undefined || value === null || value === true || value === false)
108
+ return undefined;
109
+ const normalized = String(value).trim();
110
+ return normalized.length > 0 ? normalized : undefined;
111
+ }
112
+ function getBooleanFromString(value, fallback) {
113
+ const normalized = String(value).trim().toLowerCase();
114
+ if (['1', 'true', 'yes', 'on'].includes(normalized))
115
+ return true;
116
+ if (['0', 'false', 'no', 'off'].includes(normalized))
117
+ return false;
118
+ return fallback;
119
+ }
120
+ function getBooleanOption(parsed, key, fallback = false) {
121
+ const value = getOptionValue(parsed, key);
122
+ if (value === undefined)
123
+ return fallback;
124
+ if (Array.isArray(value))
125
+ return getBooleanFromString(value[value.length - 1], fallback);
126
+ if (typeof value === 'boolean')
127
+ return value;
128
+ return getBooleanFromString(value, fallback);
129
+ }
130
+ function getBooleanFromEnv(keys, fallback = false) {
131
+ for (const key of keys) {
132
+ const value = normalizeNonEmptyString(process.env[key]);
133
+ if (!value)
134
+ continue;
135
+ return getBooleanFromString(value, fallback);
136
+ }
137
+ return fallback;
138
+ }
139
+ function getScopeIdOption(parsed) {
140
+ return getStringOption(parsed, 'scope-id') ?? getStringOption(parsed, 'workspace-id');
141
+ }
142
+ function normalizeDocmanScopeId(value) {
143
+ const normalized = normalizeNonEmptyString(value);
144
+ if (!normalized)
145
+ return undefined;
146
+ return normalized.toLowerCase() === 'default' ? DEFAULT_DOCMAN_SCOPE_ID : normalized;
147
+ }
148
+ function areHooksDisabled(parsed) {
149
+ if (getOptionValue(parsed, 'no-hook') !== undefined) {
150
+ return getBooleanOption(parsed, 'no-hook', false);
151
+ }
152
+ return getBooleanFromEnv(['DOCMAN_CLI_NO_HOOK', 'DOCMAN_CLI_DISABLE_HOOKS'], false);
153
+ }
154
+ function requireStringOption(parsed, key, label) {
155
+ const value = getStringOption(parsed, key);
156
+ if (!value) {
157
+ throw new Error(`missing_required_option:${label}`);
158
+ }
159
+ return value;
160
+ }
161
+ function parseJsonInput(raw, label) {
162
+ if (raw === undefined || raw === null)
163
+ return undefined;
164
+ if (typeof raw !== 'string')
165
+ return raw;
166
+ const trimmed = raw.trim();
167
+ if (!trimmed)
168
+ return undefined;
169
+ if (trimmed.startsWith('@')) {
170
+ const filePath = trimmed.slice(1).trim();
171
+ if (!filePath)
172
+ throw new Error(`invalid_json_${label}`);
173
+ const content = readFileSync(filePath, 'utf8');
174
+ return JSON.parse(content);
175
+ }
176
+ return JSON.parse(trimmed);
177
+ }
178
+ function normalizeIdentifier(value) {
179
+ return String(value ?? '').trim().toLowerCase().replace(/^\/+/, '');
180
+ }
181
+ function normalizeOperationIdentifier(raw) {
182
+ const normalized = raw
183
+ .trim()
184
+ .toLowerCase()
185
+ .replace(/^\/+/, '')
186
+ .replace(/^operations\//, '')
187
+ .replace(/^api\/docman\/operations\//, '')
188
+ .replace(/\//g, '.')
189
+ .replace(/\.+/g, '.');
190
+ if (!normalized)
191
+ return normalized;
192
+ return normalized.startsWith('docman.') ? normalized : `docman.${normalized}`;
193
+ }
194
+ function toKebabCase(value) {
195
+ return value
196
+ .replace(/([a-z0-9])([A-Z])/g, '$1-$2')
197
+ .replace(/[_\s.]+/g, '-')
198
+ .toLowerCase();
199
+ }
200
+ function toOptionKeyCandidatesFromArgName(argName) {
201
+ const kebab = toKebabCase(argName);
202
+ const compact = kebab.replace(/-/g, '');
203
+ const lowered = argName.toLowerCase();
204
+ return [...new Set([kebab, compact, lowered])];
205
+ }
206
+ function getOptionValueByAnyKey(parsed, keys) {
207
+ for (const key of keys) {
208
+ const value = getOptionValue(parsed, key);
209
+ if (value !== undefined)
210
+ return value;
211
+ }
212
+ return undefined;
213
+ }
214
+ function splitCsvStrings(values) {
215
+ return values
216
+ .flatMap((value) => value.split(','))
217
+ .map((value) => value.trim())
218
+ .filter(Boolean);
219
+ }
220
+ function tryParseBooleanToken(value) {
221
+ const normalized = value.trim().toLowerCase();
222
+ if (['1', 'true', 'yes', 'on'].includes(normalized))
223
+ return true;
224
+ if (['0', 'false', 'no', 'off'].includes(normalized))
225
+ return false;
226
+ return undefined;
227
+ }
228
+ function shouldTreatAsArrayArg(argName) {
229
+ return argName.endsWith('Ids') || argName.endsWith('Paths');
230
+ }
231
+ function coerceOperationArgValue(raw, argName) {
232
+ if (typeof raw === 'boolean')
233
+ return raw;
234
+ const argKey = argName.trim().toLowerCase();
235
+ const asArray = Array.isArray(raw) ? raw.map((item) => String(item)) : null;
236
+ if (asArray) {
237
+ if (shouldTreatAsArrayArg(argName))
238
+ return splitCsvStrings(asArray);
239
+ if (GENERATED_OPERATION_JSON_ARGS.has(argKey) && asArray.length > 0) {
240
+ return parseJsonInput(asArray[asArray.length - 1], argName);
241
+ }
242
+ return asArray.map((item) => {
243
+ const boolValue = tryParseBooleanToken(item);
244
+ return boolValue ?? item;
245
+ });
246
+ }
247
+ const value = String(raw).trim();
248
+ if (!value)
249
+ return value;
250
+ if (GENERATED_OPERATION_JSON_ARGS.has(argKey)) {
251
+ return parseJsonInput(value, argName);
252
+ }
253
+ if (shouldTreatAsArrayArg(argName)) {
254
+ return splitCsvStrings([value]);
255
+ }
256
+ const boolValue = tryParseBooleanToken(value);
257
+ if (boolValue !== undefined)
258
+ return boolValue;
259
+ return value;
260
+ }
261
+ async function resolveOperationIdentifier(rawIdentifier, operationMap) {
262
+ const { tooling } = await getDocmanCliRuntimeModules();
263
+ const resolvedByToolId = tooling.resolveDocmanOperationIdByToolId(rawIdentifier, { refresh: true });
264
+ if (resolvedByToolId) {
265
+ const normalizedByToolId = normalizeOperationIdentifier(resolvedByToolId);
266
+ if (operationMap.has(normalizedByToolId))
267
+ return normalizedByToolId;
268
+ }
269
+ const normalized = normalizeOperationIdentifier(rawIdentifier);
270
+ if (normalized && operationMap.has(normalized))
271
+ return normalized;
272
+ const spec = tooling.getDocmanOperationSpecById(rawIdentifier, { refresh: true });
273
+ if (!spec)
274
+ return null;
275
+ const normalizedFromSpec = normalizeOperationIdentifier(spec.operationId);
276
+ return operationMap.has(normalizedFromSpec) ? normalizedFromSpec : null;
277
+ }
278
+ async function resolveGeneratedOperationId(parsed, operationMap) {
279
+ const command = parsed.positionals[0]?.toLowerCase();
280
+ const subcommand = parsed.positionals[1]?.toLowerCase();
281
+ if (!command)
282
+ return null;
283
+ if (DIRECT_OPERATION_COMMANDS.has(command)) {
284
+ const identifier = parsed.positionals[1] ?? getStringOption(parsed, 'id');
285
+ if (!identifier)
286
+ throw new Error('missing_required_option:<operation-id-or-tool-id>');
287
+ const resolved = await resolveOperationIdentifier(identifier, operationMap);
288
+ if (!resolved)
289
+ throw new Error(`unknown_docman_operation_identifier:${identifier}`);
290
+ return resolved;
291
+ }
292
+ if (RESERVED_NON_OPERATION_COMMANDS.has(command))
293
+ return null;
294
+ if (command.includes('.')) {
295
+ const direct = await resolveOperationIdentifier(command, operationMap);
296
+ if (direct)
297
+ return direct;
298
+ }
299
+ if (subcommand) {
300
+ const nested = normalizeOperationIdentifier(`${command}.${subcommand}`);
301
+ if (operationMap.has(nested))
302
+ return nested;
303
+ }
304
+ const topLevel = normalizeOperationIdentifier(command);
305
+ if (operationMap.has(topLevel))
306
+ return topLevel;
307
+ return null;
308
+ }
309
+ function buildGeneratedOperationInput(operation, parsed, runtime) {
310
+ const explicitInput = parseJsonInput(getStringOption(parsed, 'input'), 'input');
311
+ if (explicitInput !== undefined) {
312
+ if (!explicitInput || typeof explicitInput !== 'object' || Array.isArray(explicitInput)) {
313
+ throw new Error('invalid_json_input:expected_object');
314
+ }
315
+ return explicitInput;
316
+ }
317
+ const input = {};
318
+ for (const arg of operation.args) {
319
+ const rawValue = getOptionValueByAnyKey(parsed, toOptionKeyCandidatesFromArgName(arg.name));
320
+ if (rawValue === undefined) {
321
+ if (arg.name === 'scopeId') {
322
+ input.scopeId = runtime.scopeId;
323
+ continue;
324
+ }
325
+ if (arg.name === 'workspaceId') {
326
+ input.workspaceId = runtime.workspaceId;
327
+ continue;
328
+ }
329
+ if (!arg.optional) {
330
+ throw new Error(`missing_required_option:--${toKebabCase(arg.name)}`);
331
+ }
332
+ continue;
333
+ }
334
+ input[arg.name] = coerceOperationArgValue(rawValue, arg.name);
335
+ }
336
+ return input;
337
+ }
338
+ function printJson(value) {
339
+ process.stdout.write(`${JSON.stringify(value === undefined ? null : value, null, 2)}\n`);
340
+ }
341
+ function printVersion() {
342
+ process.stdout.write(`${getDocmanCliPackageVersion()}\n`);
343
+ }
344
+ function printHelpLines(lines) {
345
+ process.stdout.write(`${lines.join('\n')}\n`);
346
+ }
347
+ function appendTextSection(target, title, lines) {
348
+ const normalized = lines.map((line) => String(line ?? '').trimEnd()).filter(Boolean);
349
+ if (normalized.length === 0)
350
+ return;
351
+ if (target.length > 0 && target[target.length - 1] !== '')
352
+ target.push('');
353
+ target.push(`${title}:`);
354
+ for (const line of normalized) {
355
+ target.push(` ${line}`);
356
+ }
357
+ }
358
+ function toStringList(value) {
359
+ if (!Array.isArray(value))
360
+ return [];
361
+ return value
362
+ .map((entry) => String(entry ?? '').trim())
363
+ .filter(Boolean);
364
+ }
365
+ function renderCommandDescriptor(descriptor) {
366
+ const lines = [descriptor.title];
367
+ for (const section of descriptor.sections) {
368
+ appendTextSection(lines, section.title, section.lines);
369
+ }
370
+ return lines;
371
+ }
372
+ function buildStandaloneInitHelpLines() {
373
+ return [
374
+ 'docman init',
375
+ '',
376
+ 'Purpose:',
377
+ ' Initialize standalone Docman runtime config for the local operator flow.',
378
+ '',
379
+ 'Usage:',
380
+ ' docman init [--runtime-mode single-user] [--repo-url <url>] [--scope-id <id>] [--json]',
381
+ '',
382
+ 'Notes:',
383
+ ' - Defaults to single-user mode.',
384
+ ' - Defaults repo URL to ~/.aops/docman.aops.sqlite.',
385
+ ` - Defaults scope id to global default scope ${DEFAULT_DOCMAN_SCOPE_ID}.`,
386
+ ' - Ensures SQLite schema readiness when the resolved repo dialect is SQLite.',
387
+ ];
388
+ }
389
+ function buildStandaloneSetupHelpLines() {
390
+ return [
391
+ 'docman setup runtime',
392
+ '',
393
+ 'Purpose:',
394
+ ' Update standalone Docman runtime storage and bootstrap state.',
395
+ '',
396
+ 'Usage:',
397
+ ' docman setup runtime [--runtime-mode single-user|multi-user] [--repo-url <url>] [--scope-id <id>] [--json]',
398
+ '',
399
+ 'Notes:',
400
+ ' - This command is rerunnable.',
401
+ ' - SQLite repos are bootstrapped automatically.',
402
+ ' - Desktop host reads the same persisted config owner as the CLI.',
403
+ ];
404
+ }
405
+ function findCommandDescriptorById(projection, id) {
406
+ return projection.commandsById[id] ?? null;
407
+ }
408
+ async function buildCliProjection() {
409
+ const { tooling } = await getDocmanCliRuntimeModules();
410
+ return tooling.buildDocmanCliProjection({ refresh: true });
411
+ }
412
+ function toProjectionOperationId(operationId) {
413
+ return normalizeOperationIdentifier(operationId).replace(/^docman\./, '');
414
+ }
415
+ function normalizeManifestHelpSubcommand(subcommand) {
416
+ if (!subcommand)
417
+ return undefined;
418
+ if (subcommand === 'hrm')
419
+ return 'host-registration';
420
+ if (subcommand === 'operations')
421
+ return 'ops';
422
+ return subcommand;
423
+ }
424
+ async function printHelp() {
425
+ const projection = await buildCliProjection();
426
+ const descriptor = findCommandDescriptorById(projection, 'docman');
427
+ if (!descriptor) {
428
+ throw new Error('missing_cli_help_root');
429
+ }
430
+ const lines = renderCommandDescriptor(descriptor);
431
+ lines.push('', 'Standalone setup commands:', ' docman init', ' docman setup runtime');
432
+ printHelpLines(lines);
433
+ }
434
+ async function tryPrintCommandHelp(parsed) {
435
+ const command = parsed.positionals[0]?.toLowerCase();
436
+ const subcommand = normalizeManifestHelpSubcommand(parsed.positionals[1]?.toLowerCase());
437
+ if (!command)
438
+ return false;
439
+ const projection = await buildCliProjection();
440
+ const renderDescriptor = (id, trailingMessage) => {
441
+ const descriptor = findCommandDescriptorById(projection, id);
442
+ if (!descriptor)
443
+ return false;
444
+ const lines = renderCommandDescriptor(descriptor);
445
+ if (trailingMessage) {
446
+ lines.push('', trailingMessage);
447
+ }
448
+ printHelpLines(lines);
449
+ return true;
450
+ };
451
+ if (command === 'version')
452
+ return renderDescriptor('version');
453
+ if (command === 'init') {
454
+ printHelpLines(buildStandaloneInitHelpLines());
455
+ return true;
456
+ }
457
+ if (command === 'setup') {
458
+ printHelpLines(buildStandaloneSetupHelpLines());
459
+ return true;
460
+ }
461
+ if (command === 'config') {
462
+ if (subcommand === 'show')
463
+ return renderDescriptor('config.show');
464
+ if (subcommand === 'set')
465
+ return renderDescriptor('config.set');
466
+ return renderDescriptor('config');
467
+ }
468
+ if (command === 'manifest') {
469
+ if (!subcommand)
470
+ return renderDescriptor('manifest');
471
+ if (subcommand === 'get')
472
+ return renderDescriptor('manifest.get');
473
+ if (subcommand === 'show')
474
+ return renderDescriptor('manifest.show');
475
+ if (subcommand === 'dcm')
476
+ return renderDescriptor('manifest.dcm');
477
+ if (subcommand === 'routes')
478
+ return renderDescriptor('manifest.routes');
479
+ if (subcommand === 'agent')
480
+ return renderDescriptor('manifest.agent');
481
+ if (subcommand === 'cli')
482
+ return renderDescriptor('manifest.cli');
483
+ if (subcommand === 'host-registration')
484
+ return renderDescriptor('manifest.host-registration');
485
+ if (subcommand === 'ops')
486
+ return renderDescriptor('manifest.ops');
487
+ return renderDescriptor('manifest');
488
+ }
489
+ if (command === 'tools')
490
+ return renderDescriptor('tools');
491
+ if (command === 'ops')
492
+ return renderDescriptor('ops');
493
+ if (command === 'tool' || command === 'invoke') {
494
+ const { tooling } = await getDocmanCliRuntimeModules();
495
+ const identifier = getStringOption(parsed, 'id');
496
+ if (!identifier)
497
+ return renderDescriptor('tool');
498
+ const spec = tooling.getDocmanOperationSpecById(identifier, { refresh: true });
499
+ if (!spec) {
500
+ return renderDescriptor('tool', `Unknown tool or operation id: ${identifier}`);
501
+ }
502
+ return renderDescriptor(toProjectionOperationId(spec.operationId));
503
+ }
504
+ if (DIRECT_OPERATION_COMMANDS.has(command)) {
505
+ const { tooling } = await getDocmanCliRuntimeModules();
506
+ const identifier = parsed.positionals[1] ?? getStringOption(parsed, 'id');
507
+ if (!identifier)
508
+ return renderDescriptor('op');
509
+ const spec = tooling.getDocmanOperationSpecById(identifier, { refresh: true });
510
+ if (!spec) {
511
+ return renderDescriptor('op', `Unknown operation or tool id: ${identifier}`);
512
+ }
513
+ return renderDescriptor(toProjectionOperationId(spec.operationId));
514
+ }
515
+ const { tooling } = await getDocmanCliRuntimeModules();
516
+ const operationSpecs = tooling.listDocmanToolingOperations({ refresh: true });
517
+ const operationMap = new Map(operationSpecs.map((operation) => [normalizeOperationIdentifier(operation.operationId), operation]));
518
+ const resolvedOperationId = await resolveGeneratedOperationId(parsed, operationMap);
519
+ if (!resolvedOperationId)
520
+ return false;
521
+ return renderDescriptor(toProjectionOperationId(resolvedOperationId));
522
+ }
523
+ function normalizeNonEmptyString(value) {
524
+ if (typeof value !== 'string')
525
+ return undefined;
526
+ const normalized = value.trim();
527
+ return normalized.length > 0 ? normalized : undefined;
528
+ }
529
+ function normalizeRepoUrlValue(value) {
530
+ const normalized = normalizeNonEmptyString(value);
531
+ if (!normalized)
532
+ return undefined;
533
+ return normalized.replace(/(?:\\r|\r)+$/g, '');
534
+ }
535
+ function normalizeRuntimeMode(value) {
536
+ const normalized = normalizeNonEmptyString(value)?.toLowerCase();
537
+ if (!normalized)
538
+ return undefined;
539
+ if (normalized === 'single-user' || normalized === 'single_user' || normalized === 'single') {
540
+ return 'single-user';
541
+ }
542
+ if (normalized === 'multi-user' || normalized === 'multi_user' || normalized === 'multi') {
543
+ return 'multi-user';
544
+ }
545
+ return undefined;
546
+ }
547
+ function getDocmanCliPackageVersion() {
548
+ if (docmanCliPackageVersionCache)
549
+ return docmanCliPackageVersionCache;
550
+ try {
551
+ const packageJson = JSON.parse(readFileSync(new URL('../package.json', import.meta.url), 'utf8'));
552
+ docmanCliPackageVersionCache = normalizeNonEmptyString(packageJson.version) ?? '0.0.0';
553
+ }
554
+ catch {
555
+ docmanCliPackageVersionCache = '0.0.0';
556
+ }
557
+ return docmanCliPackageVersionCache;
558
+ }
559
+ function toRecord(input) {
560
+ if (!input || typeof input !== 'object' || Array.isArray(input))
561
+ return {};
562
+ return input;
563
+ }
564
+ function resolveHomeDirectory(processEnv) {
565
+ const envHome = normalizeNonEmptyString(processEnv.HOME)
566
+ ?? normalizeNonEmptyString(processEnv.USERPROFILE);
567
+ return resolve(envHome ?? os.homedir());
568
+ }
569
+ function resolveExecutionMode() {
570
+ const configured = normalizeNonEmptyString(process.env.DOCMAN_CLI_EXECUTION_MODE)?.toLowerCase();
571
+ if (configured === 'tooling')
572
+ return 'tooling';
573
+ return 'host';
574
+ }
575
+ function sanitizeBlankEnvValues(processEnv) {
576
+ for (const key of DOCMAN_ENV_SANITIZE_KEYS) {
577
+ if (typeof processEnv[key] === 'string' && processEnv[key]?.trim() === '') {
578
+ delete processEnv[key];
579
+ }
580
+ }
581
+ }
582
+ function buildHostRequestContext() {
583
+ const scopeId = normalizeDocmanScopeId(process.env.DOCMAN_SCOPE_ID)
584
+ ?? normalizeDocmanScopeId(process.env.DOCMAN_WORKSPACE_ID)
585
+ ?? DEFAULT_DOCMAN_SCOPE_ID;
586
+ return {
587
+ tenantId: normalizeNonEmptyString(process.env.TENANT_ID) ?? DEFAULT_TENANT_AS_UUID_STRING,
588
+ scopeId,
589
+ workspaceId: normalizeDocmanScopeId(process.env.DOCMAN_WORKSPACE_ID) ?? scopeId,
590
+ locale: normalizeNonEmptyString(process.env.DOCMAN_LOCALE) ?? 'tr',
591
+ fallbackLocale: normalizeNonEmptyString(process.env.DOCMAN_FALLBACK_LOCALE) ?? 'en',
592
+ principal: null,
593
+ };
594
+ }
595
+ function patternToPathSegments(pattern, params) {
596
+ const raw = pattern.trim().replace(/^\/+|\/+$/g, '');
597
+ if (!raw)
598
+ return [];
599
+ const output = [];
600
+ const segments = raw.split('/').map((segment) => segment.trim()).filter(Boolean);
601
+ for (const patternSegment of segments) {
602
+ if (patternSegment === '*') {
603
+ const splat = normalizeNonEmptyString(params.splat);
604
+ if (!splat)
605
+ continue;
606
+ output.push(...splat.split('/').map((part) => encodeURIComponent(part)));
607
+ continue;
608
+ }
609
+ if (patternSegment.startsWith(':')) {
610
+ const key = patternSegment.slice(1).trim();
611
+ const value = normalizeNonEmptyString(params[key]);
612
+ if (!key || !value) {
613
+ throw new Error(`missing_required_arg:${key || 'path'}`);
614
+ }
615
+ output.push(encodeURIComponent(value));
616
+ continue;
617
+ }
618
+ output.push(patternSegment);
619
+ }
620
+ return output;
621
+ }
622
+ function resolveRouteParams(route, input) {
623
+ const inputRecord = toRecord(input);
624
+ const pathParamCandidates = toRecord(inputRecord.pathParams);
625
+ const params = {};
626
+ const segments = route.pattern
627
+ .trim()
628
+ .replace(/^\/+|\/+$/g, '')
629
+ .split('/')
630
+ .map((segment) => segment.trim())
631
+ .filter(Boolean);
632
+ for (const segment of segments) {
633
+ if (segment === '*') {
634
+ const splatValue = normalizeNonEmptyString(pathParamCandidates.splat) ?? normalizeNonEmptyString(inputRecord.splat);
635
+ if (splatValue)
636
+ params.splat = splatValue;
637
+ continue;
638
+ }
639
+ if (!segment.startsWith(':'))
640
+ continue;
641
+ const key = segment.slice(1).trim();
642
+ if (!key)
643
+ continue;
644
+ const value = normalizeNonEmptyString(pathParamCandidates[key]) ?? normalizeNonEmptyString(inputRecord[key]);
645
+ if (!value) {
646
+ throw new Error(`missing_required_arg:${key}`);
647
+ }
648
+ params[key] = value;
649
+ }
650
+ return params;
651
+ }
652
+ function buildHostDomainRequest(route, pathSegments, input) {
653
+ const baseUrl = `https://docman-cli.local/api/docman${pathSegments.length > 0 ? `/${pathSegments.join('/')}` : ''}`;
654
+ return {
655
+ method: route.method,
656
+ domain: 'docman',
657
+ path: pathSegments,
658
+ query: new URLSearchParams(),
659
+ body: input,
660
+ headers: new Headers(),
661
+ url: new URL(baseUrl),
662
+ context: buildHostRequestContext(),
663
+ };
664
+ }
665
+ async function getDocmanHostRuntime() {
666
+ if (docmanHostRuntimePromise)
667
+ return docmanHostRuntimePromise;
668
+ docmanHostRuntimePromise = (async () => {
669
+ const { hostPlugin } = await getDocmanCliRuntimeModules();
670
+ const plugin = hostPlugin.createDocmanPlugin({
671
+ defaultScopeId: normalizeNonEmptyString(process.env.DOCMAN_SCOPE_ID),
672
+ });
673
+ const routesByOperationId = new Map();
674
+ for (const route of plugin.manifest.routes) {
675
+ const normalizedOperationId = normalizeOperationIdentifier(route.operation);
676
+ if (!normalizedOperationId)
677
+ continue;
678
+ routesByOperationId.set(normalizedOperationId, route);
679
+ }
680
+ return { plugin, routesByOperationId };
681
+ })();
682
+ return docmanHostRuntimePromise;
683
+ }
684
+ async function resolveOperationIdFromIdentifier(identifier) {
685
+ const { tooling } = await getDocmanCliRuntimeModules();
686
+ const normalizedDirect = normalizeOperationIdentifier(identifier);
687
+ const directSpec = tooling.getDocmanOperationSpecById(normalizedDirect || identifier, { refresh: true });
688
+ if (directSpec)
689
+ return normalizeOperationIdentifier(directSpec.operationId);
690
+ const resolvedByAlias = tooling.resolveDocmanOperationIdByToolId(identifier, { refresh: true });
691
+ if (resolvedByAlias)
692
+ return normalizeOperationIdentifier(resolvedByAlias);
693
+ return null;
694
+ }
695
+ async function runDocmanOperationById(operationId, input = {}) {
696
+ const { tooling } = await getDocmanCliRuntimeModules();
697
+ if (resolveExecutionMode() === 'tooling') {
698
+ return tooling.runDocmanOperationById(operationId, input, { refresh: true });
699
+ }
700
+ const runtime = await getDocmanHostRuntime();
701
+ const normalizedOperationId = normalizeOperationIdentifier(operationId);
702
+ const route = runtime.routesByOperationId.get(normalizedOperationId);
703
+ if (!route) {
704
+ return tooling.runDocmanOperationById(operationId, input, { refresh: true });
705
+ }
706
+ const params = resolveRouteParams(route, input);
707
+ const path = patternToPathSegments(route.pattern, params);
708
+ const request = buildHostDomainRequest(route, path, input);
709
+ return runtime.plugin.execute({
710
+ request,
711
+ match: { route, params },
712
+ });
713
+ }
714
+ async function runDocmanToolById(identifier, input = {}) {
715
+ const { tooling } = await getDocmanCliRuntimeModules();
716
+ if (resolveExecutionMode() === 'tooling') {
717
+ return tooling.runDocmanToolById(identifier, input, { refresh: true });
718
+ }
719
+ const operationId = await resolveOperationIdFromIdentifier(identifier);
720
+ if (!operationId) {
721
+ return tooling.runDocmanToolById(identifier, input, { refresh: true });
722
+ }
723
+ return runDocmanOperationById(operationId, input);
724
+ }
725
+ function resolveOptionalHostConfigPath(parsed, processEnv, storedConfig) {
726
+ const optionPathRaw = normalizeNonEmptyString(getStringOption(parsed, 'host-config'));
727
+ if (optionPathRaw) {
728
+ const resolvedOptionPath = resolve(optionPathRaw);
729
+ if (existsSync(resolvedOptionPath))
730
+ return resolvedOptionPath;
731
+ const candidateFile = resolvedOptionPath.toLowerCase().endsWith('.json')
732
+ ? resolvedOptionPath
733
+ : resolve(resolvedOptionPath, HOST_CONFIG_FILENAME);
734
+ if (existsSync(candidateFile))
735
+ return candidateFile;
736
+ throw new Error(`host_config_not_found:${optionPathRaw}`);
737
+ }
738
+ for (const envKey of HOST_CONFIG_ENV_KEYS) {
739
+ const envValue = normalizeNonEmptyString(processEnv[envKey]);
740
+ if (!envValue)
741
+ continue;
742
+ const resolvedEnvPath = resolve(envValue);
743
+ if (existsSync(resolvedEnvPath))
744
+ return resolvedEnvPath;
745
+ const candidateFile = resolvedEnvPath.toLowerCase().endsWith('.json')
746
+ ? resolvedEnvPath
747
+ : resolve(resolvedEnvPath, HOST_CONFIG_FILENAME);
748
+ if (existsSync(candidateFile))
749
+ return candidateFile;
750
+ }
751
+ const storedPathRaw = normalizeNonEmptyString(storedConfig.hostConfigPath);
752
+ if (storedPathRaw) {
753
+ const resolvedStoredPath = resolve(storedPathRaw);
754
+ if (existsSync(resolvedStoredPath))
755
+ return resolvedStoredPath;
756
+ const candidateFile = resolvedStoredPath.toLowerCase().endsWith('.json')
757
+ ? resolvedStoredPath
758
+ : resolve(resolvedStoredPath, HOST_CONFIG_FILENAME);
759
+ if (existsSync(candidateFile))
760
+ return candidateFile;
761
+ }
762
+ const localCandidate = resolve(process.cwd(), HOST_CONFIG_FILENAME);
763
+ if (existsSync(localCandidate))
764
+ return localCandidate;
765
+ return null;
766
+ }
767
+ function resolveConfigBindingValue(binding, processEnv) {
768
+ const direct = normalizeNonEmptyString(binding);
769
+ if (direct)
770
+ return direct;
771
+ const bindingRecord = toRecord(binding);
772
+ const fromEnv = normalizeNonEmptyString(bindingRecord.fromEnv);
773
+ if (fromEnv) {
774
+ const envValue = normalizeNonEmptyString(processEnv[fromEnv]);
775
+ if (envValue)
776
+ return envValue;
777
+ }
778
+ return normalizeNonEmptyString(bindingRecord.value) ?? normalizeNonEmptyString(bindingRecord.default);
779
+ }
780
+ function applyOptionalHostRuntimeEnv(parsed, processEnv, storedConfig) {
781
+ const hostConfigPath = resolveOptionalHostConfigPath(parsed, processEnv, storedConfig);
782
+ if (!hostConfigPath)
783
+ return;
784
+ let config = {};
785
+ try {
786
+ config = toRecord(JSON.parse(readFileSync(hostConfigPath, 'utf8')));
787
+ }
788
+ catch (error) {
789
+ throw new Error(`host_config_parse_failed:${hostConfigPath}:${error instanceof Error ? error.message : String(error)}`);
790
+ }
791
+ const runtimeEnv = toRecord(toRecord(config.runtime).env);
792
+ for (const [targetKeyRaw, binding] of Object.entries(runtimeEnv)) {
793
+ const targetKey = targetKeyRaw.trim();
794
+ if (!targetKey)
795
+ continue;
796
+ if (targetKey.toUpperCase() === 'DOCMAN_REPO_URL') {
797
+ continue;
798
+ }
799
+ const resolved = resolveConfigBindingValue(binding, processEnv);
800
+ if (resolved !== undefined) {
801
+ process.env[targetKey] = resolved;
802
+ }
803
+ }
804
+ }
805
+ function resolveAopsConfigFilePath(processEnv) {
806
+ const configPathRaw = processEnv.AOPS_CLI_CONFIG_PATH ?? processEnv.AGENT_OPS_CONFIG_PATH;
807
+ const configPath = typeof configPathRaw === 'string' ? configPathRaw.trim() : '';
808
+ if (configPath.length > 0) {
809
+ const resolvedPath = resolve(configPath);
810
+ if (resolvedPath.toLowerCase().endsWith('.json')) {
811
+ return resolvedPath;
812
+ }
813
+ return resolve(resolvedPath, AOPS_CONFIG_FILENAME);
814
+ }
815
+ return resolve(resolveHomeDirectory(processEnv), '.aops', AOPS_CONFIG_FILENAME);
816
+ }
817
+ function readAopsConfig(processEnv) {
818
+ const configPath = resolveAopsConfigFilePath(processEnv);
819
+ if (!existsSync(configPath))
820
+ return {};
821
+ try {
822
+ const content = readFileSync(configPath, 'utf8');
823
+ return toRecord(JSON.parse(content));
824
+ }
825
+ catch {
826
+ return {};
827
+ }
828
+ }
829
+ function resolveConfiguredDocmanRepoUrl(processEnv) {
830
+ const config = readAopsConfig(processEnv);
831
+ const topLevel = normalizeRepoUrlValue(config.docmanPgUrl) ??
832
+ normalizeRepoUrlValue(config.docmanSqliteUrl) ??
833
+ normalizeRepoUrlValue(config.docmanRepoUrl) ??
834
+ normalizeRepoUrlValue(config.DOCMAN_PG_URL) ??
835
+ normalizeRepoUrlValue(config.DOCMAN_SQLITE_URL) ??
836
+ normalizeRepoUrlValue(config.DOCMAN_REPO_URL);
837
+ if (topLevel)
838
+ return topLevel;
839
+ const docmanConfig = toRecord(config.docman);
840
+ const docmanLevel = normalizeRepoUrlValue(docmanConfig.pgUrl) ??
841
+ normalizeRepoUrlValue(docmanConfig.sqliteUrl) ??
842
+ normalizeRepoUrlValue(docmanConfig.repoUrl) ??
843
+ normalizeRepoUrlValue(docmanConfig.repositoryUrl) ??
844
+ normalizeRepoUrlValue(docmanConfig.dbUrl);
845
+ if (docmanLevel)
846
+ return docmanLevel;
847
+ const runtimeEnv = toRecord(toRecord(config.runtime).env);
848
+ const runtimeValue = resolveConfigBindingValue(runtimeEnv.DOCMAN_PG_URL, processEnv) ??
849
+ resolveConfigBindingValue(runtimeEnv.DOCMAN_SQLITE_URL, processEnv) ??
850
+ resolveConfigBindingValue(runtimeEnv.DOCMAN_REPO_URL, processEnv);
851
+ if (runtimeValue)
852
+ return runtimeValue;
853
+ const envSection = toRecord(config.env);
854
+ return normalizeRepoUrlValue(resolveConfigBindingValue(envSection.DOCMAN_PG_URL, processEnv))
855
+ ?? normalizeRepoUrlValue(resolveConfigBindingValue(envSection.DOCMAN_SQLITE_URL, processEnv))
856
+ ?? normalizeRepoUrlValue(resolveConfigBindingValue(envSection.DOCMAN_REPO_URL, processEnv));
857
+ }
858
+ function inferDefaultRepoUrl(processEnv) {
859
+ const configuredRepoUrl = resolveConfiguredDocmanRepoUrl(processEnv);
860
+ if (configuredRepoUrl)
861
+ return configuredRepoUrl;
862
+ return getDefaultDocmanSqliteRepoUrl(processEnv);
863
+ }
864
+ function maskRepoUrlForDisplay(repoUrl) {
865
+ const normalized = normalizeRepoUrlValue(repoUrl);
866
+ if (!normalized)
867
+ return undefined;
868
+ if (inferDocmanRepoDialect(normalized) === 'sqlite')
869
+ return normalized;
870
+ return sanitizeUrl(normalized);
871
+ }
872
+ function maskStoredConfigForDisplay(stored) {
873
+ const output = {
874
+ ...stored,
875
+ ...(stored.repoUrl ? { repoUrl: maskRepoUrlForDisplay(stored.repoUrl) } : {}),
876
+ };
877
+ return output;
878
+ }
879
+ function buildConfigSetOutput(stored) {
880
+ return {
881
+ configPath: stored.path,
882
+ exists: stored.exists,
883
+ stored: maskStoredConfigForDisplay(stored.config),
884
+ };
885
+ }
886
+ function buildConfigShowOutput(processEnv) {
887
+ const loaded = readDocmanCliStoredConfig(processEnv);
888
+ const stored = loaded.config;
889
+ const defaultSqlitePath = getDefaultDocmanSqlitePath(processEnv);
890
+ const defaultSqliteRepoUrl = getDefaultDocmanSqliteRepoUrl(processEnv);
891
+ const envRepoUrl = normalizeRepoUrlValue(processEnv.DOCMAN_REPO_URL)
892
+ ?? normalizeRepoUrlValue(processEnv.DOCMAN_SQLITE_URL)
893
+ ?? normalizeRepoUrlValue(processEnv.DOCMAN_PG_URL);
894
+ const envRepoUrlBootstrapSource = normalizeNonEmptyString(processEnv.DOCMAN_CLI_BOOTSTRAPPED_REPO_URL_SOURCE);
895
+ const envTenantId = normalizeNonEmptyString(processEnv.TENANT_ID);
896
+ const envScopeId = normalizeDocmanScopeId(processEnv.DOCMAN_SCOPE_ID)
897
+ ?? normalizeDocmanScopeId(processEnv.DOCMAN_WORKSPACE_ID);
898
+ const envRuntimeMode = normalizeRuntimeMode(processEnv.DOCMAN_RUNTIME_MODE);
899
+ const envLogLevel = normalizeNonEmptyString(processEnv.LOG_LEVEL);
900
+ const envExecutionModeRaw = normalizeNonEmptyString(processEnv.DOCMAN_CLI_EXECUTION_MODE)?.toLowerCase();
901
+ const envExecutionMode = envExecutionModeRaw === 'host' || envExecutionModeRaw === 'tooling'
902
+ ? envExecutionModeRaw
903
+ : undefined;
904
+ const envHostConfigPath = normalizeNonEmptyString(processEnv.DOCMAN_CLI_HOST_CONFIG_PATH)
905
+ ?? normalizeNonEmptyString(processEnv.HOST_NODE_CONFIG);
906
+ const aopsConfigRepoUrl = resolveConfiguredDocmanRepoUrl(processEnv);
907
+ const effectiveRepoUrl = envRepoUrl ?? stored.repoUrl ?? aopsConfigRepoUrl ?? defaultSqliteRepoUrl;
908
+ return {
909
+ configPath: loaded.path,
910
+ exists: loaded.exists,
911
+ stored: maskStoredConfigForDisplay(stored),
912
+ defaults: {
913
+ aopsConfigRepoUrl: maskRepoUrlForDisplay(aopsConfigRepoUrl) ?? null,
914
+ defaultSqlitePath,
915
+ defaultSqliteRepoUrl,
916
+ },
917
+ effective: {
918
+ repoUrl: maskRepoUrlForDisplay(effectiveRepoUrl) ?? null,
919
+ repoUrlSource: envRepoUrl
920
+ ? envRepoUrlBootstrapSource === 'stored-config'
921
+ ? 'stored-config'
922
+ : 'env'
923
+ : stored.repoUrl
924
+ ? 'stored-config'
925
+ : aopsConfigRepoUrl
926
+ ? 'aops-config'
927
+ : 'default-sqlite',
928
+ runtimeMode: envRuntimeMode ?? stored.runtimeMode ?? 'single-user',
929
+ runtimeModeSource: envRuntimeMode ? 'env' : stored.runtimeMode ? 'stored-config' : 'default',
930
+ executionMode: envExecutionMode ?? stored.executionMode ?? 'host',
931
+ executionModeSource: envExecutionMode ? 'env' : stored.executionMode ? 'stored-config' : 'default',
932
+ scopeId: envScopeId ?? stored.scopeId ?? DEFAULT_DOCMAN_SCOPE_ID,
933
+ scopeIdSource: envScopeId ? 'env' : stored.scopeId ? 'stored-config' : 'default',
934
+ tenantId: envTenantId ?? stored.tenantId ?? DEFAULT_TENANT_AS_UUID_STRING,
935
+ tenantIdSource: envTenantId ? 'env' : stored.tenantId ? 'stored-config' : 'default',
936
+ logLevel: envLogLevel ?? stored.logLevel ?? null,
937
+ logLevelSource: envLogLevel ? 'env' : stored.logLevel ? 'stored-config' : 'unset',
938
+ hostConfigPath: envHostConfigPath ?? stored.hostConfigPath ?? null,
939
+ hostConfigPathSource: envHostConfigPath ? 'env' : stored.hostConfigPath ? 'stored-config' : 'unset',
940
+ },
941
+ };
942
+ }
943
+ async function buildRuntimeContext(parsed) {
944
+ sanitizeBlankEnvValues(process.env);
945
+ const storedConfig = readDocmanCliStoredConfig(process.env).config;
946
+ const executionMode = getStringOption(parsed, 'execution-mode');
947
+ if (executionMode) {
948
+ const normalizedMode = executionMode.trim().toLowerCase();
949
+ if (normalizedMode === 'host' || normalizedMode === 'tooling') {
950
+ process.env.DOCMAN_CLI_EXECUTION_MODE = normalizedMode;
951
+ }
952
+ else {
953
+ throw new Error(`invalid_execution_mode:${executionMode}`);
954
+ }
955
+ }
956
+ else if (!normalizeNonEmptyString(process.env.DOCMAN_CLI_EXECUTION_MODE) && storedConfig.executionMode) {
957
+ process.env.DOCMAN_CLI_EXECUTION_MODE = storedConfig.executionMode;
958
+ }
959
+ applyOptionalHostRuntimeEnv(parsed, process.env, storedConfig);
960
+ const runtimeConfig = resolveDocmanRuntimeConfig({
961
+ runtimeMode: getStringOption(parsed, 'runtime-mode'),
962
+ repoUrl: normalizeRepoUrlValue(getStringOption(parsed, 'repo-url')),
963
+ scopeId: getScopeIdOption(parsed),
964
+ }, process.env);
965
+ const resolvedRepoUrl = runtimeConfig.repoUrlSource === 'default-sqlite'
966
+ ? resolveConfiguredDocmanRepoUrl(process.env) ?? runtimeConfig.repoUrl
967
+ : runtimeConfig.repoUrl;
968
+ if (!normalizeNonEmptyString(resolvedRepoUrl)) {
969
+ throw new Error('missing_repo_url:empty');
970
+ }
971
+ const repoDialect = inferDocmanRepoDialect(resolvedRepoUrl);
972
+ applyDocmanRuntimeEnv({
973
+ runtimeMode: runtimeConfig.runtimeMode,
974
+ repoUrl: resolvedRepoUrl,
975
+ repoDialect,
976
+ scopeId: runtimeConfig.scopeId,
977
+ }, process.env);
978
+ if (repoDialect === 'sqlite') {
979
+ ensureDocmanSqliteSchemaReady(resolvedRepoUrl);
980
+ }
981
+ const tenantId = getStringOption(parsed, 'tenant-id')
982
+ ?? normalizeNonEmptyString(process.env.TENANT_ID)
983
+ ?? storedConfig.tenantId
984
+ ?? DEFAULT_TENANT_AS_UUID_STRING;
985
+ const scopeId = normalizeDocmanScopeId(process.env.DOCMAN_SCOPE_ID)
986
+ ?? normalizeDocmanScopeId(process.env.DOCMAN_WORKSPACE_ID)
987
+ ?? storedConfig.scopeId
988
+ ?? DEFAULT_DOCMAN_SCOPE_ID;
989
+ const logLevel = getStringOption(parsed, 'log-level')
990
+ ?? normalizeNonEmptyString(process.env.LOG_LEVEL)
991
+ ?? storedConfig.logLevel;
992
+ process.env.TENANT_ID = tenantId;
993
+ process.env.DOCMAN_SCOPE_ID = scopeId;
994
+ process.env.DOCMAN_WORKSPACE_ID = scopeId;
995
+ if (logLevel)
996
+ process.env.LOG_LEVEL = logLevel;
997
+ sanitizeBlankEnvValues(process.env);
998
+ const { tooling } = await getDocmanCliRuntimeModules();
999
+ tooling.clearDocmanToolingRuntimeCaches();
1000
+ return { scopeId, workspaceId: scopeId, tenantId };
1001
+ }
1002
+ const commandSurface = createDocmanCliCommandSurface({
1003
+ buildConfigSetOutput,
1004
+ buildConfigShowOutput,
1005
+ getStringOption,
1006
+ parseJsonInput,
1007
+ printJson,
1008
+ runOperationById: runDocmanOperationById,
1009
+ writeStoredConfig: writeDocmanCliStoredConfig,
1010
+ });
1011
+ function buildStandaloneRuntimeOutput(params) {
1012
+ return {
1013
+ ok: true,
1014
+ action: params.action,
1015
+ configPath: params.written.path,
1016
+ configExists: params.written.exists,
1017
+ stored: maskStoredConfigForDisplay(params.written.config),
1018
+ runtime: {
1019
+ runtimeMode: params.runtime.runtimeMode,
1020
+ runtimeModeSource: params.runtime.runtimeModeSource,
1021
+ repoUrl: maskRepoUrlForDisplay(params.runtime.repoUrl) ?? params.runtime.repoUrl,
1022
+ repoUrlSource: params.runtime.repoUrlSource,
1023
+ repoDialect: params.runtime.repoDialect,
1024
+ scopeId: params.runtime.scopeId,
1025
+ scopeIdSource: params.runtime.scopeIdSource,
1026
+ },
1027
+ };
1028
+ }
1029
+ async function ensureDocmanRuntimeStorageReady(repoUrl) {
1030
+ if (inferDocmanRepoDialect(repoUrl) === 'sqlite') {
1031
+ ensureDocmanSqliteSchemaReady(repoUrl);
1032
+ return;
1033
+ }
1034
+ await applyDocmanPgSchema({ repoUrl });
1035
+ }
1036
+ async function handleInit(parsed) {
1037
+ const runtimeMode = normalizeRuntimeMode(getStringOption(parsed, 'runtime-mode')) ?? 'single-user';
1038
+ const repoUrl = normalizeRepoUrlValue(getStringOption(parsed, 'repo-url')) ?? getDefaultDocmanSqliteRepoUrl(process.env);
1039
+ const scopeId = normalizeDocmanScopeId(getScopeIdOption(parsed)) ?? DEFAULT_DOCMAN_SCOPE_ID;
1040
+ const written = writeDocmanCliStoredConfig({
1041
+ runtimeMode,
1042
+ repoUrl,
1043
+ scopeId,
1044
+ }, process.env);
1045
+ const runtime = resolveDocmanRuntimeConfig({}, process.env);
1046
+ await ensureDocmanRuntimeStorageReady(runtime.repoUrl);
1047
+ applyDocmanRuntimeEnv({
1048
+ runtimeMode: runtime.runtimeMode,
1049
+ repoUrl: runtime.repoUrl,
1050
+ repoDialect: runtime.repoDialect,
1051
+ scopeId: runtime.scopeId,
1052
+ }, process.env);
1053
+ printJson(buildStandaloneRuntimeOutput({ action: 'init', written, runtime }));
1054
+ }
1055
+ async function handleSetup(subcommand, parsed) {
1056
+ const resolvedSubcommand = subcommand ?? 'runtime';
1057
+ if (resolvedSubcommand !== 'runtime') {
1058
+ throw new Error(`unknown_setup_subcommand:${resolvedSubcommand}`);
1059
+ }
1060
+ const loaded = readDocmanCliStoredConfig(process.env);
1061
+ const nextRepoUrl = normalizeRepoUrlValue(getStringOption(parsed, 'repo-url'))
1062
+ ?? loaded.config.repoUrl
1063
+ ?? inferDefaultRepoUrl(process.env);
1064
+ const nextRuntimeMode = normalizeRuntimeMode(getStringOption(parsed, 'runtime-mode')) ?? loaded.config.runtimeMode ?? 'single-user';
1065
+ const nextScopeId = normalizeDocmanScopeId(getScopeIdOption(parsed))
1066
+ ?? loaded.config.scopeId
1067
+ ?? DEFAULT_DOCMAN_SCOPE_ID;
1068
+ const written = writeDocmanCliStoredConfig({
1069
+ repoUrl: nextRepoUrl,
1070
+ runtimeMode: nextRuntimeMode,
1071
+ scopeId: nextScopeId,
1072
+ }, process.env);
1073
+ const runtime = resolveDocmanRuntimeConfig({}, process.env);
1074
+ await ensureDocmanRuntimeStorageReady(runtime.repoUrl);
1075
+ applyDocmanRuntimeEnv({
1076
+ runtimeMode: runtime.runtimeMode,
1077
+ repoUrl: runtime.repoUrl,
1078
+ repoDialect: runtime.repoDialect,
1079
+ scopeId: runtime.scopeId,
1080
+ }, process.env);
1081
+ printJson(buildStandaloneRuntimeOutput({ action: 'setup-runtime', written, runtime }));
1082
+ }
1083
+ async function buildManifestPayloads() {
1084
+ const { tooling } = await getDocmanCliRuntimeModules();
1085
+ return {
1086
+ dcm: tooling.buildDocmanDomainCapabilityManifest({ includeDocs: true, refresh: true }),
1087
+ routes: tooling.buildDocmanHostRouteProjection({ refresh: true }),
1088
+ agent: tooling.buildDocmanAgentManifest({ refresh: true }),
1089
+ cli: tooling.buildDocmanCliProjection({ refresh: true }),
1090
+ hostRegistration: buildDocmanHostRegistrationManifest({ mode: 'installed' }),
1091
+ operations: tooling.listDocmanToolingOperations({ refresh: true }),
1092
+ };
1093
+ }
1094
+ function resolveManifestArtifactId(identifier, projection) {
1095
+ const normalized = normalizeIdentifier(identifier);
1096
+ for (const artifact of projection.artifacts) {
1097
+ if (normalizeIdentifier(artifact.id) === normalized)
1098
+ return artifact.id;
1099
+ for (const alias of artifact.aliases ?? []) {
1100
+ if (normalizeIdentifier(alias) === normalized)
1101
+ return artifact.id;
1102
+ }
1103
+ }
1104
+ return null;
1105
+ }
1106
+ function getManifestArtifactValue(payloads, artifactId) {
1107
+ if (artifactId === 'dcm')
1108
+ return payloads.dcm;
1109
+ if (artifactId === 'routes')
1110
+ return payloads.routes;
1111
+ if (artifactId === 'agent')
1112
+ return payloads.agent;
1113
+ if (artifactId === 'cli')
1114
+ return payloads.cli;
1115
+ if (artifactId === 'host-registration')
1116
+ return payloads.hostRegistration;
1117
+ return payloads.operations;
1118
+ }
1119
+ function tokenizeManifestPath(rawPath) {
1120
+ return rawPath
1121
+ .replace(/\[(\d+)\]/g, '.$1')
1122
+ .split('.')
1123
+ .map((segment) => segment.trim())
1124
+ .filter(Boolean);
1125
+ }
1126
+ function resolveManifestPathValue(root, rawPath) {
1127
+ if (!rawPath)
1128
+ return { found: true, value: root };
1129
+ const segments = tokenizeManifestPath(rawPath);
1130
+ let current = root;
1131
+ let index = 0;
1132
+ while (index < segments.length) {
1133
+ const segment = segments[index];
1134
+ if (Array.isArray(current)) {
1135
+ const numericIndex = Number(segment);
1136
+ if (!Number.isInteger(numericIndex) || numericIndex < 0 || numericIndex >= current.length) {
1137
+ return { found: false, value: null };
1138
+ }
1139
+ current = current[numericIndex];
1140
+ index += 1;
1141
+ continue;
1142
+ }
1143
+ if (!current || typeof current !== 'object') {
1144
+ return { found: false, value: null };
1145
+ }
1146
+ const record = current;
1147
+ if (Object.prototype.hasOwnProperty.call(record, segment)) {
1148
+ current = record[segment];
1149
+ index += 1;
1150
+ continue;
1151
+ }
1152
+ let matched = false;
1153
+ for (let end = segments.length; end > index; end -= 1) {
1154
+ const composite = segments.slice(index, end).join('.');
1155
+ if (!Object.prototype.hasOwnProperty.call(record, composite))
1156
+ continue;
1157
+ current = record[composite];
1158
+ index = end;
1159
+ matched = true;
1160
+ break;
1161
+ }
1162
+ if (!matched) {
1163
+ return { found: false, value: null };
1164
+ }
1165
+ }
1166
+ return { found: true, value: current };
1167
+ }
1168
+ function renderManifestScalar(value) {
1169
+ if (value === null)
1170
+ return 'null';
1171
+ if (value === undefined)
1172
+ return 'undefined';
1173
+ if (typeof value === 'string')
1174
+ return value;
1175
+ if (typeof value === 'number' || typeof value === 'boolean')
1176
+ return String(value);
1177
+ return JSON.stringify(value);
1178
+ }
1179
+ function renderManifestValueLines(value, indent = '') {
1180
+ if (value === null ||
1181
+ value === undefined ||
1182
+ typeof value === 'string' ||
1183
+ typeof value === 'number' ||
1184
+ typeof value === 'boolean') {
1185
+ return [`${indent}${renderManifestScalar(value)}`];
1186
+ }
1187
+ if (Array.isArray(value)) {
1188
+ if (value.length === 0)
1189
+ return [`${indent}[]`];
1190
+ const lines = [];
1191
+ for (const item of value) {
1192
+ if (item === null ||
1193
+ item === undefined ||
1194
+ typeof item === 'string' ||
1195
+ typeof item === 'number' ||
1196
+ typeof item === 'boolean') {
1197
+ lines.push(`${indent}- ${renderManifestScalar(item)}`);
1198
+ continue;
1199
+ }
1200
+ lines.push(`${indent}-`);
1201
+ lines.push(...renderManifestValueLines(item, `${indent} `));
1202
+ }
1203
+ return lines;
1204
+ }
1205
+ const record = value;
1206
+ const keys = Object.keys(record).sort();
1207
+ if (keys.length === 0)
1208
+ return [`${indent}{}`];
1209
+ const lines = [];
1210
+ for (const key of keys) {
1211
+ const entry = record[key];
1212
+ if (entry === null ||
1213
+ entry === undefined ||
1214
+ typeof entry === 'string' ||
1215
+ typeof entry === 'number' ||
1216
+ typeof entry === 'boolean') {
1217
+ lines.push(`${indent}${key}: ${renderManifestScalar(entry)}`);
1218
+ continue;
1219
+ }
1220
+ lines.push(`${indent}${key}:`);
1221
+ lines.push(...renderManifestValueLines(entry, `${indent} `));
1222
+ }
1223
+ return lines;
1224
+ }
1225
+ function buildManifestShowLines(artifactId, value, rawPath) {
1226
+ const title = `docman manifest show ${artifactId}${rawPath ? ` --path ${rawPath}` : ''}`;
1227
+ if (rawPath) {
1228
+ const lines = [title];
1229
+ appendTextSection(lines, 'Value', renderManifestValueLines(value));
1230
+ return lines;
1231
+ }
1232
+ if (artifactId === 'dcm') {
1233
+ const manifest = toRecord(value);
1234
+ const domain = toRecord(manifest.domain);
1235
+ const capabilities = toRecord(manifest.capabilities);
1236
+ const docs = toRecord(manifest.docs);
1237
+ const domainDocs = toRecord(docs.domain);
1238
+ const operations = Array.isArray(capabilities.operations)
1239
+ ? capabilities.operations
1240
+ : [];
1241
+ const resources = Array.isArray(capabilities.resources)
1242
+ ? capabilities.resources
1243
+ : [];
1244
+ const policyOps = toRecord(toRecord(manifest.policies).operations);
1245
+ const schemaRefs = toRecord(toRecord(manifest.contracts).schemas);
1246
+ const lines = [title];
1247
+ appendTextSection(lines, 'Identity', [
1248
+ `manifest version: ${renderManifestScalar(manifest.manifestVersion)}`,
1249
+ `domain: ${renderManifestScalar(domain.id)} v${renderManifestScalar(domain.version)}`,
1250
+ `display name: ${renderManifestScalar(domain.displayName)}`,
1251
+ ]);
1252
+ appendTextSection(lines, 'Summary', [
1253
+ normalizeNonEmptyString(domain.description) ?? '',
1254
+ normalizeNonEmptyString(domainDocs.summary) ?? '',
1255
+ ]);
1256
+ appendTextSection(lines, 'Counts', [
1257
+ `operations: ${operations.length}`,
1258
+ `resources: ${resources.length}`,
1259
+ `policies: ${Object.keys(policyOps).length}`,
1260
+ `schemas: ${Object.keys(schemaRefs).length}`,
1261
+ ]);
1262
+ appendTextSection(lines, 'Resources', resources.map((resource) => {
1263
+ const resourceId = renderManifestScalar(resource.resourceId);
1264
+ const resourceTitle = normalizeNonEmptyString(resource.title);
1265
+ return resourceTitle ? `${resourceId} ${resourceTitle}` : resourceId;
1266
+ }));
1267
+ appendTextSection(lines, 'Operations', operations.map((operation) => {
1268
+ const operationId = renderManifestScalar(operation.operationId);
1269
+ const operationTitle = normalizeNonEmptyString(operation.title);
1270
+ return operationTitle ? `${operationId} ${operationTitle}` : operationId;
1271
+ }));
1272
+ appendTextSection(lines, 'Browse', [
1273
+ 'docman manifest get dcm --path docs.operations.document.list',
1274
+ 'docman manifest show dcm --path docs.operations.document.list',
1275
+ 'docman manifest get dcm --path contracts.schemas',
1276
+ ]);
1277
+ return lines;
1278
+ }
1279
+ if (artifactId === 'routes') {
1280
+ const routes = Array.isArray(value) ? value : [];
1281
+ const lines = [title];
1282
+ appendTextSection(lines, 'Counts', [`routes: ${routes.length}`]);
1283
+ appendTextSection(lines, 'Routes', routes.map((route) => (`${renderManifestScalar(route.method)} ${renderManifestScalar(route.pattern)} -> ${renderManifestScalar(route.operation)}`)));
1284
+ return lines;
1285
+ }
1286
+ if (artifactId === 'agent') {
1287
+ const manifest = toRecord(value);
1288
+ const tools = Array.isArray(manifest.tools) ? manifest.tools : [];
1289
+ const lines = [title];
1290
+ appendTextSection(lines, 'Identity', [
1291
+ `kind: ${renderManifestScalar(manifest.kind)}`,
1292
+ `version: ${renderManifestScalar(manifest.version)}`,
1293
+ `domain: ${renderManifestScalar(manifest.domain)}`,
1294
+ ]);
1295
+ appendTextSection(lines, 'Counts', [`tools: ${tools.length}`]);
1296
+ appendTextSection(lines, 'Tools', tools.map((tool) => {
1297
+ const toolId = renderManifestScalar(tool.toolId);
1298
+ const summary = normalizeNonEmptyString(tool.summary);
1299
+ return summary ? `${toolId} ${summary}` : toolId;
1300
+ }));
1301
+ return lines;
1302
+ }
1303
+ if (artifactId === 'cli') {
1304
+ const projection = value;
1305
+ const commands = Array.isArray(projection.commands) ? projection.commands : [];
1306
+ const staticCount = commands.filter((command) => command.kind !== 'operation').length;
1307
+ const operationCount = commands.filter((command) => command.kind === 'operation').length;
1308
+ const lines = [title];
1309
+ appendTextSection(lines, 'Identity', [
1310
+ `kind: ${projection.kind}`,
1311
+ `version: ${projection.version}`,
1312
+ `domain: ${projection.domain}`,
1313
+ ]);
1314
+ appendTextSection(lines, 'Counts', [
1315
+ `commands: ${commands.length}`,
1316
+ `static/root commands: ${staticCount}`,
1317
+ `operation commands: ${operationCount}`,
1318
+ `artifacts: ${projection.artifacts.length}`,
1319
+ ]);
1320
+ appendTextSection(lines, 'Source of Truth', projection.sourceOfTruth.notes);
1321
+ appendTextSection(lines, 'Browse', [
1322
+ 'docman manifest get cli --path commandsById.config.set',
1323
+ 'docman manifest get cli --path commandsById.document.list',
1324
+ 'docman manifest show cli --path commandsById.document.compose.fetch',
1325
+ ]);
1326
+ appendTextSection(lines, 'Commands', commands.map((command) => {
1327
+ const summary = normalizeNonEmptyString(command.summary);
1328
+ return summary ? `${command.id} ${summary}` : command.id;
1329
+ }));
1330
+ return lines;
1331
+ }
1332
+ if (artifactId === 'host-registration') {
1333
+ const manifest = toRecord(value);
1334
+ const providers = Array.isArray(manifest.manifestProviders)
1335
+ ? manifest.manifestProviders
1336
+ : [];
1337
+ const plugins = Array.isArray(manifest.plugins)
1338
+ ? manifest.plugins
1339
+ : [];
1340
+ const lines = [title];
1341
+ appendTextSection(lines, 'Identity', [
1342
+ `kind: ${renderManifestScalar(manifest.kind)}`,
1343
+ `domain: ${renderManifestScalar(manifest.domain)}`,
1344
+ `packageName: ${renderManifestScalar(manifest.packageName)}`,
1345
+ `baseDir: ${renderManifestScalar(manifest.baseDir)}`,
1346
+ ]);
1347
+ appendTextSection(lines, 'Description', [normalizeNonEmptyString(manifest.description) ?? '']);
1348
+ appendTextSection(lines, 'Manifest Providers', providers.map((provider) => (`${renderManifestScalar(provider.id)} -> ${renderManifestScalar(provider.module)}#${renderManifestScalar(provider.exportName)}`)));
1349
+ appendTextSection(lines, 'Plugins', plugins.map((plugin) => (`${renderManifestScalar(plugin.domain)} -> ${renderManifestScalar(plugin.module)}#${renderManifestScalar(plugin.factory)}`)));
1350
+ appendTextSection(lines, 'Notes', toStringList(manifest.notes));
1351
+ return lines;
1352
+ }
1353
+ const operations = Array.isArray(value) ? value : [];
1354
+ const lines = [title];
1355
+ appendTextSection(lines, 'Counts', [`operations: ${operations.length}`]);
1356
+ appendTextSection(lines, 'Operations', operations.map((operation) => {
1357
+ const operationId = renderManifestScalar(operation.operationId);
1358
+ const summary = normalizeNonEmptyString(operation.summary);
1359
+ return summary ? `${operationId} ${summary}` : operationId;
1360
+ }));
1361
+ return lines;
1362
+ }
1363
+ async function handleManifest(parsed) {
1364
+ const subcommand = normalizeManifestHelpSubcommand(parsed.positionals[1]?.toLowerCase());
1365
+ const payloads = await buildManifestPayloads();
1366
+ const projection = payloads.cli;
1367
+ if (!subcommand || subcommand === 'all') {
1368
+ printJson({
1369
+ dcm: payloads.dcm,
1370
+ routes: payloads.routes,
1371
+ agent: payloads.agent,
1372
+ cli: payloads.cli,
1373
+ hostRegistration: payloads.hostRegistration,
1374
+ operations: payloads.operations,
1375
+ });
1376
+ return;
1377
+ }
1378
+ if (subcommand === 'get' || subcommand === 'show') {
1379
+ const artifactInput = parsed.positionals[2];
1380
+ if (!artifactInput)
1381
+ throw new Error('missing_required_option:<artifact>');
1382
+ const artifactId = resolveManifestArtifactId(artifactInput, projection);
1383
+ if (!artifactId)
1384
+ throw new Error(`unknown_manifest_artifact:${artifactInput}`);
1385
+ const rawPath = getStringOption(parsed, 'path');
1386
+ const target = getManifestArtifactValue(payloads, artifactId);
1387
+ const resolved = resolveManifestPathValue(target, rawPath);
1388
+ if (!resolved.found) {
1389
+ throw new Error(`manifest_path_not_found:${artifactId}:${rawPath ?? '<root>'}`);
1390
+ }
1391
+ if (subcommand === 'get') {
1392
+ printJson(resolved.value);
1393
+ return;
1394
+ }
1395
+ printHelpLines(buildManifestShowLines(artifactId, resolved.value, rawPath));
1396
+ return;
1397
+ }
1398
+ const artifactId = resolveManifestArtifactId(subcommand, projection);
1399
+ if (!artifactId) {
1400
+ throw new Error(`unknown_manifest_subcommand:${subcommand}`);
1401
+ }
1402
+ printJson(getManifestArtifactValue(payloads, artifactId));
1403
+ }
1404
+ async function executeResolvedOperation(operationId, parsed, runtime, operationMap, options) {
1405
+ const allowHooks = options?.allowHooks !== false;
1406
+ if (allowHooks) {
1407
+ const handledByHook = await commandSurface.tryExecuteOperationViaHook(operationId, parsed);
1408
+ if (handledByHook)
1409
+ return;
1410
+ }
1411
+ const { tooling } = await getDocmanCliRuntimeModules();
1412
+ const operation = operationMap.get(operationId) ?? tooling.getDocmanOperationSpecById(operationId, { refresh: true });
1413
+ if (!operation) {
1414
+ throw new Error(`unknown_docman_operation:${operationId}`);
1415
+ }
1416
+ const input = buildGeneratedOperationInput(operation, parsed, runtime);
1417
+ const output = await runDocmanOperationById(operation.operationId, input);
1418
+ printJson(output);
1419
+ }
1420
+ async function main() {
1421
+ const parsed = parseArgv(process.argv.slice(2));
1422
+ const helpMode = parsed.positionals[0]?.toLowerCase() === 'help';
1423
+ const effectiveParsed = helpMode
1424
+ ? {
1425
+ positionals: parsed.positionals.slice(1),
1426
+ options: {
1427
+ ...parsed.options,
1428
+ help: true,
1429
+ },
1430
+ }
1431
+ : parsed;
1432
+ const command = effectiveParsed.positionals[0]?.toLowerCase();
1433
+ const subcommand = effectiveParsed.positionals[1]?.toLowerCase();
1434
+ const helpRequested = getBooleanOption(effectiveParsed, 'help', false);
1435
+ if (getBooleanOption(parsed, 'version', false) || (command === 'version' && !helpRequested)) {
1436
+ printVersion();
1437
+ return;
1438
+ }
1439
+ if (!command || helpRequested) {
1440
+ if (command && await tryPrintCommandHelp(effectiveParsed))
1441
+ return;
1442
+ await printHelp();
1443
+ return;
1444
+ }
1445
+ if (command === 'tools') {
1446
+ const { tooling } = await getDocmanCliRuntimeModules();
1447
+ printJson(tooling.listDocmanToolingTools({ refresh: true }));
1448
+ return;
1449
+ }
1450
+ if (command === 'init') {
1451
+ await handleInit(effectiveParsed);
1452
+ return;
1453
+ }
1454
+ if (command === 'setup') {
1455
+ await handleSetup(subcommand, effectiveParsed);
1456
+ return;
1457
+ }
1458
+ if (command === 'ops') {
1459
+ const { tooling } = await getDocmanCliRuntimeModules();
1460
+ printJson(tooling.listDocmanToolingOperations({ refresh: true }));
1461
+ return;
1462
+ }
1463
+ if (command === 'manifest') {
1464
+ await handleManifest(effectiveParsed);
1465
+ return;
1466
+ }
1467
+ if (command === 'config') {
1468
+ await commandSurface.handleConfig(subcommand, effectiveParsed);
1469
+ return;
1470
+ }
1471
+ const { tooling } = await getDocmanCliRuntimeModules();
1472
+ const operationSpecs = tooling.listDocmanToolingOperations({ refresh: true });
1473
+ const operationMap = new Map(operationSpecs.map((operation) => [normalizeOperationIdentifier(operation.operationId), operation]));
1474
+ const resolvedOperationId = await resolveGeneratedOperationId(effectiveParsed, operationMap);
1475
+ const rawOperationMode = command ? DIRECT_OPERATION_COMMANDS.has(command) : false;
1476
+ const hooksDisabled = areHooksDisabled(effectiveParsed);
1477
+ if (!resolvedOperationId && DIRECT_OPERATION_COMMANDS.has(command)) {
1478
+ throw new Error(`unknown_operation_command:${command}`);
1479
+ }
1480
+ if (command === 'tool' || command === 'invoke') {
1481
+ await buildRuntimeContext(effectiveParsed);
1482
+ const identifier = requireStringOption(effectiveParsed, 'id', '--id');
1483
+ const input = parseJsonInput(getStringOption(effectiveParsed, 'input'), 'input') ?? {};
1484
+ const output = await runDocmanToolById(identifier, input);
1485
+ printJson(output);
1486
+ return;
1487
+ }
1488
+ const runtime = await buildRuntimeContext(effectiveParsed);
1489
+ if (resolvedOperationId) {
1490
+ const allowHooks = !rawOperationMode && !hooksDisabled;
1491
+ await executeResolvedOperation(resolvedOperationId, effectiveParsed, runtime, operationMap, { allowHooks });
1492
+ return;
1493
+ }
1494
+ throw new Error(`unknown_command:${command}`);
1495
+ }
1496
+ async function disconnectRepoHandles() {
1497
+ try {
1498
+ const drizzleModule = await import('@aopslab/xf-db-drizzle');
1499
+ const tasks = [];
1500
+ if (typeof drizzleModule.drizzleDisconnect === 'function') {
1501
+ tasks.push(drizzleModule.drizzleDisconnect());
1502
+ }
1503
+ if (typeof drizzleModule.drizzleSqliteDisconnect === 'function') {
1504
+ tasks.push(drizzleModule.drizzleSqliteDisconnect());
1505
+ }
1506
+ if (tasks.length > 0) {
1507
+ await Promise.allSettled(tasks);
1508
+ }
1509
+ }
1510
+ catch { }
1511
+ }
1512
+ void (async () => {
1513
+ try {
1514
+ await main();
1515
+ }
1516
+ catch (error) {
1517
+ const message = error instanceof Error ? error.message : String(error);
1518
+ process.stderr.write(`${message}\n`);
1519
+ process.exitCode = 1;
1520
+ }
1521
+ finally {
1522
+ await disconnectRepoHandles();
1523
+ }
1524
+ })();