@cursor/july 0.1.25 → 0.1.27
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/dist/ab.d.ts +6 -0
- package/dist/ab.d.ts.map +1 -1
- package/dist/ab.js +1 -0
- package/dist/artifacts.d.ts +34 -0
- package/dist/artifacts.d.ts.map +1 -0
- package/dist/artifacts.js +57 -0
- package/dist/bin/agent-serve.js +31 -9
- package/dist/channels/github/github-channel.d.ts +1 -1
- package/dist/channels/github/github-channel.d.ts.map +1 -1
- package/dist/channels/github/github-channel.js +14 -1
- package/dist/channels/github/types.d.ts +6 -1
- package/dist/channels/github/types.d.ts.map +1 -1
- package/dist/channels/slack/api.d.ts +2 -1
- package/dist/channels/slack/api.d.ts.map +1 -1
- package/dist/channels/slack/api.js +1 -0
- package/dist/channels/slack/cursor-account.d.ts +2 -1
- package/dist/channels/slack/cursor-account.d.ts.map +1 -1
- package/dist/channels/slack/cursor-account.js +1 -1
- package/dist/channels/slack/dispatch.d.ts +4 -1
- package/dist/channels/slack/dispatch.d.ts.map +1 -1
- package/dist/channels/slack/dispatch.js +3 -3
- package/dist/channels/slack/interactive.d.ts +2 -1
- package/dist/channels/slack/interactive.d.ts.map +1 -1
- package/dist/channels/slack/interactive.js +1 -0
- package/dist/channels/slack/slack-channel.d.ts.map +1 -1
- package/dist/channels/slack/slack-channel.js +4 -3
- package/dist/channels/slack/types.d.ts +6 -1
- package/dist/channels/slack/types.d.ts.map +1 -1
- package/dist/docs/404.html +1 -1
- package/dist/docs/ab.html +2 -2
- package/dist/docs/assets/{app.DYcC9FY-.js → app.BICLoJYF.js} +1 -1
- package/dist/docs/assets/chunks/@localSearchIndexroot.CQJytDwU.js +1 -0
- package/dist/docs/assets/chunks/{VPLocalSearchBox.o4N_knTV.js → VPLocalSearchBox.wN4Ko9dT.js} +1 -1
- package/dist/docs/assets/chunks/{theme.DQ-njyo0.js → theme.dnnTE-Co.js} +2 -2
- package/dist/docs/building-with-agents.html +2 -2
- package/dist/docs/concepts.html +2 -2
- package/dist/docs/deployment.html +2 -2
- package/dist/docs/evals.html +2 -2
- package/dist/docs/example-agents/approval-buddy.html +2 -2
- package/dist/docs/example-agents/benny.html +2 -2
- package/dist/docs/example-agents/bugbot.html +2 -2
- package/dist/docs/example-agents/codebase-wiki.html +2 -2
- package/dist/docs/example-agents/codeowners-review.html +2 -2
- package/dist/docs/example-agents/concierge.html +2 -2
- package/dist/docs/example-agents/fsd.html +2 -2
- package/dist/docs/example-agents/index.html +2 -2
- package/dist/docs/example-agents/knowledge-base.html +2 -2
- package/dist/docs/example-agents/oncall.html +2 -2
- package/dist/docs/example-agents/security-reviewer.html +2 -2
- package/dist/docs/example-agents/slack-agent.html +2 -2
- package/dist/docs/example-agents/weather-agent.html +2 -2
- package/dist/docs/guides/agent-to-agent.html +2 -2
- package/dist/docs/guides/cloud-runtime.html +2 -2
- package/dist/docs/guides/github.html +2 -2
- package/dist/docs/guides/human-in-the-loop.html +2 -2
- package/dist/docs/guides/mcp-oauth.html +2 -2
- package/dist/docs/guides/slack.html +2 -2
- package/dist/docs/guides/webhooks.html +2 -2
- package/dist/docs/hillclimbing.html +2 -2
- package/dist/docs/index.html +2 -2
- package/dist/docs/quickstart.html +2 -2
- package/dist/docs/reference/agent-config.html +2 -2
- package/dist/docs/reference/channels.html +2 -2
- package/dist/docs/reference/cli.html +2 -2
- package/dist/docs/reference/connections.html +2 -2
- package/dist/docs/reference/hooks.html +2 -2
- package/dist/docs/reference/http-api.html +2 -2
- package/dist/docs/reference/instructions.html +2 -2
- package/dist/docs/reference/playground.html +2 -2
- package/dist/docs/reference/project-layout.html +2 -2
- package/dist/docs/reference/prompt.html +2 -2
- package/dist/docs/reference/schedules.html +2 -2
- package/dist/docs/reference/sessions.html +2 -2
- package/dist/docs/reference/skills.html +2 -2
- package/dist/docs/reference/subagents.html +2 -2
- package/dist/docs/reference/tools.html +2 -2
- package/dist/docs/scaffolding-agents.html +2 -2
- package/dist/docs/storage.html +2 -2
- package/dist/docs/troubleshooting.html +2 -2
- package/dist/evals/assertions.d.ts +10 -1
- package/dist/evals/assertions.d.ts.map +1 -1
- package/dist/evals/assertions.js +12 -0
- package/dist/evals.d.ts +1 -1
- package/dist/evals.d.ts.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/internal/ab-fold.d.ts.map +1 -1
- package/dist/internal/ab-fold.js +4 -0
- package/dist/internal/ab-snapshot.d.ts.map +1 -1
- package/dist/internal/ab-snapshot.js +1 -0
- package/dist/internal/artifacts-store.d.ts +45 -0
- package/dist/internal/artifacts-store.d.ts.map +1 -0
- package/dist/internal/artifacts-store.js +250 -0
- package/dist/internal/builtin-tools/artifacts.d.ts +10 -0
- package/dist/internal/builtin-tools/artifacts.d.ts.map +1 -0
- package/dist/internal/builtin-tools/artifacts.js +73 -0
- package/dist/internal/builtin-tools/index.d.ts +8 -1
- package/dist/internal/builtin-tools/index.d.ts.map +1 -1
- package/dist/internal/builtin-tools/index.js +15 -0
- package/dist/internal/cli-ax.d.ts +11 -0
- package/dist/internal/cli-ax.d.ts.map +1 -1
- package/dist/internal/cli-ax.js +80 -0
- package/dist/internal/cli-slack.d.ts.map +1 -1
- package/dist/internal/cli-slack.js +14 -6
- package/dist/internal/discovery.d.ts.map +1 -1
- package/dist/internal/discovery.js +83 -2
- package/dist/internal/distribution.d.ts.map +1 -1
- package/dist/internal/distribution.js +1 -0
- package/dist/internal/model-pricing.d.ts +49 -0
- package/dist/internal/model-pricing.d.ts.map +1 -0
- package/dist/internal/model-pricing.js +377 -0
- package/dist/internal/reminder-runner.d.ts.map +1 -1
- package/dist/internal/reminder-runner.js +1 -0
- package/dist/internal/schedule-runner.d.ts.map +1 -1
- package/dist/internal/schedule-runner.js +1 -0
- package/dist/internal/sdk-runner.d.ts.map +1 -1
- package/dist/internal/sdk-runner.js +9 -1
- package/dist/internal/server.d.ts.map +1 -1
- package/dist/internal/server.js +39 -0
- package/dist/internal/session-cost.d.ts +49 -0
- package/dist/internal/session-cost.d.ts.map +1 -0
- package/dist/internal/session-cost.js +175 -0
- package/dist/internal/session-engine.d.ts +35 -1
- package/dist/internal/session-engine.d.ts.map +1 -1
- package/dist/internal/session-engine.js +128 -7
- package/dist/internal/storage-coordinator.d.ts +15 -0
- package/dist/internal/storage-coordinator.d.ts.map +1 -1
- package/dist/internal/storage-coordinator.js +52 -0
- package/dist/internal/trajectory.d.ts +9 -1
- package/dist/internal/trajectory.d.ts.map +1 -1
- package/dist/internal/trajectory.js +32 -5
- package/dist/playground/assets/index-BDCeW4uc.js +86 -0
- package/dist/playground/assets/index-Bul1WfrB.css +1 -0
- package/dist/playground/index.html +2 -2
- package/dist/storage.d.ts +4 -0
- package/dist/storage.d.ts.map +1 -1
- package/dist/storage.js +4 -0
- package/dist/types.d.ts +164 -1
- package/dist/types.d.ts.map +1 -1
- package/package.json +26 -26
- package/src/ab.ts +7 -0
- package/src/bin/agent-serve.ts +30 -2
- package/src/channels/github/github-channel.ts +19 -2
- package/src/channels/github/types.ts +6 -0
- package/src/channels/slack/api.ts +3 -1
- package/src/channels/slack/cursor-account.ts +3 -1
- package/src/channels/slack/dispatch.ts +12 -1
- package/src/channels/slack/interactive.ts +3 -0
- package/src/channels/slack/slack-channel.ts +6 -0
- package/src/channels/slack/types.ts +6 -0
- package/src/internal/ab-fold.ts +4 -0
- package/src/internal/ab-snapshot.ts +1 -0
- package/src/internal/cli-ax.ts +95 -0
- package/src/internal/model-pricing.ts +426 -0
- package/src/internal/reminder-runner.ts +1 -0
- package/src/internal/schedule-runner.ts +1 -0
- package/src/internal/sdk-runner.ts +10 -2
- package/src/internal/server.ts +2 -0
- package/src/internal/session-cost.ts +231 -0
- package/src/internal/session-engine.ts +32 -1
- package/src/internal/trajectory.ts +45 -3
- package/src/types.ts +42 -2
- package/dist/channels/github/instrument.d.ts +0 -20
- package/dist/channels/github/instrument.d.ts.map +0 -1
- package/dist/docs/assets/chunks/@localSearchIndexroot.BQTzJjR_.js +0 -1
- package/dist/internal/json-dir-store.d.ts +0 -32
- package/dist/internal/json-dir-store.d.ts.map +0 -1
- package/dist/internal/json-dir-store.js +0 -100
- package/dist/playground/assets/index-CjOQ4hN9.css +0 -1
- package/dist/playground/assets/index-DqXdAFGa.js +0 -85
- package/src/bin/agent-serve.version.test.ts +0 -64
- package/src/channels/github/api.test.ts +0 -64
- package/src/channels/github/auth.test.ts +0 -105
- package/src/channels/github/cursor-account.test.ts +0 -204
- package/src/channels/github/forward.test.ts +0 -457
- package/src/channels/github/github.test.ts +0 -943
- package/src/channels/github/replay.test.ts +0 -179
- package/src/channels/slack/api.post-message.test.ts +0 -148
- package/src/channels/slack/approvals.test.ts +0 -328
- package/src/channels/slack/block-actions.test.ts +0 -452
- package/src/channels/slack/bot-mentions.test.ts +0 -267
- package/src/channels/slack/channel-watch.test.ts +0 -363
- package/src/channels/slack/cursor-account.test.ts +0 -253
- package/src/channels/slack/defaults.final-post.test.ts +0 -182
- package/src/channels/slack/dispatch.test.ts +0 -795
- package/src/channels/slack/eval-directive.test.ts +0 -273
- package/src/channels/slack/message-body.test.ts +0 -54
- package/src/channels/slack/nudge-store.test.ts +0 -143
- package/src/channels/slack/slack.test.ts +0 -391
- package/src/channels/slack/stop.test.ts +0 -23
- package/src/channels/slack/thread-context.test.ts +0 -202
- package/src/evals/assertions.test.ts +0 -617
- package/src/evals/expect.test.ts +0 -144
- package/src/evals/judge.test.ts +0 -181
- package/src/evals/loaders.test.ts +0 -132
- package/src/evals/matchers.test.ts +0 -95
- package/src/evals/reporters.test.ts +0 -303
- package/src/evals/run-facts.test.ts +0 -259
- package/src/internal/ab-snapshot.test.ts +0 -325
- package/src/internal/approval-gate.test.ts +0 -49
- package/src/internal/approvals.integration.test.ts +0 -383
- package/src/internal/artifacts-store.test.ts +0 -283
- package/src/internal/authored-loaders.test.ts +0 -31
- package/src/internal/builtin-tools/artifacts.test.ts +0 -247
- package/src/internal/builtin-tools/reminders.test.ts +0 -201
- package/src/internal/channel-route-schema.test.ts +0 -294
- package/src/internal/chat-attach.test.ts +0 -262
- package/src/internal/cli-deploy.test.ts +0 -1991
- package/src/internal/cli-docs.test.ts +0 -161
- package/src/internal/cli-mcp.test.ts +0 -789
- package/src/internal/cli-skills.test.ts +0 -133
- package/src/internal/cli-slack.test.ts +0 -1654
- package/src/internal/cloud-merge.test.ts +0 -74
- package/src/internal/cron.test.ts +0 -22
- package/src/internal/cursor/account-mcp.test.ts +0 -807
- package/src/internal/cursor/backend-client.test.ts +0 -591
- package/src/internal/cursor/credentials.test.ts +0 -351
- package/src/internal/cursor/github-credentials.test.ts +0 -136
- package/src/internal/cursor-account-mcp-auth.test.ts +0 -310
- package/src/internal/cursor-account.integration.test.ts +0 -441
- package/src/internal/cursor-event-relay.test.ts +0 -746
- package/src/internal/cursor-github-credentials.integration.test.ts +0 -271
- package/src/internal/cursor-slack-relay.test.ts +0 -525
- package/src/internal/deploy-source.test.ts +0 -111
- package/src/internal/discovery.artifact-tool.test.ts +0 -136
- package/src/internal/discovery.artifacts.test.ts +0 -119
- package/src/internal/discovery.builtin-tools.test.ts +0 -94
- package/src/internal/discovery.concurrency.test.ts +0 -60
- package/src/internal/discovery.cursor-account.test.ts +0 -133
- package/src/internal/discovery.cwd.test.ts +0 -83
- package/src/internal/discovery.hosting.test.ts +0 -80
- package/src/internal/discovery.identity.test.ts +0 -44
- package/src/internal/docs-site.test.ts +0 -66
- package/src/internal/duration.test.ts +0 -29
- package/src/internal/eval-judge-model.test.ts +0 -187
- package/src/internal/eval-run-store.cancel.test.ts +0 -142
- package/src/internal/eval-run-store.storage.test.ts +0 -211
- package/src/internal/eval-runner.http.test.ts +0 -403
- package/src/internal/eval-runner.run.test.ts +0 -928
- package/src/internal/evals-client.test.ts +0 -307
- package/src/internal/event-mapper.test.ts +0 -243
- package/src/internal/github-fanout.test.ts +0 -213
- package/src/internal/handleAgentServeTrigger.test.ts +0 -185
- package/src/internal/host-kv.test.ts +0 -82
- package/src/internal/host-platforms.test.ts +0 -126
- package/src/internal/http-channel.test.ts +0 -402
- package/src/internal/init-project.test.ts +0 -270
- package/src/internal/install-cursor-skills.test.ts +0 -262
- package/src/internal/local-env.test.ts +0 -120
- package/src/internal/log-ring.test.ts +0 -31
- package/src/internal/logs-client.test.ts +0 -350
- package/src/internal/mcp-endpoint.test.ts +0 -436
- package/src/internal/mcp-host.test.ts +0 -298
- package/src/internal/mcp-oauth.test.ts +0 -148
- package/src/internal/net.test.ts +0 -17
- package/src/internal/peer-connections.test.ts +0 -128
- package/src/internal/peer-mcp.integration.test.ts +0 -289
- package/src/internal/playground/toolchain.test.ts +0 -53
- package/src/internal/playground-cli.test.ts +0 -187
- package/src/internal/playground-proxy.test.ts +0 -376
- package/src/internal/prompt-context.integration.test.ts +0 -232
- package/src/internal/prompt-context.test.ts +0 -127
- package/src/internal/reminder-runner.test.ts +0 -390
- package/src/internal/reminder-store.test.ts +0 -53
- package/src/internal/request-headers.test.ts +0 -27
- package/src/internal/resolve-prod-target.test.ts +0 -787
- package/src/internal/resolved-connections.test.ts +0 -295
- package/src/internal/router.test.ts +0 -57
- package/src/internal/sdk-runner.test.ts +0 -290
- package/src/internal/server.artifacts.test.ts +0 -303
- package/src/internal/session-engine.artifacts.test.ts +0 -243
- package/src/internal/session-engine.coalesce.test.ts +0 -169
- package/src/internal/session-engine.concurrency.test.ts +0 -250
- package/src/internal/session-engine.host-oauth-mcp.test.ts +0 -110
- package/src/internal/session-engine.interrupt.test.ts +0 -577
- package/src/internal/session-engine.storage.test.ts +0 -547
- package/src/internal/session-urls.test.ts +0 -28
- package/src/internal/sessions-client.test.ts +0 -518
- package/src/internal/storage-coordinator.test.ts +0 -517
- package/src/internal/tool-call.test.ts +0 -458
- package/src/internal/tool-result.test.ts +0 -52
- package/src/internal/trajectory.approvals.test.ts +0 -83
- package/src/internal/trajectory.subagents.test.ts +0 -198
- package/src/internal/turn-governor.test.ts +0 -137
- package/src/internal/update-check.test.ts +0 -485
- package/src/internal/workspace.test.ts +0 -207
- package/src/storage-backends/cursor-hosted.test.ts +0 -121
package/src/bin/agent-serve.ts
CHANGED
|
@@ -29,6 +29,7 @@ import {
|
|
|
29
29
|
type AxCliOptions,
|
|
30
30
|
cmdCall,
|
|
31
31
|
cmdChat,
|
|
32
|
+
cmdCost,
|
|
32
33
|
cmdEval,
|
|
33
34
|
cmdEvalCancel,
|
|
34
35
|
cmdEvalStatus,
|
|
@@ -55,6 +56,7 @@ import {
|
|
|
55
56
|
} from "../internal/cli-deploy.js";
|
|
56
57
|
import {
|
|
57
58
|
CLI_COMMAND_NAME as CLI,
|
|
59
|
+
PACKAGE_NAME,
|
|
58
60
|
packageVersion,
|
|
59
61
|
} from "../internal/distribution.js";
|
|
60
62
|
import { loadAgentLocalEnv } from "../internal/local-env.js";
|
|
@@ -85,6 +87,8 @@ Usage:
|
|
|
85
87
|
${CLI} session <sessionId> [--url <baseUrl> | --prod]
|
|
86
88
|
[--json | --text | --events]
|
|
87
89
|
[--slug <slug>] [--team <id>] [--dir <path>]
|
|
90
|
+
${CLI} cost [sessionId] [--url <baseUrl> | --prod] [--json]
|
|
91
|
+
[--slug <slug>] [--team <id>] [--dir <path>]
|
|
88
92
|
${CLI} playground [--url <baseUrl> | --prod] [--session <id>] [--print]
|
|
89
93
|
[--slug <slug>] [--team <id>] [--dir <path>]
|
|
90
94
|
${CLI} docs [--port <n>] [--host <host>] [--print]
|
|
@@ -161,6 +165,10 @@ Commands:
|
|
|
161
165
|
session Show one session. Default: text trajectory. --json for trajectory
|
|
162
166
|
JSON; --events for the raw event list. To continue interactively,
|
|
163
167
|
use \`${CLI} resume [id]\`.
|
|
168
|
+
cost Pull cost metrics. With a session id: per-turn token usage and
|
|
169
|
+
estimated cost for that session. Without one: one row per
|
|
170
|
+
session plus a total. Costs are the engine's recorded estimates
|
|
171
|
+
from turn.completed events; --json for machine-readable reports.
|
|
164
172
|
playground Open the web playground. --prod starts a loopback proxy that
|
|
165
173
|
injects hosted engine credentials (browsers cannot set them).
|
|
166
174
|
--print skips opening a browser. Ctrl-C stops the proxy.
|
|
@@ -908,6 +916,22 @@ async function main(argv: string[]): Promise<number> {
|
|
|
908
916
|
);
|
|
909
917
|
}
|
|
910
918
|
|
|
919
|
+
case "cost": {
|
|
920
|
+
return cmdCost(
|
|
921
|
+
positionals[0] ?? values["session-id"] ?? values.session,
|
|
922
|
+
axFromOptions({
|
|
923
|
+
dir,
|
|
924
|
+
url: values.url,
|
|
925
|
+
prod: values.prod,
|
|
926
|
+
team: values.team,
|
|
927
|
+
apiKey: values["api-key"],
|
|
928
|
+
slug: values.slug,
|
|
929
|
+
bearerToken: values["bearer-token"],
|
|
930
|
+
json: values.json,
|
|
931
|
+
})
|
|
932
|
+
);
|
|
933
|
+
}
|
|
934
|
+
|
|
911
935
|
case "playground": {
|
|
912
936
|
return cmdPlayground(
|
|
913
937
|
axFromOptions({
|
|
@@ -1383,11 +1407,15 @@ function printServeBanner(
|
|
|
1383
1407
|
): void {
|
|
1384
1408
|
const c = stdoutPalette();
|
|
1385
1409
|
const agents = handle.agents;
|
|
1410
|
+
// Name the framework build in the boot line: hosted engines install the
|
|
1411
|
+
// published package at provision time, so the serve log is the only
|
|
1412
|
+
// durable record of which build a deployment's turns actually ran on.
|
|
1413
|
+
const versionTag = c.dim(`(${PACKAGE_NAME} ${packageVersion()})`);
|
|
1386
1414
|
if (agents.length > 1) {
|
|
1387
|
-
process.stdout.write(`${agents.length} agents listening\n`);
|
|
1415
|
+
process.stdout.write(`${agents.length} agents listening ${versionTag}\n`);
|
|
1388
1416
|
} else {
|
|
1389
1417
|
const info = projectInfo(agents[0]?.project ?? handle.project);
|
|
1390
|
-
process.stdout.write(`${info.name} listening\n`);
|
|
1418
|
+
process.stdout.write(`${info.name} listening ${versionTag}\n`);
|
|
1391
1419
|
}
|
|
1392
1420
|
|
|
1393
1421
|
const playgroundUrl = resolvePlaygroundBannerUrl(handle, opts.noPlayground);
|
|
@@ -10,6 +10,7 @@ import {
|
|
|
10
10
|
import { isDevMode } from "../../internal/dev-mode.js";
|
|
11
11
|
import type {
|
|
12
12
|
AgentCloudOptions,
|
|
13
|
+
ArtifactsApi,
|
|
13
14
|
AuthContext,
|
|
14
15
|
ChannelDefinition,
|
|
15
16
|
ChannelEventHandlers,
|
|
@@ -68,7 +69,7 @@ import type {
|
|
|
68
69
|
*/
|
|
69
70
|
type GitHubParsedContext = Omit<
|
|
70
71
|
GitHubEventContext,
|
|
71
|
-
"github" | "thread" | "host"
|
|
72
|
+
"github" | "thread" | "host" | "artifacts"
|
|
72
73
|
>;
|
|
73
74
|
|
|
74
75
|
const DEFAULT_PULL_REQUEST_ACTIONS: ReadonlySet<string> = new Set([
|
|
@@ -737,6 +738,7 @@ async function handlePullRequest(input: {
|
|
|
737
738
|
bindingState: binding,
|
|
738
739
|
installationId,
|
|
739
740
|
host: input.args.host,
|
|
741
|
+
artifacts: input.args.artifacts,
|
|
740
742
|
});
|
|
741
743
|
const dispatch =
|
|
742
744
|
input.options.onPullRequest === undefined
|
|
@@ -828,6 +830,7 @@ async function handleIssueComment(input: {
|
|
|
828
830
|
bindingState: binding,
|
|
829
831
|
installationId,
|
|
830
832
|
host: input.args.host,
|
|
833
|
+
artifacts: input.args.artifacts,
|
|
831
834
|
});
|
|
832
835
|
|
|
833
836
|
const dispatch =
|
|
@@ -918,6 +921,7 @@ async function handleReviewComment(input: {
|
|
|
918
921
|
bindingState: binding,
|
|
919
922
|
installationId,
|
|
920
923
|
host: input.args.host,
|
|
924
|
+
artifacts: input.args.artifacts,
|
|
921
925
|
});
|
|
922
926
|
|
|
923
927
|
const dispatch =
|
|
@@ -994,6 +998,7 @@ async function handleIssue(input: {
|
|
|
994
998
|
bindingState: binding,
|
|
995
999
|
installationId,
|
|
996
1000
|
host: input.args.host,
|
|
1001
|
+
artifacts: input.args.artifacts,
|
|
997
1002
|
});
|
|
998
1003
|
const dispatch = await input.options.onIssue(ctx, parsed.issue);
|
|
999
1004
|
if (dispatch === null) {
|
|
@@ -1053,6 +1058,7 @@ async function handleCheckSuite(input: {
|
|
|
1053
1058
|
ctx: parsed.unanchoredCtx,
|
|
1054
1059
|
installationId,
|
|
1055
1060
|
host: input.args.host,
|
|
1061
|
+
artifacts: input.args.artifacts,
|
|
1056
1062
|
}),
|
|
1057
1063
|
parsed.checkSuite
|
|
1058
1064
|
);
|
|
@@ -1079,6 +1085,7 @@ async function handleCheckSuite(input: {
|
|
|
1079
1085
|
bindingState: binding,
|
|
1080
1086
|
installationId,
|
|
1081
1087
|
host: input.args.host,
|
|
1088
|
+
artifacts: input.args.artifacts,
|
|
1082
1089
|
});
|
|
1083
1090
|
const dispatch = await input.options.onCheckSuite(ctx, parsed.checkSuite);
|
|
1084
1091
|
if (dispatch === null) {
|
|
@@ -1143,6 +1150,7 @@ async function handleCheckRun(input: {
|
|
|
1143
1150
|
ctx: parsed.unanchoredCtx,
|
|
1144
1151
|
installationId,
|
|
1145
1152
|
host: input.args.host,
|
|
1153
|
+
artifacts: input.args.artifacts,
|
|
1146
1154
|
}),
|
|
1147
1155
|
parsed.checkRun
|
|
1148
1156
|
);
|
|
@@ -1169,6 +1177,7 @@ async function handleCheckRun(input: {
|
|
|
1169
1177
|
bindingState: binding,
|
|
1170
1178
|
installationId,
|
|
1171
1179
|
host: input.args.host,
|
|
1180
|
+
artifacts: input.args.artifacts,
|
|
1172
1181
|
});
|
|
1173
1182
|
const dispatch = await input.options.onCheckRun(ctx, parsed.checkRun);
|
|
1174
1183
|
if (dispatch === null) {
|
|
@@ -1229,6 +1238,7 @@ async function handleWorkflowRun(input: {
|
|
|
1229
1238
|
ctx: parsed.unanchoredCtx,
|
|
1230
1239
|
installationId,
|
|
1231
1240
|
host: input.args.host,
|
|
1241
|
+
artifacts: input.args.artifacts,
|
|
1232
1242
|
}),
|
|
1233
1243
|
parsed.workflowRun
|
|
1234
1244
|
);
|
|
@@ -1255,6 +1265,7 @@ async function handleWorkflowRun(input: {
|
|
|
1255
1265
|
bindingState: binding,
|
|
1256
1266
|
installationId,
|
|
1257
1267
|
host: input.args.host,
|
|
1268
|
+
artifacts: input.args.artifacts,
|
|
1258
1269
|
});
|
|
1259
1270
|
const dispatch = await input.options.onWorkflowRun(ctx, parsed.workflowRun);
|
|
1260
1271
|
if (dispatch === null) {
|
|
@@ -1326,6 +1337,7 @@ async function handleStatus(input: {
|
|
|
1326
1337
|
bindingState: binding,
|
|
1327
1338
|
installationId,
|
|
1328
1339
|
host: input.args.host,
|
|
1340
|
+
artifacts: input.args.artifacts,
|
|
1329
1341
|
});
|
|
1330
1342
|
const dispatch = await input.options.onStatus(ctx, parsed.status);
|
|
1331
1343
|
if (dispatch === null) {
|
|
@@ -1399,6 +1411,7 @@ async function handleGenericEvent(input: {
|
|
|
1399
1411
|
bindingState: binding,
|
|
1400
1412
|
installationId,
|
|
1401
1413
|
host: input.args.host,
|
|
1414
|
+
artifacts: input.args.artifacts,
|
|
1402
1415
|
});
|
|
1403
1416
|
const dispatch = await input.options.onEvent(ctx, parsed.event);
|
|
1404
1417
|
if (dispatch === null) {
|
|
@@ -2224,11 +2237,12 @@ function escapeRegExp(value: string): string {
|
|
|
2224
2237
|
*/
|
|
2225
2238
|
function enrichEventContext(input: {
|
|
2226
2239
|
bindingConfig: GitHubBindingConfig;
|
|
2227
|
-
ctx: Omit<GitHubEventContext, "github" | "thread" | "host"> &
|
|
2240
|
+
ctx: Omit<GitHubEventContext, "github" | "thread" | "host" | "artifacts"> &
|
|
2228
2241
|
Partial<Pick<GitHubEventContext, "github" | "thread">>;
|
|
2229
2242
|
bindingState: GitHubBindingState;
|
|
2230
2243
|
installationId?: number;
|
|
2231
2244
|
host: HostContext;
|
|
2245
|
+
artifacts: ArtifactsApi;
|
|
2232
2246
|
}): GitHubEventContext {
|
|
2233
2247
|
const { github, thread } = buildGitHubBinding({
|
|
2234
2248
|
config: input.bindingConfig,
|
|
@@ -2242,6 +2256,7 @@ function enrichEventContext(input: {
|
|
|
2242
2256
|
github,
|
|
2243
2257
|
thread,
|
|
2244
2258
|
host: input.host,
|
|
2259
|
+
artifacts: input.artifacts,
|
|
2245
2260
|
};
|
|
2246
2261
|
}
|
|
2247
2262
|
|
|
@@ -2254,6 +2269,7 @@ function enrichCiContext(input: {
|
|
|
2254
2269
|
ctx: GitHubParsedContext;
|
|
2255
2270
|
installationId?: number;
|
|
2256
2271
|
host: HostContext;
|
|
2272
|
+
artifacts: ArtifactsApi;
|
|
2257
2273
|
}): GitHubEventContext {
|
|
2258
2274
|
const binding = githubBindingStateForEvent({
|
|
2259
2275
|
kind: input.ctx.conversation.kind,
|
|
@@ -2269,6 +2285,7 @@ function enrichCiContext(input: {
|
|
|
2269
2285
|
bindingState: binding,
|
|
2270
2286
|
installationId: input.installationId,
|
|
2271
2287
|
host: input.host,
|
|
2288
|
+
artifacts: input.artifacts,
|
|
2272
2289
|
});
|
|
2273
2290
|
}
|
|
2274
2291
|
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type {
|
|
2
2
|
AgentCloudOptions,
|
|
3
|
+
ArtifactsApi,
|
|
3
4
|
AuthContext,
|
|
4
5
|
AuthPolicy,
|
|
5
6
|
ChannelEventHandlers,
|
|
@@ -306,6 +307,11 @@ export interface GitHubEventContext {
|
|
|
306
307
|
thread: GitHubThread;
|
|
307
308
|
/** Shared host services (MCP / host GitHub / Slack). Same as tool `ctx.host`. */
|
|
308
309
|
host: HostContext;
|
|
310
|
+
/**
|
|
311
|
+
* Durable artifacts (unbound — the hook runs before any session is
|
|
312
|
+
* admitted; pass `sessionId` in `tag` input to attribute one).
|
|
313
|
+
*/
|
|
314
|
+
artifacts: ArtifactsApi;
|
|
309
315
|
}
|
|
310
316
|
|
|
311
317
|
/**
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
5
|
import { ErrorCode, type WebAPIPlatformError, WebClient } from "@slack/web-api";
|
|
6
|
-
import type { HostContext } from "../../types.js";
|
|
6
|
+
import type { ArtifactsApi, HostContext } from "../../types.js";
|
|
7
7
|
import {
|
|
8
8
|
SLACK_DEFAULT_LOADING_MESSAGES,
|
|
9
9
|
SLACK_LOADING_MESSAGE_MAX_LEN,
|
|
@@ -540,6 +540,7 @@ export function buildSlackBinding(args: {
|
|
|
540
540
|
threadTs: string;
|
|
541
541
|
teamId?: string;
|
|
542
542
|
host: HostContext;
|
|
543
|
+
artifacts: ArtifactsApi;
|
|
543
544
|
onThreadTsChanged?: (threadTs: string) => void;
|
|
544
545
|
log?: SlackLog;
|
|
545
546
|
}): SlackBinding {
|
|
@@ -643,5 +644,6 @@ export function buildSlackBinding(args: {
|
|
|
643
644
|
...(args.teamId === undefined ? {} : { teamId: args.teamId }),
|
|
644
645
|
},
|
|
645
646
|
host: args.host,
|
|
647
|
+
artifacts: args.artifacts,
|
|
646
648
|
};
|
|
647
649
|
}
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
* dispatches relayed envelopes through the pack's normal inbound path.
|
|
13
13
|
*/
|
|
14
14
|
|
|
15
|
-
import type { HostContext, SendMessageFn } from "../../types.js";
|
|
15
|
+
import type { ArtifactsApi, HostContext, SendMessageFn } from "../../types.js";
|
|
16
16
|
import { dispatchInboundMessage } from "./dispatch.js";
|
|
17
17
|
import type { EventIdDedupe } from "./event-id-dedupe.js";
|
|
18
18
|
import { slackTextToMarkdown } from "./inbound.js";
|
|
@@ -114,6 +114,7 @@ export async function dispatchCursorSlackEnvelope(args: {
|
|
|
114
114
|
envelope: CursorSlackEnvelope;
|
|
115
115
|
send: SendMessageFn;
|
|
116
116
|
host: HostContext;
|
|
117
|
+
artifacts: ArtifactsApi;
|
|
117
118
|
hasContinuationSession?: (continuationToken: string) => Promise<boolean>;
|
|
118
119
|
isContinuationBusy?: (continuationToken: string) => Promise<boolean>;
|
|
119
120
|
getContinuationLastBotMessageTs?: (
|
|
@@ -167,6 +168,7 @@ export async function dispatchCursorSlackEnvelope(args: {
|
|
|
167
168
|
send: args.send,
|
|
168
169
|
credentials: runtime.credentials,
|
|
169
170
|
host: args.host,
|
|
171
|
+
artifacts: args.artifacts,
|
|
170
172
|
log,
|
|
171
173
|
evalCommandsEnabled: runtime.options.evalCommands !== false,
|
|
172
174
|
cursorAgentName: envelope.agentName,
|
|
@@ -2,7 +2,12 @@
|
|
|
2
2
|
* Shared inbound dispatch for Slack Events API bodies and Socket Mode.
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
-
import type {
|
|
5
|
+
import type {
|
|
6
|
+
ArtifactsApi,
|
|
7
|
+
HostContext,
|
|
8
|
+
JsonValue,
|
|
9
|
+
SendMessageFn,
|
|
10
|
+
} from "../../types.js";
|
|
6
11
|
import { buildSlackBinding, slackContinuationKey } from "./api.js";
|
|
7
12
|
import { firstLineTitle, maybeSetThreadTitle } from "./assistant.js";
|
|
8
13
|
import type { SlackBotMentionGate } from "./bot-mentions.js";
|
|
@@ -65,6 +70,8 @@ export interface SlackInboundDispatchDeps extends SlackContinuationProbes {
|
|
|
65
70
|
credentials: SlackCredentials | undefined;
|
|
66
71
|
eventIds: EventIdDedupe;
|
|
67
72
|
host: HostContext;
|
|
73
|
+
/** Unbound artifacts facade handed to handler bindings (`ctx.artifacts`). */
|
|
74
|
+
artifacts: ArtifactsApi;
|
|
68
75
|
log?: SlackLog;
|
|
69
76
|
/** Dispatch on `app_mention`. Defaults to `true`. */
|
|
70
77
|
mentionsEnabled?: boolean;
|
|
@@ -110,6 +117,7 @@ export async function dispatchInboundMessage(args: {
|
|
|
110
117
|
send: SendMessageFn;
|
|
111
118
|
credentials: SlackCredentials | undefined;
|
|
112
119
|
host: HostContext;
|
|
120
|
+
artifacts: ArtifactsApi;
|
|
113
121
|
hasContinuationSession?: (continuationToken: string) => Promise<boolean>;
|
|
114
122
|
isContinuationBusy?: (continuationToken: string) => Promise<boolean>;
|
|
115
123
|
getContinuationLastBotMessageTs?: (
|
|
@@ -132,6 +140,7 @@ export async function dispatchInboundMessage(args: {
|
|
|
132
140
|
channelId: message.channelId,
|
|
133
141
|
threadTs: message.threadTs,
|
|
134
142
|
host: args.host,
|
|
143
|
+
artifacts: args.artifacts,
|
|
135
144
|
log,
|
|
136
145
|
...(message.teamId === undefined ? {} : { teamId: message.teamId }),
|
|
137
146
|
});
|
|
@@ -450,6 +459,7 @@ export function dispatchInboundFromEventBody(
|
|
|
450
459
|
send: deps.send,
|
|
451
460
|
credentials: deps.credentials,
|
|
452
461
|
host: deps.host,
|
|
462
|
+
artifacts: deps.artifacts,
|
|
453
463
|
log,
|
|
454
464
|
evalCommandsEnabled: deps.evalCommandsEnabled,
|
|
455
465
|
cursorAgentName: deps.cursorAgentName,
|
|
@@ -490,6 +500,7 @@ export function dispatchInboundFromEventBody(
|
|
|
490
500
|
send: deps.send,
|
|
491
501
|
credentials: deps.credentials,
|
|
492
502
|
host: deps.host,
|
|
503
|
+
artifacts: deps.artifacts,
|
|
493
504
|
log,
|
|
494
505
|
evalCommandsEnabled: deps.evalCommandsEnabled,
|
|
495
506
|
cursorAgentName: deps.cursorAgentName,
|
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
|
|
10
10
|
import type {
|
|
11
11
|
ApprovalDecision,
|
|
12
|
+
ArtifactsApi,
|
|
12
13
|
AuthContext,
|
|
13
14
|
ChannelSession,
|
|
14
15
|
HostContext,
|
|
@@ -275,6 +276,7 @@ export interface SlackBlockActionDispatchDeps extends SlackContinuationProbes {
|
|
|
275
276
|
send: SendMessageFn;
|
|
276
277
|
credentials: SlackCredentials | undefined;
|
|
277
278
|
host: HostContext;
|
|
279
|
+
artifacts: ArtifactsApi;
|
|
278
280
|
log?: SlackLog;
|
|
279
281
|
}
|
|
280
282
|
|
|
@@ -347,6 +349,7 @@ export async function dispatchBlockAction(
|
|
|
347
349
|
send: deps.send,
|
|
348
350
|
credentials: deps.credentials,
|
|
349
351
|
host: deps.host,
|
|
352
|
+
artifacts: deps.artifacts,
|
|
350
353
|
log,
|
|
351
354
|
// Click text is synthetic — never treat it as a stop/eval directive.
|
|
352
355
|
evalCommandsEnabled: false,
|
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
|
|
10
10
|
import { allowAll, defineChannel } from "../../channels.js";
|
|
11
11
|
import type {
|
|
12
|
+
ArtifactsApi,
|
|
12
13
|
ChannelDefinition,
|
|
13
14
|
ChannelEventHandlers,
|
|
14
15
|
HostContext,
|
|
@@ -215,6 +216,7 @@ export function slackChannel<const Name extends string = string>(
|
|
|
215
216
|
send: SendMessageFn;
|
|
216
217
|
waitUntil: (promise: Promise<unknown>) => void;
|
|
217
218
|
host: HostContext;
|
|
219
|
+
artifacts: ArtifactsApi;
|
|
218
220
|
hasContinuationSession?: (continuationToken: string) => Promise<boolean>;
|
|
219
221
|
isContinuationBusy?: (continuationToken: string) => Promise<boolean>;
|
|
220
222
|
getContinuationLastBotMessageTs?: (
|
|
@@ -230,6 +232,7 @@ export function slackChannel<const Name extends string = string>(
|
|
|
230
232
|
credentials,
|
|
231
233
|
eventIds,
|
|
232
234
|
host: args.host,
|
|
235
|
+
artifacts: args.artifacts,
|
|
233
236
|
log: getLog(),
|
|
234
237
|
mentionsEnabled,
|
|
235
238
|
directMessagesEnabled,
|
|
@@ -410,6 +413,7 @@ export function slackChannel<const Name extends string = string>(
|
|
|
410
413
|
send: args.send,
|
|
411
414
|
credentials,
|
|
412
415
|
host: args.host,
|
|
416
|
+
artifacts: args.artifacts,
|
|
413
417
|
log: getLog(),
|
|
414
418
|
evalCommandsEnabled,
|
|
415
419
|
...(args.hasContinuationSession === undefined
|
|
@@ -454,6 +458,7 @@ export function slackChannel<const Name extends string = string>(
|
|
|
454
458
|
send: args.send,
|
|
455
459
|
waitUntil: args.waitUntil,
|
|
456
460
|
host: args.host,
|
|
461
|
+
artifacts: args.artifacts,
|
|
457
462
|
...(args.hasContinuationSession === undefined
|
|
458
463
|
? {}
|
|
459
464
|
: { hasContinuationSession: args.hasContinuationSession }),
|
|
@@ -496,6 +501,7 @@ export function slackChannel<const Name extends string = string>(
|
|
|
496
501
|
send: args.send,
|
|
497
502
|
credentials,
|
|
498
503
|
host: args.host,
|
|
504
|
+
artifacts: args.artifacts,
|
|
499
505
|
log: getLog(),
|
|
500
506
|
hasContinuationSession: args.hasContinuationSession,
|
|
501
507
|
isContinuationBusy: args.isContinuationBusy,
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
import type {
|
|
6
6
|
AgentCloudOptions,
|
|
7
|
+
ArtifactsApi,
|
|
7
8
|
AuthContext,
|
|
8
9
|
ChannelEventHandlers,
|
|
9
10
|
HostContext,
|
|
@@ -189,6 +190,11 @@ export interface SlackBinding {
|
|
|
189
190
|
};
|
|
190
191
|
/** Shared host services (MCP / GitHub / Slack). */
|
|
191
192
|
host: HostContext;
|
|
193
|
+
/**
|
|
194
|
+
* Durable artifacts (unbound — the handler runs before any session is
|
|
195
|
+
* admitted; pass `sessionId` in `tag` input to attribute one).
|
|
196
|
+
*/
|
|
197
|
+
artifacts: ArtifactsApi;
|
|
192
198
|
}
|
|
193
199
|
|
|
194
200
|
export type SlackMessageHandler = (
|
package/src/internal/ab-fold.ts
CHANGED
|
@@ -187,6 +187,10 @@ export function applyBuiltinMetrics(
|
|
|
187
187
|
m.cacheReadTokens += usage.cacheReadTokens;
|
|
188
188
|
m.cacheWriteTokens += usage.cacheWriteTokens;
|
|
189
189
|
}
|
|
190
|
+
const cost = event.data.cost;
|
|
191
|
+
if (cost !== undefined) {
|
|
192
|
+
m.costUsd += cost.totalUsd;
|
|
193
|
+
}
|
|
190
194
|
addWallTime(accum, event.at);
|
|
191
195
|
break;
|
|
192
196
|
}
|
|
@@ -323,6 +323,7 @@ function addMetrics(target: ABMetrics, delta: ABMetrics): void {
|
|
|
323
323
|
target.outputTokens += delta.outputTokens;
|
|
324
324
|
target.cacheReadTokens += delta.cacheReadTokens;
|
|
325
325
|
target.cacheWriteTokens += delta.cacheWriteTokens;
|
|
326
|
+
target.costUsd += delta.costUsd;
|
|
326
327
|
target.wallTimeMs += delta.wallTimeMs;
|
|
327
328
|
for (const [key, value] of Object.entries(delta.custom)) {
|
|
328
329
|
target.custom[key] = (target.custom[key] ?? 0) + value;
|
package/src/internal/cli-ax.ts
CHANGED
|
@@ -50,6 +50,7 @@ import {
|
|
|
50
50
|
} from "./init-project.js";
|
|
51
51
|
import { offerInstallCursorSkills } from "./install-cursor-skills.js";
|
|
52
52
|
import { runLogsTail, sanitizeCustomerError } from "./logs-client.js";
|
|
53
|
+
import { mapPool } from "./map-pool.js";
|
|
53
54
|
import { openBrowser } from "./open-browser.js";
|
|
54
55
|
import { startPlaygroundProxy } from "./playground-proxy.js";
|
|
55
56
|
import {
|
|
@@ -59,6 +60,12 @@ import {
|
|
|
59
60
|
resolveProdTarget,
|
|
60
61
|
} from "./resolve-prod-target.js";
|
|
61
62
|
import { runSession } from "./run-client.js";
|
|
63
|
+
import {
|
|
64
|
+
buildSessionCostReport,
|
|
65
|
+
formatSessionCostText,
|
|
66
|
+
formatSessionsCostText,
|
|
67
|
+
type SessionCostRow,
|
|
68
|
+
} from "./session-cost.js";
|
|
62
69
|
import {
|
|
63
70
|
fetchSessionEvents,
|
|
64
71
|
formatSessionsTable,
|
|
@@ -1771,6 +1778,94 @@ export async function cmdSession(
|
|
|
1771
1778
|
}
|
|
1772
1779
|
}
|
|
1773
1780
|
|
|
1781
|
+
/** Sessions fetched concurrently when `cost` aggregates every session. */
|
|
1782
|
+
const COST_FETCH_CONCURRENCY = 4;
|
|
1783
|
+
|
|
1784
|
+
/**
|
|
1785
|
+
* `cost [sessionId]` — pull per-session cost metrics.
|
|
1786
|
+
*
|
|
1787
|
+
* With a session id: per-turn token usage + estimated cost for that session.
|
|
1788
|
+
* Without one: one row per session (all sessions on the target) plus a
|
|
1789
|
+
* total row. `--json` prints the underlying report(s); text is the default.
|
|
1790
|
+
* Costs are the engine's recorded estimates on `turn.completed` events
|
|
1791
|
+
* (see `model-pricing.ts`); turns persisted before cost tracking simply
|
|
1792
|
+
* count as unpriced.
|
|
1793
|
+
*/
|
|
1794
|
+
export async function cmdCost(
|
|
1795
|
+
sessionId: string | undefined,
|
|
1796
|
+
options: AxCliOptions
|
|
1797
|
+
): Promise<number> {
|
|
1798
|
+
const target = await resolveSessionTarget(options);
|
|
1799
|
+
if (typeof target === "number") {
|
|
1800
|
+
return target;
|
|
1801
|
+
}
|
|
1802
|
+
const auth = {
|
|
1803
|
+
bearerToken: options.bearerToken,
|
|
1804
|
+
headers: target.headers,
|
|
1805
|
+
};
|
|
1806
|
+
|
|
1807
|
+
try {
|
|
1808
|
+
const resolved = trimNonEmpty(sessionId);
|
|
1809
|
+
if (resolved !== undefined) {
|
|
1810
|
+
const events = await fetchSessionEvents({
|
|
1811
|
+
baseUrl: target.agentUrl,
|
|
1812
|
+
sessionId: resolved,
|
|
1813
|
+
auth,
|
|
1814
|
+
fetchImpl: options.fetchImpl,
|
|
1815
|
+
});
|
|
1816
|
+
const report = buildSessionCostReport(events);
|
|
1817
|
+
if (report.sessionId === "") {
|
|
1818
|
+
report.sessionId = resolved;
|
|
1819
|
+
}
|
|
1820
|
+
if (options.json === true) {
|
|
1821
|
+
process.stdout.write(`${JSON.stringify(report, null, 2)}\n`);
|
|
1822
|
+
} else {
|
|
1823
|
+
process.stdout.write(formatSessionCostText(report));
|
|
1824
|
+
}
|
|
1825
|
+
return 0;
|
|
1826
|
+
}
|
|
1827
|
+
|
|
1828
|
+
const listed = await listSessionsWithSource({
|
|
1829
|
+
baseUrl: target.agentUrl,
|
|
1830
|
+
auth,
|
|
1831
|
+
fetchImpl: options.fetchImpl,
|
|
1832
|
+
});
|
|
1833
|
+
const rows = await mapPool(
|
|
1834
|
+
listed.sessions,
|
|
1835
|
+
COST_FETCH_CONCURRENCY,
|
|
1836
|
+
async (session): Promise<SessionCostRow> => {
|
|
1837
|
+
const events = await fetchSessionEvents({
|
|
1838
|
+
baseUrl: target.agentUrl,
|
|
1839
|
+
sessionId: session.sessionId,
|
|
1840
|
+
auth,
|
|
1841
|
+
fetchImpl: options.fetchImpl,
|
|
1842
|
+
});
|
|
1843
|
+
const report = buildSessionCostReport(events);
|
|
1844
|
+
return {
|
|
1845
|
+
sessionId: session.sessionId,
|
|
1846
|
+
channelId: session.channelId,
|
|
1847
|
+
title: session.title,
|
|
1848
|
+
updatedAt: session.updatedAt,
|
|
1849
|
+
totals: report.totals,
|
|
1850
|
+
};
|
|
1851
|
+
}
|
|
1852
|
+
);
|
|
1853
|
+
if (options.json === true) {
|
|
1854
|
+
process.stdout.write(`${JSON.stringify({ sessions: rows }, null, 2)}\n`);
|
|
1855
|
+
} else {
|
|
1856
|
+
process.stdout.write(formatSessionsCostText(rows));
|
|
1857
|
+
}
|
|
1858
|
+
return 0;
|
|
1859
|
+
} catch (error) {
|
|
1860
|
+
process.stderr.write(
|
|
1861
|
+
`${sanitizeCustomerError(
|
|
1862
|
+
error instanceof Error ? error.message : String(error)
|
|
1863
|
+
)}\n`
|
|
1864
|
+
);
|
|
1865
|
+
return 1;
|
|
1866
|
+
}
|
|
1867
|
+
}
|
|
1868
|
+
|
|
1774
1869
|
/**
|
|
1775
1870
|
* `playground` — open the web UI against local / `--url` / `--prod`.
|
|
1776
1871
|
*
|