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
|
@@ -0,0 +1,76 @@
|
|
|
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.padRight = padRight;
|
|
7
|
+
exports.openUrl = openUrl;
|
|
8
|
+
exports.formatTimeAgoCli = formatTimeAgoCli;
|
|
9
|
+
exports.progressBar = progressBar;
|
|
10
|
+
exports.isDashboardRunning = isDashboardRunning;
|
|
11
|
+
const fs_1 = __importDefault(require("fs"));
|
|
12
|
+
const os_1 = __importDefault(require("os"));
|
|
13
|
+
const child_process_1 = require("child_process");
|
|
14
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
15
|
+
/**
|
|
16
|
+
* Pads a string on the right with spaces.
|
|
17
|
+
*/
|
|
18
|
+
function padRight(str, len) {
|
|
19
|
+
if (str.length >= len)
|
|
20
|
+
return str;
|
|
21
|
+
return str + ' '.repeat(len - str.length);
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Opens a URL in the default browser.
|
|
25
|
+
*/
|
|
26
|
+
function openUrl(url) {
|
|
27
|
+
const plat = os_1.default.platform();
|
|
28
|
+
const command = plat === 'darwin' ? 'open' : plat === 'win32' ? 'start' : 'xdg-open';
|
|
29
|
+
(0, child_process_1.exec)(`${command} "${url}"`);
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Formats a date string relative to now (e.g. "2m ago", "1h ago").
|
|
33
|
+
*/
|
|
34
|
+
function formatTimeAgoCli(dateStr) {
|
|
35
|
+
const date = new Date(dateStr);
|
|
36
|
+
const now = new Date();
|
|
37
|
+
const seconds = Math.floor((now.getTime() - date.getTime()) / 1000);
|
|
38
|
+
if (seconds < 60)
|
|
39
|
+
return `${seconds}s ago`;
|
|
40
|
+
const minutes = Math.floor(seconds / 60);
|
|
41
|
+
if (minutes < 60)
|
|
42
|
+
return `${minutes}m ago`;
|
|
43
|
+
const hours = Math.floor(minutes / 60);
|
|
44
|
+
if (hours < 24)
|
|
45
|
+
return `${hours}h ago`;
|
|
46
|
+
const days = Math.floor(hours / 24);
|
|
47
|
+
return `${days}d ago`;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Generates a green/gray progress bar string.
|
|
51
|
+
*/
|
|
52
|
+
function progressBar(pct) {
|
|
53
|
+
const total = 12;
|
|
54
|
+
const filled = Math.max(0, Math.min(total, Math.round((pct / 100) * total)));
|
|
55
|
+
return chalk_1.default.green('█'.repeat(filled)) + chalk_1.default.gray('░'.repeat(total - filled));
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Returns true if the dashboard is running (via PID file).
|
|
59
|
+
*/
|
|
60
|
+
function isDashboardRunning(pidFile) {
|
|
61
|
+
try {
|
|
62
|
+
if (!fs_1.default.existsSync(pidFile))
|
|
63
|
+
return false;
|
|
64
|
+
const pidInput = fs_1.default.readFileSync(pidFile, 'utf-8').trim();
|
|
65
|
+
if (!pidInput)
|
|
66
|
+
return false;
|
|
67
|
+
const pid = parseInt(pidInput);
|
|
68
|
+
if (isNaN(pid))
|
|
69
|
+
return false;
|
|
70
|
+
process.kill(pid, 0);
|
|
71
|
+
return true;
|
|
72
|
+
}
|
|
73
|
+
catch (_a) {
|
|
74
|
+
return false;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
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.getAvailableSkills = getAvailableSkills;
|
|
7
|
+
exports.getSkillCount = getSkillCount;
|
|
8
|
+
const fs_1 = __importDefault(require("fs"));
|
|
9
|
+
const path_1 = __importDefault(require("path"));
|
|
10
|
+
/**
|
|
11
|
+
* Discovers and returns a list of available 'cm-' skills.
|
|
12
|
+
*/
|
|
13
|
+
function getAvailableSkills() {
|
|
14
|
+
try {
|
|
15
|
+
const rootDir = path_1.default.resolve(__dirname, '..', '..');
|
|
16
|
+
const skillsDir = path_1.default.join(rootDir, 'skills');
|
|
17
|
+
if (!fs_1.default.existsSync(skillsDir)) {
|
|
18
|
+
return [];
|
|
19
|
+
}
|
|
20
|
+
return fs_1.default.readdirSync(skillsDir)
|
|
21
|
+
.filter(f => f.startsWith('cm-') && fs_1.default.statSync(path_1.default.join(skillsDir, f)).isDirectory());
|
|
22
|
+
}
|
|
23
|
+
catch (_a) {
|
|
24
|
+
return [];
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Returns the count of available 'cm-' skills.
|
|
29
|
+
*/
|
|
30
|
+
function getSkillCount() {
|
|
31
|
+
return getAvailableSkills().length;
|
|
32
|
+
}
|
package/install.sh
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env bash
|
|
2
2
|
# ════════════════════════════════════════════════════════════════
|
|
3
|
-
# CodyMaster Skills Kit
|
|
3
|
+
# CodyMaster Skills Kit — Universal Installer (see VERSION below)
|
|
4
4
|
# Inspired by: npx skills add (vercel-labs/skills)
|
|
5
5
|
#
|
|
6
6
|
# Usage:
|
|
@@ -8,24 +8,41 @@
|
|
|
8
8
|
# bash install.sh --claude Claude Code (non-interactive)
|
|
9
9
|
# bash install.sh --claude --global Claude Code, user scope
|
|
10
10
|
# bash install.sh --claude --project Claude Code, project scope
|
|
11
|
-
# bash install.sh --gemini Gemini CLI
|
|
11
|
+
# bash install.sh --gemini Gemini CLI / Antigravity (all skills)
|
|
12
|
+
# bash install.sh --gemini --profile core Antigravity: core profile only (token budget)
|
|
13
|
+
# bash install.sh --windsurf --profile core Same for project .windsurf/rules
|
|
12
14
|
# bash install.sh --aider Aider
|
|
13
15
|
# bash install.sh --continue Continue.dev
|
|
14
16
|
# bash install.sh --amazon-q Amazon Q CLI (q)
|
|
15
17
|
# bash install.sh --amp Amp
|
|
16
|
-
# bash install.sh --all All detected platforms
|
|
18
|
+
# bash install.sh --all All detected platforms (no interactive menu)
|
|
19
|
+
# bash install.sh --yes Skip onboarding menu (with --gemini, etc.)
|
|
20
|
+
# bash install.sh --cursor --cursor-project Force ./.cursor/rules (run from repo root)
|
|
17
21
|
# ════════════════════════════════════════════════════════════════
|
|
18
22
|
|
|
19
23
|
set -e
|
|
20
24
|
|
|
25
|
+
# Directory containing this script (for skills/profiles when ~/.cody-master is stale)
|
|
26
|
+
CM_SCRIPT_DIR=""
|
|
27
|
+
_cm_src="${BASH_SOURCE[0]:-$0}"
|
|
28
|
+
if [[ "$_cm_src" != /dev/fd/* ]] && [[ "$_cm_src" != /proc/self/fd/* ]]; then
|
|
29
|
+
CM_SCRIPT_DIR="$(cd "$(dirname "$_cm_src")" && pwd)"
|
|
30
|
+
fi
|
|
31
|
+
|
|
21
32
|
# ── Colors ──────────────────────────────────────────────────────
|
|
22
33
|
G='\033[0;32m'; B='\033[0;34m'; P='\033[0;35m'; O='\033[0;33m'
|
|
23
34
|
C='\033[0;36m'; R='\033[0;31m'; W='\033[1;37m'; NC='\033[0m'; BOLD='\033[1m'; DIM='\033[2m'
|
|
24
35
|
|
|
25
36
|
REPO_URL="https://github.com/tody-agent/codymaster"
|
|
26
37
|
RAW_URL="https://raw.githubusercontent.com/tody-agent/codymaster/main"
|
|
27
|
-
VERSION="4.
|
|
38
|
+
VERSION="4.7.0"
|
|
28
39
|
SCOPE="user" # default scope for Claude Code
|
|
40
|
+
SKILL_PROFILE="full" # core|growth|design|knowledge|full — see skills/profiles/
|
|
41
|
+
INSTALL_CMD="" # set by parse_install_args
|
|
42
|
+
# Skip hamster onboarding menu (non-interactive / one-liner installs)
|
|
43
|
+
SKIP_INSTALL_ONBOARDING=0
|
|
44
|
+
# Force Cursor rules into ./.cursor/rules (run from repo root)
|
|
45
|
+
CURSOR_RULES_PROJECT=0
|
|
29
46
|
|
|
30
47
|
if [ -d "skills" ]; then
|
|
31
48
|
TOTAL_SKILLS=$(ls -1d skills/cm-*/SKILL.md 2>/dev/null | wc -l | tr -d ' ')
|
|
@@ -66,6 +83,7 @@ msg() {
|
|
|
66
83
|
vi:done) echo "✅ Hoàn tất!" ;;
|
|
67
84
|
vi:onboard) echo "🎯 Bắt đầu ngay với AI Agent của bạn:" ;;
|
|
68
85
|
vi:docs) echo "📚 Tài liệu:" ;;
|
|
86
|
+
vi:press_enter) echo "Nhấn ENTER để tiếp tục" ;;
|
|
69
87
|
|
|
70
88
|
zh:welcome) echo "欢迎使用 CodyMaster v${VERSION}" ;;
|
|
71
89
|
zh:tagline) echo "Claude Code 的 ${TOTAL_SKILLS} AI 技能" ;;
|
|
@@ -79,6 +97,7 @@ msg() {
|
|
|
79
97
|
zh:done) echo "✅ 完成!" ;;
|
|
80
98
|
zh:onboard) echo "🎯 立即开始与您的 AI Agent 合作:" ;;
|
|
81
99
|
zh:docs) echo "📚 文档:" ;;
|
|
100
|
+
zh:press_enter) echo "按 Enter 继续" ;;
|
|
82
101
|
|
|
83
102
|
ko:welcome) echo "CodyMaster v${VERSION}에 오신 것을 환영합니다" ;;
|
|
84
103
|
ko:tagline) echo "Claude Code용 ${TOTAL_SKILLS} AI 스킬" ;;
|
|
@@ -92,6 +111,7 @@ msg() {
|
|
|
92
111
|
ko:done) echo "✅ 완료!" ;;
|
|
93
112
|
ko:onboard) echo "🎯 AI Agent와 즉시 시작하세요:" ;;
|
|
94
113
|
ko:docs) echo "📚 문서:" ;;
|
|
114
|
+
ko:press_enter) echo "Enter를 눌러 계속" ;;
|
|
95
115
|
|
|
96
116
|
*)
|
|
97
117
|
case "$key" in
|
|
@@ -107,6 +127,7 @@ msg() {
|
|
|
107
127
|
done) echo "✅ Done!" ;;
|
|
108
128
|
onboard) echo "🎯 Get started immediately with your AI Agent:" ;;
|
|
109
129
|
docs) echo "📚 Documentation:" ;;
|
|
130
|
+
press_enter) echo "Press ENTER to continue" ;;
|
|
110
131
|
esac
|
|
111
132
|
;;
|
|
112
133
|
esac
|
|
@@ -114,7 +135,7 @@ msg() {
|
|
|
114
135
|
|
|
115
136
|
# ── Header ───────────────────────────────────────────────────────
|
|
116
137
|
print_header() {
|
|
117
|
-
clear
|
|
138
|
+
clear 2>/dev/null || true
|
|
118
139
|
hamster_sentiment "start"
|
|
119
140
|
echo -e " ${O}( . \ --- / . )${NC}"
|
|
120
141
|
echo -e " ${O}/${NC} ${O}${BOLD}^ ^${NC} ${O}\\\\${NC}"
|
|
@@ -491,12 +512,17 @@ install_claude() {
|
|
|
491
512
|
# Cleanup old marketplace if exists
|
|
492
513
|
claude plugin marketplace remove cody-master 2>/dev/null || true
|
|
493
514
|
echo -e " ${W}Adding marketplace...${NC}"
|
|
494
|
-
claude plugin marketplace add tody-agent/codymaster
|
|
515
|
+
if ! claude plugin marketplace add tody-agent/codymaster; then
|
|
516
|
+
echo -e " ${R}⚠️ Marketplace add failed. Run:${NC} ${C}claude plugin marketplace add tody-agent/codymaster${NC}"
|
|
517
|
+
fi
|
|
495
518
|
echo -e " ${W}Installing plugin (scope: ${scope})...${NC}"
|
|
496
|
-
claude plugin install cm@codymaster --scope "$scope"
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
519
|
+
if ! claude plugin install cm@codymaster --scope "$scope"; then
|
|
520
|
+
echo -e " ${R}⚠️ Plugin install failed. Run:${NC} ${C}claude plugin install cm@codymaster --scope ${scope}${NC}"
|
|
521
|
+
else
|
|
522
|
+
echo ""
|
|
523
|
+
echo -e " ${G}✅ Claude plugin installed — scope: ${scope}${NC}"
|
|
524
|
+
fi
|
|
525
|
+
maybe_print_onboarding
|
|
500
526
|
else
|
|
501
527
|
echo -e " ${R}Claude Code CLI not found. Install from: https://claude.ai/code${NC}"
|
|
502
528
|
echo ""
|
|
@@ -516,10 +542,11 @@ install_gemini() {
|
|
|
516
542
|
echo ""
|
|
517
543
|
target="$HOME/.gemini/antigravity/skills"
|
|
518
544
|
install_skills_to "$target"
|
|
545
|
+
ensure_gemini_md_hint
|
|
519
546
|
echo ""
|
|
520
547
|
echo -e " ${G}✅ Skills installed to ${target}${NC}"
|
|
521
|
-
echo -e " ${C}ℹ
|
|
522
|
-
echo -e " ${C}ℹ
|
|
548
|
+
echo -e " ${C}ℹ GEMINI.md should reference: @~/.gemini/antigravity/skills/cm-skill-index/SKILL.md${NC}"
|
|
549
|
+
echo -e " ${C}ℹ Restart Gemini / Antigravity if it was open during install${NC}"
|
|
523
550
|
}
|
|
524
551
|
|
|
525
552
|
# ── Aider installer ──────────────────────────────────────────────
|
|
@@ -567,23 +594,49 @@ install_amp() {
|
|
|
567
594
|
echo -e " ${C}ℹ Reference skills in Amp via your AGENTS.md or system prompt${NC}"
|
|
568
595
|
}
|
|
569
596
|
|
|
570
|
-
# ── CLI installer ────────────────────────────────────────────────
|
|
571
597
|
install_cli() {
|
|
598
|
+
local auto="$1"
|
|
572
599
|
if command -v npm &>/dev/null; then
|
|
573
600
|
echo ""
|
|
574
|
-
echo -e "${G}${BOLD}CLI Dashboard —
|
|
601
|
+
echo -e "${G}${BOLD}CLI Dashboard — Cody Master CLI${NC}"
|
|
575
602
|
echo ""
|
|
576
|
-
echo -e "
|
|
577
|
-
echo -e "
|
|
603
|
+
echo -e " ${C}Official paths:${NC}"
|
|
604
|
+
echo -e " ${W}Per-project:${NC} ${C}npm install codymaster${NC} → ${C}npx cm${NC}"
|
|
605
|
+
echo -e " ${W}Global:${NC} ${C}npm install -g codymaster${NC} → ${C}cm${NC}"
|
|
578
606
|
echo ""
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
echo -e " ${
|
|
582
|
-
|
|
607
|
+
if [[ "$auto" == "--auto" ]]; then
|
|
608
|
+
echo -e " ${W}Auto: trying global install (optional — use per-project + npx if you prefer).${NC}"
|
|
609
|
+
npm install -g codymaster || echo -e " ${O}Global install failed (try: npm install codymaster in your repo, then npx cm).${NC}"
|
|
610
|
+
if [ -f "package.json" ]; then
|
|
611
|
+
if grep -q '"name": "codymaster"' package.json; then
|
|
612
|
+
npm link &>/dev/null || true
|
|
613
|
+
fi
|
|
614
|
+
fi
|
|
615
|
+
else
|
|
616
|
+
read -p " Install codymaster globally now? (y/N): " install_npm
|
|
617
|
+
if [[ "$install_npm" =~ ^[Yy]$ ]]; then
|
|
618
|
+
echo -e " ${W}Running: npm install -g codymaster${NC}"
|
|
619
|
+
npm install -g codymaster || echo -e " ${O}Note: sudo may be needed, or use: npm install codymaster && npx cm${NC}"
|
|
620
|
+
fi
|
|
583
621
|
fi
|
|
584
622
|
fi
|
|
585
623
|
}
|
|
586
624
|
|
|
625
|
+
install_openviking() {
|
|
626
|
+
echo ""
|
|
627
|
+
echo -e "${G}${BOLD}OpenViking — Installing Core Feature${NC}"
|
|
628
|
+
echo ""
|
|
629
|
+
if command -v pip3 &>/dev/null; then
|
|
630
|
+
echo -e " ${W}Running: pip3 install openviking${NC}"
|
|
631
|
+
pip3 install openviking || echo -e " ${O}⚠️ Could not install OpenViking automatically.${NC}"
|
|
632
|
+
elif command -v pip &>/dev/null; then
|
|
633
|
+
echo -e " ${W}Running: pip install openviking${NC}"
|
|
634
|
+
pip install openviking || echo -e " ${O}⚠️ Could not install OpenViking automatically.${NC}"
|
|
635
|
+
else
|
|
636
|
+
echo -e " ${R}Python pip not found. Please install pip to get OpenViking.${NC}"
|
|
637
|
+
fi
|
|
638
|
+
}
|
|
639
|
+
|
|
587
640
|
# ── Ensure clone exists ──────────────────────────────────────────
|
|
588
641
|
CLONE_DIR=""
|
|
589
642
|
ensure_clone() {
|
|
@@ -602,6 +655,7 @@ ensure_clone() {
|
|
|
602
655
|
# Clone the repo
|
|
603
656
|
echo -e " ${W}Cloning CodyMaster to ~/.cody-master...${NC}"
|
|
604
657
|
git clone --depth 1 "${REPO_URL}.git" "$HOME/.cody-master" 2>/dev/null || {
|
|
658
|
+
|
|
605
659
|
echo -e " ${R}Error: Failed to clone ${REPO_URL}${NC}"
|
|
606
660
|
echo -e " ${R}Check your internet connection and try again.${NC}"
|
|
607
661
|
exit 1
|
|
@@ -621,12 +675,50 @@ install_skills_to() {
|
|
|
621
675
|
ensure_clone
|
|
622
676
|
echo ""
|
|
623
677
|
echo -e "${G}${BOLD}Installing skills to: ${target}${NC}"
|
|
678
|
+
if [[ -n "${SKILL_PROFILE:-}" && "$SKILL_PROFILE" != "full" ]]; then
|
|
679
|
+
echo -e " ${C}Profile: ${SKILL_PROFILE}${NC}"
|
|
680
|
+
fi
|
|
624
681
|
echo ""
|
|
625
682
|
mkdir -p "$target"
|
|
626
683
|
local count=0
|
|
627
684
|
local installed=()
|
|
685
|
+
local -a allow=()
|
|
686
|
+
local use_profile=0
|
|
687
|
+
if [[ -n "${SKILL_PROFILE:-}" && "$SKILL_PROFILE" != "full" ]]; then
|
|
688
|
+
local pf="${CLONE_DIR}/skills/profiles/${SKILL_PROFILE}.txt"
|
|
689
|
+
if [[ ! -f "$pf" && -n "${CM_SCRIPT_DIR}" && -f "${CM_SCRIPT_DIR}/skills/profiles/${SKILL_PROFILE}.txt" ]]; then
|
|
690
|
+
pf="${CM_SCRIPT_DIR}/skills/profiles/${SKILL_PROFILE}.txt"
|
|
691
|
+
fi
|
|
692
|
+
if [[ ! -f "$pf" ]]; then
|
|
693
|
+
echo -e " ${R}Unknown profile '${SKILL_PROFILE}'. Valid: core, growth, design, knowledge, full${NC}"
|
|
694
|
+
echo -e " ${R}Expected: \${CLONE_DIR}/skills/profiles/${SKILL_PROFILE}.txt (git pull ~/.cody-master or run install.sh from repo)${NC}"
|
|
695
|
+
exit 1
|
|
696
|
+
fi
|
|
697
|
+
use_profile=1
|
|
698
|
+
while IFS= read -r line || [[ -n "$line" ]]; do
|
|
699
|
+
[[ "$line" =~ ^[[:space:]]*# ]] && continue
|
|
700
|
+
line="${line%%#*}"
|
|
701
|
+
line="${line#"${line%%[![:space:]]*}"}"
|
|
702
|
+
line="${line%"${line##*[![:space:]]}"}"
|
|
703
|
+
[[ -z "$line" ]] && continue
|
|
704
|
+
allow+=("$line")
|
|
705
|
+
done < "$pf"
|
|
706
|
+
fi
|
|
628
707
|
for skill_dir in "${CLONE_DIR}"/skills/cm-*/; do
|
|
629
708
|
skill_name=$(basename "$skill_dir")
|
|
709
|
+
if [[ "$use_profile" -eq 1 ]]; then
|
|
710
|
+
local found=0
|
|
711
|
+
local a
|
|
712
|
+
for a in "${allow[@]}"; do
|
|
713
|
+
if [[ "$a" == "$skill_name" ]]; then
|
|
714
|
+
found=1
|
|
715
|
+
break
|
|
716
|
+
fi
|
|
717
|
+
done
|
|
718
|
+
if [[ "$found" -eq 0 ]]; then
|
|
719
|
+
continue
|
|
720
|
+
fi
|
|
721
|
+
fi
|
|
630
722
|
if [ -f "${skill_dir}SKILL.md" ]; then
|
|
631
723
|
if [[ "$format" == "mdc" ]]; then
|
|
632
724
|
# Create Cursor glob native format
|
|
@@ -683,6 +775,109 @@ select_scope() {
|
|
|
683
775
|
esac
|
|
684
776
|
}
|
|
685
777
|
|
|
778
|
+
# ── Cursor rules path: avoid writing to a random cwd (e.g. /tmp) ──
|
|
779
|
+
resolve_cursor_rules_dir() {
|
|
780
|
+
local mode="${1:-cursor}"
|
|
781
|
+
if [[ "$mode" == "all" ]]; then
|
|
782
|
+
printf '%s' "${HOME}/.cursor/rules"
|
|
783
|
+
return
|
|
784
|
+
fi
|
|
785
|
+
if [[ "$CURSOR_RULES_PROJECT" == "1" ]]; then
|
|
786
|
+
printf '%s' ".cursor/rules"
|
|
787
|
+
return
|
|
788
|
+
fi
|
|
789
|
+
if [[ -d .git ]] || [[ -f package.json ]]; then
|
|
790
|
+
printf '%s' ".cursor/rules"
|
|
791
|
+
else
|
|
792
|
+
printf '%s' "${HOME}/.cursor/rules"
|
|
793
|
+
fi
|
|
794
|
+
}
|
|
795
|
+
|
|
796
|
+
# ── Gemini: ensure GEMINI.md points at skill index ───────────────
|
|
797
|
+
ensure_gemini_md_hint() {
|
|
798
|
+
mkdir -p "${HOME}/.gemini" 2>/dev/null || true
|
|
799
|
+
local f="${HOME}/.gemini/GEMINI.md"
|
|
800
|
+
local hint="@~/.gemini/antigravity/skills/cm-skill-index/SKILL.md"
|
|
801
|
+
if [[ ! -f "$f" ]]; then
|
|
802
|
+
{
|
|
803
|
+
echo "# Gemini CLI / Antigravity"
|
|
804
|
+
echo "# CodyMaster: load the progressive skill index first (then pull full skills as needed)"
|
|
805
|
+
echo "$hint"
|
|
806
|
+
} > "$f"
|
|
807
|
+
echo -e " ${G}✅ Created ${f} with skill index line${NC}"
|
|
808
|
+
return
|
|
809
|
+
fi
|
|
810
|
+
if ! grep -q "cm-skill-index" "$f" 2>/dev/null; then
|
|
811
|
+
{
|
|
812
|
+
echo ""
|
|
813
|
+
echo "# CodyMaster — skill index"
|
|
814
|
+
echo "$hint"
|
|
815
|
+
} >> "$f"
|
|
816
|
+
echo -e " ${G}✅ Appended CodyMaster skill index to ${f}${NC}"
|
|
817
|
+
fi
|
|
818
|
+
}
|
|
819
|
+
|
|
820
|
+
maybe_print_onboarding() {
|
|
821
|
+
[[ "$SKIP_INSTALL_ONBOARDING" == "1" ]] && return 0
|
|
822
|
+
print_onboarding
|
|
823
|
+
}
|
|
824
|
+
|
|
825
|
+
print_all_done_summary() {
|
|
826
|
+
echo ""
|
|
827
|
+
echo -e "${W}${BOLD}═══ Next steps — verify each tool you use ═══${NC}"
|
|
828
|
+
echo ""
|
|
829
|
+
echo -e " ${BOLD}Claude Code:${NC} Open Claude Code → ${C}/cm:demo${NC} or ${C}/help${NC}. If the plugin is missing:"
|
|
830
|
+
echo -e " ${C}claude plugin marketplace add tody-agent/codymaster${NC}"
|
|
831
|
+
echo -e " ${C}claude plugin install cm@codymaster --scope user${NC}"
|
|
832
|
+
echo ""
|
|
833
|
+
echo -e " ${BOLD}Gemini / Antigravity:${NC} Skills → ${C}~/.gemini/antigravity/skills/${NC}"
|
|
834
|
+
echo -e " ${C}~/.gemini/GEMINI.md${NC} should include ${C}@~/.gemini/antigravity/skills/cm-skill-index/SKILL.md${NC}"
|
|
835
|
+
echo ""
|
|
836
|
+
echo -e " ${BOLD}Cursor IDE:${NC} Rules → ${C}${HOME}/.cursor/rules${NC} ${DIM}(from one-liner --all)${NC}"
|
|
837
|
+
echo -e " Agent chat: ${C}/add-plugin cody-master${NC}"
|
|
838
|
+
echo -e " Project-only rules: ${C}cd your-repo && bash install.sh --cursor --cursor-project${NC}"
|
|
839
|
+
echo ""
|
|
840
|
+
echo -e " ${BOLD}Terminal CLI:${NC} ${C}npm install -g codymaster${NC} → ${C}cm${NC} | ${C}npm install codymaster${NC} → ${C}npx cm${NC}"
|
|
841
|
+
echo ""
|
|
842
|
+
echo -e " ${BOLD}Skill sources:${NC} ${C}~/.cody-master/skills/${NC}"
|
|
843
|
+
echo ""
|
|
844
|
+
}
|
|
845
|
+
|
|
846
|
+
# ── Parse argv: --profile NAME + first platform flag ────────────
|
|
847
|
+
parse_install_args() {
|
|
848
|
+
INSTALL_CMD=""
|
|
849
|
+
local args=("$@")
|
|
850
|
+
local i=0
|
|
851
|
+
while [[ $i -lt ${#args[@]} ]]; do
|
|
852
|
+
local a="${args[i]}"
|
|
853
|
+
case "$a" in
|
|
854
|
+
--profile)
|
|
855
|
+
SKILL_PROFILE="${args[i+1]:-full}"
|
|
856
|
+
((i+=2))
|
|
857
|
+
continue
|
|
858
|
+
;;
|
|
859
|
+
esac
|
|
860
|
+
if [[ -z "$INSTALL_CMD" ]]; then
|
|
861
|
+
case "$a" in
|
|
862
|
+
--claude) INSTALL_CMD="claude" ;;
|
|
863
|
+
--gemini|--antigravity) INSTALL_CMD="gemini" ;;
|
|
864
|
+
--cursor) INSTALL_CMD="cursor" ;;
|
|
865
|
+
--aider) INSTALL_CMD="aider" ;;
|
|
866
|
+
--continue) INSTALL_CMD="continue" ;;
|
|
867
|
+
--amazon-q) INSTALL_CMD="amazon-q" ;;
|
|
868
|
+
--amp) INSTALL_CMD="amp" ;;
|
|
869
|
+
--kiro) INSTALL_CMD="kiro" ;;
|
|
870
|
+
--windsurf) INSTALL_CMD="windsurf" ;;
|
|
871
|
+
--cline) INSTALL_CMD="cline" ;;
|
|
872
|
+
--opencode) INSTALL_CMD="opencode" ;;
|
|
873
|
+
--copilot) INSTALL_CMD="copilot" ;;
|
|
874
|
+
--all) INSTALL_CMD="all" ;;
|
|
875
|
+
esac
|
|
876
|
+
fi
|
|
877
|
+
((i++)) || true
|
|
878
|
+
done
|
|
879
|
+
}
|
|
880
|
+
|
|
686
881
|
# ════════════════════════════════════════════════════════════════
|
|
687
882
|
# MAIN
|
|
688
883
|
# ════════════════════════════════════════════════════════════════
|
|
@@ -694,92 +889,111 @@ for arg in "$@"; do
|
|
|
694
889
|
case "$arg" in
|
|
695
890
|
--global|--user) SCOPE="user" ;;
|
|
696
891
|
--project|--local) SCOPE="project" ;;
|
|
892
|
+
--yes|-y) SKIP_INSTALL_ONBOARDING=1 ;;
|
|
893
|
+
--cursor-project) CURSOR_RULES_PROJECT=1 ;;
|
|
697
894
|
esac
|
|
698
895
|
done
|
|
699
896
|
|
|
700
|
-
|
|
897
|
+
parse_install_args "$@"
|
|
898
|
+
|
|
899
|
+
# One-liner full install should finish without the interactive onboarding menu
|
|
900
|
+
if [[ "$INSTALL_CMD" == "all" ]]; then
|
|
901
|
+
SKIP_INSTALL_ONBOARDING=1
|
|
902
|
+
fi
|
|
903
|
+
|
|
904
|
+
if [[ "$INSTALL_CMD" == "claude" ]]; then
|
|
701
905
|
install_claude "$SCOPE"
|
|
702
906
|
exit 0
|
|
703
907
|
fi
|
|
704
908
|
|
|
705
|
-
if [[ "$
|
|
909
|
+
if [[ "$INSTALL_CMD" == "gemini" ]]; then
|
|
706
910
|
install_gemini
|
|
707
|
-
|
|
911
|
+
if [[ -n "${SKILL_PROFILE:-}" && "$SKILL_PROFILE" != "full" ]]; then
|
|
912
|
+
echo -e " ${C}ℹ Add more skills: bash install.sh --gemini --profile growth (same target merges new folders)${NC}"
|
|
913
|
+
echo -e " ${C}ℹ Point GEMINI.md at: @~/.gemini/antigravity/skills/cm-skill-index/SKILL.md${NC}"
|
|
914
|
+
fi
|
|
915
|
+
maybe_print_onboarding
|
|
708
916
|
exit 0
|
|
709
917
|
fi
|
|
710
918
|
|
|
711
|
-
if [[ "$
|
|
919
|
+
if [[ "$INSTALL_CMD" == "cursor" ]]; then
|
|
712
920
|
echo ""
|
|
713
921
|
echo -e "${B}${BOLD}Cursor — Installing Cody Master${NC}"
|
|
714
922
|
echo ""
|
|
715
|
-
target="
|
|
923
|
+
target="$(resolve_cursor_rules_dir cursor)"
|
|
716
924
|
install_skills_to "$target" "mdc"
|
|
717
|
-
echo -e " ${C}ℹ Cursor
|
|
718
|
-
|
|
925
|
+
echo -e " ${C}ℹ Cursor rules installed to: ${BOLD}${target}${NC}"
|
|
926
|
+
echo -e " ${C}ℹ Reopen Cursor or open a workspace folder. Also try Agent: ${BOLD}/add-plugin cody-master${NC}"
|
|
927
|
+
maybe_print_onboarding
|
|
719
928
|
exit 0
|
|
720
929
|
fi
|
|
721
930
|
|
|
722
|
-
if [[ "$
|
|
931
|
+
if [[ "$INSTALL_CMD" == "aider" ]]; then
|
|
723
932
|
install_aider
|
|
724
|
-
|
|
933
|
+
maybe_print_onboarding
|
|
725
934
|
exit 0
|
|
726
935
|
fi
|
|
727
936
|
|
|
728
|
-
if [[ "$
|
|
937
|
+
if [[ "$INSTALL_CMD" == "continue" ]]; then
|
|
729
938
|
install_continue
|
|
730
|
-
|
|
939
|
+
maybe_print_onboarding
|
|
731
940
|
exit 0
|
|
732
941
|
fi
|
|
733
942
|
|
|
734
|
-
if [[ "$
|
|
943
|
+
if [[ "$INSTALL_CMD" == "amazon-q" ]]; then
|
|
735
944
|
install_amazon_q
|
|
736
|
-
|
|
945
|
+
maybe_print_onboarding
|
|
737
946
|
exit 0
|
|
738
947
|
fi
|
|
739
948
|
|
|
740
|
-
if [[ "$
|
|
949
|
+
if [[ "$INSTALL_CMD" == "amp" ]]; then
|
|
741
950
|
install_amp
|
|
742
|
-
|
|
951
|
+
maybe_print_onboarding
|
|
743
952
|
exit 0
|
|
744
953
|
fi
|
|
745
954
|
|
|
746
|
-
if [[ "$
|
|
955
|
+
if [[ "$INSTALL_CMD" == "kiro" ]]; then
|
|
747
956
|
echo ""
|
|
748
957
|
echo -e "${O}${BOLD}Kiro — Installing Cody Master${NC}"
|
|
749
958
|
echo ""
|
|
750
959
|
install_skills_to ".kiro/steering" "raw"
|
|
751
|
-
|
|
960
|
+
maybe_print_onboarding
|
|
752
961
|
exit 0
|
|
753
962
|
fi
|
|
754
963
|
|
|
755
|
-
if [[ "$
|
|
964
|
+
if [[ "$INSTALL_CMD" == "windsurf" ]]; then
|
|
756
965
|
echo ""
|
|
757
966
|
echo -e "${O}${BOLD}Windsurf — Installing Cody Master${NC}"
|
|
758
967
|
echo ""
|
|
968
|
+
echo -e " ${C}ℹ This writes to project ${BOLD}.windsurf/rules${NC}${C} (run from repo root).${NC}"
|
|
969
|
+
echo -e " ${C}ℹ Some Windsurf builds also use global skills under Codeium paths — use the same profile flags if you copy there.${NC}"
|
|
759
970
|
install_skills_to ".windsurf/rules" "raw"
|
|
760
|
-
|
|
971
|
+
if [[ -n "${SKILL_PROFILE:-}" && "$SKILL_PROFILE" != "full" ]]; then
|
|
972
|
+
echo -e " ${C}ℹ Add more: bash install.sh --windsurf --profile growth${NC}"
|
|
973
|
+
fi
|
|
974
|
+
maybe_print_onboarding
|
|
761
975
|
exit 0
|
|
762
976
|
fi
|
|
763
977
|
|
|
764
|
-
if [[ "$
|
|
978
|
+
if [[ "$INSTALL_CMD" == "cline" ]]; then
|
|
765
979
|
echo ""
|
|
766
980
|
echo -e "${O}${BOLD}Cline/RooCode — Installing Cody Master${NC}"
|
|
767
981
|
echo ""
|
|
768
982
|
install_skills_to ".cline/skills" "raw"
|
|
769
|
-
|
|
983
|
+
maybe_print_onboarding
|
|
770
984
|
exit 0
|
|
771
985
|
fi
|
|
772
986
|
|
|
773
|
-
if [[ "$
|
|
987
|
+
if [[ "$INSTALL_CMD" == "opencode" ]]; then
|
|
774
988
|
echo ""
|
|
775
989
|
echo -e "${G}${BOLD}OpenCode — Installing Cody Master${NC}"
|
|
776
990
|
echo ""
|
|
777
991
|
install_skills_to ".opencode/skills" "raw"
|
|
778
|
-
|
|
992
|
+
maybe_print_onboarding
|
|
779
993
|
exit 0
|
|
780
994
|
fi
|
|
781
995
|
|
|
782
|
-
if [[ "$
|
|
996
|
+
if [[ "$INSTALL_CMD" == "copilot" ]]; then
|
|
783
997
|
echo ""
|
|
784
998
|
echo -e "${G}${BOLD}GitHub Copilot — Installing Cody Master${NC}"
|
|
785
999
|
echo ""
|
|
@@ -788,7 +1002,7 @@ if [[ "$1" == "--copilot" ]]; then
|
|
|
788
1002
|
exit 0
|
|
789
1003
|
fi
|
|
790
1004
|
|
|
791
|
-
if [[ "$
|
|
1005
|
+
if [[ "$INSTALL_CMD" == "all" ]]; then
|
|
792
1006
|
echo -e "${W}${BOLD}Installing to all detected platforms...${NC}"
|
|
793
1007
|
echo ""
|
|
794
1008
|
command -v claude &>/dev/null && install_claude "$SCOPE"
|
|
@@ -798,10 +1012,16 @@ if [[ "$1" == "--all" ]]; then
|
|
|
798
1012
|
command -v q &>/dev/null && install_amazon_q
|
|
799
1013
|
command -v amp &>/dev/null && install_amp
|
|
800
1014
|
[ -d "$HOME/.cursor" ] || [ -d "/Applications/Cursor.app" ] && {
|
|
801
|
-
|
|
1015
|
+
_cm_cursor_rules="$(resolve_cursor_rules_dir all)"
|
|
1016
|
+
echo -e " ${W}Cursor → ${_cm_cursor_rules} ${DIM}(not your current shell cwd)${NC}"
|
|
1017
|
+
install_skills_to "${_cm_cursor_rules}" "mdc"
|
|
802
1018
|
}
|
|
803
|
-
|
|
804
|
-
|
|
1019
|
+
install_openviking
|
|
1020
|
+
install_cli "--auto"
|
|
1021
|
+
echo ""
|
|
1022
|
+
echo -e "${G}${BOLD}✅ All installations completed!${NC}"
|
|
1023
|
+
echo -e "${C}$(msg docs) https://cody.todyle.com/docs${NC}"
|
|
1024
|
+
print_all_done_summary
|
|
805
1025
|
exit 0
|
|
806
1026
|
fi
|
|
807
1027
|
|
|
@@ -848,8 +1068,11 @@ for platform in "${platforms[@]}"; do
|
|
|
848
1068
|
;;
|
|
849
1069
|
cursor)
|
|
850
1070
|
echo ""
|
|
851
|
-
echo -e "${B}${BOLD}Cursor —
|
|
852
|
-
|
|
1071
|
+
echo -e "${B}${BOLD}Cursor — Rules + plugin${NC}"
|
|
1072
|
+
_cm_cursor_rules="$(resolve_cursor_rules_dir cursor)"
|
|
1073
|
+
install_skills_to "${_cm_cursor_rules}" "mdc"
|
|
1074
|
+
echo -e " ${C}ℹ Rules → ${_cm_cursor_rules}${NC}"
|
|
1075
|
+
echo -e " In Cursor Agent chat: ${C}/add-plugin cody-master${NC}"
|
|
853
1076
|
;;
|
|
854
1077
|
codex)
|
|
855
1078
|
echo ""
|
|
@@ -893,6 +1116,7 @@ for platform in "${platforms[@]}"; do
|
|
|
893
1116
|
esac
|
|
894
1117
|
done
|
|
895
1118
|
|
|
1119
|
+
install_openviking
|
|
896
1120
|
install_cli
|
|
897
1121
|
print_onboarding
|
|
898
1122
|
|