@companyhelm/cli 0.4.2 → 0.4.3

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.
@@ -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. */
@@ -13,6 +13,7 @@ export declare class CompanyHelmCli {
13
13
  private createStatusCommand;
14
14
  private createServerCommand;
15
15
  private createRunnerCommand;
16
+ private createProviderCommand;
16
17
  private printStatus;
17
18
  private printServerCommand;
18
19
  private printRunnerCommand;
@@ -1,6 +1,7 @@
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";
4
5
  /**
5
6
  * Defines the public `companyhelm` command that npm users install. The initial
6
7
  * command surface intentionally focuses on package discovery and local stack
@@ -29,6 +30,7 @@ export class CompanyHelmCli {
29
30
  program.addCommand(this.createStatusCommand());
30
31
  program.addCommand(this.createServerCommand());
31
32
  program.addCommand(this.createRunnerCommand());
33
+ program.addCommand(this.createProviderCommand());
32
34
  return program;
33
35
  }
34
36
  createStatusCommand() {
@@ -48,6 +50,21 @@ export class CompanyHelmCli {
48
50
  .argument("[command]", "Runner command to prepare for.", "start")
49
51
  .action((command) => this.printRunnerCommand(command));
50
52
  }
53
+ createProviderCommand() {
54
+ const providerCommand = new Command("provider")
55
+ .description("Work with CompanyHelm model provider credentials.");
56
+ providerCommand.addCommand(new Command("login")
57
+ .description("Complete a provider subscription credential login request.")
58
+ .requiredOption("--code <code>", "Provider login code from CompanyHelm.")
59
+ .option("--api-url <url>", "CompanyHelm API URL.", ProviderLoginCommand.DEFAULT_API_URL)
60
+ .action(async (options) => {
61
+ await new ProviderLoginCommand(this.io).run({
62
+ apiUrl: options.apiUrl,
63
+ code: options.code,
64
+ });
65
+ }));
66
+ return providerCommand;
67
+ }
51
68
  printStatus() {
52
69
  this.io.writeLine("CompanyHelm CLI is installed.");
53
70
  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"}
@@ -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,35 @@
1
+ import { ProviderLoginClient } from "./login_client.js";
2
+ import { ProviderOauthLoginRunner } from "./oauth_login_runner.js";
3
+ /**
4
+ * Implements `companyhelm provider login` by resolving the web-generated code, running the matching
5
+ * local OAuth flow, and atomically completing the CompanyHelm credential request.
6
+ */
7
+ export class ProviderLoginCommand {
8
+ static DEFAULT_API_URL = "https://api.companyhelm.com";
9
+ clientFactory;
10
+ io;
11
+ oauthLoginRunner;
12
+ constructor(io, clientFactory = (apiUrl) => new ProviderLoginClient(apiUrl), oauthLoginRunner = new ProviderOauthLoginRunner(io)) {
13
+ this.clientFactory = clientFactory;
14
+ this.io = io;
15
+ this.oauthLoginRunner = oauthLoginRunner;
16
+ }
17
+ async run(options) {
18
+ const client = this.clientFactory(options.apiUrl);
19
+ const request = await client.resolve(options.code);
20
+ this.io.writeLine(`Adding ${request.providerName} credential "${request.credentialName}" to ${request.companyName}.`);
21
+ this.io.writeLine(`Requested by ${request.requestedBy}. Expires at ${request.expiresAt}.`);
22
+ const credentials = await this.oauthLoginRunner.login(request.piOauthProviderId);
23
+ const result = await client.complete({
24
+ code: options.code,
25
+ credentials: {
26
+ ...credentials,
27
+ access: credentials.access,
28
+ expires: credentials.expires,
29
+ refresh: credentials.refresh,
30
+ },
31
+ });
32
+ this.io.writeLine(`Credential added successfully: ${result.credentialId}`);
33
+ }
34
+ }
35
+ //# 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,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,UAAU,OAAO,CAAC,YAAY,gBAAgB,OAAO,CAAC,cAAc,QAAQ,OAAO,CAAC,WAAW,GAAG,CAAC,CAAC;QACtH,IAAI,CAAC,EAAE,CAAC,SAAS,CAAC,gBAAgB,OAAO,CAAC,WAAW,gBAAgB,OAAO,CAAC,SAAS,GAAG,CAAC,CAAC;QAC3F,MAAM,WAAW,GAAG,MAAM,IAAI,CAAC,gBAAgB,CAAC,KAAK,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAAC;QACjF,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,QAAQ,CAAC;YACnC,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,kCAAkC,MAAM,CAAC,YAAY,EAAE,CAAC,CAAC;IAC7E,CAAC"}
@@ -0,0 +1,12 @@
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
+ private static promptLabel;
12
+ }
@@ -0,0 +1,37 @@
1
+ import { getOAuthProvider } from "@mariozechner/pi-ai/oauth";
2
+ /**
3
+ * Runs the provider OAuth flow supplied by Pi Mono and adapts its terminal callbacks to CompanyHelm's
4
+ * small CLI IO interface. This keeps provider-specific login mechanics outside command parsing.
5
+ */
6
+ export class ProviderOauthLoginRunner {
7
+ io;
8
+ constructor(io) {
9
+ this.io = io;
10
+ }
11
+ async login(providerId) {
12
+ const provider = getOAuthProvider(providerId);
13
+ if (!provider) {
14
+ throw new Error(`Pi OAuth provider is not registered: ${providerId}`);
15
+ }
16
+ return provider.login({
17
+ onAuth: (info) => {
18
+ if (info.instructions) {
19
+ this.io.writeLine(info.instructions);
20
+ }
21
+ this.io.writeLine(info.url);
22
+ },
23
+ onManualCodeInput: async () => this.io.readLine("Paste the authorization code or redirect URL: "),
24
+ onProgress: (message) => {
25
+ this.io.writeLine(message);
26
+ },
27
+ onPrompt: async (prompt) => this.io.readLine(ProviderOauthLoginRunner.promptLabel(prompt)),
28
+ });
29
+ }
30
+ static promptLabel(prompt) {
31
+ if (prompt.placeholder) {
32
+ return `${prompt.message} (${prompt.placeholder}): `;
33
+ }
34
+ return `${prompt.message}: `;
35
+ }
36
+ }
37
+ //# 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,EAA2C,MAAM,2BAA2B,CAAC;AAGtG;;;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,IAAI,CAAC,YAAY,EAAE,CAAC;oBACtB,IAAI,CAAC,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;gBACvC,CAAC;gBACD,IAAI,CAAC,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YAC9B,CAAC;YACD,iBAAiB,EAAE,KAAK,IAAI,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,QAAQ,CAAC,gDAAgD,CAAC;YACjG,UAAU,EAAE,CAAC,OAAO,EAAE,EAAE;gBACtB,IAAI,CAAC,EAAE,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;YAC7B,CAAC;YACD,QAAQ,EAAE,KAAK,EAAE,MAAmB,EAAE,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,QAAQ,CAAC,wBAAwB,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;SACxG,CAAC,CAAC;IACL,CAAC;IAEO,MAAM,CAAC,WAAW,CAAC,MAAmB;QAC5C,IAAI,MAAM,CAAC,WAAW,EAAE,CAAC;YACvB,OAAO,GAAG,MAAM,CAAC,OAAO,KAAK,MAAM,CAAC,WAAW,KAAK,CAAC;QACvD,CAAC;QAED,OAAO,GAAG,MAAM,CAAC,OAAO,IAAI,CAAC;IAC/B,CAAC;CACF"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@companyhelm/cli",
3
- "version": "0.4.2",
3
+ "version": "0.4.3",
4
4
  "description": "CompanyHelm self-hosting command-line interface.",
5
5
  "repository": {
6
6
  "type": "git",
@@ -24,7 +24,8 @@
24
24
  "test": "npm run check && node --import tsx --test tests/*.test.ts"
25
25
  },
26
26
  "dependencies": {
27
- "commander": "^14.0.3"
27
+ "commander": "^14.0.3",
28
+ "@mariozechner/pi-ai": "0.70.6"
28
29
  },
29
30
  "devDependencies": {
30
31
  "@types/node": "^20.19.41",