maka-agent 0.2.0-dev.43.20260919 → 0.2.0-dev.45.20260921

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 (89) hide show
  1. package/LICENSE +12 -6
  2. package/dist/mcp-capability-provider.js +7 -0
  3. package/dist/runtime-host-service-manager.js +1 -6
  4. package/dist/runtime-host-tui-command.js +1 -1
  5. package/dist/runtime-host-update-command.js +39 -27
  6. package/native/runtime-host-windows-task-launcher/prebuilds/win32-x64/maka-runtime-host-task-launcher.exe +0 -0
  7. package/node_modules/@maka/core/dist/artifacts.js +1 -0
  8. package/node_modules/@maka/core/dist/chat-model-choice.js +3 -0
  9. package/node_modules/@maka/core/dist/llm-connections.js +3 -21
  10. package/node_modules/@maka/core/dist/model-catalog.js +8 -20
  11. package/node_modules/@maka/core/dist/model-metadata.generated.js +304 -304
  12. package/node_modules/@maka/core/dist/model-metadata.js +1 -2
  13. package/node_modules/@maka/core/dist/model-thinking.js +16 -1
  14. package/node_modules/@maka/core/dist/models-dev-projection.js +0 -1
  15. package/node_modules/@maka/core/dist/provider-auth.js +1 -7
  16. package/node_modules/@maka/core/dist/provider-registry.js +20 -58
  17. package/node_modules/@maka/core/dist/recall.js +5 -1
  18. package/node_modules/@maka/core/dist/runtime-policy/connection-catalog-codec.js +7 -0
  19. package/node_modules/@maka/core/dist/runtime-policy/model-catalog-entry-codec.js +14 -1
  20. package/node_modules/@maka/core/dist/session-start-mode.js +2 -5
  21. package/node_modules/@maka/core/dist/session.js +0 -1
  22. package/node_modules/@maka/core/dist/settings.js +19 -3
  23. package/node_modules/@maka/core/dist/tool-quiet-preview.js +2 -16
  24. package/node_modules/@maka/core/dist/transcript-search.js +46 -0
  25. package/node_modules/@maka/core/package.json +1 -4
  26. package/node_modules/@maka/mcp/dist/index.js +22 -0
  27. package/node_modules/@maka/mcp/dist/oauth.js +4 -2
  28. package/node_modules/@maka/mcp/dist/tool-progress.js +45 -0
  29. package/node_modules/@maka/runtime/dist/model-factory.js +0 -16
  30. package/node_modules/@maka/runtime/dist/model-fetcher.js +1 -4
  31. package/node_modules/@maka/runtime/dist/model-runtime.js +0 -8
  32. package/node_modules/@maka/runtime/dist/opencode-session-header.js +2 -3
  33. package/node_modules/@maka/runtime/dist/recall-tools.js +4 -0
  34. package/node_modules/@maka/runtime/dist/session-manager.js +5 -57
  35. package/node_modules/@maka/runtime/dist/subagent-tools.js +69 -11
  36. package/node_modules/@maka/runtime/dist/test-connection.js +4 -114
  37. package/node_modules/@maka/runtime/package.json +0 -1
  38. package/node_modules/@maka/runtime-host/dist/client/client-capability-channel.js +44 -9
  39. package/node_modules/@maka/runtime-host/dist/client/host-handoff-copy.js +25 -18
  40. package/node_modules/@maka/runtime-host/dist/client/host-handoff.js +3 -1
  41. package/node_modules/@maka/runtime-host/dist/client/index.js +1 -1
  42. package/node_modules/@maka/runtime-host/dist/client/session-subscription.js +33 -3
  43. package/node_modules/@maka/runtime-host/dist/protocol/connection-effects.js +0 -108
  44. package/node_modules/@maka/runtime-host/dist/protocol/index.js +12 -1
  45. package/node_modules/@maka/runtime-host/dist/protocol/message.js +10 -0
  46. package/node_modules/@maka/runtime-host/dist/protocol/operations.js +4 -6
  47. package/node_modules/@maka/runtime-host/dist/protocol/recall.js +270 -0
  48. package/node_modules/@maka/runtime-host/dist/protocol/session-catalog.js +1 -1
  49. package/node_modules/@maka/runtime-host/dist/protocol/session-continuity.js +1 -7
  50. package/node_modules/@maka/runtime-host/dist/protocol/turn.js +0 -33
  51. package/node_modules/@maka/runtime-host/dist/protocol/usage-screen.js +12 -4
  52. package/node_modules/@maka/runtime-host/dist/server/access-credential-store.js +6 -0
  53. package/node_modules/@maka/runtime-host/dist/server/bootstrap-runtime-policy.js +31 -104
  54. package/node_modules/@maka/runtime-host/dist/server/connection-effect-coordinator.js +1 -57
  55. package/node_modules/@maka/runtime-host/dist/server/execution-composition.js +11 -35
  56. package/node_modules/@maka/runtime-host/dist/server/interactive-run-composer.js +3 -20
  57. package/node_modules/@maka/runtime-host/dist/server/interactive-turn-coordinator.js +1 -16
  58. package/node_modules/@maka/runtime-host/dist/server/message-coordinator.js +46 -28
  59. package/node_modules/@maka/runtime-host/dist/server/recall-coordinator.js +117 -0
  60. package/node_modules/@maka/runtime-host/dist/server/root-turn-coordinator.js +5 -16
  61. package/node_modules/@maka/runtime-host/dist/server/session-catalog-coordinator.js +21 -12
  62. package/node_modules/@maka/runtime-host/dist/server/session-revision-coordinator.js +0 -4
  63. package/node_modules/@maka/runtime-host/dist/server/session-turn-access-request-coordinator.js +7 -17
  64. package/node_modules/@maka/storage/dist/artifact-metadata-codec.js +4 -3
  65. package/node_modules/@maka/storage/dist/artifact-store.js +1 -11
  66. package/node_modules/@maka/storage/dist/process-lifetime-file-update-lock.js +0 -41
  67. package/node_modules/@maka/storage/dist/runtime-policy/connection-catalog-document.js +0 -62
  68. package/node_modules/@maka/storage/dist/runtime-policy/coordinator.js +0 -31
  69. package/node_modules/@maka/storage/dist/runtime-policy-stores.js +0 -3
  70. package/node_modules/@maka/storage/dist/sqlite-usage-schema.js +29 -5
  71. package/node_modules/@maka/storage/dist/sqlite-workflow-schema.js +2 -0
  72. package/node_modules/@maka/storage/dist/storage-writer-composition.js +0 -3
  73. package/node_modules/@maka/storage/dist/telemetry-file-schema.js +5 -3
  74. package/node_modules/@maka/storage/dist/usage-screen.js +5 -6
  75. package/node_modules/@maka/storage/dist/usage-stores.js +14 -4
  76. package/node_modules/@maka/storage/package.json +0 -2
  77. package/package.json +1 -1
  78. package/node_modules/@maka/core/dist/connection-usage.js +0 -27
  79. package/node_modules/@maka/core/dist/deep-research-client-progress.js +0 -132
  80. package/node_modules/@maka/core/dist/deep-research-run.js +0 -625
  81. package/node_modules/@maka/core/dist/deep-research.js +0 -208
  82. package/node_modules/@maka/core/dist/thread-search.js +0 -498
  83. package/node_modules/@maka/runtime/dist/commandcode-cli-language-model.js +0 -837
  84. package/node_modules/@maka/runtime/dist/connection-usage.js +0 -232
  85. package/node_modules/@maka/runtime/dist/deep-research-tools.js +0 -732
  86. package/node_modules/@maka/runtime-host/dist/protocol/deep-research.js +0 -233
  87. package/node_modules/@maka/runtime-host/dist/server/deep-research-coordinator.js +0 -116
  88. package/node_modules/@maka/storage/dist/deep-research-authority.js +0 -129
  89. package/node_modules/@maka/storage/dist/deep-research-store.js +0 -343
@@ -413,9 +413,8 @@ function buildStaticModelMetadata(active) {
413
413
  return {
414
414
  anthropic: ANTHROPIC_MODEL_OVERRIDES,
415
415
  'claude-subscription': claudeSubscriptionModelMetadata(active),
416
- // Both Command Code providers ride the same Provider-API effort table.
416
+ // The Command Code Provider-API plan rides the same effort table.
417
417
  commandcode: COMMAND_CODE_MODEL_METADATA,
418
- 'commandcode-go': COMMAND_CODE_MODEL_METADATA,
419
418
  'alibaba-token-plan-cn': {
420
419
  'qwen3.8-max': {
421
420
  thinkingOptions: { efforts: ['none', 'low', 'medium', 'xhigh'], toggle: true },
@@ -85,6 +85,9 @@ function normalizeModelOverride(entry) {
85
85
  declared.thinkingLevels = DECLARABLE_RELAY_THINKING_LEVELS.filter((level) => declaredSet.has(level));
86
86
  }
87
87
  }
88
+ if (isThinkingLevel(entry.defaultThinkingLevel)) {
89
+ declared.defaultThinkingLevel = entry.defaultThinkingLevel;
90
+ }
88
91
  if (typeof entry.vision === 'boolean')
89
92
  declared.vision = entry.vision;
90
93
  for (const field of [
@@ -188,6 +191,18 @@ export function thinkingVariantsForConnection(connection, modelId) {
188
191
  return declared;
189
192
  return thinkingVariantsForModel(connection.providerType, modelId);
190
193
  }
194
+ /**
195
+ * Resolve the configured new-Session default against the model's effective
196
+ * capability ladder. A stale declaration falls back to the provider default
197
+ * instead of reaching Session creation as an unsupported level.
198
+ */
199
+ export function defaultThinkingLevelForConnection(connection, modelId) {
200
+ const configured = modelOverride(connection, modelId)?.defaultThinkingLevel;
201
+ return configured !== undefined &&
202
+ thinkingVariantsForConnection(connection, modelId).includes(configured)
203
+ ? configured
204
+ : undefined;
205
+ }
191
206
  /**
192
207
  * Discard-semantics gate: returns the level when the model offers it,
193
208
  * `undefined` otherwise. Callers that must *reject* a bad level (IPC/session
@@ -225,7 +240,7 @@ export function thinkingVariantsForModel(providerType, modelId) {
225
240
  export function applyModelOverride(model, override) {
226
241
  if (!override)
227
242
  return model;
228
- const { thinkingLevels: _thinking, serviceTier: _tier, compactionThreshold: _threshold, maxOutputTokens: _outputBudget, vision, capabilities, ...facts } = override;
243
+ const { thinkingLevels: _thinking, defaultThinkingLevel: _defaultThinking, serviceTier: _tier, compactionThreshold: _threshold, maxOutputTokens: _outputBudget, vision, capabilities, ...facts } = override;
229
244
  return {
230
245
  ...model,
231
246
  ...facts,
@@ -203,7 +203,6 @@ export function projectModelsDevModel(providerId, modelId, provider, model) {
203
203
  ...(model.knowledge !== undefined ? { knowledgeCutoff: model.knowledge } : {}),
204
204
  ...(model.structured_output !== undefined ? { structuredOutput: model.structured_output } : {}),
205
205
  ...(model.last_updated !== undefined ? { lastUpdated: model.last_updated } : {}),
206
- ...(model.cost?.input === 0 ? { isFree: true } : {}),
207
206
  capabilities: {
208
207
  ...(modalities ? { vision: modalities.input.includes('image') } : {}),
209
208
  reasoning: model.reasoning === true,
@@ -22,12 +22,7 @@ import { providerAuthRequiresSecret, providerDefaultsOf, providerSupportsModelDi
22
22
  * storage coordinator actually gates — an operation with no admission point
23
23
  * does not belong here, however natural it sounds beside these three.
24
24
  */
25
- export const PROVIDER_AUTH_ACTIONS = [
26
- 'test_credentials',
27
- 'fetch_models',
28
- 'read_usage',
29
- 'start_oauth',
30
- ];
25
+ export const PROVIDER_AUTH_ACTIONS = ['test_credentials', 'fetch_models', 'start_oauth'];
31
26
  /**
32
27
  * Which credential operations a connection may run. This is an admission
33
28
  * answer, not a UI state: the storage layer refuses an unavailable action, so a
@@ -74,7 +69,6 @@ export function deriveProviderAuthContract(input) {
74
69
  fetch_models: canFetchModels && (reachableWithoutSecret || hasSecret),
75
70
  // Reading account usage needs the same reachability as a connection test:
76
71
  // a credential the provider accepts over HTTP.
77
- read_usage: reachableWithoutSecret || hasSecret,
78
72
  }),
79
73
  };
80
74
  }
@@ -17,7 +17,6 @@
17
17
  * under the License.
18
18
  */
19
19
  import { GENERATED_MODELS_DEV_METADATA, GENERATED_MODELS_DEV_MODEL_PROVIDER_OVERRIDES, GENERATED_MODELS_DEV_PROVIDER_FACTS, } from './model-metadata.generated.js';
20
- export const OPENCODE_FREE_DEFAULT_MODEL = 'nemotron-3-ultra-free';
21
20
  const siliconflow = GENERATED_MODELS_DEV_PROVIDER_FACTS.siliconflow;
22
21
  if (!siliconflow.api)
23
22
  throw new Error('models.dev SiliconFlow provider facts are missing api');
@@ -423,37 +422,6 @@ if (opencodeGo.id !== 'opencode-go' || opencodeGo.api !== 'https://opencode.ai/z
423
422
  throw new Error('models.dev OpenCode Go provider facts are missing the stable id or API');
424
423
  }
425
424
  const opencodeGoModelIds = toolCallingModelIds('OpenCode Go', GENERATED_MODELS_DEV_METADATA['opencode-go'], ['minimax-m3']).filter((id) => GENERATED_MODELS_DEV_METADATA['opencode-go'][id]?.lifecycle !== 'deprecated');
426
- // opencode-free is Maka's first-class free anonymous default. It shares the
427
- // OpenCode Zen endpoint and model ids, exposing the active tool-capable
428
- // models the models.dev snapshot marks `isFree` (zero input cost). Deriving
429
- // the set from the snapshot lets routine metadata refreshes rotate free
430
- // models in and out instead of letting a hardcoded pin rot (#3409).
431
- //
432
- // Persistently broken free models, excluded with dated evidence. Deny-only:
433
- // a stale entry hides at most one healthy model, the opposite failure mode of
434
- // the allow-list pin this replaced. Entries should be re-probed on snapshot
435
- // refreshes and removed once the model produces content again.
436
- // 2026-08-21 muse-spark-1.2-contributor-free: anonymous completions return
437
- // 200 with an empty message and bill the full token budget (4 consecutive
438
- // probes, max_tokens 8–200) — a failure shape that even "the send settles it"
439
- // cannot surface, which is why these ids are also vetoed in
440
- // `authorizeConnectionModel` rather than merely dropped from this derivation.
441
- // 2026-08-30 x-preview-f-free (Ox Alpha Free): retired upstream — dropped from
442
- // the anonymous /models listing and every completion returns HTTP 401
443
- // {"type":"ModelError","message":"Model x-preview-f-free is not supported"}.
444
- // models.dev still snapshots it as free+active, so the derivation kept offering
445
- // it as a default-enabled, picker-visible row until this quarantine. Remove
446
- // once the snapshot marks it deprecated (or upstream serves it again).
447
- const OPENCODE_FREE_BROKEN_MODEL_IDS = new Set([
448
- 'muse-spark-1.2-contributor-free',
449
- 'x-preview-f-free',
450
- ]);
451
- const opencodeFreeModelIds = toolCallingModelIds('OpenCode Free', Object.fromEntries(Object.entries(GENERATED_MODELS_DEV_METADATA.opencode).filter(([id, model]) => model.isFree === true &&
452
- model.lifecycle !== 'deprecated' &&
453
- !OPENCODE_FREE_BROKEN_MODEL_IDS.has(id))), [OPENCODE_FREE_DEFAULT_MODEL]);
454
- if (opencodeFreeModelIds[0] !== OPENCODE_FREE_DEFAULT_MODEL) {
455
- throw new Error(`models.dev opencode snapshot no longer serves ${OPENCODE_FREE_DEFAULT_MODEL} as an active tool-capable free model; pick a new OPENCODE_FREE_DEFAULT_MODEL`);
456
- }
457
425
  const githubCopilot = GENERATED_MODELS_DEV_PROVIDER_FACTS['github-copilot'];
458
426
  if (githubCopilot.id !== 'github-copilot') {
459
427
  throw new Error('models.dev GitHub Copilot provider facts are missing stable id github-copilot');
@@ -968,22 +936,15 @@ const providerRegistry = {
968
936
  label: 'OpenCode Free',
969
937
  baseUrl: opencode.api,
970
938
  authKind: 'none',
971
- fallbackModels: [...opencodeFreeModelIds],
972
- // Free and keyless: nothing is spent by having every shipped model on, and
973
- // a user who just added the connection can send immediately.
974
- enableShippedModelsByDefault: true,
975
- brokenModelIds: [...OPENCODE_FREE_BROKEN_MODEL_IDS],
976
- status: 'ready',
977
- runtimeAdapter: { kind: 'openai-compatible', name: 'provider' },
939
+ fallbackModels: [],
940
+ status: 'phase3-experimental',
941
+ runtimeAdapter: { kind: 'unavailable' },
942
+ retired: true,
978
943
  modelDiscovery: {
979
944
  kind: 'fallback',
980
- reason: 'The anonymous /models listing describes the full Zen catalog with no cost facts; which models are FREE is a models.dev fact, so the derived candidates are the inventory and the send settles availability.',
945
+ reason: 'OpenCode restricts its free tier to the OpenCode client.',
981
946
  },
982
947
  category: 'overseas',
983
- catalogGroup: 'plans',
984
- signupUrl: 'https://opencode.ai/zen',
985
- catalogOrder: 0,
986
- recommendedOrder: 0,
987
948
  },
988
949
  togetherai: {
989
950
  label: together.name,
@@ -1259,20 +1220,26 @@ const providerRegistry = {
1259
1220
  signupUrl: 'https://commandcode.ai/docs/plans/goat',
1260
1221
  catalogOrder: 41.5,
1261
1222
  },
1223
+ // Retired rather than removed: an existing connection must stay identifiable
1224
+ // and must answer `provider_retired` at readiness. Removing the entry would
1225
+ // leave it *unknown*, which `isConnectionReady` does not reject, so a send
1226
+ // would be admitted and only fail deep in model construction. Its transport
1227
+ // presented the official CLI's identity to a private endpoint, which is why
1228
+ // nothing can send through it any more.
1262
1229
  'commandcode-go': {
1263
1230
  label: 'Command Code GO',
1264
- // The API root, not `/provider/v1`: generation posts to `/alpha/generate`
1265
- // and discovery reads `/provider/v1/models`, both under it.
1266
1231
  baseUrl: 'https://api.commandcode.ai',
1267
1232
  authKind: 'api_key',
1268
1233
  fallbackModels: [],
1269
- status: 'ready',
1270
- runtimeAdapter: { kind: 'commandcode-cli' },
1271
- modelDiscovery: { kind: 'protocol', path: 'provider/v1/models' },
1234
+ status: 'phase3-experimental',
1235
+ runtimeAdapter: { kind: 'unavailable' },
1236
+ retired: true,
1237
+ modelDiscovery: {
1238
+ kind: 'fallback',
1239
+ reason: 'The GO plan was reached through the official CLI\u2019s private transport.',
1240
+ },
1272
1241
  category: 'overseas',
1273
1242
  catalogGroup: 'plans',
1274
- signupUrl: 'https://commandcode.ai/docs/plans/go',
1275
- catalogOrder: 41.6,
1276
1243
  },
1277
1244
  'cloudflare-workers-ai': {
1278
1245
  label: cloudflareWorkersAi.name,
@@ -1471,16 +1438,11 @@ export function providerDefaultsOf(providerType) {
1471
1438
  }
1472
1439
  /**
1473
1440
  * The models a provider offers with no live list to go on: the baseline it
1474
- * ships, minus anything quarantined. This is the only reader of
1441
+ * ships. This is the only reader of
1475
1442
  * `fallbackModels` — a provider's offline offer has exactly one authority.
1476
- *
1477
- * `brokenModelIds` subtracts here rather than being pruned from the baseline at
1478
- * the source because the ids it names are ones a stored connection may still
1479
- * carry from an older shipped list.
1480
1443
  */
1481
1444
  export function providerFallbackModelIds(defaults) {
1482
- const broken = new Set(defaults.brokenModelIds ?? []);
1483
- return defaults.fallbackModels.filter((id) => !broken.has(id));
1445
+ return [...defaults.fallbackModels];
1484
1446
  }
1485
1447
  /**
1486
1448
  * The provider's name as a model row shows it, or `undefined` when this build
@@ -59,7 +59,7 @@ import { validateWorkspacePrivacyContext } from './incognito.js';
59
59
  import { redactSecrets } from './redaction.js';
60
60
  import { SEARCH_QUERY_MAX_CHARS } from './search.js';
61
61
  import { collapseSessionRevisions } from './session-revisions.js';
62
- import { foldForMatch, MAX_SESSIONS_SCANNED, threadSearchMatchKind } from './thread-search.js';
62
+ import { foldForMatch, MAX_SESSIONS_SCANNED, threadSearchMatchKind } from './transcript-search.js';
63
63
  /** Okapi BM25 term-frequency saturation, Lucene's default. */
64
64
  export const RECALL_BM25_K1 = 1.2;
65
65
  /** Okapi BM25 length normalization, Lucene's default. */
@@ -960,6 +960,10 @@ function buildPassage(anchor, transcript, session, budget, activeSessionId, span
960
960
  sessionTitle: redactSecrets(session?.name ?? ''),
961
961
  ...(anchor.turnId ? { turnId: anchor.turnId } : {}),
962
962
  anchorMessageId: anchor.message.id,
963
+ // The anchor's position in the transcript this passage was built from.
964
+ // `anchorIndex` is already `findIndex` over that exact array, so this is
965
+ // the same coordinate the transcript reader addresses.
966
+ sequence: anchorIndex,
963
967
  messages,
964
968
  matchedTerms: anchor.matchedTerms,
965
969
  score: Number(anchor.score.toFixed(4)),
@@ -168,6 +168,7 @@ export function decodeModelOverridesTable(value) {
168
168
  decodeConnectionModelId(modelId);
169
169
  const entry = exactRecord(rawEntry, `relay model profile for ${modelId}`, [
170
170
  'thinkingLevels',
171
+ 'defaultThinkingLevel',
171
172
  'vision',
172
173
  'contextWindow',
173
174
  'serviceTier',
@@ -200,6 +201,12 @@ export function decodeModelOverridesTable(value) {
200
201
  }
201
202
  declared.thinkingLevels = [...entry.thinkingLevels];
202
203
  }
204
+ if (entry.defaultThinkingLevel !== undefined) {
205
+ if (!isThinkingLevel(entry.defaultThinkingLevel)) {
206
+ throw domainError(`default thinking level for ${modelId} is invalid`);
207
+ }
208
+ declared.defaultThinkingLevel = entry.defaultThinkingLevel;
209
+ }
203
210
  if (entry.vision !== undefined) {
204
211
  declared.vision = booleanValue(entry.vision, `declared vision for ${modelId}`);
205
212
  }
@@ -36,6 +36,7 @@ export function decodeModelCatalogEntry(value) {
36
36
  'defaultSupportsVision',
37
37
  'compactionThreshold',
38
38
  'thinkingLevels',
39
+ 'defaultThinkingLevel',
39
40
  'contextWindow',
40
41
  'inputLimit',
41
42
  'defaultContextWindow',
@@ -49,6 +50,7 @@ export function decodeModelCatalogEntry(value) {
49
50
  id: item.id,
50
51
  ...pick(item, ['displayName', 'description', 'contextWindow', 'inputLimit', 'knowledgeCutoff']),
51
52
  });
53
+ const thinkingLevels = decodeThinkingLevels(item.thinkingLevels);
52
54
  return {
53
55
  ...shared,
54
56
  ...Object.fromEntries(['defaultContextWindow', 'defaultInputLimit'].flatMap((field) => item[field] === undefined
@@ -67,9 +69,20 @@ export function decodeModelCatalogEntry(value) {
67
69
  defaultSupportsVision: booleanValue(item.defaultSupportsVision, 'entry default vision support'),
68
70
  }
69
71
  : {}),
70
- thinkingLevels: decodeThinkingLevels(item.thinkingLevels),
72
+ thinkingLevels,
73
+ ...(item.defaultThinkingLevel === undefined
74
+ ? {}
75
+ : {
76
+ defaultThinkingLevel: decodeDefaultThinkingLevel(item.defaultThinkingLevel, thinkingLevels),
77
+ }),
71
78
  };
72
79
  }
80
+ function decodeDefaultThinkingLevel(value, available) {
81
+ if (!isThinkingLevel(value) || !available.includes(value)) {
82
+ throw domainError('entry default thinking level is invalid');
83
+ }
84
+ return value;
85
+ }
73
86
  function decodeThinkingLevels(value) {
74
87
  if (!Array.isArray(value))
75
88
  throw domainError('entry thinking levels must be an array');
@@ -17,11 +17,6 @@
17
17
  * under the License.
18
18
  */
19
19
  export const SESSION_START_MODE_SPECS = {
20
- deep_research: {
21
- name: 'Deep Research',
22
- labels: ['mode:deep_research'],
23
- permissionMode: 'explore',
24
- },
25
20
  bot: {
26
21
  labels: ['mode:bot'],
27
22
  permissionMode: 'explore',
@@ -29,6 +24,8 @@ export const SESSION_START_MODE_SPECS = {
29
24
  };
30
25
  export const SESSION_START_MODES = Object.keys(SESSION_START_MODE_SPECS);
31
26
  export const SESSION_START_MODE_LABELS = [
27
+ // Historical mode labels remain reserved when editing old Sessions.
28
+ 'mode:deep_research',
32
29
  ...new Set(Object.values(SESSION_START_MODE_SPECS).flatMap((spec) => spec.labels)),
33
30
  ];
34
31
  export function isSessionStartMode(value) {
@@ -27,7 +27,6 @@ import { isTokenUsageFields } from './usage-record-schema.js';
27
27
  import { decodeCanonicalToolResultContent, decodePersistedToolResultContent, } from './tool-result-record-schema.js';
28
28
  import { markPersisted } from './persisted-value.js';
29
29
  import { decodeTurnOrigin } from './turn-origin.js';
30
- export { DEEP_RESEARCH_SESSION_LABEL, isDeepResearchSession } from './deep-research.js';
31
30
  /** Runtime execution states. Archive visibility is represented by `isArchived`. */
32
31
  export const SESSION_STATUSES = [
33
32
  'active',
@@ -27,6 +27,23 @@ import { normalizeSubagentSettings } from './subagent-settings.js';
27
27
  import { isPetPackId } from './pet.js';
28
28
  export { UI_LOCALE_PREFERENCES, isUiLocalePreference } from './ui-locale.js';
29
29
  export { BOT_DELIVERY_PROVIDERS, BOT_PROVIDERS, BOT_READINESS_STATES, MAX_ALLOWED_USER_IDS, createDefaultBotChannel, hasBotChannelCredentials, isBotDeliveryProvider, isBotReadinessState, normalizeAllowedUserIds, parseAllowedUserIdsFromText, } from './bot-chat-settings.js';
30
+ export const USAGE_SCREEN_SEARCH_MAX_BYTES = 1024;
31
+ const USAGE_SCREEN_UTF8 = new TextEncoder();
32
+ /** Shared domain for the Usage screen's free-text query at every boundary. */
33
+ export function isUsageScreenSearch(value) {
34
+ return (typeof value === 'string' &&
35
+ USAGE_SCREEN_UTF8.encode(value).byteLength <= USAGE_SCREEN_SEARCH_MAX_BYTES);
36
+ }
37
+ /**
38
+ * Persisted Usage timestamps may retain sub-millisecond precision. Keep them
39
+ * JSON/SQLite round-trip safe so a stored value can also name a continuation.
40
+ */
41
+ export function isUsageTimestamp(value) {
42
+ return (typeof value === 'number' &&
43
+ Number.isFinite(value) &&
44
+ value >= 0 &&
45
+ value <= Number.MAX_SAFE_INTEGER);
46
+ }
30
47
  export const SETTINGS_SECTIONS = [
31
48
  'general',
32
49
  'appearance',
@@ -608,9 +625,8 @@ function defaultChatDefaultsSettings() {
608
625
  function normalizeChatDefaultsSettings(settings) {
609
626
  return {
610
627
  ...(settings.codeModeEnabled === true ? { codeModeEnabled: true } : {}),
611
- // Same fail-closed reasoning as the mode below: a garbage persisted level
612
- // drops to "no preference" (the model's own default) rather than reaching
613
- // session creation as a rung no picker recognizes.
628
+ // Preserve the retired field while older settings documents still carry it.
629
+ // No task creation path consumes it; defaults now live on model overrides.
614
630
  thinkingLevel: isThinkingLevel(settings.thinkingLevel) ? settings.thinkingLevel : undefined,
615
631
  // A retired mode is decoded (not rejected) so an existing settings file
616
632
  // keeps working; knowing which modes are retired lives in one place.
@@ -217,13 +217,6 @@ export function formatToolInvocationLine(item, locale) {
217
217
  parts.push(`${cols}x${rows}`);
218
218
  return parts.join(' · ');
219
219
  }
220
- if (name === 'deep_research_start') {
221
- const objective = stringField(args, 'objective');
222
- if (objective) {
223
- const scopeLevel = stringField(args, 'scope_level');
224
- return redactSecrets(scopeLevel ? `${objective} (${scopeLevel})` : objective);
225
- }
226
- }
227
220
  if (name === 'GoalSet') {
228
221
  const condition = stringField(args, 'condition');
229
222
  if (condition)
@@ -304,10 +297,6 @@ const ARGS_PREVIEW_SCALAR_KEYS = [
304
297
  'id',
305
298
  'ref',
306
299
  ];
307
- // This tool's objective is the compact row's durable headline. Keep it
308
- // explicit rather than widening the generic wire allowlist with a broad key
309
- // such as `input`: non-WriteStdin tools otherwise retain arbitrary payloads.
310
- const DEEP_RESEARCH_START_PREVIEW_SCALAR_KEYS = ['objective', 'scope_level'];
311
300
  const ARGS_PREVIEW_NUMBER_KEYS = ['offset', 'limit'];
312
301
  function boundPreviewString(value) {
313
302
  const redacted = redactSecrets(value);
@@ -387,11 +376,8 @@ export function projectToolArgsPreview(toolName, args) {
387
376
  // Apply the canonical activity projection first so WriteStdin's inputPreview
388
377
  // shape (bounded, display-safe) is what the whitelist picks up.
389
378
  const projected = asRecord(projectToolActivityArgs(toolName, args)) ?? record;
390
- const scalarKeys = toolName === 'deep_research_start'
391
- ? [...ARGS_PREVIEW_SCALAR_KEYS, ...DEEP_RESEARCH_START_PREVIEW_SCALAR_KEYS]
392
- : ARGS_PREVIEW_SCALAR_KEYS;
393
379
  const picked = new Map();
394
- for (const key of scalarKeys) {
380
+ for (const key of ARGS_PREVIEW_SCALAR_KEYS) {
395
381
  if (isSensitiveKey(key))
396
382
  continue;
397
383
  const value = previewStringField(projected, key);
@@ -429,7 +415,7 @@ export function projectToolArgsPreview(toolName, args) {
429
415
  // Enforce the whole-preview budget by dropping lowest-priority fields; the
430
416
  // first picked (highest-priority) field always survives.
431
417
  const keysByPriority = [
432
- ...scalarKeys,
418
+ ...ARGS_PREVIEW_SCALAR_KEYS,
433
419
  ...ARGS_PREVIEW_NUMBER_KEYS,
434
420
  'inputPreview',
435
421
  'size',
@@ -0,0 +1,46 @@
1
+ /*
2
+ * Licensed to the Apache Software Foundation (ASF) under one
3
+ * or more contributor license agreements. See the NOTICE file
4
+ * distributed with this work for additional information
5
+ * regarding copyright ownership. The ASF licenses this file
6
+ * to you under the Apache License, Version 2.0 (the
7
+ * "License"); you may not use this file except in compliance
8
+ * with the License. You may obtain a copy of the License at
9
+ *
10
+ * http://www.apache.org/licenses/LICENSE-2.0
11
+ *
12
+ * Unless required by applicable law or agreed to in writing,
13
+ * software distributed under the License is distributed on an
14
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15
+ * KIND, either express or implied. See the License for the
16
+ * specific language governing permissions and limitations
17
+ * under the License.
18
+ */
19
+ /** Max sessions scanned per query (newest first by lastMessageAt). */
20
+ export const MAX_SESSIONS_SCANNED = 200;
21
+ /**
22
+ * NFC + lowercase canonicalization for substring match. NOT a security
23
+ * boundary — purely for case-insensitive + composed-form matching.
24
+ */
25
+ export function foldForMatch(value) {
26
+ return value.normalize('NFC').toLowerCase();
27
+ }
28
+ /** Stable result classification shared by Desktop navigation and Agent tools. */
29
+ export function threadSearchMatchKind(message) {
30
+ switch (message.type) {
31
+ case 'user':
32
+ return 'user_message';
33
+ case 'assistant':
34
+ return 'assistant_message';
35
+ case 'tool_call':
36
+ return 'tool_intent';
37
+ case 'tool_result':
38
+ return 'tool_result';
39
+ case 'permission_decision':
40
+ case 'token_usage':
41
+ case 'turn_state':
42
+ case 'workhub_coordination':
43
+ case 'system_note':
44
+ throw new Error(`Message type ${message.type} is not searchable`);
45
+ }
46
+ }
@@ -82,11 +82,8 @@
82
82
  "./agent-graph-supervisor-wake": "./dist/agent-graph-supervisor-wake.js",
83
83
  "./session-todo": "./dist/session-todo.js",
84
84
  "./external-session": "./dist/external-session.js",
85
- "./deep-research-run": "./dist/deep-research-run.js",
86
- "./deep-research-client-progress": "./dist/deep-research-client-progress.js",
87
85
  "./daily-review": "./dist/daily-review.js",
88
86
  "./work-board": "./dist/work-board.js",
89
- "./deep-research": "./dist/deep-research.js",
90
87
  "./session-start-mode": "./dist/session-start-mode.js",
91
88
  "./long-term-memory": "./dist/long-term-memory.js",
92
89
  "./local-memory": "./dist/local-memory.js",
@@ -128,7 +125,7 @@
128
125
  "./session-send-projection": "./dist/session-send-projection.js",
129
126
  "./session-name": "./dist/session-name.js",
130
127
  "./recall": "./dist/recall.js",
131
- "./thread-search": "./dist/thread-search.js",
128
+ "./transcript-search": "./dist/transcript-search.js",
132
129
  "./agent-graph-timeline": "./dist/agent-graph-timeline.js",
133
130
  "./agent-swarm": "./dist/agent-swarm.js",
134
131
  "./bot-chat-settings": "./dist/bot-chat-settings.js",
@@ -31,6 +31,7 @@ import { createMcpToolBinding, parseMcpToolBinding } from './tool-binding.js';
31
31
  import { McpToolCallError, normalizeToolCallError } from './tool-call-error.js';
32
32
  import { discoverMcpTools } from './tool-discovery.js';
33
33
  import { McpToolCallPreparer } from './tool-output-validation.js';
34
+ import { mapMcpToolProgress } from './tool-progress.js';
34
35
  import { McpCredentialCoordinator } from './credential-coordinator.js';
35
36
  import { assertTransportSecurity, urlProvenance, } from './transport-security.js';
36
37
  import { McpAuthRequiredError, McpOAuthProvider, } from './oauth.js';
@@ -597,6 +598,26 @@ export class McpClientManager {
597
598
  entry.toolSnapshot.get(toolName)?.binding !== binding)
598
599
  throw new McpToolCallError(serverId, toolName, 'tool binding is stale');
599
600
  };
601
+ const progressListener = options.onProgress ?? options.emitProgress;
602
+ let forwardedProgressTotal;
603
+ let forwardedProgressCurrent = -1;
604
+ const forwardProgress = (progress) => {
605
+ const mapped = mapMcpToolProgress(progress);
606
+ if (!mapped)
607
+ return;
608
+ if ((forwardedProgressTotal !== undefined && mapped.total !== forwardedProgressTotal) ||
609
+ mapped.current <= forwardedProgressCurrent) {
610
+ return;
611
+ }
612
+ forwardedProgressTotal ??= mapped.total;
613
+ forwardedProgressCurrent = mapped.current;
614
+ try {
615
+ progressListener?.(mapped.current, mapped.total);
616
+ }
617
+ catch {
618
+ // Progress is advisory: a listener failure must not fail the tool.
619
+ }
620
+ };
600
621
  try {
601
622
  const originalArguments = requestInteraction ? structuredClone(args) : args;
602
623
  let continuation = {};
@@ -618,6 +639,7 @@ export class McpClientManager {
618
639
  signal,
619
640
  timeout: options.timeoutMs ?? this.timeouts.callToolMs,
620
641
  toolDefinition: structuredClone(preparation.value.definitionForSdk),
642
+ ...(progressListener ? { onprogress: forwardProgress } : {}),
621
643
  ...(requestInteraction ? { allowInputRequired: true } : {}),
622
644
  });
623
645
  refreshInventory();
@@ -51,6 +51,8 @@ export class McpAuthRequiredError extends Error {
51
51
  * redirectToAuthorization. The URL itself is never opened or sent in a
52
52
  * token request. */
53
53
  const BACKGROUND_REDIRECT_URL = 'http://127.0.0.1/maka-mcp-oauth-noninteractive';
54
+ /** Product homepage sent in OAuth dynamic client registration. */
55
+ const MCP_OAUTH_CLIENT_URI = 'https://maka.apache.org/en/';
54
56
  export class McpOAuthProvider {
55
57
  options;
56
58
  /** Present only when an interactive state was supplied — the SDK treats
@@ -68,8 +70,8 @@ export class McpOAuthProvider {
68
70
  get clientMetadata() {
69
71
  return {
70
72
  client_name: this.options.clientName,
71
- client_uri: 'https://github.com/maka-agent/maka-agent',
72
- software_id: 'maka-desktop',
73
+ client_uri: MCP_OAUTH_CLIENT_URI,
74
+ software_id: this.options.clientName,
73
75
  software_version: this.options.clientVersion,
74
76
  redirect_uris: this.options.interactive ? [this.options.interactive.redirectUrl] : [],
75
77
  grant_types: ['authorization_code', 'refresh_token'],
@@ -0,0 +1,45 @@
1
+ /*
2
+ * Licensed to the Apache Software Foundation (ASF) under one
3
+ * or more contributor license agreements. See the NOTICE file
4
+ * distributed with this work for additional information
5
+ * regarding copyright ownership. The ASF licenses this file
6
+ * to you under the Apache License, Version 2.0 (the
7
+ * "License"); you may not use this file except in compliance
8
+ * with the License. You may obtain a copy of the License at
9
+ *
10
+ * http://www.apache.org/licenses/LICENSE-2.0
11
+ *
12
+ * Unless required by applicable law or agreed to in writing,
13
+ * software distributed under the License is distributed on an
14
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15
+ * KIND, either express or implied. See the License for the
16
+ * specific language governing permissions and limitations
17
+ * under the License.
18
+ */
19
+ export const MCP_TOOL_PROGRESS_MAX_TOTAL = 1_024;
20
+ /**
21
+ * Map an SDK `notifications/progress` payload onto the Host progress pair.
22
+ * First slice: only finite step counts that the shared tool-progress codec
23
+ * already accepts. Missing `total`, fractions, and inverted ranges are
24
+ * dropped so a noisy server cannot fail the tool call.
25
+ */
26
+ export function mapMcpToolProgress(value) {
27
+ if (!isRecord(value))
28
+ return undefined;
29
+ const current = value.progress;
30
+ const total = value.total;
31
+ if (typeof current !== 'number' || typeof total !== 'number')
32
+ return undefined;
33
+ if (!Number.isSafeInteger(current) ||
34
+ !Number.isSafeInteger(total) ||
35
+ current < 0 ||
36
+ total < 1 ||
37
+ total > MCP_TOOL_PROGRESS_MAX_TOTAL ||
38
+ current > total) {
39
+ return undefined;
40
+ }
41
+ return { current, total };
42
+ }
43
+ function isRecord(value) {
44
+ return typeof value === 'object' && value !== null && !Array.isArray(value);
45
+ }
@@ -33,7 +33,6 @@ import { openResponsesUrl } from './provider-urls.js';
33
33
  import { createOpenResponsesCompatibilityFinalizer } from './open-responses-compatibility.js';
34
34
  import { resolveModelRuntime, runtimeProviderName, } from './model-runtime.js';
35
35
  import { openAiCodexHeaders } from './subscription-auth.js';
36
- import { CommandCodeCliLanguageModel } from './commandcode-cli-language-model.js';
37
36
  import { createRequestCustomizationFetch } from './request-customization-fetch.js';
38
37
  import { createStreamUsageFallbackFetch } from './stream-usage-fallback-fetch.js';
39
38
  import { withOpenCodeSessionHeader } from './opencode-session-header.js';
@@ -112,13 +111,6 @@ export function getAIModel(input) {
112
111
  }).chat(modelId);
113
112
  case 'cohere':
114
113
  return createCohere({ apiKey, baseURL, fetch: requestFetch })(modelId);
115
- case 'commandcode-cli':
116
- return new CommandCodeCliLanguageModel({
117
- modelId,
118
- apiKey,
119
- apiBase: baseURL,
120
- fetch: requestFetch,
121
- });
122
114
  case 'openai-compatible': {
123
115
  if (adapter.requireBaseUrl && !baseURL) {
124
116
  throw new Error(`${connection.providerType} connection ${connection.slug} requires a base URL`);
@@ -653,14 +645,6 @@ function buildFamilyWire(connection, modelId, level, thinkingOptions, requestedL
653
645
  ? { thinking: { type: 'disabled' } }
654
646
  : {},
655
647
  };
656
- case 'commandcode-cli':
657
- // The CLI wire takes `reasoning_effort` as the CLI's own effort words.
658
- // `max` is one of them (claude-fable-5-1, moonshotai/Kimi-K3, …), so the
659
- // chosen level is forwarded verbatim — rounding it down would silently
660
- // send a weaker request than the user asked for.
661
- return level === undefined || level === 'off'
662
- ? {}
663
- : { 'commandcode-cli': { reasoningEffort: level } };
664
648
  default:
665
649
  return {};
666
650
  }
@@ -103,10 +103,7 @@ async function fetchProviderModelsStrict(connection, apiKey, fetchFn) {
103
103
  return filterDiscoveredModels(models, discovery.filter);
104
104
  }
105
105
  case 'openai':
106
- case 'openai-compatible':
107
- // The CLI transport lists models through the Provider API's `/models`,
108
- // which every plan may read.
109
- case 'commandcode-cli': {
106
+ case 'openai-compatible': {
110
107
  const r = await fetchForConnectionEffect(fetchFn, modelListUrl(baseUrl, discovery.path, discovery.query), {
111
108
  headers: {
112
109
  'content-type': 'application/json',
@@ -114,14 +114,6 @@ function adapterCalls(adapter) {
114
114
  return [{ adapter, wire: 'google-generate', reasoningReplay: { kind: 'none' } }];
115
115
  case 'cohere':
116
116
  return [{ adapter, wire: 'cohere-v2', reasoningReplay: { kind: 'none' } }];
117
- case 'commandcode-cli':
118
- return [
119
- {
120
- adapter,
121
- wire: 'commandcode-cli',
122
- reasoningReplay: { kind: 'openai-chat-plaintext', requestField: 'reasoning' },
123
- },
124
- ];
125
117
  case 'openai-codex':
126
118
  return [
127
119
  {