asynthetic 0.1.0-beta

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.
@@ -0,0 +1,61 @@
1
+ /**
2
+ * Supabase (Postgres) store. Reads the three tables defined in schema/schema.sql
3
+ * and reassembles rows into the same MigrationMap shape the local store serves.
4
+ */
5
+ import { createClient } from '@supabase/supabase-js';
6
+ import { toSummary } from './store.js';
7
+ function rowToMap(row) {
8
+ return {
9
+ ecosystem: row.ecosystem,
10
+ package: row.package,
11
+ from_version: row.from_version,
12
+ to_version: row.to_version,
13
+ summary: row.summary,
14
+ breaking_changes: [...row.breaking_changes]
15
+ .sort((a, b) => a.position - b.position)
16
+ .map(({ position: _position, affected_symbols, ...bc }) => ({
17
+ ...bc,
18
+ affected_symbols: affected_symbols ?? [],
19
+ })),
20
+ deprecations: row.deprecations,
21
+ source_urls: row.source_urls,
22
+ last_verified: row.last_verified,
23
+ status: row.status,
24
+ };
25
+ }
26
+ const SELECT = '*, breaking_changes(*), deprecations(*)';
27
+ export class SupabaseStore {
28
+ url;
29
+ client;
30
+ constructor(url, key) {
31
+ this.url = url;
32
+ this.client = createClient(url, key, { auth: { persistSession: false } });
33
+ }
34
+ async getMapsForPackage(ecosystem, pkg) {
35
+ const { data, error } = await this.client
36
+ .from('migrations')
37
+ .select(SELECT)
38
+ .eq('ecosystem', ecosystem)
39
+ .ilike('package', pkg.trim()) // no wildcards -> case-insensitive equality
40
+ .neq('status', 'stale');
41
+ if (error)
42
+ throw new Error(`Supabase query failed: ${error.message}`);
43
+ return (data ?? []).map(rowToMap);
44
+ }
45
+ async listMaps() {
46
+ const { data, error } = await this.client
47
+ .from('migrations')
48
+ .select('ecosystem, package, from_version, to_version, status, last_verified')
49
+ .neq('status', 'stale')
50
+ .order('package');
51
+ if (error)
52
+ throw new Error(`Supabase query failed: ${error.message}`);
53
+ return (data ?? []);
54
+ }
55
+ describe() {
56
+ return `Supabase (${this.url})`;
57
+ }
58
+ }
59
+ // Re-exported here so map assembly stays reusable by scripts/seed.ts.
60
+ export { toSummary };
61
+ //# sourceMappingURL=supabase-store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"supabase-store.js","sourceRoot":"","sources":["../../src/store/supabase-store.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EAAE,YAAY,EAAuB,MAAM,uBAAuB,CAAC;AAE1E,OAAO,EAAE,SAAS,EAAwC,MAAM,YAAY,CAAC;AAkC7E,SAAS,QAAQ,CAAC,GAAiB;IACjC,OAAO;QACL,SAAS,EAAE,GAAG,CAAC,SAAS;QACxB,OAAO,EAAE,GAAG,CAAC,OAAO;QACpB,YAAY,EAAE,GAAG,CAAC,YAAY;QAC9B,UAAU,EAAE,GAAG,CAAC,UAAU;QAC1B,OAAO,EAAE,GAAG,CAAC,OAAO;QACpB,gBAAgB,EAAE,CAAC,GAAG,GAAG,CAAC,gBAAgB,CAAC;aACxC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,GAAG,CAAC,CAAC,QAAQ,CAAC;aACvC,GAAG,CAAC,CAAC,EAAE,QAAQ,EAAE,SAAS,EAAE,gBAAgB,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC;YAC1D,GAAG,EAAE;YACL,gBAAgB,EAAE,gBAAgB,IAAI,EAAE;SACzC,CAAC,CAAC;QACL,YAAY,EAAE,GAAG,CAAC,YAAY;QAC9B,WAAW,EAAE,GAAG,CAAC,WAAW;QAC5B,aAAa,EAAE,GAAG,CAAC,aAAa;QAChC,MAAM,EAAE,GAAG,CAAC,MAAM;KACnB,CAAC;AACJ,CAAC;AAED,MAAM,MAAM,GAAG,yCAAyC,CAAC;AAEzD,MAAM,OAAO,aAAa;IAIL;IAHF,MAAM,CAAiB;IAExC,YACmB,GAAW,EAC5B,GAAW;QADM,QAAG,GAAH,GAAG,CAAQ;QAG5B,IAAI,CAAC,MAAM,GAAG,YAAY,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,IAAI,EAAE,EAAE,cAAc,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC;IAC5E,CAAC;IAED,KAAK,CAAC,iBAAiB,CAAC,SAAiB,EAAE,GAAW;QACpD,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,MAAM,IAAI,CAAC,MAAM;aACtC,IAAI,CAAC,YAAY,CAAC;aAClB,MAAM,CAAC,MAAM,CAAC;aACd,EAAE,CAAC,WAAW,EAAE,SAAS,CAAC;aAC1B,KAAK,CAAC,SAAS,EAAE,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC,4CAA4C;aACzE,GAAG,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QAC1B,IAAI,KAAK;YAAE,MAAM,IAAI,KAAK,CAAC,0BAA0B,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;QACtE,OAAQ,CAAC,IAAI,IAAI,EAAE,CAA+B,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IACnE,CAAC;IAED,KAAK,CAAC,QAAQ;QACZ,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,MAAM,IAAI,CAAC,MAAM;aACtC,IAAI,CAAC,YAAY,CAAC;aAClB,MAAM,CAAC,qEAAqE,CAAC;aAC7E,GAAG,CAAC,QAAQ,EAAE,OAAO,CAAC;aACtB,KAAK,CAAC,SAAS,CAAC,CAAC;QACpB,IAAI,KAAK;YAAE,MAAM,IAAI,KAAK,CAAC,0BAA0B,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;QACtE,OAAO,CAAC,IAAI,IAAI,EAAE,CAAiB,CAAC;IACtC,CAAC;IAED,QAAQ;QACN,OAAO,aAAa,IAAI,CAAC,GAAG,GAAG,CAAC;IAClC,CAAC;CACF;AAED,sEAAsE;AACtE,OAAO,EAAE,SAAS,EAAE,CAAC"}
@@ -0,0 +1,107 @@
1
+ /**
2
+ * Asynthetic — migration-map types.
3
+ *
4
+ * These mirror schema/schema.sql exactly. The Zod schema at the bottom validates
5
+ * map JSON files (data/maps/**) before they are inserted into Postgres, so a
6
+ * malformed hand-curated map fails at ingestion, not at serve time.
7
+ */
8
+ import * as z from 'zod/v4';
9
+ export type Ecosystem = 'npm';
10
+ export type ChangeCategory = 'signature-change' | 'removal' | 'deprecation' | 'behavior-change' | 'config-change' | 'import-change' | 'rename';
11
+ export type MigrationStatus = 'draft' | 'verified' | 'stale';
12
+ export interface BreakingChange {
13
+ title: string;
14
+ description: string;
15
+ category: ChangeCategory;
16
+ /** Functions/exports/config keys affected. Empty when the change is package-wide. */
17
+ affected_symbols: string[];
18
+ before_code: string | null;
19
+ after_code: string | null;
20
+ /** Plain-language "how to fix". */
21
+ migration_note: string;
22
+ /** Per-change citation; falls back to MigrationMap.source_urls when null. */
23
+ source_url: string | null;
24
+ }
25
+ export interface Deprecation {
26
+ symbol: string;
27
+ replacement: string | null;
28
+ removal_timeline: string | null;
29
+ note: string | null;
30
+ }
31
+ export interface MigrationMap {
32
+ ecosystem: Ecosystem;
33
+ package: string;
34
+ /** Concrete semver the map was verified from (e.g. "1.29.0"). */
35
+ from_version: string;
36
+ /** Concrete semver the map was verified to (e.g. "2.0.0-beta.2"). */
37
+ to_version: string;
38
+ summary: string;
39
+ breaking_changes: BreakingChange[];
40
+ deprecations: Deprecation[];
41
+ source_urls: string[];
42
+ /** ISO date (YYYY-MM-DD) the sources were last checked against this map. */
43
+ last_verified: string;
44
+ status: MigrationStatus;
45
+ }
46
+ export declare const BreakingChangeSchema: z.ZodObject<{
47
+ title: z.ZodString;
48
+ description: z.ZodString;
49
+ category: z.ZodEnum<{
50
+ "signature-change": "signature-change";
51
+ removal: "removal";
52
+ deprecation: "deprecation";
53
+ "behavior-change": "behavior-change";
54
+ "config-change": "config-change";
55
+ "import-change": "import-change";
56
+ rename: "rename";
57
+ }>;
58
+ affected_symbols: z.ZodArray<z.ZodString>;
59
+ before_code: z.ZodNullable<z.ZodString>;
60
+ after_code: z.ZodNullable<z.ZodString>;
61
+ migration_note: z.ZodString;
62
+ source_url: z.ZodNullable<z.ZodURL>;
63
+ }, z.core.$strip>;
64
+ export declare const DeprecationSchema: z.ZodObject<{
65
+ symbol: z.ZodString;
66
+ replacement: z.ZodNullable<z.ZodString>;
67
+ removal_timeline: z.ZodNullable<z.ZodString>;
68
+ note: z.ZodNullable<z.ZodString>;
69
+ }, z.core.$strip>;
70
+ export declare const MigrationMapSchema: z.ZodObject<{
71
+ ecosystem: z.ZodLiteral<"npm">;
72
+ package: z.ZodString;
73
+ from_version: z.ZodString;
74
+ to_version: z.ZodString;
75
+ summary: z.ZodString;
76
+ breaking_changes: z.ZodArray<z.ZodObject<{
77
+ title: z.ZodString;
78
+ description: z.ZodString;
79
+ category: z.ZodEnum<{
80
+ "signature-change": "signature-change";
81
+ removal: "removal";
82
+ deprecation: "deprecation";
83
+ "behavior-change": "behavior-change";
84
+ "config-change": "config-change";
85
+ "import-change": "import-change";
86
+ rename: "rename";
87
+ }>;
88
+ affected_symbols: z.ZodArray<z.ZodString>;
89
+ before_code: z.ZodNullable<z.ZodString>;
90
+ after_code: z.ZodNullable<z.ZodString>;
91
+ migration_note: z.ZodString;
92
+ source_url: z.ZodNullable<z.ZodURL>;
93
+ }, z.core.$strip>>;
94
+ deprecations: z.ZodArray<z.ZodObject<{
95
+ symbol: z.ZodString;
96
+ replacement: z.ZodNullable<z.ZodString>;
97
+ removal_timeline: z.ZodNullable<z.ZodString>;
98
+ note: z.ZodNullable<z.ZodString>;
99
+ }, z.core.$strip>>;
100
+ source_urls: z.ZodArray<z.ZodURL>;
101
+ last_verified: z.ZodISODate;
102
+ status: z.ZodEnum<{
103
+ draft: "draft";
104
+ verified: "verified";
105
+ stale: "stale";
106
+ }>;
107
+ }, z.core.$strip>;
@@ -0,0 +1,48 @@
1
+ /**
2
+ * Asynthetic — migration-map types.
3
+ *
4
+ * These mirror schema/schema.sql exactly. The Zod schema at the bottom validates
5
+ * map JSON files (data/maps/**) before they are inserted into Postgres, so a
6
+ * malformed hand-curated map fails at ingestion, not at serve time.
7
+ */
8
+ // zod/v4 subpath: the v1 MCP SDK pairs with the Zod v3 API (used for tool inputs
9
+ // in src/index.ts), while this ingestion validator uses the v4 API. zod@^3.25
10
+ // ships both, so one installed package serves both consumers.
11
+ import * as z from 'zod/v4';
12
+ export const BreakingChangeSchema = z.object({
13
+ title: z.string().min(1),
14
+ description: z.string().min(1),
15
+ category: z.enum([
16
+ 'signature-change',
17
+ 'removal',
18
+ 'deprecation',
19
+ 'behavior-change',
20
+ 'config-change',
21
+ 'import-change',
22
+ 'rename',
23
+ ]),
24
+ affected_symbols: z.array(z.string().min(1)),
25
+ before_code: z.string().min(1).nullable(),
26
+ after_code: z.string().min(1).nullable(),
27
+ migration_note: z.string().min(1),
28
+ source_url: z.url().nullable(),
29
+ });
30
+ export const DeprecationSchema = z.object({
31
+ symbol: z.string().min(1),
32
+ replacement: z.string().min(1).nullable(),
33
+ removal_timeline: z.string().min(1).nullable(),
34
+ note: z.string().min(1).nullable(),
35
+ });
36
+ export const MigrationMapSchema = z.object({
37
+ ecosystem: z.literal('npm'),
38
+ package: z.string().min(1),
39
+ from_version: z.string().min(1),
40
+ to_version: z.string().min(1),
41
+ summary: z.string().min(1),
42
+ breaking_changes: z.array(BreakingChangeSchema).min(1),
43
+ deprecations: z.array(DeprecationSchema),
44
+ source_urls: z.array(z.url()).min(1),
45
+ last_verified: z.iso.date(),
46
+ status: z.enum(['draft', 'verified', 'stale']),
47
+ });
48
+ //# sourceMappingURL=migration-map.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"migration-map.js","sourceRoot":"","sources":["../../src/types/migration-map.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,iFAAiF;AACjF,8EAA8E;AAC9E,8DAA8D;AAC9D,OAAO,KAAK,CAAC,MAAM,QAAQ,CAAC;AAoD5B,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC3C,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IACxB,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IAC9B,QAAQ,EAAE,CAAC,CAAC,IAAI,CAAC;QACf,kBAAkB;QAClB,SAAS;QACT,aAAa;QACb,iBAAiB;QACjB,eAAe;QACf,eAAe;QACf,QAAQ;KACT,CAAC;IACF,gBAAgB,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;IAC5C,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE;IACzC,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE;IACxC,cAAc,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IACjC,UAAU,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE;CAC/B,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,CAAC,MAAM,CAAC;IACxC,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IACzB,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE;IACzC,gBAAgB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE;IAC9C,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE;CACnC,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,CAAC,MAAM,CAAC;IACzC,SAAS,EAAE,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC;IAC3B,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IAC1B,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IAC/B,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IAC7B,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IAC1B,gBAAgB,EAAE,CAAC,CAAC,KAAK,CAAC,oBAAoB,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IACtD,YAAY,EAAE,CAAC,CAAC,KAAK,CAAC,iBAAiB,CAAC;IACxC,WAAW,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IACpC,aAAa,EAAE,CAAC,CAAC,GAAG,CAAC,IAAI,EAAE;IAC3B,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,UAAU,EAAE,OAAO,CAAC,CAAC;CAC/C,CAAmC,CAAC"}
package/package.json ADDED
@@ -0,0 +1,57 @@
1
+ {
2
+ "name": "asynthetic",
3
+ "version": "0.1.0-beta",
4
+ "description": "Asynthetic — MCP server that gives AI coding agents verified migration maps for fast-moving libraries: exactly what breaks between two versions and how to fix it.",
5
+ "keywords": [
6
+ "mcp",
7
+ "model-context-protocol",
8
+ "mcp-server",
9
+ "migration",
10
+ "breaking-changes",
11
+ "upgrade",
12
+ "semver",
13
+ "ai-agents"
14
+ ],
15
+ "repository": {
16
+ "type": "git",
17
+ "url": "git+https://github.com/asyntheticai/asynthetic.git"
18
+ },
19
+ "homepage": "https://github.com/asyntheticai/asynthetic#readme",
20
+ "bugs": {
21
+ "url": "https://github.com/asyntheticai/asynthetic/issues"
22
+ },
23
+ "type": "module",
24
+ "engines": {
25
+ "node": ">=22"
26
+ },
27
+ "bin": {
28
+ "asynthetic": "dist/index.js"
29
+ },
30
+ "files": [
31
+ "dist",
32
+ "data/maps"
33
+ ],
34
+ "scripts": {
35
+ "build": "tsc",
36
+ "typecheck": "tsc --noEmit",
37
+ "dev": "tsx src/index.ts",
38
+ "start": "node dist/index.js",
39
+ "seed": "tsx scripts/seed.ts",
40
+ "smoke": "npm run build && tsx scripts/smoke.ts",
41
+ "inspect": "npm run build && npx @modelcontextprotocol/inspector node dist/index.js"
42
+ },
43
+ "dependencies": {
44
+ "@modelcontextprotocol/sdk": "^1.29.0",
45
+ "@supabase/supabase-js": "^2.49.0",
46
+ "express": "^5.2.1",
47
+ "semver": "^7.8.5",
48
+ "zod": "^3.25.76"
49
+ },
50
+ "devDependencies": {
51
+ "@types/express": "^5.0.6",
52
+ "@types/node": "^22.10.0",
53
+ "@types/semver": "^7.7.1",
54
+ "tsx": "^4.19.0",
55
+ "typescript": "^5.7.0"
56
+ }
57
+ }