@ibgib/web-gib 0.0.23 → 0.0.26

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 (37) hide show
  1. package/dist/AUTO-GENERATED-version.d.mts +14 -0
  2. package/dist/AUTO-GENERATED-version.d.mts.map +1 -0
  3. package/dist/AUTO-GENERATED-version.mjs +14 -0
  4. package/dist/AUTO-GENERATED-version.mjs.map +1 -0
  5. package/package.json +4 -1
  6. package/src/AUTO-GENERATED-version.mts +14 -0
  7. package/tools/auto-generated-agent-skills/skills/ibgib-add-core-engine/SKILL.md +81 -0
  8. package/tools/auto-generated-agent-skills/skills/ibgib-add-core-engine/generate-id.js +9 -0
  9. package/tools/auto-generated-agent-skills/skills/ibgib-add-core-engine/templates/bootstrap.mts.template +58 -0
  10. package/tools/auto-generated-agent-skills/skills/ibgib-add-core-engine/templates/constants.mts.template +75 -0
  11. package/tools/auto-generated-agent-skills/skills/ibgib-add-core-engine/templates/declarations.d.ts.template +9 -0
  12. package/tools/auto-generated-agent-skills/skills/ibgib-add-core-engine/templates/helpers.web.mts.template +199 -0
  13. package/tools/auto-generated-agent-skills/skills/ibgib-add-core-engine/templates/index.html.template +65 -0
  14. package/tools/auto-generated-agent-skills/skills/ibgib-add-core-engine/templates/index.mts.template +61 -0
  15. package/tools/auto-generated-agent-skills/skills/ibgib-add-core-engine/templates/types.mts.template +128 -0
  16. package/tools/auto-generated-agent-skills/skills/ibgib-create-app-witness/SKILL.md +59 -0
  17. package/tools/auto-generated-agent-skills/skills/ibgib-create-app-witness/templates/api/function-infos.web.mts.template +11 -0
  18. package/tools/auto-generated-agent-skills/skills/ibgib-create-app-witness/templates/witness/app/app-v1.mts.template +124 -0
  19. package/tools/auto-generated-agent-skills/skills/ibgib-create-app-witness/templates/witness/app/constants.mts.template +48 -0
  20. package/tools/auto-generated-agent-skills/skills/ibgib-create-app-witness/templates/witness/app/helper.mts.template +72 -0
  21. package/tools/auto-generated-agent-skills/skills/ibgib-create-app-witness/templates/witness/app/types.mts.template +38 -0
  22. package/tools/auto-generated-agent-skills/skills/ibgib-create-component/SKILL.md +36 -0
  23. package/tools/auto-generated-agent-skills/skills/ibgib-create-component/templates/components/component-name/component.css.template +26 -0
  24. package/tools/auto-generated-agent-skills/skills/ibgib-create-component/templates/components/component-name/component.html.template +6 -0
  25. package/tools/auto-generated-agent-skills/skills/ibgib-create-component/templates/components/component-name/component.mts.template +131 -0
  26. package/tools/auto-generated-agent-skills/skills/ibgib-create-shell/SKILL.md +34 -0
  27. package/tools/auto-generated-agent-skills/skills/ibgib-create-shell/templates/ui/shell/shell-constants.mts.template +10 -0
  28. package/tools/auto-generated-agent-skills/skills/ibgib-create-shell/templates/ui/shell/shell-service.mts.template +139 -0
  29. package/tools/auto-generated-agent-skills/skills/ibgib-create-shell/templates/ui/shell/shell-types.mts.template +6 -0
  30. package/tools/auto-generated-agent-skills/skills/ibgib-enum-pattern/SKILL.md +153 -0
  31. package/tools/auto-generated-agent-skills/skills/ibgib-get-pattern/SKILL.md +92 -0
  32. package/tools/auto-generated-agent-skills/skills/ibgib-scaffold-app/SKILL.md +42 -0
  33. package/tools/auto-generated-agent-skills/skills/ibgib-targeted-refactoring/SKILL.md +84 -0
  34. package/tools/auto-generated-agent-skills/skills/ibgib-targeted-refactoring/generate-id.js +9 -0
  35. package/tools/copy-agent-skills.js +51 -0
  36. package/{generate-version-file.js → tools/generate-version-file.js} +1 -1
  37. package/tools/init-agents.js +51 -10
@@ -0,0 +1,131 @@
1
+ import thisCss from "./{{COMPONENT_NAME}}.css";
2
+ import thisHtml from "./{{COMPONENT_NAME}}.html";
3
+
4
+ import { extractErrorMsg } from "@ibgib/helper-gib/dist/helpers/utils-helper.mjs";
5
+ import { IbGibAddr } from "@ibgib/ts-gib/dist/types.mjs";
6
+ import { IbGib_V1 } from "@ibgib/ts-gib/dist/V1/types.mjs";
7
+ import { getIbGibAddr } from "@ibgib/ts-gib/dist/helper.mjs";
8
+
9
+ import { getComponentCtorArg } from "../../helpers.web.mjs";
10
+ import {
11
+ IbGibDynamicComponentMetaBase, IbGibDynamicComponentInstanceBase,
12
+ } from "@ibgib/web-gib/dist/ui/component/ibgib-dynamic-component-bases.mjs";
13
+ import {
14
+ ElementsBase, IbGibDynamicComponentInstance,
15
+ IbGibDynamicComponentInstanceInitOpts,
16
+ } from "@ibgib/web-gib/dist/ui/component/component-types.mjs";
17
+
18
+ export const {{COMPONENT_NAME_UPPER}}_COMPONENT_NAME = '{{COMPONENT_TAG_NAME}}';
19
+
20
+ /**
21
+ * Metadata for the {{COMPONENT_CLASS_PREFIX}} component.
22
+ * Handles custom element registration and instance creation.
23
+ */
24
+ export class {{COMPONENT_CLASS_PREFIX}}ComponentMeta extends IbGibDynamicComponentMetaBase {
25
+ protected lc: string = `[{{COMPONENT_CLASS_PREFIX}}ComponentMeta]`;
26
+
27
+ routeRegExp?: RegExp = new RegExp(`^${ {{COMPONENT_NAME_UPPER}}_COMPONENT_NAME }$`);
28
+ componentName = {{COMPONENT_NAME_UPPER}}_COMPONENT_NAME;
29
+
30
+ constructor() {
31
+ super(getComponentCtorArg());
32
+ customElements.define(this.componentName, {{COMPONENT_CLASS_PREFIX}}ComponentInstance);
33
+ }
34
+
35
+ async createInstance({
36
+ path,
37
+ ibGibAddr
38
+ }: {
39
+ path: string;
40
+ ibGibAddr: IbGibAddr;
41
+ }): Promise<IbGibDynamicComponentInstance> {
42
+ const lc = `${this.lc}[${this.createInstance.name}]`;
43
+ const component = document.createElement(this.componentName) as {{COMPONENT_CLASS_PREFIX}}ComponentInstance;
44
+ await component.initialize({
45
+ ibGibAddr,
46
+ meta: this,
47
+ html: thisHtml,
48
+ css: [thisCss],
49
+ });
50
+ return component;
51
+ }
52
+ }
53
+
54
+ /**
55
+ * References to DOM elements within the component's shadow root.
56
+ */
57
+ interface {{COMPONENT_CLASS_PREFIX}}Elements extends ElementsBase {
58
+ containerEl: HTMLDivElement;
59
+ titleEl: HTMLHeadingElement;
60
+ }
61
+
62
+ /**
63
+ * Concrete implementation of the {{COMPONENT_CLASS_PREFIX}} component.
64
+ * Manages its own internal state and reacts to ibGib timeline updates.
65
+ */
66
+ export class {{COMPONENT_CLASS_PREFIX}}ComponentInstance
67
+ extends IbGibDynamicComponentInstanceBase<IbGib_V1, {{COMPONENT_CLASS_PREFIX}}Elements>
68
+ implements IbGibDynamicComponentInstance<IbGib_V1, {{COMPONENT_CLASS_PREFIX}}Elements> {
69
+
70
+ protected lc: string = `[{{COMPONENT_CLASS_PREFIX}}ComponentInstance]`;
71
+
72
+ constructor() {
73
+ super();
74
+ }
75
+
76
+ override async initialize(opts: IbGibDynamicComponentInstanceInitOpts): Promise<void> {
77
+ await super.initialize(opts);
78
+ }
79
+
80
+ override async disconnected(): Promise<void> {
81
+ // Called when the element is removed from the DOM.
82
+ }
83
+
84
+ /**
85
+ * Called when the element is added to the DOM.
86
+ * Use this to query elements and attach event listeners.
87
+ */
88
+ override async created(): Promise<void> {
89
+ this.elements = {} as {{COMPONENT_CLASS_PREFIX}}Elements;
90
+ if (!this.elements) { throw new Error(`(UNEXPECTED) this.elements falsy? (E: genuuid)`); }
91
+
92
+ // Map shadow root elements
93
+ this.elements.containerEl = this.shadowRoot!.getElementById('container') as HTMLDivElement;
94
+ this.elements.titleEl = this.shadowRoot!.getElementById('title') as HTMLHeadingElement;
95
+
96
+ this.initHandlers();
97
+
98
+ if (this.ibGibAddr && !this.ibGib) {
99
+ await this.loadIbGib();
100
+ }
101
+ await this.renderUI();
102
+ }
103
+
104
+ private initHandlers() {
105
+ if (!this.elements) { throw new Error(`(UNEXPECTED) this.elements falsy? (E: genuuid)`); }
106
+ // Attach listeners here
107
+ }
108
+
109
+ /**
110
+ * Updates the UI based on the current state of this.ibGib.
111
+ */
112
+ protected override async renderUI(): Promise<void> {
113
+ const lc = `${this.lc}[${this.renderUI.name}]`;
114
+ if (!this.ibGib || !this.elements) return;
115
+
116
+ try {
117
+ this.elements.titleEl.textContent = `IbGib Component: ${this.ibGib.ib}`;
118
+ } catch (error) {
119
+ console.error(`${lc} ${extractErrorMsg(error)}`);
120
+ }
121
+ }
122
+
123
+ /**
124
+ * Automatically called by the framework when the ibGib timeline updates.
125
+ */
126
+ override async handleContextUpdated(): Promise<void> {
127
+ const lc = `${this.lc}[${this.handleContextUpdated.name}]`;
128
+ if (logalot) { console.log(`${lc} timeline updated.`); }
129
+ await this.renderUI();
130
+ }
131
+ }
@@ -0,0 +1,34 @@
1
+ ---
2
+ name: ibgib-create-shell
3
+ description: Scaffolds the foundational UI Shell for an ibgib app. Generates the shell service, constants, and types required for UI management and component registration.
4
+ ---
5
+
6
+ # ibgib-create-shell
7
+
8
+ This skill scaffolds the UI Shell architecture for an ibgib application. The Shell Service acts as a singleton on `globalThis` that manages DOM interactions, handles shell-specific events, and registers UI components with the `ibgib-component-service`.
9
+
10
+ ## Goal
11
+ To provide a clean, decoupled foundation for application-level UI management, including the `onEngineReady` lifecycle hook called by the bootstrap process.
12
+
13
+ ## Parameters
14
+ Wait for the user to provide or confirm these tokens:
15
+ - `{{APP_NAME}}`: e.g. `test-app`
16
+ - `{{APP_DIR_NAME}}`: e.g. `test-app`
17
+ - `{{APP_CLASSNAME_PREFIX}}`: e.g. `TestApp`
18
+ - `{{APP_CLASSNAME}}`: e.g. `TestAppApp_V1`
19
+ - `{{APP_HUMAN_NAME}}`: e.g. `Test App`
20
+ - `{{APP_VAR_NAME}}`: e.g. `testApp` (used for singleton naming)
21
+
22
+ ## Output Files
23
+ The skill will generate:
24
+ 1. `src/ui/shell/{{APP_DIR_NAME}}-shell-service.mts`
25
+ 2. `src/ui/shell/{{APP_DIR_NAME}}-shell-constants.mts`
26
+ 3. `src/ui/shell/{{APP_DIR_NAME}}-shell-types.mts`
27
+
28
+ ## Usage Instructions
29
+ 1. Ensure the `src/ui/shell` directory exists or the tool will create it.
30
+ 2. Generate the three files from templates.
31
+ 3. Update `src/bootstrap.mts` to import and call `get{{APP_CLASSNAME_PREFIX}}ShellSvc().onEngineReady()` in the `execFromArgs` function.
32
+
33
+ ## Integration Note
34
+ The shell service provides an `onEngineReady()` hook. This is where you should put logic to "activate" the UI once the ibgib metaspace and app witness are fully initialized.
@@ -0,0 +1,10 @@
1
+ /**
2
+ * DOM Element IDs for the shell.
3
+ */
4
+ export const ID_SHELL_CONTAINER = 'ibgib-shell-container';
5
+ export const ID_APP_ROOT = 'app-root';
6
+
7
+ /**
8
+ * Custom event names for shell-level communication.
9
+ */
10
+ export const EVENT_SHELL_READY = 'ibgib-shell-ready';
@@ -0,0 +1,139 @@
1
+ import { extractErrorMsg } from "@ibgib/helper-gib/dist/helpers/utils-helper.mjs";
2
+ import { getComponentSvc } from "@ibgib/web-gib/dist/ui/component/ibgib-component-service.mjs";
3
+ import { IbGibDynamicComponentMeta } from "@ibgib/web-gib/dist/ui/component/component-types.mjs";
4
+ import { getIbGibAddr } from "@ibgib/ts-gib/dist/helper.mjs";
5
+
6
+ import { APP_CONFIG } from "../../constants.mjs";
7
+ import { getIbGibGlobalThis_{{APP_CLASSNAME_PREFIX}} } from "../../helpers.web.mjs";
8
+ import {
9
+ ID_SHELL_CONTAINER,
10
+ EVENT_SHELL_READY,
11
+ } from "./{{APP_DIR_NAME}}-shell-constants.mjs";
12
+
13
+ /**
14
+ * Singleton service for managing the {{APP_HUMAN_NAME}} UI shell.
15
+ * Coordinates component registration and high-level DOM interactions.
16
+ */
17
+ export class {{APP_CLASSNAME_PREFIX}}ShellService {
18
+ private lc: string = `[{{APP_CLASSNAME_PREFIX}}ShellService]`;
19
+
20
+ // Elements
21
+ private shellContainer: HTMLElement | null = null;
22
+
23
+ /**
24
+ * Promise that resolves when the shell service has completed its
25
+ * asynchronous initialization (e.g. component registration).
26
+ */
27
+ public initialized: Promise<void>;
28
+
29
+ constructor() {
30
+ this.initialized = this.initialize();
31
+ }
32
+
33
+ /**
34
+ * Orchestrates the synchronous and asynchronous initialization of the shell.
35
+ */
36
+ private async initialize(): Promise<void> {
37
+ this.initElements();
38
+ this.initEventHandlers();
39
+ await this.registerComponents();
40
+ }
41
+
42
+ /**
43
+ * Registers application-specific components with the global component service.
44
+ */
45
+ private async registerComponents(): Promise<void> {
46
+ const lc = `${this.lc}[${this.registerComponents.name}]`;
47
+ try {
48
+ const componentsMeta: IbGibDynamicComponentMeta[] = [
49
+ // Add your component metas here, e.g.:
50
+ // new MyAwesomeComponentMeta(),
51
+ ];
52
+ const componentSvc = await getComponentSvc();
53
+ for (let componentMeta of componentsMeta) {
54
+ componentSvc.registerComponentMeta(componentMeta);
55
+ }
56
+ } catch (error) {
57
+ console.error(`${lc} ${extractErrorMsg(error)}`);
58
+ throw error;
59
+ }
60
+ }
61
+
62
+ private initElements(): void {
63
+ const lc = `${this.lc}[${this.initElements.name}]`;
64
+ try {
65
+ // Placeholder: this.shellContainer = document.getElementById(ID_SHELL_CONTAINER);
66
+ } catch (error) {
67
+ console.error(`${lc} ${extractErrorMsg(error)}`);
68
+ }
69
+ }
70
+
71
+ private initEventHandlers(): void {
72
+ const lc = `${this.lc}[${this.initEventHandlers.name}]`;
73
+ try {
74
+ // Register global or shell-level event listeners here.
75
+ } catch (error) {
76
+ console.error(`${lc} ${extractErrorMsg(error)}`);
77
+ }
78
+ }
79
+
80
+ /**
81
+ * Called by `bootstrap.mts` when the ibGib engine and metaspace are ready.
82
+ * Use this to reveal or activate interactive UI elements.
83
+ */
84
+ public async onEngineReady(): Promise<void> {
85
+ const lc = `${this.lc}[${this.onEngineReady.name}]`;
86
+ try {
87
+ await this.initialized;
88
+ console.log(`${lc} {{APP_HUMAN_NAME}} Shell Service is ready.`);
89
+
90
+ // 1. Get the app context from global state
91
+ const ibGibGlobalThis = getIbGibGlobalThis_{{APP_CLASSNAME_PREFIX}}(APP_CONFIG);
92
+ const appIbGib = ibGibGlobalThis.initialCommentIbGib;
93
+ if (!appIbGib) {
94
+ throw new Error(`initialCommentIbGib not found on globalThis.`);
95
+ }
96
+
97
+ // 2. Get the main component instance
98
+ const componentSvc = await getComponentSvc();
99
+ const component = await componentSvc.getComponentInstance({
100
+ path: '{{APP_DIR_NAME}}-main',
101
+ ibGibAddr: getIbGibAddr({ ibGib: appIbGib }),
102
+ useRegExpPrefilter: true,
103
+ });
104
+
105
+ if (!component) {
106
+ throw new Error(`Failed to get component instance for app.`);
107
+ }
108
+
109
+ // 3. Inject into the DOM
110
+ const appRoot = document.getElementById(ID_APP_ROOT);
111
+ if (appRoot) {
112
+ appRoot.innerHTML = ''; // Clear loading message
113
+ appRoot.appendChild(component as any);
114
+ } else {
115
+ console.warn(`${lc} #${ID_APP_ROOT} not found in DOM.`);
116
+ }
117
+
118
+ window.dispatchEvent(new CustomEvent(EVENT_SHELL_READY));
119
+ } catch (error) {
120
+ console.error(`${lc} ${extractErrorMsg(error)}`);
121
+ }
122
+ }
123
+ }
124
+
125
+ /**
126
+ * Returns the singleton instance of the Shell Service, initializing it on
127
+ * globalThis if necessary.
128
+ */
129
+ export function get{{APP_CLASSNAME_PREFIX}}ShellSvc(): {{APP_CLASSNAME_PREFIX}}ShellService {
130
+ const lc = `[get{{APP_CLASSNAME_PREFIX}}ShellSvc]`;
131
+ const ibGibGlobalThis = getIbGibGlobalThis_{{APP_CLASSNAME_PREFIX}}(APP_CONFIG);
132
+ if (!ibGibGlobalThis.{{APP_VAR_NAME}}ShellSvc) {
133
+ if (typeof (console) !== 'undefined') {
134
+ console.log(`${lc} initializing {{APP_CLASSNAME_PREFIX}}ShellService singleton on globalThis... (I: genuuid)`);
135
+ }
136
+ ibGibGlobalThis.{{APP_VAR_NAME}}ShellSvc = new {{APP_CLASSNAME_PREFIX}}ShellService();
137
+ }
138
+ return ibGibGlobalThis.{{APP_VAR_NAME}}ShellSvc;
139
+ }
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Event detail shapes for shell events.
3
+ */
4
+ export interface ShellReadyDetail {
5
+ timestamp: number;
6
+ }
@@ -0,0 +1,153 @@
1
+ ---
2
+ description: TypeScript enum pattern used in this codebase
3
+ ---
4
+
5
+ # Ibgib Enum Pattern Skill
6
+
7
+ This codebase **never** uses TypeScript's built-in `enum` keyword (it has
8
+ problematic runtime semantics and poor tree-shaking). Instead, use the
9
+ following pattern for every enum-like type.
10
+
11
+ ## When to use
12
+
13
+ - Three or more related string (or occasionally number) constants.
14
+ - The values are part of a discriminated union or are validated at runtime.
15
+ - A simple `'a' | 'b' | 'c'` union is fine for small, stable sets; promote
16
+ to the full pattern once the set starts to branch out or needs a guard/validator.
17
+
18
+ ## Full pattern
19
+
20
+ ```typescript
21
+ // #region MyEnum enum
22
+
23
+ // 1. One exported const per value.
24
+ // - Name: SCREAMING_SNAKE_CASE PREFIX_MEMBER
25
+ // - Value: kebab-case string literal
26
+ // - Hyphens in values → underscores in const names.
27
+ export const MY_ENUM_FOO_BAR = 'foo-bar';
28
+ export const MY_ENUM_BAZ = 'baz';
29
+
30
+ // 2. Union type — use typeof references so renaming a const propagates.
31
+ /**
32
+ * JSDoc describing the enum's purpose.
33
+ */
34
+ export type MyEnum =
35
+ | typeof MY_ENUM_FOO_BAR
36
+ | typeof MY_ENUM_BAZ
37
+ ;
38
+
39
+ // 3. Const enum object — keys are camelCase/underscore versions of the values
40
+ // (replace hyphens with underscores in the key).
41
+ // Satisfies the union type so TypeScript catches typos at declaration time.
42
+ export const MyEnum = {
43
+ /** Doc for foo-bar member. */
44
+ foo_bar: MY_ENUM_FOO_BAR,
45
+ /** Doc for baz member. */
46
+ baz: MY_ENUM_BAZ,
47
+ } satisfies { readonly [key: string]: MyEnum };
48
+
49
+ // 4. Valid-values array (derived from the object — stays in sync automatically).
50
+ export const MY_ENUM_VALID_VALUES: MyEnum[] = Object.values(MyEnum);
51
+
52
+ // 5. Type guard.
53
+ export function isMyEnum(value: any): value is MyEnum {
54
+ return MY_ENUM_VALID_VALUES.includes(value);
55
+ }
56
+
57
+ // #endregion MyEnum enum
58
+ ```
59
+
60
+ ## Consuming the enum
61
+
62
+ Callers should reference values via the **const object**, not the individual string constants:
63
+
64
+ ```typescript
65
+ // ✅ preferred — readable, refactor-safe
66
+ switch (strategy) {
67
+ case ParseMechanicalStrategy.markdown_heading: return splitByHeadings(text);
68
+ case ParseMechanicalStrategy.markdown_paragraph: return splitByParagraph(text);
69
+ case ParseMechanicalStrategy.custom_regexp: return splitByRegexp(text, opts.regexp);
70
+ default: throw new Error(`(UNEXPECTED) unhandled strategy: '${strategy}'`);
71
+ }
72
+
73
+ // ⚠️ acceptable when the constant itself is needed (e.g. error messages, assertions)
74
+ if (strategy === PARSE_MECHANICAL_STRATEGY_CUSTOM_REGEXP && !opts.regexp) {
75
+ throw new Error(`strategy is '${PARSE_MECHANICAL_STRATEGY_CUSTOM_REGEXP}' but regexp is falsy`);
76
+ }
77
+
78
+ // ❌ avoid — brittle string literals scattered through call sites
79
+ if (strategy === 'markdown-heading') { ... }
80
+ ```
81
+
82
+ ## Rules
83
+
84
+ | Rule | Detail |
85
+ |---|---|
86
+ | **No `enum` keyword** | Use the pattern above. `enum` has footguns (reverse mapping, ambient vs const, isolatedModules). |
87
+ | **Kebab-case values** | String values use kebab-case (`'foo-bar'`). |
88
+ | **Const names** | `PREFIX_MEMBER` in SCREAMING_SNAKE_CASE; hyphens in value → underscores in name. |
89
+ | **Object keys** | Match the value with hyphens replaced by underscores (`foo_bar`). |
90
+ | **`satisfies`** | Always use `satisfies { readonly [key: string]: MyEnum }` on the const object. |
91
+ | **Start simple** | A plain string-literal union (`'foo-bar' | 'baz'`) is fine until the set grows or needs a guard. Promote to the full pattern at that point. |
92
+ | **`_VALID_VALUES`** | Always derive from `Object.values(MyEnum)`, never hardcode. |
93
+ | **Type guard** | Implement `isMyEnum` via `VALID_VALUES.includes(value)`. |
94
+
95
+ ## Region comments
96
+
97
+ Wrap the entire block in:
98
+ ```typescript
99
+ // #region MyEnum enum
100
+ // ...
101
+ // #endregion MyEnum enum
102
+ ```
103
+
104
+ ## Example from codebase
105
+
106
+ ```typescript
107
+ // #region ChromeAIAvailability enum
108
+ export const CHROME_AI_AVAILABILITY_UNAVAILABLE = 'unavailable';
109
+ export const CHROME_AI_AVAILABILITY_DOWNLOADABLE = 'downloadable';
110
+ export const CHROME_AI_AVAILABILITY_DOWNLOADING = 'downloading';
111
+ export const CHROME_AI_AVAILABILITY_AVAILABLE = 'available';
112
+
113
+ export type ChromeAIAvailability =
114
+ | typeof CHROME_AI_AVAILABILITY_UNAVAILABLE
115
+ | typeof CHROME_AI_AVAILABILITY_DOWNLOADABLE
116
+ | typeof CHROME_AI_AVAILABILITY_DOWNLOADING
117
+ | typeof CHROME_AI_AVAILABILITY_AVAILABLE
118
+ ;
119
+
120
+ /**
121
+ * The availability of a Chrome AI API.
122
+ *
123
+ * @see https://developer.chrome.com/docs/ai/built-in
124
+ */
125
+ export const ChromeAIAvailability = {
126
+ /**
127
+ * The user's device or requested session options are not supported.
128
+ * The device may have insufficient power or disk space.
129
+ */
130
+ unavailable: CHROME_AI_AVAILABILITY_UNAVAILABLE,
131
+ /**
132
+ * Additional downloads are needed to create a session, which may include
133
+ * an expert model, a language model, or fine-tuning. User activation may
134
+ * be required to call create().
135
+ */
136
+ downloadable: CHROME_AI_AVAILABILITY_DOWNLOADABLE,
137
+ /**
138
+ * Downloads are ongoing and must complete before you can use a a session.
139
+ */
140
+ downloading: CHROME_AI_AVAILABILITY_DOWNLOADING,
141
+ /**
142
+ * You can create a session immediately.
143
+ */
144
+ available: CHROME_AI_AVAILABILITY_AVAILABLE,
145
+ } satisfies { readonly [key: string]: ChromeAIAvailability; };
146
+
147
+ export const CHROME_AI_AVAILABILITY_VALID_VALUES: ChromeAIAvailability[] = Object.values(ChromeAIAvailability);
148
+
149
+ export function isChromeAIAvailability(value: any): value is ChromeAIAvailability {
150
+ return CHROME_AI_AVAILABILITY_VALID_VALUES.includes(value);
151
+ }
152
+ // #endregion ChromeAIAvailability enum
153
+ ```
@@ -0,0 +1,92 @@
1
+ ---
2
+ description: Patterns for robustly getting IbGibs from spaces
3
+ ---
4
+
5
+ # IbGib Get Pattern Skill
6
+
7
+ This skill documents the standard pattern for retrieving IbGib objects from a space. Use this pattern to ensure robust error handling, consistent logging, and correct space interaction.
8
+
9
+ ## When to Use
10
+
11
+ - Whenever you need to `get` one or more IbGibs by their address(es).
12
+
13
+ ## Core Pattern: try..catch..finally
14
+
15
+ Always wrap retrieval logic in a `try..catch..finally` block to ensure errors are logged and execution state is finalized correctly.
16
+
17
+ ```typescript
18
+ const lc = `[${myFunctionName.name}]`;
19
+ try {
20
+ if (logalot) { console.log(`${lc} starting... (I: genuuid)`); }
21
+
22
+ // ... retrieval logic ...
23
+
24
+ } catch (error) {
25
+ console.error(`${lc} ${extractErrorMsg(error)}`);
26
+ throw error;
27
+ } finally {
28
+ if (logalot) { console.log(`${lc} complete.`); }
29
+ }
30
+ ```
31
+
32
+ ## Space Retrieval Helpers
33
+
34
+ ### Option A: Using `metaspace.get` (Preferred)
35
+
36
+ Use this when you have access to a `MetaspaceService` (It is often appropriate to provide a fallback to the default local user space, which is what the metaspace provides.)
37
+
38
+ ```typescript
39
+ // Ensure space is provided or fallback to local user space
40
+ space ??= await metaspace.getLocalUserSpace({ lock: false });
41
+ if (!space) {
42
+ throw new Error(`(UNEXPECTED) space falsy and we couldn't get default local user space from metaspace? (E: genuuid)`);
43
+ }
44
+
45
+ const resGet = await metaspace.get({ addrs, space });
46
+
47
+ // Validate result
48
+ if (resGet.success && resGet.ibGibs && resGet.ibGibs.length === addrs.length) {
49
+ return resGet.ibGibs;
50
+ } else {
51
+ // Robust error handling using rawResultIbGib
52
+ const resIbGib = resGet.rawResultIbGib as IbGibSpaceResultIbGib<IbGib_V1, IbGibSpaceResultData, IbGibSpaceResultRel8ns>;
53
+ const addrsNotFound = resIbGib?.data?.addrsNotFound ?? 'unknown';
54
+ throw new Error(`couldn't find all addrs. addrsNotFound: ${addrsNotFound}? resGet.errorMsg: ${resGet.errorMsg} (E: genuuid)`);
55
+ }
56
+ ```
57
+
58
+ ### Option B: Using `getFromSpace` (Lower Level)
59
+
60
+ Use this when `metaspace` is not available, or when working in low-level helpers.
61
+
62
+ ```typescript
63
+ import { getFromSpace } from "@ibgib/core-gib/dist/witness/space/space-helper.mjs";
64
+
65
+ // ... inside try block ...
66
+ const resGet = await getFromSpace({ space, addrs });
67
+
68
+ if (resGet.success && resGet.ibGibs?.length === addrs.length) {
69
+ return resGet.ibGibs!;
70
+ } else {
71
+ // Examine rawResultIbGib for more context
72
+ const resIbGib = resGet.rawResultIbGib as IbGibSpaceResultIbGib<IbGib_V1, IbGibSpaceResultData, IbGibSpaceResultRel8ns>;
73
+ if (!resIbGib?.data) {
74
+ throw new Error(`(UNEXPECTED) resGet.rawResultIbGib.data falsy? (E: genuuid)`);
75
+ }
76
+ throw new Error(`(UNEXPECTED) couldn't find addrs? addrsNotFound: ${resIbGib.data.addrsNotFound}? space.ib: ${space.ib} (E: genuuid)`);
77
+ }
78
+ ```
79
+
80
+ ## Key Requirements
81
+
82
+ | Requirement | Detail |
83
+ |---|---|
84
+ | **Logging** | Define `const lc = \`[\${fn.name}]\`;\` at the start. Log starting/finishing if `logalot` is true. |
85
+ | **Error Handling** | Use `extractErrorMsg(error)` in the catch block. Re-throw after logging. |
86
+ | **Result Validation** | Always check `resGet.success` AND that the returned `ibGibs` array matches the expected length. |
87
+ | **Debugging Context** | When a fetch fails, cast `resGet.rawResultIbGib` to `IbGibSpaceResultIbGib` and include `addrsNotFound` in the error message. |
88
+ | **Space Fallback** | When using `metaspace`, consider falling back to `metaspace.getLocalUserSpace({ lock: false })` if no space is provided. |
89
+
90
+ ## Real-World Example
91
+
92
+ See `apps/learning/src/common/parse/parse-helper.mts` -> `fetchLayer` for the reference implementation of this pattern.
@@ -0,0 +1,42 @@
1
+ ---
2
+ name: ibgib-scaffold-app
3
+ description: The master coordinator skill for scaffolding a complete "Hello World" ibgib application. Orchestrates sub-skills for core engine, app witness, and UI shell.
4
+ ---
5
+
6
+ # ibgib-scaffold-app
7
+
8
+ This is a Meta-Skill that coordinates multiple sub-skills to create a functional, buildable ibgib application from scratch (Greenfield) or to add ibgib to an existing project (Brownfield).
9
+
10
+ ## Goal
11
+ To orchestrate the modular sub-skills so the final application is type-safe, buildable, and consistent.
12
+
13
+ ## Sub-Skills
14
+ This coordinator uses:
15
+ 1. `ibgib-add-core-engine`: FOUNDATION (Bootstrap, Global State, Types).
16
+ 2. `ibgib-create-app-witness`: LOGIC (App Witness class, commands, helpers).
17
+ 3. `ibgib-create-shell`: UI (Shell service, event handlers).
18
+ 4. `ibgib-create-component`: COMPONENT (Initial main app component - optional but recommended).
19
+
20
+ ## Parameters (Shared State)
21
+ The agent must generate and maintain these tokens across sub-skill executions:
22
+ - `{{APP_NAME}}`: kebab-case (e.g. `test-app`)
23
+ - `{{APP_DIR_NAME}}`: folder name (e.g. `test-app`)
24
+ - `{{APP_CLASSNAME_PREFIX}}`: PascalCase (e.g. `TestApp`)
25
+ - `{{APP_CLASSNAME}}`: Full class name (e.g. `TestAppApp_V1`)
26
+ - `{{APP_HUMAN_NAME}}`: Natural language (e.g. `Test App`)
27
+ - `{{APP_VAR_NAME}}`: camelCase (e.g. `testApp`)
28
+ - `{{APP_NAME_UPPER}}`: SCREAMING_SNAKE_CASE (e.g. `TEST_APP`)
29
+
30
+ ## Workflow for Greenfield (Fresh App)
31
+ 1. **Prepare Tokens**: Generate/confirm all tokens. Generate UUIDs for IDs in templates.
32
+ 2. **Core Engine**: Call `ibgib-add-core-engine` to scaffold the 7 foundational files.
33
+ 3. **App Witness**: Call `ibgib-create-app-witness` to scaffold the witness logic.
34
+ 4. **UI Shell**: Call `ibgib-create-shell` to scaffold the shell service.
35
+ 5. **Main Component**: Call `ibgib-create-component` to create the initial app component.
36
+ 6. **Hook Up**:
37
+ - Update `bootstrap.mts` to use the shell service and register the component.
38
+ - Create `package.json` and `tsconfig.json` (if in a new directory).
39
+
40
+ ## Workflow for Brownfield (Existing Project)
41
+ 1. Determine the source root.
42
+ 2. Follow the Greenfield steps but skip `package.json` and `tsconfig.json` creation; instead, integrate with existing ones.