feat(web): build project loop workspace
This commit is contained in:
@@ -7,6 +7,7 @@
|
||||
".": "./src/index.ts",
|
||||
"./agent-os": "./src/agent-os.ts",
|
||||
"./project": "./src/project.ts",
|
||||
"./project-work": "./src/project-work.ts",
|
||||
"./signal": "./src/signal.ts"
|
||||
},
|
||||
"scripts": {
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
// oxlint-disable-next-line no-barrel-file -- The package root intentionally exposes its public modules.
|
||||
export * from "./agent-os";
|
||||
export * from "./project";
|
||||
export * from "./project-work";
|
||||
export * from "./signal";
|
||||
|
||||
30
packages/primitives/src/project-work.test.ts
Normal file
30
packages/primitives/src/project-work.test.ts
Normal file
@@ -0,0 +1,30 @@
|
||||
import { describe, expect, test } from "vitest";
|
||||
|
||||
import { getProjectWorkProgress, getProjectWorkStatus } from "./project-work";
|
||||
|
||||
describe("project work state mapping", () => {
|
||||
test("maps issue and run statuses to the same product language", () => {
|
||||
expect(getProjectWorkStatus("working")).toEqual({
|
||||
label: "In progress",
|
||||
phase: "active",
|
||||
verification: "running",
|
||||
});
|
||||
expect(getProjectWorkStatus("needs-input")).toEqual({
|
||||
label: "Needs your input",
|
||||
phase: "waiting",
|
||||
verification: "blocked",
|
||||
});
|
||||
});
|
||||
|
||||
test("keeps progress monotonic through the normal loop", () => {
|
||||
expect(getProjectWorkProgress("open")).toBeLessThan(
|
||||
getProjectWorkProgress("queued")
|
||||
);
|
||||
expect(getProjectWorkProgress("queued")).toBeLessThan(
|
||||
getProjectWorkProgress("working")
|
||||
);
|
||||
expect(getProjectWorkProgress("working")).toBeLessThan(
|
||||
getProjectWorkProgress("completed")
|
||||
);
|
||||
});
|
||||
});
|
||||
115
packages/primitives/src/project-work.ts
Normal file
115
packages/primitives/src/project-work.ts
Normal file
@@ -0,0 +1,115 @@
|
||||
export const PROJECT_ISSUE_STATUSES = [
|
||||
"open",
|
||||
"queued",
|
||||
"working",
|
||||
"needs-input",
|
||||
"completed",
|
||||
"failed",
|
||||
] as const;
|
||||
|
||||
export type ProjectIssueStatus = (typeof PROJECT_ISSUE_STATUSES)[number];
|
||||
|
||||
export const PROJECT_RUN_STATUSES = [
|
||||
"ready",
|
||||
"queued",
|
||||
"working",
|
||||
"needs-input",
|
||||
"completed",
|
||||
"failed",
|
||||
] as const;
|
||||
|
||||
export type ProjectRunStatus = (typeof PROJECT_RUN_STATUSES)[number];
|
||||
|
||||
export type ProjectWorkPhase =
|
||||
| "captured"
|
||||
| "queued"
|
||||
| "active"
|
||||
| "waiting"
|
||||
| "completed"
|
||||
| "failed";
|
||||
|
||||
export type ProjectVerificationStatus =
|
||||
| "not-started"
|
||||
| "running"
|
||||
| "blocked"
|
||||
| "passed"
|
||||
| "failed";
|
||||
|
||||
export interface ProjectWorkStatus {
|
||||
readonly label: string;
|
||||
readonly phase: ProjectWorkPhase;
|
||||
readonly verification: ProjectVerificationStatus;
|
||||
}
|
||||
|
||||
const STATUS_MAP: Readonly<
|
||||
Record<ProjectIssueStatus | ProjectRunStatus, ProjectWorkStatus>
|
||||
> = {
|
||||
completed: {
|
||||
label: "Completed",
|
||||
phase: "completed",
|
||||
verification: "passed",
|
||||
},
|
||||
failed: {
|
||||
label: "Failed",
|
||||
phase: "failed",
|
||||
verification: "failed",
|
||||
},
|
||||
"needs-input": {
|
||||
label: "Needs your input",
|
||||
phase: "waiting",
|
||||
verification: "blocked",
|
||||
},
|
||||
open: {
|
||||
label: "Ready to start",
|
||||
phase: "captured",
|
||||
verification: "not-started",
|
||||
},
|
||||
queued: {
|
||||
label: "Queued",
|
||||
phase: "queued",
|
||||
verification: "not-started",
|
||||
},
|
||||
ready: {
|
||||
label: "Ready",
|
||||
phase: "queued",
|
||||
verification: "not-started",
|
||||
},
|
||||
working: {
|
||||
label: "In progress",
|
||||
phase: "active",
|
||||
verification: "running",
|
||||
},
|
||||
};
|
||||
|
||||
export const getProjectWorkStatus = (
|
||||
status: ProjectIssueStatus | ProjectRunStatus
|
||||
): ProjectWorkStatus => STATUS_MAP[status];
|
||||
|
||||
export const getProjectWorkProgress = (
|
||||
status: ProjectIssueStatus | ProjectRunStatus
|
||||
): number => {
|
||||
switch (status) {
|
||||
case "completed": {
|
||||
return 100;
|
||||
}
|
||||
case "failed": {
|
||||
return 58;
|
||||
}
|
||||
case "needs-input": {
|
||||
return 78;
|
||||
}
|
||||
case "working": {
|
||||
return 68;
|
||||
}
|
||||
case "queued":
|
||||
case "ready": {
|
||||
return 24;
|
||||
}
|
||||
case "open": {
|
||||
return 8;
|
||||
}
|
||||
default: {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user