aiwg 2026.10.7 → 2026.10.8
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/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/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/cli/handlers/cost-report.js +7 -1
- package/dist/src/cli/handlers/decision.js +33 -8
- package/dist/src/cli/handlers/local-executor.js +33 -6
- 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/serve/shared-host-scheduler.js +4 -1
- package/dist/src/storage/backends/fortemi.js +107 -49
- package/docs/_manifest.json +8 -0
- package/docs/agents/providers/grok-build.md +11 -0
- package/docs/cli/reference.md +65 -13
- package/docs/cli/sensitive-values.md +67 -9
- 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 +1 -0
- package/docs/releases/v2026.10.8-announcement.md +174 -0
- 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/tools/ralph-external/executor-shim.mjs +50 -22
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "agent-persistence",
|
|
3
|
-
"version": "2026.10.
|
|
3
|
+
"version": "2026.10.8",
|
|
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.8",
|
|
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.8",
|
|
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.8",
|
|
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.8",
|
|
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.8",
|
|
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",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "knowledge-base",
|
|
3
|
-
"version": "2026.10.
|
|
3
|
+
"version": "2026.10.8",
|
|
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.8",
|
|
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.8",
|
|
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.8",
|
|
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.8",
|
|
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.8",
|
|
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.8",
|
|
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.8",
|
|
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.8",
|
|
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.8",
|
|
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.8",
|
|
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.8",
|
|
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",
|
|
@@ -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
|
} : {}),
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { resolveSensitiveInput, sensitiveInputOptions } from '../../auth/sensitive-input.js';
|
|
2
2
|
import { decisionPricing } from '../../decision/pricing.js';
|
|
3
|
-
import { ATTRIBUTION_FIELD_PATTERN, DecisionAskUsageError, decisionCapabilities, DecisionLedgerSinceError, decisionLedgerHistory, decisionLedgerStats, evaluateRequestPath, listPatterns, livePlan, MAX_ATTRIBUTION_FIELD_LENGTH, materializeSyntheticClassificationSetup, parseDecisionLedgerSince, readDecisionContextFile, runDecisionOffloadCheckpoint, runOfflinePattern, setupJev, showPattern, syntheticClassificationSetup, validateDecisionInput, } from '../../decision/driver.js';
|
|
3
|
+
import { ATTRIBUTION_FIELD_PATTERN, DecisionAskUsageError, decisionCapabilities, DecisionLedgerSinceError, decisionLedgerHistory, decisionLedgerStats, rotateDecisionLedger, parseDecisionLedgerRetention, evaluateRequestPath, listPatterns, livePlan, MAX_ATTRIBUTION_FIELD_LENGTH, materializeSyntheticClassificationSetup, parseDecisionLedgerSince, readDecisionContextFile, runDecisionOffloadCheckpoint, runOfflinePattern, setupJev, showPattern, syntheticClassificationSetup, validateDecisionInput, } from '../../decision/driver.js';
|
|
4
4
|
function jsonResult(value, exitCode = 0) {
|
|
5
5
|
return { exitCode, message: JSON.stringify(value, null, 2), rawOutput: true };
|
|
6
6
|
}
|
|
7
7
|
function usage() {
|
|
8
8
|
return [
|
|
9
|
-
'Usage: aiwg decision <capabilities|status|patterns|validate|evaluate|setup|history|stats|pricing> [options]',
|
|
9
|
+
'Usage: aiwg decision <capabilities|status|patterns|validate|evaluate|setup|history|stats|rotate|pricing> [options]',
|
|
10
10
|
' aiwg decision ask --question "<q>" (--yes-no | --choices a,b,c | --scale 1-5) [--context <text> | --context-file <path> | --context-stdin] [--threshold 0.8] [--timeout-ms 15000] [--passes N] [--escalation-passes N] [--provider <id>] [--session <id>] [--caller <tag>] [--record-text] [--json]',
|
|
11
11
|
'',
|
|
12
12
|
'Commands:',
|
|
@@ -20,9 +20,10 @@ function usage() {
|
|
|
20
20
|
' setup synthetic-classification [--output-dir <dir>]',
|
|
21
21
|
' setup jev [--token-interactive | --token-stdin | --token-file <path> | --token-store <name> | --token-env <name>] [--region <r>] [--endpoint <url>] [--verify] [--remove]',
|
|
22
22
|
' ask --question "<q>" (--yes-no | --choices a,b,c | --scale 1-5) [--provider <id>] [--session <id>] [--caller <tag>] [--record-text]',
|
|
23
|
-
' history [--since <date>] [--provider <id>] [--session <id>] [--kind yes-no|choices|scale] [--status answered|fallback] [--caller <tag>|<prefix>* | --no-caller] [--json]',
|
|
23
|
+
' history [--since <date>] [--provider <id>] [--session <id>] [--kind yes-no|choices|scale] [--status answered|fallback] [--caller <tag>|<prefix>* | --no-caller] [--include-archives] [--json]',
|
|
24
24
|
' pricing [--refresh --model jev-X.Y.Z] [--dry-run] [--offline | --allow-snapshot] [--json]',
|
|
25
|
-
' stats [--since <date>] [--provider <id>] [--session <id>] [--kind yes-no|choices|scale] [--status answered|fallback] [--caller <tag>|<prefix>* | --no-caller] [--group-by provider|session|kind|caller|passes|escalation] [--json]',
|
|
25
|
+
' stats [--since <date>] [--provider <id>] [--session <id>] [--kind yes-no|choices|scale] [--status answered|fallback] [--caller <tag>|<prefix>* | --no-caller] [--group-by provider|session|kind|caller|passes|escalation] [--include-archives] [--json]',
|
|
26
|
+
' rotate [--keep-last <Nd|N> | --all] [--to <path>] [--json]',
|
|
26
27
|
'',
|
|
27
28
|
'Notes:',
|
|
28
29
|
' Every COMPLETED `ask` call (CLI and MCP) appends one record to the decision',
|
|
@@ -42,9 +43,13 @@ function usage() {
|
|
|
42
43
|
` --session and --caller must match ${ATTRIBUTION_FIELD_PATTERN.source} (<= ${MAX_ATTRIBUTION_FIELD_LENGTH} characters).`,
|
|
43
44
|
' `history`/`stats` accept `--caller <tag>` (exact), `--caller \'<prefix>*\'` (prefix; the only wildcard), or `--no-caller` (records with no tag; not combinable with `--caller`).',
|
|
44
45
|
' `history`/`stats` reject unknown flags and positional arguments with exit 2.',
|
|
45
|
-
'
|
|
46
|
-
'
|
|
47
|
-
'
|
|
46
|
+
' `rotate` keeps the last 90 days by default; --keep-last accepts days or a',
|
|
47
|
+
' positive count. Rotating everything requires --all. Malformed lines stay',
|
|
48
|
+
' inline unless --all is used. Archives are private .jsonl files beneath',
|
|
49
|
+
' archive/decision/ in the resolved artifact root; --to must stay there.',
|
|
50
|
+
' `history`/`stats` optionally read archives with --include-archives, offline.',
|
|
51
|
+
' Appenders, rotation and readers share one cross-process lock.',
|
|
52
|
+
' The ledger trusts only the local filesystem under the project',
|
|
48
53
|
' artifact root, owned by the same user running aiwg — it is not a defense',
|
|
49
54
|
' against a hostile process already running as that user.',
|
|
50
55
|
].join('\n');
|
|
@@ -207,7 +212,7 @@ function parseGroupBy(value) {
|
|
|
207
212
|
return value;
|
|
208
213
|
}
|
|
209
214
|
const HISTORY_VALUE_FLAGS = ['--since', '--provider', '--session', '--kind', '--status', '--caller'];
|
|
210
|
-
const HISTORY_BOOL_FLAGS = ['--json', '--no-caller'];
|
|
215
|
+
const HISTORY_BOOL_FLAGS = ['--json', '--no-caller', '--include-archives'];
|
|
211
216
|
const STATS_VALUE_FLAGS = [...HISTORY_VALUE_FLAGS, '--group-by'];
|
|
212
217
|
const STATS_BOOL_FLAGS = HISTORY_BOOL_FLAGS;
|
|
213
218
|
/**
|
|
@@ -269,6 +274,7 @@ function parseLedgerFilters(args) {
|
|
|
269
274
|
kind: parseKindFilter(takeOption(args, '--kind')),
|
|
270
275
|
status: parseStatusFilter(takeOption(args, '--status')),
|
|
271
276
|
...parseCallerFilter(args),
|
|
277
|
+
...(args.includes('--include-archives') ? { includeArchives: true } : {}),
|
|
272
278
|
};
|
|
273
279
|
}
|
|
274
280
|
/** One header line stating the caller filter, shown only when one is set. */
|
|
@@ -323,6 +329,23 @@ async function decisionStats(ctx) {
|
|
|
323
329
|
]);
|
|
324
330
|
return { exitCode: 0, message: [...header, ...lines].join('\n'), rawOutput: true };
|
|
325
331
|
}
|
|
332
|
+
async function decisionRotate(ctx) {
|
|
333
|
+
const args = ctx.args.slice(1);
|
|
334
|
+
assertLedgerArgs(args, ['--keep-last', '--to'], ['--all', '--json']);
|
|
335
|
+
const keepLast = args.includes('--keep-last') ? takeRequiredOption(args, '--keep-last') : undefined;
|
|
336
|
+
const all = args.includes('--all');
|
|
337
|
+
try {
|
|
338
|
+
parseDecisionLedgerRetention(keepLast, all);
|
|
339
|
+
}
|
|
340
|
+
catch (error) {
|
|
341
|
+
throw new DecisionAskUsageError('invalid-retention', error instanceof Error ? error.message : String(error));
|
|
342
|
+
}
|
|
343
|
+
const result = await rotateDecisionLedger({ projectRoot: ctx.cwd, keepLast, all,
|
|
344
|
+
to: args.includes('--to') ? takeRequiredOption(args, '--to') : undefined });
|
|
345
|
+
if (args.includes('--json'))
|
|
346
|
+
return jsonResult(result);
|
|
347
|
+
return { exitCode: 0, rawOutput: true, message: `Archived ${result.archived} line(s)${result.archivePath ? ` to ${result.archivePath}` : ''}; retained ${result.retained} line(s) inline (${result.malformed} malformed).` };
|
|
348
|
+
}
|
|
326
349
|
async function executeDecision(ctx) {
|
|
327
350
|
const [command, subcommand, ...rest] = ctx.args;
|
|
328
351
|
const options = { cwd: ctx.cwd, frameworkRoot: ctx.frameworkRoot, env: process.env };
|
|
@@ -335,6 +358,8 @@ async function executeDecision(ctx) {
|
|
|
335
358
|
return await decisionAsk(ctx);
|
|
336
359
|
if (command === 'history')
|
|
337
360
|
return await decisionHistory(ctx);
|
|
361
|
+
if (command === 'rotate')
|
|
362
|
+
return await decisionRotate(ctx);
|
|
338
363
|
if (command === 'pricing') {
|
|
339
364
|
const args = ctx.args.slice(1);
|
|
340
365
|
assertLedgerArgs(args, ['--model'], ['--refresh', '--dry-run', '--offline', '--allow-snapshot', '--json']);
|
|
@@ -21,9 +21,22 @@ import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'fs';
|
|
|
21
21
|
import { createHash, randomUUID } from 'crypto';
|
|
22
22
|
import { pathToFileURL } from 'node:url';
|
|
23
23
|
import { projectAiwgPath } from '../../config/project-artifacts.js';
|
|
24
|
+
import { resolveSensitiveInput, sensitiveInputOptions } from '../../auth/sensitive-input.js';
|
|
24
25
|
const DEFAULT_PORT = 8200;
|
|
25
26
|
const DEFAULT_BIND = '127.0.0.1';
|
|
26
27
|
const DEFAULT_AIWG_SERVE = 'http://127.0.0.1:7337';
|
|
28
|
+
/** Optional input: no source keeps registration/cache behavior, even at a terminal. */
|
|
29
|
+
export async function resolveLocalExecutorToken(args, dependencies = {}) {
|
|
30
|
+
const source = sensitiveInputOptions(args, 'token');
|
|
31
|
+
const environment = dependencies.environment ?? process.env;
|
|
32
|
+
const explicit = source.interactive || source.stdin || source.file !== undefined || source.store !== undefined || source.env !== undefined;
|
|
33
|
+
if (!explicit) {
|
|
34
|
+
if (!environment.AIWG_EXECUTOR_TOKEN)
|
|
35
|
+
return undefined;
|
|
36
|
+
source.env = 'AIWG_EXECUTOR_TOKEN';
|
|
37
|
+
}
|
|
38
|
+
return resolveSensitiveInput(source, { ...dependencies, environment });
|
|
39
|
+
}
|
|
27
40
|
/**
|
|
28
41
|
* Resolve or generate-once the executor identity.
|
|
29
42
|
* Written to `.aiwg/local-executor/identity.json` so restarts reuse the same
|
|
@@ -122,6 +135,14 @@ export const localExecutorServeHandler = {
|
|
|
122
135
|
// The subcommand is: `aiwg local-executor serve [flags]`
|
|
123
136
|
// ctx.args[0] === 'serve' (consumed by router) or flags directly
|
|
124
137
|
const flagArgs = ctx.args[0] === 'serve' ? ctx.args.slice(1) : ctx.args;
|
|
138
|
+
let preexistingToken;
|
|
139
|
+
try {
|
|
140
|
+
preexistingToken = await resolveLocalExecutorToken(flagArgs);
|
|
141
|
+
}
|
|
142
|
+
catch (error) {
|
|
143
|
+
return { exitCode: 1, message: error.message };
|
|
144
|
+
}
|
|
145
|
+
const redact = (message) => preexistingToken ? message.split(preexistingToken).join('[REDACTED]') : message;
|
|
125
146
|
const opts = parseLocalExecutorArgs(flagArgs);
|
|
126
147
|
warnIfNonLoopback(opts.bind);
|
|
127
148
|
// ── Dynamic imports (same pattern as serve.ts) ──────────────────────────
|
|
@@ -138,7 +159,7 @@ export const localExecutorServeHandler = {
|
|
|
138
159
|
}
|
|
139
160
|
catch (err) {
|
|
140
161
|
return {
|
|
141
|
-
message: `Failed to load executor-shim: ${err.message}`,
|
|
162
|
+
message: `Failed to load executor-shim: ${redact(err.message)}`,
|
|
142
163
|
exitCode: 1,
|
|
143
164
|
};
|
|
144
165
|
}
|
|
@@ -148,7 +169,7 @@ export const localExecutorServeHandler = {
|
|
|
148
169
|
}
|
|
149
170
|
catch (err) {
|
|
150
171
|
return {
|
|
151
|
-
message: `Failed to load DaemonSupervisor: ${err.message}`,
|
|
172
|
+
message: `Failed to load DaemonSupervisor: ${redact(err.message)}`,
|
|
152
173
|
exitCode: 1,
|
|
153
174
|
};
|
|
154
175
|
}
|
|
@@ -208,7 +229,7 @@ export const localExecutorServeHandler = {
|
|
|
208
229
|
restBase,
|
|
209
230
|
wsBase,
|
|
210
231
|
aiwgServeUrl: opts.aiwgServe,
|
|
211
|
-
token:
|
|
232
|
+
token: preexistingToken,
|
|
212
233
|
tokenPath: projectAiwgPath(process.cwd(), 'local-executor', 'tokens', `${createHash('sha256').update(`${opts.aiwgServe}\0${opts.executorId}`).digest('hex')}.json`),
|
|
213
234
|
});
|
|
214
235
|
// Register with aiwg-serve
|
|
@@ -218,7 +239,7 @@ export const localExecutorServeHandler = {
|
|
|
218
239
|
}
|
|
219
240
|
catch (err) {
|
|
220
241
|
return {
|
|
221
|
-
message: `Failed to register with aiwg-serve at ${opts.aiwgServe}: ${err.message}\n` +
|
|
242
|
+
message: `Failed to register with aiwg-serve at ${opts.aiwgServe}: ${redact(err.message)}\n` +
|
|
222
243
|
'Is aiwg serve running? Start it with: aiwg serve --no-open',
|
|
223
244
|
exitCode: 1,
|
|
224
245
|
};
|
|
@@ -235,7 +256,7 @@ export const localExecutorServeHandler = {
|
|
|
235
256
|
catch (err) {
|
|
236
257
|
await shim.deregister();
|
|
237
258
|
return {
|
|
238
|
-
message: `Failed to start executor server: ${err.message}`,
|
|
259
|
+
message: `Failed to start executor server: ${redact(err.message).split(token).join('[REDACTED]')}`,
|
|
239
260
|
exitCode: 1,
|
|
240
261
|
};
|
|
241
262
|
}
|
|
@@ -304,9 +325,15 @@ export const localExecutorHandler = {
|
|
|
304
325
|
' --aiwg-serve <url> Registration target (default: http://127.0.0.1:7337)\n' +
|
|
305
326
|
' --max-concurrency <n> Max concurrent missions (default: 4)\n' +
|
|
306
327
|
' --executor-id <uuid> Override stable executor ID\n' +
|
|
328
|
+
' --token-interactive Read optional existing bearer without echo\n' +
|
|
329
|
+
' --token-stdin Read optional existing bearer from stdin\n' +
|
|
330
|
+
' --token-file <path> Read optional existing bearer from a private file\n' +
|
|
331
|
+
' --token-store <name> Read optional existing bearer from the OS store\n' +
|
|
332
|
+
' --token-env <NAME> Read optional existing bearer from a named variable\n' +
|
|
307
333
|
'\n' +
|
|
308
334
|
'Environment:\n' +
|
|
309
|
-
' AIWG_SERVE_ENDPOINT Override --aiwg-serve default\n'
|
|
335
|
+
' AIWG_SERVE_ENDPOINT Override --aiwg-serve default\n' +
|
|
336
|
+
' AIWG_EXECUTOR_TOKEN Optional preexisting executor bearer\n');
|
|
310
337
|
return { exitCode: 0 };
|
|
311
338
|
}
|
|
312
339
|
return {
|