@elyracode/coding-agent 0.1.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 (177) 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-runtime.d.ts +1 -0
  11. package/dist/core/agent-session-runtime.d.ts.map +1 -1
  12. package/dist/core/agent-session-runtime.js +35 -0
  13. package/dist/core/agent-session-runtime.js.map +1 -1
  14. package/dist/core/agent-session.d.ts +7 -1
  15. package/dist/core/agent-session.d.ts.map +1 -1
  16. package/dist/core/agent-session.js +55 -3
  17. package/dist/core/agent-session.js.map +1 -1
  18. package/dist/core/bash-executor.d.ts.map +1 -1
  19. package/dist/core/bash-executor.js +1 -1
  20. package/dist/core/bash-executor.js.map +1 -1
  21. package/dist/core/compaction/branch-summarization.d.ts.map +1 -1
  22. package/dist/core/compaction/branch-summarization.js +1 -1
  23. package/dist/core/compaction/branch-summarization.js.map +1 -1
  24. package/dist/core/compaction/compaction.d.ts.map +1 -1
  25. package/dist/core/compaction/compaction.js +1 -1
  26. package/dist/core/compaction/compaction.js.map +1 -1
  27. package/dist/core/extensions/loader.d.ts.map +1 -1
  28. package/dist/core/extensions/loader.js +3 -3
  29. package/dist/core/extensions/loader.js.map +1 -1
  30. package/dist/core/extensions/runner.d.ts.map +1 -1
  31. package/dist/core/extensions/runner.js +1 -1
  32. package/dist/core/extensions/runner.js.map +1 -1
  33. package/dist/core/extensions/types.d.ts +9 -9
  34. package/dist/core/extensions/types.d.ts.map +1 -1
  35. package/dist/core/extensions/types.js.map +1 -1
  36. package/dist/core/memory.d.ts +23 -0
  37. package/dist/core/memory.d.ts.map +1 -0
  38. package/dist/core/memory.js +173 -0
  39. package/dist/core/memory.js.map +1 -0
  40. package/dist/core/package-manager.d.ts.map +1 -1
  41. package/dist/core/package-manager.js +12 -12
  42. package/dist/core/package-manager.js.map +1 -1
  43. package/dist/core/session-manager.d.ts +6 -6
  44. package/dist/core/session-manager.d.ts.map +1 -1
  45. package/dist/core/session-manager.js +4 -4
  46. package/dist/core/session-manager.js.map +1 -1
  47. package/dist/core/settings-manager.d.ts +6 -0
  48. package/dist/core/settings-manager.d.ts.map +1 -1
  49. package/dist/core/settings-manager.js +16 -0
  50. package/dist/core/settings-manager.js.map +1 -1
  51. package/dist/core/smart-router.d.ts +43 -0
  52. package/dist/core/smart-router.d.ts.map +1 -0
  53. package/dist/core/smart-router.js +206 -0
  54. package/dist/core/smart-router.js.map +1 -0
  55. package/dist/core/stack-detector.d.ts +21 -0
  56. package/dist/core/stack-detector.d.ts.map +1 -0
  57. package/dist/core/stack-detector.js +120 -0
  58. package/dist/core/stack-detector.js.map +1 -0
  59. package/dist/core/system-prompt.d.ts +4 -0
  60. package/dist/core/system-prompt.d.ts.map +1 -1
  61. package/dist/core/system-prompt.js +27 -1
  62. package/dist/core/system-prompt.js.map +1 -1
  63. package/dist/core/tools/bash.d.ts +2 -2
  64. package/dist/core/tools/bash.d.ts.map +1 -1
  65. package/dist/core/tools/bash.js +3 -3
  66. package/dist/core/tools/bash.js.map +1 -1
  67. package/dist/core/tools/output-accumulator.d.ts.map +1 -1
  68. package/dist/core/tools/output-accumulator.js +1 -1
  69. package/dist/core/tools/output-accumulator.js.map +1 -1
  70. package/dist/migrations.d.ts.map +1 -1
  71. package/dist/migrations.js +1 -1
  72. package/dist/migrations.js.map +1 -1
  73. package/dist/modes/interactive/components/settings-selector.d.ts +4 -0
  74. package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
  75. package/dist/modes/interactive/components/settings-selector.js +20 -0
  76. package/dist/modes/interactive/components/settings-selector.js.map +1 -1
  77. package/dist/modes/interactive/interactive-mode.d.ts +1 -0
  78. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  79. package/dist/modes/interactive/interactive-mode.js +26 -0
  80. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  81. package/dist/package-manager-cli.d.ts.map +1 -1
  82. package/dist/package-manager-cli.js +10 -10
  83. package/dist/package-manager-cli.js.map +1 -1
  84. package/dist/utils/clipboard-image.d.ts.map +1 -1
  85. package/dist/utils/clipboard-image.js +1 -1
  86. package/dist/utils/clipboard-image.js.map +1 -1
  87. package/docs/extensions.md +17 -17
  88. package/docs/index.md +1 -1
  89. package/docs/prompt-templates.md +1 -1
  90. package/docs/providers.md +1 -1
  91. package/docs/quickstart.md +5 -5
  92. package/docs/rpc.md +6 -6
  93. package/docs/sdk.md +2 -2
  94. package/docs/session-format.md +3 -3
  95. package/docs/settings.md +4 -4
  96. package/docs/skills.md +2 -2
  97. package/docs/termux.md +3 -3
  98. package/docs/themes.md +1 -1
  99. package/docs/tui.md +1 -1
  100. package/docs/usage.md +2 -2
  101. package/examples/extensions/auto-commit-on-exit.ts +5 -5
  102. package/examples/extensions/bash-spawn-hook.ts +2 -2
  103. package/examples/extensions/bookmark.ts +5 -5
  104. package/examples/extensions/border-status-editor.ts +7 -7
  105. package/examples/extensions/built-in-tool-renderer.ts +5 -5
  106. package/examples/extensions/claude-rules.ts +3 -3
  107. package/examples/extensions/commands.ts +4 -4
  108. package/examples/extensions/confirm-destructive.ts +3 -3
  109. package/examples/extensions/custom-compaction.ts +2 -2
  110. package/examples/extensions/custom-footer.ts +2 -2
  111. package/examples/extensions/custom-header.ts +3 -3
  112. package/examples/extensions/custom-provider-anthropic/index.ts +2 -2
  113. package/examples/extensions/custom-provider-anthropic/package.json +2 -2
  114. package/examples/extensions/custom-provider-gitlab-duo/index.ts +2 -2
  115. package/examples/extensions/custom-provider-gitlab-duo/package.json +2 -2
  116. package/examples/extensions/dirty-repo-guard.ts +7 -7
  117. package/examples/extensions/doom-overlay/index.ts +2 -2
  118. package/examples/extensions/dynamic-resources/index.ts +2 -2
  119. package/examples/extensions/dynamic-tools.ts +4 -4
  120. package/examples/extensions/event-bus.ts +8 -8
  121. package/examples/extensions/file-trigger.ts +3 -3
  122. package/examples/extensions/git-checkpoint.ts +7 -7
  123. package/examples/extensions/github-issue-autocomplete.ts +6 -6
  124. package/examples/extensions/handoff.ts +2 -2
  125. package/examples/extensions/hello.ts +2 -2
  126. package/examples/extensions/hidden-thinking-label.ts +3 -3
  127. package/examples/extensions/inline-bash.ts +3 -3
  128. package/examples/extensions/input-transform.ts +2 -2
  129. package/examples/extensions/interactive-shell.ts +2 -2
  130. package/examples/extensions/mac-system-theme.ts +3 -3
  131. package/examples/extensions/message-renderer.ts +4 -4
  132. package/examples/extensions/minimal-mode.ts +8 -8
  133. package/examples/extensions/modal-editor.ts +2 -2
  134. package/examples/extensions/model-status.ts +2 -2
  135. package/examples/extensions/notify.ts +2 -2
  136. package/examples/extensions/overlay-qa-tests.ts +14 -14
  137. package/examples/extensions/overlay-test.ts +2 -2
  138. package/examples/extensions/permission-gate.ts +2 -2
  139. package/examples/extensions/pirate.ts +3 -3
  140. package/examples/extensions/plan-mode/index.ts +22 -22
  141. package/examples/extensions/preset.ts +23 -23
  142. package/examples/extensions/prompt-customizer.ts +2 -2
  143. package/examples/extensions/protected-paths.ts +2 -2
  144. package/examples/extensions/provider-payload.ts +3 -3
  145. package/examples/extensions/qna.ts +2 -2
  146. package/examples/extensions/question.ts +2 -2
  147. package/examples/extensions/questionnaire.ts +2 -2
  148. package/examples/extensions/rainbow-editor.ts +2 -2
  149. package/examples/extensions/reload-runtime.ts +4 -4
  150. package/examples/extensions/rpc-demo.ts +10 -10
  151. package/examples/extensions/sandbox/index.ts +8 -8
  152. package/examples/extensions/sandbox/package.json +2 -2
  153. package/examples/extensions/send-user-message.ts +13 -13
  154. package/examples/extensions/session-name.ts +4 -4
  155. package/examples/extensions/shutdown-command.ts +10 -10
  156. package/examples/extensions/snake.ts +3 -3
  157. package/examples/extensions/space-invaders.ts +3 -3
  158. package/examples/extensions/ssh.ts +10 -10
  159. package/examples/extensions/status-line.ts +4 -4
  160. package/examples/extensions/structured-output.ts +2 -2
  161. package/examples/extensions/subagent/index.ts +3 -3
  162. package/examples/extensions/summarize.ts +2 -2
  163. package/examples/extensions/system-prompt-header.ts +3 -3
  164. package/examples/extensions/tic-tac-toe.ts +15 -15
  165. package/examples/extensions/timed-confirm.ts +4 -4
  166. package/examples/extensions/titlebar-spinner.ts +8 -8
  167. package/examples/extensions/todo.ts +5 -5
  168. package/examples/extensions/tool-override.ts +3 -3
  169. package/examples/extensions/tools.ts +9 -9
  170. package/examples/extensions/trigger-compact.ts +3 -3
  171. package/examples/extensions/truncated-tool.ts +3 -3
  172. package/examples/extensions/widget-placement.ts +2 -2
  173. package/examples/extensions/with-deps/index.ts +2 -2
  174. package/examples/extensions/with-deps/package.json +2 -2
  175. package/examples/extensions/working-indicator.ts +5 -5
  176. package/examples/extensions/working-message-test.ts +2 -2
  177. package/package.json +5 -5
@@ -9,17 +9,17 @@
9
9
 
10
10
  import type { ExtensionAPI } from "@elyracode/coding-agent";
11
11
 
12
- export default function (pi: ExtensionAPI) {
13
- pi.registerCommand("session-name", {
12
+ export default function (elyra: ExtensionAPI) {
13
+ elyra.registerCommand("session-name", {
14
14
  description: "Set or show session name (usage: /session-name [new name])",
15
15
  handler: async (args, ctx) => {
16
16
  const name = args.trim();
17
17
 
18
18
  if (name) {
19
- pi.setSessionName(name);
19
+ elyra.setSessionName(name);
20
20
  ctx.ui.notify(`Session named: ${name}`, "info");
21
21
  } else {
22
- const current = pi.getSessionName();
22
+ const current = elyra.getSessionName();
23
23
  ctx.ui.notify(current ? `Session: ${current}` : "No session name set", "info");
24
24
  }
25
25
  },
@@ -2,26 +2,26 @@
2
2
  * Shutdown Command Extension
3
3
  *
4
4
  * Adds a /quit command that allows extensions to trigger clean shutdown.
5
- * Demonstrates how extensions can use ctx.shutdown() to exit pi cleanly.
5
+ * Demonstrates how extensions can use ctx.shutdown() to exit elyra cleanly.
6
6
  */
7
7
 
8
8
  import type { ExtensionAPI } from "@elyracode/coding-agent";
9
9
  import { Type } from "typebox";
10
10
 
11
- export default function (pi: ExtensionAPI) {
12
- // Register a /quit command that cleanly exits pi
13
- pi.registerCommand("quit", {
14
- description: "Exit pi cleanly",
11
+ export default function (elyra: ExtensionAPI) {
12
+ // Register a /quit command that cleanly exits elyra
13
+ elyra.registerCommand("quit", {
14
+ description: "Exit elyra cleanly",
15
15
  handler: async (_args, ctx) => {
16
16
  ctx.shutdown();
17
17
  },
18
18
  });
19
19
 
20
20
  // You can also create a tool that shuts down after completing work
21
- pi.registerTool({
21
+ elyra.registerTool({
22
22
  name: "finish_and_exit",
23
23
  label: "Finish and Exit",
24
- description: "Complete a task and exit pi",
24
+ description: "Complete a task and exit elyra",
25
25
  parameters: Type.Object({}),
26
26
  async execute(_toolCallId, _params, _signal, _onUpdate, ctx) {
27
27
  // Do any final work here...
@@ -37,10 +37,10 @@ export default function (pi: ExtensionAPI) {
37
37
  });
38
38
 
39
39
  // You could also create a more complex tool with parameters
40
- pi.registerTool({
40
+ elyra.registerTool({
41
41
  name: "deploy_and_exit",
42
42
  label: "Deploy and Exit",
43
- description: "Deploy the application and exit pi",
43
+ description: "Deploy the application and exit elyra",
44
44
  parameters: Type.Object({
45
45
  environment: Type.String({ description: "Target environment (e.g., production, staging)" }),
46
46
  }),
@@ -48,7 +48,7 @@ export default function (pi: ExtensionAPI) {
48
48
  onUpdate?.({ content: [{ type: "text", text: `Deploying to ${params.environment}...` }], details: {} });
49
49
 
50
50
  // Example deployment logic
51
- // const result = await pi.exec("npm", ["run", "deploy", params.environment], { signal });
51
+ // const result = await elyra.exec("npm", ["run", "deploy", params.environment], { signal });
52
52
 
53
53
  // On success, request graceful shutdown
54
54
  onUpdate?.({ content: [{ type: "text", text: "Deployment complete, exiting..." }], details: {} });
@@ -306,8 +306,8 @@ class SnakeComponent {
306
306
 
307
307
  const SNAKE_SAVE_TYPE = "snake-save";
308
308
 
309
- export default function (pi: ExtensionAPI) {
310
- pi.registerCommand("snake", {
309
+ export default function (elyra: ExtensionAPI) {
310
+ elyra.registerCommand("snake", {
311
311
  description: "Play Snake!",
312
312
 
313
313
  handler: async (_args, ctx) => {
@@ -333,7 +333,7 @@ export default function (pi: ExtensionAPI) {
333
333
  () => done(undefined),
334
334
  (state) => {
335
335
  // Save or clear state
336
- pi.appendEntry(SNAKE_SAVE_TYPE, state);
336
+ elyra.appendEntry(SNAKE_SAVE_TYPE, state);
337
337
  },
338
338
  savedState,
339
339
  );
@@ -524,8 +524,8 @@ class SpaceInvadersComponent {
524
524
 
525
525
  const INVADERS_SAVE_TYPE = "space-invaders-save";
526
526
 
527
- export default function (pi: ExtensionAPI) {
528
- pi.registerCommand("invaders", {
527
+ export default function (elyra: ExtensionAPI) {
528
+ elyra.registerCommand("invaders", {
529
529
  description: "Play Space Invaders!",
530
530
 
531
531
  handler: async (_args, ctx) => {
@@ -550,7 +550,7 @@ export default function (pi: ExtensionAPI) {
550
550
  tui,
551
551
  () => done(undefined),
552
552
  (state) => {
553
- pi.appendEntry(INVADERS_SAVE_TYPE, state);
553
+ elyra.appendEntry(INVADERS_SAVE_TYPE, state);
554
554
  },
555
555
  savedState,
556
556
  );
@@ -111,8 +111,8 @@ function createRemoteBashOps(remote: string, remoteCwd: string, localCwd: string
111
111
  };
112
112
  }
113
113
 
114
- export default function (pi: ExtensionAPI) {
115
- pi.registerFlag("ssh", { description: "SSH remote: user@host or user@host:/path", type: "string" });
114
+ export default function (elyra: ExtensionAPI) {
115
+ elyra.registerFlag("ssh", { description: "SSH remote: user@host or user@host:/path", type: "string" });
116
116
 
117
117
  const localCwd = process.cwd();
118
118
  const localRead = createReadTool(localCwd);
@@ -125,7 +125,7 @@ export default function (pi: ExtensionAPI) {
125
125
 
126
126
  const getSsh = () => resolvedSsh;
127
127
 
128
- pi.registerTool({
128
+ elyra.registerTool({
129
129
  ...localRead,
130
130
  async execute(id, params, signal, onUpdate, _ctx) {
131
131
  const ssh = getSsh();
@@ -139,7 +139,7 @@ export default function (pi: ExtensionAPI) {
139
139
  },
140
140
  });
141
141
 
142
- pi.registerTool({
142
+ elyra.registerTool({
143
143
  ...localWrite,
144
144
  async execute(id, params, signal, onUpdate, _ctx) {
145
145
  const ssh = getSsh();
@@ -153,7 +153,7 @@ export default function (pi: ExtensionAPI) {
153
153
  },
154
154
  });
155
155
 
156
- pi.registerTool({
156
+ elyra.registerTool({
157
157
  ...localEdit,
158
158
  async execute(id, params, signal, onUpdate, _ctx) {
159
159
  const ssh = getSsh();
@@ -167,7 +167,7 @@ export default function (pi: ExtensionAPI) {
167
167
  },
168
168
  });
169
169
 
170
- pi.registerTool({
170
+ elyra.registerTool({
171
171
  ...localBash,
172
172
  async execute(id, params, signal, onUpdate, _ctx) {
173
173
  const ssh = getSsh();
@@ -181,9 +181,9 @@ export default function (pi: ExtensionAPI) {
181
181
  },
182
182
  });
183
183
 
184
- pi.on("session_start", async (_event, ctx) => {
184
+ elyra.on("session_start", async (_event, ctx) => {
185
185
  // Resolve SSH config now that CLI flags are available
186
- const arg = pi.getFlag("ssh") as string | undefined;
186
+ const arg = elyra.getFlag("ssh") as string | undefined;
187
187
  if (arg) {
188
188
  if (arg.includes(":")) {
189
189
  const [remote, path] = arg.split(":");
@@ -200,14 +200,14 @@ export default function (pi: ExtensionAPI) {
200
200
  });
201
201
 
202
202
  // Handle user ! commands via SSH
203
- pi.on("user_bash", (_event) => {
203
+ elyra.on("user_bash", (_event) => {
204
204
  const ssh = getSsh();
205
205
  if (!ssh) return; // No SSH, use local execution
206
206
  return { operations: createRemoteBashOps(ssh.remote, ssh.remoteCwd, localCwd) };
207
207
  });
208
208
 
209
209
  // Replace local cwd with remote cwd in system prompt
210
- pi.on("before_agent_start", async (event) => {
210
+ elyra.on("before_agent_start", async (event) => {
211
211
  const ssh = getSsh();
212
212
  if (ssh) {
213
213
  const modified = event.systemPrompt.replace(
@@ -7,15 +7,15 @@
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
  let turnCount = 0;
12
12
 
13
- pi.on("session_start", async (_event, ctx) => {
13
+ elyra.on("session_start", async (_event, ctx) => {
14
14
  const theme = ctx.ui.theme;
15
15
  ctx.ui.setStatus("status-demo", theme.fg("dim", "Ready"));
16
16
  });
17
17
 
18
- pi.on("turn_start", async (_event, ctx) => {
18
+ elyra.on("turn_start", async (_event, ctx) => {
19
19
  turnCount++;
20
20
  const theme = ctx.ui.theme;
21
21
  const spinner = theme.fg("accent", "●");
@@ -23,7 +23,7 @@ export default function (pi: ExtensionAPI) {
23
23
  ctx.ui.setStatus("status-demo", spinner + text);
24
24
  });
25
25
 
26
- pi.on("turn_end", async (_event, ctx) => {
26
+ elyra.on("turn_end", async (_event, ctx) => {
27
27
  const theme = ctx.ui.theme;
28
28
  const check = theme.fg("success", "✓");
29
29
  const text = theme.fg("dim", ` Turn ${turnCount} complete`);
@@ -60,6 +60,6 @@ const structuredOutputTool = defineTool({
60
60
  },
61
61
  });
62
62
 
63
- export default function (pi: ExtensionAPI) {
64
- pi.registerTool(structuredOutputTool);
63
+ export default function (elyra: ExtensionAPI) {
64
+ elyra.registerTool(structuredOutputTool);
65
65
  }
@@ -208,7 +208,7 @@ async function mapWithConcurrencyLimit<TIn, TOut>(
208
208
  }
209
209
 
210
210
  async function writePromptToTempFile(agentName: string, prompt: string): Promise<{ dir: string; filePath: string }> {
211
- const tmpDir = await fs.promises.mkdtemp(path.join(os.tmpdir(), "pi-subagent-"));
211
+ const tmpDir = await fs.promises.mkdtemp(path.join(os.tmpdir(), "elyra-subagent-"));
212
212
  const safeName = agentName.replace(/[^\w.-]+/g, "_");
213
213
  const filePath = path.join(tmpDir, `prompt-${safeName}.md`);
214
214
  await withFileMutationQueue(filePath, async () => {
@@ -428,8 +428,8 @@ const SubagentParams = Type.Object({
428
428
  cwd: Type.Optional(Type.String({ description: "Working directory for the agent process (single mode)" })),
429
429
  });
430
430
 
431
- export default function (pi: ExtensionAPI) {
432
- pi.registerTool({
431
+ export default function (elyra: ExtensionAPI) {
432
+ elyra.registerTool({
433
433
  name: "subagent",
434
434
  label: "Subagent",
435
435
  description: [
@@ -142,8 +142,8 @@ const showSummaryUi = async (summary: string, ctx: ExtensionCommandContext) => {
142
142
  });
143
143
  };
144
144
 
145
- export default function (pi: ExtensionAPI) {
146
- pi.registerCommand("summarize", {
145
+ export default function (elyra: ExtensionAPI) {
146
+ elyra.registerCommand("summarize", {
147
147
  description: "Summarize the current conversation in a custom UI",
148
148
  handler: async (_args, ctx) => {
149
149
  const branch = ctx.sessionManager.getBranch();
@@ -5,13 +5,13 @@
5
5
  */
6
6
  import type { ExtensionAPI } from "@elyracode/coding-agent";
7
7
 
8
- export default function (pi: ExtensionAPI) {
9
- pi.on("agent_start", (_event, ctx) => {
8
+ export default function (elyra: ExtensionAPI) {
9
+ elyra.on("agent_start", (_event, ctx) => {
10
10
  const prompt = ctx.getSystemPrompt();
11
11
  ctx.ui.setStatus("system-prompt", `System: ${prompt.length} chars`);
12
12
  });
13
13
 
14
- pi.on("session_shutdown", (_event, ctx) => {
14
+ elyra.on("session_shutdown", (_event, ctx) => {
15
15
  ctx.ui.setStatus("system-prompt", undefined);
16
16
  });
17
17
  }
@@ -655,9 +655,9 @@ function getBoardDetails(): BoardDetails {
655
655
  };
656
656
  }
657
657
 
658
- export default function (pi: ExtensionAPI) {
659
- pi.on("session_start", async (_event, ctx) => reconstructState(ctx));
660
- pi.on("session_tree", async (_event, ctx) => reconstructState(ctx));
658
+ export default function (elyra: ExtensionAPI) {
659
+ elyra.on("session_start", async (_event, ctx) => reconstructState(ctx));
660
+ elyra.on("session_tree", async (_event, ctx) => reconstructState(ctx));
661
661
 
662
662
  // Sent once per game at end-of-game. The custom renderer paints the banner;
663
663
  // `content` is a plain-text fallback for any non-TUI consumer and for the
@@ -671,7 +671,7 @@ export default function (pi: ExtensionAPI) {
671
671
  : gameState.status === "draw"
672
672
  ? "Draw"
673
673
  : "Game over";
674
- pi.sendMessage({
674
+ elyra.sendMessage({
675
675
  customType: GAME_OVER_MESSAGE_TYPE,
676
676
  content: `Game over: ${label}.`,
677
677
  display: true,
@@ -682,7 +682,7 @@ export default function (pi: ExtensionAPI) {
682
682
  // -----------------------------------------------------------------------
683
683
  // Custom message renderer for user move messages
684
684
  // -----------------------------------------------------------------------
685
- pi.registerMessageRenderer(MOVE_MESSAGE_TYPE, (message, { expanded }, theme) => {
685
+ elyra.registerMessageRenderer(MOVE_MESSAGE_TYPE, (message, { expanded }, theme) => {
686
686
  const details = message.details as BoardDetails | undefined;
687
687
  const turnLabel =
688
688
  details?.currentTurn === "O"
@@ -695,7 +695,7 @@ export default function (pi: ExtensionAPI) {
695
695
  // -----------------------------------------------------------------------
696
696
  // Custom message renderer for game-over messages
697
697
  // -----------------------------------------------------------------------
698
- pi.registerMessageRenderer(GAME_OVER_MESSAGE_TYPE, (message, _options, theme) => {
698
+ elyra.registerMessageRenderer(GAME_OVER_MESSAGE_TYPE, (message, _options, theme) => {
699
699
  const details = message.details as BoardDetails | undefined;
700
700
  const status = (details?.status ?? "draw") as GameStatus;
701
701
  return new GameOverMessageComponent(status, details, theme);
@@ -704,7 +704,7 @@ export default function (pi: ExtensionAPI) {
704
704
  // -----------------------------------------------------------------------
705
705
  // before_agent_start - inject game instructions each turn
706
706
  // -----------------------------------------------------------------------
707
- pi.on("before_agent_start", async (event) => {
707
+ elyra.on("before_agent_start", async (event) => {
708
708
  if (!gameActive) return undefined;
709
709
 
710
710
  const instructions = `
@@ -775,7 +775,7 @@ Decide the target cell first, then dump every action for the turn in one go.
775
775
  // -----------------------------------------------------------------------
776
776
  // /tic-tac-toe command
777
777
  // -----------------------------------------------------------------------
778
- pi.registerCommand("tic-tac-toe", {
778
+ elyra.registerCommand("tic-tac-toe", {
779
779
  description: "Play tic-tac-toe against the agent",
780
780
 
781
781
  handler: async (_args, ctx) => {
@@ -789,7 +789,7 @@ Decide the target cell first, then dump every action for the turn in one go.
789
789
  gameState = createInitialState();
790
790
  }
791
791
  gameActive = true;
792
- pi.setSessionName("Tic-Tac-Toe");
792
+ elyra.setSessionName("Tic-Tac-Toe");
793
793
 
794
794
  await ctx.ui.custom<void>((tui, _theme, _kb, done) => {
795
795
  component = new TicTacToeComponent(
@@ -806,7 +806,7 @@ Decide the target cell first, then dump every action for the turn in one go.
806
806
  gameState.currentTurn = gameState.agentMark;
807
807
  }
808
808
  component?.updateState(gameState);
809
- pi.appendEntry(SAVE_TYPE, getBoardDetails());
809
+ elyra.appendEntry(SAVE_TYPE, getBoardDetails());
810
810
 
811
811
  if (gameState.status === "playing") {
812
812
  // IMPORTANT: user play does NOT touch the agent cursor.
@@ -816,7 +816,7 @@ Decide the target cell first, then dump every action for the turn in one go.
816
816
  gameState.agentCursorRow,
817
817
  gameState.agentCursorCol,
818
818
  );
819
- pi.sendMessage(
819
+ elyra.sendMessage(
820
820
  {
821
821
  customType: MOVE_MESSAGE_TYPE,
822
822
  content:
@@ -856,7 +856,7 @@ Decide the target cell first, then dump every action for the turn in one go.
856
856
  play: 0,
857
857
  };
858
858
 
859
- pi.registerTool({
859
+ elyra.registerTool({
860
860
  name: "tic_tac_toe",
861
861
  label: "Tic-Tac-Toe",
862
862
  description:
@@ -910,7 +910,7 @@ Decide the target cell first, then dump every action for the turn in one go.
910
910
  // Do NOT reset the cursor on failure. The agent can retry
911
911
  // from the cursor's current position.
912
912
  component?.updateState(gameState);
913
- pi.appendEntry(SAVE_TYPE, getBoardDetails());
913
+ elyra.appendEntry(SAVE_TYPE, getBoardDetails());
914
914
  throw new TicTacToeError(
915
915
  `Cell (${r},${c}) is already ${gameState.board[r][c]}. Your cursor is still at (${r},${c}). Move to an empty cell and retry play.`,
916
916
  );
@@ -939,7 +939,7 @@ Decide the target cell first, then dump every action for the turn in one go.
939
939
  }
940
940
 
941
941
  component?.updateState(gameState);
942
- pi.appendEntry(SAVE_TYPE, getBoardDetails());
942
+ elyra.appendEntry(SAVE_TYPE, getBoardDetails());
943
943
 
944
944
  return {
945
945
  content: [{ type: "text", text: result }],
@@ -969,7 +969,7 @@ Decide the target cell first, then dump every action for the turn in one go.
969
969
  // -----------------------------------------------------------------------
970
970
  // tic_tac_toe_see_board tool - inspect board + agent cursor.
971
971
  // -----------------------------------------------------------------------
972
- pi.registerTool({
972
+ elyra.registerTool({
973
973
  name: "tic_tac_toe_see_board",
974
974
  label: "See Board",
975
975
  description:
@@ -9,9 +9,9 @@
9
9
 
10
10
  import type { ExtensionAPI } from "@elyracode/coding-agent";
11
11
 
12
- export default function (pi: ExtensionAPI) {
12
+ export default function (elyra: ExtensionAPI) {
13
13
  // Simple approach: use timeout option (recommended)
14
- pi.registerCommand("timed", {
14
+ elyra.registerCommand("timed", {
15
15
  description: "Show a timed confirmation dialog (auto-cancels in 5s with countdown)",
16
16
  handler: async (_args, ctx) => {
17
17
  const confirmed = await ctx.ui.confirm(
@@ -28,7 +28,7 @@ export default function (pi: ExtensionAPI) {
28
28
  },
29
29
  });
30
30
 
31
- pi.registerCommand("timed-select", {
31
+ elyra.registerCommand("timed-select", {
32
32
  description: "Show a timed select dialog (auto-cancels in 10s with countdown)",
33
33
  handler: async (_args, ctx) => {
34
34
  const choice = await ctx.ui.select("Pick an option", ["Option A", "Option B", "Option C"], { timeout: 10000 });
@@ -42,7 +42,7 @@ export default function (pi: ExtensionAPI) {
42
42
  });
43
43
 
44
44
  // Manual approach: use AbortSignal for more control
45
- pi.registerCommand("timed-signal", {
45
+ elyra.registerCommand("timed-signal", {
46
46
  description: "Show a timed confirm using AbortSignal (manual approach)",
47
47
  handler: async (_args, ctx) => {
48
48
  const controller = new AbortController();
@@ -13,13 +13,13 @@ import type { ExtensionAPI, ExtensionContext } from "@elyracode/coding-agent";
13
13
 
14
14
  const BRAILLE_FRAMES = ["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"];
15
15
 
16
- function getBaseTitle(pi: ExtensionAPI): string {
16
+ function getBaseTitle(elyra: ExtensionAPI): string {
17
17
  const cwd = path.basename(process.cwd());
18
- const session = pi.getSessionName();
18
+ const session = elyra.getSessionName();
19
19
  return session ? `π - ${session} - ${cwd}` : `π - ${cwd}`;
20
20
  }
21
21
 
22
- export default function (pi: ExtensionAPI) {
22
+ export default function (elyra: ExtensionAPI) {
23
23
  let timer: ReturnType<typeof setInterval> | null = null;
24
24
  let frameIndex = 0;
25
25
 
@@ -29,7 +29,7 @@ export default function (pi: ExtensionAPI) {
29
29
  timer = null;
30
30
  }
31
31
  frameIndex = 0;
32
- ctx.ui.setTitle(getBaseTitle(pi));
32
+ ctx.ui.setTitle(getBaseTitle(elyra));
33
33
  }
34
34
 
35
35
  function startAnimation(ctx: ExtensionContext) {
@@ -37,22 +37,22 @@ export default function (pi: ExtensionAPI) {
37
37
  timer = setInterval(() => {
38
38
  const frame = BRAILLE_FRAMES[frameIndex % BRAILLE_FRAMES.length];
39
39
  const cwd = path.basename(process.cwd());
40
- const session = pi.getSessionName();
40
+ const session = elyra.getSessionName();
41
41
  const title = session ? `${frame} π - ${session} - ${cwd}` : `${frame} π - ${cwd}`;
42
42
  ctx.ui.setTitle(title);
43
43
  frameIndex++;
44
44
  }, 80);
45
45
  }
46
46
 
47
- pi.on("agent_start", async (_event, ctx) => {
47
+ elyra.on("agent_start", async (_event, ctx) => {
48
48
  startAnimation(ctx);
49
49
  });
50
50
 
51
- pi.on("agent_end", async (_event, ctx) => {
51
+ elyra.on("agent_end", async (_event, ctx) => {
52
52
  stopAnimation(ctx);
53
53
  });
54
54
 
55
- pi.on("session_shutdown", async (_event, ctx) => {
55
+ elyra.on("session_shutdown", async (_event, ctx) => {
56
56
  stopAnimation(ctx);
57
57
  });
58
58
  }
@@ -102,7 +102,7 @@ class TodoListComponent {
102
102
  }
103
103
  }
104
104
 
105
- export default function (pi: ExtensionAPI) {
105
+ export default function (elyra: ExtensionAPI) {
106
106
  // In-memory state (reconstructed from session on load)
107
107
  let todos: Todo[] = [];
108
108
  let nextId = 1;
@@ -129,11 +129,11 @@ export default function (pi: ExtensionAPI) {
129
129
  };
130
130
 
131
131
  // Reconstruct state on session events
132
- pi.on("session_start", async (_event, ctx) => reconstructState(ctx));
133
- pi.on("session_tree", async (_event, ctx) => reconstructState(ctx));
132
+ elyra.on("session_start", async (_event, ctx) => reconstructState(ctx));
133
+ elyra.on("session_tree", async (_event, ctx) => reconstructState(ctx));
134
134
 
135
135
  // Register the todo tool for the LLM
136
- pi.registerTool({
136
+ elyra.registerTool({
137
137
  name: "todo",
138
138
  label: "Todo",
139
139
  description: "Manage a todo list. Actions: list, add (text), toggle (id), clear",
@@ -281,7 +281,7 @@ export default function (pi: ExtensionAPI) {
281
281
  });
282
282
 
283
283
  // Register the /todos command for users
284
- pi.registerCommand("todos", {
284
+ elyra.registerCommand("todos", {
285
285
  description: "Show all todos on the current branch",
286
286
  handler: async (_args, ctx) => {
287
287
  if (!ctx.hasUI) {
@@ -65,8 +65,8 @@ const readSchema = Type.Object({
65
65
  limit: Type.Optional(Type.Number({ description: "Maximum number of lines to read" })),
66
66
  });
67
67
 
68
- export default function (pi: ExtensionAPI) {
69
- pi.registerTool({
68
+ export default function (elyra: ExtensionAPI) {
69
+ elyra.registerTool({
70
70
  name: "read", // Same name as built-in - this will override it
71
71
  label: "read (audited)",
72
72
  description:
@@ -129,7 +129,7 @@ export default function (pi: ExtensionAPI) {
129
129
  });
130
130
 
131
131
  // Also register a command to view the access log
132
- pi.registerCommand("read-log", {
132
+ elyra.registerCommand("read-log", {
133
133
  description: "View the file access log",
134
134
  handler: async (_args, ctx) => {
135
135
  try {
@@ -18,26 +18,26 @@ interface ToolsState {
18
18
  enabledTools: string[];
19
19
  }
20
20
 
21
- export default function toolsExtension(pi: ExtensionAPI) {
21
+ export default function toolsExtension(elyra: ExtensionAPI) {
22
22
  // Track enabled tools
23
23
  let enabledTools: Set<string> = new Set();
24
24
  let allTools: ToolInfo[] = [];
25
25
 
26
26
  // Persist current state
27
27
  function persistState() {
28
- pi.appendEntry<ToolsState>("tools-config", {
28
+ elyra.appendEntry<ToolsState>("tools-config", {
29
29
  enabledTools: Array.from(enabledTools),
30
30
  });
31
31
  }
32
32
 
33
33
  // Apply current tool selection
34
34
  function applyTools() {
35
- pi.setActiveTools(Array.from(enabledTools));
35
+ elyra.setActiveTools(Array.from(enabledTools));
36
36
  }
37
37
 
38
38
  // Find the last tools-config entry in the current branch
39
39
  function restoreFromBranch(ctx: ExtensionContext) {
40
- allTools = pi.getAllTools();
40
+ allTools = elyra.getAllTools();
41
41
 
42
42
  // Get entries in current branch only
43
43
  const branchEntries = ctx.sessionManager.getBranch();
@@ -59,16 +59,16 @@ export default function toolsExtension(pi: ExtensionAPI) {
59
59
  applyTools();
60
60
  } else {
61
61
  // No saved state - sync with currently active tools
62
- enabledTools = new Set(pi.getActiveTools());
62
+ enabledTools = new Set(elyra.getActiveTools());
63
63
  }
64
64
  }
65
65
 
66
66
  // Register /tools command
67
- pi.registerCommand("tools", {
67
+ elyra.registerCommand("tools", {
68
68
  description: "Enable/disable tools",
69
69
  handler: async (_args, ctx) => {
70
70
  // Refresh tool list
71
- allTools = pi.getAllTools();
71
+ allTools = elyra.getAllTools();
72
72
 
73
73
  await ctx.ui.custom((tui, theme, _kb, done) => {
74
74
  // Build settings items for each tool
@@ -130,12 +130,12 @@ export default function toolsExtension(pi: ExtensionAPI) {
130
130
  });
131
131
 
132
132
  // Restore state on session start
133
- pi.on("session_start", async (_event, ctx) => {
133
+ elyra.on("session_start", async (_event, ctx) => {
134
134
  restoreFromBranch(ctx);
135
135
  });
136
136
 
137
137
  // Restore state when navigating the session tree
138
- pi.on("session_tree", async (_event, ctx) => {
138
+ elyra.on("session_tree", async (_event, ctx) => {
139
139
  restoreFromBranch(ctx);
140
140
  });
141
141
  }
@@ -2,7 +2,7 @@ import type { ExtensionAPI, ExtensionContext } from "@elyracode/coding-agent";
2
2
 
3
3
  const COMPACT_THRESHOLD_TOKENS = 100_000;
4
4
 
5
- export default function (pi: ExtensionAPI) {
5
+ export default function (elyra: ExtensionAPI) {
6
6
  let previousTokens: number | null | undefined;
7
7
 
8
8
  const triggerCompaction = (ctx: ExtensionContext, customInstructions?: string) => {
@@ -24,7 +24,7 @@ export default function (pi: ExtensionAPI) {
24
24
  });
25
25
  };
26
26
 
27
- pi.on("turn_end", (_event, ctx) => {
27
+ elyra.on("turn_end", (_event, ctx) => {
28
28
  const usage = ctx.getContextUsage();
29
29
  const currentTokens = usage?.tokens ?? null;
30
30
  if (currentTokens === null) {
@@ -40,7 +40,7 @@ export default function (pi: ExtensionAPI) {
40
40
  triggerCompaction(ctx);
41
41
  });
42
42
 
43
- pi.registerCommand("trigger-compact", {
43
+ elyra.registerCommand("trigger-compact", {
44
44
  description: "Trigger compaction immediately",
45
45
  handler: async (args, ctx) => {
46
46
  const instructions = args.trim() || undefined;
@@ -45,8 +45,8 @@ interface RgDetails {
45
45
  fullOutputPath?: string;
46
46
  }
47
47
 
48
- export default function (pi: ExtensionAPI) {
49
- pi.registerTool({
48
+ export default function (elyra: ExtensionAPI) {
49
+ elyra.registerTool({
50
50
  name: "rg",
51
51
  label: "ripgrep",
52
52
  // Document the truncation limits in the tool description so the LLM knows
@@ -109,7 +109,7 @@ export default function (pi: ExtensionAPI) {
109
109
 
110
110
  if (truncation.truncated) {
111
111
  // Save full output to a temp file so LLM can access it if needed
112
- const tempDir = await mkdtemp(join(tmpdir(), "pi-rg-"));
112
+ const tempDir = await mkdtemp(join(tmpdir(), "elyra-rg-"));
113
113
  const tempFile = join(tempDir, "output.txt");
114
114
  await withFileMutationQueue(tempFile, async () => {
115
115
  await writeFile(tempFile, output, "utf8");
@@ -1,7 +1,7 @@
1
1
  import type { ExtensionAPI } from "@elyracode/coding-agent";
2
2
 
3
- export default function widgetPlacementExtension(pi: ExtensionAPI) {
4
- pi.on("session_start", (_event, ctx) => {
3
+ export default function widgetPlacementExtension(elyra: ExtensionAPI) {
4
+ elyra.on("session_start", (_event, ctx) => {
5
5
  if (!ctx.hasUI) return;
6
6
  ctx.ui.setWidget("widget-above", ["Above editor widget"]);
7
7
  ctx.ui.setWidget("widget-below", ["Below editor widget"], { placement: "belowEditor" });