copilot-tap-extension 0.2.0 → 0.2.5
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 +133 -133
- package/dist/copilot-instructions.md +187 -187
- package/dist/skills/loop/SKILL.md +89 -89
- package/package.json +48 -44
|
@@ -1,89 +1,89 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: loop
|
|
3
|
-
description: "Create a prompt-based scheduled loop with ※ tap. Use for requests like '/loop 5m check the deploy' or any ask to run a prompt on a recurring interval."
|
|
4
|
-
argument-hint: "<interval|idle> <prompt>"
|
|
5
|
-
user-invocable: true
|
|
6
|
-
---
|
|
7
|
-
|
|
8
|
-
Create a timed or idle PromptEmitter with `tap_start_emitter`.
|
|
9
|
-
|
|
10
|
-
## Expected input
|
|
11
|
-
|
|
12
|
-
Interpret the invocation as:
|
|
13
|
-
|
|
14
|
-
1. The first argument is the repeat interval, using values like `30s`, `5m`, `2h`, `1d`, or `idle`.
|
|
15
|
-
2. The rest of the input is the prompt that should be re-run on that schedule.
|
|
16
|
-
|
|
17
|
-
Example (timed):
|
|
18
|
-
|
|
19
|
-
```text
|
|
20
|
-
/loop 5m check the deploy
|
|
21
|
-
```
|
|
22
|
-
|
|
23
|
-
means:
|
|
24
|
-
|
|
25
|
-
- `runInterval = "5m"`
|
|
26
|
-
- `prompt = "check the deploy"`
|
|
27
|
-
|
|
28
|
-
Example (idle):
|
|
29
|
-
|
|
30
|
-
```text
|
|
31
|
-
/loop idle check the deploy
|
|
32
|
-
```
|
|
33
|
-
|
|
34
|
-
means:
|
|
35
|
-
|
|
36
|
-
- `every = "idle"` (re-runs whenever the session is idle)
|
|
37
|
-
- `prompt = "check the deploy"`
|
|
38
|
-
|
|
39
|
-
Timed emitters fire immediately, then repeat on the interval. Idle emitters fire immediately, then re-fire whenever the session becomes idle again (with a short delay between runs to avoid monopolizing the session).
|
|
40
|
-
|
|
41
|
-
## Max iterations
|
|
42
|
-
|
|
43
|
-
When the interval is `idle`, always ask the user for a max iteration count or default to a reasonable number (e.g. 10). Pass it as `maxRuns` to `tap_start_emitter`. This prevents runaway idle loops.
|
|
44
|
-
|
|
45
|
-
For timed intervals, `maxRuns` is optional. Only set it if the user explicitly requests a limit.
|
|
46
|
-
|
|
47
|
-
## Required behavior
|
|
48
|
-
|
|
49
|
-
When this skill is invoked:
|
|
50
|
-
|
|
51
|
-
1. Use `tap_start_emitter`.
|
|
52
|
-
2. Create a **PromptEmitter** with a timed schedule, not a CommandEmitter.
|
|
53
|
-
3. Default to:
|
|
54
|
-
- `lifespan = "temporary"`
|
|
55
|
-
- `subscribe = false`
|
|
56
|
-
4. Pick a concise emitter name (the EventStream is created automatically with the same name).
|
|
57
|
-
5. Do not invent extra EventFilter rules unless the user explicitly asks for them. PromptEmitter events always inject.
|
|
58
|
-
6. If the user explicitly asks to be notified, kept posted, or subscribed to updates, enable the SessionInjector:
|
|
59
|
-
- `subscribe = true`
|
|
60
|
-
- `delivery = "important"`
|
|
61
|
-
7. After creating the emitter, confirm:
|
|
62
|
-
- emitter name
|
|
63
|
-
- EventStream name
|
|
64
|
-
- interval
|
|
65
|
-
- scheduled prompt
|
|
66
|
-
8. After confirming the emitter, stop there. Do not immediately inspect EventStream history or react to background emitter output unless the user explicitly asks for that follow-up.
|
|
67
|
-
|
|
68
|
-
## Why subscribe defaults to false
|
|
69
|
-
|
|
70
|
-
PromptEmitter output is already delivered through two paths:
|
|
71
|
-
|
|
72
|
-
1. **`session.sendAndWait()`** -- the prompt runs inside the session, so Copilot processes and responds to it directly.
|
|
73
|
-
2. **Notification dispatcher** -- each result line is also enqueued via `handlePromptResult` and injected as a background event stream update via `session.send()`.
|
|
74
|
-
|
|
75
|
-
The `subscribe` flag controls a third layer: the **SessionInjector**. When enabled, it additionally pushes system-level messages (emitter started, stopped, errored) into the session.
|
|
76
|
-
|
|
77
|
-
For PromptEmitters, the main results already reach the session without the SessionInjector. Setting `subscribe = true` adds system noise on top of content that is already being delivered. Default to `false` to keep things clean.
|
|
78
|
-
|
|
79
|
-
For **CommandEmitters**, the SessionInjector matters more because it is the mechanism that delivers inject-outcome lines proactively. But even there, the notification dispatcher in the line router already handles inject outcomes directly.
|
|
80
|
-
|
|
81
|
-
In short: `subscribe` is about system messages and extra delivery, not about whether the user sees prompt results.
|
|
82
|
-
|
|
83
|
-
## If the input is incomplete
|
|
84
|
-
|
|
85
|
-
If the interval or prompt body is missing, ask the user for the missing piece instead of guessing.
|
|
86
|
-
|
|
87
|
-
## If the user asks for persistence
|
|
88
|
-
|
|
89
|
-
If the user explicitly asks to keep the emitter across sessions, set `lifespan = "persistent"` and say that it will be restored from config on the next session start.
|
|
1
|
+
---
|
|
2
|
+
name: loop
|
|
3
|
+
description: "Create a prompt-based scheduled loop with ※ tap. Use for requests like '/loop 5m check the deploy' or any ask to run a prompt on a recurring interval."
|
|
4
|
+
argument-hint: "<interval|idle> <prompt>"
|
|
5
|
+
user-invocable: true
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
Create a timed or idle PromptEmitter with `tap_start_emitter`.
|
|
9
|
+
|
|
10
|
+
## Expected input
|
|
11
|
+
|
|
12
|
+
Interpret the invocation as:
|
|
13
|
+
|
|
14
|
+
1. The first argument is the repeat interval, using values like `30s`, `5m`, `2h`, `1d`, or `idle`.
|
|
15
|
+
2. The rest of the input is the prompt that should be re-run on that schedule.
|
|
16
|
+
|
|
17
|
+
Example (timed):
|
|
18
|
+
|
|
19
|
+
```text
|
|
20
|
+
/loop 5m check the deploy
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
means:
|
|
24
|
+
|
|
25
|
+
- `runInterval = "5m"`
|
|
26
|
+
- `prompt = "check the deploy"`
|
|
27
|
+
|
|
28
|
+
Example (idle):
|
|
29
|
+
|
|
30
|
+
```text
|
|
31
|
+
/loop idle check the deploy
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
means:
|
|
35
|
+
|
|
36
|
+
- `every = "idle"` (re-runs whenever the session is idle)
|
|
37
|
+
- `prompt = "check the deploy"`
|
|
38
|
+
|
|
39
|
+
Timed emitters fire immediately, then repeat on the interval. Idle emitters fire immediately, then re-fire whenever the session becomes idle again (with a short delay between runs to avoid monopolizing the session).
|
|
40
|
+
|
|
41
|
+
## Max iterations
|
|
42
|
+
|
|
43
|
+
When the interval is `idle`, always ask the user for a max iteration count or default to a reasonable number (e.g. 10). Pass it as `maxRuns` to `tap_start_emitter`. This prevents runaway idle loops.
|
|
44
|
+
|
|
45
|
+
For timed intervals, `maxRuns` is optional. Only set it if the user explicitly requests a limit.
|
|
46
|
+
|
|
47
|
+
## Required behavior
|
|
48
|
+
|
|
49
|
+
When this skill is invoked:
|
|
50
|
+
|
|
51
|
+
1. Use `tap_start_emitter`.
|
|
52
|
+
2. Create a **PromptEmitter** with a timed schedule, not a CommandEmitter.
|
|
53
|
+
3. Default to:
|
|
54
|
+
- `lifespan = "temporary"`
|
|
55
|
+
- `subscribe = false`
|
|
56
|
+
4. Pick a concise emitter name (the EventStream is created automatically with the same name).
|
|
57
|
+
5. Do not invent extra EventFilter rules unless the user explicitly asks for them. PromptEmitter events always inject.
|
|
58
|
+
6. If the user explicitly asks to be notified, kept posted, or subscribed to updates, enable the SessionInjector:
|
|
59
|
+
- `subscribe = true`
|
|
60
|
+
- `delivery = "important"`
|
|
61
|
+
7. After creating the emitter, confirm:
|
|
62
|
+
- emitter name
|
|
63
|
+
- EventStream name
|
|
64
|
+
- interval
|
|
65
|
+
- scheduled prompt
|
|
66
|
+
8. After confirming the emitter, stop there. Do not immediately inspect EventStream history or react to background emitter output unless the user explicitly asks for that follow-up.
|
|
67
|
+
|
|
68
|
+
## Why subscribe defaults to false
|
|
69
|
+
|
|
70
|
+
PromptEmitter output is already delivered through two paths:
|
|
71
|
+
|
|
72
|
+
1. **`session.sendAndWait()`** -- the prompt runs inside the session, so Copilot processes and responds to it directly.
|
|
73
|
+
2. **Notification dispatcher** -- each result line is also enqueued via `handlePromptResult` and injected as a background event stream update via `session.send()`.
|
|
74
|
+
|
|
75
|
+
The `subscribe` flag controls a third layer: the **SessionInjector**. When enabled, it additionally pushes system-level messages (emitter started, stopped, errored) into the session.
|
|
76
|
+
|
|
77
|
+
For PromptEmitters, the main results already reach the session without the SessionInjector. Setting `subscribe = true` adds system noise on top of content that is already being delivered. Default to `false` to keep things clean.
|
|
78
|
+
|
|
79
|
+
For **CommandEmitters**, the SessionInjector matters more because it is the mechanism that delivers inject-outcome lines proactively. But even there, the notification dispatcher in the line router already handles inject outcomes directly.
|
|
80
|
+
|
|
81
|
+
In short: `subscribe` is about system messages and extra delivery, not about whether the user sees prompt results.
|
|
82
|
+
|
|
83
|
+
## If the input is incomplete
|
|
84
|
+
|
|
85
|
+
If the interval or prompt body is missing, ask the user for the missing piece instead of guessing.
|
|
86
|
+
|
|
87
|
+
## If the user asks for persistence
|
|
88
|
+
|
|
89
|
+
If the user explicitly asks to keep the emitter across sessions, set `lifespan = "persistent"` and say that it will be restored from config on the next session start.
|
package/package.json
CHANGED
|
@@ -1,44 +1,48 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "copilot-tap-extension",
|
|
3
|
-
"version": "0.2.
|
|
4
|
-
"description": "Copilot CLI extension for background event emitters, event streams, and session injection.",
|
|
5
|
-
"type": "module",
|
|
6
|
-
"license": "MIT",
|
|
7
|
-
"
|
|
8
|
-
"
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
"
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
"
|
|
18
|
-
"
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
"
|
|
22
|
-
"
|
|
23
|
-
"
|
|
24
|
-
"
|
|
25
|
-
"
|
|
26
|
-
"
|
|
27
|
-
"
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
"
|
|
31
|
-
"
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
"
|
|
35
|
-
"
|
|
36
|
-
"
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
"
|
|
40
|
-
"
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
1
|
+
{
|
|
2
|
+
"name": "copilot-tap-extension",
|
|
3
|
+
"version": "0.2.5",
|
|
4
|
+
"description": "Copilot CLI extension for background event emitters, event streams, and session injection.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "https://github.com/amitse/copilot-tap-extension"
|
|
10
|
+
},
|
|
11
|
+
"bin": {
|
|
12
|
+
"copilot-tap-extension": "bin/install.mjs"
|
|
13
|
+
},
|
|
14
|
+
"files": [
|
|
15
|
+
"bin/",
|
|
16
|
+
"dist/",
|
|
17
|
+
"README.md",
|
|
18
|
+
"LICENSE"
|
|
19
|
+
],
|
|
20
|
+
"scripts": {
|
|
21
|
+
"build": "node scripts/build.mjs",
|
|
22
|
+
"prepublishOnly": "npm run build",
|
|
23
|
+
"check": "node --check ./src/tap-runtime.mjs && node --check ./.github/extensions/tap/extension.mjs && node --check ./evals/run.mjs && node --check ./examples/heartbeat.mjs",
|
|
24
|
+
"demo:heartbeat": "node ./examples/heartbeat.mjs",
|
|
25
|
+
"evals:list": "node ./evals/run.mjs list",
|
|
26
|
+
"evals:smoke": "node ./evals/run.mjs smoke",
|
|
27
|
+
"evals:run": "node ./evals/run.mjs run --all --concurrency 10",
|
|
28
|
+
"evals:validate-modes": "node ./evals/run.mjs validate-modes",
|
|
29
|
+
"version:patch": "npm version patch -m \"v%s\"",
|
|
30
|
+
"version:minor": "npm version minor -m \"v%s\"",
|
|
31
|
+
"version:major": "npm version major -m \"v%s\""
|
|
32
|
+
},
|
|
33
|
+
"keywords": [
|
|
34
|
+
"copilot",
|
|
35
|
+
"copilot-cli",
|
|
36
|
+
"extensions",
|
|
37
|
+
"tap",
|
|
38
|
+
"event-emitter",
|
|
39
|
+
"event-stream",
|
|
40
|
+
"event-filter"
|
|
41
|
+
],
|
|
42
|
+
"devDependencies": {
|
|
43
|
+
"@github/copilot-sdk": "^0.2.2",
|
|
44
|
+
"esbuild": "^0.28.0",
|
|
45
|
+
"playwright": "^1.59.1",
|
|
46
|
+
"yaml": "^2.8.3"
|
|
47
|
+
}
|
|
48
|
+
}
|