trackops 2.0.3 → 2.0.5
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 +695 -402
- package/bin/trackops.js +116 -116
- package/lib/config.js +326 -326
- package/lib/control.js +208 -208
- package/lib/env.js +244 -244
- package/lib/init.js +325 -325
- package/lib/locale.js +24 -0
- package/lib/opera-bootstrap.js +941 -874
- package/lib/opera.js +494 -477
- package/lib/preferences.js +74 -74
- package/lib/registry.js +214 -196
- package/lib/release.js +56 -56
- package/lib/runtime-state.js +144 -144
- package/lib/server.js +312 -207
- package/lib/skills.js +74 -57
- package/lib/workspace.js +260 -260
- package/locales/en.json +192 -166
- package/locales/es.json +192 -166
- 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 +558 -554
- 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 -75
- package/skills/trackops/locales/en/references/troubleshooting.md +73 -55
- package/skills/trackops/locales/en/references/workflow.md +55 -32
- package/skills/trackops/references/activation.md +94 -75
- package/skills/trackops/references/troubleshooting.md +73 -55
- 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 -266
- package/ui/css/charts.css +425 -327
- package/ui/css/components.css +1107 -570
- package/ui/css/onboarding.css +133 -0
- package/ui/css/panels.css +345 -406
- package/ui/css/terminal.css +125 -0
- package/ui/css/timeline.css +58 -0
- package/ui/css/tokens.css +284 -227
- package/ui/favicon.svg +5 -5
- package/ui/index.html +99 -96
- package/ui/js/api.js +49 -13
- package/ui/js/app.js +28 -32
- package/ui/js/charts.js +526 -0
- package/ui/js/console-logger.js +172 -172
- package/ui/js/filters.js +247 -0
- package/ui/js/icons.js +129 -104
- package/ui/js/keyboard.js +229 -0
- package/ui/js/onboarding.js +33 -42
- package/ui/js/router.js +142 -125
- package/ui/js/theme.js +100 -100
- package/ui/js/time-tracker.js +248 -248
- package/ui/js/views/board.js +84 -114
- package/ui/js/views/dashboard.js +870 -0
- package/ui/js/views/flash.js +47 -47
- package/ui/js/views/projects.js +745 -0
- package/ui/js/views/scrum.js +476 -0
- package/ui/js/views/settings.js +153 -203
- package/ui/js/views/sidebar.js +37 -31
- package/ui/js/views/tasks.js +218 -101
- package/ui/js/views/timeline.js +265 -0
- package/ui/js/views/topbar.js +94 -107
- package/ui/app.js +0 -950
- package/ui/js/views/insights.js +0 -340
- package/ui/js/views/overview.js +0 -369
- package/ui/styles.css +0 -688
package/lib/skills.js
CHANGED
|
@@ -8,6 +8,14 @@ const { t, setLocale } = require("./i18n");
|
|
|
8
8
|
const { resolveSkillFile } = require("./resources");
|
|
9
9
|
|
|
10
10
|
const SKILLS_TEMPLATES_DIR = path.join(__dirname, "..", "templates", "skills");
|
|
11
|
+
const INSTALLED_SKILL_PRIORITY = [
|
|
12
|
+
"opera-skill",
|
|
13
|
+
"project-starter-skill",
|
|
14
|
+
"opera-contract-auditor",
|
|
15
|
+
"opera-policy-guard",
|
|
16
|
+
"commiter",
|
|
17
|
+
"changelog-updater",
|
|
18
|
+
];
|
|
11
19
|
|
|
12
20
|
function copyDirRecursive(src, dest) {
|
|
13
21
|
fs.mkdirSync(dest, { recursive: true });
|
|
@@ -22,9 +30,9 @@ function copyDirRecursive(src, dest) {
|
|
|
22
30
|
}
|
|
23
31
|
}
|
|
24
32
|
|
|
25
|
-
function parseFrontmatter(content) {
|
|
26
|
-
const match = content.match(/^---\s*\n([\s\S]*?)\n---/);
|
|
27
|
-
if (!match) return {};
|
|
33
|
+
function parseFrontmatter(content) {
|
|
34
|
+
const match = content.match(/^---\s*\n([\s\S]*?)\n---/);
|
|
35
|
+
if (!match) return {};
|
|
28
36
|
const fm = {};
|
|
29
37
|
for (const line of match[1].split("\n")) {
|
|
30
38
|
const sep = line.indexOf(":");
|
|
@@ -34,16 +42,16 @@ function parseFrontmatter(content) {
|
|
|
34
42
|
fm[key] = val;
|
|
35
43
|
}
|
|
36
44
|
}
|
|
37
|
-
return fm;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
function getSkillsDir(root) {
|
|
41
|
-
return config.ensureContext(root).paths.skillsDir;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
function getRegistryPath(root) {
|
|
45
|
-
return config.ensureContext(root).paths.registryPath;
|
|
46
|
-
}
|
|
45
|
+
return fm;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function getSkillsDir(root) {
|
|
49
|
+
return config.ensureContext(root).paths.skillsDir;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function getRegistryPath(root) {
|
|
53
|
+
return config.ensureContext(root).paths.registryPath;
|
|
54
|
+
}
|
|
47
55
|
|
|
48
56
|
function catalogSkills() {
|
|
49
57
|
if (!fs.existsSync(SKILLS_TEMPLATES_DIR)) return [];
|
|
@@ -58,28 +66,37 @@ function catalogSkills() {
|
|
|
58
66
|
.filter(Boolean);
|
|
59
67
|
}
|
|
60
68
|
|
|
61
|
-
function installedSkills(root) {
|
|
62
|
-
const skillsDir = getSkillsDir(root);
|
|
63
|
-
if (!fs.existsSync(skillsDir)) return [];
|
|
64
|
-
|
|
65
|
-
.filter((e) => e.isDirectory() && fs.existsSync(path.join(skillsDir, e.name, "SKILL.md")))
|
|
66
|
-
.map((e) => {
|
|
67
|
-
const fm = parseFrontmatter(fs.readFileSync(path.join(skillsDir, e.name, "SKILL.md"), "utf8"));
|
|
68
|
-
return { name: e.name, description: fm.description || "", version: fm.version || "1.0" };
|
|
69
|
-
})
|
|
70
|
-
.filter(Boolean);
|
|
71
|
-
|
|
69
|
+
function installedSkills(root) {
|
|
70
|
+
const skillsDir = getSkillsDir(root);
|
|
71
|
+
if (!fs.existsSync(skillsDir)) return [];
|
|
72
|
+
const skills = fs.readdirSync(skillsDir, { withFileTypes: true })
|
|
73
|
+
.filter((e) => e.isDirectory() && fs.existsSync(path.join(skillsDir, e.name, "SKILL.md")))
|
|
74
|
+
.map((e) => {
|
|
75
|
+
const fm = parseFrontmatter(fs.readFileSync(path.join(skillsDir, e.name, "SKILL.md"), "utf8"));
|
|
76
|
+
return { name: e.name, description: fm.description || "", version: fm.version || "1.0" };
|
|
77
|
+
})
|
|
78
|
+
.filter(Boolean);
|
|
79
|
+
skills.sort((a, b) => {
|
|
80
|
+
const ai = INSTALLED_SKILL_PRIORITY.indexOf(a.name);
|
|
81
|
+
const bi = INSTALLED_SKILL_PRIORITY.indexOf(b.name);
|
|
82
|
+
const ap = ai >= 0 ? ai : INSTALLED_SKILL_PRIORITY.length;
|
|
83
|
+
const bp = bi >= 0 ? bi : INSTALLED_SKILL_PRIORITY.length;
|
|
84
|
+
if (ap !== bp) return ap - bp;
|
|
85
|
+
return a.name.localeCompare(b.name);
|
|
86
|
+
});
|
|
87
|
+
return skills;
|
|
88
|
+
}
|
|
72
89
|
|
|
73
90
|
function updateRegistry(root) {
|
|
74
91
|
const registryPath = getRegistryPath(root);
|
|
75
92
|
fs.mkdirSync(path.dirname(registryPath), { recursive: true });
|
|
76
|
-
let locale = "es";
|
|
77
|
-
const context = config.ensureContext(root);
|
|
78
|
-
const controlFile = config.controlFilePath(context);
|
|
79
|
-
if (fs.existsSync(controlFile)) {
|
|
80
|
-
try {
|
|
81
|
-
locale = config.getLocale(config.loadControl(context));
|
|
82
|
-
setLocale(locale);
|
|
93
|
+
let locale = "es";
|
|
94
|
+
const context = config.ensureContext(root);
|
|
95
|
+
const controlFile = config.controlFilePath(context);
|
|
96
|
+
if (fs.existsSync(controlFile)) {
|
|
97
|
+
try {
|
|
98
|
+
locale = config.getLocale(config.loadControl(context));
|
|
99
|
+
setLocale(locale);
|
|
83
100
|
} catch (_error) {
|
|
84
101
|
setLocale("es");
|
|
85
102
|
}
|
|
@@ -97,29 +114,29 @@ function updateRegistry(root) {
|
|
|
97
114
|
fs.writeFileSync(registryPath, lines.join("\n") + "\n", "utf8");
|
|
98
115
|
|
|
99
116
|
// Also update control meta
|
|
100
|
-
if (fs.existsSync(controlFile)) {
|
|
101
|
-
try {
|
|
102
|
-
const control = config.loadControl(context);
|
|
103
|
-
if (control.meta.opera) {
|
|
104
|
-
control.meta.opera.skills = skills.map((s) => s.name);
|
|
105
|
-
config.saveControl(context, control);
|
|
106
|
-
}
|
|
117
|
+
if (fs.existsSync(controlFile)) {
|
|
118
|
+
try {
|
|
119
|
+
const control = config.loadControl(context);
|
|
120
|
+
if (control.meta.opera) {
|
|
121
|
+
control.meta.opera.skills = skills.map((s) => s.name);
|
|
122
|
+
config.saveControl(context, control);
|
|
123
|
+
}
|
|
107
124
|
} catch (_e) { /* ignore */ }
|
|
108
125
|
}
|
|
109
126
|
}
|
|
110
127
|
|
|
111
|
-
function installSkill(root, skillName) {
|
|
112
|
-
const context = config.ensureContext(root);
|
|
113
|
-
const control = config.loadControl(context);
|
|
114
|
-
setLocale(config.getLocale(control));
|
|
115
|
-
const locale = config.getLocale(control);
|
|
128
|
+
function installSkill(root, skillName) {
|
|
129
|
+
const context = config.ensureContext(root);
|
|
130
|
+
const control = config.loadControl(context);
|
|
131
|
+
setLocale(config.getLocale(control));
|
|
132
|
+
const locale = config.getLocale(control);
|
|
116
133
|
|
|
117
134
|
const templateDir = path.join(SKILLS_TEMPLATES_DIR, skillName);
|
|
118
135
|
if (!fs.existsSync(templateDir)) {
|
|
119
136
|
throw new Error(t("skill.notFound", { name: skillName }));
|
|
120
137
|
}
|
|
121
138
|
|
|
122
|
-
const targetDir = path.join(getSkillsDir(context), skillName);
|
|
139
|
+
const targetDir = path.join(getSkillsDir(context), skillName);
|
|
123
140
|
if (fs.existsSync(path.join(targetDir, "SKILL.md"))) {
|
|
124
141
|
console.log(t("skill.alreadyInstalled", { name: skillName }));
|
|
125
142
|
return;
|
|
@@ -130,25 +147,25 @@ function installSkill(root, skillName) {
|
|
|
130
147
|
if (localizedSkill) {
|
|
131
148
|
fs.copyFileSync(localizedSkill, path.join(targetDir, "SKILL.md"));
|
|
132
149
|
}
|
|
133
|
-
updateRegistry(context);
|
|
134
|
-
console.log(t("skill.installed", { name: skillName }));
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
function removeSkill(root, skillName) {
|
|
138
|
-
const context = config.ensureContext(root);
|
|
139
|
-
const control = config.loadControl(context);
|
|
140
|
-
setLocale(config.getLocale(control));
|
|
141
|
-
|
|
142
|
-
const targetDir = path.join(getSkillsDir(context), skillName);
|
|
150
|
+
updateRegistry(context);
|
|
151
|
+
console.log(t("skill.installed", { name: skillName }));
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
function removeSkill(root, skillName) {
|
|
155
|
+
const context = config.ensureContext(root);
|
|
156
|
+
const control = config.loadControl(context);
|
|
157
|
+
setLocale(config.getLocale(control));
|
|
158
|
+
|
|
159
|
+
const targetDir = path.join(getSkillsDir(context), skillName);
|
|
143
160
|
if (!fs.existsSync(targetDir)) {
|
|
144
161
|
console.log(t("skill.notInstalled", { name: skillName }));
|
|
145
162
|
return;
|
|
146
163
|
}
|
|
147
164
|
|
|
148
165
|
fs.rmSync(targetDir, { recursive: true, force: true });
|
|
149
|
-
updateRegistry(context);
|
|
150
|
-
console.log(t("skill.removed", { name: skillName }));
|
|
151
|
-
}
|
|
166
|
+
updateRegistry(context);
|
|
167
|
+
console.log(t("skill.removed", { name: skillName }));
|
|
168
|
+
}
|
|
152
169
|
|
|
153
170
|
/* ── CLI commands ── */
|
|
154
171
|
|