@getpaseo/cli 0.5.0-beta.4 → 0.5.0-beta.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/dist/commands/hub/daemon-client.d.ts +7 -0
- package/dist/commands/hub/hub-client/index.d.ts +3 -2
- package/dist/commands/hub/hub-client/index.js +12 -1
- package/dist/commands/hub/hub-client/internal/contracts.d.ts +17 -0
- package/dist/commands/hub/hub-client/internal/contracts.js +14 -0
- package/dist/commands/hub/index.js +3 -1
- package/dist/commands/hub/init-plan.d.ts +3 -0
- package/dist/commands/hub/init-plan.js +8 -4
- package/dist/commands/hub/init.d.ts +18 -3
- package/dist/commands/hub/init.js +218 -78
- package/dist/commands/hub/login.d.ts +2 -0
- package/dist/commands/hub/login.js +6 -0
- package/dist/commands/hub/starter-agent-runtime.d.ts +37 -0
- package/dist/commands/hub/starter-agent-runtime.js +49 -0
- package/dist/commands/hub/starter-trigger.d.ts +10 -0
- package/dist/commands/hub/starter-trigger.js +28 -0
- package/package.json +4 -4
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { ProviderSnapshotEntry } from "@getpaseo/protocol/agent-types";
|
|
1
2
|
export interface HubStatus {
|
|
2
3
|
state: string;
|
|
3
4
|
daemonId: string | null;
|
|
@@ -6,6 +7,9 @@ export interface HubStatus {
|
|
|
6
7
|
connectedAt: string | null;
|
|
7
8
|
lastError: string | null;
|
|
8
9
|
}
|
|
10
|
+
export interface HubProvidersSnapshotOptions {
|
|
11
|
+
cwd?: string;
|
|
12
|
+
}
|
|
9
13
|
export interface HubDaemonClient {
|
|
10
14
|
connectHub(url: string, token: string): Promise<{
|
|
11
15
|
status: HubStatus;
|
|
@@ -17,6 +21,9 @@ export interface HubDaemonClient {
|
|
|
17
21
|
status: HubStatus;
|
|
18
22
|
warning?: string;
|
|
19
23
|
}>;
|
|
24
|
+
getProvidersSnapshot(options?: HubProvidersSnapshotOptions): Promise<{
|
|
25
|
+
entries: ProviderSnapshotEntry[];
|
|
26
|
+
}>;
|
|
20
27
|
close(): Promise<void>;
|
|
21
28
|
}
|
|
22
29
|
export interface HubDaemonConnection {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { HubBundleFile } from "../deploy-bundle.js";
|
|
2
|
-
import { type CliAuthorization, type CliAuthorizationPoll, type HubInstallResult, type HubConfigurationResources, type HubProject, type HubValidationResult } from "./internal/contracts.js";
|
|
3
|
-
export type { CliAuthorization, CliAuthorizationPoll, HubInstallResult, HubConfigurationResources, HubProject, HubValidationResult, } from "./internal/contracts.js";
|
|
2
|
+
import { type CliAuthorization, type CliAuthorizationPoll, type HubInstallResult, type HubConfigurationResources, type HubSetupResources, type HubProject, type HubValidationResult } from "./internal/contracts.js";
|
|
3
|
+
export type { CliAuthorization, CliAuthorizationPoll, HubInstallResult, HubConfigurationResources, HubSetupResources, HubProject, HubValidationResult, } from "./internal/contracts.js";
|
|
4
4
|
interface HubConfigurationInput {
|
|
5
5
|
origin: string;
|
|
6
6
|
apiKey: string;
|
|
@@ -12,6 +12,7 @@ export declare class HubHttpClient {
|
|
|
12
12
|
pollCliAuthorization(origin: string, deviceCode: string, timeoutMilliseconds: number): Promise<CliAuthorizationPoll>;
|
|
13
13
|
listProjects(origin: string, apiKey: string): Promise<HubProject[]>;
|
|
14
14
|
listConfigurationResources(origin: string, apiKey: string): Promise<HubConfigurationResources>;
|
|
15
|
+
listSetupResources(origin: string, apiKey: string): Promise<HubSetupResources>;
|
|
15
16
|
installConfiguration(input: HubConfigurationInput): Promise<HubInstallResult>;
|
|
16
17
|
validateConfiguration(input: HubConfigurationInput): Promise<HubValidationResult>;
|
|
17
18
|
issueEnrollmentToken(origin: string, apiKey: string): Promise<string>;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { HubCommandError } from "../error.js";
|
|
2
|
-
import { authorizationPollSchema, authorizationSchema, configurationResourcesSchema, enrollmentTokenSchema, installResponseSchema, projectsResponseSchema, validationResponseSchema, } from "./internal/contracts.js";
|
|
2
|
+
import { authorizationPollSchema, authorizationSchema, configurationResourcesSchema, enrollmentTokenSchema, installResponseSchema, projectsResponseSchema, validationResponseSchema, setupResourcesSchema, } from "./internal/contracts.js";
|
|
3
3
|
import { requestHub } from "./internal/transport.js";
|
|
4
4
|
export class HubHttpClient {
|
|
5
5
|
startCliAuthorization(origin) {
|
|
@@ -56,6 +56,17 @@ export class HubHttpClient {
|
|
|
56
56
|
failureMessage: "Hub configuration resource listing failed",
|
|
57
57
|
});
|
|
58
58
|
}
|
|
59
|
+
listSetupResources(origin, apiKey) {
|
|
60
|
+
return requestHub({
|
|
61
|
+
origin,
|
|
62
|
+
path: "/api/v1/setup-resources",
|
|
63
|
+
method: "GET",
|
|
64
|
+
apiKey,
|
|
65
|
+
successStatus: 200,
|
|
66
|
+
schema: setupResourcesSchema,
|
|
67
|
+
failureMessage: "Hub guided setup resource listing failed",
|
|
68
|
+
});
|
|
69
|
+
}
|
|
59
70
|
installConfiguration(input) {
|
|
60
71
|
return requestHub({
|
|
61
72
|
origin: input.origin,
|
|
@@ -62,6 +62,22 @@ export declare const configurationResourcesSchema: z.ZodObject<{
|
|
|
62
62
|
teamName: z.ZodString;
|
|
63
63
|
}, z.core.$strict>>;
|
|
64
64
|
}, z.core.$strict>;
|
|
65
|
+
export declare const setupResourcesSchema: z.ZodObject<{
|
|
66
|
+
github: z.ZodArray<z.ZodObject<{
|
|
67
|
+
slug: z.ZodString;
|
|
68
|
+
accountLogin: z.ZodString;
|
|
69
|
+
accountType: z.ZodString;
|
|
70
|
+
repositories: z.ZodArray<z.ZodString>;
|
|
71
|
+
}, z.core.$strict>>;
|
|
72
|
+
discord: z.ZodArray<z.ZodObject<{
|
|
73
|
+
guildId: z.ZodString;
|
|
74
|
+
guildName: z.ZodString;
|
|
75
|
+
}, z.core.$strict>>;
|
|
76
|
+
slack: z.ZodArray<z.ZodObject<{
|
|
77
|
+
teamId: z.ZodString;
|
|
78
|
+
teamName: z.ZodString;
|
|
79
|
+
}, z.core.$strict>>;
|
|
80
|
+
}, z.core.$strict>;
|
|
65
81
|
export declare const installResponseSchema: z.ZodObject<{
|
|
66
82
|
projectSlug: z.ZodString;
|
|
67
83
|
version: z.ZodNumber;
|
|
@@ -80,6 +96,7 @@ export type CliAuthorization = z.infer<typeof authorizationSchema>;
|
|
|
80
96
|
export type CliAuthorizationPoll = z.infer<typeof authorizationPollSchema>;
|
|
81
97
|
export type HubProject = z.infer<typeof projectSchema>;
|
|
82
98
|
export type HubConfigurationResources = z.infer<typeof configurationResourcesSchema>;
|
|
99
|
+
export type HubSetupResources = z.infer<typeof setupResourcesSchema>;
|
|
83
100
|
export type HubInstallResult = z.infer<typeof installResponseSchema>;
|
|
84
101
|
export type HubValidationResult = z.infer<typeof validationResponseSchema>;
|
|
85
102
|
export {};
|
|
@@ -45,6 +45,20 @@ export const configurationResourcesSchema = z
|
|
|
45
45
|
slack: z.array(z.object({ slug: z.string().min(1), teamName: z.string().min(1) }).strict()),
|
|
46
46
|
})
|
|
47
47
|
.strict();
|
|
48
|
+
export const setupResourcesSchema = z
|
|
49
|
+
.object({
|
|
50
|
+
github: z.array(z
|
|
51
|
+
.object({
|
|
52
|
+
slug: z.string().min(1),
|
|
53
|
+
accountLogin: z.string().min(1),
|
|
54
|
+
accountType: z.string().min(1),
|
|
55
|
+
repositories: z.array(z.string().min(1)),
|
|
56
|
+
})
|
|
57
|
+
.strict()),
|
|
58
|
+
discord: z.array(z.object({ guildId: z.string().min(1), guildName: z.string().min(1) }).strict()),
|
|
59
|
+
slack: z.array(z.object({ teamId: z.string().min(1), teamName: z.string().min(1) }).strict()),
|
|
60
|
+
})
|
|
61
|
+
.strict();
|
|
48
62
|
export const installResponseSchema = z
|
|
49
63
|
.object({
|
|
50
64
|
projectSlug: z.string().min(1),
|
|
@@ -14,7 +14,7 @@ import { addHubProjectsCommand } from "./projects.js";
|
|
|
14
14
|
import { processHubReporter } from "./reporter.js";
|
|
15
15
|
import { hubStatusResult } from "./status-output.js";
|
|
16
16
|
import { addHubResolutionHelp } from "./help.js";
|
|
17
|
-
import { addHubInitCommand } from "./init.js";
|
|
17
|
+
import { addHubInitCommand, continueHubGuidedSetup } from "./init.js";
|
|
18
18
|
function productionEnvironment() {
|
|
19
19
|
const env = process.env;
|
|
20
20
|
const hub = new HubHttpClient();
|
|
@@ -37,6 +37,8 @@ export function createHubCommand(overrides = {}) {
|
|
|
37
37
|
credentials: environment.credentials,
|
|
38
38
|
flow: environment.login,
|
|
39
39
|
reporter: environment.reporter,
|
|
40
|
+
isInteractive: environment.isInteractive,
|
|
41
|
+
continueGuidedSetup: (origin) => continueHubGuidedSetup(origin, environment),
|
|
40
42
|
});
|
|
41
43
|
addHubInitCommand(hub, environment);
|
|
42
44
|
addHubConnectCommand(hub, {
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { HubDeployBundle } from "./deploy-bundle.js";
|
|
2
2
|
import type { HubProject } from "./hub-client/index.js";
|
|
3
3
|
import type { HubStatus } from "./daemon-client.js";
|
|
4
|
+
import type { HubStarterAgentRuntime } from "./starter-agent-runtime.js";
|
|
4
5
|
export type HubInitProvider = "github" | "slack" | "discord";
|
|
5
6
|
export type HubInitProjectResolution = {
|
|
6
7
|
kind: "none";
|
|
@@ -30,6 +31,7 @@ export interface HubInitOpeningPlan {
|
|
|
30
31
|
export interface HubInitScaffoldInput {
|
|
31
32
|
cwd: string;
|
|
32
33
|
daemonSlug: string;
|
|
34
|
+
agent: HubStarterAgentRuntime;
|
|
33
35
|
provider: HubInitProvider;
|
|
34
36
|
providerFilters: Readonly<Record<string, string>>;
|
|
35
37
|
}
|
|
@@ -39,6 +41,7 @@ export interface HubInitScaffold {
|
|
|
39
41
|
workflow: string;
|
|
40
42
|
testAction: string;
|
|
41
43
|
}
|
|
44
|
+
export declare function hubLoginResumeCommand(step: "connect" | "init", origin: string): string;
|
|
42
45
|
export declare function planHubInitOpening(input: {
|
|
43
46
|
loggedIn: boolean;
|
|
44
47
|
paseoDirectoryExists: boolean;
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import path from "node:path";
|
|
2
2
|
import YAML from "yaml";
|
|
3
|
+
export function hubLoginResumeCommand(step, origin) {
|
|
4
|
+
return step === "connect" ? `paseo hub connect ${origin}` : "paseo hub init";
|
|
5
|
+
}
|
|
3
6
|
export function planHubInitOpening(input) {
|
|
4
7
|
return {
|
|
5
8
|
replaceExisting: input.paseoDirectoryExists,
|
|
@@ -47,9 +50,10 @@ export function createHubInitScaffold(input) {
|
|
|
47
50
|
},
|
|
48
51
|
},
|
|
49
52
|
agents: {
|
|
50
|
-
|
|
51
|
-
provider:
|
|
52
|
-
|
|
53
|
+
starter: {
|
|
54
|
+
provider: input.agent.provider,
|
|
55
|
+
model: input.agent.model,
|
|
56
|
+
...(input.agent.mode === undefined ? {} : { mode: input.agent.mode }),
|
|
53
57
|
},
|
|
54
58
|
},
|
|
55
59
|
}, { lineWidth: 0 });
|
|
@@ -114,7 +118,7 @@ function workflow(input) {
|
|
|
114
118
|
environment: input.environment,
|
|
115
119
|
max_runtime: "90m",
|
|
116
120
|
idle_timeout: "10m",
|
|
117
|
-
agent: "
|
|
121
|
+
agent: "starter",
|
|
118
122
|
prompt: [
|
|
119
123
|
{
|
|
120
124
|
text: `${replyInstruction}complete this request and call hub.finish_execution when done.\n\n<user-prompt>\n\${{ paseo.prompt }}\n</user-prompt>\n`,
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
+
import { select, text } from "@clack/prompts";
|
|
1
2
|
import type { Command } from "commander";
|
|
2
3
|
import type { HubCredentialStore } from "./credentials.js";
|
|
3
4
|
import type { HubDaemonConnection } from "./daemon-client.js";
|
|
4
5
|
import type { HubHttpClient } from "./hub-client/index.js";
|
|
5
6
|
import type { CliLoginFlow } from "./login-flow.js";
|
|
6
7
|
import type { HubReporter } from "./reporter.js";
|
|
7
|
-
interface
|
|
8
|
+
export interface HubGuidedSetupEnvironment {
|
|
8
9
|
env: Readonly<Record<string, string | undefined>>;
|
|
9
10
|
credentials: HubCredentialStore;
|
|
10
11
|
hub: HubHttpClient;
|
|
@@ -12,9 +13,23 @@ interface HubInitEnvironment {
|
|
|
12
13
|
daemon: HubDaemonConnection;
|
|
13
14
|
reporter: HubReporter;
|
|
14
15
|
cwd(): string;
|
|
16
|
+
isInteractive?(): boolean;
|
|
17
|
+
prompts?: {
|
|
18
|
+
confirm(message: string, initialValue: boolean): Promise<boolean>;
|
|
19
|
+
select(options: Parameters<typeof select<string>>[0]): Promise<string>;
|
|
20
|
+
text(options: Parameters<typeof text>[0]): Promise<string>;
|
|
21
|
+
message(value: string): void;
|
|
22
|
+
};
|
|
15
23
|
}
|
|
16
|
-
|
|
17
|
-
|
|
24
|
+
interface HubGuidedSetupState {
|
|
25
|
+
origin?: string;
|
|
26
|
+
daemonId?: string;
|
|
27
|
+
deploy?: boolean;
|
|
28
|
+
}
|
|
29
|
+
export declare function addHubInitCommand(parent: Command, environment: HubGuidedSetupEnvironment): void;
|
|
30
|
+
export declare function runHubInit(environment: HubGuidedSetupEnvironment): Promise<void>;
|
|
31
|
+
export declare function runHubGuidedSetup(environment: HubGuidedSetupEnvironment, state?: HubGuidedSetupState): Promise<void>;
|
|
32
|
+
export declare function continueHubGuidedSetup(origin: string, environment: HubGuidedSetupEnvironment): Promise<void>;
|
|
18
33
|
export declare function githubRepositoryFromRemote(remote: string): string | undefined;
|
|
19
34
|
export {};
|
|
20
35
|
//# sourceMappingURL=init.d.ts.map
|
|
@@ -7,15 +7,17 @@ import { promisify } from "node:util";
|
|
|
7
7
|
import { DEFAULT_HUB_ORIGIN, resolveHubCredential } from "./authority.js";
|
|
8
8
|
import { withHubDaemon } from "./daemon-client.js";
|
|
9
9
|
import { HubCommandError } from "./error.js";
|
|
10
|
-
import { createHubInitBundle, createHubInitScaffold, planHubInitOpening, resolveHubInitConnection, resolveHubInitProjects, } from "./init-plan.js";
|
|
11
|
-
import { runHubLogin } from "./login.js";
|
|
10
|
+
import { createHubInitBundle, createHubInitScaffold, hubLoginResumeCommand, planHubInitOpening, resolveHubInitConnection, resolveHubInitProjects, } from "./init-plan.js";
|
|
12
11
|
import { runHubConnect } from "./connect.js";
|
|
13
12
|
import { runHubDeployBundle } from "./deploy.js";
|
|
14
13
|
import { runHubProjects } from "./projects.js";
|
|
15
14
|
import { normalizeHubOrigin } from "./origin.js";
|
|
15
|
+
import { selectedStarterAgentRuntime, starterAgentProviderSnapshotState, suggestedStarterAgentChoice, } from "./starter-agent-runtime.js";
|
|
16
|
+
import { availableStarterTriggerConnections, } from "./starter-trigger.js";
|
|
16
17
|
const execFileAsync = promisify(execFile);
|
|
17
18
|
const DAEMON_READY_TIMEOUT_MS = 60000;
|
|
18
19
|
const DAEMON_READY_POLL_MS = 250;
|
|
20
|
+
const PROVIDER_READY_TIMEOUT_MS = 60000;
|
|
19
21
|
class HubInitCancelledError extends Error {
|
|
20
22
|
}
|
|
21
23
|
function initErrorMessage(error) {
|
|
@@ -43,7 +45,10 @@ export function addHubInitCommand(parent, environment) {
|
|
|
43
45
|
});
|
|
44
46
|
}
|
|
45
47
|
export async function runHubInit(environment) {
|
|
46
|
-
|
|
48
|
+
await runHubGuidedSetup(environment);
|
|
49
|
+
}
|
|
50
|
+
export async function runHubGuidedSetup(environment, state = {}) {
|
|
51
|
+
requireInteractiveTerminal(environment);
|
|
47
52
|
intro("Set up Paseo Hub");
|
|
48
53
|
const cwd = environment.cwd();
|
|
49
54
|
const activeLogin = environment.credentials.active();
|
|
@@ -52,24 +57,25 @@ export async function runHubInit(environment) {
|
|
|
52
57
|
paseoDirectoryExists: await pathExists(path.join(cwd, ".paseo")),
|
|
53
58
|
});
|
|
54
59
|
if (opening.replaceExisting &&
|
|
55
|
-
!(await requiredConfirm("Replace the existing .paseo/ Hub bundle?", false))) {
|
|
60
|
+
!(await requiredConfirm(environment, "Replace the existing .paseo/ Hub bundle?", false))) {
|
|
56
61
|
throw new HubInitCancelledError("Existing .paseo/ bundle left unchanged.");
|
|
57
62
|
}
|
|
58
|
-
const origin = await ensureLogin(activeLogin?.origin, environment);
|
|
59
|
-
const daemonId = await ensureDaemonConnection(origin, environment);
|
|
63
|
+
const origin = state.origin ?? (await ensureLogin(activeLogin?.origin, environment));
|
|
64
|
+
const daemonId = state.daemonId ?? (await ensureDaemonConnection(origin, environment));
|
|
60
65
|
const project = await chooseProject(origin, environment);
|
|
61
|
-
const resources = await
|
|
62
|
-
const
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
+
const resources = await loadSetupResources(origin, environment);
|
|
67
|
+
const triggerConnections = await resolveStarterTriggerConnections(resources, cwd);
|
|
68
|
+
reportStarterTriggerConnections(environment, triggerConnections);
|
|
69
|
+
const trigger = await chooseStarterTriggerConnection(environment, triggerConnections);
|
|
70
|
+
const daemon = await loadDaemonResource(origin, daemonId, environment);
|
|
66
71
|
log.success(`Connected as ${daemon.slug}`);
|
|
67
|
-
const
|
|
68
|
-
const providerFilters = await
|
|
72
|
+
const agent = await chooseStarterAgentRuntime(environment, cwd);
|
|
73
|
+
const providerFilters = await collectProviderIdentity(trigger, environment);
|
|
69
74
|
const scaffold = createHubInitScaffold({
|
|
70
75
|
cwd,
|
|
71
76
|
daemonSlug: daemon.slug,
|
|
72
|
-
|
|
77
|
+
agent,
|
|
78
|
+
provider: trigger.provider,
|
|
73
79
|
providerFilters,
|
|
74
80
|
});
|
|
75
81
|
const bundle = createHubInitBundle(project.slug, scaffold);
|
|
@@ -85,7 +91,7 @@ export async function runHubInit(environment) {
|
|
|
85
91
|
log.success("Dry run passed");
|
|
86
92
|
await writeScaffold(cwd, scaffold, opening.replaceExisting);
|
|
87
93
|
log.success(`Created .paseo/hub.yml and ${scaffold.workflowPath}`);
|
|
88
|
-
const deploy = await requiredConfirm("Deploy now?", true);
|
|
94
|
+
const deploy = state.deploy ?? (await requiredConfirm(environment, "Deploy now?", true));
|
|
89
95
|
if (deploy) {
|
|
90
96
|
await withSpinner("Deploying bundle", async () => {
|
|
91
97
|
await runHubDeployBundle({ project: project.slug, hub: origin }, bundle, {
|
|
@@ -99,14 +105,41 @@ export async function runHubInit(environment) {
|
|
|
99
105
|
log.success("Deployed");
|
|
100
106
|
}
|
|
101
107
|
else {
|
|
102
|
-
|
|
108
|
+
reportMessage(environment, `Skipped deployment. Run: paseo hub deploy -p ${project.slug}`);
|
|
103
109
|
}
|
|
104
110
|
const activityUrl = new URL(`/projects/${project.slug}/activity`, origin).toString();
|
|
105
111
|
note(`${scaffold.testAction}\nWatch it at ${activityUrl}`, "Test your workflow");
|
|
106
112
|
outro(deploy ? "Hub is ready" : "Hub bundle is ready");
|
|
107
113
|
}
|
|
114
|
+
export async function continueHubGuidedSetup(origin, environment) {
|
|
115
|
+
if (!(await requiredConfirm(environment, "Connect this daemon to this Hub?", true))) {
|
|
116
|
+
reportMessage(environment, `Skipped daemon connection. Run: ${hubLoginResumeCommand("connect", origin)}; then paseo hub init`);
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
const daemonId = await ensureDaemonConnection(origin, environment, true);
|
|
120
|
+
if (!(await requiredConfirm(environment, "Initialize and deploy a starter workflow?", true))) {
|
|
121
|
+
reportMessage(environment, `Skipped starter workflow. Run: ${hubLoginResumeCommand("init", origin)}`);
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
124
|
+
try {
|
|
125
|
+
await runHubGuidedSetup(environment, { origin, daemonId, deploy: true });
|
|
126
|
+
}
|
|
127
|
+
catch (error) {
|
|
128
|
+
if (error instanceof HubInitCancelledError) {
|
|
129
|
+
if (environment.prompts === undefined) {
|
|
130
|
+
log.message(error.message);
|
|
131
|
+
outro("Connect an app to continue");
|
|
132
|
+
}
|
|
133
|
+
else {
|
|
134
|
+
environment.prompts.message(error.message);
|
|
135
|
+
}
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
throw error;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
108
141
|
async function ensureLogin(activeOrigin, environment) {
|
|
109
|
-
const endpoint = await requiredSelect({
|
|
142
|
+
const endpoint = await requiredSelect(environment, {
|
|
110
143
|
message: "Hub endpoint",
|
|
111
144
|
initialValue: activeOrigin === undefined || activeOrigin === DEFAULT_HUB_ORIGIN ? "hosted" : "custom",
|
|
112
145
|
options: [
|
|
@@ -116,7 +149,7 @@ async function ensureLogin(activeOrigin, environment) {
|
|
|
116
149
|
});
|
|
117
150
|
const origin = endpoint === "hosted"
|
|
118
151
|
? DEFAULT_HUB_ORIGIN
|
|
119
|
-
: await requiredText({
|
|
152
|
+
: await requiredText(environment, {
|
|
120
153
|
message: "Custom Hub URL",
|
|
121
154
|
initialValue: activeOrigin === undefined || activeOrigin === DEFAULT_HUB_ORIGIN
|
|
122
155
|
? environment.env.PASEO_HUB_URL
|
|
@@ -136,16 +169,13 @@ async function ensureLogin(activeOrigin, environment) {
|
|
|
136
169
|
log.success(`Logged in to ${normalizedOrigin}`);
|
|
137
170
|
return normalizedOrigin;
|
|
138
171
|
}
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
flow: environment.login,
|
|
143
|
-
reporter: environment.reporter,
|
|
144
|
-
});
|
|
172
|
+
environment.reporter.progress(`Logging in to ${normalizedOrigin}`);
|
|
173
|
+
const credential = await environment.login.authorize(normalizedOrigin);
|
|
174
|
+
environment.credentials.save({ origin: normalizedOrigin, credential });
|
|
145
175
|
log.success(`Logged in to ${normalizedOrigin}`);
|
|
146
176
|
return normalizedOrigin;
|
|
147
177
|
}
|
|
148
|
-
async function ensureDaemonConnection(origin, environment) {
|
|
178
|
+
async function ensureDaemonConnection(origin, environment, confirmed = false) {
|
|
149
179
|
const status = await withHubDaemon(environment.daemon, undefined, async (daemon) => daemon.getHubStatus().then((response) => response.status));
|
|
150
180
|
const connection = resolveHubInitConnection(status, origin);
|
|
151
181
|
if (connection.kind === "connected") {
|
|
@@ -157,9 +187,13 @@ async function ensureDaemonConnection(origin, environment) {
|
|
|
157
187
|
if (connection.kind === "conflict") {
|
|
158
188
|
throw new HubCommandError("HUB_DAEMON_ALREADY_CONNECTED", `This daemon is connected to ${connection.origin}. Disconnect it before running Hub init for ${origin}.`);
|
|
159
189
|
}
|
|
160
|
-
if (!
|
|
190
|
+
if (!confirmed &&
|
|
191
|
+
!(await requiredConfirm(environment, `Connect this daemon to ${origin}?`, true))) {
|
|
161
192
|
throw new HubInitCancelledError("A connected daemon is required to create the bundle.");
|
|
162
193
|
}
|
|
194
|
+
return connectDaemon(origin, environment);
|
|
195
|
+
}
|
|
196
|
+
async function connectDaemon(origin, environment) {
|
|
163
197
|
await runHubConnect(origin, {}, {
|
|
164
198
|
env: environment.env,
|
|
165
199
|
credentials: environment.credentials,
|
|
@@ -205,7 +239,7 @@ async function chooseProject(origin, environment) {
|
|
|
205
239
|
if (resolution.kind === "selected") {
|
|
206
240
|
return resolution.project;
|
|
207
241
|
}
|
|
208
|
-
const slug = await requiredSelect({
|
|
242
|
+
const slug = await requiredSelect(environment, {
|
|
209
243
|
message: "Project",
|
|
210
244
|
options: resolution.projects.map((project) => ({
|
|
211
245
|
value: project.slug,
|
|
@@ -219,56 +253,146 @@ async function chooseProject(origin, environment) {
|
|
|
219
253
|
}
|
|
220
254
|
return project;
|
|
221
255
|
}
|
|
222
|
-
async function
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
256
|
+
async function resolveStarterTriggerConnections(resources, cwd) {
|
|
257
|
+
const remote = await readCommandValue("git", ["remote", "get-url", "origin"], cwd);
|
|
258
|
+
const repository = remote === undefined ? undefined : githubRepositoryFromRemote(remote);
|
|
259
|
+
const connections = availableStarterTriggerConnections(resources, repository);
|
|
260
|
+
if (connections.length === 0) {
|
|
261
|
+
throw new HubInitCancelledError("No Hub app connection is ready for this workflow.\nConnect GitHub, Slack, or Discord in Hub → Apps, then run `paseo hub init` again.");
|
|
262
|
+
}
|
|
263
|
+
return connections;
|
|
264
|
+
}
|
|
265
|
+
function reportStarterTriggerConnections(environment, connections) {
|
|
266
|
+
const details = `${connections.map(({ label }) => label).join("\n")}\n\nOnly configured connections are shown. To add another, open Hub → Apps, then run \`paseo hub init\` again.`;
|
|
267
|
+
if (environment.prompts === undefined) {
|
|
268
|
+
note(details, "Hub app connections ready for this workflow");
|
|
269
|
+
return;
|
|
270
|
+
}
|
|
271
|
+
environment.prompts.message(`Hub app connections ready for this workflow:\n${details}`);
|
|
272
|
+
}
|
|
273
|
+
async function chooseStarterTriggerConnection(environment, connections) {
|
|
274
|
+
if (connections.length === 1) {
|
|
275
|
+
const connection = connections[0];
|
|
276
|
+
reportMessage(environment, `Using ${connection.label}`);
|
|
277
|
+
return connection;
|
|
278
|
+
}
|
|
279
|
+
const id = await requiredSelect(environment, {
|
|
280
|
+
message: "Trigger connection",
|
|
281
|
+
options: connections.map((connection) => ({ value: connection.id, label: connection.label })),
|
|
230
282
|
});
|
|
283
|
+
const connection = connections.find((candidate) => candidate.id === id);
|
|
284
|
+
if (connection === undefined) {
|
|
285
|
+
throw new HubCommandError("HUB_PROVIDER_CONNECTION_INVALID", "The selected Hub app connection is no longer available. Run paseo hub init again.");
|
|
286
|
+
}
|
|
287
|
+
return connection;
|
|
231
288
|
}
|
|
232
|
-
async function
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
289
|
+
async function chooseStarterAgentRuntime(environment, cwd) {
|
|
290
|
+
const providers = await waitForStarterAgentProviders(environment, cwd);
|
|
291
|
+
const provider = await chooseStarterAgentProvider(environment, providers);
|
|
292
|
+
const model = await chooseStarterAgentModel(environment, provider);
|
|
293
|
+
const mode = await chooseStarterAgentMode(environment, provider);
|
|
294
|
+
const runtime = selectedStarterAgentRuntime(provider, model, mode);
|
|
295
|
+
if (runtime === undefined) {
|
|
296
|
+
throw new HubCommandError("HUB_AGENT_RUNTIME_SELECTION_INVALID", "The selected starter agent runtime is no longer available. Run paseo hub init again.");
|
|
297
|
+
}
|
|
298
|
+
return runtime;
|
|
299
|
+
}
|
|
300
|
+
async function waitForStarterAgentProviders(environment, cwd) {
|
|
301
|
+
return withSpinner("Discovering agent runtimes", async (reporter) => withHubDaemon(environment.daemon, undefined, async (daemon) => {
|
|
302
|
+
const deadline = Date.now() + PROVIDER_READY_TIMEOUT_MS;
|
|
303
|
+
while (true) {
|
|
304
|
+
const snapshot = await daemon.getProvidersSnapshot({ cwd });
|
|
305
|
+
const state = starterAgentProviderSnapshotState(snapshot.entries);
|
|
306
|
+
if (state.kind === "ready")
|
|
307
|
+
return state.providers;
|
|
308
|
+
if (state.kind === "unavailable") {
|
|
309
|
+
throw new HubCommandError("HUB_AGENT_RUNTIME_REQUIRED", "No usable agent runtime is available from this daemon. Configure an enabled provider with a selectable model, then run paseo hub init again.");
|
|
310
|
+
}
|
|
311
|
+
if (Date.now() >= deadline) {
|
|
312
|
+
throw new HubCommandError("HUB_AGENT_RUNTIME_TIMEOUT", "Agent runtime discovery did not finish within 60 seconds. Check the daemon's provider configuration, then run paseo hub init again.");
|
|
313
|
+
}
|
|
314
|
+
reporter.progress("Waiting for agent runtime discovery");
|
|
315
|
+
await delay(DAEMON_READY_POLL_MS);
|
|
245
316
|
}
|
|
317
|
+
}));
|
|
318
|
+
}
|
|
319
|
+
async function chooseStarterAgentProvider(environment, providers) {
|
|
320
|
+
const selected = await requiredSelect(environment, {
|
|
321
|
+
message: "Starter agent provider",
|
|
322
|
+
options: providers.map((provider) => ({
|
|
323
|
+
value: provider.id,
|
|
324
|
+
label: provider.label,
|
|
325
|
+
})),
|
|
326
|
+
});
|
|
327
|
+
const provider = providers.find((candidate) => candidate.id === selected);
|
|
328
|
+
if (provider === undefined)
|
|
329
|
+
throw invalidStarterAgentSelection();
|
|
330
|
+
return provider;
|
|
331
|
+
}
|
|
332
|
+
async function chooseStarterAgentModel(environment, provider) {
|
|
333
|
+
const suggested = suggestedStarterAgentChoice(provider.models);
|
|
334
|
+
const selected = await requiredSelect(environment, {
|
|
335
|
+
message: "Starter agent model",
|
|
336
|
+
...(suggested === undefined ? {} : { initialValue: suggested.id }),
|
|
337
|
+
options: provider.models.map((model) => ({
|
|
338
|
+
value: model.id,
|
|
339
|
+
label: model.label,
|
|
340
|
+
...(model.suggested ? { hint: "suggested" } : {}),
|
|
341
|
+
})),
|
|
342
|
+
});
|
|
343
|
+
if (!provider.models.some((model) => model.id === selected))
|
|
344
|
+
throw invalidStarterAgentSelection();
|
|
345
|
+
return selected;
|
|
346
|
+
}
|
|
347
|
+
async function chooseStarterAgentMode(environment, provider) {
|
|
348
|
+
if (provider.modes.length === 0)
|
|
349
|
+
return undefined;
|
|
350
|
+
const suggested = suggestedStarterAgentChoice(provider.modes);
|
|
351
|
+
const selected = await requiredSelect(environment, {
|
|
352
|
+
message: "Starter agent mode",
|
|
353
|
+
...(suggested === undefined ? {} : { initialValue: suggested.id }),
|
|
354
|
+
options: provider.modes.map((mode) => ({
|
|
355
|
+
value: mode.id,
|
|
356
|
+
label: mode.label,
|
|
357
|
+
...(mode.suggested ? { hint: "suggested" } : {}),
|
|
358
|
+
})),
|
|
359
|
+
});
|
|
360
|
+
if (!provider.modes.some((mode) => mode.id === selected))
|
|
361
|
+
throw invalidStarterAgentSelection();
|
|
362
|
+
return selected;
|
|
363
|
+
}
|
|
364
|
+
function invalidStarterAgentSelection() {
|
|
365
|
+
return new HubCommandError("HUB_AGENT_RUNTIME_SELECTION_INVALID", "The selected starter agent runtime is no longer available. Run paseo hub init again.");
|
|
366
|
+
}
|
|
367
|
+
async function collectProviderIdentity(trigger, environment) {
|
|
368
|
+
if (trigger.provider === "github") {
|
|
369
|
+
const login = await readGhValue(["api", "user", "--jq", ".login"]);
|
|
246
370
|
return {
|
|
247
|
-
|
|
371
|
+
...trigger.filters,
|
|
372
|
+
user: await requiredText(environment, {
|
|
248
373
|
message: "Your GitHub username (only this user can trigger the bot)",
|
|
249
374
|
initialValue: login,
|
|
250
375
|
}),
|
|
251
|
-
repo,
|
|
252
376
|
};
|
|
253
377
|
}
|
|
254
|
-
if (provider === "slack") {
|
|
378
|
+
if (trigger.provider === "slack") {
|
|
255
379
|
return {
|
|
256
|
-
|
|
257
|
-
user: await requiredText({
|
|
258
|
-
message: "Your Slack
|
|
380
|
+
...trigger.filters,
|
|
381
|
+
user: await requiredText(environment, {
|
|
382
|
+
message: "Your Slack member ID (only this user can trigger the bot)",
|
|
259
383
|
}),
|
|
260
384
|
};
|
|
261
385
|
}
|
|
262
386
|
return {
|
|
263
|
-
|
|
264
|
-
user: await requiredText({
|
|
265
|
-
message: "Your Discord
|
|
387
|
+
...trigger.filters,
|
|
388
|
+
user: await requiredText(environment, {
|
|
389
|
+
message: "Your Discord user ID (only this user can trigger the bot)",
|
|
266
390
|
}),
|
|
267
391
|
};
|
|
268
392
|
}
|
|
269
|
-
async function
|
|
393
|
+
async function loadSetupResources(origin, environment) {
|
|
270
394
|
try {
|
|
271
|
-
return await withSpinner("Loading Hub connections", () => environment.hub.
|
|
395
|
+
return await withSpinner("Loading Hub connections", () => environment.hub.listSetupResources(origin, resolveHubCredential({
|
|
272
396
|
options: { origin },
|
|
273
397
|
env: environment.env,
|
|
274
398
|
credentials: environment.credentials,
|
|
@@ -277,21 +401,23 @@ async function loadConfigurationResources(origin, environment) {
|
|
|
277
401
|
}
|
|
278
402
|
catch (error) {
|
|
279
403
|
if (error instanceof HubCommandError && error.code === "HUB_NOT_FOUND") {
|
|
280
|
-
throw new HubCommandError("HUB_UPDATE_REQUIRED", "This Hub
|
|
404
|
+
throw new HubCommandError("HUB_UPDATE_REQUIRED", "This Hub needs an update before guided setup can use provider IDs. Update Hub and try again.");
|
|
281
405
|
}
|
|
282
406
|
throw error;
|
|
283
407
|
}
|
|
284
408
|
}
|
|
285
|
-
async function
|
|
286
|
-
|
|
287
|
-
|
|
409
|
+
async function loadDaemonResource(origin, daemonId, environment) {
|
|
410
|
+
const resources = await environment.hub.listConfigurationResources(origin, resolveHubCredential({
|
|
411
|
+
options: { origin },
|
|
412
|
+
env: environment.env,
|
|
413
|
+
credentials: environment.credentials,
|
|
414
|
+
origin,
|
|
415
|
+
}));
|
|
416
|
+
const daemon = resources.daemons.find(({ id }) => id === daemonId);
|
|
417
|
+
if (daemon === undefined) {
|
|
418
|
+
throw new HubCommandError("HUB_DAEMON_RESOURCE_MISSING", "The connected daemon is not available in this Hub organization. Reconnect it and try again.");
|
|
288
419
|
}
|
|
289
|
-
|
|
290
|
-
return connections[0].slug;
|
|
291
|
-
return requiredSelect({
|
|
292
|
-
message,
|
|
293
|
-
options: connections.map(({ slug, label }) => ({ value: slug, label })),
|
|
294
|
-
});
|
|
420
|
+
return daemon;
|
|
295
421
|
}
|
|
296
422
|
async function writeScaffold(cwd, scaffold, replaceExisting) {
|
|
297
423
|
const root = path.join(cwd, ".paseo");
|
|
@@ -380,8 +506,8 @@ async function withSpinner(message, action) {
|
|
|
380
506
|
throw error;
|
|
381
507
|
}
|
|
382
508
|
}
|
|
383
|
-
async function requiredText(options) {
|
|
384
|
-
const
|
|
509
|
+
async function requiredText(environment, options) {
|
|
510
|
+
const request = {
|
|
385
511
|
...options,
|
|
386
512
|
validate(value) {
|
|
387
513
|
const input = value ?? "";
|
|
@@ -390,26 +516,40 @@ async function requiredText(options) {
|
|
|
390
516
|
return customError;
|
|
391
517
|
return input.trim().length === 0 ? "A value is required" : undefined;
|
|
392
518
|
},
|
|
393
|
-
}
|
|
519
|
+
};
|
|
520
|
+
const answer = environment.prompts === undefined
|
|
521
|
+
? await text(request)
|
|
522
|
+
: await environment.prompts.text(request);
|
|
394
523
|
if (isCancel(answer))
|
|
395
524
|
throw new HubInitCancelledError("Hub init cancelled.");
|
|
396
525
|
return answer.trim();
|
|
397
526
|
}
|
|
398
|
-
async function requiredConfirm(message, initialValue) {
|
|
399
|
-
const answer =
|
|
527
|
+
async function requiredConfirm(environment, message, initialValue) {
|
|
528
|
+
const answer = environment.prompts === undefined
|
|
529
|
+
? await confirm({ message, initialValue })
|
|
530
|
+
: await environment.prompts.confirm(message, initialValue);
|
|
400
531
|
if (isCancel(answer))
|
|
401
532
|
throw new HubInitCancelledError("Hub init cancelled.");
|
|
402
533
|
return answer;
|
|
403
534
|
}
|
|
404
|
-
async function requiredSelect(options) {
|
|
405
|
-
const answer =
|
|
535
|
+
async function requiredSelect(environment, options) {
|
|
536
|
+
const answer = environment.prompts === undefined
|
|
537
|
+
? await select(options)
|
|
538
|
+
: (await environment.prompts.select(options));
|
|
406
539
|
if (isCancel(answer))
|
|
407
540
|
throw new HubInitCancelledError("Hub init cancelled.");
|
|
408
541
|
return answer;
|
|
409
542
|
}
|
|
410
|
-
function requireInteractiveTerminal() {
|
|
411
|
-
if (!process.stdin.isTTY
|
|
543
|
+
function requireInteractiveTerminal(environment) {
|
|
544
|
+
if (!(environment.isInteractive?.() ?? (process.stdin.isTTY && process.stdout.isTTY))) {
|
|
412
545
|
throw new HubCommandError("HUB_INIT_INTERACTIVE_REQUIRED", "paseo hub init requires a TTY.");
|
|
413
546
|
}
|
|
414
547
|
}
|
|
548
|
+
function reportMessage(environment, message) {
|
|
549
|
+
if (environment.prompts === undefined) {
|
|
550
|
+
log.message(message);
|
|
551
|
+
return;
|
|
552
|
+
}
|
|
553
|
+
environment.prompts.message(message);
|
|
554
|
+
}
|
|
415
555
|
//# sourceMappingURL=init.js.map
|
|
@@ -12,6 +12,8 @@ interface HubLoginDependencies {
|
|
|
12
12
|
credentials: HubCredentialStore;
|
|
13
13
|
flow: Pick<CliLoginFlow, "authorize">;
|
|
14
14
|
reporter: HubReporter;
|
|
15
|
+
isInteractive?(): boolean;
|
|
16
|
+
continueGuidedSetup?(origin: string): Promise<void>;
|
|
15
17
|
}
|
|
16
18
|
export declare function runHubLogin(originInput: string | undefined, options: {
|
|
17
19
|
json?: boolean;
|
|
@@ -19,6 +19,12 @@ export async function runHubLogin(originInput, options, dependencies) {
|
|
|
19
19
|
reportHubProgress(dependencies.reporter, options, `Logging in to ${origin}`);
|
|
20
20
|
const credential = await dependencies.flow.authorize(origin);
|
|
21
21
|
dependencies.credentials.save({ origin, credential });
|
|
22
|
+
reportHubProgress(dependencies.reporter, options, "Logged in");
|
|
23
|
+
if (!options.json &&
|
|
24
|
+
dependencies.isInteractive?.() &&
|
|
25
|
+
dependencies.continueGuidedSetup !== undefined) {
|
|
26
|
+
await dependencies.continueGuidedSetup(origin);
|
|
27
|
+
}
|
|
22
28
|
return { type: "single", data: { origin, status: "logged_in" }, schema };
|
|
23
29
|
}
|
|
24
30
|
export function addHubLoginCommand(parent, dependencies) {
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import type { ProviderSnapshotEntry } from "@getpaseo/protocol/agent-types";
|
|
2
|
+
export interface HubStarterAgentRuntime {
|
|
3
|
+
provider: string;
|
|
4
|
+
model: string;
|
|
5
|
+
mode?: string;
|
|
6
|
+
}
|
|
7
|
+
export interface HubStarterAgentProvider {
|
|
8
|
+
id: string;
|
|
9
|
+
label: string;
|
|
10
|
+
models: readonly HubStarterAgentModel[];
|
|
11
|
+
modes: readonly HubStarterAgentMode[];
|
|
12
|
+
}
|
|
13
|
+
export interface HubStarterAgentModel {
|
|
14
|
+
id: string;
|
|
15
|
+
label: string;
|
|
16
|
+
suggested: boolean;
|
|
17
|
+
}
|
|
18
|
+
export interface HubStarterAgentMode {
|
|
19
|
+
id: string;
|
|
20
|
+
label: string;
|
|
21
|
+
suggested: boolean;
|
|
22
|
+
}
|
|
23
|
+
export type HubStarterAgentProviderSnapshotState = {
|
|
24
|
+
kind: "ready";
|
|
25
|
+
providers: readonly HubStarterAgentProvider[];
|
|
26
|
+
} | {
|
|
27
|
+
kind: "loading";
|
|
28
|
+
} | {
|
|
29
|
+
kind: "unavailable";
|
|
30
|
+
};
|
|
31
|
+
export declare function availableStarterAgentProviders(entries: readonly ProviderSnapshotEntry[]): HubStarterAgentProvider[];
|
|
32
|
+
export declare function starterAgentProviderSnapshotState(entries: readonly ProviderSnapshotEntry[]): HubStarterAgentProviderSnapshotState;
|
|
33
|
+
export declare function suggestedStarterAgentChoice<T extends {
|
|
34
|
+
suggested: boolean;
|
|
35
|
+
}>(choices: readonly T[]): T | undefined;
|
|
36
|
+
export declare function selectedStarterAgentRuntime(provider: HubStarterAgentProvider, modelId: string, modeId?: string): HubStarterAgentRuntime | undefined;
|
|
37
|
+
//# sourceMappingURL=starter-agent-runtime.d.ts.map
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
export function availableStarterAgentProviders(entries) {
|
|
2
|
+
return entries.flatMap((entry) => {
|
|
3
|
+
if (entry.status !== "ready" || !entry.enabled)
|
|
4
|
+
return [];
|
|
5
|
+
const models = (entry.models ?? [])
|
|
6
|
+
.filter((model) => model.isSelectable !== false)
|
|
7
|
+
.map((model) => ({ id: model.id, label: model.label, suggested: model.isDefault === true }));
|
|
8
|
+
if (models.length === 0)
|
|
9
|
+
return [];
|
|
10
|
+
const modes = (entry.modes ?? []).map((mode) => ({
|
|
11
|
+
id: mode.id,
|
|
12
|
+
label: mode.label,
|
|
13
|
+
suggested: mode.id === entry.defaultModeId,
|
|
14
|
+
}));
|
|
15
|
+
return [
|
|
16
|
+
{
|
|
17
|
+
id: entry.provider,
|
|
18
|
+
label: entry.label ?? entry.provider,
|
|
19
|
+
models,
|
|
20
|
+
modes,
|
|
21
|
+
},
|
|
22
|
+
];
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
export function starterAgentProviderSnapshotState(entries) {
|
|
26
|
+
const providers = availableStarterAgentProviders(entries);
|
|
27
|
+
if (providers.length > 0)
|
|
28
|
+
return { kind: "ready", providers };
|
|
29
|
+
if (entries.length === 0)
|
|
30
|
+
return { kind: "loading" };
|
|
31
|
+
if (entries.some((entry) => entry.enabled && entry.status === "loading")) {
|
|
32
|
+
return { kind: "loading" };
|
|
33
|
+
}
|
|
34
|
+
return { kind: "unavailable" };
|
|
35
|
+
}
|
|
36
|
+
export function suggestedStarterAgentChoice(choices) {
|
|
37
|
+
return choices.find((choice) => choice.suggested);
|
|
38
|
+
}
|
|
39
|
+
export function selectedStarterAgentRuntime(provider, modelId, modeId) {
|
|
40
|
+
if (!provider.models.some((model) => model.id === modelId))
|
|
41
|
+
return undefined;
|
|
42
|
+
if (provider.modes.length === 0) {
|
|
43
|
+
return modeId === undefined ? { provider: provider.id, model: modelId } : undefined;
|
|
44
|
+
}
|
|
45
|
+
if (modeId === undefined || !provider.modes.some((mode) => mode.id === modeId))
|
|
46
|
+
return undefined;
|
|
47
|
+
return { provider: provider.id, model: modelId, mode: modeId };
|
|
48
|
+
}
|
|
49
|
+
//# sourceMappingURL=starter-agent-runtime.js.map
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { HubSetupResources } from "./hub-client/index.js";
|
|
2
|
+
import type { HubInitProvider } from "./init-plan.js";
|
|
3
|
+
export interface HubStarterTriggerConnection {
|
|
4
|
+
id: string;
|
|
5
|
+
label: string;
|
|
6
|
+
provider: HubInitProvider;
|
|
7
|
+
filters: Readonly<Record<string, string>>;
|
|
8
|
+
}
|
|
9
|
+
export declare function availableStarterTriggerConnections(resources: HubSetupResources, githubRepository?: string): HubStarterTriggerConnection[];
|
|
10
|
+
//# sourceMappingURL=starter-trigger.d.ts.map
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
export function availableStarterTriggerConnections(resources, githubRepository) {
|
|
2
|
+
return [
|
|
3
|
+
...(githubRepository !== undefined &&
|
|
4
|
+
resources.github.some(({ repositories }) => repositories.includes(githubRepository))
|
|
5
|
+
? [
|
|
6
|
+
{
|
|
7
|
+
id: `github:${githubRepository}`,
|
|
8
|
+
label: `GitHub — ${githubRepository}`,
|
|
9
|
+
provider: "github",
|
|
10
|
+
filters: { repo: githubRepository },
|
|
11
|
+
},
|
|
12
|
+
]
|
|
13
|
+
: []),
|
|
14
|
+
...resources.slack.map(({ teamId, teamName }) => ({
|
|
15
|
+
id: `slack:${teamId}`,
|
|
16
|
+
label: `Slack — ${teamName}`,
|
|
17
|
+
provider: "slack",
|
|
18
|
+
filters: { workspace: teamId },
|
|
19
|
+
})),
|
|
20
|
+
...resources.discord.map(({ guildId, guildName }) => ({
|
|
21
|
+
id: `discord:${guildId}`,
|
|
22
|
+
label: `Discord — ${guildName}`,
|
|
23
|
+
provider: "discord",
|
|
24
|
+
filters: { guild: guildId },
|
|
25
|
+
})),
|
|
26
|
+
];
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=starter-trigger.js.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@getpaseo/cli",
|
|
3
|
-
"version": "0.5.0-beta.
|
|
3
|
+
"version": "0.5.0-beta.5",
|
|
4
4
|
"description": "Paseo CLI - control your AI coding agents from the command line",
|
|
5
5
|
"bin": {
|
|
6
6
|
"paseo": "bin/paseo"
|
|
@@ -28,9 +28,9 @@
|
|
|
28
28
|
},
|
|
29
29
|
"dependencies": {
|
|
30
30
|
"@clack/prompts": "^1.0.0",
|
|
31
|
-
"@getpaseo/client": "0.5.0-beta.
|
|
32
|
-
"@getpaseo/protocol": "0.5.0-beta.
|
|
33
|
-
"@getpaseo/server": "0.5.0-beta.
|
|
31
|
+
"@getpaseo/client": "0.5.0-beta.5",
|
|
32
|
+
"@getpaseo/protocol": "0.5.0-beta.5",
|
|
33
|
+
"@getpaseo/server": "0.5.0-beta.5",
|
|
34
34
|
"chalk": "^5.3.0",
|
|
35
35
|
"commander": "^12.0.0",
|
|
36
36
|
"mime-types": "^2.1.35",
|