@poco-ai/agentero-dsh-host 0.0.0-stage → 0.1.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.
Files changed (67) hide show
  1. package/lib/bookmarks-write.d.ts +24 -0
  2. package/lib/bookmarks-write.js +181 -0
  3. package/lib/bookmarks-write.js.map +1 -0
  4. package/lib/catalog.d.ts +28 -0
  5. package/lib/catalog.js +58 -0
  6. package/lib/catalog.js.map +1 -0
  7. package/lib/cli-run.d.ts +15 -0
  8. package/lib/cli-run.js +102 -0
  9. package/lib/cli-run.js.map +1 -0
  10. package/lib/client/index.d.ts +71 -0
  11. package/lib/client/settings-model.d.ts +28 -0
  12. package/lib/client/settings.d.ts +27 -0
  13. package/lib/client/ui/button.d.ts +10 -0
  14. package/lib/client/ui/input.d.ts +2 -0
  15. package/lib/client/utils.d.ts +2 -0
  16. package/lib/client.js +4071 -0
  17. package/lib/index.d.ts +55 -0
  18. package/lib/index.js +1103 -0
  19. package/lib/index.js.map +1 -0
  20. package/lib/marks-store.d.ts +80 -0
  21. package/lib/marks-store.js +393 -0
  22. package/lib/marks-store.js.map +1 -0
  23. package/lib/notes-files.d.ts +47 -0
  24. package/lib/notes-files.js +427 -0
  25. package/lib/notes-files.js.map +1 -0
  26. package/lib/pdf-file.d.ts +23 -0
  27. package/lib/pdf-file.js +84 -0
  28. package/lib/pdf-file.js.map +1 -0
  29. package/lib/recommend.d.ts +61 -0
  30. package/lib/recommend.js +864 -0
  31. package/lib/recommend.js.map +1 -0
  32. package/lib/tools.d.ts +8 -0
  33. package/lib/tools.js +204 -0
  34. package/lib/tools.js.map +1 -0
  35. package/lib/translate.d.ts +70 -0
  36. package/lib/translate.js +80 -0
  37. package/lib/translate.js.map +1 -0
  38. package/lib/translation/batches.d.ts +21 -0
  39. package/lib/translation/batches.js +88 -0
  40. package/lib/translation/batches.js.map +1 -0
  41. package/lib/translation/chunks.d.ts +2 -0
  42. package/lib/translation/chunks.js +36 -0
  43. package/lib/translation/chunks.js.map +1 -0
  44. package/lib/translation/mask.d.ts +22 -0
  45. package/lib/translation/mask.js +69 -0
  46. package/lib/translation/mask.js.map +1 -0
  47. package/lib/translation/pipeline.d.ts +3 -0
  48. package/lib/translation/pipeline.js +119 -0
  49. package/lib/translation/pipeline.js.map +1 -0
  50. package/lib/translation/preserved-links.d.ts +26 -0
  51. package/lib/translation/preserved-links.js +127 -0
  52. package/lib/translation/preserved-links.js.map +1 -0
  53. package/lib/translation/prompt.d.ts +99 -0
  54. package/lib/translation/prompt.js +224 -0
  55. package/lib/translation/prompt.js.map +1 -0
  56. package/lib/translation/retry.d.ts +3 -0
  57. package/lib/translation/retry.js +30 -0
  58. package/lib/translation/retry.js.map +1 -0
  59. package/lib/translation/sentences.d.ts +5 -0
  60. package/lib/translation/sentences.js +77 -0
  61. package/lib/translation/sentences.js.map +1 -0
  62. package/lib/vault.d.ts +21 -0
  63. package/lib/vault.js +69 -0
  64. package/lib/vault.js.map +1 -0
  65. package/package.json +44 -3
  66. package/src/translation/MOTIF-LICENSE.txt +21 -0
  67. package/README.md +0 -3
@@ -0,0 +1,24 @@
1
+ /** One outline node as the browser sends it. */
2
+ export interface BookmarkNode {
3
+ /** Original tree path, or null for a node this session added. */
4
+ origin: string | null;
5
+ /** Title read from the PDF, used to detect a stale edit. */
6
+ originalTitle?: string;
7
+ title: string;
8
+ /** Zero-based page for new or retargeted nodes. */
9
+ pageIndex?: number;
10
+ children: BookmarkNode[];
11
+ }
12
+ /**
13
+ * Validate an untrusted outline payload.
14
+ * @param value - parsed JSON body field.
15
+ * @returns normalized nodes, or undefined when malformed or too large.
16
+ */
17
+ export declare function bookmarkNodesFrom(value: unknown): BookmarkNode[] | undefined;
18
+ /**
19
+ * Bake `nodes` into `bytes` as the document outline.
20
+ * @param bytes - original PDF.
21
+ * @param nodes - desired tree.
22
+ * @returns a new PDF; the input is not mutated.
23
+ */
24
+ export declare function writePdfBookmarks(bytes: Uint8Array, nodes: BookmarkNode[]): Promise<Uint8Array>;
@@ -0,0 +1,181 @@
1
+ /**
2
+ * Rewrite a PDF's outline (bookmarks) without touching annotations.
3
+ *
4
+ * Same contract as the desktop app: edit the original outline dictionaries so
5
+ * destinations, actions and styling survive; refuse signed documents because
6
+ * rewriting them would invalidate the signature.
7
+ */
8
+ import { PDFDict, PDFDocument, PDFHexString, PDFName, PDFNumber, PDFRef, PDFString, } from 'pdf-lib';
9
+ const MAX_NODES = 2000;
10
+ const MAX_DEPTH = 16;
11
+ const MAX_TITLE = 2000;
12
+ function isRecord(value) {
13
+ return typeof value === 'object' && value !== null && !Array.isArray(value);
14
+ }
15
+ /**
16
+ * Validate an untrusted outline payload.
17
+ * @param value - parsed JSON body field.
18
+ * @returns normalized nodes, or undefined when malformed or too large.
19
+ */
20
+ export function bookmarkNodesFrom(value) {
21
+ let count = 0;
22
+ let bad = false;
23
+ const parse = (input, depth) => {
24
+ if (!Array.isArray(input) || depth > MAX_DEPTH) {
25
+ bad = true;
26
+ return [];
27
+ }
28
+ const nodes = [];
29
+ for (const item of input) {
30
+ if (!isRecord(item)) {
31
+ bad = true;
32
+ continue;
33
+ }
34
+ const title = typeof item.title === 'string' ? item.title.trim() : '';
35
+ const origin = typeof item.origin === 'string' ? item.origin : null;
36
+ const originalTitle = typeof item.originalTitle === 'string' ? item.originalTitle : undefined;
37
+ const pageIndex = typeof item.pageIndex === 'number' ? item.pageIndex : undefined;
38
+ if (title === '' || title.length > MAX_TITLE) {
39
+ bad = true;
40
+ continue;
41
+ }
42
+ if (pageIndex !== undefined && (!Number.isInteger(pageIndex) || pageIndex < 0)) {
43
+ bad = true;
44
+ continue;
45
+ }
46
+ if (origin !== null && origin !== '') {
47
+ const segments = origin.split('.');
48
+ if (!segments.every(segment => /^\d+$/.test(segment))) {
49
+ bad = true;
50
+ continue;
51
+ }
52
+ }
53
+ count += 1;
54
+ if (count > MAX_NODES) {
55
+ bad = true;
56
+ return [];
57
+ }
58
+ nodes.push({
59
+ origin: origin === '' ? null : origin,
60
+ ...(originalTitle === undefined ? {} : { originalTitle }),
61
+ title,
62
+ ...(pageIndex === undefined ? {} : { pageIndex }),
63
+ children: parse(item.children ?? [], depth + 1),
64
+ });
65
+ }
66
+ return nodes;
67
+ };
68
+ const nodes = parse(value, 0);
69
+ return bad ? undefined : nodes;
70
+ }
71
+ /**
72
+ * Bake `nodes` into `bytes` as the document outline.
73
+ * @param bytes - original PDF.
74
+ * @param nodes - desired tree.
75
+ * @returns a new PDF; the input is not mutated.
76
+ */
77
+ export async function writePdfBookmarks(bytes, nodes) {
78
+ const pdf = await PDFDocument.load(bytes, { updateMetadata: false });
79
+ const name = PDFName.of;
80
+ for (const [, object] of pdf.context.enumerateIndirectObjects()) {
81
+ if (object instanceof PDFDict &&
82
+ (object.has(name('ByteRange')) || object.get(name('FT')) === name('Sig'))) {
83
+ throw new Error('protected');
84
+ }
85
+ }
86
+ const originals = new Map();
87
+ const seen = new Set();
88
+ const root = pdf.catalog.lookupMaybe(name('Outlines'), PDFDict);
89
+ function read(parent, prefix) {
90
+ let item = parent.get(name('First'));
91
+ let index = 0;
92
+ while (item) {
93
+ if (!(item instanceof PDFRef) || seen.has(item.toString()))
94
+ throw new Error('unsupported');
95
+ seen.add(item.toString());
96
+ const dict = pdf.context.lookup(item, PDFDict);
97
+ const action = dict.lookupMaybe(name('A'), PDFDict);
98
+ if (action && (action.get(name('S')) !== name('GoTo') || action.has(name('Next')))) {
99
+ throw new Error('unsupported');
100
+ }
101
+ const key = `${prefix}${index++}`;
102
+ originals.set(key, { dict, ref: item });
103
+ read(dict, `${key}.`);
104
+ item = dict.get(name('Next'));
105
+ }
106
+ }
107
+ if (root)
108
+ read(root, '');
109
+ const outlines = root ?? pdf.context.obj({ Type: 'Outlines' });
110
+ const rootRef = pdf.context.getObjectRef(outlines) ?? pdf.context.register(outlines);
111
+ const pages = pdf.getPages();
112
+ const used = new Set();
113
+ function write(items, parent, parentRef) {
114
+ const entries = items.map((node) => {
115
+ if (!node.title.trim())
116
+ throw new Error('invalid');
117
+ if (node.origin !== null &&
118
+ (used.has(node.origin) || !originals.has(node.origin))) {
119
+ throw new Error('unsupported');
120
+ }
121
+ if (node.origin !== null)
122
+ used.add(node.origin);
123
+ const original = node.origin === null ? undefined : originals.get(node.origin);
124
+ if (original && node.originalTitle !== undefined) {
125
+ const title = original.dict.lookup(name('Title'));
126
+ if (!(title instanceof PDFString || title instanceof PDFHexString) ||
127
+ title.decodeText() !== node.originalTitle) {
128
+ throw new Error('unsupported');
129
+ }
130
+ }
131
+ const dict = original?.dict ?? pdf.context.obj({});
132
+ const ref = original?.ref ?? pdf.context.register(dict);
133
+ dict.set(name('Title'), PDFHexString.fromText(node.title.trim()));
134
+ dict.set(name('Parent'), parentRef);
135
+ if (node.pageIndex !== undefined) {
136
+ if (!Number.isInteger(node.pageIndex) || !pages[node.pageIndex])
137
+ throw new Error('invalid');
138
+ dict.delete(name('A'));
139
+ dict.set(name('Dest'), pdf.context.obj([pages[node.pageIndex].ref, 'Fit']));
140
+ }
141
+ else if (!original) {
142
+ throw new Error('invalid');
143
+ }
144
+ return { node, dict, ref };
145
+ });
146
+ parent.delete(name('First'));
147
+ parent.delete(name('Last'));
148
+ if (entries.length) {
149
+ parent.set(name('First'), entries[0].ref);
150
+ parent.set(name('Last'), entries[entries.length - 1].ref);
151
+ }
152
+ let visible = 0;
153
+ entries.forEach(({ node, dict, ref }, i) => {
154
+ dict.delete(name('Prev'));
155
+ dict.delete(name('Next'));
156
+ if (i > 0)
157
+ dict.set(name('Prev'), entries[i - 1].ref);
158
+ if (i + 1 < entries.length)
159
+ dict.set(name('Next'), entries[i + 1].ref);
160
+ const closed = (dict.lookupMaybe(name('Count'), PDFNumber)?.asNumber() ?? 0) < 0;
161
+ const children = write(node.children, dict, ref);
162
+ dict.delete(name('Count'));
163
+ if (children)
164
+ dict.set(name('Count'), PDFNumber.of(closed ? -children : children));
165
+ visible += 1 + (closed ? 0 : children);
166
+ });
167
+ return visible;
168
+ }
169
+ const count = write(nodes, outlines, rootRef);
170
+ outlines.set(name('Count'), PDFNumber.of(count));
171
+ if (nodes.length)
172
+ pdf.catalog.set(name('Outlines'), rootRef);
173
+ else
174
+ pdf.catalog.delete(name('Outlines'));
175
+ const saved = await pdf.save({ updateFieldAppearances: false });
176
+ const check = await PDFDocument.load(saved, { updateMetadata: false });
177
+ if (check.getPageCount() !== pages.length)
178
+ throw new Error('invalid');
179
+ return saved;
180
+ }
181
+ //# sourceMappingURL=bookmarks-write.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bookmarks-write.js","sourceRoot":"","sources":["../src/bookmarks-write.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,28 @@
1
+ import type { ChildProcess } from 'node:child_process';
2
+ export interface CatalogSettings {
3
+ vault: string;
4
+ agenteroBin: string;
5
+ }
6
+ export type CatalogResult = {
7
+ status: 200;
8
+ raw: string;
9
+ } | {
10
+ status: 502;
11
+ error: string;
12
+ };
13
+ /** `agentero import id`. `text` is an arXiv id, DOI, or URL. */
14
+ export declare function importId(settings: CatalogSettings, text: string, children: Set<ChildProcess>): Promise<CatalogResult>;
15
+ /** `agentero import bib -`, with the BibTeX document on stdin. */
16
+ export declare function importBib(settings: CatalogSettings, text: string, children: Set<ChildProcess>): Promise<CatalogResult>;
17
+ /** `agentero export bib`. JSON `data.content` is the BibTeX. */
18
+ export declare function exportBib(settings: CatalogSettings, children: Set<ChildProcess>): Promise<CatalogResult>;
19
+ /** Append or remove one tag. The ref is a vault-relative paper path or id. */
20
+ export declare function changeTag(settings: CatalogSettings, ref: string, op: 'add' | 'rm', tag: string, children: Set<ChildProcess>): Promise<CatalogResult>;
21
+ /** Move a paper directory to the vault recycle bin. Does not pass `--files`. */
22
+ export declare function deletePaper(settings: CatalogSettings, ref: string, children: Set<ChildProcess>): Promise<CatalogResult>;
23
+ /** Set catalog `is_read`. */
24
+ export declare function setRead(settings: CatalogSettings, ref: string, read: boolean, children: Set<ChildProcess>): Promise<CatalogResult>;
25
+ /** Download the PDF for a paper already in the catalog. */
26
+ export declare function downloadPaper(settings: CatalogSettings, ref: string, children: Set<ChildProcess>): Promise<CatalogResult>;
27
+ /** Rank a short arXiv list for one keyword. Already-imported ids are dropped by the CLI. */
28
+ export declare function discoverArxiv(settings: CatalogSettings, keyword: string, children: Set<ChildProcess>): Promise<CatalogResult>;
package/lib/catalog.js ADDED
@@ -0,0 +1,58 @@
1
+ import { cliFailure, runAgentero } from './cli-run.js';
2
+ /** Network-backed CLI calls: import, download, BibTeX, arXiv discovery. */
3
+ const NETWORK_MS = 120_000;
4
+ /** Local catalog edits. */
5
+ const LOCAL_MS = 20_000;
6
+ async function cliJson(settings, args, timeoutMs, label, children, stdin) {
7
+ const result = await runAgentero(settings.agenteroBin, [
8
+ '--vault', settings.vault,
9
+ '--json',
10
+ ...args,
11
+ ], timeoutMs, children, stdin);
12
+ if (result.timedOut || result.spawnError !== undefined || result.code !== 0) {
13
+ return { status: 502, error: cliFailure(result, label) };
14
+ }
15
+ try {
16
+ JSON.parse(result.stdout);
17
+ }
18
+ catch {
19
+ return { status: 502, error: `${label} returned invalid JSON` };
20
+ }
21
+ return { status: 200, raw: result.stdout };
22
+ }
23
+ /** `agentero import id`. `text` is an arXiv id, DOI, or URL. */
24
+ export function importId(settings, text, children) {
25
+ return cliJson(settings, ['import', 'id', '--', text], NETWORK_MS, 'agentero import id', children);
26
+ }
27
+ /** `agentero import bib -`, with the BibTeX document on stdin. */
28
+ export function importBib(settings, text, children) {
29
+ return cliJson(settings, ['import', 'bib', '-'], NETWORK_MS, 'agentero import bib', children, text);
30
+ }
31
+ /** `agentero export bib`. JSON `data.content` is the BibTeX. */
32
+ export function exportBib(settings, children) {
33
+ return cliJson(settings, ['export', 'bib'], NETWORK_MS, 'agentero export bib', children);
34
+ }
35
+ /** Append or remove one tag. The ref is a vault-relative paper path or id. */
36
+ export function changeTag(settings, ref, op, tag, children) {
37
+ return cliJson(settings, ['paper', 'tag', op, ref, '--', tag], LOCAL_MS, 'agentero paper tag', children);
38
+ }
39
+ /** Move a paper directory to the vault recycle bin. Does not pass `--files`. */
40
+ export function deletePaper(settings, ref, children) {
41
+ return cliJson(settings, ['paper', 'delete', ref], LOCAL_MS, 'agentero paper delete', children);
42
+ }
43
+ /** Set catalog `is_read`. */
44
+ export function setRead(settings, ref, read, children) {
45
+ const args = ['paper', 'set-read', ref];
46
+ if (!read)
47
+ args.push('--false');
48
+ return cliJson(settings, args, LOCAL_MS, 'agentero paper set-read', children);
49
+ }
50
+ /** Download the PDF for a paper already in the catalog. */
51
+ export function downloadPaper(settings, ref, children) {
52
+ return cliJson(settings, ['paper', 'download', ref], NETWORK_MS, 'agentero paper download', children);
53
+ }
54
+ /** Rank a short arXiv list for one keyword. Already-imported ids are dropped by the CLI. */
55
+ export function discoverArxiv(settings, keyword, children) {
56
+ return cliJson(settings, ['discover', 'arxiv', '--keyword', keyword, '--top', '8'], NETWORK_MS, 'agentero discover arxiv', children);
57
+ }
58
+ //# sourceMappingURL=catalog.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"catalog.js","sourceRoot":"","sources":["../src/catalog.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ import { type ChildProcess } from 'node:child_process';
2
+ export interface CliRunResult {
3
+ code: number | null;
4
+ stdout: string;
5
+ stderr: string;
6
+ timedOut: boolean;
7
+ spawnError?: string;
8
+ }
9
+ /**
10
+ * Run `agentero` with an argument array. `shell` stays off.
11
+ * The child is tracked so unload can kill it.
12
+ */
13
+ export declare function runAgentero(bin: string, args: readonly string[], timeoutMs: number, children: Set<ChildProcess>, stdin?: string): Promise<CliRunResult>;
14
+ /** Human-readable failure. JSON mode prints `{ ok:false, error:{ message } }` on stdout. */
15
+ export declare function cliFailure(result: CliRunResult, label: string): string;
package/lib/cli-run.js ADDED
@@ -0,0 +1,102 @@
1
+ import { spawn } from 'node:child_process';
2
+ /**
3
+ * Run `agentero` with an argument array. `shell` stays off.
4
+ * The child is tracked so unload can kill it.
5
+ */
6
+ export function runAgentero(bin, args, timeoutMs, children, stdin) {
7
+ return new Promise((resolve) => {
8
+ let child;
9
+ try {
10
+ child = spawn(bin, args, {
11
+ shell: false,
12
+ windowsHide: true,
13
+ stdio: [stdin === undefined ? 'ignore' : 'pipe', 'pipe', 'pipe'],
14
+ });
15
+ }
16
+ catch (error) {
17
+ resolve({
18
+ code: null,
19
+ stdout: '',
20
+ stderr: '',
21
+ timedOut: false,
22
+ spawnError: error instanceof Error ? error.message : String(error),
23
+ });
24
+ return;
25
+ }
26
+ children.add(child);
27
+ if (stdin !== undefined)
28
+ child.stdin?.end(stdin);
29
+ const stdout = [];
30
+ const stderr = [];
31
+ let settled = false;
32
+ let timedOut = false;
33
+ let spawnError;
34
+ let timer;
35
+ const finish = () => {
36
+ if (settled)
37
+ return;
38
+ settled = true;
39
+ if (timer !== undefined)
40
+ clearTimeout(timer);
41
+ resolve({
42
+ code: child.exitCode,
43
+ stdout: Buffer.concat(stdout).toString('utf8'),
44
+ stderr: Buffer.concat(stderr).toString('utf8'),
45
+ timedOut,
46
+ ...(spawnError !== undefined ? { spawnError } : {}),
47
+ });
48
+ };
49
+ timer = setTimeout(() => {
50
+ timedOut = true;
51
+ try {
52
+ child.kill();
53
+ }
54
+ catch {
55
+ // The child already exited.
56
+ }
57
+ finish();
58
+ }, timeoutMs);
59
+ child.stdout?.on('data', (chunk) => { stdout.push(chunk); });
60
+ child.stderr?.on('data', (chunk) => { stderr.push(chunk); });
61
+ child.on('error', (error) => {
62
+ spawnError = error.message;
63
+ finish();
64
+ });
65
+ child.on('close', () => {
66
+ children.delete(child);
67
+ finish();
68
+ });
69
+ });
70
+ }
71
+ /** Human-readable failure. JSON mode prints `{ ok:false, error:{ message } }` on stdout. */
72
+ export function cliFailure(result, label) {
73
+ if (result.timedOut)
74
+ return `${label} timed out`;
75
+ if (result.spawnError !== undefined && result.spawnError !== '')
76
+ return result.spawnError;
77
+ const stderr = result.stderr.trim();
78
+ if (stderr !== '')
79
+ return stderr;
80
+ const stdout = result.stdout.trim();
81
+ if (stdout !== '') {
82
+ try {
83
+ const parsed = JSON.parse(stdout);
84
+ if (parsed !== null && typeof parsed === 'object' && 'error' in parsed) {
85
+ const error = parsed.error;
86
+ if (typeof error === 'string' && error !== '')
87
+ return error;
88
+ if (error !== null && typeof error === 'object' && 'message' in error && typeof error.message === 'string') {
89
+ return error.message;
90
+ }
91
+ }
92
+ }
93
+ catch {
94
+ // Fall through to the raw stdout.
95
+ }
96
+ return stdout.slice(0, 500);
97
+ }
98
+ if (result.code === null)
99
+ return `${label} failed`;
100
+ return `agentero exited with code ${result.code}`;
101
+ }
102
+ //# sourceMappingURL=cli-run.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli-run.js","sourceRoot":"","sources":["../src/cli-run.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,71 @@
1
+ import type { Context } from '@deepseek-ai/cordis';
2
+ export interface VaultInfo {
3
+ path: string;
4
+ name: string;
5
+ scope: string;
6
+ recentVaults: {
7
+ path: string;
8
+ name: string;
9
+ }[];
10
+ canPick: boolean;
11
+ }
12
+ /** Document a later panel can open. */
13
+ export type AgenteroOpenerKind = 'paper' | 'note';
14
+ /** Open one document id. The host does not register openers in this step. */
15
+ export type AgenteroOpener = (id: string) => void;
16
+ /** Browser service other Agentero panels reach through `ctx.get('agentero')`. */
17
+ export interface AgenteroClient {
18
+ getVault(): Promise<VaultInfo>;
19
+ /** Requests remain tied to the source opened by this page, even if another page switches vaults. */
20
+ request(url: string, init?: RequestInit): Promise<Response>;
21
+ /**
22
+ * Replace the opener for one kind.
23
+ * @param kind - Document kind.
24
+ * @param opener - Called by {@link AgenteroClient.open}.
25
+ * @returns Disposer that removes this opener when it is still current.
26
+ */
27
+ registerOpener(kind: AgenteroOpenerKind, opener: AgenteroOpener): () => void;
28
+ /**
29
+ * Open a document when an opener is registered.
30
+ * @param kind - Document kind.
31
+ * @param id - Document id.
32
+ * @returns False when no opener is registered for `kind`.
33
+ */
34
+ open(kind: AgenteroOpenerKind, id: string): boolean;
35
+ }
36
+ /** Owner props for the notes column beside a PDF page. */
37
+ export interface PdfNotesOwner {
38
+ /** Vault-relative paper directory, for example `papers/1706.03762`. */
39
+ paperPath: string;
40
+ }
41
+ declare module '@deepseek-ai/dsh-client-ui-slots' {
42
+ interface LocaleNamespaceMap {
43
+ 'agentero.host': 'vaultChanged' | 'unavailable';
44
+ }
45
+ interface SlotMap {
46
+ /**
47
+ * Single notes column declared by the PDF panel.
48
+ * The notes plugin fills it. An empty slot leaves the page full width.
49
+ */
50
+ 'agentero.pdf.notes': {
51
+ kind: 'single';
52
+ scope: 'session';
53
+ owner: PdfNotesOwner;
54
+ };
55
+ }
56
+ }
57
+ declare module '@deepseek-ai/cordis' {
58
+ interface Context {
59
+ /** Agentero document openers. Panels register later. */
60
+ agentero: AgenteroClient;
61
+ }
62
+ }
63
+ /** Browser plugin name. The service key is the same name. */
64
+ export declare const name = "agentero";
65
+ /** Locale, slots, and the shared configuration form serve the panels and Settings. */
66
+ export declare const inject: string[];
67
+ /**
68
+ * Provide the `agentero` service. Openers stay empty until a later step.
69
+ * @param ctx - Browser plugin context.
70
+ */
71
+ export declare function apply(ctx: Context): void;
@@ -0,0 +1,28 @@
1
+ /** Staged CLI field over the Host's `agentero-host` entry. */
2
+ import type { SnapshotStore } from '@deepseek-ai/dsh-client-store';
3
+ import { type SettingsFieldState, type SettingsFormActions, type SettingsFormScope, type SettingsFormShell } from '@deepseek-ai/dsh-client-ui-primitives';
4
+ /** Fields this page edits; the knowledge base persists through its own validated route. */
5
+ export interface AgenteroCliSettings {
6
+ agenteroBin?: string;
7
+ }
8
+ /** Draft and shared form status. */
9
+ export interface AgenteroSettingsState extends SettingsFormShell {
10
+ agenteroBin: SettingsFieldState;
11
+ }
12
+ /** Registration-side observable and edit/save actions. */
13
+ export interface AgenteroSettingsFace extends SettingsFormActions {
14
+ hooks: {
15
+ agenteroSettings: SnapshotStore<AgenteroSettingsState>;
16
+ };
17
+ }
18
+ /** Stages CLI edits over the `agentero-host` namespace. */
19
+ export declare class AgenteroSettingsModel {
20
+ private readonly form;
21
+ private readonly state;
22
+ /** @param scope - the shared configuration form of the `agentero-host` entry. */
23
+ constructor(scope: SettingsFormScope<AgenteroCliSettings>);
24
+ /** Build the face the settings section injects. */
25
+ inject(): AgenteroSettingsFace;
26
+ /** Release the entry subscription. */
27
+ dispose(): void;
28
+ }
@@ -0,0 +1,27 @@
1
+ /** Agentero's section in the dsh Settings dialog. */
2
+ import type { InjectFace, PropsLocale } from '@deepseek-ai/dsh-client-ui-slots';
3
+ import type { AgenteroSettingsFace } from './settings-model';
4
+ /** Vault facts the page reads before offering the native picker. */
5
+ export interface SettingsVault {
6
+ path: string;
7
+ canPick: boolean;
8
+ }
9
+ /** Host calls the page uses for the vault; the CLI field persists through the form face. */
10
+ export interface SettingsFace {
11
+ loadVault(): Promise<SettingsVault>;
12
+ pickVault(): Promise<string | null>;
13
+ saveVault(path: string): Promise<void>;
14
+ reload(): void;
15
+ }
16
+ export type AgenteroFace = SettingsFace & AgenteroSettingsFace;
17
+ export type AgenteroSettingsProps = PropsLocale<'agentero.settings'> & InjectFace<AgenteroFace>;
18
+ export type SettingsLocaleKey = 'nav' | 'vaultTitle' | 'vaultPlaceholder' | 'choose' | 'apply' | 'applying' | 'invalidVault' | 'cliTitle' | 'cliPlaceholder' | 'save' | 'saving' | 'saved' | 'saveFailed' | 'reset' | 'loadFailed' | 'unavailable';
19
+ export declare const en: Record<SettingsLocaleKey, string>;
20
+ export declare const zh: Record<SettingsLocaleKey, string>;
21
+ declare module '@deepseek-ai/dsh-client-ui-slots' {
22
+ interface LocaleNamespaceMap {
23
+ 'agentero.settings': SettingsLocaleKey;
24
+ }
25
+ }
26
+ /** Render the knowledge base and CLI fields inside the Settings dialog. */
27
+ export declare function AgenteroSettings(props: AgenteroSettingsProps): import("react").JSX.Element;
@@ -0,0 +1,10 @@
1
+ import { type VariantProps } from 'class-variance-authority';
2
+ import type * as React from 'react';
3
+ declare const buttonVariants: (props?: ({
4
+ variant?: "default" | "outline" | "secondary" | "ghost" | "destructive" | "link" | null | undefined;
5
+ size?: "default" | "sm" | "icon" | null | undefined;
6
+ } & import("class-variance-authority/types").ClassProp) | undefined) => string;
7
+ declare function Button({ className, variant, size, asChild, ...props }: React.ComponentProps<'button'> & VariantProps<typeof buttonVariants> & {
8
+ asChild?: boolean;
9
+ }): React.JSX.Element;
10
+ export { Button, buttonVariants };
@@ -0,0 +1,2 @@
1
+ declare const Input: import("react").ForwardRefExoticComponent<Omit<import("react").DetailedHTMLProps<import("react").InputHTMLAttributes<HTMLInputElement>, HTMLInputElement>, "ref"> & import("react").RefAttributes<HTMLInputElement>>;
2
+ export { Input };
@@ -0,0 +1,2 @@
1
+ import { type ClassValue } from 'clsx';
2
+ export declare function cn(...inputs: ClassValue[]): string;