@elyracode/coding-agent 0.2.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (157) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/dist/cli/config-selector.d.ts +1 -1
  3. package/dist/cli/config-selector.d.ts.map +1 -1
  4. package/dist/cli/config-selector.js +1 -1
  5. package/dist/cli/config-selector.js.map +1 -1
  6. package/dist/config.d.ts +1 -1
  7. package/dist/config.d.ts.map +1 -1
  8. package/dist/config.js +2 -2
  9. package/dist/config.js.map +1 -1
  10. package/dist/core/agent-session.d.ts +1 -1
  11. package/dist/core/agent-session.d.ts.map +1 -1
  12. package/dist/core/agent-session.js +8 -3
  13. package/dist/core/agent-session.js.map +1 -1
  14. package/dist/core/bash-executor.d.ts.map +1 -1
  15. package/dist/core/bash-executor.js +1 -1
  16. package/dist/core/bash-executor.js.map +1 -1
  17. package/dist/core/compaction/branch-summarization.d.ts.map +1 -1
  18. package/dist/core/compaction/branch-summarization.js +1 -1
  19. package/dist/core/compaction/branch-summarization.js.map +1 -1
  20. package/dist/core/compaction/compaction.d.ts.map +1 -1
  21. package/dist/core/compaction/compaction.js +1 -1
  22. package/dist/core/compaction/compaction.js.map +1 -1
  23. package/dist/core/extensions/loader.d.ts.map +1 -1
  24. package/dist/core/extensions/loader.js +3 -3
  25. package/dist/core/extensions/loader.js.map +1 -1
  26. package/dist/core/extensions/runner.d.ts.map +1 -1
  27. package/dist/core/extensions/runner.js +1 -1
  28. package/dist/core/extensions/runner.js.map +1 -1
  29. package/dist/core/extensions/types.d.ts +9 -9
  30. package/dist/core/extensions/types.d.ts.map +1 -1
  31. package/dist/core/extensions/types.js.map +1 -1
  32. package/dist/core/package-manager.d.ts.map +1 -1
  33. package/dist/core/package-manager.js +12 -12
  34. package/dist/core/package-manager.js.map +1 -1
  35. package/dist/core/session-manager.d.ts +6 -6
  36. package/dist/core/session-manager.d.ts.map +1 -1
  37. package/dist/core/session-manager.js +4 -4
  38. package/dist/core/session-manager.js.map +1 -1
  39. package/dist/core/stack-detector.d.ts +21 -0
  40. package/dist/core/stack-detector.d.ts.map +1 -0
  41. package/dist/core/stack-detector.js +120 -0
  42. package/dist/core/stack-detector.js.map +1 -0
  43. package/dist/core/system-prompt.d.ts +2 -0
  44. package/dist/core/system-prompt.d.ts.map +1 -1
  45. package/dist/core/system-prompt.js +13 -1
  46. package/dist/core/system-prompt.js.map +1 -1
  47. package/dist/core/tools/bash.d.ts +2 -2
  48. package/dist/core/tools/bash.d.ts.map +1 -1
  49. package/dist/core/tools/bash.js +3 -3
  50. package/dist/core/tools/bash.js.map +1 -1
  51. package/dist/core/tools/output-accumulator.d.ts.map +1 -1
  52. package/dist/core/tools/output-accumulator.js +1 -1
  53. package/dist/core/tools/output-accumulator.js.map +1 -1
  54. package/dist/migrations.d.ts.map +1 -1
  55. package/dist/migrations.js +1 -1
  56. package/dist/migrations.js.map +1 -1
  57. package/dist/modes/interactive/interactive-mode.d.ts +1 -0
  58. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  59. package/dist/modes/interactive/interactive-mode.js +18 -0
  60. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  61. package/dist/package-manager-cli.d.ts.map +1 -1
  62. package/dist/package-manager-cli.js +10 -10
  63. package/dist/package-manager-cli.js.map +1 -1
  64. package/dist/utils/clipboard-image.d.ts.map +1 -1
  65. package/dist/utils/clipboard-image.js +1 -1
  66. package/dist/utils/clipboard-image.js.map +1 -1
  67. package/docs/extensions.md +17 -17
  68. package/docs/index.md +1 -1
  69. package/docs/prompt-templates.md +1 -1
  70. package/docs/providers.md +1 -1
  71. package/docs/quickstart.md +5 -5
  72. package/docs/rpc.md +6 -6
  73. package/docs/sdk.md +2 -2
  74. package/docs/session-format.md +3 -3
  75. package/docs/settings.md +4 -4
  76. package/docs/skills.md +2 -2
  77. package/docs/termux.md +3 -3
  78. package/docs/themes.md +1 -1
  79. package/docs/tui.md +1 -1
  80. package/docs/usage.md +2 -2
  81. package/examples/extensions/auto-commit-on-exit.ts +5 -5
  82. package/examples/extensions/bash-spawn-hook.ts +2 -2
  83. package/examples/extensions/bookmark.ts +5 -5
  84. package/examples/extensions/border-status-editor.ts +7 -7
  85. package/examples/extensions/built-in-tool-renderer.ts +5 -5
  86. package/examples/extensions/claude-rules.ts +3 -3
  87. package/examples/extensions/commands.ts +4 -4
  88. package/examples/extensions/confirm-destructive.ts +3 -3
  89. package/examples/extensions/custom-compaction.ts +2 -2
  90. package/examples/extensions/custom-footer.ts +2 -2
  91. package/examples/extensions/custom-header.ts +3 -3
  92. package/examples/extensions/custom-provider-anthropic/index.ts +2 -2
  93. package/examples/extensions/custom-provider-anthropic/package.json +2 -2
  94. package/examples/extensions/custom-provider-gitlab-duo/index.ts +2 -2
  95. package/examples/extensions/custom-provider-gitlab-duo/package.json +2 -2
  96. package/examples/extensions/dirty-repo-guard.ts +7 -7
  97. package/examples/extensions/doom-overlay/index.ts +2 -2
  98. package/examples/extensions/dynamic-resources/index.ts +2 -2
  99. package/examples/extensions/dynamic-tools.ts +4 -4
  100. package/examples/extensions/event-bus.ts +8 -8
  101. package/examples/extensions/file-trigger.ts +3 -3
  102. package/examples/extensions/git-checkpoint.ts +7 -7
  103. package/examples/extensions/github-issue-autocomplete.ts +6 -6
  104. package/examples/extensions/handoff.ts +2 -2
  105. package/examples/extensions/hello.ts +2 -2
  106. package/examples/extensions/hidden-thinking-label.ts +3 -3
  107. package/examples/extensions/inline-bash.ts +3 -3
  108. package/examples/extensions/input-transform.ts +2 -2
  109. package/examples/extensions/interactive-shell.ts +2 -2
  110. package/examples/extensions/mac-system-theme.ts +3 -3
  111. package/examples/extensions/message-renderer.ts +4 -4
  112. package/examples/extensions/minimal-mode.ts +8 -8
  113. package/examples/extensions/modal-editor.ts +2 -2
  114. package/examples/extensions/model-status.ts +2 -2
  115. package/examples/extensions/notify.ts +2 -2
  116. package/examples/extensions/overlay-qa-tests.ts +14 -14
  117. package/examples/extensions/overlay-test.ts +2 -2
  118. package/examples/extensions/permission-gate.ts +2 -2
  119. package/examples/extensions/pirate.ts +3 -3
  120. package/examples/extensions/plan-mode/index.ts +22 -22
  121. package/examples/extensions/preset.ts +23 -23
  122. package/examples/extensions/prompt-customizer.ts +2 -2
  123. package/examples/extensions/protected-paths.ts +2 -2
  124. package/examples/extensions/provider-payload.ts +3 -3
  125. package/examples/extensions/qna.ts +2 -2
  126. package/examples/extensions/question.ts +2 -2
  127. package/examples/extensions/questionnaire.ts +2 -2
  128. package/examples/extensions/rainbow-editor.ts +2 -2
  129. package/examples/extensions/reload-runtime.ts +4 -4
  130. package/examples/extensions/rpc-demo.ts +10 -10
  131. package/examples/extensions/sandbox/index.ts +8 -8
  132. package/examples/extensions/sandbox/package.json +2 -2
  133. package/examples/extensions/send-user-message.ts +13 -13
  134. package/examples/extensions/session-name.ts +4 -4
  135. package/examples/extensions/shutdown-command.ts +10 -10
  136. package/examples/extensions/snake.ts +3 -3
  137. package/examples/extensions/space-invaders.ts +3 -3
  138. package/examples/extensions/ssh.ts +10 -10
  139. package/examples/extensions/status-line.ts +4 -4
  140. package/examples/extensions/structured-output.ts +2 -2
  141. package/examples/extensions/subagent/index.ts +3 -3
  142. package/examples/extensions/summarize.ts +2 -2
  143. package/examples/extensions/system-prompt-header.ts +3 -3
  144. package/examples/extensions/tic-tac-toe.ts +15 -15
  145. package/examples/extensions/timed-confirm.ts +4 -4
  146. package/examples/extensions/titlebar-spinner.ts +8 -8
  147. package/examples/extensions/todo.ts +5 -5
  148. package/examples/extensions/tool-override.ts +3 -3
  149. package/examples/extensions/tools.ts +9 -9
  150. package/examples/extensions/trigger-compact.ts +3 -3
  151. package/examples/extensions/truncated-tool.ts +3 -3
  152. package/examples/extensions/widget-placement.ts +2 -2
  153. package/examples/extensions/with-deps/index.ts +2 -2
  154. package/examples/extensions/with-deps/package.json +2 -2
  155. package/examples/extensions/working-indicator.ts +5 -5
  156. package/examples/extensions/working-message-test.ts +2 -2
  157. package/package.json +5 -5
@@ -14,7 +14,7 @@ Then start elyra in the project directory you want it to work on:
14
14
 
15
15
  ```bash
16
16
  cd /path/to/project
17
- pi
17
+ elyra
18
18
  ```
19
19
 
20
20
  ## Authenticate
@@ -33,11 +33,11 @@ Then select a provider. Built-in subscription logins include Claude Pro/Max, Cha
33
33
 
34
34
  ### Option 2: API key
35
35
 
36
- Set an API key before launching pi:
36
+ Set an API key before launching elyra:
37
37
 
38
38
  ```bash
39
39
  export ANTHROPIC_API_KEY=sk-ant-...
40
- pi
40
+ elyra
41
41
  ```
42
42
 
43
43
  You can also run `/login` and select an API-key provider to store the key in `~/.elyra/agent/auth.json`.
@@ -133,10 +133,10 @@ Use `--mode json` for JSON event output or `--mode rpc` for process integration.
133
133
 
134
134
  ## Next steps
135
135
 
136
- - [Using Pi](usage.md) - interactive mode, slash commands, sessions, context files, and CLI reference.
136
+ - [Using Elyra](usage.md) - interactive mode, slash commands, sessions, context files, and CLI reference.
137
137
  - [Providers](providers.md) - authentication and model setup.
138
138
  - [Settings](settings.md) - global and project configuration.
139
139
  - [Keybindings](keybindings.md) - shortcuts and customization.
140
- - [Pi Packages](packages.md) - install shared extensions, skills, prompts, and themes.
140
+ - [Elyra Packages](packages.md) - install shared extensions, skills, prompts, and themes.
141
141
 
142
142
  Platform notes: [Windows](windows.md), [Termux](termux.md), [tmux](tmux.md), [Terminal setup](terminal-setup.md), [Shell aliases](shell-aliases.md).
package/docs/rpc.md CHANGED
@@ -455,7 +455,7 @@ If output was truncated, includes `fullOutputPath`:
455
455
  "exitCode": 0,
456
456
  "cancelled": false,
457
457
  "truncated": true,
458
- "fullOutputPath": "/tmp/pi-bash-abc123.log"
458
+ "fullOutputPath": "/tmp/elyra-bash-abc123.log"
459
459
  }
460
460
  }
461
461
  ```
@@ -714,9 +714,9 @@ Response:
714
714
  "success": true,
715
715
  "data": {
716
716
  "commands": [
717
- {"name": "session-name", "description": "Set or clear session name", "source": "extension", "path": "/home/user/.pi/agent/extensions/session.ts"},
718
- {"name": "fix-tests", "description": "Fix failing tests", "source": "prompt", "location": "project", "path": "/home/user/myproject/.pi/agent/prompts/fix-tests.md"},
719
- {"name": "skill:brave-search", "description": "Web search via Brave API", "source": "skill", "location": "user", "path": "/home/user/.pi/agent/skills/brave-search/SKILL.md"}
717
+ {"name": "session-name", "description": "Set or clear session name", "source": "extension", "path": "/home/user/.elyra/agent/extensions/session.ts"},
718
+ {"name": "fix-tests", "description": "Fix failing tests", "source": "prompt", "location": "project", "path": "/home/user/myproject/.elyra/agent/prompts/fix-tests.md"},
719
+ {"name": "skill:brave-search", "description": "Web search via Brave API", "source": "skill", "location": "user", "path": "/home/user/.elyra/agent/skills/brave-search/SKILL.md"}
720
720
  ]
721
721
  }
722
722
  }
@@ -731,7 +731,7 @@ Each command has:
731
731
  - `"skill"`: Loaded from a skill directory (name is prefixed with `skill:`)
732
732
  - `location`: Where it was loaded from (optional, not present for extensions):
733
733
  - `"user"`: User-level (`~/.elyra/agent/`)
734
- - `"project"`: Project-level (`./.pi/agent/`)
734
+ - `"project"`: Project-level (`./.elyra/agent/`)
735
735
  - `"path"`: Explicit path via CLI or settings
736
736
  - `path`: Absolute file path to the command source (optional)
737
737
 
@@ -1132,7 +1132,7 @@ Set the terminal window/tab title. Fire-and-forget.
1132
1132
  "type": "extension_ui_request",
1133
1133
  "id": "uuid-8",
1134
1134
  "method": "setTitle",
1135
- "title": "pi - my project"
1135
+ "title": "elyra - my project"
1136
1136
  }
1137
1137
  ```
1138
1138
 
package/docs/sdk.md CHANGED
@@ -568,7 +568,7 @@ import { createAgentSession, DefaultResourceLoader } from "@elyracode/coding-age
568
568
  const loader = new DefaultResourceLoader({
569
569
  additionalExtensionPaths: ["/path/to/my-extension.ts"],
570
570
  extensionFactories: [
571
- (pi) => {
571
+ (elyra) => {
572
572
  elyra.on("agent_start", () => {
573
573
  console.log("[Inline Extension] Agent starting");
574
574
  });
@@ -819,7 +819,7 @@ const { session } = await createAgentSession({
819
819
 
820
820
  Settings load from two locations and merge:
821
821
  1. Global: `~/.elyra/agent/settings.json`
822
- 2. Project: `<cwd>/.pi/settings.json`
822
+ 2. Project: `<cwd>/.elyra/settings.json`
823
823
 
824
824
  Project overrides global. Nested objects merge keys. Setters modify global settings by default.
825
825
 
@@ -233,7 +233,7 @@ Created when context is compacted. Stores a summary of earlier messages.
233
233
 
234
234
  Optional fields:
235
235
  - `details`: Implementation-specific data (e.g., `{ readFiles: string[], modifiedFiles: string[] }` for default, or custom data for extensions)
236
- - `fromHook`: `true` if generated by an extension, `false`/`undefined` if pi-generated (legacy field name)
236
+ - `fromHook`: `true` if generated by an extension, `false`/`undefined` if elyra-generated (legacy field name)
237
237
 
238
238
  ### BranchSummaryEntry
239
239
 
@@ -245,7 +245,7 @@ Created when switching branches via `/tree` with an LLM generated summary of the
245
245
 
246
246
  Optional fields:
247
247
  - `details`: File tracking data (`{ readFiles: string[], modifiedFiles: string[] }`) for default, or custom data for extensions
248
- - `fromHook`: `true` if generated by an extension, `false`/`undefined` if pi-generated (legacy field name)
248
+ - `fromHook`: `true` if generated by an extension, `false`/`undefined` if elyra-generated (legacy field name)
249
249
 
250
250
  ### CustomEntry
251
251
 
@@ -282,7 +282,7 @@ Set `label` to `undefined` to clear a label.
282
282
 
283
283
  ### SessionInfoEntry
284
284
 
285
- Session metadata (e.g., user-defined display name). Set via `/name` command or `pi.setSessionName()` in extensions.
285
+ Session metadata (e.g., user-defined display name). Set via `/name` command or `elyra.setSessionName()` in extensions.
286
286
 
287
287
  ```json
288
288
  {"type":"session_info","id":"k1l2m3n4","parentId":"j0k1l2m3","timestamp":"2024-12-03T14:35:00.000Z","name":"Refactor auth module"}
package/docs/settings.md CHANGED
@@ -191,7 +191,7 @@ When multiple sources specify a session directory, precedence is `--session-dir`
191
191
 
192
192
  These settings define where to load extensions, skills, prompts, and themes from.
193
193
 
194
- Paths in `~/.elyra/agent/settings.json` resolve relative to `~/.elyra/agent`. Paths in `.elyra/settings.json` resolve relative to `.pi`. Absolute paths and `~` are supported.
194
+ Paths in `~/.elyra/agent/settings.json` resolve relative to `~/.elyra/agent`. Paths in `.elyra/settings.json` resolve relative to `.elyra`. Absolute paths and `~` are supported.
195
195
 
196
196
  | Setting | Type | Default | Description |
197
197
  |---------|------|---------|-------------|
@@ -210,7 +210,7 @@ String form loads all resources from a package:
210
210
 
211
211
  ```json
212
212
  {
213
- "packages": ["pi-skills", "@org/my-extension"]
213
+ "packages": ["elyra-skills", "@org/my-extension"]
214
214
  }
215
215
  ```
216
216
 
@@ -220,7 +220,7 @@ Object form filters which resources to load:
220
220
  {
221
221
  "packages": [
222
222
  {
223
- "source": "pi-skills",
223
+ "source": "elyra-skills",
224
224
  "skills": ["brave-search", "transcribe"],
225
225
  "extensions": []
226
226
  }
@@ -251,7 +251,7 @@ See [packages.md](packages.md) for package management details.
251
251
  "warnings": {
252
252
  "anthropicExtraUsage": true
253
253
  },
254
- "packages": ["pi-skills"]
254
+ "packages": ["elyra-skills"]
255
255
  }
256
256
  ```
257
257
 
package/docs/skills.md CHANGED
@@ -29,7 +29,7 @@ Elyra loads skills from:
29
29
  - Project:
30
30
  - `.elyra/skills/`
31
31
  - `.agents/skills/` in `cwd` and ancestor directories (up to git repo root, or filesystem root when not in a repo)
32
- - Packages: `skills/` directories or `pi.skills` entries in `package.json`
32
+ - Packages: `skills/` directories or `elyra.skills` entries in `package.json`
33
33
  - Settings: `skills` array with files or directories
34
34
  - CLI: `--skill <path>` (repeatable, additive even with `--no-skills`)
35
35
 
@@ -229,4 +229,4 @@ cd /path/to/brave-search && npm install
229
229
  ## Skill Repositories
230
230
 
231
231
  - [Anthropic Skills](https://github.com/anthropics/skills) - Document processing (docx, pdf, pptx, xlsx), web development
232
- - [Pi Skills](https://github.com/badlogic/pi-skills) - Web search, browser automation, Google APIs, transcription
232
+ - [Elyra Skills](https://github.com/badlogic/elyra-skills) - Web search, browser automation, Google APIs, transcription
package/docs/termux.md CHANGED
@@ -16,14 +16,14 @@ pkg update && pkg upgrade
16
16
  # Install dependencies
17
17
  pkg install nodejs termux-api git
18
18
 
19
- # Install pi
19
+ # Install elyra
20
20
  npm install -g @elyracode/coding-agent
21
21
 
22
22
  # Create config directory
23
23
  mkdir -p ~/.elyra/agent
24
24
 
25
- # Run pi
26
- pi
25
+ # Run elyra
26
+ elyra
27
27
  ```
28
28
 
29
29
  ## Clipboard Support
package/docs/themes.md CHANGED
@@ -21,7 +21,7 @@ Elyra loads themes from:
21
21
  - Built-in: `dark`, `light`
22
22
  - Global: `~/.elyra/agent/themes/*.json`
23
23
  - Project: `.elyra/themes/*.json`
24
- - Packages: `themes/` directories or `pi.themes` entries in `package.json`
24
+ - Packages: `themes/` directories or `elyra.themes` entries in `package.json`
25
25
  - Settings: `themes` array with files or directories
26
26
  - CLI: `--theme <path>` (repeatable)
27
27
 
package/docs/tui.md CHANGED
@@ -96,7 +96,7 @@ elyra.on("session_start", async (_event, ctx) => {
96
96
  });
97
97
  ```
98
98
 
99
- **In custom tools** via `pi.ui.custom()`:
99
+ **In custom tools** via `elyra.ui.custom()`:
100
100
 
101
101
  ```typescript
102
102
  async execute(toolCallId, params, onUpdate, ctx, signal) {
package/docs/usage.md CHANGED
@@ -129,7 +129,7 @@ elyra [options] [@files...] [messages...]
129
129
  elyra install <source> [-l] # Install package, -l for project-local
130
130
  elyra remove <source> [-l] # Remove package
131
131
  elyra uninstall <source> [-l] # Alias for remove
132
- elyra update [source|self|pi] # Update elyra and packages; skips pinned packages
132
+ elyra update [source|self|elyra] # Update elyra and packages; skips pinned packages
133
133
  elyra update --extensions # Update packages only
134
134
  elyra update --self # Update elyra only
135
135
  elyra update --extension <src> # Update one package
@@ -274,4 +274,4 @@ Elyra keeps the core small and pushes workflow-specific behavior into extensions
274
274
 
275
275
  It intentionally does not include built-in MCP, sub-agents, permission popups, plan mode, to-dos, or background bash. You can build or install those workflows as extensions or packages, or use external tools such as containers and tmux.
276
276
 
277
- For the full rationale, read the [blog post](https://mariozechner.at/posts/2025-11-30-pi-coding-agent/).
277
+ For the full rationale, see the design discussion in the project documentation.
@@ -7,10 +7,10 @@
7
7
 
8
8
  import type { ExtensionAPI } from "@elyracode/coding-agent";
9
9
 
10
- export default function (pi: ExtensionAPI) {
11
- pi.on("session_shutdown", async (_event, ctx) => {
10
+ export default function (elyra: ExtensionAPI) {
11
+ elyra.on("session_shutdown", async (_event, ctx) => {
12
12
  // Check for uncommitted changes
13
- const { stdout: status, code } = await pi.exec("git", ["status", "--porcelain"]);
13
+ const { stdout: status, code } = await elyra.exec("git", ["status", "--porcelain"]);
14
14
 
15
15
  if (code !== 0 || status.trim().length === 0) {
16
16
  // Not a git repo or no changes
@@ -39,8 +39,8 @@ export default function (pi: ExtensionAPI) {
39
39
  const commitMessage = `[elyra] ${firstLine.slice(0, 50)}${firstLine.length > 50 ? "..." : ""}`;
40
40
 
41
41
  // Stage and commit
42
- await pi.exec("git", ["add", "-A"]);
43
- const { code: commitCode } = await pi.exec("git", ["commit", "-m", commitMessage]);
42
+ await elyra.exec("git", ["add", "-A"]);
43
+ const { code: commitCode } = await elyra.exec("git", ["commit", "-m", commitMessage]);
44
44
 
45
45
  if (commitCode === 0 && ctx.hasUI) {
46
46
  ctx.ui.notify(`Auto-committed: ${commitMessage}`, "info");
@@ -10,7 +10,7 @@
10
10
  import type { ExtensionAPI } from "@elyracode/coding-agent";
11
11
  import { createBashTool } from "@elyracode/coding-agent";
12
12
 
13
- export default function (pi: ExtensionAPI) {
13
+ export default function (elyra: ExtensionAPI) {
14
14
  const cwd = process.cwd();
15
15
 
16
16
  const bashTool = createBashTool(cwd, {
@@ -21,7 +21,7 @@ export default function (pi: ExtensionAPI) {
21
21
  }),
22
22
  });
23
23
 
24
- pi.registerTool({
24
+ elyra.registerTool({
25
25
  ...bashTool,
26
26
  execute: async (id, params, signal, onUpdate, _ctx) => {
27
27
  return bashTool.execute(id, params, signal, onUpdate);
@@ -9,8 +9,8 @@
9
9
 
10
10
  import type { ExtensionAPI } from "@elyracode/coding-agent";
11
11
 
12
- export default function (pi: ExtensionAPI) {
13
- pi.registerCommand("bookmark", {
12
+ export default function (elyra: ExtensionAPI) {
13
+ elyra.registerCommand("bookmark", {
14
14
  description: "Bookmark last message (usage: /bookmark [label])",
15
15
  handler: async (args, ctx) => {
16
16
  const label = args.trim() || `bookmark-${Date.now()}`;
@@ -20,7 +20,7 @@ export default function (pi: ExtensionAPI) {
20
20
  for (let i = entries.length - 1; i >= 0; i--) {
21
21
  const entry = entries[i];
22
22
  if (entry.type === "message" && entry.message.role === "assistant") {
23
- pi.setLabel(entry.id, label);
23
+ elyra.setLabel(entry.id, label);
24
24
  ctx.ui.notify(`Bookmarked as: ${label}`, "info");
25
25
  return;
26
26
  }
@@ -31,7 +31,7 @@ export default function (pi: ExtensionAPI) {
31
31
  });
32
32
 
33
33
  // Remove bookmark
34
- pi.registerCommand("unbookmark", {
34
+ elyra.registerCommand("unbookmark", {
35
35
  description: "Remove bookmark from last labeled entry",
36
36
  handler: async (_args, ctx) => {
37
37
  const entries = ctx.sessionManager.getEntries();
@@ -39,7 +39,7 @@ export default function (pi: ExtensionAPI) {
39
39
  const entry = entries[i];
40
40
  const label = ctx.sessionManager.getLabel(entry.id);
41
41
  if (label) {
42
- pi.setLabel(entry.id, undefined);
42
+ elyra.setLabel(entry.id, undefined);
43
43
  ctx.ui.notify(`Removed bookmark: ${label}`, "info");
44
44
  return;
45
45
  }
@@ -68,7 +68,7 @@ class EmptyFooter implements Component {
68
68
  invalidate(): void {}
69
69
  }
70
70
 
71
- export default function (pi: ExtensionAPI) {
71
+ export default function (elyra: ExtensionAPI) {
72
72
  let isWorking = false;
73
73
  let spinnerIndex = 0;
74
74
  let spinnerTimer: ReturnType<typeof setInterval> | undefined;
@@ -82,7 +82,7 @@ export default function (pi: ExtensionAPI) {
82
82
  }
83
83
  };
84
84
 
85
- pi.on("agent_start", () => {
85
+ elyra.on("agent_start", () => {
86
86
  isWorking = true;
87
87
  stopSpinner();
88
88
  spinnerTimer = setInterval(() => {
@@ -92,25 +92,25 @@ export default function (pi: ExtensionAPI) {
92
92
  activeTui?.requestRender();
93
93
  });
94
94
 
95
- pi.on("agent_end", () => {
95
+ elyra.on("agent_end", () => {
96
96
  isWorking = false;
97
97
  stopSpinner();
98
98
  activeTui?.requestRender();
99
99
  });
100
100
 
101
- pi.on("session_shutdown", () => {
101
+ elyra.on("session_shutdown", () => {
102
102
  stopSpinner();
103
103
  activeTui = undefined;
104
104
  });
105
105
 
106
- pi.on("session_start", (_event, ctx) => {
106
+ elyra.on("session_start", (_event, ctx) => {
107
107
  ctx.ui.setWorkingVisible(false);
108
108
  ctx.ui.setFooter(() => new EmptyFooter());
109
109
 
110
110
  let branch: string | undefined;
111
111
 
112
112
  const refreshBranch = async () => {
113
- const result = await pi.exec("git", ["branch", "--show-current"], { cwd: ctx.cwd }).catch(() => undefined);
113
+ const result = await elyra.exec("git", ["branch", "--show-current"], { cwd: ctx.cwd }).catch(() => undefined);
114
114
  const stdout = result?.stdout.trim();
115
115
  branch = stdout && stdout.length > 0 ? stdout : undefined;
116
116
  activeTui?.requestRender();
@@ -129,7 +129,7 @@ export default function (pi: ExtensionAPI) {
129
129
 
130
130
  const thm = ctx.ui.theme;
131
131
  const model = ctx.model ? `${ctx.model.provider}/${ctx.model.id}` : "no model";
132
- const thinking = pi.getThinkingLevel();
132
+ const thinking = elyra.getThinkingLevel();
133
133
  const topLeft = isWorking ? thm.fg("accent", ` ${spinnerFrames[spinnerIndex]} `) : "";
134
134
  const topRight = "";
135
135
  const bottomLeft = thm.fg("muted", ` ${model} · ${formatThinking(thinking)} `);
@@ -29,12 +29,12 @@ import type { BashToolDetails, EditToolDetails, ExtensionAPI, ReadToolDetails }
29
29
  import { createBashTool, createEditTool, createReadTool, createWriteTool } from "@elyracode/coding-agent";
30
30
  import { Text } from "@elyracode/tui";
31
31
 
32
- export default function (pi: ExtensionAPI) {
32
+ export default function (elyra: ExtensionAPI) {
33
33
  const cwd = process.cwd();
34
34
 
35
35
  // --- Read tool: show path and line count ---
36
36
  const originalRead = createReadTool(cwd);
37
- pi.registerTool({
37
+ elyra.registerTool({
38
38
  name: "read",
39
39
  label: "read",
40
40
  description: originalRead.description,
@@ -93,7 +93,7 @@ export default function (pi: ExtensionAPI) {
93
93
 
94
94
  // --- Bash tool: show command and exit code ---
95
95
  const originalBash = createBashTool(cwd);
96
- pi.registerTool({
96
+ elyra.registerTool({
97
97
  name: "bash",
98
98
  label: "bash",
99
99
  description: originalBash.description,
@@ -152,7 +152,7 @@ export default function (pi: ExtensionAPI) {
152
152
 
153
153
  // --- Edit tool: show path and diff stats ---
154
154
  const originalEdit = createEditTool(cwd);
155
- pi.registerTool({
155
+ elyra.registerTool({
156
156
  name: "edit",
157
157
  label: "edit",
158
158
  description: originalEdit.description,
@@ -217,7 +217,7 @@ export default function (pi: ExtensionAPI) {
217
217
 
218
218
  // --- Write tool: show path and size ---
219
219
  const originalWrite = createWriteTool(cwd);
220
- pi.registerTool({
220
+ elyra.registerTool({
221
221
  name: "write",
222
222
  label: "write",
223
223
  description: originalWrite.description,
@@ -46,12 +46,12 @@ function findMarkdownFiles(dir: string, basePath: string = ""): string[] {
46
46
  return results;
47
47
  }
48
48
 
49
- export default function claudeRulesExtension(pi: ExtensionAPI) {
49
+ export default function claudeRulesExtension(elyra: ExtensionAPI) {
50
50
  let ruleFiles: string[] = [];
51
51
  let rulesDir: string = "";
52
52
 
53
53
  // Scan for rules on session start
54
- pi.on("session_start", async (_event, ctx) => {
54
+ elyra.on("session_start", async (_event, ctx) => {
55
55
  rulesDir = path.join(ctx.cwd, ".claude", "rules");
56
56
  ruleFiles = findMarkdownFiles(rulesDir);
57
57
 
@@ -61,7 +61,7 @@ export default function claudeRulesExtension(pi: ExtensionAPI) {
61
61
  });
62
62
 
63
63
  // Append available rules to system prompt
64
- pi.on("before_agent_start", async (event) => {
64
+ elyra.on("before_agent_start", async (event) => {
65
65
  if (ruleFiles.length === 0) {
66
66
  return;
67
67
  }
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * Commands Extension
3
3
  *
4
- * Demonstrates the pi.getCommands() API by providing a /commands command
4
+ * Demonstrates the elyra.getCommands() API by providing a /commands command
5
5
  * that lists all available slash commands in the current session.
6
6
  *
7
7
  * Usage:
@@ -12,8 +12,8 @@
12
12
 
13
13
  import type { ExtensionAPI, SlashCommandInfo } from "@elyracode/coding-agent";
14
14
 
15
- export default function commandsExtension(pi: ExtensionAPI) {
16
- pi.registerCommand("commands", {
15
+ export default function commandsExtension(elyra: ExtensionAPI) {
16
+ elyra.registerCommand("commands", {
17
17
  description: "List available slash commands",
18
18
  getArgumentCompletions: (prefix) => {
19
19
  const sources = ["extension", "prompt", "skill"];
@@ -21,7 +21,7 @@ export default function commandsExtension(pi: ExtensionAPI) {
21
21
  return filtered.length > 0 ? filtered.map((s) => ({ value: s, label: s })) : null;
22
22
  },
23
23
  handler: async (args, ctx) => {
24
- const commands = pi.getCommands();
24
+ const commands = elyra.getCommands();
25
25
  const sourceFilter = args.trim() as "extension" | "prompt" | "skill" | "";
26
26
 
27
27
  // Filter by source if specified
@@ -7,8 +7,8 @@
7
7
 
8
8
  import type { ExtensionAPI, SessionBeforeSwitchEvent, SessionMessageEntry } from "@elyracode/coding-agent";
9
9
 
10
- export default function (pi: ExtensionAPI) {
11
- pi.on("session_before_switch", async (event: SessionBeforeSwitchEvent, ctx) => {
10
+ export default function (elyra: ExtensionAPI) {
11
+ elyra.on("session_before_switch", async (event: SessionBeforeSwitchEvent, ctx) => {
12
12
  if (!ctx.hasUI) return;
13
13
 
14
14
  if (event.reason === "new") {
@@ -43,7 +43,7 @@ export default function (pi: ExtensionAPI) {
43
43
  }
44
44
  });
45
45
 
46
- pi.on("session_before_fork", async (event, ctx) => {
46
+ elyra.on("session_before_fork", async (event, ctx) => {
47
47
  if (!ctx.hasUI) return;
48
48
 
49
49
  const choice = await ctx.ui.select(`Fork from entry ${event.entryId.slice(0, 8)}?`, [
@@ -17,8 +17,8 @@ import { complete } from "@elyracode/ai";
17
17
  import type { ExtensionAPI } from "@elyracode/coding-agent";
18
18
  import { convertToLlm, serializeConversation } from "@elyracode/coding-agent";
19
19
 
20
- export default function (pi: ExtensionAPI) {
21
- pi.on("session_before_compact", async (event, ctx) => {
20
+ export default function (elyra: ExtensionAPI) {
21
+ elyra.on("session_before_compact", async (event, ctx) => {
22
22
  ctx.ui.notify("Custom compaction extension triggered", "info");
23
23
 
24
24
  const { preparation, branchEntries: _, signal } = event;
@@ -12,10 +12,10 @@ import type { AssistantMessage } from "@elyracode/ai";
12
12
  import type { ExtensionAPI } from "@elyracode/coding-agent";
13
13
  import { truncateToWidth, visibleWidth } from "@elyracode/tui";
14
14
 
15
- export default function (pi: ExtensionAPI) {
15
+ export default function (elyra: ExtensionAPI) {
16
16
  let enabled = false;
17
17
 
18
- pi.registerCommand("footer", {
18
+ elyra.registerCommand("footer", {
19
19
  description: "Toggle custom footer",
20
20
  handler: async (_args, ctx) => {
21
21
  enabled = !enabled;
@@ -44,9 +44,9 @@ function getElyraMascot(theme: Theme): string[] {
44
44
  return ["", lineEyes, lineBar, lineLeg, lineLeg, lineLeg, lineLeg, ""];
45
45
  }
46
46
 
47
- export default function (pi: ExtensionAPI) {
47
+ export default function (elyra: ExtensionAPI) {
48
48
  // Set custom header immediately on load (if UI is available)
49
- pi.on("session_start", async (_event, ctx) => {
49
+ elyra.on("session_start", async (_event, ctx) => {
50
50
  if (ctx.hasUI) {
51
51
  ctx.ui.setHeader((_tui, theme) => {
52
52
  return {
@@ -63,7 +63,7 @@ export default function (pi: ExtensionAPI) {
63
63
  });
64
64
 
65
65
  // Command to restore built-in header
66
- pi.registerCommand("builtin-header", {
66
+ elyra.registerCommand("builtin-header", {
67
67
  description: "Restore built-in header with keybinding hints",
68
68
  handler: async (_args, ctx) => {
69
69
  ctx.ui.setHeader(undefined);
@@ -565,8 +565,8 @@ function streamCustomAnthropic(
565
565
  // Extension Entry Point
566
566
  // =============================================================================
567
567
 
568
- export default function (pi: ExtensionAPI) {
569
- pi.registerProvider("custom-anthropic", {
568
+ export default function (elyra: ExtensionAPI) {
569
+ elyra.registerProvider("custom-anthropic", {
570
570
  baseUrl: "https://api.anthropic.com",
571
571
  apiKey: "CUSTOM_ANTHROPIC_API_KEY",
572
572
  api: "custom-anthropic-api",
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "elyra-extension-custom-provider-anthropic",
3
3
  "private": true,
4
- "version": "0.2.0",
5
- "type": "module",
4
+ "version": "0.3.0",
5
+ "type": "module",
6
6
  "scripts": {
7
7
  "clean": "echo 'nothing to clean'",
8
8
  "build": "echo 'nothing to build'",
@@ -324,8 +324,8 @@ export function streamGitLabDuo(
324
324
  // Extension Entry Point
325
325
  // =============================================================================
326
326
 
327
- export default function (pi: ExtensionAPI) {
328
- pi.registerProvider("gitlab-duo", {
327
+ export default function (elyra: ExtensionAPI) {
328
+ elyra.registerProvider("gitlab-duo", {
329
329
  baseUrl: AI_GATEWAY_URL,
330
330
  apiKey: "GITLAB_TOKEN",
331
331
  api: "gitlab-duo-api",
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "elyra-extension-custom-provider-gitlab-duo",
3
3
  "private": true,
4
- "version": "0.2.0",
5
- "type": "module",
4
+ "version": "0.3.0",
5
+ "type": "module",
6
6
  "scripts": {
7
7
  "clean": "echo 'nothing to clean'",
8
8
  "build": "echo 'nothing to build'",
@@ -8,12 +8,12 @@
8
8
  import type { ExtensionAPI, ExtensionContext } from "@elyracode/coding-agent";
9
9
 
10
10
  async function checkDirtyRepo(
11
- pi: ExtensionAPI,
11
+ elyra: ExtensionAPI,
12
12
  ctx: ExtensionContext,
13
13
  action: string,
14
14
  ): Promise<{ cancel: boolean } | undefined> {
15
15
  // Check for uncommitted changes
16
- const { stdout, code } = await pi.exec("git", ["status", "--porcelain"]);
16
+ const { stdout, code } = await elyra.exec("git", ["status", "--porcelain"]);
17
17
 
18
18
  if (code !== 0) {
19
19
  // Not a git repo, allow the action
@@ -44,13 +44,13 @@ async function checkDirtyRepo(
44
44
  }
45
45
  }
46
46
 
47
- export default function (pi: ExtensionAPI) {
48
- pi.on("session_before_switch", async (event, ctx) => {
47
+ export default function (elyra: ExtensionAPI) {
48
+ elyra.on("session_before_switch", async (event, ctx) => {
49
49
  const action = event.reason === "new" ? "new session" : "switch session";
50
- return checkDirtyRepo(pi, ctx, action);
50
+ return checkDirtyRepo(elyra, ctx, action);
51
51
  });
52
52
 
53
- pi.on("session_before_fork", async (_event, ctx) => {
54
- return checkDirtyRepo(pi, ctx, "fork");
53
+ elyra.on("session_before_fork", async (_event, ctx) => {
54
+ return checkDirtyRepo(elyra, ctx, "fork");
55
55
  });
56
56
  }
@@ -18,8 +18,8 @@ import { ensureWadFile } from "./wad-finder.js";
18
18
  let activeEngine: DoomEngine | null = null;
19
19
  let activeWadPath: string | null = null;
20
20
 
21
- export default function (pi: ExtensionAPI) {
22
- pi.registerCommand("doom-overlay", {
21
+ export default function (elyra: ExtensionAPI) {
22
+ elyra.registerCommand("doom-overlay", {
23
23
  description: "Play DOOM as an overlay. Q to pause and exit.",
24
24
 
25
25
  handler: async (args, ctx) => {
@@ -4,8 +4,8 @@ import type { ExtensionAPI } from "@elyracode/coding-agent";
4
4
 
5
5
  const baseDir = dirname(fileURLToPath(import.meta.url));
6
6
 
7
- export default function (pi: ExtensionAPI) {
8
- pi.on("resources_discover", () => {
7
+ export default function (elyra: ExtensionAPI) {
8
+ elyra.on("resources_discover", () => {
9
9
  return {
10
10
  skillPaths: [join(baseDir, "SKILL.md")],
11
11
  promptPaths: [join(baseDir, "dynamic.md")],