@papercraneai/cli 1.8.0 → 1.8.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.
package/bin/papercrane.js CHANGED
@@ -8,7 +8,7 @@ import path from 'path';
8
8
  import os from 'os';
9
9
  import http from 'http';
10
10
  import { http as httpClient } from '../lib/axios-client.js';
11
- import { setApiKey, clearConfig, isLoggedIn, setDefaultWorkspace, getDefaultWorkspace, setOrgId, getOrgId } from '../lib/config.js';
11
+ import { setApiKey, clearConfig, isLoggedIn, setOrgId, getOrgId } from '../lib/config.js';
12
12
  import { validateApiKey } from '../lib/cloud-client.js';
13
13
  import { listFunctions, getFunction, runFunction, formatDescribe, formatDescribeRoot, formatFlat, formatResult, formatUnconnected } from '../lib/function-client.js';
14
14
  import { listWorkspaces, resolveWorkspaceId, getLocalWorkspacePath, pullWorkspace, pushWorkspace } from '../lib/environment-client.js';
@@ -22,15 +22,18 @@ async function requireWorkspace() {
22
22
  console.error(chalk.red('Not logged in. Run: papercrane login'));
23
23
  process.exit(1);
24
24
  }
25
- const defaultWs = await getDefaultWorkspace();
26
- if (!defaultWs) {
27
- console.error(chalk.red('No workspace selected.'));
28
- console.error(chalk.dim('\nRun these commands first:'));
29
- console.error(chalk.dim(' papercrane workspaces list'));
30
- console.error(chalk.dim(' papercrane workspaces use <id>'));
31
- process.exit(1);
32
- }
33
- return defaultWs;
25
+ // Resolve current workspace from ~/.papercrane/current symlink
26
+ const currentLink = path.join(os.homedir(), '.papercrane', 'current');
27
+ try {
28
+ const target = await fs.readlink(currentLink);
29
+ const match = target.match(/workspaces\/(\d+)/);
30
+ if (match) return parseInt(match[1], 10);
31
+ } catch {}
32
+ console.error(chalk.red('No workspace selected.'));
33
+ console.error(chalk.dim('\nRun these commands first:'));
34
+ console.error(chalk.dim(' papercrane workspaces list'));
35
+ console.error(chalk.dim(' papercrane workspaces use <id>'));
36
+ process.exit(1);
34
37
  }
35
38
 
36
39
  /**
@@ -47,7 +50,6 @@ async function showPostLoginHelp() {
47
50
  if (workspaces.length === 1) {
48
51
  // Auto-select the only workspace
49
52
  const ws = workspaces[0];
50
- await setDefaultWorkspace(ws.id);
51
53
 
52
54
  const workspaceDir = getLocalWorkspacePath(ws.id);
53
55
  const { generateScaffolding } = await import('../lib/dev-server.js');
@@ -451,7 +453,7 @@ program
451
453
  console.log(chalk.cyan(`Scaffolding workspace in ${dir}...`));
452
454
 
453
455
  const { generateScaffolding } = await import('../lib/dev-server.js');
454
- await generateScaffolding(dir, { skipInstall: !options.npmInstall });
456
+ await generateScaffolding(dir, { npmInstall: options.npmInstall });
455
457
 
456
458
  // Set ~/.papercrane/current symlink → scaffolded dir
457
459
  const currentLink = path.join(os.homedir(), '.papercrane', 'current');
@@ -800,7 +802,15 @@ workspacesCmd
800
802
  }
801
803
 
802
804
  const workspaces = await listWorkspaces();
803
- const defaultWs = await getDefaultWorkspace();
805
+
806
+ // Resolve current workspace from ~/.papercrane/current symlink
807
+ let currentWsId = null;
808
+ try {
809
+ const currentLink = path.join(os.homedir(), '.papercrane', 'current');
810
+ const target = await fs.readlink(currentLink);
811
+ const match = target.match(/workspaces\/(\d+)/);
812
+ if (match) currentWsId = parseInt(match[1], 10);
813
+ } catch {}
804
814
 
805
815
  if (!workspaces || workspaces.length === 0) {
806
816
  console.log(chalk.yellow('No workspaces found.'));
@@ -809,12 +819,12 @@ workspacesCmd
809
819
 
810
820
  console.log(chalk.bold('\nWorkspaces:\n'));
811
821
  for (const ws of workspaces) {
812
- const isDefault = ws.id === defaultWs;
822
+ const isCurrent = ws.id === currentWsId;
813
823
  const status = ws.status === 'ready' ? chalk.green('ready') : chalk.yellow(ws.status);
814
- const defaultMarker = isDefault ? chalk.cyan(' (default)') : '';
824
+ const currentMarker = isCurrent ? chalk.cyan(' (current)') : '';
815
825
  const typeLabel = ws.type === 'external' ? chalk.dim('external') : chalk.dim('managed');
816
826
  const createdDate = ws.createdAt ? new Date(ws.createdAt).toLocaleDateString() : '';
817
- console.log(` ${chalk.bold(ws.id)} ${ws.name || '(unnamed)'} ${typeLabel} ${status} ${chalk.dim(createdDate)}${defaultMarker}`);
827
+ console.log(` ${chalk.bold(ws.id)} ${ws.name || '(unnamed)'} ${typeLabel} ${status} ${chalk.dim(createdDate)}${currentMarker}`);
818
828
  }
819
829
  console.log();
820
830
  } catch (error) {
@@ -825,7 +835,7 @@ workspacesCmd
825
835
 
826
836
  workspacesCmd
827
837
  .command('use <id>')
828
- .description('Set the default workspace')
838
+ .description('Set the current workspace')
829
839
  .option('--reset-scaffolding', 'Regenerate scaffolding files (layout.tsx, globals.css, configs)')
830
840
  .action(async (id, options) => {
831
841
  try {
@@ -841,8 +851,6 @@ workspacesCmd
841
851
  process.exit(1);
842
852
  }
843
853
 
844
- await setDefaultWorkspace(wsId);
845
-
846
854
  const { generateScaffolding, resetScaffolding } = await import('../lib/dev-server.js');
847
855
  const workspaceDir = getLocalWorkspacePath(wsId);
848
856
 
@@ -884,7 +892,7 @@ workspacesCmd
884
892
  await fs.symlink(workspaceDir, currentLink);
885
893
  }
886
894
 
887
- console.log(chalk.green(`✓ Default workspace set to ${wsId}`));
895
+ console.log(chalk.green(`✓ Current workspace set to ${wsId}`));
888
896
  console.log(chalk.dim(` ${currentLink} → ${workspaceDir}`));
889
897
  console.log(chalk.dim(` Dashboards: ${workspaceDir}/app/\n`));
890
898
  } catch (error) {
@@ -940,20 +948,16 @@ program
940
948
  console.log(chalk.dim('Build cache cleared.'));
941
949
  }
942
950
 
943
- await generateScaffolding(workspaceDir, { skipInstall: true });
951
+ await generateScaffolding(workspaceDir, { npmInstall: options.npmInstall });
944
952
 
945
- // npm installdev server won't work without node_modules
953
+ // Check node_modules exists fail fast if missing
946
954
  const nmDir = path.join(workspaceDir, 'node_modules');
947
- if (options.npmInstall) {
948
- console.log(chalk.dim('Running npm install...'));
949
- execSync('npm install --prefer-offline', { cwd: workspaceDir, stdio: 'inherit' });
950
- } else {
951
- try {
952
- await fs.access(nmDir);
953
- } catch {
954
- console.log(chalk.dim('node_modules not found, running npm install...'));
955
- execSync('npm install --prefer-offline', { cwd: workspaceDir, stdio: 'inherit' });
956
- }
955
+ try {
956
+ await fs.access(nmDir);
957
+ } catch {
958
+ console.error(chalk.red('Error: node_modules not found.'));
959
+ console.error(chalk.dim('Run: papercrane dev --npm-install'));
960
+ process.exit(1);
957
961
  }
958
962
 
959
963
  const port = parseInt(options.port, 10);
package/lib/dev-server.js CHANGED
@@ -257,9 +257,9 @@ 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
- * Runs npm install if node_modules doesn't exist.
260
+ * Pass { npmInstall: true } to also run npm install if node_modules doesn't exist.
261
261
  */
262
- export async function generateScaffolding(workspaceDir, { skipInstall = false } = {}) {
262
+ export async function generateScaffolding(workspaceDir, { npmInstall = false } = {}) {
263
263
  const appDir = path.join(workspaceDir, 'app');
264
264
  await fs.mkdir(appDir, { recursive: true });
265
265
 
@@ -345,8 +345,8 @@ export default nextConfig;
345
345
  `;
346
346
  await fs.writeFile(nextConfigPath, nextConfig, 'utf-8');
347
347
 
348
- // npm install — only if node_modules doesn't exist yet
349
- if (!skipInstall) {
348
+ // npm install — only when explicitly requested and node_modules doesn't exist
349
+ if (npmInstall) {
350
350
  const nmDir = path.join(workspaceDir, 'node_modules');
351
351
  if (!fsSync.existsSync(nmDir)) {
352
352
  console.log('Installing dependencies...');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@papercraneai/cli",
3
- "version": "1.8.0",
3
+ "version": "1.8.1",
4
4
  "description": "CLI tool for managing OAuth credentials for LLM integrations",
5
5
  "main": "index.js",
6
6
  "type": "module",