@beignet/cli 0.0.40 → 0.0.41

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 (93) hide show
  1. package/CHANGELOG.md +9 -0
  2. package/README.md +76 -10
  3. package/dist/analysis/source-index.d.ts +38 -0
  4. package/dist/analysis/source-index.d.ts.map +1 -0
  5. package/dist/analysis/source-index.js +271 -0
  6. package/dist/analysis/source-index.js.map +1 -0
  7. package/dist/analysis/workspace.d.ts +16 -0
  8. package/dist/analysis/workspace.d.ts.map +1 -0
  9. package/dist/analysis/workspace.js +134 -0
  10. package/dist/analysis/workspace.js.map +1 -0
  11. package/dist/app-map-schema.d.ts +5 -0
  12. package/dist/app-map-schema.d.ts.map +1 -0
  13. package/dist/app-map-schema.js +26 -0
  14. package/dist/app-map-schema.js.map +1 -0
  15. package/dist/app-map.d.ts +96 -0
  16. package/dist/app-map.d.ts.map +1 -0
  17. package/dist/app-map.js +1141 -0
  18. package/dist/app-map.js.map +1 -0
  19. package/dist/check.d.ts +7 -0
  20. package/dist/check.d.ts.map +1 -1
  21. package/dist/check.js +20 -5
  22. package/dist/check.js.map +1 -1
  23. package/dist/db.d.ts +32 -7
  24. package/dist/db.d.ts.map +1 -1
  25. package/dist/db.js +182 -14
  26. package/dist/db.js.map +1 -1
  27. package/dist/explain.d.ts +98 -0
  28. package/dist/explain.d.ts.map +1 -0
  29. package/dist/explain.js +512 -0
  30. package/dist/explain.js.map +1 -0
  31. package/dist/index.d.ts.map +1 -1
  32. package/dist/index.js +79 -2
  33. package/dist/index.js.map +1 -1
  34. package/dist/inspect.js +53 -3
  35. package/dist/inspect.js.map +1 -1
  36. package/dist/lib.d.ts +4 -0
  37. package/dist/lib.d.ts.map +1 -1
  38. package/dist/lib.js +2 -0
  39. package/dist/lib.js.map +1 -1
  40. package/dist/make.d.ts.map +1 -1
  41. package/dist/make.js +63 -2
  42. package/dist/make.js.map +1 -1
  43. package/dist/mcp.d.ts +1 -1
  44. package/dist/mcp.d.ts.map +1 -1
  45. package/dist/mcp.js +69 -1
  46. package/dist/mcp.js.map +1 -1
  47. package/dist/preflight.d.ts.map +1 -1
  48. package/dist/preflight.js +10 -0
  49. package/dist/preflight.js.map +1 -1
  50. package/dist/provider-add.d.ts.map +1 -1
  51. package/dist/provider-add.js +167 -13
  52. package/dist/provider-add.js.map +1 -1
  53. package/dist/provider-audit.d.ts +6 -0
  54. package/dist/provider-audit.d.ts.map +1 -1
  55. package/dist/provider-audit.js +63 -15
  56. package/dist/provider-audit.js.map +1 -1
  57. package/dist/templates/agents.d.ts.map +1 -1
  58. package/dist/templates/agents.js +17 -4
  59. package/dist/templates/agents.js.map +1 -1
  60. package/dist/templates/base.d.ts.map +1 -1
  61. package/dist/templates/base.js +10 -4
  62. package/dist/templates/base.js.map +1 -1
  63. package/dist/templates/index.d.ts +1 -1
  64. package/dist/templates/index.d.ts.map +1 -1
  65. package/dist/templates/index.js +8 -1
  66. package/dist/templates/index.js.map +1 -1
  67. package/dist/templates/server.d.ts +3 -0
  68. package/dist/templates/server.d.ts.map +1 -1
  69. package/dist/templates/server.js +55 -1
  70. package/dist/templates/server.js.map +1 -1
  71. package/dist/templates/shared.js +1 -1
  72. package/package.json +2 -2
  73. package/skills/app-structure/SKILL.md +22 -4
  74. package/src/analysis/source-index.ts +395 -0
  75. package/src/analysis/workspace.ts +180 -0
  76. package/src/app-map-schema.ts +28 -0
  77. package/src/app-map.ts +1705 -0
  78. package/src/check.ts +27 -4
  79. package/src/db.ts +232 -14
  80. package/src/explain.ts +786 -0
  81. package/src/index.ts +113 -2
  82. package/src/inspect.ts +70 -2
  83. package/src/lib.ts +36 -0
  84. package/src/make.ts +90 -2
  85. package/src/mcp.ts +107 -1
  86. package/src/preflight.ts +14 -0
  87. package/src/provider-add.ts +211 -12
  88. package/src/provider-audit.ts +127 -22
  89. package/src/templates/agents.ts +17 -4
  90. package/src/templates/base.ts +22 -4
  91. package/src/templates/index.ts +18 -1
  92. package/src/templates/server.ts +58 -1
  93. package/src/templates/shared.ts +1 -1
package/CHANGELOG.md CHANGED
@@ -1,5 +1,14 @@
1
1
  # @beignet/cli
2
2
 
3
+ ## 0.0.41
4
+
5
+ ### Patch Changes
6
+
7
+ - 4516b4a: Expose source-backed app explanations and the full validation loop through new CLI APIs and MCP tools with provider-registration evidence, working-directory-aware actions, bounded output, request cancellation, and honest execution safety annotations.
8
+ - bdda67d: Add a deterministic app architecture map through `beignet map`, the public CLI library API, and a token-bounded `app_map` MCP tool.
9
+ - 5d4bb96: Add a generated Inngest v4 production path with shared clients, runtime-aware registries, Next.js serve routes, registry drift checks, production credential preflight, and explicit single-attempt retry semantics.
10
+ - @beignet/core@0.0.41
11
+
3
12
  ## 0.0.40
4
13
 
5
14
  ### Patch Changes
package/README.md CHANGED
@@ -171,6 +171,7 @@ Inspect the app, then generate the next feature:
171
171
  ```bash
172
172
  # in another terminal, from my-app
173
173
  bun beignet routes
174
+ bun beignet map
174
175
  bun run lint
175
176
  bun beignet lint
176
177
  bun beignet doctor
@@ -223,7 +224,12 @@ beignet db seed [--dry-run] [--json] [--cwd <dir>]
223
224
  beignet db reset [--dry-run] [--json] [--cwd <dir>]
224
225
  beignet db schema sync [--dialect sqlite|postgres|mysql] [--tables audit,idempotency,outbox] [--output <path>] [--dry-run] [--json] [--cwd <dir>]
225
226
  beignet routes [--json] [--cwd <dir>]
226
- beignet check [--json] [--fix] [--cwd <dir>]
227
+ beignet map [--json] [--feature <name>] [--kind <kinds>] [--cwd <dir>]
228
+ beignet explain feature <name> [--json] [--cwd <dir>]
229
+ beignet explain route <method-and-path> [--json] [--cwd <dir>]
230
+ beignet explain provider <package-or-port> [--json] [--cwd <dir>]
231
+ beignet explain diagnostic <code> [--json] [--cwd <dir>]
232
+ beignet check [--json] [--fix] [--preflight] [--cwd <dir>]
227
233
  beignet lint [--json] [--cwd <dir>] [--format human|json|github]
228
234
  beignet doctor [--json] [--strict] [--fix] [--cwd <dir>] [--format human|json|github]
229
235
  beignet provider add <preset> [--dry-run] [--json] [--cwd <dir>]
@@ -333,7 +339,7 @@ partial command line; it exists for the shell integration and is safe to
333
339
  ignore otherwise. Completions complete whatever `beignet` resolves to on your
334
340
  `PATH`, such as the app-local bin installed by generated apps.
335
341
 
336
- Beignet CLI commands are convention-aware. `routes`, `lint`, `doctor`, and
342
+ Beignet CLI commands are convention-aware. `routes`, `map`, `lint`, `doctor`, and
337
343
  generators work best in the Next.js layout created by `beignet create`:
338
344
 
339
345
  ```txt
@@ -834,8 +840,11 @@ messages. Both support bounded `--limit` runs and `--dry-run` previews.
834
840
  There is intentionally no separate `beignet jobs drain` command. Outbox-backed
835
841
  jobs drain through the outbox beside durable events. Direct provider jobs should
836
842
  use provider-owned worker entrypoints, such as a BullMQ worker built with
837
- `createBullMQJobWorker(...)` or an Inngest route built with
838
- `createInngestJobFunction(...)`.
843
+ `createBullMQJobWorker(...)` or the generated Inngest `server/inngest.ts`
844
+ registry. Next apps receive `app/api/inngest/route.ts`; non-Next apps receive a
845
+ `createAppInngestFunctions(...)` factory for their runtime adapter. When the
846
+ Inngest provider is installed, `beignet make job` maintains the central
847
+ registry.
839
848
 
840
849
  Use `beignet schedule run` when you need to run a schedule explicitly from a
841
850
  local shell, CI job, or worker entrypoint:
@@ -944,6 +953,51 @@ Use JSON output when you want to feed the route catalog into another tool:
944
953
  beignet routes --json
945
954
  ```
946
955
 
956
+ ## Map app architecture
957
+
958
+ Build a deterministic, source-backed graph of the app:
959
+
960
+ ```bash
961
+ beignet map
962
+ beignet map --feature issues
963
+ beignet map --json --kind route,use-case,event,listener
964
+ ```
965
+
966
+ The human view summarizes contracts, use cases, workflows, ports, UI, and tests
967
+ per feature. JSON is a versioned `schemaVersion: 1` payload with features,
968
+ contracts, route groups, use cases, policies and abilities, workflow
969
+ definitions and registries, agent capabilities, ports, app/package providers,
970
+ tables, OpenAPI exposure, tests, cross-feature dependencies, doctor/lint
971
+ findings, and unresolved references. Every node has a stable ID and source;
972
+ every edge carries source evidence and confidence.
973
+
974
+ `--feature` keeps that feature plus its direct relationships, while `--kind`
975
+ accepts one or a comma-separated list of node kinds. These projections make
976
+ the same full graph practical for coding-agent context windows. The command is
977
+ report-only and does not fail because doctor or lint findings are present.
978
+
979
+ ## Explain mapped app concepts
980
+
981
+ Resolve one app-map target into deterministic, source-backed context:
982
+
983
+ ```bash
984
+ beignet explain feature issues
985
+ beignet explain route "POST /api/issues"
986
+ beignet explain provider storage
987
+ beignet explain diagnostic BEIGNET_ROUTE_GROUP_UNREGISTERED
988
+ ```
989
+
990
+ Human output summarizes relevant relationships, conventions, findings,
991
+ suggested files, and follow-up commands. `--json` returns the versioned
992
+ `schemaVersion: 1` payload used by the MCP `explain` tool. Feature explanations
993
+ bound their relationship list and report full and returned counts; use
994
+ `beignet map --feature <name> --json` or a route explanation for the omitted
995
+ detail. Provider explanations include the matching entry in the configured
996
+ provider registry when static provider audit proves it. Human output names
997
+ the app root, and command actions in JSON carry their own `cwd`, so an
998
+ explanation requested with `--cwd` stays copy-pasteable. Explain is report-only
999
+ and never changes the app.
1000
+
947
1001
  ## Run the validation loop
948
1002
 
949
1003
  Run `check` when you want the whole validation loop as one command:
@@ -957,12 +1011,14 @@ It runs `beignet lint`, `beignet doctor --strict`, and the app's own `lint`,
957
1011
  in that order. Every step runs even when an earlier one fails, so a single
958
1012
  run reports everything that needs fixing; the command exits non-zero when any
959
1013
  step fails. Missing package scripts are reported as skipped, never as
960
- failures.
1014
+ failures. Failed package-script output retains at most the last 64 KiB of each
1015
+ stream.
961
1016
 
962
1017
  Use `beignet check --fix` to apply doctor's low-risk registration fixes
963
1018
  before checking, and `beignet check --json` for a versioned payload
964
1019
  (`schemaVersion: 1`) with the step list, statuses, captured failure output,
965
- and applied fixes. The individual commands below still work when you need one
1020
+ and applied fixes. Add `--preflight` to run the runtime environment gate after
1021
+ strict doctor. The individual commands below still work when you need one
966
1022
  check alone or its `--format github` output.
967
1023
 
968
1024
  ## Gate the deploy environment
@@ -1135,8 +1191,8 @@ Use `beignet provider audit` when you want a report-only inventory of the
1135
1191
  provider packages installed in an app. The human audit prints provider
1136
1192
  metadata validity, registration status, required env, required tables, and
1137
1193
  declared app ports. `beignet provider audit --json` returns a versioned
1138
- `schemaVersion: 1` payload with active variants and watchers for scripts and
1139
- coding agents. The command does not fail CI for missing setup; stable,
1194
+ `schemaVersion: 1` payload with active variants, watchers, and source locations
1195
+ for matching provider-registry entries. The command does not fail CI for missing setup; stable,
1140
1196
  actionable findings belong in `doctor`.
1141
1197
 
1142
1198
  Use `beignet doctor --strict` for CI-oriented checks that may be noisy locally,
@@ -1172,8 +1228,18 @@ call the CLI as tools:
1172
1228
  beignet mcp
1173
1229
  ```
1174
1230
 
1175
- The server exposes six tools:
1176
-
1231
+ The server exposes nine tools:
1232
+
1233
+ - `app_map` - project the source-backed app graph by optional `feature`,
1234
+ `kinds`, and `includeDiagnostics` inputs (read-only)
1235
+ - `explain` - explain one source-backed feature, route, provider, or diagnostic
1236
+ with `{ kind, target }`, returning relationships, conventions, findings,
1237
+ suggested files, and follow-up commands (read-only)
1238
+ - `check` - run the complete validation loop and return versioned step
1239
+ results, bounded failure output, durations, and overall `ok`; accepts
1240
+ `{ preflight?: boolean, timeoutMs?: number }`, cancels the active script with
1241
+ the MCP request, and does not apply Beignet fixes. App scripts retain their
1242
+ normal side effects, so this is an execution tool rather than a read-only tool
1177
1243
  - `routes` - list app routes and contracts (read-only)
1178
1244
  - `doctor` - drift diagnostics as JSON, `{ strict?: boolean }` defaults to
1179
1245
  `true` (read-only)
@@ -0,0 +1,38 @@
1
+ import ts from "typescript";
2
+ import { type AnalysisWorkspace } from "./workspace.js";
3
+ export type AnalysisSourceLocation = {
4
+ file: string;
5
+ exportName?: string;
6
+ line?: number;
7
+ column?: number;
8
+ };
9
+ export type ResolvedSourceReference = {
10
+ file: string;
11
+ exportName: string;
12
+ declaration?: ts.Declaration;
13
+ };
14
+ export type LocalImportReference = {
15
+ file: string;
16
+ importPath: string;
17
+ resolvedFile: string;
18
+ kind: "type" | "value";
19
+ line: number;
20
+ column: number;
21
+ };
22
+ export type SourceIndex = {
23
+ resolveName(file: string, name: string): Promise<ResolvedSourceReference | undefined>;
24
+ resolveExpression(file: string, expression: ts.Expression): Promise<ResolvedSourceReference | undefined>;
25
+ resolveExport(file: string, exportName: string): Promise<ResolvedSourceReference | undefined>;
26
+ sourceLocation(file: string, node: ts.Node, exportName?: string): Promise<AnalysisSourceLocation>;
27
+ };
28
+ export declare function createSourceIndex(workspace: AnalysisWorkspace): SourceIndex;
29
+ export declare function exportedVariableDeclarations(sourceFile: ts.SourceFile): Array<{
30
+ exportName: string;
31
+ declaration: ts.VariableDeclaration;
32
+ }>;
33
+ export declare function literalText(node: ts.Node | undefined): string | undefined;
34
+ export declare function propertyAssignment(object: ts.ObjectLiteralExpression, name: string): ts.PropertyAssignment | undefined;
35
+ export declare function propertyName(node: ts.PropertyName): string | undefined;
36
+ export declare function visitCalls(node: ts.Node, visit: (call: ts.CallExpression) => void): void;
37
+ export declare function localImportReferences(workspace: AnalysisWorkspace, file: string): Promise<LocalImportReference[]>;
38
+ //# sourceMappingURL=source-index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"source-index.d.ts","sourceRoot":"","sources":["../../src/analysis/source-index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,YAAY,CAAC;AAC5B,OAAO,EAAE,KAAK,iBAAiB,EAA0B,MAAM,gBAAgB,CAAC;AAEhF,MAAM,MAAM,sBAAsB,GAAG;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,MAAM,MAAM,uBAAuB,GAAG;IACpC,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,EAAE,CAAC,WAAW,CAAC;CAC9B,CAAC;AAEF,MAAM,MAAM,oBAAoB,GAAG;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAaF,MAAM,MAAM,WAAW,GAAG;IACxB,WAAW,CACT,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,uBAAuB,GAAG,SAAS,CAAC,CAAC;IAChD,iBAAiB,CACf,IAAI,EAAE,MAAM,EACZ,UAAU,EAAE,EAAE,CAAC,UAAU,GACxB,OAAO,CAAC,uBAAuB,GAAG,SAAS,CAAC,CAAC;IAChD,aAAa,CACX,IAAI,EAAE,MAAM,EACZ,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,uBAAuB,GAAG,SAAS,CAAC,CAAC;IAChD,cAAc,CACZ,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,EAAE,CAAC,IAAI,EACb,UAAU,CAAC,EAAE,MAAM,GAClB,OAAO,CAAC,sBAAsB,CAAC,CAAC;CACpC,CAAC;AAEF,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,iBAAiB,GAAG,WAAW,CAuM3E;AAED,wBAAgB,4BAA4B,CAC1C,UAAU,EAAE,EAAE,CAAC,UAAU,GACxB,KAAK,CAAC;IAAE,UAAU,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,EAAE,CAAC,mBAAmB,CAAA;CAAE,CAAC,CAqBpE;AAED,wBAAgB,WAAW,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAKzE;AAED,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,EAAE,CAAC,uBAAuB,EAClC,IAAI,EAAE,MAAM,GACX,EAAE,CAAC,kBAAkB,GAAG,SAAS,CAKnC;AAED,wBAAgB,YAAY,CAAC,IAAI,EAAE,EAAE,CAAC,YAAY,GAAG,MAAM,GAAG,SAAS,CAGtE;AAED,wBAAgB,UAAU,CACxB,IAAI,EAAE,EAAE,CAAC,IAAI,EACb,KAAK,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,cAAc,KAAK,IAAI,GACvC,IAAI,CAMN;AAED,wBAAsB,qBAAqB,CACzC,SAAS,EAAE,iBAAiB,EAC5B,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,oBAAoB,EAAE,CAAC,CAkDjC"}
@@ -0,0 +1,271 @@
1
+ import ts from "typescript";
2
+ import { resolveLocalSourceFile } from "./workspace.js";
3
+ export function createSourceIndex(workspace) {
4
+ const indexes = new Map();
5
+ const readIndex = async (file) => {
6
+ const cached = indexes.get(file);
7
+ if (cached)
8
+ return cached;
9
+ const sourceFile = await workspace.readSourceFile(file);
10
+ const index = {
11
+ declarations: new Map(),
12
+ imports: new Map(),
13
+ reexports: new Map(),
14
+ exportStars: [],
15
+ };
16
+ indexes.set(file, index);
17
+ for (const statement of sourceFile.statements) {
18
+ if (ts.isImportDeclaration(statement)) {
19
+ const source = moduleText(statement.moduleSpecifier);
20
+ const target = source
21
+ ? resolveLocalSourceFile(workspace, file, source)
22
+ : undefined;
23
+ if (!target || !statement.importClause)
24
+ continue;
25
+ if (statement.importClause.name) {
26
+ index.imports.set(statement.importClause.name.text, {
27
+ kind: "named",
28
+ file: target,
29
+ exportName: "default",
30
+ });
31
+ }
32
+ const bindings = statement.importClause.namedBindings;
33
+ if (bindings && ts.isNamespaceImport(bindings)) {
34
+ index.imports.set(bindings.name.text, {
35
+ kind: "namespace",
36
+ file: target,
37
+ });
38
+ }
39
+ else if (bindings && ts.isNamedImports(bindings)) {
40
+ for (const element of bindings.elements) {
41
+ index.imports.set(element.name.text, {
42
+ kind: "named",
43
+ file: target,
44
+ exportName: element.propertyName?.text ?? element.name.text,
45
+ });
46
+ }
47
+ }
48
+ continue;
49
+ }
50
+ if (ts.isExportDeclaration(statement)) {
51
+ const source = statement.moduleSpecifier
52
+ ? moduleText(statement.moduleSpecifier)
53
+ : undefined;
54
+ const target = source
55
+ ? resolveLocalSourceFile(workspace, file, source)
56
+ : undefined;
57
+ if (!target)
58
+ continue;
59
+ if (!statement.exportClause) {
60
+ index.exportStars.push(target);
61
+ continue;
62
+ }
63
+ if (ts.isNamedExports(statement.exportClause)) {
64
+ for (const element of statement.exportClause.elements) {
65
+ index.reexports.set(element.name.text, {
66
+ file: target,
67
+ exportName: element.propertyName?.text ?? element.name.text,
68
+ });
69
+ }
70
+ }
71
+ continue;
72
+ }
73
+ if (ts.isVariableStatement(statement) && hasExportModifier(statement)) {
74
+ for (const declaration of statement.declarationList.declarations) {
75
+ if (ts.isIdentifier(declaration.name)) {
76
+ index.declarations.set(declaration.name.text, declaration);
77
+ }
78
+ }
79
+ continue;
80
+ }
81
+ if ((ts.isFunctionDeclaration(statement) ||
82
+ ts.isClassDeclaration(statement) ||
83
+ ts.isInterfaceDeclaration(statement) ||
84
+ ts.isTypeAliasDeclaration(statement) ||
85
+ ts.isEnumDeclaration(statement)) &&
86
+ hasExportModifier(statement) &&
87
+ statement.name) {
88
+ index.declarations.set(statement.name.text, statement);
89
+ }
90
+ }
91
+ return index;
92
+ };
93
+ const resolveExport = async (file, exportName, visited = new Set()) => {
94
+ const key = `${file}#${exportName}`;
95
+ if (visited.has(key))
96
+ return undefined;
97
+ visited.add(key);
98
+ const index = await readIndex(file);
99
+ const declaration = index.declarations.get(exportName);
100
+ if (declaration)
101
+ return { file, exportName, declaration };
102
+ const reexport = index.reexports.get(exportName);
103
+ if (reexport) {
104
+ return ((await resolveExport(reexport.file, reexport.exportName, visited)) ?? {
105
+ file: reexport.file,
106
+ exportName: reexport.exportName,
107
+ });
108
+ }
109
+ for (const target of index.exportStars) {
110
+ const resolved = await resolveExport(target, exportName, visited);
111
+ if (resolved)
112
+ return resolved;
113
+ }
114
+ return undefined;
115
+ };
116
+ return {
117
+ async resolveName(file, name) {
118
+ const index = await readIndex(file);
119
+ const local = index.declarations.get(name);
120
+ if (local) {
121
+ return { file, exportName: name, declaration: local };
122
+ }
123
+ const binding = index.imports.get(name);
124
+ if (binding?.kind !== "named")
125
+ return undefined;
126
+ return ((await resolveExport(binding.file, binding.exportName)) ?? {
127
+ file: binding.file,
128
+ exportName: binding.exportName,
129
+ });
130
+ },
131
+ async resolveExpression(file, rawExpression) {
132
+ const expression = unwrapExpression(rawExpression);
133
+ const index = await readIndex(file);
134
+ if (ts.isIdentifier(expression)) {
135
+ const local = index.declarations.get(expression.text);
136
+ if (local) {
137
+ return { file, exportName: expression.text, declaration: local };
138
+ }
139
+ const binding = index.imports.get(expression.text);
140
+ if (binding?.kind !== "named")
141
+ return undefined;
142
+ return ((await resolveExport(binding.file, binding.exportName)) ?? {
143
+ file: binding.file,
144
+ exportName: binding.exportName,
145
+ });
146
+ }
147
+ if (ts.isPropertyAccessExpression(expression) &&
148
+ ts.isIdentifier(expression.expression)) {
149
+ const binding = index.imports.get(expression.expression.text);
150
+ if (binding?.kind !== "namespace")
151
+ return undefined;
152
+ return ((await resolveExport(binding.file, expression.name.text)) ?? {
153
+ file: binding.file,
154
+ exportName: expression.name.text,
155
+ });
156
+ }
157
+ return undefined;
158
+ },
159
+ resolveExport(file, exportName) {
160
+ return resolveExport(file, exportName);
161
+ },
162
+ async sourceLocation(file, node, exportName) {
163
+ const sourceFile = await workspace.readSourceFile(file);
164
+ const position = sourceFile.getLineAndCharacterOfPosition(node.getStart());
165
+ return {
166
+ file,
167
+ ...(exportName ? { exportName } : {}),
168
+ line: position.line + 1,
169
+ column: position.character + 1,
170
+ };
171
+ },
172
+ };
173
+ }
174
+ export function exportedVariableDeclarations(sourceFile) {
175
+ const declarations = [];
176
+ for (const statement of sourceFile.statements) {
177
+ if (!ts.isVariableStatement(statement) || !hasExportModifier(statement)) {
178
+ continue;
179
+ }
180
+ for (const declaration of statement.declarationList.declarations) {
181
+ if (ts.isIdentifier(declaration.name)) {
182
+ declarations.push({
183
+ exportName: declaration.name.text,
184
+ declaration,
185
+ });
186
+ }
187
+ }
188
+ }
189
+ return declarations;
190
+ }
191
+ export function literalText(node) {
192
+ return node &&
193
+ (ts.isStringLiteral(node) || ts.isNoSubstitutionTemplateLiteral(node))
194
+ ? node.text
195
+ : undefined;
196
+ }
197
+ export function propertyAssignment(object, name) {
198
+ return object.properties.find((property) => ts.isPropertyAssignment(property) && propertyName(property.name) === name);
199
+ }
200
+ export function propertyName(node) {
201
+ if (ts.isIdentifier(node) || ts.isStringLiteral(node))
202
+ return node.text;
203
+ return undefined;
204
+ }
205
+ export function visitCalls(node, visit) {
206
+ const walk = (current) => {
207
+ if (ts.isCallExpression(current))
208
+ visit(current);
209
+ current.forEachChild(walk);
210
+ };
211
+ walk(node);
212
+ }
213
+ export async function localImportReferences(workspace, file) {
214
+ const sourceFile = await workspace.readSourceFile(file);
215
+ const references = [];
216
+ for (const statement of sourceFile.statements) {
217
+ if (!ts.isImportDeclaration(statement) &&
218
+ !ts.isExportDeclaration(statement)) {
219
+ continue;
220
+ }
221
+ if (!statement.moduleSpecifier)
222
+ continue;
223
+ const importPath = moduleText(statement.moduleSpecifier);
224
+ const resolvedFile = importPath
225
+ ? resolveLocalSourceFile(workspace, file, importPath)
226
+ : undefined;
227
+ if (!importPath || !resolvedFile)
228
+ continue;
229
+ const position = sourceFile.getLineAndCharacterOfPosition(statement.getStart(sourceFile));
230
+ const typeOnly = ts.isImportDeclaration(statement)
231
+ ? Boolean(statement.importClause?.isTypeOnly ||
232
+ (statement.importClause?.namedBindings &&
233
+ ts.isNamedImports(statement.importClause.namedBindings) &&
234
+ statement.importClause.namedBindings.elements.length > 0 &&
235
+ statement.importClause.namedBindings.elements.every((element) => element.isTypeOnly)))
236
+ : statement.isTypeOnly ||
237
+ (statement.exportClause &&
238
+ ts.isNamedExports(statement.exportClause) &&
239
+ statement.exportClause.elements.length > 0 &&
240
+ statement.exportClause.elements.every((element) => element.isTypeOnly));
241
+ references.push({
242
+ file,
243
+ importPath,
244
+ resolvedFile,
245
+ kind: typeOnly ? "type" : "value",
246
+ line: position.line + 1,
247
+ column: position.character + 1,
248
+ });
249
+ }
250
+ return references;
251
+ }
252
+ function moduleText(node) {
253
+ return ts.isStringLiteral(node) ? node.text : undefined;
254
+ }
255
+ function hasExportModifier(node) {
256
+ return Boolean(ts.canHaveModifiers(node) &&
257
+ ts
258
+ .getModifiers(node)
259
+ ?.some((modifier) => modifier.kind === ts.SyntaxKind.ExportKeyword));
260
+ }
261
+ function unwrapExpression(expression) {
262
+ let current = expression;
263
+ while (ts.isAsExpression(current) ||
264
+ ts.isSatisfiesExpression(current) ||
265
+ ts.isParenthesizedExpression(current) ||
266
+ ts.isNonNullExpression(current)) {
267
+ current = current.expression;
268
+ }
269
+ return current;
270
+ }
271
+ //# sourceMappingURL=source-index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"source-index.js","sourceRoot":"","sources":["../../src/analysis/source-index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ import ts from "typescript";
2
+ import { type ResolvedBeignetConfig } from "../config.js";
3
+ export type AnalysisWorkspace = {
4
+ targetDir: string;
5
+ files: string[];
6
+ fileSet: Set<string>;
7
+ config: ResolvedBeignetConfig;
8
+ atAliasRoot: string;
9
+ readSource(file: string): Promise<string>;
10
+ readSourceFile(file: string): Promise<ts.SourceFile>;
11
+ };
12
+ export declare function createAnalysisWorkspace(cwd?: string): Promise<AnalysisWorkspace>;
13
+ export declare function assertDirectory(targetDir: string): Promise<void>;
14
+ export declare function listProjectFiles(targetDir: string): Promise<string[]>;
15
+ export declare function resolveLocalSourceFile(workspace: Pick<AnalysisWorkspace, "atAliasRoot" | "fileSet">, importerFile: string, importPath: string): string | undefined;
16
+ //# sourceMappingURL=workspace.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workspace.d.ts","sourceRoot":"","sources":["../../src/analysis/workspace.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,MAAM,YAAY,CAAC;AAC5B,OAAO,EAIL,KAAK,qBAAqB,EAC3B,MAAM,cAAc,CAAC;AAWtB,MAAM,MAAM,iBAAiB,GAAG;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,OAAO,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IACrB,MAAM,EAAE,qBAAqB,CAAC;IAC9B,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAC1C,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC;CACtD,CAAC;AAEF,wBAAsB,uBAAuB,CAC3C,GAAG,SAAgB,GAClB,OAAO,CAAC,iBAAiB,CAAC,CAyC5B;AAED,wBAAsB,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAYtE;AAED,wBAAsB,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAqB3E;AAED,wBAAgB,sBAAsB,CACpC,SAAS,EAAE,IAAI,CAAC,iBAAiB,EAAE,aAAa,GAAG,SAAS,CAAC,EAC7D,YAAY,EAAE,MAAM,EACpB,UAAU,EAAE,MAAM,GACjB,MAAM,GAAG,SAAS,CA6BpB"}
@@ -0,0 +1,134 @@
1
+ import { readdir, readFile, stat } from "node:fs/promises";
2
+ import path from "node:path";
3
+ import ts from "typescript";
4
+ import { directoryPath, loadBeignetConfig, normalizePath, } from "../config.js";
5
+ const ignoredDirectoryNames = new Set([
6
+ ".git",
7
+ ".next",
8
+ ".turbo",
9
+ "coverage",
10
+ "dist",
11
+ "node_modules",
12
+ ]);
13
+ export async function createAnalysisWorkspace(cwd = process.cwd()) {
14
+ const targetDir = path.resolve(cwd);
15
+ await assertDirectory(targetDir);
16
+ const files = await listProjectFiles(targetDir);
17
+ const fileSet = new Set(files);
18
+ const config = await loadBeignetConfig(targetDir, files);
19
+ const atAliasRoot = resolveAtAliasRoot(targetDir);
20
+ const sources = new Map();
21
+ const sourceFiles = new Map();
22
+ const readSource = async (file) => {
23
+ const cached = sources.get(file);
24
+ if (cached !== undefined)
25
+ return cached;
26
+ const source = await readFile(path.join(targetDir, file), "utf8");
27
+ sources.set(file, source);
28
+ return source;
29
+ };
30
+ return {
31
+ targetDir,
32
+ files,
33
+ fileSet,
34
+ config,
35
+ atAliasRoot,
36
+ readSource,
37
+ async readSourceFile(file) {
38
+ const cached = sourceFiles.get(file);
39
+ if (cached)
40
+ return cached;
41
+ const sourceFile = ts.createSourceFile(file, await readSource(file), ts.ScriptTarget.Latest, true, scriptKind(file));
42
+ sourceFiles.set(file, sourceFile);
43
+ return sourceFile;
44
+ },
45
+ };
46
+ }
47
+ export async function assertDirectory(targetDir) {
48
+ try {
49
+ const stats = await stat(targetDir);
50
+ if (!stats.isDirectory()) {
51
+ throw new Error(`${targetDir} is not a directory.`);
52
+ }
53
+ }
54
+ catch (error) {
55
+ if (error instanceof Error && error.message.includes("not a directory")) {
56
+ throw error;
57
+ }
58
+ throw new Error(`Directory ${targetDir} does not exist.`);
59
+ }
60
+ }
61
+ export async function listProjectFiles(targetDir) {
62
+ const files = [];
63
+ async function visit(relativeDir) {
64
+ const absoluteDir = path.join(targetDir, relativeDir);
65
+ const entries = await readdir(absoluteDir, { withFileTypes: true });
66
+ for (const entry of entries) {
67
+ if (ignoredDirectoryNames.has(entry.name))
68
+ continue;
69
+ const relativePath = normalizePath(path.join(relativeDir, entry.name));
70
+ if (entry.isDirectory()) {
71
+ await visit(relativePath);
72
+ }
73
+ else if (entry.isFile()) {
74
+ files.push(relativePath);
75
+ }
76
+ }
77
+ }
78
+ await visit("");
79
+ return files.sort();
80
+ }
81
+ export function resolveLocalSourceFile(workspace, importerFile, importPath) {
82
+ let candidate;
83
+ if (importPath.startsWith("@/")) {
84
+ candidate = path.posix.join(workspace.atAliasRoot, importPath.slice("@/".length));
85
+ }
86
+ else if (importPath.startsWith(".")) {
87
+ candidate = normalizePath(path.join(path.dirname(importerFile), importPath));
88
+ }
89
+ else {
90
+ return undefined;
91
+ }
92
+ const withoutExtension = candidate.replace(/\.(c|m)?tsx?$/, "");
93
+ const candidates = [
94
+ candidate,
95
+ `${withoutExtension}.ts`,
96
+ `${withoutExtension}.tsx`,
97
+ `${withoutExtension}.mts`,
98
+ `${withoutExtension}.cts`,
99
+ `${withoutExtension}/index.ts`,
100
+ `${withoutExtension}/index.tsx`,
101
+ `${withoutExtension}/index.mts`,
102
+ `${withoutExtension}/index.cts`,
103
+ ];
104
+ return candidates.find((file) => workspace.fileSet.has(file));
105
+ }
106
+ function resolveAtAliasRoot(targetDir) {
107
+ const parsed = ts.getParsedCommandLineOfConfigFile(path.join(targetDir, "tsconfig.json"), {}, {
108
+ ...ts.sys,
109
+ onUnRecoverableConfigFileDiagnostic: () => { },
110
+ });
111
+ const aliasTarget = parsed?.options.paths?.["@/*"]?.[0];
112
+ if (!aliasTarget)
113
+ return "";
114
+ const targetWithoutWildcard = aliasTarget.replace(/[/\\]?\*$/, "");
115
+ const baseUrl = parsed.options.baseUrl ?? targetDir;
116
+ const relativeTarget = normalizePath(path.relative(targetDir, path.resolve(baseUrl, targetWithoutWildcard)));
117
+ if (relativeTarget === "" ||
118
+ relativeTarget === "." ||
119
+ relativeTarget === ".." ||
120
+ relativeTarget.startsWith("../")) {
121
+ return "";
122
+ }
123
+ return directoryPath(relativeTarget);
124
+ }
125
+ function scriptKind(file) {
126
+ if (file.endsWith(".tsx"))
127
+ return ts.ScriptKind.TSX;
128
+ if (file.endsWith(".jsx"))
129
+ return ts.ScriptKind.JSX;
130
+ if (file.endsWith(".js") || file.endsWith(".mjs"))
131
+ return ts.ScriptKind.JS;
132
+ return ts.ScriptKind.TS;
133
+ }
134
+ //# sourceMappingURL=workspace.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workspace.js","sourceRoot":"","sources":["../../src/analysis/workspace.ts"],"names":[],"mappings":"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"}