@azure-id/orc 1.9.2 → 2.1.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 +722 -0
- package/README-id.md +56 -42
- package/README.md +58 -41
- package/bin/build-agents.js +125 -29
- package/bin/clear-logs.js +620 -0
- package/bin/cli.js +1873 -180
- package/bin/fix.js +459 -0
- package/bin/gotcha-import.js +1081 -0
- package/bin/gotcha.js +1566 -0
- package/bin/graph-query.js +1 -1
- package/bin/graph.js +717 -717
- package/bin/habit.js +1538 -0
- package/bin/mockrun-catalog.js +284 -276
- package/bin/onboarding-content.js +2 -1
- package/bin/pricing.json +28 -21
- package/bin/run-undo.js +398 -0
- package/bin/trace-write.js +869 -0
- package/bin/verify-contracts.js +627 -100
- package/bin/verify-package.js +68 -10
- package/bin/webui/api.js +151 -6
- package/bin/webui/app.html +239 -232
- package/bin/webui/css/00-tokens.css +110 -92
- package/bin/webui/css/04-motion.css +87 -0
- package/bin/webui/css/06-responsive.css +203 -178
- package/bin/webui/css/panels/behaviour.css +205 -0
- package/bin/webui/css/panels/hookui.css +79 -0
- package/bin/webui/fixtures/behaviour.js +562 -0
- package/bin/webui/fixtures/extra.js +9 -9
- package/bin/webui/fixtures/flow.js +81 -81
- package/bin/webui/fixtures/hookui.js +506 -431
- package/bin/webui/fixtures/index.js +66 -3
- package/bin/webui/fixtures/knowledge.js +9 -3
- package/bin/webui/fixtures/maintenance.js +123 -42
- package/bin/webui/fixtures/rules.js +1007 -1002
- package/bin/webui/fixtures/settings.js +6 -7
- package/bin/webui/fixtures/stats.js +25 -6
- package/bin/webui/fixtures/wait.js +98 -97
- package/bin/webui/i18n/en/behaviour.json +156 -0
- package/bin/webui/i18n/en/hookui.json +290 -194
- package/bin/webui/i18n/en/maintenance.json +71 -52
- package/bin/webui/i18n/en/nav.json +25 -24
- package/bin/webui/i18n/en/settings.json +60 -60
- package/bin/webui/i18n/en/tour.json +37 -35
- package/bin/webui/i18n/id/behaviour.json +156 -0
- package/bin/webui/i18n/id/hookui.json +290 -194
- package/bin/webui/i18n/id/maintenance.json +71 -52
- package/bin/webui/i18n/id/nav.json +25 -24
- package/bin/webui/i18n/id/settings.json +60 -60
- package/bin/webui/i18n/id/tour.json +37 -35
- package/bin/webui/js/01-i18n.js +155 -154
- package/bin/webui/js/05-banners.js +181 -172
- package/bin/webui/js/06-edit.js +193 -183
- package/bin/webui/js/90-tour.js +498 -494
- package/bin/webui/js/91-shortcuts.js +126 -126
- package/bin/webui/js/99-boot.js +121 -118
- package/bin/webui/js/panels/behaviour.js +1087 -0
- package/bin/webui/js/panels/hookui.js +2196 -1691
- package/bin/webui/js/panels/maintenance.js +336 -235
- package/bin/webui/js/panels/settings.js +726 -719
- package/mock-run/INDEX.md +110 -107
- package/mock-run/extra-slots.md +1 -1
- package/mock-run/gotcha-import.md +118 -0
- package/mock-run/habits.md +129 -0
- package/mock-run/orc-aftermath.md +392 -392
- package/mock-run/orc-budget.md +29 -33
- package/mock-run/orc-cli.md +200 -200
- package/mock-run/orc-explain.md +86 -86
- package/mock-run/orc-extra.md +389 -392
- package/mock-run/orc-fix.md +87 -0
- package/mock-run/orc-pattern.md +112 -112
- package/mock-run/orc-quick.md +6 -1
- package/mock-run/orc.md +157 -157
- package/package.json +1 -1
- package/templates/agents/MODEL-MAPPING.md +37 -34
- package/templates/agents/orc-advisor-opus-5-xhigh.md +1 -7
- package/templates/agents/orc-analyze-mini-opus-5-med.md +1 -6
- package/templates/agents/orc-analyze-mini-sonnet-5-high.md +2 -5
- package/templates/agents/{orc-claude-writer-opus-4-8-high.md → orc-claude-writer-opus-5-low.md} +48 -53
- package/templates/agents/orc-context-combiner-opus-5-high.md +1 -11
- package/templates/agents/orc-executor-haiku-4-5.md +14 -6
- package/templates/agents/orc-executor-opus-4-7-high.md +14 -6
- package/templates/agents/orc-executor-opus-4-7-med.md +14 -6
- package/templates/agents/orc-executor-opus-4-8-high.md +14 -6
- package/templates/agents/orc-executor-opus-5-high.md +14 -6
- package/templates/agents/orc-executor-opus-5-low.md +14 -6
- package/templates/agents/orc-executor-opus-5-med.md +14 -6
- package/templates/agents/orc-executor-sonnet-4-6-high.md +14 -6
- package/templates/agents/orc-executor-sonnet-4-6-med.md +14 -6
- package/templates/agents/orc-executor-sonnet-5-high.md +15 -7
- package/templates/agents/orc-executor-sonnet-5-low.md +155 -0
- package/templates/agents/orc-executor-sonnet-5-med.md +155 -0
- package/templates/agents/orc-graph-noter-sonnet-4-6-med.md +1 -10
- package/templates/agents/orc-judge-opus-5-xhigh.md +5 -9
- package/templates/agents/orc-learn-writer-opus-5-low.md +1 -7
- package/templates/agents/orc-pattern-codifier-opus-5-med.md +1 -8
- package/templates/agents/orc-pattern-codifier-sonnet-5-high.md +58 -63
- package/templates/agents/orc-planner-mini-opus-5-med.md +1 -4
- package/templates/agents/orc-planner-mini-sonnet-5-high.md +2 -3
- package/templates/agents/orc-planner-opus-5-med.md +1 -4
- package/templates/agents/orc-recon-opus-5-low.md +1 -8
- package/templates/agents/orc-recon-sonnet-4-6-med.md +1 -8
- package/templates/agents/orc-retro-opus-5-med.md +6 -8
- package/templates/agents/orc-retro-sonnet-5-high.md +7 -8
- package/templates/agents/orc-reviewer-opus-5-low.md +96 -0
- package/templates/agents/orc-scout-opus-5-low.md +1 -6
- package/templates/agents/orc-scout-sonnet-4-6-high.md +35 -39
- package/templates/agents/orc-system-analyst-opus-5-high.md +1 -6
- package/templates/agents/orc-test-author-opus-5-med.md +4 -5
- package/templates/agents/orc-trace-writer-haiku-4-5.md +3 -7
- package/templates/agents/orc-verifier-opus-5-med.md +16 -8
- package/templates/agents/{orc-wiki-scanner-opus-4-8-high.md → orc-wiki-scanner-opus-5-low.md} +74 -79
- package/templates/agents/orc-wiki-scanner-sonnet-5-high.md +97 -106
- package/templates/commands/orc-analyze.md +13 -21
- package/templates/commands/orc-fast.md +10 -15
- package/templates/commands/orc-fix.md +18 -0
- package/templates/commands/orc-poly.md +12 -21
- package/templates/commands/orc-pr-driver.md +11 -30
- package/templates/commands/orc-pr-setup.md +10 -31
- package/templates/commands/orc-route.md +11 -41
- package/templates/commands/orc-test.md +5 -60
- package/templates/commands/orc-wiki.md +64 -64
- package/templates/hooks/README.md +109 -7
- package/templates/hooks/orc-session-hook.js +339 -0
- package/templates/hooks/orc-statusline-render.js +317 -23
- package/templates/hooks/orc-statusline.js +165 -50
- package/templates/hooks/orc-subagent-line.js +23 -5
- package/templates/hooks/orc-weather-fetch.js +123 -0
- package/templates/skills/_shared/README.md +9 -0
- package/templates/skills/_shared/code-graph.md +47 -55
- package/templates/skills/_shared/config-precedence.md +3 -1
- package/templates/skills/_shared/extra-dispatch.md +78 -93
- package/templates/skills/_shared/gotchas.md +248 -177
- package/templates/skills/_shared/habits.md +101 -0
- package/templates/skills/_shared/lane-contract.md +84 -0
- package/templates/skills/_shared/opus5-only.md +14 -14
- package/templates/skills/_shared/phases/README.md +142 -83
- package/templates/skills/_shared/phases/analyst-gates.md +10 -21
- package/templates/skills/_shared/phases/execution.md +8 -14
- package/templates/skills/_shared/phases/house-rules.md +27 -32
- package/templates/skills/_shared/phases/intake.md +127 -133
- package/templates/skills/_shared/phases/mock-example.md +46 -56
- package/templates/skills/_shared/phases/plan-handoff.md +91 -97
- package/templates/skills/_shared/phases/planning.md +7 -17
- package/templates/skills/_shared/phases/preflight.md +19 -42
- package/templates/skills/_shared/phases/review.md +24 -28
- package/templates/skills/_shared/phases/rules.md +18 -42
- package/templates/skills/_shared/phases/scoring.md +55 -65
- package/templates/skills/_shared/phases/security-checklist.md +46 -50
- package/templates/skills/_shared/phases/security.md +45 -55
- package/templates/skills/_shared/phases/ship.md +6 -15
- package/templates/skills/_shared/phases/stop-resume.md +2 -5
- package/templates/skills/_shared/phases/summary.md +73 -48
- package/templates/skills/_shared/phases/testgen.md +41 -51
- package/templates/skills/_shared/phases/trace-verbs.md +447 -0
- package/templates/skills/_shared/phases/trace.md +66 -297
- package/templates/skills/_shared/phases/verify.md +62 -70
- package/templates/skills/_shared/phases/wave-grouping.md +128 -133
- package/templates/skills/_shared/phases/wiki-consult.md +10 -6
- package/templates/skills/_shared/read-ladder.md +2 -55
- package/templates/skills/_shared/return-validation.md +17 -70
- package/templates/skills/_shared/review-slice.md +106 -0
- package/templates/skills/_shared/smoke-gate.md +46 -28
- package/templates/skills/_shared/wait.md +1 -0
- package/templates/skills/context-combiner/SKILL.md +15 -44
- package/templates/skills/orc/README.md +2 -2
- package/templates/skills/orc/SKILL.md +35 -63
- package/templates/skills/orc/config.md +25 -27
- package/templates/skills/orc/examples/full-run-mock.md +2 -1
- package/templates/skills/orc/references/effort-and-mode.md +17 -17
- package/templates/skills/orc/references/pattern-gate.md +89 -89
- package/templates/skills/orc/references/phases/intake.md +41 -47
- package/templates/skills/orc/references/phases/integration.md +13 -19
- package/templates/skills/orc/references/preflight-report.md +11 -12
- package/templates/skills/orc/references/ultra-mode.md +9 -7
- package/templates/skills/orc/schemas/checkpoint.md +122 -122
- package/templates/skills/orc/subskills/orc-execution/SKILL.md +27 -73
- package/templates/skills/orc/subskills/orc-execution/core.md +12 -99
- package/templates/skills/orc/subskills/orc-execution/subagent.md +14 -13
- package/templates/skills/orc/subskills/orc-review-verify/SKILL.md +12 -53
- package/templates/skills/orc/subskills/orc-review-verify/core.md +52 -135
- package/templates/skills/orc/subskills/orc-review-verify/subagent.md +7 -7
- package/templates/skills/orc/subskills/orc-testgen/SKILL.md +11 -22
- package/templates/skills/orc/subskills/orc-testgen/core.md +20 -59
- package/templates/skills/orc/subskills/orc-testgen/subagent.md +7 -7
- package/templates/skills/orc-advisor/SKILL.md +56 -60
- package/templates/skills/orc-analyze/SKILL.md +33 -67
- package/templates/skills/orc-analyze/schemas/report-audit.md +2 -1
- package/templates/skills/orc-analyze/schemas/report-prose.md +2 -1
- package/templates/skills/orc-analyze-mini/SKILL.md +35 -70
- package/templates/skills/orc-claude/SKILL.md +14 -14
- package/templates/skills/orc-claude/examples/claude-run-mock.md +65 -65
- package/templates/skills/orc-diy/README.md +31 -0
- package/templates/skills/orc-diy/SKILL.md +27 -78
- package/templates/skills/orc-diy/references/blocks/pattern.md +18 -18
- package/templates/skills/orc-fast/SKILL.md +49 -75
- package/templates/skills/orc-fix/SKILL.md +110 -0
- package/templates/skills/orc-judge/SKILL.md +77 -82
- package/templates/skills/orc-mini/SKILL.md +64 -112
- package/templates/skills/orc-mini/examples/mini-run-mock.md +4 -2
- package/templates/skills/orc-pattern/SKILL.md +27 -48
- package/templates/skills/orc-poly/SKILL.md +32 -61
- package/templates/skills/orc-pr-driver/SKILL.md +25 -51
- package/templates/skills/orc-pr-driver/references/green-gate.md +113 -105
- package/templates/skills/orc-pr-setup/SKILL.md +20 -45
- package/templates/skills/orc-quick/README.md +44 -3
- package/templates/skills/orc-quick/SKILL.md +77 -108
- package/templates/skills/orc-quick/references/dispatch-gate.md +18 -6
- package/templates/skills/orc-quick/references/gh-mode.md +50 -1
- package/templates/skills/orc-quick/references/look.md +3 -1
- package/templates/skills/orc-retro/SKILL.md +20 -19
- package/templates/skills/orc-retro/examples/retro-mock.md +17 -17
- package/templates/skills/orc-route/SKILL.md +25 -45
- package/templates/skills/orc-test/SKILL.md +16 -37
- package/templates/skills/orc-verify/SKILL.md +14 -32
- package/templates/skills/orc-wait/SKILL.md +156 -163
- package/templates/skills/orc-wiki/README.md +325 -325
- package/templates/skills/orc-wiki/SKILL.md +195 -195
- package/templates/skills/orc-wiki/examples/wiki-run-mock.md +37 -37
- package/templates/skills/orc-wiki/references/extra.md +2 -2
- package/templates/skills/orc-wiki/references/partial-refresh.md +276 -271
- package/templates/skills/orc-wiki/references/phases/phase-0.md +2 -7
- package/templates/skills/orc-wiki/references/phases/phase-1.md +1 -6
- package/templates/skills/orc-wiki/references/phases/phase-2.md +4 -9
- package/templates/skills/orc-wiki/references/phases/phase-3.md +1 -6
- package/templates/skills/orc-wiki/references/phases/phase-3c.md +4 -8
- package/templates/agents/orc-claude-writer-opus-5-med.md +0 -55
- package/templates/agents/orc-reviewer-opus-5-med.md +0 -60
- package/templates/agents/orc-wiki-scanner-opus-5-med.md +0 -81
|
@@ -1,172 +1,181 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/* 05-banners.js — orc ui client
|
|
3
|
-
The shared version promise, the update banner, the changelog modal, and
|
|
4
|
-
renderBanners — including the global-install warning that must be visible on
|
|
5
|
-
EVERY panel (config does not merge, so a global install can win skill
|
|
6
|
-
resolution while this panel edits a project file nothing reads).
|
|
7
|
-
|
|
8
|
-
Loaded by app.html in the order its numeric prefix names. Classic
|
|
9
|
-
script, no import/export: an ES module import carries no query string,
|
|
10
|
-
and every static request here needs the per-launch session token. */
|
|
11
|
-
|
|
12
|
-
/* --------------------------------------------------------------- version -- */
|
|
13
|
-
// `orc version --json` performs a REAL bounded network check against the
|
|
14
|
-
// install source and reports {version, latest, update_available}. Three places
|
|
15
|
-
// want that answer — the Overview tile, the rail badge and the Maintenance
|
|
16
|
-
// upgrade row — so the promise is shared: one check per page load, not three.
|
|
17
|
-
// `refresh()` is the only way to force a second one, and it is a button the
|
|
18
|
-
// user presses; nothing here polls for a new release on its own.
|
|
19
|
-
let versionPromise = null;
|
|
20
|
-
const versionInfo = () => (versionPromise = versionPromise || read("/api/version").then((r) => r.data));
|
|
21
|
-
function refreshVersion() {
|
|
22
|
-
versionPromise = null;
|
|
23
|
-
return versionInfo();
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
// The one place that decides what a version payload MEANS, so the tile, the rail
|
|
27
|
-
// and the upgrade row can never disagree about it. `latest: null` is not "up to
|
|
28
|
-
// date" — it is "we could not tell", which is a different thing to show.
|
|
29
|
-
function versionState(v) {
|
|
30
|
-
if (!v) return { kind: "", label: t("version.unknown.label"), note: t("version.unknown.note") };
|
|
31
|
-
if (v.check_disabled) return { kind: "", label: t("version.off.label"), note: t("version.off.note") };
|
|
32
|
-
if (!v.latest) return { kind: "warn", label: t("version.offline.label"), note: t("version.offline.note") };
|
|
33
|
-
if (v.update_available)
|
|
34
|
-
return {
|
|
35
|
-
kind: "warn",
|
|
36
|
-
label: t("version.available.label", { latest: v.latest }),
|
|
37
|
-
note: t("version.available.note", { version: v.version }),
|
|
38
|
-
};
|
|
39
|
-
return {
|
|
40
|
-
kind: "ok",
|
|
41
|
-
label: t("version.current.label"),
|
|
42
|
-
// `install_spec` is CLI data (a package spec), so it is interpolated, never
|
|
43
|
-
// translated — only the sentence around it is ours.
|
|
44
|
-
note: t("version.current.note", { version: v.version, source: v.install_spec || "the install source" }),
|
|
45
|
-
};
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
/* ---------------------------------------------------------------- banners -- */
|
|
49
|
-
|
|
50
|
-
// The ONE thing that must be visible on every panel: config does NOT merge, so
|
|
51
|
-
// a global install can win skill resolution while this panel edits a project
|
|
52
|
-
// file nothing reads. Reported here, never fixed here — this UI never edits
|
|
53
|
-
// global config, by design.
|
|
54
|
-
// The update banner. It is a BUTTON, not a notice: the useful question is
|
|
55
|
-
// "what changed", and the answer is one click away rather than on GitHub.
|
|
56
|
-
async function renderUpdateBanner(host) {
|
|
57
|
-
let v;
|
|
58
|
-
try {
|
|
59
|
-
v = await versionInfo();
|
|
60
|
-
} catch (_) {
|
|
61
|
-
return;
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
const
|
|
68
|
-
|
|
69
|
-
inner
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
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
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
slot.append(el("div", "note", t("changelog.
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
slot.append(el("div", "note", t("changelog.
|
|
112
|
-
} else {
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
if (e.
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
//
|
|
155
|
-
//
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
/* 05-banners.js — orc ui client
|
|
3
|
+
The shared version promise, the update banner, the changelog modal, and
|
|
4
|
+
renderBanners — including the global-install warning that must be visible on
|
|
5
|
+
EVERY panel (config does not merge, so a global install can win skill
|
|
6
|
+
resolution while this panel edits a project file nothing reads).
|
|
7
|
+
|
|
8
|
+
Loaded by app.html in the order its numeric prefix names. Classic
|
|
9
|
+
script, no import/export: an ES module import carries no query string,
|
|
10
|
+
and every static request here needs the per-launch session token. */
|
|
11
|
+
|
|
12
|
+
/* --------------------------------------------------------------- version -- */
|
|
13
|
+
// `orc version --json` performs a REAL bounded network check against the
|
|
14
|
+
// install source and reports {version, latest, update_available}. Three places
|
|
15
|
+
// want that answer — the Overview tile, the rail badge and the Maintenance
|
|
16
|
+
// upgrade row — so the promise is shared: one check per page load, not three.
|
|
17
|
+
// `refresh()` is the only way to force a second one, and it is a button the
|
|
18
|
+
// user presses; nothing here polls for a new release on its own.
|
|
19
|
+
let versionPromise = null;
|
|
20
|
+
const versionInfo = () => (versionPromise = versionPromise || read("/api/version").then((r) => r.data));
|
|
21
|
+
function refreshVersion() {
|
|
22
|
+
versionPromise = null;
|
|
23
|
+
return versionInfo();
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// The one place that decides what a version payload MEANS, so the tile, the rail
|
|
27
|
+
// and the upgrade row can never disagree about it. `latest: null` is not "up to
|
|
28
|
+
// date" — it is "we could not tell", which is a different thing to show.
|
|
29
|
+
function versionState(v) {
|
|
30
|
+
if (!v) return { kind: "", label: t("version.unknown.label"), note: t("version.unknown.note") };
|
|
31
|
+
if (v.check_disabled) return { kind: "", label: t("version.off.label"), note: t("version.off.note") };
|
|
32
|
+
if (!v.latest) return { kind: "warn", label: t("version.offline.label"), note: t("version.offline.note") };
|
|
33
|
+
if (v.update_available)
|
|
34
|
+
return {
|
|
35
|
+
kind: "warn",
|
|
36
|
+
label: t("version.available.label", { latest: v.latest }),
|
|
37
|
+
note: t("version.available.note", { version: v.version }),
|
|
38
|
+
};
|
|
39
|
+
return {
|
|
40
|
+
kind: "ok",
|
|
41
|
+
label: t("version.current.label"),
|
|
42
|
+
// `install_spec` is CLI data (a package spec), so it is interpolated, never
|
|
43
|
+
// translated — only the sentence around it is ours.
|
|
44
|
+
note: t("version.current.note", { version: v.version, source: v.install_spec || "the install source" }),
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/* ---------------------------------------------------------------- banners -- */
|
|
49
|
+
|
|
50
|
+
// The ONE thing that must be visible on every panel: config does NOT merge, so
|
|
51
|
+
// a global install can win skill resolution while this panel edits a project
|
|
52
|
+
// file nothing reads. Reported here, never fixed here — this UI never edits
|
|
53
|
+
// global config, by design.
|
|
54
|
+
// The update banner. It is a BUTTON, not a notice: the useful question is
|
|
55
|
+
// "what changed", and the answer is one click away rather than on GitHub.
|
|
56
|
+
async function renderUpdateBanner(host, gen) {
|
|
57
|
+
let v;
|
|
58
|
+
try {
|
|
59
|
+
v = await versionInfo();
|
|
60
|
+
} catch (_) {
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
// A newer renderBanners call has cleared the host: do not add a second copy.
|
|
64
|
+
if (gen !== bannerGen) return;
|
|
65
|
+
if (!v || !v.update_available) return;
|
|
66
|
+
|
|
67
|
+
const b = el("button", "banner banner-update");
|
|
68
|
+
b.type = "button";
|
|
69
|
+
const inner = el("div");
|
|
70
|
+
inner.append(el("strong", null, t("banner.update.title", { latest: v.latest, version: v.version })));
|
|
71
|
+
inner.append(el("div", "note", t("banner.update.note")));
|
|
72
|
+
b.append(el("span", "banner-badge", "NEW"), inner, el("span", "banner-more", t("banner.update.cta")));
|
|
73
|
+
b.addEventListener("click", () => showChangelog(v));
|
|
74
|
+
host.append(b);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// Fetched lazily — the modal is what needs the changelog, and paying for that
|
|
78
|
+
// request on every page load to fill a box nobody opened is waste.
|
|
79
|
+
async function showChangelog(v) {
|
|
80
|
+
const body = el("div", "stack stack-sm");
|
|
81
|
+
const slot = el("div", "stack stack-sm");
|
|
82
|
+
slot.append(skeleton(4));
|
|
83
|
+
body.append(slot);
|
|
84
|
+
|
|
85
|
+
const close = modal({
|
|
86
|
+
title: t("changelog.title", { version: v.latest }),
|
|
87
|
+
body,
|
|
88
|
+
actions: [
|
|
89
|
+
{ label: t("common.later"), onClick: (c) => c() },
|
|
90
|
+
{
|
|
91
|
+
label: t("changelog.goUpgrade"),
|
|
92
|
+
cls: "btn-primary",
|
|
93
|
+
onClick: (c) => {
|
|
94
|
+
c();
|
|
95
|
+
location.hash = "#/maintenance";
|
|
96
|
+
// The spotlight is armed here and lands after the panel renders — a
|
|
97
|
+
// highlight fired now would point at a node that does not exist yet.
|
|
98
|
+
startUpgradeSpotlight();
|
|
99
|
+
},
|
|
100
|
+
},
|
|
101
|
+
],
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
try {
|
|
105
|
+
const d = (await read("/api/changelog")).data;
|
|
106
|
+
slot.replaceChildren();
|
|
107
|
+
if (d.check_disabled) {
|
|
108
|
+
slot.append(el("div", "note", t("changelog.disabled")));
|
|
109
|
+
} else if (!d.fetched) {
|
|
110
|
+
slot.append(el("div", "note", t("changelog.offline")));
|
|
111
|
+
slot.append(el("div", "note", t("changelog.offlineNote")));
|
|
112
|
+
} else if (!d.entries.length) {
|
|
113
|
+
slot.append(el("div", "note", t("changelog.empty")));
|
|
114
|
+
} else {
|
|
115
|
+
for (const e of d.entries) {
|
|
116
|
+
const sec = el("div", "cl-entry");
|
|
117
|
+
const h = el("div", "cl-head");
|
|
118
|
+
h.append(el("span", "cl-version", "v" + e.version));
|
|
119
|
+
if (e.date) h.append(el("span", "cl-date", e.date));
|
|
120
|
+
sec.append(h);
|
|
121
|
+
if (e.title) sec.append(el("div", "cl-title", stripMd(e.title)));
|
|
122
|
+
if (e.body) sec.append(el("div", "cl-body", reflowMd(stripMd(e.body))));
|
|
123
|
+
slot.append(sec);
|
|
124
|
+
}
|
|
125
|
+
slot.append(el("div", "note", t("changelog.source", { src: d.source })));
|
|
126
|
+
}
|
|
127
|
+
} catch (e) {
|
|
128
|
+
slot.replaceChildren(el("div", "note", t("changelog.loadFail", { err: e.message })));
|
|
129
|
+
}
|
|
130
|
+
return close;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
// The router calls this on every route, so two calls can overlap. Both banners
|
|
134
|
+
// are appended after an await, so only the NEWEST call may append (here and in
|
|
135
|
+
// renderUpdateBanner), or a banner shows twice.
|
|
136
|
+
let bannerGen = 0;
|
|
137
|
+
async function renderBanners() {
|
|
138
|
+
const gen = ++bannerGen;
|
|
139
|
+
const host = $("#banners");
|
|
140
|
+
host.replaceChildren();
|
|
141
|
+
renderUpdateBanner(host, gen);
|
|
142
|
+
let doctor;
|
|
143
|
+
try {
|
|
144
|
+
doctor = (await read("/api/doctor")).data;
|
|
145
|
+
} catch (_) {
|
|
146
|
+
return;
|
|
147
|
+
}
|
|
148
|
+
if (gen !== bannerGen) return;
|
|
149
|
+
if (!doctor) return;
|
|
150
|
+
const g = doctor.global_install || {};
|
|
151
|
+
if (g.present && g.shadows) {
|
|
152
|
+
const finding = (doctor.findings || []).find((f) => f.id === "global-skew" || f.id === "global-retired-agents");
|
|
153
|
+
const b = el("div", "banner");
|
|
154
|
+
// Prose inside the banner flex row, not a panel container: its lines are
|
|
155
|
+
// meant to read tight, so it is deliberately not a `stack`.
|
|
156
|
+
const bannerBody = el("div");
|
|
157
|
+
bannerBody.append(el("strong", null, t("banner.global.title")));
|
|
158
|
+
bannerBody.append(el("div", null, t("banner.global.body")));
|
|
159
|
+
// The finding's own text is the CLI speaking. It is shown verbatim in every
|
|
160
|
+
// language — a doctor message names files and commands.
|
|
161
|
+
if (finding) bannerBody.append(el("div", "note", finding.message));
|
|
162
|
+
// The command that actually clears the finding, copyable. This panel is
|
|
163
|
+
// project-scoped and never writes global config, so handing over the exact
|
|
164
|
+
// line to paste is the whole of what it can do — and a wrong line here is
|
|
165
|
+
// why the warning felt permanent.
|
|
166
|
+
// The global finding's OWN command — not the first fix of any finding.
|
|
167
|
+
const fixCmd = finding && finding.fix_command;
|
|
168
|
+
if (fixCmd) {
|
|
169
|
+
const row = el("div", "banner-fix");
|
|
170
|
+
row.append(el("code", "action-cmd", fixCmd));
|
|
171
|
+
const cp = el("button", "btn btn-ghost btn-sm", t("common.copy"));
|
|
172
|
+
cp.type = "button";
|
|
173
|
+
cp.addEventListener("click", () => copy(fixCmd, t("common.copied")));
|
|
174
|
+
row.append(cp);
|
|
175
|
+
bannerBody.append(row);
|
|
176
|
+
}
|
|
177
|
+
bannerBody.append(el("div", "note", t("banner.global.check")));
|
|
178
|
+
b.append(bannerBody);
|
|
179
|
+
host.append(b);
|
|
180
|
+
}
|
|
181
|
+
}
|