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
package/lib/init.js
CHANGED
|
@@ -102,7 +102,7 @@ function buildDefaultControl(context, options) {
|
|
|
102
102
|
return {
|
|
103
103
|
meta: {
|
|
104
104
|
projectName: options.name || "My Project",
|
|
105
|
-
controlVersion:
|
|
105
|
+
controlVersion: config.DEFAULT_CONTROL_VERSION,
|
|
106
106
|
locale,
|
|
107
107
|
phases,
|
|
108
108
|
updatedAt: nowIso(),
|
|
@@ -133,12 +133,31 @@ function buildDefaultControl(context, options) {
|
|
|
133
133
|
explanationMode: null,
|
|
134
134
|
capturedAt: null,
|
|
135
135
|
},
|
|
136
|
-
discovery: {
|
|
137
|
-
projectState: null,
|
|
138
|
-
documentationState: null,
|
|
139
|
-
availableArtifacts: [],
|
|
140
|
-
},
|
|
141
|
-
|
|
136
|
+
discovery: {
|
|
137
|
+
projectState: null,
|
|
138
|
+
documentationState: null,
|
|
139
|
+
availableArtifacts: [],
|
|
140
|
+
},
|
|
141
|
+
quality: {
|
|
142
|
+
baselineProfile: "baseline",
|
|
143
|
+
activeProfiles: [],
|
|
144
|
+
verification: {
|
|
145
|
+
testCommands: [],
|
|
146
|
+
buildCommands: [],
|
|
147
|
+
smokeCommands: [],
|
|
148
|
+
reviewRequired: false,
|
|
149
|
+
},
|
|
150
|
+
lastReportAt: null,
|
|
151
|
+
lastVerificationAt: null,
|
|
152
|
+
lastReleaseReadiness: null,
|
|
153
|
+
lastPromotionReadiness: null,
|
|
154
|
+
},
|
|
155
|
+
agentInbox: {
|
|
156
|
+
pending: [],
|
|
157
|
+
history: [],
|
|
158
|
+
lastIssuedAt: null,
|
|
159
|
+
},
|
|
160
|
+
},
|
|
142
161
|
checks: {
|
|
143
162
|
lastBuild: { status: "pending", date: null, note: "" },
|
|
144
163
|
lastTest: { status: "pending", date: null, note: "" },
|
|
@@ -153,19 +172,30 @@ function buildDefaultControl(context, options) {
|
|
|
153
172
|
milestones: [],
|
|
154
173
|
decisionsPending: [],
|
|
155
174
|
tasks: [
|
|
156
|
-
{
|
|
157
|
-
id: "ops-bootstrap",
|
|
158
|
-
title: t("init.defaultTaskTitle"),
|
|
175
|
+
{
|
|
176
|
+
id: "ops-bootstrap",
|
|
177
|
+
title: t("init.defaultTaskTitle"),
|
|
159
178
|
phase: phases[0]?.id || "O",
|
|
160
179
|
stream: "Operations",
|
|
161
180
|
priority: "P0",
|
|
162
181
|
status: "pending",
|
|
163
182
|
required: true,
|
|
164
183
|
dependsOn: [],
|
|
165
|
-
summary: t("init.defaultTaskSummary"),
|
|
166
|
-
acceptance: [],
|
|
167
|
-
|
|
168
|
-
|
|
184
|
+
summary: t("init.defaultTaskSummary"),
|
|
185
|
+
acceptance: [],
|
|
186
|
+
execution: {
|
|
187
|
+
owner: config.DEFAULT_EXECUTION_OWNER,
|
|
188
|
+
lastActor: "system",
|
|
189
|
+
lastSource: "trackops_init",
|
|
190
|
+
currentSessionId: null,
|
|
191
|
+
lastSessionId: null,
|
|
192
|
+
lastSessionStatus: null,
|
|
193
|
+
awaitingUserConfirmation: false,
|
|
194
|
+
verificationPending: false,
|
|
195
|
+
updatedAt: nowIso(),
|
|
196
|
+
},
|
|
197
|
+
history: [{ at: nowIso(), action: "create", note: "trackops init" }],
|
|
198
|
+
},
|
|
169
199
|
],
|
|
170
200
|
findings: [],
|
|
171
201
|
};
|
|
@@ -300,7 +330,7 @@ function initSplitProject(root, options) {
|
|
|
300
330
|
control = JSON.parse(fs.readFileSync(controlFile, "utf8"));
|
|
301
331
|
if (!control.meta.phases) control.meta.phases = options.phases || config.buildDefaultPhases(options.locale);
|
|
302
332
|
if (!control.meta.locale) control.meta.locale = options.locale || config.DEFAULT_LOCALE;
|
|
303
|
-
if (!control.meta.controlVersion || control.meta.controlVersion <
|
|
333
|
+
if (!control.meta.controlVersion || control.meta.controlVersion < config.DEFAULT_CONTROL_VERSION) control.meta.controlVersion = config.DEFAULT_CONTROL_VERSION;
|
|
304
334
|
control.meta.updatedAt = nowIso();
|
|
305
335
|
config.saveControl(context, control);
|
|
306
336
|
} else {
|
|
@@ -358,7 +388,7 @@ function initLegacyProject(root, options) {
|
|
|
358
388
|
const existing = JSON.parse(fs.readFileSync(controlFile, "utf8"));
|
|
359
389
|
if (!existing.meta.phases) existing.meta.phases = options.phases || config.buildDefaultPhases(options.locale);
|
|
360
390
|
if (!existing.meta.locale) existing.meta.locale = options.locale || config.DEFAULT_LOCALE;
|
|
361
|
-
if (!existing.meta.controlVersion || existing.meta.controlVersion <
|
|
391
|
+
if (!existing.meta.controlVersion || existing.meta.controlVersion < config.DEFAULT_CONTROL_VERSION) existing.meta.controlVersion = config.DEFAULT_CONTROL_VERSION;
|
|
362
392
|
existing.meta.updatedAt = nowIso();
|
|
363
393
|
fs.writeFileSync(controlFile, `${JSON.stringify(existing, null, 2)}\n`, "utf8");
|
|
364
394
|
console.log(t("init.updated", { file: "project_control.json" }));
|
package/lib/opera-bootstrap.js
CHANGED
|
@@ -442,16 +442,27 @@ function buildHandoffPrompt(control, profile) {
|
|
|
442
442
|
t("handoff.instruction.intakeRequired"),
|
|
443
443
|
"",
|
|
444
444
|
"```json",
|
|
445
|
-
JSON.stringify({
|
|
446
|
-
problemStatement: "string — core problem the project solves",
|
|
447
|
-
targetUser: "string — primary user persona",
|
|
448
|
-
singularDesiredOutcome: "string — single most important outcome",
|
|
449
|
-
sourceOfTruth: "string — authoritative data source",
|
|
450
|
-
payload: "string — what gets delivered (NOT 'deliveryTarget')",
|
|
451
|
-
decisionOwnership: "user | shared | agent",
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
445
|
+
JSON.stringify({
|
|
446
|
+
problemStatement: "string — core problem the project solves",
|
|
447
|
+
targetUser: "string — primary user persona",
|
|
448
|
+
singularDesiredOutcome: "string — single most important outcome",
|
|
449
|
+
sourceOfTruth: "string — authoritative data source",
|
|
450
|
+
payload: "string — what gets delivered (NOT 'deliveryTarget')",
|
|
451
|
+
decisionOwnership: "user | shared | agent",
|
|
452
|
+
versionControl: {
|
|
453
|
+
remote: "boolean — whether the project uses a remote VCS",
|
|
454
|
+
provider: "string — github | gitlab | bitbucket | other",
|
|
455
|
+
developmentBranch: "string — main development branch",
|
|
456
|
+
releaseBranch: "string — publish/release branch",
|
|
457
|
+
},
|
|
458
|
+
deployment: {
|
|
459
|
+
mode: "string — manual | ci | platform",
|
|
460
|
+
target: "string — staging | production | preview | custom",
|
|
461
|
+
smokeCommand: "string — command to validate a releasable/deployed build",
|
|
462
|
+
},
|
|
463
|
+
inputSchema: { "fieldName": "type — at least one key required" },
|
|
464
|
+
outputSchema: { "fieldName": "type — at least one key required" },
|
|
465
|
+
}, null, 2),
|
|
455
466
|
"```",
|
|
456
467
|
);
|
|
457
468
|
|
|
@@ -508,13 +519,24 @@ async function collectBootstrapProfile(root, control, options = {}) {
|
|
|
508
519
|
sourceOfTruth: options.answers?.sourceOfTruth || previous.sourceOfTruth || scan.sourceOfTruthHint || "",
|
|
509
520
|
payload: options.answers?.payload || previous.payload || scan.payloadHint || "",
|
|
510
521
|
behaviorRules: normalizeList(options.answers?.behaviorRules || previous.behaviorRules || ""),
|
|
511
|
-
inputSchema: options.answers?.inputSchema || previous.inputSchema || {},
|
|
512
|
-
outputSchema: options.answers?.outputSchema || previous.outputSchema || {},
|
|
513
|
-
architecturalInvariants: normalizeList(options.answers?.architecturalInvariants || previous.architecturalInvariants || ""),
|
|
514
|
-
pipeline: normalizeList(options.answers?.pipeline || previous.pipeline || ""),
|
|
515
|
-
templates: normalizeList(options.answers?.templates || previous.templates || ""),
|
|
516
|
-
|
|
517
|
-
|
|
522
|
+
inputSchema: options.answers?.inputSchema || previous.inputSchema || {},
|
|
523
|
+
outputSchema: options.answers?.outputSchema || previous.outputSchema || {},
|
|
524
|
+
architecturalInvariants: normalizeList(options.answers?.architecturalInvariants || previous.architecturalInvariants || ""),
|
|
525
|
+
pipeline: normalizeList(options.answers?.pipeline || previous.pipeline || ""),
|
|
526
|
+
templates: normalizeList(options.answers?.templates || previous.templates || ""),
|
|
527
|
+
versionControl: options.answers?.versionControl || previous.versionControl || {
|
|
528
|
+
remote: false,
|
|
529
|
+
provider: "",
|
|
530
|
+
developmentBranch: context.branches.development || "develop",
|
|
531
|
+
releaseBranch: context.branches.publish || "master",
|
|
532
|
+
},
|
|
533
|
+
deployment: options.answers?.deployment || previous.deployment || {
|
|
534
|
+
mode: "",
|
|
535
|
+
target: "",
|
|
536
|
+
smokeCommand: "",
|
|
537
|
+
},
|
|
538
|
+
availableArtifacts: Array.isArray(previousDiscovery.availableArtifacts) ? previousDiscovery.availableArtifacts : [],
|
|
539
|
+
};
|
|
518
540
|
|
|
519
541
|
const answers = { ...defaults };
|
|
520
542
|
|
|
@@ -661,6 +683,17 @@ function buildDirectIntakeTemplate(profile) {
|
|
|
661
683
|
architecturalInvariants: normalizeList(profile.discovery?.architecturalInvariants || []),
|
|
662
684
|
pipeline: normalizeList(profile.discovery?.pipeline || []),
|
|
663
685
|
templates: normalizeList(profile.discovery?.templates || []),
|
|
686
|
+
versionControl: profile.discovery?.versionControl || {
|
|
687
|
+
remote: false,
|
|
688
|
+
provider: "",
|
|
689
|
+
developmentBranch: "",
|
|
690
|
+
releaseBranch: "",
|
|
691
|
+
},
|
|
692
|
+
deployment: profile.discovery?.deployment || {
|
|
693
|
+
mode: "",
|
|
694
|
+
target: "",
|
|
695
|
+
smokeCommand: "",
|
|
696
|
+
},
|
|
664
697
|
};
|
|
665
698
|
}
|
|
666
699
|
|
|
@@ -715,6 +748,8 @@ function ensureDirectBootstrapArtifacts(context, profile) {
|
|
|
715
748
|
inputSchema: intake.inputSchema || profile.discovery?.inputSchema || {},
|
|
716
749
|
outputSchema: intake.outputSchema || profile.discovery?.outputSchema || {},
|
|
717
750
|
decisionOwnership: intake.decisionOwnership || profile.discovery?.decisionOwnership || profile.decisionOwnership || null,
|
|
751
|
+
versionControl: intake.versionControl || profile.discovery?.versionControl || null,
|
|
752
|
+
deployment: intake.deployment || profile.discovery?.deployment || null,
|
|
718
753
|
},
|
|
719
754
|
};
|
|
720
755
|
const qualityReport = buildQualityReport(context, mergedProfile, specText);
|
|
@@ -816,23 +851,25 @@ function buildOperatingContract(control, profile, qualityReport, context) {
|
|
|
816
851
|
sourceArtifacts: discovery.availableArtifacts || [],
|
|
817
852
|
repoScan: profile.inference || {},
|
|
818
853
|
},
|
|
819
|
-
system: {
|
|
820
|
-
sourceOfTruth: discovery.sourceOfTruth || "",
|
|
821
|
-
externalServices: discovery.externalServices || [],
|
|
822
|
-
inputSchema: discovery.inputSchema || {},
|
|
823
|
-
outputSchema: discovery.outputSchema || {},
|
|
824
|
-
behaviorRules: discovery.behaviorRules || [],
|
|
825
|
-
architecturalInvariants: discovery.architecturalInvariants || [],
|
|
826
|
-
},
|
|
827
|
-
execution: {
|
|
828
|
-
pipeline: discovery.pipeline || [],
|
|
829
|
-
templates: discovery.templates || [],
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
854
|
+
system: {
|
|
855
|
+
sourceOfTruth: discovery.sourceOfTruth || "",
|
|
856
|
+
externalServices: discovery.externalServices || [],
|
|
857
|
+
inputSchema: discovery.inputSchema || {},
|
|
858
|
+
outputSchema: discovery.outputSchema || {},
|
|
859
|
+
behaviorRules: discovery.behaviorRules || [],
|
|
860
|
+
architecturalInvariants: discovery.architecturalInvariants || [],
|
|
861
|
+
},
|
|
862
|
+
execution: {
|
|
863
|
+
pipeline: discovery.pipeline || [],
|
|
864
|
+
templates: discovery.templates || [],
|
|
865
|
+
deployment: discovery.deployment || null,
|
|
866
|
+
phaseModel: "opera-v3",
|
|
867
|
+
taskSeeds: buildSeedTasks(control, profile).map((task) => task.id),
|
|
868
|
+
},
|
|
869
|
+
governance: {
|
|
870
|
+
policyFile: policyRelativePath(context),
|
|
871
|
+
versionControl: discovery.versionControl || null,
|
|
872
|
+
riskProfile: "standard",
|
|
836
873
|
approvalRules: [
|
|
837
874
|
"destructive_changes_require_approval",
|
|
838
875
|
"production_deploy_requires_approval",
|
|
@@ -1216,11 +1253,13 @@ function resumeBootstrap(root, control) {
|
|
|
1216
1253
|
externalServices: normalizeList(intake.externalServices || bootstrap.discovery?.externalServices || []),
|
|
1217
1254
|
behaviorRules: normalizeList(intake.behaviorRules || bootstrap.discovery?.behaviorRules || []),
|
|
1218
1255
|
architecturalInvariants: normalizeList(intake.architecturalInvariants || bootstrap.discovery?.architecturalInvariants || []),
|
|
1219
|
-
pipeline: normalizeList(intake.pipeline || bootstrap.discovery?.pipeline || []),
|
|
1220
|
-
templates: normalizeList(intake.templates || bootstrap.discovery?.templates || []),
|
|
1221
|
-
inputSchema: intake.inputSchema || bootstrap.discovery?.inputSchema || {},
|
|
1222
|
-
outputSchema: intake.outputSchema || bootstrap.discovery?.outputSchema || {},
|
|
1223
|
-
|
|
1256
|
+
pipeline: normalizeList(intake.pipeline || bootstrap.discovery?.pipeline || []),
|
|
1257
|
+
templates: normalizeList(intake.templates || bootstrap.discovery?.templates || []),
|
|
1258
|
+
inputSchema: intake.inputSchema || bootstrap.discovery?.inputSchema || {},
|
|
1259
|
+
outputSchema: intake.outputSchema || bootstrap.discovery?.outputSchema || {},
|
|
1260
|
+
versionControl: intake.versionControl || bootstrap.discovery?.versionControl || null,
|
|
1261
|
+
deployment: intake.deployment || bootstrap.discovery?.deployment || null,
|
|
1262
|
+
};
|
|
1224
1263
|
const missingFields = directMissingFields(discovery);
|
|
1225
1264
|
const profile = {
|
|
1226
1265
|
...bootstrap,
|
|
@@ -1235,12 +1274,13 @@ function resumeBootstrap(root, control) {
|
|
|
1235
1274
|
discovery,
|
|
1236
1275
|
inference: scanProject(context),
|
|
1237
1276
|
};
|
|
1238
|
-
const qualityReport = buildQualityReport(context, profile, specDossier);
|
|
1239
|
-
profile.status = qualityReport.status === "ready" ? "completed" : qualityReport.status;
|
|
1240
|
-
profile.completedAt = qualityReport.status === "ready" ? nowIso() : null;
|
|
1241
|
-
profile.
|
|
1242
|
-
|
|
1243
|
-
}
|
|
1277
|
+
const qualityReport = buildQualityReport(context, profile, specDossier);
|
|
1278
|
+
profile.status = qualityReport.status === "ready" ? "completed" : qualityReport.status;
|
|
1279
|
+
profile.completedAt = qualityReport.status === "ready" ? nowIso() : null;
|
|
1280
|
+
profile.missingFields = qualityReport.missingFields || [];
|
|
1281
|
+
profile.qualityReport = qualityReport;
|
|
1282
|
+
return { resumed: true, profile };
|
|
1283
|
+
}
|
|
1244
1284
|
|
|
1245
1285
|
function detectLegacyBootstrap(root, control) {
|
|
1246
1286
|
const context = config.ensureContext(root);
|