@aiassesstech/jessie 0.6.0 → 0.6.2

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.
Files changed (41) hide show
  1. package/dist/ea/calendar-conflicts.d.ts +30 -0
  2. package/dist/ea/calendar-conflicts.d.ts.map +1 -0
  3. package/dist/ea/calendar-conflicts.js +70 -0
  4. package/dist/ea/calendar-conflicts.js.map +1 -0
  5. package/dist/ea/correspondence-client.d.ts +54 -0
  6. package/dist/ea/correspondence-client.d.ts.map +1 -0
  7. package/dist/ea/correspondence-client.js +88 -0
  8. package/dist/ea/correspondence-client.js.map +1 -0
  9. package/dist/ea/daily-notes.d.ts +38 -0
  10. package/dist/ea/daily-notes.d.ts.map +1 -0
  11. package/dist/ea/daily-notes.js +93 -0
  12. package/dist/ea/daily-notes.js.map +1 -0
  13. package/dist/ea/ea-sweep.d.ts +49 -0
  14. package/dist/ea/ea-sweep.d.ts.map +1 -0
  15. package/dist/ea/ea-sweep.js +93 -0
  16. package/dist/ea/ea-sweep.js.map +1 -0
  17. package/dist/ea/fleet-attention-gate.d.ts +33 -0
  18. package/dist/ea/fleet-attention-gate.d.ts.map +1 -0
  19. package/dist/ea/fleet-attention-gate.js +46 -0
  20. package/dist/ea/fleet-attention-gate.js.map +1 -0
  21. package/dist/ea/gog-health.d.ts +34 -0
  22. package/dist/ea/gog-health.d.ts.map +1 -0
  23. package/dist/ea/gog-health.js +68 -0
  24. package/dist/ea/gog-health.js.map +1 -0
  25. package/dist/ea/index.d.ts +19 -0
  26. package/dist/ea/index.d.ts.map +1 -0
  27. package/dist/ea/index.js +13 -0
  28. package/dist/ea/index.js.map +1 -0
  29. package/dist/ea/sweep-state.d.ts +53 -0
  30. package/dist/ea/sweep-state.d.ts.map +1 -0
  31. package/dist/ea/sweep-state.js +145 -0
  32. package/dist/ea/sweep-state.js.map +1 -0
  33. package/dist/plugin.d.ts.map +1 -1
  34. package/dist/plugin.js +228 -2
  35. package/dist/plugin.js.map +1 -1
  36. package/dist/tools/jessie-wiki.d.ts +22 -1
  37. package/dist/tools/jessie-wiki.d.ts.map +1 -1
  38. package/dist/tools/jessie-wiki.js +21 -2
  39. package/dist/tools/jessie-wiki.js.map +1 -1
  40. package/openclaw.plugin.json +1 -1
  41. package/package.json +3 -3
@@ -0,0 +1,34 @@
1
+ /**
2
+ * GOG Health Gate — EA Infrastructure
3
+ *
4
+ * SPEC: SPEC-jessie-executive-assistant-activation-v1.0 §3.3, IH1
5
+ *
6
+ * Checks GOG (Google OAuth Gateway) availability before email/calendar
7
+ * operations. Handles first-failure and recovery notifications.
8
+ */
9
+ export interface GogHealthState {
10
+ healthy: boolean;
11
+ lastCheckedAt: string;
12
+ failedSince?: string;
13
+ notifiedGreg: boolean;
14
+ }
15
+ export interface GogHealthResult {
16
+ healthy: boolean;
17
+ firstFailure: boolean;
18
+ recovered: boolean;
19
+ }
20
+ export declare function resetGogHealthState(): void;
21
+ export declare function getGogHealthState(): GogHealthState;
22
+ /**
23
+ * Check GOG availability via `gog auth status`.
24
+ *
25
+ * Returns health status with transition flags:
26
+ * - firstFailure: GOG just went down (notify Greg once)
27
+ * - recovered: GOG just came back (notify Greg once)
28
+ */
29
+ export declare function checkGogHealth(gogBinaryPath?: string): GogHealthResult;
30
+ /**
31
+ * Mark that Greg has been notified about the current GOG state.
32
+ */
33
+ export declare function markGogNotified(): void;
34
+ //# sourceMappingURL=gog-health.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gog-health.d.ts","sourceRoot":"","sources":["../../src/ea/gog-health.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,OAAO,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,OAAO,CAAC;CACvB;AAED,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,OAAO,CAAC;IACjB,YAAY,EAAE,OAAO,CAAC;IACtB,SAAS,EAAE,OAAO,CAAC;CACpB;AAQD,wBAAgB,mBAAmB,IAAI,IAAI,CAM1C;AAED,wBAAgB,iBAAiB,IAAI,cAAc,CAElD;AAED;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,aAAa,GAAE,MAAc,GAAG,eAAe,CAkC7E;AAED;;GAEG;AACH,wBAAgB,eAAe,IAAI,IAAI,CAEtC"}
@@ -0,0 +1,68 @@
1
+ /**
2
+ * GOG Health Gate — EA Infrastructure
3
+ *
4
+ * SPEC: SPEC-jessie-executive-assistant-activation-v1.0 §3.3, IH1
5
+ *
6
+ * Checks GOG (Google OAuth Gateway) availability before email/calendar
7
+ * operations. Handles first-failure and recovery notifications.
8
+ */
9
+ import { execSync } from 'node:child_process';
10
+ let _state = {
11
+ healthy: true,
12
+ lastCheckedAt: new Date().toISOString(),
13
+ notifiedGreg: false,
14
+ };
15
+ export function resetGogHealthState() {
16
+ _state = {
17
+ healthy: true,
18
+ lastCheckedAt: new Date().toISOString(),
19
+ notifiedGreg: false,
20
+ };
21
+ }
22
+ export function getGogHealthState() {
23
+ return { ..._state };
24
+ }
25
+ /**
26
+ * Check GOG availability via `gog auth status`.
27
+ *
28
+ * Returns health status with transition flags:
29
+ * - firstFailure: GOG just went down (notify Greg once)
30
+ * - recovered: GOG just came back (notify Greg once)
31
+ */
32
+ export function checkGogHealth(gogBinaryPath = 'gog') {
33
+ const wasHealthy = _state.healthy;
34
+ let isHealthy = false;
35
+ try {
36
+ const output = execSync(`${gogBinaryPath} auth status`, {
37
+ timeout: 5000,
38
+ encoding: 'utf-8',
39
+ stdio: ['pipe', 'pipe', 'pipe'],
40
+ });
41
+ isHealthy = !output.toLowerCase().includes('expired') &&
42
+ !output.toLowerCase().includes('error') &&
43
+ !output.toLowerCase().includes('not authenticated');
44
+ }
45
+ catch {
46
+ isHealthy = false;
47
+ }
48
+ _state.lastCheckedAt = new Date().toISOString();
49
+ _state.healthy = isHealthy;
50
+ const firstFailure = wasHealthy && !isHealthy;
51
+ const recovered = !wasHealthy && isHealthy;
52
+ if (firstFailure) {
53
+ _state.failedSince = _state.lastCheckedAt;
54
+ _state.notifiedGreg = false;
55
+ }
56
+ if (recovered) {
57
+ _state.failedSince = undefined;
58
+ _state.notifiedGreg = false;
59
+ }
60
+ return { healthy: isHealthy, firstFailure, recovered };
61
+ }
62
+ /**
63
+ * Mark that Greg has been notified about the current GOG state.
64
+ */
65
+ export function markGogNotified() {
66
+ _state.notifiedGreg = true;
67
+ }
68
+ //# sourceMappingURL=gog-health.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gog-health.js","sourceRoot":"","sources":["../../src/ea/gog-health.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAe9C,IAAI,MAAM,GAAmB;IAC3B,OAAO,EAAE,IAAI;IACb,aAAa,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;IACvC,YAAY,EAAE,KAAK;CACpB,CAAC;AAEF,MAAM,UAAU,mBAAmB;IACjC,MAAM,GAAG;QACP,OAAO,EAAE,IAAI;QACb,aAAa,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QACvC,YAAY,EAAE,KAAK;KACpB,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,iBAAiB;IAC/B,OAAO,EAAE,GAAG,MAAM,EAAE,CAAC;AACvB,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,cAAc,CAAC,gBAAwB,KAAK;IAC1D,MAAM,UAAU,GAAG,MAAM,CAAC,OAAO,CAAC;IAClC,IAAI,SAAS,GAAG,KAAK,CAAC;IAEtB,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,QAAQ,CAAC,GAAG,aAAa,cAAc,EAAE;YACtD,OAAO,EAAE,IAAI;YACb,QAAQ,EAAE,OAAO;YACjB,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC;SAChC,CAAC,CAAC;QACH,SAAS,GAAG,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,SAAS,CAAC;YACzC,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,OAAO,CAAC;YACvC,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,mBAAmB,CAAC,CAAC;IAClE,CAAC;IAAC,MAAM,CAAC;QACP,SAAS,GAAG,KAAK,CAAC;IACpB,CAAC;IAED,MAAM,CAAC,aAAa,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IAChD,MAAM,CAAC,OAAO,GAAG,SAAS,CAAC;IAE3B,MAAM,YAAY,GAAG,UAAU,IAAI,CAAC,SAAS,CAAC;IAC9C,MAAM,SAAS,GAAG,CAAC,UAAU,IAAI,SAAS,CAAC;IAE3C,IAAI,YAAY,EAAE,CAAC;QACjB,MAAM,CAAC,WAAW,GAAG,MAAM,CAAC,aAAa,CAAC;QAC1C,MAAM,CAAC,YAAY,GAAG,KAAK,CAAC;IAC9B,CAAC;IAED,IAAI,SAAS,EAAE,CAAC;QACd,MAAM,CAAC,WAAW,GAAG,SAAS,CAAC;QAC/B,MAAM,CAAC,YAAY,GAAG,KAAK,CAAC;IAC9B,CAAC;IAED,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,SAAS,EAAE,CAAC;AACzD,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,eAAe;IAC7B,MAAM,CAAC,YAAY,GAAG,IAAI,CAAC;AAC7B,CAAC"}
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Jessie EA (Executive Assistant) Module — Barrel Export
3
+ *
4
+ * SPEC: SPEC-jessie-executive-assistant-activation-v1.0
5
+ */
6
+ export { checkFleetAttention, } from './fleet-attention-gate.js';
7
+ export type { FleetAttentionResult, FleetAttentionDeps } from './fleet-attention-gate.js';
8
+ export { checkGogHealth, markGogNotified, getGogHealthState, resetGogHealthState, } from './gog-health.js';
9
+ export type { GogHealthState, GogHealthResult } from './gog-health.js';
10
+ export { EaSweepState } from './sweep-state.js';
11
+ export type { SweepStateData, TriageStats, GrilloAssessmentStats, } from './sweep-state.js';
12
+ export { DailyNotes } from './daily-notes.js';
13
+ export { assessDraft, probeGrilloRecovery, } from './correspondence-client.js';
14
+ export type { CorrespondenceAssessmentResult, CorrespondenceClientDeps, } from './correspondence-client.js';
15
+ export { detectConflicts, formatConflictAlert, } from './calendar-conflicts.js';
16
+ export type { CalendarEvent, CalendarConflict } from './calendar-conflicts.js';
17
+ export { runEaSweep } from './ea-sweep.js';
18
+ export type { EaSweepDeps, EaSweepResult } from './ea-sweep.js';
19
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/ea/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EACL,mBAAmB,GACpB,MAAM,2BAA2B,CAAC;AACnC,YAAY,EAAE,oBAAoB,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAE1F,OAAO,EACL,cAAc,EACd,eAAe,EACf,iBAAiB,EACjB,mBAAmB,GACpB,MAAM,iBAAiB,CAAC;AACzB,YAAY,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAEvE,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAChD,YAAY,EACV,cAAc,EACd,WAAW,EACX,qBAAqB,GACtB,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAE9C,OAAO,EACL,WAAW,EACX,mBAAmB,GACpB,MAAM,4BAA4B,CAAC;AACpC,YAAY,EACV,8BAA8B,EAC9B,wBAAwB,GACzB,MAAM,4BAA4B,CAAC;AAEpC,OAAO,EACL,eAAe,EACf,mBAAmB,GACpB,MAAM,yBAAyB,CAAC;AACjC,YAAY,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAE/E,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC3C,YAAY,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Jessie EA (Executive Assistant) Module — Barrel Export
3
+ *
4
+ * SPEC: SPEC-jessie-executive-assistant-activation-v1.0
5
+ */
6
+ export { checkFleetAttention, } from './fleet-attention-gate.js';
7
+ export { checkGogHealth, markGogNotified, getGogHealthState, resetGogHealthState, } from './gog-health.js';
8
+ export { EaSweepState } from './sweep-state.js';
9
+ export { DailyNotes } from './daily-notes.js';
10
+ export { assessDraft, probeGrilloRecovery, } from './correspondence-client.js';
11
+ export { detectConflicts, formatConflictAlert, } from './calendar-conflicts.js';
12
+ export { runEaSweep } from './ea-sweep.js';
13
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/ea/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EACL,mBAAmB,GACpB,MAAM,2BAA2B,CAAC;AAGnC,OAAO,EACL,cAAc,EACd,eAAe,EACf,iBAAiB,EACjB,mBAAmB,GACpB,MAAM,iBAAiB,CAAC;AAGzB,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAOhD,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAE9C,OAAO,EACL,WAAW,EACX,mBAAmB,GACpB,MAAM,4BAA4B,CAAC;AAMpC,OAAO,EACL,eAAe,EACf,mBAAmB,GACpB,MAAM,yBAAyB,CAAC;AAGjC,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC"}
@@ -0,0 +1,53 @@
1
+ /**
2
+ * EA Sweep State — Persistence & Deduplication
3
+ *
4
+ * SPEC: SPEC-jessie-executive-assistant-activation-v1.0 §3.1, IH2
5
+ *
6
+ * Tracks processed message IDs to prevent re-processing, triage
7
+ * statistics, Grillo assessment counts, and sweep metadata.
8
+ * Persists to .jessie-data/ea-sweep-state.json.
9
+ */
10
+ export interface GrilloAssessmentStats {
11
+ green: number;
12
+ yellow: number;
13
+ red: number;
14
+ recuse: number;
15
+ unavailable: number;
16
+ degraded: boolean;
17
+ consecutiveTimeouts: number;
18
+ lastAssessmentHash: string;
19
+ lastRubricVersion: string;
20
+ }
21
+ export interface TriageStats {
22
+ autoResolved: number;
23
+ escalated: number;
24
+ archived: number;
25
+ tasksCreated: number;
26
+ grilloAssessments: GrilloAssessmentStats;
27
+ }
28
+ export interface SweepStateData {
29
+ lastSweepAt: string | null;
30
+ processedMessageIds: string[];
31
+ triageStats: TriageStats;
32
+ gogHealthy: boolean;
33
+ fleetAttentionDeferred: boolean;
34
+ lastDeferralReason?: string;
35
+ }
36
+ export declare class EaSweepState {
37
+ private data;
38
+ private readonly filePath;
39
+ constructor(dataDir: string);
40
+ get state(): Readonly<SweepStateData>;
41
+ isProcessed(messageId: string): boolean;
42
+ markProcessed(messageId: string): void;
43
+ recordSweep(stats: Partial<TriageStats>): void;
44
+ recordGrilloAssessment(verdict: 'green' | 'yellow' | 'red' | 'recuse' | 'unavailable', assessmentHash?: string, rubricVersion?: string): void;
45
+ setGogHealthy(healthy: boolean): void;
46
+ setFleetDeferred(deferred: boolean, reason?: string): void;
47
+ isGrilloDegraded(): boolean;
48
+ clearGrilloDegraded(): void;
49
+ pruneOldMessages(): void;
50
+ save(): void;
51
+ private load;
52
+ }
53
+ //# sourceMappingURL=sweep-state.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sweep-state.d.ts","sourceRoot":"","sources":["../../src/ea/sweep-state.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAKH,MAAM,WAAW,qBAAqB;IACpC,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,OAAO,CAAC;IAClB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,kBAAkB,EAAE,MAAM,CAAC;IAC3B,iBAAiB,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,WAAW,WAAW;IAC1B,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,iBAAiB,EAAE,qBAAqB,CAAC;CAC1C;AAED,MAAM,WAAW,cAAc;IAC7B,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,mBAAmB,EAAE,MAAM,EAAE,CAAC;IAC9B,WAAW,EAAE,WAAW,CAAC;IACzB,UAAU,EAAE,OAAO,CAAC;IACpB,sBAAsB,EAAE,OAAO,CAAC;IAChC,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC7B;AAsBD,qBAAa,YAAY;IACvB,OAAO,CAAC,IAAI,CAAiB;IAC7B,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;gBAEtB,OAAO,EAAE,MAAM;IAK3B,IAAI,KAAK,IAAI,QAAQ,CAAC,cAAc,CAAC,CAEpC;IAED,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO;IAIvC,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;IAMtC,WAAW,CAAC,KAAK,EAAE,OAAO,CAAC,WAAW,CAAC,GAAG,IAAI;IAQ9C,sBAAsB,CACpB,OAAO,EAAE,OAAO,GAAG,QAAQ,GAAG,KAAK,GAAG,QAAQ,GAAG,aAAa,EAC9D,cAAc,CAAC,EAAE,MAAM,EACvB,aAAa,CAAC,EAAE,MAAM,GACrB,IAAI;IAkBP,aAAa,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI;IAIrC,gBAAgB,CAAC,QAAQ,EAAE,OAAO,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI;IAK1D,gBAAgB,IAAI,OAAO;IAI3B,mBAAmB,IAAI,IAAI;IAK3B,gBAAgB,IAAI,IAAI;IAcxB,IAAI,IAAI,IAAI;IAUZ,OAAO,CAAC,IAAI;CAiCb"}
@@ -0,0 +1,145 @@
1
+ /**
2
+ * EA Sweep State — Persistence & Deduplication
3
+ *
4
+ * SPEC: SPEC-jessie-executive-assistant-activation-v1.0 §3.1, IH2
5
+ *
6
+ * Tracks processed message IDs to prevent re-processing, triage
7
+ * statistics, Grillo assessment counts, and sweep metadata.
8
+ * Persists to .jessie-data/ea-sweep-state.json.
9
+ */
10
+ import * as fs from 'node:fs';
11
+ import * as path from 'node:path';
12
+ const DEFAULT_STATS = {
13
+ autoResolved: 0,
14
+ escalated: 0,
15
+ archived: 0,
16
+ tasksCreated: 0,
17
+ grilloAssessments: {
18
+ green: 0,
19
+ yellow: 0,
20
+ red: 0,
21
+ recuse: 0,
22
+ unavailable: 0,
23
+ degraded: false,
24
+ consecutiveTimeouts: 0,
25
+ lastAssessmentHash: '',
26
+ lastRubricVersion: '',
27
+ },
28
+ };
29
+ const MAX_MESSAGE_AGE_MS = 7 * 24 * 60 * 60 * 1000;
30
+ export class EaSweepState {
31
+ data;
32
+ filePath;
33
+ constructor(dataDir) {
34
+ this.filePath = path.join(dataDir, 'ea-sweep-state.json');
35
+ this.data = this.load();
36
+ }
37
+ get state() {
38
+ return this.data;
39
+ }
40
+ isProcessed(messageId) {
41
+ return this.data.processedMessageIds.includes(messageId);
42
+ }
43
+ markProcessed(messageId) {
44
+ if (!this.data.processedMessageIds.includes(messageId)) {
45
+ this.data.processedMessageIds.push(messageId);
46
+ }
47
+ }
48
+ recordSweep(stats) {
49
+ this.data.lastSweepAt = new Date().toISOString();
50
+ if (stats.autoResolved)
51
+ this.data.triageStats.autoResolved += stats.autoResolved;
52
+ if (stats.escalated)
53
+ this.data.triageStats.escalated += stats.escalated;
54
+ if (stats.archived)
55
+ this.data.triageStats.archived += stats.archived;
56
+ if (stats.tasksCreated)
57
+ this.data.triageStats.tasksCreated += stats.tasksCreated;
58
+ }
59
+ recordGrilloAssessment(verdict, assessmentHash, rubricVersion) {
60
+ const ga = this.data.triageStats.grilloAssessments;
61
+ ga[verdict]++;
62
+ if (verdict === 'unavailable') {
63
+ ga.consecutiveTimeouts++;
64
+ if (ga.consecutiveTimeouts >= 2) {
65
+ ga.degraded = true;
66
+ }
67
+ }
68
+ else {
69
+ ga.consecutiveTimeouts = 0;
70
+ ga.degraded = false;
71
+ }
72
+ if (assessmentHash)
73
+ ga.lastAssessmentHash = assessmentHash;
74
+ if (rubricVersion)
75
+ ga.lastRubricVersion = rubricVersion;
76
+ }
77
+ setGogHealthy(healthy) {
78
+ this.data.gogHealthy = healthy;
79
+ }
80
+ setFleetDeferred(deferred, reason) {
81
+ this.data.fleetAttentionDeferred = deferred;
82
+ this.data.lastDeferralReason = reason;
83
+ }
84
+ isGrilloDegraded() {
85
+ return this.data.triageStats.grilloAssessments.degraded;
86
+ }
87
+ clearGrilloDegraded() {
88
+ this.data.triageStats.grilloAssessments.degraded = false;
89
+ this.data.triageStats.grilloAssessments.consecutiveTimeouts = 0;
90
+ }
91
+ pruneOldMessages() {
92
+ const cutoff = Date.now() - MAX_MESSAGE_AGE_MS;
93
+ const before = this.data.processedMessageIds.length;
94
+ this.data.processedMessageIds = this.data.processedMessageIds.filter((id) => {
95
+ const ts = parseInt(id.split('_').pop() ?? '0', 10);
96
+ return isNaN(ts) || ts > cutoff;
97
+ });
98
+ if (this.data.processedMessageIds.length < before) {
99
+ console.log(`[jessie:ea] Pruned ${before - this.data.processedMessageIds.length} old message IDs`);
100
+ }
101
+ }
102
+ save() {
103
+ const dir = path.dirname(this.filePath);
104
+ if (!fs.existsSync(dir)) {
105
+ fs.mkdirSync(dir, { recursive: true });
106
+ }
107
+ const tmp = this.filePath + '.tmp';
108
+ fs.writeFileSync(tmp, JSON.stringify(this.data, null, 2), 'utf-8');
109
+ fs.renameSync(tmp, this.filePath);
110
+ }
111
+ load() {
112
+ try {
113
+ if (fs.existsSync(this.filePath)) {
114
+ const raw = fs.readFileSync(this.filePath, 'utf-8');
115
+ const parsed = JSON.parse(raw);
116
+ return {
117
+ lastSweepAt: parsed.lastSweepAt ?? null,
118
+ processedMessageIds: parsed.processedMessageIds ?? [],
119
+ triageStats: {
120
+ ...DEFAULT_STATS,
121
+ ...(parsed.triageStats ?? {}),
122
+ grilloAssessments: {
123
+ ...DEFAULT_STATS.grilloAssessments,
124
+ ...(parsed.triageStats?.grilloAssessments ?? {}),
125
+ },
126
+ },
127
+ gogHealthy: parsed.gogHealthy ?? true,
128
+ fleetAttentionDeferred: parsed.fleetAttentionDeferred ?? false,
129
+ lastDeferralReason: parsed.lastDeferralReason,
130
+ };
131
+ }
132
+ }
133
+ catch {
134
+ console.warn('[jessie:ea] Failed to load sweep state, starting fresh');
135
+ }
136
+ return {
137
+ lastSweepAt: null,
138
+ processedMessageIds: [],
139
+ triageStats: { ...DEFAULT_STATS, grilloAssessments: { ...DEFAULT_STATS.grilloAssessments } },
140
+ gogHealthy: true,
141
+ fleetAttentionDeferred: false,
142
+ };
143
+ }
144
+ }
145
+ //# sourceMappingURL=sweep-state.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sweep-state.js","sourceRoot":"","sources":["../../src/ea/sweep-state.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAoFH,MAAM,CAAC,OAAO,UAAU,QAAQ,CAAC,GAAG,EAAE,GAAG,QAoqBxC"}
1
+ {"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAoFH,MAAM,CAAC,OAAO,UAAU,QAAQ,CAAC,GAAG,EAAE,GAAG,QA+5BxC"}
package/dist/plugin.js CHANGED
@@ -282,7 +282,7 @@ export default function register(api) {
282
282
  console.warn(`[jessie] Knowledge store init failed: ${err instanceof Error ? err.message : String(err)}`);
283
283
  }
284
284
  };
285
- const wikiTool = createJessieWikiTool(getKnowledgeStore);
285
+ const wikiTool = createJessieWikiTool(getKnowledgeStore, () => decisionStore);
286
286
  api.registerTool(wikiTool);
287
287
  // ── Phase 4: Channel Config ────────────────────────────────────
288
288
  const channelRegistry = resolveChannelRegistry(cfg);
@@ -444,6 +444,7 @@ export default function register(api) {
444
444
  fleetReceive(bus, {
445
445
  methods: [
446
446
  'assessment/result', 'assessment/failed',
447
+ 'correspondence/result',
447
448
  'drift/alert', 'drift/report',
448
449
  'health/alert', 'health/status', 'health/incident',
449
450
  'proposal/submit',
@@ -466,6 +467,21 @@ export default function register(api) {
466
467
  }).catch(() => { });
467
468
  return;
468
469
  }
470
+ if (msg.method === 'correspondence/result') {
471
+ const { verdict, reasoning, assessmentHash, rubricVersion, durationMs, dimensionFlags } = msg.params ?? {};
472
+ console.log(`[jessie] Correspondence assessment from Grillo: ${verdict} (${durationMs}ms, hash: ${assessmentHash?.slice(0, 8)}...)`);
473
+ try {
474
+ const { EaSweepState } = await import('./ea/sweep-state.js');
475
+ const sweepState = new EaSweepState(cfg.dataDir);
476
+ const verdictLower = (verdict ?? 'unavailable').toLowerCase();
477
+ sweepState.recordGrilloAssessment(verdictLower, assessmentHash, rubricVersion);
478
+ sweepState.save();
479
+ }
480
+ catch (err) {
481
+ console.warn('[jessie] Failed to record correspondence assessment:', err instanceof Error ? err.message : String(err));
482
+ }
483
+ return;
484
+ }
469
485
  if (msg.method === 'cron/scheduled') {
470
486
  const { action, data, jobId } = msg.params ?? {};
471
487
  let syntheticMessage = null;
@@ -569,6 +585,96 @@ export default function register(api) {
569
585
  }
570
586
  return;
571
587
  }
588
+ else if (action === 'ea_sweep') {
589
+ console.log(`[jessie] EA sweep triggered (job: ${jobId})`);
590
+ try {
591
+ const { runEaSweep } = await import('./ea/ea-sweep.js');
592
+ const { EaSweepState } = await import('./ea/sweep-state.js');
593
+ const { DailyNotes } = await import('./ea/daily-notes.js');
594
+ const workspaceDir = capturedWorkspaceDir ?? loadAgentWorkspaces()['jessie'];
595
+ const sweepState = new EaSweepState(cfg.dataDir);
596
+ const dailyNotes = new DailyNotes(workspaceDir ?? cfg.dataDir);
597
+ const recentAlerts = [];
598
+ const result = await runEaSweep({
599
+ decisionStore,
600
+ sweepState,
601
+ dailyNotes,
602
+ getFleetBusStatus,
603
+ getRecentFleetAlerts: () => recentAlerts,
604
+ notifyGreg: async (message, label) => {
605
+ await transport.callGateway({
606
+ method: 'agent',
607
+ params: { agentId: 'jessie', message, deliver: true, label },
608
+ });
609
+ },
610
+ });
611
+ if (result.deferred) {
612
+ syntheticMessage = `SYSTEM: EA sweep deferred — fleet attention required: ${result.deferralReason}. Execute Commander duties now.`;
613
+ }
614
+ else if (!result.gogHealthy) {
615
+ console.log('[jessie] EA sweep: GOG unavailable, limited sweep completed');
616
+ }
617
+ await fleetSend(bus, transport, {
618
+ to: 'noah',
619
+ method: 'cron/completed',
620
+ params: {
621
+ jobId, action, status: 'completed',
622
+ deferred: result.deferred,
623
+ gogHealthy: result.gogHealthy,
624
+ conflicts: result.conflictsDetected,
625
+ timestamp: new Date().toISOString(),
626
+ },
627
+ }).catch(() => { });
628
+ }
629
+ catch (err) {
630
+ console.error(`[jessie] EA sweep failed:`, err instanceof Error ? err.message : String(err));
631
+ await fleetSend(bus, transport, {
632
+ to: 'noah',
633
+ method: 'cron/failed',
634
+ params: { jobId, action, error: err instanceof Error ? err.message : String(err), timestamp: new Date().toISOString() },
635
+ }).catch(() => { });
636
+ }
637
+ return;
638
+ }
639
+ else if (action === 'daily_notes_rollover') {
640
+ console.log(`[jessie] Daily notes rollover triggered (job: ${jobId})`);
641
+ try {
642
+ const { DailyNotes } = await import('./ea/daily-notes.js');
643
+ const workspaceDir = capturedWorkspaceDir ?? loadAgentWorkspaces()['jessie'];
644
+ const dailyNotes = new DailyNotes(workspaceDir ?? cfg.dataDir);
645
+ const rollResult = dailyNotes.rollover();
646
+ console.log(`[jessie] Daily notes: closed ${rollResult.closedDate}, opened ${rollResult.openedDate}`);
647
+ await fleetSend(bus, transport, {
648
+ to: 'noah',
649
+ method: 'cron/completed',
650
+ params: { jobId, action, status: 'completed', ...rollResult, timestamp: new Date().toISOString() },
651
+ }).catch(() => { });
652
+ }
653
+ catch (err) {
654
+ console.error(`[jessie] Daily notes rollover failed:`, err instanceof Error ? err.message : String(err));
655
+ await fleetSend(bus, transport, {
656
+ to: 'noah',
657
+ method: 'cron/failed',
658
+ params: { jobId, action, error: err instanceof Error ? err.message : String(err), timestamp: new Date().toISOString() },
659
+ }).catch(() => { });
660
+ }
661
+ return;
662
+ }
663
+ else if (action === 'daily_task_prep') {
664
+ syntheticMessage = 'SYSTEM: Daily Task Prep — cron-triggered by Noah. Read tasks.md, archive yesterday\'s completed items, promote due-today items, check calendar for meeting-related tasks, flag overdue items rolling forward 3+ days. Silent operation — no message to Greg.';
665
+ }
666
+ else if (action === 'meeting_prep') {
667
+ syntheticMessage = 'SYSTEM: Meeting Prep Check — cron-triggered by Noah. Check calendar for meetings starting in 45–75 minutes. For each, generate prep brief with attendees, prior notes, open tasks, relationship context. Send to Greg if new prep needed. Skip if already prepped (check meeting-prep-state.json).';
668
+ }
669
+ else if (action === 'evening_task_sweep') {
670
+ syntheticMessage = 'SYSTEM: Evening Task Sweep — cron-triggered by Noah. Read tasks.md and today\'s daily notes. Report to Greg: completed today, overdue, coming this week, items rolling 5+ days, high-stakes items for tomorrow. Stay silent if nothing needs attention.';
671
+ }
672
+ else if (action === 'kaizen_research') {
673
+ syntheticMessage = 'SYSTEM: Kaizen Research — cron-triggered by Noah. Scan for external patterns (OpenClaw community, shared configs). Analyze internal drift: recurring corrections, noisy triage filters, stale people articles, task patterns rolling forward, veto counts and approval rates, Grillo assessment outcomes of your own drafts. Write findings to agent/kaizen/kaizen-YYYY-MM-DD.md. Surface top 3 actionable improvements for Monday morning briefing.';
674
+ }
675
+ else if (action === 'bd_sourcing') {
676
+ syntheticMessage = 'SYSTEM: BD Sourcing — cron-triggered by Noah. Partner research against agent/partners.md, outreach tracking via knowledge base people articles, CRM hygiene: flag stale contacts, update pipeline status. Any cold emails must be submitted to Grillo for LCSH assessment before sending.';
677
+ }
572
678
  else {
573
679
  console.log(`[jessie] Unknown cron action: ${action} (job: ${jobId})`);
574
680
  }
@@ -609,6 +715,19 @@ export default function register(api) {
609
715
  if (delegationId && msg.method === 'task/complete') {
610
716
  decisionStore.closeDelegation(delegationId);
611
717
  }
718
+ if (msg.method === 'task/complete' && msg.payload?.compilationEventId) {
719
+ const p = msg.payload;
720
+ decisionStore.addWikiCompilation({
721
+ timestamp: new Date().toISOString(),
722
+ target: p.target || 'jessie',
723
+ articleSlug: p.articleSlug || 'unknown',
724
+ category: p.category || 'unknown',
725
+ contentHash: p.contentHash || '',
726
+ sourceCount: p.sourceCount || 0,
727
+ derivedRatio: p.derivedRatio || 0,
728
+ compiledBy: msg.from || 'sam',
729
+ });
730
+ }
612
731
  }
613
732
  },
614
733
  });
@@ -634,6 +753,113 @@ export default function register(api) {
634
753
  fleetBusState = 'standalone';
635
754
  console.warn("[jessie] Fleet bus unavailable — operating standalone");
636
755
  });
756
+ // ──────────────────────────────────────────────────────────────
757
+ // DIAGNOSTIC: jessie_test_correspondence_dispatch
758
+ // Full A2A smoke test — sends correspondence/assess through
759
+ // the real fleet-bus transport to Grillo. Exercises every layer:
760
+ // Jessie fleetSend → transportSend → callGateway → OpenClaw A2A
761
+ // → Grillo message_received hook → dispatchToReceivers → handler
762
+ // ──────────────────────────────────────────────────────────────
763
+ api.registerTool({
764
+ name: "jessie_test_correspondence_dispatch",
765
+ description: "Diagnostic: send a correspondence/assess fleet message to Grillo " +
766
+ "through the real A2A transport. Tests the full fleet-bus path " +
767
+ "end-to-end. Returns Grillo's structured reply or transport error.",
768
+ parameters: {
769
+ type: "object",
770
+ properties: {
771
+ draft: {
772
+ type: "string",
773
+ description: "The draft message to assess.",
774
+ },
775
+ recipientPLevel: {
776
+ type: "string",
777
+ description: "Recipient priority level.",
778
+ enum: ["P0", "P1", "P2", "P3"],
779
+ },
780
+ actionType: {
781
+ type: "string",
782
+ description: "Type of correspondence.",
783
+ enum: ["cold-outreach", "auto-resolve-email", "auto-resolve-message"],
784
+ },
785
+ threadContext: {
786
+ type: "string",
787
+ description: "Optional thread context.",
788
+ },
789
+ },
790
+ required: ["draft", "recipientPLevel", "actionType"],
791
+ },
792
+ async execute(_toolCallId, params) {
793
+ const fleet = getFleetContext();
794
+ if (!fleet) {
795
+ return {
796
+ content: [{
797
+ type: "text",
798
+ text: "# Dispatch FAILED\n\n" +
799
+ `**Fleet bus state:** ${getFleetBusStatus()}\n` +
800
+ "**Reason:** fleetContext is null — fleet-bus dynamic import failed or transport not available.\n\n" +
801
+ "This confirms BB's failure mode #1 or #2: the async `import('@aiassesstech/fleet-bus')` " +
802
+ "either threw, or `createTransport()` returned null.",
803
+ }],
804
+ isError: true,
805
+ };
806
+ }
807
+ const startMs = Date.now();
808
+ try {
809
+ const result = await fleet.fleetSend(fleet.bus, fleet.transport, {
810
+ to: "grillo",
811
+ method: "correspondence/assess",
812
+ params: {
813
+ draft: params.draft,
814
+ recipientPLevel: params.recipientPLevel,
815
+ actionType: params.actionType,
816
+ threadContext: params.threadContext,
817
+ },
818
+ });
819
+ const durationMs = Date.now() - startMs;
820
+ const lines = [
821
+ "# Correspondence Dispatch — Full A2A Test",
822
+ "",
823
+ "## Transport Result",
824
+ `- **Success:** ${result.success}`,
825
+ `- **Status:** ${result.status ?? "N/A"}`,
826
+ `- **Duration:** ${durationMs}ms (transport round-trip)`,
827
+ `- **Error:** ${result.error ?? "none"}`,
828
+ "",
829
+ "## What This Proves",
830
+ result.success
831
+ ? "- ✅ Jessie's fleet-bus is connected and `fleetSend` works\n" +
832
+ "- ✅ `transportSend` serialized the %%FLEET%% message\n" +
833
+ "- ✅ `callGateway({ method: 'agent' })` delivered to Grillo\n" +
834
+ "- ✅ OpenClaw A2A transport reached Grillo's agent\n" +
835
+ "- ✅ Grillo's `message_received` hook fired\n" +
836
+ "- ✅ `dispatchToReceivers` routed to `fleetReceive` handler\n" +
837
+ "- ✅ `handleCorrespondenceAssess` executed\n\n" +
838
+ "**The full dual-path pipeline is operational.**"
839
+ : "- ❌ Transport failed — check error above\n" +
840
+ "- The message did not reach Grillo through the fleet-bus path",
841
+ ];
842
+ const reply = result.reply;
843
+ if (reply) {
844
+ lines.push("", "## Grillo's Reply (raw, first 800 chars)", "```", String(reply).slice(0, 800), "```");
845
+ }
846
+ return { content: [{ type: "text", text: lines.join("\n") }] };
847
+ }
848
+ catch (err) {
849
+ const errMsg = err instanceof Error ? err.message : String(err);
850
+ return {
851
+ content: [{
852
+ type: "text",
853
+ text: "# Dispatch FAILED — Exception\n\n" +
854
+ `**Error:** ${errMsg}\n` +
855
+ `**Duration:** ${Date.now() - startMs}ms\n\n` +
856
+ "This is a transport-level failure. Check gateway logs.",
857
+ }],
858
+ isError: true,
859
+ };
860
+ }
861
+ },
862
+ }, { optional: false });
637
863
  let capturedWorkspaceDir = null;
638
864
  api.registerHook("agent:bootstrap", async (event) => {
639
865
  const ctx = event?.context;
@@ -703,6 +929,6 @@ export default function register(api) {
703
929
  });
704
930
  console.log("[jessie] Context gate registered (before_prompt_build, policy summaries enabled, 800-token ceiling)");
705
931
  }
706
- console.log('[jessie] Plugin registered: jessie_status, jessie_briefing, jessie_delegate, jessie_decide, jessie_report, jessie_policy, jessie_tasks, jessie_trends, jessie_correct, jessie_meetings, fleet_memory_search, jessie_fleet_snapshot, jessie_wiki; /jessie command');
932
+ console.log('[jessie] Plugin registered: jessie_status, jessie_briefing, jessie_delegate, jessie_decide, jessie_report, jessie_policy, jessie_tasks, jessie_trends, jessie_correct, jessie_meetings, fleet_memory_search, jessie_fleet_snapshot, jessie_wiki, jessie_test_correspondence_dispatch; /jessie command');
707
933
  }
708
934
  //# sourceMappingURL=plugin.js.map