@jterrats/open-orchestra 0.1.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.
Files changed (93) hide show
  1. package/AGENTS.md +151 -0
  2. package/CLAUDE.md +157 -0
  3. package/README.md +60 -0
  4. package/bin/orchestra.js +8 -0
  5. package/dist/args.d.ts +3 -0
  6. package/dist/args.js +30 -0
  7. package/dist/args.js.map +1 -0
  8. package/dist/cli.d.ts +2 -0
  9. package/dist/cli.js +190 -0
  10. package/dist/cli.js.map +1 -0
  11. package/dist/commands.d.ts +44 -0
  12. package/dist/commands.js +883 -0
  13. package/dist/commands.js.map +1 -0
  14. package/dist/constants.d.ts +15 -0
  15. package/dist/constants.js +69 -0
  16. package/dist/constants.js.map +1 -0
  17. package/dist/defaults.d.ts +72 -0
  18. package/dist/defaults.js +694 -0
  19. package/dist/defaults.js.map +1 -0
  20. package/dist/fs-utils.d.ts +8 -0
  21. package/dist/fs-utils.js +35 -0
  22. package/dist/fs-utils.js.map +1 -0
  23. package/dist/model-providers.d.ts +19 -0
  24. package/dist/model-providers.js +78 -0
  25. package/dist/model-providers.js.map +1 -0
  26. package/dist/types.d.ts +550 -0
  27. package/dist/types.js +2 -0
  28. package/dist/types.js.map +1 -0
  29. package/dist/validation.d.ts +10 -0
  30. package/dist/validation.js +163 -0
  31. package/dist/validation.js.map +1 -0
  32. package/dist/web-api.d.ts +16 -0
  33. package/dist/web-api.js +220 -0
  34. package/dist/web-api.js.map +1 -0
  35. package/dist/web-chart-contracts.d.ts +13 -0
  36. package/dist/web-chart-contracts.js +13 -0
  37. package/dist/web-chart-contracts.js.map +1 -0
  38. package/dist/web-console.d.ts +1 -0
  39. package/dist/web-console.js +232 -0
  40. package/dist/web-console.js.map +1 -0
  41. package/dist/web-evidence.d.ts +25 -0
  42. package/dist/web-evidence.js +67 -0
  43. package/dist/web-evidence.js.map +1 -0
  44. package/dist/web-playwright.d.ts +3 -0
  45. package/dist/web-playwright.js +14 -0
  46. package/dist/web-playwright.js.map +1 -0
  47. package/dist/web-roles.d.ts +33 -0
  48. package/dist/web-roles.js +70 -0
  49. package/dist/web-roles.js.map +1 -0
  50. package/dist/workflow-gates.d.ts +7 -0
  51. package/dist/workflow-gates.js +291 -0
  52. package/dist/workflow-gates.js.map +1 -0
  53. package/dist/workflow-services.d.ts +56 -0
  54. package/dist/workflow-services.js +1240 -0
  55. package/dist/workflow-services.js.map +1 -0
  56. package/dist/workspace-validator.d.ts +6 -0
  57. package/dist/workspace-validator.js +189 -0
  58. package/dist/workspace-validator.js.map +1 -0
  59. package/dist/workspace.d.ts +10 -0
  60. package/dist/workspace.js +72 -0
  61. package/dist/workspace.js.map +1 -0
  62. package/docs/multi-agent-orchestrator-backlog.md +445 -0
  63. package/docs/multi-agent-orchestrator-sprint-1.md +433 -0
  64. package/docs/orchestra-mvp.md +176 -0
  65. package/package.json +63 -0
  66. package/rules/agent-collaboration.mdc +58 -0
  67. package/rules/agent-roles.mdc +105 -0
  68. package/rules/ai-assisted-development.mdc +31 -0
  69. package/rules/api-design.mdc +31 -0
  70. package/rules/architecture-decisions.mdc +27 -0
  71. package/rules/code-review-engineering.mdc +34 -0
  72. package/rules/concurrency-async.mdc +32 -0
  73. package/rules/configuration-management.mdc +31 -0
  74. package/rules/data-modeling-domain.mdc +31 -0
  75. package/rules/delivery-quality-gates.mdc +40 -0
  76. package/rules/dependency-management.mdc +31 -0
  77. package/rules/devops-tooling.mdc +55 -0
  78. package/rules/documentation-standards.mdc +26 -0
  79. package/rules/dry-clean-code.mdc +30 -0
  80. package/rules/error-handling.mdc +28 -0
  81. package/rules/frontend-engineering.mdc +32 -0
  82. package/rules/git-discipline.mdc +39 -0
  83. package/rules/infra-data-encryption.mdc +81 -0
  84. package/rules/performance-reliability.mdc +32 -0
  85. package/rules/readiness-done.mdc +32 -0
  86. package/rules/release-rollback.mdc +32 -0
  87. package/rules/rule-composition.mdc +28 -0
  88. package/rules/security-guardrails.mdc +37 -0
  89. package/rules/solid-architecture.mdc +32 -0
  90. package/rules/static-analysis-githooks.mdc +32 -0
  91. package/rules/testing-discipline.mdc +42 -0
  92. package/rules/ux-ui-product-experience.mdc +51 -0
  93. package/rules/work-intake-sequencing.mdc +39 -0
@@ -0,0 +1,163 @@
1
+ import { EVIDENCE_TYPES, REVIEW_RESULTS, SEVERITIES, TASK_STATUSES, } from "./constants.js";
2
+ export function assertObject(value, name) {
3
+ if (!value || typeof value !== "object" || Array.isArray(value)) {
4
+ throw new Error(`${name} must be an object`);
5
+ }
6
+ }
7
+ export function validateLocks(locks, taskIds, roleIds) {
8
+ if (!Array.isArray(locks)) {
9
+ throw new Error("locks must be an array");
10
+ }
11
+ const lockIds = new Set();
12
+ const claimedPaths = new Map();
13
+ for (const lock of locks) {
14
+ assertObject(lock, "lock");
15
+ assertNonEmptyString(lock.id, "lock.id");
16
+ assertNonEmptyString(lock.taskId, `lock ${lock.id}.taskId`);
17
+ assertNonEmptyString(lock.ownerRole, `lock ${lock.id}.ownerRole`);
18
+ assertNonEmptyString(lock.path, `lock ${lock.id}.path`);
19
+ assertNonEmptyString(lock.reason, `lock ${lock.id}.reason`);
20
+ assertNonEmptyString(lock.createdAt, `lock ${lock.id}.createdAt`);
21
+ if (lockIds.has(lock.id)) {
22
+ throw new Error(`duplicate lock id: ${lock.id}`);
23
+ }
24
+ if (!taskIds.has(lock.taskId)) {
25
+ throw new Error(`lock ${lock.id} has unknown task: ${lock.taskId}`);
26
+ }
27
+ if (!roleIds.has(lock.ownerRole)) {
28
+ throw new Error(`lock ${lock.id} has unknown owner role: ${lock.ownerRole}`);
29
+ }
30
+ if (claimedPaths.has(lock.path)) {
31
+ throw new Error(`lock ${lock.id} overlaps path already claimed by ${claimedPaths.get(lock.path)}`);
32
+ }
33
+ lockIds.add(lock.id);
34
+ claimedPaths.set(lock.path, lock.id);
35
+ }
36
+ }
37
+ export function taskIdsFor(tasks) {
38
+ return new Set(tasks.map((task) => task.id));
39
+ }
40
+ export function assertNonEmptyString(value, name) {
41
+ if (typeof value !== "string" || value.trim() === "") {
42
+ throw new Error(`${name} must be a non-empty string`);
43
+ }
44
+ }
45
+ export function validateRoles(roles) {
46
+ if (!Array.isArray(roles)) {
47
+ throw new Error("roles must be an array");
48
+ }
49
+ const ids = new Set();
50
+ for (const role of roles) {
51
+ assertObject(role, "role");
52
+ assertNonEmptyString(role.id, "role.id");
53
+ assertNonEmptyString(role.description, `role ${role.id}.description`);
54
+ if (!Array.isArray(role.capabilities) || role.capabilities.length === 0) {
55
+ throw new Error(`role ${role.id}.capabilities must be a non-empty array`);
56
+ }
57
+ validateOptionalStringArray(role.requiredHandoffFields, "role " + role.id + ".requiredHandoffFields");
58
+ validateOptionalStringArray(role.blockingAuthority, "role " + role.id + ".blockingAuthority");
59
+ validateOptionalStringArray(role.activationCriteria, "role " + role.id + ".activationCriteria");
60
+ validateOptionalStringArray(role.expectedEvidence, "role " + role.id + ".expectedEvidence");
61
+ validateOptionalStringArray(role.gateParticipation, "role " + role.id + ".gateParticipation");
62
+ if (ids.has(role.id)) {
63
+ throw new Error(`duplicate role id: ${role.id}`);
64
+ }
65
+ ids.add(role.id);
66
+ }
67
+ return ids;
68
+ }
69
+ export function validateTasks(tasks, roleIds) {
70
+ if (!Array.isArray(tasks)) {
71
+ throw new Error("tasks must be an array");
72
+ }
73
+ const taskIds = new Set();
74
+ for (const task of tasks) {
75
+ assertObject(task, "task");
76
+ assertNonEmptyString(task.id, "task.id");
77
+ assertNonEmptyString(task.title, `task ${task.id}.title`);
78
+ assertNonEmptyString(task.ownerRole, `task ${task.id}.ownerRole`);
79
+ if (!roleIds.has(task.ownerRole)) {
80
+ throw new Error(`task ${task.id} has unknown owner role: ${task.ownerRole}`);
81
+ }
82
+ if (typeof task.status !== "string" ||
83
+ !TASK_STATUSES.includes(task.status)) {
84
+ throw new Error(`task ${task.id} has invalid status: ${task.status}`);
85
+ }
86
+ if (taskIds.has(task.id)) {
87
+ throw new Error(`duplicate task id: ${task.id}`);
88
+ }
89
+ taskIds.add(task.id);
90
+ validateOptionalStringArray(task.paths, `task ${task.id}.paths`);
91
+ }
92
+ for (const task of tasks) {
93
+ const dependencies = task.dependencies ?? [];
94
+ if (!Array.isArray(dependencies)) {
95
+ throw new Error(`task ${task.id}.dependencies must be an array`);
96
+ }
97
+ for (const dependency of dependencies) {
98
+ if (!taskIds.has(dependency)) {
99
+ throw new Error(`task ${task.id} has unknown dependency: ${dependency}`);
100
+ }
101
+ }
102
+ }
103
+ }
104
+ function validateOptionalStringArray(value, name) {
105
+ if (value === undefined) {
106
+ return;
107
+ }
108
+ if (!Array.isArray(value)) {
109
+ throw new Error(`${name} must be an array`);
110
+ }
111
+ for (const item of value) {
112
+ assertNonEmptyString(item, `${name}[]`);
113
+ }
114
+ }
115
+ export function validateReviewInput(input, roleIds) {
116
+ assertNonEmptyString(input.task, "task");
117
+ assertNonEmptyString(input.role, "role");
118
+ if (!roleIds.has(input.role)) {
119
+ throw new Error(`unknown reviewer role: ${input.role}`);
120
+ }
121
+ if (!REVIEW_RESULTS.includes(input.result)) {
122
+ throw new Error(`result must be one of: ${REVIEW_RESULTS.join(", ")}`);
123
+ }
124
+ if (!SEVERITIES.includes(input.severity)) {
125
+ throw new Error(`severity must be one of: ${SEVERITIES.join(", ")}`);
126
+ }
127
+ assertNonEmptyString(input.findings, "findings");
128
+ assertNonEmptyString(input.recommendation, "recommendation");
129
+ }
130
+ export function validateEvidenceInput(input, roleIds) {
131
+ assertNonEmptyString(input.task, "task");
132
+ assertNonEmptyString(input.role, "role");
133
+ if (!roleIds.has(input.role)) {
134
+ throw new Error(`unknown evidence role: ${input.role}`);
135
+ }
136
+ if (!EVIDENCE_TYPES.includes(input.type)) {
137
+ throw new Error(`type must be one of: ${EVIDENCE_TYPES.join(", ")}`);
138
+ }
139
+ assertNonEmptyString(input.summary, "summary");
140
+ }
141
+ export function validateReadiness(task) {
142
+ const missing = [];
143
+ const fields = [
144
+ "backlogItem",
145
+ "goal",
146
+ "scope",
147
+ "acceptanceCriteria",
148
+ "assumptions",
149
+ "risks",
150
+ "testStrategy",
151
+ ];
152
+ for (const field of fields) {
153
+ const value = task[field];
154
+ if (Array.isArray(value) ? value.length === 0 : !value) {
155
+ missing.push(field);
156
+ }
157
+ }
158
+ return {
159
+ isReady: missing.length === 0 || Boolean(task.mechanicalOverride?.rationale),
160
+ missing,
161
+ };
162
+ }
163
+ //# sourceMappingURL=validation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validation.js","sourceRoot":"","sources":["../src/validation.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,cAAc,EACd,cAAc,EACd,UAAU,EACV,aAAa,GACd,MAAM,gBAAgB,CAAC;AAWxB,MAAM,UAAU,YAAY,CAC1B,KAAc,EACd,IAAY;IAEZ,IAAI,CAAC,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QAChE,MAAM,IAAI,KAAK,CAAC,GAAG,IAAI,oBAAoB,CAAC,CAAC;IAC/C,CAAC;AACH,CAAC;AAED,MAAM,UAAU,aAAa,CAC3B,KAAc,EACd,OAAoB,EACpB,OAAoB;IAEpB,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QAC1B,MAAM,IAAI,KAAK,CAAC,wBAAwB,CAAC,CAAC;IAC5C,CAAC;IACD,MAAM,OAAO,GAAG,IAAI,GAAG,EAAU,CAAC;IAClC,MAAM,YAAY,GAAG,IAAI,GAAG,EAAkB,CAAC;IAC/C,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QAC3B,oBAAoB,CAAC,IAAI,CAAC,EAAE,EAAE,SAAS,CAAC,CAAC;QACzC,oBAAoB,CAAC,IAAI,CAAC,MAAM,EAAE,QAAQ,IAAI,CAAC,EAAE,SAAS,CAAC,CAAC;QAC5D,oBAAoB,CAAC,IAAI,CAAC,SAAS,EAAE,QAAQ,IAAI,CAAC,EAAE,YAAY,CAAC,CAAC;QAClE,oBAAoB,CAAC,IAAI,CAAC,IAAI,EAAE,QAAQ,IAAI,CAAC,EAAE,OAAO,CAAC,CAAC;QACxD,oBAAoB,CAAC,IAAI,CAAC,MAAM,EAAE,QAAQ,IAAI,CAAC,EAAE,SAAS,CAAC,CAAC;QAC5D,oBAAoB,CAAC,IAAI,CAAC,SAAS,EAAE,QAAQ,IAAI,CAAC,EAAE,YAAY,CAAC,CAAC;QAClE,IAAI,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC;YACzB,MAAM,IAAI,KAAK,CAAC,sBAAsB,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC;QACnD,CAAC;QACD,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;YAC9B,MAAM,IAAI,KAAK,CAAC,QAAQ,IAAI,CAAC,EAAE,sBAAsB,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;QACtE,CAAC;QACD,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC;YACjC,MAAM,IAAI,KAAK,CACb,QAAQ,IAAI,CAAC,EAAE,4BAA4B,IAAI,CAAC,SAAS,EAAE,CAC5D,CAAC;QACJ,CAAC;QACD,IAAI,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;YAChC,MAAM,IAAI,KAAK,CACb,QAAQ,IAAI,CAAC,EAAE,qCAAqC,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAClF,CAAC;QACJ,CAAC;QACD,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACrB,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC;IACvC,CAAC;AACH,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,KAAa;IACtC,OAAO,IAAI,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;AAC/C,CAAC;AAED,MAAM,UAAU,oBAAoB,CAClC,KAAc,EACd,IAAY;IAEZ,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;QACrD,MAAM,IAAI,KAAK,CAAC,GAAG,IAAI,6BAA6B,CAAC,CAAC;IACxD,CAAC;AACH,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,KAAc;IAC1C,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QAC1B,MAAM,IAAI,KAAK,CAAC,wBAAwB,CAAC,CAAC;IAC5C,CAAC;IACD,MAAM,GAAG,GAAG,IAAI,GAAG,EAAU,CAAC;IAC9B,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QAC3B,oBAAoB,CAAC,IAAI,CAAC,EAAE,EAAE,SAAS,CAAC,CAAC;QACzC,oBAAoB,CAAC,IAAI,CAAC,WAAW,EAAE,QAAQ,IAAI,CAAC,EAAE,cAAc,CAAC,CAAC;QACtE,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,YAAY,CAAC,IAAI,IAAI,CAAC,YAAY,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACxE,MAAM,IAAI,KAAK,CAAC,QAAQ,IAAI,CAAC,EAAE,yCAAyC,CAAC,CAAC;QAC5E,CAAC;QACD,2BAA2B,CACzB,IAAI,CAAC,qBAAqB,EAC1B,OAAO,GAAG,IAAI,CAAC,EAAE,GAAG,wBAAwB,CAC7C,CAAC;QACF,2BAA2B,CACzB,IAAI,CAAC,iBAAiB,EACtB,OAAO,GAAG,IAAI,CAAC,EAAE,GAAG,oBAAoB,CACzC,CAAC;QACF,2BAA2B,CACzB,IAAI,CAAC,kBAAkB,EACvB,OAAO,GAAG,IAAI,CAAC,EAAE,GAAG,qBAAqB,CAC1C,CAAC;QACF,2BAA2B,CACzB,IAAI,CAAC,gBAAgB,EACrB,OAAO,GAAG,IAAI,CAAC,EAAE,GAAG,mBAAmB,CACxC,CAAC;QACF,2BAA2B,CACzB,IAAI,CAAC,iBAAiB,EACtB,OAAO,GAAG,IAAI,CAAC,EAAE,GAAG,oBAAoB,CACzC,CAAC;QACF,IAAI,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC;YACrB,MAAM,IAAI,KAAK,CAAC,sBAAsB,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC;QACnD,CAAC;QACD,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACnB,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,KAAc,EAAE,OAAoB;IAChE,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QAC1B,MAAM,IAAI,KAAK,CAAC,wBAAwB,CAAC,CAAC;IAC5C,CAAC;IACD,MAAM,OAAO,GAAG,IAAI,GAAG,EAAU,CAAC;IAClC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QAC3B,oBAAoB,CAAC,IAAI,CAAC,EAAE,EAAE,SAAS,CAAC,CAAC;QACzC,oBAAoB,CAAC,IAAI,CAAC,KAAK,EAAE,QAAQ,IAAI,CAAC,EAAE,QAAQ,CAAC,CAAC;QAC1D,oBAAoB,CAAC,IAAI,CAAC,SAAS,EAAE,QAAQ,IAAI,CAAC,EAAE,YAAY,CAAC,CAAC;QAClE,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC;YACjC,MAAM,IAAI,KAAK,CACb,QAAQ,IAAI,CAAC,EAAE,4BAA4B,IAAI,CAAC,SAAS,EAAE,CAC5D,CAAC;QACJ,CAAC;QACD,IACE,OAAO,IAAI,CAAC,MAAM,KAAK,QAAQ;YAC/B,CAAC,aAAa,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAwB,CAAC,EACtD,CAAC;YACD,MAAM,IAAI,KAAK,CAAC,QAAQ,IAAI,CAAC,EAAE,wBAAwB,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;QACxE,CAAC;QACD,IAAI,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC;YACzB,MAAM,IAAI,KAAK,CAAC,sBAAsB,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC;QACnD,CAAC;QACD,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACrB,2BAA2B,CAAC,IAAI,CAAC,KAAK,EAAE,QAAQ,IAAI,CAAC,EAAE,QAAQ,CAAC,CAAC;IACnE,CAAC;IACD,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,YAAY,GAAG,IAAI,CAAC,YAAY,IAAI,EAAE,CAAC;QAC7C,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,YAAY,CAAC,EAAE,CAAC;YACjC,MAAM,IAAI,KAAK,CAAC,QAAQ,IAAI,CAAC,EAAE,gCAAgC,CAAC,CAAC;QACnE,CAAC;QACD,KAAK,MAAM,UAAU,IAAI,YAAY,EAAE,CAAC;YACtC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,CAAC;gBAC7B,MAAM,IAAI,KAAK,CACb,QAAQ,IAAI,CAAC,EAAE,4BAA4B,UAAU,EAAE,CACxD,CAAC;YACJ,CAAC;QACH,CAAC;IACH,CAAC;AACH,CAAC;AAED,SAAS,2BAA2B,CAAC,KAAc,EAAE,IAAY;IAC/D,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QACxB,OAAO;IACT,CAAC;IACD,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QAC1B,MAAM,IAAI,KAAK,CAAC,GAAG,IAAI,mBAAmB,CAAC,CAAC;IAC9C,CAAC;IACD,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,oBAAoB,CAAC,IAAI,EAAE,GAAG,IAAI,IAAI,CAAC,CAAC;IAC1C,CAAC;AACH,CAAC;AAED,MAAM,UAAU,mBAAmB,CACjC,KAAkB,EAClB,OAAoB;IAEpB,oBAAoB,CAAC,KAAK,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IACzC,oBAAoB,CAAC,KAAK,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IACzC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;QAC7B,MAAM,IAAI,KAAK,CAAC,0BAA0B,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC;IAC1D,CAAC;IACD,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC,KAAK,CAAC,MAAsB,CAAC,EAAE,CAAC;QAC3D,MAAM,IAAI,KAAK,CAAC,0BAA0B,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACzE,CAAC;IACD,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,KAAK,CAAC,QAAoB,CAAC,EAAE,CAAC;QACrD,MAAM,IAAI,KAAK,CAAC,4BAA4B,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACvE,CAAC;IACD,oBAAoB,CAAC,KAAK,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC;IACjD,oBAAoB,CAAC,KAAK,CAAC,cAAc,EAAE,gBAAgB,CAAC,CAAC;AAC/D,CAAC;AAED,MAAM,UAAU,qBAAqB,CACnC,KAAoB,EACpB,OAAoB;IAEpB,oBAAoB,CAAC,KAAK,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IACzC,oBAAoB,CAAC,KAAK,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IACzC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;QAC7B,MAAM,IAAI,KAAK,CAAC,0BAA0B,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC;IAC1D,CAAC;IACD,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAoB,CAAC,EAAE,CAAC;QACzD,MAAM,IAAI,KAAK,CAAC,wBAAwB,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACvE,CAAC;IACD,oBAAoB,CAAC,KAAK,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;AACjD,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,IAAU;IAC1C,MAAM,OAAO,GAAa,EAAE,CAAC;IAC7B,MAAM,MAAM,GAAG;QACb,aAAa;QACb,MAAM;QACN,OAAO;QACP,oBAAoB;QACpB,aAAa;QACb,OAAO;QACP,cAAc;KACf,CAAC;IACF,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,MAAM,KAAK,GAAG,IAAI,CAAC,KAAmB,CAAC,CAAC;QACxC,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC;YACvD,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACtB,CAAC;IACH,CAAC;IACD,OAAO;QACL,OAAO,EACL,OAAO,CAAC,MAAM,KAAK,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC,kBAAkB,EAAE,SAAS,CAAC;QACrE,OAAO;KACR,CAAC;AACJ,CAAC"}
@@ -0,0 +1,16 @@
1
+ import http from "node:http";
2
+ export interface WebServerOptions {
3
+ host?: string;
4
+ port?: number;
5
+ root?: string;
6
+ }
7
+ export interface WebRouteContext {
8
+ root: string;
9
+ }
10
+ export interface WebRouteResult {
11
+ status: number;
12
+ body: unknown;
13
+ }
14
+ export declare function handleWebApiRequest(pathname: string, context: WebRouteContext): Promise<WebRouteResult>;
15
+ export declare function startWebApiServer(options?: WebServerOptions): Promise<http.Server>;
16
+ export declare function getWebServerAddress(server: http.Server): string;
@@ -0,0 +1,220 @@
1
+ import { readFile } from "node:fs/promises";
2
+ import http from "node:http";
3
+ import { dirname, join } from "node:path";
4
+ import { fileURLToPath } from "node:url";
5
+ import { listApprovals, listEvidence, listRoles, listTasks, generateTaskGraphPlan, getWorkflowConfig, getWorkflowStatus, } from "./workflow-services.js";
6
+ import { validateWorkspace } from "./workspace-validator.js";
7
+ import { listWebEvidence, readWorkspaceArtifact } from "./web-evidence.js";
8
+ import { attachWebPlaywrightEvidence, getWebPlaywrightPlan, } from "./web-playwright.js";
9
+ import { getWebRoleActivation } from "./web-roles.js";
10
+ import { renderWebConsoleHtml } from "./web-console.js";
11
+ const LOCAL_HOSTS = new Set(["127.0.0.1", "localhost", "::1"]);
12
+ const DEFAULT_WEB_HOST = "127.0.0.1";
13
+ const DEFAULT_WEB_PORT = 3717;
14
+ const PACKAGE_ROOT = dirname(dirname(fileURLToPath(import.meta.url)));
15
+ const CHART_JS_PATH = join(PACKAGE_ROOT, "node_modules/chart.js/dist/chart.umd.js");
16
+ const routes = {
17
+ "/api/status": ({ root }) => getWorkflowStatus(root),
18
+ "/api/validate": ({ root }) => validateWorkspace(root),
19
+ "/api/graph/plan": ({ root }) => generateTaskGraphPlan(root),
20
+ "/api/roles": ({ root }) => listRoles(root),
21
+ "/api/evidence": ({ root }) => listEvidence(undefined, root),
22
+ "/api/approvals": ({ root }) => listApprovals(undefined, root),
23
+ "/api/config": ({ root }) => getWorkflowConfig(root),
24
+ "/api/tasks": ({ root }) => listTasks(root),
25
+ };
26
+ const requestRoutes = {
27
+ "/api/evidence/view": async ({ root, url }) => ({
28
+ status: 200,
29
+ body: await listWebEvidence(root, webEvidenceFilters(url)),
30
+ }),
31
+ "/api/roles/activation": async ({ root }) => ({
32
+ status: 200,
33
+ body: await getWebRoleActivation(root),
34
+ }),
35
+ "/api/playwright/plan": async ({ root, url }) => ({
36
+ status: 200,
37
+ body: await getWebPlaywrightPlan(root, requiredParam(url, "task")),
38
+ }),
39
+ };
40
+ export async function handleWebApiRequest(pathname, context) {
41
+ const handler = routes[pathname];
42
+ if (!handler) {
43
+ return {
44
+ status: 404,
45
+ body: { error: "not_found", message: `unknown endpoint: ${pathname}` },
46
+ };
47
+ }
48
+ try {
49
+ return {
50
+ status: 200,
51
+ body: await handler(context),
52
+ };
53
+ }
54
+ catch (error) {
55
+ return errorResult(error);
56
+ }
57
+ }
58
+ export async function startWebApiServer(options = {}) {
59
+ const host = options.host ?? DEFAULT_WEB_HOST;
60
+ assertLocalHost(host);
61
+ const root = options.root ?? process.cwd();
62
+ const server = http.createServer(async (request, response) => {
63
+ const url = new URL(request.url ?? "/", `http://${host}`);
64
+ if (request.method === "POST" &&
65
+ url.pathname === "/api/playwright/evidence") {
66
+ const result = await handlePlaywrightEvidencePost(request, root);
67
+ writeJson(response, result.status, result.body);
68
+ return;
69
+ }
70
+ if (request.method !== "GET") {
71
+ writeJson(response, 405, {
72
+ error: "method_not_allowed",
73
+ message: "only GET and selected POST routes are supported",
74
+ });
75
+ return;
76
+ }
77
+ if (url.pathname === "/") {
78
+ writeHtml(response, renderWebConsoleHtml());
79
+ return;
80
+ }
81
+ if (url.pathname === "/vendor/chart.umd.js") {
82
+ await writeChartBundle(response);
83
+ return;
84
+ }
85
+ if (url.pathname === "/api/artifacts") {
86
+ await writeArtifactResponse(response, root, requiredParam(url, "path"));
87
+ return;
88
+ }
89
+ const requestHandler = requestRoutes[url.pathname];
90
+ const result = requestHandler
91
+ ? await safeRequestRoute(requestHandler, { root, url, request })
92
+ : await handleWebApiRequest(url.pathname, { root });
93
+ writeJson(response, result.status, result.body);
94
+ });
95
+ await new Promise((resolve, reject) => {
96
+ server.once("error", reject);
97
+ server.listen(options.port ?? DEFAULT_WEB_PORT, host, () => {
98
+ server.off("error", reject);
99
+ resolve();
100
+ });
101
+ });
102
+ return server;
103
+ }
104
+ export function getWebServerAddress(server) {
105
+ const address = server.address();
106
+ if (!address) {
107
+ throw new Error("web server is not listening");
108
+ }
109
+ return `http://${address.address}:${address.port}`;
110
+ }
111
+ function assertLocalHost(host) {
112
+ if (!LOCAL_HOSTS.has(host)) {
113
+ throw new Error("web API server can only bind to localhost");
114
+ }
115
+ }
116
+ function writeJson(response, status, body) {
117
+ response.writeHead(status, {
118
+ "content-type": "application/json; charset=utf-8",
119
+ "cache-control": "no-store",
120
+ });
121
+ response.end(`${JSON.stringify(body, null, 2)}\n`);
122
+ }
123
+ function writeHtml(response, body) {
124
+ response.writeHead(200, {
125
+ "content-type": "text/html; charset=utf-8",
126
+ "cache-control": "no-store",
127
+ });
128
+ response.end(body);
129
+ }
130
+ async function writeChartBundle(response) {
131
+ const bundle = await readFile(CHART_JS_PATH, "utf8");
132
+ response.writeHead(200, {
133
+ "content-type": "text/javascript; charset=utf-8",
134
+ "cache-control": "no-store",
135
+ });
136
+ response.end(bundle);
137
+ }
138
+ async function safeRequestRoute(handler, context) {
139
+ try {
140
+ return await handler(context);
141
+ }
142
+ catch (error) {
143
+ return errorResult(error);
144
+ }
145
+ }
146
+ async function handlePlaywrightEvidencePost(request, root) {
147
+ try {
148
+ const input = (await readJsonBody(request));
149
+ validatePlaywrightEvidenceInput(input);
150
+ return {
151
+ status: 200,
152
+ body: await attachWebPlaywrightEvidence(root, input),
153
+ };
154
+ }
155
+ catch (error) {
156
+ return errorResult(error);
157
+ }
158
+ }
159
+ async function readJsonBody(request) {
160
+ const chunks = [];
161
+ for await (const chunk of request) {
162
+ chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
163
+ }
164
+ const content = Buffer.concat(chunks).toString("utf8");
165
+ return content.trim() === "" ? {} : JSON.parse(content);
166
+ }
167
+ function validatePlaywrightEvidenceInput(input) {
168
+ if (!input.task || !input.kind || !input.path || !input.summary) {
169
+ throw new Error("task, kind, path, and summary are required");
170
+ }
171
+ if (!["screenshot", "trace", "video", "report"].includes(input.kind)) {
172
+ throw new Error(`invalid playwright evidence kind: ${input.kind}`);
173
+ }
174
+ }
175
+ function errorResult(error) {
176
+ return {
177
+ status: 500,
178
+ body: {
179
+ error: "internal_error",
180
+ message: error instanceof Error ? error.message : String(error),
181
+ },
182
+ };
183
+ }
184
+ function requiredParam(url, name) {
185
+ const value = stringParam(url, name);
186
+ if (!value) {
187
+ throw new Error(`${name} is required`);
188
+ }
189
+ return value;
190
+ }
191
+ function stringParam(url, name) {
192
+ const value = url.searchParams.get(name);
193
+ return value && value.trim() !== "" ? value : undefined;
194
+ }
195
+ function webEvidenceFilters(url) {
196
+ const filters = {};
197
+ const task = stringParam(url, "task");
198
+ const type = stringParam(url, "type");
199
+ if (task) {
200
+ filters.task = task;
201
+ }
202
+ if (type) {
203
+ filters.type = type;
204
+ }
205
+ return filters;
206
+ }
207
+ async function writeArtifactResponse(response, root, artifactPath) {
208
+ try {
209
+ const artifact = await readWorkspaceArtifact(root, artifactPath);
210
+ response.writeHead(200, {
211
+ "content-type": artifact.contentType,
212
+ "cache-control": "no-store",
213
+ });
214
+ response.end(artifact.content);
215
+ }
216
+ catch (error) {
217
+ writeJson(response, 500, errorResult(error).body);
218
+ }
219
+ }
220
+ //# sourceMappingURL=web-api.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"web-api.js","sourceRoot":"","sources":["../src/web-api.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ import type { TaskGraphPlan, WorkflowStatus } from "./types.js";
2
+ export interface DashboardChartSlice {
3
+ label: string;
4
+ value: number;
5
+ }
6
+ export interface DashboardChartData {
7
+ taskStatus: DashboardChartSlice[];
8
+ graphState: DashboardChartSlice[];
9
+ }
10
+ export declare function buildDashboardChartData(input: {
11
+ status: WorkflowStatus;
12
+ graph: TaskGraphPlan;
13
+ }): DashboardChartData;
@@ -0,0 +1,13 @@
1
+ const GRAPH_STATE_LABELS = ["ready", "blocked", "locked", "complete"];
2
+ export function buildDashboardChartData(input) {
3
+ return {
4
+ taskStatus: Object.entries(input.status.tasks.byStatus)
5
+ .map(([label, value]) => ({ label, value }))
6
+ .filter((slice) => slice.value > 0),
7
+ graphState: GRAPH_STATE_LABELS.map((label) => ({
8
+ label,
9
+ value: input.graph[label].length,
10
+ })).filter((slice) => slice.value > 0),
11
+ };
12
+ }
13
+ //# sourceMappingURL=web-chart-contracts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"web-chart-contracts.js","sourceRoot":"","sources":["../src/web-chart-contracts.ts"],"names":[],"mappings":"AAYA,MAAM,kBAAkB,GAAG,CAAC,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,UAAU,CAAU,CAAC;AAE/E,MAAM,UAAU,uBAAuB,CAAC,KAGvC;IACC,OAAO;QACL,UAAU,EAAE,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC;aACpD,GAAG,CAAC,CAAC,CAAC,KAAK,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC;aAC3C,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,KAAK,GAAG,CAAC,CAAC;QACrC,UAAU,EAAE,kBAAkB,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;YAC7C,KAAK;YACL,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,MAAM;SACjC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,KAAK,GAAG,CAAC,CAAC;KACvC,CAAC;AACJ,CAAC"}
@@ -0,0 +1 @@
1
+ export declare function renderWebConsoleHtml(): string;