@aitos/core 1.0.0 → 1.0.1

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,408 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.TelemetryStore = exports.AtomRegistryImpl = exports.Store = exports.AitosRuntime = void 0;
4
+ class Store {
5
+ constructor() {
6
+ this.data = new Map();
7
+ }
8
+ get(key) {
9
+ return this.data.get(key);
10
+ }
11
+ set(key, value) {
12
+ this.data.set(key, value);
13
+ }
14
+ has(key) {
15
+ return this.data.has(key);
16
+ }
17
+ delete(key) {
18
+ this.data.delete(key);
19
+ }
20
+ clear() {
21
+ this.data.clear();
22
+ }
23
+ }
24
+ exports.Store = Store;
25
+ class TelemetryStore {
26
+ constructor() {
27
+ this.atoms = new Map();
28
+ }
29
+ record(atom, graphName, duration, success) {
30
+ let entry = this.atoms.get(atom);
31
+ if (!entry) {
32
+ entry = { count: 0, totalDuration: 0, maxDuration: 0, errorCount: 0, lastCalled: 0, graphs: new Set() };
33
+ this.atoms.set(atom, entry);
34
+ }
35
+ entry.count++;
36
+ entry.totalDuration += duration;
37
+ if (duration > entry.maxDuration)
38
+ entry.maxDuration = duration;
39
+ if (!success)
40
+ entry.errorCount++;
41
+ entry.lastCalled = Date.now();
42
+ entry.graphs.add(graphName);
43
+ }
44
+ getStats() {
45
+ const result = [];
46
+ for (const [atom, data] of this.atoms) {
47
+ result.push({
48
+ atom,
49
+ count: data.count,
50
+ avgDuration: data.count > 0 ? Math.round(data.totalDuration / data.count) : 0,
51
+ maxDuration: data.maxDuration,
52
+ errorCount: data.errorCount,
53
+ errorRate: data.count > 0 ? Math.round((data.errorCount / data.count) * 10000) / 100 : 0,
54
+ lastCalled: data.lastCalled,
55
+ graphs: Array.from(data.graphs),
56
+ });
57
+ }
58
+ result.sort((a, b) => b.count - a.count);
59
+ return result;
60
+ }
61
+ reset() {
62
+ this.atoms.clear();
63
+ }
64
+ }
65
+ exports.TelemetryStore = TelemetryStore;
66
+ class AtomRegistryImpl {
67
+ constructor() {
68
+ this.atoms = new Map();
69
+ }
70
+ register(atom) {
71
+ const key = `${atom.name}@${atom.version}`;
72
+ this.atoms.set(key, atom);
73
+ this.atoms.set(atom.name, atom);
74
+ }
75
+ get(name) {
76
+ return this.atoms.get(name);
77
+ }
78
+ has(name) {
79
+ return this.atoms.has(name);
80
+ }
81
+ list() {
82
+ const result = [];
83
+ const seen = new Set();
84
+ for (const [key, atom] of this.atoms.entries()) {
85
+ if (!seen.has(atom.name)) {
86
+ seen.add(atom.name);
87
+ result.push(atom.name);
88
+ }
89
+ }
90
+ return result;
91
+ }
92
+ }
93
+ exports.AtomRegistryImpl = AtomRegistryImpl;
94
+ class AitosRuntime {
95
+ constructor() {
96
+ this.atoms = new Map();
97
+ this.telemetryStore = new TelemetryStore();
98
+ this.telemetryHistory = [];
99
+ }
100
+ register(atom) {
101
+ const key = `${atom.name}@${atom.version}`;
102
+ this.atoms.set(key, atom);
103
+ this.atoms.set(atom.name, atom);
104
+ }
105
+ validateGraph(graph) {
106
+ const errors = [];
107
+ this.validateGraphNodes(graph.nodes, graph.order, errors);
108
+ return { valid: errors.length === 0, errors: errors.map(e => JSON.stringify(e)) };
109
+ }
110
+ validateGraphNodes(nodes, order, errors, path = '', parentExecuted) {
111
+ const executed = parentExecuted ? new Set(parentExecuted) : new Set();
112
+ for (const nodeId of order) {
113
+ const node = nodes[nodeId];
114
+ if (!node) {
115
+ errors.push({
116
+ node: path,
117
+ code: 'NODE_NOT_FOUND',
118
+ param: '',
119
+ ref: nodeId,
120
+ message: `Node "${nodeId}" not found in nodes`
121
+ });
122
+ continue;
123
+ }
124
+ const nodePath = path ? `${path}.${nodeId}` : nodeId;
125
+ if (!node.atom) {
126
+ errors.push({ node: nodePath, code: 'MISSING_ATOM', param: '', ref: '', message: 'Missing atom field' });
127
+ continue;
128
+ }
129
+ if (typeof node.atom !== 'string') {
130
+ errors.push({ node: nodePath, code: 'INVALID_ATOM_TYPE', param: '', ref: '', message: 'Atom must be a string' });
131
+ continue;
132
+ }
133
+ if (!this.atoms.has(node.atom)) {
134
+ errors.push({ node: nodePath, code: 'ATOM_NOT_FOUND', param: '', ref: '', message: `Atom "${node.atom}" not registered` });
135
+ }
136
+ this.validateGraphReferences(node, executed, errors, nodePath, nodes);
137
+ if (node.nodes && typeof node.nodes === 'object' && 'order' in node.nodes) {
138
+ const subGraph = node.nodes;
139
+ if (subGraph.nodes && subGraph.order) {
140
+ this.validateGraphNodes(subGraph.nodes, subGraph.order, errors, `${nodePath}.nodes`, executed);
141
+ }
142
+ }
143
+ if (node.then && typeof node.then === 'object' && 'order' in node.then) {
144
+ const subGraph = node.then;
145
+ if (subGraph.nodes && subGraph.order) {
146
+ this.validateGraphNodes(subGraph.nodes, subGraph.order, errors, `${nodePath}.then`, executed);
147
+ }
148
+ }
149
+ if (node.else && typeof node.else === 'object' && 'order' in node.else) {
150
+ const subGraph = node.else;
151
+ if (subGraph.nodes && subGraph.order) {
152
+ this.validateGraphNodes(subGraph.nodes, subGraph.order, errors, `${nodePath}.else`, executed);
153
+ }
154
+ }
155
+ executed.add(nodeId);
156
+ }
157
+ }
158
+ validateGraphReferences(node, executed, errors, nodePath, nodes) {
159
+ for (const [key, value] of Object.entries(node)) {
160
+ if (['atom', 'nodes', 'then', 'else'].includes(key))
161
+ continue;
162
+ if (typeof value === 'string') {
163
+ const matches = value.matchAll(/\{\{(\w+)(?:\.(.+?))?\}\}/g);
164
+ for (const match of matches) {
165
+ const refId = match[1];
166
+ if (!executed.has(refId) && !nodes[refId]) {
167
+ const suggestions = this.generateGraphSuggestions(executed, nodes);
168
+ errors.push({
169
+ node: nodePath,
170
+ code: 'INVALID_REFERENCE',
171
+ param: key,
172
+ ref: refId,
173
+ message: `Invalid reference {{${refId}}}: node not found or not yet executed`,
174
+ suggestions
175
+ });
176
+ }
177
+ }
178
+ }
179
+ }
180
+ }
181
+ generateGraphSuggestions(executed, nodes) {
182
+ const suggestions = [];
183
+ for (const nodeId of executed) {
184
+ if (suggestions.length >= 5)
185
+ break;
186
+ const node = nodes[nodeId];
187
+ if (node) {
188
+ const atom = this.atoms.get(node.atom);
189
+ suggestions.push({
190
+ id: nodeId,
191
+ type: atom?.meta.output.type || 'unknown',
192
+ source: node.atom
193
+ });
194
+ }
195
+ }
196
+ return suggestions;
197
+ }
198
+ async executeGraph(graph, context, outerScope, graphName) {
199
+ const results = outerScope ? { ...outerScope } : {};
200
+ const gName = graphName || 'unknown';
201
+ const previousScope = context.currentScope;
202
+ context.currentScope = results;
203
+ context.runtime = this;
204
+ for (const nodeId of graph.order) {
205
+ const node = graph.nodes[nodeId];
206
+ const input = this.resolveGraphInput(node, results, context);
207
+ const startTime = performance.now();
208
+ const result = await context.execute(node.atom, input);
209
+ const duration = Math.round(performance.now() - startTime);
210
+ this.telemetryStore.record(node.atom, gName, duration, result.success);
211
+ if (!result.success) {
212
+ context.currentScope = previousScope;
213
+ throw new Error(JSON.stringify({ node: nodeId, atom: node.atom, error: result.error }));
214
+ }
215
+ results[nodeId] = result.data;
216
+ }
217
+ context.currentScope = previousScope;
218
+ return results;
219
+ }
220
+ onSnapshot(callback) {
221
+ this.snapshotCallback = callback;
222
+ }
223
+ flushTelemetry() {
224
+ const stats = this.telemetryStore.getStats();
225
+ const snapshot = { timestamp: Date.now(), stats };
226
+ this.telemetryHistory.push(snapshot);
227
+ if (this.telemetryHistory.length > 100) {
228
+ this.telemetryHistory.shift();
229
+ }
230
+ this.snapshotCallback?.(snapshot);
231
+ return snapshot;
232
+ }
233
+ getTelemetryHistory() {
234
+ return this.telemetryHistory;
235
+ }
236
+ restoreTelemetryHistory(history) {
237
+ this.telemetryHistory = history.slice(-100);
238
+ }
239
+ resolveGraphInput(node, results, context) {
240
+ const resolved = {};
241
+ const SUBGRAPH_KEYS = new Set(['nodes', 'then', 'else']);
242
+ for (const [key, value] of Object.entries(node)) {
243
+ if (key === 'atom')
244
+ continue;
245
+ if (SUBGRAPH_KEYS.has(key)) {
246
+ resolved[key] = value;
247
+ }
248
+ else {
249
+ resolved[key] = this.resolveGraphValue(value, results, context);
250
+ }
251
+ }
252
+ return resolved;
253
+ }
254
+ resolveGraphValue(value, results, context) {
255
+ if (typeof value === 'string') {
256
+ const ESCAPE_PLACEHOLDER = '\x00ESCAPED_BRACE\x00';
257
+ let processedValue = value.replace(/\\{{/g, ESCAPE_PLACEHOLDER);
258
+ const match = processedValue.match(/^\{\{(\w+)(?:\.(.+?))?\}\}$/);
259
+ if (match) {
260
+ const nodeId = match[1];
261
+ const field = match[2];
262
+ let resolvedValue;
263
+ if (nodeId in results) {
264
+ resolvedValue = results[nodeId];
265
+ }
266
+ else if (context.store.has(nodeId)) {
267
+ resolvedValue = context.store.get(nodeId);
268
+ }
269
+ else {
270
+ throw new Error(JSON.stringify({
271
+ code: 'REFERENCE_NOT_FOUND',
272
+ ref: nodeId,
273
+ message: `Reference {{${nodeId}}} not found in current scope or store`,
274
+ availableInScope: Object.keys(results),
275
+ availableInStore: context.store.has(nodeId) ? [nodeId] : [],
276
+ hint: 'Check if the reference is a node output or a store value.',
277
+ fix: `Ensure the node "${nodeId}" is executed before this reference, or use { "atom": "set", "key": "${nodeId}", "value": ... } to store the value.`
278
+ }));
279
+ }
280
+ if (field) {
281
+ return this.getFieldValue(resolvedValue, field);
282
+ }
283
+ return resolvedValue;
284
+ }
285
+ const result = processedValue.replace(/\{\{(\w+)(?:\.(.+?))?\}\}/g, (_, nodeId, field) => {
286
+ let resolvedValue;
287
+ if (nodeId in results) {
288
+ resolvedValue = results[nodeId];
289
+ }
290
+ else if (context.store.has(nodeId)) {
291
+ resolvedValue = context.store.get(nodeId);
292
+ }
293
+ else {
294
+ throw new Error(JSON.stringify({
295
+ code: 'REFERENCE_NOT_FOUND',
296
+ ref: nodeId,
297
+ message: `Reference {{${nodeId}}} not found in current scope or store`,
298
+ availableInScope: Object.keys(results),
299
+ availableInStore: context.store.has(nodeId) ? [nodeId] : [],
300
+ hint: 'Check if the reference is a node output or a store value.',
301
+ fix: `Ensure the node "${nodeId}" is executed before this reference, or use { "atom": "set", "key": "${nodeId}", "value": ... } to store the value.`
302
+ }));
303
+ }
304
+ if (field) {
305
+ return this.getFieldValue(resolvedValue, field);
306
+ }
307
+ return resolvedValue;
308
+ });
309
+ return result.replace(new RegExp(ESCAPE_PLACEHOLDER, 'g'), '{{');
310
+ }
311
+ if (Array.isArray(value)) {
312
+ return value.map(item => this.resolveGraphValue(item, results, context));
313
+ }
314
+ if (typeof value === 'object' && value !== null) {
315
+ const resolved = {};
316
+ for (const [k, v] of Object.entries(value)) {
317
+ resolved[k] = this.resolveGraphValue(v, results, context);
318
+ }
319
+ return resolved;
320
+ }
321
+ return value;
322
+ }
323
+ getFieldValue(obj, field) {
324
+ const parts = field.split('.');
325
+ let current = obj;
326
+ for (const part of parts) {
327
+ if (current === undefined || current === null)
328
+ return undefined;
329
+ current = current[part];
330
+ }
331
+ return current;
332
+ }
333
+ listAtoms() {
334
+ const result = [];
335
+ const seen = new Set();
336
+ for (const [key, atom] of this.atoms.entries()) {
337
+ if (!seen.has(atom.name)) {
338
+ seen.add(atom.name);
339
+ result.push(atom);
340
+ }
341
+ }
342
+ return result;
343
+ }
344
+ getSkillSet() {
345
+ const atoms = this.listAtoms();
346
+ const registry = {
347
+ aitos: {
348
+ version: '1.0.0',
349
+ type: 'graph-instruction-set',
350
+ },
351
+ graph: {
352
+ format: {
353
+ nodes: 'Record<nodeId, GraphNode>',
354
+ order: 'string[] (execution order)'
355
+ },
356
+ example: {
357
+ nodes: {
358
+ getY: { atom: 'get', key: 'fruitY' },
359
+ addFive: { atom: 'add', a: '{{getY}}', b: 5 },
360
+ saveY: { atom: 'set', key: 'fruitY', value: '{{addFive}}' }
361
+ },
362
+ order: ['getY', 'addFive', 'saveY']
363
+ }
364
+ },
365
+ node: {
366
+ format: { atom: 'string', '...params': 'per atom.input' },
367
+ example: { atom: 'add', a: '{{otherNodeId}}', b: 1 }
368
+ },
369
+ ref: {
370
+ format: '{{nodeId}} or {{nodeId.field}}',
371
+ rules: [
372
+ 'Use nodeId to reference another node result',
373
+ 'nodeId must be defined in nodes and appear earlier in order',
374
+ 'Use {{nodeId.field}} to access nested properties',
375
+ 'References are resolved before execution'
376
+ ]
377
+ },
378
+ atoms: atoms.map(a => ({
379
+ name: a.name,
380
+ version: a.version,
381
+ input: a.meta.input,
382
+ output: a.meta.output,
383
+ })),
384
+ validation: {
385
+ description: 'Validation checks node references and atom existence',
386
+ errorFormat: {
387
+ node: 'Node path',
388
+ code: 'Error code',
389
+ param: 'Parameter name',
390
+ ref: 'Invalid reference',
391
+ message: 'Error description',
392
+ suggestions: [
393
+ { id: 'Suggested nodeId', type: 'Output type', source: 'Atom name' }
394
+ ]
395
+ }
396
+ }
397
+ };
398
+ return JSON.stringify(registry);
399
+ }
400
+ getTelemetryStats() {
401
+ return this.telemetryStore.getStats();
402
+ }
403
+ resetTelemetry() {
404
+ this.telemetryStore.reset();
405
+ }
406
+ }
407
+ exports.AitosRuntime = AitosRuntime;
408
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicnVudGltZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9ydW50aW1lLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUVBLE1BQU0sS0FBSztJQUFYO1FBQ1UsU0FBSSxHQUFxQixJQUFJLEdBQUcsRUFBRSxDQUFDO0lBcUI3QyxDQUFDO0lBbkJDLEdBQUcsQ0FBQyxHQUFXO1FBQ2IsT0FBTyxJQUFJLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQztJQUM1QixDQUFDO0lBRUQsR0FBRyxDQUFDLEdBQVcsRUFBRSxLQUFVO1FBQ3pCLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsRUFBRSxLQUFLLENBQUMsQ0FBQztJQUM1QixDQUFDO0lBRUQsR0FBRyxDQUFDLEdBQVc7UUFDYixPQUFPLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0lBQzVCLENBQUM7SUFFRCxNQUFNLENBQUMsR0FBVztRQUNoQixJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQztJQUN4QixDQUFDO0lBRUQsS0FBSztRQUNILElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxFQUFFLENBQUM7SUFDcEIsQ0FBQztDQUNGO0FBc2JRLHNCQUFLO0FBcGJkLE1BQU0sY0FBYztJQUFwQjtRQUNVLFVBQUssR0FPUixJQUFJLEdBQUcsRUFBRSxDQUFDO0lBcUNqQixDQUFDO0lBbkNDLE1BQU0sQ0FBQyxJQUFZLEVBQUUsU0FBaUIsRUFBRSxRQUFnQixFQUFFLE9BQWdCO1FBQ3hFLElBQUksS0FBSyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ2pDLElBQUksQ0FBQyxLQUFLLEVBQUUsQ0FBQztZQUNYLEtBQUssR0FBRyxFQUFFLEtBQUssRUFBRSxDQUFDLEVBQUUsYUFBYSxFQUFFLENBQUMsRUFBRSxXQUFXLEVBQUUs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RSxFQUFFLGtCQUFrQixFQUFFLElBQUksRUFBRSxhQUFhLEVBQUUsTUFBTSxFQUFFLFdBQVcsRUFBRTtxQkFDckU7aUJBQ0Y7YUFDRjtTQUNGLENBQUM7UUFFRixPQUFPLElBQUksQ0FBQyxTQUFTLENBQUMsUUFBUSxDQUFDLENBQUM7SUFDbEMsQ0FBQztJQUVELGlCQUFpQjtRQUNmLE9BQU8sSUFBSSxDQUFDLGNBQWMsQ0FBQyxRQUFRLEVBQUUsQ0FBQztJQUN4QyxDQUFDO0lBRUQsY0FBYztRQUNaLElBQUksQ0FBQyxjQUFjLENBQUMsS0FBSyxFQUFFLENBQUM7SUFDOUIsQ0FBQztDQUNGO0FBbldELG9DQW1XQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEF0b20sIENvbnRleHQsIFJlc3VsdCwgR3JhcGgsIEdyYXBoTm9kZSwgU2NvcGUsIEF0b21SZWdpc3RyeSwgR3JhcGhWYWxpZGF0aW9uRXJyb3IsIEdyYXBoU3VnZ2VzdGlvbiwgUnVudGltZSwgVGVsZW1ldHJ5U3RhdHMsIFRlbGVtZXRyeVNuYXBzaG90IH0gZnJvbSAnLi90eXBlcyc7XG5cbmNsYXNzIFN0b3JlIHtcbiAgcHJpdmF0ZSBkYXRhOiBNYXA8c3RyaW5nLCBhbnk+ID0gbmV3IE1hcCgpO1xuXG4gIGdldChrZXk6IHN0cmluZyk6IGFueSB7XG4gICAgcmV0dXJuIHRoaXMuZGF0YS5nZXQoa2V5KTtcbiAgfVxuXG4gIHNldChrZXk6IHN0cmluZywgdmFsdWU6IGFueSk6IHZvaWQge1xuICAgIHRoaXMuZGF0YS5zZXQoa2V5LCB2YWx1ZSk7XG4gIH1cblxuICBoYXMoa2V5OiBzdHJpbmcpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5kYXRhLmhhcyhrZXkpO1xuICB9XG5cbiAgZGVsZXRlKGtleTogc3RyaW5nKTogdm9pZCB7XG4gICAgdGhpcy5kYXRhLmRlbGV0ZShrZXkpO1xuICB9XG5cbiAgY2xlYXIoKTogdm9pZCB7XG4gICAgdGhpcy5kYXRhLmNsZWFyKCk7XG4gIH1cbn1cblxuY2xhc3MgVGVsZW1ldHJ5U3RvcmUge1xuICBwcml2YXRlIGF0b21zOiBNYXA8c3RyaW5nLCB7XG4gICAgY291bnQ6IG51bWJlcjtcbiAgICB0b3RhbER1cmF0aW9uOiBudW1iZXI7XG4gICAgbWF4RHVyYXRpb246IG51bWJlcjtcbiAgICBlcnJvckNvdW50OiBudW1iZXI7XG4gICAgbGFzdENhbGxlZDogbnVtYmVyO1xuICAgIGdyYXBoczogU2V0PHN0cmluZz47XG4gIH0+ID0gbmV3IE1hcCgpO1xuXG4gIHJlY29yZChhdG9tOiBzdHJpbmcsIGdyYXBoTmFtZTogc3RyaW5nLCBkdXJhdGlvbjogbnVtYmVyLCBzdWNjZXNzOiBib29sZWFuKTogdm9pZCB7XG4gICAgbGV0IGVudHJ5ID0gdGhpcy5hdG9tcy5nZXQoYXRvbSk7XG4gICAgaWYgKCFlbnRyeSkge1xuICAgICAgZW50cnkgPSB7IGNvdW50OiAwLCB0b3RhbER1cmF0aW9uOiAwLCBtYXhEdXJhdGlvbjogMCwgZXJyb3JDb3VudDogMCwgbGFzdENhbGxlZDogMCwgZ3JhcGhzOiBuZXcgU2V0KCkgfTtcbiAgICAgIHRoaXMuYXRvbXMuc2V0KGF0b20sIGVudHJ5KTtcbiAgICB9XG4gICAgZW50cnkuY291bnQrKztcbiAgICBlbnRyeS50b3RhbER1cmF0aW9uICs9IGR1cmF0aW9uO1xuICAgIGlmIChkdXJhdGlvbiA+IGVudHJ5Lm1heER1cmF0aW9uKSBlbnRyeS5tYXhEdXJhdGlvbiA9IGR1cmF0aW9uO1xuICAgIGlmICghc3VjY2VzcykgZW50cnkuZXJyb3JDb3VudCsrO1xuICAgIGVudHJ5Lmxhc3RDYWxsZWQgPSBEYXRlLm5vdygpO1xuICAgIGVudHJ5LmdyYXBocy5hZGQoZ3JhcGhOYW1lKTtcbiAgfVxuXG4gIGdldFN0YXRzKCk6IFRlbGVtZXRyeVN0YXRzW10ge1xuICAgIGNvbnN0IHJlc3VsdDogVGVsZW1ldHJ5U3RhdHNbXSA9IFtdO1xuICAgIGZvciAoY29uc3QgW2F0b20sIGRhdGFdIG9mIHRoaXMuYXRvbXMpIHtcbiAgICAgIHJlc3VsdC5wdXNoKHtcbiAgICAgICAgYXRvbSxcbiAgICAgICAgY291bnQ6IGRhdGEuY291bnQsXG4gICAgICAgIGF2Z0R1cmF0aW9uOiBkYXRhLmNvdW50ID4gMCA/IE1hdGgucm91bmQoZGF0YS50b3RhbER1cmF0aW9uIC8gZGF0YS5jb3VudCkgOiAwLFxuICAgICAgICBtYXhEdXJhdGlvbjogZGF0YS5tYXhEdXJhdGlvbixcbiAgICAgICAgZXJyb3JDb3VudDogZGF0YS5lcnJvckNvdW50LFxuICAgICAgICBlcnJvclJhdGU6IGRhdGEuY291bnQgPiAwID8gTWF0aC5yb3VuZCgoZGF0YS5lcnJvckNvdW50IC8gZGF0YS5jb3VudCkgKiAxMDAwMCkgLyAxMDAgOiAwLFxuICAgICAgICBsYXN0Q2FsbGVkOiBkYXRhLmxhc3RDYWxsZWQsXG4gICAgICAgIGdyYXBoczogQXJyYXkuZnJvbShkYXRhLmdyYXBocyksXG4gICAgICB9KTtcbiAgICB9XG4gICAgcmVzdWx0LnNvcnQoKGEsIGIpID0+IGIuY291bnQgLSBhLmNvdW50KTtcbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG5cbiAgcmVzZXQoKTogdm9pZCB7XG4gICAgdGhpcy5hdG9tcy5jbGVhcigpO1xuICB9XG59XG5cbmNsYXNzIEF0b21SZWdpc3RyeUltcGwgaW1wbGVtZW50cyBBdG9tUmVnaXN0cnkge1xuICBwcml2YXRlIGF0b21zOiBNYXA8c3RyaW5nLCBBdG9tPiA9IG5ldyBNYXAoKTtcblxuICByZWdpc3RlcihhdG9tOiBBdG9tKTogdm9pZCB7XG4gICAgY29uc3Qga2V5ID0gYCR7YXRvbS5uYW1lfUAke2F0b20udmVyc2lvbn1gO1xuICAgIHRoaXMuYXRvbXMuc2V0KGtleSwgYXRvbSk7XG4gICAgdGhpcy5hdG9tcy5zZXQoYXRvbS5uYW1lLCBhdG9tKTtcbiAgfVxuXG4gIGdldChuYW1lOiBzdHJpbmcpOiBBdG9tIHwgdW5kZWZpbmVkIHtcbiAgICByZXR1cm4gdGhpcy5hdG9tcy5nZXQobmFtZSk7XG4gIH1cblxuICBoYXMobmFtZTogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuYXRvbXMuaGFzKG5hbWUpO1xuICB9XG5cbiAgbGlzdCgpOiBzdHJpbmdbXSB7XG4gICAgY29uc3QgcmVzdWx0OiBzdHJpbmdbXSA9IFtdO1xuICAgIGNvbnN0IHNlZW4gPSBuZXcgU2V0PHN0cmluZz4oKTtcbiAgICBcbiAgICBmb3IgKGNvbnN0IFtrZXksIGF0b21dIG9mIHRoaXMuYXRvbXMuZW50cmllcygpKSB7XG4gICAgICBpZiAoIXNlZW4uaGFzKGF0b20ubmFtZSkpIHtcbiAgICAgICAgc2Vlbi5hZGQoYXRvbS5uYW1lKTtcbiAgICAgICAgcmVzdWx0LnB1c2goYXRvbS5uYW1lKTtcbiAgICAgIH1cbiAgICB9XG4gICAgXG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxufVxuXG5leHBvcnQgY2xhc3MgQWl0b3NSdW50aW1lIGltcGxlbWVudHMgUnVudGltZSB7XG4gIHByaXZhdGUgYXRvbXM6IE1hcDxzdHJpbmcsIEF0b20+ID0gbmV3IE1hcCgpO1xuICBwcml2YXRlIHRlbGVtZXRyeVN0b3JlOiBUZWxlbWV0cnlTdG9yZSA9IG5ldyBUZWxlbWV0cnlTdG9yZSgpO1xuICBwcml2YXRlIHRlbGVtZXRyeUhpc3Rvcnk6IFRlbGVtZXRyeVNuYXBzaG90W10gPSBbXTtcbiAgcHJpdmF0ZSBzbmFwc2hvdENhbGxiYWNrPzogKHNuYXBzaG90OiBUZWxlbWV0cnlTbmFwc2hvdCkgPT4gdm9pZDtcblxuICByZWdpc3RlcihhdG9tOiBBdG9tKTogdm9pZCB7XG4gICAgY29uc3Qga2V5ID0gYCR7YXRvbS5uYW1lfUAke2F0b20udmVyc2lvbn1gO1xuICAgIHRoaXMuYXRvbXMuc2V0KGtleSwgYXRvbSk7XG4gICAgdGhpcy5hdG9tcy5zZXQoYXRvbS5uYW1lLCBhdG9tKTtcbiAgfVxuXG4gIHZhbGlkYXRlR3JhcGgoZ3JhcGg6IEdyYXBoKTogeyB2YWxpZDogYm9vbGVhbjsgZXJyb3JzOiBzdHJpbmdbXSB9IHtcbiAgICBjb25zdCBlcnJvcnM6IEdyYXBoVmFsaWRhdGlvbkVycm9yW10gPSBbXTtcbiAgICB0aGlzLnZhbGlkYXRlR3JhcGhOb2RlcyhncmFwaC5ub2RlcywgZ3JhcGgub3JkZXIsIGVycm9ycyk7XG4gICAgcmV0dXJuIHsgdmFsaWQ6IGVycm9ycy5sZW5ndGggPT09IDAsIGVycm9yczogZXJyb3JzLm1hcChlID0+IEpTT04uc3RyaW5naWZ5KGUpKSB9O1xuICB9XG5cbiAgcHJpdmF0ZSB2YWxpZGF0ZUdyYXBoTm9kZXMobm9kZXM6IFJlY29yZDxzdHJpbmcsIEdyYXBoTm9kZT4sIG9yZGVyOiBzdHJpbmdbXSwgZXJyb3JzOiBHcmFwaFZhbGlkYXRpb25FcnJvcltdLCBwYXRoOiBzdHJpbmcgPSAnJywgcGFyZW50RXhlY3V0ZWQ/OiBTZXQ8c3RyaW5nPik6IHZvaWQge1xuICAgIGNvbnN0IGV4ZWN1dGVkID0gcGFyZW50RXhlY3V0ZWQgPyBuZXcgU2V0KHBhcmVudEV4ZWN1dGVkKSA6IG5ldyBTZXQ8c3RyaW5nPigpO1xuXG4gICAgZm9yIChjb25zdCBub2RlSWQgb2Ygb3JkZXIpIHtcbiAgICAgIGNvbnN0IG5vZGUgPSBub2Rlc1tub2RlSWRdO1xuICAgICAgaWYgKCFub2RlKSB7XG4gICAgICAgIGVycm9ycy5wdXNoKHtcbiAgICAgICAgICBub2RlOiBwYXRoLFxuICAgICAgICAgIGNvZGU6ICdOT0RFX05PVF9GT1VORCcsXG4gICAgICAgICAgcGFyYW06ICcnLFxuICAgICAgICAgIHJlZjogbm9kZUlkLFxuICAgICAgICAgIG1lc3NhZ2U6IGBOb2RlIFwiJHtub2RlSWR9XCIgbm90IGZvdW5kIGluIG5vZGVzYFxuICAgICAgICB9KTtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IG5vZGVQYXRoID0gcGF0aCA/IGAke3BhdGh9LiR7bm9kZUlkfWAgOiBub2RlSWQ7XG5cbiAgICAgIGlmICghbm9kZS5hdG9tKSB7XG4gICAgICAgIGVycm9ycy5wdXNoKHsgbm9kZTogbm9kZVBhdGgsIGNvZGU6ICdNSVNTSU5HX0FUT00nLCBwYXJhbTogJycsIHJlZjogJycsIG1lc3NhZ2U6ICdNaXNzaW5nIGF0b20gZmllbGQnIH0pO1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgaWYgKHR5cGVvZiBub2RlLmF0b20gIT09ICdzdHJpbmcnKSB7XG4gICAgICAgIGVycm9ycy5wdXNoKHsgbm9kZTogbm9kZVBhdGgsIGNvZGU6ICdJTlZBTElEX0FUT01fVFlQRScsIHBhcmFtOiAnJywgcmVmOiAnJywgbWVzc2FnZTogJ0F0b20gbXVzdCBiZSBhIHN0cmluZycgfSk7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuXG4gICAgICBpZiAoIXRoaXMuYXRvbXMuaGFzKG5vZGUuYXRvbSkpIHtcbiAgICAgICAgZXJyb3JzLnB1c2goeyBub2RlOiBub2RlUGF0aCwgY29kZTogJ0FUT01fTk9UX0ZPVU5EJywgcGFyYW06ICcnLCByZWY6ICcnLCBtZXNzYWdlOiBgQXRvbSBcIiR7bm9kZS5hdG9tfVwiIG5vdCByZWdpc3RlcmVkYCB9KTtcbiAgICAgIH1cblxuICAgICAgdGhpcy52YWxpZGF0ZUdyYXBoUmVmZXJlbmNlcyhub2RlLCBleGVjdXRlZCwgZXJyb3JzLCBub2RlUGF0aCwgbm9kZXMpO1xuXG4gICAgICBpZiAobm9kZS5ub2RlcyAmJiB0eXBlb2Ygbm9kZS5ub2RlcyA9PT0gJ29iamVjdCcgJiYgJ29yZGVyJyBpbiBub2RlLm5vZGVzKSB7XG4gICAgICAgIGNvbnN0IHN1YkdyYXBoID0gbm9kZS5ub2RlcyBhcyBHcmFwaDtcbiAgICAgICAgaWYgKHN1YkdyYXBoLm5vZGVzICYmIHN1YkdyYXBoLm9yZGVyKSB7XG4gICAgICAgICAgdGhpcy52YWxpZGF0ZUdyYXBoTm9kZXMoc3ViR3JhcGgubm9kZXMsIHN1YkdyYXBoLm9yZGVyLCBlcnJvcnMsIGAke25vZGVQYXRofS5ub2Rlc2AsIGV4ZWN1dGVkKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKG5vZGUudGhlbiAmJiB0eXBlb2Ygbm9kZS50aGVuID09PSAnb2JqZWN0JyAmJiAnb3JkZXInIGluIG5vZGUudGhlbikge1xuICAgICAgICBjb25zdCBzdWJHcmFwaCA9IG5vZGUudGhlbiBhcyBHcmFwaDtcbiAgICAgICAgaWYgKHN1YkdyYXBoLm5vZGVzICYmIHN1YkdyYXBoLm9yZGVyKSB7XG4gICAgICAgICAgdGhpcy52YWxpZGF0ZUdyYXBoTm9kZXMoc3ViR3JhcGgubm9kZXMsIHN1YkdyYXBoLm9yZGVyLCBlcnJvcnMsIGAke25vZGVQYXRofS50aGVuYCwgZXhlY3V0ZWQpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAobm9kZS5lbHNlICYmIHR5cGVvZiBub2RlLmVsc2UgPT09ICdvYmplY3QnICYmICdvcmRlcicgaW4gbm9kZS5lbHNlKSB7XG4gICAgICAgIGNvbnN0IHN1YkdyYXBoID0gbm9kZS5lbHNlIGFzIEdyYXBoO1xuICAgICAgICBpZiAoc3ViR3JhcGgubm9kZXMgJiYgc3ViR3JhcGgub3JkZXIpIHtcbiAgICAgICAgICB0aGlzLnZhbGlkYXRlR3JhcGhOb2RlcyhzdWJHcmFwaC5ub2Rlcywgc3ViR3JhcGgub3JkZXIsIGVycm9ycywgYCR7bm9kZVBhdGh9LmVsc2VgLCBleGVjdXRlZCk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgZXhlY3V0ZWQuYWRkKG5vZGVJZCk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSB2YWxpZGF0ZUdyYXBoUmVmZXJlbmNlcyhub2RlOiBHcmFwaE5vZGUsIGV4ZWN1dGVkOiBTZXQ8c3RyaW5nPiwgZXJyb3JzOiBHcmFwaFZhbGlkYXRpb25FcnJvcltdLCBub2RlUGF0aDogc3RyaW5nLCBub2RlczogUmVjb3JkPHN0cmluZywgR3JhcGhOb2RlPik6IHZvaWQge1xuICAgIGZvciAoY29uc3QgW2tleSwgdmFsdWVdIG9mIE9iamVjdC5lbnRyaWVzKG5vZGUpKSB7XG4gICAgICBpZiAoWydhdG9tJywgJ25vZGVzJywgJ3RoZW4nLCAnZWxzZSddLmluY2x1ZGVzKGtleSkpIGNvbnRpbnVlO1xuXG4gICAgICBpZiAodHlwZW9mIHZhbHVlID09PSAnc3RyaW5nJykge1xuICAgICAgICBjb25zdCBtYXRjaGVzID0gdmFsdWUubWF0Y2hBbGwoL1xce1xceyhcXHcrKSg/OlxcLiguKz8pKT9cXH1cXH0vZyk7XG4gICAgICAgIGZvciAoY29uc3QgbWF0Y2ggb2YgbWF0Y2hlcykge1xuICAgICAgICAgIGNvbnN0IHJlZklkID0gbWF0Y2hbMV07XG4gICAgICAgICAgaWYgKCFleGVjdXRlZC5oYXMocmVmSWQpICYmICFub2Rlc1tyZWZJZF0pIHtcbiAgICAgICAgICAgIGNvbnN0IHN1Z2dlc3Rpb25zID0gdGhpcy5nZW5lcmF0ZUdyYXBoU3VnZ2VzdGlvbnMoZXhlY3V0ZWQsIG5vZGVzKTtcbiAgICAgICAgICAgIGVycm9ycy5wdXNoKHtcbiAgICAgICAgICAgICAgbm9kZTogbm9kZVBhdGgsXG4gICAgICAgICAgICAgIGNvZGU6ICdJTlZBTElEX1JFRkVSRU5DRScsXG4gICAgICAgICAgICAgIHBhcmFtOiBrZXksXG4gICAgICAgICAgICAgIHJlZjogcmVmSWQsXG4gICAgICAgICAgICAgIG1lc3NhZ2U6IGBJbnZhbGlkIHJlZmVyZW5jZSB7eyR7cmVmSWR9fX06IG5vZGUgbm90IGZvdW5kIG9yIG5vdCB5ZXQgZXhlY3V0ZWRgLFxuICAgICAgICAgICAgICBzdWdnZXN0aW9uc1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBnZW5lcmF0ZUdyYXBoU3VnZ2VzdGlvbnMoZXhlY3V0ZWQ6IFNldDxzdHJpbmc+LCBub2RlczogUmVjb3JkPHN0cmluZywgR3JhcGhOb2RlPik6IEdyYXBoU3VnZ2VzdGlvbltdIHtcbiAgICBjb25zdCBzdWdnZXN0aW9uczogR3JhcGhTdWdnZXN0aW9uW10gPSBbXTtcblxuICAgIGZvciAoY29uc3Qgbm9kZUlkIG9mIGV4ZWN1dGVkKSB7XG4gICAgICBpZiAoc3VnZ2VzdGlvbnMubGVuZ3RoID49IDUpIGJyZWFrO1xuICAgICAgY29uc3Qgbm9kZSA9IG5vZGVzW25vZGVJZF07XG4gICAgICBpZiAobm9kZSkge1xuICAgICAgICBjb25zdCBhdG9tID0gdGhpcy5hdG9tcy5nZXQobm9kZS5hdG9tKTtcbiAgICAgICAgc3VnZ2VzdGlvbnMucHVzaCh7XG4gICAgICAgICAgaWQ6IG5vZGVJZCxcbiAgICAgICAgICB0eXBlOiBhdG9tPy5tZXRhLm91dHB1dC50eXBlIHx8ICd1bmtub3duJyxcbiAgICAgICAgICBzb3VyY2U6IG5vZGUuYXRvbVxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gc3VnZ2VzdGlvbnM7XG4gIH1cblxuICBhc3luYyBleGVjdXRlR3JhcGgoZ3JhcGg6IEdyYXBoLCBjb250ZXh0OiBDb250ZXh0LCBvdXRlclNjb3BlPzogUmVjb3JkPHN0cmluZywgYW55PiwgZ3JhcGhOYW1lPzogc3RyaW5nKTogUHJvbWlzZTxSZWNvcmQ8c3RyaW5nLCBhbnk+PiB7XG4gICAgY29uc3QgcmVzdWx0czogUmVjb3JkPHN0cmluZywgYW55PiA9IG91dGVyU2NvcGUgPyB7IC4uLm91dGVyU2NvcGUgfSA6IHt9O1xuICAgIGNvbnN0IGdOYW1lID0gZ3JhcGhOYW1lIHx8ICd1bmtub3duJztcbiAgICBcbiAgICBjb25zdCBwcmV2aW91c1Njb3BlID0gY29udGV4dC5jdXJyZW50U2NvcGU7XG4gICAgY29udGV4dC5jdXJyZW50U2NvcGUgPSByZXN1bHRzO1xuICAgIGNvbnRleHQucnVudGltZSA9IHRoaXM7XG5cbiAgICBmb3IgKGNvbnN0IG5vZGVJZCBvZiBncmFwaC5vcmRlcikge1xuICAgICAgY29uc3Qgbm9kZSA9IGdyYXBoLm5vZGVzW25vZGVJZF07XG4gICAgICBjb25zdCBpbnB1dCA9IHRoaXMucmVzb2x2ZUdyYXBoSW5wdXQobm9kZSwgcmVzdWx0cywgY29udGV4dCk7XG4gICAgICBjb25zdCBzdGFydFRpbWUgPSBwZXJmb3JtYW5jZS5ub3coKTtcbiAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGNvbnRleHQuZXhlY3V0ZShub2RlLmF0b20sIGlucHV0KTtcbiAgICAgIGNvbnN0IGR1cmF0aW9uID0gTWF0aC5yb3VuZChwZXJmb3JtYW5jZS5ub3coKSAtIHN0YXJ0VGltZSk7XG5cbiAgICAgIHRoaXMudGVsZW1ldHJ5U3RvcmUucmVjb3JkKG5vZGUuYXRvbSwgZ05hbWUsIGR1cmF0aW9uLCByZXN1bHQuc3VjY2Vzcyk7XG5cbiAgICAgIGlmICghcmVzdWx0LnN1Y2Nlc3MpIHtcbiAgICAgICAgY29udGV4dC5jdXJyZW50U2NvcGUgPSBwcmV2aW91c1Njb3BlO1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoSlNPTi5zdHJpbmdpZnkoeyBub2RlOiBub2RlSWQsIGF0b206IG5vZGUuYXRvbSwgZXJyb3I6IHJlc3VsdC5lcnJvciB9KSk7XG4gICAgICB9XG5cbiAgICAgIHJlc3VsdHNbbm9kZUlkXSA9IHJlc3VsdC5kYXRhO1xuICAgIH1cblxuICAgIGNvbnRleHQuY3VycmVudFNjb3BlID0gcHJldmlvdXNTY29wZTtcblxuICAgIHJldHVybiByZXN1bHRzO1xuICB9XG5cbiAgb25TbmFwc2hvdChjYWxsYmFjazogKHNuYXBzaG90OiBUZWxlbWV0cnlTbmFwc2hvdCkgPT4gdm9pZCk6IHZvaWQge1xuICAgIHRoaXMuc25hcHNob3RDYWxsYmFjayA9IGNhbGxiYWNrO1xuICB9XG5cbiAgZmx1c2hUZWxlbWV0cnkoKTogVGVsZW1ldHJ5U25hcHNob3Qge1xuICAgIGNvbnN0IHN0YXRzID0gdGhpcy50ZWxlbWV0cnlTdG9yZS5nZXRTdGF0cygpO1xuICAgIGNvbnN0IHNuYXBzaG90OiBUZWxlbWV0cnlTbmFwc2hvdCA9IHsgdGltZXN0YW1wOiBEYXRlLm5vdygpLCBzdGF0cyB9O1xuICAgIHRoaXMudGVsZW1ldHJ5SGlzdG9yeS5wdXNoKHNuYXBzaG90KTtcbiAgICBpZiAodGhpcy50ZWxlbWV0cnlIaXN0b3J5Lmxlbmd0aCA+IDEwMCkge1xuICAgICAgdGhpcy50ZWxlbWV0cnlIaXN0b3J5LnNoaWZ0KCk7XG4gICAgfVxuICAgIHRoaXMuc25hcHNob3RDYWxsYmFjaz8uKHNuYXBzaG90KTtcbiAgICByZXR1cm4gc25hcHNob3Q7XG4gIH1cblxuICBnZXRUZWxlbWV0cnlIaXN0b3J5KCk6IFRlbGVtZXRyeVNuYXBzaG90W10ge1xuICAgIHJldHVybiB0aGlzLnRlbGVtZXRyeUhpc3Rvcnk7XG4gIH1cblxuICByZXN0b3JlVGVsZW1ldHJ5SGlzdG9yeShoaXN0b3J5OiBUZWxlbWV0cnlTbmFwc2hvdFtdKTogdm9pZCB7XG4gICAgdGhpcy50ZWxlbWV0cnlIaXN0b3J5ID0gaGlzdG9yeS5zbGljZSgtMTAwKTtcbiAgfVxuXG4gIHByaXZhdGUgcmVzb2x2ZUdyYXBoSW5wdXQobm9kZTogR3JhcGhOb2RlLCByZXN1bHRzOiBSZWNvcmQ8c3RyaW5nLCBhbnk+LCBjb250ZXh0OiBDb250ZXh0KTogYW55IHtcbiAgICBjb25zdCByZXNvbHZlZDogYW55ID0ge307XG4gICAgY29uc3QgU1VCR1JBUEhfS0VZUyA9IG5ldyBTZXQoWydub2RlcycsICd0aGVuJywgJ2Vsc2UnXSk7XG5cbiAgICBmb3IgKGNvbnN0IFtrZXksIHZhbHVlXSBvZiBPYmplY3QuZW50cmllcyhub2RlKSkge1xuICAgICAgaWYgKGtleSA9PT0gJ2F0b20nKSBjb250aW51ZTtcbiAgICAgIGlmIChTVUJHUkFQSF9LRVlTLmhhcyhrZXkpKSB7XG4gICAgICAgIHJlc29sdmVkW2tleV0gPSB2YWx1ZTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJlc29sdmVkW2tleV0gPSB0aGlzLnJlc29sdmVHcmFwaFZhbHVlKHZhbHVlLCByZXN1bHRzLCBjb250ZXh0KTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gcmVzb2x2ZWQ7XG4gIH1cblxuICBwcml2YXRlIHJlc29sdmVHcmFwaFZhbHVlKHZhbHVlOiBhbnksIHJlc3VsdHM6IFJlY29yZDxzdHJpbmcsIGFueT4sIGNvbnRleHQ6IENvbnRleHQpOiBhbnkge1xuICAgIGlmICh0eXBlb2YgdmFsdWUgPT09ICdzdHJpbmcnKSB7XG4gICAgICBjb25zdCBFU0NBUEVfUExBQ0VIT0xERVIgPSAnXFx4MDBFU0NBUEVEX0JSQUNFXFx4MDAnO1xuICAgICAgbGV0IHByb2Nlc3NlZFZhbHVlID0gdmFsdWUucmVwbGFjZSgvXFxcXHt7L2csIEVTQ0FQRV9QTEFDRUhPTERFUik7XG5cbiAgICAgIGNvbnN0IG1hdGNoID0gcHJvY2Vzc2VkVmFsdWUubWF0Y2goL15cXHtcXHsoXFx3KykoPzpcXC4oLis/KSk/XFx9XFx9JC8pO1xuICAgICAgaWYgKG1hdGNoKSB7XG4gICAgICAgIGNvbnN0IG5vZGVJZCA9IG1hdGNoWzFdO1xuICAgICAgICBjb25zdCBmaWVsZCA9IG1hdGNoWzJdO1xuXG4gICAgICAgIGxldCByZXNvbHZlZFZhbHVlOiBhbnk7XG4gICAgICAgIFxuICAgICAgICBpZiAobm9kZUlkIGluIHJlc3VsdHMpIHtcbiAgICAgICAgICByZXNvbHZlZFZhbHVlID0gcmVzdWx0c1tub2RlSWRdO1xuICAgICAgICB9IGVsc2UgaWYgKGNvbnRleHQuc3RvcmUuaGFzKG5vZGVJZCkpIHtcbiAgICAgICAgICByZXNvbHZlZFZhbHVlID0gY29udGV4dC5zdG9yZS5nZXQobm9kZUlkKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoSlNPTi5zdHJpbmdpZnkoe1xuICAgICAgICAgICAgY29kZTogJ1JFRkVSRU5DRV9OT1RfRk9VTkQnLFxuICAgICAgICAgICAgcmVmOiBub2RlSWQsXG4gICAgICAgICAgICBtZXNzYWdlOiBgUmVmZXJlbmNlIHt7JHtub2RlSWR9fX0gbm90IGZvdW5kIGluIGN1cnJlbnQgc2NvcGUgb3Igc3RvcmVgLFxuICAgICAgICAgICAgYXZhaWxhYmxlSW5TY29wZTogT2JqZWN0LmtleXMocmVzdWx0cyksXG4gICAgICAgICAgICBhdmFpbGFibGVJblN0b3JlOiBjb250ZXh0LnN0b3JlLmhhcyhub2RlSWQpID8gW25vZGVJZF0gOiBbXSxcbiAgICAgICAgICAgIGhpbnQ6ICdDaGVjayBpZiB0aGUgcmVmZXJlbmNlIGlzIGEgbm9kZSBvdXRwdXQgb3IgYSBzdG9yZSB2YWx1ZS4nLFxuICAgICAgICAgICAgZml4OiBgRW5zdXJlIHRoZSBub2RlIFwiJHtub2RlSWR9XCIgaXMgZXhlY3V0ZWQgYmVmb3JlIHRoaXMgcmVmZXJlbmNlLCBvciB1c2UgeyBcImF0b21cIjogXCJzZXRcIiwgXCJrZXlcIjogXCIke25vZGVJZH1cIiwgXCJ2YWx1ZVwiOiAuLi4gfSB0byBzdG9yZSB0aGUgdmFsdWUuYFxuICAgICAgICAgIH0pKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChmaWVsZCkge1xuICAgICAgICAgIHJldHVybiB0aGlzLmdldEZpZWxkVmFsdWUocmVzb2x2ZWRWYWx1ZSwgZmllbGQpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZXNvbHZlZFZhbHVlO1xuICAgICAgfVxuXG4gICAgICBjb25zdCByZXN1bHQgPSBwcm9jZXNzZWRWYWx1ZS5yZXBsYWNlKC9cXHtcXHsoXFx3KykoPzpcXC4oLis/KSk/XFx9XFx9L2csIChfLCBub2RlSWQsIGZpZWxkKSA9PiB7XG4gICAgICAgIGxldCByZXNvbHZlZFZhbHVlOiBhbnk7XG4gICAgICAgIFxuICAgICAgICBpZiAobm9kZUlkIGluIHJlc3VsdHMpIHtcbiAgICAgICAgICByZXNvbHZlZFZhbHVlID0gcmVzdWx0c1tub2RlSWRdO1xuICAgICAgICB9IGVsc2UgaWYgKGNvbnRleHQuc3RvcmUuaGFzKG5vZGVJZCkpIHtcbiAgICAgICAgICByZXNvbHZlZFZhbHVlID0gY29udGV4dC5zdG9yZS5nZXQobm9kZUlkKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoSlNPTi5zdHJpbmdpZnkoe1xuICAgICAgICAgICAgY29kZTogJ1JFRkVSRU5DRV9OT1RfRk9VTkQnLFxuICAgICAgICAgICAgcmVmOiBub2RlSWQsXG4gICAgICAgICAgICBtZXNzYWdlOiBgUmVmZXJlbmNlIHt7JHtub2RlSWR9fX0gbm90IGZvdW5kIGluIGN1cnJlbnQgc2NvcGUgb3Igc3RvcmVgLFxuICAgICAgICAgICAgYXZhaWxhYmxlSW5TY29wZTogT2JqZWN0LmtleXMocmVzdWx0cyksXG4gICAgICAgICAgICBhdmFpbGFibGVJblN0b3JlOiBjb250ZXh0LnN0b3JlLmhhcyhub2RlSWQpID8gW25vZGVJZF0gOiBbXSxcbiAgICAgICAgICAgIGhpbnQ6ICdDaGVjayBpZiB0aGUgcmVmZXJlbmNlIGlzIGEgbm9kZSBvdXRwdXQgb3IgYSBzdG9yZSB2YWx1ZS4nLFxuICAgICAgICAgICAgZml4OiBgRW5zdXJlIHRoZSBub2RlIFwiJHtub2RlSWR9XCIgaXMgZXhlY3V0ZWQgYmVmb3JlIHRoaXMgcmVmZXJlbmNlLCBvciB1c2UgeyBcImF0b21cIjogXCJzZXRcIiwgXCJrZXlcIjogXCIke25vZGVJZH1cIiwgXCJ2YWx1ZVwiOiAuLi4gfSB0byBzdG9yZSB0aGUgdmFsdWUuYFxuICAgICAgICAgIH0pKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoZmllbGQpIHtcbiAgICAgICAgICByZXR1cm4gdGhpcy5nZXRGaWVsZFZhbHVlKHJlc29sdmVkVmFsdWUsIGZpZWxkKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcmVzb2x2ZWRWYWx1ZTtcbiAgICAgIH0pO1xuXG4gICAgICByZXR1cm4gcmVzdWx0LnJlcGxhY2UobmV3IFJlZ0V4cChFU0NBUEVfUExBQ0VIT0xERVIsICdnJyksICd7eycpO1xuICAgIH1cblxuICAgIGlmIChBcnJheS5pc0FycmF5KHZhbHVlKSkge1xuICAgICAgcmV0dXJuIHZhbHVlLm1hcChpdGVtID0+IHRoaXMucmVzb2x2ZUdyYXBoVmFsdWUoaXRlbSwgcmVzdWx0cywgY29udGV4dCkpO1xuICAgIH1cblxuICAgIGlmICh0eXBlb2YgdmFsdWUgPT09ICdvYmplY3QnICYmIHZhbHVlICE9PSBudWxsKSB7XG4gICAgICBjb25zdCByZXNvbHZlZDogYW55ID0ge307XG4gICAgICBmb3IgKGNvbnN0IFtrLCB2XSBvZiBPYmplY3QuZW50cmllcyh2YWx1ZSkpIHtcbiAgICAgICAgcmVzb2x2ZWRba10gPSB0aGlzLnJlc29sdmVHcmFwaFZhbHVlKHYsIHJlc3VsdHMsIGNvbnRleHQpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHJlc29sdmVkO1xuICAgIH1cblxuICAgIHJldHVybiB2YWx1ZTtcbiAgfVxuXG4gIHByaXZhdGUgZ2V0RmllbGRWYWx1ZShvYmo6IGFueSwgZmllbGQ6IHN0cmluZyk6IGFueSB7XG4gICAgY29uc3QgcGFydHMgPSBmaWVsZC5zcGxpdCgnLicpO1xuICAgIGxldCBjdXJyZW50ID0gb2JqO1xuXG4gICAgZm9yIChjb25zdCBwYXJ0IG9mIHBhcnRzKSB7XG4gICAgICBpZiAoY3VycmVudCA9PT0gdW5kZWZpbmVkIHx8IGN1cnJlbnQgPT09IG51bGwpIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICBjdXJyZW50ID0gY3VycmVudFtwYXJ0XTtcbiAgICB9XG5cbiAgICByZXR1cm4gY3VycmVudDtcbiAgfVxuXG4gIGxpc3RBdG9tcygpOiBBdG9tW10ge1xuICAgIGNvbnN0IHJlc3VsdDogQXRvbVtdID0gW107XG4gICAgY29uc3Qgc2VlbiA9IG5ldyBTZXQ8c3RyaW5nPigpO1xuXG4gICAgZm9yIChjb25zdCBba2V5LCBhdG9tXSBvZiB0aGlzLmF0b21zLmVudHJpZXMoKSkge1xuICAgICAgaWYgKCFzZWVuLmhhcyhhdG9tLm5hbWUpKSB7XG4gICAgICAgIHNlZW4uYWRkKGF0b20ubmFtZSk7XG4gICAgICAgIHJlc3VsdC5wdXNoKGF0b20pO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cblxuICBnZXRTa2lsbFNldCgpOiBzdHJpbmcge1xuICAgIGNvbnN0IGF0b21zID0gdGhpcy5saXN0QXRvbXMoKTtcblxuICAgIGNvbnN0IHJlZ2lzdHJ5ID0ge1xuICAgICAgYWl0b3M6IHtcbiAgICAgICAgdmVyc2lvbjogJzEuMC4wJyxcbiAgICAgICAgdHlwZTogJ2dyYXBoLWluc3RydWN0aW9uLXNldCcsXG4gICAgICB9LFxuICAgICAgZ3JhcGg6IHtcbiAgICAgICAgZm9ybWF0OiB7XG4gICAgICAgICAgbm9kZXM6ICdSZWNvcmQ8bm9kZUlkLCBHcmFwaE5vZGU+JyxcbiAgICAgICAgICBvcmRlcjogJ3N0cmluZ1tdIChleGVjdXRpb24gb3JkZXIpJ1xuICAgICAgICB9LFxuICAgICAgICBleGFtcGxlOiB7XG4gICAgICAgICAgbm9kZXM6IHtcbiAgICAgICAgICAgIGdldFk6IHsgYXRvbTogJ2dldCcsIGtleTogJ2ZydWl0WScgfSxcbiAgICAgICAgICAgIGFkZEZpdmU6IHsgYXRvbTogJ2FkZCcsIGE6ICd7e2dldFl9fScsIGI6IDUgfSxcbiAgICAgICAgICAgIHNhdmVZOiB7IGF0b206ICdzZXQnLCBrZXk6ICdmcnVpdFknLCB2YWx1ZTogJ3t7YWRkRml2ZX19JyB9XG4gICAgICAgICAgfSxcbiAgICAgICAgICBvcmRlcjogWydnZXRZJywgJ2FkZEZpdmUnLCAnc2F2ZVknXVxuICAgICAgICB9XG4gICAgICB9LFxuICAgICAgbm9kZToge1xuICAgICAgICBmb3JtYXQ6IHsgYXRvbTogJ3N0cmluZycsICcuLi5wYXJhbXMnOiAncGVyIGF0b20uaW5wdXQnIH0sXG4gICAgICAgIGV4YW1wbGU6IHsgYXRvbTogJ2FkZCcsIGE6ICd7e290aGVyTm9kZUlkfX0nLCBiOiAxIH1cbiAgICAgIH0sXG4gICAgICByZWY6IHtcbiAgICAgICAgZm9ybWF0OiAne3tub2RlSWR9fSBvciB7e25vZGVJZC5maWVsZH19JyxcbiAgICAgICAgcnVsZXM6IFtcbiAgICAgICAgICAnVXNlIG5vZGVJZCB0byByZWZlcmVuY2UgYW5vdGhlciBub2RlIHJlc3VsdCcsXG4gICAgICAgICAgJ25vZGVJZCBtdXN0IGJlIGRlZmluZWQgaW4gbm9kZXMgYW5kIGFwcGVhciBlYXJsaWVyIGluIG9yZGVyJyxcbiAgICAgICAgICAnVXNlIHt7bm9kZUlkLmZpZWxkfX0gdG8gYWNjZXNzIG5lc3RlZCBwcm9wZXJ0aWVzJyxcbiAgICAgICAgICAnUmVmZXJlbmNlcyBhcmUgcmVzb2x2ZWQgYmVmb3JlIGV4ZWN1dGlvbidcbiAgICAgICAgXVxuICAgICAgfSxcbiAgICAgIGF0b21zOiBhdG9tcy5tYXAoYSA9PiAoe1xuICAgICAgICBuYW1lOiBhLm5hbWUsXG4gICAgICAgIHZlcnNpb246IGEudmVyc2lvbixcbiAgICAgICAgaW5wdXQ6IGEubWV0YS5pbnB1dCxcbiAgICAgICAgb3V0cHV0OiBhLm1ldGEub3V0cHV0LFxuICAgICAgfSkpLFxuICAgICAgdmFsaWRhdGlvbjoge1xuICAgICAgICBkZXNjcmlwdGlvbjogJ1ZhbGlkYXRpb24gY2hlY2tzIG5vZGUgcmVmZXJlbmNlcyBhbmQgYXRvbSBleGlzdGVuY2UnLFxuICAgICAgICBlcnJvckZvcm1hdDoge1xuICAgICAgICAgIG5vZGU6ICdOb2RlIHBhdGgnLFxuICAgICAgICAgIGNvZGU6ICdFcnJvciBjb2RlJyxcbiAgICAgICAgICBwYXJhbTogJ1BhcmFtZXRlciBuYW1lJyxcbiAgICAgICAgICByZWY6ICdJbnZhbGlkIHJlZmVyZW5jZScsXG4gICAgICAgICAgbWVzc2FnZTogJ0Vycm9yIGRlc2NyaXB0aW9uJyxcbiAgICAgICAgICBzdWdnZXN0aW9uczogW1xuICAgICAgICAgICAgeyBpZDogJ1N1Z2dlc3RlZCBub2RlSWQnLCB0eXBlOiAnT3V0cHV0IHR5cGUnLCBzb3VyY2U6ICdBdG9tIG5hbWUnIH1cbiAgICAgICAgICBdXG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9O1xuXG4gICAgcmV0dXJuIEpTT04uc3RyaW5naWZ5KHJlZ2lzdHJ5KTtcbiAgfVxuXG4gIGdldFRlbGVtZXRyeVN0YXRzKCk6IFRlbGVtZXRyeVN0YXRzW10ge1xuICAgIHJldHVybiB0aGlzLnRlbGVtZXRyeVN0b3JlLmdldFN0YXRzKCk7XG4gIH1cblxuICByZXNldFRlbGVtZXRyeSgpOiB2b2lkIHtcbiAgICB0aGlzLnRlbGVtZXRyeVN0b3JlLnJlc2V0KCk7XG4gIH1cbn1cblxuZXhwb3J0IHsgU3RvcmUsIEF0b21SZWdpc3RyeUltcGwsIFRlbGVtZXRyeVN0b3JlIH07XG5leHBvcnQgdHlwZSB7IEF0b20sIENvbnRleHQsIFJlc3VsdCwgR3JhcGgsIEdyYXBoTm9kZSwgU2NvcGUsIEF0b21SZWdpc3RyeSwgR3JhcGhWYWxpZGF0aW9uRXJyb3IsIEdyYXBoU3VnZ2VzdGlvbiwgUnVudGltZSwgVGVsZW1ldHJ5U3RhdHMsIFRlbGVtZXRyeVNuYXBzaG90IH07XG4iXX0=
@@ -0,0 +1,123 @@
1
+ export interface Atom {
2
+ name: string;
3
+ version: string;
4
+ meta: {
5
+ input: Array<{
6
+ name: string;
7
+ type: string;
8
+ description?: string;
9
+ }>;
10
+ output: {
11
+ type: string;
12
+ description?: string;
13
+ };
14
+ };
15
+ characteristics: {
16
+ stateless: boolean;
17
+ atomic: boolean;
18
+ composable: boolean;
19
+ };
20
+ execute: (input: any, context: Context) => Promise<Result>;
21
+ }
22
+ export interface Result {
23
+ success: boolean;
24
+ data?: any;
25
+ error?: string;
26
+ }
27
+ export interface GraphNode {
28
+ atom: string;
29
+ nodes?: Graph;
30
+ then?: Graph;
31
+ else?: Graph;
32
+ [key: string]: any;
33
+ }
34
+ export type GraphMode = 'kernel' | 'user';
35
+ export interface GraphInterface {
36
+ input: Array<{
37
+ name: string;
38
+ type: string;
39
+ description?: string;
40
+ }>;
41
+ output: {
42
+ type: string;
43
+ description?: string;
44
+ };
45
+ }
46
+ export interface Graph {
47
+ mode?: GraphMode;
48
+ _meta?: {
49
+ description?: string;
50
+ type?: string;
51
+ category?: string;
52
+ author?: string;
53
+ };
54
+ interface?: GraphInterface;
55
+ order: string[];
56
+ nodes: Record<string, GraphNode>;
57
+ }
58
+ export interface Scope {
59
+ [key: string]: any;
60
+ }
61
+ export interface Context {
62
+ store: {
63
+ get: (key: string) => any;
64
+ set: (key: string, value: any) => void;
65
+ has: (key: string) => boolean;
66
+ delete: (key: string) => void;
67
+ clear: () => void;
68
+ keys: () => IterableIterator<string>;
69
+ };
70
+ currentScope: Scope;
71
+ execute: (atomName: string, input: any) => Promise<Result>;
72
+ executeGraph?: (graph: Graph, scope?: Scope, graphName?: string) => Promise<Record<string, any>>;
73
+ runtime?: Runtime;
74
+ }
75
+ export interface AtomRegistry {
76
+ register: (atom: Atom) => void;
77
+ get: (name: string) => Atom | undefined;
78
+ has: (name: string) => boolean;
79
+ list: () => string[];
80
+ }
81
+ export interface GraphValidationError {
82
+ node: string;
83
+ code: string;
84
+ param: string;
85
+ ref: string;
86
+ message: string;
87
+ suggestions?: GraphSuggestion[];
88
+ }
89
+ export interface GraphSuggestion {
90
+ id: string;
91
+ type: string;
92
+ source: string;
93
+ }
94
+ export interface TelemetrySnapshot {
95
+ timestamp: number;
96
+ stats: TelemetryStats[];
97
+ }
98
+ export interface Runtime {
99
+ register(atom: Atom): void;
100
+ validateGraph(graph: Graph): {
101
+ valid: boolean;
102
+ errors: string[];
103
+ };
104
+ executeGraph(graph: Graph, context: Context, outerScope?: Record<string, any>, graphName?: string): Promise<Record<string, any>>;
105
+ listAtoms(): Atom[];
106
+ getSkillSet(): string;
107
+ getTelemetryStats(): TelemetryStats[];
108
+ resetTelemetry(): void;
109
+ onSnapshot(callback: (snapshot: TelemetrySnapshot) => void): void;
110
+ flushTelemetry(): TelemetrySnapshot;
111
+ getTelemetryHistory(): TelemetrySnapshot[];
112
+ restoreTelemetryHistory(history: TelemetrySnapshot[]): void;
113
+ }
114
+ export interface TelemetryStats {
115
+ atom: string;
116
+ count: number;
117
+ avgDuration: number;
118
+ maxDuration: number;
119
+ errorCount: number;
120
+ errorRate: number;
121
+ lastCalled: number;
122
+ graphs: string[];
123
+ }
package/dist/types.js ADDED
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHlwZXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvdHlwZXMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IiIsInNvdXJjZXNDb250ZW50IjpbImV4cG9ydCBpbnRlcmZhY2UgQXRvbSB7XG4gIG5hbWU6IHN0cmluZztcbiAgdmVyc2lvbjogc3RyaW5nO1xuICBtZXRhOiB7XG4gICAgaW5wdXQ6IEFycmF5PHsgbmFtZTogc3RyaW5nOyB0eXBlOiBzdHJpbmc7IGRlc2NyaXB0aW9uPzogc3RyaW5nIH0+O1xuICAgIG91dHB1dDogeyB0eXBlOiBzdHJpbmc7IGRlc2NyaXB0aW9uPzogc3RyaW5nIH07XG4gIH07XG4gIGNoYXJhY3RlcmlzdGljczoge1xuICAgIHN0YXRlbGVzczogYm9vbGVhbjtcbiAgICBhdG9taWM6IGJvb2xlYW47XG4gICAgY29tcG9zYWJsZTogYm9vbGVhbjtcbiAgfTtcbiAgZXhlY3V0ZTogKGlucHV0OiBhbnksIGNvbnRleHQ6IENvbnRleHQpID0+IFByb21pc2U8UmVzdWx0Pjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBSZXN1bHQge1xuICBzdWNjZXNzOiBib29sZWFuO1xuICBkYXRhPzogYW55O1xuICBlcnJvcj86IHN0cmluZztcbn1cblxuZXhwb3J0IGludGVyZmFjZSBHcmFwaE5vZGUge1xuICBhdG9tOiBzdHJpbmc7XG4gIG5vZGVzPzogR3JhcGg7XG4gIHRoZW4/OiBHcmFwaDtcbiAgZWxzZT86IEdyYXBoO1xuICBba2V5OiBzdHJpbmddOiBhbnk7XG59XG5cbmV4cG9ydCB0eXBlIEdyYXBoTW9kZSA9ICdrZXJuZWwnIHwgJ3VzZXInO1xuXG5leHBvcnQgaW50ZXJmYWNlIEdyYXBoSW50ZXJmYWNlIHtcbiAgaW5wdXQ6IEFycmF5PHsgbmFtZTogc3RyaW5nOyB0eXBlOiBzdHJpbmc7IGRlc2NyaXB0aW9uPzogc3RyaW5nIH0+O1xuICBvdXRwdXQ6IHsgdHlwZTogc3RyaW5nOyBkZXNjcmlwdGlvbj86IHN0cmluZyB9O1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIEdyYXBoIHtcbiAgbW9kZT86IEdyYXBoTW9kZTtcbiAgX21ldGE/OiB7IGRlc2NyaXB0aW9uPzogc3RyaW5nOyB0eXBlPzogc3RyaW5nOyBjYXRlZ29yeT86IHN0cmluZzsgYXV0aG9yPzogc3RyaW5nIH07XG4gIGludGVyZmFjZT86IEdyYXBoSW50ZXJmYWNlO1xuICBvcmRlcjogc3RyaW5nW107XG4gIG5vZGVzOiBSZWNvcmQ8c3RyaW5nLCBHcmFwaE5vZGU+O1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFNjb3BlIHtcbiAgW2tleTogc3RyaW5nXTogYW55O1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIENvbnRleHQge1xuICBzdG9yZToge1xuICAgIGdldDogKGtleTogc3RyaW5nKSA9PiBhbnk7XG4gICAgc2V0OiAoa2V5OiBzdHJpbmcsIHZhbHVlOiBhbnkpID0+IHZvaWQ7XG4gICAgaGFzOiAoa2V5OiBzdHJpbmcpID0+IGJvb2xlYW47XG4gICAgZGVsZXRlOiAoa2V5OiBzdHJpbmcpID0+IHZvaWQ7XG4gICAgY2xlYXI6ICgpID0+IHZvaWQ7XG4gICAga2V5czogKCkgPT4gSXRlcmFibGVJdGVyYXRvcjxzdHJpbmc+O1xuICB9O1xuICBjdXJyZW50U2NvcGU6IFNjb3BlO1xuICBleGVjdXRlOiAoYXRvbU5hbWU6IHN0cmluZywgaW5wdXQ6IGFueSkgPT4gUHJvbWlzZTxSZXN1bHQ+O1xuICBleGVjdXRlR3JhcGg/OiAoZ3JhcGg6IEdyYXBoLCBzY29wZT86IFNjb3BlLCBncmFwaE5hbWU/OiBzdHJpbmcpID0+IFByb21pc2U8UmVjb3JkPHN0cmluZywgYW55Pj47XG4gIHJ1bnRpbWU/OiBSdW50aW1lO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIEF0b21SZWdpc3RyeSB7XG4gIHJlZ2lzdGVyOiAoYXRvbTogQXRvbSkgPT4gdm9pZDtcbiAgZ2V0OiAobmFtZTogc3RyaW5nKSA9PiBBdG9tIHwgdW5kZWZpbmVkO1xuICBoYXM6IChuYW1lOiBzdHJpbmcpID0+IGJvb2xlYW47XG4gIGxpc3Q6ICgpID0+IHN0cmluZ1tdO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIEdyYXBoVmFsaWRhdGlvbkVycm9yIHtcbiAgbm9kZTogc3RyaW5nO1xuICBjb2RlOiBzdHJpbmc7XG4gIHBhcmFtOiBzdHJpbmc7XG4gIHJlZjogc3RyaW5nO1xuICBtZXNzYWdlOiBzdHJpbmc7XG4gIHN1Z2dlc3Rpb25zPzogR3JhcGhTdWdnZXN0aW9uW107XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgR3JhcGhTdWdnZXN0aW9uIHtcbiAgaWQ6IHN0cmluZztcbiAgdHlwZTogc3RyaW5nO1xuICBzb3VyY2U6IHN0cmluZztcbn1cblxuZXhwb3J0IGludGVyZmFjZSBUZWxlbWV0cnlTbmFwc2hvdCB7XG4gIHRpbWVzdGFtcDogbnVtYmVyO1xuICBzdGF0czogVGVsZW1ldHJ5U3RhdHNbXTtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBSdW50aW1lIHtcbiAgcmVnaXN0ZXIoYXRvbTogQXRvbSk6IHZvaWQ7XG4gIHZhbGlkYXRlR3JhcGgoZ3JhcGg6IEdyYXBoKTogeyB2YWxpZDogYm9vbGVhbjsgZXJyb3JzOiBzdHJpbmdbXSB9O1xuICBleGVjdXRlR3JhcGgoZ3JhcGg6IEdyYXBoLCBjb250ZXh0OiBDb250ZXh0LCBvdXRlclNjb3BlPzogUmVjb3JkPHN0cmluZywgYW55PiwgZ3JhcGhOYW1lPzogc3RyaW5nKTogUHJvbWlzZTxSZWNvcmQ8c3RyaW5nLCBhbnk+PjtcbiAgbGlzdEF0b21zKCk6IEF0b21bXTtcbiAgZ2V0U2tpbGxTZXQoKTogc3RyaW5nO1xuICBnZXRUZWxlbWV0cnlTdGF0cygpOiBUZWxlbWV0cnlTdGF0c1tdO1xuICByZXNldFRlbGVtZXRyeSgpOiB2b2lkO1xuICBvblNuYXBzaG90KGNhbGxiYWNrOiAoc25hcHNob3Q6IFRlbGVtZXRyeVNuYXBzaG90KSA9PiB2b2lkKTogdm9pZDtcbiAgZmx1c2hUZWxlbWV0cnkoKTogVGVsZW1ldHJ5U25hcHNob3Q7XG4gIGdldFRlbGVtZXRyeUhpc3RvcnkoKTogVGVsZW1ldHJ5U25hcHNob3RbXTtcbiAgcmVzdG9yZVRlbGVtZXRyeUhpc3RvcnkoaGlzdG9yeTogVGVsZW1ldHJ5U25hcHNob3RbXSk6IHZvaWQ7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgVGVsZW1ldHJ5U3RhdHMge1xuICBhdG9tOiBzdHJpbmc7XG4gIGNvdW50OiBudW1iZXI7XG4gIGF2Z0R1cmF0aW9uOiBudW1iZXI7XG4gIG1heER1cmF0aW9uOiBudW1iZXI7XG4gIGVycm9yQ291bnQ6IG51bWJlcjtcbiAgZXJyb3JSYXRlOiBudW1iZXI7XG4gIGxhc3RDYWxsZWQ6IG51bWJlcjtcbiAgZ3JhcGhzOiBzdHJpbmdbXTtcbn1cbiJdfQ==
package/package.json CHANGED
@@ -1,13 +1,27 @@
1
1
  {
2
2
  "name": "@aitos/core",
3
- "version": "1.0.0",
4
- "description": "AI-Native Application Framework - Build apps with atomic composition and graph execution",
5
- "main": "index.js",
3
+ "version": "1.0.1",
4
+ "description": "AITOS Core Package - AI-friendly atomic architecture based on capability dimensions",
5
+ "main": "dist/index.js",
6
+ "types": "dist/index.d.ts",
6
7
  "scripts": {
7
- "test": "echo \"Error: no test specified\" && exit 1"
8
+ "build": "tsc",
9
+ "dev": "tsc --watch"
8
10
  },
9
- "keywords": ["ai", "framework", "atomic", "graph-execution", "cross-platform"],
10
- "author": "",
11
+ "keywords": [
12
+ "aitos",
13
+ "atomic",
14
+ "architecture",
15
+ "ai-friendly",
16
+ "capability-based"
17
+ ],
18
+ "author": "AITOS Team",
11
19
  "license": "MIT",
12
- "type": "commonjs"
20
+ "files": [
21
+ "dist"
22
+ ],
23
+ "devDependencies": {
24
+ "@types/node": "^20.0.0",
25
+ "typescript": "^5.9.3"
26
+ }
13
27
  }