@kitsy/coop-core 2.2.5 → 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 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",
@@ -4458,12 +4464,52 @@ function check_unblocked(task, dependencyStatuses) {
4458
4464
  // src/state/machine.ts
4459
4465
  var VALID_TASK_TRANSITIONS = /* @__PURE__ */ new Map([
4460
4466
  ["todo", /* @__PURE__ */ new Set(["in_progress", "blocked", "canceled"])],
4461
- ["blocked", /* @__PURE__ */ new Set(["todo"])],
4467
+ ["blocked", /* @__PURE__ */ new Set(["todo", "in_progress", "canceled"])],
4462
4468
  ["in_progress", /* @__PURE__ */ new Set(["in_review", "blocked", "todo", "canceled"])],
4463
- ["in_review", /* @__PURE__ */ new Set(["done", "todo"])],
4464
- ["done", /* @__PURE__ */ new Set()],
4465
- ["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"])]
4466
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
+ }
4467
4513
  function toStatusMap2(value) {
4468
4514
  if (!value) return /* @__PURE__ */ new Map();
4469
4515
  if (value instanceof Map) return new Map(value);
@@ -4504,7 +4550,7 @@ function validateGovernanceAndDeps(task, targetStatus, context) {
4504
4550
  return null;
4505
4551
  }
4506
4552
  function transition(task, targetStatus, context = {}) {
4507
- const allowed = VALID_TASK_TRANSITIONS.get(task.status) ?? /* @__PURE__ */ new Set();
4553
+ const allowed = resolveTaskTransitions(context.config).get(task.status) ?? /* @__PURE__ */ new Set();
4508
4554
  if (!allowed.has(targetStatus)) {
4509
4555
  return {
4510
4556
  success: false,
@@ -5058,14 +5104,7 @@ function validateStructural(task, context = {}) {
5058
5104
  }
5059
5105
 
5060
5106
  // src/validator/transition.ts
5061
- var VALID_TRANSITIONS = /* @__PURE__ */ new Map([
5062
- ["todo", /* @__PURE__ */ new Set(["in_progress", "blocked", "canceled"])],
5063
- ["blocked", /* @__PURE__ */ new Set(["todo"])],
5064
- ["in_progress", /* @__PURE__ */ new Set(["in_review", "blocked", "todo", "canceled"])],
5065
- ["in_review", /* @__PURE__ */ new Set(["done", "todo"])],
5066
- ["done", /* @__PURE__ */ new Set()],
5067
- ["canceled", /* @__PURE__ */ new Set(["todo"])]
5068
- ]);
5107
+ var VALID_TRANSITIONS = VALID_TASK_TRANSITIONS;
5069
5108
  function error5(field, rule, message) {
5070
5109
  return { level: "error", field, rule, message };
5071
5110
  }
@@ -5079,14 +5118,15 @@ function asMap2(value) {
5079
5118
  return new Map(Object.entries(value));
5080
5119
  }
5081
5120
  function validate_transition(fromStatus, toStatus) {
5082
- const allowed = VALID_TRANSITIONS.get(fromStatus);
5121
+ const allowed = VALID_TASK_TRANSITIONS.get(fromStatus);
5083
5122
  return Boolean(allowed?.has(toStatus));
5084
5123
  }
5085
5124
  function validateTransition(task, toStatus, context = {}) {
5086
5125
  const issues = [];
5087
5126
  const fromStatus = task.status;
5088
- if (!validate_transition(fromStatus, toStatus)) {
5089
- const allowed = Array.from(VALID_TRANSITIONS.get(fromStatus) ?? []);
5127
+ const transitions = resolveTaskTransitions(context.config);
5128
+ if (!(transitions.get(fromStatus)?.has(toStatus) ?? false)) {
5129
+ const allowed = Array.from(transitions.get(fromStatus) ?? []);
5090
5130
  issues.push(
5091
5131
  error5(
5092
5132
  "status",
@@ -5887,6 +5927,7 @@ function validateRepo(rootDir) {
5887
5927
  check_permission,
5888
5928
  check_unblocked,
5889
5929
  check_wip,
5930
+ cloneTaskTransitions,
5890
5931
  completeItem,
5891
5932
  complexity_penalty,
5892
5933
  compute_all_readiness,
@@ -5923,6 +5964,7 @@ function validateRepo(rootDir) {
5923
5964
  get_user_role,
5924
5965
  has_legacy_project_layout,
5925
5966
  has_v2_projects_layout,
5967
+ isTaskStatus,
5926
5968
  is_external_dependency,
5927
5969
  is_project_initialized,
5928
5970
  list_projects,
@@ -5956,6 +5998,7 @@ function validateRepo(rootDir) {
5956
5998
  renderAgentPrompt,
5957
5999
  repo_default_project_id,
5958
6000
  repo_default_project_name,
6001
+ resolveTaskTransitions,
5959
6002
  resolve_external_dependencies,
5960
6003
  resolve_project,
5961
6004
  risk_penalty,
@@ -5979,6 +6022,7 @@ function validateRepo(rootDir) {
5979
6022
  validate,
5980
6023
  validateReferential,
5981
6024
  validateRepo,
6025
+ validateResolvedTaskTransitions,
5982
6026
  validateSemantic,
5983
6027
  validateStructural,
5984
6028
  validateTransition,
package/dist/index.d.cts CHANGED
@@ -802,6 +802,12 @@ interface CoopConfig {
802
802
  on_task_transition?: string;
803
803
  on_delivery_complete?: string;
804
804
  };
805
+ workflow?: {
806
+ task_transitions?: Partial<Record<TaskStatus, TaskStatus[]>>;
807
+ track_overrides?: Record<string, {
808
+ task_transitions?: Partial<Record<TaskStatus, TaskStatus[]>>;
809
+ }>;
810
+ };
805
811
  api?: {
806
812
  host?: string;
807
813
  port?: number;
@@ -1377,6 +1383,7 @@ declare function check_unblocked(task: Task, dependencyStatuses?: DependencyStat
1377
1383
  type TransitionContext = {
1378
1384
  actor?: string;
1379
1385
  dependencyStatuses?: Map<string, TaskStatus> | Record<string, TaskStatus>;
1386
+ config?: CoopConfig | Record<string, unknown>;
1380
1387
  now?: string | Date;
1381
1388
  eventEmitter?: CoopEventEmitter;
1382
1389
  };
@@ -1386,6 +1393,10 @@ type TransitionResult = {
1386
1393
  error?: string;
1387
1394
  };
1388
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[];
1389
1400
  declare function transition(task: Task, targetStatus: TaskStatus, context?: TransitionContext): TransitionResult;
1390
1401
 
1391
1402
  type ValidationLevel = "error" | "warning";
@@ -1428,6 +1439,7 @@ declare const VALID_TRANSITIONS: Map<TaskStatus, Set<TaskStatus>>;
1428
1439
  interface TransitionValidationContext {
1429
1440
  actor?: string;
1430
1441
  dependencyStatuses?: Map<string, TaskStatus> | Record<string, TaskStatus>;
1442
+ config?: CoopConfig | Record<string, unknown>;
1431
1443
  }
1432
1444
  declare function validate_transition(fromStatus: TaskStatus, toStatus: TaskStatus): boolean;
1433
1445
  declare function validateTransition(task: Task, toStatus: TaskStatus, context?: TransitionValidationContext): ValidationError[];
@@ -1541,4 +1553,4 @@ declare function validateRepo(rootDir: string): {
1541
1553
  warnings: string[];
1542
1554
  };
1543
1555
 
1544
- 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
@@ -802,6 +802,12 @@ interface CoopConfig {
802
802
  on_task_transition?: string;
803
803
  on_delivery_complete?: string;
804
804
  };
805
+ workflow?: {
806
+ task_transitions?: Partial<Record<TaskStatus, TaskStatus[]>>;
807
+ track_overrides?: Record<string, {
808
+ task_transitions?: Partial<Record<TaskStatus, TaskStatus[]>>;
809
+ }>;
810
+ };
805
811
  api?: {
806
812
  host?: string;
807
813
  port?: number;
@@ -1377,6 +1383,7 @@ declare function check_unblocked(task: Task, dependencyStatuses?: DependencyStat
1377
1383
  type TransitionContext = {
1378
1384
  actor?: string;
1379
1385
  dependencyStatuses?: Map<string, TaskStatus> | Record<string, TaskStatus>;
1386
+ config?: CoopConfig | Record<string, unknown>;
1380
1387
  now?: string | Date;
1381
1388
  eventEmitter?: CoopEventEmitter;
1382
1389
  };
@@ -1386,6 +1393,10 @@ type TransitionResult = {
1386
1393
  error?: string;
1387
1394
  };
1388
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[];
1389
1400
  declare function transition(task: Task, targetStatus: TaskStatus, context?: TransitionContext): TransitionResult;
1390
1401
 
1391
1402
  type ValidationLevel = "error" | "warning";
@@ -1428,6 +1439,7 @@ declare const VALID_TRANSITIONS: Map<TaskStatus, Set<TaskStatus>>;
1428
1439
  interface TransitionValidationContext {
1429
1440
  actor?: string;
1430
1441
  dependencyStatuses?: Map<string, TaskStatus> | Record<string, TaskStatus>;
1442
+ config?: CoopConfig | Record<string, unknown>;
1431
1443
  }
1432
1444
  declare function validate_transition(fromStatus: TaskStatus, toStatus: TaskStatus): boolean;
1433
1445
  declare function validateTransition(task: Task, toStatus: TaskStatus, context?: TransitionValidationContext): ValidationError[];
@@ -1541,4 +1553,4 @@ declare function validateRepo(rootDir: string): {
1541
1553
  warnings: string[];
1542
1554
  };
1543
1555
 
1544
- 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",
@@ -3374,12 +3376,52 @@ function check_unblocked(task, dependencyStatuses) {
3374
3376
  // src/state/machine.ts
3375
3377
  var VALID_TASK_TRANSITIONS = /* @__PURE__ */ new Map([
3376
3378
  ["todo", /* @__PURE__ */ new Set(["in_progress", "blocked", "canceled"])],
3377
- ["blocked", /* @__PURE__ */ new Set(["todo"])],
3379
+ ["blocked", /* @__PURE__ */ new Set(["todo", "in_progress", "canceled"])],
3378
3380
  ["in_progress", /* @__PURE__ */ new Set(["in_review", "blocked", "todo", "canceled"])],
3379
- ["in_review", /* @__PURE__ */ new Set(["done", "todo"])],
3380
- ["done", /* @__PURE__ */ new Set()],
3381
- ["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"])]
3382
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
+ }
3383
3425
  function toStatusMap2(value) {
3384
3426
  if (!value) return /* @__PURE__ */ new Map();
3385
3427
  if (value instanceof Map) return new Map(value);
@@ -3420,7 +3462,7 @@ function validateGovernanceAndDeps(task, targetStatus, context) {
3420
3462
  return null;
3421
3463
  }
3422
3464
  function transition(task, targetStatus, context = {}) {
3423
- const allowed = VALID_TASK_TRANSITIONS.get(task.status) ?? /* @__PURE__ */ new Set();
3465
+ const allowed = resolveTaskTransitions(context.config).get(task.status) ?? /* @__PURE__ */ new Set();
3424
3466
  if (!allowed.has(targetStatus)) {
3425
3467
  return {
3426
3468
  success: false,
@@ -3974,14 +4016,7 @@ function validateStructural(task, context = {}) {
3974
4016
  }
3975
4017
 
3976
4018
  // src/validator/transition.ts
3977
- var VALID_TRANSITIONS = /* @__PURE__ */ new Map([
3978
- ["todo", /* @__PURE__ */ new Set(["in_progress", "blocked", "canceled"])],
3979
- ["blocked", /* @__PURE__ */ new Set(["todo"])],
3980
- ["in_progress", /* @__PURE__ */ new Set(["in_review", "blocked", "todo", "canceled"])],
3981
- ["in_review", /* @__PURE__ */ new Set(["done", "todo"])],
3982
- ["done", /* @__PURE__ */ new Set()],
3983
- ["canceled", /* @__PURE__ */ new Set(["todo"])]
3984
- ]);
4019
+ var VALID_TRANSITIONS = VALID_TASK_TRANSITIONS;
3985
4020
  function error5(field, rule, message) {
3986
4021
  return { level: "error", field, rule, message };
3987
4022
  }
@@ -3995,14 +4030,15 @@ function asMap2(value) {
3995
4030
  return new Map(Object.entries(value));
3996
4031
  }
3997
4032
  function validate_transition(fromStatus, toStatus) {
3998
- const allowed = VALID_TRANSITIONS.get(fromStatus);
4033
+ const allowed = VALID_TASK_TRANSITIONS.get(fromStatus);
3999
4034
  return Boolean(allowed?.has(toStatus));
4000
4035
  }
4001
4036
  function validateTransition(task, toStatus, context = {}) {
4002
4037
  const issues = [];
4003
4038
  const fromStatus = task.status;
4004
- if (!validate_transition(fromStatus, toStatus)) {
4005
- const allowed = Array.from(VALID_TRANSITIONS.get(fromStatus) ?? []);
4039
+ const transitions = resolveTaskTransitions(context.config);
4040
+ if (!(transitions.get(fromStatus)?.has(toStatus) ?? false)) {
4041
+ const allowed = Array.from(transitions.get(fromStatus) ?? []);
4006
4042
  issues.push(
4007
4043
  error5(
4008
4044
  "status",
@@ -4802,6 +4838,7 @@ export {
4802
4838
  check_permission,
4803
4839
  check_unblocked,
4804
4840
  check_wip,
4841
+ cloneTaskTransitions,
4805
4842
  completeItem,
4806
4843
  complexity_penalty,
4807
4844
  compute_all_readiness,
@@ -4838,6 +4875,7 @@ export {
4838
4875
  get_user_role,
4839
4876
  has_legacy_project_layout,
4840
4877
  has_v2_projects_layout,
4878
+ isTaskStatus,
4841
4879
  is_external_dependency,
4842
4880
  is_project_initialized,
4843
4881
  list_projects,
@@ -4871,6 +4909,7 @@ export {
4871
4909
  renderAgentPrompt,
4872
4910
  repo_default_project_id,
4873
4911
  repo_default_project_name,
4912
+ resolveTaskTransitions,
4874
4913
  resolve_external_dependencies,
4875
4914
  resolve_project,
4876
4915
  risk_penalty,
@@ -4894,6 +4933,7 @@ export {
4894
4933
  validate,
4895
4934
  validateReferential,
4896
4935
  validateRepo,
4936
+ validateResolvedTaskTransitions,
4897
4937
  validateSemantic,
4898
4938
  validateStructural,
4899
4939
  validateTransition,
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@kitsy/coop-core",
3
3
  "description": "Core models, parser, validator, graph, and planning engine for COOP.",
4
- "version": "2.2.5",
4
+ "version": "2.3.0",
5
5
  "license": "MIT",
6
6
  "type": "module",
7
7
  "publishConfig": {