copilot-tap-extension 0.2.0 → 1.0.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/LICENSE +21 -21
- package/README.md +227 -207
- package/bin/install.mjs +183 -133
- package/dist/copilot-instructions.md +187 -187
- package/dist/extension.mjs +112 -19
- package/dist/skills/loop/SKILL.md +88 -89
- package/dist/version.json +3 -0
- package/package.json +48 -44
package/LICENSE
CHANGED
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
MIT License
|
|
2
|
-
|
|
3
|
-
Copyright (c) 2026
|
|
4
|
-
|
|
5
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
-
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
-
in the Software without restriction, including without limitation the rights
|
|
8
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
-
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
-
furnished to do so, subject to the following conditions:
|
|
11
|
-
|
|
12
|
-
The above copyright notice and this permission notice shall be included in all
|
|
13
|
-
copies or substantial portions of the Software.
|
|
14
|
-
|
|
15
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
-
SOFTWARE.
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,207 +1,227 @@
|
|
|
1
|
-
<p align="center">
|
|
2
|
-
<img src="./tap.svg" width="80" height="80" alt="※ tap">
|
|
3
|
-
</p>
|
|
4
|
-
|
|
5
|
-
<h1 align="center">※ tap</h1>
|
|
6
|
-
|
|
7
|
-
<p align="center">
|
|
8
|
-
<em>Background event filtering and injection for Copilot CLI.</em><br>
|
|
9
|
-
<sub>Look here, this matters.</sub>
|
|
10
|
-
</p>
|
|
11
|
-
|
|
12
|
-
---
|
|
13
|
-
|
|
14
|
-
Copilot CLI already runs background tasks, but their output sits idle until you check it. This extension adds **filtering and auto-injection** on top of that capability.
|
|
15
|
-
|
|
16
|
-
Background commands and agent prompts produce output line by line. An EventFilter decides what to drop, what to store, and what to push into your session. Important events arrive without you asking.
|
|
17
|
-
|
|
18
|
-
| Without this extension | With it |
|
|
19
|
-
| --- | --- |
|
|
20
|
-
| You check background output manually | Important lines are pushed into your conversation |
|
|
21
|
-
| No way to filter noisy output | Rules drop noise, keep context, inject signal |
|
|
22
|
-
| No scheduled prompt re-runs | Prompts repeat on a timer or fire when idle |
|
|
23
|
-
| Output stays in the background task | Matched events arrive in your session as they happen |
|
|
24
|
-
|
|
25
|
-
## Who is this for?
|
|
26
|
-
|
|
27
|
-
- You tail logs and want failures injected into your session while you keep coding.
|
|
28
|
-
- You maintain a repo and want PR reviews, CI failures, or new issues surfaced automatically.
|
|
29
|
-
- You run long builds and want to know when they finish or break -- without watching.
|
|
30
|
-
- You poll an API or dashboard and want the agent to react when something changes.
|
|
31
|
-
- You re-ask the same prompt periodically and want it on a timer or running whenever idle.
|
|
32
|
-
|
|
33
|
-
## Get started
|
|
34
|
-
|
|
35
|
-
Prerequisites: [Node.js](https://nodejs.org/) and [Copilot CLI](https://docs.github.com/en/copilot/github-copilot-in-the-cli).
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
```
|
|
157
|
-
.
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
[
|
|
1
|
+
<p align="center">
|
|
2
|
+
<img src="./tap.svg" width="80" height="80" alt="※ tap">
|
|
3
|
+
</p>
|
|
4
|
+
|
|
5
|
+
<h1 align="center">※ tap</h1>
|
|
6
|
+
|
|
7
|
+
<p align="center">
|
|
8
|
+
<em>Background event filtering and injection for Copilot CLI.</em><br>
|
|
9
|
+
<sub>Look here, this matters.</sub>
|
|
10
|
+
</p>
|
|
11
|
+
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
Copilot CLI already runs background tasks, but their output sits idle until you check it. This extension adds **filtering and auto-injection** on top of that capability.
|
|
15
|
+
|
|
16
|
+
Background commands and agent prompts produce output line by line. An EventFilter decides what to drop, what to store, and what to push into your session. Important events arrive without you asking.
|
|
17
|
+
|
|
18
|
+
| Without this extension | With it |
|
|
19
|
+
| --- | --- |
|
|
20
|
+
| You check background output manually | Important lines are pushed into your conversation |
|
|
21
|
+
| No way to filter noisy output | Rules drop noise, keep context, inject signal |
|
|
22
|
+
| No scheduled prompt re-runs | Prompts repeat on a timer or fire when idle |
|
|
23
|
+
| Output stays in the background task | Matched events arrive in your session as they happen |
|
|
24
|
+
|
|
25
|
+
## Who is this for?
|
|
26
|
+
|
|
27
|
+
- You tail logs and want failures injected into your session while you keep coding.
|
|
28
|
+
- You maintain a repo and want PR reviews, CI failures, or new issues surfaced automatically.
|
|
29
|
+
- You run long builds and want to know when they finish or break -- without watching.
|
|
30
|
+
- You poll an API or dashboard and want the agent to react when something changes.
|
|
31
|
+
- You re-ask the same prompt periodically and want it on a timer or running whenever idle.
|
|
32
|
+
|
|
33
|
+
## Get started
|
|
34
|
+
|
|
35
|
+
Prerequisites: [Node.js](https://nodejs.org/) ≥ 20 and [Copilot CLI](https://docs.github.com/en/copilot/github-copilot-in-the-cli).
|
|
36
|
+
|
|
37
|
+
### Install via npx (recommended)
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
# Install globally (available in all projects)
|
|
41
|
+
npx copilot-tap-extension
|
|
42
|
+
|
|
43
|
+
# Install locally (project-scoped, committed with your repo)
|
|
44
|
+
npx copilot-tap-extension --local
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
This installs the bundled extension, the `/loop` skill, and the agent instructions to the appropriate Copilot directory. Run `npx copilot-tap-extension --help` for all options.
|
|
48
|
+
|
|
49
|
+
To update to the latest version, re-run the same command with `--force`:
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
npx copilot-tap-extension --force
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
### Install from source
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
git clone https://github.com/amitse/copilot-tap-extension
|
|
59
|
+
cd copilot-tap-extension
|
|
60
|
+
npm install
|
|
61
|
+
cp tap.config.example.json tap.config.json
|
|
62
|
+
copilot
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
On Windows, replace `cp` with `copy`.
|
|
66
|
+
|
|
67
|
+
The config file tells the extension which emitters to auto-start. The example defines a heartbeat emitter:
|
|
68
|
+
|
|
69
|
+
```json
|
|
70
|
+
{
|
|
71
|
+
"emitters": [
|
|
72
|
+
{
|
|
73
|
+
"name": "heartbeat",
|
|
74
|
+
"command": "node ./examples/heartbeat.mjs",
|
|
75
|
+
"autoStart": true,
|
|
76
|
+
"eventFilter": [
|
|
77
|
+
{ "match": "booting", "outcome": "drop" },
|
|
78
|
+
{ "match": "warning|error", "outcome": "inject" },
|
|
79
|
+
{ "match": ".*", "outcome": "keep" }
|
|
80
|
+
]
|
|
81
|
+
}
|
|
82
|
+
]
|
|
83
|
+
}
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
This runs the heartbeat script on session start, drops boot messages, injects warnings and errors, and keeps everything else in the stream.
|
|
87
|
+
|
|
88
|
+
Once inside the session, describe what you want in natural language. You can also use `/loop` to set up scheduled prompts directly:
|
|
89
|
+
|
|
90
|
+
> _"Watch my build logs and tell me if anything fails"_
|
|
91
|
+
|
|
92
|
+
> _"/loop 5m check for new PR review comments"_
|
|
93
|
+
|
|
94
|
+
> _"Tail the API logs, inject errors, drop health checks"_
|
|
95
|
+
|
|
96
|
+
The agent translates these into emitter and filter configurations behind the scenes.
|
|
97
|
+
|
|
98
|
+
## How it works
|
|
99
|
+
|
|
100
|
+
An **EventEmitter** is a background worker attached to your session. There are two kinds:
|
|
101
|
+
|
|
102
|
+
- A **CommandEmitter** runs a shell command and captures stdout line by line.
|
|
103
|
+
- A **PromptEmitter** runs an agent prompt -- once, on a recurring interval, or whenever the session is idle.
|
|
104
|
+
|
|
105
|
+
Each emitter writes to an **EventStream**, an in-memory log of accepted output. The stream is created automatically and shares the emitter's name.
|
|
106
|
+
|
|
107
|
+
For CommandEmitters, an **EventFilter** decides what happens to each line. It is an ordered list of regex rules -- first match wins:
|
|
108
|
+
|
|
109
|
+
| Outcome | What happens |
|
|
110
|
+
| --- | --- |
|
|
111
|
+
| **drop** | Discarded. Never enters the stream. |
|
|
112
|
+
| **keep** | Stored in the EventStream for later review. |
|
|
113
|
+
| **surface** | Stored and shown in the session timeline. |
|
|
114
|
+
| **inject** | Stored, shown, and pushed into your conversation. |
|
|
115
|
+
|
|
116
|
+
Outcomes are inclusive: **inject** implies **surface**, and **surface** implies **keep**. Only **drop** is outside this chain.
|
|
117
|
+
|
|
118
|
+
PromptEmitter output bypasses the filter and always injects.
|
|
119
|
+
|
|
120
|
+
A **SessionInjector** controls whether stream updates are pushed into your session proactively. Enable it when you want important events to arrive as they happen.
|
|
121
|
+
|
|
122
|
+
Filters are hot-swappable while the emitter runs. `ownership="modelOwned"` lets the agent tune rules; `ownership="userOwned"` locks them to your specification.
|
|
123
|
+
|
|
124
|
+
Emitters are **temporary** by default and last only for the current session. Set `lifespan="persistent"` to save an emitter to config and restore it next session.
|
|
125
|
+
|
|
126
|
+
Run schedules control timing: **continuous** (command runs until stopped), **timed** (repeats on an interval), **oneTime** (runs once), or **idle** (prompt re-runs when the session has nothing else to do).
|
|
127
|
+
|
|
128
|
+
## What you can do
|
|
129
|
+
|
|
130
|
+
**Watch something in the background**
|
|
131
|
+
|
|
132
|
+
Tell Copilot to watch a log, build, or command. It creates a CommandEmitter, filters the output, and only interrupts you when something needs attention.
|
|
133
|
+
|
|
134
|
+
```
|
|
135
|
+
"Start a deploy watcher that tails our CI logs.
|
|
136
|
+
Drop health checks, inject any failures or rollbacks."
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
You keep coding. Twenty minutes later, Copilot interrupts: "Run 48291: deployment rollback triggered on prod."
|
|
140
|
+
|
|
141
|
+
**Loop a prompt on a schedule**
|
|
142
|
+
|
|
143
|
+
A PromptEmitter re-runs an agent prompt at a fixed interval. Useful for PR comments, CI status, or ticket queues.
|
|
144
|
+
|
|
145
|
+
```
|
|
146
|
+
/loop 15m Check for new failing CI runs or PR review comments.
|
|
147
|
+
Summarize only actionable items.
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
Every 15 minutes the agent scans and reports back. No news means no interruption.
|
|
151
|
+
|
|
152
|
+
**Run a prompt when idle**
|
|
153
|
+
|
|
154
|
+
Use `/loop idle` to re-run a prompt whenever the session has nothing else to do. Set `maxRuns` to cap iterations.
|
|
155
|
+
|
|
156
|
+
```
|
|
157
|
+
/loop idle Scan for new issues labeled urgent. Summarize what changed.
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
The prompt fires immediately, then re-fires after each idle period. It stops after reaching the iteration limit.
|
|
161
|
+
|
|
162
|
+
**Tune the filter live**
|
|
163
|
+
|
|
164
|
+
The recommended approach is a **keep-all bootstrap**: start with no EventFilter rules so all output flows into the stream. Read the stream history to learn what the output looks like, then add rules progressively:
|
|
165
|
+
|
|
166
|
+
```
|
|
167
|
+
1. Drop the noise: { "match": "health_check|heartbeat", "outcome": "drop" }
|
|
168
|
+
2. Inject the signal: { "match": "error|failure|rollback", "outcome": "inject" }
|
|
169
|
+
3. Keep the rest: { "match": ".*", "outcome": "keep" }
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
Rules can be added or changed while the emitter is running. You never need to restart it to adjust filtering.
|
|
173
|
+
|
|
174
|
+
## Repo layout
|
|
175
|
+
|
|
176
|
+
```text
|
|
177
|
+
.github/
|
|
178
|
+
extensions/tap/extension.mjs # extension entry point (loads the runtime)
|
|
179
|
+
skills/loop/ # /loop skill for scheduled and idle prompts
|
|
180
|
+
copilot-instructions.md # agent guidance for using this extension
|
|
181
|
+
src/
|
|
182
|
+
emitter/ # supervisor, lifecycle, spawn, line router
|
|
183
|
+
streams/ # EventStream store and notification dispatcher
|
|
184
|
+
tools/ # tool definitions (emitters, streams, filters)
|
|
185
|
+
config/ # persistent config store (tap.config.json)
|
|
186
|
+
format/ # display formatters for emitters and streams
|
|
187
|
+
session/ # session port abstraction
|
|
188
|
+
util/ # normalization, text, time, path helpers
|
|
189
|
+
hooks.mjs # session lifecycle hooks
|
|
190
|
+
tap-runtime.mjs # runtime factory (wires everything together)
|
|
191
|
+
tap.svg # ※ mark — the tap icon
|
|
192
|
+
docs/
|
|
193
|
+
evolution-of-tap-icon.html # design evolution: 20 agents, 20 metaphors, one mark
|
|
194
|
+
examples/heartbeat.mjs # demo CommandEmitter
|
|
195
|
+
evals/ # eval harness and test cases
|
|
196
|
+
tap.config.example.json # starter config (copy to tap.config.json)
|
|
197
|
+
PLAN.md # ubiquitous language and design decisions
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
## Further reading
|
|
201
|
+
|
|
202
|
+
| Document | When to read it |
|
|
203
|
+
| --- | --- |
|
|
204
|
+
| [Reference](./docs/reference.md) | Look up tool parameters, config fields, or the event pipeline |
|
|
205
|
+
| [Use cases and patterns](./docs/use-cases.md) | Recipes for deploy watchers, PR monitors, log tailers, and more |
|
|
206
|
+
| [Evals](./docs/evals.md) | Run or extend the automated test suite |
|
|
207
|
+
| [Copilot instructions](./src/copilot-instructions.md) | Understand or customize how the agent uses this extension |
|
|
208
|
+
| [Implementation plan](./PLAN.md) | Ubiquitous language and naming conventions for contributors |
|
|
209
|
+
| [Evolution of the ※ icon](./docs/evolution-of-tap-icon.html) | 20 metaphors, 10 variants, one mark — the design story behind ※ tap |
|
|
210
|
+
|
|
211
|
+
## Contributing
|
|
212
|
+
|
|
213
|
+
Before opening a PR, run the local checks:
|
|
214
|
+
|
|
215
|
+
```bash
|
|
216
|
+
npm run check # syntax check
|
|
217
|
+
npm run evals:smoke # smoke test
|
|
218
|
+
npm run evals:validate-modes # interactive vs prompt-mode gap
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
The runtime has no production dependencies. Dev dependencies (`@github/copilot-sdk`, `yaml`) are used for the eval harness and extension loading.
|
|
222
|
+
|
|
223
|
+
If you add a new tool or change the event pipeline, update the [reference](./docs/reference.md). If you add a new workflow pattern, add it to [use cases](./docs/use-cases.md).
|
|
224
|
+
|
|
225
|
+
## License
|
|
226
|
+
|
|
227
|
+
[MIT](./LICENSE)
|