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.
@@ -1,89 +1,88 @@
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 delivered through a single path:
71
+
72
+ 1. **`session.send()`** -- the prompt is dispatched fire-and-forget; Copilot processes and responds to it directly inside the session.
73
+
74
+ The `subscribe` flag controls the **SessionInjector**. When enabled, it additionally pushes system-level messages (emitter started, stopped, errored) into the session.
75
+
76
+ 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.
77
+
78
+ 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.
79
+
80
+ In short: `subscribe` is about system messages and extra delivery, not about whether the user sees prompt results.
81
+
82
+ ## If the input is incomplete
83
+
84
+ If the interval or prompt body is missing, ask the user for the missing piece instead of guessing.
85
+
86
+ ## If the user asks for persistence
87
+
88
+ 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.
@@ -0,0 +1,3 @@
1
+ {
2
+ "version": "1.0.0"
3
+ }
package/package.json CHANGED
@@ -1,44 +1,48 @@
1
- {
2
- "name": "copilot-tap-extension",
3
- "version": "0.2.0",
4
- "description": "Copilot CLI extension for background event emitters, event streams, and session injection.",
5
- "type": "module",
6
- "license": "MIT",
7
- "bin": {
8
- "copilot-tap-extension": "./bin/install.mjs"
9
- },
10
- "files": [
11
- "bin/",
12
- "dist/",
13
- "README.md",
14
- "LICENSE"
15
- ],
16
- "scripts": {
17
- "build": "node scripts/build.mjs",
18
- "prepublishOnly": "npm run build",
19
- "check": "node --check ./src/tap-runtime.mjs && node --check ./.github/extensions/tap/extension.mjs && node --check ./evals/run.mjs && node --check ./examples/heartbeat.mjs",
20
- "demo:heartbeat": "node ./examples/heartbeat.mjs",
21
- "evals:list": "node ./evals/run.mjs list",
22
- "evals:smoke": "node ./evals/run.mjs smoke",
23
- "evals:run": "node ./evals/run.mjs run --all --concurrency 10",
24
- "evals:validate-modes": "node ./evals/run.mjs validate-modes",
25
- "version:patch": "npm version patch -m \"v%s\"",
26
- "version:minor": "npm version minor -m \"v%s\"",
27
- "version:major": "npm version major -m \"v%s\""
28
- },
29
- "keywords": [
30
- "copilot",
31
- "copilot-cli",
32
- "extensions",
33
- "tap",
34
- "event-emitter",
35
- "event-stream",
36
- "event-filter"
37
- ],
38
- "devDependencies": {
39
- "@github/copilot-sdk": "^0.2.2",
40
- "esbuild": "^0.28.0",
41
- "playwright": "^1.59.1",
42
- "yaml": "^2.8.3"
43
- }
44
- }
1
+ {
2
+ "name": "copilot-tap-extension",
3
+ "version": "1.0.0",
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 ./src/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
+ }