@karmaniverous/jeeves-meta 0.10.1 → 0.11.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/dist/cli/jeeves-meta/index.js +46 -12
- package/dist/index.js +46 -12
- package/package.json +1 -1
|
@@ -46,11 +46,11 @@ const metaConfigSchema = z.object({
|
|
|
46
46
|
/** Maximum lines of context to include in subprocess prompts. */
|
|
47
47
|
maxLines: z.number().int().min(50).default(500),
|
|
48
48
|
/** Architect subprocess timeout in seconds. */
|
|
49
|
-
architectTimeout: z.number().int().min(30).default(
|
|
49
|
+
architectTimeout: z.number().int().min(30).default(180),
|
|
50
50
|
/** Builder subprocess timeout in seconds. */
|
|
51
|
-
builderTimeout: z.number().int().min(60).default(
|
|
51
|
+
builderTimeout: z.number().int().min(60).default(360),
|
|
52
52
|
/** Critic subprocess timeout in seconds. */
|
|
53
|
-
criticTimeout: z.number().int().min(30).default(
|
|
53
|
+
criticTimeout: z.number().int().min(30).default(240),
|
|
54
54
|
/** Thinking level for spawned synthesis sessions. */
|
|
55
55
|
thinking: z.string().default('low'),
|
|
56
56
|
/** Resolved architect system prompt text. Falls back to built-in default. */
|
|
@@ -2151,6 +2151,17 @@ async function synthesizeNode(node, currentMeta, config, executor, watcher, onPr
|
|
|
2151
2151
|
const steerChanged = hasSteerChanged(currentMeta._steer, latestArchive?._steer, Boolean(latestArchive));
|
|
2152
2152
|
// Step 7: Compute context (includes scope files and delta files)
|
|
2153
2153
|
const ctx = await buildContextPackage(node, currentMeta, watcher, logger);
|
|
2154
|
+
// Skip empty-scope entities that have no prior content.
|
|
2155
|
+
// Without scope files, child metas, or cross-refs there is nothing for
|
|
2156
|
+
// the architect/builder to work with and the cycle will either time out
|
|
2157
|
+
// or produce empty output.
|
|
2158
|
+
const hasScope = ctx.scopeFiles.length > 0 ||
|
|
2159
|
+
Object.keys(ctx.childMetas).length > 0 ||
|
|
2160
|
+
Object.keys(ctx.crossRefMetas).length > 0;
|
|
2161
|
+
if (!hasScope && !currentMeta._content) {
|
|
2162
|
+
logger?.debug({ path: node.ownerPath }, 'Skipping empty-scope entity');
|
|
2163
|
+
return { synthesized: false };
|
|
2164
|
+
}
|
|
2154
2165
|
// Step 5 (deferred): Structure hash from context scope files
|
|
2155
2166
|
const newStructureHash = computeStructureHash(ctx.scopeFiles);
|
|
2156
2167
|
const structureChanged = newStructureHash !== currentMeta._structureHash;
|
|
@@ -2447,21 +2458,41 @@ function formatSeconds(durationMs) {
|
|
|
2447
2458
|
function titleCasePhase(phase) {
|
|
2448
2459
|
return phase.charAt(0).toUpperCase() + phase.slice(1);
|
|
2449
2460
|
}
|
|
2450
|
-
/**
|
|
2451
|
-
|
|
2452
|
-
|
|
2461
|
+
/**
|
|
2462
|
+
* URL-encode each path segment individually so that spaces and special
|
|
2463
|
+
* characters are safe while preserving the `/` separators.
|
|
2464
|
+
*/
|
|
2465
|
+
function encodePathSegments(p) {
|
|
2466
|
+
return p
|
|
2467
|
+
.split('/')
|
|
2468
|
+
.map((seg) => encodeURIComponent(seg))
|
|
2469
|
+
.join('/');
|
|
2470
|
+
}
|
|
2471
|
+
/** Build a link (or plain path) to the owner directory. */
|
|
2472
|
+
function buildDirectoryLink(path, serverBaseUrl) {
|
|
2473
|
+
const normalized = normalizePath(path).replace(/^([A-Za-z]):/, '/$1');
|
|
2474
|
+
const encoded = encodePathSegments(normalized);
|
|
2475
|
+
if (!serverBaseUrl)
|
|
2476
|
+
return normalized;
|
|
2477
|
+
const base = serverBaseUrl.replace(/\/+$/, '');
|
|
2478
|
+
return `${base}/path${encoded}`;
|
|
2479
|
+
}
|
|
2480
|
+
/** Build a link (or plain path) to the entity's meta.json output file. */
|
|
2481
|
+
function buildMetaJsonLink(path, serverBaseUrl) {
|
|
2453
2482
|
const normalized = normalizePath(path).replace(/^([A-Za-z]):/, '/$1');
|
|
2454
2483
|
const metaJsonPath = `${normalized}/.meta/meta.json`;
|
|
2484
|
+
const encoded = encodePathSegments(metaJsonPath);
|
|
2455
2485
|
if (!serverBaseUrl)
|
|
2456
2486
|
return metaJsonPath;
|
|
2457
2487
|
const base = serverBaseUrl.replace(/\/+$/, '');
|
|
2458
|
-
return `${base}/path${
|
|
2488
|
+
return `${base}/path${encoded}`;
|
|
2459
2489
|
}
|
|
2460
2490
|
function formatProgressEvent(event, serverBaseUrl) {
|
|
2461
|
-
const pathDisplay = buildEntityLink(event.path, serverBaseUrl);
|
|
2462
2491
|
switch (event.type) {
|
|
2463
|
-
case 'synthesis_start':
|
|
2464
|
-
|
|
2492
|
+
case 'synthesis_start': {
|
|
2493
|
+
const dirLink = buildDirectoryLink(event.path, serverBaseUrl);
|
|
2494
|
+
return `🔬 Started meta synthesis: ${dirLink}`;
|
|
2495
|
+
}
|
|
2465
2496
|
case 'phase_start': {
|
|
2466
2497
|
if (!event.phase) {
|
|
2467
2498
|
return ' ⚙️ Phase started';
|
|
@@ -2475,16 +2506,18 @@ function formatProgressEvent(event, serverBaseUrl) {
|
|
|
2475
2506
|
return ` ✅ ${phase} complete (${formatNumber(tokens)} tokens / ${duration})`;
|
|
2476
2507
|
}
|
|
2477
2508
|
case 'synthesis_complete': {
|
|
2509
|
+
const metaLink = buildMetaJsonLink(event.path, serverBaseUrl);
|
|
2478
2510
|
const tokens = event.tokens ?? 0;
|
|
2479
2511
|
const duration = event.durationMs !== undefined
|
|
2480
2512
|
? formatSeconds(event.durationMs)
|
|
2481
2513
|
: '0.0s';
|
|
2482
|
-
return `✅ Completed: ${
|
|
2514
|
+
return `✅ Completed: ${metaLink} (${formatNumber(tokens)} tokens / ${duration})`;
|
|
2483
2515
|
}
|
|
2484
2516
|
case 'error': {
|
|
2517
|
+
const dirLink = buildDirectoryLink(event.path, serverBaseUrl);
|
|
2485
2518
|
const phase = event.phase ? `${titleCasePhase(event.phase)} ` : '';
|
|
2486
2519
|
const error = event.error ?? 'Unknown error';
|
|
2487
|
-
return `❌ Synthesis failed at ${phase}phase: ${
|
|
2520
|
+
return `❌ Synthesis failed at ${phase}phase: ${dirLink}\n Error: ${error}`;
|
|
2488
2521
|
}
|
|
2489
2522
|
default: {
|
|
2490
2523
|
return 'Unknown progress event';
|
|
@@ -11087,6 +11120,7 @@ async function startService(config, configPath) {
|
|
|
11087
11120
|
await progress.report({
|
|
11088
11121
|
type: 'error',
|
|
11089
11122
|
path: ownerPath,
|
|
11123
|
+
phase: result.error.step,
|
|
11090
11124
|
error: result.error.message,
|
|
11091
11125
|
});
|
|
11092
11126
|
}
|
package/dist/index.js
CHANGED
|
@@ -254,11 +254,11 @@ const metaConfigSchema = z.object({
|
|
|
254
254
|
/** Maximum lines of context to include in subprocess prompts. */
|
|
255
255
|
maxLines: z.number().int().min(50).default(500),
|
|
256
256
|
/** Architect subprocess timeout in seconds. */
|
|
257
|
-
architectTimeout: z.number().int().min(30).default(
|
|
257
|
+
architectTimeout: z.number().int().min(30).default(180),
|
|
258
258
|
/** Builder subprocess timeout in seconds. */
|
|
259
|
-
builderTimeout: z.number().int().min(60).default(
|
|
259
|
+
builderTimeout: z.number().int().min(60).default(360),
|
|
260
260
|
/** Critic subprocess timeout in seconds. */
|
|
261
|
-
criticTimeout: z.number().int().min(30).default(
|
|
261
|
+
criticTimeout: z.number().int().min(30).default(240),
|
|
262
262
|
/** Thinking level for spawned synthesis sessions. */
|
|
263
263
|
thinking: z.string().default('low'),
|
|
264
264
|
/** Resolved architect system prompt text. Falls back to built-in default. */
|
|
@@ -2143,6 +2143,17 @@ async function synthesizeNode(node, currentMeta, config, executor, watcher, onPr
|
|
|
2143
2143
|
const steerChanged = hasSteerChanged(currentMeta._steer, latestArchive?._steer, Boolean(latestArchive));
|
|
2144
2144
|
// Step 7: Compute context (includes scope files and delta files)
|
|
2145
2145
|
const ctx = await buildContextPackage(node, currentMeta, watcher, logger);
|
|
2146
|
+
// Skip empty-scope entities that have no prior content.
|
|
2147
|
+
// Without scope files, child metas, or cross-refs there is nothing for
|
|
2148
|
+
// the architect/builder to work with and the cycle will either time out
|
|
2149
|
+
// or produce empty output.
|
|
2150
|
+
const hasScope = ctx.scopeFiles.length > 0 ||
|
|
2151
|
+
Object.keys(ctx.childMetas).length > 0 ||
|
|
2152
|
+
Object.keys(ctx.crossRefMetas).length > 0;
|
|
2153
|
+
if (!hasScope && !currentMeta._content) {
|
|
2154
|
+
logger?.debug({ path: node.ownerPath }, 'Skipping empty-scope entity');
|
|
2155
|
+
return { synthesized: false };
|
|
2156
|
+
}
|
|
2146
2157
|
// Step 5 (deferred): Structure hash from context scope files
|
|
2147
2158
|
const newStructureHash = computeStructureHash(ctx.scopeFiles);
|
|
2148
2159
|
const structureChanged = newStructureHash !== currentMeta._structureHash;
|
|
@@ -2439,21 +2450,41 @@ function formatSeconds(durationMs) {
|
|
|
2439
2450
|
function titleCasePhase(phase) {
|
|
2440
2451
|
return phase.charAt(0).toUpperCase() + phase.slice(1);
|
|
2441
2452
|
}
|
|
2442
|
-
/**
|
|
2443
|
-
|
|
2444
|
-
|
|
2453
|
+
/**
|
|
2454
|
+
* URL-encode each path segment individually so that spaces and special
|
|
2455
|
+
* characters are safe while preserving the `/` separators.
|
|
2456
|
+
*/
|
|
2457
|
+
function encodePathSegments(p) {
|
|
2458
|
+
return p
|
|
2459
|
+
.split('/')
|
|
2460
|
+
.map((seg) => encodeURIComponent(seg))
|
|
2461
|
+
.join('/');
|
|
2462
|
+
}
|
|
2463
|
+
/** Build a link (or plain path) to the owner directory. */
|
|
2464
|
+
function buildDirectoryLink(path, serverBaseUrl) {
|
|
2465
|
+
const normalized = normalizePath(path).replace(/^([A-Za-z]):/, '/$1');
|
|
2466
|
+
const encoded = encodePathSegments(normalized);
|
|
2467
|
+
if (!serverBaseUrl)
|
|
2468
|
+
return normalized;
|
|
2469
|
+
const base = serverBaseUrl.replace(/\/+$/, '');
|
|
2470
|
+
return `${base}/path${encoded}`;
|
|
2471
|
+
}
|
|
2472
|
+
/** Build a link (or plain path) to the entity's meta.json output file. */
|
|
2473
|
+
function buildMetaJsonLink(path, serverBaseUrl) {
|
|
2445
2474
|
const normalized = normalizePath(path).replace(/^([A-Za-z]):/, '/$1');
|
|
2446
2475
|
const metaJsonPath = `${normalized}/.meta/meta.json`;
|
|
2476
|
+
const encoded = encodePathSegments(metaJsonPath);
|
|
2447
2477
|
if (!serverBaseUrl)
|
|
2448
2478
|
return metaJsonPath;
|
|
2449
2479
|
const base = serverBaseUrl.replace(/\/+$/, '');
|
|
2450
|
-
return `${base}/path${
|
|
2480
|
+
return `${base}/path${encoded}`;
|
|
2451
2481
|
}
|
|
2452
2482
|
function formatProgressEvent(event, serverBaseUrl) {
|
|
2453
|
-
const pathDisplay = buildEntityLink(event.path, serverBaseUrl);
|
|
2454
2483
|
switch (event.type) {
|
|
2455
|
-
case 'synthesis_start':
|
|
2456
|
-
|
|
2484
|
+
case 'synthesis_start': {
|
|
2485
|
+
const dirLink = buildDirectoryLink(event.path, serverBaseUrl);
|
|
2486
|
+
return `🔬 Started meta synthesis: ${dirLink}`;
|
|
2487
|
+
}
|
|
2457
2488
|
case 'phase_start': {
|
|
2458
2489
|
if (!event.phase) {
|
|
2459
2490
|
return ' ⚙️ Phase started';
|
|
@@ -2467,16 +2498,18 @@ function formatProgressEvent(event, serverBaseUrl) {
|
|
|
2467
2498
|
return ` ✅ ${phase} complete (${formatNumber(tokens)} tokens / ${duration})`;
|
|
2468
2499
|
}
|
|
2469
2500
|
case 'synthesis_complete': {
|
|
2501
|
+
const metaLink = buildMetaJsonLink(event.path, serverBaseUrl);
|
|
2470
2502
|
const tokens = event.tokens ?? 0;
|
|
2471
2503
|
const duration = event.durationMs !== undefined
|
|
2472
2504
|
? formatSeconds(event.durationMs)
|
|
2473
2505
|
: '0.0s';
|
|
2474
|
-
return `✅ Completed: ${
|
|
2506
|
+
return `✅ Completed: ${metaLink} (${formatNumber(tokens)} tokens / ${duration})`;
|
|
2475
2507
|
}
|
|
2476
2508
|
case 'error': {
|
|
2509
|
+
const dirLink = buildDirectoryLink(event.path, serverBaseUrl);
|
|
2477
2510
|
const phase = event.phase ? `${titleCasePhase(event.phase)} ` : '';
|
|
2478
2511
|
const error = event.error ?? 'Unknown error';
|
|
2479
|
-
return `❌ Synthesis failed at ${phase}phase: ${
|
|
2512
|
+
return `❌ Synthesis failed at ${phase}phase: ${dirLink}\n Error: ${error}`;
|
|
2480
2513
|
}
|
|
2481
2514
|
default: {
|
|
2482
2515
|
return 'Unknown progress event';
|
|
@@ -11079,6 +11112,7 @@ async function startService(config, configPath) {
|
|
|
11079
11112
|
await progress.report({
|
|
11080
11113
|
type: 'error',
|
|
11081
11114
|
path: ownerPath,
|
|
11115
|
+
phase: result.error.step,
|
|
11082
11116
|
error: result.error.message,
|
|
11083
11117
|
});
|
|
11084
11118
|
}
|