@beignet/cli 0.0.40 → 0.0.42
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/CHANGELOG.md +19 -0
- package/README.md +139 -17
- package/dist/analysis/source-index.d.ts +38 -0
- package/dist/analysis/source-index.d.ts.map +1 -0
- package/dist/analysis/source-index.js +271 -0
- package/dist/analysis/source-index.js.map +1 -0
- package/dist/analysis/workspace.d.ts +16 -0
- package/dist/analysis/workspace.d.ts.map +1 -0
- package/dist/analysis/workspace.js +134 -0
- package/dist/analysis/workspace.js.map +1 -0
- package/dist/app-map-schema.d.ts +5 -0
- package/dist/app-map-schema.d.ts.map +1 -0
- package/dist/app-map-schema.js +26 -0
- package/dist/app-map-schema.js.map +1 -0
- package/dist/app-map.d.ts +96 -0
- package/dist/app-map.d.ts.map +1 -0
- package/dist/app-map.js +1141 -0
- package/dist/app-map.js.map +1 -0
- package/dist/check.d.ts +7 -0
- package/dist/check.d.ts.map +1 -1
- package/dist/check.js +20 -5
- package/dist/check.js.map +1 -1
- package/dist/choices.d.ts +18 -0
- package/dist/choices.d.ts.map +1 -1
- package/dist/choices.js +35 -0
- package/dist/choices.js.map +1 -1
- package/dist/db.d.ts +49 -13
- package/dist/db.d.ts.map +1 -1
- package/dist/db.js +202 -21
- package/dist/db.js.map +1 -1
- package/dist/doctor-fixes.d.ts +64 -0
- package/dist/doctor-fixes.d.ts.map +1 -0
- package/dist/doctor-fixes.js +142 -0
- package/dist/doctor-fixes.js.map +1 -0
- package/dist/explain.d.ts +100 -0
- package/dist/explain.d.ts.map +1 -0
- package/dist/explain.js +606 -0
- package/dist/explain.js.map +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +165 -21
- package/dist/index.js.map +1 -1
- package/dist/inspect.d.ts +33 -9
- package/dist/inspect.d.ts.map +1 -1
- package/dist/inspect.js +406 -119
- package/dist/inspect.js.map +1 -1
- package/dist/lib.d.ts +10 -2
- package/dist/lib.d.ts.map +1 -1
- package/dist/lib.js +5 -2
- package/dist/lib.js.map +1 -1
- package/dist/make/shared.js +3 -3
- package/dist/make/shared.js.map +1 -1
- package/dist/make.d.ts.map +1 -1
- package/dist/make.js +63 -2
- package/dist/make.js.map +1 -1
- package/dist/mcp.d.ts +1 -1
- package/dist/mcp.d.ts.map +1 -1
- package/dist/mcp.js +188 -12
- package/dist/mcp.js.map +1 -1
- package/dist/preflight.d.ts.map +1 -1
- package/dist/preflight.js +10 -0
- package/dist/preflight.js.map +1 -1
- package/dist/provider-add.d.ts.map +1 -1
- package/dist/provider-add.js +167 -13
- package/dist/provider-add.js.map +1 -1
- package/dist/provider-audit.d.ts +6 -0
- package/dist/provider-audit.d.ts.map +1 -1
- package/dist/provider-audit.js +63 -15
- package/dist/provider-audit.js.map +1 -1
- package/dist/templates/agents.d.ts.map +1 -1
- package/dist/templates/agents.js +35 -6
- package/dist/templates/agents.js.map +1 -1
- package/dist/templates/base.d.ts.map +1 -1
- package/dist/templates/base.js +13 -7
- package/dist/templates/base.js.map +1 -1
- package/dist/templates/index.d.ts +1 -1
- package/dist/templates/index.d.ts.map +1 -1
- package/dist/templates/index.js +8 -1
- package/dist/templates/index.js.map +1 -1
- package/dist/templates/server.d.ts +3 -0
- package/dist/templates/server.d.ts.map +1 -1
- package/dist/templates/server.js +55 -1
- package/dist/templates/server.js.map +1 -1
- package/dist/templates/shared.d.ts +2 -1
- package/dist/templates/shared.d.ts.map +1 -1
- package/dist/templates/shared.js +8 -5
- package/dist/templates/shared.js.map +1 -1
- package/package.json +3 -2
- package/skills/app-structure/SKILL.md +48 -6
- package/src/analysis/source-index.ts +395 -0
- package/src/analysis/workspace.ts +180 -0
- package/src/app-map-schema.ts +28 -0
- package/src/app-map.ts +1705 -0
- package/src/check.ts +27 -4
- package/src/choices.ts +57 -0
- package/src/db.ts +276 -28
- package/src/doctor-fixes.ts +252 -0
- package/src/explain.ts +894 -0
- package/src/index.ts +237 -31
- package/src/inspect.ts +567 -147
- package/src/lib.ts +64 -1
- package/src/make/shared.ts +3 -3
- package/src/make.ts +90 -2
- package/src/mcp.ts +292 -12
- package/src/preflight.ts +14 -0
- package/src/provider-add.ts +211 -12
- package/src/provider-audit.ts +127 -22
- package/src/templates/agents.ts +35 -6
- package/src/templates/base.ts +25 -6
- package/src/templates/index.ts +18 -1
- package/src/templates/server.ts +58 -1
- package/src/templates/shared.ts +15 -7
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
import { readdir, readFile, stat } from "node:fs/promises";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import ts from "typescript";
|
|
4
|
+
import {
|
|
5
|
+
directoryPath,
|
|
6
|
+
loadBeignetConfig,
|
|
7
|
+
normalizePath,
|
|
8
|
+
type ResolvedBeignetConfig,
|
|
9
|
+
} from "../config.js";
|
|
10
|
+
|
|
11
|
+
const ignoredDirectoryNames = new Set([
|
|
12
|
+
".git",
|
|
13
|
+
".next",
|
|
14
|
+
".turbo",
|
|
15
|
+
"coverage",
|
|
16
|
+
"dist",
|
|
17
|
+
"node_modules",
|
|
18
|
+
]);
|
|
19
|
+
|
|
20
|
+
export type AnalysisWorkspace = {
|
|
21
|
+
targetDir: string;
|
|
22
|
+
files: string[];
|
|
23
|
+
fileSet: Set<string>;
|
|
24
|
+
config: ResolvedBeignetConfig;
|
|
25
|
+
atAliasRoot: string;
|
|
26
|
+
readSource(file: string): Promise<string>;
|
|
27
|
+
readSourceFile(file: string): Promise<ts.SourceFile>;
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
export async function createAnalysisWorkspace(
|
|
31
|
+
cwd = process.cwd(),
|
|
32
|
+
): Promise<AnalysisWorkspace> {
|
|
33
|
+
const targetDir = path.resolve(cwd);
|
|
34
|
+
await assertDirectory(targetDir);
|
|
35
|
+
const files = await listProjectFiles(targetDir);
|
|
36
|
+
const fileSet = new Set(files);
|
|
37
|
+
const config = await loadBeignetConfig(targetDir, files);
|
|
38
|
+
const atAliasRoot = resolveAtAliasRoot(targetDir);
|
|
39
|
+
const sources = new Map<string, string>();
|
|
40
|
+
const sourceFiles = new Map<string, ts.SourceFile>();
|
|
41
|
+
|
|
42
|
+
const readSource = async (file: string): Promise<string> => {
|
|
43
|
+
const cached = sources.get(file);
|
|
44
|
+
if (cached !== undefined) return cached;
|
|
45
|
+
|
|
46
|
+
const source = await readFile(path.join(targetDir, file), "utf8");
|
|
47
|
+
sources.set(file, source);
|
|
48
|
+
return source;
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
return {
|
|
52
|
+
targetDir,
|
|
53
|
+
files,
|
|
54
|
+
fileSet,
|
|
55
|
+
config,
|
|
56
|
+
atAliasRoot,
|
|
57
|
+
readSource,
|
|
58
|
+
async readSourceFile(file) {
|
|
59
|
+
const cached = sourceFiles.get(file);
|
|
60
|
+
if (cached) return cached;
|
|
61
|
+
|
|
62
|
+
const sourceFile = ts.createSourceFile(
|
|
63
|
+
file,
|
|
64
|
+
await readSource(file),
|
|
65
|
+
ts.ScriptTarget.Latest,
|
|
66
|
+
true,
|
|
67
|
+
scriptKind(file),
|
|
68
|
+
);
|
|
69
|
+
sourceFiles.set(file, sourceFile);
|
|
70
|
+
return sourceFile;
|
|
71
|
+
},
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
export async function assertDirectory(targetDir: string): Promise<void> {
|
|
76
|
+
try {
|
|
77
|
+
const stats = await stat(targetDir);
|
|
78
|
+
if (!stats.isDirectory()) {
|
|
79
|
+
throw new Error(`${targetDir} is not a directory.`);
|
|
80
|
+
}
|
|
81
|
+
} catch (error) {
|
|
82
|
+
if (error instanceof Error && error.message.includes("not a directory")) {
|
|
83
|
+
throw error;
|
|
84
|
+
}
|
|
85
|
+
throw new Error(`Directory ${targetDir} does not exist.`);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
export async function listProjectFiles(targetDir: string): Promise<string[]> {
|
|
90
|
+
const files: string[] = [];
|
|
91
|
+
|
|
92
|
+
async function visit(relativeDir: string): Promise<void> {
|
|
93
|
+
const absoluteDir = path.join(targetDir, relativeDir);
|
|
94
|
+
const entries = await readdir(absoluteDir, { withFileTypes: true });
|
|
95
|
+
|
|
96
|
+
for (const entry of entries) {
|
|
97
|
+
if (ignoredDirectoryNames.has(entry.name)) continue;
|
|
98
|
+
|
|
99
|
+
const relativePath = normalizePath(path.join(relativeDir, entry.name));
|
|
100
|
+
if (entry.isDirectory()) {
|
|
101
|
+
await visit(relativePath);
|
|
102
|
+
} else if (entry.isFile()) {
|
|
103
|
+
files.push(relativePath);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
await visit("");
|
|
109
|
+
return files.sort();
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
export function resolveLocalSourceFile(
|
|
113
|
+
workspace: Pick<AnalysisWorkspace, "atAliasRoot" | "fileSet">,
|
|
114
|
+
importerFile: string,
|
|
115
|
+
importPath: string,
|
|
116
|
+
): string | undefined {
|
|
117
|
+
let candidate: string;
|
|
118
|
+
if (importPath.startsWith("@/")) {
|
|
119
|
+
candidate = path.posix.join(
|
|
120
|
+
workspace.atAliasRoot,
|
|
121
|
+
importPath.slice("@/".length),
|
|
122
|
+
);
|
|
123
|
+
} else if (importPath.startsWith(".")) {
|
|
124
|
+
candidate = normalizePath(
|
|
125
|
+
path.join(path.dirname(importerFile), importPath),
|
|
126
|
+
);
|
|
127
|
+
} else {
|
|
128
|
+
return undefined;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
const withoutExtension = candidate.replace(/\.(c|m)?tsx?$/, "");
|
|
132
|
+
const candidates = [
|
|
133
|
+
candidate,
|
|
134
|
+
`${withoutExtension}.ts`,
|
|
135
|
+
`${withoutExtension}.tsx`,
|
|
136
|
+
`${withoutExtension}.mts`,
|
|
137
|
+
`${withoutExtension}.cts`,
|
|
138
|
+
`${withoutExtension}/index.ts`,
|
|
139
|
+
`${withoutExtension}/index.tsx`,
|
|
140
|
+
`${withoutExtension}/index.mts`,
|
|
141
|
+
`${withoutExtension}/index.cts`,
|
|
142
|
+
];
|
|
143
|
+
|
|
144
|
+
return candidates.find((file) => workspace.fileSet.has(file));
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
function resolveAtAliasRoot(targetDir: string): string {
|
|
148
|
+
const parsed = ts.getParsedCommandLineOfConfigFile(
|
|
149
|
+
path.join(targetDir, "tsconfig.json"),
|
|
150
|
+
{},
|
|
151
|
+
{
|
|
152
|
+
...ts.sys,
|
|
153
|
+
onUnRecoverableConfigFileDiagnostic: () => {},
|
|
154
|
+
},
|
|
155
|
+
);
|
|
156
|
+
const aliasTarget = parsed?.options.paths?.["@/*"]?.[0];
|
|
157
|
+
if (!aliasTarget) return "";
|
|
158
|
+
|
|
159
|
+
const targetWithoutWildcard = aliasTarget.replace(/[/\\]?\*$/, "");
|
|
160
|
+
const baseUrl = parsed.options.baseUrl ?? targetDir;
|
|
161
|
+
const relativeTarget = normalizePath(
|
|
162
|
+
path.relative(targetDir, path.resolve(baseUrl, targetWithoutWildcard)),
|
|
163
|
+
);
|
|
164
|
+
if (
|
|
165
|
+
relativeTarget === "" ||
|
|
166
|
+
relativeTarget === "." ||
|
|
167
|
+
relativeTarget === ".." ||
|
|
168
|
+
relativeTarget.startsWith("../")
|
|
169
|
+
) {
|
|
170
|
+
return "";
|
|
171
|
+
}
|
|
172
|
+
return directoryPath(relativeTarget);
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
function scriptKind(file: string): ts.ScriptKind {
|
|
176
|
+
if (file.endsWith(".tsx")) return ts.ScriptKind.TSX;
|
|
177
|
+
if (file.endsWith(".jsx")) return ts.ScriptKind.JSX;
|
|
178
|
+
if (file.endsWith(".js") || file.endsWith(".mjs")) return ts.ScriptKind.JS;
|
|
179
|
+
return ts.ScriptKind.TS;
|
|
180
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/** Node kinds emitted by the version 1 Beignet app-map schema. */
|
|
2
|
+
export const appMapNodeKinds = [
|
|
3
|
+
"feature",
|
|
4
|
+
"contract",
|
|
5
|
+
"route",
|
|
6
|
+
"route-group",
|
|
7
|
+
"use-case",
|
|
8
|
+
"policy",
|
|
9
|
+
"ability",
|
|
10
|
+
"event",
|
|
11
|
+
"listener",
|
|
12
|
+
"job",
|
|
13
|
+
"schedule",
|
|
14
|
+
"task",
|
|
15
|
+
"notification",
|
|
16
|
+
"upload",
|
|
17
|
+
"agent-capability",
|
|
18
|
+
"registry",
|
|
19
|
+
"port",
|
|
20
|
+
"provider",
|
|
21
|
+
"table",
|
|
22
|
+
"openapi",
|
|
23
|
+
"entrypoint",
|
|
24
|
+
"test",
|
|
25
|
+
] as const;
|
|
26
|
+
|
|
27
|
+
/** One node-kind value from the version 1 Beignet app-map schema. */
|
|
28
|
+
export type AppMapNodeKind = (typeof appMapNodeKinds)[number];
|