openmerit 0.1.8 → 0.1.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +14 -0
- package/dist/core/src/index.d.ts +7 -7
- package/dist/pi/src/index.js +4 -4
- package/dist/protocol/src/index.d.ts +15 -15
- package/dist/terminal/scout-update.json +1 -0
- package/dist/terminal/src/cli.mjs +2 -1
- package/dist/terminal/src/install.mjs +200 -57
- package/dist/terminal/src/telemetry.mjs +82 -10
- package/dist/terminal/src/updates.d.ts +62 -0
- package/dist/terminal/src/updates.js +395 -0
- package/dist/terminal/src/updates.ts +312 -0
- package/docs/inference-terminal.md +4 -0
- package/docs/scout-data-policy.md +10 -6
- package/docs/scout.md +71 -10
- package/docs/security.md +7 -1
- package/docs/testing.md +1 -1
- package/package.json +12 -6
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,19 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.1.10 — 2026-10-26
|
|
4
|
+
|
|
5
|
+
- Add default-on Claude Code background checks for compatible Scout skill/startup-rule updates, with daily checks, 15-minute failure backoff, non-blocking failure notices with the “update openmerit” fallback, manual `openmerit update`, persistent opt-out and a natural-language update instruction.
|
|
6
|
+
- Verify npm package integrity and read a bounded instruction bundle without executing downloaded code. Preserve edited files, credentials, MCP configuration, privacy settings and project policy; serialize maintenance and recover interrupted instruction writes.
|
|
7
|
+
- Disclose setup behavior, retain other Claude hooks/settings and require a new session to reliably load updated instructions. Existing installations need a one-time installer rerun after publication; incompatible releases require a reviewed manual upgrade. Hosted Scout and npm remain separate releases.
|
|
8
|
+
- Enable Scout setup usage/installation diagnostics by default, honoring telemetry, DNT and account-unlink opt-outs. Terminal/evaluation analytics remain opt-in; MCP prompt-content capture remains off.
|
|
9
|
+
|
|
10
|
+
## 0.1.9 — 2026-10-24
|
|
11
|
+
|
|
12
|
+
- Add opt-in coding-agent installation milestones, component/connection diagnostics and consent-gated setup/installation correlation retained across resumed approval and upgrades. Carry browser usage and unlink choices into setup; keep standalone CLI analytics default-off and MCP prompt-content capture off.
|
|
13
|
+
- Add bounded installation-event retries with stable delivery IDs. Report verification and remote revocation failures even when existing local command exit semantics remain successful.
|
|
14
|
+
- Coordinate the independently released Scout browser/device/MCP lifecycle telemetry, correct HTTP-200 logical-error accounting, and distinguish key authorization from verified installation. These are observed events, not skipped-call detection, guaranteed delivery or downstream model-execution tracking.
|
|
15
|
+
- Preserve existing package exports, model-decision guidance and legal metadata. Existing installations need an installer rerun; npm publication does not deploy Scout or the main website.
|
|
16
|
+
|
|
3
17
|
## 0.1.8 — 2026-10-24
|
|
4
18
|
|
|
5
19
|
- Install an owned startup rule requiring Scout before explicit or implicit application-model choices, including pretrained/local/browser models, weight downloads and SDK defaults. Keep detailed access-policy and search instructions in the skill. These instructions are guidance, not hard enforcement.
|
package/dist/core/src/index.d.ts
CHANGED
|
@@ -7,13 +7,13 @@ export interface HarnessAdapter {
|
|
|
7
7
|
scheduleWakeup?(request: HarnessWakeupRequest): Promise<HarnessDispatchReceipt>;
|
|
8
8
|
}
|
|
9
9
|
export interface IntentFactoryOptions {
|
|
10
|
-
readonly taskProfileId?: string;
|
|
10
|
+
readonly taskProfileId?: string | undefined;
|
|
11
11
|
readonly authorizationPolicyId?: string;
|
|
12
|
-
readonly policy?: SupervisedGraduationPolicy;
|
|
12
|
+
readonly policy?: SupervisedGraduationPolicy | undefined;
|
|
13
13
|
readonly id?: string;
|
|
14
14
|
readonly requestedAt?: string;
|
|
15
|
-
readonly evaluationSpend?: number;
|
|
16
|
-
readonly targetId?: string;
|
|
15
|
+
readonly evaluationSpend?: number | undefined;
|
|
16
|
+
readonly targetId?: string | undefined;
|
|
17
17
|
readonly additionalConstraints?: Readonly<Record<string, JsonValue>>;
|
|
18
18
|
}
|
|
19
19
|
export declare function createOpenMeritIntent(kind: IntentKind, options?: IntentFactoryOptions): OpenMeritIntent;
|
|
@@ -28,8 +28,8 @@ export interface VerificationResult {
|
|
|
28
28
|
}
|
|
29
29
|
export interface ResultInterpretation extends VerificationResult {
|
|
30
30
|
readonly nextStage?: ImprovementCycleState["stage"];
|
|
31
|
-
readonly config?: OpenMeritProjectConfig;
|
|
32
|
-
readonly cyclePatch?: Partial<ImprovementCycleState
|
|
31
|
+
readonly config?: OpenMeritProjectConfig | undefined;
|
|
32
|
+
readonly cyclePatch?: Partial<ImprovementCycleState> | undefined;
|
|
33
33
|
}
|
|
34
34
|
export declare function validateObservabilityCoverage(profile: TaskProfile, coverage: ObservabilityCoverage, requireReady: boolean): readonly string[];
|
|
35
35
|
export declare function interpretIntentResult(intent: OpenMeritIntent, result: AnyIntentResult, cycle: ImprovementCycleState, config: OpenMeritProjectConfig): ResultInterpretation;
|
|
@@ -52,7 +52,7 @@ export interface IssuedIntent {
|
|
|
52
52
|
readonly receipt: HarnessDispatchReceipt;
|
|
53
53
|
}
|
|
54
54
|
export interface CoordinatorIssueOptions {
|
|
55
|
-
readonly additionalConstraints?: Readonly<Record<string, JsonValue
|
|
55
|
+
readonly additionalConstraints?: Readonly<Record<string, JsonValue>> | undefined;
|
|
56
56
|
}
|
|
57
57
|
export interface AcceptedIntentResult {
|
|
58
58
|
readonly intentKind: IntentKind;
|
package/dist/pi/src/index.js
CHANGED
|
@@ -536,7 +536,7 @@ export default function openMeritExtension(pi) {
|
|
|
536
536
|
await dispatchIntent(pi, ctx, state, store, "establish_evals", registerCompletionTool, {
|
|
537
537
|
applicationTargetRequired: true,
|
|
538
538
|
detectedApplicationTargets: detectedTargetsConstraint(detectedApplicationTargets),
|
|
539
|
-
...(detectedApplicationTargets.length === 1 && detectedApplicationTargets[0]
|
|
539
|
+
...(detectedApplicationTargets.length === 1 && detectedApplicationTargets[0]?.configuredModelId ? { expectedIncumbentModelId: detectedApplicationTargets[0]?.configuredModelId } : {}),
|
|
540
540
|
});
|
|
541
541
|
});
|
|
542
542
|
pi.on("session_start", async (_event, ctx) => {
|
|
@@ -573,7 +573,7 @@ export default function openMeritExtension(pi) {
|
|
|
573
573
|
await dispatchIntent(pi, ctx, state, store, "establish_evals", registerCompletionTool, {
|
|
574
574
|
applicationTargetRequired: true,
|
|
575
575
|
detectedApplicationTargets: detectedTargetsConstraint(detectedApplicationTargets),
|
|
576
|
-
...(detectedApplicationTargets.length === 1 && detectedApplicationTargets[0]
|
|
576
|
+
...(detectedApplicationTargets.length === 1 && detectedApplicationTargets[0]?.configuredModelId ? { expectedIncumbentModelId: detectedApplicationTargets[0]?.configuredModelId } : {}),
|
|
577
577
|
});
|
|
578
578
|
}
|
|
579
579
|
}
|
|
@@ -626,7 +626,7 @@ export default function openMeritExtension(pi) {
|
|
|
626
626
|
await dispatchIntent(pi, ctx, state, store, "establish_evals", registerCompletionTool, {
|
|
627
627
|
applicationTargetRequired: true,
|
|
628
628
|
detectedApplicationTargets: detectedTargetsConstraint(detectedApplicationTargets),
|
|
629
|
-
...(detectedApplicationTargets.length === 1 && detectedApplicationTargets[0]
|
|
629
|
+
...(detectedApplicationTargets.length === 1 && detectedApplicationTargets[0]?.configuredModelId ? { expectedIncumbentModelId: detectedApplicationTargets[0]?.configuredModelId } : {}),
|
|
630
630
|
});
|
|
631
631
|
}
|
|
632
632
|
else {
|
|
@@ -652,7 +652,7 @@ export default function openMeritExtension(pi) {
|
|
|
652
652
|
await dispatchIntent(pi, ctx, state, store, "establish_evals", registerCompletionTool, {
|
|
653
653
|
applicationTargetRequired: true,
|
|
654
654
|
detectedApplicationTargets: detectedTargetsConstraint(detectedApplicationTargets),
|
|
655
|
-
...(detectedApplicationTargets.length === 1 && detectedApplicationTargets[0]
|
|
655
|
+
...(detectedApplicationTargets.length === 1 && detectedApplicationTargets[0]?.configuredModelId ? { expectedIncumbentModelId: detectedApplicationTargets[0]?.configuredModelId } : {}),
|
|
656
656
|
});
|
|
657
657
|
}
|
|
658
658
|
return;
|
|
@@ -361,16 +361,16 @@ export declare const REQUIRED_CAPABILITIES: Readonly<Record<IntentKind, readonly
|
|
|
361
361
|
export type ImprovementStage = "unconfigured" | "establishing_evidence" | "collecting_baseline" | "baseline_ready" | "discovering_candidates" | "candidates_ready" | "running_challenger_trials" | "challengers_ready" | "calculating_frontier" | "frontier_ready" | "awaiting_swap_approval" | "swap_approved" | "applying_swap" | "swap_applied" | "verifying_swap" | "swap_verified" | "verification_failed" | "rolling_back" | "monitoring";
|
|
362
362
|
export interface ImprovementCycleState {
|
|
363
363
|
readonly id: string;
|
|
364
|
-
readonly targetId?: string;
|
|
365
|
-
readonly taskProfileId?: string;
|
|
364
|
+
readonly targetId?: string | undefined;
|
|
365
|
+
readonly taskProfileId?: string | undefined;
|
|
366
366
|
readonly stage: ImprovementStage;
|
|
367
|
-
readonly activeCandidateId?: string;
|
|
368
|
-
readonly previousCandidateId?: string;
|
|
369
|
-
readonly proposedCandidateId?: string;
|
|
367
|
+
readonly activeCandidateId?: string | undefined;
|
|
368
|
+
readonly previousCandidateId?: string | undefined;
|
|
369
|
+
readonly proposedCandidateId?: string | undefined;
|
|
370
370
|
readonly verifiedSwapCount: number;
|
|
371
371
|
readonly baselineEvidenceSufficient: boolean;
|
|
372
372
|
readonly observabilityReady?: boolean;
|
|
373
|
-
readonly policy?: SupervisedGraduationPolicy;
|
|
373
|
+
readonly policy?: SupervisedGraduationPolicy | undefined;
|
|
374
374
|
}
|
|
375
375
|
export interface OpenMeritProjectConfig {
|
|
376
376
|
readonly schemaVersion: 1;
|
|
@@ -382,13 +382,13 @@ export interface OpenMeritProjectConfig {
|
|
|
382
382
|
export interface OpenMeritProjectState {
|
|
383
383
|
readonly schemaVersion: 1;
|
|
384
384
|
readonly cycle: ImprovementCycleState;
|
|
385
|
-
readonly activeIntent?: OpenMeritIntent;
|
|
386
|
-
readonly lastResult?: IntentResult;
|
|
385
|
+
readonly activeIntent?: OpenMeritIntent | undefined;
|
|
386
|
+
readonly lastResult?: IntentResult | undefined;
|
|
387
387
|
/** Durable handoffs between discovery, trials, and frontier calculation. */
|
|
388
|
-
readonly candidates?: readonly CandidateDescriptor[];
|
|
389
|
-
readonly assessments?: readonly CandidateAssessment[];
|
|
390
|
-
readonly experimentManifest?: EvidenceReference;
|
|
391
|
-
readonly observability?: ObservabilityCoverage;
|
|
388
|
+
readonly candidates?: readonly CandidateDescriptor[] | undefined;
|
|
389
|
+
readonly assessments?: readonly CandidateAssessment[] | undefined;
|
|
390
|
+
readonly experimentManifest?: EvidenceReference | undefined;
|
|
391
|
+
readonly observability?: ObservabilityCoverage | undefined;
|
|
392
392
|
readonly automation: {
|
|
393
393
|
readonly paused?: boolean;
|
|
394
394
|
readonly setupNudgeShown: boolean;
|
|
@@ -397,9 +397,9 @@ export interface OpenMeritProjectState {
|
|
|
397
397
|
readonly modelCatalogFingerprint?: string;
|
|
398
398
|
readonly modelCatalogChangedAt?: string;
|
|
399
399
|
readonly processedSignalIds?: readonly string[];
|
|
400
|
-
readonly pendingIntentKind?: IntentKind;
|
|
401
|
-
readonly pendingIntentReason?: string;
|
|
402
|
-
readonly lastAssessmentAt?: string;
|
|
400
|
+
readonly pendingIntentKind?: IntentKind | undefined;
|
|
401
|
+
readonly pendingIntentReason?: string | undefined;
|
|
402
|
+
readonly lastAssessmentAt?: string | undefined;
|
|
403
403
|
readonly baselineStartedAt?: string;
|
|
404
404
|
readonly lastReassessmentTaskCount?: number;
|
|
405
405
|
readonly lastReassessmentAt?: string;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"format":1,"contract":"scout-recommend-v1","version":"0.1.10","skill":"---\nname: openmerit-scout\ndescription: Consults OpenMerit Scout before choosing, adding, downloading, replacing or configuring any application inference model, including implicit choices while building features, pretrained browser/local models, SDK defaults, embeddings, OCR, speech, classification, detection, segmentation, LLMs and agents. Not for unrelated edits, ordinary inference calls or this coding agent's own model.\n---\n\n# OpenMerit · Scout\n\nBefore introducing, recommending, replacing or configuring an application\ninference model, call the `scout_models` tool on the `openmerit` MCP server.\nThis applies even when the user never mentions models or Scout. Downloading local\nweights, using a pretrained browser model or accepting an SDK default is a model\ndecision: consult Scout before model-specific code, installs or downloads.\nPreserve the user's explicit model choice; assess it rather than silently replacing\nit. Leave unchanged, approved application selections in place.\n\n## Project policy\n\nRead `.openmerit/scout.json` before searching. If it is absent, ask once whether this\nproject uses **existing-only** (only endpoints it can already reach) or\n**existing-first** (prefer them, ask before searching the whole catalogue), and\nwhich public catalogue endpoint IDs it can access. Save the answer:\n\n```sh\nnpx -y openmerit@latest project --policy existing-only --endpoint-id <id> ...\n```\n\nNever infer access from a model name, SDK or environment-variable name. Never\nrecord credentials, private URLs, prompts or customer data. An empty inventory\nis not permission to search all models.\n\n## Searching\n\nCall `scout_models` with a non-confidential task description and\n`endpointIds` set to the saved inventory, including `[]` when empty.\nExisting-only never broadens. For existing-first, if no existing candidate fits,\nexplain the gap and ask before a separate search without `endpointIds`. Send\nonly task requirements, never source files, secrets or real customer records.\n\nCompare model AND endpoint, evidence, reference cost/time, unknowns and\nwarnings. For multiple tasks read `tasks[].slots[0].recommendations`; the\ntop-level list is empty. Prefer the cheapest usable option the quality evidence\nsupports, without claiming benchmarks prove application accuracy. Use the\nreturned provider model ID and the project's actual SDK and protocol.\n\n## Boundaries\n\nAsk before adding providers or credentials, spending, deploying or external\nwrites. Report recommendation, endpoint connectivity and application checks as\nseparate results, each only after it succeeds. Do not switch this coding agent's\nown model.\n\nIf Scout fails or has no suitable candidate/evidence for the required deployment,\nsay so and pause the model decision; do not substitute a remembered recommendation\nor SDK default. Continue only model-independent work. Local/browser models are not\nexempt when the catalogue lacks coverage. If it reports that the device key is missing,\nexpired or revoked, run `npx -y openmerit@latest login` and then\n`npx -y openmerit@latest install` again. Never ask the user to paste a key.\n","rule":"# Application model decisions · OpenMerit Scout\n\nBefore choosing, recommending, adding, downloading, replacing or configuring\nANY application inference model, load the `openmerit-scout` skill and consult\n`scout_models` on the `openmerit` MCP server before committing to a model.\nThis applies even when the user only asks you to build a feature, never mentions\nmodels or Scout, or names a model themselves (assess it; do not silently replace it).\n\nA pretrained model, local weights, browser inference, an SDK's default model,\nembeddings, OCR, speech, image classification, detection and segmentation all\ncount as model choices, not implementation details. Identify this decision before\nwriting model-specific code, installing a model package or downloading weights.\n\nFollow the skill's project access policy. If it is missing, ask and save it first.\nIf Scout is unavailable, fails or has no suitable evidence/candidate, disclose the\ngap and pause the model decision; do not fall back to a remembered or SDK-default\nmodel. You may continue work that does not commit to a model.\n\nDo not consult Scout for unrelated edits, normal inference calls using an unchanged\napproved model, or this coding agent's own model. Do not reselect approved models\nunless the task introduces or changes a model decision.\n\nWhen the user says \"update openmerit\", run\n`npx -y openmerit@latest update --scope user` (use `--scope project` if this\nrule is in the project's .claude/rules directory). Report the result, including\nany conflict or manual-upgrade requirement. Do not delete edited files, bypass\npermissions or rerun login automatically. A new session loads updated instructions.\n"}
|
|
@@ -11,6 +11,7 @@ const help = `OpenMerit · Inference Terminal
|
|
|
11
11
|
|
|
12
12
|
openmerit dash [path] [options]
|
|
13
13
|
openmerit install --help Connect OpenMerit to your coding agent
|
|
14
|
+
openmerit update --help Update installed Scout instructions
|
|
14
15
|
openmerit eval --help Evaluate CLI changes across coding agents
|
|
15
16
|
|
|
16
17
|
--port <number> Require a specific local port (default: 4310 or a free port)
|
|
@@ -29,7 +30,7 @@ Coding-harness usage is outside this terminal's scope.
|
|
|
29
30
|
|
|
30
31
|
async function main() {
|
|
31
32
|
const args = process.argv.slice(2);
|
|
32
|
-
if (['install', 'status', 'remove', 'login', 'logout', 'project', 'doctor'].includes(args[0])) { const { main } = await import('./install.mjs'); process.exitCode = await main(args); return; }
|
|
33
|
+
if (['install', 'status', 'remove', 'login', 'logout', 'project', 'doctor', 'update'].includes(args[0])) { const { main } = await import('./install.mjs'); process.exitCode = await main(args); return; }
|
|
33
34
|
if (args[0] === 'eval') { const { main } = await import('../../eval/src/cli.mjs'); await main(args.slice(1)); return; }
|
|
34
35
|
if (!args.length || args.includes('--help') || args.includes('-h')) { console.log(help); return; }
|
|
35
36
|
if (args.shift() !== 'dash') throw new Error('Unknown command. Run openmerit --help.');
|