@mcptoolshop/claude-synergy 1.1.1 → 1.2.0
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.es.md +25 -22
- package/README.fr.md +7 -4
- package/README.hi.md +7 -4
- package/README.it.md +27 -24
- package/README.ja.md +7 -4
- package/README.md +11 -8
- package/README.pt-BR.md +7 -4
- package/README.zh.md +29 -26
- package/dist/{chunk-H3466JDH.js → chunk-CEIOLMDT.js} +197 -885
- package/dist/{chunk-HZEQG3WT.js → chunk-KFAQPOGV.js} +21 -142
- package/dist/chunk-MTW6UZBF.js +743 -0
- package/dist/chunk-MZLFGICO.js +133 -0
- package/dist/chunk-X25ZTSCJ.js +1150 -0
- package/dist/cli.js +22 -1156
- package/dist/embed-OCOZWLXF.js +10 -0
- package/dist/fetch-XS3IETWW.js +11 -0
- package/dist/{ingest-Z45YH7OX.js → ingest-D23NTE25.js} +2 -1
- package/dist/mcp-server.js +174 -2
- package/package.json +1 -1
|
@@ -1,6 +1,10 @@
|
|
|
1
|
+
import {
|
|
2
|
+
loadProductsConfig
|
|
3
|
+
} from "./chunk-MZLFGICO.js";
|
|
4
|
+
|
|
1
5
|
// src/ingest.ts
|
|
2
|
-
import { readdirSync, readFileSync
|
|
3
|
-
import { join
|
|
6
|
+
import { readdirSync, readFileSync, statSync, existsSync } from "fs";
|
|
7
|
+
import { join, relative, basename } from "path";
|
|
4
8
|
import { createHash } from "crypto";
|
|
5
9
|
import matter from "gray-matter";
|
|
6
10
|
import TurndownService from "turndown";
|
|
@@ -71,136 +75,6 @@ function extractEntities(text) {
|
|
|
71
75
|
return found;
|
|
72
76
|
}
|
|
73
77
|
|
|
74
|
-
// src/products-config.ts
|
|
75
|
-
import { readFileSync, existsSync } from "fs";
|
|
76
|
-
import { dirname, join } from "path";
|
|
77
|
-
import { fileURLToPath } from "url";
|
|
78
|
-
import { parse as parseYaml } from "yaml";
|
|
79
|
-
var __dirname2 = dirname(fileURLToPath(import.meta.url));
|
|
80
|
-
var PRODUCT_NAME_RE = /^[a-z0-9][a-z0-9-]*$/;
|
|
81
|
-
var GH_REPO_RE = /^[A-Za-z0-9._-]+\/[A-Za-z0-9._-]+$/;
|
|
82
|
-
var warnedAboutMissingYaml = false;
|
|
83
|
-
function loadProductsConfig(yamlPath) {
|
|
84
|
-
const resolved = yamlPath ?? resolveYamlPath();
|
|
85
|
-
if (!resolved || !existsSync(resolved)) {
|
|
86
|
-
if (!warnedAboutMissingYaml) {
|
|
87
|
-
console.error(`[claude-synergy] products.yaml not found at ${resolved}; using hardcoded defaults`);
|
|
88
|
-
warnedAboutMissingYaml = true;
|
|
89
|
-
}
|
|
90
|
-
return null;
|
|
91
|
-
}
|
|
92
|
-
let raw;
|
|
93
|
-
try {
|
|
94
|
-
raw = readFileSync(resolved, "utf-8");
|
|
95
|
-
} catch (e) {
|
|
96
|
-
console.error(`[claude-synergy] could not read ${resolved}: ${e.message}; using hardcoded defaults`);
|
|
97
|
-
return null;
|
|
98
|
-
}
|
|
99
|
-
if (raw.charCodeAt(0) === 65279) raw = raw.slice(1);
|
|
100
|
-
let parsed;
|
|
101
|
-
try {
|
|
102
|
-
parsed = parseYaml(raw);
|
|
103
|
-
} catch (e) {
|
|
104
|
-
throw new Error(`[claude-synergy] products.yaml parse error: ${e.message}`);
|
|
105
|
-
}
|
|
106
|
-
if (!parsed || !Array.isArray(parsed.products)) {
|
|
107
|
-
throw new Error(`[claude-synergy] products.yaml missing required 'products' array`);
|
|
108
|
-
}
|
|
109
|
-
const productMeta = {};
|
|
110
|
-
const fetchTargets = [];
|
|
111
|
-
for (const p of parsed.products) {
|
|
112
|
-
if (!p.name || !p.display_name) {
|
|
113
|
-
throw new Error(`[claude-synergy] products.yaml entry missing name/display_name: ${JSON.stringify(p)}`);
|
|
114
|
-
}
|
|
115
|
-
if (!PRODUCT_NAME_RE.test(p.name)) {
|
|
116
|
-
throw new Error(
|
|
117
|
-
`[claude-synergy] products.yaml: invalid product name '${p.name}' \u2014 must match /^[a-z0-9][a-z0-9-]*$/ (lowercase alphanumeric + hyphens, no leading hyphen)`
|
|
118
|
-
);
|
|
119
|
-
}
|
|
120
|
-
productMeta[p.name] = {
|
|
121
|
-
name: p.name,
|
|
122
|
-
display_name: p.display_name,
|
|
123
|
-
source_tier: p.tier ?? 1,
|
|
124
|
-
source_url: p.source_url ?? "",
|
|
125
|
-
fetch_strategy: p.fetch_strategy ?? "gh-releases",
|
|
126
|
-
notes: p.notes ?? null
|
|
127
|
-
};
|
|
128
|
-
if (p.fetch) {
|
|
129
|
-
const target = buildFetchTarget(p.name, p.fetch);
|
|
130
|
-
if (target) {
|
|
131
|
-
if (target.strategy === "gh-releases" && target.repo && !GH_REPO_RE.test(target.repo)) {
|
|
132
|
-
throw new Error(
|
|
133
|
-
`[claude-synergy] products.yaml: ${p.name}: invalid repo '${target.repo}' \u2014 must match 'owner/repo' (alphanumeric + dot/underscore/hyphen)`
|
|
134
|
-
);
|
|
135
|
-
}
|
|
136
|
-
fetchTargets.push(target);
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
return { productMeta, fetchTargets };
|
|
141
|
-
}
|
|
142
|
-
function buildFetchTarget(name, fetch) {
|
|
143
|
-
if (!fetch) return null;
|
|
144
|
-
const target = { product: name, strategy: fetch.type };
|
|
145
|
-
switch (fetch.type) {
|
|
146
|
-
case "gh-releases":
|
|
147
|
-
if (!fetch.repo) throw new Error(`[claude-synergy] ${name}: gh-releases requires 'repo'`);
|
|
148
|
-
target.repo = fetch.repo;
|
|
149
|
-
if (fetch.multi_package) target.multiPackage = true;
|
|
150
|
-
break;
|
|
151
|
-
case "rss":
|
|
152
|
-
if (!fetch.url) throw new Error(`[claude-synergy] ${name}: rss requires 'url'`);
|
|
153
|
-
target.rssUrl = fetch.url;
|
|
154
|
-
if (fetch.title_filter) {
|
|
155
|
-
try {
|
|
156
|
-
target.rssTitleFilter = new RegExp(fetch.title_filter, "i");
|
|
157
|
-
} catch (e) {
|
|
158
|
-
throw new Error(`[claude-synergy] ${name}: invalid rss title_filter regex: ${e.message}`);
|
|
159
|
-
}
|
|
160
|
-
}
|
|
161
|
-
break;
|
|
162
|
-
case "raw-changelog":
|
|
163
|
-
if (!fetch.url) throw new Error(`[claude-synergy] ${name}: raw-changelog requires 'url'`);
|
|
164
|
-
if (!fetch.parser) throw new Error(`[claude-synergy] ${name}: raw-changelog requires 'parser'`);
|
|
165
|
-
if (fetch.parser !== "aider-history" && fetch.parser !== "keep-a-changelog") {
|
|
166
|
-
throw new Error(
|
|
167
|
-
`[claude-synergy] ${name}: raw-changelog 'parser' must be one of: aider-history, keep-a-changelog (got '${fetch.parser}')`
|
|
168
|
-
);
|
|
169
|
-
}
|
|
170
|
-
target.rawChangelogUrl = fetch.url;
|
|
171
|
-
target.rawChangelogParser = fetch.parser;
|
|
172
|
-
break;
|
|
173
|
-
case "html-scrape":
|
|
174
|
-
if (!fetch.parser) throw new Error(`[claude-synergy] ${name}: html-scrape requires 'parser'`);
|
|
175
|
-
target.htmlParser = fetch.parser;
|
|
176
|
-
break;
|
|
177
|
-
case "catalog":
|
|
178
|
-
if (!fetch.catalog_type) throw new Error(`[claude-synergy] ${name}: catalog requires 'catalog_type'`);
|
|
179
|
-
target.catalogType = fetch.catalog_type;
|
|
180
|
-
if (fetch.max_entries) target.catalogMaxEntries = fetch.max_entries;
|
|
181
|
-
break;
|
|
182
|
-
case "playwright":
|
|
183
|
-
break;
|
|
184
|
-
default:
|
|
185
|
-
throw new Error(`[claude-synergy] ${name}: unknown fetch type ${fetch.type}`);
|
|
186
|
-
}
|
|
187
|
-
return target;
|
|
188
|
-
}
|
|
189
|
-
function resolveYamlPath() {
|
|
190
|
-
const candidates = [
|
|
191
|
-
join(__dirname2, "..", "products.yaml"),
|
|
192
|
-
join(process.cwd(), "products.yaml")
|
|
193
|
-
];
|
|
194
|
-
for (const p of candidates) {
|
|
195
|
-
try {
|
|
196
|
-
readFileSync(p);
|
|
197
|
-
return p;
|
|
198
|
-
} catch {
|
|
199
|
-
}
|
|
200
|
-
}
|
|
201
|
-
return candidates[0];
|
|
202
|
-
}
|
|
203
|
-
|
|
204
78
|
// src/ingest.ts
|
|
205
79
|
var turndown = new TurndownService({
|
|
206
80
|
headingStyle: "atx",
|
|
@@ -316,14 +190,20 @@ function ingestAll(db, productsRoot) {
|
|
|
316
190
|
};
|
|
317
191
|
const productDirs = readdirSync(productsRoot).filter((name) => {
|
|
318
192
|
try {
|
|
319
|
-
return statSync(
|
|
193
|
+
return statSync(join(productsRoot, name)).isDirectory();
|
|
320
194
|
} catch {
|
|
321
195
|
return false;
|
|
322
196
|
}
|
|
323
197
|
});
|
|
324
198
|
const insertProduct = db.prepare(`
|
|
325
|
-
INSERT
|
|
199
|
+
INSERT INTO products (name, display_name, source_tier, source_url, fetch_strategy, notes)
|
|
326
200
|
VALUES (@name, @display_name, @source_tier, @source_url, @fetch_strategy, @notes)
|
|
201
|
+
ON CONFLICT(name) DO UPDATE SET
|
|
202
|
+
display_name = excluded.display_name,
|
|
203
|
+
source_tier = excluded.source_tier,
|
|
204
|
+
source_url = excluded.source_url,
|
|
205
|
+
fetch_strategy = excluded.fetch_strategy,
|
|
206
|
+
notes = excluded.notes
|
|
327
207
|
`);
|
|
328
208
|
const insertRelease = db.prepare(`
|
|
329
209
|
INSERT OR REPLACE INTO releases (product, version, released_at, notes_path, fetched_at, source_url, bundle_size_kb, notes_hash)
|
|
@@ -342,8 +222,8 @@ function ingestAll(db, productsRoot) {
|
|
|
342
222
|
VALUES (?, ?, ?)
|
|
343
223
|
`);
|
|
344
224
|
for (const product of productDirs) {
|
|
345
|
-
const releasesDir =
|
|
346
|
-
if (!
|
|
225
|
+
const releasesDir = join(productsRoot, product, "releases");
|
|
226
|
+
if (!existsSync(releasesDir)) {
|
|
347
227
|
continue;
|
|
348
228
|
}
|
|
349
229
|
let releaseFiles;
|
|
@@ -374,8 +254,8 @@ function ingestAll(db, productsRoot) {
|
|
|
374
254
|
for (const file of releaseFiles) {
|
|
375
255
|
try {
|
|
376
256
|
stats.total++;
|
|
377
|
-
const path =
|
|
378
|
-
const raw =
|
|
257
|
+
const path = join(releasesDir, file);
|
|
258
|
+
const raw = readFileSync(path, "utf-8");
|
|
379
259
|
const { data: fm, content } = matter(raw);
|
|
380
260
|
const fmTyped = fm;
|
|
381
261
|
const baseVersion = fmTyped.version ?? basename(file, ".md");
|
|
@@ -548,7 +428,7 @@ function ingestSynergies(db, synergyDir) {
|
|
|
548
428
|
changeRefsAdded: 0,
|
|
549
429
|
errors: []
|
|
550
430
|
};
|
|
551
|
-
if (!
|
|
431
|
+
if (!existsSync(synergyDir)) {
|
|
552
432
|
return stats;
|
|
553
433
|
}
|
|
554
434
|
let files;
|
|
@@ -611,8 +491,8 @@ function ingestSynergies(db, synergyDir) {
|
|
|
611
491
|
const tx = db.transaction(() => {
|
|
612
492
|
for (const file of files) {
|
|
613
493
|
try {
|
|
614
|
-
const path =
|
|
615
|
-
const raw =
|
|
494
|
+
const path = join(synergyDir, file);
|
|
495
|
+
const raw = readFileSync(path, "utf-8");
|
|
616
496
|
const parsed = matter(raw);
|
|
617
497
|
const fm = parsed.data;
|
|
618
498
|
const body = parsed.content;
|
|
@@ -743,7 +623,6 @@ function ingestSynergies(db, synergyDir) {
|
|
|
743
623
|
}
|
|
744
624
|
|
|
745
625
|
export {
|
|
746
|
-
loadProductsConfig,
|
|
747
626
|
ingestAll,
|
|
748
627
|
ingestSynergies
|
|
749
628
|
};
|