@companyhelm/cli 0.4.2 → 0.4.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.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 CompanyHelm
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,55 @@
1
+ # CompanyHelm CLI
2
+
3
+ Standalone source repository for the public `@companyhelm/cli` npm package.
4
+
5
+ ## Install or run
6
+
7
+ Run the latest CLI without a global install:
8
+
9
+ ```bash
10
+ npx -y @companyhelm/cli@latest --help
11
+ ```
12
+
13
+ Complete a CompanyHelm provider subscription login command generated by the CompanyHelm web app:
14
+
15
+ ```bash
16
+ npx -y @companyhelm/cli@latest provider login --code <code>
17
+ ```
18
+
19
+ For non-production CompanyHelm API URLs, pass the generated API URL:
20
+
21
+ ```bash
22
+ npx -y @companyhelm/cli@latest provider login --code <code> --api-url https://api.example.test
23
+ ```
24
+
25
+ ## Development
26
+
27
+ ```bash
28
+ npm ci
29
+ npm run check
30
+ npm run test
31
+ npm run build
32
+ ```
33
+
34
+ Local development entrypoint:
35
+
36
+ ```bash
37
+ npm run dev -- provider --help
38
+ ```
39
+
40
+ ## Publishing
41
+
42
+ This repository publishes `@companyhelm/cli` with npm trusted publishing from GitHub Actions.
43
+
44
+ Trusted publisher configuration on npm must match:
45
+
46
+ - Repository: `CompanyHelm/companyhelm-cli`
47
+ - Workflow filename: `npm-publish.yml`
48
+ - Environment: blank / no environment
49
+
50
+ Publish options:
51
+
52
+ 1. Create and push a semver tag such as `v0.4.5` on a commit contained in `main`.
53
+ 2. Or manually run the **Publish npm package** workflow from `main`.
54
+
55
+ The workflow verifies the package, packs it, skips if the exact version is already on npm, and publishes with provenance using OIDC.
@@ -3,6 +3,8 @@
3
3
  * coupling business behavior to process globals or a specific terminal stream.
4
4
  */
5
5
  export interface CliIo {
6
+ /** Reads a single input line from the CLI user. */
7
+ readLine(prompt: string): Promise<string>;
6
8
  /** Writes a normal output line to the CLI user. */
7
9
  writeLine(message: string): void;
8
10
  /** Writes an error output line to the CLI user. */
@@ -8,11 +8,13 @@ import type { CliIo } from "./cli_io_interface.js";
8
8
  export declare class CompanyHelmCli {
9
9
  private readonly io;
10
10
  constructor(io?: CliIo);
11
- run(argv: string[]): Promise<void>;
11
+ run(argv: string[]): Promise<number>;
12
12
  createProgram(): Command;
13
13
  private createStatusCommand;
14
14
  private createServerCommand;
15
15
  private createRunnerCommand;
16
+ private createProviderCommand;
17
+ private static errorMessage;
16
18
  private printStatus;
17
19
  private printServerCommand;
18
20
  private printRunnerCommand;
@@ -1,6 +1,8 @@
1
1
  import { readFileSync } from "node:fs";
2
2
  import { Command } from "commander";
3
3
  import { ConsoleIo } from "./console_io.js";
4
+ import { ProviderLoginCommand } from "./provider/login_command.js";
5
+ import { TerminalStyle } from "./terminal_style.js";
4
6
  /**
5
7
  * Defines the public `companyhelm` command that npm users install. The initial
6
8
  * command surface intentionally focuses on package discovery and local stack
@@ -12,9 +14,16 @@ export class CompanyHelmCli {
12
14
  this.io = io;
13
15
  }
14
16
  async run(argv) {
15
- await this.createProgram().parseAsync(argv, {
16
- from: "node",
17
- });
17
+ try {
18
+ await this.createProgram().parseAsync(argv, {
19
+ from: "node",
20
+ });
21
+ return 0;
22
+ }
23
+ catch (error) {
24
+ this.io.writeError(TerminalStyle.error(CompanyHelmCli.errorMessage(error)));
25
+ return 1;
26
+ }
18
27
  }
19
28
  createProgram() {
20
29
  const program = new Command()
@@ -29,6 +38,7 @@ export class CompanyHelmCli {
29
38
  program.addCommand(this.createStatusCommand());
30
39
  program.addCommand(this.createServerCommand());
31
40
  program.addCommand(this.createRunnerCommand());
41
+ program.addCommand(this.createProviderCommand());
32
42
  return program;
33
43
  }
34
44
  createStatusCommand() {
@@ -48,6 +58,30 @@ export class CompanyHelmCli {
48
58
  .argument("[command]", "Runner command to prepare for.", "start")
49
59
  .action((command) => this.printRunnerCommand(command));
50
60
  }
61
+ createProviderCommand() {
62
+ const providerCommand = new Command("provider")
63
+ .description("Work with CompanyHelm model provider credentials.");
64
+ providerCommand.addCommand(new Command("login")
65
+ .description("Complete a provider subscription credential login request.")
66
+ .requiredOption("--code <code>", "Provider login code from CompanyHelm.")
67
+ .option("--api-url <url>", "CompanyHelm API URL.", ProviderLoginCommand.DEFAULT_API_URL)
68
+ .action(async (options) => {
69
+ await new ProviderLoginCommand(this.io).run({
70
+ apiUrl: options.apiUrl,
71
+ code: options.code,
72
+ });
73
+ }));
74
+ return providerCommand;
75
+ }
76
+ static errorMessage(error) {
77
+ if (error instanceof Error && error.message.length > 0) {
78
+ if (error.message === "This login code is invalid or expired.") {
79
+ return "This login code is invalid or expired. Create a new provider login command in CompanyHelm and run it again.";
80
+ }
81
+ return error.message;
82
+ }
83
+ return "CompanyHelm CLI failed. Try again, or contact support if the issue continues.";
84
+ }
51
85
  printStatus() {
52
86
  this.io.writeLine("CompanyHelm CLI is installed.");
53
87
  this.io.writeLine("Main CLI package: @companyhelm/cli");
@@ -1 +1 @@
1
- {"version":3,"file":"companyhelm_cli.js","sourceRoot":"","sources":["../src/companyhelm_cli.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"companyhelm_cli.js","sourceRoot":"","sources":["../src/companyhelm_cli.ts"],"names":[],"mappings":"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"}
@@ -4,6 +4,7 @@ import type { CliIo } from "./cli_io_interface.js";
4
4
  * binaries while keeping command handlers independent from global console APIs.
5
5
  */
6
6
  export declare class ConsoleIo implements CliIo {
7
+ readLine(prompt: string): Promise<string>;
7
8
  writeLine(message: string): void;
8
9
  writeError(message: string): void;
9
10
  }
@@ -1,8 +1,19 @@
1
+ import { createInterface } from "node:readline/promises";
2
+ import { stdin as input, stdout as output } from "node:process";
1
3
  /**
2
4
  * Bridges the CLI output interface to the process streams used by npm-created
3
5
  * binaries while keeping command handlers independent from global console APIs.
4
6
  */
5
7
  export class ConsoleIo {
8
+ async readLine(prompt) {
9
+ const readline = createInterface({ input, output });
10
+ try {
11
+ return await readline.question(prompt);
12
+ }
13
+ finally {
14
+ readline.close();
15
+ }
16
+ }
6
17
  writeLine(message) {
7
18
  process.stdout.write(`${message}\n`);
8
19
  }
@@ -1 +1 @@
1
- {"version":3,"file":"console_io.js","sourceRoot":"","sources":["../src/console_io.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,MAAM,OAAO,SAAS;IACpB,SAAS,CAAC,OAAe;QACvB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,OAAO,IAAI,CAAC,CAAC;IACvC,CAAC;IAED,UAAU,CAAC,OAAe;QACxB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,OAAO,IAAI,CAAC,CAAC;IACvC,CAAC;CACF"}
1
+ {"version":3,"file":"console_io.js","sourceRoot":"","sources":["../src/console_io.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,KAAK,IAAI,KAAK,EAAE,MAAM,IAAI,MAAM,EAAE,MAAM,cAAc,CAAC;AAGhE;;;GAGG;AACH,MAAM,OAAO,SAAS;IACpB,KAAK,CAAC,QAAQ,CAAC,MAAc;QAC3B,MAAM,QAAQ,GAAG,eAAe,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC;QACpD,IAAI,CAAC;YACH,OAAO,MAAM,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;QACzC,CAAC;gBAAS,CAAC;YACT,QAAQ,CAAC,KAAK,EAAE,CAAC;QACnB,CAAC;IACH,CAAC;IAED,SAAS,CAAC,OAAe;QACvB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,OAAO,IAAI,CAAC,CAAC;IACvC,CAAC;IAED,UAAU,CAAC,OAAe;QACxB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,OAAO,IAAI,CAAC,CAAC;IACvC,CAAC;CACF"}
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
1
  #!/usr/bin/env node
2
2
  import { CompanyHelmCli } from "./companyhelm_cli.js";
3
- await new CompanyHelmCli().run(process.argv);
3
+ process.exitCode = await new CompanyHelmCli().run(process.argv);
4
4
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAEtD,MAAM,IAAI,cAAc,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAEtD,OAAO,CAAC,QAAQ,GAAG,MAAM,IAAI,cAAc,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC"}
@@ -0,0 +1,34 @@
1
+ export type ProviderLoginResolvedRequest = {
2
+ companyName: string;
3
+ credentialName: string;
4
+ expiresAt: string;
5
+ modelProvider: string;
6
+ piOauthProviderId: string;
7
+ providerName: string;
8
+ requestId: string;
9
+ requestedBy: string;
10
+ };
11
+ export type ProviderLoginCredentials = {
12
+ access: string;
13
+ expires: number;
14
+ refresh: string;
15
+ [key: string]: unknown;
16
+ };
17
+ /**
18
+ * Calls the CompanyHelm provider credential login endpoints using only the short-lived code as the
19
+ * bearer capability. The CLI intentionally does not need a browser session or a long-lived API key.
20
+ */
21
+ export declare class ProviderLoginClient {
22
+ private readonly apiUrl;
23
+ constructor(apiUrl: string);
24
+ resolve(code: string): Promise<ProviderLoginResolvedRequest>;
25
+ complete(input: {
26
+ code: string;
27
+ credentials: ProviderLoginCredentials;
28
+ }): Promise<{
29
+ credentialId: string;
30
+ status: string;
31
+ }>;
32
+ private parseResponse;
33
+ private static normalizeApiUrl;
34
+ }
@@ -0,0 +1,41 @@
1
+ /**
2
+ * Calls the CompanyHelm provider credential login endpoints using only the short-lived code as the
3
+ * bearer capability. The CLI intentionally does not need a browser session or a long-lived API key.
4
+ */
5
+ export class ProviderLoginClient {
6
+ apiUrl;
7
+ constructor(apiUrl) {
8
+ this.apiUrl = ProviderLoginClient.normalizeApiUrl(apiUrl);
9
+ }
10
+ async resolve(code) {
11
+ const url = new URL("/model-provider-credential-login/resolve", this.apiUrl);
12
+ url.searchParams.set("code", code);
13
+ const response = await fetch(url);
14
+ return this.parseResponse(response);
15
+ }
16
+ async complete(input) {
17
+ const response = await fetch(new URL("/model-provider-credential-login/complete", this.apiUrl), {
18
+ body: JSON.stringify(input),
19
+ headers: {
20
+ "content-type": "application/json",
21
+ },
22
+ method: "POST",
23
+ });
24
+ return this.parseResponse(response);
25
+ }
26
+ async parseResponse(response) {
27
+ const payload = await response.json().catch(() => null);
28
+ if (!response.ok) {
29
+ throw new Error(payload?.error || `CompanyHelm API request failed with status ${response.status}.`);
30
+ }
31
+ return payload;
32
+ }
33
+ static normalizeApiUrl(apiUrl) {
34
+ const parsedUrl = new URL(apiUrl);
35
+ parsedUrl.pathname = parsedUrl.pathname.replace(/\/$/u, "");
36
+ parsedUrl.search = "";
37
+ parsedUrl.hash = "";
38
+ return parsedUrl.toString();
39
+ }
40
+ }
41
+ //# sourceMappingURL=login_client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"login_client.js","sourceRoot":"","sources":["../../src/provider/login_client.ts"],"names":[],"mappings":"AAkBA;;;GAGG;AACH,MAAM,OAAO,mBAAmB;IACb,MAAM,CAAS;IAEhC,YAAY,MAAc;QACxB,IAAI,CAAC,MAAM,GAAG,mBAAmB,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC;IAC5D,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,IAAY;QACxB,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,0CAA0C,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;QAC7E,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;QACnC,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,CAAC,CAAC;QAClC,OAAO,IAAI,CAAC,aAAa,CAA+B,QAAQ,CAAC,CAAC;IACpE,CAAC;IAED,KAAK,CAAC,QAAQ,CAAC,KAGd;QACC,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,IAAI,GAAG,CAAC,2CAA2C,EAAE,IAAI,CAAC,MAAM,CAAC,EAAE;YAC9F,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC;YAC3B,OAAO,EAAE;gBACP,cAAc,EAAE,kBAAkB;aACnC;YACD,MAAM,EAAE,MAAM;SACf,CAAC,CAAC;QAEH,OAAO,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;IACtC,CAAC;IAEO,KAAK,CAAC,aAAa,CAAI,QAAkB;QAC/C,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAA8B,CAAC;QACrF,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,MAAM,IAAI,KAAK,CAAC,OAAO,EAAE,KAAK,IAAI,8CAA8C,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC;QACtG,CAAC;QAED,OAAO,OAAY,CAAC;IACtB,CAAC;IAEO,MAAM,CAAC,eAAe,CAAC,MAAc;QAC3C,MAAM,SAAS,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,CAAC;QAClC,SAAS,CAAC,QAAQ,GAAG,SAAS,CAAC,QAAQ,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;QAC5D,SAAS,CAAC,MAAM,GAAG,EAAE,CAAC;QACtB,SAAS,CAAC,IAAI,GAAG,EAAE,CAAC;QACpB,OAAO,SAAS,CAAC,QAAQ,EAAE,CAAC;IAC9B,CAAC;CACF"}
@@ -0,0 +1,19 @@
1
+ import type { CliIo } from "../cli_io_interface.js";
2
+ import { ProviderLoginClient } from "./login_client.js";
3
+ import { ProviderOauthLoginRunner } from "./oauth_login_runner.js";
4
+ export type ProviderLoginCommandOptions = {
5
+ apiUrl: string;
6
+ code: string;
7
+ };
8
+ /**
9
+ * Implements `companyhelm provider login` by resolving the web-generated code, running the matching
10
+ * local OAuth flow, and atomically completing the CompanyHelm credential request.
11
+ */
12
+ export declare class ProviderLoginCommand {
13
+ static readonly DEFAULT_API_URL = "https://api.companyhelm.com";
14
+ private readonly clientFactory;
15
+ private readonly io;
16
+ private readonly oauthLoginRunner;
17
+ constructor(io: CliIo, clientFactory?: (apiUrl: string) => ProviderLoginClient, oauthLoginRunner?: ProviderOauthLoginRunner);
18
+ run(options: ProviderLoginCommandOptions): Promise<void>;
19
+ }
@@ -0,0 +1,40 @@
1
+ import { TerminalStyle } from "../terminal_style.js";
2
+ import { ProviderLoginClient } from "./login_client.js";
3
+ import { ProviderOauthLoginRunner } from "./oauth_login_runner.js";
4
+ /**
5
+ * Implements `companyhelm provider login` by resolving the web-generated code, running the matching
6
+ * local OAuth flow, and atomically completing the CompanyHelm credential request.
7
+ */
8
+ export class ProviderLoginCommand {
9
+ static DEFAULT_API_URL = "https://api.companyhelm.com";
10
+ clientFactory;
11
+ io;
12
+ oauthLoginRunner;
13
+ constructor(io, clientFactory = (apiUrl) => new ProviderLoginClient(apiUrl), oauthLoginRunner = new ProviderOauthLoginRunner(io)) {
14
+ this.clientFactory = clientFactory;
15
+ this.io = io;
16
+ this.oauthLoginRunner = oauthLoginRunner;
17
+ }
18
+ async run(options) {
19
+ const client = this.clientFactory(options.apiUrl);
20
+ const request = await client.resolve(options.code);
21
+ this.io.writeLine(TerminalStyle.info(`Adding ${request.providerName} credential to CompanyHelm.`));
22
+ this.io.writeLine(TerminalStyle.detail("Credential", request.credentialName));
23
+ this.io.writeLine(TerminalStyle.detail("Company", request.companyName));
24
+ this.io.writeLine(TerminalStyle.detail("Requested by", request.requestedBy));
25
+ this.io.writeLine(TerminalStyle.detail("Expires", request.expiresAt));
26
+ const credentials = await this.oauthLoginRunner.login(request.piOauthProviderId);
27
+ this.io.writeLine(TerminalStyle.progress("Saving credential in CompanyHelm..."));
28
+ await client.complete({
29
+ code: options.code,
30
+ credentials: {
31
+ ...credentials,
32
+ access: credentials.access,
33
+ expires: credentials.expires,
34
+ refresh: credentials.refresh,
35
+ },
36
+ });
37
+ this.io.writeLine(TerminalStyle.success(`Credential "${request.credentialName}" added to ${request.companyName}.`));
38
+ }
39
+ }
40
+ //# sourceMappingURL=login_command.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"login_command.js","sourceRoot":"","sources":["../../src/provider/login_command.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,EAAE,wBAAwB,EAAE,MAAM,yBAAyB,CAAC;AAOnE;;;GAGG;AACH,MAAM,OAAO,oBAAoB;IAC/B,MAAM,CAAU,eAAe,GAAG,6BAA6B,CAAC;IAE/C,aAAa,CAA0C;IACvD,EAAE,CAAQ;IACV,gBAAgB,CAA2B;IAE5D,YACE,EAAS,EACT,gBAAyD,CAAC,MAAM,EAAE,EAAE,CAAC,IAAI,mBAAmB,CAAC,MAAM,CAAC,EACpG,mBAA6C,IAAI,wBAAwB,CAAC,EAAE,CAAC;QAE7E,IAAI,CAAC,aAAa,GAAG,aAAa,CAAC;QACnC,IAAI,CAAC,EAAE,GAAG,EAAE,CAAC;QACb,IAAI,CAAC,gBAAgB,GAAG,gBAAgB,CAAC;IAC3C,CAAC;IAED,KAAK,CAAC,GAAG,CAAC,OAAoC;QAC5C,MAAM,MAAM,GAAG,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QAClD,MAAM,OAAO,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QACnD,IAAI,CAAC,EAAE,CAAC,SAAS,CAAC,aAAa,CAAC,IAAI,CAAC,UAAU,OAAO,CAAC,YAAY,6BAA6B,CAAC,CAAC,CAAC;QACnG,IAAI,CAAC,EAAE,CAAC,SAAS,CAAC,aAAa,CAAC,MAAM,CAAC,YAAY,EAAE,OAAO,CAAC,cAAc,CAAC,CAAC,CAAC;QAC9E,IAAI,CAAC,EAAE,CAAC,SAAS,CAAC,aAAa,CAAC,MAAM,CAAC,SAAS,EAAE,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC;QACxE,IAAI,CAAC,EAAE,CAAC,SAAS,CAAC,aAAa,CAAC,MAAM,CAAC,cAAc,EAAE,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC;QAC7E,IAAI,CAAC,EAAE,CAAC,SAAS,CAAC,aAAa,CAAC,MAAM,CAAC,SAAS,EAAE,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC;QACtE,MAAM,WAAW,GAAG,MAAM,IAAI,CAAC,gBAAgB,CAAC,KAAK,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAAC;QACjF,IAAI,CAAC,EAAE,CAAC,SAAS,CAAC,aAAa,CAAC,QAAQ,CAAC,qCAAqC,CAAC,CAAC,CAAC;QACjF,MAAM,MAAM,CAAC,QAAQ,CAAC;YACpB,IAAI,EAAE,OAAO,CAAC,IAAI;YAClB,WAAW,EAAE;gBACX,GAAG,WAAW;gBACd,MAAM,EAAE,WAAW,CAAC,MAAM;gBAC1B,OAAO,EAAE,WAAW,CAAC,OAAO;gBAC5B,OAAO,EAAE,WAAW,CAAC,OAAO;aAC7B;SACF,CAAC,CAAC;QACH,IAAI,CAAC,EAAE,CAAC,SAAS,CAAC,aAAa,CAAC,OAAO,CAAC,eAAe,OAAO,CAAC,cAAc,cAAc,OAAO,CAAC,WAAW,GAAG,CAAC,CAAC,CAAC;IACtH,CAAC"}
@@ -0,0 +1,11 @@
1
+ import { type OAuthCredentials } from "@mariozechner/pi-ai/oauth";
2
+ import type { CliIo } from "../cli_io_interface.js";
3
+ /**
4
+ * Runs the provider OAuth flow supplied by Pi Mono and adapts its terminal callbacks to CompanyHelm's
5
+ * small CLI IO interface. This keeps provider-specific login mechanics outside command parsing.
6
+ */
7
+ export declare class ProviderOauthLoginRunner {
8
+ private readonly io;
9
+ constructor(io: CliIo);
10
+ login(providerId: string): Promise<OAuthCredentials>;
11
+ }
@@ -0,0 +1,31 @@
1
+ import { getOAuthProvider } from "@mariozechner/pi-ai/oauth";
2
+ import { TerminalStyle } from "../terminal_style.js";
3
+ /**
4
+ * Runs the provider OAuth flow supplied by Pi Mono and adapts its terminal callbacks to CompanyHelm's
5
+ * small CLI IO interface. This keeps provider-specific login mechanics outside command parsing.
6
+ */
7
+ export class ProviderOauthLoginRunner {
8
+ io;
9
+ constructor(io) {
10
+ this.io = io;
11
+ }
12
+ async login(providerId) {
13
+ const provider = getOAuthProvider(providerId);
14
+ if (!provider) {
15
+ throw new Error(`Pi OAuth provider is not registered: ${providerId}`);
16
+ }
17
+ return provider.login({
18
+ onAuth: (info) => {
19
+ this.io.writeLine(TerminalStyle.info("Complete the provider login in your browser."));
20
+ this.io.writeLine(TerminalStyle.detail("Login URL", info.url));
21
+ },
22
+ onProgress: (message) => {
23
+ this.io.writeLine(TerminalStyle.progress(message));
24
+ },
25
+ onPrompt: async () => {
26
+ throw new Error("CompanyHelm CLI did not receive the provider browser callback. Open the login URL on this machine and try again.");
27
+ },
28
+ });
29
+ }
30
+ }
31
+ //# sourceMappingURL=oauth_login_runner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"oauth_login_runner.js","sourceRoot":"","sources":["../../src/provider/oauth_login_runner.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAyB,MAAM,2BAA2B,CAAC;AAEpF,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAErD;;;GAGG;AACH,MAAM,OAAO,wBAAwB;IAClB,EAAE,CAAQ;IAE3B,YAAY,EAAS;QACnB,IAAI,CAAC,EAAE,GAAG,EAAE,CAAC;IACf,CAAC;IAED,KAAK,CAAC,KAAK,CAAC,UAAkB;QAC5B,MAAM,QAAQ,GAAG,gBAAgB,CAAC,UAAU,CAAC,CAAC;QAC9C,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,MAAM,IAAI,KAAK,CAAC,wCAAwC,UAAU,EAAE,CAAC,CAAC;QACxE,CAAC;QAED,OAAO,QAAQ,CAAC,KAAK,CAAC;YACpB,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE;gBACf,IAAI,CAAC,EAAE,CAAC,SAAS,CAAC,aAAa,CAAC,IAAI,CAAC,8CAA8C,CAAC,CAAC,CAAC;gBACtF,IAAI,CAAC,EAAE,CAAC,SAAS,CAAC,aAAa,CAAC,MAAM,CAAC,WAAW,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;YACjE,CAAC;YACD,UAAU,EAAE,CAAC,OAAO,EAAE,EAAE;gBACtB,IAAI,CAAC,EAAE,CAAC,SAAS,CAAC,aAAa,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC;YACrD,CAAC;YACD,QAAQ,EAAE,KAAK,IAAI,EAAE;gBACnB,MAAM,IAAI,KAAK,CACb,kHAAkH,CACnH,CAAC;YACJ,CAAC;SACF,CAAC,CAAC;IACL,CAAC;CACF"}
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Formats concise terminal status lines with ANSI color while keeping the command handlers focused on
3
+ * provider login behavior. The output intentionally stays readable when colors are not interpreted.
4
+ */
5
+ export declare class TerminalStyle {
6
+ static readonly blue = "\u001B[34m";
7
+ static readonly green = "\u001B[32m";
8
+ static readonly gray = "\u001B[90m";
9
+ static readonly red = "\u001B[31m";
10
+ static readonly reset = "\u001B[0m";
11
+ static readonly yellow = "\u001B[33m";
12
+ static detail(label: string, value: string): string;
13
+ static error(message: string): string;
14
+ static info(message: string): string;
15
+ static progress(message: string): string;
16
+ static success(message: string): string;
17
+ }
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Formats concise terminal status lines with ANSI color while keeping the command handlers focused on
3
+ * provider login behavior. The output intentionally stays readable when colors are not interpreted.
4
+ */
5
+ export class TerminalStyle {
6
+ static blue = "\u001B[34m";
7
+ static green = "\u001B[32m";
8
+ static gray = "\u001B[90m";
9
+ static red = "\u001B[31m";
10
+ static reset = "\u001B[0m";
11
+ static yellow = "\u001B[33m";
12
+ static detail(label, value) {
13
+ return `${TerminalStyle.gray}•${TerminalStyle.reset} ${label}: ${value}`;
14
+ }
15
+ static error(message) {
16
+ return `${TerminalStyle.red}❌${TerminalStyle.reset} ${message}`;
17
+ }
18
+ static info(message) {
19
+ return `${TerminalStyle.blue}ℹ${TerminalStyle.reset} ${message}`;
20
+ }
21
+ static progress(message) {
22
+ return `${TerminalStyle.yellow}⏳${TerminalStyle.reset} ${message}`;
23
+ }
24
+ static success(message) {
25
+ return `${TerminalStyle.green}✅${TerminalStyle.reset} ${message}`;
26
+ }
27
+ }
28
+ //# sourceMappingURL=terminal_style.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"terminal_style.js","sourceRoot":"","sources":["../src/terminal_style.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,OAAO,aAAa;IACxB,MAAM,CAAU,IAAI,GAAG,YAAY,CAAC;IACpC,MAAM,CAAU,KAAK,GAAG,YAAY,CAAC;IACrC,MAAM,CAAU,IAAI,GAAG,YAAY,CAAC;IACpC,MAAM,CAAU,GAAG,GAAG,YAAY,CAAC;IACnC,MAAM,CAAU,KAAK,GAAG,WAAW,CAAC;IACpC,MAAM,CAAU,MAAM,GAAG,YAAY,CAAC;IAEtC,MAAM,CAAC,MAAM,CAAC,KAAa,EAAE,KAAa;QACxC,OAAO,GAAG,aAAa,CAAC,IAAI,IAAI,aAAa,CAAC,KAAK,IAAI,KAAK,KAAK,KAAK,EAAE,CAAC;IAC3E,CAAC;IAED,MAAM,CAAC,KAAK,CAAC,OAAe;QAC1B,OAAO,GAAG,aAAa,CAAC,GAAG,IAAI,aAAa,CAAC,KAAK,IAAI,OAAO,EAAE,CAAC;IAClE,CAAC;IAED,MAAM,CAAC,IAAI,CAAC,OAAe;QACzB,OAAO,GAAG,aAAa,CAAC,IAAI,IAAI,aAAa,CAAC,KAAK,IAAI,OAAO,EAAE,CAAC;IACnE,CAAC;IAED,MAAM,CAAC,QAAQ,CAAC,OAAe;QAC7B,OAAO,GAAG,aAAa,CAAC,MAAM,IAAI,aAAa,CAAC,KAAK,IAAI,OAAO,EAAE,CAAC;IACrE,CAAC;IAED,MAAM,CAAC,OAAO,CAAC,OAAe;QAC5B,OAAO,GAAG,aAAa,CAAC,KAAK,IAAI,aAAa,CAAC,KAAK,IAAI,OAAO,EAAE,CAAC;IACpE,CAAC"}
package/package.json CHANGED
@@ -1,12 +1,16 @@
1
1
  {
2
2
  "name": "@companyhelm/cli",
3
- "version": "0.4.2",
4
- "description": "CompanyHelm self-hosting command-line interface.",
3
+ "version": "0.4.5",
4
+ "description": "CompanyHelm command-line interface.",
5
5
  "repository": {
6
6
  "type": "git",
7
- "url": "git+https://github.com/CompanyHelm/companyhelm.git",
8
- "directory": "packages/cli"
7
+ "url": "git+https://github.com/CompanyHelm/companyhelm-cli.git"
9
8
  },
9
+ "homepage": "https://github.com/CompanyHelm/companyhelm-cli#readme",
10
+ "bugs": {
11
+ "url": "https://github.com/CompanyHelm/companyhelm-cli/issues"
12
+ },
13
+ "license": "MIT",
10
14
  "type": "module",
11
15
  "bin": {
12
16
  "companyhelm": "dist/index.js"
@@ -24,13 +28,20 @@
24
28
  "test": "npm run check && node --import tsx --test tests/*.test.ts"
25
29
  },
26
30
  "dependencies": {
31
+ "@mariozechner/pi-ai": "0.70.6",
27
32
  "commander": "^14.0.3"
28
33
  },
29
34
  "devDependencies": {
35
+ "@eslint/js": "^10.0.1",
30
36
  "@types/node": "^20.19.41",
31
- "typescript": "^5.9.3"
37
+ "eslint": "^10.1.0",
38
+ "globals": "^17.4.0",
39
+ "tsx": "^4.21.0",
40
+ "typescript": "^5.9.3",
41
+ "typescript-eslint": "^8.57.1"
32
42
  },
33
43
  "engines": {
34
44
  "node": ">=20.20.0"
35
- }
45
+ },
46
+ "packageManager": "npm@11.6.2"
36
47
  }