@rizom/ops 0.2.0-alpha.3 → 0.2.0-alpha.5

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.
@@ -0,0 +1 @@
1
+ export { createOriginCertificateRequest, generateOriginKeyPair, issueCloudflareOriginCertificate, setCloudflareZoneSslStrict, type CloudflareOriginCaResult, type FetchLike, type OriginCertificateRequest, type OriginKeyPair, } from "@brains/utils/origin-ca";
@@ -5,6 +5,7 @@ export interface ParsedArgs {
5
5
  help?: boolean | undefined;
6
6
  version?: boolean | undefined;
7
7
  dryRun?: boolean | undefined;
8
+ pushTo?: string | undefined;
8
9
  };
9
10
  }
10
11
  export declare function parseArgs(argv: string[]): ParsedArgs;
@@ -0,0 +1,9 @@
1
+ import { normalizePushTarget, type PushTarget } from "./push-target";
2
+ import { type RunCommand } from "./run-subprocess";
3
+ export type SecretPair = readonly [name: string, value: string];
4
+ export interface PushSecretsOptions {
5
+ runCommand?: RunCommand | undefined;
6
+ logger?: ((message: string) => void) | undefined;
7
+ }
8
+ export declare function pushSecretsToBackend(target: PushTarget, secrets: readonly SecretPair[], options?: PushSecretsOptions): Promise<void>;
9
+ export { normalizePushTarget };
@@ -0,0 +1,2 @@
1
+ export type PushTarget = "gh";
2
+ export declare function normalizePushTarget(value?: string): PushTarget | undefined;
@@ -1,6 +1,8 @@
1
+ import type { FetchLike } from "@brains/utils/origin-ca";
1
2
  import type { LoadPilotRegistryOptions } from "./load-registry";
2
3
  import type { ParsedArgs } from "./parse-args";
3
- import { type RunCommand as SecretRunCommand } from "./secrets-push";
4
+ import { type RunCommand as OpsRunCommand } from "./run-subprocess";
5
+ import { type SshKeygen } from "./ssh-key-bootstrap";
4
6
  import type { UserRunner } from "./user-runner";
5
7
  export interface CommandResult {
6
8
  success: boolean;
@@ -10,6 +12,9 @@ export interface CommandDependencies extends LoadPilotRegistryOptions {
10
12
  runner?: UserRunner;
11
13
  env?: NodeJS.ProcessEnv | undefined;
12
14
  logger?: ((message: string) => void) | undefined;
13
- secretRunCommand?: SecretRunCommand | undefined;
15
+ fetchImpl?: FetchLike | undefined;
16
+ secretRunCommand?: OpsRunCommand | undefined;
17
+ bootstrapRunCommand?: OpsRunCommand | undefined;
18
+ sshKeygen?: SshKeygen | undefined;
14
19
  }
15
20
  export declare function runCommand(parsed: ParsedArgs, dependencies?: CommandDependencies): Promise<CommandResult>;
@@ -0,0 +1,5 @@
1
+ export type RunCommand = (command: string, args: string[], options?: {
2
+ stdin?: string;
3
+ env?: NodeJS.ProcessEnv;
4
+ }) => Promise<void>;
5
+ export declare const runSubprocess: RunCommand;
package/dist/schema.d.ts CHANGED
@@ -19,7 +19,7 @@ export declare const pilotSchema: z.ZodObject<{
19
19
  githubOrg: string;
20
20
  contentRepoPrefix: string;
21
21
  domainSuffix: string;
22
- preset: "core" | "default" | "pro";
22
+ preset: "default" | "core" | "pro";
23
23
  aiApiKey: string;
24
24
  }, {
25
25
  schemaVersion: 1;
@@ -28,7 +28,7 @@ export declare const pilotSchema: z.ZodObject<{
28
28
  githubOrg: string;
29
29
  contentRepoPrefix: string;
30
30
  domainSuffix: string;
31
- preset: "core" | "default" | "pro";
31
+ preset: "default" | "core" | "pro";
32
32
  aiApiKey: string;
33
33
  }>;
34
34
  export declare const userSchema: z.ZodObject<{
@@ -63,22 +63,22 @@ export declare const cohortSchema: z.ZodEffects<z.ZodObject<{
63
63
  members: string[];
64
64
  aiApiKeyOverride?: string | undefined;
65
65
  brainVersionOverride?: string | undefined;
66
- presetOverride?: "core" | "default" | "pro" | undefined;
66
+ presetOverride?: "default" | "core" | "pro" | undefined;
67
67
  }, {
68
68
  members: string[];
69
69
  aiApiKeyOverride?: string | undefined;
70
70
  brainVersionOverride?: string | undefined;
71
- presetOverride?: "core" | "default" | "pro" | undefined;
71
+ presetOverride?: "default" | "core" | "pro" | undefined;
72
72
  }>, {
73
73
  members: string[];
74
74
  aiApiKeyOverride?: string | undefined;
75
75
  brainVersionOverride?: string | undefined;
76
- presetOverride?: "core" | "default" | "pro" | undefined;
76
+ presetOverride?: "default" | "core" | "pro" | undefined;
77
77
  }, {
78
78
  members: string[];
79
79
  aiApiKeyOverride?: string | undefined;
80
80
  brainVersionOverride?: string | undefined;
81
- presetOverride?: "core" | "default" | "pro" | undefined;
81
+ presetOverride?: "default" | "core" | "pro" | undefined;
82
82
  }>;
83
83
  export type PilotConfig = z.infer<typeof pilotSchema>;
84
84
  export type UserConfig = z.infer<typeof userSchema>;
@@ -1,3 +1,4 @@
1
+ import { type RunCommand } from "./run-subprocess";
1
2
  export interface SecretsPushOptions {
2
3
  env?: NodeJS.ProcessEnv | undefined;
3
4
  logger?: ((message: string) => void) | undefined;
@@ -9,8 +10,4 @@ export interface SecretsPushResult {
9
10
  skippedKeys: string[];
10
11
  dryRun?: boolean | undefined;
11
12
  }
12
- export type RunCommand = (command: string, args: string[], options?: {
13
- stdin?: string;
14
- env?: NodeJS.ProcessEnv;
15
- }) => Promise<void>;
16
13
  export declare function pushPilotSecrets(rootDir: string, handle: string, options?: SecretsPushOptions): Promise<SecretsPushResult>;
@@ -0,0 +1,26 @@
1
+ import { type FetchLike } from "@brains/utils/origin-ca";
2
+ import { type RunCommand } from "./run-subprocess";
3
+ export interface SshKeyBootstrapOptions {
4
+ env?: NodeJS.ProcessEnv | undefined;
5
+ fetchImpl?: FetchLike | undefined;
6
+ logger?: (message: string) => void;
7
+ pushTo?: string | undefined;
8
+ runCommand?: RunCommand | undefined;
9
+ sshKeygen?: SshKeygen | undefined;
10
+ }
11
+ export interface SshKeyBootstrapResult {
12
+ createdHetznerKey: boolean;
13
+ createdLocalKey: boolean;
14
+ privateKeyPath: string;
15
+ publicKeyPath: string;
16
+ sshKeyName: string;
17
+ }
18
+ export interface SshKeygen {
19
+ createEd25519KeyPair: (privateKeyPath: string, comment: string) => void;
20
+ derivePublicKey: (privateKeyPath: string) => string;
21
+ }
22
+ export declare function runPilotSshKeyBootstrap(rootDir: string, options?: SshKeyBootstrapOptions): Promise<{
23
+ success: boolean;
24
+ message?: string;
25
+ }>;
26
+ export declare function bootstrapPilotSshKey(rootDir: string, options?: SshKeyBootstrapOptions): Promise<SshKeyBootstrapResult>;
package/package.json CHANGED
@@ -4,7 +4,7 @@
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
7
- "version": "0.2.0-alpha.3",
7
+ "version": "0.2.0-alpha.5",
8
8
  "type": "module",
9
9
  "exports": {
10
10
  ".": {
@@ -38,6 +38,8 @@ When a push changes only deploy contract files, CI prints `No affected user conf
38
38
  - `brains-ops init <repo>`
39
39
  - `brains-ops render <repo>`
40
40
  - `brains-ops onboard <repo> <handle>`
41
+ - `brains-ops ssh-key:bootstrap <repo>`
42
+ - `brains-ops cert:bootstrap <repo> <handle>`
41
43
  - `brains-ops secrets:push <repo> <handle>`
42
44
  - `brains-ops reconcile-cohort <repo> <cohort>`
43
45
  - `brains-ops reconcile-all <repo>`
@@ -5,7 +5,9 @@
5
5
  3. Add or edit `users/<handle>.yaml`.
6
6
  4. Add the user to a cohort in `cohorts/*.yaml`.
7
7
  5. Run `bunx brains-ops render <repo>`.
8
- 6. Run `bunx brains-ops secrets:push <repo> <handle>`.
9
- 7. Run `bunx brains-ops onboard <repo> <handle>`.
10
- 8. For fleet upgrades, edit `pilot.yaml.brainVersion` and push once; CI rebuilds the shared image tag, refreshes generated user env files, and redeploys affected users.
11
- 9. Hand the MCP connection details to the user.
8
+ 6. Run `bunx brains-ops ssh-key:bootstrap <repo> --push-to gh`.
9
+ 7. Run `bunx brains-ops cert:bootstrap <repo> <handle> --push-to gh`.
10
+ 8. Run `bunx brains-ops secrets:push <repo> <handle>`.
11
+ 9. Run `bunx brains-ops onboard <repo> <handle>`.
12
+ 10. For fleet upgrades, edit `pilot.yaml.brainVersion` and push once; CI rebuilds the shared image tag, refreshes generated user env files, and redeploys affected users.
13
+ 11. Hand the MCP connection details to the user.
@@ -33,6 +33,17 @@ When a push changes only deploy contract files and no generated `users/<handle>/
33
33
 
34
34
  They are scaffolded from `@rizom/ops`, then versioned in this repo like any other deploy contract.
35
35
 
36
+ ## Bootstrap flow
37
+
38
+ For a new pilot user, the operator bootstrap order is:
39
+
40
+ 1. `bunx brains-ops ssh-key:bootstrap <repo> --push-to gh`
41
+ 2. `bunx brains-ops cert:bootstrap <repo> <handle> --push-to gh`
42
+ 3. `bunx brains-ops secrets:push <repo> <handle>`
43
+ 4. `bunx brains-ops onboard <repo> <handle>`
44
+
45
+ `brains-ops cert:bootstrap` writes local cert artifacts under `.brains-ops/`, which stays repo-local and ignored by git.
46
+
36
47
  ## Upgrading operator behavior
37
48
 
38
49
  When `@rizom/ops` changes the scaffolded deploy contract: