@elyracode/btw 0.7.15

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 ADDED
@@ -0,0 +1,11 @@
1
+ # Changelog
2
+
3
+ ## [0.7.15] - 2026-05-25
4
+
5
+ ### Added
6
+ - `/btw` command: parallel side conversations with tool access
7
+ - `/btw:inject` to send thread back to main agent
8
+ - `/btw:summarize` to summarize and inject
9
+ - `/btw:clear` to clear the thread
10
+ - `/btw:thread` to show current thread
11
+ - `elyra-btw` skill for side conversation guidance
package/README.md ADDED
@@ -0,0 +1,38 @@
1
+ # @elyracode/btw
2
+
3
+ Side conversations for Elyra. Ask questions while the main agent works, explore ideas without derailing the session, and inject results back when ready.
4
+
5
+ ## Install
6
+
7
+ ```bash
8
+ elyra install npm:@elyracode/btw
9
+ ```
10
+
11
+ ## Commands
12
+
13
+ | Command | Description |
14
+ |---------|-------------|
15
+ | `/btw <question>` | Ask a side question with tool access (runs in parallel) |
16
+ | `/btw:inject` | Send the BTW thread back to the main agent |
17
+ | `/btw:summarize` | Summarize the BTW thread and inject the summary |
18
+ | `/btw:clear` | Clear the BTW thread |
19
+ | `/btw:thread` | Show the current BTW thread |
20
+
21
+ ## Why
22
+
23
+ Sometimes you want to:
24
+ - Ask a clarifying question while the main agent keeps working
25
+ - Check something quickly without polluting the main context
26
+ - Think through an approach before committing to it
27
+ - Explore an idea, then inject it back once it's ready
28
+
29
+ BTW runs as an isolated sub-process with full tool access (read, bash, edit, write). Its context is separate from the main session — no token tax on the main agent.
30
+
31
+ ## Examples
32
+
33
+ ```
34
+ /btw what does the validateToken method return?
35
+ /btw how many tests are in the auth module?
36
+ /btw:inject implement the approach we discussed
37
+ /btw:clear
38
+ ```
@@ -0,0 +1,142 @@
1
+ import type { ExtensionAPI } from "@elyracode/coding-agent";
2
+
3
+ // ── Types ───────────────────────────────────────────────────────────────────
4
+
5
+ interface BtwEntry {
6
+ role: "user" | "assistant";
7
+ text: string;
8
+ timestamp: number;
9
+ }
10
+
11
+ // ── Extension ───────────────────────────────────────────────────────────────
12
+
13
+ export default function (elyra: ExtensionAPI): void {
14
+ let cwd = "";
15
+ const thread: BtwEntry[] = [];
16
+
17
+ elyra.on("session_start", async (_event, ctx) => {
18
+ cwd = ctx.cwd;
19
+ });
20
+
21
+ // ── /btw <question> ──────────────────────────────────────────────────
22
+
23
+ elyra.registerCommand("btw", {
24
+ description: "Side conversation — ask a question in parallel without affecting the main session",
25
+ async handler(args, ctx) {
26
+ // Sub-commands
27
+ if (args === ":clear" || args.startsWith(":clear ")) {
28
+ thread.length = 0;
29
+ ctx.ui.notify("BTW thread cleared", "info");
30
+ return;
31
+ }
32
+
33
+ if (args === ":thread" || args.startsWith(":thread ")) {
34
+ if (thread.length === 0) {
35
+ ctx.ui.notify("BTW thread is empty", "info");
36
+ return;
37
+ }
38
+ const formatted = thread
39
+ .map((e) => `[${e.role}] ${e.text}`)
40
+ .join("\n\n");
41
+ ctx.ui.notify(`BTW thread (${thread.length} entries):\n\n${formatted}`, "info");
42
+ return;
43
+ }
44
+
45
+ if (args === ":inject" || args.startsWith(":inject ")) {
46
+ if (thread.length === 0) {
47
+ ctx.ui.notify("BTW thread is empty, nothing to inject", "info");
48
+ return;
49
+ }
50
+ const extra = args.slice(":inject".length).trim();
51
+ const formatted = thread
52
+ .map((e) => `[${e.role}] ${e.text}`)
53
+ .join("\n\n");
54
+ const message = extra
55
+ ? `From a side conversation (BTW):\n\n${formatted}\n\nInstructions: ${extra}`
56
+ : `From a side conversation (BTW):\n\n${formatted}`;
57
+ await ctx.sendUserMessage(message);
58
+ thread.length = 0;
59
+ ctx.ui.notify("BTW thread injected into main session and cleared", "info");
60
+ return;
61
+ }
62
+
63
+ if (args === ":summarize" || args.startsWith(":summarize ")) {
64
+ if (thread.length === 0) {
65
+ ctx.ui.notify("BTW thread is empty, nothing to summarize", "info");
66
+ return;
67
+ }
68
+ const extra = args.slice(":summarize".length).trim();
69
+ const formatted = thread
70
+ .map((e) => `[${e.role}] ${e.text}`)
71
+ .join("\n\n");
72
+
73
+ // Use elyra -p to summarize in isolation
74
+ ctx.ui.notify("Summarizing BTW thread...", "info");
75
+ const summaryPrompt = `Summarize this side conversation concisely. Focus on decisions, findings, and actionable conclusions.\n\n${formatted}${extra ? `\n\nFocus: ${extra}` : ""}`;
76
+
77
+ const result = await elyra.exec("elyra", ["-p", "--no-session", summaryPrompt], {
78
+ timeout: 60_000,
79
+ cwd,
80
+ });
81
+
82
+ const summary = result.stdout.trim() || "(summary failed)";
83
+ await ctx.sendUserMessage(`Summary from a side conversation (BTW):\n\n${summary}`);
84
+ thread.length = 0;
85
+ ctx.ui.notify("BTW summary injected and thread cleared", "info");
86
+ return;
87
+ }
88
+
89
+ // Main /btw <question> handler
90
+ const question = args.trim();
91
+ if (!question) {
92
+ if (thread.length === 0) {
93
+ ctx.ui.notify(
94
+ "Usage: /btw <question>\n\nSub-commands: :inject, :summarize, :clear, :thread",
95
+ "info",
96
+ );
97
+ } else {
98
+ ctx.ui.notify(
99
+ `BTW thread has ${thread.length} entries.\n\nSub-commands: :inject, :summarize, :clear, :thread`,
100
+ "info",
101
+ );
102
+ }
103
+ return;
104
+ }
105
+
106
+ // Build context from thread history for continuity
107
+ const historyContext = thread.length > 0
108
+ ? `Previous side conversation:\n${thread.map((e) => `[${e.role}] ${e.text}`).join("\n")}\n\nNew question: ${question}`
109
+ : question;
110
+
111
+ // Add user entry
112
+ thread.push({ role: "user", text: question, timestamp: Date.now() });
113
+
114
+ ctx.ui.notify(`BTW: "${truncate(question, 60)}" — working...`, "info");
115
+
116
+ // Run in isolated process with tool access
117
+ const result = await elyra.exec("elyra", ["-p", "--no-session", historyContext], {
118
+ timeout: 120_000,
119
+ cwd,
120
+ });
121
+
122
+ const response = result.stdout.trim();
123
+ if (result.code !== 0 || !response) {
124
+ const error = result.stderr.trim() || "No response";
125
+ thread.push({ role: "assistant", text: `(error: ${error})`, timestamp: Date.now() });
126
+ ctx.ui.notify(`BTW error: ${truncate(error, 200)}`, "error");
127
+ return;
128
+ }
129
+
130
+ // Add assistant entry
131
+ thread.push({ role: "assistant", text: response, timestamp: Date.now() });
132
+
133
+ // Show response
134
+ ctx.ui.notify(`BTW response:\n\n${response}`, "info");
135
+ },
136
+ });
137
+ }
138
+
139
+ function truncate(text: string, maxLen: number): string {
140
+ if (text.length <= maxLen) return text;
141
+ return `${text.slice(0, maxLen)}...`;
142
+ }
package/package.json ADDED
@@ -0,0 +1,37 @@
1
+ {
2
+ "name": "@elyracode/btw",
3
+ "version": "0.7.15",
4
+ "description": "Side conversations for Elyra -- ask questions while the agent works, inject results back when ready",
5
+ "type": "module",
6
+ "keywords": [
7
+ "elyra-package",
8
+ "btw",
9
+ "side-chat",
10
+ "parallel",
11
+ "subagent"
12
+ ],
13
+ "license": "MIT",
14
+ "author": "Knut W. Horne",
15
+ "repository": {
16
+ "type": "git",
17
+ "url": "git+https://github.com/kwhorne/elyra.git",
18
+ "directory": "packages/btw"
19
+ },
20
+ "elyra": {
21
+ "extensions": [
22
+ "./extensions/index.ts"
23
+ ],
24
+ "skills": [
25
+ "./skills"
26
+ ]
27
+ },
28
+ "peerDependencies": {
29
+ "@elyracode/coding-agent": "*",
30
+ "typebox": "*"
31
+ },
32
+ "scripts": {
33
+ "clean": "echo 'nothing to clean'",
34
+ "build": "echo 'nothing to build'",
35
+ "check": "echo 'nothing to check'"
36
+ }
37
+ }
@@ -0,0 +1,32 @@
1
+ ---
2
+ name: elyra-btw
3
+ description: Side conversations. Use when the user wants to ask a quick question without interrupting the main task, explore an idea in parallel, or have a scratchpad conversation that can be injected back later.
4
+ ---
5
+
6
+ # Side Conversations with /btw
7
+
8
+ ## When to Suggest
9
+
10
+ Suggest `/btw` when:
11
+ - The user asks a tangential question while you're working on something
12
+ - The user wants to check something without derailing the current task
13
+ - The user says "by the way" or "quick question" or "while you're at it"
14
+ - The user wants to brainstorm before committing to an approach
15
+
16
+ ## Commands
17
+
18
+ | Command | What it does |
19
+ |---------|-------------|
20
+ | `/btw <question>` | Ask a question in a parallel side session with tool access |
21
+ | `/btw:inject` | Send the full BTW thread into this conversation |
22
+ | `/btw:summarize` | Summarize the BTW thread and inject the summary |
23
+ | `/btw:clear` | Clear the BTW thread |
24
+ | `/btw:thread` | Show the current BTW thread history |
25
+
26
+ ## Key Behavior
27
+
28
+ - BTW runs in an isolated process — its context is separate from this session
29
+ - BTW has full tool access (read, bash, edit, write, grep, find, ls)
30
+ - BTW thread persists across questions until cleared
31
+ - BTW does NOT affect the main agent's context window
32
+ - Use `/btw:inject` or `/btw:summarize` to bring results back when ready