@celilo/cli 0.1.1 → 0.1.3

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@celilo/cli",
3
- "version": "0.1.1",
3
+ "version": "0.1.3",
4
4
  "description": "Celilo — home lab orchestration CLI",
5
5
  "type": "module",
6
6
  "bin": {
@@ -10,7 +10,8 @@
10
10
  "bin/",
11
11
  "src/",
12
12
  "drizzle/",
13
- "schemas/"
13
+ "schemas/",
14
+ "tsconfig.json"
14
15
  ],
15
16
  "keywords": ["celilo", "homelab", "orchestration", "ansible", "terraform"],
16
17
  "license": "MIT",
@@ -1,6 +1,7 @@
1
1
  import { execSync } from 'node:child_process';
2
- import { existsSync } from 'node:fs';
2
+ import { cpSync, existsSync, mkdtempSync, rmSync } from 'node:fs';
3
3
  import { readFile, readdir, unlink, writeFile } from 'node:fs/promises';
4
+ import { tmpdir } from 'node:os';
4
5
  import { basename, join, relative } from 'node:path';
5
6
  import { create as tarCreate } from 'tar';
6
7
  import { parse as parseYaml } from 'yaml';
@@ -139,9 +140,20 @@ export async function buildModule(options: ModuleBuildOptions): Promise<ModuleBu
139
140
  return { success: false, error: dirError };
140
141
  }
141
142
 
143
+ // Copy source to a temp directory so the build doesn't pollute the
144
+ // source tree and avoids workspace resolution issues (e.g., a
145
+ // monorepo's root package.json triggering bun workspace linking).
146
+ const buildDir = mkdtempSync(join(tmpdir(), 'celilo-package-'));
147
+
142
148
  try {
149
+ console.log('Copying source to build directory...');
150
+ cpSync(sourceDir, buildDir, {
151
+ recursive: true,
152
+ filter: (src) => !shouldExclude(relative(sourceDir, src)),
153
+ });
154
+
143
155
  // Read manifest to get module ID
144
- const manifestPath = join(sourceDir, 'manifest.yml');
156
+ const manifestPath = join(buildDir, 'manifest.yml');
145
157
  const manifestContent = await readFile(manifestPath, 'utf-8');
146
158
  const idMatch = manifestContent.match(/^id:\s*["']?([a-z0-9-]+)["']?/m);
147
159
  if (!idMatch) {
@@ -161,18 +173,19 @@ export async function buildModule(options: ModuleBuildOptions): Promise<ModuleBu
161
173
  console.log(`Building module (${manifest.build.command ? 'command' : 'script'})...`);
162
174
  try {
163
175
  execSync(buildCmd, {
164
- cwd: sourceDir,
176
+ cwd: buildDir,
165
177
  stdio: 'inherit',
166
178
  timeout: 300_000,
167
179
  });
168
- } catch {
169
- return { success: false, error: 'Build failed' };
180
+ } catch (buildError) {
181
+ const msg = buildError instanceof Error ? buildError.message : String(buildError);
182
+ return { success: false, error: `Auto-build failed: Build exited with code ${msg}` };
170
183
  }
171
184
 
172
185
  // Verify artifacts exist
173
186
  if (manifest.build.artifacts) {
174
187
  const missing = manifest.build.artifacts.filter(
175
- (a: string) => !existsSync(join(sourceDir, a)),
188
+ (a: string) => !existsSync(join(buildDir, a)),
176
189
  );
177
190
  if (missing.length > 0) {
178
191
  return {
@@ -184,45 +197,40 @@ export async function buildModule(options: ModuleBuildOptions): Promise<ModuleBu
184
197
  }
185
198
 
186
199
  // Compute checksums
187
- const checksumsData = await computeChecksums(sourceDir);
200
+ const checksumsData = await computeChecksums(buildDir);
188
201
  const checksumsJson = JSON.stringify(checksumsData, null, 2);
189
202
 
190
203
  // Sign checksums
191
204
  const signature = await signChecksums(checksumsJson, masterKeyPath);
192
205
 
193
- // Write temporary checksums.json and signature.sig
194
- const checksumsPath = join(sourceDir, 'checksums.json');
195
- const signaturePath = join(sourceDir, 'signature.sig');
206
+ // Write checksums.json and signature.sig into build dir
207
+ const checksumsPath = join(buildDir, 'checksums.json');
208
+ const signaturePath = join(buildDir, 'signature.sig');
196
209
  await writeFile(checksumsPath, checksumsJson);
197
210
  await writeFile(signaturePath, signature);
198
211
 
199
- try {
200
- // Create tarball
201
- const finalOutputPath = outputPath || join(process.cwd(), `${moduleId}.netapp`);
202
- await tarCreate(
203
- {
204
- file: finalOutputPath,
205
- cwd: sourceDir,
206
- gzip: true,
207
- },
208
- ['checksums.json', 'signature.sig', ...Object.keys(checksumsData.files)],
209
- );
210
-
211
- return {
212
- success: true,
213
- packagePath: finalOutputPath,
214
- };
215
- } finally {
216
- // Clean up temporary files
217
- await Promise.all([
218
- unlink(checksumsPath).catch(() => {}),
219
- unlink(signaturePath).catch(() => {}),
220
- ]);
221
- }
212
+ // Create tarball
213
+ const finalOutputPath = outputPath || join(process.cwd(), `${moduleId}.netapp`);
214
+ await tarCreate(
215
+ {
216
+ file: finalOutputPath,
217
+ cwd: buildDir,
218
+ gzip: true,
219
+ },
220
+ ['checksums.json', 'signature.sig', ...Object.keys(checksumsData.files)],
221
+ );
222
+
223
+ return {
224
+ success: true,
225
+ packagePath: finalOutputPath,
226
+ };
222
227
  } catch (error) {
223
228
  return {
224
229
  success: false,
225
230
  error: `Failed to build module: ${error instanceof Error ? error.message : 'Unknown error'}`,
226
231
  };
232
+ } finally {
233
+ // Clean up temp directory
234
+ rmSync(buildDir, { recursive: true, force: true });
227
235
  }
228
236
  }
package/tsconfig.json ADDED
@@ -0,0 +1,20 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ESNext",
4
+ "module": "ESNext",
5
+ "lib": ["ESNext"],
6
+ "moduleResolution": "bundler",
7
+ "strict": true,
8
+ "esModuleInterop": true,
9
+ "skipLibCheck": true,
10
+ "forceConsistentCasingInFileNames": true,
11
+ "resolveJsonModule": true,
12
+ "isolatedModules": true,
13
+ "types": ["bun-types"],
14
+ "paths": {
15
+ "@/*": ["./src/*"]
16
+ }
17
+ },
18
+ "include": ["src/**/*"],
19
+ "exclude": ["node_modules"]
20
+ }