musubi-sdd 3.10.0 → 5.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.
Files changed (44) hide show
  1. package/README.md +24 -19
  2. package/package.json +1 -1
  3. package/src/agents/agent-loop.js +532 -0
  4. package/src/agents/agentic/code-generator.js +767 -0
  5. package/src/agents/agentic/code-reviewer.js +698 -0
  6. package/src/agents/agentic/index.js +43 -0
  7. package/src/agents/function-tool.js +432 -0
  8. package/src/agents/index.js +45 -0
  9. package/src/agents/schema-generator.js +514 -0
  10. package/src/analyzers/ast-extractor.js +870 -0
  11. package/src/analyzers/context-optimizer.js +681 -0
  12. package/src/analyzers/repository-map.js +692 -0
  13. package/src/integrations/index.js +7 -1
  14. package/src/integrations/mcp/index.js +175 -0
  15. package/src/integrations/mcp/mcp-context-provider.js +472 -0
  16. package/src/integrations/mcp/mcp-discovery.js +436 -0
  17. package/src/integrations/mcp/mcp-tool-registry.js +467 -0
  18. package/src/integrations/mcp-connector.js +818 -0
  19. package/src/integrations/tool-discovery.js +589 -0
  20. package/src/managers/index.js +7 -0
  21. package/src/managers/skill-tools.js +565 -0
  22. package/src/monitoring/cost-tracker.js +7 -0
  23. package/src/monitoring/incident-manager.js +10 -0
  24. package/src/monitoring/observability.js +10 -0
  25. package/src/monitoring/quality-dashboard.js +491 -0
  26. package/src/monitoring/release-manager.js +10 -0
  27. package/src/orchestration/agent-skill-binding.js +655 -0
  28. package/src/orchestration/error-handler.js +827 -0
  29. package/src/orchestration/index.js +235 -1
  30. package/src/orchestration/mcp-tool-adapters.js +896 -0
  31. package/src/orchestration/reasoning/index.js +58 -0
  32. package/src/orchestration/reasoning/planning-engine.js +831 -0
  33. package/src/orchestration/reasoning/reasoning-engine.js +710 -0
  34. package/src/orchestration/reasoning/self-correction.js +751 -0
  35. package/src/orchestration/skill-executor.js +665 -0
  36. package/src/orchestration/skill-registry.js +650 -0
  37. package/src/orchestration/workflow-examples.js +1072 -0
  38. package/src/orchestration/workflow-executor.js +779 -0
  39. package/src/phase4-integration.js +248 -0
  40. package/src/phase5-integration.js +402 -0
  41. package/src/steering/steering-auto-update.js +572 -0
  42. package/src/steering/steering-validator.js +547 -0
  43. package/src/templates/template-constraints.js +646 -0
  44. package/src/validators/advanced-validation.js +580 -0
@@ -0,0 +1,43 @@
1
+ /**
2
+ * @file Agentic Features Module - Index
3
+ * @description Export all agentic coding features
4
+ * @version 1.0.0
5
+ */
6
+
7
+ 'use strict';
8
+
9
+ const {
10
+ CodeGenerator,
11
+ createCodeGenerator,
12
+ generateCode,
13
+ GEN_MODE,
14
+ LANGUAGE,
15
+ TEMPLATES
16
+ } = require('./code-generator');
17
+
18
+ const {
19
+ CodeReviewer,
20
+ createCodeReviewer,
21
+ reviewCode,
22
+ SEVERITY,
23
+ CATEGORY,
24
+ DEFAULT_RULES
25
+ } = require('./code-reviewer');
26
+
27
+ module.exports = {
28
+ // Code Generator
29
+ CodeGenerator,
30
+ createCodeGenerator,
31
+ generateCode,
32
+ GEN_MODE,
33
+ LANGUAGE,
34
+ TEMPLATES,
35
+
36
+ // Code Reviewer
37
+ CodeReviewer,
38
+ createCodeReviewer,
39
+ reviewCode,
40
+ SEVERITY,
41
+ CATEGORY,
42
+ DEFAULT_RULES
43
+ };
@@ -0,0 +1,432 @@
1
+ /**
2
+ * MUSUBI Function Tool
3
+ *
4
+ * Provides decorator-style function registration and automatic
5
+ * schema generation from JSDoc comments. Inspired by OpenAI
6
+ * Agents SDK function tool patterns.
7
+ *
8
+ * @module agents/function-tool
9
+ */
10
+
11
+ /**
12
+ * @typedef {Object} FunctionToolOptions
13
+ * @property {string} [name] - Override function name
14
+ * @property {string} [description] - Tool description
15
+ * @property {Object} [parameters] - Override parameter schema
16
+ * @property {boolean} [strict=false] - Enable strict mode
17
+ */
18
+
19
+ /**
20
+ * @typedef {Object} ParameterSchema
21
+ * @property {string} type - JSON Schema type
22
+ * @property {string} [description] - Parameter description
23
+ * @property {boolean} [required] - Whether required
24
+ * @property {*} [default] - Default value
25
+ * @property {Array} [enum] - Allowed values
26
+ */
27
+
28
+ /**
29
+ * Map JavaScript types to JSON Schema types
30
+ */
31
+ const TYPE_MAP = {
32
+ 'string': 'string',
33
+ 'number': 'number',
34
+ 'integer': 'integer',
35
+ 'boolean': 'boolean',
36
+ 'object': 'object',
37
+ 'array': 'array',
38
+ 'any': 'object',
39
+ 'null': 'null',
40
+ 'undefined': 'null',
41
+ 'function': 'object',
42
+ 'symbol': 'string',
43
+ 'bigint': 'integer'
44
+ };
45
+
46
+ /**
47
+ * Parse JSDoc comment to extract parameter information
48
+ * @param {string} jsdoc - JSDoc comment string
49
+ * @returns {Object} Parsed JSDoc info
50
+ */
51
+ function parseJSDoc(jsdoc) {
52
+ if (!jsdoc) {
53
+ return { description: '', params: [], returns: null };
54
+ }
55
+
56
+ const lines = jsdoc.split('\n').map(l => l.replace(/^\s*\*\s?/, '').trim());
57
+ const result = {
58
+ description: '',
59
+ params: [],
60
+ returns: null,
61
+ example: null
62
+ };
63
+
64
+ let currentSection = 'description';
65
+ let descriptionLines = [];
66
+
67
+ for (const line of lines) {
68
+ if (line.startsWith('@param')) {
69
+ currentSection = 'param';
70
+ const match = line.match(/@param\s+\{([^}]+)\}\s+(\[)?(\w+)(?:\])?(?:\s*-?\s*(.*))?/);
71
+ if (match) {
72
+ const [, type, optional, name, description] = match;
73
+ result.params.push({
74
+ name,
75
+ type: type.toLowerCase(),
76
+ required: !optional,
77
+ description: description || ''
78
+ });
79
+ }
80
+ } else if (line.startsWith('@returns') || line.startsWith('@return')) {
81
+ currentSection = 'returns';
82
+ const match = line.match(/@returns?\s+\{([^}]+)\}\s*(.*)/);
83
+ if (match) {
84
+ result.returns = {
85
+ type: match[1].toLowerCase(),
86
+ description: match[2] || ''
87
+ };
88
+ }
89
+ } else if (line.startsWith('@example')) {
90
+ currentSection = 'example';
91
+ result.example = '';
92
+ } else if (line.startsWith('@')) {
93
+ currentSection = 'other';
94
+ } else if (currentSection === 'description' && line && !line.startsWith('/')) {
95
+ descriptionLines.push(line);
96
+ } else if (currentSection === 'example' && !line.startsWith('@')) {
97
+ result.example += (result.example ? '\n' : '') + line;
98
+ }
99
+ }
100
+
101
+ result.description = descriptionLines.join(' ').trim();
102
+ return result;
103
+ }
104
+
105
+ /**
106
+ * Convert parsed JSDoc to JSON Schema parameters
107
+ * @param {Array} params - Parsed param array
108
+ * @returns {Object} JSON Schema
109
+ */
110
+ function paramsToSchema(params) {
111
+ const properties = {};
112
+ const required = [];
113
+
114
+ for (const param of params) {
115
+ const schemaType = TYPE_MAP[param.type] || 'string';
116
+
117
+ properties[param.name] = {
118
+ type: schemaType,
119
+ description: param.description || `Parameter: ${param.name}`
120
+ };
121
+
122
+ // Handle union types (e.g., "string|number")
123
+ if (param.type.includes('|')) {
124
+ const types = param.type.split('|').map(t => TYPE_MAP[t.trim()] || 'string');
125
+ properties[param.name] = {
126
+ anyOf: types.map(t => ({ type: t })),
127
+ description: param.description
128
+ };
129
+ }
130
+
131
+ // Handle array types (e.g., "string[]")
132
+ if (param.type.endsWith('[]')) {
133
+ const itemType = TYPE_MAP[param.type.slice(0, -2)] || 'string';
134
+ properties[param.name] = {
135
+ type: 'array',
136
+ items: { type: itemType },
137
+ description: param.description
138
+ };
139
+ }
140
+
141
+ if (param.required) {
142
+ required.push(param.name);
143
+ }
144
+ }
145
+
146
+ return {
147
+ type: 'object',
148
+ properties,
149
+ required: required.length > 0 ? required : undefined,
150
+ additionalProperties: false
151
+ };
152
+ }
153
+
154
+ /**
155
+ * Create a function tool from a function with JSDoc
156
+ * @param {Function} fn - The function to wrap
157
+ * @param {FunctionToolOptions} [options] - Override options
158
+ * @returns {Object} Tool definition
159
+ */
160
+ function functionTool(fn, options = {}) {
161
+ const fnStr = fn.toString();
162
+ const name = options.name || fn.name || 'anonymous_tool';
163
+
164
+ // Try to extract JSDoc comment
165
+ let jsdocInfo = { description: '', params: [], returns: null };
166
+
167
+ // Check if function has __jsdoc property (from decorator)
168
+ if (fn.__jsdoc) {
169
+ jsdocInfo = parseJSDoc(fn.__jsdoc);
170
+ } else {
171
+ // Try to parse from function string (limited support)
172
+ const jsdocMatch = fnStr.match(/\/\*\*[\s\S]*?\*\//);
173
+ if (jsdocMatch) {
174
+ jsdocInfo = parseJSDoc(jsdocMatch[0]);
175
+ }
176
+ }
177
+
178
+ // Build parameter schema
179
+ let parameters = options.parameters;
180
+
181
+ if (!parameters && jsdocInfo.params.length > 0) {
182
+ parameters = paramsToSchema(jsdocInfo.params);
183
+ }
184
+
185
+ if (!parameters) {
186
+ // Try to infer from function parameters
187
+ const paramMatch = fnStr.match(/\(([^)]*)\)/);
188
+ if (paramMatch) {
189
+ const paramNames = paramMatch[1]
190
+ .split(',')
191
+ .map(p => p.trim().replace(/=.*$/, '').replace(/\{.*\}/, '').trim())
192
+ .filter(p => p && p !== '');
193
+
194
+ if (paramNames.length > 0) {
195
+ parameters = {
196
+ type: 'object',
197
+ properties: Object.fromEntries(
198
+ paramNames.map(name => [name, { type: 'string', description: `Parameter: ${name}` }])
199
+ ),
200
+ required: paramNames
201
+ };
202
+ }
203
+ }
204
+ }
205
+
206
+ // Default empty schema
207
+ parameters = parameters || { type: 'object', properties: {} };
208
+
209
+ return {
210
+ name,
211
+ description: options.description || jsdocInfo.description || `Function: ${name}`,
212
+ parameters,
213
+ handler: async (args) => {
214
+ // Call the original function with arguments
215
+ if (typeof args === 'object' && !Array.isArray(args)) {
216
+ // Pass as keyword arguments if possible
217
+ const paramNames = Object.keys(parameters.properties || {});
218
+ if (paramNames.length > 0) {
219
+ const orderedArgs = paramNames.map(name => args[name]);
220
+ return await fn(...orderedArgs);
221
+ }
222
+ }
223
+ return await fn(args);
224
+ },
225
+ __original: fn,
226
+ __jsdocInfo: jsdocInfo
227
+ };
228
+ }
229
+
230
+ /**
231
+ * Decorator-style wrapper for creating function tools
232
+ * Use with: const tool = asTool(myFunction, { description: '...' })
233
+ *
234
+ * @param {FunctionToolOptions} [options]
235
+ * @returns {Function} Decorator function
236
+ */
237
+ function asTool(options = {}) {
238
+ return function(fn) {
239
+ return functionTool(fn, options);
240
+ };
241
+ }
242
+
243
+ /**
244
+ * Create multiple function tools from an object of functions
245
+ * @param {Object<string, Function>} functions - Object with named functions
246
+ * @param {Object<string, FunctionToolOptions>} [options] - Per-function options
247
+ * @returns {Object[]} Array of tool definitions
248
+ */
249
+ function functionTools(functions, options = {}) {
250
+ return Object.entries(functions).map(([name, fn]) => {
251
+ const fnOptions = options[name] || {};
252
+ return functionTool(fn, { name, ...fnOptions });
253
+ });
254
+ }
255
+
256
+ /**
257
+ * Add JSDoc metadata to a function (for runtime access)
258
+ * @param {string} jsdoc - JSDoc comment
259
+ * @returns {Function} Decorator
260
+ */
261
+ function withJSDoc(jsdoc) {
262
+ return function(fn) {
263
+ fn.__jsdoc = jsdoc;
264
+ return fn;
265
+ };
266
+ }
267
+
268
+ /**
269
+ * Schema builder for complex parameter types
270
+ */
271
+ const SchemaBuilder = {
272
+ /**
273
+ * Create a string schema
274
+ * @param {Object} [options]
275
+ */
276
+ string(options = {}) {
277
+ return { type: 'string', ...options };
278
+ },
279
+
280
+ /**
281
+ * Create a number schema
282
+ * @param {Object} [options]
283
+ */
284
+ number(options = {}) {
285
+ return { type: 'number', ...options };
286
+ },
287
+
288
+ /**
289
+ * Create an integer schema
290
+ * @param {Object} [options]
291
+ */
292
+ integer(options = {}) {
293
+ return { type: 'integer', ...options };
294
+ },
295
+
296
+ /**
297
+ * Create a boolean schema
298
+ * @param {Object} [options]
299
+ */
300
+ boolean(options = {}) {
301
+ return { type: 'boolean', ...options };
302
+ },
303
+
304
+ /**
305
+ * Create an array schema
306
+ * @param {Object} itemSchema - Schema for array items
307
+ * @param {Object} [options]
308
+ */
309
+ array(itemSchema, options = {}) {
310
+ return { type: 'array', items: itemSchema, ...options };
311
+ },
312
+
313
+ /**
314
+ * Create an object schema
315
+ * @param {Object} properties - Property schemas
316
+ * @param {string[]} [required] - Required properties
317
+ * @param {Object} [options]
318
+ */
319
+ object(properties, required = [], options = {}) {
320
+ return {
321
+ type: 'object',
322
+ properties,
323
+ required: required.length > 0 ? required : undefined,
324
+ additionalProperties: options.additionalProperties ?? false,
325
+ ...options
326
+ };
327
+ },
328
+
329
+ /**
330
+ * Create an enum schema
331
+ * @param {Array} values - Allowed values
332
+ * @param {Object} [options]
333
+ */
334
+ enum(values, options = {}) {
335
+ return { type: 'string', enum: values, ...options };
336
+ },
337
+
338
+ /**
339
+ * Create a oneOf schema
340
+ * @param {Array} schemas - Possible schemas
341
+ */
342
+ oneOf(schemas) {
343
+ return { oneOf: schemas };
344
+ },
345
+
346
+ /**
347
+ * Create an anyOf schema
348
+ * @param {Array} schemas - Possible schemas
349
+ */
350
+ anyOf(schemas) {
351
+ return { anyOf: schemas };
352
+ }
353
+ };
354
+
355
+ /**
356
+ * Validate arguments against a schema
357
+ * @param {Object} args - Arguments to validate
358
+ * @param {Object} schema - JSON Schema
359
+ * @returns {Object} Validation result
360
+ */
361
+ function validateArgs(args, schema) {
362
+ const errors = [];
363
+
364
+ if (schema.type === 'object' && schema.properties) {
365
+ // Check required properties
366
+ if (schema.required) {
367
+ for (const prop of schema.required) {
368
+ if (args[prop] === undefined) {
369
+ errors.push(`Missing required parameter: ${prop}`);
370
+ }
371
+ }
372
+ }
373
+
374
+ // Type check each property
375
+ for (const [name, value] of Object.entries(args)) {
376
+ const propSchema = schema.properties[name];
377
+ if (!propSchema && schema.additionalProperties === false) {
378
+ errors.push(`Unknown parameter: ${name}`);
379
+ continue;
380
+ }
381
+
382
+ if (propSchema) {
383
+ const typeError = validateType(value, propSchema, name);
384
+ if (typeError) {
385
+ errors.push(typeError);
386
+ }
387
+ }
388
+ }
389
+ }
390
+
391
+ return {
392
+ valid: errors.length === 0,
393
+ errors
394
+ };
395
+ }
396
+
397
+ /**
398
+ * Validate a value against a type schema
399
+ * @param {*} value
400
+ * @param {Object} schema
401
+ * @param {string} name
402
+ * @returns {string|null} Error message or null
403
+ */
404
+ function validateType(value, schema, name) {
405
+ const expectedType = schema.type;
406
+ const actualType = Array.isArray(value) ? 'array' : typeof value;
407
+
408
+ if (expectedType && actualType !== expectedType) {
409
+ // Allow number for integer
410
+ if (expectedType === 'integer' && typeof value === 'number' && Number.isInteger(value)) {
411
+ return null;
412
+ }
413
+ return `Parameter '${name}' expected ${expectedType}, got ${actualType}`;
414
+ }
415
+
416
+ if (schema.enum && !schema.enum.includes(value)) {
417
+ return `Parameter '${name}' must be one of: ${schema.enum.join(', ')}`;
418
+ }
419
+
420
+ return null;
421
+ }
422
+
423
+ module.exports = {
424
+ functionTool,
425
+ functionTools,
426
+ asTool,
427
+ withJSDoc,
428
+ parseJSDoc,
429
+ paramsToSchema,
430
+ SchemaBuilder,
431
+ validateArgs
432
+ };
@@ -0,0 +1,45 @@
1
+ /**
2
+ * MUSUBI Agents Module
3
+ *
4
+ * Exports agent-related functionality including Agent Loop,
5
+ * Function Tools, Schema Generation, and Agent Registry.
6
+ *
7
+ * @module agents
8
+ */
9
+
10
+ const { AgentLoop, createMockLLMProvider } = require('./agent-loop');
11
+ const {
12
+ functionTool,
13
+ functionTools,
14
+ asTool,
15
+ withJSDoc,
16
+ parseJSDoc,
17
+ paramsToSchema,
18
+ SchemaBuilder,
19
+ validateArgs
20
+ } = require('./function-tool');
21
+ const { SchemaGenerator, createSchemaGenerator } = require('./schema-generator');
22
+ const agentDefinitions = require('./registry');
23
+
24
+ module.exports = {
25
+ // Agent Loop
26
+ AgentLoop,
27
+ createMockLLMProvider,
28
+
29
+ // Function Tools
30
+ functionTool,
31
+ functionTools,
32
+ asTool,
33
+ withJSDoc,
34
+ parseJSDoc,
35
+ paramsToSchema,
36
+ SchemaBuilder,
37
+ validateArgs,
38
+
39
+ // Schema Generator
40
+ SchemaGenerator,
41
+ createSchemaGenerator,
42
+
43
+ // Agent Registry
44
+ agentDefinitions
45
+ };