@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.
- package/README.md +1 -1
- package/dist/cli/api/approval.js +3 -3
- package/dist/cli/commands/outpost/local.js +3 -3
- package/dist/cli/commands/outpost/machine-names.d.ts +17 -0
- package/dist/cli/commands/outpost/machine-names.js +22 -0
- package/dist/cli/commands/outpost/up.js +7 -5
- package/dist/cli/commands/worker/enroll.d.ts +4 -3
- package/dist/cli/commands/worker/enroll.js +4 -3
- package/dist/cli/core/auth.d.ts +22 -2
- package/dist/cli/core/auth.js +69 -8
- package/dist/cli/core/errors.js +4 -0
- package/dist/cli/core/platform-client.d.ts +3 -2
- package/dist/cli/core/session-body.d.ts +1 -1
- package/dist/cli/core/session-body.js +1 -1
- package/dist/cli/firstRun.d.ts +3 -3
- package/dist/cli/firstRun.js +7 -5
- package/dist/cli/main.js +4 -3
- package/dist/constructs/environment.d.ts +24 -11
- package/dist/constructs/environment.js +76 -12
- package/dist/constructs/secret.d.ts +17 -7
- package/dist/constructs/secret.js +24 -16
- package/dist/core/labels.d.ts +32 -6
- package/dist/core/labels.js +70 -8
- package/dist/engine/diff.js +38 -11
- package/dist/engine/gateway-key-reconcile.d.ts +1 -2
- package/dist/engine/gateway-key-reconcile.js +19 -15
- package/dist/engine/pipeline-reconcile.js +2 -2
- package/dist/engine/pipeline-workflow-reconcile.js +15 -9
- package/dist/engine/reconcile.js +48 -15
- package/dist/engine/refusals.d.ts +0 -5
- package/dist/engine/refusals.js +1 -5
- package/dist/engine/secrets-apply.d.ts +10 -14
- package/dist/engine/secrets-apply.js +12 -17
- package/dist/engine/workflow-reconcile.d.ts +1 -1
- package/dist/generated/cli-commands.json +170 -34
- package/dist/generated/providers.d.ts +40 -0
- package/dist/generated/providers.js +30 -0
- package/docs/REFERENCE.md +26 -12
- package/node_modules/@orchestraworks/client/dist/esm/models/ApiErrorDetail.d.ts +1 -1
- package/node_modules/@orchestraworks/client/dist/esm/models/CreateEnvironmentRequest.d.ts +7 -0
- package/node_modules/@orchestraworks/client/dist/esm/models/CreateEnvironmentRequest.js +3 -0
- package/node_modules/@orchestraworks/client/dist/esm/models/CreateSecretRequest.d.ts +4 -3
- package/node_modules/@orchestraworks/client/dist/esm/models/Environment.d.ts +7 -0
- package/node_modules/@orchestraworks/client/dist/esm/models/Environment.js +3 -0
- package/node_modules/@orchestraworks/client/dist/esm/models/EnvironmentCredential.d.ts +38 -0
- package/node_modules/@orchestraworks/client/dist/esm/models/EnvironmentCredential.js +45 -0
- package/node_modules/@orchestraworks/client/dist/esm/models/EnvironmentProvisionSpec.d.ts +1 -1
- package/node_modules/@orchestraworks/client/dist/esm/models/EnvironmentProvisionSpecRequest.d.ts +1 -1
- package/node_modules/@orchestraworks/client/dist/esm/models/EnvironmentSnapshot.d.ts +1 -1
- package/node_modules/@orchestraworks/client/dist/esm/models/InjectionRecipe.d.ts +6 -0
- package/node_modules/@orchestraworks/client/dist/esm/models/InjectionRecipe.js +2 -0
- package/node_modules/@orchestraworks/client/dist/esm/models/OAuthTokenRequest.d.ts +1 -1
- package/node_modules/@orchestraworks/client/dist/esm/models/Secret.d.ts +1 -7
- package/node_modules/@orchestraworks/client/dist/esm/models/Secret.js +0 -4
- package/node_modules/@orchestraworks/client/dist/esm/models/UpdateEnvironmentRequest.d.ts +7 -0
- package/node_modules/@orchestraworks/client/dist/esm/models/UpdateEnvironmentRequest.js +3 -0
- package/node_modules/@orchestraworks/client/dist/esm/models/UpdateSecretRequest.d.ts +4 -3
- package/node_modules/@orchestraworks/client/dist/esm/models/index.d.ts +1 -0
- package/node_modules/@orchestraworks/client/dist/esm/models/index.js +1 -0
- package/node_modules/@orchestraworks/client/dist/models/ApiErrorDetail.d.ts +1 -1
- package/node_modules/@orchestraworks/client/dist/models/CreateEnvironmentRequest.d.ts +7 -0
- package/node_modules/@orchestraworks/client/dist/models/CreateEnvironmentRequest.js +3 -0
- package/node_modules/@orchestraworks/client/dist/models/CreateSecretRequest.d.ts +4 -3
- package/node_modules/@orchestraworks/client/dist/models/Environment.d.ts +7 -0
- package/node_modules/@orchestraworks/client/dist/models/Environment.js +3 -0
- package/node_modules/@orchestraworks/client/dist/models/EnvironmentCredential.d.ts +38 -0
- package/node_modules/@orchestraworks/client/dist/models/EnvironmentCredential.js +52 -0
- package/node_modules/@orchestraworks/client/dist/models/EnvironmentProvisionSpec.d.ts +1 -1
- package/node_modules/@orchestraworks/client/dist/models/EnvironmentProvisionSpecRequest.d.ts +1 -1
- package/node_modules/@orchestraworks/client/dist/models/EnvironmentSnapshot.d.ts +1 -1
- package/node_modules/@orchestraworks/client/dist/models/InjectionRecipe.d.ts +6 -0
- package/node_modules/@orchestraworks/client/dist/models/InjectionRecipe.js +2 -0
- package/node_modules/@orchestraworks/client/dist/models/OAuthTokenRequest.d.ts +1 -1
- package/node_modules/@orchestraworks/client/dist/models/Secret.d.ts +1 -7
- package/node_modules/@orchestraworks/client/dist/models/Secret.js +0 -4
- package/node_modules/@orchestraworks/client/dist/models/UpdateEnvironmentRequest.d.ts +7 -0
- package/node_modules/@orchestraworks/client/dist/models/UpdateEnvironmentRequest.js +3 -0
- package/node_modules/@orchestraworks/client/dist/models/UpdateSecretRequest.d.ts +4 -3
- package/node_modules/@orchestraworks/client/dist/models/index.d.ts +1 -0
- package/node_modules/@orchestraworks/client/dist/models/index.js +1 -0
- package/node_modules/@orchestraworks/client/package.json +1 -1
- package/package.json +4 -4
- package/skills/orchestra/SKILL.md +38 -17
- package/skills/orchestra-fdk/references/authoring.md +34 -26
- package/skills/orchestra-fdk/references/environment.md +49 -12
- package/skills/orchestra-fdk/references/integrations/code-repo.md +26 -5
- package/skills/orchestra-fdk/references/phases/1-discover.md +1 -1
- package/skills/orchestra-fdk/references/phases/2-plan.md +1 -1
- package/skills/orchestra-fdk/references/troubleshooting.md +5 -3
- package/templates/bug-fix/main.ts +7 -4
- package/templates/engineering-team/lib/environment.ts +6 -3
- package/templates/engineering-team/package.json +1 -1
- package/templates/todo-factory/main.ts +7 -4
- package/templates/todo-factory/package.json +1 -1
|
@@ -107,7 +107,7 @@ export interface EnvironmentSnapshot {
|
|
|
107
107
|
*/
|
|
108
108
|
setup?: string;
|
|
109
109
|
/**
|
|
110
|
-
* Environment variables set on every machine created from this environment, and forwarded into the agent process itself. NOT A SECRET STORE: values are stored unencrypted on the environment row and returned verbatim by every read of it, so anyone who can read the environment can read them. Put credentials in a Secret referenced by an egress allow rule instead - the broker injects those into the outbound request at the egress edge and the agent process never holds them. Names beginning SFDK_ or ORCHESTRA_ are platform-owned and rejected, and the platform writes its own reserved variables last, overriding anything you declare. Names beginning ORCHESTRA_FDK_, the inputs of an agent-as-code kit, are accepted in exactly that spelling as ordinary variables of your own. The other exception is six worker settings, accepted in exactly this spelling:
|
|
110
|
+
* Environment variables set on every machine created from this environment, and forwarded into the agent process itself. NOT A SECRET STORE: values are stored unencrypted on the environment row and returned verbatim by every read of it, so anyone who can read the environment can read them. Put credentials in a Secret referenced by an egress allow rule instead - the broker injects those into the outbound request at the egress edge and the agent process never holds them. Names beginning SFDK_ or ORCHESTRA_ are platform-owned and rejected, and the platform writes its own reserved variables last, overriding anything you declare. Names beginning ORCHESTRA_FDK_, the inputs of an agent-as-code kit, are accepted in exactly that spelling as ordinary variables of your own. The other exception is six worker settings, accepted in exactly this spelling: ORCHESTRA_WORKER_RESTART_AFTER_IDLE, ORCHESTRA_WORKER_RELEASE_FETCH_TIMEOUT and ORCHESTRA_WORKER_RELEASE_CHECK_INTERVAL, each a positive duration such as 30s or 5m; ORCHESTRA_WORKER_RELEASE_REGISTRY_URL, an http or https URL; and ORCHESTRA_WORKER_AUTO_UPGRADE and ORCHESTRA_WORKER_AUTO_RESTART, each exactly true or false, which turn the worker's move to a newer release and its restart into that release on or off. Their former spellings beginning SFDK_WORKER_ are refused. They reach the machine's worker, where each one set wins over the platform's release settings, and never an agent process. HOME and USERPROFILE are not among them: the platform sets neither, the account inside the image decides where the home directory is, and a HOME you declare here is passed to the harness to conform to or complain about. Declare a volume mount at /home if you want that home directory to be durable. On a Windows environment names are matched case-insensitively, the way Windows itself matches them - sfdk_x and orchestra_fdk_x are rejected reserved names there, and Home and HOME are one variable - while a POSIX environment matches names exactly. At most 64 entries; a key matches [A-Za-z_][A-Za-z0-9_]* and is at most 128 characters; a value is at most 4096 characters.
|
|
111
111
|
* @type {{ [key: string]: string; }}
|
|
112
112
|
* @memberof EnvironmentSnapshot
|
|
113
113
|
*/
|
|
@@ -28,6 +28,12 @@ export interface InjectionRecipe {
|
|
|
28
28
|
* @memberof InjectionRecipe
|
|
29
29
|
*/
|
|
30
30
|
removeHeaders: Array<string>;
|
|
31
|
+
/**
|
|
32
|
+
* Host patterns this secret is presented on, in egress rule host syntax (exact host, *.suffix, or *); empty or omitted covers no host. A non-empty list needs at least one header, and no pattern may name the platform API host or the object store host.
|
|
33
|
+
* @type {Array<string>}
|
|
34
|
+
* @memberof InjectionRecipe
|
|
35
|
+
*/
|
|
36
|
+
hosts?: Array<string>;
|
|
31
37
|
}
|
|
32
38
|
/**
|
|
33
39
|
* Check if a given object implements the InjectionRecipe interface.
|
|
@@ -37,6 +37,7 @@ function InjectionRecipeFromJSONTyped(json, ignoreDiscriminator) {
|
|
|
37
37
|
return {
|
|
38
38
|
'headers': json['headers'] == null ? undefined : (json['headers'].map(InjectionHeader_1.InjectionHeaderFromJSON)),
|
|
39
39
|
'removeHeaders': json['removeHeaders'],
|
|
40
|
+
'hosts': json['hosts'] == null ? undefined : json['hosts'],
|
|
40
41
|
};
|
|
41
42
|
}
|
|
42
43
|
function InjectionRecipeToJSON(json) {
|
|
@@ -49,5 +50,6 @@ function InjectionRecipeToJSONTyped(value, ignoreDiscriminator = false) {
|
|
|
49
50
|
return {
|
|
50
51
|
'headers': value['headers'] == null ? undefined : (value['headers'].map(InjectionHeader_1.InjectionHeaderToJSON)),
|
|
51
52
|
'removeHeaders': value['removeHeaders'],
|
|
53
|
+
'hosts': value['hosts'],
|
|
52
54
|
};
|
|
53
55
|
}
|
|
@@ -80,17 +80,11 @@ export interface Secret {
|
|
|
80
80
|
*/
|
|
81
81
|
expiresAt?: Date;
|
|
82
82
|
/**
|
|
83
|
-
* Optional injection recipe
|
|
83
|
+
* Optional injection recipe: the request mutations the broker applies from this secret, and the hosts it applies them on. A secret without one is stored only: the broker presents it on no request. For git over HTTPS, store base64 of <user>:<token> as the value, such as the output of printf 'x-access-token:%s' "$TOKEN" | base64 | tr -d '\n' for a GitHub token, and present it as Authorization: Basic ${secret}.
|
|
84
84
|
* @type {InjectionRecipe}
|
|
85
85
|
* @memberof Secret
|
|
86
86
|
*/
|
|
87
87
|
injection?: InjectionRecipe;
|
|
88
|
-
/**
|
|
89
|
-
* Host patterns this secret is presented on, in egress rule host syntax (exact host, *.suffix, or *); empty covers no host
|
|
90
|
-
* @type {Array<string>}
|
|
91
|
-
* @memberof Secret
|
|
92
|
-
*/
|
|
93
|
-
hosts: Array<string>;
|
|
94
88
|
/**
|
|
95
89
|
* The agents you can see that may use this secret, as IAM decides at this read. Present on the singular read only; a list row leaves it out.
|
|
96
90
|
* @type {Array<Agent>}
|
|
@@ -40,8 +40,6 @@ function instanceOfSecret(value) {
|
|
|
40
40
|
return false;
|
|
41
41
|
if (!('updatedAt' in value) || value['updatedAt'] === undefined)
|
|
42
42
|
return false;
|
|
43
|
-
if (!('hosts' in value) || value['hosts'] === undefined)
|
|
44
|
-
return false;
|
|
45
43
|
return true;
|
|
46
44
|
}
|
|
47
45
|
function SecretFromJSON(json) {
|
|
@@ -63,7 +61,6 @@ function SecretFromJSONTyped(json, ignoreDiscriminator) {
|
|
|
63
61
|
'updatedAt': (new Date(json['updatedAt'])),
|
|
64
62
|
'expiresAt': json['expiresAt'] == null ? undefined : (new Date(json['expiresAt'])),
|
|
65
63
|
'injection': json['injection'] == null ? undefined : (0, InjectionRecipe_1.InjectionRecipeFromJSON)(json['injection']),
|
|
66
|
-
'hosts': json['hosts'],
|
|
67
64
|
'usableBy': json['usableBy'] == null ? undefined : (json['usableBy'].map(Agent_1.AgentFromJSON)),
|
|
68
65
|
};
|
|
69
66
|
}
|
|
@@ -86,6 +83,5 @@ function SecretToJSONTyped(value, ignoreDiscriminator = false) {
|
|
|
86
83
|
'updatedAt': value['updatedAt'].toISOString(),
|
|
87
84
|
'expiresAt': value['expiresAt'] == null ? value['expiresAt'] : value['expiresAt'].toISOString(),
|
|
88
85
|
'injection': (0, InjectionRecipe_1.InjectionRecipeToJSON)(value['injection']),
|
|
89
|
-
'hosts': value['hosts'],
|
|
90
86
|
};
|
|
91
87
|
}
|
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
* Do not edit the class manually.
|
|
11
11
|
*/
|
|
12
12
|
import type { EnvironmentIngressPolicy } from './EnvironmentIngressPolicy';
|
|
13
|
+
import type { EnvironmentCredential } from './EnvironmentCredential';
|
|
13
14
|
import type { EnvironmentPlatformRequest } from './EnvironmentPlatformRequest';
|
|
14
15
|
import type { EnvironmentEgressPolicy } from './EnvironmentEgressPolicy';
|
|
15
16
|
import type { EnvironmentProvisionSpecRequest } from './EnvironmentProvisionSpecRequest';
|
|
@@ -44,6 +45,12 @@ export interface UpdateEnvironmentRequest {
|
|
|
44
45
|
* @memberof UpdateEnvironmentRequest
|
|
45
46
|
*/
|
|
46
47
|
ingressPolicy?: EnvironmentIngressPolicy | null;
|
|
48
|
+
/**
|
|
49
|
+
* The credentials this environment's machines get on a request that names none, in order: the first one covering the request's host is added, whatever the agent. Each entry is a Secret or Connection of this organization by id, and adding one needs the caller's own use of it. A request naming a credential gets that one instead. A provided list replaces the stored one, and absent leaves it.
|
|
50
|
+
* @type {Array<EnvironmentCredential>}
|
|
51
|
+
* @memberof UpdateEnvironmentRequest
|
|
52
|
+
*/
|
|
53
|
+
credentials?: Array<EnvironmentCredential>;
|
|
47
54
|
/**
|
|
48
55
|
* The launch spec — every fact that applies only when the platform controls the machine. Rejected on an enrolled environment, whose machine the platform never launches.
|
|
49
56
|
* @type {EnvironmentProvisionSpecRequest}
|
|
@@ -19,6 +19,7 @@ exports.UpdateEnvironmentRequestFromJSONTyped = UpdateEnvironmentRequestFromJSON
|
|
|
19
19
|
exports.UpdateEnvironmentRequestToJSON = UpdateEnvironmentRequestToJSON;
|
|
20
20
|
exports.UpdateEnvironmentRequestToJSONTyped = UpdateEnvironmentRequestToJSONTyped;
|
|
21
21
|
const EnvironmentIngressPolicy_1 = require("./EnvironmentIngressPolicy");
|
|
22
|
+
const EnvironmentCredential_1 = require("./EnvironmentCredential");
|
|
22
23
|
const EnvironmentPlatformRequest_1 = require("./EnvironmentPlatformRequest");
|
|
23
24
|
const EnvironmentEgressPolicy_1 = require("./EnvironmentEgressPolicy");
|
|
24
25
|
const EnvironmentProvisionSpecRequest_1 = require("./EnvironmentProvisionSpecRequest");
|
|
@@ -41,6 +42,7 @@ function UpdateEnvironmentRequestFromJSONTyped(json, ignoreDiscriminator) {
|
|
|
41
42
|
'platform': json['platform'] == null ? undefined : (0, EnvironmentPlatformRequest_1.EnvironmentPlatformRequestFromJSON)(json['platform']),
|
|
42
43
|
'egressPolicy': json['egressPolicy'] == null ? undefined : (0, EnvironmentEgressPolicy_1.EnvironmentEgressPolicyFromJSON)(json['egressPolicy']),
|
|
43
44
|
'ingressPolicy': json['ingressPolicy'] == null ? undefined : (0, EnvironmentIngressPolicy_1.EnvironmentIngressPolicyFromJSON)(json['ingressPolicy']),
|
|
45
|
+
'credentials': json['credentials'] == null ? undefined : (json['credentials'].map(EnvironmentCredential_1.EnvironmentCredentialFromJSON)),
|
|
44
46
|
'provisionSpec': json['provisionSpec'] == null ? undefined : (0, EnvironmentProvisionSpecRequest_1.EnvironmentProvisionSpecRequestFromJSON)(json['provisionSpec']),
|
|
45
47
|
'workingDirectory': json['workingDirectory'] == null ? undefined : json['workingDirectory'],
|
|
46
48
|
'hooks': json['hooks'] == null ? undefined : (0, EnvironmentHooksRequest_1.EnvironmentHooksRequestFromJSON)(json['hooks']),
|
|
@@ -59,6 +61,7 @@ function UpdateEnvironmentRequestToJSONTyped(value, ignoreDiscriminator = false)
|
|
|
59
61
|
'platform': (0, EnvironmentPlatformRequest_1.EnvironmentPlatformRequestToJSON)(value['platform']),
|
|
60
62
|
'egressPolicy': (0, EnvironmentEgressPolicy_1.EnvironmentEgressPolicyToJSON)(value['egressPolicy']),
|
|
61
63
|
'ingressPolicy': (0, EnvironmentIngressPolicy_1.EnvironmentIngressPolicyToJSON)(value['ingressPolicy']),
|
|
64
|
+
'credentials': value['credentials'] == null ? undefined : (value['credentials'].map(EnvironmentCredential_1.EnvironmentCredentialToJSON)),
|
|
62
65
|
'provisionSpec': (0, EnvironmentProvisionSpecRequest_1.EnvironmentProvisionSpecRequestToJSON)(value['provisionSpec']),
|
|
63
66
|
'workingDirectory': value['workingDirectory'],
|
|
64
67
|
'hooks': (0, EnvironmentHooksRequest_1.EnvironmentHooksRequestToJSON)(value['hooks']),
|
|
@@ -29,7 +29,7 @@ export interface UpdateSecretRequest {
|
|
|
29
29
|
*/
|
|
30
30
|
description?: string;
|
|
31
31
|
/**
|
|
32
|
-
* Secret value. This is write-only and is never returned by management APIs.
|
|
32
|
+
* Secret value. This is write-only and is never returned by management APIs. For git over HTTPS, store base64 of <user>:<token> as the value, such as the output of printf 'x-access-token:%s' "$TOKEN" | base64 | tr -d '\n' for a GitHub token, and present it as Authorization: Basic ${secret}.
|
|
33
33
|
* @type {string}
|
|
34
34
|
* @memberof UpdateSecretRequest
|
|
35
35
|
*/
|
|
@@ -41,7 +41,7 @@ export interface UpdateSecretRequest {
|
|
|
41
41
|
*/
|
|
42
42
|
expiresAt?: Date;
|
|
43
43
|
/**
|
|
44
|
-
* Injection recipe update: absent = unchanged, null = clear the recipe, value = replace it
|
|
44
|
+
* Injection recipe update: absent = unchanged, null = clear the recipe and its hosts, leaving the secret stored only, value = replace the recipe and its hosts. Optional injection recipe: the request mutations the broker applies from this secret, and the hosts it applies them on. A secret without one is stored only: the broker presents it on no request. For git over HTTPS, store base64 of <user>:<token> as the value, such as the output of printf 'x-access-token:%s' "$TOKEN" | base64 | tr -d '\n' for a GitHub token, and present it as Authorization: Basic ${secret}.
|
|
45
45
|
* @type {InjectionRecipe}
|
|
46
46
|
* @memberof UpdateSecretRequest
|
|
47
47
|
*/
|
|
@@ -55,9 +55,10 @@ export interface UpdateSecretRequest {
|
|
|
55
55
|
[key: string]: string | null;
|
|
56
56
|
};
|
|
57
57
|
/**
|
|
58
|
-
*
|
|
58
|
+
* Deprecated: write injection.hosts instead. Accepted for one release and moved into the recipe's hosts; a request whose recipe names other hosts is refused. Absent leaves the recipe's hosts unchanged; a list replaces them.
|
|
59
59
|
* @type {Array<string>}
|
|
60
60
|
* @memberof UpdateSecretRequest
|
|
61
|
+
* @deprecated
|
|
61
62
|
*/
|
|
62
63
|
hosts?: Array<string>;
|
|
63
64
|
}
|
|
@@ -120,6 +120,7 @@ export * from './EmbeddedResourceResource';
|
|
|
120
120
|
export * from './EntitlementPeriodUsage';
|
|
121
121
|
export * from './EntitlementTeamUsage';
|
|
122
122
|
export * from './Environment';
|
|
123
|
+
export * from './EnvironmentCredential';
|
|
123
124
|
export * from './EnvironmentDisk';
|
|
124
125
|
export * from './EnvironmentDiskMount';
|
|
125
126
|
export * from './EnvironmentEgressPolicy';
|
|
@@ -138,6 +138,7 @@ __exportStar(require("./EmbeddedResourceResource"), exports);
|
|
|
138
138
|
__exportStar(require("./EntitlementPeriodUsage"), exports);
|
|
139
139
|
__exportStar(require("./EntitlementTeamUsage"), exports);
|
|
140
140
|
__exportStar(require("./Environment"), exports);
|
|
141
|
+
__exportStar(require("./EnvironmentCredential"), exports);
|
|
141
142
|
__exportStar(require("./EnvironmentDisk"), exports);
|
|
142
143
|
__exportStar(require("./EnvironmentDiskMount"), exports);
|
|
143
144
|
__exportStar(require("./EnvironmentEgressPolicy"), exports);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@orchestraworks/cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "The Orchestra command line.",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -109,13 +109,13 @@
|
|
|
109
109
|
},
|
|
110
110
|
"dependencies": {
|
|
111
111
|
"@agentclientprotocol/sdk": "1.3.0",
|
|
112
|
-
"@orchestraworks/client": "0.
|
|
113
|
-
"@orchestraworks/worker": "0.0.
|
|
112
|
+
"@orchestraworks/client": "0.6.0",
|
|
113
|
+
"@orchestraworks/worker": "0.0.142",
|
|
114
114
|
"commander": "^14.0.0",
|
|
115
115
|
"liquidjs": "^10.28.0"
|
|
116
116
|
},
|
|
117
117
|
"optionalDependencies": {
|
|
118
|
-
"@orchestraworks/local": "0.0.
|
|
118
|
+
"@orchestraworks/local": "0.0.142"
|
|
119
119
|
},
|
|
120
120
|
"bundleDependencies": [
|
|
121
121
|
"@orchestraworks/client"
|
|
@@ -265,8 +265,8 @@ unless you set one, so it wins over the open default and over the usual allow ru
|
|
|
265
265
|
**Live effect.** The edge reads the environment's rules on each request. So an apply that changes the rules
|
|
266
266
|
reaches every machine at once, machines already running included, from their next request.
|
|
267
267
|
|
|
268
|
-
**How it relates.** On a request a rule allows, the edge adds
|
|
269
|
-
host,
|
|
268
|
+
**How it relates.** On a request a rule allows, the edge adds a secret or connection whose `hosts` cover the
|
|
269
|
+
host, only on `https`, and only when the request names it or an environment default covers it (section 6). Calls to the Orchestra platform itself skip these rules: the agent's
|
|
270
270
|
role decides them (section 1). So a machine blocked from the code host still downloads a file through
|
|
271
271
|
`orchestra files get-content`. The worker points each harness's tools at the edge through proxy variables, so
|
|
272
272
|
a service the agent runs in a container needs its name in `NO_PROXY` in the environment's settings.
|
|
@@ -291,10 +291,19 @@ resolved at the edge on an allow); AGENTS.md "Egress And Credentials". Kit: cli/
|
|
|
291
291
|
**What it's for.** It lets agents use a key without seeing it. No agent, no person and no apply output ever shows
|
|
292
292
|
the value.
|
|
293
293
|
|
|
294
|
-
**What it is.** A *secret* is a stored value that can be written and never read back. It declares
|
|
295
|
-
|
|
296
|
-
to one of those hosts. This is *credential injection at the network edge*.
|
|
297
|
-
|
|
294
|
+
**What it is.** A *secret* is a stored value that can be written and never read back. It declares an
|
|
295
|
+
`injection` recipe, the headers it sets and the `hosts` it sets them on, and the network edge adds it to an
|
|
296
|
+
allowed `https` request to one of those hosts. A secret with no recipe is stored only, and the edge never adds it. This is *credential injection at the network edge*. The edge adds it only in two cases:
|
|
297
|
+
|
|
298
|
+
- The request names it with a reference, `orchestra:secret/<id>` or `orchestra:connection/<id>`, in place
|
|
299
|
+
of its key. A `Secret` or `Connection` set as an environment `env` value is written as that reference:
|
|
300
|
+
`ANTHROPIC_API_KEY` for claude, `GH_TOKEN` for `gh`, `GITLAB_TOKEN` for `glab`, `ORCHESTRA_GIT_CREDENTIAL`
|
|
301
|
+
for git. `routeModelsViaGateway({ key })` names the gateway key this way for claude and codex. The
|
|
302
|
+
`linear`, `slack` and `teams` commands take `--connection-id <id>`.
|
|
303
|
+
- The environment's `credentials` list covers the host, for a request that names nothing. The first
|
|
304
|
+
covering entry serves; with `replace: false`, a request carrying its own value keeps it.
|
|
305
|
+
|
|
306
|
+
A request that names nothing and that no default covers leaves as it was sent.
|
|
298
307
|
|
|
299
308
|
**How it relates.** A secret is added only where a network rule lets the request leave (section 5). Never put
|
|
300
309
|
a key in an environment's settings or in instructions: the machine's processes read every setting.
|
|
@@ -325,8 +334,9 @@ network rules carry the option (sections 2 and 5).
|
|
|
325
334
|
**A Claude or Codex subscription.**
|
|
326
335
|
|
|
327
336
|
- *Claude.* `claude setup-token` prints a long-lived token. It is stored as a secret, and the network edge
|
|
328
|
-
adds it to each call to `api.anthropic.com
|
|
329
|
-
|
|
337
|
+
adds it to each call to `api.anthropic.com` that names it. The environment's `env` names the secret in
|
|
338
|
+
`CLAUDE_CODE_OAUTH_TOKEN` by reference, `orchestra:secret/<id>`, beside an empty API key, so no agent
|
|
339
|
+
and no person sees the real one. Never put the token in an environment's settings: they
|
|
330
340
|
are plain text.
|
|
331
341
|
- *Codex.* A personal access token, made by a ChatGPT Business or Enterprise member, or a separate ChatGPT
|
|
332
342
|
sign-in kept on a `/home` volume that every machine using it shares. A Codex sign-in stays off the model
|
|
@@ -337,7 +347,8 @@ network rules carry the option (sections 2 and 5).
|
|
|
337
347
|
|
|
338
348
|
**An Orchestra account, through the model gateway.** The model gateway is a hosted service at
|
|
339
349
|
`models.orchestraworks.ai`. One endpoint reaches OpenAI, Anthropic and open models. A *gateway key* is a key
|
|
340
|
-
to it, stored as a secret.
|
|
350
|
+
to it, stored as a secret. `routeModelsViaGateway({ key })` names it to each harness, and the network edge
|
|
351
|
+
adds it to each model call, so no agent and no person sees it.
|
|
341
352
|
Without it, an agent's first message fails with "Invalid API key".
|
|
342
353
|
|
|
343
354
|
- *Routing.* `orchestra model-configs` sets which providers serve a model, and in which order, so a call
|
|
@@ -348,10 +359,11 @@ Without it, an agent's first message fails with "Invalid API key".
|
|
|
348
359
|
- *A cap.* Each gateway key can carry a monthly cap, set in the console at **Settings › Gateway keys**.
|
|
349
360
|
|
|
350
361
|
**Their own provider API key.** The team's Anthropic or OpenAI API key is a secret that the network edge adds
|
|
351
|
-
to calls straight to the provider, with no gateway in between.
|
|
362
|
+
to calls straight to the provider, with no gateway in between. The environment names it in `ANTHROPIC_API_KEY`
|
|
363
|
+
or `ORCHESTRA_WORKER_OPENAI_API_KEY`, or lists it in `credentials`.
|
|
352
364
|
|
|
353
365
|
**How it relates.** Each option reaches the model through an ordinary allow rule on the model's host, and a
|
|
354
|
-
secret whose `hosts` name that host (sections 5 and 6). An agent on the model gateway turns it on in its model settings (section 2). An agent on a
|
|
366
|
+
secret whose recipe's `hosts` name that host (sections 5 and 6). An agent on the model gateway turns it on in its model settings (section 2). An agent on a
|
|
355
367
|
subscription or its own key turns it off. For plan questions, send the person to **Settings › Plan & usage**
|
|
356
368
|
in the console.
|
|
357
369
|
|
|
@@ -549,7 +561,8 @@ names its team, and a row with none sits in Shared.
|
|
|
549
561
|
|
|
550
562
|
<!-- Sources, on the kit's own branch: cli/src/cli/main.ts:60-160 (two jobs; nouns match API paths; standard
|
|
551
563
|
verbs; --output json; --body @file.json; approval defaults; orchestra api), cli/src/cli/core/auth.ts:1-45
|
|
552
|
-
(ORCHESTRA_API_TOKEN, then the login profile, then the machine's
|
|
564
|
+
(ORCHESTRA_API_TOKEN, then the file ORCHESTRA_API_TOKEN_FILE names, then the login profile, then the machine's
|
|
565
|
+
edge; ORCHESTRA_BASE_URL),
|
|
553
566
|
cli/src/cli/core/profile.ts:39-52 (profiles in ~/.config/orchestra/config.json), cli/src/generated/cli-commands.json
|
|
554
567
|
(each command's answer), cli/src/cli/core/output.ts:94-113 and :143-145 (json prints the answer as it is),
|
|
555
568
|
cli/src/cli/core/errors.ts:287-296 and :366-370 (the json error, on stderr), cli/src/cli/core/login.ts:361-363 (a
|
|
@@ -581,8 +594,12 @@ each part at length. What follows is only what a reader needs to run a command s
|
|
|
581
594
|
`~/.config/orchestra/config.json`. It selects the person's organization when they have one; with several,
|
|
582
595
|
name it: `orchestra auth login --org <organization>`. The browser sign-in renews itself. A token typed at the
|
|
583
596
|
`--no-browser` prompt cannot renew itself, so it suits a short run only.
|
|
584
|
-
- **Scripts.** `ORCHESTRA_API_TOKEN` and `ORCHESTRA_BASE_URL` in the shell are used before the profile.
|
|
585
|
-
|
|
597
|
+
- **Scripts.** `ORCHESTRA_API_TOKEN` and `ORCHESTRA_BASE_URL` in the shell are used before the profile.
|
|
598
|
+
- **On an Orchestra machine.** The worker writes the agent's own token to a file, renews it, and names the
|
|
599
|
+
file in `ORCHESTRA_API_TOKEN_FILE`. `orchestra` reads that file before each request, so the agent needs no
|
|
600
|
+
sign-in. Where a network edge stands in front of the machine, the edge replaces that token with one for the
|
|
601
|
+
same agent. A 401 here is not fixed by `orchestra auth login`: the token expired before the worker renewed
|
|
602
|
+
it, or the agent is no longer placed on the machine.
|
|
586
603
|
- **Fallback.** `orchestra api <METHOD> </path>` makes a raw call when a typed command is missing.
|
|
587
604
|
|
|
588
605
|
A first look at an organization, in the order a new reader runs it:
|
|
@@ -642,7 +659,7 @@ local/launch/modelkey.go (model key carriers per harness, the gateway address va
|
|
|
642
659
|
worker/facts/families.json (how each harness takes the gateway address); on develop at f62fad1481,
|
|
643
660
|
agents/runtime/assembly/common/placeholder-env (the images' placeholder ANTHROPIC_API_KEY),
|
|
644
661
|
LauncherProperties.kt (the gallery images at Versions/latest), launcher/config/config.go (Dsv5 default);
|
|
645
|
-
worker/facts/families.json (the ORCHESTRA_WORKER_ names), worker/service/
|
|
662
|
+
worker/facts/families.json (the ORCHESTRA_WORKER_ names), worker/service/service.go (OrchestraWorker, and the previous SfdkWorker),
|
|
646
663
|
infra/packer/azure-windows-runtime.pkr.hcl (the startup task), launcher/cloud/cloud.go (the VM tags);
|
|
647
664
|
the proven list is the test run of 2026-10-05. -->
|
|
648
665
|
|
|
@@ -672,8 +689,8 @@ the proven list is the test run of 2026-10-05. -->
|
|
|
672
689
|
1. The environment's `env` (`provisionSpec.env`). A declared value replaces our image's placeholder,
|
|
673
690
|
never a real value. The platform stores `env` values in plain text, an environment read returns
|
|
674
691
|
them, and the machine's startup data carries them.
|
|
675
|
-
2. Baked into the team's image at machine scope: on Windows the `
|
|
676
|
-
registry value, on Linux a drop-in on `
|
|
692
|
+
2. Baked into the team's image at machine scope: on Windows the `OrchestraWorker` service's
|
|
693
|
+
`Environment` registry value, on Linux a drop-in on `orchestra-worker.service`.
|
|
677
694
|
3. The `onStartAgent` hook writes the harness's own key file: `.claude/.credentials.json` for a Claude
|
|
678
695
|
sign-in, `.codex/auth.json` for `codex`, `.pi/agent/auth.json` for `pi`. A raw Claude API key has
|
|
679
696
|
no file.
|
|
@@ -681,6 +698,10 @@ the proven list is the test run of 2026-10-05. -->
|
|
|
681
698
|
`ORCHESTRA_WORKER_CLAUDE_OAUTH_TOKEN` for a Claude subscription token; `ORCHESTRA_WORKER_OPENAI_API_KEY`
|
|
682
699
|
or `ORCHESTRA_WORKER_CODEX_PERSONAL_ACCESS_TOKEN` for `codex`. With a gateway key, keep the agent's
|
|
683
700
|
model gateway on. The platform sets the gateway address.
|
|
701
|
+
- An install replaces the service an earlier release registered as `SfdkWorker` on Windows,
|
|
702
|
+
`sfdk-worker.service` on Linux or `ai.livingcomputers.sfdk.worker` on macOS. The new ones are
|
|
703
|
+
`OrchestraWorker`, `orchestra-worker.service` and `ai.livingcomputers.orchestra.worker`. Change your own
|
|
704
|
+
scripts that name the old ones.
|
|
684
705
|
- Never restart the worker service to load a key. A restart after the worker registered stops the
|
|
685
706
|
machine's work, and the platform parks the VM.
|
|
686
707
|
- The details: the orchestra-fdk skill's `references/environment.md`, "Tokens on a compute provider's
|
|
@@ -68,8 +68,10 @@ const factory = new Factory({ name: "acme-support" });
|
|
|
68
68
|
new Secret(factory, "openai-api-key", {
|
|
69
69
|
name: "OpenAI API key",
|
|
70
70
|
value: SecretValue.fromEnv("OPENAI_API_KEY_VALUE"), // read from env at apply — never in the plan
|
|
71
|
-
|
|
72
|
-
|
|
71
|
+
injection: {
|
|
72
|
+
headers: [{ name: "Authorization", value: "Bearer ${secret}" }], // how the edge presents it
|
|
73
|
+
hosts: ["api.openai.com"], // where
|
|
74
|
+
},
|
|
73
75
|
});
|
|
74
76
|
|
|
75
77
|
const runtime = new Environment(factory, "runtime", {
|
|
@@ -554,26 +556,29 @@ token the platform mints. The **Claude sign-in recipe** is the one to copy when
|
|
|
554
556
|
on a person's Claude subscription token rather than an API key:
|
|
555
557
|
|
|
556
558
|
```ts
|
|
557
|
-
new Secret(factory, "claude-sign-in", {
|
|
559
|
+
const claudeSignIn = new Secret(factory, "claude-sign-in", {
|
|
558
560
|
value: SecretValue.fromEnv("ORCHESTRA_FDK_CLAUDE_CODE_OAUTH_TOKEN"),
|
|
559
|
-
hosts: ["api.anthropic.com"],
|
|
560
561
|
injection: {
|
|
561
562
|
headers: [{ name: "authorization", value: "Bearer ${secret}" }],
|
|
562
563
|
removeHeaders: ["x-api-key"], // stripped before injection
|
|
564
|
+
hosts: ["api.anthropic.com"],
|
|
563
565
|
},
|
|
564
566
|
});
|
|
565
567
|
|
|
566
568
|
// …in the Environment's props:
|
|
567
|
-
env: { CLAUDE_CODE_OAUTH_TOKEN:
|
|
569
|
+
env: { CLAUDE_CODE_OAUTH_TOKEN: claudeSignIn, ANTHROPIC_API_KEY: "" },
|
|
568
570
|
egress: EgressPolicy.allowAll()
|
|
569
571
|
.allow("claude-sign-in", { hosts: ["api.anthropic.com"], priority: 300 }),
|
|
570
572
|
```
|
|
571
573
|
|
|
572
574
|
It injects `authorization` and nothing else. **Never inject an `anthropic-beta` header**: an injected
|
|
573
|
-
one replaces the harness's own list of beta flags, and every call then answers 400.
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
575
|
+
one replaces the harness's own list of beta flags, and every call then answers 400. A Secret as an `env`
|
|
576
|
+
value is written as its reference, `orchestra:secret/<id>`, with the id resolved at apply. In
|
|
577
|
+
`CLAUDE_CODE_OAUTH_TOKEN` it makes the harness sign in the subscription way and send its own list, and the
|
|
578
|
+
edge reads the reference where the token goes and swaps the real token in. The edge adds a credential only
|
|
579
|
+
to a request that names one, or that an environment default covers (`references/environment.md`, "Naming a
|
|
580
|
+
credential"). The empty `ANTHROPIC_API_KEY` covers the runtime image's placeholder key, which the harness
|
|
581
|
+
would otherwise send instead.
|
|
577
582
|
|
|
578
583
|
- Sources: `SecretValue.fromEnv(NAME)`, `SecretValue.fromCommandLine(label?)` and
|
|
579
584
|
`SecretValue.fromGatewayKey(key)`, plus the derived recipes `basicAuth`, `registryCredential` and
|
|
@@ -613,7 +618,7 @@ which the harness would otherwise send instead.
|
|
|
613
618
|
`GatewayKey` you declare in the same factory — `new GatewayKey(factory, "model-gateway-key", props)`,
|
|
614
619
|
whose only props are `slug`, `displayName`, `monthlyCreditCap` and `labels` — so apply mints the
|
|
615
620
|
key and writes the token it shows *exactly once* straight into this Secret, which the edge then
|
|
616
|
-
adds on its `hosts` like any other. It is legal only as the whole top-level value of exactly one Secret:
|
|
621
|
+
adds on its recipe's `hosts` like any other. It is legal only as the whole top-level value of exactly one Secret:
|
|
617
622
|
nesting it inside another recipe, or a key with zero or two Secrets, is a synth error, and there
|
|
618
623
|
is no importer because an existing key's token is unrecoverable. Rotation is new-slug-only.
|
|
619
624
|
- A **`ModelProviderKey`** is the other credential you can declare: your organization's own key for
|
|
@@ -648,11 +653,12 @@ which the harness would otherwise send instead.
|
|
|
648
653
|
suppresses it and none can supply it either, so a headless apply of a `fromCommandLine`
|
|
649
654
|
declaration refuses at *every* level and tells you to run from a terminal or change the source —
|
|
650
655
|
it never recommends a policy lever that could not clear it.
|
|
651
|
-
- Presenting a secret on the network: the `Secret` itself declares `
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
that passes `credential` or `credentials` is a synth error
|
|
655
|
-
nowhere.
|
|
656
|
+
- Presenting a secret on the network: the `Secret` itself declares an `injection` recipe — how: the
|
|
657
|
+
headers it sets, reading `${secret}`, or `${secret.<field>}` for a `SecretValue.fields` value; and
|
|
658
|
+
where: its `hosts`, each an exact host, `*.suffix`, or `*`. Egress rules carry no credential, so a rule
|
|
659
|
+
that passes `credential` or `credentials` is a synth error. A Secret with no `injection` is stored
|
|
660
|
+
only, and one whose recipe has no `hosts` is presented nowhere. The top-level `hosts` prop is
|
|
661
|
+
deprecated: it is moved into the recipe for one release.
|
|
656
662
|
|
|
657
663
|
## How the agents reach a model
|
|
658
664
|
|
|
@@ -668,9 +674,9 @@ on their own computer; run from your shell, its browser step hangs. Never read o
|
|
|
668
674
|
At apply, the shell exports it from that file into the variable the Secret reads. Declare the Claude
|
|
669
675
|
sign-in recipe (§ Secrets are recipes, never values): a `Secret`, an egress rule that allows
|
|
670
676
|
`api.anthropic.com` and sets `Authorization: Bearer ${secret}` with `x-api-key` removed, and, in the
|
|
671
|
-
environment's `env`, `CLAUDE_CODE_OAUTH_TOKEN
|
|
672
|
-
|
|
673
|
-
|
|
677
|
+
environment's `env`, `CLAUDE_CODE_OAUTH_TOKEN` set to that Secret and an empty `ANTHROPIC_API_KEY`.
|
|
678
|
+
Turn `enableModelGateway` off for the agent. The machine holds only the Secret's reference; the edge
|
|
679
|
+
adds the token. Copying the renewing credentials file instead is the fallback,
|
|
674
680
|
and follows the ChatGPT sign-in steps below.
|
|
675
681
|
- **Codex: a personal access token, where the workspace allows one.** A ChatGPT Business or Enterprise
|
|
676
682
|
member creates it at chatgpt.com/admin/access-tokens, once the workspace owner allows access tokens,
|
|
@@ -762,7 +768,7 @@ An environment's `egress` is a policy you build up from one of **two starting po
|
|
|
762
768
|
- **`EgressPolicy.allowAll()`** allows every host no rule refuses.
|
|
763
769
|
|
|
764
770
|
Rules fold onto either one the same way: a rule only opens or closes the network, a credential still goes
|
|
765
|
-
only to the hosts its own `hosts` cover, and a deny still refuses.
|
|
771
|
+
only to the hosts its own recipe's `hosts` cover, and a deny still refuses.
|
|
766
772
|
|
|
767
773
|
Most of what an agent needs to reach arrives ready-made as a **bundle** — a list of rules folded onto
|
|
768
774
|
the policy by one `applyPreset(...)` call — so **reach for the bundles first** and hand-write allow/deny
|
|
@@ -1079,7 +1085,7 @@ orchestra gateway-keys create --slug ci-smoke --output-file key.json
|
|
|
1079
1085
|
export, a CI secret) suppresses the only prompt you would have seen, the command says so in one
|
|
1080
1086
|
line on **stderr**, naming the lever — stdout stays the response document.
|
|
1081
1087
|
- **Writing to a factory-managed resource warns.** `apply` stamps what it manages with an
|
|
1082
|
-
`
|
|
1088
|
+
`orchestra.managedBy` labels key naming the owning factory, and a write to a stamped resource says so:
|
|
1083
1089
|
the next `apply` reverts it. It is a warning, not a refusal — the fallback has to stay usable in an
|
|
1084
1090
|
emergency — and it is the CLI telling you this belongs in `main.ts`.
|
|
1085
1091
|
|
|
@@ -1106,17 +1112,19 @@ itself a credential.
|
|
|
1106
1112
|
An agent running inside a machine types the **same commands** as an operator at a workstation. There
|
|
1107
1113
|
is no separate agent CLI, no agent-only spelling, and nothing for you to author differently:
|
|
1108
1114
|
|
|
1109
|
-
- **The agent
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
`
|
|
1113
|
-
|
|
1115
|
+
- **The agent sets no token.** The worker writes the agent's own short-lived platform token to a file,
|
|
1116
|
+
renews it before it expires, and sets `ORCHESTRA_API_TOKEN_FILE` to that file's path on each agent
|
|
1117
|
+
process. The CLI reads the file before each request and sends its token to the platform's public HTTPS
|
|
1118
|
+
name (`PLATFORM_BASE_URL`), with no organization header, because the token names its organization.
|
|
1119
|
+
The token works only while the agent is placed on that machine. A token set in `ORCHESTRA_API_TOKEN`
|
|
1120
|
+
comes before the file. On a machine behind the platform's network edge, the edge replaces the
|
|
1121
|
+
`Authorization` header of each call with a token for the same agent, whatever token the call carried.
|
|
1114
1122
|
- **IAM is the only difference between principals.** The same command run by an agent and by a human
|
|
1115
1123
|
differs only in what their grants allow; a refusal is a permission error naming the action, never
|
|
1116
1124
|
an instruction to log in (there is nothing in a machine to log into).
|
|
1117
1125
|
- **The factory loop works there too.** `synth`, `diff` and `apply` (and `grant`) are ordinary
|
|
1118
1126
|
platform callers, so an agent can preview and apply a factory from inside its machine with no token
|
|
1119
|
-
and no organization set — the same
|
|
1127
|
+
and no organization set — the same token file, judged by the same IAM.
|
|
1120
1128
|
- **Triggers are runtime wiring: agents observe it, they do not author it.** Declare them in code
|
|
1121
1129
|
(`new Trigger(factory, …)`) or have an explicitly granted principal create them. The managed
|
|
1122
1130
|
worker role deliberately carries **no** trigger-authoring capability, so `triggers create`
|