@karmaniverous/jeeves-meta 0.15.3 → 0.15.5
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/archive/index.d.ts +10 -0
- package/dist/archive/listArchive.d.ts +12 -0
- package/dist/archive/prune.d.ts +14 -0
- package/dist/archive/readArchive.d.ts +30 -0
- package/dist/archive/readLatest.d.ts +13 -0
- package/dist/archive/snapshot.d.ts +17 -0
- package/dist/bootstrap.d.ts +15 -0
- package/dist/cache.d.ts +22 -0
- package/dist/cli/jeeves-meta/architect.md +17 -0
- package/dist/cli/jeeves-meta/index.js +811 -734
- package/dist/cli.d.ts +10 -0
- package/dist/configHotReload.d.ts +30 -0
- package/dist/configLoader.d.ts +37 -0
- package/dist/constants.d.ts +13 -0
- package/dist/customCliCommands.d.ts +13 -0
- package/dist/descriptor.d.ts +19 -0
- package/dist/discovery/buildMinimalNode.d.ts +22 -0
- package/dist/discovery/computeSummary.d.ts +17 -0
- package/dist/discovery/discoverMetas.d.ts +19 -0
- package/dist/discovery/index.d.ts +11 -0
- package/dist/discovery/listMetas.d.ts +63 -0
- package/dist/discovery/ownershipTree.d.ts +25 -0
- package/dist/discovery/scope.d.ts +47 -0
- package/dist/discovery/types.d.ts +25 -0
- package/dist/ema.d.ts +14 -0
- package/dist/errors.d.ts +15 -0
- package/dist/escapeGlob.d.ts +23 -0
- package/dist/executor/GatewayExecutor.d.ts +48 -0
- package/dist/executor/SpawnAbortedError.d.ts +9 -0
- package/dist/executor/SpawnTimeoutError.d.ts +13 -0
- package/dist/executor/index.d.ts +8 -0
- package/dist/index.d.ts +34 -1660
- package/dist/index.js +1434 -1767
- package/dist/interfaces/MetaContext.d.ts +36 -0
- package/dist/interfaces/MetaExecutor.d.ts +46 -0
- package/dist/interfaces/WatcherClient.d.ts +75 -0
- package/dist/interfaces/index.d.ts +8 -0
- package/dist/lock.d.ts +70 -0
- package/dist/logger/index.d.ts +27 -0
- package/dist/mtimeFilter.d.ts +26 -0
- package/dist/normalizePath.d.ts +6 -0
- package/dist/orchestrator/buildTask.d.ts +38 -0
- package/dist/orchestrator/contextPackage.d.ts +30 -0
- package/dist/orchestrator/index.d.ts +10 -0
- package/dist/orchestrator/orchestratePhase.d.ts +38 -0
- package/dist/orchestrator/parseOutput.d.ts +41 -0
- package/dist/orchestrator/runPhase.d.ts +40 -0
- package/dist/phaseState/derivePhaseState.d.ts +41 -0
- package/dist/phaseState/index.d.ts +9 -0
- package/dist/phaseState/invalidate.d.ts +41 -0
- package/dist/phaseState/phaseScheduler.d.ts +57 -0
- package/dist/phaseState/phaseTransitions.d.ts +83 -0
- package/dist/progress/index.d.ts +38 -0
- package/dist/prompts/architect.md +17 -0
- package/dist/prompts/index.d.ts +15 -0
- package/dist/queue/index.d.ts +131 -0
- package/dist/readMetaJson.d.ts +17 -0
- package/dist/routes/__testUtils.d.ts +37 -0
- package/dist/routes/config.d.ts +11 -0
- package/dist/routes/configApply.d.ts +13 -0
- package/dist/routes/index.d.ts +50 -0
- package/dist/routes/metas.d.ts +9 -0
- package/dist/routes/metasUpdate.d.ts +11 -0
- package/dist/routes/preview.d.ts +8 -0
- package/dist/routes/queue.d.ts +13 -0
- package/dist/routes/seed.d.ts +8 -0
- package/dist/routes/status.d.ts +13 -0
- package/dist/routes/synthesize.d.ts +12 -0
- package/dist/routes/unlock.d.ts +8 -0
- package/dist/rules/healthCheck.d.ts +36 -0
- package/dist/rules/index.d.ts +39 -0
- package/dist/rules/verify.d.ts +22 -0
- package/dist/scheduler/index.d.ts +66 -0
- package/dist/scheduling/index.d.ts +7 -0
- package/dist/scheduling/staleness.d.ts +68 -0
- package/dist/scheduling/weightedFormula.d.ts +38 -0
- package/dist/schema/config.d.ts +54 -0
- package/dist/schema/error.d.ts +6 -0
- package/dist/schema/index.d.ts +8 -0
- package/dist/schema/meta.d.ts +71 -0
- package/dist/seed/autoSeed.d.ts +30 -0
- package/dist/seed/createMeta.d.ts +38 -0
- package/dist/seed/index.d.ts +7 -0
- package/dist/server.d.ts +24 -0
- package/dist/shutdown/index.d.ts +33 -0
- package/dist/structureHash.d.ts +15 -0
- package/dist/watcher-client/HttpWatcherClient.d.ts +38 -0
- package/dist/watcher-client/index.d.ts +6 -0
- package/package.json +17 -27
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Croner-based scheduler that discovers the highest-priority ready phase
|
|
3
|
+
* across the corpus each tick and enqueues it for execution.
|
|
4
|
+
*
|
|
5
|
+
* @module scheduler
|
|
6
|
+
*/
|
|
7
|
+
import type { Logger } from 'pino';
|
|
8
|
+
import type { MetaCache } from '../cache.js';
|
|
9
|
+
import type { SynthesisQueue } from '../queue/index.js';
|
|
10
|
+
import type { RuleRegistrar } from '../rules/index.js';
|
|
11
|
+
import type { ServiceConfig } from '../schema/config.js';
|
|
12
|
+
import type { HttpWatcherClient } from '../watcher-client/index.js';
|
|
13
|
+
/** Result of a scheduler tick's candidate discovery. */
|
|
14
|
+
export interface TickCandidate {
|
|
15
|
+
path: string;
|
|
16
|
+
phase: 'architect' | 'builder' | 'critic';
|
|
17
|
+
band: number;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Periodic scheduler that discovers the highest-priority ready phase
|
|
21
|
+
* across all metas and enqueues it for execution.
|
|
22
|
+
*
|
|
23
|
+
* Supports adaptive backoff when no candidates are found and hot-reloadable
|
|
24
|
+
* cron expressions via {@link Scheduler.updateSchedule}.
|
|
25
|
+
*/
|
|
26
|
+
export declare class Scheduler {
|
|
27
|
+
private job;
|
|
28
|
+
private backoffMultiplier;
|
|
29
|
+
private tickCount;
|
|
30
|
+
private readonly config;
|
|
31
|
+
private readonly queue;
|
|
32
|
+
private readonly logger;
|
|
33
|
+
private readonly watcher;
|
|
34
|
+
private readonly cache;
|
|
35
|
+
private registrar;
|
|
36
|
+
private currentExpression;
|
|
37
|
+
constructor(config: ServiceConfig, queue: SynthesisQueue, logger: Logger, watcher: HttpWatcherClient, cache: MetaCache);
|
|
38
|
+
/** Set the rule registrar for watcher restart detection. */
|
|
39
|
+
setRegistrar(registrar: RuleRegistrar): void;
|
|
40
|
+
/** Start the cron job. */
|
|
41
|
+
start(): void;
|
|
42
|
+
/** Stop the cron job. */
|
|
43
|
+
stop(): void;
|
|
44
|
+
/** Hot-reload the cron schedule expression. */
|
|
45
|
+
updateSchedule(expression: string): void;
|
|
46
|
+
/** Reset backoff multiplier (call after successful phase execution). */
|
|
47
|
+
resetBackoff(): void;
|
|
48
|
+
/** Whether the scheduler is currently running. */
|
|
49
|
+
get isRunning(): boolean;
|
|
50
|
+
/** Next scheduled tick time, or null if not running. */
|
|
51
|
+
get nextRunAt(): Date | null;
|
|
52
|
+
/**
|
|
53
|
+
* Single tick: discover the highest-priority ready phase and enqueue it.
|
|
54
|
+
*
|
|
55
|
+
* Applies adaptive backoff when no candidates are found.
|
|
56
|
+
*/
|
|
57
|
+
private tick;
|
|
58
|
+
/**
|
|
59
|
+
* Discover the highest-priority ready phase across the corpus.
|
|
60
|
+
*
|
|
61
|
+
* Uses phase-state-aware scheduling: priority order is
|
|
62
|
+
* critic (band 1) \> builder (band 2) \> architect (band 3),
|
|
63
|
+
* with weighted staleness as tiebreaker within a band.
|
|
64
|
+
*/
|
|
65
|
+
private discoverNextPhase;
|
|
66
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Scheduling module — staleness detection and candidate selection.
|
|
3
|
+
*
|
|
4
|
+
* @module scheduling
|
|
5
|
+
*/
|
|
6
|
+
export { actualStaleness, computeStalenessScore, hasSteerChanged, isArchitectTriggered, isStale, MAX_STALENESS_SECONDS, } from './staleness.js';
|
|
7
|
+
export { computeEffectiveStaleness, type StalenessCandidate, } from './weightedFormula.js';
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Staleness detection via watcher walk.
|
|
3
|
+
*
|
|
4
|
+
* A meta is stale when any watched file in its scope was modified after
|
|
5
|
+
* `_generatedAt`.
|
|
6
|
+
*
|
|
7
|
+
* @module scheduling/staleness
|
|
8
|
+
*/
|
|
9
|
+
import type { WatcherClient } from '../interfaces/index.js';
|
|
10
|
+
import type { MetaJson } from '../schema/index.js';
|
|
11
|
+
/**
|
|
12
|
+
* Check if a meta is stale.
|
|
13
|
+
*
|
|
14
|
+
* Uses watcher `/walk` to enumerate watched files under the scope prefix,
|
|
15
|
+
* then applies a local mtime check (fast) to detect any modifications since
|
|
16
|
+
* `_generatedAt`. Short-circuits on first match.
|
|
17
|
+
*
|
|
18
|
+
* @param scopePrefix - Path prefix for this meta's scope.
|
|
19
|
+
* @param meta - Current meta.json content.
|
|
20
|
+
* @param watcher - WatcherClient instance.
|
|
21
|
+
* @returns True if any file in scope was modified after `_generatedAt`.
|
|
22
|
+
*/
|
|
23
|
+
export declare function isStale(scopePrefix: string, meta: MetaJson, watcher: WatcherClient): Promise<boolean>;
|
|
24
|
+
/** Maximum staleness for never-synthesized metas (1 year in seconds). */
|
|
25
|
+
export declare const MAX_STALENESS_SECONDS: number;
|
|
26
|
+
/**
|
|
27
|
+
* Compute actual staleness in seconds (now minus _generatedAt).
|
|
28
|
+
*
|
|
29
|
+
* Never-synthesized metas are capped at {@link MAX_STALENESS_SECONDS}
|
|
30
|
+
* (1 year) so that depth weighting can differentiate them. Without
|
|
31
|
+
* bounding, `Infinity * depthFactor` = `Infinity` for all depths.
|
|
32
|
+
*
|
|
33
|
+
* @param meta - Current meta.json content.
|
|
34
|
+
* @returns Staleness in seconds, capped at 1 year for never-synthesized metas.
|
|
35
|
+
*/
|
|
36
|
+
export declare function actualStaleness(meta: MetaJson): number;
|
|
37
|
+
/**
|
|
38
|
+
* Check whether the architect step should be triggered.
|
|
39
|
+
*
|
|
40
|
+
* @param meta - Current meta.json.
|
|
41
|
+
* @param structureChanged - Whether the structure hash changed.
|
|
42
|
+
* @param steerChanged - Whether the steer directive changed.
|
|
43
|
+
* @param architectEvery - Config: run architect every N cycles.
|
|
44
|
+
* @returns True if the architect step should run.
|
|
45
|
+
*/
|
|
46
|
+
export declare function isArchitectTriggered(meta: MetaJson, structureChanged: boolean, steerChanged: boolean, architectEvery: number): boolean;
|
|
47
|
+
/**
|
|
48
|
+
* Detect whether the steer directive changed since the last archive.
|
|
49
|
+
*
|
|
50
|
+
* @param currentSteer - Current _steer value (or undefined).
|
|
51
|
+
* @param archiveSteer - Archive _steer value (or undefined).
|
|
52
|
+
* @param hasArchive - Whether an archive snapshot exists.
|
|
53
|
+
* @returns True if steer changed.
|
|
54
|
+
*/
|
|
55
|
+
export declare function hasSteerChanged(currentSteer: string | undefined, archiveSteer: string | undefined, hasArchive: boolean): boolean;
|
|
56
|
+
/**
|
|
57
|
+
* Compute a normalized staleness score (0–1) for display purposes.
|
|
58
|
+
*
|
|
59
|
+
* Uses the same depth/emphasis weighting as candidate selection,
|
|
60
|
+
* normalized to a 30-day window.
|
|
61
|
+
*
|
|
62
|
+
* @param stalenessSeconds - Raw staleness in seconds (null = never synthesized).
|
|
63
|
+
* @param depth - Meta tree depth.
|
|
64
|
+
* @param emphasis - Scheduling emphasis multiplier.
|
|
65
|
+
* @param depthWeight - Depth weighting exponent from config.
|
|
66
|
+
* @returns Normalized score between 0 and 1.
|
|
67
|
+
*/
|
|
68
|
+
export declare function computeStalenessScore(stalenessSeconds: number | null, depth: number, emphasis: number, depthWeight: number): number;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Weighted staleness formula for candidate selection.
|
|
3
|
+
*
|
|
4
|
+
* effectiveStaleness = actualStaleness * (normalizedDepth + 1) ^ (depthWeight * emphasis)
|
|
5
|
+
*
|
|
6
|
+
* @module scheduling/weightedFormula
|
|
7
|
+
*/
|
|
8
|
+
import type { MetaNode } from '../discovery/index.js';
|
|
9
|
+
import type { MetaJson } from '../schema/index.js';
|
|
10
|
+
/** A candidate meta with computed staleness. */
|
|
11
|
+
export interface StalenessCandidate {
|
|
12
|
+
/** The meta node. */
|
|
13
|
+
node: MetaNode;
|
|
14
|
+
/** Current meta.json content. */
|
|
15
|
+
meta: MetaJson;
|
|
16
|
+
/** Actual staleness in seconds. */
|
|
17
|
+
actualStaleness: number;
|
|
18
|
+
/** Effective staleness after depth weighting. */
|
|
19
|
+
effectiveStaleness: number;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Compute effective staleness for a set of candidates.
|
|
23
|
+
*
|
|
24
|
+
* Normalizes depths so the minimum becomes 0, then applies the formula:
|
|
25
|
+
* effectiveStaleness = actualStaleness * (normalizedDepth + 1) ^ (depthWeight * emphasis)
|
|
26
|
+
*
|
|
27
|
+
* Per-meta _emphasis (default 1) multiplies depthWeight, allowing individual
|
|
28
|
+
* metas to tune how much their tree position affects scheduling.
|
|
29
|
+
*
|
|
30
|
+
* @param candidates - Array of \{ node, meta, actualStaleness \}.
|
|
31
|
+
* @param depthWeight - Exponent for depth weighting (0 = pure staleness).
|
|
32
|
+
* @returns Same array with effectiveStaleness computed.
|
|
33
|
+
*/
|
|
34
|
+
export declare function computeEffectiveStaleness(candidates: Array<{
|
|
35
|
+
node: MetaNode;
|
|
36
|
+
meta: MetaJson;
|
|
37
|
+
actualStaleness: number;
|
|
38
|
+
}>, depthWeight: number): StalenessCandidate[];
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Zod schema for jeeves-meta service configuration.
|
|
3
|
+
*
|
|
4
|
+
* The service config is a strict superset of the core (library-compatible) meta config.
|
|
5
|
+
*
|
|
6
|
+
* @module schema/config
|
|
7
|
+
*/
|
|
8
|
+
import { type MetaConfig, metaConfigSchema } from '@karmaniverous/jeeves-meta-core';
|
|
9
|
+
import { z } from 'zod';
|
|
10
|
+
export { type MetaConfig, metaConfigSchema };
|
|
11
|
+
/** Zod schema for a single auto-seed policy rule. */
|
|
12
|
+
declare const autoSeedRuleSchema: z.ZodObject<{
|
|
13
|
+
match: z.ZodString;
|
|
14
|
+
steer: z.ZodOptional<z.ZodString>;
|
|
15
|
+
crossRefs: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
16
|
+
}, z.core.$strip>;
|
|
17
|
+
/** Inferred type for an auto-seed rule. */
|
|
18
|
+
export type AutoSeedRule = z.infer<typeof autoSeedRuleSchema>;
|
|
19
|
+
/** Zod schema for jeeves-meta service configuration (superset of MetaConfig). */
|
|
20
|
+
export declare const serviceConfigSchema: z.ZodObject<{
|
|
21
|
+
watcherUrl: z.ZodURL;
|
|
22
|
+
gatewayUrl: z.ZodDefault<z.ZodURL>;
|
|
23
|
+
gatewayApiKey: z.ZodOptional<z.ZodString>;
|
|
24
|
+
architectEvery: z.ZodDefault<z.ZodNumber>;
|
|
25
|
+
depthWeight: z.ZodDefault<z.ZodNumber>;
|
|
26
|
+
maxArchive: z.ZodDefault<z.ZodNumber>;
|
|
27
|
+
maxLines: z.ZodDefault<z.ZodNumber>;
|
|
28
|
+
architectTimeout: z.ZodDefault<z.ZodNumber>;
|
|
29
|
+
builderTimeout: z.ZodDefault<z.ZodNumber>;
|
|
30
|
+
criticTimeout: z.ZodDefault<z.ZodNumber>;
|
|
31
|
+
thinking: z.ZodDefault<z.ZodString>;
|
|
32
|
+
defaultArchitect: z.ZodOptional<z.ZodString>;
|
|
33
|
+
defaultCritic: z.ZodOptional<z.ZodString>;
|
|
34
|
+
skipUnchanged: z.ZodDefault<z.ZodBoolean>;
|
|
35
|
+
metaProperty: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
36
|
+
metaArchiveProperty: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
37
|
+
port: z.ZodDefault<z.ZodNumber>;
|
|
38
|
+
schedule: z.ZodDefault<z.ZodString>;
|
|
39
|
+
reportChannel: z.ZodOptional<z.ZodString>;
|
|
40
|
+
reportTarget: z.ZodOptional<z.ZodString>;
|
|
41
|
+
serverBaseUrl: z.ZodOptional<z.ZodString>;
|
|
42
|
+
watcherHealthIntervalMs: z.ZodDefault<z.ZodNumber>;
|
|
43
|
+
logging: z.ZodDefault<z.ZodObject<{
|
|
44
|
+
level: z.ZodDefault<z.ZodString>;
|
|
45
|
+
file: z.ZodOptional<z.ZodString>;
|
|
46
|
+
}, z.core.$strip>>;
|
|
47
|
+
autoSeed: z.ZodDefault<z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
48
|
+
match: z.ZodString;
|
|
49
|
+
steer: z.ZodOptional<z.ZodString>;
|
|
50
|
+
crossRefs: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
51
|
+
}, z.core.$strip>>>>;
|
|
52
|
+
}, z.core.$strip>;
|
|
53
|
+
/** Inferred type for service configuration. */
|
|
54
|
+
export type ServiceConfig = z.infer<typeof serviceConfigSchema>;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Re-exports for all schema modules.
|
|
3
|
+
*
|
|
4
|
+
* @module schema
|
|
5
|
+
*/
|
|
6
|
+
export { type AutoSeedRule, type MetaConfig, metaConfigSchema, type ServiceConfig, serviceConfigSchema, } from './config.js';
|
|
7
|
+
export { type MetaError, metaErrorSchema } from './error.js';
|
|
8
|
+
export { type MetaJson, metaJsonSchema, type PhaseName, phaseNames, type PhaseState, phaseStateSchema, type PhaseStatus, phaseStatuses, } from './meta.js';
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Zod schema for .meta/meta.json files.
|
|
3
|
+
*
|
|
4
|
+
* Reserved properties are underscore-prefixed and engine-managed.
|
|
5
|
+
* All other keys are open schema (builder output).
|
|
6
|
+
*
|
|
7
|
+
* @module schema/meta
|
|
8
|
+
*/
|
|
9
|
+
import { type PhaseName, phaseNames, type PhaseState, phaseStateSchema, type PhaseStatus, phaseStatuses } from '@karmaniverous/jeeves-meta-core';
|
|
10
|
+
import { z } from 'zod';
|
|
11
|
+
export { type PhaseName, phaseNames, type PhaseState, phaseStateSchema, type PhaseStatus, phaseStatuses, };
|
|
12
|
+
/** Zod schema for the reserved (underscore-prefixed) meta.json properties. */
|
|
13
|
+
export declare const metaJsonSchema: z.ZodObject<{
|
|
14
|
+
_id: z.ZodOptional<z.ZodUUID>;
|
|
15
|
+
_steer: z.ZodOptional<z.ZodString>;
|
|
16
|
+
_crossRefs: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
17
|
+
_architect: z.ZodOptional<z.ZodString>;
|
|
18
|
+
_builder: z.ZodOptional<z.ZodString>;
|
|
19
|
+
_critic: z.ZodOptional<z.ZodString>;
|
|
20
|
+
_generatedAt: z.ZodOptional<z.ZodISODateTime>;
|
|
21
|
+
_content: z.ZodOptional<z.ZodString>;
|
|
22
|
+
_structureHash: z.ZodOptional<z.ZodString>;
|
|
23
|
+
_synthesisCount: z.ZodOptional<z.ZodNumber>;
|
|
24
|
+
_feedback: z.ZodOptional<z.ZodString>;
|
|
25
|
+
_archived: z.ZodOptional<z.ZodBoolean>;
|
|
26
|
+
_archivedAt: z.ZodOptional<z.ZodISODateTime>;
|
|
27
|
+
_depth: z.ZodOptional<z.ZodNumber>;
|
|
28
|
+
_emphasis: z.ZodOptional<z.ZodNumber>;
|
|
29
|
+
_architectTokens: z.ZodOptional<z.ZodNumber>;
|
|
30
|
+
_builderTokens: z.ZodOptional<z.ZodNumber>;
|
|
31
|
+
_criticTokens: z.ZodOptional<z.ZodNumber>;
|
|
32
|
+
_architectTokensAvg: z.ZodOptional<z.ZodNumber>;
|
|
33
|
+
_builderTokensAvg: z.ZodOptional<z.ZodNumber>;
|
|
34
|
+
_criticTokensAvg: z.ZodOptional<z.ZodNumber>;
|
|
35
|
+
_state: z.ZodOptional<z.ZodUnknown>;
|
|
36
|
+
_error: z.ZodOptional<z.ZodObject<{
|
|
37
|
+
step: z.ZodEnum<{
|
|
38
|
+
architect: "architect";
|
|
39
|
+
builder: "builder";
|
|
40
|
+
critic: "critic";
|
|
41
|
+
}>;
|
|
42
|
+
code: z.ZodString;
|
|
43
|
+
message: z.ZodString;
|
|
44
|
+
}, z.core.$strip>>;
|
|
45
|
+
_disabled: z.ZodOptional<z.ZodBoolean>;
|
|
46
|
+
_phaseState: z.ZodOptional<z.ZodObject<{
|
|
47
|
+
architect: z.ZodEnum<{
|
|
48
|
+
fresh: "fresh";
|
|
49
|
+
stale: "stale";
|
|
50
|
+
pending: "pending";
|
|
51
|
+
running: "running";
|
|
52
|
+
failed: "failed";
|
|
53
|
+
}>;
|
|
54
|
+
builder: z.ZodEnum<{
|
|
55
|
+
fresh: "fresh";
|
|
56
|
+
stale: "stale";
|
|
57
|
+
pending: "pending";
|
|
58
|
+
running: "running";
|
|
59
|
+
failed: "failed";
|
|
60
|
+
}>;
|
|
61
|
+
critic: z.ZodEnum<{
|
|
62
|
+
fresh: "fresh";
|
|
63
|
+
stale: "stale";
|
|
64
|
+
pending: "pending";
|
|
65
|
+
running: "running";
|
|
66
|
+
failed: "failed";
|
|
67
|
+
}>;
|
|
68
|
+
}, z.core.$strip>>;
|
|
69
|
+
}, z.core.$loose>;
|
|
70
|
+
/** Inferred type for meta.json. */
|
|
71
|
+
export type MetaJson = z.infer<typeof metaJsonSchema>;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Auto-seed pass — scan for directories matching policy rules and seed them.
|
|
3
|
+
*
|
|
4
|
+
* Runs before discovery in each scheduler tick. For each auto-seed rule,
|
|
5
|
+
* walks matching directories via the watcher and creates .meta/ directories
|
|
6
|
+
* for those that don't already have one.
|
|
7
|
+
*
|
|
8
|
+
* Rules are processed in array order; last match wins for steer/crossRefs.
|
|
9
|
+
*
|
|
10
|
+
* @module seed/autoSeed
|
|
11
|
+
*/
|
|
12
|
+
import type { WatcherClient } from '../interfaces/index.js';
|
|
13
|
+
import type { MinimalLogger } from '../logger/index.js';
|
|
14
|
+
import type { AutoSeedRule } from '../schema/config.js';
|
|
15
|
+
/** Result of a single auto-seed pass. */
|
|
16
|
+
export interface AutoSeedResult {
|
|
17
|
+
/** Number of new metas created. */
|
|
18
|
+
seeded: number;
|
|
19
|
+
/** Paths that were seeded. */
|
|
20
|
+
paths: string[];
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Run the auto-seed pass: apply policy rules and create missing metas.
|
|
24
|
+
*
|
|
25
|
+
* @param rules - Auto-seed policy rules from config.
|
|
26
|
+
* @param watcher - Watcher client for filesystem enumeration.
|
|
27
|
+
* @param logger - Logger for reporting seed actions.
|
|
28
|
+
* @returns Summary of what was seeded.
|
|
29
|
+
*/
|
|
30
|
+
export declare function autoSeedPass(rules: AutoSeedRule[], watcher: WatcherClient, logger?: MinimalLogger): Promise<AutoSeedResult>;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Core seed logic — create a .meta/ directory with initial meta.json.
|
|
3
|
+
*
|
|
4
|
+
* Shared between the POST /seed route handler and the auto-seed pass.
|
|
5
|
+
*
|
|
6
|
+
* @module seed/createMeta
|
|
7
|
+
*/
|
|
8
|
+
/** Options for creating a new meta. */
|
|
9
|
+
export interface CreateMetaOptions {
|
|
10
|
+
/** Cross-references to other meta owner paths. */
|
|
11
|
+
crossRefs?: string[];
|
|
12
|
+
/** Steering prompt for the meta. */
|
|
13
|
+
steer?: string;
|
|
14
|
+
}
|
|
15
|
+
/** Result of creating a new meta. */
|
|
16
|
+
export interface CreateMetaResult {
|
|
17
|
+
/** Absolute path to the .meta/ directory. */
|
|
18
|
+
metaDir: string;
|
|
19
|
+
/** The generated UUID. */
|
|
20
|
+
_id: string;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Create a .meta/ directory with an initial meta.json.
|
|
24
|
+
*
|
|
25
|
+
* Does NOT check for existing .meta/ — caller is responsible for that guard.
|
|
26
|
+
*
|
|
27
|
+
* @param ownerPath - The owner directory path.
|
|
28
|
+
* @param options - Optional cross-refs and steering prompt.
|
|
29
|
+
* @returns The meta directory path and generated ID.
|
|
30
|
+
*/
|
|
31
|
+
export declare function createMeta(ownerPath: string, options?: CreateMetaOptions): Promise<CreateMetaResult>;
|
|
32
|
+
/**
|
|
33
|
+
* Check if a .meta/ directory already exists for an owner path.
|
|
34
|
+
*
|
|
35
|
+
* @param ownerPath - The owner directory path.
|
|
36
|
+
* @returns True if .meta/ already exists.
|
|
37
|
+
*/
|
|
38
|
+
export declare function metaExists(ownerPath: string): boolean;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Seed module — create .meta/ directories with initial meta.json.
|
|
3
|
+
*
|
|
4
|
+
* @module seed
|
|
5
|
+
*/
|
|
6
|
+
export { autoSeedPass, type AutoSeedResult } from './autoSeed.js';
|
|
7
|
+
export { createMeta, type CreateMetaOptions, type CreateMetaResult, metaExists, } from './createMeta.js';
|
package/dist/server.d.ts
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Minimal Fastify HTTP server for jeeves-meta service.
|
|
3
|
+
*
|
|
4
|
+
* @module server
|
|
5
|
+
*/
|
|
6
|
+
import { type FastifyBaseLogger } from 'fastify';
|
|
7
|
+
import type { Logger } from 'pino';
|
|
8
|
+
import { type RouteDeps } from './routes/index.js';
|
|
9
|
+
/** Options for creating the server. */
|
|
10
|
+
export interface ServerOptions {
|
|
11
|
+
/** Pino logger instance. */
|
|
12
|
+
logger: Logger;
|
|
13
|
+
/** Shared route dependencies (mutable — late-bound properties like registrar are set after creation). */
|
|
14
|
+
deps: RouteDeps;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Create and configure the Fastify server.
|
|
18
|
+
*
|
|
19
|
+
* @param options - Server creation options.
|
|
20
|
+
* @returns Configured Fastify instance (not yet listening).
|
|
21
|
+
*/
|
|
22
|
+
export declare function createServer(options: ServerOptions): import("fastify").FastifyInstance<import("node:http").Server<typeof import("node:http").IncomingMessage, typeof import("node:http").ServerResponse>, import("node:http").IncomingMessage, import("node:http").ServerResponse<import("node:http").IncomingMessage>, FastifyBaseLogger, import("fastify").FastifyTypeProviderDefault> & PromiseLike<import("fastify").FastifyInstance<import("node:http").Server<typeof import("node:http").IncomingMessage, typeof import("node:http").ServerResponse>, import("node:http").IncomingMessage, import("node:http").ServerResponse<import("node:http").IncomingMessage>, FastifyBaseLogger, import("fastify").FastifyTypeProviderDefault>> & {
|
|
23
|
+
__linterBrands: "SafePromiseLike";
|
|
24
|
+
};
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Graceful shutdown handler.
|
|
3
|
+
*
|
|
4
|
+
* On SIGTERM/SIGINT: stops scheduler, drains queue, cleans up locks.
|
|
5
|
+
*
|
|
6
|
+
* @module shutdown
|
|
7
|
+
*/
|
|
8
|
+
import type { Logger } from 'pino';
|
|
9
|
+
import type { SynthesisQueue } from '../queue/index.js';
|
|
10
|
+
import type { RouteDeps } from '../routes/index.js';
|
|
11
|
+
import type { Scheduler } from '../scheduler/index.js';
|
|
12
|
+
interface ShutdownDeps {
|
|
13
|
+
server: {
|
|
14
|
+
close: () => Promise<void>;
|
|
15
|
+
};
|
|
16
|
+
scheduler: Scheduler | null;
|
|
17
|
+
queue: SynthesisQueue;
|
|
18
|
+
logger: Logger;
|
|
19
|
+
routeDeps?: RouteDeps;
|
|
20
|
+
/** Optional cleanup callback (e.g., stop health check). */
|
|
21
|
+
onShutdown?: () => void;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Register shutdown handlers for SIGTERM and SIGINT.
|
|
25
|
+
*
|
|
26
|
+
* Flow:
|
|
27
|
+
* 1. Stop scheduler (no new ticks)
|
|
28
|
+
* 2. If synthesis in progress, release its lock
|
|
29
|
+
* 3. Close Fastify server
|
|
30
|
+
* 4. Exit
|
|
31
|
+
*/
|
|
32
|
+
export declare function registerShutdownHandlers(deps: ShutdownDeps): void;
|
|
33
|
+
export {};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Compute a structure hash from a sorted file listing.
|
|
3
|
+
*
|
|
4
|
+
* Used to detect when directory structure changes, triggering
|
|
5
|
+
* an architect re-run.
|
|
6
|
+
*
|
|
7
|
+
* @module structureHash
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* Compute a SHA-256 hash of a sorted file listing.
|
|
11
|
+
*
|
|
12
|
+
* @param filePaths - Array of file paths in scope.
|
|
13
|
+
* @returns Hex-encoded SHA-256 hash of the sorted, newline-joined paths.
|
|
14
|
+
*/
|
|
15
|
+
export declare function computeStructureHash(filePaths: string[]): string;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HTTP implementation of the WatcherClient interface.
|
|
3
|
+
*
|
|
4
|
+
* Talks to jeeves-watcher's POST /walk and POST /rules/register endpoints
|
|
5
|
+
* with retry and exponential backoff.
|
|
6
|
+
*
|
|
7
|
+
* @module watcher-client/HttpWatcherClient
|
|
8
|
+
*/
|
|
9
|
+
import type { InferenceRuleSpec, WatcherClient, WatcherScanRequest, WatcherScanResult } from '../interfaces/index.js';
|
|
10
|
+
/** Options for creating an HttpWatcherClient. */
|
|
11
|
+
export interface HttpWatcherClientOptions {
|
|
12
|
+
/** Base URL for the watcher service (e.g. "http://localhost:1936"). */
|
|
13
|
+
baseUrl: string;
|
|
14
|
+
/** Maximum retry attempts for transient failures. Default: 3. */
|
|
15
|
+
maxRetries?: number;
|
|
16
|
+
/** Base delay in ms for exponential backoff. Default: 1000. */
|
|
17
|
+
backoffBaseMs?: number;
|
|
18
|
+
/** Multiplier for backoff. Default: 4 (1s, 4s, 16s). */
|
|
19
|
+
backoffFactor?: number;
|
|
20
|
+
/** Per-request timeout in ms. Default: 10000. */
|
|
21
|
+
timeoutMs?: number;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* HTTP-based WatcherClient implementation with retry.
|
|
25
|
+
*/
|
|
26
|
+
export declare class HttpWatcherClient implements WatcherClient {
|
|
27
|
+
private readonly baseUrl;
|
|
28
|
+
private readonly maxRetries;
|
|
29
|
+
private readonly backoffBaseMs;
|
|
30
|
+
private readonly backoffFactor;
|
|
31
|
+
private readonly timeoutMs;
|
|
32
|
+
constructor(options: HttpWatcherClientOptions);
|
|
33
|
+
/** POST JSON with retry. */
|
|
34
|
+
private post;
|
|
35
|
+
registerRules(source: string, rules: InferenceRuleSpec[]): Promise<void>;
|
|
36
|
+
walk(globs: string[]): Promise<string[]>;
|
|
37
|
+
scan(request: WatcherScanRequest): Promise<WatcherScanResult>;
|
|
38
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@karmaniverous/jeeves-meta",
|
|
3
|
-
"version": "0.15.
|
|
3
|
+
"version": "0.15.5",
|
|
4
4
|
"author": "Jason Williscroft",
|
|
5
5
|
"description": "Fastify HTTP service for the Jeeves Meta synthesis engine",
|
|
6
6
|
"license": "BSD-3-Clause",
|
|
@@ -41,42 +41,39 @@
|
|
|
41
41
|
"node": ">=22"
|
|
42
42
|
},
|
|
43
43
|
"dependencies": {
|
|
44
|
-
"@karmaniverous/jeeves": "^0.5.
|
|
44
|
+
"@karmaniverous/jeeves": "^0.5.10",
|
|
45
|
+
"@karmaniverous/jeeves-meta-core": "^0.1.0",
|
|
45
46
|
"commander": "^14",
|
|
46
47
|
"croner": "^10",
|
|
47
48
|
"fastify": "^5.8",
|
|
48
49
|
"handlebars": "^4.7.9",
|
|
49
50
|
"package-directory": "^8.2.0",
|
|
50
51
|
"pino": "^10",
|
|
51
|
-
"zod": "^4.
|
|
52
|
+
"zod": "^4.4"
|
|
52
53
|
},
|
|
53
54
|
"devDependencies": {
|
|
54
|
-
"@
|
|
55
|
-
"@dotenvx/dotenvx": "^1.59.1",
|
|
55
|
+
"@dotenvx/dotenvx": "^1.65.0",
|
|
56
56
|
"@rollup/plugin-commonjs": "^29.0.2",
|
|
57
57
|
"@rollup/plugin-json": "^6.1.0",
|
|
58
58
|
"@rollup/plugin-node-resolve": "^16.0.3",
|
|
59
59
|
"@rollup/plugin-typescript": "^12.3.0",
|
|
60
|
-
"@types/node": "^25.
|
|
61
|
-
"@vitest/coverage-v8": "^4.1.
|
|
62
|
-
"auto-changelog": "^2.5.0",
|
|
60
|
+
"@types/node": "^25.7.0",
|
|
61
|
+
"@vitest/coverage-v8": "^4.1.6",
|
|
63
62
|
"cross-env": "^10.1.0",
|
|
64
|
-
"
|
|
65
|
-
"
|
|
66
|
-
"rollup": "^4.60.1",
|
|
63
|
+
"release-it": "^20.0.1",
|
|
64
|
+
"rollup": "^4.60.3",
|
|
67
65
|
"rollup-plugin-copy": "^3.5.0",
|
|
68
|
-
"rollup-plugin-dts": "^6.4.1",
|
|
69
66
|
"tslib": "^2.8.1",
|
|
70
|
-
"vitest": "^4.1.
|
|
67
|
+
"vitest": "^4.1.6"
|
|
71
68
|
},
|
|
72
69
|
"scripts": {
|
|
73
|
-
"build": "rimraf dist && cross-env NO_COLOR=1 rollup --config rollup.config.
|
|
70
|
+
"build": "rimraf dist && cross-env NO_COLOR=1 rollup --config rollup.config.ts --configPlugin @rollup/plugin-typescript",
|
|
74
71
|
"knip": "knip",
|
|
75
72
|
"lint": "eslint .",
|
|
76
73
|
"lint:fix": "eslint --fix .",
|
|
77
74
|
"test": "vitest run",
|
|
78
75
|
"typecheck": "tsc",
|
|
79
|
-
"changelog": "
|
|
76
|
+
"changelog": "git-cliff -o CHANGELOG.md",
|
|
80
77
|
"release": "dotenvx run -f .env.local -- release-it",
|
|
81
78
|
"release:pre": "dotenvx run -f .env.local -- release-it --no-git.requireBranch --github.prerelease --preRelease"
|
|
82
79
|
},
|
|
@@ -85,7 +82,7 @@
|
|
|
85
82
|
},
|
|
86
83
|
"release-it": {
|
|
87
84
|
"git": {
|
|
88
|
-
"changelog": "npx
|
|
85
|
+
"changelog": "npx git-cliff --unreleased --strip header",
|
|
89
86
|
"commitMessage": "chore: release @karmaniverous/jeeves-meta v${version}",
|
|
90
87
|
"tagName": "service/${version}",
|
|
91
88
|
"requireBranch": "main"
|
|
@@ -100,25 +97,18 @@
|
|
|
100
97
|
"npm run test",
|
|
101
98
|
"npm run build"
|
|
102
99
|
],
|
|
103
|
-
"before:npm:release": [
|
|
104
|
-
"npx auto-changelog -p",
|
|
105
|
-
"git add -A"
|
|
106
|
-
],
|
|
107
100
|
"after:release": [
|
|
108
101
|
"git switch -c release/service/${version}",
|
|
109
102
|
"git push -u origin release/service/${version}",
|
|
110
103
|
"git switch ${branchName}"
|
|
104
|
+
],
|
|
105
|
+
"before:npm:release": [
|
|
106
|
+
"npx git-cliff -o CHANGELOG.md",
|
|
107
|
+
"git add -A"
|
|
111
108
|
]
|
|
112
109
|
},
|
|
113
110
|
"npm": {
|
|
114
111
|
"publish": true
|
|
115
112
|
}
|
|
116
|
-
},
|
|
117
|
-
"auto-changelog": {
|
|
118
|
-
"output": "CHANGELOG.md",
|
|
119
|
-
"tagPrefix": "service/",
|
|
120
|
-
"unreleased": true,
|
|
121
|
-
"commitLimit": false,
|
|
122
|
-
"hideCredit": true
|
|
123
113
|
}
|
|
124
114
|
}
|