@autohq/cli 0.1.132 → 0.1.134
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/agent-bridge.js +46 -39
- package/dist/index.js +292 -272
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -16052,7 +16052,7 @@ var init_zod = __esm({
|
|
|
16052
16052
|
});
|
|
16053
16053
|
|
|
16054
16054
|
// ../../packages/schemas/src/ids.ts
|
|
16055
|
-
var OpaqueIdSchema, ProfileIdSchema, EnvironmentIdSchema, IdentityIdSchema, ConnectionIdSchema, ExternalAccountIdSchema, OrganizationIdSchema, ProjectIdSchema, ProviderGrantIdSchema, ServiceAccountIdSchema, SessionIdSchema, SessionRunIdSchema, SessionRunCommandIdSchema, RuntimeIdSchema, RuntimeBridgeLeaseIdSchema, EnvironmentSetupSnapshotIdSchema,
|
|
16055
|
+
var OpaqueIdSchema, ProfileIdSchema, EnvironmentIdSchema, IdentityIdSchema, ConnectionIdSchema, ExternalAccountIdSchema, OrganizationIdSchema, ProjectIdSchema, ProviderGrantIdSchema, ServiceAccountIdSchema, SessionIdSchema, SessionRunIdSchema, SessionRunCommandIdSchema, RuntimeIdSchema, RuntimeBridgeLeaseIdSchema, EnvironmentSetupSnapshotIdSchema, UserIdSchema;
|
|
16056
16056
|
var init_ids = __esm({
|
|
16057
16057
|
"../../packages/schemas/src/ids.ts"() {
|
|
16058
16058
|
"use strict";
|
|
@@ -16073,7 +16073,6 @@ var init_ids = __esm({
|
|
|
16073
16073
|
RuntimeIdSchema = OpaqueIdSchema.brand();
|
|
16074
16074
|
RuntimeBridgeLeaseIdSchema = OpaqueIdSchema.brand();
|
|
16075
16075
|
EnvironmentSetupSnapshotIdSchema = OpaqueIdSchema.brand();
|
|
16076
|
-
ToolIdSchema = OpaqueIdSchema.brand();
|
|
16077
16076
|
UserIdSchema = OpaqueIdSchema.brand();
|
|
16078
16077
|
}
|
|
16079
16078
|
});
|
|
@@ -17603,7 +17602,7 @@ function remoteMcpToolSchema(input) {
|
|
|
17603
17602
|
]).default({ kind: "none" })
|
|
17604
17603
|
});
|
|
17605
17604
|
}
|
|
17606
|
-
var
|
|
17605
|
+
var REMOTE_MCP_TRANSPORTS, LOCAL_TOOL_IMPLEMENTATIONS, SecretReferenceSchema, NoToolAuthSchema, McpOAuthToolAuthSchema, ConnectionToolAuthSchema, ConnectionsToolAuthSchema, ToolAliasSchema, RemoteMcpToolSchema, LocalAutoToolSchema, LocalPingToolSchema, LocalChatToolSchema, LocalToolSchema, GithubToolSchema, ToolSpecSchema, SessionToolConnectRequestSchema, SessionToolConnectResponseSchema, SessionToolConnectCompleteResponseSchema, InlineSessionToolSchema, SessionToolRefSchema, SessionToolsSchema;
|
|
17607
17606
|
var init_tools = __esm({
|
|
17608
17607
|
"../../packages/schemas/src/tools.ts"() {
|
|
17609
17608
|
"use strict";
|
|
@@ -17612,7 +17611,6 @@ var init_tools = __esm({
|
|
|
17612
17611
|
init_github_mcp_catalog();
|
|
17613
17612
|
init_ids();
|
|
17614
17613
|
init_resources();
|
|
17615
|
-
RESOURCE_KIND_TOOL = "tool";
|
|
17616
17614
|
REMOTE_MCP_TRANSPORTS = ["streamable_http"];
|
|
17617
17615
|
LOCAL_TOOL_IMPLEMENTATIONS = ["auto", "chat", "ping"];
|
|
17618
17616
|
SecretReferenceSchema = external_exports.object({
|
|
@@ -17676,9 +17674,7 @@ var init_tools = __esm({
|
|
|
17676
17674
|
RemoteMcpToolSchema,
|
|
17677
17675
|
LocalToolSchema
|
|
17678
17676
|
]);
|
|
17679
|
-
|
|
17680
|
-
ToolApplyRequestSchema = resourceApplySchema(ToolSpecSchema);
|
|
17681
|
-
ToolConnectRequestSchema = external_exports.object({
|
|
17677
|
+
SessionToolConnectRequestSchema = external_exports.object({
|
|
17682
17678
|
redirectUri: external_exports.string().trim().url().refine(
|
|
17683
17679
|
(value) => {
|
|
17684
17680
|
const url2 = new URL(value);
|
|
@@ -17688,21 +17684,23 @@ var init_tools = __esm({
|
|
|
17688
17684
|
return url2.protocol === "http:" && (url2.hostname === "localhost" || url2.hostname === "127.0.0.1");
|
|
17689
17685
|
},
|
|
17690
17686
|
{
|
|
17691
|
-
message: "
|
|
17687
|
+
message: "Session tool OAuth redirect URIs must use https, except localhost loopback callbacks may use http"
|
|
17692
17688
|
}
|
|
17693
17689
|
).optional()
|
|
17694
17690
|
});
|
|
17695
|
-
|
|
17691
|
+
SessionToolConnectResponseSchema = external_exports.discriminatedUnion("status", [
|
|
17696
17692
|
external_exports.object({
|
|
17697
17693
|
status: external_exports.literal("authorization_required"),
|
|
17694
|
+
session: ResourceNameSchema,
|
|
17698
17695
|
tool: ResourceNameSchema,
|
|
17699
17696
|
connection: ResourceNameSchema,
|
|
17700
17697
|
authorizationUrl: external_exports.string().trim().url(),
|
|
17701
17698
|
message: external_exports.string().trim().min(1)
|
|
17702
17699
|
})
|
|
17703
17700
|
]);
|
|
17704
|
-
|
|
17701
|
+
SessionToolConnectCompleteResponseSchema = external_exports.object({
|
|
17705
17702
|
status: external_exports.literal("connected"),
|
|
17703
|
+
session: ResourceNameSchema.optional(),
|
|
17706
17704
|
tool: ResourceNameSchema,
|
|
17707
17705
|
connection: ResourceNameSchema,
|
|
17708
17706
|
projectId: ProjectIdSchema
|
|
@@ -18055,7 +18053,7 @@ function isChatMessageEvent(trigger) {
|
|
|
18055
18053
|
function hasFilterValue(trigger, path2, expected) {
|
|
18056
18054
|
return trigger.where?.[path2] === expected;
|
|
18057
18055
|
}
|
|
18058
|
-
var RESOURCE_KIND_SESSION, SESSION_HARNESSES, TriggerFilterScalarSchema, TriggerFilterPathSchema, TriggerFilterClauseSchema, TriggerFilterSchema, SessionTriggerCheckTimeoutSchema, TriggerEventSchema, TriggerEventsSchema, SessionTriggerSharedFields, SessionTriggerEventSourceFields, SessionTriggerBaseSchema, SessionTriggerDefinitionBaseSchema, SessionTriggerSchema, SessionApplyTriggerSchema, SessionHeartbeatTriggerBaseSchema, SessionHeartbeatTriggerSchema, SessionApplyHeartbeatTriggerSchema, SessionTriggerDefinitionSchema, SessionApplyTriggerDefinitionSchema, SessionTriggersSchema, SessionApplyTriggersSchema, AVATAR_ASSET_EXTENSIONS, MAX_AVATAR_ASSET_BYTES, MIN_AVATAR_ASSET_DIMENSION_PX, MAX_AVATAR_ASSET_DIMENSION_PX, PNG_SIGNATURE, SESSION_IDENTITY_DESCRIPTION_MAX_LENGTH, SHA256_HEX_PATTERN, SessionIdentitySchema, SessionSpecFieldsSchema, SessionSpecSchema, SessionApplySpecSchema, SessionStatusSchema, SessionResourceSchema, SessionApplyRequestSchema, SessionApplyTriggerReceiptSchema, SessionApplyResponseSchema, SESSION_TELEGRAM_IDENTITY_STATUSES, SessionTelegramIdentityStatusSchema, SessionPresenceIdentitySchema, SessionPresenceResponseSchema, SessionPresenceConnectRequestSchema, SessionPresenceConnectPendingSchema, SessionPresenceConnectResponseSchema, SessionPresenceIconRequestSchema, SessionPresenceIconResponseSchema, SessionPresenceCompleteResponseSchema;
|
|
18056
|
+
var RESOURCE_KIND_AGENT, LEGACY_RESOURCE_KIND_SESSION, RESOURCE_KIND_SESSION, SESSION_HARNESSES, TriggerFilterScalarSchema, TriggerFilterPathSchema, TriggerFilterClauseSchema, TriggerFilterSchema, SessionTriggerCheckTimeoutSchema, TriggerEventSchema, TriggerEventsSchema, SessionTriggerSharedFields, SessionTriggerEventSourceFields, SessionTriggerBaseSchema, SessionTriggerDefinitionBaseSchema, SessionTriggerSchema, SessionApplyTriggerSchema, SessionHeartbeatTriggerBaseSchema, SessionHeartbeatTriggerSchema, SessionApplyHeartbeatTriggerSchema, SessionTriggerDefinitionSchema, SessionApplyTriggerDefinitionSchema, SessionTriggersSchema, SessionApplyTriggersSchema, AVATAR_ASSET_EXTENSIONS, MAX_AVATAR_ASSET_BYTES, MIN_AVATAR_ASSET_DIMENSION_PX, MAX_AVATAR_ASSET_DIMENSION_PX, PNG_SIGNATURE, SESSION_IDENTITY_DESCRIPTION_MAX_LENGTH, SHA256_HEX_PATTERN, SessionIdentitySchema, SessionSpecFieldsSchema, SessionSpecSchema, SessionApplySpecSchema, SessionStatusSchema, SessionResourceSchema, SessionApplyRequestSchema, SessionApplyTriggerReceiptSchema, SessionApplyResponseSchema, SESSION_TELEGRAM_IDENTITY_STATUSES, SessionTelegramIdentityStatusSchema, SessionPresenceIdentitySchema, SessionPresenceResponseSchema, SessionPresenceConnectRequestSchema, SessionPresenceConnectPendingSchema, SessionPresenceConnectResponseSchema, SessionPresenceIconRequestSchema, SessionPresenceIconResponseSchema, SessionPresenceCompleteResponseSchema;
|
|
18059
18057
|
var init_sessions = __esm({
|
|
18060
18058
|
"../../packages/schemas/src/sessions.ts"() {
|
|
18061
18059
|
"use strict";
|
|
@@ -18067,7 +18065,9 @@ var init_sessions = __esm({
|
|
|
18067
18065
|
init_secrets();
|
|
18068
18066
|
init_tools();
|
|
18069
18067
|
init_trigger_router();
|
|
18070
|
-
|
|
18068
|
+
RESOURCE_KIND_AGENT = "agent";
|
|
18069
|
+
LEGACY_RESOURCE_KIND_SESSION = "session";
|
|
18070
|
+
RESOURCE_KIND_SESSION = RESOURCE_KIND_AGENT;
|
|
18071
18071
|
SESSION_HARNESSES = ["claude-code"];
|
|
18072
18072
|
TriggerFilterScalarSchema = external_exports.union([
|
|
18073
18073
|
external_exports.null(),
|
|
@@ -18341,7 +18341,7 @@ var init_sessions = __esm({
|
|
|
18341
18341
|
/**
|
|
18342
18342
|
* Scopes the current agent-app scope set requests that this realized
|
|
18343
18343
|
* identity's install never granted. Computed at read time; non-empty means
|
|
18344
|
-
* the install predates a scope addition and `auto
|
|
18344
|
+
* the install predates a scope addition and `auto agents connect
|
|
18345
18345
|
* <session> --reconnect` refreshes it.
|
|
18346
18346
|
*/
|
|
18347
18347
|
missingScopes: external_exports.array(external_exports.string().trim().min(1)).optional()
|
|
@@ -18586,7 +18586,16 @@ var init_project_service_accounts = __esm({
|
|
|
18586
18586
|
});
|
|
18587
18587
|
|
|
18588
18588
|
// ../../packages/schemas/src/project-resources.ts
|
|
18589
|
-
|
|
18589
|
+
function normalizeLegacySessionKind(value) {
|
|
18590
|
+
if (isRecord(value) && value.kind === LEGACY_RESOURCE_KIND_SESSION) {
|
|
18591
|
+
return { ...value, kind: RESOURCE_KIND_SESSION };
|
|
18592
|
+
}
|
|
18593
|
+
return value;
|
|
18594
|
+
}
|
|
18595
|
+
function isRecord(value) {
|
|
18596
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
18597
|
+
}
|
|
18598
|
+
var EnvironmentApplyDocumentSchema, IdentityApplyDocumentSchema, SessionApplyDocumentSchema, ProjectApplyResourceSchema, PROJECT_RESOURCE_APPLY_ORDER, PROJECT_RESOURCE_KINDS, ProjectDeleteResourceBaseSchema, ProjectDeleteResourceSchema, AVATAR_ASSET_CONTENT_TYPES, MAX_AVATAR_ASSET_BASE64_LENGTH, ProjectApplyAssetSchema, ProjectApplyAssetsSchema, AvatarAssetUploadRequestSchema, AvatarAssetUploadResponseSchema, ProjectApplyRequestSchema, ProjectApplySystemConfigSchema, ProjectAppliedResourceSchema, ProjectApplyDiagnosticSchema, ProjectApplyResponseResourceKindSchema, ProjectApplyResponseSchema;
|
|
18590
18599
|
var init_project_resources = __esm({
|
|
18591
18600
|
"../../packages/schemas/src/project-resources.ts"() {
|
|
18592
18601
|
"use strict";
|
|
@@ -18595,7 +18604,6 @@ var init_project_resources = __esm({
|
|
|
18595
18604
|
init_identities();
|
|
18596
18605
|
init_resources();
|
|
18597
18606
|
init_sessions();
|
|
18598
|
-
init_tools();
|
|
18599
18607
|
EnvironmentApplyDocumentSchema = resourceApplyDocumentSchema(
|
|
18600
18608
|
RESOURCE_KIND_ENVIRONMENT,
|
|
18601
18609
|
EnvironmentApplyRequestSchema.shape.spec
|
|
@@ -18608,30 +18616,29 @@ var init_project_resources = __esm({
|
|
|
18608
18616
|
RESOURCE_KIND_SESSION,
|
|
18609
18617
|
SessionApplyRequestSchema.shape.spec
|
|
18610
18618
|
);
|
|
18611
|
-
ProjectApplyResourceSchema = external_exports.
|
|
18612
|
-
|
|
18613
|
-
|
|
18614
|
-
|
|
18615
|
-
|
|
18619
|
+
ProjectApplyResourceSchema = external_exports.preprocess(
|
|
18620
|
+
normalizeLegacySessionKind,
|
|
18621
|
+
external_exports.discriminatedUnion("kind", [
|
|
18622
|
+
EnvironmentApplyDocumentSchema,
|
|
18623
|
+
IdentityApplyDocumentSchema,
|
|
18624
|
+
SessionApplyDocumentSchema
|
|
18625
|
+
])
|
|
18626
|
+
);
|
|
18616
18627
|
PROJECT_RESOURCE_APPLY_ORDER = [
|
|
18617
18628
|
RESOURCE_KIND_ENVIRONMENT,
|
|
18618
18629
|
RESOURCE_KIND_IDENTITY,
|
|
18619
18630
|
RESOURCE_KIND_SESSION
|
|
18620
18631
|
];
|
|
18621
18632
|
PROJECT_RESOURCE_KINDS = PROJECT_RESOURCE_APPLY_ORDER;
|
|
18622
|
-
|
|
18623
|
-
RESOURCE_KIND_ENVIRONMENT,
|
|
18624
|
-
RESOURCE_KIND_IDENTITY,
|
|
18625
|
-
RESOURCE_KIND_SESSION,
|
|
18626
|
-
// Legacy tool resources are no longer authorable, but apply responses may
|
|
18627
|
-
// still report archived/pruned tool rows while existing installations clean
|
|
18628
|
-
// up their stored resource state.
|
|
18629
|
-
RESOURCE_KIND_TOOL
|
|
18630
|
-
]);
|
|
18631
|
-
ProjectDeleteResourceSchema = external_exports.object({
|
|
18632
|
-
kind: external_exports.enum(PROJECT_RESOURCE_KINDS),
|
|
18633
|
+
ProjectDeleteResourceBaseSchema = external_exports.object({
|
|
18633
18634
|
name: external_exports.string().trim().min(1)
|
|
18634
18635
|
});
|
|
18636
|
+
ProjectDeleteResourceSchema = external_exports.preprocess(
|
|
18637
|
+
normalizeLegacySessionKind,
|
|
18638
|
+
ProjectDeleteResourceBaseSchema.extend({
|
|
18639
|
+
kind: external_exports.enum(PROJECT_RESOURCE_KINDS)
|
|
18640
|
+
})
|
|
18641
|
+
);
|
|
18635
18642
|
AVATAR_ASSET_CONTENT_TYPES = ["image/png", "image/jpeg"];
|
|
18636
18643
|
MAX_AVATAR_ASSET_BASE64_LENGTH = Math.ceil(MAX_AVATAR_ASSET_BYTES / 3) * 4 + 4;
|
|
18637
18644
|
ProjectApplyAssetSchema = external_exports.object({
|
|
@@ -18685,6 +18692,12 @@ var init_project_resources = __esm({
|
|
|
18685
18692
|
]),
|
|
18686
18693
|
name: external_exports.string().min(1)
|
|
18687
18694
|
});
|
|
18695
|
+
ProjectApplyResponseResourceKindSchema = external_exports.union([
|
|
18696
|
+
external_exports.enum(PROJECT_RESOURCE_KINDS),
|
|
18697
|
+
external_exports.literal(LEGACY_RESOURCE_KIND_SESSION)
|
|
18698
|
+
]).transform(
|
|
18699
|
+
(kind) => kind === LEGACY_RESOURCE_KIND_SESSION ? RESOURCE_KIND_SESSION : kind
|
|
18700
|
+
);
|
|
18688
18701
|
ProjectApplyResponseSchema = external_exports.object({
|
|
18689
18702
|
dryRun: external_exports.boolean().default(false),
|
|
18690
18703
|
resources: external_exports.array(ProjectAppliedResourceSchema),
|
|
@@ -18849,18 +18862,11 @@ var init_session_runs = __esm({
|
|
|
18849
18862
|
sessionSnapshot: SessionResourceSchema,
|
|
18850
18863
|
environmentSnapshot: EnvironmentResourceSchema,
|
|
18851
18864
|
toolSnapshots: external_exports.array(
|
|
18852
|
-
external_exports.
|
|
18853
|
-
external_exports.
|
|
18854
|
-
|
|
18855
|
-
|
|
18856
|
-
|
|
18857
|
-
}),
|
|
18858
|
-
external_exports.object({
|
|
18859
|
-
source: external_exports.literal("resource"),
|
|
18860
|
-
alias: ToolAliasSchema,
|
|
18861
|
-
resource: ToolResourceSchema
|
|
18862
|
-
})
|
|
18863
|
-
])
|
|
18865
|
+
external_exports.object({
|
|
18866
|
+
source: external_exports.literal("inline"),
|
|
18867
|
+
alias: ToolAliasSchema,
|
|
18868
|
+
spec: RemoteMcpToolSchema.or(LocalToolSchema).or(GithubToolSchema)
|
|
18869
|
+
})
|
|
18864
18870
|
),
|
|
18865
18871
|
input: JsonValueSchema,
|
|
18866
18872
|
createdAt: external_exports.string().datetime(),
|
|
@@ -19637,10 +19643,6 @@ function createResourceApi(context) {
|
|
|
19637
19643
|
path: "/sessions",
|
|
19638
19644
|
applyResponseSchema: SessionApplyResponseSchema
|
|
19639
19645
|
});
|
|
19640
|
-
const tools = projectResource(context, {
|
|
19641
|
-
path: "/tools",
|
|
19642
|
-
applyResponseSchema: ToolResourceSchema
|
|
19643
|
-
});
|
|
19644
19646
|
const identities = projectResource(
|
|
19645
19647
|
context,
|
|
19646
19648
|
{
|
|
@@ -19658,19 +19660,17 @@ function createResourceApi(context) {
|
|
|
19658
19660
|
options ?? {}
|
|
19659
19661
|
),
|
|
19660
19662
|
applySessionResource: sessions.apply,
|
|
19661
|
-
applyToolResource: tools.apply,
|
|
19662
19663
|
createProjectServiceAccount: (request, options) => createProjectServiceAccount(context, request, options ?? {}),
|
|
19663
19664
|
deleteProjectResource: (request, options) => deleteProjectResource(context, request, options ?? {}),
|
|
19664
19665
|
listEnvironments: environments.list,
|
|
19665
19666
|
listIdentities: identities.list,
|
|
19666
19667
|
listProjectServiceAccounts: (options) => listProjectServiceAccounts(context, options ?? {}),
|
|
19667
19668
|
listSessions: sessions.list,
|
|
19668
|
-
listTools: tools.list,
|
|
19669
19669
|
getSessionPresence: (request, options) => getSessionPresence(context, request, options ?? {}),
|
|
19670
19670
|
connectSessionPresence: (request, options) => connectSessionPresence(context, request, options ?? {}),
|
|
19671
19671
|
recordSessionPresenceIcon: (request, options) => recordSessionPresenceIcon(context, request, options ?? {}),
|
|
19672
|
-
|
|
19673
|
-
|
|
19672
|
+
startSessionToolConnection: (request, options) => startSessionToolConnection(context, request, options ?? {}),
|
|
19673
|
+
completeSessionToolConnection: (request, options) => completeSessionToolConnection(context, request, options ?? {}),
|
|
19674
19674
|
removeProjectServiceAccount: (request, options) => removeProjectServiceAccount(context, request, options ?? {}),
|
|
19675
19675
|
rotateProjectServiceAccountToken: (request, options) => rotateProjectServiceAccountToken(context, request, options ?? {}),
|
|
19676
19676
|
updateProjectServiceAccount: (request, options) => updateProjectServiceAccount(context, request, options ?? {})
|
|
@@ -19816,13 +19816,13 @@ async function recordSessionPresenceIcon(context, request, options) {
|
|
|
19816
19816
|
}
|
|
19817
19817
|
return SessionPresenceIconResponseSchema.parse(await response.json());
|
|
19818
19818
|
}
|
|
19819
|
-
async function
|
|
19819
|
+
async function startSessionToolConnection(context, request, options) {
|
|
19820
19820
|
const project = await context.activeProject();
|
|
19821
19821
|
const response = await context.authenticatedFetch(
|
|
19822
19822
|
context.apiUrl(
|
|
19823
19823
|
projectApiPath(
|
|
19824
19824
|
project,
|
|
19825
|
-
`/tools/${encodeURIComponent(request.
|
|
19825
|
+
`/sessions/${encodeURIComponent(request.sessionName)}/tools/${encodeURIComponent(request.toolAlias)}/connections`
|
|
19826
19826
|
),
|
|
19827
19827
|
options.apiBaseUrl
|
|
19828
19828
|
),
|
|
@@ -19840,9 +19840,9 @@ async function startToolConnection(context, request, options) {
|
|
|
19840
19840
|
if (!response.ok) {
|
|
19841
19841
|
throw new Error(await responseErrorMessage(response));
|
|
19842
19842
|
}
|
|
19843
|
-
return
|
|
19843
|
+
return SessionToolConnectResponseSchema.parse(await response.json());
|
|
19844
19844
|
}
|
|
19845
|
-
async function
|
|
19845
|
+
async function completeSessionToolConnection(context, request, options) {
|
|
19846
19846
|
const url2 = new URL(
|
|
19847
19847
|
context.apiUrl(apiPath("/mcp/oauth/callback"), options.apiBaseUrl)
|
|
19848
19848
|
);
|
|
@@ -19856,7 +19856,7 @@ async function completeToolConnection(context, request, options) {
|
|
|
19856
19856
|
if (!response.ok) {
|
|
19857
19857
|
throw new Error(await responseErrorMessage(response));
|
|
19858
19858
|
}
|
|
19859
|
-
return
|
|
19859
|
+
return SessionToolConnectCompleteResponseSchema.parse(await response.json());
|
|
19860
19860
|
}
|
|
19861
19861
|
async function createProjectServiceAccount(context, request, options) {
|
|
19862
19862
|
const project = await context.activeProject();
|
|
@@ -21208,7 +21208,7 @@ var init_package = __esm({
|
|
|
21208
21208
|
"package.json"() {
|
|
21209
21209
|
package_default = {
|
|
21210
21210
|
name: "@autohq/cli",
|
|
21211
|
-
version: "0.1.
|
|
21211
|
+
version: "0.1.134",
|
|
21212
21212
|
license: "SEE LICENSE IN README.md",
|
|
21213
21213
|
publishConfig: {
|
|
21214
21214
|
access: "public"
|
|
@@ -21271,133 +21271,6 @@ var init_version = __esm({
|
|
|
21271
21271
|
}
|
|
21272
21272
|
});
|
|
21273
21273
|
|
|
21274
|
-
// src/commands/tools/connect.ts
|
|
21275
|
-
async function connectTool(input) {
|
|
21276
|
-
if (input.manual) {
|
|
21277
|
-
const result = await input.client.startToolConnection(
|
|
21278
|
-
{
|
|
21279
|
-
name: input.tool
|
|
21280
|
-
},
|
|
21281
|
-
{
|
|
21282
|
-
apiBaseUrl: input.apiBaseUrl
|
|
21283
|
-
}
|
|
21284
|
-
);
|
|
21285
|
-
writeConnectionStart(input.writeOutput, result);
|
|
21286
|
-
return;
|
|
21287
|
-
}
|
|
21288
|
-
let connection;
|
|
21289
|
-
const activeSelection = input.client.getActiveSelection();
|
|
21290
|
-
let scopeContext = toolConnectionScopeContext({
|
|
21291
|
-
activeSelection
|
|
21292
|
-
});
|
|
21293
|
-
const scopeContextPromise = resolveToolConnectionScopeContext({
|
|
21294
|
-
activeSelection,
|
|
21295
|
-
apiBaseUrl: input.apiBaseUrl,
|
|
21296
|
-
client: input.client
|
|
21297
|
-
});
|
|
21298
|
-
const callback = await createOAuthLoopbackCallback({
|
|
21299
|
-
successHtml: () => renderOAuthLoopbackPage({
|
|
21300
|
-
status: "success",
|
|
21301
|
-
eyebrow: "Auto Tool",
|
|
21302
|
-
title: `${connection?.tool ?? input.tool} is authorized`,
|
|
21303
|
-
message: "Auto received the provider authorization. The CLI will finish the token exchange in your terminal.",
|
|
21304
|
-
details: [
|
|
21305
|
-
{ label: "Tool", value: connection?.tool ?? input.tool },
|
|
21306
|
-
{ label: "Connection", value: connection?.connection },
|
|
21307
|
-
{ label: "Organization", value: scopeContext.organization },
|
|
21308
|
-
{ label: "Project", value: scopeContext.project }
|
|
21309
|
-
]
|
|
21310
|
-
}),
|
|
21311
|
-
failureHtml: () => renderOAuthLoopbackPage({
|
|
21312
|
-
status: "failure",
|
|
21313
|
-
eyebrow: "Auto Tool",
|
|
21314
|
-
title: `${connection?.tool ?? input.tool} was not authorized`,
|
|
21315
|
-
message: "The provider rejected the authorization request. Return to your terminal to see the error details.",
|
|
21316
|
-
details: [
|
|
21317
|
-
{ label: "Tool", value: connection?.tool ?? input.tool },
|
|
21318
|
-
{ label: "Connection", value: connection?.connection },
|
|
21319
|
-
{ label: "Organization", value: scopeContext.organization },
|
|
21320
|
-
{ label: "Project", value: scopeContext.project }
|
|
21321
|
-
]
|
|
21322
|
-
})
|
|
21323
|
-
});
|
|
21324
|
-
try {
|
|
21325
|
-
const result = await input.client.startToolConnection(
|
|
21326
|
-
{
|
|
21327
|
-
name: input.tool,
|
|
21328
|
-
redirectUri: callback.redirectUri
|
|
21329
|
-
},
|
|
21330
|
-
{
|
|
21331
|
-
apiBaseUrl: input.apiBaseUrl
|
|
21332
|
-
}
|
|
21333
|
-
);
|
|
21334
|
-
scopeContext = await scopeContextPromise;
|
|
21335
|
-
connection = result;
|
|
21336
|
-
writeConnectionStart(input.writeOutput, result);
|
|
21337
|
-
input.writeOutput("Waiting for browser authorization...");
|
|
21338
|
-
openBrowser(result.authorizationUrl);
|
|
21339
|
-
const authorized = await callback.result;
|
|
21340
|
-
if (!authorized.state) {
|
|
21341
|
-
throw new Error("OAuth callback is missing state");
|
|
21342
|
-
}
|
|
21343
|
-
const completed = await input.client.completeToolConnection(
|
|
21344
|
-
{
|
|
21345
|
-
code: authorized.code,
|
|
21346
|
-
state: authorized.state
|
|
21347
|
-
},
|
|
21348
|
-
{
|
|
21349
|
-
apiBaseUrl: input.apiBaseUrl
|
|
21350
|
-
}
|
|
21351
|
-
);
|
|
21352
|
-
input.writeOutput(
|
|
21353
|
-
`connected tool/${completed.tool} connection/${completed.connection}`
|
|
21354
|
-
);
|
|
21355
|
-
} finally {
|
|
21356
|
-
callback.close();
|
|
21357
|
-
}
|
|
21358
|
-
}
|
|
21359
|
-
async function resolveToolConnectionScopeContext(input) {
|
|
21360
|
-
if (!input.activeSelection.organizationId || !input.activeSelection.projectId) {
|
|
21361
|
-
return toolConnectionScopeContext({
|
|
21362
|
-
activeSelection: input.activeSelection
|
|
21363
|
-
});
|
|
21364
|
-
}
|
|
21365
|
-
try {
|
|
21366
|
-
const response = await input.client.listProjects({
|
|
21367
|
-
apiBaseUrl: input.apiBaseUrl
|
|
21368
|
-
});
|
|
21369
|
-
const activeProject = response.projects.find(
|
|
21370
|
-
(project) => project.organizationId === input.activeSelection.organizationId && project.projectId === input.activeSelection.projectId
|
|
21371
|
-
);
|
|
21372
|
-
return toolConnectionScopeContext({
|
|
21373
|
-
activeProject,
|
|
21374
|
-
activeSelection: input.activeSelection
|
|
21375
|
-
});
|
|
21376
|
-
} catch {
|
|
21377
|
-
return toolConnectionScopeContext({
|
|
21378
|
-
activeSelection: input.activeSelection
|
|
21379
|
-
});
|
|
21380
|
-
}
|
|
21381
|
-
}
|
|
21382
|
-
function toolConnectionScopeContext(input) {
|
|
21383
|
-
return {
|
|
21384
|
-
organization: input.activeProject ? `${input.activeProject.organizationName} (${input.activeProject.organizationSlug})` : input.activeSelection.organizationId,
|
|
21385
|
-
project: input.activeProject ? `${input.activeProject.projectName} (${input.activeProject.projectSlug})` : input.activeSelection.projectId
|
|
21386
|
-
};
|
|
21387
|
-
}
|
|
21388
|
-
function writeConnectionStart(writeOutput, result) {
|
|
21389
|
-
writeOutput(result.message);
|
|
21390
|
-
writeOutput(`connect tool/${result.tool} connection/${result.connection}`);
|
|
21391
|
-
writeOutput(`authorization_url ${result.authorizationUrl}`);
|
|
21392
|
-
}
|
|
21393
|
-
var init_connect = __esm({
|
|
21394
|
-
"src/commands/tools/connect.ts"() {
|
|
21395
|
-
"use strict";
|
|
21396
|
-
init_browser();
|
|
21397
|
-
init_loopback();
|
|
21398
|
-
}
|
|
21399
|
-
});
|
|
21400
|
-
|
|
21401
21274
|
// src/commands/apply/assets.ts
|
|
21402
21275
|
async function resolveApplyAssets(input) {
|
|
21403
21276
|
const entries = Object.entries(input.request.assets);
|
|
@@ -21469,7 +21342,7 @@ function stampAvatarSha256(resource, assets) {
|
|
|
21469
21342
|
}
|
|
21470
21343
|
};
|
|
21471
21344
|
}
|
|
21472
|
-
if (resource.kind ===
|
|
21345
|
+
if (resource.kind === RESOURCE_KIND_SESSION && typeof resource.spec.identity === "object" && resource.spec.identity !== null && !Array.isArray(resource.spec.identity)) {
|
|
21473
21346
|
const identity2 = resource.spec.identity;
|
|
21474
21347
|
const avatar = identity2.avatar;
|
|
21475
21348
|
const asset = avatar ? assets[avatar.asset] : void 0;
|
|
@@ -21496,6 +21369,7 @@ var MAX_APPLY_REQUEST_BODY_BYTES;
|
|
|
21496
21369
|
var init_assets = __esm({
|
|
21497
21370
|
"src/commands/apply/assets.ts"() {
|
|
21498
21371
|
"use strict";
|
|
21372
|
+
init_src();
|
|
21499
21373
|
init_resources2();
|
|
21500
21374
|
MAX_APPLY_REQUEST_BODY_BYTES = 4 * 1024 * 1024;
|
|
21501
21375
|
}
|
|
@@ -21541,7 +21415,7 @@ function readProjectApplyRequest(options) {
|
|
|
21541
21415
|
for (const resource of request.resources) {
|
|
21542
21416
|
if (resource.kind !== kind) {
|
|
21543
21417
|
throw new Error(
|
|
21544
|
-
`Resource kind "${resource.kind}" in ${path2} does not match .auto/${
|
|
21418
|
+
`Resource kind "${resource.kind}" in ${path2} does not match .auto/${primaryApplyDirectory(kind)}`
|
|
21545
21419
|
);
|
|
21546
21420
|
}
|
|
21547
21421
|
resources.push(resource);
|
|
@@ -21552,7 +21426,7 @@ function readProjectApplyRequest(options) {
|
|
|
21552
21426
|
}
|
|
21553
21427
|
function appliedResourceKind(request, response, index) {
|
|
21554
21428
|
const plannedResources = response.plan.filter(
|
|
21555
|
-
(item) => item.action !== "archive"
|
|
21429
|
+
(item) => item.action !== "archive"
|
|
21556
21430
|
);
|
|
21557
21431
|
const kind = plannedResources[index]?.kind ?? request.resources[index]?.kind;
|
|
21558
21432
|
if (!kind) {
|
|
@@ -21562,48 +21436,56 @@ function appliedResourceKind(request, response, index) {
|
|
|
21562
21436
|
}
|
|
21563
21437
|
return kind;
|
|
21564
21438
|
}
|
|
21565
|
-
function
|
|
21566
|
-
return PROJECT_RESOURCE_APPLY_ORDER.includes(
|
|
21567
|
-
kind
|
|
21568
|
-
);
|
|
21569
|
-
}
|
|
21570
|
-
function mcpOAuthToolConnectionsFromApplyRequest(request) {
|
|
21439
|
+
function mcpOAuthSessionToolConnectionsFromApplyRequest(request) {
|
|
21571
21440
|
return request.resources.filter((resource) => resource.kind === RESOURCE_KIND_SESSION).flatMap((resource) => {
|
|
21572
|
-
return
|
|
21441
|
+
return mcpOAuthSessionToolConnectionsFromSessionTools({
|
|
21442
|
+
session: resource.metadata.name,
|
|
21443
|
+
tools: resource.spec.tools
|
|
21444
|
+
});
|
|
21573
21445
|
});
|
|
21574
21446
|
}
|
|
21575
|
-
function
|
|
21447
|
+
function mcpOAuthSessionToolConnectionsFromAppliedResources(resources) {
|
|
21576
21448
|
return resources.filter((item) => item.kind === RESOURCE_KIND_SESSION).flatMap((item) => {
|
|
21577
21449
|
const resource = item.resource;
|
|
21578
|
-
return
|
|
21450
|
+
return mcpOAuthSessionToolConnectionsFromSessionTools({
|
|
21451
|
+
session: resource.metadata.name,
|
|
21452
|
+
tools: resource.spec.tools
|
|
21453
|
+
});
|
|
21579
21454
|
});
|
|
21580
21455
|
}
|
|
21581
21456
|
function applyFiles(root) {
|
|
21582
21457
|
const files = [];
|
|
21583
21458
|
for (const kind of PROJECT_RESOURCE_APPLY_ORDER) {
|
|
21584
|
-
const directory
|
|
21585
|
-
|
|
21586
|
-
|
|
21587
|
-
|
|
21588
|
-
|
|
21589
|
-
|
|
21590
|
-
|
|
21459
|
+
for (const directory of applyDirectories(kind)) {
|
|
21460
|
+
const path2 = join3(root, directory);
|
|
21461
|
+
let entries;
|
|
21462
|
+
try {
|
|
21463
|
+
entries = readdirSync2(path2, { withFileTypes: true });
|
|
21464
|
+
} catch {
|
|
21465
|
+
continue;
|
|
21466
|
+
}
|
|
21467
|
+
files.push(
|
|
21468
|
+
...resourceApplyFiles(path2, entries).map((file2) => ({
|
|
21469
|
+
kind,
|
|
21470
|
+
path: file2
|
|
21471
|
+
}))
|
|
21472
|
+
);
|
|
21591
21473
|
}
|
|
21592
|
-
files.push(
|
|
21593
|
-
...resourceApplyFiles(path2, entries).map((file2) => ({
|
|
21594
|
-
kind,
|
|
21595
|
-
path: file2
|
|
21596
|
-
}))
|
|
21597
|
-
);
|
|
21598
21474
|
}
|
|
21599
21475
|
return files;
|
|
21600
21476
|
}
|
|
21601
|
-
function
|
|
21602
|
-
return Object.entries(tools).flatMap(([alias, tool]) => {
|
|
21477
|
+
function mcpOAuthSessionToolConnectionsFromSessionTools(input) {
|
|
21478
|
+
return Object.entries(input.tools).flatMap(([alias, tool]) => {
|
|
21603
21479
|
if (tool.kind !== "mcp_remote" || tool.disabled || tool.auth.kind !== "mcp_oauth") {
|
|
21604
21480
|
return [];
|
|
21605
21481
|
}
|
|
21606
|
-
return [
|
|
21482
|
+
return [
|
|
21483
|
+
{
|
|
21484
|
+
session: input.session,
|
|
21485
|
+
tool: alias,
|
|
21486
|
+
connection: tool.auth.connection
|
|
21487
|
+
}
|
|
21488
|
+
];
|
|
21607
21489
|
});
|
|
21608
21490
|
}
|
|
21609
21491
|
function readApplyDocumentFile(path2) {
|
|
@@ -21761,12 +21643,21 @@ function isInside(path2, parent) {
|
|
|
21761
21643
|
return path2.startsWith(`${parent}/`);
|
|
21762
21644
|
}
|
|
21763
21645
|
function applyCandidate(document) {
|
|
21764
|
-
if (!
|
|
21646
|
+
if (!isRecord2(document) || !("kind" in document)) {
|
|
21765
21647
|
return { kind: RESOURCE_KIND_SESSION, value: document };
|
|
21766
21648
|
}
|
|
21649
|
+
if (document.kind === LEGACY_RESOURCE_KIND_SESSION) {
|
|
21650
|
+
return {
|
|
21651
|
+
kind: RESOURCE_KIND_SESSION,
|
|
21652
|
+
value: {
|
|
21653
|
+
metadata: document.metadata,
|
|
21654
|
+
spec: document.spec
|
|
21655
|
+
}
|
|
21656
|
+
};
|
|
21657
|
+
}
|
|
21767
21658
|
if (!PROJECT_RESOURCE_APPLY_ORDER.includes(document.kind)) {
|
|
21768
21659
|
throw new Error(
|
|
21769
|
-
`Unsupported apply resource kind "${String(document.kind)}"; supported kinds are ${PROJECT_RESOURCE_APPLY_ORDER.map((kind2) => `"${kind2}"`).join(", ")}`
|
|
21660
|
+
`Unsupported apply resource kind "${String(document.kind)}"; supported kinds are ${PROJECT_RESOURCE_APPLY_ORDER.map((kind2) => `"${kind2}"`).join(", ")} (legacy alias "session" is also accepted)`
|
|
21770
21661
|
);
|
|
21771
21662
|
}
|
|
21772
21663
|
const kind = document.kind;
|
|
@@ -21778,7 +21669,13 @@ function applyCandidate(document) {
|
|
|
21778
21669
|
}
|
|
21779
21670
|
};
|
|
21780
21671
|
}
|
|
21781
|
-
function
|
|
21672
|
+
function applyDirectories(kind) {
|
|
21673
|
+
return [...LEGACY_APPLY_DIRECTORIES[kind] ?? [], APPLY_DIRECTORIES[kind]];
|
|
21674
|
+
}
|
|
21675
|
+
function primaryApplyDirectory(kind) {
|
|
21676
|
+
return APPLY_DIRECTORIES[kind];
|
|
21677
|
+
}
|
|
21678
|
+
function isRecord2(value) {
|
|
21782
21679
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
21783
21680
|
}
|
|
21784
21681
|
function resourceApplyFiles(directory, entries) {
|
|
@@ -21797,7 +21694,7 @@ function resourceApplyFiles(directory, entries) {
|
|
|
21797
21694
|
}
|
|
21798
21695
|
return files.sort((left, right) => left.localeCompare(right));
|
|
21799
21696
|
}
|
|
21800
|
-
var APPLY_DIRECTORIES, APPLY_SCHEMAS, ALLOWED_AVATAR_EXTENSIONS;
|
|
21697
|
+
var APPLY_DIRECTORIES, LEGACY_APPLY_DIRECTORIES, APPLY_SCHEMAS, ALLOWED_AVATAR_EXTENSIONS;
|
|
21801
21698
|
var init_files = __esm({
|
|
21802
21699
|
"src/commands/apply/files.ts"() {
|
|
21803
21700
|
"use strict";
|
|
@@ -21805,17 +21702,153 @@ var init_files = __esm({
|
|
|
21805
21702
|
APPLY_DIRECTORIES = {
|
|
21806
21703
|
environment: "environments",
|
|
21807
21704
|
identity: "identities",
|
|
21808
|
-
|
|
21705
|
+
agent: "agents"
|
|
21706
|
+
};
|
|
21707
|
+
LEGACY_APPLY_DIRECTORIES = {
|
|
21708
|
+
[RESOURCE_KIND_SESSION]: ["sessions"]
|
|
21809
21709
|
};
|
|
21810
21710
|
APPLY_SCHEMAS = {
|
|
21811
21711
|
environment: EnvironmentApplyRequestSchema,
|
|
21812
21712
|
identity: IdentityApplyRequestSchema,
|
|
21813
|
-
|
|
21713
|
+
[RESOURCE_KIND_SESSION]: SessionApplyRequestSchema
|
|
21814
21714
|
};
|
|
21815
21715
|
ALLOWED_AVATAR_EXTENSIONS = /* @__PURE__ */ new Set([".jpg", ".jpeg", ".png"]);
|
|
21816
21716
|
}
|
|
21817
21717
|
});
|
|
21818
21718
|
|
|
21719
|
+
// src/commands/apply/session-tool-connect.ts
|
|
21720
|
+
async function connectSessionTool(input) {
|
|
21721
|
+
if (input.manual) {
|
|
21722
|
+
const result = await input.client.startSessionToolConnection(
|
|
21723
|
+
{
|
|
21724
|
+
sessionName: input.session,
|
|
21725
|
+
toolAlias: input.tool
|
|
21726
|
+
},
|
|
21727
|
+
{
|
|
21728
|
+
apiBaseUrl: input.apiBaseUrl
|
|
21729
|
+
}
|
|
21730
|
+
);
|
|
21731
|
+
writeConnectionStart(input.writeOutput, result);
|
|
21732
|
+
return;
|
|
21733
|
+
}
|
|
21734
|
+
let connection;
|
|
21735
|
+
const activeSelection = input.client.getActiveSelection();
|
|
21736
|
+
let scopeContext = sessionToolConnectionScopeContext({
|
|
21737
|
+
activeSelection
|
|
21738
|
+
});
|
|
21739
|
+
const scopeContextPromise = resolveSessionToolConnectionScopeContext({
|
|
21740
|
+
activeSelection,
|
|
21741
|
+
apiBaseUrl: input.apiBaseUrl,
|
|
21742
|
+
client: input.client
|
|
21743
|
+
});
|
|
21744
|
+
const callback = await createOAuthLoopbackCallback({
|
|
21745
|
+
successHtml: () => renderOAuthLoopbackPage({
|
|
21746
|
+
status: "success",
|
|
21747
|
+
eyebrow: "Auto Tool",
|
|
21748
|
+
title: `${connection?.tool ?? input.tool} is authorized`,
|
|
21749
|
+
message: "Auto received the provider authorization. The CLI will finish the token exchange in your terminal.",
|
|
21750
|
+
details: [
|
|
21751
|
+
{ label: "Session", value: connection?.session ?? input.session },
|
|
21752
|
+
{ label: "Tool", value: connection?.tool ?? input.tool },
|
|
21753
|
+
{ label: "Connection", value: connection?.connection },
|
|
21754
|
+
{ label: "Organization", value: scopeContext.organization },
|
|
21755
|
+
{ label: "Project", value: scopeContext.project }
|
|
21756
|
+
]
|
|
21757
|
+
}),
|
|
21758
|
+
failureHtml: () => renderOAuthLoopbackPage({
|
|
21759
|
+
status: "failure",
|
|
21760
|
+
eyebrow: "Auto Tool",
|
|
21761
|
+
title: `${connection?.tool ?? input.tool} was not authorized`,
|
|
21762
|
+
message: "The provider rejected the authorization request. Return to your terminal to see the error details.",
|
|
21763
|
+
details: [
|
|
21764
|
+
{ label: "Session", value: connection?.session ?? input.session },
|
|
21765
|
+
{ label: "Tool", value: connection?.tool ?? input.tool },
|
|
21766
|
+
{ label: "Connection", value: connection?.connection },
|
|
21767
|
+
{ label: "Organization", value: scopeContext.organization },
|
|
21768
|
+
{ label: "Project", value: scopeContext.project }
|
|
21769
|
+
]
|
|
21770
|
+
})
|
|
21771
|
+
});
|
|
21772
|
+
try {
|
|
21773
|
+
const result = await input.client.startSessionToolConnection(
|
|
21774
|
+
{
|
|
21775
|
+
sessionName: input.session,
|
|
21776
|
+
toolAlias: input.tool,
|
|
21777
|
+
redirectUri: callback.redirectUri
|
|
21778
|
+
},
|
|
21779
|
+
{
|
|
21780
|
+
apiBaseUrl: input.apiBaseUrl
|
|
21781
|
+
}
|
|
21782
|
+
);
|
|
21783
|
+
scopeContext = await scopeContextPromise;
|
|
21784
|
+
connection = result;
|
|
21785
|
+
writeConnectionStart(input.writeOutput, result);
|
|
21786
|
+
input.writeOutput("Waiting for browser authorization...");
|
|
21787
|
+
openBrowser(result.authorizationUrl);
|
|
21788
|
+
const authorized = await callback.result;
|
|
21789
|
+
if (!authorized.state) {
|
|
21790
|
+
throw new Error("OAuth callback is missing state");
|
|
21791
|
+
}
|
|
21792
|
+
const completed = await input.client.completeSessionToolConnection(
|
|
21793
|
+
{
|
|
21794
|
+
code: authorized.code,
|
|
21795
|
+
state: authorized.state
|
|
21796
|
+
},
|
|
21797
|
+
{
|
|
21798
|
+
apiBaseUrl: input.apiBaseUrl
|
|
21799
|
+
}
|
|
21800
|
+
);
|
|
21801
|
+
input.writeOutput(
|
|
21802
|
+
`connected agent/${completed.session ?? input.session} tool/${completed.tool} connection/${completed.connection}`
|
|
21803
|
+
);
|
|
21804
|
+
} finally {
|
|
21805
|
+
callback.close();
|
|
21806
|
+
}
|
|
21807
|
+
}
|
|
21808
|
+
async function resolveSessionToolConnectionScopeContext(input) {
|
|
21809
|
+
if (!input.activeSelection.organizationId || !input.activeSelection.projectId) {
|
|
21810
|
+
return sessionToolConnectionScopeContext({
|
|
21811
|
+
activeSelection: input.activeSelection
|
|
21812
|
+
});
|
|
21813
|
+
}
|
|
21814
|
+
try {
|
|
21815
|
+
const response = await input.client.listProjects({
|
|
21816
|
+
apiBaseUrl: input.apiBaseUrl
|
|
21817
|
+
});
|
|
21818
|
+
const activeProject = response.projects.find(
|
|
21819
|
+
(project) => project.organizationId === input.activeSelection.organizationId && project.projectId === input.activeSelection.projectId
|
|
21820
|
+
);
|
|
21821
|
+
return sessionToolConnectionScopeContext({
|
|
21822
|
+
activeProject,
|
|
21823
|
+
activeSelection: input.activeSelection
|
|
21824
|
+
});
|
|
21825
|
+
} catch {
|
|
21826
|
+
return sessionToolConnectionScopeContext({
|
|
21827
|
+
activeSelection: input.activeSelection
|
|
21828
|
+
});
|
|
21829
|
+
}
|
|
21830
|
+
}
|
|
21831
|
+
function sessionToolConnectionScopeContext(input) {
|
|
21832
|
+
return {
|
|
21833
|
+
organization: input.activeProject ? `${input.activeProject.organizationName} (${input.activeProject.organizationSlug})` : input.activeSelection.organizationId,
|
|
21834
|
+
project: input.activeProject ? `${input.activeProject.projectName} (${input.activeProject.projectSlug})` : input.activeSelection.projectId
|
|
21835
|
+
};
|
|
21836
|
+
}
|
|
21837
|
+
function writeConnectionStart(writeOutput, result) {
|
|
21838
|
+
writeOutput(result.message);
|
|
21839
|
+
writeOutput(
|
|
21840
|
+
`connect agent/${result.session} tool/${result.tool} connection/${result.connection}`
|
|
21841
|
+
);
|
|
21842
|
+
writeOutput(`authorization_url ${result.authorizationUrl}`);
|
|
21843
|
+
}
|
|
21844
|
+
var init_session_tool_connect = __esm({
|
|
21845
|
+
"src/commands/apply/session-tool-connect.ts"() {
|
|
21846
|
+
"use strict";
|
|
21847
|
+
init_browser();
|
|
21848
|
+
init_loopback();
|
|
21849
|
+
}
|
|
21850
|
+
});
|
|
21851
|
+
|
|
21819
21852
|
// src/commands/apply/actions.ts
|
|
21820
21853
|
async function applyResource(input) {
|
|
21821
21854
|
if (input.commandOptions.connect && input.commandOptions.json) {
|
|
@@ -21878,12 +21911,12 @@ async function applyProjectInput(input) {
|
|
|
21878
21911
|
);
|
|
21879
21912
|
}
|
|
21880
21913
|
if (input.commandOptions.connect) {
|
|
21881
|
-
for (const item of
|
|
21914
|
+
for (const item of mcpOAuthSessionToolConnectionsFromApplyRequest(
|
|
21882
21915
|
input.request
|
|
21883
21916
|
)) {
|
|
21884
21917
|
input.writeOutput(
|
|
21885
21918
|
style.dim(
|
|
21886
|
-
`would connect tool/${item.tool} connection/${item.connection}`
|
|
21919
|
+
`would connect agent/${item.session} tool/${item.tool} connection/${item.connection}`
|
|
21887
21920
|
)
|
|
21888
21921
|
);
|
|
21889
21922
|
}
|
|
@@ -21919,12 +21952,13 @@ async function applyProjectInput(input) {
|
|
|
21919
21952
|
}
|
|
21920
21953
|
writeDiagnostics(response.diagnostics, input.writeOutput, style);
|
|
21921
21954
|
if (input.commandOptions.connect) {
|
|
21922
|
-
const connections =
|
|
21955
|
+
const connections = mcpOAuthSessionToolConnectionsFromAppliedResources(resources);
|
|
21923
21956
|
for (const item of connections) {
|
|
21924
|
-
await
|
|
21957
|
+
await connectSessionTool({
|
|
21925
21958
|
apiBaseUrl: input.commandOptions.apiBaseUrl,
|
|
21926
21959
|
client: input.client,
|
|
21927
21960
|
manual: input.commandOptions.manualConnect,
|
|
21961
|
+
session: item.session,
|
|
21928
21962
|
tool: item.tool,
|
|
21929
21963
|
writeOutput: input.writeOutput
|
|
21930
21964
|
});
|
|
@@ -21957,9 +21991,9 @@ var init_actions = __esm({
|
|
|
21957
21991
|
"src/commands/apply/actions.ts"() {
|
|
21958
21992
|
"use strict";
|
|
21959
21993
|
init_style();
|
|
21960
|
-
init_connect();
|
|
21961
21994
|
init_assets();
|
|
21962
21995
|
init_files();
|
|
21996
|
+
init_session_tool_connect();
|
|
21963
21997
|
}
|
|
21964
21998
|
});
|
|
21965
21999
|
|
|
@@ -21970,8 +22004,11 @@ function parseProjectResourceReference(resource) {
|
|
|
21970
22004
|
throw new Error('Resource must be formatted as "kind/name"');
|
|
21971
22005
|
}
|
|
21972
22006
|
if (!PROJECT_RESOURCE_KINDS.includes(kind)) {
|
|
22007
|
+
if (kind === LEGACY_RESOURCE_KIND_SESSION) {
|
|
22008
|
+
return { kind: RESOURCE_KIND_SESSION, name };
|
|
22009
|
+
}
|
|
21973
22010
|
throw new Error(
|
|
21974
|
-
`Unsupported resource kind "${kind}"; supported kinds are ${PROJECT_RESOURCE_KINDS.map((value) => `"${value}"`).join(", ")}`
|
|
22011
|
+
`Unsupported resource kind "${kind}"; supported kinds are ${PROJECT_RESOURCE_KINDS.map((value) => `"${value}"`).join(", ")} (legacy alias "session" is also accepted)`
|
|
21975
22012
|
);
|
|
21976
22013
|
}
|
|
21977
22014
|
return { kind, name };
|
|
@@ -22017,8 +22054,8 @@ var init_resources3 = __esm({
|
|
|
22017
22054
|
[RESOURCE_KIND_SESSION]: {
|
|
22018
22055
|
kind: RESOURCE_KIND_SESSION,
|
|
22019
22056
|
section: "sessions",
|
|
22020
|
-
label: "
|
|
22021
|
-
pluralLabel: "
|
|
22057
|
+
label: "Agent",
|
|
22058
|
+
pluralLabel: "Agents"
|
|
22022
22059
|
}
|
|
22023
22060
|
};
|
|
22024
22061
|
PROJECT_RESOURCE_TUI_ORDER = [
|
|
@@ -23746,7 +23783,7 @@ function ConversationView({
|
|
|
23746
23783
|
{
|
|
23747
23784
|
name: "/back",
|
|
23748
23785
|
aliases: ["/exit"],
|
|
23749
|
-
description: "Go back to the
|
|
23786
|
+
description: "Go back to the agents dashboard",
|
|
23750
23787
|
shortcut: "esc",
|
|
23751
23788
|
action: () => {
|
|
23752
23789
|
setInput("");
|
|
@@ -23786,7 +23823,7 @@ function ConversationView({
|
|
|
23786
23823
|
/* @__PURE__ */ jsx4(Text4, { bold: true, children: "Welcome to Auto!" }),
|
|
23787
23824
|
/* @__PURE__ */ jsx4(Text4, { children: " " }),
|
|
23788
23825
|
/* @__PURE__ */ jsxs4(Box4, { gap: 2, children: [
|
|
23789
|
-
/* @__PURE__ */ jsx4(Text4, { color: "yellow", children: "
|
|
23826
|
+
/* @__PURE__ */ jsx4(Text4, { color: "yellow", children: "Agent " }),
|
|
23790
23827
|
/* @__PURE__ */ jsx4(Text4, { children: sessionName })
|
|
23791
23828
|
] }),
|
|
23792
23829
|
/* @__PURE__ */ jsxs4(Box4, { gap: 2, children: [
|
|
@@ -24710,7 +24747,6 @@ function useSwitchProject() {
|
|
|
24710
24747
|
for (const queryKey of [
|
|
24711
24748
|
["sessions"],
|
|
24712
24749
|
["environments"],
|
|
24713
|
-
["tools"],
|
|
24714
24750
|
["service-accounts"],
|
|
24715
24751
|
["connections"],
|
|
24716
24752
|
["connection-providers"]
|
|
@@ -25007,7 +25043,6 @@ var init_queries = __esm({
|
|
|
25007
25043
|
environments: (apiUrl) => ["environments", apiUrl],
|
|
25008
25044
|
identities: (apiUrl) => ["identities", apiUrl],
|
|
25009
25045
|
sessions: (apiUrl) => ["sessions", apiUrl],
|
|
25010
|
-
tools: (apiUrl) => ["tools", apiUrl],
|
|
25011
25046
|
projects: (apiUrl) => ["projects", apiUrl],
|
|
25012
25047
|
serviceAccounts: (apiUrl) => ["service-accounts", apiUrl],
|
|
25013
25048
|
connections: (apiUrl) => ["connections", apiUrl],
|
|
@@ -26518,7 +26553,7 @@ function HomeView({ apiUrl, notice, returnToSession }) {
|
|
|
26518
26553
|
}
|
|
26519
26554
|
});
|
|
26520
26555
|
if (isLoading) {
|
|
26521
|
-
return /* @__PURE__ */ jsx14(Box13, { height: termHeight, alignItems: "center", justifyContent: "center", children: /* @__PURE__ */ jsx14(Spinner, { label: "loading
|
|
26556
|
+
return /* @__PURE__ */ jsx14(Box13, { height: termHeight, alignItems: "center", justifyContent: "center", children: /* @__PURE__ */ jsx14(Spinner, { label: "loading agents\u2026" }) });
|
|
26522
26557
|
}
|
|
26523
26558
|
if (authErrorMessage && sessions.length === 0 && !projectSelectionRequired) {
|
|
26524
26559
|
return /* @__PURE__ */ jsx14(
|
|
@@ -26539,7 +26574,7 @@ function HomeView({ apiUrl, notice, returnToSession }) {
|
|
|
26539
26574
|
let sectionTitle;
|
|
26540
26575
|
switch (activeSection) {
|
|
26541
26576
|
case "sessions":
|
|
26542
|
-
sectionTitle = "
|
|
26577
|
+
sectionTitle = "Agents";
|
|
26543
26578
|
break;
|
|
26544
26579
|
case "projects":
|
|
26545
26580
|
sectionTitle = `Projects[${projects.length}]`;
|
|
@@ -26560,7 +26595,7 @@ function HomeView({ apiUrl, notice, returnToSession }) {
|
|
|
26560
26595
|
case "runs": {
|
|
26561
26596
|
const selectedSuffix = markedRunIds.length > 0 ? `, ${markedRunIds.length} selected` : "";
|
|
26562
26597
|
if (scopedSession) {
|
|
26563
|
-
sectionTitle = showArchivedRuns ? `
|
|
26598
|
+
sectionTitle = showArchivedRuns ? `Agent Runs[${scopedSession.metadata.name}: ${visibleRuns.length} archived${selectedSuffix}]` : `Agent Runs[${scopedSession.metadata.name}: ${visibleRuns.length}${selectedSuffix}]`;
|
|
26564
26599
|
} else {
|
|
26565
26600
|
sectionTitle = showArchivedRuns ? `Runs[${visibleRuns.length} archived${selectedSuffix}]` : `Runs[${visibleRuns.length}${selectedSuffix}]`;
|
|
26566
26601
|
}
|
|
@@ -26584,7 +26619,7 @@ function HomeView({ apiUrl, notice, returnToSession }) {
|
|
|
26584
26619
|
activeProject && /* @__PURE__ */ jsx14(KV, { label: "Org", value: activeProject.organizationName }),
|
|
26585
26620
|
activeProject && /* @__PURE__ */ jsx14(KV, { label: "Project", value: activeProject.projectName }),
|
|
26586
26621
|
activeProject && /* @__PURE__ */ jsx14(KV, { label: "Role", value: activeProject.role }),
|
|
26587
|
-
selectedSession && /* @__PURE__ */ jsx14(KV, { label: "
|
|
26622
|
+
selectedSession && /* @__PURE__ */ jsx14(KV, { label: "Agent", value: selectedSession.metadata.name }),
|
|
26588
26623
|
runError && /* @__PURE__ */ jsx14(KV, { label: "Error", value: runError, color: "red" }),
|
|
26589
26624
|
isRunMutationPending && /* @__PURE__ */ jsx14(
|
|
26590
26625
|
KV,
|
|
@@ -29628,7 +29663,10 @@ function registerApplyCommands(program, context) {
|
|
|
29628
29663
|
program.command("apply").description("Apply Auto resources from a file or the .auto directory.").option("-f, --file <file>", "single resource file to apply instead").option(
|
|
29629
29664
|
"--directory <directory>",
|
|
29630
29665
|
"directory containing Auto resource files"
|
|
29631
|
-
).option("--dry-run", "print the apply plan without changing resources").option("--no-prune", "leave omitted .auto resources unchanged").option(
|
|
29666
|
+
).option("--dry-run", "print the apply plan without changing resources").option("--no-prune", "leave omitted .auto resources unchanged").option(
|
|
29667
|
+
"--connect",
|
|
29668
|
+
"connect MCP OAuth session tools after applying resources"
|
|
29669
|
+
).option(
|
|
29632
29670
|
"--manual-connect",
|
|
29633
29671
|
"print MCP OAuth authorization URLs instead of opening a browser"
|
|
29634
29672
|
).option("--json", "print the apply response as JSON").option("--api-url <url>", "Auto API base URL").option("--api-base-url <url>", "Auto API base URL").action(async (commandOptions) => {
|
|
@@ -30891,7 +30929,7 @@ var humanQuickstartText = `Get started with auto:
|
|
|
30891
30929
|
1. auto auth login sign in (device flow; account setup in browser)
|
|
30892
30930
|
2. auto connections list see available providers; auto connect <provider>
|
|
30893
30931
|
3. auto apply apply .auto/ resources to your project
|
|
30894
|
-
4. auto run <
|
|
30932
|
+
4. auto run <agent> launch an agent run; add --attach to follow it
|
|
30895
30933
|
|
|
30896
30934
|
Fastest path: paste this into a coding agent running in your repo
|
|
30897
30935
|
(Claude Code, Cursor, Codex):
|
|
@@ -30905,7 +30943,7 @@ Docs and help: auto --help
|
|
|
30905
30943
|
`;
|
|
30906
30944
|
|
|
30907
30945
|
// src/commands/onboard/skill-content.generated.ts
|
|
30908
|
-
var onboardingSkillMarkdown = "# Intent\n\nYou are onboarding a user onto auto. Achieve three goals, in roughly this order, as rapidly as the user's pace allows:\n\n1. **Educate** \u2014 teach the user what auto is and how it works, and get them genuinely excited about it.\n2. **Magic moment** \u2014 get a tailor-made, deployed, proactive workflow live that solves a *real* problem for them, and have them witness it working end to end.\n3. **Self-sufficiency** \u2014 leave them with the building blocks (mental model, CI/CD, a self-improvement loop) to iterate on their auto system rapidly and safely on their own.\n\n# Background\n\n**What is auto?**\n\nauto lets you program software factories the same way you program CI/CD.\n\nCompose agents and triggers into workflows using simple YAML files, and deploy them into the cloud on merge.\n\nYou can use auto to build simple (but effective) automations:\n\n- Ticket / feedback triage and resolution\n- Automated incident / bug response\n- Custom tailored code review agents\n\nYou can also use auto to push the frontier of agentic labor:\n\n- Organized fleets of agents on long-horizon tasks\n- Multi-agent autoresearch / optimization loops\n- Agentic BDR and outbound lead engines\n- \u221E more ideas we've yet to dream up\n\nAnything that can be described in a standard operating procedure can be translated into a \"chart\" of agents and triggers in auto \u2014 the only limit is your imagination.\n\n# Reference material\n\nThis skill ships with documentation and worked examples. Read them before you onboard anyone; cite and copy from them as you go.\n\n| Path | What it covers |\n| --- | --- |\n| `docs/index.md` | The mental model: resources, events, triggers, runs. Start here. |\n| `docs/resource-model.md` | The `.auto/` directory, resource envelopes, and `auto apply` semantics. |\n| `docs/sessions-and-triggers.md` | Sessions, the trigger/event/routing vocabulary, filters, and PR checks. |\n| `docs/environments-and-profiles.md` | Sandbox images, setup steps and caching, and reusable agent profiles. |\n| `docs/tools-and-connections.md` | MCP tools, chat tools, provider connections, secrets, and the runtime tool surface agents see. |\n| `docs/cli.md` | The `auto` CLI command reference. |\n| `docs/ci-cd.md` | Service accounts and GitHub Actions for apply-on-merge. |\n| `examples/index.md` | Prose outline of every example \u2014 read this to know what's on the shelf. |\n| `examples/` | Complete, copyable `.auto/` directories \u2014 one per workflow archetype, each with a README explaining the moving parts. |\n\nIf these relative paths are not available (for example this playbook was printed by `auto onboard --agent` rather than installed as a skill directory), fetch the same content from the skills mirror: `npx skills add auto-dot-sh/skills`, or browse https://github.com/auto-dot-sh/skills.\n\n# Operating principles\n\nHold these throughout the onboarding:\n\n- **Trust live command output over this document.** The CLI evolves; run `auto --help` early and whenever in doubt, and when a command's real output disagrees with anything written here, trust the command output over this document and adapt.\n- **Converse, don't lecture.** Short messages, one question at a time, and adapt your vocabulary to the user's technical level. The pitch should take seconds, not paragraphs.\n- **Ask before changing anything outside `.auto/`.** The onboarding's write surface is the `.auto/` directory (plus the CI workflow in Beat 7, which ships as a PR). Any other file in the user's repo gets touched only with their explicit go-ahead.\n- **Warn before browsers open, and surface the link either way.** `auto auth login`, `auto connect`, `auto tools connect`, and `auto sessions connect` open a browser window *and* print the authorization URL. Give a one-sentence heads-up first (\"this will open your browser to install the GitHub App\") so it doesn't feel like something hijacked their machine. If the browser doesn't pop (some environments can't open one), don't leave the user hunting through command output \u2014 repeat the printed authorization URL back to them on its own line as a clickable fallback, one provider at a time, and tell them plainly to click it.\n- **Signal before going quiet.** Deep repo exploration and waiting on async runs both involve silence. Say what you're about to do and roughly how long it will take.\n- **Enlist the user as the second pair of hands.** They trigger the inputs you can't (tagging a bot in Slack, commenting on a PR) and verify the outputs you can't see (a Slack message arriving). Make those asks explicit and specific.\n- **Hand off, don't hint.** When the user needs to do something, spell it out the *first* time \u2014 before they have to ask. Name the exact trigger (which label, which channel, which command), where to click, and what they'll see when it works. \"Label the issue whenever you're ready\" assumes they can see what's in your head and the YAML you wrote; a numbered \"in Linear: create an issue \u2192 add the `auto-triage` label \u2192 that label is the trigger\" does not. If you catch yourself about to post a one-line \"go ahead and \u2026\", expand it.\n- **Set expectations once, then stay quiet.** When you start watching an async run, tell the user up front roughly how long it takes and what \"normal\" looks like (\"the coder run provisions a sandbox first \u2014 expect a quiet couple of minutes\"), then hold until something *they'd care about* changes. Don't narrate every monitor tick or re-report the same event from a second watcher \u2014 a stream of \"still queued / still running / no news\" reads as noise, not reassurance.\n- **Expect trouble; own the troubleshooting.** OAuth flows fail, secrets get mistyped, webhooks misfire. When something breaks, diagnose it with the CLI (`auto runs list`, `auto runs show`, `auto runs conversation`, `auto apply --dry-run`) rather than asking the user to debug.\n- **Asynchronous means asynchronous.** Triggered runs take time to spawn and act. Tell the user when a wait is expected, and tail run state rather than declaring failure early.\n- **Never fabricate success.** Verify each step actually worked (the apply plan, the trigger receipt, the run conversation) before telling the user it did.\n- **Celebrate real wins.** When a workflow completes end to end for the first time, mark the moment \u2014 emoji, a pun, a little flourish. This should feel fun.\n\n# Procedure\n\nWork through the following beats in order. They are a roadmap, not a script \u2014 skip or reorder when the user's situation clearly calls for it (for example, a user who already has an account and connections can jump straight to Beat 3).\n\n## Beat 0: Learn auto\n\nBefore talking to the user, make sure you have a working command of the system: read `docs/index.md` for the mental model, skim the rest of `docs/`, and look through `examples/` to internalize what complete workflows look like. You will be drawing on the examples heavily in Beats 3-5.\n\n## Beat 1: Establish rapport\n\n**Your very first message after launching is a plain-language pitch, not a form.** Two or three sentences on what auto is and where it's valuable, then *one* opening question. Do **not** open with `AskUserQuestion` or a multiple-choice menu \u2014 that skips the *Educate* goal and makes the onboarding feel like a config wizard. Lead with words; reach for `AskUserQuestion` only once you're past the pitch and genuinely offering discrete choices (e.g. the hero workflow in Beat 3).\n\nAfter the pitch, shift into lightly interviewing the user. You want to learn:\n\n1. **Who they are and their professional context.**\n - Hobbyist, or evaluating auto for a real business?\n - How technical are they? Engineer, or a more managerial / operational role?\n2. **Where the work that matters most to them happens.**\n - Do they have a GitHub account / organization? Is there a repo that would make a good home for their auto system \u2014 better yet, are you running inside it right now?\n - Do they work out of Slack day-to-day, and could they install auto there?\n - What else is in their operating loop? Linear, Datadog, Sentry, PostHog, Notion, Telegram, internal webhooks, and so on.\n\nKeep this light \u2014 a few questions, not a survey. You're gathering enough signal to propose workflows that will land.\n\n## Beat 2: Get up to speed\n\nIf you are running inside a repo the user has indicated is their focus, tell them you're going to explore it for a few minutes (and that you'll go quiet while a research agent reads the repo) \u2014 then **dispatch a subagent to do the deep read in parallel** rather than reading file-by-file in the main thread. This keeps the conversation responsive and your own context clean, and it forces real exploration instead of leaning on whatever `CLAUDE.md` / `AGENTS.md` happened to load.\n\nSpawn one general-purpose / Explore subagent (or a small fan-out of them for a large monorepo) and have it read **both**:\n\n- **The repo:** what the project does, how the team works (CI, review culture, issue-tracker and chat integrations), the conventions written down in `CLAUDE.md`/`AGENTS.md`/`docs/`, and \u2014 most importantly \u2014 where the recurring, automatable toil is.\n- **This skill's `docs/` and `examples/`**, so the ideas it returns are already expressed in auto's vocabulary (sessions, triggers, profiles) and mapped to a concrete archetype.\n\nHave the subagent return a structured shortlist: for each candidate workflow, a one-line description, the matching archetype, the trigger/event that would fire it, and the *specific evidence in this repo* that the toil is real (a file, a workflow, a documented rule, a past incident). That shortlist is the raw material for Beat 3.\n\nWhen the agent returns, don't just move on \u2014 **surface 1-2 concrete observations to the user** (\"you renumber migrations by hand and a missed renumber caused a prod outage; your `postman/collection.json` updates are marked NOT OPTIONAL\") so they see the exploration paid off and trust that your pitches are grounded in *their* code. If `CLAUDE.md` already told you something, say so and confirm it against the repo rather than presenting it as discovery.\n\n## Beat 3: Present some options\n\nCombine what you know about the user, their goals, and their codebase, and brainstorm at least three workflows they could deploy *today*. Anchor on the archetypes in `examples/index.md` \u2014 code review, issue triage, incident response, chat assistant, scheduled digest, an orchestrated agent fleet, a research/optimization loop, an outbound lead engine \u2014 but tailor each pitch to their actual stack and pain points (\"a review agent that enforces *your* `docs/style.md`\", not \"a code review bot\"). The archetypes are anchors, not a menu: if the user's situation suggests a useful workflow that matches none of them, it is absolutely fair game \u2014 pitch it. Calibrate ambition to the user: the simple automations land the magic moment fastest, while the frontier examples (fleet, research loop) make better second acts unless the user is clearly hungry for them.\n\nPresent the options as a question, one line each on what the workflow would do for them, and let them pick \u2014 including the option to propose their own idea instead. The winner becomes the hero use case.\n\n## Beat 4: Setup & smoke test\n\nGet the user from zero to a deployed, *hollow* version of the hero workflow \u2014 a shell that proves every input and output is wired up before you invest in the real logic. In practice:\n\n1. **Install the CLI**: `npm install -g @autohq/cli` (requires Node 20+). Verify with `auto --version`.\n2. **Sign in**: `auto auth login` (heads-up: opens a browser; account creation happens there too). You're blocked on the user completing the flow either way, so wait for them \u2014 don't busy yourself with other work mid-sign-in, which only confuses things. When you're driving from a terminal with no browser, `auto auth login --device` prints a code the user enters in their browser.\n3. **Create the org and project**: `auto orgs create` / `auto projects create`. Ask the user what they want to name them \u2014 don't pick names for them.\n4. **Connect providers**: `auto connections list --available` to see what's offered, then `auto connect <provider>` for each one the workflow needs (heads-up: browser again). GitHub connects as an App installation; Slack and Linear as OAuth grants.\n5. **Scaffold `.auto/`**: create the directory in their repo and draft the minimal resources \u2014 an environment, a profile, any tool definitions, and a session with the workflow's trigger. Copy from the matching example and strip it down.\n6. **Apply**: `auto apply --dry-run` first, show the user the plan, then `auto apply`.\n\nThen run the smoke test. Its exact shape depends on the use case, but the goal is always the same: verify that the trigger fires and the agent's output surfaces reach the user. A workflow almost always involves some communication channel, so a good smoke test \"breaks the fourth wall\" \u2014 have the hollow agent send the user a hello in Slack (or wherever they live).\n\nEnlist the user, and **hand off, don't hint** (see the operating principle): when you ask them to fire the input only they can fire, give the full, numbered steps the first time \u2014 *which* label on *which* issue, *which* channel to create, the exact command to run, and what they'll see when it lands. Don't post \"go ahead and label the issue\" and assume they know a label is the trigger; that one-liner is what makes a user ask \"wait, what exactly do I do?\". Right after `auto apply`, before you start watching, tell them in plain words what just deployed and what their next action is. Then **set expectations once** \u2014 \"the run takes a minute or two to spawn; I'll tell you when it acts\" \u2014 and watch progress yourself with `auto runs list` and `auto attach <run-id>` (live stream; `auto runs conversation <run-id>` for a snapshot), surfacing only meaningful changes rather than every tick. Troubleshoot until the smoke test passes.\n\nIf a channel install is blocked \u2014 for example the Slack workspace requires admin approval \u2014 don't stall the onboarding on it. Pick an output surface the user can verify without the channel (a PR comment, a GitHub check, the run transcript via `auto runs conversation`), continue the beats, and circle back to realize the channel identity once the approval lands.\n\n## Beat 5: Build the real thing\n\nWith inputs and outputs proven, flesh the workflow out to its real form in `.auto/` \u2014 the full profile instructions, the real prompt, the filters and routing that make it production-shaped. Tell the user what you're changing, then apply it.\n\nTest end to end: trigger the workflow for real, follow the run, and enlist the user again for out-of-band inputs and output verification. Iterate until you've witnessed one complete, successful run of the real workflow.\n\nThen celebrate. This is the magic moment \u2014 act like it. \u{1F389}\n\n## Beat 6: Bring the user up to speed\n\nWalk the user through what you built, piece by piece: which environment, profile, tools, session, and triggers you composed, how an event flows through them to become a run, and where each file lives in `.auto/`. Show short snippets from the actual files rather than describing them abstractly.\n\nThen ask: anything they want to dig into further, or shall we set up CI/CD?\n\n## Beat 7: Set up CI/CD\n\nMake merges to their default branch the deployment mechanism for their auto system (this is the \"program software factories like CI/CD\" promise made literal). Following `docs/ci-cd.md`:\n\n1. Create a service account: have the *user* run `auto service-account create ci-apply --preset applier` in their own terminal (and a second `--preset read-only` account for PR dry-runs if they want plan-on-PR). The token prints exactly once and goes straight into a repo secret \u2014 it must never be pasted into the conversation, and if you run the command yourself it lands in your transcript.\n2. Add a GitHub Actions workflow that runs `auto apply --dry-run` on pull requests and `auto apply` on pushes to the default branch.\n3. Tell the user exactly which secret to create where in their repo settings (the service-account token, shown once at creation).\n4. Open a PR containing `.auto/` and the new workflow, and ask the user to merge it.\n\nWhen the merge lands, verify the apply ran cleanly in Actions, and congratulate them \u2014 their factory now ships itself.\n\n## Beat 8: Set up a self-improvement loop\n\nTell the user there's one last step we've found high-leverage: a workflow that watches their auto system itself \u2014 sweeping recent runs for failures, bottlenecks, and drift, and proposing improvements. Explain that it's just another auto workflow, fully theirs to tune.\n\nIf they're in, copy `examples/self-improvement/` and tailor it to their setup (their channel, their sessions, their cadence). Since CI/CD is now live, do **not** run `auto apply` yourself \u2014 open a PR and let them merge it. That's the new normal, and modeling it is the point.\n\n## Beat 9: Conclusion\n\nTell the user they're all set: a live workflow, CI/CD for their auto system, and a loop that helps it improve. Recap in two or three lines what now exists. Offer to help them build or optimize additional workflows \u2014 Beat 3's runner-up ideas are natural next candidates.\n";
|
|
30946
|
+
var onboardingSkillMarkdown = "# Intent\n\nYou are onboarding a user onto auto. Achieve three goals, in roughly this order, as rapidly as the user's pace allows:\n\n1. **Educate** \u2014 teach the user what auto is and how it works, and get them genuinely excited about it.\n2. **Magic moment** \u2014 get a tailor-made, deployed, proactive workflow live that solves a *real* problem for them, and have them witness it working end to end.\n3. **Self-sufficiency** \u2014 leave them with the building blocks (mental model, CI/CD, a self-improvement loop) to iterate on their auto system rapidly and safely on their own.\n\n# Background\n\n**What is auto?**\n\nauto lets you program software factories the same way you program CI/CD.\n\nCompose agents and triggers into workflows using simple YAML files, and deploy them into the cloud on merge.\n\nYou can use auto to build simple (but effective) automations:\n\n- Ticket / feedback triage and resolution\n- Automated incident / bug response\n- Custom tailored code review agents\n\nYou can also use auto to push the frontier of agentic labor:\n\n- Organized fleets of agents on long-horizon tasks\n- Multi-agent autoresearch / optimization loops\n- Agentic BDR and outbound lead engines\n- \u221E more ideas we've yet to dream up\n\nAnything that can be described in a standard operating procedure can be translated into a \"chart\" of agents and triggers in auto \u2014 the only limit is your imagination.\n\n# Reference material\n\nThis skill ships with documentation and worked examples. Read them before you onboard anyone; cite and copy from them as you go.\n\n| Path | What it covers |\n| --- | --- |\n| `docs/index.md` | The mental model: resources, events, triggers, runs. Start here. |\n| `docs/resource-model.md` | The `.auto/` directory, resource envelopes, and `auto apply` semantics. |\n| `docs/sessions-and-triggers.md` | Agents, the trigger/event/routing vocabulary, filters, and PR checks. |\n| `docs/environments-and-profiles.md` | Sandbox images, setup steps and caching, and reusable agent profiles. |\n| `docs/tools-and-connections.md` | MCP tools, chat tools, provider connections, secrets, and the runtime tool surface agents see. |\n| `docs/cli.md` | The `auto` CLI command reference. |\n| `docs/ci-cd.md` | Service accounts and GitHub Actions for apply-on-merge. |\n| `examples/index.md` | Prose outline of every example \u2014 read this to know what's on the shelf. |\n| `examples/` | Complete, copyable `.auto/` directories \u2014 one per workflow archetype, each with a README explaining the moving parts. |\n\nIf these relative paths are not available (for example this playbook was printed by `auto onboard --agent` rather than installed as a skill directory), fetch the same content from the skills mirror: `npx skills add auto-dot-sh/skills`, or browse https://github.com/auto-dot-sh/skills.\n\n# Operating principles\n\nHold these throughout the onboarding:\n\n- **Trust live command output over this document.** The CLI evolves; run `auto --help` early and whenever in doubt, and when a command's real output disagrees with anything written here, trust the command output over this document and adapt.\n- **Converse, don't lecture.** Short messages, one question at a time, and adapt your vocabulary to the user's technical level. The pitch should take seconds, not paragraphs.\n- **Ask before changing anything outside `.auto/`.** The onboarding's write surface is the `.auto/` directory (plus the CI workflow in Beat 7, which ships as a PR). Any other file in the user's repo gets touched only with their explicit go-ahead.\n- **Warn before browsers open, and surface the link either way.** `auto auth login`, `auto connect`, and `auto agents connect` open a browser window *and* print the authorization URL. Give a one-sentence heads-up first (\"this will open your browser to install the GitHub App\") so it doesn't feel like something hijacked their machine. If the browser doesn't pop (some environments can't open one), don't leave the user hunting through command output \u2014 repeat the printed authorization URL back to them on its own line as a clickable fallback, one provider at a time, and tell them plainly to click it.\n- **Signal before going quiet.** Deep repo exploration and waiting on async runs both involve silence. Say what you're about to do and roughly how long it will take.\n- **Enlist the user as the second pair of hands.** They trigger the inputs you can't (tagging a bot in Slack, commenting on a PR) and verify the outputs you can't see (a Slack message arriving). Make those asks explicit and specific.\n- **Hand off, don't hint.** When the user needs to do something, spell it out the *first* time \u2014 before they have to ask. Name the exact trigger (which label, which channel, which command), where to click, and what they'll see when it works. \"Label the issue whenever you're ready\" assumes they can see what's in your head and the YAML you wrote; a numbered \"in Linear: create an issue \u2192 add the `auto-triage` label \u2192 that label is the trigger\" does not. If you catch yourself about to post a one-line \"go ahead and \u2026\", expand it.\n- **Set expectations once, then stay quiet.** When you start watching an async run, tell the user up front roughly how long it takes and what \"normal\" looks like (\"the coder run provisions a sandbox first \u2014 expect a quiet couple of minutes\"), then hold until something *they'd care about* changes. Don't narrate every monitor tick or re-report the same event from a second watcher \u2014 a stream of \"still queued / still running / no news\" reads as noise, not reassurance.\n- **Expect trouble; own the troubleshooting.** OAuth flows fail, secrets get mistyped, webhooks misfire. When something breaks, diagnose it with the CLI (`auto runs list`, `auto runs show`, `auto runs conversation`, `auto apply --dry-run`) rather than asking the user to debug.\n- **Asynchronous means asynchronous.** Triggered runs take time to spawn and act. Tell the user when a wait is expected, and tail run state rather than declaring failure early.\n- **Never fabricate success.** Verify each step actually worked (the apply plan, the trigger receipt, the run conversation) before telling the user it did.\n- **Celebrate real wins.** When a workflow completes end to end for the first time, mark the moment \u2014 emoji, a pun, a little flourish. This should feel fun.\n\n# Procedure\n\nWork through the following beats in order. They are a roadmap, not a script \u2014 skip or reorder when the user's situation clearly calls for it (for example, a user who already has an account and connections can jump straight to Beat 3).\n\n## Beat 0: Learn auto\n\nBefore talking to the user, make sure you have a working command of the system: read `docs/index.md` for the mental model, skim the rest of `docs/`, and look through `examples/` to internalize what complete workflows look like. You will be drawing on the examples heavily in Beats 3-5.\n\n## Beat 1: Establish rapport\n\n**Your very first message after launching is a plain-language pitch, not a form.** Two or three sentences on what auto is and where it's valuable, then *one* opening question. Do **not** open with `AskUserQuestion` or a multiple-choice menu \u2014 that skips the *Educate* goal and makes the onboarding feel like a config wizard. Lead with words; reach for `AskUserQuestion` only once you're past the pitch and genuinely offering discrete choices (e.g. the hero workflow in Beat 3).\n\nAfter the pitch, shift into lightly interviewing the user. You want to learn:\n\n1. **Who they are and their professional context.**\n - Hobbyist, or evaluating auto for a real business?\n - How technical are they? Engineer, or a more managerial / operational role?\n2. **Where the work that matters most to them happens.**\n - Do they have a GitHub account / organization? Is there a repo that would make a good home for their auto system \u2014 better yet, are you running inside it right now?\n - Do they work out of Slack day-to-day, and could they install auto there?\n - What else is in their operating loop? Linear, Datadog, Sentry, PostHog, Notion, Telegram, internal webhooks, and so on.\n\nKeep this light \u2014 a few questions, not a survey. You're gathering enough signal to propose workflows that will land.\n\n## Beat 2: Get up to speed\n\nIf you are running inside a repo the user has indicated is their focus, tell them you're going to explore it for a few minutes (and that you'll go quiet while a research agent reads the repo) \u2014 then **dispatch a subagent to do the deep read in parallel** rather than reading file-by-file in the main thread. This keeps the conversation responsive and your own context clean, and it forces real exploration instead of leaning on whatever `CLAUDE.md` / `AGENTS.md` happened to load.\n\nSpawn one general-purpose / Explore subagent (or a small fan-out of them for a large monorepo) and have it read **both**:\n\n- **The repo:** what the project does, how the team works (CI, review culture, issue-tracker and chat integrations), the conventions written down in `CLAUDE.md`/`AGENTS.md`/`docs/`, and \u2014 most importantly \u2014 where the recurring, automatable toil is.\n- **This skill's `docs/` and `examples/`**, so the ideas it returns are already expressed in auto's vocabulary (agents, triggers, profiles) and mapped to a concrete archetype.\n\nHave the subagent return a structured shortlist: for each candidate workflow, a one-line description, the matching archetype, the trigger/event that would fire it, and the *specific evidence in this repo* that the toil is real (a file, a workflow, a documented rule, a past incident). That shortlist is the raw material for Beat 3.\n\nWhen the agent returns, don't just move on \u2014 **surface 1-2 concrete observations to the user** (\"you renumber migrations by hand and a missed renumber caused a prod outage; your `postman/collection.json` updates are marked NOT OPTIONAL\") so they see the exploration paid off and trust that your pitches are grounded in *their* code. If `CLAUDE.md` already told you something, say so and confirm it against the repo rather than presenting it as discovery.\n\n## Beat 3: Present some options\n\nCombine what you know about the user, their goals, and their codebase, and brainstorm at least three workflows they could deploy *today*. Anchor on the archetypes in `examples/index.md` \u2014 code review, issue triage, incident response, chat assistant, scheduled digest, an orchestrated agent fleet, a research/optimization loop, an outbound lead engine \u2014 but tailor each pitch to their actual stack and pain points (\"a review agent that enforces *your* `docs/style.md`\", not \"a code review bot\"). The archetypes are anchors, not a menu: if the user's situation suggests a useful workflow that matches none of them, it is absolutely fair game \u2014 pitch it. Calibrate ambition to the user: the simple automations land the magic moment fastest, while the frontier examples (fleet, research loop) make better second acts unless the user is clearly hungry for them.\n\nPresent the options as a question, one line each on what the workflow would do for them, and let them pick \u2014 including the option to propose their own idea instead. The winner becomes the hero use case.\n\n## Beat 4: Setup & smoke test\n\nGet the user from zero to a deployed, *hollow* version of the hero workflow \u2014 a shell that proves every input and output is wired up before you invest in the real logic. In practice:\n\n1. **Install the CLI**: `npm install -g @autohq/cli` (requires Node 20+). Verify with `auto --version`.\n2. **Sign in**: `auto auth login` (heads-up: opens a browser; account creation happens there too). You're blocked on the user completing the flow either way, so wait for them \u2014 don't busy yourself with other work mid-sign-in, which only confuses things. When you're driving from a terminal with no browser, `auto auth login --device` prints a code the user enters in their browser.\n3. **Create the org and project**: `auto orgs create` / `auto projects create`. Ask the user what they want to name them \u2014 don't pick names for them.\n4. **Connect providers**: `auto connections list --available` to see what's offered, then `auto connect <provider>` for each one the workflow needs (heads-up: browser again). GitHub connects as an App installation; Slack and Linear as OAuth grants.\n5. **Scaffold `.auto/`**: create the directory in their repo and draft the minimal resources \u2014 an environment, a profile, any tool definitions, and an agent with the workflow's trigger. Copy from the matching example and strip it down.\n6. **Apply**: `auto apply --dry-run` first, show the user the plan, then `auto apply`.\n\nThen run the smoke test. Its exact shape depends on the use case, but the goal is always the same: verify that the trigger fires and the agent's output surfaces reach the user. A workflow almost always involves some communication channel, so a good smoke test \"breaks the fourth wall\" \u2014 have the hollow agent send the user a hello in Slack (or wherever they live).\n\nEnlist the user, and **hand off, don't hint** (see the operating principle): when you ask them to fire the input only they can fire, give the full, numbered steps the first time \u2014 *which* label on *which* issue, *which* channel to create, the exact command to run, and what they'll see when it lands. Don't post \"go ahead and label the issue\" and assume they know a label is the trigger; that one-liner is what makes a user ask \"wait, what exactly do I do?\". Right after `auto apply`, before you start watching, tell them in plain words what just deployed and what their next action is. Then **set expectations once** \u2014 \"the run takes a minute or two to spawn; I'll tell you when it acts\" \u2014 and watch progress yourself with `auto runs list` and `auto attach <run-id>` (live stream; `auto runs conversation <run-id>` for a snapshot), surfacing only meaningful changes rather than every tick. Troubleshoot until the smoke test passes.\n\nIf a channel install is blocked \u2014 for example the Slack workspace requires admin approval \u2014 don't stall the onboarding on it. Pick an output surface the user can verify without the channel (a PR comment, a GitHub check, the run transcript via `auto runs conversation`), continue the beats, and circle back to realize the channel identity once the approval lands.\n\n## Beat 5: Build the real thing\n\nWith inputs and outputs proven, flesh the workflow out to its real form in `.auto/` \u2014 the full profile instructions, the real prompt, the filters and routing that make it production-shaped. Tell the user what you're changing, then apply it.\n\nTest end to end: trigger the workflow for real, follow the run, and enlist the user again for out-of-band inputs and output verification. Iterate until you've witnessed one complete, successful run of the real workflow.\n\nThen celebrate. This is the magic moment \u2014 act like it. \u{1F389}\n\n## Beat 6: Bring the user up to speed\n\nWalk the user through what you built, piece by piece: which environment, profile, tools, agent, and triggers you composed, how an event flows through them to become a run, and where each file lives in `.auto/`. Show short snippets from the actual files rather than describing them abstractly.\n\nThen ask: anything they want to dig into further, or shall we set up CI/CD?\n\n## Beat 7: Set up CI/CD\n\nMake merges to their default branch the deployment mechanism for their auto system (this is the \"program software factories like CI/CD\" promise made literal). Following `docs/ci-cd.md`:\n\n1. Create a service account: have the *user* run `auto service-account create ci-apply --preset applier` in their own terminal (and a second `--preset read-only` account for PR dry-runs if they want plan-on-PR). The token prints exactly once and goes straight into a repo secret \u2014 it must never be pasted into the conversation, and if you run the command yourself it lands in your transcript.\n2. Add a GitHub Actions workflow that runs `auto apply --dry-run` on pull requests and `auto apply` on pushes to the default branch.\n3. Tell the user exactly which secret to create where in their repo settings (the service-account token, shown once at creation).\n4. Open a PR containing `.auto/` and the new workflow, and ask the user to merge it.\n\nWhen the merge lands, verify the apply ran cleanly in Actions, and congratulate them \u2014 their factory now ships itself.\n\n## Beat 8: Set up a self-improvement loop\n\nTell the user there's one last step we've found high-leverage: a workflow that watches their auto system itself \u2014 sweeping recent runs for failures, bottlenecks, and drift, and proposing improvements. Explain that it's just another auto workflow, fully theirs to tune.\n\nIf they're in, copy `examples/self-improvement/` and tailor it to their setup (their channel, their agents, their cadence). Since CI/CD is now live, do **not** run `auto apply` yourself \u2014 open a PR and let them merge it. That's the new normal, and modeling it is the point.\n\n## Beat 9: Conclusion\n\nTell the user they're all set: a live workflow, CI/CD for their auto system, and a loop that helps it improve. Recap in two or three lines what now exists. Offer to help them build or optimize additional workflows \u2014 Beat 3's runner-up ideas are natural next candidates.\n";
|
|
30909
30947
|
|
|
30910
30948
|
// src/commands/onboard/commands.ts
|
|
30911
30949
|
function registerOnboardCommands(program, context) {
|
|
@@ -32231,7 +32269,7 @@ function collect(value, previous = []) {
|
|
|
32231
32269
|
return [...previous, value];
|
|
32232
32270
|
}
|
|
32233
32271
|
function registerRunCommands(program, context) {
|
|
32234
|
-
const runs = program.command("runs").description("Inspect
|
|
32272
|
+
const runs = program.command("runs").description("Inspect agent runs.");
|
|
32235
32273
|
runs.command("list").description("List runs for a session or the whole project.").option("--session <name>", "session name").option("--include-archived", "include archived runs").option("--status <status>", "filter by run status (repeatable)", collect).option("--since <iso-timestamp>", "only runs created after this time").option("--limit <count>", "maximum runs to return", parsePositiveInteger).option("--api-url <url>", "Auto API base URL").option("--api-base-url <url>", "Auto API base URL").action(async (options) => {
|
|
32236
32274
|
await handleRunsList(context, options.session, options);
|
|
32237
32275
|
});
|
|
@@ -32301,7 +32339,7 @@ function registerRunCommands(program, context) {
|
|
|
32301
32339
|
runs.command("stop").description("Stop live runs and shut down their agent sessions.").argument("<run-ids...>", "run id(s)").option("--reason <reason>", "reason recorded with the stop").option("--api-url <url>", "Auto API base URL").option("--api-base-url <url>", "Auto API base URL").action(async (runIds, commandOptions) => {
|
|
32302
32340
|
await stopRunsAction(context, runIds, commandOptions);
|
|
32303
32341
|
});
|
|
32304
|
-
runs.command("benchmark-startup").description("Launch
|
|
32342
|
+
runs.command("benchmark-startup").description("Launch an agent run and measure time until awaiting.").requiredOption("--session <name>", "agent name").option("-m, --message <message>", "initial message for the run").option(
|
|
32305
32343
|
"--interactive",
|
|
32306
32344
|
"start without the default initial prompt unless --message is provided"
|
|
32307
32345
|
).option(
|
|
@@ -32323,7 +32361,7 @@ function registerRunCommands(program, context) {
|
|
|
32323
32361
|
).option("--json", "write a single JSON result object").option("--api-url <url>", "Auto API base URL").option("--api-base-url <url>", "Auto API base URL").action(async (options) => {
|
|
32324
32362
|
await benchmarkStartupAction(context, options);
|
|
32325
32363
|
});
|
|
32326
|
-
program.command("interactive").description("Launch
|
|
32364
|
+
program.command("interactive").description("Launch an agent run, stream it, and send typed messages.").argument("<session>", "agent name").option("-m, --message <message>", "initial message for the run").option("--api-url <url>", "Auto API base URL").option("--api-base-url <url>", "Auto API base URL").option("--operator <name>", "operator name for attach/detach messages").option(
|
|
32327
32365
|
"--attach-message",
|
|
32328
32366
|
"send the automated attach message after creating the run"
|
|
32329
32367
|
).option("--no-attach-message", "do not send the automated attach message").option("--no-detach-message", "do not send the automated detach message").action(
|
|
@@ -32687,7 +32725,7 @@ async function connectSessionPresence2(input) {
|
|
|
32687
32725
|
}
|
|
32688
32726
|
for (const pending of result.pending) {
|
|
32689
32727
|
input.writeOutput(
|
|
32690
|
-
`connect
|
|
32728
|
+
`connect agent/${input.session} workspace/${pending.workspace} connection/${pending.connection}`
|
|
32691
32729
|
);
|
|
32692
32730
|
input.writeOutput(`authorization_url ${pending.authorizationUrl}`);
|
|
32693
32731
|
if (pending.suggestedUsername) {
|
|
@@ -32748,7 +32786,7 @@ async function connectSessionPresence2(input) {
|
|
|
32748
32786
|
}
|
|
32749
32787
|
if (!realized) {
|
|
32750
32788
|
throw new Error(
|
|
32751
|
-
telegram ? `Timed out waiting for the Telegram bot to be confirmed under ${pending.workspace}. Confirm the creation dialog in Telegram, then re-run \`auto
|
|
32789
|
+
telegram ? `Timed out waiting for the Telegram bot to be confirmed under ${pending.workspace}. Confirm the creation dialog in Telegram, then re-run \`auto agents connect ${input.session}\`.` : `Timed out waiting for the install in workspace ${pending.workspace}. Re-run \`auto agents connect ${input.session}\` to retry.`
|
|
32752
32790
|
);
|
|
32753
32791
|
}
|
|
32754
32792
|
}
|
|
@@ -32756,19 +32794,19 @@ async function connectSessionPresence2(input) {
|
|
|
32756
32794
|
}
|
|
32757
32795
|
function realizedIdentityLine(session, identity2) {
|
|
32758
32796
|
const handle = identity2.botUsername ? `persona/@${identity2.botUsername}` : `bot/${identity2.botUserId ?? ""}`;
|
|
32759
|
-
return `connected
|
|
32797
|
+
return `connected agent/${session} workspace/${identity2.workspace} ${handle}`;
|
|
32760
32798
|
}
|
|
32761
32799
|
function staleScopesLine(session, identity2) {
|
|
32762
32800
|
if (!identity2.missingScopes?.length) {
|
|
32763
32801
|
return void 0;
|
|
32764
32802
|
}
|
|
32765
|
-
return ` workspace "${identity2.workspace}" was installed before scopes ${identity2.missingScopes.join(", ")} were added; refresh with \`auto
|
|
32803
|
+
return ` workspace "${identity2.workspace}" was installed before scopes ${identity2.missingScopes.join(", ")} were added; refresh with \`auto agents connect ${session} --reconnect\``;
|
|
32766
32804
|
}
|
|
32767
32805
|
function manualGuidance(input) {
|
|
32768
32806
|
if (input.allTelegram) {
|
|
32769
|
-
return `Open each creation link and confirm the new bot in Telegram; Auto provisions it automatically. Re-run \`auto
|
|
32807
|
+
return `Open each creation link and confirm the new bot in Telegram; Auto provisions it automatically. Re-run \`auto agents connect ${input.session}\` (or check presence) to see it realize.`;
|
|
32770
32808
|
}
|
|
32771
|
-
return input.reconnect ? "Open each authorization URL to reinstall the agent app; the callback page confirms the refreshed tokens." : "Open each authorization URL to install the agent app, then re-run with no flags or check `
|
|
32809
|
+
return input.reconnect ? "Open each authorization URL to reinstall the agent app; the callback page confirms the refreshed tokens." : "Open each authorization URL to install the agent app, then re-run with no flags or check `agents connect` again.";
|
|
32772
32810
|
}
|
|
32773
32811
|
async function promptForIconUploads(input, options) {
|
|
32774
32812
|
const presence = await input.client.getSessionPresence(
|
|
@@ -32785,14 +32823,14 @@ async function promptForIconUploads(input, options) {
|
|
|
32785
32823
|
for (const identity2 of drifted) {
|
|
32786
32824
|
const settingsUrl = `${SLACK_APPS_URL}/${identity2.appId}/general`;
|
|
32787
32825
|
input.writeOutput(
|
|
32788
|
-
`Workspace "${identity2.workspace}" agent app icon does not match the
|
|
32826
|
+
`Workspace "${identity2.workspace}" agent app icon does not match the agent avatar yet. Slack has no app-icon API; upload the avatar image once under "Display Information" at ${settingsUrl}`
|
|
32789
32827
|
);
|
|
32790
32828
|
if (identity2.avatarUrl) {
|
|
32791
32829
|
input.writeOutput(`avatar image: ${identity2.avatarUrl}`);
|
|
32792
32830
|
}
|
|
32793
32831
|
if (!canPrompt) {
|
|
32794
32832
|
input.writeOutput(
|
|
32795
|
-
`Then re-run \`auto
|
|
32833
|
+
`Then re-run \`auto agents connect ${input.session}\` interactively to record the upload.`
|
|
32796
32834
|
);
|
|
32797
32835
|
continue;
|
|
32798
32836
|
}
|
|
@@ -32832,7 +32870,7 @@ async function promptForIconUploads(input, options) {
|
|
|
32832
32870
|
options
|
|
32833
32871
|
);
|
|
32834
32872
|
input.writeOutput(
|
|
32835
|
-
`recorded icon
|
|
32873
|
+
`recorded icon agent/${input.session} workspace/${identity2.workspace} sha256/${recorded.appliedIconSha256.slice(0, 12)}`
|
|
32836
32874
|
);
|
|
32837
32875
|
}
|
|
32838
32876
|
}
|
|
@@ -32939,17 +32977,17 @@ async function launchRun(input) {
|
|
|
32939
32977
|
|
|
32940
32978
|
// src/commands/sessions/commands.ts
|
|
32941
32979
|
function registerSessionCommands(program, context) {
|
|
32942
|
-
program.command("run").description("Launch
|
|
32980
|
+
program.command("run").description("Launch an agent run on the Auto platform.").argument("<session>", "agent name").option("-m, --message <message>", "initial message for the run").option("-a, --attach", "stream the run conversation after launch").option("--api-url <url>", "Auto API base URL").option("--api-base-url <url>", "Auto API base URL").action(async (sessionName, commandOptions) => {
|
|
32943
32981
|
await launchRun({
|
|
32944
32982
|
sessionName,
|
|
32945
32983
|
commandOptions,
|
|
32946
32984
|
context
|
|
32947
32985
|
});
|
|
32948
32986
|
});
|
|
32949
|
-
const sessions = program.command("sessions").description("Manage
|
|
32987
|
+
const sessions = program.command("agents").alias("sessions").description("Manage Agent resources.");
|
|
32950
32988
|
sessions.command("connect").description(
|
|
32951
|
-
"Connect
|
|
32952
|
-
).argument("<session>", "
|
|
32989
|
+
"Connect an agent's provider presence (e.g. install its Slack agent app)."
|
|
32990
|
+
).argument("<session>", "agent resource name").option("--manual", "print authorization URLs without opening a browser").option(
|
|
32953
32991
|
"--reconnect",
|
|
32954
32992
|
"re-run the install for already-connected workspaces (repairs stranded bot tokens)"
|
|
32955
32993
|
).option("--api-url <url>", "Auto API base URL").option("--api-base-url <url>", "Auto API base URL").action(
|
|
@@ -32965,9 +33003,7 @@ function registerSessionCommands(program, context) {
|
|
|
32965
33003
|
});
|
|
32966
33004
|
}
|
|
32967
33005
|
);
|
|
32968
|
-
program.command("run-and-attach").description(
|
|
32969
|
-
"Launch a session run and immediately stream its conversation."
|
|
32970
|
-
).argument("<session>", "session name").option("-m, --message <message>", "initial message for the run").option("--api-url <url>", "Auto API base URL").option("--api-base-url <url>", "Auto API base URL").action(async (sessionName, commandOptions) => {
|
|
33006
|
+
program.command("run-and-attach").description("Launch an agent run and immediately stream its conversation.").argument("<session>", "agent name").option("-m, --message <message>", "initial message for the run").option("--api-url <url>", "Auto API base URL").option("--api-base-url <url>", "Auto API base URL").action(async (sessionName, commandOptions) => {
|
|
32971
33007
|
await launchRun({
|
|
32972
33008
|
sessionName,
|
|
32973
33009
|
commandOptions: {
|
|
@@ -32979,21 +33015,6 @@ function registerSessionCommands(program, context) {
|
|
|
32979
33015
|
});
|
|
32980
33016
|
}
|
|
32981
33017
|
|
|
32982
|
-
// src/commands/tools/commands.ts
|
|
32983
|
-
init_connect();
|
|
32984
|
-
function registerToolCommands(program, context) {
|
|
32985
|
-
const tools = program.command("tools").description("Manage Tool resources.");
|
|
32986
|
-
tools.command("connect").description("Start an OAuth connection flow for a remote MCP Tool.").argument("<tool>", "tool resource name").option("--manual", "print the authorization URL without opening a browser").option("--api-url <url>", "Auto API base URL").option("--api-base-url <url>", "Auto API base URL").action(async (tool, commandOptions) => {
|
|
32987
|
-
await connectTool({
|
|
32988
|
-
tool,
|
|
32989
|
-
apiBaseUrl: apiUrlFromOptions(context, commandOptions),
|
|
32990
|
-
manual: commandOptions.manual,
|
|
32991
|
-
client: createContextApiClient(context),
|
|
32992
|
-
writeOutput: context.writeOutput
|
|
32993
|
-
});
|
|
32994
|
-
});
|
|
32995
|
-
}
|
|
32996
|
-
|
|
32997
33018
|
// src/cli/program.ts
|
|
32998
33019
|
init_path();
|
|
32999
33020
|
init_profiles();
|
|
@@ -33161,7 +33182,6 @@ function createProgram(options = {}) {
|
|
|
33161
33182
|
registerProjectCommands(program, context);
|
|
33162
33183
|
registerConnectionCommands(program, context);
|
|
33163
33184
|
registerSecretCommands(program, context);
|
|
33164
|
-
registerToolCommands(program, context);
|
|
33165
33185
|
registerSessionCommands(program, context);
|
|
33166
33186
|
registerRunCommands(program, context);
|
|
33167
33187
|
return program;
|