@kitsy/coop-core 2.2.4 → 2.3.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 +108 -16
- package/dist/index.d.cts +15 -1
- package/dist/index.d.ts +15 -1
- package/dist/index.js +104 -16
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -64,6 +64,7 @@ __export(index_exports, {
|
|
|
64
64
|
check_permission: () => check_permission,
|
|
65
65
|
check_unblocked: () => check_unblocked,
|
|
66
66
|
check_wip: () => check_wip,
|
|
67
|
+
cloneTaskTransitions: () => cloneTaskTransitions,
|
|
67
68
|
completeItem: () => completeItem,
|
|
68
69
|
complexity_penalty: () => complexity_penalty,
|
|
69
70
|
compute_all_readiness: () => compute_all_readiness,
|
|
@@ -100,6 +101,7 @@ __export(index_exports, {
|
|
|
100
101
|
get_user_role: () => get_user_role,
|
|
101
102
|
has_legacy_project_layout: () => has_legacy_project_layout,
|
|
102
103
|
has_v2_projects_layout: () => has_v2_projects_layout,
|
|
104
|
+
isTaskStatus: () => isTaskStatus,
|
|
103
105
|
is_external_dependency: () => is_external_dependency,
|
|
104
106
|
is_project_initialized: () => is_project_initialized,
|
|
105
107
|
list_projects: () => list_projects,
|
|
@@ -133,6 +135,7 @@ __export(index_exports, {
|
|
|
133
135
|
renderAgentPrompt: () => renderAgentPrompt,
|
|
134
136
|
repo_default_project_id: () => repo_default_project_id,
|
|
135
137
|
repo_default_project_name: () => repo_default_project_name,
|
|
138
|
+
resolveTaskTransitions: () => resolveTaskTransitions,
|
|
136
139
|
resolve_external_dependencies: () => resolve_external_dependencies,
|
|
137
140
|
resolve_project: () => resolve_project,
|
|
138
141
|
risk_penalty: () => risk_penalty,
|
|
@@ -156,6 +159,7 @@ __export(index_exports, {
|
|
|
156
159
|
validate: () => validate,
|
|
157
160
|
validateReferential: () => validateReferential,
|
|
158
161
|
validateRepo: () => validateRepo,
|
|
162
|
+
validateResolvedTaskTransitions: () => validateResolvedTaskTransitions,
|
|
159
163
|
validateSemantic: () => validateSemantic,
|
|
160
164
|
validateStructural: () => validateStructural,
|
|
161
165
|
validateTransition: () => validateTransition,
|
|
@@ -2178,6 +2182,8 @@ var TASK_FIELD_ORDER = [
|
|
|
2178
2182
|
"track",
|
|
2179
2183
|
"delivery_tracks",
|
|
2180
2184
|
"priority_context",
|
|
2185
|
+
"promoted_at",
|
|
2186
|
+
"promoted_track",
|
|
2181
2187
|
"assignee",
|
|
2182
2188
|
"depends_on",
|
|
2183
2189
|
"tags",
|
|
@@ -3704,6 +3710,23 @@ function clone_ledger2(ledger) {
|
|
|
3704
3710
|
function normalize_track3(track) {
|
|
3705
3711
|
return (track ?? "unassigned").trim().toLowerCase();
|
|
3706
3712
|
}
|
|
3713
|
+
function promotion_timestamp(task, track) {
|
|
3714
|
+
if (!task.promoted_at) {
|
|
3715
|
+
return 0;
|
|
3716
|
+
}
|
|
3717
|
+
const promotedTrack = task.promoted_track?.trim();
|
|
3718
|
+
const scopedTrack = track?.trim();
|
|
3719
|
+
if (promotedTrack) {
|
|
3720
|
+
if (!scopedTrack) {
|
|
3721
|
+
return 0;
|
|
3722
|
+
}
|
|
3723
|
+
if (normalize_track3(promotedTrack) !== normalize_track3(scopedTrack)) {
|
|
3724
|
+
return 0;
|
|
3725
|
+
}
|
|
3726
|
+
}
|
|
3727
|
+
const parsed = Date.parse(task.promoted_at);
|
|
3728
|
+
return Number.isNaN(parsed) ? 0 : parsed;
|
|
3729
|
+
}
|
|
3707
3730
|
function task_matches_track(task, track) {
|
|
3708
3731
|
const normalized = normalize_track3(track);
|
|
3709
3732
|
if (normalize_track3(task.track) === normalized) {
|
|
@@ -3809,6 +3832,11 @@ function schedule_next(graph, options = {}) {
|
|
|
3809
3832
|
fits_wip: true
|
|
3810
3833
|
}));
|
|
3811
3834
|
scored.sort((a, b) => {
|
|
3835
|
+
const promotionA = promotion_timestamp(a.task, options.track);
|
|
3836
|
+
const promotionB = promotion_timestamp(b.task, options.track);
|
|
3837
|
+
if (promotionA !== promotionB) {
|
|
3838
|
+
return promotionB - promotionA;
|
|
3839
|
+
}
|
|
3812
3840
|
if (a.score !== b.score) return b.score - a.score;
|
|
3813
3841
|
return a.task.id.localeCompare(b.task.id);
|
|
3814
3842
|
});
|
|
@@ -4436,12 +4464,52 @@ function check_unblocked(task, dependencyStatuses) {
|
|
|
4436
4464
|
// src/state/machine.ts
|
|
4437
4465
|
var VALID_TASK_TRANSITIONS = /* @__PURE__ */ new Map([
|
|
4438
4466
|
["todo", /* @__PURE__ */ new Set(["in_progress", "blocked", "canceled"])],
|
|
4439
|
-
["blocked", /* @__PURE__ */ new Set(["todo"])],
|
|
4467
|
+
["blocked", /* @__PURE__ */ new Set(["todo", "in_progress", "canceled"])],
|
|
4440
4468
|
["in_progress", /* @__PURE__ */ new Set(["in_review", "blocked", "todo", "canceled"])],
|
|
4441
|
-
["in_review", /* @__PURE__ */ new Set(["done", "todo"])],
|
|
4442
|
-
["done", /* @__PURE__ */ new Set()],
|
|
4443
|
-
["canceled", /* @__PURE__ */ new Set(["todo"])]
|
|
4469
|
+
["in_review", /* @__PURE__ */ new Set(["done", "todo", "blocked", "canceled"])],
|
|
4470
|
+
["done", /* @__PURE__ */ new Set(["todo", "blocked", "canceled"])],
|
|
4471
|
+
["canceled", /* @__PURE__ */ new Set(["todo", "blocked"])]
|
|
4444
4472
|
]);
|
|
4473
|
+
function isTaskStatus(value) {
|
|
4474
|
+
return typeof value === "string" && VALID_TASK_TRANSITIONS.has(value);
|
|
4475
|
+
}
|
|
4476
|
+
function cloneTaskTransitions() {
|
|
4477
|
+
return new Map(Array.from(VALID_TASK_TRANSITIONS.entries(), ([from, targets]) => [from, new Set(targets)]));
|
|
4478
|
+
}
|
|
4479
|
+
function resolveTaskTransitions(config) {
|
|
4480
|
+
const resolved = cloneTaskTransitions();
|
|
4481
|
+
const rawWorkflow = config && typeof config === "object" && !Array.isArray(config) && typeof config.workflow === "object" ? config.workflow : null;
|
|
4482
|
+
const rawTransitions = rawWorkflow && typeof rawWorkflow.task_transitions === "object" && rawWorkflow.task_transitions !== null && !Array.isArray(rawWorkflow.task_transitions) ? rawWorkflow.task_transitions : null;
|
|
4483
|
+
if (!rawTransitions) {
|
|
4484
|
+
return resolved;
|
|
4485
|
+
}
|
|
4486
|
+
for (const [from, to] of Object.entries(rawTransitions)) {
|
|
4487
|
+
if (!isTaskStatus(from)) {
|
|
4488
|
+
continue;
|
|
4489
|
+
}
|
|
4490
|
+
if (!Array.isArray(to)) {
|
|
4491
|
+
continue;
|
|
4492
|
+
}
|
|
4493
|
+
const allowed = /* @__PURE__ */ new Set();
|
|
4494
|
+
for (const entry of to) {
|
|
4495
|
+
if (isTaskStatus(entry)) {
|
|
4496
|
+
allowed.add(entry);
|
|
4497
|
+
}
|
|
4498
|
+
}
|
|
4499
|
+
resolved.set(from, allowed);
|
|
4500
|
+
}
|
|
4501
|
+
return resolved;
|
|
4502
|
+
}
|
|
4503
|
+
function validateResolvedTaskTransitions(transitions) {
|
|
4504
|
+
const errors = [];
|
|
4505
|
+
for (const status of VALID_TASK_TRANSITIONS.keys()) {
|
|
4506
|
+
const targets = transitions.get(status);
|
|
4507
|
+
if (!targets || targets.size === 0) {
|
|
4508
|
+
errors.push(`Task status '${status}' cannot have zero outbound transitions.`);
|
|
4509
|
+
}
|
|
4510
|
+
}
|
|
4511
|
+
return errors;
|
|
4512
|
+
}
|
|
4445
4513
|
function toStatusMap2(value) {
|
|
4446
4514
|
if (!value) return /* @__PURE__ */ new Map();
|
|
4447
4515
|
if (value instanceof Map) return new Map(value);
|
|
@@ -4482,7 +4550,7 @@ function validateGovernanceAndDeps(task, targetStatus, context) {
|
|
|
4482
4550
|
return null;
|
|
4483
4551
|
}
|
|
4484
4552
|
function transition(task, targetStatus, context = {}) {
|
|
4485
|
-
const allowed =
|
|
4553
|
+
const allowed = resolveTaskTransitions(context.config).get(task.status) ?? /* @__PURE__ */ new Set();
|
|
4486
4554
|
if (!allowed.has(targetStatus)) {
|
|
4487
4555
|
return {
|
|
4488
4556
|
success: false,
|
|
@@ -4765,6 +4833,10 @@ function isIsoDate(value) {
|
|
|
4765
4833
|
}
|
|
4766
4834
|
return date.toISOString().slice(0, 10) === value;
|
|
4767
4835
|
}
|
|
4836
|
+
function isIsoDateTime(value) {
|
|
4837
|
+
const date = new Date(value);
|
|
4838
|
+
return !Number.isNaN(date.valueOf());
|
|
4839
|
+
}
|
|
4768
4840
|
function validateStringArrayField(errors, field, value, options = {}) {
|
|
4769
4841
|
if (value === void 0) {
|
|
4770
4842
|
return;
|
|
@@ -4891,6 +4963,28 @@ function validateStructural(task, context = {}) {
|
|
|
4891
4963
|
validateStringArrayField(errors, "fix_versions", task.fix_versions);
|
|
4892
4964
|
validateStringArrayField(errors, "released_in", task.released_in);
|
|
4893
4965
|
validatePriorityContext(errors, task.priority_context);
|
|
4966
|
+
if (task.promoted_at !== void 0) {
|
|
4967
|
+
if (typeof task.promoted_at !== "string" || !isIsoDateTime(task.promoted_at)) {
|
|
4968
|
+
errors.push(
|
|
4969
|
+
error4(
|
|
4970
|
+
"promoted_at",
|
|
4971
|
+
"struct.promoted_at_iso_datetime",
|
|
4972
|
+
"Field 'promoted_at' must be an ISO datetime string."
|
|
4973
|
+
)
|
|
4974
|
+
);
|
|
4975
|
+
}
|
|
4976
|
+
}
|
|
4977
|
+
if (task.promoted_track !== void 0 && task.promoted_track !== null) {
|
|
4978
|
+
if (typeof task.promoted_track !== "string" || task.promoted_track.trim().length === 0) {
|
|
4979
|
+
errors.push(
|
|
4980
|
+
error4(
|
|
4981
|
+
"promoted_track",
|
|
4982
|
+
"struct.promoted_track_string",
|
|
4983
|
+
"Field 'promoted_track' must be a non-empty string or null."
|
|
4984
|
+
)
|
|
4985
|
+
);
|
|
4986
|
+
}
|
|
4987
|
+
}
|
|
4894
4988
|
if (task.story_points !== void 0 && (!Number.isFinite(task.story_points) || task.story_points < 0)) {
|
|
4895
4989
|
errors.push(
|
|
4896
4990
|
error4(
|
|
@@ -5010,14 +5104,7 @@ function validateStructural(task, context = {}) {
|
|
|
5010
5104
|
}
|
|
5011
5105
|
|
|
5012
5106
|
// src/validator/transition.ts
|
|
5013
|
-
var VALID_TRANSITIONS =
|
|
5014
|
-
["todo", /* @__PURE__ */ new Set(["in_progress", "blocked", "canceled"])],
|
|
5015
|
-
["blocked", /* @__PURE__ */ new Set(["todo"])],
|
|
5016
|
-
["in_progress", /* @__PURE__ */ new Set(["in_review", "blocked", "todo", "canceled"])],
|
|
5017
|
-
["in_review", /* @__PURE__ */ new Set(["done", "todo"])],
|
|
5018
|
-
["done", /* @__PURE__ */ new Set()],
|
|
5019
|
-
["canceled", /* @__PURE__ */ new Set(["todo"])]
|
|
5020
|
-
]);
|
|
5107
|
+
var VALID_TRANSITIONS = VALID_TASK_TRANSITIONS;
|
|
5021
5108
|
function error5(field, rule, message) {
|
|
5022
5109
|
return { level: "error", field, rule, message };
|
|
5023
5110
|
}
|
|
@@ -5031,14 +5118,15 @@ function asMap2(value) {
|
|
|
5031
5118
|
return new Map(Object.entries(value));
|
|
5032
5119
|
}
|
|
5033
5120
|
function validate_transition(fromStatus, toStatus) {
|
|
5034
|
-
const allowed =
|
|
5121
|
+
const allowed = VALID_TASK_TRANSITIONS.get(fromStatus);
|
|
5035
5122
|
return Boolean(allowed?.has(toStatus));
|
|
5036
5123
|
}
|
|
5037
5124
|
function validateTransition(task, toStatus, context = {}) {
|
|
5038
5125
|
const issues = [];
|
|
5039
5126
|
const fromStatus = task.status;
|
|
5040
|
-
|
|
5041
|
-
|
|
5127
|
+
const transitions = resolveTaskTransitions(context.config);
|
|
5128
|
+
if (!(transitions.get(fromStatus)?.has(toStatus) ?? false)) {
|
|
5129
|
+
const allowed = Array.from(transitions.get(fromStatus) ?? []);
|
|
5042
5130
|
issues.push(
|
|
5043
5131
|
error5(
|
|
5044
5132
|
"status",
|
|
@@ -5839,6 +5927,7 @@ function validateRepo(rootDir) {
|
|
|
5839
5927
|
check_permission,
|
|
5840
5928
|
check_unblocked,
|
|
5841
5929
|
check_wip,
|
|
5930
|
+
cloneTaskTransitions,
|
|
5842
5931
|
completeItem,
|
|
5843
5932
|
complexity_penalty,
|
|
5844
5933
|
compute_all_readiness,
|
|
@@ -5875,6 +5964,7 @@ function validateRepo(rootDir) {
|
|
|
5875
5964
|
get_user_role,
|
|
5876
5965
|
has_legacy_project_layout,
|
|
5877
5966
|
has_v2_projects_layout,
|
|
5967
|
+
isTaskStatus,
|
|
5878
5968
|
is_external_dependency,
|
|
5879
5969
|
is_project_initialized,
|
|
5880
5970
|
list_projects,
|
|
@@ -5908,6 +5998,7 @@ function validateRepo(rootDir) {
|
|
|
5908
5998
|
renderAgentPrompt,
|
|
5909
5999
|
repo_default_project_id,
|
|
5910
6000
|
repo_default_project_name,
|
|
6001
|
+
resolveTaskTransitions,
|
|
5911
6002
|
resolve_external_dependencies,
|
|
5912
6003
|
resolve_project,
|
|
5913
6004
|
risk_penalty,
|
|
@@ -5931,6 +6022,7 @@ function validateRepo(rootDir) {
|
|
|
5931
6022
|
validate,
|
|
5932
6023
|
validateReferential,
|
|
5933
6024
|
validateRepo,
|
|
6025
|
+
validateResolvedTaskTransitions,
|
|
5934
6026
|
validateSemantic,
|
|
5935
6027
|
validateStructural,
|
|
5936
6028
|
validateTransition,
|
package/dist/index.d.cts
CHANGED
|
@@ -305,6 +305,8 @@ interface TaskPlanning {
|
|
|
305
305
|
track?: string;
|
|
306
306
|
delivery_tracks?: string[];
|
|
307
307
|
priority_context?: Record<string, TaskPriority>;
|
|
308
|
+
promoted_at?: string;
|
|
309
|
+
promoted_track?: string | null;
|
|
308
310
|
assignee?: string | null;
|
|
309
311
|
depends_on?: string[];
|
|
310
312
|
tags?: string[];
|
|
@@ -800,6 +802,12 @@ interface CoopConfig {
|
|
|
800
802
|
on_task_transition?: string;
|
|
801
803
|
on_delivery_complete?: string;
|
|
802
804
|
};
|
|
805
|
+
workflow?: {
|
|
806
|
+
task_transitions?: Partial<Record<TaskStatus, TaskStatus[]>>;
|
|
807
|
+
track_overrides?: Record<string, {
|
|
808
|
+
task_transitions?: Partial<Record<TaskStatus, TaskStatus[]>>;
|
|
809
|
+
}>;
|
|
810
|
+
};
|
|
803
811
|
api?: {
|
|
804
812
|
host?: string;
|
|
805
813
|
port?: number;
|
|
@@ -1375,6 +1383,7 @@ declare function check_unblocked(task: Task, dependencyStatuses?: DependencyStat
|
|
|
1375
1383
|
type TransitionContext = {
|
|
1376
1384
|
actor?: string;
|
|
1377
1385
|
dependencyStatuses?: Map<string, TaskStatus> | Record<string, TaskStatus>;
|
|
1386
|
+
config?: CoopConfig | Record<string, unknown>;
|
|
1378
1387
|
now?: string | Date;
|
|
1379
1388
|
eventEmitter?: CoopEventEmitter;
|
|
1380
1389
|
};
|
|
@@ -1384,6 +1393,10 @@ type TransitionResult = {
|
|
|
1384
1393
|
error?: string;
|
|
1385
1394
|
};
|
|
1386
1395
|
declare const VALID_TASK_TRANSITIONS: Map<TaskStatus, Set<TaskStatus>>;
|
|
1396
|
+
declare function isTaskStatus(value: unknown): value is TaskStatus;
|
|
1397
|
+
declare function cloneTaskTransitions(): Map<TaskStatus, Set<TaskStatus>>;
|
|
1398
|
+
declare function resolveTaskTransitions(config?: CoopConfig | Record<string, unknown>): Map<TaskStatus, Set<TaskStatus>>;
|
|
1399
|
+
declare function validateResolvedTaskTransitions(transitions: Map<TaskStatus, Set<TaskStatus>>): string[];
|
|
1387
1400
|
declare function transition(task: Task, targetStatus: TaskStatus, context?: TransitionContext): TransitionResult;
|
|
1388
1401
|
|
|
1389
1402
|
type ValidationLevel = "error" | "warning";
|
|
@@ -1426,6 +1439,7 @@ declare const VALID_TRANSITIONS: Map<TaskStatus, Set<TaskStatus>>;
|
|
|
1426
1439
|
interface TransitionValidationContext {
|
|
1427
1440
|
actor?: string;
|
|
1428
1441
|
dependencyStatuses?: Map<string, TaskStatus> | Record<string, TaskStatus>;
|
|
1442
|
+
config?: CoopConfig | Record<string, unknown>;
|
|
1429
1443
|
}
|
|
1430
1444
|
declare function validate_transition(fromStatus: TaskStatus, toStatus: TaskStatus): boolean;
|
|
1431
1445
|
declare function validateTransition(task: Task, toStatus: TaskStatus, context?: TransitionValidationContext): ValidationError[];
|
|
@@ -1539,4 +1553,4 @@ declare function validateRepo(rootDir: string): {
|
|
|
1539
1553
|
warnings: string[];
|
|
1540
1554
|
};
|
|
1541
1555
|
|
|
1542
|
-
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 };
|
|
1556
|
+
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, cloneTaskTransitions, 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, isTaskStatus, 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, resolveTaskTransitions, 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, validateResolvedTaskTransitions, validateSemantic, validateStructural, validateTransition, validate_graph, validate_transition, writeTask, writeYamlFile, write_schema_version, write_workspace_config };
|
package/dist/index.d.ts
CHANGED
|
@@ -305,6 +305,8 @@ interface TaskPlanning {
|
|
|
305
305
|
track?: string;
|
|
306
306
|
delivery_tracks?: string[];
|
|
307
307
|
priority_context?: Record<string, TaskPriority>;
|
|
308
|
+
promoted_at?: string;
|
|
309
|
+
promoted_track?: string | null;
|
|
308
310
|
assignee?: string | null;
|
|
309
311
|
depends_on?: string[];
|
|
310
312
|
tags?: string[];
|
|
@@ -800,6 +802,12 @@ interface CoopConfig {
|
|
|
800
802
|
on_task_transition?: string;
|
|
801
803
|
on_delivery_complete?: string;
|
|
802
804
|
};
|
|
805
|
+
workflow?: {
|
|
806
|
+
task_transitions?: Partial<Record<TaskStatus, TaskStatus[]>>;
|
|
807
|
+
track_overrides?: Record<string, {
|
|
808
|
+
task_transitions?: Partial<Record<TaskStatus, TaskStatus[]>>;
|
|
809
|
+
}>;
|
|
810
|
+
};
|
|
803
811
|
api?: {
|
|
804
812
|
host?: string;
|
|
805
813
|
port?: number;
|
|
@@ -1375,6 +1383,7 @@ declare function check_unblocked(task: Task, dependencyStatuses?: DependencyStat
|
|
|
1375
1383
|
type TransitionContext = {
|
|
1376
1384
|
actor?: string;
|
|
1377
1385
|
dependencyStatuses?: Map<string, TaskStatus> | Record<string, TaskStatus>;
|
|
1386
|
+
config?: CoopConfig | Record<string, unknown>;
|
|
1378
1387
|
now?: string | Date;
|
|
1379
1388
|
eventEmitter?: CoopEventEmitter;
|
|
1380
1389
|
};
|
|
@@ -1384,6 +1393,10 @@ type TransitionResult = {
|
|
|
1384
1393
|
error?: string;
|
|
1385
1394
|
};
|
|
1386
1395
|
declare const VALID_TASK_TRANSITIONS: Map<TaskStatus, Set<TaskStatus>>;
|
|
1396
|
+
declare function isTaskStatus(value: unknown): value is TaskStatus;
|
|
1397
|
+
declare function cloneTaskTransitions(): Map<TaskStatus, Set<TaskStatus>>;
|
|
1398
|
+
declare function resolveTaskTransitions(config?: CoopConfig | Record<string, unknown>): Map<TaskStatus, Set<TaskStatus>>;
|
|
1399
|
+
declare function validateResolvedTaskTransitions(transitions: Map<TaskStatus, Set<TaskStatus>>): string[];
|
|
1387
1400
|
declare function transition(task: Task, targetStatus: TaskStatus, context?: TransitionContext): TransitionResult;
|
|
1388
1401
|
|
|
1389
1402
|
type ValidationLevel = "error" | "warning";
|
|
@@ -1426,6 +1439,7 @@ declare const VALID_TRANSITIONS: Map<TaskStatus, Set<TaskStatus>>;
|
|
|
1426
1439
|
interface TransitionValidationContext {
|
|
1427
1440
|
actor?: string;
|
|
1428
1441
|
dependencyStatuses?: Map<string, TaskStatus> | Record<string, TaskStatus>;
|
|
1442
|
+
config?: CoopConfig | Record<string, unknown>;
|
|
1429
1443
|
}
|
|
1430
1444
|
declare function validate_transition(fromStatus: TaskStatus, toStatus: TaskStatus): boolean;
|
|
1431
1445
|
declare function validateTransition(task: Task, toStatus: TaskStatus, context?: TransitionValidationContext): ValidationError[];
|
|
@@ -1539,4 +1553,4 @@ declare function validateRepo(rootDir: string): {
|
|
|
1539
1553
|
warnings: string[];
|
|
1540
1554
|
};
|
|
1541
1555
|
|
|
1542
|
-
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 };
|
|
1556
|
+
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, cloneTaskTransitions, 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, isTaskStatus, 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, resolveTaskTransitions, 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, validateResolvedTaskTransitions, validateSemantic, validateStructural, validateTransition, validate_graph, validate_transition, writeTask, writeYamlFile, write_schema_version, write_workspace_config };
|
package/dist/index.js
CHANGED
|
@@ -1967,6 +1967,8 @@ var TASK_FIELD_ORDER = [
|
|
|
1967
1967
|
"track",
|
|
1968
1968
|
"delivery_tracks",
|
|
1969
1969
|
"priority_context",
|
|
1970
|
+
"promoted_at",
|
|
1971
|
+
"promoted_track",
|
|
1970
1972
|
"assignee",
|
|
1971
1973
|
"depends_on",
|
|
1972
1974
|
"tags",
|
|
@@ -2620,6 +2622,23 @@ function clone_ledger(ledger) {
|
|
|
2620
2622
|
function normalize_track2(track) {
|
|
2621
2623
|
return (track ?? "unassigned").trim().toLowerCase();
|
|
2622
2624
|
}
|
|
2625
|
+
function promotion_timestamp(task, track) {
|
|
2626
|
+
if (!task.promoted_at) {
|
|
2627
|
+
return 0;
|
|
2628
|
+
}
|
|
2629
|
+
const promotedTrack = task.promoted_track?.trim();
|
|
2630
|
+
const scopedTrack = track?.trim();
|
|
2631
|
+
if (promotedTrack) {
|
|
2632
|
+
if (!scopedTrack) {
|
|
2633
|
+
return 0;
|
|
2634
|
+
}
|
|
2635
|
+
if (normalize_track2(promotedTrack) !== normalize_track2(scopedTrack)) {
|
|
2636
|
+
return 0;
|
|
2637
|
+
}
|
|
2638
|
+
}
|
|
2639
|
+
const parsed = Date.parse(task.promoted_at);
|
|
2640
|
+
return Number.isNaN(parsed) ? 0 : parsed;
|
|
2641
|
+
}
|
|
2623
2642
|
function task_matches_track(task, track) {
|
|
2624
2643
|
const normalized = normalize_track2(track);
|
|
2625
2644
|
if (normalize_track2(task.track) === normalized) {
|
|
@@ -2725,6 +2744,11 @@ function schedule_next(graph, options = {}) {
|
|
|
2725
2744
|
fits_wip: true
|
|
2726
2745
|
}));
|
|
2727
2746
|
scored.sort((a, b) => {
|
|
2747
|
+
const promotionA = promotion_timestamp(a.task, options.track);
|
|
2748
|
+
const promotionB = promotion_timestamp(b.task, options.track);
|
|
2749
|
+
if (promotionA !== promotionB) {
|
|
2750
|
+
return promotionB - promotionA;
|
|
2751
|
+
}
|
|
2728
2752
|
if (a.score !== b.score) return b.score - a.score;
|
|
2729
2753
|
return a.task.id.localeCompare(b.task.id);
|
|
2730
2754
|
});
|
|
@@ -3352,12 +3376,52 @@ function check_unblocked(task, dependencyStatuses) {
|
|
|
3352
3376
|
// src/state/machine.ts
|
|
3353
3377
|
var VALID_TASK_TRANSITIONS = /* @__PURE__ */ new Map([
|
|
3354
3378
|
["todo", /* @__PURE__ */ new Set(["in_progress", "blocked", "canceled"])],
|
|
3355
|
-
["blocked", /* @__PURE__ */ new Set(["todo"])],
|
|
3379
|
+
["blocked", /* @__PURE__ */ new Set(["todo", "in_progress", "canceled"])],
|
|
3356
3380
|
["in_progress", /* @__PURE__ */ new Set(["in_review", "blocked", "todo", "canceled"])],
|
|
3357
|
-
["in_review", /* @__PURE__ */ new Set(["done", "todo"])],
|
|
3358
|
-
["done", /* @__PURE__ */ new Set()],
|
|
3359
|
-
["canceled", /* @__PURE__ */ new Set(["todo"])]
|
|
3381
|
+
["in_review", /* @__PURE__ */ new Set(["done", "todo", "blocked", "canceled"])],
|
|
3382
|
+
["done", /* @__PURE__ */ new Set(["todo", "blocked", "canceled"])],
|
|
3383
|
+
["canceled", /* @__PURE__ */ new Set(["todo", "blocked"])]
|
|
3360
3384
|
]);
|
|
3385
|
+
function isTaskStatus(value) {
|
|
3386
|
+
return typeof value === "string" && VALID_TASK_TRANSITIONS.has(value);
|
|
3387
|
+
}
|
|
3388
|
+
function cloneTaskTransitions() {
|
|
3389
|
+
return new Map(Array.from(VALID_TASK_TRANSITIONS.entries(), ([from, targets]) => [from, new Set(targets)]));
|
|
3390
|
+
}
|
|
3391
|
+
function resolveTaskTransitions(config) {
|
|
3392
|
+
const resolved = cloneTaskTransitions();
|
|
3393
|
+
const rawWorkflow = config && typeof config === "object" && !Array.isArray(config) && typeof config.workflow === "object" ? config.workflow : null;
|
|
3394
|
+
const rawTransitions = rawWorkflow && typeof rawWorkflow.task_transitions === "object" && rawWorkflow.task_transitions !== null && !Array.isArray(rawWorkflow.task_transitions) ? rawWorkflow.task_transitions : null;
|
|
3395
|
+
if (!rawTransitions) {
|
|
3396
|
+
return resolved;
|
|
3397
|
+
}
|
|
3398
|
+
for (const [from, to] of Object.entries(rawTransitions)) {
|
|
3399
|
+
if (!isTaskStatus(from)) {
|
|
3400
|
+
continue;
|
|
3401
|
+
}
|
|
3402
|
+
if (!Array.isArray(to)) {
|
|
3403
|
+
continue;
|
|
3404
|
+
}
|
|
3405
|
+
const allowed = /* @__PURE__ */ new Set();
|
|
3406
|
+
for (const entry of to) {
|
|
3407
|
+
if (isTaskStatus(entry)) {
|
|
3408
|
+
allowed.add(entry);
|
|
3409
|
+
}
|
|
3410
|
+
}
|
|
3411
|
+
resolved.set(from, allowed);
|
|
3412
|
+
}
|
|
3413
|
+
return resolved;
|
|
3414
|
+
}
|
|
3415
|
+
function validateResolvedTaskTransitions(transitions) {
|
|
3416
|
+
const errors = [];
|
|
3417
|
+
for (const status of VALID_TASK_TRANSITIONS.keys()) {
|
|
3418
|
+
const targets = transitions.get(status);
|
|
3419
|
+
if (!targets || targets.size === 0) {
|
|
3420
|
+
errors.push(`Task status '${status}' cannot have zero outbound transitions.`);
|
|
3421
|
+
}
|
|
3422
|
+
}
|
|
3423
|
+
return errors;
|
|
3424
|
+
}
|
|
3361
3425
|
function toStatusMap2(value) {
|
|
3362
3426
|
if (!value) return /* @__PURE__ */ new Map();
|
|
3363
3427
|
if (value instanceof Map) return new Map(value);
|
|
@@ -3398,7 +3462,7 @@ function validateGovernanceAndDeps(task, targetStatus, context) {
|
|
|
3398
3462
|
return null;
|
|
3399
3463
|
}
|
|
3400
3464
|
function transition(task, targetStatus, context = {}) {
|
|
3401
|
-
const allowed =
|
|
3465
|
+
const allowed = resolveTaskTransitions(context.config).get(task.status) ?? /* @__PURE__ */ new Set();
|
|
3402
3466
|
if (!allowed.has(targetStatus)) {
|
|
3403
3467
|
return {
|
|
3404
3468
|
success: false,
|
|
@@ -3681,6 +3745,10 @@ function isIsoDate(value) {
|
|
|
3681
3745
|
}
|
|
3682
3746
|
return date.toISOString().slice(0, 10) === value;
|
|
3683
3747
|
}
|
|
3748
|
+
function isIsoDateTime(value) {
|
|
3749
|
+
const date = new Date(value);
|
|
3750
|
+
return !Number.isNaN(date.valueOf());
|
|
3751
|
+
}
|
|
3684
3752
|
function validateStringArrayField(errors, field, value, options = {}) {
|
|
3685
3753
|
if (value === void 0) {
|
|
3686
3754
|
return;
|
|
@@ -3807,6 +3875,28 @@ function validateStructural(task, context = {}) {
|
|
|
3807
3875
|
validateStringArrayField(errors, "fix_versions", task.fix_versions);
|
|
3808
3876
|
validateStringArrayField(errors, "released_in", task.released_in);
|
|
3809
3877
|
validatePriorityContext(errors, task.priority_context);
|
|
3878
|
+
if (task.promoted_at !== void 0) {
|
|
3879
|
+
if (typeof task.promoted_at !== "string" || !isIsoDateTime(task.promoted_at)) {
|
|
3880
|
+
errors.push(
|
|
3881
|
+
error4(
|
|
3882
|
+
"promoted_at",
|
|
3883
|
+
"struct.promoted_at_iso_datetime",
|
|
3884
|
+
"Field 'promoted_at' must be an ISO datetime string."
|
|
3885
|
+
)
|
|
3886
|
+
);
|
|
3887
|
+
}
|
|
3888
|
+
}
|
|
3889
|
+
if (task.promoted_track !== void 0 && task.promoted_track !== null) {
|
|
3890
|
+
if (typeof task.promoted_track !== "string" || task.promoted_track.trim().length === 0) {
|
|
3891
|
+
errors.push(
|
|
3892
|
+
error4(
|
|
3893
|
+
"promoted_track",
|
|
3894
|
+
"struct.promoted_track_string",
|
|
3895
|
+
"Field 'promoted_track' must be a non-empty string or null."
|
|
3896
|
+
)
|
|
3897
|
+
);
|
|
3898
|
+
}
|
|
3899
|
+
}
|
|
3810
3900
|
if (task.story_points !== void 0 && (!Number.isFinite(task.story_points) || task.story_points < 0)) {
|
|
3811
3901
|
errors.push(
|
|
3812
3902
|
error4(
|
|
@@ -3926,14 +4016,7 @@ function validateStructural(task, context = {}) {
|
|
|
3926
4016
|
}
|
|
3927
4017
|
|
|
3928
4018
|
// src/validator/transition.ts
|
|
3929
|
-
var VALID_TRANSITIONS =
|
|
3930
|
-
["todo", /* @__PURE__ */ new Set(["in_progress", "blocked", "canceled"])],
|
|
3931
|
-
["blocked", /* @__PURE__ */ new Set(["todo"])],
|
|
3932
|
-
["in_progress", /* @__PURE__ */ new Set(["in_review", "blocked", "todo", "canceled"])],
|
|
3933
|
-
["in_review", /* @__PURE__ */ new Set(["done", "todo"])],
|
|
3934
|
-
["done", /* @__PURE__ */ new Set()],
|
|
3935
|
-
["canceled", /* @__PURE__ */ new Set(["todo"])]
|
|
3936
|
-
]);
|
|
4019
|
+
var VALID_TRANSITIONS = VALID_TASK_TRANSITIONS;
|
|
3937
4020
|
function error5(field, rule, message) {
|
|
3938
4021
|
return { level: "error", field, rule, message };
|
|
3939
4022
|
}
|
|
@@ -3947,14 +4030,15 @@ function asMap2(value) {
|
|
|
3947
4030
|
return new Map(Object.entries(value));
|
|
3948
4031
|
}
|
|
3949
4032
|
function validate_transition(fromStatus, toStatus) {
|
|
3950
|
-
const allowed =
|
|
4033
|
+
const allowed = VALID_TASK_TRANSITIONS.get(fromStatus);
|
|
3951
4034
|
return Boolean(allowed?.has(toStatus));
|
|
3952
4035
|
}
|
|
3953
4036
|
function validateTransition(task, toStatus, context = {}) {
|
|
3954
4037
|
const issues = [];
|
|
3955
4038
|
const fromStatus = task.status;
|
|
3956
|
-
|
|
3957
|
-
|
|
4039
|
+
const transitions = resolveTaskTransitions(context.config);
|
|
4040
|
+
if (!(transitions.get(fromStatus)?.has(toStatus) ?? false)) {
|
|
4041
|
+
const allowed = Array.from(transitions.get(fromStatus) ?? []);
|
|
3958
4042
|
issues.push(
|
|
3959
4043
|
error5(
|
|
3960
4044
|
"status",
|
|
@@ -4754,6 +4838,7 @@ export {
|
|
|
4754
4838
|
check_permission,
|
|
4755
4839
|
check_unblocked,
|
|
4756
4840
|
check_wip,
|
|
4841
|
+
cloneTaskTransitions,
|
|
4757
4842
|
completeItem,
|
|
4758
4843
|
complexity_penalty,
|
|
4759
4844
|
compute_all_readiness,
|
|
@@ -4790,6 +4875,7 @@ export {
|
|
|
4790
4875
|
get_user_role,
|
|
4791
4876
|
has_legacy_project_layout,
|
|
4792
4877
|
has_v2_projects_layout,
|
|
4878
|
+
isTaskStatus,
|
|
4793
4879
|
is_external_dependency,
|
|
4794
4880
|
is_project_initialized,
|
|
4795
4881
|
list_projects,
|
|
@@ -4823,6 +4909,7 @@ export {
|
|
|
4823
4909
|
renderAgentPrompt,
|
|
4824
4910
|
repo_default_project_id,
|
|
4825
4911
|
repo_default_project_name,
|
|
4912
|
+
resolveTaskTransitions,
|
|
4826
4913
|
resolve_external_dependencies,
|
|
4827
4914
|
resolve_project,
|
|
4828
4915
|
risk_penalty,
|
|
@@ -4846,6 +4933,7 @@ export {
|
|
|
4846
4933
|
validate,
|
|
4847
4934
|
validateReferential,
|
|
4848
4935
|
validateRepo,
|
|
4936
|
+
validateResolvedTaskTransitions,
|
|
4849
4937
|
validateSemantic,
|
|
4850
4938
|
validateStructural,
|
|
4851
4939
|
validateTransition,
|