@aaac/contracts 0.1.13 → 0.1.14

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.
@@ -64,6 +64,14 @@ var GovernanceSchema = z.object({
64
64
  guardrails: z.boolean().optional(),
65
65
  observability: z.boolean().optional()
66
66
  }).optional();
67
+ var BindingRefSchema = z.object({
68
+ /** npm package name implementing the binding (e.g. "@aaac/binding-cursor"). */
69
+ package: z.string().min(1),
70
+ /** CLI command name to expose (defaults to the binding id). */
71
+ command: z.string().optional(),
72
+ /** Binding-specific configuration; validated by the binding package. */
73
+ config: z.record(z.string(), z.unknown()).default({})
74
+ });
67
75
  var ComponentSchema = z.object({
68
76
  schema: z.string().regex(SCHEMA_VERSION_PATTERN, 'schema must match pattern "aaac/x.y"'),
69
77
  info: z.object({
@@ -77,6 +85,7 @@ var ComponentSchema = z.object({
77
85
  z.enum(["library", "cli", "claude", "openai"])
78
86
  ),
79
87
  governance: GovernanceSchema,
88
+ bindings: z.record(z.string(), BindingRefSchema).optional(),
80
89
  operations: z.record(z.string(), OperationSchema)
81
90
  }).superRefine((component, ctx) => {
82
91
  const usesAgentic = Object.values(component.operations).some(
@@ -148,6 +157,7 @@ function normalizeComponent(raw) {
148
157
  embedded_dsl_dir: raw.embedded_dsl_dir,
149
158
  projections: raw.projections,
150
159
  governance: raw.governance,
160
+ bindings: raw.bindings,
151
161
  operations: Object.keys(normalizedOps).length > 0 ? normalizedOps : raw.operations
152
162
  };
153
163
  }
@@ -568,9 +578,21 @@ function compileComponent(dsl, options = {}) {
568
578
  guardrails: dsl.governance.guardrails,
569
579
  observability: dsl.governance.observability
570
580
  } : void 0,
581
+ bindings: dsl.bindings ? compileBindings(dsl.bindings) : void 0,
571
582
  operations
572
583
  };
573
584
  }
585
+ function compileBindings(bindings) {
586
+ const result = {};
587
+ for (const [id, binding] of Object.entries(bindings)) {
588
+ result[id] = {
589
+ package: binding.package,
590
+ command: binding.command ?? id,
591
+ config: binding.config ?? {}
592
+ };
593
+ }
594
+ return result;
595
+ }
574
596
  async function maybeValidateComponent(ir, options) {
575
597
  if (options.validate === false) {
576
598
  return;
@@ -593,6 +615,44 @@ async function compileComponentFile(filePath, options = {}) {
593
615
  return ir;
594
616
  }
595
617
 
618
+ // src/generators/bindings-generator.ts
619
+ var bindingsGenerator = {
620
+ generate(ir, _options) {
621
+ if (!ir.bindings || Object.keys(ir.bindings).length === 0) {
622
+ return [];
623
+ }
624
+ const entries = Object.entries(ir.bindings).map(([id, binding]) => {
625
+ return ` ${JSON.stringify(id)}: {
626
+ package: ${JSON.stringify(binding.package)},
627
+ command: ${JSON.stringify(binding.command)},
628
+ config: ${JSON.stringify(binding.config)},
629
+ },`;
630
+ });
631
+ const content = `// Auto-generated by @aaac/contracts. Do not edit.
632
+
633
+ export interface BindingEntry {
634
+ /** npm package implementing the binding. */
635
+ package: string;
636
+ /** CLI command name exposed for this binding. */
637
+ command: string;
638
+ /** Binding-specific configuration (validated by the binding package). */
639
+ config: Record<string, unknown>;
640
+ }
641
+
642
+ export const bindings: Record<string, BindingEntry> = {
643
+ ${entries.join("\n")}
644
+ };
645
+ `;
646
+ return [
647
+ {
648
+ path: "bindings.generated.ts",
649
+ content,
650
+ overwrite: true
651
+ }
652
+ ];
653
+ }
654
+ };
655
+
596
656
  // src/generators/cli-generator.ts
597
657
  import { stringify as stringifyYaml } from "yaml";
598
658
  function unwrapSchema(ref) {
@@ -878,6 +938,49 @@ function buildPromptCommand() {
878
938
  function countAgenticOperations(ir) {
879
939
  return Object.values(ir.operations).filter((op) => !op.handler).length;
880
940
  }
941
+ function buildBindingCommands(ir) {
942
+ const commands = {};
943
+ if (!ir.bindings) {
944
+ return commands;
945
+ }
946
+ for (const [bindingId, binding] of Object.entries(ir.bindings)) {
947
+ const cmd = binding.command;
948
+ commands[`${cmd}.sync`] = {
949
+ summary: `Materialize ${bindingId} binding output files from the embedded DSL`,
950
+ options: [
951
+ {
952
+ name: "dry-run",
953
+ schema: { type: "boolean" },
954
+ description: "Report changes without writing files"
955
+ }
956
+ ],
957
+ exits: {
958
+ "0": { description: "Synced" },
959
+ "1": { description: "Materialization failed" }
960
+ },
961
+ "x-agent": {
962
+ risk_level: "low",
963
+ requires_confirmation: false,
964
+ idempotent: true,
965
+ binding: bindingId
966
+ }
967
+ };
968
+ commands[`${cmd}.check`] = {
969
+ summary: `Fail if ${bindingId} binding output drifts from the DSL`,
970
+ exits: {
971
+ "0": { description: "In sync" },
972
+ "2": { description: "Drift detected" }
973
+ },
974
+ "x-agent": {
975
+ risk_level: "low",
976
+ requires_confirmation: false,
977
+ idempotent: true,
978
+ binding: bindingId
979
+ }
980
+ };
981
+ }
982
+ return commands;
983
+ }
881
984
  function buildCliContract(ir) {
882
985
  const commands = {};
883
986
  for (const [name, op] of Object.entries(ir.operations)) {
@@ -886,6 +989,7 @@ function buildCliContract(ir) {
886
989
  if (ir.governance?.guardrails === true) {
887
990
  Object.assign(commands, buildGuardCommands());
888
991
  }
992
+ Object.assign(commands, buildBindingCommands(ir));
889
993
  if (countAgenticOperations(ir) >= 2) {
890
994
  commands.prompt = buildPromptCommand();
891
995
  }
@@ -1079,7 +1183,7 @@ var clientGenerator = {
1079
1183
  ctx: AaacInvocationContext,
1080
1184
  memoryRef?: string,
1081
1185
  ): Promise<${names.output}> {
1082
- return runtime.execute(${JSON.stringify(operationName)}, options, input, ctx, memoryRef);
1186
+ return runtime.execute(${JSON.stringify(operationName)}, options, input, ctx, memoryRef) as Promise<${names.output}>;
1083
1187
  }`;
1084
1188
  });
1085
1189
  if (agenticOpsCount >= 2) {
@@ -1088,7 +1192,7 @@ var clientGenerator = {
1088
1192
  input: { message: string },
1089
1193
  ctx: AaacInvocationContext,
1090
1194
  ): Promise<PromptResult> {
1091
- return runtime.executePrompt(input.message, options, ctx) as Promise<PromptResult>;
1195
+ return runtime.executePrompt(input.message, options as unknown as Record<string, unknown>, ctx) as Promise<PromptResult>;
1092
1196
  }`);
1093
1197
  }
1094
1198
  const runtimeTypeImports = agenticOpsCount >= 2 ? `import type { PromptResult, PromptExecuteOptions } from "@aaac/runtime";
@@ -1426,7 +1530,8 @@ var ALL_GENERATORS = [
1426
1530
  runtimeGenerator,
1427
1531
  cliGenerator,
1428
1532
  handlerGenerator,
1429
- embeddedDslGenerator
1533
+ embeddedDslGenerator,
1534
+ bindingsGenerator
1430
1535
  ];
1431
1536
  function generateAll(ir, options) {
1432
1537
  return ALL_GENERATORS.flatMap((gen) => gen.generate(ir, options));
@@ -1463,6 +1568,350 @@ async function writeGeneratedFiles(files, outputDir) {
1463
1568
  return { written, skipped, warnings };
1464
1569
  }
1465
1570
 
1571
+ // src/cli/governance.ts
1572
+ import { createHash } from "crypto";
1573
+ import { existsSync as existsSync2 } from "fs";
1574
+ import { chmod, mkdir as mkdir2, readFile as readFile2, writeFile as writeFile2 } from "fs/promises";
1575
+ import { dirname as dirname5, join as join3, resolve as resolve3 } from "path";
1576
+ import { parse as parseYaml3 } from "yaml";
1577
+ import { z as z2 } from "zod";
1578
+ var MANAGED_BLOCK_START = "# >>> aaac-governance:managed (do not edit) >>>";
1579
+ var MANAGED_BLOCK_END = "# <<< aaac-governance:managed <<<";
1580
+ var GOVERNANCE_LOCK_PATH = ".agent-logs/governance-manifest.lock";
1581
+ var DEFAULT_RECORDER = ".cursor/hooks/observ-record.sh";
1582
+ var DEFAULT_CURSOR_HOOKS_JSON = ".cursor/hooks.json";
1583
+ var DEFAULT_BINARY_DEST = "bin/aaac.js";
1584
+ var CURSOR_HOOKS_VERSION = 1;
1585
+ var EnvironmentsSchema = z2.object({
1586
+ git: z2.object({ hooks: z2.array(z2.string()).optional() }).optional(),
1587
+ cursor: z2.object({ hooks_json: z2.string().optional() }).optional()
1588
+ }).optional();
1589
+ var BindingsObservabilitySchema = z2.object({
1590
+ event_mapping: z2.string().optional(),
1591
+ recorder: z2.string().optional()
1592
+ }).optional();
1593
+ var BindingsSchema = z2.object({
1594
+ observability: BindingsObservabilitySchema,
1595
+ hooks: z2.array(z2.string()).optional()
1596
+ }).optional();
1597
+ var InitProjectConfigSchema = z2.object({
1598
+ environments: EnvironmentsSchema,
1599
+ bindings: BindingsSchema
1600
+ });
1601
+ async function loadInitConfig(configPath) {
1602
+ const absPath = resolve3(configPath);
1603
+ const raw = await readFile2(absPath, "utf8");
1604
+ const parsed = parseYaml3(raw);
1605
+ return InitProjectConfigSchema.parse(parsed ?? {});
1606
+ }
1607
+ var HookCommandSchema = z2.object({
1608
+ command: z2.string(),
1609
+ description: z2.string().optional()
1610
+ });
1611
+ var HookBindingSchema = z2.object({
1612
+ hooks: z2.record(z2.string(), z2.array(HookCommandSchema)).optional()
1613
+ });
1614
+ async function loadHookBindings(projectRoot, bindingPaths) {
1615
+ const result = {};
1616
+ if (!bindingPaths?.length) return result;
1617
+ const root = resolve3(projectRoot);
1618
+ for (const bindingPath of bindingPaths) {
1619
+ const absPath = resolve3(root, bindingPath);
1620
+ if (!existsSync2(absPath)) continue;
1621
+ const raw = await readFile2(absPath, "utf8");
1622
+ const parsed = HookBindingSchema.parse(parseYaml3(raw) ?? {});
1623
+ if (!parsed.hooks) continue;
1624
+ for (const [hookName, commands] of Object.entries(parsed.hooks)) {
1625
+ const list = result[hookName] ?? [];
1626
+ for (const { command } of commands) {
1627
+ if (!list.includes(command)) list.push(command);
1628
+ }
1629
+ result[hookName] = list;
1630
+ }
1631
+ }
1632
+ return result;
1633
+ }
1634
+ function escapeRegex(value) {
1635
+ return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
1636
+ }
1637
+ function createManagedBlockRegex() {
1638
+ return new RegExp(
1639
+ `${escapeRegex(MANAGED_BLOCK_START)}[\\s\\S]*?${escapeRegex(MANAGED_BLOCK_END)}\\n?`,
1640
+ "g"
1641
+ );
1642
+ }
1643
+ function buildManagedBlock(blockContent) {
1644
+ return `${MANAGED_BLOCK_START}
1645
+ ${blockContent.trimEnd()}
1646
+ ${MANAGED_BLOCK_END}
1647
+ `;
1648
+ }
1649
+ function injectManagedBlock(existingContent, blockContent) {
1650
+ const managedBlock = buildManagedBlock(blockContent);
1651
+ const re = createManagedBlockRegex();
1652
+ if (re.test(existingContent)) {
1653
+ return existingContent.replace(createManagedBlockRegex(), managedBlock);
1654
+ }
1655
+ const trimmed = existingContent.replace(/\s+$/, "");
1656
+ if (trimmed.length === 0) {
1657
+ return `#!/bin/sh
1658
+ ${managedBlock}`;
1659
+ }
1660
+ const separator = trimmed.endsWith("\n") ? "" : "\n";
1661
+ return `${trimmed}${separator}${managedBlock}`;
1662
+ }
1663
+ function removeManagedBlock(existingContent) {
1664
+ if (!existingContent.includes(MANAGED_BLOCK_START)) {
1665
+ return existingContent;
1666
+ }
1667
+ const withoutBlock = existingContent.replace(createManagedBlockRegex(), "");
1668
+ const meaningful = withoutBlock.split("\n").filter((line) => {
1669
+ const t = line.trim();
1670
+ return t.length > 0 && t !== "#!/bin/sh" && t !== "#!/bin/bash";
1671
+ });
1672
+ if (meaningful.length === 0) {
1673
+ return "";
1674
+ }
1675
+ return withoutBlock.replace(/\n{3,}/g, "\n\n").replace(/\s+$/, "\n");
1676
+ }
1677
+ function parseCursorHooksFile(raw) {
1678
+ if (!raw || !raw.trim()) {
1679
+ return { version: CURSOR_HOOKS_VERSION, hooks: {} };
1680
+ }
1681
+ const parsed = JSON.parse(raw);
1682
+ if (Array.isArray(parsed)) {
1683
+ return flatEntriesToFile(
1684
+ parsed.filter(
1685
+ (entry) => entry !== null && typeof entry === "object" && typeof entry.event === "string" && typeof entry.command === "string"
1686
+ )
1687
+ );
1688
+ }
1689
+ if (parsed && typeof parsed === "object") {
1690
+ const obj = parsed;
1691
+ const version = typeof obj.version === "number" ? obj.version : CURSOR_HOOKS_VERSION;
1692
+ const hooks = {};
1693
+ const rawHooks = obj.hooks;
1694
+ if (rawHooks && typeof rawHooks === "object" && !Array.isArray(rawHooks)) {
1695
+ for (const [event, commands] of Object.entries(rawHooks)) {
1696
+ if (Array.isArray(commands)) {
1697
+ hooks[event] = commands.filter(
1698
+ (c) => c !== null && typeof c === "object" && typeof c.command === "string"
1699
+ );
1700
+ }
1701
+ }
1702
+ }
1703
+ return { version, hooks };
1704
+ }
1705
+ return { version: CURSOR_HOOKS_VERSION, hooks: {} };
1706
+ }
1707
+ function serializeCursorHooksFile(file) {
1708
+ return JSON.stringify(file, null, 2) + "\n";
1709
+ }
1710
+ function flatEntriesToFile(entries) {
1711
+ return mergeCursorHooks({ version: CURSOR_HOOKS_VERSION, hooks: {} }, entries);
1712
+ }
1713
+ function mergeCursorHooks(existing, newEntries) {
1714
+ const hooks = {};
1715
+ for (const [event, commands] of Object.entries(existing.hooks)) {
1716
+ hooks[event] = commands.map((c) => ({ ...c }));
1717
+ }
1718
+ for (const entry of newEntries) {
1719
+ const { event, ...command } = entry;
1720
+ const list = hooks[event] ?? [];
1721
+ const idx = list.findIndex((c) => c.command === command.command);
1722
+ if (idx >= 0) {
1723
+ list[idx] = command;
1724
+ } else {
1725
+ list.push(command);
1726
+ }
1727
+ hooks[event] = list;
1728
+ }
1729
+ return { version: existing.version ?? CURSOR_HOOKS_VERSION, hooks };
1730
+ }
1731
+ function removeCursorHooks(existing, commands) {
1732
+ const removeSet = new Set(commands);
1733
+ const hooks = {};
1734
+ for (const [event, list] of Object.entries(existing.hooks)) {
1735
+ const filtered = list.filter((c) => !removeSet.has(c.command));
1736
+ if (filtered.length > 0) {
1737
+ hooks[event] = filtered;
1738
+ }
1739
+ }
1740
+ return { version: existing.version ?? CURSOR_HOOKS_VERSION, hooks };
1741
+ }
1742
+ function buildGitHookBlock(hookName, recorder, gateCommands = []) {
1743
+ const lines = [`${recorder} ${hookName} "$@" || true`];
1744
+ for (const command of gateCommands) {
1745
+ lines.push(`${command} || exit 1`);
1746
+ }
1747
+ return lines.join("\n");
1748
+ }
1749
+ function buildDefaultCursorHooks(recorder) {
1750
+ return [
1751
+ { event: "beforeSubmitPrompt", command: `${recorder} beforeSubmitPrompt` },
1752
+ { event: "afterShellExecution", command: `${recorder} afterShellExecution` }
1753
+ ];
1754
+ }
1755
+ async function ensureParentDir(filePath) {
1756
+ await mkdir2(dirname5(filePath), { recursive: true });
1757
+ }
1758
+ async function readTextFileIfExists(filePath) {
1759
+ if (!existsSync2(filePath)) return void 0;
1760
+ return readFile2(filePath, "utf8");
1761
+ }
1762
+ async function writeGovernanceLock(projectRoot, entries) {
1763
+ const lockPath = join3(projectRoot, GOVERNANCE_LOCK_PATH);
1764
+ const lock = {
1765
+ materialized_at: (/* @__PURE__ */ new Date()).toISOString(),
1766
+ entries
1767
+ };
1768
+ await ensureParentDir(lockPath);
1769
+ await writeFile2(lockPath, JSON.stringify(lock, null, 2) + "\n", "utf8");
1770
+ return GOVERNANCE_LOCK_PATH;
1771
+ }
1772
+ async function readGovernanceLock(projectRoot) {
1773
+ const lockPath = join3(projectRoot, GOVERNANCE_LOCK_PATH);
1774
+ if (!existsSync2(lockPath)) return void 0;
1775
+ const raw = await readFile2(lockPath, "utf8");
1776
+ if (!raw.trim()) return void 0;
1777
+ return JSON.parse(raw);
1778
+ }
1779
+ async function materializeHooks(options) {
1780
+ const projectRoot = resolve3(options.projectRoot);
1781
+ const result = { materialized: [], lockEntries: [] };
1782
+ const recorder = options.observabilityBinding?.recorder ?? DEFAULT_RECORDER;
1783
+ if (options.environments.git?.hooks?.length) {
1784
+ for (const hookName of options.environments.git.hooks) {
1785
+ const relPath = join3(".git/hooks", hookName);
1786
+ const absPath = join3(projectRoot, relPath);
1787
+ const blockContent = buildGitHookBlock(
1788
+ hookName,
1789
+ recorder,
1790
+ options.hookCommands?.[hookName]
1791
+ );
1792
+ const existing = await readTextFileIfExists(absPath) ?? "";
1793
+ const updated = injectManagedBlock(existing, blockContent);
1794
+ let action = "unchanged";
1795
+ if (!existsSync2(absPath)) {
1796
+ action = "created";
1797
+ } else if (updated !== existing) {
1798
+ action = "updated";
1799
+ }
1800
+ if (action !== "unchanged") {
1801
+ await ensureParentDir(absPath);
1802
+ await writeFile2(absPath, updated, "utf8");
1803
+ await chmod(absPath, 493);
1804
+ }
1805
+ result.materialized.push({ path: relPath, action });
1806
+ result.lockEntries.push({ path: relPath, type: "git-hook" });
1807
+ }
1808
+ }
1809
+ if (options.environments.cursor) {
1810
+ const rawHooksJsonValue = options.environments.cursor.hooks_json;
1811
+ const hooksJsonPath = rawHooksJsonValue ? resolve3(projectRoot, rawHooksJsonValue) : join3(projectRoot, DEFAULT_CURSOR_HOOKS_JSON);
1812
+ const relPath = hooksJsonPath.startsWith(projectRoot + "/") ? hooksJsonPath.slice(projectRoot.length + 1) : DEFAULT_CURSOR_HOOKS_JSON;
1813
+ const newEntries = buildDefaultCursorHooks(recorder);
1814
+ const existingRaw = await readTextFileIfExists(hooksJsonPath);
1815
+ const existing = parseCursorHooksFile(existingRaw);
1816
+ const merged = mergeCursorHooks(existing, newEntries);
1817
+ const serialized = serializeCursorHooksFile(merged);
1818
+ let action = "unchanged";
1819
+ if (!existsSync2(hooksJsonPath)) {
1820
+ action = "created";
1821
+ } else if (serialized !== existingRaw) {
1822
+ action = "updated";
1823
+ }
1824
+ if (action !== "unchanged") {
1825
+ await ensureParentDir(hooksJsonPath);
1826
+ await writeFile2(hooksJsonPath, serialized, "utf8");
1827
+ }
1828
+ result.materialized.push({ path: relPath, action });
1829
+ result.lockEntries.push({ path: relPath, type: "cursor-hook" });
1830
+ }
1831
+ if (result.lockEntries.length > 0) {
1832
+ const lockExisted = existsSync2(join3(projectRoot, GOVERNANCE_LOCK_PATH));
1833
+ await writeGovernanceLock(projectRoot, result.lockEntries);
1834
+ result.materialized.push({
1835
+ path: GOVERNANCE_LOCK_PATH,
1836
+ action: lockExisted ? "updated" : "created"
1837
+ });
1838
+ result.lockEntries.push({ path: GOVERNANCE_LOCK_PATH, type: "generated" });
1839
+ }
1840
+ return result;
1841
+ }
1842
+ async function unmaterializeHooks(projectRoot, lockEntries) {
1843
+ const root = resolve3(projectRoot);
1844
+ for (const entry of lockEntries) {
1845
+ if (entry.type === "generated") {
1846
+ const absPath = join3(root, entry.path);
1847
+ if (existsSync2(absPath)) {
1848
+ await writeFile2(absPath, "", "utf8");
1849
+ }
1850
+ continue;
1851
+ }
1852
+ if (entry.type === "git-hook") {
1853
+ const absPath = join3(root, entry.path);
1854
+ const existing = await readTextFileIfExists(absPath);
1855
+ if (existing === void 0) continue;
1856
+ const updated = removeManagedBlock(existing);
1857
+ await writeFile2(absPath, updated, "utf8");
1858
+ continue;
1859
+ }
1860
+ if (entry.type === "cursor-hook") {
1861
+ const absPath = join3(root, entry.path);
1862
+ const existingRaw = await readTextFileIfExists(absPath);
1863
+ if (existingRaw === void 0) continue;
1864
+ const existing = parseCursorHooksFile(existingRaw);
1865
+ const commandsToRemove = buildDefaultCursorHooks(DEFAULT_RECORDER).map((h) => h.command);
1866
+ const updated = removeCursorHooks(existing, commandsToRemove);
1867
+ await writeFile2(absPath, serializeCursorHooksFile(updated), "utf8");
1868
+ }
1869
+ }
1870
+ const lockPath = join3(root, GOVERNANCE_LOCK_PATH);
1871
+ if (existsSync2(lockPath)) {
1872
+ await writeFile2(lockPath, "", "utf8");
1873
+ }
1874
+ }
1875
+ async function copyCLIBinary(srcPath, projectRoot, destRelPath = DEFAULT_BINARY_DEST) {
1876
+ const dstPath = join3(projectRoot, destRelPath);
1877
+ const srcContent = await readFile2(srcPath);
1878
+ const srcHash = createHash("sha256").update(srcContent).digest("hex");
1879
+ if (existsSync2(dstPath)) {
1880
+ const dstContent = await readFile2(dstPath);
1881
+ const dstHash = createHash("sha256").update(dstContent).digest("hex");
1882
+ if (srcHash === dstHash) {
1883
+ return { path: destRelPath, action: "unchanged" };
1884
+ }
1885
+ await writeFile2(dstPath, srcContent);
1886
+ await chmod(dstPath, 493);
1887
+ return { path: destRelPath, action: "updated" };
1888
+ }
1889
+ await ensureParentDir(dstPath);
1890
+ await writeFile2(dstPath, srcContent);
1891
+ await chmod(dstPath, 493);
1892
+ return { path: destRelPath, action: "created" };
1893
+ }
1894
+ var SCAFFOLD_PROJECT_YAML = `schema: aaac/project/0.1
1895
+
1896
+ # Uncomment and configure to enable git hook governance:
1897
+ #
1898
+ # environments:
1899
+ # git:
1900
+ # hooks: [pre-commit, pre-push, post-commit]
1901
+ # cursor:
1902
+ # hooks_json: .cursor/hooks.json
1903
+ #
1904
+ # bindings:
1905
+ # observability:
1906
+ # event_mapping: ./bindings/observability.yaml
1907
+ # recorder: aaac-observ
1908
+ # hooks:
1909
+ # # Each file declares gate commands per git hook; a non-zero exit
1910
+ # # blocks the commit/push. Only hooks listed in environments.git.hooks
1911
+ # # are materialized.
1912
+ # - ./bindings/git.yaml
1913
+ `;
1914
+
1466
1915
  export {
1467
1916
  SUPPORTED_SCHEMA_VERSIONS,
1468
1917
  SCHEMA_VERSION_PATTERN,
@@ -1470,6 +1919,7 @@ export {
1470
1919
  OptionSchema,
1471
1920
  ArtifactSlotValueSchema,
1472
1921
  OperationSchema,
1922
+ BindingRefSchema,
1473
1923
  ComponentSchema,
1474
1924
  ComponentParseError,
1475
1925
  parseComponentString,
@@ -1484,12 +1934,24 @@ export {
1484
1934
  compileComponent,
1485
1935
  compileComponentAsync,
1486
1936
  compileComponentFile,
1937
+ bindingsGenerator,
1487
1938
  cliGenerator,
1488
1939
  clientGenerator,
1489
1940
  handlerGenerator,
1490
1941
  runtimeGenerator,
1491
1942
  typesGenerator,
1492
1943
  generateAll,
1493
- writeGeneratedFiles
1944
+ writeGeneratedFiles,
1945
+ GOVERNANCE_LOCK_PATH,
1946
+ loadInitConfig,
1947
+ loadHookBindings,
1948
+ parseCursorHooksFile,
1949
+ serializeCursorHooksFile,
1950
+ mergeCursorHooks,
1951
+ readGovernanceLock,
1952
+ materializeHooks,
1953
+ unmaterializeHooks,
1954
+ copyCLIBinary,
1955
+ SCAFFOLD_PROJECT_YAML
1494
1956
  };
1495
- //# sourceMappingURL=chunk-MWZFJ2VL.js.map
1957
+ //# sourceMappingURL=chunk-JWJLY3HJ.js.map