trackops 2.0.4 → 2.0.6
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/LICENSE +21 -21
- package/README.md +660 -575
- package/bin/trackops.js +127 -106
- package/lib/cli-format.js +118 -0
- package/lib/config.js +352 -326
- package/lib/control.js +408 -246
- package/lib/env.js +234 -222
- package/lib/i18n.js +5 -4
- package/lib/init.js +390 -282
- package/lib/locale.js +41 -41
- package/lib/opera-bootstrap.js +1066 -880
- package/lib/opera.js +615 -444
- package/lib/preferences.js +74 -74
- package/lib/registry.js +214 -214
- package/lib/release.js +56 -56
- package/lib/runtime-state.js +144 -144
- package/lib/skills.js +114 -89
- package/lib/workspace.js +259 -248
- package/locales/en.json +311 -167
- package/locales/es.json +314 -170
- package/package.json +61 -58
- package/scripts/postinstall-locale.js +21 -21
- package/scripts/skills-marketplace-smoke.js +124 -124
- package/scripts/smoke-tests.js +563 -517
- package/scripts/sync-skill-version.js +21 -21
- package/scripts/validate-skill.js +103 -103
- package/skills/trackops/SKILL.md +126 -122
- package/skills/trackops/agents/openai.yaml +7 -7
- package/skills/trackops/locales/en/SKILL.md +126 -122
- package/skills/trackops/locales/en/references/activation.md +94 -90
- package/skills/trackops/locales/en/references/troubleshooting.md +73 -67
- package/skills/trackops/locales/en/references/workflow.md +55 -32
- package/skills/trackops/references/activation.md +94 -90
- package/skills/trackops/references/troubleshooting.md +73 -67
- package/skills/trackops/references/workflow.md +55 -32
- package/skills/trackops/skill.json +29 -29
- package/templates/hooks/post-checkout +2 -2
- package/templates/hooks/post-commit +2 -2
- package/templates/hooks/post-merge +2 -2
- package/templates/opera/agent.md +28 -27
- package/templates/opera/architecture/dependency-graph.md +24 -24
- package/templates/opera/architecture/runtime-automation.md +24 -24
- package/templates/opera/architecture/runtime-operations.md +34 -34
- package/templates/opera/en/agent.md +22 -21
- package/templates/opera/en/architecture/dependency-graph.md +24 -24
- package/templates/opera/en/architecture/runtime-automation.md +24 -24
- package/templates/opera/en/architecture/runtime-operations.md +34 -34
- package/templates/opera/en/reviews/delivery-audit.md +18 -18
- package/templates/opera/en/reviews/integration-audit.md +18 -18
- package/templates/opera/en/router.md +24 -19
- package/templates/opera/references/autonomy-and-recovery.md +117 -117
- package/templates/opera/references/opera-cycle.md +193 -193
- package/templates/opera/registry.md +28 -28
- package/templates/opera/reviews/delivery-audit.md +18 -18
- package/templates/opera/reviews/integration-audit.md +18 -18
- package/templates/opera/router.md +54 -49
- package/templates/skills/changelog-updater/SKILL.md +69 -69
- package/templates/skills/commiter/SKILL.md +99 -99
- package/templates/skills/opera-contract-auditor/SKILL.md +38 -38
- package/templates/skills/opera-contract-auditor/locales/en/SKILL.md +38 -38
- package/templates/skills/opera-policy-guard/SKILL.md +26 -26
- package/templates/skills/opera-policy-guard/locales/en/SKILL.md +26 -26
- package/templates/skills/opera-skill/SKILL.md +279 -0
- package/templates/skills/opera-skill/locales/en/SKILL.md +279 -0
- package/templates/skills/opera-skill/locales/en/references/phase-dod.md +138 -0
- package/templates/skills/opera-skill/references/phase-dod.md +138 -0
- package/templates/skills/project-starter-skill/SKILL.md +150 -131
- package/templates/skills/project-starter-skill/locales/en/SKILL.md +143 -105
- package/templates/skills/project-starter-skill/references/opera-cycle.md +195 -193
- package/ui/css/base.css +284 -284
- package/ui/css/charts.css +425 -425
- package/ui/css/components.css +1107 -1107
- package/ui/css/onboarding.css +133 -133
- package/ui/css/terminal.css +125 -125
- package/ui/css/timeline.css +58 -58
- package/ui/css/tokens.css +284 -284
- package/ui/favicon.svg +5 -5
- package/ui/index.html +99 -99
- package/ui/js/charts.js +526 -526
- package/ui/js/console-logger.js +172 -172
- package/ui/js/filters.js +247 -247
- package/ui/js/icons.js +129 -129
- package/ui/js/keyboard.js +229 -229
- package/ui/js/router.js +142 -142
- package/ui/js/theme.js +100 -100
- package/ui/js/time-tracker.js +248 -248
- package/ui/js/views/dashboard.js +870 -870
- package/ui/js/views/flash.js +47 -47
- package/ui/js/views/projects.js +745 -745
- package/ui/js/views/scrum.js +476 -476
- package/ui/js/views/settings.js +331 -331
- package/ui/js/views/timeline.js +265 -265
package/package.json
CHANGED
|
@@ -1,58 +1,61 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "trackops",
|
|
3
|
-
"version": "2.0.
|
|
4
|
-
"description": "
|
|
5
|
-
"main": "lib/control.js",
|
|
6
|
-
"bin": {
|
|
7
|
-
"trackops": "bin/trackops.js"
|
|
8
|
-
},
|
|
9
|
-
"files": [
|
|
10
|
-
"bin/",
|
|
11
|
-
"lib/",
|
|
12
|
-
"locales/",
|
|
13
|
-
"skills/",
|
|
14
|
-
"scripts/",
|
|
15
|
-
"ui/",
|
|
16
|
-
"templates/"
|
|
17
|
-
],
|
|
18
|
-
"keywords": [
|
|
19
|
-
"project-management",
|
|
20
|
-
"task-management",
|
|
21
|
-
"dashboard",
|
|
22
|
-
"ops",
|
|
23
|
-
"opera",
|
|
24
|
-
"methodology",
|
|
25
|
-
"cli",
|
|
26
|
-
"devops",
|
|
27
|
-
"tracking",
|
|
28
|
-
"agile"
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
"
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
"
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
"url": "https://github.com/Baxahaun/trackops
|
|
41
|
-
},
|
|
42
|
-
"
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
"
|
|
46
|
-
"
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
"
|
|
50
|
-
"
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
"
|
|
54
|
-
"
|
|
55
|
-
"
|
|
56
|
-
"
|
|
57
|
-
|
|
58
|
-
|
|
1
|
+
{
|
|
2
|
+
"name": "trackops",
|
|
3
|
+
"version": "2.0.6",
|
|
4
|
+
"description": "Local control and coordination system for AI-agent software development",
|
|
5
|
+
"main": "lib/control.js",
|
|
6
|
+
"bin": {
|
|
7
|
+
"trackops": "bin/trackops.js"
|
|
8
|
+
},
|
|
9
|
+
"files": [
|
|
10
|
+
"bin/",
|
|
11
|
+
"lib/",
|
|
12
|
+
"locales/",
|
|
13
|
+
"skills/",
|
|
14
|
+
"scripts/",
|
|
15
|
+
"ui/",
|
|
16
|
+
"templates/"
|
|
17
|
+
],
|
|
18
|
+
"keywords": [
|
|
19
|
+
"project-management",
|
|
20
|
+
"task-management",
|
|
21
|
+
"dashboard",
|
|
22
|
+
"ops",
|
|
23
|
+
"opera",
|
|
24
|
+
"methodology",
|
|
25
|
+
"cli",
|
|
26
|
+
"devops",
|
|
27
|
+
"tracking",
|
|
28
|
+
"agile",
|
|
29
|
+
"ai-agents",
|
|
30
|
+
"coordination",
|
|
31
|
+
"skills"
|
|
32
|
+
],
|
|
33
|
+
"author": {
|
|
34
|
+
"name": "Xavier Crespo Gríman",
|
|
35
|
+
"email": "crespoxac@gmail.com",
|
|
36
|
+
"url": "https://baxahaun.com"
|
|
37
|
+
},
|
|
38
|
+
"repository": {
|
|
39
|
+
"type": "git",
|
|
40
|
+
"url": "git+https://github.com/Baxahaun/trackops.git"
|
|
41
|
+
},
|
|
42
|
+
"bugs": {
|
|
43
|
+
"url": "https://github.com/Baxahaun/trackops/issues"
|
|
44
|
+
},
|
|
45
|
+
"homepage": "https://github.com/Baxahaun/trackops#readme",
|
|
46
|
+
"funding": "https://baxahaun.github.io/trackops/#support",
|
|
47
|
+
"license": "MIT",
|
|
48
|
+
"type": "commonjs",
|
|
49
|
+
"engines": {
|
|
50
|
+
"node": ">=18"
|
|
51
|
+
},
|
|
52
|
+
"scripts": {
|
|
53
|
+
"postinstall": "node scripts/postinstall-locale.js",
|
|
54
|
+
"test": "node scripts/smoke-tests.js",
|
|
55
|
+
"test:smoke": "node scripts/smoke-tests.js",
|
|
56
|
+
"skill:sync-version": "node scripts/sync-skill-version.js",
|
|
57
|
+
"skill:validate": "node scripts/validate-skill.js",
|
|
58
|
+
"skill:smoke": "node scripts/skills-marketplace-smoke.js",
|
|
59
|
+
"release:check": "npm test && npm run skill:validate && npm run skill:smoke && npm pack --dry-run"
|
|
60
|
+
}
|
|
61
|
+
}
|
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
const runtimeState = require("../lib/runtime-state");
|
|
4
|
-
const { setLocale, t } = require("../lib/i18n");
|
|
5
|
-
|
|
6
|
-
function isGlobalInstall() {
|
|
7
|
-
return String(process.env.npm_config_global || "").toLowerCase() === "true";
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
async function main() {
|
|
11
|
-
if (!isGlobalInstall()) return;
|
|
12
|
-
const result = await runtimeState.ensureGlobalLocale({ interactive: true });
|
|
13
|
-
if (!result?.locale) return;
|
|
14
|
-
setLocale(result.locale);
|
|
15
|
-
process.stdout.write(`${t("postinstall.localeSet", { locale: result.locale, source: t(`locale.source.${result.source}`) })}\n`);
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
main().catch((error) => {
|
|
19
|
-
process.stderr.write(`${error.message}\n`);
|
|
20
|
-
process.exit(0);
|
|
21
|
-
});
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
const runtimeState = require("../lib/runtime-state");
|
|
4
|
+
const { setLocale, t } = require("../lib/i18n");
|
|
5
|
+
|
|
6
|
+
function isGlobalInstall() {
|
|
7
|
+
return String(process.env.npm_config_global || "").toLowerCase() === "true";
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
async function main() {
|
|
11
|
+
if (!isGlobalInstall()) return;
|
|
12
|
+
const result = await runtimeState.ensureGlobalLocale({ interactive: true });
|
|
13
|
+
if (!result?.locale) return;
|
|
14
|
+
setLocale(result.locale);
|
|
15
|
+
process.stdout.write(`${t("postinstall.localeSet", { locale: result.locale, source: t(`locale.source.${result.source}`) })}\n`);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
main().catch((error) => {
|
|
19
|
+
process.stderr.write(`${error.message}\n`);
|
|
20
|
+
process.exit(0);
|
|
21
|
+
});
|
|
@@ -1,124 +1,124 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
const assert = require("assert");
|
|
4
|
-
const fs = require("fs");
|
|
5
|
-
const os = require("os");
|
|
6
|
-
const path = require("path");
|
|
7
|
-
const { spawnSync } = require("child_process");
|
|
8
|
-
|
|
9
|
-
const ROOT = path.resolve(__dirname, "..");
|
|
10
|
-
const SKILL_DIR = path.join(ROOT, "skills", "trackops");
|
|
11
|
-
const SKILL_CONFIG = JSON.parse(fs.readFileSync(path.join(SKILL_DIR, "skill.json"), "utf8"));
|
|
12
|
-
|
|
13
|
-
function run(command, args, cwd, envOverrides = {}) {
|
|
14
|
-
const shell = process.platform === "win32" && /\.(cmd|bat)$/i.test(command);
|
|
15
|
-
return spawnSync(command, args, {
|
|
16
|
-
cwd,
|
|
17
|
-
encoding: "utf8",
|
|
18
|
-
env: { ...process.env, ...envOverrides },
|
|
19
|
-
shell,
|
|
20
|
-
});
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
function getNpxCommand() {
|
|
24
|
-
return process.platform === "win32" ? "npx.cmd" : "npx";
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
function ensureOk(result, context) {
|
|
28
|
-
const output = `${result.stdout || ""}\n${result.stderr || ""}`.trim();
|
|
29
|
-
assert.strictEqual(result.status, 0, output || context);
|
|
30
|
-
return output;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
function initGitRepo(repo) {
|
|
34
|
-
ensureOk(run("git", ["init"], repo), "git init failed");
|
|
35
|
-
ensureOk(run("git", ["config", "user.email", "skills-smoke@example.com"], repo), "git config email failed");
|
|
36
|
-
ensureOk(run("git", ["config", "user.name", "Skills Smoke"], repo), "git config name failed");
|
|
37
|
-
ensureOk(run("git", ["add", "."], repo), "git add failed");
|
|
38
|
-
ensureOk(run("git", ["commit", "-m", "skills smoke fixture"], repo), "git commit failed");
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
function buildIsolatedEnv(homeRoot) {
|
|
42
|
-
const env = {
|
|
43
|
-
HOME: homeRoot,
|
|
44
|
-
USERPROFILE: homeRoot,
|
|
45
|
-
APPDATA: path.join(homeRoot, "AppData", "Roaming"),
|
|
46
|
-
LOCALAPPDATA: path.join(homeRoot, "AppData", "Local"),
|
|
47
|
-
XDG_CONFIG_HOME: path.join(homeRoot, ".config"),
|
|
48
|
-
};
|
|
49
|
-
for (const value of Object.values(env)) {
|
|
50
|
-
fs.mkdirSync(value, { recursive: true });
|
|
51
|
-
}
|
|
52
|
-
return env;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
function findInstalledSkill(rootDir, skillName) {
|
|
56
|
-
const matches = [];
|
|
57
|
-
|
|
58
|
-
function walk(dir) {
|
|
59
|
-
const entries = fs.readdirSync(dir, { withFileTypes: true });
|
|
60
|
-
for (const entry of entries) {
|
|
61
|
-
const fullPath = path.join(dir, entry.name);
|
|
62
|
-
if (entry.isDirectory()) {
|
|
63
|
-
walk(fullPath);
|
|
64
|
-
continue;
|
|
65
|
-
}
|
|
66
|
-
if (entry.isFile() && entry.name === "SKILL.md" && path.basename(path.dirname(fullPath)) === skillName) {
|
|
67
|
-
matches.push(path.dirname(fullPath));
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
walk(rootDir);
|
|
73
|
-
return matches;
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
function main() {
|
|
77
|
-
const tempRoot = fs.mkdtempSync(path.join(os.tmpdir(), "trackops-skills-smoke-"));
|
|
78
|
-
const sourceRepo = path.join(tempRoot, "source");
|
|
79
|
-
const sourceSkillDir = path.join(sourceRepo, "skills", "trackops");
|
|
80
|
-
const homeRoot = path.join(tempRoot, "home");
|
|
81
|
-
|
|
82
|
-
fs.mkdirSync(path.dirname(sourceSkillDir), { recursive: true });
|
|
83
|
-
fs.cpSync(SKILL_DIR, sourceSkillDir, { recursive: true });
|
|
84
|
-
initGitRepo(sourceRepo);
|
|
85
|
-
|
|
86
|
-
const env = buildIsolatedEnv(homeRoot);
|
|
87
|
-
const distribution = SKILL_CONFIG.distribution || {};
|
|
88
|
-
const skillName = distribution.skill || SKILL_CONFIG.name;
|
|
89
|
-
|
|
90
|
-
const listResult = run(
|
|
91
|
-
getNpxCommand(),
|
|
92
|
-
["--yes", "skills", "add", sourceRepo, "--list", "--skill", skillName, "--full-depth", "-y"],
|
|
93
|
-
ROOT,
|
|
94
|
-
env,
|
|
95
|
-
);
|
|
96
|
-
const listOutput = ensureOk(listResult, "skills list failed");
|
|
97
|
-
assert.match(listOutput, /\btrackops\b/i, listOutput);
|
|
98
|
-
|
|
99
|
-
const installResult = run(
|
|
100
|
-
getNpxCommand(),
|
|
101
|
-
["--yes", "skills", "add", sourceRepo, "--skill", skillName, "--full-depth", "--global", "--agent", "codex", "--copy", "-y"],
|
|
102
|
-
ROOT,
|
|
103
|
-
env,
|
|
104
|
-
);
|
|
105
|
-
ensureOk(installResult, "skills install failed");
|
|
106
|
-
|
|
107
|
-
const installed = findInstalledSkill(homeRoot, skillName);
|
|
108
|
-
assert.ok(installed.length >= 1, `trackops skill was not installed under ${homeRoot}`);
|
|
109
|
-
|
|
110
|
-
const installedSkillDir = installed[0];
|
|
111
|
-
assert.ok(fs.existsSync(path.join(installedSkillDir, "references", "activation.md")));
|
|
112
|
-
assert.ok(fs.existsSync(path.join(installedSkillDir, "skill.json")));
|
|
113
|
-
assert.ok(!fs.existsSync(path.join(installedSkillDir, "scripts", "bootstrap-trackops.js")));
|
|
114
|
-
|
|
115
|
-
fs.rmSync(tempRoot, { recursive: true, force: true });
|
|
116
|
-
console.log("skills marketplace smoke OK");
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
try {
|
|
120
|
-
main();
|
|
121
|
-
} catch (error) {
|
|
122
|
-
console.error(error.message);
|
|
123
|
-
process.exit(1);
|
|
124
|
-
}
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
const assert = require("assert");
|
|
4
|
+
const fs = require("fs");
|
|
5
|
+
const os = require("os");
|
|
6
|
+
const path = require("path");
|
|
7
|
+
const { spawnSync } = require("child_process");
|
|
8
|
+
|
|
9
|
+
const ROOT = path.resolve(__dirname, "..");
|
|
10
|
+
const SKILL_DIR = path.join(ROOT, "skills", "trackops");
|
|
11
|
+
const SKILL_CONFIG = JSON.parse(fs.readFileSync(path.join(SKILL_DIR, "skill.json"), "utf8"));
|
|
12
|
+
|
|
13
|
+
function run(command, args, cwd, envOverrides = {}) {
|
|
14
|
+
const shell = process.platform === "win32" && /\.(cmd|bat)$/i.test(command);
|
|
15
|
+
return spawnSync(command, args, {
|
|
16
|
+
cwd,
|
|
17
|
+
encoding: "utf8",
|
|
18
|
+
env: { ...process.env, ...envOverrides },
|
|
19
|
+
shell,
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function getNpxCommand() {
|
|
24
|
+
return process.platform === "win32" ? "npx.cmd" : "npx";
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function ensureOk(result, context) {
|
|
28
|
+
const output = `${result.stdout || ""}\n${result.stderr || ""}`.trim();
|
|
29
|
+
assert.strictEqual(result.status, 0, output || context);
|
|
30
|
+
return output;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function initGitRepo(repo) {
|
|
34
|
+
ensureOk(run("git", ["init"], repo), "git init failed");
|
|
35
|
+
ensureOk(run("git", ["config", "user.email", "skills-smoke@example.com"], repo), "git config email failed");
|
|
36
|
+
ensureOk(run("git", ["config", "user.name", "Skills Smoke"], repo), "git config name failed");
|
|
37
|
+
ensureOk(run("git", ["add", "."], repo), "git add failed");
|
|
38
|
+
ensureOk(run("git", ["commit", "-m", "skills smoke fixture"], repo), "git commit failed");
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function buildIsolatedEnv(homeRoot) {
|
|
42
|
+
const env = {
|
|
43
|
+
HOME: homeRoot,
|
|
44
|
+
USERPROFILE: homeRoot,
|
|
45
|
+
APPDATA: path.join(homeRoot, "AppData", "Roaming"),
|
|
46
|
+
LOCALAPPDATA: path.join(homeRoot, "AppData", "Local"),
|
|
47
|
+
XDG_CONFIG_HOME: path.join(homeRoot, ".config"),
|
|
48
|
+
};
|
|
49
|
+
for (const value of Object.values(env)) {
|
|
50
|
+
fs.mkdirSync(value, { recursive: true });
|
|
51
|
+
}
|
|
52
|
+
return env;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function findInstalledSkill(rootDir, skillName) {
|
|
56
|
+
const matches = [];
|
|
57
|
+
|
|
58
|
+
function walk(dir) {
|
|
59
|
+
const entries = fs.readdirSync(dir, { withFileTypes: true });
|
|
60
|
+
for (const entry of entries) {
|
|
61
|
+
const fullPath = path.join(dir, entry.name);
|
|
62
|
+
if (entry.isDirectory()) {
|
|
63
|
+
walk(fullPath);
|
|
64
|
+
continue;
|
|
65
|
+
}
|
|
66
|
+
if (entry.isFile() && entry.name === "SKILL.md" && path.basename(path.dirname(fullPath)) === skillName) {
|
|
67
|
+
matches.push(path.dirname(fullPath));
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
walk(rootDir);
|
|
73
|
+
return matches;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
function main() {
|
|
77
|
+
const tempRoot = fs.mkdtempSync(path.join(os.tmpdir(), "trackops-skills-smoke-"));
|
|
78
|
+
const sourceRepo = path.join(tempRoot, "source");
|
|
79
|
+
const sourceSkillDir = path.join(sourceRepo, "skills", "trackops");
|
|
80
|
+
const homeRoot = path.join(tempRoot, "home");
|
|
81
|
+
|
|
82
|
+
fs.mkdirSync(path.dirname(sourceSkillDir), { recursive: true });
|
|
83
|
+
fs.cpSync(SKILL_DIR, sourceSkillDir, { recursive: true });
|
|
84
|
+
initGitRepo(sourceRepo);
|
|
85
|
+
|
|
86
|
+
const env = buildIsolatedEnv(homeRoot);
|
|
87
|
+
const distribution = SKILL_CONFIG.distribution || {};
|
|
88
|
+
const skillName = distribution.skill || SKILL_CONFIG.name;
|
|
89
|
+
|
|
90
|
+
const listResult = run(
|
|
91
|
+
getNpxCommand(),
|
|
92
|
+
["--yes", "skills", "add", sourceRepo, "--list", "--skill", skillName, "--full-depth", "-y"],
|
|
93
|
+
ROOT,
|
|
94
|
+
env,
|
|
95
|
+
);
|
|
96
|
+
const listOutput = ensureOk(listResult, "skills list failed");
|
|
97
|
+
assert.match(listOutput, /\btrackops\b/i, listOutput);
|
|
98
|
+
|
|
99
|
+
const installResult = run(
|
|
100
|
+
getNpxCommand(),
|
|
101
|
+
["--yes", "skills", "add", sourceRepo, "--skill", skillName, "--full-depth", "--global", "--agent", "codex", "--copy", "-y"],
|
|
102
|
+
ROOT,
|
|
103
|
+
env,
|
|
104
|
+
);
|
|
105
|
+
ensureOk(installResult, "skills install failed");
|
|
106
|
+
|
|
107
|
+
const installed = findInstalledSkill(homeRoot, skillName);
|
|
108
|
+
assert.ok(installed.length >= 1, `trackops skill was not installed under ${homeRoot}`);
|
|
109
|
+
|
|
110
|
+
const installedSkillDir = installed[0];
|
|
111
|
+
assert.ok(fs.existsSync(path.join(installedSkillDir, "references", "activation.md")));
|
|
112
|
+
assert.ok(fs.existsSync(path.join(installedSkillDir, "skill.json")));
|
|
113
|
+
assert.ok(!fs.existsSync(path.join(installedSkillDir, "scripts", "bootstrap-trackops.js")));
|
|
114
|
+
|
|
115
|
+
fs.rmSync(tempRoot, { recursive: true, force: true });
|
|
116
|
+
console.log("skills marketplace smoke OK");
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
try {
|
|
120
|
+
main();
|
|
121
|
+
} catch (error) {
|
|
122
|
+
console.error(error.message);
|
|
123
|
+
process.exit(1);
|
|
124
|
+
}
|