@openverb/music-atlas 0.1.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/CHANGELOG.md +13 -0
- package/LICENSE +25 -0
- package/README.md +162 -0
- package/dist/index.cjs +183 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +212 -0
- package/dist/index.d.ts +212 -0
- package/dist/index.js +153 -0
- package/dist/index.js.map +1 -0
- package/dist/openverb.d.ts +26 -0
- package/dist/openverb.js +299 -0
- package/dist/openverb.js.map +1 -0
- package/openverb.music_atlas.json +220 -0
- package/package.json +87 -0
package/dist/openverb.js
ADDED
|
@@ -0,0 +1,299 @@
|
|
|
1
|
+
// src/openverb.ts
|
|
2
|
+
import { createExecutor, loadLibrary } from "openverb";
|
|
3
|
+
|
|
4
|
+
// openverb.music_atlas.json
|
|
5
|
+
var openverb_music_atlas_default = {
|
|
6
|
+
namespace: "openverb.music_atlas",
|
|
7
|
+
version: "0.1.0",
|
|
8
|
+
description: "Read-only verbs for the World Music Atlas on Open Music Atlas: find places and their songs, list editions, get GeoJSON and embeddable players. No verb changes anything.",
|
|
9
|
+
verbs: [
|
|
10
|
+
{
|
|
11
|
+
name: "find_place",
|
|
12
|
+
category: "places",
|
|
13
|
+
description: "Find one place in the atlas by name, ISO 3166-1 alpha-2 code or slug. Case- and accent-insensitive.",
|
|
14
|
+
params: {
|
|
15
|
+
query: {
|
|
16
|
+
type: "string",
|
|
17
|
+
description: "A place name ('Jamaica', 'cote d'ivoire'), ISO code ('JM') or slug ('jamaica').",
|
|
18
|
+
required: true
|
|
19
|
+
}
|
|
20
|
+
},
|
|
21
|
+
returns: {
|
|
22
|
+
place: {
|
|
23
|
+
type: "object",
|
|
24
|
+
description: "The place: slug, name, isoCode, kind, continent, region, coordinates [lon, lat], isDisputed, pageUrl."
|
|
25
|
+
}
|
|
26
|
+
},
|
|
27
|
+
destructive: false,
|
|
28
|
+
requires_confirmation: false
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
name: "search_places",
|
|
32
|
+
category: "places",
|
|
33
|
+
description: "Places whose name contains the query, names starting with it first.",
|
|
34
|
+
params: {
|
|
35
|
+
query: {
|
|
36
|
+
type: "string",
|
|
37
|
+
description: "Part of a place name, e.g. 'guinea'.",
|
|
38
|
+
required: true
|
|
39
|
+
}
|
|
40
|
+
},
|
|
41
|
+
returns: {
|
|
42
|
+
places: {
|
|
43
|
+
type: "array<object>",
|
|
44
|
+
description: "Matching places."
|
|
45
|
+
},
|
|
46
|
+
count: {
|
|
47
|
+
type: "number",
|
|
48
|
+
description: "How many places matched."
|
|
49
|
+
}
|
|
50
|
+
},
|
|
51
|
+
destructive: false,
|
|
52
|
+
requires_confirmation: false
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
name: "list_places",
|
|
56
|
+
category: "places",
|
|
57
|
+
description: "List places in listening order, optionally narrowed to a UN M49 continent, region or kind.",
|
|
58
|
+
params: {
|
|
59
|
+
continent: {
|
|
60
|
+
type: "string",
|
|
61
|
+
description: "A continent, e.g. 'Africa', 'Americas', 'Asia', 'Europe', 'Oceania', 'Antarctica'.",
|
|
62
|
+
required: false
|
|
63
|
+
},
|
|
64
|
+
region: {
|
|
65
|
+
type: "string",
|
|
66
|
+
description: "A region, e.g. 'Caribbean', 'Western Africa', 'South-eastern Asia'.",
|
|
67
|
+
required: false
|
|
68
|
+
},
|
|
69
|
+
kind: {
|
|
70
|
+
type: "enum",
|
|
71
|
+
description: "The kind of place. 'place' is used where classification is contested.",
|
|
72
|
+
enum: ["country", "territory", "continent", "place"],
|
|
73
|
+
required: false
|
|
74
|
+
}
|
|
75
|
+
},
|
|
76
|
+
returns: {
|
|
77
|
+
places: {
|
|
78
|
+
type: "array<object>",
|
|
79
|
+
description: "The places."
|
|
80
|
+
},
|
|
81
|
+
count: {
|
|
82
|
+
type: "number",
|
|
83
|
+
description: "How many places."
|
|
84
|
+
}
|
|
85
|
+
},
|
|
86
|
+
destructive: false,
|
|
87
|
+
requires_confirmation: false
|
|
88
|
+
},
|
|
89
|
+
{
|
|
90
|
+
name: "get_place_song",
|
|
91
|
+
category: "songs",
|
|
92
|
+
description: "A place's song in an edition: its title, description, musical style, page and embeddable player.",
|
|
93
|
+
params: {
|
|
94
|
+
place: {
|
|
95
|
+
type: "string",
|
|
96
|
+
description: "The place's name, ISO code or slug.",
|
|
97
|
+
required: true
|
|
98
|
+
},
|
|
99
|
+
edition: {
|
|
100
|
+
type: "string",
|
|
101
|
+
description: "The edition's slug. Defaults to the 2026 Founding Edition ('2026-founding').",
|
|
102
|
+
required: false
|
|
103
|
+
}
|
|
104
|
+
},
|
|
105
|
+
returns: {
|
|
106
|
+
place: {
|
|
107
|
+
type: "object",
|
|
108
|
+
description: "The place."
|
|
109
|
+
},
|
|
110
|
+
edition: {
|
|
111
|
+
type: "object",
|
|
112
|
+
description: "The edition: slug, name, year, version, frozenAt."
|
|
113
|
+
},
|
|
114
|
+
entry: {
|
|
115
|
+
type: "object",
|
|
116
|
+
description: "The song: title, description, style, curatorsSelection, pageUrl, embedUrl."
|
|
117
|
+
}
|
|
118
|
+
},
|
|
119
|
+
destructive: false,
|
|
120
|
+
requires_confirmation: false
|
|
121
|
+
},
|
|
122
|
+
{
|
|
123
|
+
name: "get_embed_player",
|
|
124
|
+
category: "songs",
|
|
125
|
+
description: "The embeddable player for a place's song: its URL and a ready-to-use iframe.",
|
|
126
|
+
params: {
|
|
127
|
+
place: {
|
|
128
|
+
type: "string",
|
|
129
|
+
description: "The place's name, ISO code or slug.",
|
|
130
|
+
required: true
|
|
131
|
+
},
|
|
132
|
+
edition: {
|
|
133
|
+
type: "string",
|
|
134
|
+
description: "The edition's slug. Defaults to '2026-founding'.",
|
|
135
|
+
required: false
|
|
136
|
+
},
|
|
137
|
+
width: {
|
|
138
|
+
type: "string",
|
|
139
|
+
description: "The frame's width, e.g. '100%' or '300'. Defaults to '100%'.",
|
|
140
|
+
required: false
|
|
141
|
+
},
|
|
142
|
+
height: {
|
|
143
|
+
type: "string",
|
|
144
|
+
description: "The frame's height. Defaults to '212', which fits the player.",
|
|
145
|
+
required: false
|
|
146
|
+
}
|
|
147
|
+
},
|
|
148
|
+
returns: {
|
|
149
|
+
embed_url: {
|
|
150
|
+
type: "string",
|
|
151
|
+
description: "The player's URL."
|
|
152
|
+
},
|
|
153
|
+
html: {
|
|
154
|
+
type: "string",
|
|
155
|
+
description: "An iframe for the player."
|
|
156
|
+
}
|
|
157
|
+
},
|
|
158
|
+
destructive: false,
|
|
159
|
+
requires_confirmation: false
|
|
160
|
+
},
|
|
161
|
+
{
|
|
162
|
+
name: "list_editions",
|
|
163
|
+
category: "editions",
|
|
164
|
+
description: "Every published edition of the World Music Atlas, newest first.",
|
|
165
|
+
params: {},
|
|
166
|
+
returns: {
|
|
167
|
+
editions: {
|
|
168
|
+
type: "array<object>",
|
|
169
|
+
description: "Editions: slug, name, collection, year, version, styleConstraint, frozenAt, entryCount, pageUrl."
|
|
170
|
+
},
|
|
171
|
+
count: {
|
|
172
|
+
type: "number",
|
|
173
|
+
description: "How many editions."
|
|
174
|
+
}
|
|
175
|
+
},
|
|
176
|
+
destructive: false,
|
|
177
|
+
requires_confirmation: false
|
|
178
|
+
},
|
|
179
|
+
{
|
|
180
|
+
name: "get_edition",
|
|
181
|
+
category: "editions",
|
|
182
|
+
description: "An edition and every song in it, in listening order.",
|
|
183
|
+
params: {
|
|
184
|
+
edition: {
|
|
185
|
+
type: "string",
|
|
186
|
+
description: "The edition's slug. Defaults to '2026-founding'.",
|
|
187
|
+
required: false
|
|
188
|
+
}
|
|
189
|
+
},
|
|
190
|
+
returns: {
|
|
191
|
+
edition: {
|
|
192
|
+
type: "object",
|
|
193
|
+
description: "The edition."
|
|
194
|
+
},
|
|
195
|
+
entries: {
|
|
196
|
+
type: "array<object>",
|
|
197
|
+
description: "Each place and its song."
|
|
198
|
+
}
|
|
199
|
+
},
|
|
200
|
+
destructive: false,
|
|
201
|
+
requires_confirmation: false
|
|
202
|
+
},
|
|
203
|
+
{
|
|
204
|
+
name: "get_geojson",
|
|
205
|
+
category: "maps",
|
|
206
|
+
description: "An edition as a GeoJSON FeatureCollection: one point per place, with the place and its song as properties.",
|
|
207
|
+
params: {
|
|
208
|
+
edition: {
|
|
209
|
+
type: "string",
|
|
210
|
+
description: "The edition's slug. Defaults to '2026-founding'.",
|
|
211
|
+
required: false
|
|
212
|
+
}
|
|
213
|
+
},
|
|
214
|
+
returns: {
|
|
215
|
+
geojson: {
|
|
216
|
+
type: "object",
|
|
217
|
+
description: "A GeoJSON FeatureCollection, EPSG:4326."
|
|
218
|
+
}
|
|
219
|
+
},
|
|
220
|
+
destructive: false,
|
|
221
|
+
requires_confirmation: false
|
|
222
|
+
}
|
|
223
|
+
]
|
|
224
|
+
};
|
|
225
|
+
|
|
226
|
+
// src/openverb.ts
|
|
227
|
+
import { atlas, FOUNDING_EDITION } from "@openverb/music-atlas";
|
|
228
|
+
var MUSIC_ATLAS_NAMESPACE = "openverb.music_atlas";
|
|
229
|
+
var musicAtlasLibrary = loadLibrary(openverb_music_atlas_default);
|
|
230
|
+
var ok = (verb, data) => ({ verb, status: "success", data });
|
|
231
|
+
var fail = (verb, message) => ({ verb, status: "error", error_message: message });
|
|
232
|
+
var text = (v) => v === void 0 || v === null || v === "" ? void 0 : String(v);
|
|
233
|
+
function registerMusicAtlasVerbs(executor, client = atlas) {
|
|
234
|
+
const findOrFail = async (verb, query) => {
|
|
235
|
+
const place = await client.find(String(query ?? ""));
|
|
236
|
+
return place ? { place } : { error: fail(verb, `No place in the atlas matches "${query}".`) };
|
|
237
|
+
};
|
|
238
|
+
executor.register("find_place", async ({ query }) => {
|
|
239
|
+
const found = await findOrFail("find_place", query);
|
|
240
|
+
return "error" in found ? found.error : ok("find_place", { place: found.place });
|
|
241
|
+
});
|
|
242
|
+
executor.register("search_places", async ({ query }) => {
|
|
243
|
+
const places = await client.search(String(query ?? ""));
|
|
244
|
+
return ok("search_places", { places, count: places.length });
|
|
245
|
+
});
|
|
246
|
+
executor.register("list_places", async ({ continent, region, kind }) => {
|
|
247
|
+
const places = await client.places({
|
|
248
|
+
continent: text(continent),
|
|
249
|
+
region: text(region),
|
|
250
|
+
kind: text(kind)
|
|
251
|
+
});
|
|
252
|
+
return ok("list_places", { places, count: places.length });
|
|
253
|
+
});
|
|
254
|
+
executor.register("get_place_song", async ({ place, edition }) => {
|
|
255
|
+
const found = await findOrFail("get_place_song", place);
|
|
256
|
+
if ("error" in found) return found.error;
|
|
257
|
+
const slug = text(edition) ?? FOUNDING_EDITION;
|
|
258
|
+
const detail = await client.place(found.place.slug);
|
|
259
|
+
const match = detail?.entries.find((e) => e.edition.slug === slug);
|
|
260
|
+
if (!match) return fail("get_place_song", `${found.place.name} has no song in the edition "${slug}".`);
|
|
261
|
+
return ok("get_place_song", { place: found.place, edition: match.edition, entry: match.entry });
|
|
262
|
+
});
|
|
263
|
+
executor.register("get_embed_player", async ({ place, edition, width, height }) => {
|
|
264
|
+
const found = await findOrFail("get_embed_player", place);
|
|
265
|
+
if ("error" in found) return found.error;
|
|
266
|
+
const slug = text(edition) ?? FOUNDING_EDITION;
|
|
267
|
+
return ok("get_embed_player", {
|
|
268
|
+
place: found.place,
|
|
269
|
+
embed_url: client.embedUrl(found.place, slug),
|
|
270
|
+
html: client.embedHtml(found.place, slug, { width: text(width), height: text(height) })
|
|
271
|
+
});
|
|
272
|
+
});
|
|
273
|
+
executor.register("list_editions", async () => {
|
|
274
|
+
const editions = await client.editions();
|
|
275
|
+
return ok("list_editions", { editions, count: editions.length });
|
|
276
|
+
});
|
|
277
|
+
executor.register("get_edition", async ({ edition }) => {
|
|
278
|
+
const slug = text(edition) ?? FOUNDING_EDITION;
|
|
279
|
+
const detail = await client.edition(slug);
|
|
280
|
+
return detail ? ok("get_edition", detail) : fail("get_edition", `There is no edition "${slug}".`);
|
|
281
|
+
});
|
|
282
|
+
executor.register("get_geojson", async ({ edition }) => {
|
|
283
|
+
const slug = text(edition) ?? FOUNDING_EDITION;
|
|
284
|
+
const geojson = await client.geojson(slug);
|
|
285
|
+
return geojson ? ok("get_geojson", { geojson }) : fail("get_geojson", `There is no edition "${slug}".`);
|
|
286
|
+
});
|
|
287
|
+
}
|
|
288
|
+
function createMusicAtlasExecutor(client = atlas) {
|
|
289
|
+
const executor = createExecutor(musicAtlasLibrary);
|
|
290
|
+
registerMusicAtlasVerbs(executor, client);
|
|
291
|
+
return executor;
|
|
292
|
+
}
|
|
293
|
+
export {
|
|
294
|
+
MUSIC_ATLAS_NAMESPACE,
|
|
295
|
+
createMusicAtlasExecutor,
|
|
296
|
+
musicAtlasLibrary,
|
|
297
|
+
registerMusicAtlasVerbs
|
|
298
|
+
};
|
|
299
|
+
//# sourceMappingURL=openverb.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/openverb.ts","../openverb.music_atlas.json"],"sourcesContent":["/**\n * The World Music Atlas as OpenVerb verbs, so an AI agent built on OpenVerb\n * can find places, their songs, editions, GeoJSON and players.\n *\n * ```ts\n * import { createMusicAtlasExecutor } from \"@openverb/music-atlas/openverb\"\n *\n * const executor = createMusicAtlasExecutor()\n * await executor.execute({ verb: \"get_place_song\", params: { place: \"Jamaica\" } })\n * ```\n *\n * Needs `openverb` (npm install openverb). Every verb is read-only.\n */\nimport { createExecutor, loadLibrary } from \"openverb\"\nimport type { ActionResult, VerbHandler, VerbLibrary } from \"openverb\"\nimport library from \"../openverb.music_atlas.json\"\n// By package name, not \"./index\": the built file then shares the main entry's\n// client instead of carrying its own copy, whose class TypeScript would treat\n// as a different type from the OpenMusicAtlas you import and pass in.\nimport { atlas, FOUNDING_EDITION, type OpenMusicAtlas, type Place, type PlaceKind } from \"@openverb/music-atlas\"\n\nexport const MUSIC_ATLAS_NAMESPACE = \"openverb.music_atlas\"\n\n/** The verb library: everything an AI may do with the World Music Atlas. */\n// The JSON's inferred type is narrower than VerbLibrary's open records, hence via unknown.\nexport const musicAtlasLibrary: VerbLibrary = loadLibrary(library as unknown as VerbLibrary)\n\n/** Anything handlers can be registered on — an OpenVerb executor, or your own registry. */\nexport interface VerbRegistrar {\n register(verbName: string, handler: VerbHandler): void\n}\n\nconst ok = (verb: string, data: unknown): ActionResult => ({ verb, status: \"success\", data })\nconst fail = (verb: string, message: string): ActionResult => ({ verb, status: \"error\", error_message: message })\nconst text = (v: unknown) => (v === undefined || v === null || v === \"\" ? undefined : String(v))\n\n/**\n * Register a handler for every Music Atlas verb on an executor, using the\n * given client (by default, the one for https://openmusicatlas.org).\n */\nexport function registerMusicAtlasVerbs(executor: VerbRegistrar, client: OpenMusicAtlas = atlas): void {\n // Typed explicitly: an inferred union gives both branches an optional\n // `error`, and `\"error\" in found` would no longer tell them apart.\n const findOrFail = async (verb: string, query: unknown): Promise<{ place: Place } | { error: ActionResult }> => {\n const place = await client.find(String(query ?? \"\"))\n return place ? { place } : { error: fail(verb, `No place in the atlas matches \"${query}\".`) }\n }\n\n executor.register(\"find_place\", async ({ query }) => {\n const found = await findOrFail(\"find_place\", query)\n return \"error\" in found ? found.error : ok(\"find_place\", { place: found.place })\n })\n\n executor.register(\"search_places\", async ({ query }) => {\n const places = await client.search(String(query ?? \"\"))\n return ok(\"search_places\", { places, count: places.length })\n })\n\n executor.register(\"list_places\", async ({ continent, region, kind }) => {\n const places = await client.places({\n continent: text(continent),\n region: text(region),\n kind: text(kind) as PlaceKind | undefined,\n })\n return ok(\"list_places\", { places, count: places.length })\n })\n\n executor.register(\"get_place_song\", async ({ place, edition }) => {\n const found = await findOrFail(\"get_place_song\", place)\n if (\"error\" in found) return found.error\n const slug = text(edition) ?? FOUNDING_EDITION\n const detail = await client.place(found.place.slug)\n const match = detail?.entries.find((e) => e.edition.slug === slug)\n if (!match) return fail(\"get_place_song\", `${found.place.name} has no song in the edition \"${slug}\".`)\n return ok(\"get_place_song\", { place: found.place, edition: match.edition, entry: match.entry })\n })\n\n executor.register(\"get_embed_player\", async ({ place, edition, width, height }) => {\n const found = await findOrFail(\"get_embed_player\", place)\n if (\"error\" in found) return found.error\n const slug = text(edition) ?? FOUNDING_EDITION\n return ok(\"get_embed_player\", {\n place: found.place,\n embed_url: client.embedUrl(found.place, slug),\n html: client.embedHtml(found.place, slug, { width: text(width), height: text(height) }),\n })\n })\n\n executor.register(\"list_editions\", async () => {\n const editions = await client.editions()\n return ok(\"list_editions\", { editions, count: editions.length })\n })\n\n executor.register(\"get_edition\", async ({ edition }) => {\n const slug = text(edition) ?? FOUNDING_EDITION\n const detail = await client.edition(slug)\n return detail ? ok(\"get_edition\", detail) : fail(\"get_edition\", `There is no edition \"${slug}\".`)\n })\n\n executor.register(\"get_geojson\", async ({ edition }) => {\n const slug = text(edition) ?? FOUNDING_EDITION\n const geojson = await client.geojson(slug)\n return geojson ? ok(\"get_geojson\", { geojson }) : fail(\"get_geojson\", `There is no edition \"${slug}\".`)\n })\n}\n\n/** An OpenVerb executor with every Music Atlas verb registered and ready to run. */\nexport function createMusicAtlasExecutor(client: OpenMusicAtlas = atlas) {\n const executor = createExecutor(musicAtlasLibrary)\n registerMusicAtlasVerbs(executor, client)\n return executor\n}\n","{\n \"namespace\": \"openverb.music_atlas\",\n \"version\": \"0.1.0\",\n \"description\": \"Read-only verbs for the World Music Atlas on Open Music Atlas: find places and their songs, list editions, get GeoJSON and embeddable players. No verb changes anything.\",\n \"verbs\": [\n {\n \"name\": \"find_place\",\n \"category\": \"places\",\n \"description\": \"Find one place in the atlas by name, ISO 3166-1 alpha-2 code or slug. Case- and accent-insensitive.\",\n \"params\": {\n \"query\": {\n \"type\": \"string\",\n \"description\": \"A place name ('Jamaica', 'cote d'ivoire'), ISO code ('JM') or slug ('jamaica').\",\n \"required\": true\n }\n },\n \"returns\": {\n \"place\": {\n \"type\": \"object\",\n \"description\": \"The place: slug, name, isoCode, kind, continent, region, coordinates [lon, lat], isDisputed, pageUrl.\"\n }\n },\n \"destructive\": false,\n \"requires_confirmation\": false\n },\n {\n \"name\": \"search_places\",\n \"category\": \"places\",\n \"description\": \"Places whose name contains the query, names starting with it first.\",\n \"params\": {\n \"query\": {\n \"type\": \"string\",\n \"description\": \"Part of a place name, e.g. 'guinea'.\",\n \"required\": true\n }\n },\n \"returns\": {\n \"places\": {\n \"type\": \"array<object>\",\n \"description\": \"Matching places.\"\n },\n \"count\": {\n \"type\": \"number\",\n \"description\": \"How many places matched.\"\n }\n },\n \"destructive\": false,\n \"requires_confirmation\": false\n },\n {\n \"name\": \"list_places\",\n \"category\": \"places\",\n \"description\": \"List places in listening order, optionally narrowed to a UN M49 continent, region or kind.\",\n \"params\": {\n \"continent\": {\n \"type\": \"string\",\n \"description\": \"A continent, e.g. 'Africa', 'Americas', 'Asia', 'Europe', 'Oceania', 'Antarctica'.\",\n \"required\": false\n },\n \"region\": {\n \"type\": \"string\",\n \"description\": \"A region, e.g. 'Caribbean', 'Western Africa', 'South-eastern Asia'.\",\n \"required\": false\n },\n \"kind\": {\n \"type\": \"enum\",\n \"description\": \"The kind of place. 'place' is used where classification is contested.\",\n \"enum\": [\"country\", \"territory\", \"continent\", \"place\"],\n \"required\": false\n }\n },\n \"returns\": {\n \"places\": {\n \"type\": \"array<object>\",\n \"description\": \"The places.\"\n },\n \"count\": {\n \"type\": \"number\",\n \"description\": \"How many places.\"\n }\n },\n \"destructive\": false,\n \"requires_confirmation\": false\n },\n {\n \"name\": \"get_place_song\",\n \"category\": \"songs\",\n \"description\": \"A place's song in an edition: its title, description, musical style, page and embeddable player.\",\n \"params\": {\n \"place\": {\n \"type\": \"string\",\n \"description\": \"The place's name, ISO code or slug.\",\n \"required\": true\n },\n \"edition\": {\n \"type\": \"string\",\n \"description\": \"The edition's slug. Defaults to the 2026 Founding Edition ('2026-founding').\",\n \"required\": false\n }\n },\n \"returns\": {\n \"place\": {\n \"type\": \"object\",\n \"description\": \"The place.\"\n },\n \"edition\": {\n \"type\": \"object\",\n \"description\": \"The edition: slug, name, year, version, frozenAt.\"\n },\n \"entry\": {\n \"type\": \"object\",\n \"description\": \"The song: title, description, style, curatorsSelection, pageUrl, embedUrl.\"\n }\n },\n \"destructive\": false,\n \"requires_confirmation\": false\n },\n {\n \"name\": \"get_embed_player\",\n \"category\": \"songs\",\n \"description\": \"The embeddable player for a place's song: its URL and a ready-to-use iframe.\",\n \"params\": {\n \"place\": {\n \"type\": \"string\",\n \"description\": \"The place's name, ISO code or slug.\",\n \"required\": true\n },\n \"edition\": {\n \"type\": \"string\",\n \"description\": \"The edition's slug. Defaults to '2026-founding'.\",\n \"required\": false\n },\n \"width\": {\n \"type\": \"string\",\n \"description\": \"The frame's width, e.g. '100%' or '300'. Defaults to '100%'.\",\n \"required\": false\n },\n \"height\": {\n \"type\": \"string\",\n \"description\": \"The frame's height. Defaults to '212', which fits the player.\",\n \"required\": false\n }\n },\n \"returns\": {\n \"embed_url\": {\n \"type\": \"string\",\n \"description\": \"The player's URL.\"\n },\n \"html\": {\n \"type\": \"string\",\n \"description\": \"An iframe for the player.\"\n }\n },\n \"destructive\": false,\n \"requires_confirmation\": false\n },\n {\n \"name\": \"list_editions\",\n \"category\": \"editions\",\n \"description\": \"Every published edition of the World Music Atlas, newest first.\",\n \"params\": {},\n \"returns\": {\n \"editions\": {\n \"type\": \"array<object>\",\n \"description\": \"Editions: slug, name, collection, year, version, styleConstraint, frozenAt, entryCount, pageUrl.\"\n },\n \"count\": {\n \"type\": \"number\",\n \"description\": \"How many editions.\"\n }\n },\n \"destructive\": false,\n \"requires_confirmation\": false\n },\n {\n \"name\": \"get_edition\",\n \"category\": \"editions\",\n \"description\": \"An edition and every song in it, in listening order.\",\n \"params\": {\n \"edition\": {\n \"type\": \"string\",\n \"description\": \"The edition's slug. Defaults to '2026-founding'.\",\n \"required\": false\n }\n },\n \"returns\": {\n \"edition\": {\n \"type\": \"object\",\n \"description\": \"The edition.\"\n },\n \"entries\": {\n \"type\": \"array<object>\",\n \"description\": \"Each place and its song.\"\n }\n },\n \"destructive\": false,\n \"requires_confirmation\": false\n },\n {\n \"name\": \"get_geojson\",\n \"category\": \"maps\",\n \"description\": \"An edition as a GeoJSON FeatureCollection: one point per place, with the place and its song as properties.\",\n \"params\": {\n \"edition\": {\n \"type\": \"string\",\n \"description\": \"The edition's slug. Defaults to '2026-founding'.\",\n \"required\": false\n }\n },\n \"returns\": {\n \"geojson\": {\n \"type\": \"object\",\n \"description\": \"A GeoJSON FeatureCollection, EPSG:4326.\"\n }\n },\n \"destructive\": false,\n \"requires_confirmation\": false\n }\n ]\n}\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
{
|
|
2
|
+
"namespace": "openverb.music_atlas",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Read-only verbs for the World Music Atlas on Open Music Atlas: find places and their songs, list editions, get GeoJSON and embeddable players. No verb changes anything.",
|
|
5
|
+
"verbs": [
|
|
6
|
+
{
|
|
7
|
+
"name": "find_place",
|
|
8
|
+
"category": "places",
|
|
9
|
+
"description": "Find one place in the atlas by name, ISO 3166-1 alpha-2 code or slug. Case- and accent-insensitive.",
|
|
10
|
+
"params": {
|
|
11
|
+
"query": {
|
|
12
|
+
"type": "string",
|
|
13
|
+
"description": "A place name ('Jamaica', 'cote d'ivoire'), ISO code ('JM') or slug ('jamaica').",
|
|
14
|
+
"required": true
|
|
15
|
+
}
|
|
16
|
+
},
|
|
17
|
+
"returns": {
|
|
18
|
+
"place": {
|
|
19
|
+
"type": "object",
|
|
20
|
+
"description": "The place: slug, name, isoCode, kind, continent, region, coordinates [lon, lat], isDisputed, pageUrl."
|
|
21
|
+
}
|
|
22
|
+
},
|
|
23
|
+
"destructive": false,
|
|
24
|
+
"requires_confirmation": false
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
"name": "search_places",
|
|
28
|
+
"category": "places",
|
|
29
|
+
"description": "Places whose name contains the query, names starting with it first.",
|
|
30
|
+
"params": {
|
|
31
|
+
"query": {
|
|
32
|
+
"type": "string",
|
|
33
|
+
"description": "Part of a place name, e.g. 'guinea'.",
|
|
34
|
+
"required": true
|
|
35
|
+
}
|
|
36
|
+
},
|
|
37
|
+
"returns": {
|
|
38
|
+
"places": {
|
|
39
|
+
"type": "array<object>",
|
|
40
|
+
"description": "Matching places."
|
|
41
|
+
},
|
|
42
|
+
"count": {
|
|
43
|
+
"type": "number",
|
|
44
|
+
"description": "How many places matched."
|
|
45
|
+
}
|
|
46
|
+
},
|
|
47
|
+
"destructive": false,
|
|
48
|
+
"requires_confirmation": false
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
"name": "list_places",
|
|
52
|
+
"category": "places",
|
|
53
|
+
"description": "List places in listening order, optionally narrowed to a UN M49 continent, region or kind.",
|
|
54
|
+
"params": {
|
|
55
|
+
"continent": {
|
|
56
|
+
"type": "string",
|
|
57
|
+
"description": "A continent, e.g. 'Africa', 'Americas', 'Asia', 'Europe', 'Oceania', 'Antarctica'.",
|
|
58
|
+
"required": false
|
|
59
|
+
},
|
|
60
|
+
"region": {
|
|
61
|
+
"type": "string",
|
|
62
|
+
"description": "A region, e.g. 'Caribbean', 'Western Africa', 'South-eastern Asia'.",
|
|
63
|
+
"required": false
|
|
64
|
+
},
|
|
65
|
+
"kind": {
|
|
66
|
+
"type": "enum",
|
|
67
|
+
"description": "The kind of place. 'place' is used where classification is contested.",
|
|
68
|
+
"enum": ["country", "territory", "continent", "place"],
|
|
69
|
+
"required": false
|
|
70
|
+
}
|
|
71
|
+
},
|
|
72
|
+
"returns": {
|
|
73
|
+
"places": {
|
|
74
|
+
"type": "array<object>",
|
|
75
|
+
"description": "The places."
|
|
76
|
+
},
|
|
77
|
+
"count": {
|
|
78
|
+
"type": "number",
|
|
79
|
+
"description": "How many places."
|
|
80
|
+
}
|
|
81
|
+
},
|
|
82
|
+
"destructive": false,
|
|
83
|
+
"requires_confirmation": false
|
|
84
|
+
},
|
|
85
|
+
{
|
|
86
|
+
"name": "get_place_song",
|
|
87
|
+
"category": "songs",
|
|
88
|
+
"description": "A place's song in an edition: its title, description, musical style, page and embeddable player.",
|
|
89
|
+
"params": {
|
|
90
|
+
"place": {
|
|
91
|
+
"type": "string",
|
|
92
|
+
"description": "The place's name, ISO code or slug.",
|
|
93
|
+
"required": true
|
|
94
|
+
},
|
|
95
|
+
"edition": {
|
|
96
|
+
"type": "string",
|
|
97
|
+
"description": "The edition's slug. Defaults to the 2026 Founding Edition ('2026-founding').",
|
|
98
|
+
"required": false
|
|
99
|
+
}
|
|
100
|
+
},
|
|
101
|
+
"returns": {
|
|
102
|
+
"place": {
|
|
103
|
+
"type": "object",
|
|
104
|
+
"description": "The place."
|
|
105
|
+
},
|
|
106
|
+
"edition": {
|
|
107
|
+
"type": "object",
|
|
108
|
+
"description": "The edition: slug, name, year, version, frozenAt."
|
|
109
|
+
},
|
|
110
|
+
"entry": {
|
|
111
|
+
"type": "object",
|
|
112
|
+
"description": "The song: title, description, style, curatorsSelection, pageUrl, embedUrl."
|
|
113
|
+
}
|
|
114
|
+
},
|
|
115
|
+
"destructive": false,
|
|
116
|
+
"requires_confirmation": false
|
|
117
|
+
},
|
|
118
|
+
{
|
|
119
|
+
"name": "get_embed_player",
|
|
120
|
+
"category": "songs",
|
|
121
|
+
"description": "The embeddable player for a place's song: its URL and a ready-to-use iframe.",
|
|
122
|
+
"params": {
|
|
123
|
+
"place": {
|
|
124
|
+
"type": "string",
|
|
125
|
+
"description": "The place's name, ISO code or slug.",
|
|
126
|
+
"required": true
|
|
127
|
+
},
|
|
128
|
+
"edition": {
|
|
129
|
+
"type": "string",
|
|
130
|
+
"description": "The edition's slug. Defaults to '2026-founding'.",
|
|
131
|
+
"required": false
|
|
132
|
+
},
|
|
133
|
+
"width": {
|
|
134
|
+
"type": "string",
|
|
135
|
+
"description": "The frame's width, e.g. '100%' or '300'. Defaults to '100%'.",
|
|
136
|
+
"required": false
|
|
137
|
+
},
|
|
138
|
+
"height": {
|
|
139
|
+
"type": "string",
|
|
140
|
+
"description": "The frame's height. Defaults to '212', which fits the player.",
|
|
141
|
+
"required": false
|
|
142
|
+
}
|
|
143
|
+
},
|
|
144
|
+
"returns": {
|
|
145
|
+
"embed_url": {
|
|
146
|
+
"type": "string",
|
|
147
|
+
"description": "The player's URL."
|
|
148
|
+
},
|
|
149
|
+
"html": {
|
|
150
|
+
"type": "string",
|
|
151
|
+
"description": "An iframe for the player."
|
|
152
|
+
}
|
|
153
|
+
},
|
|
154
|
+
"destructive": false,
|
|
155
|
+
"requires_confirmation": false
|
|
156
|
+
},
|
|
157
|
+
{
|
|
158
|
+
"name": "list_editions",
|
|
159
|
+
"category": "editions",
|
|
160
|
+
"description": "Every published edition of the World Music Atlas, newest first.",
|
|
161
|
+
"params": {},
|
|
162
|
+
"returns": {
|
|
163
|
+
"editions": {
|
|
164
|
+
"type": "array<object>",
|
|
165
|
+
"description": "Editions: slug, name, collection, year, version, styleConstraint, frozenAt, entryCount, pageUrl."
|
|
166
|
+
},
|
|
167
|
+
"count": {
|
|
168
|
+
"type": "number",
|
|
169
|
+
"description": "How many editions."
|
|
170
|
+
}
|
|
171
|
+
},
|
|
172
|
+
"destructive": false,
|
|
173
|
+
"requires_confirmation": false
|
|
174
|
+
},
|
|
175
|
+
{
|
|
176
|
+
"name": "get_edition",
|
|
177
|
+
"category": "editions",
|
|
178
|
+
"description": "An edition and every song in it, in listening order.",
|
|
179
|
+
"params": {
|
|
180
|
+
"edition": {
|
|
181
|
+
"type": "string",
|
|
182
|
+
"description": "The edition's slug. Defaults to '2026-founding'.",
|
|
183
|
+
"required": false
|
|
184
|
+
}
|
|
185
|
+
},
|
|
186
|
+
"returns": {
|
|
187
|
+
"edition": {
|
|
188
|
+
"type": "object",
|
|
189
|
+
"description": "The edition."
|
|
190
|
+
},
|
|
191
|
+
"entries": {
|
|
192
|
+
"type": "array<object>",
|
|
193
|
+
"description": "Each place and its song."
|
|
194
|
+
}
|
|
195
|
+
},
|
|
196
|
+
"destructive": false,
|
|
197
|
+
"requires_confirmation": false
|
|
198
|
+
},
|
|
199
|
+
{
|
|
200
|
+
"name": "get_geojson",
|
|
201
|
+
"category": "maps",
|
|
202
|
+
"description": "An edition as a GeoJSON FeatureCollection: one point per place, with the place and its song as properties.",
|
|
203
|
+
"params": {
|
|
204
|
+
"edition": {
|
|
205
|
+
"type": "string",
|
|
206
|
+
"description": "The edition's slug. Defaults to '2026-founding'.",
|
|
207
|
+
"required": false
|
|
208
|
+
}
|
|
209
|
+
},
|
|
210
|
+
"returns": {
|
|
211
|
+
"geojson": {
|
|
212
|
+
"type": "object",
|
|
213
|
+
"description": "A GeoJSON FeatureCollection, EPSG:4326."
|
|
214
|
+
}
|
|
215
|
+
},
|
|
216
|
+
"destructive": false,
|
|
217
|
+
"requires_confirmation": false
|
|
218
|
+
}
|
|
219
|
+
]
|
|
220
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@openverb/music-atlas",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "The official SDK for Open Music Atlas: the World Music Atlas's places, songs, editions, GeoJSON and embeddable players, with OpenVerb verbs for AI agents.",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"openverb",
|
|
7
|
+
"open-music-atlas",
|
|
8
|
+
"world-music-atlas",
|
|
9
|
+
"music",
|
|
10
|
+
"geography",
|
|
11
|
+
"gis",
|
|
12
|
+
"geojson",
|
|
13
|
+
"maps",
|
|
14
|
+
"leaflet",
|
|
15
|
+
"maplibre",
|
|
16
|
+
"ai",
|
|
17
|
+
"agent",
|
|
18
|
+
"verbs"
|
|
19
|
+
],
|
|
20
|
+
"author": "Roman Hancel <roman@romanhancel.com>",
|
|
21
|
+
"homepage": "https://openmusicatlas.org/developers",
|
|
22
|
+
"repository": {
|
|
23
|
+
"type": "git",
|
|
24
|
+
"url": "git+https://github.com/sgthancel/openverb-music-atlas.git"
|
|
25
|
+
},
|
|
26
|
+
"bugs": {
|
|
27
|
+
"url": "https://github.com/sgthancel/openverb-music-atlas/issues"
|
|
28
|
+
},
|
|
29
|
+
"license": "MIT",
|
|
30
|
+
"type": "module",
|
|
31
|
+
"main": "./dist/index.cjs",
|
|
32
|
+
"module": "./dist/index.js",
|
|
33
|
+
"types": "./dist/index.d.ts",
|
|
34
|
+
"exports": {
|
|
35
|
+
".": {
|
|
36
|
+
"import": {
|
|
37
|
+
"types": "./dist/index.d.ts",
|
|
38
|
+
"default": "./dist/index.js"
|
|
39
|
+
},
|
|
40
|
+
"require": {
|
|
41
|
+
"types": "./dist/index.d.cts",
|
|
42
|
+
"default": "./dist/index.cjs"
|
|
43
|
+
}
|
|
44
|
+
},
|
|
45
|
+
"./openverb": {
|
|
46
|
+
"types": "./dist/openverb.d.ts",
|
|
47
|
+
"import": "./dist/openverb.js"
|
|
48
|
+
},
|
|
49
|
+
"./openverb.music_atlas.json": "./openverb.music_atlas.json",
|
|
50
|
+
"./package.json": "./package.json"
|
|
51
|
+
},
|
|
52
|
+
"files": [
|
|
53
|
+
"dist",
|
|
54
|
+
"openverb.music_atlas.json",
|
|
55
|
+
"README.md",
|
|
56
|
+
"LICENSE",
|
|
57
|
+
"CHANGELOG.md"
|
|
58
|
+
],
|
|
59
|
+
"sideEffects": false,
|
|
60
|
+
"engines": {
|
|
61
|
+
"node": ">=18"
|
|
62
|
+
},
|
|
63
|
+
"scripts": {
|
|
64
|
+
"build": "node -e \"require('node:fs').rmSync('dist',{recursive:true,force:true})\" && tsup",
|
|
65
|
+
"typecheck": "tsc --noEmit",
|
|
66
|
+
"test": "npm run build && node --test test/client.test.mjs test/cjs.test.cjs test/openverb.test.mjs",
|
|
67
|
+
"test:live": "npm run build && node --test test/live.test.mjs",
|
|
68
|
+
"prepublishOnly": "npm run typecheck && npm test"
|
|
69
|
+
},
|
|
70
|
+
"peerDependencies": {
|
|
71
|
+
"openverb": ">=0.1.0"
|
|
72
|
+
},
|
|
73
|
+
"peerDependenciesMeta": {
|
|
74
|
+
"openverb": {
|
|
75
|
+
"optional": true
|
|
76
|
+
}
|
|
77
|
+
},
|
|
78
|
+
"publishConfig": {
|
|
79
|
+
"access": "public"
|
|
80
|
+
},
|
|
81
|
+
"devDependencies": {
|
|
82
|
+
"@types/node": "^22",
|
|
83
|
+
"openverb": "^0.1.0",
|
|
84
|
+
"tsup": "^8.3.5",
|
|
85
|
+
"typescript": "^5.6.3"
|
|
86
|
+
}
|
|
87
|
+
}
|