openlore 2.0.1 → 2.0.3
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/README.md +57 -0
- package/dist/cli/commands/mcp.d.ts.map +1 -1
- package/dist/cli/commands/mcp.js +18 -1
- package/dist/cli/commands/mcp.js.map +1 -1
- package/dist/cli/export/index.d.ts +10 -0
- package/dist/cli/export/index.d.ts.map +1 -0
- package/dist/cli/export/index.js +27 -0
- package/dist/cli/export/index.js.map +1 -0
- package/dist/cli/export/scip.d.ts +22 -0
- package/dist/cli/export/scip.d.ts.map +1 -0
- package/dist/cli/export/scip.js +95 -0
- package/dist/cli/export/scip.js.map +1 -0
- package/dist/cli/index.js +19 -9
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/install/adapters/agents-md.d.ts +8 -0
- package/dist/cli/install/adapters/agents-md.d.ts.map +1 -0
- package/dist/cli/install/adapters/agents-md.js +21 -0
- package/dist/cli/install/adapters/agents-md.js.map +1 -0
- package/dist/cli/install/adapters/claude-code.d.ts +8 -0
- package/dist/cli/install/adapters/claude-code.d.ts.map +1 -0
- package/dist/cli/install/adapters/claude-code.js +184 -0
- package/dist/cli/install/adapters/claude-code.js.map +1 -0
- package/dist/cli/install/adapters/cline.d.ts +6 -0
- package/dist/cli/install/adapters/cline.d.ts.map +1 -0
- package/dist/cli/install/adapters/cline.js +19 -0
- package/dist/cli/install/adapters/cline.js.map +1 -0
- package/dist/cli/install/adapters/continue.d.ts +13 -0
- package/dist/cli/install/adapters/continue.d.ts.map +1 -0
- package/dist/cli/install/adapters/continue.js +119 -0
- package/dist/cli/install/adapters/continue.js.map +1 -0
- package/dist/cli/install/adapters/cursor.d.ts +8 -0
- package/dist/cli/install/adapters/cursor.d.ts.map +1 -0
- package/dist/cli/install/adapters/cursor.js +195 -0
- package/dist/cli/install/adapters/cursor.js.map +1 -0
- package/dist/cli/install/adapters/markdown-block.d.ts +20 -0
- package/dist/cli/install/adapters/markdown-block.d.ts.map +1 -0
- package/dist/cli/install/adapters/markdown-block.js +114 -0
- package/dist/cli/install/adapters/markdown-block.js.map +1 -0
- package/dist/cli/install/adapters/types.d.ts +39 -0
- package/dist/cli/install/adapters/types.d.ts.map +1 -0
- package/dist/cli/install/adapters/types.js +10 -0
- package/dist/cli/install/adapters/types.js.map +1 -0
- package/dist/cli/install/block.d.ts +53 -0
- package/dist/cli/install/block.d.ts.map +1 -0
- package/dist/cli/install/block.js +106 -0
- package/dist/cli/install/block.js.map +1 -0
- package/dist/cli/install/detect.d.ts +23 -0
- package/dist/cli/install/detect.d.ts.map +1 -0
- package/dist/cli/install/detect.js +115 -0
- package/dist/cli/install/detect.js.map +1 -0
- package/dist/cli/install/diff.d.ts +12 -0
- package/dist/cli/install/diff.d.ts.map +1 -0
- package/dist/cli/install/diff.js +51 -0
- package/dist/cli/install/diff.js.map +1 -0
- package/dist/cli/install/index.d.ts +19 -0
- package/dist/cli/install/index.d.ts.map +1 -0
- package/dist/cli/install/index.js +133 -0
- package/dist/cli/install/index.js.map +1 -0
- package/dist/cli/install/json-managed.d.ts +43 -0
- package/dist/cli/install/json-managed.d.ts.map +1 -0
- package/dist/cli/install/json-managed.js +137 -0
- package/dist/cli/install/json-managed.js.map +1 -0
- package/dist/cli/install/templates/agent-instructions.md +12 -0
- package/dist/cli/install/templates/cursor-openlore.mdc +7 -0
- package/dist/cli/manifest/detect/events.d.ts +31 -0
- package/dist/cli/manifest/detect/events.d.ts.map +1 -0
- package/dist/cli/manifest/detect/events.js +22 -0
- package/dist/cli/manifest/detect/events.js.map +1 -0
- package/dist/cli/manifest/detect/http-routes.d.ts +22 -0
- package/dist/cli/manifest/detect/http-routes.d.ts.map +1 -0
- package/dist/cli/manifest/detect/http-routes.js +18 -0
- package/dist/cli/manifest/detect/http-routes.js.map +1 -0
- package/dist/cli/manifest/detect/public-symbols.d.ts +46 -0
- package/dist/cli/manifest/detect/public-symbols.d.ts.map +1 -0
- package/dist/cli/manifest/detect/public-symbols.js +144 -0
- package/dist/cli/manifest/detect/public-symbols.js.map +1 -0
- package/dist/cli/manifest/emit.d.ts +103 -0
- package/dist/cli/manifest/emit.d.ts.map +1 -0
- package/dist/cli/manifest/emit.js +272 -0
- package/dist/cli/manifest/emit.js.map +1 -0
- package/dist/cli/manifest/index.d.ts +11 -0
- package/dist/cli/manifest/index.d.ts.map +1 -0
- package/dist/cli/manifest/index.js +31 -0
- package/dist/cli/manifest/index.js.map +1 -0
- package/dist/cli/manifest/schema-validator.d.ts +18 -0
- package/dist/cli/manifest/schema-validator.d.ts.map +1 -0
- package/dist/cli/manifest/schema-validator.js +77 -0
- package/dist/cli/manifest/schema-validator.js.map +1 -0
- package/dist/cli/manifest/validate.d.ts +15 -0
- package/dist/cli/manifest/validate.d.ts.map +1 -0
- package/dist/cli/manifest/validate.js +51 -0
- package/dist/cli/manifest/validate.js.map +1 -0
- package/dist/cli/preflight/diff.d.ts +42 -0
- package/dist/cli/preflight/diff.d.ts.map +1 -0
- package/dist/cli/preflight/diff.js +162 -0
- package/dist/cli/preflight/diff.js.map +1 -0
- package/dist/cli/preflight/index.d.ts +31 -0
- package/dist/cli/preflight/index.d.ts.map +1 -0
- package/dist/cli/preflight/index.js +126 -0
- package/dist/cli/preflight/index.js.map +1 -0
- package/dist/cli/preflight/report.d.ts +50 -0
- package/dist/cli/preflight/report.d.ts.map +1 -0
- package/dist/cli/preflight/report.js +174 -0
- package/dist/cli/preflight/report.js.map +1 -0
- package/dist/cli/preflight/score.d.ts +43 -0
- package/dist/cli/preflight/score.d.ts.map +1 -0
- package/dist/cli/preflight/score.js +102 -0
- package/dist/cli/preflight/score.js.map +1 -0
- package/dist/core/analyzer/file-walker.d.ts.map +1 -1
- package/dist/core/analyzer/file-walker.js +20 -13
- package/dist/core/analyzer/file-walker.js.map +1 -1
- package/dist/core/analyzer/vector-index.d.ts +2 -0
- package/dist/core/analyzer/vector-index.d.ts.map +1 -1
- package/dist/core/analyzer/vector-index.js +30 -20
- package/dist/core/analyzer/vector-index.js.map +1 -1
- package/dist/core/scip/index.d.ts +51 -0
- package/dist/core/scip/index.d.ts.map +1 -0
- package/dist/core/scip/index.js +210 -0
- package/dist/core/scip/index.js.map +1 -0
- package/dist/core/scip/moniker.d.ts +48 -0
- package/dist/core/scip/moniker.d.ts.map +1 -0
- package/dist/core/scip/moniker.js +109 -0
- package/dist/core/scip/moniker.js.map +1 -0
- package/dist/core/scip/schema.d.ts +34 -0
- package/dist/core/scip/schema.d.ts.map +1 -0
- package/dist/core/scip/schema.js +48 -0
- package/dist/core/scip/schema.js.map +1 -0
- package/dist/core/scip/vendor/scip.proto +910 -0
- package/dist/core/services/mcp-handlers/utils.d.ts +2 -0
- package/dist/core/services/mcp-handlers/utils.d.ts.map +1 -1
- package/dist/core/services/mcp-handlers/utils.js +18 -2
- package/dist/core/services/mcp-handlers/utils.js.map +1 -1
- package/examples/ci/openlore-preflight.gitlab.yml +16 -0
- package/examples/ci/openlore-preflight.sh +16 -0
- package/examples/ci/openlore-preflight.yml +30 -0
- package/package.json +6 -2
- package/schemas/openlore-manifest-v1.json +191 -0
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Derive the public API surface from data the analyzer already produced.
|
|
3
|
+
*
|
|
4
|
+
* Default (conservative, per spec-05): a symbol is "public" if it is exported
|
|
5
|
+
* from the *package entry point(s)* (TS/JS), following re-exports to their
|
|
6
|
+
* definition for an accurate kind/line. Public methods of an exported class are
|
|
7
|
+
* included too (e.g. `BillingService.refund`). For files in languages the
|
|
8
|
+
* export extractor does not cover, we fall back to "top-level non-underscore
|
|
9
|
+
* function" (matching the Python `__all__`/non-underscore convention).
|
|
10
|
+
*
|
|
11
|
+
* `--include-private` drops the public filter entirely and emits every
|
|
12
|
+
* file-level export plus every function/method node (a much larger list).
|
|
13
|
+
*
|
|
14
|
+
* Sources:
|
|
15
|
+
* - dependency-graph.json `exports[]` — name/kind/line/isReExport per file.
|
|
16
|
+
* - the call graph — public methods of exported classes, with lines.
|
|
17
|
+
*
|
|
18
|
+
* We do NOT add new language parsers here (spec-05 scope).
|
|
19
|
+
* TODO(spec-05-followup): surface exported types/interfaces with line numbers.
|
|
20
|
+
*/
|
|
21
|
+
/** A name is "public-looking" if it is not underscore/hash-prefixed. */
|
|
22
|
+
function isPublicName(name) {
|
|
23
|
+
return !/^[_#]/.test(name);
|
|
24
|
+
}
|
|
25
|
+
/** Resolve `./foo.js` (relative to `fromFile`) to a repo-relative `.ts` path. */
|
|
26
|
+
function resolveReExportTarget(fromFile, source) {
|
|
27
|
+
const dir = fromFile.includes('/') ? fromFile.slice(0, fromFile.lastIndexOf('/')) : '';
|
|
28
|
+
const parts = (dir ? `${dir}/${source}` : source).split('/');
|
|
29
|
+
const stack = [];
|
|
30
|
+
for (const p of parts) {
|
|
31
|
+
if (p === '.' || p === '')
|
|
32
|
+
continue;
|
|
33
|
+
if (p === '..')
|
|
34
|
+
stack.pop();
|
|
35
|
+
else
|
|
36
|
+
stack.push(p);
|
|
37
|
+
}
|
|
38
|
+
return stack.join('/').replace(/\.js$/, '.ts');
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Resolve an entry-point export to its defining {kind, file, line}, following
|
|
42
|
+
* re-export hops. Prefers the call graph for accurate lines; the export
|
|
43
|
+
* extractor does not always record a re-export target's own exports.
|
|
44
|
+
*/
|
|
45
|
+
function resolveExport(entry, file, exportsByFile, lookup, depth = 0) {
|
|
46
|
+
if (entry.isReExport && entry.reExportSource && depth <= 4) {
|
|
47
|
+
const target = resolveReExportTarget(file, entry.reExportSource);
|
|
48
|
+
const match = exportsByFile.get(target)?.find(e => e.name === entry.name);
|
|
49
|
+
if (match)
|
|
50
|
+
return resolveExport(match, target, exportsByFile, lookup, depth + 1);
|
|
51
|
+
const fromGraph = lookup(target, entry.name);
|
|
52
|
+
if (fromGraph)
|
|
53
|
+
return fromGraph;
|
|
54
|
+
return { name: entry.name, kind: 'symbol', file, line: entry.line };
|
|
55
|
+
}
|
|
56
|
+
// Direct export — prefer the call graph's line/kind when it knows the symbol.
|
|
57
|
+
return (lookup(file, entry.name) ?? {
|
|
58
|
+
name: entry.name,
|
|
59
|
+
kind: entry.kind === 'unknown' ? 'symbol' : entry.kind,
|
|
60
|
+
file,
|
|
61
|
+
line: entry.line,
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
export function derivePublicSymbols(args) {
|
|
65
|
+
const { nodes, classes, exportsByFile, entryFiles, includePrivate } = args;
|
|
66
|
+
const byKey = new Map();
|
|
67
|
+
// Call-graph indices for resolving re-exported definitions to file+line.
|
|
68
|
+
const freeFnIndex = new Map();
|
|
69
|
+
for (const n of nodes) {
|
|
70
|
+
if (!n.isExternal && !n.isTest && !n.className)
|
|
71
|
+
freeFnIndex.set(`${n.filePath}::${n.name}`, n);
|
|
72
|
+
}
|
|
73
|
+
const classIndex = new Map();
|
|
74
|
+
for (const c of classes)
|
|
75
|
+
classIndex.set(`${c.filePath}::${c.name}`, c);
|
|
76
|
+
const lookup = (file, name) => {
|
|
77
|
+
const fn = freeFnIndex.get(`${file}::${name}`);
|
|
78
|
+
if (fn)
|
|
79
|
+
return { name, kind: 'function', file, line: fn.startLine ?? 0 };
|
|
80
|
+
const cls = classIndex.get(`${file}::${name}`);
|
|
81
|
+
if (cls)
|
|
82
|
+
return { name, kind: 'class', file, line: 0 };
|
|
83
|
+
return null;
|
|
84
|
+
};
|
|
85
|
+
const add = (s) => {
|
|
86
|
+
const key = `${s.file}::${s.name}`;
|
|
87
|
+
if (!byKey.has(key))
|
|
88
|
+
byKey.set(key, s);
|
|
89
|
+
};
|
|
90
|
+
// Methods of a class, keyed for the "expand exported class" step.
|
|
91
|
+
const methodsByClass = new Map();
|
|
92
|
+
for (const n of nodes) {
|
|
93
|
+
if (n.isExternal || n.isTest || !n.className)
|
|
94
|
+
continue;
|
|
95
|
+
const key = `${n.filePath}::${n.className}`;
|
|
96
|
+
(methodsByClass.get(key) ?? methodsByClass.set(key, []).get(key)).push(n);
|
|
97
|
+
}
|
|
98
|
+
const addPublicMethods = (className, file) => {
|
|
99
|
+
for (const m of methodsByClass.get(`${file}::${className}`) ?? []) {
|
|
100
|
+
if (isPublicName(m.name) && !/\bprivate\b/.test(m.signature ?? '')) {
|
|
101
|
+
add({ name: `${className}.${m.name}`, kind: 'method', file, line: m.startLine ?? 0 });
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
};
|
|
105
|
+
if (includePrivate) {
|
|
106
|
+
// Everything: all file-level exports + all function/method nodes.
|
|
107
|
+
for (const [file, entries] of exportsByFile) {
|
|
108
|
+
for (const e of entries)
|
|
109
|
+
add({ name: e.name, kind: e.kind, file, line: e.line });
|
|
110
|
+
}
|
|
111
|
+
for (const n of nodes) {
|
|
112
|
+
if (n.isExternal || n.isTest)
|
|
113
|
+
continue;
|
|
114
|
+
const name = n.className ? `${n.className}.${n.name}` : n.name;
|
|
115
|
+
add({ name, kind: n.className ? 'method' : 'function', file: n.filePath, line: n.startLine ?? 0 });
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
else {
|
|
119
|
+
// Default: only the package entry point's exports (resolved), TS/JS.
|
|
120
|
+
const filesWithExports = new Set(exportsByFile.keys());
|
|
121
|
+
for (const entryFile of entryFiles) {
|
|
122
|
+
for (const e of exportsByFile.get(entryFile) ?? []) {
|
|
123
|
+
if (e.isType)
|
|
124
|
+
continue;
|
|
125
|
+
const resolved = resolveExport(e, entryFile, exportsByFile, lookup);
|
|
126
|
+
add(resolved);
|
|
127
|
+
if (resolved.kind === 'class')
|
|
128
|
+
addPublicMethods(resolved.name, resolved.file);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
// Fallback for languages/files without export info: top-level non-underscore
|
|
132
|
+
// free functions (covers Python etc. conservatively).
|
|
133
|
+
for (const n of nodes) {
|
|
134
|
+
if (n.isExternal || n.isTest || n.className)
|
|
135
|
+
continue;
|
|
136
|
+
if (filesWithExports.has(n.filePath))
|
|
137
|
+
continue;
|
|
138
|
+
if (isPublicName(n.name))
|
|
139
|
+
add({ name: n.name, kind: 'function', file: n.filePath, line: n.startLine ?? 0 });
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
return [...byKey.values()].sort((a, b) => a.file.localeCompare(b.file) || a.line - b.line || a.name.localeCompare(b.name));
|
|
143
|
+
}
|
|
144
|
+
//# sourceMappingURL=public-symbols.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"public-symbols.js","sourceRoot":"","sources":["../../../../src/cli/manifest/detect/public-symbols.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `openlore manifest emit` — write `.well-known/openlore.json`.
|
|
3
|
+
*
|
|
4
|
+
* A pure file-emission feature: it reads the analysis artifacts OpenLore has
|
|
5
|
+
* already produced plus local git state, and writes a small, public,
|
|
6
|
+
* deterministic self-description. No network, no graph-schema changes.
|
|
7
|
+
*
|
|
8
|
+
* Determinism: `generated_at` is the HEAD commit date (not wall-clock), and all
|
|
9
|
+
* arrays are sorted, so re-emitting on the same graph + commit is byte-stable.
|
|
10
|
+
*/
|
|
11
|
+
import type { SerializedCallGraph } from '../../core/analyzer/call-graph.js';
|
|
12
|
+
import { type ExportEntry, type PublicSymbol } from './detect/public-symbols.js';
|
|
13
|
+
import { type ManifestRoute, type RouteInventoryEntry } from './detect/http-routes.js';
|
|
14
|
+
import { type ManifestEvent, type ManifestConsumedEvent, type ManifestRpcEndpoint } from './detect/events.js';
|
|
15
|
+
export declare const MANIFEST_VERSION = 1;
|
|
16
|
+
export interface ManifestEmitOptions {
|
|
17
|
+
out?: string;
|
|
18
|
+
projectRoot?: string;
|
|
19
|
+
includePrivate?: boolean;
|
|
20
|
+
maxSymbols?: number;
|
|
21
|
+
}
|
|
22
|
+
export interface Manifest {
|
|
23
|
+
$schema: string;
|
|
24
|
+
openlore_manifest_version: number;
|
|
25
|
+
generated_at: string;
|
|
26
|
+
generator: {
|
|
27
|
+
name: string;
|
|
28
|
+
version: string;
|
|
29
|
+
};
|
|
30
|
+
repo: {
|
|
31
|
+
name: string;
|
|
32
|
+
git_remote: string | null;
|
|
33
|
+
git_commit: string | null;
|
|
34
|
+
default_branch: string | null;
|
|
35
|
+
};
|
|
36
|
+
languages: Array<{
|
|
37
|
+
name: string;
|
|
38
|
+
files: number;
|
|
39
|
+
functions: number;
|
|
40
|
+
}>;
|
|
41
|
+
stats: {
|
|
42
|
+
functions: number;
|
|
43
|
+
files: number;
|
|
44
|
+
modules: number;
|
|
45
|
+
avg_mccabe: number;
|
|
46
|
+
clusters: number;
|
|
47
|
+
};
|
|
48
|
+
exports: {
|
|
49
|
+
truncated?: boolean;
|
|
50
|
+
public_symbols: PublicSymbol[];
|
|
51
|
+
http_routes: ManifestRoute[];
|
|
52
|
+
rpc_endpoints: ManifestRpcEndpoint[];
|
|
53
|
+
events_emitted: ManifestEvent[];
|
|
54
|
+
events_consumed: ManifestConsumedEvent[];
|
|
55
|
+
};
|
|
56
|
+
imports: {
|
|
57
|
+
external_packages: Array<{
|
|
58
|
+
name: string;
|
|
59
|
+
version_range: string | null;
|
|
60
|
+
}>;
|
|
61
|
+
};
|
|
62
|
+
specs: {
|
|
63
|
+
count: number;
|
|
64
|
+
drift_state: 'clean' | 'drifted' | 'unverified';
|
|
65
|
+
};
|
|
66
|
+
links: {
|
|
67
|
+
repo: string | null;
|
|
68
|
+
docs: string | null;
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
interface PackageJson {
|
|
72
|
+
name?: string;
|
|
73
|
+
version?: string;
|
|
74
|
+
main?: string;
|
|
75
|
+
module?: string;
|
|
76
|
+
dependencies?: Record<string, string>;
|
|
77
|
+
peerDependencies?: Record<string, string>;
|
|
78
|
+
exports?: unknown;
|
|
79
|
+
}
|
|
80
|
+
declare function readPackageJson(projectRoot: string): PackageJson | null;
|
|
81
|
+
export interface ManifestInputs {
|
|
82
|
+
projectRoot: string;
|
|
83
|
+
graph: SerializedCallGraph;
|
|
84
|
+
exportsByFile: Map<string, ExportEntry[]>;
|
|
85
|
+
routes: RouteInventoryEntry[];
|
|
86
|
+
pkg: ReturnType<typeof readPackageJson>;
|
|
87
|
+
specCount: number;
|
|
88
|
+
git: {
|
|
89
|
+
remote: string | null;
|
|
90
|
+
commit: string | null;
|
|
91
|
+
defaultBranch: string | null;
|
|
92
|
+
committedAt: string | null;
|
|
93
|
+
};
|
|
94
|
+
toolVersion: string;
|
|
95
|
+
hasDocs: boolean;
|
|
96
|
+
}
|
|
97
|
+
/** Build the manifest object (pure — all I/O is done by the caller). */
|
|
98
|
+
export declare function buildManifest(inputs: ManifestInputs, opts: ManifestEmitOptions): Manifest;
|
|
99
|
+
/** Serialize a manifest to the exact bytes written to disk. */
|
|
100
|
+
export declare function serializeManifest(manifest: Manifest): string;
|
|
101
|
+
export declare function runManifestEmit(opts: ManifestEmitOptions): Promise<number>;
|
|
102
|
+
export {};
|
|
103
|
+
//# sourceMappingURL=emit.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"emit.d.ts","sourceRoot":"","sources":["../../../src/cli/manifest/emit.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,272 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `openlore manifest emit` — write `.well-known/openlore.json`.
|
|
3
|
+
*
|
|
4
|
+
* A pure file-emission feature: it reads the analysis artifacts OpenLore has
|
|
5
|
+
* already produced plus local git state, and writes a small, public,
|
|
6
|
+
* deterministic self-description. No network, no graph-schema changes.
|
|
7
|
+
*
|
|
8
|
+
* Determinism: `generated_at` is the HEAD commit date (not wall-clock), and all
|
|
9
|
+
* arrays are sorted, so re-emitting on the same graph + commit is byte-stable.
|
|
10
|
+
*/
|
|
11
|
+
import { execFileSync } from 'node:child_process';
|
|
12
|
+
import { existsSync, readFileSync } from 'node:fs';
|
|
13
|
+
import { mkdir, writeFile } from 'node:fs/promises';
|
|
14
|
+
import { basename, dirname, join, resolve } from 'node:path';
|
|
15
|
+
import { createRequire } from 'node:module';
|
|
16
|
+
import { logger } from '../../utils/logger.js';
|
|
17
|
+
import { readCachedContext } from '../../core/services/mcp-handlers/utils.js';
|
|
18
|
+
import { OPENLORE_DIR, OPENLORE_ANALYSIS_SUBDIR, ARTIFACT_DEPENDENCY_GRAPH, ARTIFACT_ROUTE_INVENTORY, } from '../../constants.js';
|
|
19
|
+
import { derivePublicSymbols } from './detect/public-symbols.js';
|
|
20
|
+
import { deriveHttpRoutes } from './detect/http-routes.js';
|
|
21
|
+
import { deriveEventsEmitted, deriveEventsConsumed, deriveRpcEndpoints, } from './detect/events.js';
|
|
22
|
+
export const MANIFEST_VERSION = 1;
|
|
23
|
+
const SCHEMA_URL = 'https://raw.githubusercontent.com/clay-good/OpenLore/main/schemas/openlore-manifest-v1.json';
|
|
24
|
+
const require = createRequire(import.meta.url);
|
|
25
|
+
// ── git helpers (all best-effort; never throw) ─────────────────────────────
|
|
26
|
+
function git(cwd, args) {
|
|
27
|
+
try {
|
|
28
|
+
return execFileSync('git', args, { cwd, encoding: 'utf-8', stdio: ['ignore', 'pipe', 'ignore'] }).trim() || null;
|
|
29
|
+
}
|
|
30
|
+
catch {
|
|
31
|
+
return null;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
/** Convert a git remote (ssh or https) to a browseable https URL, sans `.git`. */
|
|
35
|
+
function normalizeRemoteToWebUrl(remote) {
|
|
36
|
+
if (!remote)
|
|
37
|
+
return null;
|
|
38
|
+
let url = remote.trim().replace(/\.git$/, '');
|
|
39
|
+
const ssh = url.match(/^git@([^:]+):(.+)$/);
|
|
40
|
+
if (ssh)
|
|
41
|
+
url = `https://${ssh[1]}/${ssh[2]}`;
|
|
42
|
+
url = url.replace(/^ssh:\/\/git@/, 'https://');
|
|
43
|
+
return url;
|
|
44
|
+
}
|
|
45
|
+
function detectDefaultBranch(cwd) {
|
|
46
|
+
const originHead = git(cwd, ['symbolic-ref', '--short', 'refs/remotes/origin/HEAD']);
|
|
47
|
+
if (originHead)
|
|
48
|
+
return originHead.replace(/^origin\//, '');
|
|
49
|
+
for (const candidate of ['main', 'master']) {
|
|
50
|
+
if (git(cwd, ['rev-parse', '--verify', '--quiet', candidate]) !== null)
|
|
51
|
+
return candidate;
|
|
52
|
+
}
|
|
53
|
+
return git(cwd, ['rev-parse', '--abbrev-ref', 'HEAD']);
|
|
54
|
+
}
|
|
55
|
+
/** repo-relative file path → its top-level exports (from dependency-graph.json). */
|
|
56
|
+
function loadExportsByFile(analysisDir) {
|
|
57
|
+
const map = new Map();
|
|
58
|
+
const file = join(analysisDir, ARTIFACT_DEPENDENCY_GRAPH);
|
|
59
|
+
if (!existsSync(file))
|
|
60
|
+
return map;
|
|
61
|
+
try {
|
|
62
|
+
const data = JSON.parse(readFileSync(file, 'utf-8'));
|
|
63
|
+
for (const node of data.nodes ?? []) {
|
|
64
|
+
const path = node.file?.path;
|
|
65
|
+
if (path && Array.isArray(node.exports))
|
|
66
|
+
map.set(path, node.exports);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
catch {
|
|
70
|
+
// tolerate a malformed/partial artifact — emit what we can
|
|
71
|
+
}
|
|
72
|
+
return map;
|
|
73
|
+
}
|
|
74
|
+
function loadRoutes(analysisDir) {
|
|
75
|
+
const file = join(analysisDir, ARTIFACT_ROUTE_INVENTORY);
|
|
76
|
+
if (!existsSync(file))
|
|
77
|
+
return [];
|
|
78
|
+
try {
|
|
79
|
+
const data = JSON.parse(readFileSync(file, 'utf-8'));
|
|
80
|
+
return data.routes ?? [];
|
|
81
|
+
}
|
|
82
|
+
catch {
|
|
83
|
+
return [];
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
function countSpecs(projectRoot) {
|
|
87
|
+
try {
|
|
88
|
+
// glob is already a dependency; use sync matching against openspec/specs.
|
|
89
|
+
const specsDir = join(projectRoot, 'openspec', 'specs');
|
|
90
|
+
if (!existsSync(specsDir))
|
|
91
|
+
return 0;
|
|
92
|
+
const { globSync } = require('glob');
|
|
93
|
+
return globSync('*/spec.md', { cwd: specsDir }).length;
|
|
94
|
+
}
|
|
95
|
+
catch {
|
|
96
|
+
return 0;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Map package entry points (dist build outputs) back to their TS/JS source
|
|
101
|
+
* files, restricted to those the dependency graph actually knows about. These
|
|
102
|
+
* define the default "public" surface.
|
|
103
|
+
*/
|
|
104
|
+
function entrySourceFiles(pkg, exportsByFile) {
|
|
105
|
+
if (!pkg)
|
|
106
|
+
return [];
|
|
107
|
+
const dist = [];
|
|
108
|
+
if (typeof pkg.main === 'string')
|
|
109
|
+
dist.push(pkg.main);
|
|
110
|
+
if (typeof pkg.module === 'string')
|
|
111
|
+
dist.push(pkg.module);
|
|
112
|
+
const collect = (node) => {
|
|
113
|
+
if (typeof node === 'string')
|
|
114
|
+
dist.push(node);
|
|
115
|
+
else if (node && typeof node === 'object')
|
|
116
|
+
for (const v of Object.values(node))
|
|
117
|
+
collect(v);
|
|
118
|
+
};
|
|
119
|
+
collect(pkg.exports);
|
|
120
|
+
const toSrc = (p) => p.replace(/^\.\//, '').replace(/^dist\//, 'src/').replace(/\.(js|d\.ts)$/, '.ts');
|
|
121
|
+
const candidates = new Set(dist.map(toSrc));
|
|
122
|
+
return [...candidates].filter(f => exportsByFile.has(f)).sort();
|
|
123
|
+
}
|
|
124
|
+
function readPackageJson(projectRoot) {
|
|
125
|
+
const path = join(projectRoot, 'package.json');
|
|
126
|
+
if (!existsSync(path))
|
|
127
|
+
return null;
|
|
128
|
+
try {
|
|
129
|
+
return JSON.parse(readFileSync(path, 'utf-8'));
|
|
130
|
+
}
|
|
131
|
+
catch {
|
|
132
|
+
return null;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
function toolVersion() {
|
|
136
|
+
return require('../../../package.json').version;
|
|
137
|
+
}
|
|
138
|
+
// ── stats / languages ────────────────────────────────────────────────────────
|
|
139
|
+
function computeStats(graph) {
|
|
140
|
+
const real = graph.nodes.filter(n => !n.isExternal);
|
|
141
|
+
const files = new Set(real.map(n => n.filePath));
|
|
142
|
+
const clusters = new Set(real.map(n => n.communityId).filter((c) => !!c));
|
|
143
|
+
const mccabe = real.map(n => n.cyclomaticComplexity).filter((c) => typeof c === 'number');
|
|
144
|
+
const avg = mccabe.length ? mccabe.reduce((a, b) => a + b, 0) / mccabe.length : 0;
|
|
145
|
+
return {
|
|
146
|
+
functions: real.length,
|
|
147
|
+
files: files.size,
|
|
148
|
+
modules: graph.classes.length,
|
|
149
|
+
avg_mccabe: Math.round(avg * 10) / 10,
|
|
150
|
+
clusters: clusters.size,
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
function computeLanguages(nodes) {
|
|
154
|
+
const byLang = new Map();
|
|
155
|
+
for (const n of nodes) {
|
|
156
|
+
if (n.isExternal)
|
|
157
|
+
continue;
|
|
158
|
+
const lang = n.language.toLowerCase();
|
|
159
|
+
let entry = byLang.get(lang);
|
|
160
|
+
if (!entry) {
|
|
161
|
+
entry = { files: new Set(), functions: 0 };
|
|
162
|
+
byLang.set(lang, entry);
|
|
163
|
+
}
|
|
164
|
+
entry.files.add(n.filePath);
|
|
165
|
+
entry.functions++;
|
|
166
|
+
}
|
|
167
|
+
return [...byLang.entries()]
|
|
168
|
+
.map(([name, v]) => ({ name, files: v.files.size, functions: v.functions }))
|
|
169
|
+
.sort((a, b) => a.name.localeCompare(b.name));
|
|
170
|
+
}
|
|
171
|
+
// ── external packages ─────────────────────────────────────────────────────────
|
|
172
|
+
// TODO(spec-05-followup): first_use requires persisted per-file import sources
|
|
173
|
+
// from the analyzer (not currently surfaced), so it is omitted here.
|
|
174
|
+
function deriveExternalPackages(pkg) {
|
|
175
|
+
if (!pkg)
|
|
176
|
+
return [];
|
|
177
|
+
const deps = { ...(pkg.dependencies ?? {}), ...(pkg.peerDependencies ?? {}) };
|
|
178
|
+
return Object.entries(deps)
|
|
179
|
+
.map(([name, version_range]) => ({ name, version_range: version_range ?? null }))
|
|
180
|
+
.sort((a, b) => a.name.localeCompare(b.name));
|
|
181
|
+
}
|
|
182
|
+
/** Build the manifest object (pure — all I/O is done by the caller). */
|
|
183
|
+
export function buildManifest(inputs, opts) {
|
|
184
|
+
const repoWebUrl = normalizeRemoteToWebUrl(inputs.git.remote);
|
|
185
|
+
const repoName = inputs.pkg?.name ??
|
|
186
|
+
(repoWebUrl ? basename(repoWebUrl) : basename(inputs.projectRoot));
|
|
187
|
+
let publicSymbols = derivePublicSymbols({
|
|
188
|
+
nodes: inputs.graph.nodes,
|
|
189
|
+
classes: inputs.graph.classes,
|
|
190
|
+
exportsByFile: inputs.exportsByFile,
|
|
191
|
+
entryFiles: entrySourceFiles(inputs.pkg, inputs.exportsByFile),
|
|
192
|
+
includePrivate: opts.includePrivate ?? false,
|
|
193
|
+
});
|
|
194
|
+
let truncated = false;
|
|
195
|
+
if (typeof opts.maxSymbols === 'number' && publicSymbols.length > opts.maxSymbols) {
|
|
196
|
+
publicSymbols = publicSymbols.slice(0, opts.maxSymbols);
|
|
197
|
+
truncated = true;
|
|
198
|
+
}
|
|
199
|
+
return {
|
|
200
|
+
$schema: SCHEMA_URL,
|
|
201
|
+
openlore_manifest_version: MANIFEST_VERSION,
|
|
202
|
+
// Commit date keeps the manifest byte-stable per commit; fall back to epoch
|
|
203
|
+
// when git is unavailable (still deterministic, never wall-clock).
|
|
204
|
+
generated_at: inputs.git.committedAt ?? '1970-01-01T00:00:00Z',
|
|
205
|
+
generator: { name: 'openlore', version: inputs.toolVersion },
|
|
206
|
+
repo: {
|
|
207
|
+
name: repoName,
|
|
208
|
+
git_remote: inputs.git.remote,
|
|
209
|
+
git_commit: inputs.git.commit,
|
|
210
|
+
default_branch: inputs.git.defaultBranch,
|
|
211
|
+
},
|
|
212
|
+
languages: computeLanguages(inputs.graph.nodes),
|
|
213
|
+
stats: computeStats(inputs.graph),
|
|
214
|
+
exports: {
|
|
215
|
+
...(truncated ? { truncated: true } : {}),
|
|
216
|
+
public_symbols: publicSymbols,
|
|
217
|
+
http_routes: deriveHttpRoutes(inputs.routes),
|
|
218
|
+
rpc_endpoints: deriveRpcEndpoints(),
|
|
219
|
+
events_emitted: deriveEventsEmitted(),
|
|
220
|
+
events_consumed: deriveEventsConsumed(),
|
|
221
|
+
},
|
|
222
|
+
imports: { external_packages: deriveExternalPackages(inputs.pkg) },
|
|
223
|
+
specs: { count: inputs.specCount, drift_state: 'unverified' },
|
|
224
|
+
links: {
|
|
225
|
+
repo: repoWebUrl,
|
|
226
|
+
docs: inputs.hasDocs && repoWebUrl ? `${repoWebUrl}/tree/${inputs.git.defaultBranch ?? 'main'}/docs` : null,
|
|
227
|
+
},
|
|
228
|
+
};
|
|
229
|
+
}
|
|
230
|
+
/** Serialize a manifest to the exact bytes written to disk. */
|
|
231
|
+
export function serializeManifest(manifest) {
|
|
232
|
+
return JSON.stringify(manifest, null, 2) + '\n';
|
|
233
|
+
}
|
|
234
|
+
export async function runManifestEmit(opts) {
|
|
235
|
+
const projectRoot = resolve(opts.projectRoot ?? process.cwd());
|
|
236
|
+
const analysisDir = join(projectRoot, OPENLORE_DIR, OPENLORE_ANALYSIS_SUBDIR);
|
|
237
|
+
const ctx = await readCachedContext(projectRoot);
|
|
238
|
+
const graph = ctx?.callGraph;
|
|
239
|
+
if (!graph || graph.nodes.length === 0) {
|
|
240
|
+
logger.error('No analysis graph found. Run `openlore analyze` first.');
|
|
241
|
+
return 2;
|
|
242
|
+
}
|
|
243
|
+
const manifest = buildManifest({
|
|
244
|
+
projectRoot,
|
|
245
|
+
graph,
|
|
246
|
+
exportsByFile: loadExportsByFile(analysisDir),
|
|
247
|
+
routes: loadRoutes(analysisDir),
|
|
248
|
+
pkg: readPackageJson(projectRoot),
|
|
249
|
+
specCount: countSpecs(projectRoot),
|
|
250
|
+
git: {
|
|
251
|
+
remote: git(projectRoot, ['config', '--get', 'remote.origin.url']),
|
|
252
|
+
commit: git(projectRoot, ['rev-parse', '--short', 'HEAD']),
|
|
253
|
+
defaultBranch: detectDefaultBranch(projectRoot),
|
|
254
|
+
committedAt: git(projectRoot, ['show', '-s', '--format=%cI', 'HEAD']),
|
|
255
|
+
},
|
|
256
|
+
toolVersion: toolVersion(),
|
|
257
|
+
hasDocs: existsSync(join(projectRoot, 'docs')),
|
|
258
|
+
}, opts);
|
|
259
|
+
const outPath = resolve(opts.out ?? join(projectRoot, '.well-known', 'openlore.json'));
|
|
260
|
+
await mkdir(dirname(outPath), { recursive: true });
|
|
261
|
+
const bytes = serializeManifest(manifest);
|
|
262
|
+
await writeFile(outPath, bytes);
|
|
263
|
+
logger.success(`Wrote ${outPath} (${Buffer.byteLength(bytes)} bytes)`);
|
|
264
|
+
logger.info('public symbols', manifest.exports.public_symbols.length + (manifest.exports.truncated ? ' (truncated)' : ''));
|
|
265
|
+
logger.info('http routes', manifest.exports.http_routes.length);
|
|
266
|
+
logger.info('external packages', manifest.imports.external_packages.length);
|
|
267
|
+
if (manifest.exports.events_emitted.length === 0 && manifest.exports.rpc_endpoints.length === 0) {
|
|
268
|
+
logger.info('events / rpc', 'none detected (analyzer does not surface these yet)');
|
|
269
|
+
}
|
|
270
|
+
return 0;
|
|
271
|
+
}
|
|
272
|
+
//# sourceMappingURL=emit.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"emit.js","sourceRoot":"","sources":["../../../src/cli/manifest/emit.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `openlore manifest <emit|validate>` — federation manifest emitter.
|
|
3
|
+
*
|
|
4
|
+
* Each OpenLore-instrumented repo can publish a small, public, deterministic
|
|
5
|
+
* `.well-known/openlore.json` describing what it exposes. A future federation
|
|
6
|
+
* index (separate spec) reads these manifests to answer cross-repo questions.
|
|
7
|
+
* This command only emits and validates; it never makes network calls.
|
|
8
|
+
*/
|
|
9
|
+
import { Command } from 'commander';
|
|
10
|
+
export declare const manifestCommand: Command;
|
|
11
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/cli/manifest/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAqBpC,eAAO,MAAM,eAAe,SAGK,CAAC"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `openlore manifest <emit|validate>` — federation manifest emitter.
|
|
3
|
+
*
|
|
4
|
+
* Each OpenLore-instrumented repo can publish a small, public, deterministic
|
|
5
|
+
* `.well-known/openlore.json` describing what it exposes. A future federation
|
|
6
|
+
* index (separate spec) reads these manifests to answer cross-repo questions.
|
|
7
|
+
* This command only emits and validates; it never makes network calls.
|
|
8
|
+
*/
|
|
9
|
+
import { Command } from 'commander';
|
|
10
|
+
import { runManifestEmit } from './emit.js';
|
|
11
|
+
import { runManifestValidate } from './validate.js';
|
|
12
|
+
const emitSubcommand = new Command('emit')
|
|
13
|
+
.description('Write .well-known/openlore.json describing this repo (public symbols, routes, stats, …).')
|
|
14
|
+
.option('--out <path>', 'Output path (default: <project-root>/.well-known/openlore.json)')
|
|
15
|
+
.option('--project-root <path>', 'Project root to describe (default: current directory)')
|
|
16
|
+
.option('--include-private', 'Include non-public symbols (produces a larger manifest)', false)
|
|
17
|
+
.option('--max-symbols <int>', 'Truncate public_symbols to this many (sets "truncated": true)', (v) => parseInt(v, 10))
|
|
18
|
+
.action(async (opts) => {
|
|
19
|
+
process.exit(await runManifestEmit(opts));
|
|
20
|
+
});
|
|
21
|
+
const validateSubcommand = new Command('validate')
|
|
22
|
+
.description('Schema-check an existing manifest against openlore-manifest-v1.json.')
|
|
23
|
+
.argument('<path>', 'Path to the manifest JSON to validate')
|
|
24
|
+
.action((path) => {
|
|
25
|
+
process.exit(runManifestValidate(path));
|
|
26
|
+
});
|
|
27
|
+
export const manifestCommand = new Command('manifest')
|
|
28
|
+
.description('Emit or validate a federation manifest (.well-known/openlore.json).')
|
|
29
|
+
.addCommand(emitSubcommand)
|
|
30
|
+
.addCommand(validateSubcommand);
|
|
31
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/cli/manifest/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,eAAe,EAA4B,MAAM,WAAW,CAAC;AACtE,OAAO,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AAEpD,MAAM,cAAc,GAAG,IAAI,OAAO,CAAC,MAAM,CAAC;KACvC,WAAW,CAAC,0FAA0F,CAAC;KACvG,MAAM,CAAC,cAAc,EAAE,iEAAiE,CAAC;KACzF,MAAM,CAAC,uBAAuB,EAAE,uDAAuD,CAAC;KACxF,MAAM,CAAC,mBAAmB,EAAE,yDAAyD,EAAE,KAAK,CAAC;KAC7F,MAAM,CAAC,qBAAqB,EAAE,+DAA+D,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,QAAQ,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;KACtH,MAAM,CAAC,KAAK,EAAE,IAAyB,EAAE,EAAE;IAC1C,OAAO,CAAC,IAAI,CAAC,MAAM,eAAe,CAAC,IAAI,CAAC,CAAC,CAAC;AAC5C,CAAC,CAAC,CAAC;AAEL,MAAM,kBAAkB,GAAG,IAAI,OAAO,CAAC,UAAU,CAAC;KAC/C,WAAW,CAAC,sEAAsE,CAAC;KACnF,QAAQ,CAAC,QAAQ,EAAE,uCAAuC,CAAC;KAC3D,MAAM,CAAC,CAAC,IAAY,EAAE,EAAE;IACvB,OAAO,CAAC,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,CAAC,CAAC;AAC1C,CAAC,CAAC,CAAC;AAEL,MAAM,CAAC,MAAM,eAAe,GAAG,IAAI,OAAO,CAAC,UAAU,CAAC;KACnD,WAAW,CAAC,qEAAqE,CAAC;KAClF,UAAU,CAAC,cAAc,CAAC;KAC1B,UAAU,CAAC,kBAAkB,CAAC,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A deliberately tiny JSON Schema validator — just the subset used by
|
|
3
|
+
* schemas/openlore-manifest-v1.json. Avoids pulling in Ajv (a large dep) for a
|
|
4
|
+
* single internal schema, per spec-05's acceptance criteria.
|
|
5
|
+
*
|
|
6
|
+
* Supported keywords: type (string or array incl. "null"), const, enum,
|
|
7
|
+
* required, properties, additionalProperties (false only), items. The
|
|
8
|
+
* `integer` type is distinguished from `number`.
|
|
9
|
+
*/
|
|
10
|
+
export interface ValidationError {
|
|
11
|
+
path: string;
|
|
12
|
+
message: string;
|
|
13
|
+
}
|
|
14
|
+
type JsonSchema = Record<string, unknown>;
|
|
15
|
+
/** Validate a parsed JSON value against a parsed JSON Schema. */
|
|
16
|
+
export declare function validateAgainstSchema(value: unknown, schema: JsonSchema): ValidationError[];
|
|
17
|
+
export {};
|
|
18
|
+
//# sourceMappingURL=schema-validator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema-validator.d.ts","sourceRoot":"","sources":["../../../src/cli/manifest/schema-validator.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,KAAK,UAAU,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAoE1C,iEAAiE;AACjE,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,UAAU,GAAG,eAAe,EAAE,CAI3F"}
|