@karmaniverous/jeeves-meta 0.16.2 → 0.16.3
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/README.md +1 -1
- package/dist/cli/jeeves-meta/index.js +73 -52
- package/dist/configHotReload.d.ts +1 -1
- package/dist/configLoader.d.ts +2 -3
- package/dist/index.js +73 -52
- package/dist/orchestrator/parseOutput.d.ts +4 -3
- package/dist/progress/index.d.ts +7 -1
- package/dist/prompts/index.d.ts +0 -3
- package/dist/schema/config.d.ts +3 -4
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -19,7 +19,7 @@ HTTP service for the Jeeves knowledge synthesis engine. Provides a Fastify API,
|
|
|
19
19
|
- **Virtual rule registration** — registers 3 watcher inference rules at startup with retry
|
|
20
20
|
- **Progress reporting** — real-time synthesis events via gateway channel messages
|
|
21
21
|
- **Graceful shutdown** — stop scheduler, release locks, close server
|
|
22
|
-
- **Built-in prompts** — default architect and critic prompts ship with the package
|
|
22
|
+
- **Built-in prompts** — default architect and critic prompts ship with the package
|
|
23
23
|
- **Handlebars templates** — prompts compiled with `{ config, meta, scope }` context; architect can write template expressions into builder briefs
|
|
24
24
|
- **Config hot-reload** — all synthesis parameters reload without restart; restart-required fields (port, URLs) warn on change
|
|
25
25
|
- **Auto-seed policy** — config-driven declarative `.meta/` creation via `autoSeed` rules
|
|
@@ -714,8 +714,6 @@ const RESTART_REQUIRED_FIELDS = [
|
|
|
714
714
|
'watcherUrl',
|
|
715
715
|
'gatewayUrl',
|
|
716
716
|
'gatewayApiKey',
|
|
717
|
-
'defaultArchitect',
|
|
718
|
-
'defaultCritic',
|
|
719
717
|
];
|
|
720
718
|
let runtime = null;
|
|
721
719
|
/** Register the active service runtime for config-apply hot reload. */
|
|
@@ -795,6 +793,12 @@ const serviceConfigSchema = metaConfigSchema.extend({
|
|
|
795
793
|
reportTarget: z.string().optional(),
|
|
796
794
|
/** Optional base URL for the service, used to construct entity links in progress reports. */
|
|
797
795
|
serverBaseUrl: z.string().optional(),
|
|
796
|
+
/**
|
|
797
|
+
* Optional mapping of server drive labels to absolute filesystem paths.
|
|
798
|
+
* Used on Linux to resolve absolute paths to jeeves-server browse paths.
|
|
799
|
+
* Example: `{ "content": "/opt/jeeves/content" }`
|
|
800
|
+
*/
|
|
801
|
+
serverDriveRoots: z.record(z.string(), z.string()).optional(),
|
|
798
802
|
/** Interval in ms for periodic watcher health check. 0 = disabled. Default: 60000. */
|
|
799
803
|
watcherHealthIntervalMs: z.number().int().min(0).default(60_000),
|
|
800
804
|
/** Logging configuration. */
|
|
@@ -819,7 +823,7 @@ const serviceConfigSchema = metaConfigSchema.extend({
|
|
|
819
823
|
/**
|
|
820
824
|
* Load and resolve jeeves-meta service config.
|
|
821
825
|
*
|
|
822
|
-
* Supports
|
|
826
|
+
* Supports environment-variable substitution (dollar-brace pattern).
|
|
823
827
|
*
|
|
824
828
|
* @module configLoader
|
|
825
829
|
*/
|
|
@@ -851,24 +855,10 @@ function substituteEnvVars(value) {
|
|
|
851
855
|
}
|
|
852
856
|
return value;
|
|
853
857
|
}
|
|
854
|
-
/**
|
|
855
|
-
* Resolve \@file: references in a config value.
|
|
856
|
-
*
|
|
857
|
-
* @param value - String value that may start with "\@file:".
|
|
858
|
-
* @param baseDir - Base directory for resolving relative paths.
|
|
859
|
-
* @returns The resolved string (file contents or original value).
|
|
860
|
-
*/
|
|
861
|
-
function resolveFileRef(value, baseDir) {
|
|
862
|
-
if (!value.startsWith('@file:'))
|
|
863
|
-
return value;
|
|
864
|
-
const filePath = join(baseDir, value.slice(6));
|
|
865
|
-
return readFileSync(filePath, 'utf8');
|
|
866
|
-
}
|
|
867
858
|
/**
|
|
868
859
|
* Load service config from a JSON file.
|
|
869
860
|
*
|
|
870
|
-
*
|
|
871
|
-
* and substitutes environment-variable placeholders throughout.
|
|
861
|
+
* Substitutes environment-variable placeholders throughout.
|
|
872
862
|
*
|
|
873
863
|
* @param configPath - Path to config JSON file.
|
|
874
864
|
* @returns Validated ServiceConfig.
|
|
@@ -876,13 +866,6 @@ function resolveFileRef(value, baseDir) {
|
|
|
876
866
|
function loadServiceConfig(configPath) {
|
|
877
867
|
const rawText = readFileSync(configPath, 'utf8');
|
|
878
868
|
const raw = substituteEnvVars(JSON.parse(rawText));
|
|
879
|
-
const baseDir = dirname(configPath);
|
|
880
|
-
if (typeof raw['defaultArchitect'] === 'string') {
|
|
881
|
-
raw['defaultArchitect'] = resolveFileRef(raw['defaultArchitect'], baseDir);
|
|
882
|
-
}
|
|
883
|
-
if (typeof raw['defaultCritic'] === 'string') {
|
|
884
|
-
raw['defaultCritic'] = resolveFileRef(raw['defaultCritic'], baseDir);
|
|
885
|
-
}
|
|
886
869
|
return serviceConfigSchema.parse(raw);
|
|
887
870
|
}
|
|
888
871
|
|
|
@@ -1346,9 +1329,6 @@ function packageDirectorySync({cwd, ignoreTypeOnlyPackageJson} = {}) {
|
|
|
1346
1329
|
* Prompts ship as .md files bundled into dist/prompts/ via rollup-plugin-copy.
|
|
1347
1330
|
* Loaded at runtime relative to the compiled module location.
|
|
1348
1331
|
*
|
|
1349
|
-
* Users can override via `defaultArchitect` / `defaultCritic` in the service
|
|
1350
|
-
* config. Most installations should use the built-in defaults.
|
|
1351
|
-
*
|
|
1352
1332
|
* @module prompts
|
|
1353
1333
|
*/
|
|
1354
1334
|
const packageRoot = packageDirectorySync({
|
|
@@ -1836,7 +1816,7 @@ function buildArchitectTask(ctx, meta, config) {
|
|
|
1836
1816
|
const sections = [
|
|
1837
1817
|
`# jeeves-meta · ARCHITECT · ${ctx.path}`,
|
|
1838
1818
|
'',
|
|
1839
|
-
|
|
1819
|
+
DEFAULT_ARCHITECT_PROMPT,
|
|
1840
1820
|
'',
|
|
1841
1821
|
'## SCOPE',
|
|
1842
1822
|
`Path: ${ctx.path}`,
|
|
@@ -1885,7 +1865,7 @@ function buildBuilderTask(ctx, meta, config) {
|
|
|
1885
1865
|
includeSteer: false,
|
|
1886
1866
|
feedbackHeading: '## FEEDBACK FROM CRITIC',
|
|
1887
1867
|
});
|
|
1888
|
-
sections.push('', '## OUTPUT FORMAT', '', 'Respond with ONLY a JSON object. No explanation, no markdown fences, no text before or after.', '', 'Required schema:', '{', ' "type": "object",', ' "required": ["_content"],', ' "properties": {', ' "_content": { "type": "string", "description": "Markdown narrative synthesis" },', ' "_state": { "description": "Opaque state object for progressive work across cycles" }', ' },', ' "additionalProperties": true', '}', '', 'Add any structured fields that capture important facts about this entity', '(e.g. status, risks, dependencies, metrics). Use descriptive key names without underscore prefix.', 'The _content field is the only required key — everything else is domain-driven.', '_state is optional: set it to carry state across synthesis cycles for progressive work.', '', 'DIAGRAMS: When diagrams would aid understanding, use PlantUML in fenced code blocks (```plantuml).', 'PlantUML is rendered natively by the serving infrastructure. NEVER use ASCII art diagrams.');
|
|
1868
|
+
sections.push('', '## OUTPUT FORMAT', '', 'Respond with ONLY a JSON object. No explanation, no markdown fences, no text before or after.', '', 'Required schema:', '{', ' "type": "object",', ' "required": ["_content"],', ' "properties": {', ' "_content": { "type": "string", "description": "Markdown narrative synthesis" },', ' "_state": { "description": "Opaque state object for progressive work across cycles" }', ' },', ' "additionalProperties": true', '}', '', 'Add any structured fields that capture important facts about this entity', '(e.g. status, risks, dependencies, metrics). Use descriptive key names without underscore prefix.', 'The _content field is the only required key — everything else is domain-driven.', '_state is optional: set it to carry state across synthesis cycles for progressive work.', '', 'DIAGRAMS: When diagrams would aid understanding, use PlantUML in fenced code blocks (```plantuml).', 'PlantUML is rendered natively by the serving infrastructure. NEVER use ASCII art diagrams.', '', 'IMPORTANT: Do not call sessions_spawn or sessions_yield. Read all files directly using the tools', 'available in your session. Do not attempt to parallelize work by spawning sub-agents.');
|
|
1889
1869
|
return compileTemplate(sections.join('\n'), buildTemplateContext(ctx, meta, config));
|
|
1890
1870
|
}
|
|
1891
1871
|
/**
|
|
@@ -1900,7 +1880,7 @@ function buildCriticTask(ctx, meta, config) {
|
|
|
1900
1880
|
const sections = [
|
|
1901
1881
|
`# jeeves-meta · CRITIC · ${ctx.path}`,
|
|
1902
1882
|
'',
|
|
1903
|
-
|
|
1883
|
+
DEFAULT_CRITIC_PROMPT,
|
|
1904
1884
|
'',
|
|
1905
1885
|
'## SYNTHESIS TO EVALUATE',
|
|
1906
1886
|
meta._content ?? '(No content produced)',
|
|
@@ -2317,8 +2297,8 @@ async function computeInvalidation(meta, scopeFiles, config, node, crossRefMetas
|
|
|
2317
2297
|
// through real builder cycles, architect runs with the current prompt and
|
|
2318
2298
|
// the snapshot updates. Coupling prompt changes to invalidation causes a
|
|
2319
2299
|
// corpus-wide synthesis storm (see #163).
|
|
2320
|
-
const architectChanged = isPromptStale(meta._architect,
|
|
2321
|
-
const criticChanged = isPromptStale(meta._critic,
|
|
2300
|
+
const architectChanged = isPromptStale(meta._architect, DEFAULT_ARCHITECT_PROMPT);
|
|
2301
|
+
const criticChanged = isPromptStale(meta._critic, DEFAULT_CRITIC_PROMPT);
|
|
2322
2302
|
const effectiveSynthesisCount = meta._synthesisCount ?? 0;
|
|
2323
2303
|
// _crossRefs declaration change
|
|
2324
2304
|
const currentRefs = (meta._crossRefs ?? []).slice().sort().join(',');
|
|
@@ -2565,10 +2545,11 @@ function parseArchitectOutput(output) {
|
|
|
2565
2545
|
/**
|
|
2566
2546
|
* Parse builder output. The builder returns JSON with _content and optional fields.
|
|
2567
2547
|
*
|
|
2568
|
-
* Attempts JSON
|
|
2548
|
+
* Attempts JSON extraction via multiple strategies. Returns null if all strategies fail
|
|
2549
|
+
* (e.g. the output is plain text, self-talk, or a sub-agent delegation response).
|
|
2569
2550
|
*
|
|
2570
2551
|
* @param output - Raw subprocess output.
|
|
2571
|
-
* @returns Parsed builder output
|
|
2552
|
+
* @returns Parsed builder output, or null if output is not valid builder JSON.
|
|
2572
2553
|
*/
|
|
2573
2554
|
function parseBuilderOutput(output) {
|
|
2574
2555
|
const trimmed = stripSentinel(output);
|
|
@@ -2597,8 +2578,8 @@ function parseBuilderOutput(output) {
|
|
|
2597
2578
|
if (result)
|
|
2598
2579
|
return result;
|
|
2599
2580
|
}
|
|
2600
|
-
//
|
|
2601
|
-
return
|
|
2581
|
+
// All JSON strategies failed — not valid builder output
|
|
2582
|
+
return null;
|
|
2602
2583
|
}
|
|
2603
2584
|
/** Try to parse a string as JSON and extract builder output fields. */
|
|
2604
2585
|
function tryParseJson(str) {
|
|
@@ -2726,7 +2707,7 @@ async function runArchitect(node, currentMeta, phaseState, config, executor, wat
|
|
|
2726
2707
|
ps = architectSuccess(ps);
|
|
2727
2708
|
const architectUpdates = {
|
|
2728
2709
|
_builder: builderBrief,
|
|
2729
|
-
_architect:
|
|
2710
|
+
_architect: DEFAULT_ARCHITECT_PROMPT,
|
|
2730
2711
|
_synthesisCount: 0,
|
|
2731
2712
|
_architectTokens: architectTokens,
|
|
2732
2713
|
_generatedAt: new Date().toISOString(),
|
|
@@ -2798,6 +2779,12 @@ async function runBuilder(node, currentMeta, phaseState, config, executor, watch
|
|
|
2798
2779
|
return { executed: true, phaseState: ps, updatedMeta };
|
|
2799
2780
|
}
|
|
2800
2781
|
const builderOutput = parseBuilderOutput(rawOutput);
|
|
2782
|
+
if (!builderOutput) {
|
|
2783
|
+
throw new Error('Builder output is not valid JSON — expected { _content|content: string, ... }. ' +
|
|
2784
|
+
'Raw output (' +
|
|
2785
|
+
rawOutput.length.toString() +
|
|
2786
|
+
' chars) did not match any JSON extraction strategy.');
|
|
2787
|
+
}
|
|
2801
2788
|
const builderTokens = result.tokens;
|
|
2802
2789
|
// Builder success: builder → fresh, critic → pending
|
|
2803
2790
|
ps = builderSuccess(ps);
|
|
@@ -2829,7 +2816,8 @@ async function runBuilder(node, currentMeta, phaseState, config, executor, watch
|
|
|
2829
2816
|
try {
|
|
2830
2817
|
const raw = await readFile(err.outputPath, 'utf8');
|
|
2831
2818
|
const partial = parseBuilderOutput(raw);
|
|
2832
|
-
if (partial
|
|
2819
|
+
if (partial !== null &&
|
|
2820
|
+
partial.state !== undefined &&
|
|
2833
2821
|
JSON.stringify(partial.state) !== JSON.stringify(currentMeta._state)) {
|
|
2834
2822
|
partialState = { _state: partial.state };
|
|
2835
2823
|
}
|
|
@@ -2872,7 +2860,7 @@ async function runCritic(node, currentMeta, phaseState, config, executor, watche
|
|
|
2872
2860
|
const cycleComplete = isFullyFresh(ps);
|
|
2873
2861
|
const updates = {
|
|
2874
2862
|
_feedback: feedback,
|
|
2875
|
-
_critic:
|
|
2863
|
+
_critic: DEFAULT_CRITIC_PROMPT,
|
|
2876
2864
|
_criticTokens: criticTokens,
|
|
2877
2865
|
_error: undefined,
|
|
2878
2866
|
};
|
|
@@ -3094,29 +3082,62 @@ function encodePathSegments(p) {
|
|
|
3094
3082
|
.map((seg) => encodeURIComponent(seg))
|
|
3095
3083
|
.join('/');
|
|
3096
3084
|
}
|
|
3085
|
+
/**
|
|
3086
|
+
* Resolve a filesystem path to a jeeves-server browse path segment.
|
|
3087
|
+
*
|
|
3088
|
+
* - Windows: `j:/domains/foo` → `/j/domains/foo` (drive-letter transform).
|
|
3089
|
+
* - Linux with serverDriveRoots: `/opt/jeeves/content/slack` + roots
|
|
3090
|
+
* `{ content: "/opt/jeeves/content" }` → `/content/slack`.
|
|
3091
|
+
* - Linux without serverDriveRoots: returns the normalized path unchanged
|
|
3092
|
+
* (browse link will be invalid, but this is the pre-existing behavior).
|
|
3093
|
+
*/
|
|
3094
|
+
function resolveServerPath(path, serverDriveRoots) {
|
|
3095
|
+
const normalized = normalizePath(path);
|
|
3096
|
+
// Windows: drive letter present — use existing transform
|
|
3097
|
+
if (/^[A-Za-z]:/.test(normalized)) {
|
|
3098
|
+
return normalized.replace(/^([A-Za-z]):/, '/$1');
|
|
3099
|
+
}
|
|
3100
|
+
// Linux: attempt serverDriveRoots resolution (longest/most-specific root wins)
|
|
3101
|
+
if (serverDriveRoots) {
|
|
3102
|
+
const sorted = Object.entries(serverDriveRoots)
|
|
3103
|
+
.map(([label, root]) => [label, normalizePath(root).replace(/\/+$/, '')])
|
|
3104
|
+
.sort((a, b) => b[1].length - a[1].length);
|
|
3105
|
+
for (const [label, normalizedRoot] of sorted) {
|
|
3106
|
+
if (normalized === normalizedRoot ||
|
|
3107
|
+
normalized.startsWith(normalizedRoot + '/')) {
|
|
3108
|
+
const relative = normalized
|
|
3109
|
+
.slice(normalizedRoot.length)
|
|
3110
|
+
.replace(/^\//, '');
|
|
3111
|
+
return `/${label}${relative ? '/' + relative : ''}`;
|
|
3112
|
+
}
|
|
3113
|
+
}
|
|
3114
|
+
}
|
|
3115
|
+
// Fallback: no drive roots configured or no match — return as-is
|
|
3116
|
+
return normalized;
|
|
3117
|
+
}
|
|
3097
3118
|
/** Build a link (or plain path) to the owner directory. */
|
|
3098
|
-
function buildDirectoryLink(path, serverBaseUrl) {
|
|
3099
|
-
const
|
|
3100
|
-
const encoded = encodePathSegments(
|
|
3119
|
+
function buildDirectoryLink(path, serverBaseUrl, serverDriveRoots) {
|
|
3120
|
+
const resolved = resolveServerPath(path, serverDriveRoots);
|
|
3121
|
+
const encoded = encodePathSegments(resolved);
|
|
3101
3122
|
if (!serverBaseUrl)
|
|
3102
|
-
return
|
|
3123
|
+
return resolved;
|
|
3103
3124
|
const base = serverBaseUrl.replace(/\/+$/, '');
|
|
3104
3125
|
return `${base}/path${encoded}`;
|
|
3105
3126
|
}
|
|
3106
3127
|
/** Build a link (or plain path) to the entity's meta.json output file. */
|
|
3107
|
-
function buildMetaJsonLink(path, serverBaseUrl) {
|
|
3108
|
-
const
|
|
3109
|
-
const metaJsonPath = `${
|
|
3128
|
+
function buildMetaJsonLink(path, serverBaseUrl, serverDriveRoots) {
|
|
3129
|
+
const resolved = resolveServerPath(path, serverDriveRoots);
|
|
3130
|
+
const metaJsonPath = `${resolved}/.meta/meta.json`;
|
|
3110
3131
|
const encoded = encodePathSegments(metaJsonPath);
|
|
3111
3132
|
if (!serverBaseUrl)
|
|
3112
3133
|
return metaJsonPath;
|
|
3113
3134
|
const base = serverBaseUrl.replace(/\/+$/, '');
|
|
3114
3135
|
return `${base}/path${encoded}`;
|
|
3115
3136
|
}
|
|
3116
|
-
function formatProgressEvent(event, serverBaseUrl) {
|
|
3137
|
+
function formatProgressEvent(event, serverBaseUrl, serverDriveRoots) {
|
|
3117
3138
|
switch (event.type) {
|
|
3118
3139
|
case 'synthesis_start': {
|
|
3119
|
-
const dirLink = buildDirectoryLink(event.path, serverBaseUrl);
|
|
3140
|
+
const dirLink = buildDirectoryLink(event.path, serverBaseUrl, serverDriveRoots);
|
|
3120
3141
|
return `🔬 Started meta synthesis: ${dirLink}`;
|
|
3121
3142
|
}
|
|
3122
3143
|
case 'phase_start': {
|
|
@@ -3132,7 +3153,7 @@ function formatProgressEvent(event, serverBaseUrl) {
|
|
|
3132
3153
|
return ` ✅ ${phase} complete (${tokenStr} / ${duration})`;
|
|
3133
3154
|
}
|
|
3134
3155
|
case 'synthesis_complete': {
|
|
3135
|
-
const metaLink = buildMetaJsonLink(event.path, serverBaseUrl);
|
|
3156
|
+
const metaLink = buildMetaJsonLink(event.path, serverBaseUrl, serverDriveRoots);
|
|
3136
3157
|
const tokenStr = formatTokens(event.tokens);
|
|
3137
3158
|
const duration = event.durationMs !== undefined
|
|
3138
3159
|
? formatSeconds(event.durationMs)
|
|
@@ -3140,7 +3161,7 @@ function formatProgressEvent(event, serverBaseUrl) {
|
|
|
3140
3161
|
return `✅ Completed: ${metaLink} (${tokenStr} / ${duration})`;
|
|
3141
3162
|
}
|
|
3142
3163
|
case 'error': {
|
|
3143
|
-
const dirLink = buildDirectoryLink(event.path, serverBaseUrl);
|
|
3164
|
+
const dirLink = buildDirectoryLink(event.path, serverBaseUrl, serverDriveRoots);
|
|
3144
3165
|
const phase = event.phase ? `${titleCasePhase(event.phase)} ` : '';
|
|
3145
3166
|
const error = event.error ?? 'Unknown error';
|
|
3146
3167
|
return `❌ Synthesis failed at ${phase}phase: ${dirLink}\n Error: ${error}`;
|
|
@@ -3163,7 +3184,7 @@ class ProgressReporter {
|
|
|
3163
3184
|
const target = this.config.reportTarget ?? this.config.reportChannel;
|
|
3164
3185
|
if (!target)
|
|
3165
3186
|
return;
|
|
3166
|
-
const message = formatProgressEvent(event, this.config.serverBaseUrl);
|
|
3187
|
+
const message = formatProgressEvent(event, this.config.serverBaseUrl, this.config.serverDriveRoots);
|
|
3167
3188
|
const url = new URL('/tools/invoke', this.config.gatewayUrl);
|
|
3168
3189
|
const args = {
|
|
3169
3190
|
action: 'send',
|
|
@@ -15,7 +15,7 @@ import type { ServiceConfig } from './schema/config.js';
|
|
|
15
15
|
* Shared between the descriptor's `onConfigApply` and the file-watcher
|
|
16
16
|
* hot-reload in `bootstrap.ts`.
|
|
17
17
|
*/
|
|
18
|
-
export declare const RESTART_REQUIRED_FIELDS: readonly ["port", "watcherUrl", "gatewayUrl", "gatewayApiKey"
|
|
18
|
+
export declare const RESTART_REQUIRED_FIELDS: readonly ["port", "watcherUrl", "gatewayUrl", "gatewayApiKey"];
|
|
19
19
|
interface ConfigHotReloadRuntime {
|
|
20
20
|
config: ServiceConfig;
|
|
21
21
|
logger: Logger;
|
package/dist/configLoader.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Load and resolve jeeves-meta service config.
|
|
3
3
|
*
|
|
4
|
-
* Supports
|
|
4
|
+
* Supports environment-variable substitution (dollar-brace pattern).
|
|
5
5
|
*
|
|
6
6
|
* @module configLoader
|
|
7
7
|
*/
|
|
@@ -28,8 +28,7 @@ export declare function resolveConfigPath(args: string[]): string;
|
|
|
28
28
|
/**
|
|
29
29
|
* Load service config from a JSON file.
|
|
30
30
|
*
|
|
31
|
-
*
|
|
32
|
-
* and substitutes environment-variable placeholders throughout.
|
|
31
|
+
* Substitutes environment-variable placeholders throughout.
|
|
33
32
|
*
|
|
34
33
|
* @param configPath - Path to config JSON file.
|
|
35
34
|
* @returns Validated ServiceConfig.
|
package/dist/index.js
CHANGED
|
@@ -1203,8 +1203,6 @@ const RESTART_REQUIRED_FIELDS = [
|
|
|
1203
1203
|
'watcherUrl',
|
|
1204
1204
|
'gatewayUrl',
|
|
1205
1205
|
'gatewayApiKey',
|
|
1206
|
-
'defaultArchitect',
|
|
1207
|
-
'defaultCritic',
|
|
1208
1206
|
];
|
|
1209
1207
|
let runtime = null;
|
|
1210
1208
|
/** Register the active service runtime for config-apply hot reload. */
|
|
@@ -1284,6 +1282,12 @@ const serviceConfigSchema = metaConfigSchema.extend({
|
|
|
1284
1282
|
reportTarget: z.string().optional(),
|
|
1285
1283
|
/** Optional base URL for the service, used to construct entity links in progress reports. */
|
|
1286
1284
|
serverBaseUrl: z.string().optional(),
|
|
1285
|
+
/**
|
|
1286
|
+
* Optional mapping of server drive labels to absolute filesystem paths.
|
|
1287
|
+
* Used on Linux to resolve absolute paths to jeeves-server browse paths.
|
|
1288
|
+
* Example: `{ "content": "/opt/jeeves/content" }`
|
|
1289
|
+
*/
|
|
1290
|
+
serverDriveRoots: z.record(z.string(), z.string()).optional(),
|
|
1287
1291
|
/** Interval in ms for periodic watcher health check. 0 = disabled. Default: 60000. */
|
|
1288
1292
|
watcherHealthIntervalMs: z.number().int().min(0).default(60_000),
|
|
1289
1293
|
/** Logging configuration. */
|
|
@@ -1308,7 +1312,7 @@ const serviceConfigSchema = metaConfigSchema.extend({
|
|
|
1308
1312
|
/**
|
|
1309
1313
|
* Load and resolve jeeves-meta service config.
|
|
1310
1314
|
*
|
|
1311
|
-
* Supports
|
|
1315
|
+
* Supports environment-variable substitution (dollar-brace pattern).
|
|
1312
1316
|
*
|
|
1313
1317
|
* @module configLoader
|
|
1314
1318
|
*/
|
|
@@ -1340,19 +1344,6 @@ function substituteEnvVars(value) {
|
|
|
1340
1344
|
}
|
|
1341
1345
|
return value;
|
|
1342
1346
|
}
|
|
1343
|
-
/**
|
|
1344
|
-
* Resolve \@file: references in a config value.
|
|
1345
|
-
*
|
|
1346
|
-
* @param value - String value that may start with "\@file:".
|
|
1347
|
-
* @param baseDir - Base directory for resolving relative paths.
|
|
1348
|
-
* @returns The resolved string (file contents or original value).
|
|
1349
|
-
*/
|
|
1350
|
-
function resolveFileRef(value, baseDir) {
|
|
1351
|
-
if (!value.startsWith('@file:'))
|
|
1352
|
-
return value;
|
|
1353
|
-
const filePath = join(baseDir, value.slice(6));
|
|
1354
|
-
return readFileSync(filePath, 'utf8');
|
|
1355
|
-
}
|
|
1356
1347
|
/**
|
|
1357
1348
|
* Migrate legacy config path to the new canonical location.
|
|
1358
1349
|
*
|
|
@@ -1401,8 +1392,7 @@ function resolveConfigPath(args) {
|
|
|
1401
1392
|
/**
|
|
1402
1393
|
* Load service config from a JSON file.
|
|
1403
1394
|
*
|
|
1404
|
-
*
|
|
1405
|
-
* and substitutes environment-variable placeholders throughout.
|
|
1395
|
+
* Substitutes environment-variable placeholders throughout.
|
|
1406
1396
|
*
|
|
1407
1397
|
* @param configPath - Path to config JSON file.
|
|
1408
1398
|
* @returns Validated ServiceConfig.
|
|
@@ -1410,13 +1400,6 @@ function resolveConfigPath(args) {
|
|
|
1410
1400
|
function loadServiceConfig(configPath) {
|
|
1411
1401
|
const rawText = readFileSync(configPath, 'utf8');
|
|
1412
1402
|
const raw = substituteEnvVars(JSON.parse(rawText));
|
|
1413
|
-
const baseDir = dirname(configPath);
|
|
1414
|
-
if (typeof raw['defaultArchitect'] === 'string') {
|
|
1415
|
-
raw['defaultArchitect'] = resolveFileRef(raw['defaultArchitect'], baseDir);
|
|
1416
|
-
}
|
|
1417
|
-
if (typeof raw['defaultCritic'] === 'string') {
|
|
1418
|
-
raw['defaultCritic'] = resolveFileRef(raw['defaultCritic'], baseDir);
|
|
1419
|
-
}
|
|
1420
1403
|
return serviceConfigSchema.parse(raw);
|
|
1421
1404
|
}
|
|
1422
1405
|
|
|
@@ -1792,9 +1775,6 @@ function createLogger(config) {
|
|
|
1792
1775
|
* Prompts ship as .md files bundled into dist/prompts/ via rollup-plugin-copy.
|
|
1793
1776
|
* Loaded at runtime relative to the compiled module location.
|
|
1794
1777
|
*
|
|
1795
|
-
* Users can override via `defaultArchitect` / `defaultCritic` in the service
|
|
1796
|
-
* config. Most installations should use the built-in defaults.
|
|
1797
|
-
*
|
|
1798
1778
|
* @module prompts
|
|
1799
1779
|
*/
|
|
1800
1780
|
const packageRoot = packageDirectorySync({
|
|
@@ -2094,7 +2074,7 @@ function buildArchitectTask(ctx, meta, config) {
|
|
|
2094
2074
|
const sections = [
|
|
2095
2075
|
`# jeeves-meta · ARCHITECT · ${ctx.path}`,
|
|
2096
2076
|
'',
|
|
2097
|
-
|
|
2077
|
+
DEFAULT_ARCHITECT_PROMPT,
|
|
2098
2078
|
'',
|
|
2099
2079
|
'## SCOPE',
|
|
2100
2080
|
`Path: ${ctx.path}`,
|
|
@@ -2143,7 +2123,7 @@ function buildBuilderTask(ctx, meta, config) {
|
|
|
2143
2123
|
includeSteer: false,
|
|
2144
2124
|
feedbackHeading: '## FEEDBACK FROM CRITIC',
|
|
2145
2125
|
});
|
|
2146
|
-
sections.push('', '## OUTPUT FORMAT', '', 'Respond with ONLY a JSON object. No explanation, no markdown fences, no text before or after.', '', 'Required schema:', '{', ' "type": "object",', ' "required": ["_content"],', ' "properties": {', ' "_content": { "type": "string", "description": "Markdown narrative synthesis" },', ' "_state": { "description": "Opaque state object for progressive work across cycles" }', ' },', ' "additionalProperties": true', '}', '', 'Add any structured fields that capture important facts about this entity', '(e.g. status, risks, dependencies, metrics). Use descriptive key names without underscore prefix.', 'The _content field is the only required key — everything else is domain-driven.', '_state is optional: set it to carry state across synthesis cycles for progressive work.', '', 'DIAGRAMS: When diagrams would aid understanding, use PlantUML in fenced code blocks (```plantuml).', 'PlantUML is rendered natively by the serving infrastructure. NEVER use ASCII art diagrams.');
|
|
2126
|
+
sections.push('', '## OUTPUT FORMAT', '', 'Respond with ONLY a JSON object. No explanation, no markdown fences, no text before or after.', '', 'Required schema:', '{', ' "type": "object",', ' "required": ["_content"],', ' "properties": {', ' "_content": { "type": "string", "description": "Markdown narrative synthesis" },', ' "_state": { "description": "Opaque state object for progressive work across cycles" }', ' },', ' "additionalProperties": true', '}', '', 'Add any structured fields that capture important facts about this entity', '(e.g. status, risks, dependencies, metrics). Use descriptive key names without underscore prefix.', 'The _content field is the only required key — everything else is domain-driven.', '_state is optional: set it to carry state across synthesis cycles for progressive work.', '', 'DIAGRAMS: When diagrams would aid understanding, use PlantUML in fenced code blocks (```plantuml).', 'PlantUML is rendered natively by the serving infrastructure. NEVER use ASCII art diagrams.', '', 'IMPORTANT: Do not call sessions_spawn or sessions_yield. Read all files directly using the tools', 'available in your session. Do not attempt to parallelize work by spawning sub-agents.');
|
|
2147
2127
|
return compileTemplate(sections.join('\n'), buildTemplateContext(ctx, meta, config));
|
|
2148
2128
|
}
|
|
2149
2129
|
/**
|
|
@@ -2158,7 +2138,7 @@ function buildCriticTask(ctx, meta, config) {
|
|
|
2158
2138
|
const sections = [
|
|
2159
2139
|
`# jeeves-meta · CRITIC · ${ctx.path}`,
|
|
2160
2140
|
'',
|
|
2161
|
-
|
|
2141
|
+
DEFAULT_CRITIC_PROMPT,
|
|
2162
2142
|
'',
|
|
2163
2143
|
'## SYNTHESIS TO EVALUATE',
|
|
2164
2144
|
meta._content ?? '(No content produced)',
|
|
@@ -2575,8 +2555,8 @@ async function computeInvalidation(meta, scopeFiles, config, node, crossRefMetas
|
|
|
2575
2555
|
// through real builder cycles, architect runs with the current prompt and
|
|
2576
2556
|
// the snapshot updates. Coupling prompt changes to invalidation causes a
|
|
2577
2557
|
// corpus-wide synthesis storm (see #163).
|
|
2578
|
-
const architectChanged = isPromptStale(meta._architect,
|
|
2579
|
-
const criticChanged = isPromptStale(meta._critic,
|
|
2558
|
+
const architectChanged = isPromptStale(meta._architect, DEFAULT_ARCHITECT_PROMPT);
|
|
2559
|
+
const criticChanged = isPromptStale(meta._critic, DEFAULT_CRITIC_PROMPT);
|
|
2580
2560
|
const effectiveSynthesisCount = meta._synthesisCount ?? 0;
|
|
2581
2561
|
// _crossRefs declaration change
|
|
2582
2562
|
const currentRefs = (meta._crossRefs ?? []).slice().sort().join(',');
|
|
@@ -2823,10 +2803,11 @@ function parseArchitectOutput(output) {
|
|
|
2823
2803
|
/**
|
|
2824
2804
|
* Parse builder output. The builder returns JSON with _content and optional fields.
|
|
2825
2805
|
*
|
|
2826
|
-
* Attempts JSON
|
|
2806
|
+
* Attempts JSON extraction via multiple strategies. Returns null if all strategies fail
|
|
2807
|
+
* (e.g. the output is plain text, self-talk, or a sub-agent delegation response).
|
|
2827
2808
|
*
|
|
2828
2809
|
* @param output - Raw subprocess output.
|
|
2829
|
-
* @returns Parsed builder output
|
|
2810
|
+
* @returns Parsed builder output, or null if output is not valid builder JSON.
|
|
2830
2811
|
*/
|
|
2831
2812
|
function parseBuilderOutput(output) {
|
|
2832
2813
|
const trimmed = stripSentinel(output);
|
|
@@ -2855,8 +2836,8 @@ function parseBuilderOutput(output) {
|
|
|
2855
2836
|
if (result)
|
|
2856
2837
|
return result;
|
|
2857
2838
|
}
|
|
2858
|
-
//
|
|
2859
|
-
return
|
|
2839
|
+
// All JSON strategies failed — not valid builder output
|
|
2840
|
+
return null;
|
|
2860
2841
|
}
|
|
2861
2842
|
/** Try to parse a string as JSON and extract builder output fields. */
|
|
2862
2843
|
function tryParseJson(str) {
|
|
@@ -2984,7 +2965,7 @@ async function runArchitect(node, currentMeta, phaseState, config, executor, wat
|
|
|
2984
2965
|
ps = architectSuccess(ps);
|
|
2985
2966
|
const architectUpdates = {
|
|
2986
2967
|
_builder: builderBrief,
|
|
2987
|
-
_architect:
|
|
2968
|
+
_architect: DEFAULT_ARCHITECT_PROMPT,
|
|
2988
2969
|
_synthesisCount: 0,
|
|
2989
2970
|
_architectTokens: architectTokens,
|
|
2990
2971
|
_generatedAt: new Date().toISOString(),
|
|
@@ -3056,6 +3037,12 @@ async function runBuilder(node, currentMeta, phaseState, config, executor, watch
|
|
|
3056
3037
|
return { executed: true, phaseState: ps, updatedMeta };
|
|
3057
3038
|
}
|
|
3058
3039
|
const builderOutput = parseBuilderOutput(rawOutput);
|
|
3040
|
+
if (!builderOutput) {
|
|
3041
|
+
throw new Error('Builder output is not valid JSON — expected { _content|content: string, ... }. ' +
|
|
3042
|
+
'Raw output (' +
|
|
3043
|
+
rawOutput.length.toString() +
|
|
3044
|
+
' chars) did not match any JSON extraction strategy.');
|
|
3045
|
+
}
|
|
3059
3046
|
const builderTokens = result.tokens;
|
|
3060
3047
|
// Builder success: builder → fresh, critic → pending
|
|
3061
3048
|
ps = builderSuccess(ps);
|
|
@@ -3087,7 +3074,8 @@ async function runBuilder(node, currentMeta, phaseState, config, executor, watch
|
|
|
3087
3074
|
try {
|
|
3088
3075
|
const raw = await readFile(err.outputPath, 'utf8');
|
|
3089
3076
|
const partial = parseBuilderOutput(raw);
|
|
3090
|
-
if (partial
|
|
3077
|
+
if (partial !== null &&
|
|
3078
|
+
partial.state !== undefined &&
|
|
3091
3079
|
JSON.stringify(partial.state) !== JSON.stringify(currentMeta._state)) {
|
|
3092
3080
|
partialState = { _state: partial.state };
|
|
3093
3081
|
}
|
|
@@ -3130,7 +3118,7 @@ async function runCritic(node, currentMeta, phaseState, config, executor, watche
|
|
|
3130
3118
|
const cycleComplete = isFullyFresh(ps);
|
|
3131
3119
|
const updates = {
|
|
3132
3120
|
_feedback: feedback,
|
|
3133
|
-
_critic:
|
|
3121
|
+
_critic: DEFAULT_CRITIC_PROMPT,
|
|
3134
3122
|
_criticTokens: criticTokens,
|
|
3135
3123
|
_error: undefined,
|
|
3136
3124
|
};
|
|
@@ -3352,29 +3340,62 @@ function encodePathSegments(p) {
|
|
|
3352
3340
|
.map((seg) => encodeURIComponent(seg))
|
|
3353
3341
|
.join('/');
|
|
3354
3342
|
}
|
|
3343
|
+
/**
|
|
3344
|
+
* Resolve a filesystem path to a jeeves-server browse path segment.
|
|
3345
|
+
*
|
|
3346
|
+
* - Windows: `j:/domains/foo` → `/j/domains/foo` (drive-letter transform).
|
|
3347
|
+
* - Linux with serverDriveRoots: `/opt/jeeves/content/slack` + roots
|
|
3348
|
+
* `{ content: "/opt/jeeves/content" }` → `/content/slack`.
|
|
3349
|
+
* - Linux without serverDriveRoots: returns the normalized path unchanged
|
|
3350
|
+
* (browse link will be invalid, but this is the pre-existing behavior).
|
|
3351
|
+
*/
|
|
3352
|
+
function resolveServerPath(path, serverDriveRoots) {
|
|
3353
|
+
const normalized = normalizePath(path);
|
|
3354
|
+
// Windows: drive letter present — use existing transform
|
|
3355
|
+
if (/^[A-Za-z]:/.test(normalized)) {
|
|
3356
|
+
return normalized.replace(/^([A-Za-z]):/, '/$1');
|
|
3357
|
+
}
|
|
3358
|
+
// Linux: attempt serverDriveRoots resolution (longest/most-specific root wins)
|
|
3359
|
+
if (serverDriveRoots) {
|
|
3360
|
+
const sorted = Object.entries(serverDriveRoots)
|
|
3361
|
+
.map(([label, root]) => [label, normalizePath(root).replace(/\/+$/, '')])
|
|
3362
|
+
.sort((a, b) => b[1].length - a[1].length);
|
|
3363
|
+
for (const [label, normalizedRoot] of sorted) {
|
|
3364
|
+
if (normalized === normalizedRoot ||
|
|
3365
|
+
normalized.startsWith(normalizedRoot + '/')) {
|
|
3366
|
+
const relative = normalized
|
|
3367
|
+
.slice(normalizedRoot.length)
|
|
3368
|
+
.replace(/^\//, '');
|
|
3369
|
+
return `/${label}${relative ? '/' + relative : ''}`;
|
|
3370
|
+
}
|
|
3371
|
+
}
|
|
3372
|
+
}
|
|
3373
|
+
// Fallback: no drive roots configured or no match — return as-is
|
|
3374
|
+
return normalized;
|
|
3375
|
+
}
|
|
3355
3376
|
/** Build a link (or plain path) to the owner directory. */
|
|
3356
|
-
function buildDirectoryLink(path, serverBaseUrl) {
|
|
3357
|
-
const
|
|
3358
|
-
const encoded = encodePathSegments(
|
|
3377
|
+
function buildDirectoryLink(path, serverBaseUrl, serverDriveRoots) {
|
|
3378
|
+
const resolved = resolveServerPath(path, serverDriveRoots);
|
|
3379
|
+
const encoded = encodePathSegments(resolved);
|
|
3359
3380
|
if (!serverBaseUrl)
|
|
3360
|
-
return
|
|
3381
|
+
return resolved;
|
|
3361
3382
|
const base = serverBaseUrl.replace(/\/+$/, '');
|
|
3362
3383
|
return `${base}/path${encoded}`;
|
|
3363
3384
|
}
|
|
3364
3385
|
/** Build a link (or plain path) to the entity's meta.json output file. */
|
|
3365
|
-
function buildMetaJsonLink(path, serverBaseUrl) {
|
|
3366
|
-
const
|
|
3367
|
-
const metaJsonPath = `${
|
|
3386
|
+
function buildMetaJsonLink(path, serverBaseUrl, serverDriveRoots) {
|
|
3387
|
+
const resolved = resolveServerPath(path, serverDriveRoots);
|
|
3388
|
+
const metaJsonPath = `${resolved}/.meta/meta.json`;
|
|
3368
3389
|
const encoded = encodePathSegments(metaJsonPath);
|
|
3369
3390
|
if (!serverBaseUrl)
|
|
3370
3391
|
return metaJsonPath;
|
|
3371
3392
|
const base = serverBaseUrl.replace(/\/+$/, '');
|
|
3372
3393
|
return `${base}/path${encoded}`;
|
|
3373
3394
|
}
|
|
3374
|
-
function formatProgressEvent(event, serverBaseUrl) {
|
|
3395
|
+
function formatProgressEvent(event, serverBaseUrl, serverDriveRoots) {
|
|
3375
3396
|
switch (event.type) {
|
|
3376
3397
|
case 'synthesis_start': {
|
|
3377
|
-
const dirLink = buildDirectoryLink(event.path, serverBaseUrl);
|
|
3398
|
+
const dirLink = buildDirectoryLink(event.path, serverBaseUrl, serverDriveRoots);
|
|
3378
3399
|
return `🔬 Started meta synthesis: ${dirLink}`;
|
|
3379
3400
|
}
|
|
3380
3401
|
case 'phase_start': {
|
|
@@ -3390,7 +3411,7 @@ function formatProgressEvent(event, serverBaseUrl) {
|
|
|
3390
3411
|
return ` ✅ ${phase} complete (${tokenStr} / ${duration})`;
|
|
3391
3412
|
}
|
|
3392
3413
|
case 'synthesis_complete': {
|
|
3393
|
-
const metaLink = buildMetaJsonLink(event.path, serverBaseUrl);
|
|
3414
|
+
const metaLink = buildMetaJsonLink(event.path, serverBaseUrl, serverDriveRoots);
|
|
3394
3415
|
const tokenStr = formatTokens(event.tokens);
|
|
3395
3416
|
const duration = event.durationMs !== undefined
|
|
3396
3417
|
? formatSeconds(event.durationMs)
|
|
@@ -3398,7 +3419,7 @@ function formatProgressEvent(event, serverBaseUrl) {
|
|
|
3398
3419
|
return `✅ Completed: ${metaLink} (${tokenStr} / ${duration})`;
|
|
3399
3420
|
}
|
|
3400
3421
|
case 'error': {
|
|
3401
|
-
const dirLink = buildDirectoryLink(event.path, serverBaseUrl);
|
|
3422
|
+
const dirLink = buildDirectoryLink(event.path, serverBaseUrl, serverDriveRoots);
|
|
3402
3423
|
const phase = event.phase ? `${titleCasePhase(event.phase)} ` : '';
|
|
3403
3424
|
const error = event.error ?? 'Unknown error';
|
|
3404
3425
|
return `❌ Synthesis failed at ${phase}phase: ${dirLink}\n Error: ${error}`;
|
|
@@ -3421,7 +3442,7 @@ class ProgressReporter {
|
|
|
3421
3442
|
const target = this.config.reportTarget ?? this.config.reportChannel;
|
|
3422
3443
|
if (!target)
|
|
3423
3444
|
return;
|
|
3424
|
-
const message = formatProgressEvent(event, this.config.serverBaseUrl);
|
|
3445
|
+
const message = formatProgressEvent(event, this.config.serverBaseUrl, this.config.serverDriveRoots);
|
|
3425
3446
|
const url = new URL('/tools/invoke', this.config.gatewayUrl);
|
|
3426
3447
|
const args = {
|
|
3427
3448
|
action: 'send',
|
|
@@ -26,12 +26,13 @@ export declare function parseArchitectOutput(output: string): string;
|
|
|
26
26
|
/**
|
|
27
27
|
* Parse builder output. The builder returns JSON with _content and optional fields.
|
|
28
28
|
*
|
|
29
|
-
* Attempts JSON
|
|
29
|
+
* Attempts JSON extraction via multiple strategies. Returns null if all strategies fail
|
|
30
|
+
* (e.g. the output is plain text, self-talk, or a sub-agent delegation response).
|
|
30
31
|
*
|
|
31
32
|
* @param output - Raw subprocess output.
|
|
32
|
-
* @returns Parsed builder output
|
|
33
|
+
* @returns Parsed builder output, or null if output is not valid builder JSON.
|
|
33
34
|
*/
|
|
34
|
-
export declare function parseBuilderOutput(output: string): BuilderOutput;
|
|
35
|
+
export declare function parseBuilderOutput(output: string): BuilderOutput | null;
|
|
35
36
|
/**
|
|
36
37
|
* Parse critic output. The critic returns evaluation text.
|
|
37
38
|
*
|
package/dist/progress/index.d.ts
CHANGED
|
@@ -28,8 +28,14 @@ export type ProgressReporterConfig = {
|
|
|
28
28
|
reportTarget?: string;
|
|
29
29
|
/** Optional base URL for the service, used to construct entity links. */
|
|
30
30
|
serverBaseUrl?: string;
|
|
31
|
+
/**
|
|
32
|
+
* Optional mapping of server drive labels to absolute filesystem paths.
|
|
33
|
+
* Used on Linux to resolve absolute paths to jeeves-server browse paths.
|
|
34
|
+
* Example: `{ "content": "/opt/jeeves/content" }`
|
|
35
|
+
*/
|
|
36
|
+
serverDriveRoots?: Record<string, string>;
|
|
31
37
|
};
|
|
32
|
-
export declare function formatProgressEvent(event: ProgressEvent, serverBaseUrl?: string): string;
|
|
38
|
+
export declare function formatProgressEvent(event: ProgressEvent, serverBaseUrl?: string, serverDriveRoots?: Record<string, string>): string;
|
|
33
39
|
export declare class ProgressReporter {
|
|
34
40
|
private readonly config;
|
|
35
41
|
private readonly logger;
|
package/dist/prompts/index.d.ts
CHANGED
|
@@ -4,9 +4,6 @@
|
|
|
4
4
|
* Prompts ship as .md files bundled into dist/prompts/ via rollup-plugin-copy.
|
|
5
5
|
* Loaded at runtime relative to the compiled module location.
|
|
6
6
|
*
|
|
7
|
-
* Users can override via `defaultArchitect` / `defaultCritic` in the service
|
|
8
|
-
* config. Most installations should use the built-in defaults.
|
|
9
|
-
*
|
|
10
7
|
* @module prompts
|
|
11
8
|
*/
|
|
12
9
|
/** Built-in default architect prompt. */
|
package/dist/schema/config.d.ts
CHANGED
|
@@ -27,16 +27,15 @@ export declare const serviceConfigSchema: z.ZodObject<{
|
|
|
27
27
|
maxArchive: z.ZodDefault<z.ZodNumber>;
|
|
28
28
|
maxLines: z.ZodDefault<z.ZodNumber>;
|
|
29
29
|
thinking: z.ZodDefault<z.ZodString>;
|
|
30
|
-
defaultArchitect: z.ZodOptional<z.ZodString>;
|
|
31
|
-
defaultCritic: z.ZodOptional<z.ZodString>;
|
|
32
30
|
skipUnchanged: z.ZodDefault<z.ZodBoolean>;
|
|
33
|
-
metaProperty: z.
|
|
34
|
-
metaArchiveProperty: z.
|
|
31
|
+
metaProperty: z.ZodRecord<z.ZodString, z.ZodUnknown>;
|
|
32
|
+
metaArchiveProperty: z.ZodRecord<z.ZodString, z.ZodUnknown>;
|
|
35
33
|
port: z.ZodDefault<z.ZodNumber>;
|
|
36
34
|
schedule: z.ZodDefault<z.ZodString>;
|
|
37
35
|
reportChannel: z.ZodOptional<z.ZodString>;
|
|
38
36
|
reportTarget: z.ZodOptional<z.ZodString>;
|
|
39
37
|
serverBaseUrl: z.ZodOptional<z.ZodString>;
|
|
38
|
+
serverDriveRoots: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
40
39
|
watcherHealthIntervalMs: z.ZodDefault<z.ZodNumber>;
|
|
41
40
|
logging: z.ZodDefault<z.ZodObject<{
|
|
42
41
|
level: z.ZodDefault<z.ZodString>;
|
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.
|
|
11
|
+
"@karmaniverous/jeeves-meta-core": "^0.2.2",
|
|
12
12
|
"commander": "^14",
|
|
13
13
|
"croner": "^10",
|
|
14
14
|
"fastify": "^5.8",
|
|
@@ -110,5 +110,5 @@
|
|
|
110
110
|
},
|
|
111
111
|
"type": "module",
|
|
112
112
|
"types": "dist/index.d.ts",
|
|
113
|
-
"version": "0.16.
|
|
113
|
+
"version": "0.16.3"
|
|
114
114
|
}
|