funolio-agent 0.17.8 → 1.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (223) hide show
  1. package/dist/approval.d.ts +7 -6
  2. package/dist/approval.d.ts.map +1 -1
  3. package/dist/approval.js +40 -10
  4. package/dist/approval.js.map +1 -1
  5. package/dist/auth/anthropic-subscription.d.ts +9 -29
  6. package/dist/auth/anthropic-subscription.d.ts.map +1 -1
  7. package/dist/auth/anthropic-subscription.js +12 -133
  8. package/dist/auth/anthropic-subscription.js.map +1 -1
  9. package/dist/auth/auto-detect.d.ts +28 -6
  10. package/dist/auth/auto-detect.d.ts.map +1 -1
  11. package/dist/auth/auto-detect.js +52 -205
  12. package/dist/auth/auto-detect.js.map +1 -1
  13. package/dist/auth/credential-reader.d.ts +24 -4
  14. package/dist/auth/credential-reader.d.ts.map +1 -1
  15. package/dist/auth/credential-reader.js +31 -256
  16. package/dist/auth/credential-reader.js.map +1 -1
  17. package/dist/auth/credential-status.d.ts +7 -27
  18. package/dist/auth/credential-status.d.ts.map +1 -1
  19. package/dist/auth/credential-status.js +7 -95
  20. package/dist/auth/credential-status.js.map +1 -1
  21. package/dist/auth/index.d.ts +9 -2
  22. package/dist/auth/index.d.ts.map +1 -1
  23. package/dist/auth/index.js +10 -10
  24. package/dist/auth/index.js.map +1 -1
  25. package/dist/auth/subscription-runtime.d.ts +19 -23
  26. package/dist/auth/subscription-runtime.d.ts.map +1 -1
  27. package/dist/auth/subscription-runtime.js +24 -292
  28. package/dist/auth/subscription-runtime.js.map +1 -1
  29. package/dist/auth/token-refresh.d.ts +19 -28
  30. package/dist/auth/token-refresh.d.ts.map +1 -1
  31. package/dist/auth/token-refresh.js +26 -464
  32. package/dist/auth/token-refresh.js.map +1 -1
  33. package/dist/backfill.js +2 -2
  34. package/dist/backfill.js.map +1 -1
  35. package/dist/bot-manager.d.ts +5 -6
  36. package/dist/bot-manager.d.ts.map +1 -1
  37. package/dist/bot-manager.js +20 -62
  38. package/dist/bot-manager.js.map +1 -1
  39. package/dist/clerk-model.d.ts +0 -1
  40. package/dist/clerk-model.d.ts.map +1 -1
  41. package/dist/clerk-model.js +24 -50
  42. package/dist/clerk-model.js.map +1 -1
  43. package/dist/commands/configure-provider.js +2 -2
  44. package/dist/commands/configure-provider.js.map +1 -1
  45. package/dist/commands/configure.d.ts.map +1 -1
  46. package/dist/commands/configure.js +10 -14
  47. package/dist/commands/configure.js.map +1 -1
  48. package/dist/commands/start.d.ts.map +1 -1
  49. package/dist/commands/start.js +51 -229
  50. package/dist/commands/start.js.map +1 -1
  51. package/dist/config.d.ts +1 -1
  52. package/dist/config.d.ts.map +1 -1
  53. package/dist/config.js +2 -2
  54. package/dist/config.js.map +1 -1
  55. package/dist/context-compressor.d.ts +6 -1
  56. package/dist/context-compressor.d.ts.map +1 -1
  57. package/dist/context-compressor.js +87 -18
  58. package/dist/context-compressor.js.map +1 -1
  59. package/dist/context-window.d.ts +2 -8
  60. package/dist/context-window.d.ts.map +1 -1
  61. package/dist/context-window.js +4 -4
  62. package/dist/context-window.js.map +1 -1
  63. package/dist/eval/orchestrator-front-door-replay.js +43 -2
  64. package/dist/eval/orchestrator-front-door-replay.js.map +1 -1
  65. package/dist/eval/orchestrator-todo-dispatch-replay.d.ts +2 -0
  66. package/dist/eval/orchestrator-todo-dispatch-replay.d.ts.map +1 -0
  67. package/dist/eval/orchestrator-todo-dispatch-replay.js +253 -0
  68. package/dist/eval/orchestrator-todo-dispatch-replay.js.map +1 -0
  69. package/dist/eval/orchestrator-todo-planning-replay.d.ts +2 -0
  70. package/dist/eval/orchestrator-todo-planning-replay.d.ts.map +1 -0
  71. package/dist/eval/orchestrator-todo-planning-replay.js +247 -0
  72. package/dist/eval/orchestrator-todo-planning-replay.js.map +1 -0
  73. package/dist/eval/policy-detection-replay.d.ts +2 -0
  74. package/dist/eval/policy-detection-replay.d.ts.map +1 -0
  75. package/dist/eval/policy-detection-replay.js +122 -0
  76. package/dist/eval/policy-detection-replay.js.map +1 -0
  77. package/dist/eval/todo-worker-runtime-replay.d.ts +2 -0
  78. package/dist/eval/todo-worker-runtime-replay.d.ts.map +1 -0
  79. package/dist/eval/todo-worker-runtime-replay.js +520 -0
  80. package/dist/eval/todo-worker-runtime-replay.js.map +1 -0
  81. package/dist/integration-tokens.d.ts +6 -0
  82. package/dist/integration-tokens.d.ts.map +1 -1
  83. package/dist/integration-tokens.js +43 -0
  84. package/dist/integration-tokens.js.map +1 -1
  85. package/dist/local-data.d.ts +134 -1
  86. package/dist/local-data.d.ts.map +1 -1
  87. package/dist/local-data.js +711 -18
  88. package/dist/local-data.js.map +1 -1
  89. package/dist/local-db.d.ts.map +1 -1
  90. package/dist/local-db.js +216 -12
  91. package/dist/local-db.js.map +1 -1
  92. package/dist/local-funnel.d.ts.map +1 -1
  93. package/dist/local-funnel.js +7 -0
  94. package/dist/local-funnel.js.map +1 -1
  95. package/dist/local-server.d.ts.map +1 -1
  96. package/dist/local-server.js +119 -96
  97. package/dist/local-server.js.map +1 -1
  98. package/dist/mcp/bridge-server.d.ts.map +1 -1
  99. package/dist/mcp/bridge-server.js +8 -2
  100. package/dist/mcp/bridge-server.js.map +1 -1
  101. package/dist/mcp/manager.d.ts +5 -0
  102. package/dist/mcp/manager.d.ts.map +1 -1
  103. package/dist/mcp/manager.js +131 -2
  104. package/dist/mcp/manager.js.map +1 -1
  105. package/dist/mcp/sync-cli-config.d.ts +5 -0
  106. package/dist/mcp/sync-cli-config.d.ts.map +1 -1
  107. package/dist/mcp/sync-cli-config.js +10 -2
  108. package/dist/mcp/sync-cli-config.js.map +1 -1
  109. package/dist/message-loop.d.ts +1 -10
  110. package/dist/message-loop.d.ts.map +1 -1
  111. package/dist/message-loop.js +179 -250
  112. package/dist/message-loop.js.map +1 -1
  113. package/dist/mqtt-client.d.ts +44 -0
  114. package/dist/mqtt-client.d.ts.map +1 -1
  115. package/dist/mqtt-client.js +2 -2
  116. package/dist/mqtt-client.js.map +1 -1
  117. package/dist/orchestration/front-door-policy.d.ts +26 -9
  118. package/dist/orchestration/front-door-policy.d.ts.map +1 -1
  119. package/dist/orchestration/front-door-policy.js +242 -69
  120. package/dist/orchestration/front-door-policy.js.map +1 -1
  121. package/dist/orchestration/orchestrator-blocked-prompt.d.ts +18 -0
  122. package/dist/orchestration/orchestrator-blocked-prompt.d.ts.map +1 -0
  123. package/dist/orchestration/orchestrator-blocked-prompt.js +46 -0
  124. package/dist/orchestration/orchestrator-blocked-prompt.js.map +1 -0
  125. package/dist/orchestration/orchestrator-final-response-prompt.d.ts +10 -0
  126. package/dist/orchestration/orchestrator-final-response-prompt.d.ts.map +1 -0
  127. package/dist/orchestration/orchestrator-final-response-prompt.js +39 -0
  128. package/dist/orchestration/orchestrator-final-response-prompt.js.map +1 -0
  129. package/dist/orchestration/orchestrator-operating-prompt.d.ts +11 -0
  130. package/dist/orchestration/orchestrator-operating-prompt.d.ts.map +1 -1
  131. package/dist/orchestration/orchestrator-operating-prompt.js +106 -36
  132. package/dist/orchestration/orchestrator-operating-prompt.js.map +1 -1
  133. package/dist/orchestration/policy-prompt.d.ts +6 -0
  134. package/dist/orchestration/policy-prompt.d.ts.map +1 -0
  135. package/dist/orchestration/policy-prompt.js +40 -0
  136. package/dist/orchestration/policy-prompt.js.map +1 -0
  137. package/dist/orchestration/worker-operating-prompt.d.ts +16 -0
  138. package/dist/orchestration/worker-operating-prompt.d.ts.map +1 -0
  139. package/dist/orchestration/worker-operating-prompt.js +75 -0
  140. package/dist/orchestration/worker-operating-prompt.js.map +1 -0
  141. package/dist/orchestrator.d.ts +19 -0
  142. package/dist/orchestrator.d.ts.map +1 -1
  143. package/dist/orchestrator.js +614 -54
  144. package/dist/orchestrator.js.map +1 -1
  145. package/dist/policy-detection.d.ts +40 -0
  146. package/dist/policy-detection.d.ts.map +1 -0
  147. package/dist/policy-detection.js +298 -0
  148. package/dist/policy-detection.js.map +1 -0
  149. package/dist/providers/anthropic.d.ts +0 -5
  150. package/dist/providers/anthropic.d.ts.map +1 -1
  151. package/dist/providers/anthropic.js +34 -51
  152. package/dist/providers/anthropic.js.map +1 -1
  153. package/dist/providers/claude-cli.d.ts.map +1 -1
  154. package/dist/providers/claude-cli.js +11 -2
  155. package/dist/providers/claude-cli.js.map +1 -1
  156. package/dist/providers/codex-cli.d.ts.map +1 -1
  157. package/dist/providers/codex-cli.js +121 -2
  158. package/dist/providers/codex-cli.js.map +1 -1
  159. package/dist/providers/index.d.ts +6 -2
  160. package/dist/providers/index.d.ts.map +1 -1
  161. package/dist/providers/index.js.map +1 -1
  162. package/dist/summarization-pipeline.d.ts +1 -4
  163. package/dist/summarization-pipeline.d.ts.map +1 -1
  164. package/dist/summarization-pipeline.js +43 -56
  165. package/dist/summarization-pipeline.js.map +1 -1
  166. package/dist/tools/analyze-image.js +2 -2
  167. package/dist/tools/analyze-image.js.map +1 -1
  168. package/dist/tools/edit-file.d.ts.map +1 -1
  169. package/dist/tools/edit-file.js +16 -1
  170. package/dist/tools/edit-file.js.map +1 -1
  171. package/dist/tools/git-tools.d.ts.map +1 -1
  172. package/dist/tools/git-tools.js +32 -1
  173. package/dist/tools/git-tools.js.map +1 -1
  174. package/dist/tools/index.d.ts.map +1 -1
  175. package/dist/tools/index.js +2 -0
  176. package/dist/tools/index.js.map +1 -1
  177. package/dist/tools/list-directory.d.ts.map +1 -1
  178. package/dist/tools/list-directory.js +23 -0
  179. package/dist/tools/list-directory.js.map +1 -1
  180. package/dist/tools/notify-user.d.ts.map +1 -1
  181. package/dist/tools/notify-user.js +15 -1
  182. package/dist/tools/notify-user.js.map +1 -1
  183. package/dist/tools/read-file.d.ts.map +1 -1
  184. package/dist/tools/read-file.js +3 -1
  185. package/dist/tools/read-file.js.map +1 -1
  186. package/dist/tools/request-mcp-install.js +5 -5
  187. package/dist/tools/request-mcp-install.js.map +1 -1
  188. package/dist/tools/run-command.d.ts.map +1 -1
  189. package/dist/tools/run-command.js +16 -4
  190. package/dist/tools/run-command.js.map +1 -1
  191. package/dist/tools/sandbox.d.ts.map +1 -1
  192. package/dist/tools/sandbox.js +6 -0
  193. package/dist/tools/sandbox.js.map +1 -1
  194. package/dist/tools/schedule-task.d.ts.map +1 -1
  195. package/dist/tools/schedule-task.js +37 -0
  196. package/dist/tools/schedule-task.js.map +1 -1
  197. package/dist/tools/search-codebase.d.ts.map +1 -1
  198. package/dist/tools/search-codebase.js +251 -32
  199. package/dist/tools/search-codebase.js.map +1 -1
  200. package/dist/tools/todo-tasks.d.ts +2 -0
  201. package/dist/tools/todo-tasks.d.ts.map +1 -1
  202. package/dist/tools/todo-tasks.js +203 -6
  203. package/dist/tools/todo-tasks.js.map +1 -1
  204. package/dist/tools/web-fetch.d.ts.map +1 -1
  205. package/dist/tools/web-fetch.js +21 -2
  206. package/dist/tools/web-fetch.js.map +1 -1
  207. package/dist/tools/web-search.d.ts.map +1 -1
  208. package/dist/tools/web-search.js +38 -34
  209. package/dist/tools/web-search.js.map +1 -1
  210. package/dist/types.d.ts +2 -0
  211. package/dist/types.d.ts.map +1 -1
  212. package/dist/wizard-state.d.ts.map +1 -1
  213. package/dist/wizard-state.js +30 -8
  214. package/dist/wizard-state.js.map +1 -1
  215. package/dist/wizard-support.d.ts +2 -2
  216. package/dist/wizard-support.d.ts.map +1 -1
  217. package/dist/wizard-support.js +80 -93
  218. package/dist/wizard-support.js.map +1 -1
  219. package/dist/workflow-engine.d.ts +3 -0
  220. package/dist/workflow-engine.d.ts.map +1 -1
  221. package/dist/workflow-engine.js +111 -82
  222. package/dist/workflow-engine.js.map +1 -1
  223. package/package.json +6 -1
@@ -61,6 +61,7 @@ const config_cleanup_1 = require("./config-cleanup");
61
61
  const status_parser_1 = require("./orchestration/status-parser");
62
62
  const guided_actions_1 = require("./orchestration/guided-actions");
63
63
  const topic_normalizer_1 = require("./orchestration/topic-normalizer");
64
+ const policy_prompt_1 = require("./orchestration/policy-prompt");
64
65
  const safeguards_1 = require("./orchestration/safeguards");
65
66
  const token_counter_1 = require("./token-counter");
66
67
  const response_guard_1 = require("./response-guard");
@@ -72,6 +73,7 @@ const claude_config_writer_1 = require("./mcp/claude-config-writer");
72
73
  const subscription_runtime_1 = require("./auth/subscription-runtime");
73
74
  const local_memory_search_1 = require("./local-memory-search");
74
75
  const orchestrator_profile_1 = require("./orchestrator-profile");
76
+ const policy_detection_1 = require("./policy-detection");
75
77
  const server_runtime_1 = require("./server-runtime");
76
78
  const server_adapter_1 = require("./server-adapter");
77
79
  const wizard_support_1 = require("./wizard-support");
@@ -94,6 +96,10 @@ function startLocalServer(opts) {
94
96
  const express = requireExpress();
95
97
  const app = express();
96
98
  const port = opts.port ?? LOCAL_PORT;
99
+ const cliNormalization = data.normalizeCliProviderConnections();
100
+ if (cliNormalization.updatedIds.length > 0) {
101
+ console.info(`[local-server] normalized ${cliNormalization.updatedIds.length} CLI provider connection(s): ${cliNormalization.updatedIds.join(', ')}`);
102
+ }
97
103
  // Middleware
98
104
  app.use(express.json({ limit: '10mb' }));
99
105
  // CORS: allow any local origin. Server only listens on 127.0.0.1 so
@@ -108,6 +114,13 @@ function startLocalServer(opts) {
108
114
  next();
109
115
  });
110
116
  const USER_TODO_ACTOR = { actorType: 'user', actorId: 'User' };
117
+ function workerTodoActorFromBody(body) {
118
+ const actorType = body?.actorType === 'orchestrator' ? 'orchestrator' : 'llm';
119
+ const actorId = String(body?.actorId || '').trim();
120
+ if (!actorId)
121
+ throw new Error('actorId is required');
122
+ return { actorType, actorId };
123
+ }
111
124
  function sendTodoError(res, err) {
112
125
  const message = err?.message || String(err);
113
126
  if (/^Conflict:/i.test(message)) {
@@ -132,7 +145,7 @@ function startLocalServer(opts) {
132
145
  model: preferred.default_model || '',
133
146
  name: 'Default Agent',
134
147
  providerConnectionId: preferred.id,
135
- apiKeyEnc: preferred.api_key_enc || preferred.oauth_token || '',
148
+ apiKeyEnc: preferred.api_key_enc || '',
136
149
  isDefault: true,
137
150
  });
138
151
  console.log(chalk_1.default.green(' Created default agent profile from DB-backed provider connection'));
@@ -795,21 +808,31 @@ function startLocalServer(opts) {
795
808
  if (!providerId || !accessToken) {
796
809
  return res.status(400).json({ error: 'providerId and accessToken are required' });
797
810
  }
798
- const canonicalProviderId = providerId === 'claude-cli'
799
- ? 'anthropic'
800
- : providerId === 'codex-cli'
801
- ? 'openai'
802
- : providerId;
803
- const providerIds = [canonicalProviderId];
804
- const updated = providerIds.map((id) => {
811
+ const effectiveProviderId = providerId === 'claude-cli' || providerId === 'codex-cli'
812
+ ? providerId
813
+ : cli === 'claude'
814
+ ? 'claude-cli'
815
+ : cli === 'codex'
816
+ ? 'codex-cli'
817
+ : providerId;
818
+ const isCliProvider = effectiveProviderId === 'claude-cli' || effectiveProviderId === 'codex-cli';
819
+ if (!isCliProvider) {
820
+ return res.status(400).json({ error: 'Desktop auth refresh only supports Claude CLI or Codex CLI sessions.' });
821
+ }
822
+ const metadataJson = JSON.stringify({
823
+ source: cli ? `desktop-cli:${cli}` : 'desktop-cli',
824
+ });
825
+ const updated = [effectiveProviderId].map((id) => {
805
826
  const existing = data.findProviderConnection(id);
806
827
  if (existing) {
807
828
  return data.updateProviderConnection(existing.id, {
808
- accessMode: 'oauth',
809
- authType: 'oauth',
810
- oauthToken: accessToken,
811
- oauthRefreshToken: refreshToken || null,
812
- oauthExpiresAt: Number.isFinite(expiresAt) ? expiresAt : null,
829
+ accessMode: 'cli',
830
+ authType: 'cli',
831
+ apiKeyEnc: null,
832
+ oauthToken: null,
833
+ oauthRefreshToken: null,
834
+ oauthExpiresAt: null,
835
+ metadataJson,
813
836
  status: 'active',
814
837
  lastValidatedAt: new Date().toISOString(),
815
838
  lastError: null,
@@ -817,16 +840,12 @@ function startLocalServer(opts) {
817
840
  }
818
841
  return data.createProviderConnection({
819
842
  providerId: id,
820
- accessMode: 'oauth',
821
- authType: 'oauth',
822
- oauthToken: accessToken,
823
- oauthRefreshToken: refreshToken || undefined,
824
- oauthExpiresAt: Number.isFinite(expiresAt) ? expiresAt : null,
843
+ accessMode: 'cli',
844
+ authType: 'cli',
845
+ oauthExpiresAt: null,
825
846
  status: 'active',
826
847
  lastValidatedAt: new Date().toISOString(),
827
- metadataJson: JSON.stringify({
828
- source: cli ? `desktop-cli:${cli}` : 'desktop-cli',
829
- }),
848
+ metadataJson,
830
849
  });
831
850
  });
832
851
  res.json({ ok: true, updated });
@@ -1892,6 +1911,51 @@ function startLocalServer(opts) {
1892
1911
  sendTodoError(res, err);
1893
1912
  }
1894
1913
  });
1914
+ app.post('/api/todo/:id/worker-complete', (req, res) => {
1915
+ try {
1916
+ const taskId = Number(req.params.id);
1917
+ const { outputSummary, artifactRefs, handoffPrompt, insertTask, expectedVersion, expectedLastUpdated, } = req.body || {};
1918
+ const result = data.completeTodoTaskByWorker(taskId, {
1919
+ outputSummary: outputSummary === undefined ? undefined : String(outputSummary),
1920
+ artifactRefs: Array.isArray(artifactRefs) ? artifactRefs : undefined,
1921
+ handoffPrompt: handoffPrompt === undefined ? undefined : String(handoffPrompt),
1922
+ insertTask: insertTask ? {
1923
+ title: String(insertTask.title || ''),
1924
+ prompt: String(insertTask.prompt || ''),
1925
+ nextWorker: insertTask.nextWorker === undefined ? undefined : String(insertTask.nextWorker || ''),
1926
+ taskType: insertTask.taskType === undefined ? undefined : String(insertTask.taskType || ''),
1927
+ successCriteria: insertTask.successCriteria === undefined ? undefined : String(insertTask.successCriteria || ''),
1928
+ details: insertTask.details === undefined ? undefined : String(insertTask.details || ''),
1929
+ } : undefined,
1930
+ expectedVersion: expectedVersion === undefined ? undefined : Number(expectedVersion),
1931
+ expectedLastUpdated: expectedLastUpdated === undefined ? undefined : String(expectedLastUpdated),
1932
+ actor: workerTodoActorFromBody(req.body || {}),
1933
+ });
1934
+ res.json(result);
1935
+ }
1936
+ catch (err) {
1937
+ sendTodoError(res, err);
1938
+ }
1939
+ });
1940
+ app.post('/api/todo/:id/worker-block', (req, res) => {
1941
+ try {
1942
+ const taskId = Number(req.params.id);
1943
+ const { blockerSummary, checkedContext, userQuestion, artifactRefs, expectedVersion, expectedLastUpdated, } = req.body || {};
1944
+ const result = data.blockTodoTaskByWorker(taskId, {
1945
+ blockerSummary: String(blockerSummary || ''),
1946
+ checkedContext: String(checkedContext || ''),
1947
+ userQuestion: String(userQuestion || ''),
1948
+ artifactRefs: Array.isArray(artifactRefs) ? artifactRefs : undefined,
1949
+ expectedVersion: expectedVersion === undefined ? undefined : Number(expectedVersion),
1950
+ expectedLastUpdated: expectedLastUpdated === undefined ? undefined : String(expectedLastUpdated),
1951
+ actor: workerTodoActorFromBody(req.body || {}),
1952
+ });
1953
+ res.json(result);
1954
+ }
1955
+ catch (err) {
1956
+ sendTodoError(res, err);
1957
+ }
1958
+ });
1895
1959
  app.delete('/api/todo/:id', (req, res) => {
1896
1960
  try {
1897
1961
  const taskId = Number(req.params.id);
@@ -2091,13 +2155,13 @@ function startLocalServer(opts) {
2091
2155
  let profile = botId ? data.getAgentProfile(botId) : data.getDefaultAgentProfile();
2092
2156
  if (!profile) {
2093
2157
  // Auto-create a default profile from the DB-backed provider connection if available.
2094
- const providerConnection = data.listProviderConnections().find((conn) => !!(conn.api_key_enc || conn.oauth_token));
2158
+ const providerConnection = data.listProviderConnections().find((conn) => conn.access_mode === 'cli' || !!conn.api_key_enc);
2095
2159
  if (providerConnection) {
2096
2160
  profile = data.createAgentProfile({
2097
2161
  provider: providerConnection.provider_id,
2098
2162
  model: providerConnection.default_model || 'default',
2099
2163
  name: providerConnection.label || 'Default Agent',
2100
- apiKeyEnc: providerConnection.api_key_enc || providerConnection.oauth_token || '',
2164
+ apiKeyEnc: providerConnection.api_key_enc || '',
2101
2165
  isDefault: true,
2102
2166
  });
2103
2167
  }
@@ -2160,9 +2224,32 @@ function startLocalServer(opts) {
2160
2224
  }
2161
2225
  };
2162
2226
  // Save user message (skip if multi-bot call where first bot already saved it)
2227
+ let savedUserMessage = null;
2163
2228
  if (!skipUserMessage) {
2164
- data.addMessage(convId, 'user', message);
2229
+ savedUserMessage = data.addMessage(convId, 'user', message);
2165
2230
  (0, context_window_1.incrementTurnCount)(convId);
2231
+ const convForPolicy = data.getConversation(convId);
2232
+ const effectiveProjectId = projectId ? String(projectId) : (convForPolicy?.project_id || undefined);
2233
+ const projectForPolicy = effectiveProjectId ? data.getProject(effectiveProjectId) : undefined;
2234
+ const currentPolicy = data.getEffectiveOrchestrationPolicy(effectiveProjectId);
2235
+ const clerkForPolicy = (0, clerk_model_1.getClerk)();
2236
+ const agentNames = data.listAgentProfiles().map((agent) => agent.name);
2237
+ if (clerkForPolicy && savedUserMessage) {
2238
+ void (0, policy_detection_1.stagePolicyDetectionForMessage)({
2239
+ prompt: message,
2240
+ conversationId: convId,
2241
+ messageId: savedUserMessage.id,
2242
+ projectId: effectiveProjectId,
2243
+ projectName: projectForPolicy?.name,
2244
+ currentPolicy,
2245
+ clerk: clerkForPolicy,
2246
+ source: 'turn',
2247
+ requireCodeSignal: true,
2248
+ agentNames,
2249
+ }).catch((err) => {
2250
+ console.error(chalk_1.default.yellow(` [policy-detection] ${err.message}`));
2251
+ });
2252
+ }
2166
2253
  }
2167
2254
  // ─── Orchestrator Mode Branch ─────────────────────────
2168
2255
  if ((0, orchestrator_profile_1.isOrchestratorProfile)(profile)) {
@@ -2384,13 +2471,17 @@ function startLocalServer(opts) {
2384
2471
  if (fallbackMeta.length > 0) {
2385
2472
  systemPrompt += '\n\n[Project Overview]\n' + fallbackMeta.join('\n');
2386
2473
  }
2474
+ const effectivePolicy = data.getEffectiveOrchestrationPolicy(convForFallback?.project_id || undefined);
2475
+ systemPrompt += '\n\n' + (0, policy_prompt_1.buildEffectivePolicyPromptSection)(effectivePolicy, {
2476
+ heading: '[Effective Policy]',
2477
+ defaultLine: 'No confirmed special policy is set.',
2478
+ });
2387
2479
  try {
2388
2480
  const todoStatus = data.getTodoStatusMarker(convForFallback?.project_id ?? undefined);
2389
2481
  systemPrompt += `\n\n[TODO Coordination]\nTODO STATUS: ${todoStatus}`;
2390
2482
  }
2391
2483
  catch { /* best-effort */ }
2392
2484
  systemPrompt += '\n\n' + (0, clerk_model_1.buildTodoInstructions)(profile?.name || profile?.id || 'LLM');
2393
- systemPrompt += '\n\n' + (0, clerk_model_1.buildMemoryCaptureInstructions)();
2394
2485
  let hasSummary = false;
2395
2486
  try {
2396
2487
  const summaryContext = (0, context_window_1.getPromptContextWindow)(convId, safeguards_1.SAFEGUARDS.CONTEXT_WINDOW_TURNS);
@@ -4078,28 +4169,6 @@ async function buildChatRuntime(profile) {
4078
4169
  const cliModel = (profile.model || '').trim() || 'default';
4079
4170
  const apiKeyFallback = buildApiKeyFallback(profile);
4080
4171
  if (providerName === 'claude-cli' || providerName === 'codex-cli') {
4081
- // CLI-FIRST: Use CLI auth as primary (no daily re-auth).
4082
- // Subscription/OAuth is available as a fallback via apiKeyFallback if CLI fails at call time.
4083
- const subscriptionFallback = await resolveSubscriptionApiRuntime(profile);
4084
- const oauthFallback = subscriptionFallback ? {
4085
- providerName: subscriptionFallback.providerName,
4086
- apiKey: subscriptionFallback.apiKey,
4087
- model: subscriptionFallback.model,
4088
- llm: (0, index_1.createProvider)(subscriptionFallback.providerName, {
4089
- apiKey: subscriptionFallback.apiKey,
4090
- model: subscriptionFallback.model,
4091
- ...(subscriptionFallback.providerName === 'anthropic'
4092
- ? { requestShape: (0, subscription_runtime_1.resolveClaudeSubscriptionRequestShape)(subscriptionFallback.source) }
4093
- : {}),
4094
- ...(subscriptionFallback.baseUrl ? { baseUrl: subscriptionFallback.baseUrl } : {}),
4095
- ...(subscriptionFallback.apiQuery ? { apiQuery: subscriptionFallback.apiQuery } : {}),
4096
- ...(subscriptionFallback.apiStyle ? { apiStyle: subscriptionFallback.apiStyle } : {}),
4097
- ...(subscriptionFallback.authMode ? { authMode: subscriptionFallback.authMode } : {}),
4098
- ...(subscriptionFallback.extraHeaders ? { extraHeaders: subscriptionFallback.extraHeaders } : {}),
4099
- }),
4100
- runtimeMode: 'subscription-api',
4101
- runtimeSource: subscriptionFallback.source,
4102
- } : undefined;
4103
4172
  return {
4104
4173
  providerName,
4105
4174
  apiKey: 'cli-auth',
@@ -4107,8 +4176,7 @@ async function buildChatRuntime(profile) {
4107
4176
  llm: (0, index_1.createProvider)(providerName, { apiKey: 'cli-auth', model: cliModel }),
4108
4177
  runtimeMode: 'subscription-cli',
4109
4178
  runtimeSource: 'cli-direct',
4110
- // OAuth available as fallback if CLI auth fails
4111
- apiKeyFallback: oauthFallback || apiKeyFallback,
4179
+ apiKeyFallback,
4112
4180
  };
4113
4181
  }
4114
4182
  const apiKey = resolveApiKey(profile);
@@ -4126,8 +4194,6 @@ async function buildChatRuntime(profile) {
4126
4194
  };
4127
4195
  }
4128
4196
  function runtimeModeLabel(mode, runtimeSource) {
4129
- if (mode === 'subscription-api')
4130
- return (0, subscription_runtime_1.claudeSubscriptionRuntimeLabel)(runtimeSource);
4131
4197
  if (mode === 'subscription-cli')
4132
4198
  return 'Subscription CLI';
4133
4199
  return 'API Key';
@@ -4148,21 +4214,10 @@ function configuredRuntimeLabelForProfile(profile) {
4148
4214
  const directConnection = profile.provider_connection_id
4149
4215
  ? data.listProviderConnections().find((row) => row.id === profile.provider_connection_id)
4150
4216
  : undefined;
4151
- const connection = profile.provider === 'claude-cli'
4152
- ? data.findProviderConnection('anthropic', 'openclaw')
4153
- || data.findProviderConnection('anthropic', 'oauth')
4154
- || directConnection
4155
- : profile.provider === 'codex-cli'
4156
- ? data.findProviderConnection('openai', 'oauth')
4157
- || directConnection
4158
- : directConnection;
4217
+ const connection = directConnection;
4159
4218
  if (connection) {
4160
- if (connection.access_mode === 'openclaw')
4161
- return 'OpenClaw Connection';
4162
4219
  if (connection.access_mode === 'cli')
4163
4220
  return 'Subscription CLI';
4164
- if (connection.auth_type === 'oauth')
4165
- return 'Subscription API';
4166
4221
  return 'API Key';
4167
4222
  }
4168
4223
  if (profile.provider === 'claude-cli' || profile.provider === 'codex-cli') {
@@ -4324,7 +4379,7 @@ function buildApiKeyFallback(profile) {
4324
4379
  ? 'anthropic'
4325
4380
  : profile.provider;
4326
4381
  const configured = data.findProviderConnection(providerName);
4327
- const apiKey = configured?.api_key_enc || configured?.oauth_token || resolveApiKey({ ...profile, provider: providerName });
4382
+ const apiKey = configured?.api_key_enc || resolveApiKey({ ...profile, provider: providerName });
4328
4383
  if (!apiKey)
4329
4384
  return undefined;
4330
4385
  const model = (0, subscription_runtime_1.resolveSubscriptionApiModel)(profile.model, configured?.default_model || undefined)
@@ -4339,36 +4394,6 @@ function buildApiKeyFallback(profile) {
4339
4394
  runtimeSource: 'api-key-fallback',
4340
4395
  };
4341
4396
  }
4342
- async function resolveSubscriptionApiRuntime(profile) {
4343
- if (profile.provider === 'claude-cli') {
4344
- try {
4345
- const profileConnection = profile.provider_connection_id
4346
- ? data.getProviderConnection(profile.provider_connection_id)
4347
- : undefined;
4348
- return await (0, subscription_runtime_1.resolveClaudeSubscriptionRuntime)({
4349
- preferredModel: profile.model,
4350
- inputToken: profileConnection?.access_mode === 'openclaw' ? (profileConnection.api_key_enc || null) : null,
4351
- inputAccessMode: profileConnection?.access_mode || null,
4352
- });
4353
- }
4354
- catch (err) {
4355
- console.warn(chalk_1.default.yellow(` [chat] Claude subscription auth failed: ${err?.message || err}`));
4356
- return null;
4357
- }
4358
- }
4359
- if (profile.provider === 'codex-cli') {
4360
- try {
4361
- return await (0, subscription_runtime_1.resolveCodexSubscriptionRuntime)({
4362
- preferredModel: profile.model,
4363
- });
4364
- }
4365
- catch (err) {
4366
- console.warn(chalk_1.default.yellow(` [chat] Codex subscription auth failed: ${err?.message || err}`));
4367
- return null;
4368
- }
4369
- }
4370
- return null;
4371
- }
4372
4397
  function resolveApiKey(profile) {
4373
4398
  // Check profile-stored key first
4374
4399
  if (profile.api_key_enc)
@@ -4377,8 +4402,6 @@ function resolveApiKey(profile) {
4377
4402
  const providerConnection = data.findProviderConnection(profile.provider);
4378
4403
  if (providerConnection?.api_key_enc)
4379
4404
  return providerConnection.api_key_enc;
4380
- if (providerConnection?.oauth_token)
4381
- return providerConnection.oauth_token;
4382
4405
  // Env vars
4383
4406
  switch (profile.provider) {
4384
4407
  case 'anthropic': return process.env.ANTHROPIC_API_KEY;