graphddb 0.8.1 → 0.9.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.js CHANGED
@@ -1,17 +1,19 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  buildBridgeBundle,
4
- buildOperations
5
- } from "./chunk-LAT64YCZ.js";
4
+ buildOperations,
5
+ portableIrDocument,
6
+ renderKeyExprToTemplate
7
+ } from "./chunk-SSVG6NQK.js";
6
8
  import {
7
9
  buildManifest
8
- } from "./chunk-S2NI4PBW.js";
9
- import "./chunk-T44OB5GU.js";
10
- import "./chunk-HNY2EJPV.js";
11
- import "./chunk-L4QRCHRQ.js";
10
+ } from "./chunk-NWTEUWJD.js";
11
+ import "./chunk-XZTA4VJH.js";
12
+ import "./chunk-KOIJ4SNO.js";
13
+ import "./chunk-WOFRHRXY.js";
12
14
  import {
13
15
  MetadataRegistry
14
- } from "./chunk-L2NEDS7U.js";
16
+ } from "./chunk-ZNU7OI5I.js";
15
17
  import {
16
18
  createDefaultLinter
17
19
  } from "./chunk-XTWXMOHD.js";
@@ -540,6 +542,92 @@ var commandDefinitions = {
540
542
  }
541
543
  ]
542
544
  },
545
+ "generate.behaviors": {
546
+ "effects": {
547
+ "risk_level": "low",
548
+ "reads": [
549
+ "ts-definitions"
550
+ ],
551
+ "writes": [
552
+ "generated-code"
553
+ ]
554
+ },
555
+ "options": [
556
+ {
557
+ "name": "lang",
558
+ "schema": {
559
+ "type": "string",
560
+ "enum": [
561
+ "ts",
562
+ "python",
563
+ "go",
564
+ "rust",
565
+ "php"
566
+ ]
567
+ }
568
+ },
569
+ {
570
+ "name": "entry",
571
+ "schema": {
572
+ "type": "string"
573
+ },
574
+ "file": {
575
+ "mode": "read",
576
+ "exists": true,
577
+ "media_type": "application/typescript",
578
+ "encoding": "utf-8"
579
+ }
580
+ },
581
+ {
582
+ "name": "transactions",
583
+ "schema": {
584
+ "type": "string"
585
+ },
586
+ "file": {
587
+ "mode": "read",
588
+ "exists": true,
589
+ "media_type": "application/typescript",
590
+ "encoding": "utf-8"
591
+ }
592
+ },
593
+ {
594
+ "name": "contracts",
595
+ "schema": {
596
+ "type": "string"
597
+ },
598
+ "file": {
599
+ "mode": "read",
600
+ "exists": true,
601
+ "media_type": "application/typescript",
602
+ "encoding": "utf-8"
603
+ }
604
+ },
605
+ {
606
+ "name": "contexts",
607
+ "schema": {
608
+ "type": "string"
609
+ },
610
+ "file": {
611
+ "mode": "read",
612
+ "exists": true,
613
+ "media_type": "application/typescript",
614
+ "encoding": "utf-8"
615
+ }
616
+ },
617
+ {
618
+ "name": "runtime-import",
619
+ "schema": {
620
+ "type": "string"
621
+ }
622
+ },
623
+ {
624
+ "name": "out",
625
+ "schema": {
626
+ "type": "string"
627
+ }
628
+ }
629
+ ]
630
+ },
543
631
  "generate.cloudformation": {
544
632
  "effects": {
545
633
  "risk_level": "low",
@@ -851,8 +939,8 @@ function deriveCommandPolicy(command_id, optionValues) {
851
939
  }
852
940
 
853
941
  // src/generated/contract.ts
854
- var CONTRACT_YAML = "cli_contracts: 0.1.0\n\ninfo:\n title: GraphDDB CLI\n version: 0.1.0\n description: >-\n Contract for the graphddb code-generation CLI. The CLI reads TypeScript\n GraphDDB model + CQRS contract definitions (the single source of truth)\n and emits Python bindings (manifest.json, operations.json, types.py,\n repositories.py, __init__.py) for the Python bridge runtime.\n license:\n name: MIT\n contact:\n name: foo-log-inc\n url: https://github.com/foo-log-inc/graphddb\n\nartifact_slots:\n ts-definitions:\n description: >-\n TypeScript GraphDDB definition modules (entity models + the CQRS\n publishQuery / publishCommand contracts) used as the single source of truth.\n direction: read\n generated-code:\n description: >-\n Generated Python bindings and JSON specs written to the output directory\n (manifest.json, operations.json, types.py, repositories.py, __init__.py).\n direction: write\n ts-app-sources:\n description: >-\n Application TypeScript sources containing `DDBModel.prepare` call sites.\n Read by the prepared-statement build lint; rewritten in place by\n `transform prepared --write` (hoist normalization, issue #206).\n direction: write\n\ncommand_sets:\n graphddb:\n summary: Graph data modeling on DynamoDB \u2014 code generation CLI.\n x-stdin: >-\n No command reads from stdin. All inputs are provided via file options.\n\n commands:\n # \u2500\u2500 generate python \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n generate.python:\n summary: Generate Python bindings from TypeScript GraphDDB definitions.\n description: >-\n Loads the TypeScript entity models and CQRS contract\n definitions, builds the serializable manifest / operations bundle, and\n writes the Python bridge bindings (manifest.json, operations.json,\n types.py, repositories.py, __init__.py) to the output directory.\n Output is deterministic for a given set of inputs.\n usage:\n - graphddb generate python --entry models.ts --contracts contracts.ts --out generated/\n - graphddb generate python --entry definitions.ts --out generated/\n\n effects:\n risk_level: low\n reads:\n - ts-definitions\n writes:\n - generated-code\n\n x-agent:\n recommended_before_use:\n - \"Ensure the TypeScript definitions type-check and lint cleanly.\"\n\n options:\n - name: entry\n aliases: [e]\n required: true\n description: >-\n Entry module that registers the entity models (side-effecting\n import). May also export contracts / contexts / transactions.\n value_name: file\n schema:\n type: string\n file:\n mode: read\n exists: true\n media_type: application/typescript\n encoding: utf-8\n\n - name: transactions\n aliases: [t]\n description: >-\n Module exporting `transactions` (a defineTransactions map).\n Defaults to the entry module when omitted.\n Optional \u2014 a project with no declarative transactions omits it.\n value_name: file\n schema:\n type: string\n file:\n mode: read\n exists: true\n media_type: application/typescript\n encoding: utf-8\n\n - name: contracts\n description: >-\n Module exporting `contracts` (a map of publishQuery /\n publishCommand results \u2014 the CQRS Contract layer). Defaults to\n the entry module when omitted. Optional \u2014 a project with no\n contracts omits it, and the output gains no `contracts` content.\n value_name: file\n schema:\n type: string\n file:\n mode: read\n exists: true\n media_type: application/typescript\n encoding: utf-8\n\n - name: contexts\n description: >-\n Module exporting `contexts` (context-ownership: context name \u2192 the\n Model / Contract names that belong to it). Defaults to the\n contracts module (or the entry module) when omitted. Optional \u2014\n consumed by the boundary lint to tell own from foreign.\n value_name: file\n schema:\n type: string\n file:\n mode: read\n exists: true\n media_type: application/typescript\n encoding: utf-8\n\n - name: dataclass\n description: >-\n Emit Python result / element types as @dataclass classes instead\n of TypedDict (decimal / Optional / Connection mapped accordingly).\n schema:\n type: boolean\n\n - name: out\n aliases: [o]\n required: true\n description: Output directory for the generated Python bindings.\n value_name: dir\n schema:\n type: string\n\n exits:\n '0':\n description: Generation succeeded.\n stdout:\n format: json\n schema:\n $ref: '#/components/schemas/GenerateResult'\n files:\n - path: '{options.out}/manifest.json'\n required: true\n media_type: application/json\n description: Entity / table / key / relation metadata.\n - path: '{options.out}/operations.json'\n required: true\n media_type: application/json\n description: Per-query / per-command execution specs.\n - path: '{options.out}/types.py'\n required: true\n media_type: text/x-python\n description: TypedDict result types derived from query selects.\n - path: '{options.out}/repositories.py'\n required: true\n media_type: text/x-python\n description: Per-entity repository classes (sync methods).\n - path: '{options.out}/__init__.py'\n required: true\n media_type: text/x-python\n description: Package re-exports for the generated bindings.\n\n '1':\n description: Unexpected error.\n stderr:\n format: json\n schema:\n $ref: '#/components/schemas/Error'\n\n '2':\n description: Invalid arguments (missing/unreadable input or output).\n stderr:\n format: json\n schema:\n $ref: '#/components/schemas/Error'\n\n # \u2500\u2500 generate php \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n generate.php:\n summary: >-\n Generate typed PHP bindings (repositories + result DTOs) from\n TypeScript GraphDDB definitions.\n description: >-\n Loads the TypeScript entity models and CQRS contract\n definitions, builds the serializable manifest / operations bundle, and\n writes typed PHP bindings \u2014 one `<Entity>Repository` per entity plus a\n result DTO (and `<Item>Connection`) per query result shape \u2014 into the\n output directory. Each repository wraps the PHP `GraphDDBRuntime`; query\n methods return a hydrated `?<Result>` typed object, command methods\n return void, both calling the runtime by the original operation id. The\n layout is defined by bundled Handlebars templates users can override\n with --template-dir (per-partial) and extend with --helpers; type\n resolution always lives in code (the templates customize layout, not\n types). Output is deterministic for a given set of inputs. The `--typed`\n flag selects the typed-binding output (the only mode today; reserved for\n a future raw-binding mode).\n usage:\n - graphddb generate php --typed --entry models.ts --contracts contracts.ts --out generated/\n - graphddb generate php --typed --entry definitions.ts --out generated/\n - graphddb generate php --typed --entry definitions.ts --out generated/ --template-dir php-templates/ --helpers php-helpers.js\n\n effects:\n risk_level: low\n reads:\n - ts-definitions\n writes:\n - generated-code\n\n x-agent:\n recommended_before_use:\n - \"Ensure the TypeScript definitions type-check and lint cleanly.\"\n\n options:\n - name: entry\n aliases: [e]\n required: true\n description: >-\n Entry module that registers the entity models (side-effecting\n import). May also export contracts / contexts / transactions.\n value_name: file\n schema:\n type: string\n file:\n mode: read\n exists: true\n media_type: application/typescript\n encoding: utf-8\n\n - name: transactions\n aliases: [t]\n description: >-\n Module exporting `transactions` (a defineTransactions map).\n Defaults to the entry module when omitted.\n Optional \u2014 a project with no declarative transactions omits it.\n value_name: file\n schema:\n type: string\n file:\n mode: read\n exists: true\n media_type: application/typescript\n encoding: utf-8\n\n - name: contracts\n description: >-\n Module exporting `contracts` (the CQRS Contract layer). Defaults to\n the entry module when omitted. Optional \u2014 contract-internal\n operations are excluded from the generated binding surface.\n value_name: file\n schema:\n type: string\n file:\n mode: read\n exists: true\n media_type: application/typescript\n encoding: utf-8\n\n - name: contexts\n description: >-\n Module exporting `contexts` (context-ownership). Defaults to the\n contracts module (or the entry module) when omitted. Optional.\n value_name: file\n schema:\n type: string\n file:\n mode: read\n exists: true\n media_type: application/typescript\n encoding: utf-8\n\n - name: typed\n description: >-\n Emit the typed-binding output (repositories + result DTOs). The only\n output mode today; reserved to distinguish a future raw-binding mode.\n schema:\n type: boolean\n\n - name: template-dir\n description: >-\n Directory of override <partial>.hbs templates. Each same-named\n partial (file / dto-class / connection-class / repo-class /\n repo-method / tx-class / tx-method) overrides the bundled one;\n absent partials fall back to the bundled default. Layout only \u2014 type\n resolution always lives in code.\n value_name: dir\n schema:\n type: string\n\n - name: helpers\n description: >-\n JS module whose default (or named `helpers`) export is a map of\n extra Handlebars helpers to register alongside the built-in set.\n value_name: file\n schema:\n type: string\n\n - name: out\n aliases: [o]\n required: true\n description: Output directory for the generated PHP bindings.\n value_name: dir\n schema:\n type: string\n\n exits:\n '0':\n description: Generation succeeded.\n stdout:\n format: json\n schema:\n $ref: '#/components/schemas/GenerateResult'\n\n '1':\n description: Unexpected error.\n stderr:\n format: json\n schema:\n $ref: '#/components/schemas/Error'\n\n '2':\n description: Invalid arguments (missing/unreadable input or output).\n stderr:\n format: json\n schema:\n $ref: '#/components/schemas/Error'\n\n # \u2500\u2500 generate rust \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n generate.rust:\n summary: >-\n Generate typed Rust bindings (repositories + serde result structs) from\n TypeScript GraphDDB definitions.\n description: >-\n Loads the TypeScript entity models and CQRS contract\n definitions, builds the serializable manifest / operations bundle, and\n writes a single `bindings.rs` module of typed Rust bindings \u2014 a\n serde-`Deserialize` result struct (and `<Item>Connection`) per query\n result shape plus one `<Entity>Repository` per entity \u2014 into the output\n directory. Each repository holds an `Arc<GraphDDBRuntime>`; query methods\n return `Result<Option<T>, GraphDDBError>` (the deserialized typed\n result), command methods return `Result<(), GraphDDBError>`, both calling\n the runtime by the original operation id. The layout is defined by\n bundled Handlebars templates users can override with --template-dir\n (per-partial) and extend with --helpers; type resolution always lives in\n code (the templates customize layout, not types). Output is deterministic\n for a given set of inputs. The `--typed` flag selects the typed-binding\n output (the only mode today; reserved for a future raw-binding mode).\n usage:\n - graphddb generate rust --typed --entry models.ts --contracts contracts.ts --out generated/\n - graphddb generate rust --typed --entry definitions.ts --out generated/\n - graphddb generate rust --typed --entry definitions.ts --out generated/ --template-dir rust-templates/ --helpers rust-helpers.js\n\n effects:\n risk_level: low\n reads:\n - ts-definitions\n writes:\n - generated-code\n\n x-agent:\n recommended_before_use:\n - \"Ensure the TypeScript definitions type-check and lint cleanly.\"\n\n options:\n - name: entry\n aliases: [e]\n required: true\n description: >-\n Entry module that registers the entity models (side-effecting\n import). May also export contracts / contexts / transactions.\n value_name: file\n schema:\n type: string\n file:\n mode: read\n exists: true\n media_type: application/typescript\n encoding: utf-8\n\n - name: transactions\n aliases: [t]\n description: >-\n Module exporting `transactions` (a defineTransactions map).\n Defaults to the entry module when omitted.\n Optional \u2014 a project with no declarative transactions omits it.\n value_name: file\n schema:\n type: string\n file:\n mode: read\n exists: true\n media_type: application/typescript\n encoding: utf-8\n\n - name: contracts\n description: >-\n Module exporting `contracts` (the CQRS Contract layer). Defaults to\n the entry module when omitted. Optional \u2014 contract-internal\n operations are excluded from the generated binding surface.\n value_name: file\n schema:\n type: string\n file:\n mode: read\n exists: true\n media_type: application/typescript\n encoding: utf-8\n\n - name: contexts\n description: >-\n Module exporting `contexts` (context-ownership). Defaults to the\n contracts module (or the entry module) when omitted. Optional.\n value_name: file\n schema:\n type: string\n file:\n mode: read\n exists: true\n media_type: application/typescript\n encoding: utf-8\n\n - name: typed\n description: >-\n Emit the typed-binding output (repositories + result structs). The\n only output mode today; reserved to distinguish a future raw-binding\n mode.\n schema:\n type: boolean\n\n - name: template-dir\n description: >-\n Directory of override <partial>.hbs templates. Each same-named\n partial (file / result-struct / connection-struct / repo-struct /\n repo-method / tx-struct / tx-method) overrides the bundled one;\n absent partials fall back to the bundled default. Layout only \u2014 type\n resolution always lives in code.\n value_name: dir\n schema:\n type: string\n\n - name: helpers\n description: >-\n JS module whose default (or named `helpers`) export is a map of\n extra Handlebars helpers to register alongside the built-in set.\n value_name: file\n schema:\n type: string\n\n - name: out\n aliases: [o]\n required: true\n description: Output directory for the generated Rust bindings.\n value_name: dir\n schema:\n type: string\n\n exits:\n '0':\n description: Generation succeeded.\n stdout:\n format: json\n schema:\n $ref: '#/components/schemas/GenerateResult'\n\n '1':\n description: Unexpected error.\n stderr:\n format: json\n schema:\n $ref: '#/components/schemas/Error'\n\n '2':\n description: Invalid arguments (missing/unreadable input or output).\n stderr:\n format: json\n schema:\n $ref: '#/components/schemas/Error'\n\n # \u2500\u2500 generate go \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n generate.go:\n summary: >-\n Generate typed Go bindings (repositories + json result structs) from\n TypeScript GraphDDB definitions.\n description: >-\n Loads the TypeScript entity models and CQRS contract\n definitions, builds the serializable manifest / operations bundle, and\n writes a single `bindings.go` package of typed Go bindings \u2014 a json result\n struct (and `<Item>Connection`) per query result shape plus one\n `<Entity>Repository` per entity \u2014 into the output directory. Each\n repository holds a `*graphddb_runtime.GraphDDBRuntime`; query methods\n return `(*T, error)` (the deserialized typed result; a nil pointer for no\n match), command methods return `error`, both calling the runtime by the\n original operation id. Numbers are precision-strict (`json.Number`), so a\n large integer round-trips losslessly. The layout is defined by bundled\n Handlebars templates users can override with --template-dir (per-partial)\n and extend with --helpers; type resolution always lives in code (the\n templates customize layout, not types). Output is deterministic for a\n given set of inputs and gofmt-normalized. The `--typed` flag selects the\n typed-binding output (the only mode today; reserved for a future\n raw-binding mode).\n usage:\n - graphddb generate go --typed --entry models.ts --contracts contracts.ts --out generated/\n - graphddb generate go --typed --entry definitions.ts --out generated/\n - graphddb generate go --typed --entry definitions.ts --out generated/ --template-dir go-templates/ --helpers go-helpers.js\n\n effects:\n risk_level: low\n reads:\n - ts-definitions\n writes:\n - generated-code\n\n x-agent:\n recommended_before_use:\n - \"Ensure the TypeScript definitions type-check and lint cleanly.\"\n\n options:\n - name: entry\n aliases: [e]\n required: true\n description: >-\n Entry module that registers the entity models (side-effecting\n import). May also export contracts / contexts / transactions.\n value_name: file\n schema:\n type: string\n file:\n mode: read\n exists: true\n media_type: application/typescript\n encoding: utf-8\n\n - name: transactions\n aliases: [t]\n description: >-\n Module exporting `transactions` (a defineTransactions map).\n Defaults to the entry module when omitted.\n Optional \u2014 a project with no declarative transactions omits it.\n value_name: file\n schema:\n type: string\n file:\n mode: read\n exists: true\n media_type: application/typescript\n encoding: utf-8\n\n - name: contracts\n description: >-\n Module exporting `contracts` (the CQRS Contract layer). Defaults to\n the entry module when omitted. Optional \u2014 contract-internal\n operations are excluded from the generated binding surface.\n value_name: file\n schema:\n type: string\n file:\n mode: read\n exists: true\n media_type: application/typescript\n encoding: utf-8\n\n - name: contexts\n description: >-\n Module exporting `contexts` (context-ownership). Defaults to the\n contracts module (or the entry module) when omitted. Optional.\n value_name: file\n schema:\n type: string\n file:\n mode: read\n exists: true\n media_type: application/typescript\n encoding: utf-8\n\n - name: typed\n description: >-\n Emit the typed-binding output (repositories + result structs). The\n only output mode today; reserved to distinguish a future raw-binding\n mode.\n schema:\n type: boolean\n\n - name: template-dir\n description: >-\n Directory of override <partial>.hbs templates. Each same-named\n partial (file / result-struct / connection-struct / repo-struct /\n repo-method / tx-struct / tx-method) overrides the bundled one;\n absent partials fall back to the bundled default. Layout only \u2014 type\n resolution always lives in code.\n value_name: dir\n schema:\n type: string\n\n - name: helpers\n description: >-\n JS module whose default (or named `helpers`) export is a map of\n extra Handlebars helpers to register alongside the built-in set.\n value_name: file\n schema:\n type: string\n\n - name: out\n aliases: [o]\n required: true\n description: Output directory for the generated Go bindings.\n value_name: dir\n schema:\n type: string\n\n exits:\n '0':\n description: Generation succeeded.\n stdout:\n format: json\n schema:\n $ref: '#/components/schemas/GenerateResult'\n\n '1':\n description: Unexpected error.\n stderr:\n format: json\n schema:\n $ref: '#/components/schemas/Error'\n\n '2':\n description: Invalid arguments (missing/unreadable input or output).\n stderr:\n format: json\n schema:\n $ref: '#/components/schemas/Error'\n\n # \u2500\u2500 generate cloudformation \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n generate.cloudformation:\n summary: >-\n Generate an AWS CloudFormation template (DynamoDB table + GSIs) from\n TypeScript GraphDDB definitions.\n description: >-\n Loads the TypeScript entity models and builds the serializable\n manifest, then emits an AWS CloudFormation template describing the\n DynamoDB table(s) the single-table design maps onto: one\n `AWS::DynamoDB::Table` per physical table, with the base key schema\n (`PK` / `SK`), the unioned Global Secondary Indexes\n (`<indexName>PK` / `<indexName>SK`), `PAY_PER_REQUEST` billing, a\n `TableName` parameter (default = physical name), and Outputs\n (table name + ARN). Output is deterministic and, by default, YAML.\n usage:\n - graphddb generate cloudformation --entry models.ts --out table.yaml\n - graphddb generate cloudformation --entry models.ts --format json\n - graphddb generate cloudformation --entry models.ts --gsi-projection KEYS_ONLY --out table.yaml\n - graphddb generate cloudformation --entry models.ts --stream on --out table.yaml\n - graphddb generate cloudformation --entry models.ts --pitr --sse --table-class STANDARD_INFREQUENT_ACCESS --out table.yaml\n - graphddb generate cloudformation --entry models.ts --billing-mode PROVISIONED --rcu 10 --wcu 5 --out table.yaml\n - graphddb generate cloudformation --entry models.ts --billing-mode PROVISIONED --autoscale --autoscale-min 5 --autoscale-max 100 --autoscale-target 70 --out table.yaml\n\n effects:\n risk_level: low\n reads:\n - ts-definitions\n writes:\n - generated-code\n\n x-agent:\n recommended_before_use:\n - \"Ensure the TypeScript definitions type-check and lint cleanly.\"\n\n options:\n - name: entry\n aliases: [e]\n required: true\n description: >-\n Entry module that registers the entity models (side-effecting\n import).\n value_name: file\n schema:\n type: string\n file:\n mode: read\n exists: true\n media_type: application/typescript\n encoding: utf-8\n\n - name: out\n aliases: [o]\n description: >-\n Output file for the generated CloudFormation template. Written to\n stdout when omitted.\n value_name: file\n schema:\n type: string\n\n - name: format\n aliases: [f]\n description: Output serialization format (yaml or json).\n value_name: format\n schema:\n type: string\n enum: [yaml, json]\n default: yaml\n\n - name: gsi-projection\n description: >-\n GSI ProjectionType. ALL (default) projects every attribute;\n KEYS_ONLY projects only the key attributes.\n value_name: projection\n schema:\n type: string\n enum: [ALL, KEYS_ONLY]\n default: ALL\n\n - name: stream\n description: >-\n DynamoDB Streams (StreamSpecification NEW_AND_OLD_IMAGES) emission.\n auto (default) emits a stream only when the model set uses\n stream-based maintenance (updateMode:'stream'); on always emits;\n off never emits. When enabled, a StreamArn Output is added too.\n value_name: mode\n schema:\n type: string\n enum: [auto, on, off]\n default: auto\n\n - name: billing-mode\n description: >-\n DynamoDB billing mode. PAY_PER_REQUEST (default) is on-demand\n (no provisioned throughput). PROVISIONED emits BillingMode:\n PROVISIONED with ProvisionedThroughput (see --rcu / --wcu) on the\n table and every GSI, and unlocks Application Auto Scaling\n (--autoscale).\n value_name: mode\n schema:\n type: string\n enum: [PAY_PER_REQUEST, PROVISIONED]\n default: PAY_PER_REQUEST\n\n - name: rcu\n description: >-\n Provisioned ReadCapacityUnits (a positive integer) applied to the\n table and every GSI. Only valid with --billing-mode PROVISIONED\n (rejected with PAY_PER_REQUEST). Defaults to 5 when omitted.\n value_name: units\n schema:\n type: integer\n minimum: 1\n\n - name: wcu\n description: >-\n Provisioned WriteCapacityUnits (a positive integer) applied to the\n table and every GSI. Only valid with --billing-mode PROVISIONED\n (rejected with PAY_PER_REQUEST). Defaults to 5 when omitted.\n value_name: units\n schema:\n type: integer\n minimum: 1\n\n - name: autoscale\n description: >-\n Enable Application Auto Scaling. Emits an\n AWS::ApplicationAutoScaling::ScalableTarget +\n AWS::ApplicationAutoScaling::ScalingPolicy pair for the table read\n and write capacity AND for each GSI read and write capacity. Only\n valid with --billing-mode PROVISIONED (autoscaling is invalid on\n on-demand and is rejected). Off by default \u2014 no autoscaling\n resources are emitted unless this flag is passed.\n schema:\n type: boolean\n\n - name: autoscale-min\n description: >-\n Auto Scaling minimum capacity (MinCapacity) for every scalable\n target. Must be <= --autoscale-max. Only meaningful with\n --autoscale. Defaults to 5 when omitted.\n value_name: units\n schema:\n type: integer\n minimum: 1\n\n - name: autoscale-max\n description: >-\n Auto Scaling maximum capacity (MaxCapacity) for every scalable\n target. Must be >= --autoscale-min. Only meaningful with\n --autoscale. Defaults to 100 when omitted.\n value_name: units\n schema:\n type: integer\n minimum: 1\n\n - name: autoscale-target\n description: >-\n Auto Scaling target utilization percentage (TargetValue of the\n TargetTrackingScaling policy). Only meaningful with --autoscale.\n Defaults to 70 when omitted.\n value_name: percent\n schema:\n type: integer\n minimum: 1\n maximum: 100\n\n - name: pitr\n description: >-\n Enable point-in-time recovery (PointInTimeRecoverySpecification\n PointInTimeRecoveryEnabled:true). Off by default \u2014 the property is\n omitted entirely unless this flag is passed.\n schema:\n type: boolean\n\n - name: table-class\n description: >-\n DynamoDB table class. Omitted by default (AWS defaults to\n STANDARD); pass STANDARD or STANDARD_INFREQUENT_ACCESS to emit\n TableClass.\n value_name: class\n schema:\n type: string\n enum: [STANDARD, STANDARD_INFREQUENT_ACCESS]\n\n - name: sse\n description: >-\n Enable server-side encryption with the AWS-owned/managed key\n (SSESpecification SSEEnabled:true). Off by default \u2014 the property is\n omitted entirely unless this flag is passed.\n schema:\n type: boolean\n\n exits:\n '0':\n description: Generation succeeded.\n stdout:\n format: json\n schema:\n $ref: '#/components/schemas/GenerateResult'\n\n '1':\n description: Unexpected error.\n stderr:\n format: json\n schema:\n $ref: '#/components/schemas/Error'\n\n '2':\n description: Invalid arguments (missing/unreadable input or output).\n stderr:\n format: json\n schema:\n $ref: '#/components/schemas/Error'\n\n # \u2500\u2500 generate docs \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n generate.docs:\n summary: >-\n Generate model-specification documentation (Markdown + Mermaid) from\n TypeScript GraphDDB definitions.\n description: >-\n Loads the TypeScript entity models (and, optionally, the CQRS contract\n definitions), builds the serializable manifest / operations bundle, then\n renders human-facing model documentation \u2014 Table Overview, Entity\n Relationship Diagram, Physical Key Schema, Property Matrix, Entity\n Details, Access Patterns, Mutation Contracts, Maintained Access Paths,\n CDC, and CloudFormation summary \u2014 as Markdown with Mermaid diagrams. The\n layout is defined by bundled Handlebars templates users can override with\n --template-dir (per-partial) and extend with --helpers. Output is\n deterministic for a given set of inputs.\n usage:\n - graphddb generate docs --entry models.ts --out doc.md\n - graphddb generate docs --entry models.ts --contracts contracts.ts --out doc.md\n - graphddb generate docs --entry models.ts --out docs/\n - graphddb generate docs --entry models.ts --out docs/ --template-dir doc-templates/ --helpers doc-helpers.js\n\n effects:\n risk_level: low\n reads:\n - ts-definitions\n writes:\n - generated-code\n\n x-agent:\n recommended_before_use:\n - \"Ensure the TypeScript definitions type-check and lint cleanly.\"\n\n options:\n - name: entry\n aliases: [e]\n required: true\n description: >-\n Entry module that registers the entity models (side-effecting\n import). May also export contracts / contexts / transactions.\n value_name: file\n schema:\n type: string\n file:\n mode: read\n exists: true\n media_type: application/typescript\n encoding: utf-8\n\n - name: contracts\n description: >-\n Module exporting `contracts` (a map of publishQuery /\n publishCommand results \u2014 the CQRS Contract layer) used for the\n Access Patterns / Mutation Contracts sections. Defaults to the\n entry module when omitted. Optional.\n value_name: file\n schema:\n type: string\n file:\n mode: read\n exists: true\n media_type: application/typescript\n encoding: utf-8\n\n - name: contexts\n description: >-\n Module exporting `contexts` (context-ownership). Defaults to the\n contracts module (or the entry module) when omitted. Optional.\n value_name: file\n schema:\n type: string\n file:\n mode: read\n exists: true\n media_type: application/typescript\n encoding: utf-8\n\n - name: out\n aliases: [o]\n required: true\n description: >-\n Output path for the generated documentation. A file path ending in\n .md writes the single Markdown file at exactly that path (creating\n parent directories); any other value is treated as a directory and\n the file is written as <dir>/index.md.\n value_name: path\n schema:\n type: string\n\n - name: format\n aliases: [f]\n description: Output format. Only markdown is supported today.\n value_name: format\n schema:\n type: string\n enum: [markdown]\n default: markdown\n\n - name: split\n description: >-\n Output granularity. none (default) emits a single index.md; entity\n is reserved for a future per-entity split.\n value_name: mode\n schema:\n type: string\n enum: [none, entity]\n default: none\n\n - name: template-dir\n description: >-\n Directory of override <partial>.hbs templates. Each same-named\n partial (index / table-overview / er-diagram / key-schema /\n property-matrix / entity / access-pattern / maintained / cdc /\n cloudformation) overrides the bundled one; absent partials fall back\n to the bundled default.\n value_name: dir\n schema:\n type: string\n\n - name: helpers\n description: >-\n JS module whose default (or named `helpers`) export is a map of extra\n Handlebars helpers to register alongside the built-in set (eq / join\n / pascal / mermaidId / codeOrEmpty).\n value_name: file\n schema:\n type: string\n\n - name: billing-mode\n description: >-\n DynamoDB billing mode used in the Table Overview (shared with\n generate cloudformation). PAY_PER_REQUEST (default) or PROVISIONED.\n value_name: mode\n schema:\n type: string\n enum: [PAY_PER_REQUEST, PROVISIONED]\n default: PAY_PER_REQUEST\n\n - name: stream\n description: >-\n DynamoDB Streams state used in the Table Overview (shared with\n generate cloudformation). auto (default) detects stream-based\n maintenance (updateMode:'stream'); on always enabled; off never.\n value_name: mode\n schema:\n type: string\n enum: [auto, on, off]\n default: auto\n\n exits:\n '0':\n description: Generation succeeded.\n stdout:\n format: json\n schema:\n $ref: '#/components/schemas/GenerateResult'\n\n '1':\n description: Unexpected error.\n stderr:\n format: json\n schema:\n $ref: '#/components/schemas/Error'\n\n '2':\n description: Invalid arguments (missing/unreadable input or output).\n stderr:\n format: json\n schema:\n $ref: '#/components/schemas/Error'\n\n # \u2500\u2500 transform prepared \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n transform.prepared:\n summary: >-\n Lint and hoist-normalize `DDBModel.prepare` call sites (compile-time\n prepared statements, issue #206).\n description: >-\n A source-to-source build pass over application TypeScript files. It\n statically enforces the prepared-statement no-runtime-capture rule\n (a prepare body may reference only its `$` placeholder and\n module-static bindings; capturing a per-call runtime value \u2014 directly\n or via a helper call \u2014 is a loud error), and normalizes every\n verified INLINE `DDBModel.prepare(fn)` call site into a module-scope\n prepared slot so the plan compiles once per module and each call is\n a plain `.execute` (zero per-op planning / hashing \u2014 placement\n independent). Without --write it is a pure check (the build lint):\n violations exit non-zero and hoistable inline call sites are\n reported as notes. With --write, verified inline call sites are\n rewritten in place; files with violations are never rewritten.\n Idempotent: re-running on transformed output changes nothing.\n With --aot <artifact> (issue #208), the pass additionally compiles\n every verified prepare body at BUILD time into a static prepared-plan\n artifact (a generated TypeScript module): with --write it writes the\n artifact and rewrites each call site to load its static plan\n (`loadPreparedPlan(document, id, body)` \u2014 the body stays in source as\n the plan's compile source and fallback); without --write it is the\n DRIFT CHECK \u2014 it recompiles every plan and exits non-zero when the\n artifact is missing or differs (CI gate: model declarations changed\n without regenerating the artifact).\n usage:\n - graphddb transform prepared --src src/\n - graphddb transform prepared --src src/ --write\n - graphddb transform prepared --src src/app/handlers.ts --write\n - graphddb transform prepared --src src/ --aot src/graphddb.prepared.ts --write\n - graphddb transform prepared --src src/ --aot src/graphddb.prepared.ts\n\n effects:\n risk_level: medium\n reads:\n - ts-app-sources\n writes:\n - ts-app-sources\n\n x-agent:\n recommended_before_use:\n - \"Commit or stash pending changes first when using --write (it rewrites sources in place).\"\n\n options:\n - name: src\n aliases: [s]\n required: true\n description: >-\n A TypeScript source file, or a directory scanned recursively for\n .ts/.tsx/.mts/.cts files (node_modules, dist, hidden directories,\n and .d.ts files are skipped).\n value_name: path\n schema:\n type: string\n file:\n mode: read\n exists: true\n\n - name: write\n aliases: [w]\n description: >-\n Rewrite verified inline call sites in place (hoist\n normalization). Without it the command only checks and reports.\n schema:\n type: boolean\n\n - name: aot\n aliases: [a]\n description: >-\n Static prepared-plan artifact module path (issue #208). Enables\n build-time (AOT) compilation of every verified prepare body:\n with --write the artifact module is (re)generated and call sites\n are rewritten to load their static plan; without --write the\n pass recompiles and compares (drift check \u2014 a missing or\n differing artifact exits 1).\n value_name: artifact\n schema:\n type: string\n\n exits:\n '0':\n description: >-\n Check passed / transform applied. No no-runtime-capture\n violations were found.\n stdout:\n format: json\n schema:\n $ref: '#/components/schemas/TransformPreparedResult'\n\n '1':\n description: >-\n No-runtime-capture violations found, or --aot drift detected\n (reported in the result on stdout), or an unexpected error\n (reported on stderr).\n stdout:\n format: json\n schema:\n $ref: '#/components/schemas/TransformPreparedResult'\n\n '2':\n description: Invalid arguments (missing/unreadable input).\n stderr:\n format: json\n schema:\n $ref: '#/components/schemas/Error'\n\ncomponents:\n schemas:\n GenerateResult:\n type: object\n required: [status, outDir, files]\n properties:\n status:\n type: string\n enum: [ok]\n outDir:\n type: string\n description: Output directory the files were written to.\n files:\n type: array\n description: Paths of the generated files (relative to outDir).\n items:\n type: string\n Error:\n type: object\n required: [code, message]\n properties:\n code:\n type: string\n message:\n type: string\n TransformPreparedResult:\n type: object\n required: [status, files, hoisted, moduleScope, alreadyHoisted, errors, diagnostics]\n properties:\n status:\n type: string\n enum: [ok, violations, drift]\n files:\n type: array\n description: Source files scanned.\n items:\n type: string\n changedFiles:\n type: array\n description: Files rewritten in place (--write only).\n items:\n type: string\n hoisted:\n type: integer\n description: Inline call sites normalized (or normalizable in check mode).\n moduleScope:\n type: integer\n description: Call sites already evaluated once per module load (left as-is).\n alreadyHoisted:\n type: integer\n description: Call sites already normalized by a previous run.\n errors:\n type: integer\n description: No-runtime-capture violations found.\n artifact:\n type: string\n description: The static prepared-plan artifact path (--aot only).\n plans:\n type: integer\n description: Prepared plans compiled into the artifact (--aot only).\n drift:\n type: object\n description: >-\n Artifact drift detail (--aot check mode only; present when status\n is drift).\n properties:\n missing:\n type: boolean\n description: The artifact module does not exist.\n added:\n type: array\n items:\n type: string\n removed:\n type: array\n items:\n type: string\n changed:\n type: array\n items:\n type: string\n diagnostics:\n type: array\n description: Per-position lint diagnostics (errors and notes).\n items:\n type: object\n required: [code, category, message, file, line, column]\n properties:\n code:\n type: string\n category:\n type: string\n enum: [error, note]\n message:\n type: string\n file:\n type: string\n line:\n type: integer\n column:\n type: integer\n";
855
- var CONTRACT_JSON_STR = '{\n "cli_contracts": "0.1.0",\n "info": {\n "title": "GraphDDB CLI",\n "version": "0.1.0",\n "description": "Contract for the graphddb code-generation CLI. The CLI reads TypeScript GraphDDB model + CQRS contract definitions (the single source of truth) and emits Python bindings (manifest.json, operations.json, types.py, repositories.py, __init__.py) for the Python bridge runtime.",\n "license": {\n "name": "MIT"\n },\n "contact": {\n "name": "foo-log-inc",\n "url": "https://github.com/foo-log-inc/graphddb"\n }\n },\n "artifact_slots": {\n "ts-definitions": {\n "description": "TypeScript GraphDDB definition modules (entity models + the CQRS publishQuery / publishCommand contracts) used as the single source of truth.",\n "direction": "read"\n },\n "generated-code": {\n "description": "Generated Python bindings and JSON specs written to the output directory (manifest.json, operations.json, types.py, repositories.py, __init__.py).",\n "direction": "write"\n },\n "ts-app-sources": {\n "description": "Application TypeScript sources containing `DDBModel.prepare` call sites. Read by the prepared-statement build lint; rewritten in place by `transform prepared --write` (hoist normalization, issue #206).",\n "direction": "write"\n }\n },\n "command_sets": {\n "graphddb": {\n "summary": "Graph data modeling on DynamoDB \u2014 code generation CLI.",\n "x-stdin": "No command reads from stdin. All inputs are provided via file options.",\n "commands": {\n "generate.python": {\n "summary": "Generate Python bindings from TypeScript GraphDDB definitions.",\n "description": "Loads the TypeScript entity models and CQRS contract definitions, builds the serializable manifest / operations bundle, and writes the Python bridge bindings (manifest.json, operations.json, types.py, repositories.py, __init__.py) to the output directory. Output is deterministic for a given set of inputs.",\n "usage": [\n "graphddb generate python --entry models.ts --contracts contracts.ts --out generated/",\n "graphddb generate python --entry definitions.ts --out generated/"\n ],\n "effects": {\n "risk_level": "low",\n "reads": [\n "ts-definitions"\n ],\n "writes": [\n "generated-code"\n ]\n },\n "x-agent": {\n "recommended_before_use": [\n "Ensure the TypeScript definitions type-check and lint cleanly."\n ]\n },\n "options": [\n {\n "name": "entry",\n "aliases": [\n "e"\n ],\n "required": true,\n "description": "Entry module that registers the entity models (side-effecting import). May also export contracts / contexts / transactions.",\n "value_name": "file",\n "schema": {\n "type": "string"\n },\n "file": {\n "mode": "read",\n "exists": true,\n "media_type": "application/typescript",\n "encoding": "utf-8"\n }\n },\n {\n "name": "transactions",\n "aliases": [\n "t"\n ],\n "description": "Module exporting `transactions` (a defineTransactions map). Defaults to the entry module when omitted. Optional \u2014 a project with no declarative transactions omits it.",\n "value_name": "file",\n "schema": {\n "type": "string"\n },\n "file": {\n "mode": "read",\n "exists": true,\n "media_type": "application/typescript",\n "encoding": "utf-8"\n }\n },\n {\n "name": "contracts",\n "description": "Module exporting `contracts` (a map of publishQuery / publishCommand results \u2014 the CQRS Contract layer). Defaults to the entry module when omitted. Optional \u2014 a project with no contracts omits it, and the output gains no `contracts` content.",\n "value_name": "file",\n "schema": {\n "type": "string"\n },\n "file": {\n "mode": "read",\n "exists": true,\n "media_type": "application/typescript",\n "encoding": "utf-8"\n }\n },\n {\n "name": "contexts",\n "description": "Module exporting `contexts` (context-ownership: context name \u2192 the Model / Contract names that belong to it). Defaults to the contracts module (or the entry module) when omitted. Optional \u2014 consumed by the boundary lint to tell own from foreign.",\n "value_name": "file",\n "schema": {\n "type": "string"\n },\n "file": {\n "mode": "read",\n "exists": true,\n "media_type": "application/typescript",\n "encoding": "utf-8"\n }\n },\n {\n "name": "dataclass",\n "description": "Emit Python result / element types as @dataclass classes instead of TypedDict (decimal / Optional / Connection mapped accordingly).",\n "schema": {\n "type": "boolean"\n }\n },\n {\n "name": "out",\n "aliases": [\n "o"\n ],\n "required": true,\n "description": "Output directory for the generated Python bindings.",\n "value_name": "dir",\n "schema": {\n "type": "string"\n }\n }\n ],\n "exits": {\n "0": {\n "description": "Generation succeeded.",\n "stdout": {\n "format": "json",\n "schema": {\n "$ref": "#/components/schemas/GenerateResult"\n }\n },\n "files": [\n {\n "path": "{options.out}/manifest.json",\n "required": true,\n "media_type": "application/json",\n "description": "Entity / table / key / relation metadata."\n },\n {\n "path": "{options.out}/operations.json",\n "required": true,\n "media_type": "application/json",\n "description": "Per-query / per-command execution specs."\n },\n {\n "path": "{options.out}/types.py",\n "required": true,\n "media_type": "text/x-python",\n "description": "TypedDict result types derived from query selects."\n },\n {\n "path": "{options.out}/repositories.py",\n "required": true,\n "media_type": "text/x-python",\n "description": "Per-entity repository classes (sync methods)."\n },\n {\n "path": "{options.out}/__init__.py",\n "required": true,\n "media_type": "text/x-python",\n "description": "Package re-exports for the generated bindings."\n }\n ]\n },\n "1": {\n "description": "Unexpected error.",\n "stderr": {\n "format": "json",\n "schema": {\n "$ref": "#/components/schemas/Error"\n }\n }\n },\n "2": {\n "description": "Invalid arguments (missing/unreadable input or output).",\n "stderr": {\n "format": "json",\n "schema": {\n "$ref": "#/components/schemas/Error"\n }\n }\n }\n }\n },\n "generate.php": {\n "summary": "Generate typed PHP bindings (repositories + result DTOs) from TypeScript GraphDDB definitions.",\n "description": "Loads the TypeScript entity models and CQRS contract definitions, builds the serializable manifest / operations bundle, and writes typed PHP bindings \u2014 one `<Entity>Repository` per entity plus a result DTO (and `<Item>Connection`) per query result shape \u2014 into the output directory. Each repository wraps the PHP `GraphDDBRuntime`; query methods return a hydrated `?<Result>` typed object, command methods return void, both calling the runtime by the original operation id. The layout is defined by bundled Handlebars templates users can override with --template-dir (per-partial) and extend with --helpers; type resolution always lives in code (the templates customize layout, not types). Output is deterministic for a given set of inputs. The `--typed` flag selects the typed-binding output (the only mode today; reserved for a future raw-binding mode).",\n "usage": [\n "graphddb generate php --typed --entry models.ts --contracts contracts.ts --out generated/",\n "graphddb generate php --typed --entry definitions.ts --out generated/",\n "graphddb generate php --typed --entry definitions.ts --out generated/ --template-dir php-templates/ --helpers php-helpers.js"\n ],\n "effects": {\n "risk_level": "low",\n "reads": [\n "ts-definitions"\n ],\n "writes": [\n "generated-code"\n ]\n },\n "x-agent": {\n "recommended_before_use": [\n "Ensure the TypeScript definitions type-check and lint cleanly."\n ]\n },\n "options": [\n {\n "name": "entry",\n "aliases": [\n "e"\n ],\n "required": true,\n "description": "Entry module that registers the entity models (side-effecting import). May also export contracts / contexts / transactions.",\n "value_name": "file",\n "schema": {\n "type": "string"\n },\n "file": {\n "mode": "read",\n "exists": true,\n "media_type": "application/typescript",\n "encoding": "utf-8"\n }\n },\n {\n "name": "transactions",\n "aliases": [\n "t"\n ],\n "description": "Module exporting `transactions` (a defineTransactions map). Defaults to the entry module when omitted. Optional \u2014 a project with no declarative transactions omits it.",\n "value_name": "file",\n "schema": {\n "type": "string"\n },\n "file": {\n "mode": "read",\n "exists": true,\n "media_type": "application/typescript",\n "encoding": "utf-8"\n }\n },\n {\n "name": "contracts",\n "description": "Module exporting `contracts` (the CQRS Contract layer). Defaults to the entry module when omitted. Optional \u2014 contract-internal operations are excluded from the generated binding surface.",\n "value_name": "file",\n "schema": {\n "type": "string"\n },\n "file": {\n "mode": "read",\n "exists": true,\n "media_type": "application/typescript",\n "encoding": "utf-8"\n }\n },\n {\n "name": "contexts",\n "description": "Module exporting `contexts` (context-ownership). Defaults to the contracts module (or the entry module) when omitted. Optional.",\n "value_name": "file",\n "schema": {\n "type": "string"\n },\n "file": {\n "mode": "read",\n "exists": true,\n "media_type": "application/typescript",\n "encoding": "utf-8"\n }\n },\n {\n "name": "typed",\n "description": "Emit the typed-binding output (repositories + result DTOs). The only output mode today; reserved to distinguish a future raw-binding mode.",\n "schema": {\n "type": "boolean"\n }\n },\n {\n "name": "template-dir",\n "description": "Directory of override <partial>.hbs templates. Each same-named partial (file / dto-class / connection-class / repo-class / repo-method / tx-class / tx-method) overrides the bundled one; absent partials fall back to the bundled default. Layout only \u2014 type resolution always lives in code.",\n "value_name": "dir",\n "schema": {\n "type": "string"\n }\n },\n {\n "name": "helpers",\n "description": "JS module whose default (or named `helpers`) export is a map of extra Handlebars helpers to register alongside the built-in set.",\n "value_name": "file",\n "schema": {\n "type": "string"\n }\n },\n {\n "name": "out",\n "aliases": [\n "o"\n ],\n "required": true,\n "description": "Output directory for the generated PHP bindings.",\n "value_name": "dir",\n "schema": {\n "type": "string"\n }\n }\n ],\n "exits": {\n "0": {\n "description": "Generation succeeded.",\n "stdout": {\n "format": "json",\n "schema": {\n "$ref": "#/components/schemas/GenerateResult"\n }\n }\n },\n "1": {\n "description": "Unexpected error.",\n "stderr": {\n "format": "json",\n "schema": {\n "$ref": "#/components/schemas/Error"\n }\n }\n },\n "2": {\n "description": "Invalid arguments (missing/unreadable input or output).",\n "stderr": {\n "format": "json",\n "schema": {\n "$ref": "#/components/schemas/Error"\n }\n }\n }\n }\n },\n "generate.rust": {\n "summary": "Generate typed Rust bindings (repositories + serde result structs) from TypeScript GraphDDB definitions.",\n "description": "Loads the TypeScript entity models and CQRS contract definitions, builds the serializable manifest / operations bundle, and writes a single `bindings.rs` module of typed Rust bindings \u2014 a serde-`Deserialize` result struct (and `<Item>Connection`) per query result shape plus one `<Entity>Repository` per entity \u2014 into the output directory. Each repository holds an `Arc<GraphDDBRuntime>`; query methods return `Result<Option<T>, GraphDDBError>` (the deserialized typed result), command methods return `Result<(), GraphDDBError>`, both calling the runtime by the original operation id. The layout is defined by bundled Handlebars templates users can override with --template-dir (per-partial) and extend with --helpers; type resolution always lives in code (the templates customize layout, not types). Output is deterministic for a given set of inputs. The `--typed` flag selects the typed-binding output (the only mode today; reserved for a future raw-binding mode).",\n "usage": [\n "graphddb generate rust --typed --entry models.ts --contracts contracts.ts --out generated/",\n "graphddb generate rust --typed --entry definitions.ts --out generated/",\n "graphddb generate rust --typed --entry definitions.ts --out generated/ --template-dir rust-templates/ --helpers rust-helpers.js"\n ],\n "effects": {\n "risk_level": "low",\n "reads": [\n "ts-definitions"\n ],\n "writes": [\n "generated-code"\n ]\n },\n "x-agent": {\n "recommended_before_use": [\n "Ensure the TypeScript definitions type-check and lint cleanly."\n ]\n },\n "options": [\n {\n "name": "entry",\n "aliases": [\n "e"\n ],\n "required": true,\n "description": "Entry module that registers the entity models (side-effecting import). May also export contracts / contexts / transactions.",\n "value_name": "file",\n "schema": {\n "type": "string"\n },\n "file": {\n "mode": "read",\n "exists": true,\n "media_type": "application/typescript",\n "encoding": "utf-8"\n }\n },\n {\n "name": "transactions",\n "aliases": [\n "t"\n ],\n "description": "Module exporting `transactions` (a defineTransactions map). Defaults to the entry module when omitted. Optional \u2014 a project with no declarative transactions omits it.",\n "value_name": "file",\n "schema": {\n "type": "string"\n },\n "file": {\n "mode": "read",\n "exists": true,\n "media_type": "application/typescript",\n "encoding": "utf-8"\n }\n },\n {\n "name": "contracts",\n "description": "Module exporting `contracts` (the CQRS Contract layer). Defaults to the entry module when omitted. Optional \u2014 contract-internal operations are excluded from the generated binding surface.",\n "value_name": "file",\n "schema": {\n "type": "string"\n },\n "file": {\n "mode": "read",\n "exists": true,\n "media_type": "application/typescript",\n "encoding": "utf-8"\n }\n },\n {\n "name": "contexts",\n "description": "Module exporting `contexts` (context-ownership). Defaults to the contracts module (or the entry module) when omitted. Optional.",\n "value_name": "file",\n "schema": {\n "type": "string"\n },\n "file": {\n "mode": "read",\n "exists": true,\n "media_type": "application/typescript",\n "encoding": "utf-8"\n }\n },\n {\n "name": "typed",\n "description": "Emit the typed-binding output (repositories + result structs). The only output mode today; reserved to distinguish a future raw-binding mode.",\n "schema": {\n "type": "boolean"\n }\n },\n {\n "name": "template-dir",\n "description": "Directory of override <partial>.hbs templates. Each same-named partial (file / result-struct / connection-struct / repo-struct / repo-method / tx-struct / tx-method) overrides the bundled one; absent partials fall back to the bundled default. Layout only \u2014 type resolution always lives in code.",\n "value_name": "dir",\n "schema": {\n "type": "string"\n }\n },\n {\n "name": "helpers",\n "description": "JS module whose default (or named `helpers`) export is a map of extra Handlebars helpers to register alongside the built-in set.",\n "value_name": "file",\n "schema": {\n "type": "string"\n }\n },\n {\n "name": "out",\n "aliases": [\n "o"\n ],\n "required": true,\n "description": "Output directory for the generated Rust bindings.",\n "value_name": "dir",\n "schema": {\n "type": "string"\n }\n }\n ],\n "exits": {\n "0": {\n "description": "Generation succeeded.",\n "stdout": {\n "format": "json",\n "schema": {\n "$ref": "#/components/schemas/GenerateResult"\n }\n }\n },\n "1": {\n "description": "Unexpected error.",\n "stderr": {\n "format": "json",\n "schema": {\n "$ref": "#/components/schemas/Error"\n }\n }\n },\n "2": {\n "description": "Invalid arguments (missing/unreadable input or output).",\n "stderr": {\n "format": "json",\n "schema": {\n "$ref": "#/components/schemas/Error"\n }\n }\n }\n }\n },\n "generate.go": {\n "summary": "Generate typed Go bindings (repositories + json result structs) from TypeScript GraphDDB definitions.",\n "description": "Loads the TypeScript entity models and CQRS contract definitions, builds the serializable manifest / operations bundle, and writes a single `bindings.go` package of typed Go bindings \u2014 a json result struct (and `<Item>Connection`) per query result shape plus one `<Entity>Repository` per entity \u2014 into the output directory. Each repository holds a `*graphddb_runtime.GraphDDBRuntime`; query methods return `(*T, error)` (the deserialized typed result; a nil pointer for no match), command methods return `error`, both calling the runtime by the original operation id. Numbers are precision-strict (`json.Number`), so a large integer round-trips losslessly. The layout is defined by bundled Handlebars templates users can override with --template-dir (per-partial) and extend with --helpers; type resolution always lives in code (the templates customize layout, not types). Output is deterministic for a given set of inputs and gofmt-normalized. The `--typed` flag selects the typed-binding output (the only mode today; reserved for a future raw-binding mode).",\n "usage": [\n "graphddb generate go --typed --entry models.ts --contracts contracts.ts --out generated/",\n "graphddb generate go --typed --entry definitions.ts --out generated/",\n "graphddb generate go --typed --entry definitions.ts --out generated/ --template-dir go-templates/ --helpers go-helpers.js"\n ],\n "effects": {\n "risk_level": "low",\n "reads": [\n "ts-definitions"\n ],\n "writes": [\n "generated-code"\n ]\n },\n "x-agent": {\n "recommended_before_use": [\n "Ensure the TypeScript definitions type-check and lint cleanly."\n ]\n },\n "options": [\n {\n "name": "entry",\n "aliases": [\n "e"\n ],\n "required": true,\n "description": "Entry module that registers the entity models (side-effecting import). May also export contracts / contexts / transactions.",\n "value_name": "file",\n "schema": {\n "type": "string"\n },\n "file": {\n "mode": "read",\n "exists": true,\n "media_type": "application/typescript",\n "encoding": "utf-8"\n }\n },\n {\n "name": "transactions",\n "aliases": [\n "t"\n ],\n "description": "Module exporting `transactions` (a defineTransactions map). Defaults to the entry module when omitted. Optional \u2014 a project with no declarative transactions omits it.",\n "value_name": "file",\n "schema": {\n "type": "string"\n },\n "file": {\n "mode": "read",\n "exists": true,\n "media_type": "application/typescript",\n "encoding": "utf-8"\n }\n },\n {\n "name": "contracts",\n "description": "Module exporting `contracts` (the CQRS Contract layer). Defaults to the entry module when omitted. Optional \u2014 contract-internal operations are excluded from the generated binding surface.",\n "value_name": "file",\n "schema": {\n "type": "string"\n },\n "file": {\n "mode": "read",\n "exists": true,\n "media_type": "application/typescript",\n "encoding": "utf-8"\n }\n },\n {\n "name": "contexts",\n "description": "Module exporting `contexts` (context-ownership). Defaults to the contracts module (or the entry module) when omitted. Optional.",\n "value_name": "file",\n "schema": {\n "type": "string"\n },\n "file": {\n "mode": "read",\n "exists": true,\n "media_type": "application/typescript",\n "encoding": "utf-8"\n }\n },\n {\n "name": "typed",\n "description": "Emit the typed-binding output (repositories + result structs). The only output mode today; reserved to distinguish a future raw-binding mode.",\n "schema": {\n "type": "boolean"\n }\n },\n {\n "name": "template-dir",\n "description": "Directory of override <partial>.hbs templates. Each same-named partial (file / result-struct / connection-struct / repo-struct / repo-method / tx-struct / tx-method) overrides the bundled one; absent partials fall back to the bundled default. Layout only \u2014 type resolution always lives in code.",\n "value_name": "dir",\n "schema": {\n "type": "string"\n }\n },\n {\n "name": "helpers",\n "description": "JS module whose default (or named `helpers`) export is a map of extra Handlebars helpers to register alongside the built-in set.",\n "value_name": "file",\n "schema": {\n "type": "string"\n }\n },\n {\n "name": "out",\n "aliases": [\n "o"\n ],\n "required": true,\n "description": "Output directory for the generated Go bindings.",\n "value_name": "dir",\n "schema": {\n "type": "string"\n }\n }\n ],\n "exits": {\n "0": {\n "description": "Generation succeeded.",\n "stdout": {\n "format": "json",\n "schema": {\n "$ref": "#/components/schemas/GenerateResult"\n }\n }\n },\n "1": {\n "description": "Unexpected error.",\n "stderr": {\n "format": "json",\n "schema": {\n "$ref": "#/components/schemas/Error"\n }\n }\n },\n "2": {\n "description": "Invalid arguments (missing/unreadable input or output).",\n "stderr": {\n "format": "json",\n "schema": {\n "$ref": "#/components/schemas/Error"\n }\n }\n }\n }\n },\n "generate.cloudformation": {\n "summary": "Generate an AWS CloudFormation template (DynamoDB table + GSIs) from TypeScript GraphDDB definitions.",\n "description": "Loads the TypeScript entity models and builds the serializable manifest, then emits an AWS CloudFormation template describing the DynamoDB table(s) the single-table design maps onto: one `AWS::DynamoDB::Table` per physical table, with the base key schema (`PK` / `SK`), the unioned Global Secondary Indexes (`<indexName>PK` / `<indexName>SK`), `PAY_PER_REQUEST` billing, a `TableName` parameter (default = physical name), and Outputs (table name + ARN). Output is deterministic and, by default, YAML.",\n "usage": [\n "graphddb generate cloudformation --entry models.ts --out table.yaml",\n "graphddb generate cloudformation --entry models.ts --format json",\n "graphddb generate cloudformation --entry models.ts --gsi-projection KEYS_ONLY --out table.yaml",\n "graphddb generate cloudformation --entry models.ts --stream on --out table.yaml",\n "graphddb generate cloudformation --entry models.ts --pitr --sse --table-class STANDARD_INFREQUENT_ACCESS --out table.yaml",\n "graphddb generate cloudformation --entry models.ts --billing-mode PROVISIONED --rcu 10 --wcu 5 --out table.yaml",\n "graphddb generate cloudformation --entry models.ts --billing-mode PROVISIONED --autoscale --autoscale-min 5 --autoscale-max 100 --autoscale-target 70 --out table.yaml"\n ],\n "effects": {\n "risk_level": "low",\n "reads": [\n "ts-definitions"\n ],\n "writes": [\n "generated-code"\n ]\n },\n "x-agent": {\n "recommended_before_use": [\n "Ensure the TypeScript definitions type-check and lint cleanly."\n ]\n },\n "options": [\n {\n "name": "entry",\n "aliases": [\n "e"\n ],\n "required": true,\n "description": "Entry module that registers the entity models (side-effecting import).",\n "value_name": "file",\n "schema": {\n "type": "string"\n },\n "file": {\n "mode": "read",\n "exists": true,\n "media_type": "application/typescript",\n "encoding": "utf-8"\n }\n },\n {\n "name": "out",\n "aliases": [\n "o"\n ],\n "description": "Output file for the generated CloudFormation template. Written to stdout when omitted.",\n "value_name": "file",\n "schema": {\n "type": "string"\n }\n },\n {\n "name": "format",\n "aliases": [\n "f"\n ],\n "description": "Output serialization format (yaml or json).",\n "value_name": "format",\n "schema": {\n "type": "string",\n "enum": [\n "yaml",\n "json"\n ],\n "default": "yaml"\n }\n },\n {\n "name": "gsi-projection",\n "description": "GSI ProjectionType. ALL (default) projects every attribute; KEYS_ONLY projects only the key attributes.",\n "value_name": "projection",\n "schema": {\n "type": "string",\n "enum": [\n "ALL",\n "KEYS_ONLY"\n ],\n "default": "ALL"\n }\n },\n {\n "name": "stream",\n "description": "DynamoDB Streams (StreamSpecification NEW_AND_OLD_IMAGES) emission. auto (default) emits a stream only when the model set uses stream-based maintenance (updateMode:\'stream\'); on always emits; off never emits. When enabled, a StreamArn Output is added too.",\n "value_name": "mode",\n "schema": {\n "type": "string",\n "enum": [\n "auto",\n "on",\n "off"\n ],\n "default": "auto"\n }\n },\n {\n "name": "billing-mode",\n "description": "DynamoDB billing mode. PAY_PER_REQUEST (default) is on-demand (no provisioned throughput). PROVISIONED emits BillingMode: PROVISIONED with ProvisionedThroughput (see --rcu / --wcu) on the table and every GSI, and unlocks Application Auto Scaling (--autoscale).",\n "value_name": "mode",\n "schema": {\n "type": "string",\n "enum": [\n "PAY_PER_REQUEST",\n "PROVISIONED"\n ],\n "default": "PAY_PER_REQUEST"\n }\n },\n {\n "name": "rcu",\n "description": "Provisioned ReadCapacityUnits (a positive integer) applied to the table and every GSI. Only valid with --billing-mode PROVISIONED (rejected with PAY_PER_REQUEST). Defaults to 5 when omitted.",\n "value_name": "units",\n "schema": {\n "type": "integer",\n "minimum": 1\n }\n },\n {\n "name": "wcu",\n "description": "Provisioned WriteCapacityUnits (a positive integer) applied to the table and every GSI. Only valid with --billing-mode PROVISIONED (rejected with PAY_PER_REQUEST). Defaults to 5 when omitted.",\n "value_name": "units",\n "schema": {\n "type": "integer",\n "minimum": 1\n }\n },\n {\n "name": "autoscale",\n "description": "Enable Application Auto Scaling. Emits an AWS::ApplicationAutoScaling::ScalableTarget + AWS::ApplicationAutoScaling::ScalingPolicy pair for the table read and write capacity AND for each GSI read and write capacity. Only valid with --billing-mode PROVISIONED (autoscaling is invalid on on-demand and is rejected). Off by default \u2014 no autoscaling resources are emitted unless this flag is passed.",\n "schema": {\n "type": "boolean"\n }\n },\n {\n "name": "autoscale-min",\n "description": "Auto Scaling minimum capacity (MinCapacity) for every scalable target. Must be <= --autoscale-max. Only meaningful with --autoscale. Defaults to 5 when omitted.",\n "value_name": "units",\n "schema": {\n "type": "integer",\n "minimum": 1\n }\n },\n {\n "name": "autoscale-max",\n "description": "Auto Scaling maximum capacity (MaxCapacity) for every scalable target. Must be >= --autoscale-min. Only meaningful with --autoscale. Defaults to 100 when omitted.",\n "value_name": "units",\n "schema": {\n "type": "integer",\n "minimum": 1\n }\n },\n {\n "name": "autoscale-target",\n "description": "Auto Scaling target utilization percentage (TargetValue of the TargetTrackingScaling policy). Only meaningful with --autoscale. Defaults to 70 when omitted.",\n "value_name": "percent",\n "schema": {\n "type": "integer",\n "minimum": 1,\n "maximum": 100\n }\n },\n {\n "name": "pitr",\n "description": "Enable point-in-time recovery (PointInTimeRecoverySpecification PointInTimeRecoveryEnabled:true). Off by default \u2014 the property is omitted entirely unless this flag is passed.",\n "schema": {\n "type": "boolean"\n }\n },\n {\n "name": "table-class",\n "description": "DynamoDB table class. Omitted by default (AWS defaults to STANDARD); pass STANDARD or STANDARD_INFREQUENT_ACCESS to emit TableClass.",\n "value_name": "class",\n "schema": {\n "type": "string",\n "enum": [\n "STANDARD",\n "STANDARD_INFREQUENT_ACCESS"\n ]\n }\n },\n {\n "name": "sse",\n "description": "Enable server-side encryption with the AWS-owned/managed key (SSESpecification SSEEnabled:true). Off by default \u2014 the property is omitted entirely unless this flag is passed.",\n "schema": {\n "type": "boolean"\n }\n }\n ],\n "exits": {\n "0": {\n "description": "Generation succeeded.",\n "stdout": {\n "format": "json",\n "schema": {\n "$ref": "#/components/schemas/GenerateResult"\n }\n }\n },\n "1": {\n "description": "Unexpected error.",\n "stderr": {\n "format": "json",\n "schema": {\n "$ref": "#/components/schemas/Error"\n }\n }\n },\n "2": {\n "description": "Invalid arguments (missing/unreadable input or output).",\n "stderr": {\n "format": "json",\n "schema": {\n "$ref": "#/components/schemas/Error"\n }\n }\n }\n }\n },\n "generate.docs": {\n "summary": "Generate model-specification documentation (Markdown + Mermaid) from TypeScript GraphDDB definitions.",\n "description": "Loads the TypeScript entity models (and, optionally, the CQRS contract definitions), builds the serializable manifest / operations bundle, then renders human-facing model documentation \u2014 Table Overview, Entity Relationship Diagram, Physical Key Schema, Property Matrix, Entity Details, Access Patterns, Mutation Contracts, Maintained Access Paths, CDC, and CloudFormation summary \u2014 as Markdown with Mermaid diagrams. The layout is defined by bundled Handlebars templates users can override with --template-dir (per-partial) and extend with --helpers. Output is deterministic for a given set of inputs.",\n "usage": [\n "graphddb generate docs --entry models.ts --out doc.md",\n "graphddb generate docs --entry models.ts --contracts contracts.ts --out doc.md",\n "graphddb generate docs --entry models.ts --out docs/",\n "graphddb generate docs --entry models.ts --out docs/ --template-dir doc-templates/ --helpers doc-helpers.js"\n ],\n "effects": {\n "risk_level": "low",\n "reads": [\n "ts-definitions"\n ],\n "writes": [\n "generated-code"\n ]\n },\n "x-agent": {\n "recommended_before_use": [\n "Ensure the TypeScript definitions type-check and lint cleanly."\n ]\n },\n "options": [\n {\n "name": "entry",\n "aliases": [\n "e"\n ],\n "required": true,\n "description": "Entry module that registers the entity models (side-effecting import). May also export contracts / contexts / transactions.",\n "value_name": "file",\n "schema": {\n "type": "string"\n },\n "file": {\n "mode": "read",\n "exists": true,\n "media_type": "application/typescript",\n "encoding": "utf-8"\n }\n },\n {\n "name": "contracts",\n "description": "Module exporting `contracts` (a map of publishQuery / publishCommand results \u2014 the CQRS Contract layer) used for the Access Patterns / Mutation Contracts sections. Defaults to the entry module when omitted. Optional.",\n "value_name": "file",\n "schema": {\n "type": "string"\n },\n "file": {\n "mode": "read",\n "exists": true,\n "media_type": "application/typescript",\n "encoding": "utf-8"\n }\n },\n {\n "name": "contexts",\n "description": "Module exporting `contexts` (context-ownership). Defaults to the contracts module (or the entry module) when omitted. Optional.",\n "value_name": "file",\n "schema": {\n "type": "string"\n },\n "file": {\n "mode": "read",\n "exists": true,\n "media_type": "application/typescript",\n "encoding": "utf-8"\n }\n },\n {\n "name": "out",\n "aliases": [\n "o"\n ],\n "required": true,\n "description": "Output path for the generated documentation. A file path ending in .md writes the single Markdown file at exactly that path (creating parent directories); any other value is treated as a directory and the file is written as <dir>/index.md.",\n "value_name": "path",\n "schema": {\n "type": "string"\n }\n },\n {\n "name": "format",\n "aliases": [\n "f"\n ],\n "description": "Output format. Only markdown is supported today.",\n "value_name": "format",\n "schema": {\n "type": "string",\n "enum": [\n "markdown"\n ],\n "default": "markdown"\n }\n },\n {\n "name": "split",\n "description": "Output granularity. none (default) emits a single index.md; entity is reserved for a future per-entity split.",\n "value_name": "mode",\n "schema": {\n "type": "string",\n "enum": [\n "none",\n "entity"\n ],\n "default": "none"\n }\n },\n {\n "name": "template-dir",\n "description": "Directory of override <partial>.hbs templates. Each same-named partial (index / table-overview / er-diagram / key-schema / property-matrix / entity / access-pattern / maintained / cdc / cloudformation) overrides the bundled one; absent partials fall back to the bundled default.",\n "value_name": "dir",\n "schema": {\n "type": "string"\n }\n },\n {\n "name": "helpers",\n "description": "JS module whose default (or named `helpers`) export is a map of extra Handlebars helpers to register alongside the built-in set (eq / join / pascal / mermaidId / codeOrEmpty).",\n "value_name": "file",\n "schema": {\n "type": "string"\n }\n },\n {\n "name": "billing-mode",\n "description": "DynamoDB billing mode used in the Table Overview (shared with generate cloudformation). PAY_PER_REQUEST (default) or PROVISIONED.",\n "value_name": "mode",\n "schema": {\n "type": "string",\n "enum": [\n "PAY_PER_REQUEST",\n "PROVISIONED"\n ],\n "default": "PAY_PER_REQUEST"\n }\n },\n {\n "name": "stream",\n "description": "DynamoDB Streams state used in the Table Overview (shared with generate cloudformation). auto (default) detects stream-based maintenance (updateMode:\'stream\'); on always enabled; off never.",\n "value_name": "mode",\n "schema": {\n "type": "string",\n "enum": [\n "auto",\n "on",\n "off"\n ],\n "default": "auto"\n }\n }\n ],\n "exits": {\n "0": {\n "description": "Generation succeeded.",\n "stdout": {\n "format": "json",\n "schema": {\n "$ref": "#/components/schemas/GenerateResult"\n }\n }\n },\n "1": {\n "description": "Unexpected error.",\n "stderr": {\n "format": "json",\n "schema": {\n "$ref": "#/components/schemas/Error"\n }\n }\n },\n "2": {\n "description": "Invalid arguments (missing/unreadable input or output).",\n "stderr": {\n "format": "json",\n "schema": {\n "$ref": "#/components/schemas/Error"\n }\n }\n }\n }\n },\n "transform.prepared": {\n "summary": "Lint and hoist-normalize `DDBModel.prepare` call sites (compile-time prepared statements, issue #206).",\n "description": "A source-to-source build pass over application TypeScript files. It statically enforces the prepared-statement no-runtime-capture rule (a prepare body may reference only its `$` placeholder and module-static bindings; capturing a per-call runtime value \u2014 directly or via a helper call \u2014 is a loud error), and normalizes every verified INLINE `DDBModel.prepare(fn)` call site into a module-scope prepared slot so the plan compiles once per module and each call is a plain `.execute` (zero per-op planning / hashing \u2014 placement independent). Without --write it is a pure check (the build lint): violations exit non-zero and hoistable inline call sites are reported as notes. With --write, verified inline call sites are rewritten in place; files with violations are never rewritten. Idempotent: re-running on transformed output changes nothing. With --aot <artifact> (issue #208), the pass additionally compiles every verified prepare body at BUILD time into a static prepared-plan artifact (a generated TypeScript module): with --write it writes the artifact and rewrites each call site to load its static plan (`loadPreparedPlan(document, id, body)` \u2014 the body stays in source as the plan\'s compile source and fallback); without --write it is the DRIFT CHECK \u2014 it recompiles every plan and exits non-zero when the artifact is missing or differs (CI gate: model declarations changed without regenerating the artifact).",\n "usage": [\n "graphddb transform prepared --src src/",\n "graphddb transform prepared --src src/ --write",\n "graphddb transform prepared --src src/app/handlers.ts --write",\n "graphddb transform prepared --src src/ --aot src/graphddb.prepared.ts --write",\n "graphddb transform prepared --src src/ --aot src/graphddb.prepared.ts"\n ],\n "effects": {\n "risk_level": "medium",\n "reads": [\n "ts-app-sources"\n ],\n "writes": [\n "ts-app-sources"\n ]\n },\n "x-agent": {\n "recommended_before_use": [\n "Commit or stash pending changes first when using --write (it rewrites sources in place)."\n ]\n },\n "options": [\n {\n "name": "src",\n "aliases": [\n "s"\n ],\n "required": true,\n "description": "A TypeScript source file, or a directory scanned recursively for .ts/.tsx/.mts/.cts files (node_modules, dist, hidden directories, and .d.ts files are skipped).",\n "value_name": "path",\n "schema": {\n "type": "string"\n },\n "file": {\n "mode": "read",\n "exists": true\n }\n },\n {\n "name": "write",\n "aliases": [\n "w"\n ],\n "description": "Rewrite verified inline call sites in place (hoist normalization). Without it the command only checks and reports.",\n "schema": {\n "type": "boolean"\n }\n },\n {\n "name": "aot",\n "aliases": [\n "a"\n ],\n "description": "Static prepared-plan artifact module path (issue #208). Enables build-time (AOT) compilation of every verified prepare body: with --write the artifact module is (re)generated and call sites are rewritten to load their static plan; without --write the pass recompiles and compares (drift check \u2014 a missing or differing artifact exits 1).",\n "value_name": "artifact",\n "schema": {\n "type": "string"\n }\n }\n ],\n "exits": {\n "0": {\n "description": "Check passed / transform applied. No no-runtime-capture violations were found.",\n "stdout": {\n "format": "json",\n "schema": {\n "$ref": "#/components/schemas/TransformPreparedResult"\n }\n }\n },\n "1": {\n "description": "No-runtime-capture violations found, or --aot drift detected (reported in the result on stdout), or an unexpected error (reported on stderr).",\n "stdout": {\n "format": "json",\n "schema": {\n "$ref": "#/components/schemas/TransformPreparedResult"\n }\n }\n },\n "2": {\n "description": "Invalid arguments (missing/unreadable input).",\n "stderr": {\n "format": "json",\n "schema": {\n "$ref": "#/components/schemas/Error"\n }\n }\n }\n }\n }\n }\n }\n },\n "components": {\n "schemas": {\n "GenerateResult": {\n "type": "object",\n "required": [\n "status",\n "outDir",\n "files"\n ],\n "properties": {\n "status": {\n "type": "string",\n "enum": [\n "ok"\n ]\n },\n "outDir": {\n "type": "string",\n "description": "Output directory the files were written to."\n },\n "files": {\n "type": "array",\n "description": "Paths of the generated files (relative to outDir).",\n "items": {\n "type": "string"\n }\n }\n }\n },\n "Error": {\n "type": "object",\n "required": [\n "code",\n "message"\n ],\n "properties": {\n "code": {\n "type": "string"\n },\n "message": {\n "type": "string"\n }\n }\n },\n "TransformPreparedResult": {\n "type": "object",\n "required": [\n "status",\n "files",\n "hoisted",\n "moduleScope",\n "alreadyHoisted",\n "errors",\n "diagnostics"\n ],\n "properties": {\n "status": {\n "type": "string",\n "enum": [\n "ok",\n "violations",\n "drift"\n ]\n },\n "files": {\n "type": "array",\n "description": "Source files scanned.",\n "items": {\n "type": "string"\n }\n },\n "changedFiles": {\n "type": "array",\n "description": "Files rewritten in place (--write only).",\n "items": {\n "type": "string"\n }\n },\n "hoisted": {\n "type": "integer",\n "description": "Inline call sites normalized (or normalizable in check mode)."\n },\n "moduleScope": {\n "type": "integer",\n "description": "Call sites already evaluated once per module load (left as-is)."\n },\n "alreadyHoisted": {\n "type": "integer",\n "description": "Call sites already normalized by a previous run."\n },\n "errors": {\n "type": "integer",\n "description": "No-runtime-capture violations found."\n },\n "artifact": {\n "type": "string",\n "description": "The static prepared-plan artifact path (--aot only)."\n },\n "plans": {\n "type": "integer",\n "description": "Prepared plans compiled into the artifact (--aot only)."\n },\n "drift": {\n "type": "object",\n "description": "Artifact drift detail (--aot check mode only; present when status is drift).",\n "properties": {\n "missing": {\n "type": "boolean",\n "description": "The artifact module does not exist."\n },\n "added": {\n "type": "array",\n "items": {\n "type": "string"\n }\n },\n "removed": {\n "type": "array",\n "items": {\n "type": "string"\n }\n },\n "changed": {\n "type": "array",\n "items": {\n "type": "string"\n }\n }\n }\n },\n "diagnostics": {\n "type": "array",\n "description": "Per-position lint diagnostics (errors and notes).",\n "items": {\n "type": "object",\n "required": [\n "code",\n "category",\n "message",\n "file",\n "line",\n "column"\n ],\n "properties": {\n "code": {\n "type": "string"\n },\n "category": {\n "type": "string",\n "enum": [\n "error",\n "note"\n ]\n },\n "message": {\n "type": "string"\n },\n "file": {\n "type": "string"\n },\n "line": {\n "type": "integer"\n },\n "column": {\n "type": "integer"\n }\n }\n }\n }\n }\n }\n }\n }\n}';
942
+ var CONTRACT_YAML = "cli_contracts: 0.1.0\n\ninfo:\n title: GraphDDB CLI\n version: 0.1.0\n description: >-\n Contract for the graphddb code-generation CLI. The CLI reads TypeScript\n GraphDDB model + CQRS contract definitions (the single source of truth)\n and emits Python bindings (manifest.json, operations.json, types.py,\n repositories.py, __init__.py) for the Python bridge runtime.\n license:\n name: MIT\n contact:\n name: foo-log-inc\n url: https://github.com/foo-log-inc/graphddb\n\nartifact_slots:\n ts-definitions:\n description: >-\n TypeScript GraphDDB definition modules (entity models + the CQRS\n publishQuery / publishCommand contracts) used as the single source of truth.\n direction: read\n generated-code:\n description: >-\n Generated Python bindings and JSON specs written to the output directory\n (manifest.json, operations.json, types.py, repositories.py, __init__.py).\n direction: write\n ts-app-sources:\n description: >-\n Application TypeScript sources containing `DDBModel.prepare` call sites.\n Read by the prepared-statement build lint; rewritten in place by\n `transform prepared --write` (hoist normalization, issue #206).\n direction: write\n\ncommand_sets:\n graphddb:\n summary: Graph data modeling on DynamoDB \u2014 code generation CLI.\n x-stdin: >-\n No command reads from stdin. All inputs are provided via file options.\n\n commands:\n # \u2500\u2500 generate python \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n generate.python:\n summary: Generate Python bindings from TypeScript GraphDDB definitions.\n description: >-\n Loads the TypeScript entity models and CQRS contract\n definitions, builds the serializable manifest / operations bundle, and\n writes the Python bridge bindings (manifest.json, operations.json,\n types.py, repositories.py, __init__.py) to the output directory.\n Output is deterministic for a given set of inputs.\n usage:\n - graphddb generate python --entry models.ts --contracts contracts.ts --out generated/\n - graphddb generate python --entry definitions.ts --out generated/\n\n effects:\n risk_level: low\n reads:\n - ts-definitions\n writes:\n - generated-code\n\n x-agent:\n recommended_before_use:\n - \"Ensure the TypeScript definitions type-check and lint cleanly.\"\n\n options:\n - name: entry\n aliases: [e]\n required: true\n description: >-\n Entry module that registers the entity models (side-effecting\n import). May also export contracts / contexts / transactions.\n value_name: file\n schema:\n type: string\n file:\n mode: read\n exists: true\n media_type: application/typescript\n encoding: utf-8\n\n - name: transactions\n aliases: [t]\n description: >-\n Module exporting `transactions` (a defineTransactions map).\n Defaults to the entry module when omitted.\n Optional \u2014 a project with no declarative transactions omits it.\n value_name: file\n schema:\n type: string\n file:\n mode: read\n exists: true\n media_type: application/typescript\n encoding: utf-8\n\n - name: contracts\n description: >-\n Module exporting `contracts` (a map of publishQuery /\n publishCommand results \u2014 the CQRS Contract layer). Defaults to\n the entry module when omitted. Optional \u2014 a project with no\n contracts omits it, and the output gains no `contracts` content.\n value_name: file\n schema:\n type: string\n file:\n mode: read\n exists: true\n media_type: application/typescript\n encoding: utf-8\n\n - name: contexts\n description: >-\n Module exporting `contexts` (context-ownership: context name \u2192 the\n Model / Contract names that belong to it). Defaults to the\n contracts module (or the entry module) when omitted. Optional \u2014\n consumed by the boundary lint to tell own from foreign.\n value_name: file\n schema:\n type: string\n file:\n mode: read\n exists: true\n media_type: application/typescript\n encoding: utf-8\n\n - name: dataclass\n description: >-\n Emit Python result / element types as @dataclass classes instead\n of TypedDict (decimal / Optional / Connection mapped accordingly).\n schema:\n type: boolean\n\n - name: out\n aliases: [o]\n required: true\n description: Output directory for the generated Python bindings.\n value_name: dir\n schema:\n type: string\n\n exits:\n '0':\n description: Generation succeeded.\n stdout:\n format: json\n schema:\n $ref: '#/components/schemas/GenerateResult'\n files:\n - path: '{options.out}/manifest.json'\n required: true\n media_type: application/json\n description: Entity / table / key / relation metadata.\n - path: '{options.out}/operations.json'\n required: true\n media_type: application/json\n description: Per-query / per-command execution specs.\n - path: '{options.out}/types.py'\n required: true\n media_type: text/x-python\n description: TypedDict result types derived from query selects.\n - path: '{options.out}/repositories.py'\n required: true\n media_type: text/x-python\n description: Per-entity repository classes (sync methods).\n - path: '{options.out}/__init__.py'\n required: true\n media_type: text/x-python\n description: Package re-exports for the generated bindings.\n\n '1':\n description: Unexpected error.\n stderr:\n format: json\n schema:\n $ref: '#/components/schemas/Error'\n\n '2':\n description: Invalid arguments (missing/unreadable input or output).\n stderr:\n format: json\n schema:\n $ref: '#/components/schemas/Error'\n\n # \u2500\u2500 generate php \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n generate.php:\n summary: >-\n Generate typed PHP bindings (repositories + result DTOs) from\n TypeScript GraphDDB definitions.\n description: >-\n Loads the TypeScript entity models and CQRS contract\n definitions, builds the serializable manifest / operations bundle, and\n writes typed PHP bindings \u2014 one `<Entity>Repository` per entity plus a\n result DTO (and `<Item>Connection`) per query result shape \u2014 into the\n output directory. Each repository wraps the PHP `GraphDDBRuntime`; query\n methods return a hydrated `?<Result>` typed object, command methods\n return void, both calling the runtime by the original operation id. The\n layout is defined by bundled Handlebars templates users can override\n with --template-dir (per-partial) and extend with --helpers; type\n resolution always lives in code (the templates customize layout, not\n types). Output is deterministic for a given set of inputs. The `--typed`\n flag selects the typed-binding output (the only mode today; reserved for\n a future raw-binding mode).\n usage:\n - graphddb generate php --typed --entry models.ts --contracts contracts.ts --out generated/\n - graphddb generate php --typed --entry definitions.ts --out generated/\n - graphddb generate php --typed --entry definitions.ts --out generated/ --template-dir php-templates/ --helpers php-helpers.js\n\n effects:\n risk_level: low\n reads:\n - ts-definitions\n writes:\n - generated-code\n\n x-agent:\n recommended_before_use:\n - \"Ensure the TypeScript definitions type-check and lint cleanly.\"\n\n options:\n - name: entry\n aliases: [e]\n required: true\n description: >-\n Entry module that registers the entity models (side-effecting\n import). May also export contracts / contexts / transactions.\n value_name: file\n schema:\n type: string\n file:\n mode: read\n exists: true\n media_type: application/typescript\n encoding: utf-8\n\n - name: transactions\n aliases: [t]\n description: >-\n Module exporting `transactions` (a defineTransactions map).\n Defaults to the entry module when omitted.\n Optional \u2014 a project with no declarative transactions omits it.\n value_name: file\n schema:\n type: string\n file:\n mode: read\n exists: true\n media_type: application/typescript\n encoding: utf-8\n\n - name: contracts\n description: >-\n Module exporting `contracts` (the CQRS Contract layer). Defaults to\n the entry module when omitted. Optional \u2014 contract-internal\n operations are excluded from the generated binding surface.\n value_name: file\n schema:\n type: string\n file:\n mode: read\n exists: true\n media_type: application/typescript\n encoding: utf-8\n\n - name: contexts\n description: >-\n Module exporting `contexts` (context-ownership). Defaults to the\n contracts module (or the entry module) when omitted. Optional.\n value_name: file\n schema:\n type: string\n file:\n mode: read\n exists: true\n media_type: application/typescript\n encoding: utf-8\n\n - name: typed\n description: >-\n Emit the typed-binding output (repositories + result DTOs). The only\n output mode today; reserved to distinguish a future raw-binding mode.\n schema:\n type: boolean\n\n - name: template-dir\n description: >-\n Directory of override <partial>.hbs templates. Each same-named\n partial (file / dto-class / connection-class / repo-class /\n repo-method / tx-class / tx-method) overrides the bundled one;\n absent partials fall back to the bundled default. Layout only \u2014 type\n resolution always lives in code.\n value_name: dir\n schema:\n type: string\n\n - name: helpers\n description: >-\n JS module whose default (or named `helpers`) export is a map of\n extra Handlebars helpers to register alongside the built-in set.\n value_name: file\n schema:\n type: string\n\n - name: out\n aliases: [o]\n required: true\n description: Output directory for the generated PHP bindings.\n value_name: dir\n schema:\n type: string\n\n exits:\n '0':\n description: Generation succeeded.\n stdout:\n format: json\n schema:\n $ref: '#/components/schemas/GenerateResult'\n\n '1':\n description: Unexpected error.\n stderr:\n format: json\n schema:\n $ref: '#/components/schemas/Error'\n\n '2':\n description: Invalid arguments (missing/unreadable input or output).\n stderr:\n format: json\n schema:\n $ref: '#/components/schemas/Error'\n\n # \u2500\u2500 generate rust \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n generate.rust:\n summary: >-\n Generate typed Rust bindings (repositories + serde result structs) from\n TypeScript GraphDDB definitions.\n description: >-\n Loads the TypeScript entity models and CQRS contract\n definitions, builds the serializable manifest / operations bundle, and\n writes a single `bindings.rs` module of typed Rust bindings \u2014 a\n serde-`Deserialize` result struct (and `<Item>Connection`) per query\n result shape plus one `<Entity>Repository` per entity \u2014 into the output\n directory. Each repository holds an `Arc<GraphDDBRuntime>`; query methods\n return `Result<Option<T>, GraphDDBError>` (the deserialized typed\n result), command methods return `Result<(), GraphDDBError>`, both calling\n the runtime by the original operation id. The layout is defined by\n bundled Handlebars templates users can override with --template-dir\n (per-partial) and extend with --helpers; type resolution always lives in\n code (the templates customize layout, not types). Output is deterministic\n for a given set of inputs. The `--typed` flag selects the typed-binding\n output (the only mode today; reserved for a future raw-binding mode).\n usage:\n - graphddb generate rust --typed --entry models.ts --contracts contracts.ts --out generated/\n - graphddb generate rust --typed --entry definitions.ts --out generated/\n - graphddb generate rust --typed --entry definitions.ts --out generated/ --template-dir rust-templates/ --helpers rust-helpers.js\n\n effects:\n risk_level: low\n reads:\n - ts-definitions\n writes:\n - generated-code\n\n x-agent:\n recommended_before_use:\n - \"Ensure the TypeScript definitions type-check and lint cleanly.\"\n\n options:\n - name: entry\n aliases: [e]\n required: true\n description: >-\n Entry module that registers the entity models (side-effecting\n import). May also export contracts / contexts / transactions.\n value_name: file\n schema:\n type: string\n file:\n mode: read\n exists: true\n media_type: application/typescript\n encoding: utf-8\n\n - name: transactions\n aliases: [t]\n description: >-\n Module exporting `transactions` (a defineTransactions map).\n Defaults to the entry module when omitted.\n Optional \u2014 a project with no declarative transactions omits it.\n value_name: file\n schema:\n type: string\n file:\n mode: read\n exists: true\n media_type: application/typescript\n encoding: utf-8\n\n - name: contracts\n description: >-\n Module exporting `contracts` (the CQRS Contract layer). Defaults to\n the entry module when omitted. Optional \u2014 contract-internal\n operations are excluded from the generated binding surface.\n value_name: file\n schema:\n type: string\n file:\n mode: read\n exists: true\n media_type: application/typescript\n encoding: utf-8\n\n - name: contexts\n description: >-\n Module exporting `contexts` (context-ownership). Defaults to the\n contracts module (or the entry module) when omitted. Optional.\n value_name: file\n schema:\n type: string\n file:\n mode: read\n exists: true\n media_type: application/typescript\n encoding: utf-8\n\n - name: typed\n description: >-\n Emit the typed-binding output (repositories + result structs). The\n only output mode today; reserved to distinguish a future raw-binding\n mode.\n schema:\n type: boolean\n\n - name: template-dir\n description: >-\n Directory of override <partial>.hbs templates. Each same-named\n partial (file / result-struct / connection-struct / repo-struct /\n repo-method / tx-struct / tx-method) overrides the bundled one;\n absent partials fall back to the bundled default. Layout only \u2014 type\n resolution always lives in code.\n value_name: dir\n schema:\n type: string\n\n - name: helpers\n description: >-\n JS module whose default (or named `helpers`) export is a map of\n extra Handlebars helpers to register alongside the built-in set.\n value_name: file\n schema:\n type: string\n\n - name: out\n aliases: [o]\n required: true\n description: Output directory for the generated Rust bindings.\n value_name: dir\n schema:\n type: string\n\n exits:\n '0':\n description: Generation succeeded.\n stdout:\n format: json\n schema:\n $ref: '#/components/schemas/GenerateResult'\n\n '1':\n description: Unexpected error.\n stderr:\n format: json\n schema:\n $ref: '#/components/schemas/Error'\n\n '2':\n description: Invalid arguments (missing/unreadable input or output).\n stderr:\n format: json\n schema:\n $ref: '#/components/schemas/Error'\n\n # \u2500\u2500 generate go \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n generate.go:\n summary: >-\n Generate typed Go bindings (repositories + json result structs) from\n TypeScript GraphDDB definitions.\n description: >-\n Loads the TypeScript entity models and CQRS contract\n definitions, builds the serializable manifest / operations bundle, and\n writes a single `bindings.go` package of typed Go bindings \u2014 a json result\n struct (and `<Item>Connection`) per query result shape plus one\n `<Entity>Repository` per entity \u2014 into the output directory. Each\n repository holds a `*graphddb_runtime.GraphDDBRuntime`; query methods\n return `(*T, error)` (the deserialized typed result; a nil pointer for no\n match), command methods return `error`, both calling the runtime by the\n original operation id. Numbers are precision-strict (`json.Number`), so a\n large integer round-trips losslessly. The layout is defined by bundled\n Handlebars templates users can override with --template-dir (per-partial)\n and extend with --helpers; type resolution always lives in code (the\n templates customize layout, not types). Output is deterministic for a\n given set of inputs and gofmt-normalized. The `--typed` flag selects the\n typed-binding output (the only mode today; reserved for a future\n raw-binding mode).\n usage:\n - graphddb generate go --typed --entry models.ts --contracts contracts.ts --out generated/\n - graphddb generate go --typed --entry definitions.ts --out generated/\n - graphddb generate go --typed --entry definitions.ts --out generated/ --template-dir go-templates/ --helpers go-helpers.js\n\n effects:\n risk_level: low\n reads:\n - ts-definitions\n writes:\n - generated-code\n\n x-agent:\n recommended_before_use:\n - \"Ensure the TypeScript definitions type-check and lint cleanly.\"\n\n options:\n - name: entry\n aliases: [e]\n required: true\n description: >-\n Entry module that registers the entity models (side-effecting\n import). May also export contracts / contexts / transactions.\n value_name: file\n schema:\n type: string\n file:\n mode: read\n exists: true\n media_type: application/typescript\n encoding: utf-8\n\n - name: transactions\n aliases: [t]\n description: >-\n Module exporting `transactions` (a defineTransactions map).\n Defaults to the entry module when omitted.\n Optional \u2014 a project with no declarative transactions omits it.\n value_name: file\n schema:\n type: string\n file:\n mode: read\n exists: true\n media_type: application/typescript\n encoding: utf-8\n\n - name: contracts\n description: >-\n Module exporting `contracts` (the CQRS Contract layer). Defaults to\n the entry module when omitted. Optional \u2014 contract-internal\n operations are excluded from the generated binding surface.\n value_name: file\n schema:\n type: string\n file:\n mode: read\n exists: true\n media_type: application/typescript\n encoding: utf-8\n\n - name: contexts\n description: >-\n Module exporting `contexts` (context-ownership). Defaults to the\n contracts module (or the entry module) when omitted. Optional.\n value_name: file\n schema:\n type: string\n file:\n mode: read\n exists: true\n media_type: application/typescript\n encoding: utf-8\n\n - name: typed\n description: >-\n Emit the typed-binding output (repositories + result structs). The\n only output mode today; reserved to distinguish a future raw-binding\n mode.\n schema:\n type: boolean\n\n - name: template-dir\n description: >-\n Directory of override <partial>.hbs templates. Each same-named\n partial (file / result-struct / connection-struct / repo-struct /\n repo-method / tx-struct / tx-method) overrides the bundled one;\n absent partials fall back to the bundled default. Layout only \u2014 type\n resolution always lives in code.\n value_name: dir\n schema:\n type: string\n\n - name: helpers\n description: >-\n JS module whose default (or named `helpers`) export is a map of\n extra Handlebars helpers to register alongside the built-in set.\n value_name: file\n schema:\n type: string\n\n - name: out\n aliases: [o]\n required: true\n description: Output directory for the generated Go bindings.\n value_name: dir\n schema:\n type: string\n\n exits:\n '0':\n description: Generation succeeded.\n stdout:\n format: json\n schema:\n $ref: '#/components/schemas/GenerateResult'\n\n '1':\n description: Unexpected error.\n stderr:\n format: json\n schema:\n $ref: '#/components/schemas/Error'\n\n '2':\n description: Invalid arguments (missing/unreadable input or output).\n stderr:\n format: json\n schema:\n $ref: '#/components/schemas/Error'\n\n # \u2500\u2500 generate behaviors \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n generate.behaviors:\n summary: >-\n Generate a native behavior module (the codegen-static endpoint) via the\n upstream behavior-contracts common Generator.\n description: >-\n Loads the TypeScript entity models and CQRS contract definitions,\n builds the serializable operations bundle, wraps its universal\n components[] into the portable component-graph IR envelope\n ({irVersion, exprVersion, components} \u2014 scp-ir-architecture.md \xA75),\n and hands it to behavior-contracts' common Generator\n (`generateModule`, foo-ogawa/behavior-contracts#13) to emit ONE native\n module for the selected language (issue #257). graphddb adds no\n generation logic: envelope + invoke + file write only. The generated\n module embeds the IR as a native literal with the spec versions and\n the IR fingerprint baked in (fail-closed load-time checks, the #208\n prepared-artifact discipline) and exposes a `bind(handlers)` accessor\n that delegates to the runtime core \u2014 handlers are always injected at\n the boundary by the consuming runtime (the graphddb per-language\n behavior-exec seams). This is the OPT-IN static endpoint (\xA77.3\n endpoint 3); the JSON-dynamic operations.json path remains the\n default and is permanently supported. Output is deterministic for a\n given set of inputs.\n usage:\n - graphddb generate behaviors --lang ts --entry models.ts --contracts contracts.ts --out generated/\n - graphddb generate behaviors --lang go --entry models.ts --contracts contracts.ts --out generated/\n - graphddb generate behaviors --lang python --entry definitions.ts --out generated/\n - graphddb generate behaviors --lang rust --entry definitions.ts --out generated/ --runtime-import behavior_contracts\n - graphddb generate behaviors --lang php --entry definitions.ts --out generated/\n\n effects:\n risk_level: low\n reads:\n - ts-definitions\n writes:\n - generated-code\n\n x-agent:\n recommended_before_use:\n - \"Ensure the TypeScript definitions type-check and lint cleanly.\"\n\n options:\n - name: lang\n aliases: [l]\n required: true\n description: >-\n Target language of the generated behavior module. `ts` emits a\n typed TypeScript module, `python` a dict-literal module, `go` a\n JNode composite-literal package, `rust` a json!-constructor\n module (requires Rust >= 1.80 \u2014 std::sync::LazyLock), `php` a\n require-scoped module value.\n value_name: lang\n schema:\n type: string\n enum: [ts, python, go, rust, php]\n\n - name: entry\n aliases: [e]\n required: true\n description: >-\n Entry module that registers the entity models (side-effecting\n import). May also export contracts / contexts / transactions.\n value_name: file\n schema:\n type: string\n file:\n mode: read\n exists: true\n media_type: application/typescript\n encoding: utf-8\n\n - name: transactions\n aliases: [t]\n description: >-\n Module exporting `transactions` (a defineTransactions map).\n Defaults to the entry module when omitted. Optional.\n value_name: file\n schema:\n type: string\n file:\n mode: read\n exists: true\n media_type: application/typescript\n encoding: utf-8\n\n - name: contracts\n description: >-\n Module exporting `contracts` (the CQRS Contract layer). Defaults\n to the entry module when omitted. Optional.\n value_name: file\n schema:\n type: string\n file:\n mode: read\n exists: true\n media_type: application/typescript\n encoding: utf-8\n\n - name: contexts\n description: >-\n Module exporting `contexts` (context-ownership). Defaults to the\n contracts module (or the entry module) when omitted. Optional.\n value_name: file\n schema:\n type: string\n file:\n mode: read\n exists: true\n media_type: application/typescript\n encoding: utf-8\n\n - name: runtime-import\n description: >-\n Module specifier the generated module imports the\n behavior-contracts runtime core from. Defaults to the emitter's\n published package name per language \u2014 except `php`, which\n defaults to graphddb's vendored namespace\n (GraphDDB\\Runtime\\BehaviorContracts) so the generated module\n resolves against the PHP runtime this package ships.\n value_name: specifier\n schema:\n type: string\n\n - name: out\n aliases: [o]\n required: true\n description: Output directory for the generated behavior module.\n value_name: dir\n schema:\n type: string\n\n exits:\n '0':\n description: Generation succeeded.\n stdout:\n format: json\n schema:\n $ref: '#/components/schemas/GenerateResult'\n\n '1':\n description: Unexpected error.\n stderr:\n format: json\n schema:\n $ref: '#/components/schemas/Error'\n\n '2':\n description: Invalid arguments (missing/unreadable input or output).\n stderr:\n format: json\n schema:\n $ref: '#/components/schemas/Error'\n\n # \u2500\u2500 generate cloudformation \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n generate.cloudformation:\n summary: >-\n Generate an AWS CloudFormation template (DynamoDB table + GSIs) from\n TypeScript GraphDDB definitions.\n description: >-\n Loads the TypeScript entity models and builds the serializable\n manifest, then emits an AWS CloudFormation template describing the\n DynamoDB table(s) the single-table design maps onto: one\n `AWS::DynamoDB::Table` per physical table, with the base key schema\n (`PK` / `SK`), the unioned Global Secondary Indexes\n (`<indexName>PK` / `<indexName>SK`), `PAY_PER_REQUEST` billing, a\n `TableName` parameter (default = physical name), and Outputs\n (table name + ARN). Output is deterministic and, by default, YAML.\n usage:\n - graphddb generate cloudformation --entry models.ts --out table.yaml\n - graphddb generate cloudformation --entry models.ts --format json\n - graphddb generate cloudformation --entry models.ts --gsi-projection KEYS_ONLY --out table.yaml\n - graphddb generate cloudformation --entry models.ts --stream on --out table.yaml\n - graphddb generate cloudformation --entry models.ts --pitr --sse --table-class STANDARD_INFREQUENT_ACCESS --out table.yaml\n - graphddb generate cloudformation --entry models.ts --billing-mode PROVISIONED --rcu 10 --wcu 5 --out table.yaml\n - graphddb generate cloudformation --entry models.ts --billing-mode PROVISIONED --autoscale --autoscale-min 5 --autoscale-max 100 --autoscale-target 70 --out table.yaml\n\n effects:\n risk_level: low\n reads:\n - ts-definitions\n writes:\n - generated-code\n\n x-agent:\n recommended_before_use:\n - \"Ensure the TypeScript definitions type-check and lint cleanly.\"\n\n options:\n - name: entry\n aliases: [e]\n required: true\n description: >-\n Entry module that registers the entity models (side-effecting\n import).\n value_name: file\n schema:\n type: string\n file:\n mode: read\n exists: true\n media_type: application/typescript\n encoding: utf-8\n\n - name: out\n aliases: [o]\n description: >-\n Output file for the generated CloudFormation template. Written to\n stdout when omitted.\n value_name: file\n schema:\n type: string\n\n - name: format\n aliases: [f]\n description: Output serialization format (yaml or json).\n value_name: format\n schema:\n type: string\n enum: [yaml, json]\n default: yaml\n\n - name: gsi-projection\n description: >-\n GSI ProjectionType. ALL (default) projects every attribute;\n KEYS_ONLY projects only the key attributes.\n value_name: projection\n schema:\n type: string\n enum: [ALL, KEYS_ONLY]\n default: ALL\n\n - name: stream\n description: >-\n DynamoDB Streams (StreamSpecification NEW_AND_OLD_IMAGES) emission.\n auto (default) emits a stream only when the model set uses\n stream-based maintenance (updateMode:'stream'); on always emits;\n off never emits. When enabled, a StreamArn Output is added too.\n value_name: mode\n schema:\n type: string\n enum: [auto, on, off]\n default: auto\n\n - name: billing-mode\n description: >-\n DynamoDB billing mode. PAY_PER_REQUEST (default) is on-demand\n (no provisioned throughput). PROVISIONED emits BillingMode:\n PROVISIONED with ProvisionedThroughput (see --rcu / --wcu) on the\n table and every GSI, and unlocks Application Auto Scaling\n (--autoscale).\n value_name: mode\n schema:\n type: string\n enum: [PAY_PER_REQUEST, PROVISIONED]\n default: PAY_PER_REQUEST\n\n - name: rcu\n description: >-\n Provisioned ReadCapacityUnits (a positive integer) applied to the\n table and every GSI. Only valid with --billing-mode PROVISIONED\n (rejected with PAY_PER_REQUEST). Defaults to 5 when omitted.\n value_name: units\n schema:\n type: integer\n minimum: 1\n\n - name: wcu\n description: >-\n Provisioned WriteCapacityUnits (a positive integer) applied to the\n table and every GSI. Only valid with --billing-mode PROVISIONED\n (rejected with PAY_PER_REQUEST). Defaults to 5 when omitted.\n value_name: units\n schema:\n type: integer\n minimum: 1\n\n - name: autoscale\n description: >-\n Enable Application Auto Scaling. Emits an\n AWS::ApplicationAutoScaling::ScalableTarget +\n AWS::ApplicationAutoScaling::ScalingPolicy pair for the table read\n and write capacity AND for each GSI read and write capacity. Only\n valid with --billing-mode PROVISIONED (autoscaling is invalid on\n on-demand and is rejected). Off by default \u2014 no autoscaling\n resources are emitted unless this flag is passed.\n schema:\n type: boolean\n\n - name: autoscale-min\n description: >-\n Auto Scaling minimum capacity (MinCapacity) for every scalable\n target. Must be <= --autoscale-max. Only meaningful with\n --autoscale. Defaults to 5 when omitted.\n value_name: units\n schema:\n type: integer\n minimum: 1\n\n - name: autoscale-max\n description: >-\n Auto Scaling maximum capacity (MaxCapacity) for every scalable\n target. Must be >= --autoscale-min. Only meaningful with\n --autoscale. Defaults to 100 when omitted.\n value_name: units\n schema:\n type: integer\n minimum: 1\n\n - name: autoscale-target\n description: >-\n Auto Scaling target utilization percentage (TargetValue of the\n TargetTrackingScaling policy). Only meaningful with --autoscale.\n Defaults to 70 when omitted.\n value_name: percent\n schema:\n type: integer\n minimum: 1\n maximum: 100\n\n - name: pitr\n description: >-\n Enable point-in-time recovery (PointInTimeRecoverySpecification\n PointInTimeRecoveryEnabled:true). Off by default \u2014 the property is\n omitted entirely unless this flag is passed.\n schema:\n type: boolean\n\n - name: table-class\n description: >-\n DynamoDB table class. Omitted by default (AWS defaults to\n STANDARD); pass STANDARD or STANDARD_INFREQUENT_ACCESS to emit\n TableClass.\n value_name: class\n schema:\n type: string\n enum: [STANDARD, STANDARD_INFREQUENT_ACCESS]\n\n - name: sse\n description: >-\n Enable server-side encryption with the AWS-owned/managed key\n (SSESpecification SSEEnabled:true). Off by default \u2014 the property is\n omitted entirely unless this flag is passed.\n schema:\n type: boolean\n\n exits:\n '0':\n description: Generation succeeded.\n stdout:\n format: json\n schema:\n $ref: '#/components/schemas/GenerateResult'\n\n '1':\n description: Unexpected error.\n stderr:\n format: json\n schema:\n $ref: '#/components/schemas/Error'\n\n '2':\n description: Invalid arguments (missing/unreadable input or output).\n stderr:\n format: json\n schema:\n $ref: '#/components/schemas/Error'\n\n # \u2500\u2500 generate docs \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n generate.docs:\n summary: >-\n Generate model-specification documentation (Markdown + Mermaid) from\n TypeScript GraphDDB definitions.\n description: >-\n Loads the TypeScript entity models (and, optionally, the CQRS contract\n definitions), builds the serializable manifest / operations bundle, then\n renders human-facing model documentation \u2014 Table Overview, Entity\n Relationship Diagram, Physical Key Schema, Property Matrix, Entity\n Details, Access Patterns, Mutation Contracts, Maintained Access Paths,\n CDC, and CloudFormation summary \u2014 as Markdown with Mermaid diagrams. The\n layout is defined by bundled Handlebars templates users can override with\n --template-dir (per-partial) and extend with --helpers. Output is\n deterministic for a given set of inputs.\n usage:\n - graphddb generate docs --entry models.ts --out doc.md\n - graphddb generate docs --entry models.ts --contracts contracts.ts --out doc.md\n - graphddb generate docs --entry models.ts --out docs/\n - graphddb generate docs --entry models.ts --out docs/ --template-dir doc-templates/ --helpers doc-helpers.js\n\n effects:\n risk_level: low\n reads:\n - ts-definitions\n writes:\n - generated-code\n\n x-agent:\n recommended_before_use:\n - \"Ensure the TypeScript definitions type-check and lint cleanly.\"\n\n options:\n - name: entry\n aliases: [e]\n required: true\n description: >-\n Entry module that registers the entity models (side-effecting\n import). May also export contracts / contexts / transactions.\n value_name: file\n schema:\n type: string\n file:\n mode: read\n exists: true\n media_type: application/typescript\n encoding: utf-8\n\n - name: contracts\n description: >-\n Module exporting `contracts` (a map of publishQuery /\n publishCommand results \u2014 the CQRS Contract layer) used for the\n Access Patterns / Mutation Contracts sections. Defaults to the\n entry module when omitted. Optional.\n value_name: file\n schema:\n type: string\n file:\n mode: read\n exists: true\n media_type: application/typescript\n encoding: utf-8\n\n - name: contexts\n description: >-\n Module exporting `contexts` (context-ownership). Defaults to the\n contracts module (or the entry module) when omitted. Optional.\n value_name: file\n schema:\n type: string\n file:\n mode: read\n exists: true\n media_type: application/typescript\n encoding: utf-8\n\n - name: out\n aliases: [o]\n required: true\n description: >-\n Output path for the generated documentation. A file path ending in\n .md writes the single Markdown file at exactly that path (creating\n parent directories); any other value is treated as a directory and\n the file is written as <dir>/index.md.\n value_name: path\n schema:\n type: string\n\n - name: format\n aliases: [f]\n description: Output format. Only markdown is supported today.\n value_name: format\n schema:\n type: string\n enum: [markdown]\n default: markdown\n\n - name: split\n description: >-\n Output granularity. none (default) emits a single index.md; entity\n is reserved for a future per-entity split.\n value_name: mode\n schema:\n type: string\n enum: [none, entity]\n default: none\n\n - name: template-dir\n description: >-\n Directory of override <partial>.hbs templates. Each same-named\n partial (index / table-overview / er-diagram / key-schema /\n property-matrix / entity / access-pattern / maintained / cdc /\n cloudformation) overrides the bundled one; absent partials fall back\n to the bundled default.\n value_name: dir\n schema:\n type: string\n\n - name: helpers\n description: >-\n JS module whose default (or named `helpers`) export is a map of extra\n Handlebars helpers to register alongside the built-in set (eq / join\n / pascal / mermaidId / codeOrEmpty).\n value_name: file\n schema:\n type: string\n\n - name: billing-mode\n description: >-\n DynamoDB billing mode used in the Table Overview (shared with\n generate cloudformation). PAY_PER_REQUEST (default) or PROVISIONED.\n value_name: mode\n schema:\n type: string\n enum: [PAY_PER_REQUEST, PROVISIONED]\n default: PAY_PER_REQUEST\n\n - name: stream\n description: >-\n DynamoDB Streams state used in the Table Overview (shared with\n generate cloudformation). auto (default) detects stream-based\n maintenance (updateMode:'stream'); on always enabled; off never.\n value_name: mode\n schema:\n type: string\n enum: [auto, on, off]\n default: auto\n\n exits:\n '0':\n description: Generation succeeded.\n stdout:\n format: json\n schema:\n $ref: '#/components/schemas/GenerateResult'\n\n '1':\n description: Unexpected error.\n stderr:\n format: json\n schema:\n $ref: '#/components/schemas/Error'\n\n '2':\n description: Invalid arguments (missing/unreadable input or output).\n stderr:\n format: json\n schema:\n $ref: '#/components/schemas/Error'\n\n # \u2500\u2500 transform prepared \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n transform.prepared:\n summary: >-\n Lint and hoist-normalize `DDBModel.prepare` call sites (compile-time\n prepared statements, issue #206).\n description: >-\n A source-to-source build pass over application TypeScript files. It\n statically enforces the prepared-statement no-runtime-capture rule\n (a prepare body may reference only its `$` placeholder and\n module-static bindings; capturing a per-call runtime value \u2014 directly\n or via a helper call \u2014 is a loud error), and normalizes every\n verified INLINE `DDBModel.prepare(fn)` call site into a module-scope\n prepared slot so the plan compiles once per module and each call is\n a plain `.execute` (zero per-op planning / hashing \u2014 placement\n independent). Without --write it is a pure check (the build lint):\n violations exit non-zero and hoistable inline call sites are\n reported as notes. With --write, verified inline call sites are\n rewritten in place; files with violations are never rewritten.\n Idempotent: re-running on transformed output changes nothing.\n With --aot <artifact> (issue #208), the pass additionally compiles\n every verified prepare body at BUILD time into a static prepared-plan\n artifact (a generated TypeScript module): with --write it writes the\n artifact and rewrites each call site to load its static plan\n (`loadPreparedPlan(document, id, body)` \u2014 the body stays in source as\n the plan's compile source and fallback); without --write it is the\n DRIFT CHECK \u2014 it recompiles every plan and exits non-zero when the\n artifact is missing or differs (CI gate: model declarations changed\n without regenerating the artifact).\n usage:\n - graphddb transform prepared --src src/\n - graphddb transform prepared --src src/ --write\n - graphddb transform prepared --src src/app/handlers.ts --write\n - graphddb transform prepared --src src/ --aot src/graphddb.prepared.ts --write\n - graphddb transform prepared --src src/ --aot src/graphddb.prepared.ts\n\n effects:\n risk_level: medium\n reads:\n - ts-app-sources\n writes:\n - ts-app-sources\n\n x-agent:\n recommended_before_use:\n - \"Commit or stash pending changes first when using --write (it rewrites sources in place).\"\n\n options:\n - name: src\n aliases: [s]\n required: true\n description: >-\n A TypeScript source file, or a directory scanned recursively for\n .ts/.tsx/.mts/.cts files (node_modules, dist, hidden directories,\n and .d.ts files are skipped).\n value_name: path\n schema:\n type: string\n file:\n mode: read\n exists: true\n\n - name: write\n aliases: [w]\n description: >-\n Rewrite verified inline call sites in place (hoist\n normalization). Without it the command only checks and reports.\n schema:\n type: boolean\n\n - name: aot\n aliases: [a]\n description: >-\n Static prepared-plan artifact module path (issue #208). Enables\n build-time (AOT) compilation of every verified prepare body:\n with --write the artifact module is (re)generated and call sites\n are rewritten to load their static plan; without --write the\n pass recompiles and compares (drift check \u2014 a missing or\n differing artifact exits 1).\n value_name: artifact\n schema:\n type: string\n\n exits:\n '0':\n description: >-\n Check passed / transform applied. No no-runtime-capture\n violations were found.\n stdout:\n format: json\n schema:\n $ref: '#/components/schemas/TransformPreparedResult'\n\n '1':\n description: >-\n No-runtime-capture violations found, or --aot drift detected\n (reported in the result on stdout), or an unexpected error\n (reported on stderr).\n stdout:\n format: json\n schema:\n $ref: '#/components/schemas/TransformPreparedResult'\n\n '2':\n description: Invalid arguments (missing/unreadable input).\n stderr:\n format: json\n schema:\n $ref: '#/components/schemas/Error'\n\ncomponents:\n schemas:\n GenerateResult:\n type: object\n required: [status, outDir, files]\n properties:\n status:\n type: string\n enum: [ok]\n outDir:\n type: string\n description: Output directory the files were written to.\n files:\n type: array\n description: Paths of the generated files (relative to outDir).\n items:\n type: string\n Error:\n type: object\n required: [code, message]\n properties:\n code:\n type: string\n message:\n type: string\n TransformPreparedResult:\n type: object\n required: [status, files, hoisted, moduleScope, alreadyHoisted, errors, diagnostics]\n properties:\n status:\n type: string\n enum: [ok, violations, drift]\n files:\n type: array\n description: Source files scanned.\n items:\n type: string\n changedFiles:\n type: array\n description: Files rewritten in place (--write only).\n items:\n type: string\n hoisted:\n type: integer\n description: Inline call sites normalized (or normalizable in check mode).\n moduleScope:\n type: integer\n description: Call sites already evaluated once per module load (left as-is).\n alreadyHoisted:\n type: integer\n description: Call sites already normalized by a previous run.\n errors:\n type: integer\n description: No-runtime-capture violations found.\n artifact:\n type: string\n description: The static prepared-plan artifact path (--aot only).\n plans:\n type: integer\n description: Prepared plans compiled into the artifact (--aot only).\n drift:\n type: object\n description: >-\n Artifact drift detail (--aot check mode only; present when status\n is drift).\n properties:\n missing:\n type: boolean\n description: The artifact module does not exist.\n added:\n type: array\n items:\n type: string\n removed:\n type: array\n items:\n type: string\n changed:\n type: array\n items:\n type: string\n diagnostics:\n type: array\n description: Per-position lint diagnostics (errors and notes).\n items:\n type: object\n required: [code, category, message, file, line, column]\n properties:\n code:\n type: string\n category:\n type: string\n enum: [error, note]\n message:\n type: string\n file:\n type: string\n line:\n type: integer\n column:\n type: integer\n";
943
+ var CONTRACT_JSON_STR = '{\n "cli_contracts": "0.1.0",\n "info": {\n "title": "GraphDDB CLI",\n "version": "0.1.0",\n "description": "Contract for the graphddb code-generation CLI. The CLI reads TypeScript GraphDDB model + CQRS contract definitions (the single source of truth) and emits Python bindings (manifest.json, operations.json, types.py, repositories.py, __init__.py) for the Python bridge runtime.",\n "license": {\n "name": "MIT"\n },\n "contact": {\n "name": "foo-log-inc",\n "url": "https://github.com/foo-log-inc/graphddb"\n }\n },\n "artifact_slots": {\n "ts-definitions": {\n "description": "TypeScript GraphDDB definition modules (entity models + the CQRS publishQuery / publishCommand contracts) used as the single source of truth.",\n "direction": "read"\n },\n "generated-code": {\n "description": "Generated Python bindings and JSON specs written to the output directory (manifest.json, operations.json, types.py, repositories.py, __init__.py).",\n "direction": "write"\n },\n "ts-app-sources": {\n "description": "Application TypeScript sources containing `DDBModel.prepare` call sites. Read by the prepared-statement build lint; rewritten in place by `transform prepared --write` (hoist normalization, issue #206).",\n "direction": "write"\n }\n },\n "command_sets": {\n "graphddb": {\n "summary": "Graph data modeling on DynamoDB \u2014 code generation CLI.",\n "x-stdin": "No command reads from stdin. All inputs are provided via file options.",\n "commands": {\n "generate.python": {\n "summary": "Generate Python bindings from TypeScript GraphDDB definitions.",\n "description": "Loads the TypeScript entity models and CQRS contract definitions, builds the serializable manifest / operations bundle, and writes the Python bridge bindings (manifest.json, operations.json, types.py, repositories.py, __init__.py) to the output directory. Output is deterministic for a given set of inputs.",\n "usage": [\n "graphddb generate python --entry models.ts --contracts contracts.ts --out generated/",\n "graphddb generate python --entry definitions.ts --out generated/"\n ],\n "effects": {\n "risk_level": "low",\n "reads": [\n "ts-definitions"\n ],\n "writes": [\n "generated-code"\n ]\n },\n "x-agent": {\n "recommended_before_use": [\n "Ensure the TypeScript definitions type-check and lint cleanly."\n ]\n },\n "options": [\n {\n "name": "entry",\n "aliases": [\n "e"\n ],\n "required": true,\n "description": "Entry module that registers the entity models (side-effecting import). May also export contracts / contexts / transactions.",\n "value_name": "file",\n "schema": {\n "type": "string"\n },\n "file": {\n "mode": "read",\n "exists": true,\n "media_type": "application/typescript",\n "encoding": "utf-8"\n }\n },\n {\n "name": "transactions",\n "aliases": [\n "t"\n ],\n "description": "Module exporting `transactions` (a defineTransactions map). Defaults to the entry module when omitted. Optional \u2014 a project with no declarative transactions omits it.",\n "value_name": "file",\n "schema": {\n "type": "string"\n },\n "file": {\n "mode": "read",\n "exists": true,\n "media_type": "application/typescript",\n "encoding": "utf-8"\n }\n },\n {\n "name": "contracts",\n "description": "Module exporting `contracts` (a map of publishQuery / publishCommand results \u2014 the CQRS Contract layer). Defaults to the entry module when omitted. Optional \u2014 a project with no contracts omits it, and the output gains no `contracts` content.",\n "value_name": "file",\n "schema": {\n "type": "string"\n },\n "file": {\n "mode": "read",\n "exists": true,\n "media_type": "application/typescript",\n "encoding": "utf-8"\n }\n },\n {\n "name": "contexts",\n "description": "Module exporting `contexts` (context-ownership: context name \u2192 the Model / Contract names that belong to it). Defaults to the contracts module (or the entry module) when omitted. Optional \u2014 consumed by the boundary lint to tell own from foreign.",\n "value_name": "file",\n "schema": {\n "type": "string"\n },\n "file": {\n "mode": "read",\n "exists": true,\n "media_type": "application/typescript",\n "encoding": "utf-8"\n }\n },\n {\n "name": "dataclass",\n "description": "Emit Python result / element types as @dataclass classes instead of TypedDict (decimal / Optional / Connection mapped accordingly).",\n "schema": {\n "type": "boolean"\n }\n },\n {\n "name": "out",\n "aliases": [\n "o"\n ],\n "required": true,\n "description": "Output directory for the generated Python bindings.",\n "value_name": "dir",\n "schema": {\n "type": "string"\n }\n }\n ],\n "exits": {\n "0": {\n "description": "Generation succeeded.",\n "stdout": {\n "format": "json",\n "schema": {\n "$ref": "#/components/schemas/GenerateResult"\n }\n },\n "files": [\n {\n "path": "{options.out}/manifest.json",\n "required": true,\n "media_type": "application/json",\n "description": "Entity / table / key / relation metadata."\n },\n {\n "path": "{options.out}/operations.json",\n "required": true,\n "media_type": "application/json",\n "description": "Per-query / per-command execution specs."\n },\n {\n "path": "{options.out}/types.py",\n "required": true,\n "media_type": "text/x-python",\n "description": "TypedDict result types derived from query selects."\n },\n {\n "path": "{options.out}/repositories.py",\n "required": true,\n "media_type": "text/x-python",\n "description": "Per-entity repository classes (sync methods)."\n },\n {\n "path": "{options.out}/__init__.py",\n "required": true,\n "media_type": "text/x-python",\n "description": "Package re-exports for the generated bindings."\n }\n ]\n },\n "1": {\n "description": "Unexpected error.",\n "stderr": {\n "format": "json",\n "schema": {\n "$ref": "#/components/schemas/Error"\n }\n }\n },\n "2": {\n "description": "Invalid arguments (missing/unreadable input or output).",\n "stderr": {\n "format": "json",\n "schema": {\n "$ref": "#/components/schemas/Error"\n }\n }\n }\n }\n },\n "generate.php": {\n "summary": "Generate typed PHP bindings (repositories + result DTOs) from TypeScript GraphDDB definitions.",\n "description": "Loads the TypeScript entity models and CQRS contract definitions, builds the serializable manifest / operations bundle, and writes typed PHP bindings \u2014 one `<Entity>Repository` per entity plus a result DTO (and `<Item>Connection`) per query result shape \u2014 into the output directory. Each repository wraps the PHP `GraphDDBRuntime`; query methods return a hydrated `?<Result>` typed object, command methods return void, both calling the runtime by the original operation id. The layout is defined by bundled Handlebars templates users can override with --template-dir (per-partial) and extend with --helpers; type resolution always lives in code (the templates customize layout, not types). Output is deterministic for a given set of inputs. The `--typed` flag selects the typed-binding output (the only mode today; reserved for a future raw-binding mode).",\n "usage": [\n "graphddb generate php --typed --entry models.ts --contracts contracts.ts --out generated/",\n "graphddb generate php --typed --entry definitions.ts --out generated/",\n "graphddb generate php --typed --entry definitions.ts --out generated/ --template-dir php-templates/ --helpers php-helpers.js"\n ],\n "effects": {\n "risk_level": "low",\n "reads": [\n "ts-definitions"\n ],\n "writes": [\n "generated-code"\n ]\n },\n "x-agent": {\n "recommended_before_use": [\n "Ensure the TypeScript definitions type-check and lint cleanly."\n ]\n },\n "options": [\n {\n "name": "entry",\n "aliases": [\n "e"\n ],\n "required": true,\n "description": "Entry module that registers the entity models (side-effecting import). May also export contracts / contexts / transactions.",\n "value_name": "file",\n "schema": {\n "type": "string"\n },\n "file": {\n "mode": "read",\n "exists": true,\n "media_type": "application/typescript",\n "encoding": "utf-8"\n }\n },\n {\n "name": "transactions",\n "aliases": [\n "t"\n ],\n "description": "Module exporting `transactions` (a defineTransactions map). Defaults to the entry module when omitted. Optional \u2014 a project with no declarative transactions omits it.",\n "value_name": "file",\n "schema": {\n "type": "string"\n },\n "file": {\n "mode": "read",\n "exists": true,\n "media_type": "application/typescript",\n "encoding": "utf-8"\n }\n },\n {\n "name": "contracts",\n "description": "Module exporting `contracts` (the CQRS Contract layer). Defaults to the entry module when omitted. Optional \u2014 contract-internal operations are excluded from the generated binding surface.",\n "value_name": "file",\n "schema": {\n "type": "string"\n },\n "file": {\n "mode": "read",\n "exists": true,\n "media_type": "application/typescript",\n "encoding": "utf-8"\n }\n },\n {\n "name": "contexts",\n "description": "Module exporting `contexts` (context-ownership). Defaults to the contracts module (or the entry module) when omitted. Optional.",\n "value_name": "file",\n "schema": {\n "type": "string"\n },\n "file": {\n "mode": "read",\n "exists": true,\n "media_type": "application/typescript",\n "encoding": "utf-8"\n }\n },\n {\n "name": "typed",\n "description": "Emit the typed-binding output (repositories + result DTOs). The only output mode today; reserved to distinguish a future raw-binding mode.",\n "schema": {\n "type": "boolean"\n }\n },\n {\n "name": "template-dir",\n "description": "Directory of override <partial>.hbs templates. Each same-named partial (file / dto-class / connection-class / repo-class / repo-method / tx-class / tx-method) overrides the bundled one; absent partials fall back to the bundled default. Layout only \u2014 type resolution always lives in code.",\n "value_name": "dir",\n "schema": {\n "type": "string"\n }\n },\n {\n "name": "helpers",\n "description": "JS module whose default (or named `helpers`) export is a map of extra Handlebars helpers to register alongside the built-in set.",\n "value_name": "file",\n "schema": {\n "type": "string"\n }\n },\n {\n "name": "out",\n "aliases": [\n "o"\n ],\n "required": true,\n "description": "Output directory for the generated PHP bindings.",\n "value_name": "dir",\n "schema": {\n "type": "string"\n }\n }\n ],\n "exits": {\n "0": {\n "description": "Generation succeeded.",\n "stdout": {\n "format": "json",\n "schema": {\n "$ref": "#/components/schemas/GenerateResult"\n }\n }\n },\n "1": {\n "description": "Unexpected error.",\n "stderr": {\n "format": "json",\n "schema": {\n "$ref": "#/components/schemas/Error"\n }\n }\n },\n "2": {\n "description": "Invalid arguments (missing/unreadable input or output).",\n "stderr": {\n "format": "json",\n "schema": {\n "$ref": "#/components/schemas/Error"\n }\n }\n }\n }\n },\n "generate.rust": {\n "summary": "Generate typed Rust bindings (repositories + serde result structs) from TypeScript GraphDDB definitions.",\n "description": "Loads the TypeScript entity models and CQRS contract definitions, builds the serializable manifest / operations bundle, and writes a single `bindings.rs` module of typed Rust bindings \u2014 a serde-`Deserialize` result struct (and `<Item>Connection`) per query result shape plus one `<Entity>Repository` per entity \u2014 into the output directory. Each repository holds an `Arc<GraphDDBRuntime>`; query methods return `Result<Option<T>, GraphDDBError>` (the deserialized typed result), command methods return `Result<(), GraphDDBError>`, both calling the runtime by the original operation id. The layout is defined by bundled Handlebars templates users can override with --template-dir (per-partial) and extend with --helpers; type resolution always lives in code (the templates customize layout, not types). Output is deterministic for a given set of inputs. The `--typed` flag selects the typed-binding output (the only mode today; reserved for a future raw-binding mode).",\n "usage": [\n "graphddb generate rust --typed --entry models.ts --contracts contracts.ts --out generated/",\n "graphddb generate rust --typed --entry definitions.ts --out generated/",\n "graphddb generate rust --typed --entry definitions.ts --out generated/ --template-dir rust-templates/ --helpers rust-helpers.js"\n ],\n "effects": {\n "risk_level": "low",\n "reads": [\n "ts-definitions"\n ],\n "writes": [\n "generated-code"\n ]\n },\n "x-agent": {\n "recommended_before_use": [\n "Ensure the TypeScript definitions type-check and lint cleanly."\n ]\n },\n "options": [\n {\n "name": "entry",\n "aliases": [\n "e"\n ],\n "required": true,\n "description": "Entry module that registers the entity models (side-effecting import). May also export contracts / contexts / transactions.",\n "value_name": "file",\n "schema": {\n "type": "string"\n },\n "file": {\n "mode": "read",\n "exists": true,\n "media_type": "application/typescript",\n "encoding": "utf-8"\n }\n },\n {\n "name": "transactions",\n "aliases": [\n "t"\n ],\n "description": "Module exporting `transactions` (a defineTransactions map). Defaults to the entry module when omitted. Optional \u2014 a project with no declarative transactions omits it.",\n "value_name": "file",\n "schema": {\n "type": "string"\n },\n "file": {\n "mode": "read",\n "exists": true,\n "media_type": "application/typescript",\n "encoding": "utf-8"\n }\n },\n {\n "name": "contracts",\n "description": "Module exporting `contracts` (the CQRS Contract layer). Defaults to the entry module when omitted. Optional \u2014 contract-internal operations are excluded from the generated binding surface.",\n "value_name": "file",\n "schema": {\n "type": "string"\n },\n "file": {\n "mode": "read",\n "exists": true,\n "media_type": "application/typescript",\n "encoding": "utf-8"\n }\n },\n {\n "name": "contexts",\n "description": "Module exporting `contexts` (context-ownership). Defaults to the contracts module (or the entry module) when omitted. Optional.",\n "value_name": "file",\n "schema": {\n "type": "string"\n },\n "file": {\n "mode": "read",\n "exists": true,\n "media_type": "application/typescript",\n "encoding": "utf-8"\n }\n },\n {\n "name": "typed",\n "description": "Emit the typed-binding output (repositories + result structs). The only output mode today; reserved to distinguish a future raw-binding mode.",\n "schema": {\n "type": "boolean"\n }\n },\n {\n "name": "template-dir",\n "description": "Directory of override <partial>.hbs templates. Each same-named partial (file / result-struct / connection-struct / repo-struct / repo-method / tx-struct / tx-method) overrides the bundled one; absent partials fall back to the bundled default. Layout only \u2014 type resolution always lives in code.",\n "value_name": "dir",\n "schema": {\n "type": "string"\n }\n },\n {\n "name": "helpers",\n "description": "JS module whose default (or named `helpers`) export is a map of extra Handlebars helpers to register alongside the built-in set.",\n "value_name": "file",\n "schema": {\n "type": "string"\n }\n },\n {\n "name": "out",\n "aliases": [\n "o"\n ],\n "required": true,\n "description": "Output directory for the generated Rust bindings.",\n "value_name": "dir",\n "schema": {\n "type": "string"\n }\n }\n ],\n "exits": {\n "0": {\n "description": "Generation succeeded.",\n "stdout": {\n "format": "json",\n "schema": {\n "$ref": "#/components/schemas/GenerateResult"\n }\n }\n },\n "1": {\n "description": "Unexpected error.",\n "stderr": {\n "format": "json",\n "schema": {\n "$ref": "#/components/schemas/Error"\n }\n }\n },\n "2": {\n "description": "Invalid arguments (missing/unreadable input or output).",\n "stderr": {\n "format": "json",\n "schema": {\n "$ref": "#/components/schemas/Error"\n }\n }\n }\n }\n },\n "generate.go": {\n "summary": "Generate typed Go bindings (repositories + json result structs) from TypeScript GraphDDB definitions.",\n "description": "Loads the TypeScript entity models and CQRS contract definitions, builds the serializable manifest / operations bundle, and writes a single `bindings.go` package of typed Go bindings \u2014 a json result struct (and `<Item>Connection`) per query result shape plus one `<Entity>Repository` per entity \u2014 into the output directory. Each repository holds a `*graphddb_runtime.GraphDDBRuntime`; query methods return `(*T, error)` (the deserialized typed result; a nil pointer for no match), command methods return `error`, both calling the runtime by the original operation id. Numbers are precision-strict (`json.Number`), so a large integer round-trips losslessly. The layout is defined by bundled Handlebars templates users can override with --template-dir (per-partial) and extend with --helpers; type resolution always lives in code (the templates customize layout, not types). Output is deterministic for a given set of inputs and gofmt-normalized. The `--typed` flag selects the typed-binding output (the only mode today; reserved for a future raw-binding mode).",\n "usage": [\n "graphddb generate go --typed --entry models.ts --contracts contracts.ts --out generated/",\n "graphddb generate go --typed --entry definitions.ts --out generated/",\n "graphddb generate go --typed --entry definitions.ts --out generated/ --template-dir go-templates/ --helpers go-helpers.js"\n ],\n "effects": {\n "risk_level": "low",\n "reads": [\n "ts-definitions"\n ],\n "writes": [\n "generated-code"\n ]\n },\n "x-agent": {\n "recommended_before_use": [\n "Ensure the TypeScript definitions type-check and lint cleanly."\n ]\n },\n "options": [\n {\n "name": "entry",\n "aliases": [\n "e"\n ],\n "required": true,\n "description": "Entry module that registers the entity models (side-effecting import). May also export contracts / contexts / transactions.",\n "value_name": "file",\n "schema": {\n "type": "string"\n },\n "file": {\n "mode": "read",\n "exists": true,\n "media_type": "application/typescript",\n "encoding": "utf-8"\n }\n },\n {\n "name": "transactions",\n "aliases": [\n "t"\n ],\n "description": "Module exporting `transactions` (a defineTransactions map). Defaults to the entry module when omitted. Optional \u2014 a project with no declarative transactions omits it.",\n "value_name": "file",\n "schema": {\n "type": "string"\n },\n "file": {\n "mode": "read",\n "exists": true,\n "media_type": "application/typescript",\n "encoding": "utf-8"\n }\n },\n {\n "name": "contracts",\n "description": "Module exporting `contracts` (the CQRS Contract layer). Defaults to the entry module when omitted. Optional \u2014 contract-internal operations are excluded from the generated binding surface.",\n "value_name": "file",\n "schema": {\n "type": "string"\n },\n "file": {\n "mode": "read",\n "exists": true,\n "media_type": "application/typescript",\n "encoding": "utf-8"\n }\n },\n {\n "name": "contexts",\n "description": "Module exporting `contexts` (context-ownership). Defaults to the contracts module (or the entry module) when omitted. Optional.",\n "value_name": "file",\n "schema": {\n "type": "string"\n },\n "file": {\n "mode": "read",\n "exists": true,\n "media_type": "application/typescript",\n "encoding": "utf-8"\n }\n },\n {\n "name": "typed",\n "description": "Emit the typed-binding output (repositories + result structs). The only output mode today; reserved to distinguish a future raw-binding mode.",\n "schema": {\n "type": "boolean"\n }\n },\n {\n "name": "template-dir",\n "description": "Directory of override <partial>.hbs templates. Each same-named partial (file / result-struct / connection-struct / repo-struct / repo-method / tx-struct / tx-method) overrides the bundled one; absent partials fall back to the bundled default. Layout only \u2014 type resolution always lives in code.",\n "value_name": "dir",\n "schema": {\n "type": "string"\n }\n },\n {\n "name": "helpers",\n "description": "JS module whose default (or named `helpers`) export is a map of extra Handlebars helpers to register alongside the built-in set.",\n "value_name": "file",\n "schema": {\n "type": "string"\n }\n },\n {\n "name": "out",\n "aliases": [\n "o"\n ],\n "required": true,\n "description": "Output directory for the generated Go bindings.",\n "value_name": "dir",\n "schema": {\n "type": "string"\n }\n }\n ],\n "exits": {\n "0": {\n "description": "Generation succeeded.",\n "stdout": {\n "format": "json",\n "schema": {\n "$ref": "#/components/schemas/GenerateResult"\n }\n }\n },\n "1": {\n "description": "Unexpected error.",\n "stderr": {\n "format": "json",\n "schema": {\n "$ref": "#/components/schemas/Error"\n }\n }\n },\n "2": {\n "description": "Invalid arguments (missing/unreadable input or output).",\n "stderr": {\n "format": "json",\n "schema": {\n "$ref": "#/components/schemas/Error"\n }\n }\n }\n }\n },\n "generate.behaviors": {\n "summary": "Generate a native behavior module (the codegen-static endpoint) via the upstream behavior-contracts common Generator.",\n "description": "Loads the TypeScript entity models and CQRS contract definitions, builds the serializable operations bundle, wraps its universal components[] into the portable component-graph IR envelope ({irVersion, exprVersion, components} \u2014 scp-ir-architecture.md \xA75), and hands it to behavior-contracts\' common Generator (`generateModule`, foo-ogawa/behavior-contracts#13) to emit ONE native module for the selected language (issue #257). graphddb adds no generation logic: envelope + invoke + file write only. The generated module embeds the IR as a native literal with the spec versions and the IR fingerprint baked in (fail-closed load-time checks, the #208 prepared-artifact discipline) and exposes a `bind(handlers)` accessor that delegates to the runtime core \u2014 handlers are always injected at the boundary by the consuming runtime (the graphddb per-language behavior-exec seams). This is the OPT-IN static endpoint (\xA77.3 endpoint 3); the JSON-dynamic operations.json path remains the default and is permanently supported. Output is deterministic for a given set of inputs.",\n "usage": [\n "graphddb generate behaviors --lang ts --entry models.ts --contracts contracts.ts --out generated/",\n "graphddb generate behaviors --lang go --entry models.ts --contracts contracts.ts --out generated/",\n "graphddb generate behaviors --lang python --entry definitions.ts --out generated/",\n "graphddb generate behaviors --lang rust --entry definitions.ts --out generated/ --runtime-import behavior_contracts",\n "graphddb generate behaviors --lang php --entry definitions.ts --out generated/"\n ],\n "effects": {\n "risk_level": "low",\n "reads": [\n "ts-definitions"\n ],\n "writes": [\n "generated-code"\n ]\n },\n "x-agent": {\n "recommended_before_use": [\n "Ensure the TypeScript definitions type-check and lint cleanly."\n ]\n },\n "options": [\n {\n "name": "lang",\n "aliases": [\n "l"\n ],\n "required": true,\n "description": "Target language of the generated behavior module. `ts` emits a typed TypeScript module, `python` a dict-literal module, `go` a JNode composite-literal package, `rust` a json!-constructor module (requires Rust >= 1.80 \u2014 std::sync::LazyLock), `php` a require-scoped module value.",\n "value_name": "lang",\n "schema": {\n "type": "string",\n "enum": [\n "ts",\n "python",\n "go",\n "rust",\n "php"\n ]\n }\n },\n {\n "name": "entry",\n "aliases": [\n "e"\n ],\n "required": true,\n "description": "Entry module that registers the entity models (side-effecting import). May also export contracts / contexts / transactions.",\n "value_name": "file",\n "schema": {\n "type": "string"\n },\n "file": {\n "mode": "read",\n "exists": true,\n "media_type": "application/typescript",\n "encoding": "utf-8"\n }\n },\n {\n "name": "transactions",\n "aliases": [\n "t"\n ],\n "description": "Module exporting `transactions` (a defineTransactions map). Defaults to the entry module when omitted. Optional.",\n "value_name": "file",\n "schema": {\n "type": "string"\n },\n "file": {\n "mode": "read",\n "exists": true,\n "media_type": "application/typescript",\n "encoding": "utf-8"\n }\n },\n {\n "name": "contracts",\n "description": "Module exporting `contracts` (the CQRS Contract layer). Defaults to the entry module when omitted. Optional.",\n "value_name": "file",\n "schema": {\n "type": "string"\n },\n "file": {\n "mode": "read",\n "exists": true,\n "media_type": "application/typescript",\n "encoding": "utf-8"\n }\n },\n {\n "name": "contexts",\n "description": "Module exporting `contexts` (context-ownership). Defaults to the contracts module (or the entry module) when omitted. Optional.",\n "value_name": "file",\n "schema": {\n "type": "string"\n },\n "file": {\n "mode": "read",\n "exists": true,\n "media_type": "application/typescript",\n "encoding": "utf-8"\n }\n },\n {\n "name": "runtime-import",\n "description": "Module specifier the generated module imports the behavior-contracts runtime core from. Defaults to the emitter\'s published package name per language \u2014 except `php`, which defaults to graphddb\'s vendored namespace (GraphDDB\\\\Runtime\\\\BehaviorContracts) so the generated module resolves against the PHP runtime this package ships.",\n "value_name": "specifier",\n "schema": {\n "type": "string"\n }\n },\n {\n "name": "out",\n "aliases": [\n "o"\n ],\n "required": true,\n "description": "Output directory for the generated behavior module.",\n "value_name": "dir",\n "schema": {\n "type": "string"\n }\n }\n ],\n "exits": {\n "0": {\n "description": "Generation succeeded.",\n "stdout": {\n "format": "json",\n "schema": {\n "$ref": "#/components/schemas/GenerateResult"\n }\n }\n },\n "1": {\n "description": "Unexpected error.",\n "stderr": {\n "format": "json",\n "schema": {\n "$ref": "#/components/schemas/Error"\n }\n }\n },\n "2": {\n "description": "Invalid arguments (missing/unreadable input or output).",\n "stderr": {\n "format": "json",\n "schema": {\n "$ref": "#/components/schemas/Error"\n }\n }\n }\n }\n },\n "generate.cloudformation": {\n "summary": "Generate an AWS CloudFormation template (DynamoDB table + GSIs) from TypeScript GraphDDB definitions.",\n "description": "Loads the TypeScript entity models and builds the serializable manifest, then emits an AWS CloudFormation template describing the DynamoDB table(s) the single-table design maps onto: one `AWS::DynamoDB::Table` per physical table, with the base key schema (`PK` / `SK`), the unioned Global Secondary Indexes (`<indexName>PK` / `<indexName>SK`), `PAY_PER_REQUEST` billing, a `TableName` parameter (default = physical name), and Outputs (table name + ARN). Output is deterministic and, by default, YAML.",\n "usage": [\n "graphddb generate cloudformation --entry models.ts --out table.yaml",\n "graphddb generate cloudformation --entry models.ts --format json",\n "graphddb generate cloudformation --entry models.ts --gsi-projection KEYS_ONLY --out table.yaml",\n "graphddb generate cloudformation --entry models.ts --stream on --out table.yaml",\n "graphddb generate cloudformation --entry models.ts --pitr --sse --table-class STANDARD_INFREQUENT_ACCESS --out table.yaml",\n "graphddb generate cloudformation --entry models.ts --billing-mode PROVISIONED --rcu 10 --wcu 5 --out table.yaml",\n "graphddb generate cloudformation --entry models.ts --billing-mode PROVISIONED --autoscale --autoscale-min 5 --autoscale-max 100 --autoscale-target 70 --out table.yaml"\n ],\n "effects": {\n "risk_level": "low",\n "reads": [\n "ts-definitions"\n ],\n "writes": [\n "generated-code"\n ]\n },\n "x-agent": {\n "recommended_before_use": [\n "Ensure the TypeScript definitions type-check and lint cleanly."\n ]\n },\n "options": [\n {\n "name": "entry",\n "aliases": [\n "e"\n ],\n "required": true,\n "description": "Entry module that registers the entity models (side-effecting import).",\n "value_name": "file",\n "schema": {\n "type": "string"\n },\n "file": {\n "mode": "read",\n "exists": true,\n "media_type": "application/typescript",\n "encoding": "utf-8"\n }\n },\n {\n "name": "out",\n "aliases": [\n "o"\n ],\n "description": "Output file for the generated CloudFormation template. Written to stdout when omitted.",\n "value_name": "file",\n "schema": {\n "type": "string"\n }\n },\n {\n "name": "format",\n "aliases": [\n "f"\n ],\n "description": "Output serialization format (yaml or json).",\n "value_name": "format",\n "schema": {\n "type": "string",\n "enum": [\n "yaml",\n "json"\n ],\n "default": "yaml"\n }\n },\n {\n "name": "gsi-projection",\n "description": "GSI ProjectionType. ALL (default) projects every attribute; KEYS_ONLY projects only the key attributes.",\n "value_name": "projection",\n "schema": {\n "type": "string",\n "enum": [\n "ALL",\n "KEYS_ONLY"\n ],\n "default": "ALL"\n }\n },\n {\n "name": "stream",\n "description": "DynamoDB Streams (StreamSpecification NEW_AND_OLD_IMAGES) emission. auto (default) emits a stream only when the model set uses stream-based maintenance (updateMode:\'stream\'); on always emits; off never emits. When enabled, a StreamArn Output is added too.",\n "value_name": "mode",\n "schema": {\n "type": "string",\n "enum": [\n "auto",\n "on",\n "off"\n ],\n "default": "auto"\n }\n },\n {\n "name": "billing-mode",\n "description": "DynamoDB billing mode. PAY_PER_REQUEST (default) is on-demand (no provisioned throughput). PROVISIONED emits BillingMode: PROVISIONED with ProvisionedThroughput (see --rcu / --wcu) on the table and every GSI, and unlocks Application Auto Scaling (--autoscale).",\n "value_name": "mode",\n "schema": {\n "type": "string",\n "enum": [\n "PAY_PER_REQUEST",\n "PROVISIONED"\n ],\n "default": "PAY_PER_REQUEST"\n }\n },\n {\n "name": "rcu",\n "description": "Provisioned ReadCapacityUnits (a positive integer) applied to the table and every GSI. Only valid with --billing-mode PROVISIONED (rejected with PAY_PER_REQUEST). Defaults to 5 when omitted.",\n "value_name": "units",\n "schema": {\n "type": "integer",\n "minimum": 1\n }\n },\n {\n "name": "wcu",\n "description": "Provisioned WriteCapacityUnits (a positive integer) applied to the table and every GSI. Only valid with --billing-mode PROVISIONED (rejected with PAY_PER_REQUEST). Defaults to 5 when omitted.",\n "value_name": "units",\n "schema": {\n "type": "integer",\n "minimum": 1\n }\n },\n {\n "name": "autoscale",\n "description": "Enable Application Auto Scaling. Emits an AWS::ApplicationAutoScaling::ScalableTarget + AWS::ApplicationAutoScaling::ScalingPolicy pair for the table read and write capacity AND for each GSI read and write capacity. Only valid with --billing-mode PROVISIONED (autoscaling is invalid on on-demand and is rejected). Off by default \u2014 no autoscaling resources are emitted unless this flag is passed.",\n "schema": {\n "type": "boolean"\n }\n },\n {\n "name": "autoscale-min",\n "description": "Auto Scaling minimum capacity (MinCapacity) for every scalable target. Must be <= --autoscale-max. Only meaningful with --autoscale. Defaults to 5 when omitted.",\n "value_name": "units",\n "schema": {\n "type": "integer",\n "minimum": 1\n }\n },\n {\n "name": "autoscale-max",\n "description": "Auto Scaling maximum capacity (MaxCapacity) for every scalable target. Must be >= --autoscale-min. Only meaningful with --autoscale. Defaults to 100 when omitted.",\n "value_name": "units",\n "schema": {\n "type": "integer",\n "minimum": 1\n }\n },\n {\n "name": "autoscale-target",\n "description": "Auto Scaling target utilization percentage (TargetValue of the TargetTrackingScaling policy). Only meaningful with --autoscale. Defaults to 70 when omitted.",\n "value_name": "percent",\n "schema": {\n "type": "integer",\n "minimum": 1,\n "maximum": 100\n }\n },\n {\n "name": "pitr",\n "description": "Enable point-in-time recovery (PointInTimeRecoverySpecification PointInTimeRecoveryEnabled:true). Off by default \u2014 the property is omitted entirely unless this flag is passed.",\n "schema": {\n "type": "boolean"\n }\n },\n {\n "name": "table-class",\n "description": "DynamoDB table class. Omitted by default (AWS defaults to STANDARD); pass STANDARD or STANDARD_INFREQUENT_ACCESS to emit TableClass.",\n "value_name": "class",\n "schema": {\n "type": "string",\n "enum": [\n "STANDARD",\n "STANDARD_INFREQUENT_ACCESS"\n ]\n }\n },\n {\n "name": "sse",\n "description": "Enable server-side encryption with the AWS-owned/managed key (SSESpecification SSEEnabled:true). Off by default \u2014 the property is omitted entirely unless this flag is passed.",\n "schema": {\n "type": "boolean"\n }\n }\n ],\n "exits": {\n "0": {\n "description": "Generation succeeded.",\n "stdout": {\n "format": "json",\n "schema": {\n "$ref": "#/components/schemas/GenerateResult"\n }\n }\n },\n "1": {\n "description": "Unexpected error.",\n "stderr": {\n "format": "json",\n "schema": {\n "$ref": "#/components/schemas/Error"\n }\n }\n },\n "2": {\n "description": "Invalid arguments (missing/unreadable input or output).",\n "stderr": {\n "format": "json",\n "schema": {\n "$ref": "#/components/schemas/Error"\n }\n }\n }\n }\n },\n "generate.docs": {\n "summary": "Generate model-specification documentation (Markdown + Mermaid) from TypeScript GraphDDB definitions.",\n "description": "Loads the TypeScript entity models (and, optionally, the CQRS contract definitions), builds the serializable manifest / operations bundle, then renders human-facing model documentation \u2014 Table Overview, Entity Relationship Diagram, Physical Key Schema, Property Matrix, Entity Details, Access Patterns, Mutation Contracts, Maintained Access Paths, CDC, and CloudFormation summary \u2014 as Markdown with Mermaid diagrams. The layout is defined by bundled Handlebars templates users can override with --template-dir (per-partial) and extend with --helpers. Output is deterministic for a given set of inputs.",\n "usage": [\n "graphddb generate docs --entry models.ts --out doc.md",\n "graphddb generate docs --entry models.ts --contracts contracts.ts --out doc.md",\n "graphddb generate docs --entry models.ts --out docs/",\n "graphddb generate docs --entry models.ts --out docs/ --template-dir doc-templates/ --helpers doc-helpers.js"\n ],\n "effects": {\n "risk_level": "low",\n "reads": [\n "ts-definitions"\n ],\n "writes": [\n "generated-code"\n ]\n },\n "x-agent": {\n "recommended_before_use": [\n "Ensure the TypeScript definitions type-check and lint cleanly."\n ]\n },\n "options": [\n {\n "name": "entry",\n "aliases": [\n "e"\n ],\n "required": true,\n "description": "Entry module that registers the entity models (side-effecting import). May also export contracts / contexts / transactions.",\n "value_name": "file",\n "schema": {\n "type": "string"\n },\n "file": {\n "mode": "read",\n "exists": true,\n "media_type": "application/typescript",\n "encoding": "utf-8"\n }\n },\n {\n "name": "contracts",\n "description": "Module exporting `contracts` (a map of publishQuery / publishCommand results \u2014 the CQRS Contract layer) used for the Access Patterns / Mutation Contracts sections. Defaults to the entry module when omitted. Optional.",\n "value_name": "file",\n "schema": {\n "type": "string"\n },\n "file": {\n "mode": "read",\n "exists": true,\n "media_type": "application/typescript",\n "encoding": "utf-8"\n }\n },\n {\n "name": "contexts",\n "description": "Module exporting `contexts` (context-ownership). Defaults to the contracts module (or the entry module) when omitted. Optional.",\n "value_name": "file",\n "schema": {\n "type": "string"\n },\n "file": {\n "mode": "read",\n "exists": true,\n "media_type": "application/typescript",\n "encoding": "utf-8"\n }\n },\n {\n "name": "out",\n "aliases": [\n "o"\n ],\n "required": true,\n "description": "Output path for the generated documentation. A file path ending in .md writes the single Markdown file at exactly that path (creating parent directories); any other value is treated as a directory and the file is written as <dir>/index.md.",\n "value_name": "path",\n "schema": {\n "type": "string"\n }\n },\n {\n "name": "format",\n "aliases": [\n "f"\n ],\n "description": "Output format. Only markdown is supported today.",\n "value_name": "format",\n "schema": {\n "type": "string",\n "enum": [\n "markdown"\n ],\n "default": "markdown"\n }\n },\n {\n "name": "split",\n "description": "Output granularity. none (default) emits a single index.md; entity is reserved for a future per-entity split.",\n "value_name": "mode",\n "schema": {\n "type": "string",\n "enum": [\n "none",\n "entity"\n ],\n "default": "none"\n }\n },\n {\n "name": "template-dir",\n "description": "Directory of override <partial>.hbs templates. Each same-named partial (index / table-overview / er-diagram / key-schema / property-matrix / entity / access-pattern / maintained / cdc / cloudformation) overrides the bundled one; absent partials fall back to the bundled default.",\n "value_name": "dir",\n "schema": {\n "type": "string"\n }\n },\n {\n "name": "helpers",\n "description": "JS module whose default (or named `helpers`) export is a map of extra Handlebars helpers to register alongside the built-in set (eq / join / pascal / mermaidId / codeOrEmpty).",\n "value_name": "file",\n "schema": {\n "type": "string"\n }\n },\n {\n "name": "billing-mode",\n "description": "DynamoDB billing mode used in the Table Overview (shared with generate cloudformation). PAY_PER_REQUEST (default) or PROVISIONED.",\n "value_name": "mode",\n "schema": {\n "type": "string",\n "enum": [\n "PAY_PER_REQUEST",\n "PROVISIONED"\n ],\n "default": "PAY_PER_REQUEST"\n }\n },\n {\n "name": "stream",\n "description": "DynamoDB Streams state used in the Table Overview (shared with generate cloudformation). auto (default) detects stream-based maintenance (updateMode:\'stream\'); on always enabled; off never.",\n "value_name": "mode",\n "schema": {\n "type": "string",\n "enum": [\n "auto",\n "on",\n "off"\n ],\n "default": "auto"\n }\n }\n ],\n "exits": {\n "0": {\n "description": "Generation succeeded.",\n "stdout": {\n "format": "json",\n "schema": {\n "$ref": "#/components/schemas/GenerateResult"\n }\n }\n },\n "1": {\n "description": "Unexpected error.",\n "stderr": {\n "format": "json",\n "schema": {\n "$ref": "#/components/schemas/Error"\n }\n }\n },\n "2": {\n "description": "Invalid arguments (missing/unreadable input or output).",\n "stderr": {\n "format": "json",\n "schema": {\n "$ref": "#/components/schemas/Error"\n }\n }\n }\n }\n },\n "transform.prepared": {\n "summary": "Lint and hoist-normalize `DDBModel.prepare` call sites (compile-time prepared statements, issue #206).",\n "description": "A source-to-source build pass over application TypeScript files. It statically enforces the prepared-statement no-runtime-capture rule (a prepare body may reference only its `$` placeholder and module-static bindings; capturing a per-call runtime value \u2014 directly or via a helper call \u2014 is a loud error), and normalizes every verified INLINE `DDBModel.prepare(fn)` call site into a module-scope prepared slot so the plan compiles once per module and each call is a plain `.execute` (zero per-op planning / hashing \u2014 placement independent). Without --write it is a pure check (the build lint): violations exit non-zero and hoistable inline call sites are reported as notes. With --write, verified inline call sites are rewritten in place; files with violations are never rewritten. Idempotent: re-running on transformed output changes nothing. With --aot <artifact> (issue #208), the pass additionally compiles every verified prepare body at BUILD time into a static prepared-plan artifact (a generated TypeScript module): with --write it writes the artifact and rewrites each call site to load its static plan (`loadPreparedPlan(document, id, body)` \u2014 the body stays in source as the plan\'s compile source and fallback); without --write it is the DRIFT CHECK \u2014 it recompiles every plan and exits non-zero when the artifact is missing or differs (CI gate: model declarations changed without regenerating the artifact).",\n "usage": [\n "graphddb transform prepared --src src/",\n "graphddb transform prepared --src src/ --write",\n "graphddb transform prepared --src src/app/handlers.ts --write",\n "graphddb transform prepared --src src/ --aot src/graphddb.prepared.ts --write",\n "graphddb transform prepared --src src/ --aot src/graphddb.prepared.ts"\n ],\n "effects": {\n "risk_level": "medium",\n "reads": [\n "ts-app-sources"\n ],\n "writes": [\n "ts-app-sources"\n ]\n },\n "x-agent": {\n "recommended_before_use": [\n "Commit or stash pending changes first when using --write (it rewrites sources in place)."\n ]\n },\n "options": [\n {\n "name": "src",\n "aliases": [\n "s"\n ],\n "required": true,\n "description": "A TypeScript source file, or a directory scanned recursively for .ts/.tsx/.mts/.cts files (node_modules, dist, hidden directories, and .d.ts files are skipped).",\n "value_name": "path",\n "schema": {\n "type": "string"\n },\n "file": {\n "mode": "read",\n "exists": true\n }\n },\n {\n "name": "write",\n "aliases": [\n "w"\n ],\n "description": "Rewrite verified inline call sites in place (hoist normalization). Without it the command only checks and reports.",\n "schema": {\n "type": "boolean"\n }\n },\n {\n "name": "aot",\n "aliases": [\n "a"\n ],\n "description": "Static prepared-plan artifact module path (issue #208). Enables build-time (AOT) compilation of every verified prepare body: with --write the artifact module is (re)generated and call sites are rewritten to load their static plan; without --write the pass recompiles and compares (drift check \u2014 a missing or differing artifact exits 1).",\n "value_name": "artifact",\n "schema": {\n "type": "string"\n }\n }\n ],\n "exits": {\n "0": {\n "description": "Check passed / transform applied. No no-runtime-capture violations were found.",\n "stdout": {\n "format": "json",\n "schema": {\n "$ref": "#/components/schemas/TransformPreparedResult"\n }\n }\n },\n "1": {\n "description": "No-runtime-capture violations found, or --aot drift detected (reported in the result on stdout), or an unexpected error (reported on stderr).",\n "stdout": {\n "format": "json",\n "schema": {\n "$ref": "#/components/schemas/TransformPreparedResult"\n }\n }\n },\n "2": {\n "description": "Invalid arguments (missing/unreadable input).",\n "stderr": {\n "format": "json",\n "schema": {\n "$ref": "#/components/schemas/Error"\n }\n }\n }\n }\n }\n }\n }\n },\n "components": {\n "schemas": {\n "GenerateResult": {\n "type": "object",\n "required": [\n "status",\n "outDir",\n "files"\n ],\n "properties": {\n "status": {\n "type": "string",\n "enum": [\n "ok"\n ]\n },\n "outDir": {\n "type": "string",\n "description": "Output directory the files were written to."\n },\n "files": {\n "type": "array",\n "description": "Paths of the generated files (relative to outDir).",\n "items": {\n "type": "string"\n }\n }\n }\n },\n "Error": {\n "type": "object",\n "required": [\n "code",\n "message"\n ],\n "properties": {\n "code": {\n "type": "string"\n },\n "message": {\n "type": "string"\n }\n }\n },\n "TransformPreparedResult": {\n "type": "object",\n "required": [\n "status",\n "files",\n "hoisted",\n "moduleScope",\n "alreadyHoisted",\n "errors",\n "diagnostics"\n ],\n "properties": {\n "status": {\n "type": "string",\n "enum": [\n "ok",\n "violations",\n "drift"\n ]\n },\n "files": {\n "type": "array",\n "description": "Source files scanned.",\n "items": {\n "type": "string"\n }\n },\n "changedFiles": {\n "type": "array",\n "description": "Files rewritten in place (--write only).",\n "items": {\n "type": "string"\n }\n },\n "hoisted": {\n "type": "integer",\n "description": "Inline call sites normalized (or normalizable in check mode)."\n },\n "moduleScope": {\n "type": "integer",\n "description": "Call sites already evaluated once per module load (left as-is)."\n },\n "alreadyHoisted": {\n "type": "integer",\n "description": "Call sites already normalized by a previous run."\n },\n "errors": {\n "type": "integer",\n "description": "No-runtime-capture violations found."\n },\n "artifact": {\n "type": "string",\n "description": "The static prepared-plan artifact path (--aot only)."\n },\n "plans": {\n "type": "integer",\n "description": "Prepared plans compiled into the artifact (--aot only)."\n },\n "drift": {\n "type": "object",\n "description": "Artifact drift detail (--aot check mode only; present when status is drift).",\n "properties": {\n "missing": {\n "type": "boolean",\n "description": "The artifact module does not exist."\n },\n "added": {\n "type": "array",\n "items": {\n "type": "string"\n }\n },\n "removed": {\n "type": "array",\n "items": {\n "type": "string"\n }\n },\n "changed": {\n "type": "array",\n "items": {\n "type": "string"\n }\n }\n }\n },\n "diagnostics": {\n "type": "array",\n "description": "Per-position lint diagnostics (errors and notes).",\n "items": {\n "type": "object",\n "required": [\n "code",\n "category",\n "message",\n "file",\n "line",\n "column"\n ],\n "properties": {\n "code": {\n "type": "string"\n },\n "category": {\n "type": "string",\n "enum": [\n "error",\n "note"\n ]\n },\n "message": {\n "type": "string"\n },\n "file": {\n "type": "string"\n },\n "line": {\n "type": "integer"\n },\n "column": {\n "type": "integer"\n }\n }\n }\n }\n }\n }\n }\n }\n}';
856
944
 
857
945
  // src/generated/program.ts
858
946
  function createProgram(handlers2, version) {
@@ -896,6 +984,15 @@ function createProgram(handlers2, version) {
896
984
  }
897
985
  await handlers2.generateGo(opts, globalOpts);
898
986
  });
987
+ __cmd_generate.command("behaviors").description("Generate a native behavior module (the codegen-static endpoint) via the upstream behavior-contracts common Generator.").option("-l, --lang <lang>", "Target language of the generated behavior module. `ts` emits a typed TypeScript module, `python` a dict-literal module, `go` a JNode composite-literal package, `rust` a json!-constructor module (requires Rust >= 1.80 \u2014 std::sync::LazyLock), `php` a require-scoped module value.").option("-e, --entry <file>", "Entry module that registers the entity models (side-effecting import). May also export contracts / contexts / transactions.").option("-t, --transactions <file>", "Module exporting `transactions` (a defineTransactions map). Defaults to the entry module when omitted. Optional.").option("--contracts <file>", "Module exporting `contracts` (the CQRS Contract layer). Defaults to the entry module when omitted. Optional.").option("--contexts <file>", "Module exporting `contexts` (context-ownership). Defaults to the contracts module (or the entry module) when omitted. Optional.").option("--runtime-import <specifier>", "Module specifier the generated module imports the behavior-contracts runtime core from. Defaults to the emitter's published package name per language \u2014 except `php`, which defaults to graphddb's vendored namespace (GraphDDB\\Runtime\\BehaviorContracts) so the generated module resolves against the PHP runtime this package ships.").option("-o, --out <dir>", "Output directory for the generated behavior module.").action(async (opts, cmd) => {
988
+ const globalOpts = cmd.optsWithGlobals();
989
+ if (globalOpts.introspect) {
990
+ const policy = deriveCommandPolicy("generate.behaviors", opts);
991
+ console.log(JSON.stringify(policy, null, 2));
992
+ return;
993
+ }
994
+ await handlers2.generateBehaviors(opts, globalOpts);
995
+ });
899
996
  __cmd_generate.command("cloudformation").description("Generate an AWS CloudFormation template (DynamoDB table + GSIs) from TypeScript GraphDDB definitions.").option("-e, --entry <file>", "Entry module that registers the entity models (side-effecting import).").option("-o, --out <file>", "Output file for the generated CloudFormation template. Written to stdout when omitted.").option("-f, --format <format>", "Output serialization format (yaml or json).", "yaml").option("--gsi-projection <projection>", "GSI ProjectionType. ALL (default) projects every attribute; KEYS_ONLY projects only the key attributes.", "ALL").option("--stream <mode>", "DynamoDB Streams (StreamSpecification NEW_AND_OLD_IMAGES) emission. auto (default) emits a stream only when the model set uses stream-based maintenance (updateMode:'stream'); on always emits; off never emits. When enabled, a StreamArn Output is added too.", "auto").option("--billing-mode <mode>", "DynamoDB billing mode. PAY_PER_REQUEST (default) is on-demand (no provisioned throughput). PROVISIONED emits BillingMode: PROVISIONED with ProvisionedThroughput (see --rcu / --wcu) on the table and every GSI, and unlocks Application Auto Scaling (--autoscale).", "PAY_PER_REQUEST").option("--rcu <units>", "Provisioned ReadCapacityUnits (a positive integer) applied to the table and every GSI. Only valid with --billing-mode PROVISIONED (rejected with PAY_PER_REQUEST). Defaults to 5 when omitted.").option("--wcu <units>", "Provisioned WriteCapacityUnits (a positive integer) applied to the table and every GSI. Only valid with --billing-mode PROVISIONED (rejected with PAY_PER_REQUEST). Defaults to 5 when omitted.").option("--autoscale", "Enable Application Auto Scaling. Emits an AWS::ApplicationAutoScaling::ScalableTarget + AWS::ApplicationAutoScaling::ScalingPolicy pair for the table read and write capacity AND for each GSI read and write capacity. Only valid with --billing-mode PROVISIONED (autoscaling is invalid on on-demand and is rejected). Off by default \u2014 no autoscaling resources are emitted unless this flag is passed.").option("--autoscale-min <units>", "Auto Scaling minimum capacity (MinCapacity) for every scalable target. Must be <= --autoscale-max. Only meaningful with --autoscale. Defaults to 5 when omitted.").option("--autoscale-max <units>", "Auto Scaling maximum capacity (MaxCapacity) for every scalable target. Must be >= --autoscale-min. Only meaningful with --autoscale. Defaults to 100 when omitted.").option("--autoscale-target <percent>", "Auto Scaling target utilization percentage (TargetValue of the TargetTrackingScaling policy). Only meaningful with --autoscale. Defaults to 70 when omitted.").option("--pitr", "Enable point-in-time recovery (PointInTimeRecoverySpecification PointInTimeRecoveryEnabled:true). Off by default \u2014 the property is omitted entirely unless this flag is passed.").option("--table-class <class>", "DynamoDB table class. Omitted by default (AWS defaults to STANDARD); pass STANDARD or STANDARD_INFREQUENT_ACCESS to emit TableClass.").option("--sse", "Enable server-side encryption with the AWS-owned/managed key (SSESpecification SSEEnabled:true). Off by default \u2014 the property is omitted entirely unless this flag is passed.").action(async (opts, cmd) => {
900
997
  const globalOpts = cmd.optsWithGlobals();
901
998
  if (globalOpts.introspect) {
@@ -941,7 +1038,7 @@ function createProgram(handlers2, version) {
941
1038
  type: "cli-contracts/extract",
942
1039
  extractedAt: (/* @__PURE__ */ new Date()).toISOString(),
943
1040
  specVersion: doc.cli_contracts ?? "0.1.0",
944
- commands: ["graphddb.generate.python", "graphddb.generate.php", "graphddb.generate.rust", "graphddb.generate.go", "graphddb.generate.cloudformation", "graphddb.generate.docs", "graphddb.transform.prepared"]
1041
+ commands: ["graphddb.generate.python", "graphddb.generate.php", "graphddb.generate.rust", "graphddb.generate.go", "graphddb.generate.behaviors", "graphddb.generate.cloudformation", "graphddb.generate.docs", "graphddb.transform.prepared"]
945
1042
  };
946
1043
  }
947
1044
  Object.assign(out, doc);
@@ -958,7 +1055,7 @@ function createProgram(handlers2, version) {
958
1055
  yamlLines.push("extractedAt: " + (/* @__PURE__ */ new Date()).toISOString());
959
1056
  yamlLines.push("spec_version: " + (doc.cli_contracts ?? "0.1.0"));
960
1057
  yamlLines.push("commands:");
961
- for (const id of ["graphddb.generate.python", "graphddb.generate.php", "graphddb.generate.rust", "graphddb.generate.go", "graphddb.generate.cloudformation", "graphddb.generate.docs", "graphddb.transform.prepared"]) {
1058
+ for (const id of ["graphddb.generate.python", "graphddb.generate.php", "graphddb.generate.rust", "graphddb.generate.go", "graphddb.generate.behaviors", "graphddb.generate.cloudformation", "graphddb.generate.docs", "graphddb.transform.prepared"]) {
962
1059
  yamlLines.push(" - " + id);
963
1060
  }
964
1061
  }
@@ -1014,27 +1111,37 @@ function entityBaseName(entity) {
1014
1111
  function queryResultTypeName(queryName) {
1015
1112
  return `${toPascalCase(queryName)}Result`;
1016
1113
  }
1017
- function txElementTypeName(txName, paramName) {
1114
+ function txElementTypeName(txName, paramName, batchWrite = false) {
1115
+ if (batchWrite && paramName === "items") return `${toPascalCase(txName)}Item`;
1018
1116
  return `${toPascalCase(txName)}${toPascalCase(paramName)}Item`;
1019
1117
  }
1020
1118
  function contractOperationId(contract, method) {
1021
1119
  return `${contract}__${method}`;
1022
1120
  }
1023
- function relationSegments(resultPath) {
1024
- if (resultPath === "$") return [];
1025
- const parts = resultPath.replace(/^\$\.?/, "").split(".");
1026
- return parts.filter((p) => p !== "items");
1121
+ function relationSegments(nodeId) {
1122
+ return nodeId.split(".").filter((p) => p !== "items");
1027
1123
  }
1028
- function insertOperation(root, op, manifest) {
1029
- const segments = relationSegments(op.resultPath);
1030
- let node = root;
1124
+ function nodePorts(node) {
1125
+ if ("map" in node) return node.map.ports;
1126
+ if ("cond" in node) return void 0;
1127
+ return node.ports;
1128
+ }
1129
+ function nodeProjection(ports) {
1130
+ const port = ports.projection;
1131
+ return (port?.arr ?? []).filter((f) => typeof f === "string");
1132
+ }
1133
+ function insertComponentNode(root, node, manifest) {
1134
+ const ports = nodePorts(node);
1135
+ if (ports === void 0) return;
1136
+ const segments = relationSegments(node.id);
1137
+ let tree = root;
1031
1138
  let parent = root;
1032
1139
  let entity = root.entity;
1033
1140
  for (const prop of segments) {
1034
- parent = node;
1141
+ parent = tree;
1035
1142
  const relation = manifest.entities[entity]?.relations[prop];
1036
1143
  const target = relation?.target ?? entity;
1037
- let child = node.children.get(prop);
1144
+ let child = tree.children.get(prop);
1038
1145
  if (!child) {
1039
1146
  child = {
1040
1147
  entity: target,
@@ -1042,14 +1149,21 @@ function insertOperation(root, op, manifest) {
1042
1149
  children: /* @__PURE__ */ new Map(),
1043
1150
  implicitFields: /* @__PURE__ */ new Set()
1044
1151
  };
1045
- node.children.set(prop, child);
1152
+ tree.children.set(prop, child);
1046
1153
  }
1047
- node = child;
1154
+ tree = child;
1048
1155
  entity = target;
1049
1156
  }
1050
- node.projection = op.projection;
1051
- if (op.sourceList?.implicit) {
1052
- parent.implicitFields.add(op.sourceList.from);
1157
+ tree.projection = nodeProjection(ports);
1158
+ const implicit = ports.implicitSourceField;
1159
+ if (typeof implicit === "string") parent.implicitFields.add(implicit);
1160
+ }
1161
+ function populateResultTree(root, spec, component, manifest) {
1162
+ root.projection = spec.operations[0]?.projection ?? [];
1163
+ if (component === void 0) return;
1164
+ for (const node of component.body) {
1165
+ if (node.id === "root") continue;
1166
+ insertComponentNode(root, node, manifest);
1053
1167
  }
1054
1168
  }
1055
1169
  function emitResultClasses(node, typeName, manifest, out, seen) {
@@ -1139,7 +1253,7 @@ function emitTransactionElementTypes(transactions, out, seen) {
1139
1253
  for (const paramName of Object.keys(spec.params).sort()) {
1140
1254
  const p = spec.params[paramName];
1141
1255
  if (p.type !== "array" || !p.element) continue;
1142
- const name = txElementTypeName(txName, paramName);
1256
+ const name = txElementTypeName(txName, paramName, spec.batchWrite === true);
1143
1257
  if (seen.has(name)) continue;
1144
1258
  seen.add(name);
1145
1259
  const element = p.element;
@@ -1152,7 +1266,7 @@ function emitTransactionElementTypes(transactions, out, seen) {
1152
1266
  }
1153
1267
  }
1154
1268
  function elementParamField(name, p) {
1155
- const scalarType = p.type === "number" ? "number" : "string";
1269
+ const scalarType = p.type === "number" ? "number" : p.type === "map" ? "map" : "string";
1156
1270
  return {
1157
1271
  name,
1158
1272
  shape: "scalar",
@@ -1211,9 +1325,9 @@ function contractCommandMethodSpec(operations, binding) {
1211
1325
  }
1212
1326
  function contractCommandParams(operations, binding, spec) {
1213
1327
  const single = spec.single;
1214
- const params = single.mode === "transaction" ? operations.transactions?.[single.transaction]?.params : operations.commands[single.operation]?.params;
1328
+ const params = single.mode === "transaction" || single.mode === "batchWrite" ? operations.transactions?.[single.transaction]?.params : operations.commands[single.operation]?.params;
1215
1329
  if (!params) {
1216
- const ref = single.mode === "transaction" ? `transaction '${single.transaction}'` : `command '${single.operation}'`;
1330
+ const ref = single.mode === "transaction" || single.mode === "batchWrite" ? `transaction '${single.transaction}'` : `command '${single.operation}'`;
1217
1331
  throw new Error(
1218
1332
  `Contract '${binding.contract}.${binding.method}': its single resolution target (${ref}) is not present in the operations document.`
1219
1333
  );
@@ -1237,6 +1351,9 @@ function buildBindingModel(manifest, operations, options) {
1237
1351
  ...meta.description !== void 0 ? { description: meta.description } : {}
1238
1352
  };
1239
1353
  });
1354
+ const componentByName = new Map(
1355
+ (operations.components ?? []).map((c) => [c.name, c])
1356
+ );
1240
1357
  const resultClasses = [];
1241
1358
  const seen = /* @__PURE__ */ new Set();
1242
1359
  for (const queryName of queryNames) {
@@ -1249,7 +1366,7 @@ function buildBindingModel(manifest, operations, options) {
1249
1366
  children: /* @__PURE__ */ new Map(),
1250
1367
  implicitFields: /* @__PURE__ */ new Set()
1251
1368
  };
1252
- for (const op of spec.operations) insertOperation(root, op, manifest);
1369
+ populateResultTree(root, spec, componentByName.get(queryName), manifest);
1253
1370
  emitResultClasses(root, queryResultTypeName(queryName), manifest, resultClasses, seen);
1254
1371
  }
1255
1372
  for (const q of contractQueries) {
@@ -1272,7 +1389,7 @@ function buildBindingModel(manifest, operations, options) {
1272
1389
  children: /* @__PURE__ */ new Map(),
1273
1390
  implicitFields: /* @__PURE__ */ new Set()
1274
1391
  };
1275
- for (const op of spec.operations) insertOperation(root, op, manifest);
1392
+ populateResultTree(root, spec, componentByName.get(q.operation), manifest);
1276
1393
  emitResultClasses(root, recordName, manifest, resultClasses, seen);
1277
1394
  appendFieldsToClass(resultClasses, recordName, composeFields(methodSpec.compose ?? []));
1278
1395
  if (cardinality === "many") {
@@ -1364,8 +1481,10 @@ function buildBindingModel(manifest, operations, options) {
1364
1481
  transactionId: txName,
1365
1482
  params: buildParams(
1366
1483
  transactions[txName].params,
1367
- (p) => txElementTypeName(txName, p)
1368
- )
1484
+ (p) => txElementTypeName(txName, p, transactions[txName].batchWrite === true)
1485
+ ),
1486
+ // #298: a `batchWrite` bulk form dispatches to `executeBatchWrite`.
1487
+ ...transactions[txName].batchWrite === true ? { batchWrite: true } : {}
1369
1488
  }));
1370
1489
  return {
1371
1490
  entities,
@@ -1466,7 +1585,7 @@ function resolveField(field, mapper) {
1466
1585
  case "scalar":
1467
1586
  default:
1468
1587
  type = field.isParamScalar ? mapper.paramScalar(
1469
- field.scalarType === "number" ? "number" : field.literals ? "literal" : "string",
1588
+ field.scalarType === "number" ? "number" : field.scalarType === "map" ? "map" : field.literals ? "literal" : "string",
1470
1589
  field.literals
1471
1590
  ) : mapper.scalar(field.scalarType ?? "string", field.scalarFormat);
1472
1591
  break;
@@ -1565,7 +1684,8 @@ function resolveBindingView(model, mapper, options = {}) {
1565
1684
  })),
1566
1685
  transactions: model.transactions.map((tx) => ({
1567
1686
  transactionId: tx.transactionId,
1568
- params: tx.params.map((p) => resolveParam(p, mapper))
1687
+ params: tx.params.map((p) => resolveParam(p, mapper)),
1688
+ ...tx.batchWrite === true ? { batchWrite: true } : {}
1569
1689
  }))
1570
1690
  };
1571
1691
  }
@@ -1573,7 +1693,8 @@ function resolveBindingView(model, mapper, options = {}) {
1573
1693
  // src/codegen/python-mapper.ts
1574
1694
  var PythonTypeMapper = {
1575
1695
  language: "python",
1576
- scalar(type) {
1696
+ scalar(type, format) {
1697
+ if (format === "datetime" || format === "date") return "datetime";
1577
1698
  switch (type) {
1578
1699
  case "number":
1579
1700
  case "numberSet":
@@ -1597,6 +1718,7 @@ var PythonTypeMapper = {
1597
1718
  const lits = literals.map((l) => typeof l === "string" ? JSON.stringify(l) : String(l)).join(", ");
1598
1719
  return `Literal[${lits}]`;
1599
1720
  }
1721
+ if (kind === "map") return "dict";
1600
1722
  return kind === "number" ? "float" : "str";
1601
1723
  },
1602
1724
  connection(itemType) {
@@ -1621,8 +1743,10 @@ var TYPES = `{{header}}
1621
1743
  from __future__ import annotations
1622
1744
 
1623
1745
  {{#if isDataclass}}from dataclasses import dataclass
1624
- {{#if usesLiteral}}from typing import Literal
1625
- {{/if}}{{else}}{{#if usesLiteral}}from typing import Literal, TypedDict
1746
+ {{#if datetimeImport}}{{datetimeImport}}
1747
+ {{/if}}{{#if usesLiteral}}from typing import Literal
1748
+ {{/if}}{{else}}{{#if datetimeImport}}{{datetimeImport}}
1749
+ {{/if}}{{#if usesLiteral}}from typing import Literal, TypedDict
1626
1750
  {{else}}from typing import TypedDict
1627
1751
  {{/if}}{{/if}}
1628
1752
 
@@ -1650,7 +1774,7 @@ var REPO_CLASS = `class {{name}}:
1650
1774
 
1651
1775
  {{/unless}}{{/each}}{{else}} pass{{/if}}`;
1652
1776
  var TX_METHOD = ` def {{methodName}}(self{{#if signature}}, {{signature}}{{/if}}) -> None:
1653
- self._runtime.execute_transaction(
1777
+ self._runtime.{{runtimeCall}}(
1654
1778
  transaction_id="{{transactionId}}",
1655
1779
  params={{paramsDict}},
1656
1780
  )`;
@@ -1755,12 +1879,17 @@ function txMethodContext(m) {
1755
1879
  methodName: toSnakeCase(m.transactionId),
1756
1880
  signature: signatureOf(m.params),
1757
1881
  transactionId: m.transactionId,
1758
- paramsDict: paramsDictOf(m.params)
1882
+ paramsDict: paramsDictOf(m.params),
1883
+ runtimeCall: m.batchWrite === true ? "execute_batch_write" : "execute_transaction"
1759
1884
  };
1760
1885
  }
1761
1886
  function classesUseLiteral(classes) {
1762
1887
  return classes.some((c) => c.fields.some((f) => f.type.includes("Literal[")));
1763
1888
  }
1889
+ function datetimeImportOf(classes) {
1890
+ const usesDatetime = classes.some((c) => c.fields.some((f) => /\bdatetime\b/.test(f.type)));
1891
+ return usesDatetime ? "from datetime import datetime" : void 0;
1892
+ }
1764
1893
  function methodsUseLiteral(view) {
1765
1894
  const paramLiteral = (p) => p.type.startsWith("Literal[");
1766
1895
  return view.repositories.some((r) => r.methods.some((m) => m.params.some(paramLiteral))) || view.transactions.some((t) => t.params.some(paramLiteral));
@@ -1798,10 +1927,12 @@ function renderTypesFile(view, options) {
1798
1927
  (c) => render("type-class", classContext(c, isDataclass), engine)
1799
1928
  );
1800
1929
  const body = blocks.length === 0 ? "# (no query result types)" : blocks.join("\n\n\n");
1930
+ const datetimeImport = datetimeImportOf(view.resultClasses);
1801
1931
  const context = {
1802
1932
  header: PY_HEADER,
1803
1933
  isDataclass,
1804
1934
  usesLiteral: classesUseLiteral(view.resultClasses),
1935
+ ...datetimeImport !== void 0 ? { datetimeImport } : {},
1805
1936
  body
1806
1937
  };
1807
1938
  return render("types", context, engine);
@@ -1950,6 +2081,7 @@ var PhpTypeMapper = {
1950
2081
  }
1951
2082
  },
1952
2083
  paramScalar(kind) {
2084
+ if (kind === "map") return "array|\\stdClass";
1953
2085
  return kind === "number" ? PHP_NUMBER : "string";
1954
2086
  },
1955
2087
  connection(itemType) {
@@ -2052,7 +2184,7 @@ final class {{name}}
2052
2184
  }`;
2053
2185
  var TX_METHOD2 = `{{docblock}} public function {{methodName}}({{signature}}): void
2054
2186
  {
2055
- $this->runtime->executeTransaction('{{transactionId}}', {{paramsArray}});
2187
+ $this->runtime->{{runtimeCall}}('{{transactionId}}', {{paramsArray}});
2056
2188
  }`;
2057
2189
  var TX_CLASS2 = `/**
2058
2190
  * Typed repository for declarative transactions, wrapping a {@see GraphDDBRuntime}.
@@ -2220,7 +2352,8 @@ function txMethodContext2(method, metas) {
2220
2352
  signature: signatureOf2(method.params),
2221
2353
  transactionId: method.transactionId,
2222
2354
  paramsArray: paramsArrayOf(method.params),
2223
- docblock: txDocblockOf(method, metas)
2355
+ docblock: txDocblockOf(method, metas),
2356
+ runtimeCall: method.batchWrite === true ? "executeBatchWrite" : "executeTransaction"
2224
2357
  };
2225
2358
  }
2226
2359
  function engineOptions2(options) {
@@ -2246,12 +2379,16 @@ function renderFile(body, uses, options) {
2246
2379
  }
2247
2380
  function buildParamMetaIndex(operations, surface) {
2248
2381
  const index = /* @__PURE__ */ new Map();
2249
- const record = (opId, params) => {
2382
+ const record = (opId, params, batchWrite = false) => {
2250
2383
  const inner = /* @__PURE__ */ new Map();
2251
2384
  for (const [name, p] of Object.entries(params)) {
2252
2385
  inner.set(name, {
2253
2386
  ...p.literals !== void 0 ? { literals: p.literals } : {},
2254
- ...p.type === "array" ? { elementType: `${pascal(opId)}${pascal(name)}Item` } : {}
2387
+ // #298: a batchWrite form's `items` element is `<TxName>Item` (matching
2388
+ // `txElementTypeName` — the generic rule would double the word).
2389
+ ...p.type === "array" ? {
2390
+ elementType: batchWrite && name === "items" ? `${pascal(opId)}Item` : `${pascal(opId)}${pascal(name)}Item`
2391
+ } : {}
2255
2392
  });
2256
2393
  }
2257
2394
  index.set(opId, inner);
@@ -2265,7 +2402,7 @@ function buildParamMetaIndex(operations, surface) {
2265
2402
  if (commandSet.has(name)) record(name, spec.params ?? {});
2266
2403
  }
2267
2404
  for (const [name, spec] of Object.entries(operations.transactions ?? {})) {
2268
- record(name, spec.params ?? {});
2405
+ record(name, spec.params ?? {}, spec.batchWrite === true);
2269
2406
  }
2270
2407
  recordContractMetas(index, operations, surface, record);
2271
2408
  return index;
@@ -2278,7 +2415,7 @@ function recordContractMetas(index, operations, surface, record) {
2278
2415
  for (const c of surface.contractCommands ?? []) {
2279
2416
  const methodSpec = operations.contracts?.[c.contract]?.methods?.[c.method];
2280
2417
  const single = methodSpec && "single" in methodSpec ? methodSpec.single : void 0;
2281
- const params = single === void 0 ? void 0 : single.mode === "transaction" ? operations.transactions?.[single.transaction]?.params : operations.commands[single.operation]?.params;
2418
+ const params = single === void 0 ? void 0 : single.mode === "transaction" || single.mode === "batchWrite" ? operations.transactions?.[single.transaction]?.params : operations.commands[single.operation]?.params;
2282
2419
  if (params) record(contractOperationId(c.contract, c.method), params);
2283
2420
  }
2284
2421
  }
@@ -2397,6 +2534,7 @@ var RustTypeMapper = {
2397
2534
  }
2398
2535
  },
2399
2536
  paramScalar(kind) {
2537
+ if (kind === "map") return "serde_json::Value";
2400
2538
  return kind === "number" ? RUST_NUMBER : "String";
2401
2539
  },
2402
2540
  connection(itemType) {
@@ -2461,6 +2599,9 @@ pub struct {{name}} {
2461
2599
  runtime: Arc<GraphDDBRuntime>,
2462
2600
  }
2463
2601
 
2602
+ // Generated methods use cross-language-stable \`contract__method\` names and
2603
+ // take one typed argument per contract key/shared field.
2604
+ #[allow(non_snake_case, clippy::too_many_arguments)]
2464
2605
  impl {{name}} {
2465
2606
  /// Construct the repository over a shared runtime.
2466
2607
  pub fn new(runtime: Arc<GraphDDBRuntime>) -> Self {
@@ -2472,7 +2613,7 @@ impl {{name}} {
2472
2613
  {{/if~}}
2473
2614
  }`;
2474
2615
  var TX_METHOD3 = `{{docComment}} pub async fn {{methodName}}(&self{{#if signature}}, {{signature}}{{/if}}) -> Result<(), GraphDDBError> {
2475
- {{paramsStmts}} self.runtime.execute_transaction("{{transactionId}}", &params).await?;
2616
+ {{paramsStmts}} self.runtime.{{runtimeCall}}("{{transactionId}}", &params).await?;
2476
2617
  Ok(())
2477
2618
  }`;
2478
2619
  var TX_STRUCT = `/// Typed repository for declarative transactions, wrapping a \`GraphDDBRuntime\`.
@@ -2481,6 +2622,9 @@ pub struct {{name}} {
2481
2622
  runtime: Arc<GraphDDBRuntime>,
2482
2623
  }
2483
2624
 
2625
+ // Generated methods use cross-language-stable \`contract__method\` names and
2626
+ // take one typed argument per contract key/shared field.
2627
+ #[allow(non_snake_case, clippy::too_many_arguments)]
2484
2628
  impl {{name}} {
2485
2629
  /// Construct the repository over a shared runtime.
2486
2630
  pub fn new(runtime: Arc<GraphDDBRuntime>) -> Self {
@@ -2534,12 +2678,16 @@ function pascal2(name) {
2534
2678
  }
2535
2679
  function buildParamMetaIndex2(operations, surface) {
2536
2680
  const index = /* @__PURE__ */ new Map();
2537
- const record = (opId, params) => {
2681
+ const record = (opId, params, batchWrite = false) => {
2538
2682
  const inner = /* @__PURE__ */ new Map();
2539
2683
  for (const [name, p] of Object.entries(params)) {
2540
2684
  inner.set(name, {
2541
2685
  ...p.literals !== void 0 ? { literals: p.literals } : {},
2542
- ...p.type === "array" ? { elementType: `${pascal2(opId)}${pascal2(name)}Item` } : {}
2686
+ // #298: a batchWrite form's `items` element is `<TxName>Item` (matching
2687
+ // `txElementTypeName` — the generic rule would double the word).
2688
+ ...p.type === "array" ? {
2689
+ elementType: batchWrite && name === "items" ? `${pascal2(opId)}Item` : `${pascal2(opId)}${pascal2(name)}Item`
2690
+ } : {}
2543
2691
  });
2544
2692
  }
2545
2693
  index.set(opId, inner);
@@ -2553,7 +2701,7 @@ function buildParamMetaIndex2(operations, surface) {
2553
2701
  if (commandSet.has(name)) record(name, spec.params ?? {});
2554
2702
  }
2555
2703
  for (const [name, spec] of Object.entries(operations.transactions ?? {})) {
2556
- record(name, spec.params ?? {});
2704
+ record(name, spec.params ?? {}, spec.batchWrite === true);
2557
2705
  }
2558
2706
  for (const q of surface.contractQueries ?? []) {
2559
2707
  const spec = operations.queries[q.operation];
@@ -2562,7 +2710,7 @@ function buildParamMetaIndex2(operations, surface) {
2562
2710
  for (const c of surface.contractCommands ?? []) {
2563
2711
  const methodSpec = operations.contracts?.[c.contract]?.methods?.[c.method];
2564
2712
  const single = methodSpec && "single" in methodSpec ? methodSpec.single : void 0;
2565
- const params = single === void 0 ? void 0 : single.mode === "transaction" ? operations.transactions?.[single.transaction]?.params : operations.commands[single.operation]?.params;
2713
+ const params = single === void 0 ? void 0 : single.mode === "transaction" || single.mode === "batchWrite" ? operations.transactions?.[single.transaction]?.params : operations.commands[single.operation]?.params;
2566
2714
  if (params) record(contractOperationId(c.contract, c.method), params);
2567
2715
  }
2568
2716
  return index;
@@ -2676,7 +2824,8 @@ function txMethodContext3(method, metas) {
2676
2824
  signature: signatureOf3(method.params),
2677
2825
  transactionId: method.transactionId,
2678
2826
  paramsStmts: paramsStmtsOf(method.params),
2679
- docComment: txMethodDocComment(method, metas)
2827
+ docComment: txMethodDocComment(method, metas),
2828
+ runtimeCall: method.batchWrite === true ? "execute_batch_write" : "execute_transaction"
2680
2829
  };
2681
2830
  }
2682
2831
  function engineOptions3(options) {
@@ -2782,6 +2931,7 @@ var GoTypeMapper = {
2782
2931
  }
2783
2932
  },
2784
2933
  paramScalar(kind) {
2934
+ if (kind === "map") return "map[string]any";
2785
2935
  return kind === "number" ? GO_NUMBER : "string";
2786
2936
  },
2787
2937
  connection(itemType) {
@@ -2868,7 +3018,7 @@ func New{{name}}(runtime *graphddb_runtime.GraphDDBRuntime) *{{name}} {
2868
3018
 
2869
3019
  {{body}}{{/if}}`;
2870
3020
  var TX_METHOD4 = `{{docComment}}func (r *{{repoName}}) {{methodName}}(ctx context.Context{{#if signature}}, {{signature}}{{/if}}) error {
2871
- {{paramsStmts}} return r.runtime.ExecuteTransaction(ctx, "{{transactionId}}", params, nil)
3021
+ {{paramsStmts}} return r.runtime.{{runtimeCall}}(ctx, "{{transactionId}}", params, nil)
2872
3022
  }`;
2873
3023
  var TX_STRUCT2 = `// {{name}} is a typed repository for declarative transactions, wrapping a *graphddb_runtime.GraphDDBRuntime.
2874
3024
  type {{name}} struct {
@@ -2969,12 +3119,16 @@ function pascal3(name) {
2969
3119
  }
2970
3120
  function buildParamMetaIndex3(operations, surface) {
2971
3121
  const index = /* @__PURE__ */ new Map();
2972
- const record = (opId, params) => {
3122
+ const record = (opId, params, batchWrite = false) => {
2973
3123
  const inner = /* @__PURE__ */ new Map();
2974
3124
  for (const [name, p] of Object.entries(params)) {
2975
3125
  inner.set(name, {
2976
3126
  ...p.literals !== void 0 ? { literals: p.literals } : {},
2977
- ...p.type === "array" ? { elementType: `${pascal3(opId)}${pascal3(name)}Item` } : {}
3127
+ // #298: a batchWrite form's `items` element is `<TxName>Item` (matching
3128
+ // `txElementTypeName` — the generic rule would double the word).
3129
+ ...p.type === "array" ? {
3130
+ elementType: batchWrite && name === "items" ? `${pascal3(opId)}Item` : `${pascal3(opId)}${pascal3(name)}Item`
3131
+ } : {}
2978
3132
  });
2979
3133
  }
2980
3134
  index.set(opId, inner);
@@ -2988,7 +3142,7 @@ function buildParamMetaIndex3(operations, surface) {
2988
3142
  if (commandSet.has(name)) record(name, spec.params ?? {});
2989
3143
  }
2990
3144
  for (const [name, spec] of Object.entries(operations.transactions ?? {})) {
2991
- record(name, spec.params ?? {});
3145
+ record(name, spec.params ?? {}, spec.batchWrite === true);
2992
3146
  }
2993
3147
  for (const q of surface.contractQueries ?? []) {
2994
3148
  const spec = operations.queries[q.operation];
@@ -2997,7 +3151,7 @@ function buildParamMetaIndex3(operations, surface) {
2997
3151
  for (const c of surface.contractCommands ?? []) {
2998
3152
  const methodSpec = operations.contracts?.[c.contract]?.methods?.[c.method];
2999
3153
  const single = methodSpec && "single" in methodSpec ? methodSpec.single : void 0;
3000
- const params = single === void 0 ? void 0 : single.mode === "transaction" ? operations.transactions?.[single.transaction]?.params : operations.commands[single.operation]?.params;
3154
+ const params = single === void 0 ? void 0 : single.mode === "transaction" || single.mode === "batchWrite" ? operations.transactions?.[single.transaction]?.params : operations.commands[single.operation]?.params;
3001
3155
  if (params) record(contractOperationId(c.contract, c.method), params);
3002
3156
  }
3003
3157
  return index;
@@ -3099,7 +3253,8 @@ function txMethodContext4(repoName, method, metas) {
3099
3253
  signature: signatureOf4(method.params),
3100
3254
  transactionId: method.transactionId,
3101
3255
  paramsStmts: paramsStmtsOf2(method.params),
3102
- docComment: methodDocComment2(methodName, void 0, method.params, metas)
3256
+ docComment: methodDocComment2(methodName, void 0, method.params, metas),
3257
+ runtimeCall: method.batchWrite === true ? "ExecuteBatchWrite" : "ExecuteTransaction"
3103
3258
  };
3104
3259
  }
3105
3260
  function engineOptions4(options) {
@@ -3670,6 +3825,14 @@ function generateCdcRegistry(options = {}) {
3670
3825
  }
3671
3826
 
3672
3827
  // src/codegen/docs-model.ts
3828
+ function keyConditionTemplates(op) {
3829
+ if (op.keyCondition) return { ...op.keyCondition };
3830
+ const out = {};
3831
+ for (const [attr, node] of Object.entries(op.keyExpr ?? {})) {
3832
+ out[attr] = renderKeyExprToTemplate(node);
3833
+ }
3834
+ return out;
3835
+ }
3673
3836
  var AS_CONFIGURED = "as configured at deployment";
3674
3837
  function fieldTypeLabel(entity, field) {
3675
3838
  const f = entity.fields[field];
@@ -3709,17 +3872,37 @@ function referencesField(template, field) {
3709
3872
  function keyLabel(prefix, template) {
3710
3873
  return template ? `${prefix} = ${template}` : "";
3711
3874
  }
3875
+ function exprLiteralPrefix(node) {
3876
+ if (typeof node === "string") return node;
3877
+ if (node !== null && typeof node === "object" && "concat" in node) {
3878
+ const first = node.concat[0];
3879
+ if (typeof first === "string") return first;
3880
+ }
3881
+ return "";
3882
+ }
3883
+ function relationHops(component) {
3884
+ const hops = [];
3885
+ for (const node of component?.body ?? []) {
3886
+ if (node.id === "root" || "cond" in node) continue;
3887
+ const kind = "map" in node ? node.map.component : node.component;
3888
+ const ports = "map" in node ? node.map.ports : node.ports;
3889
+ const indexName = typeof ports.indexName === "string" ? ports.indexName : void 0;
3890
+ const table = typeof ports.table === "string" ? ports.table : "";
3891
+ const pkNode = (indexName ? ports[`${indexName}PK`] : void 0) ?? ports.PK ?? ports.pk;
3892
+ hops.push({
3893
+ type: kind,
3894
+ tableName: table,
3895
+ ...indexName !== void 0 ? { indexName } : {},
3896
+ pkTemplate: exprLiteralPrefix(pkNode)
3897
+ });
3898
+ }
3899
+ return hops;
3900
+ }
3712
3901
  function rootIndex(spec) {
3713
3902
  const root = spec.operations[0];
3714
3903
  if (!root) return "";
3715
3904
  return root.indexName ?? "PK";
3716
3905
  }
3717
- function isRelation(spec) {
3718
- return spec.operations.length > 1;
3719
- }
3720
- function usesBatchGet(spec) {
3721
- return spec.operations.some((op) => op.type === "BatchGetItem");
3722
- }
3723
3906
  function usesCursor(spec) {
3724
3907
  return (spec.cardinality ?? "many") === "many";
3725
3908
  }
@@ -3736,10 +3919,11 @@ function inputShape(spec) {
3736
3919
  return `{ ${parts.join(", ")} }`;
3737
3920
  }
3738
3921
  function opPkTemplate(op) {
3922
+ const kc = keyConditionTemplates(op);
3739
3923
  if (op.indexName) {
3740
- return op.keyCondition[`${op.indexName}PK`] ?? op.keyCondition["PK"] ?? op.keyCondition["pk"] ?? "";
3924
+ return kc[`${op.indexName}PK`] ?? kc["PK"] ?? kc["pk"] ?? "";
3741
3925
  }
3742
- return op.keyCondition["PK"] ?? op.keyCondition["pk"] ?? "";
3926
+ return kc["PK"] ?? kc["pk"] ?? "";
3743
3927
  }
3744
3928
  function rootEntityName(spec, manifest) {
3745
3929
  const root = spec.operations[0];
@@ -3756,10 +3940,10 @@ function outputShape(spec, entityName) {
3756
3940
  const base = entityName || "Result";
3757
3941
  return many ? `Page<${base}>` : base;
3758
3942
  }
3759
- function buildResolution(spec, manifest) {
3943
+ function buildResolution(spec, relHops, manifest) {
3760
3944
  const root = spec.operations[0];
3761
3945
  if (!root) return { resolve: "", diagram: [] };
3762
- if (spec.operations.length === 1) {
3946
+ if (relHops.length === 0) {
3763
3947
  const keyLabelStr = rootKeyLabel(root);
3764
3948
  const proj = root.projection.length > 0 ? `Projection(${root.projection.slice(0, 4).join(", ")})` : "Projection";
3765
3949
  const resolve4 = `${keyLabelStr} \u2192 ${root.type} \u2192 ${proj}`;
@@ -3773,13 +3957,22 @@ function buildResolution(spec, manifest) {
3773
3957
  ];
3774
3958
  return { resolve: resolve4, diagram: diagram2 };
3775
3959
  }
3960
+ const hops = [
3961
+ {
3962
+ type: root.type,
3963
+ tableName: root.tableName,
3964
+ ...root.indexName !== void 0 ? { indexName: root.indexName } : {},
3965
+ pkTemplate: opPkTemplate(root)
3966
+ },
3967
+ ...relHops
3968
+ ];
3776
3969
  const entityHops = [];
3777
3970
  const diagram = [];
3778
- for (let i = 0; i < spec.operations.length; i++) {
3779
- const op = spec.operations[i];
3780
- const entity = opEntityName(op, manifest) || op.tableName;
3781
- entityHops.push(`${op.type}(${entity}${op.indexName ? ` by ${op.indexName}` : ""})`);
3782
- const edge = i < spec.operations.length - 1 ? spec.operations[i + 1].type === "BatchGetItem" ? "BatchGet" : op.indexName ?? "PK" : "";
3971
+ for (let i = 0; i < hops.length; i++) {
3972
+ const hop = hops[i];
3973
+ const entity = hopEntityName(hop, manifest) || hop.tableName;
3974
+ entityHops.push(`${hop.type}(${entity}${hop.indexName ? ` by ${hop.indexName}` : ""})`);
3975
+ const edge = i < hops.length - 1 ? hops[i + 1].type === "BatchGetItem" ? "BatchGet" : hop.indexName ?? "PK" : "";
3783
3976
  diagram.push({ label: entity, edge });
3784
3977
  }
3785
3978
  return { resolve: entityHops.join(" \u2192 "), diagram };
@@ -3789,10 +3982,10 @@ function rootKeyLabel(op) {
3789
3982
  const prefix = op.indexName ? `${op.indexName} PK` : "PK";
3790
3983
  return `${prefix} = ${pk}`;
3791
3984
  }
3792
- function opEntityName(op, manifest) {
3793
- const pk = opPkTemplate(op);
3985
+ function hopEntityName(hop, manifest) {
3986
+ const pk = hop.pkTemplate;
3794
3987
  for (const [name, entity] of Object.entries(manifest.entities)) {
3795
- const cand = op.indexName ? gsiByName(entity, op.indexName)?.pkTemplate : entity.key?.pkTemplate;
3988
+ const cand = hop.indexName ? gsiByName(entity, hop.indexName)?.pkTemplate : entity.key?.pkTemplate;
3796
3989
  if (cand && pk) {
3797
3990
  if (literalPrefix(cand) === literalPrefix(pk)) return name;
3798
3991
  }
@@ -3998,14 +4191,18 @@ function buildDocModel(manifest, operations, registry = MetadataRegistry, option
3998
4191
  )
3999
4192
  };
4000
4193
  });
4194
+ const componentByName = new Map(
4195
+ (operations.components ?? []).map((c) => [c.name, c])
4196
+ );
4001
4197
  const accessPatterns = [];
4002
4198
  const accessMatrix = [];
4003
4199
  for (const name of Object.keys(operations.queries).sort()) {
4004
4200
  const spec = operations.queries[name];
4005
4201
  const entityName = rootEntityName(spec, manifest);
4006
- const { resolve: resolve4, diagram } = buildResolution(spec, manifest);
4007
- const relation = isRelation(spec);
4008
- const batchGet = usesBatchGet(spec);
4202
+ const relHops = relationHops(componentByName.get(name));
4203
+ const { resolve: resolve4, diagram } = buildResolution(spec, relHops, manifest);
4204
+ const relation = relHops.length > 0;
4205
+ const batchGet = spec.operations[0]?.type === "BatchGetItem" || relHops.some((h) => h.type === "BatchGetItem");
4009
4206
  const cursor = usesCursor(spec);
4010
4207
  const index = rootIndex(spec);
4011
4208
  const methodName = name.includes("__") ? name.slice(name.lastIndexOf("__") + 2) : name;
@@ -4366,6 +4563,9 @@ function renderBundle(queries = {}, commands = {}, registry = MetadataRegistry,
4366
4563
  };
4367
4564
  }
4368
4565
 
4566
+ // src/cli/handlers.ts
4567
+ import { generateModule, GeneratorFailure } from "behavior-contracts";
4568
+
4369
4569
  // src/codegen/jsdoc.ts
4370
4570
  async function loadTypescript() {
4371
4571
  try {
@@ -4817,6 +5017,92 @@ var handlers = {
4817
5017
  fail("GENERATION_FAILED", message, 1);
4818
5018
  }
4819
5019
  },
5020
+ /**
5021
+ * `generate behaviors --lang <ts|python|go|rust|php>` (issue #257 — the
5022
+ * codegen-static endpoint, §7.3 endpoint 3).
5023
+ *
5024
+ * Loads the TypeScript definitions exactly like `generate python`, builds the
5025
+ * SAME operations bundle (so the components[] are byte-identical to the ones
5026
+ * a `generate python` run serializes into operations.json — the fingerprint
5027
+ * skew check in the consuming runtimes depends on this), wraps the universal
5028
+ * `components[]` into the portable IR envelope, and invokes behavior-contracts'
5029
+ * common Generator (`generateModule`, bc#13). graphddb adds NO generation
5030
+ * logic: envelope + invoke + file write only. The dynamic JSON path stays the
5031
+ * default; the generated module is the opt-in static endpoint.
5032
+ */
5033
+ async generateBehaviors(options) {
5034
+ const {
5035
+ lang,
5036
+ entry,
5037
+ transactions: transactionsPath,
5038
+ contracts: contractsPath,
5039
+ contexts: contextsPath,
5040
+ runtimeImport,
5041
+ out
5042
+ } = options;
5043
+ if (!lang) fail("INVALID_ARGS", "Missing required option --lang.", 2);
5044
+ if (!entry) fail("INVALID_ARGS", "Missing required option --entry.", 2);
5045
+ if (!out) fail("INVALID_ARGS", "Missing required option --out.", 2);
5046
+ const LANGUAGES = {
5047
+ ts: { language: "typescript" },
5048
+ python: { language: "python" },
5049
+ go: { language: "go" },
5050
+ rust: { language: "rust" },
5051
+ php: { language: "php", runtimeImport: "GraphDDB\\Runtime\\BehaviorContracts" }
5052
+ };
5053
+ const target = LANGUAGES[lang];
5054
+ if (target === void 0) {
5055
+ fail(
5056
+ "INVALID_ARGS",
5057
+ `Unknown --lang '${lang}' (supported: ${Object.keys(LANGUAGES).join(", ")}).`,
5058
+ 2
5059
+ );
5060
+ }
5061
+ try {
5062
+ await importModelEntry(entry);
5063
+ const queries = {};
5064
+ const commands = {};
5065
+ const transactions = await loadOptionalMap(
5066
+ transactionsPath ?? entry,
5067
+ "transactions"
5068
+ );
5069
+ const contracts = await loadOptionalMap(
5070
+ contractsPath ?? entry,
5071
+ "contracts"
5072
+ );
5073
+ const contexts = await loadOptionalMap(
5074
+ contextsPath ?? contractsPath ?? entry,
5075
+ "contexts"
5076
+ );
5077
+ const abs = (p) => isAbsolute(p) ? p : resolve3(process.cwd(), p);
5078
+ await applyJsDocDescriptions({ entry: abs(entry) });
5079
+ const doc = buildOperations(queries, commands, transactions, { contracts, contexts });
5080
+ const components = doc.components ?? [];
5081
+ const generated = generateModule(
5082
+ portableIrDocument(components),
5083
+ {
5084
+ language: target.language,
5085
+ ...runtimeImport !== void 0 ? { runtimeImport } : target.runtimeImport !== void 0 ? { runtimeImport: target.runtimeImport } : {}
5086
+ }
5087
+ );
5088
+ const outDir = isAbsolute(out) ? out : resolve3(process.cwd(), out);
5089
+ mkdirSync(outDir, { recursive: true });
5090
+ writeFileSync(resolve3(outDir, generated.filenameHint), generated.code, "utf8");
5091
+ process.stdout.write(
5092
+ JSON.stringify({
5093
+ status: "ok",
5094
+ outDir: out,
5095
+ files: [generated.filenameHint]
5096
+ }) + "\n"
5097
+ );
5098
+ } catch (err) {
5099
+ if (err instanceof GeneratorFailure) {
5100
+ fail(`GENERATOR_${err.code}`, err.message, 1);
5101
+ }
5102
+ const message = err instanceof Error ? err.message : String(err);
5103
+ fail("GENERATION_FAILED", message, 1);
5104
+ }
5105
+ },
4820
5106
  /**
4821
5107
  * `generate php --typed` (issue #219, Epic #216 — typed-binding codegen).
4822
5108
  *