shopq 0.3.9 → 0.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/shopq.js +58 -3
- package/extensions/shopq-path.ts +29 -0
- package/package.json +11 -1
- package/skills/shopq/SKILL.md +1 -5
package/dist/shopq.js
CHANGED
|
@@ -232,6 +232,14 @@ function handleCommandError(err) {
|
|
|
232
232
|
}
|
|
233
233
|
throw new Error(String(err));
|
|
234
234
|
}
|
|
235
|
+
function rejectHandleFlag(parsed, usage) {
|
|
236
|
+
if (parsed.args.length === 0 && parsed.flags.handle) {
|
|
237
|
+
formatError(`--handle is not a flag for this command. Pass the identifier as a positional argument: ${usage}`);
|
|
238
|
+
process.exitCode = 2;
|
|
239
|
+
return true;
|
|
240
|
+
}
|
|
241
|
+
return false;
|
|
242
|
+
}
|
|
235
243
|
async function readFileText(path) {
|
|
236
244
|
if (!existsSync(path)) {
|
|
237
245
|
formatError(`File not found: ${path}`);
|
|
@@ -476,6 +484,8 @@ var PRODUCTS_QUERY = `query ProductList($first: Int!, $after: String, $sortKey:
|
|
|
476
484
|
vendor
|
|
477
485
|
variantsCount { count }
|
|
478
486
|
totalInventory
|
|
487
|
+
category { id name }
|
|
488
|
+
featuredImage { url }
|
|
479
489
|
}
|
|
480
490
|
}
|
|
481
491
|
pageInfo {
|
|
@@ -514,7 +524,9 @@ async function handleProductList(parsed) {
|
|
|
514
524
|
productType: e.node.productType,
|
|
515
525
|
vendor: e.node.vendor,
|
|
516
526
|
variantsCount: e.node.variantsCount.count,
|
|
517
|
-
totalInventory: e.node.totalInventory
|
|
527
|
+
totalInventory: e.node.totalInventory,
|
|
528
|
+
category: e.node.category?.name ?? null,
|
|
529
|
+
hasImage: e.node.featuredImage !== null
|
|
518
530
|
}));
|
|
519
531
|
const pageInfo = result.products.pageInfo;
|
|
520
532
|
if (parsed.flags.json) {
|
|
@@ -532,9 +544,15 @@ async function handleProductList(parsed) {
|
|
|
532
544
|
{ key: "productType", header: "Type" },
|
|
533
545
|
{ key: "vendor", header: "Vendor" },
|
|
534
546
|
{ key: "variantsCount", header: "Variants" },
|
|
535
|
-
{ key: "totalInventory", header: "Inventory" }
|
|
547
|
+
{ key: "totalInventory", header: "Inventory" },
|
|
548
|
+
{ key: "category", header: "Category" },
|
|
549
|
+
{ key: "hasImage", header: "Image" }
|
|
536
550
|
];
|
|
537
|
-
|
|
551
|
+
const tableData = products.map((p) => ({
|
|
552
|
+
...p,
|
|
553
|
+
hasImage: p.hasImage ? "Yes" : "No"
|
|
554
|
+
}));
|
|
555
|
+
formatOutput(tableData, columns, {
|
|
538
556
|
json: false,
|
|
539
557
|
noColor: parsed.flags.noColor,
|
|
540
558
|
pageInfo
|
|
@@ -552,6 +570,17 @@ var PRODUCT_GET_QUERY = `query ProductGet($id: ID!) {
|
|
|
552
570
|
vendor
|
|
553
571
|
tags
|
|
554
572
|
descriptionHtml
|
|
573
|
+
category { id name }
|
|
574
|
+
metafields(first: 25) {
|
|
575
|
+
edges {
|
|
576
|
+
node {
|
|
577
|
+
namespace
|
|
578
|
+
key
|
|
579
|
+
type
|
|
580
|
+
value
|
|
581
|
+
}
|
|
582
|
+
}
|
|
583
|
+
}
|
|
555
584
|
variants(first: 100) {
|
|
556
585
|
edges {
|
|
557
586
|
node {
|
|
@@ -602,6 +631,8 @@ function truncate(str, max) {
|
|
|
602
631
|
return `${str.slice(0, max - 3)}...`;
|
|
603
632
|
}
|
|
604
633
|
async function handleProductGet(parsed) {
|
|
634
|
+
if (rejectHandleFlag(parsed, "shopq product get <id-or-title>"))
|
|
635
|
+
return;
|
|
605
636
|
const idOrTitle = parsed.args.join(" ");
|
|
606
637
|
if (!idOrTitle) {
|
|
607
638
|
formatError("Usage: shopq product get <id-or-title>");
|
|
@@ -671,6 +702,12 @@ function outputProduct(product, parsed) {
|
|
|
671
702
|
url: e.node.url,
|
|
672
703
|
alt: e.node.altText ?? ""
|
|
673
704
|
}));
|
|
705
|
+
const metafields = product.metafields.edges.map((e) => ({
|
|
706
|
+
namespace: e.node.namespace,
|
|
707
|
+
key: e.node.key,
|
|
708
|
+
type: e.node.type,
|
|
709
|
+
value: e.node.value
|
|
710
|
+
}));
|
|
674
711
|
if (parsed.flags.json) {
|
|
675
712
|
const data = {
|
|
676
713
|
id: product.id,
|
|
@@ -680,6 +717,8 @@ function outputProduct(product, parsed) {
|
|
|
680
717
|
vendor: product.vendor,
|
|
681
718
|
tags: product.tags,
|
|
682
719
|
description: stripHtml(product.descriptionHtml),
|
|
720
|
+
category: product.category,
|
|
721
|
+
metafields,
|
|
683
722
|
variants: product.variants.edges.map((e) => ({
|
|
684
723
|
id: e.node.id,
|
|
685
724
|
sku: e.node.sku,
|
|
@@ -701,8 +740,18 @@ function outputProduct(product, parsed) {
|
|
|
701
740
|
lines.push(`${label("Type")}: ${product.productType}`);
|
|
702
741
|
lines.push(`${label("Vendor")}: ${product.vendor}`);
|
|
703
742
|
lines.push(`${label("Tags")}: ${product.tags.join(", ")}`);
|
|
743
|
+
lines.push(`${label("Category")}: ${product.category?.name ?? ""}`);
|
|
704
744
|
lines.push(`${label("Description")}: ${truncate(plainDesc, 80)}`);
|
|
705
745
|
lines.push("");
|
|
746
|
+
lines.push(`${label("Metafields")}:`);
|
|
747
|
+
if (metafields.length === 0) {
|
|
748
|
+
lines.push(" (none)");
|
|
749
|
+
} else {
|
|
750
|
+
for (const mf of metafields) {
|
|
751
|
+
lines.push(` ${mf.namespace}.${mf.key}: ${mf.value}`);
|
|
752
|
+
}
|
|
753
|
+
}
|
|
754
|
+
lines.push("");
|
|
706
755
|
lines.push(`${label("Variants")}:`);
|
|
707
756
|
for (const v of variants) {
|
|
708
757
|
lines.push(` SKU: ${v.sku} Price: ${v.price} Options: ${v.options} Qty: ${v.inventoryQuantity}`);
|
|
@@ -1103,6 +1152,8 @@ function flattenItems(items, depth, rows) {
|
|
|
1103
1152
|
}
|
|
1104
1153
|
}
|
|
1105
1154
|
async function handleMenuGet(parsed) {
|
|
1155
|
+
if (rejectHandleFlag(parsed, "shopq menu get <id-or-handle>"))
|
|
1156
|
+
return;
|
|
1106
1157
|
const idOrHandle = parsed.args.join(" ");
|
|
1107
1158
|
if (!idOrHandle) {
|
|
1108
1159
|
formatError("Usage: shopq menu get <id-or-handle>");
|
|
@@ -1549,6 +1600,8 @@ function resolvePageId(input) {
|
|
|
1549
1600
|
return { type: "handle", handle: input };
|
|
1550
1601
|
}
|
|
1551
1602
|
async function handlePageGet(parsed) {
|
|
1603
|
+
if (rejectHandleFlag(parsed, "shopq page get <id-or-handle>"))
|
|
1604
|
+
return;
|
|
1552
1605
|
const idOrHandle = parsed.args.join(" ");
|
|
1553
1606
|
if (!idOrHandle) {
|
|
1554
1607
|
formatError("Usage: shopq page get <id-or-handle>");
|
|
@@ -1844,6 +1897,8 @@ function truncate2(str, max) {
|
|
|
1844
1897
|
return `${str.slice(0, max - 3)}...`;
|
|
1845
1898
|
}
|
|
1846
1899
|
async function handleCollectionGet(parsed) {
|
|
1900
|
+
if (rejectHandleFlag(parsed, "shopq collection get <id-or-handle>"))
|
|
1901
|
+
return;
|
|
1847
1902
|
const idOrHandle = parsed.args.join(" ");
|
|
1848
1903
|
if (!idOrHandle) {
|
|
1849
1904
|
formatError("Usage: shopq collection get <id-or-handle>");
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Adds .pi/npm/node_modules/.bin to the bash tool's PATH so that
|
|
3
|
+
* `shopq` (and any other pi-installed CLI) resolves without a global install.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
|
|
7
|
+
import { createBashTool } from "@mariozechner/pi-coding-agent";
|
|
8
|
+
|
|
9
|
+
export default function (pi: ExtensionAPI) {
|
|
10
|
+
const cwd = process.cwd();
|
|
11
|
+
|
|
12
|
+
const bashTool = createBashTool(cwd, {
|
|
13
|
+
spawnHook: ({ command, cwd: spawnCwd, env }) => ({
|
|
14
|
+
command,
|
|
15
|
+
cwd: spawnCwd,
|
|
16
|
+
env: {
|
|
17
|
+
...env,
|
|
18
|
+
PATH: `${cwd}/.pi/npm/node_modules/.bin:${env.PATH ?? ""}`,
|
|
19
|
+
},
|
|
20
|
+
}),
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
pi.registerTool({
|
|
24
|
+
...bashTool,
|
|
25
|
+
execute: async (id, params, signal, onUpdate) => {
|
|
26
|
+
return bashTool.execute(id, params, signal, onUpdate);
|
|
27
|
+
},
|
|
28
|
+
});
|
|
29
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "shopq",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.1",
|
|
4
4
|
"description": "A zero-dependency Shopify Admin CLI built on Bun",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
},
|
|
10
10
|
"files": [
|
|
11
11
|
"dist",
|
|
12
|
+
"extensions",
|
|
12
13
|
"skills"
|
|
13
14
|
],
|
|
14
15
|
"scripts": {
|
|
@@ -35,6 +36,9 @@
|
|
|
35
36
|
"pi-package"
|
|
36
37
|
],
|
|
37
38
|
"pi": {
|
|
39
|
+
"extensions": [
|
|
40
|
+
"./extensions"
|
|
41
|
+
],
|
|
38
42
|
"skills": [
|
|
39
43
|
"./skills"
|
|
40
44
|
]
|
|
@@ -47,6 +51,12 @@
|
|
|
47
51
|
"@types/bun": "latest"
|
|
48
52
|
},
|
|
49
53
|
"peerDependencies": {
|
|
54
|
+
"@mariozechner/pi-coding-agent": "*",
|
|
50
55
|
"typescript": "^5.9.3"
|
|
56
|
+
},
|
|
57
|
+
"peerDependenciesMeta": {
|
|
58
|
+
"@mariozechner/pi-coding-agent": {
|
|
59
|
+
"optional": true
|
|
60
|
+
}
|
|
51
61
|
}
|
|
52
62
|
}
|
package/skills/shopq/SKILL.md
CHANGED
|
@@ -9,11 +9,7 @@ A zero-dependency Shopify Admin CLI. Structured JSON output, predictable exit co
|
|
|
9
9
|
|
|
10
10
|
## Setup
|
|
11
11
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
```bash
|
|
15
|
-
bun install -g shopq
|
|
16
|
-
```
|
|
12
|
+
If `shopq` is not found on PATH, it may not be installed globally. Let the user know they can install it with their package manager (e.g. `npm install -g shopq`, `bun install -g shopq`, etc.).
|
|
17
13
|
|
|
18
14
|
Configure credentials (one of):
|
|
19
15
|
|