项目文件夹

文件
wehub-resource-sync 23f7624596
ADR-166 MCP Bridge Security Lock / Static-source security lock (push) Failing after 0s
ADR-166 MCP Bridge Security Lock / Compose default binds loopback + Mongo has auth (push) Failing after 2s
CodeQL Advanced / Analyze (rust) (push) Failing after 0s
ADR-166 MCP Bridge Security Lock / plugin-agent-federation bindHost default (push) Failing after 1s
ADR-166 MCP Bridge Security Lock / Runtime behavior — 401 + terminal gate + fail-closed (push) Failing after 4s
business-pods-smoke / smoke (push) Failing after 1s
all-plugins-smoke / smoke-all (push) Failing after 2s
CI/CD Pipeline / Security & Code Quality (push) Failing after 1s
CI/CD Pipeline / Test Suite (ubuntu-latest) (push) Failing after 1s
CI/CD Pipeline / Build & Package (macos-latest) (push) Has been skipped
CI/CD Pipeline / Build & Package (ubuntu-latest) (push) Has been skipped
CI/CD Pipeline / Build & Package (windows-latest) (push) Has been skipped
CI/CD Pipeline / Documentation & Examples (push) Failing after 1s
Clone Tracker (14-day rolling) / Snapshot clones for ruflo ecosystem (push) Failing after 1s
CodeQL Advanced / Analyze (actions) (push) Failing after 1s
CodeQL Advanced / Analyze (javascript-typescript) (push) Failing after 1s
federation-peer-rust / stable-noop (push) Failing after 1s
metaharness-ci / score (push) Failing after 1s
metaharness-ci / router-compat (push) Failing after 0s
metaharness-ci / similarity-tests (push) Failing after 0s
no-agentbbs-smoke / smoke-without-agentbbs (push) Failing after 1s
V3 CI/CD Pipeline / Build V3 (windows-latest) (push) Has been skipped
codex-integration-audit / Codex integration audit (push) Failing after 1s
helpers-manifest-guard / guard (push) Failing after 1s
🔗 Cross-Agent Integration Tests / 🤝 Agent Coordination Tests (push) Has been skipped
🔗 Cross-Agent Integration Tests / 🧠 Memory Sharing Integration (push) Has been skipped
🔗 Cross-Agent Integration Tests / 🛡️ Fault Tolerance Tests (push) Has been skipped
🔗 Cross-Agent Integration Tests / ⚡ Performance Integration Tests (push) Has been skipped
metaharness-ci / mcp-scan (push) Failing after 1s
metaharness-ci / eject-dryrun (push) Failing after 1s
metaharness-ci / metaharness-real-data (push) Failing after 0s
no-cli-optdep-bloat-2561 / guard (push) Failing after 1s
no-metaharness-smoke / smoke-without-metaharness (push) Failing after 1s
no-phantom-agentic-flow-subpath / guard (push) Failing after 1s
🔄 Automated Rollback Manager / 🚨 Failure Detection (push) Failing after 1s
V3 CI/CD Pipeline / Plugin hooks smoke / ubuntu-latest / Node 22 (push) Failing after 1s
V3 CI/CD Pipeline / ruflo-graph-intelligence build + test smoke (#2044, ADR-123) (push) Failing after 1s
CVE Audit Gate / Audit root (critical-blocking) (push) Failing after 2s
cost-tracker-smoke / smoke (push) Failing after 3s
oia-audit-weekly / audit (push) Failing after 2s
ruflo-agent-smoke / ruflo-agent structural smoke (push) Failing after 1s
📊 Status Badges Update / 📊 Update Status Badges (push) Failing after 1s
V3 CI/CD Pipeline / Static regression guards (#2267 YAML + (push) Failing after 1s
V3 CI/CD Pipeline / Test V3 Packages (push) Failing after 0s
V3 CI/CD Pipeline / agent_execute provider routing smoke (#2042) (push) Failing after 0s
CVE Audit Gate / Audit v3 (critical-blocking) (push) Failing after 1s
federation-peer-rust / stable-native (push) Failing after 2s
🔗 Cross-Agent Integration Tests / 🚀 Integration Test Setup (push) Failing after 2s
neural-trader-smoke / runtime-smoke (push) Failing after 1s
V3 CI/CD Pipeline / Build V3 (macos-latest) (push) Has been skipped
V3 CI/CD Pipeline / Build V3 (ubuntu-latest) (push) Has been skipped
V3 CI/CD Pipeline / Type Check V3 (push) Failing after 1s
V3 CI/CD Pipeline / Smoke (no better-sqlite3) / ubuntu-latest / Node 24 (push) Failing after 1s
V3 CI/CD Pipeline / Smoke (no better-sqlite3) / ubuntu-latest / Node 22 (push) Failing after 2s
V3 CI/CD Pipeline / browser rvf create flag smoke (#2015) (push) Failing after 0s
V3 CI/CD Pipeline / Dependency review (#2046) (push) Has been skipped
V3 CI/CD Pipeline / Supply-chain audit (#2046) (push) Failing after 0s
V3 CI/CD Pipeline / witness marker drift smoke (#2021) (push) Failing after 1s
V3 CI/CD Pipeline / neural-trader portfolio CG smoke (#2068, ADR-126 Phase 3) (push) Failing after 1s
V3 CI/CD Pipeline / neural-trader backtest signing smoke (#2068, ADR-126 Phase 4) (push) Failing after 1s
V3 CI/CD Pipeline / kg-extract type-import classification smoke (#2049) (push) Failing after 0s
V3 CI/CD Pipeline / witness verify precondition smoke (#1880) (push) Failing after 2s
V3 CI/CD Pipeline / neural-trader pipeline risk-gate smoke (#2068, ADR-126 Phase 5) (push) Failing after 0s
V3 CI/CD Pipeline / neural-trader feature attribution smoke (#2068, ADR-126 Phase 6) (push) Failing after 0s
V3 CI/CD Pipeline / plugin-registry signature verification smoke (#1922, CWE-347) (push) Failing after 4s
V3 CI/CD Pipeline / memory stats legacy-DB smoke (#2120) (push) Failing after 4s
V3 CI/CD Pipeline / github deprecated actions smoke (#2089, ADR-127 Phase 3) (push) Failing after 1s
V3 CI/CD Pipeline / graph query + pathfinder smoke (ADR-130 P2+P5) (push) Has been skipped
V3 CI/CD Pipeline / graph trajectory hooks smoke (ADR-130 P3) (push) Has been skipped
V3 CI/CD Pipeline / graph plugin adapter smoke (ADR-130 P4) (push) Has been skipped
V3 CI/CD Pipeline / graph benchmark (ADR-130 P6) (push) Has been skipped
V3 CI/CD Pipeline / statusline generator delegation smoke (#2195) (push) Failing after 1s
V3 CI/CD Pipeline / wizard init regression guard (#2206 (push) Failing after 1s
V3 CI/CD Pipeline / memory no-stray-db smoke (ADR-125 P7) (push) Failing after 1s
V3 CI/CD Pipeline / github-safe injection smoke (#2089, ADR-127 Phase 1) (push) Failing after 1s
V3 CI/CD Pipeline / github actions pin smoke (#2089, ADR-127 Phase 1) (push) Failing after 1s
V3 CI/CD Pipeline / github attribution opt-in smoke (#2089, ADR-127 Phase 4) (push) Failing after 1s
V3 CI/CD Pipeline / pre-bash hook safety smoke (#2017) (push) Failing after 1s
V3 CI/CD Pipeline / Memory import smoke / ubuntu-latest (push) Failing after 0s
V3 CI/CD Pipeline / MCP protocol smoke / ubuntu-latest (push) Failing after 2s
V3 CI/CD Pipeline / ruvllm WASM auto-init smoke (#2086) (push) Failing after 4s
V3 CI/CD Pipeline / MCP paired-tool round-trip smoke (#1889) (push) Failing after 1s
V3 CI/CD Pipeline / Plugin package install-safety (#1902/#1903/#1904) (push) Failing after 1s
V3 CI/CD Pipeline / Tool description discoverability (ADR-112) (push) Failing after 3s
V3 CI/CD Pipeline / CLI npx-install smoke (#1147 / (22) (push) Failing after 1s
V3 CI/CD Pipeline / CLI npx-install smoke (#1147 / (24) (push) Failing after 1s
V3 CI/CD Pipeline / Windows hook shim smoke (#2132) / ubuntu-latest (push) Failing after 2s
V3 CI/CD Pipeline / Windows hook execution smoke (#2132) / ubuntu-latest (push) Failing after 1s
V3 CI/CD Pipeline / Windows init hooks smoke (#2132) / ubuntu-latest (push) Failing after 1s
V3 CI/CD Pipeline / Vector-index dimension audit (#1947) (push) Failing after 0s
V3 CI/CD Pipeline / Hook-command install safety (#1921) (push) Failing after 1s
V3 CI/CD Pipeline / ToolOutputGuardrail smoke (ADR-131, (push) Failing after 1s
V3 CI/CD Pipeline / init-bundle invariants smoke (#2095, ADR-128 Phase 5) (push) Failing after 1s
V3 CI/CD Pipeline / wasm provider bridge smoke (ADR-129 P1) (push) Failing after 2s
V3 CI/CD Pipeline / wasm gallery CRUD smoke (ADR-129 P3) (push) Failing after 1s
V3 CI/CD Pipeline / wasm plugin bridge smoke (ADR-129 P4) (push) Failing after 0s
V3 CI/CD Pipeline / wasm compose smoke (ADR-129 P2) (push) Failing after 4s
V3 CI/CD Pipeline / graph schema smoke (ADR-130 P1) (push) Failing after 0s
Validate Marketplace / validate (push) Failing after 1s
🔍 Verification Pipeline / 🚀 Setup Verification (push) Failing after 1s
🔍 Verification Pipeline / 🛡️ Security Verification (push) Has been skipped
🔍 Verification Pipeline / 📝 Code Quality (push) Has been skipped
🔍 Verification Pipeline / 🧪 Test Verification (${{ matrix.os }}, Node ${{ matrix.node }}) (push) Has been skipped
🔍 Verification Pipeline / 🏗️ Build Verification (push) Has been skipped
🔍 Verification Pipeline / 📚 Documentation Verification (push) Has been skipped
CVE Audit Gate / High-severity report (warn only) (push) Has been cancelled
🔄 Automated Rollback Manager / 🔄 Execute Rollback (push) Has been cancelled
🔄 Automated Rollback Manager / ✅ Post-Rollback Verification (push) Has been cancelled
🔄 Automated Rollback Manager / 📊 Rollback Monitoring (push) Has been cancelled
V3 CI/CD Pipeline / Windows init hooks smoke (#2132) / windows-latest (push) Has been cancelled
V3 CI/CD Pipeline / Windows hook execution smoke (#2132) / macos-latest (push) Has been cancelled
V3 CI/CD Pipeline / Windows hook execution smoke (#2132) / windows-latest (push) Has been cancelled
🔄 Automated Rollback Manager / ⏳ Manual Rollback Approval (push) Has been cancelled
V3 CI/CD Pipeline / MCP protocol smoke / macos-latest (push) Has been cancelled
V3 CI/CD Pipeline / Memory import smoke / macos-latest (push) Has been cancelled
V3 CI/CD Pipeline / Windows hook shim smoke (#2132) / macos-latest (push) Has been cancelled
V3 CI/CD Pipeline / Windows hook shim smoke (#2132) / windows-latest (push) Has been cancelled
V3 CI/CD Pipeline / Windows init hooks smoke (#2132) / macos-latest (push) Has been cancelled
V3 CI/CD Pipeline / Witness verify (signed manifest) / macos-latest (push) Has been cancelled
V3 CI/CD Pipeline / Witness verify (signed manifest) / ubuntu-latest (push) Has been cancelled
V3 CI/CD Pipeline / Witness verify (signed manifest) / windows-latest (push) Has been cancelled
V3 CI/CD Pipeline / Publish to npm (alpha) (push) Has been cancelled
V3 CI/CD Pipeline / Smoke (no better-sqlite3) / macos-latest / Node 22 (push) Has been cancelled
V3 CI/CD Pipeline / Plugin hooks smoke / macos-latest / Node 22 (push) Has been cancelled
CI/CD Pipeline / Deploy & Release (push) Has been cancelled
CI/CD Pipeline / CI Status (push) Has been cancelled
🔗 Cross-Agent Integration Tests / 📊 Integration Test Report (push) Has been cancelled
🔄 Automated Rollback Manager / 🔍 Pre-Rollback Validation (push) Has been cancelled
🔍 Verification Pipeline / ⚡ Performance Verification (push) Has been cancelled
🔍 Verification Pipeline / 📊 Verification Report (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 12:02:19 +08:00

226 行
8.6 KiB
JavaScript
可执行文件

此文件含有模棱两可的 Unicode 字符
此文件含有可能会与其他字符混淆的 Unicode 字符。 如果您是想特意这样的,可以安全地忽略该警告。 使用 Escape 按钮显示他们。
#!/usr/bin/env node
// cost-session — per-message cost breakdown for a single session.
//
// cost-anomaly identifies WHICH sessions are outliers ($spend distribution).
// cost-conversation lists ALL sessions and their totals.
// This skill answers: given ONE session (especially an outlier), WHICH
// MESSAGES within it were expensive?
//
// METHOD
// 1. Resolve the session jsonl: `--session-id <id>` or `--latest` (default).
// 2. Parse all assistant messages with `usage` blocks.
// 3. Cost each message via the shared PRICING table (_prices.mjs).
// 4. Sort by cost descending, surface top-N.
// 5. Output: total + per-message breakdown + cost-percentile context.
//
// Pairs with cost-anomaly: when a session is flagged as a >3.5σ outlier,
// `cost session --session-id <flagged-id>` shows the expensive messages.
//
// USAGE
// node scripts/session.mjs # latest session (default --top 20)
// node scripts/session.mjs --session-id <id> # by id (searches all project dirs)
// node scripts/session.mjs --top 10 # show top N
// node scripts/session.mjs --since 2026-06-15 # filter by ISO timestamp
// node scripts/session.mjs --format json
//
// EXIT CODES
// 0 success
// 2 config error or session not found
import { readdirSync, readFileSync, statSync, existsSync } from 'node:fs';
import { join } from 'node:path';
import { homedir } from 'node:os';
// iter 73 — shared PRICING + cost helpers.
import { modelTier, costForUsage } from './_prices.mjs';
const PROJECTS_DIR = join(homedir(), '.claude', 'projects');
const ARGS = (() => {
const a = { sessionId: null, top: 20, since: null, format: 'table' };
if (process.env.SESSION_QUIET === '1') a.format = 'json';
for (let i = 2; i < process.argv.length; i++) {
const v = process.argv[i];
if (v === '--session-id') a.sessionId = process.argv[++i];
else if (v === '--top') a.top = parseInt(process.argv[++i], 10);
else if (v === '--since') a.since = process.argv[++i];
else if (v === '--format') a.format = process.argv[++i];
else if (v === '--latest') a.sessionId = null;
}
return a;
})();
function listAllJsonls() {
if (!existsSync(PROJECTS_DIR)) return [];
const out = [];
for (const proj of readdirSync(PROJECTS_DIR)) {
const projDir = join(PROJECTS_DIR, proj);
let stat;
try { stat = statSync(projDir); } catch { continue; }
if (!stat.isDirectory()) continue;
let entries;
try { entries = readdirSync(projDir); } catch { continue; }
for (const f of entries) {
if (!f.endsWith('.jsonl')) continue;
const path = join(projDir, f);
let st;
try { st = statSync(path); } catch { continue; }
out.push({ path, mtime: st.mtimeMs, project: proj });
}
}
return out;
}
function findSessionJsonl(sessionId) {
const all = listAllJsonls();
if (!sessionId) {
// --latest: pick the most-recently-modified jsonl
if (all.length === 0) return null;
return all.sort((a, b) => b.mtime - a.mtime)[0];
}
// Scan each jsonl for the sessionId. Most jsonls contain a single
// sessionId across all their messages, so reading the first line is
// usually enough — but fall back to a full scan if needed.
for (const f of all) {
let head;
try { head = readFileSync(f.path, 'utf-8').split('\n').slice(0, 5).join('\n'); }
catch { continue; }
if (head.includes(`"sessionId":"${sessionId}"`)) return f;
}
return null;
}
function summarizeMessages(jsonlPath) {
const text = readFileSync(jsonlPath, 'utf-8');
const lines = text.split('\n').filter(Boolean);
const messages = [];
let sinceMs = null;
if (ARGS.since) {
const t = Date.parse(ARGS.since);
if (Number.isFinite(t)) sinceMs = t;
}
for (const line of lines) {
let m;
try { m = JSON.parse(line); } catch { continue; }
if (m.type !== 'assistant' || !m.message?.usage) continue;
if (sinceMs !== null && m.timestamp && new Date(m.timestamp).getTime() < sinceMs) continue;
const model = m.message.model || 'unknown';
const tier = modelTier(model);
const u = m.message.usage;
const cost = costForUsage(tier, u);
messages.push({
timestamp: m.timestamp || null,
model,
tier,
input_tokens: u.input_tokens || 0,
output_tokens: u.output_tokens || 0,
cache_creation_input_tokens: u.cache_creation_input_tokens || 0,
cache_read_input_tokens: u.cache_read_input_tokens || 0,
cost_usd: cost,
});
}
return messages;
}
function main() {
if (!Number.isInteger(ARGS.top) || ARGS.top < 1) {
console.error(`cost-session: --top must be a positive integer; got ${ARGS.top}`);
process.exit(2);
}
const sessionFile = findSessionJsonl(ARGS.sessionId);
if (!sessionFile) {
console.error(`cost-session: ${ARGS.sessionId ? `no session matches id "${ARGS.sessionId}"` : 'no sessions found'}`);
process.exit(2);
}
const messages = summarizeMessages(sessionFile.path);
if (messages.length === 0) {
if (ARGS.format === 'json') {
console.log(JSON.stringify({
sessionFile: sessionFile.path,
sessionId: ARGS.sessionId,
messageCount: 0,
total_cost_usd: 0,
messages: [],
topByMessage: [],
generatedAt: new Date().toISOString(),
}, null, 2));
} else {
console.log(`# cost-session\n\n_No costed assistant messages in \`${sessionFile.path}\`._\n`);
}
return;
}
const total = messages.reduce((s, m) => s + m.cost_usd, 0);
const sorted = messages.slice().sort((a, b) => b.cost_usd - a.cost_usd);
const top = sorted.slice(0, ARGS.top);
// Cost percentile context — p50/p90/p99 of message costs.
const ascending = messages.map((m) => m.cost_usd).sort((a, b) => a - b);
const pct = (q) => {
const idx = Math.floor(q * (ascending.length - 1));
return ascending[idx] || 0;
};
const percentiles = { p50: pct(0.5), p90: pct(0.9), p99: pct(0.99) };
const payload = {
sessionFile: sessionFile.path,
sessionId: ARGS.sessionId,
filters: { top: ARGS.top, since: ARGS.since },
messageCount: messages.length,
total_cost_usd: Math.round(total * 1e6) / 1e6,
percentiles: {
p50_cost_usd: Math.round(percentiles.p50 * 1e6) / 1e6,
p90_cost_usd: Math.round(percentiles.p90 * 1e6) / 1e6,
p99_cost_usd: Math.round(percentiles.p99 * 1e6) / 1e6,
},
topByMessage: top.map((m, i) => ({
rank: i + 1,
timestamp: m.timestamp,
model: m.model,
tier: m.tier,
input_tokens: m.input_tokens,
output_tokens: m.output_tokens,
// iter 82 — surface cache_creation_input_tokens too. Without it,
// big cache-write costs (e.g. opus @ 881K tokens = $16) look like
// a 569-token output costing $16, which is misleading.
cache_creation_input_tokens: m.cache_creation_input_tokens,
cache_read_input_tokens: m.cache_read_input_tokens,
cost_usd: Math.round(m.cost_usd * 1e6) / 1e6,
pctOfSession: total > 0 ? Math.round((m.cost_usd / total) * 10000) / 100 : 0,
})),
generatedAt: new Date().toISOString(),
};
if (ARGS.format === 'json') {
console.log(JSON.stringify(payload, null, 2));
return;
}
console.log(`# cost-session — ${sessionFile.path.split('/').pop()}`);
console.log('');
console.log(`| Metric | Value |`);
console.log(`|---|---:|`);
console.log(`| Session file | \`${sessionFile.path}\` |`);
console.log(`| Assistant messages | ${messages.length} |`);
console.log(`| **Total cost** | **$${total.toFixed(6)}** |`);
console.log(`| Median (p50) message | $${percentiles.p50.toFixed(6)} |`);
console.log(`| p90 message | $${percentiles.p90.toFixed(6)} |`);
console.log(`| p99 message | $${percentiles.p99.toFixed(6)} |`);
console.log('');
console.log(`## Top ${Math.min(ARGS.top, messages.length)} most expensive messages`);
console.log('');
console.log('| # | Timestamp | Model | Tier | In | Out | Cache W | Cache R | Cost | % session |');
console.log('|---:|---|---|---|---:|---:|---:|---:|---:|---:|');
for (const m of payload.topByMessage) {
const tsShort = m.timestamp ? m.timestamp.slice(0, 19).replace('T', ' ') : '—';
const modelShort = m.model.length > 30 ? m.model.slice(0, 27) + '…' : m.model;
console.log(`| ${m.rank} | ${tsShort} | \`${modelShort}\` | ${m.tier} | ${m.input_tokens} | ${m.output_tokens} | ${m.cache_creation_input_tokens} | ${m.cache_read_input_tokens} | $${m.cost_usd.toFixed(6)} | ${m.pctOfSession.toFixed(2)}% |`);
}
console.log('');
if (top[0].cost_usd > percentiles.p99 * 2) {
console.log(`_The top message is >2× the p99 of this session — that's an in-session outlier; check the prompt content._`);
console.log('');
}
}
main();