logicstamp-context 0.1.1 → 0.2.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.
Files changed (159) hide show
  1. package/LLM_CONTEXT.md +4 -3
  2. package/README.md +116 -19
  3. package/dist/cli/commands/compare.d.ts.map +1 -1
  4. package/dist/cli/commands/compare.js +17 -8
  5. package/dist/cli/commands/compare.js.map +1 -1
  6. package/dist/cli/commands/context/bundleFormatter.d.ts +20 -0
  7. package/dist/cli/commands/context/bundleFormatter.d.ts.map +1 -0
  8. package/dist/cli/commands/context/bundleFormatter.js +55 -0
  9. package/dist/cli/commands/context/bundleFormatter.js.map +1 -0
  10. package/dist/cli/commands/context/configManager.d.ts +23 -0
  11. package/dist/cli/commands/context/configManager.d.ts.map +1 -0
  12. package/dist/cli/commands/context/configManager.js +69 -0
  13. package/dist/cli/commands/context/configManager.js.map +1 -0
  14. package/dist/cli/commands/context/contractBuilder.d.ts +18 -0
  15. package/dist/cli/commands/context/contractBuilder.d.ts.map +1 -0
  16. package/dist/cli/commands/context/contractBuilder.js +72 -0
  17. package/dist/cli/commands/context/contractBuilder.js.map +1 -0
  18. package/dist/cli/commands/context/fileWriter.d.ts +38 -0
  19. package/dist/cli/commands/context/fileWriter.d.ts.map +1 -0
  20. package/dist/cli/commands/context/fileWriter.js +170 -0
  21. package/dist/cli/commands/context/fileWriter.js.map +1 -0
  22. package/dist/cli/commands/context/statsCalculator.d.ts +44 -0
  23. package/dist/cli/commands/context/statsCalculator.d.ts.map +1 -0
  24. package/dist/cli/commands/context/statsCalculator.js +150 -0
  25. package/dist/cli/commands/context/statsCalculator.js.map +1 -0
  26. package/dist/cli/commands/context/tokenEstimator.d.ts +76 -0
  27. package/dist/cli/commands/context/tokenEstimator.d.ts.map +1 -0
  28. package/dist/cli/commands/context/tokenEstimator.js +258 -0
  29. package/dist/cli/commands/context/tokenEstimator.js.map +1 -0
  30. package/dist/cli/commands/context.d.ts +1 -0
  31. package/dist/cli/commands/context.d.ts.map +1 -1
  32. package/dist/cli/commands/context.js +72 -399
  33. package/dist/cli/commands/context.js.map +1 -1
  34. package/dist/cli/commands/style.d.ts +11 -0
  35. package/dist/cli/commands/style.d.ts.map +1 -0
  36. package/dist/cli/commands/style.js +15 -0
  37. package/dist/cli/commands/style.js.map +1 -0
  38. package/dist/cli/handlers/cleanHandler.d.ts +5 -0
  39. package/dist/cli/handlers/cleanHandler.d.ts.map +1 -0
  40. package/dist/cli/handlers/cleanHandler.js +28 -0
  41. package/dist/cli/handlers/cleanHandler.js.map +1 -0
  42. package/dist/cli/handlers/compareHandler.d.ts +5 -0
  43. package/dist/cli/handlers/compareHandler.d.ts.map +1 -0
  44. package/dist/cli/handlers/compareHandler.js +332 -0
  45. package/dist/cli/handlers/compareHandler.js.map +1 -0
  46. package/dist/cli/handlers/contextHandler.d.ts +5 -0
  47. package/dist/cli/handlers/contextHandler.d.ts.map +1 -0
  48. package/dist/cli/handlers/contextHandler.js +24 -0
  49. package/dist/cli/handlers/contextHandler.js.map +1 -0
  50. package/dist/cli/handlers/initHandler.d.ts +6 -0
  51. package/dist/cli/handlers/initHandler.d.ts.map +1 -0
  52. package/dist/cli/handlers/initHandler.js +30 -0
  53. package/dist/cli/handlers/initHandler.js.map +1 -0
  54. package/dist/cli/handlers/styleHandler.d.ts +5 -0
  55. package/dist/cli/handlers/styleHandler.d.ts.map +1 -0
  56. package/dist/cli/handlers/styleHandler.js +30 -0
  57. package/dist/cli/handlers/styleHandler.js.map +1 -0
  58. package/dist/cli/handlers/validateHandler.d.ts +5 -0
  59. package/dist/cli/handlers/validateHandler.d.ts.map +1 -0
  60. package/dist/cli/handlers/validateHandler.js +23 -0
  61. package/dist/cli/handlers/validateHandler.js.map +1 -0
  62. package/dist/cli/parser/argumentParser.d.ts +44 -0
  63. package/dist/cli/parser/argumentParser.d.ts.map +1 -0
  64. package/dist/cli/parser/argumentParser.js +194 -0
  65. package/dist/cli/parser/argumentParser.js.map +1 -0
  66. package/dist/cli/parser/helpText.d.ts +11 -0
  67. package/dist/cli/parser/helpText.d.ts.map +1 -0
  68. package/dist/cli/parser/helpText.js +373 -0
  69. package/dist/cli/parser/helpText.js.map +1 -0
  70. package/dist/cli/stamp.js +14 -821
  71. package/dist/cli/stamp.js.map +1 -1
  72. package/dist/core/astParser/detectors.d.ts +24 -0
  73. package/dist/core/astParser/detectors.d.ts.map +1 -0
  74. package/dist/core/astParser/detectors.js +102 -0
  75. package/dist/core/astParser/detectors.js.map +1 -0
  76. package/dist/core/astParser/extractors/componentExtractor.d.ts +13 -0
  77. package/dist/core/astParser/extractors/componentExtractor.d.ts.map +1 -0
  78. package/dist/core/astParser/extractors/componentExtractor.js +41 -0
  79. package/dist/core/astParser/extractors/componentExtractor.js.map +1 -0
  80. package/dist/core/astParser/extractors/eventExtractor.d.ts +14 -0
  81. package/dist/core/astParser/extractors/eventExtractor.d.ts.map +1 -0
  82. package/dist/core/astParser/extractors/eventExtractor.js +49 -0
  83. package/dist/core/astParser/extractors/eventExtractor.js.map +1 -0
  84. package/dist/core/astParser/extractors/propExtractor.d.ts +14 -0
  85. package/dist/core/astParser/extractors/propExtractor.d.ts.map +1 -0
  86. package/dist/core/astParser/extractors/propExtractor.js +73 -0
  87. package/dist/core/astParser/extractors/propExtractor.js.map +1 -0
  88. package/dist/core/astParser/extractors/stateExtractor.d.ts +13 -0
  89. package/dist/core/astParser/extractors/stateExtractor.d.ts.map +1 -0
  90. package/dist/core/astParser/extractors/stateExtractor.js +66 -0
  91. package/dist/core/astParser/extractors/stateExtractor.js.map +1 -0
  92. package/dist/core/astParser.d.ts.map +1 -1
  93. package/dist/core/astParser.js +5 -307
  94. package/dist/core/astParser.js.map +1 -1
  95. package/dist/core/contractBuilder.d.ts +1 -0
  96. package/dist/core/contractBuilder.d.ts.map +1 -1
  97. package/dist/core/contractBuilder.js +1 -0
  98. package/dist/core/contractBuilder.js.map +1 -1
  99. package/dist/core/pack/builder.d.ts +35 -0
  100. package/dist/core/pack/builder.d.ts.map +1 -0
  101. package/dist/core/pack/builder.js +76 -0
  102. package/dist/core/pack/builder.js.map +1 -0
  103. package/dist/core/pack/collector.d.ts +20 -0
  104. package/dist/core/pack/collector.d.ts.map +1 -0
  105. package/dist/core/pack/collector.js +71 -0
  106. package/dist/core/pack/collector.js.map +1 -0
  107. package/dist/core/pack/loader.d.ts +23 -0
  108. package/dist/core/pack/loader.d.ts.map +1 -0
  109. package/dist/core/pack/loader.js +66 -0
  110. package/dist/core/pack/loader.js.map +1 -0
  111. package/dist/core/pack/resolver.d.ts +21 -0
  112. package/dist/core/pack/resolver.d.ts.map +1 -0
  113. package/dist/core/pack/resolver.js +79 -0
  114. package/dist/core/pack/resolver.js.map +1 -0
  115. package/dist/core/pack.d.ts +17 -27
  116. package/dist/core/pack.d.ts.map +1 -1
  117. package/dist/core/pack.js +18 -225
  118. package/dist/core/pack.js.map +1 -1
  119. package/dist/core/styleExtractor/index.d.ts +11 -0
  120. package/dist/core/styleExtractor/index.d.ts.map +1 -0
  121. package/dist/core/styleExtractor/index.js +11 -0
  122. package/dist/core/styleExtractor/index.js.map +1 -0
  123. package/dist/core/styleExtractor/layout.d.ts +14 -0
  124. package/dist/core/styleExtractor/layout.d.ts.map +1 -0
  125. package/dist/core/styleExtractor/layout.js +86 -0
  126. package/dist/core/styleExtractor/layout.js.map +1 -0
  127. package/dist/core/styleExtractor/motion.d.ts +20 -0
  128. package/dist/core/styleExtractor/motion.d.ts.map +1 -0
  129. package/dist/core/styleExtractor/motion.js +74 -0
  130. package/dist/core/styleExtractor/motion.js.map +1 -0
  131. package/dist/core/styleExtractor/scss.d.ts +30 -0
  132. package/dist/core/styleExtractor/scss.d.ts.map +1 -0
  133. package/dist/core/styleExtractor/scss.js +80 -0
  134. package/dist/core/styleExtractor/scss.js.map +1 -0
  135. package/dist/core/styleExtractor/styleExtractor.d.ts +11 -0
  136. package/dist/core/styleExtractor/styleExtractor.d.ts.map +1 -0
  137. package/dist/core/styleExtractor/styleExtractor.js +115 -0
  138. package/dist/core/styleExtractor/styleExtractor.js.map +1 -0
  139. package/dist/core/styleExtractor/styled.d.ts +13 -0
  140. package/dist/core/styleExtractor/styled.d.ts.map +1 -0
  141. package/dist/core/styleExtractor/styled.js +31 -0
  142. package/dist/core/styleExtractor/styled.js.map +1 -0
  143. package/dist/core/styleExtractor/tailwind.d.ts +16 -0
  144. package/dist/core/styleExtractor/tailwind.d.ts.map +1 -0
  145. package/dist/core/styleExtractor/tailwind.js +85 -0
  146. package/dist/core/styleExtractor/tailwind.js.map +1 -0
  147. package/dist/core/styleExtractor.d.ts +8 -0
  148. package/dist/core/styleExtractor.d.ts.map +1 -0
  149. package/dist/core/styleExtractor.js +8 -0
  150. package/dist/core/styleExtractor.js.map +1 -0
  151. package/dist/types/UIFContract.d.ts +71 -0
  152. package/dist/types/UIFContract.d.ts.map +1 -1
  153. package/dist/types/UIFContract.js.map +1 -1
  154. package/dist/utils/tokens.d.ts +18 -10
  155. package/dist/utils/tokens.d.ts.map +1 -1
  156. package/dist/utils/tokens.js +100 -10
  157. package/dist/utils/tokens.js.map +1 -1
  158. package/package.json +5 -1
  159. package/schema/logicstamp.context.schema.json +288 -0
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Loader module - Load contracts, manifests, and source code
3
+ */
4
+ import type { UIFContract } from '../../types/UIFContract.js';
5
+ import type { ProjectManifest } from '../manifest.js';
6
+ /**
7
+ * Load manifest from file
8
+ */
9
+ export declare function loadManifest(basePath: string): Promise<ProjectManifest>;
10
+ /**
11
+ * Load a sidecar contract file
12
+ * Sidecar path is computed from the manifest key (project-relative): resolved from projectRoot + key + '.uif.json'
13
+ */
14
+ export declare function loadContract(entryId: string, projectRoot: string): Promise<UIFContract | null>;
15
+ /**
16
+ * Extract code header (JSDoc @uif block) from source file
17
+ */
18
+ export declare function extractCodeHeader(entryId: string, projectRoot: string): Promise<string | null>;
19
+ /**
20
+ * Read full source code
21
+ */
22
+ export declare function readSourceCode(entryId: string, projectRoot: string): Promise<string | null>;
23
+ //# sourceMappingURL=loader.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../../../src/core/pack/loader.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AAC9D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAEtD;;GAEG;AACH,wBAAsB,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC,CAU7E;AAED;;;GAGG;AACH,wBAAsB,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC,CAYpG;AAED;;GAEG;AACH,wBAAsB,iBAAiB,CAAC,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAepG;AAED;;GAEG;AACH,wBAAsB,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAOjG"}
@@ -0,0 +1,66 @@
1
+ /**
2
+ * Loader module - Load contracts, manifests, and source code
3
+ */
4
+ import { readFile } from 'node:fs/promises';
5
+ import { join, resolve, isAbsolute } from 'node:path';
6
+ /**
7
+ * Load manifest from file
8
+ */
9
+ export async function loadManifest(basePath) {
10
+ const manifestPath = join(basePath, 'logicstamp.manifest.json');
11
+ try {
12
+ const content = await readFile(manifestPath, 'utf8');
13
+ return JSON.parse(content);
14
+ }
15
+ catch (error) {
16
+ throw new Error(`Failed to load manifest at ${manifestPath}: ${error.message}`);
17
+ }
18
+ }
19
+ /**
20
+ * Load a sidecar contract file
21
+ * Sidecar path is computed from the manifest key (project-relative): resolved from projectRoot + key + '.uif.json'
22
+ */
23
+ export async function loadContract(entryId, projectRoot) {
24
+ // Resolve relative path from project root
25
+ const absolutePath = isAbsolute(entryId) ? entryId : resolve(projectRoot, entryId);
26
+ const sidecarPath = `${absolutePath}.uif.json`;
27
+ try {
28
+ const content = await readFile(sidecarPath, 'utf8');
29
+ return JSON.parse(content);
30
+ }
31
+ catch (error) {
32
+ // Sidecar file doesn't exist or can't be read
33
+ return null;
34
+ }
35
+ }
36
+ /**
37
+ * Extract code header (JSDoc @uif block) from source file
38
+ */
39
+ export async function extractCodeHeader(entryId, projectRoot) {
40
+ try {
41
+ const absolutePath = isAbsolute(entryId) ? entryId : resolve(projectRoot, entryId);
42
+ const content = await readFile(absolutePath, 'utf8');
43
+ // Look for @uif JSDoc block
44
+ const headerMatch = content.match(/\/\*\*[\s\S]*?@uif[\s\S]*?\*\//);
45
+ if (headerMatch) {
46
+ return headerMatch[0];
47
+ }
48
+ return null;
49
+ }
50
+ catch (error) {
51
+ return null;
52
+ }
53
+ }
54
+ /**
55
+ * Read full source code
56
+ */
57
+ export async function readSourceCode(entryId, projectRoot) {
58
+ try {
59
+ const absolutePath = isAbsolute(entryId) ? entryId : resolve(projectRoot, entryId);
60
+ return await readFile(absolutePath, 'utf8');
61
+ }
62
+ catch (error) {
63
+ return null;
64
+ }
65
+ }
66
+ //# sourceMappingURL=loader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"loader.js","sourceRoot":"","sources":["../../../src/core/pack/loader.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAItD;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,QAAgB;IACjD,MAAM,YAAY,GAAG,IAAI,CAAC,QAAQ,EAAE,0BAA0B,CAAC,CAAC;IAChE,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC;QACrD,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,CAAoB,CAAC;IAChD,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,IAAI,KAAK,CACb,8BAA8B,YAAY,KAAM,KAAe,CAAC,OAAO,EAAE,CAC1E,CAAC;IACJ,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,OAAe,EAAE,WAAmB;IACrE,0CAA0C;IAC1C,MAAM,YAAY,GAAG,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;IACnF,MAAM,WAAW,GAAG,GAAG,YAAY,WAAW,CAAC;IAE/C,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;QACpD,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,CAAgB,CAAC;IAC5C,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,8CAA8C;QAC9C,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,OAAe,EAAE,WAAmB;IAC1E,IAAI,CAAC;QACH,MAAM,YAAY,GAAG,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;QACnF,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC;QAErD,4BAA4B;QAC5B,MAAM,WAAW,GAAG,OAAO,CAAC,KAAK,CAAC,gCAAgC,CAAC,CAAC;QACpE,IAAI,WAAW,EAAE,CAAC;YAChB,OAAO,WAAW,CAAC,CAAC,CAAC,CAAC;QACxB,CAAC;QAED,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,OAAe,EAAE,WAAmB;IACvE,IAAI,CAAC;QACH,MAAM,YAAY,GAAG,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;QACnF,OAAO,MAAM,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC;IAC9C,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC"}
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Resolver module - Resolve component names and paths to manifest keys
3
+ */
4
+ import type { ProjectManifest, ComponentNode } from '../manifest.js';
5
+ /**
6
+ * Resolve input (path or name) to a manifest key
7
+ * This is the canonical resolution used by both pack and similar commands
8
+ */
9
+ export declare function resolveKey(manifest: ProjectManifest, input: string): string | null;
10
+ /**
11
+ * Find a component node by name or path
12
+ * Returns the component node and the manifest key it was found under
13
+ */
14
+ export declare function findComponentByName(manifest: ProjectManifest, nameOrPath: string): ComponentNode | null;
15
+ /**
16
+ * Resolve a dependency name to a manifest key
17
+ * Uses the canonical resolveKey() function for consistent resolution
18
+ * Prioritizes relative paths to avoid cross-directory conflicts
19
+ */
20
+ export declare function resolveDependency(manifest: ProjectManifest, depName: string, parentId: string): string | null;
21
+ //# sourceMappingURL=resolver.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolver.d.ts","sourceRoot":"","sources":["../../../src/core/pack/resolver.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,KAAK,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAErE;;;GAGG;AACH,wBAAgB,UAAU,CACxB,QAAQ,EAAE,eAAe,EACzB,KAAK,EAAE,MAAM,GACZ,MAAM,GAAG,IAAI,CAkCf;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,eAAe,EACzB,UAAU,EAAE,MAAM,GACjB,aAAa,GAAG,IAAI,CAGtB;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAC/B,QAAQ,EAAE,eAAe,EACzB,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,GACf,MAAM,GAAG,IAAI,CA6Bf"}
@@ -0,0 +1,79 @@
1
+ /**
2
+ * Resolver module - Resolve component names and paths to manifest keys
3
+ */
4
+ import { normalizeEntryId } from '../../utils/fsx.js';
5
+ /**
6
+ * Resolve input (path or name) to a manifest key
7
+ * This is the canonical resolution used by both pack and similar commands
8
+ */
9
+ export function resolveKey(manifest, input) {
10
+ const normalized = normalizeEntryId(input);
11
+ // Try exact match first (normalized key match)
12
+ if (manifest.components[normalized]) {
13
+ return normalized;
14
+ }
15
+ // Try to find by normalized key match
16
+ const entries = Object.entries(manifest.components);
17
+ for (const [key, node] of entries) {
18
+ if (normalizeEntryId(key) === normalized || normalizeEntryId(node.entryId) === normalized) {
19
+ return key; // Return the manifest key, not the node's entryId
20
+ }
21
+ }
22
+ // Look for name match (Button, LoginForm, etc.)
23
+ // Build name → [keys] index for ambiguous cases
24
+ const nameMatches = [];
25
+ for (const [key] of entries) {
26
+ const fileName = key.split(/[/\\]/).pop()?.replace(/\.(tsx?|jsx?)$/, '');
27
+ if (fileName === input || fileName === input.replace(/\.(tsx?|jsx?)$/, '')) {
28
+ nameMatches.push(key);
29
+ }
30
+ }
31
+ if (nameMatches.length === 1) {
32
+ return nameMatches[0];
33
+ }
34
+ else if (nameMatches.length > 1) {
35
+ // Ambiguous - return first match but this should be handled by caller
36
+ return nameMatches[0];
37
+ }
38
+ return null;
39
+ }
40
+ /**
41
+ * Find a component node by name or path
42
+ * Returns the component node and the manifest key it was found under
43
+ */
44
+ export function findComponentByName(manifest, nameOrPath) {
45
+ const key = resolveKey(manifest, nameOrPath);
46
+ return key ? manifest.components[key] : null;
47
+ }
48
+ /**
49
+ * Resolve a dependency name to a manifest key
50
+ * Uses the canonical resolveKey() function for consistent resolution
51
+ * Prioritizes relative paths to avoid cross-directory conflicts
52
+ */
53
+ export function resolveDependency(manifest, depName, parentId) {
54
+ // parentId is a manifest key (canonical identifier)
55
+ // First, try relative path resolution based on parent directory
56
+ // This ensures we resolve to components in the same directory tree first
57
+ // parentId is a manifest key (normalized path), extract directory
58
+ const parentDir = parentId.substring(0, parentId.lastIndexOf('/'));
59
+ const possiblePaths = [
60
+ `${parentDir}/${depName}.tsx`,
61
+ `${parentDir}/${depName}.ts`,
62
+ `${parentDir}/${depName}/index.tsx`,
63
+ `${parentDir}/${depName}/index.ts`,
64
+ ];
65
+ for (const path of possiblePaths) {
66
+ const key = resolveKey(manifest, path);
67
+ if (key) {
68
+ return key; // Return manifest key (canonical identifier)
69
+ }
70
+ }
71
+ // Only fall back to global name search if relative paths didn't work
72
+ // This prevents cross-directory conflicts (e.g., tests/fixtures vs examples)
73
+ const key = resolveKey(manifest, depName);
74
+ if (key) {
75
+ return key; // Return manifest key (canonical identifier)
76
+ }
77
+ return null;
78
+ }
79
+ //# sourceMappingURL=resolver.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolver.js","sourceRoot":"","sources":["../../../src/core/pack/resolver.ts"],"names":[],"mappings":"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"}
@@ -23,7 +23,9 @@
23
23
  * file: uif:a70a7b698f5520bf49d74a91
24
24
  */
25
25
  import type { UIFContract } from '../types/UIFContract.js';
26
- import type { ProjectManifest, ComponentNode } from './manifest.js';
26
+ import type { ProjectManifest } from './manifest.js';
27
+ import type { MissingDependency } from './pack/collector.js';
28
+ import type { BundleNode } from './pack/builder.js';
27
29
  /**
28
30
  * Code inclusion mode for bundles
29
31
  */
@@ -48,20 +50,11 @@ export interface PackOptions {
48
50
  /**
49
51
  * A node in the bundle graph
50
52
  */
51
- export interface BundleNode {
52
- entryId: string;
53
- contract: UIFContract;
54
- codeHeader?: string | null;
55
- code?: string | null;
56
- }
53
+ export type { BundleNode } from './pack/builder.js';
57
54
  /**
58
55
  * Missing dependency information
59
56
  */
60
- export interface MissingDependency {
61
- name: string;
62
- reason: string;
63
- referencedBy?: string;
64
- }
57
+ export type { MissingDependency } from './pack/collector.js';
65
58
  /**
66
59
  * Complete bundle structure
67
60
  */
@@ -116,12 +109,12 @@ export interface LogicStampIndex {
116
109
  /**
117
110
  * Load manifest from file
118
111
  */
119
- export declare function loadManifest(basePath: string): Promise<ProjectManifest>;
112
+ export { loadManifest } from './pack/loader.js';
120
113
  /**
121
114
  * Load a sidecar contract file
122
115
  * Sidecar path is computed from the manifest key (project-relative): resolved from projectRoot + key + '.uif.json'
123
116
  */
124
- export declare function loadContract(entryId: string, projectRoot: string): Promise<UIFContract | null>;
117
+ export { loadContract } from './pack/loader.js';
125
118
  /**
126
119
  * Normalize a file path for cross-platform consistency
127
120
  * Re-exports the canonical normalizeEntryId from utils/fsx
@@ -132,45 +125,42 @@ export { normalizeEntryId } from '../utils/fsx.js';
132
125
  * Resolve input (path or name) to a manifest key
133
126
  * This is the canonical resolution used by both pack and similar commands
134
127
  */
135
- export declare function resolveKey(manifest: ProjectManifest, input: string): string | null;
128
+ export { resolveKey } from './pack/resolver.js';
136
129
  /**
137
130
  * Find a component node by name or path
138
131
  * Returns the component node and the manifest key it was found under
139
132
  */
140
- export declare function findComponentByName(manifest: ProjectManifest, nameOrPath: string): ComponentNode | null;
133
+ export { findComponentByName } from './pack/resolver.js';
141
134
  /**
142
135
  * Resolve a dependency name to a manifest key
143
136
  * Uses the canonical resolveKey() function for consistent resolution
144
137
  * Prioritizes relative paths to avoid cross-directory conflicts
145
138
  */
146
- export declare function resolveDependency(manifest: ProjectManifest, depName: string, parentId: string): string | null;
139
+ export { resolveDependency } from './pack/resolver.js';
147
140
  /**
148
141
  * Perform BFS traversal to collect dependencies
149
142
  */
150
- export declare function collectDependencies(entryId: string, manifest: ProjectManifest, depth: number, maxNodes: number): {
151
- visited: Set<string>;
152
- missing: MissingDependency[];
153
- };
143
+ export { collectDependencies } from './pack/collector.js';
154
144
  /**
155
145
  * Extract code header (JSDoc @uif block) from source file
156
146
  */
157
- export declare function extractCodeHeader(entryId: string, projectRoot: string): Promise<string | null>;
147
+ export { extractCodeHeader } from './pack/loader.js';
158
148
  /**
159
149
  * Read full source code
160
150
  */
161
- export declare function readSourceCode(entryId: string, projectRoot: string): Promise<string | null>;
151
+ export { readSourceCode } from './pack/loader.js';
162
152
  /**
163
153
  * Build edges from nodes based on dependencies
164
154
  */
165
- export declare function buildEdges(nodes: BundleNode[], manifest: ProjectManifest): [string, string][];
155
+ export { buildEdges } from './pack/builder.js';
166
156
  /**
167
157
  * Sort nodes deterministically for stable bundle hashes
168
158
  */
169
- export declare function stableSort(nodes: BundleNode[]): BundleNode[];
159
+ export { stableSort } from './pack/builder.js';
170
160
  /**
171
161
  * Compute bundle hash from nodes using stable hashing
172
162
  */
173
- export declare function computeBundleHash(nodes: BundleNode[], depth: number): string;
163
+ export { computeBundleHash } from './pack/builder.js';
174
164
  /**
175
165
  * Validate hash-lock: ensure contract hashes match current state
176
166
  *
@@ -178,7 +168,7 @@ export declare function computeBundleHash(nodes: BundleNode[], depth: number): s
178
168
  * (authoritative, not from header). fileHash() automatically strips @uif header block
179
169
  * before hashing, so header updates won't cause hash churn.
180
170
  */
181
- export declare function validateHashLock(contract: UIFContract, entryId: string, projectRoot: string): Promise<boolean>;
171
+ export { validateHashLock } from './pack/builder.js';
182
172
  /**
183
173
  * Main pack function - generates a bundle for a component
184
174
  */
@@ -1 +1 @@
1
- {"version":3,"file":"pack.d.ts","sourceRoot":"","sources":["../../src/core/pack.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"pack.d.ts","sourceRoot":"","sources":["../../src/core/pack.ts"],"names":[],"mappings":"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"}
package/dist/core/pack.js CHANGED
@@ -26,11 +26,14 @@
26
26
  * Pack module - Generate LLM-ready context bundles for components
27
27
  * Creates compact, hash-locked bundles with dependency graphs
28
28
  */
29
- import { readFile } from 'node:fs/promises';
30
- import { join, resolve, isAbsolute } from 'node:path';
29
+ import { resolve, isAbsolute } from 'node:path';
31
30
  import { normalizeEntryId } from '../utils/fsx.js';
32
- import { bundleHash as computeBundleHashStable } from '../utils/hash.js';
33
31
  import { createRequire } from 'node:module';
32
+ // Import from extracted modules
33
+ import { resolveKey } from './pack/resolver.js';
34
+ import { collectDependencies } from './pack/collector.js';
35
+ import { loadContract, readSourceCode, extractCodeHeader } from './pack/loader.js';
36
+ import { buildEdges, computeBundleHash, stableSort, validateHashLock } from './pack/builder.js';
34
37
  // Load package.json to get version
35
38
  const require = createRequire(import.meta.url);
36
39
  const pkg = require('../../package.json');
@@ -38,33 +41,12 @@ const PACKAGE_VERSION = `${pkg.name}@${pkg.version}`;
38
41
  /**
39
42
  * Load manifest from file
40
43
  */
41
- export async function loadManifest(basePath) {
42
- const manifestPath = join(basePath, 'logicstamp.manifest.json');
43
- try {
44
- const content = await readFile(manifestPath, 'utf8');
45
- return JSON.parse(content);
46
- }
47
- catch (error) {
48
- throw new Error(`Failed to load manifest at ${manifestPath}: ${error.message}`);
49
- }
50
- }
44
+ export { loadManifest } from './pack/loader.js';
51
45
  /**
52
46
  * Load a sidecar contract file
53
47
  * Sidecar path is computed from the manifest key (project-relative): resolved from projectRoot + key + '.uif.json'
54
48
  */
55
- export async function loadContract(entryId, projectRoot) {
56
- // Resolve relative path from project root
57
- const absolutePath = isAbsolute(entryId) ? entryId : resolve(projectRoot, entryId);
58
- const sidecarPath = `${absolutePath}.uif.json`;
59
- try {
60
- const content = await readFile(sidecarPath, 'utf8');
61
- return JSON.parse(content);
62
- }
63
- catch (error) {
64
- // Sidecar file doesn't exist or can't be read
65
- return null;
66
- }
67
- }
49
+ export { loadContract } from './pack/loader.js';
68
50
  /**
69
51
  * Normalize a file path for cross-platform consistency
70
52
  * Re-exports the canonical normalizeEntryId from utils/fsx
@@ -75,211 +57,42 @@ export { normalizeEntryId } from '../utils/fsx.js';
75
57
  * Resolve input (path or name) to a manifest key
76
58
  * This is the canonical resolution used by both pack and similar commands
77
59
  */
78
- export function resolveKey(manifest, input) {
79
- const normalized = normalizeEntryId(input);
80
- // Try exact match first (normalized key match)
81
- if (manifest.components[normalized]) {
82
- return normalized;
83
- }
84
- // Try to find by normalized key match
85
- const entries = Object.entries(manifest.components);
86
- for (const [key, node] of entries) {
87
- if (normalizeEntryId(key) === normalized || normalizeEntryId(node.entryId) === normalized) {
88
- return key; // Return the manifest key, not the node's entryId
89
- }
90
- }
91
- // Look for name match (Button, LoginForm, etc.)
92
- // Build name → [keys] index for ambiguous cases
93
- const nameMatches = [];
94
- for (const [key] of entries) {
95
- const fileName = key.split(/[/\\]/).pop()?.replace(/\.(tsx?|jsx?)$/, '');
96
- if (fileName === input || fileName === input.replace(/\.(tsx?|jsx?)$/, '')) {
97
- nameMatches.push(key);
98
- }
99
- }
100
- if (nameMatches.length === 1) {
101
- return nameMatches[0];
102
- }
103
- else if (nameMatches.length > 1) {
104
- // Ambiguous - return first match but this should be handled by caller
105
- return nameMatches[0];
106
- }
107
- return null;
108
- }
60
+ export { resolveKey } from './pack/resolver.js';
109
61
  /**
110
62
  * Find a component node by name or path
111
63
  * Returns the component node and the manifest key it was found under
112
64
  */
113
- export function findComponentByName(manifest, nameOrPath) {
114
- const key = resolveKey(manifest, nameOrPath);
115
- return key ? manifest.components[key] : null;
116
- }
65
+ export { findComponentByName } from './pack/resolver.js';
117
66
  /**
118
67
  * Resolve a dependency name to a manifest key
119
68
  * Uses the canonical resolveKey() function for consistent resolution
120
69
  * Prioritizes relative paths to avoid cross-directory conflicts
121
70
  */
122
- export function resolveDependency(manifest, depName, parentId) {
123
- // parentId is a manifest key (canonical identifier)
124
- // First, try relative path resolution based on parent directory
125
- // This ensures we resolve to components in the same directory tree first
126
- // parentId is a manifest key (normalized path), extract directory
127
- const parentDir = parentId.substring(0, parentId.lastIndexOf('/'));
128
- const possiblePaths = [
129
- `${parentDir}/${depName}.tsx`,
130
- `${parentDir}/${depName}.ts`,
131
- `${parentDir}/${depName}/index.tsx`,
132
- `${parentDir}/${depName}/index.ts`,
133
- ];
134
- for (const path of possiblePaths) {
135
- const key = resolveKey(manifest, path);
136
- if (key) {
137
- return key; // Return manifest key (canonical identifier)
138
- }
139
- }
140
- // Only fall back to global name search if relative paths didn't work
141
- // This prevents cross-directory conflicts (e.g., tests/fixtures vs examples)
142
- const key = resolveKey(manifest, depName);
143
- if (key) {
144
- return key; // Return manifest key (canonical identifier)
145
- }
146
- return null;
147
- }
71
+ export { resolveDependency } from './pack/resolver.js';
148
72
  /**
149
73
  * Perform BFS traversal to collect dependencies
150
74
  */
151
- export function collectDependencies(entryId, manifest, depth, maxNodes) {
152
- const visited = new Set();
153
- const missing = [];
154
- const queue = [{ id: entryId, level: 0 }];
155
- while (queue.length > 0) {
156
- const current = queue.shift();
157
- // Normalize the ID for lookup
158
- const normalizedId = normalizeEntryId(current.id);
159
- // Try to find component by normalized ID
160
- let node = manifest.components[normalizedId];
161
- let componentKey = normalizedId;
162
- // If not found, try to find by matching normalized entryIds
163
- if (!node) {
164
- for (const [key, comp] of Object.entries(manifest.components)) {
165
- if (normalizeEntryId(key) === normalizedId || normalizeEntryId(comp.entryId) === normalizedId) {
166
- node = comp;
167
- componentKey = key;
168
- break;
169
- }
170
- }
171
- }
172
- // Skip if already visited or exceeded depth
173
- if (visited.has(componentKey) || current.level > depth) {
174
- continue;
175
- }
176
- // Check max nodes limit
177
- if (visited.size >= maxNodes) {
178
- break;
179
- }
180
- if (!node) {
181
- missing.push({
182
- name: current.id,
183
- reason: 'Component not found in manifest',
184
- });
185
- continue;
186
- }
187
- visited.add(componentKey);
188
- // Only traverse deeper if we haven't reached depth limit
189
- if (current.level < depth) {
190
- // Add dependencies to queue
191
- for (const dep of node.dependencies) {
192
- const resolvedId = resolveDependency(manifest, dep, componentKey);
193
- if (resolvedId) {
194
- if (!visited.has(resolvedId)) {
195
- queue.push({ id: resolvedId, level: current.level + 1 });
196
- }
197
- }
198
- else {
199
- // Track missing dependency
200
- if (!missing.some((m) => m.name === dep)) {
201
- missing.push({
202
- name: dep,
203
- reason: 'No contract found (third-party or not scanned)',
204
- referencedBy: componentKey, // Use manifest key, not current.id
205
- });
206
- }
207
- }
208
- }
209
- }
210
- }
211
- return { visited, missing };
212
- }
75
+ export { collectDependencies } from './pack/collector.js';
213
76
  /**
214
77
  * Extract code header (JSDoc @uif block) from source file
215
78
  */
216
- export async function extractCodeHeader(entryId, projectRoot) {
217
- try {
218
- const absolutePath = isAbsolute(entryId) ? entryId : resolve(projectRoot, entryId);
219
- const content = await readFile(absolutePath, 'utf8');
220
- // Look for @uif JSDoc block
221
- const headerMatch = content.match(/\/\*\*[\s\S]*?@uif[\s\S]*?\*\//);
222
- if (headerMatch) {
223
- return headerMatch[0];
224
- }
225
- return null;
226
- }
227
- catch (error) {
228
- return null;
229
- }
230
- }
79
+ export { extractCodeHeader } from './pack/loader.js';
231
80
  /**
232
81
  * Read full source code
233
82
  */
234
- export async function readSourceCode(entryId, projectRoot) {
235
- try {
236
- const absolutePath = isAbsolute(entryId) ? entryId : resolve(projectRoot, entryId);
237
- return await readFile(absolutePath, 'utf8');
238
- }
239
- catch (error) {
240
- return null;
241
- }
242
- }
83
+ export { readSourceCode } from './pack/loader.js';
243
84
  /**
244
85
  * Build edges from nodes based on dependencies
245
86
  */
246
- export function buildEdges(nodes, manifest) {
247
- const edges = [];
248
- const nodeIds = new Set(nodes.map((n) => n.entryId));
249
- for (const node of nodes) {
250
- const componentNode = manifest.components[node.entryId];
251
- if (!componentNode)
252
- continue;
253
- for (const dep of componentNode.dependencies) {
254
- const resolvedId = resolveDependency(manifest, dep, node.entryId);
255
- // Only add edge if both nodes are in the bundle
256
- if (resolvedId && nodeIds.has(resolvedId)) {
257
- edges.push([node.entryId, resolvedId]);
258
- }
259
- }
260
- }
261
- return edges;
262
- }
87
+ export { buildEdges } from './pack/builder.js';
263
88
  /**
264
89
  * Sort nodes deterministically for stable bundle hashes
265
90
  */
266
- export function stableSort(nodes) {
267
- return [...nodes].sort((a, b) => {
268
- // Sort by entryId for determinism
269
- return a.entryId.localeCompare(b.entryId);
270
- });
271
- }
91
+ export { stableSort } from './pack/builder.js';
272
92
  /**
273
93
  * Compute bundle hash from nodes using stable hashing
274
94
  */
275
- export function computeBundleHash(nodes, depth) {
276
- // Use the stable bundleHash function from utils/hash
277
- const nodeData = nodes.map(n => ({
278
- entryId: n.entryId,
279
- semanticHash: n.contract.semanticHash,
280
- }));
281
- return computeBundleHashStable(nodeData, depth, '0.1');
282
- }
95
+ export { computeBundleHash } from './pack/builder.js';
283
96
  /**
284
97
  * Validate hash-lock: ensure contract hashes match current state
285
98
  *
@@ -287,27 +100,7 @@ export function computeBundleHash(nodes, depth) {
287
100
  * (authoritative, not from header). fileHash() automatically strips @uif header block
288
101
  * before hashing, so header updates won't cause hash churn.
289
102
  */
290
- export async function validateHashLock(contract, entryId, projectRoot) {
291
- try {
292
- // Read the actual source file
293
- const absolutePath = isAbsolute(entryId) ? entryId : resolve(projectRoot, entryId);
294
- const sourceContent = await readFile(absolutePath, 'utf8');
295
- // Recompute file hash (strips @uif header block automatically)
296
- const { fileHash: computedFileHash } = await import('../utils/hash.js');
297
- const actualFileHash = computedFileHash(sourceContent);
298
- // Compare to sidecar contract.fileHash (authoritative, not header)
299
- if (actualFileHash !== contract.fileHash) {
300
- return false;
301
- }
302
- // Semantic hash should match (derived from structure + signature)
303
- // If fileHash matches, semantic hash should also match since it's derived from the AST
304
- return true;
305
- }
306
- catch (error) {
307
- // If we can't read/parse the file, fail validation
308
- return false;
309
- }
310
- }
103
+ export { validateHashLock } from './pack/builder.js';
311
104
  /**
312
105
  * Main pack function - generates a bundle for a component
313
106
  */