chiasmus 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/LICENSE +201 -0
- package/README.md +124 -0
- package/dist/formalize/engine.d.ts +47 -0
- package/dist/formalize/engine.d.ts.map +1 -0
- package/dist/formalize/engine.js +189 -0
- package/dist/formalize/engine.js.map +1 -0
- package/dist/formalize/validate.d.ts +15 -0
- package/dist/formalize/validate.d.ts.map +1 -0
- package/dist/formalize/validate.js +124 -0
- package/dist/formalize/validate.js.map +1 -0
- package/dist/llm/anthropic.d.ts +27 -0
- package/dist/llm/anthropic.d.ts.map +1 -0
- package/dist/llm/anthropic.js +86 -0
- package/dist/llm/anthropic.js.map +1 -0
- package/dist/llm/mock.d.ts +21 -0
- package/dist/llm/mock.d.ts.map +1 -0
- package/dist/llm/mock.js +29 -0
- package/dist/llm/mock.js.map +1 -0
- package/dist/llm/openai-compatible.d.ts +20 -0
- package/dist/llm/openai-compatible.d.ts.map +1 -0
- package/dist/llm/openai-compatible.js +46 -0
- package/dist/llm/openai-compatible.js.map +1 -0
- package/dist/llm/types.d.ts +11 -0
- package/dist/llm/types.d.ts.map +1 -0
- package/dist/llm/types.js +2 -0
- package/dist/llm/types.js.map +1 -0
- package/dist/mcp-server.d.ts +12 -0
- package/dist/mcp-server.d.ts.map +1 -0
- package/dist/mcp-server.js +446 -0
- package/dist/mcp-server.js.map +1 -0
- package/dist/skills/bm25.d.ts +22 -0
- package/dist/skills/bm25.d.ts.map +1 -0
- package/dist/skills/bm25.js +71 -0
- package/dist/skills/bm25.js.map +1 -0
- package/dist/skills/learner.d.ts +21 -0
- package/dist/skills/learner.d.ts.map +1 -0
- package/dist/skills/learner.js +123 -0
- package/dist/skills/learner.js.map +1 -0
- package/dist/skills/library.d.ts +36 -0
- package/dist/skills/library.d.ts.map +1 -0
- package/dist/skills/library.js +173 -0
- package/dist/skills/library.js.map +1 -0
- package/dist/skills/starters.d.ts +3 -0
- package/dist/skills/starters.d.ts.map +1 -0
- package/dist/skills/starters.js +381 -0
- package/dist/skills/starters.js.map +1 -0
- package/dist/skills/types.d.ts +54 -0
- package/dist/skills/types.d.ts.map +1 -0
- package/dist/skills/types.js +2 -0
- package/dist/skills/types.js.map +1 -0
- package/dist/solvers/correction-loop.d.ts +34 -0
- package/dist/solvers/correction-loop.d.ts.map +1 -0
- package/dist/solvers/correction-loop.js +52 -0
- package/dist/solvers/correction-loop.js.map +1 -0
- package/dist/solvers/prolog-solver.d.ts +3 -0
- package/dist/solvers/prolog-solver.d.ts.map +1 -0
- package/dist/solvers/prolog-solver.js +93 -0
- package/dist/solvers/prolog-solver.js.map +1 -0
- package/dist/solvers/session.d.ts +11 -0
- package/dist/solvers/session.d.ts.map +1 -0
- package/dist/solvers/session.js +25 -0
- package/dist/solvers/session.js.map +1 -0
- package/dist/solvers/types.d.ts +44 -0
- package/dist/solvers/types.d.ts.map +1 -0
- package/dist/solvers/types.js +2 -0
- package/dist/solvers/types.js.map +1 -0
- package/dist/solvers/z3-solver.d.ts +3 -0
- package/dist/solvers/z3-solver.d.ts.map +1 -0
- package/dist/solvers/z3-solver.js +81 -0
- package/dist/solvers/z3-solver.js.map +1 -0
- package/package.json +85 -0
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
const PROMOTION_THRESHOLD = 3;
|
|
2
|
+
const PROMOTION_SUCCESS_RATE = 0.6;
|
|
3
|
+
const DEDUP_SIMILARITY_THRESHOLD = 0.7;
|
|
4
|
+
const EXTRACT_SYSTEM = `You are a template extraction engine. Given a verified formal specification and the problem it solved, extract a REUSABLE template.
|
|
5
|
+
|
|
6
|
+
Your job:
|
|
7
|
+
1. Identify which parts are problem-specific (concrete values) vs structural (the pattern)
|
|
8
|
+
2. Replace concrete values with {{SLOT:name}} markers
|
|
9
|
+
3. Name and describe each slot
|
|
10
|
+
4. Write a general signature that describes the class of problems this template solves
|
|
11
|
+
5. Suggest normalization recipes for common input formats
|
|
12
|
+
|
|
13
|
+
Return a JSON object with these fields:
|
|
14
|
+
{
|
|
15
|
+
"name": "kebab-case-name",
|
|
16
|
+
"domain": "one of: authorization, configuration, dependency, validation, rules, analysis",
|
|
17
|
+
"signature": "Natural language description of what class of problems this solves",
|
|
18
|
+
"slots": [{ "name": "slot_name", "description": "what goes here", "format": "example" }],
|
|
19
|
+
"normalizations": [{ "source": "input format", "transform": "how to map it" }],
|
|
20
|
+
"skeleton": "the template with {{SLOT:name}} markers"
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
Return ONLY valid JSON, no markdown fences, no explanation.`;
|
|
24
|
+
export class SkillLearner {
|
|
25
|
+
library;
|
|
26
|
+
llm;
|
|
27
|
+
constructor(library, llm) {
|
|
28
|
+
this.library = library;
|
|
29
|
+
this.llm = llm;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Extract a reusable template from a verified solution.
|
|
33
|
+
* Returns the template if accepted, null if rejected (duplicate or invalid).
|
|
34
|
+
*/
|
|
35
|
+
async extractTemplate(solver, verifiedSpec, problemDescription) {
|
|
36
|
+
const response = await this.llm.complete(EXTRACT_SYSTEM, [
|
|
37
|
+
{
|
|
38
|
+
role: "user",
|
|
39
|
+
content: `SOLVER: ${solver}
|
|
40
|
+
VERIFIED SPECIFICATION:
|
|
41
|
+
${verifiedSpec}
|
|
42
|
+
|
|
43
|
+
PROBLEM DESCRIPTION: ${problemDescription}
|
|
44
|
+
|
|
45
|
+
Extract a reusable template from this verified solution.`,
|
|
46
|
+
},
|
|
47
|
+
]);
|
|
48
|
+
// Parse LLM response
|
|
49
|
+
const cleaned = response
|
|
50
|
+
.replace(/^```(?:json)?\n?/gm, "")
|
|
51
|
+
.replace(/^```\n?/gm, "")
|
|
52
|
+
.trim();
|
|
53
|
+
let parsed;
|
|
54
|
+
try {
|
|
55
|
+
parsed = JSON.parse(cleaned);
|
|
56
|
+
}
|
|
57
|
+
catch {
|
|
58
|
+
return null;
|
|
59
|
+
}
|
|
60
|
+
// Validate required fields
|
|
61
|
+
if (typeof parsed.name !== "string" ||
|
|
62
|
+
typeof parsed.domain !== "string" ||
|
|
63
|
+
typeof parsed.signature !== "string" ||
|
|
64
|
+
typeof parsed.skeleton !== "string" ||
|
|
65
|
+
!Array.isArray(parsed.slots) ||
|
|
66
|
+
!Array.isArray(parsed.normalizations)) {
|
|
67
|
+
return null;
|
|
68
|
+
}
|
|
69
|
+
const template = {
|
|
70
|
+
name: parsed.name,
|
|
71
|
+
domain: parsed.domain,
|
|
72
|
+
solver,
|
|
73
|
+
signature: parsed.signature,
|
|
74
|
+
skeleton: parsed.skeleton,
|
|
75
|
+
slots: parsed.slots.filter((s) => typeof s.name === "string" &&
|
|
76
|
+
typeof s.description === "string" &&
|
|
77
|
+
typeof s.format === "string"),
|
|
78
|
+
normalizations: parsed.normalizations.filter((n) => typeof n.source === "string" && typeof n.transform === "string"),
|
|
79
|
+
};
|
|
80
|
+
// Check for duplicates
|
|
81
|
+
if (this.isDuplicate(template)) {
|
|
82
|
+
return null;
|
|
83
|
+
}
|
|
84
|
+
// Add to library as candidate (not promoted)
|
|
85
|
+
this.library.addLearned(template);
|
|
86
|
+
return template;
|
|
87
|
+
}
|
|
88
|
+
/** Check promotions: promote candidates with sufficient reuse and success rate */
|
|
89
|
+
checkPromotions() {
|
|
90
|
+
const all = this.library.list();
|
|
91
|
+
for (const item of all) {
|
|
92
|
+
if (item.metadata.promoted)
|
|
93
|
+
continue;
|
|
94
|
+
if (item.metadata.reuseCount < PROMOTION_THRESHOLD)
|
|
95
|
+
continue;
|
|
96
|
+
const successRate = item.metadata.reuseCount > 0
|
|
97
|
+
? item.metadata.successCount / item.metadata.reuseCount
|
|
98
|
+
: 0;
|
|
99
|
+
if (successRate >= PROMOTION_SUCCESS_RATE) {
|
|
100
|
+
this.library.promote(item.template.name);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
/** Check if a template is too similar to an existing one */
|
|
105
|
+
isDuplicate(candidate) {
|
|
106
|
+
const results = this.library.search(candidate.signature, { limit: 3 });
|
|
107
|
+
for (const result of results) {
|
|
108
|
+
if (this.textSimilarity(candidate.signature, result.template.signature) > DEDUP_SIMILARITY_THRESHOLD) {
|
|
109
|
+
return true;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
return false;
|
|
113
|
+
}
|
|
114
|
+
/** Simple word-overlap similarity (Jaccard) for dedup */
|
|
115
|
+
textSimilarity(a, b) {
|
|
116
|
+
const wordsA = new Set(a.toLowerCase().split(/\s+/));
|
|
117
|
+
const wordsB = new Set(b.toLowerCase().split(/\s+/));
|
|
118
|
+
const intersection = [...wordsA].filter((w) => wordsB.has(w)).length;
|
|
119
|
+
const union = new Set([...wordsA, ...wordsB]).size;
|
|
120
|
+
return union === 0 ? 0 : intersection / union;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
//# sourceMappingURL=learner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"learner.js","sourceRoot":"","sources":["../../src/skills/learner.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { SkillTemplate, SkillMetadata, SkillWithMetadata, SkillSearchResult } from "./types.js";
|
|
2
|
+
import type { SolverType } from "../solvers/types.js";
|
|
3
|
+
export interface SearchOptions {
|
|
4
|
+
domain?: string;
|
|
5
|
+
solver?: SolverType;
|
|
6
|
+
limit?: number;
|
|
7
|
+
}
|
|
8
|
+
export declare class SkillLibrary {
|
|
9
|
+
private db;
|
|
10
|
+
private templates;
|
|
11
|
+
private searchIndex;
|
|
12
|
+
private templateOrder;
|
|
13
|
+
private constructor();
|
|
14
|
+
static create(basePath: string): Promise<SkillLibrary>;
|
|
15
|
+
/** List all templates with metadata */
|
|
16
|
+
list(): SkillWithMetadata[];
|
|
17
|
+
/** Get a single template by name */
|
|
18
|
+
get(name: string): SkillWithMetadata | null;
|
|
19
|
+
/** Search templates by natural language query */
|
|
20
|
+
search(query: string, options?: SearchOptions): SkillSearchResult[];
|
|
21
|
+
/** Record a template use (success or failure) */
|
|
22
|
+
recordUse(name: string, success: boolean): void;
|
|
23
|
+
/** Get metadata for a template */
|
|
24
|
+
getMetadata(name: string): SkillMetadata | null;
|
|
25
|
+
/** Add a learned (candidate) template to the library. Returns false if name already exists. */
|
|
26
|
+
addLearned(template: SkillTemplate): boolean;
|
|
27
|
+
/** Promote a candidate template to full status */
|
|
28
|
+
promote(name: string): void;
|
|
29
|
+
/** Remove a template from the library */
|
|
30
|
+
remove(name: string): void;
|
|
31
|
+
/** Close the database connection */
|
|
32
|
+
close(): void;
|
|
33
|
+
private rebuildSearchIndex;
|
|
34
|
+
private loadMetadata;
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=library.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"library.d.ts","sourceRoot":"","sources":["../../src/skills/library.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EACV,aAAa,EACb,aAAa,EACb,iBAAiB,EACjB,iBAAiB,EAClB,MAAM,YAAY,CAAC;AACpB,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAEtD,MAAM,WAAW,aAAa;IAC5B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,UAAU,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,qBAAa,YAAY;IACvB,OAAO,CAAC,EAAE,CAAoB;IAC9B,OAAO,CAAC,SAAS,CAA6B;IAC9C,OAAO,CAAC,WAAW,CAAY;IAC/B,OAAO,CAAC,aAAa,CAAW;IAEhC,OAAO;WAmBM,MAAM,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC;IAiC5D,uCAAuC;IACvC,IAAI,IAAI,iBAAiB,EAAE;IAO3B,oCAAoC;IACpC,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,iBAAiB,GAAG,IAAI;IAM3C,iDAAiD;IACjD,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,GAAE,aAAkB,GAAG,iBAAiB,EAAE;IAyBvE,iDAAiD;IACjD,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,IAAI;IAY/C,kCAAkC;IAClC,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,aAAa,GAAG,IAAI;IAI/C,+FAA+F;IAC/F,UAAU,CAAC,QAAQ,EAAE,aAAa,GAAG,OAAO;IAmB5C,kDAAkD;IAClD,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAM3B,yCAAyC;IACzC,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAM1B,oCAAoC;IACpC,KAAK,IAAI,IAAI;IAIb,OAAO,CAAC,kBAAkB;IAe1B,OAAO,CAAC,YAAY;CAuBrB"}
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
import Database from "better-sqlite3";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
import { mkdirSync } from "node:fs";
|
|
4
|
+
import { STARTER_TEMPLATES } from "./starters.js";
|
|
5
|
+
import { buildIndex, search } from "./bm25.js";
|
|
6
|
+
export class SkillLibrary {
|
|
7
|
+
db;
|
|
8
|
+
templates;
|
|
9
|
+
searchIndex;
|
|
10
|
+
templateOrder; // maps BM25 doc index to template name
|
|
11
|
+
constructor(db, templates) {
|
|
12
|
+
this.db = db;
|
|
13
|
+
this.templates = templates;
|
|
14
|
+
// Build search index from template text
|
|
15
|
+
this.templateOrder = [...templates.keys()];
|
|
16
|
+
const searchTexts = this.templateOrder.map((name) => {
|
|
17
|
+
const t = templates.get(name);
|
|
18
|
+
return [
|
|
19
|
+
t.name,
|
|
20
|
+
t.domain,
|
|
21
|
+
t.signature,
|
|
22
|
+
...t.slots.map((s) => s.description),
|
|
23
|
+
...t.normalizations.map((n) => `${n.source} ${n.transform}`),
|
|
24
|
+
].join(" ");
|
|
25
|
+
});
|
|
26
|
+
this.searchIndex = buildIndex(searchTexts);
|
|
27
|
+
}
|
|
28
|
+
static async create(basePath) {
|
|
29
|
+
mkdirSync(basePath, { recursive: true });
|
|
30
|
+
const dbPath = join(basePath, "chiasmus.db");
|
|
31
|
+
const db = new Database(dbPath);
|
|
32
|
+
db.pragma("journal_mode = WAL");
|
|
33
|
+
db.exec(`
|
|
34
|
+
CREATE TABLE IF NOT EXISTS skill_metadata (
|
|
35
|
+
name TEXT PRIMARY KEY,
|
|
36
|
+
reuse_count INTEGER NOT NULL DEFAULT 0,
|
|
37
|
+
success_count INTEGER NOT NULL DEFAULT 0,
|
|
38
|
+
last_used TEXT,
|
|
39
|
+
promoted INTEGER NOT NULL DEFAULT 0
|
|
40
|
+
)
|
|
41
|
+
`);
|
|
42
|
+
// Load starter templates and ensure metadata rows exist
|
|
43
|
+
const templates = new Map();
|
|
44
|
+
const upsert = db.prepare(`
|
|
45
|
+
INSERT INTO skill_metadata (name, promoted)
|
|
46
|
+
VALUES (?, 1)
|
|
47
|
+
ON CONFLICT(name) DO NOTHING
|
|
48
|
+
`);
|
|
49
|
+
for (const t of STARTER_TEMPLATES) {
|
|
50
|
+
templates.set(t.name, t);
|
|
51
|
+
upsert.run(t.name);
|
|
52
|
+
}
|
|
53
|
+
return new SkillLibrary(db, templates);
|
|
54
|
+
}
|
|
55
|
+
/** List all templates with metadata */
|
|
56
|
+
list() {
|
|
57
|
+
return [...this.templates.values()].map((t) => ({
|
|
58
|
+
template: t,
|
|
59
|
+
metadata: this.loadMetadata(t.name),
|
|
60
|
+
}));
|
|
61
|
+
}
|
|
62
|
+
/** Get a single template by name */
|
|
63
|
+
get(name) {
|
|
64
|
+
const t = this.templates.get(name);
|
|
65
|
+
if (!t)
|
|
66
|
+
return null;
|
|
67
|
+
return { template: t, metadata: this.loadMetadata(name) };
|
|
68
|
+
}
|
|
69
|
+
/** Search templates by natural language query */
|
|
70
|
+
search(query, options = {}) {
|
|
71
|
+
const limit = options.limit ?? 10;
|
|
72
|
+
const hits = search(this.searchIndex, query, this.templates.size);
|
|
73
|
+
const results = [];
|
|
74
|
+
for (const hit of hits) {
|
|
75
|
+
const name = this.templateOrder[hit.docIndex];
|
|
76
|
+
const t = this.templates.get(name);
|
|
77
|
+
if (!t)
|
|
78
|
+
continue;
|
|
79
|
+
if (options.domain && t.domain !== options.domain)
|
|
80
|
+
continue;
|
|
81
|
+
if (options.solver && t.solver !== options.solver)
|
|
82
|
+
continue;
|
|
83
|
+
results.push({
|
|
84
|
+
template: t,
|
|
85
|
+
metadata: this.loadMetadata(name),
|
|
86
|
+
score: hit.score,
|
|
87
|
+
});
|
|
88
|
+
if (results.length >= limit)
|
|
89
|
+
break;
|
|
90
|
+
}
|
|
91
|
+
return results;
|
|
92
|
+
}
|
|
93
|
+
/** Record a template use (success or failure) */
|
|
94
|
+
recordUse(name, success) {
|
|
95
|
+
this.db
|
|
96
|
+
.prepare(`UPDATE skill_metadata
|
|
97
|
+
SET reuse_count = reuse_count + 1,
|
|
98
|
+
success_count = success_count + CASE WHEN ? THEN 1 ELSE 0 END,
|
|
99
|
+
last_used = datetime('now')
|
|
100
|
+
WHERE name = ?`)
|
|
101
|
+
.run(success ? 1 : 0, name);
|
|
102
|
+
}
|
|
103
|
+
/** Get metadata for a template */
|
|
104
|
+
getMetadata(name) {
|
|
105
|
+
return this.loadMetadata(name);
|
|
106
|
+
}
|
|
107
|
+
/** Add a learned (candidate) template to the library. Returns false if name already exists. */
|
|
108
|
+
addLearned(template) {
|
|
109
|
+
if (this.templates.has(template.name)) {
|
|
110
|
+
return false; // don't overwrite existing templates
|
|
111
|
+
}
|
|
112
|
+
this.templates.set(template.name, template);
|
|
113
|
+
this.db
|
|
114
|
+
.prepare(`INSERT INTO skill_metadata (name, promoted)
|
|
115
|
+
VALUES (?, 0)
|
|
116
|
+
ON CONFLICT(name) DO NOTHING`)
|
|
117
|
+
.run(template.name);
|
|
118
|
+
this.rebuildSearchIndex();
|
|
119
|
+
return true;
|
|
120
|
+
}
|
|
121
|
+
/** Promote a candidate template to full status */
|
|
122
|
+
promote(name) {
|
|
123
|
+
this.db
|
|
124
|
+
.prepare("UPDATE skill_metadata SET promoted = 1 WHERE name = ?")
|
|
125
|
+
.run(name);
|
|
126
|
+
}
|
|
127
|
+
/** Remove a template from the library */
|
|
128
|
+
remove(name) {
|
|
129
|
+
this.templates.delete(name);
|
|
130
|
+
this.db.prepare("DELETE FROM skill_metadata WHERE name = ?").run(name);
|
|
131
|
+
this.rebuildSearchIndex();
|
|
132
|
+
}
|
|
133
|
+
/** Close the database connection */
|
|
134
|
+
close() {
|
|
135
|
+
this.db.close();
|
|
136
|
+
}
|
|
137
|
+
rebuildSearchIndex() {
|
|
138
|
+
this.templateOrder = [...this.templates.keys()];
|
|
139
|
+
const searchTexts = this.templateOrder.map((name) => {
|
|
140
|
+
const t = this.templates.get(name);
|
|
141
|
+
return [
|
|
142
|
+
t.name,
|
|
143
|
+
t.domain,
|
|
144
|
+
t.signature,
|
|
145
|
+
...t.slots.map((s) => s.description),
|
|
146
|
+
...t.normalizations.map((n) => `${n.source} ${n.transform}`),
|
|
147
|
+
].join(" ");
|
|
148
|
+
});
|
|
149
|
+
this.searchIndex = buildIndex(searchTexts);
|
|
150
|
+
}
|
|
151
|
+
loadMetadata(name) {
|
|
152
|
+
const row = this.db
|
|
153
|
+
.prepare("SELECT * FROM skill_metadata WHERE name = ?")
|
|
154
|
+
.get(name);
|
|
155
|
+
if (!row) {
|
|
156
|
+
return {
|
|
157
|
+
name,
|
|
158
|
+
reuseCount: 0,
|
|
159
|
+
successCount: 0,
|
|
160
|
+
lastUsed: null,
|
|
161
|
+
promoted: false,
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
return {
|
|
165
|
+
name: row.name,
|
|
166
|
+
reuseCount: row.reuse_count,
|
|
167
|
+
successCount: row.success_count,
|
|
168
|
+
lastUsed: row.last_used,
|
|
169
|
+
promoted: !!row.promoted,
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
//# sourceMappingURL=library.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"library.js","sourceRoot":"","sources":["../../src/skills/library.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"starters.d.ts","sourceRoot":"","sources":["../../src/skills/starters.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAEhD,eAAO,MAAM,iBAAiB,EAAE,aAAa,EAqZ5C,CAAC"}
|