@descix/cli 2.0.0 → 2.0.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.
@@ -194,6 +194,22 @@ export class WorkspaceUnreadableError extends Error {
194
194
  }
195
195
  }
196
196
 
197
+ /**
198
+ * A workspace.json in a RETIRED format (v1, v2.1 multi-app). It is a TYPE, like
199
+ * WorkspaceUnreadableError, because tryLoad() has to branch on it: "there is no workspace
200
+ * here" and "the workspace here is in a retired format" are different answers, and only the
201
+ * first is a soft null. Measured 2026-10-10: the refusal threw a PLAIN Error, tryLoad
202
+ * swallowed it, and five app repos' stale v2.1 files silently resolved to the DEFAULT origin —
203
+ * the exact wrong-env hazard the loader exists to prevent.
204
+ */
205
+ export class WorkspaceRetiredFormatError extends Error {
206
+ constructor(message) {
207
+ super(message);
208
+ this.name = 'WorkspaceRetiredFormatError';
209
+ this.code = 'WORKSPACE_RETIRED_FORMAT';
210
+ }
211
+ }
212
+
197
213
  /**
198
214
  * WorkspaceConfig - Manages workspace-specific configuration
199
215
  *
@@ -407,11 +423,11 @@ export class WorkspaceConfig {
407
423
  // `error.message.includes('v1 workspace format')` re-throw was narrow string matching
408
424
  // (DeSciX anti-pattern #6) guarding a catch that should never have been this wide.
409
425
  if (parsed.communities && !parsed.env) {
410
- throw new Error(
411
- 'v1 workspace format is not supported. Migrate to v2.1.\n' +
426
+ throw new WorkspaceRetiredFormatError(
427
+ 'v1 workspace format is not supported. Migrate to v3.\n' +
412
428
  ` File: ${configPath}\n` +
413
429
  '\n' +
414
- 'This file is still on disk and has NOT been modified. There is no automatic v1 → v2.1\n' +
430
+ 'This file is still on disk and has NOT been modified. There is no automatic v1 → v3\n' +
415
431
  'migration: no surviving code reads the v1 layout, so its contents cannot be converted\n' +
416
432
  'for you — but they are still readable BY YOU, and this file is the only copy of them.\n' +
417
433
  moveAsideRemedy(configPath, 'descix app init')
@@ -424,7 +440,7 @@ export class WorkspaceConfig {
424
440
  // multi-app dev is sibling checkouts behind one gateway config. Same posture as the v1
425
441
  // refusal above: loud, non-destructive, the remedy is one command per app repo.
426
442
  if (parsed.env && (parsed.env.platform || parsed.env.products)) {
427
- throw new Error(
443
+ throw new WorkspaceRetiredFormatError(
428
444
  'v2.1 multi-app workspace format is not supported. Migrate to v3 (single-app).\n' +
429
445
  ` File: ${configPath}\n` +
430
446
  '\n' +
@@ -464,8 +480,9 @@ export class WorkspaceConfig {
464
480
  * Try to load workspace configuration, return null if not found
465
481
  * Useful for commands that need to check if workspace exists
466
482
  *
467
- * RETURNS NULL FOR ABSENT, THROWS FOR UNREADABLE. "There is no workspace here" and "the
468
- * workspace here is damaged" are different answers and only the first one is a soft no.
483
+ * RETURNS NULL FOR ABSENT, THROWS FOR UNREADABLE AND FOR RETIRED FORMATS. "There is no
484
+ * workspace here", "the workspace here is damaged" and "the workspace here is in a retired
485
+ * format" are different answers and only the first one is a soft no.
469
486
  * Swallowing the second made a corrupt workspace look like a fresh directory, which is how a
470
487
  * damaged workspace silently fell back to the DEFAULT (prod) origin instead of stopping.
471
488
  *
@@ -478,6 +495,7 @@ export class WorkspaceConfig {
478
495
  return await WorkspaceConfig.load(startDir);
479
496
  } catch (error) {
480
497
  if (error instanceof WorkspaceUnreadableError) throw error;
498
+ if (error instanceof WorkspaceRetiredFormatError) throw error;
481
499
  return null;
482
500
  }
483
501
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@descix/cli",
3
- "version": "2.0.0",
3
+ "version": "2.0.1",
4
4
  "description": "DeSciX CLI and MCP Server - Unified command-line interface for DeSciX platform",
5
5
  "repository": {
6
6
  "type": "git",