@agentmonitors/cli 0.5.0 → 0.6.1
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/dist/index.cjs +135 -20
- package/dist/index.cjs.map +1 -1
- package/package.json +7 -7
package/dist/index.cjs
CHANGED
|
@@ -33,10 +33,10 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
33
33
|
mod
|
|
34
34
|
));
|
|
35
35
|
|
|
36
|
-
// ../../node_modules/.pnpm/tsup@8.5.1_@microsoft+api-extractor@7.57.7_@types+node@22.19.15__jiti@2.7.0_postcss@8.5.8_typescript@5.9.3_yaml@2.
|
|
36
|
+
// ../../node_modules/.pnpm/tsup@8.5.1_@microsoft+api-extractor@7.57.7_@types+node@22.19.15__jiti@2.7.0_postcss@8.5.8_typescript@5.9.3_yaml@2.9.0/node_modules/tsup/assets/cjs_shims.js
|
|
37
37
|
var getImportMetaUrl, importMetaUrl;
|
|
38
38
|
var init_cjs_shims = __esm({
|
|
39
|
-
"../../node_modules/.pnpm/tsup@8.5.1_@microsoft+api-extractor@7.57.7_@types+node@22.19.15__jiti@2.7.0_postcss@8.5.8_typescript@5.9.3_yaml@2.
|
|
39
|
+
"../../node_modules/.pnpm/tsup@8.5.1_@microsoft+api-extractor@7.57.7_@types+node@22.19.15__jiti@2.7.0_postcss@8.5.8_typescript@5.9.3_yaml@2.9.0/node_modules/tsup/assets/cjs_shims.js"() {
|
|
40
40
|
"use strict";
|
|
41
41
|
getImportMetaUrl = () => typeof document === "undefined" ? new URL(`file:${__filename}`).href : document.currentScript && document.currentScript.tagName.toUpperCase() === "SCRIPT" ? document.currentScript.src : new URL("main.js", document.baseURI).href;
|
|
42
42
|
importMetaUrl = /* @__PURE__ */ getImportMetaUrl();
|
|
@@ -30757,16 +30757,60 @@ var notifySchema = external_exports.discriminatedUnion("strategy", [
|
|
|
30757
30757
|
debounceNotifySchema,
|
|
30758
30758
|
throttleNotifySchema
|
|
30759
30759
|
]);
|
|
30760
|
+
var urgencyLevels = ["low", "normal", "high"];
|
|
30761
|
+
var urgencyRank = {
|
|
30762
|
+
low: 0,
|
|
30763
|
+
normal: 1,
|
|
30764
|
+
high: 2
|
|
30765
|
+
};
|
|
30766
|
+
var urgencyBandSchema = external_exports.string().transform((raw, ctx) => {
|
|
30767
|
+
const text2 = raw.trim();
|
|
30768
|
+
const parts = text2.includes("..") ? text2.split("..").map((part) => part.trim()) : [text2, text2];
|
|
30769
|
+
if (parts.length !== 2) {
|
|
30770
|
+
ctx.addIssue({
|
|
30771
|
+
code: external_exports.ZodIssueCode.custom,
|
|
30772
|
+
message: 'urgency must be a single level (e.g. "normal") or a range "lo..hi" (e.g. "normal..high")'
|
|
30773
|
+
});
|
|
30774
|
+
return external_exports.NEVER;
|
|
30775
|
+
}
|
|
30776
|
+
const [loRaw, hiRaw] = parts;
|
|
30777
|
+
const isLevel = (value) => value !== void 0 && urgencyLevels.includes(value);
|
|
30778
|
+
if (!isLevel(loRaw) || !isLevel(hiRaw)) {
|
|
30779
|
+
ctx.addIssue({
|
|
30780
|
+
code: external_exports.ZodIssueCode.custom,
|
|
30781
|
+
message: `urgency bounds must each be one of ${urgencyLevels.map((level) => `"${level}"`).join(", ")}`
|
|
30782
|
+
});
|
|
30783
|
+
return external_exports.NEVER;
|
|
30784
|
+
}
|
|
30785
|
+
if (urgencyRank[loRaw] > urgencyRank[hiRaw]) {
|
|
30786
|
+
ctx.addIssue({
|
|
30787
|
+
code: external_exports.ZodIssueCode.custom,
|
|
30788
|
+
message: `urgency range "${loRaw}..${hiRaw}" is inverted \u2014 the low bound must not exceed the high bound`
|
|
30789
|
+
});
|
|
30790
|
+
return external_exports.NEVER;
|
|
30791
|
+
}
|
|
30792
|
+
return { lo: loRaw, hi: hiRaw };
|
|
30793
|
+
});
|
|
30760
30794
|
var watchSchema = external_exports.object({
|
|
30761
30795
|
type: external_exports.string().min(1).regex(/^[a-z][a-z0-9-]*$/, "watch.type must be kebab-case")
|
|
30762
30796
|
}).catchall(external_exports.unknown());
|
|
30763
30797
|
var monitorFrontmatterSchema = external_exports.object({
|
|
30764
30798
|
name: external_exports.string().min(1, "Monitor name must be non-empty when present").optional(),
|
|
30765
30799
|
watch: watchSchema,
|
|
30766
|
-
urgency:
|
|
30800
|
+
urgency: urgencyBandSchema,
|
|
30767
30801
|
notify: notifySchema.optional(),
|
|
30768
30802
|
tags: external_exports.array(external_exports.string()).optional()
|
|
30769
|
-
})
|
|
30803
|
+
}).transform(({ urgency, ...rest }) => ({
|
|
30804
|
+
...rest,
|
|
30805
|
+
// Flatten the parsed band: `urgency` is the band's low bound — the base /
|
|
30806
|
+
// default effective urgency used when no source `salience` is present (kept
|
|
30807
|
+
// under this key for backward compatibility with every existing consumer) —
|
|
30808
|
+
// and `urgencyMax` is the band's high bound (equal to `urgency` for a
|
|
30809
|
+
// scalar). Source salience may escalate the effective urgency between these
|
|
30810
|
+
// two, clamping outside the band. See 002 §4.1 / 003 §2.3.
|
|
30811
|
+
urgency: urgency.lo,
|
|
30812
|
+
urgencyMax: urgency.hi
|
|
30813
|
+
}));
|
|
30770
30814
|
function validateScope(scope, scopeSchema6) {
|
|
30771
30815
|
const validator = new Validator(scopeSchema6, "7", false);
|
|
30772
30816
|
const result = validator.validate(scope);
|
|
@@ -31298,7 +31342,18 @@ function generateMonitorSchema(sources) {
|
|
|
31298
31342
|
type: { type: "string", enum: sourceNames }
|
|
31299
31343
|
}
|
|
31300
31344
|
},
|
|
31301
|
-
|
|
31345
|
+
// A bare level (`normal`) or an authored band `lo..hi` (`normal..high`).
|
|
31346
|
+
// This editor-hint schema enforces only the *shape* of each bound; the
|
|
31347
|
+
// authoritative parser (`monitorFrontmatterSchema`) additionally rejects
|
|
31348
|
+
// an inverted range (`lo > hi`). See 001 §3.2.
|
|
31349
|
+
//
|
|
31350
|
+
// Leading/trailing whitespace is allowed (`\s*` anchors at both ends)
|
|
31351
|
+
// to mirror the Zod parser, which calls `.trim()` on the raw value
|
|
31352
|
+
// before validating bounds. Whitespace around `..` was already allowed.
|
|
31353
|
+
urgency: {
|
|
31354
|
+
type: "string",
|
|
31355
|
+
pattern: "^\\s*(low|normal|high)(\\s*\\.\\.\\s*(low|normal|high))?\\s*$"
|
|
31356
|
+
},
|
|
31302
31357
|
notify: {
|
|
31303
31358
|
type: "object",
|
|
31304
31359
|
required: ["strategy"],
|
|
@@ -32118,14 +32173,46 @@ function explainVerdict(stages) {
|
|
|
32118
32173
|
reason: stage?.reason ?? "Monitor delivered successfully."
|
|
32119
32174
|
};
|
|
32120
32175
|
}
|
|
32176
|
+
var URGENCY_BY_RANK = ["low", "normal", "high"];
|
|
32177
|
+
var URGENCY_RANK = {
|
|
32178
|
+
low: 0,
|
|
32179
|
+
normal: 1,
|
|
32180
|
+
high: 2
|
|
32181
|
+
};
|
|
32182
|
+
function effectiveObservationUrgency(monitor, observation) {
|
|
32183
|
+
const lo = monitor.frontmatter.urgency;
|
|
32184
|
+
const hi = monitor.frontmatter.urgencyMax ?? lo;
|
|
32185
|
+
const desired = observation.salience ?? lo;
|
|
32186
|
+
const rank = Math.min(
|
|
32187
|
+
Math.max(URGENCY_RANK[desired], URGENCY_RANK[lo]),
|
|
32188
|
+
URGENCY_RANK[hi]
|
|
32189
|
+
);
|
|
32190
|
+
return URGENCY_BY_RANK[rank] ?? lo;
|
|
32191
|
+
}
|
|
32121
32192
|
function serializeObservation(monitor, observation, observedAt) {
|
|
32122
|
-
return {
|
|
32193
|
+
return {
|
|
32194
|
+
monitor,
|
|
32195
|
+
observation,
|
|
32196
|
+
observedAt,
|
|
32197
|
+
effectiveUrgency: effectiveObservationUrgency(monitor, observation)
|
|
32198
|
+
};
|
|
32123
32199
|
}
|
|
32124
32200
|
function hydrateStoredObservationEnvelope(envelope) {
|
|
32125
32201
|
return {
|
|
32126
32202
|
monitor: envelope.monitor,
|
|
32127
32203
|
observation: envelope.observation,
|
|
32128
|
-
observedAt: envelope.observedAt instanceof Date ? envelope.observedAt : new Date(envelope.observedAt)
|
|
32204
|
+
observedAt: envelope.observedAt instanceof Date ? envelope.observedAt : new Date(envelope.observedAt),
|
|
32205
|
+
// Restart-safety / upgrade backfill (002 §3, issue #109): a debounce batch
|
|
32206
|
+
// persisted BEFORE the range-urgency upgrade will have no `effectiveUrgency`
|
|
32207
|
+
// field on its envelopes. Recompute it from the envelope's `monitor` +
|
|
32208
|
+
// `observation` so the materialized event row is never written with
|
|
32209
|
+
// `undefined` urgency. `effectiveObservationUrgency` degrades cleanly when
|
|
32210
|
+
// the hydrated monitor snapshot itself lacks `urgencyMax` (old monitor).
|
|
32211
|
+
// The cast to `Urgency | undefined` is intentional: at compile time
|
|
32212
|
+
// `StoredObservationEnvelope.effectiveUrgency` is always `Urgency`, but
|
|
32213
|
+
// pre-upgrade deserialized JSON may lack the field entirely.
|
|
32214
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
32215
|
+
effectiveUrgency: envelope.effectiveUrgency ?? effectiveObservationUrgency(envelope.monitor, envelope.observation)
|
|
32129
32216
|
};
|
|
32130
32217
|
}
|
|
32131
32218
|
var WEEKDAY_INDEX = {
|
|
@@ -32690,6 +32777,7 @@ var AgentMonitorRuntime = class {
|
|
|
32690
32777
|
const now = /* @__PURE__ */ new Date();
|
|
32691
32778
|
const emittedEventIds = [];
|
|
32692
32779
|
const evaluated = [];
|
|
32780
|
+
const erroredObservations = [];
|
|
32693
32781
|
for (const parsed of result.monitors) {
|
|
32694
32782
|
const monitor = parsed.monitor;
|
|
32695
32783
|
const sourceName = monitor.frontmatter.watch.type;
|
|
@@ -32714,13 +32802,15 @@ var AgentMonitorRuntime = class {
|
|
|
32714
32802
|
}
|
|
32715
32803
|
);
|
|
32716
32804
|
} catch (observeError) {
|
|
32805
|
+
const message = observeError instanceof Error ? observeError.message : String(observeError);
|
|
32806
|
+
erroredObservations.push({ monitorId: monitor.id, message });
|
|
32717
32807
|
try {
|
|
32718
32808
|
this.store.recordObservationHistory({
|
|
32719
32809
|
monitorId: monitor.id,
|
|
32720
32810
|
sourceName,
|
|
32721
32811
|
result: "errored",
|
|
32722
32812
|
observationData: {
|
|
32723
|
-
error:
|
|
32813
|
+
error: message
|
|
32724
32814
|
}
|
|
32725
32815
|
});
|
|
32726
32816
|
} catch {
|
|
@@ -32736,13 +32826,15 @@ var AgentMonitorRuntime = class {
|
|
|
32736
32826
|
})
|
|
32737
32827
|
);
|
|
32738
32828
|
} catch (ingestError) {
|
|
32829
|
+
const message = ingestError instanceof Error ? ingestError.message : String(ingestError);
|
|
32830
|
+
erroredObservations.push({ monitorId: monitor.id, message });
|
|
32739
32831
|
try {
|
|
32740
32832
|
this.store.recordObservationHistory({
|
|
32741
32833
|
monitorId: monitor.id,
|
|
32742
32834
|
sourceName,
|
|
32743
32835
|
result: "errored",
|
|
32744
32836
|
observationData: {
|
|
32745
|
-
error:
|
|
32837
|
+
error: message
|
|
32746
32838
|
}
|
|
32747
32839
|
});
|
|
32748
32840
|
} catch {
|
|
@@ -32750,7 +32842,11 @@ var AgentMonitorRuntime = class {
|
|
|
32750
32842
|
}
|
|
32751
32843
|
}
|
|
32752
32844
|
this.refreshWorkspaceSessions(workspacePath);
|
|
32753
|
-
return {
|
|
32845
|
+
return {
|
|
32846
|
+
evaluatedMonitors: evaluated,
|
|
32847
|
+
emittedEventIds,
|
|
32848
|
+
erroredObservations
|
|
32849
|
+
};
|
|
32754
32850
|
}
|
|
32755
32851
|
/**
|
|
32756
32852
|
* Funnel a batch of observations through notify dispatch, persist the updated
|
|
@@ -32802,7 +32898,8 @@ var AgentMonitorRuntime = class {
|
|
|
32802
32898
|
sourceName: emitted.monitor.frontmatter.watch.type,
|
|
32803
32899
|
observation: emitted.observation,
|
|
32804
32900
|
observedAt: emitted.observedAt,
|
|
32805
|
-
workspacePath: options2.workspacePath
|
|
32901
|
+
workspacePath: options2.workspacePath,
|
|
32902
|
+
effectiveUrgency: emitted.effectiveUrgency
|
|
32806
32903
|
});
|
|
32807
32904
|
emittedEventIds.push(event.id);
|
|
32808
32905
|
} catch (materializeError) {
|
|
@@ -33002,11 +33099,22 @@ var AgentMonitorRuntime = class {
|
|
|
33002
33099
|
}
|
|
33003
33100
|
}
|
|
33004
33101
|
for (const observation of observations) {
|
|
33102
|
+
const envelope = serializeObservation(monitor, observation, observedAt);
|
|
33005
33103
|
const notify = defaultNotifyConfigForUrgency(
|
|
33006
|
-
|
|
33104
|
+
envelope.effectiveUrgency,
|
|
33007
33105
|
monitor.frontmatter.notify
|
|
33008
33106
|
);
|
|
33009
|
-
const
|
|
33107
|
+
const isEscalated = URGENCY_RANK[envelope.effectiveUrgency] > URGENCY_RANK[monitor.frontmatter.urgency];
|
|
33108
|
+
if (isEscalated && nextState.pendingDebounce) {
|
|
33109
|
+
emitted.push(
|
|
33110
|
+
...nextState.pendingDebounce.observations.map(
|
|
33111
|
+
hydrateStoredObservationEnvelope
|
|
33112
|
+
),
|
|
33113
|
+
envelope
|
|
33114
|
+
);
|
|
33115
|
+
delete nextState.pendingDebounce;
|
|
33116
|
+
continue;
|
|
33117
|
+
}
|
|
33010
33118
|
if (!notify) {
|
|
33011
33119
|
emitted.push(envelope);
|
|
33012
33120
|
continue;
|
|
@@ -33060,7 +33168,7 @@ var AgentMonitorRuntime = class {
|
|
|
33060
33168
|
workspacePath: input.workspacePath ?? null,
|
|
33061
33169
|
monitorId: input.monitor.id,
|
|
33062
33170
|
sourceName: input.sourceName,
|
|
33063
|
-
urgency: input.
|
|
33171
|
+
urgency: input.effectiveUrgency,
|
|
33064
33172
|
title: input.observation.title,
|
|
33065
33173
|
body: input.observation.body ?? input.monitor.instructions,
|
|
33066
33174
|
summary: input.observation.summary ?? input.observation.body ?? input.observation.title,
|
|
@@ -35525,6 +35633,11 @@ function shouldReap(s) {
|
|
|
35525
35633
|
|
|
35526
35634
|
// src/commands/daemon.ts
|
|
35527
35635
|
var DEFAULT_REAP_AFTER_MS = 5 * 60 * 1e3;
|
|
35636
|
+
function appendErroredLines(summary, errored) {
|
|
35637
|
+
if (errored.length === 0) return summary;
|
|
35638
|
+
const lines = errored.map((e) => ` ${e.monitorId}: ${e.message}`);
|
|
35639
|
+
return [summary, ...lines].join("\n");
|
|
35640
|
+
}
|
|
35528
35641
|
async function runLoop(monitorsDir, workspacePath, pollMs, socketPath, reapAfterMs) {
|
|
35529
35642
|
const runtime = createRuntime();
|
|
35530
35643
|
let stopping = false;
|
|
@@ -35570,10 +35683,12 @@ async function runLoop(monitorsDir, workspacePath, pollMs, socketPath, reapAfter
|
|
|
35570
35683
|
while (!isStoppingRequested()) {
|
|
35571
35684
|
try {
|
|
35572
35685
|
const result = await runtime.tick(monitorsDir, workspacePath);
|
|
35573
|
-
if (result.emittedEventIds.length > 0) {
|
|
35574
|
-
|
|
35575
|
-
`Emitted ${String(result.emittedEventIds.length)} event(s) from ${String(result.evaluatedMonitors.length)} monitor(s)
|
|
35686
|
+
if (result.emittedEventIds.length > 0 || result.erroredObservations.length > 0) {
|
|
35687
|
+
const summary = appendErroredLines(
|
|
35688
|
+
`Emitted ${String(result.emittedEventIds.length)} event(s) from ${String(result.evaluatedMonitors.length)} monitor(s)${result.erroredObservations.length > 0 ? `, ${String(result.erroredObservations.length)} errored:` : "."}`,
|
|
35689
|
+
result.erroredObservations
|
|
35576
35690
|
);
|
|
35691
|
+
console.log(summary);
|
|
35577
35692
|
}
|
|
35578
35693
|
} catch (error2) {
|
|
35579
35694
|
const message = error2 instanceof Error ? error2.message : String(error2);
|
|
@@ -35639,9 +35754,9 @@ daemonCommand.command("once").description("Run one runtime observation cycle").a
|
|
|
35639
35754
|
console.log(JSON.stringify(result, null, 2));
|
|
35640
35755
|
return;
|
|
35641
35756
|
}
|
|
35642
|
-
|
|
35643
|
-
|
|
35644
|
-
);
|
|
35757
|
+
const erroredCount = result.erroredObservations.length;
|
|
35758
|
+
const base = `Evaluated ${String(result.evaluatedMonitors.length)} monitor(s), emitted ${String(result.emittedEventIds.length)} event(s)${erroredCount > 0 ? `, ${String(erroredCount)} errored:` : "."}`;
|
|
35759
|
+
console.log(appendErroredLines(base, result.erroredObservations));
|
|
35645
35760
|
} catch (error2) {
|
|
35646
35761
|
const message = error2 instanceof Error ? error2.message : String(error2);
|
|
35647
35762
|
reportError(message, options2.format === "json");
|