@xdsjs/dossierx-daemon 0.1.7 → 0.1.8
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/index.js +242 -32
- package/package.json +27 -19
package/dist/index.js
CHANGED
|
@@ -524,6 +524,10 @@ var DaemonLocalConfigSchema = z.object({
|
|
|
524
524
|
gitMirrorRemote: z.string().optional(),
|
|
525
525
|
gitMirrorBranch: z.string().optional(),
|
|
526
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(),
|
|
527
531
|
localApiPort: z.number().int().positive().optional()
|
|
528
532
|
});
|
|
529
533
|
function expandHomePath(input) {
|
|
@@ -732,14 +736,186 @@ function createInvestWikiRunnerFromOptions(options, env = process.env) {
|
|
|
732
736
|
return createInvestWikiRunner(resolveInvestWikiConfig(options, env));
|
|
733
737
|
}
|
|
734
738
|
|
|
739
|
+
// src/notebooklm/pythonClient.ts
|
|
740
|
+
import { execa as execa3 } from "execa";
|
|
741
|
+
import { resolveInsideWorkspace } from "@xdsjs/dossierx-workspace";
|
|
742
|
+
var DEFAULT_PYTHON_COMMAND = "python3";
|
|
743
|
+
var DEFAULT_TIMEOUT_MS = 15 * 60 * 1e3;
|
|
744
|
+
var DEFAULT_SOURCE_WAIT_TIMEOUT_SECONDS = 10 * 60;
|
|
745
|
+
var NOTEBOOKLM_PY_BRIDGE = String.raw`
|
|
746
|
+
import asyncio
|
|
747
|
+
import json
|
|
748
|
+
import os
|
|
749
|
+
import re
|
|
750
|
+
import sys
|
|
751
|
+
from datetime import datetime, timezone
|
|
752
|
+
|
|
753
|
+
def now_iso():
|
|
754
|
+
return datetime.now(timezone.utc).isoformat().replace("+00:00", "Z")
|
|
755
|
+
|
|
756
|
+
def iso_or_none(value):
|
|
757
|
+
if value is None:
|
|
758
|
+
return None
|
|
759
|
+
if hasattr(value, "isoformat"):
|
|
760
|
+
return value.isoformat()
|
|
761
|
+
return str(value)
|
|
762
|
+
|
|
763
|
+
def extract_json(text):
|
|
764
|
+
if not isinstance(text, str):
|
|
765
|
+
raise ValueError("NotebookLM answer is not text")
|
|
766
|
+
stripped = text.strip()
|
|
767
|
+
fence = chr(96) * 3
|
|
768
|
+
if stripped.startswith(fence):
|
|
769
|
+
stripped = re.sub(r"^" + fence + r"(?:json)?\s*", "", stripped)
|
|
770
|
+
stripped = re.sub(r"\s*" + fence + r"$", "", stripped)
|
|
771
|
+
try:
|
|
772
|
+
return json.loads(stripped)
|
|
773
|
+
except json.JSONDecodeError:
|
|
774
|
+
start = stripped.find("{")
|
|
775
|
+
end = stripped.rfind("}")
|
|
776
|
+
if start == -1 or end == -1 or end <= start:
|
|
777
|
+
raise
|
|
778
|
+
return json.loads(stripped[start:end + 1])
|
|
779
|
+
|
|
780
|
+
async def main():
|
|
781
|
+
payload = json.loads(sys.stdin.read() or "{}")
|
|
782
|
+
home = payload.get("home")
|
|
783
|
+
if home:
|
|
784
|
+
os.environ["NOTEBOOKLM_HOME"] = home
|
|
785
|
+
|
|
786
|
+
from notebooklm import NotebookLMClient
|
|
787
|
+
|
|
788
|
+
storage_path = payload.get("storagePath") or None
|
|
789
|
+
profile = payload.get("profile") or None
|
|
790
|
+
keepalive = payload.get("keepaliveSeconds")
|
|
791
|
+
client_options = {}
|
|
792
|
+
if storage_path:
|
|
793
|
+
client_options["path"] = storage_path
|
|
794
|
+
if profile:
|
|
795
|
+
client_options["profile"] = profile
|
|
796
|
+
if keepalive is not None:
|
|
797
|
+
client_options["keepalive"] = float(keepalive)
|
|
798
|
+
|
|
799
|
+
async with await NotebookLMClient.from_storage(**client_options) as client:
|
|
800
|
+
action = payload.get("action")
|
|
801
|
+
data = payload.get("input") or {}
|
|
802
|
+
|
|
803
|
+
if action == "health":
|
|
804
|
+
notebooks = await client.notebooks.list()
|
|
805
|
+
print(json.dumps({"ok": True, "notebookCount": len(notebooks)}, ensure_ascii=False))
|
|
806
|
+
return
|
|
807
|
+
|
|
808
|
+
if action == "createNotebook":
|
|
809
|
+
notebook = await client.notebooks.create(data["title"])
|
|
810
|
+
print(json.dumps({
|
|
811
|
+
"notebookId": notebook.id,
|
|
812
|
+
"createdAt": iso_or_none(getattr(notebook, "created_at", None)),
|
|
813
|
+
}, ensure_ascii=False))
|
|
814
|
+
return
|
|
815
|
+
|
|
816
|
+
if action == "ingestSource":
|
|
817
|
+
report = data["report"]
|
|
818
|
+
source = await client.sources.add_file(
|
|
819
|
+
data["notebookId"],
|
|
820
|
+
data["filePath"],
|
|
821
|
+
mime_type=report.get("mimeType") or "application/pdf",
|
|
822
|
+
wait=True,
|
|
823
|
+
wait_timeout=float(payload.get("sourceWaitTimeoutSeconds") or 600),
|
|
824
|
+
)
|
|
825
|
+
timestamp = now_iso()
|
|
826
|
+
print(json.dumps({
|
|
827
|
+
"reportId": data["reportId"],
|
|
828
|
+
"sourceId": source.id,
|
|
829
|
+
"uploadedAt": timestamp,
|
|
830
|
+
"ingestedAt": timestamp,
|
|
831
|
+
}, ensure_ascii=False))
|
|
832
|
+
return
|
|
833
|
+
|
|
834
|
+
if action == "extractFacts":
|
|
835
|
+
result = await client.chat.ask(
|
|
836
|
+
data["notebookId"],
|
|
837
|
+
data["prompt"],
|
|
838
|
+
source_ids=[source["sourceId"] for source in data.get("sourceIds", [])],
|
|
839
|
+
)
|
|
840
|
+
print(json.dumps(extract_json(result.answer), ensure_ascii=False))
|
|
841
|
+
return
|
|
842
|
+
|
|
843
|
+
raise ValueError(f"Unsupported NotebookLM bridge action: {action}")
|
|
844
|
+
|
|
845
|
+
asyncio.run(main())
|
|
846
|
+
`;
|
|
847
|
+
async function runBridge(options, action, input) {
|
|
848
|
+
const payload = {
|
|
849
|
+
action,
|
|
850
|
+
input,
|
|
851
|
+
profile: options.profile,
|
|
852
|
+
storagePath: options.storagePath,
|
|
853
|
+
home: options.home,
|
|
854
|
+
sourceWaitTimeoutSeconds: options.sourceWaitTimeoutSeconds ?? DEFAULT_SOURCE_WAIT_TIMEOUT_SECONDS,
|
|
855
|
+
keepaliveSeconds: options.keepaliveSeconds
|
|
856
|
+
};
|
|
857
|
+
const env = { ...process.env };
|
|
858
|
+
if (options.home) {
|
|
859
|
+
env.NOTEBOOKLM_HOME = options.home;
|
|
860
|
+
}
|
|
861
|
+
const result = await execa3(
|
|
862
|
+
options.pythonCommand ?? DEFAULT_PYTHON_COMMAND,
|
|
863
|
+
["-c", NOTEBOOKLM_PY_BRIDGE],
|
|
864
|
+
{
|
|
865
|
+
input: JSON.stringify(payload),
|
|
866
|
+
timeout: options.timeoutMs ?? DEFAULT_TIMEOUT_MS,
|
|
867
|
+
env
|
|
868
|
+
}
|
|
869
|
+
);
|
|
870
|
+
return JSON.parse(result.stdout);
|
|
871
|
+
}
|
|
872
|
+
async function probeNotebookLmPythonClient(options = {}) {
|
|
873
|
+
try {
|
|
874
|
+
const result = await runBridge(
|
|
875
|
+
{
|
|
876
|
+
...options,
|
|
877
|
+
timeoutMs: options.timeoutMs ?? 1e4
|
|
878
|
+
},
|
|
879
|
+
"health"
|
|
880
|
+
);
|
|
881
|
+
return result.ok === true;
|
|
882
|
+
} catch {
|
|
883
|
+
return false;
|
|
884
|
+
}
|
|
885
|
+
}
|
|
886
|
+
function createNotebookLmPythonClient(options) {
|
|
887
|
+
const workspaceRoot = options.workspaceRoot;
|
|
888
|
+
return {
|
|
889
|
+
async createNotebook(input) {
|
|
890
|
+
return runBridge(
|
|
891
|
+
options,
|
|
892
|
+
"createNotebook",
|
|
893
|
+
input
|
|
894
|
+
);
|
|
895
|
+
},
|
|
896
|
+
async ingestSource(input) {
|
|
897
|
+
const filePath = workspaceRoot ? resolveInsideWorkspace(workspaceRoot, input.report.localPath) : input.report.localPath;
|
|
898
|
+
return runBridge(options, "ingestSource", {
|
|
899
|
+
notebookId: input.notebookId,
|
|
900
|
+
reportId: input.report.reportId,
|
|
901
|
+
report: input.report,
|
|
902
|
+
filePath
|
|
903
|
+
});
|
|
904
|
+
},
|
|
905
|
+
async extractFacts(input) {
|
|
906
|
+
return runBridge(options, "extractFacts", input);
|
|
907
|
+
}
|
|
908
|
+
};
|
|
909
|
+
}
|
|
910
|
+
|
|
735
911
|
// src/local-api/server.ts
|
|
736
912
|
import { createServer } from "http";
|
|
737
913
|
import { readFile as readFile3, realpath, stat } from "fs/promises";
|
|
738
914
|
import path5 from "path";
|
|
739
|
-
import { execa as
|
|
915
|
+
import { execa as execa4 } from "execa";
|
|
740
916
|
import {
|
|
741
917
|
readCoverageContractBundle,
|
|
742
|
-
resolveInsideWorkspace as
|
|
918
|
+
resolveInsideWorkspace as resolveInsideWorkspace3,
|
|
743
919
|
scanCompanyManifest
|
|
744
920
|
} from "@xdsjs/dossierx-workspace";
|
|
745
921
|
|
|
@@ -747,7 +923,7 @@ import {
|
|
|
747
923
|
import { randomUUID } from "crypto";
|
|
748
924
|
import { appendFile, mkdir as mkdir2, readFile as readFile2 } from "fs/promises";
|
|
749
925
|
import path4 from "path";
|
|
750
|
-
import { resolveInsideWorkspace } from "@xdsjs/dossierx-workspace";
|
|
926
|
+
import { resolveInsideWorkspace as resolveInsideWorkspace2 } from "@xdsjs/dossierx-workspace";
|
|
751
927
|
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;
|
|
752
928
|
function assertTaskId(taskId) {
|
|
753
929
|
if (!TASK_ID_PATTERN.test(taskId)) {
|
|
@@ -756,7 +932,7 @@ function assertTaskId(taskId) {
|
|
|
756
932
|
}
|
|
757
933
|
function taskDirectory(workspaceRoot, taskId) {
|
|
758
934
|
assertTaskId(taskId);
|
|
759
|
-
return
|
|
935
|
+
return resolveInsideWorkspace2(
|
|
760
936
|
workspaceRoot,
|
|
761
937
|
path4.posix.join(".dossierx", "tasks", taskId)
|
|
762
938
|
);
|
|
@@ -820,7 +996,7 @@ function createTaskArchive(options) {
|
|
|
820
996
|
|
|
821
997
|
// src/version.ts
|
|
822
998
|
var DAEMON_PACKAGE_NAME = "@xdsjs/dossierx-daemon";
|
|
823
|
-
var DAEMON_VERSION = "0.1.
|
|
999
|
+
var DAEMON_VERSION = "0.1.8";
|
|
824
1000
|
|
|
825
1001
|
// src/local-api/server.ts
|
|
826
1002
|
var DEFAULT_MAX_FILE_BYTES = 5 * 1024 * 1024;
|
|
@@ -851,7 +1027,7 @@ async function readWorkspaceFile(options) {
|
|
|
851
1027
|
if (!ALLOWED_EXTENSIONS.has(extension)) {
|
|
852
1028
|
throw new Error("Only markdown, text, and json files can be previewed");
|
|
853
1029
|
}
|
|
854
|
-
const absolutePath =
|
|
1030
|
+
const absolutePath = resolveInsideWorkspace3(
|
|
855
1031
|
options.workspaceRoot,
|
|
856
1032
|
options.relativePath
|
|
857
1033
|
);
|
|
@@ -902,7 +1078,7 @@ async function resolveCommand(command) {
|
|
|
902
1078
|
if (path5.isAbsolute(normalizedCommand)) {
|
|
903
1079
|
return realpath(normalizedCommand).catch(() => normalizedCommand);
|
|
904
1080
|
}
|
|
905
|
-
const result = await
|
|
1081
|
+
const result = await execa4("which", [normalizedCommand], {
|
|
906
1082
|
stdin: "ignore",
|
|
907
1083
|
reject: false,
|
|
908
1084
|
timeout: 3e3
|
|
@@ -919,7 +1095,7 @@ async function detectCodexCommand(probe) {
|
|
|
919
1095
|
return null;
|
|
920
1096
|
}
|
|
921
1097
|
try {
|
|
922
|
-
const result = await
|
|
1098
|
+
const result = await execa4(command, ["--version"], {
|
|
923
1099
|
stdin: "ignore",
|
|
924
1100
|
timeout: 5e3,
|
|
925
1101
|
reject: false
|
|
@@ -1016,7 +1192,7 @@ function isNewerVersion(candidate, current) {
|
|
|
1016
1192
|
return false;
|
|
1017
1193
|
}
|
|
1018
1194
|
async function defaultLatestDaemonVersion(packageName) {
|
|
1019
|
-
const result = await
|
|
1195
|
+
const result = await execa4("npm", ["view", packageName, "version"], {
|
|
1020
1196
|
stdin: "ignore",
|
|
1021
1197
|
timeout: 8e3,
|
|
1022
1198
|
reject: false
|
|
@@ -1028,11 +1204,11 @@ async function defaultLatestDaemonVersion(packageName) {
|
|
|
1028
1204
|
}
|
|
1029
1205
|
async function defaultUpdateDaemonPackage(input) {
|
|
1030
1206
|
const customCommand = process.env.DOSSIERX_DAEMON_UPDATE_COMMAND?.trim();
|
|
1031
|
-
const result = customCommand ? await
|
|
1207
|
+
const result = customCommand ? await execa4("/bin/zsh", ["-lc", customCommand], {
|
|
1032
1208
|
stdin: "ignore",
|
|
1033
1209
|
timeout: 12e4,
|
|
1034
1210
|
reject: false
|
|
1035
|
-
}) : await
|
|
1211
|
+
}) : await execa4("npm", ["install", "-g", `${input.packageName}@latest`], {
|
|
1036
1212
|
stdin: "ignore",
|
|
1037
1213
|
timeout: 12e4,
|
|
1038
1214
|
reject: false
|
|
@@ -1295,7 +1471,7 @@ import {
|
|
|
1295
1471
|
buildCompanyManifest,
|
|
1296
1472
|
companyManifestPath,
|
|
1297
1473
|
investWikiRoot,
|
|
1298
|
-
resolveInsideWorkspace as
|
|
1474
|
+
resolveInsideWorkspace as resolveInsideWorkspace4
|
|
1299
1475
|
} from "@xdsjs/dossierx-workspace";
|
|
1300
1476
|
function isWorkspaceGuardError(error) {
|
|
1301
1477
|
if (!(error instanceof Error)) {
|
|
@@ -1309,7 +1485,7 @@ function isWorkspaceGuardError(error) {
|
|
|
1309
1485
|
}
|
|
1310
1486
|
function workspacePath(workspaceRoot, relativePath, step) {
|
|
1311
1487
|
try {
|
|
1312
|
-
return
|
|
1488
|
+
return resolveInsideWorkspace4(workspaceRoot, relativePath);
|
|
1313
1489
|
} catch (error) {
|
|
1314
1490
|
if (isWorkspaceGuardError(error)) {
|
|
1315
1491
|
throw new CodexRuntimeError(
|
|
@@ -1417,7 +1593,7 @@ async function appendOutputEvent(context, message, output) {
|
|
|
1417
1593
|
});
|
|
1418
1594
|
}
|
|
1419
1595
|
async function directoryHasFiles(root, relativePath) {
|
|
1420
|
-
const directory =
|
|
1596
|
+
const directory = resolveInsideWorkspace4(root, relativePath);
|
|
1421
1597
|
let entries;
|
|
1422
1598
|
try {
|
|
1423
1599
|
entries = await readdir(directory, { withFileTypes: true });
|
|
@@ -1513,7 +1689,7 @@ import {
|
|
|
1513
1689
|
buildCompanyManifest as buildCompanyManifest2,
|
|
1514
1690
|
companyManifestPath as companyManifestPath2,
|
|
1515
1691
|
financialReportsIndexPath,
|
|
1516
|
-
resolveInsideWorkspace as
|
|
1692
|
+
resolveInsideWorkspace as resolveInsideWorkspace5
|
|
1517
1693
|
} from "@xdsjs/dossierx-workspace";
|
|
1518
1694
|
var FinancialReportsRuntimeError = class extends Error {
|
|
1519
1695
|
code;
|
|
@@ -1563,7 +1739,7 @@ function writeWorkspaceJson(context, relativePath, value) {
|
|
|
1563
1739
|
);
|
|
1564
1740
|
}
|
|
1565
1741
|
async function writeWorkspaceBytes(context, relativePath, bytes) {
|
|
1566
|
-
const absolutePath =
|
|
1742
|
+
const absolutePath = resolveInsideWorkspace5(context.workspaceRoot, relativePath);
|
|
1567
1743
|
await mkdir3(path6.dirname(absolutePath), { recursive: true });
|
|
1568
1744
|
if (!context.dryRun) {
|
|
1569
1745
|
await writeFile2(absolutePath, bytes);
|
|
@@ -1577,7 +1753,7 @@ function createWorkspaceStorage(context) {
|
|
|
1577
1753
|
};
|
|
1578
1754
|
}
|
|
1579
1755
|
function readWorkspaceJson(context, relativePath) {
|
|
1580
|
-
const absolutePath =
|
|
1756
|
+
const absolutePath = resolveInsideWorkspace5(context.workspaceRoot, relativePath);
|
|
1581
1757
|
return readFile4(absolutePath, "utf8").then((content) => JSON.parse(content));
|
|
1582
1758
|
}
|
|
1583
1759
|
function parseReportManifest(payload) {
|
|
@@ -1841,7 +2017,7 @@ import {
|
|
|
1841
2017
|
companyManifestPath as companyManifestPath3,
|
|
1842
2018
|
investWikiConfigPath,
|
|
1843
2019
|
investWikiRoot as investWikiRoot2,
|
|
1844
|
-
resolveInsideWorkspace as
|
|
2020
|
+
resolveInsideWorkspace as resolveInsideWorkspace6
|
|
1845
2021
|
} from "@xdsjs/dossierx-workspace";
|
|
1846
2022
|
async function exists(absolutePath) {
|
|
1847
2023
|
try {
|
|
@@ -1866,7 +2042,7 @@ function isWorkspaceGuardError2(error) {
|
|
|
1866
2042
|
}
|
|
1867
2043
|
function workspacePath2(workspaceRoot, relativePath, step) {
|
|
1868
2044
|
try {
|
|
1869
|
-
return
|
|
2045
|
+
return resolveInsideWorkspace6(workspaceRoot, relativePath);
|
|
1870
2046
|
} catch (error) {
|
|
1871
2047
|
if (isWorkspaceGuardError2(error)) {
|
|
1872
2048
|
throw new InvestWikiRuntimeError(
|
|
@@ -2109,7 +2285,7 @@ import {
|
|
|
2109
2285
|
buildCompanyManifest as buildCompanyManifest4,
|
|
2110
2286
|
companyManifestPath as companyManifestPath4,
|
|
2111
2287
|
companyRoot,
|
|
2112
|
-
resolveInsideWorkspace as
|
|
2288
|
+
resolveInsideWorkspace as resolveInsideWorkspace7,
|
|
2113
2289
|
rightBusinessPath,
|
|
2114
2290
|
rightPeoplePath,
|
|
2115
2291
|
rightPricePath
|
|
@@ -2143,7 +2319,7 @@ var rightPrice = (ticker) => `# Right Price - ${ticker}
|
|
|
2143
2319
|
This is a placeholder right-price analysis for ${ticker}.
|
|
2144
2320
|
`;
|
|
2145
2321
|
async function writeWorkspaceFile(context, relativePath, content) {
|
|
2146
|
-
const absolutePath =
|
|
2322
|
+
const absolutePath = resolveInsideWorkspace7(context.workspaceRoot, relativePath);
|
|
2147
2323
|
await mkdir5(path8.dirname(absolutePath), { recursive: true });
|
|
2148
2324
|
if (!context.dryRun) {
|
|
2149
2325
|
await writeFile4(absolutePath, content);
|
|
@@ -2161,7 +2337,7 @@ async function runMockWriteCompanyReport(task, context) {
|
|
|
2161
2337
|
message: "Creating company directory",
|
|
2162
2338
|
data: { ticker }
|
|
2163
2339
|
});
|
|
2164
|
-
await mkdir5(
|
|
2340
|
+
await mkdir5(resolveInsideWorkspace7(context.workspaceRoot, companyRoot(ticker)), {
|
|
2165
2341
|
recursive: true
|
|
2166
2342
|
});
|
|
2167
2343
|
await context.appendEvent({
|
|
@@ -2465,10 +2641,10 @@ function createLogger(level = "info", stream) {
|
|
|
2465
2641
|
}
|
|
2466
2642
|
|
|
2467
2643
|
// src/runtime/detect.ts
|
|
2468
|
-
import { execa as
|
|
2644
|
+
import { execa as execa5 } from "execa";
|
|
2469
2645
|
async function commandResponds(command, args = ["--version"]) {
|
|
2470
2646
|
try {
|
|
2471
|
-
await
|
|
2647
|
+
await execa5(command, args, {
|
|
2472
2648
|
reject: true,
|
|
2473
2649
|
timeout: 2e3,
|
|
2474
2650
|
stdout: "ignore",
|
|
@@ -2479,21 +2655,22 @@ async function commandResponds(command, args = ["--version"]) {
|
|
|
2479
2655
|
return false;
|
|
2480
2656
|
}
|
|
2481
2657
|
}
|
|
2482
|
-
async function detectCapabilities() {
|
|
2483
|
-
const [git, python3, python, investWikiRuntime, codex, claude] = await Promise.all([
|
|
2658
|
+
async function detectCapabilities(options = {}) {
|
|
2659
|
+
const [git, python3, python, investWikiRuntime, codex, claude, notebookLm] = await Promise.all([
|
|
2484
2660
|
commandResponds("git"),
|
|
2485
2661
|
commandResponds("python3"),
|
|
2486
2662
|
commandResponds("python"),
|
|
2487
2663
|
commandResponds("invest-wiki-runtime"),
|
|
2488
2664
|
commandResponds("codex"),
|
|
2489
|
-
commandResponds("claude")
|
|
2665
|
+
commandResponds("claude"),
|
|
2666
|
+
probeNotebookLmPythonClient(options.notebookLm)
|
|
2490
2667
|
]);
|
|
2491
2668
|
return {
|
|
2492
2669
|
git,
|
|
2493
2670
|
node: true,
|
|
2494
2671
|
python: python3 || python,
|
|
2495
2672
|
financialReports: true,
|
|
2496
|
-
financialReportsNotebookLm:
|
|
2673
|
+
financialReportsNotebookLm: notebookLm,
|
|
2497
2674
|
financialReportsSecHtmlRenderer: true,
|
|
2498
2675
|
investWikiRuntime,
|
|
2499
2676
|
codex,
|
|
@@ -2654,6 +2831,10 @@ function runtimeOptionsFrom(input) {
|
|
|
2654
2831
|
gitMirrorRemote: input.gitMirrorRemote,
|
|
2655
2832
|
gitMirrorBranch: input.gitMirrorBranch,
|
|
2656
2833
|
gitCommand: input.gitCommand,
|
|
2834
|
+
notebookLmPythonCommand: input.notebookLmPythonCommand,
|
|
2835
|
+
notebookLmProfile: input.notebookLmProfile,
|
|
2836
|
+
notebookLmHome: input.notebookLmHome,
|
|
2837
|
+
notebookLmStoragePath: input.notebookLmStoragePath,
|
|
2657
2838
|
localApiPort: input.localApiPort
|
|
2658
2839
|
};
|
|
2659
2840
|
}
|
|
@@ -2783,11 +2964,17 @@ function buildProgram() {
|
|
|
2783
2964
|
).option("--codex-command <command>", "installed Codex CLI command").option("--codex-model <model>", "Codex model override for exec mode").option(
|
|
2784
2965
|
"--codex-sandbox <mode>",
|
|
2785
2966
|
"Codex sandbox mode: workspace-write or danger-full-access"
|
|
2786
|
-
).option("--git-mirror-root <path>", "local Git mirror repository path").option("--git-mirror-remote <url>", "remote Git mirror repository URL").option("--git-mirror-branch <branch>", "Git mirror branch name").option("--git-command <command>", "installed Git command").option(
|
|
2967
|
+
).option("--git-mirror-root <path>", "local Git mirror repository path").option("--git-mirror-remote <url>", "remote Git mirror repository URL").option("--git-mirror-branch <branch>", "Git mirror branch name").option("--git-command <command>", "installed Git command").option(
|
|
2968
|
+
"--notebook-lm-python-command <command>",
|
|
2969
|
+
"Python command used to run notebooklm-py"
|
|
2970
|
+
).option("--notebook-lm-profile <profile>", "notebooklm-py profile name").option("--notebook-lm-home <path>", "NOTEBOOKLM_HOME directory").option(
|
|
2971
|
+
"--notebook-lm-storage-path <path>",
|
|
2972
|
+
"explicit notebooklm-py storage_state.json path"
|
|
2973
|
+
).option("--local-api-port <port>", "local workspace preview API port").option("--no-local-api", "disable local workspace preview API").action(async (options) => {
|
|
2787
2974
|
await runDaemon(options);
|
|
2788
2975
|
});
|
|
2789
2976
|
const service = program.command("service").description("Manage the macOS LaunchAgent for dossierx-daemon");
|
|
2790
|
-
service.command("install").description("Write a macOS LaunchAgent plist for persistent daemon runs").option("--label <label>", "LaunchAgent label").option("--daemon-command <command>", "custom command used by launchd").option("--log-level <level>", "daemon log level", "info").option("--invest-wiki-mode <mode>", "invest wiki runner mode").option("--invest-wiki-local-repo <path>", "local llm-wiki-invest repo path").option("--invest-wiki-command <command>", "installed llm-wiki-invest command").option("--codex-command <command>", "installed Codex CLI command").option("--codex-model <model>", "Codex model override for exec mode").option("--codex-sandbox <mode>", "Codex sandbox mode").option("--git-mirror-root <path>", "local Git mirror repository path").option("--git-mirror-remote <url>", "remote Git mirror repository URL").option("--git-mirror-branch <branch>", "Git mirror branch name").option("--git-command <command>", "installed Git command").option("--local-api-port <port>", "local workspace preview API port").action(async (options) => {
|
|
2977
|
+
service.command("install").description("Write a macOS LaunchAgent plist for persistent daemon runs").option("--label <label>", "LaunchAgent label").option("--daemon-command <command>", "custom command used by launchd").option("--log-level <level>", "daemon log level", "info").option("--invest-wiki-mode <mode>", "invest wiki runner mode").option("--invest-wiki-local-repo <path>", "local llm-wiki-invest repo path").option("--invest-wiki-command <command>", "installed llm-wiki-invest command").option("--codex-command <command>", "installed Codex CLI command").option("--codex-model <model>", "Codex model override for exec mode").option("--codex-sandbox <mode>", "Codex sandbox mode").option("--git-mirror-root <path>", "local Git mirror repository path").option("--git-mirror-remote <url>", "remote Git mirror repository URL").option("--git-mirror-branch <branch>", "Git mirror branch name").option("--git-command <command>", "installed Git command").option("--notebook-lm-python-command <command>", "Python command used to run notebooklm-py").option("--notebook-lm-profile <profile>", "notebooklm-py profile name").option("--notebook-lm-home <path>", "NOTEBOOKLM_HOME directory").option("--notebook-lm-storage-path <path>", "explicit notebooklm-py storage_state.json path").option("--local-api-port <port>", "local workspace preview API port").action(async (options) => {
|
|
2791
2978
|
const result = await installLaunchAgent({
|
|
2792
2979
|
...options,
|
|
2793
2980
|
localApiPort: parsePort(options.localApiPort)
|
|
@@ -2825,6 +3012,10 @@ async function runDaemon(options) {
|
|
|
2825
3012
|
gitMirrorRemote: options.gitMirrorRemote ?? localConfig?.gitMirrorRemote,
|
|
2826
3013
|
gitMirrorBranch: options.gitMirrorBranch ?? localConfig?.gitMirrorBranch,
|
|
2827
3014
|
gitCommand: options.gitCommand ?? localConfig?.gitCommand,
|
|
3015
|
+
notebookLmPythonCommand: options.notebookLmPythonCommand ?? localConfig?.notebookLmPythonCommand ?? process.env.DOSSIERX_NOTEBOOKLM_PYTHON_COMMAND,
|
|
3016
|
+
notebookLmProfile: options.notebookLmProfile ?? localConfig?.notebookLmProfile ?? process.env.DOSSIERX_NOTEBOOKLM_PROFILE,
|
|
3017
|
+
notebookLmHome: options.notebookLmHome ?? localConfig?.notebookLmHome ?? process.env.NOTEBOOKLM_HOME,
|
|
3018
|
+
notebookLmStoragePath: options.notebookLmStoragePath ?? localConfig?.notebookLmStoragePath ?? process.env.DOSSIERX_NOTEBOOKLM_STORAGE_PATH,
|
|
2828
3019
|
localApiPort: parsePort(options.localApiPort) ?? localConfig?.localApiPort ?? parsePort(process.env.DOSSIERX_LOCAL_API_PORT) ?? DOSSIERX_DEFAULT_LOCAL_API_PORT
|
|
2829
3020
|
};
|
|
2830
3021
|
if (!serverUrl || !supabaseUrl || !supabaseAnonKey || !machineKey) {
|
|
@@ -2834,10 +3025,22 @@ async function runDaemon(options) {
|
|
|
2834
3025
|
}
|
|
2835
3026
|
const workspaceRoot = path10.resolve(expandHomePath(workspacePath3));
|
|
2836
3027
|
await ensureWorkspaceDirectory(workspaceRoot);
|
|
2837
|
-
const
|
|
3028
|
+
const notebookLmOptions = {
|
|
3029
|
+
pythonCommand: runtimeOptions.notebookLmPythonCommand,
|
|
3030
|
+
profile: runtimeOptions.notebookLmProfile,
|
|
3031
|
+
home: runtimeOptions.notebookLmHome,
|
|
3032
|
+
storagePath: runtimeOptions.notebookLmStoragePath
|
|
3033
|
+
};
|
|
3034
|
+
const capabilities = await detectCapabilities({
|
|
3035
|
+
notebookLm: notebookLmOptions
|
|
3036
|
+
});
|
|
2838
3037
|
const investWiki = createInvestWikiRunnerFromOptions(runtimeOptions);
|
|
2839
3038
|
const codex = createCodexRunnerFromOptions(runtimeOptions);
|
|
2840
3039
|
const gitMirror = createGitMirrorFromOptions(runtimeOptions);
|
|
3040
|
+
const notebookLmClient = capabilities.financialReportsNotebookLm ? createNotebookLmPythonClient({
|
|
3041
|
+
...notebookLmOptions,
|
|
3042
|
+
workspaceRoot
|
|
3043
|
+
}) : void 0;
|
|
2841
3044
|
const taskArchive = createTaskArchive({ workspaceRoot });
|
|
2842
3045
|
const api = new ApiClient({
|
|
2843
3046
|
serverUrl,
|
|
@@ -2867,6 +3070,10 @@ async function runDaemon(options) {
|
|
|
2867
3070
|
gitMirrorRemote: runtimeOptions.gitMirrorRemote,
|
|
2868
3071
|
gitMirrorBranch: runtimeOptions.gitMirrorBranch,
|
|
2869
3072
|
gitCommand: runtimeOptions.gitCommand,
|
|
3073
|
+
notebookLmPythonCommand: runtimeOptions.notebookLmPythonCommand,
|
|
3074
|
+
notebookLmProfile: runtimeOptions.notebookLmProfile,
|
|
3075
|
+
notebookLmHome: runtimeOptions.notebookLmHome,
|
|
3076
|
+
notebookLmStoragePath: runtimeOptions.notebookLmStoragePath,
|
|
2870
3077
|
localApiPort: runtimeOptions.localApiPort
|
|
2871
3078
|
});
|
|
2872
3079
|
const state = { running: false, pending: false };
|
|
@@ -2881,7 +3088,10 @@ async function runDaemon(options) {
|
|
|
2881
3088
|
codexOptions: runtimeOptions,
|
|
2882
3089
|
investWiki,
|
|
2883
3090
|
gitMirror,
|
|
2884
|
-
taskArchive
|
|
3091
|
+
taskArchive,
|
|
3092
|
+
financialReports: {
|
|
3093
|
+
notebookLmClient
|
|
3094
|
+
}
|
|
2885
3095
|
};
|
|
2886
3096
|
async function heartbeat(status) {
|
|
2887
3097
|
await api.heartbeat({
|
package/package.json
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@xdsjs/dossierx-daemon",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.8",
|
|
4
4
|
"type": "module",
|
|
5
|
-
"main": "./
|
|
6
|
-
"types": "./
|
|
5
|
+
"main": "./src/index.ts",
|
|
6
|
+
"types": "./src/index.ts",
|
|
7
7
|
"exports": {
|
|
8
8
|
".": {
|
|
9
|
-
"types": "./
|
|
10
|
-
"import": "./
|
|
9
|
+
"types": "./src/index.ts",
|
|
10
|
+
"import": "./src/index.ts"
|
|
11
11
|
}
|
|
12
12
|
},
|
|
13
13
|
"bin": {
|
|
@@ -17,21 +17,36 @@
|
|
|
17
17
|
"dist"
|
|
18
18
|
],
|
|
19
19
|
"publishConfig": {
|
|
20
|
-
"access": "public"
|
|
20
|
+
"access": "public",
|
|
21
|
+
"main": "./dist/index.js",
|
|
22
|
+
"types": "./dist/index.d.ts",
|
|
23
|
+
"exports": {
|
|
24
|
+
".": {
|
|
25
|
+
"types": "./dist/index.d.ts",
|
|
26
|
+
"import": "./dist/index.js"
|
|
27
|
+
}
|
|
28
|
+
}
|
|
21
29
|
},
|
|
22
30
|
"engines": {
|
|
23
31
|
"node": ">=20"
|
|
24
32
|
},
|
|
33
|
+
"scripts": {
|
|
34
|
+
"dev": "tsx src/index.ts",
|
|
35
|
+
"build": "tsup src/index.ts --format esm --dts --out-dir dist",
|
|
36
|
+
"typecheck": "tsc --noEmit",
|
|
37
|
+
"test": "vitest run",
|
|
38
|
+
"lint": "tsc --noEmit"
|
|
39
|
+
},
|
|
25
40
|
"dependencies": {
|
|
26
41
|
"@supabase/supabase-js": "^2.0.0",
|
|
42
|
+
"@xdsjs/dossier-financial-reports": "workspace:^",
|
|
43
|
+
"@xdsjs/dossierx-git-mirror": "workspace:^",
|
|
44
|
+
"@xdsjs/dossierx-shared": "workspace:^",
|
|
45
|
+
"@xdsjs/dossierx-workspace": "workspace:^",
|
|
27
46
|
"commander": "^14.0.0",
|
|
28
47
|
"execa": "^9.0.0",
|
|
29
48
|
"pino": "^10.0.0",
|
|
30
|
-
"zod": "^4.0.0"
|
|
31
|
-
"@xdsjs/dossier-financial-reports": "^0.1.2",
|
|
32
|
-
"@xdsjs/dossierx-git-mirror": "^0.1.2",
|
|
33
|
-
"@xdsjs/dossierx-shared": "^0.1.3",
|
|
34
|
-
"@xdsjs/dossierx-workspace": "^0.1.1"
|
|
49
|
+
"zod": "^4.0.0"
|
|
35
50
|
},
|
|
36
51
|
"devDependencies": {
|
|
37
52
|
"@types/node": "^24.0.0",
|
|
@@ -39,12 +54,5 @@
|
|
|
39
54
|
"tsup": "^8.0.0",
|
|
40
55
|
"typescript": "^5.0.0",
|
|
41
56
|
"vitest": "^3.0.0"
|
|
42
|
-
},
|
|
43
|
-
"scripts": {
|
|
44
|
-
"dev": "tsx src/index.ts",
|
|
45
|
-
"build": "tsup src/index.ts --format esm --dts --out-dir dist",
|
|
46
|
-
"typecheck": "tsc --noEmit",
|
|
47
|
-
"test": "vitest run",
|
|
48
|
-
"lint": "tsc --noEmit"
|
|
49
57
|
}
|
|
50
|
-
}
|
|
58
|
+
}
|