@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.
- package/CHANGELOG.md +17 -0
- package/dist/cli/config-selector.d.ts +1 -1
- package/dist/cli/config-selector.d.ts.map +1 -1
- package/dist/cli/config-selector.js +1 -1
- package/dist/cli/config-selector.js.map +1 -1
- package/dist/config.d.ts +1 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +2 -2
- package/dist/config.js.map +1 -1
- package/dist/core/agent-session-runtime.d.ts +1 -0
- package/dist/core/agent-session-runtime.d.ts.map +1 -1
- package/dist/core/agent-session-runtime.js +35 -0
- package/dist/core/agent-session-runtime.js.map +1 -1
- package/dist/core/agent-session.d.ts +7 -1
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +55 -3
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/bash-executor.d.ts.map +1 -1
- package/dist/core/bash-executor.js +1 -1
- package/dist/core/bash-executor.js.map +1 -1
- package/dist/core/compaction/branch-summarization.d.ts.map +1 -1
- package/dist/core/compaction/branch-summarization.js +1 -1
- package/dist/core/compaction/branch-summarization.js.map +1 -1
- package/dist/core/compaction/compaction.d.ts.map +1 -1
- package/dist/core/compaction/compaction.js +1 -1
- package/dist/core/compaction/compaction.js.map +1 -1
- package/dist/core/extensions/loader.d.ts.map +1 -1
- package/dist/core/extensions/loader.js +3 -3
- package/dist/core/extensions/loader.js.map +1 -1
- package/dist/core/extensions/runner.d.ts.map +1 -1
- package/dist/core/extensions/runner.js +1 -1
- package/dist/core/extensions/runner.js.map +1 -1
- package/dist/core/extensions/types.d.ts +9 -9
- package/dist/core/extensions/types.d.ts.map +1 -1
- package/dist/core/extensions/types.js.map +1 -1
- package/dist/core/memory.d.ts +23 -0
- package/dist/core/memory.d.ts.map +1 -0
- package/dist/core/memory.js +173 -0
- package/dist/core/memory.js.map +1 -0
- package/dist/core/package-manager.d.ts.map +1 -1
- package/dist/core/package-manager.js +12 -12
- package/dist/core/package-manager.js.map +1 -1
- package/dist/core/session-manager.d.ts +6 -6
- package/dist/core/session-manager.d.ts.map +1 -1
- package/dist/core/session-manager.js +4 -4
- package/dist/core/session-manager.js.map +1 -1
- package/dist/core/settings-manager.d.ts +6 -0
- package/dist/core/settings-manager.d.ts.map +1 -1
- package/dist/core/settings-manager.js +16 -0
- package/dist/core/settings-manager.js.map +1 -1
- package/dist/core/smart-router.d.ts +43 -0
- package/dist/core/smart-router.d.ts.map +1 -0
- package/dist/core/smart-router.js +206 -0
- package/dist/core/smart-router.js.map +1 -0
- package/dist/core/stack-detector.d.ts +21 -0
- package/dist/core/stack-detector.d.ts.map +1 -0
- package/dist/core/stack-detector.js +120 -0
- package/dist/core/stack-detector.js.map +1 -0
- package/dist/core/system-prompt.d.ts +4 -0
- package/dist/core/system-prompt.d.ts.map +1 -1
- package/dist/core/system-prompt.js +27 -1
- package/dist/core/system-prompt.js.map +1 -1
- package/dist/core/tools/bash.d.ts +2 -2
- package/dist/core/tools/bash.d.ts.map +1 -1
- package/dist/core/tools/bash.js +3 -3
- package/dist/core/tools/bash.js.map +1 -1
- package/dist/core/tools/output-accumulator.d.ts.map +1 -1
- package/dist/core/tools/output-accumulator.js +1 -1
- package/dist/core/tools/output-accumulator.js.map +1 -1
- package/dist/migrations.d.ts.map +1 -1
- package/dist/migrations.js +1 -1
- package/dist/migrations.js.map +1 -1
- package/dist/modes/interactive/components/settings-selector.d.ts +4 -0
- package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/settings-selector.js +20 -0
- package/dist/modes/interactive/components/settings-selector.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts +1 -0
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +26 -0
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/package-manager-cli.d.ts.map +1 -1
- package/dist/package-manager-cli.js +10 -10
- package/dist/package-manager-cli.js.map +1 -1
- package/dist/utils/clipboard-image.d.ts.map +1 -1
- package/dist/utils/clipboard-image.js +1 -1
- package/dist/utils/clipboard-image.js.map +1 -1
- package/docs/extensions.md +17 -17
- package/docs/index.md +1 -1
- package/docs/prompt-templates.md +1 -1
- package/docs/providers.md +1 -1
- package/docs/quickstart.md +5 -5
- package/docs/rpc.md +6 -6
- package/docs/sdk.md +2 -2
- package/docs/session-format.md +3 -3
- package/docs/settings.md +4 -4
- package/docs/skills.md +2 -2
- package/docs/termux.md +3 -3
- package/docs/themes.md +1 -1
- package/docs/tui.md +1 -1
- package/docs/usage.md +2 -2
- package/examples/extensions/auto-commit-on-exit.ts +5 -5
- package/examples/extensions/bash-spawn-hook.ts +2 -2
- package/examples/extensions/bookmark.ts +5 -5
- package/examples/extensions/border-status-editor.ts +7 -7
- package/examples/extensions/built-in-tool-renderer.ts +5 -5
- package/examples/extensions/claude-rules.ts +3 -3
- package/examples/extensions/commands.ts +4 -4
- package/examples/extensions/confirm-destructive.ts +3 -3
- package/examples/extensions/custom-compaction.ts +2 -2
- package/examples/extensions/custom-footer.ts +2 -2
- package/examples/extensions/custom-header.ts +3 -3
- package/examples/extensions/custom-provider-anthropic/index.ts +2 -2
- package/examples/extensions/custom-provider-anthropic/package.json +2 -2
- package/examples/extensions/custom-provider-gitlab-duo/index.ts +2 -2
- package/examples/extensions/custom-provider-gitlab-duo/package.json +2 -2
- package/examples/extensions/dirty-repo-guard.ts +7 -7
- package/examples/extensions/doom-overlay/index.ts +2 -2
- package/examples/extensions/dynamic-resources/index.ts +2 -2
- package/examples/extensions/dynamic-tools.ts +4 -4
- package/examples/extensions/event-bus.ts +8 -8
- package/examples/extensions/file-trigger.ts +3 -3
- package/examples/extensions/git-checkpoint.ts +7 -7
- package/examples/extensions/github-issue-autocomplete.ts +6 -6
- package/examples/extensions/handoff.ts +2 -2
- package/examples/extensions/hello.ts +2 -2
- package/examples/extensions/hidden-thinking-label.ts +3 -3
- package/examples/extensions/inline-bash.ts +3 -3
- package/examples/extensions/input-transform.ts +2 -2
- package/examples/extensions/interactive-shell.ts +2 -2
- package/examples/extensions/mac-system-theme.ts +3 -3
- package/examples/extensions/message-renderer.ts +4 -4
- package/examples/extensions/minimal-mode.ts +8 -8
- package/examples/extensions/modal-editor.ts +2 -2
- package/examples/extensions/model-status.ts +2 -2
- package/examples/extensions/notify.ts +2 -2
- package/examples/extensions/overlay-qa-tests.ts +14 -14
- package/examples/extensions/overlay-test.ts +2 -2
- package/examples/extensions/permission-gate.ts +2 -2
- package/examples/extensions/pirate.ts +3 -3
- package/examples/extensions/plan-mode/index.ts +22 -22
- package/examples/extensions/preset.ts +23 -23
- package/examples/extensions/prompt-customizer.ts +2 -2
- package/examples/extensions/protected-paths.ts +2 -2
- package/examples/extensions/provider-payload.ts +3 -3
- package/examples/extensions/qna.ts +2 -2
- package/examples/extensions/question.ts +2 -2
- package/examples/extensions/questionnaire.ts +2 -2
- package/examples/extensions/rainbow-editor.ts +2 -2
- package/examples/extensions/reload-runtime.ts +4 -4
- package/examples/extensions/rpc-demo.ts +10 -10
- package/examples/extensions/sandbox/index.ts +8 -8
- package/examples/extensions/sandbox/package.json +2 -2
- package/examples/extensions/send-user-message.ts +13 -13
- package/examples/extensions/session-name.ts +4 -4
- package/examples/extensions/shutdown-command.ts +10 -10
- package/examples/extensions/snake.ts +3 -3
- package/examples/extensions/space-invaders.ts +3 -3
- package/examples/extensions/ssh.ts +10 -10
- package/examples/extensions/status-line.ts +4 -4
- package/examples/extensions/structured-output.ts +2 -2
- package/examples/extensions/subagent/index.ts +3 -3
- package/examples/extensions/summarize.ts +2 -2
- package/examples/extensions/system-prompt-header.ts +3 -3
- package/examples/extensions/tic-tac-toe.ts +15 -15
- package/examples/extensions/timed-confirm.ts +4 -4
- package/examples/extensions/titlebar-spinner.ts +8 -8
- package/examples/extensions/todo.ts +5 -5
- package/examples/extensions/tool-override.ts +3 -3
- package/examples/extensions/tools.ts +9 -9
- package/examples/extensions/trigger-compact.ts +3 -3
- package/examples/extensions/truncated-tool.ts +3 -3
- package/examples/extensions/widget-placement.ts +2 -2
- package/examples/extensions/with-deps/index.ts +2 -2
- package/examples/extensions/with-deps/package.json +2 -2
- package/examples/extensions/working-indicator.ts +5 -5
- package/examples/extensions/working-message-test.ts +2 -2
- package/package.json +5 -5
package/docs/quickstart.md
CHANGED
|
@@ -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
|
-
|
|
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
|
|
36
|
+
Set an API key before launching elyra:
|
|
37
37
|
|
|
38
38
|
```bash
|
|
39
39
|
export ANTHROPIC_API_KEY=sk-ant-...
|
|
40
|
-
|
|
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
|
|
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
|
-
- [
|
|
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/
|
|
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/.
|
|
718
|
-
{"name": "fix-tests", "description": "Fix failing tests", "source": "prompt", "location": "project", "path": "/home/user/myproject/.
|
|
719
|
-
{"name": "skill:brave-search", "description": "Web search via Brave API", "source": "skill", "location": "user", "path": "/home/user/.
|
|
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 (`./.
|
|
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": "
|
|
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
|
-
(
|
|
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>/.
|
|
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
|
|
package/docs/session-format.md
CHANGED
|
@@ -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
|
|
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
|
|
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 `
|
|
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 `.
|
|
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": ["
|
|
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": "
|
|
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": ["
|
|
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 `
|
|
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
|
-
- [
|
|
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
|
|
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
|
|
26
|
-
|
|
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 `
|
|
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
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|
|
|
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,
|
|
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 (
|
|
11
|
-
|
|
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
|
|
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
|
|
43
|
-
const { code: commitCode } = await
|
|
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 (
|
|
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
|
-
|
|
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 (
|
|
13
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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 (
|
|
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
|
-
|
|
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
|
-
|
|
95
|
+
elyra.on("agent_end", () => {
|
|
96
96
|
isWorking = false;
|
|
97
97
|
stopSpinner();
|
|
98
98
|
activeTui?.requestRender();
|
|
99
99
|
});
|
|
100
100
|
|
|
101
|
-
|
|
101
|
+
elyra.on("session_shutdown", () => {
|
|
102
102
|
stopSpinner();
|
|
103
103
|
activeTui = undefined;
|
|
104
104
|
});
|
|
105
105
|
|
|
106
|
-
|
|
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
|
|
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 =
|
|
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 (
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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(
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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(
|
|
16
|
-
|
|
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 =
|
|
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 (
|
|
11
|
-
|
|
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
|
-
|
|
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 (
|
|
21
|
-
|
|
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 (
|
|
15
|
+
export default function (elyra: ExtensionAPI) {
|
|
16
16
|
let enabled = false;
|
|
17
17
|
|
|
18
|
-
|
|
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 (
|
|
47
|
+
export default function (elyra: ExtensionAPI) {
|
|
48
48
|
// Set custom header immediately on load (if UI is available)
|
|
49
|
-
|
|
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
|
-
|
|
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 (
|
|
569
|
-
|
|
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",
|
|
@@ -324,8 +324,8 @@ export function streamGitLabDuo(
|
|
|
324
324
|
// Extension Entry Point
|
|
325
325
|
// =============================================================================
|
|
326
326
|
|
|
327
|
-
export default function (
|
|
328
|
-
|
|
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",
|
|
@@ -8,12 +8,12 @@
|
|
|
8
8
|
import type { ExtensionAPI, ExtensionContext } from "@elyracode/coding-agent";
|
|
9
9
|
|
|
10
10
|
async function checkDirtyRepo(
|
|
11
|
-
|
|
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
|
|
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 (
|
|
48
|
-
|
|
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(
|
|
50
|
+
return checkDirtyRepo(elyra, ctx, action);
|
|
51
51
|
});
|
|
52
52
|
|
|
53
|
-
|
|
54
|
-
return checkDirtyRepo(
|
|
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 (
|
|
22
|
-
|
|
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 (
|
|
8
|
-
|
|
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")],
|