@fungi.computer/knapsack 0.1.0 → 0.2.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.
package/docs/api/index.md CHANGED
@@ -205,6 +205,7 @@ type FilesEditErrorReason =
205
205
  | "file-too-large"
206
206
  | "partial-character"
207
207
  | "unchanged"
208
+ | "not-text"
208
209
  | "conflict";
209
210
  ```
210
211
 
@@ -244,9 +245,9 @@ signal.
244
245
  type FilesPort = Readonly<{
245
246
  patch?: FilesPatch;
246
247
  read: (input, context) => Promise<z.output<typeof readOutputSchema>>;
247
- list: (input, context) => Promise<z.output<typeof listOutputSchema>>;
248
- glob: (input, context) => Promise<z.output<typeof globOutputSchema>>;
249
- grep: (input, context) => Promise<z.output<typeof grepOutputSchema>>;
248
+ list: (input, context) => Promise<z.output<typeof searchOutputSchema>>;
249
+ glob: (input, context) => Promise<z.output<typeof searchOutputSchema>>;
250
+ grep: (input, context) => Promise<z.output<typeof searchOutputSchema>>;
250
251
  replace: (
251
252
  input,
252
253
  context,
@@ -270,7 +271,7 @@ replacement.
270
271
  type FileToolName = "read" | "list" | "glob" | "grep" | "apply_patch";
271
272
  ```
272
273
 
273
- Closed set of direct, model-visible Files tools; widening one is an ADR.
274
+ Closed set of direct, model-visible Files tools; changing it is an ADR.
274
275
 
275
276
  ---
276
277
 
@@ -342,6 +343,7 @@ type ComputerConnectionOptions = Readonly<{
342
343
  id: string;
343
344
  name: string;
344
345
  namespace?: readonly string[];
346
+ confirmCalls?: boolean;
345
347
  files?: FilesConnectionOptions;
346
348
  role?: string;
347
349
  computer: KnapsackComputer;
@@ -410,7 +412,7 @@ type McpServersConnectionOptions = Readonly<{
410
412
  >;
411
413
  subscribe: (invalidate) => () => void;
412
414
  onUnavailable: (error) => void;
413
- fetch: FetchLike;
415
+ fetch: (url, init?) => Promise<Response>;
414
416
  namespace?: readonly string[];
415
417
  connectTimeoutMillis?: number;
416
418
  }>;
@@ -429,145 +431,150 @@ type McpServerUnavailableReason =
429
431
 
430
432
  Why one MCP server contributed no module to an acquisition.
431
433
 
432
- ## Variables
434
+ ---
433
435
 
434
- ### listInputSchema
436
+ ### UiConnectionOptions
435
437
 
436
438
  ```ts
437
- const listInputSchema: ZodObject<
438
- {
439
- path: ZodString;
440
- limit: ZodDefault<ZodNumber>;
441
- },
442
- $strict
443
- >;
439
+ type UiConnectionOptions = Readonly<{
440
+ id: string;
441
+ hasSession: (sessionId) => Promise<boolean>;
442
+ }>;
444
443
  ```
445
444
 
446
- Bounded directory listing request.
445
+ How one Agent host connects its Sessions' open Apps to Knapsack.ui.
447
446
 
448
447
  ---
449
448
 
450
- ### listOutputSchema
451
-
452
- ```ts
453
- const listOutputSchema: ZodObject<
454
- {
455
- path: ZodString;
456
- entries: ZodArray<
457
- ZodObject<
458
- {
459
- path: ZodString;
460
- name: ZodString;
461
- type: ZodEnum<{
462
- file: "file";
463
- directory: "directory";
464
- symlink: "symlink";
465
- }>;
466
- size: ZodNumber;
467
- modifiedAt: ZodNumber;
468
- },
469
- $strict
470
- >
471
- >;
472
- truncated: ZodBoolean;
473
- },
474
- $strict
475
- >;
449
+ ### UiConnection
450
+
451
+ ```ts
452
+ type UiConnection = Readonly<{
453
+ source: CapabilitySource;
454
+ fetch: (request) => Promise<Response>;
455
+ close: () => Promise<void>;
456
+ }>;
476
457
  ```
477
458
 
478
- Directory entries and an explicit truncation flag.
459
+ Live commands of the App open in each Agent Session's browser. The Agent reaches
460
+ them through the `ui` module (`ui.discover`, `ui.execute`); the browser runs
461
+ them through Whistle over the transport this connection serves.
479
462
 
480
- ---
463
+ ## Variables
481
464
 
482
- ### globInputSchema
465
+ ### listInputSchema
483
466
 
484
467
  ```ts
485
- const globInputSchema: ZodObject<
486
- {
487
- path: ZodString;
488
- pattern: ZodString;
489
- limit: ZodDefault<ZodNumber>;
490
- },
491
- $strict
468
+ const listInputSchema: ZodLazy<
469
+ ZodObject<
470
+ {
471
+ path: ZodDefault<ZodLazy<ZodString>>;
472
+ limit: ZodDefault<ZodNumber>;
473
+ },
474
+ $strict
475
+ >
492
476
  >;
493
477
  ```
494
478
 
495
- Bounded path-pattern search request.
479
+ List one directory level.
496
480
 
497
481
  ---
498
482
 
499
- ### globOutputSchema
483
+ ### globInputSchema
500
484
 
501
485
  ```ts
502
- const globOutputSchema: ZodObject<
503
- {
504
- path: ZodString;
505
- matches: ZodArray<ZodString>;
506
- truncated: ZodBoolean;
507
- },
508
- $strict
486
+ const globInputSchema: ZodLazy<
487
+ ZodObject<
488
+ {
489
+ path: ZodDefault<ZodLazy<ZodString>>;
490
+ pattern: ZodString;
491
+ limit: ZodDefault<ZodNumber>;
492
+ },
493
+ $strict
494
+ >
509
495
  >;
510
496
  ```
511
497
 
512
- Matching paths and an explicit truncation flag.
498
+ Match paths below a directory by glob.
513
499
 
514
500
  ---
515
501
 
516
502
  ### grepInputSchema
517
503
 
518
504
  ```ts
519
- const grepInputSchema: ZodObject<
520
- {
521
- path: ZodString;
522
- pattern: ZodString;
523
- regex: ZodDefault<ZodBoolean>;
524
- ignoreCase: ZodDefault<ZodBoolean>;
525
- limit: ZodDefault<ZodNumber>;
526
- },
527
- $strict
505
+ const grepInputSchema: ZodLazy<
506
+ ZodObject<
507
+ {
508
+ path: ZodDefault<ZodLazy<ZodString>>;
509
+ pattern: ZodString;
510
+ include: ZodOptional<ZodString>;
511
+ regex: ZodDefault<ZodBoolean>;
512
+ ignoreCase: ZodDefault<ZodBoolean>;
513
+ limit: ZodDefault<ZodNumber>;
514
+ },
515
+ $strict
516
+ >
528
517
  >;
529
518
  ```
530
519
 
531
- Bounded content-search request with optional regular-expression matching.
520
+ Search file content, optionally restricted to matching paths.
532
521
 
533
522
  ---
534
523
 
535
- ### grepOutputSchema
536
-
537
- ```ts
538
- const grepOutputSchema: ZodObject<
539
- {
540
- path: ZodString;
541
- matches: ZodArray<
542
- ZodObject<
543
- {
544
- path: ZodString;
545
- line: ZodNumber;
546
- text: ZodString;
547
- },
548
- $strict
549
- >
550
- >;
551
- truncated: ZodBoolean;
552
- },
553
- $strict
524
+ ### searchOutputSchema
525
+
526
+ ```ts
527
+ const searchOutputSchema: ZodLazy<
528
+ ZodObject<
529
+ {
530
+ path: ZodLazy<ZodString>;
531
+ results: ZodArray<
532
+ ZodLazy<
533
+ ZodObject<
534
+ {
535
+ path: ZodLazy<ZodString>;
536
+ type: ZodExactOptional<
537
+ ZodEnum<{
538
+ file: "file";
539
+ directory: "directory";
540
+ symlink: "symlink";
541
+ }>
542
+ >;
543
+ line: ZodExactOptional<ZodNumber>;
544
+ text: ZodExactOptional<ZodString>;
545
+ },
546
+ $strict
547
+ >
548
+ >
549
+ >;
550
+ truncated: ZodNullable<
551
+ ZodEnum<{
552
+ limit: "limit";
553
+ scan: "scan";
554
+ }>
555
+ >;
556
+ },
557
+ $strict
558
+ >
554
559
  >;
555
560
  ```
556
561
 
557
- Content matches and an explicit truncation flag.
562
+ Found paths or matching lines, and which cap (if any) cut the search short.
558
563
 
559
564
  ---
560
565
 
561
566
  ### editInputSchema
562
567
 
563
568
  ```ts
564
- const editInputSchema: ZodObject<
565
- {
566
- path: ZodString;
567
- oldText: ZodString;
568
- newText: ZodString;
569
- },
570
- $strict
569
+ const editInputSchema: ZodLazy<
570
+ ZodObject<
571
+ {
572
+ path: ZodLazy<ZodString>;
573
+ oldText: ZodString;
574
+ newText: ZodString;
575
+ },
576
+ $strict
577
+ >
571
578
  >;
572
579
  ```
573
580
 
@@ -578,7 +585,7 @@ Text replacement request decoded before the captured Files port is called.
578
585
  ### filesEditFailureSchema
579
586
 
580
587
  ```ts
581
- const filesEditFailureSchema: ZodObject<{
588
+ const filesEditFailureSchema: ZodLazy<ZodObject<{
582
589
  status: ZodLiteral<"failed">;
583
590
  error: ZodObject<{
584
591
  kind: ZodEnum<{
@@ -587,12 +594,13 @@ const filesEditFailureSchema: ZodObject<{
587
594
  file-too-large: "file-too-large";
588
595
  partial-character: "partial-character";
589
596
  unchanged: "unchanged";
597
+ not-text: "not-text";
590
598
  conflict: "conflict";
591
599
  }>;
592
- path: ZodString;
600
+ path: ZodLazy<ZodString>;
593
601
  message: ZodString;
594
602
  }, $strict>;
595
- }, $strict>;
603
+ }, $strict>>;
596
604
  ```
597
605
 
598
606
  Structured edit refusal, including its reason and affected path.
@@ -602,8 +610,8 @@ Structured edit refusal, including its reason and affected path.
602
610
  ### editOutputSchema
603
611
 
604
612
  ```ts
605
- const editOutputSchema: ZodUnion<readonly [ZodObject<{
606
- path: ZodString;
613
+ const editOutputSchema: ZodUnion<readonly [ZodLazy<ZodObject<{
614
+ path: ZodLazy<ZodString>;
607
615
  bytes: ZodNumber;
608
616
  diff: ZodString;
609
617
  firstChangedLine: ZodNullable<ZodNumber>;
@@ -612,7 +620,7 @@ const editOutputSchema: ZodUnion<readonly [ZodObject<{
612
620
  unifiedPatchAddedLines: ZodNumber;
613
621
  unifiedPatchRemovedLines: ZodNumber;
614
622
  unifiedPatchTruncated: ZodBoolean;
615
- }, $strict>, ZodObject<{
623
+ }, $strict>>, ZodLazy<ZodObject<{
616
624
  status: ZodLiteral<"failed">;
617
625
  error: ZodObject<{
618
626
  kind: ZodEnum<{
@@ -621,12 +629,13 @@ const editOutputSchema: ZodUnion<readonly [ZodObject<{
621
629
  file-too-large: "file-too-large";
622
630
  partial-character: "partial-character";
623
631
  unchanged: "unchanged";
632
+ not-text: "not-text";
624
633
  conflict: "conflict";
625
634
  }>;
626
- path: ZodString;
635
+ path: ZodLazy<ZodString>;
627
636
  message: ZodString;
628
637
  }, $strict>;
629
- }, $strict>]>;
638
+ }, $strict>>]>;
630
639
  ```
631
640
 
632
641
  Successful edit metadata or a typed edit refusal.
@@ -641,6 +650,7 @@ const Knapsack: Readonly<{
641
650
  computers: (input) => CapabilitySource;
642
651
  files: (input) => FilesSurface;
643
652
  mcpServers: (input) => CapabilitySource;
653
+ ui: (options) => UiConnection;
644
654
  }>;
645
655
  ```
646
656
 
@@ -676,6 +686,7 @@ function edit(
676
686
  | "file-too-large"
677
687
  | "partial-character"
678
688
  | "unchanged"
689
+ | "not-text"
679
690
  | "conflict";
680
691
  path: string;
681
692
  message: string;
@@ -705,8 +716,92 @@ captured FilesPort.
705
716
  `unifiedPatchBytes`: `number`; `unifiedPatchAddedLines`: `number`;
706
717
  `unifiedPatchRemovedLines`: `number`; `unifiedPatchTruncated`: `boolean`; \} \|
707
718
  \{ `status`: `"failed"`; `error`: \{ `kind`: \| `"not-found"` \| `"ambiguous"`
708
- \| `"file-too-large"` \| `"partial-character"` \| `"unchanged"` \| `"conflict"`;
709
- `path`: `string`; `message`: `string`; \}; \}\>
719
+ \| `"file-too-large"` \| `"partial-character"` \| `"unchanged"` \| `"not-text"`
720
+ \| `"conflict"`; `path`: `string`; `message`: `string`; \}; \}\>
721
+
722
+ ---
723
+
724
+ ### presentReadForGuest()
725
+
726
+ ```ts
727
+ function presentReadForGuest(
728
+ result,
729
+ context,
730
+ ):
731
+ | {
732
+ path: string;
733
+ content: string;
734
+ offset: number;
735
+ nextOffset: number | null;
736
+ truncated: boolean;
737
+ file?: {
738
+ computerId: string;
739
+ path: string;
740
+ };
741
+ }
742
+ | {
743
+ path: string;
744
+ image: {
745
+ ref: string;
746
+ mimeType: "image/png" | "image/jpeg" | "image/gif" | "image/webp";
747
+ bytes: number;
748
+ };
749
+ };
750
+ ```
751
+
752
+ Guest code and MCP callers never receive base64: the image goes through the
753
+ execution's image collector (the `images.view` path) and the value is a caption.
754
+
755
+ #### Parameters
756
+
757
+ | Parameter | Type |
758
+ | --------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
759
+ | `result` | \| \{ `path`: `string`; `content`: `string`; `offset`: `number`; `nextOffset`: `number` \| `null`; `truncated`: `boolean`; `file?`: \{ `computerId`: `string`; `path`: `string`; \}; \} \| \{ `path`: `string`; `image`: \{ `mimeType`: `"image/png"` \| `"image/jpeg"` \| `"image/gif"` \| `"image/webp"`; `data`: `string`; `bytes`: `number`; \}; `file?`: \{ `computerId`: `string`; `path`: `string`; \}; \} |
760
+ | `context` | `InvocationContext` |
761
+
762
+ #### Returns
763
+
764
+ ##### Type Literal
765
+
766
+ ```ts
767
+ {
768
+ path: string;
769
+ content: string;
770
+ offset: number;
771
+ nextOffset: number | null;
772
+ truncated: boolean;
773
+ file?: {
774
+ computerId: string;
775
+ path: string;
776
+ };
777
+ }
778
+ ```
779
+
780
+ | Name | Type | Default value | Description |
781
+ | ----------------- | ------------------ | ------------- | -------------------------------------------------------------------------------- |
782
+ | `path` | `string` | `pathSchema` | - |
783
+ | `content` | `string` | - | - |
784
+ | `offset` | `number` | - | - |
785
+ | `nextOffset` | `number` \| `null` | - | - |
786
+ | `truncated` | `boolean` | - | - |
787
+ | `file?` | `object` | - | Captured hosted file identity; a local Files host may have no Computer identity. |
788
+ | `file.computerId` | `string` | - | - |
789
+ | `file.path` | `string` | - | - |
790
+
791
+ ---
792
+
793
+ ##### Type Literal
794
+
795
+ ```ts
796
+ {
797
+ path: string;
798
+ image: {
799
+ ref: string;
800
+ mimeType: "image/png" | "image/jpeg" | "image/gif" | "image/webp";
801
+ bytes: number;
802
+ }
803
+ }
804
+ ```
710
805
 
711
806
  ## References
712
807
 
@@ -722,6 +817,12 @@ Re-exports [readOutputSchema](files-read.md#readoutputschema)
722
817
 
723
818
  ---
724
819
 
820
+ ### readGuestOutputSchema
821
+
822
+ Re-exports [readGuestOutputSchema](files-read.md#readguestoutputschema)
823
+
824
+ ---
825
+
725
826
  ### patchInputSchema
726
827
 
727
828
  Re-exports [patchInputSchema](files-patch.md#patchinputschema)
@@ -0,0 +1,94 @@
1
+ <!-- Generated by Botanical API docs (TypeDoc + typedoc-plugin-markdown). Do not edit. -->
2
+
3
+ [**@fungi.computer/knapsack**](README.md)
4
+
5
+ ---
6
+
7
+ [@fungi.computer/knapsack](README.md) / ui-browser
8
+
9
+ # ui-browser
10
+
11
+ ## Classes
12
+
13
+ ### UiBrowserError
14
+
15
+ Browser-side platform failure before a correlated result is accepted.
16
+
17
+ #### Extends
18
+
19
+ - `Error`
20
+
21
+ #### Constructors
22
+
23
+ ##### Constructor
24
+
25
+ ```ts
26
+ new UiBrowserError(message, options?): UiBrowserError;
27
+ ```
28
+
29
+ ###### Parameters
30
+
31
+ | Parameter | Type |
32
+ | ---------- | -------------- |
33
+ | `message` | `string` |
34
+ | `options?` | `ErrorOptions` |
35
+
36
+ ###### Returns
37
+
38
+ [`UiBrowserError`](#uibrowsererror)
39
+
40
+ ###### Overrides
41
+
42
+ ```ts
43
+ Error.constructor;
44
+ ```
45
+
46
+ ## Type Aliases
47
+
48
+ ### BrowserConnectionOptions
49
+
50
+ ```ts
51
+ type BrowserConnectionOptions = Readonly<{
52
+ baseUrl: string;
53
+ whistle: Pick<WhistleRuntime, "snapshot" | "execute">;
54
+ transport?: Readonly<{
55
+ fetch: typeof globalThis.fetch;
56
+ openEvents: (url) => EventTarget & object;
57
+ }>;
58
+ }>;
59
+ ```
60
+
61
+ One Agent Session's browser transport and the App's command runtime.
62
+
63
+ ---
64
+
65
+ ### BrowserConnection
66
+
67
+ ```ts
68
+ type BrowserConnection = Readonly<{
69
+ closed: Promise<void>;
70
+ close: () => void;
71
+ }>;
72
+ ```
73
+
74
+ A live browser connection; close it when the selected Session changes.
75
+
76
+ ## Functions
77
+
78
+ ### connectBrowser()
79
+
80
+ ```ts
81
+ function connectBrowser(options): BrowserConnection;
82
+ ```
83
+
84
+ Start the named browser Promise facade over the Effect connection program.
85
+
86
+ #### Parameters
87
+
88
+ | Parameter | Type |
89
+ | --------- | ------------------------------------------------------- |
90
+ | `options` | [`BrowserConnectionOptions`](#browserconnectionoptions) |
91
+
92
+ #### Returns
93
+
94
+ [`BrowserConnection`](#browserconnection)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fungi.computer/knapsack",
3
- "version": "0.1.0",
3
+ "version": "0.2.1",
4
4
  "author": "Levi <levi@technomancy.dev>",
5
5
  "description": "Agent tool connections projected into Mycelium capability sources",
6
6
  "type": "module",
@@ -20,6 +20,10 @@
20
20
  "types": "./dist/files-read.d.ts",
21
21
  "import": "./dist/files-read.js"
22
22
  },
23
+ "./files-search": {
24
+ "types": "./dist/files-search.d.ts",
25
+ "import": "./dist/files-search.js"
26
+ },
23
27
  "./patch": {
24
28
  "types": "./dist/patch.d.ts",
25
29
  "import": "./dist/patch.js"
@@ -27,6 +31,10 @@
27
31
  "./files-read-codec": {
28
32
  "types": "./dist/files-read-codec.d.ts",
29
33
  "import": "./dist/files-read-codec.js"
34
+ },
35
+ "./ui/browser": {
36
+ "types": "./dist/ui-browser.d.ts",
37
+ "import": "./dist/ui-browser.js"
30
38
  }
31
39
  },
32
40
  "files": [
@@ -37,18 +45,21 @@
37
45
  "LICENSE.codex"
38
46
  ],
39
47
  "dependencies": {
40
- "@fungi.computer/cairn": "0.0.1",
41
- "@fungi.computer/forage": "0.1.0",
42
- "@fungi.computer/mule": "0.0.2",
43
- "@fungi.computer/mycelium": "0.1.0",
48
+ "@fungi.computer/cairn": "0.1.0",
49
+ "@fungi.computer/forage": "0.2.0",
50
+ "@fungi.computer/mule": "0.1.1",
51
+ "@fungi.computer/mycelium": "0.2.1",
52
+ "@fungi.computer/whistle": "0.1.0",
44
53
  "@modelcontextprotocol/client": "2.0.0",
45
54
  "diff": "8.0.4",
46
55
  "effect": "4.0.2",
56
+ "ignore": "7.0.6",
47
57
  "zod": "4.4.3"
48
58
  },
49
59
  "devDependencies": {
50
60
  "@modelcontextprotocol/server": "2.0.0",
51
61
  "@types/node": "24.13.3",
62
+ "eventsource": "5.1.1",
52
63
  "typescript": "5.9.3",
53
64
  "vitest": "4.1.11"
54
65
  },