@reqvire-org/ads 0.3.21 → 0.3.23

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.
@@ -238,7 +238,10 @@ MCP before replacing a package used by a running server. Then:
238
238
  5. Dry-run/apply with `ads_apply_patch`, or a genuinely coupled transaction.
239
239
 
240
240
  Migration never edits live source or bypasses gates. It retains stable scenario
241
- IDs and check case IDs. An optional static `scenario.id` preserves a legacy
241
+ IDs, check case IDs and directory ownership. A canonical `<Owner>.ads.scenario.tsx` is the same
242
+ development entry as `Scenario.tsx`, even without a production entry or owner
243
+ contract. Explicit flat IDs and existing flat peer families remain separate.
244
+ An optional static `scenario.id` preserves a legacy
242
245
  identity when a renamed filename would otherwise be ambiguous; it must stay
243
246
  inside the owning unit and be unique. Whole-file or unimportable private behavior subjects stay
244
247
  in legacy registration with a note until deliberately resolved. Unknown runner
@@ -238,7 +238,10 @@ MCP before replacing a package used by a running server. Then:
238
238
  5. Dry-run/apply with `ads_apply_patch`, or a genuinely coupled transaction.
239
239
 
240
240
  Migration never edits live source or bypasses gates. It retains stable scenario
241
- IDs and check case IDs. An optional static `scenario.id` preserves a legacy
241
+ IDs, check case IDs and directory ownership. A canonical `<Owner>.ads.scenario.tsx` is the same
242
+ development entry as `Scenario.tsx`, even without a production entry or owner
243
+ contract. Explicit flat IDs and existing flat peer families remain separate.
244
+ An optional static `scenario.id` preserves a legacy
242
245
  identity when a renamed filename would otherwise be ambiguous; it must stay
243
246
  inside the owning unit and be unique. Whole-file or unimportable private behavior subjects stay
244
247
  in legacy registration with a note until deliberately resolved. Unknown runner
@@ -238,7 +238,10 @@ MCP before replacing a package used by a running server. Then:
238
238
  5. Dry-run/apply with `ads_apply_patch`, or a genuinely coupled transaction.
239
239
 
240
240
  Migration never edits live source or bypasses gates. It retains stable scenario
241
- IDs and check case IDs. An optional static `scenario.id` preserves a legacy
241
+ IDs, check case IDs and directory ownership. A canonical `<Owner>.ads.scenario.tsx` is the same
242
+ development entry as `Scenario.tsx`, even without a production entry or owner
243
+ contract. Explicit flat IDs and existing flat peer families remain separate.
244
+ An optional static `scenario.id` preserves a legacy
242
245
  identity when a renamed filename would otherwise be ambiguous; it must stay
243
246
  inside the owning unit and be unique. Whole-file or unimportable private behavior subjects stay
244
247
  in legacy registration with a note until deliberately resolved. Unknown runner
@@ -238,7 +238,10 @@ MCP before replacing a package used by a running server. Then:
238
238
  5. Dry-run/apply with `ads_apply_patch`, or a genuinely coupled transaction.
239
239
 
240
240
  Migration never edits live source or bypasses gates. It retains stable scenario
241
- IDs and check case IDs. An optional static `scenario.id` preserves a legacy
241
+ IDs, check case IDs and directory ownership. A canonical `<Owner>.ads.scenario.tsx` is the same
242
+ development entry as `Scenario.tsx`, even without a production entry or owner
243
+ contract. Explicit flat IDs and existing flat peer families remain separate.
244
+ An optional static `scenario.id` preserves a legacy
242
245
  identity when a renamed filename would otherwise be ambiguous; it must stay
243
246
  inside the owning unit and be unique. Whole-file or unimportable private behavior subjects stay
244
247
  in legacy registration with a note until deliberately resolved. Unknown runner
@@ -238,7 +238,10 @@ MCP before replacing a package used by a running server. Then:
238
238
  5. Dry-run/apply with `ads_apply_patch`, or a genuinely coupled transaction.
239
239
 
240
240
  Migration never edits live source or bypasses gates. It retains stable scenario
241
- IDs and check case IDs. An optional static `scenario.id` preserves a legacy
241
+ IDs, check case IDs and directory ownership. A canonical `<Owner>.ads.scenario.tsx` is the same
242
+ development entry as `Scenario.tsx`, even without a production entry or owner
243
+ contract. Explicit flat IDs and existing flat peer families remain separate.
244
+ An optional static `scenario.id` preserves a legacy
242
245
  identity when a renamed filename would otherwise be ambiguous; it must stay
243
246
  inside the owning unit and be unique. Whole-file or unimportable private behavior subjects stay
244
247
  in legacy registration with a note until deliberately resolved. Unknown runner
package/dist/units.mjs CHANGED
@@ -2,7 +2,7 @@ import { existsSync, readFileSync, readdirSync } from "node:fs";
2
2
  import path from "node:path";
3
3
  import ts from "typescript";
4
4
  import postcss from "postcss";
5
- import { adsFileRole, isDevelopmentFile, isInside } from "./config.mjs";
5
+ import { adsFileRole, isDevelopmentFile, isInside, scenarioIdentity } from "./config.mjs";
6
6
  import { importResolver } from "./boundaries.mjs";
7
7
  import { documentationFilePolicy, isProjectDocument, projectDocumentFiles } from "./project-documents.mjs";
8
8
  import { foundationFiles, foundationImportTarget } from "./token-policy.mjs";
@@ -98,8 +98,33 @@ export function inspectUnits(options) {
98
98
  // Runtime entry conventions keep directory ownership stable when an optional
99
99
  // preview is removed. A flat scenario family still denotes separate owners.
100
100
  const sameName = name => name.replace(/[-_]/g, "").toLowerCase();
101
- const flatFamilies = new Set(files.filter(file => !adsFileRole(file) && /\.scenario\.[cm]?[jt]sx?$/.test(file)).map(file => path.posix.dirname(file)));
101
+ const legacyFlatFamilies = new Set(files.filter(file => !adsFileRole(file) && /\.scenario\.[cm]?[jt]sx?$/.test(file)).map(file => path.posix.dirname(file)));
102
+ const canonicalDefaults = new Set();
102
103
  const directories = new Set(files.filter(file => /(?:^|\/)Scenario\.[cm]?[jt]sx?$/.test(file)).map(file => slash(path.dirname(file))));
104
+ // A canonical marked default is the development entry of the same directory
105
+ // owner as Scenario.tsx. It needs no production module or empty contract to
106
+ // retain that boundary. Preserve explicit flat IDs and existing peer families.
107
+ for (const file of files.filter(file => adsFileRole(file) === "scenario")) {
108
+ const directory = path.posix.dirname(file);
109
+ if (legacyFlatFamilies.has(directory) || scenarioIdentity(path.join(dsRoot,file),dsRoot) !== directory) continue;
110
+ const ast = ts.createSourceFile(file,readFileSync(path.join(dsRoot,file),"utf8"),ts.ScriptTarget.Latest,true);
111
+ const declaration = ast.statements.filter(ts.isVariableStatement).flatMap(statement=>statement.declarationList.declarations)
112
+ .find(declaration=>ts.isIdentifier(declaration.name)&&declaration.name.text==="scenario");
113
+ let metadata = declaration?.initializer;
114
+ while (metadata && (ts.isAsExpression(metadata)||ts.isSatisfiesExpression(metadata)||ts.isParenthesizedExpression(metadata))) metadata=metadata.expression;
115
+ if (!metadata || !ts.isObjectLiteralExpression(metadata)) continue;
116
+ const id = metadata.properties.find(property=>property.name && (ts.isIdentifier(property.name)||ts.isStringLiteralLike(property.name)) && property.name.text==="id");
117
+ if (id && (!ts.isPropertyAssignment(id)||!ts.isStringLiteralLike(id.initializer)||id.initializer.text!==directory)) continue;
118
+ // An unresolved spread/computed key may supply or overwrite an explicit ID.
119
+ if (metadata.properties.some((property,index)=>ts.isSpreadAssignment(property) && (!id || index>metadata.properties.indexOf(id))
120
+ || property.name && ts.isComputedPropertyName(property.name))) continue;
121
+ directories.add(directory);
122
+ canonicalDefaults.add(directory);
123
+ }
124
+ // Marked flat siblings still outrank a directory index/runtime barrel. Losing
125
+ // the final legacy spelling must not merge otherwise unrelated peer owners.
126
+ const flatFamilies = new Set(files.filter(file => /\.scenario\.[cm]?[jt]sx?$/.test(file)
127
+ && (!adsFileRole(file) || !canonicalDefaults.has(path.posix.dirname(file)))).map(file => path.posix.dirname(file)));
103
128
  for (const file of files.filter(file => /^(?:components|patterns)\/.+\/tokens\.json$/.test(file))) directories.add(path.posix.dirname(file));
104
129
  for (const file of files.filter(file => /\.ads\.contract\.[cm]?ts$/.test(file))) {
105
130
  const directory=path.posix.dirname(file);
package/docs/CHANGELOG.md CHANGED
@@ -2,6 +2,15 @@
2
2
 
3
3
  ## Unreleased
4
4
 
5
+ ## 0.3.23
6
+
7
+ - Preserve directory ownership when its last legacy composition/scenario entries
8
+ migrate to canonical `.ads.` roles. Require no artificial runtime entry or
9
+ empty contract; retain explicit flat IDs and existing flat peer families.
10
+ - Keep fully migrated flat scenario siblings separate beside directory export
11
+ barrels. Version 0.3.22 was tagged; publication was cancelled before these
12
+ additional full-migration checks completed.
13
+
5
14
  ## 0.3.21
6
15
 
7
16
  - Add statically read TypeScript owner contracts and canonical `.ads.` development
package/docs/CONTRACTS.md CHANGED
@@ -238,7 +238,10 @@ MCP before replacing a package used by a running server. Then:
238
238
  5. Dry-run/apply with `ads_apply_patch`, or a genuinely coupled transaction.
239
239
 
240
240
  Migration never edits live source or bypasses gates. It retains stable scenario
241
- IDs and check case IDs. An optional static `scenario.id` preserves a legacy
241
+ IDs, check case IDs and directory ownership. A canonical `<Owner>.ads.scenario.tsx` is the same
242
+ development entry as `Scenario.tsx`, even without a production entry or owner
243
+ contract. Explicit flat IDs and existing flat peer families remain separate.
244
+ An optional static `scenario.id` preserves a legacy
242
245
  identity when a renamed filename would otherwise be ambiguous; it must stay
243
246
  inside the owning unit and be unique. Whole-file or unimportable private behavior subjects stay
244
247
  in legacy registration with a note until deliberately resolved. Unknown runner
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@reqvire-org/ads",
3
- "version": "0.3.21",
3
+ "version": "0.3.23",
4
4
  "type": "module",
5
5
  "description": "A design system your agent can see and shape. Your components. Your look. Your code.",
6
6
  "repository": {