@karmaniverous/jeeves-meta-openclaw 0.13.1 → 0.13.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.
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { resolvePluginSetting, resolveOptionalPluginSetting, fetchJson, postJson, ok, connectionFail, createPluginToolset, resolveWorkspacePath, init, loadWorkspaceConfig, WORKSPACE_CONFIG_DEFAULTS, createAsyncContentCache, jeevesComponentDescriptorSchema, getPackageVersion, createComponentWriter } from '@karmaniverous/jeeves';
2
- import { phaseNames, getEndpoint, META_COMPONENT } from '@karmaniverous/jeeves-meta-core';
2
+ import { phaseStatuses, phaseNames, getEndpoint, META_COMPONENT } from '@karmaniverous/jeeves-meta-core';
3
3
 
4
4
  /**
5
5
  * Shared constants for the jeeves-meta OpenClaw plugin.
@@ -35,6 +35,33 @@ function getConfigRoot(api) {
35
35
  *
36
36
  * @module promptInjection
37
37
  */
38
+ /** Phase statuses that require per-phase breakdown (everything except fresh). */
39
+ const nonFreshStatuses = phaseStatuses.filter((s) => s !== 'fresh');
40
+ /**
41
+ * Format a duration in seconds as a compound human-readable interval.
42
+ *
43
+ * Produces at most two units: `2d 3h`, `1h 35m`, `45m`, etc.
44
+ * Returns `'never synthesized'` for non-finite input.
45
+ *
46
+ * @param seconds - Duration in seconds.
47
+ * @returns Formatted interval string.
48
+ */
49
+ function formatAge(seconds) {
50
+ if (!isFinite(seconds))
51
+ return 'never synthesized';
52
+ const d = Math.floor(seconds / 86400);
53
+ const h = Math.floor((seconds % 86400) / 3600);
54
+ const m = Math.floor((seconds % 3600) / 60);
55
+ if (d > 0 && h > 0)
56
+ return `${d.toString()}d ${h.toString()}h`;
57
+ if (d > 0)
58
+ return `${d.toString()}d`;
59
+ if (h > 0 && m > 0)
60
+ return `${h.toString()}h ${m.toString()}m`;
61
+ if (h > 0)
62
+ return `${h.toString()}h`;
63
+ return `${Math.max(m, 1).toString()}m`;
64
+ }
38
65
  /**
39
66
  * Generate the Meta menu Markdown for TOOLS.md.
40
67
  *
@@ -56,15 +83,6 @@ async function generateMetaMenu(client) {
56
83
  ].join('\n');
57
84
  }
58
85
  const { summary } = metas;
59
- const formatAge = (seconds) => {
60
- if (!isFinite(seconds))
61
- return 'never synthesized';
62
- if (seconds < 3600)
63
- return Math.round(seconds / 60).toString() + 'm';
64
- if (seconds < 86400)
65
- return Math.round(seconds / 3600).toString() + 'h';
66
- return Math.round(seconds / 86400).toString() + 'd';
67
- };
68
86
  // Find stalest age
69
87
  let stalestAge = 0;
70
88
  for (const item of metas.metas) {
@@ -103,20 +121,19 @@ async function generateMetaMenu(client) {
103
121
  const phaseLines = [];
104
122
  const phaseSummary = status.health.phaseStateSummary;
105
123
  if (phaseSummary) {
106
- // Aggregate counts across all phases
107
- const totals = {};
124
+ // Fresh counts are aggregated; non-fresh show <count> <state> <phase>
125
+ let freshTotal = 0;
108
126
  for (const phase of phaseNames) {
109
- const counts = phaseSummary[phase];
110
- for (const [state, count] of Object.entries(counts)) {
111
- if (count > 0) {
112
- totals[state] = (totals[state] ?? 0) + count;
113
- }
114
- }
127
+ freshTotal += phaseSummary[phase].fresh;
115
128
  }
116
129
  const parts = [];
117
- for (const state of ['fresh', 'pending', 'running', 'stale', 'failed']) {
118
- if (totals[state]) {
119
- parts.push(totals[state].toString() + ' ' + state);
130
+ if (freshTotal > 0)
131
+ parts.push(freshTotal.toString() + ' fresh');
132
+ for (const phase of phaseNames) {
133
+ for (const state of nonFreshStatuses) {
134
+ const count = phaseSummary[phase][state];
135
+ if (count > 0)
136
+ parts.push(`${count.toString()} ${state} ${phase}`);
120
137
  }
121
138
  }
122
139
  if (parts.length > 0) {
@@ -443,7 +460,7 @@ function buildMetaSeedTool(client, baseUrl) {
443
460
  },
444
461
  crossRefs: {
445
462
  type: 'string',
446
- description: 'JSON array of cross-ref owner paths (e.g. \'["j:/path/a","j:/path/b"]\').',
463
+ description: 'JSON array of cross-ref owner paths (e.g. \'["<drive label>:/path/a","<drive label>:/path/b"]\'). Use server_drives to discover available drive labels.',
447
464
  },
448
465
  steer: {
449
466
  type: 'string',
@@ -217,6 +217,10 @@ Key settings:
217
217
  | `reportChannel` | (optional) | Gateway channel name (e.g. `slack`). Legacy: also used as target if `reportTarget` is unset. |
218
218
  | `reportTarget` | (optional) | Channel/user ID to send progress messages to |
219
219
  | `tier2ScanLimit` | 50 | Max all-fresh candidates to scan per tick in Tier 2 invalidation |
220
+ | `workspaceDir` | OS tmpdir + `/jeeves-meta` | Directory for sub-agent output staging files |
221
+ | `stagingRetries` | 10 | Max retries when staging file not yet visible after session completion (min 0) |
222
+ | `stagingRetryDelayMs` | 250 | Delay between staging file retry attempts in ms (min 0) |
223
+ | `previewDeltaFilesCap` | 50 | Max delta files included in `/preview` response; excess sets `deltaFilesTruncated: true` (min 1) |
220
224
  | `logging.level` | `info` | Log level (trace/debug/info/warn/error) |
221
225
  | `logging.file` | (optional) | Log file path |
222
226
 
@@ -7,6 +7,16 @@
7
7
  * @module promptInjection
8
8
  */
9
9
  import type { MetaServiceClient } from './serviceClient.js';
10
+ /**
11
+ * Format a duration in seconds as a compound human-readable interval.
12
+ *
13
+ * Produces at most two units: `2d 3h`, `1h 35m`, `45m`, etc.
14
+ * Returns `'never synthesized'` for non-finite input.
15
+ *
16
+ * @param seconds - Duration in seconds.
17
+ * @returns Formatted interval string.
18
+ */
19
+ export declare function formatAge(seconds: number): string;
10
20
  /**
11
21
  * Generate the Meta menu Markdown for TOOLS.md.
12
22
  *
@@ -6,8 +6,8 @@
6
6
  *
7
7
  * @module serviceClient
8
8
  */
9
- import { type DepHealth, type GatewayDepHealth, type MetaListSummary, type MetasItem, type MetasResponse, type ServiceState, type WatcherDepHealth } from '@karmaniverous/jeeves-meta-core';
10
- export type { DepHealth, GatewayDepHealth, MetaListSummary, MetasItem, MetasResponse, ServiceState, WatcherDepHealth, };
9
+ import { type DepHealth, type GatewayDepHealth, type MetaListSummary, type MetasItem, type MetasResponse, type NextPhaseCandidate, type PhaseStateSummary, type ServiceState, type WatcherDepHealth } from '@karmaniverous/jeeves-meta-core';
10
+ export type { DepHealth, GatewayDepHealth, MetaListSummary, MetasItem, MetasResponse, NextPhaseCandidate, PhaseStateSummary, ServiceState, WatcherDepHealth, };
11
11
  /**
12
12
  * Service status response from GET /status.
13
13
  *
@@ -31,6 +31,10 @@ export interface StatusResponse {
31
31
  watcher: WatcherDepHealth;
32
32
  gateway: GatewayDepHealth;
33
33
  };
34
+ /** Per-phase counts of each status, from the scheduler. */
35
+ phaseStateSummary?: PhaseStateSummary;
36
+ /** Next phase candidate from the scheduler. */
37
+ nextPhase?: NextPhaseCandidate | null;
34
38
  [key: string]: unknown;
35
39
  };
36
40
  }
@@ -2,7 +2,7 @@
2
2
  "id": "jeeves-meta-openclaw",
3
3
  "name": "Jeeves Meta",
4
4
  "description": "Knowledge synthesis tools — trigger synthesis, view status, manage entities.",
5
- "version": "0.13.1",
5
+ "version": "0.13.2",
6
6
  "skills": [
7
7
  "dist/skills/jeeves-meta"
8
8
  ],
package/package.json CHANGED
@@ -8,7 +8,7 @@
8
8
  },
9
9
  "dependencies": {
10
10
  "@karmaniverous/jeeves": "^0.5.12",
11
- "@karmaniverous/jeeves-meta-core": "^0.2.0"
11
+ "@karmaniverous/jeeves-meta-core": "^0.2.1"
12
12
  },
13
13
  "description": "OpenClaw plugin for jeeves-meta — synthesis tools and virtual rule registration",
14
14
  "devDependencies": {
@@ -112,5 +112,5 @@
112
112
  },
113
113
  "type": "module",
114
114
  "types": "dist/index.d.ts",
115
- "version": "0.13.1"
115
+ "version": "0.13.2"
116
116
  }