@monoes/monomindcli 2.14.1 → 2.15.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/.claude/helpers/control-start.cjs +10 -13
- package/.claude/skills/monodesign/scripts/context.mjs +4 -4
- package/.claude/skills/monodesign/scripts/critique-storage.mjs +1 -1
- package/.claude/skills/monodesign/scripts/detect-csp.mjs +1 -6
- package/.claude/skills/monodesign/scripts/detector/browser/injected/index.mjs +16 -18
- package/.claude/skills/monodesign/scripts/detector/cli/main.mjs +3 -3
- package/.claude/skills/monodesign/scripts/detector/detect-antipatterns-browser.js +67 -47
- package/.claude/skills/monodesign/scripts/detector/engines/regex/detect-text.mjs +6 -6
- package/.claude/skills/monodesign/scripts/detector/engines/static-html/css-cascade.mjs +6 -5
- package/.claude/skills/monodesign/scripts/detector/engines/static-html/detect-html.mjs +6 -6
- package/.claude/skills/monodesign/scripts/detector/fix/index.mjs +3 -3
- package/.claude/skills/monodesign/scripts/detector/node/file-system.mjs +1 -1
- package/.claude/skills/monodesign/scripts/detector/registry/antipatterns.mjs +1 -1
- package/.claude/skills/monodesign/scripts/detector/rules/checks.mjs +24 -25
- package/.claude/skills/monodesign/scripts/detector/shared/color.mjs +2 -2
- package/.claude/skills/monodesign/scripts/detector/shared/constants.mjs +1 -1
- package/.claude/skills/monodesign/scripts/detector/shared/inline-ignores.mjs +2 -2
- package/.claude/skills/monodesign/scripts/hook-admin.mjs +6 -6
- package/.claude/skills/monodesign/scripts/hook-before-edit.mjs +4 -4
- package/.claude/skills/monodesign/scripts/hook-lib.mjs +20 -11
- package/.claude/skills/monodesign/scripts/hook.mjs +1 -1
- package/.claude/skills/monodesign/scripts/lib/design-parser.mjs +9 -42
- package/.claude/skills/monodesign/scripts/lib/is-generated.mjs +1 -1
- package/.claude/skills/monodesign/scripts/lib/monodesign-config.mjs +5 -5
- package/.claude/skills/monodesign/scripts/lib/monodesign-paths.mjs +1 -1
- package/.claude/skills/monodesign/scripts/live/event-validation.mjs +13 -13
- package/.claude/skills/monodesign/scripts/live/manual-apply.mjs +4 -4
- package/.claude/skills/monodesign/scripts/live/manual-edits-buffer.mjs +1 -1
- package/.claude/skills/monodesign/scripts/live/session-store.mjs +5 -5
- package/.claude/skills/monodesign/scripts/live/svelte-component.mjs +13 -13
- package/.claude/skills/monodesign/scripts/live/sveltekit-adapter.mjs +4 -4
- package/.claude/skills/monodesign/scripts/live/ui-core.mjs +1 -1
- package/.claude/skills/monodesign/scripts/live-accept.mjs +24 -24
- package/.claude/skills/monodesign/scripts/live-browser-dom.js +8 -7
- package/.claude/skills/monodesign/scripts/live-browser-session.js +8 -7
- package/.claude/skills/monodesign/scripts/live-browser.js +405 -432
- package/.claude/skills/monodesign/scripts/live-commit-manual-edits.mjs +6 -6
- package/.claude/skills/monodesign/scripts/live-copy-edit-agent.mjs +2 -2
- package/.claude/skills/monodesign/scripts/live-discard-manual-edits.mjs +1 -1
- package/.claude/skills/monodesign/scripts/live-inject.mjs +7 -7
- package/.claude/skills/monodesign/scripts/live-insert.mjs +11 -11
- package/.claude/skills/monodesign/scripts/live-manual-edit-evidence.mjs +4 -4
- package/.claude/skills/monodesign/scripts/live-poll.mjs +5 -5
- package/.claude/skills/monodesign/scripts/live-server.mjs +10 -10
- package/.claude/skills/monodesign/scripts/live-wrap.mjs +31 -41
- package/.claude/skills/monodesign/scripts/live.mjs +5 -5
- package/.claude/skills/monodesign/scripts/palette.mjs +3 -1
- package/.claude/skills/monodesign/scripts/pin.mjs +1 -1
- package/dist/src/commands/doc-filters.d.ts.map +1 -1
- package/dist/src/commands/doc-filters.js +6 -0
- package/dist/src/commands/doc-filters.js.map +1 -1
- package/dist/src/commands/doc-library.d.ts +2 -1
- package/dist/src/commands/doc-library.d.ts.map +1 -1
- package/dist/src/commands/doc-library.js +66 -2
- package/dist/src/commands/doc-library.js.map +1 -1
- package/dist/src/commands/doc.d.ts.map +1 -1
- package/dist/src/commands/doc.js +2 -0
- package/dist/src/commands/doc.js.map +1 -1
- package/dist/src/commands/ui.d.ts.map +1 -1
- package/dist/src/commands/ui.js +60 -0
- package/dist/src/commands/ui.js.map +1 -1
- package/dist/src/knowledge/capture-envelope.d.ts +5 -0
- package/dist/src/knowledge/capture-envelope.d.ts.map +1 -1
- package/dist/src/knowledge/capture-envelope.js +2 -0
- package/dist/src/knowledge/capture-envelope.js.map +1 -1
- package/dist/src/knowledge/document-chunking.d.ts +42 -0
- package/dist/src/knowledge/document-chunking.d.ts.map +1 -0
- package/dist/src/knowledge/document-chunking.js +288 -0
- package/dist/src/knowledge/document-chunking.js.map +1 -0
- package/dist/src/knowledge/document-index.d.ts +124 -0
- package/dist/src/knowledge/document-index.d.ts.map +1 -0
- package/dist/src/knowledge/document-index.js +314 -0
- package/dist/src/knowledge/document-index.js.map +1 -0
- package/dist/src/knowledge/document-ingest.d.ts +23 -0
- package/dist/src/knowledge/document-ingest.d.ts.map +1 -0
- package/dist/src/knowledge/document-ingest.js +368 -0
- package/dist/src/knowledge/document-ingest.js.map +1 -0
- package/dist/src/knowledge/document-pipeline.d.ts +26 -208
- package/dist/src/knowledge/document-pipeline.d.ts.map +1 -1
- package/dist/src/knowledge/document-pipeline.js +25 -1104
- package/dist/src/knowledge/document-pipeline.js.map +1 -1
- package/dist/src/knowledge/document-search.d.ts +27 -0
- package/dist/src/knowledge/document-search.d.ts.map +1 -0
- package/dist/src/knowledge/document-search.js +138 -0
- package/dist/src/knowledge/document-search.js.map +1 -0
- package/dist/src/knowledge/document-store.d.ts +28 -0
- package/dist/src/knowledge/document-store.d.ts.map +1 -0
- package/dist/src/knowledge/document-store.js +61 -0
- package/dist/src/knowledge/document-store.js.map +1 -0
- package/dist/src/knowledge/document-types.d.ts +103 -0
- package/dist/src/knowledge/document-types.d.ts.map +1 -0
- package/dist/src/knowledge/document-types.js +12 -0
- package/dist/src/knowledge/document-types.js.map +1 -0
- package/dist/src/knowledge/highlights.d.ts +168 -0
- package/dist/src/knowledge/highlights.d.ts.map +1 -0
- package/dist/src/knowledge/highlights.js +311 -0
- package/dist/src/knowledge/highlights.js.map +1 -0
- package/dist/src/knowledge/lookup.d.ts +80 -0
- package/dist/src/knowledge/lookup.d.ts.map +1 -0
- package/dist/src/knowledge/lookup.js +156 -0
- package/dist/src/knowledge/lookup.js.map +1 -0
- package/dist/src/knowledge/okf-bundle.d.ts +19 -0
- package/dist/src/knowledge/okf-bundle.d.ts.map +1 -0
- package/dist/src/knowledge/okf-bundle.js +106 -0
- package/dist/src/knowledge/okf-bundle.js.map +1 -0
- package/dist/src/knowledge/profile-store.d.ts +134 -0
- package/dist/src/knowledge/profile-store.d.ts.map +1 -0
- package/dist/src/knowledge/profile-store.js +237 -0
- package/dist/src/knowledge/profile-store.js.map +1 -0
- package/dist/src/orgrt/agent-runner.d.ts +4 -0
- package/dist/src/orgrt/agent-runner.d.ts.map +1 -1
- package/dist/src/orgrt/agent-runner.js +22 -0
- package/dist/src/orgrt/agent-runner.js.map +1 -1
- package/dist/src/orgrt/antigravity-runner.d.ts.map +1 -1
- package/dist/src/orgrt/antigravity-runner.js +2 -1
- package/dist/src/orgrt/antigravity-runner.js.map +1 -1
- package/dist/src/orgrt/authority-mask.d.ts +32 -0
- package/dist/src/orgrt/authority-mask.d.ts.map +1 -0
- package/dist/src/orgrt/authority-mask.js +135 -0
- package/dist/src/orgrt/authority-mask.js.map +1 -0
- package/dist/src/orgrt/codex-runner.d.ts.map +1 -1
- package/dist/src/orgrt/codex-runner.js +2 -1
- package/dist/src/orgrt/codex-runner.js.map +1 -1
- package/dist/src/orgrt/copilot-runner.d.ts.map +1 -1
- package/dist/src/orgrt/copilot-runner.js +2 -1
- package/dist/src/orgrt/copilot-runner.js.map +1 -1
- package/dist/src/orgrt/crush-runner.d.ts.map +1 -1
- package/dist/src/orgrt/crush-runner.js +6 -1
- package/dist/src/orgrt/crush-runner.js.map +1 -1
- package/dist/src/orgrt/daemon.d.ts +4 -0
- package/dist/src/orgrt/daemon.d.ts.map +1 -1
- package/dist/src/orgrt/daemon.js +13 -2
- package/dist/src/orgrt/daemon.js.map +1 -1
- package/dist/src/orgrt/decisions.d.ts +9 -0
- package/dist/src/orgrt/decisions.d.ts.map +1 -1
- package/dist/src/orgrt/decisions.js +32 -5
- package/dist/src/orgrt/decisions.js.map +1 -1
- package/dist/src/orgrt/file-roots.d.ts +2 -1
- package/dist/src/orgrt/file-roots.d.ts.map +1 -1
- package/dist/src/orgrt/file-roots.js +7 -3
- package/dist/src/orgrt/file-roots.js.map +1 -1
- package/dist/src/orgrt/grok-runner.d.ts.map +1 -1
- package/dist/src/orgrt/grok-runner.js +2 -1
- package/dist/src/orgrt/grok-runner.js.map +1 -1
- package/dist/src/orgrt/hermes-runner.d.ts.map +1 -1
- package/dist/src/orgrt/hermes-runner.js +2 -1
- package/dist/src/orgrt/hermes-runner.js.map +1 -1
- package/dist/src/orgrt/inbox.d.ts.map +1 -1
- package/dist/src/orgrt/inbox.js +70 -4
- package/dist/src/orgrt/inbox.js.map +1 -1
- package/dist/src/orgrt/kimicode-runner.d.ts.map +1 -1
- package/dist/src/orgrt/kimicode-runner.js +2 -1
- package/dist/src/orgrt/kimicode-runner.js.map +1 -1
- package/dist/src/orgrt/opencode-runner.d.ts.map +1 -1
- package/dist/src/orgrt/opencode-runner.js +3 -2
- package/dist/src/orgrt/opencode-runner.js.map +1 -1
- package/dist/src/orgrt/pi-rpc-runner.d.ts.map +1 -1
- package/dist/src/orgrt/pi-rpc-runner.js +3 -2
- package/dist/src/orgrt/pi-rpc-runner.js.map +1 -1
- package/dist/src/orgrt/pi-runner.d.ts.map +1 -1
- package/dist/src/orgrt/pi-runner.js +2 -1
- package/dist/src/orgrt/pi-runner.js.map +1 -1
- package/dist/src/orgrt/policy.d.ts.map +1 -1
- package/dist/src/orgrt/policy.js +3 -0
- package/dist/src/orgrt/policy.js.map +1 -1
- package/dist/src/orgrt/qwen-rpc-runner.d.ts.map +1 -1
- package/dist/src/orgrt/qwen-rpc-runner.js +3 -2
- package/dist/src/orgrt/qwen-rpc-runner.js.map +1 -1
- package/dist/src/orgrt/qwen-runner.d.ts.map +1 -1
- package/dist/src/orgrt/qwen-runner.js +2 -1
- package/dist/src/orgrt/qwen-runner.js.map +1 -1
- package/dist/src/orgrt/role-sandbox.d.ts +21 -0
- package/dist/src/orgrt/role-sandbox.d.ts.map +1 -1
- package/dist/src/orgrt/role-sandbox.js +31 -6
- package/dist/src/orgrt/role-sandbox.js.map +1 -1
- package/dist/src/orgrt/session.d.ts.map +1 -1
- package/dist/src/orgrt/session.js +21 -2
- package/dist/src/orgrt/session.js.map +1 -1
- package/dist/src/orgrt/task-dag.d.ts +3 -0
- package/dist/src/orgrt/task-dag.d.ts.map +1 -1
- package/dist/src/orgrt/task-dag.js +1 -0
- package/dist/src/orgrt/task-dag.js.map +1 -1
- package/dist/src/orgrt/types.d.ts +5 -0
- package/dist/src/orgrt/types.d.ts.map +1 -1
- package/dist/src/orgrt/types.js +23 -1
- package/dist/src/orgrt/types.js.map +1 -1
- package/dist/src/ui/dashboard.html +28 -848
- package/dist/src/ui/human-auth.mjs +103 -0
- package/dist/src/ui/org-hil.mjs +86 -37
- package/dist/src/ui/org-runtime.mjs +21 -13
- package/dist/src/ui/routes-org.mjs +49 -445
- package/dist/src/ui/server.mjs +90 -2
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +6 -6
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* "Have I already saved this?" (RCL-02) — one URL in, one answer out.
|
|
3
|
+
*
|
|
4
|
+
* The browser extension asks this on every navigation. That is the only
|
|
5
|
+
* thing that shapes this module:
|
|
6
|
+
*
|
|
7
|
+
* - it NEVER throws. An empty store, a store that has never been written,
|
|
8
|
+
* a URL that is not a URL — all of them are `{saved: false}`, because a
|
|
9
|
+
* page load must not be able to fail on a badge;
|
|
10
|
+
* - it is a pure read. No embedder, no subprocess, no index write. The
|
|
11
|
+
* answer comes off the metadata log, which is a file read;
|
|
12
|
+
* - it answers the WHOLE question in one call. `doc list` can already say
|
|
13
|
+
* that a URL is present, but not what note was written at save time —
|
|
14
|
+
* and "you saved this, and here is why you said you were saving it" is
|
|
15
|
+
* the entire value of the badge over a bookmark.
|
|
16
|
+
*
|
|
17
|
+
* Identity is `captureIdentityUrl`'s rule and nothing else: canonical URL
|
|
18
|
+
* when the capturer resolved one, fragment stripped, nothing else rewritten.
|
|
19
|
+
* Matching more loosely than the ingest side would make the badge claim
|
|
20
|
+
* pages are saved that cannot actually be found again.
|
|
21
|
+
*
|
|
22
|
+
* @module v1/cli/knowledge/lookup
|
|
23
|
+
*/
|
|
24
|
+
import * as fs from 'node:fs';
|
|
25
|
+
import * as path from 'node:path';
|
|
26
|
+
import { isCaptureEnvelope } from './capture-envelope.js';
|
|
27
|
+
import { getKnowledgeRoot, listDocuments, listDocumentVersions, } from './document-pipeline.js';
|
|
28
|
+
import { documentCapturedAt, documentSite } from './library.js';
|
|
29
|
+
const EMPTY = (url) => ({ saved: false, url, versions: 0, tags: [] });
|
|
30
|
+
/**
|
|
31
|
+
* identityUrl mirrors `captureIdentityUrl` for a raw URL rather than a
|
|
32
|
+
* provenance record: drop the fragment, trim, rewrite nothing else.
|
|
33
|
+
*
|
|
34
|
+
* Duplicated deliberately rather than reshaping the URL into a fake
|
|
35
|
+
* `CaptureProvenance` to borrow that function — the two callers mean
|
|
36
|
+
* different things ("the URL a tab is on" vs. "what this capture is of")
|
|
37
|
+
* and only happen to agree on the rule.
|
|
38
|
+
*/
|
|
39
|
+
export function identityUrl(raw) {
|
|
40
|
+
const s = String(raw ?? '').trim();
|
|
41
|
+
const hash = s.indexOf('#');
|
|
42
|
+
return (hash === -1 ? s : s.slice(0, hash)).trim();
|
|
43
|
+
}
|
|
44
|
+
/** The identity URL a record is addressable by, or undefined. */
|
|
45
|
+
function recordUrl(meta) {
|
|
46
|
+
const url = meta.canonicalUrl ?? meta.provenance?.canonicalUrl ?? meta.provenance?.url;
|
|
47
|
+
return url ? identityUrl(url) : undefined;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* countHighlights reads the `highlights.json` the extension wrote beside
|
|
51
|
+
* the document (RCL-04). Silent on every failure: the count is decoration
|
|
52
|
+
* on an answer that is already complete without it.
|
|
53
|
+
*/
|
|
54
|
+
function countHighlights(envelope) {
|
|
55
|
+
try {
|
|
56
|
+
const file = path.join(envelope, 'highlights.json');
|
|
57
|
+
if (!fs.existsSync(file))
|
|
58
|
+
return 0;
|
|
59
|
+
const parsed = JSON.parse(fs.readFileSync(file, 'utf-8'));
|
|
60
|
+
return Array.isArray(parsed?.highlights) ? parsed.highlights.length : 0;
|
|
61
|
+
}
|
|
62
|
+
catch {
|
|
63
|
+
return 0;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
/** The envelope directory for an indexed file, or undefined when the file
|
|
67
|
+
* is not inside one. */
|
|
68
|
+
export function envelopeFor(filePath) {
|
|
69
|
+
if (!filePath)
|
|
70
|
+
return undefined;
|
|
71
|
+
const dir = path.dirname(path.resolve(filePath));
|
|
72
|
+
try {
|
|
73
|
+
return isCaptureEnvelope(dir) ? dir : undefined;
|
|
74
|
+
}
|
|
75
|
+
catch {
|
|
76
|
+
return undefined;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
function provenanceOf(meta) {
|
|
80
|
+
return meta.provenance ?? {};
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* lookupUrl answers whether this URL is in the store, and what is known
|
|
84
|
+
* about it. `rootDir` is the store to look in; pass the global brain's root
|
|
85
|
+
* to ask the personal store.
|
|
86
|
+
*/
|
|
87
|
+
export function lookupUrl(rawUrl, opts = {}) {
|
|
88
|
+
const url = identityUrl(rawUrl);
|
|
89
|
+
if (!url)
|
|
90
|
+
return EMPTY('');
|
|
91
|
+
// The SAME routing the ingest used: scope `global` lives in the personal
|
|
92
|
+
// cross-project brain, not under `rootDir`. Reading the wrong store would
|
|
93
|
+
// report every globally-captured page as unsaved.
|
|
94
|
+
let root;
|
|
95
|
+
let docs;
|
|
96
|
+
try {
|
|
97
|
+
root = opts.scope ? getKnowledgeRoot(opts.scope, opts.rootDir) : opts.rootDir;
|
|
98
|
+
docs = listDocuments(root, opts.scope);
|
|
99
|
+
}
|
|
100
|
+
catch {
|
|
101
|
+
// A store that has never been written, or one this process cannot
|
|
102
|
+
// read. Neither is an error worth failing a page load over.
|
|
103
|
+
return EMPTY(url);
|
|
104
|
+
}
|
|
105
|
+
const matches = docs.filter((d) => recordUrl(d) === url);
|
|
106
|
+
if (!matches.length)
|
|
107
|
+
return EMPTY(url);
|
|
108
|
+
// The live record with the highest version. A re-captured page lands at
|
|
109
|
+
// a new path, so several records can match and only the newest is the
|
|
110
|
+
// one the badge should describe.
|
|
111
|
+
const best = matches.reduce((a, b) => ((b.version ?? 0) > (a.version ?? 0) ? b : a));
|
|
112
|
+
const prov = provenanceOf(best);
|
|
113
|
+
// The version COUNT is the larger of the record's own number and what
|
|
114
|
+
// the append-only log still holds: the log is compacted past 1MB, and
|
|
115
|
+
// the `version` field is the durable count. Reading only the log would
|
|
116
|
+
// under-report a long-lived document.
|
|
117
|
+
let logged = 0;
|
|
118
|
+
try {
|
|
119
|
+
logged = listDocumentVersions(root, best.canonicalUrl ?? url, opts.scope).length;
|
|
120
|
+
}
|
|
121
|
+
catch {
|
|
122
|
+
logged = 0;
|
|
123
|
+
}
|
|
124
|
+
const versions = Math.max(best.version ?? 1, logged, 1);
|
|
125
|
+
const envelope = envelopeFor(best.filePath);
|
|
126
|
+
const answer = {
|
|
127
|
+
saved: true,
|
|
128
|
+
url,
|
|
129
|
+
versions,
|
|
130
|
+
tags: prov.tags ?? [],
|
|
131
|
+
...(prov.title ? { title: prov.title } : {}),
|
|
132
|
+
...(documentSite(best) ? { site: documentSite(best) } : {}),
|
|
133
|
+
...(documentCapturedAt(best) ? { capturedAt: documentCapturedAt(best) } : {}),
|
|
134
|
+
...(prov.note ? { note: prov.note } : {}),
|
|
135
|
+
...(prov.collection ? { collection: prov.collection } : {}),
|
|
136
|
+
...(prov.source ? { source: prov.source } : {}),
|
|
137
|
+
filePath: best.filePath,
|
|
138
|
+
...(envelope ? { envelope } : {}),
|
|
139
|
+
scope: best.scope,
|
|
140
|
+
...(best.contentHash ? { contentHash: best.contentHash } : {}),
|
|
141
|
+
};
|
|
142
|
+
if (opts.withHighlights && envelope) {
|
|
143
|
+
const count = countHighlights(envelope);
|
|
144
|
+
if (count)
|
|
145
|
+
answer.highlights = count;
|
|
146
|
+
}
|
|
147
|
+
return answer;
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* lookupUrls answers a batch in one pass over the metadata, for a caller
|
|
151
|
+
* with several tabs to ask about. Same rules, same guarantees.
|
|
152
|
+
*/
|
|
153
|
+
export function lookupUrls(urls, opts = {}) {
|
|
154
|
+
return urls.map((u) => lookupUrl(u, opts));
|
|
155
|
+
}
|
|
156
|
+
//# sourceMappingURL=lookup.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lookup.js","sourceRoot":"","sources":["../../../src/knowledge/lookup.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OKF bundles — export the indexed documents to a portable Markdown bundle
|
|
3
|
+
* (frontmatter + `index.md`), and ingest one back.
|
|
4
|
+
*
|
|
5
|
+
* A bundle is plain files, so a round trip goes back through the ordinary
|
|
6
|
+
* ingest path rather than restoring index records directly: whatever comes
|
|
7
|
+
* back is re-extracted, re-chunked and re-versioned like any other document.
|
|
8
|
+
*
|
|
9
|
+
* Split out of document-pipeline.ts.
|
|
10
|
+
*
|
|
11
|
+
* @module v1/cli/knowledge/okf-bundle
|
|
12
|
+
*/
|
|
13
|
+
import type { BatchIngestResult } from './document-types.js';
|
|
14
|
+
export declare function exportToOKF(outputDir: string, rootDir?: string, scope?: string): Promise<{
|
|
15
|
+
exported: number;
|
|
16
|
+
outputDir: string;
|
|
17
|
+
}>;
|
|
18
|
+
export declare function importFromOKF(bundleDir: string, scope?: string, rootDir?: string): Promise<BatchIngestResult>;
|
|
19
|
+
//# sourceMappingURL=okf-bundle.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"okf-bundle.d.ts","sourceRoot":"","sources":["../../../src/knowledge/okf-bundle.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAYH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAE7D,wBAAsB,WAAW,CAC/B,SAAS,EAAE,MAAM,EACjB,OAAO,SAAmB,EAC1B,KAAK,SAAW,GACf,OAAO,CAAC;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,CAAC,CA8DlD;AAID,wBAAsB,aAAa,CACjC,SAAS,EAAE,MAAM,EACjB,KAAK,SAAW,EAChB,OAAO,SAAmB,GACzB,OAAO,CAAC,iBAAiB,CAAC,CA4B5B"}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OKF bundles — export the indexed documents to a portable Markdown bundle
|
|
3
|
+
* (frontmatter + `index.md`), and ingest one back.
|
|
4
|
+
*
|
|
5
|
+
* A bundle is plain files, so a round trip goes back through the ordinary
|
|
6
|
+
* ingest path rather than restoring index records directly: whatever comes
|
|
7
|
+
* back is re-extracted, re-chunked and re-versioned like any other document.
|
|
8
|
+
*
|
|
9
|
+
* Split out of document-pipeline.ts.
|
|
10
|
+
*
|
|
11
|
+
* @module v1/cli/knowledge/okf-bundle
|
|
12
|
+
*/
|
|
13
|
+
import * as fs from 'node:fs';
|
|
14
|
+
import * as path from 'node:path';
|
|
15
|
+
import { extractText } from '../capabilities/cap-documents.js';
|
|
16
|
+
// Static import is safe and deliberate: memory-bridge imports only node builtins
|
|
17
|
+
// at module scope (everything heavy is lazy), and the project-root rule must not
|
|
18
|
+
// be duplicated — two copies of "which directory is this project" is exactly the
|
|
19
|
+
// bug this default exists to fix.
|
|
20
|
+
import { getProjectRoot } from '../memory/memory-bridge.js';
|
|
21
|
+
import { listDocuments } from './document-index.js';
|
|
22
|
+
import { ingestDocument, toFileEntry } from './document-ingest.js';
|
|
23
|
+
export async function exportToOKF(outputDir, rootDir = getProjectRoot(), scope = 'shared') {
|
|
24
|
+
const docs = listDocuments(rootDir, scope);
|
|
25
|
+
fs.mkdirSync(outputDir, { recursive: true });
|
|
26
|
+
let exported = 0;
|
|
27
|
+
const indexEntries = [];
|
|
28
|
+
for (const doc of docs) {
|
|
29
|
+
// Read original content
|
|
30
|
+
let content = '';
|
|
31
|
+
try {
|
|
32
|
+
if (fs.existsSync(doc.filePath)) {
|
|
33
|
+
const entry = toFileEntry(doc.filePath);
|
|
34
|
+
content = await extractText(entry);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
catch {
|
|
38
|
+
continue;
|
|
39
|
+
}
|
|
40
|
+
if (!content)
|
|
41
|
+
continue;
|
|
42
|
+
const title = path.basename(doc.filePath, path.extname(doc.filePath));
|
|
43
|
+
const ext = path.extname(doc.filePath).toLowerCase();
|
|
44
|
+
const relativePath = path.relative(rootDir, doc.filePath);
|
|
45
|
+
const slug = title.replace(/[^a-zA-Z0-9._-]+/g, '-').toLowerCase();
|
|
46
|
+
const outFile = path.join(outputDir, `${slug}.md`);
|
|
47
|
+
const yamlEscape = (s) => /[:"'[\]{}#&*!|>%@`]/.test(s) ? `"${s.replace(/\\/g, '\\\\').replace(/"/g, '\\"')}"` : s;
|
|
48
|
+
const frontmatter = [
|
|
49
|
+
'---',
|
|
50
|
+
`type: Document`,
|
|
51
|
+
`title: ${yamlEscape(title)}`,
|
|
52
|
+
`description: ${yamlEscape(`Extracted from ${path.basename(doc.filePath)}`)}`,
|
|
53
|
+
`resource: ${yamlEscape(relativePath)}`,
|
|
54
|
+
`tags: ["document", ${yamlEscape(ext.slice(1))}]`,
|
|
55
|
+
`timestamp: ${yamlEscape(doc.indexedAt)}`,
|
|
56
|
+
`contentHash: ${yamlEscape(doc.contentHash)}`,
|
|
57
|
+
`chunkCount: ${doc.chunkCount}`,
|
|
58
|
+
'---',
|
|
59
|
+
'',
|
|
60
|
+
].join('\n');
|
|
61
|
+
fs.writeFileSync(outFile, frontmatter + content, 'utf-8');
|
|
62
|
+
indexEntries.push(`* [${title}](${slug}.md) - ${path.basename(doc.filePath)} (${doc.chunkCount} chunks)`);
|
|
63
|
+
exported++;
|
|
64
|
+
}
|
|
65
|
+
// Write index.md
|
|
66
|
+
const indexContent = [
|
|
67
|
+
`# Knowledge Bundle`,
|
|
68
|
+
'',
|
|
69
|
+
`Exported from monomind on ${new Date().toISOString().slice(0, 10)}`,
|
|
70
|
+
'',
|
|
71
|
+
...indexEntries,
|
|
72
|
+
'',
|
|
73
|
+
].join('\n');
|
|
74
|
+
fs.writeFileSync(path.join(outputDir, 'index.md'), indexContent, 'utf-8');
|
|
75
|
+
return { exported, outputDir };
|
|
76
|
+
}
|
|
77
|
+
// ── OKF Import ─────────────────────────────────────────────────────
|
|
78
|
+
export async function importFromOKF(bundleDir, scope = 'shared', rootDir = getProjectRoot()) {
|
|
79
|
+
const resolved = path.resolve(bundleDir);
|
|
80
|
+
const files = fs
|
|
81
|
+
.readdirSync(resolved)
|
|
82
|
+
.filter((f) => f.endsWith('.md') && f !== 'index.md' && f !== 'log.md')
|
|
83
|
+
.map((f) => path.join(resolved, f));
|
|
84
|
+
const result = {
|
|
85
|
+
filesProcessed: 0,
|
|
86
|
+
filesSkipped: 0,
|
|
87
|
+
totalChunks: 0,
|
|
88
|
+
errors: [],
|
|
89
|
+
results: [],
|
|
90
|
+
};
|
|
91
|
+
for (const file of files) {
|
|
92
|
+
const r = await ingestDocument(file, scope, rootDir);
|
|
93
|
+
result.results.push(r);
|
|
94
|
+
if (r.skipped) {
|
|
95
|
+
result.filesSkipped++;
|
|
96
|
+
}
|
|
97
|
+
else {
|
|
98
|
+
result.filesProcessed++;
|
|
99
|
+
result.totalChunks += r.chunksIndexed;
|
|
100
|
+
}
|
|
101
|
+
if (r.error && !r.skipped)
|
|
102
|
+
result.errors.push(`${r.filePath}: ${r.error}`);
|
|
103
|
+
}
|
|
104
|
+
return result;
|
|
105
|
+
}
|
|
106
|
+
//# sourceMappingURL=okf-bundle.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"okf-bundle.js","sourceRoot":"","sources":["../../../src/knowledge/okf-bundle.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Per-profile capture stores (the browser track's profile feature).
|
|
3
|
+
*
|
|
4
|
+
* mono-agent has profiles — work, personal, a client — and a page captured
|
|
5
|
+
* from the browser can name the one it belongs to (`meta.profile` on the
|
|
6
|
+
* capture envelope). The promise that makes that worth having is negative:
|
|
7
|
+
* a page saved into `work` must NOT come back from a search of `personal`.
|
|
8
|
+
*
|
|
9
|
+
* WHICH MECHANISM, AND WHY. A store here is three things — a vector db
|
|
10
|
+
* directory (`dbPath`), a namespace, and the root the `doc-metadata.jsonl`
|
|
11
|
+
* lives under — and `scope` already decides all three (see
|
|
12
|
+
* document-pipeline: `namespace()`, `effectiveRoot()`, `storeDbPath()`).
|
|
13
|
+
* `global` is the existing proof: one scope value routes to a directory
|
|
14
|
+
* outside any project. A profile is the same shape, so it is expressed the
|
|
15
|
+
* same way — a scope of `profile:<id>` — rather than as a second, parallel
|
|
16
|
+
* "which brain" parameter threaded through ingest, search, cite and
|
|
17
|
+
* related. Nothing here is a new concept; it is one more value of an
|
|
18
|
+
* existing one.
|
|
19
|
+
*
|
|
20
|
+
* WHERE THE DIRECTORY GOES. Inside the global brain
|
|
21
|
+
* (`~/.monomind/global-brain/profiles/<id>`), not beside it. That is not
|
|
22
|
+
* cosmetic: `memory-bridge.getDbPath` refuses any dbPath outside the
|
|
23
|
+
* project, the per-project data dir, or the global brain, and — this is the
|
|
24
|
+
* dangerous part — a refused path does not throw, it silently falls back to
|
|
25
|
+
* the DEFAULT store. A profile brain anywhere else would quietly put every
|
|
26
|
+
* profile's captures in one database, which is the exact failure this
|
|
27
|
+
* feature exists to prevent. Being inside the global brain also inherits
|
|
28
|
+
* its protection from `cleanup --data`, which prunes `~/.monomind/projects`
|
|
29
|
+
* and deliberately never touches its sibling.
|
|
30
|
+
*
|
|
31
|
+
* UNTRUSTED INPUT. The profile id arrives from a browser extension and
|
|
32
|
+
* becomes a directory name. `isValidProfileId` is the guard, kept
|
|
33
|
+
* deliberately identical to Go's `profiledir.ValidProfileID` — the two
|
|
34
|
+
* sides of this contract must reject exactly the same strings.
|
|
35
|
+
*
|
|
36
|
+
* @module v1/cli/knowledge/profile-store
|
|
37
|
+
*/
|
|
38
|
+
/** Scopes of the form `profile:<id>` address one profile's own store. */
|
|
39
|
+
export declare const PROFILE_SCOPE_PREFIX = "profile:";
|
|
40
|
+
/**
|
|
41
|
+
* isValidProfileId mirrors `profiledir.ValidProfileID` (Go): non-empty, no
|
|
42
|
+
* path separator, no parent-directory component. Every other function here
|
|
43
|
+
* returns undefined for an id this rejects, so a hostile id can never
|
|
44
|
+
* become a path — not even a path that is then refused.
|
|
45
|
+
*/
|
|
46
|
+
export declare function isValidProfileId(id: unknown): id is string;
|
|
47
|
+
/** The scope value addressing one profile's store, or undefined. */
|
|
48
|
+
export declare function profileScope(id: unknown): string | undefined;
|
|
49
|
+
/** The profile id inside a `profile:<id>` scope, or undefined for any other. */
|
|
50
|
+
export declare function parseProfileScope(scope: unknown): string | undefined;
|
|
51
|
+
/** True for a scope that names a profile. */
|
|
52
|
+
export declare const isProfileScope: (scope: unknown) => boolean;
|
|
53
|
+
/**
|
|
54
|
+
* profileBrainDir is a profile's store directory — the value used BOTH as
|
|
55
|
+
* the dbPath and as the metadata root, exactly as the global brain uses one
|
|
56
|
+
* directory for both.
|
|
57
|
+
*
|
|
58
|
+
* It creates the directory, which a resolver would not normally do. The
|
|
59
|
+
* reason is specific: `memory-bridge.getDbPath` compares
|
|
60
|
+
* `fs.realpathSync(dbPath)` against `fs.realpathSync(globalBrainDir)`, and
|
|
61
|
+
* a path that does not exist yet cannot be realpath'd. On a machine where
|
|
62
|
+
* the home directory is reached through a symlink, the two sides would then
|
|
63
|
+
* resolve differently, the guard would reject the path, and — because that
|
|
64
|
+
* guard falls back instead of throwing — the profile's captures would land
|
|
65
|
+
* in the default store together with every other profile's. Creating the
|
|
66
|
+
* directory first makes both sides resolvable and the comparison honest.
|
|
67
|
+
*/
|
|
68
|
+
export declare function profileBrainDir(id: unknown): string | undefined;
|
|
69
|
+
/**
|
|
70
|
+
* profileStoreDir is profileBrainDir for a `profile:<id>` SCOPE, and
|
|
71
|
+
* undefined for every other scope — the single function
|
|
72
|
+
* `document-store`'s `effectiveRoot`/`storeDbPath` consult, so that the
|
|
73
|
+
* routing rule lives in one place and the pipeline keeps a two-line hook.
|
|
74
|
+
*
|
|
75
|
+
* DO NOT MOVE THIS DIRECTORY OUT OF THE GLOBAL BRAIN. The nesting looks
|
|
76
|
+
* arbitrary and is not: `memory-bridge.getDbPath` accepts a dbPath only
|
|
77
|
+
* inside the project, the per-project data dir, or the global brain, and a
|
|
78
|
+
* path it does not accept is NOT rejected — it SILENTLY RETURNS THE DEFAULT
|
|
79
|
+
* STORE. So a profile brain sited anywhere else (beside the global brain,
|
|
80
|
+
* under `~/.monoagent`, under the profile's own root) does not fail: every
|
|
81
|
+
* profile's captures quietly land in one database, `work` turns up in a
|
|
82
|
+
* `personal` search, and nothing anywhere reports a problem. The feature
|
|
83
|
+
* fails by succeeding. `src/__tests__/profile-store-dbpath.test.ts` holds
|
|
84
|
+
* both halves of that — this path surviving, and an outside path silently
|
|
85
|
+
* becoming the default.
|
|
86
|
+
*/
|
|
87
|
+
export declare function profileStoreDir(scope: unknown): string | undefined;
|
|
88
|
+
/**
|
|
89
|
+
* profileInboxDir is where that profile's captures land, as the Go side
|
|
90
|
+
* writes them: `~/.monoagent/profiles/<id>/.monomind/inbox`.
|
|
91
|
+
*
|
|
92
|
+
* Keyed by profile id alone. mono-agent lets a profile's root be moved
|
|
93
|
+
* (`profiles.root_dir`), and the capture inbox deliberately does NOT follow
|
|
94
|
+
* it on either side — see `ProfileInbox` in `internal/capture/profile.go`
|
|
95
|
+
* for why. This path and that one are the same rule written twice, which is
|
|
96
|
+
* the cost of the two repos agreeing about a directory at all.
|
|
97
|
+
*/
|
|
98
|
+
export declare function profileInboxDir(id: unknown): string | undefined;
|
|
99
|
+
/**
|
|
100
|
+
* profileInboxes lists the profile inboxes that exist on this machine, for
|
|
101
|
+
* a sweep that wants to ingest every profile's captures rather than only
|
|
102
|
+
* the shared inbox. Missing directories are simply absent; nothing here
|
|
103
|
+
* throws.
|
|
104
|
+
*/
|
|
105
|
+
export declare function profileInboxes(): Array<{
|
|
106
|
+
id: string;
|
|
107
|
+
inbox: string;
|
|
108
|
+
scope: string;
|
|
109
|
+
}>;
|
|
110
|
+
/**
|
|
111
|
+
* captureScope is the routing rule, applied once per ingest: a capture
|
|
112
|
+
* whose envelope names a profile belongs to that profile's store, whatever
|
|
113
|
+
* scope the caller reached for.
|
|
114
|
+
*
|
|
115
|
+
* The envelope wins on purpose. The profile was chosen by a person at save
|
|
116
|
+
* time, in the browser, and every automatic caller (`doc ingest` on a path
|
|
117
|
+
* outside any project, the dashboard's watcher, an inbox sweep) picks its
|
|
118
|
+
* scope from where the FILE is rather than from what it holds. A caller
|
|
119
|
+
* that genuinely means a particular store says so by passing a
|
|
120
|
+
* `profile:<id>` scope, which is returned untouched.
|
|
121
|
+
*/
|
|
122
|
+
export declare function captureScope(scope: string, filePath: string): string;
|
|
123
|
+
/**
|
|
124
|
+
* envelopeProfile reads the `profile` out of the capture envelope holding
|
|
125
|
+
* `filePath`, if there is one. Defensive on the same terms as the rest of
|
|
126
|
+
* capture-envelope: `meta.json` is written by a browser extension on a
|
|
127
|
+
* machine we do not control, so every failure — absent, oversized,
|
|
128
|
+
* truncated, wrong-typed, or an id that could escape a directory — is
|
|
129
|
+
* "this capture names no profile", never a thrown error.
|
|
130
|
+
*/
|
|
131
|
+
export declare function envelopeProfile(filePath: string): string | undefined;
|
|
132
|
+
/** A human-readable name for a scope, for a listing or a search result. */
|
|
133
|
+
export declare function describeScope(scope: string): string;
|
|
134
|
+
//# sourceMappingURL=profile-store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"profile-store.d.ts","sourceRoot":"","sources":["../../../src/knowledge/profile-store.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AAMH,yEAAyE;AACzE,eAAO,MAAM,oBAAoB,aAAa,CAAC;AAiB/C;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,EAAE,EAAE,OAAO,GAAG,EAAE,IAAI,MAAM,CAO1D;AAED,oEAAoE;AACpE,wBAAgB,YAAY,CAAC,EAAE,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAE5D;AAED,gFAAgF;AAChF,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAIpE;AAED,6CAA6C;AAC7C,eAAO,MAAM,cAAc,UAAW,OAAO,KAAG,OAAiD,CAAC;AAKlG;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,eAAe,CAAC,EAAE,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAa/D;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAGlE;AAED;;;;;;;;;GASG;AACH,wBAAgB,eAAe,CAAC,EAAE,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAG/D;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,IAAI,KAAK,CAAC;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC,CAqBpF;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAIpE;AAKD;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAYpE;AAED,2EAA2E;AAC3E,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAGnD"}
|