mossbear 0.1.0-alpha.28 → 0.1.0-alpha.30

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.
Files changed (187) hide show
  1. package/README.md +30 -10
  2. package/dist/commands/doctor.d.ts.map +1 -1
  3. package/dist/commands/doctor.js +61 -72
  4. package/dist/commands/doctor.js.map +1 -1
  5. package/dist/commands/guides/history.d.ts +72 -0
  6. package/dist/commands/guides/history.d.ts.map +1 -0
  7. package/dist/commands/guides/history.js +217 -0
  8. package/dist/commands/guides/history.js.map +1 -0
  9. package/dist/commands/guides/index.d.ts.map +1 -1
  10. package/dist/commands/guides/index.js +4 -0
  11. package/dist/commands/guides/index.js.map +1 -1
  12. package/dist/commands/init.d.ts +1 -0
  13. package/dist/commands/init.d.ts.map +1 -1
  14. package/dist/commands/init.js +138 -68
  15. package/dist/commands/init.js.map +1 -1
  16. package/dist/commands/link.d.ts +142 -0
  17. package/dist/commands/link.d.ts.map +1 -0
  18. package/dist/commands/link.js +272 -0
  19. package/dist/commands/link.js.map +1 -0
  20. package/dist/commands/mcp.d.ts.map +1 -1
  21. package/dist/commands/mcp.js +6 -4
  22. package/dist/commands/mcp.js.map +1 -1
  23. package/dist/commands/pull.d.ts +22 -0
  24. package/dist/commands/pull.d.ts.map +1 -1
  25. package/dist/commands/pull.js +190 -75
  26. package/dist/commands/pull.js.map +1 -1
  27. package/dist/commands/status.d.ts.map +1 -1
  28. package/dist/commands/status.js +96 -23
  29. package/dist/commands/status.js.map +1 -1
  30. package/dist/commands/sync.d.ts.map +1 -1
  31. package/dist/commands/sync.js +148 -97
  32. package/dist/commands/sync.js.map +1 -1
  33. package/dist/commands/unlink.d.ts +118 -0
  34. package/dist/commands/unlink.d.ts.map +1 -0
  35. package/dist/commands/unlink.js +271 -0
  36. package/dist/commands/unlink.js.map +1 -0
  37. package/dist/commit-anchor.d.ts +25 -0
  38. package/dist/commit-anchor.d.ts.map +1 -0
  39. package/dist/commit-anchor.js +93 -0
  40. package/dist/commit-anchor.js.map +1 -0
  41. package/dist/config.d.ts +13 -0
  42. package/dist/config.d.ts.map +1 -1
  43. package/dist/config.js +19 -36
  44. package/dist/config.js.map +1 -1
  45. package/dist/context/materialize.d.ts +200 -0
  46. package/dist/context/materialize.d.ts.map +1 -0
  47. package/dist/context/materialize.js +145 -0
  48. package/dist/context/materialize.js.map +1 -0
  49. package/dist/context/pull.d.ts +41 -48
  50. package/dist/context/pull.d.ts.map +1 -1
  51. package/dist/context/pull.js +36 -287
  52. package/dist/context/pull.js.map +1 -1
  53. package/dist/docs/bundle-by-name.d.ts +47 -0
  54. package/dist/docs/bundle-by-name.d.ts.map +1 -0
  55. package/dist/docs/bundle-by-name.js +56 -0
  56. package/dist/docs/bundle-by-name.js.map +1 -0
  57. package/dist/docs/classify.d.ts +1 -1
  58. package/dist/docs/classify.d.ts.map +1 -1
  59. package/dist/docs/classify.js +2 -2
  60. package/dist/docs/classify.js.map +1 -1
  61. package/dist/docs/delivery-check.d.ts +25 -7
  62. package/dist/docs/delivery-check.d.ts.map +1 -1
  63. package/dist/docs/delivery-check.js +32 -11
  64. package/dist/docs/delivery-check.js.map +1 -1
  65. package/dist/docs/delivery.d.ts +105 -0
  66. package/dist/docs/delivery.d.ts.map +1 -0
  67. package/dist/docs/delivery.js +128 -0
  68. package/dist/docs/delivery.js.map +1 -0
  69. package/dist/docs/guide-projection.d.ts +32 -0
  70. package/dist/docs/guide-projection.d.ts.map +1 -1
  71. package/dist/docs/guide-projection.js +55 -27
  72. package/dist/docs/guide-projection.js.map +1 -1
  73. package/dist/docs/relink-mapping.d.ts.map +1 -1
  74. package/dist/docs/relink-mapping.js +2 -3
  75. package/dist/docs/relink-mapping.js.map +1 -1
  76. package/dist/docs/repo-config.d.ts +0 -6
  77. package/dist/docs/repo-config.d.ts.map +1 -1
  78. package/dist/docs/repo-config.js +7 -37
  79. package/dist/docs/repo-config.js.map +1 -1
  80. package/dist/docs/sidecar.d.ts.map +1 -1
  81. package/dist/docs/sidecar.js +11 -3
  82. package/dist/docs/sidecar.js.map +1 -1
  83. package/dist/docs/status.d.ts +130 -14
  84. package/dist/docs/status.d.ts.map +1 -1
  85. package/dist/docs/status.js +160 -18
  86. package/dist/docs/status.js.map +1 -1
  87. package/dist/docs/subscribe.d.ts +44 -47
  88. package/dist/docs/subscribe.d.ts.map +1 -1
  89. package/dist/docs/subscribe.js +52 -87
  90. package/dist/docs/subscribe.js.map +1 -1
  91. package/dist/docs/sync-docs.d.ts +90 -4
  92. package/dist/docs/sync-docs.d.ts.map +1 -1
  93. package/dist/docs/sync-docs.js +508 -924
  94. package/dist/docs/sync-docs.js.map +1 -1
  95. package/dist/docs/sync-plan.d.ts +517 -0
  96. package/dist/docs/sync-plan.d.ts.map +1 -0
  97. package/dist/docs/sync-plan.js +872 -0
  98. package/dist/docs/sync-plan.js.map +1 -0
  99. package/dist/index.d.ts.map +1 -1
  100. package/dist/index.js +7 -1
  101. package/dist/index.js.map +1 -1
  102. package/dist/mcp/client.d.ts +52 -5
  103. package/dist/mcp/client.d.ts.map +1 -1
  104. package/dist/mcp/client.js +69 -18
  105. package/dist/mcp/client.js.map +1 -1
  106. package/dist/mcp/import-tool.d.ts +19 -7
  107. package/dist/mcp/import-tool.d.ts.map +1 -1
  108. package/dist/mcp/import-tool.js +5 -5
  109. package/dist/mcp/import-tool.js.map +1 -1
  110. package/dist/mcp/scope.d.ts +35 -2
  111. package/dist/mcp/scope.d.ts.map +1 -1
  112. package/dist/mcp/scope.js +34 -2
  113. package/dist/mcp/scope.js.map +1 -1
  114. package/dist/mcp/server.d.ts +29 -12
  115. package/dist/mcp/server.d.ts.map +1 -1
  116. package/dist/mcp/server.js +376 -65
  117. package/dist/mcp/server.js.map +1 -1
  118. package/dist/mcp/write-items.d.ts +73 -14
  119. package/dist/mcp/write-items.d.ts.map +1 -1
  120. package/dist/mcp/write-items.js +90 -22
  121. package/dist/mcp/write-items.js.map +1 -1
  122. package/dist/project-hooks.d.ts +60 -0
  123. package/dist/project-hooks.d.ts.map +1 -0
  124. package/dist/project-hooks.js +93 -0
  125. package/dist/project-hooks.js.map +1 -0
  126. package/dist/rules/guide-history-client.d.ts +70 -0
  127. package/dist/rules/guide-history-client.d.ts.map +1 -0
  128. package/dist/rules/guide-history-client.js +121 -0
  129. package/dist/rules/guide-history-client.js.map +1 -0
  130. package/dist/rules/import-client.d.ts +1 -1
  131. package/dist/rules/import-paths.js +2 -2
  132. package/dist/rules/import-paths.js.map +1 -1
  133. package/dist/rules/repo-identity.d.ts +45 -0
  134. package/dist/rules/repo-identity.d.ts.map +1 -0
  135. package/dist/rules/repo-identity.js +59 -0
  136. package/dist/rules/repo-identity.js.map +1 -0
  137. package/dist/rules/unlink-client.d.ts +39 -0
  138. package/dist/rules/unlink-client.d.ts.map +1 -0
  139. package/dist/rules/unlink-client.js +86 -0
  140. package/dist/rules/unlink-client.js.map +1 -0
  141. package/dist/run-self-report.d.ts +68 -0
  142. package/dist/run-self-report.d.ts.map +1 -0
  143. package/dist/run-self-report.js +49 -0
  144. package/dist/run-self-report.js.map +1 -0
  145. package/dist/skill-template.d.ts +3 -3
  146. package/dist/skill-template.d.ts.map +1 -1
  147. package/dist/skill-template.js +59 -28
  148. package/dist/skill-template.js.map +1 -1
  149. package/dist/soft-json.d.ts +34 -0
  150. package/dist/soft-json.d.ts.map +1 -0
  151. package/dist/soft-json.js +44 -0
  152. package/dist/soft-json.js.map +1 -0
  153. package/dist/state/machine-cache.d.ts +34 -0
  154. package/dist/state/machine-cache.d.ts.map +1 -1
  155. package/dist/state/machine-cache.js +37 -0
  156. package/dist/state/machine-cache.js.map +1 -1
  157. package/dist/sync-batches.d.ts +22 -1
  158. package/dist/sync-batches.d.ts.map +1 -1
  159. package/dist/sync-batches.js +17 -0
  160. package/dist/sync-batches.js.map +1 -1
  161. package/dist/sync-client.d.ts.map +1 -1
  162. package/dist/sync-client.js +25 -1
  163. package/dist/sync-client.js.map +1 -1
  164. package/dist/transcript/narration.d.ts +46 -0
  165. package/dist/transcript/narration.d.ts.map +1 -1
  166. package/dist/transcript/narration.js +69 -4
  167. package/dist/transcript/narration.js.map +1 -1
  168. package/dist/update/assets.d.ts.map +1 -1
  169. package/dist/update/assets.js +7 -57
  170. package/dist/update/assets.js.map +1 -1
  171. package/package.json +12 -14
  172. package/dist/commands/import.d.ts +0 -57
  173. package/dist/commands/import.d.ts.map +0 -1
  174. package/dist/commands/import.js +0 -217
  175. package/dist/commands/import.js.map +0 -1
  176. package/dist/docs/enroll-default-bundle.d.ts +0 -71
  177. package/dist/docs/enroll-default-bundle.d.ts.map +0 -1
  178. package/dist/docs/enroll-default-bundle.js +0 -111
  179. package/dist/docs/enroll-default-bundle.js.map +0 -1
  180. package/dist/docs/own-bundle.d.ts +0 -76
  181. package/dist/docs/own-bundle.d.ts.map +0 -1
  182. package/dist/docs/own-bundle.js +0 -96
  183. package/dist/docs/own-bundle.js.map +0 -1
  184. package/dist/docs/resolve-subscriptions.d.ts +0 -67
  185. package/dist/docs/resolve-subscriptions.d.ts.map +0 -1
  186. package/dist/docs/resolve-subscriptions.js +0 -67
  187. package/dist/docs/resolve-subscriptions.js.map +0 -1
package/README.md CHANGED
@@ -1,8 +1,8 @@
1
1
  # mossbear
2
2
 
3
- Local-first CLI for [Mossbear](https://app.mossbear.io) — a feedback layer for AI coding agents. Mossbear grades what your agents actually did against the guides you write (`AGENTS.md`, `CLAUDE.md`, `.cursorrules`, …) and shows you which instructions work.
3
+ Local-first CLI for [Mossbear](https://app.mossbear.io) — a feedback layer for AI coding agents. Mossbear grades what your agents actually did against your guides — the rules, skills and documents you wrote (`AGENTS.md`, `CLAUDE.md`, `.cursorrules`, …) — and shows you which ones work.
4
4
 
5
- The CLI is the on-device half of the product: it hooks into your agent's lifecycle, records what each tool call did, and syncs **only action metadata** to your dashboard, which grades the run against your guides. Raw hook data, file contents, and conversation transcripts never leave your machine.
5
+ The CLI is the on-device half of the product: it hooks into your agent's lifecycle, records what each tool call did, and syncs that record to your dashboard, which grades the run against your rules and skills. Your file contents, your diffs and your raw conversation transcripts never leave your machine — [Privacy](#privacy) lists exactly what does.
6
6
 
7
7
  ## Install
8
8
 
@@ -68,7 +68,8 @@ mossbear sync --token <token> # remembered after the first successful sync
68
68
  | `mossbear sync` | Upload logged actions + extracted feedback for grading, pull the guide bundle (run by the Stop and SessionEnd hooks) |
69
69
  | `mossbear pull <bundle>` | Pull a context bundle's canonical items into a local directory as Markdown (default `.mossbear/context/<bundle>/`) |
70
70
  | `mossbear mcp` | Run the Mossbear MCP server, exposing your context layer (bundles + inbox) to any agent |
71
- | `mossbear import` | Adopt this repo's existing guide files (`AGENTS.md`, `.agents/`, `CLAUDE.md`, `.claude/rules/`, `.cursorrules`, `.cursor/rules/*.mdc`) into your dashboard — pick from a list, never type a path |
71
+ | `mossbear link` | Adopt this repo's existing guide files (`AGENTS.md`, `.agents/`, `CLAUDE.md`, `.claude/rules/`, `.cursorrules`, `.cursor/rules/*.mdc`) into your dashboard — pick from a list, never type a path |
72
+ | `mossbear unlink <file>` | Stop delivering a file you linked — it stays on disk, and `mossbear link` puts it back |
72
73
  | `mossbear guides active` / `search` | List or search your synced guides |
73
74
  | `mossbear suggest` | Review pending guide suggestions |
74
75
  | `mossbear status` | Show pending actions + config status |
@@ -79,16 +80,16 @@ mossbear sync --token <token> # remembered after the first successful sync
79
80
  If the repo already has an `AGENTS.md`, `CLAUDE.md`, `.cursorrules`, or skills, `mossbear init` finds them and offers to import them once a token is configured (`--import-guides` / `--no-import-guides` to answer without the prompt). To do it later, or after adding a new guide file:
80
81
 
81
82
  ```bash
82
- mossbear import # pick from a list; Enter takes all of them
83
- mossbear import --yes # no prompt (required when stdin is not a TTY)
84
- mossbear import --global # also scan ~/.claude/CLAUDE.md
83
+ mossbear link # pick from a list; Enter takes all of them
84
+ mossbear link --yes # no prompt (required when stdin is not a TTY)
85
+ mossbear link --global # also scan ~/.claude/CLAUDE.md
85
86
  ```
86
87
 
87
88
  Files a context bundle already manages are **listed as managed** rather than hidden,
88
89
  and cannot be selected — they are canonical in the dashboard, so edit them there or
89
90
  on disk and run `mossbear sync`.
90
91
 
91
- Re-run `mossbear import` after editing a guide file. There is no file watcher: a
92
+ Re-run `mossbear link` after editing a guide file. There is no file watcher: a
92
93
  watcher pushed one import per save, and because import has no update path, each save
93
94
  filed a *new* guide row rather than updating the existing one. Continuous guide sync
94
95
  returns via `mossbear sync` once guides have stable identity — see
@@ -98,9 +99,28 @@ It reads the dashboard URL from `~/.mossbear/config.json`, so a `--dashboard-url
98
99
 
99
100
  ## Privacy
100
101
 
101
- - The CLI runs no LLM calls and holds no provider credentials. Grading happens on the dashboard, over the action metadata and guide text you synced — never file contents.
102
- - Only action metadata and guide file content you explicitly import are synced. Shell command text is secret-redacted and length-capped before it is recorded at all.
103
- - No telemetry.
102
+ The CLI runs no LLM calls and holds no provider credentials, and produces no verdict of its own — grading happens on the dashboard, over what you synced. There is no telemetry.
103
+
104
+ **Stays on your machine, always:** your file contents, your diffs, raw hook payloads, and full conversation transcripts.
105
+
106
+ **Sent to your dashboard.** Five classes, and nothing else:
107
+
108
+ 1. **Action metadata** — tool-call types, one-line summaries, and file *paths* (never contents). Shell command text is secret-redacted and length-capped before it is recorded at all.
109
+ 2. **Guide-file manifests** — the paths, formats and SHA-256 hashes of the instruction files that were in your agent's context, so a verdict can name which version of a guide it graded against.
110
+ 3. **Token usage**, read out of the transcript locally.
111
+ 4. **Content you explicitly push** — guide files you `mossbear link`, and context you capture or push through the MCP server.
112
+ 5. **Two kinds of derived prose**: drafted guide suggestions (their text and the reasoning behind them), and a short narration of what you and the agent said, which the dashboard shows as evidence beside a verdict. Both are extracted from the transcript **on your machine**, have code blocks stripped structurally before upload, and are length-capped on the wire.
113
+
114
+ That fifth class is the one worth deciding about, because it is prose rather than metadata. Narration is per-repo and you can turn it off:
115
+
116
+ ```bash
117
+ mossbear narration # show the current setting for this repo
118
+ mossbear narration off # stop sending transcript excerpts from here
119
+ ```
120
+
121
+ Guide suggestions have no equivalent switch yet — if you do not want drafted suggestions leaving the machine, do not run `mossbear sync` in that repo.
122
+
123
+ We enumerate these rather than summarising them as "metadata" on purpose: this is a promise you can check by watching your own network traffic, and one you can check is worth more than one you cannot.
104
124
 
105
125
  ## Links
106
126
 
@@ -1 +1 @@
1
- {"version":3,"file":"doctor.d.ts","sourceRoot":"","sources":["../../src/commands/doctor.ts"],"names":[],"mappings":"AAyGA,eAAO,MAAM,aAAa;;;;;;;;;;;EAuMxB,CAAA"}
1
+ {"version":3,"file":"doctor.d.ts","sourceRoot":"","sources":["../../src/commands/doctor.ts"],"names":[],"mappings":"AA8CA,eAAO,MAAM,aAAa;;;;;;;;;;;EAwPxB,CAAA"}
@@ -1,12 +1,13 @@
1
- import { readFile } from 'node:fs/promises';
2
- import { join } from 'node:path';
3
1
  import { defineCommand } from 'citty';
4
2
  import { MOSSBEAR_TOKEN_ENV, readEnvToken, resolveDashboardUrl, resolveToken, } from '../config.js';
5
3
  import { describeDashboardHealth } from '../dashboard-health.js';
6
4
  import { describeGuideDelivery } from '../docs/delivery-check.js';
5
+ import { repoBundleIds } from '../docs/delivery.js';
7
6
  import { collidesWithHomeConfig, readRepoDocsConfig } from '../docs/repo-config.js';
8
- import { MOSSBEAR_HOOK_COMMAND, MOSSBEAR_SYNC_COMMAND, isMossbearLoggerCommand, stopHookUploadsActions, } from '../hooks-settings.js';
7
+ import { MOSSBEAR_HOOK_COMMAND, MOSSBEAR_SYNC_COMMAND, stopHookUploadsActions, } from '../hooks-settings.js';
8
+ import { createContextClient } from '../mcp/client.js';
9
9
  import { resolveOnPath } from '../path-resolve.js';
10
+ import { detectLoggerHook, readProjectHooks } from '../project-hooks.js';
10
11
  import { resolveRepoRoot } from '../repo-root.js';
11
12
  import { discoverGuideFiles } from '../rules/discover.js';
12
13
  import { verifyDashboardToken } from '../token-verify.js';
@@ -14,55 +15,6 @@ import { detectBundledSkillDrift } from '../update/assets.js';
14
15
  import { checkForUpdate, formatUpdateNotice } from '../update/notice.js';
15
16
  import { formatUpdateSuccess, performUpdate, syncGeneratedAssets, } from '../update/perform.js';
16
17
  import { CLI_VERSION } from '../version.js';
17
- /** The project's parsed `.claude/settings.json`, or null when absent/malformed. */
18
- async function readProjectSettings() {
19
- const settingsPath = join(process.cwd(), '.claude', 'settings.json');
20
- try {
21
- const raw = await readFile(settingsPath, 'utf8');
22
- return JSON.parse(raw);
23
- }
24
- catch {
25
- return null;
26
- }
27
- }
28
- /**
29
- * Which form of the logger hook this project's settings configure for one
30
- * event, if any. Shared by `PostToolUse` (the success logger) and
31
- * `PostToolUseFailure` (`hook-failure-event-registration`) — same command,
32
- * same recognizer, only the settings.json key differs.
33
- */
34
- function detectConfiguredHookFor(settings, event) {
35
- try {
36
- if (!settings)
37
- return { form: 'none' };
38
- const hooks = settings['hooks'];
39
- const groups = hooks?.[event];
40
- if (!Array.isArray(groups))
41
- return { form: 'none' };
42
- // Shares the recognizer with the merge so the two cannot disagree about
43
- // what counts as configured — the substring match this replaced would miss
44
- // the portable command and call a correctly wired repo unconfigured.
45
- for (const group of groups) {
46
- const groupHooks = group['hooks'];
47
- if (!Array.isArray(groupHooks))
48
- continue;
49
- for (const hook of groupHooks) {
50
- if (typeof hook === 'object' && hook !== null) {
51
- if (isMossbearLoggerCommand(hook['command'])) {
52
- return { form: 'portable' };
53
- }
54
- }
55
- }
56
- }
57
- return { form: 'none' };
58
- }
59
- catch {
60
- return { form: 'none' };
61
- }
62
- }
63
- function detectConfiguredHook(settings) {
64
- return detectConfiguredHookFor(settings, 'PostToolUse');
65
- }
66
18
  /**
67
19
  * True when this project's Stop hooks upload the session (`mossbear sync`).
68
20
  *
@@ -73,10 +25,7 @@ function detectConfiguredHook(settings) {
73
25
  * is destroyed at session end the entire record is lost with it. Doctor
74
26
  * reporting all-clear in that state is what let it go unnoticed here.
75
27
  */
76
- function detectUploadHook(settings) {
77
- if (!settings)
78
- return false;
79
- const hooks = settings['hooks'];
28
+ function detectUploadHook(hooks) {
80
29
  return stopHookUploadsActions(hooks?.['Stop']);
81
30
  }
82
31
  export const doctorCommand = defineCommand({
@@ -97,12 +46,10 @@ export const doctorCommand = defineCommand({
97
46
  },
98
47
  },
99
48
  async run({ args }) {
100
- const settings = await readProjectSettings();
101
- const hook = detectConfiguredHook(settings);
102
- const hooksConfigured = hook.form !== 'none';
103
- const failureHook = detectConfiguredHookFor(settings, 'PostToolUseFailure');
104
- const failureHookConfigured = failureHook.form !== 'none';
105
- const uploadConfigured = detectUploadHook(settings);
49
+ const projectHooks = await readProjectHooks(process.cwd());
50
+ const hooksConfigured = detectLoggerHook(projectHooks, 'PostToolUse') !== null;
51
+ const failureHookConfigured = detectLoggerHook(projectHooks, 'PostToolUseFailure') !== null;
52
+ const uploadConfigured = detectUploadHook(projectHooks);
106
53
  const hookBinPath = resolveOnPath(MOSSBEAR_HOOK_COMMAND);
107
54
  // The Stop hooks invoke `mossbear`, which ships as a separate bin from
108
55
  // `mossbear-hook` and can be missing while the other resolves.
@@ -127,8 +74,30 @@ export const doctorCommand = defineCommand({
127
74
  })
128
75
  .then((files) => ({ files, failed: false }))
129
76
  .catch(() => ({ files: [], failed: true }));
77
+ // The account scope, which only the server can answer. `null` when this run
78
+ // has no token or the dashboard is unreachable — deliberately not zero, see
79
+ // `GuideDeliveryInput.userSubscriptionCount`.
80
+ const deliveryToken = await resolveToken().catch(() => '');
81
+ let userSubscriptionCount = null;
82
+ if (deliveryToken) {
83
+ try {
84
+ const client = createContextClient({
85
+ dashboardUrl: await resolveDashboardUrl(args['dashboard-url']),
86
+ token: deliveryToken,
87
+ });
88
+ const resolved = await client.resolveSubscriptions(repoBundleIds(repoDocs.subscriptions));
89
+ userSubscriptionCount = resolved.bundles.filter(({ scopes }) => scopes.includes('user')).length;
90
+ }
91
+ catch {
92
+ // Left null. The dashboard probe further down reports an unreachable or
93
+ // rejected token as its own check, so a second message here would say
94
+ // the same thing twice — and this check's own detail line already tells
95
+ // the user it could not look.
96
+ }
97
+ }
130
98
  const delivery = describeGuideDelivery({
131
- subscriptionCount: repoDocs.subscriptions.length,
99
+ repoSubscriptionCount: repoDocs.subscriptions.length,
100
+ userSubscriptionCount,
132
101
  guideFileCount: discovered.files.length,
133
102
  malformedConfig: repoDocs.malformed,
134
103
  discoveryFailed: discovered.failed,
@@ -161,10 +130,16 @@ export const doctorCommand = defineCommand({
161
130
  },
162
131
  {
163
132
  label: 'Claude Code hooks configured',
164
- ok: hooksConfigured,
165
- detail: hooksConfigured
166
- ? `.claude/settings.json has PostToolUse hook (${MOSSBEAR_HOOK_COMMAND})`
167
- : 'not configured — run `mossbear init` in your project',
133
+ // Configured is not the same as able to run — the same distinction the
134
+ // two checks below already make. Without `runnerOk` a stripped PATH
135
+ // rendered `✗ mossbear-hook on PATH` directly above a `✓` here, so the
136
+ // inert case reported as healthy.
137
+ ok: hooksConfigured && runnerOk,
138
+ detail: !hooksConfigured
139
+ ? 'not configured — run `mossbear init` in your project'
140
+ : runnerOk
141
+ ? `.claude/settings.json has PostToolUse hook (${MOSSBEAR_HOOK_COMMAND})`
142
+ : `${MOSSBEAR_HOOK_COMMAND} not on PATH — reinstall globally (npm install -g mossbear)`,
168
143
  },
169
144
  // Only meaningful once the logger is wired: with no PostToolUse hook
170
145
  // there is nothing to upload, and the check above already says so. Two
@@ -196,7 +171,7 @@ export const doctorCommand = defineCommand({
196
171
  // case `missingHookPathWarning` already covers for init.
197
172
  ok: uploadConfigured && mossbearBinPath !== null,
198
173
  detail: !uploadConfigured
199
- ? `actions are being logged to ~/.mossbear/runs/ and never uploaded — add a \`${MOSSBEAR_SYNC_COMMAND}\` Stop hook by running \`mossbear init\`, or pass --no-sync-hook if you sync some other way`
174
+ ? `actions are being logged to ~/.mossbear/runs/ and never uploaded — run \`mossbear init\` to add the \`${MOSSBEAR_SYNC_COMMAND}\` Stop hook. If you upload some other way, this check will keep reporting.`
200
175
  : mossbearBinPath === null
201
176
  ? '`mossbear` is not on PATH, so the configured Stop hook fails with command-not-found and nothing uploads — reinstall globally (npm install -g mossbear)'
202
177
  : `.claude/settings.json has Stop hook (${MOSSBEAR_SYNC_COMMAND})`,
@@ -209,7 +184,11 @@ export const doctorCommand = defineCommand({
209
184
  for (const check of checks) {
210
185
  const icon = check.ok ? '✓' : '✗';
211
186
  const line = ` ${icon} ${check.label}`;
212
- console.log(args.verbose ? `${line} (${check.detail ?? ''})` : line);
187
+ // A failing check always shows its detail: the detail *is* the remedy,
188
+ // and hiding it behind --verbose left the default run printing bare `✗`
189
+ // labels under a summary that says "See above for details".
190
+ const detail = check.detail ?? '';
191
+ console.log(!check.ok || args.verbose ? `${line}${detail ? ` (${detail})` : ''}` : line);
213
192
  if (!check.ok)
214
193
  allOk = false;
215
194
  }
@@ -219,6 +198,7 @@ export const doctorCommand = defineCommand({
219
198
  // broken connection instead of a misleading "configured" — that gap is the
220
199
  // activation-failure signal this check exists to close.
221
200
  const token = await resolveToken().catch(() => '');
201
+ let verification = null;
222
202
  if (!token) {
223
203
  console.log(` i ${describeDashboardHealth('unconfigured', '')}`);
224
204
  }
@@ -230,7 +210,7 @@ export const doctorCommand = defineCommand({
230
210
  console.log(` i token from $${MOSSBEAR_TOKEN_ENV}`);
231
211
  }
232
212
  const dashboardUrl = await resolveDashboardUrl(args['dashboard-url']);
233
- const verification = await verifyDashboardToken(dashboardUrl, token);
213
+ verification = await verifyDashboardToken(dashboardUrl, token);
234
214
  console.log(` i ${describeDashboardHealth(verification, dashboardUrl)}`);
235
215
  }
236
216
  // Repo-local skills are user-editable, so they are only reported (see
@@ -242,10 +222,19 @@ export const doctorCommand = defineCommand({
242
222
  ' run `mossbear init --skills-only` to rewrite them (this overwrites local edits)');
243
223
  }
244
224
  if (!allOk) {
245
- console.error('\nSome checks failed. See above for details.');
225
+ // The verdict goes to stdout with the checks it summarizes; only the
226
+ // pointer to the next command goes to stderr. Splitting them left a
227
+ // piped run with no verdict at all on the failing path.
228
+ console.log('\nSome checks failed.');
229
+ console.error('Run `mossbear doctor --verbose` for the full detail on each.');
246
230
  process.exit(1);
247
231
  }
248
- console.log('\nAll checks passed.');
232
+ // The connection is informational and never fails the run (see above), but
233
+ // it must not be summarized away either: a rejected token means nothing
234
+ // will sync, and "All checks passed." on its own reads as a clean bill.
235
+ console.log(verification === 'rejected'
236
+ ? '\nEnvironment checks passed. The dashboard is not accepting this token, so nothing will sync until you replace it.'
237
+ : '\nAll checks passed.');
249
238
  // Doctor is the "check and fix my setup" surface, so it is the one place
250
239
  // that offers to run the update rather than just naming it. Suppressed
251
240
  // exactly like the ambient notice (TTY, env, config) via checkForUpdate.
@@ -1 +1 @@
1
- {"version":3,"file":"doctor.js","sourceRoot":"","sources":["../../src/commands/doctor.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"doctor.js","sourceRoot":"","sources":["../../src/commands/doctor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,OAAO,CAAA;AAErC,OAAO,EACL,kBAAkB,EAClB,YAAY,EACZ,mBAAmB,EACnB,YAAY,GACb,MAAM,cAAc,CAAA;AACrB,OAAO,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAA;AAChE,OAAO,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAA;AACjE,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAA;AACnD,OAAO,EAAE,sBAAsB,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAA;AACnF,OAAO,EACL,qBAAqB,EACrB,qBAAqB,EACrB,sBAAsB,GACvB,MAAM,sBAAsB,CAAA;AAC7B,OAAO,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAA;AACtD,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAA;AAClD,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAA;AACxE,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAA;AACjD,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAA;AACzD,OAAO,EAA0B,oBAAoB,EAAE,MAAM,oBAAoB,CAAA;AACjF,OAAO,EAAE,uBAAuB,EAAE,MAAM,qBAAqB,CAAA;AAC7D,OAAO,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAA;AACxE,OAAO,EACL,mBAAmB,EACnB,aAAa,EACb,mBAAmB,GACpB,MAAM,sBAAsB,CAAA;AAC7B,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAA;AAE3C;;;;;;;;;GASG;AACH,SAAS,gBAAgB,CAAC,KAAqC;IAC7D,OAAO,sBAAsB,CAAC,KAAK,EAAE,CAAC,MAAM,CAAC,CAAC,CAAA;AAChD,CAAC;AAED,MAAM,CAAC,MAAM,aAAa,GAAG,aAAa,CAAC;IACzC,IAAI,EAAE;QACJ,IAAI,EAAE,QAAQ;QACd,WAAW,EAAE,gDAAgD;KAC9D;IACD,IAAI,EAAE;QACJ,OAAO,EAAE;YACP,IAAI,EAAE,SAAS;YACf,WAAW,EAAE,+BAA+B;YAC5C,OAAO,EAAE,KAAK;SACf;QACD,eAAe,EAAE;YACf,IAAI,EAAE,QAAQ;YACd,WAAW,EACT,uHAAuH;YACzH,OAAO,EAAE,EAAE;SACZ;KACF;IACD,KAAK,CAAC,GAAG,CAAC,EAAE,IAAI,EAAE;QAChB,MAAM,YAAY,GAAG,MAAM,gBAAgB,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,CAAA;QAC1D,MAAM,eAAe,GAAG,gBAAgB,CAAC,YAAY,EAAE,aAAa,CAAC,KAAK,IAAI,CAAA;QAC9E,MAAM,qBAAqB,GACzB,gBAAgB,CAAC,YAAY,EAAE,oBAAoB,CAAC,KAAK,IAAI,CAAA;QAC/D,MAAM,gBAAgB,GAAG,gBAAgB,CAAC,YAAY,CAAC,CAAA;QACvD,MAAM,WAAW,GAAG,aAAa,CAAC,qBAAqB,CAAC,CAAA;QACxD,uEAAuE;QACvE,+DAA+D;QAC/D,MAAM,eAAe,GAAG,aAAa,CAAC,UAAU,CAAC,CAAA;QACjD,6EAA6E;QAC7E,0EAA0E;QAC1E,wEAAwE;QACxE,MAAM,QAAQ,GAAG,WAAW,KAAK,IAAI,CAAA;QAErC,MAAM,UAAU,GAAG,MAAM,uBAAuB,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,CAAA;QAE/D,gEAAgE;QAChE,6EAA6E;QAC7E,yEAAyE;QACzE,qDAAqD;QACrD,MAAM,YAAY,GAAG,eAAe,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,CAAA;QACnD,MAAM,QAAQ,GAAG,MAAM,kBAAkB,CAAC,YAAY,CAAC,CAAA;QACvD,2EAA2E;QAC3E,4EAA4E;QAC5E,uEAAuE;QACvE,MAAM,UAAU,GAAG,MAAM,kBAAkB,CAAC;YAC1C,GAAG,EAAE,YAAY;YACjB,mBAAmB,EAAE,KAAK;SAC3B,CAAC;aACC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC;aAC3C,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAA;QAC7C,4EAA4E;QAC5E,4EAA4E;QAC5E,8CAA8C;QAC9C,MAAM,aAAa,GAAG,MAAM,YAAY,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,CAAA;QAC1D,IAAI,qBAAqB,GAAkB,IAAI,CAAA;QAC/C,IAAI,aAAa,EAAE,CAAC;YAClB,IAAI,CAAC;gBACH,MAAM,MAAM,GAAG,mBAAmB,CAAC;oBACjC,YAAY,EAAE,MAAM,mBAAmB,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;oBAC9D,KAAK,EAAE,aAAa;iBACrB,CAAC,CAAA;gBACF,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,oBAAoB,CAChD,aAAa,CAAC,QAAQ,CAAC,aAAa,CAAC,CACtC,CAAA;gBACD,qBAAqB,GAAG,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,CAC7D,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CACxB,CAAC,MAAM,CAAA;YACV,CAAC;YAAC,MAAM,CAAC;gBACP,wEAAwE;gBACxE,sEAAsE;gBACtE,wEAAwE;gBACxE,8BAA8B;YAChC,CAAC;QACH,CAAC;QAED,MAAM,QAAQ,GAAG,qBAAqB,CAAC;YACrC,qBAAqB,EAAE,QAAQ,CAAC,aAAa,CAAC,MAAM;YACpD,qBAAqB;YACrB,cAAc,EAAE,UAAU,CAAC,KAAK,CAAC,MAAM;YACvC,eAAe,EAAE,QAAQ,CAAC,SAAS;YACnC,eAAe,EAAE,UAAU,CAAC,MAAM;YAClC,aAAa,EAAE,sBAAsB,CAAC,YAAY,CAAC;SACpD,CAAC,CAAA;QAEF,MAAM,MAAM,GAA2D;YACrE;gBACE,KAAK,EAAE,gBAAgB;gBACvB,EAAE,EAAE,QAAQ,CAAC,EAAE;gBACf,MAAM,EAAE,QAAQ,CAAC,MAAM;aACxB;YACD;gBACE,KAAK,EAAE,cAAc;gBACrB,EAAE,EAAE,QAAQ,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,EAAE;gBAChD,MAAM,EAAE,OAAO,CAAC,OAAO;aACxB;YACD,yEAAyE;YACzE,+DAA+D;YAC/D,iEAAiE;YACjE,wEAAwE;YACxE,2EAA2E;YAC3E,uEAAuE;YACvE,8CAA8C;YAC9C;gBACE,KAAK,EAAE,uBAAuB;gBAC9B,EAAE,EAAE,QAAQ;gBACZ,MAAM,EAAE,QAAQ;oBACd,CAAC,CAAC,CAAC,WAAW,IAAI,qBAAqB,CAAC;oBACxC,CAAC,CAAC,GAAG,qBAAqB,6DAA6D;aAC1F;YACD;gBACE,KAAK,EAAE,8BAA8B;gBACrC,uEAAuE;gBACvE,oEAAoE;gBACpE,uEAAuE;gBACvE,kCAAkC;gBAClC,EAAE,EAAE,eAAe,IAAI,QAAQ;gBAC/B,MAAM,EAAE,CAAC,eAAe;oBACtB,CAAC,CAAC,sDAAsD;oBACxD,CAAC,CAAC,QAAQ;wBACR,CAAC,CAAC,+CAA+C,qBAAqB,GAAG;wBACzE,CAAC,CAAC,GAAG,qBAAqB,6DAA6D;aAC5F;YACD,qEAAqE;YACrE,uEAAuE;YACvE,sEAAsE;YACtE,GAAG,CAAC,eAAe;gBACjB,CAAC,CAAC;oBACE;wBACE,+DAA+D;wBAC/D,8DAA8D;wBAC9D,8DAA8D;wBAC9D,gEAAgE;wBAChE,gEAAgE;wBAChE,+DAA+D;wBAC/D,oDAAoD;wBACpD,KAAK,EAAE,+CAA+C;wBACtD,EAAE,EAAE,qBAAqB,IAAI,QAAQ;wBACrC,MAAM,EAAE,CAAC,qBAAqB;4BAC5B,CAAC,CAAC,2FAA2F;4BAC7F,CAAC,CAAC,QAAQ;gCACR,CAAC,CAAC,sDAAsD,qBAAqB,GAAG;gCAChF,CAAC,CAAC,GAAG,qBAAqB,6DAA6D;qBAC5F;oBACD;wBACE,KAAK,EAAE,kCAAkC;wBACzC,8DAA8D;wBAC9D,sEAAsE;wBACtE,iEAAiE;wBACjE,oEAAoE;wBACpE,yDAAyD;wBACzD,EAAE,EAAE,gBAAgB,IAAI,eAAe,KAAK,IAAI;wBAChD,MAAM,EAAE,CAAC,gBAAgB;4BACvB,CAAC,CAAC,yGAAyG,qBAAqB,6EAA6E;4BAC7M,CAAC,CAAC,eAAe,KAAK,IAAI;gCACxB,CAAC,CAAC,wJAAwJ;gCAC1J,CAAC,CAAC,wCAAwC,qBAAqB,GAAG;qBACvE;iBACF;gBACH,CAAC,CAAC,EAAE,CAAC;SACR,CAAA;QAED,OAAO,CAAC,GAAG,CAAC,cAAc,WAAW,EAAE,CAAC,CAAA;QAExC,IAAI,KAAK,GAAG,IAAI,CAAA;QAChB,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;YAC3B,MAAM,IAAI,GAAG,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAA;YACjC,MAAM,IAAI,GAAG,KAAK,IAAI,KAAK,KAAK,CAAC,KAAK,EAAE,CAAA;YACxC,uEAAuE;YACvE,wEAAwE;YACxE,4DAA4D;YAC5D,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,IAAI,EAAE,CAAA;YACjC,OAAO,CAAC,GAAG,CACT,CAAC,KAAK,CAAC,EAAE,IAAI,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,IAAI,GAAG,MAAM,CAAC,CAAC,CAAC,KAAK,MAAM,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAC5E,CAAA;YACD,IAAI,CAAC,KAAK,CAAC,EAAE;gBAAE,KAAK,GAAG,KAAK,CAAA;QAC9B,CAAC;QAED,mEAAmE;QACnE,wEAAwE;QACxE,2EAA2E;QAC3E,2EAA2E;QAC3E,wDAAwD;QACxD,MAAM,KAAK,GAAG,MAAM,YAAY,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,CAAA;QAClD,IAAI,YAAY,GAA6B,IAAI,CAAA;QACjD,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,OAAO,CAAC,GAAG,CAAC,QAAQ,uBAAuB,CAAC,cAAc,EAAE,EAAE,CAAC,EAAE,CAAC,CAAA;QACpE,CAAC;aAAM,CAAC;YACN,wEAAwE;YACxE,yEAAyE;YACzE,oEAAoE;YACpE,IAAI,YAAY,EAAE,EAAE,CAAC;gBACnB,OAAO,CAAC,GAAG,CAAC,oBAAoB,kBAAkB,EAAE,CAAC,CAAA;YACvD,CAAC;YACD,MAAM,YAAY,GAAG,MAAM,mBAAmB,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC,CAAA;YACrE,YAAY,GAAG,MAAM,oBAAoB,CAAC,YAAY,EAAE,KAAK,CAAC,CAAA;YAC9D,OAAO,CAAC,GAAG,CAAC,QAAQ,uBAAuB,CAAC,YAAY,EAAE,YAAY,CAAC,EAAE,CAAC,CAAA;QAC5E,CAAC;QAED,sEAAsE;QACtE,4EAA4E;QAC5E,0EAA0E;QAC1E,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC1B,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;YACtD,OAAO,CAAC,GAAG,CACT,uDAAuD,KAAK,IAAI;gBAC9D,sFAAsF,CACzF,CAAA;QACH,CAAC;QAED,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,qEAAqE;YACrE,oEAAoE;YACpE,wDAAwD;YACxD,OAAO,CAAC,GAAG,CAAC,uBAAuB,CAAC,CAAA;YACpC,OAAO,CAAC,KAAK,CAAC,8DAA8D,CAAC,CAAA;YAC7E,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;QACjB,CAAC;QAED,2EAA2E;QAC3E,wEAAwE;QACxE,wEAAwE;QACxE,OAAO,CAAC,GAAG,CACT,YAAY,KAAK,UAAU;YACzB,CAAC,CAAC,oHAAoH;YACtH,CAAC,CAAC,sBAAsB,CAC3B,CAAA;QAED,yEAAyE;QACzE,uEAAuE;QACvE,yEAAyE;QACzE,MAAM,MAAM,GAAG,MAAM,cAAc,EAAE,CAAA;QACrC,IAAI,CAAC,MAAM;YAAE,OAAM;QAEnB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,kBAAkB,CAAC,MAAM,CAAC,CAAC,CAAA;QAChD,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK;YAAE,OAAM;QAEhC,MAAM,MAAM,GAAG,MAAM,aAAa,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC,CAAA;QAChE,IAAI,MAAM,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;YAChC,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC,MAAM,EAAE,MAAM,CAAC,gBAAgB,CAAC,CAAC,CAAA;YACjE,MAAM,mBAAmB,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,CAAA;QAC1C,CAAC;aAAM,IAAI,MAAM,CAAC,MAAM,KAAK,QAAQ,EAAE,CAAC;YACtC,wEAAwE;YACxE,2DAA2D;YAC3D,OAAO,CAAC,IAAI,CACV,oBAAoB,MAAM,CAAC,MAAM,wBAAwB,MAAM,CAAC,OAAO,EAAE,CAC1E,CAAA;QACH,CAAC;IACH,CAAC;CACF,CAAC,CAAA"}
@@ -0,0 +1,72 @@
1
+ import type { GuideHistoryChange } from '@mossbear/protocol';
2
+ /**
3
+ * `mossbear guides history <guide>` — what grading found about one guide.
4
+ *
5
+ * The shell twin of the `guide_history` MCP tool, over the same endpoint and
6
+ * the same client (`rules/guide-history-client.ts`). Both exist because an
7
+ * improvement session's wiring is not knowable in advance: an MCP-wired agent
8
+ * calls the tool, and any other agent — or the user, at a prompt — runs this
9
+ * (spec → Resolved, 2026-08-22).
10
+ *
11
+ * **This one reaches the network**, unlike `guides active` and `guides search`,
12
+ * which read the local cache. Verdicts are the server's and the CLI holds none
13
+ * of them by design, so there is nothing local to read here.
14
+ *
15
+ * `--json` is not a convenience flag: an agent invoking this through a shell
16
+ * wants the payload the MCP tool returns, delimiters included, rather than
17
+ * prose it has to parse back.
18
+ */
19
+ export declare const guidesHistoryCommand: import("citty").CommandDef<{
20
+ guide: {
21
+ type: "positional";
22
+ description: string;
23
+ required: true;
24
+ };
25
+ root: {
26
+ type: "string";
27
+ description: string;
28
+ default: string;
29
+ };
30
+ 'guide-id': {
31
+ type: "string";
32
+ description: string;
33
+ default: string;
34
+ };
35
+ json: {
36
+ type: "boolean";
37
+ description: string;
38
+ default: false;
39
+ };
40
+ token: {
41
+ type: "string";
42
+ description: string;
43
+ default: string;
44
+ };
45
+ 'dashboard-url': {
46
+ type: "string";
47
+ description: string;
48
+ default: string;
49
+ };
50
+ }>;
51
+ /**
52
+ * The last edit's two windows, as sentences.
53
+ *
54
+ * **A window and its denominators, and then it stops.** "Since" is the
55
+ * strongest word the evidence supports — the model changed, the task mix
56
+ * changed and the codebase changed too — so nothing here says the edit caused
57
+ * what followed it, and the date is a boundary rather than an attribution.
58
+ *
59
+ * **A suppressed pair is a sentence, not a silence**, and so is a guide with no
60
+ * earlier wording. Printing nothing in either case would leave a reader unable
61
+ * to tell "too few runs to say" from "this edit changed nothing", which are
62
+ * opposite statements — the same reason the payload carries `change: null`
63
+ * rather than omitting the key.
64
+ *
65
+ * **A regression reads exactly like an improvement**: same place, same words,
66
+ * different verb. It is the more useful of the two, because it says the
67
+ * guidance is not the lever.
68
+ *
69
+ * Exported for its unit test, and pure so that test needs no network.
70
+ */
71
+ export declare function guideChangeLines(change: GuideHistoryChange | null): string[];
72
+ //# sourceMappingURL=history.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"history.d.ts","sourceRoot":"","sources":["../../../src/commands/guides/history.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAEV,kBAAkB,EAEnB,MAAM,oBAAoB,CAAA;AAE3B;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAoF/B,CAAA;AA2EF;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,kBAAkB,GAAG,IAAI,GAAG,MAAM,EAAE,CAuC5E"}
@@ -0,0 +1,217 @@
1
+ import { defineCommand } from 'citty';
2
+ import { resolveDashboardUrl, resolveToken } from '../../config.js';
3
+ import { errText } from '../../err-text.js';
4
+ import { fetchGuideHistory } from '../../rules/guide-history-client.js';
5
+ import { resolveRepoIdentity } from '../../rules/repo-identity.js';
6
+ /**
7
+ * `mossbear guides history <guide>` — what grading found about one guide.
8
+ *
9
+ * The shell twin of the `guide_history` MCP tool, over the same endpoint and
10
+ * the same client (`rules/guide-history-client.ts`). Both exist because an
11
+ * improvement session's wiring is not knowable in advance: an MCP-wired agent
12
+ * calls the tool, and any other agent — or the user, at a prompt — runs this
13
+ * (spec → Resolved, 2026-08-22).
14
+ *
15
+ * **This one reaches the network**, unlike `guides active` and `guides search`,
16
+ * which read the local cache. Verdicts are the server's and the CLI holds none
17
+ * of them by design, so there is nothing local to read here.
18
+ *
19
+ * `--json` is not a convenience flag: an agent invoking this through a shell
20
+ * wants the payload the MCP tool returns, delimiters included, rather than
21
+ * prose it has to parse back.
22
+ */
23
+ export const guidesHistoryCommand = defineCommand({
24
+ meta: {
25
+ name: 'history',
26
+ description: 'Show what grading found about one guide or skill (reads the dashboard)',
27
+ },
28
+ args: {
29
+ guide: {
30
+ type: 'positional',
31
+ description: "The guide file's path (.claude/skills/reviewer/SKILL.md, AGENTS.md) or a bare skill name (reviewer)",
32
+ required: true,
33
+ },
34
+ root: {
35
+ type: 'string',
36
+ description: 'project or global — which discovery root, when a name reaches both',
37
+ default: '',
38
+ },
39
+ 'guide-id': {
40
+ type: 'string',
41
+ description: 'The exact guide, when a name reached several and the refusal listed them',
42
+ default: '',
43
+ },
44
+ json: {
45
+ type: 'boolean',
46
+ description: 'Print the raw payload instead of a summary',
47
+ default: false,
48
+ },
49
+ token: {
50
+ type: 'string',
51
+ description: 'Mossbear API token — overrides the stored one for this call',
52
+ default: '',
53
+ },
54
+ 'dashboard-url': {
55
+ type: 'string',
56
+ description: 'Override the dashboard base URL',
57
+ default: '',
58
+ },
59
+ },
60
+ async run({ args }) {
61
+ const root = args.root.trim();
62
+ if (root !== '' && root !== 'project' && root !== 'global') {
63
+ console.error(` root must be "project" or "global" — got "${root}".`);
64
+ process.exitCode = 1;
65
+ return;
66
+ }
67
+ const token = await resolveToken(args.token);
68
+ if (!token) {
69
+ console.error('No Mossbear token configured. Get one from the dashboard (Settings → Developer → CLI Token), then run `mossbear init --token <token>` or pass `mossbear guides history <guide> --token <token>`.');
70
+ process.exitCode = 1;
71
+ return;
72
+ }
73
+ const dashboardUrl = await resolveDashboardUrl(args['dashboard-url']);
74
+ let history;
75
+ try {
76
+ history = await fetchGuideHistory({
77
+ dashboardUrl,
78
+ token,
79
+ guide: args.guide,
80
+ root: root === '' ? undefined : root,
81
+ guideId: args['guide-id'] === '' ? undefined : args['guide-id'],
82
+ // A thunk: nothing about this repo is read unless the server says the
83
+ // identifier is ambiguous. Narrowing every query to this repo would
84
+ // stop answering about a guide adopted from another one.
85
+ disambiguateWith: () => resolveRepoIdentity(process.cwd()),
86
+ });
87
+ }
88
+ catch (err) {
89
+ console.error(` ${errText(err)}`);
90
+ process.exitCode = 1;
91
+ return;
92
+ }
93
+ if (args.json) {
94
+ console.log(JSON.stringify(history, null, 2));
95
+ return;
96
+ }
97
+ printHistory(history);
98
+ },
99
+ });
100
+ /**
101
+ * The summary a person reads.
102
+ *
103
+ * Every branch below is a *different* sentence for a different state, which is
104
+ * the whole point: "no runs have engaged this guide", "no run has used this
105
+ * wording yet" and "never graded" are three facts, and one sentence covering
106
+ * all three would state something the record does not say.
107
+ */
108
+ function printHistory(history) {
109
+ const { guide, window: figures } = history;
110
+ const where = guide.path === null ? '(no declared path)' : guide.path;
111
+ const rootLabel = guide.root === null ? '' : ` [${guide.root}]`;
112
+ console.log(`${guide.title} — ${where}${rootLabel}`);
113
+ if (history.state === 'unevaluated') {
114
+ console.log('\n Not yet graded. No run has produced a verdict for this guide.');
115
+ return;
116
+ }
117
+ if (history.state === 'awaiting_current_revision') {
118
+ // The normal state right after an edit: a real record, none of it about the
119
+ // wording on disk now. Reporting it as "not graded" would be a claim the
120
+ // user can contradict from their own dashboard.
121
+ const count = figures.olderRevisionRows;
122
+ const hedge = figures.isWindowed ? 'at least ' : '';
123
+ console.log(`\n No runs on this wording yet. ${hedge}${count} earlier verdict(s) judged wording it no longer has.`);
124
+ }
125
+ else if (figures.alignmentRate === null) {
126
+ console.log(`\n Graded in ${figures.total} run(s), none of which engaged this guide.`);
127
+ }
128
+ else if (figures.isLowConfidence) {
129
+ // Below the threshold the counts are the honest report and a percentage is
130
+ // not — one applicable run does not make a rate.
131
+ console.log(`\n Aligned in ${figures.aligned} of ${figures.applicable} run(s) that engaged this guide — too few runs to read as a rate.`);
132
+ }
133
+ else {
134
+ console.log(`\n ${Math.round(figures.alignmentRate * 100)}% aligned — ${figures.aligned} of ${figures.applicable} run(s) that engaged this guide.`);
135
+ }
136
+ if (history.state === 'evaluated') {
137
+ const scope = figures.isWindowed
138
+ ? `a sample of the last ${figures.windowSize} graded runs`
139
+ : `every graded run so far`;
140
+ console.log(` Counted over ${scope}; ${figures.notApplicable} never engaged it.`);
141
+ }
142
+ // Already indented to match the block above; the leading blank line separates
143
+ // the pair from the rate it qualifies.
144
+ for (const line of guideChangeLines(history.change))
145
+ console.log(line);
146
+ if (history.findings.length === 0) {
147
+ console.log('\n No recorded findings.');
148
+ return;
149
+ }
150
+ const more = history.findingsOmitted > 0 ? ` (${history.findingsOmitted} more not shown)` : '';
151
+ console.log(`\n Recent findings${more}:`);
152
+ for (const finding of history.findings) {
153
+ const age = finding.isCurrentRevision ? '' : ' — about earlier wording';
154
+ console.log(`\n · ${finding.occurredAt}${age}`);
155
+ // Printed with its markers intact. They are what says "this is transcript-
156
+ // derived text, not instructions", and an agent reading this through a
157
+ // shell needs that as much as one reading the MCP tool's JSON.
158
+ console.log(indent(finding.reasoning));
159
+ }
160
+ }
161
+ /**
162
+ * The last edit's two windows, as sentences.
163
+ *
164
+ * **A window and its denominators, and then it stops.** "Since" is the
165
+ * strongest word the evidence supports — the model changed, the task mix
166
+ * changed and the codebase changed too — so nothing here says the edit caused
167
+ * what followed it, and the date is a boundary rather than an attribution.
168
+ *
169
+ * **A suppressed pair is a sentence, not a silence**, and so is a guide with no
170
+ * earlier wording. Printing nothing in either case would leave a reader unable
171
+ * to tell "too few runs to say" from "this edit changed nothing", which are
172
+ * opposite statements — the same reason the payload carries `change: null`
173
+ * rather than omitting the key.
174
+ *
175
+ * **A regression reads exactly like an improvement**: same place, same words,
176
+ * different verb. It is the more useful of the two, because it says the
177
+ * guidance is not the lever.
178
+ *
179
+ * Exported for its unit test, and pure so that test needs no network.
180
+ */
181
+ export function guideChangeLines(change) {
182
+ if (change === null) {
183
+ return ['', ' No before/after: this guide has no earlier wording with graded runs.'];
184
+ }
185
+ const when = change.changedAt === null ? '' : ` (recorded ${change.changedAt})`;
186
+ const { since, before } = change;
187
+ const lines = ['', ` Since the last edit${when}:`];
188
+ if (change.suppressedBy !== null) {
189
+ // Below the sample floor a percentage is a lie with a decimal point in it,
190
+ // so the counts are the whole report and the sentence names which side is
191
+ // thin: too few runs *since* is the ordinary state right after an edit,
192
+ // while too few *before* means there was never a baseline to compare with.
193
+ lines.push(change.suppressedBy === 'since'
194
+ ? ` Not enough runs since this change to compare — ${since.applicable} run(s) have engaged this wording, against ${before.applicable} on the wording before it.`
195
+ : change.suppressedBy === 'before'
196
+ ? ` Not enough runs before this change to compare — ${before.applicable} run(s) engaged the previous wording.`
197
+ : ` Not enough runs either side of this change to compare — ${since.applicable} since, ${before.applicable} before.`);
198
+ return lines;
199
+ }
200
+ const verb = change.direction === 'improved'
201
+ ? 'more often'
202
+ : change.direction === 'regressed'
203
+ ? 'less often'
204
+ : 'about as often';
205
+ lines.push(` Aligned ${verb} since this change: ${since.aligned} of ${since.applicable} run(s) that engaged this wording, against ${before.aligned} of ${before.applicable} before it.`);
206
+ if (change.isWindowed) {
207
+ lines.push(` Each side is a bounded sample of its own wording — up to ${change.windowSize} runs — not a lifetime total.`);
208
+ }
209
+ return lines;
210
+ }
211
+ function indent(block) {
212
+ return block
213
+ .split('\n')
214
+ .map((line) => ` ${line}`)
215
+ .join('\n');
216
+ }
217
+ //# sourceMappingURL=history.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"history.js","sourceRoot":"","sources":["../../../src/commands/guides/history.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,OAAO,CAAA;AAErC,OAAO,EAAE,mBAAmB,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAA;AACnE,OAAO,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAA;AAC3C,OAAO,EAAE,iBAAiB,EAAE,MAAM,qCAAqC,CAAA;AACvE,OAAO,EAAE,mBAAmB,EAAE,MAAM,8BAA8B,CAAA;AAQlE;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG,aAAa,CAAC;IAChD,IAAI,EAAE;QACJ,IAAI,EAAE,SAAS;QACf,WAAW,EAAE,wEAAwE;KACtF;IACD,IAAI,EAAE;QACJ,KAAK,EAAE;YACL,IAAI,EAAE,YAAY;YAClB,WAAW,EACT,qGAAqG;YACvG,QAAQ,EAAE,IAAI;SACf;QACD,IAAI,EAAE;YACJ,IAAI,EAAE,QAAQ;YACd,WAAW,EAAE,oEAAoE;YACjF,OAAO,EAAE,EAAE;SACZ;QACD,UAAU,EAAE;YACV,IAAI,EAAE,QAAQ;YACd,WAAW,EACT,0EAA0E;YAC5E,OAAO,EAAE,EAAE;SACZ;QACD,IAAI,EAAE;YACJ,IAAI,EAAE,SAAS;YACf,WAAW,EAAE,4CAA4C;YACzD,OAAO,EAAE,KAAK;SACf;QACD,KAAK,EAAE;YACL,IAAI,EAAE,QAAQ;YACd,WAAW,EAAE,6DAA6D;YAC1E,OAAO,EAAE,EAAE;SACZ;QACD,eAAe,EAAE;YACf,IAAI,EAAE,QAAQ;YACd,WAAW,EAAE,iCAAiC;YAC9C,OAAO,EAAE,EAAE;SACZ;KACF;IACD,KAAK,CAAC,GAAG,CAAC,EAAE,IAAI,EAAE;QAChB,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAA;QAC7B,IAAI,IAAI,KAAK,EAAE,IAAI,IAAI,KAAK,SAAS,IAAI,IAAI,KAAK,QAAQ,EAAE,CAAC;YAC3D,OAAO,CAAC,KAAK,CAAC,+CAA+C,IAAI,IAAI,CAAC,CAAA;YACtE,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAA;YACpB,OAAM;QACR,CAAC;QAED,MAAM,KAAK,GAAG,MAAM,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;QAC5C,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,OAAO,CAAC,KAAK,CACX,kMAAkM,CACnM,CAAA;YACD,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAA;YACpB,OAAM;QACR,CAAC;QAED,MAAM,YAAY,GAAG,MAAM,mBAAmB,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC,CAAA;QAErE,IAAI,OAA6B,CAAA;QACjC,IAAI,CAAC;YACH,OAAO,GAAG,MAAM,iBAAiB,CAAC;gBAChC,YAAY;gBACZ,KAAK;gBACL,KAAK,EAAE,IAAI,CAAC,KAAK;gBACjB,IAAI,EAAE,IAAI,KAAK,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAE,IAA2B;gBAC5D,OAAO,EAAE,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC;gBAC/D,sEAAsE;gBACtE,oEAAoE;gBACpE,yDAAyD;gBACzD,gBAAgB,EAAE,GAAG,EAAE,CAAC,mBAAmB,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC;aAC3D,CAAC,CAAA;QACJ,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,CAAC,KAAK,CAAC,KAAK,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;YAClC,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAA;YACpB,OAAM;QACR,CAAC;QAED,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;YACd,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAA;YAC7C,OAAM;QACR,CAAC;QAED,YAAY,CAAC,OAAO,CAAC,CAAA;IACvB,CAAC;CACF,CAAC,CAAA;AAEF;;;;;;;GAOG;AACH,SAAS,YAAY,CAAC,OAA6B;IACjD,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,OAAO,CAAA;IAC1C,MAAM,KAAK,GAAG,KAAK,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC,CAAC,oBAAoB,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAA;IACrE,MAAM,SAAS,GAAG,KAAK,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,KAAK,CAAC,IAAI,GAAG,CAAA;IAC/D,OAAO,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC,KAAK,MAAM,KAAK,GAAG,SAAS,EAAE,CAAC,CAAA;IAEpD,IAAI,OAAO,CAAC,KAAK,KAAK,aAAa,EAAE,CAAC;QACpC,OAAO,CAAC,GAAG,CAAC,mEAAmE,CAAC,CAAA;QAChF,OAAM;IACR,CAAC;IAED,IAAI,OAAO,CAAC,KAAK,KAAK,2BAA2B,EAAE,CAAC;QAClD,4EAA4E;QAC5E,yEAAyE;QACzE,gDAAgD;QAChD,MAAM,KAAK,GAAG,OAAO,CAAC,iBAAiB,CAAA;QACvC,MAAM,KAAK,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,CAAA;QACnD,OAAO,CAAC,GAAG,CACT,oCAAoC,KAAK,GAAG,KAAK,sDAAsD,CACxG,CAAA;IACH,CAAC;SAAM,IAAI,OAAO,CAAC,aAAa,KAAK,IAAI,EAAE,CAAC;QAC1C,OAAO,CAAC,GAAG,CACT,iBAAiB,OAAO,CAAC,KAAK,4CAA4C,CAC3E,CAAA;IACH,CAAC;SAAM,IAAI,OAAO,CAAC,eAAe,EAAE,CAAC;QACnC,2EAA2E;QAC3E,iDAAiD;QACjD,OAAO,CAAC,GAAG,CACT,kBAAkB,OAAO,CAAC,OAAO,OAAO,OAAO,CAAC,UAAU,mEAAmE,CAC9H,CAAA;IACH,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,GAAG,CACT,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,aAAa,GAAG,GAAG,CAAC,eAAe,OAAO,CAAC,OAAO,OAAO,OAAO,CAAC,UAAU,kCAAkC,CACxI,CAAA;IACH,CAAC;IAED,IAAI,OAAO,CAAC,KAAK,KAAK,WAAW,EAAE,CAAC;QAClC,MAAM,KAAK,GAAG,OAAO,CAAC,UAAU;YAC9B,CAAC,CAAC,wBAAwB,OAAO,CAAC,UAAU,cAAc;YAC1D,CAAC,CAAC,yBAAyB,CAAA;QAC7B,OAAO,CAAC,GAAG,CAAC,kBAAkB,KAAK,KAAK,OAAO,CAAC,aAAa,oBAAoB,CAAC,CAAA;IACpF,CAAC;IAED,8EAA8E;IAC9E,uCAAuC;IACvC,KAAK,MAAM,IAAI,IAAI,gBAAgB,CAAC,OAAO,CAAC,MAAM,CAAC;QAAE,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;IAEtE,IAAI,OAAO,CAAC,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAClC,OAAO,CAAC,GAAG,CAAC,2BAA2B,CAAC,CAAA;QACxC,OAAM;IACR,CAAC;IAED,MAAM,IAAI,GACR,OAAO,CAAC,eAAe,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,OAAO,CAAC,eAAe,kBAAkB,CAAC,CAAC,CAAC,EAAE,CAAA;IACnF,OAAO,CAAC,GAAG,CAAC,sBAAsB,IAAI,GAAG,CAAC,CAAA;IAC1C,KAAK,MAAM,OAAO,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC;QACvC,MAAM,GAAG,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,0BAA0B,CAAA;QACvE,OAAO,CAAC,GAAG,CAAC,SAAS,OAAO,CAAC,UAAU,GAAG,GAAG,EAAE,CAAC,CAAA;QAChD,2EAA2E;QAC3E,uEAAuE;QACvE,+DAA+D;QAC/D,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAA;IACxC,CAAC;AACH,CAAC;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,UAAU,gBAAgB,CAAC,MAAiC;IAChE,IAAI,MAAM,KAAK,IAAI,EAAE,CAAC;QACpB,OAAO,CAAC,EAAE,EAAE,wEAAwE,CAAC,CAAA;IACvF,CAAC;IAED,MAAM,IAAI,GAAG,MAAM,CAAC,SAAS,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,cAAc,MAAM,CAAC,SAAS,GAAG,CAAA;IAC/E,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,MAAM,CAAA;IAChC,MAAM,KAAK,GAAG,CAAC,EAAE,EAAE,wBAAwB,IAAI,GAAG,CAAC,CAAA;IAEnD,IAAI,MAAM,CAAC,YAAY,KAAK,IAAI,EAAE,CAAC;QACjC,2EAA2E;QAC3E,0EAA0E;QAC1E,wEAAwE;QACxE,2EAA2E;QAC3E,KAAK,CAAC,IAAI,CACR,MAAM,CAAC,YAAY,KAAK,OAAO;YAC7B,CAAC,CAAC,sDAAsD,KAAK,CAAC,UAAU,8CAA8C,MAAM,CAAC,UAAU,4BAA4B;YACnK,CAAC,CAAC,MAAM,CAAC,YAAY,KAAK,QAAQ;gBAChC,CAAC,CAAC,uDAAuD,MAAM,CAAC,UAAU,uCAAuC;gBACjH,CAAC,CAAC,+DAA+D,KAAK,CAAC,UAAU,WAAW,MAAM,CAAC,UAAU,UAAU,CAC5H,CAAA;QACD,OAAO,KAAK,CAAA;IACd,CAAC;IAED,MAAM,IAAI,GACR,MAAM,CAAC,SAAS,KAAK,UAAU;QAC7B,CAAC,CAAC,YAAY;QACd,CAAC,CAAC,MAAM,CAAC,SAAS,KAAK,WAAW;YAChC,CAAC,CAAC,YAAY;YACd,CAAC,CAAC,gBAAgB,CAAA;IACxB,KAAK,CAAC,IAAI,CACR,eAAe,IAAI,uBAAuB,KAAK,CAAC,OAAO,OAAO,KAAK,CAAC,UAAU,8CAA8C,MAAM,CAAC,OAAO,OAAO,MAAM,CAAC,UAAU,aAAa,CAChL,CAAA;IACD,IAAI,MAAM,CAAC,UAAU,EAAE,CAAC;QACtB,KAAK,CAAC,IAAI,CACR,gEAAgE,MAAM,CAAC,UAAU,+BAA+B,CACjH,CAAA;IACH,CAAC;IACD,OAAO,KAAK,CAAA;AACd,CAAC;AAED,SAAS,MAAM,CAAC,KAAa;IAC3B,OAAO,KAAK;SACT,KAAK,CAAC,IAAI,CAAC;SACX,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,IAAI,EAAE,CAAC;SAC5B,IAAI,CAAC,IAAI,CAAC,CAAA;AACf,CAAC"}