@orchestraworks/cli 0.5.7 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (94) hide show
  1. package/README.md +1 -1
  2. package/dist/cli/api/approval.js +3 -3
  3. package/dist/cli/commands/outpost/local.js +3 -3
  4. package/dist/cli/commands/outpost/machine-names.d.ts +17 -0
  5. package/dist/cli/commands/outpost/machine-names.js +22 -0
  6. package/dist/cli/commands/outpost/up.js +7 -5
  7. package/dist/cli/commands/worker/enroll.d.ts +4 -3
  8. package/dist/cli/commands/worker/enroll.js +4 -3
  9. package/dist/cli/core/auth.d.ts +22 -2
  10. package/dist/cli/core/auth.js +69 -8
  11. package/dist/cli/core/errors.js +4 -0
  12. package/dist/cli/core/platform-client.d.ts +3 -2
  13. package/dist/cli/core/session-body.d.ts +1 -1
  14. package/dist/cli/core/session-body.js +1 -1
  15. package/dist/cli/firstRun.d.ts +3 -3
  16. package/dist/cli/firstRun.js +7 -5
  17. package/dist/cli/main.js +4 -3
  18. package/dist/constructs/environment.d.ts +24 -11
  19. package/dist/constructs/environment.js +76 -12
  20. package/dist/constructs/secret.d.ts +17 -7
  21. package/dist/constructs/secret.js +24 -16
  22. package/dist/core/labels.d.ts +32 -6
  23. package/dist/core/labels.js +70 -8
  24. package/dist/engine/diff.js +38 -11
  25. package/dist/engine/gateway-key-reconcile.d.ts +1 -2
  26. package/dist/engine/gateway-key-reconcile.js +19 -15
  27. package/dist/engine/pipeline-reconcile.js +2 -2
  28. package/dist/engine/pipeline-workflow-reconcile.js +15 -9
  29. package/dist/engine/reconcile.js +48 -15
  30. package/dist/engine/refusals.d.ts +0 -5
  31. package/dist/engine/refusals.js +1 -5
  32. package/dist/engine/secrets-apply.d.ts +10 -14
  33. package/dist/engine/secrets-apply.js +12 -17
  34. package/dist/engine/workflow-reconcile.d.ts +1 -1
  35. package/dist/generated/cli-commands.json +170 -34
  36. package/dist/generated/providers.d.ts +40 -0
  37. package/dist/generated/providers.js +30 -0
  38. package/docs/REFERENCE.md +26 -12
  39. package/node_modules/@orchestraworks/client/dist/esm/models/ApiErrorDetail.d.ts +1 -1
  40. package/node_modules/@orchestraworks/client/dist/esm/models/CreateEnvironmentRequest.d.ts +7 -0
  41. package/node_modules/@orchestraworks/client/dist/esm/models/CreateEnvironmentRequest.js +3 -0
  42. package/node_modules/@orchestraworks/client/dist/esm/models/CreateSecretRequest.d.ts +4 -3
  43. package/node_modules/@orchestraworks/client/dist/esm/models/Environment.d.ts +7 -0
  44. package/node_modules/@orchestraworks/client/dist/esm/models/Environment.js +3 -0
  45. package/node_modules/@orchestraworks/client/dist/esm/models/EnvironmentCredential.d.ts +38 -0
  46. package/node_modules/@orchestraworks/client/dist/esm/models/EnvironmentCredential.js +45 -0
  47. package/node_modules/@orchestraworks/client/dist/esm/models/EnvironmentProvisionSpec.d.ts +1 -1
  48. package/node_modules/@orchestraworks/client/dist/esm/models/EnvironmentProvisionSpecRequest.d.ts +1 -1
  49. package/node_modules/@orchestraworks/client/dist/esm/models/EnvironmentSnapshot.d.ts +1 -1
  50. package/node_modules/@orchestraworks/client/dist/esm/models/InjectionRecipe.d.ts +6 -0
  51. package/node_modules/@orchestraworks/client/dist/esm/models/InjectionRecipe.js +2 -0
  52. package/node_modules/@orchestraworks/client/dist/esm/models/OAuthTokenRequest.d.ts +1 -1
  53. package/node_modules/@orchestraworks/client/dist/esm/models/Secret.d.ts +1 -7
  54. package/node_modules/@orchestraworks/client/dist/esm/models/Secret.js +0 -4
  55. package/node_modules/@orchestraworks/client/dist/esm/models/UpdateEnvironmentRequest.d.ts +7 -0
  56. package/node_modules/@orchestraworks/client/dist/esm/models/UpdateEnvironmentRequest.js +3 -0
  57. package/node_modules/@orchestraworks/client/dist/esm/models/UpdateSecretRequest.d.ts +4 -3
  58. package/node_modules/@orchestraworks/client/dist/esm/models/index.d.ts +1 -0
  59. package/node_modules/@orchestraworks/client/dist/esm/models/index.js +1 -0
  60. package/node_modules/@orchestraworks/client/dist/models/ApiErrorDetail.d.ts +1 -1
  61. package/node_modules/@orchestraworks/client/dist/models/CreateEnvironmentRequest.d.ts +7 -0
  62. package/node_modules/@orchestraworks/client/dist/models/CreateEnvironmentRequest.js +3 -0
  63. package/node_modules/@orchestraworks/client/dist/models/CreateSecretRequest.d.ts +4 -3
  64. package/node_modules/@orchestraworks/client/dist/models/Environment.d.ts +7 -0
  65. package/node_modules/@orchestraworks/client/dist/models/Environment.js +3 -0
  66. package/node_modules/@orchestraworks/client/dist/models/EnvironmentCredential.d.ts +38 -0
  67. package/node_modules/@orchestraworks/client/dist/models/EnvironmentCredential.js +52 -0
  68. package/node_modules/@orchestraworks/client/dist/models/EnvironmentProvisionSpec.d.ts +1 -1
  69. package/node_modules/@orchestraworks/client/dist/models/EnvironmentProvisionSpecRequest.d.ts +1 -1
  70. package/node_modules/@orchestraworks/client/dist/models/EnvironmentSnapshot.d.ts +1 -1
  71. package/node_modules/@orchestraworks/client/dist/models/InjectionRecipe.d.ts +6 -0
  72. package/node_modules/@orchestraworks/client/dist/models/InjectionRecipe.js +2 -0
  73. package/node_modules/@orchestraworks/client/dist/models/OAuthTokenRequest.d.ts +1 -1
  74. package/node_modules/@orchestraworks/client/dist/models/Secret.d.ts +1 -7
  75. package/node_modules/@orchestraworks/client/dist/models/Secret.js +0 -4
  76. package/node_modules/@orchestraworks/client/dist/models/UpdateEnvironmentRequest.d.ts +7 -0
  77. package/node_modules/@orchestraworks/client/dist/models/UpdateEnvironmentRequest.js +3 -0
  78. package/node_modules/@orchestraworks/client/dist/models/UpdateSecretRequest.d.ts +4 -3
  79. package/node_modules/@orchestraworks/client/dist/models/index.d.ts +1 -0
  80. package/node_modules/@orchestraworks/client/dist/models/index.js +1 -0
  81. package/node_modules/@orchestraworks/client/package.json +1 -1
  82. package/package.json +4 -4
  83. package/skills/orchestra/SKILL.md +38 -17
  84. package/skills/orchestra-fdk/references/authoring.md +34 -26
  85. package/skills/orchestra-fdk/references/environment.md +49 -12
  86. package/skills/orchestra-fdk/references/integrations/code-repo.md +26 -5
  87. package/skills/orchestra-fdk/references/phases/1-discover.md +1 -1
  88. package/skills/orchestra-fdk/references/phases/2-plan.md +1 -1
  89. package/skills/orchestra-fdk/references/troubleshooting.md +5 -3
  90. package/templates/bug-fix/main.ts +7 -4
  91. package/templates/engineering-team/lib/environment.ts +6 -3
  92. package/templates/engineering-team/package.json +1 -1
  93. package/templates/todo-factory/main.ts +7 -4
  94. package/templates/todo-factory/package.json +1 -1
@@ -219,7 +219,7 @@ the `agent` user. The worker writes a sign-in file only when none is there, so t
219
219
  **Before any cloud apply,** search `<factory>` for that marker, and for any credential in the setup script,
220
220
  in the environment's settings (`ENV`, which becomes `provisionSpec.env`), in the agents' instructions, and
221
221
  in every work-item description you write. Remove each one. Use a Secret
222
- instead: a gateway key, or a Secret whose `hosts` name where the edge adds it. Tell the developer why: the setup script and
222
+ instead: a gateway key, or a Secret whose recipe's `hosts` name where the edge adds it. Tell the developer why: the setup script and
223
223
  the settings are stored as plain text and shown on every read.
224
224
 
225
225
  ### Start the local environment
@@ -318,7 +318,7 @@ The local key is never carried over. It stays on the developer's computer. In th
318
318
  Orchestra Secret, and our network edge adds it to each model call, so no machine and no person holds it:
319
319
 
320
320
  - For the gateway, `apply` creates the gateway key and its secret. The starter already declares them.
321
- - For a subscription token or a provider key, declare a Secret whose `hosts` name the provider's host, and a
321
+ - For a subscription token or a provider key, declare a Secret whose recipe's `hosts` name the provider's host, and a
322
322
  rule that opens that host, as phase 2 of the orchestra-fdk skill, "The model route", says (orchestra skill,
323
323
  sections 6 and 7).
324
324
 
@@ -378,12 +378,15 @@ into `orchestra-factory-notes.md`.
378
378
  captured Windows VM does not register. The worker's own command, `worker install-machine --cloud
379
379
  azure`, adds the three parts the image must contain. The section "A team's own image" below gives the
380
380
  steps:
381
- - The worker's release package, at `C:\ProgramData\sfdk\worker\package`.
382
- - The worker's Windows service, `SfdkWorker`. It runs `worker.exe run --root C:\ProgramData\sfdk\worker
381
+ - The worker's release package, at `C:\ProgramData\orchestra\worker\package`.
382
+ - The worker's Windows service, `OrchestraWorker`. It runs `worker.exe run --root C:\ProgramData\orchestra\worker
383
383
  --service` as LocalSystem. It is demand-start (`Manual`), not automatic. On a failure it restarts
384
384
  three times, 2 seconds apart, and a clean stop with a non-zero exit code counts as a failure.
385
385
  - The startup task `orchestra-azure-userdata`. It runs `worker.exe boot-files --cloud azure` as SYSTEM
386
- at each boot. It writes the files that the VM's startup data carries, then starts `SfdkWorker`.
386
+ at each boot. It writes the files that the VM's startup data carries, then starts `OrchestraWorker`.
387
+ - An install replaces the service an earlier release registered as `SfdkWorker`. Change your own
388
+ scripts that name it. On an image an earlier release built, the startup task still starts
389
+ `SfdkWorker`.
387
390
 
388
391
  Our image runs the same command, from `install-vm-runtime.ps1` and the image template
389
392
  `infra/packer/azure-windows-runtime.pkr.hcl`. Under a Launcher, the image needs no WinDivert, no
@@ -463,7 +466,7 @@ agent can run the team's own `docker compose up` unchanged.
463
466
  *machine endpoint*, a web address that only signed-in members of the organization can open.
464
467
  4. Write the app's own settings files (`.env.local`) into the Set up item's description, because the code
465
468
  is not on the machine when the setup script runs. Put only local or test values there. A real secret
466
- becomes a Secret whose `hosts` name where the edge adds it.
469
+ becomes a Secret whose recipe's `hosts` name where the edge adds it.
467
470
  5. Choose the size by what CI uses for the same work. The template's sizes are fixed per agent: lg is
468
471
  32 CPU, md 16, sm 2.
469
472
  6. When the project runs containers, keep the disk at `/var/lib/docker`. The starter declares it. It keeps
@@ -650,8 +653,8 @@ failure stops the run and names the step. The team can run it again.
650
653
  - It refuses a VM that has already run as a machine, and a running worker service. Build on a new VM.
651
654
  - On Windows it creates the worker's folders for SYSTEM and the administrators only, so other accounts on
652
655
  the VM cannot add programs or read the boot files.
653
- - It copies the worker's package to the machine-wide root, `C:\ProgramData\sfdk\worker` or
654
- `/var/lib/sfdk/worker`.
656
+ - It copies the worker's package to the machine-wide root, `C:\ProgramData\orchestra\worker` or
657
+ `/var/lib/orchestra/worker`.
655
658
  - On Linux it creates the `agent` account, uid 1000, home `/home`.
656
659
  - It defines the worker's service, and the startup task that writes the boot files and starts the worker.
657
660
  - `--harness claude` preinstalls a harness. Without it, the harness installs itself on its first turn.
@@ -691,7 +694,7 @@ a Launcher machine, and the team installs their own tools.
691
694
  After each restart, run the check. Stop when it shows `"restartPending":false`:
692
695
 
693
696
  ```powershell
694
- & "$env:ProgramData\sfdk\worker\package\worker.exe" check --profile launcher --output json
697
+ & "$env:ProgramData\orchestra\worker\package\worker.exe" check --profile launcher --output json
695
698
  ```
696
699
 
697
700
  6. Generalize with Sysprep. It takes about 4 minutes, and the VM then stops:
@@ -815,8 +818,8 @@ Tokens on a compute provider's machines:
815
818
  carries them. Tell the developer this. If it is not acceptable, use route 2 or 3, or a Secret added
816
819
  at our network edge where one stands in front.
817
820
  2. **Baked into the team's image**, at machine scope, before Sysprep or generalizing. On Windows, that
818
- is the `SfdkWorker` service's `Environment` registry value. On Linux, it is a drop-in on
819
- `sfdk-worker.service`.
821
+ is the `OrchestraWorker` service's `Environment` registry value. On Linux, it is a drop-in on
822
+ `orchestra-worker.service`.
820
823
  3. **The `onStartAgent` hook** writes the harness's own key file in the agent's home:
821
824
  `.claude/.credentials.json` for a Claude sign-in, `.codex/auth.json` for `codex`, or
822
825
  `.pi/agent/auth.json` for `pi`. The worker keeps a real value it finds there. The hook can read the
@@ -870,6 +873,40 @@ that need no private service.
870
873
  **Check:** the typecheck and the synth pass, and the plan is as in item 3. Go back to the orchestra-fdk
871
874
  skill's phase 4 for the apply.
872
875
 
876
+ ### Naming a credential
877
+
878
+ The network edge adds a credential to a request in two cases only. A request that names none and that no
879
+ environment default covers leaves with the headers it was sent, a placeholder included.
880
+
881
+ - **The request names it.** Set the variable a tool reads its token from to a `Secret` or a `Connection`
882
+ in the environment's `env`. Apply writes `orchestra:secret/<id>` or `orchestra:connection/<id>`, and the
883
+ tool sends that reference where its token goes. The edge reads it and adds the credential, if the
884
+ agent may use it.
885
+
886
+ | Tool | Variable |
887
+ |---|---|
888
+ | claude, pi | `ANTHROPIC_API_KEY`, or `CLAUDE_CODE_OAUTH_TOKEN` for a subscription token |
889
+ | codex | `ORCHESTRA_WORKER_OPENAI_API_KEY`, which the worker writes into codex's own auth file |
890
+ | `gh` | `GH_TOKEN` |
891
+ | `glab` | `GITLAB_TOKEN`, which `glab` sends as `Private-Token` |
892
+ | git | `ORCHESTRA_GIT_CREDENTIAL`: the image's git credential helper answers it when the server asks |
893
+ | `linear`, `slack`, `teams` | `--connection-id <id>` on the command; it reads no connection |
894
+
895
+ `routeModelsViaGateway({ key })` sets `ANTHROPIC_API_KEY` and `ORCHESTRA_WORKER_OPENAI_API_KEY` to the
896
+ key Secret itself, so declare neither beside it.
897
+
898
+ - **An environment credential covers the host.** `credentials` lists Secrets and Connections. A
899
+ request from the environment's machines that names none gets the first whose hosts cover its host,
900
+ whatever the agent. `replace` is true unless set: with `replace: false`, a request that carries its own
901
+ value in the credential's header keeps it and gets nothing. Adding an entry needs your own use of that
902
+ credential.
903
+
904
+ ```ts
905
+ credentials: [{ credential: githubConnection }, { credential: modelKey, replace: false }],
906
+ ```
907
+
908
+ With no `credentials` declared, apply leaves the live list alone; `[]` clears it.
909
+
873
910
  ## 7. The cloud
874
911
 
875
912
  The cloud is the fallback when no local mode can run. It is also the confirmation after the local proof:
@@ -914,7 +951,7 @@ agent's shell, its browser step hangs.
914
951
  copy it, then `umask 077 && pbpaste | tr -d '\n' > <file> && pbcopy </dev/null`. At apply, the shell
915
952
  exports it from that file into the variable a `Secret` reads. An egress rule allows `api.anthropic.com`
916
953
  and adds `Authorization: Bearer ${secret}`, removing `x-api-key`. The environment's `env` holds only
917
- `CLAUDE_CODE_OAUTH_TOKEN=software-factory-egress-placeholder` and an empty `ANTHROPIC_API_KEY`, and the
954
+ `CLAUDE_CODE_OAUTH_TOKEN` set to the Secret, its reference, and an empty `ANTHROPIC_API_KEY`, and the
918
955
  agent's gateway setting is off. Never put the token itself in `env`. The Claude sign-in recipe in
919
956
  `references/authoring.md` shows the declaration. Copying the renewing credentials file is the fallback,
920
957
  and follows the ChatGPT sign-in steps below.
@@ -4,7 +4,10 @@ Give access with a Secret the network edge adds, or with the provider's platform
4
4
  so add only the rule that adds the credential. Git over HTTPS and the REST API often take the token in
5
5
  different forms: give each its own rule, scoped by host or by path. A connection also brings events, which
6
6
  a `Trigger` turns into work. The agent installs or uses whatever git or API client it prefers. The edge adds
7
- the credential to its requests.
7
+ the credential only to a request that names it, or that an environment default covers
8
+ (`../environment.md`, "Naming a credential"). Name it in the environment's `env`: `GH_TOKEN` for `gh`,
9
+ `GITLAB_TOKEN` for `glab`, and `ORCHESTRA_GIT_CREDENTIAL` for git, each set to the Secret or the
10
+ Connection.
8
11
 
9
12
  Phase 3, "From a recipe to code", turns a recipe into a Secret and a rule.
10
13
 
@@ -21,8 +24,25 @@ project or the profile; Azure DevOps **User settings › Personal access tokens*
21
24
 
22
25
  ## Git over HTTPS
23
26
 
24
- Git sends Basic auth. The edge adds it, so the agent clones `https://<host>/<path>.git` with no user name
25
- and no password in the address.
27
+ Git sends Basic auth. The image's git credential helper answers the reference in `ORCHESTRA_GIT_CREDENTIAL`
28
+ as the password when the server asks, and the edge replaces it, so the agent clones
29
+ `https://<host>/<path>.git` with no user name and no password in the address. A default that covers the
30
+ host adds the credential with no reference.
31
+
32
+ A git token Secret stores the encoded value `base64("<user>:<token>")` and presents it as `Basic`. The
33
+ recipe has no base64 step, so encode the pair first. `SecretValue.basicAuth(user, value)` encodes it at
34
+ apply; to store it through the API or the console, encode it yourself:
35
+
36
+ ```sh
37
+ printf 'x-access-token:%s' "$TOKEN" | base64 | tr -d '\n'
38
+ ```
39
+
40
+ ```ts
41
+ new Secret(factory, "github-git", {
42
+ value: SecretValue.basicAuth("x-access-token", SecretValue.fromEnv("ORCHESTRA_FDK_GITHUB_TOKEN")),
43
+ injection: { headers: [{ name: "Authorization", value: "Basic ${secret}" }], hosts: ["github.com"] },
44
+ });
45
+ ```
26
46
 
27
47
  - **GitHub:** the user name is `x-access-token`, and the password is the token:
28
48
  `SecretValue.basicAuth("x-access-token", SecretValue.fromEnv("ORCHESTRA_FDK_GITHUB_TOKEN"))`. The GitHub
@@ -42,8 +62,9 @@ the first declared wins for every request. So scope the API rule to `paths: ["/a
42
62
  priority, 310. The git rule at 300 takes the rest of the host.
43
63
 
44
64
  The API rule replaces the `PRIVATE-TOKEN` header. A project access token must be sent this way: sent as
45
- `Authorization: Bearer` beside a placeholder `PRIVATE-TOKEN`, GitLab answers 401. A personal token works the
46
- same way.
65
+ `Authorization: Bearer` beside another `PRIVATE-TOKEN`, GitLab answers 401. A personal token works the
66
+ same way. `glab` sends `GITLAB_TOKEN` as `Private-Token`, so set `GITLAB_TOKEN` to the Secret or the
67
+ Connection, and the edge reads the reference there.
47
68
 
48
69
  With the `gitlab` connection and `Auth.oauth()`, use `.allow(gitlab, { paths: ["/api/*"], priority: 310 })`
49
70
  for the API instead, and keep the git rule. GitLab does not let the platform register the webhook. The
@@ -19,7 +19,7 @@ npx --package @orchestraworks/cli orchestra workflows list --all-pages --output
19
19
  npx --package @orchestraworks/cli orchestra connections list --output json
20
20
  ```
21
21
 
22
- A row that an apply made carries the label `sfdk.managedBy`, whose value is the factory's name.
22
+ A row that an apply made carries the label `orchestra.managedBy`, whose value is the factory's name.
23
23
 
24
24
  1. Infer what the developer most likely wants:
25
25
  - *No agents and no pipelines:* the account is empty. Infer **a new factory**.
@@ -90,7 +90,7 @@ your shell, its browser step hangs. You never read or copy the value.
90
90
 
91
91
  - *Claude.* `claude setup-token` prints a long-lived token. The developer saves it in the private file as
92
92
  `ORCHESTRA_FDK_CLAUDE_CODE_OAUTH_TOKEN`. The factory stores it as a Secret, and the network edge adds it to
93
- calls to `api.anthropic.com`. The machine holds only a placeholder token and an empty API key. Declare the
93
+ calls to `api.anthropic.com` that name it. The machine holds only the Secret's reference and an empty API key. Declare the
94
94
  Claude sign-in recipe from `../authoring.md`, "Secrets are recipes, never values". Never put the token in
95
95
  the environment's settings: they are stored and shown in plain text.
96
96
  - *Codex.* A personal access token, which begins `at-`. A ChatGPT Business or Enterprise member makes it at
@@ -48,7 +48,8 @@ The network edge answers the agent, not you. The agent sees one of these:
48
48
  host. `details.reason` is `policy_denied` or `ambiguous_match` (two rules match with equal weight). The
49
49
  answer does not name a rule.
50
50
  - `403 egress identity missing` or `egress destination mismatch`, or `502 egress broker unavailable` or
51
- `egress upstream unavailable`: a fault on the path, not the rules.
51
+ `egress upstream unavailable`: a fault on the path, not the rules. A `421 egress destination mismatch`
52
+ asks the client to send the request again on a new connection, and a browser does this by itself.
52
53
 
53
54
  To check the rules the machine has now, read `egressPolicy` in `get-diagnostics`: `defaultAction`, and each
54
55
  rule's name, priority, action, hosts and paths. Fix the rules in code and apply. Rules reach running
@@ -82,7 +83,8 @@ C, "Tokens on a compute provider's machines").
82
83
 
83
84
  - A `401` from the model provider, or "Invalid API key": the agent has no model key. Check the route the
84
85
  team chose: the environment's `env`, the image's worker service environment (on Windows, the
85
- `SfdkWorker` service's `Environment` registry value), or the key file the `onStartAgent` hook writes.
86
+ `OrchestraWorker` service's `Environment` registry value, or `SfdkWorker` on an image an earlier
87
+ release built), or the key file the `onStartAgent` hook writes.
86
88
  - The image's value is a real key and `env` declares another: the image's value wins. A declared value
87
89
  replaces only our image's placeholder.
88
90
  - Never restart the worker service to load a key. A restart after the worker registered stops the
@@ -108,7 +110,7 @@ C, "Tokens on a compute provider's machines").
108
110
  - A trigger that could not start a session shows the reason on the trigger's `lastDecision`. A work item
109
111
  shows a feed note: `No session started for <agent>: ...`.
110
112
  - The model gateway answers `403` with `credits_exhausted` or `budget_exceeded`, in the model provider's
111
- own error shape, with a `[sfdk]` prefix on the message.
113
+ own error shape, with an `[orchestra]` prefix on the message.
112
114
  - `403` with `PLAN_FEATURE_DISABLED`: the plan does not include the feature. This is not a credit problem.
113
115
 
114
116
  `maxSessionsPerMachine` is not an error. A session past it starts another machine.
@@ -68,13 +68,16 @@ const github = new Connection(factory, "github", {
68
68
  install: { permissions: ["contents:write"] },
69
69
  });
70
70
 
71
- // The edge adds the gateway key on the gateway's host. The runtime image's placeholder key rides x-api-key, and
72
- // the gateway refuses two keys that disagree, so the recipe removes it.
71
+ // The edge adds the gateway key on the gateway's host. Claude sends the key's reference in x-api-key, and the
72
+ // gateway refuses two keys that disagree, so the recipe removes it.
73
73
  const gatewayHost = required("ORCHESTRA_FDK_MODEL_GATEWAY_HOST");
74
74
  const gatewayKey = new Secret(factory, "model-gateway-key", {
75
75
  value: SecretValue.fromGatewayKey(new GatewayKey(factory, "model-gateway", { displayName: "__FACTORY_NAME__ bug fixing" })),
76
- hosts: [gatewayHost],
77
- injection: { headers: [{ name: "Authorization", value: "Bearer ${secret}" }], removeHeaders: ["x-api-key"] },
76
+ injection: {
77
+ headers: [{ name: "Authorization", value: "Bearer ${secret}" }],
78
+ removeHeaders: ["x-api-key"],
79
+ hosts: [gatewayHost],
80
+ },
78
81
  });
79
82
  // init-if: anthropic
80
83
 
@@ -59,9 +59,12 @@ export function declareKeys(factory: Factory): Keys {
59
59
  name: "Model gateway key",
60
60
  description: "Added to model calls at the network edge. The agents never see it.",
61
61
  value: SecretValue.fromGatewayKey(gatewayKey),
62
- hosts: [DEFAULT_MODEL_GATEWAY_HOST],
63
- // The runtime image's placeholder key rides x-api-key, and the gateway refuses two keys that disagree.
64
- injection: { headers: [{ name: "Authorization", value: "Bearer ${secret}" }], removeHeaders: ["x-api-key"] },
62
+ // Claude sends the key's reference in x-api-key, and the gateway refuses two keys that disagree.
63
+ injection: {
64
+ headers: [{ name: "Authorization", value: "Bearer ${secret}" }],
65
+ removeHeaders: ["x-api-key"],
66
+ hosts: [DEFAULT_MODEL_GATEWAY_HOST],
67
+ },
65
68
  });
66
69
  return { modelGateway };
67
70
  }
@@ -9,7 +9,7 @@
9
9
  "typecheck": "tsc -p tsconfig.json"
10
10
  },
11
11
  "dependencies": {
12
- "@orchestraworks/cli": "^0.5.0"
12
+ "@orchestraworks/cli": "^0.6.0"
13
13
  },
14
14
  "devDependencies": {
15
15
  "@types/node": "^22.10.0",
@@ -66,13 +66,16 @@ const github = new Connection(factory, "github", {
66
66
  install: { permissions: ["contents:write"] },
67
67
  });
68
68
 
69
- // The edge adds the gateway key on the gateway's host. The runtime image's placeholder key rides x-api-key, and
70
- // the gateway refuses two keys that disagree, so the recipe removes it.
69
+ // The edge adds the gateway key on the gateway's host. Claude sends the key's reference in x-api-key, and the
70
+ // gateway refuses two keys that disagree, so the recipe removes it.
71
71
  const gatewayHost = required("ORCHESTRA_FDK_MODEL_GATEWAY_HOST");
72
72
  const gatewayKey = new Secret(factory, "model-gateway-key", {
73
73
  value: SecretValue.fromGatewayKey(new GatewayKey(factory, "model-gateway", { displayName: "todo-app bug fixing" })),
74
- hosts: [gatewayHost],
75
- injection: { headers: [{ name: "Authorization", value: "Bearer ${secret}" }], removeHeaders: ["x-api-key"] },
74
+ injection: {
75
+ headers: [{ name: "Authorization", value: "Bearer ${secret}" }],
76
+ removeHeaders: ["x-api-key"],
77
+ hosts: [gatewayHost],
78
+ },
76
79
  });
77
80
 
78
81
  // The image tag hashes the runtime image and every file under image/: a rebuilt image under an unchanged tag
@@ -9,7 +9,7 @@
9
9
  "typecheck": "tsc -p tsconfig.json"
10
10
  },
11
11
  "dependencies": {
12
- "@orchestraworks/cli": "^0.5.0"
12
+ "@orchestraworks/cli": "^0.6.0"
13
13
  },
14
14
  "devDependencies": {
15
15
  "@types/node": "^22.10.0",