A live forecast of the context window, drawn above the prompt.

ADYA is a compact governance and product layer built around the existing registry surfaces, with a deterministic local mode and a DSH-native execution mode.
completed only when evidence exists, otherwise needs_review or a persisted failure state.ADYA_LLM_MODE=dsh execution through the checked-out DeepSeek Harness Node SDK: DSH owns the Agent loop, workflow, temporary child Agents, model-facing tools, and sessions; ADYA owns the product API, contracts, native capability policy, evidence projection, memory, and the HTTP/user/admin planes.The existing DSH tool registry, workflow engine, subagent lifecycle, and session persistence are reused. The ADYA native plugin adds one governed capability surface over the existing DSH registry instead of maintaining a second agent executor or an HTTP bridge.
$env:ADYA_ADMIN_TOKEN = "replace-with-a-long-random-local-token"
$env:ADYA_DATA_FILE = "data/state.json"
python server.py
Open http://localhost:8080. Send X-User-Id: alice when using the user plane. Send X-Admin-Token for admin operations.
The default mode is dependency-free and deterministic. It is explicitly labeled local-demo; its temporary graph agents are simulated ADYA demo agents, not proof of DSH-native execution.
$body = @{ goal = "Build a governed registry-backed multi-agent memory demo"; requested_agents = 5 } | ConvertTo-Json
Invoke-RestMethod http://localhost:8080/api/runs -Method Post -Headers @{ "X-User-Id" = "alice" } -ContentType "application/json" -Body $body
graph.nodes, events, governance, artifacts.review, memory_hits, and cleanup event.$feedback = @{ run_id = "<run-id-from-response>"; text = "Prefer registry evidence before synthesis"; score = 5 } | ConvertTo-Json
Invoke-RestMethod http://localhost:8080/api/feedback -Method Post -Headers @{ "X-User-Id" = "alice" } -ContentType "application/json" -Body $feedback
$body = @{ goal = "Use prior registry memory to build another governed demo" } | ConvertTo-Json
Invoke-RestMethod http://localhost:8080/api/runs -Method Post -Headers @{ "X-User-Id" = "alice" } -ContentType "application/json" -Body $body
ADYA_ADMIN_TOKEN and use the admin plane to inspect /api/admin/audit, /api/admin/errors, registries, contracts, and memory.Set ADYA_LLM_MODE=dsh and follow docs/setup.md. This path fails closed if the checked-out DSH runtime is unavailable; it does not fall back to the deterministic local orchestrator.
python -m unittest discover -s tests -v
python -m pytest -q
python -m py_compile harness.py server.py adya-share/harness.py adya-share/server.py
The architecture and configuration details are in docs/architecture.md and docs/setup.md. The native DSH acceptance test is conditional; run it with ADYA_DSH_ACCEPTANCE=1 when Node and the checked-out DSH source runtime are available. The checked-in fixture is keyless; a live provider run is a separate, unclaimed check.
The service is container-ready through Dockerfile, but no GCP deployment is claimed here. A GCP project, billing/free-tier choice, region, and authenticated gcloud account must be confirmed before an external deployment is performed. JSON state on local disk is suitable for a demo, not a multi-instance Cloud Run deployment without a durable datastore.
hooks/token-weather.mjs 88 lines1// Token Weather, from "Getting started with Claude Code mods"
2// (https://claude.dev/blog/getting-started-with-claude-code-mods/, Anthropic, 2026-10-01).
3// The published module, unchanged.
4
5// Token Weather: a live forecast of the context window, above the prompt.
6
7const HISTORY = 12;
8const BARS = "▁▂▃▄▅▆▇█";
9const FORECAST = [
10 { upTo: 25, icon: "☀", word: "Clear", color: "yellow" },
11 { upTo: 50, icon: "☁", word: "Cloudy", color: "cyan" },
12 { upTo: 75, icon: "☂", word: "Showers", color: "blue" },
13 { upTo: 90, icon: "☇", word: "Storm", color: "magenta" },
14 { upTo: Infinity, icon: "↯", word: "Compact soon", color: "red" },
15];
16
17// Held by the host, so the history survives a hot reload of this file.
18const readings = { plugin: "token-weather", key: "readings" };
19
20export function register(on) {
21 on("session.start", async ($, e, next) => {
22 const result = await next(e);
23 await takeReading($);
24 return result;
25 });
26
27 on("turn.complete", async ($, e, next) => {
28 const result = await next(e);
29 if (!e.agentId) {
30 await takeReading($); // main-loop turns only, not subagents
31 }
32 return result;
33 });
34
35 on("ui.render", { component: "AbovePrompt" }, async ($, e, next) => {
36 const { value: history = [] } = await $.state.get(readings);
37 if (e.props.hasSurvey || history.length === 0) {
38 return next(e);
39 }
40 const { Box, Text } = $.ui.resolve(e);
41 return band(Box, Text, history, e.props.bodyColumns);
42 });
43}
44
45async function takeReading($) {
46 const { context } = await $.session.usage();
47 if (!context?.window) return;
48 const tokens = context.tokens ?? 0;
49 const percent = context.percent ?? Math.round((tokens / context.window) * 100);
50 const { value: history = [] } = await $.state.get(readings);
51 await $.state.set(readings, [...history, { tokens, window: context.window, percent }].slice(-HISTORY));
52}
53
54function band(Box, Text, history, columns) {
55 const now = history[history.length - 1];
56 const f = FORECAST.find((b) => now.percent < b.upTo);
57 const parts = [
58 Text({ color: f.color, bold: true, children: `${f.icon} ${f.word}` }),
59 Text({ children: ` ${now.percent}% of context` }),
60 Text({ dimColor: true, children: ` ${short(now.tokens)} / ${short(now.window)}` }),
61 ];
62 if (columns >= 60) {
63 parts.push(Text({ dimColor: true, children: " last turns " }));
64 parts.push(Text({ color: f.color, children: sparkline(history) }));
65 if (history.length > 1) {
66 parts.push(Text({ dimColor: true, children: trend(history) }));
67 }
68 }
69 return Box({ flexDirection: "row", paddingX: 1, children: parts });
70}
71
72function sparkline(history) {
73 const top = Math.max(...history.map((r) => r.tokens), 1);
74 return history.map((r) => BARS[Math.floor((r.tokens / top) * (BARS.length - 1))]).join("");
75}
76
77function trend(history) {
78 const delta = history[history.length - 1].tokens - history[history.length - 2].tokens;
79 if (delta === 0) return " steady";
80 return delta > 0 ? ` ▲ +${short(delta)} last turn` : ` ▼ ${short(-delta)} last turn`;
81}
82
83function short(n) {
84 if (n >= 1_000_000) return `${+(n / 1_000_000).toFixed(1)}M`;
85 if (n >= 1_000) return `${+(n / 1_000).toFixed(1)}k`;
86 return String(n);
87}
88types/index.d.ts 11 lines1// Token Weather's type contract, from https://claude.dev/blog/getting-started-with-claude-code-mods/
2// (Anthropic, 2026-10-01). The published file, unchanged.
3
4export type TokenWeatherReading = { tokens: number; window: number; percent: number }
5
6declare module 'claude-code' {
7 interface PluginState {
8 'token-weather': { readings: TokenWeatherReading[] }
9 }
10}
11