mossbear 0.1.0-alpha.29 → 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.
- package/README.md +24 -8
- package/dist/commands/doctor.d.ts.map +1 -1
- package/dist/commands/doctor.js +7 -62
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/guides/history.d.ts +72 -0
- package/dist/commands/guides/history.d.ts.map +1 -0
- package/dist/commands/guides/history.js +217 -0
- package/dist/commands/guides/history.js.map +1 -0
- package/dist/commands/guides/index.d.ts.map +1 -1
- package/dist/commands/guides/index.js +4 -0
- package/dist/commands/guides/index.js.map +1 -1
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +10 -0
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/mcp.d.ts.map +1 -1
- package/dist/commands/mcp.js +6 -4
- package/dist/commands/mcp.js.map +1 -1
- package/dist/commands/pull.d.ts +22 -0
- package/dist/commands/pull.d.ts.map +1 -1
- package/dist/commands/pull.js +150 -75
- package/dist/commands/pull.js.map +1 -1
- package/dist/commands/status.d.ts.map +1 -1
- package/dist/commands/status.js +39 -25
- package/dist/commands/status.js.map +1 -1
- package/dist/commands/sync.d.ts.map +1 -1
- package/dist/commands/sync.js +59 -2
- package/dist/commands/sync.js.map +1 -1
- package/dist/commit-anchor.d.ts +25 -0
- package/dist/commit-anchor.d.ts.map +1 -0
- package/dist/commit-anchor.js +93 -0
- package/dist/commit-anchor.js.map +1 -0
- package/dist/config.d.ts +13 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +19 -36
- package/dist/config.js.map +1 -1
- package/dist/context/materialize.d.ts +200 -0
- package/dist/context/materialize.d.ts.map +1 -0
- package/dist/context/materialize.js +145 -0
- package/dist/context/materialize.js.map +1 -0
- package/dist/context/pull.d.ts +38 -54
- package/dist/context/pull.d.ts.map +1 -1
- package/dist/context/pull.js +34 -288
- package/dist/context/pull.js.map +1 -1
- package/dist/docs/guide-projection.d.ts +32 -0
- package/dist/docs/guide-projection.d.ts.map +1 -1
- package/dist/docs/guide-projection.js +55 -27
- package/dist/docs/guide-projection.js.map +1 -1
- package/dist/docs/relink-mapping.d.ts.map +1 -1
- package/dist/docs/relink-mapping.js +2 -3
- package/dist/docs/relink-mapping.js.map +1 -1
- package/dist/docs/repo-config.d.ts +0 -6
- package/dist/docs/repo-config.d.ts.map +1 -1
- package/dist/docs/repo-config.js +7 -37
- package/dist/docs/repo-config.js.map +1 -1
- package/dist/docs/sidecar.d.ts.map +1 -1
- package/dist/docs/sidecar.js +11 -3
- package/dist/docs/sidecar.js.map +1 -1
- package/dist/docs/status.d.ts +130 -14
- package/dist/docs/status.d.ts.map +1 -1
- package/dist/docs/status.js +160 -18
- package/dist/docs/status.js.map +1 -1
- package/dist/docs/subscribe.d.ts +14 -17
- package/dist/docs/subscribe.d.ts.map +1 -1
- package/dist/docs/subscribe.js +15 -46
- package/dist/docs/subscribe.js.map +1 -1
- package/dist/docs/sync-docs.d.ts +72 -3
- package/dist/docs/sync-docs.d.ts.map +1 -1
- package/dist/docs/sync-docs.js +491 -917
- package/dist/docs/sync-docs.js.map +1 -1
- package/dist/docs/sync-plan.d.ts +517 -0
- package/dist/docs/sync-plan.d.ts.map +1 -0
- package/dist/docs/sync-plan.js +872 -0
- package/dist/docs/sync-plan.js.map +1 -0
- package/dist/mcp/client.d.ts +28 -0
- package/dist/mcp/client.d.ts.map +1 -1
- package/dist/mcp/client.js +56 -13
- package/dist/mcp/client.js.map +1 -1
- package/dist/mcp/import-tool.d.ts +19 -7
- package/dist/mcp/import-tool.d.ts.map +1 -1
- package/dist/mcp/import-tool.js +5 -5
- package/dist/mcp/import-tool.js.map +1 -1
- package/dist/mcp/scope.d.ts +35 -2
- package/dist/mcp/scope.d.ts.map +1 -1
- package/dist/mcp/scope.js +34 -2
- package/dist/mcp/scope.js.map +1 -1
- package/dist/mcp/server.d.ts +29 -12
- package/dist/mcp/server.d.ts.map +1 -1
- package/dist/mcp/server.js +335 -73
- package/dist/mcp/server.js.map +1 -1
- package/dist/mcp/write-items.d.ts +73 -14
- package/dist/mcp/write-items.d.ts.map +1 -1
- package/dist/mcp/write-items.js +90 -22
- package/dist/mcp/write-items.js.map +1 -1
- package/dist/project-hooks.d.ts +60 -0
- package/dist/project-hooks.d.ts.map +1 -0
- package/dist/project-hooks.js +93 -0
- package/dist/project-hooks.js.map +1 -0
- package/dist/rules/guide-history-client.d.ts +70 -0
- package/dist/rules/guide-history-client.d.ts.map +1 -0
- package/dist/rules/guide-history-client.js +121 -0
- package/dist/rules/guide-history-client.js.map +1 -0
- package/dist/rules/import-paths.js +2 -2
- package/dist/rules/import-paths.js.map +1 -1
- package/dist/rules/repo-identity.d.ts +45 -0
- package/dist/rules/repo-identity.d.ts.map +1 -0
- package/dist/rules/repo-identity.js +59 -0
- package/dist/rules/repo-identity.js.map +1 -0
- package/dist/run-self-report.d.ts +68 -0
- package/dist/run-self-report.d.ts.map +1 -0
- package/dist/run-self-report.js +49 -0
- package/dist/run-self-report.js.map +1 -0
- package/dist/skill-template.d.ts +3 -3
- package/dist/skill-template.d.ts.map +1 -1
- package/dist/skill-template.js +59 -28
- package/dist/skill-template.js.map +1 -1
- package/dist/soft-json.d.ts +34 -0
- package/dist/soft-json.d.ts.map +1 -0
- package/dist/soft-json.js +44 -0
- package/dist/soft-json.js.map +1 -0
- package/dist/state/machine-cache.d.ts +34 -0
- package/dist/state/machine-cache.d.ts.map +1 -1
- package/dist/state/machine-cache.js +37 -0
- package/dist/state/machine-cache.js.map +1 -1
- package/dist/sync-batches.d.ts +22 -1
- package/dist/sync-batches.d.ts.map +1 -1
- package/dist/sync-batches.js +17 -0
- package/dist/sync-batches.js.map +1 -1
- package/dist/transcript/narration.d.ts +46 -0
- package/dist/transcript/narration.d.ts.map +1 -1
- package/dist/transcript/narration.js +69 -4
- package/dist/transcript/narration.js.map +1 -1
- package/dist/update/assets.d.ts.map +1 -1
- package/dist/update/assets.js +7 -57
- package/dist/update/assets.js.map +1 -1
- package/package.json +12 -14
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
|
|
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
|
|
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
|
|
|
@@ -69,10 +69,7 @@ mossbear sync --token <token> # remembered after the first successful sync
|
|
|
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
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
|
-
<<<<<<< HEAD
|
|
73
72
|
| `mossbear unlink <file>` | Stop delivering a file you linked — it stays on disk, and `mossbear link` puts it back |
|
|
74
|
-
=======
|
|
75
|
-
>>>>>>> origin/main
|
|
76
73
|
| `mossbear guides active` / `search` | List or search your synced guides |
|
|
77
74
|
| `mossbear suggest` | Review pending guide suggestions |
|
|
78
75
|
| `mossbear status` | Show pending actions + config status |
|
|
@@ -102,9 +99,28 @@ It reads the dashboard URL from `~/.mossbear/config.json`, so a `--dashboard-url
|
|
|
102
99
|
|
|
103
100
|
## Privacy
|
|
104
101
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
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.
|
|
108
124
|
|
|
109
125
|
## Links
|
|
110
126
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"doctor.d.ts","sourceRoot":"","sources":["../../src/commands/doctor.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"doctor.d.ts","sourceRoot":"","sources":["../../src/commands/doctor.ts"],"names":[],"mappings":"AA8CA,eAAO,MAAM,aAAa;;;;;;;;;;;EAwPxB,CAAA"}
|
package/dist/commands/doctor.js
CHANGED
|
@@ -1,14 +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';
|
|
7
5
|
import { repoBundleIds } from '../docs/delivery.js';
|
|
8
6
|
import { collidesWithHomeConfig, readRepoDocsConfig } from '../docs/repo-config.js';
|
|
9
|
-
import { MOSSBEAR_HOOK_COMMAND, MOSSBEAR_SYNC_COMMAND,
|
|
7
|
+
import { MOSSBEAR_HOOK_COMMAND, MOSSBEAR_SYNC_COMMAND, stopHookUploadsActions, } from '../hooks-settings.js';
|
|
10
8
|
import { createContextClient } from '../mcp/client.js';
|
|
11
9
|
import { resolveOnPath } from '../path-resolve.js';
|
|
10
|
+
import { detectLoggerHook, readProjectHooks } from '../project-hooks.js';
|
|
12
11
|
import { resolveRepoRoot } from '../repo-root.js';
|
|
13
12
|
import { discoverGuideFiles } from '../rules/discover.js';
|
|
14
13
|
import { verifyDashboardToken } from '../token-verify.js';
|
|
@@ -16,55 +15,6 @@ import { detectBundledSkillDrift } from '../update/assets.js';
|
|
|
16
15
|
import { checkForUpdate, formatUpdateNotice } from '../update/notice.js';
|
|
17
16
|
import { formatUpdateSuccess, performUpdate, syncGeneratedAssets, } from '../update/perform.js';
|
|
18
17
|
import { CLI_VERSION } from '../version.js';
|
|
19
|
-
/** The project's parsed `.claude/settings.json`, or null when absent/malformed. */
|
|
20
|
-
async function readProjectSettings() {
|
|
21
|
-
const settingsPath = join(process.cwd(), '.claude', 'settings.json');
|
|
22
|
-
try {
|
|
23
|
-
const raw = await readFile(settingsPath, 'utf8');
|
|
24
|
-
return JSON.parse(raw);
|
|
25
|
-
}
|
|
26
|
-
catch {
|
|
27
|
-
return null;
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
/**
|
|
31
|
-
* Which form of the logger hook this project's settings configure for one
|
|
32
|
-
* event, if any. Shared by `PostToolUse` (the success logger) and
|
|
33
|
-
* `PostToolUseFailure` (`hook-failure-event-registration`) — same command,
|
|
34
|
-
* same recognizer, only the settings.json key differs.
|
|
35
|
-
*/
|
|
36
|
-
function detectConfiguredHookFor(settings, event) {
|
|
37
|
-
try {
|
|
38
|
-
if (!settings)
|
|
39
|
-
return { form: 'none' };
|
|
40
|
-
const hooks = settings['hooks'];
|
|
41
|
-
const groups = hooks?.[event];
|
|
42
|
-
if (!Array.isArray(groups))
|
|
43
|
-
return { form: 'none' };
|
|
44
|
-
// Shares the recognizer with the merge so the two cannot disagree about
|
|
45
|
-
// what counts as configured — the substring match this replaced would miss
|
|
46
|
-
// the portable command and call a correctly wired repo unconfigured.
|
|
47
|
-
for (const group of groups) {
|
|
48
|
-
const groupHooks = group['hooks'];
|
|
49
|
-
if (!Array.isArray(groupHooks))
|
|
50
|
-
continue;
|
|
51
|
-
for (const hook of groupHooks) {
|
|
52
|
-
if (typeof hook === 'object' && hook !== null) {
|
|
53
|
-
if (isMossbearLoggerCommand(hook['command'])) {
|
|
54
|
-
return { form: 'portable' };
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
return { form: 'none' };
|
|
60
|
-
}
|
|
61
|
-
catch {
|
|
62
|
-
return { form: 'none' };
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
function detectConfiguredHook(settings) {
|
|
66
|
-
return detectConfiguredHookFor(settings, 'PostToolUse');
|
|
67
|
-
}
|
|
68
18
|
/**
|
|
69
19
|
* True when this project's Stop hooks upload the session (`mossbear sync`).
|
|
70
20
|
*
|
|
@@ -75,10 +25,7 @@ function detectConfiguredHook(settings) {
|
|
|
75
25
|
* is destroyed at session end the entire record is lost with it. Doctor
|
|
76
26
|
* reporting all-clear in that state is what let it go unnoticed here.
|
|
77
27
|
*/
|
|
78
|
-
function detectUploadHook(
|
|
79
|
-
if (!settings)
|
|
80
|
-
return false;
|
|
81
|
-
const hooks = settings['hooks'];
|
|
28
|
+
function detectUploadHook(hooks) {
|
|
82
29
|
return stopHookUploadsActions(hooks?.['Stop']);
|
|
83
30
|
}
|
|
84
31
|
export const doctorCommand = defineCommand({
|
|
@@ -99,12 +46,10 @@ export const doctorCommand = defineCommand({
|
|
|
99
46
|
},
|
|
100
47
|
},
|
|
101
48
|
async run({ args }) {
|
|
102
|
-
const
|
|
103
|
-
const
|
|
104
|
-
const
|
|
105
|
-
const
|
|
106
|
-
const failureHookConfigured = failureHook.form !== 'none';
|
|
107
|
-
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);
|
|
108
53
|
const hookBinPath = resolveOnPath(MOSSBEAR_HOOK_COMMAND);
|
|
109
54
|
// The Stop hooks invoke `mossbear`, which ships as a separate bin from
|
|
110
55
|
// `mossbear-hook` and can be missing while the other resolves.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"doctor.js","sourceRoot":"","sources":["../../src/commands/doctor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"doctor.js","sourceRoot":"","sources":["../../src/commands/doctor.ts"],"names":[],"mappings":"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"}
|
|
@@ -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":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/commands/guides/index.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,aAAa,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/commands/guides/index.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,aAAa,qDAwBxB,CAAA"}
|
|
@@ -18,6 +18,10 @@ export const guidesCommand = defineCommand({
|
|
|
18
18
|
project: () => import('./project.js').then((m) => m.guidesProjectCommand),
|
|
19
19
|
active: () => import('./active.js').then((m) => m.guidesActiveCommand),
|
|
20
20
|
search: () => import('./search.js').then((m) => m.guidesSearchCommand),
|
|
21
|
+
// The one verb here that reaches the network. `active` and `search` read the
|
|
22
|
+
// synced cache; verdicts are the server's and the CLI holds none of them by
|
|
23
|
+
// design, so there is nothing local for this to read.
|
|
24
|
+
history: () => import('./history.js').then((m) => m.guidesHistoryCommand),
|
|
21
25
|
},
|
|
22
26
|
});
|
|
23
27
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/commands/guides/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,OAAO,CAAA;AAErC,MAAM,CAAC,MAAM,aAAa,GAAG,aAAa,CAAC;IACzC,IAAI,EAAE;QACJ,IAAI,EAAE,QAAQ;QACd,WAAW,EAAE,oCAAoC;KAClD;IACD,WAAW,EAAE;QACX,6EAA6E;QAC7E,uEAAuE;QACvE,yEAAyE;QACzE,uDAAuD;QACvD,EAAE;QACF,2EAA2E;QAC3E,6EAA6E;QAC7E,2EAA2E;QAC3E,4EAA4E;QAC5E,6EAA6E;QAC7E,OAAO,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,oBAAoB,CAAC;QACzE,MAAM,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,mBAAmB,CAAC;QACtE,MAAM,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/commands/guides/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,OAAO,CAAA;AAErC,MAAM,CAAC,MAAM,aAAa,GAAG,aAAa,CAAC;IACzC,IAAI,EAAE;QACJ,IAAI,EAAE,QAAQ;QACd,WAAW,EAAE,oCAAoC;KAClD;IACD,WAAW,EAAE;QACX,6EAA6E;QAC7E,uEAAuE;QACvE,yEAAyE;QACzE,uDAAuD;QACvD,EAAE;QACF,2EAA2E;QAC3E,6EAA6E;QAC7E,2EAA2E;QAC3E,4EAA4E;QAC5E,6EAA6E;QAC7E,OAAO,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,oBAAoB,CAAC;QACzE,MAAM,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,mBAAmB,CAAC;QACtE,MAAM,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,mBAAmB,CAAC;QACtE,6EAA6E;QAC7E,4EAA4E;QAC5E,sDAAsD;QACtD,OAAO,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,oBAAoB,CAAC;KAC1E;CACF,CAAC,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AAkHA,eAAO,MAAM,kBAAkB,+JAM9B,CAAA;AAED,eAAO,MAAM,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AAkHA,eAAO,MAAM,kBAAkB,+JAM9B,CAAA;AAED,eAAO,MAAM,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA09BtB,CAAA"}
|
package/dist/commands/init.js
CHANGED
|
@@ -363,6 +363,13 @@ export const initCommand = defineCommand({
|
|
|
363
363
|
let skipHookMerge = false;
|
|
364
364
|
// Reported to the user below: "updated" a file that did not exist reads
|
|
365
365
|
// as though init edited something they had written.
|
|
366
|
+
//
|
|
367
|
+
// It has to advance as the run goes, which is why the writes below set it.
|
|
368
|
+
// Five hooks are installed in sequence and only the first creates the
|
|
369
|
+
// file; read once and never moved, this reported "created
|
|
370
|
+
// .claude/settings.json" five times for one creation and four amendments
|
|
371
|
+
// — observed on a fresh repo 2026-08-22. Copy rule 5: say what happened,
|
|
372
|
+
// specifically enough that the reader can check it.
|
|
366
373
|
let settingsExisted = false;
|
|
367
374
|
try {
|
|
368
375
|
const raw = await readFile(settingsPath, 'utf8');
|
|
@@ -387,6 +394,7 @@ export const initCommand = defineCommand({
|
|
|
387
394
|
if (loggerMerge.action === 'installed') {
|
|
388
395
|
settingsChanged = true;
|
|
389
396
|
console.log(` ${settingsExisted ? 'updated' : 'created'} .claude/settings.json with PostToolUse hook`);
|
|
397
|
+
settingsExisted = true;
|
|
390
398
|
}
|
|
391
399
|
else if (loggerMerge.action === 'repaired') {
|
|
392
400
|
settingsChanged = true;
|
|
@@ -412,6 +420,7 @@ export const initCommand = defineCommand({
|
|
|
412
420
|
if (failureMerge.action === 'installed') {
|
|
413
421
|
settingsChanged = true;
|
|
414
422
|
console.log(` ${settingsExisted ? 'updated' : 'created'} .claude/settings.json with PostToolUseFailure hook`);
|
|
423
|
+
settingsExisted = true;
|
|
415
424
|
}
|
|
416
425
|
else if (failureMerge.action === 'repaired') {
|
|
417
426
|
settingsChanged = true;
|
|
@@ -553,6 +562,7 @@ export const initCommand = defineCommand({
|
|
|
553
562
|
if (merge.action === 'installed') {
|
|
554
563
|
settingsChanged = true;
|
|
555
564
|
console.log(` ${settingsExisted ? 'updated' : 'created'} .claude/settings.json with ${event} hook (${entry.command})`);
|
|
565
|
+
settingsExisted = true;
|
|
556
566
|
}
|
|
557
567
|
else {
|
|
558
568
|
console.log(` .claude/settings.json already has ${event} hook (${entry.command}) — skipped`);
|