@goondan/cli 0.0.3-alpha1

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 (124) hide show
  1. package/dist/bin.d.ts +2 -0
  2. package/dist/bin.js +148 -0
  3. package/dist/bin.js.map +1 -0
  4. package/dist/commands/context.d.ts +8 -0
  5. package/dist/commands/context.js +2 -0
  6. package/dist/commands/context.js.map +1 -0
  7. package/dist/commands/doctor.d.ts +12 -0
  8. package/dist/commands/doctor.js +7 -0
  9. package/dist/commands/doctor.js.map +1 -0
  10. package/dist/commands/init.d.ts +12 -0
  11. package/dist/commands/init.js +29 -0
  12. package/dist/commands/init.js.map +1 -0
  13. package/dist/commands/instance-interactive.d.ts +19 -0
  14. package/dist/commands/instance-interactive.js +259 -0
  15. package/dist/commands/instance-interactive.js.map +1 -0
  16. package/dist/commands/instance.d.ts +30 -0
  17. package/dist/commands/instance.js +36 -0
  18. package/dist/commands/instance.js.map +1 -0
  19. package/dist/commands/logs.d.ts +12 -0
  20. package/dist/commands/logs.js +23 -0
  21. package/dist/commands/logs.js.map +1 -0
  22. package/dist/commands/package.d.ts +30 -0
  23. package/dist/commands/package.js +51 -0
  24. package/dist/commands/package.js.map +1 -0
  25. package/dist/commands/restart.d.ts +12 -0
  26. package/dist/commands/restart.js +14 -0
  27. package/dist/commands/restart.js.map +1 -0
  28. package/dist/commands/run.d.ts +12 -0
  29. package/dist/commands/run.js +33 -0
  30. package/dist/commands/run.js.map +1 -0
  31. package/dist/commands/validate.d.ts +12 -0
  32. package/dist/commands/validate.js +22 -0
  33. package/dist/commands/validate.js.map +1 -0
  34. package/dist/constants.d.ts +2 -0
  35. package/dist/constants.js +3 -0
  36. package/dist/constants.js.map +1 -0
  37. package/dist/errors.d.ts +22 -0
  38. package/dist/errors.js +93 -0
  39. package/dist/errors.js.map +1 -0
  40. package/dist/formatter.d.ts +7 -0
  41. package/dist/formatter.js +141 -0
  42. package/dist/formatter.js.map +1 -0
  43. package/dist/help.d.ts +1 -0
  44. package/dist/help.js +25 -0
  45. package/dist/help.js.map +1 -0
  46. package/dist/index.d.ts +6 -0
  47. package/dist/index.js +9 -0
  48. package/dist/index.js.map +1 -0
  49. package/dist/options.d.ts +13 -0
  50. package/dist/options.js +57 -0
  51. package/dist/options.js.map +1 -0
  52. package/dist/parser.d.ts +85 -0
  53. package/dist/parser.js +123 -0
  54. package/dist/parser.js.map +1 -0
  55. package/dist/router.d.ts +2 -0
  56. package/dist/router.js +130 -0
  57. package/dist/router.js.map +1 -0
  58. package/dist/services/config.d.ts +13 -0
  59. package/dist/services/config.js +141 -0
  60. package/dist/services/config.js.map +1 -0
  61. package/dist/services/conversation-state.d.ts +20 -0
  62. package/dist/services/conversation-state.js +198 -0
  63. package/dist/services/conversation-state.js.map +1 -0
  64. package/dist/services/defaults.d.ts +2 -0
  65. package/dist/services/defaults.js +92 -0
  66. package/dist/services/defaults.js.map +1 -0
  67. package/dist/services/doctor.d.ts +8 -0
  68. package/dist/services/doctor.js +160 -0
  69. package/dist/services/doctor.js.map +1 -0
  70. package/dist/services/env.d.ts +6 -0
  71. package/dist/services/env.js +76 -0
  72. package/dist/services/env.js.map +1 -0
  73. package/dist/services/init.d.ts +4 -0
  74. package/dist/services/init.js +174 -0
  75. package/dist/services/init.js.map +1 -0
  76. package/dist/services/instances.d.ts +7 -0
  77. package/dist/services/instances.js +393 -0
  78. package/dist/services/instances.js.map +1 -0
  79. package/dist/services/logs.d.ts +6 -0
  80. package/dist/services/logs.js +131 -0
  81. package/dist/services/logs.js.map +1 -0
  82. package/dist/services/package.d.ts +11 -0
  83. package/dist/services/package.js +630 -0
  84. package/dist/services/package.js.map +1 -0
  85. package/dist/services/path.d.ts +5 -0
  86. package/dist/services/path.js +25 -0
  87. package/dist/services/path.js.map +1 -0
  88. package/dist/services/registry.d.ts +12 -0
  89. package/dist/services/registry.js +219 -0
  90. package/dist/services/registry.js.map +1 -0
  91. package/dist/services/runtime-restart-signal.d.ts +5 -0
  92. package/dist/services/runtime-restart-signal.js +18 -0
  93. package/dist/services/runtime-restart-signal.js.map +1 -0
  94. package/dist/services/runtime-restart.d.ts +11 -0
  95. package/dist/services/runtime-restart.js +151 -0
  96. package/dist/services/runtime-restart.js.map +1 -0
  97. package/dist/services/runtime-routing.d.ts +40 -0
  98. package/dist/services/runtime-routing.js +154 -0
  99. package/dist/services/runtime-routing.js.map +1 -0
  100. package/dist/services/runtime-runner-connector-child.d.ts +1 -0
  101. package/dist/services/runtime-runner-connector-child.js +188 -0
  102. package/dist/services/runtime-runner-connector-child.js.map +1 -0
  103. package/dist/services/runtime-runner-protocol.d.ts +12 -0
  104. package/dist/services/runtime-runner-protocol.js +14 -0
  105. package/dist/services/runtime-runner-protocol.js.map +1 -0
  106. package/dist/services/runtime-runner.d.ts +1 -0
  107. package/dist/services/runtime-runner.js +2595 -0
  108. package/dist/services/runtime-runner.js.map +1 -0
  109. package/dist/services/runtime.d.ts +10 -0
  110. package/dist/services/runtime.js +569 -0
  111. package/dist/services/runtime.js.map +1 -0
  112. package/dist/services/turn-policy.d.ts +7 -0
  113. package/dist/services/turn-policy.js +13 -0
  114. package/dist/services/turn-policy.js.map +1 -0
  115. package/dist/services/validator.d.ts +6 -0
  116. package/dist/services/validator.js +126 -0
  117. package/dist/services/validator.js.map +1 -0
  118. package/dist/types.d.ts +243 -0
  119. package/dist/types.js +2 -0
  120. package/dist/types.js.map +1 -0
  121. package/dist/utils.d.ts +7 -0
  122. package/dist/utils.js +72 -0
  123. package/dist/utils.js.map +1 -0
  124. package/package.json +30 -0
@@ -0,0 +1,126 @@
1
+ import path from 'node:path';
2
+ import { readFile, writeFile } from 'node:fs/promises';
3
+ import { BundleLoader, isJsonObject, parseYamlDocument, splitYamlDocuments, } from '@goondan/runtime';
4
+ import { exists } from '../utils.js';
5
+ import { resolveManifestPath } from './path.js';
6
+ const ERROR_HELP_BASE_URL = 'https://docs.goondan.io/errors';
7
+ export class DefaultBundleValidator {
8
+ cwd;
9
+ constructor(cwd) {
10
+ this.cwd = cwd;
11
+ }
12
+ async validate(pathOrFile, strict, fix) {
13
+ const manifestPath = resolveManifestPath(this.cwd, pathOrFile);
14
+ const errors = [];
15
+ const warnings = [];
16
+ const hasManifest = await exists(manifestPath);
17
+ if (!hasManifest) {
18
+ errors.push({
19
+ code: 'FILE_NOT_FOUND',
20
+ message: 'Bundle 파일을 찾을 수 없습니다.',
21
+ path: manifestPath,
22
+ suggestion: 'goondan.yaml 경로를 확인하거나 파일을 생성하세요.',
23
+ helpUrl: `${ERROR_HELP_BASE_URL}/FILE_NOT_FOUND`,
24
+ });
25
+ return { valid: false, errors, warnings };
26
+ }
27
+ if (fix) {
28
+ const fixResult = await tryFixMissingApiVersion(manifestPath);
29
+ if (fixResult.applied) {
30
+ warnings.push({
31
+ code: 'API_VERSION_FIXED',
32
+ message: `apiVersion 누락 문서 ${fixResult.fixedCount}개를 자동 수정했습니다.`,
33
+ path: manifestPath,
34
+ suggestion: '변경된 내용을 검토하고 필요 시 세부 필드를 정리하세요.',
35
+ helpUrl: `${ERROR_HELP_BASE_URL}/API_VERSION_FIXED`,
36
+ });
37
+ }
38
+ }
39
+ const bundleDir = path.dirname(manifestPath);
40
+ const loader = new BundleLoader();
41
+ const loaded = await loader.load(bundleDir);
42
+ errors.push(...loaded.errors.map((error) => toDiagnosticIssue(error)));
43
+ if (loaded.resources.length === 0) {
44
+ errors.push({
45
+ code: 'KIND_MISSING',
46
+ message: 'kind 필드를 가진 리소스 문서를 찾을 수 없습니다.',
47
+ path: manifestPath,
48
+ suggestion: '최소 하나 이상의 리소스 문서를 정의하세요.',
49
+ helpUrl: `${ERROR_HELP_BASE_URL}/KIND_MISSING`,
50
+ });
51
+ }
52
+ if (!loaded.resources.some((resource) => resource.kind === 'Swarm')) {
53
+ warnings.push({
54
+ code: 'SWARM_MISSING',
55
+ message: 'Swarm 리소스를 찾지 못했습니다.',
56
+ path: manifestPath,
57
+ suggestion: '실행 대상 Swarm 리소스를 추가하세요.',
58
+ helpUrl: `${ERROR_HELP_BASE_URL}/SWARM_MISSING`,
59
+ });
60
+ }
61
+ if (strict && warnings.length > 0) {
62
+ warnings.forEach((warning) => {
63
+ errors.push({
64
+ ...warning,
65
+ code: `STRICT_${warning.code}`,
66
+ message: `[strict] ${warning.message}`,
67
+ });
68
+ });
69
+ }
70
+ return {
71
+ valid: errors.length === 0,
72
+ errors,
73
+ warnings,
74
+ };
75
+ }
76
+ }
77
+ function toDiagnosticIssue(error) {
78
+ return {
79
+ code: error.code,
80
+ message: error.message,
81
+ path: error.path,
82
+ suggestion: error.suggestion,
83
+ helpUrl: error.helpUrl ?? `${ERROR_HELP_BASE_URL}/${error.code}`,
84
+ };
85
+ }
86
+ async function tryFixMissingApiVersion(manifestPath) {
87
+ const source = await readFile(manifestPath, 'utf8');
88
+ const docs = splitYamlDocuments(source);
89
+ if (docs.length === 0) {
90
+ return { applied: false, fixedCount: 0 };
91
+ }
92
+ let fixedCount = 0;
93
+ const fixedDocs = docs.map((doc) => {
94
+ const trimmed = doc.trim();
95
+ if (trimmed.length === 0) {
96
+ return doc;
97
+ }
98
+ try {
99
+ const parsed = parseYamlDocument(doc);
100
+ if (!isJsonObject(parsed)) {
101
+ return doc;
102
+ }
103
+ const hasKind = typeof parsed.kind === 'string' && parsed.kind.trim().length > 0;
104
+ const hasApiVersion = typeof parsed.apiVersion === 'string' && parsed.apiVersion.trim().length > 0;
105
+ if (!hasKind || hasApiVersion) {
106
+ return doc;
107
+ }
108
+ fixedCount += 1;
109
+ return `apiVersion: goondan.ai/v1\n${doc}`;
110
+ }
111
+ catch {
112
+ return doc;
113
+ }
114
+ });
115
+ if (fixedCount === 0) {
116
+ return { applied: false, fixedCount: 0 };
117
+ }
118
+ const serialized = fixedDocs.join('\n---\n');
119
+ const output = serialized.endsWith('\n') ? serialized : `${serialized}\n`;
120
+ await writeFile(manifestPath, output, 'utf8');
121
+ return {
122
+ applied: true,
123
+ fixedCount,
124
+ };
125
+ }
126
+ //# sourceMappingURL=validator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validator.js","sourceRoot":"","sources":["../../src/services/validator.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,243 @@
1
+ export type ExitCode = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 130;
2
+ export type OutputFormat = 'text' | 'json' | 'github';
3
+ export interface DiagnosticIssue {
4
+ code: string;
5
+ message: string;
6
+ path?: string;
7
+ resource?: string;
8
+ field?: string;
9
+ suggestion?: string;
10
+ helpUrl?: string;
11
+ }
12
+ export interface ValidationResult {
13
+ valid: boolean;
14
+ errors: DiagnosticIssue[];
15
+ warnings: DiagnosticIssue[];
16
+ }
17
+ export interface RuntimeStartRequest {
18
+ bundlePath: string;
19
+ swarm?: string;
20
+ instanceKey?: string;
21
+ watch: boolean;
22
+ foreground?: boolean;
23
+ interactive: boolean;
24
+ input?: string;
25
+ inputFile?: string;
26
+ noInstall: boolean;
27
+ envFile?: string;
28
+ stateRoot?: string;
29
+ }
30
+ export interface RuntimeStartResult {
31
+ instanceKey: string;
32
+ pid?: number;
33
+ completion?: Promise<ExitCode>;
34
+ }
35
+ export interface RuntimeRestartRequest {
36
+ agent?: string;
37
+ instanceKey?: string;
38
+ fresh: boolean;
39
+ stateRoot?: string;
40
+ }
41
+ export interface RuntimeRestartResult {
42
+ restarted: string[];
43
+ instanceKey?: string;
44
+ pid?: number;
45
+ }
46
+ export type LogStream = 'stdout' | 'stderr' | 'both';
47
+ export interface LogReadRequest {
48
+ instanceKey?: string;
49
+ process: string;
50
+ stream: LogStream;
51
+ lines: number;
52
+ stateRoot?: string;
53
+ }
54
+ export interface LogChunk {
55
+ stream: 'stdout' | 'stderr';
56
+ path: string;
57
+ lines: string[];
58
+ }
59
+ export interface LogReadResult {
60
+ instanceKey: string;
61
+ process: string;
62
+ chunks: LogChunk[];
63
+ }
64
+ export interface InstanceRecord {
65
+ key: string;
66
+ agent: string;
67
+ status: string;
68
+ createdAt: string;
69
+ updatedAt: string;
70
+ }
71
+ export interface ListInstancesRequest {
72
+ agent?: string;
73
+ limit: number;
74
+ all: boolean;
75
+ stateRoot?: string;
76
+ }
77
+ export interface DeleteInstanceRequest {
78
+ key: string;
79
+ force: boolean;
80
+ stateRoot?: string;
81
+ }
82
+ export interface PackageAddRequest {
83
+ ref: string;
84
+ dev: boolean;
85
+ exact: boolean;
86
+ registry?: string;
87
+ bundlePath: string;
88
+ stateRoot?: string;
89
+ }
90
+ export interface PackageAddResult {
91
+ ref: string;
92
+ added: boolean;
93
+ manifestPath: string;
94
+ resolvedVersion?: string;
95
+ }
96
+ export interface PackageInstallRequest {
97
+ frozenLockfile: boolean;
98
+ bundlePath: string;
99
+ registry?: string;
100
+ stateRoot?: string;
101
+ }
102
+ export interface PackageInstallResult {
103
+ installed: number;
104
+ lockfilePath?: string;
105
+ }
106
+ export interface PackagePublishRequest {
107
+ path: string;
108
+ tag: string;
109
+ access: 'public' | 'restricted';
110
+ dryRun: boolean;
111
+ registry?: string;
112
+ stateRoot?: string;
113
+ }
114
+ export interface PackagePublishResult {
115
+ published: boolean;
116
+ registryUrl: string;
117
+ packageName: string;
118
+ version: string;
119
+ tag: string;
120
+ dryRun: boolean;
121
+ }
122
+ export interface RegistryPackageMetadata {
123
+ name: string;
124
+ latestVersion: string;
125
+ }
126
+ export interface RegistryVersionDist {
127
+ tarball: string;
128
+ shasum: string;
129
+ integrity: string;
130
+ }
131
+ export interface RegistryPackageVersionMetadata {
132
+ version: string;
133
+ dependencies: Record<string, string>;
134
+ deprecated: string;
135
+ access: 'public' | 'restricted';
136
+ dist: RegistryVersionDist;
137
+ }
138
+ export interface RegistryPublishAttachment {
139
+ data: string;
140
+ contentType?: string;
141
+ length?: number;
142
+ }
143
+ export interface RegistryPublishPayload {
144
+ name: string;
145
+ version: string;
146
+ access: 'public' | 'restricted';
147
+ description?: string;
148
+ dependencies?: Record<string, string>;
149
+ deprecated?: string;
150
+ 'dist-tags'?: Record<string, string>;
151
+ _attachments: Record<string, RegistryPublishAttachment>;
152
+ }
153
+ export interface RegistryPublishResult {
154
+ ok: boolean;
155
+ registryUrl: string;
156
+ }
157
+ export interface RegistryClient {
158
+ resolvePackage(ref: string, registryUrl: string, token?: string): Promise<RegistryPackageMetadata>;
159
+ getPackageVersion(packageName: string, version: string, registryUrl: string, token?: string): Promise<RegistryPackageVersionMetadata>;
160
+ publishPackage(payload: RegistryPublishPayload, registryUrl: string, token?: string): Promise<RegistryPublishResult>;
161
+ }
162
+ export interface RuntimeController {
163
+ startOrchestrator(request: RuntimeStartRequest): Promise<RuntimeStartResult>;
164
+ restart(request: RuntimeRestartRequest): Promise<RuntimeRestartResult>;
165
+ }
166
+ export interface BundleValidator {
167
+ validate(pathOrFile: string, strict: boolean, fix: boolean): Promise<ValidationResult>;
168
+ }
169
+ export interface InstanceStore {
170
+ list(request: ListInstancesRequest): Promise<InstanceRecord[]>;
171
+ delete(request: DeleteInstanceRequest): Promise<boolean>;
172
+ }
173
+ export interface PackageService {
174
+ addDependency(request: PackageAddRequest): Promise<PackageAddResult>;
175
+ installDependencies(request: PackageInstallRequest): Promise<PackageInstallResult>;
176
+ publishPackage(request: PackagePublishRequest): Promise<PackagePublishResult>;
177
+ }
178
+ export interface DoctorCheck {
179
+ category: string;
180
+ name: string;
181
+ level: 'ok' | 'warn' | 'fail';
182
+ detail: string;
183
+ suggestion?: string;
184
+ }
185
+ export interface DoctorReport {
186
+ checks: DoctorCheck[];
187
+ passed: number;
188
+ warnings: number;
189
+ errors: number;
190
+ }
191
+ export interface DoctorService {
192
+ run(bundlePath: string, fix: boolean, stateRoot?: string): Promise<DoctorReport>;
193
+ }
194
+ export interface LogService {
195
+ read(request: LogReadRequest): Promise<LogReadResult>;
196
+ }
197
+ export type InitTemplate = 'default' | 'multi-agent' | 'package' | 'minimal';
198
+ export interface InitRequest {
199
+ targetDir: string;
200
+ name: string;
201
+ template: InitTemplate;
202
+ asPackage: boolean;
203
+ git: boolean;
204
+ force: boolean;
205
+ }
206
+ export interface InitResult {
207
+ projectDir: string;
208
+ template: InitTemplate;
209
+ filesCreated: string[];
210
+ gitInitialized: boolean;
211
+ }
212
+ export interface InitService {
213
+ init(request: InitRequest): Promise<InitResult>;
214
+ }
215
+ export interface TerminalIO {
216
+ readonly stdinIsTTY: boolean;
217
+ readonly stdoutIsTTY: boolean;
218
+ readonly columns: number;
219
+ setRawMode(enable: boolean): void;
220
+ onData(callback: (data: Buffer) => void): void;
221
+ offData(callback: (data: Buffer) => void): void;
222
+ resume(): void;
223
+ pause(): void;
224
+ write(data: string): void;
225
+ }
226
+ export interface CliIO {
227
+ out(message: string): void;
228
+ err(message: string): void;
229
+ }
230
+ export interface CliDependencies {
231
+ io: CliIO;
232
+ terminal: TerminalIO;
233
+ env: NodeJS.ProcessEnv;
234
+ cwd: string;
235
+ version: string;
236
+ runtime: RuntimeController;
237
+ validator: BundleValidator;
238
+ instances: InstanceStore;
239
+ packages: PackageService;
240
+ doctor: DoctorService;
241
+ logs: LogService;
242
+ init: InitService;
243
+ }
package/dist/types.js ADDED
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,7 @@
1
+ export declare function isObjectRecord(value: unknown): value is Record<string, unknown>;
2
+ export declare function exists(targetPath: string): Promise<boolean>;
3
+ export declare function resolveBundlePath(cwd: string, configuredPath: string): Promise<string>;
4
+ export declare function readTextFileIfExists(filePath: string): Promise<string | undefined>;
5
+ export declare function trimQuotes(value: string): string;
6
+ export declare function formatDate(input: Date): string;
7
+ export declare function splitYamlDocuments(content: string): string[];
package/dist/utils.js ADDED
@@ -0,0 +1,72 @@
1
+ import { access, readFile } from 'node:fs/promises';
2
+ import path from 'node:path';
3
+ export function isObjectRecord(value) {
4
+ return typeof value === 'object' && value !== null;
5
+ }
6
+ export async function exists(targetPath) {
7
+ try {
8
+ await access(targetPath);
9
+ return true;
10
+ }
11
+ catch {
12
+ return false;
13
+ }
14
+ }
15
+ export async function resolveBundlePath(cwd, configuredPath) {
16
+ const candidate = path.resolve(cwd, configuredPath);
17
+ const candidateExists = await exists(candidate);
18
+ if (candidateExists) {
19
+ return candidate;
20
+ }
21
+ return candidate;
22
+ }
23
+ export async function readTextFileIfExists(filePath) {
24
+ const ok = await exists(filePath);
25
+ if (!ok) {
26
+ return undefined;
27
+ }
28
+ return readFile(filePath, 'utf8');
29
+ }
30
+ export function trimQuotes(value) {
31
+ const trimmed = value.trim();
32
+ if (trimmed.length >= 2) {
33
+ const first = trimmed[0];
34
+ const last = trimmed[trimmed.length - 1];
35
+ if ((first === '"' && last === '"') || (first === "'" && last === "'")) {
36
+ return trimmed.slice(1, -1);
37
+ }
38
+ }
39
+ return trimmed;
40
+ }
41
+ export function formatDate(input) {
42
+ const year = String(input.getFullYear());
43
+ const month = String(input.getMonth() + 1).padStart(2, '0');
44
+ const day = String(input.getDate()).padStart(2, '0');
45
+ const hour = String(input.getHours()).padStart(2, '0');
46
+ const minute = String(input.getMinutes()).padStart(2, '0');
47
+ const second = String(input.getSeconds()).padStart(2, '0');
48
+ return `${year}-${month}-${day} ${hour}:${minute}:${second}`;
49
+ }
50
+ export function splitYamlDocuments(content) {
51
+ const lines = content.split(/\r?\n/);
52
+ const documents = [[]];
53
+ for (const line of lines) {
54
+ if (line.trim() === '---') {
55
+ documents.push([]);
56
+ continue;
57
+ }
58
+ const lastIndex = documents.length - 1;
59
+ const lastDocument = documents[lastIndex];
60
+ if (lastDocument) {
61
+ lastDocument.push(line);
62
+ }
63
+ }
64
+ const normalized = documents
65
+ .map((doc) => doc.join('\n').trimEnd())
66
+ .filter((doc) => doc.length > 0);
67
+ if (normalized.length === 0) {
68
+ return [''];
69
+ }
70
+ return normalized;
71
+ }
72
+ //# sourceMappingURL=utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,30 @@
1
+ {
2
+ "name": "@goondan/cli",
3
+ "version": "0.0.3-alpha1",
4
+ "description": "Goondan CLI (gdn)",
5
+ "type": "module",
6
+ "bin": {
7
+ "gdn": "dist/bin.js"
8
+ },
9
+ "main": "dist/index.js",
10
+ "types": "dist/index.d.ts",
11
+ "files": [
12
+ "dist"
13
+ ],
14
+ "dependencies": {
15
+ "@optique/core": "^0.9.0",
16
+ "@optique/run": "^0.9.0",
17
+ "@goondan/runtime": "0.0.3-alpha1"
18
+ },
19
+ "devDependencies": {
20
+ "@types/node": "^22.19.7",
21
+ "typescript": "^5.9.3",
22
+ "vitest": "^2.1.9"
23
+ },
24
+ "scripts": {
25
+ "build": "tsc -p tsconfig.json && chmod +x dist/bin.js",
26
+ "typecheck": "tsc -p tsconfig.json --noEmit",
27
+ "test": "pnpm --filter @goondan/runtime build && vitest run",
28
+ "clean": "rm -rf dist"
29
+ }
30
+ }