auxilo-mcp 0.9.27 → 0.9.28
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/mcp-server.js +1 -1
- package/package.json +1 -1
- package/scripts/providers/claude-code.js +13 -0
- package/scripts/providers/index.js +9 -1
- package/scripts/runner.js +20 -9
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.
|
|
201
|
+
{ name: 'auxilo', version: '0.9.28' },
|
|
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.
|
|
3
|
+
"version": "0.9.28",
|
|
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",
|
|
@@ -516,6 +516,10 @@ function wrapperIdentity(wrapper, cliVersion) {
|
|
|
516
516
|
...(observed === null && { identity_unresolved: models.length ? 'ambiguous' : 'missing' }) };
|
|
517
517
|
}
|
|
518
518
|
|
|
519
|
+
// Exact production CLI wording (verified 2026-09-27..10-01). Add another alternative only for
|
|
520
|
+
// another CONFIRMED real CLI message, never a guessed synonym.
|
|
521
|
+
const OAUTH_EXPIRED_PATTERN = /Failed to authenticate:\s*OAuth session expired and could not be refreshed/i;
|
|
522
|
+
|
|
519
523
|
function runCliMode(opts, mode) {
|
|
520
524
|
const spawn = typeof opts.spawnSyncImpl === 'function' ? opts.spawnSyncImpl : spawnSync;
|
|
521
525
|
const bin = typeof opts.claudeBin === 'string' ? opts.claudeBin : resolveClaudeBin(opts);
|
|
@@ -552,6 +556,14 @@ function runCliMode(opts, mode) {
|
|
|
552
556
|
if ((!decoded.wrapper && authPattern.test(stdout)) || authPattern.test(String(res.stderr || ''))) {
|
|
553
557
|
return { ...fail('cli-unauthenticated', authReason), ...(authStatus === 'logged-in' && { authDiscrepancy: true }) };
|
|
554
558
|
}
|
|
559
|
+
// EXT-0806c: an expired, unrefreshable OAuth session exits nonzero with this exact CLI
|
|
560
|
+
// message on either stream. Nonzero exit only, and stdout only when no result wrapper
|
|
561
|
+
// decoded, so a successful run whose own text discusses an auth bug never matches. Like
|
|
562
|
+
// the check above it is a post-spawn outcome: no `refusal`, so it never permits fallback.
|
|
563
|
+
if (Number.isInteger(res.status) && res.status !== 0
|
|
564
|
+
&& ((!decoded.wrapper && OAUTH_EXPIRED_PATTERN.test(stdout)) || OAUTH_EXPIRED_PATTERN.test(String(res.stderr || '')))) {
|
|
565
|
+
return { ...fail('cli-unauthenticated', authReason), ...(authStatus === 'logged-in' && { authDiscrepancy: true }) };
|
|
566
|
+
}
|
|
555
567
|
if (res.status !== 0) return fail('model-error', 'local model exited unsuccessfully');
|
|
556
568
|
if (decoded.malformed) return fail('model-error', mode === 'judge' ? 'local judge returned malformed JSON wrapper' : 'local model returned malformed JSON wrapper');
|
|
557
569
|
if (decoded.unsuccessful) return fail('model-error', 'local model returned no successful result');
|
|
@@ -676,4 +688,5 @@ module.exports = {
|
|
|
676
688
|
getClaudeCliVersion,
|
|
677
689
|
looksLikeUnsupportedSettingSourcesFlag,
|
|
678
690
|
_resetSettingSourcesCacheForTests,
|
|
691
|
+
OAUTH_EXPIRED_PATTERN,
|
|
679
692
|
};
|
|
@@ -366,6 +366,7 @@ async function runModel(opts = {}) {
|
|
|
366
366
|
const order = [record.route, ...AUTOMATIC_PROVIDER_ORDER.filter(id =>
|
|
367
367
|
(id !== record.route || record.route === 'byo-key') && (id !== 'byo-key' || configuredByo))];
|
|
368
368
|
const attempts = [];
|
|
369
|
+
let firstFailure = null;
|
|
369
370
|
for (const id of order) {
|
|
370
371
|
if (id !== store.record.route) {
|
|
371
372
|
const updated = store.mutate(routeMetadata(id, opts, 'auto'));
|
|
@@ -394,6 +395,7 @@ async function runModel(opts = {}) {
|
|
|
394
395
|
if (standalone) result = { ...result, ...finishJob(context) };
|
|
395
396
|
return result;
|
|
396
397
|
}
|
|
398
|
+
if (!attempts.length) firstFailure = result;
|
|
397
399
|
attempts.push(id + '=' + (NON_RETRYABLE_FOR_THIS_PROVIDER.has(result.reasonCode) ? result.reasonCode : 'unavailable'));
|
|
398
400
|
if (result.refusal !== 'pre-invocation' || !store.canFallback()) {
|
|
399
401
|
const release = store.hold('pinned-route-unusable');
|
|
@@ -405,7 +407,13 @@ async function runModel(opts = {}) {
|
|
|
405
407
|
const released = store.hold('pinned-route-unusable');
|
|
406
408
|
context.hold = released.hold || 'pinned-route-unusable';
|
|
407
409
|
if (!configuredByo && !attempts.some(attempt => attempt.startsWith('byo-key='))) attempts.push('byo-key=provider-not-configured');
|
|
408
|
-
|
|
410
|
+
// EXT-0806c: a generic 'no-usable-provider' reads as UNKNOWN downstream and never alerts. When the
|
|
411
|
+
// first-choice provider was refused for an unauthenticated CLI, the chain already knows the
|
|
412
|
+
// actionable cause, so surface it; the attempts list stays in `reason`. Read from the first
|
|
413
|
+
// attempt's result object, never from the attempts strings.
|
|
414
|
+
const unauthenticated = Boolean(firstFailure) && firstFailure.reasonCode === 'cli-unauthenticated';
|
|
415
|
+
return { ok: false, text: '', usage: null, authStatus: unauthenticated ? 'logged-out' : 'unknown',
|
|
416
|
+
reasonCode: unauthenticated ? 'cli-unauthenticated' : 'no-usable-provider',
|
|
409
417
|
reason: 'no usable extraction provider (tried: ' + attempts.join('; ') + ')', hold: context.hold };
|
|
410
418
|
}
|
|
411
419
|
|
package/scripts/runner.js
CHANGED
|
@@ -364,10 +364,11 @@ async function finalizeExtractionRun(outcomes, opts = {}) {
|
|
|
364
364
|
: loadExtractionSkipState(opts);
|
|
365
365
|
if (rows.length === 0) return state;
|
|
366
366
|
|
|
367
|
-
//
|
|
368
|
-
//
|
|
369
|
-
|
|
370
|
-
|
|
367
|
+
// Only a completed real extraction (a row that is not a skipped extraction)
|
|
368
|
+
// resets both visibility streaks. A 'model-error' skip is counted as an
|
|
369
|
+
// unknown skip, never a reset: an expired-OAuth outage once classified as
|
|
370
|
+
// model-error reset its own alarm on every sweep (EXT-0806c).
|
|
371
|
+
const resetsAuthStreak = rows.some((row) => !isSkippedExtraction(row));
|
|
371
372
|
if (resetsAuthStreak) {
|
|
372
373
|
const reset = {
|
|
373
374
|
...zeroExtractionSkipState(),
|
|
@@ -383,8 +384,7 @@ async function finalizeExtractionRun(outcomes, opts = {}) {
|
|
|
383
384
|
const hasUnauthenticated = rows.some((row) => isSkippedExtraction(row)
|
|
384
385
|
&& row.reasonCode === 'cli-unauthenticated');
|
|
385
386
|
if (!hasUnauthenticated) {
|
|
386
|
-
const hasUnknown = rows.some((row) => isSkippedExtraction(row)
|
|
387
|
-
&& row.reasonCode !== 'model-error');
|
|
387
|
+
const hasUnknown = rows.some((row) => isSkippedExtraction(row));
|
|
388
388
|
if (!hasUnknown) return state;
|
|
389
389
|
const unknown = {
|
|
390
390
|
...state,
|
|
@@ -1066,6 +1066,8 @@ function installDigest() {
|
|
|
1066
1066
|
|
|
1067
1067
|
// ─── Status (B14) ───────────────────────────────────────────────────────────
|
|
1068
1068
|
|
|
1069
|
+
const EXTRACTION_STALE_MS = 48 * 60 * 60 * 1000;
|
|
1070
|
+
|
|
1069
1071
|
function renderExtractionStatus(opts = {}) {
|
|
1070
1072
|
const state = normalizeExtractionSkipState(opts.state) || zeroExtractionSkipState();
|
|
1071
1073
|
const ledger = opts.ledger && typeof opts.ledger === 'object' ? opts.ledger : {};
|
|
@@ -1086,19 +1088,28 @@ function renderExtractionStatus(opts = {}) {
|
|
|
1086
1088
|
|
|
1087
1089
|
const timestamp = ledger.lastRealExtractionAt;
|
|
1088
1090
|
if (typeof timestamp === 'string' && isCanonicalIsoTimestamp(timestamp)) {
|
|
1091
|
+
const rawNow = typeof opts.now === 'function' ? opts.now() : opts.now;
|
|
1092
|
+
const nowMs = rawNow === undefined ? Date.now()
|
|
1093
|
+
: rawNow instanceof Date ? rawNow.getTime()
|
|
1094
|
+
: typeof rawNow === 'string' ? Date.parse(rawNow) : Number(rawNow);
|
|
1095
|
+
const ageMs = nowMs - Date.parse(timestamp);
|
|
1096
|
+
if (Number.isFinite(ageMs) && ageMs > EXTRACTION_STALE_MS) {
|
|
1097
|
+
return `Extraction: STALE (no real extraction for ${Math.floor(ageMs / 3600000)}h, last ${timestamp}). ` +
|
|
1098
|
+
'Run `claude auth login` and check extract.log';
|
|
1099
|
+
}
|
|
1089
1100
|
return `Extraction: OK (last real extraction ${timestamp})`;
|
|
1090
1101
|
}
|
|
1091
1102
|
return 'Extraction: OK (last real extraction unavailable)';
|
|
1092
1103
|
}
|
|
1093
1104
|
|
|
1094
|
-
function currentExtractionStatusLine(ledger) {
|
|
1105
|
+
function currentExtractionStatusLine(ledger, now) {
|
|
1095
1106
|
const state = loadExtractionSkipState();
|
|
1096
1107
|
let authStatus = 'unknown';
|
|
1097
1108
|
try {
|
|
1098
1109
|
const { checkClaudeAuthStatus } = require('./extract-local.js');
|
|
1099
1110
|
authStatus = checkClaudeAuthStatus();
|
|
1100
1111
|
} catch { /* missing/broken local CLI state is UNKNOWN, never authenticated */ }
|
|
1101
|
-
return renderExtractionStatus({ state, ledger, authStatus });
|
|
1112
|
+
return renderExtractionStatus({ state, ledger, authStatus, now });
|
|
1102
1113
|
}
|
|
1103
1114
|
|
|
1104
1115
|
async function printStatus() {
|
|
@@ -1146,7 +1157,7 @@ async function printStatus() {
|
|
|
1146
1157
|
console.log(`Pending queue: ${pendingCount} file(s)`);
|
|
1147
1158
|
|
|
1148
1159
|
// 7. Extraction health — durable skip state plus the authoritative CLI auth probe.
|
|
1149
|
-
console.log(currentExtractionStatusLine(ledger));
|
|
1160
|
+
console.log(currentExtractionStatusLine(ledger, Date.now()));
|
|
1150
1161
|
}
|
|
1151
1162
|
|
|
1152
1163
|
// ─── Scrub + Verify ─────────────────────────────────────────────────────────
|