tracksiy 0.2.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -134,6 +134,7 @@ Labels: `bug`, `feature`, `question`, `blocker`. `npx tracksiy support` prints t
134
134
  | `issues bulk-status` | Change the status of every issue matching a filter. Dry run unless --apply. | write | `issues_bulk_status` |
135
135
  | `issues comment <id>` | Leave a comment on an issue for the next agent or human: what you found, what you tried. | write | `issues_comment` |
136
136
  | `issues activity <id>` | Who did what to an issue and why: resolutions (and in which release), regressions, comments, claims. | read | `issues_activity` |
137
+ | `issues verify-fixed <id>` | Did the fix hold? Judged by the fix release's own traffic: fixed, regressed or undetermined. Exit 10 unless fixed. | read | `issues_verify_fixed` |
137
138
  | `issues claim <id>` | Take a lease on an issue so no other agent works on it meanwhile. Lapses on its own. | write | `issues_claim` |
138
139
  | `issues unclaim <id>` | Give back your lease on an issue. | write | `issues_unclaim` |
139
140
  | `projects create <name>` | Everything a new app needs in one idempotent call: the project, an ingest key per surface, an upload token, and the next steps. | write | `projects_create` |
package/dist/tracksiy.mjs CHANGED
@@ -4,7 +4,7 @@
4
4
  import { readFileSync as readFileSync2 } from "node:fs";
5
5
 
6
6
  // src/version.ts
7
- var VERSION = true ? "0.2.0" : "0.0.0-dev";
7
+ var VERSION = true ? "0.3.0" : "0.0.0-dev";
8
8
  var USER_AGENT = `tracksiy-cli/${VERSION} (node ${process.versions.node}; ${process.platform})`;
9
9
 
10
10
  // src/core/errors.ts
@@ -1122,6 +1122,40 @@ var activity = {
1122
1122
  return ctx.api.get(await projectPath(ctx, `issues/${encodeURIComponent(ctx.input.id)}/activity`), { limit: ctx.input.limit });
1123
1123
  }
1124
1124
  };
1125
+ var verifyFixed = {
1126
+ path: ["issues", "verify-fixed"],
1127
+ summary: "Did the fix hold? Judged by the fix release's own traffic: fixed, regressed or undetermined. Exit 10 unless fixed.",
1128
+ description: "regressed: the issue has an event from the fix release or a newer one. undetermined: the fix release has had too little traffic (--min-traffic), or the issue's old rate predicts fewer than 3 occurrences in that traffic. fixed otherwise. The fix release defaults to the one the issue was resolved in. --wait polls until the verdict is not undetermined.",
1129
+ context: "project",
1130
+ effect: "read",
1131
+ endpoint: { method: "GET", path: "/api/agent/v1/projects/{org}/{project}/issues/{issue_id}/verify" },
1132
+ args: [{ name: "id", required: true, description: "Issue id." }],
1133
+ flags: {
1134
+ release: { type: "string", value: "<version>", description: "The fix release. Default: the one it was resolved in." },
1135
+ "min-traffic": { type: "integer", value: "<n>", description: "Transactions + errors + sessions from the fix release needed before silence counts (default 100)." },
1136
+ wait: { type: "integer", value: "<seconds>", description: "Poll every 30 s until fixed or regressed, up to this long." }
1137
+ },
1138
+ examples: [
1139
+ { command: "tracksiy issues verify-fixed 4812", description: "Verdict now." },
1140
+ { command: "tracksiy issues verify-fixed 4812 --wait 1800", description: "In a deploy script: wait up to 30 min for enough traffic." }
1141
+ ],
1142
+ output: "{verdict, reason, release, since, eventsSince, staleEvents, traffic{transactions, errors, sessions, total}, baselinePer1000, expectedEvents, latestEvent?}",
1143
+ text: (d) => kv(d, ["verdict", "reason", "release", "since", "eventsSince", "staleEvents", "expectedEvents"]) + `
1144
+ traffic: ${d.traffic?.total ?? 0} (${d.traffic?.transactions ?? 0} transactions, ${d.traffic?.errors ?? 0} errors, ${d.traffic?.sessions ?? 0} sessions)`,
1145
+ async run(ctx) {
1146
+ const path = await projectPath(ctx, `issues/${encodeURIComponent(ctx.input.id)}/verify`);
1147
+ const query = { release: ctx.input.release, minTraffic: ctx.input.minTraffic };
1148
+ const deadline = Date.now() + (ctx.input.wait ?? 0) * 1e3;
1149
+ let data = await ctx.api.get(path, query);
1150
+ while (data?.verdict === "undetermined" && Date.now() + 3e4 <= deadline) {
1151
+ ctx.log(`undetermined: ${data.reason} -- checking again in 30 s`);
1152
+ await new Promise((r) => setTimeout(r, 3e4));
1153
+ data = await ctx.api.get(path, query);
1154
+ }
1155
+ if (data?.verdict !== "fixed") throw new CheckFailed(`${data?.verdict ?? "unknown"}: ${data?.reason ?? ""}`, data, data?.verdict === "regressed" ? "Reopened by its own release: look at latestEvent." : "Wait for traffic (--wait), or lower --min-traffic.");
1156
+ return data;
1157
+ }
1158
+ };
1125
1159
  var claim = {
1126
1160
  path: ["issues", "claim"],
1127
1161
  summary: "Take a lease on an issue so no other agent works on it meanwhile. Lapses on its own.",
@@ -1195,7 +1229,7 @@ var bulk = {
1195
1229
  return ctx.api.send("POST", await projectPath(ctx, "issues/status"), body);
1196
1230
  }
1197
1231
  };
1198
- var issues_default = [list, view, resolve2, ignore, unresolve, bulk, comment, activity, claim, unclaim];
1232
+ var issues_default = [list, view, resolve2, ignore, unresolve, bulk, comment, activity, verifyFixed, claim, unclaim];
1199
1233
 
1200
1234
  // src/commands/projects.ts
1201
1235
  var create = {
@@ -1294,12 +1328,12 @@ var onboarding = {
1294
1328
  var projects_default = [create, verify, onboarding];
1295
1329
 
1296
1330
  // src/commands/alerts.ts
1297
- var RECIPIENT_TYPES = ["email", "webhook", "discord", "googlechat", "telegram"];
1331
+ var RECIPIENT_TYPES = ["email", "webhook", "discord", "googlechat", "telegram", "peerpacket"];
1298
1332
  var DECLARE = {
1299
1333
  recipient: {
1300
1334
  type: "list",
1301
1335
  value: "email|<type>:<url>",
1302
- description: `Who is told. Repeatable. \`email\` alone reaches the members of the project's teams; webhook, discord, googlechat and telegram take a URL: \`<type>:<url>\` (telegram: the Bot API sendMessage URL with chat_id).`
1336
+ description: `Who is told. Repeatable. \`email\` alone reaches the members of the project's teams; webhook, discord, googlechat and telegram take a URL: \`<type>:<url>\` (telegram: the Bot API sendMessage URL with chat_id; peerpacket: https://peerpacket.com/channels/<channel>?to=<handle>&as=<author>&key=<pp_live_\u2026> -- each alert becomes a ticket for that agent, closed when its issues are resolved).`
1303
1337
  },
1304
1338
  delivery: { type: "string", enum: ["immediate", "digest"], description: "For --recipient: send each alert now, or batch into the digest hours. Default immediate." },
1305
1339
  "new-issue": { type: "boolean", description: "Alert on every new issue (default true). --no-new-issue to turn off." },
@@ -1376,7 +1410,8 @@ var set = {
1376
1410
  flags: DECLARE,
1377
1411
  examples: [
1378
1412
  { command: "tracksiy alerts set --recipient email --threshold 50/10", description: "Email the project's team on new issues, on bursts, and on downtime." },
1379
- { command: "tracksiy alerts set --recipient 'telegram:https://api.telegram.org/bot<token>/sendMessage?chat_id=<id>' --delivery digest", description: "Telegram, batched into the digest hours." }
1413
+ { command: "tracksiy alerts set --recipient 'telegram:https://api.telegram.org/bot<token>/sendMessage?chat_id=<id>' --delivery digest", description: "Telegram, batched into the digest hours." },
1414
+ { command: "tracksiy alerts set --recipient 'peerpacket:https://peerpacket.com/channels/shop-ops?to=shop-agent&as=tracksiy-alerts&key=pp_live_\u2026'", description: "Alerts land as PeerPacket tickets for the shop's agent." }
1380
1415
  ],
1381
1416
  output: "The stored alerting state, same shape as `alerts get`.",
1382
1417
  text: rulesText,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tracksiy",
3
- "version": "0.2.0",
3
+ "version": "0.3.0",
4
4
  "description": "Agent-first CLI and MCP server for Tracksiy: errors, uptime, alerts, releases and source maps, from one token.",
5
5
  "type": "module",
6
6
  "bin": {