mossbear 0.1.0-alpha.28 → 0.1.0-alpha.29
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 +9 -5
- package/dist/commands/doctor.d.ts.map +1 -1
- package/dist/commands/doctor.js +54 -10
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/init.d.ts +1 -0
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +128 -68
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/link.d.ts +142 -0
- package/dist/commands/link.d.ts.map +1 -0
- package/dist/commands/link.js +272 -0
- package/dist/commands/link.js.map +1 -0
- package/dist/commands/pull.d.ts.map +1 -1
- package/dist/commands/pull.js +49 -9
- package/dist/commands/pull.js.map +1 -1
- package/dist/commands/status.d.ts.map +1 -1
- package/dist/commands/status.js +61 -2
- package/dist/commands/status.js.map +1 -1
- package/dist/commands/sync.d.ts.map +1 -1
- package/dist/commands/sync.js +89 -95
- package/dist/commands/sync.js.map +1 -1
- package/dist/commands/unlink.d.ts +118 -0
- package/dist/commands/unlink.d.ts.map +1 -0
- package/dist/commands/unlink.js +271 -0
- package/dist/commands/unlink.js.map +1 -0
- package/dist/context/pull.d.ts +11 -2
- package/dist/context/pull.d.ts.map +1 -1
- package/dist/context/pull.js +6 -3
- package/dist/context/pull.js.map +1 -1
- package/dist/docs/bundle-by-name.d.ts +47 -0
- package/dist/docs/bundle-by-name.d.ts.map +1 -0
- package/dist/docs/bundle-by-name.js +56 -0
- package/dist/docs/bundle-by-name.js.map +1 -0
- package/dist/docs/classify.d.ts +1 -1
- package/dist/docs/classify.d.ts.map +1 -1
- package/dist/docs/classify.js +2 -2
- package/dist/docs/classify.js.map +1 -1
- package/dist/docs/delivery-check.d.ts +25 -7
- package/dist/docs/delivery-check.d.ts.map +1 -1
- package/dist/docs/delivery-check.js +32 -11
- package/dist/docs/delivery-check.js.map +1 -1
- package/dist/docs/delivery.d.ts +105 -0
- package/dist/docs/delivery.d.ts.map +1 -0
- package/dist/docs/delivery.js +128 -0
- package/dist/docs/delivery.js.map +1 -0
- package/dist/docs/subscribe.d.ts +30 -30
- package/dist/docs/subscribe.d.ts.map +1 -1
- package/dist/docs/subscribe.js +37 -41
- package/dist/docs/subscribe.js.map +1 -1
- package/dist/docs/sync-docs.d.ts +18 -1
- package/dist/docs/sync-docs.d.ts.map +1 -1
- package/dist/docs/sync-docs.js +28 -18
- package/dist/docs/sync-docs.js.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7 -1
- package/dist/index.js.map +1 -1
- package/dist/mcp/client.d.ts +24 -5
- package/dist/mcp/client.d.ts.map +1 -1
- package/dist/mcp/client.js +14 -6
- package/dist/mcp/client.js.map +1 -1
- package/dist/mcp/server.d.ts.map +1 -1
- package/dist/mcp/server.js +57 -8
- package/dist/mcp/server.js.map +1 -1
- package/dist/rules/import-client.d.ts +1 -1
- package/dist/rules/unlink-client.d.ts +39 -0
- package/dist/rules/unlink-client.d.ts.map +1 -0
- package/dist/rules/unlink-client.js +86 -0
- package/dist/rules/unlink-client.js.map +1 -0
- package/dist/sync-client.d.ts.map +1 -1
- package/dist/sync-client.js +25 -1
- package/dist/sync-client.js.map +1 -1
- package/package.json +5 -5
- package/dist/commands/import.d.ts +0 -57
- package/dist/commands/import.d.ts.map +0 -1
- package/dist/commands/import.js +0 -217
- package/dist/commands/import.js.map +0 -1
- package/dist/docs/enroll-default-bundle.d.ts +0 -71
- package/dist/docs/enroll-default-bundle.d.ts.map +0 -1
- package/dist/docs/enroll-default-bundle.js +0 -111
- package/dist/docs/enroll-default-bundle.js.map +0 -1
- package/dist/docs/own-bundle.d.ts +0 -76
- package/dist/docs/own-bundle.d.ts.map +0 -1
- package/dist/docs/own-bundle.js +0 -96
- package/dist/docs/own-bundle.js.map +0 -1
- package/dist/docs/resolve-subscriptions.d.ts +0 -67
- package/dist/docs/resolve-subscriptions.d.ts.map +0 -1
- package/dist/docs/resolve-subscriptions.js +0 -67
- package/dist/docs/resolve-subscriptions.js.map +0 -1
package/README.md
CHANGED
|
@@ -68,7 +68,11 @@ 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
|
|
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
|
+
| `mossbear unlink <file>` | Stop delivering a file you linked — it stays on disk, and `mossbear link` puts it back |
|
|
74
|
+
=======
|
|
75
|
+
>>>>>>> origin/main
|
|
72
76
|
| `mossbear guides active` / `search` | List or search your synced guides |
|
|
73
77
|
| `mossbear suggest` | Review pending guide suggestions |
|
|
74
78
|
| `mossbear status` | Show pending actions + config status |
|
|
@@ -79,16 +83,16 @@ mossbear sync --token <token> # remembered after the first successful sync
|
|
|
79
83
|
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
84
|
|
|
81
85
|
```bash
|
|
82
|
-
mossbear
|
|
83
|
-
mossbear
|
|
84
|
-
mossbear
|
|
86
|
+
mossbear link # pick from a list; Enter takes all of them
|
|
87
|
+
mossbear link --yes # no prompt (required when stdin is not a TTY)
|
|
88
|
+
mossbear link --global # also scan ~/.claude/CLAUDE.md
|
|
85
89
|
```
|
|
86
90
|
|
|
87
91
|
Files a context bundle already manages are **listed as managed** rather than hidden,
|
|
88
92
|
and cannot be selected — they are canonical in the dashboard, so edit them there or
|
|
89
93
|
on disk and run `mossbear sync`.
|
|
90
94
|
|
|
91
|
-
Re-run `mossbear
|
|
95
|
+
Re-run `mossbear link` after editing a guide file. There is no file watcher: a
|
|
92
96
|
watcher pushed one import per save, and because import has no update path, each save
|
|
93
97
|
filed a *new* guide row rather than updating the existing one. Continuous guide sync
|
|
94
98
|
returns via `mossbear sync` once guides have stable identity — see
|
|
@@ -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":"AA2GA,eAAO,MAAM,aAAa;;;;;;;;;;;EAyPxB,CAAA"}
|
package/dist/commands/doctor.js
CHANGED
|
@@ -4,8 +4,10 @@ import { defineCommand } from 'citty';
|
|
|
4
4
|
import { MOSSBEAR_TOKEN_ENV, readEnvToken, resolveDashboardUrl, resolveToken, } from '../config.js';
|
|
5
5
|
import { describeDashboardHealth } from '../dashboard-health.js';
|
|
6
6
|
import { describeGuideDelivery } from '../docs/delivery-check.js';
|
|
7
|
+
import { repoBundleIds } from '../docs/delivery.js';
|
|
7
8
|
import { collidesWithHomeConfig, readRepoDocsConfig } from '../docs/repo-config.js';
|
|
8
9
|
import { MOSSBEAR_HOOK_COMMAND, MOSSBEAR_SYNC_COMMAND, isMossbearLoggerCommand, stopHookUploadsActions, } from '../hooks-settings.js';
|
|
10
|
+
import { createContextClient } from '../mcp/client.js';
|
|
9
11
|
import { resolveOnPath } from '../path-resolve.js';
|
|
10
12
|
import { resolveRepoRoot } from '../repo-root.js';
|
|
11
13
|
import { discoverGuideFiles } from '../rules/discover.js';
|
|
@@ -127,8 +129,30 @@ export const doctorCommand = defineCommand({
|
|
|
127
129
|
})
|
|
128
130
|
.then((files) => ({ files, failed: false }))
|
|
129
131
|
.catch(() => ({ files: [], failed: true }));
|
|
132
|
+
// The account scope, which only the server can answer. `null` when this run
|
|
133
|
+
// has no token or the dashboard is unreachable — deliberately not zero, see
|
|
134
|
+
// `GuideDeliveryInput.userSubscriptionCount`.
|
|
135
|
+
const deliveryToken = await resolveToken().catch(() => '');
|
|
136
|
+
let userSubscriptionCount = null;
|
|
137
|
+
if (deliveryToken) {
|
|
138
|
+
try {
|
|
139
|
+
const client = createContextClient({
|
|
140
|
+
dashboardUrl: await resolveDashboardUrl(args['dashboard-url']),
|
|
141
|
+
token: deliveryToken,
|
|
142
|
+
});
|
|
143
|
+
const resolved = await client.resolveSubscriptions(repoBundleIds(repoDocs.subscriptions));
|
|
144
|
+
userSubscriptionCount = resolved.bundles.filter(({ scopes }) => scopes.includes('user')).length;
|
|
145
|
+
}
|
|
146
|
+
catch {
|
|
147
|
+
// Left null. The dashboard probe further down reports an unreachable or
|
|
148
|
+
// rejected token as its own check, so a second message here would say
|
|
149
|
+
// the same thing twice — and this check's own detail line already tells
|
|
150
|
+
// the user it could not look.
|
|
151
|
+
}
|
|
152
|
+
}
|
|
130
153
|
const delivery = describeGuideDelivery({
|
|
131
|
-
|
|
154
|
+
repoSubscriptionCount: repoDocs.subscriptions.length,
|
|
155
|
+
userSubscriptionCount,
|
|
132
156
|
guideFileCount: discovered.files.length,
|
|
133
157
|
malformedConfig: repoDocs.malformed,
|
|
134
158
|
discoveryFailed: discovered.failed,
|
|
@@ -161,10 +185,16 @@ export const doctorCommand = defineCommand({
|
|
|
161
185
|
},
|
|
162
186
|
{
|
|
163
187
|
label: 'Claude Code hooks configured',
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
188
|
+
// Configured is not the same as able to run — the same distinction the
|
|
189
|
+
// two checks below already make. Without `runnerOk` a stripped PATH
|
|
190
|
+
// rendered `✗ mossbear-hook on PATH` directly above a `✓` here, so the
|
|
191
|
+
// inert case reported as healthy.
|
|
192
|
+
ok: hooksConfigured && runnerOk,
|
|
193
|
+
detail: !hooksConfigured
|
|
194
|
+
? 'not configured — run `mossbear init` in your project'
|
|
195
|
+
: runnerOk
|
|
196
|
+
? `.claude/settings.json has PostToolUse hook (${MOSSBEAR_HOOK_COMMAND})`
|
|
197
|
+
: `${MOSSBEAR_HOOK_COMMAND} not on PATH — reinstall globally (npm install -g mossbear)`,
|
|
168
198
|
},
|
|
169
199
|
// Only meaningful once the logger is wired: with no PostToolUse hook
|
|
170
200
|
// there is nothing to upload, and the check above already says so. Two
|
|
@@ -196,7 +226,7 @@ export const doctorCommand = defineCommand({
|
|
|
196
226
|
// case `missingHookPathWarning` already covers for init.
|
|
197
227
|
ok: uploadConfigured && mossbearBinPath !== null,
|
|
198
228
|
detail: !uploadConfigured
|
|
199
|
-
? `actions are being logged to ~/.mossbear/runs/ and never uploaded — add
|
|
229
|
+
? `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
230
|
: mossbearBinPath === null
|
|
201
231
|
? '`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
232
|
: `.claude/settings.json has Stop hook (${MOSSBEAR_SYNC_COMMAND})`,
|
|
@@ -209,7 +239,11 @@ export const doctorCommand = defineCommand({
|
|
|
209
239
|
for (const check of checks) {
|
|
210
240
|
const icon = check.ok ? '✓' : '✗';
|
|
211
241
|
const line = ` ${icon} ${check.label}`;
|
|
212
|
-
|
|
242
|
+
// A failing check always shows its detail: the detail *is* the remedy,
|
|
243
|
+
// and hiding it behind --verbose left the default run printing bare `✗`
|
|
244
|
+
// labels under a summary that says "See above for details".
|
|
245
|
+
const detail = check.detail ?? '';
|
|
246
|
+
console.log(!check.ok || args.verbose ? `${line}${detail ? ` (${detail})` : ''}` : line);
|
|
213
247
|
if (!check.ok)
|
|
214
248
|
allOk = false;
|
|
215
249
|
}
|
|
@@ -219,6 +253,7 @@ export const doctorCommand = defineCommand({
|
|
|
219
253
|
// broken connection instead of a misleading "configured" — that gap is the
|
|
220
254
|
// activation-failure signal this check exists to close.
|
|
221
255
|
const token = await resolveToken().catch(() => '');
|
|
256
|
+
let verification = null;
|
|
222
257
|
if (!token) {
|
|
223
258
|
console.log(` i ${describeDashboardHealth('unconfigured', '')}`);
|
|
224
259
|
}
|
|
@@ -230,7 +265,7 @@ export const doctorCommand = defineCommand({
|
|
|
230
265
|
console.log(` i token from $${MOSSBEAR_TOKEN_ENV}`);
|
|
231
266
|
}
|
|
232
267
|
const dashboardUrl = await resolveDashboardUrl(args['dashboard-url']);
|
|
233
|
-
|
|
268
|
+
verification = await verifyDashboardToken(dashboardUrl, token);
|
|
234
269
|
console.log(` i ${describeDashboardHealth(verification, dashboardUrl)}`);
|
|
235
270
|
}
|
|
236
271
|
// Repo-local skills are user-editable, so they are only reported (see
|
|
@@ -242,10 +277,19 @@ export const doctorCommand = defineCommand({
|
|
|
242
277
|
' run `mossbear init --skills-only` to rewrite them (this overwrites local edits)');
|
|
243
278
|
}
|
|
244
279
|
if (!allOk) {
|
|
245
|
-
|
|
280
|
+
// The verdict goes to stdout with the checks it summarizes; only the
|
|
281
|
+
// pointer to the next command goes to stderr. Splitting them left a
|
|
282
|
+
// piped run with no verdict at all on the failing path.
|
|
283
|
+
console.log('\nSome checks failed.');
|
|
284
|
+
console.error('Run `mossbear doctor --verbose` for the full detail on each.');
|
|
246
285
|
process.exit(1);
|
|
247
286
|
}
|
|
248
|
-
|
|
287
|
+
// The connection is informational and never fails the run (see above), but
|
|
288
|
+
// it must not be summarized away either: a rejected token means nothing
|
|
289
|
+
// will sync, and "All checks passed." on its own reads as a clean bill.
|
|
290
|
+
console.log(verification === 'rejected'
|
|
291
|
+
? '\nEnvironment checks passed. The dashboard is not accepting this token, so nothing will sync until you replace it.'
|
|
292
|
+
: '\nAll checks passed.');
|
|
249
293
|
// Doctor is the "check and fix my setup" surface, so it is the one place
|
|
250
294
|
// that offers to run the update rather than just naming it. Suppressed
|
|
251
295
|
// 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":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAA;AAC3C,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAEhC,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,sBAAsB,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAA;AACnF,OAAO,EACL,qBAAqB,EACrB,qBAAqB,EACrB,uBAAuB,EACvB,sBAAsB,GACvB,MAAM,sBAAsB,CAAA;AAC7B,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAA;AAClD,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAA;AACjD,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAA;AACzD,OAAO,
|
|
1
|
+
{"version":3,"file":"doctor.js","sourceRoot":"","sources":["../../src/commands/doctor.ts"],"names":[],"mappings":"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"}
|
package/dist/commands/init.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
export declare const AGENTS_MD_TEMPLATE = "# AGENTS.md\n\n## Rules\n\n<!-- Add rules below. Adopt them with `mossbear link` and the dashboard\n grades each session's actions against them. -->\n";
|
|
1
2
|
export declare const initCommand: import("citty").CommandDef<{
|
|
2
3
|
force: {
|
|
3
4
|
type: "boolean";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"
|
|
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;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAg9BtB,CAAA"}
|
package/dist/commands/init.js
CHANGED
|
@@ -2,10 +2,11 @@ import { mkdir, writeFile, readFile, access, chmod } from 'node:fs/promises';
|
|
|
2
2
|
import { homedir } from 'node:os';
|
|
3
3
|
import { join } from 'node:path';
|
|
4
4
|
import { createInterface } from 'node:readline/promises';
|
|
5
|
-
import {
|
|
5
|
+
import { PROTOCOL_VERSION } from '@mossbear/protocol';
|
|
6
6
|
import { defineCommand } from 'citty';
|
|
7
|
-
import { MOSSBEAR_CONFIG_MODE, DEFAULT_DASHBOARD_URL, ensureMossbearDir, normalizeDashboardUrl, readConfigDashboardUrl, readConfigDiscoverGlobal, removeConfigEvalSection, resolveDashboardUrl, resolveToken, writeConfigDashboardUrl, writeConfigDiscoverGlobal, writeConfigToken, } from '../config.js';
|
|
8
|
-
import {
|
|
7
|
+
import { MOSSBEAR_CONFIG_MODE, DEFAULT_DASHBOARD_URL, MOSSBEAR_DASHBOARD_URL_ENV, ensureMossbearDir, normalizeDashboardUrl, readConfigDashboardUrl, readEnvDashboardUrl, readConfigDiscoverGlobal, removeConfigEvalSection, resolveDashboardUrl, resolveToken, writeConfigDashboardUrl, writeConfigDiscoverGlobal, writeConfigToken, } from '../config.js';
|
|
8
|
+
import { deliveryBundles, legacySubscribedSlugs, legacySubscriptionMessage, repoBundleIds, } from '../docs/delivery.js';
|
|
9
|
+
import { readRepoDocsConfig, readRepoProjectId } from '../docs/repo-config.js';
|
|
9
10
|
import { resolveInitSubscriptionSelection, subscribeBundleSelections, } from '../docs/subscribe.js';
|
|
10
11
|
import { formatDocsSyncLine, syncSubscribedDocs } from '../docs/sync-docs.js';
|
|
11
12
|
import { errText } from '../err-text.js';
|
|
@@ -43,7 +44,10 @@ async function writeBundledSkills(cwd, overwrite) {
|
|
|
43
44
|
else {
|
|
44
45
|
await mkdir(skillDir, { recursive: true });
|
|
45
46
|
await writeFile(skillPath, skill.content);
|
|
46
|
-
|
|
47
|
+
// Say what actually happened: this is an unprompted, unrecoverable
|
|
48
|
+
// overwrite, and "updated" reads as a merge. `AGENTS.md` below already
|
|
49
|
+
// says "overwrote" for the same operation.
|
|
50
|
+
console.log(` ${skillExists ? `overwrote ${rel} (any local edits are gone)` : `created ${rel}`}`);
|
|
47
51
|
}
|
|
48
52
|
}
|
|
49
53
|
catch (err) {
|
|
@@ -52,11 +56,22 @@ async function writeBundledSkills(cwd, overwrite) {
|
|
|
52
56
|
}
|
|
53
57
|
}
|
|
54
58
|
}
|
|
55
|
-
|
|
59
|
+
/**
|
|
60
|
+
* The adoption verb, as it is spelled for users.
|
|
61
|
+
*
|
|
62
|
+
* Interpolated into anything Mossbear writes to a user's disk rather than typed
|
|
63
|
+
* inline. `AGENTS_MD_TEMPLATE` below is committed into the user's own repo, so a
|
|
64
|
+
* hardcoded command name survives every later rename **in a file we can never
|
|
65
|
+
* reach again** — which is exactly what happened to `mossbear import` before the
|
|
66
|
+
* 2026-08-21 rename. A future call site must not have to remember this
|
|
67
|
+
* (Planning Principle 14).
|
|
68
|
+
*/
|
|
69
|
+
const ADOPT_VERB = 'mossbear link';
|
|
70
|
+
export const AGENTS_MD_TEMPLATE = `# AGENTS.md
|
|
56
71
|
|
|
57
72
|
## Rules
|
|
58
73
|
|
|
59
|
-
<!-- Add rules below.
|
|
74
|
+
<!-- Add rules below. Adopt them with \`${ADOPT_VERB}\` and the dashboard
|
|
60
75
|
grades each session's actions against them. -->
|
|
61
76
|
`;
|
|
62
77
|
export const initCommand = defineCommand({
|
|
@@ -206,7 +221,26 @@ export const initCommand = defineCommand({
|
|
|
206
221
|
// "https://app.mossbear.io/some/path " collapses to origin only.
|
|
207
222
|
const flagDashboardUrl = normalizeDashboardUrl(args['dashboard-url']);
|
|
208
223
|
if (args['dashboard-url'].trim() && !flagDashboardUrl) {
|
|
209
|
-
|
|
224
|
+
// A mistyped flag is user input, not a crash: `pull` and `sync` answer
|
|
225
|
+
// the same class with one line and an exit code, and throwing here put a
|
|
226
|
+
// Node stack trace on screen twice.
|
|
227
|
+
console.error(`--dashboard-url needs a full http(s) URL, e.g. https://app.mossbear.io — got: ${args['dashboard-url']}`);
|
|
228
|
+
process.exitCode = 1;
|
|
229
|
+
return;
|
|
230
|
+
}
|
|
231
|
+
// `readEnvDashboardUrl` throws on a malformed value by design (a silent
|
|
232
|
+
// fallback would send a staging container's verdicts to prod). Answer that
|
|
233
|
+
// here the way the `--dashboard-url` branch above does — one line and a
|
|
234
|
+
// failing exit — rather than letting it escape as an uncaught exception
|
|
235
|
+
// after init has already written files.
|
|
236
|
+
let envDashboardUrl = '';
|
|
237
|
+
try {
|
|
238
|
+
envDashboardUrl = readEnvDashboardUrl();
|
|
239
|
+
}
|
|
240
|
+
catch {
|
|
241
|
+
console.error(`$${MOSSBEAR_DASHBOARD_URL_ENV} needs a full http(s) URL, e.g. https://app.mossbear.io — got: ${process.env[MOSSBEAR_DASHBOARD_URL_ENV] ?? ''}`);
|
|
242
|
+
process.exitCode = 1;
|
|
243
|
+
return;
|
|
210
244
|
}
|
|
211
245
|
const existingDashboardUrl = await readConfigDashboardUrl().catch(() => '');
|
|
212
246
|
if (flagDashboardUrl) {
|
|
@@ -216,6 +250,12 @@ export const initCommand = defineCommand({
|
|
|
216
250
|
else if (existingDashboardUrl) {
|
|
217
251
|
console.log(` ~/.mossbear/config.json: dashboardUrl = ${existingDashboardUrl} (pass --dashboard-url to change)`);
|
|
218
252
|
}
|
|
253
|
+
else if (envDashboardUrl) {
|
|
254
|
+
// The env var outranks the config file (`config.ts` → resolveDashboardUrl),
|
|
255
|
+
// so reporting the config's fallback here named a dashboard the runtime
|
|
256
|
+
// would not actually use. `doctor` already names $MOSSBEAR_TOKEN the same way.
|
|
257
|
+
console.log(` dashboard URL comes from $${MOSSBEAR_DASHBOARD_URL_ENV} (${envDashboardUrl}) — it takes precedence over ~/.mossbear/config.json`);
|
|
258
|
+
}
|
|
219
259
|
else if (!args.prompt || !process.stdin.isTTY) {
|
|
220
260
|
console.log(` ~/.mossbear/config.json: dashboardUrl unset — runtime falls back to ${DEFAULT_DASHBOARD_URL}`);
|
|
221
261
|
}
|
|
@@ -321,13 +361,18 @@ export const initCommand = defineCommand({
|
|
|
321
361
|
await mkdir(claudeDir, { recursive: true });
|
|
322
362
|
let settings = {};
|
|
323
363
|
let skipHookMerge = false;
|
|
364
|
+
// Reported to the user below: "updated" a file that did not exist reads
|
|
365
|
+
// as though init edited something they had written.
|
|
366
|
+
let settingsExisted = false;
|
|
324
367
|
try {
|
|
325
368
|
const raw = await readFile(settingsPath, 'utf8');
|
|
369
|
+
settingsExisted = true;
|
|
326
370
|
settings = JSON.parse(raw);
|
|
327
371
|
}
|
|
328
372
|
catch (err) {
|
|
329
373
|
if (err.code !== 'ENOENT') {
|
|
330
|
-
console.warn('
|
|
374
|
+
console.warn(' .claude/settings.json could not be read as JSON, so no hooks were installed — nothing this agent does will be recorded.\n' +
|
|
375
|
+
' Fix or delete that file, then run `mossbear init` again.');
|
|
331
376
|
skipHookMerge = true;
|
|
332
377
|
}
|
|
333
378
|
}
|
|
@@ -341,7 +386,7 @@ export const initCommand = defineCommand({
|
|
|
341
386
|
hooks['PostToolUse'] = loggerMerge.postToolUse;
|
|
342
387
|
if (loggerMerge.action === 'installed') {
|
|
343
388
|
settingsChanged = true;
|
|
344
|
-
console.log('
|
|
389
|
+
console.log(` ${settingsExisted ? 'updated' : 'created'} .claude/settings.json with PostToolUse hook`);
|
|
345
390
|
}
|
|
346
391
|
else if (loggerMerge.action === 'repaired') {
|
|
347
392
|
settingsChanged = true;
|
|
@@ -366,7 +411,7 @@ export const initCommand = defineCommand({
|
|
|
366
411
|
hooks['PostToolUseFailure'] = failureMerge.postToolUse;
|
|
367
412
|
if (failureMerge.action === 'installed') {
|
|
368
413
|
settingsChanged = true;
|
|
369
|
-
console.log('
|
|
414
|
+
console.log(` ${settingsExisted ? 'updated' : 'created'} .claude/settings.json with PostToolUseFailure hook`);
|
|
370
415
|
}
|
|
371
416
|
else if (failureMerge.action === 'repaired') {
|
|
372
417
|
settingsChanged = true;
|
|
@@ -507,7 +552,7 @@ export const initCommand = defineCommand({
|
|
|
507
552
|
hooks[event] = merge.groups;
|
|
508
553
|
if (merge.action === 'installed') {
|
|
509
554
|
settingsChanged = true;
|
|
510
|
-
console.log(` updated .claude/settings.json with ${event} hook (${entry.command})`);
|
|
555
|
+
console.log(` ${settingsExisted ? 'updated' : 'created'} .claude/settings.json with ${event} hook (${entry.command})`);
|
|
511
556
|
}
|
|
512
557
|
else {
|
|
513
558
|
console.log(` .claude/settings.json already has ${event} hook (${entry.command}) — skipped`);
|
|
@@ -593,10 +638,6 @@ export const initCommand = defineCommand({
|
|
|
593
638
|
id: bundle.id,
|
|
594
639
|
slug: bundle.slug,
|
|
595
640
|
name: bundle.name,
|
|
596
|
-
// Carried, not dropped: the listing spans every workspace the caller
|
|
597
|
-
// belongs to, so two bundles here can share a slug and only one of
|
|
598
|
-
// them is theirs to subscribe a repo to.
|
|
599
|
-
ownedByCaller: bundle.ownedByCaller,
|
|
600
641
|
}));
|
|
601
642
|
if (offered.length > 0) {
|
|
602
643
|
let answer = '';
|
|
@@ -609,72 +650,92 @@ export const initCommand = defineCommand({
|
|
|
609
650
|
// Raised by Codex on #593.
|
|
610
651
|
if (interactive && !forcedPull) {
|
|
611
652
|
console.log('\nSubscribe this repo to bundles (it receives their members):');
|
|
653
|
+
console.log('Your own guides come with your account either way.');
|
|
612
654
|
offered.forEach((bundle, index) => {
|
|
613
|
-
|
|
614
|
-
// workspace puts a namesake in this list too, and labelling both
|
|
615
|
-
// "(default)" offers a choice the picker cannot honour: a
|
|
616
|
-
// selection resolves to the bundle the caller owns.
|
|
617
|
-
const marker = bundle.slug === DEFAULT_GUIDES_SLUG && bundle.ownedByCaller !== false
|
|
618
|
-
? ' (default)'
|
|
619
|
-
: '';
|
|
620
|
-
console.log(` ${index + 1}. ${bundle.name} [${bundle.slug}]${marker}`);
|
|
655
|
+
console.log(` ${index + 1}. ${bundle.name} [${bundle.slug}]`);
|
|
621
656
|
});
|
|
622
657
|
const rl = createInterface({ input: process.stdin, output: process.stdout });
|
|
623
658
|
try {
|
|
624
|
-
answer = await rl.question('Numbers or slugs, comma-separated [enter =
|
|
659
|
+
answer = await rl.question('Numbers or slugs, comma-separated [enter = none]: ');
|
|
625
660
|
}
|
|
626
661
|
finally {
|
|
627
662
|
rl.close();
|
|
628
663
|
}
|
|
629
664
|
}
|
|
630
|
-
// An empty answer
|
|
631
|
-
//
|
|
632
|
-
// on one rule
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
}
|
|
637
|
-
else {
|
|
665
|
+
// An empty answer means no *repo* subscription — a complete answer
|
|
666
|
+
// now that a user-scoped subscription reaches every repo the account
|
|
667
|
+
// syncs, so the forced path and a bare Enter converge on one rule
|
|
668
|
+
// rather than two (`bundle-identity-collapse-plan.md` → Slice A2).
|
|
669
|
+
const selections = resolveInitSubscriptionSelection(answer, offered);
|
|
670
|
+
if (selections.length > 0) {
|
|
638
671
|
const result = await subscribeBundleSelections(cwd, selections);
|
|
639
672
|
if (result.ok) {
|
|
640
673
|
console.log(` Subscribed to ${selections.map(({ slug }) => slug).join(', ')} — commit .mossbear/config.json so teammates get the same`);
|
|
641
674
|
if (result.removedToken) {
|
|
642
675
|
console.warn(' warning: removed an API token from .mossbear/config.json — rotate it if that file was ever committed.');
|
|
643
676
|
}
|
|
644
|
-
// Materialize immediately, through the one reconciler. A failure
|
|
645
|
-
// here is reported and not fatal: the subscription is already
|
|
646
|
-
// committed, so the next `mossbear sync` materializes anyway — the
|
|
647
|
-
// repo is correctly configured either way, which is the
|
|
648
|
-
// difference between this and the engine it replaced.
|
|
649
|
-
try {
|
|
650
|
-
const docsResult = await syncSubscribedDocs(client, selections.map(({ slug }) => slug), resolveRepoRoot(cwd),
|
|
651
|
-
// **`prune: false` is load-bearing, not caution.**
|
|
652
|
-
// `syncSubscribedDocs` treats its bundle list as the
|
|
653
|
-
// exhaustive subscription set and retires mappings absent
|
|
654
|
-
// from it. `subscribeBundleSelections` *merges* into any
|
|
655
|
-
// subscriptions the repo already had, so passing only this
|
|
656
|
-
// run's selections would unlink files still owned by a
|
|
657
|
-
// bundle the user did not happen to re-select — on a re-run
|
|
658
|
-
// of `init`, silently. `init` is a first-run materialize and
|
|
659
|
-
// has no business retiring anything; `mossbear sync` owns the
|
|
660
|
-
// exhaustive pass, and prints the retirement lines that go
|
|
661
|
-
// with it. Raised by Codex on #593.
|
|
662
|
-
{ prune: false });
|
|
663
|
-
for (const bundleResult of docsResult.results) {
|
|
664
|
-
console.log(formatDocsSyncLine(bundleResult));
|
|
665
|
-
for (const path of bundleResult.wroteOutsideDir) {
|
|
666
|
-
materializedPaths.add(path);
|
|
667
|
-
}
|
|
668
|
-
}
|
|
669
|
-
}
|
|
670
|
-
catch (err) {
|
|
671
|
-
console.warn(` warning: subscribed, but could not materialize yet — ${errText(err)}. Run \`mossbear sync\`.`);
|
|
672
|
-
}
|
|
673
677
|
}
|
|
674
678
|
else {
|
|
675
679
|
console.warn(` warning: could not record the subscription (${result.reason})`);
|
|
676
680
|
}
|
|
677
681
|
}
|
|
682
|
+
// **Materialize the union, not the selection.** What this repo
|
|
683
|
+
// receives is its committed subscriptions plus the account's, and the
|
|
684
|
+
// account half is exactly what makes a bare Enter a complete answer —
|
|
685
|
+
// so materializing only what was just typed would leave
|
|
686
|
+
// `--pull-guides` ("restore guidance without prompting") delivering
|
|
687
|
+
// nothing on the path it exists for.
|
|
688
|
+
//
|
|
689
|
+
// A failure here is reported and not fatal: any subscription is
|
|
690
|
+
// already committed, so the next `mossbear sync` materializes anyway —
|
|
691
|
+
// the repo is correctly configured either way, which is the difference
|
|
692
|
+
// between this and the engine it replaced.
|
|
693
|
+
try {
|
|
694
|
+
const docsRoot = resolveRepoRoot(cwd);
|
|
695
|
+
const committed = await readRepoDocsConfig(docsRoot);
|
|
696
|
+
const delivery = await client.resolveSubscriptions(repoBundleIds(committed.subscriptions));
|
|
697
|
+
const subscribed = deliveryBundles(delivery);
|
|
698
|
+
// Named here as well as in `mossbear sync`. A pre-id entry resolves to
|
|
699
|
+
// nothing now, so without this an upgrading repo would be told it has
|
|
700
|
+
// no subscriptions — or quietly get only its account-scoped bundles —
|
|
701
|
+
// while the entry it does have goes unmentioned. Raised by Codex on
|
|
702
|
+
// #736.
|
|
703
|
+
for (const legacy of legacySubscribedSlugs(committed.subscriptions)) {
|
|
704
|
+
console.warn(legacySubscriptionMessage(legacy));
|
|
705
|
+
}
|
|
706
|
+
if (subscribed.length === 0) {
|
|
707
|
+
console.log(' Nothing subscribed yet — `mossbear pull <bundle>` subscribes this repo, or subscribe a bundle to your account in the dashboard.');
|
|
708
|
+
}
|
|
709
|
+
else {
|
|
710
|
+
const docsResult = await syncSubscribedDocs(client, subscribed, docsRoot,
|
|
711
|
+
// **`prune: false` is load-bearing, not caution.**
|
|
712
|
+
// `syncSubscribedDocs` treats its bundle list as the exhaustive
|
|
713
|
+
// subscription set and retires mappings absent from it. This
|
|
714
|
+
// list is the union as the server currently reports it, so a
|
|
715
|
+
// transient omission — a workspace membership still
|
|
716
|
+
// propagating, a bundle mid-move — would unlink files on a
|
|
717
|
+
// re-run of `init`, silently. `init` is a first-run materialize
|
|
718
|
+
// and has no business retiring anything; `mossbear sync` owns the
|
|
719
|
+
// exhaustive pass, and prints the retirement lines that go with
|
|
720
|
+
// it. Raised by Codex on #593.
|
|
721
|
+
{ prune: false });
|
|
722
|
+
for (const bundleResult of docsResult.results) {
|
|
723
|
+
console.log(formatDocsSyncLine(bundleResult));
|
|
724
|
+
for (const path of bundleResult.wroteOutsideDir) {
|
|
725
|
+
materializedPaths.add(path);
|
|
726
|
+
}
|
|
727
|
+
}
|
|
728
|
+
}
|
|
729
|
+
}
|
|
730
|
+
catch (err) {
|
|
731
|
+
console.warn(` warning: could not materialize your bundles yet — ${errText(err)}. Run \`mossbear sync\`.`);
|
|
732
|
+
}
|
|
733
|
+
}
|
|
734
|
+
else {
|
|
735
|
+
// An account with no bundles is a state, not a blank: the adjacent
|
|
736
|
+
// "you picked none" case already speaks, and staying silent here left
|
|
737
|
+
// the step invisible to anyone wondering whether it ran.
|
|
738
|
+
console.log(' No bundles in your dashboard yet — create one there, then run `mossbear pull <bundle>` here.');
|
|
678
739
|
}
|
|
679
740
|
}
|
|
680
741
|
catch (err) {
|
|
@@ -769,14 +830,14 @@ export const initCommand = defineCommand({
|
|
|
769
830
|
const alreadyEnabled = await readConfigDiscoverGlobal().catch(() => false);
|
|
770
831
|
if (alreadyEnabled) {
|
|
771
832
|
console.log(' ~/.mossbear/config.json: discoverGlobal already enabled — skipping prompt');
|
|
772
|
-
console.log(
|
|
833
|
+
console.log(` (pass \`${ADOPT_VERB} --no-global\` to skip globals for one run)`);
|
|
773
834
|
}
|
|
774
835
|
else if (globalGuideFiles.length > 0) {
|
|
775
836
|
const summary = globalGuideFiles.map((f) => f.displayPath).join(', ');
|
|
776
837
|
const rl = createInterface({ input: process.stdin, output: process.stdout });
|
|
777
838
|
try {
|
|
778
839
|
const answer = (await rl.question(`\nFound global rule file(s): ${summary}\n` +
|
|
779
|
-
|
|
840
|
+
`Scan global config by default during "${ADOPT_VERB}"? [y/N] `))
|
|
780
841
|
.trim()
|
|
781
842
|
.toLowerCase();
|
|
782
843
|
if (answer === 'y' || answer === 'yes') {
|
|
@@ -855,14 +916,14 @@ export const initCommand = defineCommand({
|
|
|
855
916
|
}
|
|
856
917
|
catch (err) {
|
|
857
918
|
console.warn(` warning: could not import guide files — ${errText(err)}`);
|
|
858
|
-
console.warn(
|
|
919
|
+
console.warn(` Retry any time with \`${ADOPT_VERB}\`.`);
|
|
859
920
|
}
|
|
860
921
|
}
|
|
861
922
|
}
|
|
862
923
|
console.log('\nDone. Next steps:');
|
|
863
924
|
console.log(' Edit AGENTS.md to add your rules');
|
|
864
925
|
if (hasToken) {
|
|
865
|
-
console.log(' mossbear sync — pull
|
|
926
|
+
console.log(' mossbear sync — pull your guides and upload this session for grading (the hooks run it for you)');
|
|
866
927
|
}
|
|
867
928
|
else {
|
|
868
929
|
console.log(' mossbear sync --token <token> — connect your dashboard (Settings → Developer → CLI Token); remembered after the first run');
|
|
@@ -870,11 +931,10 @@ export const initCommand = defineCommand({
|
|
|
870
931
|
// Always listed, not just when this run found files: someone who adds an
|
|
871
932
|
// AGENTS.md tomorrow needs to know the command exists today.
|
|
872
933
|
console.log(importableGuideFiles.length > 0
|
|
873
|
-
? `
|
|
874
|
-
:
|
|
934
|
+
? ` ${ADOPT_VERB} — adopt this repo's existing guide files (${importableGuideFiles.length} found) into your dashboard`
|
|
935
|
+
: ` ${ADOPT_VERB} — adopt this repo's existing guide files into your dashboard`);
|
|
875
936
|
console.log(' mossbear guides active — list cached guides');
|
|
876
937
|
console.log(' mossbear doctor — verify your environment');
|
|
877
|
-
console.log(" mossbear sync — upload this session's actions for grading (the Stop and SessionEnd hooks run it; SessionStart runs it with --no-actions, to refresh subscribed bundles before your first turn)");
|
|
878
938
|
},
|
|
879
939
|
});
|
|
880
940
|
//# sourceMappingURL=init.js.map
|