@xdsjs/dossierx-daemon 0.1.13 → 0.1.14

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 (2) hide show
  1. package/dist/index.js +1455 -197
  2. package/package.json +3 -3
package/dist/index.js CHANGED
@@ -1,26 +1,912 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  // src/cli.ts
4
- import { mkdir as mkdir7, stat as stat4 } from "fs/promises";
4
+ import { mkdir as mkdir9, stat as stat5 } from "fs/promises";
5
5
  import os3 from "os";
6
- import path10 from "path";
6
+ import path14 from "path";
7
7
  import { Command } from "commander";
8
- import { DOSSIERX_DEFAULT_WORKSPACE_PATH } from "@xdsjs/dossierx-workspace";
8
+
9
+ // ../../node_modules/.pnpm/@xdsjs+dossierx-workspace@0.1.1/node_modules/@xdsjs/dossierx-workspace/dist/index.js
10
+ import path from "path";
11
+ import { createHash } from "crypto";
12
+ import { mkdir, readdir, readFile, stat, writeFile } from "fs/promises";
13
+ import path2 from "path";
14
+
15
+ // ../../node_modules/.pnpm/@xdsjs+dossierx-shared@0.1.5/node_modules/@xdsjs/dossierx-shared/dist/index.js
16
+ import { z } from "zod";
17
+ import { z as z2 } from "zod";
18
+ import { z as z3 } from "zod";
19
+ import { z as z4 } from "zod";
20
+ import { z as z5 } from "zod";
21
+ import { z as z6 } from "zod";
22
+ import { z as z7 } from "zod";
23
+ import { z as z8 } from "zod";
24
+ import { z as z9 } from "zod";
25
+ import { z as z10 } from "zod";
26
+ var MarketSchema = z.enum(["us", "hk", "cn"]);
27
+ var TickerSchema = z.string().min(1).max(16).transform((value) => value.trim().toUpperCase());
28
+ var ISO_DATE_TIME_PATTERN = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d+)?(?:Z|[+-]\d{2}:\d{2})$/;
29
+ var ISODateTimeSchema = z.string().refine(
30
+ (value) => ISO_DATE_TIME_PATTERN.test(value) && !Number.isNaN(Date.parse(value)),
31
+ "Invalid ISO datetime"
32
+ );
33
+ var JsonObjectSchema = z.record(z.string(), z.unknown());
34
+ var MachineStatusSchema = z2.enum([
35
+ "offline",
36
+ "online",
37
+ "idle",
38
+ "running",
39
+ "error"
40
+ ]);
41
+ var DaemonCapabilitiesSchema = z2.object({
42
+ git: z2.boolean().default(false),
43
+ node: z2.boolean().default(false),
44
+ python: z2.boolean().default(false),
45
+ financialReports: z2.boolean().default(false),
46
+ financialReportsNotebookLm: z2.boolean().default(false),
47
+ financialReportsSecHtmlRenderer: z2.boolean().default(false),
48
+ investWikiRuntime: z2.boolean().default(false),
49
+ codex: z2.boolean().default(false),
50
+ claude: z2.boolean().default(false)
51
+ });
52
+ var WorkspaceStatusSchema = z3.enum(["ready", "missing", "error"]);
53
+ var MachineTopicSchema = z4.string().regex(/^machine:[a-f0-9-]+$/);
54
+ var TaskAvailableEventSchema = z4.object({
55
+ event: z4.literal("task_available"),
56
+ payload: z4.object({
57
+ taskId: z4.string().uuid(),
58
+ createdAt: ISODateTimeSchema
59
+ })
60
+ });
61
+ var TaskCancelledEventSchema = z4.object({
62
+ event: z4.literal("task_cancelled"),
63
+ payload: z4.object({
64
+ taskId: z4.string().uuid()
65
+ })
66
+ });
67
+ var RealtimeEventSchema = z4.discriminatedUnion("event", [
68
+ TaskAvailableEventSchema,
69
+ TaskCancelledEventSchema
70
+ ]);
71
+ var ManifestPageTypeSchema = z5.enum([
72
+ "right_business",
73
+ "right_people",
74
+ "right_price",
75
+ "wiki",
76
+ "article",
77
+ "source_note"
78
+ ]);
79
+ var ManifestPageSchema = z5.object({
80
+ type: ManifestPageTypeSchema,
81
+ title: z5.string(),
82
+ path: z5.string(),
83
+ size: z5.number().int().nonnegative(),
84
+ hash: z5.string(),
85
+ updatedAt: ISODateTimeSchema
86
+ });
87
+ var CompanyManifestSchema = z5.object({
88
+ schemaVersion: z5.literal(1),
89
+ ticker: TickerSchema,
90
+ market: MarketSchema,
91
+ updatedAt: ISODateTimeSchema,
92
+ commitSha: z5.string().optional(),
93
+ pages: z5.array(ManifestPageSchema)
94
+ });
95
+ var TaskStatusSchema = z6.enum([
96
+ "queued",
97
+ "claimed",
98
+ "running",
99
+ "succeeded",
100
+ "failed",
101
+ "cancelled"
102
+ ]);
103
+ var TaskTypeSchema = z6.enum([
104
+ "mock.write_company_report",
105
+ "workspace.scan",
106
+ "invest_wiki.init_company_vault",
107
+ "invest_wiki.status",
108
+ "invest_wiki.sync",
109
+ "codex.run_invest_wiki_flow",
110
+ "financial_reports.sync_reports",
111
+ "financial_reports.ingest_notebook",
112
+ "financial_reports.extract_facts",
113
+ "financial_reports.refresh_company"
114
+ ]);
115
+ var MockWriteCompanyReportPayloadSchema = z6.object({
116
+ ticker: TickerSchema,
117
+ market: MarketSchema.default("us"),
118
+ companyName: z6.string().optional()
119
+ });
120
+ var WorkspaceScanPayloadSchema = z6.object({});
121
+ var InvestWikiInitCompanyVaultPayloadSchema = z6.object({
122
+ ticker: TickerSchema,
123
+ market: MarketSchema.default("us"),
124
+ companyName: z6.string().trim().min(1),
125
+ cik: z6.string().trim().min(1).optional(),
126
+ exchange: z6.string().trim().min(1).optional()
127
+ });
128
+ var InvestWikiStatusPayloadSchema = z6.object({
129
+ ticker: TickerSchema
130
+ });
131
+ var InvestWikiSyncPayloadSchema = z6.object({
132
+ ticker: TickerSchema,
133
+ dryRun: z6.boolean().default(false)
134
+ });
135
+ var CodexRunInvestWikiFlowPayloadSchema = z6.object({
136
+ ticker: TickerSchema,
137
+ market: z6.literal("us").default("us"),
138
+ companyName: z6.string().trim().min(1).optional(),
139
+ cik: z6.string().trim().min(1).optional(),
140
+ exchange: z6.string().trim().min(1).optional()
141
+ });
142
+ var FinancialReportMarketSchema = z6.enum(["US", "A", "H"]);
143
+ var FinancialReportTypeSchema = z6.enum([
144
+ "annual",
145
+ "half_year",
146
+ "q1",
147
+ "q3"
148
+ ]);
149
+ var FinancialReportListingSchema = z6.object({
150
+ market: FinancialReportMarketSchema,
151
+ ticker: z6.string().trim().min(1).max(32).transform((value) => value.toUpperCase()),
152
+ exchange: z6.string().trim().min(1).optional(),
153
+ currency: z6.string().trim().min(1).optional(),
154
+ primary: z6.boolean().default(false)
155
+ });
156
+ var FinancialReportCninfoIdentifierSchema = z6.object({
157
+ stockCode: z6.string().trim().min(1),
158
+ orgId: z6.string().trim().min(1),
159
+ column: z6.enum(["sse", "szse", "hke"])
160
+ });
161
+ var FinancialReportIssuerIdentifiersSchema = z6.object({
162
+ cik: z6.string().trim().min(1).optional(),
163
+ cninfoCode: z6.string().trim().min(1).optional(),
164
+ hkexStockCode: z6.string().trim().min(1).optional(),
165
+ cninfo: FinancialReportCninfoIdentifierSchema.optional(),
166
+ lei: z6.string().trim().min(1).optional(),
167
+ isin: z6.string().trim().min(1).optional()
168
+ }).default({});
169
+ function primaryFinancialReportMarket(listings) {
170
+ return listings.find((listing) => listing.primary)?.market ?? listings[0]?.market;
171
+ }
172
+ var FinancialReportIssuerPayloadSchema = z6.object({
173
+ issuerId: z6.string().trim().min(1),
174
+ companyId: z6.string().trim().min(1),
175
+ displayName: z6.string().trim().min(1),
176
+ legalName: z6.string().trim().min(1),
177
+ domicile: z6.string().trim().min(1).optional(),
178
+ listings: z6.array(FinancialReportListingSchema).min(1),
179
+ identifiers: FinancialReportIssuerIdentifiersSchema
180
+ }).superRefine((issuer, context) => {
181
+ const market = primaryFinancialReportMarket(issuer.listings);
182
+ if (market === "US" && !issuer.identifiers.cik) {
183
+ context.addIssue({
184
+ code: "custom",
185
+ path: ["identifiers", "cik"],
186
+ message: "US financial report issuers require SEC CIK"
187
+ });
188
+ }
189
+ if ((market === "A" || market === "H") && !issuer.identifiers.cninfo) {
190
+ context.addIssue({
191
+ code: "custom",
192
+ path: ["identifiers", "cninfo"],
193
+ message: "A/H financial report issuers require CNinfo identifiers"
194
+ });
195
+ }
196
+ });
197
+ var FinancialReportYearsSchema = z6.array(z6.number().int().min(1990).max(2100)).min(1);
198
+ var FinancialReportTypesPayloadSchema = z6.array(FinancialReportTypeSchema).min(1).optional();
199
+ var FinancialReportsSyncPayloadSchema = z6.object({
200
+ issuer: FinancialReportIssuerPayloadSchema,
201
+ fiscalYears: FinancialReportYearsSchema,
202
+ reportTypes: FinancialReportTypesPayloadSchema
203
+ });
204
+ var FinancialReportsIngestNotebookPayloadSchema = z6.object({
205
+ issuer: FinancialReportIssuerPayloadSchema,
206
+ manifestPath: z6.string().trim().min(1),
207
+ factsAsOf: z6.string().trim().min(1).optional(),
208
+ notebookTitle: z6.string().trim().min(1).optional()
209
+ });
210
+ var FinancialReportsExtractFactsPayloadSchema = FinancialReportsIngestNotebookPayloadSchema;
211
+ var FinancialReportsRefreshCompanyPayloadSchema = z6.object({
212
+ issuer: FinancialReportIssuerPayloadSchema,
213
+ fiscalYears: FinancialReportYearsSchema,
214
+ reportTypes: FinancialReportTypesPayloadSchema,
215
+ factsAsOf: z6.string().trim().min(1).optional(),
216
+ notebookTitle: z6.string().trim().min(1).optional()
217
+ });
218
+ var TaskSchema = z6.discriminatedUnion("type", [
219
+ z6.object({
220
+ id: z6.string().uuid(),
221
+ type: z6.literal("mock.write_company_report"),
222
+ payload: MockWriteCompanyReportPayloadSchema
223
+ }),
224
+ z6.object({
225
+ id: z6.string().uuid(),
226
+ type: z6.literal("workspace.scan"),
227
+ payload: WorkspaceScanPayloadSchema
228
+ }),
229
+ z6.object({
230
+ id: z6.string().uuid(),
231
+ type: z6.literal("invest_wiki.init_company_vault"),
232
+ payload: InvestWikiInitCompanyVaultPayloadSchema
233
+ }),
234
+ z6.object({
235
+ id: z6.string().uuid(),
236
+ type: z6.literal("invest_wiki.status"),
237
+ payload: InvestWikiStatusPayloadSchema
238
+ }),
239
+ z6.object({
240
+ id: z6.string().uuid(),
241
+ type: z6.literal("invest_wiki.sync"),
242
+ payload: InvestWikiSyncPayloadSchema
243
+ }),
244
+ z6.object({
245
+ id: z6.string().uuid(),
246
+ type: z6.literal("codex.run_invest_wiki_flow"),
247
+ payload: CodexRunInvestWikiFlowPayloadSchema
248
+ }),
249
+ z6.object({
250
+ id: z6.string().uuid(),
251
+ type: z6.literal("financial_reports.sync_reports"),
252
+ payload: FinancialReportsSyncPayloadSchema
253
+ }),
254
+ z6.object({
255
+ id: z6.string().uuid(),
256
+ type: z6.literal("financial_reports.ingest_notebook"),
257
+ payload: FinancialReportsIngestNotebookPayloadSchema
258
+ }),
259
+ z6.object({
260
+ id: z6.string().uuid(),
261
+ type: z6.literal("financial_reports.extract_facts"),
262
+ payload: FinancialReportsExtractFactsPayloadSchema
263
+ }),
264
+ z6.object({
265
+ id: z6.string().uuid(),
266
+ type: z6.literal("financial_reports.refresh_company"),
267
+ payload: FinancialReportsRefreshCompanyPayloadSchema
268
+ })
269
+ ]);
270
+ var TaskEventLevelSchema = z6.enum([
271
+ "debug",
272
+ "info",
273
+ "warn",
274
+ "error"
275
+ ]);
276
+ var TaskEventInputSchema = z6.object({
277
+ level: TaskEventLevelSchema.default("info"),
278
+ message: z6.string().min(1).max(2e3),
279
+ data: z6.record(z6.string(), z6.unknown()).default({})
280
+ });
281
+ var CoverageStateSchema = z7.enum(["complete", "incomplete", "unknown"]);
282
+ var CoverageBlockingReasonSchema = z7.object({
283
+ code: z7.string().trim().min(1),
284
+ message: z7.string().trim().min(1),
285
+ expectationId: z7.string().trim().min(1)
286
+ });
287
+ var CoverageSummarySchema = z7.object({
288
+ requiredTotal: z7.number().int().nonnegative().optional(),
289
+ requiredFound: z7.number().int().nonnegative().optional(),
290
+ requiredMissing: z7.number().int().nonnegative().optional(),
291
+ requiredFailed: z7.number().int().nonnegative().optional(),
292
+ optionalTotal: z7.number().int().nonnegative().optional()
293
+ });
294
+ var FinancialReportCoverageStatusSchema = z7.enum([
295
+ "complete",
296
+ "partial",
297
+ "incomplete"
298
+ ]);
299
+ var FinancialReportsTaskResultSchema = z7.object({
300
+ schemaVersion: z7.literal("financial-reports/task-result/v1"),
301
+ issuerId: z7.string().trim().min(1),
302
+ companyId: z7.string().trim().min(1),
303
+ ticker: z7.string().trim().min(1),
304
+ manifestPath: z7.string().trim().min(1).optional(),
305
+ manifestHash: z7.string().regex(/^sha256:[a-f0-9]{64}$/i).optional(),
306
+ notebookPath: z7.string().trim().min(1).optional(),
307
+ factsBundlePath: z7.string().trim().min(1).optional(),
308
+ wikiPath: z7.string().trim().min(1).optional(),
309
+ reportCount: z7.number().int().nonnegative().optional(),
310
+ coverageStatus: FinancialReportCoverageStatusSchema.optional(),
311
+ blockingReasons: z7.array(z7.string().trim().min(1)).default([])
312
+ });
313
+ var GitSnapshotSchema = z7.object({
314
+ status: z7.enum(["published", "unchanged"]),
315
+ commitSha: z7.string().optional(),
316
+ previousCommitSha: z7.string().optional(),
317
+ treeHash: z7.string(),
318
+ branch: z7.string(),
319
+ pushed: z7.boolean(),
320
+ remoteUrl: z7.string().optional(),
321
+ generatedAt: z7.string()
322
+ });
323
+ var TaskResultSchema = z7.object({
324
+ generatedFiles: z7.array(z7.string()).default([]),
325
+ manifestPath: z7.string().optional(),
326
+ manifest: CompanyManifestSchema.optional(),
327
+ commitSha: z7.string().optional(),
328
+ gitSnapshot: GitSnapshotSchema.optional(),
329
+ schemaVersion: z7.string().optional(),
330
+ runId: z7.string().optional(),
331
+ bundlePath: z7.string().optional(),
332
+ sourceInventoryPath: z7.string().optional(),
333
+ qualityReportPath: z7.string().optional(),
334
+ coverageState: CoverageStateSchema.optional(),
335
+ commercialReportAllowed: z7.boolean().optional(),
336
+ blockingReasons: z7.array(CoverageBlockingReasonSchema).default([]),
337
+ coverageSummary: CoverageSummarySchema.optional(),
338
+ financialReports: FinancialReportsTaskResultSchema.optional()
339
+ });
340
+ var AgentRuntimeSchema = z8.enum(["codex_cli"]);
341
+ var AgentStatusSchema = z8.enum(["ready", "disabled", "error"]);
342
+ var AgentReasoningEffortSchema = z8.enum([
343
+ "low",
344
+ "medium",
345
+ "high",
346
+ "xhigh"
347
+ ]);
348
+ var AgentAllowedTaskTypeSchema = z8.enum([
349
+ "invest_wiki.init_company_vault",
350
+ "invest_wiki.sync",
351
+ "codex.run_invest_wiki_flow",
352
+ "financial_reports.sync_reports",
353
+ "financial_reports.ingest_notebook",
354
+ "financial_reports.extract_facts",
355
+ "financial_reports.refresh_company"
356
+ ]);
357
+ var AgentConfigSchema = z8.object({
358
+ defaultSkill: z8.string().trim().min(1).default("invest-wiki-flow"),
359
+ workspaceRoot: z8.string().trim().min(1).default("~/dossierx"),
360
+ networkAccess: z8.boolean().default(true),
361
+ allowOutsideWorkspace: z8.boolean().default(false),
362
+ codexCommand: z8.string().trim().min(1).default("codex"),
363
+ codexVersion: z8.string().trim().min(1).optional(),
364
+ codexSandbox: z8.enum(["workspace-write", "danger-full-access"]).default("danger-full-access"),
365
+ allowedTaskTypes: z8.array(AgentAllowedTaskTypeSchema).default([
366
+ "invest_wiki.init_company_vault",
367
+ "invest_wiki.sync",
368
+ "codex.run_invest_wiki_flow"
369
+ ])
370
+ });
371
+ var CreateAgentRequestSchema = z8.object({
372
+ machineId: z8.string().uuid(),
373
+ name: z8.string().trim().min(1).max(120),
374
+ description: z8.string().trim().max(3e3).optional(),
375
+ runtime: AgentRuntimeSchema.default("codex_cli"),
376
+ model: z8.string().trim().min(1).max(80).default("gpt-5.5"),
377
+ reasoningEffort: AgentReasoningEffortSchema.default("medium"),
378
+ config: z8.unknown().optional().transform((value) => AgentConfigSchema.parse(value ?? {}))
379
+ });
380
+ var UpdateAgentRequestSchema = z8.object({
381
+ machineId: z8.string().uuid(),
382
+ name: z8.string().trim().min(1).max(120),
383
+ description: z8.string().trim().max(3e3).optional(),
384
+ model: z8.string().trim().min(1).max(80),
385
+ reasoningEffort: AgentReasoningEffortSchema,
386
+ config: z8.unknown().transform((value) => AgentConfigSchema.parse(value ?? {}))
387
+ });
388
+ var DaemonBootstrapRequestSchema = z9.object({
389
+ hostname: z9.string(),
390
+ os: z9.string(),
391
+ workspacePath: z9.string(),
392
+ daemonVersion: z9.string(),
393
+ capabilities: DaemonCapabilitiesSchema
394
+ });
395
+ var DaemonBootstrapResponseSchema = z9.object({
396
+ machineId: z9.string().uuid(),
397
+ workspaceId: z9.string().uuid(),
398
+ realtime: z9.object({
399
+ topic: MachineTopicSchema,
400
+ private: z9.boolean().default(false)
401
+ }),
402
+ polling: z9.object({
403
+ fallbackIntervalMs: z9.number().int().positive()
404
+ }),
405
+ limits: z9.object({
406
+ maxEventBatchSize: z9.number().int().positive(),
407
+ maxPayloadBytes: z9.number().int().positive()
408
+ })
409
+ });
410
+ var DaemonHeartbeatRequestSchema = z9.object({
411
+ machineId: z9.string().uuid(),
412
+ workspacePath: z9.string(),
413
+ status: MachineStatusSchema,
414
+ capabilities: DaemonCapabilitiesSchema,
415
+ currentTaskId: z9.string().uuid().optional()
416
+ });
417
+ var DaemonHeartbeatResponseSchema = z9.object({
418
+ ok: z9.boolean(),
419
+ nextHeartbeatMs: z9.number().int().positive()
420
+ });
421
+ var ClaimTaskRequestSchema = z9.object({
422
+ machineId: z9.string().uuid(),
423
+ maxTasks: z9.number().int().min(1).max(1).default(1)
424
+ });
425
+ var ClaimedTaskAgentSchema = z9.object({
426
+ id: z9.string().uuid(),
427
+ runtime: AgentRuntimeSchema,
428
+ model: z9.string().trim().min(1),
429
+ reasoningEffort: AgentReasoningEffortSchema,
430
+ config: AgentConfigSchema
431
+ });
432
+ var ClaimTaskResponseSchema = z9.object({
433
+ task: TaskSchema.nullable(),
434
+ agent: ClaimedTaskAgentSchema.nullable().default(null),
435
+ retryAfterMs: z9.number().int().positive()
436
+ });
437
+ var AppendTaskEventsRequestSchema = z9.object({
438
+ events: z9.array(TaskEventInputSchema).min(1).max(50)
439
+ });
440
+ var AppendTaskEventsResponseSchema = z9.object({
441
+ ok: z9.boolean()
442
+ });
443
+ var CompleteTaskRequestSchema = z9.object({
444
+ result: TaskResultSchema.prefault({})
445
+ });
446
+ var CompleteTaskResponseSchema = z9.object({
447
+ ok: z9.boolean()
448
+ });
449
+ var FailTaskRequestSchema = z9.object({
450
+ error: z9.object({
451
+ code: z9.string(),
452
+ message: z9.string(),
453
+ step: z9.string().optional(),
454
+ recoverable: z9.boolean().default(false)
455
+ })
456
+ });
457
+ var FailTaskResponseSchema = z9.object({
458
+ ok: z9.boolean()
459
+ });
460
+ var DaemonErrorCodeSchema = z10.enum([
461
+ "AUTH_FAILED",
462
+ "WORKSPACE_NOT_FOUND",
463
+ "WORKSPACE_ACCESS_DENIED",
464
+ "RUNTIME_NOT_FOUND",
465
+ "COMMAND_FAILED",
466
+ "TASK_CANCELLED",
467
+ "GIT_FAILED",
468
+ "GIT_PUSH_DENIED",
469
+ "NETWORK_ERROR",
470
+ "VALIDATION_ERROR",
471
+ "UNKNOWN"
472
+ ]);
473
+
474
+ // ../../node_modules/.pnpm/@xdsjs+dossierx-workspace@0.1.1/node_modules/@xdsjs/dossierx-workspace/dist/index.js
475
+ import { readFile as readFile2 } from "fs/promises";
476
+ import path3 from "path";
477
+ import { z as z11 } from "zod";
478
+ function resolveInsideWorkspace(root, relativePath) {
479
+ if (!path.isAbsolute(root)) {
480
+ throw new Error("Workspace root must be absolute");
481
+ }
482
+ if (path.isAbsolute(relativePath)) {
483
+ throw new Error("Path must be relative to workspace");
484
+ }
485
+ const resolvedRoot = path.resolve(root);
486
+ const resolvedTarget = path.resolve(root, relativePath);
487
+ if (resolvedTarget !== resolvedRoot && !resolvedTarget.startsWith(resolvedRoot + path.sep)) {
488
+ throw new Error("Path escapes workspace");
489
+ }
490
+ return resolvedTarget;
491
+ }
492
+ function sha256Text(content) {
493
+ return `sha256:${createHash("sha256").update(content).digest("hex")}`;
494
+ }
495
+ var DOSSIERX_CONFIG_DIR = "~/.dossierx";
496
+ var DOSSIERX_DEFAULT_WORKSPACE_PATH = "~/dossierx";
497
+ function normalizeTicker(ticker) {
498
+ return ticker.trim().toUpperCase();
499
+ }
500
+ function companyRoot(ticker) {
501
+ return `companies/${normalizeTicker(ticker)}`;
502
+ }
503
+ function companyManifestPath(ticker) {
504
+ return `${companyRoot(ticker)}/manifest.json`;
505
+ }
506
+ function rightRoot(ticker) {
507
+ return `${companyRoot(ticker)}/right`;
508
+ }
509
+ function rightBusinessPath(ticker) {
510
+ return `${rightRoot(ticker)}/right-business.md`;
511
+ }
512
+ function rightPeoplePath(ticker) {
513
+ return `${rightRoot(ticker)}/right-people.md`;
514
+ }
515
+ function rightPricePath(ticker) {
516
+ return `${rightRoot(ticker)}/right-price.md`;
517
+ }
518
+ function investWikiRoot(ticker) {
519
+ return companyRoot(ticker);
520
+ }
521
+ function investWikiConfigPath(ticker) {
522
+ return `${investWikiRoot(ticker)}/.llm-wiki-invest/config.toml`;
523
+ }
524
+ function wikiRoot(ticker) {
525
+ return `${companyRoot(ticker)}/wiki`;
526
+ }
527
+ function sourcesRoot(ticker) {
528
+ return `${companyRoot(ticker)}/sources`;
529
+ }
530
+ function articlesRoot(ticker) {
531
+ return `${companyRoot(ticker)}/articles`;
532
+ }
533
+ function financialReportsRoot(ticker) {
534
+ return `${companyRoot(ticker)}/financial-reports`;
535
+ }
536
+ function financialReportsIndexPath(ticker) {
537
+ return `${financialReportsRoot(ticker)}/report-index.json`;
538
+ }
539
+ var INVEST_WIKI_TOP_LEVEL_FILES = [
540
+ "AGENTS.md",
541
+ "CLAUDE.md",
542
+ "wiki-agent.md",
543
+ "wiki-log.md",
544
+ "wiki-purpose.md",
545
+ "wiki-schema.md"
546
+ ];
547
+ var MANIFEST_TEXT_EXTENSIONS = /* @__PURE__ */ new Set([
548
+ ".md",
549
+ ".txt",
550
+ ".toml",
551
+ ".json",
552
+ ".yml",
553
+ ".yaml"
554
+ ]);
555
+ function manifestTitle(relativePath) {
556
+ return path2.basename(relativePath);
557
+ }
558
+ function canIncludeFile(relativePath) {
559
+ if (relativePath.endsWith("/manifest.json")) {
560
+ return false;
561
+ }
562
+ return MANIFEST_TEXT_EXTENSIONS.has(path2.extname(relativePath).toLowerCase());
563
+ }
564
+ async function collectDirectoryCandidates(input, depth = 0) {
565
+ const maxDepth = 3;
566
+ if (depth > maxDepth) {
567
+ return [];
568
+ }
569
+ const absoluteRoot = resolveInsideWorkspace(
570
+ input.workspaceRoot,
571
+ input.rootRelativePath
572
+ );
573
+ let entries;
574
+ try {
575
+ entries = await readdir(absoluteRoot, { withFileTypes: true });
576
+ } catch (error) {
577
+ if (error.code === "ENOENT") {
578
+ return [];
579
+ }
580
+ throw error;
581
+ }
582
+ const candidates = [];
583
+ for (const entry of entries.sort((a, b) => a.name.localeCompare(b.name))) {
584
+ if (entry.name.startsWith(".")) {
585
+ continue;
586
+ }
587
+ const relativePath = `${input.rootRelativePath}/${entry.name}`;
588
+ if (entry.isDirectory()) {
589
+ candidates.push(
590
+ ...await collectDirectoryCandidates(
591
+ {
592
+ workspaceRoot: input.workspaceRoot,
593
+ rootRelativePath: relativePath,
594
+ type: input.type
595
+ },
596
+ depth + 1
597
+ )
598
+ );
599
+ continue;
600
+ }
601
+ if (!entry.isFile() || !canIncludeFile(relativePath)) {
602
+ continue;
603
+ }
604
+ candidates.push({
605
+ type: input.type,
606
+ title: manifestTitle(relativePath),
607
+ relativePath
608
+ });
609
+ }
610
+ return candidates;
611
+ }
612
+ async function scanCompanyManifest(input) {
613
+ const ticker = normalizeTicker(input.ticker);
614
+ const staticCandidates = [
615
+ {
616
+ type: "right_business",
617
+ title: "Right Business",
618
+ relativePath: rightBusinessPath(ticker)
619
+ },
620
+ {
621
+ type: "right_people",
622
+ title: "Right People",
623
+ relativePath: rightPeoplePath(ticker)
624
+ },
625
+ {
626
+ type: "right_price",
627
+ title: "Right Price",
628
+ relativePath: rightPricePath(ticker)
629
+ },
630
+ {
631
+ type: "wiki",
632
+ title: "Invest Wiki Vault",
633
+ relativePath: investWikiConfigPath(ticker)
634
+ }
635
+ ];
636
+ const topLevelCandidates = INVEST_WIKI_TOP_LEVEL_FILES.map((fileName) => ({
637
+ type: "wiki",
638
+ title: fileName,
639
+ relativePath: `${companyRoot(ticker)}/${fileName}`
640
+ }));
641
+ const directoryCandidates = (await Promise.all([
642
+ collectDirectoryCandidates({
643
+ workspaceRoot: input.workspaceRoot,
644
+ rootRelativePath: wikiRoot(ticker),
645
+ type: "wiki"
646
+ }),
647
+ collectDirectoryCandidates({
648
+ workspaceRoot: input.workspaceRoot,
649
+ rootRelativePath: sourcesRoot(ticker),
650
+ type: "source_note"
651
+ }),
652
+ collectDirectoryCandidates({
653
+ workspaceRoot: input.workspaceRoot,
654
+ rootRelativePath: articlesRoot(ticker),
655
+ type: "article"
656
+ }),
657
+ collectDirectoryCandidates({
658
+ workspaceRoot: input.workspaceRoot,
659
+ rootRelativePath: financialReportsRoot(ticker),
660
+ type: "source_note"
661
+ })
662
+ ])).flat();
663
+ const candidates = [
664
+ ...staticCandidates,
665
+ ...topLevelCandidates,
666
+ ...directoryCandidates
667
+ ];
668
+ const pages = [];
669
+ const seenPaths = /* @__PURE__ */ new Set();
670
+ for (const candidate of candidates) {
671
+ if (seenPaths.has(candidate.relativePath)) {
672
+ continue;
673
+ }
674
+ seenPaths.add(candidate.relativePath);
675
+ const absolutePath = resolveInsideWorkspace(
676
+ input.workspaceRoot,
677
+ candidate.relativePath
678
+ );
679
+ try {
680
+ const [fileStat, content] = await Promise.all([
681
+ stat(absolutePath),
682
+ readFile(absolutePath, "utf8")
683
+ ]);
684
+ if (!fileStat.isFile()) {
685
+ continue;
686
+ }
687
+ pages.push({
688
+ type: candidate.type,
689
+ title: candidate.title,
690
+ path: candidate.relativePath,
691
+ size: Buffer.byteLength(content),
692
+ hash: sha256Text(content),
693
+ updatedAt: fileStat.mtime.toISOString()
694
+ });
695
+ } catch (error) {
696
+ if (error.code !== "ENOENT") {
697
+ throw error;
698
+ }
699
+ }
700
+ }
701
+ const parsed = CompanyManifestSchema.parse({
702
+ schemaVersion: 1,
703
+ ticker,
704
+ market: input.market,
705
+ updatedAt: (/* @__PURE__ */ new Date()).toISOString(),
706
+ commitSha: input.commitSha,
707
+ pages
708
+ });
709
+ return parsed;
710
+ }
711
+ async function buildCompanyManifest(input) {
712
+ const ticker = normalizeTicker(input.ticker);
713
+ const parsed = await scanCompanyManifest(input);
714
+ const manifestRelativePath = companyManifestPath(ticker);
715
+ const manifestAbsolutePath = resolveInsideWorkspace(
716
+ input.workspaceRoot,
717
+ manifestRelativePath
718
+ );
719
+ await mkdir(path2.dirname(manifestAbsolutePath), { recursive: true });
720
+ await writeFile(manifestAbsolutePath, `${JSON.stringify(parsed, null, 2)}
721
+ `);
722
+ return parsed;
723
+ }
724
+ var COVERAGE_CONTRACT_SCHEMA_VERSION = "coverage-contract/v0";
725
+ var CoveragePresetSchema = z11.object({
726
+ id: z11.string().min(1),
727
+ version: z11.string().min(1)
728
+ });
729
+ var CoverageCompanySchema = z11.object({
730
+ ticker: z11.string().min(1),
731
+ name: z11.string().min(1).optional(),
732
+ market: z11.enum(["us", "hk", "cn"]).optional()
733
+ });
734
+ var CoverageBundleSchema = z11.object({
735
+ schemaVersion: z11.string().min(1),
736
+ runId: z11.string().min(1),
737
+ completedAt: z11.string().min(1),
738
+ company: CoverageCompanySchema,
739
+ preset: CoveragePresetSchema,
740
+ files: z11.object({
741
+ manifest: z11.literal("manifest.json"),
742
+ sourceInventory: z11.literal("source_inventory.json"),
743
+ qualityReport: z11.literal("quality_report.json"),
744
+ result: z11.literal("result.json")
745
+ })
746
+ });
747
+ var CoverageBlockingReasonSchema2 = z11.object({
748
+ code: z11.enum([
749
+ "missing_required_source",
750
+ "failed_required_source",
751
+ "skipped_required_source",
752
+ "required_source_needs_review"
753
+ ]),
754
+ message: z11.string().min(1),
755
+ expectationId: z11.string().min(1)
756
+ });
757
+ var CoverageQualityReportSchema = z11.object({
758
+ schemaVersion: z11.string().min(1),
759
+ runId: z11.string().min(1),
760
+ preset: CoveragePresetSchema,
761
+ commercialReportAllowed: z11.boolean(),
762
+ summary: z11.object({
763
+ requiredTotal: z11.number().int().nonnegative(),
764
+ requiredFound: z11.number().int().nonnegative(),
765
+ requiredMissing: z11.number().int().nonnegative(),
766
+ requiredFailed: z11.number().int().nonnegative(),
767
+ optionalTotal: z11.number().int().nonnegative()
768
+ }),
769
+ blockingReasons: z11.array(CoverageBlockingReasonSchema2)
770
+ });
771
+ var CoverageSourceInventoryItemSchema = z11.object({
772
+ expectationId: z11.string().min(1),
773
+ label: z11.string().min(1),
774
+ required: z11.boolean(),
775
+ authority: z11.string().min(1),
776
+ documentType: z11.string().min(1),
777
+ asOf: z11.string().min(1),
778
+ period: z11.string().min(1),
779
+ selectionRule: z11.string().min(1),
780
+ status: z11.enum(["found", "missing", "failed", "skipped", "not_applicable"]),
781
+ manualSupplementAllowed: z11.boolean(),
782
+ sourceId: z11.string().optional(),
783
+ contentHash: z11.string().optional(),
784
+ materializedPath: z11.string().optional(),
785
+ sourceDate: z11.string().optional(),
786
+ filingDate: z11.string().optional(),
787
+ errorCode: z11.string().optional(),
788
+ reason: z11.string().optional(),
789
+ message: z11.string().optional()
790
+ }).superRefine((item, context) => {
791
+ if (item.status === "found") {
792
+ for (const field of ["sourceId", "contentHash", "materializedPath"]) {
793
+ if (!item[field]) {
794
+ context.addIssue({
795
+ code: "custom",
796
+ message: `found source inventory item requires ${field}`,
797
+ path: [field]
798
+ });
799
+ }
800
+ }
801
+ return;
802
+ }
803
+ if (!item.errorCode) {
804
+ context.addIssue({
805
+ code: "custom",
806
+ message: "non-found source inventory item requires errorCode",
807
+ path: ["errorCode"]
808
+ });
809
+ }
810
+ if (!item.reason && !item.message) {
811
+ context.addIssue({
812
+ code: "custom",
813
+ message: "non-found source inventory item requires reason or message",
814
+ path: ["reason"]
815
+ });
816
+ }
817
+ });
818
+ var CoverageSourceInventorySchema = z11.object({
819
+ schemaVersion: z11.string().min(1),
820
+ runId: z11.string().min(1),
821
+ preset: CoveragePresetSchema,
822
+ items: z11.array(CoverageSourceInventoryItemSchema)
823
+ });
824
+ async function readJsonFile(absolutePath) {
825
+ return JSON.parse(await readFile2(absolutePath, "utf8"));
826
+ }
827
+ function assertSupportedSchemaVersion(value, label) {
828
+ if (value !== COVERAGE_CONTRACT_SCHEMA_VERSION) {
829
+ throw new Error(
830
+ `Unsupported coverage contract schema version in ${label}: ${value}`
831
+ );
832
+ }
833
+ }
834
+ function parseBundle(value) {
835
+ try {
836
+ return CoverageBundleSchema.parse(value);
837
+ } catch (error) {
838
+ throw new Error(
839
+ `Invalid coverage bundle: ${error instanceof Error ? error.message : String(error)}`
840
+ );
841
+ }
842
+ }
843
+ function parseQualityReport(value) {
844
+ try {
845
+ return CoverageQualityReportSchema.parse(value);
846
+ } catch (error) {
847
+ throw new Error(
848
+ `Invalid quality_report.json: ${error instanceof Error ? error.message : String(error)}`
849
+ );
850
+ }
851
+ }
852
+ function parseSourceInventory(value) {
853
+ try {
854
+ return CoverageSourceInventorySchema.parse(value);
855
+ } catch (error) {
856
+ throw new Error(
857
+ `Invalid source_inventory.json: ${error instanceof Error ? error.message : String(error)}`
858
+ );
859
+ }
860
+ }
861
+ function relativeRunFile(bundlePath, fileName) {
862
+ return path3.posix.join(path3.posix.dirname(bundlePath), fileName);
863
+ }
864
+ async function readCoverageContractBundle(input) {
865
+ const bundleAbsolutePath = resolveInsideWorkspace(
866
+ input.workspaceRoot,
867
+ input.bundlePath
868
+ );
869
+ const bundle = parseBundle(await readJsonFile(bundleAbsolutePath));
870
+ assertSupportedSchemaVersion(bundle.schemaVersion, "bundle.json");
871
+ const qualityReportPath = relativeRunFile(
872
+ input.bundlePath,
873
+ bundle.files.qualityReport
874
+ );
875
+ const sourceInventoryPath = relativeRunFile(
876
+ input.bundlePath,
877
+ bundle.files.sourceInventory
878
+ );
879
+ const qualityReport = parseQualityReport(
880
+ await readJsonFile(
881
+ resolveInsideWorkspace(input.workspaceRoot, qualityReportPath)
882
+ )
883
+ );
884
+ const sourceInventory = parseSourceInventory(
885
+ await readJsonFile(
886
+ resolveInsideWorkspace(input.workspaceRoot, sourceInventoryPath)
887
+ )
888
+ );
889
+ assertSupportedSchemaVersion(
890
+ qualityReport.schemaVersion,
891
+ "quality_report.json"
892
+ );
893
+ assertSupportedSchemaVersion(
894
+ sourceInventory.schemaVersion,
895
+ "source_inventory.json"
896
+ );
897
+ return {
898
+ bundle,
899
+ qualityReport,
900
+ sourceInventory,
901
+ files: {
902
+ bundlePath: input.bundlePath,
903
+ qualityReportPath,
904
+ sourceInventoryPath
905
+ }
906
+ };
907
+ }
9
908
 
10
909
  // src/api/client.ts
11
- import {
12
- AppendTaskEventsRequestSchema,
13
- AppendTaskEventsResponseSchema,
14
- ClaimTaskResponseSchema,
15
- CompleteTaskRequestSchema,
16
- CompleteTaskResponseSchema,
17
- DaemonBootstrapRequestSchema,
18
- DaemonBootstrapResponseSchema,
19
- DaemonHeartbeatRequestSchema,
20
- DaemonHeartbeatResponseSchema,
21
- FailTaskRequestSchema,
22
- FailTaskResponseSchema
23
- } from "@xdsjs/dossierx-shared";
24
910
  var ApiClient = class {
25
911
  serverUrl;
26
912
  machineKey;
@@ -30,8 +916,8 @@ var ApiClient = class {
30
916
  this.machineKey = options.machineKey;
31
917
  this.fetchImpl = options.fetchImpl ?? fetch;
32
918
  }
33
- async post(path11, body, schema) {
34
- const response = await this.fetchImpl(`${this.serverUrl}${path11}`, {
919
+ async post(path15, body, schema) {
920
+ const response = await this.fetchImpl(`${this.serverUrl}${path15}`, {
35
921
  method: "POST",
36
922
  headers: {
37
923
  authorization: `Bearer ${this.machineKey}`,
@@ -496,61 +1382,476 @@ function createCodexRunnerFromOptions(options, env = process.env) {
496
1382
  }
497
1383
 
498
1384
  // src/git-mirror.ts
499
- import path2 from "path";
500
- import {
501
- publishCompanySnapshot
502
- } from "@xdsjs/dossierx-git-mirror";
1385
+ import path6 from "path";
1386
+
1387
+ // ../../node_modules/.pnpm/@xdsjs+dossierx-git-mirror@0.1.2/node_modules/@xdsjs/dossierx-git-mirror/dist/index.js
1388
+ import path32 from "path";
1389
+ import { mkdir as mkdir2, readdir as readdir2 } from "fs/promises";
1390
+ import path4 from "path";
1391
+ import { execa as execa2 } from "execa";
1392
+ import { lstat, mkdir as mkdir22, readFile as readFile3, rm, writeFile as writeFile2 } from "fs/promises";
1393
+ import path22 from "path";
1394
+ import { createHash as createHash2 } from "crypto";
1395
+ import { lstat as lstat2, readFile as readFile22 } from "fs/promises";
1396
+ var GitMirrorError = class extends Error {
1397
+ code;
1398
+ step;
1399
+ constructor(code, message, step) {
1400
+ super(message);
1401
+ this.name = "GitMirrorError";
1402
+ this.code = code;
1403
+ this.step = step;
1404
+ }
1405
+ };
1406
+ function validationError(message, step = "git_mirror.snapshot") {
1407
+ return new GitMirrorError("GIT_MIRROR_VALIDATION_ERROR", message, step);
1408
+ }
1409
+ function commandError(message, step = "git_mirror.git") {
1410
+ return new GitMirrorError("GIT_MIRROR_COMMAND_ERROR", message, step);
1411
+ }
1412
+ async function git(input, args) {
1413
+ const result = await execa2(input.gitCommand ?? "git", args, {
1414
+ cwd: input.cwd,
1415
+ reject: false
1416
+ });
1417
+ if (result.exitCode !== 0) {
1418
+ throw commandError(
1419
+ `git ${args.join(" ")} failed: ${result.stderr || result.stdout}`,
1420
+ "git_mirror.git"
1421
+ );
1422
+ }
1423
+ return result.stdout.trim();
1424
+ }
1425
+ async function pathExists(absolutePath) {
1426
+ try {
1427
+ await readdir2(absolutePath);
1428
+ return true;
1429
+ } catch (error) {
1430
+ if (error.code === "ENOENT") {
1431
+ return false;
1432
+ }
1433
+ throw error;
1434
+ }
1435
+ }
1436
+ async function isEmptyDirectory(absolutePath) {
1437
+ try {
1438
+ const entries = await readdir2(absolutePath);
1439
+ return entries.length === 0;
1440
+ } catch (error) {
1441
+ if (error.code === "ENOENT") {
1442
+ return true;
1443
+ }
1444
+ throw error;
1445
+ }
1446
+ }
1447
+ async function ensureGitRepository(input) {
1448
+ const gitDir = path4.join(input.mirrorRoot, ".git");
1449
+ if (!await pathExists(gitDir)) {
1450
+ if (input.remoteUrl) {
1451
+ await mkdir2(path4.dirname(input.mirrorRoot), { recursive: true });
1452
+ if (!await isEmptyDirectory(input.mirrorRoot)) {
1453
+ throw validationError(
1454
+ "Git mirror root must be empty when cloning a remote repository",
1455
+ "git_mirror.git.init"
1456
+ );
1457
+ }
1458
+ const result = await execa2(
1459
+ input.gitCommand ?? "git",
1460
+ ["clone", input.remoteUrl, input.mirrorRoot],
1461
+ { reject: false }
1462
+ );
1463
+ if (result.exitCode !== 0) {
1464
+ throw commandError(
1465
+ `git clone failed: ${result.stderr || result.stdout}`,
1466
+ "git_mirror.git.clone"
1467
+ );
1468
+ }
1469
+ await git({ cwd: input.mirrorRoot, gitCommand: input.gitCommand }, [
1470
+ "checkout",
1471
+ "-B",
1472
+ input.branch
1473
+ ]);
1474
+ } else {
1475
+ await mkdir2(input.mirrorRoot, { recursive: true });
1476
+ await git({ cwd: input.mirrorRoot, gitCommand: input.gitCommand }, ["init"]);
1477
+ await git({ cwd: input.mirrorRoot, gitCommand: input.gitCommand }, [
1478
+ "checkout",
1479
+ "-B",
1480
+ input.branch
1481
+ ]);
1482
+ }
1483
+ } else {
1484
+ await git({ cwd: input.mirrorRoot, gitCommand: input.gitCommand }, [
1485
+ "checkout",
1486
+ "-B",
1487
+ input.branch
1488
+ ]);
1489
+ }
1490
+ await git({ cwd: input.mirrorRoot, gitCommand: input.gitCommand }, [
1491
+ "config",
1492
+ "user.name",
1493
+ input.authorName
1494
+ ]);
1495
+ await git({ cwd: input.mirrorRoot, gitCommand: input.gitCommand }, [
1496
+ "config",
1497
+ "user.email",
1498
+ input.authorEmail
1499
+ ]);
1500
+ if (input.remoteUrl) {
1501
+ const currentRemote = await execa2(
1502
+ input.gitCommand ?? "git",
1503
+ ["remote", "get-url", "origin"],
1504
+ { cwd: input.mirrorRoot, reject: false }
1505
+ );
1506
+ if (currentRemote.exitCode === 0) {
1507
+ if (currentRemote.stdout.trim() !== input.remoteUrl) {
1508
+ await git({ cwd: input.mirrorRoot, gitCommand: input.gitCommand }, [
1509
+ "remote",
1510
+ "set-url",
1511
+ "origin",
1512
+ input.remoteUrl
1513
+ ]);
1514
+ }
1515
+ } else {
1516
+ await git({ cwd: input.mirrorRoot, gitCommand: input.gitCommand }, [
1517
+ "remote",
1518
+ "add",
1519
+ "origin",
1520
+ input.remoteUrl
1521
+ ]);
1522
+ }
1523
+ }
1524
+ }
1525
+ async function gitRevParseHead(input) {
1526
+ const result = await execa2(input.gitCommand ?? "git", ["rev-parse", "HEAD"], {
1527
+ cwd: input.cwd,
1528
+ reject: false
1529
+ });
1530
+ return result.exitCode === 0 ? result.stdout.trim() : void 0;
1531
+ }
1532
+ async function stageCompany(input) {
1533
+ await git(input, ["add", "--", input.companyRoot]);
1534
+ }
1535
+ async function stagedPaths(input) {
1536
+ const output = await git(input, ["diff", "--cached", "--name-only"]);
1537
+ return output ? output.split("\n").filter(Boolean) : [];
1538
+ }
1539
+ async function commit(input) {
1540
+ await git(input, ["commit", "-m", input.message]);
1541
+ }
1542
+ async function push(input) {
1543
+ await git(input, ["push", "-u", "origin", input.branch]);
1544
+ }
1545
+ function sha256Text2(content) {
1546
+ return `sha256:${createHash2("sha256").update(content).digest("hex")}`;
1547
+ }
1548
+ function treeHashForManifest(manifest) {
1549
+ const lines = manifest.pages.map((page) => `${page.path}\0${page.hash}\0${page.size}`).sort((a, b) => a.localeCompare(b));
1550
+ return sha256Text2(`${lines.join("\n")}
1551
+ `);
1552
+ }
1553
+ function snapshotMetadataPath(ticker) {
1554
+ return `${companyRoot(ticker)}/.dossierx/snapshot.json`;
1555
+ }
1556
+ async function buildCompanySnapshot(input) {
1557
+ const ticker = normalizeTicker(input.company.ticker);
1558
+ const manifest = await buildCompanyManifest({
1559
+ workspaceRoot: input.workspaceRoot,
1560
+ ticker,
1561
+ market: input.company.market
1562
+ });
1563
+ const manifestPath = companyManifestPath(ticker);
1564
+ const files = [];
1565
+ for (const page of manifest.pages) {
1566
+ const absolutePath = resolveInsideWorkspace(input.workspaceRoot, page.path);
1567
+ const fileStat = await lstat(absolutePath);
1568
+ if (fileStat.isSymbolicLink()) {
1569
+ throw validationError(`Manifest page cannot be a symlink: ${page.path}`);
1570
+ }
1571
+ if (!fileStat.isFile()) {
1572
+ throw validationError(`Manifest page is not a regular file: ${page.path}`);
1573
+ }
1574
+ files.push({
1575
+ relativePath: page.path,
1576
+ hash: page.hash,
1577
+ size: page.size
1578
+ });
1579
+ }
1580
+ return {
1581
+ manifest,
1582
+ manifestPath,
1583
+ treeHash: treeHashForManifest(manifest),
1584
+ files
1585
+ };
1586
+ }
1587
+ async function copyTextFile(input) {
1588
+ const from = resolveInsideWorkspace(input.fromRoot, input.relativePath);
1589
+ const to = resolveInsideWorkspace(input.toRoot, input.relativePath);
1590
+ const fileStat = await lstat(from);
1591
+ if (fileStat.isSymbolicLink()) {
1592
+ throw validationError(`Snapshot file cannot be a symlink: ${input.relativePath}`);
1593
+ }
1594
+ if (!fileStat.isFile()) {
1595
+ throw validationError(`Snapshot file is not a regular file: ${input.relativePath}`);
1596
+ }
1597
+ await mkdir22(path22.dirname(to), { recursive: true });
1598
+ await writeFile2(to, await readFile3(from));
1599
+ }
1600
+ async function copyCompanySnapshot(input) {
1601
+ const companyRelativeRoot = companyRoot(input.snapshot.manifest.ticker);
1602
+ await rm(resolveInsideWorkspace(input.mirrorRoot, companyRelativeRoot), {
1603
+ recursive: true,
1604
+ force: true
1605
+ });
1606
+ for (const file of input.snapshot.files) {
1607
+ await copyTextFile({
1608
+ fromRoot: input.workspaceRoot,
1609
+ toRoot: input.mirrorRoot,
1610
+ relativePath: file.relativePath
1611
+ });
1612
+ }
1613
+ await copyTextFile({
1614
+ fromRoot: input.workspaceRoot,
1615
+ toRoot: input.mirrorRoot,
1616
+ relativePath: input.snapshot.manifestPath
1617
+ });
1618
+ const metadataAbsolutePath = resolveInsideWorkspace(
1619
+ input.mirrorRoot,
1620
+ snapshotMetadataPath(input.snapshot.manifest.ticker)
1621
+ );
1622
+ await mkdir22(path22.dirname(metadataAbsolutePath), { recursive: true });
1623
+ await writeFile2(
1624
+ metadataAbsolutePath,
1625
+ `${JSON.stringify(input.metadata, null, 2)}
1626
+ `
1627
+ );
1628
+ }
1629
+ async function readSnapshotMetadata(input) {
1630
+ try {
1631
+ const metadata = JSON.parse(
1632
+ await readFile3(
1633
+ resolveInsideWorkspace(
1634
+ input.mirrorRoot,
1635
+ snapshotMetadataPath(input.ticker)
1636
+ ),
1637
+ "utf8"
1638
+ )
1639
+ );
1640
+ return metadata.schemaVersion === 1 ? metadata : null;
1641
+ } catch (error) {
1642
+ if (error.code === "ENOENT") {
1643
+ return null;
1644
+ }
1645
+ throw error;
1646
+ }
1647
+ }
1648
+ async function verifyCompanySnapshot(input) {
1649
+ const ticker = normalizeTicker(input.company.ticker);
1650
+ const manifestPath = companyManifestPath(ticker);
1651
+ const manifest = CompanyManifestSchema.parse(
1652
+ JSON.parse(
1653
+ await readFile22(resolveInsideWorkspace(input.mirrorRoot, manifestPath), "utf8")
1654
+ )
1655
+ );
1656
+ if (manifest.ticker !== ticker || manifest.market !== input.company.market) {
1657
+ throw validationError("Mirror manifest company identity does not match");
1658
+ }
1659
+ for (const page of manifest.pages) {
1660
+ const absolutePath = resolveInsideWorkspace(input.mirrorRoot, page.path);
1661
+ const fileStat = await lstat2(absolutePath);
1662
+ if (fileStat.isSymbolicLink()) {
1663
+ throw validationError(`Mirror page cannot be a symlink: ${page.path}`);
1664
+ }
1665
+ if (!fileStat.isFile()) {
1666
+ throw validationError(`Mirror page is not a regular file: ${page.path}`);
1667
+ }
1668
+ const content = await readFile22(absolutePath, "utf8");
1669
+ const size = Buffer.byteLength(content);
1670
+ const hash = sha256Text2(content);
1671
+ if (size !== page.size || hash !== page.hash) {
1672
+ throw validationError(`Mirror page hash mismatch: ${page.path}`);
1673
+ }
1674
+ }
1675
+ const treeHash = treeHashForManifest(manifest);
1676
+ if (input.expectedTreeHash && treeHash !== input.expectedTreeHash) {
1677
+ throw validationError("Mirror tree hash does not match expected tree hash");
1678
+ }
1679
+ return { ok: true, manifest, treeHash };
1680
+ }
1681
+ async function publishCompanySnapshot(input) {
1682
+ const ticker = normalizeTicker(input.company.ticker);
1683
+ const branch = input.branch ?? "main";
1684
+ const mirrorRoot = path32.resolve(input.mirrorRoot);
1685
+ const workspaceRoot = path32.resolve(input.workspaceRoot);
1686
+ const authorName = input.authorName ?? "DossierX daemon";
1687
+ const authorEmail = input.authorEmail ?? "dossierx@local";
1688
+ const gitOptions = { cwd: mirrorRoot, gitCommand: input.gitCommand };
1689
+ const generatedAt = (/* @__PURE__ */ new Date()).toISOString();
1690
+ await ensureGitRepository({
1691
+ mirrorRoot,
1692
+ remoteUrl: input.remoteUrl,
1693
+ branch,
1694
+ gitCommand: input.gitCommand,
1695
+ authorName,
1696
+ authorEmail
1697
+ });
1698
+ const previousCommitSha = await gitRevParseHead(gitOptions);
1699
+ const snapshot = await buildCompanySnapshot({
1700
+ workspaceRoot,
1701
+ company: { ticker, market: input.company.market }
1702
+ });
1703
+ const existingMetadata = await readSnapshotMetadata({ mirrorRoot, ticker });
1704
+ if (existingMetadata?.treeHash === snapshot.treeHash) {
1705
+ try {
1706
+ await verifyCompanySnapshot({
1707
+ mirrorRoot,
1708
+ company: { ticker, market: input.company.market },
1709
+ expectedTreeHash: snapshot.treeHash
1710
+ });
1711
+ return {
1712
+ status: "unchanged",
1713
+ ticker,
1714
+ market: input.company.market,
1715
+ manifestPath: snapshot.manifestPath,
1716
+ commitSha: previousCommitSha,
1717
+ previousCommitSha,
1718
+ treeHash: snapshot.treeHash,
1719
+ branch,
1720
+ pushed: false,
1721
+ remoteUrl: input.remoteUrl,
1722
+ generatedAt
1723
+ };
1724
+ } catch {
1725
+ }
1726
+ }
1727
+ const metadata = {
1728
+ schemaVersion: 1,
1729
+ ticker,
1730
+ market: input.company.market,
1731
+ taskId: input.taskId,
1732
+ treeHash: snapshot.treeHash,
1733
+ generatedAt
1734
+ };
1735
+ await copyCompanySnapshot({
1736
+ workspaceRoot,
1737
+ mirrorRoot,
1738
+ snapshot,
1739
+ metadata
1740
+ });
1741
+ await verifyCompanySnapshot({
1742
+ mirrorRoot,
1743
+ company: { ticker, market: input.company.market },
1744
+ expectedTreeHash: snapshot.treeHash
1745
+ });
1746
+ const companyRelativeRoot = companyRoot(ticker);
1747
+ await stageCompany({ ...gitOptions, companyRoot: companyRelativeRoot });
1748
+ const staged = await stagedPaths(gitOptions);
1749
+ const invalidStagedPath = staged.find(
1750
+ (relativePath) => !relativePath.startsWith(`${companyRelativeRoot}/`)
1751
+ );
1752
+ if (invalidStagedPath) {
1753
+ throw validationError(
1754
+ `Git mirror staged a file outside ${companyRelativeRoot}: ${invalidStagedPath}`,
1755
+ "git_mirror.git.stage"
1756
+ );
1757
+ }
1758
+ if (staged.length === 0) {
1759
+ return {
1760
+ status: "unchanged",
1761
+ ticker,
1762
+ market: input.company.market,
1763
+ manifestPath: snapshot.manifestPath,
1764
+ commitSha: previousCommitSha,
1765
+ previousCommitSha,
1766
+ treeHash: snapshot.treeHash,
1767
+ branch,
1768
+ pushed: false,
1769
+ remoteUrl: input.remoteUrl,
1770
+ generatedAt
1771
+ };
1772
+ }
1773
+ await commit({
1774
+ ...gitOptions,
1775
+ message: `Mirror ${ticker} workspace snapshot`
1776
+ });
1777
+ const commitSha = await gitRevParseHead(gitOptions);
1778
+ const shouldPush = input.push ?? Boolean(input.remoteUrl);
1779
+ if (shouldPush && !input.remoteUrl) {
1780
+ throw validationError(
1781
+ "Git mirror push requires a remote URL",
1782
+ "git_mirror.git.push"
1783
+ );
1784
+ }
1785
+ if (shouldPush) {
1786
+ await push({ ...gitOptions, branch });
1787
+ }
1788
+ return {
1789
+ status: "published",
1790
+ ticker,
1791
+ market: input.company.market,
1792
+ manifestPath: snapshot.manifestPath,
1793
+ commitSha,
1794
+ previousCommitSha,
1795
+ treeHash: snapshot.treeHash,
1796
+ branch,
1797
+ pushed: shouldPush,
1798
+ remoteUrl: input.remoteUrl,
1799
+ generatedAt
1800
+ };
1801
+ }
1802
+ var GITHUB_APP_TOKEN_TTL_SECONDS = 9 * 60;
1803
+ var GITHUB_APP_TOKEN_CACHE_MS = 50 * 60 * 1e3;
1804
+ var GITHUB_MANIFEST_CACHE_MS = 60 * 1e3;
503
1805
 
504
1806
  // src/local-config.ts
505
- import { chmod, mkdir, readFile, writeFile } from "fs/promises";
1807
+ import { chmod, mkdir as mkdir3, readFile as readFile4, writeFile as writeFile3 } from "fs/promises";
506
1808
  import os from "os";
507
- import path from "path";
508
- import { z } from "zod";
509
- import { DOSSIERX_CONFIG_DIR } from "@xdsjs/dossierx-workspace";
510
- var DaemonLocalConfigSchema = z.object({
511
- machineId: z.string().uuid().optional(),
512
- machineKey: z.string().startsWith("dx_machine_"),
513
- serverUrl: z.string().min(1),
514
- supabaseUrl: z.string().min(1),
515
- supabaseAnonKey: z.string().min(1),
516
- workspacePath: z.string().min(1),
517
- investWikiMode: z.string().optional(),
518
- investWikiLocalRepo: z.string().optional(),
519
- investWikiCommand: z.string().optional(),
520
- codexCommand: z.string().optional(),
521
- codexModel: z.string().optional(),
522
- codexSandbox: z.string().optional(),
523
- gitMirrorRoot: z.string().optional(),
524
- gitMirrorRemote: z.string().optional(),
525
- gitMirrorBranch: z.string().optional(),
526
- gitCommand: z.string().optional(),
527
- notebookLmPythonCommand: z.string().optional(),
528
- notebookLmProfile: z.string().optional(),
529
- notebookLmHome: z.string().optional(),
530
- notebookLmStoragePath: z.string().optional(),
531
- localApiPort: z.number().int().positive().optional()
1809
+ import path5 from "path";
1810
+ import { z as z12 } from "zod";
1811
+ var DaemonLocalConfigSchema = z12.object({
1812
+ machineId: z12.string().uuid().optional(),
1813
+ machineKey: z12.string().startsWith("dx_machine_"),
1814
+ serverUrl: z12.string().min(1),
1815
+ supabaseUrl: z12.string().min(1),
1816
+ supabaseAnonKey: z12.string().min(1),
1817
+ workspacePath: z12.string().min(1),
1818
+ investWikiMode: z12.string().optional(),
1819
+ investWikiLocalRepo: z12.string().optional(),
1820
+ investWikiCommand: z12.string().optional(),
1821
+ codexCommand: z12.string().optional(),
1822
+ codexModel: z12.string().optional(),
1823
+ codexSandbox: z12.string().optional(),
1824
+ gitMirrorRoot: z12.string().optional(),
1825
+ gitMirrorRemote: z12.string().optional(),
1826
+ gitMirrorBranch: z12.string().optional(),
1827
+ gitCommand: z12.string().optional(),
1828
+ notebookLmPythonCommand: z12.string().optional(),
1829
+ notebookLmProfile: z12.string().optional(),
1830
+ notebookLmHome: z12.string().optional(),
1831
+ notebookLmStoragePath: z12.string().optional(),
1832
+ localApiPort: z12.number().int().positive().optional()
532
1833
  });
533
1834
  function expandHomePath(input) {
534
1835
  if (input === "~") {
535
1836
  return os.homedir();
536
1837
  }
537
1838
  if (input.startsWith("~/")) {
538
- return path.join(os.homedir(), input.slice(2));
1839
+ return path5.join(os.homedir(), input.slice(2));
539
1840
  }
540
1841
  return input;
541
1842
  }
542
1843
  function getDaemonConfigDir(env = process.env) {
543
- return path.resolve(
1844
+ return path5.resolve(
544
1845
  expandHomePath(env.DOSSIERX_CONFIG_DIR ?? DOSSIERX_CONFIG_DIR)
545
1846
  );
546
1847
  }
547
1848
  function daemonConfigPath(configDir = getDaemonConfigDir()) {
548
- return path.join(configDir, "config.json");
1849
+ return path5.join(configDir, "config.json");
549
1850
  }
550
1851
  async function readDaemonLocalConfig(configDir = getDaemonConfigDir()) {
551
1852
  try {
552
1853
  return DaemonLocalConfigSchema.parse(
553
- JSON.parse(await readFile(daemonConfigPath(configDir), "utf8"))
1854
+ JSON.parse(await readFile4(daemonConfigPath(configDir), "utf8"))
554
1855
  );
555
1856
  } catch (error) {
556
1857
  if (error && typeof error === "object" && "code" in error && error.code === "ENOENT") {
@@ -561,9 +1862,9 @@ async function readDaemonLocalConfig(configDir = getDaemonConfigDir()) {
561
1862
  }
562
1863
  async function writeDaemonLocalConfig(config, configDir = getDaemonConfigDir()) {
563
1864
  const parsed = DaemonLocalConfigSchema.parse(config);
564
- await mkdir(configDir, { recursive: true, mode: 448 });
1865
+ await mkdir3(configDir, { recursive: true, mode: 448 });
565
1866
  const target = daemonConfigPath(configDir);
566
- await writeFile(target, `${JSON.stringify(parsed, null, 2)}
1867
+ await writeFile3(target, `${JSON.stringify(parsed, null, 2)}
567
1868
  `, {
568
1869
  mode: 384
569
1870
  });
@@ -575,9 +1876,9 @@ function createGitMirrorFromOptions(options) {
575
1876
  if (!options.gitMirrorRoot && !options.gitMirrorRemote) {
576
1877
  return null;
577
1878
  }
578
- const mirrorRoot = path2.resolve(
1879
+ const mirrorRoot = path6.resolve(
579
1880
  expandHomePath(
580
- options.gitMirrorRoot ?? path2.join(getDaemonConfigDir(), "git-mirror")
1881
+ options.gitMirrorRoot ?? path6.join(getDaemonConfigDir(), "git-mirror")
581
1882
  )
582
1883
  );
583
1884
  return {
@@ -595,8 +1896,8 @@ function createGitMirrorFromOptions(options) {
595
1896
 
596
1897
  // src/invest-wiki/runner.ts
597
1898
  import { access } from "fs/promises";
598
- import path3 from "path";
599
- import { execa as execa2 } from "execa";
1899
+ import path7 from "path";
1900
+ import { execa as execa3 } from "execa";
600
1901
 
601
1902
  // src/invest-wiki/config.ts
602
1903
  function resolveInvestWikiConfig(options, env = process.env) {
@@ -676,7 +1977,7 @@ function commandFailureMessage2(error) {
676
1977
  }
677
1978
  async function runInvestWikiCommand(command, args, options) {
678
1979
  try {
679
- return await execa2(command, args, options);
1980
+ return await execa3(command, args, options);
680
1981
  } catch (error) {
681
1982
  throw new InvestWikiRuntimeError(
682
1983
  "COMMAND_FAILED",
@@ -689,7 +1990,7 @@ function createLocalRepoRunner(config) {
689
1990
  return {
690
1991
  kind: "local-repo",
691
1992
  async run(args, options) {
692
- const cliPath = path3.join(config.localRepo, "dist", "cli.js");
1993
+ const cliPath = path7.join(config.localRepo, "dist", "cli.js");
693
1994
  await assertFileExists(cliPath);
694
1995
  const result = await runInvestWikiCommand(
695
1996
  process.execPath,
@@ -737,8 +2038,7 @@ function createInvestWikiRunnerFromOptions(options, env = process.env) {
737
2038
  }
738
2039
 
739
2040
  // src/notebooklm/pythonClient.ts
740
- import { execa as execa3 } from "execa";
741
- import { resolveInsideWorkspace } from "@xdsjs/dossierx-workspace";
2041
+ import { execa as execa4 } from "execa";
742
2042
  var DEFAULT_PYTHON_COMMAND = "python3";
743
2043
  var DEFAULT_TIMEOUT_MS = 15 * 60 * 1e3;
744
2044
  var DEFAULT_SOURCE_WAIT_TIMEOUT_SECONDS = 10 * 60;
@@ -858,7 +2158,7 @@ async function runBridge(options, action, input) {
858
2158
  if (options.home) {
859
2159
  env.NOTEBOOKLM_HOME = options.home;
860
2160
  }
861
- const result = await execa3(
2161
+ const result = await execa4(
862
2162
  options.pythonCommand ?? DEFAULT_PYTHON_COMMAND,
863
2163
  ["-c", NOTEBOOKLM_PY_BRIDGE],
864
2164
  {
@@ -910,20 +2210,14 @@ function createNotebookLmPythonClient(options) {
910
2210
 
911
2211
  // src/local-api/server.ts
912
2212
  import { createServer } from "http";
913
- import { readFile as readFile3, realpath, stat } from "fs/promises";
914
- import path5 from "path";
915
- import { execa as execa4 } from "execa";
916
- import {
917
- readCoverageContractBundle,
918
- resolveInsideWorkspace as resolveInsideWorkspace3,
919
- scanCompanyManifest
920
- } from "@xdsjs/dossierx-workspace";
2213
+ import { readFile as readFile6, realpath, stat as stat2 } from "fs/promises";
2214
+ import path9 from "path";
2215
+ import { execa as execa5 } from "execa";
921
2216
 
922
2217
  // src/task-archive.ts
923
2218
  import { randomUUID } from "crypto";
924
- import { appendFile, mkdir as mkdir2, readFile as readFile2 } from "fs/promises";
925
- import path4 from "path";
926
- import { resolveInsideWorkspace as resolveInsideWorkspace2 } from "@xdsjs/dossierx-workspace";
2219
+ import { appendFile, mkdir as mkdir4, readFile as readFile5 } from "fs/promises";
2220
+ import path8 from "path";
927
2221
  var TASK_ID_PATTERN = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
928
2222
  function assertTaskId(taskId) {
929
2223
  if (!TASK_ID_PATTERN.test(taskId)) {
@@ -932,14 +2226,14 @@ function assertTaskId(taskId) {
932
2226
  }
933
2227
  function taskDirectory(workspaceRoot, taskId) {
934
2228
  assertTaskId(taskId);
935
- return resolveInsideWorkspace2(
2229
+ return resolveInsideWorkspace(
936
2230
  workspaceRoot,
937
- path4.posix.join(".dossierx", "tasks", taskId)
2231
+ path8.posix.join(".dossierx", "tasks", taskId)
938
2232
  );
939
2233
  }
940
2234
  async function ensureTaskDirectory(workspaceRoot, taskId) {
941
2235
  const directory = taskDirectory(workspaceRoot, taskId);
942
- await mkdir2(directory, { recursive: true });
2236
+ await mkdir4(directory, { recursive: true });
943
2237
  return directory;
944
2238
  }
945
2239
  function parseEventLine(line) {
@@ -967,7 +2261,7 @@ function createTaskArchive(options) {
967
2261
  created_at: now().toISOString()
968
2262
  };
969
2263
  await appendFile(
970
- path4.join(directory, "events.jsonl"),
2264
+ path8.join(directory, "events.jsonl"),
971
2265
  `${JSON.stringify(archivedEvent)}
972
2266
  `,
973
2267
  "utf8"
@@ -976,13 +2270,13 @@ function createTaskArchive(options) {
976
2270
  },
977
2271
  async appendRawOutput(taskId, stream, chunk) {
978
2272
  const directory = await ensureTaskDirectory(options.workspaceRoot, taskId);
979
- await appendFile(path4.join(directory, `${stream}.log`), chunk, "utf8");
2273
+ await appendFile(path8.join(directory, `${stream}.log`), chunk, "utf8");
980
2274
  },
981
2275
  async listEvents(taskId) {
982
2276
  const directory = taskDirectory(options.workspaceRoot, taskId);
983
2277
  let content = "";
984
2278
  try {
985
- content = await readFile2(path4.join(directory, "events.jsonl"), "utf8");
2279
+ content = await readFile5(path8.join(directory, "events.jsonl"), "utf8");
986
2280
  } catch (error) {
987
2281
  if (error.code === "ENOENT") {
988
2282
  return [];
@@ -996,7 +2290,7 @@ function createTaskArchive(options) {
996
2290
 
997
2291
  // src/version.ts
998
2292
  var DAEMON_PACKAGE_NAME = "@xdsjs/dossierx-daemon";
999
- var DAEMON_VERSION = "0.1.13";
2293
+ var DAEMON_VERSION = "0.1.14";
1000
2294
 
1001
2295
  // src/local-api/server.ts
1002
2296
  var DEFAULT_MAX_FILE_BYTES = 5 * 1024 * 1024;
@@ -1023,15 +2317,15 @@ function requestUrl(request) {
1023
2317
  return new URL(request.url ?? "/", "http://127.0.0.1");
1024
2318
  }
1025
2319
  async function readWorkspaceFile(options) {
1026
- const extension = path5.extname(options.relativePath).toLowerCase();
2320
+ const extension = path9.extname(options.relativePath).toLowerCase();
1027
2321
  if (!ALLOWED_EXTENSIONS.has(extension)) {
1028
2322
  throw new Error("Only markdown, text, and json files can be previewed");
1029
2323
  }
1030
- const absolutePath = resolveInsideWorkspace3(
2324
+ const absolutePath = resolveInsideWorkspace(
1031
2325
  options.workspaceRoot,
1032
2326
  options.relativePath
1033
2327
  );
1034
- const stats = await stat(absolutePath);
2328
+ const stats = await stat2(absolutePath);
1035
2329
  if (!stats.isFile()) {
1036
2330
  throw new Error("Path is not a file");
1037
2331
  }
@@ -1040,7 +2334,7 @@ async function readWorkspaceFile(options) {
1040
2334
  }
1041
2335
  return {
1042
2336
  path: options.relativePath,
1043
- content: await readFile3(absolutePath, "utf8"),
2337
+ content: await readFile6(absolutePath, "utf8"),
1044
2338
  size: stats.size,
1045
2339
  updatedAt: stats.mtime.toISOString()
1046
2340
  };
@@ -1075,10 +2369,10 @@ function uniqueProbes(probes) {
1075
2369
  }
1076
2370
  async function resolveCommand(command) {
1077
2371
  const normalizedCommand = command.trim();
1078
- if (path5.isAbsolute(normalizedCommand)) {
2372
+ if (path9.isAbsolute(normalizedCommand)) {
1079
2373
  return realpath(normalizedCommand).catch(() => normalizedCommand);
1080
2374
  }
1081
- const result = await execa4("which", [normalizedCommand], {
2375
+ const result = await execa5("which", [normalizedCommand], {
1082
2376
  stdin: "ignore",
1083
2377
  reject: false,
1084
2378
  timeout: 3e3
@@ -1095,7 +2389,7 @@ async function detectCodexCommand(probe) {
1095
2389
  return null;
1096
2390
  }
1097
2391
  try {
1098
- const result = await execa4(command, ["--version"], {
2392
+ const result = await execa5(command, ["--version"], {
1099
2393
  stdin: "ignore",
1100
2394
  timeout: 5e3,
1101
2395
  reject: false
@@ -1192,7 +2486,7 @@ function isNewerVersion(candidate, current) {
1192
2486
  return false;
1193
2487
  }
1194
2488
  async function defaultLatestDaemonVersion(packageName) {
1195
- const result = await execa4("npm", ["view", packageName, "version"], {
2489
+ const result = await execa5("npm", ["view", packageName, "version"], {
1196
2490
  stdin: "ignore",
1197
2491
  timeout: 8e3,
1198
2492
  reject: false
@@ -1204,11 +2498,11 @@ async function defaultLatestDaemonVersion(packageName) {
1204
2498
  }
1205
2499
  async function defaultUpdateDaemonPackage(input) {
1206
2500
  const customCommand = process.env.DOSSIERX_DAEMON_UPDATE_COMMAND?.trim();
1207
- const result = customCommand ? await execa4("/bin/zsh", ["-lc", customCommand], {
2501
+ const result = customCommand ? await execa5("/bin/zsh", ["-lc", customCommand], {
1208
2502
  stdin: "ignore",
1209
2503
  timeout: 12e4,
1210
2504
  reject: false
1211
- }) : await execa4("npm", ["install", "-g", `${input.packageName}@latest`], {
2505
+ }) : await execa5("npm", ["install", "-g", `${input.packageName}@latest`], {
1212
2506
  stdin: "ignore",
1213
2507
  timeout: 12e4,
1214
2508
  reject: false
@@ -1446,12 +2740,7 @@ async function startWorkspaceReadServer(options) {
1446
2740
  }
1447
2741
 
1448
2742
  // src/loop.ts
1449
- import { z as z2 } from "zod";
1450
- import {
1451
- TaskEventInputSchema,
1452
- TaskSchema
1453
- } from "@xdsjs/dossierx-shared";
1454
- import { GitMirrorError } from "@xdsjs/dossierx-git-mirror";
2743
+ import { z as z13 } from "zod";
1455
2744
 
1456
2745
  // src/errors.ts
1457
2746
  function failTaskError(error, code = "UNKNOWN", step) {
@@ -1466,13 +2755,7 @@ function failTaskError(error, code = "UNKNOWN", step) {
1466
2755
  }
1467
2756
 
1468
2757
  // src/executors/codex.ts
1469
- import { readdir, stat as stat2 } from "fs/promises";
1470
- import {
1471
- buildCompanyManifest,
1472
- companyManifestPath,
1473
- investWikiRoot,
1474
- resolveInsideWorkspace as resolveInsideWorkspace4
1475
- } from "@xdsjs/dossierx-workspace";
2758
+ import { readdir as readdir3, stat as stat3 } from "fs/promises";
1476
2759
  function isWorkspaceGuardError(error) {
1477
2760
  if (!(error instanceof Error)) {
1478
2761
  return false;
@@ -1485,7 +2768,7 @@ function isWorkspaceGuardError(error) {
1485
2768
  }
1486
2769
  function workspacePath(workspaceRoot, relativePath, step) {
1487
2770
  try {
1488
- return resolveInsideWorkspace4(workspaceRoot, relativePath);
2771
+ return resolveInsideWorkspace(workspaceRoot, relativePath);
1489
2772
  } catch (error) {
1490
2773
  if (isWorkspaceGuardError(error)) {
1491
2774
  throw new CodexRuntimeError(
@@ -1509,7 +2792,7 @@ function requireRunner(context) {
1509
2792
  }
1510
2793
  async function requireFile(filePath, step) {
1511
2794
  try {
1512
- const fileStat = await stat2(filePath);
2795
+ const fileStat = await stat3(filePath);
1513
2796
  if (fileStat.isFile()) {
1514
2797
  return;
1515
2798
  }
@@ -1527,7 +2810,7 @@ async function requireFile(filePath, step) {
1527
2810
  async function requireInitializedVault(workspaceRoot, ticker, step) {
1528
2811
  const vaultRoot = workspacePath(workspaceRoot, investWikiRoot(ticker), step);
1529
2812
  try {
1530
- const vaultStat = await stat2(vaultRoot);
2813
+ const vaultStat = await stat3(vaultRoot);
1531
2814
  if (!vaultStat.isDirectory()) {
1532
2815
  throw new CodexRuntimeError(
1533
2816
  "WORKSPACE_NOT_FOUND",
@@ -1593,10 +2876,10 @@ async function appendOutputEvent(context, message, output) {
1593
2876
  });
1594
2877
  }
1595
2878
  async function directoryHasFiles(root, relativePath) {
1596
- const directory = resolveInsideWorkspace4(root, relativePath);
2879
+ const directory = resolveInsideWorkspace(root, relativePath);
1597
2880
  let entries;
1598
2881
  try {
1599
- entries = await readdir(directory, { withFileTypes: true });
2882
+ entries = await readdir3(directory, { withFileTypes: true });
1600
2883
  } catch (error) {
1601
2884
  if (error.code === "ENOENT") {
1602
2885
  return false;
@@ -1672,9 +2955,9 @@ async function runCodexTask(task, context) {
1672
2955
  }
1673
2956
 
1674
2957
  // src/executors/financialReports.ts
1675
- import { createHash } from "crypto";
1676
- import { mkdir as mkdir3, readFile as readFile4, writeFile as writeFile2 } from "fs/promises";
1677
- import path6 from "path";
2958
+ import { createHash as createHash3 } from "crypto";
2959
+ import { mkdir as mkdir5, readFile as readFile7, writeFile as writeFile4 } from "fs/promises";
2960
+ import path10 from "path";
1678
2961
  import {
1679
2962
  FinancialReportManifestSchema,
1680
2963
  assessReportCoverage,
@@ -1685,12 +2968,6 @@ import {
1685
2968
  renderSecHtmlToPdf,
1686
2969
  runNotebookLmFinancialReportsIngest
1687
2970
  } from "@xdsjs/dossier-financial-reports";
1688
- import {
1689
- buildCompanyManifest as buildCompanyManifest2,
1690
- companyManifestPath as companyManifestPath2,
1691
- financialReportsIndexPath,
1692
- resolveInsideWorkspace as resolveInsideWorkspace5
1693
- } from "@xdsjs/dossierx-workspace";
1694
2971
  var FinancialReportsRuntimeError = class extends Error {
1695
2972
  code;
1696
2973
  step;
@@ -1728,7 +3005,7 @@ function marketToAppMarket(market) {
1728
3005
  return "cn";
1729
3006
  }
1730
3007
  function sha256Json(value) {
1731
- return `sha256:${createHash("sha256").update(JSON.stringify(value)).digest("hex")}`;
3008
+ return `sha256:${createHash3("sha256").update(JSON.stringify(value)).digest("hex")}`;
1732
3009
  }
1733
3010
  function writeWorkspaceJson(context, relativePath, value) {
1734
3011
  return writeWorkspaceBytes(
@@ -1747,10 +3024,10 @@ function writeWorkspaceText(context, relativePath, value) {
1747
3024
  );
1748
3025
  }
1749
3026
  async function writeWorkspaceBytes(context, relativePath, bytes) {
1750
- const absolutePath = resolveInsideWorkspace5(context.workspaceRoot, relativePath);
1751
- await mkdir3(path6.dirname(absolutePath), { recursive: true });
3027
+ const absolutePath = resolveInsideWorkspace(context.workspaceRoot, relativePath);
3028
+ await mkdir5(path10.dirname(absolutePath), { recursive: true });
1752
3029
  if (!context.dryRun) {
1753
- await writeFile2(absolutePath, bytes);
3030
+ await writeFile4(absolutePath, bytes);
1754
3031
  }
1755
3032
  }
1756
3033
  function createWorkspaceStorage(context) {
@@ -1761,8 +3038,8 @@ function createWorkspaceStorage(context) {
1761
3038
  };
1762
3039
  }
1763
3040
  function readWorkspaceJson(context, relativePath) {
1764
- const absolutePath = resolveInsideWorkspace5(context.workspaceRoot, relativePath);
1765
- return readFile4(absolutePath, "utf8").then((content) => JSON.parse(content));
3041
+ const absolutePath = resolveInsideWorkspace(context.workspaceRoot, relativePath);
3042
+ return readFile7(absolutePath, "utf8").then((content) => JSON.parse(content));
1766
3043
  }
1767
3044
  function parseReportManifest(payload) {
1768
3045
  const maybeRecord = typeof payload === "object" && payload !== null ? payload : {};
@@ -1930,7 +3207,7 @@ async function runSyncReports(task, context) {
1930
3207
  missingReports: result.missingReports
1931
3208
  };
1932
3209
  await writeWorkspaceJson(context, reportIndexPath, reportIndex);
1933
- const companyManifest = context.dryRun ? void 0 : await buildCompanyManifest2({
3210
+ const companyManifest = context.dryRun ? void 0 : await buildCompanyManifest({
1934
3211
  workspaceRoot: context.workspaceRoot,
1935
3212
  ticker,
1936
3213
  market: marketToAppMarket(market)
@@ -1949,9 +3226,9 @@ async function runSyncReports(task, context) {
1949
3226
  generatedFiles: [
1950
3227
  ...result.manifest.reports.map((report) => report.localPath),
1951
3228
  reportIndexPath,
1952
- companyManifestPath2(ticker)
3229
+ companyManifestPath(ticker)
1953
3230
  ],
1954
- manifestPath: companyManifestPath2(ticker),
3231
+ manifestPath: companyManifestPath(ticker),
1955
3232
  manifest: companyManifest,
1956
3233
  blockingReasons: [],
1957
3234
  financialReports: financialTaskResult({
@@ -1997,7 +3274,7 @@ async function runNotebookIngest(task, context) {
1997
3274
  wikiPath,
1998
3275
  renderFinancialFactsWiki(ingest.factsBundle)
1999
3276
  );
2000
- const companyManifest = context.dryRun ? void 0 : await buildCompanyManifest2({
3277
+ const companyManifest = context.dryRun ? void 0 : await buildCompanyManifest({
2001
3278
  workspaceRoot: context.workspaceRoot,
2002
3279
  ticker,
2003
3280
  market: marketToAppMarket(primaryMarket(manifest.issuer))
@@ -2017,9 +3294,9 @@ async function runNotebookIngest(task, context) {
2017
3294
  notebookPath,
2018
3295
  factsBundlePath,
2019
3296
  wikiPath,
2020
- companyManifestPath2(ticker)
3297
+ companyManifestPath(ticker)
2021
3298
  ],
2022
- manifestPath: companyManifestPath2(ticker),
3299
+ manifestPath: companyManifestPath(ticker),
2023
3300
  manifest: companyManifest,
2024
3301
  blockingReasons: [],
2025
3302
  financialReports: financialTaskResult({
@@ -2091,15 +3368,8 @@ async function runFinancialReportsTask(task, context) {
2091
3368
  }
2092
3369
 
2093
3370
  // src/executors/investWiki.ts
2094
- import { access as access2, mkdir as mkdir4, readFile as readFile5, stat as stat3, writeFile as writeFile3 } from "fs/promises";
2095
- import path7 from "path";
2096
- import {
2097
- buildCompanyManifest as buildCompanyManifest3,
2098
- companyManifestPath as companyManifestPath3,
2099
- investWikiConfigPath,
2100
- investWikiRoot as investWikiRoot2,
2101
- resolveInsideWorkspace as resolveInsideWorkspace6
2102
- } from "@xdsjs/dossierx-workspace";
3371
+ import { access as access2, mkdir as mkdir6, readFile as readFile8, stat as stat4, writeFile as writeFile5 } from "fs/promises";
3372
+ import path11 from "path";
2103
3373
  async function exists(absolutePath) {
2104
3374
  try {
2105
3375
  await access2(absolutePath);
@@ -2123,7 +3393,7 @@ function isWorkspaceGuardError2(error) {
2123
3393
  }
2124
3394
  function workspacePath2(workspaceRoot, relativePath, step) {
2125
3395
  try {
2126
- return resolveInsideWorkspace6(workspaceRoot, relativePath);
3396
+ return resolveInsideWorkspace(workspaceRoot, relativePath);
2127
3397
  } catch (error) {
2128
3398
  if (isWorkspaceGuardError2(error)) {
2129
3399
  throw new InvestWikiRuntimeError(
@@ -2146,9 +3416,9 @@ function requireRunner2(context) {
2146
3416
  return context.investWiki;
2147
3417
  }
2148
3418
  async function requireVaultRoot(workspaceRoot, ticker, step) {
2149
- const vaultRoot = workspacePath2(workspaceRoot, investWikiRoot2(ticker), step);
3419
+ const vaultRoot = workspacePath2(workspaceRoot, investWikiRoot(ticker), step);
2150
3420
  try {
2151
- const vaultStat = await stat3(vaultRoot);
3421
+ const vaultStat = await stat4(vaultRoot);
2152
3422
  if (vaultStat.isDirectory()) {
2153
3423
  return vaultRoot;
2154
3424
  }
@@ -2204,11 +3474,11 @@ function isMarket(value) {
2204
3474
  async function readManifestMarket(workspaceRoot, ticker) {
2205
3475
  const manifestPath = workspacePath2(
2206
3476
  workspaceRoot,
2207
- companyManifestPath3(ticker),
3477
+ companyManifestPath(ticker),
2208
3478
  "invest_wiki.sync"
2209
3479
  );
2210
3480
  try {
2211
- const manifest = JSON.parse(await readFile5(manifestPath, "utf8"));
3481
+ const manifest = JSON.parse(await readFile8(manifestPath, "utf8"));
2212
3482
  if (!isMarket(manifest.market)) {
2213
3483
  throw new InvestWikiRuntimeError(
2214
3484
  "VALIDATION_ERROR",
@@ -2234,7 +3504,7 @@ async function readManifestMarket(workspaceRoot, ticker) {
2234
3504
  async function runInitCompanyVault(task, context) {
2235
3505
  const runner = requireRunner2(context);
2236
3506
  const ticker = task.payload.ticker;
2237
- const vaultRelativePath = investWikiRoot2(ticker);
3507
+ const vaultRelativePath = investWikiRoot(ticker);
2238
3508
  const vaultRoot = workspacePath2(
2239
3509
  context.workspaceRoot,
2240
3510
  vaultRelativePath,
@@ -2251,7 +3521,7 @@ async function runInitCompanyVault(task, context) {
2251
3521
  `${vaultRelativePath}/.llm-wiki-invest/dossier-state.json`,
2252
3522
  "invest_wiki.init_company_vault"
2253
3523
  );
2254
- await mkdir4(vaultRoot, { recursive: true });
3524
+ await mkdir6(vaultRoot, { recursive: true });
2255
3525
  await context.appendEvent({
2256
3526
  level: "info",
2257
3527
  message: "Initializing invest-wiki vault",
@@ -2270,10 +3540,10 @@ async function runInitCompanyVault(task, context) {
2270
3540
  const statusOutput = await runner.run(["dossier", "status"], { cwd: vaultRoot });
2271
3541
  await appendOutputEvent2(context, "Invest wiki dossier status completed", statusOutput);
2272
3542
  if (!await exists(markerPath)) {
2273
- await mkdir4(path7.dirname(markerPath), { recursive: true });
2274
- await writeFile3(markerPath, "# Created by dossierx-daemon\n");
3543
+ await mkdir6(path11.dirname(markerPath), { recursive: true });
3544
+ await writeFile5(markerPath, "# Created by dossierx-daemon\n");
2275
3545
  }
2276
- const manifest = await buildCompanyManifest3({
3546
+ const manifest = await buildCompanyManifest({
2277
3547
  workspaceRoot: context.workspaceRoot,
2278
3548
  ticker,
2279
3549
  market: task.payload.market
@@ -2287,10 +3557,10 @@ async function runInitCompanyVault(task, context) {
2287
3557
  generatedFiles: [
2288
3558
  vaultRelativePath,
2289
3559
  markerRelativePath,
2290
- companyManifestPath3(ticker)
3560
+ companyManifestPath(ticker)
2291
3561
  ],
2292
3562
  blockingReasons: [],
2293
- manifestPath: companyManifestPath3(ticker),
3563
+ manifestPath: companyManifestPath(ticker),
2294
3564
  manifest
2295
3565
  };
2296
3566
  }
@@ -2315,7 +3585,7 @@ async function runStatus(task, context) {
2315
3585
  return {
2316
3586
  generatedFiles: [],
2317
3587
  blockingReasons: [],
2318
- manifestPath: companyManifestPath3(ticker)
3588
+ manifestPath: companyManifestPath(ticker)
2319
3589
  };
2320
3590
  }
2321
3591
  async function runSync(task, context) {
@@ -2330,7 +3600,7 @@ async function runSync(task, context) {
2330
3600
  const args = task.payload.dryRun ? ["sync", "--dry-run"] : ["sync"];
2331
3601
  const output = await runner.run(args, { cwd: vaultRoot });
2332
3602
  await appendOutputEvent2(context, "Invest wiki sync completed", output);
2333
- const manifest = await buildCompanyManifest3({
3603
+ const manifest = await buildCompanyManifest({
2334
3604
  workspaceRoot: context.workspaceRoot,
2335
3605
  ticker,
2336
3606
  market
@@ -2338,7 +3608,7 @@ async function runSync(task, context) {
2338
3608
  return {
2339
3609
  generatedFiles: [],
2340
3610
  blockingReasons: [],
2341
- manifestPath: companyManifestPath3(ticker),
3611
+ manifestPath: companyManifestPath(ticker),
2342
3612
  manifest
2343
3613
  };
2344
3614
  }
@@ -2360,17 +3630,8 @@ async function runInvestWikiTask(task, context) {
2360
3630
  }
2361
3631
 
2362
3632
  // src/executors/mockWriteCompanyReport.ts
2363
- import { mkdir as mkdir5, writeFile as writeFile4 } from "fs/promises";
2364
- import path8 from "path";
2365
- import {
2366
- buildCompanyManifest as buildCompanyManifest4,
2367
- companyManifestPath as companyManifestPath4,
2368
- companyRoot,
2369
- resolveInsideWorkspace as resolveInsideWorkspace7,
2370
- rightBusinessPath,
2371
- rightPeoplePath,
2372
- rightPricePath
2373
- } from "@xdsjs/dossierx-workspace";
3633
+ import { mkdir as mkdir7, writeFile as writeFile6 } from "fs/promises";
3634
+ import path12 from "path";
2374
3635
  var rightBusiness = (ticker) => `# Right Business - ${ticker}
2375
3636
 
2376
3637
  > Mock output generated by dossierx-daemon.
@@ -2400,10 +3661,10 @@ var rightPrice = (ticker) => `# Right Price - ${ticker}
2400
3661
  This is a placeholder right-price analysis for ${ticker}.
2401
3662
  `;
2402
3663
  async function writeWorkspaceFile(context, relativePath, content) {
2403
- const absolutePath = resolveInsideWorkspace7(context.workspaceRoot, relativePath);
2404
- await mkdir5(path8.dirname(absolutePath), { recursive: true });
3664
+ const absolutePath = resolveInsideWorkspace(context.workspaceRoot, relativePath);
3665
+ await mkdir7(path12.dirname(absolutePath), { recursive: true });
2405
3666
  if (!context.dryRun) {
2406
- await writeFile4(absolutePath, content);
3667
+ await writeFile6(absolutePath, content);
2407
3668
  }
2408
3669
  }
2409
3670
  async function runMockWriteCompanyReport(task, context) {
@@ -2418,7 +3679,7 @@ async function runMockWriteCompanyReport(task, context) {
2418
3679
  message: "Creating company directory",
2419
3680
  data: { ticker }
2420
3681
  });
2421
- await mkdir5(resolveInsideWorkspace7(context.workspaceRoot, companyRoot(ticker)), {
3682
+ await mkdir7(resolveInsideWorkspace(context.workspaceRoot, companyRoot(ticker)), {
2422
3683
  recursive: true
2423
3684
  });
2424
3685
  await context.appendEvent({
@@ -2442,11 +3703,11 @@ async function runMockWriteCompanyReport(task, context) {
2442
3703
  await context.appendEvent({
2443
3704
  level: "info",
2444
3705
  message: "Generating manifest.json",
2445
- data: { path: companyManifestPath4(ticker) }
3706
+ data: { path: companyManifestPath(ticker) }
2446
3707
  });
2447
3708
  let manifest;
2448
3709
  if (!context.dryRun) {
2449
- manifest = await buildCompanyManifest4({
3710
+ manifest = await buildCompanyManifest({
2450
3711
  workspaceRoot: context.workspaceRoot,
2451
3712
  ticker,
2452
3713
  market: task.payload.market
@@ -2458,9 +3719,9 @@ async function runMockWriteCompanyReport(task, context) {
2458
3719
  data: { ticker }
2459
3720
  });
2460
3721
  return {
2461
- generatedFiles: [...generatedFiles, companyManifestPath4(ticker)],
3722
+ generatedFiles: [...generatedFiles, companyManifestPath(ticker)],
2462
3723
  blockingReasons: [],
2463
- manifestPath: companyManifestPath4(ticker),
3724
+ manifestPath: companyManifestPath(ticker),
2464
3725
  manifest
2465
3726
  };
2466
3727
  }
@@ -2487,7 +3748,7 @@ function taskIdFromUnknown(value) {
2487
3748
  if (!value || typeof value !== "object" || !("id" in value)) {
2488
3749
  return null;
2489
3750
  }
2490
- const parsed = z2.string().uuid().safeParse(value.id);
3751
+ const parsed = z13.string().uuid().safeParse(value.id);
2491
3752
  return parsed.success ? parsed.data : null;
2492
3753
  }
2493
3754
  async function appendEvent(ctx, taskId, message) {
@@ -2722,10 +3983,10 @@ function createLogger(level = "info", stream) {
2722
3983
  }
2723
3984
 
2724
3985
  // src/runtime/detect.ts
2725
- import { execa as execa5 } from "execa";
3986
+ import { execa as execa6 } from "execa";
2726
3987
  async function commandResponds(command, args = ["--version"]) {
2727
3988
  try {
2728
- await execa5(command, args, {
3989
+ await execa6(command, args, {
2729
3990
  reject: true,
2730
3991
  timeout: 2e3,
2731
3992
  stdout: "ignore",
@@ -2737,7 +3998,7 @@ async function commandResponds(command, args = ["--version"]) {
2737
3998
  }
2738
3999
  }
2739
4000
  async function detectCapabilities(options = {}) {
2740
- const [git, python3, python, investWikiRuntime, codex, claude, notebookLm] = await Promise.all([
4001
+ const [git2, python3, python, investWikiRuntime, codex, claude, notebookLm] = await Promise.all([
2741
4002
  commandResponds("git"),
2742
4003
  commandResponds("python3"),
2743
4004
  commandResponds("python"),
@@ -2747,7 +4008,7 @@ async function detectCapabilities(options = {}) {
2747
4008
  probeNotebookLmPythonClient(options.notebookLm)
2748
4009
  ]);
2749
4010
  return {
2750
- git,
4011
+ git: git2,
2751
4012
  node: true,
2752
4013
  python: python3 || python,
2753
4014
  financialReports: true,
@@ -2761,9 +4022,6 @@ async function detectCapabilities(options = {}) {
2761
4022
 
2762
4023
  // src/realtime/client.ts
2763
4024
  import { createClient } from "@supabase/supabase-js";
2764
- import {
2765
- RealtimeEventSchema
2766
- } from "@xdsjs/dossierx-shared";
2767
4025
  function normalizeBroadcast(message) {
2768
4026
  const value = message;
2769
4027
  if (value.payload && typeof value.payload === "object" && "event" in value.payload) {
@@ -2829,9 +4087,9 @@ async function subscribeToTaskAvailable(options, onEvent, onInvalidEvent) {
2829
4087
  }
2830
4088
 
2831
4089
  // src/service.ts
2832
- import { mkdir as mkdir6, unlink, writeFile as writeFile5 } from "fs/promises";
4090
+ import { mkdir as mkdir8, unlink, writeFile as writeFile7 } from "fs/promises";
2833
4091
  import os2 from "os";
2834
- import path9 from "path";
4092
+ import path13 from "path";
2835
4093
  var LAUNCH_AGENT_LABEL = "com.xdsjs.dossierx-daemon";
2836
4094
  function xmlEscape(value) {
2837
4095
  return value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&apos;");
@@ -2840,10 +4098,10 @@ function shellQuote(value) {
2840
4098
  return `'${value.replaceAll("'", "'\\''")}'`;
2841
4099
  }
2842
4100
  function launchAgentsDir() {
2843
- return path9.join(os2.homedir(), "Library", "LaunchAgents");
4101
+ return path13.join(os2.homedir(), "Library", "LaunchAgents");
2844
4102
  }
2845
4103
  function launchAgentPlistPath(label = LAUNCH_AGENT_LABEL, dir = launchAgentsDir()) {
2846
- return path9.join(dir, `${label}.plist`);
4104
+ return path13.join(dir, `${label}.plist`);
2847
4105
  }
2848
4106
  function resolveDaemonProgramArguments(input) {
2849
4107
  if (input.daemonCommand?.trim()) {
@@ -2854,14 +4112,14 @@ function resolveDaemonProgramArguments(input) {
2854
4112
  if (!entry) {
2855
4113
  throw new Error("Unable to resolve daemon entrypoint for LaunchAgent");
2856
4114
  }
2857
- if (path9.extname(entry) === ".ts") {
4115
+ if (path13.extname(entry) === ".ts") {
2858
4116
  throw new Error(
2859
4117
  "LaunchAgent cannot run a TypeScript daemon entrypoint directly; pass --daemon-command when installing from source"
2860
4118
  );
2861
4119
  }
2862
4120
  return [
2863
4121
  input.execPath ?? process.execPath,
2864
- path9.resolve(entry),
4122
+ path13.resolve(entry),
2865
4123
  "--log-level",
2866
4124
  input.logLevel ?? "info"
2867
4125
  ];
@@ -2924,7 +4182,7 @@ async function installLaunchAgent(options = {}) {
2924
4182
  throw new Error("DossierX LaunchAgent service is only supported on macOS");
2925
4183
  }
2926
4184
  const label = options.label ?? LAUNCH_AGENT_LABEL;
2927
- const configDir = path9.resolve(
4185
+ const configDir = path13.resolve(
2928
4186
  expandHomePath(options.configDir ?? getDaemonConfigDir())
2929
4187
  );
2930
4188
  const config = await readDaemonLocalConfig(configDir);
@@ -2944,8 +4202,8 @@ async function installLaunchAgent(options = {}) {
2944
4202
  );
2945
4203
  }
2946
4204
  const plistPath = launchAgentPlistPath(label, options.launchAgentsDir);
2947
- const stdoutPath = path9.join(configDir, "daemon.out.log");
2948
- const stderrPath = path9.join(configDir, "daemon.err.log");
4205
+ const stdoutPath = path13.join(configDir, "daemon.out.log");
4206
+ const stderrPath = path13.join(configDir, "daemon.err.log");
2949
4207
  const uid = typeof process.getuid === "function" ? process.getuid() : "<uid>";
2950
4208
  const programArguments = resolveDaemonProgramArguments({
2951
4209
  daemonCommand: options.daemonCommand,
@@ -2953,9 +4211,9 @@ async function installLaunchAgent(options = {}) {
2953
4211
  argv: options.argv,
2954
4212
  execPath: options.execPath
2955
4213
  });
2956
- await mkdir6(path9.dirname(plistPath), { recursive: true });
2957
- await mkdir6(configDir, { recursive: true, mode: 448 });
2958
- await writeFile5(
4214
+ await mkdir8(path13.dirname(plistPath), { recursive: true });
4215
+ await mkdir8(configDir, { recursive: true, mode: 448 });
4216
+ await writeFile7(
2959
4217
  plistPath,
2960
4218
  buildLaunchAgentPlist({
2961
4219
  label,
@@ -2996,14 +4254,14 @@ async function uninstallLaunchAgent(options = {}) {
2996
4254
 
2997
4255
  // src/cli.ts
2998
4256
  async function ensureWorkspaceDirectory(workspace) {
2999
- await mkdir7(workspace, { recursive: true }).catch(async (error) => {
3000
- const stats2 = await stat4(workspace).catch(() => null);
4257
+ await mkdir9(workspace, { recursive: true }).catch(async (error) => {
4258
+ const stats2 = await stat5(workspace).catch(() => null);
3001
4259
  if (!stats2?.isDirectory()) {
3002
4260
  throw new Error("Workspace path is not a directory");
3003
4261
  }
3004
4262
  throw error;
3005
4263
  });
3006
- const stats = await stat4(workspace);
4264
+ const stats = await stat5(workspace);
3007
4265
  if (!stats.isDirectory()) {
3008
4266
  throw new Error("Workspace path is not a directory");
3009
4267
  }
@@ -3109,7 +4367,7 @@ async function runDaemon(options) {
3109
4367
  "Missing daemon connection config. Run the generated daemon command from DossierX first."
3110
4368
  );
3111
4369
  }
3112
- const workspaceRoot = path10.resolve(expandHomePath(workspacePath3));
4370
+ const workspaceRoot = path14.resolve(expandHomePath(workspacePath3));
3113
4371
  await ensureWorkspaceDirectory(workspaceRoot);
3114
4372
  const notebookLmOptions = {
3115
4373
  pythonCommand: runtimeOptions.notebookLmPythonCommand,