@lightward/mechanic-cli 0.1.9 → 0.1.10

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 (39) hide show
  1. package/README.md +14 -0
  2. package/dist/client.d.ts +2 -1
  3. package/dist/client.d.ts.map +1 -1
  4. package/dist/client.js +4 -0
  5. package/dist/commands/globals/delete.d.ts +13 -0
  6. package/dist/commands/globals/delete.d.ts.map +1 -0
  7. package/dist/commands/globals/delete.js +28 -0
  8. package/dist/commands/globals/list.d.ts +10 -0
  9. package/dist/commands/globals/list.d.ts.map +1 -0
  10. package/dist/commands/globals/list.js +39 -0
  11. package/dist/commands/globals/pull.d.ts +11 -0
  12. package/dist/commands/globals/pull.d.ts.map +1 -0
  13. package/dist/commands/globals/pull.js +42 -0
  14. package/dist/commands/globals/push.d.ts +11 -0
  15. package/dist/commands/globals/push.d.ts.map +1 -0
  16. package/dist/commands/globals/push.js +57 -0
  17. package/dist/commands/globals/set.d.ts +13 -0
  18. package/dist/commands/globals/set.d.ts.map +1 -0
  19. package/dist/commands/globals/set.js +26 -0
  20. package/dist/commands/secrets/delete.d.ts +13 -0
  21. package/dist/commands/secrets/delete.d.ts.map +1 -0
  22. package/dist/commands/secrets/delete.js +28 -0
  23. package/dist/commands/secrets/list.d.ts +10 -0
  24. package/dist/commands/secrets/list.d.ts.map +1 -0
  25. package/dist/commands/secrets/list.js +37 -0
  26. package/dist/commands/secrets/set.d.ts +25 -0
  27. package/dist/commands/secrets/set.d.ts.map +1 -0
  28. package/dist/commands/secrets/set.js +91 -0
  29. package/dist/commands/shop/deprecations.d.ts +20 -0
  30. package/dist/commands/shop/deprecations.d.ts.map +1 -0
  31. package/dist/commands/shop/deprecations.js +95 -0
  32. package/dist/commands/tasks/list.d.ts.map +1 -1
  33. package/dist/commands/tasks/list.js +12 -1
  34. package/dist/config-keys.d.ts +2 -0
  35. package/dist/config-keys.d.ts.map +1 -0
  36. package/dist/config-keys.js +8 -0
  37. package/dist/types.d.ts +23 -0
  38. package/dist/types.d.ts.map +1 -1
  39. package/package.json +2 -2
package/README.md CHANGED
@@ -126,6 +126,7 @@ mechanic auth login [--token <token>]
126
126
  mechanic auth logout
127
127
  mechanic github init [--force]
128
128
  mechanic shop status [--json]
129
+ mechanic shop deprecations [task] [--json]
129
130
  mechanic tasks list [--verbose] [--json]
130
131
  mechanic tasks new <name> [--force] [--json]
131
132
  mechanic tasks open <task>
@@ -191,6 +192,19 @@ unless you pass `--force`. It does not create anything in Mechanic until you run
191
192
  running runs, waiting runs, queue lag, and the largest backlog groups by task,
192
193
  action, and event topic.
193
194
 
195
+ `shop deprecations` shows unresolved Shopify API deprecations reported by tasks
196
+ in the configured shop. Pass a task slug, task file, helper directory, or linked
197
+ remote task ID to focus on one task:
198
+
199
+ ```bash
200
+ mechanic shop deprecations
201
+ mechanic shop deprecations order-tagger
202
+ ```
203
+
204
+ The output includes the task's configured Shopify API version and the Shopify API
205
+ version seen in the deprecated request. Use `--json` for monitoring scripts,
206
+ agents, or dashboards.
207
+
194
208
  `tasks status` shows whether local task JSON files are linked, ready to publish,
195
209
  and in sync with their remote Mechanic tasks. Use `--local` when you only want
196
210
  the fast offline check for JSON validity, link state, and helper-folder drift.
package/dist/client.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import type { JsonObject, ShopStatusResponse, TaskEnvelope, TaskListResponse, TaskPreviewResponse } from "./types.js";
1
+ import type { JsonObject, ShopDeprecationsResponse, ShopStatusResponse, TaskEnvelope, TaskListResponse, TaskPreviewResponse } from "./types.js";
2
2
  export declare const USER_AGENT: string;
3
3
  type RequestOptions = {
4
4
  method?: string;
@@ -27,6 +27,7 @@ export declare class MechanicClient {
27
27
  request<T>(pathname: string, options?: RequestOptions): Promise<T>;
28
28
  verifyAuth(): Promise<AuthVerification>;
29
29
  getShopStatus(): Promise<ShopStatusResponse>;
30
+ getShopDeprecations(taskId?: string): Promise<ShopDeprecationsResponse>;
30
31
  listTasks(): Promise<TaskListResponse>;
31
32
  getTask(id: string): Promise<TaskEnvelope>;
32
33
  previewTask(task: JsonObject, id?: string): Promise<TaskPreviewResponse>;
@@ -1 +1 @@
1
- {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,UAAU,EAAE,kBAAkB,EAAE,YAAY,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAKtH,eAAO,MAAM,UAAU,QAAkD,CAAC;AAE1E,KAAK,cAAc,GAAG;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAC7B,IAAI,CAAC,EAAE;QACL,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;KAChC,GAAG,IAAI,CAAC;IACT,SAAS,CAAC,EAAE;QACV,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QACrB,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;KAC5B,CAAC;CACH,CAAC;AAwGF,qBAAa,cAAc;IACzB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,kBAAkB,CAAC,EAAE,MAAM,CAAC;IACrC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;gBAEX,EAAE,OAAO,EAAE,kBAAkB,EAAE,KAAK,EAAE,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,kBAAkB,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE;IAM7G,OAAO,CAAC,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,GAAE,cAAmB,GAAG,OAAO,CAAC,CAAC,CAAC;IAgD5E,UAAU,IAAI,OAAO,CAAC,gBAAgB,CAAC;IAIvC,aAAa,IAAI,OAAO,CAAC,kBAAkB,CAAC;IAI5C,SAAS,IAAI,OAAO,CAAC,gBAAgB,CAAC;IAItC,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC;IAI1C,WAAW,CAAC,IAAI,EAAE,UAAU,EAAE,EAAE,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,mBAAmB,CAAC;IASxE,iBAAiB,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,mBAAmB,CAAC;IAM3D,UAAU,CAAC,IAAI,EAAE,UAAU,EAAE,cAAc,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC;IAQ5E,UAAU,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE;QAAE,IAAI,EAAE,UAAU,CAAC;QAAC,qBAAqB,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,OAAO,CAAC,YAAY,CAAC;CAM3H"}
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACV,UAAU,EACV,wBAAwB,EACxB,kBAAkB,EAClB,YAAY,EACZ,gBAAgB,EAChB,mBAAmB,EACpB,MAAM,YAAY,CAAC;AAKpB,eAAO,MAAM,UAAU,QAAkD,CAAC;AAE1E,KAAK,cAAc,GAAG;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAC7B,IAAI,CAAC,EAAE;QACL,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;KAChC,GAAG,IAAI,CAAC;IACT,SAAS,CAAC,EAAE;QACV,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QACrB,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;KAC5B,CAAC;CACH,CAAC;AAwGF,qBAAa,cAAc;IACzB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,kBAAkB,CAAC,EAAE,MAAM,CAAC;IACrC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;gBAEX,EAAE,OAAO,EAAE,kBAAkB,EAAE,KAAK,EAAE,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,kBAAkB,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE;IAM7G,OAAO,CAAC,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,GAAE,cAAmB,GAAG,OAAO,CAAC,CAAC,CAAC;IAgD5E,UAAU,IAAI,OAAO,CAAC,gBAAgB,CAAC;IAIvC,aAAa,IAAI,OAAO,CAAC,kBAAkB,CAAC;IAI5C,mBAAmB,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,wBAAwB,CAAC;IAMvE,SAAS,IAAI,OAAO,CAAC,gBAAgB,CAAC;IAItC,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC;IAI1C,WAAW,CAAC,IAAI,EAAE,UAAU,EAAE,EAAE,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,mBAAmB,CAAC;IASxE,iBAAiB,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,mBAAmB,CAAC;IAM3D,UAAU,CAAC,IAAI,EAAE,UAAU,EAAE,cAAc,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC;IAQ5E,UAAU,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE;QAAE,IAAI,EAAE,UAAU,CAAC;QAAC,qBAAqB,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,OAAO,CAAC,YAAY,CAAC;CAM3H"}
package/dist/client.js CHANGED
@@ -141,6 +141,10 @@ export class MechanicClient {
141
141
  getShopStatus() {
142
142
  return this.request("/v1/shop/status");
143
143
  }
144
+ getShopDeprecations(taskId) {
145
+ const search = taskId ? `?${new URLSearchParams({ task_id: taskId }).toString()}` : "";
146
+ return this.request(`/v1/shop/deprecations${search}`);
147
+ }
144
148
  listTasks() {
145
149
  return this.request("/v1/tasks");
146
150
  }
@@ -0,0 +1,13 @@
1
+ import { BaseCommand } from "../../base-command.js";
2
+ export default class GlobalsDelete extends BaseCommand {
3
+ static summary: string;
4
+ static description: string;
5
+ static args: {
6
+ key: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
7
+ };
8
+ static flags: {
9
+ force: import("@oclif/core/interfaces").BooleanFlag<boolean>;
10
+ };
11
+ run(): Promise<void>;
12
+ }
13
+ //# sourceMappingURL=delete.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"delete.d.ts","sourceRoot":"","sources":["../../../src/commands/globals/delete.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAIpD,MAAM,CAAC,OAAO,OAAO,aAAc,SAAQ,WAAW;IACpD,OAAgB,OAAO,SAA6B;IACpD,OAAgB,WAAW,SAA2C;IAEtE,OAAgB,IAAI;;MAElB;IAEF,OAAgB,KAAK;;MAKnB;IAEI,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;CAc3B"}
@@ -0,0 +1,28 @@
1
+ import { Args, Flags } from "@oclif/core";
2
+ import { BaseCommand } from "../../base-command.js";
3
+ import { validateConfigKey } from "../../config-keys.js";
4
+ import { CliError } from "../../errors.js";
5
+ export default class GlobalsDelete extends BaseCommand {
6
+ static summary = "Delete one shop global.";
7
+ static description = "Delete one visible shop-level global.";
8
+ static args = {
9
+ key: Args.string({ required: true, description: "Global key, using lower snake-case." }),
10
+ };
11
+ static flags = {
12
+ force: Flags.boolean({
13
+ char: "f",
14
+ description: "Delete without an interactive confirmation.",
15
+ }),
16
+ };
17
+ async run() {
18
+ const { args, flags } = await this.parse(GlobalsDelete);
19
+ const key = validateConfigKey(args.key);
20
+ if (!flags.force) {
21
+ throw new CliError(`Deleting global ${key} cannot be undone. Re-run with --force to confirm.`, 2);
22
+ }
23
+ const project = await this.loadProject();
24
+ const client = await this.verifiedClientForProject(project);
25
+ await client.deleteGlobal(key);
26
+ this.log(`${this.success("Deleted")} global ${this.taskName(key)}`);
27
+ }
28
+ }
@@ -0,0 +1,10 @@
1
+ import { BaseCommand } from "../../base-command.js";
2
+ export default class GlobalsList extends BaseCommand {
3
+ static summary: string;
4
+ static description: string;
5
+ static flags: {
6
+ json: import("@oclif/core/interfaces").BooleanFlag<boolean>;
7
+ };
8
+ run(): Promise<void>;
9
+ }
10
+ //# sourceMappingURL=list.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list.d.ts","sourceRoot":"","sources":["../../../src/commands/globals/list.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAUpD,MAAM,CAAC,OAAO,OAAO,WAAY,SAAQ,WAAW;IAClD,OAAgB,OAAO,SAAwB;IAC/C,OAAgB,WAAW,SAAqE;IAEhG,OAAgB,KAAK;;MAInB;IAEI,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;CAwB3B"}
@@ -0,0 +1,39 @@
1
+ import { Flags } from "@oclif/core";
2
+ import { BaseCommand } from "../../base-command.js";
3
+ function formatValue(value) {
4
+ if (value === undefined) {
5
+ return "";
6
+ }
7
+ return JSON.stringify(value);
8
+ }
9
+ export default class GlobalsList extends BaseCommand {
10
+ static summary = "List shop globals.";
11
+ static description = "List visible shop-level JSON globals for this Mechanic project.";
12
+ static flags = {
13
+ json: Flags.boolean({
14
+ description: "Print globals as JSON for agents, scripts, or editor integrations.",
15
+ }),
16
+ };
17
+ async run() {
18
+ const { flags } = await this.parse(GlobalsList);
19
+ const project = await this.loadProject();
20
+ const client = await this.verifiedClientForProject(project);
21
+ const response = await client.listGlobals();
22
+ const globals = response.globals || [];
23
+ if (flags.json) {
24
+ this.outputJson({
25
+ shop_domain: project.shopDomain,
26
+ globals,
27
+ });
28
+ return;
29
+ }
30
+ this.table([
31
+ ["Key", "Value", "Updated"],
32
+ ...globals.map((global) => [
33
+ this.taskName(global.key),
34
+ formatValue(global.value),
35
+ this.muted(global.updated_at || ""),
36
+ ]),
37
+ ]);
38
+ }
39
+ }
@@ -0,0 +1,11 @@
1
+ import { BaseCommand } from "../../base-command.js";
2
+ export default class GlobalsPull extends BaseCommand {
3
+ static summary: string;
4
+ static description: string;
5
+ static flags: {
6
+ out: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
7
+ force: import("@oclif/core/interfaces").BooleanFlag<boolean>;
8
+ };
9
+ run(): Promise<void>;
10
+ }
11
+ //# sourceMappingURL=pull.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pull.d.ts","sourceRoot":"","sources":["../../../src/commands/globals/pull.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAOpD,MAAM,CAAC,OAAO,OAAO,WAAY,SAAQ,WAAW;IAClD,OAAgB,OAAO,SAAmD;IAC1E,OAAgB,WAAW,SAAiE;IAE5F,OAAgB,KAAK;;;MAQnB;IAEI,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;CA0B3B"}
@@ -0,0 +1,42 @@
1
+ import { Flags } from "@oclif/core";
2
+ import path from "node:path";
3
+ import { BaseCommand } from "../../base-command.js";
4
+ import { CliError } from "../../errors.js";
5
+ import { pathExists, readText, writeText } from "../../fs.js";
6
+ import { stableStringify } from "../../json.js";
7
+ const DEFAULT_GLOBALS_FILE = "mechanic.globals.json";
8
+ export default class GlobalsPull extends BaseCommand {
9
+ static summary = "Pull shop globals into mechanic.globals.json.";
10
+ static description = "Pull visible shop-level globals into a repo-safe JSON file.";
11
+ static flags = {
12
+ out: Flags.string({
13
+ description: "File path to write.",
14
+ default: DEFAULT_GLOBALS_FILE,
15
+ }),
16
+ force: Flags.boolean({
17
+ description: "Overwrite an existing globals file when its contents differ.",
18
+ }),
19
+ };
20
+ async run() {
21
+ const { flags } = await this.parse(GlobalsPull);
22
+ const project = await this.loadProject();
23
+ const client = await this.verifiedClientForProject(project);
24
+ const response = await client.listGlobals();
25
+ const globals = Object.fromEntries((response.globals || []).map((global) => [global.key, global.value]));
26
+ const file = path.resolve(project.cwd, flags.out);
27
+ const relativeFile = path.relative(project.cwd, file) || file;
28
+ const contents = `${stableStringify(globals)}\n`;
29
+ if (await pathExists(file)) {
30
+ const existingContents = await readText(file);
31
+ if (existingContents === contents) {
32
+ this.log(`${this.success("Unchanged")} ${this.taskName(relativeFile)}`);
33
+ return;
34
+ }
35
+ if (!flags.force) {
36
+ throw new CliError(`${relativeFile} already exists and differs. Re-run with --force to overwrite.`, 2);
37
+ }
38
+ }
39
+ await writeText(file, contents);
40
+ this.log(`${this.success("Wrote")} ${this.taskName(relativeFile)}`);
41
+ }
42
+ }
@@ -0,0 +1,11 @@
1
+ import { BaseCommand } from "../../base-command.js";
2
+ export default class GlobalsPush extends BaseCommand {
3
+ static summary: string;
4
+ static description: string;
5
+ static flags: {
6
+ file: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
7
+ "dry-run": import("@oclif/core/interfaces").BooleanFlag<boolean>;
8
+ };
9
+ run(): Promise<void>;
10
+ }
11
+ //# sourceMappingURL=push.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"push.d.ts","sourceRoot":"","sources":["../../../src/commands/globals/push.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAgBpD,MAAM,CAAC,OAAO,OAAO,WAAY,SAAQ,WAAW;IAClD,OAAgB,OAAO,SAA8C;IACrE,OAAgB,WAAW,SAAmI;IAE9J,OAAgB,KAAK;;;MAQnB;IAEI,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;CAuC3B"}
@@ -0,0 +1,57 @@
1
+ import { Flags } from "@oclif/core";
2
+ import path from "node:path";
3
+ import { BaseCommand } from "../../base-command.js";
4
+ import { validateConfigKey } from "../../config-keys.js";
5
+ import { CliError } from "../../errors.js";
6
+ import { readJson } from "../../fs.js";
7
+ import { stableStringify } from "../../json.js";
8
+ const DEFAULT_GLOBALS_FILE = "mechanic.globals.json";
9
+ function ensurePlainObject(value, source) {
10
+ if (!value || typeof value !== "object" || Array.isArray(value) || Object.getPrototypeOf(value) !== Object.prototype) {
11
+ throw new CliError(`${source} must contain a JSON object mapping global keys to values.`, 2);
12
+ }
13
+ return value;
14
+ }
15
+ export default class GlobalsPush extends BaseCommand {
16
+ static summary = "Push mechanic.globals.json to this shop.";
17
+ static description = "Push visible shop-level globals from a repo-safe JSON file. This updates listed keys and does not delete missing remote keys.";
18
+ static flags = {
19
+ file: Flags.string({
20
+ description: "Globals JSON file to read.",
21
+ default: DEFAULT_GLOBALS_FILE,
22
+ }),
23
+ "dry-run": Flags.boolean({
24
+ description: "Show what would be pushed without writing to Mechanic.",
25
+ }),
26
+ };
27
+ async run() {
28
+ const { flags } = await this.parse(GlobalsPush);
29
+ const project = await this.loadProject();
30
+ const client = await this.verifiedClientForProject(project);
31
+ const file = path.resolve(project.cwd, flags.file);
32
+ const entries = Object.entries(ensurePlainObject(await readJson(file), path.relative(project.cwd, file) || file));
33
+ const rows = [["Key", "Action"]];
34
+ for (const [key] of entries) {
35
+ validateConfigKey(key);
36
+ }
37
+ if (flags["dry-run"]) {
38
+ const remoteGlobals = Object.fromEntries((await client.listGlobals()).globals?.map((global) => [global.key, global.value]) || []);
39
+ for (const [key, value] of entries) {
40
+ const remoteValue = remoteGlobals[key];
41
+ const action = remoteValue === undefined
42
+ ? "would create"
43
+ : stableStringify(remoteValue) === stableStringify(value)
44
+ ? "unchanged"
45
+ : "would update";
46
+ rows.push([this.taskName(key), this.actionLabel(action)]);
47
+ }
48
+ this.table(rows);
49
+ return;
50
+ }
51
+ for (const [key, value] of entries) {
52
+ await client.setGlobal(key, value);
53
+ rows.push([this.taskName(key), this.actionLabel("updated")]);
54
+ }
55
+ this.table(rows);
56
+ }
57
+ }
@@ -0,0 +1,13 @@
1
+ import { BaseCommand } from "../../base-command.js";
2
+ export default class GlobalsSet extends BaseCommand {
3
+ static summary: string;
4
+ static description: string;
5
+ static args: {
6
+ key: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
7
+ };
8
+ static flags: {
9
+ json: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
10
+ };
11
+ run(): Promise<void>;
12
+ }
13
+ //# sourceMappingURL=set.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"set.d.ts","sourceRoot":"","sources":["../../../src/commands/globals/set.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAIpD,MAAM,CAAC,OAAO,OAAO,UAAW,SAAQ,WAAW;IACjD,OAAgB,OAAO,SAA0B;IACjD,OAAgB,WAAW,SAA6C;IAExE,OAAgB,IAAI;;MAElB;IAEF,OAAgB,KAAK;;MAKnB;IAEI,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;CAU3B"}
@@ -0,0 +1,26 @@
1
+ import { Args, Flags } from "@oclif/core";
2
+ import { BaseCommand } from "../../base-command.js";
3
+ import { validateConfigKey } from "../../config-keys.js";
4
+ import { parseJson } from "../../json.js";
5
+ export default class GlobalsSet extends BaseCommand {
6
+ static summary = "Set one shop global.";
7
+ static description = "Set one visible shop-level JSON global.";
8
+ static args = {
9
+ key: Args.string({ required: true, description: "Global key, using lower snake-case." }),
10
+ };
11
+ static flags = {
12
+ json: Flags.string({
13
+ required: true,
14
+ description: "JSON value to store.",
15
+ }),
16
+ };
17
+ async run() {
18
+ const { args, flags } = await this.parse(GlobalsSet);
19
+ const key = validateConfigKey(args.key);
20
+ const value = parseJson(flags.json, "--json");
21
+ const project = await this.loadProject();
22
+ const client = await this.verifiedClientForProject(project);
23
+ await client.setGlobal(key, value);
24
+ this.log(`${this.success("Set")} global ${this.taskName(key)}`);
25
+ }
26
+ }
@@ -0,0 +1,13 @@
1
+ import { BaseCommand } from "../../base-command.js";
2
+ export default class SecretsDelete extends BaseCommand {
3
+ static summary: string;
4
+ static description: string;
5
+ static args: {
6
+ key: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
7
+ };
8
+ static flags: {
9
+ force: import("@oclif/core/interfaces").BooleanFlag<boolean>;
10
+ };
11
+ run(): Promise<void>;
12
+ }
13
+ //# sourceMappingURL=delete.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"delete.d.ts","sourceRoot":"","sources":["../../../src/commands/secrets/delete.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAIpD,MAAM,CAAC,OAAO,OAAO,aAAc,SAAQ,WAAW;IACpD,OAAgB,OAAO,SAA6B;IACpD,OAAgB,WAAW,SAAqF;IAEhH,OAAgB,IAAI;;MAElB;IAEF,OAAgB,KAAK;;MAKnB;IAEI,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;CAc3B"}
@@ -0,0 +1,28 @@
1
+ import { Args, Flags } from "@oclif/core";
2
+ import { BaseCommand } from "../../base-command.js";
3
+ import { validateConfigKey } from "../../config-keys.js";
4
+ import { CliError } from "../../errors.js";
5
+ export default class SecretsDelete extends BaseCommand {
6
+ static summary = "Delete one shop secret.";
7
+ static description = "Delete one write-only shop-level secret. Affected tasks may fail until updated.";
8
+ static args = {
9
+ key: Args.string({ required: true, description: "Secret key, using lower snake-case." }),
10
+ };
11
+ static flags = {
12
+ force: Flags.boolean({
13
+ char: "f",
14
+ description: "Delete without an interactive confirmation.",
15
+ }),
16
+ };
17
+ async run() {
18
+ const { args, flags } = await this.parse(SecretsDelete);
19
+ const key = validateConfigKey(args.key);
20
+ if (!flags.force) {
21
+ throw new CliError(`Deleting secret ${key} can break tasks until updated. Re-run with --force to confirm.`, 2);
22
+ }
23
+ const project = await this.loadProject();
24
+ const client = await this.verifiedClientForProject(project);
25
+ await client.deleteSecret(key);
26
+ this.log(`${this.success("Deleted")} secret ${this.taskName(key)}`);
27
+ }
28
+ }
@@ -0,0 +1,10 @@
1
+ import { BaseCommand } from "../../base-command.js";
2
+ export default class SecretsList extends BaseCommand {
3
+ static summary: string;
4
+ static description: string;
5
+ static flags: {
6
+ json: import("@oclif/core/interfaces").BooleanFlag<boolean>;
7
+ };
8
+ run(): Promise<void>;
9
+ }
10
+ //# sourceMappingURL=list.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list.d.ts","sourceRoot":"","sources":["../../../src/commands/secrets/list.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAMpD,MAAM,CAAC,OAAO,OAAO,WAAY,SAAQ,WAAW;IAClD,OAAgB,OAAO,SAAwB;IAC/C,OAAgB,WAAW,SAAmF;IAE9G,OAAgB,KAAK;;MAInB;IAEI,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;CAyB3B"}
@@ -0,0 +1,37 @@
1
+ import { Flags } from "@oclif/core";
2
+ import { BaseCommand } from "../../base-command.js";
3
+ function formatCount(value) {
4
+ return typeof value === "number" ? value.toLocaleString() : "0";
5
+ }
6
+ export default class SecretsList extends BaseCommand {
7
+ static summary = "List shop secrets.";
8
+ static description = "List write-only shop-level secret metadata. Secret values are never returned.";
9
+ static flags = {
10
+ json: Flags.boolean({
11
+ description: "Print secret metadata as JSON for agents, scripts, or editor integrations.",
12
+ }),
13
+ };
14
+ async run() {
15
+ const { flags } = await this.parse(SecretsList);
16
+ const project = await this.loadProject();
17
+ const client = await this.verifiedClientForProject(project);
18
+ const response = await client.listSecrets();
19
+ const secrets = response.secrets || [];
20
+ if (flags.json) {
21
+ this.outputJson({
22
+ shop_domain: project.shopDomain,
23
+ secrets,
24
+ });
25
+ return;
26
+ }
27
+ this.table([
28
+ ["Key", "Value", "Task refs", "Updated"],
29
+ ...secrets.map((secret) => [
30
+ this.taskName(secret.key),
31
+ secret.value_present ? this.success("set") : this.muted("missing"),
32
+ formatCount(secret.task_reference_count),
33
+ this.muted(secret.updated_at || ""),
34
+ ]),
35
+ ]);
36
+ }
37
+ }
@@ -0,0 +1,25 @@
1
+ import { stdin } from "node:process";
2
+ import { BaseCommand } from "../../base-command.js";
3
+ type SecretStdin = typeof stdin;
4
+ export declare function readStdin(input?: SecretStdin): Promise<string>;
5
+ export declare function readSecretValueFromStdin(input?: SecretStdin): Promise<string>;
6
+ export declare function readSecretValueFromEnv(envName: string, env?: NodeJS.ProcessEnv): string;
7
+ export default class SecretsSet extends BaseCommand {
8
+ static summary: string;
9
+ static description: string;
10
+ static args: {
11
+ key: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
12
+ };
13
+ static flags: {
14
+ "from-stdin": import("@oclif/core/interfaces").BooleanFlag<boolean>;
15
+ force: import("@oclif/core/interfaces").BooleanFlag<boolean>;
16
+ "value-env": import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
17
+ };
18
+ run(): Promise<void>;
19
+ secretValue(flags: {
20
+ "from-stdin"?: boolean;
21
+ "value-env"?: string;
22
+ }): Promise<string>;
23
+ }
24
+ export {};
25
+ //# sourceMappingURL=set.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"set.d.ts","sourceRoot":"","sources":["../../../src/commands/secrets/set.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,EAAE,MAAM,cAAc,CAAC;AAErC,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAIpD,KAAK,WAAW,GAAG,OAAO,KAAK,CAAC;AAEhC,wBAAgB,SAAS,CAAC,KAAK,GAAE,WAAmB,GAAG,OAAO,CAAC,MAAM,CAAC,CAmBrE;AAED,wBAAsB,wBAAwB,CAC5C,KAAK,GAAE,WAAmB,GACzB,OAAO,CAAC,MAAM,CAAC,CAQjB;AAED,wBAAgB,sBAAsB,CACpC,OAAO,EAAE,MAAM,EACf,GAAG,GAAE,MAAM,CAAC,UAAwB,GACnC,MAAM,CAYR;AAED,MAAM,CAAC,OAAO,OAAO,UAAW,SAAQ,WAAW;IACjD,OAAgB,OAAO,SAA0B;IACjD,OAAgB,WAAW,SAAwE;IAEnG,OAAgB,IAAI;;MAElB;IAEF,OAAgB,KAAK;;;;MAanB;IAEI,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;IAiBpB,WAAW,CAAC,KAAK,EAAE;QAAE,YAAY,CAAC,EAAE,OAAO,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,MAAM,CAAC;CAsB5F"}
@@ -0,0 +1,91 @@
1
+ import { Args, Flags } from "@oclif/core";
2
+ import { stdin } from "node:process";
3
+ import { promptForHiddenValue } from "../../auth.js";
4
+ import { BaseCommand } from "../../base-command.js";
5
+ import { validateConfigKey } from "../../config-keys.js";
6
+ import { CliError } from "../../errors.js";
7
+ export function readStdin(input = stdin) {
8
+ if (input.isTTY) {
9
+ throw new CliError("Cannot read secret value from stdin while stdin is a TTY. Pipe a value or use --value-env.", 2);
10
+ }
11
+ return new Promise((resolve, reject) => {
12
+ let value = "";
13
+ input.setEncoding("utf8");
14
+ input.on("data", (chunk) => {
15
+ value += chunk;
16
+ });
17
+ input.on("end", () => {
18
+ resolve(value);
19
+ });
20
+ input.on("error", reject);
21
+ });
22
+ }
23
+ export async function readSecretValueFromStdin(input = stdin) {
24
+ const value = await readStdin(input);
25
+ if (value.length === 0) {
26
+ throw new CliError("Secret value cannot be blank.", 2);
27
+ }
28
+ return value;
29
+ }
30
+ export function readSecretValueFromEnv(envName, env = process.env) {
31
+ const value = env[envName];
32
+ if (value === undefined) {
33
+ throw new CliError(`Environment variable ${envName} is not set.`, 2);
34
+ }
35
+ if (value.length === 0) {
36
+ throw new CliError(`Environment variable ${envName} is empty.`, 2);
37
+ }
38
+ return value;
39
+ }
40
+ export default class SecretsSet extends BaseCommand {
41
+ static summary = "Set one shop secret.";
42
+ static description = "Set one write-only shop secret. The secret value is never printed.";
43
+ static args = {
44
+ key: Args.string({ required: true, description: "Secret key, using lower snake-case." }),
45
+ };
46
+ static flags = {
47
+ "from-stdin": Flags.boolean({
48
+ description: "Read the secret value from stdin.",
49
+ exclusive: ["value-env"],
50
+ }),
51
+ force: Flags.boolean({
52
+ char: "f",
53
+ description: "Replace the value when this secret key already exists.",
54
+ }),
55
+ "value-env": Flags.string({
56
+ description: "Read the secret value from the named environment variable.",
57
+ exclusive: ["from-stdin"],
58
+ }),
59
+ };
60
+ async run() {
61
+ const { args, flags } = await this.parse(SecretsSet);
62
+ const key = validateConfigKey(args.key);
63
+ const project = await this.loadProject();
64
+ const client = await this.verifiedClientForProject(project);
65
+ const existing = (await client.listSecrets()).secrets?.some((secret) => secret.key === key);
66
+ if (existing && !flags.force) {
67
+ throw new CliError(`Secret ${key} already exists. Re-run with --force to replace its value.`, 2);
68
+ }
69
+ const value = await this.secretValue(flags);
70
+ await client.setSecret(key, value);
71
+ this.log(`${this.success(existing ? "Replaced" : "Set")} secret ${this.taskName(key)}`);
72
+ }
73
+ async secretValue(flags) {
74
+ if (flags["from-stdin"]) {
75
+ return readSecretValueFromStdin();
76
+ }
77
+ if (flags["value-env"]) {
78
+ return readSecretValueFromEnv(flags["value-env"]);
79
+ }
80
+ const value = await promptForHiddenValue({
81
+ blankMessage: "Secret value cannot be blank.",
82
+ missingInputMessage: "Provide a secret value with --from-stdin or --value-env.",
83
+ prompt: "Secret value: ",
84
+ trim: false,
85
+ });
86
+ if (value === null) {
87
+ throw new CliError("Secret value cannot be blank.", 2);
88
+ }
89
+ return value;
90
+ }
91
+ }
@@ -0,0 +1,20 @@
1
+ import { BaseCommand } from "../../base-command.js";
2
+ import type { Project, ShopDeprecationsResponse } from "../../types.js";
3
+ type ShopDeprecation = ShopDeprecationsResponse["deprecations"][number];
4
+ export default class ShopDeprecations extends BaseCommand {
5
+ static summary: string;
6
+ static description: string;
7
+ static args: {
8
+ task: import("@oclif/core/interfaces").Arg<string | undefined, Record<string, unknown>>;
9
+ };
10
+ static flags: {
11
+ json: import("@oclif/core/interfaces").BooleanFlag<boolean>;
12
+ };
13
+ run(): Promise<void>;
14
+ taskIdForSelector(project: Project, input: string): Promise<string>;
15
+ deprecationsTable(response: ShopDeprecationsResponse): string[][];
16
+ deprecationCountSummary(response: ShopDeprecationsResponse): string;
17
+ requestSummary(deprecation: ShopDeprecation): string;
18
+ }
19
+ export {};
20
+ //# sourceMappingURL=deprecations.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"deprecations.d.ts","sourceRoot":"","sources":["../../../src/commands/shop/deprecations.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAGpD,OAAO,KAAK,EAAE,OAAO,EAAE,wBAAwB,EAAE,MAAM,gBAAgB,CAAC;AAExE,KAAK,eAAe,GAAG,wBAAwB,CAAC,cAAc,CAAC,CAAC,MAAM,CAAC,CAAC;AAUxE,MAAM,CAAC,OAAO,OAAO,gBAAiB,SAAQ,WAAW;IACvD,OAAgB,OAAO,SAA6D;IACpF,OAAgB,WAAW,SAAqH;IAEhJ,OAAgB,IAAI;;MAKlB;IAEF,OAAgB,KAAK;;MAInB;IAEI,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;IAyCpB,iBAAiB,CAAC,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAUzE,iBAAiB,CAAC,QAAQ,EAAE,wBAAwB,GAAG,MAAM,EAAE,EAAE;IAcjE,uBAAuB,CAAC,QAAQ,EAAE,wBAAwB,GAAG,MAAM;IAOnE,cAAc,CAAC,WAAW,EAAE,eAAe,GAAG,MAAM;CAcrD"}
@@ -0,0 +1,95 @@
1
+ import { Args, Flags } from "@oclif/core";
2
+ import { BaseCommand } from "../../base-command.js";
3
+ import { CliError } from "../../errors.js";
4
+ import { resolveTaskSelector } from "../../tasks.js";
5
+ function formatCount(value) {
6
+ return typeof value === "number" ? value.toLocaleString() : "--";
7
+ }
8
+ function formatValue(value) {
9
+ return value && value.trim() ? value : "--";
10
+ }
11
+ export default class ShopDeprecations extends BaseCommand {
12
+ static summary = "Show unresolved Shopify API deprecations for this shop.";
13
+ static description = "Show unresolved Shopify API deprecations reported by this shop's tasks, optionally filtered to one linked task.";
14
+ static args = {
15
+ task: Args.string({
16
+ description: "Optional task selector, linked task ID, local slug, task JSON file, or helper directory.",
17
+ required: false,
18
+ }),
19
+ };
20
+ static flags = {
21
+ json: Flags.boolean({
22
+ description: "Print deprecations as JSON for agents, scripts, or editor integrations.",
23
+ }),
24
+ };
25
+ async run() {
26
+ const { args, flags } = await this.parse(ShopDeprecations);
27
+ const project = await this.loadProject();
28
+ const client = await this.verifiedClientForProject(project);
29
+ const taskId = args.task ? await this.taskIdForSelector(project, args.task) : undefined;
30
+ const response = await client.getShopDeprecations(taskId);
31
+ if (flags.json) {
32
+ this.outputJson(response);
33
+ return;
34
+ }
35
+ this.log(`${this.accent("Shop")} ${response.shop.shopify_domain}`);
36
+ if (taskId) {
37
+ this.log(`${this.accent("Task")} ${this.taskId(project, taskId)}`);
38
+ }
39
+ if (response.deprecations.length === 0) {
40
+ this.log("");
41
+ this.log(this.success("No unresolved Shopify API deprecations."));
42
+ return;
43
+ }
44
+ this.log(`${this.accent("Deprecations")} ${this.deprecationCountSummary(response)}`);
45
+ if (response.truncated) {
46
+ const limit = typeof response.limit === "number" ? response.limit.toLocaleString() : response.deprecations.length.toLocaleString();
47
+ this.log(this.color("yellow", `Showing the first ${limit} unresolved deprecations. Filter with "mechanic shop deprecations <task>" for one task.`));
48
+ }
49
+ this.log("");
50
+ this.table(this.deprecationsTable(response));
51
+ this.log("");
52
+ this.log(this.accent("Details"));
53
+ response.deprecations.forEach((deprecation, index) => {
54
+ this.log(`${index + 1}. ${this.taskName(deprecation.task_name || deprecation.task_id)}`);
55
+ this.log(` ${this.muted("Request")} ${this.requestSummary(deprecation)}`);
56
+ this.log(` ${this.muted("Reason")} ${formatValue(deprecation.reason)}`);
57
+ });
58
+ }
59
+ async taskIdForSelector(project, input) {
60
+ const selector = await resolveTaskSelector(project, input, { allowHelperDir: true, allowRemoteId: true });
61
+ if (!selector.remoteId) {
62
+ throw new CliError(`${input} is not linked to a remote Mechanic task. Pull or publish it first.`, 2);
63
+ }
64
+ return selector.remoteId;
65
+ }
66
+ deprecationsTable(response) {
67
+ return [
68
+ ["#", "Task", "Task API", "Request API", "Last seen", "Count"],
69
+ ...response.deprecations.map((deprecation, index) => [
70
+ String(index + 1),
71
+ this.taskName(deprecation.task_name || deprecation.task_id),
72
+ formatValue(deprecation.task_shopify_api_version),
73
+ formatValue(deprecation.shopify_api_version),
74
+ this.muted(formatValue(deprecation.last_occurrence_at)),
75
+ formatCount(deprecation.occurrences_count),
76
+ ]),
77
+ ];
78
+ }
79
+ deprecationCountSummary(response) {
80
+ const shown = response.deprecations.length;
81
+ const total = typeof response.total_count === "number" ? response.total_count : shown;
82
+ return `${shown.toLocaleString()}/${total.toLocaleString()} shown`;
83
+ }
84
+ requestSummary(deprecation) {
85
+ const method = formatValue(deprecation.request_method);
86
+ const path = formatValue(deprecation.request_path);
87
+ if (method === "--") {
88
+ return path;
89
+ }
90
+ if (path === "--") {
91
+ return method;
92
+ }
93
+ return `${method} ${path}`;
94
+ }
95
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"list.d.ts","sourceRoot":"","sources":["../../../src/commands/tasks/list.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAGpD,MAAM,CAAC,OAAO,OAAO,SAAU,SAAQ,WAAW;IAChD,OAAgB,OAAO,SAAkD;IACzE,OAAgB,WAAW,SAAsF;IAEjH,OAAgB,KAAK;;;MAQnB;IAEI,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;CAgD3B"}
1
+ {"version":3,"file":"list.d.ts","sourceRoot":"","sources":["../../../src/commands/tasks/list.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAcpD,MAAM,CAAC,OAAO,OAAO,SAAU,SAAQ,WAAW;IAChD,OAAgB,OAAO,SAAkD;IACzE,OAAgB,WAAW,SAAsF;IAEjH,OAAgB,KAAK;;;MAQnB;IAEI,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;CAoD3B"}
@@ -1,6 +1,13 @@
1
1
  import { Flags } from "@oclif/core";
2
2
  import { BaseCommand } from "../../base-command.js";
3
3
  import { slugForRemoteId } from "../../config.js";
4
+ function taskShopifyApiVersion(envelope) {
5
+ if (typeof envelope.shopify_api_version === "string" && envelope.shopify_api_version.trim()) {
6
+ return envelope.shopify_api_version;
7
+ }
8
+ const version = envelope.task?.shopify_api_version;
9
+ return typeof version === "string" && version.trim() ? version : null;
10
+ }
4
11
  export default class TasksList extends BaseCommand {
5
12
  static summary = "List remote tasks without changing anything.";
6
13
  static description = "List remote Mechanic tasks without pulling, publishing, or changing local files.";
@@ -28,6 +35,7 @@ export default class TasksList extends BaseCommand {
28
35
  id: envelope.id,
29
36
  name: typeof envelope.task?.name === "string" ? envelope.task.name : "",
30
37
  updated_at: envelope.updated_at || null,
38
+ shopify_api_version: taskShopifyApiVersion(envelope),
31
39
  content_hash: envelope.content_hash || null,
32
40
  linked: Boolean(link),
33
41
  slug: slug || null,
@@ -37,13 +45,16 @@ export default class TasksList extends BaseCommand {
37
45
  });
38
46
  return;
39
47
  }
40
- const rows = flags.verbose ? [["Name", "File", "Updated", "ID", "Hash"]] : [["Name", "File", "Updated", "ID"]];
48
+ const rows = flags.verbose
49
+ ? [["Name", "File", "API version", "Updated", "ID", "Hash"]]
50
+ : [["Name", "File", "API version", "Updated", "ID"]];
41
51
  for (const envelope of response.tasks || []) {
42
52
  const slug = slugForRemoteId(project, envelope.id);
43
53
  const link = slug ? project.links.tasks[slug] : null;
44
54
  const row = [
45
55
  this.taskName(String(envelope.task?.name || "")),
46
56
  link ? this.taskName(link.file || `${project.tasksDirName}/${slug}.json`) : this.muted("--"),
57
+ taskShopifyApiVersion(envelope) || this.muted("--"),
47
58
  this.muted(envelope.updated_at || ""),
48
59
  this.taskId(project, envelope.id),
49
60
  ];
@@ -0,0 +1,2 @@
1
+ export declare function validateConfigKey(key: string): string;
2
+ //# sourceMappingURL=config-keys.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config-keys.d.ts","sourceRoot":"","sources":["../src/config-keys.ts"],"names":[],"mappings":"AAIA,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAMrD"}
@@ -0,0 +1,8 @@
1
+ import { CliError } from "./errors.js";
2
+ const CONFIG_KEY_PATTERN = /^[a-z][a-z0-9_]*$/;
3
+ export function validateConfigKey(key) {
4
+ if (!CONFIG_KEY_PATTERN.test(key)) {
5
+ throw new CliError("Keys must use lower snake-case and match /^[a-z][a-z0-9_]*$/.", 2);
6
+ }
7
+ return key;
8
+ }
package/dist/types.d.ts CHANGED
@@ -30,6 +30,7 @@ export type TaskEnvelope = {
30
30
  updated_at?: string;
31
31
  content_hash: string;
32
32
  enabled?: boolean | null;
33
+ shopify_api_version?: string | null;
33
34
  task: JsonObject;
34
35
  };
35
36
  export type TaskListResponse = {
@@ -154,4 +155,26 @@ export type ShopStatusResponse = {
154
155
  };
155
156
  checked_at: string;
156
157
  };
158
+ export type ShopDeprecationsResponse = {
159
+ shop: {
160
+ shopify_domain: string;
161
+ };
162
+ total_count?: number;
163
+ limit?: number;
164
+ truncated?: boolean;
165
+ deprecations: Array<{
166
+ id: number;
167
+ task_id: string;
168
+ task_name?: string | null;
169
+ task_shopify_api_version?: string | null;
170
+ reason: string;
171
+ shopify_api_version?: string | null;
172
+ request_method?: string | null;
173
+ request_path?: string | null;
174
+ response_code?: number | null;
175
+ occurrences_count?: number | null;
176
+ first_occurrence_at?: string | null;
177
+ last_occurrence_at?: string | null;
178
+ }>;
179
+ };
157
180
  //# sourceMappingURL=types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lightward/mechanic-cli",
3
- "version": "0.1.9",
3
+ "version": "0.1.10",
4
4
  "description": "Develop, preview, diff, and publish Mechanic Shopify automation tasks from local files",
5
5
  "type": "module",
6
6
  "keywords": [
@@ -50,7 +50,7 @@
50
50
  "description": "Generate optional GitHub Actions workflows for Mechanic task updates."
51
51
  },
52
52
  "shop": {
53
- "description": "Inspect this shop's Mechanic queue and backlog."
53
+ "description": "Inspect this shop's Mechanic queue, backlog, and deprecations."
54
54
  },
55
55
  "tasks": {
56
56
  "description": "List, pull, edit, diff, and publish Mechanic tasks."