@soederpop/luca 0.0.29 → 0.0.31

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 (50) hide show
  1. package/commands/try-all-challenges.ts +1 -1
  2. package/docs/TABLE-OF-CONTENTS.md +0 -3
  3. package/docs/tutorials/20-browser-esm.md +234 -0
  4. package/package.json +1 -1
  5. package/src/agi/container.server.ts +4 -0
  6. package/src/agi/features/assistant.ts +120 -3
  7. package/src/agi/features/browser-use.ts +623 -0
  8. package/src/bootstrap/generated.ts +236 -308
  9. package/src/cli/build-info.ts +2 -2
  10. package/src/clients/rest.ts +7 -7
  11. package/src/command.ts +20 -1
  12. package/src/commands/chat.ts +22 -0
  13. package/src/commands/describe.ts +67 -2
  14. package/src/commands/prompt.ts +23 -3
  15. package/src/commands/serve.ts +27 -0
  16. package/src/container.ts +411 -113
  17. package/src/endpoint.ts +6 -0
  18. package/src/helper.ts +226 -5
  19. package/src/introspection/generated.agi.ts +16089 -10021
  20. package/src/introspection/generated.node.ts +5102 -2077
  21. package/src/introspection/generated.web.ts +379 -291
  22. package/src/introspection/index.ts +7 -0
  23. package/src/introspection/scan.ts +224 -7
  24. package/src/node/container.ts +31 -10
  25. package/src/node/features/content-db.ts +7 -7
  26. package/src/node/features/disk-cache.ts +11 -11
  27. package/src/node/features/esbuild.ts +3 -3
  28. package/src/node/features/file-manager.ts +15 -15
  29. package/src/node/features/fs.ts +23 -22
  30. package/src/node/features/git.ts +10 -10
  31. package/src/node/features/helpers.ts +5 -2
  32. package/src/node/features/ink.ts +13 -13
  33. package/src/node/features/ipc-socket.ts +8 -8
  34. package/src/node/features/networking.ts +3 -3
  35. package/src/node/features/os.ts +7 -7
  36. package/src/node/features/package-finder.ts +15 -15
  37. package/src/node/features/proc.ts +1 -1
  38. package/src/node/features/ui.ts +13 -13
  39. package/src/node/features/vm.ts +4 -4
  40. package/src/scaffolds/generated.ts +1 -1
  41. package/src/servers/express.ts +24 -6
  42. package/src/servers/mcp.ts +4 -4
  43. package/src/servers/socket.ts +6 -6
  44. package/docs/apis/features/node/window-manager.md +0 -445
  45. package/docs/examples/window-manager-layouts.md +0 -180
  46. package/docs/examples/window-manager.md +0 -125
  47. package/docs/window-manager-fix.md +0 -249
  48. package/scripts/test-window-manager-lifecycle.ts +0 -86
  49. package/scripts/test-window-manager.ts +0 -43
  50. package/src/node/features/window-manager.ts +0 -1603
@@ -1,7 +1,7 @@
1
1
  import { setBuildTimeData, setContainerBuildTimeData } from './index.js';
2
2
 
3
3
  // Auto-generated introspection registry data
4
- // Generated at: 2026-03-24T01:41:39.159Z
4
+ // Generated at: 2026-03-24T09:08:05.900Z
5
5
 
6
6
  setBuildTimeData('features.containerLink', {
7
7
  "id": "features.containerLink",
@@ -520,7 +520,34 @@ setBuildTimeData('features.speech', {
520
520
  "language": "ts",
521
521
  "code": "const speech = container.feature('speech')\nspeech.say('Hello from the browser!')\n\n// Choose a specific voice\nconst speech = container.feature('speech', { voice: 'Google UK English Female' })\nspeech.say('Cheerio!')"
522
522
  }
523
- ]
523
+ ],
524
+ "types": {
525
+ "Voice": {
526
+ "description": "",
527
+ "properties": {
528
+ "voiceURI": {
529
+ "type": "string",
530
+ "description": ""
531
+ },
532
+ "name": {
533
+ "type": "string",
534
+ "description": ""
535
+ },
536
+ "lang": {
537
+ "type": "string",
538
+ "description": ""
539
+ },
540
+ "localService": {
541
+ "type": "boolean",
542
+ "description": ""
543
+ },
544
+ "default": {
545
+ "type": "boolean",
546
+ "description": ""
547
+ }
548
+ }
549
+ }
550
+ }
524
551
  });
525
552
 
526
553
  setBuildTimeData('features.helpers', {
@@ -635,10 +662,10 @@ setBuildTimeData('features.helpers', {
635
662
  // Container introspection data
636
663
  setContainerBuildTimeData('Container', {
637
664
  "className": "Container",
638
- "description": "Containers are single objects that contain state, an event bus, and registries of helpers such as: - features - clients - servers A Helper represents a category of components in your program which have a common interface, e.g. all servers can be started / stopped, all features can be enabled, if supported, all clients can connect to something. A Helper can be introspected at runtime to learn about the interface of the helper. A helper has state, and emits events. You can design your own containers and load them up with the helpers you want for that environment.",
665
+ "description": "The Container is the core runtime object in Luca. It is a singleton per process that acts as an event bus, state machine, and dependency injector. It holds registries of helpers (features, clients, servers, commands, endpoints) and provides factory methods to create instances from them. All helper instances share the container's context, enabling them to communicate and coordinate. The container detects its runtime environment (Node, Bun, browser, Electron) and can load platform-specific feature implementations accordingly. Use `container.feature('name')` to create feature instances, `container.use(Plugin)` to extend the container with new capabilities, and `container.on('event', handler)` to react to lifecycle events.",
639
666
  "methods": {
640
667
  "subcontainer": {
641
- "description": "Creates a new subcontainer instance of the same concrete Container subclass. The new instance is constructed with the same options as this container, shallow-merged with any overrides you provide. This preserves the runtime container type (e.g. NodeContainer, BrowserContainer, etc.).",
668
+ "description": "Creates a new subcontainer instance of the same concrete Container subclass. The new instance is constructed with the same options as this container, shallow-merged with any overrides you provide. This preserves the runtime container type (e.g. NodeContainer, AGIContainer, etc.).",
642
669
  "parameters": {
643
670
  "this": {
644
671
  "type": "This",
@@ -646,17 +673,23 @@ setContainerBuildTimeData('Container', {
646
673
  },
647
674
  "options": {
648
675
  "type": "ConstructorParameters<This['constructor']>[0]",
649
- "description": "Options to override for the new container instance."
676
+ "description": "Options to override for the new container instance"
650
677
  }
651
678
  },
652
679
  "required": [
653
680
  "this",
654
681
  "options"
655
682
  ],
656
- "returns": "This"
683
+ "returns": "This",
684
+ "examples": [
685
+ {
686
+ "language": "ts",
687
+ "code": "const child = container.subcontainer({ cwd: '/tmp/workspace' })\nchild.cwd // '/tmp/workspace'"
688
+ }
689
+ ]
657
690
  },
658
691
  "addContext": {
659
- "description": "",
692
+ "description": "Add a value to the container's shared context, which is passed to all helper instances. Accepts either a key and value, or an object of key-value pairs to merge in.",
660
693
  "parameters": {
661
694
  "keyOrContext": {
662
695
  "type": "keyof ContainerContext | Partial<ContainerContext>",
@@ -664,105 +697,67 @@ setContainerBuildTimeData('Container', {
664
697
  },
665
698
  "value": {
666
699
  "type": "ContainerContext[keyof ContainerContext]",
667
- "description": "Parameter value"
700
+ "description": "The context value (omit when passing an object)"
668
701
  }
669
702
  },
670
703
  "required": [
671
704
  "keyOrContext"
672
705
  ],
673
- "returns": "this"
706
+ "returns": "this",
707
+ "examples": [
708
+ {
709
+ "language": "ts",
710
+ "code": "container.addContext('db', dbConnection)\ncontainer.addContext({ db: dbConnection, cache: redisClient })"
711
+ }
712
+ ]
674
713
  },
675
714
  "setState": {
676
- "description": "Sets the state of the container.",
715
+ "description": "Sets the state of the container. Accepts a partial state object to merge, or a function that receives the current state and returns the new state.",
677
716
  "parameters": {
678
717
  "newState": {
679
718
  "type": "SetStateValue<ContainerState>",
680
- "description": "The new state of the container."
719
+ "description": "A partial state object to merge, or a function `(current) => newState`"
681
720
  }
682
721
  },
683
722
  "required": [
684
723
  "newState"
685
724
  ],
686
- "returns": "void"
725
+ "returns": "this",
726
+ "examples": [
727
+ {
728
+ "language": "ts",
729
+ "code": "container.setState({ started: true })\ncontainer.setState((prev) => ({ ...prev, started: true }))"
730
+ }
731
+ ]
687
732
  },
688
733
  "bus": {
689
- "description": "Convenience method for creating a new event bus instance.",
734
+ "description": "Create a new standalone event bus instance. Useful when you need a scoped event channel that is independent of the container's own event bus.",
690
735
  "parameters": {},
691
736
  "required": [],
692
- "returns": "void"
737
+ "returns": "Bus",
738
+ "examples": [
739
+ {
740
+ "language": "ts",
741
+ "code": "const myBus = container.bus()\nmyBus.on('data', (payload) => console.log(payload))\nmyBus.emit('data', { count: 42 })"
742
+ }
743
+ ]
693
744
  },
694
745
  "newState": {
695
- "description": "Convenience method for creating a new observable State object.",
746
+ "description": "Create a new standalone observable State object. Useful when you need reactive state that is independent of the container's own state.",
696
747
  "parameters": {
697
748
  "initialState": {
698
749
  "type": "T",
699
- "description": "Parameter initialState"
750
+ "description": "The initial state object (defaults to empty)"
700
751
  }
701
752
  },
702
753
  "required": [],
703
- "returns": "void"
704
- },
705
- "normalizeHelperOptions": {
706
- "description": "Parse helper options through the helper's static options schema so defaults are materialized.",
707
- "parameters": {
708
- "BaseClass": {
709
- "type": "any",
710
- "description": "Parameter BaseClass"
711
- },
712
- "options": {
713
- "type": "any",
714
- "description": "Parameter options"
715
- },
716
- "fallbackName": {
717
- "type": "string",
718
- "description": "Parameter fallbackName"
719
- }
720
- },
721
- "required": [
722
- "BaseClass",
723
- "options"
724
- ],
725
- "returns": "void"
726
- },
727
- "buildHelperCacheKey": {
728
- "description": "",
729
- "parameters": {
730
- "type": {
731
- "type": "string",
732
- "description": "Parameter type"
733
- },
734
- "id": {
735
- "type": "string",
736
- "description": "Parameter id"
737
- },
738
- "options": {
739
- "type": "any",
740
- "description": "Parameter options"
741
- },
742
- "omitOptionKeys": {
743
- "type": "string[]",
744
- "description": "Parameter omitOptionKeys"
754
+ "returns": "State<T>",
755
+ "examples": [
756
+ {
757
+ "language": "ts",
758
+ "code": "const myState = container.newState({ count: 0, loading: false })\nmyState.observe(() => console.log('Changed:', myState.current))\nmyState.set('count', 1)"
745
759
  }
746
- },
747
- "required": [
748
- "type",
749
- "id",
750
- "options"
751
- ],
752
- "returns": "void"
753
- },
754
- "createHelperInstance": {
755
- "description": "",
756
- "parameters": {
757
- "{\n cache,\n type,\n id,\n BaseClass,\n options,\n fallbackName,\n omitOptionKeys = [],\n context,\n }": {
758
- "type": "{\n cache: Map<string, any>\n type: string\n id: string\n BaseClass: any\n options?: any\n fallbackName?: string\n omitOptionKeys?: string[]\n context?: any\n }",
759
- "description": "Parameter {\n cache,\n type,\n id,\n BaseClass,\n options,\n fallbackName,\n omitOptionKeys = [],\n context,\n }"
760
- }
761
- },
762
- "required": [
763
- "{\n cache,\n type,\n id,\n BaseClass,\n options,\n fallbackName,\n omitOptionKeys = [],\n context,\n }"
764
- ],
765
- "returns": "void"
760
+ ]
766
761
  },
767
762
  "feature": {
768
763
  "description": "Creates a new instance of a feature. If you pass the same arguments, it will return the same instance as last time you created that. If you need the ability to create fresh instances, it is up to you how you define your options to support that.",
@@ -782,136 +777,154 @@ setContainerBuildTimeData('Container', {
782
777
  "returns": "InstanceType<Features[T]>"
783
778
  },
784
779
  "start": {
785
- "description": "TODO: A container should be able to container.use(plugin) and that plugin should be able to define an asynchronous method that will be run when the container is started. Right now there's nothing to do with starting / stopping a container but that might be neat.",
780
+ "description": "Start the container. Emits the 'started' event and sets `state.started` to true. Plugins and features can listen for this event to perform initialization.",
786
781
  "parameters": {},
787
782
  "required": [],
788
- "returns": "void"
783
+ "returns": "Promise<this>",
784
+ "examples": [
785
+ {
786
+ "language": "ts",
787
+ "code": "container.on('started', () => console.log('Ready'))\nawait container.start()"
788
+ }
789
+ ]
789
790
  },
790
791
  "emit": {
791
792
  "description": "Emit an event on the container's event bus.",
792
793
  "parameters": {
793
794
  "event": {
794
795
  "type": "string",
795
- "description": "Parameter event"
796
+ "description": "The event name"
796
797
  },
797
798
  "args": {
798
799
  "type": "any[]",
799
- "description": "Parameter args"
800
+ "description": "Arguments to pass to listeners"
800
801
  }
801
802
  },
802
803
  "required": [
803
804
  "event",
804
805
  "args"
805
806
  ],
806
- "returns": "void"
807
+ "returns": "this",
808
+ "examples": [
809
+ {
810
+ "language": "ts",
811
+ "code": "container.emit('taskCompleted', { id: 'abc', result: 42 })"
812
+ }
813
+ ]
807
814
  },
808
815
  "on": {
809
816
  "description": "Subscribe to an event on the container's event bus.",
810
817
  "parameters": {
811
818
  "event": {
812
819
  "type": "string",
813
- "description": "Parameter event"
820
+ "description": "The event name"
814
821
  },
815
822
  "listener": {
816
823
  "type": "(...args: any[]) => void",
817
- "description": "Parameter listener"
824
+ "description": "The callback function"
818
825
  }
819
826
  },
820
827
  "required": [
821
828
  "event",
822
829
  "listener"
823
830
  ],
824
- "returns": "void"
831
+ "returns": "this",
832
+ "examples": [
833
+ {
834
+ "language": "ts",
835
+ "code": "container.on('featureEnabled', (id, feature) => {\n console.log(`Feature ${id} enabled`)\n})"
836
+ }
837
+ ]
825
838
  },
826
839
  "off": {
827
840
  "description": "Unsubscribe a listener from an event on the container's event bus.",
828
841
  "parameters": {
829
842
  "event": {
830
843
  "type": "string",
831
- "description": "Parameter event"
844
+ "description": "The event name"
832
845
  },
833
846
  "listener": {
834
847
  "type": "(...args: any[]) => void",
835
- "description": "Parameter listener"
848
+ "description": "The listener to remove"
836
849
  }
837
850
  },
838
851
  "required": [
839
852
  "event"
840
853
  ],
841
- "returns": "void"
854
+ "returns": "this"
842
855
  },
843
856
  "once": {
844
857
  "description": "Subscribe to an event on the container's event bus, but only fire once.",
845
858
  "parameters": {
846
859
  "event": {
847
860
  "type": "string",
848
- "description": "Parameter event"
861
+ "description": "The event name"
849
862
  },
850
863
  "listener": {
851
864
  "type": "(...args: any[]) => void",
852
- "description": "Parameter listener"
865
+ "description": "The callback function (invoked at most once)"
853
866
  }
854
867
  },
855
868
  "required": [
856
869
  "event",
857
870
  "listener"
858
871
  ],
859
- "returns": "void"
872
+ "returns": "this"
860
873
  },
861
874
  "waitFor": {
862
- "description": "Returns a promise that will resolve when the event is emitted",
875
+ "description": "Returns a promise that resolves the next time the given event is emitted. Useful for awaiting one-time lifecycle transitions.",
863
876
  "parameters": {
864
877
  "event": {
865
878
  "type": "string",
866
- "description": "Parameter event"
879
+ "description": "The event name to wait for"
867
880
  }
868
881
  },
869
882
  "required": [
870
883
  "event"
871
884
  ],
872
- "returns": "void"
873
- },
874
- "registerHelperType": {
875
- "description": "Register a helper type (registry + factory pair) on this container. Called automatically by Helper.attach() methods (e.g. Client.attach, Server.attach).",
876
- "parameters": {
877
- "registryName": {
878
- "type": "string",
879
- "description": "The plural name of the registry, e.g. \"clients\", \"servers\""
880
- },
881
- "factoryName": {
882
- "type": "string",
883
- "description": "The singular factory method name, e.g. \"client\", \"server\""
885
+ "returns": "Promise<any>",
886
+ "examples": [
887
+ {
888
+ "language": "ts",
889
+ "code": "await container.waitFor('started')\nconsole.log('Container is ready')"
884
890
  }
885
- },
886
- "required": [
887
- "registryName",
888
- "factoryName"
889
- ],
890
- "returns": "void"
891
+ ]
891
892
  },
892
893
  "inspect": {
893
894
  "description": "Returns a full introspection object for this container, merging build-time AST data (JSDoc descriptions, methods, getters) with runtime data (registries, factories, state, environment).",
894
895
  "parameters": {},
895
896
  "required": [],
896
- "returns": "ContainerIntrospection"
897
+ "returns": "ContainerIntrospection",
898
+ "examples": [
899
+ {
900
+ "language": "ts",
901
+ "code": "const info = container.inspect()\nconsole.log(info.methods) // all public methods with descriptions\nconsole.log(info.getters) // all getters with return types\nconsole.log(info.registries) // features, clients, servers, etc."
902
+ }
903
+ ]
897
904
  },
898
905
  "inspectAsText": {
899
- "description": "Returns a human-readable markdown representation of this container's introspection data. Useful in REPLs, AI agent contexts, or documentation generation. The first argument can be a section name (`'methods'`, `'getters'`, etc.) to render only that section, or a number for the starting heading depth (backward compatible).",
906
+ "description": "Returns a human-readable markdown representation of this container's introspection data. Useful in REPLs, AI agent contexts, or documentation generation. Pass a section name to render only that section (e.g. 'methods', 'getters', 'events', 'state').",
900
907
  "parameters": {
901
908
  "sectionOrDepth": {
902
909
  "type": "IntrospectionSection | number",
903
- "description": "Parameter sectionOrDepth"
910
+ "description": "A section name to render, or heading depth number"
904
911
  },
905
912
  "startHeadingDepth": {
906
913
  "type": "number",
907
- "description": "Parameter startHeadingDepth"
914
+ "description": "Starting markdown heading depth (default 1)"
908
915
  }
909
916
  },
910
917
  "required": [],
911
- "returns": "string"
918
+ "returns": "string",
919
+ "examples": [
920
+ {
921
+ "language": "ts",
922
+ "code": "console.log(container.inspectAsText()) // full description\nconsole.log(container.inspectAsText('methods')) // just methods"
923
+ }
924
+ ]
912
925
  },
913
926
  "introspectAsText": {
914
- "description": "Alias for inspectAsText",
927
+ "description": "Alias for inspectAsText.",
915
928
  "parameters": {
916
929
  "sectionOrDepth": {
917
930
  "type": "IntrospectionSection | number",
@@ -926,33 +939,42 @@ setContainerBuildTimeData('Container', {
926
939
  "returns": "string"
927
940
  },
928
941
  "introspectAsJSON": {
929
- "description": "Alias for inspectAsJSON",
930
- "parameters": {
931
- "sectionOrDepth": {
932
- "type": "IntrospectionSection | number",
933
- "description": "Parameter sectionOrDepth"
934
- },
935
- "startHeadingDepth": {
936
- "type": "number",
937
- "description": "Parameter startHeadingDepth"
942
+ "description": "Alias for inspect, returns JSON introspection data.",
943
+ "parameters": {},
944
+ "required": [],
945
+ "returns": "ContainerIntrospection"
946
+ },
947
+ "inspectAsType": {
948
+ "description": "Returns the container's introspection data formatted as a TypeScript interface declaration. Includes the container's own methods, getters, factories, and registered helper types.",
949
+ "parameters": {},
950
+ "required": [],
951
+ "returns": "string",
952
+ "examples": [
953
+ {
954
+ "language": "ts",
955
+ "code": "console.log(container.inspectAsType())\n// interface NodeContainer {\n// feature<T>(id: string, options?: object): T;\n// readonly uuid: string;\n// ...\n// }"
938
956
  }
939
- },
957
+ ]
958
+ },
959
+ "introspectAsType": {
960
+ "description": "",
961
+ "parameters": {},
940
962
  "required": [],
941
- "returns": "any"
963
+ "returns": "string"
942
964
  },
943
965
  "sleep": {
944
966
  "description": "Sleep for the specified number of milliseconds. Useful for scripting and sequencing.",
945
967
  "parameters": {
946
968
  "ms": {
947
- "type": "any",
969
+ "type": "number",
948
970
  "description": "Parameter ms"
949
971
  }
950
972
  },
951
973
  "required": [],
952
- "returns": "void"
974
+ "returns": "Promise<this>"
953
975
  },
954
976
  "use": {
955
- "description": "Apply a plugin or enable a feature by string name. Plugins must have a static attach(container) method.",
977
+ "description": "Apply a plugin or enable a feature by string name. Plugins are classes with a static `attach(container)` method that extend the container with new registries, factories, or capabilities.",
956
978
  "parameters": {
957
979
  "plugin": {
958
980
  "type": "Extension<T>",
@@ -966,25 +988,37 @@ setContainerBuildTimeData('Container', {
966
988
  "required": [
967
989
  "plugin"
968
990
  ],
969
- "returns": "this & T"
991
+ "returns": "this & T",
992
+ "examples": [
993
+ {
994
+ "language": "ts",
995
+ "code": "// Enable a feature by name\ncontainer.use('contentDb')\n\n// Attach a plugin class (e.g. Client, Server, or custom)\ncontainer.use(Client) // registers the clients registry + client() factory\ncontainer.use(Server) // registers the servers registry + server() factory"
996
+ }
997
+ ]
970
998
  }
971
999
  },
972
1000
  "getters": {
973
1001
  "state": {
974
1002
  "description": "The observable state object for this container instance.",
975
- "returns": "any"
1003
+ "returns": "State<ContainerState>"
976
1004
  },
977
1005
  "enabledFeatureIds": {
978
1006
  "description": "Returns the list of shortcut IDs for all currently enabled features.",
979
- "returns": "any"
1007
+ "returns": "string[]"
980
1008
  },
981
1009
  "enabledFeatures": {
982
1010
  "description": "Returns a map of enabled feature shortcut IDs to their instances.",
983
1011
  "returns": "Partial<AvailableInstanceTypes<Features>>"
984
1012
  },
985
- "describer": {
986
- "description": "Lazy-initialized ContainerDescriber for introspecting registries, helpers, and members.",
987
- "returns": "ContainerDescriber"
1013
+ "utils": {
1014
+ "description": "Common utilities available on every container. Provides UUID generation, object hashing, string case conversion, and lodash helpers — no imports needed. - `utils.uuid()` — generate a v4 UUID - `utils.hashObject(obj)` — deterministic hash of any object - `utils.stringUtils` — `{ kebabCase, camelCase, upperFirst, lowerFirst, pluralize, singularize }` - `utils.lodash` — `{ uniq, keyBy, uniqBy, groupBy, debounce, throttle, mapValues, mapKeys, pick, get, set, omit }`",
1015
+ "returns": "ContainerUtils",
1016
+ "examples": [
1017
+ {
1018
+ "language": "ts",
1019
+ "code": "const id = container.utils.uuid()\nconst hash = container.utils.hashObject({ foo: 'bar' })\nconst name = container.utils.stringUtils.camelCase('my-feature')\nconst unique = container.utils.lodash.uniq([1, 2, 2, 3])"
1020
+ }
1021
+ ]
988
1022
  },
989
1023
  "context": {
990
1024
  "description": "The Container's context is an object that contains the enabled features, the container itself, and any additional context that has been added to the container. All helper instances that are created by the container will have access to the shared context.",
@@ -992,35 +1026,45 @@ setContainerBuildTimeData('Container', {
992
1026
  },
993
1027
  "currentState": {
994
1028
  "description": "The current state of the container. This is a snapshot of the container's state at the time this method is called.",
995
- "returns": "any"
1029
+ "returns": "ContainerState"
1030
+ },
1031
+ "features": {
1032
+ "description": "The features registry. Use it to check what features are available, look up feature classes, or check if a feature is registered.",
1033
+ "returns": "FeaturesRegistry",
1034
+ "examples": [
1035
+ {
1036
+ "language": "ts",
1037
+ "code": "container.features.available // ['fs', 'git', 'grep', ...]\ncontainer.features.has('fs') // true\ncontainer.features.lookup('fs') // FS class"
1038
+ }
1039
+ ]
996
1040
  },
997
1041
  "isBrowser": {
998
1042
  "description": "Returns true if the container is running in a browser.",
999
- "returns": "any"
1043
+ "returns": "boolean"
1000
1044
  },
1001
1045
  "isBun": {
1002
1046
  "description": "Returns true if the container is running in Bun.",
1003
- "returns": "any"
1047
+ "returns": "boolean"
1004
1048
  },
1005
1049
  "isNode": {
1006
1050
  "description": "Returns true if the container is running in Node.",
1007
- "returns": "any"
1051
+ "returns": "boolean"
1008
1052
  },
1009
1053
  "isElectron": {
1010
1054
  "description": "Returns true if the container is running in Electron.",
1011
- "returns": "any"
1055
+ "returns": "boolean"
1012
1056
  },
1013
1057
  "isDevelopment": {
1014
1058
  "description": "Returns true if the container is running in development mode.",
1015
- "returns": "any"
1059
+ "returns": "boolean"
1016
1060
  },
1017
1061
  "isProduction": {
1018
1062
  "description": "Returns true if the container is running in production mode.",
1019
- "returns": "any"
1063
+ "returns": "boolean"
1020
1064
  },
1021
1065
  "isCI": {
1022
1066
  "description": "Returns true if the container is running in a CI environment.",
1023
- "returns": "any"
1067
+ "returns": "boolean"
1024
1068
  },
1025
1069
  "registryNames": {
1026
1070
  "description": "Returns the names of all attached registries (e.g. [\"features\", \"clients\", \"servers\"]).",
@@ -1571,7 +1615,34 @@ export const introspectionData = [
1571
1615
  "language": "ts",
1572
1616
  "code": "const speech = container.feature('speech')\nspeech.say('Hello from the browser!')\n\n// Choose a specific voice\nconst speech = container.feature('speech', { voice: 'Google UK English Female' })\nspeech.say('Cheerio!')"
1573
1617
  }
1574
- ]
1618
+ ],
1619
+ "types": {
1620
+ "Voice": {
1621
+ "description": "",
1622
+ "properties": {
1623
+ "voiceURI": {
1624
+ "type": "string",
1625
+ "description": ""
1626
+ },
1627
+ "name": {
1628
+ "type": "string",
1629
+ "description": ""
1630
+ },
1631
+ "lang": {
1632
+ "type": "string",
1633
+ "description": ""
1634
+ },
1635
+ "localService": {
1636
+ "type": "boolean",
1637
+ "description": ""
1638
+ },
1639
+ "default": {
1640
+ "type": "boolean",
1641
+ "description": ""
1642
+ }
1643
+ }
1644
+ }
1645
+ }
1575
1646
  },
1576
1647
  {
1577
1648
  "id": "features.helpers",
@@ -1686,10 +1757,10 @@ export const introspectionData = [
1686
1757
  export const containerIntrospectionData = [
1687
1758
  {
1688
1759
  "className": "Container",
1689
- "description": "Containers are single objects that contain state, an event bus, and registries of helpers such as: - features - clients - servers A Helper represents a category of components in your program which have a common interface, e.g. all servers can be started / stopped, all features can be enabled, if supported, all clients can connect to something. A Helper can be introspected at runtime to learn about the interface of the helper. A helper has state, and emits events. You can design your own containers and load them up with the helpers you want for that environment.",
1760
+ "description": "The Container is the core runtime object in Luca. It is a singleton per process that acts as an event bus, state machine, and dependency injector. It holds registries of helpers (features, clients, servers, commands, endpoints) and provides factory methods to create instances from them. All helper instances share the container's context, enabling them to communicate and coordinate. The container detects its runtime environment (Node, Bun, browser, Electron) and can load platform-specific feature implementations accordingly. Use `container.feature('name')` to create feature instances, `container.use(Plugin)` to extend the container with new capabilities, and `container.on('event', handler)` to react to lifecycle events.",
1690
1761
  "methods": {
1691
1762
  "subcontainer": {
1692
- "description": "Creates a new subcontainer instance of the same concrete Container subclass. The new instance is constructed with the same options as this container, shallow-merged with any overrides you provide. This preserves the runtime container type (e.g. NodeContainer, BrowserContainer, etc.).",
1763
+ "description": "Creates a new subcontainer instance of the same concrete Container subclass. The new instance is constructed with the same options as this container, shallow-merged with any overrides you provide. This preserves the runtime container type (e.g. NodeContainer, AGIContainer, etc.).",
1693
1764
  "parameters": {
1694
1765
  "this": {
1695
1766
  "type": "This",
@@ -1697,17 +1768,23 @@ export const containerIntrospectionData = [
1697
1768
  },
1698
1769
  "options": {
1699
1770
  "type": "ConstructorParameters<This['constructor']>[0]",
1700
- "description": "Options to override for the new container instance."
1771
+ "description": "Options to override for the new container instance"
1701
1772
  }
1702
1773
  },
1703
1774
  "required": [
1704
1775
  "this",
1705
1776
  "options"
1706
1777
  ],
1707
- "returns": "This"
1778
+ "returns": "This",
1779
+ "examples": [
1780
+ {
1781
+ "language": "ts",
1782
+ "code": "const child = container.subcontainer({ cwd: '/tmp/workspace' })\nchild.cwd // '/tmp/workspace'"
1783
+ }
1784
+ ]
1708
1785
  },
1709
1786
  "addContext": {
1710
- "description": "",
1787
+ "description": "Add a value to the container's shared context, which is passed to all helper instances. Accepts either a key and value, or an object of key-value pairs to merge in.",
1711
1788
  "parameters": {
1712
1789
  "keyOrContext": {
1713
1790
  "type": "keyof ContainerContext | Partial<ContainerContext>",
@@ -1715,105 +1792,67 @@ export const containerIntrospectionData = [
1715
1792
  },
1716
1793
  "value": {
1717
1794
  "type": "ContainerContext[keyof ContainerContext]",
1718
- "description": "Parameter value"
1795
+ "description": "The context value (omit when passing an object)"
1719
1796
  }
1720
1797
  },
1721
1798
  "required": [
1722
1799
  "keyOrContext"
1723
1800
  ],
1724
- "returns": "this"
1801
+ "returns": "this",
1802
+ "examples": [
1803
+ {
1804
+ "language": "ts",
1805
+ "code": "container.addContext('db', dbConnection)\ncontainer.addContext({ db: dbConnection, cache: redisClient })"
1806
+ }
1807
+ ]
1725
1808
  },
1726
1809
  "setState": {
1727
- "description": "Sets the state of the container.",
1810
+ "description": "Sets the state of the container. Accepts a partial state object to merge, or a function that receives the current state and returns the new state.",
1728
1811
  "parameters": {
1729
1812
  "newState": {
1730
1813
  "type": "SetStateValue<ContainerState>",
1731
- "description": "The new state of the container."
1814
+ "description": "A partial state object to merge, or a function `(current) => newState`"
1732
1815
  }
1733
1816
  },
1734
1817
  "required": [
1735
1818
  "newState"
1736
1819
  ],
1737
- "returns": "void"
1820
+ "returns": "this",
1821
+ "examples": [
1822
+ {
1823
+ "language": "ts",
1824
+ "code": "container.setState({ started: true })\ncontainer.setState((prev) => ({ ...prev, started: true }))"
1825
+ }
1826
+ ]
1738
1827
  },
1739
1828
  "bus": {
1740
- "description": "Convenience method for creating a new event bus instance.",
1829
+ "description": "Create a new standalone event bus instance. Useful when you need a scoped event channel that is independent of the container's own event bus.",
1741
1830
  "parameters": {},
1742
1831
  "required": [],
1743
- "returns": "void"
1832
+ "returns": "Bus",
1833
+ "examples": [
1834
+ {
1835
+ "language": "ts",
1836
+ "code": "const myBus = container.bus()\nmyBus.on('data', (payload) => console.log(payload))\nmyBus.emit('data', { count: 42 })"
1837
+ }
1838
+ ]
1744
1839
  },
1745
1840
  "newState": {
1746
- "description": "Convenience method for creating a new observable State object.",
1841
+ "description": "Create a new standalone observable State object. Useful when you need reactive state that is independent of the container's own state.",
1747
1842
  "parameters": {
1748
1843
  "initialState": {
1749
1844
  "type": "T",
1750
- "description": "Parameter initialState"
1845
+ "description": "The initial state object (defaults to empty)"
1751
1846
  }
1752
1847
  },
1753
1848
  "required": [],
1754
- "returns": "void"
1755
- },
1756
- "normalizeHelperOptions": {
1757
- "description": "Parse helper options through the helper's static options schema so defaults are materialized.",
1758
- "parameters": {
1759
- "BaseClass": {
1760
- "type": "any",
1761
- "description": "Parameter BaseClass"
1762
- },
1763
- "options": {
1764
- "type": "any",
1765
- "description": "Parameter options"
1766
- },
1767
- "fallbackName": {
1768
- "type": "string",
1769
- "description": "Parameter fallbackName"
1770
- }
1771
- },
1772
- "required": [
1773
- "BaseClass",
1774
- "options"
1775
- ],
1776
- "returns": "void"
1777
- },
1778
- "buildHelperCacheKey": {
1779
- "description": "",
1780
- "parameters": {
1781
- "type": {
1782
- "type": "string",
1783
- "description": "Parameter type"
1784
- },
1785
- "id": {
1786
- "type": "string",
1787
- "description": "Parameter id"
1788
- },
1789
- "options": {
1790
- "type": "any",
1791
- "description": "Parameter options"
1792
- },
1793
- "omitOptionKeys": {
1794
- "type": "string[]",
1795
- "description": "Parameter omitOptionKeys"
1849
+ "returns": "State<T>",
1850
+ "examples": [
1851
+ {
1852
+ "language": "ts",
1853
+ "code": "const myState = container.newState({ count: 0, loading: false })\nmyState.observe(() => console.log('Changed:', myState.current))\nmyState.set('count', 1)"
1796
1854
  }
1797
- },
1798
- "required": [
1799
- "type",
1800
- "id",
1801
- "options"
1802
- ],
1803
- "returns": "void"
1804
- },
1805
- "createHelperInstance": {
1806
- "description": "",
1807
- "parameters": {
1808
- "{\n cache,\n type,\n id,\n BaseClass,\n options,\n fallbackName,\n omitOptionKeys = [],\n context,\n }": {
1809
- "type": "{\n cache: Map<string, any>\n type: string\n id: string\n BaseClass: any\n options?: any\n fallbackName?: string\n omitOptionKeys?: string[]\n context?: any\n }",
1810
- "description": "Parameter {\n cache,\n type,\n id,\n BaseClass,\n options,\n fallbackName,\n omitOptionKeys = [],\n context,\n }"
1811
- }
1812
- },
1813
- "required": [
1814
- "{\n cache,\n type,\n id,\n BaseClass,\n options,\n fallbackName,\n omitOptionKeys = [],\n context,\n }"
1815
- ],
1816
- "returns": "void"
1855
+ ]
1817
1856
  },
1818
1857
  "feature": {
1819
1858
  "description": "Creates a new instance of a feature. If you pass the same arguments, it will return the same instance as last time you created that. If you need the ability to create fresh instances, it is up to you how you define your options to support that.",
@@ -1833,136 +1872,154 @@ export const containerIntrospectionData = [
1833
1872
  "returns": "InstanceType<Features[T]>"
1834
1873
  },
1835
1874
  "start": {
1836
- "description": "TODO: A container should be able to container.use(plugin) and that plugin should be able to define an asynchronous method that will be run when the container is started. Right now there's nothing to do with starting / stopping a container but that might be neat.",
1875
+ "description": "Start the container. Emits the 'started' event and sets `state.started` to true. Plugins and features can listen for this event to perform initialization.",
1837
1876
  "parameters": {},
1838
1877
  "required": [],
1839
- "returns": "void"
1878
+ "returns": "Promise<this>",
1879
+ "examples": [
1880
+ {
1881
+ "language": "ts",
1882
+ "code": "container.on('started', () => console.log('Ready'))\nawait container.start()"
1883
+ }
1884
+ ]
1840
1885
  },
1841
1886
  "emit": {
1842
1887
  "description": "Emit an event on the container's event bus.",
1843
1888
  "parameters": {
1844
1889
  "event": {
1845
1890
  "type": "string",
1846
- "description": "Parameter event"
1891
+ "description": "The event name"
1847
1892
  },
1848
1893
  "args": {
1849
1894
  "type": "any[]",
1850
- "description": "Parameter args"
1895
+ "description": "Arguments to pass to listeners"
1851
1896
  }
1852
1897
  },
1853
1898
  "required": [
1854
1899
  "event",
1855
1900
  "args"
1856
1901
  ],
1857
- "returns": "void"
1902
+ "returns": "this",
1903
+ "examples": [
1904
+ {
1905
+ "language": "ts",
1906
+ "code": "container.emit('taskCompleted', { id: 'abc', result: 42 })"
1907
+ }
1908
+ ]
1858
1909
  },
1859
1910
  "on": {
1860
1911
  "description": "Subscribe to an event on the container's event bus.",
1861
1912
  "parameters": {
1862
1913
  "event": {
1863
1914
  "type": "string",
1864
- "description": "Parameter event"
1915
+ "description": "The event name"
1865
1916
  },
1866
1917
  "listener": {
1867
1918
  "type": "(...args: any[]) => void",
1868
- "description": "Parameter listener"
1919
+ "description": "The callback function"
1869
1920
  }
1870
1921
  },
1871
1922
  "required": [
1872
1923
  "event",
1873
1924
  "listener"
1874
1925
  ],
1875
- "returns": "void"
1926
+ "returns": "this",
1927
+ "examples": [
1928
+ {
1929
+ "language": "ts",
1930
+ "code": "container.on('featureEnabled', (id, feature) => {\n console.log(`Feature ${id} enabled`)\n})"
1931
+ }
1932
+ ]
1876
1933
  },
1877
1934
  "off": {
1878
1935
  "description": "Unsubscribe a listener from an event on the container's event bus.",
1879
1936
  "parameters": {
1880
1937
  "event": {
1881
1938
  "type": "string",
1882
- "description": "Parameter event"
1939
+ "description": "The event name"
1883
1940
  },
1884
1941
  "listener": {
1885
1942
  "type": "(...args: any[]) => void",
1886
- "description": "Parameter listener"
1943
+ "description": "The listener to remove"
1887
1944
  }
1888
1945
  },
1889
1946
  "required": [
1890
1947
  "event"
1891
1948
  ],
1892
- "returns": "void"
1949
+ "returns": "this"
1893
1950
  },
1894
1951
  "once": {
1895
1952
  "description": "Subscribe to an event on the container's event bus, but only fire once.",
1896
1953
  "parameters": {
1897
1954
  "event": {
1898
1955
  "type": "string",
1899
- "description": "Parameter event"
1956
+ "description": "The event name"
1900
1957
  },
1901
1958
  "listener": {
1902
1959
  "type": "(...args: any[]) => void",
1903
- "description": "Parameter listener"
1960
+ "description": "The callback function (invoked at most once)"
1904
1961
  }
1905
1962
  },
1906
1963
  "required": [
1907
1964
  "event",
1908
1965
  "listener"
1909
1966
  ],
1910
- "returns": "void"
1967
+ "returns": "this"
1911
1968
  },
1912
1969
  "waitFor": {
1913
- "description": "Returns a promise that will resolve when the event is emitted",
1970
+ "description": "Returns a promise that resolves the next time the given event is emitted. Useful for awaiting one-time lifecycle transitions.",
1914
1971
  "parameters": {
1915
1972
  "event": {
1916
1973
  "type": "string",
1917
- "description": "Parameter event"
1974
+ "description": "The event name to wait for"
1918
1975
  }
1919
1976
  },
1920
1977
  "required": [
1921
1978
  "event"
1922
1979
  ],
1923
- "returns": "void"
1924
- },
1925
- "registerHelperType": {
1926
- "description": "Register a helper type (registry + factory pair) on this container. Called automatically by Helper.attach() methods (e.g. Client.attach, Server.attach).",
1927
- "parameters": {
1928
- "registryName": {
1929
- "type": "string",
1930
- "description": "The plural name of the registry, e.g. \"clients\", \"servers\""
1931
- },
1932
- "factoryName": {
1933
- "type": "string",
1934
- "description": "The singular factory method name, e.g. \"client\", \"server\""
1980
+ "returns": "Promise<any>",
1981
+ "examples": [
1982
+ {
1983
+ "language": "ts",
1984
+ "code": "await container.waitFor('started')\nconsole.log('Container is ready')"
1935
1985
  }
1936
- },
1937
- "required": [
1938
- "registryName",
1939
- "factoryName"
1940
- ],
1941
- "returns": "void"
1986
+ ]
1942
1987
  },
1943
1988
  "inspect": {
1944
1989
  "description": "Returns a full introspection object for this container, merging build-time AST data (JSDoc descriptions, methods, getters) with runtime data (registries, factories, state, environment).",
1945
1990
  "parameters": {},
1946
1991
  "required": [],
1947
- "returns": "ContainerIntrospection"
1992
+ "returns": "ContainerIntrospection",
1993
+ "examples": [
1994
+ {
1995
+ "language": "ts",
1996
+ "code": "const info = container.inspect()\nconsole.log(info.methods) // all public methods with descriptions\nconsole.log(info.getters) // all getters with return types\nconsole.log(info.registries) // features, clients, servers, etc."
1997
+ }
1998
+ ]
1948
1999
  },
1949
2000
  "inspectAsText": {
1950
- "description": "Returns a human-readable markdown representation of this container's introspection data. Useful in REPLs, AI agent contexts, or documentation generation. The first argument can be a section name (`'methods'`, `'getters'`, etc.) to render only that section, or a number for the starting heading depth (backward compatible).",
2001
+ "description": "Returns a human-readable markdown representation of this container's introspection data. Useful in REPLs, AI agent contexts, or documentation generation. Pass a section name to render only that section (e.g. 'methods', 'getters', 'events', 'state').",
1951
2002
  "parameters": {
1952
2003
  "sectionOrDepth": {
1953
2004
  "type": "IntrospectionSection | number",
1954
- "description": "Parameter sectionOrDepth"
2005
+ "description": "A section name to render, or heading depth number"
1955
2006
  },
1956
2007
  "startHeadingDepth": {
1957
2008
  "type": "number",
1958
- "description": "Parameter startHeadingDepth"
2009
+ "description": "Starting markdown heading depth (default 1)"
1959
2010
  }
1960
2011
  },
1961
2012
  "required": [],
1962
- "returns": "string"
2013
+ "returns": "string",
2014
+ "examples": [
2015
+ {
2016
+ "language": "ts",
2017
+ "code": "console.log(container.inspectAsText()) // full description\nconsole.log(container.inspectAsText('methods')) // just methods"
2018
+ }
2019
+ ]
1963
2020
  },
1964
2021
  "introspectAsText": {
1965
- "description": "Alias for inspectAsText",
2022
+ "description": "Alias for inspectAsText.",
1966
2023
  "parameters": {
1967
2024
  "sectionOrDepth": {
1968
2025
  "type": "IntrospectionSection | number",
@@ -1977,33 +2034,42 @@ export const containerIntrospectionData = [
1977
2034
  "returns": "string"
1978
2035
  },
1979
2036
  "introspectAsJSON": {
1980
- "description": "Alias for inspectAsJSON",
1981
- "parameters": {
1982
- "sectionOrDepth": {
1983
- "type": "IntrospectionSection | number",
1984
- "description": "Parameter sectionOrDepth"
1985
- },
1986
- "startHeadingDepth": {
1987
- "type": "number",
1988
- "description": "Parameter startHeadingDepth"
2037
+ "description": "Alias for inspect, returns JSON introspection data.",
2038
+ "parameters": {},
2039
+ "required": [],
2040
+ "returns": "ContainerIntrospection"
2041
+ },
2042
+ "inspectAsType": {
2043
+ "description": "Returns the container's introspection data formatted as a TypeScript interface declaration. Includes the container's own methods, getters, factories, and registered helper types.",
2044
+ "parameters": {},
2045
+ "required": [],
2046
+ "returns": "string",
2047
+ "examples": [
2048
+ {
2049
+ "language": "ts",
2050
+ "code": "console.log(container.inspectAsType())\n// interface NodeContainer {\n// feature<T>(id: string, options?: object): T;\n// readonly uuid: string;\n// ...\n// }"
1989
2051
  }
1990
- },
2052
+ ]
2053
+ },
2054
+ "introspectAsType": {
2055
+ "description": "",
2056
+ "parameters": {},
1991
2057
  "required": [],
1992
- "returns": "any"
2058
+ "returns": "string"
1993
2059
  },
1994
2060
  "sleep": {
1995
2061
  "description": "Sleep for the specified number of milliseconds. Useful for scripting and sequencing.",
1996
2062
  "parameters": {
1997
2063
  "ms": {
1998
- "type": "any",
2064
+ "type": "number",
1999
2065
  "description": "Parameter ms"
2000
2066
  }
2001
2067
  },
2002
2068
  "required": [],
2003
- "returns": "void"
2069
+ "returns": "Promise<this>"
2004
2070
  },
2005
2071
  "use": {
2006
- "description": "Apply a plugin or enable a feature by string name. Plugins must have a static attach(container) method.",
2072
+ "description": "Apply a plugin or enable a feature by string name. Plugins are classes with a static `attach(container)` method that extend the container with new registries, factories, or capabilities.",
2007
2073
  "parameters": {
2008
2074
  "plugin": {
2009
2075
  "type": "Extension<T>",
@@ -2017,25 +2083,37 @@ export const containerIntrospectionData = [
2017
2083
  "required": [
2018
2084
  "plugin"
2019
2085
  ],
2020
- "returns": "this & T"
2086
+ "returns": "this & T",
2087
+ "examples": [
2088
+ {
2089
+ "language": "ts",
2090
+ "code": "// Enable a feature by name\ncontainer.use('contentDb')\n\n// Attach a plugin class (e.g. Client, Server, or custom)\ncontainer.use(Client) // registers the clients registry + client() factory\ncontainer.use(Server) // registers the servers registry + server() factory"
2091
+ }
2092
+ ]
2021
2093
  }
2022
2094
  },
2023
2095
  "getters": {
2024
2096
  "state": {
2025
2097
  "description": "The observable state object for this container instance.",
2026
- "returns": "any"
2098
+ "returns": "State<ContainerState>"
2027
2099
  },
2028
2100
  "enabledFeatureIds": {
2029
2101
  "description": "Returns the list of shortcut IDs for all currently enabled features.",
2030
- "returns": "any"
2102
+ "returns": "string[]"
2031
2103
  },
2032
2104
  "enabledFeatures": {
2033
2105
  "description": "Returns a map of enabled feature shortcut IDs to their instances.",
2034
2106
  "returns": "Partial<AvailableInstanceTypes<Features>>"
2035
2107
  },
2036
- "describer": {
2037
- "description": "Lazy-initialized ContainerDescriber for introspecting registries, helpers, and members.",
2038
- "returns": "ContainerDescriber"
2108
+ "utils": {
2109
+ "description": "Common utilities available on every container. Provides UUID generation, object hashing, string case conversion, and lodash helpers — no imports needed. - `utils.uuid()` — generate a v4 UUID - `utils.hashObject(obj)` — deterministic hash of any object - `utils.stringUtils` — `{ kebabCase, camelCase, upperFirst, lowerFirst, pluralize, singularize }` - `utils.lodash` — `{ uniq, keyBy, uniqBy, groupBy, debounce, throttle, mapValues, mapKeys, pick, get, set, omit }`",
2110
+ "returns": "ContainerUtils",
2111
+ "examples": [
2112
+ {
2113
+ "language": "ts",
2114
+ "code": "const id = container.utils.uuid()\nconst hash = container.utils.hashObject({ foo: 'bar' })\nconst name = container.utils.stringUtils.camelCase('my-feature')\nconst unique = container.utils.lodash.uniq([1, 2, 2, 3])"
2115
+ }
2116
+ ]
2039
2117
  },
2040
2118
  "context": {
2041
2119
  "description": "The Container's context is an object that contains the enabled features, the container itself, and any additional context that has been added to the container. All helper instances that are created by the container will have access to the shared context.",
@@ -2043,35 +2121,45 @@ export const containerIntrospectionData = [
2043
2121
  },
2044
2122
  "currentState": {
2045
2123
  "description": "The current state of the container. This is a snapshot of the container's state at the time this method is called.",
2046
- "returns": "any"
2124
+ "returns": "ContainerState"
2125
+ },
2126
+ "features": {
2127
+ "description": "The features registry. Use it to check what features are available, look up feature classes, or check if a feature is registered.",
2128
+ "returns": "FeaturesRegistry",
2129
+ "examples": [
2130
+ {
2131
+ "language": "ts",
2132
+ "code": "container.features.available // ['fs', 'git', 'grep', ...]\ncontainer.features.has('fs') // true\ncontainer.features.lookup('fs') // FS class"
2133
+ }
2134
+ ]
2047
2135
  },
2048
2136
  "isBrowser": {
2049
2137
  "description": "Returns true if the container is running in a browser.",
2050
- "returns": "any"
2138
+ "returns": "boolean"
2051
2139
  },
2052
2140
  "isBun": {
2053
2141
  "description": "Returns true if the container is running in Bun.",
2054
- "returns": "any"
2142
+ "returns": "boolean"
2055
2143
  },
2056
2144
  "isNode": {
2057
2145
  "description": "Returns true if the container is running in Node.",
2058
- "returns": "any"
2146
+ "returns": "boolean"
2059
2147
  },
2060
2148
  "isElectron": {
2061
2149
  "description": "Returns true if the container is running in Electron.",
2062
- "returns": "any"
2150
+ "returns": "boolean"
2063
2151
  },
2064
2152
  "isDevelopment": {
2065
2153
  "description": "Returns true if the container is running in development mode.",
2066
- "returns": "any"
2154
+ "returns": "boolean"
2067
2155
  },
2068
2156
  "isProduction": {
2069
2157
  "description": "Returns true if the container is running in production mode.",
2070
- "returns": "any"
2158
+ "returns": "boolean"
2071
2159
  },
2072
2160
  "isCI": {
2073
2161
  "description": "Returns true if the container is running in a CI environment.",
2074
- "returns": "any"
2162
+ "returns": "boolean"
2075
2163
  },
2076
2164
  "registryNames": {
2077
2165
  "description": "Returns the names of all attached registries (e.g. [\"features\", \"clients\", \"servers\"]).",