@qvac/harness 0.2.2 → 0.2.4

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.
@@ -2,6 +2,7 @@ import { homedir } from 'os';
2
2
  import { join } from 'path';
3
3
  import process from 'process';
4
4
  import { persistent } from 'bare-storage';
5
+ import { isAndroid, isIOS } from 'which-runtime';
5
6
  export const MODEL_CACHE_PATH_ENV = 'QVAC_MODEL_CACHE_PATH';
6
7
  export const SDK_HOME_ENV = 'SNAP_USER_COMMON';
7
8
  export function releaseChannel(environment) {
@@ -14,7 +15,8 @@ export function releaseChannel(environment) {
14
15
  export function resolveStorage(channel, overrides = {}, env = process.env) {
15
16
  const snapCommon = env[SDK_HOME_ENV];
16
17
  const root = overrides.root ?? join(snapCommon ?? persistent(), 'qvac', channel);
17
- const canonicalSdkHome = snapCommon ?? env['HOME'] ?? env['USERPROFILE'] ?? homedir();
18
+ const onMobile = isAndroid || isIOS;
19
+ const canonicalSdkHome = snapCommon ?? (onMobile ? persistent() : (env['HOME'] ?? env['USERPROFILE'] ?? homedir()));
18
20
  return {
19
21
  root,
20
22
  assistant: join(root, 'assistant'),
@@ -94,6 +94,8 @@ export function writeCapabilities(builder, outFile) {
94
94
  s +=
95
95
  '// what hrpc hands a duplex handler (its own async iterator hangs - see api/attachments.ts)\n';
96
96
  s += 'export interface HandlerFrames<Frame> {\n';
97
+ s +=
98
+ " readonly writeStream?: { readonly destroyed: boolean; readonly destroying: boolean; on(event: 'close', listener: () => void): void; off(event: 'close', listener: () => void): void }\n";
97
99
  s += " on(event: 'data', listener: (frame: Frame) => void): void\n";
98
100
  s += " on(event: 'end', listener: () => void): void\n";
99
101
  s += " on(event: 'error', listener: (err: Error) => void): void\n";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@qvac/harness",
3
- "version": "0.2.2",
3
+ "version": "0.2.4",
4
4
  "type": "module",
5
5
  "description": "An AI harness implementing generate(context) via @qvac/sdk. Knows nothing about workbench, hyperdb, or chunks — just inference in, events out.",
6
6
  "exports": {
@@ -175,14 +175,171 @@
175
175
  "default": "./dist-lib/schema/release-tags.js"
176
176
  },
177
177
  "./dist/harness.cjs": "./dist/harness.cjs",
178
+ "./worker/stow-entry.mjs": "./worker/stow-entry.mjs",
179
+ "./lib/tools/catalog.ts": {
180
+ "types": "./dist-lib/lib/tools/catalog.d.ts",
181
+ "default": "./dist-lib/lib/tools/catalog.js"
182
+ },
183
+ "./lib/tools/create-documents.ts": {
184
+ "types": "./dist-lib/lib/tools/create-documents.d.ts",
185
+ "default": "./dist-lib/lib/tools/create-documents.js"
186
+ },
187
+ "./lib/tools/edit-documents.ts": {
188
+ "types": "./dist-lib/lib/tools/edit-documents.d.ts",
189
+ "default": "./dist-lib/lib/tools/edit-documents.js"
190
+ },
191
+ "./lib/tools/edit-image.ts": {
192
+ "types": "./dist-lib/lib/tools/edit-image.d.ts",
193
+ "default": "./dist-lib/lib/tools/edit-image.js"
194
+ },
195
+ "./lib/tools/exec/adapters/adapter.ts": {
196
+ "types": "./dist-lib/lib/tools/exec/adapters/adapter.d.ts",
197
+ "default": "./dist-lib/lib/tools/exec/adapters/adapter.js"
198
+ },
178
199
  "./lib/tools/exec/adapters/python/attachments.ts": {
179
200
  "types": "./dist-lib/lib/tools/exec/adapters/python/attachments.d.ts",
180
201
  "default": "./dist-lib/lib/tools/exec/adapters/python/attachments.js"
181
202
  },
203
+ "./lib/tools/exec/adapters/python/create-effect.ts": {
204
+ "types": "./dist-lib/lib/tools/exec/adapters/python/create-effect.d.ts",
205
+ "default": "./dist-lib/lib/tools/exec/adapters/python/create-effect.js"
206
+ },
207
+ "./lib/tools/exec/adapters/python/loader.ts": {
208
+ "types": "./dist-lib/lib/tools/exec/adapters/python/loader.d.ts",
209
+ "default": "./dist-lib/lib/tools/exec/adapters/python/loader.js"
210
+ },
211
+ "./lib/tools/exec/adapters/python/memfs.ts": {
212
+ "types": "./dist-lib/lib/tools/exec/adapters/python/memfs.d.ts",
213
+ "default": "./dist-lib/lib/tools/exec/adapters/python/memfs.js"
214
+ },
215
+ "./lib/tools/exec/adapters/python/output-policy.ts": {
216
+ "types": "./dist-lib/lib/tools/exec/adapters/python/output-policy.d.ts",
217
+ "default": "./dist-lib/lib/tools/exec/adapters/python/output-policy.js"
218
+ },
219
+ "./lib/tools/exec/adapters/python/pyodide.ts": {
220
+ "types": "./dist-lib/lib/tools/exec/adapters/python/pyodide.d.ts",
221
+ "default": "./dist-lib/lib/tools/exec/adapters/python/pyodide.js"
222
+ },
223
+ "./lib/tools/exec/adapters/python/python-adapter.ts": {
224
+ "types": "./dist-lib/lib/tools/exec/adapters/python/python-adapter.d.ts",
225
+ "default": "./dist-lib/lib/tools/exec/adapters/python/python-adapter.js"
226
+ },
227
+ "./lib/tools/exec/adapters/python/run-session.ts": {
228
+ "types": "./dist-lib/lib/tools/exec/adapters/python/run-session.d.ts",
229
+ "default": "./dist-lib/lib/tools/exec/adapters/python/run-session.js"
230
+ },
231
+ "./lib/tools/exec/adapters/python/wheels.ts": {
232
+ "types": "./dist-lib/lib/tools/exec/adapters/python/wheels.d.ts",
233
+ "default": "./dist-lib/lib/tools/exec/adapters/python/wheels.js"
234
+ },
235
+ "./lib/tools/exec/adapters/python/worker/client.ts": {
236
+ "types": "./dist-lib/lib/tools/exec/adapters/python/worker/client.d.ts",
237
+ "default": "./dist-lib/lib/tools/exec/adapters/python/worker/client.js"
238
+ },
239
+ "./lib/tools/exec/adapters/python/worker/entry.ts": {
240
+ "types": "./dist-lib/lib/tools/exec/adapters/python/worker/entry.d.ts",
241
+ "default": "./dist-lib/lib/tools/exec/adapters/python/worker/entry.js"
242
+ },
243
+ "./lib/tools/exec/adapters/python/worker/protocol.ts": {
244
+ "types": "./dist-lib/lib/tools/exec/adapters/python/worker/protocol.d.ts",
245
+ "default": "./dist-lib/lib/tools/exec/adapters/python/worker/protocol.js"
246
+ },
247
+ "./lib/tools/exec/adapters/python/worker/spawn-bare.ts": {
248
+ "types": "./dist-lib/lib/tools/exec/adapters/python/worker/spawn-bare.d.ts",
249
+ "default": "./dist-lib/lib/tools/exec/adapters/python/worker/spawn-bare.js"
250
+ },
251
+ "./lib/tools/exec/adapters/python/worker/spawn-node.ts": {
252
+ "types": "./dist-lib/lib/tools/exec/adapters/python/worker/spawn-node.d.ts",
253
+ "default": "./dist-lib/lib/tools/exec/adapters/python/worker/spawn-node.js"
254
+ },
255
+ "./lib/tools/exec/adapters/shell/shell-adapter.ts": {
256
+ "types": "./dist-lib/lib/tools/exec/adapters/shell/shell-adapter.d.ts",
257
+ "default": "./dist-lib/lib/tools/exec/adapters/shell/shell-adapter.js"
258
+ },
259
+ "./lib/tools/exec/obsidian/cli-process.ts": {
260
+ "types": "./dist-lib/lib/tools/exec/obsidian/cli-process.d.ts",
261
+ "default": "./dist-lib/lib/tools/exec/obsidian/cli-process.js"
262
+ },
263
+ "./lib/tools/exec/obsidian/cli.ts": {
264
+ "types": "./dist-lib/lib/tools/exec/obsidian/cli.d.ts",
265
+ "default": "./dist-lib/lib/tools/exec/obsidian/cli.js"
266
+ },
267
+ "./lib/tools/exec/obsidian/command.ts": {
268
+ "types": "./dist-lib/lib/tools/exec/obsidian/command.d.ts",
269
+ "default": "./dist-lib/lib/tools/exec/obsidian/command.js"
270
+ },
271
+ "./lib/tools/exec/obsidian/guidance.ts": {
272
+ "types": "./dist-lib/lib/tools/exec/obsidian/guidance.d.ts",
273
+ "default": "./dist-lib/lib/tools/exec/obsidian/guidance.js"
274
+ },
275
+ "./lib/tools/exec/obsidian/note-name.ts": {
276
+ "types": "./dist-lib/lib/tools/exec/obsidian/note-name.d.ts",
277
+ "default": "./dist-lib/lib/tools/exec/obsidian/note-name.js"
278
+ },
279
+ "./lib/tools/exec/obsidian/output.ts": {
280
+ "types": "./dist-lib/lib/tools/exec/obsidian/output.d.ts",
281
+ "default": "./dist-lib/lib/tools/exec/obsidian/output.js"
282
+ },
283
+ "./lib/tools/exec/obsidian/route.ts": {
284
+ "types": "./dist-lib/lib/tools/exec/obsidian/route.d.ts",
285
+ "default": "./dist-lib/lib/tools/exec/obsidian/route.js"
286
+ },
287
+ "./lib/tools/exec/obsidian/safe-path.ts": {
288
+ "types": "./dist-lib/lib/tools/exec/obsidian/safe-path.d.ts",
289
+ "default": "./dist-lib/lib/tools/exec/obsidian/safe-path.js"
290
+ },
291
+ "./lib/tools/exec/obsidian/vault-create.ts": {
292
+ "types": "./dist-lib/lib/tools/exec/obsidian/vault-create.d.ts",
293
+ "default": "./dist-lib/lib/tools/exec/obsidian/vault-create.js"
294
+ },
295
+ "./lib/tools/exec/obsidian/vault-fs.ts": {
296
+ "types": "./dist-lib/lib/tools/exec/obsidian/vault-fs.d.ts",
297
+ "default": "./dist-lib/lib/tools/exec/obsidian/vault-fs.js"
298
+ },
299
+ "./lib/tools/exec/obsidian/vault-paths.ts": {
300
+ "types": "./dist-lib/lib/tools/exec/obsidian/vault-paths.d.ts",
301
+ "default": "./dist-lib/lib/tools/exec/obsidian/vault-paths.js"
302
+ },
303
+ "./lib/tools/exec/obsidian/vault-read.ts": {
304
+ "types": "./dist-lib/lib/tools/exec/obsidian/vault-read.d.ts",
305
+ "default": "./dist-lib/lib/tools/exec/obsidian/vault-read.js"
306
+ },
307
+ "./lib/tools/exec/obsidian/vault-write.ts": {
308
+ "types": "./dist-lib/lib/tools/exec/obsidian/vault-write.d.ts",
309
+ "default": "./dist-lib/lib/tools/exec/obsidian/vault-write.js"
310
+ },
311
+ "./lib/tools/exec/runner.ts": {
312
+ "types": "./dist-lib/lib/tools/exec/runner.d.ts",
313
+ "default": "./dist-lib/lib/tools/exec/runner.js"
314
+ },
315
+ "./lib/tools/exec/scope.ts": {
316
+ "types": "./dist-lib/lib/tools/exec/scope.d.ts",
317
+ "default": "./dist-lib/lib/tools/exec/scope.js"
318
+ },
319
+ "./lib/tools/exec/shell-argv.ts": {
320
+ "types": "./dist-lib/lib/tools/exec/shell-argv.d.ts",
321
+ "default": "./dist-lib/lib/tools/exec/shell-argv.js"
322
+ },
323
+ "./lib/tools/file-glob.ts": {
324
+ "types": "./dist-lib/lib/tools/file-glob.d.ts",
325
+ "default": "./dist-lib/lib/tools/file-glob.js"
326
+ },
182
327
  "./lib/tools/fs/drive.ts": {
183
328
  "types": "./dist-lib/lib/tools/fs/drive.d.ts",
184
329
  "default": "./dist-lib/lib/tools/fs/drive.js"
185
330
  },
331
+ "./lib/tools/fs/glob.ts": {
332
+ "types": "./dist-lib/lib/tools/fs/glob.d.ts",
333
+ "default": "./dist-lib/lib/tools/fs/glob.js"
334
+ },
335
+ "./lib/tools/fs/local.ts": {
336
+ "types": "./dist-lib/lib/tools/fs/local.d.ts",
337
+ "default": "./dist-lib/lib/tools/fs/local.js"
338
+ },
339
+ "./lib/tools/fs/read.ts": {
340
+ "types": "./dist-lib/lib/tools/fs/read.d.ts",
341
+ "default": "./dist-lib/lib/tools/fs/read.js"
342
+ },
186
343
  "./lib/tools/fs/remote-protocol.ts": {
187
344
  "types": "./dist-lib/lib/tools/fs/remote-protocol.d.ts",
188
345
  "default": "./dist-lib/lib/tools/fs/remote-protocol.js"
@@ -191,37 +348,193 @@
191
348
  "types": "./dist-lib/lib/tools/fs/remote.d.ts",
192
349
  "default": "./dist-lib/lib/tools/fs/remote.js"
193
350
  },
351
+ "./lib/tools/fs/scope.ts": {
352
+ "types": "./dist-lib/lib/tools/fs/scope.d.ts",
353
+ "default": "./dist-lib/lib/tools/fs/scope.js"
354
+ },
355
+ "./lib/tools/fs/walk.ts": {
356
+ "types": "./dist-lib/lib/tools/fs/walk.d.ts",
357
+ "default": "./dist-lib/lib/tools/fs/walk.js"
358
+ },
194
359
  "./lib/tools/fs/write.ts": {
195
360
  "types": "./dist-lib/lib/tools/fs/write.d.ts",
196
361
  "default": "./dist-lib/lib/tools/fs/write.js"
197
362
  },
363
+ "./lib/tools/generate-image.ts": {
364
+ "types": "./dist-lib/lib/tools/generate-image.d.ts",
365
+ "default": "./dist-lib/lib/tools/generate-image.js"
366
+ },
367
+ "./lib/tools/generate-music.ts": {
368
+ "types": "./dist-lib/lib/tools/generate-music.d.ts",
369
+ "default": "./dist-lib/lib/tools/generate-music.js"
370
+ },
371
+ "./lib/tools/grep.ts": {
372
+ "types": "./dist-lib/lib/tools/grep.d.ts",
373
+ "default": "./dist-lib/lib/tools/grep.js"
374
+ },
375
+ "./lib/tools/http-methods.ts": {
376
+ "types": "./dist-lib/lib/tools/http-methods.d.ts",
377
+ "default": "./dist-lib/lib/tools/http-methods.js"
378
+ },
379
+ "./lib/tools/http-request/encode-fields.ts": {
380
+ "types": "./dist-lib/lib/tools/http-request/encode-fields.d.ts",
381
+ "default": "./dist-lib/lib/tools/http-request/encode-fields.js"
382
+ },
383
+ "./lib/tools/http-request/truncate-response.ts": {
384
+ "types": "./dist-lib/lib/tools/http-request/truncate-response.d.ts",
385
+ "default": "./dist-lib/lib/tools/http-request/truncate-response.js"
386
+ },
387
+ "./lib/tools/http-request/utils.ts": {
388
+ "types": "./dist-lib/lib/tools/http-request/utils.d.ts",
389
+ "default": "./dist-lib/lib/tools/http-request/utils.js"
390
+ },
391
+ "./lib/tools/mcp/utils.ts": {
392
+ "types": "./dist-lib/lib/tools/mcp/utils.d.ts",
393
+ "default": "./dist-lib/lib/tools/mcp/utils.js"
394
+ },
395
+ "./lib/tools/model-args.ts": {
396
+ "types": "./dist-lib/lib/tools/model-args.d.ts",
397
+ "default": "./dist-lib/lib/tools/model-args.js"
398
+ },
399
+ "./lib/tools/operations/builders.ts": {
400
+ "types": "./dist-lib/lib/tools/operations/builders.d.ts",
401
+ "default": "./dist-lib/lib/tools/operations/builders.js"
402
+ },
198
403
  "./lib/tools/operations/compile.ts": {
199
404
  "types": "./dist-lib/lib/tools/operations/compile.d.ts",
200
405
  "default": "./dist-lib/lib/tools/operations/compile.js"
201
406
  },
407
+ "./lib/tools/operations/gmail-message.ts": {
408
+ "types": "./dist-lib/lib/tools/operations/gmail-message.d.ts",
409
+ "default": "./dist-lib/lib/tools/operations/gmail-message.js"
410
+ },
411
+ "./lib/tools/operations/manifest.ts": {
412
+ "types": "./dist-lib/lib/tools/operations/manifest.d.ts",
413
+ "default": "./dist-lib/lib/tools/operations/manifest.js"
414
+ },
415
+ "./lib/tools/outbound-guard.ts": {
416
+ "types": "./dist-lib/lib/tools/outbound-guard.d.ts",
417
+ "default": "./dist-lib/lib/tools/outbound-guard.js"
418
+ },
419
+ "./lib/tools/private-ip.ts": {
420
+ "types": "./dist-lib/lib/tools/private-ip.d.ts",
421
+ "default": "./dist-lib/lib/tools/private-ip.js"
422
+ },
423
+ "./lib/tools/read-files.ts": {
424
+ "types": "./dist-lib/lib/tools/read-files.d.ts",
425
+ "default": "./dist-lib/lib/tools/read-files.js"
426
+ },
427
+ "./lib/tools/skills/auth-resolver.ts": {
428
+ "types": "./dist-lib/lib/tools/skills/auth-resolver.d.ts",
429
+ "default": "./dist-lib/lib/tools/skills/auth-resolver.js"
430
+ },
431
+ "./lib/tools/skills/bin-check.ts": {
432
+ "types": "./dist-lib/lib/tools/skills/bin-check.d.ts",
433
+ "default": "./dist-lib/lib/tools/skills/bin-check.js"
434
+ },
202
435
  "./lib/tools/skills/bundled-dir.ts": {
203
436
  "types": "./dist-lib/lib/tools/skills/bundled-dir.d.ts",
204
437
  "default": "./dist-lib/lib/tools/skills/bundled-dir.js"
205
438
  },
439
+ "./lib/tools/skills/bundled-hash.ts": {
440
+ "types": "./dist-lib/lib/tools/skills/bundled-hash.d.ts",
441
+ "default": "./dist-lib/lib/tools/skills/bundled-hash.js"
442
+ },
443
+ "./lib/tools/skills/catalog.ts": {
444
+ "types": "./dist-lib/lib/tools/skills/catalog.d.ts",
445
+ "default": "./dist-lib/lib/tools/skills/catalog.js"
446
+ },
447
+ "./lib/tools/skills/cli-argv.ts": {
448
+ "types": "./dist-lib/lib/tools/skills/cli-argv.d.ts",
449
+ "default": "./dist-lib/lib/tools/skills/cli-argv.js"
450
+ },
451
+ "./lib/tools/skills/cli-schema-check.ts": {
452
+ "types": "./dist-lib/lib/tools/skills/cli-schema-check.d.ts",
453
+ "default": "./dist-lib/lib/tools/skills/cli-schema-check.js"
454
+ },
455
+ "./lib/tools/skills/cli-schema-load.ts": {
456
+ "types": "./dist-lib/lib/tools/skills/cli-schema-load.d.ts",
457
+ "default": "./dist-lib/lib/tools/skills/cli-schema-load.js"
458
+ },
459
+ "./lib/tools/skills/cli-schema-types.ts": {
460
+ "types": "./dist-lib/lib/tools/skills/cli-schema-types.d.ts",
461
+ "default": "./dist-lib/lib/tools/skills/cli-schema-types.js"
462
+ },
463
+ "./lib/tools/skills/cli-schema.ts": {
464
+ "types": "./dist-lib/lib/tools/skills/cli-schema.d.ts",
465
+ "default": "./dist-lib/lib/tools/skills/cli-schema.js"
466
+ },
467
+ "./lib/tools/skills/credential-check.ts": {
468
+ "types": "./dist-lib/lib/tools/skills/credential-check.d.ts",
469
+ "default": "./dist-lib/lib/tools/skills/credential-check.js"
470
+ },
471
+ "./lib/tools/skills/credential-grants.ts": {
472
+ "types": "./dist-lib/lib/tools/skills/credential-grants.d.ts",
473
+ "default": "./dist-lib/lib/tools/skills/credential-grants.js"
474
+ },
475
+ "./lib/tools/skills/credential-health.ts": {
476
+ "types": "./dist-lib/lib/tools/skills/credential-health.d.ts",
477
+ "default": "./dist-lib/lib/tools/skills/credential-health.js"
478
+ },
206
479
  "./lib/tools/skills/credential-slots.ts": {
207
480
  "types": "./dist-lib/lib/tools/skills/credential-slots.d.ts",
208
481
  "default": "./dist-lib/lib/tools/skills/credential-slots.js"
209
482
  },
483
+ "./lib/tools/skills/frontmatter-parser.ts": {
484
+ "types": "./dist-lib/lib/tools/skills/frontmatter-parser.d.ts",
485
+ "default": "./dist-lib/lib/tools/skills/frontmatter-parser.js"
486
+ },
210
487
  "./lib/tools/skills/manifest-parse.ts": {
211
488
  "types": "./dist-lib/lib/tools/skills/manifest-parse.d.ts",
212
489
  "default": "./dist-lib/lib/tools/skills/manifest-parse.js"
213
490
  },
491
+ "./lib/tools/skills/manifest.ts": {
492
+ "types": "./dist-lib/lib/tools/skills/manifest.d.ts",
493
+ "default": "./dist-lib/lib/tools/skills/manifest.js"
494
+ },
495
+ "./lib/tools/skills/obsidian-readiness.ts": {
496
+ "types": "./dist-lib/lib/tools/skills/obsidian-readiness.d.ts",
497
+ "default": "./dist-lib/lib/tools/skills/obsidian-readiness.js"
498
+ },
214
499
  "./lib/tools/skills/overlay-crud.ts": {
215
500
  "types": "./dist-lib/lib/tools/skills/overlay-crud.d.ts",
216
501
  "default": "./dist-lib/lib/tools/skills/overlay-crud.js"
217
502
  },
503
+ "./lib/tools/skills/overlay-dir.ts": {
504
+ "types": "./dist-lib/lib/tools/skills/overlay-dir.d.ts",
505
+ "default": "./dist-lib/lib/tools/skills/overlay-dir.js"
506
+ },
507
+ "./lib/tools/skills/overlay-watch.ts": {
508
+ "types": "./dist-lib/lib/tools/skills/overlay-watch.d.ts",
509
+ "default": "./dist-lib/lib/tools/skills/overlay-watch.js"
510
+ },
218
511
  "./lib/tools/skills/scope-key.ts": {
219
512
  "types": "./dist-lib/lib/tools/skills/scope-key.d.ts",
220
513
  "default": "./dist-lib/lib/tools/skills/scope-key.js"
221
514
  },
515
+ "./lib/tools/skills/setup-routes.ts": {
516
+ "types": "./dist-lib/lib/tools/skills/setup-routes.d.ts",
517
+ "default": "./dist-lib/lib/tools/skills/setup-routes.js"
518
+ },
519
+ "./lib/tools/skills/skill-settings.ts": {
520
+ "types": "./dist-lib/lib/tools/skills/skill-settings.d.ts",
521
+ "default": "./dist-lib/lib/tools/skills/skill-settings.js"
522
+ },
523
+ "./lib/tools/skills/skill-state-constants.ts": {
524
+ "types": "./dist-lib/lib/tools/skills/skill-state-constants.d.ts",
525
+ "default": "./dist-lib/lib/tools/skills/skill-state-constants.js"
526
+ },
222
527
  "./lib/tools/skills/skill-state.ts": {
223
528
  "types": "./dist-lib/lib/tools/skills/skill-state.d.ts",
224
529
  "default": "./dist-lib/lib/tools/skills/skill-state.js"
530
+ },
531
+ "./lib/tools/skills/tool-grants.ts": {
532
+ "types": "./dist-lib/lib/tools/skills/tool-grants.d.ts",
533
+ "default": "./dist-lib/lib/tools/skills/tool-grants.js"
534
+ },
535
+ "./lib/tools/url-guard.ts": {
536
+ "types": "./dist-lib/lib/tools/url-guard.d.ts",
537
+ "default": "./dist-lib/lib/tools/url-guard.js"
225
538
  }
226
539
  },
227
540
  "scripts": {
@@ -0,0 +1,174 @@
1
+ // bare-stow entry: serves the Harness over the ipc duplex bare-stow wires.
2
+ // argv (empty = absent): [2] skillsDir, [3] SDK storage JSON (required: the fs deny list fences it), [4] embedding config JSON,
3
+ // [5] imageModel JSON, [6] imageClamps JSON,
4
+ // [7] '1' to enable harness logging (written to `harness.log`, beside assistant.log),
5
+ // [8] llm config JSON (llmDevice/llmGpuLayers/contextSize/kvCacheK/kvCacheV),
6
+ // [9] musicModel JSON, [10] musicClamps JSON, [11] vendored python wheels dir.
7
+ import FileLog from 'bare-file-logger'
8
+ import fs from 'fs'
9
+ import { dirname, join } from 'path'
10
+ import process from 'bare-process'
11
+ import { configureSdkStorage } from '../dist-lib/lib/sdk-storage.js'
12
+ import {
13
+ Harness,
14
+ loadSkillCatalog,
15
+ serveHarness,
16
+ setHarnessLog,
17
+ setHarnessLogSink
18
+ } from '../dist-lib/index.js'
19
+ import { createCreateDocumentsTool } from '../dist-lib/lib/tools/create-documents.js'
20
+ import { createEditDocumentsTool } from '../dist-lib/lib/tools/edit-documents.js'
21
+ import { createExecTool } from '../dist-lib/lib/tools/exec.js'
22
+ import { createFileGlobTool } from '../dist-lib/lib/tools/file-glob.js'
23
+ import { deniedRootsFor } from '../dist-lib/lib/tools/fs/scope.js'
24
+ import { createGrepTool } from '../dist-lib/lib/tools/grep.js'
25
+ import { createHttpRequestTool } from '../dist-lib/lib/tools/http-request.js'
26
+ import { createMcpCallTool } from '../dist-lib/lib/tools/mcp-call.js'
27
+ import { compileOperationTools } from '../dist-lib/lib/tools/operations/compile.js'
28
+ import { createReadFilesTool } from '../dist-lib/lib/tools/read-files.js'
29
+ import { createSkillTool } from '../dist-lib/lib/tools/skill.js'
30
+ import { ensureBundledSkillsDir } from '../dist-lib/lib/tools/skills/bundled-dir.js'
31
+ import { credentialAllowListFor, mcpReadMethods } from '../dist-lib/lib/tools/skills/index.js'
32
+ import { createWebFetchTool } from '../dist-lib/lib/tools/web-fetch.js'
33
+ import { createWebSearchTool } from '../dist-lib/lib/tools/web-search.js'
34
+
35
+ // at maxSize rotate to a single overwritten archive, as the assistant's Logger does
36
+ const LOG_MAX_SIZE = 100_000_000
37
+ const SCOPE = '[harness]'
38
+ // when the file will not open, everything still has somewhere to go that is not the pipe
39
+ const DISCARD = { info() {}, debug() {}, warn() {}, error() {} }
40
+
41
+ // On Windows the host does not read our stdout, and writing past the OS buffer takes the
42
+ // Bare thread with it: the event loop stops, nothing raises, and a download never produces
43
+ // a byte. Elsewhere the same write only queues in memory (measured), which is why it only
44
+ // showed up there. Every line goes to a file instead, via the FileLog the assistant uses.
45
+ function openHarnessLog(path) {
46
+ try {
47
+ fs.mkdirSync(dirname(path), { recursive: true })
48
+ return new FileLog(path, { maxSize: LOG_MAX_SIZE, rotate: (p) => `${p}.1` })
49
+ } catch {
50
+ return null
51
+ }
52
+ }
53
+
54
+ // Ungated by the host's log flag: the SDK and its addons log through `console`, and a
55
+ // chatty dependency must not be able to wedge this process.
56
+ function captureConsole(log) {
57
+ console.log = console.info = (...args) => log.info(SCOPE, ...args)
58
+ console.debug = (...args) => log.debug(SCOPE, ...args)
59
+ console.warn = (...args) => log.warn(SCOPE, ...args)
60
+ console.error = (...args) => log.error(SCOPE, ...args)
61
+ }
62
+
63
+ // The SDK's logger has console on by default, whoever asked; follow the host instead.
64
+ async function alignSdkConsoleWithHost(hostWantsLogs) {
65
+ try {
66
+ const logging = await import('@qvac/sdk/logging')
67
+ logging.setGlobalConsoleOutput(hostWantsLogs)
68
+ } catch {
69
+ // a log setting must not decide whether this process boots
70
+ }
71
+ }
72
+
73
+ export default async function start(ipc, ready) {
74
+ let harness
75
+ let dying = false
76
+ // close() cancels in-flight SDK model loads (see Harness._close) so exit is not
77
+ // parked behind a multi-GB load; a wedged native call still ends at the host's
78
+ // kill deadline (bare-supervisor/stow reap)
79
+ const die = () => {
80
+ if (dying) return
81
+ dying = true
82
+ Promise.resolve(harness?.close())
83
+ .catch(() => {})
84
+ .then(() => Bare.exit(0))
85
+ }
86
+ Bare.IPC.on('end', die).on('close', die)
87
+
88
+ const sdkStorage = JSON.parse(Bare.argv[3] || '{}')
89
+ const deniedRoots = deniedRootsFor(sdkStorage.home)
90
+ const hostWantsLogs = Bare.argv[7] === '1'
91
+ setHarnessLog(hostWantsLogs)
92
+ // before the first await, so nothing logs ahead of the sink. The SDK home sits in
93
+ // the storage root, which is where the host writes assistant.log — harness.log
94
+ // belongs next to it.
95
+ const log = openHarnessLog(join(dirname(sdkStorage.home), 'harness.log')) ?? DISCARD
96
+ setHarnessLogSink((line) => log.info(SCOPE, line))
97
+ captureConsole(log)
98
+ await alignSdkConsoleWithHost(hostWantsLogs)
99
+
100
+ const skillsDir = Bare.argv[2] || (await ensureBundledSkillsDir())
101
+ const embedConfig = JSON.parse(Bare.argv[4] || '{}')
102
+ const imageModel = Bare.argv[5] ? JSON.parse(Bare.argv[5]) : undefined
103
+ const imageClamps = Bare.argv[6] ? JSON.parse(Bare.argv[6]) : undefined
104
+ const llmConfig = Bare.argv[8] ? JSON.parse(Bare.argv[8]) : {}
105
+ const musicModel = Bare.argv[9] ? JSON.parse(Bare.argv[9]) : undefined
106
+ const musicClamps = Bare.argv[10] ? JSON.parse(Bare.argv[10]) : undefined
107
+ // Only the host knows where the shipped wheels landed.
108
+ if (Bare.argv[11]) process.env.QVAC_PYTHON_WHEELS_DIR = Bare.argv[11]
109
+
110
+ configureSdkStorage(sdkStorage)
111
+ process.env.QVAC_PYODIDE_CACHE_DIR = `${sdkStorage.home}/pyodide-cache`
112
+
113
+ const skillCatalog = skillsDir ? await loadSkillCatalog(skillsDir) : undefined
114
+ const credentialed = skillCatalog
115
+ ? {
116
+ credentialStore: (key, ctx) => harness?.resolveCredential(key, ctx) ?? null,
117
+ credentialAllowList: credentialAllowListFor(skillCatalog)
118
+ }
119
+ : undefined
120
+
121
+ const httpRequestTool = createHttpRequestTool(credentialed)
122
+ const mcpCallTool = createMcpCallTool({
123
+ ...credentialed,
124
+ readMethods: skillCatalog ? mcpReadMethods(skillCatalog) : undefined
125
+ })
126
+ const tools = [
127
+ httpRequestTool,
128
+ createExecTool({
129
+ ...credentialed,
130
+ deniedRoots,
131
+ skillsDir,
132
+ skillSettings: (skill, agentId) => harness?.skillSettings(skill, agentId) ?? {}
133
+ }),
134
+ mcpCallTool,
135
+ createWebSearchTool(),
136
+ createWebFetchTool(),
137
+ createReadFilesTool({ deniedRoots }),
138
+ createFileGlobTool({ deniedRoots }),
139
+ createGrepTool({ deniedRoots }),
140
+ createCreateDocumentsTool({ deniedRoots }),
141
+ createEditDocumentsTool({ deniedRoots })
142
+ ]
143
+ if (skillCatalog) {
144
+ tools.push(...compileOperationTools(skillCatalog, { httpRequestTool, mcpCallTool }))
145
+ }
146
+ if (skillsDir) {
147
+ tools.push(
148
+ createSkillTool({
149
+ skillsDir,
150
+ ...(credentialed ? { credentialStore: credentialed.credentialStore } : {})
151
+ })
152
+ )
153
+ }
154
+ harness = new Harness({
155
+ tools,
156
+ skillsDir,
157
+ imageModel,
158
+ imageClamps,
159
+ musicModel,
160
+ musicClamps,
161
+ embedDevice: embedConfig.device,
162
+ embedGpuLayers: embedConfig.gpuLayers,
163
+ embedBatchSize: embedConfig.batchSize,
164
+ llmDevice: llmConfig.llmDevice,
165
+ llmGpuLayers: llmConfig.llmGpuLayers,
166
+ contextSize: llmConfig.contextSize,
167
+ kvCacheK: llmConfig.kvCacheK,
168
+ kvCacheV: llmConfig.kvCacheV
169
+ })
170
+ serveHarness(ipc, harness)
171
+ ready()
172
+
173
+ return () => {}
174
+ }
@@ -0,0 +1,68 @@
1
+ /* global Bare */
2
+ // What bare-stow generates as a bundle's `__main__.mjs`, as a plain file.
3
+ //
4
+ // A stow bundle is two halves: the JS inlined into it, and the native addons
5
+ // offloaded beside it, because dlopen cannot read a path inside a bundle. The
6
+ // tarball carries dist/prebuilds-manifest.json naming those addons, not the
7
+ // addons themselves, so whoever spawns the bundle has to put them back from
8
+ // their own node_modules — and then the two halves come from different
9
+ // installs. @qvac/core 0.1.2 shipped that way and hung on boot: a bare-pipe one
10
+ // patch release ahead of the JS calling it, no error, no exit.
11
+ //
12
+ // Nothing needs a bundle to spawn this. Run under `bare` from inside
13
+ // node_modules, every addon already sits beside the JS that calls it, out of
14
+ // one install, so they cannot disagree. The bundle stays published for hosts
15
+ // that relocate the code out of node_modules — a packaged desktop or mobile
16
+ // app, which stow their own entries anyway — and this is for everyone else.
17
+ //
18
+ // The protocol is bare-stow's own published export and the host end is
19
+ // unchanged: bare-supervisor's sidecar runner wraps this exactly as it wraps
20
+ // a bundle.
21
+ import protocol from 'bare-stow/protocol'
22
+
23
+ const ipc = protocol.attach(Bare.IPC)
24
+
25
+ let stop = null
26
+ let readied = false
27
+ let exited = false
28
+
29
+ function ready() {
30
+ if (readied) return
31
+ readied = true
32
+
33
+ ipc.send('ready')
34
+ }
35
+
36
+ async function shutdown(code, err = null) {
37
+ if (exited) return
38
+ exited = true
39
+
40
+ try {
41
+ if (stop) await stop()
42
+ } catch (e) {
43
+ err = err || e
44
+ }
45
+
46
+ if (err) ipc.send('error', { message: err.message, stack: err.stack })
47
+
48
+ await ipc.send('exit', { code })
49
+
50
+ Bare.exit(code)
51
+ }
52
+
53
+ ipc.on('terminate', () => shutdown(0))
54
+
55
+ Bare.on('beforeExit', (exitCode) => shutdown(exitCode))
56
+ .on('uncaughtException', (err) => shutdown(1, err))
57
+ .on('unhandledRejection', (err) => shutdown(1, err))
58
+
59
+ try {
60
+ const entry = await import('./harness-sidecar.mjs')
61
+ const start = entry.default
62
+
63
+ stop = (await start(ipc, ready)) || null
64
+
65
+ ready()
66
+ } catch (err) {
67
+ shutdown(1, err)
68
+ }