trackops 2.0.5 → 2.1.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 +319 -695
- package/bin/trackops.js +52 -23
- package/lib/cli-format.js +118 -0
- package/lib/config.js +277 -44
- package/lib/control.js +1052 -352
- package/lib/env.js +40 -28
- package/lib/i18n.js +5 -4
- package/lib/init.js +194 -56
- package/lib/opera-bootstrap.js +326 -106
- package/lib/opera-phase-dod.js +485 -0
- package/lib/opera.js +243 -78
- 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 +43 -35
- package/lib/workspace.js +32 -21
- package/locales/en.json +431 -75
- package/locales/es.json +432 -76
- package/package.json +6 -5
- package/scripts/quality-unit-tests.js +130 -0
- package/scripts/smoke-tests.js +438 -96
- package/skills/trackops/skill.json +29 -29
- package/templates/skills/opera-quality-guard/SKILL.md +26 -0
- package/templates/skills/opera-quality-guard/locales/en/SKILL.md +26 -0
- package/templates/skills/opera-skill/SKILL.md +8 -0
- package/templates/skills/opera-skill/locales/en/SKILL.md +8 -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
package/lib/skills.js
CHANGED
|
@@ -6,6 +6,7 @@ const path = require("path");
|
|
|
6
6
|
const config = require("./config");
|
|
7
7
|
const { t, setLocale } = require("./i18n");
|
|
8
8
|
const { resolveSkillFile } = require("./resources");
|
|
9
|
+
const fmt = require("./cli-format");
|
|
9
10
|
|
|
10
11
|
const SKILLS_TEMPLATES_DIR = path.join(__dirname, "..", "templates", "skills");
|
|
11
12
|
const INSTALLED_SKILL_PRIORITY = [
|
|
@@ -102,11 +103,14 @@ function updateRegistry(root) {
|
|
|
102
103
|
}
|
|
103
104
|
}
|
|
104
105
|
const skills = installedSkills(root);
|
|
105
|
-
const header = locale === "en" ? "# Skills Registry" : "#
|
|
106
|
-
const empty = locale === "en"
|
|
107
|
-
? "_No skills installed yet. Use `trackops skill install <name>` to add one._"
|
|
108
|
-
: "
|
|
109
|
-
const
|
|
106
|
+
const header = locale === "en" ? "# Skills Registry" : "# Registro de skills";
|
|
107
|
+
const empty = locale === "en"
|
|
108
|
+
? "_No skills installed yet. Use `trackops skill install <name>` to add one._"
|
|
109
|
+
: "_Todavia no hay skills instaladas. Usa `trackops skill install <nombre>` para añadir una._";
|
|
110
|
+
const tableHeader = locale === "en"
|
|
111
|
+
? "| Skill | Version | Description |"
|
|
112
|
+
: "| Skill | Version | Descripcion |";
|
|
113
|
+
const lines = [header, "", tableHeader, "|-------|---------|-------------|"];
|
|
110
114
|
for (const s of skills) {
|
|
111
115
|
lines.push(`| ${s.name} | ${s.version} | ${s.description} |`);
|
|
112
116
|
}
|
|
@@ -121,7 +125,11 @@ function updateRegistry(root) {
|
|
|
121
125
|
control.meta.opera.skills = skills.map((s) => s.name);
|
|
122
126
|
config.saveControl(context, control);
|
|
123
127
|
}
|
|
124
|
-
} catch (
|
|
128
|
+
} catch (error) {
|
|
129
|
+
if (process.env.TRACKOPS_DEBUG) {
|
|
130
|
+
process.stderr.write(`[skills] Registry update error: ${error.message}\n`);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
125
133
|
}
|
|
126
134
|
}
|
|
127
135
|
|
|
@@ -148,7 +156,7 @@ function installSkill(root, skillName) {
|
|
|
148
156
|
fs.copyFileSync(localizedSkill, path.join(targetDir, "SKILL.md"));
|
|
149
157
|
}
|
|
150
158
|
updateRegistry(context);
|
|
151
|
-
|
|
159
|
+
fmt.success(t("skill.installed", { name: skillName }));
|
|
152
160
|
}
|
|
153
161
|
|
|
154
162
|
function removeSkill(root, skillName) {
|
|
@@ -164,37 +172,37 @@ function removeSkill(root, skillName) {
|
|
|
164
172
|
|
|
165
173
|
fs.rmSync(targetDir, { recursive: true, force: true });
|
|
166
174
|
updateRegistry(context);
|
|
167
|
-
|
|
175
|
+
fmt.success(t("skill.removed", { name: skillName }));
|
|
168
176
|
}
|
|
169
177
|
|
|
170
178
|
/* ── CLI commands ── */
|
|
171
179
|
|
|
172
|
-
function cmdInstall(root, skillName) {
|
|
173
|
-
if (!skillName) { console.error("
|
|
174
|
-
installSkill(root, skillName);
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
function cmdList(root) {
|
|
178
|
-
const skills = installedSkills(root);
|
|
179
|
-
if (!skills.length) { console.log("
|
|
180
|
-
console.log(t("skill.listTitle"));
|
|
181
|
-
for (const s of skills) {
|
|
182
|
-
console.log(` ${s.name} (v${s.version}) — ${s.description}`);
|
|
183
|
-
}
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
function cmdRemove(root, skillName) {
|
|
187
|
-
if (!skillName) { console.error("
|
|
188
|
-
removeSkill(root, skillName);
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
function cmdCatalog() {
|
|
192
|
-
const skills = catalogSkills();
|
|
193
|
-
if (!skills.length) { console.log("
|
|
194
|
-
console.log(t("skill.catalogTitle"));
|
|
195
|
-
for (const s of skills) {
|
|
196
|
-
console.log(` ${s.name} (v${s.version}) — ${s.description}`);
|
|
197
|
-
}
|
|
198
|
-
}
|
|
180
|
+
function cmdInstall(root, skillName) {
|
|
181
|
+
if (!skillName) { console.error(t("skill.nameRequired")); process.exit(1); }
|
|
182
|
+
installSkill(root, skillName);
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
function cmdList(root) {
|
|
186
|
+
const skills = installedSkills(root);
|
|
187
|
+
if (!skills.length) { console.log(t("skill.noneInstalled")); return; }
|
|
188
|
+
console.log(t("skill.listTitle"));
|
|
189
|
+
for (const s of skills) {
|
|
190
|
+
console.log(` ${s.name} (v${s.version}) — ${s.description}`);
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
function cmdRemove(root, skillName) {
|
|
195
|
+
if (!skillName) { console.error(t("skill.nameRequired")); process.exit(1); }
|
|
196
|
+
removeSkill(root, skillName);
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
function cmdCatalog() {
|
|
200
|
+
const skills = catalogSkills();
|
|
201
|
+
if (!skills.length) { console.log(t("skill.noneCatalog")); return; }
|
|
202
|
+
console.log(t("skill.catalogTitle"));
|
|
203
|
+
for (const s of skills) {
|
|
204
|
+
console.log(` ${s.name} (v${s.version}) — ${s.description}`);
|
|
205
|
+
}
|
|
206
|
+
}
|
|
199
207
|
|
|
200
208
|
module.exports = { installSkill, removeSkill, installedSkills, catalogSkills, updateRegistry, cmdInstall, cmdList, cmdRemove, cmdCatalog };
|
package/lib/workspace.js
CHANGED
|
@@ -4,9 +4,10 @@ const fs = require("fs");
|
|
|
4
4
|
const path = require("path");
|
|
5
5
|
const { spawnSync } = require("child_process");
|
|
6
6
|
|
|
7
|
-
const config = require("./config");
|
|
8
|
-
const registry = require("./registry");
|
|
9
|
-
const env = require("./env");
|
|
7
|
+
const config = require("./config");
|
|
8
|
+
const registry = require("./registry");
|
|
9
|
+
const env = require("./env");
|
|
10
|
+
const { t, setLocale } = require("./i18n");
|
|
10
11
|
|
|
11
12
|
const OPS_ARTIFACTS = [
|
|
12
13
|
"project_control.json",
|
|
@@ -224,29 +225,39 @@ function migrateWorkspace(rootDir, options = {}) {
|
|
|
224
225
|
return { root, backupBranch, context };
|
|
225
226
|
}
|
|
226
227
|
|
|
227
|
-
function status(contextOrRoot) {
|
|
228
|
-
const context = config.ensureContext(contextOrRoot);
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
}
|
|
237
|
-
console.log(
|
|
238
|
-
}
|
|
228
|
+
function status(contextOrRoot) {
|
|
229
|
+
const context = config.ensureContext(contextOrRoot);
|
|
230
|
+
try {
|
|
231
|
+
setLocale(config.getLocale(config.loadControl(context)));
|
|
232
|
+
} catch (_error) {
|
|
233
|
+
setLocale("es");
|
|
234
|
+
}
|
|
235
|
+
console.log(t("workspace.status.title"));
|
|
236
|
+
console.log(t("workspace.status.layout", { value: context.layout }));
|
|
237
|
+
console.log(t("workspace.status.root", { path: context.workspaceRoot }));
|
|
238
|
+
console.log(t("workspace.status.app", { path: context.appRoot }));
|
|
239
|
+
console.log(t("workspace.status.ops", { path: context.opsRoot }));
|
|
240
|
+
if (context.manifestFile) {
|
|
241
|
+
console.log(t("workspace.status.manifest", { path: context.manifestFile }));
|
|
242
|
+
}
|
|
243
|
+
console.log(t("workspace.status.control", { path: context.controlFile }));
|
|
244
|
+
}
|
|
239
245
|
|
|
240
246
|
function cmdStatus(root) {
|
|
241
247
|
status(root);
|
|
242
248
|
}
|
|
243
249
|
|
|
244
|
-
function cmdMigrate(root, args = []) {
|
|
245
|
-
const allowDirty = args.includes("--allow-dirty");
|
|
246
|
-
const result = migrateWorkspace(root, { allowDirty });
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
}
|
|
250
|
+
function cmdMigrate(root, args = []) {
|
|
251
|
+
const allowDirty = args.includes("--allow-dirty");
|
|
252
|
+
const result = migrateWorkspace(root, { allowDirty });
|
|
253
|
+
try {
|
|
254
|
+
setLocale(config.getLocale(config.loadControl(result.context)));
|
|
255
|
+
} catch (_error) {
|
|
256
|
+
setLocale("es");
|
|
257
|
+
}
|
|
258
|
+
console.log(t("workspace.migrate.updated", { path: result.root }));
|
|
259
|
+
console.log(t("workspace.migrate.backup", { branch: result.backupBranch }));
|
|
260
|
+
}
|
|
250
261
|
|
|
251
262
|
module.exports = {
|
|
252
263
|
OPS_ARTIFACTS,
|