codymaster 4.6.0 → 4.8.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 +19 -1
- package/README.md +80 -30
- package/dist/browse-server.js +251 -0
- package/dist/cli/command-registry.js +26 -0
- package/dist/cli/commands/agent.js +120 -0
- package/dist/cli/commands/dashboard.js +93 -0
- package/dist/cli/commands/design-studio.js +111 -0
- package/dist/cli/commands/distro.js +25 -0
- package/dist/cli/commands/engineering.js +488 -0
- package/dist/cli/commands/project.js +324 -0
- package/dist/cli/commands/skill-chain.js +269 -0
- package/dist/cli/commands/system.js +89 -0
- package/dist/cli/commands/task.js +254 -0
- package/dist/cli/update-check.js +83 -0
- package/dist/cm-config.js +110 -0
- package/dist/cm-suggest.js +77 -0
- package/dist/distro-validate.js +54 -0
- package/dist/guardian-core.js +74 -0
- package/dist/index.js +36 -2759
- package/dist/mcp-context-server.js +60 -1
- package/dist/mcp-skills-tools.js +81 -0
- package/dist/retro-summary.js +70 -0
- package/dist/second-opinion-providers.js +79 -0
- package/dist/sprint-pipeline.js +228 -0
- package/dist/storage-backend.js +5 -60
- package/dist/utils/cli-utils.js +76 -0
- package/dist/utils/skill-utils.js +32 -0
- package/install.sh +274 -50
- package/package.json +16 -5
- package/scripts/build-skills.mjs +51 -0
- package/scripts/gate-0-repo-hygiene.js +75 -0
- package/scripts/postinstall.js +55 -0
- package/scripts/security-scan.js +1 -1
- package/scripts/validate-skills.mjs +42 -0
- package/scripts/viking-demo.ts +105 -0
- package/skills/CLAUDE.md +2 -2
- package/skills/cm-ads-tracker/SKILL.md +3 -6
- package/skills/cm-browse/SKILL.md +28 -0
- package/skills/cm-conductor-worktrees/SKILL.md +24 -0
- package/skills/cm-content-factory/SKILL.md +1 -1
- package/skills/cm-content-factory/landing/docs/content/changelog.md +36 -0
- package/skills/cm-content-factory/landing/docs/content/deployment.md +46 -0
- package/skills/cm-content-factory/landing/docs/content/execution-flow.md +67 -0
- package/skills/cm-content-factory/landing/docs/content/openspace.md +27 -0
- package/skills/cm-content-factory/landing/docs/content/openviking.md +33 -0
- package/skills/cm-content-factory/landing/docs/content/use-cases.md +26 -0
- package/skills/cm-content-factory/landing/docs/content/v5-intro.md +28 -0
- package/skills/cm-content-factory/landing/docs/index.html +240 -0
- package/skills/cm-content-factory/landing/index.html +99 -99
- package/skills/cm-content-factory/landing/script.js +42 -0
- package/skills/cm-content-factory/landing/translations.js +400 -400
- package/skills/cm-design-studio/SKILL.md +30 -0
- package/skills/cm-ecosystem-roadmap/SKILL.md +11 -0
- package/skills/cm-engineering-meta/SKILL.md +69 -0
- package/skills/cm-growth-hacking/SKILL.md +1 -12
- package/skills/cm-guardian-runtime/SKILL.md +22 -0
- package/skills/cm-mcp-engineering/SKILL.md +18 -0
- package/skills/cm-notebooklm/SKILL.md +1 -17
- package/skills/cm-post-deploy-canary/SKILL.md +18 -0
- package/skills/cm-qa-visual-cli/SKILL.md +18 -0
- package/skills/cm-retro-cli/SKILL.md +19 -0
- package/skills/cm-second-opinion-cli/SKILL.md +19 -0
- package/skills/cm-secret-shield/SKILL.md +2 -2
- package/skills/cm-sprint-bus/SKILL.md +29 -0
- package/skills/cm-tdd/SKILL.md +61 -74
- package/skills/profiles/README.md +21 -0
- package/skills/profiles/core.txt +23 -0
- package/skills/profiles/design.txt +6 -0
- package/skills/profiles/full.txt +58 -0
- package/skills/profiles/growth.txt +10 -0
- package/skills/profiles/knowledge.txt +7 -0
- package/scripts/test-gemini.js +0 -13
- package/skills/cm-frappe-agent/SKILL.md +0 -134
- package/skills/cm-frappe-agent/agents/doctype-architect.md +0 -596
- package/skills/cm-frappe-agent/agents/erpnext-customizer.md +0 -643
- package/skills/cm-frappe-agent/agents/frappe-backend.md +0 -814
- package/skills/cm-frappe-agent/agents/frappe-custom-frontend.md +0 -557
- package/skills/cm-frappe-agent/agents/frappe-debugger.md +0 -625
- package/skills/cm-frappe-agent/agents/frappe-fixer.md +0 -275
- package/skills/cm-frappe-agent/agents/frappe-frontend.md +0 -660
- package/skills/cm-frappe-agent/agents/frappe-installer.md +0 -158
- package/skills/cm-frappe-agent/agents/frappe-performance.md +0 -307
- package/skills/cm-frappe-agent/agents/frappe-planner.md +0 -419
- package/skills/cm-frappe-agent/agents/frappe-remote-ops.md +0 -153
- package/skills/cm-frappe-agent/agents/github-workflow.md +0 -286
- package/skills/cm-frappe-agent/commands/frappe-app.md +0 -351
- package/skills/cm-frappe-agent/commands/frappe-backend.md +0 -162
- package/skills/cm-frappe-agent/commands/frappe-bench.md +0 -254
- package/skills/cm-frappe-agent/commands/frappe-debug.md +0 -263
- package/skills/cm-frappe-agent/commands/frappe-doctype-create.md +0 -272
- package/skills/cm-frappe-agent/commands/frappe-doctype-field.md +0 -310
- package/skills/cm-frappe-agent/commands/frappe-erpnext.md +0 -210
- package/skills/cm-frappe-agent/commands/frappe-fix.md +0 -59
- package/skills/cm-frappe-agent/commands/frappe-frontend.md +0 -210
- package/skills/cm-frappe-agent/commands/frappe-fullstack.md +0 -243
- package/skills/cm-frappe-agent/commands/frappe-github.md +0 -57
- package/skills/cm-frappe-agent/commands/frappe-install.md +0 -52
- package/skills/cm-frappe-agent/commands/frappe-plan.md +0 -442
- package/skills/cm-frappe-agent/commands/frappe-remote.md +0 -58
- package/skills/cm-frappe-agent/commands/frappe-test.md +0 -356
- package/skills/cm-frappe-agent/docs/README.md +0 -51
- package/skills/cm-frappe-agent/docs/agents-catalog.md +0 -113
- package/skills/cm-frappe-agent/docs/architecture.md +0 -149
- package/skills/cm-frappe-agent/docs/commands-catalog.md +0 -82
- package/skills/cm-frappe-agent/docs/resources-catalog.md +0 -66
- package/skills/cm-frappe-agent/docs/sitemap-urls.txt +0 -52
- package/skills/cm-frappe-agent/docs/sitemap.md +0 -81
- package/skills/cm-frappe-agent/docs/sop/user-guide.md +0 -178
- package/skills/cm-frappe-agent/docs/sop/vibe-coding-guide.md +0 -122
- package/skills/cm-frappe-agent/resources/7-layer-architecture.md +0 -985
- package/skills/cm-frappe-agent/resources/bench_commands.md +0 -73
- package/skills/cm-frappe-agent/resources/code-patterns-guide.md +0 -948
- package/skills/cm-frappe-agent/resources/common_pitfalls.md +0 -266
- package/skills/cm-frappe-agent/resources/doctype-registry.md +0 -158
- package/skills/cm-frappe-agent/resources/installation-guide.md +0 -289
- package/skills/cm-frappe-agent/resources/rest-api-patterns.md +0 -182
- package/skills/cm-frappe-agent/resources/scaffold_checklist.md +0 -82
- package/skills/cm-frappe-agent/resources/upgrade_patterns.md +0 -113
- package/skills/cm-frappe-agent/resources/web-form-patterns.md +0 -252
- package/skills/cm-frappe-agent/skills/bench-commands/SKILL.md +0 -621
- package/skills/cm-frappe-agent/skills/client-scripts/SKILL.md +0 -642
- package/skills/cm-frappe-agent/skills/doctype-patterns/SKILL.md +0 -576
- package/skills/cm-frappe-agent/skills/frappe-api/SKILL.md +0 -740
- package/skills/cm-frappe-agent/skills/remote-operations/SKILL.md +0 -47
- package/skills/cm-frappe-agent/skills/server-scripts/SKILL.md +0 -608
- package/skills/cm-frappe-agent/skills/web-forms/SKILL.md +0 -46
- package/skills/frappe-app-builder.zip +0 -0
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
/**
|
|
4
4
|
* CodyMaster MCP Context Server
|
|
5
5
|
*
|
|
6
|
-
* Exposes
|
|
6
|
+
* Exposes 13 tools over JSON-RPC 2.0 / stdio (Content-Length framing):
|
|
7
7
|
* cm_query — FTS5 search across learnings + decisions
|
|
8
8
|
* cm_resolve — resolve a cm:// URI at L0/L1/L2
|
|
9
9
|
* cm_bus_read — read context bus state
|
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
* cm_budget_check — check token budget for a category
|
|
12
12
|
* cm_memory_decay — TTL cleanup for learnings
|
|
13
13
|
* cm_index_refresh — regenerate L0 indexes
|
|
14
|
+
* cm_plan / cm_review / cm_qa / cm_deploy / cm_search / cm_memory_query — engineering kit bridge
|
|
14
15
|
*
|
|
15
16
|
* Usage (stdio MCP):
|
|
16
17
|
* node dist/mcp-context-server.js --project /path/to/project
|
|
@@ -44,6 +45,7 @@ const uri_resolver_1 = require("./uri-resolver");
|
|
|
44
45
|
const context_bus_1 = require("./context-bus");
|
|
45
46
|
const token_budget_1 = require("./token-budget");
|
|
46
47
|
const l0_indexer_1 = require("./l0-indexer");
|
|
48
|
+
const mcp_skills_tools_1 = require("./mcp-skills-tools");
|
|
47
49
|
// ─── Config ──────────────────────────────────────────────────────────────────
|
|
48
50
|
const SERVER_NAME = 'cm-context';
|
|
49
51
|
const SERVER_VERSION = '1.0.0';
|
|
@@ -295,6 +297,51 @@ const TOOLS = [
|
|
|
295
297
|
},
|
|
296
298
|
},
|
|
297
299
|
},
|
|
300
|
+
{
|
|
301
|
+
name: 'cm_plan',
|
|
302
|
+
description: 'Sprint + context bus snapshot: pipeline state, next skill hint, artifact paths.',
|
|
303
|
+
inputSchema: { type: 'object', properties: {} },
|
|
304
|
+
},
|
|
305
|
+
{
|
|
306
|
+
name: 'cm_review',
|
|
307
|
+
description: 'Read sprint review artifact preview if present; points to cm-code-review workflow.',
|
|
308
|
+
inputSchema: { type: 'object', properties: {} },
|
|
309
|
+
},
|
|
310
|
+
{
|
|
311
|
+
name: 'cm_qa',
|
|
312
|
+
description: 'QA hints: browse daemon, visual QA CLI, quality gates.',
|
|
313
|
+
inputSchema: { type: 'object', properties: {} },
|
|
314
|
+
},
|
|
315
|
+
{
|
|
316
|
+
name: 'cm_deploy',
|
|
317
|
+
description: 'Deploy workflow hints (cm-safe-deploy, canary).',
|
|
318
|
+
inputSchema: { type: 'object', properties: {} },
|
|
319
|
+
},
|
|
320
|
+
{
|
|
321
|
+
name: 'cm_search',
|
|
322
|
+
description: 'Search learnings + decisions (same backing store as cm_query).',
|
|
323
|
+
inputSchema: {
|
|
324
|
+
type: 'object',
|
|
325
|
+
properties: {
|
|
326
|
+
query: { type: 'string' },
|
|
327
|
+
scope: { type: 'string', enum: ['learnings', 'decisions', 'all'] },
|
|
328
|
+
limit: { type: 'number' },
|
|
329
|
+
},
|
|
330
|
+
required: ['query'],
|
|
331
|
+
},
|
|
332
|
+
},
|
|
333
|
+
{
|
|
334
|
+
name: 'cm_memory_query',
|
|
335
|
+
description: 'Alias-style memory search across learnings and decisions.',
|
|
336
|
+
inputSchema: {
|
|
337
|
+
type: 'object',
|
|
338
|
+
properties: {
|
|
339
|
+
query: { type: 'string' },
|
|
340
|
+
limit: { type: 'number' },
|
|
341
|
+
},
|
|
342
|
+
required: ['query'],
|
|
343
|
+
},
|
|
344
|
+
},
|
|
298
345
|
];
|
|
299
346
|
// ─── MCP stdio protocol (JSON-RPC 2.0, Content-Length framing) ───────────────
|
|
300
347
|
function sendMessage(msg) {
|
|
@@ -344,6 +391,18 @@ function handleRequest(msg) {
|
|
|
344
391
|
result = cmMemoryDecay(a);
|
|
345
392
|
else if (name === 'cm_index_refresh')
|
|
346
393
|
result = cmIndexRefresh(a);
|
|
394
|
+
else if (name === 'cm_plan')
|
|
395
|
+
result = (0, mcp_skills_tools_1.cmPlanTool)(PROJECT_PATH);
|
|
396
|
+
else if (name === 'cm_review')
|
|
397
|
+
result = (0, mcp_skills_tools_1.cmReviewTool)(PROJECT_PATH);
|
|
398
|
+
else if (name === 'cm_qa')
|
|
399
|
+
result = (0, mcp_skills_tools_1.cmQaTool)(PROJECT_PATH);
|
|
400
|
+
else if (name === 'cm_deploy')
|
|
401
|
+
result = (0, mcp_skills_tools_1.cmDeployTool)(PROJECT_PATH);
|
|
402
|
+
else if (name === 'cm_search')
|
|
403
|
+
result = (0, mcp_skills_tools_1.cmSearchTool)(PROJECT_PATH, a);
|
|
404
|
+
else if (name === 'cm_memory_query')
|
|
405
|
+
result = (0, mcp_skills_tools_1.cmMemoryQueryTool)(PROJECT_PATH, a);
|
|
347
406
|
else
|
|
348
407
|
throw new Error(`Unknown tool: ${name}`);
|
|
349
408
|
respond(id, {
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Extra MCP tool handlers: plan/review/qa/deploy/search — bridge to sprint + memory.
|
|
4
|
+
*/
|
|
5
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
6
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
7
|
+
};
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.cmPlanTool = cmPlanTool;
|
|
10
|
+
exports.cmReviewTool = cmReviewTool;
|
|
11
|
+
exports.cmQaTool = cmQaTool;
|
|
12
|
+
exports.cmDeployTool = cmDeployTool;
|
|
13
|
+
exports.cmSearchTool = cmSearchTool;
|
|
14
|
+
exports.cmMemoryQueryTool = cmMemoryQueryTool;
|
|
15
|
+
const fs_1 = __importDefault(require("fs"));
|
|
16
|
+
const path_1 = __importDefault(require("path"));
|
|
17
|
+
const context_bus_1 = require("./context-bus");
|
|
18
|
+
const sprint_pipeline_1 = require("./sprint-pipeline");
|
|
19
|
+
const context_db_1 = require("./context-db");
|
|
20
|
+
function cmPlanTool(projectPath) {
|
|
21
|
+
const sprint = (0, sprint_pipeline_1.readSprintState)(projectPath);
|
|
22
|
+
const bus = (0, context_bus_1.readBus)(projectPath);
|
|
23
|
+
const preview = (0, sprint_pipeline_1.sprintArtifactPreviewFromDisk)(projectPath);
|
|
24
|
+
return {
|
|
25
|
+
sprint_active: !!sprint,
|
|
26
|
+
sprint: sprint !== null && sprint !== void 0 ? sprint : null,
|
|
27
|
+
context_bus: bus,
|
|
28
|
+
default_pipeline: sprint_pipeline_1.SPRINT_STEPS,
|
|
29
|
+
next_skill_hint: sprint
|
|
30
|
+
? sprint.current_index >= sprint.pipeline.length
|
|
31
|
+
? '(sprint complete — run cm-retro)'
|
|
32
|
+
: (0, sprint_pipeline_1.skillMappingForStep)(sprint.pipeline[sprint.current_index])
|
|
33
|
+
: 'cm-planning',
|
|
34
|
+
artifact_paths: preview.artifacts,
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
function cmReviewTool(projectPath) {
|
|
38
|
+
const artDir = path_1.default.join(projectPath, '.cm', 'sprint', 'artifacts', 'review.md');
|
|
39
|
+
let review = '';
|
|
40
|
+
if (fs_1.default.existsSync(artDir))
|
|
41
|
+
review = fs_1.default.readFileSync(artDir, 'utf8');
|
|
42
|
+
return {
|
|
43
|
+
review_artifact: artDir,
|
|
44
|
+
has_content: review.length > 0,
|
|
45
|
+
preview: review.slice(0, 4000),
|
|
46
|
+
hint: 'Use cm-code-review skill for full checklist; paste diff + requirements.',
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
function cmQaTool(projectPath) {
|
|
50
|
+
return {
|
|
51
|
+
browse_daemon: 'Run: cm browse start --token <secret> then POST /session/start',
|
|
52
|
+
visual: 'cm qa-visual --url http://localhost:3000',
|
|
53
|
+
gates: ['cm-quality-gate', 'cm-test-gate'],
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
function cmDeployTool(projectPath) {
|
|
57
|
+
return {
|
|
58
|
+
hint: 'Use cm-safe-deploy skill; after ship run cm canary --url <prod>',
|
|
59
|
+
project: projectPath,
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
function cmSearchTool(projectPath, args) {
|
|
63
|
+
const { query, scope = 'all', limit = 10 } = args;
|
|
64
|
+
const dbPath = (0, context_db_1.getDbPath)(projectPath);
|
|
65
|
+
(0, context_db_1.openDb)(dbPath);
|
|
66
|
+
const results = [];
|
|
67
|
+
if (scope === 'all' || scope === 'learnings') {
|
|
68
|
+
for (const l of (0, context_db_1.queryLearnings)(dbPath, query, undefined, limit)) {
|
|
69
|
+
results.push(Object.assign({ type: 'learning' }, l));
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
if (scope === 'all' || scope === 'decisions') {
|
|
73
|
+
for (const d of (0, context_db_1.queryDecisions)(dbPath, query, limit)) {
|
|
74
|
+
results.push(Object.assign({ type: 'decision' }, d));
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
return { query, scope, count: results.length, results };
|
|
78
|
+
}
|
|
79
|
+
function cmMemoryQueryTool(projectPath, args) {
|
|
80
|
+
return cmSearchTool(projectPath, Object.assign(Object.assign({}, args), { scope: 'all' }));
|
|
81
|
+
}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Aggregate `.cm/operational-learnings.jsonl` for `cm retro summary`.
|
|
4
|
+
*/
|
|
5
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
6
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
7
|
+
};
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.loadRetroEntries = loadRetroEntries;
|
|
10
|
+
exports.filterSince = filterSince;
|
|
11
|
+
exports.countByTool = countByTool;
|
|
12
|
+
exports.formatRetroMarkdown = formatRetroMarkdown;
|
|
13
|
+
exports.formatRetroJson = formatRetroJson;
|
|
14
|
+
const fs_1 = __importDefault(require("fs"));
|
|
15
|
+
function loadRetroEntries(filePath) {
|
|
16
|
+
if (!fs_1.default.existsSync(filePath))
|
|
17
|
+
return [];
|
|
18
|
+
const out = [];
|
|
19
|
+
for (const line of fs_1.default.readFileSync(filePath, 'utf8').split('\n')) {
|
|
20
|
+
const t = line.trim();
|
|
21
|
+
if (!t)
|
|
22
|
+
continue;
|
|
23
|
+
try {
|
|
24
|
+
const o = JSON.parse(t);
|
|
25
|
+
if (typeof o.ts === 'string' && typeof o.note === 'string') {
|
|
26
|
+
out.push({
|
|
27
|
+
ts: o.ts,
|
|
28
|
+
tool: typeof o.tool === 'string' ? o.tool : 'unknown',
|
|
29
|
+
note: o.note,
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
catch (_a) {
|
|
34
|
+
/* skip malformed line */
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
return out;
|
|
38
|
+
}
|
|
39
|
+
function filterSince(entries, sinceIso) {
|
|
40
|
+
const t0 = new Date(sinceIso).getTime();
|
|
41
|
+
if (Number.isNaN(t0))
|
|
42
|
+
return entries;
|
|
43
|
+
return entries.filter((e) => new Date(e.ts).getTime() >= t0);
|
|
44
|
+
}
|
|
45
|
+
function countByTool(entries) {
|
|
46
|
+
const m = {};
|
|
47
|
+
for (const e of entries) {
|
|
48
|
+
m[e.tool] = (m[e.tool] || 0) + 1;
|
|
49
|
+
}
|
|
50
|
+
return m;
|
|
51
|
+
}
|
|
52
|
+
function formatRetroMarkdown(entries, byTool) {
|
|
53
|
+
const lines = ['# Retro summary', '', `**Total entries:** ${entries.length}`, ''];
|
|
54
|
+
lines.push('## By tool');
|
|
55
|
+
for (const [tool, n] of Object.entries(byTool).sort((a, b) => b[1] - a[1])) {
|
|
56
|
+
lines.push(`- **${tool}:** ${n}`);
|
|
57
|
+
}
|
|
58
|
+
lines.push('', '## Entries (chronological)');
|
|
59
|
+
for (const e of entries.sort((a, b) => a.ts.localeCompare(b.ts))) {
|
|
60
|
+
lines.push(`- \`${e.ts}\` [${e.tool}] ${e.note}`);
|
|
61
|
+
}
|
|
62
|
+
return lines.join('\n');
|
|
63
|
+
}
|
|
64
|
+
function formatRetroJson(entries, byTool) {
|
|
65
|
+
return JSON.stringify({
|
|
66
|
+
total: entries.length,
|
|
67
|
+
by_tool: byTool,
|
|
68
|
+
entries: entries.sort((a, b) => a.ts.localeCompare(b.ts)),
|
|
69
|
+
}, null, 2);
|
|
70
|
+
}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Redaction + secondary-model review for `cm second-opinion`.
|
|
4
|
+
*/
|
|
5
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
6
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
7
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
8
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
9
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
10
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
11
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
12
|
+
});
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.redactDiffForReview = redactDiffForReview;
|
|
16
|
+
exports.reviewWithOpenAI = reviewWithOpenAI;
|
|
17
|
+
exports.reviewWithAnthropic = reviewWithAnthropic;
|
|
18
|
+
const SYSTEM = 'You are a senior reviewer. List risks, bugs, and missing tests. Be concise. Do not restate the entire diff.';
|
|
19
|
+
function redactDiffForReview(text, maxLen = 120000) {
|
|
20
|
+
let t = text.slice(0, maxLen);
|
|
21
|
+
t = t.replace(/^(\s*(?:#\s*)?(?:API_KEY|API_SECRET|SECRET|PASSWORD|ACCESS_TOKEN|AUTH_TOKEN|BEARER|Authorization)\s*[:=]\s*)\S+.*$/gim, '$1[REDACTED]');
|
|
22
|
+
t = t.replace(/\b(sk-[a-zA-Z0-9]{20,}|xox[baprs]-[A-Za-z0-9-]{10,}|ghp_[A-Za-z0-9]{36,}|gho_[A-Za-z0-9]{36,}|AKIA[0-9A-Z]{16})\b/g, '[REDACTED_TOKEN]');
|
|
23
|
+
return t;
|
|
24
|
+
}
|
|
25
|
+
function reviewWithOpenAI(diffText) {
|
|
26
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
27
|
+
var _a, _b, _c, _d;
|
|
28
|
+
const key = process.env.OPENAI_API_KEY;
|
|
29
|
+
if (!key)
|
|
30
|
+
throw new Error('OPENAI_API_KEY is not set');
|
|
31
|
+
const model = process.env.CM_SECOND_OPINION_MODEL || 'gpt-4o-mini';
|
|
32
|
+
const res = yield fetch('https://api.openai.com/v1/chat/completions', {
|
|
33
|
+
method: 'POST',
|
|
34
|
+
headers: {
|
|
35
|
+
'Content-Type': 'application/json',
|
|
36
|
+
Authorization: `Bearer ${key}`,
|
|
37
|
+
},
|
|
38
|
+
body: JSON.stringify({
|
|
39
|
+
model,
|
|
40
|
+
messages: [
|
|
41
|
+
{ role: 'system', content: SYSTEM },
|
|
42
|
+
{ role: 'user', content: `Review this diff:\n\n${diffText}` },
|
|
43
|
+
],
|
|
44
|
+
}),
|
|
45
|
+
});
|
|
46
|
+
if (!res.ok)
|
|
47
|
+
throw new Error(yield res.text());
|
|
48
|
+
const data = (yield res.json());
|
|
49
|
+
return (_d = (_c = (_b = (_a = data.choices) === null || _a === void 0 ? void 0 : _a[0]) === null || _b === void 0 ? void 0 : _b.message) === null || _c === void 0 ? void 0 : _c.content) !== null && _d !== void 0 ? _d : '';
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
function reviewWithAnthropic(diffText) {
|
|
53
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
54
|
+
var _a, _b;
|
|
55
|
+
const key = process.env.ANTHROPIC_API_KEY;
|
|
56
|
+
if (!key)
|
|
57
|
+
throw new Error('ANTHROPIC_API_KEY is not set');
|
|
58
|
+
const model = process.env.CM_ANTHROPIC_MODEL || 'claude-3-5-haiku-20241022';
|
|
59
|
+
const res = yield fetch('https://api.anthropic.com/v1/messages', {
|
|
60
|
+
method: 'POST',
|
|
61
|
+
headers: {
|
|
62
|
+
'Content-Type': 'application/json',
|
|
63
|
+
'x-api-key': key,
|
|
64
|
+
'anthropic-version': '2023-06-01',
|
|
65
|
+
},
|
|
66
|
+
body: JSON.stringify({
|
|
67
|
+
model,
|
|
68
|
+
max_tokens: 4096,
|
|
69
|
+
system: SYSTEM,
|
|
70
|
+
messages: [{ role: 'user', content: `Review this diff:\n\n${diffText}` }],
|
|
71
|
+
}),
|
|
72
|
+
});
|
|
73
|
+
if (!res.ok)
|
|
74
|
+
throw new Error(yield res.text());
|
|
75
|
+
const data = (yield res.json());
|
|
76
|
+
const block = (_a = data.content) === null || _a === void 0 ? void 0 : _a.find((c) => c.type === 'text');
|
|
77
|
+
return (_b = block === null || block === void 0 ? void 0 : block.text) !== null && _b !== void 0 ? _b : '';
|
|
78
|
+
});
|
|
79
|
+
}
|
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Opinionated sprint pipeline + Context Bus files under `.cm/sprint/`.
|
|
4
|
+
* Complements root `context-bus.json` with step artifacts (ADR 002).
|
|
5
|
+
*/
|
|
6
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
7
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
8
|
+
};
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.SPRINT_STEPS = void 0;
|
|
11
|
+
exports.readSprintState = readSprintState;
|
|
12
|
+
exports.writeSprintState = writeSprintState;
|
|
13
|
+
exports.initSprint = initSprint;
|
|
14
|
+
exports.completeSprintStep = completeSprintStep;
|
|
15
|
+
exports.skipSprintStep = skipSprintStep;
|
|
16
|
+
exports.resetSprint = resetSprint;
|
|
17
|
+
exports.sprintDryRun = sprintDryRun;
|
|
18
|
+
exports.sprintArtifactPreviewFromDisk = sprintArtifactPreviewFromDisk;
|
|
19
|
+
exports.skillMappingForStep = skillMappingForStep;
|
|
20
|
+
const fs_1 = __importDefault(require("fs"));
|
|
21
|
+
const path_1 = __importDefault(require("path"));
|
|
22
|
+
exports.SPRINT_STEPS = [
|
|
23
|
+
'brainstorm',
|
|
24
|
+
'plan',
|
|
25
|
+
'design',
|
|
26
|
+
'tdd',
|
|
27
|
+
'build',
|
|
28
|
+
'review',
|
|
29
|
+
'qa',
|
|
30
|
+
'security',
|
|
31
|
+
'ship',
|
|
32
|
+
'monitor',
|
|
33
|
+
'retro',
|
|
34
|
+
];
|
|
35
|
+
function sprintDir(projectPath) {
|
|
36
|
+
return path_1.default.join(projectPath, '.cm', 'sprint');
|
|
37
|
+
}
|
|
38
|
+
function statePath(projectPath) {
|
|
39
|
+
return path_1.default.join(sprintDir(projectPath), 'state.json');
|
|
40
|
+
}
|
|
41
|
+
function ensureSprintDir(projectPath) {
|
|
42
|
+
const d = sprintDir(projectPath);
|
|
43
|
+
const art = path_1.default.join(d, 'artifacts');
|
|
44
|
+
if (!fs_1.default.existsSync(art))
|
|
45
|
+
fs_1.default.mkdirSync(art, { recursive: true });
|
|
46
|
+
}
|
|
47
|
+
function normalizeSprintState(raw) {
|
|
48
|
+
var _a;
|
|
49
|
+
return Object.assign(Object.assign({}, raw), { version: raw.version === 2 ? 2 : 1, skipped: (_a = raw.skipped) !== null && _a !== void 0 ? _a : [] });
|
|
50
|
+
}
|
|
51
|
+
function readSprintState(projectPath) {
|
|
52
|
+
const p = statePath(projectPath);
|
|
53
|
+
if (!fs_1.default.existsSync(p))
|
|
54
|
+
return null;
|
|
55
|
+
try {
|
|
56
|
+
const raw = JSON.parse(fs_1.default.readFileSync(p, 'utf8'));
|
|
57
|
+
return normalizeSprintState(raw);
|
|
58
|
+
}
|
|
59
|
+
catch (_a) {
|
|
60
|
+
return null;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
function writeSprintState(projectPath, state) {
|
|
64
|
+
ensureSprintDir(projectPath);
|
|
65
|
+
fs_1.default.writeFileSync(statePath(projectPath), JSON.stringify(state, null, 2), 'utf8');
|
|
66
|
+
}
|
|
67
|
+
function initSprint(projectPath, fromStep) {
|
|
68
|
+
ensureSprintDir(projectPath);
|
|
69
|
+
const now = new Date().toISOString();
|
|
70
|
+
let pipeline = [...exports.SPRINT_STEPS];
|
|
71
|
+
let startIdx = 0;
|
|
72
|
+
if (fromStep) {
|
|
73
|
+
const i = pipeline.indexOf(fromStep);
|
|
74
|
+
if (i >= 0)
|
|
75
|
+
startIdx = i;
|
|
76
|
+
}
|
|
77
|
+
const state = {
|
|
78
|
+
version: 2,
|
|
79
|
+
pipeline,
|
|
80
|
+
current_index: startIdx,
|
|
81
|
+
completed: [],
|
|
82
|
+
skipped: [],
|
|
83
|
+
started_at: now,
|
|
84
|
+
updated_at: now,
|
|
85
|
+
artifacts_dir: path_1.default.join(sprintDir(projectPath), 'artifacts'),
|
|
86
|
+
};
|
|
87
|
+
writeSprintState(projectPath, state);
|
|
88
|
+
appendEvent(projectPath, { type: 'init', from: fromStep !== null && fromStep !== void 0 ? fromStep : null, at: now });
|
|
89
|
+
return state;
|
|
90
|
+
}
|
|
91
|
+
function completeSprintStep(projectPath, step, artifactBody) {
|
|
92
|
+
let state = readSprintState(projectPath);
|
|
93
|
+
if (!state)
|
|
94
|
+
state = initSprint(projectPath);
|
|
95
|
+
if (state.current_index >= state.pipeline.length) {
|
|
96
|
+
throw new Error('Sprint pipeline already finished');
|
|
97
|
+
}
|
|
98
|
+
const expected = state.pipeline[state.current_index];
|
|
99
|
+
if (expected !== step) {
|
|
100
|
+
throw new Error(`Expected step "${expected}", got "${step}"`);
|
|
101
|
+
}
|
|
102
|
+
const artFile = path_1.default.join(state.artifacts_dir, `${step}.md`);
|
|
103
|
+
fs_1.default.writeFileSync(artFile, artifactBody, 'utf8');
|
|
104
|
+
state.completed.push(step);
|
|
105
|
+
state.current_index = Math.min(state.current_index + 1, state.pipeline.length);
|
|
106
|
+
state.updated_at = new Date().toISOString();
|
|
107
|
+
state.version = 2;
|
|
108
|
+
writeSprintState(projectPath, state);
|
|
109
|
+
appendEvent(projectPath, { type: 'complete', step, at: state.updated_at });
|
|
110
|
+
return state;
|
|
111
|
+
}
|
|
112
|
+
const SKIP_STUB = (step, at) => `# ${step}\n\n_Skipped via \`cm sprint skip\` at ${at}._\n`;
|
|
113
|
+
function skipSprintStep(projectPath, step) {
|
|
114
|
+
let state = readSprintState(projectPath);
|
|
115
|
+
if (!state)
|
|
116
|
+
state = initSprint(projectPath);
|
|
117
|
+
if (state.current_index >= state.pipeline.length) {
|
|
118
|
+
throw new Error('Sprint pipeline already finished');
|
|
119
|
+
}
|
|
120
|
+
const expected = state.pipeline[state.current_index];
|
|
121
|
+
if (expected !== step) {
|
|
122
|
+
throw new Error(`Expected step "${expected}", got "${step}"`);
|
|
123
|
+
}
|
|
124
|
+
const at = new Date().toISOString();
|
|
125
|
+
const artFile = path_1.default.join(state.artifacts_dir, `${step}.md`);
|
|
126
|
+
fs_1.default.writeFileSync(artFile, SKIP_STUB(step, at), 'utf8');
|
|
127
|
+
state.skipped.push(step);
|
|
128
|
+
state.current_index = Math.min(state.current_index + 1, state.pipeline.length);
|
|
129
|
+
state.updated_at = at;
|
|
130
|
+
state.version = 2;
|
|
131
|
+
writeSprintState(projectPath, state);
|
|
132
|
+
appendEvent(projectPath, { type: 'skip', step, at });
|
|
133
|
+
return state;
|
|
134
|
+
}
|
|
135
|
+
function backupDirName() {
|
|
136
|
+
return new Date().toISOString().replace(/:/g, '-');
|
|
137
|
+
}
|
|
138
|
+
/** Remove sprint state; optional backup under `.cm/sprint/backup/<timestamp>/`. */
|
|
139
|
+
function resetSprint(projectPath, options) {
|
|
140
|
+
const backup = (options === null || options === void 0 ? void 0 : options.backup) !== false;
|
|
141
|
+
const sd = sprintDir(projectPath);
|
|
142
|
+
const st = statePath(projectPath);
|
|
143
|
+
const ev = eventsPath(projectPath);
|
|
144
|
+
const art = path_1.default.join(sd, 'artifacts');
|
|
145
|
+
const hasState = fs_1.default.existsSync(st);
|
|
146
|
+
let hasEvents = false;
|
|
147
|
+
if (fs_1.default.existsSync(ev)) {
|
|
148
|
+
try {
|
|
149
|
+
hasEvents = fs_1.default.statSync(ev).size > 0;
|
|
150
|
+
}
|
|
151
|
+
catch (_a) {
|
|
152
|
+
hasEvents = false;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
let hasArtifacts = false;
|
|
156
|
+
if (fs_1.default.existsSync(art)) {
|
|
157
|
+
try {
|
|
158
|
+
hasArtifacts = fs_1.default.readdirSync(art).length > 0;
|
|
159
|
+
}
|
|
160
|
+
catch (_b) {
|
|
161
|
+
hasArtifacts = false;
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
if (!hasState && !hasEvents && !hasArtifacts) {
|
|
165
|
+
return { ok: false, reason: 'no_sprint_data' };
|
|
166
|
+
}
|
|
167
|
+
let backupPath;
|
|
168
|
+
if (backup) {
|
|
169
|
+
const stamp = backupDirName();
|
|
170
|
+
backupPath = path_1.default.join(sd, 'backup', stamp);
|
|
171
|
+
fs_1.default.mkdirSync(backupPath, { recursive: true });
|
|
172
|
+
if (hasState)
|
|
173
|
+
fs_1.default.copyFileSync(st, path_1.default.join(backupPath, 'state.json'));
|
|
174
|
+
if (fs_1.default.existsSync(ev))
|
|
175
|
+
fs_1.default.copyFileSync(ev, path_1.default.join(backupPath, 'events.jsonl'));
|
|
176
|
+
if (fs_1.default.existsSync(art)) {
|
|
177
|
+
const destArt = path_1.default.join(backupPath, 'artifacts');
|
|
178
|
+
fs_1.default.cpSync(art, destArt, { recursive: true });
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
fs_1.default.rmSync(st, { force: true });
|
|
182
|
+
fs_1.default.rmSync(ev, { force: true });
|
|
183
|
+
fs_1.default.rmSync(art, { recursive: true, force: true });
|
|
184
|
+
fs_1.default.mkdirSync(art, { recursive: true });
|
|
185
|
+
return { ok: true, backupDir: backupPath };
|
|
186
|
+
}
|
|
187
|
+
function sprintDryRun(projectPath) {
|
|
188
|
+
var _a;
|
|
189
|
+
const state = (_a = readSprintState(projectPath)) !== null && _a !== void 0 ? _a : initSprint(projectPath);
|
|
190
|
+
return sprintArtifactPreview(state);
|
|
191
|
+
}
|
|
192
|
+
/** Read-only preview without creating files (for MCP / status). */
|
|
193
|
+
function sprintArtifactPreviewFromDisk(projectPath) {
|
|
194
|
+
const state = readSprintState(projectPath);
|
|
195
|
+
if (!state) {
|
|
196
|
+
const base = path_1.default.join(projectPath, '.cm', 'sprint', 'artifacts');
|
|
197
|
+
const artifacts = exports.SPRINT_STEPS.map((s) => path_1.default.join(base, `${s}.md`));
|
|
198
|
+
return { steps: [...exports.SPRINT_STEPS], artifacts };
|
|
199
|
+
}
|
|
200
|
+
return sprintArtifactPreview(state);
|
|
201
|
+
}
|
|
202
|
+
function sprintArtifactPreview(state) {
|
|
203
|
+
const artifacts = state.pipeline.map((s) => path_1.default.join(state.artifacts_dir, `${s}.md`));
|
|
204
|
+
return { steps: [...state.pipeline], artifacts };
|
|
205
|
+
}
|
|
206
|
+
function eventsPath(projectPath) {
|
|
207
|
+
return path_1.default.join(sprintDir(projectPath), 'events.jsonl');
|
|
208
|
+
}
|
|
209
|
+
function appendEvent(projectPath, rec) {
|
|
210
|
+
ensureSprintDir(projectPath);
|
|
211
|
+
fs_1.default.appendFileSync(eventsPath(projectPath), JSON.stringify(rec) + '\n', 'utf8');
|
|
212
|
+
}
|
|
213
|
+
function skillMappingForStep(step) {
|
|
214
|
+
const map = {
|
|
215
|
+
brainstorm: 'cm-brainstorm-idea',
|
|
216
|
+
plan: 'cm-planning',
|
|
217
|
+
design: 'cm-ui-preview / cm-design-system',
|
|
218
|
+
tdd: 'cm-tdd',
|
|
219
|
+
build: 'cm-execution',
|
|
220
|
+
review: 'cm-code-review',
|
|
221
|
+
qa: 'cm-quality-gate / cm-test-gate',
|
|
222
|
+
security: 'cm-secret-shield / cm-security-gate',
|
|
223
|
+
ship: 'cm-safe-deploy',
|
|
224
|
+
monitor: 'cm-canary (post-deploy)',
|
|
225
|
+
retro: 'cm-retro',
|
|
226
|
+
};
|
|
227
|
+
return map[step];
|
|
228
|
+
}
|
package/dist/storage-backend.js
CHANGED
|
@@ -1,16 +1,12 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
3
|
exports.VikingBackend = exports.SqliteBackend = void 0;
|
|
7
4
|
exports.getBackend = getBackend;
|
|
8
|
-
const fs_1 = __importDefault(require("fs"));
|
|
9
|
-
const path_1 = __importDefault(require("path"));
|
|
10
5
|
const context_db_1 = require("./context-db");
|
|
11
6
|
const viking_backend_1 = require("./backends/viking-backend");
|
|
12
7
|
Object.defineProperty(exports, "VikingBackend", { enumerable: true, get: function () { return viking_backend_1.VikingBackend; } });
|
|
13
8
|
const viking_http_client_1 = require("./backends/viking-http-client");
|
|
9
|
+
const cm_config_1 = require("./cm-config");
|
|
14
10
|
// ─── SqliteBackend ────────────────────────────────────────────────────────────
|
|
15
11
|
/**
|
|
16
12
|
* Default backend — thin wrapper around context-db.ts (better-sqlite3 + FTS5).
|
|
@@ -39,62 +35,11 @@ class SqliteBackend {
|
|
|
39
35
|
getSkillOutputs(sessionId) { return (0, context_db_1.getSkillOutputs)(this.dbPath, sessionId); }
|
|
40
36
|
}
|
|
41
37
|
exports.SqliteBackend = SqliteBackend;
|
|
42
|
-
/**
|
|
43
|
-
* Minimal YAML parser — reads `storage.backend` and `storage.viking.*` keys.
|
|
44
|
-
* Avoids adding a js-yaml dependency for a handful of config fields.
|
|
45
|
-
*
|
|
46
|
-
* Supported format:
|
|
47
|
-
* storage:
|
|
48
|
-
* backend: viking
|
|
49
|
-
* viking:
|
|
50
|
-
* host: localhost
|
|
51
|
-
* port: 1933
|
|
52
|
-
* workspace: codymaster
|
|
53
|
-
* timeout: 60000
|
|
54
|
-
*/
|
|
55
|
-
function loadStorageConfig(projectPath) {
|
|
56
|
-
var _a;
|
|
57
|
-
const configPath = path_1.default.join(projectPath, '.cm', 'config.yaml');
|
|
58
|
-
if (!fs_1.default.existsSync(configPath))
|
|
59
|
-
return {};
|
|
60
|
-
try {
|
|
61
|
-
const raw = fs_1.default.readFileSync(configPath, 'utf-8');
|
|
62
|
-
// Extract storage.backend
|
|
63
|
-
const backendMatch = raw.match(/^storage:\s*\n(?:[ \t]+\S[^\n]*\n)*?[ \t]+backend:\s*(\S+)/m);
|
|
64
|
-
const backend = (_a = backendMatch === null || backendMatch === void 0 ? void 0 : backendMatch[1]) === null || _a === void 0 ? void 0 : _a.trim();
|
|
65
|
-
// Extract storage.viking.* keys
|
|
66
|
-
const vikingBlock = raw.match(/[ \t]+viking:\s*\n((?:[ \t]{4,}[^\n]+\n?)*)/m);
|
|
67
|
-
let viking;
|
|
68
|
-
if (vikingBlock === null || vikingBlock === void 0 ? void 0 : vikingBlock[1]) {
|
|
69
|
-
viking = {};
|
|
70
|
-
for (const line of vikingBlock[1].split('\n')) {
|
|
71
|
-
const kv = line.match(/[ \t]+(\w+):\s*(\S+)/);
|
|
72
|
-
if (!kv)
|
|
73
|
-
continue;
|
|
74
|
-
const [, key, val] = kv;
|
|
75
|
-
if (key === 'host')
|
|
76
|
-
viking.host = val;
|
|
77
|
-
if (key === 'workspace')
|
|
78
|
-
viking.workspace = val;
|
|
79
|
-
if (key === 'port')
|
|
80
|
-
viking.port = parseInt(val, 10);
|
|
81
|
-
if (key === 'timeout')
|
|
82
|
-
viking.timeout = parseInt(val, 10);
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
if (!backend)
|
|
86
|
-
return {};
|
|
87
|
-
return { storage: Object.assign({ backend }, (viking ? { viking } : {})) };
|
|
88
|
-
}
|
|
89
|
-
catch (_b) {
|
|
90
|
-
return {};
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
38
|
// ─── Factory ─────────────────────────────────────────────────────────────────
|
|
94
39
|
/**
|
|
95
40
|
* Returns the configured StorageBackend for the given project.
|
|
96
41
|
*
|
|
97
|
-
* Reads `.cm/config.yaml → storage.backend` (default: `sqlite`).
|
|
42
|
+
* Reads `.cm/config.yaml → storage.backend` via `loadCmConfig` (default: `sqlite`).
|
|
98
43
|
* For `viking` backend, reads `storage.viking.*` for connection config.
|
|
99
44
|
*
|
|
100
45
|
* Usage:
|
|
@@ -104,11 +49,11 @@ function loadStorageConfig(projectPath) {
|
|
|
104
49
|
*/
|
|
105
50
|
function getBackend(projectPath) {
|
|
106
51
|
var _a, _b, _c;
|
|
107
|
-
const
|
|
108
|
-
const engine = (_b = (_a =
|
|
52
|
+
const cfg = (0, cm_config_1.loadCmConfig)(projectPath);
|
|
53
|
+
const engine = ((_b = (_a = cfg.storage) === null || _a === void 0 ? void 0 : _a.backend) !== null && _b !== void 0 ? _b : 'sqlite').toLowerCase();
|
|
109
54
|
switch (engine) {
|
|
110
55
|
case 'viking': {
|
|
111
|
-
const vikingConfig = Object.assign(Object.assign({}, viking_http_client_1.DEFAULT_VIKING_CONFIG), (_c =
|
|
56
|
+
const vikingConfig = Object.assign(Object.assign({}, viking_http_client_1.DEFAULT_VIKING_CONFIG), (_c = cfg.storage) === null || _c === void 0 ? void 0 : _c.viking);
|
|
112
57
|
return new viking_backend_1.VikingBackend(vikingConfig);
|
|
113
58
|
}
|
|
114
59
|
case 'sqlite':
|