@taskforcehq/taskforce 0.3.328 → 0.3.329
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/dist/Taskforce.module.css +233 -34
- package/dist/TaskforceCore.js +237 -230
- package/dist/annotatedAttachments/AnnotatedAttachmentSessionStore.js +1 -1
- package/dist/cli.js +34 -0
- package/dist/cliCloudTargetGuard.d.ts +5 -0
- package/dist/cliCloudTargetGuard.js +11 -0
- package/dist/components/features/AnnotatedAttachmentWorkspace.js +24 -8
- package/dist/components/features/TaskSettings.d.ts +12 -1
- package/dist/components/features/TaskSettings.js +147 -40
- package/dist/components/features/agentCapabilities/AgentCapabilitiesPrototype.d.ts +1 -1
- package/dist/components/features/planning/PlanningModule.js +2 -5
- package/dist/components/features/planning/PlanningTaskOrderList.d.ts +1 -1
- package/dist/components/features/planning/PlanningTaskOrderList.js +17 -6
- package/dist/components/features/planning/planningTaskArrangement.d.ts +1 -0
- package/dist/components/features/planning/planningTaskArrangement.js +5 -5
- package/dist/components/features/taskforceAgentEditorModel.js +3 -1
- package/dist/components/task/TaskCard.d.ts +5 -0
- package/dist/components/task/TaskCard.js +65 -10
- package/dist/components/task/TaskImageReviews.js +14 -5
- package/dist/components/task/TaskKanban.d.ts +6 -1
- package/dist/components/task/TaskKanban.js +152 -6
- package/dist/components/task/TaskList.d.ts +5 -0
- package/dist/components/task/TaskList.js +3 -3
- package/dist/components/ui/PasswordInput.d.ts +6 -0
- package/dist/components/ui/PasswordInput.js +11 -0
- package/dist/components/ui/TopNoticeLayer.js +1 -1
- package/dist/components/views/AppShellHeader.js +32 -11
- package/dist/components/views/PlanComparisonPage.js +12 -0
- package/dist/components/views/StandaloneLayout.js +7 -31
- package/dist/components/views/WidgetView.js +3 -3
- package/dist/components/views/panels/PlanningDrawer.js +5 -12
- package/dist/components/views/standalone/modals/AccountSettingsModal.js +26 -17
- package/dist/config/envSchema.js +12 -0
- package/dist/config/localServiceRuntimeContract.d.ts +13 -0
- package/dist/config/localServiceRuntimeContract.js +135 -0
- package/dist/core/AiProfileService.js +46 -8
- package/dist/core/DeletedTaskLifecycleService.d.ts +1 -0
- package/dist/core/DeletedTaskLifecycleService.js +37 -6
- package/dist/core/TaskAttachmentLinksDurableMutationService.d.ts +3 -2
- package/dist/core/TaskAttachmentLinksDurableMutationService.js +33 -9
- package/dist/core/Taskforce.d.ts +62 -2
- package/dist/core/Taskforce.js +635 -32
- package/dist/core/types.d.ts +6 -0
- package/dist/hooks/sync/useDurableLocalOutboxDrain.d.ts +1 -1
- package/dist/hooks/sync/useDurableTaskCreateMutation.js +1 -1
- package/dist/hooks/sync/useDurableTaskMetadataMutation.d.ts +1 -0
- package/dist/hooks/sync/useDurableTaskMetadataMutation.js +1 -0
- package/dist/hooks/sync/useDurableTaskStatusMutation.d.ts +1 -0
- package/dist/hooks/tasks/taskHttpMutation.js +1 -0
- package/dist/hooks/tasks/useCloudTaskSearch.d.ts +12 -0
- package/dist/hooks/tasks/useCloudTaskSearch.js +71 -0
- package/dist/hooks/tasks/useTaskDescriptionImageDraftRecovery.d.ts +16 -0
- package/dist/hooks/tasks/useTaskDescriptionImageDraftRecovery.js +197 -0
- package/dist/hooks/tasks/useTaskEditorNavigation.d.ts +16 -3
- package/dist/hooks/tasks/useTaskEditorNavigation.js +72 -13
- package/dist/hooks/tasks/useTaskFormActions.d.ts +6 -0
- package/dist/hooks/tasks/useTaskFormActions.js +65 -12
- package/dist/hooks/ui/useSettingsModel.d.ts +24 -2
- package/dist/hooks/ui/useSettingsModel.js +13 -2
- package/dist/hooks/ui/useSettingsPersistence.d.ts +12 -1
- package/dist/hooks/ui/useSettingsPersistence.js +74 -47
- package/dist/hooks/useFilterSort.d.ts +7 -3
- package/dist/hooks/useFilterSort.js +15 -5
- package/dist/hooks/useTaskData.d.ts +10 -1
- package/dist/hooks/useTaskData.js +216 -7
- package/dist/hooks/useTaskMutations.d.ts +10 -2
- package/dist/hooks/useTaskMutations.js +223 -43
- package/dist/hooks/useTaskforce.d.ts +37 -9
- package/dist/hooks/useTaskforce.js +349 -39
- package/dist/hooks/useUiNotice.d.ts +4 -0
- package/dist/hooks/useUiNotice.js +4 -0
- package/dist/mcp/adminWorkspaceRegistrar.js +3 -3
- package/dist/mcp/documentAssetRegistrar.js +44 -35
- package/dist/mcp/documentHelpers.d.ts +1 -0
- package/dist/mcp/documentHelpers.js +7 -3
- package/dist/mcp/runtime.js +172 -42
- package/dist/mcp/taskPlanningRegistrar.js +41 -38
- package/dist/mcp/toolCallCompatibility.js +38 -1
- package/dist/mcp/toolCatalog.d.ts +1 -0
- package/dist/migrations/taskSchemaMigrations.js +12 -0
- package/dist/runtime/appGateDefinitions.d.ts +30 -6
- package/dist/runtime/appGateDefinitions.js +6 -6
- package/dist/runtime/appGates.d.ts +12 -13
- package/dist/runtime/appGates.js +29 -13
- package/dist/runtime/nodeAppGates.d.ts +8 -0
- package/dist/runtime/nodeAppGates.js +27 -0
- package/dist/server/cloudCollectionRead.d.ts +1 -1
- package/dist/server/cloudCollectionRead.js +2 -2
- package/dist/server/index.d.ts +3 -0
- package/dist/server/index.js +15 -3
- package/dist/server/localServiceLease.d.ts +3 -0
- package/dist/server/localServiceLease.js +9 -1
- package/dist/server/localWorkspaceSyncServerRuntime.js +10 -3
- package/dist/server/rateLimit.d.ts +1 -0
- package/dist/server/rateLimit.js +4 -0
- package/dist/server/realtimeSyncWs.js +36 -12
- package/dist/server/routes/admin.js +1 -0
- package/dist/server/routes/agentRoles.js +3 -2
- package/dist/server/routes/agentSkills.js +3 -2
- package/dist/server/routes/agents.js +118 -16
- package/dist/server/routes/annotatedAttachments.js +3 -2
- package/dist/server/routes/auth.js +3 -1
- package/dist/server/routes/durableTaskHttpRouters.d.ts +9 -2
- package/dist/server/routes/localService.js +2 -0
- package/dist/server/routes/primitives.d.ts +2 -0
- package/dist/server/routes/syncAuxRoutes.js +5 -2
- package/dist/server/routes/syncPullApplyRoutes.js +23 -4
- package/dist/server/routes/syncV3FeedRoutes.js +18 -16
- package/dist/server/routes/syncV3LocalCaptureRoutes.js +28 -2
- package/dist/server/routes/syncV3LocalFeedApplyRoutes.d.ts +1 -0
- package/dist/server/routes/syncV3LocalFeedApplyRoutes.js +26 -0
- package/dist/server/routes/syncV3OperationRoutes.js +10 -0
- package/dist/server/routes/tasks.js +103 -11
- package/dist/server/routes/workspaces.js +43 -1
- package/dist/server/workspaceDeletionAdmission.d.ts +23 -0
- package/dist/server/workspaceDeletionAdmission.js +50 -0
- package/dist/service/localServiceCli.js +16 -0
- package/dist/service/localServiceClientLifecycle.js +36 -10
- package/dist/services/codexAppServerModelGateway.d.ts +112 -0
- package/dist/services/codexAppServerModelGateway.js +438 -0
- package/dist/services/taskforceAgentMcpBridge.d.ts +7 -1
- package/dist/services/taskforceAgentMcpBridge.js +23 -3
- package/dist/shared/taskforceAgentDefinition.js +7 -1
- package/dist/shared/taskforceAgentModels.d.ts +1 -0
- package/dist/shared/taskforceAgentModels.js +30 -1
- package/dist/storage/postgresAdapter.d.ts +20 -3
- package/dist/storage/postgresAdapter.js +106 -14
- package/dist/storage/postgresWorker.js +13 -4
- package/dist/storage/postgresWorkerProtocol.d.ts +29 -0
- package/dist/storage/postgresWorkerProtocol.js +30 -0
- package/dist/sync/cloudSyncApi.d.ts +4 -1
- package/dist/sync/cloudSyncApi.js +7 -2
- package/dist/sync/contentSyncState.d.ts +1 -1
- package/dist/sync/coordinator/localSyncExecutionPermitStore.d.ts +1 -0
- package/dist/sync/coordinator/localSyncExecutionPermitStore.js +7 -1
- package/dist/sync/coordinator/localWorkspaceSyncRunner.js +6 -2
- package/dist/sync/engine/workspaceSyncEngineBrowserGatewayRemoteServices.js +20 -2
- package/dist/sync/engine/workspaceSyncEngineLocalServices.d.ts +4 -0
- package/dist/sync/engine/workspaceSyncEngineLocalServices.js +11 -0
- package/dist/sync/engine/workspaceSyncEngineRemoteServices.d.ts +11 -0
- package/dist/sync/engine/workspaceSyncEngineRemoteServices.js +2 -1
- package/dist/sync/engine/workspaceSyncEngineServerRemoteServices.js +31 -4
- package/dist/sync/engine/workspaceSyncEngineServerRunnerOperations.d.ts +3 -1
- package/dist/sync/engine/workspaceSyncEngineServerRunnerOperations.js +25 -8
- package/dist/sync/engine/workspaceSyncEngineTransfers.d.ts +1 -1
- package/dist/sync/engine/workspaceSyncEngineTransfers.js +8 -3
- package/dist/sync/syncService.d.ts +2 -0
- package/dist/sync/syncService.js +4 -1
- package/dist/sync/v3/combinedFeedCapability.js +4 -0
- package/dist/sync/v3/durableTaskAttachmentLinksMutationRouter.d.ts +2 -0
- package/dist/sync/v3/durableTaskAttachmentLinksMutationRouter.js +11 -1
- package/dist/sync/v3/durableTaskChecklistMutationRouter.d.ts +2 -0
- package/dist/sync/v3/durableTaskChecklistMutationRouter.js +4 -0
- package/dist/sync/v3/durableTaskHttpBulkMutationRouter.d.ts +1 -0
- package/dist/sync/v3/durableTaskHttpBulkMutationRouter.js +30 -8
- package/dist/sync/v3/durableTaskHttpRootMutationRouter.d.ts +5 -3
- package/dist/sync/v3/durableTaskHttpRootMutationRouter.js +27 -2
- package/dist/sync/v3/localTaskAttachmentLinksOutboxService.d.ts +2 -0
- package/dist/sync/v3/localTaskAttachmentLinksOutboxService.js +47 -7
- package/dist/sync/v3/localTaskCreateOutboxService.js +15 -6
- package/dist/sync/v3/localTaskMetadataClient.d.ts +1 -0
- package/dist/sync/v3/localTaskMetadataClient.js +1 -0
- package/dist/sync/v3/localTaskMetadataOutboxHandler.js +5 -1
- package/dist/sync/v3/localTaskMetadataOutboxService.d.ts +2 -0
- package/dist/sync/v3/localTaskMetadataOutboxService.js +7 -0
- package/dist/sync/v3/localTaskRestoreOutboxService.js +14 -6
- package/dist/sync/v3/localTaskStatusClient.d.ts +1 -0
- package/dist/sync/v3/localTaskStatusClient.js +6 -1
- package/dist/sync/v3/localTaskStatusOutboxService.d.ts +2 -0
- package/dist/sync/v3/localTaskStatusOutboxService.js +54 -13
- package/dist/sync/v3/syncDurabilityStore.d.ts +7 -0
- package/dist/sync/v3/syncDurabilityStore.js +31 -11
- package/dist/sync/v3/taskAttachmentLinksMutationService.d.ts +6 -4
- package/dist/sync/v3/taskAttachmentLinksMutationService.js +19 -10
- package/dist/sync/v3/taskChecklistMutationService.d.ts +4 -2
- package/dist/sync/v3/taskChecklistMutationService.js +4 -0
- package/dist/sync/v3/taskCreateMutationService.d.ts +2 -2
- package/dist/sync/v3/taskCreateMutationService.js +7 -4
- package/dist/sync/v3/taskMetadataMutationService.d.ts +3 -0
- package/dist/sync/v3/taskMetadataMutationService.js +4 -0
- package/dist/sync/v3/taskRestoreMutationService.d.ts +2 -2
- package/dist/sync/v3/taskRestoreMutationService.js +7 -4
- package/dist/sync/v3/taskStatusMutationService.d.ts +2 -0
- package/dist/sync/v3/taskStatusMutationService.js +4 -0
- package/dist/sync/v3/workflowAssignmentSync.d.ts +1 -0
- package/dist/sync/v3/workflowAssignmentSync.js +3 -0
- package/dist/sync/v3/workspaceSyncV2ProjectionExclusions.d.ts +1 -1
- package/dist/sync/v3/workspaceSyncV2ProjectionExclusions.js +13 -3
- package/dist/sync/v3/workspaceSyncV3AttachmentApplyObligationStore.d.ts +11 -0
- package/dist/sync/v3/workspaceSyncV3AttachmentApplyObligationStore.js +27 -10
- package/dist/sync/v3/workspaceSyncV3AttachmentAssetHydration.d.ts +2 -1
- package/dist/sync/v3/workspaceSyncV3AttachmentAssetHydration.js +52 -10
- package/dist/sync/v3/workspaceSyncV3CloudOperationHandler.js +9 -1
- package/dist/sync/v3/workspaceSyncV3CombinedFeedOrchestrator.js +8 -3
- package/dist/sync/v3/workspaceSyncV3CombinedLocalApply.js +51 -10
- package/dist/sync/v3/workspaceSyncV3CombinedRepairBaseline.d.ts +7 -0
- package/dist/sync/v3/workspaceSyncV3CombinedRepairBaseline.js +30 -18
- package/dist/sync/v3/workspaceSyncV3CombinedRepairMaterialization.d.ts +9 -4
- package/dist/sync/v3/workspaceSyncV3CombinedRepairMaterialization.js +98 -47
- package/dist/sync/v3/workspaceSyncV3CombinedRepairSnapshot.d.ts +10 -0
- package/dist/sync/v3/workspaceSyncV3CombinedRepairSnapshot.js +58 -21
- package/dist/sync/v3/workspaceSyncV3CombinedWireContract.d.ts +3 -1
- package/dist/sync/v3/workspaceSyncV3CombinedWireContract.js +18 -0
- package/dist/sync/v3/workspaceSyncV3CoverageRegistry.js +6 -0
- package/dist/sync/v3/workspaceSyncV3FeedProfile.d.ts +1 -1
- package/dist/sync/v3/workspaceSyncV3LegacyBoundaryAttestation.d.ts +1 -0
- package/dist/sync/v3/workspaceSyncV3LegacyBoundaryAttestation.js +23 -10
- package/dist/sync/v3/workspaceSyncV3NestedTaskApply.d.ts +3 -0
- package/dist/sync/v3/workspaceSyncV3NestedTaskApply.js +64 -13
- package/dist/sync/v3/workspaceSyncV3NestedTaskCodecs.d.ts +9 -0
- package/dist/sync/v3/workspaceSyncV3NestedTaskCodecs.js +26 -0
- package/dist/sync/v3/workspaceSyncV3NestedTaskProjection.d.ts +15 -5
- package/dist/sync/v3/workspaceSyncV3NestedTaskProjection.js +50 -14
- package/dist/sync/v3/workspaceSyncV3NestedTaskRepairSnapshot.d.ts +2 -1
- package/dist/sync/v3/workspaceSyncV3NestedTaskRepairSnapshot.js +11 -3
- package/dist/sync/v3/workspaceSyncV3OperationProtocol.d.ts +2 -0
- package/dist/sync/v3/workspaceSyncV3OperatorDiagnostics.d.ts +2 -0
- package/dist/sync/v3/workspaceSyncV3OperatorDiagnostics.js +19 -7
- package/dist/sync/v3/workspaceSyncV3TaskCommentAudit.js +9 -2
- package/dist/sync/v3/workspaceSyncV3TaskCoverCoverage.d.ts +7 -0
- package/dist/sync/v3/workspaceSyncV3TaskCoverCoverage.js +37 -0
- package/dist/sync/v3/workspaceSyncV3TaskCoverWireContract.d.ts +6 -0
- package/dist/sync/v3/workspaceSyncV3TaskCoverWireContract.js +9 -0
- package/dist/sync/workspacePullFeed.js +2 -1
- package/dist/sync/workspaceRepair.d.ts +3 -0
- package/dist/sync/workspaceRepair.js +67 -6
- package/dist/types.d.ts +47 -1
- package/dist/types.js +6 -0
- package/dist/ui/assets/{AiIdentityRosterCard-MZs7lVED.js → AiIdentityRosterCard-BZM4aQnM.js} +1 -1
- package/dist/ui/assets/AiProfilesModule-BbAEWtHH.js +1 -0
- package/dist/ui/assets/AnnotatedAttachmentWorkspace-B68Wg-RV.js +3 -0
- package/dist/ui/assets/AnnotatedAttachmentWorkspace-TzYu7pkG.css +1 -0
- package/dist/ui/assets/{AssetTraySortControl-Kf1pelSy.js → AssetTraySortControl-C8Rztyal.js} +1 -1
- package/dist/ui/assets/{ContextAttachmentManager-B8boOs6Q.js → ContextAttachmentManager-Cj3c7X9y.js} +2 -2
- package/dist/ui/assets/{DocumentWorkspace-DXH4XUsB.js → DocumentWorkspace-B5uvzems.js} +1 -1
- package/dist/ui/assets/{EntityActivityTimeline-BtSTq0ON.js → EntityActivityTimeline-BVFvCB5R.js} +1 -1
- package/dist/ui/assets/PlanningModule-B5DWQOGz.js +1 -0
- package/dist/ui/assets/PlansPage-AY4cGWco.js +1 -0
- package/dist/ui/assets/TaskContextUpload-DZxTVesW.js +1 -0
- package/dist/ui/assets/TaskSettings-BeWAuyZj.js +12 -0
- package/dist/ui/assets/{TaskforceAgentsModule-BazdUwxZ.js → TaskforceAgentsModule-BifCYtjR.js} +6 -6
- package/dist/ui/assets/{WorkflowManagerModule-DWFspC-o.js → WorkflowManagerModule-DEr5di_r.js} +1 -1
- package/dist/ui/assets/index-I5zhdtgt.js +7 -0
- package/dist/ui/assets/index-VRFsx3wz.css +1 -0
- package/dist/ui/assets/{vendor-icons-BkFLXavV.js → vendor-icons-D9Lpw-j4.js} +1 -1
- package/dist/ui/index.html +3 -3
- package/dist/utils/taskActivity.d.ts +3 -2
- package/dist/utils/taskActivity.js +19 -2
- package/dist/utils/taskEditorReconciliation.d.ts +40 -0
- package/dist/utils/taskEditorReconciliation.js +217 -0
- package/dist/utils/taskNormalization.d.ts +1 -0
- package/dist/utils/taskNormalization.js +39 -0
- package/dist/utils/taskSearch.js +2 -2
- package/dist/utils/uiNotice.d.ts +4 -0
- package/package.json +16 -4
- package/dist/ui/assets/AiProfilesModule-C3i0LOxe.js +0 -1
- package/dist/ui/assets/AnnotatedAttachmentWorkspace-CBRZ8rca.css +0 -1
- package/dist/ui/assets/AnnotatedAttachmentWorkspace-DVZk5Tln.js +0 -3
- package/dist/ui/assets/PlanningModule-BPVyEa-f.js +0 -1
- package/dist/ui/assets/PlansPage-ChqgxALc.js +0 -1
- package/dist/ui/assets/TaskContextUpload-CB3ol0sN.js +0 -1
- package/dist/ui/assets/TaskSettings-g4ECKNOz.js +0 -12
- package/dist/ui/assets/index-BUplSsv_.js +0 -7
- package/dist/ui/assets/index-gz2EXuoK.css +0 -1
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
export const WORKSPACE_DELETE_RETRY_COOLDOWN_MS = 30_000;
|
|
2
|
+
/**
|
|
3
|
+
* Serializes destructive workspace cleanup inside one server process and
|
|
4
|
+
* throttles immediate retries after an attempt settles. The caller supplies
|
|
5
|
+
* time so the admission policy can be verified without timers.
|
|
6
|
+
*/
|
|
7
|
+
export class WorkspaceDeletionAdmission {
|
|
8
|
+
cooldownMs;
|
|
9
|
+
entries = new Map();
|
|
10
|
+
constructor(cooldownMs = WORKSPACE_DELETE_RETRY_COOLDOWN_MS) {
|
|
11
|
+
this.cooldownMs = cooldownMs;
|
|
12
|
+
}
|
|
13
|
+
checkExisting(key, now = Date.now()) {
|
|
14
|
+
let existing = this.entries.get(key);
|
|
15
|
+
if (existing?.state === 'cooldown' && existing.retryAt <= now) {
|
|
16
|
+
this.entries.delete(key);
|
|
17
|
+
existing = undefined;
|
|
18
|
+
}
|
|
19
|
+
if (existing?.state === 'in-flight') {
|
|
20
|
+
return {
|
|
21
|
+
allowed: false,
|
|
22
|
+
code: 'WORKSPACE_DELETE_IN_PROGRESS',
|
|
23
|
+
retryAfterMs: Math.max(1_000, this.cooldownMs),
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
if (existing?.state === 'cooldown') {
|
|
27
|
+
return {
|
|
28
|
+
allowed: false,
|
|
29
|
+
code: 'WORKSPACE_DELETE_RETRY_COOLDOWN',
|
|
30
|
+
retryAfterMs: Math.max(1_000, existing.retryAt - now),
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
return null;
|
|
34
|
+
}
|
|
35
|
+
acquire(key, now = Date.now()) {
|
|
36
|
+
const existing = this.checkExisting(key, now);
|
|
37
|
+
if (existing)
|
|
38
|
+
return existing;
|
|
39
|
+
this.entries.set(key, { state: 'in-flight' });
|
|
40
|
+
return { allowed: true };
|
|
41
|
+
}
|
|
42
|
+
settle(key, now = Date.now()) {
|
|
43
|
+
if (this.entries.get(key)?.state !== 'in-flight')
|
|
44
|
+
return;
|
|
45
|
+
this.entries.set(key, {
|
|
46
|
+
state: 'cooldown',
|
|
47
|
+
retryAt: now + this.cooldownMs,
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import * as fs from 'fs';
|
|
2
2
|
import * as path from 'path';
|
|
3
3
|
import { applyLocalServiceCloudTarget, localServiceCloudTargetsEqual, parseLocalServiceCloudTarget, resolveLocalServiceCloudTarget, } from '../config/localServiceCloudTarget.js';
|
|
4
|
+
import { localServiceRuntimeContractsEqual, parseLocalServiceRuntimeContract, resolveLocalServiceRuntimeContract, } from '../config/localServiceRuntimeContract.js';
|
|
4
5
|
import { createStandaloneServer } from '../server/index.js';
|
|
5
6
|
import { inspectLocalServiceDescriptor, redactLocalServiceDescriptor, } from '../server/localServiceLease.js';
|
|
6
7
|
import { acquireLocalServiceOwnershipForRuntime, } from '../server/localServiceOwnershipBootstrap.js';
|
|
@@ -66,6 +67,13 @@ function reportCloudTargetMismatch(descriptorTarget, requestedTarget, error) {
|
|
|
66
67
|
+ 'Stop it with `taskforce service stop --drain`, then retry.');
|
|
67
68
|
return true;
|
|
68
69
|
}
|
|
70
|
+
function reportRuntimeContractMismatch(descriptorContract, requestedContract, error) {
|
|
71
|
+
if (localServiceRuntimeContractsEqual(descriptorContract, requestedContract))
|
|
72
|
+
return false;
|
|
73
|
+
error('Taskforce service is running with a different or unverified local runtime contract. '
|
|
74
|
+
+ 'Stop it with `taskforce service stop --drain`, then retry.');
|
|
75
|
+
return true;
|
|
76
|
+
}
|
|
69
77
|
function defaultRegisterShutdownSignals(handler) {
|
|
70
78
|
process.once('SIGINT', handler);
|
|
71
79
|
process.once('SIGTERM', handler);
|
|
@@ -85,6 +93,7 @@ async function waitForDescriptor(input, expected, options) {
|
|
|
85
93
|
async function runForeground(command, options) {
|
|
86
94
|
const requestedCloudTarget = resolveLocalServiceCloudTarget(options.env);
|
|
87
95
|
applyLocalServiceCloudTarget(options.env, requestedCloudTarget);
|
|
96
|
+
const requestedRuntimeContract = resolveLocalServiceRuntimeContract(options.env);
|
|
88
97
|
const ownership = await options.acquireOwnership(command.projectRoot, options.env);
|
|
89
98
|
if (!ownership)
|
|
90
99
|
throw new Error('The shared local service requires local runtime mode.');
|
|
@@ -96,6 +105,8 @@ async function runForeground(command, options) {
|
|
|
96
105
|
return 2;
|
|
97
106
|
if (reportCloudTargetMismatch(inspection.descriptor.cloudTarget, requestedCloudTarget, options.error))
|
|
98
107
|
return 2;
|
|
108
|
+
if (reportRuntimeContractMismatch(inspection.descriptor.runtimeContract, requestedRuntimeContract, options.error))
|
|
109
|
+
return 2;
|
|
99
110
|
options.log(`Taskforce service is already running at ${inspection.descriptor.endpoint}.`);
|
|
100
111
|
return 0;
|
|
101
112
|
}
|
|
@@ -129,6 +140,7 @@ async function runForeground(command, options) {
|
|
|
129
140
|
bootstrapCapability: ownership.lease.bootstrapCapability,
|
|
130
141
|
ownershipKey: ownership.lease.identity.ownershipKey,
|
|
131
142
|
cloudTarget: requestedCloudTarget,
|
|
143
|
+
runtimeContract: requestedRuntimeContract,
|
|
132
144
|
},
|
|
133
145
|
afterShutdown: async () => {
|
|
134
146
|
removeSignals();
|
|
@@ -152,6 +164,7 @@ async function runForeground(command, options) {
|
|
|
152
164
|
protocolVersion: LOCAL_SERVICE_PROTOCOL_VERSION,
|
|
153
165
|
appVersion: options.appVersion,
|
|
154
166
|
cloudTarget: requestedCloudTarget,
|
|
167
|
+
runtimeContract: requestedRuntimeContract,
|
|
155
168
|
});
|
|
156
169
|
removeSignals = options.registerShutdownSignals(shutdown);
|
|
157
170
|
server.once('error', (error) => {
|
|
@@ -231,11 +244,14 @@ async function runStatus(command, options) {
|
|
|
231
244
|
const payload = await response.json();
|
|
232
245
|
const coordinatorPayload = payload.coordinator;
|
|
233
246
|
const diagnosticCloudTarget = parseLocalServiceCloudTarget(payload.cloudTarget);
|
|
247
|
+
const diagnosticRuntimeContract = parseLocalServiceRuntimeContract(payload.runtimeContract);
|
|
234
248
|
if (payload.ownerPid !== inspection.descriptor.pid
|
|
235
249
|
|| payload.generation !== inspection.descriptor.generation
|
|
236
250
|
|| payload.protocolVersion !== inspection.descriptor.protocolVersion
|
|
237
251
|
|| (inspection.descriptor.cloudTarget
|
|
238
252
|
&& !localServiceCloudTargetsEqual(diagnosticCloudTarget, inspection.descriptor.cloudTarget))
|
|
253
|
+
|| (inspection.descriptor.runtimeContract
|
|
254
|
+
&& !localServiceRuntimeContractsEqual(diagnosticRuntimeContract, inspection.descriptor.runtimeContract))
|
|
239
255
|
|| !Array.isArray(payload.sessions)
|
|
240
256
|
|| !coordinatorPayload
|
|
241
257
|
|| typeof coordinatorPayload !== 'object'
|
|
@@ -2,6 +2,7 @@ import { spawn } from 'child_process';
|
|
|
2
2
|
import * as fs from 'fs';
|
|
3
3
|
import * as path from 'path';
|
|
4
4
|
import { applyLocalServiceCloudTarget, localServiceCloudTargetsEqual, parseLocalServiceCloudTarget, resolveLocalServiceCloudTarget, } from '../config/localServiceCloudTarget.js';
|
|
5
|
+
import { localServiceRuntimeContractsEqual, parseLocalServiceRuntimeContract, resolveLocalServiceRuntimeContract, } from '../config/localServiceRuntimeContract.js';
|
|
5
6
|
import { inspectLocalServiceDescriptor, } from '../server/localServiceLease.js';
|
|
6
7
|
import { resolveLocalDatabaseIdentity } from '../server/localDatabaseIdentity.js';
|
|
7
8
|
export const LOCAL_SERVICE_PROTOCOL_VERSION = '1';
|
|
@@ -23,6 +24,11 @@ const LOCAL_MCP_CLIENT_ENV_KEYS = [
|
|
|
23
24
|
'TASKFORCE_AI_SURFACE_TYPE',
|
|
24
25
|
'TASKFORCE_AI_SEAT_SCOPE',
|
|
25
26
|
];
|
|
27
|
+
function isQaIdentityEnvironmentKey(key) {
|
|
28
|
+
return key.startsWith('TASKFORCE_E2E_')
|
|
29
|
+
|| key.startsWith('TASKFORCE_PLAYWRIGHT_')
|
|
30
|
+
|| key.startsWith('SYNC_SOAK_');
|
|
31
|
+
}
|
|
26
32
|
export function resolveLocalServiceLeaseInput(projectRoot, env) {
|
|
27
33
|
const provider = env.TASKFORCE_DB_PROVIDER === 'postgres' ? 'postgres' : 'sqlite';
|
|
28
34
|
return {
|
|
@@ -44,6 +50,10 @@ function buildLocalServiceProcessEnv(env, cloudTarget) {
|
|
|
44
50
|
const serviceEnv = { ...env };
|
|
45
51
|
for (const key of LOCAL_MCP_CLIENT_ENV_KEYS)
|
|
46
52
|
delete serviceEnv[key];
|
|
53
|
+
for (const key of Object.keys(serviceEnv)) {
|
|
54
|
+
if (isQaIdentityEnvironmentKey(key))
|
|
55
|
+
delete serviceEnv[key];
|
|
56
|
+
}
|
|
47
57
|
applyLocalServiceCloudTarget(serviceEnv, cloudTarget);
|
|
48
58
|
return serviceEnv;
|
|
49
59
|
}
|
|
@@ -84,10 +94,18 @@ async function validateLocalServiceReadiness(descriptor, fetchFn) {
|
|
|
84
94
|
const readinessCloudTarget = readinessHasCloudTarget
|
|
85
95
|
? parseLocalServiceCloudTarget(readiness.cloudTarget)
|
|
86
96
|
: null;
|
|
97
|
+
const readinessHasRuntimeContract = Object.prototype.hasOwnProperty.call(readiness, 'runtimeContract');
|
|
98
|
+
const readinessRuntimeContract = readinessHasRuntimeContract
|
|
99
|
+
? parseLocalServiceRuntimeContract(readiness.runtimeContract)
|
|
100
|
+
: null;
|
|
87
101
|
const descriptorCloudTarget = descriptor.cloudTarget || null;
|
|
102
|
+
const descriptorRuntimeContract = descriptor.runtimeContract || null;
|
|
88
103
|
const cloudTargetsMatch = descriptorCloudTarget || readinessCloudTarget
|
|
89
104
|
? localServiceCloudTargetsEqual(descriptorCloudTarget, readinessCloudTarget)
|
|
90
105
|
: true;
|
|
106
|
+
const runtimeContractsMatch = descriptorRuntimeContract || readinessRuntimeContract
|
|
107
|
+
? localServiceRuntimeContractsEqual(descriptorRuntimeContract, readinessRuntimeContract)
|
|
108
|
+
: true;
|
|
91
109
|
if (readiness.ready !== true
|
|
92
110
|
|| readiness.protocolVersion !== LOCAL_SERVICE_PROTOCOL_VERSION
|
|
93
111
|
|| readiness.protocolVersion !== descriptor.protocolVersion
|
|
@@ -96,10 +114,15 @@ async function validateLocalServiceReadiness(descriptor, fetchFn) {
|
|
|
96
114
|
|| readiness.endpoint !== descriptor.endpoint
|
|
97
115
|
|| readiness.dataIdentity !== descriptor.ownershipKey
|
|
98
116
|
|| (readinessHasCloudTarget && !readinessCloudTarget)
|
|
99
|
-
|| !cloudTargetsMatch
|
|
117
|
+
|| !cloudTargetsMatch
|
|
118
|
+
|| (readinessHasRuntimeContract && !readinessRuntimeContract)
|
|
119
|
+
|| !runtimeContractsMatch) {
|
|
100
120
|
throw new Error('Taskforce shared local service readiness does not match its descriptor.');
|
|
101
121
|
}
|
|
102
|
-
return
|
|
122
|
+
return {
|
|
123
|
+
cloudTarget: descriptorCloudTarget,
|
|
124
|
+
runtimeContract: descriptorRuntimeContract,
|
|
125
|
+
};
|
|
103
126
|
}
|
|
104
127
|
async function requestIdleLocalServiceShutdown(descriptor, fetchFn) {
|
|
105
128
|
let response;
|
|
@@ -121,7 +144,7 @@ async function requestIdleLocalServiceShutdown(descriptor, fetchFn) {
|
|
|
121
144
|
});
|
|
122
145
|
}
|
|
123
146
|
catch (error) {
|
|
124
|
-
throw new Error('Taskforce service uses a different cloud target and could not be stopped safely. '
|
|
147
|
+
throw new Error('Taskforce service uses a different cloud target or runtime contract and could not be stopped safely. '
|
|
125
148
|
+ `No replacement was started. ${String(error?.message || error)}`);
|
|
126
149
|
}
|
|
127
150
|
if (!response.ok) {
|
|
@@ -129,7 +152,7 @@ async function requestIdleLocalServiceShutdown(descriptor, fetchFn) {
|
|
|
129
152
|
const activeClientHint = response.status === 409
|
|
130
153
|
? ' It may have active MCP clients; close them or run `taskforce service stop --drain`, then retry.'
|
|
131
154
|
: '';
|
|
132
|
-
throw new Error(`Taskforce service uses a different cloud target and refused safe idle replacement (${response.status}).`
|
|
155
|
+
throw new Error(`Taskforce service uses a different cloud target or runtime contract and refused safe idle replacement (${response.status}).`
|
|
133
156
|
+ activeClientHint
|
|
134
157
|
+ (detail ? ` ${detail}` : ''));
|
|
135
158
|
}
|
|
@@ -141,13 +164,15 @@ export async function discoverOrStartLocalService(input) {
|
|
|
141
164
|
const inspectDescriptor = input.inspectDescriptor || inspectLocalServiceDescriptor;
|
|
142
165
|
const fetchFn = input.fetch || fetch;
|
|
143
166
|
const requestedCloudTarget = resolveLocalServiceCloudTarget(input.env);
|
|
167
|
+
const requestedRuntimeContract = resolveLocalServiceRuntimeContract(input.env);
|
|
144
168
|
const current = await inspectDescriptor(leaseInput);
|
|
145
169
|
if (current.status === 'live' && current.descriptor) {
|
|
146
170
|
if (current.descriptor.protocolVersion !== LOCAL_SERVICE_PROTOCOL_VERSION) {
|
|
147
171
|
throw new Error(`Taskforce service protocol ${current.descriptor.protocolVersion} is incompatible with client protocol ${LOCAL_SERVICE_PROTOCOL_VERSION}.`);
|
|
148
172
|
}
|
|
149
|
-
const
|
|
150
|
-
if (localServiceCloudTargetsEqual(
|
|
173
|
+
const running = await validateLocalServiceReadiness(current.descriptor, fetchFn);
|
|
174
|
+
if (localServiceCloudTargetsEqual(running.cloudTarget, requestedCloudTarget)
|
|
175
|
+
&& localServiceRuntimeContractsEqual(running.runtimeContract, requestedRuntimeContract)) {
|
|
151
176
|
return current.descriptor;
|
|
152
177
|
}
|
|
153
178
|
await requestIdleLocalServiceShutdown(current.descriptor, fetchFn);
|
|
@@ -157,7 +182,7 @@ export async function discoverOrStartLocalService(input) {
|
|
|
157
182
|
nowMs: input.nowMs,
|
|
158
183
|
});
|
|
159
184
|
if (stopped.status !== 'stale') {
|
|
160
|
-
throw new Error('Taskforce service accepted
|
|
185
|
+
throw new Error('Taskforce service accepted configuration replacement but did not release its owner lease. No replacement was started.');
|
|
161
186
|
}
|
|
162
187
|
}
|
|
163
188
|
if (current.status === 'indeterminate') {
|
|
@@ -181,9 +206,10 @@ export async function discoverOrStartLocalService(input) {
|
|
|
181
206
|
if (inspection.descriptor.protocolVersion !== LOCAL_SERVICE_PROTOCOL_VERSION) {
|
|
182
207
|
throw new Error(`Taskforce service protocol ${inspection.descriptor.protocolVersion} is incompatible with client protocol ${LOCAL_SERVICE_PROTOCOL_VERSION}.`);
|
|
183
208
|
}
|
|
184
|
-
const
|
|
185
|
-
if (!localServiceCloudTargetsEqual(
|
|
186
|
-
|
|
209
|
+
const started = await validateLocalServiceReadiness(inspection.descriptor, fetchFn);
|
|
210
|
+
if (!localServiceCloudTargetsEqual(started.cloudTarget, requestedCloudTarget)
|
|
211
|
+
|| !localServiceRuntimeContractsEqual(started.runtimeContract, requestedRuntimeContract)) {
|
|
212
|
+
throw new Error('Taskforce service started with a different or unverified cloud target/runtime contract; refusing to attach.');
|
|
187
213
|
}
|
|
188
214
|
return inspection.descriptor;
|
|
189
215
|
}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import type { ModelGateway, ModelGatewayGenerateInput, ModelGatewayGenerateResult } from './modelGateway.js';
|
|
2
|
+
export type CodexAppServerModelKeyIdMap = Partial<Record<string, string>>;
|
|
3
|
+
type CodexAppServerApprovalPolicy = 'never';
|
|
4
|
+
type CodexAppServerSandboxMode = 'read-only';
|
|
5
|
+
type CodexAppServerSandboxPolicy = {
|
|
6
|
+
type: 'readOnly';
|
|
7
|
+
networkAccess: false;
|
|
8
|
+
};
|
|
9
|
+
type CodexAppServerRuntimePolicy = {
|
|
10
|
+
cwd: string;
|
|
11
|
+
approvalPolicy: CodexAppServerApprovalPolicy;
|
|
12
|
+
sandbox: CodexAppServerSandboxMode;
|
|
13
|
+
sandboxPolicy: CodexAppServerSandboxPolicy;
|
|
14
|
+
};
|
|
15
|
+
export interface CodexAppServerClient {
|
|
16
|
+
initialize(): Promise<void>;
|
|
17
|
+
assertChatGptSubscriptionAuth(): Promise<void>;
|
|
18
|
+
startThread(input: {
|
|
19
|
+
model: string;
|
|
20
|
+
developerInstructions?: string;
|
|
21
|
+
} & CodexAppServerRuntimePolicy): Promise<{
|
|
22
|
+
threadId: string;
|
|
23
|
+
}>;
|
|
24
|
+
startTurnAndCollectText(input: {
|
|
25
|
+
threadId: string;
|
|
26
|
+
prompt: string;
|
|
27
|
+
model: string;
|
|
28
|
+
timeoutMs: number;
|
|
29
|
+
} & CodexAppServerRuntimePolicy): Promise<{
|
|
30
|
+
text: string;
|
|
31
|
+
stopReason?: string;
|
|
32
|
+
}>;
|
|
33
|
+
close(): void;
|
|
34
|
+
}
|
|
35
|
+
export interface CodexAppServerModelGatewayOptions {
|
|
36
|
+
client?: CodexAppServerClient;
|
|
37
|
+
clientFactory?: () => CodexAppServerClient;
|
|
38
|
+
command?: string;
|
|
39
|
+
args?: string[];
|
|
40
|
+
cwd?: string;
|
|
41
|
+
env?: NodeJS.ProcessEnv;
|
|
42
|
+
modelKeyIds?: CodexAppServerModelKeyIdMap;
|
|
43
|
+
timeoutMs?: number;
|
|
44
|
+
requestTimeoutMs?: number;
|
|
45
|
+
}
|
|
46
|
+
export declare const DEFAULT_CODEX_APP_SERVER_MODEL_KEY_IDS: CodexAppServerModelKeyIdMap;
|
|
47
|
+
export declare function buildCodexAppServerEnv(source?: NodeJS.ProcessEnv): NodeJS.ProcessEnv;
|
|
48
|
+
export declare function sanitizeCodexAppServerStderr(value: unknown): string;
|
|
49
|
+
export declare function collectCodexAppServerStderr(current: string, chunk: unknown): string;
|
|
50
|
+
export declare function assertCodexChatGptSubscriptionAccount(result: unknown): void;
|
|
51
|
+
export declare function isCodexSubscriptionDevRuntimeAllowed(source?: NodeJS.ProcessEnv): boolean;
|
|
52
|
+
export declare function extractCodexTurnCompletion(messages: unknown[]): {
|
|
53
|
+
text: string;
|
|
54
|
+
stopReason: string;
|
|
55
|
+
} | null;
|
|
56
|
+
export declare class CodexAppServerJsonRpcClient implements CodexAppServerClient {
|
|
57
|
+
private readonly process;
|
|
58
|
+
private readonly pending;
|
|
59
|
+
private readonly notifications;
|
|
60
|
+
private nextId;
|
|
61
|
+
private initialized;
|
|
62
|
+
private readonly lineReader;
|
|
63
|
+
private readonly requestTimeoutMs;
|
|
64
|
+
private readonly turnRejectors;
|
|
65
|
+
private terminalError;
|
|
66
|
+
private stderrTail;
|
|
67
|
+
constructor(options?: {
|
|
68
|
+
command?: string;
|
|
69
|
+
args?: string[];
|
|
70
|
+
cwd?: string;
|
|
71
|
+
env?: NodeJS.ProcessEnv;
|
|
72
|
+
requestTimeoutMs?: number;
|
|
73
|
+
});
|
|
74
|
+
initialize(): Promise<void>;
|
|
75
|
+
assertChatGptSubscriptionAuth(): Promise<void>;
|
|
76
|
+
startThread(input: {
|
|
77
|
+
model: string;
|
|
78
|
+
developerInstructions?: string;
|
|
79
|
+
} & CodexAppServerRuntimePolicy): Promise<{
|
|
80
|
+
threadId: string;
|
|
81
|
+
}>;
|
|
82
|
+
startTurnAndCollectText(input: {
|
|
83
|
+
threadId: string;
|
|
84
|
+
prompt: string;
|
|
85
|
+
system?: string;
|
|
86
|
+
model: string;
|
|
87
|
+
timeoutMs: number;
|
|
88
|
+
} & CodexAppServerRuntimePolicy): Promise<{
|
|
89
|
+
text: string;
|
|
90
|
+
stopReason?: string;
|
|
91
|
+
}>;
|
|
92
|
+
close(): void;
|
|
93
|
+
private request;
|
|
94
|
+
private sendNotification;
|
|
95
|
+
private handleLine;
|
|
96
|
+
private sendResponseError;
|
|
97
|
+
private waitForTurnCompletion;
|
|
98
|
+
private rejectAll;
|
|
99
|
+
private fail;
|
|
100
|
+
}
|
|
101
|
+
export declare class CodexAppServerModelGateway implements ModelGateway {
|
|
102
|
+
private readonly client?;
|
|
103
|
+
private readonly clientFactory;
|
|
104
|
+
private readonly modelKeyIds;
|
|
105
|
+
private readonly timeoutMs;
|
|
106
|
+
private readonly cwd;
|
|
107
|
+
constructor(options?: CodexAppServerModelGatewayOptions);
|
|
108
|
+
generate(input: ModelGatewayGenerateInput): Promise<ModelGatewayGenerateResult>;
|
|
109
|
+
private resolveModelId;
|
|
110
|
+
private formatMessages;
|
|
111
|
+
}
|
|
112
|
+
export {};
|