auxilo-mcp 0.9.25 → 0.9.26

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/bin/auxilo-cli.js CHANGED
@@ -167,12 +167,12 @@ const CONSENT_TEXT = `
167
167
  • READS the session transcript on your machine,
168
168
  • SCRUBS it locally (sensitivity filter: API keys, tokens, emails, PII
169
169
  are redacted first),
170
- • EXTRACTS reusable learnings locally through the first model client you
171
- are signed in to (Claude Code, then Codex) or, when neither is
172
- available, a provider key you set yourself. For this step your
173
- scrubbed transcript goes only to that provider, under your own
174
- account with them, and any use is charged to that account, never to
175
- Auxilo. It is never sent to Auxilo, raw or scrubbed.
170
+ • EXTRACTS reusable learnings locally through Claude Code, when you
171
+ are signed in to it, or a provider key you set yourself. For this
172
+ step your scrubbed transcript goes only to that provider, under
173
+ your own account with them, and any use is charged to that
174
+ account, never to Auxilo. It is never sent to Auxilo, raw or
175
+ scrubbed.
176
176
  • UPLOADS only the finished learning drafts (title, body, category,
177
177
  tags, task context, outcome) to Auxilo (${'POST /learn'}). Everything
178
178
  waits in your review queue until you approve it, one learning at a
@@ -645,7 +645,7 @@ const CLI_CLEAN_LANE_CALIBRATED_PROVIDERS = ['claude-code'];
645
645
  * that with two read-only, no-detect sources of TRUTH, in priority order:
646
646
  * (1) AUXILO_EXTRACTION_PROVIDER, if set, is a certain fact about the
647
647
  * current session's config — reading it is not a guess — validated
648
- * against providers.PROVIDER_ORDER exactly as resolveProvider() itself
648
+ * against providers.KNOWN_PROVIDER_IDS exactly as resolveProvider() itself
649
649
  * validates an override, without calling it.
650
650
  * (2) Otherwise, providers.json's `selected` field — the LAST provider a
651
651
  * genuine resolveProvider() full-scan actually chose and persisted
@@ -661,10 +661,10 @@ const CLI_CLEAN_LANE_CALIBRATED_PROVIDERS = ['claude-code'];
661
661
  function lastRecordedProviderResolution() {
662
662
  const override = process.env.AUXILO_EXTRACTION_PROVIDER;
663
663
  if (override) {
664
- if (providers.PROVIDER_ORDER.includes(override)) return { ok: true, id: override };
664
+ if (providers.KNOWN_PROVIDER_IDS.includes(override)) return { ok: true, id: override };
665
665
  return {
666
666
  ok: false,
667
- reason: `AUXILO_EXTRACTION_PROVIDER="${override}" is not a known provider (expected one of: ${providers.PROVIDER_ORDER.join(', ')})`,
667
+ reason: `AUXILO_EXTRACTION_PROVIDER="${override}" is not a known provider (expected one of: ${providers.KNOWN_PROVIDER_IDS.join(', ')})`,
668
668
  };
669
669
  }
670
670
  try {
@@ -709,7 +709,9 @@ function extractionProviderLine(resolution) {
709
709
  * 'no-model-provider-available' (nothing even LOOKED usable at the detect()
710
710
  * stage) — this is the selection-fall-through exhaustion code from
711
711
  * scripts/providers/index.js's runModel(), where every provider in
712
- * PROVIDER_ORDER was actually tried and each failed for its own reason.
712
+ * AUTOMATIC_PROVIDER_ORDER was actually tried and each failed for its own
713
+ * reason. codex-cli remains reachable only through the explicit override,
714
+ * which never enters this fallback walk.
713
715
  */
714
716
  const STATUS_WORTHY_SKIP_REASON_CODES = Object.freeze([
715
717
  'cli-billing-helper-configured',
@@ -1513,7 +1515,7 @@ async function cmdProvider(flags) {
1513
1515
  }
1514
1516
  throw err;
1515
1517
  }
1516
- console.log(`\n✓ Saved to ${written} (mode 0600). This machine will use your own ${vendor} key for extraction when no earlier provider in the order is available.`);
1518
+ console.log(`\n✓ Saved to ${written} (mode 0600). This machine drafts through Claude Code first when you are signed in to it; your ${vendor} key only takes over when Claude Code is not usable, and once it does, it keeps drafting even after Claude Code becomes usable again.`);
1517
1519
  }
1518
1520
 
1519
1521
  // ─── Entry point ────────────────────────────────────────────────────────────
@@ -1575,9 +1577,11 @@ available on your account every subcommand says so and changes nothing.
1575
1577
  learnings keep their 7-day retraction window.`,
1576
1578
  provider: `Usage: auxilo provider <status|set|clear>
1577
1579
 
1578
- Configure a bring-your-own (BYO) model provider key for local extraction —
1579
- used only when no earlier provider in the fixed order (claude-code,
1580
- codex-cli) is available. Auxilo never sees or bills this key.
1580
+ Configure a bring-your-own (BYO) model provider key for local extraction.
1581
+ Claude Code drafts first when you are signed in to it; your key only
1582
+ takes over when Claude Code is not usable, and once it does, it keeps
1583
+ drafting even after Claude Code becomes usable again. Auxilo never sees
1584
+ or bills this key.
1581
1585
 
1582
1586
  status Show the configured vendor and model (never the key itself).
1583
1587
  set Configure a vendor, model, and key. Interactive ONLY: the key is
package/mcp-server.js CHANGED
@@ -198,7 +198,7 @@ async function postBulkChunks(headers, decisions) {
198
198
  }
199
199
 
200
200
  const server = new Server(
201
- { name: 'auxilo', version: '0.9.25' },
201
+ { name: 'auxilo', version: '0.9.26' },
202
202
  {
203
203
  capabilities: { tools: {} },
204
204
  instructions: `You are connected to Auxilo, a knowledge marketplace where AI agents buy and sell operational learnings.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "auxilo-mcp",
3
- "version": "0.9.25",
3
+ "version": "0.9.26",
4
4
  "mcpName": "io.github.silent-architects/auxilo",
5
5
  "description": "MCP server for Auxilo. Your agent stops solving the same problem twice: auto-extracted learnings, free self-unlocks, and earnings when other agents unlock yours.",
6
6
  "main": "mcp-server.js",
@@ -681,13 +681,14 @@ function formatArgvForLog(argv) {
681
681
  * PRE_SPAWN_SKIP_REASON_CODES, so they render finder=skipped, not ran. The
682
682
  * observed defect lines (finder=ran, flags=n/a) come from a DIFFERENT case:
683
683
  * scripts/providers/index.js's runModel() falls through from claude-code to
684
- * the next configured provider (e.g. codex-cli) whenever claude-code's own
685
- * attempt fails with a NON_RETRYABLE_FOR_THIS_PROVIDER reasonCode, and
686
- * returns that OTHER provider's result directly when it stops there. That
687
- * provider's result carries no `argv` field at all (argv is a
688
- * claude-code-only concept), so there is no shipped argv being hidden here —
689
- * 'unknown' remains the correct, honest `hooks` value regardless of which
690
- * provider is named.
684
+ * the next automatic provider (byo-key) whenever claude-code's own attempt
685
+ * fails with a NON_RETRYABLE_FOR_THIS_PROVIDER reasonCode, and returns that
686
+ * OTHER provider's result directly when it stops there. codex-cli is not in
687
+ * that automatic walk; it remains reachable only through the explicit env
688
+ * override, which never falls through. A non-Claude provider's result carries
689
+ * no `argv` field at all (argv is a claude-code-only concept), so there is no
690
+ * shipped argv being hidden here — 'unknown' remains the correct, honest
691
+ * `hooks` value regardless of which provider is named.
691
692
  *
692
693
  * EXTRACTION-MODEL-PROVENANCE (PUNCH-LIST P1) closed the mismatch this
693
694
  * docblock used to describe as a known, deferred gap: a fallthrough
@@ -10,20 +10,22 @@
10
10
  * from ~/.auxilo/providers.json if it is STILL usable (re-verified via its
11
11
  * own detect() every call, never trusted blindly — a stale persisted choice
12
12
  * falls through to a full re-scan rather than failing) → else the first
13
- * provider whose detect() is true, in fixed order (claude-code → codex-cli →
14
- * byo-key) → else ok:false, with a reason naming every provider tried.
13
+ * provider whose detect() is true, in automatic order (claude-code →
14
+ * byo-key) → else ok:false, with a reason naming every automatic provider
15
+ * tried. codex-cli remains available only through the explicit env override.
15
16
  *
16
17
  * runModel(): resolves via resolveProvider(), then actually RUNS it. A
17
18
  * non-override resolution that fails with a reasonCode meaning "this
18
19
  * provider cannot run at all" (NON_RETRYABLE_FOR_THIS_PROVIDER — e.g.
19
20
  * unauthenticated, not installed, a billing helper is configured) falls
20
- * through to the next provider in PROVIDER_ORDER rather than reporting a
21
- * hard failure; a working provider that merely failed once (timeout, model
22
- * error) does not fall through — that is still the builder's chosen
23
- * provider having a bad run, not a reason to switch under them. An explicit
24
- * env override never falls through, honoring the operator's explicit
25
- * choice. Every provider exhausted → reasonCode 'no-usable-provider' with
26
- * every attempt's reason summarized in `reason`.
21
+ * through to the next provider in AUTOMATIC_PROVIDER_ORDER rather than
22
+ * reporting a hard failure; a working provider that merely failed once
23
+ * (timeout, model error) does not fall through — that is still the builder's
24
+ * chosen provider having a bad run, not a reason to switch under them. An
25
+ * explicit env override, including codex-cli, never falls through, honoring
26
+ * the operator's explicit choice. Every automatic provider exhausted →
27
+ * reasonCode 'no-usable-provider' with every attempt's reason summarized in
28
+ * `reason`.
27
29
  *
28
30
  * codex-cli.js and byo-key.js don't exist yet (PART B/C). loadOptionalProvider()
29
31
  * degrades a missing module into a "not installed yet" stub so this file — and
@@ -71,7 +73,8 @@ function loadOptionalProvider(id, modulePath) {
71
73
  const codexCli = loadOptionalProvider('codex-cli', './codex-cli.js');
72
74
  const byoKey = loadOptionalProvider('byo-key', './byo-key.js');
73
75
 
74
- const PROVIDER_ORDER = Object.freeze(['claude-code', 'codex-cli', 'byo-key']);
76
+ const KNOWN_PROVIDER_IDS = Object.freeze(['claude-code', 'codex-cli', 'byo-key']);
77
+ const AUTOMATIC_PROVIDER_ORDER = Object.freeze(['claude-code', 'byo-key']);
75
78
  const PROVIDERS = {
76
79
  'claude-code': claudeCode,
77
80
  'codex-cli': codexCli,
@@ -145,19 +148,16 @@ async function resolveProvider(opts = {}) {
145
148
  if (!Object.prototype.hasOwnProperty.call(PROVIDERS, override)) {
146
149
  return {
147
150
  ok: false,
148
- reason: `AUXILO_EXTRACTION_PROVIDER="${override}" is not a known provider (expected one of: ${PROVIDER_ORDER.join(', ')})`,
151
+ reason: `AUXILO_EXTRACTION_PROVIDER="${override}" is not a known provider (expected one of: ${KNOWN_PROVIDER_IDS.join(', ')})`,
149
152
  };
150
153
  }
151
154
  return { ok: true, id: override, module: PROVIDERS[override] };
152
155
  }
153
156
 
154
- const cache = opts.providerCache || defaultCache;
155
- if (cache.resolved) return cache.resolved;
156
-
157
157
  // Fast path (EXTRACT-PER-CLIENT W1 FIX, PUNCH-LIST P1, item 3): the
158
158
  // persisted `selected` choice — written by a prior successful resolution,
159
159
  // possibly in an earlier process — skips re-probing every provider ahead
160
- // of it in PROVIDER_ORDER when it is STILL usable (the common
160
+ // of it in AUTOMATIC_PROVIDER_ORDER when it is STILL usable (the common
161
161
  // steady-state case: same builder, same login, repeated extraction
162
162
  // calls). "Usable" is re-verified via that provider's own detect() every
163
163
  // time, never trusted blindly from the file alone. A stale persisted
@@ -185,6 +185,26 @@ async function resolveProvider(opts = {}) {
185
185
  const log = typeof opts.log === 'function' ? opts.log : console.error;
186
186
  const statePath = opts.providersStatePath || PROVIDERS_STATE_PATH;
187
187
  const persistedState = readProvidersState(statePath);
188
+
189
+ // EPC2-2 E0: codex-cli failed the live isolation sentinel and is therefore
190
+ // ineligible for automatic selection. Treat a cached pre-E0 winner as
191
+ // absent in memory on EVERY resolution, even if the best-effort migration
192
+ // below cannot rewrite providers.json. The explicit env override above is
193
+ // intentionally untouched and remains the only route to codex-cli.
194
+ if (persistedState.selected === 'codex-cli') {
195
+ delete persistedState.selected;
196
+ try {
197
+ if (typeof byoKey.writeProvidersStateAtomic !== 'function') throw new Error('writer unavailable');
198
+ byoKey.writeProvidersStateAtomic(persistedState, opts);
199
+ } catch {
200
+ log('[providers] could not clear retired automatic codex-cli selection; continuing without it');
201
+ }
202
+ }
203
+
204
+ const cache = opts.providerCache || defaultCache;
205
+ if (cache.resolved && cache.resolved.id !== 'codex-cli') return cache.resolved;
206
+ if (cache.resolved && cache.resolved.id === 'codex-cli') delete cache.resolved;
207
+
188
208
  const persistedId = persistedState.selected;
189
209
  if (typeof persistedId === 'string' && Object.prototype.hasOwnProperty.call(PROVIDERS, persistedId)) {
190
210
  const persistedMod = PROVIDERS[persistedId];
@@ -203,7 +223,7 @@ async function resolveProvider(opts = {}) {
203
223
  }
204
224
 
205
225
  const tried = [];
206
- for (const id of PROVIDER_ORDER) {
226
+ for (const id of AUTOMATIC_PROVIDER_ORDER) {
207
227
  const mod = PROVIDERS[id];
208
228
  tried.push(id);
209
229
  let available = false;
@@ -224,7 +244,7 @@ async function resolveProvider(opts = {}) {
224
244
 
225
245
  /**
226
246
  * reasonCodes meaning "this provider cannot run at all right now" — safe to
227
- * try the NEXT provider in PROVIDER_ORDER rather than reporting a hard
247
+ * try the NEXT provider in AUTOMATIC_PROVIDER_ORDER rather than reporting a hard
228
248
  * failure (EXTRACT-PER-CLIENT W1 FIX, PUNCH-LIST P1, item 2). Everything
229
249
  * else (timeouts, model errors, malformed output, rate limits) means the
230
250
  * chosen provider DID run and failed on THIS call — that is not a signal to
@@ -241,7 +261,8 @@ const NON_RETRYABLE_FOR_THIS_PROVIDER = new Set([
241
261
  // EXTRACTION-CHILD-HOOKS (0.9.15): the resolved claude-code CLI doesn't
242
262
  // support --setting-sources, so it can never run isolated — same
243
263
  // "cannot run at all right now" class as the codes above, safe to try the
244
- // next provider in PROVIDER_ORDER rather than reporting a hard failure.
264
+ // next automatic provider rather than reporting a hard failure. codex-cli
265
+ // remains reachable only through the explicit override, which never walks.
245
266
  'cli-settings-isolation-unsupported',
246
267
  ]);
247
268
 
@@ -288,9 +309,9 @@ function hasUsableIdentity(identity) {
288
309
  * what lets the per-run `[providers]` log name the provider that actually
289
310
  * ran even when that provider's own failure return carries no identity
290
311
  * (codex-cli and byo-key only self-stamp on their SINGLE success return —
291
- * this is the exact fall-through failure case the investigation traced:
292
- * claude-code skipped, codex-cli ran and failed, no identity of its own,
293
- * the label used to be re-guessed as claude-code by the old fallback).
312
+ * the automatic fall-through failure case is now: claude-code skipped,
313
+ * byo-key ran and failed, no identity of its own, and the label must name
314
+ * byo-key rather than be re-guessed as claude-code by the old fallback).
294
315
  * - Every other provider on a SUCCESS: `{provider:'unknown', ...}` —
295
316
  * byo-key.js and codex-cli.js both self-stamp `identity` on their only
296
317
  * success return BY CONTRACT; a success with none means that contract was
@@ -321,10 +342,10 @@ function deriveIdentity(id, result) {
321
342
  * byo-key's real model name). Applied to every result this registry
322
343
  * returns, success or failure, so the per-run `[providers]` log
323
344
  * (scripts/extract-local.js's logProviderRunSummary) names the provider
324
- * that actually ran even on a failure — that is the fall-through failure
325
- * case this row's investigation traced (claude-code skipped, codex-cli ran
326
- * and failed with no identity of its own, the stamp used to be re-guessed
327
- * as claude-code by the caller).
345
+ * that actually ran even on a failure — the automatic fall-through failure
346
+ * case is now claude-code skipped, byo-key ran and failed with no identity
347
+ * of its own, and the stamp must not be re-guessed as claude-code by the
348
+ * caller.
328
349
  */
329
350
  function withIdentity(id, result) {
330
351
  if (hasUsableIdentity(result && result.identity)) return result;
@@ -333,19 +354,20 @@ function withIdentity(id, result) {
333
354
 
334
355
  /**
335
356
  * runModel(opts) — resolve a starting provider via resolveProvider(), then
336
- * walk PROVIDER_ORDER from there, calling each candidate's OWN runModel()
357
+ * walk AUTOMATIC_PROVIDER_ORDER from there, calling each candidate's OWN runModel()
337
358
  * (never a separate detect() pre-check — a provider's runModel() already
338
359
  * performs the equivalent authoritative check internally and returns a
339
360
  * specific, accurate reason, so a second detect() call would only add a
340
361
  * redundant probe without adding information). Falls through to the next
341
362
  * provider when the current one's failure reasonCode is in
342
363
  * NON_RETRYABLE_FOR_THIS_PROVIDER; when resolveProvider itself found no
343
- * usable provider at all, the walk starts at PROVIDER_ORDER's beginning so
344
- * every provider still gets an actual runModel() call and contributes its
345
- * own reason (not just a single generic "no provider available"). An
346
- * explicit AUXILO_EXTRACTION_PROVIDER override never falls through — it is
347
- * the operator's explicit choice, so its own failure reason is reported
348
- * as-is. When every provider tried is exhausted, returns reasonCode
364
+ * usable provider at all, the walk starts at AUTOMATIC_PROVIDER_ORDER's
365
+ * beginning so every automatic provider still gets an actual runModel()
366
+ * call and contributes its own reason (not just a single generic "no
367
+ * provider available"). An explicit AUXILO_EXTRACTION_PROVIDER override,
368
+ * including codex-cli, never falls through — it is the operator's explicit
369
+ * choice, so its own failure reason is reported as-is. When every provider
370
+ * tried is exhausted, returns reasonCode
349
371
  * 'no-usable-provider' with a bounded summary of every provider's reason in
350
372
  * `reason` (no secrets — each provider's own reason string is already
351
373
  * secret-free by contract) and NO identity — nothing actually ran to
@@ -375,8 +397,10 @@ async function runModel(opts = {}) {
375
397
 
376
398
  const log = typeof opts.log === 'function' ? opts.log : console.error;
377
399
  const resolved = await resolveProvider(opts);
378
- const startIdx = resolved.ok ? PROVIDER_ORDER.indexOf(resolved.id) : -1;
379
- const order = startIdx === -1 ? PROVIDER_ORDER.slice() : PROVIDER_ORDER.slice(startIdx);
400
+ const startIdx = resolved.ok ? AUTOMATIC_PROVIDER_ORDER.indexOf(resolved.id) : -1;
401
+ const order = startIdx === -1
402
+ ? AUTOMATIC_PROVIDER_ORDER.slice()
403
+ : AUTOMATIC_PROVIDER_ORDER.slice(startIdx);
380
404
 
381
405
  const attempts = [];
382
406
  for (const id of order) {
@@ -411,7 +435,8 @@ async function runModel(opts = {}) {
411
435
  module.exports = {
412
436
  runModel,
413
437
  resolveProvider,
414
- PROVIDER_ORDER,
438
+ KNOWN_PROVIDER_IDS,
439
+ AUTOMATIC_PROVIDER_ORDER,
415
440
  PROVIDERS_STATE_PATH,
416
441
  NON_RETRYABLE_FOR_THIS_PROVIDER,
417
442
  };