@papercraneai/cli 1.8.1 → 1.8.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/bin/papercrane.js CHANGED
@@ -927,7 +927,7 @@ program
927
927
  const currentLink = path.join(os.homedir(), '.papercrane', 'current');
928
928
  try {
929
929
  await fs.readlink(currentLink);
930
- workspaceDir = currentLink;
930
+ workspaceDir = await fs.realpath(currentLink);
931
931
  } catch {
932
932
  console.error(chalk.red('No workspace set up.'));
933
933
  console.error(chalk.dim('\nRun one of:'));
package/lib/dev-server.js CHANGED
@@ -257,25 +257,32 @@ export async function resetScaffolding(workspaceDir) {
257
257
  /**
258
258
  * Generate the project structure inside the workspace.
259
259
  * Creates package.json, tsconfig.json, postcss.config.mjs, app/layout.tsx, app/globals.css.
260
- * Pass { npmInstall: true } to also run npm install if node_modules doesn't exist.
260
+ *
261
+ * By default, scaffolding files are always overwritten to ensure stale versions
262
+ * (e.g. missing @source directive) don't cause broken builds.
263
+ *
264
+ * Options:
265
+ * npmInstall: true → run npm install if node_modules doesn't exist
266
+ * keepExisting: true → only write files that don't already exist
261
267
  */
262
- export async function generateScaffolding(workspaceDir, { npmInstall = false } = {}) {
268
+ export async function generateScaffolding(workspaceDir, { npmInstall = false, keepExisting = false } = {}) {
263
269
  const appDir = path.join(workspaceDir, 'app');
264
270
  await fs.mkdir(appDir, { recursive: true });
265
271
 
266
- // layout.tsx and globals.css in app/
267
- const layoutPath = path.join(appDir, 'layout.tsx');
268
- const globalsPath = path.join(appDir, 'globals.css');
269
-
270
- try { await fs.access(layoutPath); } catch {
271
- await fs.writeFile(layoutPath, LAYOUT_TEMPLATE, 'utf-8');
272
+ /** Write a file, skipping if keepExisting and file already exists. */
273
+ async function writeScaffold(filePath, content) {
274
+ if (keepExisting) {
275
+ try { await fs.access(filePath); return; } catch {}
276
+ }
277
+ await fs.writeFile(filePath, content, 'utf-8');
272
278
  }
273
279
 
274
- try { await fs.access(globalsPath); } catch {
275
- await fs.writeFile(globalsPath, GLOBALS_CSS_TEMPLATE, 'utf-8');
276
- }
280
+ // layout.tsx and globals.css in app/
281
+ await writeScaffold(path.join(appDir, 'layout.tsx'), LAYOUT_TEMPLATE);
282
+ await writeScaffold(path.join(appDir, 'globals.css'), GLOBALS_CSS_TEMPLATE);
277
283
 
278
284
  // package.json — @papercraneai/cli brings in next, react, and all dashboard deps
285
+ // Always keepExisting for package.json — user/system may have added deps.
279
286
  const pkgPath = path.join(workspaceDir, 'package.json');
280
287
  try { await fs.access(pkgPath); } catch {
281
288
  const pkg = {
@@ -288,16 +295,12 @@ export async function generateScaffolding(workspaceDir, { npmInstall = false } =
288
295
  }
289
296
 
290
297
  // .npmrc
291
- const npmrcPath = path.join(workspaceDir, '.npmrc');
292
- try { await fs.access(npmrcPath); } catch {
293
- await fs.writeFile(npmrcPath, [
294
- 'legacy-peer-deps=true', // react-simple-maps peer dep compatibility
295
- 'install-links=true', // ensures file: deps get transitive deps hoisted
296
- ].join('\n') + '\n', 'utf-8');
297
- }
298
+ await writeScaffold(path.join(workspaceDir, '.npmrc'), [
299
+ 'legacy-peer-deps=true', // react-simple-maps peer dep compatibility
300
+ 'install-links=true', // ensures file: deps get transitive deps hoisted
301
+ ].join('\n') + '\n');
298
302
 
299
303
  // tsconfig.json — path aliases resolve through node_modules/@papercraneai/cli
300
- const tsconfigPath = path.join(workspaceDir, 'tsconfig.json');
301
304
  const tsconfig = {
302
305
  compilerOptions: {
303
306
  target: "ES2017",
@@ -323,27 +326,29 @@ export async function generateScaffolding(workspaceDir, { npmInstall = false } =
323
326
  include: ["next-env.d.ts", "**/*.ts", "**/*.tsx", "**/*.mts"],
324
327
  exclude: ["node_modules"],
325
328
  };
326
- await fs.writeFile(tsconfigPath, JSON.stringify(tsconfig, null, 2), 'utf-8');
329
+ await writeScaffold(path.join(workspaceDir, 'tsconfig.json'), JSON.stringify(tsconfig, null, 2));
327
330
 
328
331
  // postcss.config.mjs — Tailwind compilation
329
- await fs.writeFile(path.join(workspaceDir, 'postcss.config.mjs'), POSTCSS_CONFIG, 'utf-8');
332
+ await writeScaffold(path.join(workspaceDir, 'postcss.config.mjs'), POSTCSS_CONFIG);
330
333
 
331
334
  // next.config.mjs
332
335
  // NOTE: next is pinned to 16.1.7 in package.json. Next.js 16.2.0 introduced
333
336
  // a cross-origin HMR block that breaks webpack-hmr over Daytona proxy domains.
334
337
  // To upgrade past 16.1.7, add allowedDevOrigins: ['*.daytonaproxy01.net'] to
335
338
  // the config below.
336
- const nextConfigPath = path.join(workspaceDir, 'next.config.mjs');
337
339
  const nextConfig = `/** @type {import('next').NextConfig} */
338
340
  const nextConfig = {
339
341
  transpilePackages: ['@papercraneai/cli', '@papercrane/dashboard-grid'],
340
342
  turbopack: {
341
343
  root: ${JSON.stringify(workspaceDir)},
342
344
  },
345
+ experimental: {
346
+ turbopackFileSystemCacheForDev: false,
347
+ },
343
348
  };
344
349
  export default nextConfig;
345
350
  `;
346
- await fs.writeFile(nextConfigPath, nextConfig, 'utf-8');
351
+ await writeScaffold(path.join(workspaceDir, 'next.config.mjs'), nextConfig);
347
352
 
348
353
  // npm install — only when explicitly requested and node_modules doesn't exist
349
354
  if (npmInstall) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@papercraneai/cli",
3
- "version": "1.8.1",
3
+ "version": "1.8.3",
4
4
  "description": "CLI tool for managing OAuth credentials for LLM integrations",
5
5
  "main": "index.js",
6
6
  "type": "module",