@iaforged/context-code 1.0.77 → 1.0.79
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/README.md +68 -68
- package/cli.js +8515 -8515
- package/context-bootstrap.js +27 -27
- package/dist/src/bootstrap/state.js +3 -0
- package/dist/src/bridge/bridgeMain.js +40 -40
- package/dist/src/cli/print.js +12 -12
- package/dist/src/commands/agent/agent.js +8 -0
- package/dist/src/commands/commit-push-pr.js +55 -55
- package/dist/src/commands/createMovedToPluginCommand.js +9 -9
- package/dist/src/commands/init-verifiers.js +238 -238
- package/dist/src/commands/init.js +216 -216
- package/dist/src/commands/install.js +2 -2
- package/dist/src/commands/login/login.js +24 -10
- package/dist/src/commands/orchestrate/index.js +1 -1
- package/dist/src/commands/orchestrate/orchestrate.js +110 -24
- package/dist/src/commands/profile/profile.js +15 -1
- package/dist/src/commands/provider/index.js +1 -1
- package/dist/src/commands/provider/provider.js +34 -1
- package/dist/src/commands/review.js +22 -22
- package/dist/src/commands/run/index.js +2 -2
- package/dist/src/commands/run/run.js +63 -61
- package/dist/src/commands/team/index.js +1 -1
- package/dist/src/commands/team/team.js +84 -76
- package/dist/src/commands/team-auto/teamAuto.js +89 -29
- package/dist/src/commands/terminalSetup/terminalSetup.js +24 -24
- package/dist/src/commands/usage/index.js +7 -0
- package/dist/src/commands/usage/usage.js +5 -0
- package/dist/src/commands/workspace/workspace.js +39 -31
- package/dist/src/commands.js +0 -2
- package/dist/src/components/ConsoleOAuthFlow.js +92 -14
- package/dist/src/components/ModelPicker.js +2 -0
- package/dist/src/components/agents/generateAgent.js +92 -92
- package/dist/src/components/grove/Grove.js +10 -10
- package/dist/src/components/permissions/AskUserQuestionPermissionRequest/AskUserQuestionPermissionRequest.js +8 -8
- package/dist/src/constants/geminiOAuth.js +13 -0
- package/dist/src/constants/github-app.js +134 -134
- package/dist/src/constants/prompts.js +123 -123
- package/dist/src/coordinator/coordinatorMode.js +252 -252
- package/dist/src/hooks/useTypeahead.js +7 -7
- package/dist/src/ink/reconciler.js +7 -7
- package/dist/src/main.js +5 -5
- package/dist/src/memdir/findRelevantMemories.js +6 -6
- package/dist/src/services/MagicDocs/prompts.js +56 -56
- package/dist/src/services/PromptSuggestion/promptSuggestion.js +29 -29
- package/dist/src/services/SessionMemory/prompts.js +66 -66
- package/dist/src/services/api/openai.js +584 -21
- package/dist/src/services/limits/adapters/ollama.js +3 -3
- package/dist/src/services/oauth/geminiCli.js +107 -0
- package/dist/src/services/orchestration/execution/AgentTaskExecutor.js +5 -3
- package/dist/src/services/orchestration/execution/OrchestrationExecutionRuntime.js +18 -18
- package/dist/src/services/orchestration/global/reporting.js +2 -2
- package/dist/src/services/toolUseSummary/toolUseSummaryGenerator.js +9 -9
- package/dist/src/skills/bundled/batch.js +78 -78
- package/dist/src/skills/bundled/claudeApi.js +34 -34
- package/dist/src/skills/bundled/claudeInChrome.js +4 -4
- package/dist/src/skills/bundled/debug.js +36 -36
- package/dist/src/skills/bundled/scheduleRemoteAgents.js +151 -151
- package/dist/src/skills/bundled/skillify.js +132 -132
- package/dist/src/skills/bundled/stuck.js +53 -53
- package/dist/src/skills/bundled/updateConfig.js +418 -418
- package/dist/src/tasks/RemoteAgentTask/RemoteAgentTask.js +26 -26
- package/dist/src/tools/AgentTool/AgentTool.js +7 -7
- package/dist/src/tools/AgentTool/built-in/claudeCodeGuideAgent.js +67 -67
- package/dist/src/tools/AgentTool/built-in/exploreAgent.js +32 -32
- package/dist/src/tools/AgentTool/built-in/generalPurposeAgent.js +13 -13
- package/dist/src/tools/AgentTool/built-in/planAgent.js +49 -49
- package/dist/src/tools/AgentTool/built-in/statuslineSetup.js +129 -129
- package/dist/src/tools/AgentTool/built-in/verificationAgent.js +119 -119
- package/dist/src/tools/AgentTool/prompt.js +131 -131
- package/dist/src/tools/AgentTool/runAgent.js +9 -9
- package/dist/src/tools/BashTool/BashTool.js +10 -10
- package/dist/src/tools/BashTool/prompt.js +94 -94
- package/dist/src/tools/ConfigTool/prompt.js +29 -29
- package/dist/src/tools/EnterWorktreeTool/prompt.js +27 -27
- package/dist/src/tools/FileReadTool/prompt.js +12 -12
- package/dist/src/tools/PowerShellTool/prompt.js +82 -82
- package/dist/src/tools/RemoteTriggerTool/prompt.js +9 -9
- package/dist/src/tools/ScheduleCronTool/prompt.js +37 -37
- package/dist/src/tools/TeamCreateTool/prompt.js +110 -110
- package/dist/src/tools/TeamDeleteTool/prompt.js +13 -13
- package/dist/src/utils/advisor.js +15 -15
- package/dist/src/utils/api.js +2 -2
- package/dist/src/utils/auth.js +207 -2
- package/dist/src/utils/autoUpdater.js +18 -18
- package/dist/src/utils/bash/ShellSnapshot.js +86 -86
- package/dist/src/utils/bash/commands.js +61 -61
- package/dist/src/utils/claudeInChrome/prompt.js +53 -53
- package/dist/src/utils/claudeInChrome/setup.js +8 -8
- package/dist/src/utils/databaseMcp/server/queries.js +632 -632
- package/dist/src/utils/deepLink/registerProtocol.js +35 -35
- package/dist/src/utils/deepLink/terminalLauncher.js +12 -12
- package/dist/src/utils/hooks/execAgentHook.js +7 -7
- package/dist/src/utils/hooks/execPromptHook.js +4 -4
- package/dist/src/utils/hooks/skillImprovement.js +36 -36
- package/dist/src/utils/logoV2Utils.js +1 -1
- package/dist/src/utils/mcp/dateTimeParser.js +9 -9
- package/dist/src/utils/messages.js +191 -191
- package/dist/src/utils/model/model.js +18 -0
- package/dist/src/utils/model/modelOptions.js +51 -1
- package/dist/src/utils/model/modelStrings.js +5 -1
- package/dist/src/utils/model/modelSupportOverrides.js +3 -0
- package/dist/src/utils/model/providerBaseUrls.js +6 -1
- package/dist/src/utils/model/providerCatalog.js +64 -28
- package/dist/src/utils/model/providerModels.js +88 -17
- package/dist/src/utils/model/providerProfiles.js +8 -0
- package/dist/src/utils/model/providerProfilesDb.js +578 -393
- package/dist/src/utils/model/providerSwitch.js +12 -0
- package/dist/src/utils/model/providerWorkspaces.js +2 -0
- package/dist/src/utils/model/providers.js +65 -2
- package/dist/src/utils/orchestration/store/providerWorkspaceStore.js +3 -1
- package/dist/src/utils/orchestration/store/runStore.js +47 -47
- package/dist/src/utils/orchestration/store/teamStore.js +61 -61
- package/dist/src/utils/powershell/parser.js +253 -253
- package/dist/src/utils/sessionTitle.js +12 -12
- package/dist/src/utils/sideQuestion.js +17 -17
- package/dist/src/utils/status.js +1 -1
- package/dist/src/utils/swarm/backends/registry.js +9 -9
- package/dist/src/utils/telemetry/instrumentation.js +9 -9
- package/dist/src/utils/teleport.js +15 -15
- package/dist/src/utils/undercover.js +28 -28
- package/package.json +1 -1
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { resetModelCapabilityOverridesForProviderChange } from './modelSupportOverrides.js';
|
|
2
|
+
import { resetModelStringsForProviderChange } from './modelStrings.js';
|
|
1
3
|
import { getStoredLastModelForProvider, setStoredActiveProviderPreference, setStoredLastModelForProvider, } from './providerProfilesDb.js';
|
|
2
4
|
import { getProviderProfileLastModel, isProfiledProvider, setActiveProfileForProvider, setProviderProfileLastModel, } from './providerProfiles.js';
|
|
3
5
|
export function toProviderPreference(provider) {
|
|
@@ -9,6 +11,10 @@ export function toProviderPreference(provider) {
|
|
|
9
11
|
return 'ollama';
|
|
10
12
|
if (provider === 'ollama-cloud')
|
|
11
13
|
return 'ollama-cloud';
|
|
14
|
+
if (provider === 'gemini-api')
|
|
15
|
+
return 'gemini-api';
|
|
16
|
+
if (provider === 'gemini-google')
|
|
17
|
+
return 'gemini-google';
|
|
12
18
|
if (provider === 'zai')
|
|
13
19
|
return 'zai';
|
|
14
20
|
if (provider === 'minimax')
|
|
@@ -34,6 +40,8 @@ export function switchProviderPreference(params) {
|
|
|
34
40
|
params.currentProvider === 'openrouter' ||
|
|
35
41
|
params.currentProvider === 'ollama' ||
|
|
36
42
|
params.currentProvider === 'ollama-cloud' ||
|
|
43
|
+
params.currentProvider === 'gemini-api' ||
|
|
44
|
+
params.currentProvider === 'gemini-google' ||
|
|
37
45
|
params.currentProvider === 'zai' ||
|
|
38
46
|
params.currentProvider === 'minimax'
|
|
39
47
|
? params.currentProvider
|
|
@@ -46,5 +54,9 @@ export function switchProviderPreference(params) {
|
|
|
46
54
|
setActiveProfileForProvider(params.targetProvider, params.targetProfileName ?? undefined);
|
|
47
55
|
}
|
|
48
56
|
setStoredActiveProviderPreference(params.targetProvider);
|
|
57
|
+
if (sourceProvider !== params.targetProvider) {
|
|
58
|
+
resetModelStringsForProviderChange();
|
|
59
|
+
resetModelCapabilityOverridesForProviderChange();
|
|
60
|
+
}
|
|
49
61
|
return getStoredModelForProvider(params.targetProvider);
|
|
50
62
|
}
|
|
@@ -65,15 +65,62 @@ export function isOllamaProviderConfigured() {
|
|
|
65
65
|
}
|
|
66
66
|
export function isOllamaCloudProviderConfigured() {
|
|
67
67
|
try {
|
|
68
|
+
const storage = getSecureStorage().read();
|
|
69
|
+
const scopedKeys = Object.entries(storage?.providerProfileApiKeys ?? {}).some(([key, value]) => key.startsWith('ollama-cloud/') &&
|
|
70
|
+
typeof value === 'string' &&
|
|
71
|
+
value.trim());
|
|
68
72
|
const activeProvider = getStoredActiveProviderPreference();
|
|
69
|
-
return Boolean(process.env.
|
|
73
|
+
return Boolean(process.env.OLLAMA_CLOUD_BASE_URL ||
|
|
74
|
+
process.env.OLLAMA_BASE_URL ||
|
|
70
75
|
process.env.OLLAMA_API_KEY ||
|
|
76
|
+
storage?.providerApiKeys?.['ollama-cloud'] ||
|
|
77
|
+
scopedKeys ||
|
|
71
78
|
isProviderBaseUrlCustomized('ollama-cloud') ||
|
|
72
79
|
activeProvider === 'ollama-cloud' ||
|
|
73
80
|
activeProvider === 'ollama');
|
|
74
81
|
}
|
|
75
82
|
catch {
|
|
76
|
-
return Boolean(process.env.
|
|
83
|
+
return Boolean(process.env.OLLAMA_CLOUD_BASE_URL ||
|
|
84
|
+
process.env.OLLAMA_BASE_URL ||
|
|
85
|
+
process.env.OLLAMA_API_KEY);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
export function isGeminiApiProviderConfigured() {
|
|
89
|
+
try {
|
|
90
|
+
const storage = getSecureStorage().read();
|
|
91
|
+
const scopedKeys = Object.entries(storage?.providerProfileApiKeys ?? {}).some(([key, value]) => key.startsWith('gemini-api/') && typeof value === 'string' && value.trim());
|
|
92
|
+
return Boolean(process.env.GEMINI_API_KEY ||
|
|
93
|
+
process.env.GOOGLE_API_KEY ||
|
|
94
|
+
storage?.providerApiKeys?.['gemini-api'] ||
|
|
95
|
+
scopedKeys);
|
|
96
|
+
}
|
|
97
|
+
catch {
|
|
98
|
+
return Boolean(process.env.GEMINI_API_KEY || process.env.GOOGLE_API_KEY);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
export function isGeminiGoogleProviderConfigured() {
|
|
102
|
+
try {
|
|
103
|
+
const activeProvider = getStoredActiveProviderPreference();
|
|
104
|
+
return Boolean(process.env.GEMINI_OAUTH_TOKEN ||
|
|
105
|
+
process.env.GOOGLE_OAUTH_ACCESS_TOKEN ||
|
|
106
|
+
process.env.GOOGLE_APPLICATION_CREDENTIALS ||
|
|
107
|
+
process.env.GEMINI_GOOGLE_PROJECT_ID ||
|
|
108
|
+
process.env.GOOGLE_CLOUD_PROJECT ||
|
|
109
|
+
process.env.GCLOUD_PROJECT ||
|
|
110
|
+
Object.entries(storage?.providerProfileOauth ?? {}).some(([key, value]) => key.startsWith('gemini-google/') &&
|
|
111
|
+
typeof value === 'object' &&
|
|
112
|
+
value !== null &&
|
|
113
|
+
typeof value.accessToken === 'string' &&
|
|
114
|
+
value.accessToken.trim()) ||
|
|
115
|
+
activeProvider === 'gemini-google');
|
|
116
|
+
}
|
|
117
|
+
catch {
|
|
118
|
+
return Boolean(process.env.GEMINI_OAUTH_TOKEN ||
|
|
119
|
+
process.env.GOOGLE_OAUTH_ACCESS_TOKEN ||
|
|
120
|
+
process.env.GOOGLE_APPLICATION_CREDENTIALS ||
|
|
121
|
+
process.env.GEMINI_GOOGLE_PROJECT_ID ||
|
|
122
|
+
process.env.GOOGLE_CLOUD_PROJECT ||
|
|
123
|
+
process.env.GCLOUD_PROJECT);
|
|
77
124
|
}
|
|
78
125
|
}
|
|
79
126
|
export function isZAIProviderConfigured() {
|
|
@@ -105,6 +152,8 @@ export function isOpenAICompatibleProvider(provider) {
|
|
|
105
152
|
provider === 'openrouter' ||
|
|
106
153
|
provider === 'ollama' ||
|
|
107
154
|
provider === 'ollama-cloud' ||
|
|
155
|
+
provider === 'gemini-api' ||
|
|
156
|
+
provider === 'gemini-google' ||
|
|
108
157
|
provider === 'zai');
|
|
109
158
|
}
|
|
110
159
|
export function hasDualProviderSessions() {
|
|
@@ -112,6 +161,8 @@ export function hasDualProviderSessions() {
|
|
|
112
161
|
isOpenRouterProviderConfigured() ||
|
|
113
162
|
isOllamaProviderConfigured() ||
|
|
114
163
|
isOllamaCloudProviderConfigured() ||
|
|
164
|
+
isGeminiApiProviderConfigured() ||
|
|
165
|
+
isGeminiGoogleProviderConfigured() ||
|
|
115
166
|
isZAIProviderConfigured() ||
|
|
116
167
|
isMiniMaxProviderConfigured()) &&
|
|
117
168
|
hasStoredClaudeAIOAuthToken());
|
|
@@ -138,6 +189,10 @@ export function getAPIProvider() {
|
|
|
138
189
|
return 'ollama';
|
|
139
190
|
if (preference === 'ollama-cloud')
|
|
140
191
|
return 'ollama-cloud';
|
|
192
|
+
if (preference === 'gemini-api')
|
|
193
|
+
return 'gemini-api';
|
|
194
|
+
if (preference === 'gemini-google')
|
|
195
|
+
return 'gemini-google';
|
|
141
196
|
if (preference === 'zai')
|
|
142
197
|
return 'zai';
|
|
143
198
|
if (preference === 'minimax')
|
|
@@ -150,6 +205,8 @@ export function getAPIProvider() {
|
|
|
150
205
|
const openRouterConfigured = isOpenRouterProviderConfigured();
|
|
151
206
|
const ollamaConfigured = isOllamaProviderConfigured();
|
|
152
207
|
const ollamaCloudConfigured = isOllamaCloudProviderConfigured();
|
|
208
|
+
const geminiApiConfigured = isGeminiApiProviderConfigured();
|
|
209
|
+
const geminiGoogleConfigured = isGeminiGoogleProviderConfigured();
|
|
153
210
|
const zaiConfigured = isZAIProviderConfigured();
|
|
154
211
|
const minimaxConfigured = isMiniMaxProviderConfigured();
|
|
155
212
|
if (openAIConfigured) {
|
|
@@ -164,6 +221,12 @@ export function getAPIProvider() {
|
|
|
164
221
|
if (minimaxConfigured) {
|
|
165
222
|
return 'minimax';
|
|
166
223
|
}
|
|
224
|
+
if (geminiApiConfigured) {
|
|
225
|
+
return 'gemini-api';
|
|
226
|
+
}
|
|
227
|
+
if (geminiGoogleConfigured) {
|
|
228
|
+
return 'gemini-google';
|
|
229
|
+
}
|
|
167
230
|
if (ollamaCloudConfigured) {
|
|
168
231
|
return 'ollama-cloud';
|
|
169
232
|
}
|
|
@@ -4,8 +4,10 @@ const DEFAULT_WORKSPACE_DISPLAY_NAMES = {
|
|
|
4
4
|
claude: 'Claude',
|
|
5
5
|
openai: 'OpenAI',
|
|
6
6
|
openrouter: 'OpenRouter',
|
|
7
|
-
ollama: 'Ollama
|
|
7
|
+
ollama: 'Ollama',
|
|
8
8
|
'ollama-cloud': 'Ollama Cloud',
|
|
9
|
+
'gemini-api': 'Gemini API',
|
|
10
|
+
'gemini-google': 'Gemini Google',
|
|
9
11
|
zai: 'Z.AI',
|
|
10
12
|
minimax: 'MiniMax',
|
|
11
13
|
};
|
|
@@ -27,7 +27,7 @@ function rowToTask(row) {
|
|
|
27
27
|
runId: typed.run_id,
|
|
28
28
|
parentTaskId: typed.parent_task_id ?? null,
|
|
29
29
|
scopeType: typed.scope_type,
|
|
30
|
-
|
|
30
|
+
teamUnitId: typed.team_unit_id ?? null,
|
|
31
31
|
assignedAgentId: typed.assigned_agent_id ?? null,
|
|
32
32
|
title: typed.title,
|
|
33
33
|
instructions: typed.instructions,
|
|
@@ -71,7 +71,7 @@ function rowToTaskResult(row) {
|
|
|
71
71
|
createdAt: typed.created_at,
|
|
72
72
|
};
|
|
73
73
|
}
|
|
74
|
-
function
|
|
74
|
+
function rowToTeamReport(row) {
|
|
75
75
|
if (!row) {
|
|
76
76
|
return null;
|
|
77
77
|
}
|
|
@@ -79,7 +79,7 @@ function rowToDomainReport(row) {
|
|
|
79
79
|
return {
|
|
80
80
|
id: typed.id,
|
|
81
81
|
runId: typed.run_id,
|
|
82
|
-
|
|
82
|
+
teamUnitId: typed.team_unit_id,
|
|
83
83
|
localOrchestratorAgentId: typed.local_orchestrator_agent_id ?? null,
|
|
84
84
|
status: typed.status,
|
|
85
85
|
summary: typed.summary,
|
|
@@ -196,7 +196,7 @@ export async function updateOrchestrationRun(id, input) {
|
|
|
196
196
|
export async function listOrchestrationTasks(runId) {
|
|
197
197
|
const db = await getOrchestrationDatabase();
|
|
198
198
|
return db
|
|
199
|
-
.prepare(`SELECT id, run_id, parent_task_id, scope_type,
|
|
199
|
+
.prepare(`SELECT id, run_id, parent_task_id, scope_type, team_unit_id, assigned_agent_id, title, instructions, status, result_summary, created_at, finished_at
|
|
200
200
|
FROM orchestration_tasks
|
|
201
201
|
WHERE run_id = ?
|
|
202
202
|
ORDER BY created_at, id`)
|
|
@@ -207,27 +207,27 @@ export async function listOrchestrationTasks(runId) {
|
|
|
207
207
|
export async function getOrchestrationTaskById(id) {
|
|
208
208
|
const db = await getOrchestrationDatabase();
|
|
209
209
|
const row = db
|
|
210
|
-
.prepare(`SELECT id, run_id, parent_task_id, scope_type,
|
|
210
|
+
.prepare(`SELECT id, run_id, parent_task_id, scope_type, team_unit_id, assigned_agent_id, title, instructions, status, result_summary, created_at, finished_at
|
|
211
211
|
FROM orchestration_tasks
|
|
212
212
|
WHERE id = ?`)
|
|
213
213
|
.get(requireText(id, 'id'));
|
|
214
214
|
return rowToTask(row);
|
|
215
215
|
}
|
|
216
|
-
export async function
|
|
216
|
+
export async function listOrchestrationTasksByTeamUnit(runId, teamUnitId) {
|
|
217
217
|
const db = await getOrchestrationDatabase();
|
|
218
218
|
return db
|
|
219
|
-
.prepare(`SELECT id, run_id, parent_task_id, scope_type,
|
|
219
|
+
.prepare(`SELECT id, run_id, parent_task_id, scope_type, team_unit_id, assigned_agent_id, title, instructions, status, result_summary, created_at, finished_at
|
|
220
220
|
FROM orchestration_tasks
|
|
221
|
-
WHERE run_id = ? AND
|
|
221
|
+
WHERE run_id = ? AND team_unit_id = ?
|
|
222
222
|
ORDER BY created_at, id`)
|
|
223
|
-
.all(requireText(runId, 'runId'), requireText(
|
|
223
|
+
.all(requireText(runId, 'runId'), requireText(teamUnitId, 'teamUnitId'))
|
|
224
224
|
.map(rowToTask)
|
|
225
225
|
.filter((task) => task !== null);
|
|
226
226
|
}
|
|
227
227
|
export async function listOrchestrationTasksByAgent(runId, agentId) {
|
|
228
228
|
const db = await getOrchestrationDatabase();
|
|
229
229
|
return db
|
|
230
|
-
.prepare(`SELECT id, run_id, parent_task_id, scope_type,
|
|
230
|
+
.prepare(`SELECT id, run_id, parent_task_id, scope_type, team_unit_id, assigned_agent_id, title, instructions, status, result_summary, created_at, finished_at
|
|
231
231
|
FROM orchestration_tasks
|
|
232
232
|
WHERE run_id = ? AND assigned_agent_id = ?
|
|
233
233
|
ORDER BY created_at, id`)
|
|
@@ -257,15 +257,15 @@ export async function listOrchestrationMessagesByTask(taskId) {
|
|
|
257
257
|
.map(rowToMessage)
|
|
258
258
|
.filter((message) => message !== null);
|
|
259
259
|
}
|
|
260
|
-
export async function
|
|
260
|
+
export async function listOrchestrationMessagesByTeamUnit(runId, teamUnitId) {
|
|
261
261
|
const db = await getOrchestrationDatabase();
|
|
262
262
|
return db
|
|
263
263
|
.prepare(`SELECT messages.id, messages.run_id, messages.task_id, messages.from_agent_id, messages.to_agent_id, messages.message_type, messages.content, messages.created_at
|
|
264
264
|
FROM orchestration_messages AS messages
|
|
265
265
|
INNER JOIN orchestration_tasks AS tasks ON tasks.id = messages.task_id
|
|
266
|
-
WHERE messages.run_id = ? AND tasks.
|
|
266
|
+
WHERE messages.run_id = ? AND tasks.team_unit_id = ?
|
|
267
267
|
ORDER BY messages.created_at, messages.id`)
|
|
268
|
-
.all(requireText(runId, 'runId'), requireText(
|
|
268
|
+
.all(requireText(runId, 'runId'), requireText(teamUnitId, 'teamUnitId'))
|
|
269
269
|
.map(rowToMessage)
|
|
270
270
|
.filter((message) => message !== null);
|
|
271
271
|
}
|
|
@@ -274,8 +274,8 @@ export async function createOrchestrationTask(input) {
|
|
|
274
274
|
const id = randomUUID();
|
|
275
275
|
const createdAt = nowIso();
|
|
276
276
|
db.prepare(`INSERT INTO orchestration_tasks (
|
|
277
|
-
id, run_id, parent_task_id, scope_type,
|
|
278
|
-
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`).run(id, requireText(input.runId, 'runId'), toNullableText(input.parentTaskId), requireText(input.scopeType, 'scopeType'), toNullableText(input.
|
|
277
|
+
id, run_id, parent_task_id, scope_type, team_unit_id, assigned_agent_id, title, instructions, status, result_summary, created_at, finished_at
|
|
278
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`).run(id, requireText(input.runId, 'runId'), toNullableText(input.parentTaskId), requireText(input.scopeType, 'scopeType'), toNullableText(input.teamUnitId), toNullableText(input.assignedAgentId), requireText(input.title, 'title'), requireText(input.instructions, 'instructions'), input.status ?? 'pending', toNullableText(input.resultSummary), createdAt, toNullableText(input.finishedAt));
|
|
279
279
|
const created = (await listOrchestrationTasks(input.runId)).find(task => task.id === id);
|
|
280
280
|
if (!created) {
|
|
281
281
|
throw new Error('Failed to create orchestration task.');
|
|
@@ -285,7 +285,7 @@ export async function createOrchestrationTask(input) {
|
|
|
285
285
|
export async function updateOrchestrationTask(id, input) {
|
|
286
286
|
const db = await getOrchestrationDatabase();
|
|
287
287
|
const row = db
|
|
288
|
-
.prepare(`SELECT id, run_id, parent_task_id, scope_type,
|
|
288
|
+
.prepare(`SELECT id, run_id, parent_task_id, scope_type, team_unit_id, assigned_agent_id, title, instructions, status, result_summary, created_at, finished_at
|
|
289
289
|
FROM orchestration_tasks
|
|
290
290
|
WHERE id = ?`)
|
|
291
291
|
.get(id);
|
|
@@ -294,8 +294,8 @@ export async function updateOrchestrationTask(id, input) {
|
|
|
294
294
|
throw new Error(`Orchestration task not found: ${id}`);
|
|
295
295
|
}
|
|
296
296
|
db.prepare(`UPDATE orchestration_tasks
|
|
297
|
-
SET parent_task_id = ?, scope_type = ?,
|
|
298
|
-
WHERE id = ?`).run(input.parentTaskId === undefined ? existing.parentTaskId : toNullableText(input.parentTaskId), input.scopeType === undefined ? existing.scopeType : requireText(input.scopeType, 'scopeType'), input.
|
|
297
|
+
SET parent_task_id = ?, scope_type = ?, team_unit_id = ?, assigned_agent_id = ?, title = ?, instructions = ?, status = ?, result_summary = ?, finished_at = ?
|
|
298
|
+
WHERE id = ?`).run(input.parentTaskId === undefined ? existing.parentTaskId : toNullableText(input.parentTaskId), input.scopeType === undefined ? existing.scopeType : requireText(input.scopeType, 'scopeType'), input.teamUnitId === undefined ? existing.teamUnitId : toNullableText(input.teamUnitId), input.assignedAgentId === undefined ? existing.assignedAgentId : toNullableText(input.assignedAgentId), input.title === undefined ? existing.title : requireText(input.title, 'title'), input.instructions === undefined ? existing.instructions : requireText(input.instructions, 'instructions'), input.status ?? existing.status, input.resultSummary === undefined ? existing.resultSummary : toNullableText(input.resultSummary), input.finishedAt === undefined ? existing.finishedAt : toNullableText(input.finishedAt), id);
|
|
299
299
|
const updated = (await listOrchestrationTasks(existing.runId)).find(task => task.id === id);
|
|
300
300
|
if (!updated) {
|
|
301
301
|
throw new Error(`Failed to reload orchestration task: ${id}`);
|
|
@@ -360,58 +360,58 @@ export async function listOrchestrationTaskResultsByRun(runId) {
|
|
|
360
360
|
.map(rowToTaskResult)
|
|
361
361
|
.filter((result) => result !== null);
|
|
362
362
|
}
|
|
363
|
-
export async function
|
|
363
|
+
export async function listOrchestrationTaskResultsByTeamUnit(runId, teamUnitId) {
|
|
364
364
|
const db = await getOrchestrationDatabase();
|
|
365
365
|
return db
|
|
366
366
|
.prepare(`SELECT results.id, results.run_id, results.task_id, results.agent_id, results.result_type, results.status, results.summary, results.content, results.metadata_json, results.created_at
|
|
367
367
|
FROM orchestration_task_results AS results
|
|
368
368
|
INNER JOIN orchestration_tasks AS tasks ON tasks.id = results.task_id
|
|
369
|
-
WHERE results.run_id = ? AND tasks.
|
|
369
|
+
WHERE results.run_id = ? AND tasks.team_unit_id = ?
|
|
370
370
|
ORDER BY results.created_at, results.id`)
|
|
371
|
-
.all(requireText(runId, 'runId'), requireText(
|
|
371
|
+
.all(requireText(runId, 'runId'), requireText(teamUnitId, 'teamUnitId'))
|
|
372
372
|
.map(rowToTaskResult)
|
|
373
373
|
.filter((result) => result !== null);
|
|
374
374
|
}
|
|
375
|
-
export async function
|
|
375
|
+
export async function upsertOrchestrationTeamReport(input) {
|
|
376
376
|
const db = await getOrchestrationDatabase();
|
|
377
377
|
const now = nowIso();
|
|
378
|
-
const existing = await
|
|
378
|
+
const existing = await getOrchestrationTeamReport(input.runId, input.teamUnitId);
|
|
379
379
|
if (existing) {
|
|
380
|
-
db.prepare(`UPDATE
|
|
380
|
+
db.prepare(`UPDATE orchestration_team_reports
|
|
381
381
|
SET local_orchestrator_agent_id = ?, status = ?, summary = ?, blockers = ?, output = ?, metrics_json = ?, updated_at = ?, submitted_at = ?
|
|
382
382
|
WHERE id = ?`).run(input.localOrchestratorAgentId === undefined
|
|
383
383
|
? existing.localOrchestratorAgentId
|
|
384
384
|
: toNullableText(input.localOrchestratorAgentId), input.status ?? existing.status, requireText(input.summary, 'summary'), input.blockers === undefined ? existing.blockers : toNullableText(input.blockers), input.output === undefined ? existing.output : toNullableText(input.output), input.metricsJson === undefined ? existing.metricsJson : toNullableText(input.metricsJson), now, input.submittedAt === undefined ? existing.submittedAt : toNullableText(input.submittedAt), existing.id);
|
|
385
385
|
}
|
|
386
386
|
else {
|
|
387
|
-
db.prepare(`INSERT INTO
|
|
388
|
-
id, run_id,
|
|
389
|
-
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`).run(randomUUID(), requireText(input.runId, 'runId'), requireText(input.
|
|
387
|
+
db.prepare(`INSERT INTO orchestration_team_reports (
|
|
388
|
+
id, run_id, team_unit_id, local_orchestrator_agent_id, status, summary, blockers, output, metrics_json, created_at, updated_at, submitted_at
|
|
389
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`).run(randomUUID(), requireText(input.runId, 'runId'), requireText(input.teamUnitId, 'teamUnitId'), toNullableText(input.localOrchestratorAgentId), input.status ?? 'submitted', requireText(input.summary, 'summary'), toNullableText(input.blockers), toNullableText(input.output), toNullableText(input.metricsJson), now, now, toNullableText(input.submittedAt));
|
|
390
390
|
}
|
|
391
|
-
const saved = await
|
|
391
|
+
const saved = await getOrchestrationTeamReport(input.runId, input.teamUnitId);
|
|
392
392
|
if (!saved) {
|
|
393
|
-
throw new Error('Failed to save orchestration
|
|
393
|
+
throw new Error('Failed to save orchestration team report.');
|
|
394
394
|
}
|
|
395
395
|
return saved;
|
|
396
396
|
}
|
|
397
|
-
export async function
|
|
397
|
+
export async function getOrchestrationTeamReport(runId, teamUnitId) {
|
|
398
398
|
const db = await getOrchestrationDatabase();
|
|
399
399
|
const row = db
|
|
400
|
-
.prepare(`SELECT id, run_id,
|
|
401
|
-
FROM
|
|
402
|
-
WHERE run_id = ? AND
|
|
403
|
-
.get(requireText(runId, 'runId'), requireText(
|
|
404
|
-
return
|
|
400
|
+
.prepare(`SELECT id, run_id, team_unit_id, local_orchestrator_agent_id, status, summary, blockers, output, metrics_json, created_at, updated_at, submitted_at
|
|
401
|
+
FROM orchestration_team_reports
|
|
402
|
+
WHERE run_id = ? AND team_unit_id = ?`)
|
|
403
|
+
.get(requireText(runId, 'runId'), requireText(teamUnitId, 'teamUnitId'));
|
|
404
|
+
return rowToTeamReport(row);
|
|
405
405
|
}
|
|
406
|
-
export async function
|
|
406
|
+
export async function listOrchestrationTeamReports(runId) {
|
|
407
407
|
const db = await getOrchestrationDatabase();
|
|
408
408
|
return db
|
|
409
|
-
.prepare(`SELECT id, run_id,
|
|
410
|
-
FROM
|
|
409
|
+
.prepare(`SELECT id, run_id, team_unit_id, local_orchestrator_agent_id, status, summary, blockers, output, metrics_json, created_at, updated_at, submitted_at
|
|
410
|
+
FROM orchestration_team_reports
|
|
411
411
|
WHERE run_id = ?
|
|
412
412
|
ORDER BY updated_at, id`)
|
|
413
413
|
.all(requireText(runId, 'runId'))
|
|
414
|
-
.map(
|
|
414
|
+
.map(rowToTeamReport)
|
|
415
415
|
.filter((report) => report !== null);
|
|
416
416
|
}
|
|
417
417
|
export async function upsertOrchestrationRunReport(input) {
|
|
@@ -443,13 +443,13 @@ export async function getOrchestrationRunReport(runId) {
|
|
|
443
443
|
.get(requireText(runId, 'runId'));
|
|
444
444
|
return rowToRunReport(row);
|
|
445
445
|
}
|
|
446
|
-
export async function
|
|
447
|
-
const tasks = await
|
|
448
|
-
const resultCount = (await
|
|
449
|
-
const report = await
|
|
446
|
+
export async function getOrchestrationTeamSummary(runId, teamUnitId) {
|
|
447
|
+
const tasks = await listOrchestrationTasksByTeamUnit(runId, teamUnitId);
|
|
448
|
+
const resultCount = (await listOrchestrationTaskResultsByTeamUnit(runId, teamUnitId)).length;
|
|
449
|
+
const report = await getOrchestrationTeamReport(runId, teamUnitId);
|
|
450
450
|
return {
|
|
451
451
|
runId: requireText(runId, 'runId'),
|
|
452
|
-
|
|
452
|
+
teamUnitId: requireText(teamUnitId, 'teamUnitId'),
|
|
453
453
|
...countTasks(tasks),
|
|
454
454
|
resultCount,
|
|
455
455
|
reportStatus: report?.status ?? null,
|
|
@@ -463,14 +463,14 @@ export async function getOrchestrationRunSummary(runId) {
|
|
|
463
463
|
}
|
|
464
464
|
const tasks = await listOrchestrationTasks(run.id);
|
|
465
465
|
const results = await listOrchestrationTaskResultsByRun(run.id);
|
|
466
|
-
const
|
|
466
|
+
const teamReports = await listOrchestrationTeamReports(run.id);
|
|
467
467
|
const runReport = await getOrchestrationRunReport(run.id);
|
|
468
468
|
return {
|
|
469
469
|
run,
|
|
470
470
|
...countTasks(tasks),
|
|
471
471
|
resultCount: results.length,
|
|
472
|
-
|
|
473
|
-
|
|
472
|
+
teamReportCount: teamReports.length,
|
|
473
|
+
completedTeamReportCount: teamReports.filter(report => report.status === 'submitted' || report.status === 'accepted').length,
|
|
474
474
|
runReport,
|
|
475
475
|
};
|
|
476
476
|
}
|
|
@@ -15,7 +15,7 @@ function rowToTeam(row) {
|
|
|
15
15
|
updatedAt: typed.updated_at,
|
|
16
16
|
};
|
|
17
17
|
}
|
|
18
|
-
function
|
|
18
|
+
function rowToTeamUnit(row) {
|
|
19
19
|
if (!row) {
|
|
20
20
|
return null;
|
|
21
21
|
}
|
|
@@ -23,7 +23,7 @@ function rowToTeamDomain(row) {
|
|
|
23
23
|
return {
|
|
24
24
|
id: typed.id,
|
|
25
25
|
teamId: typed.team_id,
|
|
26
|
-
|
|
26
|
+
unitName: typed.unit_name,
|
|
27
27
|
workspaceId: typed.workspace_id ?? null,
|
|
28
28
|
localOrchestratorAgentId: typed.local_orchestrator_agent_id ?? null,
|
|
29
29
|
leadAgentId: typed.lead_agent_id ?? null,
|
|
@@ -33,14 +33,14 @@ function rowToTeamDomain(row) {
|
|
|
33
33
|
updatedAt: typed.updated_at,
|
|
34
34
|
};
|
|
35
35
|
}
|
|
36
|
-
function
|
|
36
|
+
function rowToTeamUnitMember(row) {
|
|
37
37
|
if (!row) {
|
|
38
38
|
return null;
|
|
39
39
|
}
|
|
40
40
|
const typed = row;
|
|
41
41
|
return {
|
|
42
42
|
id: typed.id,
|
|
43
|
-
|
|
43
|
+
teamUnitId: typed.team_unit_id,
|
|
44
44
|
agentId: typed.agent_id,
|
|
45
45
|
duty: typed.duty ?? null,
|
|
46
46
|
priority: typed.priority,
|
|
@@ -76,23 +76,23 @@ async function getTeamRowById(id) {
|
|
|
76
76
|
.get(id);
|
|
77
77
|
return rowToTeam(row);
|
|
78
78
|
}
|
|
79
|
-
async function
|
|
79
|
+
async function getTeamUnitRowById(id) {
|
|
80
80
|
const db = await getOrchestrationDatabase();
|
|
81
81
|
const row = db
|
|
82
|
-
.prepare(`SELECT id, team_id,
|
|
83
|
-
FROM
|
|
82
|
+
.prepare(`SELECT id, team_id, unit_name, workspace_id, local_orchestrator_agent_id, lead_agent_id, selection_mode, required, created_at, updated_at
|
|
83
|
+
FROM team_units
|
|
84
84
|
WHERE id = ?`)
|
|
85
85
|
.get(id);
|
|
86
|
-
return
|
|
86
|
+
return rowToTeamUnit(row);
|
|
87
87
|
}
|
|
88
|
-
async function
|
|
88
|
+
async function getTeamUnitMemberRowById(id) {
|
|
89
89
|
const db = await getOrchestrationDatabase();
|
|
90
90
|
const row = db
|
|
91
|
-
.prepare(`SELECT id,
|
|
92
|
-
FROM
|
|
91
|
+
.prepare(`SELECT id, team_unit_id, agent_id, duty, priority, created_at, updated_at
|
|
92
|
+
FROM team_unit_members
|
|
93
93
|
WHERE id = ?`)
|
|
94
94
|
.get(id);
|
|
95
|
-
return
|
|
95
|
+
return rowToTeamUnitMember(row);
|
|
96
96
|
}
|
|
97
97
|
export async function listTeams() {
|
|
98
98
|
const db = await getOrchestrationDatabase();
|
|
@@ -163,40 +163,40 @@ export async function deleteTeam(id) {
|
|
|
163
163
|
});
|
|
164
164
|
return true;
|
|
165
165
|
}
|
|
166
|
-
export async function
|
|
166
|
+
export async function listTeamUnits(teamId) {
|
|
167
167
|
const db = await getOrchestrationDatabase();
|
|
168
168
|
return db
|
|
169
|
-
.prepare(`SELECT id, team_id,
|
|
170
|
-
FROM
|
|
169
|
+
.prepare(`SELECT id, team_id, unit_name, workspace_id, local_orchestrator_agent_id, lead_agent_id, selection_mode, required, created_at, updated_at
|
|
170
|
+
FROM team_units
|
|
171
171
|
WHERE team_id = ?
|
|
172
|
-
ORDER BY
|
|
172
|
+
ORDER BY unit_name, created_at, id`)
|
|
173
173
|
.all(requireText(teamId, 'teamId'))
|
|
174
|
-
.map(
|
|
175
|
-
.filter((
|
|
174
|
+
.map(rowToTeamUnit)
|
|
175
|
+
.filter((unit) => unit !== null);
|
|
176
176
|
}
|
|
177
|
-
export async function
|
|
178
|
-
return
|
|
177
|
+
export async function getTeamUnitById(id) {
|
|
178
|
+
return getTeamUnitRowById(id);
|
|
179
179
|
}
|
|
180
|
-
export async function
|
|
180
|
+
export async function createTeamUnit(input) {
|
|
181
181
|
const db = await getOrchestrationDatabase();
|
|
182
182
|
const id = randomUUID();
|
|
183
183
|
const now = nowIso();
|
|
184
|
-
db.prepare(`INSERT INTO
|
|
185
|
-
id, team_id,
|
|
186
|
-
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`).run(id, requireText(input.teamId, 'teamId'), requireText(input.
|
|
187
|
-
const created = await
|
|
184
|
+
db.prepare(`INSERT INTO team_units (
|
|
185
|
+
id, team_id, unit_name, workspace_id, local_orchestrator_agent_id, lead_agent_id, selection_mode, required, created_at, updated_at
|
|
186
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`).run(id, requireText(input.teamId, 'teamId'), requireText(input.unitName, 'unitName'), toNullableText(input.workspaceId), toNullableText(input.localOrchestratorAgentId), toNullableText(input.leadAgentId), resolveSelectionMode(input.selectionMode), toDbBoolean(resolveBoolean(input.required, false)), now, now);
|
|
187
|
+
const created = await getTeamUnitById(id);
|
|
188
188
|
if (!created) {
|
|
189
|
-
throw new Error('Failed to create team
|
|
189
|
+
throw new Error('Failed to create team unit.');
|
|
190
190
|
}
|
|
191
191
|
return created;
|
|
192
192
|
}
|
|
193
|
-
export async function
|
|
194
|
-
const existing = await
|
|
193
|
+
export async function updateTeamUnit(id, input) {
|
|
194
|
+
const existing = await getTeamUnitRowById(id);
|
|
195
195
|
if (!existing) {
|
|
196
|
-
throw new Error(`Team
|
|
196
|
+
throw new Error(`Team unit not found: ${id}`);
|
|
197
197
|
}
|
|
198
198
|
const db = await getOrchestrationDatabase();
|
|
199
|
-
const
|
|
199
|
+
const unitName = resolveRequiredText(input.unitName, existing.unitName, 'unitName');
|
|
200
200
|
const workspaceId = input.workspaceId === undefined
|
|
201
201
|
? existing.workspaceId
|
|
202
202
|
: toNullableText(input.workspaceId);
|
|
@@ -210,76 +210,76 @@ export async function updateTeamDomain(id, input) {
|
|
|
210
210
|
? existing.selectionMode
|
|
211
211
|
: resolveSelectionMode(input.selectionMode, existing.selectionMode);
|
|
212
212
|
const required = resolveBoolean(input.required, existing.required);
|
|
213
|
-
db.prepare(`UPDATE
|
|
214
|
-
SET
|
|
215
|
-
WHERE id = ?`).run(
|
|
216
|
-
const updated = await
|
|
213
|
+
db.prepare(`UPDATE team_units
|
|
214
|
+
SET unit_name = ?, workspace_id = ?, local_orchestrator_agent_id = ?, lead_agent_id = ?, selection_mode = ?, required = ?, updated_at = ?
|
|
215
|
+
WHERE id = ?`).run(unitName, workspaceId, localOrchestratorAgentId, leadAgentId, selectionMode, toDbBoolean(required), nowIso(), id);
|
|
216
|
+
const updated = await getTeamUnitRowById(id);
|
|
217
217
|
if (!updated) {
|
|
218
|
-
throw new Error(`Failed to reload team
|
|
218
|
+
throw new Error(`Failed to reload team unit: ${id}`);
|
|
219
219
|
}
|
|
220
220
|
return updated;
|
|
221
221
|
}
|
|
222
|
-
export async function
|
|
223
|
-
const existing = await
|
|
222
|
+
export async function deleteTeamUnit(id) {
|
|
223
|
+
const existing = await getTeamUnitRowById(id);
|
|
224
224
|
if (!existing) {
|
|
225
225
|
return false;
|
|
226
226
|
}
|
|
227
227
|
await withOrchestrationTransaction(async (db) => {
|
|
228
|
-
db.prepare(`DELETE FROM
|
|
228
|
+
db.prepare(`DELETE FROM team_units WHERE id = ?`).run(id);
|
|
229
229
|
});
|
|
230
230
|
return true;
|
|
231
231
|
}
|
|
232
|
-
export async function
|
|
232
|
+
export async function listTeamUnitMembers(teamUnitId) {
|
|
233
233
|
const db = await getOrchestrationDatabase();
|
|
234
234
|
return db
|
|
235
|
-
.prepare(`SELECT id,
|
|
236
|
-
FROM
|
|
237
|
-
WHERE
|
|
235
|
+
.prepare(`SELECT id, team_unit_id, agent_id, duty, priority, created_at, updated_at
|
|
236
|
+
FROM team_unit_members
|
|
237
|
+
WHERE team_unit_id = ?
|
|
238
238
|
ORDER BY priority DESC, created_at, id`)
|
|
239
|
-
.all(requireText(
|
|
240
|
-
.map(
|
|
239
|
+
.all(requireText(teamUnitId, 'teamUnitId'))
|
|
240
|
+
.map(rowToTeamUnitMember)
|
|
241
241
|
.filter((member) => member !== null);
|
|
242
242
|
}
|
|
243
|
-
export async function
|
|
244
|
-
return
|
|
243
|
+
export async function getTeamUnitMemberById(id) {
|
|
244
|
+
return getTeamUnitMemberRowById(id);
|
|
245
245
|
}
|
|
246
|
-
export async function
|
|
246
|
+
export async function createTeamUnitMember(input) {
|
|
247
247
|
const db = await getOrchestrationDatabase();
|
|
248
248
|
const id = randomUUID();
|
|
249
249
|
const now = nowIso();
|
|
250
|
-
db.prepare(`INSERT INTO
|
|
251
|
-
id,
|
|
252
|
-
) VALUES (?, ?, ?, ?, ?, ?, ?)`).run(id, requireText(input.
|
|
253
|
-
const created = await
|
|
250
|
+
db.prepare(`INSERT INTO team_unit_members (
|
|
251
|
+
id, team_unit_id, agent_id, duty, priority, created_at, updated_at
|
|
252
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?)`).run(id, requireText(input.teamUnitId, 'teamUnitId'), requireText(input.agentId, 'agentId'), toNullableText(input.duty), resolvePriority(input.priority), now, now);
|
|
253
|
+
const created = await getTeamUnitMemberById(id);
|
|
254
254
|
if (!created) {
|
|
255
|
-
throw new Error('Failed to create team
|
|
255
|
+
throw new Error('Failed to create team unit member.');
|
|
256
256
|
}
|
|
257
257
|
return created;
|
|
258
258
|
}
|
|
259
|
-
export async function
|
|
260
|
-
const existing = await
|
|
259
|
+
export async function updateTeamUnitMember(id, input) {
|
|
260
|
+
const existing = await getTeamUnitMemberRowById(id);
|
|
261
261
|
if (!existing) {
|
|
262
|
-
throw new Error(`Team
|
|
262
|
+
throw new Error(`Team unit member not found: ${id}`);
|
|
263
263
|
}
|
|
264
264
|
const db = await getOrchestrationDatabase();
|
|
265
265
|
const duty = input.duty === undefined ? existing.duty : toNullableText(input.duty);
|
|
266
266
|
const priority = resolvePriority(input.priority, existing.priority);
|
|
267
|
-
db.prepare(`UPDATE
|
|
267
|
+
db.prepare(`UPDATE team_unit_members
|
|
268
268
|
SET duty = ?, priority = ?, updated_at = ?
|
|
269
269
|
WHERE id = ?`).run(duty, priority, nowIso(), id);
|
|
270
|
-
const updated = await
|
|
270
|
+
const updated = await getTeamUnitMemberRowById(id);
|
|
271
271
|
if (!updated) {
|
|
272
|
-
throw new Error(`Failed to reload team
|
|
272
|
+
throw new Error(`Failed to reload team unit member: ${id}`);
|
|
273
273
|
}
|
|
274
274
|
return updated;
|
|
275
275
|
}
|
|
276
|
-
export async function
|
|
277
|
-
const existing = await
|
|
276
|
+
export async function deleteTeamUnitMember(id) {
|
|
277
|
+
const existing = await getTeamUnitMemberRowById(id);
|
|
278
278
|
if (!existing) {
|
|
279
279
|
return false;
|
|
280
280
|
}
|
|
281
281
|
await withOrchestrationTransaction(async (db) => {
|
|
282
|
-
db.prepare(`DELETE FROM
|
|
282
|
+
db.prepare(`DELETE FROM team_unit_members WHERE id = ?`).run(id);
|
|
283
283
|
});
|
|
284
284
|
return true;
|
|
285
285
|
}
|