@kbediako/codex-orchestrator 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 (150) hide show
  1. package/LICENSE +7 -0
  2. package/README.md +238 -0
  3. package/dist/bin/codex-orchestrator.js +507 -0
  4. package/dist/orchestrator/src/agents/builder.js +16 -0
  5. package/dist/orchestrator/src/agents/index.js +4 -0
  6. package/dist/orchestrator/src/agents/planner.js +17 -0
  7. package/dist/orchestrator/src/agents/reviewer.js +13 -0
  8. package/dist/orchestrator/src/agents/tester.js +13 -0
  9. package/dist/orchestrator/src/cli/adapters/CommandBuilder.js +20 -0
  10. package/dist/orchestrator/src/cli/adapters/CommandPlanner.js +164 -0
  11. package/dist/orchestrator/src/cli/adapters/CommandReviewer.js +32 -0
  12. package/dist/orchestrator/src/cli/adapters/CommandTester.js +33 -0
  13. package/dist/orchestrator/src/cli/adapters/index.js +4 -0
  14. package/dist/orchestrator/src/cli/config/userConfig.js +28 -0
  15. package/dist/orchestrator/src/cli/doctor.js +48 -0
  16. package/dist/orchestrator/src/cli/events/runEvents.js +84 -0
  17. package/dist/orchestrator/src/cli/exec/command.js +56 -0
  18. package/dist/orchestrator/src/cli/exec/context.js +108 -0
  19. package/dist/orchestrator/src/cli/exec/experience.js +77 -0
  20. package/dist/orchestrator/src/cli/exec/finalization.js +140 -0
  21. package/dist/orchestrator/src/cli/exec/learning.js +62 -0
  22. package/dist/orchestrator/src/cli/exec/stageRunner.js +71 -0
  23. package/dist/orchestrator/src/cli/exec/summary.js +109 -0
  24. package/dist/orchestrator/src/cli/exec/telemetry.js +18 -0
  25. package/dist/orchestrator/src/cli/exec/tfgrpo.js +200 -0
  26. package/dist/orchestrator/src/cli/exec/tfgrpoArtifacts.js +19 -0
  27. package/dist/orchestrator/src/cli/exec/types.js +1 -0
  28. package/dist/orchestrator/src/cli/init.js +64 -0
  29. package/dist/orchestrator/src/cli/mcp.js +124 -0
  30. package/dist/orchestrator/src/cli/metrics/metricsAggregator.js +404 -0
  31. package/dist/orchestrator/src/cli/metrics/metricsRecorder.js +138 -0
  32. package/dist/orchestrator/src/cli/orchestrator.js +554 -0
  33. package/dist/orchestrator/src/cli/pipelines/defaultDiagnostics.js +32 -0
  34. package/dist/orchestrator/src/cli/pipelines/designReference.js +72 -0
  35. package/dist/orchestrator/src/cli/pipelines/hiFiDesignToolkit.js +71 -0
  36. package/dist/orchestrator/src/cli/pipelines/index.js +34 -0
  37. package/dist/orchestrator/src/cli/run/environment.js +24 -0
  38. package/dist/orchestrator/src/cli/run/manifest.js +367 -0
  39. package/dist/orchestrator/src/cli/run/manifestPersister.js +88 -0
  40. package/dist/orchestrator/src/cli/run/runPaths.js +30 -0
  41. package/dist/orchestrator/src/cli/selfCheck.js +12 -0
  42. package/dist/orchestrator/src/cli/services/commandRunner.js +420 -0
  43. package/dist/orchestrator/src/cli/services/controlPlaneService.js +107 -0
  44. package/dist/orchestrator/src/cli/services/execRuntime.js +69 -0
  45. package/dist/orchestrator/src/cli/services/pipelineResolver.js +47 -0
  46. package/dist/orchestrator/src/cli/services/runPreparation.js +82 -0
  47. package/dist/orchestrator/src/cli/services/runSummaryWriter.js +35 -0
  48. package/dist/orchestrator/src/cli/services/schedulerService.js +42 -0
  49. package/dist/orchestrator/src/cli/tasks/taskMetadata.js +19 -0
  50. package/dist/orchestrator/src/cli/telemetry/schema.js +8 -0
  51. package/dist/orchestrator/src/cli/types.js +1 -0
  52. package/dist/orchestrator/src/cli/ui/HudApp.js +112 -0
  53. package/dist/orchestrator/src/cli/ui/controller.js +26 -0
  54. package/dist/orchestrator/src/cli/ui/store.js +240 -0
  55. package/dist/orchestrator/src/cli/utils/enforcementMode.js +12 -0
  56. package/dist/orchestrator/src/cli/utils/fs.js +8 -0
  57. package/dist/orchestrator/src/cli/utils/interactive.js +25 -0
  58. package/dist/orchestrator/src/cli/utils/jsonlWriter.js +10 -0
  59. package/dist/orchestrator/src/cli/utils/optionalDeps.js +30 -0
  60. package/dist/orchestrator/src/cli/utils/packageInfo.js +25 -0
  61. package/dist/orchestrator/src/cli/utils/planFormatter.js +49 -0
  62. package/dist/orchestrator/src/cli/utils/runId.js +7 -0
  63. package/dist/orchestrator/src/cli/utils/specGuardRunner.js +26 -0
  64. package/dist/orchestrator/src/cli/utils/strings.js +8 -0
  65. package/dist/orchestrator/src/cli/utils/time.js +6 -0
  66. package/dist/orchestrator/src/control-plane/drift-reporter.js +109 -0
  67. package/dist/orchestrator/src/control-plane/index.js +3 -0
  68. package/dist/orchestrator/src/control-plane/request-builder.js +217 -0
  69. package/dist/orchestrator/src/control-plane/types.js +1 -0
  70. package/dist/orchestrator/src/control-plane/validator.js +50 -0
  71. package/dist/orchestrator/src/credentials/CredentialBroker.js +1 -0
  72. package/dist/orchestrator/src/events/EventBus.js +25 -0
  73. package/dist/orchestrator/src/learning/crystalizer.js +108 -0
  74. package/dist/orchestrator/src/learning/harvester.js +146 -0
  75. package/dist/orchestrator/src/learning/manifest.js +56 -0
  76. package/dist/orchestrator/src/learning/runner.js +177 -0
  77. package/dist/orchestrator/src/learning/validator.js +164 -0
  78. package/dist/orchestrator/src/logger.js +20 -0
  79. package/dist/orchestrator/src/manager.js +388 -0
  80. package/dist/orchestrator/src/persistence/ArtifactStager.js +95 -0
  81. package/dist/orchestrator/src/persistence/ExperienceStore.js +210 -0
  82. package/dist/orchestrator/src/persistence/PersistenceCoordinator.js +65 -0
  83. package/dist/orchestrator/src/persistence/RunManifestWriter.js +23 -0
  84. package/dist/orchestrator/src/persistence/TaskStateStore.js +172 -0
  85. package/dist/orchestrator/src/persistence/identifierGuards.js +1 -0
  86. package/dist/orchestrator/src/persistence/lockFile.js +26 -0
  87. package/dist/orchestrator/src/persistence/sanitizeIdentifier.js +26 -0
  88. package/dist/orchestrator/src/persistence/sanitizeRunId.js +8 -0
  89. package/dist/orchestrator/src/persistence/sanitizeTaskId.js +8 -0
  90. package/dist/orchestrator/src/persistence/writeAtomicFile.js +4 -0
  91. package/dist/orchestrator/src/privacy/guard.js +111 -0
  92. package/dist/orchestrator/src/scheduler/index.js +1 -0
  93. package/dist/orchestrator/src/scheduler/plan.js +171 -0
  94. package/dist/orchestrator/src/scheduler/types.js +1 -0
  95. package/dist/orchestrator/src/sync/CloudRunsClient.js +1 -0
  96. package/dist/orchestrator/src/sync/CloudRunsHttpClient.js +82 -0
  97. package/dist/orchestrator/src/sync/CloudSyncWorker.js +206 -0
  98. package/dist/orchestrator/src/sync/createCloudSyncWorker.js +15 -0
  99. package/dist/orchestrator/src/types.js +1 -0
  100. package/dist/orchestrator/src/utils/atomicWrite.js +15 -0
  101. package/dist/orchestrator/src/utils/errorMessage.js +14 -0
  102. package/dist/orchestrator/src/utils/executionMode.js +69 -0
  103. package/dist/packages/control-plane-schemas/src/index.js +1 -0
  104. package/dist/packages/control-plane-schemas/src/run-request.js +548 -0
  105. package/dist/packages/orchestrator/src/exec/handle-service.js +203 -0
  106. package/dist/packages/orchestrator/src/exec/session-manager.js +147 -0
  107. package/dist/packages/orchestrator/src/exec/unified-exec.js +432 -0
  108. package/dist/packages/orchestrator/src/index.js +3 -0
  109. package/dist/packages/orchestrator/src/instructions/loader.js +101 -0
  110. package/dist/packages/orchestrator/src/instructions/promptPacks.js +151 -0
  111. package/dist/packages/orchestrator/src/notifications/index.js +74 -0
  112. package/dist/packages/orchestrator/src/telemetry/otel-exporter.js +142 -0
  113. package/dist/packages/orchestrator/src/tool-orchestrator.js +161 -0
  114. package/dist/packages/sdk-node/src/orchestrator.js +195 -0
  115. package/dist/packages/shared/config/designConfig.js +495 -0
  116. package/dist/packages/shared/config/env.js +37 -0
  117. package/dist/packages/shared/config/index.js +2 -0
  118. package/dist/packages/shared/design-artifacts/writer.js +221 -0
  119. package/dist/packages/shared/events/serializer.js +84 -0
  120. package/dist/packages/shared/events/types.js +1 -0
  121. package/dist/packages/shared/manifest/artifactUtils.js +36 -0
  122. package/dist/packages/shared/manifest/designArtifacts.js +665 -0
  123. package/dist/packages/shared/manifest/fileIO.js +29 -0
  124. package/dist/packages/shared/manifest/toolRuns.js +78 -0
  125. package/dist/packages/shared/manifest/toolkitArtifacts.js +223 -0
  126. package/dist/packages/shared/manifest/types.js +5 -0
  127. package/dist/packages/shared/manifest/validator.js +73 -0
  128. package/dist/packages/shared/manifest/writer.js +2 -0
  129. package/dist/packages/shared/streams/stdio.js +112 -0
  130. package/dist/scripts/design/pipeline/advanced-assets.js +466 -0
  131. package/dist/scripts/design/pipeline/componentize.js +74 -0
  132. package/dist/scripts/design/pipeline/context.js +34 -0
  133. package/dist/scripts/design/pipeline/extract.js +249 -0
  134. package/dist/scripts/design/pipeline/optionalDeps.js +107 -0
  135. package/dist/scripts/design/pipeline/prepare.js +46 -0
  136. package/dist/scripts/design/pipeline/reference.js +94 -0
  137. package/dist/scripts/design/pipeline/state.js +206 -0
  138. package/dist/scripts/design/pipeline/toolkit/common.js +94 -0
  139. package/dist/scripts/design/pipeline/toolkit/extract.js +258 -0
  140. package/dist/scripts/design/pipeline/toolkit/publish.js +202 -0
  141. package/dist/scripts/design/pipeline/toolkit/publishActions.js +12 -0
  142. package/dist/scripts/design/pipeline/toolkit/reference.js +846 -0
  143. package/dist/scripts/design/pipeline/toolkit/snapshot.js +882 -0
  144. package/dist/scripts/design/pipeline/toolkit/tokens.js +456 -0
  145. package/dist/scripts/design/pipeline/visual-regression.js +137 -0
  146. package/dist/scripts/design/pipeline/write-artifacts.js +61 -0
  147. package/package.json +97 -0
  148. package/schemas/manifest.json +1064 -0
  149. package/templates/README.md +12 -0
  150. package/templates/codex/mcp-client.json +8 -0
@@ -0,0 +1,203 @@
1
+ import { randomUUID } from 'node:crypto';
2
+ const DEFAULT_MAX_STORED_FRAMES = 500;
3
+ const DEFAULT_MAX_QUEUE_SIZE = 32;
4
+ export class RemoteExecHandleService {
5
+ handles = new Map();
6
+ maxStoredFrames;
7
+ now;
8
+ guard;
9
+ constructor(options = {}) {
10
+ this.maxStoredFrames = options.maxStoredFrames ?? DEFAULT_MAX_STORED_FRAMES;
11
+ this.now = options.now ?? (() => new Date());
12
+ this.guard = options.guard;
13
+ }
14
+ setGuard(guard) {
15
+ this.guard = guard;
16
+ }
17
+ issueHandle(correlationId) {
18
+ const id = randomUUID();
19
+ const createdAt = this.now().toISOString();
20
+ const handle = {
21
+ id,
22
+ correlationId,
23
+ createdAt,
24
+ frames: [],
25
+ status: 'open',
26
+ observers: new Map(),
27
+ nextSequence: 1,
28
+ decisions: []
29
+ };
30
+ this.handles.set(id, handle);
31
+ return this.describeHandle(handle);
32
+ }
33
+ async append(handleId, event) {
34
+ const handle = this.getHandle(handleId);
35
+ if (handle.status === 'closed') {
36
+ return;
37
+ }
38
+ const frame = {
39
+ sequence: handle.nextSequence,
40
+ event,
41
+ timestamp: event.timestamp
42
+ };
43
+ handle.nextSequence += 1;
44
+ const processed = this.guard
45
+ ? await this.guard.process(frame, { handleId })
46
+ : { frame, decision: { action: 'allow' } };
47
+ handle.decisions.push({ sequence: frame.sequence, decision: processed.decision });
48
+ if (processed.frame) {
49
+ handle.frames.push(processed.frame);
50
+ if (handle.frames.length > this.maxStoredFrames) {
51
+ handle.frames.splice(0, handle.frames.length - this.maxStoredFrames);
52
+ }
53
+ this.notifyObservers(handle, processed.frame);
54
+ }
55
+ this.pruneDecisions(handle);
56
+ }
57
+ close(handleId) {
58
+ const handle = this.getHandle(handleId);
59
+ handle.status = 'closed';
60
+ }
61
+ subscribe(handleId, observerId, options, onFrame) {
62
+ const handle = this.getHandle(handleId);
63
+ const state = {
64
+ id: observerId,
65
+ queue: [],
66
+ maxQueueSize: Math.max(1, options.maxQueueSize ?? DEFAULT_MAX_QUEUE_SIZE),
67
+ delivered: 0,
68
+ dropped: 0,
69
+ flushing: false,
70
+ callback: onFrame
71
+ };
72
+ handle.observers.set(observerId, state);
73
+ // Replay frames from requested sequence.
74
+ const fromSequence = options.fromSequence ?? 1;
75
+ const startIndex = this.findFrameStartIndex(handle.frames, fromSequence);
76
+ for (let index = startIndex; index < handle.frames.length; index += 1) {
77
+ const frame = handle.frames[index];
78
+ if (!frame) {
79
+ continue;
80
+ }
81
+ this.enqueueFrame(state, frame);
82
+ }
83
+ const unsubscribe = () => {
84
+ handle.observers.delete(observerId);
85
+ };
86
+ return {
87
+ unsubscribe,
88
+ stats: () => ({ delivered: state.delivered, dropped: state.dropped })
89
+ };
90
+ }
91
+ getSnapshot(handleId, fromSequence = 1) {
92
+ const handle = this.getHandle(handleId);
93
+ const startIndex = this.findFrameStartIndex(handle.frames, fromSequence);
94
+ return handle.frames.slice(startIndex);
95
+ }
96
+ getDescriptor(handleId) {
97
+ const handle = this.getHandle(handleId);
98
+ return this.describeHandle(handle);
99
+ }
100
+ getDecisions(handleId) {
101
+ const handle = this.getHandle(handleId);
102
+ return [...handle.decisions];
103
+ }
104
+ getHandle(handleId) {
105
+ const handle = this.handles.get(handleId);
106
+ if (!handle) {
107
+ throw new Error(`Exec handle ${handleId} not found.`);
108
+ }
109
+ return handle;
110
+ }
111
+ enqueueFrame(observer, frame) {
112
+ if (observer.queue.length >= observer.maxQueueSize) {
113
+ observer.queue.shift();
114
+ observer.dropped += 1;
115
+ }
116
+ observer.queue.push(frame);
117
+ this.flush(observer);
118
+ }
119
+ notifyObservers(handle, frame) {
120
+ for (const observer of handle.observers.values()) {
121
+ this.enqueueFrame(observer, frame);
122
+ }
123
+ }
124
+ flush(observer) {
125
+ if (observer.flushing) {
126
+ return;
127
+ }
128
+ observer.flushing = true;
129
+ queueMicrotask(() => {
130
+ observer.flushing = false;
131
+ while (observer.queue.length > 0) {
132
+ const frame = observer.queue.shift();
133
+ if (!frame) {
134
+ continue;
135
+ }
136
+ observer.delivered += 1;
137
+ observer.callback(frame);
138
+ }
139
+ });
140
+ }
141
+ describeHandle(handle) {
142
+ return {
143
+ id: handle.id,
144
+ correlationId: handle.correlationId,
145
+ createdAt: handle.createdAt,
146
+ frameCount: handle.frames.length,
147
+ status: handle.status,
148
+ latestSequence: handle.nextSequence - 1
149
+ };
150
+ }
151
+ pruneDecisions(handle) {
152
+ if (handle.decisions.length === 0) {
153
+ return;
154
+ }
155
+ if (this.maxStoredFrames <= 0) {
156
+ handle.decisions.length = 0;
157
+ return;
158
+ }
159
+ const slidingMinSequence = Math.max(1, handle.nextSequence - this.maxStoredFrames);
160
+ const preservedSequences = new Set();
161
+ for (const frame of handle.frames) {
162
+ preservedSequences.add(frame.sequence);
163
+ }
164
+ let writeIndex = 0;
165
+ for (let index = 0; index < handle.decisions.length; index += 1) {
166
+ const entry = handle.decisions[index];
167
+ if (!entry) {
168
+ continue;
169
+ }
170
+ const keep = entry.sequence >= slidingMinSequence || preservedSequences.has(entry.sequence);
171
+ if (keep) {
172
+ handle.decisions[writeIndex] = entry;
173
+ writeIndex += 1;
174
+ }
175
+ }
176
+ if (writeIndex < handle.decisions.length) {
177
+ handle.decisions.length = writeIndex;
178
+ }
179
+ }
180
+ findFrameStartIndex(frames, fromSequence) {
181
+ if (fromSequence <= 1 || frames.length === 0) {
182
+ return 0;
183
+ }
184
+ let low = 0;
185
+ let high = frames.length - 1;
186
+ let result = frames.length;
187
+ while (low <= high) {
188
+ const mid = (low + high) >> 1;
189
+ const frame = frames[mid];
190
+ if (!frame) {
191
+ break;
192
+ }
193
+ if (frame.sequence >= fromSequence) {
194
+ result = mid;
195
+ high = mid - 1;
196
+ }
197
+ else {
198
+ low = mid + 1;
199
+ }
200
+ }
201
+ return result;
202
+ }
203
+ }
@@ -0,0 +1,147 @@
1
+ import { EventEmitter } from 'node:events';
2
+ import { randomUUID } from 'node:crypto';
3
+ /**
4
+ * Manages reusable exec sessions (e.g. PTY handles) keyed by identifier while
5
+ * providing lifecycle hooks and environment snapshots for observability.
6
+ */
7
+ export class ExecSessionManager {
8
+ sessions = new Map();
9
+ emitter = new EventEmitter({ captureRejections: false });
10
+ factory;
11
+ baseEnv;
12
+ now;
13
+ idGenerator;
14
+ constructor(options) {
15
+ this.factory = options.factory;
16
+ this.baseEnv = options.baseEnv ? { ...options.baseEnv } : { ...process.env };
17
+ this.now = options.now ?? (() => new Date());
18
+ this.idGenerator = options.idGenerator ?? (() => randomUUID());
19
+ }
20
+ async acquire(options = {}) {
21
+ const id = options.id ?? this.idGenerator();
22
+ const reuse = options.reuse ?? Boolean(options.id);
23
+ const persisted = options.persist ?? Boolean(options.id);
24
+ const envSnapshot = this.snapshotEnv(options.env);
25
+ if (persisted && reuse) {
26
+ const existing = this.sessions.get(id);
27
+ if (existing) {
28
+ existing.lastUsedAt = this.now().toISOString();
29
+ if (options.env !== undefined) {
30
+ existing.envSnapshot = envSnapshot;
31
+ }
32
+ return this.createLease(existing, true, persisted);
33
+ }
34
+ }
35
+ if (!reuse && persisted) {
36
+ await this.dispose(id);
37
+ }
38
+ const managed = await this.createSession(id, envSnapshot, persisted);
39
+ if (persisted) {
40
+ this.sessions.set(id, managed);
41
+ }
42
+ return this.createLease(managed, false, persisted);
43
+ }
44
+ async dispose(id) {
45
+ const session = this.sessions.get(id);
46
+ if (!session) {
47
+ return;
48
+ }
49
+ this.sessions.delete(id);
50
+ await this.teardown(session);
51
+ }
52
+ async disposeAll() {
53
+ const disposals = Array.from(this.sessions.values()).map((session) => this.teardown(session));
54
+ this.sessions.clear();
55
+ await Promise.all(disposals);
56
+ }
57
+ getSnapshot(id) {
58
+ const session = this.sessions.get(id);
59
+ return session ? { ...session.envSnapshot } : undefined;
60
+ }
61
+ on(event, listener) {
62
+ this.emitter.on(event, listener);
63
+ return () => {
64
+ this.emitter.off(event, listener);
65
+ };
66
+ }
67
+ async createSession(id, envSnapshot, persisted) {
68
+ const createdAt = this.now().toISOString();
69
+ const handle = await this.factory({
70
+ id,
71
+ env: envSnapshot,
72
+ persisted,
73
+ createdAt
74
+ });
75
+ const managed = {
76
+ id,
77
+ handle,
78
+ envSnapshot,
79
+ createdAt,
80
+ lastUsedAt: createdAt,
81
+ persisted
82
+ };
83
+ this.emit('session:created', managed);
84
+ return managed;
85
+ }
86
+ createLease(session, reused, persisted) {
87
+ return {
88
+ id: session.id,
89
+ handle: session.handle,
90
+ envSnapshot: { ...session.envSnapshot },
91
+ createdAt: session.createdAt,
92
+ lastUsedAt: session.lastUsedAt,
93
+ persisted,
94
+ reused,
95
+ release: async () => {
96
+ if (!persisted) {
97
+ await this.teardown(session);
98
+ }
99
+ else {
100
+ session.lastUsedAt = this.now().toISOString();
101
+ }
102
+ }
103
+ };
104
+ }
105
+ async teardown(session) {
106
+ try {
107
+ await session.handle.dispose();
108
+ }
109
+ finally {
110
+ session.lastUsedAt = this.now().toISOString();
111
+ this.emit('session:disposed', session);
112
+ }
113
+ }
114
+ emit(event, session) {
115
+ const payload = {
116
+ type: event,
117
+ session: {
118
+ id: session.id,
119
+ envSnapshot: { ...session.envSnapshot },
120
+ createdAt: session.createdAt,
121
+ lastUsedAt: session.lastUsedAt,
122
+ persisted: session.persisted,
123
+ handle: session.handle
124
+ }
125
+ };
126
+ this.emitter.emit(event, payload);
127
+ }
128
+ snapshotEnv(overrides) {
129
+ const snapshot = {};
130
+ for (const [key, value] of Object.entries(this.baseEnv)) {
131
+ if (typeof value === 'string') {
132
+ snapshot[key] = value;
133
+ }
134
+ }
135
+ if (overrides) {
136
+ for (const [key, value] of Object.entries(overrides)) {
137
+ if (value === undefined) {
138
+ delete snapshot[key];
139
+ }
140
+ else {
141
+ snapshot[key] = value;
142
+ }
143
+ }
144
+ }
145
+ return snapshot;
146
+ }
147
+ }