@hraness/sponge 0.4.1 → 0.5.1

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 (39) hide show
  1. package/README.md +17 -16
  2. package/dist/src/acquisition/capture.d.ts +1 -4
  3. package/dist/src/acquisition/capture.js +12 -23
  4. package/dist/src/acquisition/clip-helper.js +14 -0
  5. package/dist/src/acquisition/errors.d.ts +2 -1
  6. package/dist/src/acquisition/errors.js +4 -33
  7. package/dist/src/acquisition/lock.d.ts +1 -1
  8. package/dist/src/acquisition/lock.js +1 -1
  9. package/dist/src/acquisition/pins.d.ts +1 -1
  10. package/dist/src/acquisition/pins.js +7 -13
  11. package/dist/src/acquisition/process.d.ts +1 -1
  12. package/dist/src/acquisition/process.js +1 -2
  13. package/dist/src/acquisition/runtime.d.ts +0 -4
  14. package/dist/src/acquisition/runtime.js +12 -18
  15. package/dist/src/app/source.d.ts +2 -0
  16. package/dist/src/app/source.js +18 -0
  17. package/dist/src/cli/commands.js +28 -18
  18. package/dist/src/cli/config.d.ts +2 -1
  19. package/dist/src/cli/config.js +8 -8
  20. package/dist/src/cli/runtimes.js +1 -1
  21. package/dist/src/cli/worker.js +13 -10
  22. package/dist/src/errors.d.ts +1 -0
  23. package/dist/src/errors.js +2 -0
  24. package/dist/src/media/capture.d.ts +6 -2
  25. package/dist/src/media/capture.js +33 -42
  26. package/dist/src/models/catalog.d.ts +4 -2
  27. package/dist/src/models/catalog.js +39 -20
  28. package/dist/src/models/runtime.d.ts +11 -3
  29. package/dist/src/models/runtime.js +18 -11
  30. package/dist/src/pdf/capture-helper.js +6 -5
  31. package/dist/src/pdf/capture.d.ts +0 -4
  32. package/dist/src/pdf/capture.js +2 -14
  33. package/dist/src/pdf/errors.js +1 -3
  34. package/dist/src/worker/basic.d.ts +1 -1
  35. package/dist/src/worker/basic.js +5 -3
  36. package/native/runtime-manifest.json +14 -6
  37. package/package.json +1 -1
  38. package/dist/src/media/capture-helper.js +0 -21
  39. /package/dist/src/{media/capture-helper.d.ts → acquisition/clip-helper.d.ts} +0 -0
@@ -1,5 +1,6 @@
1
1
  import type { AsrRuntime } from '../inference/asr/runtime.js';
2
2
  import type { EmbeddingRuntime } from '../inference/embedding/index.js';
3
+ import type { MediaRuntime } from '../media/capture.js';
3
4
  import { type NativeCatalog, type NativeKind } from './catalog.js';
4
5
  export declare function nativeSetupPlan(kind: NativeKind, version: string): Promise<{
5
6
  supported: boolean;
@@ -11,12 +12,19 @@ export declare function nativeSetupPlan(kind: NativeKind, version: string): Prom
11
12
  requiredFreeBytes: number;
12
13
  artifacts: readonly import("./artifacts.js").ModelArtifact[];
13
14
  }>;
15
+ type NativeRuntime = AsrRuntime | EmbeddingRuntime | MediaRuntime;
14
16
  export declare function setupNativeRuntime(cacheRoot: string, catalog: NativeCatalog, kind: NativeKind, options?: {
15
17
  signal?: AbortSignal;
16
- }): Promise<AsrRuntime | EmbeddingRuntime>;
18
+ }): Promise<NativeRuntime>;
17
19
  export declare function provisionNative(kind: 'asr', cacheRoot: string, version: string, signal?: AbortSignal): Promise<AsrRuntime>;
18
20
  export declare function provisionNative(kind: 'embedding', cacheRoot: string, version: string, signal?: AbortSignal): Promise<EmbeddingRuntime>;
19
- export declare function provisionNative(kind: NativeKind, cacheRoot: string, version: string, signal?: AbortSignal): Promise<AsrRuntime | EmbeddingRuntime>;
21
+ export declare function provisionNative(kind: 'media', cacheRoot: string, version: string, signal?: AbortSignal): Promise<MediaRuntime>;
22
+ export declare function provisionNative(kind: NativeKind, cacheRoot: string, version: string, signal?: AbortSignal): Promise<NativeRuntime>;
20
23
  export declare function inspectNative(kind: 'asr', cacheRoot: string, version: string): Promise<AsrRuntime>;
21
24
  export declare function inspectNative(kind: 'embedding', cacheRoot: string, version: string): Promise<EmbeddingRuntime>;
22
- export declare function inspectNative(kind: NativeKind, cacheRoot: string, version: string): Promise<AsrRuntime | EmbeddingRuntime>;
25
+ export declare function inspectNative(kind: 'media', cacheRoot: string, version: string): Promise<MediaRuntime>;
26
+ export declare function inspectNative(kind: NativeKind, cacheRoot: string, version: string): Promise<NativeRuntime>;
27
+ type RuntimeOf<K extends NativeKind> = K extends 'asr' ? AsrRuntime : K extends 'embedding' ? EmbeddingRuntime : MediaRuntime;
28
+ /** An installed runtime, or undefined when it is not installed or this platform cannot run it. */
29
+ export declare function optionalNative<K extends NativeKind>(kind: K, cacheRoot: string, version: string): Promise<RuntimeOf<K> | undefined>;
30
+ export {};
@@ -4,7 +4,7 @@ import { privateRoot } from '../acquisition/files.js';
4
4
  import { nativeArtifactFetch } from './download.js';
5
5
  import { inspectInstalledModelPackage, provisionModelPackage, recoverModelPackage, modelSetupPlan, } from './artifacts.js';
6
6
  import { nativePlatformSupported, nativeModelPackage, loadNativeCatalog, } from './catalog.js';
7
- import { SpongeError } from '../errors.js';
7
+ import { SpongeError, publicCode } from '../errors.js';
8
8
  export async function nativeSetupPlan(kind, version) {
9
9
  const catalog = await loadNativeCatalog(version);
10
10
  return {
@@ -24,6 +24,10 @@ function asr(c, p) {
24
24
  model: p['whistle.cact'],
25
25
  };
26
26
  }
27
+ function media(c, p) {
28
+ return { helper: p['sponge-media'], helperSha256: c.artifacts.find((a) => a.role === 'media-helper').sha256 };
29
+ }
30
+ const runtimeOf = (kind, c, p) => kind === 'asr' ? asr(c, p) : kind === 'embedding' ? embedding(c, p) : media(c, p);
27
31
  function embedding(c, p) {
28
32
  return {
29
33
  helper: p['sponge-embedding'],
@@ -48,7 +52,7 @@ export async function setupNativeRuntime(cacheRoot, catalog, kind, options = {})
48
52
  await privateRoot(cacheRoot);
49
53
  await recoverModelPackage(cacheRoot, manifest);
50
54
  const paths = await provisionModelPackage(cacheRoot, manifest, { ...options, fetch: nativeArtifactFetch(manifest) });
51
- return kind === 'asr' ? asr(catalog, paths) : embedding(catalog, paths);
55
+ return runtimeOf(kind, catalog, paths);
52
56
  }
53
57
  async function installed(cacheRoot, catalog, kind) {
54
58
  const paths = await inspectInstalledModelPackage(cacheRoot, nativeModelPackage(catalog, kind));
@@ -56,18 +60,21 @@ async function installed(cacheRoot, catalog, kind) {
56
60
  throw new SpongeError('runtime-missing');
57
61
  return paths;
58
62
  }
59
- async function inspectAsrRuntime(cacheRoot, catalog) {
60
- supported();
61
- return asr(catalog, await installed(cacheRoot, catalog, 'asr'));
62
- }
63
- async function inspectEmbeddingRuntime(cacheRoot, catalog) {
64
- supported();
65
- return embedding(catalog, await installed(cacheRoot, catalog, 'embedding'));
66
- }
67
63
  export async function provisionNative(kind, cacheRoot, version, signal) {
68
64
  return setupNativeRuntime(cacheRoot, await loadNativeCatalog(version), kind, { signal });
69
65
  }
70
66
  export async function inspectNative(kind, cacheRoot, version) {
67
+ supported();
71
68
  const catalog = await loadNativeCatalog(version);
72
- return kind === 'asr' ? inspectAsrRuntime(cacheRoot, catalog) : inspectEmbeddingRuntime(cacheRoot, catalog);
69
+ return runtimeOf(kind, catalog, await installed(cacheRoot, catalog, kind));
70
+ }
71
+ /** An installed runtime, or undefined when it is not installed or this platform cannot run it. */
72
+ export async function optionalNative(kind, cacheRoot, version) {
73
+ try {
74
+ return (await inspectNative(kind, cacheRoot, version));
75
+ }
76
+ catch (error) {
77
+ if (!['runtime-missing', 'unsupported'].includes(publicCode(error, 'integrity')))
78
+ throw error;
79
+ }
73
80
  }
@@ -1,10 +1,11 @@
1
- // Pinned public SDK bridge. Native subprocesses inherit the supervisor's group.
1
+ // Pinned public Wordcell bridge. Native subprocesses inherit the supervisor's group.
2
2
  const runtime = process.argv[2], args = process.argv.slice(3);
3
3
  try {
4
- const { runPdfAcquisition } = await import(import.meta.resolve('@hraness/ghostget/pdf-acquisition', `${runtime}/package.json`));
5
- const { runPdfToolCommand } = await import(import.meta.resolve('@hraness/wordcell/pdf', `${runtime}/package.json`));
6
- process.exitCode = await runPdfAcquisition(args, process.env, { stdout: (value) => process.stdout.write(value), stderr: (value) => process.stderr.write(value) }, {
7
- runTool: (specification) => runPdfToolCommand({ ...specification, processGroup: 'inherit' }),
4
+ const { runPdfCommand, runPdfToolCommand } = await import(import.meta.resolve('@hraness/wordcell/pdf', `${runtime}/package.json`));
5
+ process.exitCode = await runPdfCommand(args, process.env, { stdout: (value) => process.stdout.write(value), stderr: (value) => process.stderr.write(value) }, {
6
+ captureDependencies: {
7
+ runTool: (specification) => runPdfToolCommand({ ...specification, processGroup: 'inherit' }),
8
+ },
8
9
  });
9
10
  }
10
11
  catch {
@@ -2,10 +2,6 @@ import type { CaptureResult, ErrorEnvelope } from '../../contracts/index.js';
2
2
  import { runOwned } from '../acquisition/process.js';
3
3
  import { type CaptureRuntime } from '../acquisition/runtime.js';
4
4
  type CaptureConnection = {
5
- kind: 'account';
6
- stateHome: string;
7
- accountId: string;
8
- } | {
9
5
  kind: 'cdp';
10
6
  endpoint: string;
11
7
  };
@@ -52,7 +52,7 @@ export async function capturePdf(request) {
52
52
  return failure(requestId, 'invalid-input');
53
53
  if (url.protocol === 'file:' && (url.host || url.search || url.hash || request.connection))
54
54
  return failure(requestId, 'invalid-input');
55
- if (request.connection?.kind === 'cdp' || request.allowPrivateNetwork)
55
+ if (request.connection || request.allowPrivateNetwork)
56
56
  return failure(requestId, 'unsupported');
57
57
  const captureHelper = fileURLToPath(new URL(import.meta.url.endsWith('.ts') ? './capture-helper.ts' : './capture-helper.js', import.meta.url));
58
58
  const args = [
@@ -76,21 +76,9 @@ export async function capturePdf(request) {
76
76
  '--quiet',
77
77
  '--json',
78
78
  ];
79
- let selectedState;
80
- if (request.connection?.kind === 'account') {
81
- if (!/^[a-zA-Z0-9_.-]{1,128}$/.test(request.connection.accountId))
82
- return failure(requestId, 'invalid-input');
83
- try {
84
- selectedState = await privateRoot(request.connection.stateHome);
85
- }
86
- catch {
87
- return failure(requestId, 'repair-auth');
88
- }
89
- args.push('--auth', request.connection.accountId);
90
- }
91
79
  const root = await realpath(await mkdtemp(join(base, 'capture-'))), home = join(root, 'home'), output = join(root, 'bundles');
92
80
  args.push('--output', output);
93
- const env = isolatedEnvironment(home, home, selectedState ?? join(home, 'state'));
81
+ const env = isolatedEnvironment(home, home);
94
82
  const controller = new AbortController();
95
83
  const abort = () => controller.abort();
96
84
  signal?.addEventListener('abort', abort, { once: true });
@@ -1,4 +1,4 @@
1
- import { failure, upstreamFailure } from '../acquisition/errors.js';
1
+ import { failure } from '../acquisition/errors.js';
2
2
  /** Wordcell's pinned PDF code field is authoritative; prose is never classified. */
3
3
  export function pdfFailure(value, requestId) {
4
4
  if (!value || typeof value !== 'object' || Array.isArray(value))
@@ -6,8 +6,6 @@ export function pdfFailure(value, requestId) {
6
6
  const record = value;
7
7
  if (record.ok !== false)
8
8
  return failure(requestId, 'unclassified');
9
- if (record.captureError)
10
- return upstreamFailure(value, requestId);
11
9
  const codes = {
12
10
  'invalid-input': 'invalid-input',
13
11
  encrypted: 'unsupported',
@@ -2,7 +2,7 @@ import type { LibraryStore } from '../store/index.js';
2
2
  import { type ArticleOptions, type ArticleOutcome } from '../app/article.js';
3
3
  import { type MediaOptions } from '../media/handler.js';
4
4
  /** Content handlers over the durable sequential worker and its process supervisor. */
5
- export declare function drainLibrary(store: LibraryStore, options: ArticleOptions & Pick<MediaOptions, 'asrRuntime' | 'language' | 'forceLocal'> & {
5
+ export declare function drainLibrary(store: LibraryStore, options: ArticleOptions & Pick<MediaOptions, 'asrRuntime' | 'mediaRuntime' | 'language' | 'forceLocal'> & {
6
6
  jobId?: string;
7
7
  resolveConnection?: (realm: string) => ArticleOptions['connection'];
8
8
  onResult?: (result: ArticleOutcome) => void;
@@ -1,4 +1,5 @@
1
1
  import { failure } from '../acquisition/errors.js';
2
+ import { codeOf, publicCode } from '../errors.js';
2
3
  import { ingestArticle } from '../app/article.js';
3
4
  import { ingestPdf } from '../pdf/index.js';
4
5
  import { ingestMedia } from '../media/handler.js';
@@ -11,10 +12,11 @@ export async function drainLibrary(store, options) {
11
12
  try {
12
13
  connection = options.resolveConnection?.(source?.realm ?? 'public') ?? options.connection;
13
14
  }
14
- catch {
15
- store.queue.fail(context.attempt, 'repair-auth');
15
+ catch (error) {
16
+ const code = codeOf(error) === 'connection-retired' ? 'connection-retired' : 'repair-auth';
17
+ store.queue.fail(context.attempt, code);
16
18
  store.queue.settle(context.attempt);
17
- return { ...failure(context.attempt.attemptId, 'repair-auth', 'acquisition'), cleanup: 'settled' };
19
+ return { ...failure(context.attempt.attemptId, publicCode(code), 'acquisition'), cleanup: 'settled' };
18
20
  }
19
21
  if (source?.kind === 'media') {
20
22
  const { capture: _articleCapture, ...mediaOptions } = options;
@@ -20,21 +20,29 @@
20
20
  "sha256": "9526db9ee35e7eb4a5a58ac1e53330032f22a13890bd4ee01818fb380a57a362"
21
21
  },
22
22
  {
23
- "bytes": 23486,
23
+ "bytes": 534912,
24
+ "name": "sponge-media-macos26-arm64",
25
+ "role": "media-helper",
26
+ "sha256": "c4ce953a360fda573004ad69407a29f212e12564bf191cefaa2f8c05fec852ce"
27
+ },
28
+ {
29
+ "bytes": 23606,
24
30
  "name": "native-NOTICES.txt",
25
31
  "role": "notices",
26
- "sha256": "6e62f14bd094001b8da42af6fc42877e51b0d5616ae960917ef214fc45767088"
32
+ "sha256": "f56e55503bebba456ce7a8bcc4bcab3a5c34fa71d57c1e0243179dd4ba429fbf"
27
33
  }
28
34
  ],
29
35
  "build": {
30
- "asrSourceSha256": "6a84b1b2040f17cb510a71548c1453442df15f820ceb0ac8cec3086b4ccefbdc",
36
+ "asrSourceSha256": "6d060d06c7efdc2a9a5537b4d2e108673afc0db596367e9ff876af44bc60d942",
31
37
  "clangVersion": "Apple clang version 21.0.0 (clang-2100.1.1.101)",
32
- "embeddingSourceSha256": "b029dadccaeba029fb9ef302daaefc6a134e8d46440c1e8c227f374d97202ce3",
38
+ "embeddingSourceSha256": "04e07c5f696d5d1d639b004c200da0d0044e473a8b6fdc6ef2be696a97fdf552",
39
+ "mediaSourceSha256": "b35bba5fb8d9f88d67a0aa6fc3e282bd9dbed9077d994fc4de4428eb3df6381e",
40
+ "rustcVersion": "rustc 1.97.1 (8bab26f4f 2026-07-14)",
33
41
  "swiftVersion": "Apple Swift version 6.3.3 (swiftlang-6.3.3.1.3 clang-2100.1.1.101)"
34
42
  },
35
43
  "minimumMacOS": "26.0",
36
- "packageVersion": "0.4.1",
44
+ "packageVersion": "0.5.1",
37
45
  "platform": "darwin",
38
46
  "schemaVersion": 1,
39
- "sourceCommit": "82fefa4ca18700e2e7390e1372c7c672ddac11fa"
47
+ "sourceCommit": "142391ee43de6dc6dba8ef209c73b177539b4725"
40
48
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hraness/sponge",
3
- "version": "0.4.1",
3
+ "version": "0.5.1",
4
4
  "description": "A local library for captured articles and verified offline assets.",
5
5
  "repository": {
6
6
  "type": "git",
@@ -1,21 +0,0 @@
1
- /** Public Ghostget SDK bridge; its complete inherited group belongs to the caller. */
2
- import { readFile } from 'node:fs/promises';
3
- import { processIdentity } from '../worker/identity.js';
4
- import { SpongeError } from '../errors.js';
5
- try {
6
- const config = JSON.parse(await readFile(process.argv[2], 'utf8'));
7
- const sdk = await import(import.meta.resolve('@hraness/ghostget/media-acquisition', `${config.runtimeRoot}/package.json`));
8
- const identity = await processIdentity(process.pid);
9
- if (!identity)
10
- throw new SpongeError('unavailable');
11
- const result = await sdk.acquireEphemeralMedia({
12
- ...config.request,
13
- processGroup: 'inherit',
14
- supervisor: { requestId: config.requestId, processGroupId: process.pid, processStartIdentity: identity.started },
15
- });
16
- process.stdout.write(JSON.stringify(result));
17
- }
18
- catch {
19
- process.stdout.write(JSON.stringify({ ok: false, code: 'unavailable', cleanup: 'settled' }));
20
- process.exitCode = 1;
21
- }