tracksiy 0.10.0 → 0.11.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 +4 -0
- package/dist/tracksiy.mjs +168 -27
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -139,6 +139,10 @@ Labels: `bug`, `feature`, `question`, `blocker`. `npx tracksiy support` prints t
|
|
|
139
139
|
| `monitors timing <slug>` | Where an HTTP monitor's time goes (DNS, connect, server, TTFB, download, page size); how long a job runs and how close to its max runtime. | read | `monitors_timing` |
|
|
140
140
|
| `storage` | What each project holds on the server (events, transactions, source maps, debug files), largest first, with its retention limits. | read | `storage` |
|
|
141
141
|
| `mobile` | How fast the app is on phones: app start (cold/warm) against the window before, per OS and release, and per screen TTID/TTFD and slow/frozen frames, with checks for what the SDK does not report. | read | `mobile` |
|
|
142
|
+
| `logs list` | What the app logged, newest first: by level, text, trace, release, attribute. --follow keeps printing new lines. | read | `logs_list` |
|
|
143
|
+
| `logs patterns` | The loudest log lines, counted across their values (message template, or the body with numbers and ids blanked). | read | `logs_patterns` |
|
|
144
|
+
| `logs stats` | Log counts per level per minute, hour or day. | read | `logs_stats` |
|
|
145
|
+
| `issues logs <id>` | What the app logged around an error: the logs in the traces of the issue's last events. | read | `issues_logs` |
|
|
142
146
|
| `issues list` | Recent issues of a project, newest activity first, with the frames that matter inlined. | read | `issues_list` |
|
|
143
147
|
| `issues view <id>` | One issue in enough depth to act on: latest event, stack frames, tags, recent volume. | read | `issues_view` |
|
|
144
148
|
| `issues resolve <ids...>` | Mark issues resolved, optionally fixed in a release so old clients do not reopen them. Records why. | write | `issues_resolve` |
|
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.
|
|
7
|
+
var VERSION = true ? "0.11.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
|
|
@@ -508,8 +508,8 @@ function table(rows, columns2) {
|
|
|
508
508
|
widths[i]--;
|
|
509
509
|
}
|
|
510
510
|
const fit = (s, n) => s.length > n ? s.slice(0, Math.max(1, n - 1)) + "\u2026" : s.padEnd(n);
|
|
511
|
-
const
|
|
512
|
-
return [
|
|
511
|
+
const line2 = (vals) => vals.map((v, i) => fit(v, widths[i])).join(" ").trimEnd();
|
|
512
|
+
return [line2(cols.map(([n]) => n.toUpperCase())), ...cells.map(line2)].join("\n");
|
|
513
513
|
}
|
|
514
514
|
function kv(obj, keys) {
|
|
515
515
|
const entries = (keys ?? Object.keys(obj)).filter((k) => k in obj && isScalar(obj[k]));
|
|
@@ -1050,7 +1050,7 @@ var settingsGet = {
|
|
|
1050
1050
|
context: "project",
|
|
1051
1051
|
effect: "read",
|
|
1052
1052
|
endpoint: { method: "GET", path: "/api/agent/v1/projects/{org}/{project}/settings" },
|
|
1053
|
-
output: "{sourceRoots[], environments[], environmentPolicy, fingerprintRules[], privacyRules[], performanceIssues, storage{maxEventsPerIssue, sourcemapKeepReleases, sourcemapKeepUsedDays}, releaseHealth{crashFreeSessionsMin, minSessions, maxDropPct, velocityPct, velocityMinEvents}}",
|
|
1053
|
+
output: "{sourceRoots[], environments[], environmentPolicy, fingerprintRules[], privacyRules[], performanceIssues, storage{maxEventsPerIssue, sourcemapKeepReleases, sourcemapKeepUsedDays}, releaseHealth{crashFreeSessionsMin, minSessions, maxDropPct, velocityPct, velocityMinEvents}, logs{enabled, minLevel, dailyLimit}}",
|
|
1054
1054
|
async run(ctx) {
|
|
1055
1055
|
return ctx.api.get(await projectPath(ctx, "settings"));
|
|
1056
1056
|
}
|
|
@@ -1090,6 +1090,9 @@ var settingsSet = {
|
|
|
1090
1090
|
"max-drop-pct": { type: "number", value: "<points>", description: "...or this many points worse than the previous release of the line (default 0.5)." },
|
|
1091
1091
|
"velocity-pct": { type: "number", value: "<pct>", description: "Velocity alert: one issue's events in 30 minutes reaching this % of the release's sessions in the last hour (default 1)." },
|
|
1092
1092
|
"velocity-min-events": { type: "integer", value: "<n>", description: "...with at least this many events (default 10)." },
|
|
1093
|
+
logs: { type: "boolean", description: "Store structured logs at all (default on). --no-logs drops them, counted as log:disabled." },
|
|
1094
|
+
"logs-min-level": { type: "string", enum: ["trace", "debug", "info", "warn", "error", "fatal"], description: "Drop log lines below this level at ingest (default trace)." },
|
|
1095
|
+
"logs-daily-limit": { type: "integer", value: "<n>", description: "At most this many log lines a day (default 100000); the rest are dropped and counted as log:daily_limit." },
|
|
1093
1096
|
body: { type: "json", value: "<json|@file|->", description: "The whole declaration; overrides the flags." }
|
|
1094
1097
|
},
|
|
1095
1098
|
examples: [
|
|
@@ -1099,7 +1102,7 @@ var settingsSet = {
|
|
|
1099
1102
|
{ command: "tracksiy settings set --source-root 'strip=/var/www/shop/,prepend=backend/,surface=backend'", description: "The server checkout is only the repo's backend/ directory." },
|
|
1100
1103
|
{ command: "tracksiy settings set --max-events-per-issue 500 --sourcemap-keep-releases 5", description: "A noisy project keeps less on disk." }
|
|
1101
1104
|
],
|
|
1102
|
-
output: "{sourceRoots[], environments[], environmentPolicy, fingerprintRules[], privacyRules[], performanceIssues, storage{maxEventsPerIssue, sourcemapKeepReleases, sourcemapKeepUsedDays}, releaseHealth{crashFreeSessionsMin, minSessions, maxDropPct, velocityPct, velocityMinEvents}}",
|
|
1105
|
+
output: "{sourceRoots[], environments[], environmentPolicy, fingerprintRules[], privacyRules[], performanceIssues, storage{maxEventsPerIssue, sourcemapKeepReleases, sourcemapKeepUsedDays}, releaseHealth{crashFreeSessionsMin, minSessions, maxDropPct, velocityPct, velocityMinEvents}, logs{enabled, minLevel, dailyLimit}}",
|
|
1103
1106
|
async run(ctx) {
|
|
1104
1107
|
const path = await projectPath(ctx, "settings");
|
|
1105
1108
|
const i = ctx.input;
|
|
@@ -1118,6 +1121,12 @@ var settingsSet = {
|
|
|
1118
1121
|
...i.sourcemapKeepReleases !== void 0 ? { sourcemapKeepReleases: i.sourcemapKeepReleases } : {},
|
|
1119
1122
|
...i.sourcemapKeepUsedDays !== void 0 ? { sourcemapKeepUsedDays: i.sourcemapKeepUsedDays } : {}
|
|
1120
1123
|
},
|
|
1124
|
+
logs: {
|
|
1125
|
+
...current.logs ?? {},
|
|
1126
|
+
...i.logs !== void 0 ? { enabled: i.logs } : {},
|
|
1127
|
+
...i.logsMinLevel !== void 0 ? { minLevel: i.logsMinLevel } : {},
|
|
1128
|
+
...i.logsDailyLimit !== void 0 ? { dailyLimit: i.logsDailyLimit } : {}
|
|
1129
|
+
},
|
|
1121
1130
|
releaseHealth: {
|
|
1122
1131
|
...current.releaseHealth ?? {},
|
|
1123
1132
|
...i.crashFreeMin !== void 0 ? { crashFreeSessionsMin: i.crashFreeMin } : {},
|
|
@@ -1461,6 +1470,137 @@ ${checks}`;
|
|
|
1461
1470
|
};
|
|
1462
1471
|
var mobile_default = [mobile];
|
|
1463
1472
|
|
|
1473
|
+
// src/commands/logs.ts
|
|
1474
|
+
var LEVELS = ["trace", "debug", "info", "warn", "error", "fatal"];
|
|
1475
|
+
var line = (l) => `${String(l.timestamp).slice(11, 23)} ${String(l.level).toUpperCase().padEnd(5)} ${l.body}${l.traceId ? ` [trace ${String(l.traceId).slice(0, 8)}]` : ""}`;
|
|
1476
|
+
function filters(i) {
|
|
1477
|
+
return {
|
|
1478
|
+
since: since(i.since),
|
|
1479
|
+
until: since(i.until, "until"),
|
|
1480
|
+
level: i.level,
|
|
1481
|
+
query: i.query,
|
|
1482
|
+
trace: i.trace,
|
|
1483
|
+
release: i.release,
|
|
1484
|
+
environment: i.environment,
|
|
1485
|
+
logger: i.logger,
|
|
1486
|
+
attribute: i.attribute,
|
|
1487
|
+
pattern: i.pattern,
|
|
1488
|
+
limit: i.limit,
|
|
1489
|
+
cursor: i.cursor
|
|
1490
|
+
};
|
|
1491
|
+
}
|
|
1492
|
+
var FILTER_FLAGS = {
|
|
1493
|
+
since: { type: "string", value: TIME, description: "Window start (default 1h ago; at most 31 days)." },
|
|
1494
|
+
until: { type: "string", value: TIME, description: "Window end (default now)." },
|
|
1495
|
+
level: { type: "string", enum: LEVELS, description: "The lowest level shown." },
|
|
1496
|
+
query: { type: "string", value: "<text>", description: "Case-insensitive text in the line." },
|
|
1497
|
+
trace: { type: "string", value: "<trace id>", description: "Only this trace (32 hex)." },
|
|
1498
|
+
release: { type: "string", value: "<version>", description: "Only this release." },
|
|
1499
|
+
environment: { type: "string", value: "<name>", description: "Only this environment." },
|
|
1500
|
+
logger: { type: "string", value: "<name>", description: "Only this logger / origin (sentry.origin, logger.name)." },
|
|
1501
|
+
attribute: { type: "string", value: "<key=value>", description: "Only lines with this attribute value." },
|
|
1502
|
+
pattern: { type: "integer", value: "<n>", description: "Only this pattern (from `logs patterns`)." }
|
|
1503
|
+
};
|
|
1504
|
+
var list = {
|
|
1505
|
+
path: ["logs", "list"],
|
|
1506
|
+
aliases: [["logs"]],
|
|
1507
|
+
summary: "What the app logged, newest first: by level, text, trace, release, attribute. --follow keeps printing new lines.",
|
|
1508
|
+
description: "Structured logs from the SDKs (Sentry.logger.*, sentry-laravel's sentry_logs channel, the mobile loggers). `next` pages older lines (--cursor). --follow 10m polls every 3 s and prints new lines as they arrive (stderr), then returns them all. Per-project limits: `settings set --logs/--logs-min-level/--logs-daily-limit`.",
|
|
1509
|
+
context: "project",
|
|
1510
|
+
effect: "read",
|
|
1511
|
+
endpoint: { method: "GET", path: "/api/agent/v1/projects/{org}/{project}/logs" },
|
|
1512
|
+
flags: {
|
|
1513
|
+
...FILTER_FLAGS,
|
|
1514
|
+
limit: { type: "integer", value: "<n>", description: "Lines per page (default 100, at most 500)." },
|
|
1515
|
+
cursor: { type: "string", value: "<id>", description: "The `next` of the previous page." },
|
|
1516
|
+
follow: { type: "string", value: "<duration>", description: "Keep polling for new lines this long: 5m, 1h." }
|
|
1517
|
+
},
|
|
1518
|
+
examples: [
|
|
1519
|
+
{ command: "tracksiy logs --level warn --since 30m", description: "Warnings and errors of the last half hour." },
|
|
1520
|
+
{ command: "tracksiy logs --trace 5b8efff798038103d269b633813fc60c", description: "Everything one request logged." },
|
|
1521
|
+
{ command: "tracksiy logs --query checkout --follow 10m", description: "Watch a deploy." }
|
|
1522
|
+
],
|
|
1523
|
+
output: "{since, until, logs:[{id, timestamp, level, severity, body, traceId, spanId, release, environment, logger, source, pattern, attributes}], next}",
|
|
1524
|
+
text: (d) => `${(d.logs ?? []).slice().reverse().map(line).join("\n") || "(no lines)"}${d.next ? `
|
|
1525
|
+
|
|
1526
|
+
older: --cursor ${d.next}` : ""}`,
|
|
1527
|
+
async run(ctx) {
|
|
1528
|
+
const path = await projectPath(ctx, "logs");
|
|
1529
|
+
const query = filters(ctx.input);
|
|
1530
|
+
const followSeconds = duration(ctx.input.follow, "follow") ?? 0;
|
|
1531
|
+
let data = await ctx.api.get(path, query);
|
|
1532
|
+
if (!followSeconds) return data;
|
|
1533
|
+
const seen = new Set((data.logs ?? []).map((l) => l.id));
|
|
1534
|
+
const all = [...data.logs ?? []];
|
|
1535
|
+
let lastTime = all.length ? all[0].timestamp : (/* @__PURE__ */ new Date()).toISOString();
|
|
1536
|
+
const deadline = Date.now() + followSeconds * 1e3;
|
|
1537
|
+
while (Date.now() < deadline) {
|
|
1538
|
+
await new Promise((r) => setTimeout(r, 3e3));
|
|
1539
|
+
const page = await ctx.api.get(path, { ...query, since: lastTime, cursor: void 0, limit: 500 });
|
|
1540
|
+
const fresh = (page.logs ?? []).filter((l) => !seen.has(l.id)).reverse();
|
|
1541
|
+
for (const l of fresh) {
|
|
1542
|
+
seen.add(l.id);
|
|
1543
|
+
all.unshift(l);
|
|
1544
|
+
ctx.log(line(l));
|
|
1545
|
+
lastTime = l.timestamp;
|
|
1546
|
+
}
|
|
1547
|
+
}
|
|
1548
|
+
return { ...data, logs: all, next: null };
|
|
1549
|
+
}
|
|
1550
|
+
};
|
|
1551
|
+
var patterns = {
|
|
1552
|
+
path: ["logs", "patterns"],
|
|
1553
|
+
summary: "The loudest log lines, counted across their values (message template, or the body with numbers and ids blanked).",
|
|
1554
|
+
context: "project",
|
|
1555
|
+
effect: "read",
|
|
1556
|
+
endpoint: { method: "GET", path: "/api/agent/v1/projects/{org}/{project}/logs/patterns" },
|
|
1557
|
+
flags: {
|
|
1558
|
+
since: FILTER_FLAGS.since,
|
|
1559
|
+
until: FILTER_FLAGS.until,
|
|
1560
|
+
level: FILTER_FLAGS.level,
|
|
1561
|
+
limit: { type: "integer", value: "<n>", description: "Patterns (default 100, at most 200)." }
|
|
1562
|
+
},
|
|
1563
|
+
examples: [{ command: "tracksiy logs patterns --since 24h --level warn", description: "Which warnings repeat; then `logs --pattern <n>`." }],
|
|
1564
|
+
output: "{patterns:[{pattern, count, level, lastSeen, template, sample}]}",
|
|
1565
|
+
text: (d) => table(d.patterns ?? [], ["count", "level", ["line", (r) => (r.template ?? r.sample ?? "").slice(0, 100)], "pattern"]),
|
|
1566
|
+
async run(ctx) {
|
|
1567
|
+
const i = ctx.input;
|
|
1568
|
+
return ctx.api.get(await projectPath(ctx, "logs/patterns"), { since: since(i.since), until: since(i.until, "until"), level: i.level, limit: i.limit });
|
|
1569
|
+
}
|
|
1570
|
+
};
|
|
1571
|
+
var stats = {
|
|
1572
|
+
path: ["logs", "stats"],
|
|
1573
|
+
summary: "Log counts per level per minute, hour or day.",
|
|
1574
|
+
context: "project",
|
|
1575
|
+
effect: "read",
|
|
1576
|
+
endpoint: { method: "GET", path: "/api/agent/v1/projects/{org}/{project}/logs/stats" },
|
|
1577
|
+
flags: { since: FILTER_FLAGS.since, until: FILTER_FLAGS.until },
|
|
1578
|
+
output: "{bucketSeconds, totals{level: n}, buckets:[{start, counts}]}",
|
|
1579
|
+
text: (d) => `${kv(d.totals ?? {})}
|
|
1580
|
+
|
|
1581
|
+
${table(d.buckets ?? [], ["start", ...LEVELS.map((lvl) => [lvl, (r) => r.counts?.[lvl] ?? ""])])}`,
|
|
1582
|
+
async run(ctx) {
|
|
1583
|
+
const i = ctx.input;
|
|
1584
|
+
return ctx.api.get(await projectPath(ctx, "logs/stats"), { since: since(i.since), until: since(i.until, "until") });
|
|
1585
|
+
}
|
|
1586
|
+
};
|
|
1587
|
+
var issueLogs = {
|
|
1588
|
+
path: ["issues", "logs"],
|
|
1589
|
+
summary: "What the app logged around an error: the logs in the traces of the issue's last events.",
|
|
1590
|
+
context: "project",
|
|
1591
|
+
effect: "read",
|
|
1592
|
+
endpoint: { method: "GET", path: "/api/agent/v1/projects/{org}/{project}/issues/{id}/logs" },
|
|
1593
|
+
args: [{ name: "id", required: true, description: "The issue id." }],
|
|
1594
|
+
output: "{issueId, traces[], logs[...], notes[]}",
|
|
1595
|
+
text: (d) => `${(d.logs ?? []).slice().reverse().map(line).join("\n") || "(no lines)"}${(d.notes ?? []).length ? `
|
|
1596
|
+
|
|
1597
|
+
${d.notes.join("\n")}` : ""}`,
|
|
1598
|
+
async run(ctx) {
|
|
1599
|
+
return ctx.api.get(await projectPath(ctx, `issues/${encodeURIComponent(ctx.input.id)}/logs`));
|
|
1600
|
+
}
|
|
1601
|
+
};
|
|
1602
|
+
var logs_default = [list, patterns, stats, issueLogs];
|
|
1603
|
+
|
|
1464
1604
|
// src/commands/issues.ts
|
|
1465
1605
|
import { writeFileSync } from "node:fs";
|
|
1466
1606
|
var FILTERS = {
|
|
@@ -1518,7 +1658,7 @@ var issueRows = (issues) => table(issues ?? [], [
|
|
|
1518
1658
|
["status", (r) => r.regressedAt && r.status === "unresolved" ? "regressed" : r.status],
|
|
1519
1659
|
["title", (r) => r.title]
|
|
1520
1660
|
]);
|
|
1521
|
-
var
|
|
1661
|
+
var list2 = {
|
|
1522
1662
|
path: ["issues", "list"],
|
|
1523
1663
|
aliases: [["issues"]],
|
|
1524
1664
|
summary: "Recent issues of a project, newest activity first, with the frames that matter inlined.",
|
|
@@ -1818,7 +1958,7 @@ var bulk = {
|
|
|
1818
1958
|
return result;
|
|
1819
1959
|
}
|
|
1820
1960
|
};
|
|
1821
|
-
var issues_default = [
|
|
1961
|
+
var issues_default = [list2, view, resolve2, ignore, unresolve, bulk, merge, comment, activity, verifyFixed, claim, unclaim];
|
|
1822
1962
|
|
|
1823
1963
|
// src/commands/projects.ts
|
|
1824
1964
|
var create = {
|
|
@@ -1933,8 +2073,8 @@ var DECLARE = {
|
|
|
1933
2073
|
"replace-recipients": { type: "boolean", description: "Make the recipient list exactly this one (default: add to it)." },
|
|
1934
2074
|
body: { type: "json", value: "<json|@file|->", description: "Raw request body; overrides the other flags." }
|
|
1935
2075
|
};
|
|
1936
|
-
function recipients(
|
|
1937
|
-
return (
|
|
2076
|
+
function recipients(list6, delivery) {
|
|
2077
|
+
return (list6 ?? []).map((raw) => {
|
|
1938
2078
|
const i = raw.indexOf(":");
|
|
1939
2079
|
const type = i > 0 ? raw.slice(0, i) : raw;
|
|
1940
2080
|
if (!RECIPIENT_TYPES.includes(type)) {
|
|
@@ -2115,7 +2255,7 @@ var settingsSet2 = {
|
|
|
2115
2255
|
var alerts_default = [get, set, test, coverage, defaults, settingsGet2, settingsSet2];
|
|
2116
2256
|
|
|
2117
2257
|
// src/commands/keys.ts
|
|
2118
|
-
var
|
|
2258
|
+
var list3 = {
|
|
2119
2259
|
path: ["keys", "list"],
|
|
2120
2260
|
aliases: [["keys"]],
|
|
2121
2261
|
summary: "Every ingest key of the project: its surface, whether ingest accepts it, its rate limit and volume.",
|
|
@@ -2172,11 +2312,11 @@ var rotate = {
|
|
|
2172
2312
|
return ctx.api.send("POST", await projectPath(ctx, `keys/${seg(ctx.input.name)}/rotate`));
|
|
2173
2313
|
}
|
|
2174
2314
|
};
|
|
2175
|
-
var keys_default = [
|
|
2315
|
+
var keys_default = [list3, set2, rotate];
|
|
2176
2316
|
|
|
2177
2317
|
// src/commands/releases.ts
|
|
2178
2318
|
import { execFileSync } from "node:child_process";
|
|
2179
|
-
var
|
|
2319
|
+
var list4 = {
|
|
2180
2320
|
path: ["releases", "list"],
|
|
2181
2321
|
aliases: [["releases"]],
|
|
2182
2322
|
summary: "What did the last deploys break? Recent releases with their events, issues and the issues they introduced.",
|
|
@@ -2322,7 +2462,7 @@ ${table(d.newIssues, ["short_id", "count", "title"])}` : ""}`,
|
|
|
2322
2462
|
return data;
|
|
2323
2463
|
}
|
|
2324
2464
|
};
|
|
2325
|
-
var releases_default = [
|
|
2465
|
+
var releases_default = [list4, health2, declare, verdict];
|
|
2326
2466
|
|
|
2327
2467
|
// src/commands/artifacts.ts
|
|
2328
2468
|
import { readFile as readFile2, writeFile as writeFile2 } from "node:fs/promises";
|
|
@@ -2763,7 +2903,7 @@ var artifacts_default = [sourcemapsInject, sourcemapsUpload, proguardUpload, art
|
|
|
2763
2903
|
|
|
2764
2904
|
// src/commands/tokens.ts
|
|
2765
2905
|
var SCOPE_HINT = "e.g. org:read,project:read,event:read,event:write,project:write,project:releases,project:admin";
|
|
2766
|
-
var
|
|
2906
|
+
var list5 = {
|
|
2767
2907
|
path: ["tokens", "list"],
|
|
2768
2908
|
aliases: [["tokens"]],
|
|
2769
2909
|
summary: "Your tokens, newest first, without their values.",
|
|
@@ -2876,7 +3016,7 @@ var self = {
|
|
|
2876
3016
|
return ctx.api.get("tokens/self");
|
|
2877
3017
|
}
|
|
2878
3018
|
};
|
|
2879
|
-
var tokens_default = [
|
|
3019
|
+
var tokens_default = [list5, self, create2, update, remove, rotate2];
|
|
2880
3020
|
|
|
2881
3021
|
// src/commands/support.ts
|
|
2882
3022
|
var SUPPORT = {
|
|
@@ -3540,15 +3680,15 @@ function makeContext(spec, input, globals, surface, io) {
|
|
|
3540
3680
|
const org = () => {
|
|
3541
3681
|
orgPromise ??= (async () => {
|
|
3542
3682
|
if (config.org) return config.org;
|
|
3543
|
-
const
|
|
3544
|
-
if (
|
|
3545
|
-
log(`using organization ${
|
|
3546
|
-
return
|
|
3683
|
+
const list6 = await visible();
|
|
3684
|
+
if (list6.length === 1) {
|
|
3685
|
+
log(`using organization ${list6[0].slug}`);
|
|
3686
|
+
return list6[0].slug;
|
|
3547
3687
|
}
|
|
3548
3688
|
throw usageError(
|
|
3549
3689
|
"missing_org",
|
|
3550
|
-
|
|
3551
|
-
|
|
3690
|
+
list6.length ? "Which organization? This token can see several." : "This token cannot see any organization.",
|
|
3691
|
+
list6.length ? `Pass --org <slug>, set TRACKSIY_ORG, or add "org" to ${".tracksiy.json"}. Visible: ${list6.map((o) => o.slug).join(", ")}` : "Check the token with `tracksiy auth status`."
|
|
3552
3692
|
);
|
|
3553
3693
|
})();
|
|
3554
3694
|
return orgPromise;
|
|
@@ -3558,8 +3698,8 @@ function makeContext(spec, input, globals, surface, io) {
|
|
|
3558
3698
|
projectPromise ??= (async () => {
|
|
3559
3699
|
const o = await org();
|
|
3560
3700
|
if (config.project) return { org: o, project: config.project };
|
|
3561
|
-
const
|
|
3562
|
-
const projects2 =
|
|
3701
|
+
const list6 = await visible();
|
|
3702
|
+
const projects2 = list6.find((x) => x.slug === o)?.projects ?? [];
|
|
3563
3703
|
if (projects2.length === 1) {
|
|
3564
3704
|
log(`using project ${o}/${projects2[0].slug}`);
|
|
3565
3705
|
return { org: o, project: projects2[0].slug };
|
|
@@ -3724,11 +3864,11 @@ async function serve(io, defaults2) {
|
|
|
3724
3864
|
const rl = createInterface({ input: process.stdin, crlfDelay: Infinity });
|
|
3725
3865
|
io.stderr(`tracksiy mcp ${VERSION}: ${server.toolCount} tools on stdio
|
|
3726
3866
|
`);
|
|
3727
|
-
for await (const
|
|
3728
|
-
if (!
|
|
3867
|
+
for await (const line2 of rl) {
|
|
3868
|
+
if (!line2.trim()) continue;
|
|
3729
3869
|
let msg;
|
|
3730
3870
|
try {
|
|
3731
|
-
msg = JSON.parse(
|
|
3871
|
+
msg = JSON.parse(line2);
|
|
3732
3872
|
} catch {
|
|
3733
3873
|
write({ jsonrpc: "2.0", id: null, error: { code: -32700, message: "Parse error" } });
|
|
3734
3874
|
continue;
|
|
@@ -3782,6 +3922,7 @@ var COMMANDS = [
|
|
|
3782
3922
|
...perf_default,
|
|
3783
3923
|
...storage_default,
|
|
3784
3924
|
...mobile_default,
|
|
3925
|
+
...logs_default,
|
|
3785
3926
|
...issues_default,
|
|
3786
3927
|
...projects_default,
|
|
3787
3928
|
...alerts_default,
|
|
@@ -3795,7 +3936,7 @@ var COMMANDS = [
|
|
|
3795
3936
|
];
|
|
3796
3937
|
var GROUPS = [
|
|
3797
3938
|
["Start", "init auth onboarding describe"],
|
|
3798
|
-
["Look", "overview changes health storage orgs projects issues monitors performance mobile queries not-found releases alerts keys artifacts settings privacy-preview"],
|
|
3939
|
+
["Look", "overview changes health storage orgs projects issues monitors performance mobile logs queries not-found releases alerts keys artifacts settings privacy-preview"],
|
|
3799
3940
|
["Ship", "sourcemaps proguard"],
|
|
3800
3941
|
["Manage", "tokens"],
|
|
3801
3942
|
["Talk to us", "support"],
|