akm-cli 0.9.0-beta.47 → 0.9.0-beta.49

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.
@@ -1,26 +1,10 @@
1
1
  // This Source Code Form is subject to the terms of the Mozilla Public
2
2
  // License, v. 2.0. If a copy of the MPL was not distributed with this
3
3
  // file, You can obtain one at https://mozilla.org/MPL/2.0/.
4
- /**
5
- * Internal entry point for the `agent` integration. CLI-only project — no
6
- * public exports map. Other akm modules import from this barrel for the
7
- * sake of grouping imports.
8
- *
9
- * Surface:
10
- * • Types: AgentProfile, AgentConfig, AgentRunResult, AgentFailureReason.
11
- * • Profiles: getBuiltinAgentProfile, listBuiltinAgentProfiles, BUILTIN_AGENT_PROFILE_NAMES.
12
- * • Config: parseAgentConfig, resolveProfileFromConfig, requireAgentProfile, listResolvedAgentProfiles, listAgentProfileNames.
13
- * • Spawn: runAgent. Builders: getCommandBuilder, AgentCommandBuilder, AgentDispatchRequest — platform-specific argv construction.
14
- * • Detection: detectAgentCliProfiles, pickDefaultAgentProfile, defaultWhich.
15
- */
16
- // The OpenCode SDK runner moved to its harness directory in #564
17
- // (`harnesses/opencode-sdk/`). Re-exported here so existing `agent/index`
18
- // import sites keep working.
19
- export { runAgentSdk } from "../harnesses/opencode-sdk/index.js";
20
4
  export { getCommandBuilder } from "./builders.js";
21
- export { DEFAULT_AGENT_TIMEOUT_MS, listAgentProfileNames, listResolvedAgentProfiles, parseAgentConfig, requireAgentProfile, resolveAgentProfile, resolveDefaultProfileName, resolveProfileFromConfig, } from "./config.js";
5
+ export { DEFAULT_AGENT_TIMEOUT_MS, listAgentProfileNames, listResolvedAgentProfiles, requireAgentProfile, resolveAgentProfile, resolveDefaultProfileName, resolveProfileFromConfig, } from "./config.js";
22
6
  export { defaultWhich, detectAgentCliProfiles, pickDefaultAgentProfile } from "./detect.js";
23
7
  export { listBuiltinModelAliases, resolveModel } from "./model-aliases.js";
24
8
  export { BUILTIN_AGENT_PROFILE_NAMES, getBuiltinAgentProfile, listBuiltinAgentProfiles, } from "./profiles.js";
25
- export { buildProposePrompt, buildReflectPrompt, buildSchemaRepairPrompt, extractDraftConfidence, parseAgentProposalPayload, stripJsonFences, } from "./prompts.js";
9
+ export { buildProposePrompt, buildReflectPrompt, buildSchemaRepairPrompt, extractDraftConfidence, parseAgentProposalPayload, } from "./prompts.js";
26
10
  export { runAgent } from "./spawn.js";
@@ -444,11 +444,3 @@ export function parseAgentProposalPayload(stdout) {
444
444
  }
445
445
  return out;
446
446
  }
447
- /**
448
- * Strip `\`\`\`json … \`\`\`` fences and `<think>…</think>` reasoning blocks
449
- * from agent output. Thin wrapper around `core/parse` helpers, kept exported
450
- * for backward compatibility (re-exported from `integrations/agent/index.ts`).
451
- */
452
- export function stripJsonFences(text) {
453
- return stripCodeFences(stripThinkBlocks(text));
454
- }
@@ -60,9 +60,8 @@ const HARNESS_BY_ANY_ID = (() => {
60
60
  })();
61
61
  /**
62
62
  * Canonical, ordered list of valid harness / platform ids. The Zod
63
- * `AgentPlatformSchema` enum, the `AgentProfileConfigV2` platform union,
64
- * `parseAgentProfilesMapV2`'s membership check, and setup's `DetectedHarness`
65
- * union all derive from this so they cannot drift.
63
+ * `AgentPlatformSchema` enum, the `AgentProfileConfig` platform union, and
64
+ * setup's `DetectedHarness` union all derive from this so they cannot drift.
66
65
  */
67
66
  export const VALID_HARNESS_IDS = Object.freeze(HARNESS_REGISTRY.map((h) => h.id));
68
67
  /** Harnesses that expose readable native session logs. */
@@ -5,7 +5,7 @@
5
5
  * OpenCode SDK harness (#564).
6
6
  *
7
7
  * Per-harness barrel for the SDK-mode dispatch path:
8
- * - agent runner → ./sdk-runner.ts (runOpencodeSdk / runAgentSdk)
8
+ * - agent runner → ./sdk-runner.ts (runOpencodeSdk)
9
9
  *
10
10
  * It also defines {@link OpencodeSdkHarness}, the {@link AkmHarness} descriptor
11
11
  * that `HARNESS_REGISTRY` registers.
@@ -17,7 +17,7 @@
17
17
  * names. Canonical id is `'opencode-sdk'` with no alias.
18
18
  */
19
19
  import { BaseHarness } from "../types.js";
20
- export { closeServer, runAgentSdk, runOpencodeSdk } from "./sdk-runner.js";
20
+ export { closeServer, runOpencodeSdk } from "./sdk-runner.js";
21
21
  function caps(c) {
22
22
  return {
23
23
  sessionLogs: false,
@@ -230,5 +230,3 @@ export async function runOpencodeSdk(profile, prompt, opts = {}, llmConfig) {
230
230
  await client.session.delete({ path: { id: sessionId } }).catch(() => { });
231
231
  }
232
232
  }
233
- /** @deprecated Use {@link runOpencodeSdk} instead. */
234
- export const runAgentSdk = runOpencodeSdk;
@@ -12,10 +12,10 @@
12
12
  * Initialized from `cli.ts` before `runMain`.
13
13
  */
14
14
  import { UsageError } from "../core/errors.js";
15
- export const OUTPUT_FORMATS = ["json", "yaml", "text", "jsonl", "md", "html"];
16
- export const DETAIL_LEVELS = ["brief", "normal", "full"];
17
- export const SHAPE_MODES = ["human", "agent", "summary"];
18
- export function parseOutputFormat(value) {
15
+ const OUTPUT_FORMATS = ["json", "yaml", "text", "jsonl", "md", "html"];
16
+ const DETAIL_LEVELS = ["brief", "normal", "full"];
17
+ const SHAPE_MODES = ["human", "agent", "summary"];
18
+ function parseOutputFormat(value) {
19
19
  if (!value)
20
20
  return undefined;
21
21
  if (OUTPUT_FORMATS.includes(value))
@@ -29,7 +29,7 @@ export function parseDetailLevel(value) {
29
29
  return value;
30
30
  throw new UsageError(`Invalid value for --detail: ${value}. Expected one of: ${DETAIL_LEVELS.join("|")}`, "INVALID_DETAIL_VALUE");
31
31
  }
32
- export function parseShapeMode(value) {
32
+ function parseShapeMode(value) {
33
33
  if (!value)
34
34
  return undefined;
35
35
  if (SHAPE_MODES.includes(value))
@@ -9699,18 +9699,43 @@ function insertProposalIfAbsent(db, proposal, stashDir) {
9699
9699
  const changes = result.changes ?? 0;
9700
9700
  return Number(changes) > 0;
9701
9701
  }
9702
+ function isRetryableBeginError(err) {
9703
+ const msg = (err instanceof Error ? err.message : String(err)).toLowerCase();
9704
+ return msg.includes("within a transaction") || msg.includes("database is locked") || msg.includes("database table is locked");
9705
+ }
9706
+ function sleepSyncMs(ms) {
9707
+ if (ms <= 0)
9708
+ return;
9709
+ Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, ms);
9710
+ }
9702
9711
  function withImmediateTransaction(db, fn) {
9703
- db.exec("BEGIN IMMEDIATE");
9704
- try {
9705
- const result = fn();
9706
- db.exec("COMMIT");
9707
- return result;
9708
- } catch (err) {
9712
+ let lastBeginErr;
9713
+ for (let attempt = 1;attempt <= WITH_IMMEDIATE_TX_MAX_ATTEMPTS; attempt++) {
9709
9714
  try {
9710
- db.exec("ROLLBACK");
9711
- } catch {}
9712
- throw err;
9715
+ db.exec("BEGIN IMMEDIATE");
9716
+ } catch (err) {
9717
+ lastBeginErr = err;
9718
+ if (isRetryableBeginError(err) && attempt < WITH_IMMEDIATE_TX_MAX_ATTEMPTS) {
9719
+ try {
9720
+ db.exec("ROLLBACK");
9721
+ } catch {}
9722
+ sleepSyncMs(2 ** (attempt - 1));
9723
+ continue;
9724
+ }
9725
+ throw err;
9726
+ }
9727
+ try {
9728
+ const result = fn();
9729
+ db.exec("COMMIT");
9730
+ return result;
9731
+ } catch (err) {
9732
+ try {
9733
+ db.exec("ROLLBACK");
9734
+ } catch {}
9735
+ throw err;
9736
+ }
9713
9737
  }
9738
+ throw lastBeginErr;
9714
9739
  }
9715
9740
  function upsertTaskHistory(db, row) {
9716
9741
  db.prepare(`
@@ -10074,6 +10099,7 @@ function upsertBodyEmbeddings(db, entries) {
10074
10099
  }
10075
10100
  })();
10076
10101
  }
10102
+ var WITH_IMMEDIATE_TX_MAX_ATTEMPTS = 5;
10077
10103
  var init_state_db = __esm(() => {
10078
10104
  init_managed_db();
10079
10105
  init_improve_types();
@@ -10327,7 +10353,7 @@ function pruneOldBackups(backupDir) {
10327
10353
  function getConfigLockPath() {
10328
10354
  return path7.join(getConfigDir(), "config.json.lck");
10329
10355
  }
10330
- function sleepSyncMs(ms) {
10356
+ function sleepSyncMs2(ms) {
10331
10357
  sleepSync(ms);
10332
10358
  }
10333
10359
  function acquireConfigLock() {
@@ -10348,7 +10374,7 @@ function acquireConfigLock() {
10348
10374
  continue;
10349
10375
  }
10350
10376
  if (attempt < CONFIG_LOCK_MAX_RETRIES - 1) {
10351
- sleepSyncMs(CONFIG_LOCK_RETRY_DELAY_MS);
10377
+ sleepSyncMs2(CONFIG_LOCK_RETRY_DELAY_MS);
10352
10378
  }
10353
10379
  }
10354
10380
  return () => {};
@@ -11241,9 +11267,7 @@ var init_profiles = __esm(() => {
11241
11267
 
11242
11268
  // src/integrations/agent/config.ts
11243
11269
  var init_config = __esm(() => {
11244
- init_config2();
11245
11270
  init_errors();
11246
- init_warn();
11247
11271
  init_profiles();
11248
11272
  });
11249
11273
 
@@ -15785,7 +15809,7 @@ var init_config_schema = __esm(() => {
15785
15809
  });
15786
15810
  LlmCapabilitiesSchema = exports_external.object({
15787
15811
  structuredOutput: exports_external.boolean().optional()
15788
- }).strict();
15812
+ }).passthrough();
15789
15813
  LlmConnectionConfigSchema = exports_external.object({
15790
15814
  provider: exports_external.string().optional(),
15791
15815
  endpoint: exports_external.string(),
@@ -15800,13 +15824,13 @@ var init_config_schema = __esm(() => {
15800
15824
  contextLength: positiveInt.optional(),
15801
15825
  judgeModel: exports_external.string().min(1).optional(),
15802
15826
  enableThinking: exports_external.boolean().optional()
15803
- }).strict();
15827
+ }).passthrough();
15804
15828
  LlmProfileConfigSchema = LlmConnectionConfigSchema.extend({
15805
15829
  supportsJsonSchema: exports_external.boolean().optional()
15806
- }).strict();
15830
+ }).passthrough();
15807
15831
  EmbeddingOllamaOptionsSchema = exports_external.object({
15808
15832
  num_ctx: positiveInt.optional()
15809
- }).strict();
15833
+ }).passthrough();
15810
15834
  EmbeddingConnectionConfigSchema = exports_external.object({
15811
15835
  provider: exports_external.string().optional(),
15812
15836
  endpoint: exports_external.string().optional(),
@@ -15819,7 +15843,7 @@ var init_config_schema = __esm(() => {
15819
15843
  chunkSize: positiveInt.optional(),
15820
15844
  contextLength: positiveInt.optional(),
15821
15845
  ollamaOptions: EmbeddingOllamaOptionsSchema.optional()
15822
- }).strict();
15846
+ }).passthrough();
15823
15847
  AgentPlatformSchema = exports_external.enum(VALID_HARNESS_IDS);
15824
15848
  AgentProfileConfigSchema = exports_external.object({
15825
15849
  platform: AgentPlatformSchema,
@@ -15827,7 +15851,7 @@ var init_config_schema = __esm(() => {
15827
15851
  args: exports_external.array(exports_external.string()).optional(),
15828
15852
  workspace: exports_external.string().min(1).optional(),
15829
15853
  model: exports_external.string().min(1).optional()
15830
- }).strict();
15854
+ }).passthrough();
15831
15855
  ImproveProcessConfigSchema = exports_external.object({
15832
15856
  enabled: exports_external.boolean().optional(),
15833
15857
  mode: exports_external.enum(["llm", "agent", "sdk"]).optional(),
@@ -15839,10 +15863,10 @@ var init_config_schema = __esm(() => {
15839
15863
  enabled: exports_external.boolean().optional(),
15840
15864
  cosineThreshold: exports_external.number().min(0).max(1).optional(),
15841
15865
  cosineCandidateLimit: exports_external.number().int().positive().optional()
15842
- }).strict().optional(),
15843
- judgedCache: exports_external.object({ enabled: exports_external.boolean().optional() }).strict().optional(),
15844
- qualityGate: exports_external.object({ enabled: exports_external.boolean().optional() }).strict().optional(),
15845
- contradictionDetection: exports_external.object({ enabled: exports_external.boolean().optional() }).strict().optional(),
15866
+ }).passthrough().optional(),
15867
+ judgedCache: exports_external.object({ enabled: exports_external.boolean().optional() }).passthrough().optional(),
15868
+ qualityGate: exports_external.object({ enabled: exports_external.boolean().optional() }).passthrough().optional(),
15869
+ contradictionDetection: exports_external.object({ enabled: exports_external.boolean().optional() }).passthrough().optional(),
15846
15870
  defaultSince: exports_external.string().min(1).optional(),
15847
15871
  maxTotalChars: positiveInt.optional(),
15848
15872
  minContentChars: exports_external.number().int().min(0).optional(),
@@ -15864,28 +15888,28 @@ var init_config_schema = __esm(() => {
15864
15888
  enabled: exports_external.boolean().optional(),
15865
15889
  staleDays: exports_external.number().int().min(0).optional(),
15866
15890
  demotionFactor: exports_external.number().min(0).max(1).optional()
15867
- }).strict().optional(),
15891
+ }).passthrough().optional(),
15868
15892
  schemaSimilarity: exports_external.object({
15869
15893
  enabled: exports_external.boolean().optional(),
15870
15894
  epsilon: exports_external.number().min(0).max(1).optional(),
15871
15895
  confidencePenalty: exports_external.number().min(0).max(1).optional()
15872
- }).strict().optional(),
15896
+ }).passthrough().optional(),
15873
15897
  hotProbation: exports_external.object({
15874
15898
  enabled: exports_external.boolean().optional()
15875
- }).strict().optional(),
15899
+ }).passthrough().optional(),
15876
15900
  antiCollapse: exports_external.object({
15877
15901
  enabled: exports_external.boolean().optional(),
15878
15902
  maxGeneration: exports_external.number().int().min(1).optional(),
15879
15903
  lexicalDiversityCheck: exports_external.boolean().optional(),
15880
15904
  randomClusterFraction: exports_external.number().min(0).max(1).optional()
15881
- }).strict().optional(),
15905
+ }).passthrough().optional(),
15882
15906
  cls: exports_external.object({
15883
15907
  enabled: exports_external.boolean().optional(),
15884
15908
  adjacentCount: exports_external.number().int().min(1).optional()
15885
- }).strict().optional(),
15909
+ }).passthrough().optional(),
15886
15910
  fidelityCheck: exports_external.object({
15887
15911
  enabled: exports_external.boolean().optional()
15888
- }).strict().optional(),
15912
+ }).passthrough().optional(),
15889
15913
  minClusterSize: exports_external.number().int().min(2).optional(),
15890
15914
  maxClustersPerRun: positiveInt.optional(),
15891
15915
  maxClusterSize: positiveInt.optional(),
@@ -15896,7 +15920,7 @@ var init_config_schema = __esm(() => {
15896
15920
  minRecurrence: exports_external.number().int().min(2).optional(),
15897
15921
  maxProposalsPerRun: positiveInt.optional(),
15898
15922
  emitAs: exports_external.enum(["workflow", "skill"]).optional(),
15899
- lowValueFilter: exports_external.object({ enabled: exports_external.boolean().optional() }).strict().optional(),
15923
+ lowValueFilter: exports_external.object({ enabled: exports_external.boolean().optional() }).passthrough().optional(),
15900
15924
  proceduralAwareFloor: exports_external.boolean().optional(),
15901
15925
  applyMode: exports_external.enum(["queue", "promote"]).optional(),
15902
15926
  policy: exports_external.string().min(1).optional(),
@@ -15907,8 +15931,8 @@ var init_config_schema = __esm(() => {
15907
15931
  mode: exports_external.enum(["llm", "agent", "sdk"]).optional(),
15908
15932
  profile: exports_external.string().min(1).optional(),
15909
15933
  timeoutMs: exports_external.union([positiveInt, exports_external.null()]).optional()
15910
- }).strict().optional()
15911
- }).strict();
15934
+ }).passthrough().optional()
15935
+ }).passthrough();
15912
15936
  ImproveProfileProcessesSchema = exports_external.object({
15913
15937
  reflect: ImproveProcessConfigSchema.optional(),
15914
15938
  distill: ImproveProcessConfigSchema.optional(),
@@ -15921,35 +15945,11 @@ var init_config_schema = __esm(() => {
15921
15945
  recombine: ImproveProcessConfigSchema.optional(),
15922
15946
  procedural: ImproveProcessConfigSchema.optional()
15923
15947
  }).passthrough().superRefine((val, ctx) => {
15924
- const raw = val;
15925
- if ("feedbackDistillation" in raw) {
15948
+ if ("feedbackDistillation" in val) {
15926
15949
  ctx.addIssue({
15927
15950
  code: exports_external.ZodIssueCode.custom,
15928
15951
  message: "feedbackDistillation was removed in 0.8.0 \u2014 use processes.distill.enabled instead. " + "It now controls both the orchestration gate and the LLM-call gate."
15929
15952
  });
15930
- return;
15931
- }
15932
- const allowed = new Set([
15933
- "reflect",
15934
- "distill",
15935
- "consolidate",
15936
- "memoryInference",
15937
- "graphExtraction",
15938
- "validation",
15939
- "extract",
15940
- "triage",
15941
- "proactiveMaintenance",
15942
- "recombine",
15943
- "procedural"
15944
- ]);
15945
- for (const k of Object.keys(raw)) {
15946
- if (!allowed.has(k)) {
15947
- ctx.addIssue({
15948
- code: exports_external.ZodIssueCode.unrecognized_keys,
15949
- keys: [k],
15950
- message: `Unrecognized improve process key: "${k}".`
15951
- });
15952
- }
15953
15953
  }
15954
15954
  });
15955
15955
  ImproveProfileConfigSchema = exports_external.object({
@@ -15963,18 +15963,18 @@ var init_config_schema = __esm(() => {
15963
15963
  enabled: exports_external.boolean().optional(),
15964
15964
  push: exports_external.boolean().optional(),
15965
15965
  message: exports_external.string().min(1).optional()
15966
- }).strict().optional()
15967
- }).strict();
15966
+ }).passthrough().optional()
15967
+ }).passthrough();
15968
15968
  ProfilesSchema = exports_external.object({
15969
15969
  llm: exports_external.record(exports_external.string(), LlmProfileConfigSchema).optional(),
15970
15970
  agent: exports_external.record(exports_external.string(), AgentProfileConfigSchema).optional(),
15971
15971
  improve: exports_external.record(exports_external.string(), ImproveProfileConfigSchema).optional()
15972
- }).strict();
15972
+ }).passthrough();
15973
15973
  DefaultsSchema = exports_external.object({
15974
15974
  llm: exports_external.string().min(1).optional(),
15975
15975
  agent: exports_external.string().min(1).optional(),
15976
15976
  improve: exports_external.string().min(1).optional()
15977
- }).strict();
15977
+ }).passthrough();
15978
15978
  SourceConfigEntryOptionsSchema = exports_external.object({
15979
15979
  pushOnCommit: exports_external.boolean().optional()
15980
15980
  }).passthrough();
@@ -15988,7 +15988,7 @@ var init_config_schema = __esm(() => {
15988
15988
  primary: exports_external.boolean().optional(),
15989
15989
  options: SourceConfigEntryOptionsSchema.optional(),
15990
15990
  wikiName: exports_external.string().min(1).optional()
15991
- }).strict().superRefine((entry, ctx) => {
15991
+ }).passthrough().superRefine((entry, ctx) => {
15992
15992
  if (entry.writable === true && (entry.type === "website" || entry.type === "npm")) {
15993
15993
  ctx.addIssue({
15994
15994
  code: exports_external.ZodIssueCode.custom,
@@ -16002,7 +16002,7 @@ var init_config_schema = __esm(() => {
16002
16002
  enabled: exports_external.boolean().optional(),
16003
16003
  provider: exports_external.string().min(1).optional(),
16004
16004
  options: exports_external.record(exports_external.unknown()).optional()
16005
- }).strict();
16005
+ }).passthrough();
16006
16006
  KitSourceSchema = exports_external.enum(["filesystem", "git", "npm", "github", "website", "local"]);
16007
16007
  InstalledStashEntrySchema = exports_external.object({
16008
16008
  id: nonEmptyString,
@@ -16016,7 +16016,7 @@ var init_config_schema = __esm(() => {
16016
16016
  resolvedVersion: exports_external.string().min(1).optional(),
16017
16017
  resolvedRevision: exports_external.string().min(1).optional(),
16018
16018
  wikiName: exports_external.string().min(1).optional()
16019
- }).strict().superRefine((entry, ctx) => {
16019
+ }).passthrough().superRefine((entry, ctx) => {
16020
16020
  if (entry.writable === true && entry.source !== "git" && entry.source !== "filesystem") {
16021
16021
  ctx.addIssue({
16022
16022
  code: exports_external.ZodIssueCode.custom,
@@ -16027,7 +16027,7 @@ var init_config_schema = __esm(() => {
16027
16027
  OutputConfigSchema = exports_external.object({
16028
16028
  format: exports_external.enum(["json", "yaml", "text"]).optional(),
16029
16029
  detail: exports_external.enum(["brief", "normal", "full"]).optional()
16030
- }).strict();
16030
+ }).passthrough();
16031
16031
  SearchGraphBoostSchema = exports_external.object({
16032
16032
  directBoostPerEntity: nonNegativeNumber.optional(),
16033
16033
  directBoostCap: nonNegativeNumber.optional(),
@@ -16036,21 +16036,21 @@ var init_config_schema = __esm(() => {
16036
16036
  maxHops: positiveInt.max(3).optional(),
16037
16037
  confidenceMode: exports_external.enum(["off", "blend", "multiply"]).default("blend").optional(),
16038
16038
  confidenceWeight: exports_external.number().finite().min(0).max(1).default(0.2).optional()
16039
- }).strict();
16039
+ }).passthrough();
16040
16040
  SearchConfigSchema = exports_external.object({
16041
16041
  minScore: nonNegativeNumber.optional(),
16042
16042
  defaultExcludeTypes: exports_external.array(nonEmptyString).optional(),
16043
- curateRerank: exports_external.object({ enabled: exports_external.boolean().optional() }).strict().optional(),
16043
+ curateRerank: exports_external.object({ enabled: exports_external.boolean().optional() }).passthrough().optional(),
16044
16044
  graphBoost: SearchGraphBoostSchema.optional()
16045
- }).strict();
16045
+ }).passthrough();
16046
16046
  FeedbackConfigSchema = exports_external.object({
16047
16047
  requireReason: exports_external.boolean().optional(),
16048
16048
  allowedFailureModes: exports_external.array(nonEmptyString).optional()
16049
- }).strict();
16049
+ }).passthrough();
16050
16050
  ImproveUtilityDecaySchema = exports_external.object({
16051
16051
  halfLifeDays: exports_external.number().finite().min(0.1).optional(),
16052
16052
  feedbackStabilityBoost: exports_external.number().finite().min(1).optional()
16053
- }).strict();
16053
+ }).passthrough();
16054
16054
  ImproveCalibrationSchema = exports_external.object({
16055
16055
  autoTune: exports_external.boolean().optional(),
16056
16056
  minThreshold: exports_external.number().int().min(0).max(100).optional(),
@@ -16058,23 +16058,23 @@ var init_config_schema = __esm(() => {
16058
16058
  maxStep: positiveInt.optional(),
16059
16059
  minSamples: nonNegativeNumber.optional(),
16060
16060
  targetAcceptRate: exports_external.number().finite().min(0).max(1).optional()
16061
- }).strict();
16061
+ }).passthrough();
16062
16062
  ImproveExplorationSchema = exports_external.object({
16063
16063
  enabled: exports_external.boolean().optional(),
16064
16064
  budgetFraction: exports_external.number().finite().min(0).max(1).optional()
16065
- }).strict();
16065
+ }).passthrough();
16066
16066
  ImproveSalienceSchema = exports_external.object({
16067
16067
  outcomeWeightEnabled: exports_external.boolean().optional(),
16068
16068
  salienceThreshold: exports_external.number().min(0).max(1).optional(),
16069
16069
  replayBudget: exports_external.number().int().min(0).optional()
16070
- }).strict();
16070
+ }).passthrough();
16071
16071
  ImproveConfigSchema = exports_external.object({
16072
16072
  utilityDecay: ImproveUtilityDecaySchema.optional(),
16073
16073
  eventRetentionDays: nonNegativeNumber.optional(),
16074
16074
  calibration: ImproveCalibrationSchema.optional(),
16075
16075
  exploration: ImproveExplorationSchema.optional(),
16076
16076
  salience: ImproveSalienceSchema.optional()
16077
- }).strict();
16077
+ }).passthrough();
16078
16078
  GRAPH_EXTRACTION_INCLUDE_TYPES_ALLOWED = [
16079
16079
  "memory",
16080
16080
  "knowledge",
@@ -16140,11 +16140,11 @@ var init_config_schema = __esm(() => {
16140
16140
  memoryInferenceBatchSize: positiveInt.optional(),
16141
16141
  lazyGraphExtraction: exports_external.boolean().optional()
16142
16142
  }).passthrough());
16143
- MetadataEnhanceSchema = exports_external.object({ enabled: exports_external.boolean().optional() }).strict();
16143
+ MetadataEnhanceSchema = exports_external.object({ enabled: exports_external.boolean().optional() }).passthrough();
16144
16144
  StalenessDetectionSchema = exports_external.object({
16145
16145
  enabled: exports_external.boolean().optional(),
16146
16146
  thresholdDays: positiveInt.optional()
16147
- }).strict();
16147
+ }).passthrough();
16148
16148
  IndexConfigSchema = exports_external.preprocess((raw, ctx) => {
16149
16149
  if (raw === undefined || raw === null)
16150
16150
  return raw;
@@ -16190,10 +16190,10 @@ var init_config_schema = __esm(() => {
16190
16190
  SetupTaskSchedulesSchema = exports_external.object({
16191
16191
  improve: exports_external.string().min(1).optional(),
16192
16192
  index: exports_external.string().min(1).optional()
16193
- }).strict();
16193
+ }).passthrough();
16194
16194
  SetupConfigSchema = exports_external.object({
16195
16195
  taskSchedules: SetupTaskSchedulesSchema.optional()
16196
- }).strict();
16196
+ }).passthrough();
16197
16197
  AkmConfigShape = {
16198
16198
  configVersion: exports_external.union([exports_external.string().min(1), exports_external.number()]).optional(),
16199
16199
  profiles: ProfilesSchema.optional(),
@@ -16214,7 +16214,7 @@ var init_config_schema = __esm(() => {
16214
16214
  improve: ImproveConfigSchema.optional(),
16215
16215
  setup: SetupConfigSchema.optional()
16216
16216
  };
16217
- AkmConfigBaseSchema = exports_external.object(AkmConfigShape).strict();
16217
+ AkmConfigBaseSchema = exports_external.object(AkmConfigShape).passthrough();
16218
16218
  AkmConfigSchema = AkmConfigBaseSchema.superRefine((config, ctx) => {
16219
16219
  if (config.defaultWriteTarget !== undefined) {
16220
16220
  const knownNames = (config.sources ?? []).map((s) => s.name).filter((n) => typeof n === "string" && n.length > 0);
@@ -4,6 +4,21 @@
4
4
  import { fetchWithRetry } from "../../core/common.js";
5
5
  const YOUTUBE_HOSTS = new Set(["www.youtube.com", "youtube.com", "m.youtube.com", "youtu.be"]);
6
6
  const WATCH_HOST = "https://www.youtube.com/watch?v=";
7
+ // Captions: the WEB watch-page caption baseUrls are now Proof-of-Origin-Token
8
+ // gated (they carry `exp=xpe` and return an empty body without a `pot` token).
9
+ // The ANDROID InnerTube `player` client still returns UNGATED caption baseUrls
10
+ // that serve the transcript, so captions are sourced from there. See
11
+ // https://github.com/yt-dlp/yt-dlp/issues/13075.
12
+ const INNERTUBE_PLAYER_URL = "https://www.youtube.com/youtubei/v1/player";
13
+ // Long-stable public InnerTube key; only authorizes the player call (not auth).
14
+ const DEFAULT_INNERTUBE_KEY = "AIzaSyAO_FJ2SlqU8Q4STEHLGCilw_Y9_11qcW8";
15
+ const ANDROID_INNERTUBE_CLIENT = {
16
+ clientName: "ANDROID",
17
+ clientVersion: "20.10.38",
18
+ androidSdkVersion: 34,
19
+ hl: "en",
20
+ gl: "US",
21
+ };
7
22
  function extractVideoId(url) {
8
23
  if (!YOUTUBE_HOSTS.has(url.hostname))
9
24
  return null;
@@ -129,13 +144,45 @@ async function fetchText(url, timeoutMs, signal) {
129
144
  return response.text();
130
145
  }
131
146
  function parseTranscript(xml) {
132
- const texts = [...xml.matchAll(/<text\b[^>]*>([\s\S]*?)<\/text>/g)]
133
- .map((match) => decodeEntities(stripTags(match[1] ?? "")).trim())
134
- .filter(Boolean);
147
+ // Two timedtext shapes: legacy srv1 `<text>` cues, and the format-3
148
+ // `<timedtext format="3">` `<p>` cues that the ANDROID InnerTube caption
149
+ // URLs return. Strip any nested `<s>` word tags via stripTags.
150
+ const matches = [...xml.matchAll(/<text\b[^>]*>([\s\S]*?)<\/text>/g), ...xml.matchAll(/<p\b[^>]*>([\s\S]*?)<\/p>/g)];
151
+ const texts = matches.map((match) => decodeEntities(stripTags(match[1] ?? "")).trim()).filter(Boolean);
135
152
  if (texts.length === 0)
136
153
  return null;
137
154
  return texts.join("\n");
138
155
  }
156
+ /**
157
+ * Fetch caption tracks via the ANDROID InnerTube `player` endpoint, whose
158
+ * caption baseUrls are not POT-gated. Returns [] on any failure so the caller
159
+ * can fall back to the (usually empty) watch-page tracks and degrade to a
160
+ * description-only snapshot.
161
+ */
162
+ async function fetchInnertubeCaptionTracks(videoId, apiKey, timeoutMs, signal) {
163
+ try {
164
+ const response = await fetchWithRetry(`${INNERTUBE_PLAYER_URL}?key=${encodeURIComponent(apiKey)}`, {
165
+ method: "POST",
166
+ headers: {
167
+ "Content-Type": "application/json",
168
+ "User-Agent": "com.google.android.youtube/20.10.38 (Linux; U; Android 14) gzip",
169
+ },
170
+ body: JSON.stringify({ context: { client: ANDROID_INNERTUBE_CLIENT }, videoId }),
171
+ signal,
172
+ }, { timeout: timeoutMs, retries: 1 });
173
+ if (!response.ok)
174
+ return [];
175
+ const json = (await response.json());
176
+ return json.captions?.playerCaptionsTracklistRenderer?.captionTracks ?? [];
177
+ }
178
+ catch {
179
+ return [];
180
+ }
181
+ }
182
+ /** Extract the page's InnerTube API key, falling back to the stable default. */
183
+ function extractInnertubeKey(html) {
184
+ return html.match(/"INNERTUBE_API_KEY":"([^"]+)"/)?.[1] ?? DEFAULT_INNERTUBE_KEY;
185
+ }
139
186
  const youtubeFetcher = {
140
187
  name: "youtube-transcript",
141
188
  matches(url) {
@@ -161,7 +208,14 @@ const youtubeFetcher = {
161
208
  if (description) {
162
209
  sections.push("## Description", "", description);
163
210
  }
164
- const tracks = playerResponse.captions?.playerCaptionsTracklistRenderer?.captionTracks ?? [];
211
+ // Prefer ungated ANDROID InnerTube caption tracks; fall back to the
212
+ // (now usually empty) watch-page tracks so a description-only snapshot
213
+ // still works when InnerTube is unavailable.
214
+ const apiKey = extractInnertubeKey(watchHtml);
215
+ let tracks = await fetchInnertubeCaptionTracks(videoId, apiKey, context.timeoutMs, context.signal);
216
+ if (tracks.length === 0) {
217
+ tracks = playerResponse.captions?.playerCaptionsTracklistRenderer?.captionTracks ?? [];
218
+ }
165
219
  const captionUrl = chooseCaptionTrack(tracks);
166
220
  if (captionUrl) {
167
221
  const transcriptXml = await fetchText(captionUrl, context.timeoutMs, context.signal);
@@ -29,7 +29,7 @@ import fs from "node:fs";
29
29
  import path from "node:path";
30
30
  import { ConfigError } from "../../core/errors.js";
31
31
  import { getTaskLogDir } from "../../core/paths.js";
32
- import { resolveAkmInvocation } from "../resolveAkmBin.js";
32
+ import { resolveAkmInvocation } from "../resolve-akm-bin.js";
33
33
  import { parseSchedule, translateToCron } from "../schedule.js";
34
34
  const BEGIN = (id) => `# akm:task ${id} BEGIN`;
35
35
  const END = (id) => `# akm:task ${id} END`;
@@ -27,7 +27,7 @@ import path from "node:path";
27
27
  import launchdTemplate from "../../assets/backends/launchd-template.xml" with { type: "text" };
28
28
  import { ConfigError } from "../../core/errors.js";
29
29
  import { getTaskLogDir } from "../../core/paths.js";
30
- import { resolveAkmInvocation } from "../resolveAkmBin.js";
30
+ import { resolveAkmInvocation } from "../resolve-akm-bin.js";
31
31
  import { parseSchedule, translateToLaunchd } from "../schedule.js";
32
32
  import { escapeXml, nodeExec, nodeFs } from "./exec-utils.js";
33
33
  export const LAUNCHD_LABEL_PREFIX = "com.akm.task.";
@@ -35,7 +35,7 @@ import path from "node:path";
35
35
  import schtasksTemplate from "../../assets/backends/schtasks-template.xml" with { type: "text" };
36
36
  import { ConfigError } from "../../core/errors.js";
37
37
  import { getTaskLogDir } from "../../core/paths.js";
38
- import { resolveAkmInvocation } from "../resolveAkmBin.js";
38
+ import { resolveAkmInvocation } from "../resolve-akm-bin.js";
39
39
  import { parseSchedule, translateToSchtasks } from "../schedule.js";
40
40
  import { escapeXml, nodeExec, nodeFs } from "./exec-utils.js";
41
41
  export const DEFAULT_FOLDER_PREFIX = "\\akm\\";
@@ -44,8 +44,8 @@ export function resolveAkmInvocation(options = {}) {
44
44
  /**
45
45
  * From the URL of a module inside `src/tasks/` figure out the CLI entry.
46
46
  *
47
- * • dev `…/src/tasks/resolveAkmBin.ts` → `…/src/cli.ts`
48
- * • build `…/dist/tasks/resolveAkmBin.js` → `…/dist/cli.js`
47
+ * • dev `…/src/tasks/resolve-akm-bin.ts` → `…/src/cli.ts`
48
+ * • build `…/dist/tasks/resolve-akm-bin.js` → `…/dist/cli.js`
49
49
  */
50
50
  function resolveCliEntry(moduleUrl) {
51
51
  let modulePath;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "akm-cli",
3
- "version": "0.9.0-beta.47",
3
+ "version": "0.9.0-beta.49",
4
4
  "type": "module",
5
5
  "description": "akm (Agent Knowledge Management) — A package manager for AI agent skills, commands, tools, and knowledge. Works with Claude Code, OpenCode, Cursor, and any AI coding assistant.",
6
6
  "keywords": [