trackops 2.0.6 → 2.2.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/README.md +307 -701
- package/bin/trackops.js +24 -16
- package/lib/config.js +265 -58
- package/lib/control.js +830 -292
- package/lib/init.js +46 -16
- package/lib/opera-bootstrap.js +85 -45
- package/lib/opera-phase-dod.js +485 -0
- package/lib/opera.js +8 -5
- package/lib/plans.js +1329 -0
- package/lib/quality-assert.js +49 -0
- package/lib/quality.js +1759 -0
- package/lib/release.js +18 -11
- package/lib/server.js +504 -192
- package/lib/skills.js +94 -41
- package/locales/en.json +249 -15
- package/locales/es.json +249 -15
- package/package.json +3 -2
- package/scripts/quality-unit-tests.js +130 -0
- package/scripts/skills-marketplace-smoke.js +156 -124
- package/scripts/smoke-tests.js +378 -71
- package/scripts/sync-skill-version.js +29 -19
- package/scripts/validate-skill.js +188 -103
- package/skills/trackops/SKILL.md +25 -7
- package/skills/trackops/locales/en/SKILL.md +25 -7
- package/skills/trackops/locales/en/references/activation.md +3 -3
- package/skills/trackops/locales/en/references/workflow.md +5 -4
- package/skills/trackops/references/activation.md +3 -3
- package/skills/trackops/references/workflow.md +5 -4
- package/skills/trackops/skill.json +29 -29
- package/skills/trackops-quality-guard/SKILL.md +78 -0
- package/skills/trackops-quality-guard/agents/openai.yaml +7 -0
- package/skills/trackops-quality-guard/locales/en/SKILL.md +78 -0
- package/skills/trackops-quality-guard/locales/en/references/commands.md +36 -0
- package/skills/trackops-quality-guard/locales/en/references/decision-policy.md +16 -0
- package/skills/trackops-quality-guard/locales/en/references/output-format.md +24 -0
- package/skills/trackops-quality-guard/references/commands.md +36 -0
- package/skills/trackops-quality-guard/references/decision-policy.md +16 -0
- package/skills/trackops-quality-guard/references/output-format.md +24 -0
- package/skills/trackops-quality-guard/skill.json +28 -0
- package/templates/skills/opera-skill/SKILL.md +12 -0
- package/templates/skills/opera-skill/locales/en/SKILL.md +12 -0
- package/templates/skills/trackops-quality-guard/SKILL.md +72 -0
- package/templates/skills/trackops-quality-guard/locales/en/SKILL.md +72 -0
- package/templates/skills/trackops-quality-guard/locales/en/references/commands.md +30 -0
- package/templates/skills/trackops-quality-guard/locales/en/references/decision-policy.md +14 -0
- package/templates/skills/trackops-quality-guard/locales/en/references/output-format.md +21 -0
- package/templates/skills/trackops-quality-guard/references/commands.md +30 -0
- package/templates/skills/trackops-quality-guard/references/decision-policy.md +14 -0
- package/templates/skills/trackops-quality-guard/references/output-format.md +21 -0
- package/ui/js/api.js +93 -26
- package/ui/js/app.js +13 -7
- package/ui/js/filters.js +49 -29
- package/ui/js/time-tracker.js +41 -28
- package/ui/js/views/board.js +22 -14
- package/ui/js/views/dashboard.js +206 -49
- package/ui/js/views/execution.js +7 -3
- package/ui/js/views/plans.js +284 -0
- package/ui/js/views/scrum.js +25 -13
- package/ui/js/views/sidebar.js +9 -8
- package/ui/js/views/tasks.js +238 -134
|
@@ -1,124 +1,156 @@
|
|
|
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
|
|
11
|
-
const
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
return
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
);
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
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 SKILLS_ROOT = path.join(ROOT, "skills");
|
|
11
|
+
const REQUIRED_PUBLIC_SKILLS = ["trackops", "trackops-quality-guard"];
|
|
12
|
+
|
|
13
|
+
const REQUIRED_FILES_BY_SKILL = {
|
|
14
|
+
trackops: [
|
|
15
|
+
"references/activation.md",
|
|
16
|
+
"references/workflow.md",
|
|
17
|
+
"references/troubleshooting.md",
|
|
18
|
+
"skill.json",
|
|
19
|
+
],
|
|
20
|
+
"trackops-quality-guard": [
|
|
21
|
+
"references/commands.md",
|
|
22
|
+
"references/decision-policy.md",
|
|
23
|
+
"references/output-format.md",
|
|
24
|
+
"skill.json",
|
|
25
|
+
],
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
function run(command, args, cwd, envOverrides = {}) {
|
|
29
|
+
const shell = process.platform === "win32" && /\.(cmd|bat)$/i.test(command);
|
|
30
|
+
return spawnSync(command, args, {
|
|
31
|
+
cwd,
|
|
32
|
+
encoding: "utf8",
|
|
33
|
+
env: { ...process.env, ...envOverrides },
|
|
34
|
+
shell,
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function getNpxCommand() {
|
|
39
|
+
return process.platform === "win32" ? "npx.cmd" : "npx";
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function ensureOk(result, context) {
|
|
43
|
+
const output = `${result.stdout || ""}\n${result.stderr || ""}`.trim();
|
|
44
|
+
assert.strictEqual(result.status, 0, output || context);
|
|
45
|
+
return output;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function initGitRepo(repo) {
|
|
49
|
+
ensureOk(run("git", ["init"], repo), "git init failed");
|
|
50
|
+
ensureOk(run("git", ["config", "user.email", "skills-smoke@example.com"], repo), "git config email failed");
|
|
51
|
+
ensureOk(run("git", ["config", "user.name", "Skills Smoke"], repo), "git config name failed");
|
|
52
|
+
ensureOk(run("git", ["add", "."], repo), "git add failed");
|
|
53
|
+
ensureOk(run("git", ["commit", "-m", "skills smoke fixture"], repo), "git commit failed");
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
function buildIsolatedEnv(homeRoot) {
|
|
57
|
+
const env = {
|
|
58
|
+
HOME: homeRoot,
|
|
59
|
+
USERPROFILE: homeRoot,
|
|
60
|
+
APPDATA: path.join(homeRoot, "AppData", "Roaming"),
|
|
61
|
+
LOCALAPPDATA: path.join(homeRoot, "AppData", "Local"),
|
|
62
|
+
XDG_CONFIG_HOME: path.join(homeRoot, ".config"),
|
|
63
|
+
};
|
|
64
|
+
for (const value of Object.values(env)) {
|
|
65
|
+
fs.mkdirSync(value, { recursive: true });
|
|
66
|
+
}
|
|
67
|
+
return env;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
function findInstalledSkill(rootDir, skillName) {
|
|
71
|
+
const matches = [];
|
|
72
|
+
|
|
73
|
+
function walk(dir) {
|
|
74
|
+
const entries = fs.readdirSync(dir, { withFileTypes: true });
|
|
75
|
+
for (const entry of entries) {
|
|
76
|
+
const fullPath = path.join(dir, entry.name);
|
|
77
|
+
if (entry.isDirectory()) {
|
|
78
|
+
walk(fullPath);
|
|
79
|
+
continue;
|
|
80
|
+
}
|
|
81
|
+
if (entry.isFile() && entry.name === "SKILL.md" && path.basename(path.dirname(fullPath)) === skillName) {
|
|
82
|
+
matches.push(path.dirname(fullPath));
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
walk(rootDir);
|
|
88
|
+
return matches;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
function discoverPublicSkills() {
|
|
92
|
+
return fs.readdirSync(SKILLS_ROOT, { withFileTypes: true })
|
|
93
|
+
.filter((entry) => entry.isDirectory() && fs.existsSync(path.join(SKILLS_ROOT, entry.name, "skill.json")))
|
|
94
|
+
.map((entry) => {
|
|
95
|
+
const dir = path.join(SKILLS_ROOT, entry.name);
|
|
96
|
+
const config = JSON.parse(fs.readFileSync(path.join(dir, "skill.json"), "utf8"));
|
|
97
|
+
return { name: entry.name, dir, config };
|
|
98
|
+
})
|
|
99
|
+
.sort((a, b) => a.name.localeCompare(b.name));
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
function main() {
|
|
103
|
+
const tempRoot = fs.mkdtempSync(path.join(os.tmpdir(), "trackops-skills-smoke-"));
|
|
104
|
+
const sourceRepo = path.join(tempRoot, "source");
|
|
105
|
+
const homeRoot = path.join(tempRoot, "home");
|
|
106
|
+
|
|
107
|
+
fs.mkdirSync(sourceRepo, { recursive: true });
|
|
108
|
+
fs.cpSync(SKILLS_ROOT, path.join(sourceRepo, "skills"), { recursive: true });
|
|
109
|
+
initGitRepo(sourceRepo);
|
|
110
|
+
|
|
111
|
+
const env = buildIsolatedEnv(homeRoot);
|
|
112
|
+
const skills = discoverPublicSkills();
|
|
113
|
+
for (const skillName of REQUIRED_PUBLIC_SKILLS) {
|
|
114
|
+
assert.ok(skills.some((entry) => entry.name === skillName), `missing public skill ${skillName}`);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
for (const entry of skills) {
|
|
118
|
+
const distribution = entry.config.distribution || {};
|
|
119
|
+
const skillName = distribution.skill || entry.config.name;
|
|
120
|
+
|
|
121
|
+
const listResult = run(
|
|
122
|
+
getNpxCommand(),
|
|
123
|
+
["--yes", "skills", "add", sourceRepo, "--list", "--skill", skillName, "--full-depth", "-y"],
|
|
124
|
+
ROOT,
|
|
125
|
+
env,
|
|
126
|
+
);
|
|
127
|
+
const listOutput = ensureOk(listResult, `skills list failed for ${skillName}`);
|
|
128
|
+
assert.ok(listOutput.includes(skillName), listOutput);
|
|
129
|
+
|
|
130
|
+
const installResult = run(
|
|
131
|
+
getNpxCommand(),
|
|
132
|
+
["--yes", "skills", "add", sourceRepo, "--skill", skillName, "--full-depth", "--global", "--agent", "codex", "--copy", "-y"],
|
|
133
|
+
ROOT,
|
|
134
|
+
env,
|
|
135
|
+
);
|
|
136
|
+
ensureOk(installResult, `skills install failed for ${skillName}`);
|
|
137
|
+
|
|
138
|
+
const installed = findInstalledSkill(homeRoot, skillName);
|
|
139
|
+
assert.ok(installed.length >= 1, `${skillName} was not installed under ${homeRoot}`);
|
|
140
|
+
|
|
141
|
+
const installedSkillDir = installed[0];
|
|
142
|
+
for (const relativeFile of REQUIRED_FILES_BY_SKILL[skillName] || []) {
|
|
143
|
+
assert.ok(fs.existsSync(path.join(installedSkillDir, relativeFile)), `missing ${relativeFile} for ${skillName}`);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
fs.rmSync(tempRoot, { recursive: true, force: true });
|
|
148
|
+
console.log("skills marketplace smoke OK");
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
try {
|
|
152
|
+
main();
|
|
153
|
+
} catch (error) {
|
|
154
|
+
console.error(error.message);
|
|
155
|
+
process.exit(1);
|
|
156
|
+
}
|