dsh-reference-anything 0.3.1 → 0.3.2

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 (107) hide show
  1. package/LICENSE +22 -22
  2. package/NOTICE.md +52 -25
  3. package/README.md +334 -285
  4. package/cordis.patch.yml +89 -18
  5. package/lib/client.js +13530 -517
  6. package/lib/contract.d.ts +155 -3
  7. package/lib/contract.js +68 -4
  8. package/lib/download-directory.d.ts +18 -0
  9. package/lib/download-directory.js +55 -0
  10. package/lib/errors.d.ts +4 -0
  11. package/lib/host.d.ts +96 -3
  12. package/lib/host.js +88 -5
  13. package/lib/index.d.ts +22 -2
  14. package/lib/index.js +57 -7
  15. package/lib/opencli.d.ts +5 -3
  16. package/lib/opencli.js +13 -6
  17. package/lib/openlist/host.d.ts +157 -0
  18. package/lib/openlist/host.js +873 -0
  19. package/lib/openlist/index.d.ts +84 -0
  20. package/lib/openlist/index.js +507 -0
  21. package/lib/render.d.ts +12 -7
  22. package/lib/render.js +27 -21
  23. package/lib/sources/cloud-drive/cache.d.ts +60 -0
  24. package/lib/sources/cloud-drive/cache.js +107 -0
  25. package/lib/sources/cloud-drive/index.d.ts +190 -0
  26. package/lib/sources/cloud-drive/index.js +526 -0
  27. package/lib/sources/cloud-drive/providers/http.d.ts +27 -0
  28. package/lib/sources/cloud-drive/providers/http.js +73 -0
  29. package/lib/sources/cloud-drive/providers/openlist.d.ts +59 -0
  30. package/lib/sources/cloud-drive/providers/openlist.js +535 -0
  31. package/lib/sources/cloud-drive/registry.d.ts +53 -0
  32. package/lib/sources/cloud-drive/registry.js +101 -0
  33. package/lib/sources/cloud-drive/types.d.ts +169 -0
  34. package/lib/sources/cloud-drive/types.js +17 -0
  35. package/lib/sources/file.d.ts +2 -0
  36. package/lib/sources/file.js +2 -0
  37. package/lib/sources/local-agent/adapters/claude-code.d.ts +16 -0
  38. package/lib/sources/local-agent/adapters/claude-code.js +171 -0
  39. package/lib/sources/local-agent/adapters/codex.d.ts +20 -0
  40. package/lib/sources/local-agent/adapters/codex.js +204 -0
  41. package/lib/sources/local-agent/adapters/cursor.d.ts +23 -0
  42. package/lib/sources/local-agent/adapters/cursor.js +121 -0
  43. package/lib/sources/local-agent/adapters/gemini-cli.d.ts +20 -0
  44. package/lib/sources/local-agent/adapters/gemini-cli.js +141 -0
  45. package/lib/sources/local-agent/adapters/grokbuild.d.ts +22 -0
  46. package/lib/sources/local-agent/adapters/grokbuild.js +76 -0
  47. package/lib/sources/local-agent/adapters/hermes.d.ts +19 -0
  48. package/lib/sources/local-agent/adapters/hermes.js +85 -0
  49. package/lib/sources/local-agent/adapters/kimi.d.ts +28 -0
  50. package/lib/sources/local-agent/adapters/kimi.js +261 -0
  51. package/lib/sources/local-agent/adapters/openclaw.d.ts +21 -0
  52. package/lib/sources/local-agent/adapters/openclaw.js +120 -0
  53. package/lib/sources/local-agent/adapters/opencode.d.ts +44 -0
  54. package/lib/sources/local-agent/adapters/opencode.js +236 -0
  55. package/lib/sources/local-agent/adapters/pi.d.ts +26 -0
  56. package/lib/sources/local-agent/adapters/pi.js +242 -0
  57. package/lib/sources/local-agent/adapters/qoder.d.ts +19 -0
  58. package/lib/sources/local-agent/adapters/qoder.js +93 -0
  59. package/lib/sources/local-agent/adapters/reasonix.d.ts +23 -0
  60. package/lib/sources/local-agent/adapters/reasonix.js +90 -0
  61. package/lib/sources/local-agent/adapters/shared.d.ts +163 -0
  62. package/lib/sources/local-agent/adapters/shared.js +415 -0
  63. package/lib/sources/local-agent/adapters/sqlite-shared.d.ts +92 -0
  64. package/lib/sources/local-agent/adapters/sqlite-shared.js +215 -0
  65. package/lib/sources/local-agent/adapters/zcode.d.ts +41 -0
  66. package/lib/sources/local-agent/adapters/zcode.js +159 -0
  67. package/lib/sources/local-agent/index.d.ts +222 -0
  68. package/lib/sources/local-agent/index.js +656 -0
  69. package/lib/sources/local-agent/page.d.ts +55 -0
  70. package/lib/sources/local-agent/page.js +83 -0
  71. package/lib/sources/local-agent/path.d.ts +8 -0
  72. package/lib/sources/local-agent/path.js +43 -0
  73. package/lib/sources/local-agent/registry.d.ts +68 -0
  74. package/lib/sources/local-agent/registry.js +116 -0
  75. package/lib/sources/local-agent/scan.d.ts +175 -0
  76. package/lib/sources/local-agent/scan.js +472 -0
  77. package/lib/sources/local-agent/sqlite.d.ts +45 -0
  78. package/lib/sources/local-agent/sqlite.js +113 -0
  79. package/lib/sources/local-agent/store.d.ts +93 -0
  80. package/lib/sources/local-agent/store.js +113 -0
  81. package/lib/sources/local-agent/types.d.ts +338 -0
  82. package/lib/sources/local-agent/types.js +20 -0
  83. package/lib/sources/web-chat/index.d.ts +5 -1
  84. package/lib/sources/web-chat/index.js +47 -8
  85. package/lib/store/spec.d.ts +50 -0
  86. package/lib/store/spec.js +2 -2
  87. package/lib/sync/index.d.ts +1 -0
  88. package/lib/sync/index.js +28 -8
  89. package/lib/tool.d.ts +5 -0
  90. package/lib/tool.js +418 -45
  91. package/lib/typert.js +13 -1
  92. package/lib/types.d.ts +28 -2
  93. package/lib/update.d.ts +6 -0
  94. package/lib/update.js +29 -1
  95. package/lib/web.js +5 -1
  96. package/lib/wire.d.ts +80 -0
  97. package/lib/wire.js +30 -1
  98. package/opencli-plugin/chatgpt.js +30 -27
  99. package/opencli-plugin/claude.js +12 -8
  100. package/opencli-plugin/common.js +266 -187
  101. package/opencli-plugin/deepseek.js +8 -5
  102. package/opencli-plugin/gemini.js +42 -38
  103. package/opencli-plugin/grok.js +22 -21
  104. package/opencli-plugin/kimi.js +34 -31
  105. package/opencli-plugin/opencli-plugin.json +6 -6
  106. package/opencli-plugin/package.json +8 -8
  107. package/package.json +200 -185
package/lib/index.d.ts CHANGED
@@ -10,6 +10,7 @@
10
10
  * @module dsh-reference-anything
11
11
  */
12
12
  import { Context, Service } from '@deepseek-ai/cordis';
13
+ import type { Session } from '@deepseek-ai/dsh-session';
13
14
  import z from '@deepseek-ai/schemastery';
14
15
  import type { ReferenceRef, ReferenceSnapshot, ReferenceSource, ReferenceSummary, ReferenceWindow } from './types.ts';
15
16
  export type * from './types.ts';
@@ -52,10 +53,29 @@ export default class ReferenceRuntime extends Service {
52
53
  registerSource(source: ReferenceSource): () => void;
53
54
  /** @returns the registered source ids, in registration order. */
54
55
  sourceIds(): string[];
55
- /** Authorize one task to read a Web conversation named by its user or discovery tool. */
56
+ /**
57
+ * Whether a source's items may only be read after an explicit grant.
58
+ *
59
+ * An unregistered source fails closed: registration order must never decide
60
+ * authorization, and `read()` would reject it as `SOURCE_UNKNOWN` a moment
61
+ * later anyway.
62
+ */
63
+ private gated;
64
+ /**
65
+ * Qualify the grant by source.
66
+ *
67
+ * Two sources can mint the same opaque id, and an unqualified key would let
68
+ * a grant for one silently authorize the other. NUL cannot occur in either
69
+ * half, so the join is unambiguous.
70
+ */
71
+ private static grantKey;
72
+ private static contentMentions;
73
+ /** Authorize one task to read a gated reference named by its user or discovery tool. */
56
74
  grant(sessionId: string, ref: ReferenceRef): void;
57
- /** Enforce that a Web conversation URI originated in this task's mention/list surface. */
75
+ /** Enforce that a gated URI originated in this task's mention/list surface. */
58
76
  assertGranted(sessionId: string | undefined, ref: ReferenceRef): void;
77
+ /** Allow a gated URI granted live or named in this task's durable user/tool-result history. */
78
+ assertSessionGranted(session: Session | undefined, ref: ReferenceRef): void;
59
79
  /** Release task-local grants when a host knows the task is gone. */
60
80
  revoke(sessionId: string): void;
61
81
  /**
package/lib/index.js CHANGED
@@ -12,6 +12,7 @@
12
12
  import { Context, Service } from '@deepseek-ai/cordis';
13
13
  import z from '@deepseek-ai/schemastery';
14
14
  import { ReferenceAnythingError } from "./errors.js";
15
+ import { mayContainReference, parseReferenceText } from "./uri.js";
15
16
  export { ReferenceAnythingError } from "./errors.js";
16
17
  export { REFERENCE_SCHEME, decodeReferenceUri, encodeReferenceUri, formatReferenceMention, mayContainReference, parseReferenceText, } from "./uri.js";
17
18
  /** Fan-out cap applied to discovery when a caller names no limit of its own. */
@@ -57,22 +58,71 @@ export default class ReferenceRuntime extends Service {
57
58
  sourceIds() {
58
59
  return [...this.sources.keys()];
59
60
  }
60
- /** Authorize one task to read a Web conversation named by its user or discovery tool. */
61
+ /**
62
+ * Whether a source's items may only be read after an explicit grant.
63
+ *
64
+ * An unregistered source fails closed: registration order must never decide
65
+ * authorization, and `read()` would reject it as `SOURCE_UNKNOWN` a moment
66
+ * later anyway.
67
+ */
68
+ gated(source) {
69
+ const registered = this.sources.get(source);
70
+ return registered === undefined || registered.requiresGrant === true;
71
+ }
72
+ /**
73
+ * Qualify the grant by source.
74
+ *
75
+ * Two sources can mint the same opaque id, and an unqualified key would let
76
+ * a grant for one silently authorize the other. NUL cannot occur in either
77
+ * half, so the join is unambiguous.
78
+ */
79
+ static grantKey(ref) { return `${ref.source}\u0000${ref.id}`; }
80
+ static contentMentions(blocks, key) {
81
+ return blocks.some(block => {
82
+ if (block.type === 'tool-result')
83
+ return ReferenceRuntime.contentMentions(block.content, key);
84
+ if (block.type !== 'text' || !mayContainReference(block.text))
85
+ return false;
86
+ try {
87
+ return parseReferenceText(block.text).references.some(input => ReferenceRuntime.grantKey(input.ref) === key);
88
+ }
89
+ catch {
90
+ return false;
91
+ }
92
+ });
93
+ }
94
+ /** Authorize one task to read a gated reference named by its user or discovery tool. */
61
95
  grant(sessionId, ref) {
62
- if (ref.source !== 'web-chat')
63
- return;
96
+ // Recorded unconditionally: a source may register after the mention that
97
+ // named it, and a grant for an ungated source is merely inert.
64
98
  const values = this.grants.get(sessionId) ?? new Set();
65
- values.add(ref.id);
99
+ values.add(ReferenceRuntime.grantKey(ref));
66
100
  this.grants.set(sessionId, values);
67
101
  }
68
- /** Enforce that a Web conversation URI originated in this task's mention/list surface. */
102
+ /** Enforce that a gated URI originated in this task's mention/list surface. */
69
103
  assertGranted(sessionId, ref) {
70
- if (ref.source !== 'web-chat')
104
+ if (!this.gated(ref.source))
71
105
  return;
72
- if (!sessionId || !this.grants.get(sessionId)?.has(ref.id)) {
106
+ if (!sessionId || !this.grants.get(sessionId)?.has(ReferenceRuntime.grantKey(ref))) {
73
107
  throw new ReferenceAnythingError('this task has not been granted access to that conversation reference', 'CONVERSATION_REFERENCE_NOT_GRANTED');
74
108
  }
75
109
  }
110
+ /** Allow a gated URI granted live or named in this task's durable user/tool-result history. */
111
+ assertSessionGranted(session, ref) {
112
+ const key = ReferenceRuntime.grantKey(ref);
113
+ if (session && !this.grants.get(String(session.id))?.has(key)) {
114
+ const mentioned = session.events.some(event => {
115
+ if (event.type === 'user/message')
116
+ return ReferenceRuntime.contentMentions(event.data.content, key);
117
+ if (event.type === 'tool/result')
118
+ return ReferenceRuntime.contentMentions(event.data.message.content, key);
119
+ return false;
120
+ });
121
+ if (mentioned)
122
+ this.grant(String(session.id), ref);
123
+ }
124
+ this.assertGranted(session && String(session.id), ref);
125
+ }
76
126
  /** Release task-local grants when a host knows the task is gone. */
77
127
  revoke(sessionId) { this.grants.delete(sessionId); }
78
128
  /**
package/lib/opencli.d.ts CHANGED
@@ -1,9 +1,11 @@
1
1
  import type { ChatProvider } from './store/spec.ts';
2
2
  import type { ProviderConversationRow, ProviderTurnRow } from './store/store.ts';
3
3
  export declare const MIN_OPENCLI_VERSION = "1.8.6";
4
- export declare const MIN_ADAPTER_VERSION = "0.2.2";
4
+ export declare const MIN_ADAPTER_VERSION = "0.2.3";
5
+ /** Allows a 25 MiB attachment to cross JSON/base64 stdout with bounded headroom. */
6
+ export declare const DEFAULT_OPENCLI_MAX_STDOUT_BYTES: number;
5
7
  export declare const OPENCLI_NPM_PACKAGE = "@jackwener/opencli";
6
- export type OpenCliErrorCode = 'EXTENSION_NOT_CONNECTED' | 'PROVIDER_TIMEOUT' | 'PROVIDER_NOT_LOGGED_IN' | 'PROVIDER_ACCOUNT_MISMATCH' | 'OPENCLI_CONFIGURATION' | 'OPENCLI_OUTPUT_TOO_LARGE' | 'OPENCLI_FAILED' | 'OPENCLI_INSTALL_FAILED';
8
+ export type OpenCliErrorCode = 'EXTENSION_NOT_CONNECTED' | 'PROVIDER_TIMEOUT' | 'PROVIDER_NOT_LOGGED_IN' | 'PROVIDER_ACCOUNT_MISMATCH' | 'PROVIDER_RATE_LIMIT' | 'OPENCLI_CONFIGURATION' | 'OPENCLI_OUTPUT_TOO_LARGE' | 'OPENCLI_FAILED' | 'OPENCLI_INSTALL_FAILED' | 'ATTACHMENT_TOO_LARGE';
7
9
  export declare class OpenCliError extends Error {
8
10
  readonly code: OpenCliErrorCode;
9
11
  constructor(message: string, code: OpenCliErrorCode, options?: ErrorOptions);
@@ -95,7 +97,7 @@ export declare class OpenCliRunner {
95
97
  /** Resolve account identity and history through one OpenCLI browser command. */
96
98
  syncIndex(provider: ChatProvider, signal?: AbortSignal, since?: string, accountScope?: string): Promise<ProviderIndex>;
97
99
  detail(provider: ChatProvider, id: string, signal?: AbortSignal, accountScope?: string): Promise<ProviderTurnRow[]>;
98
- attachment(provider: ChatProvider, locator: string, output: string, maxBytes: number, signal?: AbortSignal): Promise<Record<string, unknown>>;
100
+ attachment(provider: ChatProvider, locator: string, output: string, maxBytes: number, signal?: AbortSignal, accountScope?: string): Promise<Record<string, unknown>>;
99
101
  health(signal?: AbortSignal): Promise<OpenCliHealth>;
100
102
  /** Inspect local OpenCLI, daemon, extension and plugin state without an active connectivity probe. */
101
103
  quickHealth(signal?: AbortSignal): Promise<OpenCliHealth>;
package/lib/opencli.js CHANGED
@@ -5,7 +5,9 @@ import { promisify } from 'node:util';
5
5
  import { createHash } from 'node:crypto';
6
6
  const execFile = promisify(nodeExecFile);
7
7
  export const MIN_OPENCLI_VERSION = '1.8.6';
8
- export const MIN_ADAPTER_VERSION = '0.2.2';
8
+ export const MIN_ADAPTER_VERSION = '0.2.3';
9
+ /** Allows a 25 MiB attachment to cross JSON/base64 stdout with bounded headroom. */
10
+ export const DEFAULT_OPENCLI_MAX_STDOUT_BYTES = 40 * 1024 * 1024;
9
11
  export const OPENCLI_NPM_PACKAGE = '@jackwener/opencli';
10
12
  const SITE = {
11
13
  chatgpt: 'dsh-chatgpt', claude: 'dsh-claude', gemini: 'dsh-gemini',
@@ -55,7 +57,7 @@ export class OpenCliRunner {
55
57
  this.profile = options.profile || '';
56
58
  this.prefixArgs = options.prefixArgs ?? [];
57
59
  this.timeoutMs = options.timeoutMs ?? 60_000;
58
- this.maxStdoutBytes = options.maxStdoutBytes ?? 32 * 1024 * 1024;
60
+ this.maxStdoutBytes = options.maxStdoutBytes ?? DEFAULT_OPENCLI_MAX_STDOUT_BYTES;
59
61
  }
60
62
  async whoami(provider, signal) {
61
63
  const rows = await this.json(SITE[provider], 'whoami', [], signal);
@@ -107,8 +109,11 @@ export class OpenCliRunner {
107
109
  };
108
110
  });
109
111
  }
110
- async attachment(provider, locator, output, maxBytes, signal) {
111
- const rows = await this.json(SITE[provider], 'attachment', [locator, '--output', output, '--maxBytes', String(maxBytes)], signal);
112
+ async attachment(provider, locator, output, maxBytes, signal, accountScope = '') {
113
+ const rows = await this.json(SITE[provider], 'attachment', [
114
+ locator, '--output', output, '--maxBytes', String(maxBytes),
115
+ ...(accountScope ? ['--accountScope', accountScope] : []),
116
+ ], signal);
112
117
  return rows[0] ?? {};
113
118
  }
114
119
  async health(signal) {
@@ -246,8 +251,10 @@ export class OpenCliRunner {
246
251
  const stderr = String(detail.stderr || detail.stdout || '').trim().slice(0, 2_000);
247
252
  const exit = typeof detail.code === 'number' ? detail.code : undefined;
248
253
  const code = stderr.includes('DSH_ACCOUNT_SCOPE_MISMATCH') ? 'PROVIDER_ACCOUNT_MISMATCH'
249
- : exit === 69 ? 'EXTENSION_NOT_CONNECTED' : exit === 75 ? 'PROVIDER_TIMEOUT'
250
- : exit === 77 ? 'PROVIDER_NOT_LOGGED_IN' : exit === 78 ? 'OPENCLI_CONFIGURATION' : 'OPENCLI_FAILED';
254
+ : stderr.includes('DSH_PROVIDER_RATE_LIMIT') ? 'PROVIDER_RATE_LIMIT'
255
+ : stderr.includes('DSH_ATTACHMENT_TOO_LARGE') ? 'ATTACHMENT_TOO_LARGE'
256
+ : exit === 69 ? 'EXTENSION_NOT_CONNECTED' : exit === 75 ? 'PROVIDER_TIMEOUT'
257
+ : exit === 77 ? 'PROVIDER_NOT_LOGGED_IN' : exit === 78 ? 'OPENCLI_CONFIGURATION' : 'OPENCLI_FAILED';
251
258
  throw new OpenCliError(stderr || `OpenCLI exited with ${String(detail.code)}`, code, { cause: error });
252
259
  }
253
260
  }
@@ -0,0 +1,157 @@
1
+ import { chmod, copyFile, mkdir, readFile, rename, unlink, writeFile } from 'node:fs/promises';
2
+ import { spawn as nodeSpawn } from 'node:child_process';
3
+ /** Deliberately fixed; upgrades are a conscious manifest change. */
4
+ export declare const OPENLIST_FIXED_VERSION = "v4.2.2";
5
+ export declare const OPENLIST_CREDENTIAL_DIRECTORY: string;
6
+ export declare const OPENLIST_CREDENTIAL_FILE: string;
7
+ export interface OpenListAsset {
8
+ readonly platform: string;
9
+ readonly arch: string;
10
+ readonly url: string;
11
+ readonly sha256: string;
12
+ readonly archive: 'tar.gz' | 'zip';
13
+ readonly binary: string;
14
+ }
15
+ export interface OpenListReleaseManifest {
16
+ readonly version: string;
17
+ readonly assets: readonly OpenListAsset[];
18
+ }
19
+ /** SHA-256 values were computed from the six named GitHub v4.2.2 release assets. */
20
+ export declare const OPENLIST_RELEASE: OpenListReleaseManifest;
21
+ export interface OpenListCredentials {
22
+ readonly endpoint: string;
23
+ readonly username?: string;
24
+ readonly password?: string;
25
+ readonly token?: string;
26
+ readonly mode?: 'managed' | 'external';
27
+ readonly version?: string; /** Host-only cache revision. */
28
+ readonly generation?: number;
29
+ }
30
+ export type OpenListAdminMutationState = 'not-started' | 'committed' | 'unknown';
31
+ /** Safe administration facts. No storage addition, credentials, or raw URLs cross this boundary. */
32
+ export interface OpenListMount {
33
+ readonly id: string;
34
+ readonly name: string;
35
+ readonly driver: string;
36
+ readonly enabled: boolean;
37
+ readonly status?: 'ready' | 'disabled' | 'error';
38
+ readonly error?: string;
39
+ readonly capacityUsed?: number;
40
+ readonly capacityTotal?: number;
41
+ readonly indexStatus?: 'idle' | 'running' | 'complete' | 'failed';
42
+ readonly indexProgress?: number;
43
+ readonly indexCount?: number;
44
+ }
45
+ export interface OpenListDriverField {
46
+ readonly name: string;
47
+ readonly label: string;
48
+ readonly type: 'text' | 'password' | 'number' | 'boolean' | 'select';
49
+ readonly secret: boolean;
50
+ readonly required: boolean;
51
+ readonly hasDefault?: boolean;
52
+ readonly default?: string | number | boolean;
53
+ readonly options?: readonly {
54
+ readonly label: string;
55
+ readonly value: string;
56
+ }[];
57
+ }
58
+ export interface OpenListDriver {
59
+ readonly name: string;
60
+ readonly description?: string;
61
+ readonly quickAuth: boolean;
62
+ readonly fields: readonly OpenListDriverField[];
63
+ }
64
+ /** Host-only mount creation values. `addition` is serialized only on the Host. */
65
+ export interface OpenListMountInput {
66
+ readonly mountPath: string;
67
+ readonly driver: string;
68
+ readonly addition: Record<string, unknown>;
69
+ readonly order?: number;
70
+ readonly remark?: string;
71
+ }
72
+ export interface OpenListSeams {
73
+ readonly fetch?: typeof fetch;
74
+ readonly spawn?: typeof nodeSpawn;
75
+ readonly readFile?: typeof readFile;
76
+ readonly writeFile?: typeof writeFile;
77
+ readonly mkdir?: typeof mkdir;
78
+ readonly chmod?: typeof chmod;
79
+ readonly rename?: typeof rename;
80
+ readonly copyFile?: typeof copyFile;
81
+ readonly unlink?: typeof unlink;
82
+ readonly fsyncFile?: (path: string) => Promise<void>;
83
+ /** Required on Windows to apply a restrictive ACL (for example via icacls). */
84
+ readonly securePermissions?: (path: string, directory: boolean) => Promise<void>;
85
+ readonly sleep?: (ms: number) => Promise<void>;
86
+ /** Test/integration seam for the executable replacement transaction. */
87
+ readonly install?: typeof installOpenList;
88
+ }
89
+ /** Exchange external username/password for the raw OpenList token. */
90
+ export declare function authenticateOpenList(endpoint: string, username: string, password: string, fetchImpl?: (input: string, init?: RequestInit) => Promise<Response>, signal?: AbortSignal): Promise<string>;
91
+ /** Download only a manifest-pinned binary after validating its SHA-256. */
92
+ export declare function installOpenList(dataRoot: string, manifest?: OpenListReleaseManifest, seams?: OpenListSeams, os?: NodeJS.Platform, cpu?: string, signal?: AbortSignal, retainBackup?: boolean): Promise<{
93
+ version: string;
94
+ path: string;
95
+ finish: (success: boolean) => Promise<void>;
96
+ }>;
97
+ /** Extract only the expected executable; archive paths never reach the filesystem. */
98
+ export declare function unpackOpenListBinary(archive: Uint8Array, asset: OpenListAsset): Uint8Array;
99
+ /** Select exactly the release asset for this OS and CPU architecture. */
100
+ export declare function selectOpenListAsset(manifest: OpenListReleaseManifest, os?: NodeJS.Platform, cpu?: string): OpenListAsset;
101
+ export declare function sha256(bytes: Uint8Array): string;
102
+ export declare function verifyOpenListAsset(bytes: Uint8Array, expected: string): boolean;
103
+ /** Validate an endpoint without leaking its full value in a diagnostic. */
104
+ export declare function validateOpenListEndpoint(value: string, managed?: boolean): string;
105
+ export declare function isLoopback(host: string): boolean;
106
+ /** Ask the kernel for a loopback port. Start immediately afterwards to minimize the normal port race. */
107
+ export declare function chooseOpenListPort(): Promise<number>;
108
+ export declare function readOpenListCredentials(path?: string, seams?: OpenListSeams): Promise<OpenListCredentials | undefined>;
109
+ export declare function writeOpenListCredentials(credentials: OpenListCredentials, path?: string, seams?: OpenListSeams, signal?: AbortSignal): Promise<void>;
110
+ /** A Host-private authenticated API wrapper with redacted errors and safe mount shapes. */
111
+ export declare class OpenListHostClient {
112
+ private credentials;
113
+ private readonly refreshToken?;
114
+ private readonly managed;
115
+ private readonly fetchImpl;
116
+ private readonly secretDefaults;
117
+ constructor(credentials: OpenListCredentials, seams?: OpenListSeams, refreshToken?: ((signal?: AbortSignal) => Promise<OpenListCredentials>) | undefined, managed?: boolean);
118
+ connect(signal?: AbortSignal): Promise<void>;
119
+ drivers(signal?: AbortSignal): Promise<string[]>;
120
+ driverInfo(signal?: AbortSignal): Promise<OpenListDriver[]>;
121
+ fillSecretDefaults(driver: string, supplied: Record<string, unknown>): Record<string, unknown>;
122
+ mounts(signal?: AbortSignal): Promise<OpenListMount[]>;
123
+ createMount(input: OpenListMountInput, signal?: AbortSignal): Promise<OpenListMount>;
124
+ updateMount(id: string, input: OpenListMountInput, signal?: AbortSignal): Promise<OpenListMount>;
125
+ /** Reauthentication patches only credential fields onto the full host-side row. */
126
+ updateMountPatch(id: string, additionPatch: Record<string, unknown>, signal?: AbortSignal): Promise<OpenListMount>;
127
+ removeMount(id: string, signal?: AbortSignal): Promise<void>;
128
+ disableMount(id: string, disabled?: boolean, signal?: AbortSignal): Promise<void>;
129
+ configureManagedIndex(signal?: AbortSignal): Promise<void>;
130
+ updateIndex(mountPath: string, signal?: AbortSignal): Promise<void>;
131
+ reindexMount(_id?: string, signal?: AbortSignal): Promise<{
132
+ supported: true;
133
+ }>;
134
+ indexProgress(signal?: AbortSignal): Promise<Pick<OpenListMount, 'indexStatus' | 'indexProgress' | 'indexCount'> | undefined>;
135
+ private request;
136
+ private mountRows;
137
+ private storageRow;
138
+ private mountRow;
139
+ }
140
+ /** Owns only a process it launched; it never kills a user-managed OpenList. */
141
+ export declare class ManagedOpenListRuntime {
142
+ private readonly seams;
143
+ private child;
144
+ constructor(seams?: OpenListSeams);
145
+ get running(): boolean;
146
+ start(binary: string, dataDirectory: string, port?: number, signal?: AbortSignal): Promise<string>;
147
+ /** Generate an administrator password without exposing it in argv. */
148
+ setAdminPassword(binary: string, dataDirectory: string, _password?: string, signal?: AbortSignal, mutationState?: (state: OpenListAdminMutationState) => void): Promise<string>;
149
+ stop(): Promise<void>;
150
+ }
151
+ /** v4.2.2 reads `scheme.address` and `scheme.http_port` from data/config.json. */
152
+ export declare function writeManagedOpenListConfig(dataDirectory: string, port: number, seams?: OpenListSeams, signal?: AbortSignal): Promise<void>;
153
+ export declare function parseRandomAdminPassword(output: string): string | undefined;
154
+ export declare function isSensitiveDriverField(name: string): boolean;
155
+ export declare function isApiPagesQuickDriver(name: string): boolean;
156
+ /** Recover the only crash window in Windows' two-rename executable replacement. */
157
+ export declare function recoverInterruptedReplacement(target: string, backup: string, marker: string, seams?: OpenListSeams, windows?: boolean, owner?: symbol): Promise<void>;