@azure-id/orc 1.8.1 → 1.9.0
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/CHANGELOG.md +386 -0
- package/README-id.md +110 -73
- package/README.md +96 -33
- package/bin/cli.js +45520 -44867
- package/bin/graph-extract.js +2409 -120
- package/bin/graph-gain.js +404 -0
- package/bin/graph-map.js +232 -0
- package/bin/graph-notes.js +49 -8
- package/bin/graph-query.js +1770 -808
- package/bin/graph-resolve.js +93 -16
- package/bin/graph-shard.js +325 -0
- package/bin/graph.js +658 -605
- package/bin/verify-contracts.js +297 -56
- package/bin/verify-package.js +29 -1
- package/bin/webui/api.js +6 -0
- package/bin/webui/fixtures/index.js +6 -1
- package/bin/webui/fixtures/knowledge.js +41 -1
- package/bin/webui/fixtures/stats.js +107 -104
- package/bin/webui/i18n/en/knowledge.json +16 -1
- package/bin/webui/i18n/id/knowledge.json +16 -1
- package/bin/webui/js/panels/knowledge.js +68 -3
- package/mock-run/orc-quick.md +141 -113
- package/package.json +1 -1
- package/templates/agents/MODEL-MAPPING.md +15 -5
- package/templates/agents/orc-executor-haiku-4-5.md +25 -13
- package/templates/agents/orc-executor-opus-4-7-high.md +25 -13
- package/templates/agents/orc-executor-opus-4-7-med.md +25 -13
- package/templates/agents/orc-executor-opus-4-8-high.md +25 -13
- package/templates/agents/orc-executor-opus-5-high.md +25 -13
- package/templates/agents/orc-executor-opus-5-low.md +25 -13
- package/templates/agents/orc-executor-opus-5-med.md +25 -13
- package/templates/agents/orc-executor-sonnet-4-6-high.md +25 -13
- package/templates/agents/orc-executor-sonnet-4-6-med.md +25 -13
- package/templates/agents/orc-executor-sonnet-5-high.md +25 -13
- package/templates/agents/orc-graph-noter-sonnet-4-6-med.md +15 -12
- package/templates/agents/orc-planner-mini-opus-5-med.md +75 -69
- package/templates/agents/orc-planner-mini-sonnet-5-high.md +73 -67
- package/templates/agents/orc-recon-opus-5-low.md +99 -0
- package/templates/agents/orc-recon-sonnet-4-6-med.md +99 -0
- package/templates/commands/orc-mini.md +10 -12
- package/templates/commands/orc-quick.md +20 -33
- package/templates/hooks/README.md +13 -3
- package/templates/hooks/orc-graph-hook.js +148 -13
- package/templates/hooks/orc-trace.js +476 -471
- package/templates/skills/_shared/code-graph.md +148 -20
- package/templates/skills/_shared/phases/execution.md +13 -11
- package/templates/skills/_shared/phases/planning.md +8 -1
- package/templates/skills/_shared/phases/rules.md +172 -159
- package/templates/skills/_shared/phases/ship.md +5 -1
- package/templates/skills/_shared/phases/trace.md +4 -1
- package/templates/skills/_shared/phases/wiki-consult.md +10 -6
- package/templates/skills/_shared/read-ladder.md +10 -2
- package/templates/skills/_shared/return-validation.md +22 -0
- package/templates/skills/context-combiner/SKILL.md +13 -13
- package/templates/skills/orc/SKILL.md +1 -1
- package/templates/skills/orc/subskills/orc-execution/core.md +171 -159
- package/templates/skills/orc-analyze/SKILL.md +13 -13
- package/templates/skills/orc-diy/references/flow-schema.md +1 -1
- package/templates/skills/orc-mini/SKILL.md +148 -136
- package/templates/skills/orc-mini/examples/mini-run-mock.md +64 -50
- package/templates/skills/orc-mini/references/complexity.md +105 -0
- package/templates/skills/orc-quick/README.md +495 -423
- package/templates/skills/orc-quick/SKILL.md +157 -211
- package/templates/skills/orc-quick/references/context-doc.md +145 -114
- package/templates/skills/orc-quick/references/defect.md +101 -0
- package/templates/skills/orc-quick/references/dispatch-gate.md +55 -24
- package/templates/skills/orc-quick/references/gh-mode.md +148 -127
- package/templates/skills/orc-quick/references/look.md +107 -0
- package/templates/skills/orc-wiki/references/staleness.md +1 -1
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
// case here; it is never an edit to a 1 700-line module.
|
|
22
22
|
const { PROJECT, doctor, where } = require("./shell.js");
|
|
23
23
|
const { config } = require("./settings.js");
|
|
24
|
-
const { wiki, wikiDocs, wikiShow, wikiCoverage, wikiCoverageFull, wikiUnregistered, wikiPlan, wikiDebt, wikiUsage, patterns, patternShow, gotchas, gotchasArchived, gotchaPrunePreview, wikiImpact, graph } = require("./knowledge.js");
|
|
24
|
+
const { wiki, wikiDocs, wikiShow, wikiCoverage, wikiCoverageFull, wikiUnregistered, wikiPlan, wikiDebt, wikiUsage, patterns, patternShow, gotchas, gotchasArchived, gotchaPrunePreview, wikiImpact, graph, graphGain, graphGainMeasured } = require("./knowledge.js");
|
|
25
25
|
const { runs, runDetail, runDetailClosed, aftermath } = require("./runs.js");
|
|
26
26
|
const { stats, budgetForecast, budgetRates } = require("./stats.js");
|
|
27
27
|
const { pact } = require("./pact.js");
|
|
@@ -309,6 +309,11 @@ module.exports.get = function get(route, q) {
|
|
|
309
309
|
// v1.8.0 — the code graph, DRIFTED (the state the card must be designed for).
|
|
310
310
|
case "/api/graph":
|
|
311
311
|
return graph;
|
|
312
|
+
// v1.8.2 W4b — the gain meter, and the A/B behind its second button.
|
|
313
|
+
case "/api/graph/gain":
|
|
314
|
+
return graphGain;
|
|
315
|
+
case "/api/graph/gain/measured":
|
|
316
|
+
return graphGainMeasured;
|
|
312
317
|
case "/api/patterns":
|
|
313
318
|
return patterns;
|
|
314
319
|
case "/api/gotchas":
|
|
@@ -313,4 +313,44 @@ const graph = {
|
|
|
313
313
|
trace: "GRAPH-CONSULT drifted :: files=1920 symbols=5896 gen=42",
|
|
314
314
|
};
|
|
315
315
|
|
|
316
|
-
|
|
316
|
+
// v1.8.2 W4b — `orc graph gain --json`. The fixture carries the ESTIMATE word
|
|
317
|
+
// and a RANGE, because those are the two things the card must never lose.
|
|
318
|
+
const graphGain = {
|
|
319
|
+
ok: true,
|
|
320
|
+
state: "rows",
|
|
321
|
+
scope: "project",
|
|
322
|
+
run: null,
|
|
323
|
+
since: null,
|
|
324
|
+
calls_recorded: 41,
|
|
325
|
+
runs: 6,
|
|
326
|
+
generation_range: [38, 42],
|
|
327
|
+
paid: { card: 4120, source: 610, hints: 182, total: 4912 },
|
|
328
|
+
avoided: { low: 18900, high: 71400 },
|
|
329
|
+
calls: { low: 58, high: 113 },
|
|
330
|
+
net: { low: 13988, high: 66488 },
|
|
331
|
+
by_command: { ctx: 29, impact: 6, changes: 4, "for-slice": 2 },
|
|
332
|
+
hints: { injected: 11, read_notes: 3, updates: 9 },
|
|
333
|
+
estimate: true,
|
|
334
|
+
carry_note:
|
|
335
|
+
"a card is re-sent on every later turn of the agent that received it — and so is the read it replaced. Both halves carry the same multiplier, so these are FIRST-ENTRY tokens on both sides (eval/graph-replay.js).",
|
|
336
|
+
};
|
|
337
|
+
|
|
338
|
+
// The A/B, with enough runs in both groups to print a comparison.
|
|
339
|
+
const graphGainMeasured = {
|
|
340
|
+
ok: true,
|
|
341
|
+
state: "compared",
|
|
342
|
+
min_runs: 3,
|
|
343
|
+
corpus: { dir: "~/.claude/projects/-home-dev-shop", ok: true },
|
|
344
|
+
runs: { on: 6, off: 4 },
|
|
345
|
+
rows: { on: [], off: [] },
|
|
346
|
+
compare: {
|
|
347
|
+
exec_retrieval_calls: { on: { n: 6, median: 19, min: 12, max: 27 }, off: { n: 4, median: 31, min: 24, max: 39 }, delta_pct: -39, off_spread_pct: 48 },
|
|
348
|
+
exec_bash_searches: { on: { n: 6, median: 2, min: 0, max: 5 }, off: { n: 4, median: 3, min: 1, max: 6 }, delta_pct: -33, off_spread_pct: 167 },
|
|
349
|
+
exec_result_tokens: { on: { n: 6, median: 27900, min: 18200, max: 41800 }, off: { n: 4, median: 41200, min: 29100, max: 60300 }, delta_pct: -32, off_spread_pct: 76 },
|
|
350
|
+
session_result_tokens: { on: { n: 6, median: 188000, min: 141000, max: 244000 }, off: { n: 4, median: 187000, min: 132000, max: 251000 }, delta_pct: 1, off_spread_pct: 64 },
|
|
351
|
+
},
|
|
352
|
+
note:
|
|
353
|
+
"executor windows and session totals are kept apart: the main session is 74–80% of a run and the graph never touches it. Every delta is printed beside the OFF group's own spread — a delta smaller than that spread is noise, not a result.",
|
|
354
|
+
};
|
|
355
|
+
|
|
356
|
+
module.exports = { wiki, wikiDocs, wikiShow, wikiCoverage, wikiCoverageFull, wikiUnregistered, wikiPlan, wikiDebt, wikiUsage, patterns, patternShow, gotchas, gotchasArchived, gotchaPrunePreview, wikiImpact, graph, graphGain, graphGainMeasured };
|
|
@@ -1,104 +1,107 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/* fixtures/stats.js — canned data for `orc ui --fixtures`.
|
|
3
|
-
Usage, the cost forecast and the dated rate table. The forecast is a RANGE
|
|
4
|
-
with a sample count, and cache-read is its own segment.
|
|
5
|
-
|
|
6
|
-
THE RULE FOR EVERY FILE IN HERE: carry ONE OF EVERY STATE, including the
|
|
7
|
-
ugly ones. You cannot DESIGN a STALE chip on a fresh wiki, and a state
|
|
8
|
-
with no fixture is a state nobody has ever looked at. A per-state count
|
|
9
|
-
test asserts this, so a new state cannot ship without one.
|
|
10
|
-
|
|
11
|
-
Shapes MUST match what `bin/cli.js --json` really emits — a drifted
|
|
12
|
-
fixture is worse than no fixture. */
|
|
13
|
-
|
|
14
|
-
const { PROJECT } = require("./shell.js");
|
|
15
|
-
|
|
16
|
-
const stats = {
|
|
17
|
-
log_dir: PROJECT + "/.claude/orc/logs",
|
|
18
|
-
runs: 61,
|
|
19
|
-
from: "2026-04-11",
|
|
20
|
-
to: "2026-08-08",
|
|
21
|
-
lanes: { orc: 22, quick: 17, mini: 9, wiki: 6, fast: 4, ultra: 2, grill: 1 },
|
|
22
|
-
agents: { "orc-executor": 88, "orc-system-analyst": 21, "orc-planner": 21, "orc-reviewer": 18, "orc-verifier": 18, "orc-scout": 12, "orc-wiki-scanner": 9, "orc-trace-writer": 61 },
|
|
23
|
-
dispatches: 248,
|
|
24
|
-
downgrades: 3,
|
|
25
|
-
unfinished: 2,
|
|
26
|
-
unknown_lane: 1,
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
{ band: "[90
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
{
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
{ lane: "
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
"[
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
"
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
/* fixtures/stats.js — canned data for `orc ui --fixtures`.
|
|
3
|
+
Usage, the cost forecast and the dated rate table. The forecast is a RANGE
|
|
4
|
+
with a sample count, and cache-read is its own segment.
|
|
5
|
+
|
|
6
|
+
THE RULE FOR EVERY FILE IN HERE: carry ONE OF EVERY STATE, including the
|
|
7
|
+
ugly ones. You cannot DESIGN a STALE chip on a fresh wiki, and a state
|
|
8
|
+
with no fixture is a state nobody has ever looked at. A per-state count
|
|
9
|
+
test asserts this, so a new state cannot ship without one.
|
|
10
|
+
|
|
11
|
+
Shapes MUST match what `bin/cli.js --json` really emits — a drifted
|
|
12
|
+
fixture is worse than no fixture. */
|
|
13
|
+
|
|
14
|
+
const { PROJECT } = require("./shell.js");
|
|
15
|
+
|
|
16
|
+
const stats = {
|
|
17
|
+
log_dir: PROJECT + "/.claude/orc/logs",
|
|
18
|
+
runs: 61,
|
|
19
|
+
from: "2026-04-11",
|
|
20
|
+
to: "2026-08-08",
|
|
21
|
+
lanes: { orc: 22, quick: 17, mini: 9, wiki: 6, fast: 4, ultra: 2, grill: 1 },
|
|
22
|
+
agents: { "orc-executor": 88, "orc-system-analyst": 21, "orc-planner": 21, "orc-reviewer": 18, "orc-verifier": 18, "orc-scout": 12, "orc-wiki-scanner": 9, "orc-trace-writer": 61 },
|
|
23
|
+
dispatches: 248,
|
|
24
|
+
downgrades: 3,
|
|
25
|
+
unfinished: 2,
|
|
26
|
+
unknown_lane: 1,
|
|
27
|
+
// v1.8.2 W4b — the code-graph row. `paid` is exact; the avoided pair is an
|
|
28
|
+
// ESTIMATE and always a RANGE, which is why the panel never shows one number.
|
|
29
|
+
graph: { calls: 41, runs: 6, paid: 4912, avoided_low: 18900, avoided_high: 71400, estimate: true },
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
/* ============================================================ v0.46.0 ====== */
|
|
33
|
+
/* Same rule as everything above: ONE OF EVERY STATE, including the ugly ones.
|
|
34
|
+
You cannot design a BROKEN promise card on a ledger where everything holds,
|
|
35
|
+
a REFUSE checklist on a repo with no refusals, or an empty-debt Knowledge
|
|
36
|
+
panel on a wiki that owes four docs. test/webui.test.js asserts the count per
|
|
37
|
+
state, so a new state cannot ship without a fixture. */
|
|
38
|
+
|
|
39
|
+
const budgetForecast = {
|
|
40
|
+
ok: true,
|
|
41
|
+
plan: PROJECT + "/.claude/orc/run/store-credit/plan.md",
|
|
42
|
+
tasks: 14,
|
|
43
|
+
waves: 5,
|
|
44
|
+
tokens: {
|
|
45
|
+
p50: { input: 53400, cache_write: 362800, cache_read: 733800, output: 75100 },
|
|
46
|
+
p90: { input: 81000, cache_write: 548000, cache_read: 1140000, output: 118000 },
|
|
47
|
+
},
|
|
48
|
+
raw: { p50: 1225100, p90: 1887000 },
|
|
49
|
+
weighted: { p50: 564680, p90: 861000 },
|
|
50
|
+
usd: { p50: 6.76, p90: 10.5 },
|
|
51
|
+
price_table: { as_of: "2026-08-01", age_days: 9, stale: false, path: "bin/pricing.json" },
|
|
52
|
+
quota: { available: true, plan: "max20", label: "Max 20x", window_pct: 18.2, weekly_pct: 4.1 },
|
|
53
|
+
// A task at CONTEXT RISK — the state that cannot be designed on a small plan.
|
|
54
|
+
context_risk: [{ task: "T12", agent: "orc-executor-opus-5-med", peak: 189000, window: 200000, pct: 95 }],
|
|
55
|
+
bands: [
|
|
56
|
+
{ band: "[0,30)", agent: "orc-executor-haiku-4-5", count: 2, tasks: ["T01", "T02"], samples: 9, p50: { input: 1200, cache_write: 6400, cache_read: 11800, output: 900 }, p90: { input: 1800, cache_write: 9200, cache_read: 17000, output: 1400 } },
|
|
57
|
+
{ band: "[40,55)", agent: "orc-executor-sonnet-4-6-high", count: 3, tasks: ["T03", "T05", "T07"], samples: 12, p50: { input: 7800, cache_write: 52100, cache_read: 104000, output: 8400 }, p90: { input: 11000, cache_write: 75000, cache_read: 150000, output: 12000 } },
|
|
58
|
+
{ band: "[65,90)", agent: "orc-executor-opus-5-low", count: 1, tasks: ["T04"], samples: 6, p50: { input: 5700, cache_write: 40200, cache_read: 81000, output: 9300 }, p90: { input: 8100, cache_write: 58000, cache_read: 117000, output: 13400 } },
|
|
59
|
+
// A band with insufficient history — the low-confidence warning is not
|
|
60
|
+
// optional chrome, so the fixture has to be able to trigger it.
|
|
61
|
+
{ band: "[90,100]", agent: "orc-executor-opus-5-med", count: 1, tasks: ["T12"], samples: 2, p50: { input: 9100, cache_write: 61000, cache_read: 128000, output: 17000 }, p90: { input: 14000, cache_write: 94000, cache_read: 198000, output: 26000 } },
|
|
62
|
+
],
|
|
63
|
+
fixed_roles: [
|
|
64
|
+
{ role: "orc-system-analyst-opus-5-high", samples: 11, p50: { input: 6100, cache_write: 41000, cache_read: 82000, output: 9000 }, p90: { input: 8600, cache_write: 58000, cache_read: 116000, output: 13000 } },
|
|
65
|
+
{ role: "orc-planner-opus-5-med", samples: 11, p50: { input: 5000, cache_write: 33000, cache_read: 68000, output: 7400 }, p90: { input: 7100, cache_write: 47000, cache_read: 96000, output: 10500 } },
|
|
66
|
+
{ role: "orc-trace-writer-haiku-4-5", samples: 41, p50: { input: 900, cache_write: 3000, cache_read: 5400, output: 700 }, p90: { input: 1300, cache_write: 4400, cache_read: 7800, output: 1000 } },
|
|
67
|
+
],
|
|
68
|
+
low_confidence_bands: 1,
|
|
69
|
+
min_samples: 5,
|
|
70
|
+
// Non-zero on purpose: `unattributed` is shown whenever it is above 0, and a
|
|
71
|
+
// fixture where it is always 0 makes that branch undesignable.
|
|
72
|
+
unattributed: { blocks: 12, tokens: { input: 900, cache_write: 12000, cache_read: 24000, output: 1100 } },
|
|
73
|
+
transcripts_readable: true,
|
|
74
|
+
lanes: [
|
|
75
|
+
{ lane: "ultra", cmd: "/orc-ultra", raw: 2410000, weighted: 1090000, usd: 14.2, low_confidence_bands: 1, low_confidence_roles: 0 },
|
|
76
|
+
{ lane: "orc", cmd: "/orc", raw: 1225100, weighted: 564680, usd: 6.76, low_confidence_bands: 1, low_confidence_roles: 0 },
|
|
77
|
+
{ lane: "mini", cmd: "/orc-mini", raw: 410000, weighted: 188000, usd: 2.1, low_confidence_bands: 0, low_confidence_roles: 0 },
|
|
78
|
+
{ lane: "fast", cmd: "/orc-fast", raw: 0, weighted: 0, usd: null, low_confidence_bands: 1, low_confidence_roles: 1 },
|
|
79
|
+
],
|
|
80
|
+
view: "auto",
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
const budgetRates = {
|
|
84
|
+
ok: true,
|
|
85
|
+
version: 1,
|
|
86
|
+
calibrated_at: "10-08-2026 09:40:11",
|
|
87
|
+
transcript_dir: "/home/you/.claude/projects/-example-project",
|
|
88
|
+
transcripts_readable: true,
|
|
89
|
+
transcript_files: 31,
|
|
90
|
+
traces_read: 42,
|
|
91
|
+
dispatches_joined: 96,
|
|
92
|
+
price_table_as_of: "2026-08-01",
|
|
93
|
+
bands: {
|
|
94
|
+
"[0,30)": { samples: 9, p50: { input: 1200, cache_write: 6400, cache_read: 11800, output: 900 }, p90: { input: 1800, cache_write: 9200, cache_read: 17000, output: 1400 }, peak_p50: 24000, peak_p90: 38000 },
|
|
95
|
+
"[40,55)": { samples: 12, p50: { input: 7800, cache_write: 52100, cache_read: 104000, output: 8400 }, p90: { input: 11000, cache_write: 75000, cache_read: 150000, output: 12000 }, peak_p50: 78000, peak_p90: 121000 },
|
|
96
|
+
"[70,80)": { samples: 6, p50: { input: 5700, cache_write: 40200, cache_read: 81000, output: 9300 }, p90: { input: 8100, cache_write: 58000, cache_read: 117000, output: 13400 }, peak_p50: 96000, peak_p90: 142000 },
|
|
97
|
+
"[90,100]": { samples: 2, p50: { input: 9100, cache_write: 61000, cache_read: 128000, output: 17000 }, p90: { input: 14000, cache_write: 94000, cache_read: 198000, output: 26000 }, peak_p50: 151000, peak_p90: 189000 },
|
|
98
|
+
},
|
|
99
|
+
roles: {
|
|
100
|
+
"orc-system-analyst-opus-5-high": { samples: 11, p50: { input: 6100, cache_write: 41000, cache_read: 82000, output: 9000 }, p90: { input: 8600, cache_write: 58000, cache_read: 116000, output: 13000 }, peak_p50: 88000, peak_p90: 131000 },
|
|
101
|
+
"orc-trace-writer-haiku-4-5": { samples: 41, p50: { input: 900, cache_write: 3000, cache_read: 5400, output: 700 }, p90: { input: 1300, cache_write: 4400, cache_read: 7800, output: 1000 }, peak_p50: 9000, peak_p90: 14000 },
|
|
102
|
+
},
|
|
103
|
+
lanes: {},
|
|
104
|
+
unattributed: { blocks: 12, tokens: { input: 900, cache_write: 12000, cache_read: 24000, output: 1100 } },
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
module.exports = { stats, budgetForecast, budgetRates };
|
|
@@ -163,5 +163,20 @@
|
|
|
163
163
|
"knowledge.wiki.unregistered": "The wiki is {state} — nothing can read it until it is registered.",
|
|
164
164
|
"knowledge.wiki.why": "why: {reason}",
|
|
165
165
|
"knowledge.graph.generation": "Generation",
|
|
166
|
-
"knowledge.graph.selfheal": "It keeps itself current: a read repairs the files it is about to answer for, and the installed hook updates the map when a worker finishes. Nothing runs on a timer."
|
|
166
|
+
"knowledge.graph.selfheal": "It keeps itself current: a read repairs the files it is about to answer for, and the installed hook updates the map when a worker finishes. Nothing runs on a timer.",
|
|
167
|
+
"knowledge.gain.none": "No graph reads recorded yet. The first `orc graph ctx` starts the ledger.",
|
|
168
|
+
"knowledge.gain.strip": "paid {paid} · avoided ~{low}–{high} (estimate) · {calls} calls",
|
|
169
|
+
"knowledge.gain.paid": "Tokens put in (cards · source · hints)",
|
|
170
|
+
"knowledge.gain.avoided": "Retrieval probably kept out (estimate)",
|
|
171
|
+
"knowledge.gain.net": "Net tokens · net tool calls",
|
|
172
|
+
"knowledge.gain.byCommand": "By command",
|
|
173
|
+
"knowledge.gain.hints": "Hints (injected · read notes · updates)",
|
|
174
|
+
"knowledge.gain.measure": "Compare my ON and OFF runs",
|
|
175
|
+
"knowledge.gain.estimate": "`avoided` is an estimate of the retrieval a read ladder would have paid for, never a bill. `paid` is exact.",
|
|
176
|
+
"knowledge.gain.measuredHead": "{on} runs with the graph on vs {off} with it off",
|
|
177
|
+
"knowledge.gain.measuredFew": "Too few runs to compare. Three runs in each group are needed; the rows are recorded and the comparison waits.",
|
|
178
|
+
"knowledge.gain.execCalls": "worker retrieval",
|
|
179
|
+
"knowledge.gain.execTokens": "worker tool results",
|
|
180
|
+
"knowledge.gain.sessionTokens": "session tool results",
|
|
181
|
+
"knowledge.gain.noise": "a change smaller than the spread beside it is noise, not a result"
|
|
167
182
|
}
|
|
@@ -163,5 +163,20 @@
|
|
|
163
163
|
"knowledge.wiki.unregistered": "Wiki berstatus {state} — tidak ada yang bisa membacanya sampai terdaftar.",
|
|
164
164
|
"knowledge.wiki.why": "sebab: {reason}",
|
|
165
165
|
"knowledge.graph.generation": "Generasi",
|
|
166
|
-
"knowledge.graph.selfheal": "Peta ini memperbarui dirinya: satu pembacaan memperbaiki berkas yang akan dijawabnya, dan hook yang terpasang memperbarui peta saat satu pekerja selesai. Tidak ada yang berjalan dengan pewaktu."
|
|
166
|
+
"knowledge.graph.selfheal": "Peta ini memperbarui dirinya: satu pembacaan memperbaiki berkas yang akan dijawabnya, dan hook yang terpasang memperbarui peta saat satu pekerja selesai. Tidak ada yang berjalan dengan pewaktu.",
|
|
167
|
+
"knowledge.gain.none": "Belum ada pembacaan grafik yang tercatat. `orc graph ctx` pertama memulai catatannya.",
|
|
168
|
+
"knowledge.gain.strip": "dibayar {paid} · dihindari ~{low}–{high} (perkiraan) · {calls} panggilan",
|
|
169
|
+
"knowledge.gain.paid": "Token yang dimasukkan (kartu · sumber · petunjuk)",
|
|
170
|
+
"knowledge.gain.avoided": "Pembacaan yang mungkin dihindari (perkiraan)",
|
|
171
|
+
"knowledge.gain.net": "Token bersih · panggilan alat bersih",
|
|
172
|
+
"knowledge.gain.byCommand": "Menurut perintah",
|
|
173
|
+
"knowledge.gain.hints": "Petunjuk (dikirim · catatan baca · pembaruan)",
|
|
174
|
+
"knowledge.gain.measure": "Bandingkan proses ON dan OFF saya",
|
|
175
|
+
"knowledge.gain.estimate": "`dihindari` adalah perkiraan pembacaan yang akan dibayar tangga baca, bukan tagihan. `dibayar` adalah angka pasti.",
|
|
176
|
+
"knowledge.gain.measuredHead": "{on} proses dengan grafik hidup vs {off} dengan grafik mati",
|
|
177
|
+
"knowledge.gain.measuredFew": "Terlalu sedikit proses untuk dibandingkan. Perlu tiga proses di tiap kelompok; barisnya tercatat dan perbandingannya menunggu.",
|
|
178
|
+
"knowledge.gain.execCalls": "pembacaan pekerja",
|
|
179
|
+
"knowledge.gain.execTokens": "hasil alat pekerja",
|
|
180
|
+
"knowledge.gain.sessionTokens": "hasil alat sesi",
|
|
181
|
+
"knowledge.gain.noise": "perubahan yang lebih kecil dari sebarannya adalah derau, bukan hasil"
|
|
167
182
|
}
|
|
@@ -35,7 +35,7 @@ let KN_TAB = "wiki";
|
|
|
35
35
|
|
|
36
36
|
async function renderKnowledge(body) {
|
|
37
37
|
body.replaceChildren(skeleton(6));
|
|
38
|
-
const [wikiRes, impactRes, patRes, gotRes, planRes, debtRes, usageRes, docsRes, covRes, refsRes, graphRes] = await Promise.all([
|
|
38
|
+
const [wikiRes, impactRes, patRes, gotRes, planRes, debtRes, usageRes, docsRes, covRes, refsRes, graphRes, gainRes] = await Promise.all([
|
|
39
39
|
read("/api/wiki").catch((e) => ({ data: null, error: e })),
|
|
40
40
|
read("/api/wiki/impact").catch((e) => ({ data: null, error: e })),
|
|
41
41
|
read("/api/patterns").catch((e) => ({ data: null, error: e })),
|
|
@@ -50,6 +50,9 @@ async function renderKnowledge(body) {
|
|
|
50
50
|
read("/api/wiki/refs").catch((e) => ({ data: null, error: e })),
|
|
51
51
|
// v1.8.0 — the code graph. `graph status` exits 0-3 and every code is DATA.
|
|
52
52
|
read("/api/graph").catch((e) => ({ data: null, error: e })),
|
|
53
|
+
// v1.8.2 W4b — the gain meter. Exit 1 (no ledger yet) is DATA, like every
|
|
54
|
+
// other read on this panel.
|
|
55
|
+
read("/api/graph/gain").catch((e) => ({ data: null, error: e })),
|
|
53
56
|
]);
|
|
54
57
|
const d = {
|
|
55
58
|
wiki: wikiRes.data || {},
|
|
@@ -63,6 +66,7 @@ async function renderKnowledge(body) {
|
|
|
63
66
|
coverage: covRes.data,
|
|
64
67
|
refs: refsRes.data,
|
|
65
68
|
graph: graphRes.data,
|
|
69
|
+
graphGain: gainRes.data,
|
|
66
70
|
// A read that FAILED is not the same as a read that came back empty, and
|
|
67
71
|
// rendering them identically is what turned a truncated 30 KB payload into
|
|
68
72
|
// "this repo has no wiki and no git" (v0.49.4). The server already puts the
|
|
@@ -145,7 +149,7 @@ function knowledgeHeaderStrip(d) {
|
|
|
145
149
|
the state word is never replaced by a friendlier synonym. An update is FREE
|
|
146
150
|
(parser only, no model), so it is a button; an OFF graph shows the one config
|
|
147
151
|
command that turns it on, because turning a feature on is the user's call. */
|
|
148
|
-
function graphCard(g, body) {
|
|
152
|
+
function graphCard(g, body, gain) {
|
|
149
153
|
const c = card(t("knowledge.graph.title"));
|
|
150
154
|
if (!g || !g.state) {
|
|
151
155
|
c.append(empty(t("knowledge.graph.unknown"), t("knowledge.graph.unknownHint")));
|
|
@@ -191,15 +195,76 @@ function graphCard(g, body) {
|
|
|
191
195
|
// click.
|
|
192
196
|
c.append(el("div", "note", t("knowledge.graph.selfheal")));
|
|
193
197
|
c.append(el("div", "note", t("knowledge.graph.locator")));
|
|
198
|
+
// K5 (v1.8.2 W4b) — the gain strip. It renders exactly the CLI's JSON and
|
|
199
|
+
// invents nothing: the word "estimate" is part of the string, never a
|
|
200
|
+
// tooltip, and `avoided` is a RANGE because one number for a counterfactual
|
|
201
|
+
// is the claim this whole meter refuses to make.
|
|
202
|
+
gainStrip(c, gain, body);
|
|
194
203
|
return c;
|
|
195
204
|
}
|
|
196
205
|
|
|
206
|
+
function gainStrip(c, g, body) {
|
|
207
|
+
if (!g || g.state !== "rows") {
|
|
208
|
+
c.append(el("div", "note", t("knowledge.gain.none")));
|
|
209
|
+
return;
|
|
210
|
+
}
|
|
211
|
+
c.append(
|
|
212
|
+
el(
|
|
213
|
+
"div",
|
|
214
|
+
"note",
|
|
215
|
+
t("knowledge.gain.strip")
|
|
216
|
+
.replace("{paid}", kTokUi(g.paid.total))
|
|
217
|
+
.replace("{low}", kTokUi(g.avoided.low))
|
|
218
|
+
.replace("{high}", kTokUi(g.avoided.high))
|
|
219
|
+
.replace("{calls}", String(g.calls_recorded))
|
|
220
|
+
)
|
|
221
|
+
);
|
|
222
|
+
c.append(
|
|
223
|
+
kvList([
|
|
224
|
+
[t("knowledge.gain.paid"), `${kTokUi(g.paid.total)} (${kTokUi(g.paid.card)} · ${kTokUi(g.paid.source)} · ${kTokUi(g.paid.hints)})`],
|
|
225
|
+
[t("knowledge.gain.avoided"), `~${kTokUi(g.avoided.low)} – ${kTokUi(g.avoided.high)}`],
|
|
226
|
+
[t("knowledge.gain.net"), `~${kTokUi(g.net.low)} – ${kTokUi(g.net.high)} · ~${g.calls.low} – ${g.calls.high}`],
|
|
227
|
+
[t("knowledge.gain.byCommand"), Object.entries(g.by_command).map(([k, v]) => `${k} ${v}`).join(" · ") || "—"],
|
|
228
|
+
[t("knowledge.gain.hints"), `${g.hints.injected} · ${g.hints.read_notes} · ${g.hints.updates}`],
|
|
229
|
+
])
|
|
230
|
+
);
|
|
231
|
+
const btn = el("button", "btn btn-sm", t("knowledge.gain.measure"));
|
|
232
|
+
btn.type = "button";
|
|
233
|
+
const out = el("div", "note");
|
|
234
|
+
btn.addEventListener("click", async () => {
|
|
235
|
+
btn.disabled = true;
|
|
236
|
+
const r = await read("/api/graph/gain/measured").catch(() => ({ data: null }));
|
|
237
|
+
btn.disabled = false;
|
|
238
|
+
out.textContent = measuredText(r && r.data);
|
|
239
|
+
});
|
|
240
|
+
c.append(btn);
|
|
241
|
+
c.append(out);
|
|
242
|
+
c.append(el("div", "note", t("knowledge.gain.estimate")));
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
// The A/B in words. Every delta carries its N and the OFF group's own spread,
|
|
246
|
+
// because a delta smaller than that spread is noise and the panel must say so
|
|
247
|
+
// in the same sentence, never in a footnote.
|
|
248
|
+
function measuredText(m) {
|
|
249
|
+
if (!m || !m.compare) return t("knowledge.gain.measuredFew");
|
|
250
|
+
const c = m.compare;
|
|
251
|
+
const row = (label, x, unit) =>
|
|
252
|
+
`${label} ${x.off.median} → ${x.on.median} ${unit} (${x.delta_pct > 0 ? "+" : ""}${x.delta_pct}%, N ${x.off.n}/${x.on.n}, OFF spread ±${x.off_spread_pct}%)`;
|
|
253
|
+
return [
|
|
254
|
+
t("knowledge.gain.measuredHead").replace("{on}", String(m.runs.on)).replace("{off}", String(m.runs.off)),
|
|
255
|
+
row(t("knowledge.gain.execCalls"), c.exec_retrieval_calls, "calls"),
|
|
256
|
+
row(t("knowledge.gain.execTokens"), c.exec_result_tokens, "tokens"),
|
|
257
|
+
row(t("knowledge.gain.sessionTokens"), c.session_result_tokens, "tokens"),
|
|
258
|
+
t("knowledge.gain.noise"),
|
|
259
|
+
].join(" · ");
|
|
260
|
+
}
|
|
261
|
+
|
|
197
262
|
/* ── TAB 1 — WIKI ────────────────────────────────────────────────────────── */
|
|
198
263
|
function knWikiTab(d, body) {
|
|
199
264
|
const out = frag();
|
|
200
265
|
out.append(wikiPlanCard(d.plan, d.debt, body));
|
|
201
266
|
out.append(wikiOneDocCard(d.refs));
|
|
202
|
-
out.append(graphCard(d.graph, body));
|
|
267
|
+
out.append(graphCard(d.graph, body, d.graphGain));
|
|
203
268
|
if (d.usage && d.usage.rows) out.append(wikiUsageCard(d.usage, body));
|
|
204
269
|
|
|
205
270
|
const w = d.wiki;
|