@sensigo/realm-cli 0.12.0 → 0.13.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.
Files changed (54) hide show
  1. package/dist/agent/run-attach.d.ts +24 -0
  2. package/dist/agent/run-attach.d.ts.map +1 -0
  3. package/dist/agent/run-attach.js +77 -0
  4. package/dist/agent/run-attach.js.map +1 -0
  5. package/dist/commands/agent.d.ts +13 -0
  6. package/dist/commands/agent.d.ts.map +1 -1
  7. package/dist/commands/agent.js +38 -8
  8. package/dist/commands/agent.js.map +1 -1
  9. package/dist/commands/init.d.ts +2 -1
  10. package/dist/commands/init.d.ts.map +1 -1
  11. package/dist/commands/init.js +42 -1
  12. package/dist/commands/init.js.map +1 -1
  13. package/dist/commands/inspect.d.ts +1 -0
  14. package/dist/commands/inspect.d.ts.map +1 -1
  15. package/dist/commands/inspect.js +93 -1
  16. package/dist/commands/inspect.js.map +1 -1
  17. package/dist/commands/listen.d.ts +11 -0
  18. package/dist/commands/listen.d.ts.map +1 -1
  19. package/dist/commands/listen.js +36 -1
  20. package/dist/commands/listen.js.map +1 -1
  21. package/dist/commands/mcp.d.ts +2 -1
  22. package/dist/commands/mcp.d.ts.map +1 -1
  23. package/dist/commands/mcp.js +12 -5
  24. package/dist/commands/mcp.js.map +1 -1
  25. package/dist/commands/register.d.ts +6 -0
  26. package/dist/commands/register.d.ts.map +1 -1
  27. package/dist/commands/register.js +20 -1
  28. package/dist/commands/register.js.map +1 -1
  29. package/dist/commands/run.d.ts.map +1 -1
  30. package/dist/commands/run.js +12 -0
  31. package/dist/commands/run.js.map +1 -1
  32. package/dist/commands/serve.d.ts +6 -0
  33. package/dist/commands/serve.d.ts.map +1 -1
  34. package/dist/commands/serve.js +17 -4
  35. package/dist/commands/serve.js.map +1 -1
  36. package/dist/commands/test.d.ts.map +1 -1
  37. package/dist/commands/test.js +25 -1
  38. package/dist/commands/test.js.map +1 -1
  39. package/dist/commands/validate.d.ts.map +1 -1
  40. package/dist/commands/validate.js +53 -8
  41. package/dist/commands/validate.js.map +1 -1
  42. package/dist/commands/watch.d.ts.map +1 -1
  43. package/dist/commands/watch.js +6 -1
  44. package/dist/commands/watch.js.map +1 -1
  45. package/dist/extensions/extension-identity.d.ts +63 -0
  46. package/dist/extensions/extension-identity.d.ts.map +1 -0
  47. package/dist/extensions/extension-identity.js +218 -0
  48. package/dist/extensions/extension-identity.js.map +1 -0
  49. package/dist/extensions/load-project-extensions.d.ts +36 -0
  50. package/dist/extensions/load-project-extensions.d.ts.map +1 -0
  51. package/dist/extensions/load-project-extensions.js +358 -0
  52. package/dist/extensions/load-project-extensions.js.map +1 -0
  53. package/dist/index.js +1 -1
  54. package/package.json +4 -4
@@ -1,12 +1,35 @@
1
1
  // realm validate <path> — validates a workflow YAML file without registering it.
2
+ //
3
+ // Strictness asymmetry (documented): extension-free workflows validate through the EXACT
4
+ // from-string path used before project extensions existed (byte-identical behavior).
5
+ // Workflows declaring `extensions:` (or validated with --extensions-module) go through
6
+ // file-based loading so extension modules can be resolved, then a SECOND pass validates
7
+ // step `config` against each resolved adapter's `config_schema` (two-pass).
2
8
  import { Command } from 'commander';
3
9
  import { join } from 'node:path';
4
10
  import { readFileSync } from 'node:fs';
5
- import { loadWorkflowFromString, WorkflowError } from '@sensigo/realm';
11
+ import { load } from 'js-yaml';
12
+ import { loadWorkflowFromString, loadWorkflowFromFile, WorkflowError } from '@sensigo/realm';
13
+ import { loadProjectExtensions } from '../extensions/load-project-extensions.js';
14
+ /** Pre-scan: does the YAML carry a top-level `extensions` key? (Parse errors → false; the
15
+ * real loader below reports them with its existing error surface.) */
16
+ function hasTopLevelExtensions(content) {
17
+ try {
18
+ const raw = load(content);
19
+ return (typeof raw === 'object' &&
20
+ raw !== null &&
21
+ !Array.isArray(raw) &&
22
+ 'extensions' in raw);
23
+ }
24
+ catch {
25
+ return false;
26
+ }
27
+ }
6
28
  export const validateCommand = new Command('validate')
7
29
  .argument('<path>', 'Path to workflow directory or workflow.yaml file')
30
+ .option('--extensions-module <path>', "Extensions module that REPLACES the workflow's declared 'extensions' modules (repair/override)")
8
31
  .description('Validate a workflow YAML file')
9
- .action((inputPath) => {
32
+ .action(async (inputPath, opts) => {
10
33
  const filePath = inputPath.endsWith('.yaml') || inputPath.endsWith('.yml')
11
34
  ? inputPath
12
35
  : join(inputPath, 'workflow.yaml');
@@ -20,16 +43,38 @@ export const validateCommand = new Command('validate')
20
43
  process.exit(1);
21
44
  return;
22
45
  }
46
+ if (!hasTopLevelExtensions(content) && opts.extensionsModule === undefined) {
47
+ // Extension-free: the exact current from-string path — byte-identical behavior.
48
+ try {
49
+ const definition = loadWorkflowFromString(content);
50
+ console.log(`Valid: ${definition.id} v${definition.version} (${Object.keys(definition.steps).length} steps)`);
51
+ }
52
+ catch (err) {
53
+ if (err instanceof WorkflowError) {
54
+ console.error(`Invalid: ${err.message}`);
55
+ process.exit(1);
56
+ }
57
+ throw err;
58
+ }
59
+ return;
60
+ }
61
+ // Extensions declared (or an override supplied): file-based two-pass validation.
23
62
  try {
24
- const definition = loadWorkflowFromString(content);
63
+ // Pass 1: structural validation + extension resolution metadata (source_dir/trust_root).
64
+ const definition = loadWorkflowFromFile(filePath);
65
+ const { registry, manifest } = await loadProjectExtensions(definition, opts.extensionsModule !== undefined ? { overrideModule: opts.extensionsModule } : {});
66
+ // Pass 2: step config validated against each resolved adapter's config_schema.
67
+ loadWorkflowFromFile(filePath, registry);
25
68
  console.log(`Valid: ${definition.id} v${definition.version} (${Object.keys(definition.steps).length} steps)`);
69
+ if (manifest.modules.length > 0) {
70
+ console.log(`Extensions: ${manifest.modules.map((m) => m.declared).join(', ')} ` +
71
+ `(adapters: ${manifest.adapters.length}, handlers: ${manifest.handlers.length}, ` +
72
+ `processors: ${manifest.processors.length})`);
73
+ }
26
74
  }
27
75
  catch (err) {
28
- if (err instanceof WorkflowError) {
29
- console.error(`Invalid: ${err.message}`);
30
- process.exit(1);
31
- }
32
- throw err;
76
+ console.error(`Invalid: ${err instanceof Error ? err.message : String(err)}`);
77
+ process.exit(1);
33
78
  }
34
79
  });
35
80
  //# sourceMappingURL=validate.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"validate.js","sourceRoot":"","sources":["../../src/commands/validate.ts"],"names":[],"mappings":"AAAA,iFAAiF;AACjF,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,sBAAsB,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAEvE,MAAM,CAAC,MAAM,eAAe,GAAG,IAAI,OAAO,CAAC,UAAU,CAAC;KACnD,QAAQ,CAAC,QAAQ,EAAE,kDAAkD,CAAC;KACtE,WAAW,CAAC,+BAA+B,CAAC;KAC5C,MAAM,CAAC,CAAC,SAAiB,EAAE,EAAE;IAC5B,MAAM,QAAQ,GACZ,SAAS,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,SAAS,CAAC,QAAQ,CAAC,MAAM,CAAC;QACvD,CAAC,CAAC,SAAS;QACX,CAAC,CAAC,IAAI,CAAC,SAAS,EAAE,eAAe,CAAC,CAAC;IAEvC,IAAI,OAAe,CAAC;IACpB,IAAI,CAAC;QACH,OAAO,GAAG,YAAY,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;IAC3C,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QACjE,OAAO,CAAC,KAAK,CAAC,UAAU,OAAO,EAAE,CAAC,CAAC;QACnC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAChB,OAAO;IACT,CAAC;IAED,IAAI,CAAC;QACH,MAAM,UAAU,GAAG,sBAAsB,CAAC,OAAO,CAAC,CAAC;QACnD,OAAO,CAAC,GAAG,CACT,UAAU,UAAU,CAAC,EAAE,KAAK,UAAU,CAAC,OAAO,KAAK,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,MAAM,SAAS,CACjG,CAAC;IACJ,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAI,GAAG,YAAY,aAAa,EAAE,CAAC;YACjC,OAAO,CAAC,KAAK,CAAC,YAAY,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;YACzC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QACD,MAAM,GAAG,CAAC;IACZ,CAAC;AACH,CAAC,CAAC,CAAC"}
1
+ {"version":3,"file":"validate.js","sourceRoot":"","sources":["../../src/commands/validate.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"watch.d.ts","sourceRoot":"","sources":["../../src/commands/watch.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AA0BxD;;;;;;;;;;;;GAYG;AACH,wBAAsB,aAAa,CACjC,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,iBAAiB,EACxB,MAAM,CAAC,EAAE,WAAW,EACpB,WAAW,CAAC,EAAE,MAAM,GACnB,OAAO,CAAC,IAAI,CAAC,CA4Df;AAED,eAAO,MAAM,YAAY,SAoBrB,CAAC"}
1
+ {"version":3,"file":"watch.d.ts","sourceRoot":"","sources":["../../src/commands/watch.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AA+BxD;;;;;;;;;;;;GAYG;AACH,wBAAsB,aAAa,CACjC,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,iBAAiB,EACxB,MAAM,CAAC,EAAE,WAAW,EACpB,WAAW,CAAC,EAAE,MAAM,GACnB,OAAO,CAAC,IAAI,CAAC,CA4Df;AAED,eAAO,MAAM,YAAY,SAoBrB,CAAC"}
@@ -3,16 +3,21 @@ import { watch, existsSync } from 'node:fs';
3
3
  import { join, dirname, resolve } from 'node:path';
4
4
  import { Command } from 'commander';
5
5
  import { loadWorkflowFromFile, WorkflowError } from '@sensigo/realm';
6
+ import { loadWorkflowForRegistration } from './register.js';
6
7
  /**
7
8
  * Attempts to load and register a workflow YAML file.
8
9
  * Logs the result (success or validation error) to stdout/stderr.
10
+ * Like `realm workflow register`, each (re-)registration mints the trust decision: when the
11
+ * workflow declares `extensions:`, the modules load + duck-validate and step config gets the
12
+ * config_schema two-pass BEFORE persisting. NOTE: long-lived watch processes keep the FIRST
13
+ * imported content of each module path (ESM cache) — restart watch to pick up module changes.
9
14
  * @param filePath Path to the workflow YAML file.
10
15
  * @param store The registrar to register into.
11
16
  */
12
17
  async function registerFile(filePath, store) {
13
18
  const timestamp = new Date().toISOString();
14
19
  try {
15
- const definition = loadWorkflowFromFile(filePath);
20
+ const definition = await loadWorkflowForRegistration(filePath);
16
21
  await store.register(definition);
17
22
  console.log(`[${timestamp}] Registered: ${definition.id} v${definition.version} (${Object.keys(definition.steps).length} steps)`);
18
23
  }
@@ -1 +1 @@
1
- {"version":3,"file":"watch.js","sourceRoot":"","sources":["../../src/commands/watch.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"watch.js","sourceRoot":"","sources":["../../src/commands/watch.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,63 @@
1
+ import type { ExtensionIdentityEntry, ExtensionIdentityModule, ExtensionIdentitySignals } from '@sensigo/realm';
2
+ import { extensionIdentityDiffers } from '@sensigo/realm';
3
+ /** The one sweep-rule version this module can compute. Comparison ALWAYS recomputes under
4
+ * the RECORDED rule string — a future rules change must add a new version, never mutate v1. */
5
+ export declare const DIR_TREE_V1_RULES = "dir_tree_v1: include .js,.mjs,.cjs,.ts,.mts,.cts,.json; exclude dirs node_modules,.git; skip symlinks; sort by relpath; sha256(relpath\\0filehash); caps 2000 files/50MB";
6
+ /** Compares two identity entries — tree_hash + per-module entry hashes + override flag. */
7
+ export { extensionIdentityDiffers as identityDiffers };
8
+ export interface ComputeIdentityInput {
9
+ declared: string;
10
+ resolved: string;
11
+ format: ExtensionIdentityModule['format'];
12
+ }
13
+ export interface ComputeIdentityOptions {
14
+ /** Trust root for the advisory signals (package.json version, .git HEAD). */
15
+ trustRoot?: string;
16
+ /** Set when --extensions-module replaced the declared modules. */
17
+ overrideActive?: boolean;
18
+ /** Injected for tests; defaults to `new Date().toISOString()`. */
19
+ capturedAt?: string;
20
+ /** Injected for tests; defaults to `process.pid`. */
21
+ pid?: number;
22
+ }
23
+ /**
24
+ * Computes the dir_tree_v1 identity of a set of loaded extension modules: per-module
25
+ * sha256 entry hashes plus a deterministic directory-tree fingerprint over the deduped
26
+ * parent directories of the resolved entries. Pure fs + crypto — never loads code.
27
+ */
28
+ export declare function computeExtensionIdentity(modules: ComputeIdentityInput[], opts?: ComputeIdentityOptions): ExtensionIdentityEntry;
29
+ /**
30
+ * Builds an identity entry that records a capture/load FAILURE — the failure is itself
31
+ * evidence (WorkflowContextSnapshot.error precedent). Modules/tree are empty placeholders.
32
+ */
33
+ export declare function errorExtensionIdentityEntry(message: string, opts?: Pick<ComputeIdentityOptions, 'capturedAt' | 'pid' | 'overrideActive'>): ExtensionIdentityEntry;
34
+ /** Per-component result of a --check-drift recomputation against current disk state. */
35
+ export interface RecomputeResult {
36
+ comparable: true;
37
+ /** Per recorded module: current entry hash (undefined = file unreadable/missing). */
38
+ modules: Array<{
39
+ resolved: string;
40
+ recorded_hash: string;
41
+ current_hash?: string;
42
+ }>;
43
+ tree: {
44
+ recorded_hash: string;
45
+ current_hash: string;
46
+ current_truncated: boolean;
47
+ };
48
+ signals?: ExtensionIdentitySignals;
49
+ }
50
+ export interface RecomputeNotComparable {
51
+ comparable: false;
52
+ reason: string;
53
+ }
54
+ /**
55
+ * Recomputes an entry's identity from CURRENT disk state STRICTLY under the entry's
56
+ * RECORDED rules and roots — an unknown rules version yields an explicit cannot-compare
57
+ * rather than a guess (a rules change must never manufacture phantom drift).
58
+ * Pure fs + crypto — never loads code.
59
+ */
60
+ export declare function recomputeIdentity(entry: ExtensionIdentityEntry, opts?: {
61
+ trustRoot?: string;
62
+ }): RecomputeResult | RecomputeNotComparable;
63
+ //# sourceMappingURL=extension-identity.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"extension-identity.d.ts","sourceRoot":"","sources":["../../src/extensions/extension-identity.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EACV,sBAAsB,EACtB,uBAAuB,EACvB,wBAAwB,EACzB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,wBAAwB,EAAE,MAAM,gBAAgB,CAAC;AAE1D;gGACgG;AAChG,eAAO,MAAM,iBAAiB,6KAC8I,CAAC;AAO7K,2FAA2F;AAC3F,OAAO,EAAE,wBAAwB,IAAI,eAAe,EAAE,CAAC;AAEvD,MAAM,WAAW,oBAAoB;IACnC,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,uBAAuB,CAAC,QAAQ,CAAC,CAAC;CAC3C;AAED,MAAM,WAAW,sBAAsB;IACrC,6EAA6E;IAC7E,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,kEAAkE;IAClE,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,kEAAkE;IAClE,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,qDAAqD;IACrD,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAyHD;;;;GAIG;AACH,wBAAgB,wBAAwB,CACtC,OAAO,EAAE,oBAAoB,EAAE,EAC/B,IAAI,GAAE,sBAA2B,GAChC,sBAAsB,CAqBxB;AAED;;;GAGG;AACH,wBAAgB,2BAA2B,CACzC,OAAO,EAAE,MAAM,EACf,IAAI,GAAE,IAAI,CAAC,sBAAsB,EAAE,YAAY,GAAG,KAAK,GAAG,gBAAgB,CAAM,GAC/E,sBAAsB,CAiBxB;AAED,wFAAwF;AACxF,MAAM,WAAW,eAAe;IAC9B,UAAU,EAAE,IAAI,CAAC;IACjB,qFAAqF;IACrF,OAAO,EAAE,KAAK,CAAC;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,aAAa,EAAE,MAAM,CAAC;QAAC,YAAY,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACnF,IAAI,EAAE;QAAE,aAAa,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,MAAM,CAAC;QAAC,iBAAiB,EAAE,OAAO,CAAA;KAAE,CAAC;IAClF,OAAO,CAAC,EAAE,wBAAwB,CAAC;CACpC;AAED,MAAM,WAAW,sBAAsB;IACrC,UAAU,EAAE,KAAK,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,sBAAsB,EAC7B,IAAI,GAAE;IAAE,SAAS,CAAC,EAAE,MAAM,CAAA;CAAO,GAChC,eAAe,GAAG,sBAAsB,CAkC1C"}
@@ -0,0 +1,218 @@
1
+ // extension-identity.ts — PURE fingerprint + compare for extension-code drift evidence
2
+ // (issue #119). This module is STRUCTURALLY incapable of loading code: no dynamic import,
3
+ // no module-require creation, anywhere. It only reads bytes (fs), hashes them (crypto),
4
+ // and manipulates paths — which is exactly why read-only commands (`realm run inspect
5
+ // --check-drift`) may use it without ever gaining the capability to execute project code.
6
+ // A structural test (read-only-no-extensions.test.ts) enforces this.
7
+ import { createHash } from 'node:crypto';
8
+ import { readFileSync, readdirSync } from 'node:fs';
9
+ import { dirname, join, relative, sep } from 'node:path';
10
+ import { extensionIdentityDiffers } from '@sensigo/realm';
11
+ /** The one sweep-rule version this module can compute. Comparison ALWAYS recomputes under
12
+ * the RECORDED rule string — a future rules change must add a new version, never mutate v1. */
13
+ export const DIR_TREE_V1_RULES = 'dir_tree_v1: include .js,.mjs,.cjs,.ts,.mts,.cts,.json; exclude dirs node_modules,.git; skip symlinks; sort by relpath; sha256(relpath\\0filehash); caps 2000 files/50MB';
14
+ const INCLUDED_EXTENSIONS = new Set(['.js', '.mjs', '.cjs', '.ts', '.mts', '.cts', '.json']);
15
+ const EXCLUDED_DIR_NAMES = new Set(['node_modules', '.git']);
16
+ const MAX_FILES = 2000;
17
+ const MAX_TOTAL_BYTES = 50 * 1024 * 1024;
18
+ /** Compares two identity entries — tree_hash + per-module entry hashes + override flag. */
19
+ export { extensionIdentityDiffers as identityDiffers };
20
+ function sha256Hex(data) {
21
+ return createHash('sha256').update(data).digest('hex');
22
+ }
23
+ function fileExtension(path) {
24
+ const base = path.slice(path.lastIndexOf(sep) + 1);
25
+ const dot = base.lastIndexOf('.');
26
+ return dot === -1 ? '' : base.slice(dot);
27
+ }
28
+ /**
29
+ * Deterministically enumerates the relative paths of sweep-eligible files under `root`
30
+ * per dir_tree_v1: included extensions only, `node_modules`/`.git` directories excluded at
31
+ * any depth, symlinks (files and directories) skipped, sorted by relative path.
32
+ * Enumeration is cap-free — caps apply at the hashing stage so the truncated fingerprint
33
+ * covers a DETERMINISTIC prefix of the sorted listing.
34
+ */
35
+ function enumerateTreeFiles(root) {
36
+ const relPaths = [];
37
+ const walk = (dir) => {
38
+ let entries;
39
+ try {
40
+ entries = readdirSync(dir, { withFileTypes: true });
41
+ }
42
+ catch {
43
+ return; // unreadable directory — skipped (deterministic for a given tree state)
44
+ }
45
+ for (const entry of entries) {
46
+ const full = join(dir, entry.name);
47
+ if (entry.isSymbolicLink())
48
+ continue; // dir_tree_v1: symlinks skipped
49
+ if (entry.isDirectory()) {
50
+ if (EXCLUDED_DIR_NAMES.has(entry.name))
51
+ continue;
52
+ walk(full);
53
+ }
54
+ else if (entry.isFile()) {
55
+ if (INCLUDED_EXTENSIONS.has(fileExtension(entry.name))) {
56
+ relPaths.push(relative(root, full));
57
+ }
58
+ }
59
+ }
60
+ };
61
+ walk(root);
62
+ return relPaths.sort();
63
+ }
64
+ /** Hashes the sorted file listing of `roots` under the dir_tree_v1 caps. */
65
+ function sweepTree(roots) {
66
+ // Enumerate everything first (cheap), THEN hash under caps — the truncation point is a
67
+ // deterministic prefix of the sorted listing, so truncated hashes stay comparable.
68
+ const perRoot = roots.map((root) => enumerateTreeFiles(root).map((rel) => ({ root, rel })));
69
+ const allFiles = perRoot.flat();
70
+ const lines = [];
71
+ let totalBytes = 0;
72
+ let truncated = false;
73
+ for (const file of allFiles) {
74
+ if (lines.length >= MAX_FILES || totalBytes >= MAX_TOTAL_BYTES) {
75
+ truncated = true;
76
+ break;
77
+ }
78
+ let bytes;
79
+ try {
80
+ bytes = readFileSync(join(file.root, file.rel));
81
+ }
82
+ catch {
83
+ // File disappeared between enumeration and hashing — record it as unreadable
84
+ // (deterministic for a given tree state; a vanishing file IS a tree change).
85
+ lines.push(`${file.rel}\u0000<unreadable>`);
86
+ continue;
87
+ }
88
+ totalBytes += bytes.length;
89
+ lines.push(`${file.rel}\u0000${sha256Hex(bytes)}`);
90
+ }
91
+ return {
92
+ file_count: lines.length,
93
+ total_bytes: totalBytes,
94
+ tree_hash: sha256Hex(lines.join('\n')),
95
+ truncated,
96
+ };
97
+ }
98
+ /** Advisory signals — each independently fail-soft to undefined; never compared. */
99
+ function collectSignals(trustRoot) {
100
+ if (trustRoot === undefined)
101
+ return undefined;
102
+ const signals = {};
103
+ try {
104
+ const pkg = JSON.parse(readFileSync(join(trustRoot, 'package.json'), 'utf8'));
105
+ if (typeof pkg.version === 'string')
106
+ signals.package_version = pkg.version;
107
+ }
108
+ catch {
109
+ // fail-soft
110
+ }
111
+ try {
112
+ // Read .git/HEAD; dereference ONE ref file. No child processes, ever.
113
+ const head = readFileSync(join(trustRoot, '.git', 'HEAD'), 'utf8').trim();
114
+ if (head.startsWith('ref: ')) {
115
+ const refPath = head.slice('ref: '.length).trim();
116
+ const refValue = readFileSync(join(trustRoot, '.git', refPath), 'utf8').trim();
117
+ if (refValue !== '')
118
+ signals.git_head = refValue;
119
+ }
120
+ else if (head !== '') {
121
+ signals.git_head = head; // detached HEAD — the hash itself
122
+ }
123
+ }
124
+ catch {
125
+ // fail-soft (packed refs, no .git, unreadable — all acceptable)
126
+ }
127
+ return signals.package_version === undefined && signals.git_head === undefined
128
+ ? undefined
129
+ : signals;
130
+ }
131
+ /**
132
+ * Computes the dir_tree_v1 identity of a set of loaded extension modules: per-module
133
+ * sha256 entry hashes plus a deterministic directory-tree fingerprint over the deduped
134
+ * parent directories of the resolved entries. Pure fs + crypto — never loads code.
135
+ */
136
+ export function computeExtensionIdentity(modules, opts = {}) {
137
+ const moduleEntries = modules.map((m) => ({
138
+ declared: m.declared,
139
+ resolved: m.resolved,
140
+ entry_hash: sha256Hex(readFileSync(m.resolved)),
141
+ format: m.format,
142
+ }));
143
+ const roots = [...new Set(modules.map((m) => dirname(m.resolved)))].sort();
144
+ const tree = sweepTree(roots);
145
+ const signals = collectSignals(opts.trustRoot);
146
+ return {
147
+ captured_at: opts.capturedAt ?? new Date().toISOString(),
148
+ pid: opts.pid ?? process.pid,
149
+ modules: moduleEntries,
150
+ tree: { roots, rules: DIR_TREE_V1_RULES, ...tree },
151
+ ...(signals !== undefined ? { signals } : {}),
152
+ coverage: 'dir_tree_v1',
153
+ ...(opts.overrideActive === true ? { override_active: true } : {}),
154
+ };
155
+ }
156
+ /**
157
+ * Builds an identity entry that records a capture/load FAILURE — the failure is itself
158
+ * evidence (WorkflowContextSnapshot.error precedent). Modules/tree are empty placeholders.
159
+ */
160
+ export function errorExtensionIdentityEntry(message, opts = {}) {
161
+ return {
162
+ captured_at: opts.capturedAt ?? new Date().toISOString(),
163
+ pid: opts.pid ?? process.pid,
164
+ modules: [],
165
+ tree: {
166
+ roots: [],
167
+ rules: DIR_TREE_V1_RULES,
168
+ file_count: 0,
169
+ total_bytes: 0,
170
+ tree_hash: '',
171
+ truncated: false,
172
+ },
173
+ coverage: 'dir_tree_v1',
174
+ ...(opts.overrideActive === true ? { override_active: true } : {}),
175
+ error: message,
176
+ };
177
+ }
178
+ /**
179
+ * Recomputes an entry's identity from CURRENT disk state STRICTLY under the entry's
180
+ * RECORDED rules and roots — an unknown rules version yields an explicit cannot-compare
181
+ * rather than a guess (a rules change must never manufacture phantom drift).
182
+ * Pure fs + crypto — never loads code.
183
+ */
184
+ export function recomputeIdentity(entry, opts = {}) {
185
+ if (entry.tree.rules !== DIR_TREE_V1_RULES) {
186
+ return {
187
+ comparable: false,
188
+ reason: `cannot compare (unknown rules '${entry.tree.rules}')`,
189
+ };
190
+ }
191
+ const modules = entry.modules.map((m) => {
192
+ let currentHash;
193
+ try {
194
+ currentHash = sha256Hex(readFileSync(m.resolved));
195
+ }
196
+ catch {
197
+ currentHash = undefined;
198
+ }
199
+ return {
200
+ resolved: m.resolved,
201
+ recorded_hash: m.entry_hash,
202
+ ...(currentHash !== undefined ? { current_hash: currentHash } : {}),
203
+ };
204
+ });
205
+ const tree = sweepTree(entry.tree.roots);
206
+ const signals = collectSignals(opts.trustRoot);
207
+ return {
208
+ comparable: true,
209
+ modules,
210
+ tree: {
211
+ recorded_hash: entry.tree.tree_hash,
212
+ current_hash: tree.tree_hash,
213
+ current_truncated: tree.truncated,
214
+ },
215
+ ...(signals !== undefined ? { signals } : {}),
216
+ };
217
+ }
218
+ //# sourceMappingURL=extension-identity.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"extension-identity.js","sourceRoot":"","sources":["../../src/extensions/extension-identity.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,36 @@
1
+ import { ExtensionRegistry } from '@sensigo/realm';
2
+ import type { ExtensionManifest, WorkflowDefinition } from '@sensigo/realm';
3
+ export interface LoadProjectExtensionsOptions {
4
+ /**
5
+ * Operator-typed module path that REPLACES the workflow's declared extension modules
6
+ * (repair/override tool). Containment does not apply to an operator-typed path.
7
+ */
8
+ overrideModule?: string;
9
+ }
10
+ export interface LoadedProjectExtensions {
11
+ registry: ExtensionRegistry;
12
+ manifest: ExtensionManifest;
13
+ }
14
+ /** @internal Test-only: clears the process-lifetime registry cache. */
15
+ export declare function clearProjectExtensionsCache(): void;
16
+ /**
17
+ * Loads the project extension modules declared by a workflow definition (or an operator
18
+ * override) and returns a registry (defaults + extensions applied) plus a manifest of what
19
+ * was loaded. No `extensions` on the definition and no override → `createDefaultRegistry()`
20
+ * plus an empty manifest — the byte-identical fallback, cached process-wide.
21
+ *
22
+ * Precedence: defaults < legacy env-gated built-ins (applied by `realm agent`, see agent.ts)
23
+ * < declared extensions < --extensions-module override.
24
+ *
25
+ * CONTRACT: returned registries are shared process-lifetime cache entries. The only
26
+ * permitted mutation is `getOrCreateRateLimiter` (serve bucket persistence, by design);
27
+ * any tier composition on top requires `ExtensionRegistry.clone()`.
28
+ */
29
+ export declare function loadProjectExtensions(definition: WorkflowDefinition, opts?: LoadProjectExtensionsOptions): Promise<LoadedProjectExtensions>;
30
+ /**
31
+ * Builds a `registryProvider` for the MCP server (serve / mcp stdio): resolves each
32
+ * definition's extensions through the process-lifetime loader cache. An operator override
33
+ * replaces declared modules for EVERY definition served by this process.
34
+ */
35
+ export declare function makeRegistryProvider(overrideModule?: string): (definition: WorkflowDefinition) => Promise<ExtensionRegistry>;
36
+ //# sourceMappingURL=load-project-extensions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"load-project-extensions.d.ts","sourceRoot":"","sources":["../../src/extensions/load-project-extensions.ts"],"names":[],"mappings":"AAeA,OAAO,EAAyB,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAC1E,OAAO,KAAK,EAAE,iBAAiB,EAAsB,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAGhG,MAAM,WAAW,4BAA4B;IAC3C;;;OAGG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,uBAAuB;IACtC,QAAQ,EAAE,iBAAiB,CAAC;IAC5B,QAAQ,EAAE,iBAAiB,CAAC;CAC7B;AAiBD,uEAAuE;AACvE,wBAAgB,2BAA2B,IAAI,IAAI,CAElD;AA4BD;;;;;;;;;;;;GAYG;AACH,wBAAsB,qBAAqB,CACzC,UAAU,EAAE,kBAAkB,EAC9B,IAAI,CAAC,EAAE,4BAA4B,GAClC,OAAO,CAAC,uBAAuB,CAAC,CA0ElC;AA4SD;;;;GAIG;AACH,wBAAgB,oBAAoB,CAClC,cAAc,CAAC,EAAE,MAAM,GACtB,CAAC,UAAU,EAAE,kBAAkB,KAAK,OAAO,CAAC,iBAAiB,CAAC,CAQhE"}