@01.software/cli 0.10.3 → 0.10.4
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/index.js +485 -37
- package/dist/index.js.map +1 -1
- package/dist/mcp/{chunk-VSMPWKVX.js → chunk-F5VI4HQM.js} +252 -218
- package/dist/mcp/chunk-F5VI4HQM.js.map +1 -0
- package/dist/mcp/http.js +1 -1
- package/dist/mcp/stdio.js +1 -1
- package/dist/mcp/vercel.js +251 -217
- package/package.json +2 -2
- package/dist/mcp/chunk-VSMPWKVX.js.map +0 -1
package/dist/index.js
CHANGED
|
@@ -8,7 +8,7 @@ import { Command } from "commander";
|
|
|
8
8
|
import {
|
|
9
9
|
CollectionClient,
|
|
10
10
|
ServerCommerceClient
|
|
11
|
-
} from "@01.software/sdk";
|
|
11
|
+
} from "@01.software/sdk/server";
|
|
12
12
|
|
|
13
13
|
// src/lib/credentials.ts
|
|
14
14
|
import {
|
|
@@ -166,6 +166,9 @@ function classifyError(err) {
|
|
|
166
166
|
if (isPermissionCode(code)) {
|
|
167
167
|
return { type: "permission", code };
|
|
168
168
|
}
|
|
169
|
+
if (code === "auth_error" || code === "permission_error") {
|
|
170
|
+
return { type: "permission", code: "credential_invalid" };
|
|
171
|
+
}
|
|
169
172
|
if (isDegradedCode(code)) {
|
|
170
173
|
const out = { type: "degraded", code };
|
|
171
174
|
if (typeof obj.retryAfter === "number") {
|
|
@@ -187,7 +190,7 @@ function classifyError(err) {
|
|
|
187
190
|
}
|
|
188
191
|
const name = typeof obj.name === "string" ? obj.name : void 0;
|
|
189
192
|
const status = typeof obj.status === "number" ? obj.status : void 0;
|
|
190
|
-
if (name === "ConfigError" || status === 401) {
|
|
193
|
+
if (name === "ConfigError" || name === "AuthError" || name === "PermissionError" || status === 401 || status === 403) {
|
|
191
194
|
return { type: "permission", code: "credential_invalid" };
|
|
192
195
|
}
|
|
193
196
|
if (name === "NetworkError" || name === "TimeoutError" || status === 408 || status === 503) {
|
|
@@ -440,7 +443,14 @@ function exitWithError(error, options = {}) {
|
|
|
440
443
|
function isValidBearerToken(secret) {
|
|
441
444
|
return secret.startsWith("sk01_") || secret.startsWith("pat01_");
|
|
442
445
|
}
|
|
443
|
-
function
|
|
446
|
+
function credentialError(detail) {
|
|
447
|
+
return {
|
|
448
|
+
type: "permission",
|
|
449
|
+
code: "credential_invalid",
|
|
450
|
+
detail
|
|
451
|
+
};
|
|
452
|
+
}
|
|
453
|
+
function resolveClientCredentials(apiKeyFlag) {
|
|
444
454
|
let publishableKey = process.env.SOFTWARE_PUBLISHABLE_KEY;
|
|
445
455
|
let secretKey = apiKeyFlag ?? process.env.SOFTWARE_SECRET_KEY;
|
|
446
456
|
if (!publishableKey || !secretKey) {
|
|
@@ -458,29 +468,25 @@ function resolveClient(apiKeyFlag) {
|
|
|
458
468
|
}
|
|
459
469
|
}
|
|
460
470
|
if (!publishableKey || !secretKey) {
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
t("PassApiKey"),
|
|
469
|
-
t("SetEnvVars")
|
|
470
|
-
]
|
|
471
|
-
}
|
|
471
|
+
throw credentialError({
|
|
472
|
+
message: t("AuthenticationRequired"),
|
|
473
|
+
steps: [
|
|
474
|
+
t("RunLoginToAuthenticate"),
|
|
475
|
+
t("PassApiKey"),
|
|
476
|
+
t("SetEnvVars")
|
|
477
|
+
]
|
|
472
478
|
});
|
|
473
479
|
}
|
|
474
480
|
if (!isValidBearerToken(secretKey)) {
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
detail: {
|
|
479
|
-
message: t("InvalidApiKeyFormat"),
|
|
480
|
-
suggestion: t("RetiredHexCredentialsRejected")
|
|
481
|
-
}
|
|
481
|
+
throw credentialError({
|
|
482
|
+
message: t("InvalidApiKeyFormat"),
|
|
483
|
+
suggestion: t("RetiredHexCredentialsRejected")
|
|
482
484
|
});
|
|
483
485
|
}
|
|
486
|
+
return { publishableKey, secretKey };
|
|
487
|
+
}
|
|
488
|
+
function resolveClientOrThrow(apiKeyFlag) {
|
|
489
|
+
const { publishableKey, secretKey } = resolveClientCredentials(apiKeyFlag);
|
|
484
490
|
const serverOptions = { publishableKey, secretKey };
|
|
485
491
|
return {
|
|
486
492
|
collections: new CollectionClient(
|
|
@@ -495,11 +501,37 @@ function resolveClient(apiKeyFlag) {
|
|
|
495
501
|
secretKey
|
|
496
502
|
};
|
|
497
503
|
}
|
|
504
|
+
function resolveClient(apiKeyFlag) {
|
|
505
|
+
try {
|
|
506
|
+
return resolveClientOrThrow(apiKeyFlag);
|
|
507
|
+
} catch (error) {
|
|
508
|
+
exitWithError(error);
|
|
509
|
+
}
|
|
510
|
+
}
|
|
498
511
|
|
|
499
512
|
// src/commands/crud.ts
|
|
500
513
|
import { readFileSync as readFileSync2 } from "fs";
|
|
501
514
|
import { basename } from "path";
|
|
515
|
+
|
|
516
|
+
// src/lib/collections.ts
|
|
502
517
|
import { COLLECTIONS } from "@01.software/sdk";
|
|
518
|
+
function validateCollection(name) {
|
|
519
|
+
if (COLLECTIONS.includes(name)) {
|
|
520
|
+
return name;
|
|
521
|
+
}
|
|
522
|
+
const normalized = name.replace(/-/g, "").toLowerCase();
|
|
523
|
+
const suggestions = COLLECTIONS.filter((collection) => {
|
|
524
|
+
const candidate = collection.replace(/-/g, "").toLowerCase();
|
|
525
|
+
return candidate.startsWith(normalized) || normalized.startsWith(candidate) || normalized.length >= 3 && candidate.includes(normalized);
|
|
526
|
+
}).slice(0, 5);
|
|
527
|
+
const hint = suggestions.length > 0 ? `Did you mean: ${suggestions.join(", ")}?` : 'Run "01 --help" for available collections.';
|
|
528
|
+
throw new Error(`Unknown collection "${name}". ${hint}`);
|
|
529
|
+
}
|
|
530
|
+
function parseSelect(input) {
|
|
531
|
+
return Object.fromEntries(
|
|
532
|
+
input.split(",").map((field) => field.trim()).map((field) => [field, true])
|
|
533
|
+
);
|
|
534
|
+
}
|
|
503
535
|
|
|
504
536
|
// src/lib/parse.ts
|
|
505
537
|
function failArg(label, value, expectedKind) {
|
|
@@ -581,21 +613,6 @@ function readFileAsBlob(filePath) {
|
|
|
581
613
|
const buffer = readFileSync2(filePath);
|
|
582
614
|
return { blob: new Blob([buffer]), filename: basename(filePath) };
|
|
583
615
|
}
|
|
584
|
-
function validateCollection(name) {
|
|
585
|
-
if (!COLLECTIONS.includes(name)) {
|
|
586
|
-
const normalized = name.replace(/-/g, "").toLowerCase();
|
|
587
|
-
const suggestions = COLLECTIONS.filter((c) => {
|
|
588
|
-
const cn = c.replace(/-/g, "").toLowerCase();
|
|
589
|
-
return cn.startsWith(normalized) || normalized.startsWith(cn) || normalized.length >= 3 && cn.includes(normalized);
|
|
590
|
-
}).slice(0, 5);
|
|
591
|
-
const hint = suggestions.length > 0 ? `Did you mean: ${suggestions.join(", ")}?` : 'Run "01 --help" for available collections.';
|
|
592
|
-
throw new Error(`Unknown collection "${name}". ${hint}`);
|
|
593
|
-
}
|
|
594
|
-
return name;
|
|
595
|
-
}
|
|
596
|
-
function parseSelect(input) {
|
|
597
|
-
return Object.fromEntries(input.split(",").map((f) => [f.trim(), true]));
|
|
598
|
-
}
|
|
599
616
|
function registerCrudCommands(program2, getClient2, getFormat2) {
|
|
600
617
|
program2.command("query <collection>").description("Query documents from a collection").option("--where <json>", "Filter conditions (JSON)").option("--limit <n>", "Max results", (v) => parseInt(v, 10)).option("--page <n>", "Page number", (v) => parseInt(v, 10)).option("--sort <field>", "Sort field (prefix with - for descending)").option(
|
|
601
618
|
"--depth <n>",
|
|
@@ -1552,8 +1569,9 @@ function registerSchemaCommands(program2, getClient2, getFormat2) {
|
|
|
1552
1569
|
});
|
|
1553
1570
|
}
|
|
1554
1571
|
|
|
1555
|
-
// ../contracts/
|
|
1572
|
+
// ../contracts/dist/index.js
|
|
1556
1573
|
import { z as z3 } from "zod";
|
|
1574
|
+
import { z as z22 } from "zod";
|
|
1557
1575
|
var tenantFieldConfigStateSchema = z3.object({
|
|
1558
1576
|
hiddenFields: z3.array(z3.string()),
|
|
1559
1577
|
isHidden: z3.boolean()
|
|
@@ -1697,6 +1715,233 @@ var collectionSchemaResponseSchema = z3.object({
|
|
|
1697
1715
|
fields: z3.array(collectionFieldSchema)
|
|
1698
1716
|
}).strict()
|
|
1699
1717
|
}).strict();
|
|
1718
|
+
var transactionStatusSchema = z22.enum([
|
|
1719
|
+
"pending",
|
|
1720
|
+
"paid",
|
|
1721
|
+
"failed",
|
|
1722
|
+
"canceled"
|
|
1723
|
+
]);
|
|
1724
|
+
var updateTransactionSchema = z22.object({
|
|
1725
|
+
pgPaymentId: z22.string().min(1, "pgPaymentId is required").describe("PG payment ID (required)"),
|
|
1726
|
+
status: transactionStatusSchema.describe(
|
|
1727
|
+
"New transaction status (required)"
|
|
1728
|
+
),
|
|
1729
|
+
paymentMethod: z22.string().optional().describe("Payment method (optional)"),
|
|
1730
|
+
receiptUrl: z22.string().optional().describe("Receipt URL (optional)"),
|
|
1731
|
+
paymentKey: z22.string().min(1).optional().describe("Provider payment key for verified paid confirmation"),
|
|
1732
|
+
amount: z22.number().int().positive().optional().describe("Provider-confirmed amount for verified paid confirmation")
|
|
1733
|
+
}).strict();
|
|
1734
|
+
var providerSlugSchema = z22.string().trim().regex(/^[a-z0-9][a-z0-9_-]{0,63}$/, "pgProvider must be lowercase slug");
|
|
1735
|
+
var confirmPaymentSchema = z22.object({
|
|
1736
|
+
orderNumber: z22.string().min(1).optional(),
|
|
1737
|
+
pgPaymentId: z22.string().min(1, "pgPaymentId is required").describe("Provider payment identifier stored on the transaction"),
|
|
1738
|
+
pgProvider: providerSlugSchema.describe(
|
|
1739
|
+
"Payment provider slug, e.g. toss, portone, stripe"
|
|
1740
|
+
),
|
|
1741
|
+
pgOrderId: z22.string().min(1).optional(),
|
|
1742
|
+
amount: z22.number().int().nonnegative("amount must be non-negative").describe("Provider-confirmed amount in minor units"),
|
|
1743
|
+
currency: z22.string().min(1).optional(),
|
|
1744
|
+
paymentMethod: z22.string().optional(),
|
|
1745
|
+
receiptUrl: z22.string().url().optional(),
|
|
1746
|
+
approvedAt: z22.string().optional(),
|
|
1747
|
+
providerStatus: z22.string().optional(),
|
|
1748
|
+
providerEventId: z22.string().min(1).optional(),
|
|
1749
|
+
confirmationSource: z22.enum([
|
|
1750
|
+
"provider_webhook",
|
|
1751
|
+
"provider_lookup",
|
|
1752
|
+
"provider_api_confirm",
|
|
1753
|
+
"manual_server"
|
|
1754
|
+
]).optional(),
|
|
1755
|
+
metadata: z22.record(z22.string(), z22.unknown()).optional()
|
|
1756
|
+
}).strict();
|
|
1757
|
+
var returnReasonSchema2 = z22.enum([
|
|
1758
|
+
"change_of_mind",
|
|
1759
|
+
"defective",
|
|
1760
|
+
"wrong_delivery",
|
|
1761
|
+
"damaged",
|
|
1762
|
+
"other"
|
|
1763
|
+
]);
|
|
1764
|
+
var restockActionSchema = z22.enum(["return_to_stock", "discard"]);
|
|
1765
|
+
var returnWithRefundItemSchema = z22.object({
|
|
1766
|
+
orderItem: z22.union([z22.string(), z22.number()]).transform(String),
|
|
1767
|
+
quantity: z22.number().int().positive("quantity must be a positive integer"),
|
|
1768
|
+
restockAction: restockActionSchema.default("return_to_stock"),
|
|
1769
|
+
restockingFee: z22.number().min(0, "restockingFee must be non-negative").optional().describe("Restocking fee charged for this line (ADR 0005 \xA7Gap 1)")
|
|
1770
|
+
}).strict();
|
|
1771
|
+
var returnWithRefundSchema = z22.object({
|
|
1772
|
+
orderNumber: z22.string().min(1, "orderNumber is required").describe("Order number (required)"),
|
|
1773
|
+
reason: returnReasonSchema2.optional().describe("Return reason (optional)"),
|
|
1774
|
+
reasonDetail: z22.string().optional().describe("Detailed reason text (optional)"),
|
|
1775
|
+
returnItems: z22.array(returnWithRefundItemSchema).min(1, "At least one return item is required").max(100, "Too many return items").describe("Array of products to return (required)"),
|
|
1776
|
+
refundAmount: z22.number().min(0, "refundAmount must be non-negative").describe("Refund amount (required, min 0)"),
|
|
1777
|
+
returnShippingFee: z22.number().min(0, "returnShippingFee must be non-negative").optional().describe("Return shipping fee charged to the customer (ADR 0005 \xA7Gap 1)"),
|
|
1778
|
+
pgPaymentId: z22.string().min(1, "pgPaymentId is required").describe("PG payment ID for refund (required)"),
|
|
1779
|
+
paymentKey: z22.string().min(1).optional().describe("Provider payment key for verified refund"),
|
|
1780
|
+
refundReceiptUrl: z22.string().optional().describe("Refund receipt URL (optional)")
|
|
1781
|
+
}).strict();
|
|
1782
|
+
var MCP_TOOL_CONTRACT = {
|
|
1783
|
+
"query-collection": {
|
|
1784
|
+
consoleRole: "tenant-viewer",
|
|
1785
|
+
oauthScope: "mcp:read",
|
|
1786
|
+
readOnly: true
|
|
1787
|
+
},
|
|
1788
|
+
"get-collection-by-id": {
|
|
1789
|
+
consoleRole: "tenant-viewer",
|
|
1790
|
+
oauthScope: "mcp:read",
|
|
1791
|
+
readOnly: true
|
|
1792
|
+
},
|
|
1793
|
+
"get-order": {
|
|
1794
|
+
consoleRole: "tenant-viewer",
|
|
1795
|
+
oauthScope: "mcp:read",
|
|
1796
|
+
readOnly: true
|
|
1797
|
+
},
|
|
1798
|
+
"stock-check": {
|
|
1799
|
+
consoleRole: "tenant-viewer",
|
|
1800
|
+
oauthScope: "mcp:read",
|
|
1801
|
+
readOnly: true
|
|
1802
|
+
},
|
|
1803
|
+
"product-detail": {
|
|
1804
|
+
consoleRole: "tenant-viewer",
|
|
1805
|
+
oauthScope: "mcp:read",
|
|
1806
|
+
readOnly: true
|
|
1807
|
+
},
|
|
1808
|
+
"product-upsert": {
|
|
1809
|
+
consoleRole: "tenant-admin",
|
|
1810
|
+
oauthScope: "mcp:write",
|
|
1811
|
+
readOnly: false
|
|
1812
|
+
},
|
|
1813
|
+
"validate-discount": {
|
|
1814
|
+
consoleRole: "tenant-viewer",
|
|
1815
|
+
oauthScope: "mcp:read",
|
|
1816
|
+
readOnly: true
|
|
1817
|
+
},
|
|
1818
|
+
"calculate-shipping": {
|
|
1819
|
+
consoleRole: "tenant-viewer",
|
|
1820
|
+
oauthScope: "mcp:read",
|
|
1821
|
+
readOnly: true
|
|
1822
|
+
},
|
|
1823
|
+
"get-collection-schema": {
|
|
1824
|
+
consoleRole: "tenant-viewer",
|
|
1825
|
+
oauthScope: "mcp:read",
|
|
1826
|
+
readOnly: true
|
|
1827
|
+
},
|
|
1828
|
+
"list-configurable-fields": {
|
|
1829
|
+
consoleRole: "tenant-viewer",
|
|
1830
|
+
oauthScope: "mcp:read",
|
|
1831
|
+
readOnly: true
|
|
1832
|
+
},
|
|
1833
|
+
"get-tenant-context": {
|
|
1834
|
+
consoleRole: "tenant-viewer",
|
|
1835
|
+
oauthScope: "mcp:read",
|
|
1836
|
+
readOnly: true
|
|
1837
|
+
},
|
|
1838
|
+
"check-feature-progress": {
|
|
1839
|
+
consoleRole: "tenant-viewer",
|
|
1840
|
+
oauthScope: "mcp:read",
|
|
1841
|
+
readOnly: true
|
|
1842
|
+
},
|
|
1843
|
+
"add-cart-item": {
|
|
1844
|
+
consoleRole: "tenant-editor",
|
|
1845
|
+
oauthScope: "mcp:write",
|
|
1846
|
+
readOnly: false
|
|
1847
|
+
},
|
|
1848
|
+
"update-cart-item": {
|
|
1849
|
+
consoleRole: "tenant-editor",
|
|
1850
|
+
oauthScope: "mcp:write",
|
|
1851
|
+
readOnly: false
|
|
1852
|
+
},
|
|
1853
|
+
"remove-cart-item": {
|
|
1854
|
+
consoleRole: "tenant-editor",
|
|
1855
|
+
oauthScope: "mcp:write",
|
|
1856
|
+
readOnly: false
|
|
1857
|
+
},
|
|
1858
|
+
"clear-cart": {
|
|
1859
|
+
consoleRole: "tenant-editor",
|
|
1860
|
+
oauthScope: "mcp:write",
|
|
1861
|
+
readOnly: false
|
|
1862
|
+
},
|
|
1863
|
+
"apply-discount": {
|
|
1864
|
+
consoleRole: "tenant-editor",
|
|
1865
|
+
oauthScope: "mcp:write",
|
|
1866
|
+
readOnly: false
|
|
1867
|
+
},
|
|
1868
|
+
"remove-discount": {
|
|
1869
|
+
consoleRole: "tenant-editor",
|
|
1870
|
+
oauthScope: "mcp:write",
|
|
1871
|
+
readOnly: false
|
|
1872
|
+
},
|
|
1873
|
+
checkout: {
|
|
1874
|
+
consoleRole: "tenant-admin",
|
|
1875
|
+
oauthScope: "mcp:write",
|
|
1876
|
+
readOnly: false
|
|
1877
|
+
},
|
|
1878
|
+
"create-order": {
|
|
1879
|
+
consoleRole: "tenant-admin",
|
|
1880
|
+
oauthScope: "mcp:write",
|
|
1881
|
+
readOnly: false
|
|
1882
|
+
},
|
|
1883
|
+
"update-order": {
|
|
1884
|
+
consoleRole: "tenant-admin",
|
|
1885
|
+
oauthScope: "mcp:write",
|
|
1886
|
+
readOnly: false
|
|
1887
|
+
},
|
|
1888
|
+
"create-fulfillment": {
|
|
1889
|
+
consoleRole: "tenant-admin",
|
|
1890
|
+
oauthScope: "mcp:write",
|
|
1891
|
+
readOnly: false
|
|
1892
|
+
},
|
|
1893
|
+
"update-fulfillment": {
|
|
1894
|
+
consoleRole: "tenant-admin",
|
|
1895
|
+
oauthScope: "mcp:write",
|
|
1896
|
+
readOnly: false
|
|
1897
|
+
},
|
|
1898
|
+
"create-return": {
|
|
1899
|
+
consoleRole: "tenant-admin",
|
|
1900
|
+
oauthScope: "mcp:write",
|
|
1901
|
+
readOnly: false
|
|
1902
|
+
},
|
|
1903
|
+
"update-return": {
|
|
1904
|
+
consoleRole: "tenant-admin",
|
|
1905
|
+
oauthScope: "mcp:write",
|
|
1906
|
+
readOnly: false
|
|
1907
|
+
},
|
|
1908
|
+
"return-with-refund": {
|
|
1909
|
+
consoleRole: "tenant-admin",
|
|
1910
|
+
oauthScope: "mcp:write",
|
|
1911
|
+
readOnly: false
|
|
1912
|
+
},
|
|
1913
|
+
"update-transaction": {
|
|
1914
|
+
consoleRole: "tenant-admin",
|
|
1915
|
+
oauthScope: "mcp:write",
|
|
1916
|
+
readOnly: false
|
|
1917
|
+
},
|
|
1918
|
+
"update-field-config": {
|
|
1919
|
+
consoleRole: "tenant-admin",
|
|
1920
|
+
oauthScope: "mcp:write",
|
|
1921
|
+
readOnly: false
|
|
1922
|
+
},
|
|
1923
|
+
"sdk-get-recipe": {
|
|
1924
|
+
consoleRole: "tenant-viewer",
|
|
1925
|
+
oauthScope: "mcp:read",
|
|
1926
|
+
readOnly: true
|
|
1927
|
+
},
|
|
1928
|
+
"sdk-search-docs": {
|
|
1929
|
+
consoleRole: "tenant-viewer",
|
|
1930
|
+
oauthScope: "mcp:read",
|
|
1931
|
+
readOnly: true
|
|
1932
|
+
},
|
|
1933
|
+
"sdk-get-auth-setup": {
|
|
1934
|
+
consoleRole: "tenant-viewer",
|
|
1935
|
+
oauthScope: "mcp:read",
|
|
1936
|
+
readOnly: true
|
|
1937
|
+
},
|
|
1938
|
+
"sdk-get-collection-pattern": {
|
|
1939
|
+
consoleRole: "tenant-viewer",
|
|
1940
|
+
oauthScope: "mcp:read",
|
|
1941
|
+
readOnly: true
|
|
1942
|
+
}
|
|
1943
|
+
};
|
|
1944
|
+
var MCP_TOOL_NAMES = Object.keys(MCP_TOOL_CONTRACT);
|
|
1700
1945
|
|
|
1701
1946
|
// src/commands/feature.ts
|
|
1702
1947
|
function getApiUrl2() {
|
|
@@ -1850,6 +2095,207 @@ Prerequisites:
|
|
|
1850
2095
|
});
|
|
1851
2096
|
}
|
|
1852
2097
|
|
|
2098
|
+
// src/commands/agent.ts
|
|
2099
|
+
import { COLLECTIONS as COLLECTIONS3 } from "@01.software/sdk";
|
|
2100
|
+
|
|
2101
|
+
// src/lib/agent-output.ts
|
|
2102
|
+
function stringifyAgentJson(data, options = {}) {
|
|
2103
|
+
return options.pretty ? JSON.stringify(data, null, 2) : JSON.stringify(data);
|
|
2104
|
+
}
|
|
2105
|
+
function asRecord(value) {
|
|
2106
|
+
return value && typeof value === "object" ? value : null;
|
|
2107
|
+
}
|
|
2108
|
+
function errorMessage(error) {
|
|
2109
|
+
const raw = asRecord(error);
|
|
2110
|
+
if (raw) {
|
|
2111
|
+
if (typeof raw.message === "string" && raw.message.length > 0) {
|
|
2112
|
+
return raw.message;
|
|
2113
|
+
}
|
|
2114
|
+
if (raw.detail && typeof raw.detail === "object" && typeof raw.detail.message === "string") {
|
|
2115
|
+
return String(raw.detail.message);
|
|
2116
|
+
}
|
|
2117
|
+
}
|
|
2118
|
+
if (error instanceof Error && error.message.length > 0) {
|
|
2119
|
+
return error.message;
|
|
2120
|
+
}
|
|
2121
|
+
if (typeof error === "string" && error.length > 0) {
|
|
2122
|
+
return error;
|
|
2123
|
+
}
|
|
2124
|
+
return "Internal error";
|
|
2125
|
+
}
|
|
2126
|
+
function isRawNotFound(error) {
|
|
2127
|
+
const raw = asRecord(error);
|
|
2128
|
+
return raw?.status === 404 || raw?.code === "not_found" || raw?.name === "GoneError";
|
|
2129
|
+
}
|
|
2130
|
+
function agentErrorExitCode(code) {
|
|
2131
|
+
switch (code) {
|
|
2132
|
+
case "INVALID_INPUT":
|
|
2133
|
+
return 2;
|
|
2134
|
+
case "AUTH_FAILED":
|
|
2135
|
+
return 3;
|
|
2136
|
+
case "NOT_FOUND":
|
|
2137
|
+
return 4;
|
|
2138
|
+
case "INTERNAL":
|
|
2139
|
+
return 1;
|
|
2140
|
+
}
|
|
2141
|
+
}
|
|
2142
|
+
function classifyAgentError(error) {
|
|
2143
|
+
const adminError = classifyError(error);
|
|
2144
|
+
const message = errorMessage(error);
|
|
2145
|
+
if (isRawNotFound(error) || adminError.code === "not_found") {
|
|
2146
|
+
return { error: { code: "NOT_FOUND", message } };
|
|
2147
|
+
}
|
|
2148
|
+
if (adminError.type === "permission") {
|
|
2149
|
+
return { error: { code: "AUTH_FAILED", message } };
|
|
2150
|
+
}
|
|
2151
|
+
if (adminError.type === "validation" && adminError.code !== "unknown") {
|
|
2152
|
+
return { error: { code: "INVALID_INPUT", message } };
|
|
2153
|
+
}
|
|
2154
|
+
return { error: { code: "INTERNAL", message } };
|
|
2155
|
+
}
|
|
2156
|
+
function printAgentSuccess(data, options = {}) {
|
|
2157
|
+
console.log(stringifyAgentJson(data, options));
|
|
2158
|
+
}
|
|
2159
|
+
function printAgentError(error, options = {}) {
|
|
2160
|
+
const envelope = classifyAgentError(error);
|
|
2161
|
+
console.log(stringifyAgentJson(envelope, options));
|
|
2162
|
+
return envelope;
|
|
2163
|
+
}
|
|
2164
|
+
function exitWithAgentError(error, options = {}) {
|
|
2165
|
+
const envelope = printAgentError(error, options);
|
|
2166
|
+
process.exit(agentErrorExitCode(envelope.error.code));
|
|
2167
|
+
}
|
|
2168
|
+
|
|
2169
|
+
// src/commands/agent.ts
|
|
2170
|
+
var AGENT_PROTOCOL_VERSION = "1";
|
|
2171
|
+
function buildStableAgentFields() {
|
|
2172
|
+
return {
|
|
2173
|
+
id: { type: "string", queryable: true },
|
|
2174
|
+
createdAt: { type: "string", queryable: true },
|
|
2175
|
+
updatedAt: { type: "string", queryable: true }
|
|
2176
|
+
};
|
|
2177
|
+
}
|
|
2178
|
+
function invalidInput(message, field, value) {
|
|
2179
|
+
const error = new Error(message);
|
|
2180
|
+
Object.assign(error, {
|
|
2181
|
+
type: "validation",
|
|
2182
|
+
code: "invalid_argument",
|
|
2183
|
+
field,
|
|
2184
|
+
detail: { message, value, field }
|
|
2185
|
+
});
|
|
2186
|
+
return error;
|
|
2187
|
+
}
|
|
2188
|
+
function parsePositiveInteger(value, field) {
|
|
2189
|
+
if (value == null) return void 0;
|
|
2190
|
+
if (/^[1-9]\d*$/.test(value)) return Number(value);
|
|
2191
|
+
throw invalidInput(`--${field} must be a positive integer`, field, value);
|
|
2192
|
+
}
|
|
2193
|
+
function handleCommanderError(error) {
|
|
2194
|
+
if (error.code === "commander.helpDisplayed") {
|
|
2195
|
+
process.exit(error.exitCode);
|
|
2196
|
+
}
|
|
2197
|
+
exitWithAgentError(invalidInput(error.message, "command"));
|
|
2198
|
+
}
|
|
2199
|
+
function configureAgentParser(command) {
|
|
2200
|
+
command.configureOutput({
|
|
2201
|
+
writeErr: () => {
|
|
2202
|
+
},
|
|
2203
|
+
writeOut: (str) => {
|
|
2204
|
+
process.stdout.write(str);
|
|
2205
|
+
}
|
|
2206
|
+
});
|
|
2207
|
+
command.exitOverride(handleCommanderError);
|
|
2208
|
+
return command;
|
|
2209
|
+
}
|
|
2210
|
+
function parseWhere(value) {
|
|
2211
|
+
if (value == null) return void 0;
|
|
2212
|
+
try {
|
|
2213
|
+
const parsed = JSON.parse(value);
|
|
2214
|
+
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
2215
|
+
return parsed;
|
|
2216
|
+
}
|
|
2217
|
+
} catch {
|
|
2218
|
+
throw invalidInput("--where must be a JSON object", "where", value);
|
|
2219
|
+
}
|
|
2220
|
+
throw invalidInput("--where must be a JSON object", "where", value);
|
|
2221
|
+
}
|
|
2222
|
+
function buildAgentManifest() {
|
|
2223
|
+
const collections = {};
|
|
2224
|
+
for (const collection of COLLECTIONS3) {
|
|
2225
|
+
collections[collection] = {
|
|
2226
|
+
operations: ["query", "get"],
|
|
2227
|
+
fields: buildStableAgentFields()
|
|
2228
|
+
};
|
|
2229
|
+
}
|
|
2230
|
+
return {
|
|
2231
|
+
version: AGENT_PROTOCOL_VERSION,
|
|
2232
|
+
collections
|
|
2233
|
+
};
|
|
2234
|
+
}
|
|
2235
|
+
function validateAgentCollection(collection) {
|
|
2236
|
+
try {
|
|
2237
|
+
return validateCollection(collection);
|
|
2238
|
+
} catch (error) {
|
|
2239
|
+
const message = error instanceof Error ? error.message : `Unknown collection "${collection}".`;
|
|
2240
|
+
throw invalidInput(message, "collection", collection);
|
|
2241
|
+
}
|
|
2242
|
+
}
|
|
2243
|
+
function registerAgentCommands(program2, getClient2) {
|
|
2244
|
+
const agent = configureAgentParser(
|
|
2245
|
+
program2.command("agent").description("Machine-stable CLI namespace for coding agents").addHelpText(
|
|
2246
|
+
"after",
|
|
2247
|
+
"\nContract: docs/agent-cli-contract.md\nJSON only on stdout; no TTY effects."
|
|
2248
|
+
)
|
|
2249
|
+
);
|
|
2250
|
+
configureAgentParser(
|
|
2251
|
+
agent.command("manifest").description("Print the Agent CLI protocol manifest").option("--pretty", "Print 2-space indented JSON").action((opts) => {
|
|
2252
|
+
printAgentSuccess(buildAgentManifest(), { pretty: Boolean(opts.pretty) });
|
|
2253
|
+
})
|
|
2254
|
+
);
|
|
2255
|
+
configureAgentParser(
|
|
2256
|
+
agent.command("query <collection>").description("Query documents from a collection").option("--where <json>", "Filter conditions as a JSON object").option("--limit <n>", "Max results").option("--page <n>", "Page number").option("--sort <field>", "Sort field; prefix with - for descending").option("--select <fields>", "Comma-separated fields to select").option("--pretty", "Print 2-space indented JSON").action(
|
|
2257
|
+
async (collection, opts) => {
|
|
2258
|
+
try {
|
|
2259
|
+
const col = validateAgentCollection(collection);
|
|
2260
|
+
const options = {};
|
|
2261
|
+
const where = parseWhere(opts.where);
|
|
2262
|
+
const limit = parsePositiveInteger(opts.limit, "limit");
|
|
2263
|
+
const page = parsePositiveInteger(opts.page, "page");
|
|
2264
|
+
if (where) options.where = where;
|
|
2265
|
+
if (limit != null) options.limit = limit;
|
|
2266
|
+
if (page != null) options.page = page;
|
|
2267
|
+
if (opts.sort) options.sort = opts.sort;
|
|
2268
|
+
if (opts.select) options.select = parseSelect(opts.select);
|
|
2269
|
+
const client = getClient2();
|
|
2270
|
+
const result = await client.collections.from(col).find(options);
|
|
2271
|
+
printAgentSuccess(result, { pretty: Boolean(opts.pretty) });
|
|
2272
|
+
} catch (error) {
|
|
2273
|
+
exitWithAgentError(error, { pretty: Boolean(opts.pretty) });
|
|
2274
|
+
}
|
|
2275
|
+
}
|
|
2276
|
+
)
|
|
2277
|
+
);
|
|
2278
|
+
configureAgentParser(
|
|
2279
|
+
agent.command("get <collection> [id]").description("Get a document by ID").option("--select <fields>", "Comma-separated fields to select").option("--pretty", "Print 2-space indented JSON").action(
|
|
2280
|
+
async (collection, id, opts) => {
|
|
2281
|
+
try {
|
|
2282
|
+
const col = validateAgentCollection(collection);
|
|
2283
|
+
if (!id) {
|
|
2284
|
+
throw invalidInput("Missing required argument: id", "id");
|
|
2285
|
+
}
|
|
2286
|
+
const options = {};
|
|
2287
|
+
if (opts.select) options.select = parseSelect(opts.select);
|
|
2288
|
+
const client = getClient2();
|
|
2289
|
+
const result = await client.collections.from(col).findById(id, options);
|
|
2290
|
+
printAgentSuccess(result, { pretty: Boolean(opts.pretty) });
|
|
2291
|
+
} catch (error) {
|
|
2292
|
+
exitWithAgentError(error, { pretty: Boolean(opts.pretty) });
|
|
2293
|
+
}
|
|
2294
|
+
}
|
|
2295
|
+
)
|
|
2296
|
+
);
|
|
2297
|
+
}
|
|
2298
|
+
|
|
1853
2299
|
// src/index.ts
|
|
1854
2300
|
var require2 = createRequire(import.meta.url);
|
|
1855
2301
|
var { version } = require2("../package.json");
|
|
@@ -1865,6 +2311,8 @@ process.on("unhandledRejection", (err) => {
|
|
|
1865
2311
|
exitWithError(err, { format: getFormat() });
|
|
1866
2312
|
});
|
|
1867
2313
|
var getClient = () => resolveClient(program.opts().apiKey);
|
|
2314
|
+
var getAgentClient = () => resolveClientOrThrow(program.opts().apiKey);
|
|
2315
|
+
registerAgentCommands(program, getAgentClient);
|
|
1868
2316
|
registerCrudCommands(program, getClient, getFormat);
|
|
1869
2317
|
registerOrderCommands(program, getClient, getFormat);
|
|
1870
2318
|
registerReturnCommands(program, getClient, getFormat);
|