@kitsy/coop-core 2.1.1 → 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/dist/index.cjs +180 -5
- package/dist/index.d.cts +26 -2
- package/dist/index.d.ts +26 -2
- package/dist/index.js +179 -5
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -85,6 +85,7 @@ __export(index_exports, {
|
|
|
85
85
|
detect_cycle: () => detect_cycle,
|
|
86
86
|
detect_delivery_risks: () => detect_delivery_risks,
|
|
87
87
|
determinism_weight: () => determinism_weight,
|
|
88
|
+
effective_priority: () => effective_priority,
|
|
88
89
|
effective_weekly_hours: () => effective_weekly_hours,
|
|
89
90
|
effort_or_default: () => effort_or_default,
|
|
90
91
|
ensureCoopLayout: () => ensureCoopLayout,
|
|
@@ -2172,23 +2173,30 @@ var TASK_FIELD_ORDER = [
|
|
|
2172
2173
|
"aliases",
|
|
2173
2174
|
"priority",
|
|
2174
2175
|
"track",
|
|
2176
|
+
"delivery_tracks",
|
|
2177
|
+
"priority_context",
|
|
2175
2178
|
"assignee",
|
|
2176
2179
|
"depends_on",
|
|
2177
2180
|
"tags",
|
|
2178
2181
|
"delivery",
|
|
2182
|
+
"fix_versions",
|
|
2183
|
+
"released_in",
|
|
2179
2184
|
"acceptance",
|
|
2180
2185
|
"tests_required",
|
|
2181
2186
|
"origin",
|
|
2182
2187
|
"complexity",
|
|
2183
2188
|
"determinism",
|
|
2189
|
+
"story_points",
|
|
2184
2190
|
"estimate",
|
|
2185
2191
|
"resources",
|
|
2192
|
+
"time",
|
|
2186
2193
|
"execution",
|
|
2187
2194
|
"artifacts",
|
|
2188
2195
|
"governance",
|
|
2189
2196
|
"risk",
|
|
2190
2197
|
"metrics",
|
|
2191
|
-
"enterprise"
|
|
2198
|
+
"enterprise",
|
|
2199
|
+
"comments"
|
|
2192
2200
|
];
|
|
2193
2201
|
var ORDERED_TASK_FIELDS = new Set(TASK_FIELD_ORDER);
|
|
2194
2202
|
function buildOrderedFrontmatter(task, raw) {
|
|
@@ -3393,6 +3401,13 @@ function detect_delivery_risks(delivery, graph, velocity, options = {}) {
|
|
|
3393
3401
|
}
|
|
3394
3402
|
|
|
3395
3403
|
// src/planning/scorer.ts
|
|
3404
|
+
function effective_priority(task, track) {
|
|
3405
|
+
const candidate = track?.trim();
|
|
3406
|
+
if (candidate && task.priority_context?.[candidate]) {
|
|
3407
|
+
return task.priority_context[candidate];
|
|
3408
|
+
}
|
|
3409
|
+
return task.priority ?? "p2";
|
|
3410
|
+
}
|
|
3396
3411
|
var DEFAULT_SCORE_WEIGHTS = {
|
|
3397
3412
|
priority: {
|
|
3398
3413
|
p0: 100,
|
|
@@ -3545,9 +3560,9 @@ function unresolved_dependencies(task, graph) {
|
|
|
3545
3560
|
return !dep || dep.status !== "done" && dep.status !== "canceled";
|
|
3546
3561
|
});
|
|
3547
3562
|
}
|
|
3548
|
-
function priority_weight(task, config) {
|
|
3563
|
+
function priority_weight(task, config, track) {
|
|
3549
3564
|
const weights = configured_weights(config);
|
|
3550
|
-
const priority = task
|
|
3565
|
+
const priority = effective_priority(task, track);
|
|
3551
3566
|
return weights.priority[priority];
|
|
3552
3567
|
}
|
|
3553
3568
|
function urgency_weight(task, deliveries, today, config) {
|
|
@@ -3645,7 +3660,7 @@ function compute_score(task, graph, context = {}) {
|
|
|
3645
3660
|
const deliveries = context.deliveries ?? graph.deliveries;
|
|
3646
3661
|
const today = context.today ?? /* @__PURE__ */ new Date();
|
|
3647
3662
|
const config = context.config;
|
|
3648
|
-
return priority_weight(task, config) + urgency_weight(task, deliveries, today, config) + dependency_unlock_weight(task.id, graph, config) + critical_path_weight(task.id, context.cpm, config) + determinism_weight(task, config) + executor_fit_weight(task, context.target_executor, config) + type_weight(task, config) + complexity_penalty(task, config) + risk_penalty(task, config);
|
|
3663
|
+
return priority_weight(task, config, context.track) + urgency_weight(task, deliveries, today, config) + dependency_unlock_weight(task.id, graph, config) + critical_path_weight(task.id, context.cpm, config) + determinism_weight(task, config) + executor_fit_weight(task, context.target_executor, config) + type_weight(task, config) + complexity_penalty(task, config) + risk_penalty(task, config);
|
|
3649
3664
|
}
|
|
3650
3665
|
|
|
3651
3666
|
// src/planning/scheduler.ts
|
|
@@ -3686,6 +3701,13 @@ function clone_ledger2(ledger) {
|
|
|
3686
3701
|
function normalize_track3(track) {
|
|
3687
3702
|
return (track ?? "unassigned").trim().toLowerCase();
|
|
3688
3703
|
}
|
|
3704
|
+
function task_matches_track(task, track) {
|
|
3705
|
+
const normalized = normalize_track3(track);
|
|
3706
|
+
if (normalize_track3(task.track) === normalized) {
|
|
3707
|
+
return true;
|
|
3708
|
+
}
|
|
3709
|
+
return (task.delivery_tracks ?? []).some((candidate) => normalize_track3(candidate) === normalized);
|
|
3710
|
+
}
|
|
3689
3711
|
function find_track_slots2(ledger, track) {
|
|
3690
3712
|
const normalized = normalize_track3(track);
|
|
3691
3713
|
return ledger.slots.get(normalized) ?? ledger.slots.get("unassigned") ?? null;
|
|
@@ -3753,7 +3775,7 @@ function schedule_next(graph, options = {}) {
|
|
|
3753
3775
|
);
|
|
3754
3776
|
let filtered = ready_tasks;
|
|
3755
3777
|
if (options.track) {
|
|
3756
|
-
filtered = filtered.filter((task) => (task
|
|
3778
|
+
filtered = filtered.filter((task) => task_matches_track(task, options.track));
|
|
3757
3779
|
}
|
|
3758
3780
|
const deliveryFilter = options.delivery;
|
|
3759
3781
|
if (deliveryFilter) {
|
|
@@ -3776,6 +3798,7 @@ function schedule_next(graph, options = {}) {
|
|
|
3776
3798
|
cpm,
|
|
3777
3799
|
today: options.today ?? /* @__PURE__ */ new Date(),
|
|
3778
3800
|
target_executor: options.executor,
|
|
3801
|
+
track: options.track,
|
|
3779
3802
|
config: options.config
|
|
3780
3803
|
}),
|
|
3781
3804
|
readiness: compute_readiness(task, graph),
|
|
@@ -4656,6 +4679,18 @@ function validateSemantic(task, context = {}) {
|
|
|
4656
4679
|
}
|
|
4657
4680
|
}
|
|
4658
4681
|
}
|
|
4682
|
+
if (task.time?.planned_hours !== void 0 && task.time.logs) {
|
|
4683
|
+
const plannedTotal = task.time.logs.filter((entry) => entry.kind === "planned").reduce((sum, entry) => sum + entry.hours, 0);
|
|
4684
|
+
if (plannedTotal > 0 && plannedTotal !== task.time.planned_hours) {
|
|
4685
|
+
issues.push(
|
|
4686
|
+
warning2(
|
|
4687
|
+
"time.planned_hours",
|
|
4688
|
+
"sem.time_planned_mismatch",
|
|
4689
|
+
`Task planned_hours (${task.time.planned_hours}) does not match total planned logs (${plannedTotal}).`
|
|
4690
|
+
)
|
|
4691
|
+
);
|
|
4692
|
+
}
|
|
4693
|
+
}
|
|
4659
4694
|
const taskStatuses = asMap(context.taskStatuses);
|
|
4660
4695
|
if (task.status === "done" && (task.depends_on?.length ?? 0) > 0) {
|
|
4661
4696
|
const unresolved = (task.depends_on ?? []).filter((depId) => taskStatuses.get(depId) !== "done");
|
|
@@ -4744,6 +4779,45 @@ function validateStringArrayField(errors, field, value, options = {}) {
|
|
|
4744
4779
|
}
|
|
4745
4780
|
}
|
|
4746
4781
|
}
|
|
4782
|
+
function isPriority(value) {
|
|
4783
|
+
return typeof value === "string" && Object.values(TaskPriority).includes(value);
|
|
4784
|
+
}
|
|
4785
|
+
function validatePriorityContext(errors, value) {
|
|
4786
|
+
if (value === void 0) {
|
|
4787
|
+
return;
|
|
4788
|
+
}
|
|
4789
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
4790
|
+
errors.push(
|
|
4791
|
+
error4(
|
|
4792
|
+
"priority_context",
|
|
4793
|
+
"struct.priority_context_object",
|
|
4794
|
+
"Field 'priority_context' must be an object keyed by track id."
|
|
4795
|
+
)
|
|
4796
|
+
);
|
|
4797
|
+
return;
|
|
4798
|
+
}
|
|
4799
|
+
for (const [track, priority] of Object.entries(value)) {
|
|
4800
|
+
if (!track.trim()) {
|
|
4801
|
+
errors.push(
|
|
4802
|
+
error4(
|
|
4803
|
+
"priority_context",
|
|
4804
|
+
"struct.priority_context_key",
|
|
4805
|
+
"Field 'priority_context' keys must be non-empty track ids."
|
|
4806
|
+
)
|
|
4807
|
+
);
|
|
4808
|
+
continue;
|
|
4809
|
+
}
|
|
4810
|
+
if (!isPriority(priority)) {
|
|
4811
|
+
errors.push(
|
|
4812
|
+
error4(
|
|
4813
|
+
"priority_context",
|
|
4814
|
+
"struct.priority_context_priority",
|
|
4815
|
+
`Priority override for track '${track}' must be one of ${Object.values(TaskPriority).join(", ")}.`
|
|
4816
|
+
)
|
|
4817
|
+
);
|
|
4818
|
+
}
|
|
4819
|
+
}
|
|
4820
|
+
}
|
|
4747
4821
|
function validateStructural(task, context = {}) {
|
|
4748
4822
|
const errors = [];
|
|
4749
4823
|
const required = ["id", "title", "type", "status", "created", "updated"];
|
|
@@ -4810,6 +4884,106 @@ function validateStructural(task, context = {}) {
|
|
|
4810
4884
|
}
|
|
4811
4885
|
validateStringArrayField(errors, "acceptance", task.acceptance);
|
|
4812
4886
|
validateStringArrayField(errors, "tests_required", task.tests_required);
|
|
4887
|
+
validateStringArrayField(errors, "delivery_tracks", task.delivery_tracks);
|
|
4888
|
+
validateStringArrayField(errors, "fix_versions", task.fix_versions);
|
|
4889
|
+
validateStringArrayField(errors, "released_in", task.released_in);
|
|
4890
|
+
validatePriorityContext(errors, task.priority_context);
|
|
4891
|
+
if (task.story_points !== void 0 && (!Number.isFinite(task.story_points) || task.story_points < 0)) {
|
|
4892
|
+
errors.push(
|
|
4893
|
+
error4(
|
|
4894
|
+
"story_points",
|
|
4895
|
+
"struct.story_points_non_negative",
|
|
4896
|
+
"Field 'story_points' must be a non-negative number."
|
|
4897
|
+
)
|
|
4898
|
+
);
|
|
4899
|
+
}
|
|
4900
|
+
if (task.time !== void 0) {
|
|
4901
|
+
if (!task.time || typeof task.time !== "object" || Array.isArray(task.time)) {
|
|
4902
|
+
errors.push(error4("time", "struct.time_object", "Field 'time' must be an object."));
|
|
4903
|
+
} else {
|
|
4904
|
+
if (task.time.planned_hours !== void 0 && (!Number.isFinite(task.time.planned_hours) || task.time.planned_hours < 0)) {
|
|
4905
|
+
errors.push(
|
|
4906
|
+
error4(
|
|
4907
|
+
"time.planned_hours",
|
|
4908
|
+
"struct.time_planned_hours_non_negative",
|
|
4909
|
+
"Field 'time.planned_hours' must be a non-negative number."
|
|
4910
|
+
)
|
|
4911
|
+
);
|
|
4912
|
+
}
|
|
4913
|
+
if (task.time.logs !== void 0) {
|
|
4914
|
+
if (!Array.isArray(task.time.logs)) {
|
|
4915
|
+
errors.push(error4("time.logs", "struct.time_logs_array", "Field 'time.logs' must be an array."));
|
|
4916
|
+
} else {
|
|
4917
|
+
for (const [index, entry] of task.time.logs.entries()) {
|
|
4918
|
+
if (!entry || typeof entry !== "object" || Array.isArray(entry)) {
|
|
4919
|
+
errors.push(
|
|
4920
|
+
error4("time.logs", "struct.time_logs_object", `Entry ${index} in 'time.logs' must be an object.`)
|
|
4921
|
+
);
|
|
4922
|
+
continue;
|
|
4923
|
+
}
|
|
4924
|
+
const record = entry;
|
|
4925
|
+
if (typeof record.at !== "string" || record.at.trim().length === 0) {
|
|
4926
|
+
errors.push(error4("time.logs", "struct.time_logs_at", `Entry ${index} in 'time.logs' requires 'at'.`));
|
|
4927
|
+
}
|
|
4928
|
+
if (typeof record.actor !== "string" || record.actor.trim().length === 0) {
|
|
4929
|
+
errors.push(
|
|
4930
|
+
error4("time.logs", "struct.time_logs_actor", `Entry ${index} in 'time.logs' requires 'actor'.`)
|
|
4931
|
+
);
|
|
4932
|
+
}
|
|
4933
|
+
if (record.kind !== "planned" && record.kind !== "worked") {
|
|
4934
|
+
errors.push(
|
|
4935
|
+
error4(
|
|
4936
|
+
"time.logs",
|
|
4937
|
+
"struct.time_logs_kind",
|
|
4938
|
+
`Entry ${index} in 'time.logs' must use kind planned|worked.`
|
|
4939
|
+
)
|
|
4940
|
+
);
|
|
4941
|
+
}
|
|
4942
|
+
if (typeof record.hours !== "number" || !Number.isFinite(record.hours) || record.hours < 0) {
|
|
4943
|
+
errors.push(
|
|
4944
|
+
error4(
|
|
4945
|
+
"time.logs",
|
|
4946
|
+
"struct.time_logs_hours",
|
|
4947
|
+
`Entry ${index} in 'time.logs' requires non-negative numeric 'hours'.`
|
|
4948
|
+
)
|
|
4949
|
+
);
|
|
4950
|
+
}
|
|
4951
|
+
if (record.note !== void 0 && typeof record.note !== "string") {
|
|
4952
|
+
errors.push(
|
|
4953
|
+
error4(
|
|
4954
|
+
"time.logs",
|
|
4955
|
+
"struct.time_logs_note",
|
|
4956
|
+
`Entry ${index} in 'time.logs' must use a string note when present.`
|
|
4957
|
+
)
|
|
4958
|
+
);
|
|
4959
|
+
}
|
|
4960
|
+
}
|
|
4961
|
+
}
|
|
4962
|
+
}
|
|
4963
|
+
}
|
|
4964
|
+
}
|
|
4965
|
+
if (task.comments !== void 0) {
|
|
4966
|
+
if (!Array.isArray(task.comments)) {
|
|
4967
|
+
errors.push(error4("comments", "struct.comments_array", "Field 'comments' must be an array."));
|
|
4968
|
+
} else {
|
|
4969
|
+
for (const [index, entry] of task.comments.entries()) {
|
|
4970
|
+
if (!entry || typeof entry !== "object" || Array.isArray(entry)) {
|
|
4971
|
+
errors.push(error4("comments", "struct.comments_object", `Entry ${index} in 'comments' must be an object.`));
|
|
4972
|
+
continue;
|
|
4973
|
+
}
|
|
4974
|
+
const record = entry;
|
|
4975
|
+
if (typeof record.at !== "string" || record.at.trim().length === 0) {
|
|
4976
|
+
errors.push(error4("comments", "struct.comments_at", `Entry ${index} in 'comments' requires 'at'.`));
|
|
4977
|
+
}
|
|
4978
|
+
if (typeof record.author !== "string" || record.author.trim().length === 0) {
|
|
4979
|
+
errors.push(error4("comments", "struct.comments_author", `Entry ${index} in 'comments' requires 'author'.`));
|
|
4980
|
+
}
|
|
4981
|
+
if (typeof record.body !== "string" || record.body.trim().length === 0) {
|
|
4982
|
+
errors.push(error4("comments", "struct.comments_body", `Entry ${index} in 'comments' requires 'body'.`));
|
|
4983
|
+
}
|
|
4984
|
+
}
|
|
4985
|
+
}
|
|
4986
|
+
}
|
|
4813
4987
|
if (task.origin !== void 0) {
|
|
4814
4988
|
if (!task.origin || typeof task.origin !== "object" || Array.isArray(task.origin)) {
|
|
4815
4989
|
errors.push(error4("origin", "struct.origin_object", "Field 'origin' must be an object."));
|
|
@@ -5683,6 +5857,7 @@ function validateRepo(rootDir) {
|
|
|
5683
5857
|
detect_cycle,
|
|
5684
5858
|
detect_delivery_risks,
|
|
5685
5859
|
determinism_weight,
|
|
5860
|
+
effective_priority,
|
|
5686
5861
|
effective_weekly_hours,
|
|
5687
5862
|
effort_or_default,
|
|
5688
5863
|
ensureCoopLayout,
|
package/dist/index.d.cts
CHANGED
|
@@ -285,14 +285,30 @@ interface TaskCore {
|
|
|
285
285
|
created: string;
|
|
286
286
|
updated: string;
|
|
287
287
|
}
|
|
288
|
+
interface TaskTimeLog {
|
|
289
|
+
at: string;
|
|
290
|
+
actor: string;
|
|
291
|
+
kind: "planned" | "worked";
|
|
292
|
+
hours: number;
|
|
293
|
+
note?: string;
|
|
294
|
+
}
|
|
295
|
+
interface TaskComment {
|
|
296
|
+
at: string;
|
|
297
|
+
author: string;
|
|
298
|
+
body: string;
|
|
299
|
+
}
|
|
288
300
|
interface TaskPlanning {
|
|
289
301
|
aliases?: string[];
|
|
290
302
|
priority?: TaskPriority;
|
|
291
303
|
track?: string;
|
|
304
|
+
delivery_tracks?: string[];
|
|
305
|
+
priority_context?: Record<string, TaskPriority>;
|
|
292
306
|
assignee?: string | null;
|
|
293
307
|
depends_on?: string[];
|
|
294
308
|
tags?: string[];
|
|
295
309
|
delivery?: string | null;
|
|
310
|
+
fix_versions?: string[];
|
|
311
|
+
released_in?: string[];
|
|
296
312
|
acceptance?: string[];
|
|
297
313
|
tests_required?: string[];
|
|
298
314
|
origin?: {
|
|
@@ -317,8 +333,13 @@ interface TaskResources {
|
|
|
317
333
|
interface TaskEstimation {
|
|
318
334
|
complexity?: TaskComplexity;
|
|
319
335
|
determinism?: TaskDeterminism;
|
|
336
|
+
story_points?: number;
|
|
320
337
|
estimate?: TaskEstimate;
|
|
321
338
|
resources?: TaskResources;
|
|
339
|
+
time?: {
|
|
340
|
+
planned_hours?: number;
|
|
341
|
+
logs?: TaskTimeLog[];
|
|
342
|
+
};
|
|
322
343
|
}
|
|
323
344
|
interface RunbookStep {
|
|
324
345
|
step: string;
|
|
@@ -380,6 +401,7 @@ interface TaskGovernance {
|
|
|
380
401
|
target_cycle_time_days?: number;
|
|
381
402
|
};
|
|
382
403
|
enterprise?: Record<string, unknown>;
|
|
404
|
+
comments?: TaskComment[];
|
|
383
405
|
}
|
|
384
406
|
type Task = TaskCore & TaskPlanning & TaskEstimation & TaskExecution & TaskGovernance;
|
|
385
407
|
interface TaskComputed {
|
|
@@ -1218,15 +1240,17 @@ interface ScoreContext {
|
|
|
1218
1240
|
cpm?: CriticalPathResult;
|
|
1219
1241
|
today?: string | Date;
|
|
1220
1242
|
target_executor?: ExecutorType;
|
|
1243
|
+
track?: string;
|
|
1221
1244
|
config?: CoopConfig;
|
|
1222
1245
|
}
|
|
1246
|
+
declare function effective_priority(task: Task, track?: string): TaskPriority;
|
|
1223
1247
|
/**
|
|
1224
1248
|
* Default readiness ranking weights used by `compute_score`.
|
|
1225
1249
|
* [SPEC: Scheduler v2.0 §4.6]
|
|
1226
1250
|
*/
|
|
1227
1251
|
declare const DEFAULT_SCORE_WEIGHTS: ScoreWeights;
|
|
1228
1252
|
/** [SPEC: Scheduler v2.0 §4.6] */
|
|
1229
|
-
declare function priority_weight(task: Task, config?: CoopConfig): number;
|
|
1253
|
+
declare function priority_weight(task: Task, config?: CoopConfig, track?: string): number;
|
|
1230
1254
|
/** [SPEC: Scheduler v2.0 §4.6] */
|
|
1231
1255
|
declare function urgency_weight(task: Task, deliveries: Map<string, Delivery> | Delivery[], today: string | Date, config?: CoopConfig): number;
|
|
1232
1256
|
/** [SPEC: Scheduler v2.0 §4.6] */
|
|
@@ -1501,4 +1525,4 @@ declare function validateRepo(rootDir: string): {
|
|
|
1501
1525
|
warnings: string[];
|
|
1502
1526
|
};
|
|
1503
1527
|
|
|
1504
|
-
export { type AIAgent, type AIResource, type AgentSpec, type AllocationResult, ArtifactType, type AuthConfig, type AuthPolicy, type AutoTransitionResult, type AvailabilityWindow, type BacklogItem, type BacklogItemData, COOP_EVENT_TYPES, CURRENT_SCHEMA_VERSION, type CapacityLedger, type ComparisonResult, type ComparisonRow, type ComputeNode, type ComputeResource, type CoopConfig, type CoopEvent, CoopEventEmitter, type CoopEventType, type CoopProjectRef, type CoopWorkspaceConfig, type CreateItemParams, type CriticalPathResult, type CriticalPathTaskMetrics, DEFAULT_SCORE_WEIGHTS, type Delivery, type DeliveryAtRisk, type DeliveryBudget, type DeliveryCommitted, type DeliveryGovernance, type DeliveryRisk, type DeliveryRiskType, type DeliveryScope, DeliveryStatus, type DetectedDeliveryRisk, type EffectiveCapacity, type EventByType, type ExecutionConstraints, type ExecutionPermissions, ExecutorType, type ExternalDependencyRef, type ExternalDependencyResolution, type ExternalDependencyResolutionStatus, type ExternalDependencyResolverOptions, type ExternalRepoConfig, type FeasibilityResult, type FeasibilityRisk, type FeasibilityStatus, type FeasibilitySummary, type FilterSpec, type FrontmatterParseResult, type GraphCycleDetected, type GraphValidationContext, type GraphValidationResult, type HookRunResult, type HumanMember, type HumanResource, ITEM_STATUSES, ITEM_TYPES, type Idea, IdeaStatus, IndexManager, type IndexStatus, type ItemLinks, type ItemStatus, type ItemType, MIGRATIONS, type MigrateRepositoryOptions, type MigrationContext, type MigrationDefinition, type MigrationReport, type MonteCarloHistogramBucket, type MonteCarloOptions, type MonteCarloResult, type MonteCarloWorkerPayload, type ParsedDelivery, type ParsedIdea, type ParsedTask, type Permission, type PermissionContext, type PluginAction, type PluginActionConsole, type PluginActionGitHubPr, type PluginActionHandler, type PluginActionHandlerResult, type PluginActionWebhook, type PluginManifest, type PluginRunOptions, type PluginRunRecord, type PluginTrigger, type PolicyAction, type ReadinessComputation, type ReadinessPartitions, type ReadinessState, type ReadinessTransitionEvent, type ReadinessWarning, type ReferentialValidationContext, type RepoConfig, type RepoState, type ResourceProfile, RiskLevel, type Role, type Run, type RunCompleted, type RunFailed, type RunResourcesConsumed, type RunStarted, RunStatus, type RunStepResult, RunStepStatus, RunbookAction, type RunbookStep, type ScheduleOptions, type ScoreContext, type ScoredTask, type SemanticValidationContext, type SimulationResult, type StructuralValidationContext, type Task, type TaskAssigned, TaskComplexity, type TaskComputed, type TaskCore, type TaskCreated, TaskDeterminism, type TaskEstimate, type TaskEstimation, type TaskExecution, type TaskGovernance, type TaskGraph, type TaskPlanning, TaskPriority, type TaskResources, type TaskScheduleEntry, TaskStatus, type TaskTransitioned, type TaskTransitionedEvent, TaskType, type Track, type TrackUtilization, type TrackWip, type TransitionContext, type TransitionResult, type TransitionValidationContext, type UpdateItemParams, VALID_TASK_TRANSITIONS, VALID_TRANSITIONS, type ValidationContext, type ValidationError, type ValidationLevel, type ValidationResult, type VelocityMetrics, type VelocityPoint, type VelocityTrend, type WhatIfBaseline, type WhatIfModification, type WriteTaskOptions, allocate, allocate_ai, allocate_ai_tokens, analyze_feasibility, analyze_what_if, build_capacity_ledger, build_graph, check_blocked, check_permission, check_unblocked, check_wip, completeItem, complexity_penalty, compute_all_readiness, compute_critical_path, compute_readiness, compute_readiness_with_corrections, compute_score, compute_velocity, coop_project_config_path, coop_project_root, coop_projects_dir, coop_workspace_config_path, coop_workspace_dir, createItem, create_seeded_rng, critical_path_weight, deleteItem, dependency_unlock_weight, detect_cycle, detect_delivery_risks, determinism_weight, effective_weekly_hours, effort_or_default, ensureCoopLayout, ensure_workspace_layout, executor_fit_weight, external_dependencies_for_task, extract_subgraph, findRepoRoot, find_external_dependencies, getItemById, get_remaining_tokens, get_user_role, has_legacy_project_layout, has_v2_projects_layout, is_external_dependency, is_project_initialized, list_projects, loadState, load_auth_config, load_completed_runs, load_graph, load_plugins, migrate_repository, migrate_task, monte_carlo_forecast, parseDeliveryContent, parseDeliveryFile, parseFrontmatterContent, parseFrontmatterFile, parseIdeaContent, parseIdeaFile, parseTaskContent, parseTaskFile, parseYamlContent, parseYamlFile, parse_external_dependency, partition_by_readiness, pert_hours, pert_stddev, priority_weight, queryItems, read_project_config, read_schema_version, read_workspace_config, renderAgentPrompt, repo_default_project_id, repo_default_project_name, resolve_external_dependencies, resolve_project, risk_penalty, run_hook, run_monte_carlo_chunk, run_plugins_for_event, sample_pert_beta, sample_task_hours, schedule_next, simulate_schedule, stringifyFrontmatter, stringifyYamlContent, task_effort_hours, topological_sort, transition, transitive_dependencies, transitive_dependents, type_weight, updateItem, urgency_weight, validate, validateReferential, validateRepo, validateSemantic, validateStructural, validateTransition, validate_graph, validate_transition, writeTask, writeYamlFile, write_schema_version, write_workspace_config };
|
|
1528
|
+
export { type AIAgent, type AIResource, type AgentSpec, type AllocationResult, ArtifactType, type AuthConfig, type AuthPolicy, type AutoTransitionResult, type AvailabilityWindow, type BacklogItem, type BacklogItemData, COOP_EVENT_TYPES, CURRENT_SCHEMA_VERSION, type CapacityLedger, type ComparisonResult, type ComparisonRow, type ComputeNode, type ComputeResource, type CoopConfig, type CoopEvent, CoopEventEmitter, type CoopEventType, type CoopProjectRef, type CoopWorkspaceConfig, type CreateItemParams, type CriticalPathResult, type CriticalPathTaskMetrics, DEFAULT_SCORE_WEIGHTS, type Delivery, type DeliveryAtRisk, type DeliveryBudget, type DeliveryCommitted, type DeliveryGovernance, type DeliveryRisk, type DeliveryRiskType, type DeliveryScope, DeliveryStatus, type DetectedDeliveryRisk, type EffectiveCapacity, type EventByType, type ExecutionConstraints, type ExecutionPermissions, ExecutorType, type ExternalDependencyRef, type ExternalDependencyResolution, type ExternalDependencyResolutionStatus, type ExternalDependencyResolverOptions, type ExternalRepoConfig, type FeasibilityResult, type FeasibilityRisk, type FeasibilityStatus, type FeasibilitySummary, type FilterSpec, type FrontmatterParseResult, type GraphCycleDetected, type GraphValidationContext, type GraphValidationResult, type HookRunResult, type HumanMember, type HumanResource, ITEM_STATUSES, ITEM_TYPES, type Idea, IdeaStatus, IndexManager, type IndexStatus, type ItemLinks, type ItemStatus, type ItemType, MIGRATIONS, type MigrateRepositoryOptions, type MigrationContext, type MigrationDefinition, type MigrationReport, type MonteCarloHistogramBucket, type MonteCarloOptions, type MonteCarloResult, type MonteCarloWorkerPayload, type ParsedDelivery, type ParsedIdea, type ParsedTask, type Permission, type PermissionContext, type PluginAction, type PluginActionConsole, type PluginActionGitHubPr, type PluginActionHandler, type PluginActionHandlerResult, type PluginActionWebhook, type PluginManifest, type PluginRunOptions, type PluginRunRecord, type PluginTrigger, type PolicyAction, type ReadinessComputation, type ReadinessPartitions, type ReadinessState, type ReadinessTransitionEvent, type ReadinessWarning, type ReferentialValidationContext, type RepoConfig, type RepoState, type ResourceProfile, RiskLevel, type Role, type Run, type RunCompleted, type RunFailed, type RunResourcesConsumed, type RunStarted, RunStatus, type RunStepResult, RunStepStatus, RunbookAction, type RunbookStep, type ScheduleOptions, type ScoreContext, type ScoredTask, type SemanticValidationContext, type SimulationResult, type StructuralValidationContext, type Task, type TaskAssigned, type TaskComment, TaskComplexity, type TaskComputed, type TaskCore, type TaskCreated, TaskDeterminism, type TaskEstimate, type TaskEstimation, type TaskExecution, type TaskGovernance, type TaskGraph, type TaskPlanning, TaskPriority, type TaskResources, type TaskScheduleEntry, TaskStatus, type TaskTimeLog, type TaskTransitioned, type TaskTransitionedEvent, TaskType, type Track, type TrackUtilization, type TrackWip, type TransitionContext, type TransitionResult, type TransitionValidationContext, type UpdateItemParams, VALID_TASK_TRANSITIONS, VALID_TRANSITIONS, type ValidationContext, type ValidationError, type ValidationLevel, type ValidationResult, type VelocityMetrics, type VelocityPoint, type VelocityTrend, type WhatIfBaseline, type WhatIfModification, type WriteTaskOptions, allocate, allocate_ai, allocate_ai_tokens, analyze_feasibility, analyze_what_if, build_capacity_ledger, build_graph, check_blocked, check_permission, check_unblocked, check_wip, completeItem, complexity_penalty, compute_all_readiness, compute_critical_path, compute_readiness, compute_readiness_with_corrections, compute_score, compute_velocity, coop_project_config_path, coop_project_root, coop_projects_dir, coop_workspace_config_path, coop_workspace_dir, createItem, create_seeded_rng, critical_path_weight, deleteItem, dependency_unlock_weight, detect_cycle, detect_delivery_risks, determinism_weight, effective_priority, effective_weekly_hours, effort_or_default, ensureCoopLayout, ensure_workspace_layout, executor_fit_weight, external_dependencies_for_task, extract_subgraph, findRepoRoot, find_external_dependencies, getItemById, get_remaining_tokens, get_user_role, has_legacy_project_layout, has_v2_projects_layout, is_external_dependency, is_project_initialized, list_projects, loadState, load_auth_config, load_completed_runs, load_graph, load_plugins, migrate_repository, migrate_task, monte_carlo_forecast, parseDeliveryContent, parseDeliveryFile, parseFrontmatterContent, parseFrontmatterFile, parseIdeaContent, parseIdeaFile, parseTaskContent, parseTaskFile, parseYamlContent, parseYamlFile, parse_external_dependency, partition_by_readiness, pert_hours, pert_stddev, priority_weight, queryItems, read_project_config, read_schema_version, read_workspace_config, renderAgentPrompt, repo_default_project_id, repo_default_project_name, resolve_external_dependencies, resolve_project, risk_penalty, run_hook, run_monte_carlo_chunk, run_plugins_for_event, sample_pert_beta, sample_task_hours, schedule_next, simulate_schedule, stringifyFrontmatter, stringifyYamlContent, task_effort_hours, topological_sort, transition, transitive_dependencies, transitive_dependents, type_weight, updateItem, urgency_weight, validate, validateReferential, validateRepo, validateSemantic, validateStructural, validateTransition, validate_graph, validate_transition, writeTask, writeYamlFile, write_schema_version, write_workspace_config };
|
package/dist/index.d.ts
CHANGED
|
@@ -285,14 +285,30 @@ interface TaskCore {
|
|
|
285
285
|
created: string;
|
|
286
286
|
updated: string;
|
|
287
287
|
}
|
|
288
|
+
interface TaskTimeLog {
|
|
289
|
+
at: string;
|
|
290
|
+
actor: string;
|
|
291
|
+
kind: "planned" | "worked";
|
|
292
|
+
hours: number;
|
|
293
|
+
note?: string;
|
|
294
|
+
}
|
|
295
|
+
interface TaskComment {
|
|
296
|
+
at: string;
|
|
297
|
+
author: string;
|
|
298
|
+
body: string;
|
|
299
|
+
}
|
|
288
300
|
interface TaskPlanning {
|
|
289
301
|
aliases?: string[];
|
|
290
302
|
priority?: TaskPriority;
|
|
291
303
|
track?: string;
|
|
304
|
+
delivery_tracks?: string[];
|
|
305
|
+
priority_context?: Record<string, TaskPriority>;
|
|
292
306
|
assignee?: string | null;
|
|
293
307
|
depends_on?: string[];
|
|
294
308
|
tags?: string[];
|
|
295
309
|
delivery?: string | null;
|
|
310
|
+
fix_versions?: string[];
|
|
311
|
+
released_in?: string[];
|
|
296
312
|
acceptance?: string[];
|
|
297
313
|
tests_required?: string[];
|
|
298
314
|
origin?: {
|
|
@@ -317,8 +333,13 @@ interface TaskResources {
|
|
|
317
333
|
interface TaskEstimation {
|
|
318
334
|
complexity?: TaskComplexity;
|
|
319
335
|
determinism?: TaskDeterminism;
|
|
336
|
+
story_points?: number;
|
|
320
337
|
estimate?: TaskEstimate;
|
|
321
338
|
resources?: TaskResources;
|
|
339
|
+
time?: {
|
|
340
|
+
planned_hours?: number;
|
|
341
|
+
logs?: TaskTimeLog[];
|
|
342
|
+
};
|
|
322
343
|
}
|
|
323
344
|
interface RunbookStep {
|
|
324
345
|
step: string;
|
|
@@ -380,6 +401,7 @@ interface TaskGovernance {
|
|
|
380
401
|
target_cycle_time_days?: number;
|
|
381
402
|
};
|
|
382
403
|
enterprise?: Record<string, unknown>;
|
|
404
|
+
comments?: TaskComment[];
|
|
383
405
|
}
|
|
384
406
|
type Task = TaskCore & TaskPlanning & TaskEstimation & TaskExecution & TaskGovernance;
|
|
385
407
|
interface TaskComputed {
|
|
@@ -1218,15 +1240,17 @@ interface ScoreContext {
|
|
|
1218
1240
|
cpm?: CriticalPathResult;
|
|
1219
1241
|
today?: string | Date;
|
|
1220
1242
|
target_executor?: ExecutorType;
|
|
1243
|
+
track?: string;
|
|
1221
1244
|
config?: CoopConfig;
|
|
1222
1245
|
}
|
|
1246
|
+
declare function effective_priority(task: Task, track?: string): TaskPriority;
|
|
1223
1247
|
/**
|
|
1224
1248
|
* Default readiness ranking weights used by `compute_score`.
|
|
1225
1249
|
* [SPEC: Scheduler v2.0 §4.6]
|
|
1226
1250
|
*/
|
|
1227
1251
|
declare const DEFAULT_SCORE_WEIGHTS: ScoreWeights;
|
|
1228
1252
|
/** [SPEC: Scheduler v2.0 §4.6] */
|
|
1229
|
-
declare function priority_weight(task: Task, config?: CoopConfig): number;
|
|
1253
|
+
declare function priority_weight(task: Task, config?: CoopConfig, track?: string): number;
|
|
1230
1254
|
/** [SPEC: Scheduler v2.0 §4.6] */
|
|
1231
1255
|
declare function urgency_weight(task: Task, deliveries: Map<string, Delivery> | Delivery[], today: string | Date, config?: CoopConfig): number;
|
|
1232
1256
|
/** [SPEC: Scheduler v2.0 §4.6] */
|
|
@@ -1501,4 +1525,4 @@ declare function validateRepo(rootDir: string): {
|
|
|
1501
1525
|
warnings: string[];
|
|
1502
1526
|
};
|
|
1503
1527
|
|
|
1504
|
-
export { type AIAgent, type AIResource, type AgentSpec, type AllocationResult, ArtifactType, type AuthConfig, type AuthPolicy, type AutoTransitionResult, type AvailabilityWindow, type BacklogItem, type BacklogItemData, COOP_EVENT_TYPES, CURRENT_SCHEMA_VERSION, type CapacityLedger, type ComparisonResult, type ComparisonRow, type ComputeNode, type ComputeResource, type CoopConfig, type CoopEvent, CoopEventEmitter, type CoopEventType, type CoopProjectRef, type CoopWorkspaceConfig, type CreateItemParams, type CriticalPathResult, type CriticalPathTaskMetrics, DEFAULT_SCORE_WEIGHTS, type Delivery, type DeliveryAtRisk, type DeliveryBudget, type DeliveryCommitted, type DeliveryGovernance, type DeliveryRisk, type DeliveryRiskType, type DeliveryScope, DeliveryStatus, type DetectedDeliveryRisk, type EffectiveCapacity, type EventByType, type ExecutionConstraints, type ExecutionPermissions, ExecutorType, type ExternalDependencyRef, type ExternalDependencyResolution, type ExternalDependencyResolutionStatus, type ExternalDependencyResolverOptions, type ExternalRepoConfig, type FeasibilityResult, type FeasibilityRisk, type FeasibilityStatus, type FeasibilitySummary, type FilterSpec, type FrontmatterParseResult, type GraphCycleDetected, type GraphValidationContext, type GraphValidationResult, type HookRunResult, type HumanMember, type HumanResource, ITEM_STATUSES, ITEM_TYPES, type Idea, IdeaStatus, IndexManager, type IndexStatus, type ItemLinks, type ItemStatus, type ItemType, MIGRATIONS, type MigrateRepositoryOptions, type MigrationContext, type MigrationDefinition, type MigrationReport, type MonteCarloHistogramBucket, type MonteCarloOptions, type MonteCarloResult, type MonteCarloWorkerPayload, type ParsedDelivery, type ParsedIdea, type ParsedTask, type Permission, type PermissionContext, type PluginAction, type PluginActionConsole, type PluginActionGitHubPr, type PluginActionHandler, type PluginActionHandlerResult, type PluginActionWebhook, type PluginManifest, type PluginRunOptions, type PluginRunRecord, type PluginTrigger, type PolicyAction, type ReadinessComputation, type ReadinessPartitions, type ReadinessState, type ReadinessTransitionEvent, type ReadinessWarning, type ReferentialValidationContext, type RepoConfig, type RepoState, type ResourceProfile, RiskLevel, type Role, type Run, type RunCompleted, type RunFailed, type RunResourcesConsumed, type RunStarted, RunStatus, type RunStepResult, RunStepStatus, RunbookAction, type RunbookStep, type ScheduleOptions, type ScoreContext, type ScoredTask, type SemanticValidationContext, type SimulationResult, type StructuralValidationContext, type Task, type TaskAssigned, TaskComplexity, type TaskComputed, type TaskCore, type TaskCreated, TaskDeterminism, type TaskEstimate, type TaskEstimation, type TaskExecution, type TaskGovernance, type TaskGraph, type TaskPlanning, TaskPriority, type TaskResources, type TaskScheduleEntry, TaskStatus, type TaskTransitioned, type TaskTransitionedEvent, TaskType, type Track, type TrackUtilization, type TrackWip, type TransitionContext, type TransitionResult, type TransitionValidationContext, type UpdateItemParams, VALID_TASK_TRANSITIONS, VALID_TRANSITIONS, type ValidationContext, type ValidationError, type ValidationLevel, type ValidationResult, type VelocityMetrics, type VelocityPoint, type VelocityTrend, type WhatIfBaseline, type WhatIfModification, type WriteTaskOptions, allocate, allocate_ai, allocate_ai_tokens, analyze_feasibility, analyze_what_if, build_capacity_ledger, build_graph, check_blocked, check_permission, check_unblocked, check_wip, completeItem, complexity_penalty, compute_all_readiness, compute_critical_path, compute_readiness, compute_readiness_with_corrections, compute_score, compute_velocity, coop_project_config_path, coop_project_root, coop_projects_dir, coop_workspace_config_path, coop_workspace_dir, createItem, create_seeded_rng, critical_path_weight, deleteItem, dependency_unlock_weight, detect_cycle, detect_delivery_risks, determinism_weight, effective_weekly_hours, effort_or_default, ensureCoopLayout, ensure_workspace_layout, executor_fit_weight, external_dependencies_for_task, extract_subgraph, findRepoRoot, find_external_dependencies, getItemById, get_remaining_tokens, get_user_role, has_legacy_project_layout, has_v2_projects_layout, is_external_dependency, is_project_initialized, list_projects, loadState, load_auth_config, load_completed_runs, load_graph, load_plugins, migrate_repository, migrate_task, monte_carlo_forecast, parseDeliveryContent, parseDeliveryFile, parseFrontmatterContent, parseFrontmatterFile, parseIdeaContent, parseIdeaFile, parseTaskContent, parseTaskFile, parseYamlContent, parseYamlFile, parse_external_dependency, partition_by_readiness, pert_hours, pert_stddev, priority_weight, queryItems, read_project_config, read_schema_version, read_workspace_config, renderAgentPrompt, repo_default_project_id, repo_default_project_name, resolve_external_dependencies, resolve_project, risk_penalty, run_hook, run_monte_carlo_chunk, run_plugins_for_event, sample_pert_beta, sample_task_hours, schedule_next, simulate_schedule, stringifyFrontmatter, stringifyYamlContent, task_effort_hours, topological_sort, transition, transitive_dependencies, transitive_dependents, type_weight, updateItem, urgency_weight, validate, validateReferential, validateRepo, validateSemantic, validateStructural, validateTransition, validate_graph, validate_transition, writeTask, writeYamlFile, write_schema_version, write_workspace_config };
|
|
1528
|
+
export { type AIAgent, type AIResource, type AgentSpec, type AllocationResult, ArtifactType, type AuthConfig, type AuthPolicy, type AutoTransitionResult, type AvailabilityWindow, type BacklogItem, type BacklogItemData, COOP_EVENT_TYPES, CURRENT_SCHEMA_VERSION, type CapacityLedger, type ComparisonResult, type ComparisonRow, type ComputeNode, type ComputeResource, type CoopConfig, type CoopEvent, CoopEventEmitter, type CoopEventType, type CoopProjectRef, type CoopWorkspaceConfig, type CreateItemParams, type CriticalPathResult, type CriticalPathTaskMetrics, DEFAULT_SCORE_WEIGHTS, type Delivery, type DeliveryAtRisk, type DeliveryBudget, type DeliveryCommitted, type DeliveryGovernance, type DeliveryRisk, type DeliveryRiskType, type DeliveryScope, DeliveryStatus, type DetectedDeliveryRisk, type EffectiveCapacity, type EventByType, type ExecutionConstraints, type ExecutionPermissions, ExecutorType, type ExternalDependencyRef, type ExternalDependencyResolution, type ExternalDependencyResolutionStatus, type ExternalDependencyResolverOptions, type ExternalRepoConfig, type FeasibilityResult, type FeasibilityRisk, type FeasibilityStatus, type FeasibilitySummary, type FilterSpec, type FrontmatterParseResult, type GraphCycleDetected, type GraphValidationContext, type GraphValidationResult, type HookRunResult, type HumanMember, type HumanResource, ITEM_STATUSES, ITEM_TYPES, type Idea, IdeaStatus, IndexManager, type IndexStatus, type ItemLinks, type ItemStatus, type ItemType, MIGRATIONS, type MigrateRepositoryOptions, type MigrationContext, type MigrationDefinition, type MigrationReport, type MonteCarloHistogramBucket, type MonteCarloOptions, type MonteCarloResult, type MonteCarloWorkerPayload, type ParsedDelivery, type ParsedIdea, type ParsedTask, type Permission, type PermissionContext, type PluginAction, type PluginActionConsole, type PluginActionGitHubPr, type PluginActionHandler, type PluginActionHandlerResult, type PluginActionWebhook, type PluginManifest, type PluginRunOptions, type PluginRunRecord, type PluginTrigger, type PolicyAction, type ReadinessComputation, type ReadinessPartitions, type ReadinessState, type ReadinessTransitionEvent, type ReadinessWarning, type ReferentialValidationContext, type RepoConfig, type RepoState, type ResourceProfile, RiskLevel, type Role, type Run, type RunCompleted, type RunFailed, type RunResourcesConsumed, type RunStarted, RunStatus, type RunStepResult, RunStepStatus, RunbookAction, type RunbookStep, type ScheduleOptions, type ScoreContext, type ScoredTask, type SemanticValidationContext, type SimulationResult, type StructuralValidationContext, type Task, type TaskAssigned, type TaskComment, TaskComplexity, type TaskComputed, type TaskCore, type TaskCreated, TaskDeterminism, type TaskEstimate, type TaskEstimation, type TaskExecution, type TaskGovernance, type TaskGraph, type TaskPlanning, TaskPriority, type TaskResources, type TaskScheduleEntry, TaskStatus, type TaskTimeLog, type TaskTransitioned, type TaskTransitionedEvent, TaskType, type Track, type TrackUtilization, type TrackWip, type TransitionContext, type TransitionResult, type TransitionValidationContext, type UpdateItemParams, VALID_TASK_TRANSITIONS, VALID_TRANSITIONS, type ValidationContext, type ValidationError, type ValidationLevel, type ValidationResult, type VelocityMetrics, type VelocityPoint, type VelocityTrend, type WhatIfBaseline, type WhatIfModification, type WriteTaskOptions, allocate, allocate_ai, allocate_ai_tokens, analyze_feasibility, analyze_what_if, build_capacity_ledger, build_graph, check_blocked, check_permission, check_unblocked, check_wip, completeItem, complexity_penalty, compute_all_readiness, compute_critical_path, compute_readiness, compute_readiness_with_corrections, compute_score, compute_velocity, coop_project_config_path, coop_project_root, coop_projects_dir, coop_workspace_config_path, coop_workspace_dir, createItem, create_seeded_rng, critical_path_weight, deleteItem, dependency_unlock_weight, detect_cycle, detect_delivery_risks, determinism_weight, effective_priority, effective_weekly_hours, effort_or_default, ensureCoopLayout, ensure_workspace_layout, executor_fit_weight, external_dependencies_for_task, extract_subgraph, findRepoRoot, find_external_dependencies, getItemById, get_remaining_tokens, get_user_role, has_legacy_project_layout, has_v2_projects_layout, is_external_dependency, is_project_initialized, list_projects, loadState, load_auth_config, load_completed_runs, load_graph, load_plugins, migrate_repository, migrate_task, monte_carlo_forecast, parseDeliveryContent, parseDeliveryFile, parseFrontmatterContent, parseFrontmatterFile, parseIdeaContent, parseIdeaFile, parseTaskContent, parseTaskFile, parseYamlContent, parseYamlFile, parse_external_dependency, partition_by_readiness, pert_hours, pert_stddev, priority_weight, queryItems, read_project_config, read_schema_version, read_workspace_config, renderAgentPrompt, repo_default_project_id, repo_default_project_name, resolve_external_dependencies, resolve_project, risk_penalty, run_hook, run_monte_carlo_chunk, run_plugins_for_event, sample_pert_beta, sample_task_hours, schedule_next, simulate_schedule, stringifyFrontmatter, stringifyYamlContent, task_effort_hours, topological_sort, transition, transitive_dependencies, transitive_dependents, type_weight, updateItem, urgency_weight, validate, validateReferential, validateRepo, validateSemantic, validateStructural, validateTransition, validate_graph, validate_transition, writeTask, writeYamlFile, write_schema_version, write_workspace_config };
|
package/dist/index.js
CHANGED
|
@@ -1962,23 +1962,30 @@ var TASK_FIELD_ORDER = [
|
|
|
1962
1962
|
"aliases",
|
|
1963
1963
|
"priority",
|
|
1964
1964
|
"track",
|
|
1965
|
+
"delivery_tracks",
|
|
1966
|
+
"priority_context",
|
|
1965
1967
|
"assignee",
|
|
1966
1968
|
"depends_on",
|
|
1967
1969
|
"tags",
|
|
1968
1970
|
"delivery",
|
|
1971
|
+
"fix_versions",
|
|
1972
|
+
"released_in",
|
|
1969
1973
|
"acceptance",
|
|
1970
1974
|
"tests_required",
|
|
1971
1975
|
"origin",
|
|
1972
1976
|
"complexity",
|
|
1973
1977
|
"determinism",
|
|
1978
|
+
"story_points",
|
|
1974
1979
|
"estimate",
|
|
1975
1980
|
"resources",
|
|
1981
|
+
"time",
|
|
1976
1982
|
"execution",
|
|
1977
1983
|
"artifacts",
|
|
1978
1984
|
"governance",
|
|
1979
1985
|
"risk",
|
|
1980
1986
|
"metrics",
|
|
1981
|
-
"enterprise"
|
|
1987
|
+
"enterprise",
|
|
1988
|
+
"comments"
|
|
1982
1989
|
];
|
|
1983
1990
|
var ORDERED_TASK_FIELDS = new Set(TASK_FIELD_ORDER);
|
|
1984
1991
|
function buildOrderedFrontmatter(task, raw) {
|
|
@@ -2310,6 +2317,13 @@ function detect_delivery_risks(delivery, graph, velocity, options = {}) {
|
|
|
2310
2317
|
}
|
|
2311
2318
|
|
|
2312
2319
|
// src/planning/scorer.ts
|
|
2320
|
+
function effective_priority(task, track) {
|
|
2321
|
+
const candidate = track?.trim();
|
|
2322
|
+
if (candidate && task.priority_context?.[candidate]) {
|
|
2323
|
+
return task.priority_context[candidate];
|
|
2324
|
+
}
|
|
2325
|
+
return task.priority ?? "p2";
|
|
2326
|
+
}
|
|
2313
2327
|
var DEFAULT_SCORE_WEIGHTS = {
|
|
2314
2328
|
priority: {
|
|
2315
2329
|
p0: 100,
|
|
@@ -2462,9 +2476,9 @@ function unresolved_dependencies(task, graph) {
|
|
|
2462
2476
|
return !dep || dep.status !== "done" && dep.status !== "canceled";
|
|
2463
2477
|
});
|
|
2464
2478
|
}
|
|
2465
|
-
function priority_weight(task, config) {
|
|
2479
|
+
function priority_weight(task, config, track) {
|
|
2466
2480
|
const weights = configured_weights(config);
|
|
2467
|
-
const priority = task
|
|
2481
|
+
const priority = effective_priority(task, track);
|
|
2468
2482
|
return weights.priority[priority];
|
|
2469
2483
|
}
|
|
2470
2484
|
function urgency_weight(task, deliveries, today, config) {
|
|
@@ -2562,7 +2576,7 @@ function compute_score(task, graph, context = {}) {
|
|
|
2562
2576
|
const deliveries = context.deliveries ?? graph.deliveries;
|
|
2563
2577
|
const today = context.today ?? /* @__PURE__ */ new Date();
|
|
2564
2578
|
const config = context.config;
|
|
2565
|
-
return priority_weight(task, config) + urgency_weight(task, deliveries, today, config) + dependency_unlock_weight(task.id, graph, config) + critical_path_weight(task.id, context.cpm, config) + determinism_weight(task, config) + executor_fit_weight(task, context.target_executor, config) + type_weight(task, config) + complexity_penalty(task, config) + risk_penalty(task, config);
|
|
2579
|
+
return priority_weight(task, config, context.track) + urgency_weight(task, deliveries, today, config) + dependency_unlock_weight(task.id, graph, config) + critical_path_weight(task.id, context.cpm, config) + determinism_weight(task, config) + executor_fit_weight(task, context.target_executor, config) + type_weight(task, config) + complexity_penalty(task, config) + risk_penalty(task, config);
|
|
2566
2580
|
}
|
|
2567
2581
|
|
|
2568
2582
|
// src/planning/scheduler.ts
|
|
@@ -2603,6 +2617,13 @@ function clone_ledger(ledger) {
|
|
|
2603
2617
|
function normalize_track2(track) {
|
|
2604
2618
|
return (track ?? "unassigned").trim().toLowerCase();
|
|
2605
2619
|
}
|
|
2620
|
+
function task_matches_track(task, track) {
|
|
2621
|
+
const normalized = normalize_track2(track);
|
|
2622
|
+
if (normalize_track2(task.track) === normalized) {
|
|
2623
|
+
return true;
|
|
2624
|
+
}
|
|
2625
|
+
return (task.delivery_tracks ?? []).some((candidate) => normalize_track2(candidate) === normalized);
|
|
2626
|
+
}
|
|
2606
2627
|
function find_track_slots(ledger, track) {
|
|
2607
2628
|
const normalized = normalize_track2(track);
|
|
2608
2629
|
return ledger.slots.get(normalized) ?? ledger.slots.get("unassigned") ?? null;
|
|
@@ -2670,7 +2691,7 @@ function schedule_next(graph, options = {}) {
|
|
|
2670
2691
|
);
|
|
2671
2692
|
let filtered = ready_tasks;
|
|
2672
2693
|
if (options.track) {
|
|
2673
|
-
filtered = filtered.filter((task) => (task
|
|
2694
|
+
filtered = filtered.filter((task) => task_matches_track(task, options.track));
|
|
2674
2695
|
}
|
|
2675
2696
|
const deliveryFilter = options.delivery;
|
|
2676
2697
|
if (deliveryFilter) {
|
|
@@ -2693,6 +2714,7 @@ function schedule_next(graph, options = {}) {
|
|
|
2693
2714
|
cpm,
|
|
2694
2715
|
today: options.today ?? /* @__PURE__ */ new Date(),
|
|
2695
2716
|
target_executor: options.executor,
|
|
2717
|
+
track: options.track,
|
|
2696
2718
|
config: options.config
|
|
2697
2719
|
}),
|
|
2698
2720
|
readiness: compute_readiness(task, graph),
|
|
@@ -3573,6 +3595,18 @@ function validateSemantic(task, context = {}) {
|
|
|
3573
3595
|
}
|
|
3574
3596
|
}
|
|
3575
3597
|
}
|
|
3598
|
+
if (task.time?.planned_hours !== void 0 && task.time.logs) {
|
|
3599
|
+
const plannedTotal = task.time.logs.filter((entry) => entry.kind === "planned").reduce((sum, entry) => sum + entry.hours, 0);
|
|
3600
|
+
if (plannedTotal > 0 && plannedTotal !== task.time.planned_hours) {
|
|
3601
|
+
issues.push(
|
|
3602
|
+
warning2(
|
|
3603
|
+
"time.planned_hours",
|
|
3604
|
+
"sem.time_planned_mismatch",
|
|
3605
|
+
`Task planned_hours (${task.time.planned_hours}) does not match total planned logs (${plannedTotal}).`
|
|
3606
|
+
)
|
|
3607
|
+
);
|
|
3608
|
+
}
|
|
3609
|
+
}
|
|
3576
3610
|
const taskStatuses = asMap(context.taskStatuses);
|
|
3577
3611
|
if (task.status === "done" && (task.depends_on?.length ?? 0) > 0) {
|
|
3578
3612
|
const unresolved = (task.depends_on ?? []).filter((depId) => taskStatuses.get(depId) !== "done");
|
|
@@ -3661,6 +3695,45 @@ function validateStringArrayField(errors, field, value, options = {}) {
|
|
|
3661
3695
|
}
|
|
3662
3696
|
}
|
|
3663
3697
|
}
|
|
3698
|
+
function isPriority(value) {
|
|
3699
|
+
return typeof value === "string" && Object.values(TaskPriority).includes(value);
|
|
3700
|
+
}
|
|
3701
|
+
function validatePriorityContext(errors, value) {
|
|
3702
|
+
if (value === void 0) {
|
|
3703
|
+
return;
|
|
3704
|
+
}
|
|
3705
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
3706
|
+
errors.push(
|
|
3707
|
+
error4(
|
|
3708
|
+
"priority_context",
|
|
3709
|
+
"struct.priority_context_object",
|
|
3710
|
+
"Field 'priority_context' must be an object keyed by track id."
|
|
3711
|
+
)
|
|
3712
|
+
);
|
|
3713
|
+
return;
|
|
3714
|
+
}
|
|
3715
|
+
for (const [track, priority] of Object.entries(value)) {
|
|
3716
|
+
if (!track.trim()) {
|
|
3717
|
+
errors.push(
|
|
3718
|
+
error4(
|
|
3719
|
+
"priority_context",
|
|
3720
|
+
"struct.priority_context_key",
|
|
3721
|
+
"Field 'priority_context' keys must be non-empty track ids."
|
|
3722
|
+
)
|
|
3723
|
+
);
|
|
3724
|
+
continue;
|
|
3725
|
+
}
|
|
3726
|
+
if (!isPriority(priority)) {
|
|
3727
|
+
errors.push(
|
|
3728
|
+
error4(
|
|
3729
|
+
"priority_context",
|
|
3730
|
+
"struct.priority_context_priority",
|
|
3731
|
+
`Priority override for track '${track}' must be one of ${Object.values(TaskPriority).join(", ")}.`
|
|
3732
|
+
)
|
|
3733
|
+
);
|
|
3734
|
+
}
|
|
3735
|
+
}
|
|
3736
|
+
}
|
|
3664
3737
|
function validateStructural(task, context = {}) {
|
|
3665
3738
|
const errors = [];
|
|
3666
3739
|
const required = ["id", "title", "type", "status", "created", "updated"];
|
|
@@ -3727,6 +3800,106 @@ function validateStructural(task, context = {}) {
|
|
|
3727
3800
|
}
|
|
3728
3801
|
validateStringArrayField(errors, "acceptance", task.acceptance);
|
|
3729
3802
|
validateStringArrayField(errors, "tests_required", task.tests_required);
|
|
3803
|
+
validateStringArrayField(errors, "delivery_tracks", task.delivery_tracks);
|
|
3804
|
+
validateStringArrayField(errors, "fix_versions", task.fix_versions);
|
|
3805
|
+
validateStringArrayField(errors, "released_in", task.released_in);
|
|
3806
|
+
validatePriorityContext(errors, task.priority_context);
|
|
3807
|
+
if (task.story_points !== void 0 && (!Number.isFinite(task.story_points) || task.story_points < 0)) {
|
|
3808
|
+
errors.push(
|
|
3809
|
+
error4(
|
|
3810
|
+
"story_points",
|
|
3811
|
+
"struct.story_points_non_negative",
|
|
3812
|
+
"Field 'story_points' must be a non-negative number."
|
|
3813
|
+
)
|
|
3814
|
+
);
|
|
3815
|
+
}
|
|
3816
|
+
if (task.time !== void 0) {
|
|
3817
|
+
if (!task.time || typeof task.time !== "object" || Array.isArray(task.time)) {
|
|
3818
|
+
errors.push(error4("time", "struct.time_object", "Field 'time' must be an object."));
|
|
3819
|
+
} else {
|
|
3820
|
+
if (task.time.planned_hours !== void 0 && (!Number.isFinite(task.time.planned_hours) || task.time.planned_hours < 0)) {
|
|
3821
|
+
errors.push(
|
|
3822
|
+
error4(
|
|
3823
|
+
"time.planned_hours",
|
|
3824
|
+
"struct.time_planned_hours_non_negative",
|
|
3825
|
+
"Field 'time.planned_hours' must be a non-negative number."
|
|
3826
|
+
)
|
|
3827
|
+
);
|
|
3828
|
+
}
|
|
3829
|
+
if (task.time.logs !== void 0) {
|
|
3830
|
+
if (!Array.isArray(task.time.logs)) {
|
|
3831
|
+
errors.push(error4("time.logs", "struct.time_logs_array", "Field 'time.logs' must be an array."));
|
|
3832
|
+
} else {
|
|
3833
|
+
for (const [index, entry] of task.time.logs.entries()) {
|
|
3834
|
+
if (!entry || typeof entry !== "object" || Array.isArray(entry)) {
|
|
3835
|
+
errors.push(
|
|
3836
|
+
error4("time.logs", "struct.time_logs_object", `Entry ${index} in 'time.logs' must be an object.`)
|
|
3837
|
+
);
|
|
3838
|
+
continue;
|
|
3839
|
+
}
|
|
3840
|
+
const record = entry;
|
|
3841
|
+
if (typeof record.at !== "string" || record.at.trim().length === 0) {
|
|
3842
|
+
errors.push(error4("time.logs", "struct.time_logs_at", `Entry ${index} in 'time.logs' requires 'at'.`));
|
|
3843
|
+
}
|
|
3844
|
+
if (typeof record.actor !== "string" || record.actor.trim().length === 0) {
|
|
3845
|
+
errors.push(
|
|
3846
|
+
error4("time.logs", "struct.time_logs_actor", `Entry ${index} in 'time.logs' requires 'actor'.`)
|
|
3847
|
+
);
|
|
3848
|
+
}
|
|
3849
|
+
if (record.kind !== "planned" && record.kind !== "worked") {
|
|
3850
|
+
errors.push(
|
|
3851
|
+
error4(
|
|
3852
|
+
"time.logs",
|
|
3853
|
+
"struct.time_logs_kind",
|
|
3854
|
+
`Entry ${index} in 'time.logs' must use kind planned|worked.`
|
|
3855
|
+
)
|
|
3856
|
+
);
|
|
3857
|
+
}
|
|
3858
|
+
if (typeof record.hours !== "number" || !Number.isFinite(record.hours) || record.hours < 0) {
|
|
3859
|
+
errors.push(
|
|
3860
|
+
error4(
|
|
3861
|
+
"time.logs",
|
|
3862
|
+
"struct.time_logs_hours",
|
|
3863
|
+
`Entry ${index} in 'time.logs' requires non-negative numeric 'hours'.`
|
|
3864
|
+
)
|
|
3865
|
+
);
|
|
3866
|
+
}
|
|
3867
|
+
if (record.note !== void 0 && typeof record.note !== "string") {
|
|
3868
|
+
errors.push(
|
|
3869
|
+
error4(
|
|
3870
|
+
"time.logs",
|
|
3871
|
+
"struct.time_logs_note",
|
|
3872
|
+
`Entry ${index} in 'time.logs' must use a string note when present.`
|
|
3873
|
+
)
|
|
3874
|
+
);
|
|
3875
|
+
}
|
|
3876
|
+
}
|
|
3877
|
+
}
|
|
3878
|
+
}
|
|
3879
|
+
}
|
|
3880
|
+
}
|
|
3881
|
+
if (task.comments !== void 0) {
|
|
3882
|
+
if (!Array.isArray(task.comments)) {
|
|
3883
|
+
errors.push(error4("comments", "struct.comments_array", "Field 'comments' must be an array."));
|
|
3884
|
+
} else {
|
|
3885
|
+
for (const [index, entry] of task.comments.entries()) {
|
|
3886
|
+
if (!entry || typeof entry !== "object" || Array.isArray(entry)) {
|
|
3887
|
+
errors.push(error4("comments", "struct.comments_object", `Entry ${index} in 'comments' must be an object.`));
|
|
3888
|
+
continue;
|
|
3889
|
+
}
|
|
3890
|
+
const record = entry;
|
|
3891
|
+
if (typeof record.at !== "string" || record.at.trim().length === 0) {
|
|
3892
|
+
errors.push(error4("comments", "struct.comments_at", `Entry ${index} in 'comments' requires 'at'.`));
|
|
3893
|
+
}
|
|
3894
|
+
if (typeof record.author !== "string" || record.author.trim().length === 0) {
|
|
3895
|
+
errors.push(error4("comments", "struct.comments_author", `Entry ${index} in 'comments' requires 'author'.`));
|
|
3896
|
+
}
|
|
3897
|
+
if (typeof record.body !== "string" || record.body.trim().length === 0) {
|
|
3898
|
+
errors.push(error4("comments", "struct.comments_body", `Entry ${index} in 'comments' requires 'body'.`));
|
|
3899
|
+
}
|
|
3900
|
+
}
|
|
3901
|
+
}
|
|
3902
|
+
}
|
|
3730
3903
|
if (task.origin !== void 0) {
|
|
3731
3904
|
if (!task.origin || typeof task.origin !== "object" || Array.isArray(task.origin)) {
|
|
3732
3905
|
errors.push(error4("origin", "struct.origin_object", "Field 'origin' must be an object."));
|
|
@@ -4599,6 +4772,7 @@ export {
|
|
|
4599
4772
|
detect_cycle,
|
|
4600
4773
|
detect_delivery_risks,
|
|
4601
4774
|
determinism_weight,
|
|
4775
|
+
effective_priority,
|
|
4602
4776
|
effective_weekly_hours,
|
|
4603
4777
|
effort_or_default,
|
|
4604
4778
|
ensureCoopLayout,
|