@sentroy-co/client-sdk 2.8.0 → 2.9.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.
package/AGENTS.md CHANGED
@@ -774,6 +774,43 @@ function ConfigPanel() {
774
774
  - The bootstrap token is per-(project, environment). A `prod` token cannot read `staging` and vice versa.
775
775
  - Variable values are AES-256-GCM encrypted at rest in the Sentroy vault DB. Decryption happens server-side just before the fetch endpoint streams the response.
776
776
 
777
+ ### CLI (`sentroy env ...`)
778
+
779
+ The package ships a `sentroy` binary. After `npm install` (or `npm install -g`) it's available on `PATH`; `npx sentroy ...` works without a global install.
780
+
781
+ Auth is the same `SENTROY_ENV_API_KEY` used by `getEnv()` (or pass `--token=stk_env_...`). Base URL defaults to `https://sentroy.com` (override with `SENTROY_ENV_API_URL` or `--url=`). The token's (project, environment) scope is implicit — never specified on the CLI.
782
+
783
+ ```bash
784
+ # Push a local file to the vault. Without --delete-missing it's upsert-only.
785
+ # With --delete-missing it's a full sync — any vault key not in the file
786
+ # is removed (CLI prompts for confirmation interactively).
787
+ sentroy env push .env.production --delete-missing
788
+ sentroy env push .env.production --dry-run # show diff, no writes
789
+
790
+ # Diff local vs vault without writing.
791
+ sentroy env diff .env.production --delete-missing
792
+
793
+ # Pull the vault into a local file. Refuses to overwrite without --force.
794
+ sentroy env pull .env.staging --force
795
+
796
+ # List keys (or KEY=value with --values; only public-flagged with --public-only).
797
+ sentroy env list
798
+ sentroy env list --values
799
+ sentroy env list --public-only
800
+ ```
801
+
802
+ `push` requires the token to have `write` permission (toggle when generating the token in the dashboard). `pull`, `list`, and `diff` only need `read`.
803
+
804
+ The CLI parses the same `.env` flavour as the dashboard's developer mode:
805
+
806
+ - blank line resets pending description / public flag
807
+ - `# any comment` above a key becomes the variable's description
808
+ - `# @public` on its own line marks the next key as browser-readable
809
+ - `KEY="quoted with spaces"` and `KEY='single quoted'` both supported
810
+ - `export KEY=value` prefix is stripped
811
+
812
+ REST endpoint behind `push`: `POST /api/env-vault/push` with body `{ entries: [{key, value, public?, description?}], deleteMissing?: boolean }` and `Authorization: Bearer stk_env_...`. Response: `{ added, updated, unchanged, deleted, total, project, environment }`. Each insert/update/delete writes one audit log entry (checksum, no plaintext) tagged `source: "cli-push"`.
813
+
777
814
  ## Requirements
778
815
 
779
816
  - Node.js 18+ (uses native `fetch`)
package/README.md CHANGED
@@ -106,6 +106,20 @@ const siteKey = useEnv("TURNSTILE_SITE_KEY")
106
106
 
107
107
  Bootstrap is a single env: `SENTROY_ENV_API_KEY`. Public/private split is enforced server-side — the React hook only ever sees `public: true` variables. Full reference at [docs.sentroy.com/env-vault](https://docs.sentroy.com/env-vault).
108
108
 
109
+ ### CLI
110
+
111
+ The package ships a `sentroy` CLI for syncing local `.env` files to the vault — useful for build pipelines and onboarding.
112
+
113
+ ```bash
114
+ # Use SENTROY_ENV_API_KEY (or pass --token=stk_env_...)
115
+ npx sentroy env push .env.production --delete-missing
116
+ npx sentroy env diff .env.production
117
+ npx sentroy env pull .env.staging --force
118
+ npx sentroy env list --values --public-only
119
+ ```
120
+
121
+ The token's (project, environment) scope is implicit. `--delete-missing` makes the push a full sync — keys not in the local file are removed from the vault. The token must have `write` permission for `push`; everything else only needs `read`.
122
+
109
123
  ## Self-hosted vs hosted
110
124
 
111
125
  The SDK is identical in both modes. Only `baseUrl` changes:
package/bin/sentroy.js ADDED
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env node
2
+ // Thin shim — keeps the shebang out of TypeScript-emitted files so tsc
3
+ // can still emit them as plain CommonJS modules without preserving comments.
4
+ require("../dist/cli/index.js")
@@ -0,0 +1,35 @@
1
+ /**
2
+ * Minimal .env parser + serializer used by the CLI.
3
+ *
4
+ * Format conventions (mirrors apps/core/components/admin/env-vault-content.tsx
5
+ * developer mode):
6
+ * - blank line resets pending description/public flag
7
+ * - `# @public` on its own line marks the next variable as browser-readable
8
+ * - `# any other text` becomes the next variable's description
9
+ * - `KEY=value` (unquoted)
10
+ * - `KEY="value with spaces"` (double-quoted; supports \n, \", \\ escapes)
11
+ * - `KEY='single quotes'` (single-quoted; literal)
12
+ * - `export KEY=value` (export prefix stripped)
13
+ *
14
+ * Anything else is reported as a parse error with the offending line number.
15
+ */
16
+ export interface DotenvEntry {
17
+ key: string;
18
+ value: string;
19
+ public: boolean;
20
+ description: string | null;
21
+ }
22
+ export interface DotenvParseResult {
23
+ entries: DotenvEntry[];
24
+ errors: {
25
+ line: number;
26
+ message: string;
27
+ }[];
28
+ }
29
+ export declare function parseDotenv(text: string): DotenvParseResult;
30
+ /**
31
+ * Inverse of parseDotenv — emit a .env document that round-trips through it.
32
+ * Quotes values that contain whitespace or shell-special characters.
33
+ */
34
+ export declare function serializeDotenv(entries: DotenvEntry[]): string;
35
+ //# sourceMappingURL=dotenv.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dotenv.d.ts","sourceRoot":"","sources":["../../src/cli/dotenv.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,MAAM,WAAW,WAAW;IAC1B,GAAG,EAAE,MAAM,CAAA;IACX,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,EAAE,OAAO,CAAA;IACf,WAAW,EAAE,MAAM,GAAG,IAAI,CAAA;CAC3B;AAED,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,WAAW,EAAE,CAAA;IACtB,MAAM,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,EAAE,CAAA;CAC5C;AAID,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,iBAAiB,CA2F3D;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,WAAW,EAAE,GAAG,MAAM,CAkB9D"}
@@ -0,0 +1,125 @@
1
+ "use strict";
2
+ /**
3
+ * Minimal .env parser + serializer used by the CLI.
4
+ *
5
+ * Format conventions (mirrors apps/core/components/admin/env-vault-content.tsx
6
+ * developer mode):
7
+ * - blank line resets pending description/public flag
8
+ * - `# @public` on its own line marks the next variable as browser-readable
9
+ * - `# any other text` becomes the next variable's description
10
+ * - `KEY=value` (unquoted)
11
+ * - `KEY="value with spaces"` (double-quoted; supports \n, \", \\ escapes)
12
+ * - `KEY='single quotes'` (single-quoted; literal)
13
+ * - `export KEY=value` (export prefix stripped)
14
+ *
15
+ * Anything else is reported as a parse error with the offending line number.
16
+ */
17
+ Object.defineProperty(exports, "__esModule", { value: true });
18
+ exports.parseDotenv = parseDotenv;
19
+ exports.serializeDotenv = serializeDotenv;
20
+ const KEY_PATTERN = /^[A-Z_][A-Z0-9_]*$/;
21
+ function parseDotenv(text) {
22
+ const lines = text.split(/\r?\n/);
23
+ const entries = [];
24
+ const errors = [];
25
+ const seen = new Set();
26
+ let pendingDescription = [];
27
+ let pendingPublic = false;
28
+ for (let i = 0; i < lines.length; i++) {
29
+ const raw = lines[i] ?? "";
30
+ const line = raw.trim();
31
+ if (line === "") {
32
+ pendingDescription = [];
33
+ pendingPublic = false;
34
+ continue;
35
+ }
36
+ if (line.startsWith("#")) {
37
+ const body = line.slice(1).trim();
38
+ if (body === "@public") {
39
+ pendingPublic = true;
40
+ }
41
+ else if (body) {
42
+ pendingDescription.push(body);
43
+ }
44
+ continue;
45
+ }
46
+ const work = line.startsWith("export ") ? line.slice(7).trimStart() : line;
47
+ const eq = work.indexOf("=");
48
+ if (eq <= 0) {
49
+ errors.push({
50
+ line: i + 1,
51
+ message: "invalid syntax (expected KEY=value)",
52
+ });
53
+ pendingDescription = [];
54
+ pendingPublic = false;
55
+ continue;
56
+ }
57
+ const key = work.slice(0, eq).trim();
58
+ let value = work.slice(eq + 1);
59
+ if (!KEY_PATTERN.test(key)) {
60
+ errors.push({
61
+ line: i + 1,
62
+ message: "key must match [A-Z_][A-Z0-9_]*",
63
+ });
64
+ pendingDescription = [];
65
+ pendingPublic = false;
66
+ continue;
67
+ }
68
+ const trimmed = value.trim();
69
+ if ((trimmed.startsWith('"') && trimmed.endsWith('"')) ||
70
+ (trimmed.startsWith("'") && trimmed.endsWith("'"))) {
71
+ value = trimmed.slice(1, -1);
72
+ if (trimmed.startsWith('"')) {
73
+ value = value
74
+ .replace(/\\n/g, "\n")
75
+ .replace(/\\"/g, '"')
76
+ .replace(/\\\\/g, "\\");
77
+ }
78
+ }
79
+ else {
80
+ value = trimmed;
81
+ }
82
+ if (seen.has(key)) {
83
+ errors.push({ line: i + 1, message: `duplicate key ${key}` });
84
+ pendingDescription = [];
85
+ pendingPublic = false;
86
+ continue;
87
+ }
88
+ seen.add(key);
89
+ entries.push({
90
+ key,
91
+ value,
92
+ public: pendingPublic,
93
+ description: pendingDescription.length > 0 ? pendingDescription.join(" ") : null,
94
+ });
95
+ pendingDescription = [];
96
+ pendingPublic = false;
97
+ }
98
+ return { entries, errors };
99
+ }
100
+ /**
101
+ * Inverse of parseDotenv — emit a .env document that round-trips through it.
102
+ * Quotes values that contain whitespace or shell-special characters.
103
+ */
104
+ function serializeDotenv(entries) {
105
+ const blocks = [];
106
+ for (const e of entries) {
107
+ const parts = [];
108
+ if (e.description)
109
+ parts.push(`# ${e.description}`);
110
+ if (e.public)
111
+ parts.push("# @public");
112
+ const value = e.value;
113
+ const needsQuote = /[\s"'#$`\\]/.test(value) || value === "";
114
+ const escaped = needsQuote
115
+ ? `"${value
116
+ .replace(/\\/g, "\\\\")
117
+ .replace(/"/g, '\\"')
118
+ .replace(/\n/g, "\\n")}"`
119
+ : value;
120
+ parts.push(`${e.key}=${escaped}`);
121
+ blocks.push(parts.join("\n"));
122
+ }
123
+ return blocks.join("\n\n") + (blocks.length > 0 ? "\n" : "");
124
+ }
125
+ //# sourceMappingURL=dotenv.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dotenv.js","sourceRoot":"","sources":["../../src/cli/dotenv.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * `sentroy env <subcommand>` — vault sync from a local .env file.
3
+ *
4
+ * The token's (project, environment) scope is implicit; the CLI never
5
+ * asks for either since it can't change them.
6
+ */
7
+ export declare function cmdPush(args: string[]): Promise<void>;
8
+ export declare function cmdPull(args: string[]): Promise<void>;
9
+ export declare function cmdList(args: string[]): Promise<void>;
10
+ export declare function cmdDiff(args: string[]): Promise<void>;
11
+ //# sourceMappingURL=env.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"env.d.ts","sourceRoot":"","sources":["../../src/cli/env.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAgMH,wBAAsB,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAgF3D;AAID,wBAAsB,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAwB3D;AAID,wBAAsB,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAmB3D;AAID,wBAAsB,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAyB3D"}
@@ -0,0 +1,331 @@
1
+ "use strict";
2
+ /**
3
+ * `sentroy env <subcommand>` — vault sync from a local .env file.
4
+ *
5
+ * The token's (project, environment) scope is implicit; the CLI never
6
+ * asks for either since it can't change them.
7
+ */
8
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
9
+ if (k2 === undefined) k2 = k;
10
+ var desc = Object.getOwnPropertyDescriptor(m, k);
11
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
12
+ desc = { enumerable: true, get: function() { return m[k]; } };
13
+ }
14
+ Object.defineProperty(o, k2, desc);
15
+ }) : (function(o, m, k, k2) {
16
+ if (k2 === undefined) k2 = k;
17
+ o[k2] = m[k];
18
+ }));
19
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
20
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
21
+ }) : function(o, v) {
22
+ o["default"] = v;
23
+ });
24
+ var __importStar = (this && this.__importStar) || (function () {
25
+ var ownKeys = function(o) {
26
+ ownKeys = Object.getOwnPropertyNames || function (o) {
27
+ var ar = [];
28
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
29
+ return ar;
30
+ };
31
+ return ownKeys(o);
32
+ };
33
+ return function (mod) {
34
+ if (mod && mod.__esModule) return mod;
35
+ var result = {};
36
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
37
+ __setModuleDefault(result, mod);
38
+ return result;
39
+ };
40
+ })();
41
+ Object.defineProperty(exports, "__esModule", { value: true });
42
+ exports.cmdPush = cmdPush;
43
+ exports.cmdPull = cmdPull;
44
+ exports.cmdList = cmdList;
45
+ exports.cmdDiff = cmdDiff;
46
+ const fs = __importStar(require("fs"));
47
+ const path = __importStar(require("path"));
48
+ const readline = __importStar(require("readline"));
49
+ const dotenv_1 = require("./dotenv");
50
+ const DEFAULT_FILE = ".env";
51
+ const DEFAULT_BASE_URL = "https://sentroy.com";
52
+ // ── ANSI helpers (no deps) ───────────────────────────────────────────────
53
+ const supportsColor = process.stdout.isTTY && process.env.TERM !== "dumb";
54
+ const c = {
55
+ bold: (s) => (supportsColor ? `\x1b[1m${s}\x1b[0m` : s),
56
+ dim: (s) => (supportsColor ? `\x1b[2m${s}\x1b[0m` : s),
57
+ red: (s) => (supportsColor ? `\x1b[31m${s}\x1b[0m` : s),
58
+ green: (s) => (supportsColor ? `\x1b[32m${s}\x1b[0m` : s),
59
+ yellow: (s) => (supportsColor ? `\x1b[33m${s}\x1b[0m` : s),
60
+ cyan: (s) => (supportsColor ? `\x1b[36m${s}\x1b[0m` : s),
61
+ magenta: (s) => (supportsColor ? `\x1b[35m${s}\x1b[0m` : s),
62
+ };
63
+ function fail(msg) {
64
+ process.stderr.write(`${c.red("✗")} ${msg}\n`);
65
+ process.exit(1);
66
+ }
67
+ function info(msg) {
68
+ process.stdout.write(`${c.cyan("→")} ${msg}\n`);
69
+ }
70
+ function ok(msg) {
71
+ process.stdout.write(`${c.green("✓")} ${msg}\n`);
72
+ }
73
+ function warn(msg) {
74
+ process.stdout.write(`${c.yellow("⚠")} ${msg}\n`);
75
+ }
76
+ function resolveSharedOpts(rest) {
77
+ const token = (typeof rest.token === "string" ? rest.token : null) ??
78
+ process.env.SENTROY_ENV_API_KEY ??
79
+ null;
80
+ if (!token) {
81
+ fail("no token. Pass --token=stk_env_... or set SENTROY_ENV_API_KEY in your environment.");
82
+ }
83
+ const baseUrl = (typeof rest.url === "string" ? rest.url : null) ??
84
+ process.env.SENTROY_ENV_API_URL ??
85
+ DEFAULT_BASE_URL;
86
+ return { token, baseUrl: baseUrl.replace(/\/+$/, "") };
87
+ }
88
+ async function http(shared, path, init) {
89
+ const res = await fetch(`${shared.baseUrl}${path}`, {
90
+ ...init,
91
+ headers: {
92
+ Authorization: `Bearer ${shared.token}`,
93
+ ...(init?.body ? { "Content-Type": "application/json" } : {}),
94
+ ...(init?.headers ?? {}),
95
+ },
96
+ });
97
+ const text = await res.text();
98
+ let body;
99
+ try {
100
+ body = text ? JSON.parse(text) : null;
101
+ }
102
+ catch {
103
+ body = text;
104
+ }
105
+ if (!res.ok) {
106
+ const errMsg = body && typeof body === "object" && "error" in body
107
+ ? String(body.error)
108
+ : `HTTP ${res.status}`;
109
+ throw new Error(`${path}: ${errMsg}`);
110
+ }
111
+ return body?.data;
112
+ }
113
+ function readFileOrFail(file) {
114
+ if (!fs.existsSync(file)) {
115
+ fail(`file not found: ${file}`);
116
+ }
117
+ return fs.readFileSync(file, "utf8");
118
+ }
119
+ function computeDiff(local, remote) {
120
+ const remoteByKey = new Map(remote.map((v) => [v.key, v]));
121
+ const added = [];
122
+ const updated = [];
123
+ const unchanged = [];
124
+ for (const e of local) {
125
+ const r = remoteByKey.get(e.key);
126
+ if (!r) {
127
+ added.push(e);
128
+ continue;
129
+ }
130
+ if (r.value !== e.value || r.public !== e.public) {
131
+ updated.push({ entry: e, remote: r });
132
+ }
133
+ else {
134
+ unchanged.push({ entry: e, remote: r });
135
+ }
136
+ }
137
+ const localKeys = new Set(local.map((e) => e.key));
138
+ const deleted = remote.filter((v) => !localKeys.has(v.key));
139
+ return { added, updated, unchanged, deleted };
140
+ }
141
+ function printDiff(diff, deleteMissing) {
142
+ for (const e of diff.added) {
143
+ process.stdout.write(` ${c.green("+")} ${e.key}\n`);
144
+ }
145
+ for (const u of diff.updated) {
146
+ process.stdout.write(` ${c.yellow("~")} ${u.entry.key}\n`);
147
+ }
148
+ if (deleteMissing) {
149
+ for (const d of diff.deleted) {
150
+ process.stdout.write(` ${c.red("-")} ${d.key}\n`);
151
+ }
152
+ }
153
+ else if (diff.deleted.length > 0) {
154
+ process.stdout.write(` ${c.dim(`(${diff.deleted.length} key(s) only in vault, kept — pass --delete-missing to remove)`)}\n`);
155
+ }
156
+ }
157
+ async function confirm(question) {
158
+ if (!process.stdin.isTTY)
159
+ return false;
160
+ const rl = readline.createInterface({
161
+ input: process.stdin,
162
+ output: process.stdout,
163
+ });
164
+ const answer = await new Promise((resolve) => {
165
+ rl.question(`${question} [y/N] `, (ans) => {
166
+ rl.close();
167
+ resolve(ans.trim().toLowerCase());
168
+ });
169
+ });
170
+ return answer === "y" || answer === "yes";
171
+ }
172
+ // ── push ─────────────────────────────────────────────────────────────────
173
+ async function cmdPush(args) {
174
+ const { positional, flags } = parseFlags(args);
175
+ const file = positional[0] ?? DEFAULT_FILE;
176
+ const dryRun = !!flags["dry-run"];
177
+ const deleteMissing = !!flags["delete-missing"];
178
+ const shared = resolveSharedOpts(flags);
179
+ const text = readFileOrFail(path.resolve(process.cwd(), file));
180
+ const parsed = (0, dotenv_1.parseDotenv)(text);
181
+ if (parsed.errors.length > 0) {
182
+ process.stderr.write(`${c.red("✗")} parse errors in ${file}:\n`);
183
+ for (const err of parsed.errors) {
184
+ process.stderr.write(` line ${err.line}: ${err.message}\n`);
185
+ }
186
+ process.exit(1);
187
+ }
188
+ info(`fetching current vault snapshot…`);
189
+ const remote = await http(shared, "/api/env-vault/fetch");
190
+ const diff = computeDiff(parsed.entries, remote.variables);
191
+ process.stdout.write(`\n${c.bold(remote.project)} ${c.dim("/")} ${c.magenta(remote.environment)} ${c.dim(`(${file} → ${shared.baseUrl})`)}\n`);
192
+ printDiff(diff, deleteMissing);
193
+ process.stdout.write(`\n ${c.dim("summary:")} ${diff.added.length} new · ${diff.updated.length} updated · ${diff.unchanged.length} unchanged${deleteMissing ? ` · ${diff.deleted.length} to delete` : ""}\n\n`);
194
+ if (diff.added.length === 0 &&
195
+ diff.updated.length === 0 &&
196
+ (!deleteMissing || diff.deleted.length === 0)) {
197
+ ok("nothing to push.");
198
+ return;
199
+ }
200
+ if (dryRun) {
201
+ info("dry run — no changes pushed.");
202
+ return;
203
+ }
204
+ if (deleteMissing && diff.deleted.length > 0) {
205
+ if (flags.yes) {
206
+ info(`--yes provided, skipping confirmation for ${diff.deleted.length} delete(s).`);
207
+ }
208
+ else if (!process.stdin.isTTY) {
209
+ fail(`refusing to delete ${diff.deleted.length} key(s) without --yes in a non-interactive shell.`);
210
+ }
211
+ else {
212
+ const proceed = await confirm(`${c.yellow("⚠")} this will delete ${diff.deleted.length} key(s) from the vault. continue?`);
213
+ if (!proceed) {
214
+ warn("aborted.");
215
+ return;
216
+ }
217
+ }
218
+ }
219
+ const result = await http(shared, "/api/env-vault/push", {
220
+ method: "POST",
221
+ body: JSON.stringify({
222
+ entries: parsed.entries.map((e) => ({
223
+ key: e.key,
224
+ value: e.value,
225
+ public: e.public,
226
+ description: e.description,
227
+ })),
228
+ deleteMissing,
229
+ }),
230
+ });
231
+ ok(`${result.added} added · ${result.updated} updated · ${result.unchanged} unchanged · ${result.deleted} deleted`);
232
+ }
233
+ // ── pull ─────────────────────────────────────────────────────────────────
234
+ async function cmdPull(args) {
235
+ const { positional, flags } = parseFlags(args);
236
+ const file = positional[0] ?? DEFAULT_FILE;
237
+ const force = !!flags.force;
238
+ const shared = resolveSharedOpts(flags);
239
+ const target = path.resolve(process.cwd(), file);
240
+ if (fs.existsSync(target) && !force) {
241
+ fail(`${file} already exists. Pass --force to overwrite.`);
242
+ }
243
+ info(`fetching from ${shared.baseUrl}…`);
244
+ const remote = await http(shared, "/api/env-vault/fetch");
245
+ const entries = remote.variables.map((v) => ({
246
+ key: v.key,
247
+ value: v.value,
248
+ public: v.public,
249
+ description: null,
250
+ }));
251
+ const text = (0, dotenv_1.serializeDotenv)(entries);
252
+ fs.writeFileSync(target, text, "utf8");
253
+ ok(`wrote ${entries.length} variable(s) to ${file} (${remote.project}/${remote.environment})`);
254
+ }
255
+ // ── list ─────────────────────────────────────────────────────────────────
256
+ async function cmdList(args) {
257
+ const { flags } = parseFlags(args);
258
+ const showValues = !!flags.values;
259
+ const publicOnly = !!flags["public-only"];
260
+ const shared = resolveSharedOpts(flags);
261
+ const endpoint = publicOnly ? "/api/env-vault/public" : "/api/env-vault/fetch";
262
+ const remote = await http(shared, endpoint);
263
+ process.stdout.write(`${c.bold(remote.project)} ${c.dim("/")} ${c.magenta(remote.environment)} ${c.dim(`(${remote.variables.length} variable(s))`)}\n`);
264
+ for (const v of remote.variables) {
265
+ const tag = v.public ? c.dim(" [public]") : "";
266
+ if (showValues) {
267
+ process.stdout.write(` ${c.cyan(v.key)}=${v.value}${tag}\n`);
268
+ }
269
+ else {
270
+ process.stdout.write(` ${c.cyan(v.key)}${tag}\n`);
271
+ }
272
+ }
273
+ }
274
+ // ── diff ─────────────────────────────────────────────────────────────────
275
+ async function cmdDiff(args) {
276
+ const { positional, flags } = parseFlags(args);
277
+ const file = positional[0] ?? DEFAULT_FILE;
278
+ const deleteMissing = !!flags["delete-missing"];
279
+ const shared = resolveSharedOpts(flags);
280
+ const text = readFileOrFail(path.resolve(process.cwd(), file));
281
+ const parsed = (0, dotenv_1.parseDotenv)(text);
282
+ if (parsed.errors.length > 0) {
283
+ process.stderr.write(`${c.red("✗")} parse errors in ${file}:\n`);
284
+ for (const err of parsed.errors) {
285
+ process.stderr.write(` line ${err.line}: ${err.message}\n`);
286
+ }
287
+ process.exit(1);
288
+ }
289
+ const remote = await http(shared, "/api/env-vault/fetch");
290
+ const diff = computeDiff(parsed.entries, remote.variables);
291
+ process.stdout.write(`${c.bold(remote.project)} ${c.dim("/")} ${c.magenta(remote.environment)} ${c.dim(`(${file} vs vault)`)}\n`);
292
+ printDiff(diff, deleteMissing);
293
+ process.stdout.write(`\n ${c.dim("summary:")} ${diff.added.length} new · ${diff.updated.length} updated · ${diff.unchanged.length} unchanged · ${diff.deleted.length} only in vault\n`);
294
+ }
295
+ /**
296
+ * Flags that take a value as a separate token (`--flag value`). All other
297
+ * `--flag` tokens are booleans. The `--flag=value` form always works
298
+ * regardless of this list. Keeping this explicit avoids the classic argv
299
+ * bug where `--dry-run /path/to/file` swallows the positional.
300
+ */
301
+ const VALUE_FLAGS = new Set(["token", "url"]);
302
+ function parseFlags(args) {
303
+ const positional = [];
304
+ const flags = {};
305
+ for (let i = 0; i < args.length; i++) {
306
+ const a = args[i];
307
+ if (!a.startsWith("--")) {
308
+ positional.push(a);
309
+ continue;
310
+ }
311
+ const body = a.slice(2);
312
+ const eq = body.indexOf("=");
313
+ if (eq >= 0) {
314
+ flags[body.slice(0, eq)] = body.slice(eq + 1);
315
+ continue;
316
+ }
317
+ if (VALUE_FLAGS.has(body)) {
318
+ const next = args[i + 1];
319
+ if (next === undefined || next.startsWith("--")) {
320
+ fail(`flag --${body} requires a value (use --${body}=value or --${body} value)`);
321
+ }
322
+ flags[body] = next;
323
+ i++;
324
+ }
325
+ else {
326
+ flags[body] = true;
327
+ }
328
+ }
329
+ return { positional, flags };
330
+ }
331
+ //# sourceMappingURL=env.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"env.js","sourceRoot":"","sources":["../../src/cli/env.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * `sentroy` — CLI entry point.
3
+ *
4
+ * Subcommand router with no third-party deps. Today only `env` exists;
5
+ * future subcommands (`mail`, `media`, etc.) hook in here.
6
+ */
7
+ export {};
8
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG"}