agentsmesh 0.40.0 → 0.41.0
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 +75 -0
- package/README.md +1 -1
- package/dist/canonical.js +299 -238
- package/dist/canonical.js.map +1 -1
- package/dist/cli.js +271 -332
- package/dist/engine.d.ts +7 -8
- package/dist/engine.js +771 -276
- package/dist/engine.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1733 -521
- package/dist/index.js.map +1 -1
- package/dist/{init-B1qdo3Dl.d.ts → init-DruMEhnc.d.ts} +97 -42
- package/dist/lessons.d.ts +7 -4
- package/dist/lessons.js +2091 -613
- package/dist/lessons.js.map +1 -1
- package/dist/{target-descriptor-CvTJyDxd.d.ts → target-descriptor-CMV6vxVE.d.ts} +7 -0
- package/dist/targets.d.ts +2 -2
- package/dist/targets.js +265 -219
- package/dist/targets.js.map +1 -1
- package/package.json +3 -2
|
@@ -150,6 +150,12 @@ declare const DEFAULT_RECALL_MAX_TOKENS = 1200;
|
|
|
150
150
|
*/
|
|
151
151
|
declare function rankLessons(graph: LessonsGraph, query: LessonsQuery, matches: readonly MatchedLesson[], options?: RankOptions): RankedLesson[];
|
|
152
152
|
|
|
153
|
+
/** Warning for a command trigger dropped at capture because it can never fire. */
|
|
154
|
+
interface DeadCommandWarning {
|
|
155
|
+
readonly code: 'DEAD_COMMAND_PATTERN';
|
|
156
|
+
readonly message: string;
|
|
157
|
+
}
|
|
158
|
+
|
|
153
159
|
interface AutoPruneSummary {
|
|
154
160
|
readonly removedTriggers: number;
|
|
155
161
|
readonly removedTopics: number;
|
|
@@ -170,7 +176,7 @@ interface AutoPruneSummary {
|
|
|
170
176
|
* because that lesson is captured then silently never recalled. These guardrails
|
|
171
177
|
* are the warn-only complement to that single hard block.
|
|
172
178
|
*/
|
|
173
|
-
type GuardrailCode = 'OVERSIZED_LESSON_TRIGGERS' | 'BROAD_GLOB_TRIGGER' | 'WIDE_GLOB_MATCH' | 'KEYWORD_ONLY_LESSON' | 'LOW_SIGNAL_KEYWORD' | 'STOPWORD_KEYWORD' | 'DEAD_GLOB' | 'NEAR_DUPLICATE_LESSON';
|
|
179
|
+
type GuardrailCode = 'OVERSIZED_LESSON_TRIGGERS' | 'BROAD_GLOB_TRIGGER' | 'WIDE_GLOB_MATCH' | 'KEYWORD_ONLY_LESSON' | 'LOW_SIGNAL_KEYWORD' | 'STOPWORD_KEYWORD' | 'DEAD_GLOB' | 'PENDING_GLOB' | 'NEAR_DUPLICATE_LESSON';
|
|
174
180
|
interface GuardrailWarning {
|
|
175
181
|
readonly code: GuardrailCode;
|
|
176
182
|
readonly message: string;
|
|
@@ -215,13 +221,17 @@ interface AddLessonOptions {
|
|
|
215
221
|
*/
|
|
216
222
|
readonly knownPaths?: ReadonlySet<string>;
|
|
217
223
|
}
|
|
224
|
+
/** A non-blocking capture warning: a guardrail nudge or a dropped dead command trigger. */
|
|
225
|
+
type AddLessonWarning = GuardrailWarning | DeadCommandWarning;
|
|
218
226
|
interface AddLessonResult {
|
|
219
227
|
readonly id: string;
|
|
220
228
|
readonly isNewLesson: boolean;
|
|
221
229
|
readonly isNewTopic: boolean;
|
|
222
230
|
readonly newTriggerIds: string[];
|
|
223
|
-
/**
|
|
224
|
-
readonly
|
|
231
|
+
/** What a re-add changed on the existing lesson; empty for a new lesson or a no-op. */
|
|
232
|
+
readonly changes: string[];
|
|
233
|
+
/** Non-blocking capture warnings for the resulting (merged) lesson. */
|
|
234
|
+
readonly warnings: AddLessonWarning[];
|
|
225
235
|
/**
|
|
226
236
|
* Counts of structural cruft the opt-in auto-prune cleaned up right after this
|
|
227
237
|
* capture (config `autoPrune: true`). Present only when something was pruned;
|
|
@@ -231,6 +241,33 @@ interface AddLessonResult {
|
|
|
231
241
|
}
|
|
232
242
|
declare function addLesson(projectRoot: string, input: AddLessonInput, options?: AddLessonOptions): Promise<AddLessonResult>;
|
|
233
243
|
|
|
244
|
+
type ValidationLevel = 'error' | 'warning';
|
|
245
|
+
interface ValidationFinding {
|
|
246
|
+
readonly level: ValidationLevel;
|
|
247
|
+
readonly code: string;
|
|
248
|
+
readonly message: string;
|
|
249
|
+
readonly lessonId?: string;
|
|
250
|
+
/** Every lesson one aggregate finding covers (machine-readable; the message names a few). */
|
|
251
|
+
readonly lessonIds?: readonly string[];
|
|
252
|
+
readonly topicId?: string;
|
|
253
|
+
readonly triggerId?: string;
|
|
254
|
+
}
|
|
255
|
+
interface ValidationReport {
|
|
256
|
+
/** True when no `error`-level findings exist (warnings do not affect `ok`). */
|
|
257
|
+
readonly ok: boolean;
|
|
258
|
+
readonly findings: ValidationFinding[];
|
|
259
|
+
}
|
|
260
|
+
interface ValidateOptions {
|
|
261
|
+
/**
|
|
262
|
+
* Working-tree file list (project-relative, forward-slash) for the dead-glob
|
|
263
|
+
* liveness check. When omitted the check is SKIPPED — the pure write-barrier
|
|
264
|
+
* call in `mutate.ts` passes nothing, so `add` never walks the tree and a
|
|
265
|
+
* liveness warning can never block a write. The CLI/lint callers supply it.
|
|
266
|
+
*/
|
|
267
|
+
readonly knownPaths?: ReadonlySet<string>;
|
|
268
|
+
}
|
|
269
|
+
declare function validateLessonsGraph(graph: LessonsGraph, options?: ValidateOptions): ValidationReport;
|
|
270
|
+
|
|
234
271
|
interface MutateOptions {
|
|
235
272
|
readonly retries?: number;
|
|
236
273
|
}
|
|
@@ -302,33 +339,6 @@ declare function stripLegacyMarkers(rule: string): string;
|
|
|
302
339
|
*/
|
|
303
340
|
declare function stripMarkersInGraph(projectRoot: string, options?: StripMarkersOptions): Promise<StripMarkersReport>;
|
|
304
341
|
|
|
305
|
-
type ValidationLevel = 'error' | 'warning';
|
|
306
|
-
interface ValidationFinding {
|
|
307
|
-
readonly level: ValidationLevel;
|
|
308
|
-
readonly code: string;
|
|
309
|
-
readonly message: string;
|
|
310
|
-
readonly lessonId?: string;
|
|
311
|
-
/** Every lesson one aggregate finding covers (machine-readable; the message names a few). */
|
|
312
|
-
readonly lessonIds?: readonly string[];
|
|
313
|
-
readonly topicId?: string;
|
|
314
|
-
readonly triggerId?: string;
|
|
315
|
-
}
|
|
316
|
-
interface ValidationReport {
|
|
317
|
-
/** True when no `error`-level findings exist (warnings do not affect `ok`). */
|
|
318
|
-
readonly ok: boolean;
|
|
319
|
-
readonly findings: ValidationFinding[];
|
|
320
|
-
}
|
|
321
|
-
interface ValidateOptions {
|
|
322
|
-
/**
|
|
323
|
-
* Working-tree file list (project-relative, forward-slash) for the dead-glob
|
|
324
|
-
* liveness check. When omitted the check is SKIPPED — the pure write-barrier
|
|
325
|
-
* call in `mutate.ts` passes nothing, so `add` never walks the tree and a
|
|
326
|
-
* liveness warning can never block a write. The CLI/lint callers supply it.
|
|
327
|
-
*/
|
|
328
|
-
readonly knownPaths?: ReadonlySet<string>;
|
|
329
|
-
}
|
|
330
|
-
declare function validateLessonsGraph(graph: LessonsGraph, options?: ValidateOptions): ValidationReport;
|
|
331
|
-
|
|
332
342
|
interface ImportLegacyOptions {
|
|
333
343
|
/** ISO date stamped onto every imported lesson's `createdAt`. */
|
|
334
344
|
readonly migratedAt: string;
|
|
@@ -353,6 +363,12 @@ interface ImportLegacyOptions {
|
|
|
353
363
|
* data; `force` is irrelevant in this mode.
|
|
354
364
|
*/
|
|
355
365
|
readonly merge?: boolean;
|
|
366
|
+
/**
|
|
367
|
+
* Refuse ({@link LessonsGraphExistsError}) when `lessons.json` exists at write
|
|
368
|
+
* time under the lock, even if empty. Auto-migration sets this so two first
|
|
369
|
+
* writers cannot both migrate.
|
|
370
|
+
*/
|
|
371
|
+
readonly requireAbsentGraph?: boolean;
|
|
356
372
|
}
|
|
357
373
|
/** Thrown when migration would overwrite an already-populated graph without `force`. */
|
|
358
374
|
declare class LessonsGraphExistsError extends Error {
|
|
@@ -377,31 +393,54 @@ interface ImportLegacyReport {
|
|
|
377
393
|
* `existsSync(lessonsPaths(root).index)` before invoking (see
|
|
378
394
|
* `maybeAutoMigrateLessons` and the `import-md` handler); re-running on a
|
|
379
395
|
* post-migration tree, where the legacy files are already gone, throws.
|
|
396
|
+
* Topic files outside `.agentsmesh/lessons/` are refused (LegacyTopicPathError).
|
|
380
397
|
*/
|
|
381
398
|
declare function importLegacyLessons(projectRoot: string, options: ImportLegacyOptions): Promise<ImportLegacyReport>;
|
|
382
399
|
|
|
383
400
|
/**
|
|
384
401
|
* Cross-platform process lock backed by an atomic mkdir.
|
|
385
402
|
*
|
|
386
|
-
*
|
|
387
|
-
*
|
|
388
|
-
*
|
|
389
|
-
*
|
|
403
|
+
* Each acquisition gets a random owner token, kept as an `owner-<token>` marker
|
|
404
|
+
* in the lock dir next to `holder.json` (pid, host, start time). The lock
|
|
405
|
+
* changes hands only by removing that exact marker, so neither a release nor
|
|
406
|
+
* a stale eviction can delete a lock that already passed to another process.
|
|
407
|
+
*
|
|
408
|
+
* Stale recovery: a dead same-host holder, or a live pid that now belongs to
|
|
409
|
+
* another process, is evicted at once. Any holder older than `staleMs` (or
|
|
410
|
+
* dated in the future past clock skew) is evicted too — the bound for hung
|
|
411
|
+
* processes and holders on other hosts. A holder evicted this way sees
|
|
412
|
+
* `isHeld()` turn false, so it can refuse to write.
|
|
390
413
|
*/
|
|
391
414
|
interface LockOptions {
|
|
392
415
|
/** Maximum retry attempts before throwing LockAcquisitionError. */
|
|
393
416
|
retries?: number;
|
|
394
|
-
/** Delay
|
|
417
|
+
/** Delay before the first retry in ms (default 200). */
|
|
395
418
|
retryDelayMs?: number;
|
|
419
|
+
/** Cap for the doubling delay. Defaults to `retryDelayMs`, i.e. a fixed delay. */
|
|
420
|
+
maxRetryDelayMs?: number;
|
|
421
|
+
/** Spread each delay over the upper half of its window so waiters do not retry in step. */
|
|
422
|
+
jitter?: boolean;
|
|
396
423
|
/**
|
|
397
|
-
*
|
|
398
|
-
*
|
|
424
|
+
* Age bound (default 6h): a lock older than this is evicted even when its
|
|
425
|
+
* holder is still alive or cannot be probed (other host).
|
|
399
426
|
*/
|
|
400
427
|
staleMs?: number;
|
|
401
428
|
/** Human-readable lock name surfaced in LockAcquisitionError, e.g. "lessons lock". */
|
|
402
429
|
label?: string;
|
|
430
|
+
/** Called once, with the holder, when a wait lasts `waitNoticeMs` (default 2000). */
|
|
431
|
+
onWait?: (holder: string) => void;
|
|
432
|
+
waitNoticeMs?: number;
|
|
403
433
|
}
|
|
404
434
|
type LockRelease = () => Promise<void>;
|
|
435
|
+
/** The release function of an acquired lock. */
|
|
436
|
+
interface HeldLock extends LockRelease {
|
|
437
|
+
/**
|
|
438
|
+
* False once this acquisition no longer owns the lock: released, or evicted
|
|
439
|
+
* as stale (e.g. the process was paused longer than `staleMs`). Check it
|
|
440
|
+
* right before a write that must not overwrite a later holder's work.
|
|
441
|
+
*/
|
|
442
|
+
isHeld(): Promise<boolean>;
|
|
443
|
+
}
|
|
405
444
|
|
|
406
445
|
/**
|
|
407
446
|
* Process lock for lessons-graph writes.
|
|
@@ -410,13 +449,12 @@ type LockRelease = () => Promise<void>;
|
|
|
410
449
|
* the rule once per failure, even when a hooked CI step and the user's editor
|
|
411
450
|
* race for the same `lessons.json`. The lock lives at
|
|
412
451
|
* `.agentsmesh/lessons/.lessons.lock` and reuses the same `acquireProcessLock`
|
|
413
|
-
* primitive as `.install.lock` / `.generate.lock`,
|
|
414
|
-
* cleanup, and PID metadata all behave identically.
|
|
452
|
+
* primitive as `.install.lock` / `.generate.lock`, with its own timing below.
|
|
415
453
|
*/
|
|
416
454
|
|
|
417
455
|
declare const LESSONS_LOCK_FILENAME = ".lessons.lock";
|
|
418
456
|
declare function lessonsLockPath(projectRoot: string): string;
|
|
419
|
-
declare function acquireLessonsLock(projectRoot: string, opts?: LockOptions): Promise<
|
|
457
|
+
declare function acquireLessonsLock(projectRoot: string, opts?: LockOptions): Promise<HeldLock>;
|
|
420
458
|
|
|
421
459
|
/**
|
|
422
460
|
* Default on-disk locations for the lessons subsystem.
|
|
@@ -472,18 +510,35 @@ declare function toRelPath(projectRoot: string, absolute: string): string;
|
|
|
472
510
|
*/
|
|
473
511
|
declare const LESSONS_PROCEDURAL_RULE = "## Lessons (BLOCKING)\n\nGraph `.agentsmesh/lessons/lessons.json` is canonical; never hand-edit it. Manual: `lessons` skill.\n\n**Recall:** before every file edit or state-changing command, MUST run `agentsmesh lessons query --file <path> --cmd <command> --session auto` and obey matches; at task start, ALSO run `agentsmesh lessons query --keyword \"<task terms>\" --always --session auto` for conceptual + universal rules no path/command names. Pure-read commands and recall itself are exempt.\n\n**Capture:** after any failure, user correction, regression, wrong assumption, useful surprise, repeated friction, or non-obvious fix, MUST self-critique and run `agentsmesh lessons add \"<imperative rule>\" --topic <id> --trigger-file <glob> --evidence <sha|lesson-id>`.\n\n**Before final:** report `Lesson: captured <id>` or `Lesson: none`. No recall/capture gate = task incomplete. No shell: use `lessons_query` / `lessons_add`.";
|
|
474
512
|
|
|
513
|
+
type MergeDriverSetup = {
|
|
514
|
+
readonly status: 'configured' | 'updated' | 'unchanged' | 'skipped';
|
|
515
|
+
readonly command: string;
|
|
516
|
+
} | {
|
|
517
|
+
readonly status: 'custom';
|
|
518
|
+
readonly command: string;
|
|
519
|
+
readonly existing: string;
|
|
520
|
+
} | {
|
|
521
|
+
readonly status: 'failed';
|
|
522
|
+
readonly command: string;
|
|
523
|
+
readonly reason: string;
|
|
524
|
+
};
|
|
525
|
+
|
|
475
526
|
interface ScaffoldLessonsResult {
|
|
476
527
|
readonly created: string[];
|
|
477
528
|
/** Managed artifacts rewritten to the current wording (e.g. a stale skill). */
|
|
478
529
|
readonly updated: string[];
|
|
479
530
|
readonly skipped: string[];
|
|
480
531
|
readonly rootRuleUpdated: boolean;
|
|
481
|
-
/** True when
|
|
532
|
+
/** True when any lessons runtime-artifact entry was added to `.gitignore`. */
|
|
482
533
|
readonly gitignoreUpdated: boolean;
|
|
483
534
|
/** True when the lessons.json merge-driver entry was added to `.gitattributes`. */
|
|
484
535
|
readonly gitattributesUpdated: boolean;
|
|
485
|
-
/** True when the
|
|
536
|
+
/** True when the lessons recall hook was injected into `hooks.yaml`. */
|
|
486
537
|
readonly recallHookInjected: boolean;
|
|
538
|
+
/** What this clone's merge-driver setup did; teammates get it on `generate`. */
|
|
539
|
+
readonly mergeDriver: MergeDriverSetup;
|
|
540
|
+
/** Set when recall hooks still need a global install to reach teammates. */
|
|
541
|
+
readonly recallHookTeamHint: string | null;
|
|
487
542
|
}
|
|
488
543
|
/**
|
|
489
544
|
* Idempotent scaffolder for the lessons subsystem. Backs `agentsmesh init
|
package/dist/lessons.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { o as RankedLesson, j as LessonsQuery, A as AddLessonInput, a as AddLessonOptions, b as AddLessonResult } from './init-
|
|
2
|
-
export { c as AddLessonTriggers, D as DEFAULT_RECALL_LIMIT, X as DEFAULT_RECALL_MAX_TOKENS, I as ImportLegacyOptions, d as ImportLegacyReport, Y as LESSONS_LOCK_FILENAME, L as LESSONS_PROCEDURAL_RULE, e as Lesson, f as LessonStatus, g as LessonsGraph, Z as LessonsGraphExistsError, h as LessonsGraphSchema, i as LessonsPaths, M as MatchedLesson, k as MergeLessonsOptions, l as MergeLessonsResult, m as MutateOptions, R as RankOptions, n as RankReason, S as ScaffoldLessonsResult, p as StripMarkersOptions, q as StripMarkersReport, T as Topic, r as Trigger, s as TriggerKind, U as UnknownTopicError, V as ValidationFinding, t as ValidationLevel, u as ValidationReport, v as acquireLessonsLock, w as addLesson, x as graphFilePath, y as importLegacyLessons, _ as lessonsLockPath, z as lessonsPaths, B as loadLessonsGraph, C as mergeLessons, E as mutateLessonsGraph, F as parseGraph, G as queryLessons, H as rankLessons, J as scaffoldLessons, K as serializeGraph, N as stripLegacyMarkers, O as stripMarkersInGraph, P as toRelPath, Q as tryLoadLessonsGraph, W as validateLessonsGraph } from './init-
|
|
1
|
+
import { o as RankedLesson, j as LessonsQuery, A as AddLessonInput, a as AddLessonOptions, b as AddLessonResult } from './init-DruMEhnc.js';
|
|
2
|
+
export { c as AddLessonTriggers, D as DEFAULT_RECALL_LIMIT, X as DEFAULT_RECALL_MAX_TOKENS, I as ImportLegacyOptions, d as ImportLegacyReport, Y as LESSONS_LOCK_FILENAME, L as LESSONS_PROCEDURAL_RULE, e as Lesson, f as LessonStatus, g as LessonsGraph, Z as LessonsGraphExistsError, h as LessonsGraphSchema, i as LessonsPaths, M as MatchedLesson, k as MergeLessonsOptions, l as MergeLessonsResult, m as MutateOptions, R as RankOptions, n as RankReason, S as ScaffoldLessonsResult, p as StripMarkersOptions, q as StripMarkersReport, T as Topic, r as Trigger, s as TriggerKind, U as UnknownTopicError, V as ValidationFinding, t as ValidationLevel, u as ValidationReport, v as acquireLessonsLock, w as addLesson, x as graphFilePath, y as importLegacyLessons, _ as lessonsLockPath, z as lessonsPaths, B as loadLessonsGraph, C as mergeLessons, E as mutateLessonsGraph, F as parseGraph, G as queryLessons, H as rankLessons, J as scaffoldLessons, K as serializeGraph, N as stripLegacyMarkers, O as stripMarkersInGraph, P as toRelPath, Q as tryLoadLessonsGraph, W as validateLessonsGraph } from './init-DruMEhnc.js';
|
|
3
3
|
import 'zod';
|
|
4
4
|
|
|
5
5
|
/**
|
|
@@ -92,6 +92,8 @@ declare function captureLesson(projectRoot: string, input: AddLessonInput, optio
|
|
|
92
92
|
* legacy store: if it added first it would create `lessons.json`, which then
|
|
93
93
|
* permanently blocks the absent-graph auto-migration. Returns true if it
|
|
94
94
|
* migrated. No-op when a graph already exists or no legacy index is present.
|
|
95
|
+
* The unlocked checks are a fast path; `requireAbsentGraph` repeats the graph
|
|
96
|
+
* check under the lessons lock before the legacy store is read.
|
|
95
97
|
*/
|
|
96
98
|
declare function maybeAutoMigrateLessons(projectRoot: string): Promise<boolean>;
|
|
97
99
|
|
|
@@ -108,8 +110,9 @@ declare function maybeAutoMigrateLessons(projectRoot: string): Promise<boolean>;
|
|
|
108
110
|
* linear in the input length for any pattern it can compile.
|
|
109
111
|
*
|
|
110
112
|
* A pattern is "safe" iff the linear engine can compile it. Patterns it cannot
|
|
111
|
-
* evaluate
|
|
112
|
-
*
|
|
113
|
+
* evaluate are dead triggers: capture drops them (DEAD_COMMAND_PATTERN), the
|
|
114
|
+
* write barrier and validate flag stored ones (INVALID_/UNSAFE_TRIGGER_PATTERN),
|
|
115
|
+
* and recall skips them: fail closed.
|
|
113
116
|
*/
|
|
114
117
|
|
|
115
118
|
/** True when `pattern` can be matched by the linear engine (no ReDoS risk). */
|