codymaster 4.5.4 → 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 +46 -1
- package/README.md +86 -31
- package/dist/backends/viking-backend.js +235 -0
- package/dist/backends/viking-http-client.js +176 -0
- 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/continuity.js +8 -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 +63 -0
- package/dist/utils/cli-utils.js +76 -0
- package/dist/utils/skill-utils.js +32 -0
- package/install.sh +286 -58
- 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 +56 -1
- 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/_shared/helpers.md +10 -0
- 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-continuity/SKILL.md +33 -6
- 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-start/SKILL.md +11 -2
- 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
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* viking-http-client.ts
|
|
4
|
+
*
|
|
5
|
+
* Thin HTTP wrapper around the OpenViking REST API (localhost:1933 by default).
|
|
6
|
+
* Uses Node.js built-in `fetch` (Node 18+) — no extra dependencies.
|
|
7
|
+
*
|
|
8
|
+
* OpenViking API reference: https://github.com/volcengine/OpenViking
|
|
9
|
+
*/
|
|
10
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
11
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
12
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
13
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
14
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
15
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
16
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
17
|
+
});
|
|
18
|
+
};
|
|
19
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
20
|
+
exports.VikingHttpClient = exports.DEFAULT_VIKING_CONFIG = void 0;
|
|
21
|
+
exports.DEFAULT_VIKING_CONFIG = {
|
|
22
|
+
host: 'localhost',
|
|
23
|
+
port: 1933,
|
|
24
|
+
workspace: 'codymaster',
|
|
25
|
+
timeout: 60000,
|
|
26
|
+
};
|
|
27
|
+
// ─── Client ─────────────────────────────────────────────────────────────────
|
|
28
|
+
class VikingHttpClient {
|
|
29
|
+
constructor(config = exports.DEFAULT_VIKING_CONFIG) {
|
|
30
|
+
this.baseUrl = `http://${config.host}:${config.port}`;
|
|
31
|
+
this.workspace = config.workspace;
|
|
32
|
+
this.timeout = config.timeout;
|
|
33
|
+
}
|
|
34
|
+
// ── Helpers ──────────────────────────────────────────────────────────────
|
|
35
|
+
workspaceUri(path) {
|
|
36
|
+
// Normalize: ov://<workspace>/<path>
|
|
37
|
+
const clean = path.startsWith('/') ? path.slice(1) : path;
|
|
38
|
+
return `ov://${this.workspace}/${clean}`;
|
|
39
|
+
}
|
|
40
|
+
request(method, endpoint, body) {
|
|
41
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
42
|
+
const url = `${this.baseUrl}${endpoint}`;
|
|
43
|
+
const controller = new AbortController();
|
|
44
|
+
const timer = setTimeout(() => controller.abort(), this.timeout);
|
|
45
|
+
try {
|
|
46
|
+
const res = yield fetch(url, {
|
|
47
|
+
method,
|
|
48
|
+
headers: { 'Content-Type': 'application/json' },
|
|
49
|
+
body: body != null ? JSON.stringify(body) : undefined,
|
|
50
|
+
signal: controller.signal,
|
|
51
|
+
});
|
|
52
|
+
if (!res.ok) {
|
|
53
|
+
const text = yield res.text().catch(() => '');
|
|
54
|
+
throw new Error(`OpenViking HTTP ${res.status} at ${endpoint}: ${text}`);
|
|
55
|
+
}
|
|
56
|
+
// 204 No Content
|
|
57
|
+
if (res.status === 204)
|
|
58
|
+
return {};
|
|
59
|
+
return (yield res.json());
|
|
60
|
+
}
|
|
61
|
+
finally {
|
|
62
|
+
clearTimeout(timer);
|
|
63
|
+
}
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
// ── Health ────────────────────────────────────────────────────────────────
|
|
67
|
+
health() {
|
|
68
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
69
|
+
return this.request('GET', '/health');
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
isHealthy() {
|
|
73
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
74
|
+
try {
|
|
75
|
+
const status = yield this.health();
|
|
76
|
+
return status.healthy === true;
|
|
77
|
+
}
|
|
78
|
+
catch (_a) {
|
|
79
|
+
return false;
|
|
80
|
+
}
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
// ── Filesystem ops ────────────────────────────────────────────────────────
|
|
84
|
+
/**
|
|
85
|
+
* Write content to a URI.
|
|
86
|
+
* mode: 'overwrite' (default) | 'append'
|
|
87
|
+
*/
|
|
88
|
+
write(uriPath_1, content_1) {
|
|
89
|
+
return __awaiter(this, arguments, void 0, function* (uriPath, content, mode = 'overwrite') {
|
|
90
|
+
return this.request('POST', '/write', {
|
|
91
|
+
uri: this.workspaceUri(uriPath),
|
|
92
|
+
content,
|
|
93
|
+
mode,
|
|
94
|
+
wait: true,
|
|
95
|
+
});
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
/** Read content from a URI. */
|
|
99
|
+
read(uriPath) {
|
|
100
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
101
|
+
var _a;
|
|
102
|
+
const res = yield this.request('POST', '/read', {
|
|
103
|
+
uri: this.workspaceUri(uriPath),
|
|
104
|
+
});
|
|
105
|
+
return (_a = res.content) !== null && _a !== void 0 ? _a : '';
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
/** List items under a URI directory. */
|
|
109
|
+
ls(uriPath) {
|
|
110
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
111
|
+
var _a;
|
|
112
|
+
const res = yield this.request('POST', '/ls', {
|
|
113
|
+
uri: this.workspaceUri(uriPath),
|
|
114
|
+
});
|
|
115
|
+
return (_a = res.items) !== null && _a !== void 0 ? _a : [];
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
/** Delete a URI (file or directory). */
|
|
119
|
+
rm(uriPath_1) {
|
|
120
|
+
return __awaiter(this, arguments, void 0, function* (uriPath, recursive = false) {
|
|
121
|
+
yield this.request('POST', '/rm', {
|
|
122
|
+
uri: this.workspaceUri(uriPath),
|
|
123
|
+
recursive,
|
|
124
|
+
});
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
/** Create directory at URI. */
|
|
128
|
+
mkdir(uriPath) {
|
|
129
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
130
|
+
yield this.request('POST', '/mkdir', {
|
|
131
|
+
uri: this.workspaceUri(uriPath),
|
|
132
|
+
});
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
// ── Search ────────────────────────────────────────────────────────────────
|
|
136
|
+
/**
|
|
137
|
+
* Semantic vector search within a target URI scope.
|
|
138
|
+
* Returns top-k results sorted by relevance score.
|
|
139
|
+
*/
|
|
140
|
+
search(query_1, targetUriPath_1) {
|
|
141
|
+
return __awaiter(this, arguments, void 0, function* (query, targetUriPath, limit = 10, scoreThreshold) {
|
|
142
|
+
var _a;
|
|
143
|
+
const body = {
|
|
144
|
+
query,
|
|
145
|
+
target_uri: this.workspaceUri(targetUriPath),
|
|
146
|
+
limit,
|
|
147
|
+
};
|
|
148
|
+
if (scoreThreshold != null)
|
|
149
|
+
body.score_threshold = scoreThreshold;
|
|
150
|
+
const res = yield this.request('POST', '/search', body);
|
|
151
|
+
return (_a = res.items) !== null && _a !== void 0 ? _a : [];
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
// ── Tiered summaries ──────────────────────────────────────────────────────
|
|
155
|
+
/** Get L0 abstract summary of a URI. */
|
|
156
|
+
abstract(uriPath) {
|
|
157
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
158
|
+
var _a;
|
|
159
|
+
const res = yield this.request('POST', '/abstract', {
|
|
160
|
+
uri: this.workspaceUri(uriPath),
|
|
161
|
+
});
|
|
162
|
+
return (_a = res.content) !== null && _a !== void 0 ? _a : '';
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
/** Get L1 overview of a URI. */
|
|
166
|
+
overview(uriPath) {
|
|
167
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
168
|
+
var _a;
|
|
169
|
+
const res = yield this.request('POST', '/overview', {
|
|
170
|
+
uri: this.workspaceUri(uriPath),
|
|
171
|
+
});
|
|
172
|
+
return (_a = res.content) !== null && _a !== void 0 ? _a : '';
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
exports.VikingHttpClient = VikingHttpClient;
|
|
@@ -0,0 +1,251 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Local HTTP browse daemon (Playwright + Express). Bearer auth.
|
|
4
|
+
* Refs: POST /refs/refresh tags interactive elements with data-cm-ref.
|
|
5
|
+
*/
|
|
6
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
7
|
+
if (k2 === undefined) k2 = k;
|
|
8
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
9
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
10
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
11
|
+
}
|
|
12
|
+
Object.defineProperty(o, k2, desc);
|
|
13
|
+
}) : (function(o, m, k, k2) {
|
|
14
|
+
if (k2 === undefined) k2 = k;
|
|
15
|
+
o[k2] = m[k];
|
|
16
|
+
}));
|
|
17
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
18
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
19
|
+
}) : function(o, v) {
|
|
20
|
+
o["default"] = v;
|
|
21
|
+
});
|
|
22
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
23
|
+
var ownKeys = function(o) {
|
|
24
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
25
|
+
var ar = [];
|
|
26
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
27
|
+
return ar;
|
|
28
|
+
};
|
|
29
|
+
return ownKeys(o);
|
|
30
|
+
};
|
|
31
|
+
return function (mod) {
|
|
32
|
+
if (mod && mod.__esModule) return mod;
|
|
33
|
+
var result = {};
|
|
34
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
35
|
+
__setModuleDefault(result, mod);
|
|
36
|
+
return result;
|
|
37
|
+
};
|
|
38
|
+
})();
|
|
39
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
40
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
41
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
42
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
43
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
44
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
45
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
46
|
+
});
|
|
47
|
+
};
|
|
48
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
49
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
50
|
+
};
|
|
51
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
52
|
+
exports.BrowseDaemon = void 0;
|
|
53
|
+
const express_1 = __importDefault(require("express"));
|
|
54
|
+
function createRing(max) {
|
|
55
|
+
const buf = [];
|
|
56
|
+
return {
|
|
57
|
+
push(item) {
|
|
58
|
+
buf.push(item);
|
|
59
|
+
while (buf.length > max)
|
|
60
|
+
buf.shift();
|
|
61
|
+
},
|
|
62
|
+
snapshot: () => [...buf],
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
class BrowseDaemon {
|
|
66
|
+
constructor(opts) {
|
|
67
|
+
this.opts = opts;
|
|
68
|
+
this.app = (0, express_1.default)();
|
|
69
|
+
this.httpServer = null;
|
|
70
|
+
this.browser = null;
|
|
71
|
+
this.context = null;
|
|
72
|
+
this.page = null;
|
|
73
|
+
this.consoleBuf = createRing(200);
|
|
74
|
+
this.networkBuf = createRing(200);
|
|
75
|
+
this.refMap = {};
|
|
76
|
+
this.app.use(express_1.default.json({ limit: '2mb' }));
|
|
77
|
+
this.app.use(this.authMiddleware.bind(this));
|
|
78
|
+
this.routes();
|
|
79
|
+
}
|
|
80
|
+
authMiddleware(req, res, next) {
|
|
81
|
+
if (req.path === '/health')
|
|
82
|
+
return next();
|
|
83
|
+
const h = req.headers.authorization || '';
|
|
84
|
+
const want = `Bearer ${this.opts.token}`;
|
|
85
|
+
if (h !== want) {
|
|
86
|
+
res.status(401).json({ error: 'unauthorized' });
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
next();
|
|
90
|
+
}
|
|
91
|
+
routes() {
|
|
92
|
+
this.app.get('/health', (_req, res) => {
|
|
93
|
+
res.json({ ok: true, hasPage: !!this.page });
|
|
94
|
+
});
|
|
95
|
+
this.app.post('/session/start', (req, res) => __awaiter(this, void 0, void 0, function* () {
|
|
96
|
+
var _a, _b, _c;
|
|
97
|
+
try {
|
|
98
|
+
const headless = (_c = (_b = (_a = req.body) === null || _a === void 0 ? void 0 : _a.headless) !== null && _b !== void 0 ? _b : this.opts.headless) !== null && _c !== void 0 ? _c : true;
|
|
99
|
+
const pw = yield Promise.resolve().then(() => __importStar(require('playwright')));
|
|
100
|
+
this.browser = yield pw.chromium.launch({ headless });
|
|
101
|
+
this.context = yield this.browser.newContext();
|
|
102
|
+
this.page = yield this.context.newPage();
|
|
103
|
+
this.page.on('console', (msg) => {
|
|
104
|
+
this.consoleBuf.push({
|
|
105
|
+
type: msg.type(),
|
|
106
|
+
text: msg.text(),
|
|
107
|
+
ts: new Date().toISOString(),
|
|
108
|
+
});
|
|
109
|
+
});
|
|
110
|
+
this.context.on('response', (response) => {
|
|
111
|
+
try {
|
|
112
|
+
this.networkBuf.push({
|
|
113
|
+
url: response.url(),
|
|
114
|
+
method: response.request().method(),
|
|
115
|
+
status: response.status(),
|
|
116
|
+
ts: new Date().toISOString(),
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
catch (_a) {
|
|
120
|
+
/* ignore */
|
|
121
|
+
}
|
|
122
|
+
});
|
|
123
|
+
res.json({ ok: true });
|
|
124
|
+
}
|
|
125
|
+
catch (e) {
|
|
126
|
+
res.status(500).json({ error: e.message });
|
|
127
|
+
}
|
|
128
|
+
}));
|
|
129
|
+
this.app.post('/navigate', (req, res) => __awaiter(this, void 0, void 0, function* () {
|
|
130
|
+
var _a;
|
|
131
|
+
try {
|
|
132
|
+
const url = (_a = req.body) === null || _a === void 0 ? void 0 : _a.url;
|
|
133
|
+
if (!url || !this.page) {
|
|
134
|
+
res.status(400).json({ error: 'url required and session must be started' });
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
137
|
+
yield this.page.goto(url, { waitUntil: 'domcontentloaded', timeout: 60000 });
|
|
138
|
+
res.json({ ok: true, url: this.page.url() });
|
|
139
|
+
}
|
|
140
|
+
catch (e) {
|
|
141
|
+
res.status(500).json({ error: e.message });
|
|
142
|
+
}
|
|
143
|
+
}));
|
|
144
|
+
this.app.post('/refs/refresh', (_req, res) => __awaiter(this, void 0, void 0, function* () {
|
|
145
|
+
try {
|
|
146
|
+
if (!this.page) {
|
|
147
|
+
res.status(400).json({ error: 'no session' });
|
|
148
|
+
return;
|
|
149
|
+
}
|
|
150
|
+
const mapping = yield this.page.evaluate(() => {
|
|
151
|
+
const sel = 'a[href],button,input,textarea,select,[role="button"],[onclick]';
|
|
152
|
+
const nodes = Array.from(document.querySelectorAll(sel));
|
|
153
|
+
const out = {};
|
|
154
|
+
nodes.forEach((el, i) => {
|
|
155
|
+
const id = `e${i + 1}`;
|
|
156
|
+
el.setAttribute('data-cm-ref', id);
|
|
157
|
+
const tag = el.tagName.toLowerCase();
|
|
158
|
+
const txt = (el.textContent || '').trim().slice(0, 80);
|
|
159
|
+
out[id] = `${tag}${txt ? `: ${txt}` : ''}`;
|
|
160
|
+
});
|
|
161
|
+
return out;
|
|
162
|
+
});
|
|
163
|
+
this.refMap = mapping;
|
|
164
|
+
res.json({ ok: true, refs: mapping });
|
|
165
|
+
}
|
|
166
|
+
catch (e) {
|
|
167
|
+
res.status(500).json({ error: e.message });
|
|
168
|
+
}
|
|
169
|
+
}));
|
|
170
|
+
this.app.post('/click', (req, res) => __awaiter(this, void 0, void 0, function* () {
|
|
171
|
+
var _a, _b;
|
|
172
|
+
try {
|
|
173
|
+
const ref = (_b = (_a = req.body) === null || _a === void 0 ? void 0 : _a.ref) === null || _b === void 0 ? void 0 : _b.replace(/^@/, '');
|
|
174
|
+
if (!ref || !this.page) {
|
|
175
|
+
res.status(400).json({ error: 'ref required' });
|
|
176
|
+
return;
|
|
177
|
+
}
|
|
178
|
+
yield this.page.click(`[data-cm-ref="${ref}"]`, { timeout: 15000 });
|
|
179
|
+
res.json({ ok: true });
|
|
180
|
+
}
|
|
181
|
+
catch (e) {
|
|
182
|
+
res.status(500).json({ error: e.message });
|
|
183
|
+
}
|
|
184
|
+
}));
|
|
185
|
+
this.app.post('/fill', (req, res) => __awaiter(this, void 0, void 0, function* () {
|
|
186
|
+
var _a, _b, _c;
|
|
187
|
+
try {
|
|
188
|
+
const ref = (_b = (_a = req.body) === null || _a === void 0 ? void 0 : _a.ref) === null || _b === void 0 ? void 0 : _b.replace(/^@/, '');
|
|
189
|
+
const value = (_c = req.body) === null || _c === void 0 ? void 0 : _c.value;
|
|
190
|
+
if (!ref || value === undefined || !this.page) {
|
|
191
|
+
res.status(400).json({ error: 'ref and value required' });
|
|
192
|
+
return;
|
|
193
|
+
}
|
|
194
|
+
yield this.page.fill(`[data-cm-ref="${ref}"]`, value, { timeout: 15000 });
|
|
195
|
+
res.json({ ok: true });
|
|
196
|
+
}
|
|
197
|
+
catch (e) {
|
|
198
|
+
res.status(500).json({ error: e.message });
|
|
199
|
+
}
|
|
200
|
+
}));
|
|
201
|
+
this.app.get('/screenshot', (_req, res) => __awaiter(this, void 0, void 0, function* () {
|
|
202
|
+
try {
|
|
203
|
+
if (!this.page) {
|
|
204
|
+
res.status(400).json({ error: 'no session' });
|
|
205
|
+
return;
|
|
206
|
+
}
|
|
207
|
+
const buf = yield this.page.screenshot({ type: 'png' });
|
|
208
|
+
res.setHeader('Content-Type', 'image/png');
|
|
209
|
+
res.send(buf);
|
|
210
|
+
}
|
|
211
|
+
catch (e) {
|
|
212
|
+
res.status(500).json({ error: e.message });
|
|
213
|
+
}
|
|
214
|
+
}));
|
|
215
|
+
this.app.get('/console', (_req, res) => {
|
|
216
|
+
res.json({ entries: this.consoleBuf.snapshot() });
|
|
217
|
+
});
|
|
218
|
+
this.app.get('/network', (_req, res) => {
|
|
219
|
+
res.json({ entries: this.networkBuf.snapshot() });
|
|
220
|
+
});
|
|
221
|
+
}
|
|
222
|
+
listen() {
|
|
223
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
224
|
+
var _a;
|
|
225
|
+
const host = this.opts.host || '127.0.0.1';
|
|
226
|
+
const port = (_a = this.opts.port) !== null && _a !== void 0 ? _a : 17395;
|
|
227
|
+
return new Promise((resolve, reject) => {
|
|
228
|
+
this.httpServer = this.app.listen(port, host, () => resolve());
|
|
229
|
+
this.httpServer.on('error', reject);
|
|
230
|
+
});
|
|
231
|
+
});
|
|
232
|
+
}
|
|
233
|
+
close() {
|
|
234
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
235
|
+
if (this.page)
|
|
236
|
+
yield this.page.close().catch(() => { });
|
|
237
|
+
if (this.context)
|
|
238
|
+
yield this.context.close().catch(() => { });
|
|
239
|
+
if (this.browser)
|
|
240
|
+
yield this.browser.close().catch(() => { });
|
|
241
|
+
this.page = null;
|
|
242
|
+
this.context = null;
|
|
243
|
+
this.browser = null;
|
|
244
|
+
if (this.httpServer) {
|
|
245
|
+
yield new Promise((r) => this.httpServer.close(() => r()));
|
|
246
|
+
this.httpServer = null;
|
|
247
|
+
}
|
|
248
|
+
});
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
exports.BrowseDaemon = BrowseDaemon;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.registerAllCommands = registerAllCommands;
|
|
4
|
+
const agent_1 = require("./commands/agent");
|
|
5
|
+
const dashboard_1 = require("./commands/dashboard");
|
|
6
|
+
const project_1 = require("./commands/project");
|
|
7
|
+
const skill_chain_1 = require("./commands/skill-chain");
|
|
8
|
+
const system_1 = require("./commands/system");
|
|
9
|
+
const task_1 = require("./commands/task");
|
|
10
|
+
const engineering_1 = require("./commands/engineering");
|
|
11
|
+
const design_studio_1 = require("./commands/design-studio");
|
|
12
|
+
const distro_1 = require("./commands/distro");
|
|
13
|
+
/**
|
|
14
|
+
* Registers all CLI commands with the provided program instance.
|
|
15
|
+
*/
|
|
16
|
+
function registerAllCommands(program) {
|
|
17
|
+
(0, agent_1.registerAgentCommands)(program);
|
|
18
|
+
(0, dashboard_1.registerDashboardCommands)(program);
|
|
19
|
+
(0, project_1.registerProjectCommands)(program);
|
|
20
|
+
(0, skill_chain_1.registerSkillChainCommands)(program);
|
|
21
|
+
(0, system_1.registerSystemCommands)(program);
|
|
22
|
+
(0, task_1.registerTaskCommands)(program);
|
|
23
|
+
(0, engineering_1.registerEngineeringCommands)(program);
|
|
24
|
+
(0, design_studio_1.registerDesignStudioCommands)(program);
|
|
25
|
+
(0, distro_1.registerDistroCommands)(program);
|
|
26
|
+
}
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.registerAgentCommands = registerAgentCommands;
|
|
13
|
+
const continuity_1 = require("../../continuity");
|
|
14
|
+
const box_1 = require("../../ui/box");
|
|
15
|
+
const theme_1 = require("../../ui/theme");
|
|
16
|
+
const cli_utils_1 = require("../../utils/cli-utils");
|
|
17
|
+
function registerAgentCommands(program) {
|
|
18
|
+
program
|
|
19
|
+
.command('agent [cmd] [args...]')
|
|
20
|
+
.alias('a')
|
|
21
|
+
.description('Agent management (status|memory|brain|learn)')
|
|
22
|
+
.action((cmd, args) => {
|
|
23
|
+
switch (cmd) {
|
|
24
|
+
case 'status':
|
|
25
|
+
case 'st':
|
|
26
|
+
agentStatus();
|
|
27
|
+
break;
|
|
28
|
+
case 'memory':
|
|
29
|
+
case 'mem':
|
|
30
|
+
agentMemory();
|
|
31
|
+
break;
|
|
32
|
+
case 'brain':
|
|
33
|
+
case 'br':
|
|
34
|
+
agentBrain();
|
|
35
|
+
break;
|
|
36
|
+
case 'learn':
|
|
37
|
+
agentLearn(args.join(' '));
|
|
38
|
+
break;
|
|
39
|
+
default: agentStatus();
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
program
|
|
43
|
+
.command('brain')
|
|
44
|
+
.alias('br')
|
|
45
|
+
.description('Show AI brain/working memory')
|
|
46
|
+
.action(() => agentBrain());
|
|
47
|
+
}
|
|
48
|
+
function agentStatus() {
|
|
49
|
+
const summary = (0, continuity_1.getContinuityStatus)(process.cwd());
|
|
50
|
+
if (!summary.initialized) {
|
|
51
|
+
console.log((0, box_1.renderResult)('warning', 'No active CodyMaster brain initialized in this directory.', [
|
|
52
|
+
(0, theme_1.dim)('Run `cm init` to start.')
|
|
53
|
+
]));
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
console.log((0, box_1.renderCommandHeader)('Agent Status: Hamster v4.6', '🐹'));
|
|
57
|
+
console.log((0, theme_1.brand)(' 🧠 Memory Index:'));
|
|
58
|
+
console.log((0, theme_1.dim)(` Iterations: ${summary.iteration}`));
|
|
59
|
+
console.log((0, theme_1.dim)(` Current Goal: ${summary.activeGoal}`));
|
|
60
|
+
console.log((0, theme_1.dim)(` Current Phase: ${summary.phase}`));
|
|
61
|
+
console.log((0, theme_1.dim)(` Tasks Completed: ${summary.completedCount}`));
|
|
62
|
+
console.log((0, theme_1.dim)(` Active Blockers: ${summary.blockerCount}`));
|
|
63
|
+
console.log(`\n ${(0, theme_1.brand)('📊 Activity Summary:')}`);
|
|
64
|
+
console.log((0, theme_1.dim)(` Learnings: ${summary.learningCount}`));
|
|
65
|
+
console.log((0, theme_1.dim)(` Decisions: ${summary.decisionCount}`));
|
|
66
|
+
console.log();
|
|
67
|
+
}
|
|
68
|
+
function agentMemory() {
|
|
69
|
+
const learnings = (0, continuity_1.getLearnings)(process.cwd()).slice(0, 5);
|
|
70
|
+
if (learnings.length === 0) {
|
|
71
|
+
console.log((0, box_1.renderResult)('info', 'No memories stored yet.'));
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
console.log((0, box_1.renderCommandHeader)('Agent Memory (Latest)', '🧠'));
|
|
75
|
+
learnings.forEach((l) => {
|
|
76
|
+
console.log(` ${(0, theme_1.success)('●')} ${(0, theme_1.brand)(l.whatFailed)}`);
|
|
77
|
+
console.log((0, theme_1.dim)(` ${l.howToPrevent} (${(0, cli_utils_1.formatTimeAgoCli)(l.timestamp)})`));
|
|
78
|
+
});
|
|
79
|
+
console.log();
|
|
80
|
+
}
|
|
81
|
+
function agentBrain() {
|
|
82
|
+
const state = (0, continuity_1.readContinuityState)(process.cwd());
|
|
83
|
+
if (!state) {
|
|
84
|
+
console.log((0, box_1.renderResult)('warning', 'Brain not initialized.'));
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
console.log((0, box_1.renderCommandHeader)(`Agent Brain: ${state.project}`, '🧠'));
|
|
88
|
+
console.log((0, theme_1.brand)(` Goal: ${state.activeGoal}`));
|
|
89
|
+
console.log((0, theme_1.dim)(` Phase: ${state.currentPhase} (Iter ${state.currentIteration})`));
|
|
90
|
+
console.log(`\n ${(0, theme_1.brand)('Next Actions:')}`);
|
|
91
|
+
state.nextActions.slice(0, 5).forEach((act, idx) => {
|
|
92
|
+
console.log(` ${idx + 1}. ${act}`);
|
|
93
|
+
});
|
|
94
|
+
if (state.activeBlockers.length > 0) {
|
|
95
|
+
console.log(`\n ${(0, theme_1.warning)('Blockers:')}`);
|
|
96
|
+
state.activeBlockers.forEach((b) => console.log(` ⚠️ ${b}`));
|
|
97
|
+
}
|
|
98
|
+
console.log();
|
|
99
|
+
}
|
|
100
|
+
function agentLearn(content) {
|
|
101
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
102
|
+
var _a;
|
|
103
|
+
if (!content) {
|
|
104
|
+
console.log((0, box_1.renderResult)('error', 'Please provide a learning to record.'));
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
const state = (0, continuity_1.readContinuityState)(process.cwd());
|
|
108
|
+
const learning = {
|
|
109
|
+
whatFailed: content,
|
|
110
|
+
whyFailed: 'Manual entry',
|
|
111
|
+
howToPrevent: 'Recorded via CLI',
|
|
112
|
+
timestamp: new Date().toISOString(),
|
|
113
|
+
agent: 'CLI User',
|
|
114
|
+
taskId: ((_a = state === null || state === void 0 ? void 0 : state.currentTask) === null || _a === void 0 ? void 0 : _a.id) || 'manual',
|
|
115
|
+
module: 'system'
|
|
116
|
+
};
|
|
117
|
+
(0, continuity_1.addLearning)(process.cwd(), learning);
|
|
118
|
+
console.log((0, box_1.renderResult)('success', 'Learning recorded in brain.'));
|
|
119
|
+
});
|
|
120
|
+
}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.registerDashboardCommands = registerDashboardCommands;
|
|
7
|
+
const fs_1 = __importDefault(require("fs"));
|
|
8
|
+
const dashboard_1 = require("../../dashboard");
|
|
9
|
+
const data_1 = require("../../data");
|
|
10
|
+
const theme_1 = require("../../ui/theme");
|
|
11
|
+
const box_1 = require("../../ui/box");
|
|
12
|
+
const cli_utils_1 = require("../../utils/cli-utils");
|
|
13
|
+
function registerDashboardCommands(program) {
|
|
14
|
+
program
|
|
15
|
+
.command('dashboard [cmd]')
|
|
16
|
+
.alias('dash')
|
|
17
|
+
.description('Dashboard server (start|stop|status|open)')
|
|
18
|
+
.option('-p, --port <port>', 'Port number', String(data_1.DEFAULT_PORT))
|
|
19
|
+
.action((cmd, opts) => {
|
|
20
|
+
const port = parseInt(opts.port) || data_1.DEFAULT_PORT;
|
|
21
|
+
switch (cmd) {
|
|
22
|
+
case 'start':
|
|
23
|
+
case undefined:
|
|
24
|
+
if (isDashboardRunning()) {
|
|
25
|
+
console.log((0, box_1.renderResult)('warning', 'Dashboard already running.', [`${(0, theme_1.dim)('URL:')} ${(0, theme_1.brand)(`http://localhost:${port}`)}`]));
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
(0, dashboard_1.launchDashboard)(port);
|
|
29
|
+
break;
|
|
30
|
+
case 'stop':
|
|
31
|
+
stopDashboard();
|
|
32
|
+
break;
|
|
33
|
+
case 'status':
|
|
34
|
+
dashboardStatus(port);
|
|
35
|
+
break;
|
|
36
|
+
case 'open':
|
|
37
|
+
console.log((0, box_1.renderResult)('info', `Opening http://localhost:${port} ...`));
|
|
38
|
+
(0, cli_utils_1.openUrl)(`http://localhost:${port}`);
|
|
39
|
+
break;
|
|
40
|
+
case 'url':
|
|
41
|
+
console.log(`http://localhost:${port}`);
|
|
42
|
+
break;
|
|
43
|
+
default: console.log((0, box_1.renderResult)('error', `Unknown: ${cmd}`, [(0, theme_1.dim)('Available: start, stop, status, open, url')]));
|
|
44
|
+
}
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
function isDashboardRunning() {
|
|
48
|
+
try {
|
|
49
|
+
if (!fs_1.default.existsSync(data_1.PID_FILE))
|
|
50
|
+
return false;
|
|
51
|
+
const pid = parseInt(fs_1.default.readFileSync(data_1.PID_FILE, 'utf-8').trim());
|
|
52
|
+
process.kill(pid, 0);
|
|
53
|
+
return true;
|
|
54
|
+
}
|
|
55
|
+
catch (_a) {
|
|
56
|
+
try {
|
|
57
|
+
fs_1.default.unlinkSync(data_1.PID_FILE);
|
|
58
|
+
}
|
|
59
|
+
catch (_b) { }
|
|
60
|
+
return false;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
function stopDashboard() {
|
|
64
|
+
try {
|
|
65
|
+
if (!fs_1.default.existsSync(data_1.PID_FILE)) {
|
|
66
|
+
console.log((0, box_1.renderResult)('warning', 'No dashboard running.'));
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
const pid = parseInt(fs_1.default.readFileSync(data_1.PID_FILE, 'utf-8').trim());
|
|
70
|
+
process.kill(pid, 'SIGTERM');
|
|
71
|
+
try {
|
|
72
|
+
fs_1.default.unlinkSync(data_1.PID_FILE);
|
|
73
|
+
}
|
|
74
|
+
catch (_a) { }
|
|
75
|
+
console.log((0, box_1.renderResult)('success', `Dashboard stopped (PID ${pid}).`));
|
|
76
|
+
}
|
|
77
|
+
catch (err) {
|
|
78
|
+
console.log((0, box_1.renderResult)('error', `Failed to stop: ${err.message}`));
|
|
79
|
+
try {
|
|
80
|
+
fs_1.default.unlinkSync(data_1.PID_FILE);
|
|
81
|
+
}
|
|
82
|
+
catch (_b) { }
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
function dashboardStatus(port) {
|
|
86
|
+
if (isDashboardRunning()) {
|
|
87
|
+
const pid = fs_1.default.readFileSync(data_1.PID_FILE, 'utf-8').trim();
|
|
88
|
+
console.log((0, box_1.renderResult)('success', 'Dashboard RUNNING', [`${(0, theme_1.dim)('PID:')} ${(0, theme_1.brand)(pid)}`, `${(0, theme_1.dim)('URL:')} ${(0, theme_1.brand)(`http://localhost:${port}`)}`]));
|
|
89
|
+
}
|
|
90
|
+
else {
|
|
91
|
+
console.log((0, box_1.renderResult)('warning', 'Dashboard NOT running', [(0, theme_1.dim)('Start with: cm dashboard start')]));
|
|
92
|
+
}
|
|
93
|
+
}
|