@elyracode/coding-agent 0.2.0 → 0.3.1

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 +17 -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
@@ -21,7 +21,7 @@ function normalizeToolName(input: string): string | undefined {
21
21
  return trimmed;
22
22
  }
23
23
 
24
- export default function dynamicToolsExtension(pi: ExtensionAPI) {
24
+ export default function dynamicToolsExtension(elyra: ExtensionAPI) {
25
25
  const registeredToolNames = new Set<string>();
26
26
 
27
27
  const registerEchoTool = (name: string, label: string, prefix: string): boolean => {
@@ -30,7 +30,7 @@ export default function dynamicToolsExtension(pi: ExtensionAPI) {
30
30
  }
31
31
 
32
32
  registeredToolNames.add(name);
33
- pi.registerTool({
33
+ elyra.registerTool({
34
34
  name,
35
35
  label,
36
36
  description: `Echo a message with prefix: ${prefix}`,
@@ -48,12 +48,12 @@ export default function dynamicToolsExtension(pi: ExtensionAPI) {
48
48
  return true;
49
49
  };
50
50
 
51
- pi.on("session_start", (_event, ctx) => {
51
+ elyra.on("session_start", (_event, ctx) => {
52
52
  registerEchoTool("echo_session", "Echo Session", "[session] ");
53
53
  ctx.ui.notify("Registered dynamic tool: echo_session", "info");
54
54
  });
55
55
 
56
- pi.registerCommand("add-echo-tool", {
56
+ elyra.registerCommand("add-echo-tool", {
57
57
  description: "Register a new echo tool dynamically: /add-echo-tool <tool_name>",
58
58
  handler: async (args, ctx) => {
59
59
  const toolName = normalizeToolName(args);
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * Inter-extension event bus example.
3
3
  *
4
- * Shows pi.events for communication between extensions. One extension
4
+ * Shows elyra.events for communication between extensions. One extension
5
5
  * can emit events that other extensions listen to.
6
6
  *
7
7
  * Usage: /emit [event-name] [data] - emit an event on the bus
@@ -9,33 +9,33 @@
9
9
 
10
10
  import type { ExtensionAPI, ExtensionContext } from "@elyracode/coding-agent";
11
11
 
12
- export default function (pi: ExtensionAPI) {
12
+ export default function (elyra: ExtensionAPI) {
13
13
  // Store ctx for use in event handler
14
14
  let currentCtx: ExtensionContext | undefined;
15
15
 
16
- pi.on("session_start", async (_event, ctx) => {
16
+ elyra.on("session_start", async (_event, ctx) => {
17
17
  currentCtx = ctx;
18
18
  });
19
19
 
20
20
  // Listen for events from other extensions
21
- pi.events.on("my:notification", (data) => {
21
+ elyra.events.on("my:notification", (data) => {
22
22
  const { message, from } = data as { message: string; from: string };
23
23
  currentCtx?.ui.notify(`Event from ${from}: ${message}`, "info");
24
24
  });
25
25
 
26
26
  // Command to emit events (emits "my:notification" which the listener above receives)
27
- pi.registerCommand("emit", {
27
+ elyra.registerCommand("emit", {
28
28
  description: "Emit my:notification event (usage: /emit message)",
29
29
  handler: async (args, _ctx) => {
30
30
  const message = args.trim() || "hello";
31
- pi.events.emit("my:notification", { message, from: "/emit command" });
31
+ elyra.events.emit("my:notification", { message, from: "/emit command" });
32
32
  // Listener above will show the notification
33
33
  },
34
34
  });
35
35
 
36
36
  // Example: emit on session start
37
- pi.on("session_start", async () => {
38
- pi.events.emit("my:notification", {
37
+ elyra.on("session_start", async () => {
38
+ elyra.events.emit("my:notification", {
39
39
  message: "Session started",
40
40
  from: "event-bus-example",
41
41
  });
@@ -11,15 +11,15 @@
11
11
  import * as fs from "node:fs";
12
12
  import type { ExtensionAPI } from "@elyracode/coding-agent";
13
13
 
14
- export default function (pi: ExtensionAPI) {
15
- pi.on("session_start", async (_event, ctx) => {
14
+ export default function (elyra: ExtensionAPI) {
15
+ elyra.on("session_start", async (_event, ctx) => {
16
16
  const triggerFile = "/tmp/agent-trigger.txt";
17
17
 
18
18
  fs.watch(triggerFile, () => {
19
19
  try {
20
20
  const content = fs.readFileSync(triggerFile, "utf-8").trim();
21
21
  if (content) {
22
- pi.sendMessage(
22
+ elyra.sendMessage(
23
23
  {
24
24
  customType: "file-trigger",
25
25
  content: `External trigger: ${content}`,
@@ -7,26 +7,26 @@
7
7
 
8
8
  import type { ExtensionAPI } from "@elyracode/coding-agent";
9
9
 
10
- export default function (pi: ExtensionAPI) {
10
+ export default function (elyra: ExtensionAPI) {
11
11
  const checkpoints = new Map<string, string>();
12
12
  let currentEntryId: string | undefined;
13
13
 
14
14
  // Track the current entry ID when user messages are saved
15
- pi.on("tool_result", async (_event, ctx) => {
15
+ elyra.on("tool_result", async (_event, ctx) => {
16
16
  const leaf = ctx.sessionManager.getLeafEntry();
17
17
  if (leaf) currentEntryId = leaf.id;
18
18
  });
19
19
 
20
- pi.on("turn_start", async () => {
20
+ elyra.on("turn_start", async () => {
21
21
  // Create a git stash entry before LLM makes changes
22
- const { stdout } = await pi.exec("git", ["stash", "create"]);
22
+ const { stdout } = await elyra.exec("git", ["stash", "create"]);
23
23
  const ref = stdout.trim();
24
24
  if (ref && currentEntryId) {
25
25
  checkpoints.set(currentEntryId, ref);
26
26
  }
27
27
  });
28
28
 
29
- pi.on("session_before_fork", async (event, ctx) => {
29
+ elyra.on("session_before_fork", async (event, ctx) => {
30
30
  const ref = checkpoints.get(event.entryId);
31
31
  if (!ref) return;
32
32
 
@@ -41,12 +41,12 @@ export default function (pi: ExtensionAPI) {
41
41
  ]);
42
42
 
43
43
  if (choice?.startsWith("Yes")) {
44
- await pi.exec("git", ["stash", "apply", ref]);
44
+ await elyra.exec("git", ["stash", "apply", ref]);
45
45
  ctx.ui.notify("Code restored to checkpoint", "info");
46
46
  }
47
47
  });
48
48
 
49
- pi.on("agent_end", async () => {
49
+ elyra.on("agent_end", async () => {
50
50
  // Clear checkpoints after agent completes
51
51
  checkpoints.clear();
52
52
  });
@@ -39,8 +39,8 @@ function parseGitHubRepo(remoteUrl: string): string | undefined {
39
39
  return undefined;
40
40
  }
41
41
 
42
- async function resolveGitHubRepo(pi: ExtensionAPI, cwd: string): Promise<RepoResolution> {
43
- const result = await pi.exec("git", ["remote", "-v"], { cwd, timeout: 5_000 });
42
+ async function resolveGitHubRepo(elyra: ExtensionAPI, cwd: string): Promise<RepoResolution> {
43
+ const result = await elyra.exec("git", ["remote", "-v"], { cwd, timeout: 5_000 });
44
44
  if (result.code !== 0) {
45
45
  return { ok: false, error: "github-issue-autocomplete: cwd is not a git repository" };
46
46
  }
@@ -127,9 +127,9 @@ function createIssueAutocompleteProvider(
127
127
  };
128
128
  }
129
129
 
130
- export default function (pi: ExtensionAPI): void {
131
- pi.on("session_start", async (_event, ctx) => {
132
- const resolvedRepo = await resolveGitHubRepo(pi, ctx.cwd);
130
+ export default function (elyra: ExtensionAPI): void {
131
+ elyra.on("session_start", async (_event, ctx) => {
132
+ const resolvedRepo = await resolveGitHubRepo(elyra, ctx.cwd);
133
133
  if (!resolvedRepo.ok) {
134
134
  ctx.ui.notify(resolvedRepo.error, "error");
135
135
  return;
@@ -141,7 +141,7 @@ export default function (pi: ExtensionAPI): void {
141
141
 
142
142
  const getIssues = async (): Promise<GitHubIssue[] | undefined> => {
143
143
  issuesPromise ||= (async () => {
144
- const result = await pi.exec(
144
+ const result = await elyra.exec(
145
145
  "gh",
146
146
  [
147
147
  "issue",
@@ -77,8 +77,8 @@ function getHandoffMessages(branch: SessionEntry[]): AgentMessage[] {
77
77
  return compactedBranch.map(entryToMessage).filter((message) => message !== undefined);
78
78
  }
79
79
 
80
- export default function (pi: ExtensionAPI) {
81
- pi.registerCommand("handoff", {
80
+ export default function (elyra: ExtensionAPI) {
81
+ elyra.registerCommand("handoff", {
82
82
  description: "Transfer context to a new focused session",
83
83
  handler: async (args, ctx) => {
84
84
  if (!ctx.hasUI) {
@@ -21,6 +21,6 @@ const helloTool = defineTool({
21
21
  },
22
22
  });
23
23
 
24
- export default function (pi: ExtensionAPI) {
25
- pi.registerTool(helloTool);
24
+ export default function (elyra: ExtensionAPI) {
25
+ elyra.registerTool(helloTool);
26
26
  }
@@ -22,18 +22,18 @@ import type { ExtensionAPI, ExtensionContext } from "@elyracode/coding-agent";
22
22
 
23
23
  const DEFAULT_LABEL = "Pondering...";
24
24
 
25
- export default function (pi: ExtensionAPI) {
25
+ export default function (elyra: ExtensionAPI) {
26
26
  let label = DEFAULT_LABEL;
27
27
 
28
28
  const applyLabel = (ctx: ExtensionContext) => {
29
29
  ctx.ui.setHiddenThinkingLabel(label);
30
30
  };
31
31
 
32
- pi.on("session_start", async (_event, ctx) => {
32
+ elyra.on("session_start", async (_event, ctx) => {
33
33
  applyLabel(ctx);
34
34
  });
35
35
 
36
- pi.registerCommand("thinking-label", {
36
+ elyra.registerCommand("thinking-label", {
37
37
  description: "Set the hidden thinking label. Use without args to reset.",
38
38
  handler: async (args, ctx) => {
39
39
  const nextLabel = args.trim();
@@ -16,11 +16,11 @@
16
16
  */
17
17
  import type { ExtensionAPI } from "@elyracode/coding-agent";
18
18
 
19
- export default function (pi: ExtensionAPI) {
19
+ export default function (elyra: ExtensionAPI) {
20
20
  const PATTERN = /!\{([^}]+)\}/g;
21
21
  const TIMEOUT_MS = 30000;
22
22
 
23
- pi.on("input", async (event, ctx) => {
23
+ elyra.on("input", async (event, ctx) => {
24
24
  const text = event.text;
25
25
 
26
26
  // Don't process if it's a whole-line bash command (starts with !)
@@ -51,7 +51,7 @@ export default function (pi: ExtensionAPI) {
51
51
  // Execute each command and collect results
52
52
  for (const { full, command } of matches) {
53
53
  try {
54
- const bashResult = await pi.exec("bash", ["-c", command], {
54
+ const bashResult = await elyra.exec("bash", ["-c", command], {
55
55
  timeout: TIMEOUT_MS,
56
56
  });
57
57
 
@@ -11,8 +11,8 @@
11
11
  */
12
12
  import type { ExtensionAPI } from "@elyracode/coding-agent";
13
13
 
14
- export default function (pi: ExtensionAPI) {
15
- pi.on("input", async (event, ctx) => {
14
+ export default function (elyra: ExtensionAPI) {
15
+ elyra.on("input", async (event, ctx) => {
16
16
  // Source-based logic: skip processing for extension-injected messages
17
17
  if (event.source === "extension") {
18
18
  return { action: "continue" };
@@ -128,8 +128,8 @@ function isInteractiveCommand(command: string): boolean {
128
128
  return false;
129
129
  }
130
130
 
131
- export default function (pi: ExtensionAPI) {
132
- pi.on("user_bash", async (event, ctx) => {
131
+ export default function (elyra: ExtensionAPI) {
132
+ elyra.on("user_bash", async (event, ctx) => {
133
133
  let command = event.command;
134
134
  let forceInteractive = false;
135
135
 
@@ -22,10 +22,10 @@ async function isDarkMode(): Promise<boolean> {
22
22
  }
23
23
  }
24
24
 
25
- export default function (pi: ExtensionAPI) {
25
+ export default function (elyra: ExtensionAPI) {
26
26
  let intervalId: ReturnType<typeof setInterval> | null = null;
27
27
 
28
- pi.on("session_start", async (_event, ctx) => {
28
+ elyra.on("session_start", async (_event, ctx) => {
29
29
  let currentTheme = (await isDarkMode()) ? "dark" : "light";
30
30
  ctx.ui.setTheme(currentTheme);
31
31
 
@@ -38,7 +38,7 @@ export default function (pi: ExtensionAPI) {
38
38
  }, 2000);
39
39
  });
40
40
 
41
- pi.on("session_shutdown", () => {
41
+ elyra.on("session_shutdown", () => {
42
42
  if (intervalId) {
43
43
  clearInterval(intervalId);
44
44
  intervalId = null;
@@ -10,9 +10,9 @@
10
10
  import type { ExtensionAPI } from "@elyracode/coding-agent";
11
11
  import { Box, Text } from "@elyracode/tui";
12
12
 
13
- export default function (pi: ExtensionAPI) {
13
+ export default function (elyra: ExtensionAPI) {
14
14
  // Register custom renderer for "status-update" messages
15
- pi.registerMessageRenderer("status-update", (message, { expanded }, theme) => {
15
+ elyra.registerMessageRenderer("status-update", (message, { expanded }, theme) => {
16
16
  const details = message.details as { level: string; timestamp: number } | undefined;
17
17
  const level = details?.level ?? "info";
18
18
 
@@ -35,7 +35,7 @@ export default function (pi: ExtensionAPI) {
35
35
  });
36
36
 
37
37
  // Command to send status messages
38
- pi.registerCommand("status", {
38
+ elyra.registerCommand("status", {
39
39
  description: "Send a status message (usage: /status [warn|error] message)",
40
40
  handler: async (args, _ctx) => {
41
41
  const parts = args.trim().split(/\s+/);
@@ -48,7 +48,7 @@ export default function (pi: ExtensionAPI) {
48
48
  content = parts.slice(1).join(" ") || "Status update";
49
49
  }
50
50
 
51
- pi.sendMessage({
51
+ elyra.sendMessage({
52
52
  customType: "status-update",
53
53
  content,
54
54
  display: true,
@@ -64,11 +64,11 @@ function getBuiltInTools(cwd: string) {
64
64
  return tools;
65
65
  }
66
66
 
67
- export default function (pi: ExtensionAPI) {
67
+ export default function (elyra: ExtensionAPI) {
68
68
  // =========================================================================
69
69
  // Read Tool
70
70
  // =========================================================================
71
- pi.registerTool({
71
+ elyra.registerTool({
72
72
  name: "read",
73
73
  label: "read",
74
74
  description:
@@ -115,7 +115,7 @@ export default function (pi: ExtensionAPI) {
115
115
  // =========================================================================
116
116
  // Bash Tool
117
117
  // =========================================================================
118
- pi.registerTool({
118
+ elyra.registerTool({
119
119
  name: "bash",
120
120
  label: "bash",
121
121
  description:
@@ -164,7 +164,7 @@ export default function (pi: ExtensionAPI) {
164
164
  // =========================================================================
165
165
  // Write Tool
166
166
  // =========================================================================
167
- pi.registerTool({
167
+ elyra.registerTool({
168
168
  name: "write",
169
169
  label: "write",
170
170
  description:
@@ -206,7 +206,7 @@ export default function (pi: ExtensionAPI) {
206
206
  // =========================================================================
207
207
  // Edit Tool
208
208
  // =========================================================================
209
- pi.registerTool({
209
+ elyra.registerTool({
210
210
  name: "edit",
211
211
  label: "edit",
212
212
  description:
@@ -251,7 +251,7 @@ export default function (pi: ExtensionAPI) {
251
251
  // =========================================================================
252
252
  // Find Tool
253
253
  // =========================================================================
254
- pi.registerTool({
254
+ elyra.registerTool({
255
255
  name: "find",
256
256
  label: "find",
257
257
  description:
@@ -309,7 +309,7 @@ export default function (pi: ExtensionAPI) {
309
309
  // =========================================================================
310
310
  // Grep Tool
311
311
  // =========================================================================
312
- pi.registerTool({
312
+ elyra.registerTool({
313
313
  name: "grep",
314
314
  label: "grep",
315
315
  description:
@@ -371,7 +371,7 @@ export default function (pi: ExtensionAPI) {
371
371
  // =========================================================================
372
372
  // Ls Tool
373
373
  // =========================================================================
374
- pi.registerTool({
374
+ elyra.registerTool({
375
375
  name: "ls",
376
376
  label: "ls",
377
377
  description:
@@ -78,8 +78,8 @@ class ModalEditor extends CustomEditor {
78
78
  }
79
79
  }
80
80
 
81
- export default function (pi: ExtensionAPI) {
82
- pi.on("session_start", (_event, ctx) => {
81
+ export default function (elyra: ExtensionAPI) {
82
+ elyra.on("session_start", (_event, ctx) => {
83
83
  ctx.ui.setEditorComponent((tui, theme, kb) => new ModalEditor(tui, theme, kb));
84
84
  });
85
85
  }
@@ -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.on("model_select", async (event, ctx) => {
12
+ export default function (elyra: ExtensionAPI) {
13
+ elyra.on("model_select", async (event, ctx) => {
14
14
  const { model, previousModel, source } = event;
15
15
 
16
16
  // Format model identifiers
@@ -48,8 +48,8 @@ function notify(title: string, body: string): void {
48
48
  }
49
49
  }
50
50
 
51
- export default function (pi: ExtensionAPI) {
52
- pi.on("agent_end", async () => {
51
+ export default function (elyra: ExtensionAPI) {
52
+ elyra.on("agent_end", async () => {
53
53
  notify("Elyra", "Ready for input");
54
54
  });
55
55
  }
@@ -27,9 +27,9 @@ import { spawn } from "child_process";
27
27
  // Global handle for toggle demo (in real code, use a more elegant pattern)
28
28
  let globalToggleHandle: OverlayHandle | null = null;
29
29
 
30
- export default function (pi: ExtensionAPI) {
30
+ export default function (elyra: ExtensionAPI) {
31
31
  // Animation demo - proves overlays can handle real-time updates (like elyra-doom would need)
32
- pi.registerCommand("overlay-animation", {
32
+ elyra.registerCommand("overlay-animation", {
33
33
  description: "Test real-time animation in overlay (~30 FPS)",
34
34
  handler: async (_args: string, ctx: ExtensionCommandContext) => {
35
35
  await ctx.ui.custom<void>((tui, theme, _kb, done) => new AnimationDemoComponent(tui, theme, done), {
@@ -40,7 +40,7 @@ export default function (pi: ExtensionAPI) {
40
40
  });
41
41
 
42
42
  // Test all 9 anchor positions
43
- pi.registerCommand("overlay-anchors", {
43
+ elyra.registerCommand("overlay-anchors", {
44
44
  description: "Cycle through all anchor positions",
45
45
  handler: async (_args: string, ctx: ExtensionCommandContext) => {
46
46
  const anchors: OverlayAnchor[] = [
@@ -78,7 +78,7 @@ export default function (pi: ExtensionAPI) {
78
78
  });
79
79
 
80
80
  // Test margins and offsets
81
- pi.registerCommand("overlay-margins", {
81
+ elyra.registerCommand("overlay-margins", {
82
82
  description: "Test margin and offset options",
83
83
  handler: async (_args: string, ctx: ExtensionCommandContext) => {
84
84
  const configs: { name: string; options: OverlayOptions }[] = [
@@ -112,7 +112,7 @@ export default function (pi: ExtensionAPI) {
112
112
  });
113
113
 
114
114
  // Test stacked overlays
115
- pi.registerCommand("overlay-stack", {
115
+ elyra.registerCommand("overlay-stack", {
116
116
  description: "Test stacked overlays",
117
117
  handler: async (_args: string, ctx: ExtensionCommandContext) => {
118
118
  // Three large overlays that overlap in the center area
@@ -156,7 +156,7 @@ export default function (pi: ExtensionAPI) {
156
156
  });
157
157
 
158
158
  // Test width overflow scenarios (original crash case) - streams real process output
159
- pi.registerCommand("overlay-overflow", {
159
+ elyra.registerCommand("overlay-overflow", {
160
160
  description: "Test width overflow with streaming process output",
161
161
  handler: async (_args: string, ctx: ExtensionCommandContext) => {
162
162
  await ctx.ui.custom<void>((tui, theme, _kb, done) => new StreamingOverflowComponent(tui, theme, done), {
@@ -167,7 +167,7 @@ export default function (pi: ExtensionAPI) {
167
167
  });
168
168
 
169
169
  // Test overlay at terminal edge
170
- pi.registerCommand("overlay-edge", {
170
+ elyra.registerCommand("overlay-edge", {
171
171
  description: "Test overlay positioned at terminal edge",
172
172
  handler: async (_args: string, ctx: ExtensionCommandContext) => {
173
173
  await ctx.ui.custom<void>((_tui, theme, _kb, done) => new EdgeTestComponent(theme, done), {
@@ -178,7 +178,7 @@ export default function (pi: ExtensionAPI) {
178
178
  });
179
179
 
180
180
  // Test percentage-based positioning
181
- pi.registerCommand("overlay-percent", {
181
+ elyra.registerCommand("overlay-percent", {
182
182
  description: "Test percentage-based positioning",
183
183
  handler: async (_args: string, ctx: ExtensionCommandContext) => {
184
184
  const configs = [
@@ -214,7 +214,7 @@ export default function (pi: ExtensionAPI) {
214
214
  });
215
215
 
216
216
  // Test maxHeight
217
- pi.registerCommand("overlay-maxheight", {
217
+ elyra.registerCommand("overlay-maxheight", {
218
218
  description: "Test maxHeight truncation",
219
219
  handler: async (_args: string, ctx: ExtensionCommandContext) => {
220
220
  await ctx.ui.custom<void>((_tui, theme, _kb, done) => new MaxHeightTestComponent(theme, done), {
@@ -225,7 +225,7 @@ export default function (pi: ExtensionAPI) {
225
225
  });
226
226
 
227
227
  // Test responsive sidepanel - only shows when terminal is wide enough
228
- pi.registerCommand("overlay-sidepanel", {
228
+ elyra.registerCommand("overlay-sidepanel", {
229
229
  description: "Test responsive sidepanel (hides when terminal < 100 cols)",
230
230
  handler: async (_args: string, ctx: ExtensionCommandContext) => {
231
231
  await ctx.ui.custom<void>((tui, theme, _kb, done) => new SidepanelComponent(tui, theme, done), {
@@ -243,7 +243,7 @@ export default function (pi: ExtensionAPI) {
243
243
  });
244
244
 
245
245
  // Test toggle overlay - demonstrates OverlayHandle.setHidden() via onHandle callback
246
- pi.registerCommand("overlay-toggle", {
246
+ elyra.registerCommand("overlay-toggle", {
247
247
  description: "Test overlay toggle (press 't' to toggle visibility)",
248
248
  handler: async (_args: string, ctx: ExtensionCommandContext) => {
249
249
  await ctx.ui.custom<void>((tui, theme, _kb, done) => new ToggleDemoComponent(tui, theme, done), {
@@ -261,7 +261,7 @@ export default function (pi: ExtensionAPI) {
261
261
  });
262
262
 
263
263
  // Non-capturing overlay demo - passive info panel that doesn't steal focus
264
- pi.registerCommand("overlay-passive", {
264
+ elyra.registerCommand("overlay-passive", {
265
265
  description: "Test non-capturing overlay (passive info panel alongside active overlay)",
266
266
  handler: async (_args: string, ctx: ExtensionCommandContext) => {
267
267
  ctx.ui.setEditorText("");
@@ -273,7 +273,7 @@ export default function (pi: ExtensionAPI) {
273
273
  });
274
274
 
275
275
  // Focus cycling demo - demonstrates focus(), unfocus(), isFocused() and rendering order
276
- pi.registerCommand("overlay-focus", {
276
+ elyra.registerCommand("overlay-focus", {
277
277
  description: "Test focus cycling and rendering order with non-capturing overlays",
278
278
  handler: async (_args: string, ctx: ExtensionCommandContext) => {
279
279
  ctx.ui.setEditorText("");
@@ -285,7 +285,7 @@ export default function (pi: ExtensionAPI) {
285
285
  });
286
286
 
287
287
  // Test multiple input panels with simulated streaming
288
- pi.registerCommand("overlay-streaming", {
288
+ elyra.registerCommand("overlay-streaming", {
289
289
  description: "Multiple input panels with simulated streaming (Tab to cycle focus)",
290
290
  handler: async (_args: string, ctx: ExtensionCommandContext) => {
291
291
  ctx.ui.setEditorText("");
@@ -11,8 +11,8 @@
11
11
  import type { ExtensionAPI, ExtensionCommandContext, Theme } from "@elyracode/coding-agent";
12
12
  import { CURSOR_MARKER, type Focusable, matchesKey, visibleWidth } from "@elyracode/tui";
13
13
 
14
- export default function (pi: ExtensionAPI) {
15
- pi.registerCommand("overlay-test", {
14
+ export default function (elyra: ExtensionAPI) {
15
+ elyra.registerCommand("overlay-test", {
16
16
  description: "Test overlay rendering with edge cases",
17
17
  handler: async (_args: string, ctx: ExtensionCommandContext) => {
18
18
  const result = await ctx.ui.custom<{ action: string; query?: string } | undefined>(
@@ -7,10 +7,10 @@
7
7
 
8
8
  import type { ExtensionAPI } from "@elyracode/coding-agent";
9
9
 
10
- export default function (pi: ExtensionAPI) {
10
+ export default function (elyra: ExtensionAPI) {
11
11
  const dangerousPatterns = [/\brm\s+(-rf?|--recursive)/i, /\bsudo\b/i, /\b(chmod|chown)\b.*777/i];
12
12
 
13
- pi.on("tool_call", async (event, ctx) => {
13
+ elyra.on("tool_call", async (event, ctx) => {
14
14
  if (event.toolName !== "bash") return undefined;
15
15
 
16
16
  const command = event.input.command as string;
@@ -12,11 +12,11 @@
12
12
 
13
13
  import type { ExtensionAPI } from "@elyracode/coding-agent";
14
14
 
15
- export default function pirateExtension(pi: ExtensionAPI) {
15
+ export default function pirateExtension(elyra: ExtensionAPI) {
16
16
  let pirateMode = false;
17
17
 
18
18
  // Register /pirate command to toggle pirate mode
19
- pi.registerCommand("pirate", {
19
+ elyra.registerCommand("pirate", {
20
20
  description: "Toggle pirate mode (agent speaks like a pirate)",
21
21
  handler: async (_args, ctx) => {
22
22
  pirateMode = !pirateMode;
@@ -25,7 +25,7 @@ export default function pirateExtension(pi: ExtensionAPI) {
25
25
  });
26
26
 
27
27
  // Append to system prompt when pirate mode is enabled
28
- pi.on("before_agent_start", async (event) => {
28
+ elyra.on("before_agent_start", async (event) => {
29
29
  if (pirateMode) {
30
30
  return {
31
31
  systemPrompt: