@autohq/cli 0.1.146 → 0.1.148
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/README.md +6 -6
- package/dist/agent-bridge.js +217 -195
- package/dist/index.js +1278 -1167
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -184,7 +184,7 @@ function currentProfileName(path2 = defaultConfigPath()) {
|
|
|
184
184
|
function writeConfig(config2, path2 = defaultConfigPath()) {
|
|
185
185
|
const profilePath = activeProfilePath(path2);
|
|
186
186
|
if (!profilePath) {
|
|
187
|
-
throw new Error("Not logged in.
|
|
187
|
+
throw new Error("Not logged in. Session `auto auth login` first.");
|
|
188
188
|
}
|
|
189
189
|
writeProfileFile(config2, profilePath);
|
|
190
190
|
}
|
|
@@ -16061,7 +16061,7 @@ var init_zod = __esm({
|
|
|
16061
16061
|
});
|
|
16062
16062
|
|
|
16063
16063
|
// ../../packages/schemas/src/ids.ts
|
|
16064
|
-
var OpaqueIdSchema, ProfileIdSchema, EnvironmentIdSchema, IdentityIdSchema, ConnectionIdSchema, ExternalAccountIdSchema, OrganizationIdSchema, ProjectIdSchema, ProviderGrantIdSchema, ServiceAccountIdSchema, AgentIdSchema,
|
|
16064
|
+
var OpaqueIdSchema, ProfileIdSchema, EnvironmentIdSchema, IdentityIdSchema, ConnectionIdSchema, ExternalAccountIdSchema, OrganizationIdSchema, ProjectIdSchema, ProviderGrantIdSchema, ServiceAccountIdSchema, AgentIdSchema, SessionIdSchema, SessionCommandIdSchema, RuntimeIdSchema, RuntimeBridgeLeaseIdSchema, EnvironmentSetupSnapshotIdSchema, UserIdSchema;
|
|
16065
16065
|
var init_ids = __esm({
|
|
16066
16066
|
"../../packages/schemas/src/ids.ts"() {
|
|
16067
16067
|
"use strict";
|
|
@@ -16077,8 +16077,8 @@ var init_ids = __esm({
|
|
|
16077
16077
|
ProviderGrantIdSchema = OpaqueIdSchema.brand();
|
|
16078
16078
|
ServiceAccountIdSchema = OpaqueIdSchema.brand();
|
|
16079
16079
|
AgentIdSchema = OpaqueIdSchema.brand();
|
|
16080
|
-
|
|
16081
|
-
|
|
16080
|
+
SessionIdSchema = OpaqueIdSchema.brand();
|
|
16081
|
+
SessionCommandIdSchema = OpaqueIdSchema.brand();
|
|
16082
16082
|
RuntimeIdSchema = OpaqueIdSchema.brand();
|
|
16083
16083
|
RuntimeBridgeLeaseIdSchema = OpaqueIdSchema.brand();
|
|
16084
16084
|
EnvironmentSetupSnapshotIdSchema = OpaqueIdSchema.brand();
|
|
@@ -16104,8 +16104,8 @@ var init_auth = __esm({
|
|
|
16104
16104
|
"environments:write",
|
|
16105
16105
|
"profiles:read",
|
|
16106
16106
|
"profiles:write",
|
|
16107
|
-
"
|
|
16108
|
-
"
|
|
16107
|
+
"sessions:read",
|
|
16108
|
+
"sessions:write",
|
|
16109
16109
|
"events:write",
|
|
16110
16110
|
"provider_grants:read",
|
|
16111
16111
|
"provider_grants:write",
|
|
@@ -16138,8 +16138,8 @@ var init_auth = __esm({
|
|
|
16138
16138
|
component: external_exports.string().trim().min(1)
|
|
16139
16139
|
}),
|
|
16140
16140
|
external_exports.object({
|
|
16141
|
-
kind: external_exports.literal("
|
|
16142
|
-
|
|
16141
|
+
kind: external_exports.literal("session"),
|
|
16142
|
+
sessionId: external_exports.string().trim().min(1)
|
|
16143
16143
|
})
|
|
16144
16144
|
]);
|
|
16145
16145
|
AuthClientSchema = external_exports.discriminatedUnion("kind", [
|
|
@@ -16160,7 +16160,7 @@ var init_auth = __esm({
|
|
|
16160
16160
|
kind: external_exports.literal("worker")
|
|
16161
16161
|
}),
|
|
16162
16162
|
external_exports.object({
|
|
16163
|
-
kind: external_exports.literal("
|
|
16163
|
+
kind: external_exports.literal("session_token")
|
|
16164
16164
|
})
|
|
16165
16165
|
]);
|
|
16166
16166
|
AuthActorSchema = external_exports.object({
|
|
@@ -16200,7 +16200,7 @@ var init_auth = __esm({
|
|
|
16200
16200
|
"environments:read",
|
|
16201
16201
|
"tools:read",
|
|
16202
16202
|
"agents:read",
|
|
16203
|
-
"
|
|
16203
|
+
"sessions:read",
|
|
16204
16204
|
"provider_grants:read"
|
|
16205
16205
|
];
|
|
16206
16206
|
SERVICE_ACCOUNT_SCOPE_PRESETS = {
|
|
@@ -16378,19 +16378,24 @@ var init_chat = __esm({
|
|
|
16378
16378
|
kind: external_exports.enum(["explicit_mention", "thread_participation"])
|
|
16379
16379
|
}).optional(),
|
|
16380
16380
|
attribution: external_exports.object({
|
|
16381
|
-
|
|
16381
|
+
sessionId: external_exports.string().trim().min(1),
|
|
16382
16382
|
agentName: external_exports.string().trim().min(1)
|
|
16383
16383
|
}).optional(),
|
|
16384
16384
|
attributions: external_exports.array(
|
|
16385
16385
|
external_exports.object({
|
|
16386
|
-
|
|
16386
|
+
sessionId: external_exports.string().trim().min(1),
|
|
16387
16387
|
agentName: external_exports.string().trim().min(1)
|
|
16388
16388
|
})
|
|
16389
16389
|
).optional(),
|
|
16390
16390
|
/** On addressed events: the agent identity this message mentioned. */
|
|
16391
16391
|
agent: external_exports.object({
|
|
16392
16392
|
agentName: external_exports.string().trim().min(1),
|
|
16393
|
-
botUserId: external_exports.string().trim().min(1)
|
|
16393
|
+
botUserId: external_exports.string().trim().min(1).optional(),
|
|
16394
|
+
addressing: external_exports.object({
|
|
16395
|
+
kind: external_exports.enum(["slack_auto_prefix", "slack_bot_user"]),
|
|
16396
|
+
alias: external_exports.string().trim().min(1).optional(),
|
|
16397
|
+
delimiter: external_exports.enum([".", ":", "/", "-"]).optional()
|
|
16398
|
+
}).optional()
|
|
16394
16399
|
}).optional(),
|
|
16395
16400
|
/**
|
|
16396
16401
|
* On broadcast events: agent identities the message mentioned. Each
|
|
@@ -16401,7 +16406,12 @@ var init_chat = __esm({
|
|
|
16401
16406
|
external_exports.object({
|
|
16402
16407
|
agentId: external_exports.string().trim().min(1),
|
|
16403
16408
|
agentName: external_exports.string().trim().min(1),
|
|
16404
|
-
botUserId: external_exports.string().trim().min(1)
|
|
16409
|
+
botUserId: external_exports.string().trim().min(1).optional(),
|
|
16410
|
+
addressing: external_exports.object({
|
|
16411
|
+
kind: external_exports.enum(["slack_auto_prefix", "slack_bot_user"]),
|
|
16412
|
+
alias: external_exports.string().trim().min(1).optional(),
|
|
16413
|
+
delimiter: external_exports.enum([".", ":", "/", "-"]).optional()
|
|
16414
|
+
}).optional()
|
|
16405
16415
|
})
|
|
16406
16416
|
).optional()
|
|
16407
16417
|
}).optional(),
|
|
@@ -16758,7 +16768,7 @@ var init_conversation = __esm({
|
|
|
16758
16768
|
ConversationEntryEventSchema = external_exports.object({
|
|
16759
16769
|
type: external_exports.literal("conversation.entry"),
|
|
16760
16770
|
id: external_exports.string().min(1),
|
|
16761
|
-
|
|
16771
|
+
sessionId: SessionIdSchema,
|
|
16762
16772
|
sequence: external_exports.number().int().nonnegative(),
|
|
16763
16773
|
messageId: external_exports.string().min(1).optional(),
|
|
16764
16774
|
role: ConversationRoleSchema,
|
|
@@ -16775,7 +16785,7 @@ var init_conversation = __esm({
|
|
|
16775
16785
|
ConversationDeltaEventSchema = external_exports.object({
|
|
16776
16786
|
type: external_exports.literal("conversation.delta"),
|
|
16777
16787
|
id: external_exports.string().min(1),
|
|
16778
|
-
|
|
16788
|
+
sessionId: SessionIdSchema,
|
|
16779
16789
|
sequence: external_exports.number().int().nonnegative(),
|
|
16780
16790
|
messageId: external_exports.string().min(1),
|
|
16781
16791
|
partId: external_exports.string().min(1),
|
|
@@ -17080,7 +17090,7 @@ function syntheticDeltaEntry(event) {
|
|
|
17080
17090
|
return {
|
|
17081
17091
|
type: "conversation.entry",
|
|
17082
17092
|
id: `delta:${event.messageId}`,
|
|
17083
|
-
|
|
17093
|
+
sessionId: event.sessionId,
|
|
17084
17094
|
sequence: event.sequence,
|
|
17085
17095
|
messageId: event.messageId,
|
|
17086
17096
|
role: event.role,
|
|
@@ -17804,8 +17814,11 @@ var init_trigger_router = __esm({
|
|
|
17804
17814
|
external_exports.object({
|
|
17805
17815
|
kind: external_exports.literal("allLiveRuns")
|
|
17806
17816
|
}),
|
|
17807
|
-
// Use
|
|
17817
|
+
// Use attributedSessions for follow-up delivery only. Spawn triggers that can
|
|
17808
17818
|
// overlap with attributed events should filter `$.auto.attributions` out.
|
|
17819
|
+
external_exports.object({
|
|
17820
|
+
kind: external_exports.literal("attributedSessions")
|
|
17821
|
+
}),
|
|
17809
17822
|
external_exports.object({
|
|
17810
17823
|
kind: external_exports.literal("attributedRuns")
|
|
17811
17824
|
})
|
|
@@ -17845,7 +17858,7 @@ var init_trigger_router = __esm({
|
|
|
17845
17858
|
}).strict(),
|
|
17846
17859
|
external_exports.object({
|
|
17847
17860
|
kind: external_exports.literal("command"),
|
|
17848
|
-
commandId:
|
|
17861
|
+
commandId: SessionCommandIdSchema
|
|
17849
17862
|
}).strict()
|
|
17850
17863
|
]);
|
|
17851
17864
|
HeartbeatTickWorkflowInputSchema = external_exports.object({
|
|
@@ -18071,7 +18084,7 @@ function validateAttributedRunsTriggerPairing(triggers, context) {
|
|
|
18071
18084
|
context.addIssue({
|
|
18072
18085
|
code: external_exports.ZodIssueCode.custom,
|
|
18073
18086
|
path: [index, "where", "$.auto.authored"],
|
|
18074
|
-
message: 'Chat message
|
|
18087
|
+
message: 'Chat message attributedSessions delivery triggers must filter out Auto-authored messages with "$.auto.authored": false.'
|
|
18075
18088
|
});
|
|
18076
18089
|
}
|
|
18077
18090
|
for (const [spawnIndex, spawnTrigger] of triggers.entries()) {
|
|
@@ -18091,7 +18104,7 @@ function validateAttributedRunsTriggerPairing(triggers, context) {
|
|
|
18091
18104
|
context.addIssue({
|
|
18092
18105
|
code: external_exports.ZodIssueCode.custom,
|
|
18093
18106
|
path: [deliverIndex, "routing"],
|
|
18094
|
-
message: 'Overlapping spawn and
|
|
18107
|
+
message: 'Overlapping spawn and attributedSessions delivery triggers on the same event must use mutually exclusive "$.auto.attributions" filters: spawn requires { exists: false }, attributedSessions delivery requires { exists: true }.'
|
|
18095
18108
|
});
|
|
18096
18109
|
}
|
|
18097
18110
|
}
|
|
@@ -18100,7 +18113,7 @@ function isSpawnTrigger(trigger) {
|
|
|
18100
18113
|
return trigger.routing.kind === "spawn";
|
|
18101
18114
|
}
|
|
18102
18115
|
function isAttributedRunsDeliverTrigger(trigger) {
|
|
18103
|
-
return trigger.routing.kind === "deliver" && trigger.routing.routeBy.kind === "attributedRuns";
|
|
18116
|
+
return trigger.routing.kind === "deliver" && (trigger.routing.routeBy.kind === "attributedSessions" || trigger.routing.routeBy.kind === "attributedRuns");
|
|
18104
18117
|
}
|
|
18105
18118
|
function hasAutoAttributionsExists(trigger, expected) {
|
|
18106
18119
|
const clause = trigger.where?.["$.auto.attributions"];
|
|
@@ -18400,7 +18413,7 @@ var init_agents = __esm({
|
|
|
18400
18413
|
});
|
|
18401
18414
|
AgentPresenceConnectRequestSchema = external_exports.object({
|
|
18402
18415
|
/**
|
|
18403
|
-
*
|
|
18416
|
+
* Rerun the install OAuth for already-realized identities too. The repair
|
|
18404
18417
|
* path for a stranded bot token (e.g. the single-use refresh token was
|
|
18405
18418
|
* consumed but the rotated pair failed to persist): the stored app
|
|
18406
18419
|
* credentials are reused, so this never creates a new Slack app.
|
|
@@ -18768,29 +18781,29 @@ var init_realtime = __esm({
|
|
|
18768
18781
|
}
|
|
18769
18782
|
});
|
|
18770
18783
|
|
|
18771
|
-
// ../../packages/schemas/src/
|
|
18772
|
-
var
|
|
18773
|
-
var
|
|
18774
|
-
"../../packages/schemas/src/
|
|
18784
|
+
// ../../packages/schemas/src/session-diagnostics.ts
|
|
18785
|
+
var SESSION_DIAGNOSTIC_REALTIME_EVENT, SESSION_DIAGNOSTIC_LEVELS, SESSION_DIAGNOSTIC_SOURCES, SESSION_DIAGNOSTIC_PHASES, SESSION_DIAGNOSTIC_STATUSES, SessionDiagnosticLevelSchema, SessionDiagnosticSourceSchema, SessionDiagnosticPhaseSchema, SessionDiagnosticStatusSchema, SessionDiagnosticEventSchema;
|
|
18786
|
+
var init_session_diagnostics = __esm({
|
|
18787
|
+
"../../packages/schemas/src/session-diagnostics.ts"() {
|
|
18775
18788
|
"use strict";
|
|
18776
18789
|
init_zod();
|
|
18777
18790
|
init_ids();
|
|
18778
18791
|
init_primitives();
|
|
18779
|
-
|
|
18780
|
-
|
|
18792
|
+
SESSION_DIAGNOSTIC_REALTIME_EVENT = "session.diagnostic";
|
|
18793
|
+
SESSION_DIAGNOSTIC_LEVELS = [
|
|
18781
18794
|
"debug",
|
|
18782
18795
|
"info",
|
|
18783
18796
|
"warn",
|
|
18784
18797
|
"error"
|
|
18785
18798
|
];
|
|
18786
|
-
|
|
18799
|
+
SESSION_DIAGNOSTIC_SOURCES = [
|
|
18787
18800
|
"web",
|
|
18788
18801
|
"worker",
|
|
18789
18802
|
"activity",
|
|
18790
18803
|
"bridge",
|
|
18791
18804
|
"runtime"
|
|
18792
18805
|
];
|
|
18793
|
-
|
|
18806
|
+
SESSION_DIAGNOSTIC_PHASES = [
|
|
18794
18807
|
"dispatch",
|
|
18795
18808
|
"environment",
|
|
18796
18809
|
"bridge",
|
|
@@ -18798,28 +18811,30 @@ var init_run_diagnostics = __esm({
|
|
|
18798
18811
|
"command",
|
|
18799
18812
|
"runtime"
|
|
18800
18813
|
];
|
|
18801
|
-
|
|
18814
|
+
SESSION_DIAGNOSTIC_STATUSES = [
|
|
18802
18815
|
"started",
|
|
18803
18816
|
"succeeded",
|
|
18804
18817
|
"retrying",
|
|
18805
18818
|
"failed",
|
|
18806
18819
|
"skipped"
|
|
18807
18820
|
];
|
|
18808
|
-
|
|
18809
|
-
|
|
18810
|
-
|
|
18811
|
-
|
|
18812
|
-
|
|
18813
|
-
|
|
18821
|
+
SessionDiagnosticLevelSchema = external_exports.enum(SESSION_DIAGNOSTIC_LEVELS);
|
|
18822
|
+
SessionDiagnosticSourceSchema = external_exports.enum(SESSION_DIAGNOSTIC_SOURCES);
|
|
18823
|
+
SessionDiagnosticPhaseSchema = external_exports.enum(SESSION_DIAGNOSTIC_PHASES);
|
|
18824
|
+
SessionDiagnosticStatusSchema = external_exports.enum(
|
|
18825
|
+
SESSION_DIAGNOSTIC_STATUSES
|
|
18826
|
+
);
|
|
18827
|
+
SessionDiagnosticEventSchema = external_exports.object({
|
|
18828
|
+
type: external_exports.literal(SESSION_DIAGNOSTIC_REALTIME_EVENT),
|
|
18814
18829
|
id: external_exports.string().min(1),
|
|
18815
|
-
|
|
18816
|
-
level:
|
|
18817
|
-
source:
|
|
18818
|
-
phase:
|
|
18830
|
+
sessionId: SessionIdSchema,
|
|
18831
|
+
level: SessionDiagnosticLevelSchema,
|
|
18832
|
+
source: SessionDiagnosticSourceSchema,
|
|
18833
|
+
phase: SessionDiagnosticPhaseSchema,
|
|
18819
18834
|
step: external_exports.string().trim().min(1),
|
|
18820
|
-
status:
|
|
18835
|
+
status: SessionDiagnosticStatusSchema,
|
|
18821
18836
|
message: external_exports.string().trim().min(1),
|
|
18822
|
-
commandId:
|
|
18837
|
+
commandId: SessionCommandIdSchema.optional(),
|
|
18823
18838
|
runtimeId: RuntimeIdSchema.optional(),
|
|
18824
18839
|
bridgeLeaseId: RuntimeBridgeLeaseIdSchema.optional(),
|
|
18825
18840
|
attempt: external_exports.number().int().nonnegative().optional(),
|
|
@@ -18830,15 +18845,15 @@ var init_run_diagnostics = __esm({
|
|
|
18830
18845
|
}
|
|
18831
18846
|
});
|
|
18832
18847
|
|
|
18833
|
-
// ../../packages/schemas/src/
|
|
18834
|
-
function
|
|
18835
|
-
return
|
|
18848
|
+
// ../../packages/schemas/src/sessions.ts
|
|
18849
|
+
function isSessionTerminalStatus(status) {
|
|
18850
|
+
return SESSION_TERMINAL_STATUSES.some(
|
|
18836
18851
|
(terminalStatus) => terminalStatus === status
|
|
18837
18852
|
);
|
|
18838
18853
|
}
|
|
18839
|
-
var
|
|
18840
|
-
var
|
|
18841
|
-
"../../packages/schemas/src/
|
|
18854
|
+
var SESSION_STATUSES, SESSION_TERMINAL_STATUSES, SESSION_DISPLAY_TITLE_MAX_LENGTH, SessionStatusSchema, RunDisplayTitleSchema, SESSION_CHECK_STATUSES, SESSION_CHECK_CONCLUSIONS, SESSION_CHECK_TIMEOUT_PHASES, SessionCheckStatusSchema, SessionCheckConclusionSchema, SessionCheckTimeoutPhaseSchema, ManualSessionRequestSchema, SessionArchiveRequestSchema, SessionsArchiveRequestSchema, SessionRecordSchema, SessionsArchiveResponseSchema;
|
|
18855
|
+
var init_sessions = __esm({
|
|
18856
|
+
"../../packages/schemas/src/sessions.ts"() {
|
|
18842
18857
|
"use strict";
|
|
18843
18858
|
init_zod();
|
|
18844
18859
|
init_agents();
|
|
@@ -18847,45 +18862,47 @@ var init_runs = __esm({
|
|
|
18847
18862
|
init_ids();
|
|
18848
18863
|
init_primitives();
|
|
18849
18864
|
init_tools();
|
|
18850
|
-
|
|
18865
|
+
SESSION_STATUSES = [
|
|
18851
18866
|
"queued",
|
|
18852
18867
|
"running",
|
|
18853
18868
|
"awaiting",
|
|
18854
18869
|
"failed",
|
|
18855
18870
|
"stopped"
|
|
18856
18871
|
];
|
|
18857
|
-
|
|
18858
|
-
|
|
18859
|
-
|
|
18860
|
-
RunDisplayTitleSchema = external_exports.string().trim().max(
|
|
18861
|
-
|
|
18872
|
+
SESSION_TERMINAL_STATUSES = ["failed", "stopped"];
|
|
18873
|
+
SESSION_DISPLAY_TITLE_MAX_LENGTH = 64;
|
|
18874
|
+
SessionStatusSchema = external_exports.enum(SESSION_STATUSES);
|
|
18875
|
+
RunDisplayTitleSchema = external_exports.string().trim().max(SESSION_DISPLAY_TITLE_MAX_LENGTH);
|
|
18876
|
+
SESSION_CHECK_STATUSES = [
|
|
18862
18877
|
"queued",
|
|
18863
18878
|
"in_progress",
|
|
18864
18879
|
"completed"
|
|
18865
18880
|
];
|
|
18866
|
-
|
|
18867
|
-
|
|
18868
|
-
|
|
18869
|
-
|
|
18870
|
-
|
|
18871
|
-
|
|
18881
|
+
SESSION_CHECK_CONCLUSIONS = ["success", "failure"];
|
|
18882
|
+
SESSION_CHECK_TIMEOUT_PHASES = ["begin", "complete"];
|
|
18883
|
+
SessionCheckStatusSchema = external_exports.enum(SESSION_CHECK_STATUSES);
|
|
18884
|
+
SessionCheckConclusionSchema = external_exports.enum(SESSION_CHECK_CONCLUSIONS);
|
|
18885
|
+
SessionCheckTimeoutPhaseSchema = external_exports.enum(
|
|
18886
|
+
SESSION_CHECK_TIMEOUT_PHASES
|
|
18887
|
+
);
|
|
18888
|
+
ManualSessionRequestSchema = external_exports.object({
|
|
18872
18889
|
message: external_exports.string().trim().min(1).max(2e4).optional(),
|
|
18873
18890
|
interactive: external_exports.boolean().optional()
|
|
18874
18891
|
});
|
|
18875
|
-
|
|
18892
|
+
SessionArchiveRequestSchema = external_exports.object({
|
|
18876
18893
|
archived: external_exports.boolean()
|
|
18877
18894
|
});
|
|
18878
|
-
|
|
18879
|
-
|
|
18895
|
+
SessionsArchiveRequestSchema = external_exports.object({
|
|
18896
|
+
session_ids: external_exports.array(SessionIdSchema).min(1).max(100),
|
|
18880
18897
|
archived: external_exports.boolean()
|
|
18881
18898
|
});
|
|
18882
|
-
|
|
18883
|
-
id:
|
|
18899
|
+
SessionRecordSchema = external_exports.object({
|
|
18900
|
+
id: SessionIdSchema,
|
|
18884
18901
|
organizationId: external_exports.string().trim().min(1),
|
|
18885
18902
|
projectId: external_exports.string().trim().min(1).nullable(),
|
|
18886
18903
|
agentId: AgentIdSchema,
|
|
18887
18904
|
runtimeId: RuntimeIdSchema.nullable(),
|
|
18888
|
-
status:
|
|
18905
|
+
status: SessionStatusSchema,
|
|
18889
18906
|
idempotencyKey: external_exports.string().min(1).nullable(),
|
|
18890
18907
|
correlationKey: external_exports.string().nullable(),
|
|
18891
18908
|
workflowId: external_exports.string().min(1),
|
|
@@ -18908,24 +18925,24 @@ var init_runs = __esm({
|
|
|
18908
18925
|
archivedAt: external_exports.string().datetime().nullable(),
|
|
18909
18926
|
error: JsonValueSchema.nullable()
|
|
18910
18927
|
});
|
|
18911
|
-
|
|
18928
|
+
SessionsArchiveResponseSchema = external_exports.object({
|
|
18912
18929
|
archived: external_exports.boolean(),
|
|
18913
|
-
|
|
18930
|
+
sessions: external_exports.array(SessionRecordSchema)
|
|
18914
18931
|
});
|
|
18915
18932
|
}
|
|
18916
18933
|
});
|
|
18917
18934
|
|
|
18918
|
-
// ../../packages/schemas/src/
|
|
18919
|
-
var TruncatedValueSchema, RunConversationSearchSnippetSchema, RunConversationSearchMatchSchema, RunConversationSearchResponseSchema,
|
|
18920
|
-
var
|
|
18921
|
-
"../../packages/schemas/src/
|
|
18935
|
+
// ../../packages/schemas/src/session-introspection.ts
|
|
18936
|
+
var TruncatedValueSchema, RunConversationSearchSnippetSchema, RunConversationSearchMatchSchema, RunConversationSearchResponseSchema, SessionToolExchangeSchema, SessionToolExchangesResponseSchema, SESSION_TRIGGER_DELIVERY_ACTIONS, SessionTriggerDeliveryActionSchema, SESSION_EVENT_ORIGIN_KINDS, SessionEventOriginKindSchema, SessionTriggerDeliveryRecordSchema, SessionTriggersResponseSchema, RunArtifactRecordSchema, RunArtifactsResponseSchema, RunTurnSchema, SessionToolStatSchema, RunSummarySchema;
|
|
18937
|
+
var init_session_introspection = __esm({
|
|
18938
|
+
"../../packages/schemas/src/session-introspection.ts"() {
|
|
18922
18939
|
"use strict";
|
|
18923
18940
|
init_zod();
|
|
18924
18941
|
init_auth();
|
|
18925
18942
|
init_conversation();
|
|
18926
18943
|
init_ids();
|
|
18927
18944
|
init_primitives();
|
|
18928
|
-
|
|
18945
|
+
init_sessions();
|
|
18929
18946
|
TruncatedValueSchema = external_exports.object({
|
|
18930
18947
|
truncated: external_exports.literal(true),
|
|
18931
18948
|
truncatedPreview: external_exports.string(),
|
|
@@ -18960,7 +18977,7 @@ var init_run_introspection = __esm({
|
|
|
18960
18977
|
*/
|
|
18961
18978
|
nextAfterSequence: external_exports.number().int().nullable()
|
|
18962
18979
|
});
|
|
18963
|
-
|
|
18980
|
+
SessionToolExchangeSchema = external_exports.object({
|
|
18964
18981
|
name: external_exports.string(),
|
|
18965
18982
|
callSequence: external_exports.number().int().nonnegative(),
|
|
18966
18983
|
resultSequence: external_exports.number().int().nonnegative().nullable(),
|
|
@@ -18973,8 +18990,8 @@ var init_run_introspection = __esm({
|
|
|
18973
18990
|
startedAt: external_exports.string().datetime(),
|
|
18974
18991
|
completedAt: external_exports.string().datetime().nullable()
|
|
18975
18992
|
});
|
|
18976
|
-
|
|
18977
|
-
exchanges: external_exports.array(
|
|
18993
|
+
SessionToolExchangesResponseSchema = external_exports.object({
|
|
18994
|
+
exchanges: external_exports.array(SessionToolExchangeSchema),
|
|
18978
18995
|
hasMore: external_exports.boolean(),
|
|
18979
18996
|
/**
|
|
18980
18997
|
* Sequence bounds of the entries window this page consumed (not just the
|
|
@@ -18984,27 +19001,27 @@ var init_run_introspection = __esm({
|
|
|
18984
19001
|
nextAfterSequence: external_exports.number().int().nullable(),
|
|
18985
19002
|
nextBeforeSequence: external_exports.number().int().nullable()
|
|
18986
19003
|
});
|
|
18987
|
-
|
|
19004
|
+
SESSION_TRIGGER_DELIVERY_ACTIONS = [
|
|
18988
19005
|
"started",
|
|
18989
19006
|
"signaled",
|
|
18990
19007
|
"dropped",
|
|
18991
19008
|
"warned",
|
|
18992
19009
|
"errored"
|
|
18993
19010
|
];
|
|
18994
|
-
|
|
18995
|
-
|
|
19011
|
+
SessionTriggerDeliveryActionSchema = external_exports.enum(
|
|
19012
|
+
SESSION_TRIGGER_DELIVERY_ACTIONS
|
|
18996
19013
|
);
|
|
18997
|
-
|
|
19014
|
+
SESSION_EVENT_ORIGIN_KINDS = [
|
|
18998
19015
|
"internal",
|
|
18999
19016
|
"provider_grant",
|
|
19000
19017
|
"webhook"
|
|
19001
19018
|
];
|
|
19002
|
-
|
|
19003
|
-
|
|
19004
|
-
action:
|
|
19019
|
+
SessionEventOriginKindSchema = external_exports.enum(SESSION_EVENT_ORIGIN_KINDS);
|
|
19020
|
+
SessionTriggerDeliveryRecordSchema = external_exports.object({
|
|
19021
|
+
action: SessionTriggerDeliveryActionSchema,
|
|
19005
19022
|
triggerId: external_exports.string(),
|
|
19006
19023
|
eventKey: external_exports.string(),
|
|
19007
|
-
originKind:
|
|
19024
|
+
originKind: SessionEventOriginKindSchema,
|
|
19008
19025
|
occurredAt: external_exports.string().datetime(),
|
|
19009
19026
|
receivedAt: external_exports.string().datetime(),
|
|
19010
19027
|
deliveredAt: external_exports.string().datetime(),
|
|
@@ -19012,13 +19029,13 @@ var init_run_introspection = __esm({
|
|
|
19012
19029
|
/** Event payload; may be a {@link TruncatedValueSchema} marker. */
|
|
19013
19030
|
payload: JsonValueSchema.optional()
|
|
19014
19031
|
});
|
|
19015
|
-
|
|
19016
|
-
/** The `started` delivery that spawned the
|
|
19017
|
-
spawn:
|
|
19018
|
-
/** Who started the
|
|
19032
|
+
SessionTriggersResponseSchema = external_exports.object({
|
|
19033
|
+
/** The `started` delivery that spawned the session; null for manual/agent spawns. */
|
|
19034
|
+
spawn: SessionTriggerDeliveryRecordSchema.nullable(),
|
|
19035
|
+
/** Who started the session, for manual/CLI/agent spawns. */
|
|
19019
19036
|
starter: AuthActorSchema.nullable(),
|
|
19020
|
-
/** Subsequent deliveries against the
|
|
19021
|
-
deliveries: external_exports.array(
|
|
19037
|
+
/** Subsequent deliveries against the session, chronological. */
|
|
19038
|
+
deliveries: external_exports.array(SessionTriggerDeliveryRecordSchema)
|
|
19022
19039
|
});
|
|
19023
19040
|
RunArtifactRecordSchema = external_exports.object({
|
|
19024
19041
|
artifactType: external_exports.string(),
|
|
@@ -19036,14 +19053,14 @@ var init_run_introspection = __esm({
|
|
|
19036
19053
|
completedAt: external_exports.string().datetime().nullable(),
|
|
19037
19054
|
toolCallCount: external_exports.number().int().nonnegative()
|
|
19038
19055
|
});
|
|
19039
|
-
|
|
19056
|
+
SessionToolStatSchema = external_exports.object({
|
|
19040
19057
|
name: external_exports.string(),
|
|
19041
|
-
/**
|
|
19058
|
+
/** Session-wide call count from the SQL aggregate. */
|
|
19042
19059
|
calls: external_exports.number().int().nonnegative(),
|
|
19043
19060
|
/**
|
|
19044
19061
|
* Derived from the summary's recent-entries window (most recent ~1000
|
|
19045
|
-
* entries), so on very long
|
|
19046
|
-
* relative to the
|
|
19062
|
+
* entries), so on very long sessions `errors` and `durationMs` can understate
|
|
19063
|
+
* relative to the session-wide `calls`.
|
|
19047
19064
|
*/
|
|
19048
19065
|
errors: external_exports.number().int().nonnegative(),
|
|
19049
19066
|
durationMs: external_exports.object({
|
|
@@ -19052,11 +19069,11 @@ var init_run_introspection = __esm({
|
|
|
19052
19069
|
})
|
|
19053
19070
|
});
|
|
19054
19071
|
RunSummarySchema = external_exports.object({
|
|
19055
|
-
|
|
19056
|
-
id:
|
|
19072
|
+
session: external_exports.object({
|
|
19073
|
+
id: SessionIdSchema,
|
|
19057
19074
|
agentName: external_exports.string(),
|
|
19058
19075
|
displayTitle: external_exports.string(),
|
|
19059
|
-
status:
|
|
19076
|
+
status: SessionStatusSchema,
|
|
19060
19077
|
error: JsonValueSchema.nullable(),
|
|
19061
19078
|
workflowId: external_exports.string(),
|
|
19062
19079
|
createdAt: external_exports.string().datetime(),
|
|
@@ -19065,9 +19082,9 @@ var init_run_introspection = __esm({
|
|
|
19065
19082
|
archivedAt: external_exports.string().datetime().nullable()
|
|
19066
19083
|
}),
|
|
19067
19084
|
timing: external_exports.object({
|
|
19068
|
-
/** `startedAt - createdAt`; null until the
|
|
19085
|
+
/** `startedAt - createdAt`; null until the session starts. */
|
|
19069
19086
|
queuedMs: external_exports.number().int().nonnegative().nullable(),
|
|
19070
|
-
/** `(finishedAt ?? now) - startedAt`; null until the
|
|
19087
|
+
/** `(finishedAt ?? now) - startedAt`; null until the session starts. */
|
|
19071
19088
|
activeMs: external_exports.number().int().nonnegative().nullable(),
|
|
19072
19089
|
/** `(finishedAt ?? now) - createdAt`. */
|
|
19073
19090
|
totalMs: external_exports.number().int().nonnegative()
|
|
@@ -19086,15 +19103,15 @@ var init_run_introspection = __esm({
|
|
|
19086
19103
|
failedEntryCount: external_exports.number().int().nonnegative(),
|
|
19087
19104
|
lastSequence: external_exports.number().int().nonnegative()
|
|
19088
19105
|
}),
|
|
19089
|
-
tools: external_exports.array(
|
|
19106
|
+
tools: external_exports.array(SessionToolStatSchema),
|
|
19090
19107
|
/**
|
|
19091
|
-
* True when the
|
|
19108
|
+
* True when the session has more conversation entries than the summary's
|
|
19092
19109
|
* recent-entries window, meaning per-tool `errors`/`durationMs` (and
|
|
19093
|
-
* `turns`) describe only the most recent slice of the
|
|
19110
|
+
* `turns`) describe only the most recent slice of the session.
|
|
19094
19111
|
*/
|
|
19095
19112
|
toolStatsWindowed: external_exports.boolean(),
|
|
19096
19113
|
trigger: external_exports.object({
|
|
19097
|
-
/** Spawning event key, or "manual" / "agent" for actor-started
|
|
19114
|
+
/** Spawning event key, or "manual" / "agent" for actor-started sessions. */
|
|
19098
19115
|
spawn: external_exports.string(),
|
|
19099
19116
|
signaledCount: external_exports.number().int().nonnegative(),
|
|
19100
19117
|
droppedCount: external_exports.number().int().nonnegative()
|
|
@@ -19114,8 +19131,8 @@ var init_run_introspection = __esm({
|
|
|
19114
19131
|
external_exports.object({
|
|
19115
19132
|
name: external_exports.string(),
|
|
19116
19133
|
displayName: external_exports.string(),
|
|
19117
|
-
status:
|
|
19118
|
-
conclusion:
|
|
19134
|
+
status: SessionCheckStatusSchema,
|
|
19135
|
+
conclusion: SessionCheckConclusionSchema.nullable(),
|
|
19119
19136
|
completedAt: external_exports.string().datetime().nullable()
|
|
19120
19137
|
})
|
|
19121
19138
|
)
|
|
@@ -19123,16 +19140,16 @@ var init_run_introspection = __esm({
|
|
|
19123
19140
|
}
|
|
19124
19141
|
});
|
|
19125
19142
|
|
|
19126
|
-
// ../../packages/schemas/src/
|
|
19127
|
-
var
|
|
19128
|
-
var
|
|
19129
|
-
"../../packages/schemas/src/
|
|
19143
|
+
// ../../packages/schemas/src/session-commands.ts
|
|
19144
|
+
var SESSION_COMMAND_KINDS, SESSION_DISPATCH_COMMAND_KINDS, SESSION_PERSISTED_COMMAND_KINDS, SESSION_LIFECYCLE_COMMAND_KINDS, SESSION_COMMAND_STATUSES, SESSION_DISPATCH_COMMAND_STATUSES, SessionCommandKindSchema, SessionPersistedCommandKindSchema, SessionDispatchCommandKindSchema, RunLifecycleCommandKindSchema, SessionCommandStatusSchema, SessionDispatchCommandStatusSchema, SessionCommandSenderSchema, RunMessageCommandPayloadSchema, RunAnswerCommandPayloadSchema, RunLifecycleCommandPayloadSchema, SessionCommandPayloadSchema, CreateRunMessageCommandRequestSchema, CreateRunAnswerCommandRequestSchema, CreateRunLifecycleCommandRequestSchema, CreateSessionCommandRequestSchema, RunResolutionPolicySchema, AgentAddressedCommandTargetSchema, SessionCommandRecordBaseSchema, RunStartCommandPayloadSchema, RunStartWithMessageCommandPayloadSchema, SessionPersistedCommandPayloadSchema, SessionCommandRecordSchema, SessionDispatchMessageCommandPayloadSchema, SessionDispatchAnswerCommandPayloadSchema, SessionDispatchStopCommandPayloadSchema, SessionDispatchCommandPayloadSchema, SessionDispatchCommandRecordBaseSchema, SessionDispatchCommandRecordSchema;
|
|
19145
|
+
var init_session_commands = __esm({
|
|
19146
|
+
"../../packages/schemas/src/session-commands.ts"() {
|
|
19130
19147
|
"use strict";
|
|
19131
19148
|
init_zod();
|
|
19132
19149
|
init_auth();
|
|
19133
19150
|
init_ids();
|
|
19134
19151
|
init_primitives();
|
|
19135
|
-
|
|
19152
|
+
SESSION_COMMAND_KINDS = [
|
|
19136
19153
|
"message",
|
|
19137
19154
|
"answer",
|
|
19138
19155
|
"pause",
|
|
@@ -19141,14 +19158,14 @@ var init_run_commands = __esm({
|
|
|
19141
19158
|
"cancel",
|
|
19142
19159
|
"stop"
|
|
19143
19160
|
];
|
|
19144
|
-
|
|
19161
|
+
SESSION_DISPATCH_COMMAND_KINDS = [
|
|
19145
19162
|
"start",
|
|
19146
19163
|
"startWithMessage",
|
|
19147
19164
|
"message",
|
|
19148
19165
|
"answer",
|
|
19149
19166
|
"stop"
|
|
19150
19167
|
];
|
|
19151
|
-
|
|
19168
|
+
SESSION_PERSISTED_COMMAND_KINDS = [
|
|
19152
19169
|
"message",
|
|
19153
19170
|
"pause",
|
|
19154
19171
|
"resume",
|
|
@@ -19159,38 +19176,40 @@ var init_run_commands = __esm({
|
|
|
19159
19176
|
"startWithMessage",
|
|
19160
19177
|
"answer"
|
|
19161
19178
|
];
|
|
19162
|
-
|
|
19179
|
+
SESSION_LIFECYCLE_COMMAND_KINDS = [
|
|
19163
19180
|
"pause",
|
|
19164
19181
|
"resume",
|
|
19165
19182
|
"interrupt",
|
|
19166
19183
|
"cancel",
|
|
19167
19184
|
"stop"
|
|
19168
19185
|
];
|
|
19169
|
-
|
|
19186
|
+
SESSION_COMMAND_STATUSES = [
|
|
19170
19187
|
"pending",
|
|
19171
19188
|
"dispatching",
|
|
19172
19189
|
"accepted",
|
|
19173
19190
|
"failed"
|
|
19174
19191
|
];
|
|
19175
|
-
|
|
19192
|
+
SESSION_DISPATCH_COMMAND_STATUSES = [
|
|
19176
19193
|
"pending",
|
|
19177
19194
|
"dispatching",
|
|
19178
19195
|
"accepted",
|
|
19179
19196
|
"failed"
|
|
19180
19197
|
];
|
|
19181
|
-
|
|
19182
|
-
|
|
19183
|
-
|
|
19198
|
+
SessionCommandKindSchema = external_exports.enum(SESSION_COMMAND_KINDS);
|
|
19199
|
+
SessionPersistedCommandKindSchema = external_exports.enum(
|
|
19200
|
+
SESSION_PERSISTED_COMMAND_KINDS
|
|
19201
|
+
);
|
|
19202
|
+
SessionDispatchCommandKindSchema = external_exports.enum(
|
|
19203
|
+
SESSION_DISPATCH_COMMAND_KINDS
|
|
19184
19204
|
);
|
|
19185
|
-
RunDispatchCommandKindSchema = external_exports.enum(RUN_DISPATCH_COMMAND_KINDS);
|
|
19186
19205
|
RunLifecycleCommandKindSchema = external_exports.enum(
|
|
19187
|
-
|
|
19206
|
+
SESSION_LIFECYCLE_COMMAND_KINDS
|
|
19188
19207
|
);
|
|
19189
|
-
|
|
19190
|
-
|
|
19191
|
-
|
|
19208
|
+
SessionCommandStatusSchema = external_exports.enum(SESSION_COMMAND_STATUSES);
|
|
19209
|
+
SessionDispatchCommandStatusSchema = external_exports.enum(
|
|
19210
|
+
SESSION_DISPATCH_COMMAND_STATUSES
|
|
19192
19211
|
);
|
|
19193
|
-
|
|
19212
|
+
SessionCommandSenderSchema = external_exports.discriminatedUnion("type", [
|
|
19194
19213
|
external_exports.object({
|
|
19195
19214
|
type: external_exports.literal("operator"),
|
|
19196
19215
|
id: external_exports.string().trim().min(1).nullable().default(null),
|
|
@@ -19198,7 +19217,7 @@ var init_run_commands = __esm({
|
|
|
19198
19217
|
}),
|
|
19199
19218
|
external_exports.object({
|
|
19200
19219
|
type: external_exports.literal("agent"),
|
|
19201
|
-
|
|
19220
|
+
sessionId: SessionIdSchema
|
|
19202
19221
|
}),
|
|
19203
19222
|
external_exports.object({
|
|
19204
19223
|
type: external_exports.literal("system")
|
|
@@ -19218,7 +19237,7 @@ var init_run_commands = __esm({
|
|
|
19218
19237
|
RunLifecycleCommandPayloadSchema = external_exports.object({
|
|
19219
19238
|
reason: external_exports.string().trim().min(1).optional()
|
|
19220
19239
|
}).strict();
|
|
19221
|
-
|
|
19240
|
+
SessionCommandPayloadSchema = external_exports.union([
|
|
19222
19241
|
RunMessageCommandPayloadSchema,
|
|
19223
19242
|
RunAnswerCommandPayloadSchema,
|
|
19224
19243
|
RunLifecycleCommandPayloadSchema
|
|
@@ -19231,7 +19250,7 @@ var init_run_commands = __esm({
|
|
|
19231
19250
|
CreateRunLifecycleCommandRequestSchema = external_exports.object({
|
|
19232
19251
|
reason: external_exports.string().trim().min(1).optional()
|
|
19233
19252
|
});
|
|
19234
|
-
|
|
19253
|
+
CreateSessionCommandRequestSchema = external_exports.discriminatedUnion("kind", [
|
|
19235
19254
|
external_exports.object({
|
|
19236
19255
|
kind: external_exports.literal("message"),
|
|
19237
19256
|
payload: CreateRunMessageCommandRequestSchema
|
|
@@ -19273,12 +19292,12 @@ var init_run_commands = __esm({
|
|
|
19273
19292
|
}).refine((value) => Boolean(value.agentId) !== Boolean(value.agentName), {
|
|
19274
19293
|
message: "Provide exactly one of agentId or agentName"
|
|
19275
19294
|
});
|
|
19276
|
-
|
|
19277
|
-
id:
|
|
19278
|
-
|
|
19279
|
-
sender:
|
|
19295
|
+
SessionCommandRecordBaseSchema = external_exports.object({
|
|
19296
|
+
id: SessionCommandIdSchema,
|
|
19297
|
+
sessionId: SessionIdSchema,
|
|
19298
|
+
sender: SessionCommandSenderSchema,
|
|
19280
19299
|
idempotencyKey: external_exports.string().min(1).nullable(),
|
|
19281
|
-
status:
|
|
19300
|
+
status: SessionCommandStatusSchema,
|
|
19282
19301
|
attemptCount: external_exports.number().int().nonnegative(),
|
|
19283
19302
|
nextAttemptAt: external_exports.string().datetime().nullable(),
|
|
19284
19303
|
lastAttemptAt: external_exports.string().datetime().nullable(),
|
|
@@ -19295,78 +19314,81 @@ var init_run_commands = __esm({
|
|
|
19295
19314
|
kind: external_exports.literal("startWithMessage"),
|
|
19296
19315
|
message: external_exports.string().trim().min(1)
|
|
19297
19316
|
}).strict();
|
|
19298
|
-
|
|
19317
|
+
SessionPersistedCommandPayloadSchema = external_exports.union([
|
|
19299
19318
|
RunMessageCommandPayloadSchema,
|
|
19300
19319
|
RunAnswerCommandPayloadSchema,
|
|
19301
19320
|
RunLifecycleCommandPayloadSchema,
|
|
19302
19321
|
RunStartCommandPayloadSchema,
|
|
19303
19322
|
RunStartWithMessageCommandPayloadSchema
|
|
19304
19323
|
]);
|
|
19305
|
-
|
|
19306
|
-
|
|
19324
|
+
SessionCommandRecordSchema = external_exports.discriminatedUnion("kind", [
|
|
19325
|
+
SessionCommandRecordBaseSchema.extend({
|
|
19307
19326
|
kind: external_exports.literal("message"),
|
|
19308
19327
|
payload: RunMessageCommandPayloadSchema
|
|
19309
19328
|
}),
|
|
19310
|
-
|
|
19329
|
+
SessionCommandRecordBaseSchema.extend({
|
|
19311
19330
|
kind: external_exports.literal("answer"),
|
|
19312
19331
|
payload: RunAnswerCommandPayloadSchema
|
|
19313
19332
|
}),
|
|
19314
|
-
|
|
19333
|
+
SessionCommandRecordBaseSchema.extend({
|
|
19315
19334
|
kind: external_exports.literal("pause"),
|
|
19316
19335
|
payload: RunLifecycleCommandPayloadSchema
|
|
19317
19336
|
}),
|
|
19318
|
-
|
|
19337
|
+
SessionCommandRecordBaseSchema.extend({
|
|
19319
19338
|
kind: external_exports.literal("resume"),
|
|
19320
19339
|
payload: RunLifecycleCommandPayloadSchema
|
|
19321
19340
|
}),
|
|
19322
|
-
|
|
19341
|
+
SessionCommandRecordBaseSchema.extend({
|
|
19323
19342
|
kind: external_exports.literal("interrupt"),
|
|
19324
19343
|
payload: RunLifecycleCommandPayloadSchema
|
|
19325
19344
|
}),
|
|
19326
|
-
|
|
19345
|
+
SessionCommandRecordBaseSchema.extend({
|
|
19327
19346
|
kind: external_exports.literal("cancel"),
|
|
19328
19347
|
payload: RunLifecycleCommandPayloadSchema
|
|
19329
19348
|
}),
|
|
19330
|
-
|
|
19349
|
+
SessionCommandRecordBaseSchema.extend({
|
|
19331
19350
|
kind: external_exports.literal("stop"),
|
|
19332
19351
|
payload: RunLifecycleCommandPayloadSchema
|
|
19333
19352
|
}),
|
|
19334
|
-
|
|
19353
|
+
SessionCommandRecordBaseSchema.extend({
|
|
19335
19354
|
kind: external_exports.literal("start"),
|
|
19336
19355
|
payload: RunStartCommandPayloadSchema
|
|
19337
19356
|
}),
|
|
19338
|
-
|
|
19357
|
+
SessionCommandRecordBaseSchema.extend({
|
|
19339
19358
|
kind: external_exports.literal("startWithMessage"),
|
|
19340
19359
|
payload: RunStartWithMessageCommandPayloadSchema
|
|
19341
19360
|
})
|
|
19342
19361
|
]);
|
|
19343
|
-
|
|
19362
|
+
SessionDispatchMessageCommandPayloadSchema = external_exports.object({
|
|
19344
19363
|
kind: external_exports.literal("message"),
|
|
19345
19364
|
message: external_exports.string().trim().min(1)
|
|
19346
19365
|
}).strict();
|
|
19347
|
-
|
|
19366
|
+
SessionDispatchAnswerCommandPayloadSchema = external_exports.object({
|
|
19348
19367
|
kind: external_exports.literal("answer"),
|
|
19349
19368
|
toolCallId: external_exports.string().trim().min(1),
|
|
19350
19369
|
answers: external_exports.record(external_exports.string(), external_exports.string()),
|
|
19351
19370
|
response: external_exports.string().trim().min(1).optional()
|
|
19352
19371
|
}).strict();
|
|
19353
|
-
|
|
19372
|
+
SessionDispatchStopCommandPayloadSchema = external_exports.object({
|
|
19354
19373
|
kind: external_exports.literal("stop"),
|
|
19355
19374
|
reason: external_exports.string().trim().min(1).optional()
|
|
19356
19375
|
}).strict();
|
|
19357
|
-
|
|
19358
|
-
|
|
19359
|
-
|
|
19360
|
-
|
|
19361
|
-
|
|
19362
|
-
|
|
19363
|
-
|
|
19364
|
-
|
|
19365
|
-
|
|
19366
|
-
|
|
19367
|
-
|
|
19376
|
+
SessionDispatchCommandPayloadSchema = external_exports.discriminatedUnion(
|
|
19377
|
+
"kind",
|
|
19378
|
+
[
|
|
19379
|
+
RunStartCommandPayloadSchema,
|
|
19380
|
+
RunStartWithMessageCommandPayloadSchema,
|
|
19381
|
+
SessionDispatchMessageCommandPayloadSchema,
|
|
19382
|
+
SessionDispatchAnswerCommandPayloadSchema,
|
|
19383
|
+
SessionDispatchStopCommandPayloadSchema
|
|
19384
|
+
]
|
|
19385
|
+
);
|
|
19386
|
+
SessionDispatchCommandRecordBaseSchema = external_exports.object({
|
|
19387
|
+
id: SessionCommandIdSchema,
|
|
19388
|
+
sessionId: SessionIdSchema,
|
|
19389
|
+
sender: SessionCommandSenderSchema,
|
|
19368
19390
|
idempotencyKey: external_exports.string().min(1).nullable(),
|
|
19369
|
-
status:
|
|
19391
|
+
status: SessionDispatchCommandStatusSchema,
|
|
19370
19392
|
attemptCount: external_exports.number().int().nonnegative(),
|
|
19371
19393
|
nextAttemptAt: external_exports.string().datetime().nullable(),
|
|
19372
19394
|
lastAttemptAt: external_exports.string().datetime().nullable(),
|
|
@@ -19376,33 +19398,33 @@ var init_run_commands = __esm({
|
|
|
19376
19398
|
createdAt: external_exports.string().datetime(),
|
|
19377
19399
|
updatedAt: external_exports.string().datetime()
|
|
19378
19400
|
});
|
|
19379
|
-
|
|
19380
|
-
|
|
19401
|
+
SessionDispatchCommandRecordSchema = external_exports.discriminatedUnion("kind", [
|
|
19402
|
+
SessionDispatchCommandRecordBaseSchema.extend({
|
|
19381
19403
|
kind: external_exports.literal("start"),
|
|
19382
19404
|
payload: RunStartCommandPayloadSchema
|
|
19383
19405
|
}),
|
|
19384
|
-
|
|
19406
|
+
SessionDispatchCommandRecordBaseSchema.extend({
|
|
19385
19407
|
kind: external_exports.literal("startWithMessage"),
|
|
19386
19408
|
payload: RunStartWithMessageCommandPayloadSchema
|
|
19387
19409
|
}),
|
|
19388
|
-
|
|
19410
|
+
SessionDispatchCommandRecordBaseSchema.extend({
|
|
19389
19411
|
kind: external_exports.literal("message"),
|
|
19390
|
-
payload:
|
|
19412
|
+
payload: SessionDispatchMessageCommandPayloadSchema
|
|
19391
19413
|
}),
|
|
19392
|
-
|
|
19414
|
+
SessionDispatchCommandRecordBaseSchema.extend({
|
|
19393
19415
|
kind: external_exports.literal("answer"),
|
|
19394
|
-
payload:
|
|
19416
|
+
payload: SessionDispatchAnswerCommandPayloadSchema
|
|
19395
19417
|
}),
|
|
19396
|
-
|
|
19418
|
+
SessionDispatchCommandRecordBaseSchema.extend({
|
|
19397
19419
|
kind: external_exports.literal("stop"),
|
|
19398
|
-
payload:
|
|
19420
|
+
payload: SessionDispatchStopCommandPayloadSchema
|
|
19399
19421
|
})
|
|
19400
19422
|
]);
|
|
19401
19423
|
}
|
|
19402
19424
|
});
|
|
19403
19425
|
|
|
19404
19426
|
// ../../packages/schemas/src/runtimes.ts
|
|
19405
|
-
var RuntimeRecordSchema,
|
|
19427
|
+
var RuntimeRecordSchema, SessionCommandDispatchWorkflowInputSchema, SessionCommandDispatchSignalPayloadSchema, RealtimeRunCursorSchema;
|
|
19406
19428
|
var init_runtimes = __esm({
|
|
19407
19429
|
"../../packages/schemas/src/runtimes.ts"() {
|
|
19408
19430
|
"use strict";
|
|
@@ -19414,12 +19436,12 @@ var init_runtimes = __esm({
|
|
|
19414
19436
|
createdAt: external_exports.string().datetime(),
|
|
19415
19437
|
updatedAt: external_exports.string().datetime()
|
|
19416
19438
|
});
|
|
19417
|
-
|
|
19418
|
-
|
|
19419
|
-
commandId:
|
|
19439
|
+
SessionCommandDispatchWorkflowInputSchema = external_exports.object({
|
|
19440
|
+
sessionId: SessionIdSchema,
|
|
19441
|
+
commandId: SessionCommandIdSchema
|
|
19420
19442
|
}).strict();
|
|
19421
|
-
|
|
19422
|
-
commandId:
|
|
19443
|
+
SessionCommandDispatchSignalPayloadSchema = external_exports.object({
|
|
19444
|
+
commandId: SessionCommandIdSchema
|
|
19423
19445
|
}).strict();
|
|
19424
19446
|
RealtimeRunCursorSchema = external_exports.string().regex(/^rt:(0|[1-9]\d*)$/);
|
|
19425
19447
|
}
|
|
@@ -19462,12 +19484,12 @@ var init_src = __esm({
|
|
|
19462
19484
|
init_primitives();
|
|
19463
19485
|
init_realtime();
|
|
19464
19486
|
init_resources();
|
|
19465
|
-
|
|
19466
|
-
|
|
19487
|
+
init_session_diagnostics();
|
|
19488
|
+
init_session_introspection();
|
|
19467
19489
|
init_secrets();
|
|
19468
|
-
|
|
19490
|
+
init_session_commands();
|
|
19469
19491
|
init_runtimes();
|
|
19470
|
-
|
|
19492
|
+
init_sessions();
|
|
19471
19493
|
init_agents();
|
|
19472
19494
|
init_temporal();
|
|
19473
19495
|
init_tools();
|
|
@@ -19479,7 +19501,7 @@ var init_src = __esm({
|
|
|
19479
19501
|
function requireActiveProject(config2) {
|
|
19480
19502
|
if (!config2.organizationId || !config2.projectId) {
|
|
19481
19503
|
throw new Error(
|
|
19482
|
-
"
|
|
19504
|
+
"Session `auto orgs use <organization>` and `auto projects use <project>` first."
|
|
19483
19505
|
);
|
|
19484
19506
|
}
|
|
19485
19507
|
return {
|
|
@@ -19632,8 +19654,10 @@ function agentApiPath(project, agentName, path2 = "") {
|
|
|
19632
19654
|
`/agents/${encodeURIComponent(agentName)}${cleanSubpath(path2)}`
|
|
19633
19655
|
);
|
|
19634
19656
|
}
|
|
19635
|
-
function runApiPath(
|
|
19636
|
-
return apiPath(
|
|
19657
|
+
function runApiPath(sessionId, path2 = "") {
|
|
19658
|
+
return apiPath(
|
|
19659
|
+
`/sessions/${encodeURIComponent(sessionId)}${cleanSubpath(path2)}`
|
|
19660
|
+
);
|
|
19637
19661
|
}
|
|
19638
19662
|
function cleanSubpath(path2) {
|
|
19639
19663
|
const trimmed = path2.trim();
|
|
@@ -20100,7 +20124,7 @@ function createApiClient(input) {
|
|
|
20100
20124
|
const { organizationId } = await resolveActiveSelection();
|
|
20101
20125
|
if (!organizationId) {
|
|
20102
20126
|
throw new Error(
|
|
20103
|
-
"No active organization.
|
|
20127
|
+
"No active organization. Session `auto auth login` to sign in, then `auto orgs use <organization>` to select one."
|
|
20104
20128
|
);
|
|
20105
20129
|
}
|
|
20106
20130
|
return { organizationId };
|
|
@@ -20897,10 +20921,13 @@ function createApiClient(input) {
|
|
|
20897
20921
|
}
|
|
20898
20922
|
return await response.json();
|
|
20899
20923
|
},
|
|
20900
|
-
async
|
|
20924
|
+
async triggerSession(agentName, options) {
|
|
20901
20925
|
const project = await activeProject();
|
|
20902
20926
|
const response = await authenticatedFetch(
|
|
20903
|
-
apiUrl(
|
|
20927
|
+
apiUrl(
|
|
20928
|
+
agentApiPath(project, agentName, "/sessions"),
|
|
20929
|
+
options.apiBaseUrl
|
|
20930
|
+
),
|
|
20904
20931
|
{
|
|
20905
20932
|
method: "POST",
|
|
20906
20933
|
headers: {
|
|
@@ -20918,9 +20945,12 @@ function createApiClient(input) {
|
|
|
20918
20945
|
}
|
|
20919
20946
|
return await response.json();
|
|
20920
20947
|
},
|
|
20921
|
-
async
|
|
20948
|
+
async streamSessionConversation(sessionId, options) {
|
|
20922
20949
|
const url2 = new URL(
|
|
20923
|
-
apiUrl(
|
|
20950
|
+
apiUrl(
|
|
20951
|
+
runApiPath(sessionId, "/conversation/stream"),
|
|
20952
|
+
options.apiBaseUrl
|
|
20953
|
+
)
|
|
20924
20954
|
);
|
|
20925
20955
|
if (options.cursor) {
|
|
20926
20956
|
url2.searchParams.set("cursor", options.cursor);
|
|
@@ -20940,11 +20970,11 @@ function createApiClient(input) {
|
|
|
20940
20970
|
}
|
|
20941
20971
|
if (!response.body) {
|
|
20942
20972
|
throw new Error(
|
|
20943
|
-
"
|
|
20973
|
+
"Session conversation stream response did not include a body"
|
|
20944
20974
|
);
|
|
20945
20975
|
}
|
|
20946
20976
|
for await (const event of readSseEvents(response.body)) {
|
|
20947
|
-
if (event.event !== "
|
|
20977
|
+
if (event.event !== "session.conversation") {
|
|
20948
20978
|
continue;
|
|
20949
20979
|
}
|
|
20950
20980
|
const parsedJson = JSON.parse(event.data);
|
|
@@ -20961,9 +20991,12 @@ function createApiClient(input) {
|
|
|
20961
20991
|
}
|
|
20962
20992
|
}
|
|
20963
20993
|
},
|
|
20964
|
-
async
|
|
20994
|
+
async streamSessionDiagnostics(sessionId, options) {
|
|
20965
20995
|
const response = await authenticatedFetch(
|
|
20966
|
-
apiUrl(
|
|
20996
|
+
apiUrl(
|
|
20997
|
+
runApiPath(sessionId, "/diagnostics/stream"),
|
|
20998
|
+
options.apiBaseUrl
|
|
20999
|
+
),
|
|
20967
21000
|
{
|
|
20968
21001
|
signal: options.signal,
|
|
20969
21002
|
headers: {
|
|
@@ -20977,15 +21010,15 @@ function createApiClient(input) {
|
|
|
20977
21010
|
}
|
|
20978
21011
|
if (!response.body) {
|
|
20979
21012
|
throw new Error(
|
|
20980
|
-
"
|
|
21013
|
+
"Session diagnostics stream response did not include a body"
|
|
20981
21014
|
);
|
|
20982
21015
|
}
|
|
20983
21016
|
for await (const event of readSseEvents(response.body)) {
|
|
20984
|
-
if (event.event !==
|
|
21017
|
+
if (event.event !== SESSION_DIAGNOSTIC_REALTIME_EVENT) {
|
|
20985
21018
|
continue;
|
|
20986
21019
|
}
|
|
20987
21020
|
const parsedJson = JSON.parse(event.data);
|
|
20988
|
-
const parsed =
|
|
21021
|
+
const parsed = SessionDiagnosticEventSchema.safeParse(parsedJson);
|
|
20989
21022
|
if (!parsed.success) {
|
|
20990
21023
|
input.writeError(
|
|
20991
21024
|
`Skipping invalid diagnostic event: ${parsed.error.message}`
|
|
@@ -20995,9 +21028,9 @@ function createApiClient(input) {
|
|
|
20995
21028
|
options.onEvent(parsed.data);
|
|
20996
21029
|
}
|
|
20997
21030
|
},
|
|
20998
|
-
async
|
|
21031
|
+
async getSession(sessionId, options = {}) {
|
|
20999
21032
|
const response = await authenticatedFetch(
|
|
21000
|
-
apiUrl(runApiPath(
|
|
21033
|
+
apiUrl(runApiPath(sessionId), options.apiBaseUrl),
|
|
21001
21034
|
{},
|
|
21002
21035
|
options.apiBaseUrl
|
|
21003
21036
|
);
|
|
@@ -21006,39 +21039,45 @@ function createApiClient(input) {
|
|
|
21006
21039
|
}
|
|
21007
21040
|
return await response.json();
|
|
21008
21041
|
},
|
|
21009
|
-
async
|
|
21010
|
-
return requestJson(runApiPath(
|
|
21042
|
+
async archiveSession(sessionId, options = {}) {
|
|
21043
|
+
return requestJson(runApiPath(sessionId), {
|
|
21011
21044
|
apiBaseUrl: options.apiBaseUrl,
|
|
21012
21045
|
method: "PATCH",
|
|
21013
21046
|
body: { archived: true }
|
|
21014
21047
|
});
|
|
21015
21048
|
},
|
|
21016
|
-
async
|
|
21017
|
-
return requestJson(runApiPath(
|
|
21049
|
+
async unarchiveSession(sessionId, options = {}) {
|
|
21050
|
+
return requestJson(runApiPath(sessionId), {
|
|
21018
21051
|
apiBaseUrl: options.apiBaseUrl,
|
|
21019
21052
|
method: "PATCH",
|
|
21020
21053
|
body: { archived: false }
|
|
21021
21054
|
});
|
|
21022
21055
|
},
|
|
21023
|
-
async
|
|
21056
|
+
async archiveSessions(sessionIds, options = {}) {
|
|
21024
21057
|
const scope = await activeProject();
|
|
21025
|
-
return requestJson(
|
|
21026
|
-
|
|
21027
|
-
|
|
21028
|
-
|
|
21029
|
-
|
|
21058
|
+
return requestJson(
|
|
21059
|
+
projectApiPath(scope, "/sessions"),
|
|
21060
|
+
{
|
|
21061
|
+
apiBaseUrl: options.apiBaseUrl,
|
|
21062
|
+
method: "PATCH",
|
|
21063
|
+
body: { session_ids: sessionIds, archived: true }
|
|
21064
|
+
}
|
|
21065
|
+
);
|
|
21030
21066
|
},
|
|
21031
|
-
async
|
|
21067
|
+
async unarchiveSessions(sessionIds, options = {}) {
|
|
21032
21068
|
const scope = await activeProject();
|
|
21033
|
-
return requestJson(
|
|
21034
|
-
|
|
21035
|
-
|
|
21036
|
-
|
|
21037
|
-
|
|
21069
|
+
return requestJson(
|
|
21070
|
+
projectApiPath(scope, "/sessions"),
|
|
21071
|
+
{
|
|
21072
|
+
apiBaseUrl: options.apiBaseUrl,
|
|
21073
|
+
method: "PATCH",
|
|
21074
|
+
body: { session_ids: sessionIds, archived: false }
|
|
21075
|
+
}
|
|
21076
|
+
);
|
|
21038
21077
|
},
|
|
21039
|
-
async sendMessage(
|
|
21078
|
+
async sendMessage(sessionId, message, options = {}) {
|
|
21040
21079
|
const response = await authenticatedFetch(
|
|
21041
|
-
apiUrl(runApiPath(
|
|
21080
|
+
apiUrl(runApiPath(sessionId, "/messages"), options.apiBaseUrl),
|
|
21042
21081
|
{
|
|
21043
21082
|
method: "POST",
|
|
21044
21083
|
headers: {
|
|
@@ -21056,9 +21095,9 @@ function createApiClient(input) {
|
|
|
21056
21095
|
}
|
|
21057
21096
|
return await response.json();
|
|
21058
21097
|
},
|
|
21059
|
-
async sendAnswer(
|
|
21098
|
+
async sendAnswer(sessionId, answer, options = {}) {
|
|
21060
21099
|
const response = await authenticatedFetch(
|
|
21061
|
-
apiUrl(runApiPath(
|
|
21100
|
+
apiUrl(runApiPath(sessionId, "/commands"), options.apiBaseUrl),
|
|
21062
21101
|
{
|
|
21063
21102
|
method: "POST",
|
|
21064
21103
|
headers: {
|
|
@@ -21076,9 +21115,9 @@ function createApiClient(input) {
|
|
|
21076
21115
|
}
|
|
21077
21116
|
return await response.json();
|
|
21078
21117
|
},
|
|
21079
|
-
async
|
|
21118
|
+
async stopSession(sessionId, options = {}) {
|
|
21080
21119
|
const response = await authenticatedFetch(
|
|
21081
|
-
apiUrl(runApiPath(
|
|
21120
|
+
apiUrl(runApiPath(sessionId, "/commands"), options.apiBaseUrl),
|
|
21082
21121
|
{
|
|
21083
21122
|
method: "POST",
|
|
21084
21123
|
headers: {
|
|
@@ -21096,29 +21135,29 @@ function createApiClient(input) {
|
|
|
21096
21135
|
}
|
|
21097
21136
|
return await response.json();
|
|
21098
21137
|
},
|
|
21099
|
-
async
|
|
21138
|
+
async listAgentSessions(agentName, options = {}) {
|
|
21100
21139
|
const scope = await activeProject();
|
|
21101
21140
|
return requestJson(
|
|
21102
|
-
agentApiPath(scope, agentName, "/
|
|
21141
|
+
agentApiPath(scope, agentName, "/sessions"),
|
|
21103
21142
|
{
|
|
21104
21143
|
apiBaseUrl: options.apiBaseUrl,
|
|
21105
21144
|
searchParams: runListSearchParams(options)
|
|
21106
21145
|
}
|
|
21107
21146
|
);
|
|
21108
21147
|
},
|
|
21109
|
-
async
|
|
21148
|
+
async listSessions(options = {}) {
|
|
21110
21149
|
const scope = await activeProject();
|
|
21111
|
-
return requestJson(projectApiPath(scope, "/
|
|
21150
|
+
return requestJson(projectApiPath(scope, "/sessions"), {
|
|
21112
21151
|
apiBaseUrl: options.apiBaseUrl,
|
|
21113
21152
|
searchParams: runListSearchParams(options)
|
|
21114
21153
|
});
|
|
21115
21154
|
},
|
|
21116
|
-
async
|
|
21117
|
-
return requestJson(runApiPath(
|
|
21155
|
+
async getSessionSummary(sessionId, options = {}) {
|
|
21156
|
+
return requestJson(runApiPath(sessionId, "/summary"), {
|
|
21118
21157
|
apiBaseUrl: options.apiBaseUrl
|
|
21119
21158
|
});
|
|
21120
21159
|
},
|
|
21121
|
-
async
|
|
21160
|
+
async getSessionConversation(sessionId, options = {}) {
|
|
21122
21161
|
const searchParams = [];
|
|
21123
21162
|
if (options.cursor) searchParams.push(["cursor", options.cursor]);
|
|
21124
21163
|
if (options.before !== void 0)
|
|
@@ -21129,14 +21168,14 @@ function createApiClient(input) {
|
|
|
21129
21168
|
for (const kind of options.kinds ?? []) searchParams.push(["kind", kind]);
|
|
21130
21169
|
for (const role of options.roles ?? []) searchParams.push(["role", role]);
|
|
21131
21170
|
return requestJson(
|
|
21132
|
-
runApiPath(
|
|
21171
|
+
runApiPath(sessionId, "/conversation"),
|
|
21133
21172
|
{
|
|
21134
21173
|
apiBaseUrl: options.apiBaseUrl,
|
|
21135
21174
|
searchParams
|
|
21136
21175
|
}
|
|
21137
21176
|
);
|
|
21138
21177
|
},
|
|
21139
|
-
async
|
|
21178
|
+
async searchSessionConversation(sessionId, queries, options = {}) {
|
|
21140
21179
|
const searchParams = queries.map((query) => [
|
|
21141
21180
|
"q",
|
|
21142
21181
|
query
|
|
@@ -21148,14 +21187,14 @@ function createApiClient(input) {
|
|
|
21148
21187
|
if (options.limit !== void 0)
|
|
21149
21188
|
searchParams.push(["limit", String(options.limit)]);
|
|
21150
21189
|
return requestJson(
|
|
21151
|
-
runApiPath(
|
|
21190
|
+
runApiPath(sessionId, "/conversation/search"),
|
|
21152
21191
|
{
|
|
21153
21192
|
apiBaseUrl: options.apiBaseUrl,
|
|
21154
21193
|
searchParams
|
|
21155
21194
|
}
|
|
21156
21195
|
);
|
|
21157
21196
|
},
|
|
21158
|
-
async
|
|
21197
|
+
async listSessionToolExchanges(sessionId, options = {}) {
|
|
21159
21198
|
const searchParams = [];
|
|
21160
21199
|
if (options.toolName) searchParams.push(["toolName", options.toolName]);
|
|
21161
21200
|
if (options.errorsOnly) searchParams.push(["errorsOnly", "true"]);
|
|
@@ -21167,31 +21206,37 @@ function createApiClient(input) {
|
|
|
21167
21206
|
if (options.limit !== void 0)
|
|
21168
21207
|
searchParams.push(["limit", String(options.limit)]);
|
|
21169
21208
|
return requestJson(
|
|
21170
|
-
runApiPath(
|
|
21209
|
+
runApiPath(sessionId, "/tools"),
|
|
21171
21210
|
{
|
|
21172
21211
|
apiBaseUrl: options.apiBaseUrl,
|
|
21173
21212
|
searchParams
|
|
21174
21213
|
}
|
|
21175
21214
|
);
|
|
21176
21215
|
},
|
|
21177
|
-
async
|
|
21178
|
-
return requestJson(
|
|
21179
|
-
|
|
21180
|
-
|
|
21181
|
-
|
|
21216
|
+
async listSessionTriggers(sessionId, options = {}) {
|
|
21217
|
+
return requestJson(
|
|
21218
|
+
runApiPath(sessionId, "/triggers"),
|
|
21219
|
+
{
|
|
21220
|
+
apiBaseUrl: options.apiBaseUrl,
|
|
21221
|
+
searchParams: options.payload ? { payload: options.payload } : void 0
|
|
21222
|
+
}
|
|
21223
|
+
);
|
|
21182
21224
|
},
|
|
21183
|
-
async listRunArtifacts(
|
|
21225
|
+
async listRunArtifacts(sessionId, options = {}) {
|
|
21184
21226
|
return requestJson(
|
|
21185
|
-
runApiPath(
|
|
21227
|
+
runApiPath(sessionId, "/artifacts"),
|
|
21186
21228
|
{
|
|
21187
21229
|
apiBaseUrl: options.apiBaseUrl
|
|
21188
21230
|
}
|
|
21189
21231
|
);
|
|
21190
21232
|
},
|
|
21191
|
-
async
|
|
21192
|
-
return requestJson(
|
|
21193
|
-
|
|
21194
|
-
|
|
21233
|
+
async listSessionCommands(sessionId, options = {}) {
|
|
21234
|
+
return requestJson(
|
|
21235
|
+
runApiPath(sessionId, "/commands"),
|
|
21236
|
+
{
|
|
21237
|
+
apiBaseUrl: options.apiBaseUrl
|
|
21238
|
+
}
|
|
21239
|
+
);
|
|
21195
21240
|
},
|
|
21196
21241
|
getOperatorInfo() {
|
|
21197
21242
|
const config2 = readConfig(input.configPath);
|
|
@@ -21261,7 +21306,7 @@ var init_package = __esm({
|
|
|
21261
21306
|
"package.json"() {
|
|
21262
21307
|
package_default = {
|
|
21263
21308
|
name: "@autohq/cli",
|
|
21264
|
-
version: "0.1.
|
|
21309
|
+
version: "0.1.148",
|
|
21265
21310
|
license: "SEE LICENSE IN README.md",
|
|
21266
21311
|
publishConfig: {
|
|
21267
21312
|
access: "public"
|
|
@@ -22174,10 +22219,6 @@ async function resolveApplyAssets(input) {
|
|
|
22174
22219
|
if (probe.stored) {
|
|
22175
22220
|
continue;
|
|
22176
22221
|
}
|
|
22177
|
-
if (input.dryRun) {
|
|
22178
|
-
inline2[probe.path] = probe.asset;
|
|
22179
|
-
continue;
|
|
22180
|
-
}
|
|
22181
22222
|
if (!await uploadAvatarAsset2(input.client, probe.asset, input.apiBaseUrl)) {
|
|
22182
22223
|
inline2[probe.path] = probe.asset;
|
|
22183
22224
|
}
|
|
@@ -23391,23 +23432,24 @@ function diffLines(oldLines, newLines) {
|
|
|
23391
23432
|
}
|
|
23392
23433
|
function collapseContext(lines) {
|
|
23393
23434
|
const collapsed = [];
|
|
23394
|
-
let
|
|
23435
|
+
let session = [];
|
|
23395
23436
|
const flush = (isLeading, isTrailing) => {
|
|
23396
23437
|
const keepStart = isLeading ? 0 : DIFF_CONTEXT_LINES;
|
|
23397
23438
|
const keepEnd = isTrailing ? 0 : DIFF_CONTEXT_LINES;
|
|
23398
|
-
if (
|
|
23399
|
-
collapsed.push(...
|
|
23439
|
+
if (session.length <= keepStart + keepEnd + 1) {
|
|
23440
|
+
collapsed.push(...session);
|
|
23400
23441
|
} else {
|
|
23401
|
-
collapsed.push(...
|
|
23442
|
+
collapsed.push(...session.slice(0, keepStart));
|
|
23402
23443
|
collapsed.push({ type: "gap", text: "" });
|
|
23403
|
-
if (keepEnd > 0)
|
|
23444
|
+
if (keepEnd > 0)
|
|
23445
|
+
collapsed.push(...session.slice(session.length - keepEnd));
|
|
23404
23446
|
}
|
|
23405
|
-
|
|
23447
|
+
session = [];
|
|
23406
23448
|
};
|
|
23407
23449
|
let seenChange = false;
|
|
23408
23450
|
for (const line of lines) {
|
|
23409
23451
|
if (line.type === "context") {
|
|
23410
|
-
|
|
23452
|
+
session.push(line);
|
|
23411
23453
|
continue;
|
|
23412
23454
|
}
|
|
23413
23455
|
flush(!seenChange, false);
|
|
@@ -24257,7 +24299,7 @@ import TextInput2 from "ink-text-input";
|
|
|
24257
24299
|
import { useCallback, useEffect as useEffect2, useMemo as useMemo2, useRef, useState as useState2 } from "react";
|
|
24258
24300
|
import { Fragment as Fragment2, jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
24259
24301
|
function ConversationView({
|
|
24260
|
-
|
|
24302
|
+
sessionId,
|
|
24261
24303
|
agentName,
|
|
24262
24304
|
workingDirectory,
|
|
24263
24305
|
apiUrl
|
|
@@ -24275,7 +24317,7 @@ function ConversationView({
|
|
|
24275
24317
|
const [completedTurn, setCompletedTurn] = useState2(null);
|
|
24276
24318
|
const turnRef = useRef({
|
|
24277
24319
|
startedAt: Date.now(),
|
|
24278
|
-
word: pickActivityWord(
|
|
24320
|
+
word: pickActivityWord(sessionId)
|
|
24279
24321
|
});
|
|
24280
24322
|
const sawLiveTurnActivity = useRef(false);
|
|
24281
24323
|
const pendingLocalCommand = useRef(false);
|
|
@@ -24298,11 +24340,11 @@ function ConversationView({
|
|
|
24298
24340
|
const seenDiagnosticIds = useRef(/* @__PURE__ */ new Set());
|
|
24299
24341
|
const [selectedCommandIndex, setSelectedCommandIndex] = useState2(0);
|
|
24300
24342
|
const applyRunSnapshot = useCallback(
|
|
24301
|
-
(
|
|
24302
|
-
setStatus(
|
|
24343
|
+
(session) => {
|
|
24344
|
+
setStatus(session.status);
|
|
24303
24345
|
if (shouldAcceptUserInputFromRunSnapshot({
|
|
24304
|
-
status:
|
|
24305
|
-
runInput:
|
|
24346
|
+
status: session.status,
|
|
24347
|
+
runInput: session.input,
|
|
24306
24348
|
hasConversationActivity: hasConversationActivity.current,
|
|
24307
24349
|
hasPendingLocalCommand: pendingLocalCommand.current
|
|
24308
24350
|
})) {
|
|
@@ -24377,7 +24419,7 @@ function ConversationView({
|
|
|
24377
24419
|
void (async () => {
|
|
24378
24420
|
while (!abort.signal.aborted) {
|
|
24379
24421
|
try {
|
|
24380
|
-
await client.
|
|
24422
|
+
await client.streamSessionConversation(sessionId, {
|
|
24381
24423
|
apiBaseUrl: apiUrl,
|
|
24382
24424
|
signal: abort.signal,
|
|
24383
24425
|
cursor,
|
|
@@ -24394,16 +24436,16 @@ function ConversationView({
|
|
|
24394
24436
|
await sleep2(250, abort.signal);
|
|
24395
24437
|
}
|
|
24396
24438
|
})();
|
|
24397
|
-
void client.
|
|
24439
|
+
void client.getSession(sessionId, { apiBaseUrl: apiUrl }).then(applyRunSnapshot).catch(() => void 0);
|
|
24398
24440
|
const statusPoll = setInterval(() => {
|
|
24399
|
-
void client.
|
|
24441
|
+
void client.getSession(sessionId, { apiBaseUrl: apiUrl }).then(applyRunSnapshot).catch(() => void 0);
|
|
24400
24442
|
}, 2e3);
|
|
24401
24443
|
return () => {
|
|
24402
24444
|
abort.abort();
|
|
24403
24445
|
clearInterval(statusPoll);
|
|
24404
24446
|
buffer.dispose();
|
|
24405
24447
|
};
|
|
24406
|
-
}, [
|
|
24448
|
+
}, [sessionId, apiUrl, client, applyRunSnapshot, updateAwaitingReply]);
|
|
24407
24449
|
useEffect2(() => {
|
|
24408
24450
|
if (!debugActive) {
|
|
24409
24451
|
return;
|
|
@@ -24412,7 +24454,7 @@ function ConversationView({
|
|
|
24412
24454
|
void (async () => {
|
|
24413
24455
|
while (!abort.signal.aborted) {
|
|
24414
24456
|
try {
|
|
24415
|
-
await client.
|
|
24457
|
+
await client.streamSessionDiagnostics(sessionId, {
|
|
24416
24458
|
apiBaseUrl: apiUrl,
|
|
24417
24459
|
signal: abort.signal,
|
|
24418
24460
|
onEvent: (event) => {
|
|
@@ -24429,9 +24471,9 @@ function ConversationView({
|
|
|
24429
24471
|
}
|
|
24430
24472
|
setDiagnostics(
|
|
24431
24473
|
(prev) => mergeDiagnosticEvent(prev, {
|
|
24432
|
-
type: "
|
|
24474
|
+
type: "session.diagnostic",
|
|
24433
24475
|
id: `local-diagnostics-error-${Date.now()}`,
|
|
24434
|
-
|
|
24476
|
+
sessionId,
|
|
24435
24477
|
level: "warn",
|
|
24436
24478
|
source: "web",
|
|
24437
24479
|
phase: "runtime",
|
|
@@ -24453,7 +24495,7 @@ function ConversationView({
|
|
|
24453
24495
|
return () => {
|
|
24454
24496
|
abort.abort();
|
|
24455
24497
|
};
|
|
24456
|
-
}, [debugActive,
|
|
24498
|
+
}, [debugActive, sessionId, apiUrl, client]);
|
|
24457
24499
|
const isFailed = status === "failed";
|
|
24458
24500
|
const showPalette = input.startsWith("/") && !isFailed;
|
|
24459
24501
|
const paletteQuery = showPalette ? input.slice(1) : "";
|
|
@@ -24501,21 +24543,21 @@ function ConversationView({
|
|
|
24501
24543
|
}
|
|
24502
24544
|
try {
|
|
24503
24545
|
const receipt = pendingQuestionToolCallId ? await client.sendAnswer(
|
|
24504
|
-
|
|
24546
|
+
sessionId,
|
|
24505
24547
|
{
|
|
24506
24548
|
toolCallId: pendingQuestionToolCallId,
|
|
24507
24549
|
answers: {},
|
|
24508
24550
|
response: text
|
|
24509
24551
|
},
|
|
24510
24552
|
{ apiBaseUrl: apiUrl }
|
|
24511
|
-
) : await client.sendMessage(
|
|
24553
|
+
) : await client.sendMessage(sessionId, text, {
|
|
24512
24554
|
apiBaseUrl: apiUrl
|
|
24513
24555
|
});
|
|
24514
24556
|
const createdAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
24515
24557
|
const localEntry = {
|
|
24516
24558
|
type: "conversation.entry",
|
|
24517
24559
|
id: `local-${receipt.command_id}`,
|
|
24518
|
-
|
|
24560
|
+
sessionId,
|
|
24519
24561
|
sequence: -1,
|
|
24520
24562
|
messageId: receipt.command_id,
|
|
24521
24563
|
role: "user",
|
|
@@ -24544,7 +24586,7 @@ function ConversationView({
|
|
|
24544
24586
|
}
|
|
24545
24587
|
},
|
|
24546
24588
|
[
|
|
24547
|
-
|
|
24589
|
+
sessionId,
|
|
24548
24590
|
apiUrl,
|
|
24549
24591
|
client,
|
|
24550
24592
|
sending,
|
|
@@ -24573,7 +24615,7 @@ function ConversationView({
|
|
|
24573
24615
|
setAnsweredQuestionIds((prev) => new Set(prev).add(toolCallId));
|
|
24574
24616
|
try {
|
|
24575
24617
|
await client.sendAnswer(
|
|
24576
|
-
|
|
24618
|
+
sessionId,
|
|
24577
24619
|
{ toolCallId, answers: submit.answers },
|
|
24578
24620
|
{ apiBaseUrl: apiUrl }
|
|
24579
24621
|
);
|
|
@@ -24590,7 +24632,7 @@ function ConversationView({
|
|
|
24590
24632
|
setSending(false);
|
|
24591
24633
|
}
|
|
24592
24634
|
},
|
|
24593
|
-
[
|
|
24635
|
+
[sessionId, apiUrl, client, sending, isFailed, updateAwaitingReply]
|
|
24594
24636
|
);
|
|
24595
24637
|
const commands = [
|
|
24596
24638
|
{
|
|
@@ -24606,7 +24648,7 @@ function ConversationView({
|
|
|
24606
24648
|
{
|
|
24607
24649
|
name: "/debug",
|
|
24608
24650
|
aliases: debugActive ? ["/debug-off"] : ["/debug-on"],
|
|
24609
|
-
description: debugActive ? "Hide
|
|
24651
|
+
description: debugActive ? "Hide session diagnostics" : "Show live session diagnostics",
|
|
24610
24652
|
action: () => {
|
|
24611
24653
|
setInput("");
|
|
24612
24654
|
setDebugActive((active) => {
|
|
@@ -24640,8 +24682,8 @@ function ConversationView({
|
|
|
24640
24682
|
/* @__PURE__ */ jsx4(Text4, { children: agentName })
|
|
24641
24683
|
] }),
|
|
24642
24684
|
/* @__PURE__ */ jsxs4(Box4, { gap: 2, children: [
|
|
24643
|
-
/* @__PURE__ */ jsx4(Text4, { color: "yellow", children: "
|
|
24644
|
-
/* @__PURE__ */ jsx4(Text4, { dimColor: true, children:
|
|
24685
|
+
/* @__PURE__ */ jsx4(Text4, { color: "yellow", children: "Session " }),
|
|
24686
|
+
/* @__PURE__ */ jsx4(Text4, { dimColor: true, children: sessionId })
|
|
24645
24687
|
] }),
|
|
24646
24688
|
workingDirectory && /* @__PURE__ */ jsxs4(Box4, { gap: 2, children: [
|
|
24647
24689
|
/* @__PURE__ */ jsx4(Text4, { color: "yellow", children: "cwd " }),
|
|
@@ -24688,7 +24730,7 @@ function ConversationView({
|
|
|
24688
24730
|
/* @__PURE__ */ jsxs4(Box4, { flexDirection: "column", borderStyle: "round", paddingX: 1, children: [
|
|
24689
24731
|
isFailed ? /* @__PURE__ */ jsxs4(Box4, { children: [
|
|
24690
24732
|
/* @__PURE__ */ jsx4(Text4, { color: "red", bold: true, children: "\u2717 " }),
|
|
24691
|
-
/* @__PURE__ */ jsx4(Text4, { dimColor: true, children: "
|
|
24733
|
+
/* @__PURE__ */ jsx4(Text4, { dimColor: true, children: "session failed" })
|
|
24692
24734
|
] }) : showQuestionPrompt && pendingQuestion ? /* @__PURE__ */ jsx4(
|
|
24693
24735
|
QuestionPrompt,
|
|
24694
24736
|
{
|
|
@@ -24730,7 +24772,7 @@ function ConversationView({
|
|
|
24730
24772
|
/* @__PURE__ */ jsxs4(Box4, { gap: 2, children: [
|
|
24731
24773
|
/* @__PURE__ */ jsx4(Text4, { dimColor: true, children: agentName }),
|
|
24732
24774
|
/* @__PURE__ */ jsx4(Text4, { dimColor: true, children: "\xB7" }),
|
|
24733
|
-
/* @__PURE__ */ jsx4(Text4, { dimColor: true, children:
|
|
24775
|
+
/* @__PURE__ */ jsx4(Text4, { dimColor: true, children: sessionId })
|
|
24734
24776
|
] }),
|
|
24735
24777
|
/* @__PURE__ */ jsxs4(Text4, { dimColor: true, children: [
|
|
24736
24778
|
awaitingReply && !isFailed ? "working" : status,
|
|
@@ -25089,7 +25131,7 @@ function agentConfigLabel(agent) {
|
|
|
25089
25131
|
const pieces = [
|
|
25090
25132
|
agent.spec.harness,
|
|
25091
25133
|
agent.spec.environment ? `env:${agent.spec.environment}` : void 0,
|
|
25092
|
-
`${agent.status.runCount}
|
|
25134
|
+
`${agent.status.runCount} sessions`
|
|
25093
25135
|
].filter(Boolean);
|
|
25094
25136
|
return pieces.join(" ");
|
|
25095
25137
|
}
|
|
@@ -25619,15 +25661,15 @@ function useIdentities(apiUrl) {
|
|
|
25619
25661
|
const client = useApiClient();
|
|
25620
25662
|
return useQuery(identitiesQueryOptions(client, apiUrl));
|
|
25621
25663
|
}
|
|
25622
|
-
function
|
|
25664
|
+
function useAgentSessions(agentName, apiUrl, includeArchived = false) {
|
|
25623
25665
|
const client = useApiClient();
|
|
25624
25666
|
return useQuery(
|
|
25625
|
-
|
|
25667
|
+
agentSessionsQueryOptions(client, agentName, apiUrl, includeArchived)
|
|
25626
25668
|
);
|
|
25627
25669
|
}
|
|
25628
|
-
function
|
|
25670
|
+
function useSessions(apiUrl, includeArchived = false) {
|
|
25629
25671
|
const client = useApiClient();
|
|
25630
|
-
return useQuery(
|
|
25672
|
+
return useQuery(sessionsQueryOptions(client, apiUrl, includeArchived));
|
|
25631
25673
|
}
|
|
25632
25674
|
function useProjects(apiUrl) {
|
|
25633
25675
|
const client = useApiClient();
|
|
@@ -25809,15 +25851,18 @@ function useRemoveConnection(apiUrl) {
|
|
|
25809
25851
|
})
|
|
25810
25852
|
});
|
|
25811
25853
|
}
|
|
25812
|
-
function
|
|
25854
|
+
function useTriggerSession(apiUrl) {
|
|
25813
25855
|
const client = useApiClient();
|
|
25814
25856
|
const queryClient = useQueryClient();
|
|
25815
25857
|
return useMutation({
|
|
25816
|
-
mutationFn: (agentName) => client.
|
|
25858
|
+
mutationFn: (agentName) => client.triggerSession(agentName, {
|
|
25859
|
+
interactive: true,
|
|
25860
|
+
apiBaseUrl: apiUrl
|
|
25861
|
+
}),
|
|
25817
25862
|
onSuccess: (_created, agentName) => {
|
|
25818
|
-
void queryClient.invalidateQueries({ queryKey: ["
|
|
25863
|
+
void queryClient.invalidateQueries({ queryKey: ["sessions", apiUrl] });
|
|
25819
25864
|
void queryClient.invalidateQueries({
|
|
25820
|
-
queryKey: ["agent-
|
|
25865
|
+
queryKey: ["agent-sessions", agentName, apiUrl]
|
|
25821
25866
|
});
|
|
25822
25867
|
void queryClient.invalidateQueries({
|
|
25823
25868
|
queryKey: queryKeys.agents(apiUrl)
|
|
@@ -25829,40 +25874,40 @@ function useArchiveRuns(apiUrl) {
|
|
|
25829
25874
|
const client = useApiClient();
|
|
25830
25875
|
const queryClient = useQueryClient();
|
|
25831
25876
|
return useMutation({
|
|
25832
|
-
mutationFn: (
|
|
25833
|
-
onSuccess: (result) => invalidateRunsQueries(queryClient, apiUrl, result.
|
|
25877
|
+
mutationFn: (sessionIds) => client.archiveSessions(sessionIds, { apiBaseUrl: apiUrl }),
|
|
25878
|
+
onSuccess: (result) => invalidateRunsQueries(queryClient, apiUrl, result.sessions)
|
|
25834
25879
|
});
|
|
25835
25880
|
}
|
|
25836
|
-
function
|
|
25881
|
+
function useUnarchiveSessions(apiUrl) {
|
|
25837
25882
|
const client = useApiClient();
|
|
25838
25883
|
const queryClient = useQueryClient();
|
|
25839
25884
|
return useMutation({
|
|
25840
|
-
mutationFn: (
|
|
25841
|
-
onSuccess: (result) => invalidateRunsQueries(queryClient, apiUrl, result.
|
|
25885
|
+
mutationFn: (sessionIds) => client.unarchiveSessions(sessionIds, { apiBaseUrl: apiUrl }),
|
|
25886
|
+
onSuccess: (result) => invalidateRunsQueries(queryClient, apiUrl, result.sessions)
|
|
25842
25887
|
});
|
|
25843
25888
|
}
|
|
25844
|
-
function
|
|
25889
|
+
function useStopSessions(apiUrl) {
|
|
25845
25890
|
const client = useApiClient();
|
|
25846
25891
|
const queryClient = useQueryClient();
|
|
25847
25892
|
return useMutation({
|
|
25848
|
-
mutationFn: (
|
|
25849
|
-
(
|
|
25850
|
-
|
|
25893
|
+
mutationFn: (sessionIds) => stopSessionsBatch(
|
|
25894
|
+
(sessionId) => client.stopSession(sessionId, { apiBaseUrl: apiUrl }),
|
|
25895
|
+
sessionIds
|
|
25851
25896
|
),
|
|
25852
|
-
//
|
|
25853
|
-
//
|
|
25897
|
+
// stopSession returns a command receipt, not session records, so invalidate the
|
|
25898
|
+
// session-list query families directly to pick up the new statuses.
|
|
25854
25899
|
onSuccess: () => invalidateRunListQueries(queryClient, apiUrl)
|
|
25855
25900
|
});
|
|
25856
25901
|
}
|
|
25857
|
-
async function
|
|
25902
|
+
async function stopSessionsBatch(stopSession, sessionIds) {
|
|
25858
25903
|
const outcomes = await Promise.all(
|
|
25859
|
-
|
|
25904
|
+
sessionIds.map(async (sessionId) => {
|
|
25860
25905
|
try {
|
|
25861
|
-
await
|
|
25862
|
-
return {
|
|
25906
|
+
await stopSession(sessionId);
|
|
25907
|
+
return { sessionId, ok: true, message: "" };
|
|
25863
25908
|
} catch (error51) {
|
|
25864
25909
|
return {
|
|
25865
|
-
|
|
25910
|
+
sessionId,
|
|
25866
25911
|
ok: false,
|
|
25867
25912
|
message: error51 instanceof Error ? error51.message : String(error51)
|
|
25868
25913
|
};
|
|
@@ -25870,37 +25915,37 @@ async function stopRunsBatch(stopRun, runIds) {
|
|
|
25870
25915
|
})
|
|
25871
25916
|
);
|
|
25872
25917
|
return {
|
|
25873
|
-
stopped: outcomes.filter((o) => o.ok).map((o) => o.
|
|
25874
|
-
failed: outcomes.filter((o) => !o.ok).map((o) => ({
|
|
25918
|
+
stopped: outcomes.filter((o) => o.ok).map((o) => o.sessionId),
|
|
25919
|
+
failed: outcomes.filter((o) => !o.ok).map((o) => ({ sessionId: o.sessionId, message: o.message }))
|
|
25875
25920
|
};
|
|
25876
25921
|
}
|
|
25877
|
-
function
|
|
25922
|
+
function agentSessionsQueryOptions(client, agentName, apiUrl, includeArchived = false) {
|
|
25878
25923
|
return queryOptions({
|
|
25879
|
-
queryKey: queryKeys.
|
|
25924
|
+
queryKey: queryKeys.agentSessions(agentName ?? "", apiUrl, includeArchived),
|
|
25880
25925
|
queryFn: async () => {
|
|
25881
|
-
const res = await client.
|
|
25926
|
+
const res = await client.listAgentSessions(agentName ?? "", {
|
|
25882
25927
|
apiBaseUrl: apiUrl,
|
|
25883
25928
|
includeArchived,
|
|
25884
|
-
// The
|
|
25929
|
+
// The session-list routes default to 50; ask for the server max so the
|
|
25885
25930
|
// TUI keeps showing deep history.
|
|
25886
|
-
limit:
|
|
25931
|
+
limit: TUI_SESSION_LIST_LIMIT
|
|
25887
25932
|
});
|
|
25888
|
-
return res.
|
|
25933
|
+
return res.sessions;
|
|
25889
25934
|
},
|
|
25890
25935
|
enabled: Boolean(agentName),
|
|
25891
25936
|
...runsFreshnessOptions()
|
|
25892
25937
|
});
|
|
25893
25938
|
}
|
|
25894
|
-
function
|
|
25939
|
+
function sessionsQueryOptions(client, apiUrl, includeArchived = false) {
|
|
25895
25940
|
return queryOptions({
|
|
25896
|
-
queryKey: queryKeys.
|
|
25941
|
+
queryKey: queryKeys.sessions(apiUrl, includeArchived),
|
|
25897
25942
|
queryFn: async () => {
|
|
25898
|
-
const res = await client.
|
|
25943
|
+
const res = await client.listSessions({
|
|
25899
25944
|
apiBaseUrl: apiUrl,
|
|
25900
25945
|
includeArchived,
|
|
25901
|
-
limit:
|
|
25946
|
+
limit: TUI_SESSION_LIST_LIMIT
|
|
25902
25947
|
});
|
|
25903
|
-
return res.
|
|
25948
|
+
return res.sessions;
|
|
25904
25949
|
},
|
|
25905
25950
|
...runsFreshnessOptions()
|
|
25906
25951
|
});
|
|
@@ -25909,7 +25954,7 @@ function runsFreshnessOptions() {
|
|
|
25909
25954
|
return {
|
|
25910
25955
|
staleTime: 0,
|
|
25911
25956
|
refetchOnMount: "always",
|
|
25912
|
-
refetchInterval:
|
|
25957
|
+
refetchInterval: SESSIONS_REFETCH_INTERVAL_MS
|
|
25913
25958
|
};
|
|
25914
25959
|
}
|
|
25915
25960
|
function environmentsQueryOptions(client, apiUrl) {
|
|
@@ -26003,27 +26048,27 @@ function sortAgents(list) {
|
|
|
26003
26048
|
function sortByName(list) {
|
|
26004
26049
|
return list.slice().sort((a, b) => a.metadata.name.localeCompare(b.metadata.name));
|
|
26005
26050
|
}
|
|
26006
|
-
function invalidateRunsQueries(queryClient, apiUrl,
|
|
26007
|
-
void queryClient.invalidateQueries({ queryKey: ["
|
|
26051
|
+
function invalidateRunsQueries(queryClient, apiUrl, sessions) {
|
|
26052
|
+
void queryClient.invalidateQueries({ queryKey: ["sessions", apiUrl] });
|
|
26008
26053
|
for (const agentName of new Set(
|
|
26009
|
-
|
|
26054
|
+
sessions.map((session) => session.snapshot.metadata.name)
|
|
26010
26055
|
)) {
|
|
26011
26056
|
void queryClient.invalidateQueries({
|
|
26012
|
-
queryKey: ["
|
|
26057
|
+
queryKey: ["sessions", agentName, apiUrl]
|
|
26013
26058
|
});
|
|
26014
26059
|
}
|
|
26015
26060
|
}
|
|
26016
26061
|
function invalidateRunListQueries(queryClient, apiUrl) {
|
|
26017
|
-
void queryClient.invalidateQueries({ queryKey: ["
|
|
26018
|
-
void queryClient.invalidateQueries({ queryKey: ["
|
|
26062
|
+
void queryClient.invalidateQueries({ queryKey: ["sessions", apiUrl] });
|
|
26063
|
+
void queryClient.invalidateQueries({ queryKey: ["sessions"] });
|
|
26019
26064
|
}
|
|
26020
|
-
var
|
|
26065
|
+
var TUI_SESSION_LIST_LIMIT, queryKeys, SESSIONS_REFETCH_INTERVAL_MS;
|
|
26021
26066
|
var init_queries = __esm({
|
|
26022
26067
|
"src/tui/hooks/queries.ts"() {
|
|
26023
26068
|
"use strict";
|
|
26024
26069
|
init_src();
|
|
26025
26070
|
init_ApiClientContext();
|
|
26026
|
-
|
|
26071
|
+
TUI_SESSION_LIST_LIMIT = 200;
|
|
26027
26072
|
queryKeys = {
|
|
26028
26073
|
environments: (apiUrl) => ["environments", apiUrl],
|
|
26029
26074
|
identities: (apiUrl) => ["identities", apiUrl],
|
|
@@ -26033,10 +26078,10 @@ var init_queries = __esm({
|
|
|
26033
26078
|
connections: (apiUrl) => ["connections", apiUrl],
|
|
26034
26079
|
githubSyncBindings: (apiUrl) => ["github-sync-bindings", apiUrl],
|
|
26035
26080
|
connectionProviders: (apiUrl) => ["connection-providers", apiUrl],
|
|
26036
|
-
|
|
26037
|
-
|
|
26081
|
+
sessions: (apiUrl, includeArchived = false) => ["sessions", apiUrl, includeArchived],
|
|
26082
|
+
agentSessions: (agentName, apiUrl, includeArchived = false) => ["agent-sessions", agentName, apiUrl, includeArchived]
|
|
26038
26083
|
};
|
|
26039
|
-
|
|
26084
|
+
SESSIONS_REFETCH_INTERVAL_MS = 5e3;
|
|
26040
26085
|
}
|
|
26041
26086
|
});
|
|
26042
26087
|
|
|
@@ -26051,15 +26096,15 @@ var init_string = __esm({
|
|
|
26051
26096
|
}
|
|
26052
26097
|
});
|
|
26053
26098
|
|
|
26054
|
-
// src/tui/
|
|
26099
|
+
// src/tui/SessionsView.tsx
|
|
26055
26100
|
import { Box as Box11, Text as Text12, useStdout as useStdout6 } from "ink";
|
|
26056
26101
|
import { jsx as jsx12, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
26057
|
-
function
|
|
26102
|
+
function SessionsView({
|
|
26058
26103
|
scopedAgent,
|
|
26059
26104
|
apiUrl,
|
|
26060
26105
|
selectedIndex = 0,
|
|
26061
26106
|
showArchived = false,
|
|
26062
|
-
|
|
26107
|
+
selectedSessionIds = EMPTY_SELECTED_RUN_IDS
|
|
26063
26108
|
}) {
|
|
26064
26109
|
const { stdout } = useStdout6();
|
|
26065
26110
|
const termWidth = stdout?.columns ?? 120;
|
|
@@ -26069,27 +26114,30 @@ function RunsView({
|
|
|
26069
26114
|
termWidth - TABLE_PANEL_BORDER_X - TABLE_PADDING_X * 2 - TABLE_GAP * ROW_GAP_COUNT2 - COL_SELECTED - COL_ID - COL_STATUS2 - COL_AGENT - COL_TRIGGER - COL_STARTED - COL_DURATION
|
|
26070
26115
|
);
|
|
26071
26116
|
const agentName = scopedAgent?.metadata.name;
|
|
26072
|
-
const
|
|
26073
|
-
const
|
|
26074
|
-
const activeQuery = scopedAgent ?
|
|
26075
|
-
const { data:
|
|
26076
|
-
const sorted =
|
|
26117
|
+
const allSessionsQuery = useSessions(apiUrl, showArchived);
|
|
26118
|
+
const sessionsQuery = useAgentSessions(agentName, apiUrl, showArchived);
|
|
26119
|
+
const activeQuery = scopedAgent ? sessionsQuery : allSessionsQuery;
|
|
26120
|
+
const { data: sessions, isLoading, error: error51 } = activeQuery;
|
|
26121
|
+
const sorted = sessionsForArchiveMode(sessions ?? [], showArchived);
|
|
26077
26122
|
const visibleCount = Math.max(1, termHeight - CHROME_ROWS);
|
|
26078
26123
|
const safeIndex = Math.min(Math.max(0, selectedIndex), sorted.length - 1);
|
|
26079
26124
|
let scrollOffset = Math.max(0, safeIndex - (visibleCount - 1));
|
|
26080
26125
|
if (sorted.length - scrollOffset < visibleCount) {
|
|
26081
26126
|
scrollOffset = Math.max(0, sorted.length - visibleCount);
|
|
26082
26127
|
}
|
|
26083
|
-
const
|
|
26128
|
+
const visibleSessions = sorted.slice(
|
|
26129
|
+
scrollOffset,
|
|
26130
|
+
scrollOffset + visibleCount
|
|
26131
|
+
);
|
|
26084
26132
|
const hiddenAbove = scrollOffset;
|
|
26085
26133
|
const hiddenBelow = Math.max(
|
|
26086
26134
|
0,
|
|
26087
|
-
sorted.length - (scrollOffset +
|
|
26135
|
+
sorted.length - (scrollOffset + visibleSessions.length)
|
|
26088
26136
|
);
|
|
26089
|
-
return /* @__PURE__ */ jsx12(Box11, { flexGrow: 1, flexDirection: "column", children: isLoading ? /* @__PURE__ */ jsx12(Box11, { paddingX: 2, children: /* @__PURE__ */ jsx12(Text12, { dimColor: true, children: "loading
|
|
26090
|
-
"failed to load
|
|
26137
|
+
return /* @__PURE__ */ jsx12(Box11, { flexGrow: 1, flexDirection: "column", children: isLoading ? /* @__PURE__ */ jsx12(Box11, { paddingX: 2, children: /* @__PURE__ */ jsx12(Text12, { dimColor: true, children: "loading sessions\u2026" }) }) : error51 ? /* @__PURE__ */ jsx12(Box11, { paddingX: 2, children: /* @__PURE__ */ jsxs10(Text12, { color: "red", children: [
|
|
26138
|
+
"failed to load sessions: ",
|
|
26091
26139
|
String(error51)
|
|
26092
|
-
] }) }) : sorted.length === 0 ? /* @__PURE__ */ jsx12(Box11, { paddingX: 2, children: /* @__PURE__ */ jsx12(Text12, { dimColor: true, children: showArchived ? "no archived
|
|
26140
|
+
] }) }) : sorted.length === 0 ? /* @__PURE__ */ jsx12(Box11, { paddingX: 2, children: /* @__PURE__ */ jsx12(Text12, { dimColor: true, children: showArchived ? "no archived sessions" : "no sessions yet \u2014 press n to start a new session" }) }) : /* @__PURE__ */ jsxs10(Box11, { flexDirection: "column", children: [
|
|
26093
26141
|
/* @__PURE__ */ jsxs10(Box11, { paddingX: TABLE_PADDING_X, paddingBottom: 1, gap: TABLE_GAP, children: [
|
|
26094
26142
|
/* @__PURE__ */ jsx12(HeaderCell, { width: COL_SELECTED, children: "SEL" }),
|
|
26095
26143
|
/* @__PURE__ */ jsx12(HeaderCell, { width: COL_ID, children: "ID" }),
|
|
@@ -26105,12 +26153,12 @@ function RunsView({
|
|
|
26105
26153
|
hiddenAbove,
|
|
26106
26154
|
" more above"
|
|
26107
26155
|
] }) }),
|
|
26108
|
-
|
|
26156
|
+
visibleSessions.map((session, vi) => {
|
|
26109
26157
|
const i = scrollOffset + vi;
|
|
26110
|
-
const title =
|
|
26111
|
-
const err =
|
|
26158
|
+
const title = sessionDisplayTitle(session);
|
|
26159
|
+
const err = session.status === "failed" ? errorMessage(session) : null;
|
|
26112
26160
|
const isSelected = i === safeIndex;
|
|
26113
|
-
const isMarked =
|
|
26161
|
+
const isMarked = selectedSessionIds.has(session.id);
|
|
26114
26162
|
return /* @__PURE__ */ jsxs10(Box11, { flexDirection: "column", children: [
|
|
26115
26163
|
/* @__PURE__ */ jsxs10(TableRow, { selected: isSelected, children: [
|
|
26116
26164
|
/* @__PURE__ */ jsx12(
|
|
@@ -26131,18 +26179,18 @@ function RunsView({
|
|
|
26131
26179
|
selected: isSelected,
|
|
26132
26180
|
dim: !isSelected,
|
|
26133
26181
|
primary: true,
|
|
26134
|
-
children:
|
|
26182
|
+
children: shortSessionId(session.id)
|
|
26135
26183
|
}
|
|
26136
26184
|
),
|
|
26137
26185
|
/* @__PURE__ */ jsxs10(Box11, { width: COL_STATUS2, gap: 1, children: [
|
|
26138
|
-
/* @__PURE__ */ jsx12(StatusDot, { status:
|
|
26186
|
+
/* @__PURE__ */ jsx12(StatusDot, { status: session.status, selected: isSelected }),
|
|
26139
26187
|
/* @__PURE__ */ jsx12(
|
|
26140
26188
|
Text12,
|
|
26141
26189
|
{
|
|
26142
26190
|
color: isSelected ? "black" : void 0,
|
|
26143
26191
|
dimColor: !isSelected,
|
|
26144
26192
|
wrap: "truncate",
|
|
26145
|
-
children:
|
|
26193
|
+
children: session.status
|
|
26146
26194
|
}
|
|
26147
26195
|
)
|
|
26148
26196
|
] }),
|
|
@@ -26152,7 +26200,7 @@ function RunsView({
|
|
|
26152
26200
|
width: COL_AGENT,
|
|
26153
26201
|
selected: isSelected,
|
|
26154
26202
|
dim: !isSelected,
|
|
26155
|
-
children: agentNameForRun(
|
|
26203
|
+
children: agentNameForRun(session)
|
|
26156
26204
|
}
|
|
26157
26205
|
),
|
|
26158
26206
|
/* @__PURE__ */ jsx12(
|
|
@@ -26161,7 +26209,7 @@ function RunsView({
|
|
|
26161
26209
|
width: COL_TRIGGER,
|
|
26162
26210
|
selected: isSelected,
|
|
26163
26211
|
dim: !isSelected,
|
|
26164
|
-
children: triggerKind(
|
|
26212
|
+
children: triggerKind(session)
|
|
26165
26213
|
}
|
|
26166
26214
|
),
|
|
26167
26215
|
/* @__PURE__ */ jsx12(TableCell, { width: titleWidth, selected: isSelected, children: truncateToWidth(title, titleWidth) }),
|
|
@@ -26172,7 +26220,7 @@ function RunsView({
|
|
|
26172
26220
|
selected: isSelected,
|
|
26173
26221
|
dim: !isSelected,
|
|
26174
26222
|
justifyContent: "flex-end",
|
|
26175
|
-
children: relativeTime3(
|
|
26223
|
+
children: relativeTime3(session.startedAt ?? session.createdAt)
|
|
26176
26224
|
}
|
|
26177
26225
|
),
|
|
26178
26226
|
/* @__PURE__ */ jsx12(
|
|
@@ -26182,7 +26230,7 @@ function RunsView({
|
|
|
26182
26230
|
selected: isSelected,
|
|
26183
26231
|
dim: !isSelected,
|
|
26184
26232
|
justifyContent: "flex-end",
|
|
26185
|
-
children: duration3(
|
|
26233
|
+
children: duration3(session)
|
|
26186
26234
|
}
|
|
26187
26235
|
)
|
|
26188
26236
|
] }),
|
|
@@ -26190,7 +26238,7 @@ function RunsView({
|
|
|
26190
26238
|
"\u2514 ",
|
|
26191
26239
|
fitToWidth(err, Math.max(40, termWidth - 20))
|
|
26192
26240
|
] }) })
|
|
26193
|
-
] },
|
|
26241
|
+
] }, session.id);
|
|
26194
26242
|
}),
|
|
26195
26243
|
hiddenBelow > 0 && /* @__PURE__ */ jsx12(Box11, { paddingX: 2, children: /* @__PURE__ */ jsxs10(Text12, { dimColor: true, children: [
|
|
26196
26244
|
"\u2193 ",
|
|
@@ -26210,10 +26258,10 @@ function relativeTime3(dateStr) {
|
|
|
26210
26258
|
const d = Math.floor(h / 24);
|
|
26211
26259
|
return `${d}d ago`;
|
|
26212
26260
|
}
|
|
26213
|
-
function duration3(
|
|
26214
|
-
if (!
|
|
26215
|
-
const end =
|
|
26216
|
-
const ms = new Date(end).getTime() - new Date(
|
|
26261
|
+
function duration3(session) {
|
|
26262
|
+
if (!session.startedAt) return "\u2014";
|
|
26263
|
+
const end = session.finishedAt ?? (/* @__PURE__ */ new Date()).toISOString();
|
|
26264
|
+
const ms = new Date(end).getTime() - new Date(session.startedAt).getTime();
|
|
26217
26265
|
const s = Math.max(0, Math.floor(ms / 1e3));
|
|
26218
26266
|
if (s < 60) return `${s}s`;
|
|
26219
26267
|
const m = Math.floor(s / 60);
|
|
@@ -26221,7 +26269,7 @@ function duration3(run) {
|
|
|
26221
26269
|
const h = Math.floor(m / 60);
|
|
26222
26270
|
return `${h}h${m % 60 ? ` ${m % 60}m` : ""}`;
|
|
26223
26271
|
}
|
|
26224
|
-
function
|
|
26272
|
+
function shortSessionId(id) {
|
|
26225
26273
|
const tail = id.split("-").pop();
|
|
26226
26274
|
return tail ? tail.slice(0, 12) : id.slice(0, 12);
|
|
26227
26275
|
}
|
|
@@ -26231,40 +26279,42 @@ function readField(value, key) {
|
|
|
26231
26279
|
}
|
|
26232
26280
|
return void 0;
|
|
26233
26281
|
}
|
|
26234
|
-
function triggerKind(
|
|
26235
|
-
const t = readField(
|
|
26282
|
+
function triggerKind(session) {
|
|
26283
|
+
const t = readField(session.input, "trigger");
|
|
26236
26284
|
return typeof t === "string" ? t : "\u2014";
|
|
26237
26285
|
}
|
|
26238
|
-
function
|
|
26239
|
-
return
|
|
26286
|
+
function sessionDisplayTitle(session) {
|
|
26287
|
+
return session.displayTitle.replace(/\s+/g, " ").trim();
|
|
26240
26288
|
}
|
|
26241
26289
|
function truncateToWidth(value, width) {
|
|
26242
26290
|
if (!value) return " ";
|
|
26243
26291
|
if (value.length <= width) return value;
|
|
26244
26292
|
return `${value.slice(0, Math.max(0, width - 1))}\u2026`;
|
|
26245
26293
|
}
|
|
26246
|
-
function agentNameForRun(
|
|
26247
|
-
return
|
|
26294
|
+
function agentNameForRun(session) {
|
|
26295
|
+
return session.snapshot.metadata.name;
|
|
26248
26296
|
}
|
|
26249
|
-
function errorMessage(
|
|
26250
|
-
if (
|
|
26251
|
-
if (typeof
|
|
26252
|
-
const msg = readField(
|
|
26297
|
+
function errorMessage(session) {
|
|
26298
|
+
if (session.error == null) return null;
|
|
26299
|
+
if (typeof session.error === "string") return session.error;
|
|
26300
|
+
const msg = readField(session.error, "message");
|
|
26253
26301
|
if (typeof msg === "string") return msg;
|
|
26254
26302
|
try {
|
|
26255
|
-
return JSON.stringify(
|
|
26303
|
+
return JSON.stringify(session.error);
|
|
26256
26304
|
} catch {
|
|
26257
26305
|
return null;
|
|
26258
26306
|
}
|
|
26259
26307
|
}
|
|
26260
|
-
function
|
|
26261
|
-
return
|
|
26308
|
+
function sessionsForArchiveMode(sessions, showArchived) {
|
|
26309
|
+
return sessions.filter(
|
|
26310
|
+
(session) => showArchived ? Boolean(session.archivedAt) : !session.archivedAt
|
|
26311
|
+
).slice().sort(
|
|
26262
26312
|
(a, b) => new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime()
|
|
26263
26313
|
);
|
|
26264
26314
|
}
|
|
26265
26315
|
var COL_SELECTED, COL_ID, COL_STATUS2, COL_AGENT, COL_TRIGGER, COL_STARTED, COL_DURATION, ROW_GAP_COUNT2, EMPTY_SELECTED_RUN_IDS, CHROME_ROWS;
|
|
26266
|
-
var
|
|
26267
|
-
"src/tui/
|
|
26316
|
+
var init_SessionsView = __esm({
|
|
26317
|
+
"src/tui/SessionsView.tsx"() {
|
|
26268
26318
|
"use strict";
|
|
26269
26319
|
init_StatusDot();
|
|
26270
26320
|
init_Table();
|
|
@@ -26445,27 +26495,27 @@ function HomeView({ apiUrl, notice, returnToAgent }) {
|
|
|
26445
26495
|
const termWidth = termSize.width;
|
|
26446
26496
|
const termHeight = termSize.height;
|
|
26447
26497
|
const [activeSection, setSection] = useState3(
|
|
26448
|
-
returnToAgent ? "
|
|
26498
|
+
returnToAgent ? "sessions" : "agents"
|
|
26449
26499
|
);
|
|
26450
26500
|
const [agentIndex, setAgentIndex] = useState3(0);
|
|
26451
26501
|
const [environmentIndex, setEnvironmentIndex] = useState3(0);
|
|
26452
26502
|
const [identityIndex, setIdentityIndex] = useState3(0);
|
|
26453
26503
|
const [projectIndex, setProjectIndex] = useState3(0);
|
|
26454
26504
|
const [serviceAccountIndex, setServiceAccountIndex] = useState3(0);
|
|
26455
|
-
const [
|
|
26505
|
+
const [sessionIndex, setSessionIndex] = useState3(0);
|
|
26456
26506
|
const [runScopeAgentName, setRunScopeAgentName] = useState3(
|
|
26457
26507
|
returnToAgent ?? null
|
|
26458
26508
|
);
|
|
26459
|
-
const [
|
|
26460
|
-
const [
|
|
26509
|
+
const [showArchivedSessions, setShowArchivedSessions] = useState3(false);
|
|
26510
|
+
const [selectedSessionIds, setSelectedSessionIds] = useState3(
|
|
26461
26511
|
() => /* @__PURE__ */ new Set()
|
|
26462
26512
|
);
|
|
26463
26513
|
const [pendingArchiveRunKey, setPendingArchiveRunKey] = useState3(null);
|
|
26464
|
-
const [
|
|
26514
|
+
const [pendingUnarchiveSessionKey, setPendingUnarchiveSessionKey] = useState3(null);
|
|
26465
26515
|
const [pendingStopRunKey, setPendingStopRunKey] = useState3(
|
|
26466
26516
|
null
|
|
26467
26517
|
);
|
|
26468
|
-
const [
|
|
26518
|
+
const [sessionNotice, setSessionNotice] = useState3(null);
|
|
26469
26519
|
const [connectionIndex, setConnectionIndex] = useState3(0);
|
|
26470
26520
|
const [connectionProviderIndex, setConnectionProviderIndex] = useState3(0);
|
|
26471
26521
|
const [connectionMode, setConnectionMode] = useState3("connections");
|
|
@@ -26539,10 +26589,10 @@ function HomeView({ apiUrl, notice, returnToAgent }) {
|
|
|
26539
26589
|
const createServiceAccount2 = useCreateServiceAccount(apiUrl);
|
|
26540
26590
|
const rotateServiceAccount2 = useRotateServiceAccount(apiUrl);
|
|
26541
26591
|
const removeServiceAccount2 = useRemoveServiceAccount(apiUrl);
|
|
26542
|
-
const
|
|
26543
|
-
const
|
|
26544
|
-
const
|
|
26545
|
-
const
|
|
26592
|
+
const triggerSession = useTriggerSession(apiUrl);
|
|
26593
|
+
const archiveSessions = useArchiveRuns(apiUrl);
|
|
26594
|
+
const unarchiveSessions = useUnarchiveSessions(apiUrl);
|
|
26595
|
+
const stopSessions = useStopSessions(apiUrl);
|
|
26546
26596
|
const [connectionNotice, setConnectionNotice] = useState3(null);
|
|
26547
26597
|
const [serviceAccountNotice, setServiceAccountNotice] = useState3(null);
|
|
26548
26598
|
const [pendingRemoveConnectionKey, setPendingRemoveConnectionKey] = useState3(null);
|
|
@@ -26639,37 +26689,43 @@ function HomeView({ apiUrl, notice, returnToAgent }) {
|
|
|
26639
26689
|
);
|
|
26640
26690
|
const inspectPanelHeight = Math.max(1, termHeight - 12);
|
|
26641
26691
|
const scopedAgent = runScopeAgentName ? agents.find((agent) => agent.metadata.name === runScopeAgentName) : void 0;
|
|
26642
|
-
const { data:
|
|
26643
|
-
|
|
26692
|
+
const { data: allSessionsRaw = [] } = useSessions(
|
|
26693
|
+
apiUrl,
|
|
26694
|
+
showArchivedSessions
|
|
26695
|
+
);
|
|
26696
|
+
const { data: scopedSessionsRaw = [] } = useAgentSessions(
|
|
26644
26697
|
scopedAgent?.metadata.name,
|
|
26645
26698
|
apiUrl,
|
|
26646
|
-
|
|
26699
|
+
showArchivedSessions
|
|
26700
|
+
);
|
|
26701
|
+
const visibleSessionsRaw = scopedAgent ? scopedSessionsRaw : allSessionsRaw;
|
|
26702
|
+
const visibleSessions = sessionsForArchiveMode(
|
|
26703
|
+
visibleSessionsRaw,
|
|
26704
|
+
showArchivedSessions
|
|
26647
26705
|
);
|
|
26648
|
-
const
|
|
26649
|
-
const
|
|
26650
|
-
|
|
26651
|
-
|
|
26652
|
-
visibleRuns,
|
|
26653
|
-
selectedRunIds
|
|
26706
|
+
const selectedSession = visibleSessions[sessionIndex];
|
|
26707
|
+
const markedSessionIds = selectedSessionIdsForVisibleRuns(
|
|
26708
|
+
visibleSessions,
|
|
26709
|
+
selectedSessionIds
|
|
26654
26710
|
);
|
|
26655
|
-
const
|
|
26711
|
+
const visibleSessionIdKey = visibleSessions.map((session) => session.id).join("\0");
|
|
26656
26712
|
useEffect3(() => {
|
|
26657
|
-
|
|
26658
|
-
}, [
|
|
26713
|
+
setSessionIndex((i) => clampListIndex(i, visibleSessions.length));
|
|
26714
|
+
}, [visibleSessions.length]);
|
|
26659
26715
|
useEffect3(() => {
|
|
26660
|
-
|
|
26716
|
+
setSelectedSessionIds((current) => {
|
|
26661
26717
|
if (current.size === 0) {
|
|
26662
26718
|
return current;
|
|
26663
26719
|
}
|
|
26664
|
-
const
|
|
26665
|
-
|
|
26720
|
+
const visibleSessionIds = new Set(
|
|
26721
|
+
visibleSessionIdKey ? visibleSessionIdKey.split("\0") : []
|
|
26666
26722
|
);
|
|
26667
26723
|
const next = new Set(
|
|
26668
|
-
[...current].filter((
|
|
26724
|
+
[...current].filter((sessionId) => visibleSessionIds.has(sessionId))
|
|
26669
26725
|
);
|
|
26670
26726
|
return next.size === current.size ? current : next;
|
|
26671
26727
|
});
|
|
26672
|
-
}, [
|
|
26728
|
+
}, [visibleSessionIdKey]);
|
|
26673
26729
|
useEffect3(() => {
|
|
26674
26730
|
const environmentName = selectedAgent?.spec.environment;
|
|
26675
26731
|
if (!environmentName) return;
|
|
@@ -26680,168 +26736,183 @@ function HomeView({ apiUrl, notice, returnToAgent }) {
|
|
|
26680
26736
|
}, [environments, selectedAgent]);
|
|
26681
26737
|
const connectionStatus = startConnection.error instanceof Error ? startConnection.error.message : allowConnection.error instanceof Error ? allowConnection.error.message : removeConnection.error instanceof Error ? removeConnection.error.message : createGithubSyncBinding.error instanceof Error ? createGithubSyncBinding.error.message : connectionNotice;
|
|
26682
26738
|
const startRun = useCallback2(() => {
|
|
26683
|
-
if (!scopedAgent ||
|
|
26684
|
-
|
|
26685
|
-
|
|
26739
|
+
if (!scopedAgent || triggerSession.isPending) return;
|
|
26740
|
+
triggerSession.reset();
|
|
26741
|
+
triggerSession.mutate(scopedAgent.metadata.name, {
|
|
26686
26742
|
onSuccess: (created) => {
|
|
26687
26743
|
exit({
|
|
26688
|
-
|
|
26744
|
+
sessionId: created.session_id,
|
|
26689
26745
|
agentName: scopedAgent.metadata.name,
|
|
26690
26746
|
workingDirectory: scopedAgent.spec.workingDirectory
|
|
26691
26747
|
});
|
|
26692
26748
|
}
|
|
26693
26749
|
});
|
|
26694
|
-
}, [scopedAgent,
|
|
26750
|
+
}, [scopedAgent, triggerSession, exit]);
|
|
26695
26751
|
const toggleSelectedRun = useCallback2(() => {
|
|
26696
26752
|
setPendingArchiveRunKey(null);
|
|
26697
|
-
|
|
26753
|
+
setPendingUnarchiveSessionKey(null);
|
|
26698
26754
|
setPendingStopRunKey(null);
|
|
26699
|
-
|
|
26700
|
-
|
|
26701
|
-
|
|
26702
|
-
if (!
|
|
26703
|
-
|
|
26755
|
+
archiveSessions.reset();
|
|
26756
|
+
unarchiveSessions.reset();
|
|
26757
|
+
stopSessions.reset();
|
|
26758
|
+
if (!selectedSession) {
|
|
26759
|
+
setSessionNotice("Select a session before marking it.");
|
|
26704
26760
|
return;
|
|
26705
26761
|
}
|
|
26706
|
-
const wasSelected =
|
|
26707
|
-
|
|
26762
|
+
const wasSelected = selectedSessionIds.has(selectedSession.id);
|
|
26763
|
+
setSelectedSessionIds((current) => {
|
|
26708
26764
|
const next = new Set(current);
|
|
26709
|
-
if (next.has(
|
|
26710
|
-
next.delete(
|
|
26765
|
+
if (next.has(selectedSession.id)) {
|
|
26766
|
+
next.delete(selectedSession.id);
|
|
26711
26767
|
} else {
|
|
26712
|
-
next.add(
|
|
26768
|
+
next.add(selectedSession.id);
|
|
26713
26769
|
}
|
|
26714
26770
|
return next;
|
|
26715
26771
|
});
|
|
26716
|
-
|
|
26717
|
-
wasSelected ? `Unmarked
|
|
26772
|
+
setSessionNotice(
|
|
26773
|
+
wasSelected ? `Unmarked session ${shortSessionId2(selectedSession.id)}.` : `Marked session ${shortSessionId2(selectedSession.id)}.`
|
|
26718
26774
|
);
|
|
26719
|
-
}, [
|
|
26775
|
+
}, [
|
|
26776
|
+
archiveSessions,
|
|
26777
|
+
selectedSession,
|
|
26778
|
+
selectedSessionIds,
|
|
26779
|
+
stopSessions,
|
|
26780
|
+
unarchiveSessions
|
|
26781
|
+
]);
|
|
26720
26782
|
const archiveSelectedRun = useCallback2(() => {
|
|
26721
|
-
|
|
26722
|
-
|
|
26723
|
-
|
|
26724
|
-
|
|
26783
|
+
archiveSessions.reset();
|
|
26784
|
+
unarchiveSessions.reset();
|
|
26785
|
+
stopSessions.reset();
|
|
26786
|
+
setPendingUnarchiveSessionKey(null);
|
|
26725
26787
|
setPendingStopRunKey(null);
|
|
26726
|
-
const
|
|
26727
|
-
|
|
26728
|
-
|
|
26788
|
+
const sessionIds = sessionIdsForArchiveAction({
|
|
26789
|
+
markedSessionIds,
|
|
26790
|
+
selectedSession
|
|
26729
26791
|
});
|
|
26730
|
-
if (
|
|
26731
|
-
|
|
26792
|
+
if (sessionIds.length === 0) {
|
|
26793
|
+
setSessionNotice("Select a session before archiving.");
|
|
26732
26794
|
return;
|
|
26733
26795
|
}
|
|
26734
|
-
const actionKey = runArchiveActionKey(
|
|
26796
|
+
const actionKey = runArchiveActionKey(sessionIds);
|
|
26735
26797
|
if (pendingArchiveRunKey !== actionKey) {
|
|
26736
26798
|
setPendingArchiveRunKey(actionKey);
|
|
26737
|
-
|
|
26738
|
-
`Press a again to archive ${runActionTargetLabel(
|
|
26799
|
+
setSessionNotice(
|
|
26800
|
+
`Press a again to archive ${runActionTargetLabel(sessionIds, markedSessionIds.length)}.`
|
|
26739
26801
|
);
|
|
26740
26802
|
return;
|
|
26741
26803
|
}
|
|
26742
26804
|
setPendingArchiveRunKey(null);
|
|
26743
|
-
|
|
26744
|
-
|
|
26805
|
+
setSessionNotice(null);
|
|
26806
|
+
archiveSessions.mutate(sessionIds, {
|
|
26745
26807
|
onSuccess: (result) => {
|
|
26746
|
-
|
|
26747
|
-
|
|
26808
|
+
setSelectedSessionIds(/* @__PURE__ */ new Set());
|
|
26809
|
+
setSessionNotice(
|
|
26810
|
+
`Archived ${pluralizeRunCount(result.sessions.length)}.`
|
|
26811
|
+
);
|
|
26748
26812
|
}
|
|
26749
26813
|
});
|
|
26750
26814
|
}, [
|
|
26751
|
-
|
|
26752
|
-
|
|
26815
|
+
archiveSessions,
|
|
26816
|
+
markedSessionIds,
|
|
26753
26817
|
pendingArchiveRunKey,
|
|
26754
|
-
|
|
26755
|
-
|
|
26756
|
-
|
|
26818
|
+
selectedSession,
|
|
26819
|
+
stopSessions,
|
|
26820
|
+
unarchiveSessions
|
|
26757
26821
|
]);
|
|
26758
26822
|
const unarchiveSelectedRun = useCallback2(() => {
|
|
26759
|
-
|
|
26760
|
-
|
|
26761
|
-
|
|
26823
|
+
archiveSessions.reset();
|
|
26824
|
+
unarchiveSessions.reset();
|
|
26825
|
+
stopSessions.reset();
|
|
26762
26826
|
setPendingArchiveRunKey(null);
|
|
26763
26827
|
setPendingStopRunKey(null);
|
|
26764
|
-
const
|
|
26765
|
-
|
|
26766
|
-
|
|
26828
|
+
const sessionIds = sessionIdsForArchiveAction({
|
|
26829
|
+
markedSessionIds,
|
|
26830
|
+
selectedSession
|
|
26767
26831
|
});
|
|
26768
|
-
if (
|
|
26769
|
-
|
|
26832
|
+
if (sessionIds.length === 0) {
|
|
26833
|
+
setSessionNotice("Select an archived session before restoring.");
|
|
26770
26834
|
return;
|
|
26771
26835
|
}
|
|
26772
|
-
const actionKey = runArchiveActionKey(
|
|
26773
|
-
if (
|
|
26774
|
-
|
|
26775
|
-
|
|
26776
|
-
`Press u again to restore ${runActionTargetLabel(
|
|
26836
|
+
const actionKey = runArchiveActionKey(sessionIds);
|
|
26837
|
+
if (pendingUnarchiveSessionKey !== actionKey) {
|
|
26838
|
+
setPendingUnarchiveSessionKey(actionKey);
|
|
26839
|
+
setSessionNotice(
|
|
26840
|
+
`Press u again to restore ${runActionTargetLabel(sessionIds, markedSessionIds.length)}.`
|
|
26777
26841
|
);
|
|
26778
26842
|
return;
|
|
26779
26843
|
}
|
|
26780
|
-
|
|
26781
|
-
|
|
26782
|
-
|
|
26844
|
+
setPendingUnarchiveSessionKey(null);
|
|
26845
|
+
setSessionNotice(null);
|
|
26846
|
+
unarchiveSessions.mutate(sessionIds, {
|
|
26783
26847
|
onSuccess: (result) => {
|
|
26784
|
-
|
|
26785
|
-
|
|
26848
|
+
setSelectedSessionIds(/* @__PURE__ */ new Set());
|
|
26849
|
+
setSessionNotice(
|
|
26850
|
+
`Restored ${pluralizeRunCount(result.sessions.length)}.`
|
|
26851
|
+
);
|
|
26786
26852
|
}
|
|
26787
26853
|
});
|
|
26788
26854
|
}, [
|
|
26789
|
-
|
|
26790
|
-
|
|
26791
|
-
|
|
26792
|
-
|
|
26793
|
-
|
|
26794
|
-
|
|
26855
|
+
archiveSessions,
|
|
26856
|
+
markedSessionIds,
|
|
26857
|
+
pendingUnarchiveSessionKey,
|
|
26858
|
+
selectedSession,
|
|
26859
|
+
stopSessions,
|
|
26860
|
+
unarchiveSessions
|
|
26795
26861
|
]);
|
|
26796
26862
|
const stopSelectedRuns = useCallback2(() => {
|
|
26797
|
-
|
|
26798
|
-
|
|
26799
|
-
|
|
26863
|
+
stopSessions.reset();
|
|
26864
|
+
archiveSessions.reset();
|
|
26865
|
+
unarchiveSessions.reset();
|
|
26800
26866
|
setPendingArchiveRunKey(null);
|
|
26801
|
-
|
|
26802
|
-
const
|
|
26803
|
-
|
|
26867
|
+
setPendingUnarchiveSessionKey(null);
|
|
26868
|
+
const sessionIds = sessionIdsForArchiveAction({
|
|
26869
|
+
markedSessionIds,
|
|
26870
|
+
selectedSession
|
|
26871
|
+
});
|
|
26872
|
+
if (sessionIds.length === 0) {
|
|
26804
26873
|
setPendingStopRunKey(null);
|
|
26805
|
-
|
|
26874
|
+
setSessionNotice("Select a session before stopping.");
|
|
26806
26875
|
return;
|
|
26807
26876
|
}
|
|
26808
|
-
const runsById = new Map(
|
|
26809
|
-
|
|
26810
|
-
|
|
26877
|
+
const runsById = new Map(
|
|
26878
|
+
visibleSessions.map((session) => [session.id, session])
|
|
26879
|
+
);
|
|
26880
|
+
const { stoppableSessionIds, skippedSessionIds } = partitionRunsForStop(
|
|
26881
|
+
sessionIds,
|
|
26811
26882
|
runsById
|
|
26812
26883
|
);
|
|
26813
|
-
if (
|
|
26884
|
+
if (stoppableSessionIds.length === 0) {
|
|
26814
26885
|
setPendingStopRunKey(null);
|
|
26815
|
-
|
|
26816
|
-
`Nothing to stop \u2014 ${pluralizeRunCount(
|
|
26886
|
+
setSessionNotice(
|
|
26887
|
+
`Nothing to stop \u2014 ${pluralizeRunCount(skippedSessionIds.length)} already stopped or failed.`
|
|
26817
26888
|
);
|
|
26818
26889
|
return;
|
|
26819
26890
|
}
|
|
26820
|
-
const actionKey = runArchiveActionKey(
|
|
26891
|
+
const actionKey = runArchiveActionKey(stoppableSessionIds);
|
|
26821
26892
|
if (pendingStopRunKey !== actionKey) {
|
|
26822
26893
|
setPendingStopRunKey(actionKey);
|
|
26823
|
-
const skipNote =
|
|
26824
|
-
|
|
26825
|
-
`Press s again to stop ${stopTargetLabel(
|
|
26894
|
+
const skipNote = skippedSessionIds.length > 0 ? ` (skipping ${pluralizeRunCount(skippedSessionIds.length)} already stopped or failed)` : "";
|
|
26895
|
+
setSessionNotice(
|
|
26896
|
+
`Press s again to stop ${stopTargetLabel(stoppableSessionIds, markedSessionIds.length > 0)}${skipNote}.`
|
|
26826
26897
|
);
|
|
26827
26898
|
return;
|
|
26828
26899
|
}
|
|
26829
26900
|
setPendingStopRunKey(null);
|
|
26830
|
-
|
|
26831
|
-
|
|
26901
|
+
setSessionNotice(null);
|
|
26902
|
+
stopSessions.mutate(stoppableSessionIds, {
|
|
26832
26903
|
onSuccess: (result) => {
|
|
26833
|
-
|
|
26834
|
-
|
|
26904
|
+
setSelectedSessionIds(/* @__PURE__ */ new Set());
|
|
26905
|
+
setSessionNotice(stopResultNotice(result, skippedSessionIds.length));
|
|
26835
26906
|
}
|
|
26836
26907
|
});
|
|
26837
26908
|
}, [
|
|
26838
|
-
|
|
26839
|
-
|
|
26909
|
+
archiveSessions,
|
|
26910
|
+
markedSessionIds,
|
|
26840
26911
|
pendingStopRunKey,
|
|
26841
|
-
|
|
26842
|
-
|
|
26843
|
-
|
|
26844
|
-
|
|
26912
|
+
selectedSession,
|
|
26913
|
+
stopSessions,
|
|
26914
|
+
unarchiveSessions,
|
|
26915
|
+
visibleSessions
|
|
26845
26916
|
]);
|
|
26846
26917
|
const projectSelectionRequired = /No active (organization|project)/i.test(authErrorMessage ?? "") && projects.length > 0;
|
|
26847
26918
|
useEffect3(() => {
|
|
@@ -27093,31 +27164,31 @@ function HomeView({ apiUrl, notice, returnToAgent }) {
|
|
|
27093
27164
|
(section) => {
|
|
27094
27165
|
if (section === "agents") {
|
|
27095
27166
|
setSection("agents");
|
|
27096
|
-
|
|
27097
|
-
|
|
27167
|
+
setShowArchivedSessions(false);
|
|
27168
|
+
setSelectedSessionIds(/* @__PURE__ */ new Set());
|
|
27098
27169
|
setPendingArchiveRunKey(null);
|
|
27099
|
-
|
|
27170
|
+
setPendingUnarchiveSessionKey(null);
|
|
27100
27171
|
setPendingStopRunKey(null);
|
|
27101
|
-
|
|
27102
|
-
|
|
27172
|
+
setSessionNotice(null);
|
|
27173
|
+
triggerSession.reset();
|
|
27103
27174
|
return;
|
|
27104
27175
|
}
|
|
27105
|
-
if (section === "
|
|
27176
|
+
if (section === "sessions") {
|
|
27106
27177
|
setRunScopeAgentName(null);
|
|
27107
|
-
|
|
27108
|
-
|
|
27109
|
-
|
|
27178
|
+
setSessionIndex(0);
|
|
27179
|
+
setShowArchivedSessions(false);
|
|
27180
|
+
setSelectedSessionIds(/* @__PURE__ */ new Set());
|
|
27110
27181
|
setPendingArchiveRunKey(null);
|
|
27111
|
-
|
|
27182
|
+
setPendingUnarchiveSessionKey(null);
|
|
27112
27183
|
setPendingStopRunKey(null);
|
|
27113
|
-
|
|
27114
|
-
setSection("
|
|
27115
|
-
|
|
27184
|
+
setSessionNotice(null);
|
|
27185
|
+
setSection("sessions");
|
|
27186
|
+
triggerSession.reset();
|
|
27116
27187
|
return;
|
|
27117
27188
|
}
|
|
27118
27189
|
setSection(section);
|
|
27119
27190
|
},
|
|
27120
|
-
[
|
|
27191
|
+
[triggerSession]
|
|
27121
27192
|
);
|
|
27122
27193
|
useEffect3(() => {
|
|
27123
27194
|
if (activeSection !== "serviceAccounts") {
|
|
@@ -27134,13 +27205,13 @@ function HomeView({ apiUrl, notice, returnToAgent }) {
|
|
|
27134
27205
|
}
|
|
27135
27206
|
}, [activeSection]);
|
|
27136
27207
|
useEffect3(() => {
|
|
27137
|
-
if (activeSection !== "
|
|
27138
|
-
|
|
27208
|
+
if (activeSection !== "sessions") {
|
|
27209
|
+
setSelectedSessionIds(/* @__PURE__ */ new Set());
|
|
27139
27210
|
setPendingArchiveRunKey(null);
|
|
27140
|
-
|
|
27211
|
+
setPendingUnarchiveSessionKey(null);
|
|
27141
27212
|
setPendingStopRunKey(null);
|
|
27142
|
-
|
|
27143
|
-
|
|
27213
|
+
setSessionNotice(null);
|
|
27214
|
+
setShowArchivedSessions(false);
|
|
27144
27215
|
}
|
|
27145
27216
|
}, [activeSection]);
|
|
27146
27217
|
useInput4((input, key) => {
|
|
@@ -27226,77 +27297,77 @@ function HomeView({ apiUrl, notice, returnToAgent }) {
|
|
|
27226
27297
|
}
|
|
27227
27298
|
if (key.return && selectedAgent) {
|
|
27228
27299
|
setRunScopeAgentName(selectedAgent.metadata.name);
|
|
27229
|
-
|
|
27230
|
-
|
|
27231
|
-
|
|
27300
|
+
setSessionIndex(0);
|
|
27301
|
+
setShowArchivedSessions(false);
|
|
27302
|
+
setSelectedSessionIds(/* @__PURE__ */ new Set());
|
|
27232
27303
|
setPendingArchiveRunKey(null);
|
|
27233
|
-
|
|
27304
|
+
setPendingUnarchiveSessionKey(null);
|
|
27234
27305
|
setPendingStopRunKey(null);
|
|
27235
|
-
|
|
27236
|
-
setSection("
|
|
27237
|
-
|
|
27306
|
+
setSessionNotice(null);
|
|
27307
|
+
setSection("sessions");
|
|
27308
|
+
triggerSession.reset();
|
|
27238
27309
|
return;
|
|
27239
27310
|
}
|
|
27240
27311
|
}
|
|
27241
|
-
if (activeSection === "
|
|
27312
|
+
if (activeSection === "sessions") {
|
|
27242
27313
|
if (key.escape) {
|
|
27243
27314
|
setSection("agents");
|
|
27244
|
-
|
|
27315
|
+
triggerSession.reset();
|
|
27245
27316
|
return;
|
|
27246
27317
|
}
|
|
27247
27318
|
if (input === "v") {
|
|
27248
|
-
|
|
27249
|
-
|
|
27250
|
-
|
|
27319
|
+
setShowArchivedSessions((value) => !value);
|
|
27320
|
+
setSessionIndex(0);
|
|
27321
|
+
setSelectedSessionIds(/* @__PURE__ */ new Set());
|
|
27251
27322
|
setPendingArchiveRunKey(null);
|
|
27252
|
-
|
|
27323
|
+
setPendingUnarchiveSessionKey(null);
|
|
27253
27324
|
setPendingStopRunKey(null);
|
|
27254
|
-
|
|
27255
|
-
|
|
27256
|
-
|
|
27257
|
-
|
|
27325
|
+
setSessionNotice(null);
|
|
27326
|
+
archiveSessions.reset();
|
|
27327
|
+
unarchiveSessions.reset();
|
|
27328
|
+
stopSessions.reset();
|
|
27258
27329
|
return;
|
|
27259
27330
|
}
|
|
27260
27331
|
if (input === " ") {
|
|
27261
27332
|
toggleSelectedRun();
|
|
27262
27333
|
return;
|
|
27263
27334
|
}
|
|
27264
|
-
if (input === "n" && scopedAgent && !
|
|
27335
|
+
if (input === "n" && scopedAgent && !showArchivedSessions) {
|
|
27265
27336
|
startRun();
|
|
27266
27337
|
return;
|
|
27267
27338
|
}
|
|
27268
|
-
if (input === "a" && !
|
|
27339
|
+
if (input === "a" && !showArchivedSessions) {
|
|
27269
27340
|
archiveSelectedRun();
|
|
27270
27341
|
return;
|
|
27271
27342
|
}
|
|
27272
|
-
if (input === "s" && !
|
|
27343
|
+
if (input === "s" && !showArchivedSessions) {
|
|
27273
27344
|
stopSelectedRuns();
|
|
27274
27345
|
return;
|
|
27275
27346
|
}
|
|
27276
|
-
if (input === "u" &&
|
|
27347
|
+
if (input === "u" && showArchivedSessions) {
|
|
27277
27348
|
unarchiveSelectedRun();
|
|
27278
27349
|
return;
|
|
27279
27350
|
}
|
|
27280
27351
|
if (key.upArrow) {
|
|
27281
27352
|
setPendingArchiveRunKey(null);
|
|
27282
|
-
|
|
27353
|
+
setPendingUnarchiveSessionKey(null);
|
|
27283
27354
|
setPendingStopRunKey(null);
|
|
27284
|
-
|
|
27355
|
+
setSessionIndex((i) => Math.max(0, i - 1));
|
|
27285
27356
|
return;
|
|
27286
27357
|
}
|
|
27287
27358
|
if (key.downArrow) {
|
|
27288
27359
|
setPendingArchiveRunKey(null);
|
|
27289
|
-
|
|
27360
|
+
setPendingUnarchiveSessionKey(null);
|
|
27290
27361
|
setPendingStopRunKey(null);
|
|
27291
|
-
|
|
27362
|
+
setSessionIndex((i) => clampListIndex(i + 1, visibleSessions.length));
|
|
27292
27363
|
return;
|
|
27293
27364
|
}
|
|
27294
|
-
if (key.return &&
|
|
27295
|
-
const
|
|
27365
|
+
if (key.return && visibleSessions[sessionIndex]) {
|
|
27366
|
+
const session = visibleSessions[sessionIndex];
|
|
27296
27367
|
exit({
|
|
27297
|
-
|
|
27298
|
-
agentName:
|
|
27299
|
-
workingDirectory:
|
|
27368
|
+
sessionId: session.id,
|
|
27369
|
+
agentName: session.snapshot.metadata.name,
|
|
27370
|
+
workingDirectory: session.snapshot.spec.workingDirectory
|
|
27300
27371
|
});
|
|
27301
27372
|
return;
|
|
27302
27373
|
}
|
|
@@ -27632,12 +27703,12 @@ function HomeView({ apiUrl, notice, returnToAgent }) {
|
|
|
27632
27703
|
case "connections":
|
|
27633
27704
|
sectionTitle = connectionMode === "providers" ? `Providers[${connectionProviderRowCount}]` : `Connections[${connectionRowCount}]`;
|
|
27634
27705
|
break;
|
|
27635
|
-
case "
|
|
27636
|
-
const selectedSuffix =
|
|
27706
|
+
case "sessions": {
|
|
27707
|
+
const selectedSuffix = markedSessionIds.length > 0 ? `, ${markedSessionIds.length} selected` : "";
|
|
27637
27708
|
if (scopedAgent) {
|
|
27638
|
-
sectionTitle =
|
|
27709
|
+
sectionTitle = showArchivedSessions ? `Agent Sessions[${scopedAgent.metadata.name}: ${visibleSessions.length} archived${selectedSuffix}]` : `Agent Sessions[${scopedAgent.metadata.name}: ${visibleSessions.length}${selectedSuffix}]`;
|
|
27639
27710
|
} else {
|
|
27640
|
-
sectionTitle =
|
|
27711
|
+
sectionTitle = showArchivedSessions ? `Sessions[${visibleSessions.length} archived${selectedSuffix}]` : `Sessions[${visibleSessions.length}${selectedSuffix}]`;
|
|
27641
27712
|
}
|
|
27642
27713
|
break;
|
|
27643
27714
|
}
|
|
@@ -27645,8 +27716,8 @@ function HomeView({ apiUrl, notice, returnToAgent }) {
|
|
|
27645
27716
|
if (inspectedResource) {
|
|
27646
27717
|
sectionTitle = `Inspect ${inspectedResource.kind}/${inspectedResource.name}`;
|
|
27647
27718
|
}
|
|
27648
|
-
const runError = errorMessage2(
|
|
27649
|
-
const isRunMutationPending =
|
|
27719
|
+
const runError = errorMessage2(triggerSession.error) ?? errorMessage2(archiveSessions.error) ?? errorMessage2(unarchiveSessions.error) ?? errorMessage2(stopSessions.error);
|
|
27720
|
+
const isRunMutationPending = triggerSession.isPending || archiveSessions.isPending || unarchiveSessions.isPending || stopSessions.isPending;
|
|
27650
27721
|
const isConnectionMutationPending = startConnection.isPending || allowConnection.isPending || removeConnection.isPending || createGithubSyncBinding.isPending;
|
|
27651
27722
|
const serviceAccountStatus = createServiceAccount2.error instanceof Error ? createServiceAccount2.error.message : rotateServiceAccount2.error instanceof Error ? rotateServiceAccount2.error.message : removeServiceAccount2.error instanceof Error ? removeServiceAccount2.error.message : serviceAccountNotice;
|
|
27652
27723
|
const isServiceAccountMutationPending = createServiceAccount2.isPending || rotateServiceAccount2.isPending || removeServiceAccount2.isPending;
|
|
@@ -27677,15 +27748,15 @@ function HomeView({ apiUrl, notice, returnToAgent }) {
|
|
|
27677
27748
|
Spinner,
|
|
27678
27749
|
{
|
|
27679
27750
|
label: runMutationStatusLabel({
|
|
27680
|
-
starting:
|
|
27681
|
-
archiving:
|
|
27682
|
-
stopping:
|
|
27751
|
+
starting: triggerSession.isPending,
|
|
27752
|
+
archiving: archiveSessions.isPending,
|
|
27753
|
+
stopping: stopSessions.isPending
|
|
27683
27754
|
})
|
|
27684
27755
|
}
|
|
27685
27756
|
)
|
|
27686
27757
|
}
|
|
27687
27758
|
),
|
|
27688
|
-
(
|
|
27759
|
+
(sessionNotice ?? notice) && /* @__PURE__ */ jsx14(KV, { label: "Notice", value: sessionNotice ?? notice })
|
|
27689
27760
|
] }),
|
|
27690
27761
|
/* @__PURE__ */ jsxs12(Box13, { gap: 3, flexShrink: 0, children: [
|
|
27691
27762
|
resourceColumns.map((col) => /* @__PURE__ */ jsx14(Box13, { flexDirection: "column", children: col.map(({ k, label, activeSection: p }) => /* @__PURE__ */ jsx14(
|
|
@@ -27765,12 +27836,12 @@ function HomeView({ apiUrl, notice, returnToAgent }) {
|
|
|
27765
27836
|
{ k: "space", label: "Select" },
|
|
27766
27837
|
{
|
|
27767
27838
|
k: "v",
|
|
27768
|
-
label:
|
|
27839
|
+
label: showArchivedSessions ? "Active" : "Archived"
|
|
27769
27840
|
},
|
|
27770
|
-
...
|
|
27841
|
+
...showArchivedSessions ? [{ k: "u", label: "Restore" }] : [
|
|
27771
27842
|
{ k: "a", label: "Archive" },
|
|
27772
27843
|
{ k: "s", label: "Stop" },
|
|
27773
|
-
...scopedAgent ? [{ k: "n", label: "New
|
|
27844
|
+
...scopedAgent ? [{ k: "n", label: "New session" }] : []
|
|
27774
27845
|
],
|
|
27775
27846
|
{ k: "esc", label: "Back" },
|
|
27776
27847
|
{ k: "q", label: "Quit" }
|
|
@@ -27916,13 +27987,13 @@ function HomeView({ apiUrl, notice, returnToAgent }) {
|
|
|
27916
27987
|
error: projectsErrorMessage
|
|
27917
27988
|
}
|
|
27918
27989
|
) : /* @__PURE__ */ jsx14(
|
|
27919
|
-
|
|
27990
|
+
SessionsView,
|
|
27920
27991
|
{
|
|
27921
27992
|
scopedAgent,
|
|
27922
27993
|
apiUrl,
|
|
27923
|
-
selectedIndex:
|
|
27924
|
-
showArchived:
|
|
27925
|
-
|
|
27994
|
+
selectedIndex: sessionIndex,
|
|
27995
|
+
showArchived: showArchivedSessions,
|
|
27996
|
+
selectedSessionIds
|
|
27926
27997
|
}
|
|
27927
27998
|
)
|
|
27928
27999
|
}
|
|
@@ -27948,24 +28019,24 @@ function HomeView({ apiUrl, notice, returnToAgent }) {
|
|
|
27948
28019
|
children: ` ${activeSection} `
|
|
27949
28020
|
}
|
|
27950
28021
|
),
|
|
27951
|
-
!inspectedResource && (activeSection === "agents" || activeSection === "
|
|
28022
|
+
!inspectedResource && (activeSection === "agents" || activeSection === "sessions") && /* @__PURE__ */ jsxs12(Fragment3, { children: [
|
|
27952
28023
|
/* @__PURE__ */ jsx14(
|
|
27953
28024
|
Text14,
|
|
27954
28025
|
{
|
|
27955
28026
|
backgroundColor: activeSection === "agents" ? "cyan" : void 0,
|
|
27956
28027
|
color: activeSection === "agents" ? "black" : void 0,
|
|
27957
|
-
dimColor: activeSection === "
|
|
28028
|
+
dimColor: activeSection === "sessions",
|
|
27958
28029
|
children: " agents "
|
|
27959
28030
|
}
|
|
27960
28031
|
),
|
|
27961
|
-
activeSection === "
|
|
28032
|
+
activeSection === "sessions" && scopedAgent ? /* @__PURE__ */ jsxs12(Fragment3, { children: [
|
|
27962
28033
|
/* @__PURE__ */ jsx14(Text14, { dimColor: true, children: "\u203A" }),
|
|
27963
28034
|
/* @__PURE__ */ jsx14(Text14, { dimColor: true, children: ` ${scopedAgent.metadata.name} ` }),
|
|
27964
28035
|
/* @__PURE__ */ jsx14(Text14, { dimColor: true, children: "\u203A" }),
|
|
27965
|
-
/* @__PURE__ */ jsx14(Text14, { backgroundColor: "cyan", color: "black", children: "
|
|
27966
|
-
] }) : activeSection === "
|
|
28036
|
+
/* @__PURE__ */ jsx14(Text14, { backgroundColor: "cyan", color: "black", children: " sessions " })
|
|
28037
|
+
] }) : activeSection === "sessions" ? /* @__PURE__ */ jsxs12(Fragment3, { children: [
|
|
27967
28038
|
/* @__PURE__ */ jsx14(Text14, { dimColor: true, children: "\u203A" }),
|
|
27968
|
-
/* @__PURE__ */ jsx14(Text14, { backgroundColor: "cyan", color: "black", children: "
|
|
28039
|
+
/* @__PURE__ */ jsx14(Text14, { backgroundColor: "cyan", color: "black", children: " sessions " })
|
|
27969
28040
|
] }) : null
|
|
27970
28041
|
] })
|
|
27971
28042
|
] })
|
|
@@ -28008,27 +28079,27 @@ function chunkActionKeys(keys, size) {
|
|
|
28008
28079
|
}
|
|
28009
28080
|
return chunks;
|
|
28010
28081
|
}
|
|
28011
|
-
function
|
|
28012
|
-
return
|
|
28082
|
+
function selectedSessionIdsForVisibleRuns(sessions, selectedSessionIds) {
|
|
28083
|
+
return sessions.filter((session) => selectedSessionIds.has(session.id)).map((session) => session.id);
|
|
28013
28084
|
}
|
|
28014
|
-
function
|
|
28015
|
-
return input.
|
|
28085
|
+
function sessionIdsForArchiveAction(input) {
|
|
28086
|
+
return input.markedSessionIds.length > 0 ? input.markedSessionIds : input.selectedSession ? [input.selectedSession.id] : [];
|
|
28016
28087
|
}
|
|
28017
|
-
function partitionRunsForStop(
|
|
28018
|
-
const
|
|
28019
|
-
const
|
|
28020
|
-
for (const
|
|
28021
|
-
const
|
|
28022
|
-
if (
|
|
28023
|
-
|
|
28088
|
+
function partitionRunsForStop(sessionIds, runsById) {
|
|
28089
|
+
const stoppableSessionIds = [];
|
|
28090
|
+
const skippedSessionIds = [];
|
|
28091
|
+
for (const sessionId of sessionIds) {
|
|
28092
|
+
const session = runsById.get(sessionId);
|
|
28093
|
+
if (session && isSessionTerminalStatus(session.status)) {
|
|
28094
|
+
skippedSessionIds.push(sessionId);
|
|
28024
28095
|
} else {
|
|
28025
|
-
|
|
28096
|
+
stoppableSessionIds.push(sessionId);
|
|
28026
28097
|
}
|
|
28027
28098
|
}
|
|
28028
|
-
return {
|
|
28099
|
+
return { stoppableSessionIds, skippedSessionIds };
|
|
28029
28100
|
}
|
|
28030
|
-
function stopTargetLabel(
|
|
28031
|
-
return bulk ? pluralizeRunCount(
|
|
28101
|
+
function stopTargetLabel(sessionIds, bulk) {
|
|
28102
|
+
return bulk ? pluralizeRunCount(sessionIds.length) : `session ${shortSessionId2(sessionIds[0] ?? "")}`;
|
|
28032
28103
|
}
|
|
28033
28104
|
function stopResultNotice(result, skippedCount) {
|
|
28034
28105
|
const parts = [`Stopped ${pluralizeRunCount(result.stopped.length)}`];
|
|
@@ -28046,23 +28117,23 @@ function runMutationStatusLabel(pending) {
|
|
|
28046
28117
|
if (pending.stopping) return "stopping\u2026";
|
|
28047
28118
|
return "restoring\u2026";
|
|
28048
28119
|
}
|
|
28049
|
-
function runArchiveActionKey(
|
|
28050
|
-
return
|
|
28120
|
+
function runArchiveActionKey(sessionIds) {
|
|
28121
|
+
return sessionIds.join("\0");
|
|
28051
28122
|
}
|
|
28052
|
-
function runActionTargetLabel(
|
|
28123
|
+
function runActionTargetLabel(sessionIds, markedRunCount) {
|
|
28053
28124
|
if (markedRunCount > 0) {
|
|
28054
|
-
return `${markedRunCount} selected ${markedRunCount === 1 ? "
|
|
28125
|
+
return `${markedRunCount} selected ${markedRunCount === 1 ? "session" : "sessions"}`;
|
|
28055
28126
|
}
|
|
28056
|
-
return `
|
|
28127
|
+
return `session ${shortSessionId2(sessionIds[0] ?? "")}`;
|
|
28057
28128
|
}
|
|
28058
28129
|
function pluralizeRunCount(count) {
|
|
28059
|
-
return `${count} ${count === 1 ? "
|
|
28130
|
+
return `${count} ${count === 1 ? "session" : "sessions"}`;
|
|
28060
28131
|
}
|
|
28061
28132
|
function errorMessage2(error51) {
|
|
28062
28133
|
if (error51 instanceof Error) return error51.message;
|
|
28063
28134
|
return error51 ? String(error51) : null;
|
|
28064
28135
|
}
|
|
28065
|
-
function
|
|
28136
|
+
function shortSessionId2(id) {
|
|
28066
28137
|
const tail = id.split("-").pop();
|
|
28067
28138
|
return tail ? tail.slice(0, 12) : id.slice(0, 12);
|
|
28068
28139
|
}
|
|
@@ -28171,7 +28242,7 @@ var init_HomeView = __esm({
|
|
|
28171
28242
|
init_ConnectionsView();
|
|
28172
28243
|
init_ProjectsView();
|
|
28173
28244
|
init_ResourceViews();
|
|
28174
|
-
|
|
28245
|
+
init_SessionsView();
|
|
28175
28246
|
init_SpecInspector();
|
|
28176
28247
|
init_queries();
|
|
28177
28248
|
init_string();
|
|
@@ -28179,7 +28250,7 @@ var init_HomeView = __esm({
|
|
|
28179
28250
|
CONNECTION_REFRESH_TIMEOUT_MS = 9e4;
|
|
28180
28251
|
DASHBOARD_NAV_ITEMS = [
|
|
28181
28252
|
resourceNavItem({ k: "1", section: "agents" }),
|
|
28182
|
-
{ k: "2", label: "
|
|
28253
|
+
{ k: "2", label: "Sessions", activeSection: "sessions" },
|
|
28183
28254
|
resourceNavItem({ k: "3", section: "environments" }),
|
|
28184
28255
|
resourceNavItem({ k: "4", section: "identities" }),
|
|
28185
28256
|
{ k: "5", label: "Projects", activeSection: "projects" },
|
|
@@ -28398,7 +28469,7 @@ async function launch(opts) {
|
|
|
28398
28469
|
const { waitUntilExit: waitConv } = render(
|
|
28399
28470
|
providers(
|
|
28400
28471
|
React.createElement(ConversationView, {
|
|
28401
|
-
|
|
28472
|
+
sessionId: selection.sessionId,
|
|
28402
28473
|
agentName: selection.agentName,
|
|
28403
28474
|
workingDirectory: selection.workingDirectory,
|
|
28404
28475
|
apiUrl
|
|
@@ -28537,7 +28608,7 @@ function logout(context) {
|
|
|
28537
28608
|
function listAccounts(context) {
|
|
28538
28609
|
const profiles = listProfiles(context.configPath);
|
|
28539
28610
|
if (profiles.length === 0) {
|
|
28540
|
-
throw new Error("No stored accounts.
|
|
28611
|
+
throw new Error("No stored accounts. Session `auto auth login` first.");
|
|
28541
28612
|
}
|
|
28542
28613
|
for (const profile of profiles) {
|
|
28543
28614
|
context.writeOutput(
|
|
@@ -28561,7 +28632,7 @@ function switchAccount(context, accountRef, options = {}) {
|
|
|
28561
28632
|
}
|
|
28562
28633
|
const profiles = listProfiles(context.configPath);
|
|
28563
28634
|
if (profiles.length === 0) {
|
|
28564
|
-
throw new Error("No stored accounts.
|
|
28635
|
+
throw new Error("No stored accounts. Session `auto auth login` first.");
|
|
28565
28636
|
}
|
|
28566
28637
|
const byName = profiles.find((profile) => profile.name === accountRef);
|
|
28567
28638
|
const matches = byName ? [byName] : profiles.filter(
|
|
@@ -28569,7 +28640,7 @@ function switchAccount(context, accountRef, options = {}) {
|
|
|
28569
28640
|
);
|
|
28570
28641
|
if (matches.length === 0) {
|
|
28571
28642
|
throw new Error(
|
|
28572
|
-
`No stored account for ${accountRef}.
|
|
28643
|
+
`No stored account for ${accountRef}. Session \`auto auth login\` to add it.`
|
|
28573
28644
|
);
|
|
28574
28645
|
}
|
|
28575
28646
|
const active = readConfig(context.configPath);
|
|
@@ -28745,8 +28816,8 @@ function actorLabel(whoami) {
|
|
|
28745
28816
|
return "user";
|
|
28746
28817
|
case "provider_grant":
|
|
28747
28818
|
return "provider_grant";
|
|
28748
|
-
case "
|
|
28749
|
-
return "
|
|
28819
|
+
case "session":
|
|
28820
|
+
return "session";
|
|
28750
28821
|
case "system":
|
|
28751
28822
|
return "system";
|
|
28752
28823
|
}
|
|
@@ -28963,8 +29034,8 @@ async function readStream(stream) {
|
|
|
28963
29034
|
// ../../packages/protocol/src/index.ts
|
|
28964
29035
|
init_zod();
|
|
28965
29036
|
var OpaqueIdSchema2 = external_exports.string().trim().min(1);
|
|
28966
|
-
var
|
|
28967
|
-
var
|
|
29037
|
+
var SessionIdSchema2 = OpaqueIdSchema2.brand();
|
|
29038
|
+
var SessionCommandIdSchema2 = OpaqueIdSchema2.brand();
|
|
28968
29039
|
var RuntimeIdSchema2 = OpaqueIdSchema2.brand();
|
|
28969
29040
|
var RuntimeBridgeLeaseIdSchema2 = OpaqueIdSchema2.brand();
|
|
28970
29041
|
var JsonValueSchema2 = external_exports.lazy(
|
|
@@ -28977,7 +29048,7 @@ var JsonValueSchema2 = external_exports.lazy(
|
|
|
28977
29048
|
external_exports.record(external_exports.string(), JsonValueSchema2)
|
|
28978
29049
|
])
|
|
28979
29050
|
);
|
|
28980
|
-
var
|
|
29051
|
+
var SessionCommandKindSchema2 = external_exports.enum([
|
|
28981
29052
|
"message",
|
|
28982
29053
|
"answer",
|
|
28983
29054
|
"pause",
|
|
@@ -29074,8 +29145,8 @@ var RuntimeBridgeBootstrapPlaintextSchema = external_exports.object({
|
|
|
29074
29145
|
version: external_exports.literal(1),
|
|
29075
29146
|
outputSeqStart: external_exports.number().int().nonnegative(),
|
|
29076
29147
|
claude: AgentBridgeClaudeConfigSchema,
|
|
29077
|
-
// Endpoint +
|
|
29078
|
-
// the
|
|
29148
|
+
// Endpoint + session token for the git credential broker. Present only when
|
|
29149
|
+
// the session has GitHub App git mounts; rides the encrypted bootstrap so the
|
|
29079
29150
|
// token lives in agent-bridge memory, never on disk.
|
|
29080
29151
|
gitCredentials: external_exports.object({
|
|
29081
29152
|
url: external_exports.string().trim().min(1),
|
|
@@ -29090,7 +29161,7 @@ var RuntimeBridgeEncryptedBootstrapSchema = external_exports.object({
|
|
|
29090
29161
|
salt: external_exports.string().trim().min(1)
|
|
29091
29162
|
});
|
|
29092
29163
|
var RuntimeBridgeBootstrapEnvelopeSchema = external_exports.object({
|
|
29093
|
-
|
|
29164
|
+
sessionId: SessionIdSchema2,
|
|
29094
29165
|
runtimeId: RuntimeIdSchema2,
|
|
29095
29166
|
bridgeLeaseId: RuntimeBridgeLeaseIdSchema2,
|
|
29096
29167
|
bootstrap: RuntimeBridgeEncryptedBootstrapSchema
|
|
@@ -29111,18 +29182,18 @@ var RuntimeBridgeBootstrapAckSchema = external_exports.object({
|
|
|
29111
29182
|
ignoredBootstrapKeys: external_exports.array(external_exports.string().trim().min(1)).optional()
|
|
29112
29183
|
});
|
|
29113
29184
|
var RuntimeBridgeConnectedPayloadSchema = external_exports.object({
|
|
29114
|
-
|
|
29185
|
+
sessionId: SessionIdSchema2,
|
|
29115
29186
|
runtimeId: RuntimeIdSchema2,
|
|
29116
29187
|
bridgeLeaseId: RuntimeBridgeLeaseIdSchema2
|
|
29117
29188
|
});
|
|
29118
29189
|
var RuntimeBridgeCommandDeliverySchema = external_exports.object({
|
|
29119
29190
|
type: external_exports.literal("command.delivery"),
|
|
29120
29191
|
deliveryId: external_exports.string().trim().min(1),
|
|
29121
|
-
commandId:
|
|
29122
|
-
|
|
29192
|
+
commandId: SessionCommandIdSchema2,
|
|
29193
|
+
sessionId: SessionIdSchema2,
|
|
29123
29194
|
runtimeId: RuntimeIdSchema2,
|
|
29124
29195
|
bridgeLeaseId: RuntimeBridgeLeaseIdSchema2,
|
|
29125
|
-
kind:
|
|
29196
|
+
kind: SessionCommandKindSchema2,
|
|
29126
29197
|
payload: JsonValueSchema2,
|
|
29127
29198
|
attempt: external_exports.number().int().nonnegative(),
|
|
29128
29199
|
createdAt: external_exports.string().datetime()
|
|
@@ -29141,8 +29212,8 @@ var RuntimeBridgeCommandAckStatusSchema = external_exports.enum([
|
|
|
29141
29212
|
var RuntimeBridgeCommandAckSchema = external_exports.object({
|
|
29142
29213
|
type: external_exports.literal("command.ack"),
|
|
29143
29214
|
deliveryId: external_exports.string().trim().min(1),
|
|
29144
|
-
commandId:
|
|
29145
|
-
|
|
29215
|
+
commandId: SessionCommandIdSchema2,
|
|
29216
|
+
sessionId: SessionIdSchema2,
|
|
29146
29217
|
runtimeId: RuntimeIdSchema2,
|
|
29147
29218
|
bridgeLeaseId: RuntimeBridgeLeaseIdSchema2,
|
|
29148
29219
|
status: RuntimeBridgeCommandAckStatusSchema,
|
|
@@ -29153,13 +29224,13 @@ var RuntimeBridgeCommandAckSchema = external_exports.object({
|
|
|
29153
29224
|
var RuntimeBridgeCommandDeliveryAcceptedSchema = external_exports.object({
|
|
29154
29225
|
type: external_exports.literal("command.delivery.accepted"),
|
|
29155
29226
|
deliveryId: external_exports.string().trim().min(1),
|
|
29156
|
-
commandId:
|
|
29227
|
+
commandId: SessionCommandIdSchema2,
|
|
29157
29228
|
result: external_exports.enum(["injected", "duplicate"]),
|
|
29158
29229
|
at: external_exports.string().datetime()
|
|
29159
29230
|
}).strict();
|
|
29160
29231
|
var RuntimeBridgeOutputEntryEnvelopeSchema = external_exports.object({
|
|
29161
29232
|
type: external_exports.literal("conversation.entry"),
|
|
29162
|
-
|
|
29233
|
+
sessionId: SessionIdSchema2,
|
|
29163
29234
|
runtimeId: RuntimeIdSchema2,
|
|
29164
29235
|
bridgeLeaseId: RuntimeBridgeLeaseIdSchema2,
|
|
29165
29236
|
outputSeq: external_exports.number().int().positive(),
|
|
@@ -29170,11 +29241,11 @@ var RuntimeBridgeOutputEntryEnvelopeSchema = external_exports.object({
|
|
|
29170
29241
|
content: ConversationEntryContentSchema2,
|
|
29171
29242
|
createdAt: external_exports.string().datetime(),
|
|
29172
29243
|
completedAt: external_exports.string().datetime().nullable(),
|
|
29173
|
-
|
|
29244
|
+
sessionStatusAfter: external_exports.enum(["awaiting", "failed"]).optional()
|
|
29174
29245
|
}).strict();
|
|
29175
29246
|
var RuntimeBridgeOutputDeltaEnvelopeSchema = external_exports.object({
|
|
29176
29247
|
type: external_exports.literal("conversation.delta"),
|
|
29177
|
-
|
|
29248
|
+
sessionId: SessionIdSchema2,
|
|
29178
29249
|
runtimeId: RuntimeIdSchema2,
|
|
29179
29250
|
bridgeLeaseId: RuntimeBridgeLeaseIdSchema2,
|
|
29180
29251
|
outputSeq: external_exports.number().int().positive(),
|
|
@@ -29191,7 +29262,7 @@ var RuntimeBridgeOutputEnvelopeSchema = external_exports.discriminatedUnion("typ
|
|
|
29191
29262
|
]);
|
|
29192
29263
|
var RuntimeBridgeOutputAckSchema = external_exports.object({
|
|
29193
29264
|
type: external_exports.literal("runtime.output.ack"),
|
|
29194
|
-
|
|
29265
|
+
sessionId: SessionIdSchema2,
|
|
29195
29266
|
runtimeId: RuntimeIdSchema2,
|
|
29196
29267
|
bridgeLeaseId: RuntimeBridgeLeaseIdSchema2,
|
|
29197
29268
|
outputSeq: external_exports.number().int().positive(),
|
|
@@ -29210,7 +29281,7 @@ function commandAck(input) {
|
|
|
29210
29281
|
type: "command.ack",
|
|
29211
29282
|
deliveryId: input.delivery.deliveryId,
|
|
29212
29283
|
commandId: input.delivery.commandId,
|
|
29213
|
-
|
|
29284
|
+
sessionId: input.delivery.sessionId,
|
|
29214
29285
|
runtimeId: input.delivery.runtimeId,
|
|
29215
29286
|
bridgeLeaseId: input.delivery.bridgeLeaseId,
|
|
29216
29287
|
status: input.status,
|
|
@@ -29244,7 +29315,7 @@ function decryptRuntimeBridgeBootstrap(input) {
|
|
|
29244
29315
|
decipher.setAAD(
|
|
29245
29316
|
bootstrapAdditionalData({
|
|
29246
29317
|
accessToken: input.accessToken,
|
|
29247
|
-
|
|
29318
|
+
sessionId: envelope.sessionId,
|
|
29248
29319
|
runtimeId: envelope.runtimeId,
|
|
29249
29320
|
bridgeLeaseId: envelope.bridgeLeaseId
|
|
29250
29321
|
})
|
|
@@ -29278,7 +29349,7 @@ function deriveBootstrapKey(accessToken, salt) {
|
|
|
29278
29349
|
}
|
|
29279
29350
|
function bootstrapAdditionalData(input) {
|
|
29280
29351
|
return Buffer.from(
|
|
29281
|
-
`${input.
|
|
29352
|
+
`${input.sessionId}:${input.runtimeId}:${input.bridgeLeaseId}:v1`,
|
|
29282
29353
|
"utf8"
|
|
29283
29354
|
);
|
|
29284
29355
|
}
|
|
@@ -29326,7 +29397,7 @@ async function runAgentBridgeSocket(options) {
|
|
|
29326
29397
|
});
|
|
29327
29398
|
socket.on(
|
|
29328
29399
|
RUNTIME_BRIDGE_BOOTSTRAP_EVENT,
|
|
29329
|
-
|
|
29400
|
+
createSessiontimeBridgeBootstrapListener({
|
|
29330
29401
|
token: options.token,
|
|
29331
29402
|
onBootstrap: options.onBootstrap,
|
|
29332
29403
|
createHandler: (bootstrap) => options.createHandler({
|
|
@@ -29361,7 +29432,7 @@ async function runAgentBridgeSocket(options) {
|
|
|
29361
29432
|
reconnectLoop.stop();
|
|
29362
29433
|
handler.setContext(context);
|
|
29363
29434
|
options.writeOutput?.(
|
|
29364
|
-
`agent_bridge_connected
|
|
29435
|
+
`agent_bridge_connected session_id=${context.sessionId} runtime_id=${context.runtimeId} bridge_lease_id=${context.bridgeLeaseId}`
|
|
29365
29436
|
);
|
|
29366
29437
|
void handler.replayPendingOutputs().catch((error51) => {
|
|
29367
29438
|
options.writeOutput?.(
|
|
@@ -29406,7 +29477,7 @@ async function runAgentBridgeSocket(options) {
|
|
|
29406
29477
|
});
|
|
29407
29478
|
});
|
|
29408
29479
|
}
|
|
29409
|
-
function
|
|
29480
|
+
function createSessiontimeBridgeBootstrapListener(input) {
|
|
29410
29481
|
return async (rawEnvelope, ack) => {
|
|
29411
29482
|
const bootstrapStartedAt = Date.now();
|
|
29412
29483
|
input.writeOutput?.(
|
|
@@ -29415,7 +29486,7 @@ function createRuntimeBridgeBootstrapListener(input) {
|
|
|
29415
29486
|
try {
|
|
29416
29487
|
const envelope = RuntimeBridgeBootstrapEnvelopeSchema.parse(rawEnvelope);
|
|
29417
29488
|
const context = RuntimeBridgeConnectedPayloadSchema.parse({
|
|
29418
|
-
|
|
29489
|
+
sessionId: envelope.sessionId,
|
|
29419
29490
|
runtimeId: envelope.runtimeId,
|
|
29420
29491
|
bridgeLeaseId: envelope.bridgeLeaseId
|
|
29421
29492
|
});
|
|
@@ -29628,7 +29699,7 @@ function buildOutputEnvelope(context, outputSeq, projection) {
|
|
|
29628
29699
|
const { delta } = projection;
|
|
29629
29700
|
return RuntimeBridgeOutputEnvelopeSchema.parse({
|
|
29630
29701
|
type: "conversation.delta",
|
|
29631
|
-
|
|
29702
|
+
sessionId: context.sessionId,
|
|
29632
29703
|
runtimeId: context.runtimeId,
|
|
29633
29704
|
bridgeLeaseId: context.bridgeLeaseId,
|
|
29634
29705
|
outputSeq,
|
|
@@ -29644,7 +29715,7 @@ function buildOutputEnvelope(context, outputSeq, projection) {
|
|
|
29644
29715
|
const createdAt = now2();
|
|
29645
29716
|
return RuntimeBridgeOutputEnvelopeSchema.parse({
|
|
29646
29717
|
type: "conversation.entry",
|
|
29647
|
-
|
|
29718
|
+
sessionId: context.sessionId,
|
|
29648
29719
|
runtimeId: context.runtimeId,
|
|
29649
29720
|
bridgeLeaseId: context.bridgeLeaseId,
|
|
29650
29721
|
outputSeq,
|
|
@@ -29655,7 +29726,7 @@ function buildOutputEnvelope(context, outputSeq, projection) {
|
|
|
29655
29726
|
content: entry.content,
|
|
29656
29727
|
createdAt,
|
|
29657
29728
|
completedAt: entry.status === "in_progress" ? null : createdAt,
|
|
29658
|
-
...entry.
|
|
29729
|
+
...entry.sessionStatusAfter ? { sessionStatusAfter: entry.sessionStatusAfter } : {}
|
|
29659
29730
|
});
|
|
29660
29731
|
}
|
|
29661
29732
|
function isSuccessfulOutputAck(ack) {
|
|
@@ -29690,8 +29761,8 @@ var ClaudeCodeProjector = class {
|
|
|
29690
29761
|
(entry) => ({
|
|
29691
29762
|
type: "entry",
|
|
29692
29763
|
// A question entry means the SDK is parked on AskUserQuestion waiting
|
|
29693
|
-
// for an operator answer, so the
|
|
29694
|
-
entry: entry.kind === "question" ? { ...entry,
|
|
29764
|
+
// for an operator answer, so the session transitions to awaiting input.
|
|
29765
|
+
entry: entry.kind === "question" ? { ...entry, sessionStatusAfter: "awaiting" } : entry
|
|
29695
29766
|
})
|
|
29696
29767
|
);
|
|
29697
29768
|
if (parsed.result) {
|
|
@@ -29707,7 +29778,7 @@ function projectClaudeCodeResult(result) {
|
|
|
29707
29778
|
role: "system",
|
|
29708
29779
|
kind: "status",
|
|
29709
29780
|
status: result.isError ? "failed" : "completed",
|
|
29710
|
-
|
|
29781
|
+
sessionStatusAfter: result.isError ? "failed" : "awaiting",
|
|
29711
29782
|
content: {
|
|
29712
29783
|
parts: [
|
|
29713
29784
|
{
|
|
@@ -29760,12 +29831,12 @@ var AGENT_BRIDGE_RUNTIME_DIR = "/tmp/auto-bridge-runtime";
|
|
|
29760
29831
|
var CLAUDE_SESSION_RESUME_PATH = `${AGENT_BRIDGE_RUNTIME_DIR}/claude-session-id`;
|
|
29761
29832
|
function fileClaudeSessionResumeStore(path2 = CLAUDE_SESSION_RESUME_PATH) {
|
|
29762
29833
|
return {
|
|
29763
|
-
read(
|
|
29834
|
+
read(sessionId) {
|
|
29764
29835
|
if (!existsSync2(path2)) {
|
|
29765
29836
|
return null;
|
|
29766
29837
|
}
|
|
29767
29838
|
const record2 = parseResumeRecord(readFileSync2(path2, "utf8"));
|
|
29768
|
-
if (!record2 || record2.
|
|
29839
|
+
if (!record2 || record2.sessionId !== sessionId) {
|
|
29769
29840
|
return null;
|
|
29770
29841
|
}
|
|
29771
29842
|
return record2.agentId;
|
|
@@ -29780,8 +29851,8 @@ function fileClaudeSessionResumeStore(path2 = CLAUDE_SESSION_RESUME_PATH) {
|
|
|
29780
29851
|
function parseResumeRecord(raw) {
|
|
29781
29852
|
try {
|
|
29782
29853
|
const value = JSON.parse(raw);
|
|
29783
|
-
if (value !== null && typeof value === "object" && "
|
|
29784
|
-
return {
|
|
29854
|
+
if (value !== null && typeof value === "object" && "sessionId" in value && "agentId" in value && typeof value.sessionId === "string" && typeof value.agentId === "string" && value.agentId.length > 0) {
|
|
29855
|
+
return { sessionId: value.sessionId, agentId: value.agentId };
|
|
29785
29856
|
}
|
|
29786
29857
|
return null;
|
|
29787
29858
|
} catch {
|
|
@@ -29968,7 +30039,7 @@ function withClaudeStderrDiagnosticsPointer(error51, capturedStderr) {
|
|
|
29968
30039
|
return base;
|
|
29969
30040
|
}
|
|
29970
30041
|
return new Error(
|
|
29971
|
-
`${base.message} (recent Claude stderr captured in
|
|
30042
|
+
`${base.message} (recent Claude stderr captured in session diagnostics)`,
|
|
29972
30043
|
{ cause: base }
|
|
29973
30044
|
);
|
|
29974
30045
|
}
|
|
@@ -30351,7 +30422,7 @@ var ClaudeCodeCommandHandler = class {
|
|
|
30351
30422
|
const delivery = RuntimeBridgeCommandDeliverySchema.parse(rawDelivery);
|
|
30352
30423
|
const socketId = this.input.socketId?.();
|
|
30353
30424
|
const activeContext = this.context;
|
|
30354
|
-
if (!activeContext || delivery.
|
|
30425
|
+
if (!activeContext || delivery.sessionId !== activeContext.sessionId || delivery.runtimeId !== activeContext.runtimeId || delivery.bridgeLeaseId !== activeContext.bridgeLeaseId) {
|
|
30355
30426
|
return commandAck({
|
|
30356
30427
|
delivery,
|
|
30357
30428
|
socketId,
|
|
@@ -30502,7 +30573,7 @@ var ClaudeCodeCommandHandler = class {
|
|
|
30502
30573
|
}
|
|
30503
30574
|
this.pendingQuestions.clear();
|
|
30504
30575
|
}
|
|
30505
|
-
// Permission callback for the Claude Agent SDK session. The
|
|
30576
|
+
// Permission callback for the Claude Agent SDK session. The sessions with
|
|
30506
30577
|
// bypassPermissions, so regular tools are auto-approved and only the
|
|
30507
30578
|
// AskUserQuestion tool reaches this callback for a real decision: it parks
|
|
30508
30579
|
// the SDK on a promise that an `answer` bridge command later resolves.
|
|
@@ -30591,7 +30662,7 @@ var ClaudeCodeCommandHandler = class {
|
|
|
30591
30662
|
}
|
|
30592
30663
|
try {
|
|
30593
30664
|
store.write({
|
|
30594
|
-
|
|
30665
|
+
sessionId: activeContext.sessionId,
|
|
30595
30666
|
agentId: message.session_id
|
|
30596
30667
|
});
|
|
30597
30668
|
this.persistedAgentId = message.session_id;
|
|
@@ -30608,7 +30679,7 @@ var ClaudeCodeCommandHandler = class {
|
|
|
30608
30679
|
return void 0;
|
|
30609
30680
|
}
|
|
30610
30681
|
try {
|
|
30611
|
-
return store.read(activeContext.
|
|
30682
|
+
return store.read(activeContext.sessionId) ?? void 0;
|
|
30612
30683
|
} catch (error51) {
|
|
30613
30684
|
this.input.writeOutput?.(
|
|
30614
30685
|
`agent_bridge_session_id_read_failed error=${error51 instanceof Error ? error51.message : String(error51)}`
|
|
@@ -30711,13 +30782,15 @@ function requiredEnv(env, key) {
|
|
|
30711
30782
|
|
|
30712
30783
|
// src/commands/agent-bridge/commands.ts
|
|
30713
30784
|
function registerAgentBridgeCommands(program, context) {
|
|
30714
|
-
const agentBridge = program.command("agent-bridge", { hidden: true }).description("
|
|
30785
|
+
const agentBridge = program.command("agent-bridge", { hidden: true }).description("Session the internal runtime bridge wrapper.").action(async () => {
|
|
30715
30786
|
await runAgentBridgeProcess({
|
|
30716
30787
|
env: context.env,
|
|
30717
30788
|
writeOutput: context.writeOutput
|
|
30718
30789
|
});
|
|
30719
30790
|
});
|
|
30720
|
-
agentBridge.command("git-credential [operation]").description(
|
|
30791
|
+
agentBridge.command("git-credential [operation]").description(
|
|
30792
|
+
"git credential helper backed by the session's broker endpoint."
|
|
30793
|
+
).option("--check", "Exit 0 when the helper is available.").allowUnknownOption(true).action(async (operation, options) => {
|
|
30721
30794
|
const exitCode = await runGitCredentialHelper({
|
|
30722
30795
|
args: [
|
|
30723
30796
|
...options.check ? ["--check"] : [],
|
|
@@ -30899,7 +30972,7 @@ async function connectAgentPresence2(input) {
|
|
|
30899
30972
|
}
|
|
30900
30973
|
if (!realized) {
|
|
30901
30974
|
throw new Error(
|
|
30902
|
-
telegram ? `Timed out waiting for the Telegram bot to be confirmed under ${pending.workspace}. Confirm the creation dialog in Telegram, then
|
|
30975
|
+
telegram ? `Timed out waiting for the Telegram bot to be confirmed under ${pending.workspace}. Confirm the creation dialog in Telegram, then rerun \`auto agents connect ${input.agent}\`.` : `Timed out waiting for the install in workspace ${pending.workspace}. Rerun \`auto agents connect ${input.agent}\` to retry.`
|
|
30903
30976
|
);
|
|
30904
30977
|
}
|
|
30905
30978
|
}
|
|
@@ -30917,9 +30990,9 @@ function staleScopesLine(agent, identity2) {
|
|
|
30917
30990
|
}
|
|
30918
30991
|
function manualGuidance(input) {
|
|
30919
30992
|
if (input.allTelegram) {
|
|
30920
|
-
return `Open each creation link and confirm the new bot in Telegram; Auto provisions it automatically.
|
|
30993
|
+
return `Open each creation link and confirm the new bot in Telegram; Auto provisions it automatically. Rerun \`auto agents connect ${input.agent}\` (or check presence) to see it realize.`;
|
|
30921
30994
|
}
|
|
30922
|
-
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.";
|
|
30995
|
+
return input.reconnect ? "Open each authorization URL to reinstall the dedicated agent app; the callback page confirms the refreshed tokens." : "Open each authorization URL to install the dedicated agent app, then re-run with no flags or check `agents connect` again.";
|
|
30923
30996
|
}
|
|
30924
30997
|
async function promptForIconUploads(input, options) {
|
|
30925
30998
|
const presence = await input.client.getAgentPresence(
|
|
@@ -30943,7 +31016,7 @@ async function promptForIconUploads(input, options) {
|
|
|
30943
31016
|
}
|
|
30944
31017
|
if (!canPrompt) {
|
|
30945
31018
|
input.writeOutput(
|
|
30946
|
-
`Then
|
|
31019
|
+
`Then rerun \`auto agents connect ${input.agent}\` interactively to record the upload.`
|
|
30947
31020
|
);
|
|
30948
31021
|
continue;
|
|
30949
31022
|
}
|
|
@@ -31058,10 +31131,10 @@ async function registerConfigTokenInteractively(input, options, refusal) {
|
|
|
31058
31131
|
);
|
|
31059
31132
|
}
|
|
31060
31133
|
|
|
31061
|
-
// src/commands/agents/
|
|
31134
|
+
// src/commands/agents/start.ts
|
|
31062
31135
|
init_conversation2();
|
|
31063
31136
|
|
|
31064
|
-
// src/commands/
|
|
31137
|
+
// src/commands/sessions/list.ts
|
|
31065
31138
|
async function handleRunsList(context, agentName, options = {}) {
|
|
31066
31139
|
const result = await fetchRuns(context, agentName, options);
|
|
31067
31140
|
context.io.writeResult(result, formatRunsText);
|
|
@@ -31075,32 +31148,32 @@ async function fetchRuns(context, agentName, options) {
|
|
|
31075
31148
|
since: options.since,
|
|
31076
31149
|
limit: options.limit
|
|
31077
31150
|
};
|
|
31078
|
-
const response = agentName ? await client.
|
|
31151
|
+
const response = agentName ? await client.listAgentSessions(agentName, clientOptions) : await client.listSessions(clientOptions);
|
|
31079
31152
|
return {
|
|
31080
31153
|
agent: agentName ?? null,
|
|
31081
|
-
|
|
31154
|
+
sessions: response.sessions,
|
|
31082
31155
|
includeArchived: Boolean(options.includeArchived)
|
|
31083
31156
|
};
|
|
31084
31157
|
}
|
|
31085
31158
|
function formatRunsText(result, writeLine, style) {
|
|
31086
|
-
if (result.
|
|
31159
|
+
if (result.sessions.length === 0) {
|
|
31087
31160
|
writeLine(
|
|
31088
31161
|
style.dim(
|
|
31089
|
-
result.agent ? `No
|
|
31162
|
+
result.agent ? `No sessions found for agent ${result.agent}.` : "No sessions found in the current project."
|
|
31090
31163
|
)
|
|
31091
31164
|
);
|
|
31092
31165
|
return;
|
|
31093
31166
|
}
|
|
31094
|
-
for (const
|
|
31095
|
-
const archived =
|
|
31167
|
+
for (const session of result.sessions) {
|
|
31168
|
+
const archived = session.archivedAt ? ` ${style.dim(`archived_at=${session.archivedAt}`)}` : "";
|
|
31096
31169
|
writeLine(
|
|
31097
|
-
`${style.id(
|
|
31098
|
-
|
|
31170
|
+
`${style.id(session.id)} ${styleSessionStatus(style, session.status)} ${style.dim(
|
|
31171
|
+
session.createdAt
|
|
31099
31172
|
)}${archived}`
|
|
31100
31173
|
);
|
|
31101
31174
|
}
|
|
31102
31175
|
}
|
|
31103
|
-
function
|
|
31176
|
+
function styleSessionStatus(style, status) {
|
|
31104
31177
|
switch (status) {
|
|
31105
31178
|
case "failed":
|
|
31106
31179
|
return style.error(status);
|
|
@@ -31116,29 +31189,29 @@ function styleRunStatus(style, status) {
|
|
|
31116
31189
|
}
|
|
31117
31190
|
}
|
|
31118
31191
|
|
|
31119
|
-
// src/commands/agents/
|
|
31120
|
-
async function
|
|
31192
|
+
// src/commands/agents/start.ts
|
|
31193
|
+
async function launchSession(input) {
|
|
31121
31194
|
const client = createContextApiClient(input.context);
|
|
31122
31195
|
const apiBaseUrl = apiUrlFromOptions(input.context, input.commandOptions);
|
|
31123
|
-
const created = await client.
|
|
31196
|
+
const created = await client.triggerSession(input.agentName, {
|
|
31124
31197
|
message: input.commandOptions.message,
|
|
31125
31198
|
apiBaseUrl
|
|
31126
31199
|
});
|
|
31127
31200
|
const style = input.context.io.style;
|
|
31128
31201
|
input.context.writeOutput(
|
|
31129
|
-
`${style.label("
|
|
31202
|
+
`${style.label("session_id")} ${style.id(created.session_id)}`
|
|
31130
31203
|
);
|
|
31131
31204
|
input.context.writeOutput(
|
|
31132
31205
|
`${style.label("workflow_id")} ${style.id(created.workflow_id)}`
|
|
31133
31206
|
);
|
|
31134
31207
|
input.context.writeOutput(
|
|
31135
|
-
`${style.label("status")} ${
|
|
31208
|
+
`${style.label("status")} ${styleSessionStatus(style, created.status)}`
|
|
31136
31209
|
);
|
|
31137
31210
|
if (input.commandOptions.attach) {
|
|
31138
31211
|
const writeConversationEvent = createConversationStreamWriter({
|
|
31139
31212
|
writeLine: input.context.writeOutput
|
|
31140
31213
|
});
|
|
31141
|
-
await client.
|
|
31214
|
+
await client.streamSessionConversation(created.session_id, {
|
|
31142
31215
|
apiBaseUrl,
|
|
31143
31216
|
onEvent: writeConversationEvent
|
|
31144
31217
|
});
|
|
@@ -31147,13 +31220,15 @@ async function launchRun(input) {
|
|
|
31147
31220
|
|
|
31148
31221
|
// src/commands/agents/commands.ts
|
|
31149
31222
|
function registerAgentCommands(program, context) {
|
|
31150
|
-
program.command("
|
|
31151
|
-
|
|
31152
|
-
|
|
31153
|
-
|
|
31154
|
-
|
|
31155
|
-
|
|
31156
|
-
|
|
31223
|
+
program.command("start").description("Launch an agent session on the Auto platform.").argument("<agent>", "agent name").option("-m, --message <message>", "initial message for the session").option("-a, --attach", "stream the session conversation after launch").option("--api-url <url>", "Auto API base URL").option("--api-base-url <url>", "Auto API base URL").action(
|
|
31224
|
+
async (agentName, commandOptions) => {
|
|
31225
|
+
await launchSession({
|
|
31226
|
+
agentName,
|
|
31227
|
+
commandOptions,
|
|
31228
|
+
context
|
|
31229
|
+
});
|
|
31230
|
+
}
|
|
31231
|
+
);
|
|
31157
31232
|
const agents = program.command("agents").description("Manage Agent resources.");
|
|
31158
31233
|
agents.command("render").description("Render a local Agent authoring file after imports/removals.").argument("<agent>", "agent name or path").option(
|
|
31159
31234
|
"--directory <directory>",
|
|
@@ -31194,11 +31269,9 @@ function registerAgentCommands(program, context) {
|
|
|
31194
31269
|
writeOutput: context.writeOutput
|
|
31195
31270
|
});
|
|
31196
31271
|
});
|
|
31197
|
-
agents.command("connect").description(
|
|
31198
|
-
"Connect an agent's provider presence (e.g. install its Slack agent app)."
|
|
31199
|
-
).argument("<agent>", "agent resource name").option("--manual", "print authorization URLs without opening a browser").option(
|
|
31272
|
+
agents.command("connect").description("Set up optional dedicated provider presence for an agent.").argument("<agent>", "agent resource name").option("--manual", "print authorization URLs without opening a browser").option(
|
|
31200
31273
|
"--reconnect",
|
|
31201
|
-
"
|
|
31274
|
+
"rerun the install for already-connected workspaces (repairs stranded bot tokens)"
|
|
31202
31275
|
).option("--api-url <url>", "Auto API base URL").option("--api-base-url <url>", "Auto API base URL").action(
|
|
31203
31276
|
async (agentName, commandOptions) => {
|
|
31204
31277
|
await connectAgentPresence2({
|
|
@@ -31212,16 +31285,6 @@ function registerAgentCommands(program, context) {
|
|
|
31212
31285
|
});
|
|
31213
31286
|
}
|
|
31214
31287
|
);
|
|
31215
|
-
program.command("run-and-attach").description("Launch an agent run and immediately stream its conversation.").argument("<agent>", "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 (agentName, commandOptions) => {
|
|
31216
|
-
await launchRun({
|
|
31217
|
-
agentName,
|
|
31218
|
-
commandOptions: {
|
|
31219
|
-
...commandOptions,
|
|
31220
|
-
attach: true
|
|
31221
|
-
},
|
|
31222
|
-
context
|
|
31223
|
-
});
|
|
31224
|
-
});
|
|
31225
31288
|
}
|
|
31226
31289
|
|
|
31227
31290
|
// src/commands/apply/commands.ts
|
|
@@ -31300,7 +31363,7 @@ async function confirmDestructiveAction(context, input) {
|
|
|
31300
31363
|
return;
|
|
31301
31364
|
}
|
|
31302
31365
|
if (!context.io.canPrompt()) {
|
|
31303
|
-
throw new Error(`${input.message}
|
|
31366
|
+
throw new Error(`${input.message} Rerun with --yes to confirm.`);
|
|
31304
31367
|
}
|
|
31305
31368
|
const readline = createCliReadline({
|
|
31306
31369
|
stdin: context.stdin,
|
|
@@ -31323,7 +31386,7 @@ async function requireProjectScope(input) {
|
|
|
31323
31386
|
return resolved;
|
|
31324
31387
|
}
|
|
31325
31388
|
throw new Error(
|
|
31326
|
-
`No project selected.
|
|
31389
|
+
`No project selected. Session \`auto projects use <project>\` or pass ${input.explicitHint}.`
|
|
31327
31390
|
);
|
|
31328
31391
|
}
|
|
31329
31392
|
async function resolveProjectScope(input) {
|
|
@@ -31387,7 +31450,7 @@ async function requireConnection(input) {
|
|
|
31387
31450
|
);
|
|
31388
31451
|
}
|
|
31389
31452
|
throw new Error(
|
|
31390
|
-
`No ${input.provider} connection found matching ${identifier}.
|
|
31453
|
+
`No ${input.provider} connection found matching ${identifier}. Session \`auto connections list\` to see available connections.`
|
|
31391
31454
|
);
|
|
31392
31455
|
}
|
|
31393
31456
|
if (matches.length > 1) {
|
|
@@ -31399,13 +31462,13 @@ async function requireConnection(input) {
|
|
|
31399
31462
|
}
|
|
31400
31463
|
if (grants.length === 0) {
|
|
31401
31464
|
throw new Error(
|
|
31402
|
-
`No ${input.provider} connections found.
|
|
31465
|
+
`No ${input.provider} connections found. Session \`auto connect ${input.provider}\` first.`
|
|
31403
31466
|
);
|
|
31404
31467
|
}
|
|
31405
31468
|
if (grants.length > 1) {
|
|
31406
31469
|
const names = grants.map((grant) => grant.name).join(", ");
|
|
31407
31470
|
throw new Error(
|
|
31408
|
-
`Multiple ${input.provider} connections found: ${names}.
|
|
31471
|
+
`Multiple ${input.provider} connections found: ${names}. Rerun with --connection <name>.`
|
|
31409
31472
|
);
|
|
31410
31473
|
}
|
|
31411
31474
|
return grants[0];
|
|
@@ -31508,7 +31571,7 @@ function staleGrantNotices(connections, style) {
|
|
|
31508
31571
|
return connections.flatMap(
|
|
31509
31572
|
(connection) => connection.grants.filter(stale).map(
|
|
31510
31573
|
(grant) => style.warn(
|
|
31511
|
-
`grant ${grant.name}: installed before scopes ${(grant.missingScopes ?? []).join(", ")} were added \u2014
|
|
31574
|
+
`grant ${grant.name}: installed before scopes ${(grant.missingScopes ?? []).join(", ")} were added \u2014 rerun \`auto connect ${connection.provider}\` to re-consent`
|
|
31512
31575
|
)
|
|
31513
31576
|
)
|
|
31514
31577
|
);
|
|
@@ -31671,7 +31734,7 @@ async function waitForNewGrant(input, knownGrantIds) {
|
|
|
31671
31734
|
}
|
|
31672
31735
|
}
|
|
31673
31736
|
throw new ConnectionWaitTimeoutError(
|
|
31674
|
-
`Timed out waiting for the ${input.provider} connection to complete. The authorization may still land (or may have re-authorized an existing connection); check \`auto connections list --provider ${input.provider}\`, or
|
|
31737
|
+
`Timed out waiting for the ${input.provider} connection to complete. The authorization may still land (or may have re-authorized an existing connection); check \`auto connections list --provider ${input.provider}\`, or rerun with --no-wait to skip waiting.`
|
|
31675
31738
|
);
|
|
31676
31739
|
}
|
|
31677
31740
|
|
|
@@ -31768,7 +31831,7 @@ async function selectGithubInstallation(input) {
|
|
|
31768
31831
|
);
|
|
31769
31832
|
if (!input.context.io.canPrompt()) {
|
|
31770
31833
|
input.context.writeOutput(
|
|
31771
|
-
"Multiple existing GitHub installations were found.
|
|
31834
|
+
"Multiple existing GitHub installations were found. Rerun with --installation <account-or-id> to use one, or continue with the install URL below."
|
|
31772
31835
|
);
|
|
31773
31836
|
return void 0;
|
|
31774
31837
|
}
|
|
@@ -32468,12 +32531,12 @@ var humanQuickstartText = `Get started with auto:
|
|
|
32468
32531
|
1. auto auth login sign in (device flow; account setup in browser)
|
|
32469
32532
|
2. auto connections list see available providers; auto connect <provider>
|
|
32470
32533
|
3. auto apply apply .auto/ resources to your project
|
|
32471
|
-
4. auto
|
|
32534
|
+
4. auto start <agent> launch an agent session; add --attach to follow it
|
|
32472
32535
|
|
|
32473
32536
|
Fastest path: paste this into a coding agent running in your repo
|
|
32474
32537
|
(Claude Code, Cursor, Codex):
|
|
32475
32538
|
|
|
32476
|
-
"
|
|
32539
|
+
"Session \`auto onboard --agent\` and follow the instructions it prints."
|
|
32477
32540
|
|
|
32478
32541
|
The agent walks you through setup end to end, studies your repo, and installs
|
|
32479
32542
|
a first workflow tailored to how your team works.
|
|
@@ -32482,7 +32545,7 @@ Docs and help: auto --help
|
|
|
32482
32545
|
`;
|
|
32483
32546
|
|
|
32484
32547
|
// src/commands/onboard/skill-content.generated.ts
|
|
32485
|
-
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/agents` directory, inline identities/environments, imports, and `auto apply` semantics. |\n| `docs/agents-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, environment fragments, and durable agent prompts. |\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, inline tools, and fragments) 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 agent files \u2014 an agent with the workflow's prompt, tools, inline identity, triggers, and any environment fragment it imports. 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 agent system prompt, the real initial 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 agent files, environment fragments, inline identity, tools, 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";
|
|
32548
|
+
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, sessions. Start here. |\n| `docs/resource-model.md` | The `.auto/agents` directory, inline identities/environments, imports, and `auto apply` semantics. |\n| `docs/agents-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, environment fragments, and durable agent prompts. |\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 sessions 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 session, tell the user up front roughly how long it takes and what \"normal\" looks like (\"the coder session 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 sessions list`, `auto sessions show`, `auto sessions conversation`, `auto apply --dry-run`) rather than asking the user to debug.\n- **Asynchronous means asynchronous.** Triggered sessions take time to spawn and act. Tell the user when a wait is expected, and tail session state rather than declaring failure early.\n- **Never fabricate success.** Verify each step actually worked (the apply plan, the trigger receipt, the session 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, inline tools, and fragments) 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 agent files \u2014 an agent with the workflow's prompt, tools, inline identity, triggers, and any environment fragment it imports. 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 session takes a minute or two to spawn; I'll tell you when it acts\" \u2014 and watch progress yourself with `auto sessions list` and `auto attach <session-id>` (live stream; `auto sessions conversation <session-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 session transcript via `auto sessions 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 agent system prompt, the real initial 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 agent files, environment fragments, inline identity, tools, 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 sessions 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";
|
|
32486
32549
|
|
|
32487
32550
|
// src/commands/onboard/commands.ts
|
|
32488
32551
|
function registerOnboardCommands(program, context) {
|
|
@@ -32846,25 +32909,342 @@ function memberLine2(member, style) {
|
|
|
32846
32909
|
].filter(Boolean).join(" ");
|
|
32847
32910
|
}
|
|
32848
32911
|
|
|
32849
|
-
// src/commands/
|
|
32912
|
+
// src/commands/secrets/actions.ts
|
|
32913
|
+
async function setSecret(input) {
|
|
32914
|
+
const value = await secretValue({
|
|
32915
|
+
options: input.commandOptions,
|
|
32916
|
+
env: input.context.env,
|
|
32917
|
+
stdin: input.context.stdin
|
|
32918
|
+
});
|
|
32919
|
+
const response = await input.client.setSecret(
|
|
32920
|
+
input.name,
|
|
32921
|
+
{ value },
|
|
32922
|
+
{
|
|
32923
|
+
projectId: await secretProjectId(input),
|
|
32924
|
+
apiBaseUrl: input.commandOptions.apiBaseUrl
|
|
32925
|
+
}
|
|
32926
|
+
);
|
|
32927
|
+
writeSetResponse(response, input);
|
|
32928
|
+
}
|
|
32929
|
+
async function listSecrets(input) {
|
|
32930
|
+
const response = await input.client.listSecrets({
|
|
32931
|
+
projectId: await secretProjectId(input),
|
|
32932
|
+
apiBaseUrl: input.commandOptions.apiBaseUrl
|
|
32933
|
+
});
|
|
32934
|
+
if (input.commandOptions.json) {
|
|
32935
|
+
input.context.writeOutput(JSON.stringify(response));
|
|
32936
|
+
return;
|
|
32937
|
+
}
|
|
32938
|
+
if (response.secrets.length === 0) {
|
|
32939
|
+
input.context.writeOutput("No secrets found.");
|
|
32940
|
+
return;
|
|
32941
|
+
}
|
|
32942
|
+
for (const secret of response.secrets) {
|
|
32943
|
+
input.context.writeOutput(
|
|
32944
|
+
`${secret.name} ${scopeLabel(secret.projectId)} updated ${secret.updatedAt}`
|
|
32945
|
+
);
|
|
32946
|
+
}
|
|
32947
|
+
}
|
|
32948
|
+
async function removeSecret(input) {
|
|
32949
|
+
await confirmDestructiveAction(input.context, {
|
|
32950
|
+
message: `This will remove secret "${input.name}".`,
|
|
32951
|
+
yes: input.commandOptions.yes
|
|
32952
|
+
});
|
|
32953
|
+
const response = await input.client.removeSecret(input.name, {
|
|
32954
|
+
projectId: await secretProjectId(input),
|
|
32955
|
+
apiBaseUrl: input.commandOptions.apiBaseUrl
|
|
32956
|
+
});
|
|
32957
|
+
writeRemoveResponse(response, input);
|
|
32958
|
+
}
|
|
32959
|
+
async function secretProjectId(input) {
|
|
32960
|
+
if (!input.commandOptions.project) {
|
|
32961
|
+
return void 0;
|
|
32962
|
+
}
|
|
32963
|
+
const scope = await requireProjectScope({
|
|
32964
|
+
context: input.context,
|
|
32965
|
+
options: input.commandOptions,
|
|
32966
|
+
identifier: input.commandOptions.project,
|
|
32967
|
+
explicitHint: "--project <project>"
|
|
32968
|
+
});
|
|
32969
|
+
return scope.projectId;
|
|
32970
|
+
}
|
|
32971
|
+
async function secretValue(input) {
|
|
32972
|
+
const sources = [
|
|
32973
|
+
input.options.stdin ? "stdin" : void 0,
|
|
32974
|
+
input.options.value !== void 0 ? "value" : void 0,
|
|
32975
|
+
input.options.fromEnv ? "from-env" : void 0
|
|
32976
|
+
].filter(Boolean);
|
|
32977
|
+
if (sources.length > 1) {
|
|
32978
|
+
throw new Error("Use only one of --stdin, --value, or --from-env.");
|
|
32979
|
+
}
|
|
32980
|
+
let value;
|
|
32981
|
+
if (input.options.value !== void 0) {
|
|
32982
|
+
value = input.options.value;
|
|
32983
|
+
} else if (input.options.fromEnv) {
|
|
32984
|
+
const envValue = input.env[input.options.fromEnv];
|
|
32985
|
+
if (envValue === void 0) {
|
|
32986
|
+
throw new Error(`Environment variable not set: ${input.options.fromEnv}`);
|
|
32987
|
+
}
|
|
32988
|
+
value = envValue;
|
|
32989
|
+
} else if (input.options.stdin) {
|
|
32990
|
+
value = await readStream2(input.stdin, Boolean(input.options.raw));
|
|
32991
|
+
} else {
|
|
32992
|
+
throw new Error(
|
|
32993
|
+
"Provide the secret value with --stdin, --value, or --from-env."
|
|
32994
|
+
);
|
|
32995
|
+
}
|
|
32996
|
+
if (value.length === 0 && !input.options.raw) {
|
|
32997
|
+
throw new Error(
|
|
32998
|
+
"Secret value is empty. Pass --raw to store an empty value."
|
|
32999
|
+
);
|
|
33000
|
+
}
|
|
33001
|
+
return value;
|
|
33002
|
+
}
|
|
33003
|
+
async function readStream2(stream, raw) {
|
|
33004
|
+
const chunks = [];
|
|
33005
|
+
for await (const chunk of stream) {
|
|
33006
|
+
chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(String(chunk)));
|
|
33007
|
+
}
|
|
33008
|
+
const value = Buffer.concat(chunks).toString("utf8");
|
|
33009
|
+
return raw ? value : value.replace(/\r?\n$/, "");
|
|
33010
|
+
}
|
|
33011
|
+
function writeSetResponse(response, input) {
|
|
33012
|
+
if (input.commandOptions.json) {
|
|
33013
|
+
input.context.writeOutput(JSON.stringify(response));
|
|
33014
|
+
return;
|
|
33015
|
+
}
|
|
33016
|
+
input.context.writeOutput(
|
|
33017
|
+
`secret ${response.secret.name} updated scope=${scopeLabel(response.secret.projectId)}`
|
|
33018
|
+
);
|
|
33019
|
+
}
|
|
33020
|
+
function writeRemoveResponse(response, input) {
|
|
33021
|
+
if (input.commandOptions.json) {
|
|
33022
|
+
input.context.writeOutput(JSON.stringify(response));
|
|
33023
|
+
return;
|
|
33024
|
+
}
|
|
33025
|
+
input.context.writeOutput(
|
|
33026
|
+
`secret ${response.secret.name} removed scope=${scopeLabel(response.secret.projectId)}`
|
|
33027
|
+
);
|
|
33028
|
+
}
|
|
33029
|
+
function scopeLabel(projectId) {
|
|
33030
|
+
return projectId ? `project:${projectId}` : "organization";
|
|
33031
|
+
}
|
|
33032
|
+
|
|
33033
|
+
// src/commands/secrets/commands.ts
|
|
33034
|
+
function registerSecretCommands(program, context) {
|
|
33035
|
+
const secrets = program.command("secrets").description("Manage Auto organization and project secrets.");
|
|
33036
|
+
secrets.command("set").description("Create or update a secret without printing its value.").argument("<name>", "secret name").option("--project <project>", "project id; defaults to organization scope").option("--stdin", "read the secret value from stdin").option("--value <value>", "secret value").option(
|
|
33037
|
+
"--from-env <name>",
|
|
33038
|
+
"read the secret value from an environment variable"
|
|
33039
|
+
).option("--raw", "allow empty values and preserve stdin exactly").option("--json", "print the updated secret metadata as JSON").option("--api-url <url>", "Auto API base URL").option("--api-base-url <url>", "Auto API base URL").action(async (name, commandOptions) => {
|
|
33040
|
+
await setSecret({
|
|
33041
|
+
client: createContextApiClient(context),
|
|
33042
|
+
commandOptions: withApiBaseUrl(context, commandOptions),
|
|
33043
|
+
context,
|
|
33044
|
+
name
|
|
33045
|
+
});
|
|
33046
|
+
});
|
|
33047
|
+
secrets.command("list").alias("ls").description("List secret metadata.").option("--project <project>", "project id; defaults to organization scope").option("--json", "print secret metadata as JSON").option("--api-url <url>", "Auto API base URL").option("--api-base-url <url>", "Auto API base URL").action(async (commandOptions) => {
|
|
33048
|
+
await listSecrets({
|
|
33049
|
+
client: createContextApiClient(context),
|
|
33050
|
+
commandOptions: withApiBaseUrl(context, commandOptions),
|
|
33051
|
+
context
|
|
33052
|
+
});
|
|
33053
|
+
});
|
|
33054
|
+
secrets.command("remove").alias("rm").description("Remove a secret.").argument("<name>", "secret name").option("--project <project>", "project id; defaults to organization scope").option("--json", "print removed secret metadata as JSON").option("-y, --yes", "skip confirmation prompt").option("--api-url <url>", "Auto API base URL").option("--api-base-url <url>", "Auto API base URL").action(async (name, commandOptions) => {
|
|
33055
|
+
await removeSecret({
|
|
33056
|
+
client: createContextApiClient(context),
|
|
33057
|
+
commandOptions: withApiBaseUrl(context, commandOptions),
|
|
33058
|
+
context,
|
|
33059
|
+
name
|
|
33060
|
+
});
|
|
33061
|
+
});
|
|
33062
|
+
}
|
|
33063
|
+
function withApiBaseUrl(context, commandOptions) {
|
|
33064
|
+
return {
|
|
33065
|
+
...commandOptions,
|
|
33066
|
+
apiBaseUrl: apiUrlFromOptions(context, commandOptions)
|
|
33067
|
+
};
|
|
33068
|
+
}
|
|
33069
|
+
|
|
33070
|
+
// src/commands/service-accounts/actions.ts
|
|
33071
|
+
init_src();
|
|
33072
|
+
async function createServiceAccount(input) {
|
|
33073
|
+
const response = await input.client.createProjectServiceAccount(
|
|
33074
|
+
{ name: input.name, scopes: requestedScopes(input.commandOptions) },
|
|
33075
|
+
{ apiBaseUrl: input.commandOptions.apiBaseUrl }
|
|
33076
|
+
);
|
|
33077
|
+
writeServiceAccountTokenResponse(response, input);
|
|
33078
|
+
}
|
|
33079
|
+
async function updateServiceAccount(input) {
|
|
33080
|
+
const response = await input.client.updateProjectServiceAccount(
|
|
33081
|
+
{ name: input.name, scopes: requestedScopes(input.commandOptions) },
|
|
33082
|
+
{ apiBaseUrl: input.commandOptions.apiBaseUrl }
|
|
33083
|
+
);
|
|
33084
|
+
if (input.commandOptions.json) {
|
|
33085
|
+
input.writeOutput(JSON.stringify(response));
|
|
33086
|
+
return;
|
|
33087
|
+
}
|
|
33088
|
+
writeServiceAccountScopesResponse(response, input.writeOutput);
|
|
33089
|
+
}
|
|
33090
|
+
async function rotateServiceAccount(input) {
|
|
33091
|
+
const response = await input.client.rotateProjectServiceAccountToken(
|
|
33092
|
+
{ name: input.name },
|
|
33093
|
+
{ apiBaseUrl: input.commandOptions.apiBaseUrl }
|
|
33094
|
+
);
|
|
33095
|
+
writeServiceAccountTokenResponse(response, input);
|
|
33096
|
+
}
|
|
33097
|
+
async function removeServiceAccount(input) {
|
|
33098
|
+
const response = await input.client.removeProjectServiceAccount(
|
|
33099
|
+
{ name: input.name },
|
|
33100
|
+
{ apiBaseUrl: input.commandOptions.apiBaseUrl }
|
|
33101
|
+
);
|
|
33102
|
+
if (input.commandOptions.json) {
|
|
33103
|
+
input.writeOutput(JSON.stringify(response));
|
|
33104
|
+
return;
|
|
33105
|
+
}
|
|
33106
|
+
input.writeOutput(`removed service-account ${response.serviceAccount.name}`);
|
|
33107
|
+
}
|
|
33108
|
+
function requestedScopes(options) {
|
|
33109
|
+
const presetNames = Object.keys(SERVICE_ACCOUNT_SCOPE_PRESETS).join(", ");
|
|
33110
|
+
const scopes = [];
|
|
33111
|
+
if (options.preset !== void 0) {
|
|
33112
|
+
const preset = ServiceAccountScopePresetSchema.safeParse(options.preset);
|
|
33113
|
+
if (!preset.success) {
|
|
33114
|
+
throw new Error(
|
|
33115
|
+
`Unknown preset "${options.preset}". Available presets: ${presetNames}.`
|
|
33116
|
+
);
|
|
33117
|
+
}
|
|
33118
|
+
scopes.push(...SERVICE_ACCOUNT_SCOPE_PRESETS[preset.data]);
|
|
33119
|
+
}
|
|
33120
|
+
for (const scope of options.scope ?? []) {
|
|
33121
|
+
if (!AuthScopeSchema.safeParse(scope).success) {
|
|
33122
|
+
throw new Error(
|
|
33123
|
+
`Unknown scope "${scope}". Valid scopes: ${AUTH_SCOPES.join(", ")}.`
|
|
33124
|
+
);
|
|
33125
|
+
}
|
|
33126
|
+
scopes.push(scope);
|
|
33127
|
+
}
|
|
33128
|
+
if (scopes.length === 0) {
|
|
33129
|
+
throw new Error(
|
|
33130
|
+
`Provide --preset <preset> (${presetNames}) or at least one --scope.`
|
|
33131
|
+
);
|
|
33132
|
+
}
|
|
33133
|
+
return [...new Set(scopes)];
|
|
33134
|
+
}
|
|
33135
|
+
function writeServiceAccountTokenResponse(response, input) {
|
|
33136
|
+
if (input.commandOptions.json) {
|
|
33137
|
+
input.writeOutput(JSON.stringify(response));
|
|
33138
|
+
return;
|
|
33139
|
+
}
|
|
33140
|
+
input.writeOutput(`service-account ${response.serviceAccount.name}`);
|
|
33141
|
+
input.writeOutput(
|
|
33142
|
+
`scopes ${response.serviceAccount.scopes.join(", ") || "(none)"}`
|
|
33143
|
+
);
|
|
33144
|
+
input.writeOutput(`token ${response.token}`);
|
|
33145
|
+
}
|
|
33146
|
+
function writeServiceAccountScopesResponse(response, writeOutput) {
|
|
33147
|
+
writeOutput(`service-account ${response.serviceAccount.name}`);
|
|
33148
|
+
writeOutput(
|
|
33149
|
+
`scopes ${response.serviceAccount.scopes.join(", ") || "(none)"}`
|
|
33150
|
+
);
|
|
33151
|
+
}
|
|
33152
|
+
|
|
33153
|
+
// src/commands/service-accounts/commands.ts
|
|
33154
|
+
function registerServiceAccountCommands(program, context) {
|
|
33155
|
+
const serviceAccount = program.command("service-account").description("Manage Auto project service accounts.");
|
|
33156
|
+
serviceAccount.command("create").description("Create a project service account and print its token.").argument("<name>", "service account name").option(
|
|
33157
|
+
"--preset <preset>",
|
|
33158
|
+
"grant a named scope bundle (read-only, applier)"
|
|
33159
|
+
).option(
|
|
33160
|
+
"--scope <scope>",
|
|
33161
|
+
"grant a scope; repeat to grant multiple scopes",
|
|
33162
|
+
collectScopes
|
|
33163
|
+
).option("--json", "print the created service account as JSON").option("--api-url <url>", "Auto API base URL").option("--api-base-url <url>", "Auto API base URL").action(
|
|
33164
|
+
async (name, commandOptions) => {
|
|
33165
|
+
await createServiceAccount({
|
|
33166
|
+
client: createContextApiClient(context),
|
|
33167
|
+
commandOptions: withApiBaseUrl2(context, commandOptions),
|
|
33168
|
+
name,
|
|
33169
|
+
writeOutput: context.writeOutput
|
|
33170
|
+
});
|
|
33171
|
+
}
|
|
33172
|
+
);
|
|
33173
|
+
serviceAccount.command("update").description("Update project service account scopes.").argument("<name>", "service account name").option(
|
|
33174
|
+
"--preset <preset>",
|
|
33175
|
+
"grant a named scope bundle (read-only, applier)"
|
|
33176
|
+
).option(
|
|
33177
|
+
"--scope <scope>",
|
|
33178
|
+
"grant a scope; repeat to grant multiple scopes",
|
|
33179
|
+
collectScopes
|
|
33180
|
+
).option("--json", "print the updated service account as JSON").option("--api-url <url>", "Auto API base URL").option("--api-base-url <url>", "Auto API base URL").action(
|
|
33181
|
+
async (name, commandOptions) => {
|
|
33182
|
+
await updateServiceAccount({
|
|
33183
|
+
client: createContextApiClient(context),
|
|
33184
|
+
commandOptions: withApiBaseUrl2(context, commandOptions),
|
|
33185
|
+
name,
|
|
33186
|
+
writeOutput: context.writeOutput
|
|
33187
|
+
});
|
|
33188
|
+
}
|
|
33189
|
+
);
|
|
33190
|
+
serviceAccount.command("rotate").description("Rotate a project service account token.").argument("<name>", "service account name").option("--json", "print the service account token as JSON").option("-y, --yes", "skip confirmation prompt").option("--api-url <url>", "Auto API base URL").option("--api-base-url <url>", "Auto API base URL").action(
|
|
33191
|
+
async (name, commandOptions) => {
|
|
33192
|
+
await confirmDestructiveAction(context, {
|
|
33193
|
+
message: `This will rotate service account "${name}" and revoke its current token.`,
|
|
33194
|
+
yes: commandOptions.yes
|
|
33195
|
+
});
|
|
33196
|
+
await rotateServiceAccount({
|
|
33197
|
+
client: createContextApiClient(context),
|
|
33198
|
+
commandOptions: withApiBaseUrl2(context, commandOptions),
|
|
33199
|
+
name,
|
|
33200
|
+
writeOutput: context.writeOutput
|
|
33201
|
+
});
|
|
33202
|
+
}
|
|
33203
|
+
);
|
|
33204
|
+
serviceAccount.command("remove").description("Remove a project service account and revoke its token.").argument("<name>", "service account name").option("--json", "print the removed service account as JSON").option("-y, --yes", "skip confirmation prompt").option("--api-url <url>", "Auto API base URL").option("--api-base-url <url>", "Auto API base URL").action(
|
|
33205
|
+
async (name, commandOptions) => {
|
|
33206
|
+
await confirmDestructiveAction(context, {
|
|
33207
|
+
message: `This will remove service account "${name}" and revoke its token.`,
|
|
33208
|
+
yes: commandOptions.yes
|
|
33209
|
+
});
|
|
33210
|
+
await removeServiceAccount({
|
|
33211
|
+
client: createContextApiClient(context),
|
|
33212
|
+
commandOptions: withApiBaseUrl2(context, commandOptions),
|
|
33213
|
+
name,
|
|
33214
|
+
writeOutput: context.writeOutput
|
|
33215
|
+
});
|
|
33216
|
+
}
|
|
33217
|
+
);
|
|
33218
|
+
}
|
|
33219
|
+
function collectScopes(scope, scopes) {
|
|
33220
|
+
return [...scopes ?? [], scope];
|
|
33221
|
+
}
|
|
33222
|
+
function withApiBaseUrl2(context, commandOptions) {
|
|
33223
|
+
return {
|
|
33224
|
+
...commandOptions,
|
|
33225
|
+
apiBaseUrl: apiUrlFromOptions(context, commandOptions)
|
|
33226
|
+
};
|
|
33227
|
+
}
|
|
33228
|
+
|
|
33229
|
+
// src/commands/sessions/conversation.ts
|
|
32850
33230
|
init_conversation2();
|
|
32851
|
-
async function
|
|
33231
|
+
async function streamSessionConversation(input) {
|
|
32852
33232
|
const writeConversationEvent = createConversationStreamWriter({
|
|
32853
33233
|
writeChunk: input.stdout ? (chunk) => {
|
|
32854
33234
|
input.stdout?.write(chunk);
|
|
32855
33235
|
} : void 0,
|
|
32856
33236
|
writeLine: input.writeOutput
|
|
32857
33237
|
});
|
|
32858
|
-
await input.client.
|
|
33238
|
+
await input.client.streamSessionConversation(input.sessionId, {
|
|
32859
33239
|
apiBaseUrl: input.apiBaseUrl,
|
|
32860
33240
|
onEvent: writeConversationEvent
|
|
32861
33241
|
});
|
|
32862
33242
|
}
|
|
32863
33243
|
|
|
32864
|
-
// src/commands/
|
|
33244
|
+
// src/commands/sessions/interactive.ts
|
|
32865
33245
|
init_conversation2();
|
|
32866
33246
|
|
|
32867
|
-
// src/commands/
|
|
33247
|
+
// src/commands/sessions/operator.ts
|
|
32868
33248
|
function operatorName(explicit, env) {
|
|
32869
33249
|
return explicit?.trim() || env.AUTO_OPERATOR_NAME?.trim() || env.USER?.trim() || env.USERNAME?.trim() || "operator";
|
|
32870
33250
|
}
|
|
@@ -32877,20 +33257,20 @@ function automationMetadata(event, operator) {
|
|
|
32877
33257
|
};
|
|
32878
33258
|
}
|
|
32879
33259
|
function attachMessage(operator) {
|
|
32880
|
-
return `automated message: ${operator} has just attached to this
|
|
33260
|
+
return `automated message: ${operator} has just attached to this session. At your next safe point, pause your current work, greet them, and briefly summarize what you are working on.`;
|
|
32881
33261
|
}
|
|
32882
33262
|
function detachMessage(operator) {
|
|
32883
|
-
return `automated message: ${operator} has just detached from this
|
|
33263
|
+
return `automated message: ${operator} has just detached from this session. Continue independently, incorporate relevant discussion where useful, and persist until the assigned work is complete. Do not wait for further operator input.`;
|
|
32884
33264
|
}
|
|
32885
33265
|
|
|
32886
|
-
// src/commands/
|
|
33266
|
+
// src/commands/sessions/interactive.ts
|
|
32887
33267
|
async function runConsole(input) {
|
|
32888
33268
|
input.writeOutput(
|
|
32889
33269
|
"Type messages and press Enter. Type .detach to leave it running."
|
|
32890
33270
|
);
|
|
32891
33271
|
if (input.sendAttachMessage) {
|
|
32892
33272
|
await input.client.sendMessage(
|
|
32893
|
-
input.
|
|
33273
|
+
input.sessionId,
|
|
32894
33274
|
attachMessage(input.operatorName),
|
|
32895
33275
|
{
|
|
32896
33276
|
apiBaseUrl: input.apiBaseUrl,
|
|
@@ -32909,7 +33289,7 @@ async function runConsole(input) {
|
|
|
32909
33289
|
const stream = (async () => {
|
|
32910
33290
|
while (!abort.signal.aborted) {
|
|
32911
33291
|
try {
|
|
32912
|
-
await input.client.
|
|
33292
|
+
await input.client.streamSessionConversation(input.sessionId, {
|
|
32913
33293
|
apiBaseUrl: input.apiBaseUrl,
|
|
32914
33294
|
signal: abort.signal,
|
|
32915
33295
|
cursor,
|
|
@@ -32933,7 +33313,7 @@ async function runConsole(input) {
|
|
|
32933
33313
|
})();
|
|
32934
33314
|
const consoleInput = createInteractiveInputController({
|
|
32935
33315
|
client: input.client,
|
|
32936
|
-
|
|
33316
|
+
sessionId: input.sessionId,
|
|
32937
33317
|
apiBaseUrl: input.apiBaseUrl,
|
|
32938
33318
|
operatorName: input.operatorName,
|
|
32939
33319
|
sendDetachMessage: input.sendDetachMessage,
|
|
@@ -32943,7 +33323,7 @@ async function runConsole(input) {
|
|
|
32943
33323
|
});
|
|
32944
33324
|
const status = pollUntilFailed({
|
|
32945
33325
|
client: input.client,
|
|
32946
|
-
|
|
33326
|
+
sessionId: input.sessionId,
|
|
32947
33327
|
apiBaseUrl: input.apiBaseUrl,
|
|
32948
33328
|
onFailed: () => {
|
|
32949
33329
|
consoleInput.close();
|
|
@@ -32978,7 +33358,7 @@ function createInteractiveInputController(input) {
|
|
|
32978
33358
|
if (message === ".detach") {
|
|
32979
33359
|
if (input.sendDetachMessage) {
|
|
32980
33360
|
const command2 = await input.client.sendMessage(
|
|
32981
|
-
input.
|
|
33361
|
+
input.sessionId,
|
|
32982
33362
|
detachMessage(input.operatorName),
|
|
32983
33363
|
{
|
|
32984
33364
|
apiBaseUrl: input.apiBaseUrl,
|
|
@@ -32990,12 +33370,16 @@ function createInteractiveInputController(input) {
|
|
|
32990
33370
|
);
|
|
32991
33371
|
input.writeOutput(`sent ${command2.command_id}`);
|
|
32992
33372
|
}
|
|
32993
|
-
input.writeOutput(`detached ${input.
|
|
33373
|
+
input.writeOutput(`detached ${input.sessionId}`);
|
|
32994
33374
|
return;
|
|
32995
33375
|
}
|
|
32996
|
-
const command = await input.client.sendMessage(
|
|
32997
|
-
|
|
32998
|
-
|
|
33376
|
+
const command = await input.client.sendMessage(
|
|
33377
|
+
input.sessionId,
|
|
33378
|
+
message,
|
|
33379
|
+
{
|
|
33380
|
+
apiBaseUrl: input.apiBaseUrl
|
|
33381
|
+
}
|
|
33382
|
+
);
|
|
32999
33383
|
input.writeOutput(`sent ${command.command_id}`);
|
|
33000
33384
|
}
|
|
33001
33385
|
} finally {
|
|
@@ -33049,10 +33433,10 @@ function pollUntilFailed(input) {
|
|
|
33049
33433
|
if (cancelled) {
|
|
33050
33434
|
return;
|
|
33051
33435
|
}
|
|
33052
|
-
const
|
|
33436
|
+
const session = await input.client.getSession(input.sessionId, {
|
|
33053
33437
|
apiBaseUrl: input.apiBaseUrl
|
|
33054
33438
|
});
|
|
33055
|
-
if (
|
|
33439
|
+
if (session.status === "failed") {
|
|
33056
33440
|
input.onFailed();
|
|
33057
33441
|
return;
|
|
33058
33442
|
}
|
|
@@ -33061,31 +33445,33 @@ function pollUntilFailed(input) {
|
|
|
33061
33445
|
return { done, cancel };
|
|
33062
33446
|
}
|
|
33063
33447
|
|
|
33064
|
-
// src/commands/
|
|
33065
|
-
function
|
|
33448
|
+
// src/commands/sessions/service.ts
|
|
33449
|
+
function createSessionServiceClient(context) {
|
|
33066
33450
|
return createContextApiClient(context);
|
|
33067
33451
|
}
|
|
33068
33452
|
|
|
33069
|
-
// src/commands/
|
|
33453
|
+
// src/commands/sessions/actions.ts
|
|
33070
33454
|
async function interactiveRunAction(context, agentName, commandOptions) {
|
|
33071
|
-
const client =
|
|
33455
|
+
const client = createSessionServiceClient(context);
|
|
33072
33456
|
const apiBaseUrl = apiUrlFromOptions(context, commandOptions);
|
|
33073
|
-
const created = await client.
|
|
33457
|
+
const created = await client.triggerSession(agentName, {
|
|
33074
33458
|
message: commandOptions.message,
|
|
33075
33459
|
interactive: true,
|
|
33076
33460
|
apiBaseUrl
|
|
33077
33461
|
});
|
|
33078
33462
|
const style = context.io.style;
|
|
33079
|
-
context.writeOutput(
|
|
33463
|
+
context.writeOutput(
|
|
33464
|
+
`${style.label("session_id")} ${style.id(created.session_id)}`
|
|
33465
|
+
);
|
|
33080
33466
|
context.writeOutput(
|
|
33081
33467
|
`${style.label("workflow_id")} ${style.id(created.workflow_id)}`
|
|
33082
33468
|
);
|
|
33083
33469
|
context.writeOutput(
|
|
33084
|
-
`${style.label("status")} ${
|
|
33470
|
+
`${style.label("status")} ${styleSessionStatus(style, created.status)}`
|
|
33085
33471
|
);
|
|
33086
33472
|
await runConsole({
|
|
33087
33473
|
client,
|
|
33088
|
-
|
|
33474
|
+
sessionId: created.session_id,
|
|
33089
33475
|
apiBaseUrl,
|
|
33090
33476
|
operatorName: operatorName(commandOptions.operator, context.env),
|
|
33091
33477
|
sendAttachMessage: commandOptions.attachMessage === true,
|
|
@@ -33095,94 +33481,108 @@ async function interactiveRunAction(context, agentName, commandOptions) {
|
|
|
33095
33481
|
stdout: context.stdout
|
|
33096
33482
|
});
|
|
33097
33483
|
}
|
|
33098
|
-
async function attachRunAction(context,
|
|
33099
|
-
await
|
|
33100
|
-
client:
|
|
33101
|
-
|
|
33484
|
+
async function attachRunAction(context, sessionId, commandOptions) {
|
|
33485
|
+
await streamSessionConversation({
|
|
33486
|
+
client: createSessionServiceClient(context),
|
|
33487
|
+
sessionId,
|
|
33102
33488
|
apiBaseUrl: apiUrlFromOptions(context, commandOptions),
|
|
33103
33489
|
stdout: context.stdout,
|
|
33104
33490
|
writeOutput: context.writeOutput
|
|
33105
33491
|
});
|
|
33106
33492
|
}
|
|
33107
|
-
async function
|
|
33108
|
-
const
|
|
33109
|
-
|
|
33110
|
-
|
|
33493
|
+
async function archiveSessionAction(context, sessionId, commandOptions) {
|
|
33494
|
+
const session = await createSessionServiceClient(context).archiveSession(
|
|
33495
|
+
sessionId,
|
|
33496
|
+
{
|
|
33497
|
+
apiBaseUrl: apiUrlFromOptions(context, commandOptions)
|
|
33498
|
+
}
|
|
33499
|
+
);
|
|
33111
33500
|
const style = context.io.style;
|
|
33112
|
-
context.writeOutput(`${style.label("
|
|
33501
|
+
context.writeOutput(`${style.label("session_id")} ${style.id(session.id)}`);
|
|
33113
33502
|
context.writeOutput(
|
|
33114
|
-
`${style.label("archived_at")} ${style.dim(
|
|
33503
|
+
`${style.label("archived_at")} ${style.dim(session.archivedAt ?? "")}`
|
|
33115
33504
|
);
|
|
33116
33505
|
}
|
|
33117
|
-
async function
|
|
33118
|
-
const result = await
|
|
33119
|
-
|
|
33120
|
-
|
|
33506
|
+
async function archiveSessionsAction(context, sessionIds, commandOptions) {
|
|
33507
|
+
const result = await createSessionServiceClient(context).archiveSessions(
|
|
33508
|
+
sessionIds,
|
|
33509
|
+
{
|
|
33510
|
+
apiBaseUrl: apiUrlFromOptions(context, commandOptions)
|
|
33511
|
+
}
|
|
33512
|
+
);
|
|
33121
33513
|
const style = context.io.style;
|
|
33122
|
-
for (const
|
|
33514
|
+
for (const session of result.sessions) {
|
|
33123
33515
|
context.writeOutput(
|
|
33124
|
-
`${style.label("
|
|
33516
|
+
`${style.label("session_id")} ${style.id(session.id)} ${style.label(
|
|
33125
33517
|
"archived_at"
|
|
33126
|
-
)} ${style.dim(
|
|
33518
|
+
)} ${style.dim(session.archivedAt ?? "")}`
|
|
33127
33519
|
);
|
|
33128
33520
|
}
|
|
33129
33521
|
}
|
|
33130
|
-
async function
|
|
33131
|
-
const
|
|
33132
|
-
|
|
33133
|
-
|
|
33522
|
+
async function unarchiveSessionAction(context, sessionId, commandOptions) {
|
|
33523
|
+
const session = await createSessionServiceClient(context).unarchiveSession(
|
|
33524
|
+
sessionId,
|
|
33525
|
+
{
|
|
33526
|
+
apiBaseUrl: apiUrlFromOptions(context, commandOptions)
|
|
33527
|
+
}
|
|
33528
|
+
);
|
|
33134
33529
|
const style = context.io.style;
|
|
33135
|
-
context.writeOutput(`${style.label("
|
|
33136
|
-
context.writeOutput(
|
|
33530
|
+
context.writeOutput(`${style.label("session_id")} ${style.id(session.id)}`);
|
|
33531
|
+
context.writeOutput(
|
|
33532
|
+
`${style.label("archived")} ${Boolean(session.archivedAt)}`
|
|
33533
|
+
);
|
|
33137
33534
|
}
|
|
33138
|
-
async function
|
|
33139
|
-
const result = await
|
|
33140
|
-
|
|
33141
|
-
|
|
33535
|
+
async function unarchiveSessionsAction(context, sessionIds, commandOptions) {
|
|
33536
|
+
const result = await createSessionServiceClient(context).unarchiveSessions(
|
|
33537
|
+
sessionIds,
|
|
33538
|
+
{
|
|
33539
|
+
apiBaseUrl: apiUrlFromOptions(context, commandOptions)
|
|
33540
|
+
}
|
|
33541
|
+
);
|
|
33142
33542
|
const style = context.io.style;
|
|
33143
|
-
for (const
|
|
33543
|
+
for (const session of result.sessions) {
|
|
33144
33544
|
context.writeOutput(
|
|
33145
|
-
`${style.label("
|
|
33545
|
+
`${style.label("session_id")} ${style.id(session.id)} ${style.label(
|
|
33146
33546
|
"archived"
|
|
33147
|
-
)} ${Boolean(
|
|
33547
|
+
)} ${Boolean(session.archivedAt)}`
|
|
33148
33548
|
);
|
|
33149
33549
|
}
|
|
33150
33550
|
}
|
|
33151
|
-
async function
|
|
33152
|
-
const client =
|
|
33551
|
+
async function stopSessionsAction(context, sessionIds, commandOptions) {
|
|
33552
|
+
const client = createSessionServiceClient(context);
|
|
33153
33553
|
const apiBaseUrl = apiUrlFromOptions(context, commandOptions);
|
|
33154
33554
|
const style = context.io.style;
|
|
33155
|
-
const
|
|
33156
|
-
for (const
|
|
33555
|
+
const failedSessionIds = [];
|
|
33556
|
+
for (const sessionId of sessionIds) {
|
|
33157
33557
|
try {
|
|
33158
|
-
const command = await client.
|
|
33558
|
+
const command = await client.stopSession(sessionId, {
|
|
33159
33559
|
apiBaseUrl,
|
|
33160
33560
|
reason: commandOptions.reason
|
|
33161
33561
|
});
|
|
33162
33562
|
context.writeOutput(
|
|
33163
|
-
`${style.label("
|
|
33563
|
+
`${style.label("session_id")} ${style.id(sessionId)} ${style.label(
|
|
33164
33564
|
"command_id"
|
|
33165
33565
|
)} ${style.id(command.command_id)} ${style.label("status")} ${command.status}`
|
|
33166
33566
|
);
|
|
33167
33567
|
} catch (error51) {
|
|
33168
|
-
|
|
33568
|
+
failedSessionIds.push(sessionId);
|
|
33169
33569
|
context.writeOutput(
|
|
33170
|
-
`${style.label("
|
|
33570
|
+
`${style.label("session_id")} ${style.id(sessionId)} ${style.error(
|
|
33171
33571
|
`error ${error51 instanceof Error ? error51.message : String(error51)}`
|
|
33172
33572
|
)}`
|
|
33173
33573
|
);
|
|
33174
33574
|
}
|
|
33175
33575
|
}
|
|
33176
|
-
if (
|
|
33576
|
+
if (failedSessionIds.length > 0) {
|
|
33177
33577
|
throw new Error(
|
|
33178
|
-
`Failed to stop ${
|
|
33578
|
+
`Failed to stop ${failedSessionIds.length} of ${sessionIds.length} session(s): ${failedSessionIds.join(", ")}`
|
|
33179
33579
|
);
|
|
33180
33580
|
}
|
|
33181
33581
|
}
|
|
33182
|
-
async function consoleRunAction(context,
|
|
33582
|
+
async function consoleRunAction(context, sessionId, commandOptions) {
|
|
33183
33583
|
await runConsole({
|
|
33184
|
-
client:
|
|
33185
|
-
|
|
33584
|
+
client: createSessionServiceClient(context),
|
|
33585
|
+
sessionId,
|
|
33186
33586
|
apiBaseUrl: apiUrlFromOptions(context, commandOptions),
|
|
33187
33587
|
operatorName: operatorName(commandOptions.operator, context.env),
|
|
33188
33588
|
sendAttachMessage: commandOptions.attachMessage !== false,
|
|
@@ -33192,9 +33592,9 @@ async function consoleRunAction(context, runId, commandOptions) {
|
|
|
33192
33592
|
stdout: context.stdout
|
|
33193
33593
|
});
|
|
33194
33594
|
}
|
|
33195
|
-
async function sendRunMessageAction(context,
|
|
33196
|
-
const command = await
|
|
33197
|
-
|
|
33595
|
+
async function sendRunMessageAction(context, sessionId, message, commandOptions) {
|
|
33596
|
+
const command = await createSessionServiceClient(context).sendMessage(
|
|
33597
|
+
sessionId,
|
|
33198
33598
|
message,
|
|
33199
33599
|
{
|
|
33200
33600
|
apiBaseUrl: apiUrlFromOptions(context, commandOptions)
|
|
@@ -33207,7 +33607,7 @@ async function sendRunMessageAction(context, runId, message, commandOptions) {
|
|
|
33207
33607
|
context.writeOutput(`${style.label("status")} ${command.status}`);
|
|
33208
33608
|
}
|
|
33209
33609
|
|
|
33210
|
-
// src/commands/
|
|
33610
|
+
// src/commands/sessions/benchmark-startup.ts
|
|
33211
33611
|
import { performance } from "perf_hooks";
|
|
33212
33612
|
var DEFAULT_TIMEOUT_MS = 3e5;
|
|
33213
33613
|
var DEFAULT_POLL_INTERVAL_MS = 1e3;
|
|
@@ -33223,11 +33623,11 @@ async function benchmarkStartupAction(context, commandOptions) {
|
|
|
33223
33623
|
if (commandOptions.thresholdMs !== void 0) {
|
|
33224
33624
|
validatePositiveInteger(commandOptions.thresholdMs, "threshold-ms");
|
|
33225
33625
|
}
|
|
33226
|
-
const client =
|
|
33626
|
+
const client = createSessionServiceClient(context);
|
|
33227
33627
|
const apiBaseUrl = apiUrlFromOptions(context, commandOptions);
|
|
33228
33628
|
const startedAt = /* @__PURE__ */ new Date();
|
|
33229
33629
|
const start = performance.now();
|
|
33230
|
-
const created = await client.
|
|
33630
|
+
const created = await client.triggerSession(commandOptions.agent, {
|
|
33231
33631
|
message: commandOptions.message,
|
|
33232
33632
|
...commandOptions.interactive === true ? { interactive: true } : {},
|
|
33233
33633
|
apiBaseUrl
|
|
@@ -33236,7 +33636,7 @@ async function benchmarkStartupAction(context, commandOptions) {
|
|
|
33236
33636
|
const diagnosticsAbort = new AbortController();
|
|
33237
33637
|
const diagnosticsDone = streamDiagnosticsBestEffort({
|
|
33238
33638
|
client,
|
|
33239
|
-
|
|
33639
|
+
sessionId: created.session_id,
|
|
33240
33640
|
apiBaseUrl,
|
|
33241
33641
|
signal: diagnosticsAbort.signal,
|
|
33242
33642
|
onEvent: diagnostics.push,
|
|
@@ -33244,7 +33644,7 @@ async function benchmarkStartupAction(context, commandOptions) {
|
|
|
33244
33644
|
});
|
|
33245
33645
|
const poll = await pollUntilAwaiting({
|
|
33246
33646
|
client,
|
|
33247
|
-
|
|
33647
|
+
sessionId: created.session_id,
|
|
33248
33648
|
initialStatus: created.status,
|
|
33249
33649
|
apiBaseUrl,
|
|
33250
33650
|
timeoutMs,
|
|
@@ -33256,7 +33656,7 @@ async function benchmarkStartupAction(context, commandOptions) {
|
|
|
33256
33656
|
await settleDiagnostics(diagnosticsDone);
|
|
33257
33657
|
const thresholdPassed = commandOptions.thresholdMs === void 0 ? void 0 : elapsedMs <= commandOptions.thresholdMs;
|
|
33258
33658
|
const result = {
|
|
33259
|
-
|
|
33659
|
+
session_id: created.session_id,
|
|
33260
33660
|
workflow_id: created.workflow_id,
|
|
33261
33661
|
status: poll.status,
|
|
33262
33662
|
started_at: startedAt.toISOString(),
|
|
@@ -33277,15 +33677,17 @@ async function benchmarkStartupAction(context, commandOptions) {
|
|
|
33277
33677
|
writeBenchmarkResult(context, result, commandOptions.json === true);
|
|
33278
33678
|
if (poll.timedOut) {
|
|
33279
33679
|
throw new Error(
|
|
33280
|
-
`
|
|
33680
|
+
`Session ${created.session_id} did not reach awaiting within ${timeoutMs}ms`
|
|
33281
33681
|
);
|
|
33282
33682
|
}
|
|
33283
33683
|
if (poll.status === "failed") {
|
|
33284
|
-
throw new Error(
|
|
33684
|
+
throw new Error(
|
|
33685
|
+
`Session ${created.session_id} failed before reaching awaiting`
|
|
33686
|
+
);
|
|
33285
33687
|
}
|
|
33286
33688
|
if (thresholdPassed === false) {
|
|
33287
33689
|
throw new Error(
|
|
33288
|
-
`
|
|
33690
|
+
`Session ${created.session_id} reached awaiting in ${elapsedMs}ms, above threshold ${commandOptions.thresholdMs}ms`
|
|
33289
33691
|
);
|
|
33290
33692
|
}
|
|
33291
33693
|
}
|
|
@@ -33314,11 +33716,11 @@ async function pollUntilAwaiting(input) {
|
|
|
33314
33716
|
if (Date.now() >= deadline) {
|
|
33315
33717
|
return { status, pollCount, timedOut: true };
|
|
33316
33718
|
}
|
|
33317
|
-
const
|
|
33719
|
+
const session = await input.client.getSession(input.sessionId, {
|
|
33318
33720
|
apiBaseUrl: input.apiBaseUrl
|
|
33319
33721
|
});
|
|
33320
33722
|
pollCount += 1;
|
|
33321
|
-
status =
|
|
33723
|
+
status = session.status;
|
|
33322
33724
|
}
|
|
33323
33725
|
}
|
|
33324
33726
|
function delay2(ms) {
|
|
@@ -33369,7 +33771,7 @@ function createDiagnosticCollector(limit) {
|
|
|
33369
33771
|
}
|
|
33370
33772
|
async function streamDiagnosticsBestEffort(input) {
|
|
33371
33773
|
try {
|
|
33372
|
-
await input.client.
|
|
33774
|
+
await input.client.streamSessionDiagnostics(input.sessionId, {
|
|
33373
33775
|
apiBaseUrl: input.apiBaseUrl,
|
|
33374
33776
|
signal: input.signal,
|
|
33375
33777
|
onEvent: input.onEvent
|
|
@@ -33388,7 +33790,7 @@ function writeBenchmarkResult(context, result, json2) {
|
|
|
33388
33790
|
context.writeOutput(JSON.stringify(result));
|
|
33389
33791
|
return;
|
|
33390
33792
|
}
|
|
33391
|
-
context.writeOutput(`
|
|
33793
|
+
context.writeOutput(`session_id ${result.session_id}`);
|
|
33392
33794
|
context.writeOutput(`workflow_id ${result.workflow_id}`);
|
|
33393
33795
|
context.writeOutput(`status ${result.status}`);
|
|
33394
33796
|
context.writeOutput(`elapsed_ms ${result.elapsed_ms}`);
|
|
@@ -33430,30 +33832,30 @@ function validateNonNegativeInteger(value, label) {
|
|
|
33430
33832
|
}
|
|
33431
33833
|
}
|
|
33432
33834
|
|
|
33433
|
-
// src/commands/
|
|
33835
|
+
// src/commands/sessions/introspect.ts
|
|
33434
33836
|
var PREVIEW_CHARS = 160;
|
|
33435
|
-
async function handleRunsShow(context,
|
|
33837
|
+
async function handleRunsShow(context, sessionId, options = {}) {
|
|
33436
33838
|
const client = createContextApiClient(context);
|
|
33437
33839
|
const apiBaseUrl = apiUrlFromOptions(context, options);
|
|
33438
|
-
const [
|
|
33439
|
-
client.
|
|
33440
|
-
client.
|
|
33840
|
+
const [session, summary] = await Promise.all([
|
|
33841
|
+
client.getSession(sessionId, { apiBaseUrl }),
|
|
33842
|
+
client.getSessionSummary(sessionId, { apiBaseUrl })
|
|
33441
33843
|
]);
|
|
33442
|
-
context.io.writeResult({
|
|
33844
|
+
context.io.writeResult({ session, summary }, formatRunShowText);
|
|
33443
33845
|
}
|
|
33444
33846
|
function formatRunShowText(result, writeLine, style) {
|
|
33445
33847
|
const { summary } = result;
|
|
33446
33848
|
writeLine(
|
|
33447
|
-
`${style.id(summary.
|
|
33448
|
-
`agent=${summary.
|
|
33849
|
+
`${style.id(summary.session.id)} ${styleSessionStatus(style, summary.session.status)} ${style.dim(
|
|
33850
|
+
`agent=${summary.session.agentName}`
|
|
33449
33851
|
)}`
|
|
33450
33852
|
);
|
|
33451
|
-
if (summary.
|
|
33452
|
-
writeLine(`${style.label("title:")} ${summary.
|
|
33853
|
+
if (summary.session.displayTitle) {
|
|
33854
|
+
writeLine(`${style.label("title:")} ${summary.session.displayTitle}`);
|
|
33453
33855
|
}
|
|
33454
33856
|
writeLine(
|
|
33455
33857
|
style.dim(
|
|
33456
|
-
`created=${summary.
|
|
33858
|
+
`created=${summary.session.createdAt} started=${summary.session.startedAt ?? "-"} finished=${summary.session.finishedAt ?? "-"}`
|
|
33457
33859
|
)
|
|
33458
33860
|
);
|
|
33459
33861
|
writeLine(
|
|
@@ -33498,14 +33900,14 @@ function formatRunShowText(result, writeLine, style) {
|
|
|
33498
33900
|
`${style.label("check:")} ${check2.name} ${check2.status}${check2.conclusion ? ` ${styleCheckConclusion(style, check2.conclusion)}` : ""}`
|
|
33499
33901
|
);
|
|
33500
33902
|
}
|
|
33501
|
-
if (summary.
|
|
33502
|
-
writeLine(style.error(`error: ${JSON.stringify(summary.
|
|
33903
|
+
if (summary.session.error !== null) {
|
|
33904
|
+
writeLine(style.error(`error: ${JSON.stringify(summary.session.error)}`));
|
|
33503
33905
|
}
|
|
33504
33906
|
}
|
|
33505
|
-
async function handleRunsConversation(context,
|
|
33907
|
+
async function handleRunsConversation(context, sessionId, options = {}) {
|
|
33506
33908
|
const client = createContextApiClient(context);
|
|
33507
33909
|
const tailMode = !options.after;
|
|
33508
|
-
const response = await client.
|
|
33910
|
+
const response = await client.getSessionConversation(sessionId, {
|
|
33509
33911
|
apiBaseUrl: apiUrlFromOptions(context, options),
|
|
33510
33912
|
cursor: options.after,
|
|
33511
33913
|
before: options.before,
|
|
@@ -33516,7 +33918,7 @@ async function handleRunsConversation(context, runId, options = {}) {
|
|
|
33516
33918
|
const events = [...response.events].sort((a, b) => a.sequence - b.sequence);
|
|
33517
33919
|
context.io.writeResult(
|
|
33518
33920
|
{
|
|
33519
|
-
|
|
33921
|
+
sessionId,
|
|
33520
33922
|
events,
|
|
33521
33923
|
cursor: response.cursor,
|
|
33522
33924
|
hasMore: response.hasMore,
|
|
@@ -33554,15 +33956,15 @@ function formatConversationText(result, writeLine, style) {
|
|
|
33554
33956
|
}
|
|
33555
33957
|
}
|
|
33556
33958
|
}
|
|
33557
|
-
async function handleRunsSearch(context,
|
|
33959
|
+
async function handleRunsSearch(context, sessionId, queries, options = {}) {
|
|
33558
33960
|
const client = createContextApiClient(context);
|
|
33559
|
-
const response = await client.
|
|
33961
|
+
const response = await client.searchSessionConversation(sessionId, queries, {
|
|
33560
33962
|
apiBaseUrl: apiUrlFromOptions(context, options),
|
|
33561
33963
|
kinds: options.kind,
|
|
33562
33964
|
after: options.after,
|
|
33563
33965
|
limit: options.limit
|
|
33564
33966
|
});
|
|
33565
|
-
context.io.writeResult({
|
|
33967
|
+
context.io.writeResult({ sessionId, queries, ...response }, formatSearchText);
|
|
33566
33968
|
}
|
|
33567
33969
|
function formatSearchText(result, writeLine, style) {
|
|
33568
33970
|
if (result.matches.length === 0) {
|
|
@@ -33586,9 +33988,9 @@ function formatSearchText(result, writeLine, style) {
|
|
|
33586
33988
|
);
|
|
33587
33989
|
}
|
|
33588
33990
|
}
|
|
33589
|
-
async function handleRunsTools(context,
|
|
33991
|
+
async function handleRunsTools(context, sessionId, options = {}) {
|
|
33590
33992
|
const client = createContextApiClient(context);
|
|
33591
|
-
const response = await client.
|
|
33993
|
+
const response = await client.listSessionToolExchanges(sessionId, {
|
|
33592
33994
|
apiBaseUrl: apiUrlFromOptions(context, options),
|
|
33593
33995
|
toolName: options.tool,
|
|
33594
33996
|
errorsOnly: options.errors,
|
|
@@ -33596,7 +33998,7 @@ async function handleRunsTools(context, runId, options = {}) {
|
|
|
33596
33998
|
before: options.before,
|
|
33597
33999
|
limit: options.limit
|
|
33598
34000
|
});
|
|
33599
|
-
context.io.writeResult({
|
|
34001
|
+
context.io.writeResult({ sessionId, ...response }, formatToolsText);
|
|
33600
34002
|
}
|
|
33601
34003
|
function formatToolsText(result, writeLine, style) {
|
|
33602
34004
|
if (result.exchanges.length === 0) {
|
|
@@ -33626,12 +34028,12 @@ function exchangeOutcome(style, isError) {
|
|
|
33626
34028
|
}
|
|
33627
34029
|
return isError ? style.error("ERR") : style.success("ok");
|
|
33628
34030
|
}
|
|
33629
|
-
async function handleRunsTriggers(context,
|
|
34031
|
+
async function handleRunsTriggers(context, sessionId, options = {}) {
|
|
33630
34032
|
const client = createContextApiClient(context);
|
|
33631
|
-
const response = await client.
|
|
34033
|
+
const response = await client.listSessionTriggers(sessionId, {
|
|
33632
34034
|
apiBaseUrl: apiUrlFromOptions(context, options)
|
|
33633
34035
|
});
|
|
33634
|
-
context.io.writeResult({
|
|
34036
|
+
context.io.writeResult({ sessionId, ...response }, formatTriggersText);
|
|
33635
34037
|
}
|
|
33636
34038
|
function formatTriggersText(result, writeLine, style) {
|
|
33637
34039
|
if (result.spawn) {
|
|
@@ -33642,7 +34044,7 @@ function formatTriggersText(result, writeLine, style) {
|
|
|
33642
34044
|
);
|
|
33643
34045
|
} else if (result.starter) {
|
|
33644
34046
|
writeLine(
|
|
33645
|
-
`${style.label("spawn:")} ${result.starter.principal.kind === "
|
|
34047
|
+
`${style.label("spawn:")} ${result.starter.principal.kind === "session" ? "agent" : "manual"} ${style.dim(`starter=${JSON.stringify(result.starter.principal)}`)}`
|
|
33646
34048
|
);
|
|
33647
34049
|
} else {
|
|
33648
34050
|
writeLine(`${style.label("spawn:")} manual`);
|
|
@@ -33658,12 +34060,12 @@ function formatTriggersText(result, writeLine, style) {
|
|
|
33658
34060
|
);
|
|
33659
34061
|
}
|
|
33660
34062
|
}
|
|
33661
|
-
async function handleRunsArtifacts(context,
|
|
34063
|
+
async function handleRunsArtifacts(context, sessionId, options = {}) {
|
|
33662
34064
|
const client = createContextApiClient(context);
|
|
33663
|
-
const response = await client.listRunArtifacts(
|
|
34065
|
+
const response = await client.listRunArtifacts(sessionId, {
|
|
33664
34066
|
apiBaseUrl: apiUrlFromOptions(context, options)
|
|
33665
34067
|
});
|
|
33666
|
-
context.io.writeResult({
|
|
34068
|
+
context.io.writeResult({ sessionId, ...response }, formatArtifactsText);
|
|
33667
34069
|
}
|
|
33668
34070
|
function formatArtifactsText(result, writeLine, style) {
|
|
33669
34071
|
if (result.artifacts.length === 0) {
|
|
@@ -33678,12 +34080,12 @@ function formatArtifactsText(result, writeLine, style) {
|
|
|
33678
34080
|
);
|
|
33679
34081
|
}
|
|
33680
34082
|
}
|
|
33681
|
-
async function handleRunsCommands(context,
|
|
34083
|
+
async function handleRunsCommands(context, sessionId, options = {}) {
|
|
33682
34084
|
const client = createContextApiClient(context);
|
|
33683
|
-
const response = await client.
|
|
34085
|
+
const response = await client.listSessionCommands(sessionId, {
|
|
33684
34086
|
apiBaseUrl: apiUrlFromOptions(context, options)
|
|
33685
34087
|
});
|
|
33686
|
-
context.io.writeResult({
|
|
34088
|
+
context.io.writeResult({ sessionId, ...response }, formatCommandsText);
|
|
33687
34089
|
}
|
|
33688
34090
|
function formatCommandsText(result, writeLine, style) {
|
|
33689
34091
|
if (result.commands.length === 0) {
|
|
@@ -33748,21 +34150,29 @@ function clip(text) {
|
|
|
33748
34150
|
return text.length > PREVIEW_CHARS ? `${text.slice(0, PREVIEW_CHARS)}\u2026` : text;
|
|
33749
34151
|
}
|
|
33750
34152
|
|
|
33751
|
-
// src/commands/
|
|
34153
|
+
// src/commands/sessions/commands.ts
|
|
33752
34154
|
function collect(value, previous = []) {
|
|
33753
34155
|
return [...previous, value];
|
|
33754
34156
|
}
|
|
33755
|
-
function
|
|
33756
|
-
const
|
|
33757
|
-
|
|
34157
|
+
function registerSessionCommands(program, context) {
|
|
34158
|
+
const sessions = program.command("sessions").description("Inspect agent sessions.");
|
|
34159
|
+
sessions.command("list").description("List sessions for an agent or the whole project.").option("--agent <name>", "agent name").option("--include-archived", "include archived sessions").option(
|
|
34160
|
+
"--status <status>",
|
|
34161
|
+
"filter by session status (repeatable)",
|
|
34162
|
+
collect
|
|
34163
|
+
).option("--since <iso-timestamp>", "only sessions created after this time").option(
|
|
34164
|
+
"--limit <count>",
|
|
34165
|
+
"maximum sessions to return",
|
|
34166
|
+
parsePositiveInteger
|
|
34167
|
+
).option("--api-url <url>", "Auto API base URL").option("--api-base-url <url>", "Auto API base URL").action(async (options) => {
|
|
33758
34168
|
await handleRunsList(context, options.agent, options);
|
|
33759
34169
|
});
|
|
33760
|
-
|
|
33761
|
-
await handleRunsShow(context,
|
|
34170
|
+
sessions.command("show").description("Show a session's lifecycle, timing, and behavior summary.").argument("<session-id>", "session id").option("--api-url <url>", "Auto API base URL").option("--api-base-url <url>", "Auto API base URL").action(async (sessionId, commandOptions) => {
|
|
34171
|
+
await handleRunsShow(context, sessionId, commandOptions);
|
|
33762
34172
|
});
|
|
33763
|
-
|
|
33764
|
-
"Read a snapshot of a
|
|
33765
|
-
).argument("<
|
|
34173
|
+
sessions.command("conversation").description(
|
|
34174
|
+
"Read a snapshot of a session's conversation (most recent entries by default)."
|
|
34175
|
+
).argument("<session-id>", "session id").option(
|
|
33766
34176
|
"--tail <count>",
|
|
33767
34177
|
"number of most recent entries",
|
|
33768
34178
|
parsePositiveInteger
|
|
@@ -33771,20 +34181,22 @@ function registerRunCommands(program, context) {
|
|
|
33771
34181
|
"only entries older than this sequence (backward paging)",
|
|
33772
34182
|
parsePositiveInteger
|
|
33773
34183
|
).option("--kind <kind>", "filter by entry kind (repeatable)", collect).option("--full", "do not clip entry previews in text output").option("--api-url <url>", "Auto API base URL").option("--api-base-url <url>", "Auto API base URL").action(
|
|
33774
|
-
async (
|
|
33775
|
-
await handleRunsConversation(context,
|
|
34184
|
+
async (sessionId, commandOptions) => {
|
|
34185
|
+
await handleRunsConversation(context, sessionId, commandOptions);
|
|
33776
34186
|
}
|
|
33777
34187
|
);
|
|
33778
|
-
|
|
34188
|
+
sessions.command("search").description(
|
|
34189
|
+
"Grep a session's transcript; multiple query terms OR together."
|
|
34190
|
+
).argument("<session-id>", "session id").argument("<query...>", "search term(s), at least 2 characters each").option("--kind <kind>", "filter by entry kind (repeatable)", collect).option(
|
|
33779
34191
|
"--after <sequence>",
|
|
33780
34192
|
"only entries after this sequence (forward paging)",
|
|
33781
34193
|
parsePositiveInteger
|
|
33782
34194
|
).option("--limit <count>", "maximum matched entries", parsePositiveInteger).option("--api-url <url>", "Auto API base URL").option("--api-base-url <url>", "Auto API base URL").action(
|
|
33783
|
-
async (
|
|
33784
|
-
await handleRunsSearch(context,
|
|
34195
|
+
async (sessionId, queries, commandOptions) => {
|
|
34196
|
+
await handleRunsSearch(context, sessionId, queries, commandOptions);
|
|
33785
34197
|
}
|
|
33786
34198
|
);
|
|
33787
|
-
|
|
34199
|
+
sessions.command("tools").description("List a session's paired tool calls and results with timing.").argument("<session-id>", "session id").option("--tool <name>", "filter by tool name").option("--errors", "only failed exchanges").option(
|
|
33788
34200
|
"--after <sequence>",
|
|
33789
34201
|
"only exchanges after this entry sequence",
|
|
33790
34202
|
parsePositiveInteger
|
|
@@ -33793,37 +34205,49 @@ function registerRunCommands(program, context) {
|
|
|
33793
34205
|
"only exchanges before this entry sequence (backward paging)",
|
|
33794
34206
|
parsePositiveInteger
|
|
33795
34207
|
).option("--limit <count>", "maximum exchanges", parsePositiveInteger).option("--api-url <url>", "Auto API base URL").option("--api-base-url <url>", "Auto API base URL").action(
|
|
33796
|
-
async (
|
|
33797
|
-
await handleRunsTools(context,
|
|
34208
|
+
async (sessionId, commandOptions) => {
|
|
34209
|
+
await handleRunsTools(context, sessionId, commandOptions);
|
|
33798
34210
|
}
|
|
33799
34211
|
);
|
|
33800
|
-
|
|
33801
|
-
await handleRunsTriggers(context,
|
|
34212
|
+
sessions.command("triggers").description("Show what spawned a session and the events delivered to it.").argument("<session-id>", "session id").option("--api-url <url>", "Auto API base URL").option("--api-base-url <url>", "Auto API base URL").action(async (sessionId, commandOptions) => {
|
|
34213
|
+
await handleRunsTriggers(context, sessionId, commandOptions);
|
|
33802
34214
|
});
|
|
33803
|
-
|
|
33804
|
-
await handleRunsArtifacts(context,
|
|
34215
|
+
sessions.command("artifacts").description("List artifacts a session currently owns.").argument("<session-id>", "session id").option("--api-url <url>", "Auto API base URL").option("--api-base-url <url>", "Auto API base URL").action(async (sessionId, commandOptions) => {
|
|
34216
|
+
await handleRunsArtifacts(context, sessionId, commandOptions);
|
|
33805
34217
|
});
|
|
33806
|
-
|
|
33807
|
-
await handleRunsCommands(context,
|
|
34218
|
+
sessions.command("commands").description("List a session's inbound command history.").argument("<session-id>", "session id").option("--api-url <url>", "Auto API base URL").option("--api-base-url <url>", "Auto API base URL").action(async (sessionId, commandOptions) => {
|
|
34219
|
+
await handleRunsCommands(context, sessionId, commandOptions);
|
|
33808
34220
|
});
|
|
33809
|
-
|
|
33810
|
-
|
|
33811
|
-
|
|
34221
|
+
sessions.command("archive").description(
|
|
34222
|
+
"Archive sessions so they are hidden from default session lists."
|
|
34223
|
+
).argument("<session-ids...>", "session id(s)").option("--api-url <url>", "Auto API base URL").option("--api-base-url <url>", "Auto API base URL").action(async (sessionIds, commandOptions) => {
|
|
34224
|
+
if (sessionIds.length === 1) {
|
|
34225
|
+
await archiveSessionAction(
|
|
34226
|
+
context,
|
|
34227
|
+
sessionIds[0],
|
|
34228
|
+
commandOptions
|
|
34229
|
+
);
|
|
33812
34230
|
return;
|
|
33813
34231
|
}
|
|
33814
|
-
await
|
|
34232
|
+
await archiveSessionsAction(context, sessionIds, commandOptions);
|
|
33815
34233
|
});
|
|
33816
|
-
|
|
33817
|
-
if (
|
|
33818
|
-
await
|
|
34234
|
+
sessions.command("unarchive").description("Restore archived sessions to default session lists.").argument("<session-ids...>", "session id(s)").option("--api-url <url>", "Auto API base URL").option("--api-base-url <url>", "Auto API base URL").action(async (sessionIds, commandOptions) => {
|
|
34235
|
+
if (sessionIds.length === 1) {
|
|
34236
|
+
await unarchiveSessionAction(
|
|
34237
|
+
context,
|
|
34238
|
+
sessionIds[0],
|
|
34239
|
+
commandOptions
|
|
34240
|
+
);
|
|
33819
34241
|
return;
|
|
33820
34242
|
}
|
|
33821
|
-
await
|
|
33822
|
-
});
|
|
33823
|
-
runs.command("stop").description("Stop live runs and shut down their agent agents.").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) => {
|
|
33824
|
-
await stopRunsAction(context, runIds, commandOptions);
|
|
34243
|
+
await unarchiveSessionsAction(context, sessionIds, commandOptions);
|
|
33825
34244
|
});
|
|
33826
|
-
|
|
34245
|
+
sessions.command("stop").description("Stop live sessions and shut down their agent agents.").argument("<session-ids...>", "session 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(
|
|
34246
|
+
async (sessionIds, commandOptions) => {
|
|
34247
|
+
await stopSessionsAction(context, sessionIds, commandOptions);
|
|
34248
|
+
}
|
|
34249
|
+
);
|
|
34250
|
+
sessions.command("benchmark-startup").description("Launch an agent session and measure time until awaiting.").requiredOption("--agent <name>", "agent name").option("-m, --message <message>", "initial message for the session").option(
|
|
33827
34251
|
"--interactive",
|
|
33828
34252
|
"start without the default initial prompt unless --message is provided"
|
|
33829
34253
|
).option(
|
|
@@ -33832,7 +34256,7 @@ function registerRunCommands(program, context) {
|
|
|
33832
34256
|
parsePositiveInteger
|
|
33833
34257
|
).option(
|
|
33834
34258
|
"--poll-interval-ms <ms>",
|
|
33835
|
-
"
|
|
34259
|
+
"session status polling interval",
|
|
33836
34260
|
parsePositiveInteger
|
|
33837
34261
|
).option(
|
|
33838
34262
|
"--threshold-ms <ms>",
|
|
@@ -33845,343 +34269,30 @@ function registerRunCommands(program, context) {
|
|
|
33845
34269
|
).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) => {
|
|
33846
34270
|
await benchmarkStartupAction(context, options);
|
|
33847
34271
|
});
|
|
33848
|
-
program.command("interactive").description("Launch an agent
|
|
34272
|
+
program.command("interactive").description("Launch an agent session, stream it, and send typed messages.").argument("<agent>", "agent name").option("-m, --message <message>", "initial message for the session").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(
|
|
33849
34273
|
"--attach-message",
|
|
33850
|
-
"send the automated attach message after creating the
|
|
34274
|
+
"send the automated attach message after creating the session"
|
|
33851
34275
|
).option("--no-attach-message", "do not send the automated attach message").option("--no-detach-message", "do not send the automated detach message").action(
|
|
33852
34276
|
async (agentName, commandOptions) => {
|
|
33853
34277
|
await interactiveRunAction(context, agentName, commandOptions);
|
|
33854
34278
|
}
|
|
33855
34279
|
);
|
|
33856
|
-
program.command("attach").description("Stream an existing
|
|
33857
|
-
await attachRunAction(context,
|
|
33858
|
-
});
|
|
33859
|
-
program.command("console").description("Attach to a live run, stream it, and send typed messages.").argument("<run-id>", "run id").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("--no-attach-message", "do not send the automated attach message").option("--no-detach-message", "do not send the automated detach message").action(async (runId, commandOptions) => {
|
|
33860
|
-
await consoleRunAction(context, runId, commandOptions);
|
|
33861
|
-
});
|
|
33862
|
-
program.command("send").description("Send a message command to a resumable run.").argument("<run-id>", "run id").argument("<message>", "message to send").option("--api-url <url>", "Auto API base URL").option("--api-base-url <url>", "Auto API base URL").action(
|
|
33863
|
-
async (runId, message, commandOptions) => {
|
|
33864
|
-
await sendRunMessageAction(context, runId, message, commandOptions);
|
|
33865
|
-
}
|
|
33866
|
-
);
|
|
33867
|
-
}
|
|
33868
|
-
|
|
33869
|
-
// src/commands/secrets/actions.ts
|
|
33870
|
-
async function setSecret(input) {
|
|
33871
|
-
const value = await secretValue({
|
|
33872
|
-
options: input.commandOptions,
|
|
33873
|
-
env: input.context.env,
|
|
33874
|
-
stdin: input.context.stdin
|
|
33875
|
-
});
|
|
33876
|
-
const response = await input.client.setSecret(
|
|
33877
|
-
input.name,
|
|
33878
|
-
{ value },
|
|
33879
|
-
{
|
|
33880
|
-
projectId: await secretProjectId(input),
|
|
33881
|
-
apiBaseUrl: input.commandOptions.apiBaseUrl
|
|
33882
|
-
}
|
|
33883
|
-
);
|
|
33884
|
-
writeSetResponse(response, input);
|
|
33885
|
-
}
|
|
33886
|
-
async function listSecrets(input) {
|
|
33887
|
-
const response = await input.client.listSecrets({
|
|
33888
|
-
projectId: await secretProjectId(input),
|
|
33889
|
-
apiBaseUrl: input.commandOptions.apiBaseUrl
|
|
33890
|
-
});
|
|
33891
|
-
if (input.commandOptions.json) {
|
|
33892
|
-
input.context.writeOutput(JSON.stringify(response));
|
|
33893
|
-
return;
|
|
33894
|
-
}
|
|
33895
|
-
if (response.secrets.length === 0) {
|
|
33896
|
-
input.context.writeOutput("No secrets found.");
|
|
33897
|
-
return;
|
|
33898
|
-
}
|
|
33899
|
-
for (const secret of response.secrets) {
|
|
33900
|
-
input.context.writeOutput(
|
|
33901
|
-
`${secret.name} ${scopeLabel(secret.projectId)} updated ${secret.updatedAt}`
|
|
33902
|
-
);
|
|
33903
|
-
}
|
|
33904
|
-
}
|
|
33905
|
-
async function removeSecret(input) {
|
|
33906
|
-
await confirmDestructiveAction(input.context, {
|
|
33907
|
-
message: `This will remove secret "${input.name}".`,
|
|
33908
|
-
yes: input.commandOptions.yes
|
|
33909
|
-
});
|
|
33910
|
-
const response = await input.client.removeSecret(input.name, {
|
|
33911
|
-
projectId: await secretProjectId(input),
|
|
33912
|
-
apiBaseUrl: input.commandOptions.apiBaseUrl
|
|
33913
|
-
});
|
|
33914
|
-
writeRemoveResponse(response, input);
|
|
33915
|
-
}
|
|
33916
|
-
async function secretProjectId(input) {
|
|
33917
|
-
if (!input.commandOptions.project) {
|
|
33918
|
-
return void 0;
|
|
33919
|
-
}
|
|
33920
|
-
const scope = await requireProjectScope({
|
|
33921
|
-
context: input.context,
|
|
33922
|
-
options: input.commandOptions,
|
|
33923
|
-
identifier: input.commandOptions.project,
|
|
33924
|
-
explicitHint: "--project <project>"
|
|
33925
|
-
});
|
|
33926
|
-
return scope.projectId;
|
|
33927
|
-
}
|
|
33928
|
-
async function secretValue(input) {
|
|
33929
|
-
const sources = [
|
|
33930
|
-
input.options.stdin ? "stdin" : void 0,
|
|
33931
|
-
input.options.value !== void 0 ? "value" : void 0,
|
|
33932
|
-
input.options.fromEnv ? "from-env" : void 0
|
|
33933
|
-
].filter(Boolean);
|
|
33934
|
-
if (sources.length > 1) {
|
|
33935
|
-
throw new Error("Use only one of --stdin, --value, or --from-env.");
|
|
33936
|
-
}
|
|
33937
|
-
let value;
|
|
33938
|
-
if (input.options.value !== void 0) {
|
|
33939
|
-
value = input.options.value;
|
|
33940
|
-
} else if (input.options.fromEnv) {
|
|
33941
|
-
const envValue = input.env[input.options.fromEnv];
|
|
33942
|
-
if (envValue === void 0) {
|
|
33943
|
-
throw new Error(`Environment variable not set: ${input.options.fromEnv}`);
|
|
33944
|
-
}
|
|
33945
|
-
value = envValue;
|
|
33946
|
-
} else if (input.options.stdin) {
|
|
33947
|
-
value = await readStream2(input.stdin, Boolean(input.options.raw));
|
|
33948
|
-
} else {
|
|
33949
|
-
throw new Error(
|
|
33950
|
-
"Provide the secret value with --stdin, --value, or --from-env."
|
|
33951
|
-
);
|
|
33952
|
-
}
|
|
33953
|
-
if (value.length === 0 && !input.options.raw) {
|
|
33954
|
-
throw new Error(
|
|
33955
|
-
"Secret value is empty. Pass --raw to store an empty value."
|
|
33956
|
-
);
|
|
33957
|
-
}
|
|
33958
|
-
return value;
|
|
33959
|
-
}
|
|
33960
|
-
async function readStream2(stream, raw) {
|
|
33961
|
-
const chunks = [];
|
|
33962
|
-
for await (const chunk of stream) {
|
|
33963
|
-
chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(String(chunk)));
|
|
33964
|
-
}
|
|
33965
|
-
const value = Buffer.concat(chunks).toString("utf8");
|
|
33966
|
-
return raw ? value : value.replace(/\r?\n$/, "");
|
|
33967
|
-
}
|
|
33968
|
-
function writeSetResponse(response, input) {
|
|
33969
|
-
if (input.commandOptions.json) {
|
|
33970
|
-
input.context.writeOutput(JSON.stringify(response));
|
|
33971
|
-
return;
|
|
33972
|
-
}
|
|
33973
|
-
input.context.writeOutput(
|
|
33974
|
-
`secret ${response.secret.name} updated scope=${scopeLabel(response.secret.projectId)}`
|
|
33975
|
-
);
|
|
33976
|
-
}
|
|
33977
|
-
function writeRemoveResponse(response, input) {
|
|
33978
|
-
if (input.commandOptions.json) {
|
|
33979
|
-
input.context.writeOutput(JSON.stringify(response));
|
|
33980
|
-
return;
|
|
33981
|
-
}
|
|
33982
|
-
input.context.writeOutput(
|
|
33983
|
-
`secret ${response.secret.name} removed scope=${scopeLabel(response.secret.projectId)}`
|
|
33984
|
-
);
|
|
33985
|
-
}
|
|
33986
|
-
function scopeLabel(projectId) {
|
|
33987
|
-
return projectId ? `project:${projectId}` : "organization";
|
|
33988
|
-
}
|
|
33989
|
-
|
|
33990
|
-
// src/commands/secrets/commands.ts
|
|
33991
|
-
function registerSecretCommands(program, context) {
|
|
33992
|
-
const secrets = program.command("secrets").description("Manage Auto organization and project secrets.");
|
|
33993
|
-
secrets.command("set").description("Create or update a secret without printing its value.").argument("<name>", "secret name").option("--project <project>", "project id; defaults to organization scope").option("--stdin", "read the secret value from stdin").option("--value <value>", "secret value").option(
|
|
33994
|
-
"--from-env <name>",
|
|
33995
|
-
"read the secret value from an environment variable"
|
|
33996
|
-
).option("--raw", "allow empty values and preserve stdin exactly").option("--json", "print the updated secret metadata as JSON").option("--api-url <url>", "Auto API base URL").option("--api-base-url <url>", "Auto API base URL").action(async (name, commandOptions) => {
|
|
33997
|
-
await setSecret({
|
|
33998
|
-
client: createContextApiClient(context),
|
|
33999
|
-
commandOptions: withApiBaseUrl(context, commandOptions),
|
|
34000
|
-
context,
|
|
34001
|
-
name
|
|
34002
|
-
});
|
|
34003
|
-
});
|
|
34004
|
-
secrets.command("list").alias("ls").description("List secret metadata.").option("--project <project>", "project id; defaults to organization scope").option("--json", "print secret metadata as JSON").option("--api-url <url>", "Auto API base URL").option("--api-base-url <url>", "Auto API base URL").action(async (commandOptions) => {
|
|
34005
|
-
await listSecrets({
|
|
34006
|
-
client: createContextApiClient(context),
|
|
34007
|
-
commandOptions: withApiBaseUrl(context, commandOptions),
|
|
34008
|
-
context
|
|
34009
|
-
});
|
|
34280
|
+
program.command("attach").description("Stream an existing session conversation.").argument("<session-id>", "session id").option("--api-url <url>", "Auto API base URL").option("--api-base-url <url>", "Auto API base URL").action(async (sessionId, commandOptions) => {
|
|
34281
|
+
await attachRunAction(context, sessionId, commandOptions);
|
|
34010
34282
|
});
|
|
34011
|
-
|
|
34012
|
-
|
|
34013
|
-
|
|
34014
|
-
|
|
34015
|
-
context,
|
|
34016
|
-
name
|
|
34017
|
-
});
|
|
34018
|
-
});
|
|
34019
|
-
}
|
|
34020
|
-
function withApiBaseUrl(context, commandOptions) {
|
|
34021
|
-
return {
|
|
34022
|
-
...commandOptions,
|
|
34023
|
-
apiBaseUrl: apiUrlFromOptions(context, commandOptions)
|
|
34024
|
-
};
|
|
34025
|
-
}
|
|
34026
|
-
|
|
34027
|
-
// src/commands/service-accounts/actions.ts
|
|
34028
|
-
init_src();
|
|
34029
|
-
async function createServiceAccount(input) {
|
|
34030
|
-
const response = await input.client.createProjectServiceAccount(
|
|
34031
|
-
{ name: input.name, scopes: requestedScopes(input.commandOptions) },
|
|
34032
|
-
{ apiBaseUrl: input.commandOptions.apiBaseUrl }
|
|
34033
|
-
);
|
|
34034
|
-
writeServiceAccountTokenResponse(response, input);
|
|
34035
|
-
}
|
|
34036
|
-
async function updateServiceAccount(input) {
|
|
34037
|
-
const response = await input.client.updateProjectServiceAccount(
|
|
34038
|
-
{ name: input.name, scopes: requestedScopes(input.commandOptions) },
|
|
34039
|
-
{ apiBaseUrl: input.commandOptions.apiBaseUrl }
|
|
34040
|
-
);
|
|
34041
|
-
if (input.commandOptions.json) {
|
|
34042
|
-
input.writeOutput(JSON.stringify(response));
|
|
34043
|
-
return;
|
|
34044
|
-
}
|
|
34045
|
-
writeServiceAccountScopesResponse(response, input.writeOutput);
|
|
34046
|
-
}
|
|
34047
|
-
async function rotateServiceAccount(input) {
|
|
34048
|
-
const response = await input.client.rotateProjectServiceAccountToken(
|
|
34049
|
-
{ name: input.name },
|
|
34050
|
-
{ apiBaseUrl: input.commandOptions.apiBaseUrl }
|
|
34051
|
-
);
|
|
34052
|
-
writeServiceAccountTokenResponse(response, input);
|
|
34053
|
-
}
|
|
34054
|
-
async function removeServiceAccount(input) {
|
|
34055
|
-
const response = await input.client.removeProjectServiceAccount(
|
|
34056
|
-
{ name: input.name },
|
|
34057
|
-
{ apiBaseUrl: input.commandOptions.apiBaseUrl }
|
|
34058
|
-
);
|
|
34059
|
-
if (input.commandOptions.json) {
|
|
34060
|
-
input.writeOutput(JSON.stringify(response));
|
|
34061
|
-
return;
|
|
34062
|
-
}
|
|
34063
|
-
input.writeOutput(`removed service-account ${response.serviceAccount.name}`);
|
|
34064
|
-
}
|
|
34065
|
-
function requestedScopes(options) {
|
|
34066
|
-
const presetNames = Object.keys(SERVICE_ACCOUNT_SCOPE_PRESETS).join(", ");
|
|
34067
|
-
const scopes = [];
|
|
34068
|
-
if (options.preset !== void 0) {
|
|
34069
|
-
const preset = ServiceAccountScopePresetSchema.safeParse(options.preset);
|
|
34070
|
-
if (!preset.success) {
|
|
34071
|
-
throw new Error(
|
|
34072
|
-
`Unknown preset "${options.preset}". Available presets: ${presetNames}.`
|
|
34073
|
-
);
|
|
34074
|
-
}
|
|
34075
|
-
scopes.push(...SERVICE_ACCOUNT_SCOPE_PRESETS[preset.data]);
|
|
34076
|
-
}
|
|
34077
|
-
for (const scope of options.scope ?? []) {
|
|
34078
|
-
if (!AuthScopeSchema.safeParse(scope).success) {
|
|
34079
|
-
throw new Error(
|
|
34080
|
-
`Unknown scope "${scope}". Valid scopes: ${AUTH_SCOPES.join(", ")}.`
|
|
34081
|
-
);
|
|
34082
|
-
}
|
|
34083
|
-
scopes.push(scope);
|
|
34084
|
-
}
|
|
34085
|
-
if (scopes.length === 0) {
|
|
34086
|
-
throw new Error(
|
|
34087
|
-
`Provide --preset <preset> (${presetNames}) or at least one --scope.`
|
|
34088
|
-
);
|
|
34089
|
-
}
|
|
34090
|
-
return [...new Set(scopes)];
|
|
34091
|
-
}
|
|
34092
|
-
function writeServiceAccountTokenResponse(response, input) {
|
|
34093
|
-
if (input.commandOptions.json) {
|
|
34094
|
-
input.writeOutput(JSON.stringify(response));
|
|
34095
|
-
return;
|
|
34096
|
-
}
|
|
34097
|
-
input.writeOutput(`service-account ${response.serviceAccount.name}`);
|
|
34098
|
-
input.writeOutput(
|
|
34099
|
-
`scopes ${response.serviceAccount.scopes.join(", ") || "(none)"}`
|
|
34100
|
-
);
|
|
34101
|
-
input.writeOutput(`token ${response.token}`);
|
|
34102
|
-
}
|
|
34103
|
-
function writeServiceAccountScopesResponse(response, writeOutput) {
|
|
34104
|
-
writeOutput(`service-account ${response.serviceAccount.name}`);
|
|
34105
|
-
writeOutput(
|
|
34106
|
-
`scopes ${response.serviceAccount.scopes.join(", ") || "(none)"}`
|
|
34107
|
-
);
|
|
34108
|
-
}
|
|
34109
|
-
|
|
34110
|
-
// src/commands/service-accounts/commands.ts
|
|
34111
|
-
function registerServiceAccountCommands(program, context) {
|
|
34112
|
-
const serviceAccount = program.command("service-account").description("Manage Auto project service accounts.");
|
|
34113
|
-
serviceAccount.command("create").description("Create a project service account and print its token.").argument("<name>", "service account name").option(
|
|
34114
|
-
"--preset <preset>",
|
|
34115
|
-
"grant a named scope bundle (read-only, applier)"
|
|
34116
|
-
).option(
|
|
34117
|
-
"--scope <scope>",
|
|
34118
|
-
"grant a scope; repeat to grant multiple scopes",
|
|
34119
|
-
collectScopes
|
|
34120
|
-
).option("--json", "print the created service account as JSON").option("--api-url <url>", "Auto API base URL").option("--api-base-url <url>", "Auto API base URL").action(
|
|
34121
|
-
async (name, commandOptions) => {
|
|
34122
|
-
await createServiceAccount({
|
|
34123
|
-
client: createContextApiClient(context),
|
|
34124
|
-
commandOptions: withApiBaseUrl2(context, commandOptions),
|
|
34125
|
-
name,
|
|
34126
|
-
writeOutput: context.writeOutput
|
|
34127
|
-
});
|
|
34128
|
-
}
|
|
34129
|
-
);
|
|
34130
|
-
serviceAccount.command("update").description("Update project service account scopes.").argument("<name>", "service account name").option(
|
|
34131
|
-
"--preset <preset>",
|
|
34132
|
-
"grant a named scope bundle (read-only, applier)"
|
|
34133
|
-
).option(
|
|
34134
|
-
"--scope <scope>",
|
|
34135
|
-
"grant a scope; repeat to grant multiple scopes",
|
|
34136
|
-
collectScopes
|
|
34137
|
-
).option("--json", "print the updated service account as JSON").option("--api-url <url>", "Auto API base URL").option("--api-base-url <url>", "Auto API base URL").action(
|
|
34138
|
-
async (name, commandOptions) => {
|
|
34139
|
-
await updateServiceAccount({
|
|
34140
|
-
client: createContextApiClient(context),
|
|
34141
|
-
commandOptions: withApiBaseUrl2(context, commandOptions),
|
|
34142
|
-
name,
|
|
34143
|
-
writeOutput: context.writeOutput
|
|
34144
|
-
});
|
|
34145
|
-
}
|
|
34146
|
-
);
|
|
34147
|
-
serviceAccount.command("rotate").description("Rotate a project service account token.").argument("<name>", "service account name").option("--json", "print the service account token as JSON").option("-y, --yes", "skip confirmation prompt").option("--api-url <url>", "Auto API base URL").option("--api-base-url <url>", "Auto API base URL").action(
|
|
34148
|
-
async (name, commandOptions) => {
|
|
34149
|
-
await confirmDestructiveAction(context, {
|
|
34150
|
-
message: `This will rotate service account "${name}" and revoke its current token.`,
|
|
34151
|
-
yes: commandOptions.yes
|
|
34152
|
-
});
|
|
34153
|
-
await rotateServiceAccount({
|
|
34154
|
-
client: createContextApiClient(context),
|
|
34155
|
-
commandOptions: withApiBaseUrl2(context, commandOptions),
|
|
34156
|
-
name,
|
|
34157
|
-
writeOutput: context.writeOutput
|
|
34158
|
-
});
|
|
34283
|
+
program.command("console").description(
|
|
34284
|
+
"Attach to a live session, stream it, and send typed messages."
|
|
34285
|
+
).argument("<session-id>", "session id").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("--no-attach-message", "do not send the automated attach message").option("--no-detach-message", "do not send the automated detach message").action(
|
|
34286
|
+
async (sessionId, commandOptions) => {
|
|
34287
|
+
await consoleRunAction(context, sessionId, commandOptions);
|
|
34159
34288
|
}
|
|
34160
34289
|
);
|
|
34161
|
-
|
|
34162
|
-
async (
|
|
34163
|
-
await
|
|
34164
|
-
message: `This will remove service account "${name}" and revoke its token.`,
|
|
34165
|
-
yes: commandOptions.yes
|
|
34166
|
-
});
|
|
34167
|
-
await removeServiceAccount({
|
|
34168
|
-
client: createContextApiClient(context),
|
|
34169
|
-
commandOptions: withApiBaseUrl2(context, commandOptions),
|
|
34170
|
-
name,
|
|
34171
|
-
writeOutput: context.writeOutput
|
|
34172
|
-
});
|
|
34290
|
+
program.command("send").description("Send a message command to a resumable session.").argument("<session-id>", "session id").argument("<message>", "message to send").option("--api-url <url>", "Auto API base URL").option("--api-base-url <url>", "Auto API base URL").action(
|
|
34291
|
+
async (sessionId, message, commandOptions) => {
|
|
34292
|
+
await sendRunMessageAction(context, sessionId, message, commandOptions);
|
|
34173
34293
|
}
|
|
34174
34294
|
);
|
|
34175
34295
|
}
|
|
34176
|
-
function collectScopes(scope, scopes) {
|
|
34177
|
-
return [...scopes ?? [], scope];
|
|
34178
|
-
}
|
|
34179
|
-
function withApiBaseUrl2(context, commandOptions) {
|
|
34180
|
-
return {
|
|
34181
|
-
...commandOptions,
|
|
34182
|
-
apiBaseUrl: apiUrlFromOptions(context, commandOptions)
|
|
34183
|
-
};
|
|
34184
|
-
}
|
|
34185
34296
|
|
|
34186
34297
|
// src/commands/sync/repo.ts
|
|
34187
34298
|
import { execFile as execFileWithCallback } from "child_process";
|
|
@@ -34480,7 +34591,7 @@ function createProgram(options = {}) {
|
|
|
34480
34591
|
registerSecretCommands(program, context);
|
|
34481
34592
|
registerSyncCommands(program, context);
|
|
34482
34593
|
registerAgentCommands(program, context);
|
|
34483
|
-
|
|
34594
|
+
registerSessionCommands(program, context);
|
|
34484
34595
|
return program;
|
|
34485
34596
|
}
|
|
34486
34597
|
|