gnosys 5.11.3 → 5.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +332 -5151
- package/dist/index.js +364 -235
- package/dist/lib/addCommand.d.ts +9 -0
- package/dist/lib/addCommand.js +103 -0
- package/dist/lib/addStructuredCommand.d.ts +16 -0
- package/dist/lib/addStructuredCommand.js +103 -0
- package/dist/lib/ambiguityCommand.d.ts +4 -0
- package/dist/lib/ambiguityCommand.js +36 -0
- package/dist/lib/apiKeyVault.d.ts +78 -0
- package/dist/lib/apiKeyVault.js +447 -0
- package/dist/lib/askCommand.d.ts +13 -0
- package/dist/lib/askCommand.js +145 -0
- package/dist/lib/audioExtract.js +4 -1
- package/dist/lib/auditCommand.d.ts +7 -0
- package/dist/lib/auditCommand.js +27 -0
- package/dist/lib/backupCommand.d.ts +6 -0
- package/dist/lib/backupCommand.js +54 -0
- package/dist/lib/bootstrapCommand.d.ts +15 -0
- package/dist/lib/bootstrapCommand.js +51 -0
- package/dist/lib/briefingCommand.d.ts +7 -0
- package/dist/lib/briefingCommand.js +92 -0
- package/dist/lib/centralizeCommand.d.ts +5 -0
- package/dist/lib/centralizeCommand.js +16 -0
- package/dist/lib/chatCommand.d.ts +12 -0
- package/dist/lib/chatCommand.js +46 -0
- package/dist/lib/checkCommand.d.ts +4 -0
- package/dist/lib/checkCommand.js +133 -0
- package/dist/lib/clientReadOverlay.d.ts +27 -0
- package/dist/lib/clientReadOverlay.js +73 -0
- package/dist/lib/clientReadResolve.d.ts +32 -0
- package/dist/lib/clientReadResolve.js +84 -0
- package/dist/lib/commitContextCommand.d.ts +9 -0
- package/dist/lib/commitContextCommand.js +142 -0
- package/dist/lib/config.d.ts +43 -3
- package/dist/lib/config.js +58 -57
- package/dist/lib/configCommand.d.ts +10 -0
- package/dist/lib/configCommand.js +321 -0
- package/dist/lib/connectCommand.d.ts +8 -0
- package/dist/lib/connectCommand.js +19 -0
- package/dist/lib/db.d.ts +52 -0
- package/dist/lib/db.js +169 -1
- package/dist/lib/dearchiveCommand.d.ts +7 -0
- package/dist/lib/dearchiveCommand.js +41 -0
- package/dist/lib/discoverCommand.d.ts +9 -0
- package/dist/lib/discoverCommand.js +87 -0
- package/dist/lib/doctorCommand.d.ts +6 -0
- package/dist/lib/doctorCommand.js +256 -0
- package/dist/lib/dream.d.ts +42 -2
- package/dist/lib/dream.js +290 -30
- package/dist/lib/dreamCommand.d.ts +10 -0
- package/dist/lib/dreamCommand.js +195 -0
- package/dist/lib/dreamLaunchd.d.ts +2 -0
- package/dist/lib/dreamLaunchd.js +72 -0
- package/dist/lib/dreamLogCommand.d.ts +10 -0
- package/dist/lib/dreamLogCommand.js +58 -0
- package/dist/lib/dreamReport.d.ts +7 -0
- package/dist/lib/dreamReport.js +114 -0
- package/dist/lib/dreamRunLog.d.ts +121 -0
- package/dist/lib/dreamRunLog.js +212 -0
- package/dist/lib/embeddings.js +3 -0
- package/dist/lib/exportCommand.d.ts +18 -0
- package/dist/lib/exportCommand.js +101 -0
- package/dist/lib/fsearchCommand.d.ts +8 -0
- package/dist/lib/fsearchCommand.js +44 -0
- package/dist/lib/graphCommand.d.ts +4 -0
- package/dist/lib/graphCommand.js +68 -0
- package/dist/lib/helperGenerateCommand.d.ts +5 -0
- package/dist/lib/helperGenerateCommand.js +27 -0
- package/dist/lib/historyCommand.d.ts +5 -0
- package/dist/lib/historyCommand.js +51 -0
- package/dist/lib/hybridSearchCommand.d.ts +12 -0
- package/dist/lib/hybridSearchCommand.js +95 -0
- package/dist/lib/ideMcpInstall.d.ts +30 -0
- package/dist/lib/ideMcpInstall.js +102 -0
- package/dist/lib/importCommand.d.ts +16 -0
- package/dist/lib/importCommand.js +89 -0
- package/dist/lib/importProjectCommand.d.ts +6 -0
- package/dist/lib/importProjectCommand.js +43 -0
- package/dist/lib/ingestCommand.d.ts +13 -0
- package/dist/lib/ingestCommand.js +95 -0
- package/dist/lib/installOutput.d.ts +36 -0
- package/dist/lib/installOutput.js +55 -0
- package/dist/lib/lensCommand.d.ts +20 -0
- package/dist/lib/lensCommand.js +61 -0
- package/dist/lib/lensing.d.ts +1 -0
- package/dist/lib/lensing.js +50 -9
- package/dist/lib/linksCommand.d.ts +7 -0
- package/dist/lib/linksCommand.js +48 -0
- package/dist/lib/listCommand.d.ts +8 -0
- package/dist/lib/listCommand.js +74 -0
- package/dist/lib/llm.d.ts +1 -1
- package/dist/lib/llm.js +26 -8
- package/dist/lib/localDiskCheck.d.ts +17 -0
- package/dist/lib/localDiskCheck.js +54 -0
- package/dist/lib/machineConfig.d.ts +11 -1
- package/dist/lib/machineConfig.js +16 -0
- package/dist/lib/machineRegistry.d.ts +61 -0
- package/dist/lib/machineRegistry.js +80 -0
- package/dist/lib/maintainCommand.d.ts +8 -0
- package/dist/lib/maintainCommand.js +34 -0
- package/dist/lib/masterLease.d.ts +20 -0
- package/dist/lib/masterLease.js +68 -0
- package/dist/lib/migrateCommand.d.ts +7 -0
- package/dist/lib/migrateCommand.js +158 -0
- package/dist/lib/migrateDbCommand.d.ts +9 -0
- package/dist/lib/migrateDbCommand.js +94 -0
- package/dist/lib/modelValidation.d.ts +5 -0
- package/dist/lib/modelValidation.js +27 -0
- package/dist/lib/openrouterTiers.d.ts +29 -0
- package/dist/lib/openrouterTiers.js +113 -0
- package/dist/lib/prefCommand.d.ts +10 -0
- package/dist/lib/prefCommand.js +118 -0
- package/dist/lib/projectsCommand.d.ts +8 -0
- package/dist/lib/projectsCommand.js +131 -0
- package/dist/lib/readCommand.d.ts +7 -0
- package/dist/lib/readCommand.js +62 -0
- package/dist/lib/recall.d.ts +3 -0
- package/dist/lib/recall.js +19 -4
- package/dist/lib/recallCommand.d.ts +11 -0
- package/dist/lib/recallCommand.js +112 -0
- package/dist/lib/reflectCommand.d.ts +8 -0
- package/dist/lib/reflectCommand.js +61 -0
- package/dist/lib/reindexCommand.d.ts +4 -0
- package/dist/lib/reindexCommand.js +34 -0
- package/dist/lib/reindexGraphCommand.d.ts +4 -0
- package/dist/lib/reindexGraphCommand.js +12 -0
- package/dist/lib/reinforceCommand.d.ts +8 -0
- package/dist/lib/reinforceCommand.js +40 -0
- package/dist/lib/remote.d.ts +5 -1
- package/dist/lib/remote.js +5 -1
- package/dist/lib/remoteWizard.d.ts +24 -5
- package/dist/lib/remoteWizard.js +308 -319
- package/dist/lib/restoreCommand.d.ts +5 -0
- package/dist/lib/restoreCommand.js +35 -0
- package/dist/lib/sandboxStartCommand.d.ts +6 -0
- package/dist/lib/sandboxStartCommand.js +25 -0
- package/dist/lib/sandboxStatusCommand.d.ts +4 -0
- package/dist/lib/sandboxStatusCommand.js +24 -0
- package/dist/lib/sandboxStopCommand.d.ts +4 -0
- package/dist/lib/sandboxStopCommand.js +21 -0
- package/dist/lib/searchCommand.d.ts +9 -0
- package/dist/lib/searchCommand.js +90 -0
- package/dist/lib/semanticSearchCommand.d.ts +8 -0
- package/dist/lib/semanticSearchCommand.js +52 -0
- package/dist/lib/setup/configSetRender.js +2 -0
- package/dist/lib/setup/providerGlyphs.d.ts +19 -0
- package/dist/lib/setup/providerGlyphs.js +42 -0
- package/dist/lib/setup/remoteRender.d.ts +31 -1
- package/dist/lib/setup/remoteRender.js +95 -4
- package/dist/lib/setup/sections/ides.d.ts +7 -0
- package/dist/lib/setup/sections/ides.js +24 -2
- package/dist/lib/setup/sections/providers.d.ts +17 -0
- package/dist/lib/setup/sections/providers.js +255 -0
- package/dist/lib/setup/sections/routing.d.ts +2 -6
- package/dist/lib/setup/sections/routing.js +33 -85
- package/dist/lib/setup/sections/taskRoutingEditor.d.ts +17 -0
- package/dist/lib/setup/sections/taskRoutingEditor.js +149 -0
- package/dist/lib/setup/summary.d.ts +9 -0
- package/dist/lib/setup/summary.js +51 -37
- package/dist/lib/setup/ui/status.d.ts +1 -0
- package/dist/lib/setup/ui/status.js +2 -0
- package/dist/lib/setup.d.ts +108 -3
- package/dist/lib/setup.js +813 -303
- package/dist/lib/setupKeys.d.ts +42 -0
- package/dist/lib/setupKeys.js +564 -0
- package/dist/lib/setupRemoteCommand.d.ts +4 -0
- package/dist/lib/setupRemoteCommand.js +28 -0
- package/dist/lib/setupRemotePullCommand.d.ts +5 -0
- package/dist/lib/setupRemotePullCommand.js +52 -0
- package/dist/lib/setupRemotePushCommand.d.ts +5 -0
- package/dist/lib/setupRemotePushCommand.js +57 -0
- package/dist/lib/setupRemoteResolveCommand.d.ts +4 -0
- package/dist/lib/setupRemoteResolveCommand.js +48 -0
- package/dist/lib/setupRemoteStatusCommand.d.ts +4 -0
- package/dist/lib/setupRemoteStatusCommand.js +73 -0
- package/dist/lib/setupRemoteSyncCommand.d.ts +6 -0
- package/dist/lib/setupRemoteSyncCommand.js +65 -0
- package/dist/lib/setupSyncProjectsCommand.d.ts +4 -0
- package/dist/lib/setupSyncProjectsCommand.js +292 -0
- package/dist/lib/staleCommand.d.ts +8 -0
- package/dist/lib/staleCommand.js +34 -0
- package/dist/lib/statsCommand.d.ts +6 -0
- package/dist/lib/statsCommand.js +142 -0
- package/dist/lib/statusCommand.d.ts +18 -0
- package/dist/lib/statusCommand.js +250 -0
- package/dist/lib/storesCommand.d.ts +2 -0
- package/dist/lib/storesCommand.js +4 -0
- package/dist/lib/syncClient.d.ts +47 -0
- package/dist/lib/syncClient.js +212 -0
- package/dist/lib/syncCommand.d.ts +6 -0
- package/dist/lib/syncCommand.js +57 -0
- package/dist/lib/syncDoctorCommand.d.ts +5 -0
- package/dist/lib/syncDoctorCommand.js +100 -0
- package/dist/lib/syncIngest.d.ts +19 -0
- package/dist/lib/syncIngest.js +152 -0
- package/dist/lib/syncIngestLaunchd.d.ts +8 -0
- package/dist/lib/syncIngestLaunchd.js +93 -0
- package/dist/lib/syncIngestStartup.d.ts +5 -0
- package/dist/lib/syncIngestStartup.js +29 -0
- package/dist/lib/syncIngestSystemd.d.ts +10 -0
- package/dist/lib/syncIngestSystemd.js +97 -0
- package/dist/lib/syncIngestTimer.d.ts +8 -0
- package/dist/lib/syncIngestTimer.js +27 -0
- package/dist/lib/syncIngestTimerCommand.d.ts +7 -0
- package/dist/lib/syncIngestTimerCommand.js +83 -0
- package/dist/lib/syncLock.d.ts +6 -0
- package/dist/lib/syncLock.js +74 -0
- package/dist/lib/syncSnapshot.d.ts +30 -0
- package/dist/lib/syncSnapshot.js +184 -0
- package/dist/lib/syncStaging.d.ts +81 -0
- package/dist/lib/syncStaging.js +239 -0
- package/dist/lib/tagsAddCommand.d.ts +8 -0
- package/dist/lib/tagsAddCommand.js +18 -0
- package/dist/lib/tagsCommand.d.ts +4 -0
- package/dist/lib/tagsCommand.js +16 -0
- package/dist/lib/timelineCommand.d.ts +7 -0
- package/dist/lib/timelineCommand.js +49 -0
- package/dist/lib/traceCommand.d.ts +6 -0
- package/dist/lib/traceCommand.js +39 -0
- package/dist/lib/traverseCommand.d.ts +6 -0
- package/dist/lib/traverseCommand.js +58 -0
- package/dist/lib/updateCommand.d.ts +13 -0
- package/dist/lib/updateCommand.js +67 -0
- package/dist/lib/updateStatusCommand.d.ts +5 -0
- package/dist/lib/updateStatusCommand.js +38 -0
- package/dist/lib/webAddCommand.d.ts +8 -0
- package/dist/lib/webAddCommand.js +55 -0
- package/dist/lib/webBuildCommand.d.ts +10 -0
- package/dist/lib/webBuildCommand.js +65 -0
- package/dist/lib/webBuildIndexCommand.d.ts +8 -0
- package/dist/lib/webBuildIndexCommand.js +37 -0
- package/dist/lib/webIngestCommand.d.ts +11 -0
- package/dist/lib/webIngestCommand.js +51 -0
- package/dist/lib/webInitCommand.d.ts +9 -0
- package/dist/lib/webInitCommand.js +167 -0
- package/dist/lib/webRemoveCommand.d.ts +5 -0
- package/dist/lib/webRemoveCommand.js +41 -0
- package/dist/lib/webStatusCommand.d.ts +5 -0
- package/dist/lib/webStatusCommand.js +94 -0
- package/dist/lib/webUpdateCommand.d.ts +7 -0
- package/dist/lib/webUpdateCommand.js +72 -0
- package/dist/lib/workingSetCommand.d.ts +6 -0
- package/dist/lib/workingSetCommand.js +37 -0
- package/package.json +2 -1
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import path from "path";
|
|
2
|
+
export async function runWebBuildCommand(getWebStorePath, opts) {
|
|
3
|
+
try {
|
|
4
|
+
const { loadConfig } = await import("./config.js");
|
|
5
|
+
const { ingestSite } = await import("./webIngest.js");
|
|
6
|
+
const { buildIndex, writeIndex } = await import("./webIndex.js");
|
|
7
|
+
const gnosysConfig = await loadConfig(await getWebStorePath());
|
|
8
|
+
const webConfig = gnosysConfig.web;
|
|
9
|
+
if (!webConfig) {
|
|
10
|
+
throw new Error("No web configuration found in gnosys.json. Run 'gnosys web init' first.");
|
|
11
|
+
}
|
|
12
|
+
// Step 1: Ingest
|
|
13
|
+
const ingestResult = await ingestSite({
|
|
14
|
+
source: webConfig.source,
|
|
15
|
+
sitemapUrl: opts.source || webConfig.sitemapUrl,
|
|
16
|
+
contentDir: opts.source || webConfig.contentDir,
|
|
17
|
+
urls: webConfig.urls,
|
|
18
|
+
outputDir: webConfig.outputDir,
|
|
19
|
+
exclude: webConfig.exclude,
|
|
20
|
+
categories: webConfig.categories,
|
|
21
|
+
llmEnrich: opts.llm ? webConfig.llmEnrich : false,
|
|
22
|
+
prune: opts.prune || webConfig.prune,
|
|
23
|
+
concurrency: parseInt(opts.concurrency) || webConfig.concurrency,
|
|
24
|
+
crawlDelayMs: webConfig.crawlDelayMs,
|
|
25
|
+
dryRun: opts.dryRun,
|
|
26
|
+
}, gnosysConfig);
|
|
27
|
+
// Step 2: Build index (skip if dry run)
|
|
28
|
+
let indexStats = { documentCount: 0, tokenCount: 0 };
|
|
29
|
+
if (!opts.dryRun) {
|
|
30
|
+
const index = await buildIndex(webConfig.outputDir);
|
|
31
|
+
const indexPath = path.join(webConfig.outputDir, "gnosys-index.json");
|
|
32
|
+
await writeIndex(index, indexPath);
|
|
33
|
+
indexStats = {
|
|
34
|
+
documentCount: index.documentCount,
|
|
35
|
+
tokenCount: Object.keys(index.invertedIndex).length,
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
if (opts.json) {
|
|
39
|
+
console.log(JSON.stringify({ ...ingestResult, index: indexStats }));
|
|
40
|
+
}
|
|
41
|
+
else {
|
|
42
|
+
console.log(`Web build complete (${ingestResult.duration}ms):`);
|
|
43
|
+
console.log(` Added: ${ingestResult.added.length}`);
|
|
44
|
+
console.log(` Updated: ${ingestResult.updated.length}`);
|
|
45
|
+
console.log(` Unchanged: ${ingestResult.unchanged.length}`);
|
|
46
|
+
console.log(` Removed: ${ingestResult.removed.length}`);
|
|
47
|
+
console.log(` Index: ${indexStats.documentCount} docs, ${indexStats.tokenCount} tokens`);
|
|
48
|
+
if (ingestResult.errors.length > 0) {
|
|
49
|
+
console.log(` Errors: ${ingestResult.errors.length}`);
|
|
50
|
+
for (const e of ingestResult.errors) {
|
|
51
|
+
console.log(` ${e.url}: ${e.error}`);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
catch (err) {
|
|
57
|
+
if (opts.json) {
|
|
58
|
+
console.log(JSON.stringify({ ok: false, error: err instanceof Error ? err.message : String(err) }));
|
|
59
|
+
}
|
|
60
|
+
else {
|
|
61
|
+
console.error(`Web build failed: ${err instanceof Error ? err.message : err}`);
|
|
62
|
+
}
|
|
63
|
+
process.exit(1);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { GetWebStorePath } from "./webInitCommand.js";
|
|
2
|
+
export type WebBuildIndexCommandOptions = {
|
|
3
|
+
input?: string;
|
|
4
|
+
output?: string;
|
|
5
|
+
stopWords: boolean;
|
|
6
|
+
json?: boolean;
|
|
7
|
+
};
|
|
8
|
+
export declare function runWebBuildIndexCommand(getWebStorePath: GetWebStorePath, opts: WebBuildIndexCommandOptions): Promise<void>;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import path from "path";
|
|
2
|
+
export async function runWebBuildIndexCommand(getWebStorePath, opts) {
|
|
3
|
+
try {
|
|
4
|
+
const { loadConfig } = await import("./config.js");
|
|
5
|
+
const { buildIndex, writeIndex } = await import("./webIndex.js");
|
|
6
|
+
const gnosysConfig = await loadConfig(await getWebStorePath());
|
|
7
|
+
const knowledgeDir = opts.input || gnosysConfig.web?.outputDir || "./knowledge";
|
|
8
|
+
const outputPath = opts.output || path.join(knowledgeDir, "gnosys-index.json");
|
|
9
|
+
const index = await buildIndex(knowledgeDir, {
|
|
10
|
+
stopWords: opts.stopWords,
|
|
11
|
+
});
|
|
12
|
+
await writeIndex(index, outputPath);
|
|
13
|
+
if (opts.json) {
|
|
14
|
+
console.log(JSON.stringify({
|
|
15
|
+
ok: true,
|
|
16
|
+
documentCount: index.documentCount,
|
|
17
|
+
tokenCount: Object.keys(index.invertedIndex).length,
|
|
18
|
+
outputPath,
|
|
19
|
+
}));
|
|
20
|
+
}
|
|
21
|
+
else {
|
|
22
|
+
console.log(`Search index built:`);
|
|
23
|
+
console.log(` Documents: ${index.documentCount}`);
|
|
24
|
+
console.log(` Tokens: ${Object.keys(index.invertedIndex).length}`);
|
|
25
|
+
console.log(` Output: ${outputPath}`);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
catch (err) {
|
|
29
|
+
if (opts.json) {
|
|
30
|
+
console.log(JSON.stringify({ ok: false, error: err instanceof Error ? err.message : String(err) }));
|
|
31
|
+
}
|
|
32
|
+
else {
|
|
33
|
+
console.error(`Build index failed: ${err instanceof Error ? err.message : err}`);
|
|
34
|
+
}
|
|
35
|
+
process.exit(1);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { GetWebStorePath } from "./webInitCommand.js";
|
|
2
|
+
export type WebIngestCommandOptions = {
|
|
3
|
+
source?: string;
|
|
4
|
+
prune?: boolean;
|
|
5
|
+
llm: boolean;
|
|
6
|
+
concurrency: string;
|
|
7
|
+
dryRun?: boolean;
|
|
8
|
+
verbose?: boolean;
|
|
9
|
+
json?: boolean;
|
|
10
|
+
};
|
|
11
|
+
export declare function runWebIngestCommand(getWebStorePath: GetWebStorePath, opts: WebIngestCommandOptions): Promise<void>;
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
export async function runWebIngestCommand(getWebStorePath, opts) {
|
|
2
|
+
try {
|
|
3
|
+
const { loadConfig } = await import("./config.js");
|
|
4
|
+
const { ingestSite } = await import("./webIngest.js");
|
|
5
|
+
const gnosysConfig = await loadConfig(await getWebStorePath());
|
|
6
|
+
const webConfig = gnosysConfig.web;
|
|
7
|
+
if (!webConfig) {
|
|
8
|
+
throw new Error("No web configuration found in gnosys.json. Run 'gnosys web init' first.");
|
|
9
|
+
}
|
|
10
|
+
const result = await ingestSite({
|
|
11
|
+
source: webConfig.source,
|
|
12
|
+
sitemapUrl: opts.source || webConfig.sitemapUrl,
|
|
13
|
+
contentDir: opts.source || webConfig.contentDir,
|
|
14
|
+
urls: webConfig.urls,
|
|
15
|
+
outputDir: webConfig.outputDir,
|
|
16
|
+
exclude: webConfig.exclude,
|
|
17
|
+
categories: webConfig.categories,
|
|
18
|
+
llmEnrich: opts.llm ? webConfig.llmEnrich : false,
|
|
19
|
+
prune: opts.prune || webConfig.prune,
|
|
20
|
+
concurrency: parseInt(opts.concurrency) || webConfig.concurrency,
|
|
21
|
+
crawlDelayMs: webConfig.crawlDelayMs,
|
|
22
|
+
dryRun: opts.dryRun,
|
|
23
|
+
verbose: opts.verbose,
|
|
24
|
+
}, gnosysConfig);
|
|
25
|
+
if (opts.json) {
|
|
26
|
+
console.log(JSON.stringify(result, null, 2));
|
|
27
|
+
}
|
|
28
|
+
else {
|
|
29
|
+
console.log(`Ingestion complete (${result.duration}ms):`);
|
|
30
|
+
console.log(` Added: ${result.added.length}`);
|
|
31
|
+
console.log(` Updated: ${result.updated.length}`);
|
|
32
|
+
console.log(` Unchanged: ${result.unchanged.length}`);
|
|
33
|
+
console.log(` Removed: ${result.removed.length}`);
|
|
34
|
+
if (result.errors.length > 0) {
|
|
35
|
+
console.log(` Errors: ${result.errors.length}`);
|
|
36
|
+
for (const e of result.errors) {
|
|
37
|
+
console.log(` ${e.url}: ${e.error}`);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
catch (err) {
|
|
43
|
+
if (opts.json) {
|
|
44
|
+
console.log(JSON.stringify({ ok: false, error: err instanceof Error ? err.message : String(err) }));
|
|
45
|
+
}
|
|
46
|
+
else {
|
|
47
|
+
console.error(`Ingest failed: ${err instanceof Error ? err.message : err}`);
|
|
48
|
+
}
|
|
49
|
+
process.exit(1);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export type WebInitCommandOptions = {
|
|
2
|
+
source: string;
|
|
3
|
+
output: string;
|
|
4
|
+
config: boolean;
|
|
5
|
+
nonInteractive?: boolean;
|
|
6
|
+
json?: boolean;
|
|
7
|
+
};
|
|
8
|
+
export type GetWebStorePath = () => Promise<string>;
|
|
9
|
+
export declare function runWebInitCommand(getWebStorePath: GetWebStorePath, opts: WebInitCommandOptions): Promise<void>;
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
export async function runWebInitCommand(getWebStorePath, opts) {
|
|
2
|
+
try {
|
|
3
|
+
const { mkdirSync } = await import("fs");
|
|
4
|
+
const { loadConfig, updateConfig, resolveTaskModel } = await import("./config.js");
|
|
5
|
+
const { createInterface } = await import("readline/promises");
|
|
6
|
+
const storePath = await getWebStorePath();
|
|
7
|
+
const DIM = "\x1b[2m";
|
|
8
|
+
const BOLD = "\x1b[1m";
|
|
9
|
+
const CYAN = "\x1b[36m";
|
|
10
|
+
const GREEN = "\x1b[32m";
|
|
11
|
+
const RESET = "\x1b[0m";
|
|
12
|
+
const CHECK = `${GREEN}\u2713${RESET}`;
|
|
13
|
+
let sitemapUrl = "";
|
|
14
|
+
let outputDir = opts.output;
|
|
15
|
+
let llmEnrich = true;
|
|
16
|
+
let envVarName = "ANTHROPIC_API_KEY";
|
|
17
|
+
// Detect current agent config for provider info
|
|
18
|
+
let agentProvider = "anthropic";
|
|
19
|
+
let agentModel = "";
|
|
20
|
+
try {
|
|
21
|
+
const cfg = await loadConfig(storePath);
|
|
22
|
+
agentProvider = cfg.llm.defaultProvider;
|
|
23
|
+
const taskModel = resolveTaskModel(cfg, "structuring");
|
|
24
|
+
agentModel = taskModel.model;
|
|
25
|
+
}
|
|
26
|
+
catch { /* no config yet */ }
|
|
27
|
+
// Map provider to env var name
|
|
28
|
+
const providerEnvVars = {
|
|
29
|
+
anthropic: "ANTHROPIC_API_KEY",
|
|
30
|
+
openai: "OPENAI_API_KEY",
|
|
31
|
+
groq: "GROQ_API_KEY",
|
|
32
|
+
xai: "XAI_API_KEY",
|
|
33
|
+
mistral: "MISTRAL_API_KEY",
|
|
34
|
+
ollama: "",
|
|
35
|
+
lmstudio: "",
|
|
36
|
+
custom: "GNOSYS_LLM_API_KEY",
|
|
37
|
+
};
|
|
38
|
+
if (!opts.nonInteractive && !opts.json && process.stdout.isTTY) {
|
|
39
|
+
const rl = createInterface({ input: process.stdin, output: process.stdout });
|
|
40
|
+
try {
|
|
41
|
+
console.log();
|
|
42
|
+
console.log(`${BOLD}Web Knowledge Base Setup${RESET}`);
|
|
43
|
+
console.log();
|
|
44
|
+
console.log(`${DIM}This sets up a /knowledge/ directory in your project.`);
|
|
45
|
+
console.log(`Gnosys crawls your site, converts pages to markdown, and`);
|
|
46
|
+
console.log(`builds a search index. Everything deploys with your app.`);
|
|
47
|
+
console.log();
|
|
48
|
+
console.log(`No API keys are stored in your project. The LLM key is`);
|
|
49
|
+
console.log(`read from an environment variable at build time.${RESET}`);
|
|
50
|
+
console.log();
|
|
51
|
+
// Step 1: Sitemap URL
|
|
52
|
+
console.log(`${BOLD}Step 1/3${RESET} ${DIM}\u2014${RESET} Content source`);
|
|
53
|
+
console.log();
|
|
54
|
+
console.log(`${DIM} \u2022 Deployed site: https://yoursite.com/sitemap.xml`);
|
|
55
|
+
console.log(` \u2022 Local dev: http://localhost:3000/sitemap.xml`);
|
|
56
|
+
console.log(` \u2022 Not ready yet: press Enter (add later in gnosys.json)${RESET}`);
|
|
57
|
+
console.log();
|
|
58
|
+
const urlAnswer = await rl.question("Sitemap URL: ");
|
|
59
|
+
sitemapUrl = urlAnswer.trim();
|
|
60
|
+
console.log();
|
|
61
|
+
// Step 2: LLM enrichment
|
|
62
|
+
console.log(`${BOLD}Step 2/3${RESET} ${DIM}\u2014${RESET} LLM enrichment`);
|
|
63
|
+
console.log();
|
|
64
|
+
console.log(`${DIM}LLM enrichment generates better tags, keyword clouds, and`);
|
|
65
|
+
console.log(`frontmatter for each page. Without it, Gnosys uses TF-IDF`);
|
|
66
|
+
console.log(`keyword extraction (free, no API key needed, decent quality).${RESET}`);
|
|
67
|
+
console.log();
|
|
68
|
+
if (agentModel && providerEnvVars[agentProvider]) {
|
|
69
|
+
console.log(`${DIM}Your agent setup uses ${agentProvider}/${agentModel} for structuring.${RESET}`);
|
|
70
|
+
}
|
|
71
|
+
console.log();
|
|
72
|
+
const enrichAnswer = await rl.question("Enable LLM enrichment? [Y/n] ");
|
|
73
|
+
llmEnrich = !enrichAnswer.trim().toLowerCase().startsWith("n");
|
|
74
|
+
console.log();
|
|
75
|
+
// Step 3: CI/CD env var
|
|
76
|
+
if (llmEnrich) {
|
|
77
|
+
console.log(`${BOLD}Step 3/3${RESET} ${DIM}\u2014${RESET} CI/CD environment variable`);
|
|
78
|
+
console.log();
|
|
79
|
+
console.log(`${DIM}In CI/CD (GitHub Actions, Vercel, Netlify), the LLM API key`);
|
|
80
|
+
console.log(`is read from an environment variable. No keys are stored in`);
|
|
81
|
+
console.log(`your project or committed to git.${RESET}`);
|
|
82
|
+
console.log();
|
|
83
|
+
const defaultEnv = providerEnvVars[agentProvider] || "ANTHROPIC_API_KEY";
|
|
84
|
+
const envAnswer = await rl.question(`Env var name for API key (${defaultEnv}): `);
|
|
85
|
+
envVarName = envAnswer.trim() || defaultEnv;
|
|
86
|
+
}
|
|
87
|
+
else {
|
|
88
|
+
console.log(`${DIM}Step 3/3 \u2014 Skipped (no LLM = no API key needed)${RESET}`);
|
|
89
|
+
envVarName = "";
|
|
90
|
+
}
|
|
91
|
+
console.log();
|
|
92
|
+
// Output dir
|
|
93
|
+
const dirAnswer = await rl.question(`Output directory (${opts.output}): `);
|
|
94
|
+
outputDir = dirAnswer.trim() || opts.output;
|
|
95
|
+
rl.close();
|
|
96
|
+
}
|
|
97
|
+
catch {
|
|
98
|
+
rl.close();
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
// Create output directory
|
|
102
|
+
mkdirSync(outputDir, { recursive: true });
|
|
103
|
+
// Update gnosys.json with web config
|
|
104
|
+
if (opts.config) {
|
|
105
|
+
try {
|
|
106
|
+
const config = await loadConfig(storePath);
|
|
107
|
+
if (!config.web) {
|
|
108
|
+
await updateConfig(storePath, {
|
|
109
|
+
web: {
|
|
110
|
+
source: opts.source,
|
|
111
|
+
...(sitemapUrl ? { sitemapUrl } : {}),
|
|
112
|
+
outputDir,
|
|
113
|
+
exclude: ["/api", "/admin", "/_next"],
|
|
114
|
+
categories: {
|
|
115
|
+
"/blog/*": "blog",
|
|
116
|
+
"/services/*": "services",
|
|
117
|
+
"/products/*": "products",
|
|
118
|
+
"/about*": "company",
|
|
119
|
+
},
|
|
120
|
+
llmEnrich,
|
|
121
|
+
prune: false,
|
|
122
|
+
},
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
catch {
|
|
127
|
+
// No gnosys.json yet — run gnosys init first
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
if (opts.json) {
|
|
131
|
+
console.log(JSON.stringify({ ok: true, outputDir, source: opts.source, sitemapUrl: sitemapUrl || null, llmEnrich, envVarName: envVarName || null }));
|
|
132
|
+
}
|
|
133
|
+
else {
|
|
134
|
+
console.log(`${CHECK} Created ${outputDir}/`);
|
|
135
|
+
console.log(`${CHECK} Updated gnosys.json with web config`);
|
|
136
|
+
if (sitemapUrl) {
|
|
137
|
+
console.log(`${CHECK} Sitemap: ${sitemapUrl}`);
|
|
138
|
+
}
|
|
139
|
+
console.log(`${CHECK} LLM enrichment: ${llmEnrich ? "enabled" : "disabled (TF-IDF mode)"}`);
|
|
140
|
+
if (envVarName) {
|
|
141
|
+
console.log(`${CHECK} CI/CD env var: ${envVarName}`);
|
|
142
|
+
}
|
|
143
|
+
console.log();
|
|
144
|
+
console.log(`${BOLD}Next steps:${RESET}`);
|
|
145
|
+
if (!sitemapUrl) {
|
|
146
|
+
console.log(` 1. Add your sitemap URL to gnosys.json → web.sitemapUrl`);
|
|
147
|
+
}
|
|
148
|
+
if (envVarName) {
|
|
149
|
+
console.log(` ${sitemapUrl ? "1" : "2"}. Set ${CYAN}${envVarName}${RESET} in your hosting provider (Vercel, Netlify, GitHub Actions)`);
|
|
150
|
+
console.log(` ${DIM}Never commit API keys to your repo${RESET}`);
|
|
151
|
+
}
|
|
152
|
+
console.log(` ${!sitemapUrl && envVarName ? "3" : envVarName || !sitemapUrl ? "2" : "1"}. Run: ${CYAN}gnosys web build${RESET}`);
|
|
153
|
+
console.log(` ${!sitemapUrl && envVarName ? "4" : envVarName || !sitemapUrl ? "3" : "2"}. Add to package.json: ${CYAN}"postbuild": "npx gnosys web build"${RESET}`);
|
|
154
|
+
console.log();
|
|
155
|
+
console.log(`${DIM}Every deploy will re-crawl and rebuild the search index automatically.${RESET}`);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
catch (err) {
|
|
159
|
+
if (opts.json) {
|
|
160
|
+
console.log(JSON.stringify({ ok: false, error: err instanceof Error ? err.message : String(err) }));
|
|
161
|
+
}
|
|
162
|
+
else {
|
|
163
|
+
console.error(`Web init failed: ${err instanceof Error ? err.message : err}`);
|
|
164
|
+
}
|
|
165
|
+
process.exit(1);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { existsSync } from "fs";
|
|
2
|
+
import path from "path";
|
|
3
|
+
export async function runWebRemoveCommand(getWebStorePath, filepath, opts) {
|
|
4
|
+
try {
|
|
5
|
+
const { loadConfig } = await import("./config.js");
|
|
6
|
+
const { buildIndex, writeIndex } = await import("./webIndex.js");
|
|
7
|
+
const fsp = await import("fs/promises");
|
|
8
|
+
const gnosysConfig = await loadConfig(await getWebStorePath());
|
|
9
|
+
const webConfig = gnosysConfig.web;
|
|
10
|
+
const knowledgeDir = webConfig?.outputDir || "./knowledge";
|
|
11
|
+
const knowledgeRoot = path.resolve(knowledgeDir);
|
|
12
|
+
const fullPath = path.resolve(knowledgeRoot, filepath);
|
|
13
|
+
const relativePath = path.relative(knowledgeRoot, fullPath);
|
|
14
|
+
if (path.isAbsolute(filepath) || relativePath.startsWith("..") || path.isAbsolute(relativePath)) {
|
|
15
|
+
throw new Error(`Refusing to remove file outside knowledge directory: ${filepath}`);
|
|
16
|
+
}
|
|
17
|
+
if (!existsSync(fullPath)) {
|
|
18
|
+
throw new Error(`File not found: ${fullPath}`);
|
|
19
|
+
}
|
|
20
|
+
await fsp.unlink(fullPath);
|
|
21
|
+
// Rebuild index
|
|
22
|
+
const index = await buildIndex(knowledgeRoot);
|
|
23
|
+
await writeIndex(index, path.join(knowledgeRoot, "gnosys-index.json"));
|
|
24
|
+
if (opts.json) {
|
|
25
|
+
console.log(JSON.stringify({ ok: true, removed: filepath, documentCount: index.documentCount }));
|
|
26
|
+
}
|
|
27
|
+
else {
|
|
28
|
+
console.log(`Removed: ${filepath}`);
|
|
29
|
+
console.log(`Index rebuilt: ${index.documentCount} documents`);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
catch (err) {
|
|
33
|
+
if (opts.json) {
|
|
34
|
+
console.log(JSON.stringify({ ok: false, error: err instanceof Error ? err.message : String(err) }));
|
|
35
|
+
}
|
|
36
|
+
else {
|
|
37
|
+
console.error(`Web remove failed: ${err instanceof Error ? err.message : err}`);
|
|
38
|
+
}
|
|
39
|
+
process.exit(1);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { existsSync, readFileSync } from "fs";
|
|
2
|
+
import path from "path";
|
|
3
|
+
export async function runWebStatusCommand(getWebStorePath, opts) {
|
|
4
|
+
try {
|
|
5
|
+
const { loadConfig } = await import("./config.js");
|
|
6
|
+
const { readdirSync, statSync } = await import("fs");
|
|
7
|
+
const gnosysConfig = await loadConfig(await getWebStorePath());
|
|
8
|
+
const webConfig = gnosysConfig.web;
|
|
9
|
+
const knowledgeDir = webConfig?.outputDir || "./knowledge";
|
|
10
|
+
const resolvedDir = path.resolve(knowledgeDir);
|
|
11
|
+
if (!existsSync(resolvedDir)) {
|
|
12
|
+
if (opts.json) {
|
|
13
|
+
console.log(JSON.stringify({ ok: true, exists: false, message: "Knowledge directory not found" }));
|
|
14
|
+
}
|
|
15
|
+
else {
|
|
16
|
+
console.log(`Knowledge directory not found: ${resolvedDir}`);
|
|
17
|
+
console.log(`Run 'gnosys web init' to get started.`);
|
|
18
|
+
}
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
const categoryCounts = {};
|
|
22
|
+
let totalFiles = 0;
|
|
23
|
+
function countFiles(dir) {
|
|
24
|
+
const entries = readdirSync(dir, { withFileTypes: true });
|
|
25
|
+
for (const entry of entries) {
|
|
26
|
+
const fullPath = path.join(dir, entry.name);
|
|
27
|
+
if (entry.isDirectory()) {
|
|
28
|
+
countFiles(fullPath);
|
|
29
|
+
}
|
|
30
|
+
else if (entry.isFile() && entry.name.endsWith(".md")) {
|
|
31
|
+
const category = path.relative(resolvedDir, dir) || "root";
|
|
32
|
+
categoryCounts[category] = (categoryCounts[category] || 0) + 1;
|
|
33
|
+
totalFiles++;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
countFiles(resolvedDir);
|
|
38
|
+
const indexPath = path.join(resolvedDir, "gnosys-index.json");
|
|
39
|
+
let indexInfo = { exists: false };
|
|
40
|
+
if (existsSync(indexPath)) {
|
|
41
|
+
const stat = statSync(indexPath);
|
|
42
|
+
try {
|
|
43
|
+
const indexData = JSON.parse(readFileSync(indexPath, "utf-8"));
|
|
44
|
+
indexInfo = {
|
|
45
|
+
exists: true,
|
|
46
|
+
documentCount: indexData.documentCount,
|
|
47
|
+
size: stat.size,
|
|
48
|
+
generated: indexData.generated,
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
catch {
|
|
52
|
+
indexInfo = { exists: true, size: stat.size };
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
if (opts.json) {
|
|
56
|
+
console.log(JSON.stringify({
|
|
57
|
+
ok: true,
|
|
58
|
+
knowledgeDir: resolvedDir,
|
|
59
|
+
totalFiles,
|
|
60
|
+
categoryCounts,
|
|
61
|
+
index: indexInfo,
|
|
62
|
+
}, null, 2));
|
|
63
|
+
}
|
|
64
|
+
else {
|
|
65
|
+
console.log(`Web Knowledge Base Status:`);
|
|
66
|
+
console.log(` Directory: ${resolvedDir}`);
|
|
67
|
+
console.log(` Total files: ${totalFiles}`);
|
|
68
|
+
if (Object.keys(categoryCounts).length > 0) {
|
|
69
|
+
console.log(` By category:`);
|
|
70
|
+
for (const [cat, count] of Object.entries(categoryCounts).sort()) {
|
|
71
|
+
console.log(` ${cat}: ${count}`);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
if (indexInfo.exists) {
|
|
75
|
+
console.log(` Index: ${indexInfo.documentCount ?? "?"} docs, ${((indexInfo.size || 0) / 1024).toFixed(1)}KB`);
|
|
76
|
+
if (indexInfo.generated) {
|
|
77
|
+
console.log(` Last built: ${indexInfo.generated}`);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
else {
|
|
81
|
+
console.log(` Index: not built (run 'gnosys web build-index')`);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
catch (err) {
|
|
86
|
+
if (opts.json) {
|
|
87
|
+
console.log(JSON.stringify({ ok: false, error: err instanceof Error ? err.message : String(err) }));
|
|
88
|
+
}
|
|
89
|
+
else {
|
|
90
|
+
console.error(`Web status failed: ${err instanceof Error ? err.message : err}`);
|
|
91
|
+
}
|
|
92
|
+
process.exit(1);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { GetWebStorePath } from "./webInitCommand.js";
|
|
2
|
+
export type WebUpdateCommandOptions = {
|
|
3
|
+
llm: boolean;
|
|
4
|
+
category?: string;
|
|
5
|
+
json?: boolean;
|
|
6
|
+
};
|
|
7
|
+
export declare function runWebUpdateCommand(getWebStorePath: GetWebStorePath, urlOrPath: string, opts: WebUpdateCommandOptions): Promise<void>;
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { existsSync } from "fs";
|
|
2
|
+
import path from "path";
|
|
3
|
+
export async function runWebUpdateCommand(getWebStorePath, urlOrPath, opts) {
|
|
4
|
+
try {
|
|
5
|
+
const { loadConfig } = await import("./config.js");
|
|
6
|
+
const { ingestUrl } = await import("./webIngest.js");
|
|
7
|
+
const { buildIndex, writeIndex } = await import("./webIndex.js");
|
|
8
|
+
const gnosysConfig = await loadConfig(await getWebStorePath());
|
|
9
|
+
const webConfig = gnosysConfig.web;
|
|
10
|
+
if (!webConfig) {
|
|
11
|
+
throw new Error("No web configuration found in gnosys.json. Run 'gnosys web init' first.");
|
|
12
|
+
}
|
|
13
|
+
const knowledgeDir = webConfig.outputDir || "./knowledge";
|
|
14
|
+
const knowledgeRoot = path.resolve(knowledgeDir);
|
|
15
|
+
const isUrl = urlOrPath.startsWith("http://") || urlOrPath.startsWith("https://");
|
|
16
|
+
if (isUrl) {
|
|
17
|
+
// Re-ingest the URL
|
|
18
|
+
const categories = opts.category
|
|
19
|
+
? { "/*": opts.category }
|
|
20
|
+
: webConfig.categories;
|
|
21
|
+
const result = await ingestUrl(urlOrPath, {
|
|
22
|
+
source: "urls",
|
|
23
|
+
outputDir: knowledgeDir,
|
|
24
|
+
categories,
|
|
25
|
+
llmEnrich: opts.llm ? webConfig.llmEnrich : false,
|
|
26
|
+
prune: false,
|
|
27
|
+
concurrency: 1,
|
|
28
|
+
crawlDelayMs: 0,
|
|
29
|
+
}, gnosysConfig);
|
|
30
|
+
// Rebuild index
|
|
31
|
+
const index = await buildIndex(knowledgeRoot);
|
|
32
|
+
await writeIndex(index, path.join(knowledgeRoot, "gnosys-index.json"));
|
|
33
|
+
if (opts.json) {
|
|
34
|
+
console.log(JSON.stringify({ ok: true, ...result, documentCount: index.documentCount }));
|
|
35
|
+
}
|
|
36
|
+
else {
|
|
37
|
+
console.log(`Updated: ${urlOrPath}`);
|
|
38
|
+
console.log(` Added: ${result.added.length}, Updated: ${result.updated.length}`);
|
|
39
|
+
console.log(`Index rebuilt: ${index.documentCount} documents`);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
else {
|
|
43
|
+
// Refresh a local knowledge file — rebuild index
|
|
44
|
+
const fullPath = path.resolve(knowledgeRoot, urlOrPath);
|
|
45
|
+
const relativePath = path.relative(knowledgeRoot, fullPath);
|
|
46
|
+
if (path.isAbsolute(urlOrPath) || relativePath.startsWith("..") || path.isAbsolute(relativePath)) {
|
|
47
|
+
throw new Error(`Refusing to refresh file outside knowledge directory: ${urlOrPath}`);
|
|
48
|
+
}
|
|
49
|
+
if (!existsSync(fullPath)) {
|
|
50
|
+
throw new Error(`File not found: ${fullPath}`);
|
|
51
|
+
}
|
|
52
|
+
const index = await buildIndex(knowledgeRoot);
|
|
53
|
+
await writeIndex(index, path.join(knowledgeRoot, "gnosys-index.json"));
|
|
54
|
+
if (opts.json) {
|
|
55
|
+
console.log(JSON.stringify({ ok: true, refreshed: urlOrPath, documentCount: index.documentCount }));
|
|
56
|
+
}
|
|
57
|
+
else {
|
|
58
|
+
console.log(`Refreshed: ${urlOrPath}`);
|
|
59
|
+
console.log(`Index rebuilt: ${index.documentCount} documents`);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
catch (err) {
|
|
64
|
+
if (opts.json) {
|
|
65
|
+
console.log(JSON.stringify({ ok: false, error: err instanceof Error ? err.message : String(err) }));
|
|
66
|
+
}
|
|
67
|
+
else {
|
|
68
|
+
console.error(`Web update failed: ${err instanceof Error ? err.message : err}`);
|
|
69
|
+
}
|
|
70
|
+
process.exit(1);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { GnosysDB } from "./db.js";
|
|
2
|
+
export async function runWorkingSetCommand(opts) {
|
|
3
|
+
let centralDb = null;
|
|
4
|
+
try {
|
|
5
|
+
centralDb = GnosysDB.openCentral();
|
|
6
|
+
if (!centralDb.isAvailable()) {
|
|
7
|
+
console.error("Central DB not available.");
|
|
8
|
+
process.exit(1);
|
|
9
|
+
}
|
|
10
|
+
const { getWorkingSet, formatWorkingSet, detectCurrentProject } = await import("./federated.js");
|
|
11
|
+
const pid = await detectCurrentProject(centralDb, opts.directory || undefined);
|
|
12
|
+
if (!pid) {
|
|
13
|
+
console.error("No project detected.");
|
|
14
|
+
process.exit(1);
|
|
15
|
+
}
|
|
16
|
+
const windowHours = parseInt(opts.window, 10);
|
|
17
|
+
const workingSet = getWorkingSet(centralDb, pid, { windowHours });
|
|
18
|
+
if (opts.json) {
|
|
19
|
+
console.log(JSON.stringify({
|
|
20
|
+
projectId: pid,
|
|
21
|
+
windowHours,
|
|
22
|
+
count: workingSet.length,
|
|
23
|
+
memories: workingSet.map((m) => ({ id: m.id, title: m.title, category: m.category, modified: m.modified })),
|
|
24
|
+
}, null, 2));
|
|
25
|
+
}
|
|
26
|
+
else {
|
|
27
|
+
console.log(formatWorkingSet(workingSet));
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
catch (err) {
|
|
31
|
+
console.error(`Error: ${err instanceof Error ? err.message : err}`);
|
|
32
|
+
process.exit(1);
|
|
33
|
+
}
|
|
34
|
+
finally {
|
|
35
|
+
centralDb?.close();
|
|
36
|
+
}
|
|
37
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "gnosys",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.12.0",
|
|
4
4
|
"description": "Gnosys — Persistent Memory for AI Agents. Sandbox-first runtime, central SQLite brain, federated search, Dream Mode, Web Knowledge Base, Obsidian export.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -21,6 +21,7 @@
|
|
|
21
21
|
"scripts": {
|
|
22
22
|
"prebuild": "node -e \"require('fs').rmSync('dist',{recursive:true,force:true})\"",
|
|
23
23
|
"build": "tsc",
|
|
24
|
+
"postbuild": "node -e \"const fs=require('fs');for (const f of ['dist/cli.js','dist/index.js']) { try { fs.chmodSync(f,0o755); } catch {} }\"",
|
|
24
25
|
"prebuild:publish": "node -e \"require('fs').rmSync('dist',{recursive:true,force:true})\"",
|
|
25
26
|
"build:publish": "tsc -p tsconfig.publish.json",
|
|
26
27
|
"start": "node dist/index.js",
|