@jacobwisniewski/openstack 0.1.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.
Files changed (42) hide show
  1. package/README.md +46 -0
  2. package/dist/__tests__/cli.test.d.ts +2 -0
  3. package/dist/__tests__/cli.test.d.ts.map +1 -0
  4. package/dist/__tests__/cli.test.js +21 -0
  5. package/dist/__tests__/cli.test.js.map +1 -0
  6. package/dist/__tests__/commands.test.d.ts +2 -0
  7. package/dist/__tests__/commands.test.d.ts.map +1 -0
  8. package/dist/__tests__/commands.test.js +295 -0
  9. package/dist/__tests__/commands.test.js.map +1 -0
  10. package/dist/__tests__/config-operations.test.d.ts +2 -0
  11. package/dist/__tests__/config-operations.test.d.ts.map +1 -0
  12. package/dist/__tests__/config-operations.test.js +132 -0
  13. package/dist/__tests__/config-operations.test.js.map +1 -0
  14. package/dist/__tests__/fixtures.d.ts +59 -0
  15. package/dist/__tests__/fixtures.d.ts.map +1 -0
  16. package/dist/__tests__/fixtures.js +59 -0
  17. package/dist/__tests__/fixtures.js.map +1 -0
  18. package/dist/__tests__/validation.test.d.ts +2 -0
  19. package/dist/__tests__/validation.test.d.ts.map +1 -0
  20. package/dist/__tests__/validation.test.js +124 -0
  21. package/dist/__tests__/validation.test.js.map +1 -0
  22. package/dist/cli.d.ts +3 -0
  23. package/dist/cli.d.ts.map +1 -0
  24. package/dist/cli.js +142 -0
  25. package/dist/cli.js.map +1 -0
  26. package/dist/commands.d.ts +97 -0
  27. package/dist/commands.d.ts.map +1 -0
  28. package/dist/commands.js +245 -0
  29. package/dist/commands.js.map +1 -0
  30. package/dist/result.d.ts +2 -0
  31. package/dist/result.d.ts.map +1 -0
  32. package/dist/result.js +9 -0
  33. package/dist/result.js.map +1 -0
  34. package/dist/types/index.d.ts +26 -0
  35. package/dist/types/index.d.ts.map +1 -0
  36. package/dist/types/index.js +3 -0
  37. package/dist/types/index.js.map +1 -0
  38. package/dist/validation.d.ts +21 -0
  39. package/dist/validation.d.ts.map +1 -0
  40. package/dist/validation.js +32 -0
  41. package/dist/validation.js.map +1 -0
  42. package/package.json +54 -0
@@ -0,0 +1,245 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.isInitialized = isInitialized;
37
+ exports.loadConfig = loadConfig;
38
+ exports.saveConfig = saveConfig;
39
+ exports.copyDir = copyDir;
40
+ exports.init = init;
41
+ exports.list = list;
42
+ exports.remove = remove;
43
+ exports.install = install;
44
+ exports.use = use;
45
+ const path = __importStar(require("path"));
46
+ const YAML = __importStar(require("yaml"));
47
+ const validation_1 = require("./validation");
48
+ function isInitialized(paths, fs) {
49
+ return fs.existsSync(paths.configFile);
50
+ }
51
+ function loadConfig(paths, fs) {
52
+ if (!fs.existsSync(paths.configFile)) {
53
+ return null;
54
+ }
55
+ const content = fs.readFileSync(paths.configFile, "utf-8");
56
+ const rawConfig = YAML.parse(content);
57
+ const validationResult = (0, validation_1.validateConfig)(rawConfig);
58
+ if (validationResult.isErr()) {
59
+ return null;
60
+ }
61
+ return validationResult.value;
62
+ }
63
+ function saveConfig(paths, fs, config) {
64
+ const content = `version: "${config.version}"
65
+ active_profile: "${config.active_profile}"
66
+ profiles:
67
+ ${config.profiles
68
+ .map((p) => ` - name: "${p.name}"\n source: "${p.source}"\n installed_at: "${p.installed_at}"`)
69
+ .join("\n")}
70
+ `;
71
+ fs.writeFileSync(paths.configFile, content);
72
+ }
73
+ function copyDir(fs, src, dest) {
74
+ if (!fs.existsSync(dest)) {
75
+ fs.mkdirSync(dest, { recursive: true });
76
+ }
77
+ const entries = fs.readdirSync(src, { withFileTypes: true });
78
+ for (const entry of entries) {
79
+ const srcPath = path.join(src, entry.name);
80
+ const destPath = path.join(dest, entry.name);
81
+ if (entry.isDirectory()) {
82
+ copyDir(fs, srcPath, destPath);
83
+ }
84
+ else {
85
+ fs.copyFileSync(srcPath, destPath);
86
+ }
87
+ }
88
+ }
89
+ function init(paths, fs, options, packageVersion) {
90
+ if (!fs.existsSync(paths.opencodeDir)) {
91
+ return { success: false, error: "OpenCode config directory not found at ~/.config/opencode" };
92
+ }
93
+ if (isInitialized(paths, fs) && !options.force) {
94
+ return {
95
+ success: false,
96
+ error: "Already initialized. Use --force to re-initialize (DANGER: will overwrite default backup).",
97
+ };
98
+ }
99
+ if (!fs.existsSync(paths.openstackDir)) {
100
+ fs.mkdirSync(paths.openstackDir, { recursive: true });
101
+ }
102
+ if (!fs.existsSync(paths.profilesDir)) {
103
+ fs.mkdirSync(paths.profilesDir, { recursive: true });
104
+ }
105
+ const defaultProfileDir = path.join(paths.profilesDir, "default");
106
+ if (fs.existsSync(defaultProfileDir) && options.force) {
107
+ fs.rmSync(defaultProfileDir, { recursive: true });
108
+ }
109
+ copyDir(fs, paths.opencodeDir, defaultProfileDir);
110
+ const config = {
111
+ version: packageVersion,
112
+ active_profile: "default",
113
+ profiles: [
114
+ {
115
+ name: "default",
116
+ source: "local",
117
+ installed_at: new Date().toISOString(),
118
+ },
119
+ ],
120
+ };
121
+ saveConfig(paths, fs, config);
122
+ return {
123
+ success: true,
124
+ message: "openstack initialized successfully!\n" +
125
+ " Current config backed up to: ~/.config/openstack/profiles/default/\n" +
126
+ " Active profile: default\n" +
127
+ "\n" +
128
+ "Next steps:\n" +
129
+ " 1. Install a profile: openstack install <git-url>\n" +
130
+ " 2. Switch profiles: openstack use <profile-name>",
131
+ };
132
+ }
133
+ function list(paths, fs) {
134
+ const config = loadConfig(paths, fs);
135
+ if (!config) {
136
+ return null;
137
+ }
138
+ return config.profiles.map((p) => ({
139
+ name: p.name,
140
+ source: p.source,
141
+ isActive: p.name === config.active_profile,
142
+ }));
143
+ }
144
+ function remove(paths, fs, options) {
145
+ const config = loadConfig(paths, fs);
146
+ if (!config) {
147
+ return { success: false, error: "Failed to load config" };
148
+ }
149
+ const profileIndex = config.profiles.findIndex((p) => p.name === options.name);
150
+ if (profileIndex === -1) {
151
+ return {
152
+ success: false,
153
+ error: `Profile "${options.name}" not found`,
154
+ };
155
+ }
156
+ // Prevent removing active profile unless forced
157
+ if (config.active_profile === options.name && !options.force) {
158
+ return {
159
+ success: false,
160
+ error: `Cannot remove active profile "${options.name}". Switch to another profile first, or use --force.`,
161
+ };
162
+ }
163
+ const profileDir = path.join(paths.profilesDir, options.name);
164
+ if (fs.existsSync(profileDir)) {
165
+ fs.rmSync(profileDir, { recursive: true });
166
+ }
167
+ // Remove from config
168
+ config.profiles.splice(profileIndex, 1);
169
+ // If we removed the active profile (with force), switch to default
170
+ if (config.active_profile === options.name) {
171
+ config.active_profile = "default";
172
+ }
173
+ saveConfig(paths, fs, config);
174
+ return {
175
+ success: true,
176
+ message: `Profile "${options.name}" removed successfully`,
177
+ };
178
+ }
179
+ function install(paths, fs, git, source, options) {
180
+ const config = loadConfig(paths, fs);
181
+ if (!config) {
182
+ return { success: false, error: "openstack not initialized. Run 'openstack init' first." };
183
+ }
184
+ // Determine profile name from source or options
185
+ const profileName = options.name ?? source.split("/").pop()?.replace(/\.git$/, "") ?? "unknown";
186
+ const profileDir = path.join(paths.profilesDir, profileName);
187
+ if (fs.existsSync(profileDir)) {
188
+ return { success: false, error: `Profile "${profileName}" already exists` };
189
+ }
190
+ // Clone the repository
191
+ try {
192
+ git.clone(source, profileDir);
193
+ }
194
+ catch {
195
+ return { success: false, error: `Failed to clone from ${source}` };
196
+ }
197
+ // Add to config
198
+ config.profiles.push({
199
+ name: profileName,
200
+ source,
201
+ installed_at: new Date().toISOString(),
202
+ });
203
+ saveConfig(paths, fs, config);
204
+ return {
205
+ success: true,
206
+ message: `Profile "${profileName}" installed successfully from ${source}`,
207
+ };
208
+ }
209
+ function use(paths, fs, options) {
210
+ const config = loadConfig(paths, fs);
211
+ if (!config) {
212
+ return { success: false, error: "Failed to load config" };
213
+ }
214
+ const profile = config.profiles.find((p) => p.name === options.name);
215
+ if (!profile) {
216
+ return { success: false, error: `Profile "${options.name}" not found` };
217
+ }
218
+ const profileDir = path.join(paths.profilesDir, options.name);
219
+ if (!fs.existsSync(profileDir)) {
220
+ return { success: false, error: `Profile directory for "${options.name}" not found` };
221
+ }
222
+ // Remove existing symlink if any
223
+ if (fs.existsSync(paths.opencodeDir)) {
224
+ const stat = fs.lstatSync(paths.opencodeDir);
225
+ if (stat.isSymbolicLink()) {
226
+ fs.unlinkSync(paths.opencodeDir);
227
+ }
228
+ else {
229
+ return {
230
+ success: false,
231
+ error: `~/.config/opencode exists and is not a symlink. Please remove it manually or use 'openstack init --force' to re-initialize.`,
232
+ };
233
+ }
234
+ }
235
+ // Create symlink to profile
236
+ fs.symlinkSync(profileDir, paths.opencodeDir, "dir");
237
+ // Update config
238
+ config.active_profile = options.name;
239
+ saveConfig(paths, fs, config);
240
+ return {
241
+ success: true,
242
+ message: `Switched to profile "${options.name}"`,
243
+ };
244
+ }
245
+ //# sourceMappingURL=commands.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"commands.js","sourceRoot":"","sources":["../src/commands.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export { ok, err, Result, ResultAsync } from "neverthrow";
2
+ //# sourceMappingURL=result.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"result.d.ts","sourceRoot":"","sources":["../src/result.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,EAAE,EAAE,GAAG,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC"}
package/dist/result.js ADDED
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ResultAsync = exports.Result = exports.err = exports.ok = void 0;
4
+ var neverthrow_1 = require("neverthrow");
5
+ Object.defineProperty(exports, "ok", { enumerable: true, get: function () { return neverthrow_1.ok; } });
6
+ Object.defineProperty(exports, "err", { enumerable: true, get: function () { return neverthrow_1.err; } });
7
+ Object.defineProperty(exports, "Result", { enumerable: true, get: function () { return neverthrow_1.Result; } });
8
+ Object.defineProperty(exports, "ResultAsync", { enumerable: true, get: function () { return neverthrow_1.ResultAsync; } });
9
+ //# sourceMappingURL=result.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"result.js","sourceRoot":"","sources":["../src/result.ts"],"names":[],"mappings":";;;AAAA,yCAA0D;AAAjD,gGAAA,EAAE,OAAA;AAAE,iGAAA,GAAG,OAAA;AAAE,oGAAA,MAAM,OAAA;AAAE,yGAAA,WAAW,OAAA"}
@@ -0,0 +1,26 @@
1
+ export interface Config {
2
+ version: string;
3
+ active_profile: string;
4
+ profiles: ProfileEntry[];
5
+ }
6
+ export interface ProfileEntry {
7
+ name: string;
8
+ source: string;
9
+ installed_at: string;
10
+ }
11
+ export interface Profile {
12
+ name: string;
13
+ path: string;
14
+ source: string;
15
+ installed_at: Date;
16
+ }
17
+ export interface ValidationResult {
18
+ valid: boolean;
19
+ errors: string[];
20
+ }
21
+ export interface CommandResult {
22
+ success: boolean;
23
+ message?: string;
24
+ error?: Error;
25
+ }
26
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,MAAM;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,cAAc,EAAE,MAAM,CAAC;IACvB,QAAQ,EAAE,YAAY,EAAE,CAAC;CAC1B;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,OAAO;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,IAAI,CAAC;CACpB;AAED,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAED,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,KAAK,CAAC;CACf"}
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":""}
@@ -0,0 +1,21 @@
1
+ import { z } from "zod";
2
+ import { Result } from "neverthrow";
3
+ export declare const ProfileEntrySchema: z.ZodObject<{
4
+ name: z.ZodString;
5
+ source: z.ZodString;
6
+ installed_at: z.ZodString;
7
+ }, z.core.$strip>;
8
+ export declare const OpenStackConfigSchema: z.ZodObject<{
9
+ version: z.ZodString;
10
+ active_profile: z.ZodString;
11
+ profiles: z.ZodArray<z.ZodObject<{
12
+ name: z.ZodString;
13
+ source: z.ZodString;
14
+ installed_at: z.ZodString;
15
+ }, z.core.$strip>>;
16
+ }, z.core.$strip>;
17
+ export type ValidatedOpenStackConfig = z.infer<typeof OpenStackConfigSchema>;
18
+ export type ValidatedProfileEntry = z.infer<typeof ProfileEntrySchema>;
19
+ export declare function validateConfig(data: unknown): Result<ValidatedOpenStackConfig, string>;
20
+ export declare function validateProfileEntry(data: unknown): Result<ValidatedProfileEntry, string>;
21
+ //# sourceMappingURL=validation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../src/validation.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,MAAM,EAAW,MAAM,YAAY,CAAC;AAE7C,eAAO,MAAM,kBAAkB;;;;iBAI7B,CAAC;AAEH,eAAO,MAAM,qBAAqB;;;;;;;;iBAIhC,CAAC;AAEH,MAAM,MAAM,wBAAwB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAAC;AAC7E,MAAM,MAAM,qBAAqB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAEvE,wBAAgB,cAAc,CAAC,IAAI,EAAE,OAAO,GAAG,MAAM,CAAC,wBAAwB,EAAE,MAAM,CAAC,CAMtF;AAED,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,OAAO,GAAG,MAAM,CAAC,qBAAqB,EAAE,MAAM,CAAC,CAMzF"}
@@ -0,0 +1,32 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.OpenStackConfigSchema = exports.ProfileEntrySchema = void 0;
4
+ exports.validateConfig = validateConfig;
5
+ exports.validateProfileEntry = validateProfileEntry;
6
+ const zod_1 = require("zod");
7
+ const neverthrow_1 = require("neverthrow");
8
+ exports.ProfileEntrySchema = zod_1.z.object({
9
+ name: zod_1.z.string().min(1),
10
+ source: zod_1.z.string(),
11
+ installed_at: zod_1.z.string().datetime(),
12
+ });
13
+ exports.OpenStackConfigSchema = zod_1.z.object({
14
+ version: zod_1.z.string(),
15
+ active_profile: zod_1.z.string(),
16
+ profiles: zod_1.z.array(exports.ProfileEntrySchema),
17
+ });
18
+ function validateConfig(data) {
19
+ const result = exports.OpenStackConfigSchema.safeParse(data);
20
+ if (!result.success) {
21
+ return (0, neverthrow_1.err)(zod_1.z.prettifyError(result.error));
22
+ }
23
+ return (0, neverthrow_1.ok)(result.data);
24
+ }
25
+ function validateProfileEntry(data) {
26
+ const result = exports.ProfileEntrySchema.safeParse(data);
27
+ if (!result.success) {
28
+ return (0, neverthrow_1.err)(zod_1.z.prettifyError(result.error));
29
+ }
30
+ return (0, neverthrow_1.ok)(result.data);
31
+ }
32
+ //# sourceMappingURL=validation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validation.js","sourceRoot":"","sources":["../src/validation.ts"],"names":[],"mappings":";;;AAkBA,wCAMC;AAED,oDAMC;AAhCD,6BAAwB;AACxB,2CAA6C;AAEhC,QAAA,kBAAkB,GAAG,OAAC,CAAC,MAAM,CAAC;IACzC,IAAI,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IACvB,MAAM,EAAE,OAAC,CAAC,MAAM,EAAE;IAClB,YAAY,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;CACpC,CAAC,CAAC;AAEU,QAAA,qBAAqB,GAAG,OAAC,CAAC,MAAM,CAAC;IAC5C,OAAO,EAAE,OAAC,CAAC,MAAM,EAAE;IACnB,cAAc,EAAE,OAAC,CAAC,MAAM,EAAE;IAC1B,QAAQ,EAAE,OAAC,CAAC,KAAK,CAAC,0BAAkB,CAAC;CACtC,CAAC,CAAC;AAKH,SAAgB,cAAc,CAAC,IAAa;IAC1C,MAAM,MAAM,GAAG,6BAAqB,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;IACrD,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;QACpB,OAAO,IAAA,gBAAG,EAAC,OAAC,CAAC,aAAa,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;IAC5C,CAAC;IACD,OAAO,IAAA,eAAE,EAAC,MAAM,CAAC,IAAI,CAAC,CAAC;AACzB,CAAC;AAED,SAAgB,oBAAoB,CAAC,IAAa;IAChD,MAAM,MAAM,GAAG,0BAAkB,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;IAClD,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;QACpB,OAAO,IAAA,gBAAG,EAAC,OAAC,CAAC,aAAa,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;IAC5C,CAAC;IACD,OAAO,IAAA,eAAE,EAAC,MAAM,CAAC,IAAI,CAAC,CAAC;AACzB,CAAC"}
package/package.json ADDED
@@ -0,0 +1,54 @@
1
+ {
2
+ "name": "@jacobwisniewski/openstack",
3
+ "version": "0.1.1",
4
+ "description": "Simple profile management for OpenCode configurations",
5
+ "main": "dist/index.js",
6
+ "bin": {
7
+ "openstack": "dist/cli.js"
8
+ },
9
+ "scripts": {
10
+ "build": "tsc",
11
+ "dev": "tsc --watch",
12
+ "prepare": "npm run build",
13
+ "lint": "oxlint --import-plugin --tsconfig tsconfig.json src/",
14
+ "lint:fix": "oxlint --import-plugin --tsconfig tsconfig.json src/ --fix",
15
+ "format": "oxfmt --write src/",
16
+ "format:check": "oxfmt --check src/",
17
+ "test": "vitest run",
18
+ "test:watch": "vitest",
19
+ "typecheck": "tsc --noEmit"
20
+ },
21
+ "keywords": [
22
+ "opencode",
23
+ "cli",
24
+ "profile",
25
+ "config",
26
+ "ai"
27
+ ],
28
+ "author": "Jacob Wisniewski",
29
+ "license": "MIT",
30
+ "files": [
31
+ "dist",
32
+ "README.md",
33
+ "LICENSE"
34
+ ],
35
+ "engines": {
36
+ "node": ">=18.0.0"
37
+ },
38
+ "publishConfig": {
39
+ "access": "public"
40
+ },
41
+ "devDependencies": {
42
+ "@types/node": "^20.0.0",
43
+ "oxfmt": "^0.44.0",
44
+ "oxlint": "^1.59.0",
45
+ "typescript": "^5.0.0",
46
+ "vitest": "^4.1.3"
47
+ },
48
+ "dependencies": {
49
+ "commander": "^12.0.0",
50
+ "neverthrow": "^8.2.0",
51
+ "yaml": "^2.8.3",
52
+ "zod": "^4.3.6"
53
+ }
54
+ }