@moretea-labs/forge 1.7.0 → 1.7.1
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/AGENTS.md +2 -0
- package/CHANGELOG.md +13 -0
- package/CLAUDE.md +2 -0
- package/THIRD_PARTY_NOTICES.md +1 -1
- package/agents/openai.yaml +1 -1
- package/assets/partials-agents/02-operating-mode.partial.md +2 -0
- package/assets/plugin-registry.v1.json +3 -3
- package/assets/skill-version.json +2 -2
- package/assets/templates/helpers/check-architecture-sync.sh +17 -0
- package/assets/templates/helpers/inspect-project-state.ts +8 -6
- package/assets/templates/helpers/migrate-workflow-docs.ts +9 -7
- package/assets/templates/helpers/workflow-contract.ts +5 -1
- package/docs/architecture/CURRENT.md +12 -4
- package/docs/forge-plugin-management.md +1 -1
- package/docs/operations/controller-performance-and-502.md +19 -0
- package/docs/operations/homebrew.md +2 -2
- package/package.json +5 -2
- package/scripts/architecture-event.ts +2 -820
- package/scripts/architecture-queue.sh +2 -645
- package/scripts/archive-architecture-request.sh +2 -242
- package/scripts/archive-workflow.sh +1 -291
- package/scripts/benchmark-work-efficiency.ts +0 -0
- package/scripts/capability-config.ts +2 -392
- package/scripts/capability-resolver.ts +2 -503
- package/scripts/capture-plan.sh +1 -332
- package/scripts/check-agent-tooling.sh +2 -1531
- package/scripts/check-architecture-sync.sh +2 -302
- package/scripts/check-brain-manifest.sh +2 -253
- package/scripts/check-context-files.sh +2 -47
- package/scripts/check-deploy-sql-order.sh +2 -115
- package/scripts/check-runtime-architecture.mjs +243 -16
- package/scripts/check-skill-version.ts +3 -191
- package/scripts/check-source-duplication.mjs +61 -0
- package/scripts/check-stable-baseline.ts +0 -0
- package/scripts/check-task-sync.sh +2 -63
- package/scripts/check-task-workflow.sh +2 -1000
- package/scripts/codex-handoff-resume.sh +2 -267
- package/scripts/context-contract-sync.sh +2 -514
- package/scripts/contract-run.ts +2 -463
- package/scripts/contract-worktree.sh +1 -702
- package/scripts/ensure-task-workflow.sh +1 -1192
- package/scripts/inspect-project-state.ts +4 -279
- package/scripts/lib/project-init-lib.sh +7 -2
- package/scripts/lib/run-forge-helper.sh +19 -0
- package/scripts/lib/run-forge-helper.ts +26 -0
- package/scripts/migrate-project-template.sh +1 -33
- package/scripts/migrate-workflow-docs.ts +4 -412
- package/scripts/new-plan.sh +1 -180
- package/scripts/new-spec.sh +1 -47
- package/scripts/new-sprint.sh +1 -46
- package/scripts/plan-to-todo.sh +1 -771
- package/scripts/prepare-codex-handoff.sh +2 -201
- package/scripts/prepare-handoff.sh +1 -78
- package/scripts/refresh-current-status.sh +2 -467
- package/scripts/run-governed-gate.ts +3 -0
- package/scripts/select-agent-context-blocks.sh +2 -64
- package/scripts/ship-worktrees.sh +1 -531
- package/scripts/sprint-backlog.sh +1 -834
- package/scripts/stage-runtime-release.ts +2 -1
- package/scripts/summarize-failures.sh +2 -123
- package/scripts/switch-plan.sh +1 -150
- package/scripts/sync-brain-docs.sh +2 -379
- package/scripts/sync-generated-authority.mjs +175 -0
- package/scripts/verify-contract.sh +2 -593
- package/scripts/verify-sprint.sh +1 -500
- package/scripts/workflow-contract.ts +4 -201
- package/scripts/workstream-sync.sh +2 -261
- package/src/cli/agent-jobs/executor-health.ts +1 -1
- package/src/cli/commands/plugin.ts +12 -3
- package/src/cli/controller/check-runner.ts +7 -2
- package/src/cli/controller/context-pack.ts +46 -21
- package/src/cli/github/contracts.ts +16 -0
- package/src/cli/github/github.ts +2 -16
- package/src/cli/github/session.ts +2 -1
- package/src/cli/local-bridge/facade-api.ts +37 -47
- package/src/cli/local-bridge/server.ts +2 -2
- package/src/cli/mcp/legacy-tool-service.ts +10 -33
- package/src/cli/mcp/post-finalize-work-attribution.ts +150 -0
- package/src/cli/mcp/repository-tools.ts +85 -89
- package/src/cli/mcp/server.ts +57 -13
- package/src/cli/mcp/tool-contract.ts +14 -0
- package/src/cli/mcp/toolset.ts +2 -2
- package/src/cli/mcp/transports/http.ts +23 -0
- package/src/cli/repositories/command-classifier.ts +2 -2
- package/src/cli/repositories/command-executor.ts +24 -6
- package/src/cli/repositories/repository-snapshot.ts +5 -2
- package/src/cli/repositories/structured-git.ts +57 -3
- package/src/cli/repository/inspector.ts +11 -3
- package/src/runtime/context/generic-lsp-provider.ts +1 -1
- package/src/runtime/context/semantic-navigation-contract.ts +61 -0
- package/src/runtime/context/semantic-navigation.ts +9 -61
- package/src/runtime/control-plane/execution/direct-edit-work-completion.ts +18 -25
- package/src/runtime/control-plane/execution/repository-work-attribution.ts +106 -0
- package/src/runtime/control-plane/execution/retained-work-resume.ts +203 -0
- package/src/runtime/control-plane/execution/work-completion-authority.ts +58 -0
- package/src/runtime/control-plane/execution/work-evidence-policy.ts +200 -0
- package/src/runtime/control-plane/execution/work-execution-support.ts +386 -0
- package/src/runtime/control-plane/execution/work-finalization-service.ts +1913 -0
- package/src/runtime/control-plane/execution/work-handle-authority.ts +96 -0
- package/src/runtime/control-plane/execution/work-handle-store.ts +1 -1
- package/src/runtime/control-plane/execution/work-operation-service.ts +468 -0
- package/src/runtime/control-plane/execution/work-path-scope.ts +37 -0
- package/src/runtime/control-plane/execution/work-preparation-service.ts +479 -0
- package/src/runtime/control-plane/execution/work-process-evidence.ts +129 -0
- package/src/runtime/control-plane/execution/work-task-receipt.ts +4 -43
- package/src/runtime/control-plane/execution/work-terminal-cleanup.ts +13 -3
- package/src/runtime/control-plane/execution/work-verification-context.ts +56 -0
- package/src/runtime/control-plane/execution/work-verification-service.ts +388 -0
- package/src/runtime/control-plane/execution/work-verification-snapshot.ts +5 -1
- package/src/runtime/control-plane/facade/controller-round-relay.ts +164 -37
- package/src/runtime/control-plane/facade/controller-session-store.ts +183 -24
- package/src/runtime/control-plane/facade/goal-workloop-access.ts +15 -1
- package/src/runtime/control-plane/facade/goal-workloop.ts +329 -148
- package/src/runtime/control-plane/facade/index.ts +2 -0
- package/src/runtime/control-plane/facade/plan-contract-store.ts +90 -22
- package/src/runtime/control-plane/facade/repository-work-admission.ts +147 -0
- package/src/runtime/control-plane/facade/requirement-authority.ts +83 -0
- package/src/runtime/control-plane/facade/types.ts +68 -5
- package/src/runtime/control-plane/facade/work-contract-store.ts +3 -209
- package/src/runtime/control-plane/facade/work-state-machine.ts +250 -0
- package/src/runtime/control-plane/global-scheduler/maintenance.ts +14 -7
- package/src/runtime/control-plane/global-scheduler/scheduler.ts +5 -1
- package/src/runtime/control-plane/launcher/chatgpt-work-binding-store.ts +13 -0
- package/src/runtime/control-plane/launcher/chatgpt-work-continuation.ts +15 -6
- package/src/runtime/control-plane/launcher/launch-reservation-store.ts +54 -5
- package/src/runtime/control-plane/launcher/thin-launcher.ts +56 -7
- package/src/runtime/control-plane/persistence/requirement-store.ts +0 -12
- package/src/runtime/control-plane/repo-actor/registry.ts +4 -2
- package/src/runtime/control-plane/routing/route-policy.ts +18 -6
- package/src/runtime/control-plane/routing/workspace-admission.ts +70 -0
- package/src/runtime/evidence/process-check-execution.ts +18 -0
- package/src/runtime/execution/jobs/child-reference.ts +6 -2
- package/src/runtime/execution/process-runtime/check-result.ts +53 -18
- package/src/runtime/execution/process-runtime/check-runner-sidecar.ts +7 -1
- package/src/runtime/execution/process-runtime/command-facade.ts +39 -17
- package/src/runtime/execution/process-runtime/lightweight-managed.ts +20 -3
- package/src/runtime/execution/process-runtime/persisted-check.ts +4 -1
- package/src/runtime/execution/process-runtime/runtime.ts +10 -0
- package/src/runtime/execution/process-runtime/types.ts +2 -12
- package/src/runtime/execution/work-activity.ts +21 -0
- package/src/runtime/execution/workers/executor.ts +18 -13
- package/src/runtime/gateway/mcp/execution-tools.ts +35 -2930
- package/src/runtime/gateway/mcp/legacy-ios-tool-adapter.ts +61 -0
- package/src/runtime/gateway/mcp/router.ts +2 -2
- package/src/runtime/gateway/mcp/runtime-tool-definitions.ts +21 -2
- package/src/runtime/gateway/mcp/runtime-tools.ts +805 -1009
- package/src/runtime/plugins/app-store-connect-adapter.ts +93 -28
- package/src/runtime/plugins/browser-adapter.ts +256 -1083
- package/src/runtime/plugins/browser-handoff-host.ts +2 -25
- package/src/runtime/plugins/browser-handoff.ts +18 -3
- package/src/runtime/plugins/browser-macos-bridge.ts +121 -16
- package/src/runtime/plugins/browser-manifest-surface.ts +603 -0
- package/src/runtime/plugins/browser-native-session-service.ts +222 -0
- package/src/runtime/plugins/browser-runtime-contract.ts +2 -0
- package/src/runtime/plugins/browser-runtime.ts +10 -0
- package/src/runtime/plugins/browser-session-store.ts +121 -0
- package/src/runtime/plugins/browser-session-types.ts +98 -0
- package/src/runtime/plugins/desktop-operator-registration.ts +4 -4
- package/src/runtime/plugins/external-adapter.ts +92 -58
- package/src/runtime/plugins/macos-capability-broker.ts +0 -8
- package/src/runtime/plugins/store.ts +66 -9
- package/src/runtime/plugins/types.ts +3 -1
- package/src/runtime/recovery/maintenance-executor.ts +61 -25
- package/src/runtime/root/package-connector-service.ts +46 -4
- package/src/runtime/root/package-runtime-release.ts +1 -1
- package/src/runtime/root/package-runtime-service.ts +33 -2
- package/src/runtime/root/release-manifest.ts +137 -16
- package/src/runtime/root/release-materialize.ts +109 -35
- package/src/runtime/root/types.ts +10 -0
- package/src/runtime/standalone-recovery/core.ts +425 -194
- package/src/runtime/standalone-recovery/entry.ts +1 -1
- package/src/runtime/standalone-recovery/installer.ts +1 -1
- package/src/runtime/workflow/schedules/engine.ts +113 -87
- package/src/runtime/workflow/schedules/settlement.ts +26 -23
- package/src/runtime/workflow/schedules/store.ts +79 -10
|
@@ -28,6 +28,7 @@ interface ScheduleRequestRecord {
|
|
|
28
28
|
createdAt: string;
|
|
29
29
|
}
|
|
30
30
|
type CreateScheduleInput = Omit<RepositorySchedule, 'schemaVersion' | 'revision' | 'scheduleId' | 'createdAt' | 'updatedAt' | 'consecutiveFailures'>;
|
|
31
|
+
type ScheduleMutableUpdate = Partial<Omit<RepositorySchedule, 'schemaVersion' | 'revision' | 'scheduleId' | 'repoId' | 'requestId' | 'createdAt' | 'updatedAt'>>;
|
|
31
32
|
|
|
32
33
|
export interface ScheduleOccurrenceHandoffInput {
|
|
33
34
|
title: string;
|
|
@@ -62,6 +63,30 @@ function occurrenceIndexPath(controllerHome: string, repoId: string): string {
|
|
|
62
63
|
function requestPath(controllerHome: string, repoId: string, requestId: string): string {
|
|
63
64
|
return join(schedulesRoot(controllerHome, repoId), 'indexes', 'requests', `${createHash('sha256').update(requestId).digest('hex')}.json`);
|
|
64
65
|
}
|
|
66
|
+
|
|
67
|
+
const EXTERNAL_CONTROLLER_WAKE_MAX_FAILURES = 3;
|
|
68
|
+
const EXTERNAL_CONTROLLER_WAKE_DAILY_BUDGET_MINUTES = 60;
|
|
69
|
+
const EXTERNAL_CONTROLLER_WAKE_MIN_COOLDOWN_MINUTES = 10;
|
|
70
|
+
|
|
71
|
+
function boundedSchedulePolicy(schedule: RepositorySchedule): RepositorySchedule['policy'] {
|
|
72
|
+
const policy = {
|
|
73
|
+
...schedule.policy,
|
|
74
|
+
backoffBaseMinutes: Math.max(1, schedule.policy.backoffBaseMinutes ?? schedule.policy.cooldownMinutes ?? 1),
|
|
75
|
+
backoffMaxMinutes: Math.max(1, schedule.policy.backoffMaxMinutes ?? 24 * 60),
|
|
76
|
+
};
|
|
77
|
+
if (schedule.action.operation !== 'external_controller_wake') return policy;
|
|
78
|
+
// A Work-bound controller wake is expensive and can affect the user's
|
|
79
|
+
// browser. No schedule payload may convert a transient tool outage into an
|
|
80
|
+
// all-day retry loop. Larger work needs an explicit future user action after
|
|
81
|
+
// the bounded lane records useful failure evidence.
|
|
82
|
+
return {
|
|
83
|
+
...policy,
|
|
84
|
+
maxFailures: Math.max(1, Math.min(policy.maxFailures, EXTERNAL_CONTROLLER_WAKE_MAX_FAILURES)),
|
|
85
|
+
dailyBudgetMinutes: Math.max(1, Math.min(policy.dailyBudgetMinutes, EXTERNAL_CONTROLLER_WAKE_DAILY_BUDGET_MINUTES)),
|
|
86
|
+
cooldownMinutes: Math.max(policy.cooldownMinutes, EXTERNAL_CONTROLLER_WAKE_MIN_COOLDOWN_MINUTES),
|
|
87
|
+
backoffBaseMinutes: Math.max(policy.backoffBaseMinutes, EXTERNAL_CONTROLLER_WAKE_MIN_COOLDOWN_MINUTES),
|
|
88
|
+
};
|
|
89
|
+
}
|
|
65
90
|
function canonical(value: unknown): unknown {
|
|
66
91
|
if (Array.isArray(value)) return value.map(canonical);
|
|
67
92
|
if (value && typeof value === 'object') return Object.fromEntries(Object.entries(value as Record<string, unknown>)
|
|
@@ -136,22 +161,62 @@ export function getSchedule(controllerHome: string, repoId: string, scheduleId:
|
|
|
136
161
|
...schedule,
|
|
137
162
|
revision: Number.isFinite(schedule.revision) ? schedule.revision : 1,
|
|
138
163
|
requestId: schedule.requestId || `legacy-schedule:${schedule.scheduleId}`,
|
|
139
|
-
policy:
|
|
140
|
-
...schedule.policy,
|
|
141
|
-
backoffBaseMinutes: Math.max(1, schedule.policy.backoffBaseMinutes ?? schedule.policy.cooldownMinutes ?? 1),
|
|
142
|
-
backoffMaxMinutes: Math.max(1, schedule.policy.backoffMaxMinutes ?? 24 * 60),
|
|
143
|
-
},
|
|
164
|
+
policy: boundedSchedulePolicy(schedule),
|
|
144
165
|
consecutiveNoops: Math.max(0, schedule.consecutiveNoops ?? 0),
|
|
145
166
|
};
|
|
146
167
|
}
|
|
147
168
|
|
|
169
|
+
function persistScheduleRevision(
|
|
170
|
+
controllerHome: string,
|
|
171
|
+
current: RepositorySchedule,
|
|
172
|
+
candidate: RepositorySchedule,
|
|
173
|
+
): RepositorySchedule {
|
|
174
|
+
const next: RepositorySchedule = {
|
|
175
|
+
...candidate,
|
|
176
|
+
schemaVersion: current.schemaVersion,
|
|
177
|
+
revision: current.revision + 1,
|
|
178
|
+
scheduleId: current.scheduleId,
|
|
179
|
+
repoId: current.repoId,
|
|
180
|
+
requestId: current.requestId,
|
|
181
|
+
createdAt: current.createdAt,
|
|
182
|
+
updatedAt: new Date().toISOString(),
|
|
183
|
+
};
|
|
184
|
+
writeJsonAtomic(schedulePath(controllerHome, next.repoId, next.scheduleId), next);
|
|
185
|
+
appendRuntimeEvent(controllerHome, { repoId: next.repoId, entityType: 'schedule', entityId: next.scheduleId, eventType: 'schedule_updated', requestId: next.requestId, revision: next.revision, data: { enabled: next.enabled, pausedReason: next.pausedReason } });
|
|
186
|
+
return next;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
/**
|
|
190
|
+
* Persist a caller-owned Schedule snapshot only when its revision is still the
|
|
191
|
+
* current authority. User/configuration mutations use this path so stale
|
|
192
|
+
* writers fail closed instead of overwriting a newer decision.
|
|
193
|
+
*/
|
|
148
194
|
export function saveSchedule(controllerHome: string, schedule: RepositorySchedule): RepositorySchedule {
|
|
149
195
|
return withControllerLock(controllerHome, { scope: 'task', repoId: schedule.repoId, taskId: `schedule-${schedule.scheduleId}` }, `save-schedule:${schedule.scheduleId}`, () => {
|
|
150
196
|
const current = getSchedule(controllerHome, schedule.repoId, schedule.scheduleId);
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
return
|
|
197
|
+
if (schedule.revision !== current.revision) {
|
|
198
|
+
throw new Error(`SCHEDULE_REVISION_CONFLICT: ${schedule.scheduleId}:expected=${schedule.revision}:actual=${current.revision}`);
|
|
199
|
+
}
|
|
200
|
+
return persistScheduleRevision(controllerHome, current, schedule);
|
|
201
|
+
}, 10_000);
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
/**
|
|
205
|
+
* Apply runtime-owned settlement/observation fields to the latest Schedule
|
|
206
|
+
* authority while holding the Schedule lock. Identity and revision fields are
|
|
207
|
+
* never writable through this path. Long-running occurrences use this instead
|
|
208
|
+
* of replaying a stale whole-record snapshot after user state may have changed.
|
|
209
|
+
*/
|
|
210
|
+
export function updateSchedule(
|
|
211
|
+
controllerHome: string,
|
|
212
|
+
repoId: string,
|
|
213
|
+
scheduleId: string,
|
|
214
|
+
update: (current: RepositorySchedule) => ScheduleMutableUpdate,
|
|
215
|
+
): RepositorySchedule {
|
|
216
|
+
return withControllerLock(controllerHome, { scope: 'task', repoId, taskId: `schedule-${scheduleId}` }, `update-schedule:${scheduleId}`, () => {
|
|
217
|
+
const current = getSchedule(controllerHome, repoId, scheduleId);
|
|
218
|
+
const changes = update(current);
|
|
219
|
+
return persistScheduleRevision(controllerHome, current, { ...current, ...changes });
|
|
155
220
|
}, 10_000);
|
|
156
221
|
}
|
|
157
222
|
|
|
@@ -269,7 +334,11 @@ export function saveOccurrence(controllerHome: string, occurrence: ScheduleOccur
|
|
|
269
334
|
const next = withControllerLock(controllerHome, { scope: 'task', repoId: occurrence.repoId, taskId: `schedule-${occurrence.scheduleId}` }, `save-occurrence:${occurrence.occurrenceId}`, () => {
|
|
270
335
|
const existingPath = occurrencePath(controllerHome, occurrence.repoId, occurrence.occurrenceId);
|
|
271
336
|
const previous = existsSync(existingPath) ? readJsonFile<ScheduleOccurrence>(existingPath) : undefined;
|
|
272
|
-
const
|
|
337
|
+
const expectedRevision = previous?.revision ?? 0;
|
|
338
|
+
if (occurrence.revision !== expectedRevision) {
|
|
339
|
+
throw new Error(`SCHEDULE_OCCURRENCE_REVISION_CONFLICT: ${occurrence.occurrenceId}:expected=${occurrence.revision}:actual=${expectedRevision}`);
|
|
340
|
+
}
|
|
341
|
+
const saved = { ...occurrence, revision: expectedRevision + 1, updatedAt: new Date().toISOString() };
|
|
273
342
|
writeJsonAtomic(existingPath, saved);
|
|
274
343
|
upsertOccurrenceIndexUnlocked(controllerHome, saved);
|
|
275
344
|
const schedule = getSchedule(controllerHome, saved.repoId, saved.scheduleId);
|