@h-rig/dependency-graph-plugin 0.0.6-alpha.156 → 0.0.6-alpha.158

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.
Files changed (31) hide show
  1. package/dist/src/analysis/blockers.d.ts +35 -0
  2. package/dist/src/analysis/blockers.js +355 -0
  3. package/dist/src/{graph-model → analysis}/dependencyGraph.d.ts +1 -2
  4. package/dist/src/{graph.js → analysis/dependencyGraph.js} +256 -128
  5. package/dist/src/{graph.d.ts → analysis/graph.d.ts} +3 -4
  6. package/dist/src/analysis/graph.js +944 -0
  7. package/dist/src/analysis/rigSelectors.d.ts +26 -0
  8. package/dist/src/analysis/rigSelectors.js +172 -0
  9. package/dist/src/analysis/rollupModel.js +401 -0
  10. package/dist/src/{rollups.d.ts → analysis/rollups.d.ts} +2 -4
  11. package/dist/src/analysis/rollups.js +589 -0
  12. package/dist/src/{graph-model → analysis}/taskGraphCodes.js +1 -1
  13. package/dist/src/{graph-model → analysis}/taskGraphLayout.d.ts +2 -2
  14. package/dist/src/{graph-model → analysis}/taskGraphLayout.js +75 -29
  15. package/dist/src/analysis/taskGraphPrimitives.d.ts +58 -0
  16. package/dist/src/analysis/taskGraphPrimitives.js +528 -0
  17. package/dist/src/index.js +567 -396
  18. package/dist/src/plugin.d.ts +1 -11
  19. package/dist/src/plugin.js +567 -396
  20. package/package.json +3 -6
  21. package/dist/src/graph-model/dependencyGraph.js +0 -485
  22. package/dist/src/graph-model/rollups.js +0 -166
  23. package/dist/src/rollups.js +0 -199
  24. package/dist/src/taskRanking.d.ts +0 -24
  25. package/dist/src/taskRanking.js +0 -160
  26. package/dist/src/taskScore.d.ts +0 -17
  27. package/dist/src/taskScore.js +0 -49
  28. package/dist/src/taskSelection.d.ts +0 -33
  29. package/dist/src/taskSelection.js +0 -181
  30. /package/dist/src/{graph-model/rollups.d.ts → analysis/rollupModel.d.ts} +0 -0
  31. /package/dist/src/{graph-model → analysis}/taskGraphCodes.d.ts +0 -0
@@ -1,17 +1,71 @@
1
1
  // @bun
2
- // packages/dependency-graph-plugin/src/graph-model/taskGraphLayout.ts
2
+ // packages/dependency-graph-plugin/src/analysis/taskGraphPrimitives.ts
3
3
  import {
4
- buildTaskReferenceIndex,
5
- readTaskMetadataStringList,
6
- resolveTaskReference
4
+ OPERATOR_INACTIVE_RUN_STATUSES
7
5
  } from "@rig/contracts";
8
- import {
9
- selectPendingApprovals,
10
- selectRunsByTask,
11
- selectUserInputsForRun
12
- } from "@rig/read-model-plugin";
6
+ function isObjectRecord(value) {
7
+ return typeof value === "object" && value !== null && !Array.isArray(value);
8
+ }
9
+ function readStringList(value) {
10
+ return Array.isArray(value) ? value.filter((entry) => typeof entry === "string" && entry.length > 0) : [];
11
+ }
12
+ function readTaskMetadataStringList(task, key) {
13
+ const taskRecord = task;
14
+ const topLevel = readStringList(taskRecord[key]);
15
+ if (topLevel.length > 0)
16
+ return topLevel;
17
+ const metadata = isObjectRecord(task.metadata) ? task.metadata : null;
18
+ const metadataList = readStringList(metadata?.[key]);
19
+ if (metadataList.length > 0)
20
+ return metadataList;
21
+ if (key === "dependencies") {
22
+ return readStringList(metadata?.deps);
23
+ }
24
+ return [];
25
+ }
26
+ function readTaskSourceIssueId(task) {
27
+ if (typeof task.sourceIssueId === "string" && task.sourceIssueId.length > 0) {
28
+ return task.sourceIssueId;
29
+ }
30
+ const metadata = isObjectRecord(task.metadata) ? task.metadata : null;
31
+ if (typeof metadata?.sourceIssueId === "string" && metadata.sourceIssueId.length > 0) {
32
+ return metadata.sourceIssueId;
33
+ }
34
+ const rigMetadata = isObjectRecord(metadata?._rig) ? metadata._rig : null;
35
+ return typeof rigMetadata?.sourceIssueId === "string" && rigMetadata.sourceIssueId.length > 0 ? rigMetadata.sourceIssueId : null;
36
+ }
37
+ function resolveTaskReference(ref, tasksById, taskIdByExternalRef, taskIdBySourceIssueId) {
38
+ if (tasksById.has(ref))
39
+ return ref;
40
+ return taskIdBySourceIssueId.get(ref) ?? taskIdByExternalRef.get(ref) ?? null;
41
+ }
42
+ function buildTaskReferenceIndex(tasks) {
43
+ return {
44
+ tasksById: new Map(tasks.map((task) => [task.id, task])),
45
+ taskIdByExternalRef: new Map(tasks.flatMap((task) => task.externalId ? [[task.externalId, task.id]] : [])),
46
+ taskIdBySourceIssueId: new Map(tasks.flatMap((task) => {
47
+ const sourceIssueId = readTaskSourceIssueId(task);
48
+ return sourceIssueId ? [[sourceIssueId, task.id]] : [];
49
+ }))
50
+ };
51
+ }
52
+ var TASK_STATUSES = new Set([
53
+ "draft",
54
+ "open",
55
+ "ready",
56
+ "queued",
57
+ "running",
58
+ "in_progress",
59
+ "under_review",
60
+ "blocked",
61
+ "unknown",
62
+ "completed",
63
+ "failed",
64
+ "cancelled",
65
+ "closed"
66
+ ]);
13
67
 
14
- // packages/dependency-graph-plugin/src/graph-model/taskGraphCodes.ts
68
+ // packages/dependency-graph-plugin/src/analysis/taskGraphCodes.ts
15
69
  var TASK_CODE_RE = /^\[([A-Z0-9]+(?:-[A-Z0-9]+)*)\]\s*/;
16
70
  function extractTaskCode(title) {
17
71
  const match = title.match(TASK_CODE_RE);
@@ -32,7 +86,7 @@ function stripTaskCode(label) {
32
86
  return label.replace(TASK_CODE_RE, "");
33
87
  }
34
88
 
35
- // packages/dependency-graph-plugin/src/graph-model/taskGraphLayout.ts
89
+ // packages/dependency-graph-plugin/src/analysis/taskGraphLayout.ts
36
90
  var CARD_WIDTH = 200;
37
91
  var CARD_HEIGHT = 110;
38
92
  var CELL_V_PAD = 12;
@@ -51,14 +105,14 @@ var PALETTE = [
51
105
  { bg: "#132c35", border: "#1783a6", edge: "#53c4e5" },
52
106
  { bg: "#26310f", border: "#6d9a19", edge: "#a7da42" }
53
107
  ];
54
- function isObjectRecord(value) {
108
+ function isObjectRecord2(value) {
55
109
  return typeof value === "object" && value !== null && !Array.isArray(value);
56
110
  }
57
111
  function readIssueType(task) {
58
- const metadata = isObjectRecord(task.metadata) ? task.metadata : null;
112
+ const metadata = isObjectRecord2(task.metadata) ? task.metadata : null;
59
113
  if (typeof metadata?.issueType === "string")
60
114
  return metadata.issueType;
61
- const raw = isObjectRecord(metadata?.raw) ? metadata.raw : null;
115
+ const raw = isObjectRecord2(metadata?.raw) ? metadata.raw : null;
62
116
  return typeof raw?.issueType === "string" ? raw.issueType : null;
63
117
  }
64
118
  function isGraphTask(task) {
@@ -157,7 +211,7 @@ function computeDepths(ids, edges) {
157
211
  }
158
212
  return memo;
159
213
  }
160
- function buildTaskGraphLayout(snapshot, tasks, options) {
214
+ function buildTaskGraphLayout(tasks, options) {
161
215
  const showParentChild = options?.showParentChild ?? false;
162
216
  const graphTasks = tasks.filter(isGraphTask);
163
217
  if (graphTasks.length === 0) {
@@ -288,7 +342,6 @@ function buildTaskGraphLayout(snapshot, tasks, options) {
288
342
  x: (colX[index] ?? 0) + CELL_H_PAD,
289
343
  width: CARD_WIDTH
290
344
  }));
291
- const pendingApprovalRunIds = new Set(selectPendingApprovals(snapshot).map((approval) => approval.runId));
292
345
  const nodes = [];
293
346
  for (const [rowIndex, [rowKey]] of orderedRows.entries()) {
294
347
  for (let stage = 0;stage <= maxStage; stage += 1) {
@@ -297,13 +350,6 @@ function buildTaskGraphLayout(snapshot, tasks, options) {
297
350
  const baseY = (rowY[rowIndex] ?? 0) + CELL_V_PAD;
298
351
  const palette = PALETTE[rowIndex % PALETTE.length];
299
352
  for (const [stackIndex, task] of cellTasks.entries()) {
300
- const runs = selectRunsByTask(snapshot, task.id);
301
- const runIds = new Set(runs.map((run) => run.id));
302
- const hasApprovals = runs.some((run) => pendingApprovalRunIds.has(run.id));
303
- const hasPendingUserInput = runs.some((run) => selectUserInputsForRun(snapshot, run.id).some((request) => request.status === "pending"));
304
- const hasRejectedReview = (snapshot?.reviews ?? []).some((review) => runIds.has(review.runId) && review.status === "rejected");
305
- const hasFailedValidations = (snapshot?.validations ?? []).some((validation) => runIds.has(validation.runId) && validation.status === "failed");
306
- const artifactCount = (snapshot?.artifacts ?? []).filter((artifact) => runIds.has(artifact.runId)).length;
307
353
  nodes.push({
308
354
  id: task.id,
309
355
  taskId: task.id,
@@ -321,12 +367,12 @@ function buildTaskGraphLayout(snapshot, tasks, options) {
321
367
  strippedTitle: stripTaskCode(task.title),
322
368
  depsIn: depsIn.get(task.id) ?? 0,
323
369
  depsOut: depsOut.get(task.id) ?? 0,
324
- runCount: runs.length,
325
- hasApprovals,
326
- hasPendingUserInput,
327
- hasRejectedReview,
328
- hasFailedValidations,
329
- artifactCount
370
+ runCount: 0,
371
+ hasApprovals: false,
372
+ hasPendingUserInput: false,
373
+ hasRejectedReview: false,
374
+ hasFailedValidations: false,
375
+ artifactCount: 0
330
376
  });
331
377
  }
332
378
  }
@@ -0,0 +1,58 @@
1
+ import { type ClientTaskProjection, type RunJournalProjection, type RunStatus, type TaskDependencyBadgeSummary, type TaskDependencyProjection, type TaskProjectionInput, type TaskScopeInput, type TaskSummary } from "@rig/contracts";
2
+ export declare function readTaskMetadataStringList(task: TaskDependencyProjection, key: "dependencies" | "parentChildDeps" | "labels"): string[];
3
+ export declare function readTaskBlockingDependencyRefs(task: TaskDependencyProjection): string[];
4
+ export declare function readTaskDependencyRefs(task: TaskDependencyProjection): string[];
5
+ export declare function readTaskSourceIssueId(task: TaskDependencyProjection): string | null;
6
+ export declare function readTaskScope(task: TaskDependencyProjection): string[];
7
+ export declare function disjointScope(left: TaskScopeInput, right: TaskScopeInput): boolean;
8
+ export declare function resolveTaskReference(ref: string, tasksById: ReadonlyMap<string, TaskDependencyProjection>, taskIdByExternalRef: ReadonlyMap<string, string>, taskIdBySourceIssueId: ReadonlyMap<string, string>): string | null;
9
+ export declare function buildTaskReferenceIndex<T extends TaskDependencyProjection>(tasks: readonly T[]): {
10
+ readonly tasksById: Map<string, T>;
11
+ readonly taskIdByExternalRef: Map<string, string>;
12
+ readonly taskIdBySourceIssueId: Map<string, string>;
13
+ };
14
+ export declare function computeTaskBlockingDepths<T extends TaskDependencyProjection>(tasks: readonly T[]): Map<string, number>;
15
+ export declare function isTaskTerminalStatus(status: string | null | undefined): boolean;
16
+ export declare function computeTaskDependencyBadges(tasks: readonly TaskDependencyProjection[]): Map<string, TaskDependencyBadgeSummary>;
17
+ export declare function normalizeTaskStatus(status: unknown): TaskSummary["status"];
18
+ export declare function toTaskDependencyProjection(task: TaskProjectionInput): ClientTaskProjection;
19
+ export declare function toTaskSummary(task: TaskProjectionInput, defaults?: {
20
+ readonly workspaceId?: string;
21
+ readonly graphId?: string | null;
22
+ }): TaskSummary;
23
+ export declare function selectNextReadyTaskByPriority<T extends TaskDependencyProjection>(tasks: readonly T[], options?: {
24
+ readonly excludeTaskIds?: Iterable<string>;
25
+ readonly filter?: (task: T) => boolean;
26
+ }): T | null;
27
+ export type RigTaskSessionProjection = Pick<RunJournalProjection, "record" | "status" | "lastEventAt"> & {
28
+ readonly taskId?: string | null;
29
+ };
30
+ export interface RigTaskStatusGroupingInput<T extends TaskDependencyProjection = TaskDependencyProjection> {
31
+ readonly tasks: readonly T[];
32
+ readonly sessions?: readonly RigTaskSessionProjection[];
33
+ readonly workspaceId?: string | null;
34
+ }
35
+ export interface RigTaskStatusGroup<T extends TaskDependencyProjection = TaskDependencyProjection> {
36
+ readonly status: string;
37
+ readonly tasks: readonly T[];
38
+ }
39
+ export declare function projectTaskStatusForGrouping(status: string | null | undefined): string;
40
+ export declare function projectRunStatusForTaskGrouping(status: RunStatus | null | undefined): string | null;
41
+ export declare function projectTaskStatusWithSessions(task: TaskDependencyProjection, sessionsByTask?: ReadonlyMap<string, RigTaskSessionProjection>): string;
42
+ export declare function selectTasksGroupedByStatus<T extends TaskDependencyProjection>(input: RigTaskStatusGroupingInput<T>): Array<RigTaskStatusGroup<T>>;
43
+ export declare function normalizeTaskAssigneeFilter(assignee: string | null | undefined, currentUserLogin?: string | null): string | null;
44
+ export declare function readTaskAssigneeLogins(task: TaskDependencyProjection): readonly string[];
45
+ export declare function taskMatchesAssigneeFilter(task: TaskDependencyProjection, assignee: string | null | undefined, options?: {
46
+ readonly currentUserLogin?: string | null;
47
+ }): boolean;
48
+ export declare function selectTasksAssignedTo<T extends TaskDependencyProjection>(tasks: readonly T[], assignee: string | null | undefined, options?: {
49
+ readonly currentUserLogin?: string | null;
50
+ }): T[];
51
+ export declare function selectTasksAssignedToMe<T extends TaskDependencyProjection>(tasks: readonly T[], currentUserLogin: string | null | undefined): T[];
52
+ /** Keep only the most-recently-updated run per task id. */
53
+ export declare function latestRunByTaskId<T extends {
54
+ readonly taskId: string | null;
55
+ readonly updatedAt: string | null;
56
+ readonly startedAt: string | null;
57
+ }>(runs: readonly T[]): Map<string, T>;
58
+ export declare function isOperatorActiveRunStatus(status: unknown): boolean;