@paybond/kit 0.9.8 → 0.10.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 (58) hide show
  1. package/dist/cli/audit-export.d.ts +7 -0
  2. package/dist/cli/audit-export.js +120 -0
  3. package/dist/cli/automation.d.ts +25 -0
  4. package/dist/cli/automation.js +297 -0
  5. package/dist/cli/body.d.ts +7 -0
  6. package/dist/cli/body.js +22 -0
  7. package/dist/cli/color.d.ts +15 -0
  8. package/dist/cli/color.js +39 -0
  9. package/dist/cli/command-spec.d.ts +12 -0
  10. package/dist/cli/command-spec.js +330 -0
  11. package/dist/cli/commands/discovery.d.ts +8 -0
  12. package/dist/cli/commands/discovery.js +194 -0
  13. package/dist/cli/commands/setup.d.ts +15 -0
  14. package/dist/cli/commands/setup.js +397 -0
  15. package/dist/cli/commands/workflows.d.ts +7 -0
  16. package/dist/cli/commands/workflows.js +209 -0
  17. package/dist/cli/config.d.ts +14 -0
  18. package/dist/cli/config.js +96 -0
  19. package/dist/cli/context.d.ts +22 -0
  20. package/dist/cli/context.js +109 -0
  21. package/dist/cli/credentials.d.ts +21 -0
  22. package/dist/cli/credentials.js +141 -0
  23. package/dist/cli/doctor-agent.d.ts +15 -0
  24. package/dist/cli/doctor-agent.js +311 -0
  25. package/dist/cli/envelope.d.ts +14 -0
  26. package/dist/cli/envelope.js +46 -0
  27. package/dist/cli/globals.d.ts +22 -0
  28. package/dist/cli/globals.js +238 -0
  29. package/dist/cli/help.d.ts +3 -0
  30. package/dist/cli/help.js +51 -0
  31. package/dist/cli/mcp-install.d.ts +41 -0
  32. package/dist/cli/mcp-install.js +95 -0
  33. package/dist/cli/mcp-policy.d.ts +23 -0
  34. package/dist/cli/mcp-policy.js +104 -0
  35. package/dist/cli/mcp-verify-config.d.ts +37 -0
  36. package/dist/cli/mcp-verify-config.js +174 -0
  37. package/dist/cli/redact.d.ts +4 -0
  38. package/dist/cli/redact.js +67 -0
  39. package/dist/cli/request-id.d.ts +2 -0
  40. package/dist/cli/request-id.js +5 -0
  41. package/dist/cli/router.d.ts +2 -0
  42. package/dist/cli/router.js +275 -0
  43. package/dist/cli/suggest.d.ts +4 -0
  44. package/dist/cli/suggest.js +58 -0
  45. package/dist/cli/support-diagnostics.d.ts +19 -0
  46. package/dist/cli/support-diagnostics.js +47 -0
  47. package/dist/cli/types.d.ts +72 -0
  48. package/dist/cli/types.js +60 -0
  49. package/dist/cli/ux.d.ts +8 -0
  50. package/dist/cli/ux.js +164 -0
  51. package/dist/cli.d.ts +2 -0
  52. package/dist/cli.js +38 -0
  53. package/dist/init.js +9 -14
  54. package/dist/login.d.ts +14 -1
  55. package/dist/login.js +123 -63
  56. package/dist/mcp-server.d.ts +4 -0
  57. package/dist/mcp-server.js +204 -76
  58. package/package.json +5 -2
@@ -0,0 +1,7 @@
1
+ export declare const MANIFEST_CORE_FIELD_ORDER: readonly ["schema_version", "kind", "tenant_realm_id", "job_id", "generated_at_rfc3339", "gateway_build_version", "score_model_version", "disclosure_tier", "redaction_profile", "checkpoint_last_ledger_seq", "export_filter", "artifacts"];
2
+ export declare function buildManifestCore(manifest: Record<string, unknown>): Record<string, unknown>;
3
+ export declare function manifestCoreBytes(manifest: Record<string, unknown>): Uint8Array;
4
+ export declare function verifyAuditManifest(manifest: Record<string, unknown>): boolean;
5
+ export declare function auditVerifyResult(manifest: Record<string, unknown>, path: string): Record<string, unknown>;
6
+ export declare function readManifestFromBundle(bundlePath: string, cwd: string): Promise<string>;
7
+ export declare function verifyAuditBundleLocal(path: string, cwd: string): Promise<Record<string, unknown>>;
@@ -0,0 +1,120 @@
1
+ import { createHash } from "node:crypto";
2
+ import { readFile } from "node:fs/promises";
3
+ import { spawn } from "node:child_process";
4
+ import { verify as ed25519Verify } from "@noble/ed25519";
5
+ import { ensureEd25519Sha512Sync } from "../ed25519-sync.js";
6
+ import { CliError } from "./types.js";
7
+ export const MANIFEST_CORE_FIELD_ORDER = [
8
+ "schema_version",
9
+ "kind",
10
+ "tenant_realm_id",
11
+ "job_id",
12
+ "generated_at_rfc3339",
13
+ "gateway_build_version",
14
+ "score_model_version",
15
+ "disclosure_tier",
16
+ "redaction_profile",
17
+ "checkpoint_last_ledger_seq",
18
+ "export_filter",
19
+ "artifacts",
20
+ ];
21
+ export function buildManifestCore(manifest) {
22
+ const core = {};
23
+ for (const key of MANIFEST_CORE_FIELD_ORDER) {
24
+ if (key === "checkpoint_last_ledger_seq") {
25
+ if (!(key in manifest)) {
26
+ continue;
27
+ }
28
+ const value = manifest[key];
29
+ if (value === 0 || value === null) {
30
+ continue;
31
+ }
32
+ core[key] = value;
33
+ continue;
34
+ }
35
+ if (key in manifest) {
36
+ core[key] = manifest[key];
37
+ }
38
+ }
39
+ return core;
40
+ }
41
+ export function manifestCoreBytes(manifest) {
42
+ const core = buildManifestCore(manifest);
43
+ return new TextEncoder().encode(JSON.stringify(core));
44
+ }
45
+ function hexToBytes(hex) {
46
+ const normalized = hex.trim();
47
+ const out = new Uint8Array(normalized.length / 2);
48
+ for (let i = 0; i < out.length; i += 1) {
49
+ out[i] = Number.parseInt(normalized.slice(i * 2, i * 2 + 2), 16);
50
+ }
51
+ return out;
52
+ }
53
+ function bytesToHex(bytes) {
54
+ return Array.from(bytes)
55
+ .map((byte) => byte.toString(16).padStart(2, "0"))
56
+ .join("");
57
+ }
58
+ export function verifyAuditManifest(manifest) {
59
+ const coreBytes = manifestCoreBytes(manifest);
60
+ const digest = createHash("sha256").update(coreBytes).digest();
61
+ const expected = String(manifest.signed_payload_sha256_hex ?? "").trim().toLowerCase();
62
+ if (bytesToHex(new Uint8Array(digest)) !== expected) {
63
+ return false;
64
+ }
65
+ const signatureHex = String(manifest.ed25519_signature_hex ?? "").trim();
66
+ const publicKeyHex = String(manifest.signing_public_key_ed25519_hex ?? "").trim();
67
+ if (!signatureHex || !publicKeyHex) {
68
+ return false;
69
+ }
70
+ ensureEd25519Sha512Sync();
71
+ return ed25519Verify(hexToBytes(signatureHex), digest, hexToBytes(publicKeyHex));
72
+ }
73
+ export function auditVerifyResult(manifest, path) {
74
+ return {
75
+ verified: verifyAuditManifest(manifest),
76
+ manifest_kind: String(manifest.kind ?? ""),
77
+ tenant_realm_id: String(manifest.tenant_realm_id ?? ""),
78
+ job_id: String(manifest.job_id ?? ""),
79
+ path,
80
+ };
81
+ }
82
+ export async function readManifestFromBundle(bundlePath, cwd) {
83
+ if (bundlePath.endsWith(".zip")) {
84
+ const result = await new Promise((resolvePromise) => {
85
+ const child = spawn("unzip", ["-p", bundlePath, "manifest.json"], { cwd });
86
+ let stdout = "";
87
+ let stderr = "";
88
+ child.stdout.on("data", (chunk) => {
89
+ stdout += String(chunk);
90
+ });
91
+ child.stderr.on("data", (chunk) => {
92
+ stderr += String(chunk);
93
+ });
94
+ child.on("close", (code) => resolvePromise({ code, stdout, stderr }));
95
+ child.on("error", () => resolvePromise({ code: 127, stdout: "", stderr: "unzip not found" }));
96
+ });
97
+ if (result.code !== 0 || !result.stdout.trim()) {
98
+ throw new CliError(result.stderr.trim() || "unable to read manifest.json from ZIP bundle", {
99
+ category: "validation",
100
+ code: "cli.audit.bundle_read_failed",
101
+ });
102
+ }
103
+ return result.stdout;
104
+ }
105
+ const manifestPath = bundlePath.endsWith("manifest.json")
106
+ ? bundlePath
107
+ : `${bundlePath.replace(/\/+$/, "")}/manifest.json`;
108
+ return readFile(manifestPath, "utf8");
109
+ }
110
+ export async function verifyAuditBundleLocal(path, cwd) {
111
+ const manifestRaw = await readManifestFromBundle(path, cwd);
112
+ const manifest = JSON.parse(manifestRaw);
113
+ if (!manifest || typeof manifest !== "object" || Array.isArray(manifest)) {
114
+ throw new CliError("manifest.json must be a JSON object", {
115
+ category: "validation",
116
+ code: "cli.audit.invalid_manifest",
117
+ });
118
+ }
119
+ return auditVerifyResult(manifest, path);
120
+ }
@@ -0,0 +1,25 @@
1
+ /** Stable machine-readable warning codes for automation consumers. */
2
+ export declare const CLI_WARN_PARTIAL_RESULTS = "cli.warn.partial_results";
3
+ export declare const CLI_WARN_GATEWAY_RETRY = "cli.warn.gateway_retry";
4
+ export declare const CLI_WARN_DEPRECATED_ALIAS = "cli.warn.deprecated_alias";
5
+ export declare const CLI_WARN_ENV_FALLBACK = "cli.warn.env_fallback";
6
+ export declare function formatWarning(code: string, detail?: string): string;
7
+ export declare function deprecatedAliasWarning(argv0: string | undefined): string | undefined;
8
+ export declare function parseJsonFields(raw: string): string[];
9
+ export declare function selectJsonFields(rows: Record<string, unknown>[], fields: string[]): Record<string, unknown>[];
10
+ export declare function extractListArray(data: Record<string, unknown>): Record<string, unknown>[] | null;
11
+ export declare function applyJsonFieldSelection(command: string, data: Record<string, unknown>, fields: string[]): Record<string, unknown> | Record<string, unknown>[];
12
+ export declare function applyJqFilter(data: unknown, expr: string): unknown;
13
+ export declare function supportsAutomationOutput(command: string): boolean;
14
+ export declare function applyAutomationTransforms(command: string, data: Record<string, unknown>, options: {
15
+ jsonFields?: string;
16
+ jqExpr?: string;
17
+ }): unknown;
18
+ export declare function extractNextCursor(body: Record<string, unknown>): string | undefined;
19
+ export declare function partialResultsWarning(nextCursor: string | undefined): string | undefined;
20
+ export declare function buildListQueryParams(limit: string | undefined, cursor: string | undefined, defaults?: {
21
+ limit?: string;
22
+ }): URLSearchParams;
23
+ export declare function readJsonBody(source: string, stdin?: NodeJS.ReadableStream): Promise<Record<string, unknown>>;
24
+ export declare function writeAtomicFile(path: string, content: string | Uint8Array, mode?: number): void;
25
+ export declare function writeAtomicFileAsync(path: string, content: string | Uint8Array, mode?: number): Promise<void>;
@@ -0,0 +1,297 @@
1
+ import { spawnSync } from "node:child_process";
2
+ import { mkdtempSync, renameSync, rmSync, writeFileSync, chmodSync } from "node:fs";
3
+ import { readFile } from "node:fs/promises";
4
+ import { tmpdir } from "node:os";
5
+ import { dirname, join } from "node:path";
6
+ import { CliError } from "./types.js";
7
+ /** Stable machine-readable warning codes for automation consumers. */
8
+ export const CLI_WARN_PARTIAL_RESULTS = "cli.warn.partial_results";
9
+ export const CLI_WARN_GATEWAY_RETRY = "cli.warn.gateway_retry";
10
+ export const CLI_WARN_DEPRECATED_ALIAS = "cli.warn.deprecated_alias";
11
+ export const CLI_WARN_ENV_FALLBACK = "cli.warn.env_fallback";
12
+ export function formatWarning(code, detail) {
13
+ return detail ? `${code}: ${detail}` : code;
14
+ }
15
+ const LEGACY_INVOCATION_ALIASES = {
16
+ "paybond-kit-login": "paybond login",
17
+ "paybond-init": "paybond init guardrail",
18
+ "paybond-kit-init": "paybond init guardrail",
19
+ "paybond-mcp-server": "paybond mcp serve",
20
+ };
21
+ export function deprecatedAliasWarning(argv0) {
22
+ const base = (argv0 ?? "").split(/[/\\]/).pop() ?? "";
23
+ const canonical = LEGACY_INVOCATION_ALIASES[base];
24
+ if (!canonical) {
25
+ return undefined;
26
+ }
27
+ return formatWarning(CLI_WARN_DEPRECATED_ALIAS, `use ${canonical} instead of ${base}`);
28
+ }
29
+ export function parseJsonFields(raw) {
30
+ const fields = raw
31
+ .split(",")
32
+ .map((part) => part.trim())
33
+ .filter(Boolean);
34
+ if (fields.length === 0) {
35
+ throw new CliError("invalid --json (expected comma-separated field names)", {
36
+ category: "usage",
37
+ code: "cli.usage.invalid_json_fields",
38
+ });
39
+ }
40
+ return fields;
41
+ }
42
+ function readNestedField(row, field) {
43
+ const parts = field.split(".").filter(Boolean);
44
+ let current = row;
45
+ for (const part of parts) {
46
+ if (!current || typeof current !== "object" || Array.isArray(current)) {
47
+ return undefined;
48
+ }
49
+ current = current[part];
50
+ }
51
+ return current;
52
+ }
53
+ export function selectJsonFields(rows, fields) {
54
+ return rows.map((row) => {
55
+ const selected = {};
56
+ for (const field of fields) {
57
+ const value = field.includes(".") ? readNestedField(row, field) : row[field];
58
+ if (field.includes(".")) {
59
+ selected[field] = value;
60
+ }
61
+ else {
62
+ selected[field] = value;
63
+ }
64
+ }
65
+ return selected;
66
+ });
67
+ }
68
+ const LIST_ARRAY_KEYS = ["items", "keys", "exports", "intents", "tools", "entries", "contracts", "jobs"];
69
+ export function extractListArray(data) {
70
+ for (const key of LIST_ARRAY_KEYS) {
71
+ const value = data[key];
72
+ if (Array.isArray(value)) {
73
+ return value.filter((item) => Boolean(item) && typeof item === "object" && !Array.isArray(item));
74
+ }
75
+ }
76
+ return null;
77
+ }
78
+ export function applyJsonFieldSelection(command, data, fields) {
79
+ const rows = extractListArray(data);
80
+ if (rows) {
81
+ return selectJsonFields(rows, fields);
82
+ }
83
+ return selectJsonFields([data], fields)[0] ?? {};
84
+ }
85
+ function trySimpleJqPath(data, expr) {
86
+ const trimmed = expr.trim();
87
+ if (!trimmed || trimmed === ".") {
88
+ return data;
89
+ }
90
+ const pipeParts = trimmed.split("|").map((part) => part.trim());
91
+ let current = data;
92
+ for (const part of pipeParts) {
93
+ if (part === ".") {
94
+ continue;
95
+ }
96
+ if (part === ".[]") {
97
+ if (!Array.isArray(current)) {
98
+ return undefined;
99
+ }
100
+ current = current;
101
+ continue;
102
+ }
103
+ if (part.endsWith("[]")) {
104
+ const key = part.slice(0, -2);
105
+ if (key === ".") {
106
+ if (!Array.isArray(current)) {
107
+ return undefined;
108
+ }
109
+ continue;
110
+ }
111
+ if (!key.startsWith(".") || !current || typeof current !== "object" || Array.isArray(current)) {
112
+ return undefined;
113
+ }
114
+ const field = key.slice(1);
115
+ const nested = current[field];
116
+ if (!Array.isArray(nested)) {
117
+ return undefined;
118
+ }
119
+ current = nested;
120
+ continue;
121
+ }
122
+ if (part.startsWith(".")) {
123
+ const arraySubfield = part.match(/^\.([^.[]+)(\[\])(?:\.(.+))?$/);
124
+ if (arraySubfield) {
125
+ const [, field, , subfield] = arraySubfield;
126
+ if (!current || typeof current !== "object" || Array.isArray(current)) {
127
+ return undefined;
128
+ }
129
+ const nested = current[field];
130
+ if (!Array.isArray(nested)) {
131
+ return undefined;
132
+ }
133
+ if (!subfield) {
134
+ current = nested;
135
+ continue;
136
+ }
137
+ current = nested.map((item) => item && typeof item === "object" && !Array.isArray(item)
138
+ ? item[subfield]
139
+ : undefined);
140
+ continue;
141
+ }
142
+ const pathParts = part.slice(1).split(".").filter(Boolean);
143
+ for (const segment of pathParts) {
144
+ if (!current || typeof current !== "object" || Array.isArray(current)) {
145
+ return undefined;
146
+ }
147
+ current = current[segment];
148
+ }
149
+ continue;
150
+ }
151
+ return undefined;
152
+ }
153
+ return current;
154
+ }
155
+ function runJqBinary(data, expr) {
156
+ try {
157
+ const result = spawnSync("jq", ["-c", expr], {
158
+ input: JSON.stringify(data),
159
+ encoding: "utf8",
160
+ maxBuffer: 10 * 1024 * 1024,
161
+ });
162
+ if (result.status !== 0 || result.error) {
163
+ return undefined;
164
+ }
165
+ const output = result.stdout.trim();
166
+ if (!output) {
167
+ return null;
168
+ }
169
+ return JSON.parse(output);
170
+ }
171
+ catch {
172
+ return undefined;
173
+ }
174
+ }
175
+ export function applyJqFilter(data, expr) {
176
+ const trimmed = expr.trim();
177
+ if (!trimmed || trimmed === ".") {
178
+ return data;
179
+ }
180
+ const simple = trySimpleJqPath(data, trimmed);
181
+ if (simple !== undefined) {
182
+ return simple;
183
+ }
184
+ const fromBinary = runJqBinary(data, trimmed);
185
+ if (fromBinary !== undefined) {
186
+ return fromBinary;
187
+ }
188
+ throw new CliError(`invalid --jq expression: ${expr}`, {
189
+ category: "usage",
190
+ code: "cli.usage.invalid_jq",
191
+ });
192
+ }
193
+ export function supportsAutomationOutput(command) {
194
+ return (command.endsWith(" list") ||
195
+ command.endsWith(" get") ||
196
+ command === "whoami" ||
197
+ command === "mcp tools" ||
198
+ command === "a2a contracts" ||
199
+ command === "a2a card");
200
+ }
201
+ export function applyAutomationTransforms(command, data, options) {
202
+ if (!supportsAutomationOutput(command)) {
203
+ if (options.jsonFields || options.jqExpr) {
204
+ throw new CliError(`--json/--jq are not supported for ${command}`, {
205
+ category: "usage",
206
+ code: "cli.usage.automation_unsupported",
207
+ });
208
+ }
209
+ return data;
210
+ }
211
+ let current = data;
212
+ if (options.jsonFields) {
213
+ current = applyJsonFieldSelection(command, data, parseJsonFields(options.jsonFields));
214
+ }
215
+ if (options.jqExpr) {
216
+ current = applyJqFilter(current, options.jqExpr);
217
+ }
218
+ return current;
219
+ }
220
+ export function extractNextCursor(body) {
221
+ const raw = body.next_cursor ?? body.nextCursor ?? body.cursor_next;
222
+ if (typeof raw === "string" && raw.trim()) {
223
+ return raw.trim();
224
+ }
225
+ return undefined;
226
+ }
227
+ export function partialResultsWarning(nextCursor) {
228
+ if (!nextCursor) {
229
+ return undefined;
230
+ }
231
+ return formatWarning(CLI_WARN_PARTIAL_RESULTS, "more items available; pass --cursor");
232
+ }
233
+ export function buildListQueryParams(limit, cursor, defaults = {}) {
234
+ const params = new URLSearchParams({ limit: limit?.trim() || defaults.limit || "20" });
235
+ if (cursor?.trim()) {
236
+ params.set("cursor", cursor.trim());
237
+ }
238
+ return params;
239
+ }
240
+ export async function readJsonBody(source, stdin) {
241
+ const normalized = source.trim();
242
+ let raw;
243
+ if (normalized === "-" || normalized === "stdin") {
244
+ if (!stdin) {
245
+ throw new CliError("JSON body requires --body - with stdin piped in", {
246
+ category: "usage",
247
+ code: "cli.usage.missing_stdin",
248
+ });
249
+ }
250
+ const chunks = [];
251
+ for await (const chunk of stdin) {
252
+ chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(String(chunk)));
253
+ }
254
+ raw = Buffer.concat(chunks).toString("utf8");
255
+ }
256
+ else {
257
+ raw = await readFile(normalized, "utf8");
258
+ }
259
+ const parsed = JSON.parse(raw);
260
+ if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
261
+ throw new CliError("JSON body must be an object", { category: "validation", code: "cli.validation.invalid_json_body" });
262
+ }
263
+ return parsed;
264
+ }
265
+ export function writeAtomicFile(path, content, mode = 0o600) {
266
+ const dir = dirname(path);
267
+ const prefix = join(dir, ".paybond-write-");
268
+ const tempDir = mkdtempSync(prefix);
269
+ const tempFile = join(tempDir, "payload");
270
+ try {
271
+ writeFileSync(tempFile, content);
272
+ chmodSync(tempFile, mode);
273
+ renameSync(tempFile, path);
274
+ rmSync(tempDir, { recursive: true, force: true });
275
+ }
276
+ catch (err) {
277
+ rmSync(tempDir, { recursive: true, force: true });
278
+ throw err;
279
+ }
280
+ }
281
+ export async function writeAtomicFileAsync(path, content, mode = 0o600) {
282
+ const { mkdir, writeFile, chmod, rename, rm } = await import("node:fs/promises");
283
+ const dir = dirname(path);
284
+ await mkdir(dir, { recursive: true });
285
+ const tempDir = await import("node:fs/promises").then((mod) => mod.mkdtemp(join(tmpdir(), "paybond-write-")));
286
+ const tempFile = join(tempDir, "payload");
287
+ try {
288
+ await writeFile(tempFile, content);
289
+ await chmod(tempFile, mode);
290
+ await rename(tempFile, path);
291
+ await rm(tempDir, { recursive: true, force: true });
292
+ }
293
+ catch (err) {
294
+ await rm(tempDir, { recursive: true, force: true });
295
+ throw err;
296
+ }
297
+ }
@@ -0,0 +1,7 @@
1
+ export declare function resolveJsonBody(argv: string[], options?: {
2
+ required?: boolean;
3
+ missingMessage?: string;
4
+ }): Promise<{
5
+ payload: Record<string, unknown>;
6
+ rest: string[];
7
+ }>;
@@ -0,0 +1,22 @@
1
+ import { consumeBooleanFlag, consumeFlag } from "./globals.js";
2
+ import { readJsonBody } from "./automation.js";
3
+ import { CliError } from "./types.js";
4
+ export async function resolveJsonBody(argv, options) {
5
+ const required = options?.required ?? true;
6
+ const missingMessage = options?.missingMessage ?? "missing JSON body; pass --body <json-file> or --stdin";
7
+ const stdinFlag = consumeBooleanFlag(argv, "--stdin");
8
+ if (stdinFlag.present) {
9
+ return { payload: await readJsonBody("-", process.stdin), rest: stdinFlag.rest };
10
+ }
11
+ const bodyFlag = consumeFlag(stdinFlag.rest, "--body");
12
+ if (!bodyFlag.value) {
13
+ if (!required) {
14
+ return { payload: {}, rest: bodyFlag.rest };
15
+ }
16
+ throw new CliError(missingMessage, {
17
+ category: "usage",
18
+ code: "cli.usage.missing_body",
19
+ });
20
+ }
21
+ return { payload: await readJsonBody(bodyFlag.value, process.stdin), rest: bodyFlag.rest };
22
+ }
@@ -0,0 +1,15 @@
1
+ import type { ColorMode, GlobalOptions } from "./types.js";
2
+ declare const ANSI: {
3
+ readonly reset: "\u001B[0m";
4
+ readonly bold: "\u001B[1m";
5
+ readonly dim: "\u001B[2m";
6
+ readonly green: "\u001B[32m";
7
+ readonly yellow: "\u001B[33m";
8
+ readonly cyan: "\u001B[36m";
9
+ };
10
+ export type AnsiStyle = keyof typeof ANSI;
11
+ export declare function resolveColorModeFromEnv(env?: NodeJS.ProcessEnv): ColorMode;
12
+ export declare function parseColorMode(raw: string): ColorMode;
13
+ export declare function shouldUseColor(globals: GlobalOptions, isTTY?: boolean): boolean;
14
+ export declare function colorize(text: string, style: AnsiStyle, enabled: boolean): string;
15
+ export {};
@@ -0,0 +1,39 @@
1
+ const ANSI = {
2
+ reset: "\x1b[0m",
3
+ bold: "\x1b[1m",
4
+ dim: "\x1b[2m",
5
+ green: "\x1b[32m",
6
+ yellow: "\x1b[33m",
7
+ cyan: "\x1b[36m",
8
+ };
9
+ export function resolveColorModeFromEnv(env = process.env) {
10
+ if (env.NO_COLOR !== undefined && env.NO_COLOR.trim() !== "") {
11
+ return "never";
12
+ }
13
+ return "auto";
14
+ }
15
+ export function parseColorMode(raw) {
16
+ const value = raw.trim().toLowerCase();
17
+ if (value === "auto" || value === "always" || value === "never") {
18
+ return value;
19
+ }
20
+ throw new Error("invalid --color (expected auto|always|never)");
21
+ }
22
+ export function shouldUseColor(globals, isTTY = process.stdout.isTTY === true) {
23
+ if (globals.format === "json") {
24
+ return false;
25
+ }
26
+ if (globals.color === "never") {
27
+ return false;
28
+ }
29
+ if (globals.color === "always") {
30
+ return true;
31
+ }
32
+ return isTTY;
33
+ }
34
+ export function colorize(text, style, enabled) {
35
+ if (!enabled) {
36
+ return text;
37
+ }
38
+ return `${ANSI[style]}${text}${ANSI.reset}`;
39
+ }
@@ -0,0 +1,12 @@
1
+ export declare const COMMAND_PATHS: string[];
2
+ export declare const GLOBAL_FLAG_NAMES: string[];
3
+ export declare const COMMAND_EXAMPLES: Record<string, string[]>;
4
+ export declare const COMPLETIONS: Record<string, string[]>;
5
+ export declare const WORKFLOWS: Array<{
6
+ title: string;
7
+ description?: string;
8
+ examples: string[];
9
+ next?: string;
10
+ }>;
11
+ export declare const DOCS_BASE_URL = "https://docs.paybond.ai/kit";
12
+ export declare const COMPLETION_SCRIPTS: Record<"bash" | "zsh" | "fish", string>;