@dataworks-technology/cli 1.2.0 → 1.4.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.
Files changed (56) hide show
  1. package/.agents/plugins/marketplace.json +20 -0
  2. package/.claude-plugin/marketplace.json +16 -0
  3. package/README.md +85 -2
  4. package/bin/mcp.js +9 -0
  5. package/bin/postinstall.js +23 -0
  6. package/dist/commands/agents/install.d.ts +17 -0
  7. package/dist/commands/agents/install.d.ts.map +1 -0
  8. package/dist/commands/agents/install.js +57 -0
  9. package/dist/commands/agents/install.js.map +1 -0
  10. package/dist/commands/agents/reminder.d.ts +16 -0
  11. package/dist/commands/agents/reminder.d.ts.map +1 -0
  12. package/dist/commands/agents/reminder.js +45 -0
  13. package/dist/commands/agents/reminder.js.map +1 -0
  14. package/dist/commands/commands.d.ts.map +1 -1
  15. package/dist/commands/commands.js +2 -0
  16. package/dist/commands/commands.js.map +1 -1
  17. package/dist/generated/metrics.d.ts +15 -0
  18. package/dist/generated/metrics.d.ts.map +1 -0
  19. package/dist/generated/metrics.js +131 -0
  20. package/dist/generated/metrics.js.map +1 -0
  21. package/dist/lib/agent-install.d.ts +24 -0
  22. package/dist/lib/agent-install.d.ts.map +1 -0
  23. package/dist/lib/agent-install.js +196 -0
  24. package/dist/lib/agent-install.js.map +1 -0
  25. package/dist/lib/agent-reminder.d.ts +17 -0
  26. package/dist/lib/agent-reminder.d.ts.map +1 -0
  27. package/dist/lib/agent-reminder.js +81 -0
  28. package/dist/lib/agent-reminder.js.map +1 -0
  29. package/dist/lib/command.d.ts +1 -0
  30. package/dist/lib/command.d.ts.map +1 -1
  31. package/dist/lib/command.js +5 -0
  32. package/dist/lib/command.js.map +1 -1
  33. package/dist/lib/metric-names.d.ts +29 -0
  34. package/dist/lib/metric-names.d.ts.map +1 -0
  35. package/dist/lib/metric-names.js +171 -0
  36. package/dist/lib/metric-names.js.map +1 -0
  37. package/dist/lib/query-metrics.d.ts +73 -0
  38. package/dist/lib/query-metrics.d.ts.map +1 -0
  39. package/dist/lib/query-metrics.js +374 -0
  40. package/dist/lib/query-metrics.js.map +1 -0
  41. package/dist/mcp/main.d.ts +2 -0
  42. package/dist/mcp/main.d.ts.map +1 -0
  43. package/dist/mcp/main.js +7 -0
  44. package/dist/mcp/main.js.map +1 -0
  45. package/dist/mcp/server.d.ts +85 -0
  46. package/dist/mcp/server.d.ts.map +1 -0
  47. package/dist/mcp/server.js +248 -0
  48. package/dist/mcp/server.js.map +1 -0
  49. package/oclif.manifest.json +872 -759
  50. package/package.json +22 -8
  51. package/plugins/dataworks/.claude-plugin/plugin.json +10 -0
  52. package/plugins/dataworks/.codex-plugin/plugin.json +27 -0
  53. package/plugins/dataworks/.mcp.json +8 -0
  54. package/plugins/dataworks/skills/query-dataworks-metrics/SKILL.md +70 -0
  55. package/plugins/dataworks/skills/query-dataworks-metrics/agents/openai.yaml +13 -0
  56. package/skills/dataworks-cli/SKILL.md +18 -2
@@ -0,0 +1,196 @@
1
+ import { spawnSync } from "node:child_process";
2
+ import { resolve } from "node:path";
3
+ import { fileURLToPath } from "node:url";
4
+ const marketplaceName = "dataworks-cli";
5
+ const pluginId = `dataworks@${marketplaceName}`;
6
+ export const supportedAgentClients = ["codex", "claude-code"];
7
+ export function dataworksPackageRoot() {
8
+ return fileURLToPath(new URL("../../", import.meta.url));
9
+ }
10
+ function defaultRunner(command, args) {
11
+ const result = spawnSync(command, [...args], {
12
+ encoding: "utf8",
13
+ stdio: ["ignore", "pipe", "pipe"],
14
+ });
15
+ return {
16
+ status: result.status,
17
+ stdout: result.stdout ?? "",
18
+ stderr: result.stderr ?? "",
19
+ error: result.error,
20
+ };
21
+ }
22
+ function executable(client) {
23
+ return client === "codex" ? "codex" : "claude";
24
+ }
25
+ function failureMessage(result) {
26
+ return (result.stderr.trim() ||
27
+ result.stdout.trim() ||
28
+ result.error?.message ||
29
+ "The client command failed without an error message.");
30
+ }
31
+ function parseJson(value) {
32
+ try {
33
+ return JSON.parse(value);
34
+ }
35
+ catch {
36
+ return undefined;
37
+ }
38
+ }
39
+ function codexMarketplaceRoot(payload) {
40
+ if (!payload || typeof payload !== "object")
41
+ return undefined;
42
+ const marketplaces = payload.marketplaces;
43
+ if (!Array.isArray(marketplaces))
44
+ return undefined;
45
+ const entry = marketplaces.find((candidate) => !!candidate &&
46
+ typeof candidate === "object" &&
47
+ candidate.name === marketplaceName);
48
+ return entry?.root;
49
+ }
50
+ function claudeMarketplace(payload) {
51
+ if (!Array.isArray(payload))
52
+ return { exists: false };
53
+ const entry = payload.find((candidate) => !!candidate &&
54
+ typeof candidate === "object" &&
55
+ candidate.name === marketplaceName);
56
+ return {
57
+ exists: !!entry,
58
+ root: entry?.path ?? entry?.installLocation,
59
+ };
60
+ }
61
+ function pluginIsInstalled(client, payload) {
62
+ const entries = client === "codex" && payload && typeof payload === "object"
63
+ ? payload.installed
64
+ : payload;
65
+ if (!Array.isArray(entries))
66
+ return false;
67
+ return entries.some((entry) => {
68
+ if (!entry || typeof entry !== "object")
69
+ return false;
70
+ const item = entry;
71
+ return (item.id === pluginId ||
72
+ item.pluginId === pluginId ||
73
+ (item.name === "dataworks" &&
74
+ (item.marketplace === marketplaceName ||
75
+ item.marketplaceName === marketplaceName)));
76
+ });
77
+ }
78
+ function unavailable(client) {
79
+ const binary = executable(client);
80
+ return {
81
+ client,
82
+ status: "unavailable",
83
+ message: `${binary} is not installed or is not available on PATH.`,
84
+ nextStep: `Install ${client === "codex" ? "Codex" : "Claude Code"}, then run \`dw agents install ${client}\` again.`,
85
+ };
86
+ }
87
+ function failed(client, result, nextStep) {
88
+ return {
89
+ client,
90
+ status: "failed",
91
+ message: failureMessage(result),
92
+ nextStep,
93
+ };
94
+ }
95
+ function installCodex(options) {
96
+ const { run, packageRoot, force } = options;
97
+ const list = run("codex", ["plugin", "marketplace", "list", "--json"]);
98
+ if (list.status !== 0) {
99
+ return failed("codex", list, "Run `codex plugin marketplace list` to inspect the Codex plugin configuration, then retry.");
100
+ }
101
+ const listedRoot = codexMarketplaceRoot(parseJson(list.stdout));
102
+ const currentRoot = listedRoot ? resolve(listedRoot) : undefined;
103
+ if (currentRoot && currentRoot !== packageRoot) {
104
+ if (!force) {
105
+ return {
106
+ client: "codex",
107
+ status: "failed",
108
+ message: `The ${marketplaceName} marketplace already points to ${currentRoot}.`,
109
+ nextStep: "Run `dw agents install codex --force` to replace the stale marketplace registration.",
110
+ };
111
+ }
112
+ const remove = run("codex", ["plugin", "marketplace", "remove", marketplaceName]);
113
+ if (remove.status !== 0) {
114
+ return failed("codex", remove, "Run `codex plugin marketplace list` to inspect the conflicting registration.");
115
+ }
116
+ }
117
+ if (!currentRoot || currentRoot !== packageRoot) {
118
+ const addMarketplace = run("codex", [
119
+ "plugin",
120
+ "marketplace",
121
+ "add",
122
+ packageRoot,
123
+ "--json",
124
+ ]);
125
+ if (addMarketplace.status !== 0) {
126
+ return failed("codex", addMarketplace, `Run \`codex plugin marketplace add ${packageRoot}\`, then retry.`);
127
+ }
128
+ }
129
+ const before = run("codex", ["plugin", "list", "--json"]);
130
+ const alreadyInstalled = before.status === 0 && pluginIsInstalled("codex", parseJson(before.stdout));
131
+ const install = run("codex", ["plugin", "add", pluginId, "--json"]);
132
+ if (install.status !== 0) {
133
+ return failed("codex", install, `Run \`codex plugin add ${pluginId}\`, then retry.`);
134
+ }
135
+ return {
136
+ client: "codex",
137
+ status: alreadyInstalled ? "updated" : "installed",
138
+ message: "The Dataworks skill and query_metrics MCP server are enabled.",
139
+ nextStep: "Start a new Codex thread before asking a Dataworks metrics question.",
140
+ };
141
+ }
142
+ function installClaudeCode(options) {
143
+ const { run, packageRoot, force } = options;
144
+ const list = run("claude", ["plugin", "marketplace", "list", "--json"]);
145
+ if (list.status !== 0) {
146
+ return failed("claude-code", list, "Run `claude plugin marketplace list --json` to inspect the Claude Code plugin configuration, then retry.");
147
+ }
148
+ const marketplace = claudeMarketplace(parseJson(list.stdout));
149
+ const currentRoot = marketplace.root ? resolve(marketplace.root) : undefined;
150
+ if (marketplace.exists && currentRoot && currentRoot !== packageRoot && !force) {
151
+ return {
152
+ client: "claude-code",
153
+ status: "failed",
154
+ message: `The ${marketplaceName} marketplace already points to ${currentRoot}.`,
155
+ nextStep: "Run `dw agents install claude-code --force` to replace the stale marketplace registration.",
156
+ };
157
+ }
158
+ if (marketplace.exists && force) {
159
+ const remove = run("claude", ["plugin", "marketplace", "remove", marketplaceName]);
160
+ if (remove.status !== 0) {
161
+ return failed("claude-code", remove, "Run `claude plugin marketplace list --json` to inspect the conflicting registration.");
162
+ }
163
+ }
164
+ if (!marketplace.exists || force) {
165
+ const addMarketplace = run("claude", ["plugin", "marketplace", "add", packageRoot]);
166
+ if (addMarketplace.status !== 0) {
167
+ return failed("claude-code", addMarketplace, `Run \`claude plugin marketplace add ${packageRoot}\`, then retry.`);
168
+ }
169
+ }
170
+ const before = run("claude", ["plugin", "list", "--json"]);
171
+ const alreadyInstalled = before.status === 0 && pluginIsInstalled("claude-code", parseJson(before.stdout));
172
+ const action = alreadyInstalled ? "update" : "install";
173
+ const install = run("claude", ["plugin", action, pluginId, "--scope", "user"]);
174
+ if (install.status !== 0) {
175
+ return failed("claude-code", install, `Run \`claude plugin ${action} ${pluginId} --scope user\`, then retry.`);
176
+ }
177
+ return {
178
+ client: "claude-code",
179
+ status: alreadyInstalled ? "updated" : "installed",
180
+ message: "The Dataworks skill and query_metrics MCP server are enabled.",
181
+ nextStep: "Run `/reload-plugins` in Claude Code, or start a new session.",
182
+ };
183
+ }
184
+ export function installAgentIntegration(client, options = {}) {
185
+ const resolved = {
186
+ force: options.force ?? false,
187
+ packageRoot: resolve(options.packageRoot ?? dataworksPackageRoot()),
188
+ run: options.run ?? defaultRunner,
189
+ };
190
+ const binary = executable(client);
191
+ const detected = resolved.run(binary, ["--version"]);
192
+ if (detected.status !== 0 || detected.error)
193
+ return unavailable(client);
194
+ return client === "codex" ? installCodex(resolved) : installClaudeCode(resolved);
195
+ }
196
+ //# sourceMappingURL=agent-install.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-install.js","sourceRoot":"","sources":["../../src/lib/agent-install.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ export interface AgentReminderPreferences {
2
+ disabled: boolean;
3
+ configured: boolean;
4
+ lastShownAt?: string;
5
+ }
6
+ export interface AgentReminderContext {
7
+ argv: readonly string[];
8
+ isTTY: boolean;
9
+ now?: Date;
10
+ disabledByEnvironment?: boolean;
11
+ }
12
+ export declare function agentReminderPath(): string;
13
+ export declare function readAgentReminderPreferences(): Promise<AgentReminderPreferences>;
14
+ export declare function shouldShowAgentReminder(preferences: AgentReminderPreferences, context: AgentReminderContext): boolean;
15
+ export declare function maybeShowAgentReminder(argv: readonly string[]): Promise<void>;
16
+ export declare function configureAgentReminder(action: "disable" | "enable" | "configured"): Promise<AgentReminderPreferences>;
17
+ //# sourceMappingURL=agent-reminder.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-reminder.d.ts","sourceRoot":"","sources":["../../src/lib/agent-reminder.ts"],"names":[],"mappings":"AAMA,MAAM,WAAW,wBAAwB;IACvC,QAAQ,EAAE,OAAO,CAAC;IAClB,UAAU,EAAE,OAAO,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,SAAS,MAAM,EAAE,CAAC;IACxB,KAAK,EAAE,OAAO,CAAC;IACf,GAAG,CAAC,EAAE,IAAI,CAAC;IACX,qBAAqB,CAAC,EAAE,OAAO,CAAC;CACjC;AAOD,wBAAgB,iBAAiB,IAAI,MAAM,CAE1C;AAED,wBAAsB,4BAA4B,IAAI,OAAO,CAAC,wBAAwB,CAAC,CAetF;AAYD,wBAAgB,uBAAuB,CACrC,WAAW,EAAE,wBAAwB,EACrC,OAAO,EAAE,oBAAoB,GAC5B,OAAO,CAUT;AAED,wBAAsB,sBAAsB,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAwBnF;AAED,wBAAsB,sBAAsB,CAC1C,MAAM,EAAE,SAAS,GAAG,QAAQ,GAAG,YAAY,GAC1C,OAAO,CAAC,wBAAwB,CAAC,CAUnC"}
@@ -0,0 +1,81 @@
1
+ import { mkdir, readFile, writeFile } from "node:fs/promises";
2
+ import { dirname, join } from "node:path";
3
+ import { configPath } from "./config-store.js";
4
+ const reminderIntervalMs = 24 * 60 * 60 * 1000;
5
+ const defaultPreferences = {
6
+ disabled: false,
7
+ configured: false,
8
+ };
9
+ export function agentReminderPath() {
10
+ return join(dirname(configPath()), "agent-reminder.json");
11
+ }
12
+ export async function readAgentReminderPreferences() {
13
+ try {
14
+ const stored = JSON.parse(await readFile(agentReminderPath(), "utf8"));
15
+ return {
16
+ disabled: stored.disabled === true,
17
+ configured: stored.configured === true,
18
+ lastShownAt: typeof stored.lastShownAt === "string" ? stored.lastShownAt : undefined,
19
+ };
20
+ }
21
+ catch (error) {
22
+ if (error?.code === "ENOENT")
23
+ return { ...defaultPreferences };
24
+ throw error;
25
+ }
26
+ }
27
+ async function writeAgentReminderPreferences(preferences) {
28
+ const path = agentReminderPath();
29
+ await mkdir(dirname(path), { recursive: true, mode: 0o700 });
30
+ await writeFile(path, `${JSON.stringify(preferences, null, 2)}\n`, {
31
+ mode: 0o600,
32
+ });
33
+ }
34
+ export function shouldShowAgentReminder(preferences, context) {
35
+ if (!context.isTTY || context.disabledByEnvironment)
36
+ return false;
37
+ if (preferences.disabled || preferences.configured)
38
+ return false;
39
+ if (context.argv.includes("--json"))
40
+ return false;
41
+ if (context.argv[0] === "agents")
42
+ return false;
43
+ if (!preferences.lastShownAt)
44
+ return true;
45
+ const lastShown = Date.parse(preferences.lastShownAt);
46
+ if (!Number.isFinite(lastShown))
47
+ return true;
48
+ return (context.now ?? new Date()).getTime() - lastShown >= reminderIntervalMs;
49
+ }
50
+ export async function maybeShowAgentReminder(argv) {
51
+ try {
52
+ const preferences = await readAgentReminderPreferences();
53
+ if (!shouldShowAgentReminder(preferences, {
54
+ argv,
55
+ isTTY: process.stderr.isTTY === true,
56
+ disabledByEnvironment: process.env.DW_NO_AGENT_REMINDER === "1",
57
+ })) {
58
+ return;
59
+ }
60
+ process.stderr.write("Tip: enable Dataworks in Codex or Claude Code with `dw agents install`.\n" +
61
+ "Hide this reminder with `dw agents reminder disable`.\n");
62
+ await writeAgentReminderPreferences({
63
+ ...preferences,
64
+ lastShownAt: new Date().toISOString(),
65
+ });
66
+ }
67
+ catch {
68
+ // A reminder must never block or fail the requested CLI command.
69
+ }
70
+ }
71
+ export async function configureAgentReminder(action) {
72
+ const current = await readAgentReminderPreferences();
73
+ const preferences = action === "disable"
74
+ ? { ...current, disabled: true }
75
+ : action === "configured"
76
+ ? { ...current, configured: true }
77
+ : { disabled: false, configured: false };
78
+ await writeAgentReminderPreferences(preferences);
79
+ return preferences;
80
+ }
81
+ //# sourceMappingURL=agent-reminder.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-reminder.js","sourceRoot":"","sources":["../../src/lib/agent-reminder.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,7 @@
1
1
  import { Command } from "@oclif/core";
2
2
  import type { CommandError } from "@oclif/core/interfaces";
3
3
  export declare abstract class DataworksCommand extends Command {
4
+ protected init(): Promise<void>;
4
5
  protected catch(error: CommandError): Promise<void>;
5
6
  }
6
7
  //# sourceMappingURL=command.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"command.d.ts","sourceRoot":"","sources":["../../src/lib/command.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AACtC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAG3D,8BAAsB,gBAAiB,SAAQ,OAAO;cAC3B,KAAK,CAAC,KAAK,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC;CAiBnE"}
1
+ {"version":3,"file":"command.d.ts","sourceRoot":"","sources":["../../src/lib/command.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AACtC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAI3D,8BAAsB,gBAAiB,SAAQ,OAAO;cAC3B,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;cAKrB,KAAK,CAAC,KAAK,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC;CAiBnE"}
@@ -1,6 +1,11 @@
1
1
  import { Command } from "@oclif/core";
2
2
  import { toCliError } from "./errors.js";
3
+ import { maybeShowAgentReminder } from "./agent-reminder.js";
3
4
  export class DataworksCommand extends Command {
5
+ async init() {
6
+ await super.init();
7
+ await maybeShowAgentReminder(this.argv);
8
+ }
4
9
  async catch(error) {
5
10
  const cliError = toCliError(error);
6
11
  if (this.argv.includes("--json")) {
@@ -1 +1 @@
1
- {"version":3,"file":"command.js","sourceRoot":"","sources":["../../src/lib/command.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAEtC,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEzC,MAAM,OAAgB,gBAAiB,SAAQ,OAAO;IACjC,KAAK,CAAC,KAAK,CAAC,KAAmB;QAChD,MAAM,QAAQ,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC;QACnC,IAAI,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;YACjC,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,GAAG,IAAI,CAAC,SAAS,CAAC;gBAChB,KAAK,EAAE;oBACL,IAAI,EAAE,QAAQ,CAAC,IAAI;oBACnB,OAAO,EAAE,QAAQ,CAAC,OAAO;oBACzB,OAAO,EAAE,QAAQ,CAAC,OAAO;iBAC1B;aACF,CAAC,IAAI,CACP,CAAC;QACJ,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,UAAU,QAAQ,CAAC,IAAI,MAAM,QAAQ,CAAC,OAAO,IAAI,CAAC,CAAC;QAC1E,CAAC;QACD,OAAO,CAAC,QAAQ,GAAG,QAAQ,CAAC,QAAQ,CAAC;IACvC,CAAC;CACF"}
1
+ {"version":3,"file":"command.js","sourceRoot":"","sources":["../../src/lib/command.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAEtC,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AAE7D,MAAM,OAAgB,gBAAiB,SAAQ,OAAO;IACjC,KAAK,CAAC,IAAI;QAC3B,MAAM,KAAK,CAAC,IAAI,EAAE,CAAC;QACnB,MAAM,sBAAsB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC1C,CAAC;IAEkB,KAAK,CAAC,KAAK,CAAC,KAAmB;QAChD,MAAM,QAAQ,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC;QACnC,IAAI,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;YACjC,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,GAAG,IAAI,CAAC,SAAS,CAAC;gBAChB,KAAK,EAAE;oBACL,IAAI,EAAE,QAAQ,CAAC,IAAI;oBACnB,OAAO,EAAE,QAAQ,CAAC,OAAO;oBACzB,OAAO,EAAE,QAAQ,CAAC,OAAO;iBAC1B;aACF,CAAC,IAAI,CACP,CAAC;QACJ,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,UAAU,QAAQ,CAAC,IAAI,MAAM,QAAQ,CAAC,OAAO,IAAI,CAAC,CAAC;QAC1E,CAAC;QACD,OAAO,CAAC,QAAQ,GAAG,QAAQ,CAAC,QAAQ,CAAC;IACvC,CAAC;CACF"}
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Metric name resolution for the CLI and the MCP `query_metrics` tool.
3
+ *
4
+ * The canonical names and categories come from src/generated/metrics.ts, which is
5
+ * generated from @dataworks/sdk — edit the SDK, not this file, to add a metric.
6
+ * What lives here is the CLI-owned layer the SDK does not define: the everyday
7
+ * wordings a user or model is likely to type, and display units.
8
+ */
9
+ import { allMetricNames, metricCategories, metricLabels, type MetricCategory } from "../generated/metrics.js";
10
+ export { allMetricNames, metricCategories, metricLabels, type MetricCategory };
11
+ /** Normalize wording to a lookup key: "Heart Rate" and "heart-rate" both give "heartrate". */
12
+ export declare function compactMetricName(value: string): string;
13
+ export interface ResolvedMetricName {
14
+ canonical: string;
15
+ category: MetricCategory;
16
+ unit: string | null;
17
+ }
18
+ /** Resolve a canonical name or alias; undefined for an unknown or custom metric. */
19
+ export declare function resolveMetricName(requested: string): ResolvedMetricName | undefined;
20
+ /** Every accepted spelling, for docs and error details. */
21
+ export declare function metricAliases(): string[];
22
+ /**
23
+ * Canonical names closest to what was asked for, so an unknown metric can point at
24
+ * the real spelling instead of only being rejected.
25
+ */
26
+ export declare function suggestMetricNames(requested: string, limit?: number): string[];
27
+ /** Compact catalogue listing for tool descriptions and skill docs. */
28
+ export declare function metricCatalogSummary(): string;
29
+ //# sourceMappingURL=metric-names.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"metric-names.d.ts","sourceRoot":"","sources":["../../src/lib/metric-names.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EACL,cAAc,EACd,gBAAgB,EAEhB,YAAY,EACZ,KAAK,cAAc,EACpB,MAAM,yBAAyB,CAAC;AAEjC,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,YAAY,EAAE,KAAK,cAAc,EAAE,CAAC;AA+F/E,8FAA8F;AAC9F,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAKvD;AAOD,MAAM,WAAW,kBAAkB;IACjC,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,cAAc,CAAC;IACzB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;CACrB;AAED,oFAAoF;AACpF,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,MAAM,GAAG,kBAAkB,GAAG,SAAS,CAQnF;AAED,2DAA2D;AAC3D,wBAAgB,aAAa,IAAI,MAAM,EAAE,CAExC;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,SAAI,GAAG,MAAM,EAAE,CAyBzE;AASD,sEAAsE;AACtE,wBAAgB,oBAAoB,IAAI,MAAM,CAI7C"}
@@ -0,0 +1,171 @@
1
+ /**
2
+ * Metric name resolution for the CLI and the MCP `query_metrics` tool.
3
+ *
4
+ * The canonical names and categories come from src/generated/metrics.ts, which is
5
+ * generated from @dataworks/sdk — edit the SDK, not this file, to add a metric.
6
+ * What lives here is the CLI-owned layer the SDK does not define: the everyday
7
+ * wordings a user or model is likely to type, and display units.
8
+ */
9
+ import { allMetricNames, metricCategories, metricCategoryByName, metricLabels, } from "../generated/metrics.js";
10
+ export { allMetricNames, metricCategories, metricLabels };
11
+ /**
12
+ * Units for metrics whose scale the catalogue states explicitly, either in the
13
+ * SDK's category comments or its label text. Metrics whose unit upstream leaves
14
+ * unstated are omitted and report `null` rather than a guess.
15
+ */
16
+ const METRIC_UNITS = {
17
+ heartrate: "bpm",
18
+ "net-time": "s",
19
+ "checkpoint-time": "s",
20
+ "leg-time": "s",
21
+ "sub-time": "s",
22
+ "time-to-leader": "s",
23
+ "total-drafting-seconds": "s",
24
+ distance: "km",
25
+ "distance-swim": "km",
26
+ "distance-bike": "km",
27
+ "distance-run": "km",
28
+ speed: "km/h",
29
+ "speed-bike": "km/h",
30
+ pace: "sec/km",
31
+ "pace-swim": "sec/km",
32
+ "pace-run": "sec/km",
33
+ "heading-degrees": "degrees",
34
+ };
35
+ /**
36
+ * Everyday wordings that do not match a canonical name once punctuation and case
37
+ * are stripped. Canonical names register themselves, so "heart rate" already
38
+ * resolves to `heartrate` without an entry here.
39
+ */
40
+ const EXTRA_ALIASES = {
41
+ // GPS
42
+ gps: "latlong",
43
+ gpsposition: "latlong",
44
+ location: "latlong",
45
+ position: "latlong",
46
+ coordinates: "latlong",
47
+ coords: "latlong",
48
+ // Heart rate
49
+ hr: "heartrate",
50
+ bpm: "heartrate",
51
+ pulse: "heartrate",
52
+ heartbeat: "heartrate",
53
+ // Power
54
+ watts: "power",
55
+ pwr: "power",
56
+ cyclingpower: "power-cycling",
57
+ bikepower: "power-cycling",
58
+ instantpower: "pwr_instant",
59
+ // Cadence
60
+ rpm: "cadence",
61
+ cyclingcadence: "cadence-cycling",
62
+ bikecadence: "cadence-cycling",
63
+ // Speed and elevation
64
+ velocity: "speed",
65
+ bikespeed: "speed-bike",
66
+ elevation: "altitude",
67
+ height: "altitude",
68
+ // Timing
69
+ finishtime: "net-time",
70
+ totaltime: "net-time",
71
+ splittime: "sub-time",
72
+ // Distance
73
+ swimdistance: "distance-swim",
74
+ bikedistance: "distance-bike",
75
+ rundistance: "distance-run",
76
+ // Pace
77
+ swimpace: "pace-swim",
78
+ runpace: "pace-run",
79
+ // Misc
80
+ placing: "rank",
81
+ ranking: "rank",
82
+ drafting: "is-drafting",
83
+ energy: "active-energy-burned",
84
+ calories: "active-energy-burned",
85
+ };
86
+ /**
87
+ * Umbrella words that name a family of metrics rather than one, so they cannot be
88
+ * resolved but can still be answered with candidates. `timing` earns its place:
89
+ * the CLI used to accept it as a metric name that no catalogue entry ever matched.
90
+ */
91
+ const CONCEPT_SUGGESTIONS = {
92
+ timing: ["net-time", "checkpoint-time", "leg-time", "sub-time"],
93
+ time: ["net-time", "checkpoint-time", "leg-time", "sub-time"],
94
+ split: ["sub-time", "leg-time"],
95
+ splits: ["sub-time", "leg-time"],
96
+ duration: ["net-time", "leg-time"],
97
+ gap: ["gap-to-leader", "gap-to-ahead", "time-to-leader"],
98
+ zone: ["heartrate", "power"],
99
+ zones: ["heartrate", "power"],
100
+ };
101
+ /** Normalize wording to a lookup key: "Heart Rate" and "heart-rate" both give "heartrate". */
102
+ export function compactMetricName(value) {
103
+ return value
104
+ .trim()
105
+ .toLocaleLowerCase()
106
+ .replaceAll(/[^a-z0-9]/g, "");
107
+ }
108
+ const ALIASES = {
109
+ ...Object.fromEntries(allMetricNames.map((name) => [compactMetricName(name), name])),
110
+ ...EXTRA_ALIASES,
111
+ };
112
+ /** Resolve a canonical name or alias; undefined for an unknown or custom metric. */
113
+ export function resolveMetricName(requested) {
114
+ const canonical = ALIASES[compactMetricName(requested)];
115
+ if (!canonical)
116
+ return undefined;
117
+ const category = metricCategoryByName[canonical];
118
+ // Only reachable if an EXTRA_ALIASES entry outlives the metric it points at, in
119
+ // which case falling through to the unknown-metric path beats a bad query.
120
+ if (!category)
121
+ return undefined;
122
+ return { canonical, category, unit: METRIC_UNITS[canonical] ?? null };
123
+ }
124
+ /** Every accepted spelling, for docs and error details. */
125
+ export function metricAliases() {
126
+ return Object.keys(ALIASES).sort();
127
+ }
128
+ /**
129
+ * Canonical names closest to what was asked for, so an unknown metric can point at
130
+ * the real spelling instead of only being rejected.
131
+ */
132
+ export function suggestMetricNames(requested, limit = 5) {
133
+ const needle = compactMetricName(requested);
134
+ if (!needle)
135
+ return [];
136
+ const requestedTokens = new Set(requested
137
+ .toLocaleLowerCase()
138
+ .split(/[^a-z0-9]+/)
139
+ .filter((token) => token.length > 2));
140
+ const concepts = new Set([needle, ...requestedTokens].flatMap((token) => CONCEPT_SUGGESTIONS[token] ?? []));
141
+ const scored = allMetricNames
142
+ .map((name) => {
143
+ const haystack = compactMetricName(name);
144
+ let score = 0;
145
+ if (haystack.startsWith(needle) || needle.startsWith(haystack))
146
+ score = 3;
147
+ else if (haystack.includes(needle) || needle.includes(haystack))
148
+ score = 2;
149
+ else if (concepts.has(name))
150
+ score = 2;
151
+ else if (sharesToken(name, requestedTokens))
152
+ score = 1;
153
+ return { name, score };
154
+ })
155
+ .filter((entry) => entry.score > 0);
156
+ scored.sort((a, b) => b.score - a.score || a.name.localeCompare(b.name));
157
+ return scored.slice(0, limit).map((entry) => entry.name);
158
+ }
159
+ function sharesToken(metric, requestedTokens) {
160
+ return metric
161
+ .toLocaleLowerCase()
162
+ .split(/[^a-z0-9]+/)
163
+ .some((token) => token.length > 2 && requestedTokens.has(token));
164
+ }
165
+ /** Compact catalogue listing for tool descriptions and skill docs. */
166
+ export function metricCatalogSummary() {
167
+ return Object.keys(metricCategories)
168
+ .map((category) => `${category}: ${metricCategories[category].join(", ")}`)
169
+ .join(". ");
170
+ }
171
+ //# sourceMappingURL=metric-names.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"metric-names.js","sourceRoot":"","sources":["../../src/lib/metric-names.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,73 @@
1
+ import { executeGraphql } from "./graphql-transport.js";
2
+ import { type MetricCategory } from "./metric-names.js";
3
+ import { requireSession } from "./session.js";
4
+ export type { MetricCategory };
5
+ export interface QueryMetricsInput {
6
+ athleteId?: string;
7
+ athleteName?: string;
8
+ metric: string;
9
+ metricCategory?: MetricCategory;
10
+ limit?: number;
11
+ order?: "newest" | "oldest";
12
+ from?: string;
13
+ to?: string;
14
+ eventId?: string;
15
+ datasetDatasourceId?: string;
16
+ tenantId?: string;
17
+ timeoutMs?: number;
18
+ }
19
+ export interface MetricPosition {
20
+ latitude: number;
21
+ longitude: number;
22
+ }
23
+ export interface MetricRow {
24
+ timestamp: string | number | null;
25
+ timestampIso: string | null;
26
+ athleteId: string | null;
27
+ metric: string | null;
28
+ value: unknown;
29
+ unit: string | null;
30
+ position: MetricPosition | null;
31
+ eventId: string | null;
32
+ datasetDatasourceId: string | null;
33
+ }
34
+ export interface QueryMetricsOutput {
35
+ environment: "uat" | "live";
36
+ tenantId: string;
37
+ athlete: {
38
+ publicId: string;
39
+ name: string | null;
40
+ matchedBy: "public_id" | "name" | "partial_name";
41
+ };
42
+ metric: {
43
+ requested: string;
44
+ canonical: string;
45
+ category: MetricCategory;
46
+ unit: string | null;
47
+ };
48
+ filters: {
49
+ eventId: string | null;
50
+ datasetDatasourceId: string | null;
51
+ from: string | null;
52
+ to: string | null;
53
+ };
54
+ order: "newest" | "oldest";
55
+ limit: number;
56
+ count: number;
57
+ rowCount: number;
58
+ status: string;
59
+ queryExecutionId: string | null;
60
+ queryTimeMs: number | null;
61
+ rows: MetricRow[];
62
+ }
63
+ export interface QueryMetricsDependencies {
64
+ graphql: typeof executeGraphql;
65
+ session: typeof requireSession;
66
+ sleep: (milliseconds: number, signal?: AbortSignal) => Promise<void>;
67
+ now: () => number;
68
+ }
69
+ export declare function queryMetrics(input: QueryMetricsInput, options?: {
70
+ dependencies?: Partial<QueryMetricsDependencies>;
71
+ signal?: AbortSignal;
72
+ }): Promise<QueryMetricsOutput>;
73
+ //# sourceMappingURL=query-metrics.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"query-metrics.d.ts","sourceRoot":"","sources":["../../src/lib/query-metrics.ts"],"names":[],"mappings":"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"}