@autohq/cli 0.1.147 → 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 +205 -193
- package/dist/index.js +1264 -1161
- 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,12 +16378,12 @@ 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(),
|
|
@@ -16768,7 +16768,7 @@ var init_conversation = __esm({
|
|
|
16768
16768
|
ConversationEntryEventSchema = external_exports.object({
|
|
16769
16769
|
type: external_exports.literal("conversation.entry"),
|
|
16770
16770
|
id: external_exports.string().min(1),
|
|
16771
|
-
|
|
16771
|
+
sessionId: SessionIdSchema,
|
|
16772
16772
|
sequence: external_exports.number().int().nonnegative(),
|
|
16773
16773
|
messageId: external_exports.string().min(1).optional(),
|
|
16774
16774
|
role: ConversationRoleSchema,
|
|
@@ -16785,7 +16785,7 @@ var init_conversation = __esm({
|
|
|
16785
16785
|
ConversationDeltaEventSchema = external_exports.object({
|
|
16786
16786
|
type: external_exports.literal("conversation.delta"),
|
|
16787
16787
|
id: external_exports.string().min(1),
|
|
16788
|
-
|
|
16788
|
+
sessionId: SessionIdSchema,
|
|
16789
16789
|
sequence: external_exports.number().int().nonnegative(),
|
|
16790
16790
|
messageId: external_exports.string().min(1),
|
|
16791
16791
|
partId: external_exports.string().min(1),
|
|
@@ -17090,7 +17090,7 @@ function syntheticDeltaEntry(event) {
|
|
|
17090
17090
|
return {
|
|
17091
17091
|
type: "conversation.entry",
|
|
17092
17092
|
id: `delta:${event.messageId}`,
|
|
17093
|
-
|
|
17093
|
+
sessionId: event.sessionId,
|
|
17094
17094
|
sequence: event.sequence,
|
|
17095
17095
|
messageId: event.messageId,
|
|
17096
17096
|
role: event.role,
|
|
@@ -17814,8 +17814,11 @@ var init_trigger_router = __esm({
|
|
|
17814
17814
|
external_exports.object({
|
|
17815
17815
|
kind: external_exports.literal("allLiveRuns")
|
|
17816
17816
|
}),
|
|
17817
|
-
// Use
|
|
17817
|
+
// Use attributedSessions for follow-up delivery only. Spawn triggers that can
|
|
17818
17818
|
// overlap with attributed events should filter `$.auto.attributions` out.
|
|
17819
|
+
external_exports.object({
|
|
17820
|
+
kind: external_exports.literal("attributedSessions")
|
|
17821
|
+
}),
|
|
17819
17822
|
external_exports.object({
|
|
17820
17823
|
kind: external_exports.literal("attributedRuns")
|
|
17821
17824
|
})
|
|
@@ -17855,7 +17858,7 @@ var init_trigger_router = __esm({
|
|
|
17855
17858
|
}).strict(),
|
|
17856
17859
|
external_exports.object({
|
|
17857
17860
|
kind: external_exports.literal("command"),
|
|
17858
|
-
commandId:
|
|
17861
|
+
commandId: SessionCommandIdSchema
|
|
17859
17862
|
}).strict()
|
|
17860
17863
|
]);
|
|
17861
17864
|
HeartbeatTickWorkflowInputSchema = external_exports.object({
|
|
@@ -18081,7 +18084,7 @@ function validateAttributedRunsTriggerPairing(triggers, context) {
|
|
|
18081
18084
|
context.addIssue({
|
|
18082
18085
|
code: external_exports.ZodIssueCode.custom,
|
|
18083
18086
|
path: [index, "where", "$.auto.authored"],
|
|
18084
|
-
message: 'Chat message
|
|
18087
|
+
message: 'Chat message attributedSessions delivery triggers must filter out Auto-authored messages with "$.auto.authored": false.'
|
|
18085
18088
|
});
|
|
18086
18089
|
}
|
|
18087
18090
|
for (const [spawnIndex, spawnTrigger] of triggers.entries()) {
|
|
@@ -18101,7 +18104,7 @@ function validateAttributedRunsTriggerPairing(triggers, context) {
|
|
|
18101
18104
|
context.addIssue({
|
|
18102
18105
|
code: external_exports.ZodIssueCode.custom,
|
|
18103
18106
|
path: [deliverIndex, "routing"],
|
|
18104
|
-
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 }.'
|
|
18105
18108
|
});
|
|
18106
18109
|
}
|
|
18107
18110
|
}
|
|
@@ -18110,7 +18113,7 @@ function isSpawnTrigger(trigger) {
|
|
|
18110
18113
|
return trigger.routing.kind === "spawn";
|
|
18111
18114
|
}
|
|
18112
18115
|
function isAttributedRunsDeliverTrigger(trigger) {
|
|
18113
|
-
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");
|
|
18114
18117
|
}
|
|
18115
18118
|
function hasAutoAttributionsExists(trigger, expected) {
|
|
18116
18119
|
const clause = trigger.where?.["$.auto.attributions"];
|
|
@@ -18410,7 +18413,7 @@ var init_agents = __esm({
|
|
|
18410
18413
|
});
|
|
18411
18414
|
AgentPresenceConnectRequestSchema = external_exports.object({
|
|
18412
18415
|
/**
|
|
18413
|
-
*
|
|
18416
|
+
* Rerun the install OAuth for already-realized identities too. The repair
|
|
18414
18417
|
* path for a stranded bot token (e.g. the single-use refresh token was
|
|
18415
18418
|
* consumed but the rotated pair failed to persist): the stored app
|
|
18416
18419
|
* credentials are reused, so this never creates a new Slack app.
|
|
@@ -18778,29 +18781,29 @@ var init_realtime = __esm({
|
|
|
18778
18781
|
}
|
|
18779
18782
|
});
|
|
18780
18783
|
|
|
18781
|
-
// ../../packages/schemas/src/
|
|
18782
|
-
var
|
|
18783
|
-
var
|
|
18784
|
-
"../../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"() {
|
|
18785
18788
|
"use strict";
|
|
18786
18789
|
init_zod();
|
|
18787
18790
|
init_ids();
|
|
18788
18791
|
init_primitives();
|
|
18789
|
-
|
|
18790
|
-
|
|
18792
|
+
SESSION_DIAGNOSTIC_REALTIME_EVENT = "session.diagnostic";
|
|
18793
|
+
SESSION_DIAGNOSTIC_LEVELS = [
|
|
18791
18794
|
"debug",
|
|
18792
18795
|
"info",
|
|
18793
18796
|
"warn",
|
|
18794
18797
|
"error"
|
|
18795
18798
|
];
|
|
18796
|
-
|
|
18799
|
+
SESSION_DIAGNOSTIC_SOURCES = [
|
|
18797
18800
|
"web",
|
|
18798
18801
|
"worker",
|
|
18799
18802
|
"activity",
|
|
18800
18803
|
"bridge",
|
|
18801
18804
|
"runtime"
|
|
18802
18805
|
];
|
|
18803
|
-
|
|
18806
|
+
SESSION_DIAGNOSTIC_PHASES = [
|
|
18804
18807
|
"dispatch",
|
|
18805
18808
|
"environment",
|
|
18806
18809
|
"bridge",
|
|
@@ -18808,28 +18811,30 @@ var init_run_diagnostics = __esm({
|
|
|
18808
18811
|
"command",
|
|
18809
18812
|
"runtime"
|
|
18810
18813
|
];
|
|
18811
|
-
|
|
18814
|
+
SESSION_DIAGNOSTIC_STATUSES = [
|
|
18812
18815
|
"started",
|
|
18813
18816
|
"succeeded",
|
|
18814
18817
|
"retrying",
|
|
18815
18818
|
"failed",
|
|
18816
18819
|
"skipped"
|
|
18817
18820
|
];
|
|
18818
|
-
|
|
18819
|
-
|
|
18820
|
-
|
|
18821
|
-
|
|
18822
|
-
|
|
18823
|
-
|
|
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),
|
|
18824
18829
|
id: external_exports.string().min(1),
|
|
18825
|
-
|
|
18826
|
-
level:
|
|
18827
|
-
source:
|
|
18828
|
-
phase:
|
|
18830
|
+
sessionId: SessionIdSchema,
|
|
18831
|
+
level: SessionDiagnosticLevelSchema,
|
|
18832
|
+
source: SessionDiagnosticSourceSchema,
|
|
18833
|
+
phase: SessionDiagnosticPhaseSchema,
|
|
18829
18834
|
step: external_exports.string().trim().min(1),
|
|
18830
|
-
status:
|
|
18835
|
+
status: SessionDiagnosticStatusSchema,
|
|
18831
18836
|
message: external_exports.string().trim().min(1),
|
|
18832
|
-
commandId:
|
|
18837
|
+
commandId: SessionCommandIdSchema.optional(),
|
|
18833
18838
|
runtimeId: RuntimeIdSchema.optional(),
|
|
18834
18839
|
bridgeLeaseId: RuntimeBridgeLeaseIdSchema.optional(),
|
|
18835
18840
|
attempt: external_exports.number().int().nonnegative().optional(),
|
|
@@ -18840,15 +18845,15 @@ var init_run_diagnostics = __esm({
|
|
|
18840
18845
|
}
|
|
18841
18846
|
});
|
|
18842
18847
|
|
|
18843
|
-
// ../../packages/schemas/src/
|
|
18844
|
-
function
|
|
18845
|
-
return
|
|
18848
|
+
// ../../packages/schemas/src/sessions.ts
|
|
18849
|
+
function isSessionTerminalStatus(status) {
|
|
18850
|
+
return SESSION_TERMINAL_STATUSES.some(
|
|
18846
18851
|
(terminalStatus) => terminalStatus === status
|
|
18847
18852
|
);
|
|
18848
18853
|
}
|
|
18849
|
-
var
|
|
18850
|
-
var
|
|
18851
|
-
"../../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"() {
|
|
18852
18857
|
"use strict";
|
|
18853
18858
|
init_zod();
|
|
18854
18859
|
init_agents();
|
|
@@ -18857,45 +18862,47 @@ var init_runs = __esm({
|
|
|
18857
18862
|
init_ids();
|
|
18858
18863
|
init_primitives();
|
|
18859
18864
|
init_tools();
|
|
18860
|
-
|
|
18865
|
+
SESSION_STATUSES = [
|
|
18861
18866
|
"queued",
|
|
18862
18867
|
"running",
|
|
18863
18868
|
"awaiting",
|
|
18864
18869
|
"failed",
|
|
18865
18870
|
"stopped"
|
|
18866
18871
|
];
|
|
18867
|
-
|
|
18868
|
-
|
|
18869
|
-
|
|
18870
|
-
RunDisplayTitleSchema = external_exports.string().trim().max(
|
|
18871
|
-
|
|
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 = [
|
|
18872
18877
|
"queued",
|
|
18873
18878
|
"in_progress",
|
|
18874
18879
|
"completed"
|
|
18875
18880
|
];
|
|
18876
|
-
|
|
18877
|
-
|
|
18878
|
-
|
|
18879
|
-
|
|
18880
|
-
|
|
18881
|
-
|
|
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({
|
|
18882
18889
|
message: external_exports.string().trim().min(1).max(2e4).optional(),
|
|
18883
18890
|
interactive: external_exports.boolean().optional()
|
|
18884
18891
|
});
|
|
18885
|
-
|
|
18892
|
+
SessionArchiveRequestSchema = external_exports.object({
|
|
18886
18893
|
archived: external_exports.boolean()
|
|
18887
18894
|
});
|
|
18888
|
-
|
|
18889
|
-
|
|
18895
|
+
SessionsArchiveRequestSchema = external_exports.object({
|
|
18896
|
+
session_ids: external_exports.array(SessionIdSchema).min(1).max(100),
|
|
18890
18897
|
archived: external_exports.boolean()
|
|
18891
18898
|
});
|
|
18892
|
-
|
|
18893
|
-
id:
|
|
18899
|
+
SessionRecordSchema = external_exports.object({
|
|
18900
|
+
id: SessionIdSchema,
|
|
18894
18901
|
organizationId: external_exports.string().trim().min(1),
|
|
18895
18902
|
projectId: external_exports.string().trim().min(1).nullable(),
|
|
18896
18903
|
agentId: AgentIdSchema,
|
|
18897
18904
|
runtimeId: RuntimeIdSchema.nullable(),
|
|
18898
|
-
status:
|
|
18905
|
+
status: SessionStatusSchema,
|
|
18899
18906
|
idempotencyKey: external_exports.string().min(1).nullable(),
|
|
18900
18907
|
correlationKey: external_exports.string().nullable(),
|
|
18901
18908
|
workflowId: external_exports.string().min(1),
|
|
@@ -18918,24 +18925,24 @@ var init_runs = __esm({
|
|
|
18918
18925
|
archivedAt: external_exports.string().datetime().nullable(),
|
|
18919
18926
|
error: JsonValueSchema.nullable()
|
|
18920
18927
|
});
|
|
18921
|
-
|
|
18928
|
+
SessionsArchiveResponseSchema = external_exports.object({
|
|
18922
18929
|
archived: external_exports.boolean(),
|
|
18923
|
-
|
|
18930
|
+
sessions: external_exports.array(SessionRecordSchema)
|
|
18924
18931
|
});
|
|
18925
18932
|
}
|
|
18926
18933
|
});
|
|
18927
18934
|
|
|
18928
|
-
// ../../packages/schemas/src/
|
|
18929
|
-
var TruncatedValueSchema, RunConversationSearchSnippetSchema, RunConversationSearchMatchSchema, RunConversationSearchResponseSchema,
|
|
18930
|
-
var
|
|
18931
|
-
"../../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"() {
|
|
18932
18939
|
"use strict";
|
|
18933
18940
|
init_zod();
|
|
18934
18941
|
init_auth();
|
|
18935
18942
|
init_conversation();
|
|
18936
18943
|
init_ids();
|
|
18937
18944
|
init_primitives();
|
|
18938
|
-
|
|
18945
|
+
init_sessions();
|
|
18939
18946
|
TruncatedValueSchema = external_exports.object({
|
|
18940
18947
|
truncated: external_exports.literal(true),
|
|
18941
18948
|
truncatedPreview: external_exports.string(),
|
|
@@ -18970,7 +18977,7 @@ var init_run_introspection = __esm({
|
|
|
18970
18977
|
*/
|
|
18971
18978
|
nextAfterSequence: external_exports.number().int().nullable()
|
|
18972
18979
|
});
|
|
18973
|
-
|
|
18980
|
+
SessionToolExchangeSchema = external_exports.object({
|
|
18974
18981
|
name: external_exports.string(),
|
|
18975
18982
|
callSequence: external_exports.number().int().nonnegative(),
|
|
18976
18983
|
resultSequence: external_exports.number().int().nonnegative().nullable(),
|
|
@@ -18983,8 +18990,8 @@ var init_run_introspection = __esm({
|
|
|
18983
18990
|
startedAt: external_exports.string().datetime(),
|
|
18984
18991
|
completedAt: external_exports.string().datetime().nullable()
|
|
18985
18992
|
});
|
|
18986
|
-
|
|
18987
|
-
exchanges: external_exports.array(
|
|
18993
|
+
SessionToolExchangesResponseSchema = external_exports.object({
|
|
18994
|
+
exchanges: external_exports.array(SessionToolExchangeSchema),
|
|
18988
18995
|
hasMore: external_exports.boolean(),
|
|
18989
18996
|
/**
|
|
18990
18997
|
* Sequence bounds of the entries window this page consumed (not just the
|
|
@@ -18994,27 +19001,27 @@ var init_run_introspection = __esm({
|
|
|
18994
19001
|
nextAfterSequence: external_exports.number().int().nullable(),
|
|
18995
19002
|
nextBeforeSequence: external_exports.number().int().nullable()
|
|
18996
19003
|
});
|
|
18997
|
-
|
|
19004
|
+
SESSION_TRIGGER_DELIVERY_ACTIONS = [
|
|
18998
19005
|
"started",
|
|
18999
19006
|
"signaled",
|
|
19000
19007
|
"dropped",
|
|
19001
19008
|
"warned",
|
|
19002
19009
|
"errored"
|
|
19003
19010
|
];
|
|
19004
|
-
|
|
19005
|
-
|
|
19011
|
+
SessionTriggerDeliveryActionSchema = external_exports.enum(
|
|
19012
|
+
SESSION_TRIGGER_DELIVERY_ACTIONS
|
|
19006
19013
|
);
|
|
19007
|
-
|
|
19014
|
+
SESSION_EVENT_ORIGIN_KINDS = [
|
|
19008
19015
|
"internal",
|
|
19009
19016
|
"provider_grant",
|
|
19010
19017
|
"webhook"
|
|
19011
19018
|
];
|
|
19012
|
-
|
|
19013
|
-
|
|
19014
|
-
action:
|
|
19019
|
+
SessionEventOriginKindSchema = external_exports.enum(SESSION_EVENT_ORIGIN_KINDS);
|
|
19020
|
+
SessionTriggerDeliveryRecordSchema = external_exports.object({
|
|
19021
|
+
action: SessionTriggerDeliveryActionSchema,
|
|
19015
19022
|
triggerId: external_exports.string(),
|
|
19016
19023
|
eventKey: external_exports.string(),
|
|
19017
|
-
originKind:
|
|
19024
|
+
originKind: SessionEventOriginKindSchema,
|
|
19018
19025
|
occurredAt: external_exports.string().datetime(),
|
|
19019
19026
|
receivedAt: external_exports.string().datetime(),
|
|
19020
19027
|
deliveredAt: external_exports.string().datetime(),
|
|
@@ -19022,13 +19029,13 @@ var init_run_introspection = __esm({
|
|
|
19022
19029
|
/** Event payload; may be a {@link TruncatedValueSchema} marker. */
|
|
19023
19030
|
payload: JsonValueSchema.optional()
|
|
19024
19031
|
});
|
|
19025
|
-
|
|
19026
|
-
/** The `started` delivery that spawned the
|
|
19027
|
-
spawn:
|
|
19028
|
-
/** 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. */
|
|
19029
19036
|
starter: AuthActorSchema.nullable(),
|
|
19030
|
-
/** Subsequent deliveries against the
|
|
19031
|
-
deliveries: external_exports.array(
|
|
19037
|
+
/** Subsequent deliveries against the session, chronological. */
|
|
19038
|
+
deliveries: external_exports.array(SessionTriggerDeliveryRecordSchema)
|
|
19032
19039
|
});
|
|
19033
19040
|
RunArtifactRecordSchema = external_exports.object({
|
|
19034
19041
|
artifactType: external_exports.string(),
|
|
@@ -19046,14 +19053,14 @@ var init_run_introspection = __esm({
|
|
|
19046
19053
|
completedAt: external_exports.string().datetime().nullable(),
|
|
19047
19054
|
toolCallCount: external_exports.number().int().nonnegative()
|
|
19048
19055
|
});
|
|
19049
|
-
|
|
19056
|
+
SessionToolStatSchema = external_exports.object({
|
|
19050
19057
|
name: external_exports.string(),
|
|
19051
|
-
/**
|
|
19058
|
+
/** Session-wide call count from the SQL aggregate. */
|
|
19052
19059
|
calls: external_exports.number().int().nonnegative(),
|
|
19053
19060
|
/**
|
|
19054
19061
|
* Derived from the summary's recent-entries window (most recent ~1000
|
|
19055
|
-
* entries), so on very long
|
|
19056
|
-
* relative to the
|
|
19062
|
+
* entries), so on very long sessions `errors` and `durationMs` can understate
|
|
19063
|
+
* relative to the session-wide `calls`.
|
|
19057
19064
|
*/
|
|
19058
19065
|
errors: external_exports.number().int().nonnegative(),
|
|
19059
19066
|
durationMs: external_exports.object({
|
|
@@ -19062,11 +19069,11 @@ var init_run_introspection = __esm({
|
|
|
19062
19069
|
})
|
|
19063
19070
|
});
|
|
19064
19071
|
RunSummarySchema = external_exports.object({
|
|
19065
|
-
|
|
19066
|
-
id:
|
|
19072
|
+
session: external_exports.object({
|
|
19073
|
+
id: SessionIdSchema,
|
|
19067
19074
|
agentName: external_exports.string(),
|
|
19068
19075
|
displayTitle: external_exports.string(),
|
|
19069
|
-
status:
|
|
19076
|
+
status: SessionStatusSchema,
|
|
19070
19077
|
error: JsonValueSchema.nullable(),
|
|
19071
19078
|
workflowId: external_exports.string(),
|
|
19072
19079
|
createdAt: external_exports.string().datetime(),
|
|
@@ -19075,9 +19082,9 @@ var init_run_introspection = __esm({
|
|
|
19075
19082
|
archivedAt: external_exports.string().datetime().nullable()
|
|
19076
19083
|
}),
|
|
19077
19084
|
timing: external_exports.object({
|
|
19078
|
-
/** `startedAt - createdAt`; null until the
|
|
19085
|
+
/** `startedAt - createdAt`; null until the session starts. */
|
|
19079
19086
|
queuedMs: external_exports.number().int().nonnegative().nullable(),
|
|
19080
|
-
/** `(finishedAt ?? now) - startedAt`; null until the
|
|
19087
|
+
/** `(finishedAt ?? now) - startedAt`; null until the session starts. */
|
|
19081
19088
|
activeMs: external_exports.number().int().nonnegative().nullable(),
|
|
19082
19089
|
/** `(finishedAt ?? now) - createdAt`. */
|
|
19083
19090
|
totalMs: external_exports.number().int().nonnegative()
|
|
@@ -19096,15 +19103,15 @@ var init_run_introspection = __esm({
|
|
|
19096
19103
|
failedEntryCount: external_exports.number().int().nonnegative(),
|
|
19097
19104
|
lastSequence: external_exports.number().int().nonnegative()
|
|
19098
19105
|
}),
|
|
19099
|
-
tools: external_exports.array(
|
|
19106
|
+
tools: external_exports.array(SessionToolStatSchema),
|
|
19100
19107
|
/**
|
|
19101
|
-
* True when the
|
|
19108
|
+
* True when the session has more conversation entries than the summary's
|
|
19102
19109
|
* recent-entries window, meaning per-tool `errors`/`durationMs` (and
|
|
19103
|
-
* `turns`) describe only the most recent slice of the
|
|
19110
|
+
* `turns`) describe only the most recent slice of the session.
|
|
19104
19111
|
*/
|
|
19105
19112
|
toolStatsWindowed: external_exports.boolean(),
|
|
19106
19113
|
trigger: external_exports.object({
|
|
19107
|
-
/** Spawning event key, or "manual" / "agent" for actor-started
|
|
19114
|
+
/** Spawning event key, or "manual" / "agent" for actor-started sessions. */
|
|
19108
19115
|
spawn: external_exports.string(),
|
|
19109
19116
|
signaledCount: external_exports.number().int().nonnegative(),
|
|
19110
19117
|
droppedCount: external_exports.number().int().nonnegative()
|
|
@@ -19124,8 +19131,8 @@ var init_run_introspection = __esm({
|
|
|
19124
19131
|
external_exports.object({
|
|
19125
19132
|
name: external_exports.string(),
|
|
19126
19133
|
displayName: external_exports.string(),
|
|
19127
|
-
status:
|
|
19128
|
-
conclusion:
|
|
19134
|
+
status: SessionCheckStatusSchema,
|
|
19135
|
+
conclusion: SessionCheckConclusionSchema.nullable(),
|
|
19129
19136
|
completedAt: external_exports.string().datetime().nullable()
|
|
19130
19137
|
})
|
|
19131
19138
|
)
|
|
@@ -19133,16 +19140,16 @@ var init_run_introspection = __esm({
|
|
|
19133
19140
|
}
|
|
19134
19141
|
});
|
|
19135
19142
|
|
|
19136
|
-
// ../../packages/schemas/src/
|
|
19137
|
-
var
|
|
19138
|
-
var
|
|
19139
|
-
"../../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"() {
|
|
19140
19147
|
"use strict";
|
|
19141
19148
|
init_zod();
|
|
19142
19149
|
init_auth();
|
|
19143
19150
|
init_ids();
|
|
19144
19151
|
init_primitives();
|
|
19145
|
-
|
|
19152
|
+
SESSION_COMMAND_KINDS = [
|
|
19146
19153
|
"message",
|
|
19147
19154
|
"answer",
|
|
19148
19155
|
"pause",
|
|
@@ -19151,14 +19158,14 @@ var init_run_commands = __esm({
|
|
|
19151
19158
|
"cancel",
|
|
19152
19159
|
"stop"
|
|
19153
19160
|
];
|
|
19154
|
-
|
|
19161
|
+
SESSION_DISPATCH_COMMAND_KINDS = [
|
|
19155
19162
|
"start",
|
|
19156
19163
|
"startWithMessage",
|
|
19157
19164
|
"message",
|
|
19158
19165
|
"answer",
|
|
19159
19166
|
"stop"
|
|
19160
19167
|
];
|
|
19161
|
-
|
|
19168
|
+
SESSION_PERSISTED_COMMAND_KINDS = [
|
|
19162
19169
|
"message",
|
|
19163
19170
|
"pause",
|
|
19164
19171
|
"resume",
|
|
@@ -19169,38 +19176,40 @@ var init_run_commands = __esm({
|
|
|
19169
19176
|
"startWithMessage",
|
|
19170
19177
|
"answer"
|
|
19171
19178
|
];
|
|
19172
|
-
|
|
19179
|
+
SESSION_LIFECYCLE_COMMAND_KINDS = [
|
|
19173
19180
|
"pause",
|
|
19174
19181
|
"resume",
|
|
19175
19182
|
"interrupt",
|
|
19176
19183
|
"cancel",
|
|
19177
19184
|
"stop"
|
|
19178
19185
|
];
|
|
19179
|
-
|
|
19186
|
+
SESSION_COMMAND_STATUSES = [
|
|
19180
19187
|
"pending",
|
|
19181
19188
|
"dispatching",
|
|
19182
19189
|
"accepted",
|
|
19183
19190
|
"failed"
|
|
19184
19191
|
];
|
|
19185
|
-
|
|
19192
|
+
SESSION_DISPATCH_COMMAND_STATUSES = [
|
|
19186
19193
|
"pending",
|
|
19187
19194
|
"dispatching",
|
|
19188
19195
|
"accepted",
|
|
19189
19196
|
"failed"
|
|
19190
19197
|
];
|
|
19191
|
-
|
|
19192
|
-
|
|
19193
|
-
|
|
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
|
|
19194
19204
|
);
|
|
19195
|
-
RunDispatchCommandKindSchema = external_exports.enum(RUN_DISPATCH_COMMAND_KINDS);
|
|
19196
19205
|
RunLifecycleCommandKindSchema = external_exports.enum(
|
|
19197
|
-
|
|
19206
|
+
SESSION_LIFECYCLE_COMMAND_KINDS
|
|
19198
19207
|
);
|
|
19199
|
-
|
|
19200
|
-
|
|
19201
|
-
|
|
19208
|
+
SessionCommandStatusSchema = external_exports.enum(SESSION_COMMAND_STATUSES);
|
|
19209
|
+
SessionDispatchCommandStatusSchema = external_exports.enum(
|
|
19210
|
+
SESSION_DISPATCH_COMMAND_STATUSES
|
|
19202
19211
|
);
|
|
19203
|
-
|
|
19212
|
+
SessionCommandSenderSchema = external_exports.discriminatedUnion("type", [
|
|
19204
19213
|
external_exports.object({
|
|
19205
19214
|
type: external_exports.literal("operator"),
|
|
19206
19215
|
id: external_exports.string().trim().min(1).nullable().default(null),
|
|
@@ -19208,7 +19217,7 @@ var init_run_commands = __esm({
|
|
|
19208
19217
|
}),
|
|
19209
19218
|
external_exports.object({
|
|
19210
19219
|
type: external_exports.literal("agent"),
|
|
19211
|
-
|
|
19220
|
+
sessionId: SessionIdSchema
|
|
19212
19221
|
}),
|
|
19213
19222
|
external_exports.object({
|
|
19214
19223
|
type: external_exports.literal("system")
|
|
@@ -19228,7 +19237,7 @@ var init_run_commands = __esm({
|
|
|
19228
19237
|
RunLifecycleCommandPayloadSchema = external_exports.object({
|
|
19229
19238
|
reason: external_exports.string().trim().min(1).optional()
|
|
19230
19239
|
}).strict();
|
|
19231
|
-
|
|
19240
|
+
SessionCommandPayloadSchema = external_exports.union([
|
|
19232
19241
|
RunMessageCommandPayloadSchema,
|
|
19233
19242
|
RunAnswerCommandPayloadSchema,
|
|
19234
19243
|
RunLifecycleCommandPayloadSchema
|
|
@@ -19241,7 +19250,7 @@ var init_run_commands = __esm({
|
|
|
19241
19250
|
CreateRunLifecycleCommandRequestSchema = external_exports.object({
|
|
19242
19251
|
reason: external_exports.string().trim().min(1).optional()
|
|
19243
19252
|
});
|
|
19244
|
-
|
|
19253
|
+
CreateSessionCommandRequestSchema = external_exports.discriminatedUnion("kind", [
|
|
19245
19254
|
external_exports.object({
|
|
19246
19255
|
kind: external_exports.literal("message"),
|
|
19247
19256
|
payload: CreateRunMessageCommandRequestSchema
|
|
@@ -19283,12 +19292,12 @@ var init_run_commands = __esm({
|
|
|
19283
19292
|
}).refine((value) => Boolean(value.agentId) !== Boolean(value.agentName), {
|
|
19284
19293
|
message: "Provide exactly one of agentId or agentName"
|
|
19285
19294
|
});
|
|
19286
|
-
|
|
19287
|
-
id:
|
|
19288
|
-
|
|
19289
|
-
sender:
|
|
19295
|
+
SessionCommandRecordBaseSchema = external_exports.object({
|
|
19296
|
+
id: SessionCommandIdSchema,
|
|
19297
|
+
sessionId: SessionIdSchema,
|
|
19298
|
+
sender: SessionCommandSenderSchema,
|
|
19290
19299
|
idempotencyKey: external_exports.string().min(1).nullable(),
|
|
19291
|
-
status:
|
|
19300
|
+
status: SessionCommandStatusSchema,
|
|
19292
19301
|
attemptCount: external_exports.number().int().nonnegative(),
|
|
19293
19302
|
nextAttemptAt: external_exports.string().datetime().nullable(),
|
|
19294
19303
|
lastAttemptAt: external_exports.string().datetime().nullable(),
|
|
@@ -19305,78 +19314,81 @@ var init_run_commands = __esm({
|
|
|
19305
19314
|
kind: external_exports.literal("startWithMessage"),
|
|
19306
19315
|
message: external_exports.string().trim().min(1)
|
|
19307
19316
|
}).strict();
|
|
19308
|
-
|
|
19317
|
+
SessionPersistedCommandPayloadSchema = external_exports.union([
|
|
19309
19318
|
RunMessageCommandPayloadSchema,
|
|
19310
19319
|
RunAnswerCommandPayloadSchema,
|
|
19311
19320
|
RunLifecycleCommandPayloadSchema,
|
|
19312
19321
|
RunStartCommandPayloadSchema,
|
|
19313
19322
|
RunStartWithMessageCommandPayloadSchema
|
|
19314
19323
|
]);
|
|
19315
|
-
|
|
19316
|
-
|
|
19324
|
+
SessionCommandRecordSchema = external_exports.discriminatedUnion("kind", [
|
|
19325
|
+
SessionCommandRecordBaseSchema.extend({
|
|
19317
19326
|
kind: external_exports.literal("message"),
|
|
19318
19327
|
payload: RunMessageCommandPayloadSchema
|
|
19319
19328
|
}),
|
|
19320
|
-
|
|
19329
|
+
SessionCommandRecordBaseSchema.extend({
|
|
19321
19330
|
kind: external_exports.literal("answer"),
|
|
19322
19331
|
payload: RunAnswerCommandPayloadSchema
|
|
19323
19332
|
}),
|
|
19324
|
-
|
|
19333
|
+
SessionCommandRecordBaseSchema.extend({
|
|
19325
19334
|
kind: external_exports.literal("pause"),
|
|
19326
19335
|
payload: RunLifecycleCommandPayloadSchema
|
|
19327
19336
|
}),
|
|
19328
|
-
|
|
19337
|
+
SessionCommandRecordBaseSchema.extend({
|
|
19329
19338
|
kind: external_exports.literal("resume"),
|
|
19330
19339
|
payload: RunLifecycleCommandPayloadSchema
|
|
19331
19340
|
}),
|
|
19332
|
-
|
|
19341
|
+
SessionCommandRecordBaseSchema.extend({
|
|
19333
19342
|
kind: external_exports.literal("interrupt"),
|
|
19334
19343
|
payload: RunLifecycleCommandPayloadSchema
|
|
19335
19344
|
}),
|
|
19336
|
-
|
|
19345
|
+
SessionCommandRecordBaseSchema.extend({
|
|
19337
19346
|
kind: external_exports.literal("cancel"),
|
|
19338
19347
|
payload: RunLifecycleCommandPayloadSchema
|
|
19339
19348
|
}),
|
|
19340
|
-
|
|
19349
|
+
SessionCommandRecordBaseSchema.extend({
|
|
19341
19350
|
kind: external_exports.literal("stop"),
|
|
19342
19351
|
payload: RunLifecycleCommandPayloadSchema
|
|
19343
19352
|
}),
|
|
19344
|
-
|
|
19353
|
+
SessionCommandRecordBaseSchema.extend({
|
|
19345
19354
|
kind: external_exports.literal("start"),
|
|
19346
19355
|
payload: RunStartCommandPayloadSchema
|
|
19347
19356
|
}),
|
|
19348
|
-
|
|
19357
|
+
SessionCommandRecordBaseSchema.extend({
|
|
19349
19358
|
kind: external_exports.literal("startWithMessage"),
|
|
19350
19359
|
payload: RunStartWithMessageCommandPayloadSchema
|
|
19351
19360
|
})
|
|
19352
19361
|
]);
|
|
19353
|
-
|
|
19362
|
+
SessionDispatchMessageCommandPayloadSchema = external_exports.object({
|
|
19354
19363
|
kind: external_exports.literal("message"),
|
|
19355
19364
|
message: external_exports.string().trim().min(1)
|
|
19356
19365
|
}).strict();
|
|
19357
|
-
|
|
19366
|
+
SessionDispatchAnswerCommandPayloadSchema = external_exports.object({
|
|
19358
19367
|
kind: external_exports.literal("answer"),
|
|
19359
19368
|
toolCallId: external_exports.string().trim().min(1),
|
|
19360
19369
|
answers: external_exports.record(external_exports.string(), external_exports.string()),
|
|
19361
19370
|
response: external_exports.string().trim().min(1).optional()
|
|
19362
19371
|
}).strict();
|
|
19363
|
-
|
|
19372
|
+
SessionDispatchStopCommandPayloadSchema = external_exports.object({
|
|
19364
19373
|
kind: external_exports.literal("stop"),
|
|
19365
19374
|
reason: external_exports.string().trim().min(1).optional()
|
|
19366
19375
|
}).strict();
|
|
19367
|
-
|
|
19368
|
-
|
|
19369
|
-
|
|
19370
|
-
|
|
19371
|
-
|
|
19372
|
-
|
|
19373
|
-
|
|
19374
|
-
|
|
19375
|
-
|
|
19376
|
-
|
|
19377
|
-
|
|
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,
|
|
19378
19390
|
idempotencyKey: external_exports.string().min(1).nullable(),
|
|
19379
|
-
status:
|
|
19391
|
+
status: SessionDispatchCommandStatusSchema,
|
|
19380
19392
|
attemptCount: external_exports.number().int().nonnegative(),
|
|
19381
19393
|
nextAttemptAt: external_exports.string().datetime().nullable(),
|
|
19382
19394
|
lastAttemptAt: external_exports.string().datetime().nullable(),
|
|
@@ -19386,33 +19398,33 @@ var init_run_commands = __esm({
|
|
|
19386
19398
|
createdAt: external_exports.string().datetime(),
|
|
19387
19399
|
updatedAt: external_exports.string().datetime()
|
|
19388
19400
|
});
|
|
19389
|
-
|
|
19390
|
-
|
|
19401
|
+
SessionDispatchCommandRecordSchema = external_exports.discriminatedUnion("kind", [
|
|
19402
|
+
SessionDispatchCommandRecordBaseSchema.extend({
|
|
19391
19403
|
kind: external_exports.literal("start"),
|
|
19392
19404
|
payload: RunStartCommandPayloadSchema
|
|
19393
19405
|
}),
|
|
19394
|
-
|
|
19406
|
+
SessionDispatchCommandRecordBaseSchema.extend({
|
|
19395
19407
|
kind: external_exports.literal("startWithMessage"),
|
|
19396
19408
|
payload: RunStartWithMessageCommandPayloadSchema
|
|
19397
19409
|
}),
|
|
19398
|
-
|
|
19410
|
+
SessionDispatchCommandRecordBaseSchema.extend({
|
|
19399
19411
|
kind: external_exports.literal("message"),
|
|
19400
|
-
payload:
|
|
19412
|
+
payload: SessionDispatchMessageCommandPayloadSchema
|
|
19401
19413
|
}),
|
|
19402
|
-
|
|
19414
|
+
SessionDispatchCommandRecordBaseSchema.extend({
|
|
19403
19415
|
kind: external_exports.literal("answer"),
|
|
19404
|
-
payload:
|
|
19416
|
+
payload: SessionDispatchAnswerCommandPayloadSchema
|
|
19405
19417
|
}),
|
|
19406
|
-
|
|
19418
|
+
SessionDispatchCommandRecordBaseSchema.extend({
|
|
19407
19419
|
kind: external_exports.literal("stop"),
|
|
19408
|
-
payload:
|
|
19420
|
+
payload: SessionDispatchStopCommandPayloadSchema
|
|
19409
19421
|
})
|
|
19410
19422
|
]);
|
|
19411
19423
|
}
|
|
19412
19424
|
});
|
|
19413
19425
|
|
|
19414
19426
|
// ../../packages/schemas/src/runtimes.ts
|
|
19415
|
-
var RuntimeRecordSchema,
|
|
19427
|
+
var RuntimeRecordSchema, SessionCommandDispatchWorkflowInputSchema, SessionCommandDispatchSignalPayloadSchema, RealtimeRunCursorSchema;
|
|
19416
19428
|
var init_runtimes = __esm({
|
|
19417
19429
|
"../../packages/schemas/src/runtimes.ts"() {
|
|
19418
19430
|
"use strict";
|
|
@@ -19424,12 +19436,12 @@ var init_runtimes = __esm({
|
|
|
19424
19436
|
createdAt: external_exports.string().datetime(),
|
|
19425
19437
|
updatedAt: external_exports.string().datetime()
|
|
19426
19438
|
});
|
|
19427
|
-
|
|
19428
|
-
|
|
19429
|
-
commandId:
|
|
19439
|
+
SessionCommandDispatchWorkflowInputSchema = external_exports.object({
|
|
19440
|
+
sessionId: SessionIdSchema,
|
|
19441
|
+
commandId: SessionCommandIdSchema
|
|
19430
19442
|
}).strict();
|
|
19431
|
-
|
|
19432
|
-
commandId:
|
|
19443
|
+
SessionCommandDispatchSignalPayloadSchema = external_exports.object({
|
|
19444
|
+
commandId: SessionCommandIdSchema
|
|
19433
19445
|
}).strict();
|
|
19434
19446
|
RealtimeRunCursorSchema = external_exports.string().regex(/^rt:(0|[1-9]\d*)$/);
|
|
19435
19447
|
}
|
|
@@ -19472,12 +19484,12 @@ var init_src = __esm({
|
|
|
19472
19484
|
init_primitives();
|
|
19473
19485
|
init_realtime();
|
|
19474
19486
|
init_resources();
|
|
19475
|
-
|
|
19476
|
-
|
|
19487
|
+
init_session_diagnostics();
|
|
19488
|
+
init_session_introspection();
|
|
19477
19489
|
init_secrets();
|
|
19478
|
-
|
|
19490
|
+
init_session_commands();
|
|
19479
19491
|
init_runtimes();
|
|
19480
|
-
|
|
19492
|
+
init_sessions();
|
|
19481
19493
|
init_agents();
|
|
19482
19494
|
init_temporal();
|
|
19483
19495
|
init_tools();
|
|
@@ -19489,7 +19501,7 @@ var init_src = __esm({
|
|
|
19489
19501
|
function requireActiveProject(config2) {
|
|
19490
19502
|
if (!config2.organizationId || !config2.projectId) {
|
|
19491
19503
|
throw new Error(
|
|
19492
|
-
"
|
|
19504
|
+
"Session `auto orgs use <organization>` and `auto projects use <project>` first."
|
|
19493
19505
|
);
|
|
19494
19506
|
}
|
|
19495
19507
|
return {
|
|
@@ -19642,8 +19654,10 @@ function agentApiPath(project, agentName, path2 = "") {
|
|
|
19642
19654
|
`/agents/${encodeURIComponent(agentName)}${cleanSubpath(path2)}`
|
|
19643
19655
|
);
|
|
19644
19656
|
}
|
|
19645
|
-
function runApiPath(
|
|
19646
|
-
return apiPath(
|
|
19657
|
+
function runApiPath(sessionId, path2 = "") {
|
|
19658
|
+
return apiPath(
|
|
19659
|
+
`/sessions/${encodeURIComponent(sessionId)}${cleanSubpath(path2)}`
|
|
19660
|
+
);
|
|
19647
19661
|
}
|
|
19648
19662
|
function cleanSubpath(path2) {
|
|
19649
19663
|
const trimmed = path2.trim();
|
|
@@ -20110,7 +20124,7 @@ function createApiClient(input) {
|
|
|
20110
20124
|
const { organizationId } = await resolveActiveSelection();
|
|
20111
20125
|
if (!organizationId) {
|
|
20112
20126
|
throw new Error(
|
|
20113
|
-
"No active organization.
|
|
20127
|
+
"No active organization. Session `auto auth login` to sign in, then `auto orgs use <organization>` to select one."
|
|
20114
20128
|
);
|
|
20115
20129
|
}
|
|
20116
20130
|
return { organizationId };
|
|
@@ -20907,10 +20921,13 @@ function createApiClient(input) {
|
|
|
20907
20921
|
}
|
|
20908
20922
|
return await response.json();
|
|
20909
20923
|
},
|
|
20910
|
-
async
|
|
20924
|
+
async triggerSession(agentName, options) {
|
|
20911
20925
|
const project = await activeProject();
|
|
20912
20926
|
const response = await authenticatedFetch(
|
|
20913
|
-
apiUrl(
|
|
20927
|
+
apiUrl(
|
|
20928
|
+
agentApiPath(project, agentName, "/sessions"),
|
|
20929
|
+
options.apiBaseUrl
|
|
20930
|
+
),
|
|
20914
20931
|
{
|
|
20915
20932
|
method: "POST",
|
|
20916
20933
|
headers: {
|
|
@@ -20928,9 +20945,12 @@ function createApiClient(input) {
|
|
|
20928
20945
|
}
|
|
20929
20946
|
return await response.json();
|
|
20930
20947
|
},
|
|
20931
|
-
async
|
|
20948
|
+
async streamSessionConversation(sessionId, options) {
|
|
20932
20949
|
const url2 = new URL(
|
|
20933
|
-
apiUrl(
|
|
20950
|
+
apiUrl(
|
|
20951
|
+
runApiPath(sessionId, "/conversation/stream"),
|
|
20952
|
+
options.apiBaseUrl
|
|
20953
|
+
)
|
|
20934
20954
|
);
|
|
20935
20955
|
if (options.cursor) {
|
|
20936
20956
|
url2.searchParams.set("cursor", options.cursor);
|
|
@@ -20950,11 +20970,11 @@ function createApiClient(input) {
|
|
|
20950
20970
|
}
|
|
20951
20971
|
if (!response.body) {
|
|
20952
20972
|
throw new Error(
|
|
20953
|
-
"
|
|
20973
|
+
"Session conversation stream response did not include a body"
|
|
20954
20974
|
);
|
|
20955
20975
|
}
|
|
20956
20976
|
for await (const event of readSseEvents(response.body)) {
|
|
20957
|
-
if (event.event !== "
|
|
20977
|
+
if (event.event !== "session.conversation") {
|
|
20958
20978
|
continue;
|
|
20959
20979
|
}
|
|
20960
20980
|
const parsedJson = JSON.parse(event.data);
|
|
@@ -20971,9 +20991,12 @@ function createApiClient(input) {
|
|
|
20971
20991
|
}
|
|
20972
20992
|
}
|
|
20973
20993
|
},
|
|
20974
|
-
async
|
|
20994
|
+
async streamSessionDiagnostics(sessionId, options) {
|
|
20975
20995
|
const response = await authenticatedFetch(
|
|
20976
|
-
apiUrl(
|
|
20996
|
+
apiUrl(
|
|
20997
|
+
runApiPath(sessionId, "/diagnostics/stream"),
|
|
20998
|
+
options.apiBaseUrl
|
|
20999
|
+
),
|
|
20977
21000
|
{
|
|
20978
21001
|
signal: options.signal,
|
|
20979
21002
|
headers: {
|
|
@@ -20987,15 +21010,15 @@ function createApiClient(input) {
|
|
|
20987
21010
|
}
|
|
20988
21011
|
if (!response.body) {
|
|
20989
21012
|
throw new Error(
|
|
20990
|
-
"
|
|
21013
|
+
"Session diagnostics stream response did not include a body"
|
|
20991
21014
|
);
|
|
20992
21015
|
}
|
|
20993
21016
|
for await (const event of readSseEvents(response.body)) {
|
|
20994
|
-
if (event.event !==
|
|
21017
|
+
if (event.event !== SESSION_DIAGNOSTIC_REALTIME_EVENT) {
|
|
20995
21018
|
continue;
|
|
20996
21019
|
}
|
|
20997
21020
|
const parsedJson = JSON.parse(event.data);
|
|
20998
|
-
const parsed =
|
|
21021
|
+
const parsed = SessionDiagnosticEventSchema.safeParse(parsedJson);
|
|
20999
21022
|
if (!parsed.success) {
|
|
21000
21023
|
input.writeError(
|
|
21001
21024
|
`Skipping invalid diagnostic event: ${parsed.error.message}`
|
|
@@ -21005,9 +21028,9 @@ function createApiClient(input) {
|
|
|
21005
21028
|
options.onEvent(parsed.data);
|
|
21006
21029
|
}
|
|
21007
21030
|
},
|
|
21008
|
-
async
|
|
21031
|
+
async getSession(sessionId, options = {}) {
|
|
21009
21032
|
const response = await authenticatedFetch(
|
|
21010
|
-
apiUrl(runApiPath(
|
|
21033
|
+
apiUrl(runApiPath(sessionId), options.apiBaseUrl),
|
|
21011
21034
|
{},
|
|
21012
21035
|
options.apiBaseUrl
|
|
21013
21036
|
);
|
|
@@ -21016,39 +21039,45 @@ function createApiClient(input) {
|
|
|
21016
21039
|
}
|
|
21017
21040
|
return await response.json();
|
|
21018
21041
|
},
|
|
21019
|
-
async
|
|
21020
|
-
return requestJson(runApiPath(
|
|
21042
|
+
async archiveSession(sessionId, options = {}) {
|
|
21043
|
+
return requestJson(runApiPath(sessionId), {
|
|
21021
21044
|
apiBaseUrl: options.apiBaseUrl,
|
|
21022
21045
|
method: "PATCH",
|
|
21023
21046
|
body: { archived: true }
|
|
21024
21047
|
});
|
|
21025
21048
|
},
|
|
21026
|
-
async
|
|
21027
|
-
return requestJson(runApiPath(
|
|
21049
|
+
async unarchiveSession(sessionId, options = {}) {
|
|
21050
|
+
return requestJson(runApiPath(sessionId), {
|
|
21028
21051
|
apiBaseUrl: options.apiBaseUrl,
|
|
21029
21052
|
method: "PATCH",
|
|
21030
21053
|
body: { archived: false }
|
|
21031
21054
|
});
|
|
21032
21055
|
},
|
|
21033
|
-
async
|
|
21056
|
+
async archiveSessions(sessionIds, options = {}) {
|
|
21034
21057
|
const scope = await activeProject();
|
|
21035
|
-
return requestJson(
|
|
21036
|
-
|
|
21037
|
-
|
|
21038
|
-
|
|
21039
|
-
|
|
21058
|
+
return requestJson(
|
|
21059
|
+
projectApiPath(scope, "/sessions"),
|
|
21060
|
+
{
|
|
21061
|
+
apiBaseUrl: options.apiBaseUrl,
|
|
21062
|
+
method: "PATCH",
|
|
21063
|
+
body: { session_ids: sessionIds, archived: true }
|
|
21064
|
+
}
|
|
21065
|
+
);
|
|
21040
21066
|
},
|
|
21041
|
-
async
|
|
21067
|
+
async unarchiveSessions(sessionIds, options = {}) {
|
|
21042
21068
|
const scope = await activeProject();
|
|
21043
|
-
return requestJson(
|
|
21044
|
-
|
|
21045
|
-
|
|
21046
|
-
|
|
21047
|
-
|
|
21069
|
+
return requestJson(
|
|
21070
|
+
projectApiPath(scope, "/sessions"),
|
|
21071
|
+
{
|
|
21072
|
+
apiBaseUrl: options.apiBaseUrl,
|
|
21073
|
+
method: "PATCH",
|
|
21074
|
+
body: { session_ids: sessionIds, archived: false }
|
|
21075
|
+
}
|
|
21076
|
+
);
|
|
21048
21077
|
},
|
|
21049
|
-
async sendMessage(
|
|
21078
|
+
async sendMessage(sessionId, message, options = {}) {
|
|
21050
21079
|
const response = await authenticatedFetch(
|
|
21051
|
-
apiUrl(runApiPath(
|
|
21080
|
+
apiUrl(runApiPath(sessionId, "/messages"), options.apiBaseUrl),
|
|
21052
21081
|
{
|
|
21053
21082
|
method: "POST",
|
|
21054
21083
|
headers: {
|
|
@@ -21066,9 +21095,9 @@ function createApiClient(input) {
|
|
|
21066
21095
|
}
|
|
21067
21096
|
return await response.json();
|
|
21068
21097
|
},
|
|
21069
|
-
async sendAnswer(
|
|
21098
|
+
async sendAnswer(sessionId, answer, options = {}) {
|
|
21070
21099
|
const response = await authenticatedFetch(
|
|
21071
|
-
apiUrl(runApiPath(
|
|
21100
|
+
apiUrl(runApiPath(sessionId, "/commands"), options.apiBaseUrl),
|
|
21072
21101
|
{
|
|
21073
21102
|
method: "POST",
|
|
21074
21103
|
headers: {
|
|
@@ -21086,9 +21115,9 @@ function createApiClient(input) {
|
|
|
21086
21115
|
}
|
|
21087
21116
|
return await response.json();
|
|
21088
21117
|
},
|
|
21089
|
-
async
|
|
21118
|
+
async stopSession(sessionId, options = {}) {
|
|
21090
21119
|
const response = await authenticatedFetch(
|
|
21091
|
-
apiUrl(runApiPath(
|
|
21120
|
+
apiUrl(runApiPath(sessionId, "/commands"), options.apiBaseUrl),
|
|
21092
21121
|
{
|
|
21093
21122
|
method: "POST",
|
|
21094
21123
|
headers: {
|
|
@@ -21106,29 +21135,29 @@ function createApiClient(input) {
|
|
|
21106
21135
|
}
|
|
21107
21136
|
return await response.json();
|
|
21108
21137
|
},
|
|
21109
|
-
async
|
|
21138
|
+
async listAgentSessions(agentName, options = {}) {
|
|
21110
21139
|
const scope = await activeProject();
|
|
21111
21140
|
return requestJson(
|
|
21112
|
-
agentApiPath(scope, agentName, "/
|
|
21141
|
+
agentApiPath(scope, agentName, "/sessions"),
|
|
21113
21142
|
{
|
|
21114
21143
|
apiBaseUrl: options.apiBaseUrl,
|
|
21115
21144
|
searchParams: runListSearchParams(options)
|
|
21116
21145
|
}
|
|
21117
21146
|
);
|
|
21118
21147
|
},
|
|
21119
|
-
async
|
|
21148
|
+
async listSessions(options = {}) {
|
|
21120
21149
|
const scope = await activeProject();
|
|
21121
|
-
return requestJson(projectApiPath(scope, "/
|
|
21150
|
+
return requestJson(projectApiPath(scope, "/sessions"), {
|
|
21122
21151
|
apiBaseUrl: options.apiBaseUrl,
|
|
21123
21152
|
searchParams: runListSearchParams(options)
|
|
21124
21153
|
});
|
|
21125
21154
|
},
|
|
21126
|
-
async
|
|
21127
|
-
return requestJson(runApiPath(
|
|
21155
|
+
async getSessionSummary(sessionId, options = {}) {
|
|
21156
|
+
return requestJson(runApiPath(sessionId, "/summary"), {
|
|
21128
21157
|
apiBaseUrl: options.apiBaseUrl
|
|
21129
21158
|
});
|
|
21130
21159
|
},
|
|
21131
|
-
async
|
|
21160
|
+
async getSessionConversation(sessionId, options = {}) {
|
|
21132
21161
|
const searchParams = [];
|
|
21133
21162
|
if (options.cursor) searchParams.push(["cursor", options.cursor]);
|
|
21134
21163
|
if (options.before !== void 0)
|
|
@@ -21139,14 +21168,14 @@ function createApiClient(input) {
|
|
|
21139
21168
|
for (const kind of options.kinds ?? []) searchParams.push(["kind", kind]);
|
|
21140
21169
|
for (const role of options.roles ?? []) searchParams.push(["role", role]);
|
|
21141
21170
|
return requestJson(
|
|
21142
|
-
runApiPath(
|
|
21171
|
+
runApiPath(sessionId, "/conversation"),
|
|
21143
21172
|
{
|
|
21144
21173
|
apiBaseUrl: options.apiBaseUrl,
|
|
21145
21174
|
searchParams
|
|
21146
21175
|
}
|
|
21147
21176
|
);
|
|
21148
21177
|
},
|
|
21149
|
-
async
|
|
21178
|
+
async searchSessionConversation(sessionId, queries, options = {}) {
|
|
21150
21179
|
const searchParams = queries.map((query) => [
|
|
21151
21180
|
"q",
|
|
21152
21181
|
query
|
|
@@ -21158,14 +21187,14 @@ function createApiClient(input) {
|
|
|
21158
21187
|
if (options.limit !== void 0)
|
|
21159
21188
|
searchParams.push(["limit", String(options.limit)]);
|
|
21160
21189
|
return requestJson(
|
|
21161
|
-
runApiPath(
|
|
21190
|
+
runApiPath(sessionId, "/conversation/search"),
|
|
21162
21191
|
{
|
|
21163
21192
|
apiBaseUrl: options.apiBaseUrl,
|
|
21164
21193
|
searchParams
|
|
21165
21194
|
}
|
|
21166
21195
|
);
|
|
21167
21196
|
},
|
|
21168
|
-
async
|
|
21197
|
+
async listSessionToolExchanges(sessionId, options = {}) {
|
|
21169
21198
|
const searchParams = [];
|
|
21170
21199
|
if (options.toolName) searchParams.push(["toolName", options.toolName]);
|
|
21171
21200
|
if (options.errorsOnly) searchParams.push(["errorsOnly", "true"]);
|
|
@@ -21177,31 +21206,37 @@ function createApiClient(input) {
|
|
|
21177
21206
|
if (options.limit !== void 0)
|
|
21178
21207
|
searchParams.push(["limit", String(options.limit)]);
|
|
21179
21208
|
return requestJson(
|
|
21180
|
-
runApiPath(
|
|
21209
|
+
runApiPath(sessionId, "/tools"),
|
|
21181
21210
|
{
|
|
21182
21211
|
apiBaseUrl: options.apiBaseUrl,
|
|
21183
21212
|
searchParams
|
|
21184
21213
|
}
|
|
21185
21214
|
);
|
|
21186
21215
|
},
|
|
21187
|
-
async
|
|
21188
|
-
return requestJson(
|
|
21189
|
-
|
|
21190
|
-
|
|
21191
|
-
|
|
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
|
+
);
|
|
21192
21224
|
},
|
|
21193
|
-
async listRunArtifacts(
|
|
21225
|
+
async listRunArtifacts(sessionId, options = {}) {
|
|
21194
21226
|
return requestJson(
|
|
21195
|
-
runApiPath(
|
|
21227
|
+
runApiPath(sessionId, "/artifacts"),
|
|
21196
21228
|
{
|
|
21197
21229
|
apiBaseUrl: options.apiBaseUrl
|
|
21198
21230
|
}
|
|
21199
21231
|
);
|
|
21200
21232
|
},
|
|
21201
|
-
async
|
|
21202
|
-
return requestJson(
|
|
21203
|
-
|
|
21204
|
-
|
|
21233
|
+
async listSessionCommands(sessionId, options = {}) {
|
|
21234
|
+
return requestJson(
|
|
21235
|
+
runApiPath(sessionId, "/commands"),
|
|
21236
|
+
{
|
|
21237
|
+
apiBaseUrl: options.apiBaseUrl
|
|
21238
|
+
}
|
|
21239
|
+
);
|
|
21205
21240
|
},
|
|
21206
21241
|
getOperatorInfo() {
|
|
21207
21242
|
const config2 = readConfig(input.configPath);
|
|
@@ -21271,7 +21306,7 @@ var init_package = __esm({
|
|
|
21271
21306
|
"package.json"() {
|
|
21272
21307
|
package_default = {
|
|
21273
21308
|
name: "@autohq/cli",
|
|
21274
|
-
version: "0.1.
|
|
21309
|
+
version: "0.1.148",
|
|
21275
21310
|
license: "SEE LICENSE IN README.md",
|
|
21276
21311
|
publishConfig: {
|
|
21277
21312
|
access: "public"
|
|
@@ -22184,10 +22219,6 @@ async function resolveApplyAssets(input) {
|
|
|
22184
22219
|
if (probe.stored) {
|
|
22185
22220
|
continue;
|
|
22186
22221
|
}
|
|
22187
|
-
if (input.dryRun) {
|
|
22188
|
-
inline2[probe.path] = probe.asset;
|
|
22189
|
-
continue;
|
|
22190
|
-
}
|
|
22191
22222
|
if (!await uploadAvatarAsset2(input.client, probe.asset, input.apiBaseUrl)) {
|
|
22192
22223
|
inline2[probe.path] = probe.asset;
|
|
22193
22224
|
}
|
|
@@ -23401,23 +23432,24 @@ function diffLines(oldLines, newLines) {
|
|
|
23401
23432
|
}
|
|
23402
23433
|
function collapseContext(lines) {
|
|
23403
23434
|
const collapsed = [];
|
|
23404
|
-
let
|
|
23435
|
+
let session = [];
|
|
23405
23436
|
const flush = (isLeading, isTrailing) => {
|
|
23406
23437
|
const keepStart = isLeading ? 0 : DIFF_CONTEXT_LINES;
|
|
23407
23438
|
const keepEnd = isTrailing ? 0 : DIFF_CONTEXT_LINES;
|
|
23408
|
-
if (
|
|
23409
|
-
collapsed.push(...
|
|
23439
|
+
if (session.length <= keepStart + keepEnd + 1) {
|
|
23440
|
+
collapsed.push(...session);
|
|
23410
23441
|
} else {
|
|
23411
|
-
collapsed.push(...
|
|
23442
|
+
collapsed.push(...session.slice(0, keepStart));
|
|
23412
23443
|
collapsed.push({ type: "gap", text: "" });
|
|
23413
|
-
if (keepEnd > 0)
|
|
23444
|
+
if (keepEnd > 0)
|
|
23445
|
+
collapsed.push(...session.slice(session.length - keepEnd));
|
|
23414
23446
|
}
|
|
23415
|
-
|
|
23447
|
+
session = [];
|
|
23416
23448
|
};
|
|
23417
23449
|
let seenChange = false;
|
|
23418
23450
|
for (const line of lines) {
|
|
23419
23451
|
if (line.type === "context") {
|
|
23420
|
-
|
|
23452
|
+
session.push(line);
|
|
23421
23453
|
continue;
|
|
23422
23454
|
}
|
|
23423
23455
|
flush(!seenChange, false);
|
|
@@ -24267,7 +24299,7 @@ import TextInput2 from "ink-text-input";
|
|
|
24267
24299
|
import { useCallback, useEffect as useEffect2, useMemo as useMemo2, useRef, useState as useState2 } from "react";
|
|
24268
24300
|
import { Fragment as Fragment2, jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
24269
24301
|
function ConversationView({
|
|
24270
|
-
|
|
24302
|
+
sessionId,
|
|
24271
24303
|
agentName,
|
|
24272
24304
|
workingDirectory,
|
|
24273
24305
|
apiUrl
|
|
@@ -24285,7 +24317,7 @@ function ConversationView({
|
|
|
24285
24317
|
const [completedTurn, setCompletedTurn] = useState2(null);
|
|
24286
24318
|
const turnRef = useRef({
|
|
24287
24319
|
startedAt: Date.now(),
|
|
24288
|
-
word: pickActivityWord(
|
|
24320
|
+
word: pickActivityWord(sessionId)
|
|
24289
24321
|
});
|
|
24290
24322
|
const sawLiveTurnActivity = useRef(false);
|
|
24291
24323
|
const pendingLocalCommand = useRef(false);
|
|
@@ -24308,11 +24340,11 @@ function ConversationView({
|
|
|
24308
24340
|
const seenDiagnosticIds = useRef(/* @__PURE__ */ new Set());
|
|
24309
24341
|
const [selectedCommandIndex, setSelectedCommandIndex] = useState2(0);
|
|
24310
24342
|
const applyRunSnapshot = useCallback(
|
|
24311
|
-
(
|
|
24312
|
-
setStatus(
|
|
24343
|
+
(session) => {
|
|
24344
|
+
setStatus(session.status);
|
|
24313
24345
|
if (shouldAcceptUserInputFromRunSnapshot({
|
|
24314
|
-
status:
|
|
24315
|
-
runInput:
|
|
24346
|
+
status: session.status,
|
|
24347
|
+
runInput: session.input,
|
|
24316
24348
|
hasConversationActivity: hasConversationActivity.current,
|
|
24317
24349
|
hasPendingLocalCommand: pendingLocalCommand.current
|
|
24318
24350
|
})) {
|
|
@@ -24387,7 +24419,7 @@ function ConversationView({
|
|
|
24387
24419
|
void (async () => {
|
|
24388
24420
|
while (!abort.signal.aborted) {
|
|
24389
24421
|
try {
|
|
24390
|
-
await client.
|
|
24422
|
+
await client.streamSessionConversation(sessionId, {
|
|
24391
24423
|
apiBaseUrl: apiUrl,
|
|
24392
24424
|
signal: abort.signal,
|
|
24393
24425
|
cursor,
|
|
@@ -24404,16 +24436,16 @@ function ConversationView({
|
|
|
24404
24436
|
await sleep2(250, abort.signal);
|
|
24405
24437
|
}
|
|
24406
24438
|
})();
|
|
24407
|
-
void client.
|
|
24439
|
+
void client.getSession(sessionId, { apiBaseUrl: apiUrl }).then(applyRunSnapshot).catch(() => void 0);
|
|
24408
24440
|
const statusPoll = setInterval(() => {
|
|
24409
|
-
void client.
|
|
24441
|
+
void client.getSession(sessionId, { apiBaseUrl: apiUrl }).then(applyRunSnapshot).catch(() => void 0);
|
|
24410
24442
|
}, 2e3);
|
|
24411
24443
|
return () => {
|
|
24412
24444
|
abort.abort();
|
|
24413
24445
|
clearInterval(statusPoll);
|
|
24414
24446
|
buffer.dispose();
|
|
24415
24447
|
};
|
|
24416
|
-
}, [
|
|
24448
|
+
}, [sessionId, apiUrl, client, applyRunSnapshot, updateAwaitingReply]);
|
|
24417
24449
|
useEffect2(() => {
|
|
24418
24450
|
if (!debugActive) {
|
|
24419
24451
|
return;
|
|
@@ -24422,7 +24454,7 @@ function ConversationView({
|
|
|
24422
24454
|
void (async () => {
|
|
24423
24455
|
while (!abort.signal.aborted) {
|
|
24424
24456
|
try {
|
|
24425
|
-
await client.
|
|
24457
|
+
await client.streamSessionDiagnostics(sessionId, {
|
|
24426
24458
|
apiBaseUrl: apiUrl,
|
|
24427
24459
|
signal: abort.signal,
|
|
24428
24460
|
onEvent: (event) => {
|
|
@@ -24439,9 +24471,9 @@ function ConversationView({
|
|
|
24439
24471
|
}
|
|
24440
24472
|
setDiagnostics(
|
|
24441
24473
|
(prev) => mergeDiagnosticEvent(prev, {
|
|
24442
|
-
type: "
|
|
24474
|
+
type: "session.diagnostic",
|
|
24443
24475
|
id: `local-diagnostics-error-${Date.now()}`,
|
|
24444
|
-
|
|
24476
|
+
sessionId,
|
|
24445
24477
|
level: "warn",
|
|
24446
24478
|
source: "web",
|
|
24447
24479
|
phase: "runtime",
|
|
@@ -24463,7 +24495,7 @@ function ConversationView({
|
|
|
24463
24495
|
return () => {
|
|
24464
24496
|
abort.abort();
|
|
24465
24497
|
};
|
|
24466
|
-
}, [debugActive,
|
|
24498
|
+
}, [debugActive, sessionId, apiUrl, client]);
|
|
24467
24499
|
const isFailed = status === "failed";
|
|
24468
24500
|
const showPalette = input.startsWith("/") && !isFailed;
|
|
24469
24501
|
const paletteQuery = showPalette ? input.slice(1) : "";
|
|
@@ -24511,21 +24543,21 @@ function ConversationView({
|
|
|
24511
24543
|
}
|
|
24512
24544
|
try {
|
|
24513
24545
|
const receipt = pendingQuestionToolCallId ? await client.sendAnswer(
|
|
24514
|
-
|
|
24546
|
+
sessionId,
|
|
24515
24547
|
{
|
|
24516
24548
|
toolCallId: pendingQuestionToolCallId,
|
|
24517
24549
|
answers: {},
|
|
24518
24550
|
response: text
|
|
24519
24551
|
},
|
|
24520
24552
|
{ apiBaseUrl: apiUrl }
|
|
24521
|
-
) : await client.sendMessage(
|
|
24553
|
+
) : await client.sendMessage(sessionId, text, {
|
|
24522
24554
|
apiBaseUrl: apiUrl
|
|
24523
24555
|
});
|
|
24524
24556
|
const createdAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
24525
24557
|
const localEntry = {
|
|
24526
24558
|
type: "conversation.entry",
|
|
24527
24559
|
id: `local-${receipt.command_id}`,
|
|
24528
|
-
|
|
24560
|
+
sessionId,
|
|
24529
24561
|
sequence: -1,
|
|
24530
24562
|
messageId: receipt.command_id,
|
|
24531
24563
|
role: "user",
|
|
@@ -24554,7 +24586,7 @@ function ConversationView({
|
|
|
24554
24586
|
}
|
|
24555
24587
|
},
|
|
24556
24588
|
[
|
|
24557
|
-
|
|
24589
|
+
sessionId,
|
|
24558
24590
|
apiUrl,
|
|
24559
24591
|
client,
|
|
24560
24592
|
sending,
|
|
@@ -24583,7 +24615,7 @@ function ConversationView({
|
|
|
24583
24615
|
setAnsweredQuestionIds((prev) => new Set(prev).add(toolCallId));
|
|
24584
24616
|
try {
|
|
24585
24617
|
await client.sendAnswer(
|
|
24586
|
-
|
|
24618
|
+
sessionId,
|
|
24587
24619
|
{ toolCallId, answers: submit.answers },
|
|
24588
24620
|
{ apiBaseUrl: apiUrl }
|
|
24589
24621
|
);
|
|
@@ -24600,7 +24632,7 @@ function ConversationView({
|
|
|
24600
24632
|
setSending(false);
|
|
24601
24633
|
}
|
|
24602
24634
|
},
|
|
24603
|
-
[
|
|
24635
|
+
[sessionId, apiUrl, client, sending, isFailed, updateAwaitingReply]
|
|
24604
24636
|
);
|
|
24605
24637
|
const commands = [
|
|
24606
24638
|
{
|
|
@@ -24616,7 +24648,7 @@ function ConversationView({
|
|
|
24616
24648
|
{
|
|
24617
24649
|
name: "/debug",
|
|
24618
24650
|
aliases: debugActive ? ["/debug-off"] : ["/debug-on"],
|
|
24619
|
-
description: debugActive ? "Hide
|
|
24651
|
+
description: debugActive ? "Hide session diagnostics" : "Show live session diagnostics",
|
|
24620
24652
|
action: () => {
|
|
24621
24653
|
setInput("");
|
|
24622
24654
|
setDebugActive((active) => {
|
|
@@ -24650,8 +24682,8 @@ function ConversationView({
|
|
|
24650
24682
|
/* @__PURE__ */ jsx4(Text4, { children: agentName })
|
|
24651
24683
|
] }),
|
|
24652
24684
|
/* @__PURE__ */ jsxs4(Box4, { gap: 2, children: [
|
|
24653
|
-
/* @__PURE__ */ jsx4(Text4, { color: "yellow", children: "
|
|
24654
|
-
/* @__PURE__ */ jsx4(Text4, { dimColor: true, children:
|
|
24685
|
+
/* @__PURE__ */ jsx4(Text4, { color: "yellow", children: "Session " }),
|
|
24686
|
+
/* @__PURE__ */ jsx4(Text4, { dimColor: true, children: sessionId })
|
|
24655
24687
|
] }),
|
|
24656
24688
|
workingDirectory && /* @__PURE__ */ jsxs4(Box4, { gap: 2, children: [
|
|
24657
24689
|
/* @__PURE__ */ jsx4(Text4, { color: "yellow", children: "cwd " }),
|
|
@@ -24698,7 +24730,7 @@ function ConversationView({
|
|
|
24698
24730
|
/* @__PURE__ */ jsxs4(Box4, { flexDirection: "column", borderStyle: "round", paddingX: 1, children: [
|
|
24699
24731
|
isFailed ? /* @__PURE__ */ jsxs4(Box4, { children: [
|
|
24700
24732
|
/* @__PURE__ */ jsx4(Text4, { color: "red", bold: true, children: "\u2717 " }),
|
|
24701
|
-
/* @__PURE__ */ jsx4(Text4, { dimColor: true, children: "
|
|
24733
|
+
/* @__PURE__ */ jsx4(Text4, { dimColor: true, children: "session failed" })
|
|
24702
24734
|
] }) : showQuestionPrompt && pendingQuestion ? /* @__PURE__ */ jsx4(
|
|
24703
24735
|
QuestionPrompt,
|
|
24704
24736
|
{
|
|
@@ -24740,7 +24772,7 @@ function ConversationView({
|
|
|
24740
24772
|
/* @__PURE__ */ jsxs4(Box4, { gap: 2, children: [
|
|
24741
24773
|
/* @__PURE__ */ jsx4(Text4, { dimColor: true, children: agentName }),
|
|
24742
24774
|
/* @__PURE__ */ jsx4(Text4, { dimColor: true, children: "\xB7" }),
|
|
24743
|
-
/* @__PURE__ */ jsx4(Text4, { dimColor: true, children:
|
|
24775
|
+
/* @__PURE__ */ jsx4(Text4, { dimColor: true, children: sessionId })
|
|
24744
24776
|
] }),
|
|
24745
24777
|
/* @__PURE__ */ jsxs4(Text4, { dimColor: true, children: [
|
|
24746
24778
|
awaitingReply && !isFailed ? "working" : status,
|
|
@@ -25099,7 +25131,7 @@ function agentConfigLabel(agent) {
|
|
|
25099
25131
|
const pieces = [
|
|
25100
25132
|
agent.spec.harness,
|
|
25101
25133
|
agent.spec.environment ? `env:${agent.spec.environment}` : void 0,
|
|
25102
|
-
`${agent.status.runCount}
|
|
25134
|
+
`${agent.status.runCount} sessions`
|
|
25103
25135
|
].filter(Boolean);
|
|
25104
25136
|
return pieces.join(" ");
|
|
25105
25137
|
}
|
|
@@ -25629,15 +25661,15 @@ function useIdentities(apiUrl) {
|
|
|
25629
25661
|
const client = useApiClient();
|
|
25630
25662
|
return useQuery(identitiesQueryOptions(client, apiUrl));
|
|
25631
25663
|
}
|
|
25632
|
-
function
|
|
25664
|
+
function useAgentSessions(agentName, apiUrl, includeArchived = false) {
|
|
25633
25665
|
const client = useApiClient();
|
|
25634
25666
|
return useQuery(
|
|
25635
|
-
|
|
25667
|
+
agentSessionsQueryOptions(client, agentName, apiUrl, includeArchived)
|
|
25636
25668
|
);
|
|
25637
25669
|
}
|
|
25638
|
-
function
|
|
25670
|
+
function useSessions(apiUrl, includeArchived = false) {
|
|
25639
25671
|
const client = useApiClient();
|
|
25640
|
-
return useQuery(
|
|
25672
|
+
return useQuery(sessionsQueryOptions(client, apiUrl, includeArchived));
|
|
25641
25673
|
}
|
|
25642
25674
|
function useProjects(apiUrl) {
|
|
25643
25675
|
const client = useApiClient();
|
|
@@ -25819,15 +25851,18 @@ function useRemoveConnection(apiUrl) {
|
|
|
25819
25851
|
})
|
|
25820
25852
|
});
|
|
25821
25853
|
}
|
|
25822
|
-
function
|
|
25854
|
+
function useTriggerSession(apiUrl) {
|
|
25823
25855
|
const client = useApiClient();
|
|
25824
25856
|
const queryClient = useQueryClient();
|
|
25825
25857
|
return useMutation({
|
|
25826
|
-
mutationFn: (agentName) => client.
|
|
25858
|
+
mutationFn: (agentName) => client.triggerSession(agentName, {
|
|
25859
|
+
interactive: true,
|
|
25860
|
+
apiBaseUrl: apiUrl
|
|
25861
|
+
}),
|
|
25827
25862
|
onSuccess: (_created, agentName) => {
|
|
25828
|
-
void queryClient.invalidateQueries({ queryKey: ["
|
|
25863
|
+
void queryClient.invalidateQueries({ queryKey: ["sessions", apiUrl] });
|
|
25829
25864
|
void queryClient.invalidateQueries({
|
|
25830
|
-
queryKey: ["agent-
|
|
25865
|
+
queryKey: ["agent-sessions", agentName, apiUrl]
|
|
25831
25866
|
});
|
|
25832
25867
|
void queryClient.invalidateQueries({
|
|
25833
25868
|
queryKey: queryKeys.agents(apiUrl)
|
|
@@ -25839,40 +25874,40 @@ function useArchiveRuns(apiUrl) {
|
|
|
25839
25874
|
const client = useApiClient();
|
|
25840
25875
|
const queryClient = useQueryClient();
|
|
25841
25876
|
return useMutation({
|
|
25842
|
-
mutationFn: (
|
|
25843
|
-
onSuccess: (result) => invalidateRunsQueries(queryClient, apiUrl, result.
|
|
25877
|
+
mutationFn: (sessionIds) => client.archiveSessions(sessionIds, { apiBaseUrl: apiUrl }),
|
|
25878
|
+
onSuccess: (result) => invalidateRunsQueries(queryClient, apiUrl, result.sessions)
|
|
25844
25879
|
});
|
|
25845
25880
|
}
|
|
25846
|
-
function
|
|
25881
|
+
function useUnarchiveSessions(apiUrl) {
|
|
25847
25882
|
const client = useApiClient();
|
|
25848
25883
|
const queryClient = useQueryClient();
|
|
25849
25884
|
return useMutation({
|
|
25850
|
-
mutationFn: (
|
|
25851
|
-
onSuccess: (result) => invalidateRunsQueries(queryClient, apiUrl, result.
|
|
25885
|
+
mutationFn: (sessionIds) => client.unarchiveSessions(sessionIds, { apiBaseUrl: apiUrl }),
|
|
25886
|
+
onSuccess: (result) => invalidateRunsQueries(queryClient, apiUrl, result.sessions)
|
|
25852
25887
|
});
|
|
25853
25888
|
}
|
|
25854
|
-
function
|
|
25889
|
+
function useStopSessions(apiUrl) {
|
|
25855
25890
|
const client = useApiClient();
|
|
25856
25891
|
const queryClient = useQueryClient();
|
|
25857
25892
|
return useMutation({
|
|
25858
|
-
mutationFn: (
|
|
25859
|
-
(
|
|
25860
|
-
|
|
25893
|
+
mutationFn: (sessionIds) => stopSessionsBatch(
|
|
25894
|
+
(sessionId) => client.stopSession(sessionId, { apiBaseUrl: apiUrl }),
|
|
25895
|
+
sessionIds
|
|
25861
25896
|
),
|
|
25862
|
-
//
|
|
25863
|
-
//
|
|
25897
|
+
// stopSession returns a command receipt, not session records, so invalidate the
|
|
25898
|
+
// session-list query families directly to pick up the new statuses.
|
|
25864
25899
|
onSuccess: () => invalidateRunListQueries(queryClient, apiUrl)
|
|
25865
25900
|
});
|
|
25866
25901
|
}
|
|
25867
|
-
async function
|
|
25902
|
+
async function stopSessionsBatch(stopSession, sessionIds) {
|
|
25868
25903
|
const outcomes = await Promise.all(
|
|
25869
|
-
|
|
25904
|
+
sessionIds.map(async (sessionId) => {
|
|
25870
25905
|
try {
|
|
25871
|
-
await
|
|
25872
|
-
return {
|
|
25906
|
+
await stopSession(sessionId);
|
|
25907
|
+
return { sessionId, ok: true, message: "" };
|
|
25873
25908
|
} catch (error51) {
|
|
25874
25909
|
return {
|
|
25875
|
-
|
|
25910
|
+
sessionId,
|
|
25876
25911
|
ok: false,
|
|
25877
25912
|
message: error51 instanceof Error ? error51.message : String(error51)
|
|
25878
25913
|
};
|
|
@@ -25880,37 +25915,37 @@ async function stopRunsBatch(stopRun, runIds) {
|
|
|
25880
25915
|
})
|
|
25881
25916
|
);
|
|
25882
25917
|
return {
|
|
25883
|
-
stopped: outcomes.filter((o) => o.ok).map((o) => o.
|
|
25884
|
-
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 }))
|
|
25885
25920
|
};
|
|
25886
25921
|
}
|
|
25887
|
-
function
|
|
25922
|
+
function agentSessionsQueryOptions(client, agentName, apiUrl, includeArchived = false) {
|
|
25888
25923
|
return queryOptions({
|
|
25889
|
-
queryKey: queryKeys.
|
|
25924
|
+
queryKey: queryKeys.agentSessions(agentName ?? "", apiUrl, includeArchived),
|
|
25890
25925
|
queryFn: async () => {
|
|
25891
|
-
const res = await client.
|
|
25926
|
+
const res = await client.listAgentSessions(agentName ?? "", {
|
|
25892
25927
|
apiBaseUrl: apiUrl,
|
|
25893
25928
|
includeArchived,
|
|
25894
|
-
// The
|
|
25929
|
+
// The session-list routes default to 50; ask for the server max so the
|
|
25895
25930
|
// TUI keeps showing deep history.
|
|
25896
|
-
limit:
|
|
25931
|
+
limit: TUI_SESSION_LIST_LIMIT
|
|
25897
25932
|
});
|
|
25898
|
-
return res.
|
|
25933
|
+
return res.sessions;
|
|
25899
25934
|
},
|
|
25900
25935
|
enabled: Boolean(agentName),
|
|
25901
25936
|
...runsFreshnessOptions()
|
|
25902
25937
|
});
|
|
25903
25938
|
}
|
|
25904
|
-
function
|
|
25939
|
+
function sessionsQueryOptions(client, apiUrl, includeArchived = false) {
|
|
25905
25940
|
return queryOptions({
|
|
25906
|
-
queryKey: queryKeys.
|
|
25941
|
+
queryKey: queryKeys.sessions(apiUrl, includeArchived),
|
|
25907
25942
|
queryFn: async () => {
|
|
25908
|
-
const res = await client.
|
|
25943
|
+
const res = await client.listSessions({
|
|
25909
25944
|
apiBaseUrl: apiUrl,
|
|
25910
25945
|
includeArchived,
|
|
25911
|
-
limit:
|
|
25946
|
+
limit: TUI_SESSION_LIST_LIMIT
|
|
25912
25947
|
});
|
|
25913
|
-
return res.
|
|
25948
|
+
return res.sessions;
|
|
25914
25949
|
},
|
|
25915
25950
|
...runsFreshnessOptions()
|
|
25916
25951
|
});
|
|
@@ -25919,7 +25954,7 @@ function runsFreshnessOptions() {
|
|
|
25919
25954
|
return {
|
|
25920
25955
|
staleTime: 0,
|
|
25921
25956
|
refetchOnMount: "always",
|
|
25922
|
-
refetchInterval:
|
|
25957
|
+
refetchInterval: SESSIONS_REFETCH_INTERVAL_MS
|
|
25923
25958
|
};
|
|
25924
25959
|
}
|
|
25925
25960
|
function environmentsQueryOptions(client, apiUrl) {
|
|
@@ -26013,27 +26048,27 @@ function sortAgents(list) {
|
|
|
26013
26048
|
function sortByName(list) {
|
|
26014
26049
|
return list.slice().sort((a, b) => a.metadata.name.localeCompare(b.metadata.name));
|
|
26015
26050
|
}
|
|
26016
|
-
function invalidateRunsQueries(queryClient, apiUrl,
|
|
26017
|
-
void queryClient.invalidateQueries({ queryKey: ["
|
|
26051
|
+
function invalidateRunsQueries(queryClient, apiUrl, sessions) {
|
|
26052
|
+
void queryClient.invalidateQueries({ queryKey: ["sessions", apiUrl] });
|
|
26018
26053
|
for (const agentName of new Set(
|
|
26019
|
-
|
|
26054
|
+
sessions.map((session) => session.snapshot.metadata.name)
|
|
26020
26055
|
)) {
|
|
26021
26056
|
void queryClient.invalidateQueries({
|
|
26022
|
-
queryKey: ["
|
|
26057
|
+
queryKey: ["sessions", agentName, apiUrl]
|
|
26023
26058
|
});
|
|
26024
26059
|
}
|
|
26025
26060
|
}
|
|
26026
26061
|
function invalidateRunListQueries(queryClient, apiUrl) {
|
|
26027
|
-
void queryClient.invalidateQueries({ queryKey: ["
|
|
26028
|
-
void queryClient.invalidateQueries({ queryKey: ["
|
|
26062
|
+
void queryClient.invalidateQueries({ queryKey: ["sessions", apiUrl] });
|
|
26063
|
+
void queryClient.invalidateQueries({ queryKey: ["sessions"] });
|
|
26029
26064
|
}
|
|
26030
|
-
var
|
|
26065
|
+
var TUI_SESSION_LIST_LIMIT, queryKeys, SESSIONS_REFETCH_INTERVAL_MS;
|
|
26031
26066
|
var init_queries = __esm({
|
|
26032
26067
|
"src/tui/hooks/queries.ts"() {
|
|
26033
26068
|
"use strict";
|
|
26034
26069
|
init_src();
|
|
26035
26070
|
init_ApiClientContext();
|
|
26036
|
-
|
|
26071
|
+
TUI_SESSION_LIST_LIMIT = 200;
|
|
26037
26072
|
queryKeys = {
|
|
26038
26073
|
environments: (apiUrl) => ["environments", apiUrl],
|
|
26039
26074
|
identities: (apiUrl) => ["identities", apiUrl],
|
|
@@ -26043,10 +26078,10 @@ var init_queries = __esm({
|
|
|
26043
26078
|
connections: (apiUrl) => ["connections", apiUrl],
|
|
26044
26079
|
githubSyncBindings: (apiUrl) => ["github-sync-bindings", apiUrl],
|
|
26045
26080
|
connectionProviders: (apiUrl) => ["connection-providers", apiUrl],
|
|
26046
|
-
|
|
26047
|
-
|
|
26081
|
+
sessions: (apiUrl, includeArchived = false) => ["sessions", apiUrl, includeArchived],
|
|
26082
|
+
agentSessions: (agentName, apiUrl, includeArchived = false) => ["agent-sessions", agentName, apiUrl, includeArchived]
|
|
26048
26083
|
};
|
|
26049
|
-
|
|
26084
|
+
SESSIONS_REFETCH_INTERVAL_MS = 5e3;
|
|
26050
26085
|
}
|
|
26051
26086
|
});
|
|
26052
26087
|
|
|
@@ -26061,15 +26096,15 @@ var init_string = __esm({
|
|
|
26061
26096
|
}
|
|
26062
26097
|
});
|
|
26063
26098
|
|
|
26064
|
-
// src/tui/
|
|
26099
|
+
// src/tui/SessionsView.tsx
|
|
26065
26100
|
import { Box as Box11, Text as Text12, useStdout as useStdout6 } from "ink";
|
|
26066
26101
|
import { jsx as jsx12, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
26067
|
-
function
|
|
26102
|
+
function SessionsView({
|
|
26068
26103
|
scopedAgent,
|
|
26069
26104
|
apiUrl,
|
|
26070
26105
|
selectedIndex = 0,
|
|
26071
26106
|
showArchived = false,
|
|
26072
|
-
|
|
26107
|
+
selectedSessionIds = EMPTY_SELECTED_RUN_IDS
|
|
26073
26108
|
}) {
|
|
26074
26109
|
const { stdout } = useStdout6();
|
|
26075
26110
|
const termWidth = stdout?.columns ?? 120;
|
|
@@ -26079,27 +26114,30 @@ function RunsView({
|
|
|
26079
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
|
|
26080
26115
|
);
|
|
26081
26116
|
const agentName = scopedAgent?.metadata.name;
|
|
26082
|
-
const
|
|
26083
|
-
const
|
|
26084
|
-
const activeQuery = scopedAgent ?
|
|
26085
|
-
const { data:
|
|
26086
|
-
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);
|
|
26087
26122
|
const visibleCount = Math.max(1, termHeight - CHROME_ROWS);
|
|
26088
26123
|
const safeIndex = Math.min(Math.max(0, selectedIndex), sorted.length - 1);
|
|
26089
26124
|
let scrollOffset = Math.max(0, safeIndex - (visibleCount - 1));
|
|
26090
26125
|
if (sorted.length - scrollOffset < visibleCount) {
|
|
26091
26126
|
scrollOffset = Math.max(0, sorted.length - visibleCount);
|
|
26092
26127
|
}
|
|
26093
|
-
const
|
|
26128
|
+
const visibleSessions = sorted.slice(
|
|
26129
|
+
scrollOffset,
|
|
26130
|
+
scrollOffset + visibleCount
|
|
26131
|
+
);
|
|
26094
26132
|
const hiddenAbove = scrollOffset;
|
|
26095
26133
|
const hiddenBelow = Math.max(
|
|
26096
26134
|
0,
|
|
26097
|
-
sorted.length - (scrollOffset +
|
|
26135
|
+
sorted.length - (scrollOffset + visibleSessions.length)
|
|
26098
26136
|
);
|
|
26099
|
-
return /* @__PURE__ */ jsx12(Box11, { flexGrow: 1, flexDirection: "column", children: isLoading ? /* @__PURE__ */ jsx12(Box11, { paddingX: 2, children: /* @__PURE__ */ jsx12(Text12, { dimColor: true, children: "loading
|
|
26100
|
-
"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: ",
|
|
26101
26139
|
String(error51)
|
|
26102
|
-
] }) }) : 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: [
|
|
26103
26141
|
/* @__PURE__ */ jsxs10(Box11, { paddingX: TABLE_PADDING_X, paddingBottom: 1, gap: TABLE_GAP, children: [
|
|
26104
26142
|
/* @__PURE__ */ jsx12(HeaderCell, { width: COL_SELECTED, children: "SEL" }),
|
|
26105
26143
|
/* @__PURE__ */ jsx12(HeaderCell, { width: COL_ID, children: "ID" }),
|
|
@@ -26115,12 +26153,12 @@ function RunsView({
|
|
|
26115
26153
|
hiddenAbove,
|
|
26116
26154
|
" more above"
|
|
26117
26155
|
] }) }),
|
|
26118
|
-
|
|
26156
|
+
visibleSessions.map((session, vi) => {
|
|
26119
26157
|
const i = scrollOffset + vi;
|
|
26120
|
-
const title =
|
|
26121
|
-
const err =
|
|
26158
|
+
const title = sessionDisplayTitle(session);
|
|
26159
|
+
const err = session.status === "failed" ? errorMessage(session) : null;
|
|
26122
26160
|
const isSelected = i === safeIndex;
|
|
26123
|
-
const isMarked =
|
|
26161
|
+
const isMarked = selectedSessionIds.has(session.id);
|
|
26124
26162
|
return /* @__PURE__ */ jsxs10(Box11, { flexDirection: "column", children: [
|
|
26125
26163
|
/* @__PURE__ */ jsxs10(TableRow, { selected: isSelected, children: [
|
|
26126
26164
|
/* @__PURE__ */ jsx12(
|
|
@@ -26141,18 +26179,18 @@ function RunsView({
|
|
|
26141
26179
|
selected: isSelected,
|
|
26142
26180
|
dim: !isSelected,
|
|
26143
26181
|
primary: true,
|
|
26144
|
-
children:
|
|
26182
|
+
children: shortSessionId(session.id)
|
|
26145
26183
|
}
|
|
26146
26184
|
),
|
|
26147
26185
|
/* @__PURE__ */ jsxs10(Box11, { width: COL_STATUS2, gap: 1, children: [
|
|
26148
|
-
/* @__PURE__ */ jsx12(StatusDot, { status:
|
|
26186
|
+
/* @__PURE__ */ jsx12(StatusDot, { status: session.status, selected: isSelected }),
|
|
26149
26187
|
/* @__PURE__ */ jsx12(
|
|
26150
26188
|
Text12,
|
|
26151
26189
|
{
|
|
26152
26190
|
color: isSelected ? "black" : void 0,
|
|
26153
26191
|
dimColor: !isSelected,
|
|
26154
26192
|
wrap: "truncate",
|
|
26155
|
-
children:
|
|
26193
|
+
children: session.status
|
|
26156
26194
|
}
|
|
26157
26195
|
)
|
|
26158
26196
|
] }),
|
|
@@ -26162,7 +26200,7 @@ function RunsView({
|
|
|
26162
26200
|
width: COL_AGENT,
|
|
26163
26201
|
selected: isSelected,
|
|
26164
26202
|
dim: !isSelected,
|
|
26165
|
-
children: agentNameForRun(
|
|
26203
|
+
children: agentNameForRun(session)
|
|
26166
26204
|
}
|
|
26167
26205
|
),
|
|
26168
26206
|
/* @__PURE__ */ jsx12(
|
|
@@ -26171,7 +26209,7 @@ function RunsView({
|
|
|
26171
26209
|
width: COL_TRIGGER,
|
|
26172
26210
|
selected: isSelected,
|
|
26173
26211
|
dim: !isSelected,
|
|
26174
|
-
children: triggerKind(
|
|
26212
|
+
children: triggerKind(session)
|
|
26175
26213
|
}
|
|
26176
26214
|
),
|
|
26177
26215
|
/* @__PURE__ */ jsx12(TableCell, { width: titleWidth, selected: isSelected, children: truncateToWidth(title, titleWidth) }),
|
|
@@ -26182,7 +26220,7 @@ function RunsView({
|
|
|
26182
26220
|
selected: isSelected,
|
|
26183
26221
|
dim: !isSelected,
|
|
26184
26222
|
justifyContent: "flex-end",
|
|
26185
|
-
children: relativeTime3(
|
|
26223
|
+
children: relativeTime3(session.startedAt ?? session.createdAt)
|
|
26186
26224
|
}
|
|
26187
26225
|
),
|
|
26188
26226
|
/* @__PURE__ */ jsx12(
|
|
@@ -26192,7 +26230,7 @@ function RunsView({
|
|
|
26192
26230
|
selected: isSelected,
|
|
26193
26231
|
dim: !isSelected,
|
|
26194
26232
|
justifyContent: "flex-end",
|
|
26195
|
-
children: duration3(
|
|
26233
|
+
children: duration3(session)
|
|
26196
26234
|
}
|
|
26197
26235
|
)
|
|
26198
26236
|
] }),
|
|
@@ -26200,7 +26238,7 @@ function RunsView({
|
|
|
26200
26238
|
"\u2514 ",
|
|
26201
26239
|
fitToWidth(err, Math.max(40, termWidth - 20))
|
|
26202
26240
|
] }) })
|
|
26203
|
-
] },
|
|
26241
|
+
] }, session.id);
|
|
26204
26242
|
}),
|
|
26205
26243
|
hiddenBelow > 0 && /* @__PURE__ */ jsx12(Box11, { paddingX: 2, children: /* @__PURE__ */ jsxs10(Text12, { dimColor: true, children: [
|
|
26206
26244
|
"\u2193 ",
|
|
@@ -26220,10 +26258,10 @@ function relativeTime3(dateStr) {
|
|
|
26220
26258
|
const d = Math.floor(h / 24);
|
|
26221
26259
|
return `${d}d ago`;
|
|
26222
26260
|
}
|
|
26223
|
-
function duration3(
|
|
26224
|
-
if (!
|
|
26225
|
-
const end =
|
|
26226
|
-
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();
|
|
26227
26265
|
const s = Math.max(0, Math.floor(ms / 1e3));
|
|
26228
26266
|
if (s < 60) return `${s}s`;
|
|
26229
26267
|
const m = Math.floor(s / 60);
|
|
@@ -26231,7 +26269,7 @@ function duration3(run) {
|
|
|
26231
26269
|
const h = Math.floor(m / 60);
|
|
26232
26270
|
return `${h}h${m % 60 ? ` ${m % 60}m` : ""}`;
|
|
26233
26271
|
}
|
|
26234
|
-
function
|
|
26272
|
+
function shortSessionId(id) {
|
|
26235
26273
|
const tail = id.split("-").pop();
|
|
26236
26274
|
return tail ? tail.slice(0, 12) : id.slice(0, 12);
|
|
26237
26275
|
}
|
|
@@ -26241,40 +26279,42 @@ function readField(value, key) {
|
|
|
26241
26279
|
}
|
|
26242
26280
|
return void 0;
|
|
26243
26281
|
}
|
|
26244
|
-
function triggerKind(
|
|
26245
|
-
const t = readField(
|
|
26282
|
+
function triggerKind(session) {
|
|
26283
|
+
const t = readField(session.input, "trigger");
|
|
26246
26284
|
return typeof t === "string" ? t : "\u2014";
|
|
26247
26285
|
}
|
|
26248
|
-
function
|
|
26249
|
-
return
|
|
26286
|
+
function sessionDisplayTitle(session) {
|
|
26287
|
+
return session.displayTitle.replace(/\s+/g, " ").trim();
|
|
26250
26288
|
}
|
|
26251
26289
|
function truncateToWidth(value, width) {
|
|
26252
26290
|
if (!value) return " ";
|
|
26253
26291
|
if (value.length <= width) return value;
|
|
26254
26292
|
return `${value.slice(0, Math.max(0, width - 1))}\u2026`;
|
|
26255
26293
|
}
|
|
26256
|
-
function agentNameForRun(
|
|
26257
|
-
return
|
|
26294
|
+
function agentNameForRun(session) {
|
|
26295
|
+
return session.snapshot.metadata.name;
|
|
26258
26296
|
}
|
|
26259
|
-
function errorMessage(
|
|
26260
|
-
if (
|
|
26261
|
-
if (typeof
|
|
26262
|
-
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");
|
|
26263
26301
|
if (typeof msg === "string") return msg;
|
|
26264
26302
|
try {
|
|
26265
|
-
return JSON.stringify(
|
|
26303
|
+
return JSON.stringify(session.error);
|
|
26266
26304
|
} catch {
|
|
26267
26305
|
return null;
|
|
26268
26306
|
}
|
|
26269
26307
|
}
|
|
26270
|
-
function
|
|
26271
|
-
return
|
|
26308
|
+
function sessionsForArchiveMode(sessions, showArchived) {
|
|
26309
|
+
return sessions.filter(
|
|
26310
|
+
(session) => showArchived ? Boolean(session.archivedAt) : !session.archivedAt
|
|
26311
|
+
).slice().sort(
|
|
26272
26312
|
(a, b) => new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime()
|
|
26273
26313
|
);
|
|
26274
26314
|
}
|
|
26275
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;
|
|
26276
|
-
var
|
|
26277
|
-
"src/tui/
|
|
26316
|
+
var init_SessionsView = __esm({
|
|
26317
|
+
"src/tui/SessionsView.tsx"() {
|
|
26278
26318
|
"use strict";
|
|
26279
26319
|
init_StatusDot();
|
|
26280
26320
|
init_Table();
|
|
@@ -26455,27 +26495,27 @@ function HomeView({ apiUrl, notice, returnToAgent }) {
|
|
|
26455
26495
|
const termWidth = termSize.width;
|
|
26456
26496
|
const termHeight = termSize.height;
|
|
26457
26497
|
const [activeSection, setSection] = useState3(
|
|
26458
|
-
returnToAgent ? "
|
|
26498
|
+
returnToAgent ? "sessions" : "agents"
|
|
26459
26499
|
);
|
|
26460
26500
|
const [agentIndex, setAgentIndex] = useState3(0);
|
|
26461
26501
|
const [environmentIndex, setEnvironmentIndex] = useState3(0);
|
|
26462
26502
|
const [identityIndex, setIdentityIndex] = useState3(0);
|
|
26463
26503
|
const [projectIndex, setProjectIndex] = useState3(0);
|
|
26464
26504
|
const [serviceAccountIndex, setServiceAccountIndex] = useState3(0);
|
|
26465
|
-
const [
|
|
26505
|
+
const [sessionIndex, setSessionIndex] = useState3(0);
|
|
26466
26506
|
const [runScopeAgentName, setRunScopeAgentName] = useState3(
|
|
26467
26507
|
returnToAgent ?? null
|
|
26468
26508
|
);
|
|
26469
|
-
const [
|
|
26470
|
-
const [
|
|
26509
|
+
const [showArchivedSessions, setShowArchivedSessions] = useState3(false);
|
|
26510
|
+
const [selectedSessionIds, setSelectedSessionIds] = useState3(
|
|
26471
26511
|
() => /* @__PURE__ */ new Set()
|
|
26472
26512
|
);
|
|
26473
26513
|
const [pendingArchiveRunKey, setPendingArchiveRunKey] = useState3(null);
|
|
26474
|
-
const [
|
|
26514
|
+
const [pendingUnarchiveSessionKey, setPendingUnarchiveSessionKey] = useState3(null);
|
|
26475
26515
|
const [pendingStopRunKey, setPendingStopRunKey] = useState3(
|
|
26476
26516
|
null
|
|
26477
26517
|
);
|
|
26478
|
-
const [
|
|
26518
|
+
const [sessionNotice, setSessionNotice] = useState3(null);
|
|
26479
26519
|
const [connectionIndex, setConnectionIndex] = useState3(0);
|
|
26480
26520
|
const [connectionProviderIndex, setConnectionProviderIndex] = useState3(0);
|
|
26481
26521
|
const [connectionMode, setConnectionMode] = useState3("connections");
|
|
@@ -26549,10 +26589,10 @@ function HomeView({ apiUrl, notice, returnToAgent }) {
|
|
|
26549
26589
|
const createServiceAccount2 = useCreateServiceAccount(apiUrl);
|
|
26550
26590
|
const rotateServiceAccount2 = useRotateServiceAccount(apiUrl);
|
|
26551
26591
|
const removeServiceAccount2 = useRemoveServiceAccount(apiUrl);
|
|
26552
|
-
const
|
|
26553
|
-
const
|
|
26554
|
-
const
|
|
26555
|
-
const
|
|
26592
|
+
const triggerSession = useTriggerSession(apiUrl);
|
|
26593
|
+
const archiveSessions = useArchiveRuns(apiUrl);
|
|
26594
|
+
const unarchiveSessions = useUnarchiveSessions(apiUrl);
|
|
26595
|
+
const stopSessions = useStopSessions(apiUrl);
|
|
26556
26596
|
const [connectionNotice, setConnectionNotice] = useState3(null);
|
|
26557
26597
|
const [serviceAccountNotice, setServiceAccountNotice] = useState3(null);
|
|
26558
26598
|
const [pendingRemoveConnectionKey, setPendingRemoveConnectionKey] = useState3(null);
|
|
@@ -26649,37 +26689,43 @@ function HomeView({ apiUrl, notice, returnToAgent }) {
|
|
|
26649
26689
|
);
|
|
26650
26690
|
const inspectPanelHeight = Math.max(1, termHeight - 12);
|
|
26651
26691
|
const scopedAgent = runScopeAgentName ? agents.find((agent) => agent.metadata.name === runScopeAgentName) : void 0;
|
|
26652
|
-
const { data:
|
|
26653
|
-
|
|
26692
|
+
const { data: allSessionsRaw = [] } = useSessions(
|
|
26693
|
+
apiUrl,
|
|
26694
|
+
showArchivedSessions
|
|
26695
|
+
);
|
|
26696
|
+
const { data: scopedSessionsRaw = [] } = useAgentSessions(
|
|
26654
26697
|
scopedAgent?.metadata.name,
|
|
26655
26698
|
apiUrl,
|
|
26656
|
-
|
|
26699
|
+
showArchivedSessions
|
|
26700
|
+
);
|
|
26701
|
+
const visibleSessionsRaw = scopedAgent ? scopedSessionsRaw : allSessionsRaw;
|
|
26702
|
+
const visibleSessions = sessionsForArchiveMode(
|
|
26703
|
+
visibleSessionsRaw,
|
|
26704
|
+
showArchivedSessions
|
|
26657
26705
|
);
|
|
26658
|
-
const
|
|
26659
|
-
const
|
|
26660
|
-
|
|
26661
|
-
|
|
26662
|
-
visibleRuns,
|
|
26663
|
-
selectedRunIds
|
|
26706
|
+
const selectedSession = visibleSessions[sessionIndex];
|
|
26707
|
+
const markedSessionIds = selectedSessionIdsForVisibleRuns(
|
|
26708
|
+
visibleSessions,
|
|
26709
|
+
selectedSessionIds
|
|
26664
26710
|
);
|
|
26665
|
-
const
|
|
26711
|
+
const visibleSessionIdKey = visibleSessions.map((session) => session.id).join("\0");
|
|
26666
26712
|
useEffect3(() => {
|
|
26667
|
-
|
|
26668
|
-
}, [
|
|
26713
|
+
setSessionIndex((i) => clampListIndex(i, visibleSessions.length));
|
|
26714
|
+
}, [visibleSessions.length]);
|
|
26669
26715
|
useEffect3(() => {
|
|
26670
|
-
|
|
26716
|
+
setSelectedSessionIds((current) => {
|
|
26671
26717
|
if (current.size === 0) {
|
|
26672
26718
|
return current;
|
|
26673
26719
|
}
|
|
26674
|
-
const
|
|
26675
|
-
|
|
26720
|
+
const visibleSessionIds = new Set(
|
|
26721
|
+
visibleSessionIdKey ? visibleSessionIdKey.split("\0") : []
|
|
26676
26722
|
);
|
|
26677
26723
|
const next = new Set(
|
|
26678
|
-
[...current].filter((
|
|
26724
|
+
[...current].filter((sessionId) => visibleSessionIds.has(sessionId))
|
|
26679
26725
|
);
|
|
26680
26726
|
return next.size === current.size ? current : next;
|
|
26681
26727
|
});
|
|
26682
|
-
}, [
|
|
26728
|
+
}, [visibleSessionIdKey]);
|
|
26683
26729
|
useEffect3(() => {
|
|
26684
26730
|
const environmentName = selectedAgent?.spec.environment;
|
|
26685
26731
|
if (!environmentName) return;
|
|
@@ -26690,168 +26736,183 @@ function HomeView({ apiUrl, notice, returnToAgent }) {
|
|
|
26690
26736
|
}, [environments, selectedAgent]);
|
|
26691
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;
|
|
26692
26738
|
const startRun = useCallback2(() => {
|
|
26693
|
-
if (!scopedAgent ||
|
|
26694
|
-
|
|
26695
|
-
|
|
26739
|
+
if (!scopedAgent || triggerSession.isPending) return;
|
|
26740
|
+
triggerSession.reset();
|
|
26741
|
+
triggerSession.mutate(scopedAgent.metadata.name, {
|
|
26696
26742
|
onSuccess: (created) => {
|
|
26697
26743
|
exit({
|
|
26698
|
-
|
|
26744
|
+
sessionId: created.session_id,
|
|
26699
26745
|
agentName: scopedAgent.metadata.name,
|
|
26700
26746
|
workingDirectory: scopedAgent.spec.workingDirectory
|
|
26701
26747
|
});
|
|
26702
26748
|
}
|
|
26703
26749
|
});
|
|
26704
|
-
}, [scopedAgent,
|
|
26750
|
+
}, [scopedAgent, triggerSession, exit]);
|
|
26705
26751
|
const toggleSelectedRun = useCallback2(() => {
|
|
26706
26752
|
setPendingArchiveRunKey(null);
|
|
26707
|
-
|
|
26753
|
+
setPendingUnarchiveSessionKey(null);
|
|
26708
26754
|
setPendingStopRunKey(null);
|
|
26709
|
-
|
|
26710
|
-
|
|
26711
|
-
|
|
26712
|
-
if (!
|
|
26713
|
-
|
|
26755
|
+
archiveSessions.reset();
|
|
26756
|
+
unarchiveSessions.reset();
|
|
26757
|
+
stopSessions.reset();
|
|
26758
|
+
if (!selectedSession) {
|
|
26759
|
+
setSessionNotice("Select a session before marking it.");
|
|
26714
26760
|
return;
|
|
26715
26761
|
}
|
|
26716
|
-
const wasSelected =
|
|
26717
|
-
|
|
26762
|
+
const wasSelected = selectedSessionIds.has(selectedSession.id);
|
|
26763
|
+
setSelectedSessionIds((current) => {
|
|
26718
26764
|
const next = new Set(current);
|
|
26719
|
-
if (next.has(
|
|
26720
|
-
next.delete(
|
|
26765
|
+
if (next.has(selectedSession.id)) {
|
|
26766
|
+
next.delete(selectedSession.id);
|
|
26721
26767
|
} else {
|
|
26722
|
-
next.add(
|
|
26768
|
+
next.add(selectedSession.id);
|
|
26723
26769
|
}
|
|
26724
26770
|
return next;
|
|
26725
26771
|
});
|
|
26726
|
-
|
|
26727
|
-
wasSelected ? `Unmarked
|
|
26772
|
+
setSessionNotice(
|
|
26773
|
+
wasSelected ? `Unmarked session ${shortSessionId2(selectedSession.id)}.` : `Marked session ${shortSessionId2(selectedSession.id)}.`
|
|
26728
26774
|
);
|
|
26729
|
-
}, [
|
|
26775
|
+
}, [
|
|
26776
|
+
archiveSessions,
|
|
26777
|
+
selectedSession,
|
|
26778
|
+
selectedSessionIds,
|
|
26779
|
+
stopSessions,
|
|
26780
|
+
unarchiveSessions
|
|
26781
|
+
]);
|
|
26730
26782
|
const archiveSelectedRun = useCallback2(() => {
|
|
26731
|
-
|
|
26732
|
-
|
|
26733
|
-
|
|
26734
|
-
|
|
26783
|
+
archiveSessions.reset();
|
|
26784
|
+
unarchiveSessions.reset();
|
|
26785
|
+
stopSessions.reset();
|
|
26786
|
+
setPendingUnarchiveSessionKey(null);
|
|
26735
26787
|
setPendingStopRunKey(null);
|
|
26736
|
-
const
|
|
26737
|
-
|
|
26738
|
-
|
|
26788
|
+
const sessionIds = sessionIdsForArchiveAction({
|
|
26789
|
+
markedSessionIds,
|
|
26790
|
+
selectedSession
|
|
26739
26791
|
});
|
|
26740
|
-
if (
|
|
26741
|
-
|
|
26792
|
+
if (sessionIds.length === 0) {
|
|
26793
|
+
setSessionNotice("Select a session before archiving.");
|
|
26742
26794
|
return;
|
|
26743
26795
|
}
|
|
26744
|
-
const actionKey = runArchiveActionKey(
|
|
26796
|
+
const actionKey = runArchiveActionKey(sessionIds);
|
|
26745
26797
|
if (pendingArchiveRunKey !== actionKey) {
|
|
26746
26798
|
setPendingArchiveRunKey(actionKey);
|
|
26747
|
-
|
|
26748
|
-
`Press a again to archive ${runActionTargetLabel(
|
|
26799
|
+
setSessionNotice(
|
|
26800
|
+
`Press a again to archive ${runActionTargetLabel(sessionIds, markedSessionIds.length)}.`
|
|
26749
26801
|
);
|
|
26750
26802
|
return;
|
|
26751
26803
|
}
|
|
26752
26804
|
setPendingArchiveRunKey(null);
|
|
26753
|
-
|
|
26754
|
-
|
|
26805
|
+
setSessionNotice(null);
|
|
26806
|
+
archiveSessions.mutate(sessionIds, {
|
|
26755
26807
|
onSuccess: (result) => {
|
|
26756
|
-
|
|
26757
|
-
|
|
26808
|
+
setSelectedSessionIds(/* @__PURE__ */ new Set());
|
|
26809
|
+
setSessionNotice(
|
|
26810
|
+
`Archived ${pluralizeRunCount(result.sessions.length)}.`
|
|
26811
|
+
);
|
|
26758
26812
|
}
|
|
26759
26813
|
});
|
|
26760
26814
|
}, [
|
|
26761
|
-
|
|
26762
|
-
|
|
26815
|
+
archiveSessions,
|
|
26816
|
+
markedSessionIds,
|
|
26763
26817
|
pendingArchiveRunKey,
|
|
26764
|
-
|
|
26765
|
-
|
|
26766
|
-
|
|
26818
|
+
selectedSession,
|
|
26819
|
+
stopSessions,
|
|
26820
|
+
unarchiveSessions
|
|
26767
26821
|
]);
|
|
26768
26822
|
const unarchiveSelectedRun = useCallback2(() => {
|
|
26769
|
-
|
|
26770
|
-
|
|
26771
|
-
|
|
26823
|
+
archiveSessions.reset();
|
|
26824
|
+
unarchiveSessions.reset();
|
|
26825
|
+
stopSessions.reset();
|
|
26772
26826
|
setPendingArchiveRunKey(null);
|
|
26773
26827
|
setPendingStopRunKey(null);
|
|
26774
|
-
const
|
|
26775
|
-
|
|
26776
|
-
|
|
26828
|
+
const sessionIds = sessionIdsForArchiveAction({
|
|
26829
|
+
markedSessionIds,
|
|
26830
|
+
selectedSession
|
|
26777
26831
|
});
|
|
26778
|
-
if (
|
|
26779
|
-
|
|
26832
|
+
if (sessionIds.length === 0) {
|
|
26833
|
+
setSessionNotice("Select an archived session before restoring.");
|
|
26780
26834
|
return;
|
|
26781
26835
|
}
|
|
26782
|
-
const actionKey = runArchiveActionKey(
|
|
26783
|
-
if (
|
|
26784
|
-
|
|
26785
|
-
|
|
26786
|
-
`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)}.`
|
|
26787
26841
|
);
|
|
26788
26842
|
return;
|
|
26789
26843
|
}
|
|
26790
|
-
|
|
26791
|
-
|
|
26792
|
-
|
|
26844
|
+
setPendingUnarchiveSessionKey(null);
|
|
26845
|
+
setSessionNotice(null);
|
|
26846
|
+
unarchiveSessions.mutate(sessionIds, {
|
|
26793
26847
|
onSuccess: (result) => {
|
|
26794
|
-
|
|
26795
|
-
|
|
26848
|
+
setSelectedSessionIds(/* @__PURE__ */ new Set());
|
|
26849
|
+
setSessionNotice(
|
|
26850
|
+
`Restored ${pluralizeRunCount(result.sessions.length)}.`
|
|
26851
|
+
);
|
|
26796
26852
|
}
|
|
26797
26853
|
});
|
|
26798
26854
|
}, [
|
|
26799
|
-
|
|
26800
|
-
|
|
26801
|
-
|
|
26802
|
-
|
|
26803
|
-
|
|
26804
|
-
|
|
26855
|
+
archiveSessions,
|
|
26856
|
+
markedSessionIds,
|
|
26857
|
+
pendingUnarchiveSessionKey,
|
|
26858
|
+
selectedSession,
|
|
26859
|
+
stopSessions,
|
|
26860
|
+
unarchiveSessions
|
|
26805
26861
|
]);
|
|
26806
26862
|
const stopSelectedRuns = useCallback2(() => {
|
|
26807
|
-
|
|
26808
|
-
|
|
26809
|
-
|
|
26863
|
+
stopSessions.reset();
|
|
26864
|
+
archiveSessions.reset();
|
|
26865
|
+
unarchiveSessions.reset();
|
|
26810
26866
|
setPendingArchiveRunKey(null);
|
|
26811
|
-
|
|
26812
|
-
const
|
|
26813
|
-
|
|
26867
|
+
setPendingUnarchiveSessionKey(null);
|
|
26868
|
+
const sessionIds = sessionIdsForArchiveAction({
|
|
26869
|
+
markedSessionIds,
|
|
26870
|
+
selectedSession
|
|
26871
|
+
});
|
|
26872
|
+
if (sessionIds.length === 0) {
|
|
26814
26873
|
setPendingStopRunKey(null);
|
|
26815
|
-
|
|
26874
|
+
setSessionNotice("Select a session before stopping.");
|
|
26816
26875
|
return;
|
|
26817
26876
|
}
|
|
26818
|
-
const runsById = new Map(
|
|
26819
|
-
|
|
26820
|
-
|
|
26877
|
+
const runsById = new Map(
|
|
26878
|
+
visibleSessions.map((session) => [session.id, session])
|
|
26879
|
+
);
|
|
26880
|
+
const { stoppableSessionIds, skippedSessionIds } = partitionRunsForStop(
|
|
26881
|
+
sessionIds,
|
|
26821
26882
|
runsById
|
|
26822
26883
|
);
|
|
26823
|
-
if (
|
|
26884
|
+
if (stoppableSessionIds.length === 0) {
|
|
26824
26885
|
setPendingStopRunKey(null);
|
|
26825
|
-
|
|
26826
|
-
`Nothing to stop \u2014 ${pluralizeRunCount(
|
|
26886
|
+
setSessionNotice(
|
|
26887
|
+
`Nothing to stop \u2014 ${pluralizeRunCount(skippedSessionIds.length)} already stopped or failed.`
|
|
26827
26888
|
);
|
|
26828
26889
|
return;
|
|
26829
26890
|
}
|
|
26830
|
-
const actionKey = runArchiveActionKey(
|
|
26891
|
+
const actionKey = runArchiveActionKey(stoppableSessionIds);
|
|
26831
26892
|
if (pendingStopRunKey !== actionKey) {
|
|
26832
26893
|
setPendingStopRunKey(actionKey);
|
|
26833
|
-
const skipNote =
|
|
26834
|
-
|
|
26835
|
-
`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}.`
|
|
26836
26897
|
);
|
|
26837
26898
|
return;
|
|
26838
26899
|
}
|
|
26839
26900
|
setPendingStopRunKey(null);
|
|
26840
|
-
|
|
26841
|
-
|
|
26901
|
+
setSessionNotice(null);
|
|
26902
|
+
stopSessions.mutate(stoppableSessionIds, {
|
|
26842
26903
|
onSuccess: (result) => {
|
|
26843
|
-
|
|
26844
|
-
|
|
26904
|
+
setSelectedSessionIds(/* @__PURE__ */ new Set());
|
|
26905
|
+
setSessionNotice(stopResultNotice(result, skippedSessionIds.length));
|
|
26845
26906
|
}
|
|
26846
26907
|
});
|
|
26847
26908
|
}, [
|
|
26848
|
-
|
|
26849
|
-
|
|
26909
|
+
archiveSessions,
|
|
26910
|
+
markedSessionIds,
|
|
26850
26911
|
pendingStopRunKey,
|
|
26851
|
-
|
|
26852
|
-
|
|
26853
|
-
|
|
26854
|
-
|
|
26912
|
+
selectedSession,
|
|
26913
|
+
stopSessions,
|
|
26914
|
+
unarchiveSessions,
|
|
26915
|
+
visibleSessions
|
|
26855
26916
|
]);
|
|
26856
26917
|
const projectSelectionRequired = /No active (organization|project)/i.test(authErrorMessage ?? "") && projects.length > 0;
|
|
26857
26918
|
useEffect3(() => {
|
|
@@ -27103,31 +27164,31 @@ function HomeView({ apiUrl, notice, returnToAgent }) {
|
|
|
27103
27164
|
(section) => {
|
|
27104
27165
|
if (section === "agents") {
|
|
27105
27166
|
setSection("agents");
|
|
27106
|
-
|
|
27107
|
-
|
|
27167
|
+
setShowArchivedSessions(false);
|
|
27168
|
+
setSelectedSessionIds(/* @__PURE__ */ new Set());
|
|
27108
27169
|
setPendingArchiveRunKey(null);
|
|
27109
|
-
|
|
27170
|
+
setPendingUnarchiveSessionKey(null);
|
|
27110
27171
|
setPendingStopRunKey(null);
|
|
27111
|
-
|
|
27112
|
-
|
|
27172
|
+
setSessionNotice(null);
|
|
27173
|
+
triggerSession.reset();
|
|
27113
27174
|
return;
|
|
27114
27175
|
}
|
|
27115
|
-
if (section === "
|
|
27176
|
+
if (section === "sessions") {
|
|
27116
27177
|
setRunScopeAgentName(null);
|
|
27117
|
-
|
|
27118
|
-
|
|
27119
|
-
|
|
27178
|
+
setSessionIndex(0);
|
|
27179
|
+
setShowArchivedSessions(false);
|
|
27180
|
+
setSelectedSessionIds(/* @__PURE__ */ new Set());
|
|
27120
27181
|
setPendingArchiveRunKey(null);
|
|
27121
|
-
|
|
27182
|
+
setPendingUnarchiveSessionKey(null);
|
|
27122
27183
|
setPendingStopRunKey(null);
|
|
27123
|
-
|
|
27124
|
-
setSection("
|
|
27125
|
-
|
|
27184
|
+
setSessionNotice(null);
|
|
27185
|
+
setSection("sessions");
|
|
27186
|
+
triggerSession.reset();
|
|
27126
27187
|
return;
|
|
27127
27188
|
}
|
|
27128
27189
|
setSection(section);
|
|
27129
27190
|
},
|
|
27130
|
-
[
|
|
27191
|
+
[triggerSession]
|
|
27131
27192
|
);
|
|
27132
27193
|
useEffect3(() => {
|
|
27133
27194
|
if (activeSection !== "serviceAccounts") {
|
|
@@ -27144,13 +27205,13 @@ function HomeView({ apiUrl, notice, returnToAgent }) {
|
|
|
27144
27205
|
}
|
|
27145
27206
|
}, [activeSection]);
|
|
27146
27207
|
useEffect3(() => {
|
|
27147
|
-
if (activeSection !== "
|
|
27148
|
-
|
|
27208
|
+
if (activeSection !== "sessions") {
|
|
27209
|
+
setSelectedSessionIds(/* @__PURE__ */ new Set());
|
|
27149
27210
|
setPendingArchiveRunKey(null);
|
|
27150
|
-
|
|
27211
|
+
setPendingUnarchiveSessionKey(null);
|
|
27151
27212
|
setPendingStopRunKey(null);
|
|
27152
|
-
|
|
27153
|
-
|
|
27213
|
+
setSessionNotice(null);
|
|
27214
|
+
setShowArchivedSessions(false);
|
|
27154
27215
|
}
|
|
27155
27216
|
}, [activeSection]);
|
|
27156
27217
|
useInput4((input, key) => {
|
|
@@ -27236,77 +27297,77 @@ function HomeView({ apiUrl, notice, returnToAgent }) {
|
|
|
27236
27297
|
}
|
|
27237
27298
|
if (key.return && selectedAgent) {
|
|
27238
27299
|
setRunScopeAgentName(selectedAgent.metadata.name);
|
|
27239
|
-
|
|
27240
|
-
|
|
27241
|
-
|
|
27300
|
+
setSessionIndex(0);
|
|
27301
|
+
setShowArchivedSessions(false);
|
|
27302
|
+
setSelectedSessionIds(/* @__PURE__ */ new Set());
|
|
27242
27303
|
setPendingArchiveRunKey(null);
|
|
27243
|
-
|
|
27304
|
+
setPendingUnarchiveSessionKey(null);
|
|
27244
27305
|
setPendingStopRunKey(null);
|
|
27245
|
-
|
|
27246
|
-
setSection("
|
|
27247
|
-
|
|
27306
|
+
setSessionNotice(null);
|
|
27307
|
+
setSection("sessions");
|
|
27308
|
+
triggerSession.reset();
|
|
27248
27309
|
return;
|
|
27249
27310
|
}
|
|
27250
27311
|
}
|
|
27251
|
-
if (activeSection === "
|
|
27312
|
+
if (activeSection === "sessions") {
|
|
27252
27313
|
if (key.escape) {
|
|
27253
27314
|
setSection("agents");
|
|
27254
|
-
|
|
27315
|
+
triggerSession.reset();
|
|
27255
27316
|
return;
|
|
27256
27317
|
}
|
|
27257
27318
|
if (input === "v") {
|
|
27258
|
-
|
|
27259
|
-
|
|
27260
|
-
|
|
27319
|
+
setShowArchivedSessions((value) => !value);
|
|
27320
|
+
setSessionIndex(0);
|
|
27321
|
+
setSelectedSessionIds(/* @__PURE__ */ new Set());
|
|
27261
27322
|
setPendingArchiveRunKey(null);
|
|
27262
|
-
|
|
27323
|
+
setPendingUnarchiveSessionKey(null);
|
|
27263
27324
|
setPendingStopRunKey(null);
|
|
27264
|
-
|
|
27265
|
-
|
|
27266
|
-
|
|
27267
|
-
|
|
27325
|
+
setSessionNotice(null);
|
|
27326
|
+
archiveSessions.reset();
|
|
27327
|
+
unarchiveSessions.reset();
|
|
27328
|
+
stopSessions.reset();
|
|
27268
27329
|
return;
|
|
27269
27330
|
}
|
|
27270
27331
|
if (input === " ") {
|
|
27271
27332
|
toggleSelectedRun();
|
|
27272
27333
|
return;
|
|
27273
27334
|
}
|
|
27274
|
-
if (input === "n" && scopedAgent && !
|
|
27335
|
+
if (input === "n" && scopedAgent && !showArchivedSessions) {
|
|
27275
27336
|
startRun();
|
|
27276
27337
|
return;
|
|
27277
27338
|
}
|
|
27278
|
-
if (input === "a" && !
|
|
27339
|
+
if (input === "a" && !showArchivedSessions) {
|
|
27279
27340
|
archiveSelectedRun();
|
|
27280
27341
|
return;
|
|
27281
27342
|
}
|
|
27282
|
-
if (input === "s" && !
|
|
27343
|
+
if (input === "s" && !showArchivedSessions) {
|
|
27283
27344
|
stopSelectedRuns();
|
|
27284
27345
|
return;
|
|
27285
27346
|
}
|
|
27286
|
-
if (input === "u" &&
|
|
27347
|
+
if (input === "u" && showArchivedSessions) {
|
|
27287
27348
|
unarchiveSelectedRun();
|
|
27288
27349
|
return;
|
|
27289
27350
|
}
|
|
27290
27351
|
if (key.upArrow) {
|
|
27291
27352
|
setPendingArchiveRunKey(null);
|
|
27292
|
-
|
|
27353
|
+
setPendingUnarchiveSessionKey(null);
|
|
27293
27354
|
setPendingStopRunKey(null);
|
|
27294
|
-
|
|
27355
|
+
setSessionIndex((i) => Math.max(0, i - 1));
|
|
27295
27356
|
return;
|
|
27296
27357
|
}
|
|
27297
27358
|
if (key.downArrow) {
|
|
27298
27359
|
setPendingArchiveRunKey(null);
|
|
27299
|
-
|
|
27360
|
+
setPendingUnarchiveSessionKey(null);
|
|
27300
27361
|
setPendingStopRunKey(null);
|
|
27301
|
-
|
|
27362
|
+
setSessionIndex((i) => clampListIndex(i + 1, visibleSessions.length));
|
|
27302
27363
|
return;
|
|
27303
27364
|
}
|
|
27304
|
-
if (key.return &&
|
|
27305
|
-
const
|
|
27365
|
+
if (key.return && visibleSessions[sessionIndex]) {
|
|
27366
|
+
const session = visibleSessions[sessionIndex];
|
|
27306
27367
|
exit({
|
|
27307
|
-
|
|
27308
|
-
agentName:
|
|
27309
|
-
workingDirectory:
|
|
27368
|
+
sessionId: session.id,
|
|
27369
|
+
agentName: session.snapshot.metadata.name,
|
|
27370
|
+
workingDirectory: session.snapshot.spec.workingDirectory
|
|
27310
27371
|
});
|
|
27311
27372
|
return;
|
|
27312
27373
|
}
|
|
@@ -27642,12 +27703,12 @@ function HomeView({ apiUrl, notice, returnToAgent }) {
|
|
|
27642
27703
|
case "connections":
|
|
27643
27704
|
sectionTitle = connectionMode === "providers" ? `Providers[${connectionProviderRowCount}]` : `Connections[${connectionRowCount}]`;
|
|
27644
27705
|
break;
|
|
27645
|
-
case "
|
|
27646
|
-
const selectedSuffix =
|
|
27706
|
+
case "sessions": {
|
|
27707
|
+
const selectedSuffix = markedSessionIds.length > 0 ? `, ${markedSessionIds.length} selected` : "";
|
|
27647
27708
|
if (scopedAgent) {
|
|
27648
|
-
sectionTitle =
|
|
27709
|
+
sectionTitle = showArchivedSessions ? `Agent Sessions[${scopedAgent.metadata.name}: ${visibleSessions.length} archived${selectedSuffix}]` : `Agent Sessions[${scopedAgent.metadata.name}: ${visibleSessions.length}${selectedSuffix}]`;
|
|
27649
27710
|
} else {
|
|
27650
|
-
sectionTitle =
|
|
27711
|
+
sectionTitle = showArchivedSessions ? `Sessions[${visibleSessions.length} archived${selectedSuffix}]` : `Sessions[${visibleSessions.length}${selectedSuffix}]`;
|
|
27651
27712
|
}
|
|
27652
27713
|
break;
|
|
27653
27714
|
}
|
|
@@ -27655,8 +27716,8 @@ function HomeView({ apiUrl, notice, returnToAgent }) {
|
|
|
27655
27716
|
if (inspectedResource) {
|
|
27656
27717
|
sectionTitle = `Inspect ${inspectedResource.kind}/${inspectedResource.name}`;
|
|
27657
27718
|
}
|
|
27658
|
-
const runError = errorMessage2(
|
|
27659
|
-
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;
|
|
27660
27721
|
const isConnectionMutationPending = startConnection.isPending || allowConnection.isPending || removeConnection.isPending || createGithubSyncBinding.isPending;
|
|
27661
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;
|
|
27662
27723
|
const isServiceAccountMutationPending = createServiceAccount2.isPending || rotateServiceAccount2.isPending || removeServiceAccount2.isPending;
|
|
@@ -27687,15 +27748,15 @@ function HomeView({ apiUrl, notice, returnToAgent }) {
|
|
|
27687
27748
|
Spinner,
|
|
27688
27749
|
{
|
|
27689
27750
|
label: runMutationStatusLabel({
|
|
27690
|
-
starting:
|
|
27691
|
-
archiving:
|
|
27692
|
-
stopping:
|
|
27751
|
+
starting: triggerSession.isPending,
|
|
27752
|
+
archiving: archiveSessions.isPending,
|
|
27753
|
+
stopping: stopSessions.isPending
|
|
27693
27754
|
})
|
|
27694
27755
|
}
|
|
27695
27756
|
)
|
|
27696
27757
|
}
|
|
27697
27758
|
),
|
|
27698
|
-
(
|
|
27759
|
+
(sessionNotice ?? notice) && /* @__PURE__ */ jsx14(KV, { label: "Notice", value: sessionNotice ?? notice })
|
|
27699
27760
|
] }),
|
|
27700
27761
|
/* @__PURE__ */ jsxs12(Box13, { gap: 3, flexShrink: 0, children: [
|
|
27701
27762
|
resourceColumns.map((col) => /* @__PURE__ */ jsx14(Box13, { flexDirection: "column", children: col.map(({ k, label, activeSection: p }) => /* @__PURE__ */ jsx14(
|
|
@@ -27775,12 +27836,12 @@ function HomeView({ apiUrl, notice, returnToAgent }) {
|
|
|
27775
27836
|
{ k: "space", label: "Select" },
|
|
27776
27837
|
{
|
|
27777
27838
|
k: "v",
|
|
27778
|
-
label:
|
|
27839
|
+
label: showArchivedSessions ? "Active" : "Archived"
|
|
27779
27840
|
},
|
|
27780
|
-
...
|
|
27841
|
+
...showArchivedSessions ? [{ k: "u", label: "Restore" }] : [
|
|
27781
27842
|
{ k: "a", label: "Archive" },
|
|
27782
27843
|
{ k: "s", label: "Stop" },
|
|
27783
|
-
...scopedAgent ? [{ k: "n", label: "New
|
|
27844
|
+
...scopedAgent ? [{ k: "n", label: "New session" }] : []
|
|
27784
27845
|
],
|
|
27785
27846
|
{ k: "esc", label: "Back" },
|
|
27786
27847
|
{ k: "q", label: "Quit" }
|
|
@@ -27926,13 +27987,13 @@ function HomeView({ apiUrl, notice, returnToAgent }) {
|
|
|
27926
27987
|
error: projectsErrorMessage
|
|
27927
27988
|
}
|
|
27928
27989
|
) : /* @__PURE__ */ jsx14(
|
|
27929
|
-
|
|
27990
|
+
SessionsView,
|
|
27930
27991
|
{
|
|
27931
27992
|
scopedAgent,
|
|
27932
27993
|
apiUrl,
|
|
27933
|
-
selectedIndex:
|
|
27934
|
-
showArchived:
|
|
27935
|
-
|
|
27994
|
+
selectedIndex: sessionIndex,
|
|
27995
|
+
showArchived: showArchivedSessions,
|
|
27996
|
+
selectedSessionIds
|
|
27936
27997
|
}
|
|
27937
27998
|
)
|
|
27938
27999
|
}
|
|
@@ -27958,24 +28019,24 @@ function HomeView({ apiUrl, notice, returnToAgent }) {
|
|
|
27958
28019
|
children: ` ${activeSection} `
|
|
27959
28020
|
}
|
|
27960
28021
|
),
|
|
27961
|
-
!inspectedResource && (activeSection === "agents" || activeSection === "
|
|
28022
|
+
!inspectedResource && (activeSection === "agents" || activeSection === "sessions") && /* @__PURE__ */ jsxs12(Fragment3, { children: [
|
|
27962
28023
|
/* @__PURE__ */ jsx14(
|
|
27963
28024
|
Text14,
|
|
27964
28025
|
{
|
|
27965
28026
|
backgroundColor: activeSection === "agents" ? "cyan" : void 0,
|
|
27966
28027
|
color: activeSection === "agents" ? "black" : void 0,
|
|
27967
|
-
dimColor: activeSection === "
|
|
28028
|
+
dimColor: activeSection === "sessions",
|
|
27968
28029
|
children: " agents "
|
|
27969
28030
|
}
|
|
27970
28031
|
),
|
|
27971
|
-
activeSection === "
|
|
28032
|
+
activeSection === "sessions" && scopedAgent ? /* @__PURE__ */ jsxs12(Fragment3, { children: [
|
|
27972
28033
|
/* @__PURE__ */ jsx14(Text14, { dimColor: true, children: "\u203A" }),
|
|
27973
28034
|
/* @__PURE__ */ jsx14(Text14, { dimColor: true, children: ` ${scopedAgent.metadata.name} ` }),
|
|
27974
28035
|
/* @__PURE__ */ jsx14(Text14, { dimColor: true, children: "\u203A" }),
|
|
27975
|
-
/* @__PURE__ */ jsx14(Text14, { backgroundColor: "cyan", color: "black", children: "
|
|
27976
|
-
] }) : activeSection === "
|
|
28036
|
+
/* @__PURE__ */ jsx14(Text14, { backgroundColor: "cyan", color: "black", children: " sessions " })
|
|
28037
|
+
] }) : activeSection === "sessions" ? /* @__PURE__ */ jsxs12(Fragment3, { children: [
|
|
27977
28038
|
/* @__PURE__ */ jsx14(Text14, { dimColor: true, children: "\u203A" }),
|
|
27978
|
-
/* @__PURE__ */ jsx14(Text14, { backgroundColor: "cyan", color: "black", children: "
|
|
28039
|
+
/* @__PURE__ */ jsx14(Text14, { backgroundColor: "cyan", color: "black", children: " sessions " })
|
|
27979
28040
|
] }) : null
|
|
27980
28041
|
] })
|
|
27981
28042
|
] })
|
|
@@ -28018,27 +28079,27 @@ function chunkActionKeys(keys, size) {
|
|
|
28018
28079
|
}
|
|
28019
28080
|
return chunks;
|
|
28020
28081
|
}
|
|
28021
|
-
function
|
|
28022
|
-
return
|
|
28082
|
+
function selectedSessionIdsForVisibleRuns(sessions, selectedSessionIds) {
|
|
28083
|
+
return sessions.filter((session) => selectedSessionIds.has(session.id)).map((session) => session.id);
|
|
28023
28084
|
}
|
|
28024
|
-
function
|
|
28025
|
-
return input.
|
|
28085
|
+
function sessionIdsForArchiveAction(input) {
|
|
28086
|
+
return input.markedSessionIds.length > 0 ? input.markedSessionIds : input.selectedSession ? [input.selectedSession.id] : [];
|
|
28026
28087
|
}
|
|
28027
|
-
function partitionRunsForStop(
|
|
28028
|
-
const
|
|
28029
|
-
const
|
|
28030
|
-
for (const
|
|
28031
|
-
const
|
|
28032
|
-
if (
|
|
28033
|
-
|
|
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);
|
|
28034
28095
|
} else {
|
|
28035
|
-
|
|
28096
|
+
stoppableSessionIds.push(sessionId);
|
|
28036
28097
|
}
|
|
28037
28098
|
}
|
|
28038
|
-
return {
|
|
28099
|
+
return { stoppableSessionIds, skippedSessionIds };
|
|
28039
28100
|
}
|
|
28040
|
-
function stopTargetLabel(
|
|
28041
|
-
return bulk ? pluralizeRunCount(
|
|
28101
|
+
function stopTargetLabel(sessionIds, bulk) {
|
|
28102
|
+
return bulk ? pluralizeRunCount(sessionIds.length) : `session ${shortSessionId2(sessionIds[0] ?? "")}`;
|
|
28042
28103
|
}
|
|
28043
28104
|
function stopResultNotice(result, skippedCount) {
|
|
28044
28105
|
const parts = [`Stopped ${pluralizeRunCount(result.stopped.length)}`];
|
|
@@ -28056,23 +28117,23 @@ function runMutationStatusLabel(pending) {
|
|
|
28056
28117
|
if (pending.stopping) return "stopping\u2026";
|
|
28057
28118
|
return "restoring\u2026";
|
|
28058
28119
|
}
|
|
28059
|
-
function runArchiveActionKey(
|
|
28060
|
-
return
|
|
28120
|
+
function runArchiveActionKey(sessionIds) {
|
|
28121
|
+
return sessionIds.join("\0");
|
|
28061
28122
|
}
|
|
28062
|
-
function runActionTargetLabel(
|
|
28123
|
+
function runActionTargetLabel(sessionIds, markedRunCount) {
|
|
28063
28124
|
if (markedRunCount > 0) {
|
|
28064
|
-
return `${markedRunCount} selected ${markedRunCount === 1 ? "
|
|
28125
|
+
return `${markedRunCount} selected ${markedRunCount === 1 ? "session" : "sessions"}`;
|
|
28065
28126
|
}
|
|
28066
|
-
return `
|
|
28127
|
+
return `session ${shortSessionId2(sessionIds[0] ?? "")}`;
|
|
28067
28128
|
}
|
|
28068
28129
|
function pluralizeRunCount(count) {
|
|
28069
|
-
return `${count} ${count === 1 ? "
|
|
28130
|
+
return `${count} ${count === 1 ? "session" : "sessions"}`;
|
|
28070
28131
|
}
|
|
28071
28132
|
function errorMessage2(error51) {
|
|
28072
28133
|
if (error51 instanceof Error) return error51.message;
|
|
28073
28134
|
return error51 ? String(error51) : null;
|
|
28074
28135
|
}
|
|
28075
|
-
function
|
|
28136
|
+
function shortSessionId2(id) {
|
|
28076
28137
|
const tail = id.split("-").pop();
|
|
28077
28138
|
return tail ? tail.slice(0, 12) : id.slice(0, 12);
|
|
28078
28139
|
}
|
|
@@ -28181,7 +28242,7 @@ var init_HomeView = __esm({
|
|
|
28181
28242
|
init_ConnectionsView();
|
|
28182
28243
|
init_ProjectsView();
|
|
28183
28244
|
init_ResourceViews();
|
|
28184
|
-
|
|
28245
|
+
init_SessionsView();
|
|
28185
28246
|
init_SpecInspector();
|
|
28186
28247
|
init_queries();
|
|
28187
28248
|
init_string();
|
|
@@ -28189,7 +28250,7 @@ var init_HomeView = __esm({
|
|
|
28189
28250
|
CONNECTION_REFRESH_TIMEOUT_MS = 9e4;
|
|
28190
28251
|
DASHBOARD_NAV_ITEMS = [
|
|
28191
28252
|
resourceNavItem({ k: "1", section: "agents" }),
|
|
28192
|
-
{ k: "2", label: "
|
|
28253
|
+
{ k: "2", label: "Sessions", activeSection: "sessions" },
|
|
28193
28254
|
resourceNavItem({ k: "3", section: "environments" }),
|
|
28194
28255
|
resourceNavItem({ k: "4", section: "identities" }),
|
|
28195
28256
|
{ k: "5", label: "Projects", activeSection: "projects" },
|
|
@@ -28408,7 +28469,7 @@ async function launch(opts) {
|
|
|
28408
28469
|
const { waitUntilExit: waitConv } = render(
|
|
28409
28470
|
providers(
|
|
28410
28471
|
React.createElement(ConversationView, {
|
|
28411
|
-
|
|
28472
|
+
sessionId: selection.sessionId,
|
|
28412
28473
|
agentName: selection.agentName,
|
|
28413
28474
|
workingDirectory: selection.workingDirectory,
|
|
28414
28475
|
apiUrl
|
|
@@ -28547,7 +28608,7 @@ function logout(context) {
|
|
|
28547
28608
|
function listAccounts(context) {
|
|
28548
28609
|
const profiles = listProfiles(context.configPath);
|
|
28549
28610
|
if (profiles.length === 0) {
|
|
28550
|
-
throw new Error("No stored accounts.
|
|
28611
|
+
throw new Error("No stored accounts. Session `auto auth login` first.");
|
|
28551
28612
|
}
|
|
28552
28613
|
for (const profile of profiles) {
|
|
28553
28614
|
context.writeOutput(
|
|
@@ -28571,7 +28632,7 @@ function switchAccount(context, accountRef, options = {}) {
|
|
|
28571
28632
|
}
|
|
28572
28633
|
const profiles = listProfiles(context.configPath);
|
|
28573
28634
|
if (profiles.length === 0) {
|
|
28574
|
-
throw new Error("No stored accounts.
|
|
28635
|
+
throw new Error("No stored accounts. Session `auto auth login` first.");
|
|
28575
28636
|
}
|
|
28576
28637
|
const byName = profiles.find((profile) => profile.name === accountRef);
|
|
28577
28638
|
const matches = byName ? [byName] : profiles.filter(
|
|
@@ -28579,7 +28640,7 @@ function switchAccount(context, accountRef, options = {}) {
|
|
|
28579
28640
|
);
|
|
28580
28641
|
if (matches.length === 0) {
|
|
28581
28642
|
throw new Error(
|
|
28582
|
-
`No stored account for ${accountRef}.
|
|
28643
|
+
`No stored account for ${accountRef}. Session \`auto auth login\` to add it.`
|
|
28583
28644
|
);
|
|
28584
28645
|
}
|
|
28585
28646
|
const active = readConfig(context.configPath);
|
|
@@ -28755,8 +28816,8 @@ function actorLabel(whoami) {
|
|
|
28755
28816
|
return "user";
|
|
28756
28817
|
case "provider_grant":
|
|
28757
28818
|
return "provider_grant";
|
|
28758
|
-
case "
|
|
28759
|
-
return "
|
|
28819
|
+
case "session":
|
|
28820
|
+
return "session";
|
|
28760
28821
|
case "system":
|
|
28761
28822
|
return "system";
|
|
28762
28823
|
}
|
|
@@ -28973,8 +29034,8 @@ async function readStream(stream) {
|
|
|
28973
29034
|
// ../../packages/protocol/src/index.ts
|
|
28974
29035
|
init_zod();
|
|
28975
29036
|
var OpaqueIdSchema2 = external_exports.string().trim().min(1);
|
|
28976
|
-
var
|
|
28977
|
-
var
|
|
29037
|
+
var SessionIdSchema2 = OpaqueIdSchema2.brand();
|
|
29038
|
+
var SessionCommandIdSchema2 = OpaqueIdSchema2.brand();
|
|
28978
29039
|
var RuntimeIdSchema2 = OpaqueIdSchema2.brand();
|
|
28979
29040
|
var RuntimeBridgeLeaseIdSchema2 = OpaqueIdSchema2.brand();
|
|
28980
29041
|
var JsonValueSchema2 = external_exports.lazy(
|
|
@@ -28987,7 +29048,7 @@ var JsonValueSchema2 = external_exports.lazy(
|
|
|
28987
29048
|
external_exports.record(external_exports.string(), JsonValueSchema2)
|
|
28988
29049
|
])
|
|
28989
29050
|
);
|
|
28990
|
-
var
|
|
29051
|
+
var SessionCommandKindSchema2 = external_exports.enum([
|
|
28991
29052
|
"message",
|
|
28992
29053
|
"answer",
|
|
28993
29054
|
"pause",
|
|
@@ -29084,8 +29145,8 @@ var RuntimeBridgeBootstrapPlaintextSchema = external_exports.object({
|
|
|
29084
29145
|
version: external_exports.literal(1),
|
|
29085
29146
|
outputSeqStart: external_exports.number().int().nonnegative(),
|
|
29086
29147
|
claude: AgentBridgeClaudeConfigSchema,
|
|
29087
|
-
// Endpoint +
|
|
29088
|
-
// 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
|
|
29089
29150
|
// token lives in agent-bridge memory, never on disk.
|
|
29090
29151
|
gitCredentials: external_exports.object({
|
|
29091
29152
|
url: external_exports.string().trim().min(1),
|
|
@@ -29100,7 +29161,7 @@ var RuntimeBridgeEncryptedBootstrapSchema = external_exports.object({
|
|
|
29100
29161
|
salt: external_exports.string().trim().min(1)
|
|
29101
29162
|
});
|
|
29102
29163
|
var RuntimeBridgeBootstrapEnvelopeSchema = external_exports.object({
|
|
29103
|
-
|
|
29164
|
+
sessionId: SessionIdSchema2,
|
|
29104
29165
|
runtimeId: RuntimeIdSchema2,
|
|
29105
29166
|
bridgeLeaseId: RuntimeBridgeLeaseIdSchema2,
|
|
29106
29167
|
bootstrap: RuntimeBridgeEncryptedBootstrapSchema
|
|
@@ -29121,18 +29182,18 @@ var RuntimeBridgeBootstrapAckSchema = external_exports.object({
|
|
|
29121
29182
|
ignoredBootstrapKeys: external_exports.array(external_exports.string().trim().min(1)).optional()
|
|
29122
29183
|
});
|
|
29123
29184
|
var RuntimeBridgeConnectedPayloadSchema = external_exports.object({
|
|
29124
|
-
|
|
29185
|
+
sessionId: SessionIdSchema2,
|
|
29125
29186
|
runtimeId: RuntimeIdSchema2,
|
|
29126
29187
|
bridgeLeaseId: RuntimeBridgeLeaseIdSchema2
|
|
29127
29188
|
});
|
|
29128
29189
|
var RuntimeBridgeCommandDeliverySchema = external_exports.object({
|
|
29129
29190
|
type: external_exports.literal("command.delivery"),
|
|
29130
29191
|
deliveryId: external_exports.string().trim().min(1),
|
|
29131
|
-
commandId:
|
|
29132
|
-
|
|
29192
|
+
commandId: SessionCommandIdSchema2,
|
|
29193
|
+
sessionId: SessionIdSchema2,
|
|
29133
29194
|
runtimeId: RuntimeIdSchema2,
|
|
29134
29195
|
bridgeLeaseId: RuntimeBridgeLeaseIdSchema2,
|
|
29135
|
-
kind:
|
|
29196
|
+
kind: SessionCommandKindSchema2,
|
|
29136
29197
|
payload: JsonValueSchema2,
|
|
29137
29198
|
attempt: external_exports.number().int().nonnegative(),
|
|
29138
29199
|
createdAt: external_exports.string().datetime()
|
|
@@ -29151,8 +29212,8 @@ var RuntimeBridgeCommandAckStatusSchema = external_exports.enum([
|
|
|
29151
29212
|
var RuntimeBridgeCommandAckSchema = external_exports.object({
|
|
29152
29213
|
type: external_exports.literal("command.ack"),
|
|
29153
29214
|
deliveryId: external_exports.string().trim().min(1),
|
|
29154
|
-
commandId:
|
|
29155
|
-
|
|
29215
|
+
commandId: SessionCommandIdSchema2,
|
|
29216
|
+
sessionId: SessionIdSchema2,
|
|
29156
29217
|
runtimeId: RuntimeIdSchema2,
|
|
29157
29218
|
bridgeLeaseId: RuntimeBridgeLeaseIdSchema2,
|
|
29158
29219
|
status: RuntimeBridgeCommandAckStatusSchema,
|
|
@@ -29163,13 +29224,13 @@ var RuntimeBridgeCommandAckSchema = external_exports.object({
|
|
|
29163
29224
|
var RuntimeBridgeCommandDeliveryAcceptedSchema = external_exports.object({
|
|
29164
29225
|
type: external_exports.literal("command.delivery.accepted"),
|
|
29165
29226
|
deliveryId: external_exports.string().trim().min(1),
|
|
29166
|
-
commandId:
|
|
29227
|
+
commandId: SessionCommandIdSchema2,
|
|
29167
29228
|
result: external_exports.enum(["injected", "duplicate"]),
|
|
29168
29229
|
at: external_exports.string().datetime()
|
|
29169
29230
|
}).strict();
|
|
29170
29231
|
var RuntimeBridgeOutputEntryEnvelopeSchema = external_exports.object({
|
|
29171
29232
|
type: external_exports.literal("conversation.entry"),
|
|
29172
|
-
|
|
29233
|
+
sessionId: SessionIdSchema2,
|
|
29173
29234
|
runtimeId: RuntimeIdSchema2,
|
|
29174
29235
|
bridgeLeaseId: RuntimeBridgeLeaseIdSchema2,
|
|
29175
29236
|
outputSeq: external_exports.number().int().positive(),
|
|
@@ -29180,11 +29241,11 @@ var RuntimeBridgeOutputEntryEnvelopeSchema = external_exports.object({
|
|
|
29180
29241
|
content: ConversationEntryContentSchema2,
|
|
29181
29242
|
createdAt: external_exports.string().datetime(),
|
|
29182
29243
|
completedAt: external_exports.string().datetime().nullable(),
|
|
29183
|
-
|
|
29244
|
+
sessionStatusAfter: external_exports.enum(["awaiting", "failed"]).optional()
|
|
29184
29245
|
}).strict();
|
|
29185
29246
|
var RuntimeBridgeOutputDeltaEnvelopeSchema = external_exports.object({
|
|
29186
29247
|
type: external_exports.literal("conversation.delta"),
|
|
29187
|
-
|
|
29248
|
+
sessionId: SessionIdSchema2,
|
|
29188
29249
|
runtimeId: RuntimeIdSchema2,
|
|
29189
29250
|
bridgeLeaseId: RuntimeBridgeLeaseIdSchema2,
|
|
29190
29251
|
outputSeq: external_exports.number().int().positive(),
|
|
@@ -29201,7 +29262,7 @@ var RuntimeBridgeOutputEnvelopeSchema = external_exports.discriminatedUnion("typ
|
|
|
29201
29262
|
]);
|
|
29202
29263
|
var RuntimeBridgeOutputAckSchema = external_exports.object({
|
|
29203
29264
|
type: external_exports.literal("runtime.output.ack"),
|
|
29204
|
-
|
|
29265
|
+
sessionId: SessionIdSchema2,
|
|
29205
29266
|
runtimeId: RuntimeIdSchema2,
|
|
29206
29267
|
bridgeLeaseId: RuntimeBridgeLeaseIdSchema2,
|
|
29207
29268
|
outputSeq: external_exports.number().int().positive(),
|
|
@@ -29220,7 +29281,7 @@ function commandAck(input) {
|
|
|
29220
29281
|
type: "command.ack",
|
|
29221
29282
|
deliveryId: input.delivery.deliveryId,
|
|
29222
29283
|
commandId: input.delivery.commandId,
|
|
29223
|
-
|
|
29284
|
+
sessionId: input.delivery.sessionId,
|
|
29224
29285
|
runtimeId: input.delivery.runtimeId,
|
|
29225
29286
|
bridgeLeaseId: input.delivery.bridgeLeaseId,
|
|
29226
29287
|
status: input.status,
|
|
@@ -29254,7 +29315,7 @@ function decryptRuntimeBridgeBootstrap(input) {
|
|
|
29254
29315
|
decipher.setAAD(
|
|
29255
29316
|
bootstrapAdditionalData({
|
|
29256
29317
|
accessToken: input.accessToken,
|
|
29257
|
-
|
|
29318
|
+
sessionId: envelope.sessionId,
|
|
29258
29319
|
runtimeId: envelope.runtimeId,
|
|
29259
29320
|
bridgeLeaseId: envelope.bridgeLeaseId
|
|
29260
29321
|
})
|
|
@@ -29288,7 +29349,7 @@ function deriveBootstrapKey(accessToken, salt) {
|
|
|
29288
29349
|
}
|
|
29289
29350
|
function bootstrapAdditionalData(input) {
|
|
29290
29351
|
return Buffer.from(
|
|
29291
|
-
`${input.
|
|
29352
|
+
`${input.sessionId}:${input.runtimeId}:${input.bridgeLeaseId}:v1`,
|
|
29292
29353
|
"utf8"
|
|
29293
29354
|
);
|
|
29294
29355
|
}
|
|
@@ -29336,7 +29397,7 @@ async function runAgentBridgeSocket(options) {
|
|
|
29336
29397
|
});
|
|
29337
29398
|
socket.on(
|
|
29338
29399
|
RUNTIME_BRIDGE_BOOTSTRAP_EVENT,
|
|
29339
|
-
|
|
29400
|
+
createSessiontimeBridgeBootstrapListener({
|
|
29340
29401
|
token: options.token,
|
|
29341
29402
|
onBootstrap: options.onBootstrap,
|
|
29342
29403
|
createHandler: (bootstrap) => options.createHandler({
|
|
@@ -29371,7 +29432,7 @@ async function runAgentBridgeSocket(options) {
|
|
|
29371
29432
|
reconnectLoop.stop();
|
|
29372
29433
|
handler.setContext(context);
|
|
29373
29434
|
options.writeOutput?.(
|
|
29374
|
-
`agent_bridge_connected
|
|
29435
|
+
`agent_bridge_connected session_id=${context.sessionId} runtime_id=${context.runtimeId} bridge_lease_id=${context.bridgeLeaseId}`
|
|
29375
29436
|
);
|
|
29376
29437
|
void handler.replayPendingOutputs().catch((error51) => {
|
|
29377
29438
|
options.writeOutput?.(
|
|
@@ -29416,7 +29477,7 @@ async function runAgentBridgeSocket(options) {
|
|
|
29416
29477
|
});
|
|
29417
29478
|
});
|
|
29418
29479
|
}
|
|
29419
|
-
function
|
|
29480
|
+
function createSessiontimeBridgeBootstrapListener(input) {
|
|
29420
29481
|
return async (rawEnvelope, ack) => {
|
|
29421
29482
|
const bootstrapStartedAt = Date.now();
|
|
29422
29483
|
input.writeOutput?.(
|
|
@@ -29425,7 +29486,7 @@ function createRuntimeBridgeBootstrapListener(input) {
|
|
|
29425
29486
|
try {
|
|
29426
29487
|
const envelope = RuntimeBridgeBootstrapEnvelopeSchema.parse(rawEnvelope);
|
|
29427
29488
|
const context = RuntimeBridgeConnectedPayloadSchema.parse({
|
|
29428
|
-
|
|
29489
|
+
sessionId: envelope.sessionId,
|
|
29429
29490
|
runtimeId: envelope.runtimeId,
|
|
29430
29491
|
bridgeLeaseId: envelope.bridgeLeaseId
|
|
29431
29492
|
});
|
|
@@ -29638,7 +29699,7 @@ function buildOutputEnvelope(context, outputSeq, projection) {
|
|
|
29638
29699
|
const { delta } = projection;
|
|
29639
29700
|
return RuntimeBridgeOutputEnvelopeSchema.parse({
|
|
29640
29701
|
type: "conversation.delta",
|
|
29641
|
-
|
|
29702
|
+
sessionId: context.sessionId,
|
|
29642
29703
|
runtimeId: context.runtimeId,
|
|
29643
29704
|
bridgeLeaseId: context.bridgeLeaseId,
|
|
29644
29705
|
outputSeq,
|
|
@@ -29654,7 +29715,7 @@ function buildOutputEnvelope(context, outputSeq, projection) {
|
|
|
29654
29715
|
const createdAt = now2();
|
|
29655
29716
|
return RuntimeBridgeOutputEnvelopeSchema.parse({
|
|
29656
29717
|
type: "conversation.entry",
|
|
29657
|
-
|
|
29718
|
+
sessionId: context.sessionId,
|
|
29658
29719
|
runtimeId: context.runtimeId,
|
|
29659
29720
|
bridgeLeaseId: context.bridgeLeaseId,
|
|
29660
29721
|
outputSeq,
|
|
@@ -29665,7 +29726,7 @@ function buildOutputEnvelope(context, outputSeq, projection) {
|
|
|
29665
29726
|
content: entry.content,
|
|
29666
29727
|
createdAt,
|
|
29667
29728
|
completedAt: entry.status === "in_progress" ? null : createdAt,
|
|
29668
|
-
...entry.
|
|
29729
|
+
...entry.sessionStatusAfter ? { sessionStatusAfter: entry.sessionStatusAfter } : {}
|
|
29669
29730
|
});
|
|
29670
29731
|
}
|
|
29671
29732
|
function isSuccessfulOutputAck(ack) {
|
|
@@ -29700,8 +29761,8 @@ var ClaudeCodeProjector = class {
|
|
|
29700
29761
|
(entry) => ({
|
|
29701
29762
|
type: "entry",
|
|
29702
29763
|
// A question entry means the SDK is parked on AskUserQuestion waiting
|
|
29703
|
-
// for an operator answer, so the
|
|
29704
|
-
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
|
|
29705
29766
|
})
|
|
29706
29767
|
);
|
|
29707
29768
|
if (parsed.result) {
|
|
@@ -29717,7 +29778,7 @@ function projectClaudeCodeResult(result) {
|
|
|
29717
29778
|
role: "system",
|
|
29718
29779
|
kind: "status",
|
|
29719
29780
|
status: result.isError ? "failed" : "completed",
|
|
29720
|
-
|
|
29781
|
+
sessionStatusAfter: result.isError ? "failed" : "awaiting",
|
|
29721
29782
|
content: {
|
|
29722
29783
|
parts: [
|
|
29723
29784
|
{
|
|
@@ -29770,12 +29831,12 @@ var AGENT_BRIDGE_RUNTIME_DIR = "/tmp/auto-bridge-runtime";
|
|
|
29770
29831
|
var CLAUDE_SESSION_RESUME_PATH = `${AGENT_BRIDGE_RUNTIME_DIR}/claude-session-id`;
|
|
29771
29832
|
function fileClaudeSessionResumeStore(path2 = CLAUDE_SESSION_RESUME_PATH) {
|
|
29772
29833
|
return {
|
|
29773
|
-
read(
|
|
29834
|
+
read(sessionId) {
|
|
29774
29835
|
if (!existsSync2(path2)) {
|
|
29775
29836
|
return null;
|
|
29776
29837
|
}
|
|
29777
29838
|
const record2 = parseResumeRecord(readFileSync2(path2, "utf8"));
|
|
29778
|
-
if (!record2 || record2.
|
|
29839
|
+
if (!record2 || record2.sessionId !== sessionId) {
|
|
29779
29840
|
return null;
|
|
29780
29841
|
}
|
|
29781
29842
|
return record2.agentId;
|
|
@@ -29790,8 +29851,8 @@ function fileClaudeSessionResumeStore(path2 = CLAUDE_SESSION_RESUME_PATH) {
|
|
|
29790
29851
|
function parseResumeRecord(raw) {
|
|
29791
29852
|
try {
|
|
29792
29853
|
const value = JSON.parse(raw);
|
|
29793
|
-
if (value !== null && typeof value === "object" && "
|
|
29794
|
-
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 };
|
|
29795
29856
|
}
|
|
29796
29857
|
return null;
|
|
29797
29858
|
} catch {
|
|
@@ -29978,7 +30039,7 @@ function withClaudeStderrDiagnosticsPointer(error51, capturedStderr) {
|
|
|
29978
30039
|
return base;
|
|
29979
30040
|
}
|
|
29980
30041
|
return new Error(
|
|
29981
|
-
`${base.message} (recent Claude stderr captured in
|
|
30042
|
+
`${base.message} (recent Claude stderr captured in session diagnostics)`,
|
|
29982
30043
|
{ cause: base }
|
|
29983
30044
|
);
|
|
29984
30045
|
}
|
|
@@ -30361,7 +30422,7 @@ var ClaudeCodeCommandHandler = class {
|
|
|
30361
30422
|
const delivery = RuntimeBridgeCommandDeliverySchema.parse(rawDelivery);
|
|
30362
30423
|
const socketId = this.input.socketId?.();
|
|
30363
30424
|
const activeContext = this.context;
|
|
30364
|
-
if (!activeContext || delivery.
|
|
30425
|
+
if (!activeContext || delivery.sessionId !== activeContext.sessionId || delivery.runtimeId !== activeContext.runtimeId || delivery.bridgeLeaseId !== activeContext.bridgeLeaseId) {
|
|
30365
30426
|
return commandAck({
|
|
30366
30427
|
delivery,
|
|
30367
30428
|
socketId,
|
|
@@ -30512,7 +30573,7 @@ var ClaudeCodeCommandHandler = class {
|
|
|
30512
30573
|
}
|
|
30513
30574
|
this.pendingQuestions.clear();
|
|
30514
30575
|
}
|
|
30515
|
-
// Permission callback for the Claude Agent SDK session. The
|
|
30576
|
+
// Permission callback for the Claude Agent SDK session. The sessions with
|
|
30516
30577
|
// bypassPermissions, so regular tools are auto-approved and only the
|
|
30517
30578
|
// AskUserQuestion tool reaches this callback for a real decision: it parks
|
|
30518
30579
|
// the SDK on a promise that an `answer` bridge command later resolves.
|
|
@@ -30601,7 +30662,7 @@ var ClaudeCodeCommandHandler = class {
|
|
|
30601
30662
|
}
|
|
30602
30663
|
try {
|
|
30603
30664
|
store.write({
|
|
30604
|
-
|
|
30665
|
+
sessionId: activeContext.sessionId,
|
|
30605
30666
|
agentId: message.session_id
|
|
30606
30667
|
});
|
|
30607
30668
|
this.persistedAgentId = message.session_id;
|
|
@@ -30618,7 +30679,7 @@ var ClaudeCodeCommandHandler = class {
|
|
|
30618
30679
|
return void 0;
|
|
30619
30680
|
}
|
|
30620
30681
|
try {
|
|
30621
|
-
return store.read(activeContext.
|
|
30682
|
+
return store.read(activeContext.sessionId) ?? void 0;
|
|
30622
30683
|
} catch (error51) {
|
|
30623
30684
|
this.input.writeOutput?.(
|
|
30624
30685
|
`agent_bridge_session_id_read_failed error=${error51 instanceof Error ? error51.message : String(error51)}`
|
|
@@ -30721,13 +30782,15 @@ function requiredEnv(env, key) {
|
|
|
30721
30782
|
|
|
30722
30783
|
// src/commands/agent-bridge/commands.ts
|
|
30723
30784
|
function registerAgentBridgeCommands(program, context) {
|
|
30724
|
-
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 () => {
|
|
30725
30786
|
await runAgentBridgeProcess({
|
|
30726
30787
|
env: context.env,
|
|
30727
30788
|
writeOutput: context.writeOutput
|
|
30728
30789
|
});
|
|
30729
30790
|
});
|
|
30730
|
-
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) => {
|
|
30731
30794
|
const exitCode = await runGitCredentialHelper({
|
|
30732
30795
|
args: [
|
|
30733
30796
|
...options.check ? ["--check"] : [],
|
|
@@ -30909,7 +30972,7 @@ async function connectAgentPresence2(input) {
|
|
|
30909
30972
|
}
|
|
30910
30973
|
if (!realized) {
|
|
30911
30974
|
throw new Error(
|
|
30912
|
-
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.`
|
|
30913
30976
|
);
|
|
30914
30977
|
}
|
|
30915
30978
|
}
|
|
@@ -30927,7 +30990,7 @@ function staleScopesLine(agent, identity2) {
|
|
|
30927
30990
|
}
|
|
30928
30991
|
function manualGuidance(input) {
|
|
30929
30992
|
if (input.allTelegram) {
|
|
30930
|
-
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.`;
|
|
30931
30994
|
}
|
|
30932
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.";
|
|
30933
30996
|
}
|
|
@@ -30953,7 +31016,7 @@ async function promptForIconUploads(input, options) {
|
|
|
30953
31016
|
}
|
|
30954
31017
|
if (!canPrompt) {
|
|
30955
31018
|
input.writeOutput(
|
|
30956
|
-
`Then
|
|
31019
|
+
`Then rerun \`auto agents connect ${input.agent}\` interactively to record the upload.`
|
|
30957
31020
|
);
|
|
30958
31021
|
continue;
|
|
30959
31022
|
}
|
|
@@ -31068,10 +31131,10 @@ async function registerConfigTokenInteractively(input, options, refusal) {
|
|
|
31068
31131
|
);
|
|
31069
31132
|
}
|
|
31070
31133
|
|
|
31071
|
-
// src/commands/agents/
|
|
31134
|
+
// src/commands/agents/start.ts
|
|
31072
31135
|
init_conversation2();
|
|
31073
31136
|
|
|
31074
|
-
// src/commands/
|
|
31137
|
+
// src/commands/sessions/list.ts
|
|
31075
31138
|
async function handleRunsList(context, agentName, options = {}) {
|
|
31076
31139
|
const result = await fetchRuns(context, agentName, options);
|
|
31077
31140
|
context.io.writeResult(result, formatRunsText);
|
|
@@ -31085,32 +31148,32 @@ async function fetchRuns(context, agentName, options) {
|
|
|
31085
31148
|
since: options.since,
|
|
31086
31149
|
limit: options.limit
|
|
31087
31150
|
};
|
|
31088
|
-
const response = agentName ? await client.
|
|
31151
|
+
const response = agentName ? await client.listAgentSessions(agentName, clientOptions) : await client.listSessions(clientOptions);
|
|
31089
31152
|
return {
|
|
31090
31153
|
agent: agentName ?? null,
|
|
31091
|
-
|
|
31154
|
+
sessions: response.sessions,
|
|
31092
31155
|
includeArchived: Boolean(options.includeArchived)
|
|
31093
31156
|
};
|
|
31094
31157
|
}
|
|
31095
31158
|
function formatRunsText(result, writeLine, style) {
|
|
31096
|
-
if (result.
|
|
31159
|
+
if (result.sessions.length === 0) {
|
|
31097
31160
|
writeLine(
|
|
31098
31161
|
style.dim(
|
|
31099
|
-
result.agent ? `No
|
|
31162
|
+
result.agent ? `No sessions found for agent ${result.agent}.` : "No sessions found in the current project."
|
|
31100
31163
|
)
|
|
31101
31164
|
);
|
|
31102
31165
|
return;
|
|
31103
31166
|
}
|
|
31104
|
-
for (const
|
|
31105
|
-
const archived =
|
|
31167
|
+
for (const session of result.sessions) {
|
|
31168
|
+
const archived = session.archivedAt ? ` ${style.dim(`archived_at=${session.archivedAt}`)}` : "";
|
|
31106
31169
|
writeLine(
|
|
31107
|
-
`${style.id(
|
|
31108
|
-
|
|
31170
|
+
`${style.id(session.id)} ${styleSessionStatus(style, session.status)} ${style.dim(
|
|
31171
|
+
session.createdAt
|
|
31109
31172
|
)}${archived}`
|
|
31110
31173
|
);
|
|
31111
31174
|
}
|
|
31112
31175
|
}
|
|
31113
|
-
function
|
|
31176
|
+
function styleSessionStatus(style, status) {
|
|
31114
31177
|
switch (status) {
|
|
31115
31178
|
case "failed":
|
|
31116
31179
|
return style.error(status);
|
|
@@ -31126,29 +31189,29 @@ function styleRunStatus(style, status) {
|
|
|
31126
31189
|
}
|
|
31127
31190
|
}
|
|
31128
31191
|
|
|
31129
|
-
// src/commands/agents/
|
|
31130
|
-
async function
|
|
31192
|
+
// src/commands/agents/start.ts
|
|
31193
|
+
async function launchSession(input) {
|
|
31131
31194
|
const client = createContextApiClient(input.context);
|
|
31132
31195
|
const apiBaseUrl = apiUrlFromOptions(input.context, input.commandOptions);
|
|
31133
|
-
const created = await client.
|
|
31196
|
+
const created = await client.triggerSession(input.agentName, {
|
|
31134
31197
|
message: input.commandOptions.message,
|
|
31135
31198
|
apiBaseUrl
|
|
31136
31199
|
});
|
|
31137
31200
|
const style = input.context.io.style;
|
|
31138
31201
|
input.context.writeOutput(
|
|
31139
|
-
`${style.label("
|
|
31202
|
+
`${style.label("session_id")} ${style.id(created.session_id)}`
|
|
31140
31203
|
);
|
|
31141
31204
|
input.context.writeOutput(
|
|
31142
31205
|
`${style.label("workflow_id")} ${style.id(created.workflow_id)}`
|
|
31143
31206
|
);
|
|
31144
31207
|
input.context.writeOutput(
|
|
31145
|
-
`${style.label("status")} ${
|
|
31208
|
+
`${style.label("status")} ${styleSessionStatus(style, created.status)}`
|
|
31146
31209
|
);
|
|
31147
31210
|
if (input.commandOptions.attach) {
|
|
31148
31211
|
const writeConversationEvent = createConversationStreamWriter({
|
|
31149
31212
|
writeLine: input.context.writeOutput
|
|
31150
31213
|
});
|
|
31151
|
-
await client.
|
|
31214
|
+
await client.streamSessionConversation(created.session_id, {
|
|
31152
31215
|
apiBaseUrl,
|
|
31153
31216
|
onEvent: writeConversationEvent
|
|
31154
31217
|
});
|
|
@@ -31157,13 +31220,15 @@ async function launchRun(input) {
|
|
|
31157
31220
|
|
|
31158
31221
|
// src/commands/agents/commands.ts
|
|
31159
31222
|
function registerAgentCommands(program, context) {
|
|
31160
|
-
program.command("
|
|
31161
|
-
|
|
31162
|
-
|
|
31163
|
-
|
|
31164
|
-
|
|
31165
|
-
|
|
31166
|
-
|
|
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
|
+
);
|
|
31167
31232
|
const agents = program.command("agents").description("Manage Agent resources.");
|
|
31168
31233
|
agents.command("render").description("Render a local Agent authoring file after imports/removals.").argument("<agent>", "agent name or path").option(
|
|
31169
31234
|
"--directory <directory>",
|
|
@@ -31206,7 +31271,7 @@ function registerAgentCommands(program, context) {
|
|
|
31206
31271
|
});
|
|
31207
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(
|
|
31208
31273
|
"--reconnect",
|
|
31209
|
-
"
|
|
31274
|
+
"rerun the install for already-connected workspaces (repairs stranded bot tokens)"
|
|
31210
31275
|
).option("--api-url <url>", "Auto API base URL").option("--api-base-url <url>", "Auto API base URL").action(
|
|
31211
31276
|
async (agentName, commandOptions) => {
|
|
31212
31277
|
await connectAgentPresence2({
|
|
@@ -31220,16 +31285,6 @@ function registerAgentCommands(program, context) {
|
|
|
31220
31285
|
});
|
|
31221
31286
|
}
|
|
31222
31287
|
);
|
|
31223
|
-
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) => {
|
|
31224
|
-
await launchRun({
|
|
31225
|
-
agentName,
|
|
31226
|
-
commandOptions: {
|
|
31227
|
-
...commandOptions,
|
|
31228
|
-
attach: true
|
|
31229
|
-
},
|
|
31230
|
-
context
|
|
31231
|
-
});
|
|
31232
|
-
});
|
|
31233
31288
|
}
|
|
31234
31289
|
|
|
31235
31290
|
// src/commands/apply/commands.ts
|
|
@@ -31308,7 +31363,7 @@ async function confirmDestructiveAction(context, input) {
|
|
|
31308
31363
|
return;
|
|
31309
31364
|
}
|
|
31310
31365
|
if (!context.io.canPrompt()) {
|
|
31311
|
-
throw new Error(`${input.message}
|
|
31366
|
+
throw new Error(`${input.message} Rerun with --yes to confirm.`);
|
|
31312
31367
|
}
|
|
31313
31368
|
const readline = createCliReadline({
|
|
31314
31369
|
stdin: context.stdin,
|
|
@@ -31331,7 +31386,7 @@ async function requireProjectScope(input) {
|
|
|
31331
31386
|
return resolved;
|
|
31332
31387
|
}
|
|
31333
31388
|
throw new Error(
|
|
31334
|
-
`No project selected.
|
|
31389
|
+
`No project selected. Session \`auto projects use <project>\` or pass ${input.explicitHint}.`
|
|
31335
31390
|
);
|
|
31336
31391
|
}
|
|
31337
31392
|
async function resolveProjectScope(input) {
|
|
@@ -31395,7 +31450,7 @@ async function requireConnection(input) {
|
|
|
31395
31450
|
);
|
|
31396
31451
|
}
|
|
31397
31452
|
throw new Error(
|
|
31398
|
-
`No ${input.provider} connection found matching ${identifier}.
|
|
31453
|
+
`No ${input.provider} connection found matching ${identifier}. Session \`auto connections list\` to see available connections.`
|
|
31399
31454
|
);
|
|
31400
31455
|
}
|
|
31401
31456
|
if (matches.length > 1) {
|
|
@@ -31407,13 +31462,13 @@ async function requireConnection(input) {
|
|
|
31407
31462
|
}
|
|
31408
31463
|
if (grants.length === 0) {
|
|
31409
31464
|
throw new Error(
|
|
31410
|
-
`No ${input.provider} connections found.
|
|
31465
|
+
`No ${input.provider} connections found. Session \`auto connect ${input.provider}\` first.`
|
|
31411
31466
|
);
|
|
31412
31467
|
}
|
|
31413
31468
|
if (grants.length > 1) {
|
|
31414
31469
|
const names = grants.map((grant) => grant.name).join(", ");
|
|
31415
31470
|
throw new Error(
|
|
31416
|
-
`Multiple ${input.provider} connections found: ${names}.
|
|
31471
|
+
`Multiple ${input.provider} connections found: ${names}. Rerun with --connection <name>.`
|
|
31417
31472
|
);
|
|
31418
31473
|
}
|
|
31419
31474
|
return grants[0];
|
|
@@ -31516,7 +31571,7 @@ function staleGrantNotices(connections, style) {
|
|
|
31516
31571
|
return connections.flatMap(
|
|
31517
31572
|
(connection) => connection.grants.filter(stale).map(
|
|
31518
31573
|
(grant) => style.warn(
|
|
31519
|
-
`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`
|
|
31520
31575
|
)
|
|
31521
31576
|
)
|
|
31522
31577
|
);
|
|
@@ -31679,7 +31734,7 @@ async function waitForNewGrant(input, knownGrantIds) {
|
|
|
31679
31734
|
}
|
|
31680
31735
|
}
|
|
31681
31736
|
throw new ConnectionWaitTimeoutError(
|
|
31682
|
-
`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.`
|
|
31683
31738
|
);
|
|
31684
31739
|
}
|
|
31685
31740
|
|
|
@@ -31776,7 +31831,7 @@ async function selectGithubInstallation(input) {
|
|
|
31776
31831
|
);
|
|
31777
31832
|
if (!input.context.io.canPrompt()) {
|
|
31778
31833
|
input.context.writeOutput(
|
|
31779
|
-
"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."
|
|
31780
31835
|
);
|
|
31781
31836
|
return void 0;
|
|
31782
31837
|
}
|
|
@@ -32476,12 +32531,12 @@ var humanQuickstartText = `Get started with auto:
|
|
|
32476
32531
|
1. auto auth login sign in (device flow; account setup in browser)
|
|
32477
32532
|
2. auto connections list see available providers; auto connect <provider>
|
|
32478
32533
|
3. auto apply apply .auto/ resources to your project
|
|
32479
|
-
4. auto
|
|
32534
|
+
4. auto start <agent> launch an agent session; add --attach to follow it
|
|
32480
32535
|
|
|
32481
32536
|
Fastest path: paste this into a coding agent running in your repo
|
|
32482
32537
|
(Claude Code, Cursor, Codex):
|
|
32483
32538
|
|
|
32484
|
-
"
|
|
32539
|
+
"Session \`auto onboard --agent\` and follow the instructions it prints."
|
|
32485
32540
|
|
|
32486
32541
|
The agent walks you through setup end to end, studies your repo, and installs
|
|
32487
32542
|
a first workflow tailored to how your team works.
|
|
@@ -32490,7 +32545,7 @@ Docs and help: auto --help
|
|
|
32490
32545
|
`;
|
|
32491
32546
|
|
|
32492
32547
|
// src/commands/onboard/skill-content.generated.ts
|
|
32493
|
-
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";
|
|
32494
32549
|
|
|
32495
32550
|
// src/commands/onboard/commands.ts
|
|
32496
32551
|
function registerOnboardCommands(program, context) {
|
|
@@ -32854,25 +32909,342 @@ function memberLine2(member, style) {
|
|
|
32854
32909
|
].filter(Boolean).join(" ");
|
|
32855
32910
|
}
|
|
32856
32911
|
|
|
32857
|
-
// 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
|
|
32858
33230
|
init_conversation2();
|
|
32859
|
-
async function
|
|
33231
|
+
async function streamSessionConversation(input) {
|
|
32860
33232
|
const writeConversationEvent = createConversationStreamWriter({
|
|
32861
33233
|
writeChunk: input.stdout ? (chunk) => {
|
|
32862
33234
|
input.stdout?.write(chunk);
|
|
32863
33235
|
} : void 0,
|
|
32864
33236
|
writeLine: input.writeOutput
|
|
32865
33237
|
});
|
|
32866
|
-
await input.client.
|
|
33238
|
+
await input.client.streamSessionConversation(input.sessionId, {
|
|
32867
33239
|
apiBaseUrl: input.apiBaseUrl,
|
|
32868
33240
|
onEvent: writeConversationEvent
|
|
32869
33241
|
});
|
|
32870
33242
|
}
|
|
32871
33243
|
|
|
32872
|
-
// src/commands/
|
|
33244
|
+
// src/commands/sessions/interactive.ts
|
|
32873
33245
|
init_conversation2();
|
|
32874
33246
|
|
|
32875
|
-
// src/commands/
|
|
33247
|
+
// src/commands/sessions/operator.ts
|
|
32876
33248
|
function operatorName(explicit, env) {
|
|
32877
33249
|
return explicit?.trim() || env.AUTO_OPERATOR_NAME?.trim() || env.USER?.trim() || env.USERNAME?.trim() || "operator";
|
|
32878
33250
|
}
|
|
@@ -32885,20 +33257,20 @@ function automationMetadata(event, operator) {
|
|
|
32885
33257
|
};
|
|
32886
33258
|
}
|
|
32887
33259
|
function attachMessage(operator) {
|
|
32888
|
-
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.`;
|
|
32889
33261
|
}
|
|
32890
33262
|
function detachMessage(operator) {
|
|
32891
|
-
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.`;
|
|
32892
33264
|
}
|
|
32893
33265
|
|
|
32894
|
-
// src/commands/
|
|
33266
|
+
// src/commands/sessions/interactive.ts
|
|
32895
33267
|
async function runConsole(input) {
|
|
32896
33268
|
input.writeOutput(
|
|
32897
33269
|
"Type messages and press Enter. Type .detach to leave it running."
|
|
32898
33270
|
);
|
|
32899
33271
|
if (input.sendAttachMessage) {
|
|
32900
33272
|
await input.client.sendMessage(
|
|
32901
|
-
input.
|
|
33273
|
+
input.sessionId,
|
|
32902
33274
|
attachMessage(input.operatorName),
|
|
32903
33275
|
{
|
|
32904
33276
|
apiBaseUrl: input.apiBaseUrl,
|
|
@@ -32917,7 +33289,7 @@ async function runConsole(input) {
|
|
|
32917
33289
|
const stream = (async () => {
|
|
32918
33290
|
while (!abort.signal.aborted) {
|
|
32919
33291
|
try {
|
|
32920
|
-
await input.client.
|
|
33292
|
+
await input.client.streamSessionConversation(input.sessionId, {
|
|
32921
33293
|
apiBaseUrl: input.apiBaseUrl,
|
|
32922
33294
|
signal: abort.signal,
|
|
32923
33295
|
cursor,
|
|
@@ -32941,7 +33313,7 @@ async function runConsole(input) {
|
|
|
32941
33313
|
})();
|
|
32942
33314
|
const consoleInput = createInteractiveInputController({
|
|
32943
33315
|
client: input.client,
|
|
32944
|
-
|
|
33316
|
+
sessionId: input.sessionId,
|
|
32945
33317
|
apiBaseUrl: input.apiBaseUrl,
|
|
32946
33318
|
operatorName: input.operatorName,
|
|
32947
33319
|
sendDetachMessage: input.sendDetachMessage,
|
|
@@ -32951,7 +33323,7 @@ async function runConsole(input) {
|
|
|
32951
33323
|
});
|
|
32952
33324
|
const status = pollUntilFailed({
|
|
32953
33325
|
client: input.client,
|
|
32954
|
-
|
|
33326
|
+
sessionId: input.sessionId,
|
|
32955
33327
|
apiBaseUrl: input.apiBaseUrl,
|
|
32956
33328
|
onFailed: () => {
|
|
32957
33329
|
consoleInput.close();
|
|
@@ -32986,7 +33358,7 @@ function createInteractiveInputController(input) {
|
|
|
32986
33358
|
if (message === ".detach") {
|
|
32987
33359
|
if (input.sendDetachMessage) {
|
|
32988
33360
|
const command2 = await input.client.sendMessage(
|
|
32989
|
-
input.
|
|
33361
|
+
input.sessionId,
|
|
32990
33362
|
detachMessage(input.operatorName),
|
|
32991
33363
|
{
|
|
32992
33364
|
apiBaseUrl: input.apiBaseUrl,
|
|
@@ -32998,12 +33370,16 @@ function createInteractiveInputController(input) {
|
|
|
32998
33370
|
);
|
|
32999
33371
|
input.writeOutput(`sent ${command2.command_id}`);
|
|
33000
33372
|
}
|
|
33001
|
-
input.writeOutput(`detached ${input.
|
|
33373
|
+
input.writeOutput(`detached ${input.sessionId}`);
|
|
33002
33374
|
return;
|
|
33003
33375
|
}
|
|
33004
|
-
const command = await input.client.sendMessage(
|
|
33005
|
-
|
|
33006
|
-
|
|
33376
|
+
const command = await input.client.sendMessage(
|
|
33377
|
+
input.sessionId,
|
|
33378
|
+
message,
|
|
33379
|
+
{
|
|
33380
|
+
apiBaseUrl: input.apiBaseUrl
|
|
33381
|
+
}
|
|
33382
|
+
);
|
|
33007
33383
|
input.writeOutput(`sent ${command.command_id}`);
|
|
33008
33384
|
}
|
|
33009
33385
|
} finally {
|
|
@@ -33057,10 +33433,10 @@ function pollUntilFailed(input) {
|
|
|
33057
33433
|
if (cancelled) {
|
|
33058
33434
|
return;
|
|
33059
33435
|
}
|
|
33060
|
-
const
|
|
33436
|
+
const session = await input.client.getSession(input.sessionId, {
|
|
33061
33437
|
apiBaseUrl: input.apiBaseUrl
|
|
33062
33438
|
});
|
|
33063
|
-
if (
|
|
33439
|
+
if (session.status === "failed") {
|
|
33064
33440
|
input.onFailed();
|
|
33065
33441
|
return;
|
|
33066
33442
|
}
|
|
@@ -33069,31 +33445,33 @@ function pollUntilFailed(input) {
|
|
|
33069
33445
|
return { done, cancel };
|
|
33070
33446
|
}
|
|
33071
33447
|
|
|
33072
|
-
// src/commands/
|
|
33073
|
-
function
|
|
33448
|
+
// src/commands/sessions/service.ts
|
|
33449
|
+
function createSessionServiceClient(context) {
|
|
33074
33450
|
return createContextApiClient(context);
|
|
33075
33451
|
}
|
|
33076
33452
|
|
|
33077
|
-
// src/commands/
|
|
33453
|
+
// src/commands/sessions/actions.ts
|
|
33078
33454
|
async function interactiveRunAction(context, agentName, commandOptions) {
|
|
33079
|
-
const client =
|
|
33455
|
+
const client = createSessionServiceClient(context);
|
|
33080
33456
|
const apiBaseUrl = apiUrlFromOptions(context, commandOptions);
|
|
33081
|
-
const created = await client.
|
|
33457
|
+
const created = await client.triggerSession(agentName, {
|
|
33082
33458
|
message: commandOptions.message,
|
|
33083
33459
|
interactive: true,
|
|
33084
33460
|
apiBaseUrl
|
|
33085
33461
|
});
|
|
33086
33462
|
const style = context.io.style;
|
|
33087
|
-
context.writeOutput(
|
|
33463
|
+
context.writeOutput(
|
|
33464
|
+
`${style.label("session_id")} ${style.id(created.session_id)}`
|
|
33465
|
+
);
|
|
33088
33466
|
context.writeOutput(
|
|
33089
33467
|
`${style.label("workflow_id")} ${style.id(created.workflow_id)}`
|
|
33090
33468
|
);
|
|
33091
33469
|
context.writeOutput(
|
|
33092
|
-
`${style.label("status")} ${
|
|
33470
|
+
`${style.label("status")} ${styleSessionStatus(style, created.status)}`
|
|
33093
33471
|
);
|
|
33094
33472
|
await runConsole({
|
|
33095
33473
|
client,
|
|
33096
|
-
|
|
33474
|
+
sessionId: created.session_id,
|
|
33097
33475
|
apiBaseUrl,
|
|
33098
33476
|
operatorName: operatorName(commandOptions.operator, context.env),
|
|
33099
33477
|
sendAttachMessage: commandOptions.attachMessage === true,
|
|
@@ -33103,94 +33481,108 @@ async function interactiveRunAction(context, agentName, commandOptions) {
|
|
|
33103
33481
|
stdout: context.stdout
|
|
33104
33482
|
});
|
|
33105
33483
|
}
|
|
33106
|
-
async function attachRunAction(context,
|
|
33107
|
-
await
|
|
33108
|
-
client:
|
|
33109
|
-
|
|
33484
|
+
async function attachRunAction(context, sessionId, commandOptions) {
|
|
33485
|
+
await streamSessionConversation({
|
|
33486
|
+
client: createSessionServiceClient(context),
|
|
33487
|
+
sessionId,
|
|
33110
33488
|
apiBaseUrl: apiUrlFromOptions(context, commandOptions),
|
|
33111
33489
|
stdout: context.stdout,
|
|
33112
33490
|
writeOutput: context.writeOutput
|
|
33113
33491
|
});
|
|
33114
33492
|
}
|
|
33115
|
-
async function
|
|
33116
|
-
const
|
|
33117
|
-
|
|
33118
|
-
|
|
33493
|
+
async function archiveSessionAction(context, sessionId, commandOptions) {
|
|
33494
|
+
const session = await createSessionServiceClient(context).archiveSession(
|
|
33495
|
+
sessionId,
|
|
33496
|
+
{
|
|
33497
|
+
apiBaseUrl: apiUrlFromOptions(context, commandOptions)
|
|
33498
|
+
}
|
|
33499
|
+
);
|
|
33119
33500
|
const style = context.io.style;
|
|
33120
|
-
context.writeOutput(`${style.label("
|
|
33501
|
+
context.writeOutput(`${style.label("session_id")} ${style.id(session.id)}`);
|
|
33121
33502
|
context.writeOutput(
|
|
33122
|
-
`${style.label("archived_at")} ${style.dim(
|
|
33503
|
+
`${style.label("archived_at")} ${style.dim(session.archivedAt ?? "")}`
|
|
33123
33504
|
);
|
|
33124
33505
|
}
|
|
33125
|
-
async function
|
|
33126
|
-
const result = await
|
|
33127
|
-
|
|
33128
|
-
|
|
33506
|
+
async function archiveSessionsAction(context, sessionIds, commandOptions) {
|
|
33507
|
+
const result = await createSessionServiceClient(context).archiveSessions(
|
|
33508
|
+
sessionIds,
|
|
33509
|
+
{
|
|
33510
|
+
apiBaseUrl: apiUrlFromOptions(context, commandOptions)
|
|
33511
|
+
}
|
|
33512
|
+
);
|
|
33129
33513
|
const style = context.io.style;
|
|
33130
|
-
for (const
|
|
33514
|
+
for (const session of result.sessions) {
|
|
33131
33515
|
context.writeOutput(
|
|
33132
|
-
`${style.label("
|
|
33516
|
+
`${style.label("session_id")} ${style.id(session.id)} ${style.label(
|
|
33133
33517
|
"archived_at"
|
|
33134
|
-
)} ${style.dim(
|
|
33518
|
+
)} ${style.dim(session.archivedAt ?? "")}`
|
|
33135
33519
|
);
|
|
33136
33520
|
}
|
|
33137
33521
|
}
|
|
33138
|
-
async function
|
|
33139
|
-
const
|
|
33140
|
-
|
|
33141
|
-
|
|
33522
|
+
async function unarchiveSessionAction(context, sessionId, commandOptions) {
|
|
33523
|
+
const session = await createSessionServiceClient(context).unarchiveSession(
|
|
33524
|
+
sessionId,
|
|
33525
|
+
{
|
|
33526
|
+
apiBaseUrl: apiUrlFromOptions(context, commandOptions)
|
|
33527
|
+
}
|
|
33528
|
+
);
|
|
33142
33529
|
const style = context.io.style;
|
|
33143
|
-
context.writeOutput(`${style.label("
|
|
33144
|
-
context.writeOutput(
|
|
33530
|
+
context.writeOutput(`${style.label("session_id")} ${style.id(session.id)}`);
|
|
33531
|
+
context.writeOutput(
|
|
33532
|
+
`${style.label("archived")} ${Boolean(session.archivedAt)}`
|
|
33533
|
+
);
|
|
33145
33534
|
}
|
|
33146
|
-
async function
|
|
33147
|
-
const result = await
|
|
33148
|
-
|
|
33149
|
-
|
|
33535
|
+
async function unarchiveSessionsAction(context, sessionIds, commandOptions) {
|
|
33536
|
+
const result = await createSessionServiceClient(context).unarchiveSessions(
|
|
33537
|
+
sessionIds,
|
|
33538
|
+
{
|
|
33539
|
+
apiBaseUrl: apiUrlFromOptions(context, commandOptions)
|
|
33540
|
+
}
|
|
33541
|
+
);
|
|
33150
33542
|
const style = context.io.style;
|
|
33151
|
-
for (const
|
|
33543
|
+
for (const session of result.sessions) {
|
|
33152
33544
|
context.writeOutput(
|
|
33153
|
-
`${style.label("
|
|
33545
|
+
`${style.label("session_id")} ${style.id(session.id)} ${style.label(
|
|
33154
33546
|
"archived"
|
|
33155
|
-
)} ${Boolean(
|
|
33547
|
+
)} ${Boolean(session.archivedAt)}`
|
|
33156
33548
|
);
|
|
33157
33549
|
}
|
|
33158
33550
|
}
|
|
33159
|
-
async function
|
|
33160
|
-
const client =
|
|
33551
|
+
async function stopSessionsAction(context, sessionIds, commandOptions) {
|
|
33552
|
+
const client = createSessionServiceClient(context);
|
|
33161
33553
|
const apiBaseUrl = apiUrlFromOptions(context, commandOptions);
|
|
33162
33554
|
const style = context.io.style;
|
|
33163
|
-
const
|
|
33164
|
-
for (const
|
|
33555
|
+
const failedSessionIds = [];
|
|
33556
|
+
for (const sessionId of sessionIds) {
|
|
33165
33557
|
try {
|
|
33166
|
-
const command = await client.
|
|
33558
|
+
const command = await client.stopSession(sessionId, {
|
|
33167
33559
|
apiBaseUrl,
|
|
33168
33560
|
reason: commandOptions.reason
|
|
33169
33561
|
});
|
|
33170
33562
|
context.writeOutput(
|
|
33171
|
-
`${style.label("
|
|
33563
|
+
`${style.label("session_id")} ${style.id(sessionId)} ${style.label(
|
|
33172
33564
|
"command_id"
|
|
33173
33565
|
)} ${style.id(command.command_id)} ${style.label("status")} ${command.status}`
|
|
33174
33566
|
);
|
|
33175
33567
|
} catch (error51) {
|
|
33176
|
-
|
|
33568
|
+
failedSessionIds.push(sessionId);
|
|
33177
33569
|
context.writeOutput(
|
|
33178
|
-
`${style.label("
|
|
33570
|
+
`${style.label("session_id")} ${style.id(sessionId)} ${style.error(
|
|
33179
33571
|
`error ${error51 instanceof Error ? error51.message : String(error51)}`
|
|
33180
33572
|
)}`
|
|
33181
33573
|
);
|
|
33182
33574
|
}
|
|
33183
33575
|
}
|
|
33184
|
-
if (
|
|
33576
|
+
if (failedSessionIds.length > 0) {
|
|
33185
33577
|
throw new Error(
|
|
33186
|
-
`Failed to stop ${
|
|
33578
|
+
`Failed to stop ${failedSessionIds.length} of ${sessionIds.length} session(s): ${failedSessionIds.join(", ")}`
|
|
33187
33579
|
);
|
|
33188
33580
|
}
|
|
33189
33581
|
}
|
|
33190
|
-
async function consoleRunAction(context,
|
|
33582
|
+
async function consoleRunAction(context, sessionId, commandOptions) {
|
|
33191
33583
|
await runConsole({
|
|
33192
|
-
client:
|
|
33193
|
-
|
|
33584
|
+
client: createSessionServiceClient(context),
|
|
33585
|
+
sessionId,
|
|
33194
33586
|
apiBaseUrl: apiUrlFromOptions(context, commandOptions),
|
|
33195
33587
|
operatorName: operatorName(commandOptions.operator, context.env),
|
|
33196
33588
|
sendAttachMessage: commandOptions.attachMessage !== false,
|
|
@@ -33200,9 +33592,9 @@ async function consoleRunAction(context, runId, commandOptions) {
|
|
|
33200
33592
|
stdout: context.stdout
|
|
33201
33593
|
});
|
|
33202
33594
|
}
|
|
33203
|
-
async function sendRunMessageAction(context,
|
|
33204
|
-
const command = await
|
|
33205
|
-
|
|
33595
|
+
async function sendRunMessageAction(context, sessionId, message, commandOptions) {
|
|
33596
|
+
const command = await createSessionServiceClient(context).sendMessage(
|
|
33597
|
+
sessionId,
|
|
33206
33598
|
message,
|
|
33207
33599
|
{
|
|
33208
33600
|
apiBaseUrl: apiUrlFromOptions(context, commandOptions)
|
|
@@ -33215,7 +33607,7 @@ async function sendRunMessageAction(context, runId, message, commandOptions) {
|
|
|
33215
33607
|
context.writeOutput(`${style.label("status")} ${command.status}`);
|
|
33216
33608
|
}
|
|
33217
33609
|
|
|
33218
|
-
// src/commands/
|
|
33610
|
+
// src/commands/sessions/benchmark-startup.ts
|
|
33219
33611
|
import { performance } from "perf_hooks";
|
|
33220
33612
|
var DEFAULT_TIMEOUT_MS = 3e5;
|
|
33221
33613
|
var DEFAULT_POLL_INTERVAL_MS = 1e3;
|
|
@@ -33231,11 +33623,11 @@ async function benchmarkStartupAction(context, commandOptions) {
|
|
|
33231
33623
|
if (commandOptions.thresholdMs !== void 0) {
|
|
33232
33624
|
validatePositiveInteger(commandOptions.thresholdMs, "threshold-ms");
|
|
33233
33625
|
}
|
|
33234
|
-
const client =
|
|
33626
|
+
const client = createSessionServiceClient(context);
|
|
33235
33627
|
const apiBaseUrl = apiUrlFromOptions(context, commandOptions);
|
|
33236
33628
|
const startedAt = /* @__PURE__ */ new Date();
|
|
33237
33629
|
const start = performance.now();
|
|
33238
|
-
const created = await client.
|
|
33630
|
+
const created = await client.triggerSession(commandOptions.agent, {
|
|
33239
33631
|
message: commandOptions.message,
|
|
33240
33632
|
...commandOptions.interactive === true ? { interactive: true } : {},
|
|
33241
33633
|
apiBaseUrl
|
|
@@ -33244,7 +33636,7 @@ async function benchmarkStartupAction(context, commandOptions) {
|
|
|
33244
33636
|
const diagnosticsAbort = new AbortController();
|
|
33245
33637
|
const diagnosticsDone = streamDiagnosticsBestEffort({
|
|
33246
33638
|
client,
|
|
33247
|
-
|
|
33639
|
+
sessionId: created.session_id,
|
|
33248
33640
|
apiBaseUrl,
|
|
33249
33641
|
signal: diagnosticsAbort.signal,
|
|
33250
33642
|
onEvent: diagnostics.push,
|
|
@@ -33252,7 +33644,7 @@ async function benchmarkStartupAction(context, commandOptions) {
|
|
|
33252
33644
|
});
|
|
33253
33645
|
const poll = await pollUntilAwaiting({
|
|
33254
33646
|
client,
|
|
33255
|
-
|
|
33647
|
+
sessionId: created.session_id,
|
|
33256
33648
|
initialStatus: created.status,
|
|
33257
33649
|
apiBaseUrl,
|
|
33258
33650
|
timeoutMs,
|
|
@@ -33264,7 +33656,7 @@ async function benchmarkStartupAction(context, commandOptions) {
|
|
|
33264
33656
|
await settleDiagnostics(diagnosticsDone);
|
|
33265
33657
|
const thresholdPassed = commandOptions.thresholdMs === void 0 ? void 0 : elapsedMs <= commandOptions.thresholdMs;
|
|
33266
33658
|
const result = {
|
|
33267
|
-
|
|
33659
|
+
session_id: created.session_id,
|
|
33268
33660
|
workflow_id: created.workflow_id,
|
|
33269
33661
|
status: poll.status,
|
|
33270
33662
|
started_at: startedAt.toISOString(),
|
|
@@ -33285,15 +33677,17 @@ async function benchmarkStartupAction(context, commandOptions) {
|
|
|
33285
33677
|
writeBenchmarkResult(context, result, commandOptions.json === true);
|
|
33286
33678
|
if (poll.timedOut) {
|
|
33287
33679
|
throw new Error(
|
|
33288
|
-
`
|
|
33680
|
+
`Session ${created.session_id} did not reach awaiting within ${timeoutMs}ms`
|
|
33289
33681
|
);
|
|
33290
33682
|
}
|
|
33291
33683
|
if (poll.status === "failed") {
|
|
33292
|
-
throw new Error(
|
|
33684
|
+
throw new Error(
|
|
33685
|
+
`Session ${created.session_id} failed before reaching awaiting`
|
|
33686
|
+
);
|
|
33293
33687
|
}
|
|
33294
33688
|
if (thresholdPassed === false) {
|
|
33295
33689
|
throw new Error(
|
|
33296
|
-
`
|
|
33690
|
+
`Session ${created.session_id} reached awaiting in ${elapsedMs}ms, above threshold ${commandOptions.thresholdMs}ms`
|
|
33297
33691
|
);
|
|
33298
33692
|
}
|
|
33299
33693
|
}
|
|
@@ -33322,11 +33716,11 @@ async function pollUntilAwaiting(input) {
|
|
|
33322
33716
|
if (Date.now() >= deadline) {
|
|
33323
33717
|
return { status, pollCount, timedOut: true };
|
|
33324
33718
|
}
|
|
33325
|
-
const
|
|
33719
|
+
const session = await input.client.getSession(input.sessionId, {
|
|
33326
33720
|
apiBaseUrl: input.apiBaseUrl
|
|
33327
33721
|
});
|
|
33328
33722
|
pollCount += 1;
|
|
33329
|
-
status =
|
|
33723
|
+
status = session.status;
|
|
33330
33724
|
}
|
|
33331
33725
|
}
|
|
33332
33726
|
function delay2(ms) {
|
|
@@ -33377,7 +33771,7 @@ function createDiagnosticCollector(limit) {
|
|
|
33377
33771
|
}
|
|
33378
33772
|
async function streamDiagnosticsBestEffort(input) {
|
|
33379
33773
|
try {
|
|
33380
|
-
await input.client.
|
|
33774
|
+
await input.client.streamSessionDiagnostics(input.sessionId, {
|
|
33381
33775
|
apiBaseUrl: input.apiBaseUrl,
|
|
33382
33776
|
signal: input.signal,
|
|
33383
33777
|
onEvent: input.onEvent
|
|
@@ -33396,7 +33790,7 @@ function writeBenchmarkResult(context, result, json2) {
|
|
|
33396
33790
|
context.writeOutput(JSON.stringify(result));
|
|
33397
33791
|
return;
|
|
33398
33792
|
}
|
|
33399
|
-
context.writeOutput(`
|
|
33793
|
+
context.writeOutput(`session_id ${result.session_id}`);
|
|
33400
33794
|
context.writeOutput(`workflow_id ${result.workflow_id}`);
|
|
33401
33795
|
context.writeOutput(`status ${result.status}`);
|
|
33402
33796
|
context.writeOutput(`elapsed_ms ${result.elapsed_ms}`);
|
|
@@ -33438,30 +33832,30 @@ function validateNonNegativeInteger(value, label) {
|
|
|
33438
33832
|
}
|
|
33439
33833
|
}
|
|
33440
33834
|
|
|
33441
|
-
// src/commands/
|
|
33835
|
+
// src/commands/sessions/introspect.ts
|
|
33442
33836
|
var PREVIEW_CHARS = 160;
|
|
33443
|
-
async function handleRunsShow(context,
|
|
33837
|
+
async function handleRunsShow(context, sessionId, options = {}) {
|
|
33444
33838
|
const client = createContextApiClient(context);
|
|
33445
33839
|
const apiBaseUrl = apiUrlFromOptions(context, options);
|
|
33446
|
-
const [
|
|
33447
|
-
client.
|
|
33448
|
-
client.
|
|
33840
|
+
const [session, summary] = await Promise.all([
|
|
33841
|
+
client.getSession(sessionId, { apiBaseUrl }),
|
|
33842
|
+
client.getSessionSummary(sessionId, { apiBaseUrl })
|
|
33449
33843
|
]);
|
|
33450
|
-
context.io.writeResult({
|
|
33844
|
+
context.io.writeResult({ session, summary }, formatRunShowText);
|
|
33451
33845
|
}
|
|
33452
33846
|
function formatRunShowText(result, writeLine, style) {
|
|
33453
33847
|
const { summary } = result;
|
|
33454
33848
|
writeLine(
|
|
33455
|
-
`${style.id(summary.
|
|
33456
|
-
`agent=${summary.
|
|
33849
|
+
`${style.id(summary.session.id)} ${styleSessionStatus(style, summary.session.status)} ${style.dim(
|
|
33850
|
+
`agent=${summary.session.agentName}`
|
|
33457
33851
|
)}`
|
|
33458
33852
|
);
|
|
33459
|
-
if (summary.
|
|
33460
|
-
writeLine(`${style.label("title:")} ${summary.
|
|
33853
|
+
if (summary.session.displayTitle) {
|
|
33854
|
+
writeLine(`${style.label("title:")} ${summary.session.displayTitle}`);
|
|
33461
33855
|
}
|
|
33462
33856
|
writeLine(
|
|
33463
33857
|
style.dim(
|
|
33464
|
-
`created=${summary.
|
|
33858
|
+
`created=${summary.session.createdAt} started=${summary.session.startedAt ?? "-"} finished=${summary.session.finishedAt ?? "-"}`
|
|
33465
33859
|
)
|
|
33466
33860
|
);
|
|
33467
33861
|
writeLine(
|
|
@@ -33506,14 +33900,14 @@ function formatRunShowText(result, writeLine, style) {
|
|
|
33506
33900
|
`${style.label("check:")} ${check2.name} ${check2.status}${check2.conclusion ? ` ${styleCheckConclusion(style, check2.conclusion)}` : ""}`
|
|
33507
33901
|
);
|
|
33508
33902
|
}
|
|
33509
|
-
if (summary.
|
|
33510
|
-
writeLine(style.error(`error: ${JSON.stringify(summary.
|
|
33903
|
+
if (summary.session.error !== null) {
|
|
33904
|
+
writeLine(style.error(`error: ${JSON.stringify(summary.session.error)}`));
|
|
33511
33905
|
}
|
|
33512
33906
|
}
|
|
33513
|
-
async function handleRunsConversation(context,
|
|
33907
|
+
async function handleRunsConversation(context, sessionId, options = {}) {
|
|
33514
33908
|
const client = createContextApiClient(context);
|
|
33515
33909
|
const tailMode = !options.after;
|
|
33516
|
-
const response = await client.
|
|
33910
|
+
const response = await client.getSessionConversation(sessionId, {
|
|
33517
33911
|
apiBaseUrl: apiUrlFromOptions(context, options),
|
|
33518
33912
|
cursor: options.after,
|
|
33519
33913
|
before: options.before,
|
|
@@ -33524,7 +33918,7 @@ async function handleRunsConversation(context, runId, options = {}) {
|
|
|
33524
33918
|
const events = [...response.events].sort((a, b) => a.sequence - b.sequence);
|
|
33525
33919
|
context.io.writeResult(
|
|
33526
33920
|
{
|
|
33527
|
-
|
|
33921
|
+
sessionId,
|
|
33528
33922
|
events,
|
|
33529
33923
|
cursor: response.cursor,
|
|
33530
33924
|
hasMore: response.hasMore,
|
|
@@ -33562,15 +33956,15 @@ function formatConversationText(result, writeLine, style) {
|
|
|
33562
33956
|
}
|
|
33563
33957
|
}
|
|
33564
33958
|
}
|
|
33565
|
-
async function handleRunsSearch(context,
|
|
33959
|
+
async function handleRunsSearch(context, sessionId, queries, options = {}) {
|
|
33566
33960
|
const client = createContextApiClient(context);
|
|
33567
|
-
const response = await client.
|
|
33961
|
+
const response = await client.searchSessionConversation(sessionId, queries, {
|
|
33568
33962
|
apiBaseUrl: apiUrlFromOptions(context, options),
|
|
33569
33963
|
kinds: options.kind,
|
|
33570
33964
|
after: options.after,
|
|
33571
33965
|
limit: options.limit
|
|
33572
33966
|
});
|
|
33573
|
-
context.io.writeResult({
|
|
33967
|
+
context.io.writeResult({ sessionId, queries, ...response }, formatSearchText);
|
|
33574
33968
|
}
|
|
33575
33969
|
function formatSearchText(result, writeLine, style) {
|
|
33576
33970
|
if (result.matches.length === 0) {
|
|
@@ -33594,9 +33988,9 @@ function formatSearchText(result, writeLine, style) {
|
|
|
33594
33988
|
);
|
|
33595
33989
|
}
|
|
33596
33990
|
}
|
|
33597
|
-
async function handleRunsTools(context,
|
|
33991
|
+
async function handleRunsTools(context, sessionId, options = {}) {
|
|
33598
33992
|
const client = createContextApiClient(context);
|
|
33599
|
-
const response = await client.
|
|
33993
|
+
const response = await client.listSessionToolExchanges(sessionId, {
|
|
33600
33994
|
apiBaseUrl: apiUrlFromOptions(context, options),
|
|
33601
33995
|
toolName: options.tool,
|
|
33602
33996
|
errorsOnly: options.errors,
|
|
@@ -33604,7 +33998,7 @@ async function handleRunsTools(context, runId, options = {}) {
|
|
|
33604
33998
|
before: options.before,
|
|
33605
33999
|
limit: options.limit
|
|
33606
34000
|
});
|
|
33607
|
-
context.io.writeResult({
|
|
34001
|
+
context.io.writeResult({ sessionId, ...response }, formatToolsText);
|
|
33608
34002
|
}
|
|
33609
34003
|
function formatToolsText(result, writeLine, style) {
|
|
33610
34004
|
if (result.exchanges.length === 0) {
|
|
@@ -33634,12 +34028,12 @@ function exchangeOutcome(style, isError) {
|
|
|
33634
34028
|
}
|
|
33635
34029
|
return isError ? style.error("ERR") : style.success("ok");
|
|
33636
34030
|
}
|
|
33637
|
-
async function handleRunsTriggers(context,
|
|
34031
|
+
async function handleRunsTriggers(context, sessionId, options = {}) {
|
|
33638
34032
|
const client = createContextApiClient(context);
|
|
33639
|
-
const response = await client.
|
|
34033
|
+
const response = await client.listSessionTriggers(sessionId, {
|
|
33640
34034
|
apiBaseUrl: apiUrlFromOptions(context, options)
|
|
33641
34035
|
});
|
|
33642
|
-
context.io.writeResult({
|
|
34036
|
+
context.io.writeResult({ sessionId, ...response }, formatTriggersText);
|
|
33643
34037
|
}
|
|
33644
34038
|
function formatTriggersText(result, writeLine, style) {
|
|
33645
34039
|
if (result.spawn) {
|
|
@@ -33650,7 +34044,7 @@ function formatTriggersText(result, writeLine, style) {
|
|
|
33650
34044
|
);
|
|
33651
34045
|
} else if (result.starter) {
|
|
33652
34046
|
writeLine(
|
|
33653
|
-
`${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)}`)}`
|
|
33654
34048
|
);
|
|
33655
34049
|
} else {
|
|
33656
34050
|
writeLine(`${style.label("spawn:")} manual`);
|
|
@@ -33666,12 +34060,12 @@ function formatTriggersText(result, writeLine, style) {
|
|
|
33666
34060
|
);
|
|
33667
34061
|
}
|
|
33668
34062
|
}
|
|
33669
|
-
async function handleRunsArtifacts(context,
|
|
34063
|
+
async function handleRunsArtifacts(context, sessionId, options = {}) {
|
|
33670
34064
|
const client = createContextApiClient(context);
|
|
33671
|
-
const response = await client.listRunArtifacts(
|
|
34065
|
+
const response = await client.listRunArtifacts(sessionId, {
|
|
33672
34066
|
apiBaseUrl: apiUrlFromOptions(context, options)
|
|
33673
34067
|
});
|
|
33674
|
-
context.io.writeResult({
|
|
34068
|
+
context.io.writeResult({ sessionId, ...response }, formatArtifactsText);
|
|
33675
34069
|
}
|
|
33676
34070
|
function formatArtifactsText(result, writeLine, style) {
|
|
33677
34071
|
if (result.artifacts.length === 0) {
|
|
@@ -33686,12 +34080,12 @@ function formatArtifactsText(result, writeLine, style) {
|
|
|
33686
34080
|
);
|
|
33687
34081
|
}
|
|
33688
34082
|
}
|
|
33689
|
-
async function handleRunsCommands(context,
|
|
34083
|
+
async function handleRunsCommands(context, sessionId, options = {}) {
|
|
33690
34084
|
const client = createContextApiClient(context);
|
|
33691
|
-
const response = await client.
|
|
34085
|
+
const response = await client.listSessionCommands(sessionId, {
|
|
33692
34086
|
apiBaseUrl: apiUrlFromOptions(context, options)
|
|
33693
34087
|
});
|
|
33694
|
-
context.io.writeResult({
|
|
34088
|
+
context.io.writeResult({ sessionId, ...response }, formatCommandsText);
|
|
33695
34089
|
}
|
|
33696
34090
|
function formatCommandsText(result, writeLine, style) {
|
|
33697
34091
|
if (result.commands.length === 0) {
|
|
@@ -33756,21 +34150,29 @@ function clip(text) {
|
|
|
33756
34150
|
return text.length > PREVIEW_CHARS ? `${text.slice(0, PREVIEW_CHARS)}\u2026` : text;
|
|
33757
34151
|
}
|
|
33758
34152
|
|
|
33759
|
-
// src/commands/
|
|
34153
|
+
// src/commands/sessions/commands.ts
|
|
33760
34154
|
function collect(value, previous = []) {
|
|
33761
34155
|
return [...previous, value];
|
|
33762
34156
|
}
|
|
33763
|
-
function
|
|
33764
|
-
const
|
|
33765
|
-
|
|
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) => {
|
|
33766
34168
|
await handleRunsList(context, options.agent, options);
|
|
33767
34169
|
});
|
|
33768
|
-
|
|
33769
|
-
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);
|
|
33770
34172
|
});
|
|
33771
|
-
|
|
33772
|
-
"Read a snapshot of a
|
|
33773
|
-
).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(
|
|
33774
34176
|
"--tail <count>",
|
|
33775
34177
|
"number of most recent entries",
|
|
33776
34178
|
parsePositiveInteger
|
|
@@ -33779,20 +34181,22 @@ function registerRunCommands(program, context) {
|
|
|
33779
34181
|
"only entries older than this sequence (backward paging)",
|
|
33780
34182
|
parsePositiveInteger
|
|
33781
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(
|
|
33782
|
-
async (
|
|
33783
|
-
await handleRunsConversation(context,
|
|
34184
|
+
async (sessionId, commandOptions) => {
|
|
34185
|
+
await handleRunsConversation(context, sessionId, commandOptions);
|
|
33784
34186
|
}
|
|
33785
34187
|
);
|
|
33786
|
-
|
|
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(
|
|
33787
34191
|
"--after <sequence>",
|
|
33788
34192
|
"only entries after this sequence (forward paging)",
|
|
33789
34193
|
parsePositiveInteger
|
|
33790
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(
|
|
33791
|
-
async (
|
|
33792
|
-
await handleRunsSearch(context,
|
|
34195
|
+
async (sessionId, queries, commandOptions) => {
|
|
34196
|
+
await handleRunsSearch(context, sessionId, queries, commandOptions);
|
|
33793
34197
|
}
|
|
33794
34198
|
);
|
|
33795
|
-
|
|
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(
|
|
33796
34200
|
"--after <sequence>",
|
|
33797
34201
|
"only exchanges after this entry sequence",
|
|
33798
34202
|
parsePositiveInteger
|
|
@@ -33801,37 +34205,49 @@ function registerRunCommands(program, context) {
|
|
|
33801
34205
|
"only exchanges before this entry sequence (backward paging)",
|
|
33802
34206
|
parsePositiveInteger
|
|
33803
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(
|
|
33804
|
-
async (
|
|
33805
|
-
await handleRunsTools(context,
|
|
34208
|
+
async (sessionId, commandOptions) => {
|
|
34209
|
+
await handleRunsTools(context, sessionId, commandOptions);
|
|
33806
34210
|
}
|
|
33807
34211
|
);
|
|
33808
|
-
|
|
33809
|
-
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);
|
|
33810
34214
|
});
|
|
33811
|
-
|
|
33812
|
-
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);
|
|
33813
34217
|
});
|
|
33814
|
-
|
|
33815
|
-
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);
|
|
33816
34220
|
});
|
|
33817
|
-
|
|
33818
|
-
|
|
33819
|
-
|
|
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
|
+
);
|
|
33820
34230
|
return;
|
|
33821
34231
|
}
|
|
33822
|
-
await
|
|
34232
|
+
await archiveSessionsAction(context, sessionIds, commandOptions);
|
|
33823
34233
|
});
|
|
33824
|
-
|
|
33825
|
-
if (
|
|
33826
|
-
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
|
+
);
|
|
33827
34241
|
return;
|
|
33828
34242
|
}
|
|
33829
|
-
await
|
|
33830
|
-
});
|
|
33831
|
-
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) => {
|
|
33832
|
-
await stopRunsAction(context, runIds, commandOptions);
|
|
34243
|
+
await unarchiveSessionsAction(context, sessionIds, commandOptions);
|
|
33833
34244
|
});
|
|
33834
|
-
|
|
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(
|
|
33835
34251
|
"--interactive",
|
|
33836
34252
|
"start without the default initial prompt unless --message is provided"
|
|
33837
34253
|
).option(
|
|
@@ -33840,7 +34256,7 @@ function registerRunCommands(program, context) {
|
|
|
33840
34256
|
parsePositiveInteger
|
|
33841
34257
|
).option(
|
|
33842
34258
|
"--poll-interval-ms <ms>",
|
|
33843
|
-
"
|
|
34259
|
+
"session status polling interval",
|
|
33844
34260
|
parsePositiveInteger
|
|
33845
34261
|
).option(
|
|
33846
34262
|
"--threshold-ms <ms>",
|
|
@@ -33853,343 +34269,30 @@ function registerRunCommands(program, context) {
|
|
|
33853
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) => {
|
|
33854
34270
|
await benchmarkStartupAction(context, options);
|
|
33855
34271
|
});
|
|
33856
|
-
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(
|
|
33857
34273
|
"--attach-message",
|
|
33858
|
-
"send the automated attach message after creating the
|
|
34274
|
+
"send the automated attach message after creating the session"
|
|
33859
34275
|
).option("--no-attach-message", "do not send the automated attach message").option("--no-detach-message", "do not send the automated detach message").action(
|
|
33860
34276
|
async (agentName, commandOptions) => {
|
|
33861
34277
|
await interactiveRunAction(context, agentName, commandOptions);
|
|
33862
34278
|
}
|
|
33863
34279
|
);
|
|
33864
|
-
program.command("attach").description("Stream an existing
|
|
33865
|
-
await attachRunAction(context,
|
|
33866
|
-
});
|
|
33867
|
-
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) => {
|
|
33868
|
-
await consoleRunAction(context, runId, commandOptions);
|
|
33869
|
-
});
|
|
33870
|
-
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(
|
|
33871
|
-
async (runId, message, commandOptions) => {
|
|
33872
|
-
await sendRunMessageAction(context, runId, message, commandOptions);
|
|
33873
|
-
}
|
|
33874
|
-
);
|
|
33875
|
-
}
|
|
33876
|
-
|
|
33877
|
-
// src/commands/secrets/actions.ts
|
|
33878
|
-
async function setSecret(input) {
|
|
33879
|
-
const value = await secretValue({
|
|
33880
|
-
options: input.commandOptions,
|
|
33881
|
-
env: input.context.env,
|
|
33882
|
-
stdin: input.context.stdin
|
|
33883
|
-
});
|
|
33884
|
-
const response = await input.client.setSecret(
|
|
33885
|
-
input.name,
|
|
33886
|
-
{ value },
|
|
33887
|
-
{
|
|
33888
|
-
projectId: await secretProjectId(input),
|
|
33889
|
-
apiBaseUrl: input.commandOptions.apiBaseUrl
|
|
33890
|
-
}
|
|
33891
|
-
);
|
|
33892
|
-
writeSetResponse(response, input);
|
|
33893
|
-
}
|
|
33894
|
-
async function listSecrets(input) {
|
|
33895
|
-
const response = await input.client.listSecrets({
|
|
33896
|
-
projectId: await secretProjectId(input),
|
|
33897
|
-
apiBaseUrl: input.commandOptions.apiBaseUrl
|
|
33898
|
-
});
|
|
33899
|
-
if (input.commandOptions.json) {
|
|
33900
|
-
input.context.writeOutput(JSON.stringify(response));
|
|
33901
|
-
return;
|
|
33902
|
-
}
|
|
33903
|
-
if (response.secrets.length === 0) {
|
|
33904
|
-
input.context.writeOutput("No secrets found.");
|
|
33905
|
-
return;
|
|
33906
|
-
}
|
|
33907
|
-
for (const secret of response.secrets) {
|
|
33908
|
-
input.context.writeOutput(
|
|
33909
|
-
`${secret.name} ${scopeLabel(secret.projectId)} updated ${secret.updatedAt}`
|
|
33910
|
-
);
|
|
33911
|
-
}
|
|
33912
|
-
}
|
|
33913
|
-
async function removeSecret(input) {
|
|
33914
|
-
await confirmDestructiveAction(input.context, {
|
|
33915
|
-
message: `This will remove secret "${input.name}".`,
|
|
33916
|
-
yes: input.commandOptions.yes
|
|
33917
|
-
});
|
|
33918
|
-
const response = await input.client.removeSecret(input.name, {
|
|
33919
|
-
projectId: await secretProjectId(input),
|
|
33920
|
-
apiBaseUrl: input.commandOptions.apiBaseUrl
|
|
33921
|
-
});
|
|
33922
|
-
writeRemoveResponse(response, input);
|
|
33923
|
-
}
|
|
33924
|
-
async function secretProjectId(input) {
|
|
33925
|
-
if (!input.commandOptions.project) {
|
|
33926
|
-
return void 0;
|
|
33927
|
-
}
|
|
33928
|
-
const scope = await requireProjectScope({
|
|
33929
|
-
context: input.context,
|
|
33930
|
-
options: input.commandOptions,
|
|
33931
|
-
identifier: input.commandOptions.project,
|
|
33932
|
-
explicitHint: "--project <project>"
|
|
33933
|
-
});
|
|
33934
|
-
return scope.projectId;
|
|
33935
|
-
}
|
|
33936
|
-
async function secretValue(input) {
|
|
33937
|
-
const sources = [
|
|
33938
|
-
input.options.stdin ? "stdin" : void 0,
|
|
33939
|
-
input.options.value !== void 0 ? "value" : void 0,
|
|
33940
|
-
input.options.fromEnv ? "from-env" : void 0
|
|
33941
|
-
].filter(Boolean);
|
|
33942
|
-
if (sources.length > 1) {
|
|
33943
|
-
throw new Error("Use only one of --stdin, --value, or --from-env.");
|
|
33944
|
-
}
|
|
33945
|
-
let value;
|
|
33946
|
-
if (input.options.value !== void 0) {
|
|
33947
|
-
value = input.options.value;
|
|
33948
|
-
} else if (input.options.fromEnv) {
|
|
33949
|
-
const envValue = input.env[input.options.fromEnv];
|
|
33950
|
-
if (envValue === void 0) {
|
|
33951
|
-
throw new Error(`Environment variable not set: ${input.options.fromEnv}`);
|
|
33952
|
-
}
|
|
33953
|
-
value = envValue;
|
|
33954
|
-
} else if (input.options.stdin) {
|
|
33955
|
-
value = await readStream2(input.stdin, Boolean(input.options.raw));
|
|
33956
|
-
} else {
|
|
33957
|
-
throw new Error(
|
|
33958
|
-
"Provide the secret value with --stdin, --value, or --from-env."
|
|
33959
|
-
);
|
|
33960
|
-
}
|
|
33961
|
-
if (value.length === 0 && !input.options.raw) {
|
|
33962
|
-
throw new Error(
|
|
33963
|
-
"Secret value is empty. Pass --raw to store an empty value."
|
|
33964
|
-
);
|
|
33965
|
-
}
|
|
33966
|
-
return value;
|
|
33967
|
-
}
|
|
33968
|
-
async function readStream2(stream, raw) {
|
|
33969
|
-
const chunks = [];
|
|
33970
|
-
for await (const chunk of stream) {
|
|
33971
|
-
chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(String(chunk)));
|
|
33972
|
-
}
|
|
33973
|
-
const value = Buffer.concat(chunks).toString("utf8");
|
|
33974
|
-
return raw ? value : value.replace(/\r?\n$/, "");
|
|
33975
|
-
}
|
|
33976
|
-
function writeSetResponse(response, input) {
|
|
33977
|
-
if (input.commandOptions.json) {
|
|
33978
|
-
input.context.writeOutput(JSON.stringify(response));
|
|
33979
|
-
return;
|
|
33980
|
-
}
|
|
33981
|
-
input.context.writeOutput(
|
|
33982
|
-
`secret ${response.secret.name} updated scope=${scopeLabel(response.secret.projectId)}`
|
|
33983
|
-
);
|
|
33984
|
-
}
|
|
33985
|
-
function writeRemoveResponse(response, input) {
|
|
33986
|
-
if (input.commandOptions.json) {
|
|
33987
|
-
input.context.writeOutput(JSON.stringify(response));
|
|
33988
|
-
return;
|
|
33989
|
-
}
|
|
33990
|
-
input.context.writeOutput(
|
|
33991
|
-
`secret ${response.secret.name} removed scope=${scopeLabel(response.secret.projectId)}`
|
|
33992
|
-
);
|
|
33993
|
-
}
|
|
33994
|
-
function scopeLabel(projectId) {
|
|
33995
|
-
return projectId ? `project:${projectId}` : "organization";
|
|
33996
|
-
}
|
|
33997
|
-
|
|
33998
|
-
// src/commands/secrets/commands.ts
|
|
33999
|
-
function registerSecretCommands(program, context) {
|
|
34000
|
-
const secrets = program.command("secrets").description("Manage Auto organization and project secrets.");
|
|
34001
|
-
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(
|
|
34002
|
-
"--from-env <name>",
|
|
34003
|
-
"read the secret value from an environment variable"
|
|
34004
|
-
).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) => {
|
|
34005
|
-
await setSecret({
|
|
34006
|
-
client: createContextApiClient(context),
|
|
34007
|
-
commandOptions: withApiBaseUrl(context, commandOptions),
|
|
34008
|
-
context,
|
|
34009
|
-
name
|
|
34010
|
-
});
|
|
34011
|
-
});
|
|
34012
|
-
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) => {
|
|
34013
|
-
await listSecrets({
|
|
34014
|
-
client: createContextApiClient(context),
|
|
34015
|
-
commandOptions: withApiBaseUrl(context, commandOptions),
|
|
34016
|
-
context
|
|
34017
|
-
});
|
|
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);
|
|
34018
34282
|
});
|
|
34019
|
-
|
|
34020
|
-
|
|
34021
|
-
|
|
34022
|
-
|
|
34023
|
-
context,
|
|
34024
|
-
name
|
|
34025
|
-
});
|
|
34026
|
-
});
|
|
34027
|
-
}
|
|
34028
|
-
function withApiBaseUrl(context, commandOptions) {
|
|
34029
|
-
return {
|
|
34030
|
-
...commandOptions,
|
|
34031
|
-
apiBaseUrl: apiUrlFromOptions(context, commandOptions)
|
|
34032
|
-
};
|
|
34033
|
-
}
|
|
34034
|
-
|
|
34035
|
-
// src/commands/service-accounts/actions.ts
|
|
34036
|
-
init_src();
|
|
34037
|
-
async function createServiceAccount(input) {
|
|
34038
|
-
const response = await input.client.createProjectServiceAccount(
|
|
34039
|
-
{ name: input.name, scopes: requestedScopes(input.commandOptions) },
|
|
34040
|
-
{ apiBaseUrl: input.commandOptions.apiBaseUrl }
|
|
34041
|
-
);
|
|
34042
|
-
writeServiceAccountTokenResponse(response, input);
|
|
34043
|
-
}
|
|
34044
|
-
async function updateServiceAccount(input) {
|
|
34045
|
-
const response = await input.client.updateProjectServiceAccount(
|
|
34046
|
-
{ name: input.name, scopes: requestedScopes(input.commandOptions) },
|
|
34047
|
-
{ apiBaseUrl: input.commandOptions.apiBaseUrl }
|
|
34048
|
-
);
|
|
34049
|
-
if (input.commandOptions.json) {
|
|
34050
|
-
input.writeOutput(JSON.stringify(response));
|
|
34051
|
-
return;
|
|
34052
|
-
}
|
|
34053
|
-
writeServiceAccountScopesResponse(response, input.writeOutput);
|
|
34054
|
-
}
|
|
34055
|
-
async function rotateServiceAccount(input) {
|
|
34056
|
-
const response = await input.client.rotateProjectServiceAccountToken(
|
|
34057
|
-
{ name: input.name },
|
|
34058
|
-
{ apiBaseUrl: input.commandOptions.apiBaseUrl }
|
|
34059
|
-
);
|
|
34060
|
-
writeServiceAccountTokenResponse(response, input);
|
|
34061
|
-
}
|
|
34062
|
-
async function removeServiceAccount(input) {
|
|
34063
|
-
const response = await input.client.removeProjectServiceAccount(
|
|
34064
|
-
{ name: input.name },
|
|
34065
|
-
{ apiBaseUrl: input.commandOptions.apiBaseUrl }
|
|
34066
|
-
);
|
|
34067
|
-
if (input.commandOptions.json) {
|
|
34068
|
-
input.writeOutput(JSON.stringify(response));
|
|
34069
|
-
return;
|
|
34070
|
-
}
|
|
34071
|
-
input.writeOutput(`removed service-account ${response.serviceAccount.name}`);
|
|
34072
|
-
}
|
|
34073
|
-
function requestedScopes(options) {
|
|
34074
|
-
const presetNames = Object.keys(SERVICE_ACCOUNT_SCOPE_PRESETS).join(", ");
|
|
34075
|
-
const scopes = [];
|
|
34076
|
-
if (options.preset !== void 0) {
|
|
34077
|
-
const preset = ServiceAccountScopePresetSchema.safeParse(options.preset);
|
|
34078
|
-
if (!preset.success) {
|
|
34079
|
-
throw new Error(
|
|
34080
|
-
`Unknown preset "${options.preset}". Available presets: ${presetNames}.`
|
|
34081
|
-
);
|
|
34082
|
-
}
|
|
34083
|
-
scopes.push(...SERVICE_ACCOUNT_SCOPE_PRESETS[preset.data]);
|
|
34084
|
-
}
|
|
34085
|
-
for (const scope of options.scope ?? []) {
|
|
34086
|
-
if (!AuthScopeSchema.safeParse(scope).success) {
|
|
34087
|
-
throw new Error(
|
|
34088
|
-
`Unknown scope "${scope}". Valid scopes: ${AUTH_SCOPES.join(", ")}.`
|
|
34089
|
-
);
|
|
34090
|
-
}
|
|
34091
|
-
scopes.push(scope);
|
|
34092
|
-
}
|
|
34093
|
-
if (scopes.length === 0) {
|
|
34094
|
-
throw new Error(
|
|
34095
|
-
`Provide --preset <preset> (${presetNames}) or at least one --scope.`
|
|
34096
|
-
);
|
|
34097
|
-
}
|
|
34098
|
-
return [...new Set(scopes)];
|
|
34099
|
-
}
|
|
34100
|
-
function writeServiceAccountTokenResponse(response, input) {
|
|
34101
|
-
if (input.commandOptions.json) {
|
|
34102
|
-
input.writeOutput(JSON.stringify(response));
|
|
34103
|
-
return;
|
|
34104
|
-
}
|
|
34105
|
-
input.writeOutput(`service-account ${response.serviceAccount.name}`);
|
|
34106
|
-
input.writeOutput(
|
|
34107
|
-
`scopes ${response.serviceAccount.scopes.join(", ") || "(none)"}`
|
|
34108
|
-
);
|
|
34109
|
-
input.writeOutput(`token ${response.token}`);
|
|
34110
|
-
}
|
|
34111
|
-
function writeServiceAccountScopesResponse(response, writeOutput) {
|
|
34112
|
-
writeOutput(`service-account ${response.serviceAccount.name}`);
|
|
34113
|
-
writeOutput(
|
|
34114
|
-
`scopes ${response.serviceAccount.scopes.join(", ") || "(none)"}`
|
|
34115
|
-
);
|
|
34116
|
-
}
|
|
34117
|
-
|
|
34118
|
-
// src/commands/service-accounts/commands.ts
|
|
34119
|
-
function registerServiceAccountCommands(program, context) {
|
|
34120
|
-
const serviceAccount = program.command("service-account").description("Manage Auto project service accounts.");
|
|
34121
|
-
serviceAccount.command("create").description("Create a project service account and print its token.").argument("<name>", "service account name").option(
|
|
34122
|
-
"--preset <preset>",
|
|
34123
|
-
"grant a named scope bundle (read-only, applier)"
|
|
34124
|
-
).option(
|
|
34125
|
-
"--scope <scope>",
|
|
34126
|
-
"grant a scope; repeat to grant multiple scopes",
|
|
34127
|
-
collectScopes
|
|
34128
|
-
).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(
|
|
34129
|
-
async (name, commandOptions) => {
|
|
34130
|
-
await createServiceAccount({
|
|
34131
|
-
client: createContextApiClient(context),
|
|
34132
|
-
commandOptions: withApiBaseUrl2(context, commandOptions),
|
|
34133
|
-
name,
|
|
34134
|
-
writeOutput: context.writeOutput
|
|
34135
|
-
});
|
|
34136
|
-
}
|
|
34137
|
-
);
|
|
34138
|
-
serviceAccount.command("update").description("Update project service account scopes.").argument("<name>", "service account name").option(
|
|
34139
|
-
"--preset <preset>",
|
|
34140
|
-
"grant a named scope bundle (read-only, applier)"
|
|
34141
|
-
).option(
|
|
34142
|
-
"--scope <scope>",
|
|
34143
|
-
"grant a scope; repeat to grant multiple scopes",
|
|
34144
|
-
collectScopes
|
|
34145
|
-
).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(
|
|
34146
|
-
async (name, commandOptions) => {
|
|
34147
|
-
await updateServiceAccount({
|
|
34148
|
-
client: createContextApiClient(context),
|
|
34149
|
-
commandOptions: withApiBaseUrl2(context, commandOptions),
|
|
34150
|
-
name,
|
|
34151
|
-
writeOutput: context.writeOutput
|
|
34152
|
-
});
|
|
34153
|
-
}
|
|
34154
|
-
);
|
|
34155
|
-
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(
|
|
34156
|
-
async (name, commandOptions) => {
|
|
34157
|
-
await confirmDestructiveAction(context, {
|
|
34158
|
-
message: `This will rotate service account "${name}" and revoke its current token.`,
|
|
34159
|
-
yes: commandOptions.yes
|
|
34160
|
-
});
|
|
34161
|
-
await rotateServiceAccount({
|
|
34162
|
-
client: createContextApiClient(context),
|
|
34163
|
-
commandOptions: withApiBaseUrl2(context, commandOptions),
|
|
34164
|
-
name,
|
|
34165
|
-
writeOutput: context.writeOutput
|
|
34166
|
-
});
|
|
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);
|
|
34167
34288
|
}
|
|
34168
34289
|
);
|
|
34169
|
-
|
|
34170
|
-
async (
|
|
34171
|
-
await
|
|
34172
|
-
message: `This will remove service account "${name}" and revoke its token.`,
|
|
34173
|
-
yes: commandOptions.yes
|
|
34174
|
-
});
|
|
34175
|
-
await removeServiceAccount({
|
|
34176
|
-
client: createContextApiClient(context),
|
|
34177
|
-
commandOptions: withApiBaseUrl2(context, commandOptions),
|
|
34178
|
-
name,
|
|
34179
|
-
writeOutput: context.writeOutput
|
|
34180
|
-
});
|
|
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);
|
|
34181
34293
|
}
|
|
34182
34294
|
);
|
|
34183
34295
|
}
|
|
34184
|
-
function collectScopes(scope, scopes) {
|
|
34185
|
-
return [...scopes ?? [], scope];
|
|
34186
|
-
}
|
|
34187
|
-
function withApiBaseUrl2(context, commandOptions) {
|
|
34188
|
-
return {
|
|
34189
|
-
...commandOptions,
|
|
34190
|
-
apiBaseUrl: apiUrlFromOptions(context, commandOptions)
|
|
34191
|
-
};
|
|
34192
|
-
}
|
|
34193
34296
|
|
|
34194
34297
|
// src/commands/sync/repo.ts
|
|
34195
34298
|
import { execFile as execFileWithCallback } from "child_process";
|
|
@@ -34488,7 +34591,7 @@ function createProgram(options = {}) {
|
|
|
34488
34591
|
registerSecretCommands(program, context);
|
|
34489
34592
|
registerSyncCommands(program, context);
|
|
34490
34593
|
registerAgentCommands(program, context);
|
|
34491
|
-
|
|
34594
|
+
registerSessionCommands(program, context);
|
|
34492
34595
|
return program;
|
|
34493
34596
|
}
|
|
34494
34597
|
|