@elyracode/coding-agent 0.9.17 → 0.9.19

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 (29) hide show
  1. package/CHANGELOG.md +13 -0
  2. package/dist/core/keybindings.d.ts +10 -0
  3. package/dist/core/keybindings.d.ts.map +1 -1
  4. package/dist/core/keybindings.js +8 -0
  5. package/dist/core/keybindings.js.map +1 -1
  6. package/dist/core/stack-detector.d.ts +1 -1
  7. package/dist/core/stack-detector.d.ts.map +1 -1
  8. package/dist/core/stack-detector.js +27 -1
  9. package/dist/core/stack-detector.js.map +1 -1
  10. package/dist/modes/interactive/components/index.d.ts +1 -0
  11. package/dist/modes/interactive/components/index.d.ts.map +1 -1
  12. package/dist/modes/interactive/components/index.js +1 -0
  13. package/dist/modes/interactive/components/index.js.map +1 -1
  14. package/dist/modes/interactive/components/package-browser.d.ts +26 -0
  15. package/dist/modes/interactive/components/package-browser.d.ts.map +1 -0
  16. package/dist/modes/interactive/components/package-browser.js +137 -0
  17. package/dist/modes/interactive/components/package-browser.js.map +1 -0
  18. package/dist/modes/interactive/interactive-mode.d.ts +1 -0
  19. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  20. package/dist/modes/interactive/interactive-mode.js +72 -45
  21. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  22. package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
  23. package/examples/extensions/custom-provider-anthropic/package.json +1 -1
  24. package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
  25. package/examples/extensions/sandbox/package-lock.json +2 -2
  26. package/examples/extensions/sandbox/package.json +1 -1
  27. package/examples/extensions/with-deps/package-lock.json +2 -2
  28. package/examples/extensions/with-deps/package.json +1 -1
  29. package/package.json +5 -5
package/CHANGELOG.md CHANGED
@@ -1,5 +1,18 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.9.19] - 2026-07-18
4
+
5
+ ### Changed
6
+ - Redesigned the `/ext` (`/packages`) extension browser: a clean, scrollable list with aligned name/description columns, multi-select via space (install one or several at once), and a persistent reminder to run `/reload` after installing. Adds `@elyracode/stack-elyra-framework` to the list.
7
+
8
+ ## [0.9.18] - 2026-07-18
9
+
10
+ ### Added
11
+ - Detect Elyra Framework (Rust + Svelte 5 desktop framework) projects via `elyra.toml` or an `elyra` dependency in `Cargo.toml`, suggesting `@elyracode/stack-elyra-framework`
12
+
13
+ ### Fixed
14
+ - Package browser: added missing `@elyracode/lsp-php` and `@elyracode/stack-silt` entries
15
+
3
16
  ## [0.9.17] - 2026-07-18
4
17
 
5
18
  ### Changed
@@ -42,6 +42,8 @@ export interface AppKeybindings {
42
42
  "app.tree.filter.all": true;
43
43
  "app.tree.filter.cycleForward": true;
44
44
  "app.tree.filter.cycleBackward": true;
45
+ "app.packages.toggle": true;
46
+ "app.packages.install": true;
45
47
  }
46
48
  export type AppKeybinding = keyof AppKeybindings;
47
49
  declare module "@elyracode/tui" {
@@ -341,6 +343,14 @@ export declare const KEYBINDINGS: {
341
343
  readonly defaultKeys: "shift+ctrl+o";
342
344
  readonly description: "Tree filter: cycle backward";
343
345
  };
346
+ readonly "app.packages.toggle": {
347
+ readonly defaultKeys: "space";
348
+ readonly description: "Package browser: toggle selection";
349
+ };
350
+ readonly "app.packages.install": {
351
+ readonly defaultKeys: "enter";
352
+ readonly description: "Package browser: install selected";
353
+ };
344
354
  };
345
355
  export declare function migrateKeybindingsConfig(rawConfig: Record<string, unknown>): {
346
356
  config: Record<string, unknown>;
@@ -1 +1 @@
1
- {"version":3,"file":"keybindings.d.ts","sourceRoot":"","sources":["../../src/core/keybindings.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,KAAK,UAAU,EAEf,KAAK,iBAAiB,EACtB,KAAK,KAAK,EAEV,kBAAkB,IAAI,qBAAqB,EAC3C,MAAM,gBAAgB,CAAC;AAKxB,MAAM,WAAW,cAAc;IAC9B,eAAe,EAAE,IAAI,CAAC;IACtB,WAAW,EAAE,IAAI,CAAC;IAClB,UAAU,EAAE,IAAI,CAAC;IACjB,aAAa,EAAE,IAAI,CAAC;IACpB,oBAAoB,EAAE,IAAI,CAAC;IAC3B,wBAAwB,EAAE,IAAI,CAAC;IAC/B,yBAAyB,EAAE,IAAI,CAAC;IAChC,kBAAkB,EAAE,IAAI,CAAC;IACzB,kBAAkB,EAAE,IAAI,CAAC;IACzB,qBAAqB,EAAE,IAAI,CAAC;IAC5B,+BAA+B,EAAE,IAAI,CAAC;IACtC,qBAAqB,EAAE,IAAI,CAAC;IAC5B,sBAAsB,EAAE,IAAI,CAAC;IAC7B,qBAAqB,EAAE,IAAI,CAAC;IAC5B,0BAA0B,EAAE,IAAI,CAAC;IACjC,iBAAiB,EAAE,IAAI,CAAC;IACxB,kBAAkB,EAAE,IAAI,CAAC;IACzB,kBAAkB,EAAE,IAAI,CAAC;IACzB,oBAAoB,EAAE,IAAI,CAAC;IAC3B,oBAAoB,EAAE,IAAI,CAAC;IAC3B,mBAAmB,EAAE,IAAI,CAAC;IAC1B,uBAAuB,EAAE,IAAI,CAAC;IAC9B,oBAAoB,EAAE,IAAI,CAAC;IAC3B,+BAA+B,EAAE,IAAI,CAAC;IACtC,wBAAwB,EAAE,IAAI,CAAC;IAC/B,wBAAwB,EAAE,IAAI,CAAC;IAC/B,oBAAoB,EAAE,IAAI,CAAC;IAC3B,oBAAoB,EAAE,IAAI,CAAC;IAC3B,+BAA+B,EAAE,IAAI,CAAC;IACtC,iBAAiB,EAAE,IAAI,CAAC;IACxB,sBAAsB,EAAE,IAAI,CAAC;IAC7B,qBAAqB,EAAE,IAAI,CAAC;IAC5B,2BAA2B,EAAE,IAAI,CAAC;IAClC,sBAAsB,EAAE,IAAI,CAAC;IAC7B,wBAAwB,EAAE,IAAI,CAAC;IAC/B,yBAAyB,EAAE,IAAI,CAAC;IAChC,yBAAyB,EAAE,IAAI,CAAC;IAChC,0BAA0B,EAAE,IAAI,CAAC;IACjC,6BAA6B,EAAE,IAAI,CAAC;IACpC,qBAAqB,EAAE,IAAI,CAAC;IAC5B,8BAA8B,EAAE,IAAI,CAAC;IACrC,+BAA+B,EAAE,IAAI,CAAC;CACtC;AAED,MAAM,MAAM,aAAa,GAAG,MAAM,cAAc,CAAC;AAEjD,OAAO,QAAQ,gBAAgB,CAAC;IAC/B,UAAU,WAAY,SAAQ,cAAc;KAAG;CAC/C;AAED,eAAO,MAAM,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAEJ,WAAW,EAAE,QAAQ;iBAAE,WAAW,EAAE,iBAAiB;;;iBACzD,WAAW,EAAE,QAAQ;iBAAE,WAAW,EAAE,cAAc;;;iBACnD,WAAW,EAAE,QAAQ;iBAAE,WAAW,EAAE,2BAA2B;;;iBAE5E,WAAW;iBACX,WAAW,EAAE,uBAAuB;;;iBAGpC,WAAW,EAAE,WAAW;iBACxB,WAAW,EAAE,sBAAsB;;;iBAGnC,WAAW,EAAE,QAAQ;iBACrB,WAAW,EAAE,qBAAqB;;;iBAGlC,WAAW,EAAE,cAAc;iBAC3B,WAAW,EAAE,yBAAyB;;;iBAEjB,WAAW,EAAE,QAAQ;iBAAE,WAAW,EAAE,qBAAqB;;;iBACzD,WAAW,EAAE,QAAQ;iBAAE,WAAW,EAAE,oBAAoB;;;iBAE7E,WAAW,EAAE,QAAQ;iBACrB,WAAW,EAAE,wBAAwB;;;iBAGrC,WAAW,EAAE,QAAQ;iBACrB,WAAW,EAAE,6BAA6B;;;iBAG1C,WAAW,EAAE,QAAQ;iBACrB,WAAW,EAAE,sBAAsB;;;iBAGnC,WAAW,EAAE,WAAW;iBACxB,WAAW,EAAE,yBAAyB;;;iBAGtC,WAAW,EAAE,QAAQ;iBACrB,WAAW,EAAE,yBAAyB;;;iBAGtC,WAAW;iBACX,WAAW,EAAE,4BAA4B;;;iBAErB,WAAW;iBAAM,WAAW,EAAE,qBAAqB;;;iBAClD,WAAW;iBAAM,WAAW,EAAE,mBAAmB;;;iBACjD,WAAW;iBAAM,WAAW,EAAE,sBAAsB;;;iBAClD,WAAW;iBAAM,WAAW,EAAE,kBAAkB;;;iBAChD,WAAW;iBAAM,WAAW,EAAE,oCAAoC;;;iBAEzF,WAAW;iBACX,WAAW,EAAE,6BAA6B;;;iBAG1C,WAAW;iBACX,WAAW,EAAE,iCAAiC;;;iBAG9C,WAAW,EAAE,SAAS;iBACtB,WAAW,EAAE,iBAAiB;;;iBAG9B,WAAW,EAAE,SAAS;iBACtB,WAAW,EAAE,8BAA8B;;;iBAG3C,WAAW,EAAE,QAAQ;iBACrB,WAAW,EAAE,6BAA6B;;;iBAG1C,WAAW,EAAE,QAAQ;iBACrB,WAAW,EAAE,0BAA0B;;;iBAGvC,WAAW,EAAE,QAAQ;iBACrB,WAAW,EAAE,gBAAgB;;;iBAG7B,WAAW,EAAE,QAAQ;iBACrB,WAAW,EAAE,gBAAgB;;;iBAG7B,WAAW,EAAE,gBAAgB;iBAC7B,WAAW,EAAE,oCAAoC;;;iBAGjD,WAAW,EAAE,QAAQ;iBACrB,WAAW,EAAE,sBAAsB;;;iBAGnC,WAAW,EAAE,QAAQ;iBACrB,WAAW,EAAE,mBAAmB;;;iBAGhC,WAAW,EAAE,QAAQ;iBACrB,WAAW,EAAE,kBAAkB;;;iBAG/B,WAAW,EAAE,QAAQ;iBACrB,WAAW,EAAE,gCAAgC;;;iBAG7C,WAAW,EAAE,QAAQ;iBACrB,WAAW,EAAE,wBAAwB;;;iBAGrC,WAAW,EAAE,UAAU;iBACvB,WAAW,EAAE,0BAA0B;;;iBAGvC,WAAW,EAAE,QAAQ;iBACrB,WAAW,EAAE,2BAA2B;;;iBAGxC,WAAW,EAAE,QAAQ;iBACrB,WAAW,EAAE,gCAAgC;;;iBAG7C,WAAW,EAAE,QAAQ;iBACrB,WAAW,EAAE,iCAAiC;;;iBAG9C,WAAW,EAAE,QAAQ;iBACrB,WAAW,EAAE,mCAAmC;;;iBAGhD,WAAW,EAAE,QAAQ;iBACrB,WAAW,EAAE,+BAA+B;;;iBAG5C,WAAW,EAAE,QAAQ;iBACrB,WAAW,EAAE,4BAA4B;;;iBAGzC,WAAW,EAAE,cAAc;iBAC3B,WAAW,EAAE,6BAA6B;;CAEF,CAAC;AAwF3C,wBAAgB,wBAAwB,CAAC,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG;IAC7E,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAChC,QAAQ,EAAE,OAAO,CAAC;CAClB,CAiBA;AA8BD,qBAAa,kBAAmB,SAAQ,qBAAqB;IAC5D,OAAO,CAAC,UAAU,CAAqB;IAEvC,YAAY,YAAY,GAAE,iBAAsB,EAAE,UAAU,CAAC,EAAE,MAAM,EAGpE;IAED,MAAM,CAAC,MAAM,CAAC,QAAQ,GAAE,MAAsB,GAAG,kBAAkB,CAIlE;IAED,MAAM,IAAI,IAAI,CAGb;IAED,kBAAkB,IAAI,iBAAiB,CAEtC;IAED,OAAO,CAAC,MAAM,CAAC,YAAY;CAK3B;AAED,YAAY,EAAE,UAAU,EAAE,iBAAiB,EAAE,KAAK,EAAE,CAAC"}
1
+ {"version":3,"file":"keybindings.d.ts","sourceRoot":"","sources":["../../src/core/keybindings.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,KAAK,UAAU,EAEf,KAAK,iBAAiB,EACtB,KAAK,KAAK,EAEV,kBAAkB,IAAI,qBAAqB,EAC3C,MAAM,gBAAgB,CAAC;AAKxB,MAAM,WAAW,cAAc;IAC9B,eAAe,EAAE,IAAI,CAAC;IACtB,WAAW,EAAE,IAAI,CAAC;IAClB,UAAU,EAAE,IAAI,CAAC;IACjB,aAAa,EAAE,IAAI,CAAC;IACpB,oBAAoB,EAAE,IAAI,CAAC;IAC3B,wBAAwB,EAAE,IAAI,CAAC;IAC/B,yBAAyB,EAAE,IAAI,CAAC;IAChC,kBAAkB,EAAE,IAAI,CAAC;IACzB,kBAAkB,EAAE,IAAI,CAAC;IACzB,qBAAqB,EAAE,IAAI,CAAC;IAC5B,+BAA+B,EAAE,IAAI,CAAC;IACtC,qBAAqB,EAAE,IAAI,CAAC;IAC5B,sBAAsB,EAAE,IAAI,CAAC;IAC7B,qBAAqB,EAAE,IAAI,CAAC;IAC5B,0BAA0B,EAAE,IAAI,CAAC;IACjC,iBAAiB,EAAE,IAAI,CAAC;IACxB,kBAAkB,EAAE,IAAI,CAAC;IACzB,kBAAkB,EAAE,IAAI,CAAC;IACzB,oBAAoB,EAAE,IAAI,CAAC;IAC3B,oBAAoB,EAAE,IAAI,CAAC;IAC3B,mBAAmB,EAAE,IAAI,CAAC;IAC1B,uBAAuB,EAAE,IAAI,CAAC;IAC9B,oBAAoB,EAAE,IAAI,CAAC;IAC3B,+BAA+B,EAAE,IAAI,CAAC;IACtC,wBAAwB,EAAE,IAAI,CAAC;IAC/B,wBAAwB,EAAE,IAAI,CAAC;IAC/B,oBAAoB,EAAE,IAAI,CAAC;IAC3B,oBAAoB,EAAE,IAAI,CAAC;IAC3B,+BAA+B,EAAE,IAAI,CAAC;IACtC,iBAAiB,EAAE,IAAI,CAAC;IACxB,sBAAsB,EAAE,IAAI,CAAC;IAC7B,qBAAqB,EAAE,IAAI,CAAC;IAC5B,2BAA2B,EAAE,IAAI,CAAC;IAClC,sBAAsB,EAAE,IAAI,CAAC;IAC7B,wBAAwB,EAAE,IAAI,CAAC;IAC/B,yBAAyB,EAAE,IAAI,CAAC;IAChC,yBAAyB,EAAE,IAAI,CAAC;IAChC,0BAA0B,EAAE,IAAI,CAAC;IACjC,6BAA6B,EAAE,IAAI,CAAC;IACpC,qBAAqB,EAAE,IAAI,CAAC;IAC5B,8BAA8B,EAAE,IAAI,CAAC;IACrC,+BAA+B,EAAE,IAAI,CAAC;IACtC,qBAAqB,EAAE,IAAI,CAAC;IAC5B,sBAAsB,EAAE,IAAI,CAAC;CAC7B;AAED,MAAM,MAAM,aAAa,GAAG,MAAM,cAAc,CAAC;AAEjD,OAAO,QAAQ,gBAAgB,CAAC;IAC/B,UAAU,WAAY,SAAQ,cAAc;KAAG;CAC/C;AAED,eAAO,MAAM,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAEJ,WAAW,EAAE,QAAQ;iBAAE,WAAW,EAAE,iBAAiB;;;iBACzD,WAAW,EAAE,QAAQ;iBAAE,WAAW,EAAE,cAAc;;;iBACnD,WAAW,EAAE,QAAQ;iBAAE,WAAW,EAAE,2BAA2B;;;iBAE5E,WAAW;iBACX,WAAW,EAAE,uBAAuB;;;iBAGpC,WAAW,EAAE,WAAW;iBACxB,WAAW,EAAE,sBAAsB;;;iBAGnC,WAAW,EAAE,QAAQ;iBACrB,WAAW,EAAE,qBAAqB;;;iBAGlC,WAAW,EAAE,cAAc;iBAC3B,WAAW,EAAE,yBAAyB;;;iBAEjB,WAAW,EAAE,QAAQ;iBAAE,WAAW,EAAE,qBAAqB;;;iBACzD,WAAW,EAAE,QAAQ;iBAAE,WAAW,EAAE,oBAAoB;;;iBAE7E,WAAW,EAAE,QAAQ;iBACrB,WAAW,EAAE,wBAAwB;;;iBAGrC,WAAW,EAAE,QAAQ;iBACrB,WAAW,EAAE,6BAA6B;;;iBAG1C,WAAW,EAAE,QAAQ;iBACrB,WAAW,EAAE,sBAAsB;;;iBAGnC,WAAW,EAAE,WAAW;iBACxB,WAAW,EAAE,yBAAyB;;;iBAGtC,WAAW,EAAE,QAAQ;iBACrB,WAAW,EAAE,yBAAyB;;;iBAGtC,WAAW;iBACX,WAAW,EAAE,4BAA4B;;;iBAErB,WAAW;iBAAM,WAAW,EAAE,qBAAqB;;;iBAClD,WAAW;iBAAM,WAAW,EAAE,mBAAmB;;;iBACjD,WAAW;iBAAM,WAAW,EAAE,sBAAsB;;;iBAClD,WAAW;iBAAM,WAAW,EAAE,kBAAkB;;;iBAChD,WAAW;iBAAM,WAAW,EAAE,oCAAoC;;;iBAEzF,WAAW;iBACX,WAAW,EAAE,6BAA6B;;;iBAG1C,WAAW;iBACX,WAAW,EAAE,iCAAiC;;;iBAG9C,WAAW,EAAE,SAAS;iBACtB,WAAW,EAAE,iBAAiB;;;iBAG9B,WAAW,EAAE,SAAS;iBACtB,WAAW,EAAE,8BAA8B;;;iBAG3C,WAAW,EAAE,QAAQ;iBACrB,WAAW,EAAE,6BAA6B;;;iBAG1C,WAAW,EAAE,QAAQ;iBACrB,WAAW,EAAE,0BAA0B;;;iBAGvC,WAAW,EAAE,QAAQ;iBACrB,WAAW,EAAE,gBAAgB;;;iBAG7B,WAAW,EAAE,QAAQ;iBACrB,WAAW,EAAE,gBAAgB;;;iBAG7B,WAAW,EAAE,gBAAgB;iBAC7B,WAAW,EAAE,oCAAoC;;;iBAGjD,WAAW,EAAE,QAAQ;iBACrB,WAAW,EAAE,sBAAsB;;;iBAGnC,WAAW,EAAE,QAAQ;iBACrB,WAAW,EAAE,mBAAmB;;;iBAGhC,WAAW,EAAE,QAAQ;iBACrB,WAAW,EAAE,kBAAkB;;;iBAG/B,WAAW,EAAE,QAAQ;iBACrB,WAAW,EAAE,gCAAgC;;;iBAG7C,WAAW,EAAE,QAAQ;iBACrB,WAAW,EAAE,wBAAwB;;;iBAGrC,WAAW,EAAE,UAAU;iBACvB,WAAW,EAAE,0BAA0B;;;iBAGvC,WAAW,EAAE,QAAQ;iBACrB,WAAW,EAAE,2BAA2B;;;iBAGxC,WAAW,EAAE,QAAQ;iBACrB,WAAW,EAAE,gCAAgC;;;iBAG7C,WAAW,EAAE,QAAQ;iBACrB,WAAW,EAAE,iCAAiC;;;iBAG9C,WAAW,EAAE,QAAQ;iBACrB,WAAW,EAAE,mCAAmC;;;iBAGhD,WAAW,EAAE,QAAQ;iBACrB,WAAW,EAAE,+BAA+B;;;iBAG5C,WAAW,EAAE,QAAQ;iBACrB,WAAW,EAAE,4BAA4B;;;iBAGzC,WAAW,EAAE,cAAc;iBAC3B,WAAW,EAAE,6BAA6B;;;iBAG1C,WAAW,EAAE,OAAO;iBACpB,WAAW,EAAE,mCAAmC;;;iBAGhD,WAAW,EAAE,OAAO;iBACpB,WAAW,EAAE,mCAAmC;;CAER,CAAC;AAwF3C,wBAAgB,wBAAwB,CAAC,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG;IAC7E,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAChC,QAAQ,EAAE,OAAO,CAAC;CAClB,CAiBA;AA8BD,qBAAa,kBAAmB,SAAQ,qBAAqB;IAC5D,OAAO,CAAC,UAAU,CAAqB;IAEvC,YAAY,YAAY,GAAE,iBAAsB,EAAE,UAAU,CAAC,EAAE,MAAM,EAGpE;IAED,MAAM,CAAC,MAAM,CAAC,QAAQ,GAAE,MAAsB,GAAG,kBAAkB,CAIlE;IAED,MAAM,IAAI,IAAI,CAGb;IAED,kBAAkB,IAAI,iBAAiB,CAEtC;IAED,OAAO,CAAC,MAAM,CAAC,YAAY;CAK3B;AAED,YAAY,EAAE,UAAU,EAAE,iBAAiB,EAAE,KAAK,EAAE,CAAC"}
@@ -142,6 +142,14 @@ export const KEYBINDINGS = {
142
142
  defaultKeys: "shift+ctrl+o",
143
143
  description: "Tree filter: cycle backward",
144
144
  },
145
+ "app.packages.toggle": {
146
+ defaultKeys: "space",
147
+ description: "Package browser: toggle selection",
148
+ },
149
+ "app.packages.install": {
150
+ defaultKeys: "enter",
151
+ description: "Package browser: install selected",
152
+ },
145
153
  };
146
154
  const KEYBINDING_NAME_MIGRATIONS = {
147
155
  cursorUp: "tui.editor.cursorUp",
@@ -1 +1 @@
1
- {"version":3,"file":"keybindings.js","sourceRoot":"","sources":["../../src/core/keybindings.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n\ttype Keybinding,\n\ttype KeybindingDefinitions,\n\ttype KeybindingsConfig,\n\ttype KeyId,\n\tTUI_KEYBINDINGS,\n\tKeybindingsManager as TuiKeybindingsManager,\n} from \"@elyracode/tui\";\nimport { existsSync, readFileSync } from \"fs\";\nimport { join } from \"path\";\nimport { getAgentDir } from \"../config.js\";\n\nexport interface AppKeybindings {\n\t\"app.interrupt\": true;\n\t\"app.clear\": true;\n\t\"app.exit\": true;\n\t\"app.suspend\": true;\n\t\"app.thinking.cycle\": true;\n\t\"app.model.cycleForward\": true;\n\t\"app.model.cycleBackward\": true;\n\t\"app.model.select\": true;\n\t\"app.tools.expand\": true;\n\t\"app.thinking.toggle\": true;\n\t\"app.session.toggleNamedFilter\": true;\n\t\"app.editor.external\": true;\n\t\"app.message.followUp\": true;\n\t\"app.message.dequeue\": true;\n\t\"app.clipboard.pasteImage\": true;\n\t\"app.session.new\": true;\n\t\"app.session.tree\": true;\n\t\"app.session.fork\": true;\n\t\"app.session.resume\": true;\n\t\"app.session.rewind\": true;\n\t\"app.tree.foldOrUp\": true;\n\t\"app.tree.unfoldOrDown\": true;\n\t\"app.tree.editLabel\": true;\n\t\"app.tree.toggleLabelTimestamp\": true;\n\t\"app.session.togglePath\": true;\n\t\"app.session.toggleSort\": true;\n\t\"app.session.rename\": true;\n\t\"app.session.delete\": true;\n\t\"app.session.deleteNoninvasive\": true;\n\t\"app.models.save\": true;\n\t\"app.models.enableAll\": true;\n\t\"app.models.clearAll\": true;\n\t\"app.models.toggleProvider\": true;\n\t\"app.models.reorderUp\": true;\n\t\"app.models.reorderDown\": true;\n\t\"app.tree.filter.default\": true;\n\t\"app.tree.filter.noTools\": true;\n\t\"app.tree.filter.userOnly\": true;\n\t\"app.tree.filter.labeledOnly\": true;\n\t\"app.tree.filter.all\": true;\n\t\"app.tree.filter.cycleForward\": true;\n\t\"app.tree.filter.cycleBackward\": true;\n}\n\nexport type AppKeybinding = keyof AppKeybindings;\n\ndeclare module \"@elyracode/tui\" {\n\tinterface Keybindings extends AppKeybindings {}\n}\n\nexport const KEYBINDINGS = {\n\t...TUI_KEYBINDINGS,\n\t\"app.interrupt\": { defaultKeys: \"escape\", description: \"Cancel or abort\" },\n\t\"app.clear\": { defaultKeys: \"ctrl+c\", description: \"Clear editor\" },\n\t\"app.exit\": { defaultKeys: \"ctrl+d\", description: \"Exit when editor is empty\" },\n\t\"app.suspend\": {\n\t\tdefaultKeys: process.platform === \"win32\" ? [] : \"ctrl+z\",\n\t\tdescription: \"Suspend to background\",\n\t},\n\t\"app.thinking.cycle\": {\n\t\tdefaultKeys: \"shift+tab\",\n\t\tdescription: \"Cycle thinking level\",\n\t},\n\t\"app.model.cycleForward\": {\n\t\tdefaultKeys: \"ctrl+p\",\n\t\tdescription: \"Cycle to next model\",\n\t},\n\t\"app.model.cycleBackward\": {\n\t\tdefaultKeys: \"shift+ctrl+p\",\n\t\tdescription: \"Cycle to previous model\",\n\t},\n\t\"app.model.select\": { defaultKeys: \"ctrl+l\", description: \"Open model selector\" },\n\t\"app.tools.expand\": { defaultKeys: \"ctrl+o\", description: \"Toggle tool output\" },\n\t\"app.thinking.toggle\": {\n\t\tdefaultKeys: \"ctrl+t\",\n\t\tdescription: \"Toggle thinking blocks\",\n\t},\n\t\"app.session.toggleNamedFilter\": {\n\t\tdefaultKeys: \"ctrl+n\",\n\t\tdescription: \"Toggle named session filter\",\n\t},\n\t\"app.editor.external\": {\n\t\tdefaultKeys: \"ctrl+g\",\n\t\tdescription: \"Open external editor\",\n\t},\n\t\"app.message.followUp\": {\n\t\tdefaultKeys: \"alt+enter\",\n\t\tdescription: \"Queue follow-up message\",\n\t},\n\t\"app.message.dequeue\": {\n\t\tdefaultKeys: \"alt+up\",\n\t\tdescription: \"Restore queued messages\",\n\t},\n\t\"app.clipboard.pasteImage\": {\n\t\tdefaultKeys: process.platform === \"win32\" ? \"alt+v\" : \"ctrl+v\",\n\t\tdescription: \"Paste image from clipboard\",\n\t},\n\t\"app.session.new\": { defaultKeys: [], description: \"Start a new session\" },\n\t\"app.session.tree\": { defaultKeys: [], description: \"Open session tree\" },\n\t\"app.session.fork\": { defaultKeys: [], description: \"Fork current session\" },\n\t\"app.session.resume\": { defaultKeys: [], description: \"Resume a session\" },\n\t\"app.session.rewind\": { defaultKeys: [], description: \"Rewind session to a previous point\" },\n\t\"app.tree.foldOrUp\": {\n\t\tdefaultKeys: [\"ctrl+left\", \"alt+left\"],\n\t\tdescription: \"Fold tree branch or move up\",\n\t},\n\t\"app.tree.unfoldOrDown\": {\n\t\tdefaultKeys: [\"ctrl+right\", \"alt+right\"],\n\t\tdescription: \"Unfold tree branch or move down\",\n\t},\n\t\"app.tree.editLabel\": {\n\t\tdefaultKeys: \"shift+l\",\n\t\tdescription: \"Edit tree label\",\n\t},\n\t\"app.tree.toggleLabelTimestamp\": {\n\t\tdefaultKeys: \"shift+t\",\n\t\tdescription: \"Toggle tree label timestamps\",\n\t},\n\t\"app.session.togglePath\": {\n\t\tdefaultKeys: \"ctrl+p\",\n\t\tdescription: \"Toggle session path display\",\n\t},\n\t\"app.session.toggleSort\": {\n\t\tdefaultKeys: \"ctrl+s\",\n\t\tdescription: \"Toggle session sort mode\",\n\t},\n\t\"app.session.rename\": {\n\t\tdefaultKeys: \"ctrl+r\",\n\t\tdescription: \"Rename session\",\n\t},\n\t\"app.session.delete\": {\n\t\tdefaultKeys: \"ctrl+d\",\n\t\tdescription: \"Delete session\",\n\t},\n\t\"app.session.deleteNoninvasive\": {\n\t\tdefaultKeys: \"ctrl+backspace\",\n\t\tdescription: \"Delete session when query is empty\",\n\t},\n\t\"app.models.save\": {\n\t\tdefaultKeys: \"ctrl+s\",\n\t\tdescription: \"Save model selection\",\n\t},\n\t\"app.models.enableAll\": {\n\t\tdefaultKeys: \"ctrl+a\",\n\t\tdescription: \"Enable all models\",\n\t},\n\t\"app.models.clearAll\": {\n\t\tdefaultKeys: \"ctrl+x\",\n\t\tdescription: \"Clear all models\",\n\t},\n\t\"app.models.toggleProvider\": {\n\t\tdefaultKeys: \"ctrl+p\",\n\t\tdescription: \"Toggle all models for provider\",\n\t},\n\t\"app.models.reorderUp\": {\n\t\tdefaultKeys: \"alt+up\",\n\t\tdescription: \"Move model up in order\",\n\t},\n\t\"app.models.reorderDown\": {\n\t\tdefaultKeys: \"alt+down\",\n\t\tdescription: \"Move model down in order\",\n\t},\n\t\"app.tree.filter.default\": {\n\t\tdefaultKeys: \"ctrl+d\",\n\t\tdescription: \"Tree filter: default view\",\n\t},\n\t\"app.tree.filter.noTools\": {\n\t\tdefaultKeys: \"ctrl+t\",\n\t\tdescription: \"Tree filter: hide tool results\",\n\t},\n\t\"app.tree.filter.userOnly\": {\n\t\tdefaultKeys: \"ctrl+u\",\n\t\tdescription: \"Tree filter: user messages only\",\n\t},\n\t\"app.tree.filter.labeledOnly\": {\n\t\tdefaultKeys: \"ctrl+l\",\n\t\tdescription: \"Tree filter: labeled entries only\",\n\t},\n\t\"app.tree.filter.all\": {\n\t\tdefaultKeys: \"ctrl+a\",\n\t\tdescription: \"Tree filter: show all entries\",\n\t},\n\t\"app.tree.filter.cycleForward\": {\n\t\tdefaultKeys: \"ctrl+o\",\n\t\tdescription: \"Tree filter: cycle forward\",\n\t},\n\t\"app.tree.filter.cycleBackward\": {\n\t\tdefaultKeys: \"shift+ctrl+o\",\n\t\tdescription: \"Tree filter: cycle backward\",\n\t},\n} as const satisfies KeybindingDefinitions;\n\nconst KEYBINDING_NAME_MIGRATIONS = {\n\tcursorUp: \"tui.editor.cursorUp\",\n\tcursorDown: \"tui.editor.cursorDown\",\n\tcursorLeft: \"tui.editor.cursorLeft\",\n\tcursorRight: \"tui.editor.cursorRight\",\n\tcursorWordLeft: \"tui.editor.cursorWordLeft\",\n\tcursorWordRight: \"tui.editor.cursorWordRight\",\n\tcursorLineStart: \"tui.editor.cursorLineStart\",\n\tcursorLineEnd: \"tui.editor.cursorLineEnd\",\n\tjumpForward: \"tui.editor.jumpForward\",\n\tjumpBackward: \"tui.editor.jumpBackward\",\n\tpageUp: \"tui.editor.pageUp\",\n\tpageDown: \"tui.editor.pageDown\",\n\tdeleteCharBackward: \"tui.editor.deleteCharBackward\",\n\tdeleteCharForward: \"tui.editor.deleteCharForward\",\n\tdeleteWordBackward: \"tui.editor.deleteWordBackward\",\n\tdeleteWordForward: \"tui.editor.deleteWordForward\",\n\tdeleteToLineStart: \"tui.editor.deleteToLineStart\",\n\tdeleteToLineEnd: \"tui.editor.deleteToLineEnd\",\n\tyank: \"tui.editor.yank\",\n\tyankPop: \"tui.editor.yankPop\",\n\tundo: \"tui.editor.undo\",\n\tnewLine: \"tui.input.newLine\",\n\tsubmit: \"tui.input.submit\",\n\ttab: \"tui.input.tab\",\n\tcopy: \"tui.input.copy\",\n\tselectUp: \"tui.select.up\",\n\tselectDown: \"tui.select.down\",\n\tselectPageUp: \"tui.select.pageUp\",\n\tselectPageDown: \"tui.select.pageDown\",\n\tselectConfirm: \"tui.select.confirm\",\n\tselectCancel: \"tui.select.cancel\",\n\tinterrupt: \"app.interrupt\",\n\tclear: \"app.clear\",\n\texit: \"app.exit\",\n\tsuspend: \"app.suspend\",\n\tcycleThinkingLevel: \"app.thinking.cycle\",\n\tcycleModelForward: \"app.model.cycleForward\",\n\tcycleModelBackward: \"app.model.cycleBackward\",\n\tselectModel: \"app.model.select\",\n\texpandTools: \"app.tools.expand\",\n\ttoggleThinking: \"app.thinking.toggle\",\n\ttoggleSessionNamedFilter: \"app.session.toggleNamedFilter\",\n\texternalEditor: \"app.editor.external\",\n\tfollowUp: \"app.message.followUp\",\n\tdequeue: \"app.message.dequeue\",\n\tpasteImage: \"app.clipboard.pasteImage\",\n\tnewSession: \"app.session.new\",\n\ttree: \"app.session.tree\",\n\tfork: \"app.session.fork\",\n\tresume: \"app.session.resume\",\n\ttreeFoldOrUp: \"app.tree.foldOrUp\",\n\ttreeUnfoldOrDown: \"app.tree.unfoldOrDown\",\n\ttreeEditLabel: \"app.tree.editLabel\",\n\ttreeToggleLabelTimestamp: \"app.tree.toggleLabelTimestamp\",\n\ttoggleSessionPath: \"app.session.togglePath\",\n\ttoggleSessionSort: \"app.session.toggleSort\",\n\trenameSession: \"app.session.rename\",\n\tdeleteSession: \"app.session.delete\",\n\tdeleteSessionNoninvasive: \"app.session.deleteNoninvasive\",\n} as const satisfies Record<string, Keybinding>;\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n\treturn typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction isLegacyKeybindingName(key: string): key is keyof typeof KEYBINDING_NAME_MIGRATIONS {\n\treturn key in KEYBINDING_NAME_MIGRATIONS;\n}\n\nfunction toKeybindingsConfig(value: unknown): KeybindingsConfig {\n\tif (!isRecord(value)) return {};\n\n\tconst config: KeybindingsConfig = {};\n\tfor (const [key, binding] of Object.entries(value)) {\n\t\tif (typeof binding === \"string\") {\n\t\t\tconfig[key] = binding as KeyId;\n\t\t\tcontinue;\n\t\t}\n\t\tif (Array.isArray(binding) && binding.every((entry) => typeof entry === \"string\")) {\n\t\t\tconfig[key] = binding as KeyId[];\n\t\t}\n\t}\n\treturn config;\n}\n\nexport function migrateKeybindingsConfig(rawConfig: Record<string, unknown>): {\n\tconfig: Record<string, unknown>;\n\tmigrated: boolean;\n} {\n\tconst config: Record<string, unknown> = {};\n\tlet migrated = false;\n\n\tfor (const [key, value] of Object.entries(rawConfig)) {\n\t\tconst nextKey = isLegacyKeybindingName(key) ? KEYBINDING_NAME_MIGRATIONS[key] : key;\n\t\tif (nextKey !== key) {\n\t\t\tmigrated = true;\n\t\t}\n\t\tif (key !== nextKey && Object.hasOwn(rawConfig, nextKey)) {\n\t\t\tmigrated = true;\n\t\t\tcontinue;\n\t\t}\n\t\tconfig[nextKey] = value;\n\t}\n\n\treturn { config: orderKeybindingsConfig(config), migrated };\n}\n\nfunction orderKeybindingsConfig(config: Record<string, unknown>): Record<string, unknown> {\n\tconst ordered: Record<string, unknown> = {};\n\tfor (const keybinding of Object.keys(KEYBINDINGS)) {\n\t\tif (Object.hasOwn(config, keybinding)) {\n\t\t\tordered[keybinding] = config[keybinding];\n\t\t}\n\t}\n\n\tconst extras = Object.keys(config)\n\t\t.filter((key) => !Object.hasOwn(ordered, key))\n\t\t.sort();\n\tfor (const key of extras) {\n\t\tordered[key] = config[key];\n\t}\n\n\treturn ordered;\n}\n\nfunction loadRawConfig(path: string): Record<string, unknown> | undefined {\n\tif (!existsSync(path)) return undefined;\n\ttry {\n\t\tconst parsed = JSON.parse(readFileSync(path, \"utf-8\")) as unknown;\n\t\treturn isRecord(parsed) ? parsed : undefined;\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n\nexport class KeybindingsManager extends TuiKeybindingsManager {\n\tprivate configPath: string | undefined;\n\n\tconstructor(userBindings: KeybindingsConfig = {}, configPath?: string) {\n\t\tsuper(KEYBINDINGS, userBindings);\n\t\tthis.configPath = configPath;\n\t}\n\n\tstatic create(agentDir: string = getAgentDir()): KeybindingsManager {\n\t\tconst configPath = join(agentDir, \"keybindings.json\");\n\t\tconst userBindings = KeybindingsManager.loadFromFile(configPath);\n\t\treturn new KeybindingsManager(userBindings, configPath);\n\t}\n\n\treload(): void {\n\t\tif (!this.configPath) return;\n\t\tthis.setUserBindings(KeybindingsManager.loadFromFile(this.configPath));\n\t}\n\n\tgetEffectiveConfig(): KeybindingsConfig {\n\t\treturn this.getResolvedBindings();\n\t}\n\n\tprivate static loadFromFile(path: string): KeybindingsConfig {\n\t\tconst rawConfig = loadRawConfig(path);\n\t\tif (!rawConfig) return {};\n\t\treturn toKeybindingsConfig(migrateKeybindingsConfig(rawConfig).config);\n\t}\n}\n\nexport type { Keybinding, KeybindingsConfig, KeyId };\n"]}
1
+ {"version":3,"file":"keybindings.js","sourceRoot":"","sources":["../../src/core/keybindings.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n\ttype Keybinding,\n\ttype KeybindingDefinitions,\n\ttype KeybindingsConfig,\n\ttype KeyId,\n\tTUI_KEYBINDINGS,\n\tKeybindingsManager as TuiKeybindingsManager,\n} from \"@elyracode/tui\";\nimport { existsSync, readFileSync } from \"fs\";\nimport { join } from \"path\";\nimport { getAgentDir } from \"../config.js\";\n\nexport interface AppKeybindings {\n\t\"app.interrupt\": true;\n\t\"app.clear\": true;\n\t\"app.exit\": true;\n\t\"app.suspend\": true;\n\t\"app.thinking.cycle\": true;\n\t\"app.model.cycleForward\": true;\n\t\"app.model.cycleBackward\": true;\n\t\"app.model.select\": true;\n\t\"app.tools.expand\": true;\n\t\"app.thinking.toggle\": true;\n\t\"app.session.toggleNamedFilter\": true;\n\t\"app.editor.external\": true;\n\t\"app.message.followUp\": true;\n\t\"app.message.dequeue\": true;\n\t\"app.clipboard.pasteImage\": true;\n\t\"app.session.new\": true;\n\t\"app.session.tree\": true;\n\t\"app.session.fork\": true;\n\t\"app.session.resume\": true;\n\t\"app.session.rewind\": true;\n\t\"app.tree.foldOrUp\": true;\n\t\"app.tree.unfoldOrDown\": true;\n\t\"app.tree.editLabel\": true;\n\t\"app.tree.toggleLabelTimestamp\": true;\n\t\"app.session.togglePath\": true;\n\t\"app.session.toggleSort\": true;\n\t\"app.session.rename\": true;\n\t\"app.session.delete\": true;\n\t\"app.session.deleteNoninvasive\": true;\n\t\"app.models.save\": true;\n\t\"app.models.enableAll\": true;\n\t\"app.models.clearAll\": true;\n\t\"app.models.toggleProvider\": true;\n\t\"app.models.reorderUp\": true;\n\t\"app.models.reorderDown\": true;\n\t\"app.tree.filter.default\": true;\n\t\"app.tree.filter.noTools\": true;\n\t\"app.tree.filter.userOnly\": true;\n\t\"app.tree.filter.labeledOnly\": true;\n\t\"app.tree.filter.all\": true;\n\t\"app.tree.filter.cycleForward\": true;\n\t\"app.tree.filter.cycleBackward\": true;\n\t\"app.packages.toggle\": true;\n\t\"app.packages.install\": true;\n}\n\nexport type AppKeybinding = keyof AppKeybindings;\n\ndeclare module \"@elyracode/tui\" {\n\tinterface Keybindings extends AppKeybindings {}\n}\n\nexport const KEYBINDINGS = {\n\t...TUI_KEYBINDINGS,\n\t\"app.interrupt\": { defaultKeys: \"escape\", description: \"Cancel or abort\" },\n\t\"app.clear\": { defaultKeys: \"ctrl+c\", description: \"Clear editor\" },\n\t\"app.exit\": { defaultKeys: \"ctrl+d\", description: \"Exit when editor is empty\" },\n\t\"app.suspend\": {\n\t\tdefaultKeys: process.platform === \"win32\" ? [] : \"ctrl+z\",\n\t\tdescription: \"Suspend to background\",\n\t},\n\t\"app.thinking.cycle\": {\n\t\tdefaultKeys: \"shift+tab\",\n\t\tdescription: \"Cycle thinking level\",\n\t},\n\t\"app.model.cycleForward\": {\n\t\tdefaultKeys: \"ctrl+p\",\n\t\tdescription: \"Cycle to next model\",\n\t},\n\t\"app.model.cycleBackward\": {\n\t\tdefaultKeys: \"shift+ctrl+p\",\n\t\tdescription: \"Cycle to previous model\",\n\t},\n\t\"app.model.select\": { defaultKeys: \"ctrl+l\", description: \"Open model selector\" },\n\t\"app.tools.expand\": { defaultKeys: \"ctrl+o\", description: \"Toggle tool output\" },\n\t\"app.thinking.toggle\": {\n\t\tdefaultKeys: \"ctrl+t\",\n\t\tdescription: \"Toggle thinking blocks\",\n\t},\n\t\"app.session.toggleNamedFilter\": {\n\t\tdefaultKeys: \"ctrl+n\",\n\t\tdescription: \"Toggle named session filter\",\n\t},\n\t\"app.editor.external\": {\n\t\tdefaultKeys: \"ctrl+g\",\n\t\tdescription: \"Open external editor\",\n\t},\n\t\"app.message.followUp\": {\n\t\tdefaultKeys: \"alt+enter\",\n\t\tdescription: \"Queue follow-up message\",\n\t},\n\t\"app.message.dequeue\": {\n\t\tdefaultKeys: \"alt+up\",\n\t\tdescription: \"Restore queued messages\",\n\t},\n\t\"app.clipboard.pasteImage\": {\n\t\tdefaultKeys: process.platform === \"win32\" ? \"alt+v\" : \"ctrl+v\",\n\t\tdescription: \"Paste image from clipboard\",\n\t},\n\t\"app.session.new\": { defaultKeys: [], description: \"Start a new session\" },\n\t\"app.session.tree\": { defaultKeys: [], description: \"Open session tree\" },\n\t\"app.session.fork\": { defaultKeys: [], description: \"Fork current session\" },\n\t\"app.session.resume\": { defaultKeys: [], description: \"Resume a session\" },\n\t\"app.session.rewind\": { defaultKeys: [], description: \"Rewind session to a previous point\" },\n\t\"app.tree.foldOrUp\": {\n\t\tdefaultKeys: [\"ctrl+left\", \"alt+left\"],\n\t\tdescription: \"Fold tree branch or move up\",\n\t},\n\t\"app.tree.unfoldOrDown\": {\n\t\tdefaultKeys: [\"ctrl+right\", \"alt+right\"],\n\t\tdescription: \"Unfold tree branch or move down\",\n\t},\n\t\"app.tree.editLabel\": {\n\t\tdefaultKeys: \"shift+l\",\n\t\tdescription: \"Edit tree label\",\n\t},\n\t\"app.tree.toggleLabelTimestamp\": {\n\t\tdefaultKeys: \"shift+t\",\n\t\tdescription: \"Toggle tree label timestamps\",\n\t},\n\t\"app.session.togglePath\": {\n\t\tdefaultKeys: \"ctrl+p\",\n\t\tdescription: \"Toggle session path display\",\n\t},\n\t\"app.session.toggleSort\": {\n\t\tdefaultKeys: \"ctrl+s\",\n\t\tdescription: \"Toggle session sort mode\",\n\t},\n\t\"app.session.rename\": {\n\t\tdefaultKeys: \"ctrl+r\",\n\t\tdescription: \"Rename session\",\n\t},\n\t\"app.session.delete\": {\n\t\tdefaultKeys: \"ctrl+d\",\n\t\tdescription: \"Delete session\",\n\t},\n\t\"app.session.deleteNoninvasive\": {\n\t\tdefaultKeys: \"ctrl+backspace\",\n\t\tdescription: \"Delete session when query is empty\",\n\t},\n\t\"app.models.save\": {\n\t\tdefaultKeys: \"ctrl+s\",\n\t\tdescription: \"Save model selection\",\n\t},\n\t\"app.models.enableAll\": {\n\t\tdefaultKeys: \"ctrl+a\",\n\t\tdescription: \"Enable all models\",\n\t},\n\t\"app.models.clearAll\": {\n\t\tdefaultKeys: \"ctrl+x\",\n\t\tdescription: \"Clear all models\",\n\t},\n\t\"app.models.toggleProvider\": {\n\t\tdefaultKeys: \"ctrl+p\",\n\t\tdescription: \"Toggle all models for provider\",\n\t},\n\t\"app.models.reorderUp\": {\n\t\tdefaultKeys: \"alt+up\",\n\t\tdescription: \"Move model up in order\",\n\t},\n\t\"app.models.reorderDown\": {\n\t\tdefaultKeys: \"alt+down\",\n\t\tdescription: \"Move model down in order\",\n\t},\n\t\"app.tree.filter.default\": {\n\t\tdefaultKeys: \"ctrl+d\",\n\t\tdescription: \"Tree filter: default view\",\n\t},\n\t\"app.tree.filter.noTools\": {\n\t\tdefaultKeys: \"ctrl+t\",\n\t\tdescription: \"Tree filter: hide tool results\",\n\t},\n\t\"app.tree.filter.userOnly\": {\n\t\tdefaultKeys: \"ctrl+u\",\n\t\tdescription: \"Tree filter: user messages only\",\n\t},\n\t\"app.tree.filter.labeledOnly\": {\n\t\tdefaultKeys: \"ctrl+l\",\n\t\tdescription: \"Tree filter: labeled entries only\",\n\t},\n\t\"app.tree.filter.all\": {\n\t\tdefaultKeys: \"ctrl+a\",\n\t\tdescription: \"Tree filter: show all entries\",\n\t},\n\t\"app.tree.filter.cycleForward\": {\n\t\tdefaultKeys: \"ctrl+o\",\n\t\tdescription: \"Tree filter: cycle forward\",\n\t},\n\t\"app.tree.filter.cycleBackward\": {\n\t\tdefaultKeys: \"shift+ctrl+o\",\n\t\tdescription: \"Tree filter: cycle backward\",\n\t},\n\t\"app.packages.toggle\": {\n\t\tdefaultKeys: \"space\",\n\t\tdescription: \"Package browser: toggle selection\",\n\t},\n\t\"app.packages.install\": {\n\t\tdefaultKeys: \"enter\",\n\t\tdescription: \"Package browser: install selected\",\n\t},\n} as const satisfies KeybindingDefinitions;\n\nconst KEYBINDING_NAME_MIGRATIONS = {\n\tcursorUp: \"tui.editor.cursorUp\",\n\tcursorDown: \"tui.editor.cursorDown\",\n\tcursorLeft: \"tui.editor.cursorLeft\",\n\tcursorRight: \"tui.editor.cursorRight\",\n\tcursorWordLeft: \"tui.editor.cursorWordLeft\",\n\tcursorWordRight: \"tui.editor.cursorWordRight\",\n\tcursorLineStart: \"tui.editor.cursorLineStart\",\n\tcursorLineEnd: \"tui.editor.cursorLineEnd\",\n\tjumpForward: \"tui.editor.jumpForward\",\n\tjumpBackward: \"tui.editor.jumpBackward\",\n\tpageUp: \"tui.editor.pageUp\",\n\tpageDown: \"tui.editor.pageDown\",\n\tdeleteCharBackward: \"tui.editor.deleteCharBackward\",\n\tdeleteCharForward: \"tui.editor.deleteCharForward\",\n\tdeleteWordBackward: \"tui.editor.deleteWordBackward\",\n\tdeleteWordForward: \"tui.editor.deleteWordForward\",\n\tdeleteToLineStart: \"tui.editor.deleteToLineStart\",\n\tdeleteToLineEnd: \"tui.editor.deleteToLineEnd\",\n\tyank: \"tui.editor.yank\",\n\tyankPop: \"tui.editor.yankPop\",\n\tundo: \"tui.editor.undo\",\n\tnewLine: \"tui.input.newLine\",\n\tsubmit: \"tui.input.submit\",\n\ttab: \"tui.input.tab\",\n\tcopy: \"tui.input.copy\",\n\tselectUp: \"tui.select.up\",\n\tselectDown: \"tui.select.down\",\n\tselectPageUp: \"tui.select.pageUp\",\n\tselectPageDown: \"tui.select.pageDown\",\n\tselectConfirm: \"tui.select.confirm\",\n\tselectCancel: \"tui.select.cancel\",\n\tinterrupt: \"app.interrupt\",\n\tclear: \"app.clear\",\n\texit: \"app.exit\",\n\tsuspend: \"app.suspend\",\n\tcycleThinkingLevel: \"app.thinking.cycle\",\n\tcycleModelForward: \"app.model.cycleForward\",\n\tcycleModelBackward: \"app.model.cycleBackward\",\n\tselectModel: \"app.model.select\",\n\texpandTools: \"app.tools.expand\",\n\ttoggleThinking: \"app.thinking.toggle\",\n\ttoggleSessionNamedFilter: \"app.session.toggleNamedFilter\",\n\texternalEditor: \"app.editor.external\",\n\tfollowUp: \"app.message.followUp\",\n\tdequeue: \"app.message.dequeue\",\n\tpasteImage: \"app.clipboard.pasteImage\",\n\tnewSession: \"app.session.new\",\n\ttree: \"app.session.tree\",\n\tfork: \"app.session.fork\",\n\tresume: \"app.session.resume\",\n\ttreeFoldOrUp: \"app.tree.foldOrUp\",\n\ttreeUnfoldOrDown: \"app.tree.unfoldOrDown\",\n\ttreeEditLabel: \"app.tree.editLabel\",\n\ttreeToggleLabelTimestamp: \"app.tree.toggleLabelTimestamp\",\n\ttoggleSessionPath: \"app.session.togglePath\",\n\ttoggleSessionSort: \"app.session.toggleSort\",\n\trenameSession: \"app.session.rename\",\n\tdeleteSession: \"app.session.delete\",\n\tdeleteSessionNoninvasive: \"app.session.deleteNoninvasive\",\n} as const satisfies Record<string, Keybinding>;\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n\treturn typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction isLegacyKeybindingName(key: string): key is keyof typeof KEYBINDING_NAME_MIGRATIONS {\n\treturn key in KEYBINDING_NAME_MIGRATIONS;\n}\n\nfunction toKeybindingsConfig(value: unknown): KeybindingsConfig {\n\tif (!isRecord(value)) return {};\n\n\tconst config: KeybindingsConfig = {};\n\tfor (const [key, binding] of Object.entries(value)) {\n\t\tif (typeof binding === \"string\") {\n\t\t\tconfig[key] = binding as KeyId;\n\t\t\tcontinue;\n\t\t}\n\t\tif (Array.isArray(binding) && binding.every((entry) => typeof entry === \"string\")) {\n\t\t\tconfig[key] = binding as KeyId[];\n\t\t}\n\t}\n\treturn config;\n}\n\nexport function migrateKeybindingsConfig(rawConfig: Record<string, unknown>): {\n\tconfig: Record<string, unknown>;\n\tmigrated: boolean;\n} {\n\tconst config: Record<string, unknown> = {};\n\tlet migrated = false;\n\n\tfor (const [key, value] of Object.entries(rawConfig)) {\n\t\tconst nextKey = isLegacyKeybindingName(key) ? KEYBINDING_NAME_MIGRATIONS[key] : key;\n\t\tif (nextKey !== key) {\n\t\t\tmigrated = true;\n\t\t}\n\t\tif (key !== nextKey && Object.hasOwn(rawConfig, nextKey)) {\n\t\t\tmigrated = true;\n\t\t\tcontinue;\n\t\t}\n\t\tconfig[nextKey] = value;\n\t}\n\n\treturn { config: orderKeybindingsConfig(config), migrated };\n}\n\nfunction orderKeybindingsConfig(config: Record<string, unknown>): Record<string, unknown> {\n\tconst ordered: Record<string, unknown> = {};\n\tfor (const keybinding of Object.keys(KEYBINDINGS)) {\n\t\tif (Object.hasOwn(config, keybinding)) {\n\t\t\tordered[keybinding] = config[keybinding];\n\t\t}\n\t}\n\n\tconst extras = Object.keys(config)\n\t\t.filter((key) => !Object.hasOwn(ordered, key))\n\t\t.sort();\n\tfor (const key of extras) {\n\t\tordered[key] = config[key];\n\t}\n\n\treturn ordered;\n}\n\nfunction loadRawConfig(path: string): Record<string, unknown> | undefined {\n\tif (!existsSync(path)) return undefined;\n\ttry {\n\t\tconst parsed = JSON.parse(readFileSync(path, \"utf-8\")) as unknown;\n\t\treturn isRecord(parsed) ? parsed : undefined;\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n\nexport class KeybindingsManager extends TuiKeybindingsManager {\n\tprivate configPath: string | undefined;\n\n\tconstructor(userBindings: KeybindingsConfig = {}, configPath?: string) {\n\t\tsuper(KEYBINDINGS, userBindings);\n\t\tthis.configPath = configPath;\n\t}\n\n\tstatic create(agentDir: string = getAgentDir()): KeybindingsManager {\n\t\tconst configPath = join(agentDir, \"keybindings.json\");\n\t\tconst userBindings = KeybindingsManager.loadFromFile(configPath);\n\t\treturn new KeybindingsManager(userBindings, configPath);\n\t}\n\n\treload(): void {\n\t\tif (!this.configPath) return;\n\t\tthis.setUserBindings(KeybindingsManager.loadFromFile(this.configPath));\n\t}\n\n\tgetEffectiveConfig(): KeybindingsConfig {\n\t\treturn this.getResolvedBindings();\n\t}\n\n\tprivate static loadFromFile(path: string): KeybindingsConfig {\n\t\tconst rawConfig = loadRawConfig(path);\n\t\tif (!rawConfig) return {};\n\t\treturn toKeybindingsConfig(migrateKeybindingsConfig(rawConfig).config);\n\t}\n}\n\nexport type { Keybinding, KeybindingsConfig, KeyId };\n"]}
@@ -4,7 +4,7 @@ export interface DetectedFramework {
4
4
  version?: string;
5
5
  }
6
6
  /** Known stack profiles that can be suggested for installation */
7
- export type KnownStack = "TALL" | "RILT" | "VILT" | "SILT";
7
+ export type KnownStack = "TALL" | "RILT" | "VILT" | "SILT" | "ELYRA_FRAMEWORK";
8
8
  /** Result of stack detection */
9
9
  export interface StackDetectionResult {
10
10
  /** All detected frameworks */
@@ -1 +1 @@
1
- {"version":3,"file":"stack-detector.d.ts","sourceRoot":"","sources":["../../src/core/stack-detector.ts"],"names":[],"mappings":"AAGA,mDAAmD;AACnD,MAAM,WAAW,iBAAiB;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,kEAAkE;AAClE,MAAM,MAAM,UAAU,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC;AAE3D,gCAAgC;AAChC,MAAM,WAAW,oBAAoB;IACpC,8BAA8B;IAC9B,UAAU,EAAE,iBAAiB,EAAE,CAAC;IAChC,yEAAyE;IACzE,KAAK,CAAC,EAAE,UAAU,CAAC;IACnB,yDAAyD;IACzD,OAAO,EAAE,MAAM,CAAC;CAChB;AAED,yDAAyD;AACzD,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,oBAAoB,CAyH7D;AASD,0DAA0D;AAC1D,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,UAAU,GAAG,MAAM,CAW7D"}
1
+ {"version":3,"file":"stack-detector.d.ts","sourceRoot":"","sources":["../../src/core/stack-detector.ts"],"names":[],"mappings":"AAGA,mDAAmD;AACnD,MAAM,WAAW,iBAAiB;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,kEAAkE;AAClE,MAAM,MAAM,UAAU,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,iBAAiB,CAAC;AAE/E,gCAAgC;AAChC,MAAM,WAAW,oBAAoB;IACpC,8BAA8B;IAC9B,UAAU,EAAE,iBAAiB,EAAE,CAAC;IAChC,yEAAyE;IACzE,KAAK,CAAC,EAAE,UAAU,CAAC;IACnB,yDAAyD;IACzD,OAAO,EAAE,MAAM,CAAC;CAChB;AAED,yDAAyD;AACzD,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,oBAAoB,CA+I7D;AASD,0DAA0D;AAC1D,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,UAAU,GAAG,MAAM,CAa7D"}
@@ -83,13 +83,34 @@ export function detectStack(cwd) {
83
83
  // Ignore malformed package.json
84
84
  }
85
85
  }
86
+ // Detect Elyra Framework (Rust + Svelte 5 desktop apps). `rata new` scaffolds
87
+ // an `elyra.toml` config file, which is the most reliable signal; fall back
88
+ // to a plain-text check for the `elyra` crate dependency in Cargo.toml (TOML
89
+ // isn't parsed here to avoid adding a parser dependency for one field).
90
+ const cargoPath = join(cwd, "Cargo.toml");
91
+ if (existsSync(join(cwd, "elyra.toml")) || existsSync(cargoPath)) {
92
+ try {
93
+ const cargoText = existsSync(cargoPath) ? readFileSync(cargoPath, "utf-8") : "";
94
+ const hasElyraCrate = /^\s*elyra\s*=/m.test(cargoText) || /\[dependencies\.elyra\]/.test(cargoText);
95
+ if (existsSync(join(cwd, "elyra.toml")) || hasElyraCrate) {
96
+ const versionMatch = cargoText.match(/^\s*elyra\s*=\s*\{[^}]*version\s*=\s*"([^"]+)"/m);
97
+ frameworks.push({ name: "Elyra Framework", version: versionMatch?.[1] });
98
+ }
99
+ }
100
+ catch {
101
+ // Ignore unreadable Cargo.toml
102
+ }
103
+ }
86
104
  if (frameworks.length === 0) {
87
105
  return { frameworks, summary: "" };
88
106
  }
89
107
  // Detect known stack profiles
90
108
  const has = (name) => frameworks.some((f) => f.name === name);
91
109
  let stack;
92
- if (has("Laravel") && has("Tailwind CSS") && has("Alpine.js") && has("Livewire")) {
110
+ if (has("Elyra Framework")) {
111
+ stack = "ELYRA_FRAMEWORK";
112
+ }
113
+ else if (has("Laravel") && has("Tailwind CSS") && has("Alpine.js") && has("Livewire")) {
93
114
  stack = "TALL";
94
115
  }
95
116
  else if (has("Laravel") && has("Tailwind CSS") && has("Inertia") && has("React")) {
@@ -117,6 +138,9 @@ export function detectStack(cwd) {
117
138
  else if (stack === "SILT") {
118
139
  summary = `SILT stack project (Svelte, Inertia, Laravel, Tailwind).\n${frameworkList}`;
119
140
  }
141
+ else if (stack === "ELYRA_FRAMEWORK") {
142
+ summary = `Elyra Framework project (Rust + Svelte 5 desktop app, Laravel-inspired ergonomics).\n${frameworkList}`;
143
+ }
120
144
  return { frameworks, stack, summary };
121
145
  }
122
146
  /** Strip semver constraint prefixes (^, ~, >=, etc.) to get a clean version */
@@ -137,6 +161,8 @@ export function getSuggestedPackage(stack) {
137
161
  return "@elyracode/stack-vilt";
138
162
  case "SILT":
139
163
  return "@elyracode/stack-silt";
164
+ case "ELYRA_FRAMEWORK":
165
+ return "@elyracode/stack-elyra-framework";
140
166
  }
141
167
  }
142
168
  //# sourceMappingURL=stack-detector.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"stack-detector.js","sourceRoot":"","sources":["../../src/core/stack-detector.ts"],"names":[],"mappings":"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","sourcesContent":["import { existsSync, readFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\n\n/** Individual framework detected in the project */\nexport interface DetectedFramework {\n\tname: string;\n\tversion?: string;\n}\n\n/** Known stack profiles that can be suggested for installation */\nexport type KnownStack = \"TALL\" | \"RILT\" | \"VILT\" | \"SILT\";\n\n/** Result of stack detection */\nexport interface StackDetectionResult {\n\t/** All detected frameworks */\n\tframeworks: DetectedFramework[];\n\t/** Recognized stack profile (if frameworks match a known combination) */\n\tstack?: KnownStack;\n\t/** Human-readable summary for system prompt injection */\n\tsummary: string;\n}\n\n/** Detect the technology stack in a project directory */\nexport function detectStack(cwd: string): StackDetectionResult {\n\tconst frameworks: DetectedFramework[] = [];\n\n\t// Parse composer.json for PHP/Laravel dependencies\n\tconst composerPath = join(cwd, \"composer.json\");\n\tif (existsSync(composerPath)) {\n\t\ttry {\n\t\t\tconst composer = JSON.parse(readFileSync(composerPath, \"utf-8\"));\n\t\t\tconst deps = { ...composer.require, ...composer[\"require-dev\"] };\n\n\t\t\tif (deps[\"laravel/framework\"]) {\n\t\t\t\tframeworks.push({ name: \"Laravel\", version: extractVersion(deps[\"laravel/framework\"]) });\n\t\t\t}\n\t\t\tif (deps[\"livewire/livewire\"]) {\n\t\t\t\tframeworks.push({ name: \"Livewire\", version: extractVersion(deps[\"livewire/livewire\"]) });\n\t\t\t}\n\t\t\tif (deps[\"livewire/flux\"]) {\n\t\t\t\tframeworks.push({ name: \"Flux UI\", version: extractVersion(deps[\"livewire/flux\"]) });\n\t\t\t}\n\t\t\tif (deps[\"inertiajs/inertia-laravel\"]) {\n\t\t\t\tframeworks.push({ name: \"Inertia\", version: extractVersion(deps[\"inertiajs/inertia-laravel\"]) });\n\t\t\t}\n\t\t\tif (deps[\"laravel/reverb\"]) {\n\t\t\t\tframeworks.push({ name: \"Reverb\", version: extractVersion(deps[\"laravel/reverb\"]) });\n\t\t\t}\n\t\t\tif (deps[\"laravel/sanctum\"]) {\n\t\t\t\tframeworks.push({ name: \"Sanctum\", version: extractVersion(deps[\"laravel/sanctum\"]) });\n\t\t\t}\n\t\t\tif (deps[\"filament/filament\"]) {\n\t\t\t\tframeworks.push({ name: \"Filament\", version: extractVersion(deps[\"filament/filament\"]) });\n\t\t\t}\n\t\t\tif (deps[\"laravel/ai\"]) {\n\t\t\t\tframeworks.push({ name: \"Laravel AI SDK\", version: extractVersion(deps[\"laravel/ai\"]) });\n\t\t\t}\n\t\t} catch {\n\t\t\t// Ignore malformed composer.json\n\t\t}\n\t}\n\n\t// Parse package.json for JS/frontend dependencies\n\tconst packagePath = join(cwd, \"package.json\");\n\tif (existsSync(packagePath)) {\n\t\ttry {\n\t\t\tconst pkg = JSON.parse(readFileSync(packagePath, \"utf-8\"));\n\t\t\tconst deps = { ...pkg.dependencies, ...pkg.devDependencies };\n\n\t\t\tif (deps.vue) {\n\t\t\t\tframeworks.push({ name: \"Vue\", version: extractVersion(deps.vue) });\n\t\t\t}\n\t\t\tif (deps.alpinejs) {\n\t\t\t\tframeworks.push({ name: \"Alpine.js\", version: extractVersion(deps.alpinejs) });\n\t\t\t}\n\t\t\tif (deps.tailwindcss) {\n\t\t\t\tframeworks.push({ name: \"Tailwind CSS\", version: extractVersion(deps.tailwindcss) });\n\t\t\t}\n\t\t\tif (\n\t\t\t\tdeps[\"@inertiajs/vue3\"] ||\n\t\t\t\tdeps[\"@inertiajs/vue2\"] ||\n\t\t\t\tdeps[\"@inertiajs/react\"] ||\n\t\t\t\tdeps[\"@inertiajs/svelte\"]\n\t\t\t) {\n\t\t\t\t// Inertia frontend adapter -- version from whichever is present\n\t\t\t\tconst inertiaFe =\n\t\t\t\t\tdeps[\"@inertiajs/vue3\"] ||\n\t\t\t\t\tdeps[\"@inertiajs/vue2\"] ||\n\t\t\t\t\tdeps[\"@inertiajs/react\"] ||\n\t\t\t\t\tdeps[\"@inertiajs/svelte\"];\n\t\t\t\tif (!frameworks.some((f) => f.name === \"Inertia\")) {\n\t\t\t\t\tframeworks.push({ name: \"Inertia\", version: extractVersion(inertiaFe) });\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (deps.react || deps[\"react-dom\"]) {\n\t\t\t\tframeworks.push({ name: \"React\", version: extractVersion(deps.react || deps[\"react-dom\"]) });\n\t\t\t}\n\t\t\tif (deps.svelte) {\n\t\t\t\tframeworks.push({ name: \"Svelte\", version: extractVersion(deps.svelte) });\n\t\t\t}\n\t\t\tif (deps.typescript) {\n\t\t\t\tframeworks.push({ name: \"TypeScript\", version: extractVersion(deps.typescript) });\n\t\t\t}\n\t\t\tif (deps.vite) {\n\t\t\t\tframeworks.push({ name: \"Vite\", version: extractVersion(deps.vite) });\n\t\t\t}\n\t\t} catch {\n\t\t\t// Ignore malformed package.json\n\t\t}\n\t}\n\n\tif (frameworks.length === 0) {\n\t\treturn { frameworks, summary: \"\" };\n\t}\n\n\t// Detect known stack profiles\n\tconst has = (name: string) => frameworks.some((f) => f.name === name);\n\tlet stack: KnownStack | undefined;\n\n\tif (has(\"Laravel\") && has(\"Tailwind CSS\") && has(\"Alpine.js\") && has(\"Livewire\")) {\n\t\tstack = \"TALL\";\n\t} else if (has(\"Laravel\") && has(\"Tailwind CSS\") && has(\"Inertia\") && has(\"React\")) {\n\t\tstack = \"RILT\";\n\t} else if (has(\"Laravel\") && has(\"Tailwind CSS\") && has(\"Inertia\") && has(\"Vue\")) {\n\t\tstack = \"VILT\";\n\t} else if (has(\"Laravel\") && has(\"Tailwind CSS\") && has(\"Inertia\") && has(\"Svelte\")) {\n\t\tstack = \"SILT\";\n\t}\n\n\t// Build human-readable summary\n\tconst frameworkList = frameworks.map((f) => (f.version ? `${f.name} ${f.version}` : f.name)).join(\", \");\n\tlet summary = `Detected frameworks: ${frameworkList}`;\n\tif (stack === \"TALL\") {\n\t\tconst hasFlux = has(\"Flux UI\");\n\t\tsummary = `TALL stack project (Tailwind, Alpine.js, Laravel, Livewire${hasFlux ? \", Flux UI\" : \"\"}).\\n${frameworkList}`;\n\t} else if (stack === \"RILT\") {\n\t\tsummary = `RILT stack project (React, Inertia, Laravel, Tailwind).\\n${frameworkList}`;\n\t} else if (stack === \"VILT\") {\n\t\tsummary = `VILT stack project (Vue, Inertia, Laravel, Tailwind).\\n${frameworkList}`;\n\t} else if (stack === \"SILT\") {\n\t\tsummary = `SILT stack project (Svelte, Inertia, Laravel, Tailwind).\\n${frameworkList}`;\n\t}\n\n\treturn { frameworks, stack, summary };\n}\n\n/** Strip semver constraint prefixes (^, ~, >=, etc.) to get a clean version */\nfunction extractVersion(constraint: string | undefined): string | undefined {\n\tif (!constraint) return undefined;\n\tconst match = constraint.match(/(\\d+\\.\\d+(?:\\.\\d+)?)/);\n\treturn match?.[1];\n}\n\n/** Get the suggested package name for a detected stack */\nexport function getSuggestedPackage(stack: KnownStack): string {\n\tswitch (stack) {\n\t\tcase \"TALL\":\n\t\t\treturn \"@elyracode/stack-tall\";\n\t\tcase \"RILT\":\n\t\t\treturn \"@elyracode/stack-rilt\";\n\t\tcase \"VILT\":\n\t\t\treturn \"@elyracode/stack-vilt\";\n\t\tcase \"SILT\":\n\t\t\treturn \"@elyracode/stack-silt\";\n\t}\n}\n"]}
1
+ {"version":3,"file":"stack-detector.js","sourceRoot":"","sources":["../../src/core/stack-detector.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAqBjC,yDAAyD;AACzD,MAAM,UAAU,WAAW,CAAC,GAAW;IACtC,MAAM,UAAU,GAAwB,EAAE,CAAC;IAE3C,mDAAmD;IACnD,MAAM,YAAY,GAAG,IAAI,CAAC,GAAG,EAAE,eAAe,CAAC,CAAC;IAChD,IAAI,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;QAC9B,IAAI,CAAC;YACJ,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC,CAAC;YACjE,MAAM,IAAI,GAAG,EAAE,GAAG,QAAQ,CAAC,OAAO,EAAE,GAAG,QAAQ,CAAC,aAAa,CAAC,EAAE,CAAC;YAEjE,IAAI,IAAI,CAAC,mBAAmB,CAAC,EAAE,CAAC;gBAC/B,UAAU,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,cAAc,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC,EAAE,CAAC,CAAC;YAC1F,CAAC;YACD,IAAI,IAAI,CAAC,mBAAmB,CAAC,EAAE,CAAC;gBAC/B,UAAU,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,OAAO,EAAE,cAAc,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC,EAAE,CAAC,CAAC;YAC3F,CAAC;YACD,IAAI,IAAI,CAAC,eAAe,CAAC,EAAE,CAAC;gBAC3B,UAAU,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,cAAc,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC,EAAE,CAAC,CAAC;YACtF,CAAC;YACD,IAAI,IAAI,CAAC,2BAA2B,CAAC,EAAE,CAAC;gBACvC,UAAU,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,cAAc,CAAC,IAAI,CAAC,2BAA2B,CAAC,CAAC,EAAE,CAAC,CAAC;YAClG,CAAC;YACD,IAAI,IAAI,CAAC,gBAAgB,CAAC,EAAE,CAAC;gBAC5B,UAAU,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,cAAc,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC,EAAE,CAAC,CAAC;YACtF,CAAC;YACD,IAAI,IAAI,CAAC,iBAAiB,CAAC,EAAE,CAAC;gBAC7B,UAAU,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,cAAc,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC,EAAE,CAAC,CAAC;YACxF,CAAC;YACD,IAAI,IAAI,CAAC,mBAAmB,CAAC,EAAE,CAAC;gBAC/B,UAAU,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,OAAO,EAAE,cAAc,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC,EAAE,CAAC,CAAC;YAC3F,CAAC;YACD,IAAI,IAAI,CAAC,YAAY,CAAC,EAAE,CAAC;gBACxB,UAAU,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,gBAAgB,EAAE,OAAO,EAAE,cAAc,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,EAAE,CAAC,CAAC;YAC1F,CAAC;QACF,CAAC;QAAC,MAAM,CAAC;YACR,iCAAiC;QAClC,CAAC;IACF,CAAC;IAED,kDAAkD;IAClD,MAAM,WAAW,GAAG,IAAI,CAAC,GAAG,EAAE,cAAc,CAAC,CAAC;IAC9C,IAAI,UAAU,CAAC,WAAW,CAAC,EAAE,CAAC;QAC7B,IAAI,CAAC;YACJ,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC,CAAC;YAC3D,MAAM,IAAI,GAAG,EAAE,GAAG,GAAG,CAAC,YAAY,EAAE,GAAG,GAAG,CAAC,eAAe,EAAE,CAAC;YAE7D,IAAI,IAAI,CAAC,GAAG,EAAE,CAAC;gBACd,UAAU,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,cAAc,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YACrE,CAAC;YACD,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;gBACnB,UAAU,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,cAAc,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;YAChF,CAAC;YACD,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;gBACtB,UAAU,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,cAAc,EAAE,OAAO,EAAE,cAAc,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC;YACtF,CAAC;YACD,IACC,IAAI,CAAC,iBAAiB,CAAC;gBACvB,IAAI,CAAC,iBAAiB,CAAC;gBACvB,IAAI,CAAC,kBAAkB,CAAC;gBACxB,IAAI,CAAC,mBAAmB,CAAC,EACxB,CAAC;gBACF,gEAAgE;gBAChE,MAAM,SAAS,GACd,IAAI,CAAC,iBAAiB,CAAC;oBACvB,IAAI,CAAC,iBAAiB,CAAC;oBACvB,IAAI,CAAC,kBAAkB,CAAC;oBACxB,IAAI,CAAC,mBAAmB,CAAC,CAAC;gBAC3B,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,SAAS,CAAC,EAAE,CAAC;oBACnD,UAAU,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,cAAc,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;gBAC1E,CAAC;YACF,CAAC;YACD,IAAI,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,WAAW,CAAC,EAAE,CAAC;gBACrC,UAAU,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,cAAc,CAAC,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,WAAW,CAAC,CAAC,EAAE,CAAC,CAAC;YAC9F,CAAC;YACD,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;gBACjB,UAAU,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,cAAc,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;YAC3E,CAAC;YACD,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;gBACrB,UAAU,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,YAAY,EAAE,OAAO,EAAE,cAAc,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;YACnF,CAAC;YACD,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;gBACf,UAAU,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YACvE,CAAC;QACF,CAAC;QAAC,MAAM,CAAC;YACR,gCAAgC;QACjC,CAAC;IACF,CAAC;IAED,8EAA8E;IAC9E,4EAA4E;IAC5E,6EAA6E;IAC7E,wEAAwE;IACxE,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,YAAY,CAAC,CAAC;IAC1C,IAAI,UAAU,CAAC,IAAI,CAAC,GAAG,EAAE,YAAY,CAAC,CAAC,IAAI,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;QAClE,IAAI,CAAC;YACJ,MAAM,SAAS,GAAG,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;YAChF,MAAM,aAAa,GAAG,gBAAgB,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,yBAAyB,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;YACpG,IAAI,UAAU,CAAC,IAAI,CAAC,GAAG,EAAE,YAAY,CAAC,CAAC,IAAI,aAAa,EAAE,CAAC;gBAC1D,MAAM,YAAY,GAAG,SAAS,CAAC,KAAK,CAAC,iDAAiD,CAAC,CAAC;gBACxF,UAAU,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,iBAAiB,EAAE,OAAO,EAAE,YAAY,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;YAC1E,CAAC;QACF,CAAC;QAAC,MAAM,CAAC;YACR,+BAA+B;QAChC,CAAC;IACF,CAAC;IAED,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC7B,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC;IACpC,CAAC;IAED,8BAA8B;IAC9B,MAAM,GAAG,GAAG,CAAC,IAAY,EAAE,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC;IACtE,IAAI,KAA6B,CAAC;IAElC,IAAI,GAAG,CAAC,iBAAiB,CAAC,EAAE,CAAC;QAC5B,KAAK,GAAG,iBAAiB,CAAC;IAC3B,CAAC;SAAM,IAAI,GAAG,CAAC,SAAS,CAAC,IAAI,GAAG,CAAC,cAAc,CAAC,IAAI,GAAG,CAAC,WAAW,CAAC,IAAI,GAAG,CAAC,UAAU,CAAC,EAAE,CAAC;QACzF,KAAK,GAAG,MAAM,CAAC;IAChB,CAAC;SAAM,IAAI,GAAG,CAAC,SAAS,CAAC,IAAI,GAAG,CAAC,cAAc,CAAC,IAAI,GAAG,CAAC,SAAS,CAAC,IAAI,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC;QACpF,KAAK,GAAG,MAAM,CAAC;IAChB,CAAC;SAAM,IAAI,GAAG,CAAC,SAAS,CAAC,IAAI,GAAG,CAAC,cAAc,CAAC,IAAI,GAAG,CAAC,SAAS,CAAC,IAAI,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;QAClF,KAAK,GAAG,MAAM,CAAC;IAChB,CAAC;SAAM,IAAI,GAAG,CAAC,SAAS,CAAC,IAAI,GAAG,CAAC,cAAc,CAAC,IAAI,GAAG,CAAC,SAAS,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;QACrF,KAAK,GAAG,MAAM,CAAC;IAChB,CAAC;IAED,+BAA+B;IAC/B,MAAM,aAAa,GAAG,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACxG,IAAI,OAAO,GAAG,wBAAwB,aAAa,EAAE,CAAC;IACtD,IAAI,KAAK,KAAK,MAAM,EAAE,CAAC;QACtB,MAAM,OAAO,GAAG,GAAG,CAAC,SAAS,CAAC,CAAC;QAC/B,OAAO,GAAG,6DAA6D,OAAO,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,OAAO,aAAa,EAAE,CAAC;IACzH,CAAC;SAAM,IAAI,KAAK,KAAK,MAAM,EAAE,CAAC;QAC7B,OAAO,GAAG,4DAA4D,aAAa,EAAE,CAAC;IACvF,CAAC;SAAM,IAAI,KAAK,KAAK,MAAM,EAAE,CAAC;QAC7B,OAAO,GAAG,0DAA0D,aAAa,EAAE,CAAC;IACrF,CAAC;SAAM,IAAI,KAAK,KAAK,MAAM,EAAE,CAAC;QAC7B,OAAO,GAAG,6DAA6D,aAAa,EAAE,CAAC;IACxF,CAAC;SAAM,IAAI,KAAK,KAAK,iBAAiB,EAAE,CAAC;QACxC,OAAO,GAAG,wFAAwF,aAAa,EAAE,CAAC;IACnH,CAAC;IAED,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC;AACvC,CAAC;AAED,+EAA+E;AAC/E,SAAS,cAAc,CAAC,UAA8B;IACrD,IAAI,CAAC,UAAU;QAAE,OAAO,SAAS,CAAC;IAClC,MAAM,KAAK,GAAG,UAAU,CAAC,KAAK,CAAC,sBAAsB,CAAC,CAAC;IACvD,OAAO,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC;AACnB,CAAC;AAED,0DAA0D;AAC1D,MAAM,UAAU,mBAAmB,CAAC,KAAiB;IACpD,QAAQ,KAAK,EAAE,CAAC;QACf,KAAK,MAAM;YACV,OAAO,uBAAuB,CAAC;QAChC,KAAK,MAAM;YACV,OAAO,uBAAuB,CAAC;QAChC,KAAK,MAAM;YACV,OAAO,uBAAuB,CAAC;QAChC,KAAK,MAAM;YACV,OAAO,uBAAuB,CAAC;QAChC,KAAK,iBAAiB;YACrB,OAAO,kCAAkC,CAAC;IAC5C,CAAC;AACF,CAAC","sourcesContent":["import { existsSync, readFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\n\n/** Individual framework detected in the project */\nexport interface DetectedFramework {\n\tname: string;\n\tversion?: string;\n}\n\n/** Known stack profiles that can be suggested for installation */\nexport type KnownStack = \"TALL\" | \"RILT\" | \"VILT\" | \"SILT\" | \"ELYRA_FRAMEWORK\";\n\n/** Result of stack detection */\nexport interface StackDetectionResult {\n\t/** All detected frameworks */\n\tframeworks: DetectedFramework[];\n\t/** Recognized stack profile (if frameworks match a known combination) */\n\tstack?: KnownStack;\n\t/** Human-readable summary for system prompt injection */\n\tsummary: string;\n}\n\n/** Detect the technology stack in a project directory */\nexport function detectStack(cwd: string): StackDetectionResult {\n\tconst frameworks: DetectedFramework[] = [];\n\n\t// Parse composer.json for PHP/Laravel dependencies\n\tconst composerPath = join(cwd, \"composer.json\");\n\tif (existsSync(composerPath)) {\n\t\ttry {\n\t\t\tconst composer = JSON.parse(readFileSync(composerPath, \"utf-8\"));\n\t\t\tconst deps = { ...composer.require, ...composer[\"require-dev\"] };\n\n\t\t\tif (deps[\"laravel/framework\"]) {\n\t\t\t\tframeworks.push({ name: \"Laravel\", version: extractVersion(deps[\"laravel/framework\"]) });\n\t\t\t}\n\t\t\tif (deps[\"livewire/livewire\"]) {\n\t\t\t\tframeworks.push({ name: \"Livewire\", version: extractVersion(deps[\"livewire/livewire\"]) });\n\t\t\t}\n\t\t\tif (deps[\"livewire/flux\"]) {\n\t\t\t\tframeworks.push({ name: \"Flux UI\", version: extractVersion(deps[\"livewire/flux\"]) });\n\t\t\t}\n\t\t\tif (deps[\"inertiajs/inertia-laravel\"]) {\n\t\t\t\tframeworks.push({ name: \"Inertia\", version: extractVersion(deps[\"inertiajs/inertia-laravel\"]) });\n\t\t\t}\n\t\t\tif (deps[\"laravel/reverb\"]) {\n\t\t\t\tframeworks.push({ name: \"Reverb\", version: extractVersion(deps[\"laravel/reverb\"]) });\n\t\t\t}\n\t\t\tif (deps[\"laravel/sanctum\"]) {\n\t\t\t\tframeworks.push({ name: \"Sanctum\", version: extractVersion(deps[\"laravel/sanctum\"]) });\n\t\t\t}\n\t\t\tif (deps[\"filament/filament\"]) {\n\t\t\t\tframeworks.push({ name: \"Filament\", version: extractVersion(deps[\"filament/filament\"]) });\n\t\t\t}\n\t\t\tif (deps[\"laravel/ai\"]) {\n\t\t\t\tframeworks.push({ name: \"Laravel AI SDK\", version: extractVersion(deps[\"laravel/ai\"]) });\n\t\t\t}\n\t\t} catch {\n\t\t\t// Ignore malformed composer.json\n\t\t}\n\t}\n\n\t// Parse package.json for JS/frontend dependencies\n\tconst packagePath = join(cwd, \"package.json\");\n\tif (existsSync(packagePath)) {\n\t\ttry {\n\t\t\tconst pkg = JSON.parse(readFileSync(packagePath, \"utf-8\"));\n\t\t\tconst deps = { ...pkg.dependencies, ...pkg.devDependencies };\n\n\t\t\tif (deps.vue) {\n\t\t\t\tframeworks.push({ name: \"Vue\", version: extractVersion(deps.vue) });\n\t\t\t}\n\t\t\tif (deps.alpinejs) {\n\t\t\t\tframeworks.push({ name: \"Alpine.js\", version: extractVersion(deps.alpinejs) });\n\t\t\t}\n\t\t\tif (deps.tailwindcss) {\n\t\t\t\tframeworks.push({ name: \"Tailwind CSS\", version: extractVersion(deps.tailwindcss) });\n\t\t\t}\n\t\t\tif (\n\t\t\t\tdeps[\"@inertiajs/vue3\"] ||\n\t\t\t\tdeps[\"@inertiajs/vue2\"] ||\n\t\t\t\tdeps[\"@inertiajs/react\"] ||\n\t\t\t\tdeps[\"@inertiajs/svelte\"]\n\t\t\t) {\n\t\t\t\t// Inertia frontend adapter -- version from whichever is present\n\t\t\t\tconst inertiaFe =\n\t\t\t\t\tdeps[\"@inertiajs/vue3\"] ||\n\t\t\t\t\tdeps[\"@inertiajs/vue2\"] ||\n\t\t\t\t\tdeps[\"@inertiajs/react\"] ||\n\t\t\t\t\tdeps[\"@inertiajs/svelte\"];\n\t\t\t\tif (!frameworks.some((f) => f.name === \"Inertia\")) {\n\t\t\t\t\tframeworks.push({ name: \"Inertia\", version: extractVersion(inertiaFe) });\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (deps.react || deps[\"react-dom\"]) {\n\t\t\t\tframeworks.push({ name: \"React\", version: extractVersion(deps.react || deps[\"react-dom\"]) });\n\t\t\t}\n\t\t\tif (deps.svelte) {\n\t\t\t\tframeworks.push({ name: \"Svelte\", version: extractVersion(deps.svelte) });\n\t\t\t}\n\t\t\tif (deps.typescript) {\n\t\t\t\tframeworks.push({ name: \"TypeScript\", version: extractVersion(deps.typescript) });\n\t\t\t}\n\t\t\tif (deps.vite) {\n\t\t\t\tframeworks.push({ name: \"Vite\", version: extractVersion(deps.vite) });\n\t\t\t}\n\t\t} catch {\n\t\t\t// Ignore malformed package.json\n\t\t}\n\t}\n\n\t// Detect Elyra Framework (Rust + Svelte 5 desktop apps). `rata new` scaffolds\n\t// an `elyra.toml` config file, which is the most reliable signal; fall back\n\t// to a plain-text check for the `elyra` crate dependency in Cargo.toml (TOML\n\t// isn't parsed here to avoid adding a parser dependency for one field).\n\tconst cargoPath = join(cwd, \"Cargo.toml\");\n\tif (existsSync(join(cwd, \"elyra.toml\")) || existsSync(cargoPath)) {\n\t\ttry {\n\t\t\tconst cargoText = existsSync(cargoPath) ? readFileSync(cargoPath, \"utf-8\") : \"\";\n\t\t\tconst hasElyraCrate = /^\\s*elyra\\s*=/m.test(cargoText) || /\\[dependencies\\.elyra\\]/.test(cargoText);\n\t\t\tif (existsSync(join(cwd, \"elyra.toml\")) || hasElyraCrate) {\n\t\t\t\tconst versionMatch = cargoText.match(/^\\s*elyra\\s*=\\s*\\{[^}]*version\\s*=\\s*\"([^\"]+)\"/m);\n\t\t\t\tframeworks.push({ name: \"Elyra Framework\", version: versionMatch?.[1] });\n\t\t\t}\n\t\t} catch {\n\t\t\t// Ignore unreadable Cargo.toml\n\t\t}\n\t}\n\n\tif (frameworks.length === 0) {\n\t\treturn { frameworks, summary: \"\" };\n\t}\n\n\t// Detect known stack profiles\n\tconst has = (name: string) => frameworks.some((f) => f.name === name);\n\tlet stack: KnownStack | undefined;\n\n\tif (has(\"Elyra Framework\")) {\n\t\tstack = \"ELYRA_FRAMEWORK\";\n\t} else if (has(\"Laravel\") && has(\"Tailwind CSS\") && has(\"Alpine.js\") && has(\"Livewire\")) {\n\t\tstack = \"TALL\";\n\t} else if (has(\"Laravel\") && has(\"Tailwind CSS\") && has(\"Inertia\") && has(\"React\")) {\n\t\tstack = \"RILT\";\n\t} else if (has(\"Laravel\") && has(\"Tailwind CSS\") && has(\"Inertia\") && has(\"Vue\")) {\n\t\tstack = \"VILT\";\n\t} else if (has(\"Laravel\") && has(\"Tailwind CSS\") && has(\"Inertia\") && has(\"Svelte\")) {\n\t\tstack = \"SILT\";\n\t}\n\n\t// Build human-readable summary\n\tconst frameworkList = frameworks.map((f) => (f.version ? `${f.name} ${f.version}` : f.name)).join(\", \");\n\tlet summary = `Detected frameworks: ${frameworkList}`;\n\tif (stack === \"TALL\") {\n\t\tconst hasFlux = has(\"Flux UI\");\n\t\tsummary = `TALL stack project (Tailwind, Alpine.js, Laravel, Livewire${hasFlux ? \", Flux UI\" : \"\"}).\\n${frameworkList}`;\n\t} else if (stack === \"RILT\") {\n\t\tsummary = `RILT stack project (React, Inertia, Laravel, Tailwind).\\n${frameworkList}`;\n\t} else if (stack === \"VILT\") {\n\t\tsummary = `VILT stack project (Vue, Inertia, Laravel, Tailwind).\\n${frameworkList}`;\n\t} else if (stack === \"SILT\") {\n\t\tsummary = `SILT stack project (Svelte, Inertia, Laravel, Tailwind).\\n${frameworkList}`;\n\t} else if (stack === \"ELYRA_FRAMEWORK\") {\n\t\tsummary = `Elyra Framework project (Rust + Svelte 5 desktop app, Laravel-inspired ergonomics).\\n${frameworkList}`;\n\t}\n\n\treturn { frameworks, stack, summary };\n}\n\n/** Strip semver constraint prefixes (^, ~, >=, etc.) to get a clean version */\nfunction extractVersion(constraint: string | undefined): string | undefined {\n\tif (!constraint) return undefined;\n\tconst match = constraint.match(/(\\d+\\.\\d+(?:\\.\\d+)?)/);\n\treturn match?.[1];\n}\n\n/** Get the suggested package name for a detected stack */\nexport function getSuggestedPackage(stack: KnownStack): string {\n\tswitch (stack) {\n\t\tcase \"TALL\":\n\t\t\treturn \"@elyracode/stack-tall\";\n\t\tcase \"RILT\":\n\t\t\treturn \"@elyracode/stack-rilt\";\n\t\tcase \"VILT\":\n\t\t\treturn \"@elyracode/stack-vilt\";\n\t\tcase \"SILT\":\n\t\t\treturn \"@elyracode/stack-silt\";\n\t\tcase \"ELYRA_FRAMEWORK\":\n\t\t\treturn \"@elyracode/stack-elyra-framework\";\n\t}\n}\n"]}
@@ -17,6 +17,7 @@ export { keyHint, keyText, rawKeyHint } from "./keybinding-hints.js";
17
17
  export { LoginDialogComponent } from "./login-dialog.js";
18
18
  export { ModelSelectorComponent } from "./model-selector.js";
19
19
  export { OAuthSelectorComponent } from "./oauth-selector.js";
20
+ export { PackageBrowserComponent, type PackageBrowserItem } from "./package-browser.js";
20
21
  export { type RewindPoint, RewindSelectorComponent } from "./rewind-selector.js";
21
22
  export { type ModelsCallbacks, type ModelsConfig, ScopedModelsSelectorComponent } from "./scoped-models-selector.js";
22
23
  export { SessionSelectorComponent } from "./session-selector.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/modes/interactive/components/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAC5C,OAAO,EAAE,yBAAyB,EAAE,MAAM,wBAAwB,CAAC;AACnE,OAAO,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AAC7D,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,6BAA6B,EAAE,MAAM,6BAA6B,CAAC;AAC5E,OAAO,EAAE,iCAAiC,EAAE,MAAM,iCAAiC,CAAC;AACpF,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AAC7D,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,EAAE,KAAK,iBAAiB,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAC/D,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,wBAAwB,EAAE,MAAM,uBAAuB,CAAC;AACjE,OAAO,EAAE,uBAAuB,EAAE,MAAM,sBAAsB,CAAC;AAC/D,OAAO,EAAE,0BAA0B,EAAE,MAAM,yBAAyB,CAAC;AACrE,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AACrE,OAAO,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AACzD,OAAO,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AAC7D,OAAO,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AAC7D,OAAO,EAAE,KAAK,WAAW,EAAE,uBAAuB,EAAE,MAAM,sBAAsB,CAAC;AACjF,OAAO,EAAE,KAAK,eAAe,EAAE,KAAK,YAAY,EAAE,6BAA6B,EAAE,MAAM,6BAA6B,CAAC;AACrH,OAAO,EAAE,wBAAwB,EAAE,MAAM,uBAAuB,CAAC;AACjE,OAAO,EAAE,KAAK,iBAAiB,EAAE,KAAK,cAAc,EAAE,yBAAyB,EAAE,MAAM,wBAAwB,CAAC;AAChH,OAAO,EAAE,2BAA2B,EAAE,MAAM,2BAA2B,CAAC;AACxE,OAAO,EAAE,+BAA+B,EAAE,MAAM,+BAA+B,CAAC;AAChF,OAAO,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AAC7D,OAAO,EAAE,yBAAyB,EAAE,MAAM,wBAAwB,CAAC;AACnE,OAAO,EAAE,sBAAsB,EAAE,KAAK,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AACxF,OAAO,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAC3D,OAAO,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AACzD,OAAO,EAAE,4BAA4B,EAAE,MAAM,4BAA4B,CAAC;AAC1E,OAAO,EAAE,qBAAqB,EAAE,KAAK,oBAAoB,EAAE,MAAM,sBAAsB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/modes/interactive/components/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAC5C,OAAO,EAAE,yBAAyB,EAAE,MAAM,wBAAwB,CAAC;AACnE,OAAO,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AAC7D,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,6BAA6B,EAAE,MAAM,6BAA6B,CAAC;AAC5E,OAAO,EAAE,iCAAiC,EAAE,MAAM,iCAAiC,CAAC;AACpF,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AAC7D,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,EAAE,KAAK,iBAAiB,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAC/D,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,wBAAwB,EAAE,MAAM,uBAAuB,CAAC;AACjE,OAAO,EAAE,uBAAuB,EAAE,MAAM,sBAAsB,CAAC;AAC/D,OAAO,EAAE,0BAA0B,EAAE,MAAM,yBAAyB,CAAC;AACrE,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AACrE,OAAO,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AACzD,OAAO,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AAC7D,OAAO,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AAC7D,OAAO,EAAE,uBAAuB,EAAE,KAAK,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AACxF,OAAO,EAAE,KAAK,WAAW,EAAE,uBAAuB,EAAE,MAAM,sBAAsB,CAAC;AACjF,OAAO,EAAE,KAAK,eAAe,EAAE,KAAK,YAAY,EAAE,6BAA6B,EAAE,MAAM,6BAA6B,CAAC;AACrH,OAAO,EAAE,wBAAwB,EAAE,MAAM,uBAAuB,CAAC;AACjE,OAAO,EAAE,KAAK,iBAAiB,EAAE,KAAK,cAAc,EAAE,yBAAyB,EAAE,MAAM,wBAAwB,CAAC;AAChH,OAAO,EAAE,2BAA2B,EAAE,MAAM,2BAA2B,CAAC;AACxE,OAAO,EAAE,+BAA+B,EAAE,MAAM,+BAA+B,CAAC;AAChF,OAAO,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AAC7D,OAAO,EAAE,yBAAyB,EAAE,MAAM,wBAAwB,CAAC;AACnE,OAAO,EAAE,sBAAsB,EAAE,KAAK,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AACxF,OAAO,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAC3D,OAAO,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AACzD,OAAO,EAAE,4BAA4B,EAAE,MAAM,4BAA4B,CAAC;AAC1E,OAAO,EAAE,qBAAqB,EAAE,KAAK,oBAAoB,EAAE,MAAM,sBAAsB,CAAC"}
@@ -18,6 +18,7 @@ export { keyHint, keyText, rawKeyHint } from "./keybinding-hints.js";
18
18
  export { LoginDialogComponent } from "./login-dialog.js";
19
19
  export { ModelSelectorComponent } from "./model-selector.js";
20
20
  export { OAuthSelectorComponent } from "./oauth-selector.js";
21
+ export { PackageBrowserComponent } from "./package-browser.js";
21
22
  export { RewindSelectorComponent } from "./rewind-selector.js";
22
23
  export { ScopedModelsSelectorComponent } from "./scoped-models-selector.js";
23
24
  export { SessionSelectorComponent } from "./session-selector.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/modes/interactive/components/index.ts"],"names":[],"mappings":"AAAA,+BAA+B;AAC/B,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAC5C,OAAO,EAAE,yBAAyB,EAAE,MAAM,wBAAwB,CAAC;AACnE,OAAO,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AAC7D,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,6BAA6B,EAAE,MAAM,6BAA6B,CAAC;AAC5E,OAAO,EAAE,iCAAiC,EAAE,MAAM,iCAAiC,CAAC;AACpF,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AAC7D,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,EAA0B,UAAU,EAAE,MAAM,WAAW,CAAC;AAC/D,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,wBAAwB,EAAE,MAAM,uBAAuB,CAAC;AACjE,OAAO,EAAE,uBAAuB,EAAE,MAAM,sBAAsB,CAAC;AAC/D,OAAO,EAAE,0BAA0B,EAAE,MAAM,yBAAyB,CAAC;AACrE,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AACrE,OAAO,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AACzD,OAAO,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AAC7D,OAAO,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AAC7D,OAAO,EAAoB,uBAAuB,EAAE,MAAM,sBAAsB,CAAC;AACjF,OAAO,EAA2C,6BAA6B,EAAE,MAAM,6BAA6B,CAAC;AACrH,OAAO,EAAE,wBAAwB,EAAE,MAAM,uBAAuB,CAAC;AACjE,OAAO,EAA+C,yBAAyB,EAAE,MAAM,wBAAwB,CAAC;AAChH,OAAO,EAAE,2BAA2B,EAAE,MAAM,2BAA2B,CAAC;AACxE,OAAO,EAAE,+BAA+B,EAAE,MAAM,+BAA+B,CAAC;AAChF,OAAO,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AAC7D,OAAO,EAAE,yBAAyB,EAAE,MAAM,wBAAwB,CAAC;AACnE,OAAO,EAAE,sBAAsB,EAA6B,MAAM,qBAAqB,CAAC;AACxF,OAAO,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAC3D,OAAO,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AACzD,OAAO,EAAE,4BAA4B,EAAE,MAAM,4BAA4B,CAAC;AAC1E,OAAO,EAAE,qBAAqB,EAA6B,MAAM,sBAAsB,CAAC","sourcesContent":["// UI Components for extensions\nexport { ArminComponent } from \"./armin.js\";\nexport { AssistantMessageComponent } from \"./assistant-message.js\";\nexport { BashExecutionComponent } from \"./bash-execution.js\";\nexport { BorderedLoader } from \"./bordered-loader.js\";\nexport { BranchSummaryMessageComponent } from \"./branch-summary-message.js\";\nexport { CompactionSummaryMessageComponent } from \"./compaction-summary-message.js\";\nexport { CustomEditor } from \"./custom-editor.js\";\nexport { CustomMessageComponent } from \"./custom-message.js\";\nexport { DaxnutsComponent } from \"./daxnuts.js\";\nexport { type RenderDiffOptions, renderDiff } from \"./diff.js\";\nexport { DynamicBorder } from \"./dynamic-border.js\";\nexport { ExtensionEditorComponent } from \"./extension-editor.js\";\nexport { ExtensionInputComponent } from \"./extension-input.js\";\nexport { ExtensionSelectorComponent } from \"./extension-selector.js\";\nexport { FooterComponent } from \"./footer.js\";\nexport { keyHint, keyText, rawKeyHint } from \"./keybinding-hints.js\";\nexport { LoginDialogComponent } from \"./login-dialog.js\";\nexport { ModelSelectorComponent } from \"./model-selector.js\";\nexport { OAuthSelectorComponent } from \"./oauth-selector.js\";\nexport { type RewindPoint, RewindSelectorComponent } from \"./rewind-selector.js\";\nexport { type ModelsCallbacks, type ModelsConfig, ScopedModelsSelectorComponent } from \"./scoped-models-selector.js\";\nexport { SessionSelectorComponent } from \"./session-selector.js\";\nexport { type SettingsCallbacks, type SettingsConfig, SettingsSelectorComponent } from \"./settings-selector.js\";\nexport { ShowImagesSelectorComponent } from \"./show-images-selector.js\";\nexport { SkillInvocationMessageComponent } from \"./skill-invocation-message.js\";\nexport { ThemeSelectorComponent } from \"./theme-selector.js\";\nexport { ThinkingSelectorComponent } from \"./thinking-selector.js\";\nexport { ToolExecutionComponent, type ToolExecutionOptions } from \"./tool-execution.js\";\nexport { TreeSelectorComponent } from \"./tree-selector.js\";\nexport { UserMessageComponent } from \"./user-message.js\";\nexport { UserMessageSelectorComponent } from \"./user-message-selector.js\";\nexport { truncateToVisualLines, type VisualTruncateResult } from \"./visual-truncate.js\";\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/modes/interactive/components/index.ts"],"names":[],"mappings":"AAAA,+BAA+B;AAC/B,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAC5C,OAAO,EAAE,yBAAyB,EAAE,MAAM,wBAAwB,CAAC;AACnE,OAAO,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AAC7D,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,6BAA6B,EAAE,MAAM,6BAA6B,CAAC;AAC5E,OAAO,EAAE,iCAAiC,EAAE,MAAM,iCAAiC,CAAC;AACpF,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AAC7D,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,EAA0B,UAAU,EAAE,MAAM,WAAW,CAAC;AAC/D,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,wBAAwB,EAAE,MAAM,uBAAuB,CAAC;AACjE,OAAO,EAAE,uBAAuB,EAAE,MAAM,sBAAsB,CAAC;AAC/D,OAAO,EAAE,0BAA0B,EAAE,MAAM,yBAAyB,CAAC;AACrE,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AACrE,OAAO,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AACzD,OAAO,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AAC7D,OAAO,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AAC7D,OAAO,EAAE,uBAAuB,EAA2B,MAAM,sBAAsB,CAAC;AACxF,OAAO,EAAoB,uBAAuB,EAAE,MAAM,sBAAsB,CAAC;AACjF,OAAO,EAA2C,6BAA6B,EAAE,MAAM,6BAA6B,CAAC;AACrH,OAAO,EAAE,wBAAwB,EAAE,MAAM,uBAAuB,CAAC;AACjE,OAAO,EAA+C,yBAAyB,EAAE,MAAM,wBAAwB,CAAC;AAChH,OAAO,EAAE,2BAA2B,EAAE,MAAM,2BAA2B,CAAC;AACxE,OAAO,EAAE,+BAA+B,EAAE,MAAM,+BAA+B,CAAC;AAChF,OAAO,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AAC7D,OAAO,EAAE,yBAAyB,EAAE,MAAM,wBAAwB,CAAC;AACnE,OAAO,EAAE,sBAAsB,EAA6B,MAAM,qBAAqB,CAAC;AACxF,OAAO,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAC3D,OAAO,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AACzD,OAAO,EAAE,4BAA4B,EAAE,MAAM,4BAA4B,CAAC;AAC1E,OAAO,EAAE,qBAAqB,EAA6B,MAAM,sBAAsB,CAAC","sourcesContent":["// UI Components for extensions\nexport { ArminComponent } from \"./armin.js\";\nexport { AssistantMessageComponent } from \"./assistant-message.js\";\nexport { BashExecutionComponent } from \"./bash-execution.js\";\nexport { BorderedLoader } from \"./bordered-loader.js\";\nexport { BranchSummaryMessageComponent } from \"./branch-summary-message.js\";\nexport { CompactionSummaryMessageComponent } from \"./compaction-summary-message.js\";\nexport { CustomEditor } from \"./custom-editor.js\";\nexport { CustomMessageComponent } from \"./custom-message.js\";\nexport { DaxnutsComponent } from \"./daxnuts.js\";\nexport { type RenderDiffOptions, renderDiff } from \"./diff.js\";\nexport { DynamicBorder } from \"./dynamic-border.js\";\nexport { ExtensionEditorComponent } from \"./extension-editor.js\";\nexport { ExtensionInputComponent } from \"./extension-input.js\";\nexport { ExtensionSelectorComponent } from \"./extension-selector.js\";\nexport { FooterComponent } from \"./footer.js\";\nexport { keyHint, keyText, rawKeyHint } from \"./keybinding-hints.js\";\nexport { LoginDialogComponent } from \"./login-dialog.js\";\nexport { ModelSelectorComponent } from \"./model-selector.js\";\nexport { OAuthSelectorComponent } from \"./oauth-selector.js\";\nexport { PackageBrowserComponent, type PackageBrowserItem } from \"./package-browser.js\";\nexport { type RewindPoint, RewindSelectorComponent } from \"./rewind-selector.js\";\nexport { type ModelsCallbacks, type ModelsConfig, ScopedModelsSelectorComponent } from \"./scoped-models-selector.js\";\nexport { SessionSelectorComponent } from \"./session-selector.js\";\nexport { type SettingsCallbacks, type SettingsConfig, SettingsSelectorComponent } from \"./settings-selector.js\";\nexport { ShowImagesSelectorComponent } from \"./show-images-selector.js\";\nexport { SkillInvocationMessageComponent } from \"./skill-invocation-message.js\";\nexport { ThemeSelectorComponent } from \"./theme-selector.js\";\nexport { ThinkingSelectorComponent } from \"./thinking-selector.js\";\nexport { ToolExecutionComponent, type ToolExecutionOptions } from \"./tool-execution.js\";\nexport { TreeSelectorComponent } from \"./tree-selector.js\";\nexport { UserMessageComponent } from \"./user-message.js\";\nexport { UserMessageSelectorComponent } from \"./user-message-selector.js\";\nexport { truncateToVisualLines, type VisualTruncateResult } from \"./visual-truncate.js\";\n"]}
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Package browser: a clean, multi-select list for browsing and installing
3
+ * Elyra extensions. Supports windowed scrolling, checkbox selection of one or
4
+ * more packages, and a clear call to run /reload after installing.
5
+ */
6
+ import { Container } from "@elyracode/tui";
7
+ export interface PackageBrowserItem {
8
+ /** Full package name, e.g. "@elyracode/stack-tall". */
9
+ value: string;
10
+ /** Short display name, e.g. "stack-tall". */
11
+ name: string;
12
+ /** One-line description. */
13
+ description: string;
14
+ }
15
+ export declare class PackageBrowserComponent extends Container {
16
+ private readonly items;
17
+ private readonly onConfirm;
18
+ private readonly onCancel;
19
+ private readonly list;
20
+ private readonly titleText;
21
+ constructor(items: PackageBrowserItem[], onConfirm: (values: string[]) => void, onCancel: () => void);
22
+ private updateTitle;
23
+ handleInput(keyData: string): void;
24
+ private currentValue;
25
+ }
26
+ //# sourceMappingURL=package-browser.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"package-browser.d.ts","sourceRoot":"","sources":["../../../../src/modes/interactive/components/package-browser.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EAAE,SAAS,EAA+D,MAAM,gBAAgB,CAAC;AAKxG,MAAM,WAAW,kBAAkB;IAClC,uDAAuD;IACvD,KAAK,EAAE,MAAM,CAAC;IACd,6CAA6C;IAC7C,IAAI,EAAE,MAAM,CAAC;IACb,4BAA4B;IAC5B,WAAW,EAAE,MAAM,CAAC;CACpB;AA2ED,qBAAa,uBAAwB,SAAQ,SAAS;IAKpD,OAAO,CAAC,QAAQ,CAAC,KAAK;IACtB,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,QAAQ;IAN1B,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAc;IACnC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAO;IAEjC,YACkB,KAAK,EAAE,kBAAkB,EAAE,EAC3B,SAAS,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,IAAI,EACrC,QAAQ,EAAE,MAAM,IAAI,EAmCrC;IAED,OAAO,CAAC,WAAW;IAMnB,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CA8BjC;IAED,OAAO,CAAC,YAAY;CAIpB"}
@@ -0,0 +1,137 @@
1
+ /**
2
+ * Package browser: a clean, multi-select list for browsing and installing
3
+ * Elyra extensions. Supports windowed scrolling, checkbox selection of one or
4
+ * more packages, and a clear call to run /reload after installing.
5
+ */
6
+ import { Container, getKeybindings, Spacer, Text, truncateToWidth, visibleWidth } from "@elyracode/tui";
7
+ import { theme } from "../theme/theme.js";
8
+ import { DynamicBorder } from "./dynamic-border.js";
9
+ import { keyHint, rawKeyHint } from "./keybinding-hints.js";
10
+ const MAX_VISIBLE = 12;
11
+ const MIN_NAME_COLUMN = 14;
12
+ const MAX_NAME_COLUMN = 28;
13
+ const NAME_GAP = 2;
14
+ /**
15
+ * Inner scrollable, windowed list with checkbox multi-select.
16
+ * The parent PackageBrowserComponent owns key handling and state mutation;
17
+ * this component is purely presentational.
18
+ */
19
+ class PackageList {
20
+ constructor(items) {
21
+ this.items = items;
22
+ this.selectedIndex = 0;
23
+ this.checked = new Set();
24
+ }
25
+ invalidate() { }
26
+ nameColumnWidth() {
27
+ const widest = this.items.reduce((max, item) => Math.max(max, visibleWidth(item.name)), 0);
28
+ return Math.max(MIN_NAME_COLUMN, Math.min(MAX_NAME_COLUMN, widest));
29
+ }
30
+ render(width) {
31
+ if (this.items.length === 0) {
32
+ return [theme.fg("muted", " No extensions available")];
33
+ }
34
+ const nameColumn = this.nameColumnWidth();
35
+ const start = Math.max(0, Math.min(this.selectedIndex - Math.floor(MAX_VISIBLE / 2), this.items.length - MAX_VISIBLE));
36
+ const end = Math.min(start + MAX_VISIBLE, this.items.length);
37
+ const lines = [];
38
+ for (let i = start; i < end; i++) {
39
+ const item = this.items[i];
40
+ if (!item)
41
+ continue;
42
+ lines.push(this.renderRow(item, i === this.selectedIndex, this.checked.has(item.value), width, nameColumn));
43
+ }
44
+ if (start > 0 || end < this.items.length) {
45
+ lines.push(theme.fg("muted", ` (${this.selectedIndex + 1}/${this.items.length})`));
46
+ }
47
+ return lines;
48
+ }
49
+ renderRow(item, isCursor, isChecked, width, nameColumn) {
50
+ const cursor = isCursor ? "→ " : " ";
51
+ const box = isChecked ? "[x] " : "[ ] ";
52
+ const name = truncateToWidth(item.name, nameColumn, "…", true);
53
+ const used = visibleWidth(cursor) + visibleWidth(box) + nameColumn + NAME_GAP;
54
+ const descWidth = width - used - 1;
55
+ const description = descWidth > 6 ? truncateToWidth(item.description, descWidth, "…") : "";
56
+ const cursorPart = isCursor ? theme.fg("accent", cursor) : cursor;
57
+ const boxPart = isChecked ? theme.fg("success", box) : theme.fg("dim", box);
58
+ const namePart = isCursor ? theme.fg("accent", name) : theme.fg("text", name);
59
+ const descPart = description ? theme.fg("muted", `${" ".repeat(NAME_GAP)}${description}`) : "";
60
+ return `${cursorPart}${boxPart}${namePart}${descPart}`;
61
+ }
62
+ }
63
+ export class PackageBrowserComponent extends Container {
64
+ constructor(items, onConfirm, onCancel) {
65
+ super();
66
+ this.items = items;
67
+ this.onConfirm = onConfirm;
68
+ this.onCancel = onCancel;
69
+ this.list = new PackageList(items);
70
+ this.addChild(new DynamicBorder());
71
+ this.addChild(new Spacer(1));
72
+ this.titleText = new Text("", 1, 0);
73
+ this.addChild(this.titleText);
74
+ this.addChild(new Spacer(1));
75
+ this.addChild(this.list);
76
+ this.addChild(new Spacer(1));
77
+ this.addChild(new Text(rawKeyHint("↑↓", "navigate") +
78
+ " " +
79
+ keyHint("app.packages.toggle", "select") +
80
+ " " +
81
+ keyHint("app.packages.install", "install") +
82
+ " " +
83
+ keyHint("tui.select.cancel", "cancel"), 1, 0));
84
+ this.addChild(new Spacer(1));
85
+ this.addChild(new Text(theme.fg("dim", "Installed extensions activate after you run /reload."), 1, 0));
86
+ this.addChild(new Spacer(1));
87
+ this.addChild(new DynamicBorder());
88
+ this.updateTitle();
89
+ }
90
+ updateTitle() {
91
+ const count = this.list.checked.size;
92
+ const suffix = count > 0 ? theme.fg("muted", ` (${count} selected)`) : "";
93
+ this.titleText.setText(theme.fg("accent", theme.bold("Install Extensions")) + suffix);
94
+ }
95
+ handleInput(keyData) {
96
+ const kb = getKeybindings();
97
+ if (kb.matches(keyData, "tui.select.up")) {
98
+ this.list.selectedIndex = this.list.selectedIndex === 0 ? this.items.length - 1 : this.list.selectedIndex - 1;
99
+ }
100
+ else if (kb.matches(keyData, "tui.select.down")) {
101
+ this.list.selectedIndex = this.list.selectedIndex === this.items.length - 1 ? 0 : this.list.selectedIndex + 1;
102
+ }
103
+ else if (kb.matches(keyData, "tui.select.pageUp")) {
104
+ this.list.selectedIndex = Math.max(0, this.list.selectedIndex - MAX_VISIBLE);
105
+ }
106
+ else if (kb.matches(keyData, "tui.select.pageDown")) {
107
+ this.list.selectedIndex = Math.min(this.items.length - 1, this.list.selectedIndex + MAX_VISIBLE);
108
+ }
109
+ else if (kb.matches(keyData, "app.packages.toggle")) {
110
+ const item = this.items[this.list.selectedIndex];
111
+ if (item) {
112
+ if (this.list.checked.has(item.value)) {
113
+ this.list.checked.delete(item.value);
114
+ }
115
+ else {
116
+ this.list.checked.add(item.value);
117
+ }
118
+ this.updateTitle();
119
+ }
120
+ }
121
+ else if (kb.matches(keyData, "app.packages.install")) {
122
+ const selected = this.list.checked.size > 0
123
+ ? this.items.filter((item) => this.list.checked.has(item.value)).map((item) => item.value)
124
+ : this.currentValue();
125
+ if (selected.length > 0)
126
+ this.onConfirm(selected);
127
+ }
128
+ else if (kb.matches(keyData, "tui.select.cancel")) {
129
+ this.onCancel();
130
+ }
131
+ }
132
+ currentValue() {
133
+ const item = this.items[this.list.selectedIndex];
134
+ return item ? [item.value] : [];
135
+ }
136
+ }
137
+ //# sourceMappingURL=package-browser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"package-browser.js","sourceRoot":"","sources":["../../../../src/modes/interactive/components/package-browser.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Package browser: a clean, multi-select list for browsing and installing\n * Elyra extensions. Supports windowed scrolling, checkbox selection of one or\n * more packages, and a clear call to run /reload after installing.\n */\n\nimport type { Component } from \"@elyracode/tui\";\nimport { Container, getKeybindings, Spacer, Text, truncateToWidth, visibleWidth } from \"@elyracode/tui\";\nimport { theme } from \"../theme/theme.js\";\nimport { DynamicBorder } from \"./dynamic-border.js\";\nimport { keyHint, rawKeyHint } from \"./keybinding-hints.js\";\n\nexport interface PackageBrowserItem {\n\t/** Full package name, e.g. \"@elyracode/stack-tall\". */\n\tvalue: string;\n\t/** Short display name, e.g. \"stack-tall\". */\n\tname: string;\n\t/** One-line description. */\n\tdescription: string;\n}\n\nconst MAX_VISIBLE = 12;\nconst MIN_NAME_COLUMN = 14;\nconst MAX_NAME_COLUMN = 28;\nconst NAME_GAP = 2;\n\n/**\n * Inner scrollable, windowed list with checkbox multi-select.\n * The parent PackageBrowserComponent owns key handling and state mutation;\n * this component is purely presentational.\n */\nclass PackageList implements Component {\n\tselectedIndex = 0;\n\treadonly checked = new Set<string>();\n\n\tconstructor(private readonly items: PackageBrowserItem[]) {}\n\n\tinvalidate(): void {}\n\n\tprivate nameColumnWidth(): number {\n\t\tconst widest = this.items.reduce((max, item) => Math.max(max, visibleWidth(item.name)), 0);\n\t\treturn Math.max(MIN_NAME_COLUMN, Math.min(MAX_NAME_COLUMN, widest));\n\t}\n\n\trender(width: number): string[] {\n\t\tif (this.items.length === 0) {\n\t\t\treturn [theme.fg(\"muted\", \" No extensions available\")];\n\t\t}\n\n\t\tconst nameColumn = this.nameColumnWidth();\n\t\tconst start = Math.max(\n\t\t\t0,\n\t\t\tMath.min(this.selectedIndex - Math.floor(MAX_VISIBLE / 2), this.items.length - MAX_VISIBLE),\n\t\t);\n\t\tconst end = Math.min(start + MAX_VISIBLE, this.items.length);\n\n\t\tconst lines: string[] = [];\n\t\tfor (let i = start; i < end; i++) {\n\t\t\tconst item = this.items[i];\n\t\t\tif (!item) continue;\n\t\t\tlines.push(this.renderRow(item, i === this.selectedIndex, this.checked.has(item.value), width, nameColumn));\n\t\t}\n\n\t\tif (start > 0 || end < this.items.length) {\n\t\t\tlines.push(theme.fg(\"muted\", ` (${this.selectedIndex + 1}/${this.items.length})`));\n\t\t}\n\n\t\treturn lines;\n\t}\n\n\tprivate renderRow(\n\t\titem: PackageBrowserItem,\n\t\tisCursor: boolean,\n\t\tisChecked: boolean,\n\t\twidth: number,\n\t\tnameColumn: number,\n\t): string {\n\t\tconst cursor = isCursor ? \"→ \" : \" \";\n\t\tconst box = isChecked ? \"[x] \" : \"[ ] \";\n\t\tconst name = truncateToWidth(item.name, nameColumn, \"…\", true);\n\n\t\tconst used = visibleWidth(cursor) + visibleWidth(box) + nameColumn + NAME_GAP;\n\t\tconst descWidth = width - used - 1;\n\t\tconst description = descWidth > 6 ? truncateToWidth(item.description, descWidth, \"…\") : \"\";\n\n\t\tconst cursorPart = isCursor ? theme.fg(\"accent\", cursor) : cursor;\n\t\tconst boxPart = isChecked ? theme.fg(\"success\", box) : theme.fg(\"dim\", box);\n\t\tconst namePart = isCursor ? theme.fg(\"accent\", name) : theme.fg(\"text\", name);\n\t\tconst descPart = description ? theme.fg(\"muted\", `${\" \".repeat(NAME_GAP)}${description}`) : \"\";\n\n\t\treturn `${cursorPart}${boxPart}${namePart}${descPart}`;\n\t}\n}\n\nexport class PackageBrowserComponent extends Container {\n\tprivate readonly list: PackageList;\n\tprivate readonly titleText: Text;\n\n\tconstructor(\n\t\tprivate readonly items: PackageBrowserItem[],\n\t\tprivate readonly onConfirm: (values: string[]) => void,\n\t\tprivate readonly onCancel: () => void,\n\t) {\n\t\tsuper();\n\n\t\tthis.list = new PackageList(items);\n\n\t\tthis.addChild(new DynamicBorder());\n\t\tthis.addChild(new Spacer(1));\n\n\t\tthis.titleText = new Text(\"\", 1, 0);\n\t\tthis.addChild(this.titleText);\n\t\tthis.addChild(new Spacer(1));\n\n\t\tthis.addChild(this.list);\n\t\tthis.addChild(new Spacer(1));\n\n\t\tthis.addChild(\n\t\t\tnew Text(\n\t\t\t\trawKeyHint(\"↑↓\", \"navigate\") +\n\t\t\t\t\t\" \" +\n\t\t\t\t\tkeyHint(\"app.packages.toggle\", \"select\") +\n\t\t\t\t\t\" \" +\n\t\t\t\t\tkeyHint(\"app.packages.install\", \"install\") +\n\t\t\t\t\t\" \" +\n\t\t\t\t\tkeyHint(\"tui.select.cancel\", \"cancel\"),\n\t\t\t\t1,\n\t\t\t\t0,\n\t\t\t),\n\t\t);\n\t\tthis.addChild(new Spacer(1));\n\t\tthis.addChild(new Text(theme.fg(\"dim\", \"Installed extensions activate after you run /reload.\"), 1, 0));\n\t\tthis.addChild(new Spacer(1));\n\t\tthis.addChild(new DynamicBorder());\n\n\t\tthis.updateTitle();\n\t}\n\n\tprivate updateTitle(): void {\n\t\tconst count = this.list.checked.size;\n\t\tconst suffix = count > 0 ? theme.fg(\"muted\", ` (${count} selected)`) : \"\";\n\t\tthis.titleText.setText(theme.fg(\"accent\", theme.bold(\"Install Extensions\")) + suffix);\n\t}\n\n\thandleInput(keyData: string): void {\n\t\tconst kb = getKeybindings();\n\n\t\tif (kb.matches(keyData, \"tui.select.up\")) {\n\t\t\tthis.list.selectedIndex = this.list.selectedIndex === 0 ? this.items.length - 1 : this.list.selectedIndex - 1;\n\t\t} else if (kb.matches(keyData, \"tui.select.down\")) {\n\t\t\tthis.list.selectedIndex = this.list.selectedIndex === this.items.length - 1 ? 0 : this.list.selectedIndex + 1;\n\t\t} else if (kb.matches(keyData, \"tui.select.pageUp\")) {\n\t\t\tthis.list.selectedIndex = Math.max(0, this.list.selectedIndex - MAX_VISIBLE);\n\t\t} else if (kb.matches(keyData, \"tui.select.pageDown\")) {\n\t\t\tthis.list.selectedIndex = Math.min(this.items.length - 1, this.list.selectedIndex + MAX_VISIBLE);\n\t\t} else if (kb.matches(keyData, \"app.packages.toggle\")) {\n\t\t\tconst item = this.items[this.list.selectedIndex];\n\t\t\tif (item) {\n\t\t\t\tif (this.list.checked.has(item.value)) {\n\t\t\t\t\tthis.list.checked.delete(item.value);\n\t\t\t\t} else {\n\t\t\t\t\tthis.list.checked.add(item.value);\n\t\t\t\t}\n\t\t\t\tthis.updateTitle();\n\t\t\t}\n\t\t} else if (kb.matches(keyData, \"app.packages.install\")) {\n\t\t\tconst selected =\n\t\t\t\tthis.list.checked.size > 0\n\t\t\t\t\t? this.items.filter((item) => this.list.checked.has(item.value)).map((item) => item.value)\n\t\t\t\t\t: this.currentValue();\n\t\t\tif (selected.length > 0) this.onConfirm(selected);\n\t\t} else if (kb.matches(keyData, \"tui.select.cancel\")) {\n\t\t\tthis.onCancel();\n\t\t}\n\t}\n\n\tprivate currentValue(): string[] {\n\t\tconst item = this.items[this.list.selectedIndex];\n\t\treturn item ? [item.value] : [];\n\t}\n}\n"]}
@@ -385,6 +385,7 @@ export declare class InteractiveMode {
385
385
  private showOAuthLoginSelect;
386
386
  private showLoginDialog;
387
387
  private handlePackageBrowser;
388
+ private installPackages;
388
389
  private handleReloadCommand;
389
390
  private handleExportCommand;
390
391
  private getPathCommandArgument;