@cat-factory/cli 0.3.0 → 0.4.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/args.d.ts CHANGED
@@ -45,5 +45,5 @@ export declare const OPTION_DEFAULTS: {
45
45
  readonly k3sClusterName: 'cat-factory';
46
46
  readonly k3sRuntime: K3sRuntime;
47
47
  };
48
- export declare const HELP_TEXT = "cat-factory \u2014 bootstrap a local cat-factory deployment\n\nUsage:\n cat-factory [init] [options]\n cat-factory k3s [options]\n\nCommands:\n init Scaffold a local-mode backend (local/) + frontend SPA (frontend/): generate the\n crypto secrets, mint a GitHub/GitLab PAT (opens your browser), write gitignored .env.\n k3s Guided local Kubernetes setup: probe the host for a usable cluster and report what's\n found + recommended (provisioning + handler wiring land in a follow-up).\n\nOptions (init):\n -d, --dir <path> Target directory (default: ./<name>)\n --name <name> Project name slug (default: cat-factory)\n --title <title> Frontend app title (default: Agent Architecture Board)\n --provider <p> Source control: github | gitlab (default: github)\n --token <token> PAT value (skips the browser/paste flow)\n --db-url <url> Postgres DATABASE_URL\n --api-base <url> Backend API base for the SPA (default: http://localhost:<port>)\n --port <n> Backend HTTP port (default: 8787; also sets the SPA's api-base)\n --harness-image <ref> Executor-harness image (default: ghcr.io ...:latest)\n --container-runtime <r> Agent container runtime: docker | podman | orbstack | colima | apple\n --no-open Don't open the browser (just print the token URL)\n -y, --yes Non-interactive: use defaults/flags, never prompt\n -f, --force Overwrite existing files\n -h, --help Show this help\n -v, --version Show the CLI version\n\nOptions (k3s):\n --cluster-name <n> Name for a provisioned local cluster (default: cat-factory)\n --runtime <r> Kubernetes distribution: k3d | kind | k3s (default: k3d)\n -y, --yes Non-interactive: pick the recommended path, never prompt\n";
48
+ export declare const HELP_TEXT = "cat-factory \u2014 bootstrap a local cat-factory deployment\n\nUsage:\n cat-factory [init] [options]\n cat-factory k3s [options]\n\nCommands:\n init Scaffold a local-mode backend (local/) + frontend SPA (frontend/): generate the\n crypto secrets, mint a GitHub/GitLab PAT (opens your browser), write gitignored .env.\n k3s Guided local Kubernetes setup: probe the host for a usable cluster, then create (or\n reuse) one + a least-privilege ServiceAccount and print the values to wire the\n Local k3s environment handler. A k3s install needs sudo, so it is only ever printed.\n\nOptions (init):\n -d, --dir <path> Target directory (default: ./<name>)\n --name <name> Project name slug (default: cat-factory)\n --title <title> Frontend app title (default: Agent Architecture Board)\n --provider <p> Source control: github | gitlab (default: github)\n --token <token> PAT value (skips the browser/paste flow)\n --db-url <url> Postgres DATABASE_URL\n --api-base <url> Backend API base for the SPA (default: http://localhost:<port>)\n --port <n> Backend HTTP port (default: 8787; also sets the SPA's api-base)\n --harness-image <ref> Executor-harness image (default: ghcr.io ...:latest)\n --container-runtime <r> Agent container runtime: docker | podman | orbstack | colima | apple\n --no-open Don't open the browser (just print the token URL)\n -y, --yes Non-interactive: use defaults/flags, never prompt\n -f, --force Overwrite existing files\n -h, --help Show this help\n -v, --version Show the CLI version\n\nOptions (k3s):\n --cluster-name <n> Name for a provisioned local cluster (default: cat-factory)\n --runtime <r> Kubernetes distribution: k3d | kind | k3s (default: k3d)\n -y, --yes Non-interactive: pick the recommended path + skip confirms\n";
49
49
  //# sourceMappingURL=args.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"args.d.ts","sourceRoot":"","sources":["../src/args.ts"],"names":[],"mappings":"AAAA,OAAO,EAAsB,KAAK,gBAAgB,EAAyB,MAAM,gBAAgB,CAAA;AACjG,OAAO,EAAiB,KAAK,WAAW,EAAE,MAAM,UAAU,CAAA;AAE1D,0EAA0E;AAC1E,eAAO,MAAM,YAAY,YAAI,KAAK,EAAE,MAAM,EAAE,KAAK,CAAU,CAAA;AAC3D,MAAM,MAAM,UAAU,GAAG,CAAC,OAAO,YAAY,CAAC,CAAC,MAAM,CAAC,CAAA;AAEtD,8FAA8F;AAC9F,MAAM,WAAW,UAAU;IACzB,+FAA+F;IAC/F,OAAO,EAAE,MAAM,GAAG,KAAK,GAAG,MAAM,GAAG,SAAS,CAAA;IAC5C,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,QAAQ,CAAC,EAAE,WAAW,CAAA;IACtB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,4EAA4E;IAC5E,gBAAgB,CAAC,EAAE,gBAAgB,CAAA;IACnC,2DAA2D;IAC3D,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,sEAAsE;IACtE,UAAU,CAAC,EAAE,UAAU,CAAA;IACvB,4EAA4E;IAC5E,MAAM,EAAE,OAAO,CAAA;IACf,+FAA+F;IAC/F,GAAG,EAAE,OAAO,CAAA;IACZ,oDAAoD;IACpD,KAAK,EAAE,OAAO,CAAA;CACf;AAQD,qBAAa,QAAS,SAAQ,KAAK;CAAG;AAEtC,mGAAmG;AACnG,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,UAAU,CAgGpD;AA8BD,qEAAqE;AACrE,eAAO,MAAM,eAAe;aAC1B,WAAW,EAAE,aAAa;aAC1B,QAAQ,EAAE,0BAA0B;aACpC,QAAQ,EAAc,WAAW;aACjC,WAAW,EAAE,8CAA8C;aAI3D,IAAI,EAAE,IAAI;aACV,YAAY;aACZ,gBAAgB,EAAc,gBAAgB;aAE9C,cAAc,EAAE,aAAa;aAC7B,UAAU,EAAW,UAAU;CACvB,CAAA;AAEV,eAAO,MAAM,SAAS,m1DAiCrB,CAAA"}
1
+ {"version":3,"file":"args.d.ts","sourceRoot":"","sources":["../src/args.ts"],"names":[],"mappings":"AAAA,OAAO,EAAsB,KAAK,gBAAgB,EAAyB,MAAM,gBAAgB,CAAA;AACjG,OAAO,EAAiB,KAAK,WAAW,EAAE,MAAM,UAAU,CAAA;AAE1D,0EAA0E;AAC1E,eAAO,MAAM,YAAY,YAAI,KAAK,EAAE,MAAM,EAAE,KAAK,CAAU,CAAA;AAC3D,MAAM,MAAM,UAAU,GAAG,CAAC,OAAO,YAAY,CAAC,CAAC,MAAM,CAAC,CAAA;AAEtD,8FAA8F;AAC9F,MAAM,WAAW,UAAU;IACzB,+FAA+F;IAC/F,OAAO,EAAE,MAAM,GAAG,KAAK,GAAG,MAAM,GAAG,SAAS,CAAA;IAC5C,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,QAAQ,CAAC,EAAE,WAAW,CAAA;IACtB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,4EAA4E;IAC5E,gBAAgB,CAAC,EAAE,gBAAgB,CAAA;IACnC,2DAA2D;IAC3D,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,sEAAsE;IACtE,UAAU,CAAC,EAAE,UAAU,CAAA;IACvB,4EAA4E;IAC5E,MAAM,EAAE,OAAO,CAAA;IACf,+FAA+F;IAC/F,GAAG,EAAE,OAAO,CAAA;IACZ,oDAAoD;IACpD,KAAK,EAAE,OAAO,CAAA;CACf;AAQD,qBAAa,QAAS,SAAQ,KAAK;CAAG;AAEtC,mGAAmG;AACnG,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,UAAU,CAgGpD;AA8BD,qEAAqE;AACrE,eAAO,MAAM,eAAe;aAC1B,WAAW,EAAE,aAAa;aAC1B,QAAQ,EAAE,0BAA0B;aACpC,QAAQ,EAAc,WAAW;aACjC,WAAW,EAAE,8CAA8C;aAI3D,IAAI,EAAE,IAAI;aACV,YAAY;aACZ,gBAAgB,EAAc,gBAAgB;aAE9C,cAAc,EAAE,aAAa;aAC7B,UAAU,EAAW,UAAU;CACvB,CAAA;AAEV,eAAO,MAAM,SAAS,y7DAkCrB,CAAA"}
package/dist/args.js CHANGED
@@ -156,8 +156,9 @@ Usage:
156
156
  Commands:
157
157
  init Scaffold a local-mode backend (local/) + frontend SPA (frontend/): generate the
158
158
  crypto secrets, mint a GitHub/GitLab PAT (opens your browser), write gitignored .env.
159
- k3s Guided local Kubernetes setup: probe the host for a usable cluster and report what's
160
- found + recommended (provisioning + handler wiring land in a follow-up).
159
+ k3s Guided local Kubernetes setup: probe the host for a usable cluster, then create (or
160
+ reuse) one + a least-privilege ServiceAccount and print the values to wire the
161
+ Local k3s environment handler. A k3s install needs sudo, so it is only ever printed.
161
162
 
162
163
  Options (init):
163
164
  -d, --dir <path> Target directory (default: ./<name>)
@@ -179,6 +180,6 @@ Options (init):
179
180
  Options (k3s):
180
181
  --cluster-name <n> Name for a provisioned local cluster (default: cat-factory)
181
182
  --runtime <r> Kubernetes distribution: k3d | kind | k3s (default: k3d)
182
- -y, --yes Non-interactive: pick the recommended path, never prompt
183
+ -y, --yes Non-interactive: pick the recommended path + skip confirms
183
184
  `;
184
185
  //# sourceMappingURL=args.js.map
package/dist/args.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"args.js","sourceRoot":"","sources":["../src/args.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"args.js","sourceRoot":"","sources":["../src/args.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAyB,qBAAqB,EAAE,MAAM,gBAAgB,CAAA;AACjG,OAAO,EAAE,aAAa,EAAoB,MAAM,UAAU,CAAA;AAE1D,0EAA0E;AAC1E,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,CAAU,CAAA;AA8B3D,MAAM,QAAQ,GAAG;IACf,MAAM,EAAE,KAAK;IACb,GAAG,EAAE,KAAK;IACV,KAAK,EAAE,KAAK;CACJ,CAAA;AAEV,MAAM,OAAO,QAAS,SAAQ,KAAK;CAAG;AAEtC,mGAAmG;AACnG,MAAM,UAAU,SAAS,CAAC,IAAc;IACtC,MAAM,IAAI,GAAe,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,QAAQ,EAAE,CAAA;IACzD,IAAI,UAAU,GAAG,KAAK,CAAA;IAEtB,MAAM,SAAS,GAAG,CAAC,IAAY,EAAE,MAA0B,EAAE,IAAc,EAAU,EAAE;QACrF,IAAI,MAAM,KAAK,SAAS;YAAE,OAAO,MAAM,CAAA;QACvC,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,EAAE,CAAA;QACzB,IAAI,IAAI,KAAK,SAAS;YAAE,MAAM,IAAI,QAAQ,CAAC,qBAAqB,IAAI,EAAE,CAAC,CAAA;QACvE,OAAO,IAAI,CAAA;IACb,CAAC,CAAA;IAED,MAAM,KAAK,GAAG,CAAC,GAAG,IAAI,CAAC,CAAA;IACvB,OAAO,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACxB,MAAM,GAAG,GAAG,KAAK,CAAC,KAAK,EAAY,CAAA;QACnC,MAAM,EAAE,GAAG,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAA;QAC3B,MAAM,IAAI,GAAG,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,CAAA;QACvE,MAAM,MAAM,GAAG,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAA;QAEhF,QAAQ,IAAI,EAAE,CAAC;YACb,KAAK,MAAM;gBACT,IAAI,CAAC,UAAU,EAAE,CAAC;oBAChB,IAAI,CAAC,OAAO,GAAG,MAAM,CAAA;oBACrB,UAAU,GAAG,IAAI,CAAA;gBACnB,CAAC;gBACD,MAAK;YACP,KAAK,KAAK;gBACR,IAAI,CAAC,UAAU,EAAE,CAAC;oBAChB,IAAI,CAAC,OAAO,GAAG,KAAK,CAAA;oBACpB,UAAU,GAAG,IAAI,CAAA;gBACnB,CAAC;gBACD,MAAK;YACP,KAAK,MAAM,CAAC;YACZ,KAAK,QAAQ,CAAC;YACd,KAAK,IAAI;gBACP,IAAI,CAAC,OAAO,GAAG,MAAM,CAAA;gBACrB,UAAU,GAAG,IAAI,CAAA;gBACjB,MAAK;YACP,KAAK,SAAS,CAAC;YACf,KAAK,WAAW,CAAC;YACjB,KAAK,IAAI;gBACP,IAAI,CAAC,OAAO,GAAG,SAAS,CAAA;gBACxB,UAAU,GAAG,IAAI,CAAA;gBACjB,MAAK;YACP,KAAK,OAAO,CAAC;YACb,KAAK,IAAI;gBACP,IAAI,CAAC,GAAG,GAAG,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,CAAA;gBACzC,MAAK;YACP,KAAK,QAAQ;gBACX,IAAI,CAAC,WAAW,GAAG,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,CAAA;gBACjD,MAAK;YACP,KAAK,SAAS;gBACZ,IAAI,CAAC,QAAQ,GAAG,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,CAAA;gBAC9C,MAAK;YACP,KAAK,YAAY;gBACf,IAAI,CAAC,QAAQ,GAAG,aAAa,CAAC,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,CAAC,CAAA;gBAC7D,MAAK;YACP,KAAK,SAAS;gBACZ,IAAI,CAAC,KAAK,GAAG,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,CAAA;gBAC3C,MAAK;YACP,KAAK,UAAU;gBACb,IAAI,CAAC,WAAW,GAAG,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,CAAA;gBACjD,MAAK;YACP,KAAK,YAAY;gBACf,IAAI,CAAC,OAAO,GAAG,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,CAAA;gBAC7C,MAAK;YACP,KAAK,QAAQ;gBACX,IAAI,CAAC,IAAI,GAAG,SAAS,CAAC,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,CAAC,CAAA;gBACrD,MAAK;YACP,KAAK,iBAAiB;gBACpB,IAAI,CAAC,YAAY,GAAG,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,CAAA;gBAClD,MAAK;YACP,KAAK,qBAAqB;gBACxB,IAAI,CAAC,gBAAgB,GAAG,qBAAqB,CAAC,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,CAAC,CAAA;gBAC7E,MAAK;YACP,KAAK,gBAAgB;gBACnB,IAAI,CAAC,WAAW,GAAG,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,CAAA;gBACjD,MAAK;YACP,KAAK,WAAW;gBACd,IAAI,CAAC,UAAU,GAAG,eAAe,CAAC,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,CAAC,CAAA;gBACjE,MAAK;YACP,KAAK,WAAW;gBACd,IAAI,CAAC,MAAM,GAAG,IAAI,CAAA;gBAClB,MAAK;YACP,KAAK,OAAO,CAAC;YACb,KAAK,IAAI;gBACP,IAAI,CAAC,GAAG,GAAG,IAAI,CAAA;gBACf,MAAK;YACP,KAAK,SAAS,CAAC;YACf,KAAK,IAAI;gBACP,IAAI,CAAC,KAAK,GAAG,IAAI,CAAA;gBACjB,MAAK;YACP;gBACE,MAAM,IAAI,QAAQ,CAAC,qBAAqB,GAAG,EAAE,CAAC,CAAA;QAClD,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAA;AACb,CAAC;AAED,SAAS,aAAa,CAAC,KAAa;IAClC,MAAM,CAAC,GAAG,KAAK,CAAC,WAAW,EAAE,CAAA;IAC7B,IAAK,aAAmC,CAAC,QAAQ,CAAC,CAAC,CAAC;QAAE,OAAO,CAAgB,CAAA;IAC7E,MAAM,IAAI,QAAQ,CAAC,uBAAuB,KAAK,gBAAgB,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;AAC9F,CAAC;AAED,SAAS,qBAAqB,CAAC,KAAa;IAC1C,MAAM,CAAC,GAAG,KAAK,CAAC,WAAW,EAAE,CAAA;IAC7B,IAAK,kBAAwC,CAAC,QAAQ,CAAC,CAAC,CAAC;QAAE,OAAO,CAAqB,CAAA;IACvF,MAAM,IAAI,QAAQ,CAChB,gCAAgC,KAAK,gBAAgB,kBAAkB,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CACvF,CAAA;AACH,CAAC;AAED,SAAS,eAAe,CAAC,KAAa;IACpC,MAAM,CAAC,GAAG,KAAK,CAAC,WAAW,EAAE,CAAA;IAC7B,IAAK,YAAkC,CAAC,QAAQ,CAAC,CAAC,CAAC;QAAE,OAAO,CAAe,CAAA;IAC3E,MAAM,IAAI,QAAQ,CAAC,sBAAsB,KAAK,gBAAgB,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;AAC5F,CAAC;AAED,SAAS,SAAS,CAAC,KAAa;IAC9B,MAAM,CAAC,GAAG,MAAM,CAAC,KAAK,CAAC,CAAA;IACvB,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,KAAK,EAAE,CAAC;QAC/C,MAAM,IAAI,QAAQ,CAAC,mBAAmB,KAAK,iCAAiC,CAAC,CAAA;IAC/E,CAAC;IACD,OAAO,CAAC,CAAA;AACV,CAAC;AAED,qEAAqE;AACrE,MAAM,CAAC,MAAM,eAAe,GAAG;IAC7B,WAAW,EAAE,aAAa;IAC1B,QAAQ,EAAE,0BAA0B;IACpC,QAAQ,EAAE,QAAuB;IACjC,WAAW,EAAE,8CAA8C;IAC3D,0EAA0E;IAC1E,0FAA0F;IAC1F,gCAAgC;IAChC,IAAI,EAAE,IAAI;IACV,YAAY,EAAE,qBAAqB;IACnC,gBAAgB,EAAE,QAA4B;IAC9C,0BAA0B;IAC1B,cAAc,EAAE,aAAa;IAC7B,UAAU,EAAE,KAAmB;CACvB,CAAA;AAEV,MAAM,CAAC,MAAM,SAAS,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAkCxB,CAAA"}
@@ -31,9 +31,14 @@ export interface HostShell {
31
31
  * rejects: a missing binary resolves to `{ code: COMMAND_NOT_FOUND }` so the probe can treat
32
32
  * "not installed" uniformly, and a command that overruns `timeoutMs` is killed and resolves to
33
33
  * `{ code: COMMAND_TIMED_OUT }`. Output is returned to the caller, never logged here.
34
+ *
35
+ * `opts.input`, when set, is written to the child's stdin and the stream is closed — used to
36
+ * feed a manifest to `kubectl apply -f -` WITHOUT writing it (or the token Secret it creates)
37
+ * to a temp file on disk.
34
38
  */
35
39
  run(cmd: string, args: string[], opts?: {
36
40
  timeoutMs?: number;
41
+ input?: string;
37
42
  }): Promise<ShellResult>;
38
43
  }
39
44
  /** The real, process-backed {@link HostShell}. */
@@ -1 +1 @@
1
- {"version":3,"file":"host-shell.d.ts","sourceRoot":"","sources":["../src/host-shell.ts"],"names":[],"mappings":"AAEA;;;;GAIG;AACH,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,MAAM,CAAA;CACf;AAED,mGAAmG;AACnG,eAAO,MAAM,iBAAiB,MAAM,CAAA;AAEpC,kGAAkG;AAClG,eAAO,MAAM,iBAAiB,MAAM,CAAA;AAEpC;;;;;GAKG;AACH,eAAO,MAAM,0BAA0B,QAAS,CAAA;AAEhD;;;;;GAKG;AACH,MAAM,WAAW,SAAS;IACxB;;;;;OAKG;IACH,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,IAAI,CAAC,EAAE;QAAE,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,WAAW,CAAC,CAAA;CACtF;AAED,kDAAkD;AAClD,wBAAgB,eAAe,IAAI,SAAS,CAkD3C"}
1
+ {"version":3,"file":"host-shell.d.ts","sourceRoot":"","sources":["../src/host-shell.ts"],"names":[],"mappings":"AAEA;;;;GAIG;AACH,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,MAAM,CAAA;CACf;AAED,mGAAmG;AACnG,eAAO,MAAM,iBAAiB,MAAM,CAAA;AAEpC,kGAAkG;AAClG,eAAO,MAAM,iBAAiB,MAAM,CAAA;AAEpC;;;;;GAKG;AACH,eAAO,MAAM,0BAA0B,QAAS,CAAA;AAEhD;;;;;GAKG;AACH,MAAM,WAAW,SAAS;IACxB;;;;;;;;;OASG;IACH,GAAG,CACD,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,MAAM,EAAE,EACd,IAAI,CAAC,EAAE;QAAE,SAAS,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,GAC5C,OAAO,CAAC,WAAW,CAAC,CAAA;CACxB;AAED,kDAAkD;AAClD,wBAAgB,eAAe,IAAI,SAAS,CA2D3C"}
@@ -28,14 +28,22 @@ export function createNodeShell() {
28
28
  clearTimeout(timer);
29
29
  resolve(result);
30
30
  };
31
+ // Feed stdin only when there's input; otherwise leave it closed (`ignore`).
32
+ const stdin = opts?.input !== undefined ? 'pipe' : 'ignore';
31
33
  let child;
32
34
  try {
33
- child = spawn(cmd, args, { stdio: ['ignore', 'pipe', 'pipe'] });
35
+ child = spawn(cmd, args, { stdio: [stdin, 'pipe', 'pipe'] });
34
36
  }
35
37
  catch {
36
38
  finish({ code: COMMAND_NOT_FOUND, stdout: '', stderr: `${cmd}: not found` });
37
39
  return;
38
40
  }
41
+ if (opts?.input !== undefined && child.stdin) {
42
+ // A child that exits before draining stdin raises EPIPE on the write; swallow it so a
43
+ // fast-failing command surfaces as its exit code, not an unhandled stream error.
44
+ child.stdin.on('error', () => { });
45
+ child.stdin.end(opts.input);
46
+ }
39
47
  // Watchdog: kill a child that runs past the deadline (e.g. `kubectl` stuck dialing an
40
48
  // unreachable apiserver) and report it as timed-out rather than blocking the probe forever.
41
49
  timer = setTimeout(() => {
@@ -1 +1 @@
1
- {"version":3,"file":"host-shell.js","sourceRoot":"","sources":["../src/host-shell.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"host-shell.js","sourceRoot":"","sources":["../src/host-shell.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,101 @@
1
+ import { type CliOptions } from './args.js';
2
+ import { type HostShell } from './host-shell.js';
3
+ import { type Io } from './io.js';
4
+ import { type HostState, type OfferId } from './k3s-probe.js';
5
+ /** The namespace + ServiceAccount + long-lived token Secret the guided setup creates. */
6
+ export declare const CAT_FACTORY_NAMESPACE = "cat-factory";
7
+ export declare const SERVICE_ACCOUNT_NAME = "cat-factory";
8
+ export declare const TOKEN_SECRET_NAME = "cat-factory-token";
9
+ /** The apiserver port k3d/kind is asked to publish (the kube default). */
10
+ export declare const DEFAULT_API_PORT = 6443;
11
+ /**
12
+ * Watchdog budget (ms) for `k3d cluster create` / `kind create cluster`. These pull node images on
13
+ * the first run and routinely take 30–90s, so they need far more than the {@link HostShell} default
14
+ * (10s) — otherwise the watchdog SIGKILLs the create mid-flight and the whole create path fails.
15
+ */
16
+ export declare const CLUSTER_CREATE_TIMEOUT_MS = 300000;
17
+ /** A single command to run through the {@link HostShell}, optionally with stdin `input`. */
18
+ export interface Command {
19
+ cmd: string;
20
+ args: string[];
21
+ input?: string;
22
+ /** Per-command watchdog override (ms). Absent ⇒ the {@link HostShell} default applies. */
23
+ timeoutMs?: number;
24
+ }
25
+ /**
26
+ * The resolved local-k3s connection produced by provisioning: the apiserver URL read from the
27
+ * kubeconfig plus the minted ServiceAccount token. Consumed by the hand-off (slice 3 builds the
28
+ * `kubernetes` handler from it). `insecureSkipTlsVerify` is always true — a local k3s/k3d/kind
29
+ * apiserver self-signs its cert.
30
+ */
31
+ export interface ResolvedConnection {
32
+ engine: 'local-k3s';
33
+ /** The provisioned/created cluster name (create paths only; absent for reuse). */
34
+ clusterName?: string;
35
+ apiServerUrl: string;
36
+ apiToken: string;
37
+ insecureSkipTlsVerify: true;
38
+ }
39
+ /** Raised when a provisioning command fails; carries an actionable message (never the token). */
40
+ export declare class ProvisionError extends Error {
41
+ }
42
+ /**
43
+ * The reduced-privilege RBAC the local-k3s environment backend needs, applied via
44
+ * `kubectl apply -f -` (idempotent). It grants the ServiceAccount:
45
+ * - cluster-wide `namespaces` create/delete (the ephemeral-env backend stands up one per PR),
46
+ * - the per-PR resource kinds the backend applies (the manifest allow-list), cluster-wide so
47
+ * they land in whichever per-PR namespace is created,
48
+ * - `pods` + `pods/proxy` (so the SAME token can also back the Kubernetes runner backend).
49
+ * It deliberately does NOT bind `cluster-admin` (see docs/initiatives/local-k3s-guided-setup.md).
50
+ * The cluster-scoped grant is required because per-PR namespaces don't exist yet when the token is
51
+ * minted. A long-lived token Secret is created (k8s >= 1.24 no longer auto-creates one) and read
52
+ * back rather than a short-lived `kubectl create token`.
53
+ *
54
+ * Credential-bearing kinds (`secrets`, `serviceaccounts`) are granted WITHOUT cluster-wide
55
+ * `list`/`watch` — that would let the token enumerate and read every Secret (and thus every other
56
+ * ServiceAccount token) in the cluster, a privilege-escalation path that would make this grant
57
+ * effectively cluster-admin on a single-node cluster. Only single-object create/get/patch/delete
58
+ * (by name) is granted — enough to deploy per-PR app config. (Residual: a `get` on a KNOWN secret
59
+ * name in any namespace is still possible; acceptable for a local dev cluster, and the reason the
60
+ * token must be kept private.)
61
+ */
62
+ export declare const RBAC_MANIFEST = "apiVersion: v1\nkind: Namespace\nmetadata:\n name: cat-factory\n---\napiVersion: v1\nkind: ServiceAccount\nmetadata:\n name: cat-factory\n namespace: cat-factory\n---\napiVersion: rbac.authorization.k8s.io/v1\nkind: ClusterRole\nmetadata:\n name: cat-factory-env\nrules:\n - apiGroups: ['']\n resources: ['namespaces']\n verbs: ['create', 'get', 'list', 'watch', 'delete']\n - apiGroups: ['']\n resources: ['services', 'configmaps', 'persistentvolumeclaims', 'pods']\n verbs: ['create', 'get', 'list', 'watch', 'patch', 'update', 'delete']\n - apiGroups: ['']\n resources: ['secrets', 'serviceaccounts']\n verbs: ['create', 'get', 'patch', 'update', 'delete']\n - apiGroups: ['']\n resources: ['pods/proxy']\n verbs: ['create', 'get']\n - apiGroups: ['apps']\n resources: ['deployments', 'statefulsets', 'replicasets']\n verbs: ['create', 'get', 'list', 'watch', 'patch', 'update', 'delete']\n - apiGroups: ['batch']\n resources: ['jobs']\n verbs: ['create', 'get', 'list', 'watch', 'patch', 'update', 'delete']\n - apiGroups: ['networking.k8s.io']\n resources: ['ingresses']\n verbs: ['create', 'get', 'list', 'watch', 'patch', 'update', 'delete']\n - apiGroups: ['gateway.networking.k8s.io']\n resources: ['gateways', 'httproutes']\n verbs: ['create', 'get', 'list', 'watch', 'patch', 'update', 'delete']\n---\napiVersion: rbac.authorization.k8s.io/v1\nkind: ClusterRoleBinding\nmetadata:\n name: cat-factory-env\nroleRef:\n apiGroup: rbac.authorization.k8s.io\n kind: ClusterRole\n name: cat-factory-env\nsubjects:\n - kind: ServiceAccount\n name: cat-factory\n namespace: cat-factory\n---\napiVersion: v1\nkind: Secret\nmetadata:\n name: cat-factory-token\n namespace: cat-factory\n annotations:\n kubernetes.io/service-account.name: cat-factory\ntype: kubernetes.io/service-account-token\n";
63
+ /** `k3d cluster create <name> --api-port <port>` — publishes the apiserver on the host port. */
64
+ export declare function k3dCreateCommand(name: string, apiPort?: number): Command;
65
+ /** `kind create cluster --name <name>`. */
66
+ export declare function kindCreateCommand(name: string): Command;
67
+ /** The kubeconfig context name k3d/kind assigns to a cluster it creates. */
68
+ export declare function contextName(runtime: 'k3d' | 'kind', name: string): string;
69
+ /** `kubectl apply -f -` with the RBAC manifest on stdin (idempotent), targeting `context`. */
70
+ export declare function applyRbacCommand(context?: string): Command;
71
+ /** Read the base64 token out of the SA token Secret via jsonpath, targeting `context`. */
72
+ export declare function readTokenCommand(context?: string): Command;
73
+ /** Read the target context's apiserver URL from the kubeconfig. */
74
+ export declare function readApiServerCommand(context?: string): Command;
75
+ /** Decode the base64 token the Secret exposes; empty until the token controller populates it. */
76
+ export declare function decodeToken(base64: string): string;
77
+ /** Normalize the wildcard bind address k3d writes for the apiserver to a dialable loopback host. */
78
+ export declare function normalizeApiServerUrl(url: string): string;
79
+ /**
80
+ * Whether the (context, apiserver URL) pair looks like a LOCAL cluster. Used to refuse silently
81
+ * mutating a remote/production cluster in `--yes` mode: the `use-existing` offer fires for ANY
82
+ * reachable kubeconfig, which may point at a shared cluster. A local-looking context name OR a
83
+ * loopback/Docker-host apiserver is treated as local.
84
+ */
85
+ export declare function looksLocalCluster(context: string | undefined, apiServerUrl: string): boolean;
86
+ /** Injectable dependencies for the provisioner (mirrors the k3s-command deps). */
87
+ export interface ProvisionDeps {
88
+ shell: HostShell;
89
+ io: Io;
90
+ /** Delay between token-Secret read attempts (real setTimeout; a no-op in tests). */
91
+ sleep?: (ms: number) => Promise<void>;
92
+ }
93
+ /**
94
+ * Provision (or reuse) a local cluster for the chosen offer, create the least-privilege
95
+ * ServiceAccount + RBAC, mint a long-lived token, and read the apiserver URL — returning the
96
+ * resolved `local-k3s` connection. Every MUTATING step (cluster create, RBAC apply) is behind an
97
+ * explicit confirm unless `--yes`. Idempotent: an existing cluster/SA is reused, not duplicated
98
+ * (`kubectl apply` and `k3d/kind` reuse). `install-k3s` is NOT handled here — it is guidance-only.
99
+ */
100
+ export declare function provisionCluster(chosen: Exclude<OfferId, 'install-k3s'>, state: HostState, options: CliOptions, deps: ProvisionDeps): Promise<ResolvedConnection>;
101
+ //# sourceMappingURL=k3s-provision.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"k3s-provision.d.ts","sourceRoot":"","sources":["../src/k3s-provision.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,UAAU,EAAmB,MAAM,WAAW,CAAA;AAC5D,OAAO,EAAE,KAAK,SAAS,EAAoB,MAAM,iBAAiB,CAAA;AAClE,OAAO,EAAE,KAAK,EAAE,EAAE,MAAM,SAAS,CAAA;AACjC,OAAO,EAAE,KAAK,SAAS,EAAE,KAAK,OAAO,EAAE,MAAM,gBAAgB,CAAA;AAE7D,yFAAyF;AACzF,eAAO,MAAM,qBAAqB,gBAAgB,CAAA;AAClD,eAAO,MAAM,oBAAoB,gBAAgB,CAAA;AACjD,eAAO,MAAM,iBAAiB,sBAAsB,CAAA;AACpD,0EAA0E;AAC1E,eAAO,MAAM,gBAAgB,OAAO,CAAA;AAEpC;;;;GAIG;AACH,eAAO,MAAM,yBAAyB,SAAU,CAAA;AAEhD,4FAA4F;AAC5F,MAAM,WAAW,OAAO;IACtB,GAAG,EAAE,MAAM,CAAA;IACX,IAAI,EAAE,MAAM,EAAE,CAAA;IACd,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,0FAA0F;IAC1F,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED;;;;;GAKG;AACH,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,WAAW,CAAA;IACnB,kFAAkF;IAClF,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,YAAY,EAAE,MAAM,CAAA;IACpB,QAAQ,EAAE,MAAM,CAAA;IAChB,qBAAqB,EAAE,IAAI,CAAA;CAC5B;AAED,iGAAiG;AACjG,qBAAa,cAAe,SAAQ,KAAK;CAAG;AAE5C;;;;;;;;;;;;;;;;;;;GAmBG;AACH,eAAO,MAAM,aAAa,o1DA8DzB,CAAA;AAMD,gGAAgG;AAChG,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,MAAyB,GAAG,OAAO,CAM1F;AAED,2CAA2C;AAC3C,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAMvD;AAED,4EAA4E;AAC5E,wBAAgB,WAAW,CAAC,OAAO,EAAE,KAAK,GAAG,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAEzE;AAYD,8FAA8F;AAC9F,wBAAgB,gBAAgB,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAE1D;AAED,0FAA0F;AAC1F,wBAAgB,gBAAgB,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAgB1D;AAED,mEAAmE;AACnE,wBAAgB,oBAAoB,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAQ9D;AAED,iGAAiG;AACjG,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAElD;AAeD,oGAAoG;AACpG,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAEzD;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,EAAE,YAAY,EAAE,MAAM,GAAG,OAAO,CAY5F;AAMD,kFAAkF;AAClF,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,SAAS,CAAA;IAChB,EAAE,EAAE,EAAE,CAAA;IACN,oFAAoF;IACpF,KAAK,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;CACtC;AA4DD;;;;;;GAMG;AACH,wBAAsB,gBAAgB,CACpC,MAAM,EAAE,OAAO,CAAC,OAAO,EAAE,aAAa,CAAC,EACvC,KAAK,EAAE,SAAS,EAChB,OAAO,EAAE,UAAU,EACnB,IAAI,EAAE,aAAa,GAClB,OAAO,CAAC,kBAAkB,CAAC,CA0E7B"}
@@ -0,0 +1,315 @@
1
+ import { OPTION_DEFAULTS } from './args.js';
2
+ import {} from './host-shell.js';
3
+ import {} from './io.js';
4
+ import {} from './k3s-probe.js';
5
+ /** The namespace + ServiceAccount + long-lived token Secret the guided setup creates. */
6
+ export const CAT_FACTORY_NAMESPACE = 'cat-factory';
7
+ export const SERVICE_ACCOUNT_NAME = 'cat-factory';
8
+ export const TOKEN_SECRET_NAME = 'cat-factory-token';
9
+ /** The apiserver port k3d/kind is asked to publish (the kube default). */
10
+ export const DEFAULT_API_PORT = 6443;
11
+ /**
12
+ * Watchdog budget (ms) for `k3d cluster create` / `kind create cluster`. These pull node images on
13
+ * the first run and routinely take 30–90s, so they need far more than the {@link HostShell} default
14
+ * (10s) — otherwise the watchdog SIGKILLs the create mid-flight and the whole create path fails.
15
+ */
16
+ export const CLUSTER_CREATE_TIMEOUT_MS = 300_000;
17
+ /** Raised when a provisioning command fails; carries an actionable message (never the token). */
18
+ export class ProvisionError extends Error {
19
+ }
20
+ /**
21
+ * The reduced-privilege RBAC the local-k3s environment backend needs, applied via
22
+ * `kubectl apply -f -` (idempotent). It grants the ServiceAccount:
23
+ * - cluster-wide `namespaces` create/delete (the ephemeral-env backend stands up one per PR),
24
+ * - the per-PR resource kinds the backend applies (the manifest allow-list), cluster-wide so
25
+ * they land in whichever per-PR namespace is created,
26
+ * - `pods` + `pods/proxy` (so the SAME token can also back the Kubernetes runner backend).
27
+ * It deliberately does NOT bind `cluster-admin` (see docs/initiatives/local-k3s-guided-setup.md).
28
+ * The cluster-scoped grant is required because per-PR namespaces don't exist yet when the token is
29
+ * minted. A long-lived token Secret is created (k8s >= 1.24 no longer auto-creates one) and read
30
+ * back rather than a short-lived `kubectl create token`.
31
+ *
32
+ * Credential-bearing kinds (`secrets`, `serviceaccounts`) are granted WITHOUT cluster-wide
33
+ * `list`/`watch` — that would let the token enumerate and read every Secret (and thus every other
34
+ * ServiceAccount token) in the cluster, a privilege-escalation path that would make this grant
35
+ * effectively cluster-admin on a single-node cluster. Only single-object create/get/patch/delete
36
+ * (by name) is granted — enough to deploy per-PR app config. (Residual: a `get` on a KNOWN secret
37
+ * name in any namespace is still possible; acceptable for a local dev cluster, and the reason the
38
+ * token must be kept private.)
39
+ */
40
+ export const RBAC_MANIFEST = `apiVersion: v1
41
+ kind: Namespace
42
+ metadata:
43
+ name: ${CAT_FACTORY_NAMESPACE}
44
+ ---
45
+ apiVersion: v1
46
+ kind: ServiceAccount
47
+ metadata:
48
+ name: ${SERVICE_ACCOUNT_NAME}
49
+ namespace: ${CAT_FACTORY_NAMESPACE}
50
+ ---
51
+ apiVersion: rbac.authorization.k8s.io/v1
52
+ kind: ClusterRole
53
+ metadata:
54
+ name: cat-factory-env
55
+ rules:
56
+ - apiGroups: ['']
57
+ resources: ['namespaces']
58
+ verbs: ['create', 'get', 'list', 'watch', 'delete']
59
+ - apiGroups: ['']
60
+ resources: ['services', 'configmaps', 'persistentvolumeclaims', 'pods']
61
+ verbs: ['create', 'get', 'list', 'watch', 'patch', 'update', 'delete']
62
+ - apiGroups: ['']
63
+ resources: ['secrets', 'serviceaccounts']
64
+ verbs: ['create', 'get', 'patch', 'update', 'delete']
65
+ - apiGroups: ['']
66
+ resources: ['pods/proxy']
67
+ verbs: ['create', 'get']
68
+ - apiGroups: ['apps']
69
+ resources: ['deployments', 'statefulsets', 'replicasets']
70
+ verbs: ['create', 'get', 'list', 'watch', 'patch', 'update', 'delete']
71
+ - apiGroups: ['batch']
72
+ resources: ['jobs']
73
+ verbs: ['create', 'get', 'list', 'watch', 'patch', 'update', 'delete']
74
+ - apiGroups: ['networking.k8s.io']
75
+ resources: ['ingresses']
76
+ verbs: ['create', 'get', 'list', 'watch', 'patch', 'update', 'delete']
77
+ - apiGroups: ['gateway.networking.k8s.io']
78
+ resources: ['gateways', 'httproutes']
79
+ verbs: ['create', 'get', 'list', 'watch', 'patch', 'update', 'delete']
80
+ ---
81
+ apiVersion: rbac.authorization.k8s.io/v1
82
+ kind: ClusterRoleBinding
83
+ metadata:
84
+ name: cat-factory-env
85
+ roleRef:
86
+ apiGroup: rbac.authorization.k8s.io
87
+ kind: ClusterRole
88
+ name: cat-factory-env
89
+ subjects:
90
+ - kind: ServiceAccount
91
+ name: ${SERVICE_ACCOUNT_NAME}
92
+ namespace: ${CAT_FACTORY_NAMESPACE}
93
+ ---
94
+ apiVersion: v1
95
+ kind: Secret
96
+ metadata:
97
+ name: ${TOKEN_SECRET_NAME}
98
+ namespace: ${CAT_FACTORY_NAMESPACE}
99
+ annotations:
100
+ kubernetes.io/service-account.name: ${SERVICE_ACCOUNT_NAME}
101
+ type: kubernetes.io/service-account-token
102
+ `;
103
+ // ---------------------------------------------------------------------------
104
+ // Pure command planners — no shell-out, so they are unit-testable in isolation.
105
+ // ---------------------------------------------------------------------------
106
+ /** `k3d cluster create <name> --api-port <port>` — publishes the apiserver on the host port. */
107
+ export function k3dCreateCommand(name, apiPort = DEFAULT_API_PORT) {
108
+ return {
109
+ cmd: 'k3d',
110
+ args: ['cluster', 'create', name, '--api-port', String(apiPort)],
111
+ timeoutMs: CLUSTER_CREATE_TIMEOUT_MS,
112
+ };
113
+ }
114
+ /** `kind create cluster --name <name>`. */
115
+ export function kindCreateCommand(name) {
116
+ return {
117
+ cmd: 'kind',
118
+ args: ['create', 'cluster', '--name', name],
119
+ timeoutMs: CLUSTER_CREATE_TIMEOUT_MS,
120
+ };
121
+ }
122
+ /** The kubeconfig context name k3d/kind assigns to a cluster it creates. */
123
+ export function contextName(runtime, name) {
124
+ return `${runtime}-${name}`;
125
+ }
126
+ /**
127
+ * Append an explicit `--context <ctx>` when one is supplied, so a command targets a SPECIFIC
128
+ * kubeconfig context instead of mutating (and leaving mutated) the global current-context. Absent
129
+ * ⇒ the command operates on whatever context is already current (used for the reuse path, where
130
+ * the current context IS the target).
131
+ */
132
+ function withContext(args, context) {
133
+ return context ? [...args, '--context', context] : args;
134
+ }
135
+ /** `kubectl apply -f -` with the RBAC manifest on stdin (idempotent), targeting `context`. */
136
+ export function applyRbacCommand(context) {
137
+ return { cmd: 'kubectl', args: withContext(['apply', '-f', '-'], context), input: RBAC_MANIFEST };
138
+ }
139
+ /** Read the base64 token out of the SA token Secret via jsonpath, targeting `context`. */
140
+ export function readTokenCommand(context) {
141
+ return {
142
+ cmd: 'kubectl',
143
+ args: withContext([
144
+ '-n',
145
+ CAT_FACTORY_NAMESPACE,
146
+ 'get',
147
+ 'secret',
148
+ TOKEN_SECRET_NAME,
149
+ '-o',
150
+ 'jsonpath={.data.token}',
151
+ ], context),
152
+ };
153
+ }
154
+ /** Read the target context's apiserver URL from the kubeconfig. */
155
+ export function readApiServerCommand(context) {
156
+ return {
157
+ cmd: 'kubectl',
158
+ args: withContext(['config', 'view', '--minify', '-o', 'jsonpath={.clusters[0].cluster.server}'], context),
159
+ };
160
+ }
161
+ /** Decode the base64 token the Secret exposes; empty until the token controller populates it. */
162
+ export function decodeToken(base64) {
163
+ return Buffer.from(base64.trim(), 'base64').toString('utf8').trim();
164
+ }
165
+ /** kubeconfig context names that unambiguously denote a LOCAL cluster. */
166
+ const LOCAL_CONTEXT_PREFIXES = ['k3d-', 'kind-'];
167
+ const LOCAL_CONTEXT_NAMES = ['minikube', 'docker-desktop', 'orbstack', 'colima', 'rancher-desktop'];
168
+ /** Hostnames that denote a LOCAL apiserver (loopback / the Docker host alias). */
169
+ const LOCAL_API_HOSTS = [
170
+ 'localhost',
171
+ '127.0.0.1',
172
+ '0.0.0.0',
173
+ '::1',
174
+ '[::1]',
175
+ 'host.docker.internal',
176
+ ];
177
+ /** Normalize the wildcard bind address k3d writes for the apiserver to a dialable loopback host. */
178
+ export function normalizeApiServerUrl(url) {
179
+ return url.replace('//0.0.0.0:', '//127.0.0.1:');
180
+ }
181
+ /**
182
+ * Whether the (context, apiserver URL) pair looks like a LOCAL cluster. Used to refuse silently
183
+ * mutating a remote/production cluster in `--yes` mode: the `use-existing` offer fires for ANY
184
+ * reachable kubeconfig, which may point at a shared cluster. A local-looking context name OR a
185
+ * loopback/Docker-host apiserver is treated as local.
186
+ */
187
+ export function looksLocalCluster(context, apiServerUrl) {
188
+ const ctx = (context ?? '').toLowerCase();
189
+ if (LOCAL_CONTEXT_PREFIXES.some((p) => ctx.startsWith(p)))
190
+ return true;
191
+ if (LOCAL_CONTEXT_NAMES.includes(ctx))
192
+ return true;
193
+ let host = '';
194
+ try {
195
+ host = new URL(apiServerUrl).hostname.toLowerCase();
196
+ }
197
+ catch {
198
+ host = '';
199
+ }
200
+ if (LOCAL_API_HOSTS.includes(host))
201
+ return true;
202
+ return host.endsWith('.local') || host.endsWith('.localhost') || host.endsWith('.nip.io');
203
+ }
204
+ const realSleep = (ms) => new Promise((r) => setTimeout(r, ms));
205
+ /** Run a command, throwing a {@link ProvisionError} with the captured stderr on a non-zero exit. */
206
+ async function runOrThrow(shell, command, what, hint) {
207
+ const result = await shell.run(command.cmd, command.args, {
208
+ input: command.input,
209
+ timeoutMs: command.timeoutMs,
210
+ });
211
+ if (result.code !== 0) {
212
+ const detail = (result.stderr || result.stdout).trim();
213
+ const base = detail || `${command.cmd} exited ${result.code}`;
214
+ throw new ProvisionError(`${what} failed: ${base}${hint ? hint(base) : ''}`);
215
+ }
216
+ return result;
217
+ }
218
+ /** An extra hint appended to a create failure that looks like an apiserver-port collision. */
219
+ function portCollisionHint(detail) {
220
+ return /already (allocated|in use)|address already in use|port is already/i.test(detail)
221
+ ? ` (the apiserver port ${DEFAULT_API_PORT} may already be in use — free it, or remove the conflicting cluster, then re-run)`
222
+ : '';
223
+ }
224
+ /** Ask to run a mutating step; `--yes` proceeds without prompting. Declining throws. */
225
+ async function confirmStep(io, options, prompt) {
226
+ if (options.yes)
227
+ return;
228
+ const ok = await io.confirm(prompt, true);
229
+ if (!ok)
230
+ throw new ProvisionError('Cancelled — nothing further was changed on your host.');
231
+ }
232
+ /**
233
+ * Read the ServiceAccount token from its Secret, retrying while the token controller populates it.
234
+ * A freshly-applied `kubernetes.io/service-account-token` Secret has an empty `.data.token` for a
235
+ * moment; poll until it's non-empty (or give up with an actionable error).
236
+ */
237
+ async function readSaToken(deps, context) {
238
+ const sleep = deps.sleep ?? realSleep;
239
+ const attempts = 20;
240
+ for (let i = 0; i < attempts; i++) {
241
+ const result = await runOrThrow(deps.shell, readTokenCommand(context), 'Reading the ServiceAccount token');
242
+ const token = decodeToken(result.stdout);
243
+ if (token.length > 0)
244
+ return token;
245
+ if (i < attempts - 1)
246
+ await sleep(500);
247
+ }
248
+ throw new ProvisionError(`The ServiceAccount token Secret "${TOKEN_SECRET_NAME}" never populated. Re-run \`cat-factory k3s\` once the cluster is settled.`);
249
+ }
250
+ /**
251
+ * Provision (or reuse) a local cluster for the chosen offer, create the least-privilege
252
+ * ServiceAccount + RBAC, mint a long-lived token, and read the apiserver URL — returning the
253
+ * resolved `local-k3s` connection. Every MUTATING step (cluster create, RBAC apply) is behind an
254
+ * explicit confirm unless `--yes`. Idempotent: an existing cluster/SA is reused, not duplicated
255
+ * (`kubectl apply` and `k3d/kind` reuse). `install-k3s` is NOT handled here — it is guidance-only.
256
+ */
257
+ export async function provisionCluster(chosen, state, options, deps) {
258
+ const { io, shell } = deps;
259
+ // The kubeconfig context every subsequent command targets. Create paths get an explicit
260
+ // `--context` (so we never mutate the user's global current-context); reuse operates on the
261
+ // already-current context (`undefined`).
262
+ let targetContext;
263
+ let createdName;
264
+ if (chosen === 'create-k3d' || chosen === 'create-kind') {
265
+ const clusterName = options.clusterName ?? OPTION_DEFAULTS.k3sClusterName;
266
+ const runtime = chosen === 'create-kind' ? 'kind' : 'k3d';
267
+ const existing = runtime === 'kind' ? state.detections.kindClusters : state.detections.k3dClusters;
268
+ if (existing.includes(clusterName)) {
269
+ io.info(`Reusing the existing ${runtime} cluster "${clusterName}".`);
270
+ }
271
+ else {
272
+ await confirmStep(io, options, `Create a local ${runtime} cluster "${clusterName}"?`);
273
+ io.info(`Creating the ${runtime} cluster "${clusterName}" (this can take a minute)…`);
274
+ const create = runtime === 'kind' ? kindCreateCommand(clusterName) : k3dCreateCommand(clusterName);
275
+ await runOrThrow(shell, create, `Creating the ${runtime} cluster`, portCollisionHint);
276
+ }
277
+ targetContext = contextName(runtime, clusterName);
278
+ createdName = clusterName;
279
+ }
280
+ else {
281
+ // use-existing: operate on the current context (its name is what the probe detected).
282
+ targetContext = undefined;
283
+ }
284
+ // Read the apiserver URL first (a read-only op): it names the target in the confirm below and
285
+ // gates the reuse path against accidentally mutating a non-local cluster.
286
+ const apiServer = await runOrThrow(shell, readApiServerCommand(targetContext), 'Reading the apiserver URL');
287
+ const apiServerUrl = normalizeApiServerUrl(apiServer.stdout.trim());
288
+ if (apiServerUrl.length === 0) {
289
+ throw new ProvisionError('Could not read the apiserver URL from your kubeconfig.');
290
+ }
291
+ const contextLabel = state.detections.clusterContext;
292
+ const targetDescription = createdName
293
+ ? `the ${chosen === 'create-kind' ? 'kind' : 'k3d'} cluster "${createdName}" (${apiServerUrl})`
294
+ : contextLabel
295
+ ? `context "${contextLabel}" (${apiServerUrl})`
296
+ : `the current cluster (${apiServerUrl})`;
297
+ // Refuse to silently mutate a cluster that doesn't look local when running non-interactively —
298
+ // `use-existing` fires for ANY reachable kubeconfig, which could be a shared/remote cluster.
299
+ if (chosen === 'use-existing' && options.yes && !looksLocalCluster(contextLabel, apiServerUrl)) {
300
+ throw new ProvisionError(`Refusing to auto-provision in --yes mode: ${targetDescription} does not look like a local cluster. Re-run without --yes to confirm explicitly, or point kubeconfig at a local k3d/kind/k3s cluster.`);
301
+ }
302
+ await confirmStep(io, options, `Apply the cat-factory ServiceAccount + RBAC to ${targetDescription}?`);
303
+ io.info('Applying the ServiceAccount + RBAC…');
304
+ await runOrThrow(shell, applyRbacCommand(targetContext), 'Applying the RBAC manifest');
305
+ io.info('Minting the ServiceAccount token…');
306
+ const apiToken = await readSaToken(deps, targetContext);
307
+ return {
308
+ engine: 'local-k3s',
309
+ clusterName: createdName,
310
+ apiServerUrl,
311
+ apiToken,
312
+ insecureSkipTlsVerify: true,
313
+ };
314
+ }
315
+ //# sourceMappingURL=k3s-provision.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"k3s-provision.js","sourceRoot":"","sources":["../src/k3s-provision.ts"],"names":[],"mappings":"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"}
package/dist/k3s.d.ts CHANGED
@@ -2,6 +2,7 @@ import { type CliOptions } from './args.js';
2
2
  import { type HostShell } from './host-shell.js';
3
3
  import { type Io } from './io.js';
4
4
  import { type HostState, type OfferId } from './k3s-probe.js';
5
+ import { type ResolvedConnection } from './k3s-provision.js';
5
6
  /** The k3s command's injectable dependencies (defaults to the real console IO + host shell). */
6
7
  export interface K3sDeps {
7
8
  io?: Io;
@@ -11,15 +12,19 @@ export interface K3sDeps {
11
12
  export interface K3sResult {
12
13
  state: HostState;
13
14
  chosen: OfferId;
15
+ /** The resolved connection when a provisioning path ran + succeeded (not for `install-k3s`). */
16
+ connection?: ResolvedConnection;
14
17
  }
15
18
  /** The one-liner k3s install command (needs sudo — printed, never run for the user). */
16
19
  export declare const K3S_INSTALL_COMMAND = "curl -sfL https://get.k3s.io | sh -";
17
20
  /**
18
- * `cat-factory k3s` — guided local-cluster setup (slice 1: probe + report + offer).
21
+ * `cat-factory k3s` — guided local-cluster setup: probe offer provision → hand-off.
19
22
  *
20
- * Probes the host over the {@link HostShell} seam, reports what was found, and lets the user pick
21
- * a setup path. Provisioning + handler wiring land in later slices; this slice stops at the choice
22
- * and prints the appropriate guidance. `@clack/prompts` is reached only through {@link Io}.
23
+ * Probes the host over the {@link HostShell} seam, reports what was found, lets the user pick a
24
+ * setup path, then (for the k3d/kind/existing-cluster paths) provisions the cluster + a
25
+ * least-privilege ServiceAccount and prints the resolved connection values to wire into the
26
+ * Settings → Infrastructure → Local k3s form. `install-k3s` needs sudo, so it is guidance-only
27
+ * (the command is printed, never run). `@clack/prompts` is reached only through {@link Io}.
23
28
  */
24
29
  export declare function setupK3s(options: CliOptions, deps?: K3sDeps): Promise<K3sResult>;
25
30
  //# sourceMappingURL=k3s.d.ts.map
package/dist/k3s.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"k3s.d.ts","sourceRoot":"","sources":["../src/k3s.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,UAAU,EAAmB,MAAM,WAAW,CAAA;AAC5D,OAAO,EAAmB,KAAK,SAAS,EAAE,MAAM,iBAAiB,CAAA;AACjE,OAAO,EAAmB,KAAK,EAAE,EAAE,MAAM,SAAS,CAAA;AAClD,OAAO,EAAE,KAAK,SAAS,EAAc,KAAK,OAAO,EAAa,MAAM,gBAAgB,CAAA;AAEpF,gGAAgG;AAChG,MAAM,WAAW,OAAO;IACtB,EAAE,CAAC,EAAE,EAAE,CAAA;IACP,KAAK,CAAC,EAAE,SAAS,CAAA;CAClB;AAED,qFAAqF;AACrF,MAAM,WAAW,SAAS;IACxB,KAAK,EAAE,SAAS,CAAA;IAChB,MAAM,EAAE,OAAO,CAAA;CAChB;AAED,wFAAwF;AACxF,eAAO,MAAM,mBAAmB,wCAAwC,CAAA;AAExE;;;;;;GAMG;AACH,wBAAsB,QAAQ,CAAC,OAAO,EAAE,UAAU,EAAE,IAAI,GAAE,OAAY,GAAG,OAAO,CAAC,SAAS,CAAC,CAgB1F"}
1
+ {"version":3,"file":"k3s.d.ts","sourceRoot":"","sources":["../src/k3s.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,UAAU,EAAmB,MAAM,WAAW,CAAA;AAC5D,OAAO,EAAmB,KAAK,SAAS,EAAE,MAAM,iBAAiB,CAAA;AACjE,OAAO,EAAmB,KAAK,EAAE,EAAE,MAAM,SAAS,CAAA;AAClD,OAAO,EAAE,KAAK,SAAS,EAAc,KAAK,OAAO,EAAa,MAAM,gBAAgB,CAAA;AACpF,OAAO,EAIL,KAAK,kBAAkB,EACxB,MAAM,oBAAoB,CAAA;AAE3B,gGAAgG;AAChG,MAAM,WAAW,OAAO;IACtB,EAAE,CAAC,EAAE,EAAE,CAAA;IACP,KAAK,CAAC,EAAE,SAAS,CAAA;CAClB;AAED,qFAAqF;AACrF,MAAM,WAAW,SAAS;IACxB,KAAK,EAAE,SAAS,CAAA;IAChB,MAAM,EAAE,OAAO,CAAA;IACf,gGAAgG;IAChG,UAAU,CAAC,EAAE,kBAAkB,CAAA;CAChC;AAED,wFAAwF;AACxF,eAAO,MAAM,mBAAmB,wCAAwC,CAAA;AAExE;;;;;;;;GAQG;AACH,wBAAsB,QAAQ,CAAC,OAAO,EAAE,UAAU,EAAE,IAAI,GAAE,OAAY,GAAG,OAAO,CAAC,SAAS,CAAC,CAkC1F"}
package/dist/k3s.js CHANGED
@@ -2,14 +2,17 @@ import { OPTION_DEFAULTS } from './args.js';
2
2
  import { createNodeShell } from './host-shell.js';
3
3
  import { createConsoleIo } from './io.js';
4
4
  import { probeHost } from './k3s-probe.js';
5
+ import { CAT_FACTORY_NAMESPACE, provisionCluster, ProvisionError, } from './k3s-provision.js';
5
6
  /** The one-liner k3s install command (needs sudo — printed, never run for the user). */
6
7
  export const K3S_INSTALL_COMMAND = 'curl -sfL https://get.k3s.io | sh -';
7
8
  /**
8
- * `cat-factory k3s` — guided local-cluster setup (slice 1: probe + report + offer).
9
+ * `cat-factory k3s` — guided local-cluster setup: probe offer provision → hand-off.
9
10
  *
10
- * Probes the host over the {@link HostShell} seam, reports what was found, and lets the user pick
11
- * a setup path. Provisioning + handler wiring land in later slices; this slice stops at the choice
12
- * and prints the appropriate guidance. `@clack/prompts` is reached only through {@link Io}.
11
+ * Probes the host over the {@link HostShell} seam, reports what was found, lets the user pick a
12
+ * setup path, then (for the k3d/kind/existing-cluster paths) provisions the cluster + a
13
+ * least-privilege ServiceAccount and prints the resolved connection values to wire into the
14
+ * Settings → Infrastructure → Local k3s form. `install-k3s` needs sudo, so it is guidance-only
15
+ * (the command is printed, never run). `@clack/prompts` is reached only through {@link Io}.
13
16
  */
14
17
  export async function setupK3s(options, deps = {}) {
15
18
  const io = deps.io ?? createConsoleIo();
@@ -20,8 +23,25 @@ export async function setupK3s(options, deps = {}) {
20
23
  const state = await probeHost(shell, preferred);
21
24
  io.info(renderReport(state));
22
25
  const chosen = await chooseOffer(state, options, io);
23
- printGuidance(chosen, state, options, io);
24
- return { state, chosen };
26
+ // The k3s install needs sudo — we only ever print the command, never provision on the user's behalf.
27
+ if (chosen === 'install-k3s') {
28
+ printInstallGuidance(state, io);
29
+ return { state, chosen };
30
+ }
31
+ let connection;
32
+ try {
33
+ connection = await provisionCluster(chosen, state, options, { io, shell });
34
+ }
35
+ catch (err) {
36
+ // A declined confirm or a failed command is an expected, non-fatal outcome — report and stop.
37
+ if (err instanceof ProvisionError) {
38
+ io.warn(err.message);
39
+ return { state, chosen };
40
+ }
41
+ throw err;
42
+ }
43
+ printConnectionSummary(connection, io);
44
+ return { state, chosen, connection };
25
45
  }
26
46
  /** Render the human-readable findings report from the classified host state. */
27
47
  function renderReport(state) {
@@ -67,66 +87,54 @@ function offerLabel(o) {
67
87
  return o.recommended ? `${o.label} (recommended)` : o.label;
68
88
  }
69
89
  /**
70
- * Print the guidance for the chosen path. The k3s command is only ever PRINTED (it needs sudo). The
71
- * k3d/kind / existing-cluster paths summarize what the follow-up slice will do — this slice
72
- * intentionally stops before mutating the host.
90
+ * Print the k3s install guidance. The install needs sudo, so the command is only ever PRINTED
91
+ * cat-factory never runs it for the user.
73
92
  */
74
- function printGuidance(chosen, state, options, io) {
75
- if (chosen === 'install-k3s') {
76
- // Don't tell a user who already has k3s to re-install it — point them at starting the service.
77
- io.info(state.detections.k3s.installed
78
- ? [
79
- '',
80
- 'k3s is already installed. Start it (needs sudo), e.g.:',
81
- '',
82
- ' sudo systemctl start k3s # or: sudo k3s server',
83
- '',
84
- 'Then re-run `cat-factory k3s` — it will detect the running cluster and offer to wire it.',
85
- ].join('\n')
86
- : [
87
- '',
88
- 'Install k3s (single-node) — run this yourself (needs sudo):',
89
- '',
90
- ` ${K3S_INSTALL_COMMAND}`,
91
- '',
92
- 'Then re-run `cat-factory k3s` — it will detect the new cluster and offer to wire it.',
93
- ].join('\n'));
94
- return;
95
- }
96
- if (chosen === 'use-existing') {
97
- io.info([
93
+ function printInstallGuidance(state, io) {
94
+ // Don't tell a user who already has k3s to re-install it — point them at starting the service.
95
+ io.info(state.detections.k3s.installed
96
+ ? [
97
+ '',
98
+ 'k3s is already installed. Start it (needs sudo), e.g.:',
99
+ '',
100
+ ' sudo systemctl start k3s # or: sudo k3s server',
98
101
  '',
99
- `Selected: reuse the existing cluster${state.detections.clusterContext ? ` (context: ${state.detections.clusterContext})` : ''}.`,
102
+ 'Then re-run `cat-factory k3s` — it will detect the running cluster and provision the handler.',
103
+ ].join('\n')
104
+ : [
100
105
  '',
101
- 'Next (coming in the follow-up step): cat-factory will',
102
- ' - read the apiserver URL from your kubeconfig',
103
- ' - create a least-privilege ServiceAccount + RBAC and mint a token',
104
- ' - hand the values to the Settings → Infrastructure → Local k3s form to Test + Save',
106
+ 'Install k3s (single-node) run this yourself (needs sudo):',
105
107
  '',
106
- 'Provisioning is not performed in this release — nothing was changed on your host.',
108
+ ` ${K3S_INSTALL_COMMAND}`,
109
+ '',
110
+ 'Then re-run `cat-factory k3s` — it will detect the new cluster and provision the handler.',
107
111
  ].join('\n'));
108
- return;
109
- }
110
- // create-k3d | create-kind
111
- const distro = chosen === 'create-kind' ? 'kind' : 'k3d';
112
- const clusterName = options.clusterName ?? OPTION_DEFAULTS.k3sClusterName;
113
- const existing = chosen === 'create-kind' ? state.detections.kindClusters : state.detections.k3dClusters;
114
- const collision = existing.includes(clusterName);
112
+ }
113
+ /**
114
+ * Print the resolved connection so the user can wire it into the Settings → Infrastructure →
115
+ * Local k3s form (Test Save). The apiserver token is shown ONCE here (the user's own local
116
+ * cluster credential, to paste) — it is never written to disk or a log by cat-factory. Slice 3
117
+ * replaces this with a deep-linked, pre-filled form.
118
+ */
119
+ function printConnectionSummary(connection, io) {
115
120
  io.info([
116
121
  '',
117
- `Selected: create a local ${distro} cluster "${clusterName}".`,
118
- // A cluster of that name already exists — the follow-up provisioner is idempotent (it reuses
119
- // rather than duplicates), so flag it now instead of surprising the user in the next slice.
120
- ...(collision
121
- ? [` ! a ${distro} cluster named "${clusterName}" already exists it will be reused.`]
122
- : []),
122
+ connection.clusterName
123
+ ? `Cluster "${connection.clusterName}" is ready and wired for cat-factory.`
124
+ : 'The existing cluster is wired for cat-factory.',
125
+ '',
126
+ 'Open Settings Infrastructure Kubernetes Local k3s and enter:',
127
+ ` • API server URL: ${connection.apiServerUrl}`,
128
+ ` • Skip TLS verification: yes (local self-signed cert)`,
129
+ ` • Namespace template: cf-env-{{pullNumber}}`,
130
+ ` • Ingress host template: {{branch}}.127.0.0.1.nip.io`,
131
+ ` • ServiceAccount: ${CAT_FACTORY_NAMESPACE}/${CAT_FACTORY_NAMESPACE}`,
132
+ '',
133
+ 'Then paste this ServiceAccount token into the "API token" field and click Test → Save:',
123
134
  '',
124
- 'Next (coming in the follow-up step): cat-factory will',
125
- ` - create the ${distro} cluster and read its apiserver URL`,
126
- ' - create a least-privilege ServiceAccount + RBAC and mint a token',
127
- ' - hand the values to the Settings → Infrastructure → Local k3s form to Test + Save',
135
+ ` ${connection.apiToken}`,
128
136
  '',
129
- 'Provisioning is not performed in this release nothing was changed on your host.',
137
+ 'Keep the token privateit grants access to your local cluster.',
130
138
  ].join('\n'));
131
139
  }
132
140
  //# sourceMappingURL=k3s.js.map
package/dist/k3s.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"k3s.js","sourceRoot":"","sources":["../src/k3s.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"k3s.js","sourceRoot":"","sources":["../src/k3s.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  export declare const LOCAL_SERVER_VERSION = "^0.33.0";
2
- export declare const APP_VERSION = "^0.63.1";
2
+ export declare const APP_VERSION = "^0.64.0";
3
3
  export declare const NUXT_VERSION = "^4.4.8";
4
4
  export declare const TYPES_NODE_VERSION = "^26.0.1";
5
5
  export declare const TYPESCRIPT_VERSION = "7.0.1-rc";
package/dist/templates.js CHANGED
@@ -10,7 +10,7 @@
10
10
  // workspace version. Bump these when cutting a CLI release against newer libraries. (The two
11
11
  // libraries version independently.)
12
12
  export const LOCAL_SERVER_VERSION = '^0.33.0';
13
- export const APP_VERSION = '^0.63.1';
13
+ export const APP_VERSION = '^0.64.0';
14
14
  export const NUXT_VERSION = '^4.4.8';
15
15
  export const TYPES_NODE_VERSION = '^26.0.1';
16
16
  export const TYPESCRIPT_VERSION = '7.0.1-rc';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cat-factory/cli",
3
- "version": "0.3.0",
3
+ "version": "0.4.0",
4
4
  "description": "Bootstrap CLI for the Agent Architecture Board: scaffold a local-mode deployment (Node/local backend + frontend SPA) on your own machine — generates the crypto secrets, populates and gitignores the .env files, and mints a GitHub/GitLab personal access token by opening the browser at the right pre-scoped URL.",
5
5
  "keywords": [
6
6
  "bootstrap",