@tikoci/rosetta 0.6.7 → 0.6.9
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 +2 -0
- package/package.json +1 -1
- package/src/browse.ts +211 -21
- package/src/db.ts +113 -0
- package/src/extract-all-versions.ts +83 -21
- package/src/extract-schema.ts +596 -0
- package/src/extract-skills.ts +390 -0
- package/src/mcp.ts +107 -8
- package/src/paths.ts +9 -2
- package/src/query.test.ts +128 -1
- package/src/query.ts +157 -9
- package/src/release.test.ts +29 -0
- package/src/schema-roundtrip.test.ts +373 -0
|
@@ -2,10 +2,14 @@
|
|
|
2
2
|
/**
|
|
3
3
|
* extract-all-versions.ts — Extract command trees from all RouterOS versions.
|
|
4
4
|
*
|
|
5
|
-
* Discovers RouterOS versions from restraml and extracts each
|
|
6
|
-
*
|
|
5
|
+
* Discovers RouterOS versions from restraml and extracts each version's
|
|
6
|
+
* command tree into schema_nodes/command_versions.
|
|
7
7
|
*
|
|
8
|
-
*
|
|
8
|
+
* Prefers deep-inspect.{x86,arm64}.json (multi-arch, completion data) when
|
|
9
|
+
* available; falls back to inspect.json (legacy) for older versions.
|
|
10
|
+
*
|
|
11
|
+
* The latest stable version is loaded as the primary (rebuilds schema_nodes
|
|
12
|
+
* and commands tables). All other versions only add to the junction tables.
|
|
9
13
|
*
|
|
10
14
|
* Usage:
|
|
11
15
|
* bun run src/extract-all-versions.ts [restraml-base-url-or-local-docs-dir]
|
|
@@ -20,8 +24,15 @@ const SOURCE = process.argv[2];
|
|
|
20
24
|
interface VersionInfo {
|
|
21
25
|
version: string;
|
|
22
26
|
channel: "stable" | "development";
|
|
27
|
+
/** deep-inspect.x86.json path/URL (null if not available) */
|
|
28
|
+
deepX86: string | null;
|
|
29
|
+
/** deep-inspect.arm64.json path/URL (null if not available) */
|
|
30
|
+
deepArm64: string | null;
|
|
31
|
+
/** Legacy inspect.json path/URL (fallback when no deep-inspect) */
|
|
23
32
|
inspectPath: string;
|
|
24
33
|
hasExtra: boolean;
|
|
34
|
+
/** true when at least one deep-inspect file is available */
|
|
35
|
+
hasDeepInspect: boolean;
|
|
25
36
|
}
|
|
26
37
|
|
|
27
38
|
function classifyChannel(version: string): "stable" | "development" {
|
|
@@ -55,18 +66,36 @@ async function discoverRemoteVersions(): Promise<VersionInfo[]> {
|
|
|
55
66
|
const versionNames = await discoverRemoteVersionList();
|
|
56
67
|
const baseUrl = RESTRAML_PAGES_URL;
|
|
57
68
|
|
|
58
|
-
//
|
|
59
|
-
//
|
|
60
|
-
//
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
69
|
+
// For each version, check if deep-inspect files exist (HEAD probe).
|
|
70
|
+
// Deep-inspect files are at: <baseUrl>/<version>/extra/deep-inspect.{x86,arm64}.json
|
|
71
|
+
// Fall back to: <baseUrl>/<version>/extra/inspect.json
|
|
72
|
+
const results: VersionInfo[] = [];
|
|
73
|
+
|
|
74
|
+
for (const name of versionNames.filter((n) => /^\d+\.\d+/.test(n))) {
|
|
75
|
+
const x86Url = `${baseUrl}/${name}/extra/deep-inspect.x86.json`;
|
|
76
|
+
const arm64Url = `${baseUrl}/${name}/extra/deep-inspect.arm64.json`;
|
|
77
|
+
const inspectUrl = `${baseUrl}/${name}/extra/inspect.json`;
|
|
78
|
+
|
|
79
|
+
// Probe deep-inspect availability via HEAD request (fast, no body)
|
|
80
|
+
const [x86Ok, arm64Ok] = await Promise.all([
|
|
81
|
+
fetch(x86Url, { method: "HEAD" }).then((r) => r.ok).catch(() => false),
|
|
82
|
+
fetch(arm64Url, { method: "HEAD" }).then((r) => r.ok).catch(() => false),
|
|
83
|
+
]);
|
|
84
|
+
|
|
85
|
+
const hasDeepInspect = x86Ok || arm64Ok;
|
|
86
|
+
|
|
87
|
+
results.push({
|
|
64
88
|
version: name,
|
|
65
89
|
channel: classifyChannel(name),
|
|
66
|
-
|
|
90
|
+
deepX86: x86Ok ? x86Url : null,
|
|
91
|
+
deepArm64: arm64Ok ? arm64Url : null,
|
|
92
|
+
inspectPath: inspectUrl,
|
|
67
93
|
hasExtra: true,
|
|
68
|
-
|
|
69
|
-
|
|
94
|
+
hasDeepInspect,
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
return results.sort((a, b) => compareVersions(a.version, b.version));
|
|
70
99
|
}
|
|
71
100
|
|
|
72
101
|
function discoverLocalVersions(docsDir: string): VersionInfo[] {
|
|
@@ -74,18 +103,26 @@ function discoverLocalVersions(docsDir: string): VersionInfo[] {
|
|
|
74
103
|
return entries
|
|
75
104
|
.map((name) => {
|
|
76
105
|
const dir = resolve(docsDir, name);
|
|
106
|
+
const deepX86Path = resolve(dir, "extra/deep-inspect.x86.json");
|
|
107
|
+
const deepArm64Path = resolve(dir, "extra/deep-inspect.arm64.json");
|
|
77
108
|
const extraPath = resolve(dir, "extra/inspect.json");
|
|
78
109
|
const basePath = resolve(dir, "inspect.json");
|
|
79
110
|
const hasExtra = existsSync(extraPath);
|
|
80
111
|
const inspectPath = hasExtra ? extraPath : basePath;
|
|
112
|
+
const deepX86 = existsSync(deepX86Path) ? deepX86Path : null;
|
|
113
|
+
const deepArm64 = existsSync(deepArm64Path) ? deepArm64Path : null;
|
|
114
|
+
const hasDeepInspect = deepX86 !== null || deepArm64 !== null;
|
|
81
115
|
|
|
82
|
-
if (!existsSync(inspectPath)) return null;
|
|
116
|
+
if (!existsSync(inspectPath) && !hasDeepInspect) return null;
|
|
83
117
|
|
|
84
118
|
return {
|
|
85
119
|
version: name,
|
|
86
120
|
channel: classifyChannel(name),
|
|
121
|
+
deepX86,
|
|
122
|
+
deepArm64,
|
|
87
123
|
inspectPath,
|
|
88
124
|
hasExtra,
|
|
125
|
+
hasDeepInspect,
|
|
89
126
|
};
|
|
90
127
|
})
|
|
91
128
|
.filter((v): v is VersionInfo => v !== null)
|
|
@@ -112,10 +149,16 @@ const latest = latestStable || versions[versions.length - 1];
|
|
|
112
149
|
console.log(`Latest stable: ${latest?.version ?? "none"}`);
|
|
113
150
|
|
|
114
151
|
// Run extraction for each version
|
|
115
|
-
//
|
|
116
|
-
//
|
|
152
|
+
// For versions with deep-inspect: use extract-schema.ts (multi-arch, completion data)
|
|
153
|
+
// For versions without: fall back to extract-commands.ts (legacy)
|
|
154
|
+
// Primary version (latest stable) rebuilds the main tables; others accumulate only.
|
|
117
155
|
|
|
118
|
-
const
|
|
156
|
+
const extractSchemaCmd = resolve(import.meta.dir, "extract-schema.ts");
|
|
157
|
+
const extractCommandsCmd = resolve(import.meta.dir, "extract-commands.ts");
|
|
158
|
+
|
|
159
|
+
const deepCount = versions.filter((v) => v.hasDeepInspect).length;
|
|
160
|
+
const legacyCount = versions.length - deepCount;
|
|
161
|
+
console.log(`Deep-inspect versions: ${deepCount}, legacy inspect.json: ${legacyCount}`);
|
|
119
162
|
|
|
120
163
|
let extracted = 0;
|
|
121
164
|
for (const v of versions) {
|
|
@@ -128,12 +171,31 @@ for (const v of versions) {
|
|
|
128
171
|
];
|
|
129
172
|
|
|
130
173
|
console.log(`\n${"=".repeat(60)}`);
|
|
131
|
-
console.log(`${isPrimary ? "PRIMARY" : "accumulate"}: ${v.version} (${v.channel})`);
|
|
132
174
|
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
175
|
+
let proc: ReturnType<typeof Bun.spawnSync>;
|
|
176
|
+
|
|
177
|
+
if (v.hasDeepInspect) {
|
|
178
|
+
// Use extract-schema.ts with both arch files
|
|
179
|
+
const schemaFlags = [
|
|
180
|
+
...(v.deepX86 ? [`--x86=${v.deepX86}`] : []),
|
|
181
|
+
...(v.deepArm64 ? [`--arm64=${v.deepArm64}`] : []),
|
|
182
|
+
...flags,
|
|
183
|
+
];
|
|
184
|
+
console.log(`${isPrimary ? "PRIMARY" : "accumulate"}: ${v.version} (${v.channel}) [deep-inspect]`);
|
|
185
|
+
|
|
186
|
+
proc = Bun.spawnSync(["bun", "run", extractSchemaCmd, ...schemaFlags], {
|
|
187
|
+
cwd: resolve(import.meta.dir, ".."),
|
|
188
|
+
stdio: ["inherit", "inherit", "inherit"],
|
|
189
|
+
});
|
|
190
|
+
} else {
|
|
191
|
+
// Legacy fallback: use extract-commands.ts
|
|
192
|
+
console.log(`${isPrimary ? "PRIMARY" : "accumulate"}: ${v.version} (${v.channel}) [legacy inspect.json]`);
|
|
193
|
+
|
|
194
|
+
proc = Bun.spawnSync(["bun", "run", extractCommandsCmd, v.inspectPath, ...flags], {
|
|
195
|
+
cwd: resolve(import.meta.dir, ".."),
|
|
196
|
+
stdio: ["inherit", "inherit", "inherit"],
|
|
197
|
+
});
|
|
198
|
+
}
|
|
137
199
|
|
|
138
200
|
if (proc.exitCode !== 0) {
|
|
139
201
|
console.error(`FAILED: ${v.version} (exit ${proc.exitCode})`);
|