@cursor/july 0.1.41 → 0.1.43
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/AGENTS.md +10 -3
- package/dist/bin/agent-serve.js +3 -1
- package/dist/channels/github/api.d.ts +5 -0
- package/dist/channels/github/api.d.ts.map +1 -1
- package/dist/channels/github/api.js +18 -0
- package/dist/channels/github/defaults.d.ts +4 -5
- package/dist/channels/github/defaults.d.ts.map +1 -1
- package/dist/channels/github/defaults.js +27 -1
- package/dist/channels/github/github-channel.d.ts.map +1 -1
- package/dist/channels/github/github-channel.js +28 -5
- package/dist/channels/github/index.d.ts +1 -0
- package/dist/channels/github/index.d.ts.map +1 -1
- package/dist/channels/github/index.js +1 -0
- package/dist/channels/github/progress.d.ts +54 -0
- package/dist/channels/github/progress.d.ts.map +1 -0
- package/dist/channels/github/progress.js +168 -0
- package/dist/channels/github/state.d.ts +2 -0
- package/dist/channels/github/state.d.ts.map +1 -1
- package/dist/channels/github/state.js +1 -1
- package/dist/channels/github/types.d.ts +8 -4
- package/dist/channels/github/types.d.ts.map +1 -1
- package/dist/channels/slack/slack-channel.d.ts +4 -0
- package/dist/channels/slack/slack-channel.d.ts.map +1 -1
- package/dist/channels/slack/slack-channel.js +4 -0
- package/dist/docs/404.html +2 -2
- package/dist/docs/ab.html +4 -4
- package/dist/docs/assets/{app.mIw24pb1.js → app.DsTLo2j1.js} +1 -1
- package/dist/docs/assets/chunks/@localSearchIndexroot.BZx4pmZL.js +1 -0
- package/dist/docs/assets/chunks/{VPLocalSearchBox.hOzpPwrG.js → VPLocalSearchBox.DoVfutcV.js} +1 -1
- package/dist/docs/assets/chunks/{theme.BtFhUYmh.js → theme.DtuVtKkc.js} +2 -2
- package/dist/docs/assets/{deployment.md.BHVjVqRa.js → deployment.md.Cdp4rTE4.js} +1 -1
- package/dist/docs/assets/{guides_github.md.R2QlpR75.js → guides_github.md.DSg0j9qj.js} +29 -3
- package/dist/docs/assets/{guides_github.md.R2QlpR75.lean.js → guides_github.md.DSg0j9qj.lean.js} +1 -1
- package/dist/docs/assets/guides_opentelemetry.md.DmyUwC5R.js +20 -0
- package/dist/docs/assets/guides_opentelemetry.md.DmyUwC5R.lean.js +1 -0
- package/dist/docs/assets/{index.md.BKpbkCa6.js → index.md.CMc5FP7E.js} +2 -1
- package/dist/docs/assets/{reference_channels.md.BIabFUAI.js → reference_channels.md.MN8iDy8V.js} +1 -1
- package/dist/docs/assets/reference_hooks.md.4cbRRIIu.js +14 -0
- package/dist/docs/assets/{reference_hooks.md.BHeG-vjK.lean.js → reference_hooks.md.4cbRRIIu.lean.js} +1 -1
- package/dist/docs/assets/{reference_project-layout.md._XdeMahr.js → reference_project-layout.md.D3MdHM2z.js} +2 -1
- package/dist/docs/assets/templates_triage.md.CConZt1z.js +11 -0
- package/dist/docs/assets/templates_triage.md.CConZt1z.lean.js +1 -0
- package/dist/docs/building-with-agents.html +5 -5
- package/dist/docs/concepts.html +5 -5
- package/dist/docs/deployment.html +6 -6
- package/dist/docs/evals.html +4 -4
- package/dist/docs/example-agents/approval-buddy.html +4 -4
- package/dist/docs/example-agents/benny.html +4 -4
- package/dist/docs/example-agents/bugbot.html +4 -4
- package/dist/docs/example-agents/codebase-wiki.html +4 -4
- package/dist/docs/example-agents/codeowners-review.html +4 -4
- package/dist/docs/example-agents/concierge.html +4 -4
- package/dist/docs/example-agents/fsd.html +4 -4
- package/dist/docs/example-agents/index.html +5 -5
- package/dist/docs/example-agents/knowledge-base.html +4 -4
- package/dist/docs/example-agents/oncall.html +4 -4
- package/dist/docs/example-agents/security-reviewer.html +4 -4
- package/dist/docs/example-agents/slack-agent.html +4 -4
- package/dist/docs/example-agents/weather-agent.html +4 -4
- package/dist/docs/guides/agent-to-agent.html +4 -4
- package/dist/docs/guides/cloud-runtime.html +5 -5
- package/dist/docs/guides/github.html +33 -7
- package/dist/docs/guides/human-in-the-loop.html +4 -4
- package/dist/docs/guides/mcp-oauth.html +4 -4
- package/dist/docs/guides/opentelemetry.html +44 -0
- package/dist/docs/guides/slack.html +4 -4
- package/dist/docs/guides/webhooks.html +4 -4
- package/dist/docs/hashmap.json +1 -1
- package/dist/docs/hillclimbing.html +4 -4
- package/dist/docs/index.html +7 -6
- package/dist/docs/quickstart.html +4 -4
- package/dist/docs/reference/agent-config.html +4 -4
- package/dist/docs/reference/artifacts.html +4 -4
- package/dist/docs/reference/channels.html +6 -6
- package/dist/docs/reference/cli.html +4 -4
- package/dist/docs/reference/connections.html +4 -4
- package/dist/docs/reference/hooks.html +9 -7
- package/dist/docs/reference/http-api.html +4 -4
- package/dist/docs/reference/instructions.html +4 -4
- package/dist/docs/reference/playground.html +4 -4
- package/dist/docs/reference/project-layout.html +7 -6
- package/dist/docs/reference/prompt.html +4 -4
- package/dist/docs/reference/schedules.html +4 -4
- package/dist/docs/reference/sessions.html +4 -4
- package/dist/docs/reference/skills.html +4 -4
- package/dist/docs/reference/subagents.html +4 -4
- package/dist/docs/reference/tools.html +4 -4
- package/dist/docs/scaffolding-agents.html +4 -4
- package/dist/docs/storage.html +4 -4
- package/dist/docs/templates/triage.html +35 -0
- package/dist/docs/troubleshooting.html +4 -4
- package/dist/hooks.d.ts +3 -1
- package/dist/hooks.d.ts.map +1 -1
- package/dist/hooks.js +3 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/internal/cli-ax.d.ts +1 -0
- package/dist/internal/cli-ax.d.ts.map +1 -1
- package/dist/internal/cli-ax.js +18 -3
- package/dist/internal/discovery.d.ts.map +1 -1
- package/dist/internal/discovery.js +36 -4
- package/dist/internal/distribution.d.ts.map +1 -1
- package/dist/internal/distribution.js +1 -0
- package/dist/internal/init-project.d.ts +24 -0
- package/dist/internal/init-project.d.ts.map +1 -1
- package/dist/internal/init-project.js +126 -7
- package/dist/internal/otel/attrs.d.ts +7 -0
- package/dist/internal/otel/attrs.d.ts.map +1 -0
- package/dist/internal/otel/attrs.js +13 -0
- package/dist/internal/otel/collector.d.ts +16 -0
- package/dist/internal/otel/collector.d.ts.map +1 -0
- package/dist/internal/otel/collector.js +564 -0
- package/dist/internal/otel/config.d.ts +42 -0
- package/dist/internal/otel/config.d.ts.map +1 -0
- package/dist/internal/otel/config.js +236 -0
- package/dist/internal/otel/http.d.ts +11 -0
- package/dist/internal/otel/http.d.ts.map +1 -0
- package/dist/internal/otel/http.js +97 -0
- package/dist/internal/otel/runtime.d.ts +21 -0
- package/dist/internal/otel/runtime.d.ts.map +1 -0
- package/dist/internal/otel/runtime.js +188 -0
- package/dist/internal/server.d.ts.map +1 -1
- package/dist/internal/server.js +25 -1
- package/dist/internal/session-engine.d.ts +10 -1
- package/dist/internal/session-engine.d.ts.map +1 -1
- package/dist/internal/session-engine.js +36 -2
- package/dist/memory.d.ts +4 -0
- package/dist/memory.d.ts.map +1 -1
- package/dist/memory.js +4 -0
- package/dist/otel.d.ts +88 -0
- package/dist/otel.d.ts.map +1 -0
- package/dist/otel.js +64 -0
- package/dist/playground/assets/{index-B3HBneZZ.js → index-D-DIYQzw.js} +31 -31
- package/dist/playground/assets/index-DQTH622f.css +1 -0
- package/dist/playground/index.html +2 -2
- package/dist/types.d.ts +31 -4
- package/dist/types.d.ts.map +1 -1
- package/docs/README.md +3 -0
- package/docs/deployment.md +2 -1
- package/docs/guides/github.md +79 -6
- package/docs/guides/opentelemetry.md +184 -0
- package/docs/reference/channels.md +3 -1
- package/docs/reference/hooks.md +25 -5
- package/docs/reference/project-layout.md +2 -0
- package/docs/templates/triage.md +147 -0
- package/package.json +23 -1
- package/skills/create-agent/SKILL.md +2 -2
- package/skills/debug/SKILL.md +4 -0
- package/skills/framework-map/SKILL.md +2 -0
- package/skills/otel/SKILL.md +80 -0
- package/src/bin/agent-serve.ts +3 -1
- package/src/channels/github/api.ts +22 -0
- package/src/channels/github/defaults.ts +27 -6
- package/src/channels/github/github-channel.ts +27 -1
- package/src/channels/github/index.ts +1 -0
- package/src/channels/github/progress.ts +243 -0
- package/src/channels/github/state.ts +3 -0
- package/src/channels/github/types.ts +8 -4
- package/src/channels/slack/slack-channel.ts +4 -0
- package/src/hooks.ts +3 -1
- package/src/index.ts +6 -0
- package/src/internal/cli-ax.ts +19 -1
- package/src/internal/discovery.ts +59 -4
- package/src/internal/distribution.ts +1 -0
- package/src/internal/init-project.ts +150 -7
- package/src/internal/otel/attrs.ts +18 -0
- package/src/internal/otel/collector.ts +796 -0
- package/src/internal/otel/config.ts +307 -0
- package/src/internal/otel/http.ts +126 -0
- package/src/internal/otel/runtime.ts +271 -0
- package/src/internal/server.ts +38 -1
- package/src/internal/session-engine.ts +52 -0
- package/src/memory.ts +4 -0
- package/src/otel.ts +155 -0
- package/src/types.ts +29 -4
- package/templates/triage/README.md +48 -0
- package/templates/triage/agent/agent.ts +14 -0
- package/templates/triage/agent/channels/intake.ts +20 -0
- package/templates/triage/agent/channels/slack.ts +3 -0
- package/templates/triage/agent/hooks/memory.ts +3 -0
- package/templates/triage/agent/instructions.md +27 -0
- package/templates/triage/agent/skills/triage-rubric.md +43 -0
- package/templates/triage/agent/tools/record_triage.ts +23 -0
- package/templates/triage/evals/evals.config.ts +5 -0
- package/templates/triage/evals/triage.eval.ts +43 -0
- package/templates/triage/package.json +18 -0
- package/templates/triage/tsconfig.json +12 -0
- package/dist/docs/assets/chunks/@localSearchIndexroot.BA7V8dEJ.js +0 -1
- package/dist/docs/assets/reference_hooks.md.BHeG-vjK.js +0 -12
- package/dist/playground/assets/index-Bqk9nplh.css +0 -1
- /package/dist/docs/assets/{deployment.md.BHVjVqRa.lean.js → deployment.md.Cdp4rTE4.lean.js} +0 -0
- /package/dist/docs/assets/{index.md.BKpbkCa6.lean.js → index.md.CMc5FP7E.lean.js} +0 -0
- /package/dist/docs/assets/{reference_channels.md.BIabFUAI.lean.js → reference_channels.md.MN8iDy8V.lean.js} +0 -0
- /package/dist/docs/assets/{reference_project-layout.md._XdeMahr.lean.js → reference_project-layout.md.D3MdHM2z.lean.js} +0 -0
package/docs/reference/hooks.md
CHANGED
|
@@ -27,7 +27,9 @@ import { defineHook } from "@cursor/july/hooks";
|
|
|
27
27
|
export default defineHook({
|
|
28
28
|
events: {
|
|
29
29
|
async "turn.completed"(event, ctx) {
|
|
30
|
-
|
|
30
|
+
const prior = await ctx.host.kv.get("last-result");
|
|
31
|
+
const notes = await ctx.host.files.read("notes.md");
|
|
32
|
+
console.log("turn done", ctx.session.id, event.data.usage, prior, notes);
|
|
31
33
|
},
|
|
32
34
|
async "turn.failed"(event, ctx) {
|
|
33
35
|
// page, count, or record
|
|
@@ -46,9 +48,14 @@ for everything. Handlers receive the event with its envelope (`index`,
|
|
|
46
48
|
| `ctx.session` | Read-only session info: id, channel, mode, auth |
|
|
47
49
|
| `ctx.agent` | `{ name }` of the agent the event belongs to |
|
|
48
50
|
| `ctx.channel` | `{ id, continuationToken }` for the owning channel |
|
|
49
|
-
| `ctx.stateRoot` | The agent's durable state root
|
|
51
|
+
| `ctx.stateRoot` | The agent's durable state root. Prefer `ctx.host.kv` / `ctx.host.files` for derived state; this tree resets on hosted replace |
|
|
52
|
+
| `ctx.host` | Shared host services; same as a tool's `ctx.host`. Pull JSON with `ctx.host.kv` and file-shaped state with `ctx.host.files` (session-bound by default; pass `{ scope: "deployment" }` for agent-wide files) |
|
|
50
53
|
| `ctx.artifacts` | Session-bound [artifacts](./artifacts.md) facade: `tag` auto-fills the session |
|
|
51
54
|
|
|
55
|
+
Hook context includes `ctx.host`, the same shared services a tool
|
|
56
|
+
gets. Persist JSON with `ctx.host.kv` and file-shaped state with
|
|
57
|
+
`ctx.host.files`. Hooks observe; they do not own delivery surfaces.
|
|
58
|
+
|
|
52
59
|
## Hooks, channel events, evals, or A/B?
|
|
53
60
|
|
|
54
61
|
All of them consume the same stream, for different jobs:
|
|
@@ -60,6 +67,15 @@ All of them consume the same stream, for different jobs:
|
|
|
60
67
|
| Can affect the run | no | yes, it owns the surface | n/a | yes through arm instructions or `session.abs`; collection is observe-only |
|
|
61
68
|
| Authored at | `agent/hooks/*.ts` | channel config | `evals/**/*.eval.ts` | [`agent/ab.ts` or `agent/ab/*.ts`](../ab.md) |
|
|
62
69
|
|
|
70
|
+
For GitHub commit status and sticky PR banners, use
|
|
71
|
+
`githubChannel({ progress: { commitStatus, banner } })` from
|
|
72
|
+
`@cursor/july/channels/github`. That is the supported Autofix-style
|
|
73
|
+
path. See [GitHub: Show PR progress](../guides/github.md#show-pr-progress).
|
|
74
|
+
Override channel `events` only when the lifecycle is custom (for
|
|
75
|
+
example [Approval Buddy](../example-agents/approval-buddy.md)'s
|
|
76
|
+
never-red status from tool output). Do not use `defineHook` for those
|
|
77
|
+
writes.
|
|
78
|
+
|
|
63
79
|
## Patterns
|
|
64
80
|
|
|
65
81
|
Usage metering: subscribe to `turn.completed` and forward
|
|
@@ -70,7 +86,9 @@ Failure alerting: `turn.failed` carries the message, and
|
|
|
70
86
|
|
|
71
87
|
Derived state: `agent.bound` fires when the Cursor SDK agent id is known
|
|
72
88
|
(`bc-…` on cloud). A PR agent can record PR → agent id from it in a
|
|
73
|
-
hook
|
|
89
|
+
hook with `ctx.host.kv`, so later webhook wakes resume the same cloud
|
|
90
|
+
conversation. Prefer `ctx.host.kv` or `ctx.host.files` for ids that
|
|
91
|
+
must survive hosted replace. `stateRoot` resets on replace.
|
|
74
92
|
|
|
75
93
|
Transcript export: subscribe to `"*"` and append to your own store. The
|
|
76
94
|
NDJSON envelope is already ordered and replayable.
|
|
@@ -80,8 +98,10 @@ NDJSON envelope is already ordered and replayable.
|
|
|
80
98
|
Continue with these pages:
|
|
81
99
|
|
|
82
100
|
- [Sessions and streaming](./sessions.md): every event a hook can see
|
|
83
|
-
- [
|
|
84
|
-
|
|
101
|
+
- [OpenTelemetry](../guides/opentelemetry.md): OTLP traces and metrics
|
|
102
|
+
from the same event stream
|
|
103
|
+
- [Deployment](../deployment.md#observability): runtime logs and export
|
|
104
|
+
paths
|
|
85
105
|
- [Channels](./channels.md#events): the delivery-side counterpart
|
|
86
106
|
- [Live A/B metrics](../ab.md): sticky variants over the same event
|
|
87
107
|
stream
|
|
@@ -53,6 +53,7 @@ my-agent/
|
|
|
53
53
|
│ │ └── github.ts # the GitHub webhook channel pack
|
|
54
54
|
│ ├── hooks/
|
|
55
55
|
│ │ └── audit.ts # observe the runtime event stream
|
|
56
|
+
│ ├── otel.ts # optional OpenTelemetry export
|
|
56
57
|
│ ├── ab.ts # optional live A/B experiment
|
|
57
58
|
│ ├── ab/
|
|
58
59
|
│ │ └── concise.ts # optional: more experiments
|
|
@@ -83,6 +84,7 @@ Each path maps to a capability and a reference page.
|
|
|
83
84
|
| `agent/subagents/<id>/` | Child agent directory; `description` required | [Subagents](./subagents.md) |
|
|
84
85
|
| `agent/channels/*.ts` | HTTP surfaces beyond the built-in session API; `slack.ts` and `github.ts` use the platform packs | [Channels](./channels.md) |
|
|
85
86
|
| `agent/hooks/*.ts` | Observe-only event subscribers, never fatal | [Hooks](./hooks.md) |
|
|
87
|
+
| `agent/otel.ts` | `defineOtel` OTLP export (traces, metrics, optional logs) | [OpenTelemetry](../guides/opentelemetry.md) |
|
|
86
88
|
| `agent/ab.ts`, `agent/ab/*.ts` | `defineAB` experiments with sticky variants and live metrics | [Live A/B metrics](../ab.md) |
|
|
87
89
|
| `agent/ab.config.ts` | `defineABConfig` shared A/B settings | [Live A/B metrics](../ab.md) |
|
|
88
90
|
| `agent/storage.ts` | `defineStorage` backend for the durable `host.kv` / `host.files` APIs | [Storage](../storage.md) |
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "Ship a triage agent from the template"
|
|
3
|
+
description: "Scaffold the triage template, make its rubric yours, prove it with evals, and deploy it to Cursor-managed hosting."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Ship a triage agent from the template
|
|
7
|
+
|
|
8
|
+
The triage template is a working agent you own from the first command.
|
|
9
|
+
It reads a report, classifies it as a bug, a question, or feedback,
|
|
10
|
+
judges severity against a rubric, records a structured verdict, and
|
|
11
|
+
replies with the next step. This page walks the whole arc: scaffold,
|
|
12
|
+
first verdict, customize, prove, wire Slack, deploy.
|
|
13
|
+
|
|
14
|
+
Every file the template ships is yours to edit. The only dependency is
|
|
15
|
+
`@cursor/july` itself, pinned to the version the template was tested
|
|
16
|
+
against. Nothing phones home to a template registry.
|
|
17
|
+
|
|
18
|
+
## Scaffold it
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
npx @cursor/july init ./triage-agent --template triage
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
One command with no prior install. It writes twelve files, runs
|
|
25
|
+
`npm install`, puts `agent-sdk` on your PATH, and offers a browser
|
|
26
|
+
sign-in when the machine has no Cursor credential. Model turns need
|
|
27
|
+
that credential, so sign in now rather than mid-flow:
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
agent-sdk login
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
The scaffold is a plain directory. Commit it to your own repo.
|
|
34
|
+
|
|
35
|
+
## Get the first verdict
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
cd triage-agent
|
|
39
|
+
agent-sdk dev
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
Open the playground URL it prints and type a real report:
|
|
43
|
+
|
|
44
|
+
> Export to CSV has returned 500s since this morning. Request id 41ac.
|
|
45
|
+
> Retrying does not help.
|
|
46
|
+
|
|
47
|
+
Watch the turn. The agent reads the `triage-rubric` skill, calls
|
|
48
|
+
`record_triage` with a structured verdict, and replies in six lines or
|
|
49
|
+
fewer. The tool call renders inline, so you see the exact kind,
|
|
50
|
+
severity, and next step it recorded.
|
|
51
|
+
|
|
52
|
+
Integrations use the same door your playground does. The `intake`
|
|
53
|
+
channel accepts reports over HTTP:
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
curl -X POST http://127.0.0.1:3000/triage-agent/v1/channels/intake/report \
|
|
57
|
+
-H 'content-type: application/json' \
|
|
58
|
+
-d '{"message":"How do I rotate staging API keys?","reporter":"dana"}'
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
The composer also autocompletes `/report`, which drives this route.
|
|
62
|
+
|
|
63
|
+
## Make the rubric yours
|
|
64
|
+
|
|
65
|
+
`agent/skills/triage-rubric.md` holds the judgment: what counts as a
|
|
66
|
+
bug, the tie-breakers, and the severity ladder. Edit it first. Your
|
|
67
|
+
team's definition of `urgent` belongs there, in plain markdown, and the
|
|
68
|
+
next turn uses it without a restart step.
|
|
69
|
+
|
|
70
|
+
`agent/instructions.md` owns the flow around the rubric: when to ask a
|
|
71
|
+
clarifying question, the one-call `record_triage` rule, and the reply
|
|
72
|
+
shape.
|
|
73
|
+
|
|
74
|
+
## Prove it with evals
|
|
75
|
+
|
|
76
|
+
The template ships three smoke cases, one per kind. Run them after
|
|
77
|
+
every rubric edit:
|
|
78
|
+
|
|
79
|
+
```bash
|
|
80
|
+
agent-sdk eval
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
Each case sends a realistic report and asserts a verdict was recorded
|
|
84
|
+
with the expected kind. When you tighten the rubric, add a case for the
|
|
85
|
+
report style you tightened it for. The eval suite is the regression
|
|
86
|
+
net for prompt changes, so grow it with the rubric.
|
|
87
|
+
|
|
88
|
+
## File verdicts into your tracker
|
|
89
|
+
|
|
90
|
+
`agent/tools/record_triage.ts` defines the verdict shape with a zod
|
|
91
|
+
schema and returns it. Point its `execute` at Linear, GitHub Issues, or
|
|
92
|
+
a webhook to file real tickets. Test the tool without a model turn:
|
|
93
|
+
|
|
94
|
+
```bash
|
|
95
|
+
agent-sdk call record_triage --dir . --input '{
|
|
96
|
+
"kind": "bug",
|
|
97
|
+
"severity": "high",
|
|
98
|
+
"title": "CSV export 500s",
|
|
99
|
+
"summary": "Export returns 500 since this morning.",
|
|
100
|
+
"nextStep": "Check export service logs."
|
|
101
|
+
}'
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
The call validates against the schema and runs your `execute` body
|
|
105
|
+
in-process, so tracker wiring gets a fast loop.
|
|
106
|
+
|
|
107
|
+
## Wire it to Slack
|
|
108
|
+
|
|
109
|
+
The `slack` channel idles until its tokens exist, so local work never
|
|
110
|
+
blocks on Slack. When you want it live:
|
|
111
|
+
|
|
112
|
+
```bash
|
|
113
|
+
agent-sdk slack setup
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
The guided flow creates the Slack app and writes the token pair to
|
|
117
|
+
`.env.local`. Restart `agent-sdk dev`, invite the bot to a channel, and
|
|
118
|
+
@mention it with a report. The [Slack guide](../guides/slack.md) covers
|
|
119
|
+
channel watching and approvals when you outgrow mentions.
|
|
120
|
+
|
|
121
|
+
## Deploy it
|
|
122
|
+
|
|
123
|
+
```bash
|
|
124
|
+
agent-sdk deploy
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
From your git checkout, `deploy` infers the repo, ref, and slug, builds
|
|
128
|
+
the ref on Cursor-managed hosting, and prints the hosted URL plus a
|
|
129
|
+
one-time alias token. Store the token. Production Slack tokens go in as
|
|
130
|
+
deployment secrets:
|
|
131
|
+
|
|
132
|
+
```bash
|
|
133
|
+
agent-sdk secrets set SLACK_BOT_TOKEN SLACK_APP_TOKEN --slug triage-agent
|
|
134
|
+
agent-sdk deploy
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
Check on it with `agent-sdk deployments`. The
|
|
138
|
+
[deployment guide](../deployment.md) covers self-hosting, storage, and
|
|
139
|
+
auth when you need them.
|
|
140
|
+
|
|
141
|
+
## Where to go next
|
|
142
|
+
|
|
143
|
+
- Add a GitHub intake with the [GitHub guide](../guides/github.md), so
|
|
144
|
+
issue comments triage themselves.
|
|
145
|
+
- Persist verdicts across restarts with [storage](../storage.md).
|
|
146
|
+
- Measure rubric changes on live traffic with
|
|
147
|
+
[A/B metrics](../ab.md).
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cursor/july",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.43",
|
|
4
4
|
"description": "(early alpha) Filesystem-first framework for defining Cursor agents as markdown and TypeScript and serving them over channels with the Cursor SDK.",
|
|
5
5
|
"license": "SEE LICENSE IN LICENSE.md",
|
|
6
6
|
"repository": {
|
|
@@ -31,6 +31,7 @@
|
|
|
31
31
|
"!src/internal/tenant-mcp/**",
|
|
32
32
|
"skills/**/*",
|
|
33
33
|
"!skills/operate/**",
|
|
34
|
+
"templates/**/*",
|
|
34
35
|
"docs/**/*.md",
|
|
35
36
|
"!docs/.cursor/**",
|
|
36
37
|
"package.json",
|
|
@@ -177,6 +178,12 @@
|
|
|
177
178
|
"import": "./dist/storage-backends/cursor-hosted.js",
|
|
178
179
|
"default": "./dist/storage-backends/cursor-hosted.js"
|
|
179
180
|
},
|
|
181
|
+
"./otel": {
|
|
182
|
+
"anysphere-source": "./src/otel.ts",
|
|
183
|
+
"types": "./dist/otel.d.ts",
|
|
184
|
+
"import": "./dist/otel.js",
|
|
185
|
+
"default": "./dist/otel.js"
|
|
186
|
+
},
|
|
180
187
|
"./package.json": {
|
|
181
188
|
"anysphere-source": "./package.json",
|
|
182
189
|
"bun": "./package.json",
|
|
@@ -212,6 +219,21 @@
|
|
|
212
219
|
"@modelcontextprotocol/sdk": "1.25.1",
|
|
213
220
|
"@octokit/auth-app": "^7.2.0",
|
|
214
221
|
"@octokit/rest": "^21.1.1",
|
|
222
|
+
"@opentelemetry/api": "^1.9.0",
|
|
223
|
+
"@opentelemetry/api-logs": "^0.208.0",
|
|
224
|
+
"@opentelemetry/core": "^2.6.1",
|
|
225
|
+
"@opentelemetry/exporter-logs-otlp-http": "^0.208.0",
|
|
226
|
+
"@opentelemetry/exporter-logs-otlp-proto": "^0.208.0",
|
|
227
|
+
"@opentelemetry/exporter-metrics-otlp-http": "^0.208.0",
|
|
228
|
+
"@opentelemetry/exporter-metrics-otlp-proto": "^0.208.0",
|
|
229
|
+
"@opentelemetry/exporter-trace-otlp-http": "^0.208.0",
|
|
230
|
+
"@opentelemetry/exporter-trace-otlp-proto": "^0.208.0",
|
|
231
|
+
"@opentelemetry/resources": "^2.6.1",
|
|
232
|
+
"@opentelemetry/sdk-logs": "^0.208.0",
|
|
233
|
+
"@opentelemetry/sdk-metrics": "^2.2.0",
|
|
234
|
+
"@opentelemetry/sdk-trace-base": "^2.6.1",
|
|
235
|
+
"@opentelemetry/sdk-trace-node": "^2.6.1",
|
|
236
|
+
"@opentelemetry/semantic-conventions": "^1.27.0",
|
|
215
237
|
"@slack/socket-mode": "^2.0.7",
|
|
216
238
|
"@slack/web-api": "^7.18.0",
|
|
217
239
|
"croner": "^8.0.1",
|
|
@@ -16,8 +16,8 @@ channels working
|
|
|
16
16
|
with the user, prove a turn runs end-to-end, and set up the improvement loop.
|
|
17
17
|
Sibling skills: `framework-map` for orientation, `setup-slack` for Slack
|
|
18
18
|
wiring, `mcp-auth` for host MCP OAuth, `github` for webhook-driven
|
|
19
|
-
agents, `evals` for the eval API, `ab` for live A/B metrics, `
|
|
20
|
-
for iteration once the agent runs.
|
|
19
|
+
agents, `evals` for the eval API, `ab` for live A/B metrics, `otel` for
|
|
20
|
+
OpenTelemetry export, `hillclimb` for iteration once the agent runs.
|
|
21
21
|
|
|
22
22
|
Read `framework-map/SKILL.md` first if you haven't; treat the package
|
|
23
23
|
`AGENTS.md` and `README.md` as ground truth for
|
package/skills/debug/SKILL.md
CHANGED
|
@@ -10,6 +10,10 @@ description: >-
|
|
|
10
10
|
|
|
11
11
|
# Debugging the Agent SDK locally
|
|
12
12
|
|
|
13
|
+
This skill is **local** `agent-sdk serve` / playground. A **hosted**
|
|
14
|
+
deployment that is stopped, slow to start, or failing `/v1/health` is
|
|
15
|
+
`.cursor/skills/debugging/debug-agent-serve-deployment/SKILL.md`.
|
|
16
|
+
|
|
13
17
|
Read `framework-map/SKILL.md` (sibling skill) first if you don't know the
|
|
14
18
|
project structure or session model. Everything below assumes Node/tsx (`pnpm exec tsx
|
|
15
19
|
src/bin/agent-serve.ts ...` in the everysphere monorepo).
|
|
@@ -63,6 +63,7 @@ path live under README "Folder structure".
|
|
|
63
63
|
| `agent/hooks/*.ts` | Observe-only event subscribers (never fatal) |
|
|
64
64
|
| `agent/ab.ts` or `agent/ab/*.ts` | Live A/B metrics (`defineAB`); sticky `split` + `onSample` |
|
|
65
65
|
| `agent/ab.config.ts` | Optional A/B `maxPlaygroundSessions` / `persistSamples` / `persistSnapshots` |
|
|
66
|
+
| `agent/otel.ts` | OpenTelemetry export (`defineOtel`); also `OTEL_EXPORTER_OTLP_*` env |
|
|
66
67
|
| `agent/schedules/*` | Cron-driven runs (UTC, 5-field; never auto-fire under `--dev`) |
|
|
67
68
|
| `agent/sandbox/workspace/` | Files seeded into each session workspace (local runtime only) |
|
|
68
69
|
| `agent/lib/` | Import-only shared code, never discovered |
|
|
@@ -151,6 +152,7 @@ folder mounts every sibling agent too.
|
|
|
151
152
|
- Scaffolding → `packages/agent-serve/skills/create-agent/SKILL.md`
|
|
152
153
|
- Evals → `packages/agent-serve/skills/evals/SKILL.md`
|
|
153
154
|
- Live A/B metrics → `packages/agent-serve/skills/ab/SKILL.md`
|
|
155
|
+
- OpenTelemetry → `packages/agent-serve/skills/otel/SKILL.md`
|
|
154
156
|
- GitHub webhooks → `packages/agent-serve/skills/github/SKILL.md`
|
|
155
157
|
- Slack → `packages/agent-serve/skills/setup-slack/SKILL.md`
|
|
156
158
|
- Host MCP OAuth → `packages/agent-serve/skills/mcp-auth/SKILL.md`
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: agentkit-otel
|
|
3
|
+
description: >-
|
|
4
|
+
Wire OpenTelemetry export for an Agent SDK agent (defineOtel, OTLP env,
|
|
5
|
+
traces/metrics/logs). Use when adding observability, Datadog/Grafana/OTLP
|
|
6
|
+
export, or session/turn/tool tracing.
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# Agent SDK OpenTelemetry (`defineOtel`)
|
|
10
|
+
|
|
11
|
+
Push session, turn, tool, and subagent traces, plus token and cost
|
|
12
|
+
metrics, from the serve process to an OTLP collector. Logs are off
|
|
13
|
+
until you opt in.
|
|
14
|
+
|
|
15
|
+
Read [OpenTelemetry](../../docs/guides/opentelemetry.md) for the full
|
|
16
|
+
guide, including how this joins Cursor enterprise export.
|
|
17
|
+
|
|
18
|
+
## Enable
|
|
19
|
+
|
|
20
|
+
Any one of:
|
|
21
|
+
|
|
22
|
+
1. **Env.** Set `OTEL_EXPORTER_OTLP_ENDPOINT` (and optional
|
|
23
|
+
`OTEL_SERVICE_NAME`, `OTEL_EXPORTER_OTLP_HEADERS`,
|
|
24
|
+
`OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf|http/json`).
|
|
25
|
+
Per-signal URLs work when the base URL is unset:
|
|
26
|
+
`OTEL_EXPORTER_OTLP_TRACES_ENDPOINT` / `_METRICS_ENDPOINT` /
|
|
27
|
+
`_LOGS_ENDPOINT`.
|
|
28
|
+
2. **Authored.** `agent/otel.ts`:
|
|
29
|
+
|
|
30
|
+
```ts
|
|
31
|
+
import { defineOtel } from "@cursor/july/otel";
|
|
32
|
+
|
|
33
|
+
export default defineOtel({
|
|
34
|
+
serviceName: "cursor",
|
|
35
|
+
exporters: [
|
|
36
|
+
{
|
|
37
|
+
url: "https://otel.example.com",
|
|
38
|
+
protocol: "http/protobuf",
|
|
39
|
+
headers: { Authorization: "Bearer …" },
|
|
40
|
+
},
|
|
41
|
+
],
|
|
42
|
+
});
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
3. **Programmatic.** `serve(dir, { otel: { … } })`. Pass `otel: false`
|
|
46
|
+
to disable even when env or `agent/otel.ts` are set.
|
|
47
|
+
|
|
48
|
+
Multiple `exporters` fan out. Default protocol is `http/protobuf`.
|
|
49
|
+
Use `http/json` only when the collector requires it. `grpc` is ignored.
|
|
50
|
+
|
|
51
|
+
Precedence: `serve({ otel })` over `agent/otel.ts` over env.
|
|
52
|
+
|
|
53
|
+
## Signals
|
|
54
|
+
|
|
55
|
+
| Signal | Default | What |
|
|
56
|
+
| --- | --- | --- |
|
|
57
|
+
| Traces | on | `agent_sdk.http` → `agent_sdk.session` → `agent_sdk.turn` → `agent_sdk.tool` / `agent_sdk.subagent` |
|
|
58
|
+
| Metrics | on | `cursor.token.usage`, `cursor.tool.calls`, `cursor.cost.usage`, plus `agent_sdk.*` counts and HTTP duration |
|
|
59
|
+
| Logs | off | Opt in with `logs: true`, `OTEL_LOGS_EXPORTER=otlp`, or `OTEL_LOG_USER_PROMPTS=1` / `OTEL_LOG_TOOL_CONTENT=1` |
|
|
60
|
+
|
|
61
|
+
Prompt text, tool payloads, and failure text stay off the wire unless
|
|
62
|
+
those flags are set.
|
|
63
|
+
|
|
64
|
+
## Attributes worth joining on
|
|
65
|
+
|
|
66
|
+
- `cursor.conversation.id` (session id)
|
|
67
|
+
- `cursor.tool.name` / `cursor.tool.kind` / `cursor.tool.status`
|
|
68
|
+
- `cursor.token.type`, `cursor.model.name`
|
|
69
|
+
- `agent_sdk.agent`, `agent_sdk.turn_id`, `agent_sdk.call_id`, `agent_sdk.channel`
|
|
70
|
+
|
|
71
|
+
Resource defaults: `service.name=cursor`, `cursor.entrypoint=sdk_ts`,
|
|
72
|
+
`cursor.surface=unspecified`.
|
|
73
|
+
|
|
74
|
+
Inbound HTTP extracts W3C `traceparent`, so a channel request parents
|
|
75
|
+
the session span when the turn starts in that request.
|
|
76
|
+
|
|
77
|
+
If another TracerProvider already owns the process (CLI / IDE), Agent
|
|
78
|
+
SDK reuses it. Run `serve` as its own process when Agent SDK should
|
|
79
|
+
own the destination. Conflicting `agent/otel.ts` files across mounts
|
|
80
|
+
fail at serve start.
|
package/src/bin/agent-serve.ts
CHANGED
|
@@ -100,7 +100,7 @@ Usage:
|
|
|
100
100
|
${CLI} trajectory --events <file.ndjson> [--text]
|
|
101
101
|
${CLI} call <tool> [--input <json>] [--dir <path> | --url <baseUrl> | --prod]
|
|
102
102
|
[--session <id>] [--slug <slug>] [--team <id>]
|
|
103
|
-
${CLI} init [dir] [--json]
|
|
103
|
+
${CLI} init [dir] [--template <name>] [--json]
|
|
104
104
|
${CLI} convert-automation <url> [--dir <path>] [--json]
|
|
105
105
|
${CLI} install-skills [--print] [--json]
|
|
106
106
|
${CLI} mcp --prod [--slug <slug>] [--team <id>] [--dir <path>]
|
|
@@ -467,6 +467,7 @@ async function main(argv: string[]): Promise<number> {
|
|
|
467
467
|
allowPositionals: true,
|
|
468
468
|
options: {
|
|
469
469
|
dir: { type: "string", default: "." },
|
|
470
|
+
template: { type: "string" },
|
|
470
471
|
port: { type: "string" },
|
|
471
472
|
host: { type: "string" },
|
|
472
473
|
mode: { type: "string" },
|
|
@@ -624,6 +625,7 @@ async function main(argv: string[]): Promise<number> {
|
|
|
624
625
|
return cmdInit({
|
|
625
626
|
dir,
|
|
626
627
|
initTarget: positionals[0],
|
|
628
|
+
template: values.template,
|
|
627
629
|
json: values.json,
|
|
628
630
|
});
|
|
629
631
|
}
|
|
@@ -258,6 +258,28 @@ export async function createGitHubIssueComment(
|
|
|
258
258
|
}
|
|
259
259
|
}
|
|
260
260
|
|
|
261
|
+
/** Update an issue or PR timeline comment by id. */
|
|
262
|
+
export async function updateGitHubIssueComment(
|
|
263
|
+
input: GitHubResourceInput & { body: string; commentId: number }
|
|
264
|
+
): Promise<GitHubPostedComment> {
|
|
265
|
+
const octokit = await createGitHubOctokit(input);
|
|
266
|
+
try {
|
|
267
|
+
const response = await octokit.rest.issues.updateComment({
|
|
268
|
+
owner: input.owner,
|
|
269
|
+
repo: input.repo,
|
|
270
|
+
comment_id: input.commentId,
|
|
271
|
+
body: input.body,
|
|
272
|
+
});
|
|
273
|
+
return toPostedComment(response.data);
|
|
274
|
+
} catch (error) {
|
|
275
|
+
throw wrapOctokitError(
|
|
276
|
+
error,
|
|
277
|
+
"PATCH",
|
|
278
|
+
`/repos/${input.owner}/${input.repo}/issues/comments/${input.commentId}`
|
|
279
|
+
);
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
|
|
261
283
|
/** Reply to an inline pull-request review comment thread. */
|
|
262
284
|
export async function createGitHubReviewCommentReply(
|
|
263
285
|
input: GitHubResourceInput & {
|
|
@@ -5,14 +5,11 @@
|
|
|
5
5
|
import type { ChannelEventHandlers } from "../../types.js";
|
|
6
6
|
import type { GitHubBindingConfig } from "./binding.js";
|
|
7
7
|
import { buildGitHubBinding, formatGitHubOutboundComment } from "./binding.js";
|
|
8
|
+
import { applyGitHubProgress, type GitHubProgressConfig } from "./progress.js";
|
|
8
9
|
import type { GitHubChannelState } from "./state.js";
|
|
9
10
|
|
|
10
|
-
export interface GitHubProgressConfig {
|
|
11
|
-
/** When false, skip the eyes reaction on turn.started. Defaults to true. */
|
|
12
|
-
reactions?: boolean;
|
|
13
|
-
}
|
|
14
|
-
|
|
15
11
|
export interface BuildDefaultGitHubEventsOptions extends GitHubBindingConfig {
|
|
12
|
+
botName?: string;
|
|
16
13
|
progress?: GitHubProgressConfig;
|
|
17
14
|
/**
|
|
18
15
|
* When false, skip posting completed assistant messages back to GitHub.
|
|
@@ -22,7 +19,8 @@ export interface BuildDefaultGitHubEventsOptions extends GitHubBindingConfig {
|
|
|
22
19
|
}
|
|
23
20
|
|
|
24
21
|
/**
|
|
25
|
-
* Built-in delivery: eyes reaction on turn start,
|
|
22
|
+
* Built-in delivery: eyes reaction on turn start, optional commit status /
|
|
23
|
+
* sticky banner via {@link GitHubProgressConfig}, post assistant text on
|
|
26
24
|
* `message.completed`, and a short error comment on turn/session failure.
|
|
27
25
|
*/
|
|
28
26
|
export function buildDefaultGitHubEvents(
|
|
@@ -32,6 +30,11 @@ export function buildDefaultGitHubEvents(
|
|
|
32
30
|
|
|
33
31
|
return {
|
|
34
32
|
async "turn.started"(_event, channel) {
|
|
33
|
+
await applyGitHubProgress({
|
|
34
|
+
phase: "pending",
|
|
35
|
+
channel,
|
|
36
|
+
options,
|
|
37
|
+
});
|
|
35
38
|
if (options.progress?.reactions === false) {
|
|
36
39
|
return;
|
|
37
40
|
}
|
|
@@ -49,6 +52,14 @@ export function buildDefaultGitHubEvents(
|
|
|
49
52
|
}
|
|
50
53
|
},
|
|
51
54
|
|
|
55
|
+
async "turn.completed"(_event, channel) {
|
|
56
|
+
await applyGitHubProgress({
|
|
57
|
+
phase: "success",
|
|
58
|
+
channel,
|
|
59
|
+
options,
|
|
60
|
+
});
|
|
61
|
+
},
|
|
62
|
+
|
|
52
63
|
async "message.completed"(event, channel) {
|
|
53
64
|
if (!deliverReplies) {
|
|
54
65
|
return;
|
|
@@ -71,10 +82,20 @@ export function buildDefaultGitHubEvents(
|
|
|
71
82
|
},
|
|
72
83
|
|
|
73
84
|
async "turn.failed"(event, channel) {
|
|
85
|
+
await applyGitHubProgress({
|
|
86
|
+
phase: "failure",
|
|
87
|
+
channel,
|
|
88
|
+
options,
|
|
89
|
+
});
|
|
74
90
|
await postFailure(channel, options, event.data.message);
|
|
75
91
|
},
|
|
76
92
|
|
|
77
93
|
async "session.failed"(event, channel) {
|
|
94
|
+
await applyGitHubProgress({
|
|
95
|
+
phase: "failure",
|
|
96
|
+
channel,
|
|
97
|
+
options,
|
|
98
|
+
});
|
|
78
99
|
await postFailure(channel, options, event.data.message);
|
|
79
100
|
},
|
|
80
101
|
};
|
|
@@ -958,6 +958,9 @@ async function handleReviewComment(input: {
|
|
|
958
958
|
binding,
|
|
959
959
|
deliveryId: ctx.deliveryId,
|
|
960
960
|
eventName: ctx.eventName,
|
|
961
|
+
headSha: parsed.headSha,
|
|
962
|
+
headRef: parsed.headRef,
|
|
963
|
+
baseRef: parsed.baseRef,
|
|
961
964
|
}),
|
|
962
965
|
});
|
|
963
966
|
}
|
|
@@ -1459,6 +1462,8 @@ async function startTurn(input: {
|
|
|
1459
1462
|
title: input.dispatch.title ?? defaultGitHubTitle(input.ctx),
|
|
1460
1463
|
...(input.cloud === undefined ? {} : { cloud: input.cloud }),
|
|
1461
1464
|
state: input.state as unknown as JsonValue,
|
|
1465
|
+
// Resume must refresh headSha / refs without wiping sticky banner id.
|
|
1466
|
+
refreshState: input.state as unknown as JsonValue,
|
|
1462
1467
|
});
|
|
1463
1468
|
return Response.json({
|
|
1464
1469
|
ok: true,
|
|
@@ -1612,6 +1617,9 @@ function parseReviewCommentEvent(args: {
|
|
|
1612
1617
|
action: string;
|
|
1613
1618
|
ctx: GitHubParsedContext;
|
|
1614
1619
|
comment: GitHubComment;
|
|
1620
|
+
headSha?: string;
|
|
1621
|
+
headRef?: string;
|
|
1622
|
+
baseRef?: string;
|
|
1615
1623
|
} | null {
|
|
1616
1624
|
const schema = z.object({
|
|
1617
1625
|
action: z.string().min(1),
|
|
@@ -1619,6 +1627,17 @@ function parseReviewCommentEvent(args: {
|
|
|
1619
1627
|
pull_request: z.object({
|
|
1620
1628
|
number: z.number().int().positive(),
|
|
1621
1629
|
html_url: z.string().url(),
|
|
1630
|
+
head: z
|
|
1631
|
+
.object({
|
|
1632
|
+
sha: z.string().min(1).optional(),
|
|
1633
|
+
ref: z.string().min(1).optional(),
|
|
1634
|
+
})
|
|
1635
|
+
.optional(),
|
|
1636
|
+
base: z
|
|
1637
|
+
.object({
|
|
1638
|
+
ref: z.string().min(1).optional(),
|
|
1639
|
+
})
|
|
1640
|
+
.optional(),
|
|
1622
1641
|
}),
|
|
1623
1642
|
comment: z.object({
|
|
1624
1643
|
id: z.number(),
|
|
@@ -1679,7 +1698,14 @@ function parseReviewCommentEvent(args: {
|
|
|
1679
1698
|
? {}
|
|
1680
1699
|
: { inReplyToId: payload.comment.in_reply_to_id }),
|
|
1681
1700
|
};
|
|
1682
|
-
return {
|
|
1701
|
+
return {
|
|
1702
|
+
action: payload.action,
|
|
1703
|
+
ctx,
|
|
1704
|
+
comment,
|
|
1705
|
+
headSha: payload.pull_request.head?.sha,
|
|
1706
|
+
headRef: payload.pull_request.head?.ref,
|
|
1707
|
+
baseRef: payload.pull_request.base?.ref,
|
|
1708
|
+
};
|
|
1683
1709
|
}
|
|
1684
1710
|
|
|
1685
1711
|
function parseIssueEvent(args: {
|
|
@@ -47,6 +47,7 @@ export * from "./defaults.js";
|
|
|
47
47
|
export * from "./events.js";
|
|
48
48
|
export * from "./forward.js";
|
|
49
49
|
export * from "./github-channel.js";
|
|
50
|
+
export * from "./progress.js";
|
|
50
51
|
export * from "./replay.js";
|
|
51
52
|
export * from "./state.js";
|
|
52
53
|
export * from "./types.js";
|