aiwg 2026.10.7 → 2026.10.9
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/agentic/code/addons/aiwg-hooks/hooks/aiwg-session.cjs +10 -1
- package/agentic/code/plugins/agent-loop/.claude-plugin/plugin.json +1 -1
- package/agentic/code/plugins/agent-persistence/.claude-plugin/plugin.json +1 -1
- package/agentic/code/plugins/agentic-installer/.claude-plugin/plugin.json +1 -1
- package/agentic/code/plugins/aiwg-dev/.claude-plugin/plugin.json +1 -1
- package/agentic/code/plugins/aiwg-evals/.claude-plugin/plugin.json +1 -1
- package/agentic/code/plugins/auto-memory/.claude-plugin/plugin.json +1 -1
- package/agentic/code/plugins/browser-control/.claude-plugin/plugin.json +1 -1
- package/agentic/code/plugins/color-palette/.claude-plugin/plugin.json +1 -1
- package/agentic/code/plugins/compound-memory/.claude-plugin/plugin.json +1 -1
- package/agentic/code/plugins/context-curator/.claude-plugin/plugin.json +1 -1
- package/agentic/code/plugins/daemon/.claude-plugin/plugin.json +1 -1
- package/agentic/code/plugins/doc-intelligence/.claude-plugin/plugin.json +1 -1
- package/agentic/code/plugins/droid-bridge/.claude-plugin/plugin.json +1 -1
- package/agentic/code/plugins/forensics/.claude-plugin/plugin.json +1 -1
- package/agentic/code/plugins/guided-implementation/.claude-plugin/plugin.json +1 -1
- package/agentic/code/plugins/hooks/.claude-plugin/plugin.json +1 -1
- package/agentic/code/plugins/hooks/hooks/aiwg-session.cjs +10 -1
- package/agentic/code/plugins/knowledge-base/.claude-plugin/plugin.json +1 -1
- package/agentic/code/plugins/line-memory/.claude-plugin/plugin.json +1 -1
- package/agentic/code/plugins/llm-wiki/.claude-plugin/plugin.json +1 -1
- package/agentic/code/plugins/marketing/.claude-plugin/plugin.json +1 -1
- package/agentic/code/plugins/media-curator/.claude-plugin/plugin.json +1 -1
- package/agentic/code/plugins/nlp-prod/.claude-plugin/plugin.json +1 -1
- package/agentic/code/plugins/ops/.claude-plugin/plugin.json +1 -1
- package/agentic/code/plugins/prose-integration/.claude-plugin/plugin.json +1 -1
- package/agentic/code/plugins/research/.claude-plugin/plugin.json +1 -1
- package/agentic/code/plugins/rlm/.claude-plugin/plugin.json +1 -1
- package/agentic/code/plugins/sdlc/.claude-plugin/plugin.json +1 -1
- package/agentic/code/plugins/security-engineering/.claude-plugin/plugin.json +1 -1
- package/agentic/code/plugins/semantic-memory/.claude-plugin/plugin.json +1 -1
- package/agentic/code/plugins/skill-factory/.claude-plugin/plugin.json +1 -1
- package/agentic/code/plugins/star-prompt/.claude-plugin/plugin.json +1 -1
- package/agentic/code/plugins/testing-quality/.claude-plugin/plugin.json +1 -1
- package/agentic/code/plugins/twelve-factor/.claude-plugin/plugin.json +1 -1
- package/agentic/code/plugins/uat-mcp/.claude-plugin/plugin.json +1 -1
- package/agentic/code/plugins/utils/.claude-plugin/plugin.json +1 -1
- package/agentic/code/plugins/validation-complete/.claude-plugin/plugin.json +1 -1
- package/agentic/code/plugins/verbalized-sampling/.claude-plugin/plugin.json +1 -1
- package/agentic/code/plugins/voice/.claude-plugin/plugin.json +1 -1
- package/agentic/code/plugins/writing/.claude-plugin/plugin.json +1 -1
- package/dist/src/artifacts/cli.js +9 -5
- package/dist/src/auth/config.js +3 -8
- package/dist/src/auth/resource-credentials.js +35 -2
- package/dist/src/cli/handlers/cost-report.js +7 -1
- package/dist/src/cli/handlers/decision.js +33 -8
- package/dist/src/cli/handlers/diagnose.js +13 -0
- package/dist/src/cli/handlers/local-executor.js +33 -6
- package/dist/src/cli/handlers/resource-versions.js +8 -5
- package/dist/src/cli/handlers/script-runner.js +13 -1
- package/dist/src/cli/handlers/use.js +18 -3
- package/dist/src/cost/fleet-report.js +20 -22
- package/dist/src/decision/driver.d.ts +2 -2
- package/dist/src/decision/driver.js +2 -2
- package/dist/src/decision/egress-live-qualification.d.ts +2 -2
- package/dist/src/decision/jev-credentials.js +18 -5
- package/dist/src/decision/ledger.d.ts +31 -10
- package/dist/src/decision/ledger.js +230 -34
- package/dist/src/mcp/cli.mjs +105 -19
- package/dist/src/mcp/credentials.d.mts +4 -0
- package/dist/src/mcp/credentials.mjs +44 -3
- package/dist/src/mcp/grok-build-config.mjs +2 -0
- package/dist/src/mcp/omp-config.mjs +2 -0
- package/dist/src/mcp/registry.js +19 -15
- package/dist/src/mcp/registry.mjs +2 -18
- package/dist/src/mcp/tools/agentic-sandbox.mjs +46 -28
- package/dist/src/models/grok-build-models.js +20 -0
- package/dist/src/providers/provider-definitions.js +2 -2
- package/dist/src/resources/web-release.js +76 -65
- package/dist/src/serve/shared-host-scheduler.js +4 -1
- package/dist/src/storage/backends/fortemi.js +112 -50
- package/dist/src/storage/backends/logseq.js +16 -3
- package/dist/src/storage/backends/postgres.js +74 -33
- package/dist/src/storage/backends/postgrest.js +37 -13
- package/dist/src/storage/config.js +6 -1
- package/dist/src/uhp/config.js +4 -0
- package/docs/_manifest.json +16 -0
- package/docs/agents/providers/grok-build.md +11 -0
- package/docs/cli/reference.md +70 -15
- package/docs/cli/sensitive-values.md +188 -16
- package/docs/cli/web-backed-resources.md +25 -3
- package/docs/daemon-guide.md +7 -1
- package/docs/decision/jev-quickstart.md +70 -20
- package/docs/guides/openrouter-fleet-costs.md +4 -2
- package/docs/mcp/README.md +19 -1
- package/docs/providers/grok-build-direct.md +17 -11
- package/docs/providers/grok-build-models.md +10 -0
- package/docs/providers/grok-build-qualification.json +7 -2
- package/docs/providers/grok-build-qualification.md +12 -2
- package/docs/releases/_manifest.json +2 -0
- package/docs/releases/v2026.10.8-announcement.md +174 -0
- package/docs/releases/v2026.10.9-announcement.md +177 -0
- package/docs/storage/backends/fortemi.md +10 -0
- package/docs/storage/backends/logseq.md +5 -2
- package/docs/storage/backends/postgres.md +6 -3
- package/docs/storage/backends/postgrest.md +12 -1
- package/docs/storage/evidence/claims.v1.json +2 -1
- package/docs/storage/evidence/postgres-direct-reference-v1.json +42 -35
- package/docs/storage/evidence/postgres-postgrest-reference-v1.json +36 -27
- package/docs/storage/qualification.md +35 -4
- package/docs/uhp-client.md +2 -1
- package/package.json +1 -1
- package/prebuilt/fortemi-core/framework/aiwg-fortemi-index-v2.json +1 -1
- package/prebuilt/fortemi-core/framework/manifest.json +5 -5
- package/prebuilt/fortemi-core/framework/source-stats.json +1 -1
- package/prebuilt/framework-relations/manifest.json +3 -3
- package/prebuilt/framework-relations/relations.json +1 -1
- package/schemas/storage/storage.config.v1.schema.json +1 -1
- package/tools/daemon/agent-supervisor.mjs +2 -1
- package/tools/daemon/config.mjs +118 -1
- package/tools/daemon/daemon-main.mjs +26 -16
- package/tools/daemon/provider-watcher.mjs +3 -0
- package/tools/daemon/resource-bounds.mjs +6 -1
- package/tools/daemon/scheduled-task-runner.mjs +5 -2
- package/tools/messaging/adapter-registry.mjs +6 -4
- package/tools/messaging/adapters/base.mjs +20 -1
- package/tools/messaging/adapters/discord.mjs +8 -2
- package/tools/messaging/adapters/slack.mjs +4 -0
- package/tools/messaging/adapters/telegram.mjs +10 -2
- package/tools/messaging/chat-handler.mjs +4 -1
- package/tools/messaging/index.mjs +3 -1
- package/tools/ralph-external/executor-shim.mjs +50 -22
|
@@ -45,8 +45,17 @@ async function compactContext() {
|
|
|
45
45
|
try {
|
|
46
46
|
const buffer = Buffer.alloc(65537);
|
|
47
47
|
let used = 0;
|
|
48
|
+
// stdin can be a non-blocking pipe whose writer has not sent the event yet.
|
|
49
|
+
// EAGAIN means "no data yet", not "no input": wait briefly and retry.
|
|
50
|
+
const deadline = Date.now() + 5000;
|
|
51
|
+
const pause = new Int32Array(new SharedArrayBuffer(4));
|
|
48
52
|
while (used < buffer.length) {
|
|
49
|
-
|
|
53
|
+
let count;
|
|
54
|
+
try { count = fs.readSync(0, buffer, used, buffer.length - used, null); }
|
|
55
|
+
catch (error) {
|
|
56
|
+
if (error && error.code === 'EAGAIN' && Date.now() < deadline) { Atomics.wait(pause, 0, 0, 10); continue; }
|
|
57
|
+
throw error;
|
|
58
|
+
}
|
|
50
59
|
if (count === 0) break;
|
|
51
60
|
used += count;
|
|
52
61
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "agent-persistence",
|
|
3
|
-
"version": "2026.10.
|
|
3
|
+
"version": "2026.10.9",
|
|
4
4
|
"description": "Human-in-the-loop (HITL) gate definitions for agent operations. Provides reusable YAML gates for destructive-action authorization, false-positive override, and recovery escalation. Loaded by agent loops and orchestrators that need bounded human checkpoints.",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "AIWG Contributors",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "agentic-installer",
|
|
3
|
-
"version": "2026.10.
|
|
3
|
+
"version": "2026.10.9",
|
|
4
4
|
"description": "Structured YAML manifests for reproducible, agent-driven software installation across platforms. Scripts are the primary artifact; agentic instructions handle adaptation and recovery.",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "AIWG Contributors",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "aiwg-dev",
|
|
3
|
-
"version": "2026.10.
|
|
3
|
+
"version": "2026.10.9",
|
|
4
4
|
"description": "Developer tooling for building AIWG itself and AIWG addons/frameworks. Not for end users — install explicitly with `aiwg use aiwg-dev`.",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "AIWG Contributors",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "browser-control",
|
|
3
|
-
"version": "2026.10.
|
|
3
|
+
"version": "2026.10.9",
|
|
4
4
|
"description": "Drive a real, user-installed Chromium-derived browser from an AIWG agent. Wraps @playwright/mcp with a setup wizard, health-check doctor, allow-list enforcement, and an opinionated agent persona that respects authorization and audit boundaries.",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "AIWG Contributors",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "color-palette",
|
|
3
|
-
"version": "2026.10.
|
|
3
|
+
"version": "2026.10.9",
|
|
4
4
|
"description": "Color palette selection and review tooling with color theory fundamentals, current trend research, and accessibility analysis.",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "AIWG Contributors",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "forensics",
|
|
3
|
-
"version": "2026.10.
|
|
3
|
+
"version": "2026.10.9",
|
|
4
4
|
"description": "Digital forensics and incident response framework with 14 specialized agents covering target profiling, evidence acquisition, log/memory/container/cloud analysis, IOC extraction, and reporting.",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "AIWG Contributors",
|
|
@@ -45,8 +45,17 @@ async function compactContext() {
|
|
|
45
45
|
try {
|
|
46
46
|
const buffer = Buffer.alloc(65537);
|
|
47
47
|
let used = 0;
|
|
48
|
+
// stdin can be a non-blocking pipe whose writer has not sent the event yet.
|
|
49
|
+
// EAGAIN means "no data yet", not "no input": wait briefly and retry.
|
|
50
|
+
const deadline = Date.now() + 5000;
|
|
51
|
+
const pause = new Int32Array(new SharedArrayBuffer(4));
|
|
48
52
|
while (used < buffer.length) {
|
|
49
|
-
|
|
53
|
+
let count;
|
|
54
|
+
try { count = fs.readSync(0, buffer, used, buffer.length - used, null); }
|
|
55
|
+
catch (error) {
|
|
56
|
+
if (error && error.code === 'EAGAIN' && Date.now() < deadline) { Atomics.wait(pause, 0, 0, 10); continue; }
|
|
57
|
+
throw error;
|
|
58
|
+
}
|
|
50
59
|
if (count === 0) break;
|
|
51
60
|
used += count;
|
|
52
61
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "knowledge-base",
|
|
3
|
-
"version": "2026.10.
|
|
3
|
+
"version": "2026.10.9",
|
|
4
4
|
"description": "Knowledge-base / wiki framework with skills for ingestion, query, and lint. Build a structured, citable corpus with cross-references and concept pages.",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "AIWG Contributors",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "llm-wiki",
|
|
3
|
-
"version": "2026.10.
|
|
3
|
+
"version": "2026.10.9",
|
|
4
4
|
"description": "LLM-maintained markdown wiki that compounds as sources are ingested. Thin topology declaration on the semantic memory kernel — ships schema profiles and page templates, no custom mechanics.",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "AIWG Contributors",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "media-curator",
|
|
3
|
-
"version": "2026.10.
|
|
3
|
+
"version": "2026.10.9",
|
|
4
4
|
"description": "Media archive management framework with 7 specialized agents for source discovery, acquisition (yt-dlp / Internet Archive / Bandcamp), quality assessment, metadata tagging, and provenance tracking.",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "AIWG Contributors",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nlp-prod",
|
|
3
|
-
"version": "2026.10.
|
|
3
|
+
"version": "2026.10.9",
|
|
4
4
|
"description": "Tools, skills, and CLI extensions for designing and productionizing LLM inference pipelines. Pattern-guided, slim by default, eval-first.",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "AIWG Contributors",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ops",
|
|
3
|
-
"version": "2026.10.
|
|
3
|
+
"version": "2026.10.9",
|
|
4
4
|
"description": "Operational infrastructure framework with 12 specialized agents covering incident response, runbook execution, fleet inventory, certificate lifecycle, and disaster recovery planning.",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "AIWG Contributors",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "research",
|
|
3
|
-
"version": "2026.10.
|
|
3
|
+
"version": "2026.10.9",
|
|
4
4
|
"description": "Research workflow framework with 9 specialized agents for discovery, acquisition, synthesis, citation management, GRADE quality assessment, and OAIS-compliant archival.",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "AIWG Contributors",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "rlm",
|
|
3
|
-
"version": "2026.10.
|
|
3
|
+
"version": "2026.10.9",
|
|
4
4
|
"description": "RLM-inspired recursive context decomposition for processing arbitrarily large codebases and document corpora through programmatic sub-agent delegation",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "AIWG Contributors",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "security-engineering",
|
|
3
|
-
"version": "2026.10.
|
|
3
|
+
"version": "2026.10.9",
|
|
4
4
|
"description": "Applied security framework for cryptographic primitive selection, chain-of-trust design, authentication factor analysis, supply-chain trust, and physical-threat modeling. Complements OWASP-style application audits.",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "AIWG Contributors",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "semantic-memory",
|
|
3
|
-
"version": "2026.10.
|
|
3
|
+
"version": "2026.10.9",
|
|
4
4
|
"description": "Topology-agnostic semantic memory operations: ingest, lint, query-capture, and structured event logging. Consumers declare a memory topology in their manifest.json; kernel skills read that contract to parameterize behavior.",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "AIWG Contributors",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "skill-factory",
|
|
3
|
-
"version": "2026.10.
|
|
3
|
+
"version": "2026.10.9",
|
|
4
4
|
"description": "Build, enhance, validate, and package Claude skills end-to-end. Coordinates skill-builder, skill-enhancer, quality-checker, and skill-packager via the skill-architect agent.",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "AIWG Contributors",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "uat-mcp",
|
|
3
|
-
"version": "2026.10.
|
|
3
|
+
"version": "2026.10.9",
|
|
4
4
|
"description": "Agent-executable acceptance testing via MCP connections — generate, execute, and report on UAT plans that validate MCP tool surfaces.",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "AIWG Contributors",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "verbalized-sampling",
|
|
3
|
-
"version": "2026.10.
|
|
3
|
+
"version": "2026.10.9",
|
|
4
4
|
"description": "Training-free prompting technique that improves output diversity by 1.6-2.1x through verbalized probability distributions, addressing RLHF mode collapse",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "AIWG Contributors",
|
|
@@ -24,9 +24,9 @@ import { resolveIndexWorkers } from './index-preparation.js';
|
|
|
24
24
|
import { SUPPORTED_VIEWS } from './corpus-views/renderers.js';
|
|
25
25
|
import { parseResourceSelector, readVerifiedRegularFile, } from '../resources/web-release.js';
|
|
26
26
|
import { findPackageRoot } from '../cli/find-package-root.js';
|
|
27
|
-
import { createResourceCredentialProvider } from '../auth/resource-credentials.js';
|
|
27
|
+
import { createResourceCredentialProvider, prepareResourceCredentials } from '../auth/resource-credentials.js';
|
|
28
28
|
const MAX_RESOURCE_TRUST_ROOT_BYTES = 64 * 1024;
|
|
29
|
-
function webReleaseOptionsFromEnvironment() {
|
|
29
|
+
function webReleaseOptionsFromEnvironment(credentialProvider = createResourceCredentialProvider(process.env)) {
|
|
30
30
|
const baseUrl = process.env.AIWG_RESOURCE_BASE_URL;
|
|
31
31
|
const cacheRoot = process.env.AIWG_RESOURCE_CACHE_ROOT;
|
|
32
32
|
const trustRootFile = process.env.AIWG_RESOURCE_TRUST_ROOT_FILE;
|
|
@@ -44,7 +44,7 @@ function webReleaseOptionsFromEnvironment() {
|
|
|
44
44
|
}
|
|
45
45
|
}
|
|
46
46
|
return {
|
|
47
|
-
credentialProvider
|
|
47
|
+
credentialProvider,
|
|
48
48
|
...(baseUrl === undefined ? {} : { baseUrl }),
|
|
49
49
|
...(cacheRoot === undefined ? {} : { cacheRoot }),
|
|
50
50
|
...(publicKeyPem === undefined ? {} : { publicKeyPem }),
|
|
@@ -1465,6 +1465,8 @@ const DISCOVER_VALUE_FLAGS = new Set([
|
|
|
1465
1465
|
* @implements #1214
|
|
1466
1466
|
*/
|
|
1467
1467
|
async function handleDiscover(args) {
|
|
1468
|
+
const credentials = await prepareResourceCredentials(args);
|
|
1469
|
+
args = credentials.args;
|
|
1468
1470
|
const { discoverCapability } = await import('./query-engine.js');
|
|
1469
1471
|
const cwd = process.cwd();
|
|
1470
1472
|
// Parse the positional phrase. Flags may appear before or after it — the
|
|
@@ -1526,7 +1528,7 @@ async function handleDiscover(args) {
|
|
|
1526
1528
|
const offline = flags.includes('--offline');
|
|
1527
1529
|
const webReleaseOptions = resourceSource === 'local'
|
|
1528
1530
|
? undefined
|
|
1529
|
-
: webReleaseOptionsFromEnvironment();
|
|
1531
|
+
: webReleaseOptionsFromEnvironment(credentials.credentialProvider);
|
|
1530
1532
|
await discoverCapability(cwd, {
|
|
1531
1533
|
phrase,
|
|
1532
1534
|
typeFilter,
|
|
@@ -1578,6 +1580,8 @@ function showFlagValues(flags, name) {
|
|
|
1578
1580
|
return values;
|
|
1579
1581
|
}
|
|
1580
1582
|
async function handleShow(args) {
|
|
1583
|
+
const credentials = await prepareResourceCredentials(args);
|
|
1584
|
+
args = credentials.args;
|
|
1581
1585
|
const { showArtifact, showMetadata } = await import('./query-engine.js');
|
|
1582
1586
|
const cwd = process.cwd();
|
|
1583
1587
|
const positional = [];
|
|
@@ -1676,7 +1680,7 @@ async function handleShow(args) {
|
|
|
1676
1680
|
const offline = flags.includes('--offline');
|
|
1677
1681
|
const webReleaseOptions = resourceSource === 'local'
|
|
1678
1682
|
? undefined
|
|
1679
|
-
: webReleaseOptionsFromEnvironment();
|
|
1683
|
+
: webReleaseOptionsFromEnvironment(credentials.credentialProvider);
|
|
1680
1684
|
const params = {
|
|
1681
1685
|
name,
|
|
1682
1686
|
boundRuleBodies: flags.includes('--bound-rule-bodies'),
|
package/dist/src/auth/config.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import fs from "node:fs";
|
|
2
1
|
import path from "node:path";
|
|
2
|
+
import { readPrivateValueFile } from "./sensitive-input.js";
|
|
3
3
|
export const DEFAULT_AUTH_BASE_URL = "https://releases.aiwg.io";
|
|
4
4
|
export const DEFAULT_AUTH_CLIENT_ID = "aiwg-cli";
|
|
5
5
|
export const DEFAULT_AUTH_SCOPES = ["releases:read", "profile:read"];
|
|
@@ -24,14 +24,9 @@ export function authConfigFromEnvironment(env = process.env) {
|
|
|
24
24
|
throw new Error("AIWG auth scopes are invalid");
|
|
25
25
|
return { baseUrl, clientId, scopes, requestTimeoutMs: 30_000 };
|
|
26
26
|
}
|
|
27
|
-
export function explicitResourceToken(env = process.env) {
|
|
27
|
+
export async function explicitResourceToken(env = process.env) {
|
|
28
28
|
if (env.AIWG_RESOURCE_TOKEN_FILE) {
|
|
29
|
-
|
|
30
|
-
const stat = fs.lstatSync(pathname);
|
|
31
|
-
if (!stat.isFile() || stat.isSymbolicLink() || (stat.mode & 0o077) !== 0) {
|
|
32
|
-
throw new Error("AIWG_RESOURCE_TOKEN_FILE must be a non-symlink regular file with mode 0600");
|
|
33
|
-
}
|
|
34
|
-
return fs.readFileSync(pathname, "utf8").trim() || null;
|
|
29
|
+
return await readPrivateValueFile(path.resolve(env.AIWG_RESOURCE_TOKEN_FILE), "AIWG_RESOURCE_TOKEN_FILE") || null;
|
|
35
30
|
}
|
|
36
31
|
return env.AIWG_RESOURCE_TOKEN?.trim() || null;
|
|
37
32
|
}
|
|
@@ -1,12 +1,19 @@
|
|
|
1
1
|
import { explicitResourceToken } from "./config.js";
|
|
2
2
|
import { createCredentialStore } from "./credential-store.js";
|
|
3
|
+
import { resolveSensitiveInput, sensitiveInputOptions } from "./sensitive-input.js";
|
|
3
4
|
/**
|
|
4
5
|
* Resolve credentials for protected release downloads. Explicit compatibility
|
|
5
6
|
* inputs take precedence over interactive-login credentials.
|
|
6
7
|
*/
|
|
7
|
-
export function createResourceCredentialProvider(env = process.env, store) {
|
|
8
|
+
export function createResourceCredentialProvider(env = process.env, store, source = {}, dependencies = {}) {
|
|
9
|
+
const hasSource = source.interactive || source.stdin || source.file !== undefined || source.store !== undefined || source.env !== undefined;
|
|
10
|
+
// A command may fetch several manifests and bodies. Never consume stdin or
|
|
11
|
+
// ask for the same explicit credential more than once, including on failure.
|
|
12
|
+
let resolvedSource;
|
|
8
13
|
return async () => {
|
|
9
|
-
|
|
14
|
+
if (hasSource)
|
|
15
|
+
return resolvedSource ??= resolveSensitiveInput({ ...source, prefix: 'resource-token' }, { ...dependencies, environment: env });
|
|
16
|
+
const explicit = await explicitResourceToken(env);
|
|
10
17
|
if (explicit)
|
|
11
18
|
return explicit;
|
|
12
19
|
const selected = store ?? createCredentialStore();
|
|
@@ -22,4 +29,30 @@ export function createResourceCredentialProvider(env = process.env, store) {
|
|
|
22
29
|
}
|
|
23
30
|
};
|
|
24
31
|
}
|
|
32
|
+
/** Parse once before command-specific positional parsing or helper forwarding. */
|
|
33
|
+
export async function prepareResourceCredentials(args, env = process.env, store, dependencies = {}) {
|
|
34
|
+
const source = sensitiveInputOptions(args, 'resource-token');
|
|
35
|
+
const remaining = [];
|
|
36
|
+
const valueFlags = ['--resource-token-file', '--resource-token-store', '--resource-token-env'];
|
|
37
|
+
for (let index = 0; index < args.length; index++) {
|
|
38
|
+
const token = args[index];
|
|
39
|
+
if (token === '--') {
|
|
40
|
+
remaining.push(...args.slice(index));
|
|
41
|
+
break;
|
|
42
|
+
}
|
|
43
|
+
if (valueFlags.includes(token)) {
|
|
44
|
+
index++;
|
|
45
|
+
continue;
|
|
46
|
+
}
|
|
47
|
+
if (valueFlags.some(flag => token.startsWith(`${flag}=`)) ||
|
|
48
|
+
token === '--resource-token-stdin' || token === '--resource-token-interactive')
|
|
49
|
+
continue;
|
|
50
|
+
remaining.push(token);
|
|
51
|
+
}
|
|
52
|
+
const credentialProvider = createResourceCredentialProvider(env, store, source, dependencies);
|
|
53
|
+
if (source.interactive || source.stdin || source.file !== undefined || source.store !== undefined || source.env !== undefined) {
|
|
54
|
+
await credentialProvider();
|
|
55
|
+
}
|
|
56
|
+
return { args: remaining, credentialProvider, omitEnv: ['AIWG_RESOURCE_TOKEN', ...(source.env ? [source.env] : [])] };
|
|
57
|
+
}
|
|
25
58
|
//# sourceMappingURL=resource-credentials.js.map
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
/** OpenRouter fleet cost-report CLI handler. @issue #1187 */
|
|
2
2
|
import os from 'node:os';
|
|
3
3
|
import path from 'node:path';
|
|
4
|
+
import { sensitiveInputOptions } from '../../auth/sensitive-input.js';
|
|
4
5
|
import { FleetConfigMissingError, formatFleetSpendReport, generateFleetSpendReport, } from '../../cost/fleet-report.js';
|
|
5
6
|
function option(args, name) {
|
|
6
7
|
const index = args.indexOf(name);
|
|
@@ -9,10 +10,11 @@ function option(args, name) {
|
|
|
9
10
|
}
|
|
10
11
|
function usage() {
|
|
11
12
|
return [
|
|
12
|
-
'Usage: aiwg cost-report (--fleet | --key <key_ref>) [--source openrouter] [--config <fleet.yaml>] [--json]',
|
|
13
|
+
'Usage: aiwg cost-report (--fleet | --key <key_ref> [--key-store <name>]) [--source openrouter] [--config <fleet.yaml>] [--json]',
|
|
13
14
|
'',
|
|
14
15
|
'Reads bot-to-key references from ~/.config/aiwg/fleet.yaml and credentials from',
|
|
15
16
|
'~/.config/aiwg/keys/<key_ref> or AIWG_OPENROUTER_KEY_<KEY_REF>.',
|
|
17
|
+
'Use --key-store <name> for one key, or per-entry key_store references in fleet YAML.',
|
|
16
18
|
'',
|
|
17
19
|
'AIWG observes and correlates spend; OpenRouter enforces all key limits and caps.',
|
|
18
20
|
].join('\n');
|
|
@@ -40,6 +42,9 @@ export const costReportHandler = {
|
|
|
40
42
|
? path.resolve(ctx.cwd, configuredPath)
|
|
41
43
|
: path.join(os.homedir(), '.config', 'aiwg', 'fleet.yaml');
|
|
42
44
|
try {
|
|
45
|
+
const keyStore = sensitiveInputOptions(ctx.args, 'key').store;
|
|
46
|
+
if (keyStore !== undefined && !keyRef)
|
|
47
|
+
return { exitCode: 2, message: '--key-store requires --key <key_ref>; use per-entry key_store references for --fleet.' };
|
|
43
48
|
const capValue = option(ctx.args, '--monthly-cap');
|
|
44
49
|
const cap = capValue === undefined ? 0 : Number(capValue);
|
|
45
50
|
if (!Number.isFinite(cap) || cap < 0)
|
|
@@ -53,6 +58,7 @@ export const costReportHandler = {
|
|
|
53
58
|
bot: option(ctx.args, '--bot') ?? keyRef,
|
|
54
59
|
machine: option(ctx.args, '--machine') ?? os.hostname(),
|
|
55
60
|
key_ref: keyRef,
|
|
61
|
+
...(keyStore !== undefined ? { key_store: keyStore } : {}),
|
|
56
62
|
monthly_cap: cap,
|
|
57
63
|
}],
|
|
58
64
|
} : {}),
|