@fungi.computer/knapsack 0.0.2 → 0.2.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.
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
 
@@ -429,145 +430,150 @@ type McpServerUnavailableReason =
429
430
 
430
431
  Why one MCP server contributed no module to an acquisition.
431
432
 
432
- ## Variables
433
+ ---
433
434
 
434
- ### listInputSchema
435
+ ### UiConnectionOptions
435
436
 
436
437
  ```ts
437
- const listInputSchema: ZodObject<
438
- {
439
- path: ZodString;
440
- limit: ZodDefault<ZodNumber>;
441
- },
442
- $strict
443
- >;
438
+ type UiConnectionOptions = Readonly<{
439
+ id: string;
440
+ hasSession: (sessionId) => Promise<boolean>;
441
+ }>;
444
442
  ```
445
443
 
446
- Bounded directory listing request.
444
+ How one Agent host connects its Sessions' open Apps to Knapsack.ui.
447
445
 
448
446
  ---
449
447
 
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
- >;
448
+ ### UiConnection
449
+
450
+ ```ts
451
+ type UiConnection = Readonly<{
452
+ source: CapabilitySource;
453
+ fetch: (request) => Promise<Response>;
454
+ close: () => Promise<void>;
455
+ }>;
476
456
  ```
477
457
 
478
- Directory entries and an explicit truncation flag.
458
+ Live commands of the App open in each Agent Session's browser. The Agent reaches
459
+ them through the `ui` module (`ui.discover`, `ui.execute`); the browser runs
460
+ them through Whistle over the transport this connection serves.
479
461
 
480
- ---
462
+ ## Variables
481
463
 
482
- ### globInputSchema
464
+ ### listInputSchema
483
465
 
484
466
  ```ts
485
- const globInputSchema: ZodObject<
486
- {
487
- path: ZodString;
488
- pattern: ZodString;
489
- limit: ZodDefault<ZodNumber>;
490
- },
491
- $strict
467
+ const listInputSchema: ZodLazy<
468
+ ZodObject<
469
+ {
470
+ path: ZodDefault<ZodLazy<ZodString>>;
471
+ limit: ZodDefault<ZodNumber>;
472
+ },
473
+ $strict
474
+ >
492
475
  >;
493
476
  ```
494
477
 
495
- Bounded path-pattern search request.
478
+ List one directory level.
496
479
 
497
480
  ---
498
481
 
499
- ### globOutputSchema
482
+ ### globInputSchema
500
483
 
501
484
  ```ts
502
- const globOutputSchema: ZodObject<
503
- {
504
- path: ZodString;
505
- matches: ZodArray<ZodString>;
506
- truncated: ZodBoolean;
507
- },
508
- $strict
485
+ const globInputSchema: ZodLazy<
486
+ ZodObject<
487
+ {
488
+ path: ZodDefault<ZodLazy<ZodString>>;
489
+ pattern: ZodString;
490
+ limit: ZodDefault<ZodNumber>;
491
+ },
492
+ $strict
493
+ >
509
494
  >;
510
495
  ```
511
496
 
512
- Matching paths and an explicit truncation flag.
497
+ Match paths below a directory by glob.
513
498
 
514
499
  ---
515
500
 
516
501
  ### grepInputSchema
517
502
 
518
503
  ```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
504
+ const grepInputSchema: ZodLazy<
505
+ ZodObject<
506
+ {
507
+ path: ZodDefault<ZodLazy<ZodString>>;
508
+ pattern: ZodString;
509
+ include: ZodOptional<ZodString>;
510
+ regex: ZodDefault<ZodBoolean>;
511
+ ignoreCase: ZodDefault<ZodBoolean>;
512
+ limit: ZodDefault<ZodNumber>;
513
+ },
514
+ $strict
515
+ >
528
516
  >;
529
517
  ```
530
518
 
531
- Bounded content-search request with optional regular-expression matching.
519
+ Search file content, optionally restricted to matching paths.
532
520
 
533
521
  ---
534
522
 
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
523
+ ### searchOutputSchema
524
+
525
+ ```ts
526
+ const searchOutputSchema: ZodLazy<
527
+ ZodObject<
528
+ {
529
+ path: ZodLazy<ZodString>;
530
+ results: ZodArray<
531
+ ZodLazy<
532
+ ZodObject<
533
+ {
534
+ path: ZodLazy<ZodString>;
535
+ type: ZodExactOptional<
536
+ ZodEnum<{
537
+ file: "file";
538
+ directory: "directory";
539
+ symlink: "symlink";
540
+ }>
541
+ >;
542
+ line: ZodExactOptional<ZodNumber>;
543
+ text: ZodExactOptional<ZodString>;
544
+ },
545
+ $strict
546
+ >
547
+ >
548
+ >;
549
+ truncated: ZodNullable<
550
+ ZodEnum<{
551
+ limit: "limit";
552
+ scan: "scan";
553
+ }>
554
+ >;
555
+ },
556
+ $strict
557
+ >
554
558
  >;
555
559
  ```
556
560
 
557
- Content matches and an explicit truncation flag.
561
+ Found paths or matching lines, and which cap (if any) cut the search short.
558
562
 
559
563
  ---
560
564
 
561
565
  ### editInputSchema
562
566
 
563
567
  ```ts
564
- const editInputSchema: ZodObject<
565
- {
566
- path: ZodString;
567
- oldText: ZodString;
568
- newText: ZodString;
569
- },
570
- $strict
568
+ const editInputSchema: ZodLazy<
569
+ ZodObject<
570
+ {
571
+ path: ZodLazy<ZodString>;
572
+ oldText: ZodString;
573
+ newText: ZodString;
574
+ },
575
+ $strict
576
+ >
571
577
  >;
572
578
  ```
573
579
 
@@ -578,7 +584,7 @@ Text replacement request decoded before the captured Files port is called.
578
584
  ### filesEditFailureSchema
579
585
 
580
586
  ```ts
581
- const filesEditFailureSchema: ZodObject<{
587
+ const filesEditFailureSchema: ZodLazy<ZodObject<{
582
588
  status: ZodLiteral<"failed">;
583
589
  error: ZodObject<{
584
590
  kind: ZodEnum<{
@@ -587,12 +593,13 @@ const filesEditFailureSchema: ZodObject<{
587
593
  file-too-large: "file-too-large";
588
594
  partial-character: "partial-character";
589
595
  unchanged: "unchanged";
596
+ not-text: "not-text";
590
597
  conflict: "conflict";
591
598
  }>;
592
- path: ZodString;
599
+ path: ZodLazy<ZodString>;
593
600
  message: ZodString;
594
601
  }, $strict>;
595
- }, $strict>;
602
+ }, $strict>>;
596
603
  ```
597
604
 
598
605
  Structured edit refusal, including its reason and affected path.
@@ -602,8 +609,8 @@ Structured edit refusal, including its reason and affected path.
602
609
  ### editOutputSchema
603
610
 
604
611
  ```ts
605
- const editOutputSchema: ZodUnion<readonly [ZodObject<{
606
- path: ZodString;
612
+ const editOutputSchema: ZodUnion<readonly [ZodLazy<ZodObject<{
613
+ path: ZodLazy<ZodString>;
607
614
  bytes: ZodNumber;
608
615
  diff: ZodString;
609
616
  firstChangedLine: ZodNullable<ZodNumber>;
@@ -612,7 +619,7 @@ const editOutputSchema: ZodUnion<readonly [ZodObject<{
612
619
  unifiedPatchAddedLines: ZodNumber;
613
620
  unifiedPatchRemovedLines: ZodNumber;
614
621
  unifiedPatchTruncated: ZodBoolean;
615
- }, $strict>, ZodObject<{
622
+ }, $strict>>, ZodLazy<ZodObject<{
616
623
  status: ZodLiteral<"failed">;
617
624
  error: ZodObject<{
618
625
  kind: ZodEnum<{
@@ -621,12 +628,13 @@ const editOutputSchema: ZodUnion<readonly [ZodObject<{
621
628
  file-too-large: "file-too-large";
622
629
  partial-character: "partial-character";
623
630
  unchanged: "unchanged";
631
+ not-text: "not-text";
624
632
  conflict: "conflict";
625
633
  }>;
626
- path: ZodString;
634
+ path: ZodLazy<ZodString>;
627
635
  message: ZodString;
628
636
  }, $strict>;
629
- }, $strict>]>;
637
+ }, $strict>>]>;
630
638
  ```
631
639
 
632
640
  Successful edit metadata or a typed edit refusal.
@@ -641,6 +649,7 @@ const Knapsack: Readonly<{
641
649
  computers: (input) => CapabilitySource;
642
650
  files: (input) => FilesSurface;
643
651
  mcpServers: (input) => CapabilitySource;
652
+ ui: (options) => UiConnection;
644
653
  }>;
645
654
  ```
646
655
 
@@ -676,6 +685,7 @@ function edit(
676
685
  | "file-too-large"
677
686
  | "partial-character"
678
687
  | "unchanged"
688
+ | "not-text"
679
689
  | "conflict";
680
690
  path: string;
681
691
  message: string;
@@ -705,8 +715,92 @@ captured FilesPort.
705
715
  `unifiedPatchBytes`: `number`; `unifiedPatchAddedLines`: `number`;
706
716
  `unifiedPatchRemovedLines`: `number`; `unifiedPatchTruncated`: `boolean`; \} \|
707
717
  \{ `status`: `"failed"`; `error`: \{ `kind`: \| `"not-found"` \| `"ambiguous"`
708
- \| `"file-too-large"` \| `"partial-character"` \| `"unchanged"` \| `"conflict"`;
709
- `path`: `string`; `message`: `string`; \}; \}\>
718
+ \| `"file-too-large"` \| `"partial-character"` \| `"unchanged"` \| `"not-text"`
719
+ \| `"conflict"`; `path`: `string`; `message`: `string`; \}; \}\>
720
+
721
+ ---
722
+
723
+ ### presentReadForGuest()
724
+
725
+ ```ts
726
+ function presentReadForGuest(
727
+ result,
728
+ context,
729
+ ):
730
+ | {
731
+ path: string;
732
+ content: string;
733
+ offset: number;
734
+ nextOffset: number | null;
735
+ truncated: boolean;
736
+ file?: {
737
+ computerId: string;
738
+ path: string;
739
+ };
740
+ }
741
+ | {
742
+ path: string;
743
+ image: {
744
+ ref: string;
745
+ mimeType: "image/png" | "image/jpeg" | "image/gif" | "image/webp";
746
+ bytes: number;
747
+ };
748
+ };
749
+ ```
750
+
751
+ Guest code and MCP callers never receive base64: the image goes through the
752
+ execution's image collector (the `images.view` path) and the value is a caption.
753
+
754
+ #### Parameters
755
+
756
+ | Parameter | Type |
757
+ | --------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
758
+ | `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`; \}; \} |
759
+ | `context` | `InvocationContext` |
760
+
761
+ #### Returns
762
+
763
+ ##### Type Literal
764
+
765
+ ```ts
766
+ {
767
+ path: string;
768
+ content: string;
769
+ offset: number;
770
+ nextOffset: number | null;
771
+ truncated: boolean;
772
+ file?: {
773
+ computerId: string;
774
+ path: string;
775
+ };
776
+ }
777
+ ```
778
+
779
+ | Name | Type | Default value | Description |
780
+ | ----------------- | ------------------ | ------------- | -------------------------------------------------------------------------------- |
781
+ | `path` | `string` | `pathSchema` | - |
782
+ | `content` | `string` | - | - |
783
+ | `offset` | `number` | - | - |
784
+ | `nextOffset` | `number` \| `null` | - | - |
785
+ | `truncated` | `boolean` | - | - |
786
+ | `file?` | `object` | - | Captured hosted file identity; a local Files host may have no Computer identity. |
787
+ | `file.computerId` | `string` | - | - |
788
+ | `file.path` | `string` | - | - |
789
+
790
+ ---
791
+
792
+ ##### Type Literal
793
+
794
+ ```ts
795
+ {
796
+ path: string;
797
+ image: {
798
+ ref: string;
799
+ mimeType: "image/png" | "image/jpeg" | "image/gif" | "image/webp";
800
+ bytes: number;
801
+ }
802
+ }
803
+ ```
710
804
 
711
805
  ## References
712
806
 
@@ -722,6 +816,12 @@ Re-exports [readOutputSchema](files-read.md#readoutputschema)
722
816
 
723
817
  ---
724
818
 
819
+ ### readGuestOutputSchema
820
+
821
+ Re-exports [readGuestOutputSchema](files-read.md#readguestoutputschema)
822
+
823
+ ---
824
+
725
825
  ### patchInputSchema
726
826
 
727
827
  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.0.2",
3
+ "version": "0.2.0",
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.0.2",
42
- "@fungi.computer/mule": "0.0.2",
43
- "@fungi.computer/mycelium": "0.0.2",
48
+ "@fungi.computer/cairn": "0.1.0",
49
+ "@fungi.computer/forage": "0.2.0",
50
+ "@fungi.computer/mule": "0.1.0",
51
+ "@fungi.computer/mycelium": "0.2.0",
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
  },