@locusai/cli 0.11.5 → 0.11.7
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/bin/agent/worker.js +570 -56
- package/bin/locus.js +864 -274
- package/package.json +2 -2
package/bin/locus.js
CHANGED
|
@@ -7507,14 +7507,16 @@ class CodexRunner {
|
|
|
7507
7507
|
projectPath;
|
|
7508
7508
|
model;
|
|
7509
7509
|
log;
|
|
7510
|
+
reasoningEffort;
|
|
7510
7511
|
activeProcess = null;
|
|
7511
7512
|
eventEmitter;
|
|
7512
7513
|
currentToolName;
|
|
7513
7514
|
timeoutMs;
|
|
7514
|
-
constructor(projectPath, model = DEFAULT_MODEL[PROVIDER.CODEX], log, timeoutMs) {
|
|
7515
|
+
constructor(projectPath, model = DEFAULT_MODEL[PROVIDER.CODEX], log, timeoutMs, reasoningEffort) {
|
|
7515
7516
|
this.projectPath = projectPath;
|
|
7516
7517
|
this.model = model;
|
|
7517
7518
|
this.log = log;
|
|
7519
|
+
this.reasoningEffort = reasoningEffort;
|
|
7518
7520
|
this.timeoutMs = timeoutMs ?? DEFAULT_TIMEOUT_MS2;
|
|
7519
7521
|
}
|
|
7520
7522
|
setEventEmitter(emitter) {
|
|
@@ -7779,6 +7781,9 @@ class CodexRunner {
|
|
|
7779
7781
|
if (this.model) {
|
|
7780
7782
|
args.push("--model", this.model);
|
|
7781
7783
|
}
|
|
7784
|
+
if (this.reasoningEffort) {
|
|
7785
|
+
args.push("-c", `model_reasoning_effort=${this.reasoningEffort}`);
|
|
7786
|
+
}
|
|
7782
7787
|
args.push("-");
|
|
7783
7788
|
return args;
|
|
7784
7789
|
}
|
|
@@ -7833,7 +7838,7 @@ function createAiRunner(provider, config) {
|
|
|
7833
7838
|
const model = config.model ?? DEFAULT_MODEL[resolvedProvider];
|
|
7834
7839
|
switch (resolvedProvider) {
|
|
7835
7840
|
case PROVIDER.CODEX:
|
|
7836
|
-
return new CodexRunner(config.projectPath, model, config.log, config.timeoutMs);
|
|
7841
|
+
return new CodexRunner(config.projectPath, model, config.log, config.timeoutMs, config.reasoningEffort ?? "high");
|
|
7837
7842
|
default:
|
|
7838
7843
|
return new ClaudeRunner(config.projectPath, model, config.log, config.timeoutMs);
|
|
7839
7844
|
}
|
|
@@ -37977,12 +37982,536 @@ var init_models = __esm(() => {
|
|
|
37977
37982
|
init_workspace();
|
|
37978
37983
|
});
|
|
37979
37984
|
|
|
37985
|
+
// ../shared/src/protocol/envelope.ts
|
|
37986
|
+
var PROTOCOL_VERSION = 1, ProtocolVersionSchema, ProtocolEnvelopeSchema;
|
|
37987
|
+
var init_envelope = __esm(() => {
|
|
37988
|
+
init_zod();
|
|
37989
|
+
ProtocolVersionSchema = exports_external.literal(PROTOCOL_VERSION);
|
|
37990
|
+
ProtocolEnvelopeSchema = exports_external.object({
|
|
37991
|
+
protocol: ProtocolVersionSchema,
|
|
37992
|
+
type: exports_external.string()
|
|
37993
|
+
});
|
|
37994
|
+
});
|
|
37995
|
+
|
|
37996
|
+
// ../shared/src/protocol/errors.ts
|
|
37997
|
+
var ProtocolErrorCode, ProtocolErrorCodeSchema, ProtocolErrorSchema;
|
|
37998
|
+
var init_errors3 = __esm(() => {
|
|
37999
|
+
init_zod();
|
|
38000
|
+
ProtocolErrorCode = {
|
|
38001
|
+
CLI_NOT_FOUND: "CLI_NOT_FOUND",
|
|
38002
|
+
AUTH_EXPIRED: "AUTH_EXPIRED",
|
|
38003
|
+
NETWORK_TIMEOUT: "NETWORK_TIMEOUT",
|
|
38004
|
+
CONTEXT_LIMIT: "CONTEXT_LIMIT",
|
|
38005
|
+
MALFORMED_EVENT: "MALFORMED_EVENT",
|
|
38006
|
+
PROCESS_CRASHED: "PROCESS_CRASHED",
|
|
38007
|
+
SESSION_NOT_FOUND: "SESSION_NOT_FOUND",
|
|
38008
|
+
UNKNOWN: "UNKNOWN"
|
|
38009
|
+
};
|
|
38010
|
+
ProtocolErrorCodeSchema = exports_external.enum(ProtocolErrorCode);
|
|
38011
|
+
ProtocolErrorSchema = exports_external.object({
|
|
38012
|
+
code: ProtocolErrorCodeSchema,
|
|
38013
|
+
message: exports_external.string(),
|
|
38014
|
+
details: exports_external.unknown().optional(),
|
|
38015
|
+
recoverable: exports_external.boolean()
|
|
38016
|
+
});
|
|
38017
|
+
});
|
|
38018
|
+
|
|
38019
|
+
// ../shared/src/protocol/cli-stream.ts
|
|
38020
|
+
function createCliStreamEvent(type, sessionId, payload) {
|
|
38021
|
+
return CliStreamEventSchema.parse({
|
|
38022
|
+
protocol: PROTOCOL_VERSION,
|
|
38023
|
+
type,
|
|
38024
|
+
sessionId,
|
|
38025
|
+
timestamp: Date.now(),
|
|
38026
|
+
payload
|
|
38027
|
+
});
|
|
38028
|
+
}
|
|
38029
|
+
var CliStreamEventType, CliStreamEventTypeSchema, CliStreamBaseSchema, CliStartEventSchema, CliTextDeltaEventSchema, CliThinkingEventSchema, CliToolStartedEventSchema, CliToolCompletedEventSchema, CliStatusEventSchema, CliErrorEventSchema, CliDoneEventSchema, CliStreamEventSchema;
|
|
38030
|
+
var init_cli_stream = __esm(() => {
|
|
38031
|
+
init_zod();
|
|
38032
|
+
init_envelope();
|
|
38033
|
+
init_errors3();
|
|
38034
|
+
CliStreamEventType = {
|
|
38035
|
+
START: "start",
|
|
38036
|
+
TEXT_DELTA: "text_delta",
|
|
38037
|
+
THINKING: "thinking",
|
|
38038
|
+
TOOL_STARTED: "tool_started",
|
|
38039
|
+
TOOL_COMPLETED: "tool_completed",
|
|
38040
|
+
STATUS: "status",
|
|
38041
|
+
ERROR: "error",
|
|
38042
|
+
DONE: "done"
|
|
38043
|
+
};
|
|
38044
|
+
CliStreamEventTypeSchema = exports_external.enum(CliStreamEventType);
|
|
38045
|
+
CliStreamBaseSchema = exports_external.object({
|
|
38046
|
+
protocol: ProtocolVersionSchema,
|
|
38047
|
+
sessionId: exports_external.string(),
|
|
38048
|
+
timestamp: exports_external.number()
|
|
38049
|
+
});
|
|
38050
|
+
CliStartEventSchema = CliStreamBaseSchema.extend({
|
|
38051
|
+
type: exports_external.literal(CliStreamEventType.START),
|
|
38052
|
+
payload: exports_external.object({
|
|
38053
|
+
command: exports_external.string(),
|
|
38054
|
+
model: exports_external.string().optional(),
|
|
38055
|
+
provider: exports_external.string().optional(),
|
|
38056
|
+
cwd: exports_external.string().optional()
|
|
38057
|
+
})
|
|
38058
|
+
});
|
|
38059
|
+
CliTextDeltaEventSchema = CliStreamBaseSchema.extend({
|
|
38060
|
+
type: exports_external.literal(CliStreamEventType.TEXT_DELTA),
|
|
38061
|
+
payload: exports_external.object({
|
|
38062
|
+
content: exports_external.string()
|
|
38063
|
+
})
|
|
38064
|
+
});
|
|
38065
|
+
CliThinkingEventSchema = CliStreamBaseSchema.extend({
|
|
38066
|
+
type: exports_external.literal(CliStreamEventType.THINKING),
|
|
38067
|
+
payload: exports_external.object({
|
|
38068
|
+
content: exports_external.string().optional()
|
|
38069
|
+
})
|
|
38070
|
+
});
|
|
38071
|
+
CliToolStartedEventSchema = CliStreamBaseSchema.extend({
|
|
38072
|
+
type: exports_external.literal(CliStreamEventType.TOOL_STARTED),
|
|
38073
|
+
payload: exports_external.object({
|
|
38074
|
+
tool: exports_external.string(),
|
|
38075
|
+
toolId: exports_external.string().optional(),
|
|
38076
|
+
parameters: exports_external.record(exports_external.string(), exports_external.unknown()).optional()
|
|
38077
|
+
})
|
|
38078
|
+
});
|
|
38079
|
+
CliToolCompletedEventSchema = CliStreamBaseSchema.extend({
|
|
38080
|
+
type: exports_external.literal(CliStreamEventType.TOOL_COMPLETED),
|
|
38081
|
+
payload: exports_external.object({
|
|
38082
|
+
tool: exports_external.string(),
|
|
38083
|
+
toolId: exports_external.string().optional(),
|
|
38084
|
+
success: exports_external.boolean(),
|
|
38085
|
+
duration: exports_external.number().optional(),
|
|
38086
|
+
error: exports_external.string().optional()
|
|
38087
|
+
})
|
|
38088
|
+
});
|
|
38089
|
+
CliStatusEventSchema = CliStreamBaseSchema.extend({
|
|
38090
|
+
type: exports_external.literal(CliStreamEventType.STATUS),
|
|
38091
|
+
payload: exports_external.object({
|
|
38092
|
+
status: exports_external.string(),
|
|
38093
|
+
message: exports_external.string().optional()
|
|
38094
|
+
})
|
|
38095
|
+
});
|
|
38096
|
+
CliErrorEventSchema = CliStreamBaseSchema.extend({
|
|
38097
|
+
type: exports_external.literal(CliStreamEventType.ERROR),
|
|
38098
|
+
payload: exports_external.object({
|
|
38099
|
+
error: ProtocolErrorSchema
|
|
38100
|
+
})
|
|
38101
|
+
});
|
|
38102
|
+
CliDoneEventSchema = CliStreamBaseSchema.extend({
|
|
38103
|
+
type: exports_external.literal(CliStreamEventType.DONE),
|
|
38104
|
+
payload: exports_external.object({
|
|
38105
|
+
exitCode: exports_external.number().int(),
|
|
38106
|
+
duration: exports_external.number(),
|
|
38107
|
+
toolsUsed: exports_external.array(exports_external.string()).optional(),
|
|
38108
|
+
tokensUsed: exports_external.number().optional(),
|
|
38109
|
+
success: exports_external.boolean()
|
|
38110
|
+
})
|
|
38111
|
+
});
|
|
38112
|
+
CliStreamEventSchema = exports_external.discriminatedUnion("type", [
|
|
38113
|
+
CliStartEventSchema,
|
|
38114
|
+
CliTextDeltaEventSchema,
|
|
38115
|
+
CliThinkingEventSchema,
|
|
38116
|
+
CliToolStartedEventSchema,
|
|
38117
|
+
CliToolCompletedEventSchema,
|
|
38118
|
+
CliStatusEventSchema,
|
|
38119
|
+
CliErrorEventSchema,
|
|
38120
|
+
CliDoneEventSchema
|
|
38121
|
+
]);
|
|
38122
|
+
});
|
|
38123
|
+
|
|
38124
|
+
// ../shared/src/protocol/context.ts
|
|
38125
|
+
var ActiveFileContextSchema, SelectionContextSchema, WorkspaceContextSchema, ContextPayloadSchema;
|
|
38126
|
+
var init_context = __esm(() => {
|
|
38127
|
+
init_zod();
|
|
38128
|
+
ActiveFileContextSchema = exports_external.object({
|
|
38129
|
+
filePath: exports_external.string(),
|
|
38130
|
+
languageId: exports_external.string().optional()
|
|
38131
|
+
});
|
|
38132
|
+
SelectionContextSchema = exports_external.object({
|
|
38133
|
+
filePath: exports_external.string(),
|
|
38134
|
+
languageId: exports_external.string().optional(),
|
|
38135
|
+
startLine: exports_external.number().int().min(0),
|
|
38136
|
+
startColumn: exports_external.number().int().min(0),
|
|
38137
|
+
endLine: exports_external.number().int().min(0),
|
|
38138
|
+
endColumn: exports_external.number().int().min(0),
|
|
38139
|
+
text: exports_external.string()
|
|
38140
|
+
});
|
|
38141
|
+
WorkspaceContextSchema = exports_external.object({
|
|
38142
|
+
rootPath: exports_external.string(),
|
|
38143
|
+
name: exports_external.string().optional()
|
|
38144
|
+
});
|
|
38145
|
+
ContextPayloadSchema = exports_external.object({
|
|
38146
|
+
workspace: WorkspaceContextSchema.optional(),
|
|
38147
|
+
activeFile: ActiveFileContextSchema.optional(),
|
|
38148
|
+
selection: SelectionContextSchema.optional()
|
|
38149
|
+
});
|
|
38150
|
+
});
|
|
38151
|
+
|
|
38152
|
+
// ../shared/src/protocol/session.ts
|
|
38153
|
+
var SessionStatus, SessionStatusSchema, SessionTransitionEvent, SessionTransitionEventSchema, SESSION_TRANSITIONS, TERMINAL_STATUSES, SessionMetadataSchema, SessionSummarySchema;
|
|
38154
|
+
var init_session = __esm(() => {
|
|
38155
|
+
init_zod();
|
|
38156
|
+
SessionStatus = {
|
|
38157
|
+
IDLE: "idle",
|
|
38158
|
+
STARTING: "starting",
|
|
38159
|
+
RUNNING: "running",
|
|
38160
|
+
STREAMING: "streaming",
|
|
38161
|
+
COMPLETED: "completed",
|
|
38162
|
+
CANCELED: "canceled",
|
|
38163
|
+
INTERRUPTED: "interrupted",
|
|
38164
|
+
FAILED: "failed",
|
|
38165
|
+
RESUMING: "resuming"
|
|
38166
|
+
};
|
|
38167
|
+
SessionStatusSchema = exports_external.enum(SessionStatus);
|
|
38168
|
+
SessionTransitionEvent = {
|
|
38169
|
+
CREATE_SESSION: "create_session",
|
|
38170
|
+
CLI_SPAWNED: "cli_spawned",
|
|
38171
|
+
FIRST_TEXT_DELTA: "first_text_delta",
|
|
38172
|
+
RESULT_RECEIVED: "result_received",
|
|
38173
|
+
USER_STOP: "user_stop",
|
|
38174
|
+
PROCESS_LOST: "process_lost",
|
|
38175
|
+
RESUME: "resume",
|
|
38176
|
+
ERROR: "error"
|
|
38177
|
+
};
|
|
38178
|
+
SessionTransitionEventSchema = exports_external.enum(SessionTransitionEvent);
|
|
38179
|
+
SESSION_TRANSITIONS = [
|
|
38180
|
+
{
|
|
38181
|
+
from: SessionStatus.IDLE,
|
|
38182
|
+
event: SessionTransitionEvent.CREATE_SESSION,
|
|
38183
|
+
to: SessionStatus.STARTING
|
|
38184
|
+
},
|
|
38185
|
+
{
|
|
38186
|
+
from: SessionStatus.STARTING,
|
|
38187
|
+
event: SessionTransitionEvent.CLI_SPAWNED,
|
|
38188
|
+
to: SessionStatus.RUNNING
|
|
38189
|
+
},
|
|
38190
|
+
{
|
|
38191
|
+
from: SessionStatus.STARTING,
|
|
38192
|
+
event: SessionTransitionEvent.ERROR,
|
|
38193
|
+
to: SessionStatus.FAILED
|
|
38194
|
+
},
|
|
38195
|
+
{
|
|
38196
|
+
from: SessionStatus.RUNNING,
|
|
38197
|
+
event: SessionTransitionEvent.FIRST_TEXT_DELTA,
|
|
38198
|
+
to: SessionStatus.STREAMING
|
|
38199
|
+
},
|
|
38200
|
+
{
|
|
38201
|
+
from: SessionStatus.RUNNING,
|
|
38202
|
+
event: SessionTransitionEvent.USER_STOP,
|
|
38203
|
+
to: SessionStatus.CANCELED
|
|
38204
|
+
},
|
|
38205
|
+
{
|
|
38206
|
+
from: SessionStatus.RUNNING,
|
|
38207
|
+
event: SessionTransitionEvent.PROCESS_LOST,
|
|
38208
|
+
to: SessionStatus.INTERRUPTED
|
|
38209
|
+
},
|
|
38210
|
+
{
|
|
38211
|
+
from: SessionStatus.RUNNING,
|
|
38212
|
+
event: SessionTransitionEvent.ERROR,
|
|
38213
|
+
to: SessionStatus.FAILED
|
|
38214
|
+
},
|
|
38215
|
+
{
|
|
38216
|
+
from: SessionStatus.STREAMING,
|
|
38217
|
+
event: SessionTransitionEvent.RESULT_RECEIVED,
|
|
38218
|
+
to: SessionStatus.COMPLETED
|
|
38219
|
+
},
|
|
38220
|
+
{
|
|
38221
|
+
from: SessionStatus.STREAMING,
|
|
38222
|
+
event: SessionTransitionEvent.USER_STOP,
|
|
38223
|
+
to: SessionStatus.CANCELED
|
|
38224
|
+
},
|
|
38225
|
+
{
|
|
38226
|
+
from: SessionStatus.STREAMING,
|
|
38227
|
+
event: SessionTransitionEvent.PROCESS_LOST,
|
|
38228
|
+
to: SessionStatus.INTERRUPTED
|
|
38229
|
+
},
|
|
38230
|
+
{
|
|
38231
|
+
from: SessionStatus.STREAMING,
|
|
38232
|
+
event: SessionTransitionEvent.ERROR,
|
|
38233
|
+
to: SessionStatus.FAILED
|
|
38234
|
+
},
|
|
38235
|
+
{
|
|
38236
|
+
from: SessionStatus.INTERRUPTED,
|
|
38237
|
+
event: SessionTransitionEvent.RESUME,
|
|
38238
|
+
to: SessionStatus.RESUMING
|
|
38239
|
+
},
|
|
38240
|
+
{
|
|
38241
|
+
from: SessionStatus.RESUMING,
|
|
38242
|
+
event: SessionTransitionEvent.CLI_SPAWNED,
|
|
38243
|
+
to: SessionStatus.RUNNING
|
|
38244
|
+
},
|
|
38245
|
+
{
|
|
38246
|
+
from: SessionStatus.RESUMING,
|
|
38247
|
+
event: SessionTransitionEvent.ERROR,
|
|
38248
|
+
to: SessionStatus.FAILED
|
|
38249
|
+
},
|
|
38250
|
+
{
|
|
38251
|
+
from: SessionStatus.COMPLETED,
|
|
38252
|
+
event: SessionTransitionEvent.CREATE_SESSION,
|
|
38253
|
+
to: SessionStatus.STARTING
|
|
38254
|
+
},
|
|
38255
|
+
{
|
|
38256
|
+
from: SessionStatus.CANCELED,
|
|
38257
|
+
event: SessionTransitionEvent.CREATE_SESSION,
|
|
38258
|
+
to: SessionStatus.STARTING
|
|
38259
|
+
},
|
|
38260
|
+
{
|
|
38261
|
+
from: SessionStatus.FAILED,
|
|
38262
|
+
event: SessionTransitionEvent.CREATE_SESSION,
|
|
38263
|
+
to: SessionStatus.STARTING
|
|
38264
|
+
}
|
|
38265
|
+
];
|
|
38266
|
+
TERMINAL_STATUSES = new Set([
|
|
38267
|
+
SessionStatus.COMPLETED,
|
|
38268
|
+
SessionStatus.CANCELED,
|
|
38269
|
+
SessionStatus.FAILED
|
|
38270
|
+
]);
|
|
38271
|
+
SessionMetadataSchema = exports_external.object({
|
|
38272
|
+
sessionId: exports_external.string(),
|
|
38273
|
+
status: SessionStatusSchema,
|
|
38274
|
+
model: exports_external.string().optional(),
|
|
38275
|
+
createdAt: exports_external.number(),
|
|
38276
|
+
updatedAt: exports_external.number(),
|
|
38277
|
+
title: exports_external.string().optional()
|
|
38278
|
+
});
|
|
38279
|
+
SessionSummarySchema = exports_external.object({
|
|
38280
|
+
sessionId: exports_external.string(),
|
|
38281
|
+
status: SessionStatusSchema,
|
|
38282
|
+
model: exports_external.string().optional(),
|
|
38283
|
+
title: exports_external.string().optional(),
|
|
38284
|
+
createdAt: exports_external.number(),
|
|
38285
|
+
updatedAt: exports_external.number(),
|
|
38286
|
+
messageCount: exports_external.number(),
|
|
38287
|
+
toolCount: exports_external.number()
|
|
38288
|
+
});
|
|
38289
|
+
});
|
|
38290
|
+
|
|
38291
|
+
// ../shared/src/protocol/host-events.ts
|
|
38292
|
+
var HostEventType, HostEventTypeSchema, TimelineEntryKind, TimelineEntryKindSchema, TimelineEntrySchema, SessionStateEventSchema, TextDeltaEventSchema, ToolStartedEventSchema, ToolCompletedEventSchema, ThinkingEventSchema, ErrorEventSchema, SessionListEventSchema, SessionCompletedEventSchema, HostEventSchema;
|
|
38293
|
+
var init_host_events = __esm(() => {
|
|
38294
|
+
init_zod();
|
|
38295
|
+
init_envelope();
|
|
38296
|
+
init_errors3();
|
|
38297
|
+
init_session();
|
|
38298
|
+
HostEventType = {
|
|
38299
|
+
SESSION_STATE: "session_state",
|
|
38300
|
+
TEXT_DELTA: "text_delta",
|
|
38301
|
+
TOOL_STARTED: "tool_started",
|
|
38302
|
+
TOOL_COMPLETED: "tool_completed",
|
|
38303
|
+
THINKING: "thinking",
|
|
38304
|
+
ERROR: "error",
|
|
38305
|
+
SESSION_LIST: "session_list",
|
|
38306
|
+
SESSION_COMPLETED: "session_completed"
|
|
38307
|
+
};
|
|
38308
|
+
HostEventTypeSchema = exports_external.enum(HostEventType);
|
|
38309
|
+
TimelineEntryKind = {
|
|
38310
|
+
MESSAGE: "message",
|
|
38311
|
+
TOOL_CALL: "tool_call",
|
|
38312
|
+
STATUS: "status",
|
|
38313
|
+
ERROR: "error",
|
|
38314
|
+
DONE: "done"
|
|
38315
|
+
};
|
|
38316
|
+
TimelineEntryKindSchema = exports_external.enum(TimelineEntryKind);
|
|
38317
|
+
TimelineEntrySchema = exports_external.object({
|
|
38318
|
+
id: exports_external.string(),
|
|
38319
|
+
kind: TimelineEntryKindSchema,
|
|
38320
|
+
timestamp: exports_external.number(),
|
|
38321
|
+
data: exports_external.record(exports_external.string(), exports_external.unknown())
|
|
38322
|
+
});
|
|
38323
|
+
SessionStateEventSchema = exports_external.object({
|
|
38324
|
+
protocol: ProtocolVersionSchema,
|
|
38325
|
+
type: exports_external.literal(HostEventType.SESSION_STATE),
|
|
38326
|
+
payload: exports_external.object({
|
|
38327
|
+
sessionId: exports_external.string(),
|
|
38328
|
+
status: SessionStatusSchema,
|
|
38329
|
+
metadata: SessionMetadataSchema.optional(),
|
|
38330
|
+
timeline: exports_external.array(TimelineEntrySchema).optional()
|
|
38331
|
+
})
|
|
38332
|
+
});
|
|
38333
|
+
TextDeltaEventSchema = exports_external.object({
|
|
38334
|
+
protocol: ProtocolVersionSchema,
|
|
38335
|
+
type: exports_external.literal(HostEventType.TEXT_DELTA),
|
|
38336
|
+
payload: exports_external.object({
|
|
38337
|
+
sessionId: exports_external.string(),
|
|
38338
|
+
content: exports_external.string()
|
|
38339
|
+
})
|
|
38340
|
+
});
|
|
38341
|
+
ToolStartedEventSchema = exports_external.object({
|
|
38342
|
+
protocol: ProtocolVersionSchema,
|
|
38343
|
+
type: exports_external.literal(HostEventType.TOOL_STARTED),
|
|
38344
|
+
payload: exports_external.object({
|
|
38345
|
+
sessionId: exports_external.string(),
|
|
38346
|
+
tool: exports_external.string(),
|
|
38347
|
+
toolId: exports_external.string().optional(),
|
|
38348
|
+
parameters: exports_external.record(exports_external.string(), exports_external.unknown()).optional()
|
|
38349
|
+
})
|
|
38350
|
+
});
|
|
38351
|
+
ToolCompletedEventSchema = exports_external.object({
|
|
38352
|
+
protocol: ProtocolVersionSchema,
|
|
38353
|
+
type: exports_external.literal(HostEventType.TOOL_COMPLETED),
|
|
38354
|
+
payload: exports_external.object({
|
|
38355
|
+
sessionId: exports_external.string(),
|
|
38356
|
+
tool: exports_external.string(),
|
|
38357
|
+
toolId: exports_external.string().optional(),
|
|
38358
|
+
result: exports_external.unknown().optional(),
|
|
38359
|
+
duration: exports_external.number().optional(),
|
|
38360
|
+
success: exports_external.boolean(),
|
|
38361
|
+
error: exports_external.string().optional()
|
|
38362
|
+
})
|
|
38363
|
+
});
|
|
38364
|
+
ThinkingEventSchema = exports_external.object({
|
|
38365
|
+
protocol: ProtocolVersionSchema,
|
|
38366
|
+
type: exports_external.literal(HostEventType.THINKING),
|
|
38367
|
+
payload: exports_external.object({
|
|
38368
|
+
sessionId: exports_external.string(),
|
|
38369
|
+
content: exports_external.string().optional()
|
|
38370
|
+
})
|
|
38371
|
+
});
|
|
38372
|
+
ErrorEventSchema = exports_external.object({
|
|
38373
|
+
protocol: ProtocolVersionSchema,
|
|
38374
|
+
type: exports_external.literal(HostEventType.ERROR),
|
|
38375
|
+
payload: exports_external.object({
|
|
38376
|
+
sessionId: exports_external.string().optional(),
|
|
38377
|
+
error: ProtocolErrorSchema
|
|
38378
|
+
})
|
|
38379
|
+
});
|
|
38380
|
+
SessionListEventSchema = exports_external.object({
|
|
38381
|
+
protocol: ProtocolVersionSchema,
|
|
38382
|
+
type: exports_external.literal(HostEventType.SESSION_LIST),
|
|
38383
|
+
payload: exports_external.object({
|
|
38384
|
+
sessions: exports_external.array(SessionSummarySchema)
|
|
38385
|
+
})
|
|
38386
|
+
});
|
|
38387
|
+
SessionCompletedEventSchema = exports_external.object({
|
|
38388
|
+
protocol: ProtocolVersionSchema,
|
|
38389
|
+
type: exports_external.literal(HostEventType.SESSION_COMPLETED),
|
|
38390
|
+
payload: exports_external.object({
|
|
38391
|
+
sessionId: exports_external.string(),
|
|
38392
|
+
summary: exports_external.string().optional()
|
|
38393
|
+
})
|
|
38394
|
+
});
|
|
38395
|
+
HostEventSchema = exports_external.discriminatedUnion("type", [
|
|
38396
|
+
SessionStateEventSchema,
|
|
38397
|
+
TextDeltaEventSchema,
|
|
38398
|
+
ToolStartedEventSchema,
|
|
38399
|
+
ToolCompletedEventSchema,
|
|
38400
|
+
ThinkingEventSchema,
|
|
38401
|
+
ErrorEventSchema,
|
|
38402
|
+
SessionListEventSchema,
|
|
38403
|
+
SessionCompletedEventSchema
|
|
38404
|
+
]);
|
|
38405
|
+
});
|
|
38406
|
+
|
|
38407
|
+
// ../shared/src/protocol/ui-intents.ts
|
|
38408
|
+
var UIIntentType, UIIntentTypeSchema, SubmitPromptIntentSchema, StopSessionIntentSchema, ResumeSessionIntentSchema, RequestSessionsIntentSchema, RequestSessionDetailIntentSchema, ClearSessionIntentSchema, WebviewReadyIntentSchema, UIIntentSchema;
|
|
38409
|
+
var init_ui_intents = __esm(() => {
|
|
38410
|
+
init_zod();
|
|
38411
|
+
init_context();
|
|
38412
|
+
init_envelope();
|
|
38413
|
+
UIIntentType = {
|
|
38414
|
+
SUBMIT_PROMPT: "submit_prompt",
|
|
38415
|
+
STOP_SESSION: "stop_session",
|
|
38416
|
+
RESUME_SESSION: "resume_session",
|
|
38417
|
+
REQUEST_SESSIONS: "request_sessions",
|
|
38418
|
+
REQUEST_SESSION_DETAIL: "request_session_detail",
|
|
38419
|
+
CLEAR_SESSION: "clear_session",
|
|
38420
|
+
WEBVIEW_READY: "webview_ready"
|
|
38421
|
+
};
|
|
38422
|
+
UIIntentTypeSchema = exports_external.enum(UIIntentType);
|
|
38423
|
+
SubmitPromptIntentSchema = exports_external.object({
|
|
38424
|
+
protocol: ProtocolVersionSchema,
|
|
38425
|
+
type: exports_external.literal(UIIntentType.SUBMIT_PROMPT),
|
|
38426
|
+
payload: exports_external.object({
|
|
38427
|
+
text: exports_external.string().min(1),
|
|
38428
|
+
context: ContextPayloadSchema.optional()
|
|
38429
|
+
})
|
|
38430
|
+
});
|
|
38431
|
+
StopSessionIntentSchema = exports_external.object({
|
|
38432
|
+
protocol: ProtocolVersionSchema,
|
|
38433
|
+
type: exports_external.literal(UIIntentType.STOP_SESSION),
|
|
38434
|
+
payload: exports_external.object({
|
|
38435
|
+
sessionId: exports_external.string()
|
|
38436
|
+
})
|
|
38437
|
+
});
|
|
38438
|
+
ResumeSessionIntentSchema = exports_external.object({
|
|
38439
|
+
protocol: ProtocolVersionSchema,
|
|
38440
|
+
type: exports_external.literal(UIIntentType.RESUME_SESSION),
|
|
38441
|
+
payload: exports_external.object({
|
|
38442
|
+
sessionId: exports_external.string()
|
|
38443
|
+
})
|
|
38444
|
+
});
|
|
38445
|
+
RequestSessionsIntentSchema = exports_external.object({
|
|
38446
|
+
protocol: ProtocolVersionSchema,
|
|
38447
|
+
type: exports_external.literal(UIIntentType.REQUEST_SESSIONS),
|
|
38448
|
+
payload: exports_external.object({}).optional()
|
|
38449
|
+
});
|
|
38450
|
+
RequestSessionDetailIntentSchema = exports_external.object({
|
|
38451
|
+
protocol: ProtocolVersionSchema,
|
|
38452
|
+
type: exports_external.literal(UIIntentType.REQUEST_SESSION_DETAIL),
|
|
38453
|
+
payload: exports_external.object({
|
|
38454
|
+
sessionId: exports_external.string()
|
|
38455
|
+
})
|
|
38456
|
+
});
|
|
38457
|
+
ClearSessionIntentSchema = exports_external.object({
|
|
38458
|
+
protocol: ProtocolVersionSchema,
|
|
38459
|
+
type: exports_external.literal(UIIntentType.CLEAR_SESSION),
|
|
38460
|
+
payload: exports_external.object({
|
|
38461
|
+
sessionId: exports_external.string()
|
|
38462
|
+
})
|
|
38463
|
+
});
|
|
38464
|
+
WebviewReadyIntentSchema = exports_external.object({
|
|
38465
|
+
protocol: ProtocolVersionSchema,
|
|
38466
|
+
type: exports_external.literal(UIIntentType.WEBVIEW_READY),
|
|
38467
|
+
payload: exports_external.object({}).optional()
|
|
38468
|
+
});
|
|
38469
|
+
UIIntentSchema = exports_external.discriminatedUnion("type", [
|
|
38470
|
+
SubmitPromptIntentSchema,
|
|
38471
|
+
StopSessionIntentSchema,
|
|
38472
|
+
ResumeSessionIntentSchema,
|
|
38473
|
+
RequestSessionsIntentSchema,
|
|
38474
|
+
RequestSessionDetailIntentSchema,
|
|
38475
|
+
ClearSessionIntentSchema,
|
|
38476
|
+
WebviewReadyIntentSchema
|
|
38477
|
+
]);
|
|
38478
|
+
});
|
|
38479
|
+
|
|
38480
|
+
// ../shared/src/protocol/helpers.ts
|
|
38481
|
+
function createProtocolError(code, message, options) {
|
|
38482
|
+
return {
|
|
38483
|
+
code,
|
|
38484
|
+
message,
|
|
38485
|
+
details: options?.details,
|
|
38486
|
+
recoverable: options?.recoverable ?? false
|
|
38487
|
+
};
|
|
38488
|
+
}
|
|
38489
|
+
var init_helpers = __esm(() => {
|
|
38490
|
+
init_envelope();
|
|
38491
|
+
init_host_events();
|
|
38492
|
+
init_session();
|
|
38493
|
+
init_ui_intents();
|
|
38494
|
+
});
|
|
38495
|
+
|
|
38496
|
+
// ../shared/src/protocol/index.ts
|
|
38497
|
+
var init_protocol = __esm(() => {
|
|
38498
|
+
init_cli_stream();
|
|
38499
|
+
init_context();
|
|
38500
|
+
init_envelope();
|
|
38501
|
+
init_errors3();
|
|
38502
|
+
init_helpers();
|
|
38503
|
+
init_host_events();
|
|
38504
|
+
init_session();
|
|
38505
|
+
init_ui_intents();
|
|
38506
|
+
});
|
|
38507
|
+
|
|
37980
38508
|
// ../shared/src/index.ts
|
|
37981
38509
|
var init_src = __esm(() => {
|
|
37982
38510
|
init_common();
|
|
37983
38511
|
init_constants();
|
|
37984
38512
|
init_enums();
|
|
37985
38513
|
init_models();
|
|
38514
|
+
init_protocol();
|
|
37986
38515
|
});
|
|
37987
38516
|
|
|
37988
38517
|
// ../sdk/src/modules/tasks.ts
|
|
@@ -38268,11 +38797,11 @@ ${line}`;
|
|
|
38268
38797
|
writeFileSync3(this.progressPath, updated);
|
|
38269
38798
|
}
|
|
38270
38799
|
getFullContext() {
|
|
38271
|
-
const
|
|
38800
|
+
const context2 = this.readContext();
|
|
38272
38801
|
const progress = this.readProgress();
|
|
38273
38802
|
const parts = [];
|
|
38274
|
-
if (
|
|
38275
|
-
parts.push(
|
|
38803
|
+
if (context2.trim()) {
|
|
38804
|
+
parts.push(context2.trim());
|
|
38276
38805
|
}
|
|
38277
38806
|
if (progress.trim()) {
|
|
38278
38807
|
parts.push(progress.trim());
|
|
@@ -38597,10 +39126,10 @@ ${task2.description || "No description provided."}
|
|
|
38597
39126
|
let hasLocalContext = false;
|
|
38598
39127
|
if (existsSync6(contextPath)) {
|
|
38599
39128
|
try {
|
|
38600
|
-
const
|
|
38601
|
-
if (
|
|
39129
|
+
const context2 = readFileSync6(contextPath, "utf-8");
|
|
39130
|
+
if (context2.trim().length > 20) {
|
|
38602
39131
|
prompt += `## Project Context (Local)
|
|
38603
|
-
${
|
|
39132
|
+
${context2}
|
|
38604
39133
|
|
|
38605
39134
|
`;
|
|
38606
39135
|
hasLocalContext = true;
|
|
@@ -38730,10 +39259,10 @@ ${query}
|
|
|
38730
39259
|
let hasLocalContext = false;
|
|
38731
39260
|
if (existsSync6(contextPath)) {
|
|
38732
39261
|
try {
|
|
38733
|
-
const
|
|
38734
|
-
if (
|
|
39262
|
+
const context2 = readFileSync6(contextPath, "utf-8");
|
|
39263
|
+
if (context2.trim().length > 20) {
|
|
38735
39264
|
prompt += `## Project Context (Local)
|
|
38736
|
-
${
|
|
39265
|
+
${context2}
|
|
38737
39266
|
|
|
38738
39267
|
`;
|
|
38739
39268
|
hasLocalContext = true;
|
|
@@ -38932,7 +39461,8 @@ function parseWorkerArgs(argv) {
|
|
|
38932
39461
|
if (value && !value.startsWith("--"))
|
|
38933
39462
|
i++;
|
|
38934
39463
|
config2.provider = resolveProvider2(value);
|
|
38935
|
-
}
|
|
39464
|
+
} else if (arg === "--reasoning-effort")
|
|
39465
|
+
config2.reasoningEffort = args[++i];
|
|
38936
39466
|
}
|
|
38937
39467
|
if (!config2.agentId || !config2.workspaceId || !config2.apiBase || !config2.apiKey || !config2.projectPath) {
|
|
38938
39468
|
console.error("Missing required arguments");
|
|
@@ -38994,7 +39524,8 @@ class AgentWorker {
|
|
|
38994
39524
|
this.aiRunner = createAiRunner(provider, {
|
|
38995
39525
|
projectPath,
|
|
38996
39526
|
model: config2.model,
|
|
38997
|
-
log
|
|
39527
|
+
log,
|
|
39528
|
+
reasoningEffort: config2.reasoningEffort
|
|
38998
39529
|
});
|
|
38999
39530
|
this.taskExecutor = new TaskExecutor({
|
|
39000
39531
|
aiRunner: this.aiRunner,
|
|
@@ -39689,10 +40220,10 @@ class HistoryManager {
|
|
|
39689
40220
|
getSessionPath(sessionId) {
|
|
39690
40221
|
return join7(this.historyDir, `${sessionId}.json`);
|
|
39691
40222
|
}
|
|
39692
|
-
saveSession(
|
|
39693
|
-
const filePath = this.getSessionPath(
|
|
39694
|
-
|
|
39695
|
-
writeFileSync4(filePath, JSON.stringify(
|
|
40223
|
+
saveSession(session2) {
|
|
40224
|
+
const filePath = this.getSessionPath(session2.id);
|
|
40225
|
+
session2.updatedAt = Date.now();
|
|
40226
|
+
writeFileSync4(filePath, JSON.stringify(session2, null, 2), "utf-8");
|
|
39696
40227
|
}
|
|
39697
40228
|
loadSession(sessionId) {
|
|
39698
40229
|
const filePath = this.getSessionPath(sessionId);
|
|
@@ -39723,9 +40254,9 @@ class HistoryManager {
|
|
|
39723
40254
|
let sessions = [];
|
|
39724
40255
|
for (const file2 of files) {
|
|
39725
40256
|
if (file2.endsWith(".json")) {
|
|
39726
|
-
const
|
|
39727
|
-
if (
|
|
39728
|
-
sessions.push(
|
|
40257
|
+
const session2 = this.loadSession(file2.replace(".json", ""));
|
|
40258
|
+
if (session2) {
|
|
40259
|
+
sessions.push(session2);
|
|
39729
40260
|
}
|
|
39730
40261
|
}
|
|
39731
40262
|
}
|
|
@@ -39747,7 +40278,7 @@ class HistoryManager {
|
|
|
39747
40278
|
}
|
|
39748
40279
|
if (options.query) {
|
|
39749
40280
|
const query = options.query.toLowerCase();
|
|
39750
|
-
filtered = filtered.filter((
|
|
40281
|
+
filtered = filtered.filter((session2) => session2.messages.some((msg) => msg.content.toLowerCase().includes(query)));
|
|
39751
40282
|
}
|
|
39752
40283
|
const offset = options.offset ?? 0;
|
|
39753
40284
|
const limit = options.limit ?? filtered.length;
|
|
@@ -39783,8 +40314,8 @@ class HistoryManager {
|
|
|
39783
40314
|
let deleted = 0;
|
|
39784
40315
|
if (sessions.length > this.maxSessions) {
|
|
39785
40316
|
const sessionsToDelete = sessions.slice(this.maxSessions);
|
|
39786
|
-
for (const
|
|
39787
|
-
if (this.deleteSession(
|
|
40317
|
+
for (const session2 of sessionsToDelete) {
|
|
40318
|
+
if (this.deleteSession(session2.id)) {
|
|
39788
40319
|
deleted++;
|
|
39789
40320
|
}
|
|
39790
40321
|
}
|
|
@@ -40329,6 +40860,9 @@ ${c.primary("\uD83E\uDD16 Locus Agent Orchestrator")}`);
|
|
|
40329
40860
|
if (this.config.provider) {
|
|
40330
40861
|
args.push("--provider", this.config.provider);
|
|
40331
40862
|
}
|
|
40863
|
+
if (this.config.reasoningEffort) {
|
|
40864
|
+
args.push("--reasoning-effort", this.config.reasoningEffort);
|
|
40865
|
+
}
|
|
40332
40866
|
if (this.resolvedSprintId) {
|
|
40333
40867
|
args.push("--sprint-id", this.resolvedSprintId);
|
|
40334
40868
|
}
|
|
@@ -40666,78 +41200,6 @@ var init_plan_manager = __esm(() => {
|
|
|
40666
41200
|
init_sprint_plan();
|
|
40667
41201
|
});
|
|
40668
41202
|
|
|
40669
|
-
// ../sdk/src/planning/agents/architect.ts
|
|
40670
|
-
function buildArchitectPrompt(input) {
|
|
40671
|
-
let prompt = `# Role: Software Architect
|
|
40672
|
-
|
|
40673
|
-
You are a Software Architect participating in an async sprint planning meeting. The Tech Lead has produced an initial task breakdown. Your job is to refine it.
|
|
40674
|
-
|
|
40675
|
-
## CEO Directive
|
|
40676
|
-
> ${input.directive}
|
|
40677
|
-
`;
|
|
40678
|
-
if (input.feedback) {
|
|
40679
|
-
prompt += `
|
|
40680
|
-
## CEO Feedback on Previous Plan
|
|
40681
|
-
> ${input.feedback}
|
|
40682
|
-
|
|
40683
|
-
IMPORTANT: Ensure the refined plan addresses this feedback.
|
|
40684
|
-
`;
|
|
40685
|
-
}
|
|
40686
|
-
prompt += `
|
|
40687
|
-
## Project Context
|
|
40688
|
-
${input.projectContext || "No project context available."}
|
|
40689
|
-
|
|
40690
|
-
## Tech Lead's Task Breakdown
|
|
40691
|
-
${input.techLeadOutput}
|
|
40692
|
-
|
|
40693
|
-
## Your Task
|
|
40694
|
-
|
|
40695
|
-
Review and refine the Tech Lead's breakdown:
|
|
40696
|
-
|
|
40697
|
-
1. **Ordering** — Order tasks so that foundational work comes first. Tasks that produce outputs consumed by later tasks must appear earlier in the list. Foundation tasks (schemas, config, shared code) must be listed before tasks that build on them. The array index IS the execution order.
|
|
40698
|
-
2. **Risk Assessment** — Flag tasks that are risky, underestimated, or have unknowns.
|
|
40699
|
-
3. **Task Merging** — If two tasks are trivially small and related, merge them.
|
|
40700
|
-
4. **Complexity Scoring** — Rate each task 1-5 (1=trivial, 5=very complex).
|
|
40701
|
-
5. **Missing Tasks** — Add any tasks the Tech Lead missed (database migrations, configuration, testing, etc.).
|
|
40702
|
-
6. **Description Quality** — Review and improve each task description to be a clear, actionable implementation guide. Each description must tell the executing agent exactly what to do, where to do it (specific files/modules), how to do it (patterns, utilities, data flow), and what is NOT in scope. Vague descriptions like "Add authentication" must be rewritten with specific file paths, implementation approach, and boundaries.
|
|
40703
|
-
|
|
40704
|
-
## CRITICAL: Task Ordering & Dependencies
|
|
40705
|
-
|
|
40706
|
-
Tasks are executed SEQUENTIALLY by a single agent on ONE branch. The agent works through tasks in array order. Each completed task's changes are available to subsequent tasks. You MUST enforce these rules:
|
|
40707
|
-
|
|
40708
|
-
1. **Order tasks by dependency.** Foundation tasks (schemas, config, shared code) must come first. Tasks that build on earlier work must appear later in the list.
|
|
40709
|
-
2. **Each task must be self-contained for its scope.** A task can depend on earlier tasks (they run sequentially), but must include all changes needed for its own goal.
|
|
40710
|
-
3. **Split tasks at logical boundaries.** Since tasks run sequentially on the same branch, splitting is safe — later tasks see earlier changes. Split when it improves clarity and reviewability.
|
|
40711
|
-
4. **Flag risks.** In your risk assessment, call out tasks that are complex or have unknowns.
|
|
40712
|
-
|
|
40713
|
-
## Output Format
|
|
40714
|
-
|
|
40715
|
-
Your entire response must be a single JSON object — no text before it, no text after it, no markdown code blocks, no explanation. Start your response with the "{" character:
|
|
40716
|
-
|
|
40717
|
-
{
|
|
40718
|
-
"tasks": [
|
|
40719
|
-
{
|
|
40720
|
-
"title": "string",
|
|
40721
|
-
"description": "string (detailed implementation guide: what to do, where to do it, how to do it, and boundaries)",
|
|
40722
|
-
"assigneeRole": "BACKEND | FRONTEND | QA | PM | DESIGN",
|
|
40723
|
-
"priority": "HIGH | MEDIUM | LOW | CRITICAL",
|
|
40724
|
-
"labels": ["string"],
|
|
40725
|
-
"acceptanceCriteria": ["string"],
|
|
40726
|
-
"complexity": 3
|
|
40727
|
-
}
|
|
40728
|
-
],
|
|
40729
|
-
"risks": [
|
|
40730
|
-
{
|
|
40731
|
-
"description": "string",
|
|
40732
|
-
"mitigation": "string",
|
|
40733
|
-
"severity": "low | medium | high"
|
|
40734
|
-
}
|
|
40735
|
-
],
|
|
40736
|
-
"architectureNotes": "string (notes for the Sprint Organizer about parallelism opportunities and constraints)"
|
|
40737
|
-
}`;
|
|
40738
|
-
return prompt;
|
|
40739
|
-
}
|
|
40740
|
-
|
|
40741
41203
|
// ../sdk/src/planning/agents/cross-task-reviewer.ts
|
|
40742
41204
|
function buildCrossTaskReviewerPrompt(input) {
|
|
40743
41205
|
let prompt = `# Role: Cross-Task Reviewer (Architect + Engineer + Planner)
|
|
@@ -40773,7 +41235,7 @@ IMPORTANT: Ensure the reviewed plan still addresses this feedback.
|
|
|
40773
41235
|
${input.projectContext || "No project context available."}
|
|
40774
41236
|
|
|
40775
41237
|
## Sprint Plan to Review
|
|
40776
|
-
${input.
|
|
41238
|
+
${input.plannerOutput}
|
|
40777
41239
|
|
|
40778
41240
|
## Your Review Checklist
|
|
40779
41241
|
|
|
@@ -40852,11 +41314,11 @@ IMPORTANT:
|
|
|
40852
41314
|
return prompt;
|
|
40853
41315
|
}
|
|
40854
41316
|
|
|
40855
|
-
// ../sdk/src/planning/agents/
|
|
40856
|
-
function
|
|
40857
|
-
let prompt = `# Role: Sprint
|
|
41317
|
+
// ../sdk/src/planning/agents/planner.ts
|
|
41318
|
+
function buildPlannerPrompt(input) {
|
|
41319
|
+
let prompt = `# Role: Sprint Planner
|
|
40858
41320
|
|
|
40859
|
-
You are a Sprint
|
|
41321
|
+
You are a Sprint Planner — an expert engineer, architect, and project organizer rolled into one. Your job is to take a CEO directive and produce a complete, ready-to-execute sprint plan in a single pass.
|
|
40860
41322
|
|
|
40861
41323
|
## CEO Directive
|
|
40862
41324
|
> ${input.directive}
|
|
@@ -40866,40 +41328,64 @@ You are a Sprint Organizer finalizing the sprint plan from a planning meeting. T
|
|
|
40866
41328
|
## CEO Feedback on Previous Plan
|
|
40867
41329
|
> ${input.feedback}
|
|
40868
41330
|
|
|
40869
|
-
IMPORTANT: The
|
|
41331
|
+
IMPORTANT: Incorporate this feedback into your plan. The CEO has reviewed a previous plan and wants changes.
|
|
40870
41332
|
`;
|
|
40871
41333
|
}
|
|
40872
41334
|
prompt += `
|
|
40873
|
-
##
|
|
40874
|
-
${input.
|
|
41335
|
+
## Project Context
|
|
41336
|
+
${input.projectContext || "No project context available."}
|
|
41337
|
+
|
|
41338
|
+
## Codebase Structure
|
|
41339
|
+
${input.codebaseIndex || "No codebase index available."}
|
|
40875
41340
|
|
|
40876
41341
|
## Your Task
|
|
40877
41342
|
|
|
40878
|
-
|
|
41343
|
+
Analyze the directive and produce a **complete sprint plan** with the following:
|
|
40879
41344
|
|
|
40880
|
-
1. **Sprint Name** — A concise, memorable name
|
|
41345
|
+
1. **Sprint Name** — A concise, memorable name (2-4 words)
|
|
40881
41346
|
2. **Sprint Goal** — One paragraph describing what this sprint delivers
|
|
40882
|
-
3. **
|
|
40883
|
-
4. **
|
|
40884
|
-
5. **
|
|
40885
|
-
|
|
40886
|
-
|
|
40887
|
-
|
|
40888
|
-
|
|
40889
|
-
-
|
|
40890
|
-
-
|
|
40891
|
-
-
|
|
40892
|
-
-
|
|
40893
|
-
-
|
|
41347
|
+
3. **Duration Estimate** — How many days this sprint will take with a single agent working sequentially
|
|
41348
|
+
4. **Task Breakdown** — An ordered list of tasks that fully implement the directive
|
|
41349
|
+
5. **Risk Assessment** — Potential risks with mitigations
|
|
41350
|
+
|
|
41351
|
+
### Task Requirements
|
|
41352
|
+
|
|
41353
|
+
For each task, provide:
|
|
41354
|
+
- **Title** — Clear, action-oriented (e.g., "Implement user registration API endpoint")
|
|
41355
|
+
- **Description** — A detailed, actionable implementation guide (see below)
|
|
41356
|
+
- **Assignee Role** — BACKEND, FRONTEND, QA, PM, or DESIGN
|
|
41357
|
+
- **Priority** — CRITICAL, HIGH, MEDIUM, or LOW
|
|
41358
|
+
- **Complexity** — 1 (trivial) to 5 (very complex)
|
|
41359
|
+
- **Labels** — Relevant tags (e.g., "api", "database", "ui", "auth")
|
|
41360
|
+
- **Acceptance Criteria** — Specific, testable conditions for completion
|
|
40894
41361
|
|
|
40895
|
-
|
|
41362
|
+
### CRITICAL: Task Description Requirements
|
|
40896
41363
|
|
|
40897
|
-
|
|
41364
|
+
Each task description will be handed to an INDEPENDENT agent as its primary instruction. The agent will have access to the codebase but NO context about the planning meeting. Each description MUST include:
|
|
40898
41365
|
|
|
40899
|
-
1. **
|
|
40900
|
-
2. **
|
|
40901
|
-
3. **
|
|
40902
|
-
4. **
|
|
41366
|
+
1. **What to do** — Clearly state the goal and expected behavior/outcome
|
|
41367
|
+
2. **Where to do it** — List specific files, modules, or directories to modify or create. Reference existing code paths when extending functionality
|
|
41368
|
+
3. **How to do it** — Key implementation details: which patterns to follow, which existing utilities or services to use, what the data flow looks like
|
|
41369
|
+
4. **Boundaries** — What is NOT in scope for this task to prevent overlap with other tasks
|
|
41370
|
+
|
|
41371
|
+
Bad example: "Add authentication to the API."
|
|
41372
|
+
Good example: "Implement JWT-based authentication middleware in src/middleware/auth.ts. Create a verifyToken middleware that extracts the Bearer token from the Authorization header, validates it using the existing JWT_SECRET from env config, and attaches the decoded user payload to req.user. Apply this middleware to all routes in src/routes/protected/. This task does NOT include user registration or password reset — those are handled separately."
|
|
41373
|
+
|
|
41374
|
+
### CRITICAL: Task Ordering Rules
|
|
41375
|
+
|
|
41376
|
+
Tasks are executed SEQUENTIALLY by a single agent on ONE branch. The agent works through tasks in array order. Therefore:
|
|
41377
|
+
|
|
41378
|
+
1. **Foundation first.** Place foundational tasks (schemas, config, shared code) at the beginning. Later tasks can build on earlier ones since they run in sequence.
|
|
41379
|
+
2. **No forward dependencies.** A task must NOT depend on a task that appears later in the list.
|
|
41380
|
+
3. **Each task is self-contained for its scope.** A task can depend on earlier tasks but must include all changes needed for its own goal.
|
|
41381
|
+
4. **Keep tasks focused.** Each task should do one logical unit of work. Avoid trivially small or overly large tasks.
|
|
41382
|
+
5. **Merge related trivial work.** If two pieces of work are trivially small and tightly related, combine them into one task.
|
|
41383
|
+
|
|
41384
|
+
### Sprint Scope Guidelines
|
|
41385
|
+
|
|
41386
|
+
- If the sprint would exceed 12 tasks, reduce scope or merge related tasks
|
|
41387
|
+
- Ensure acceptance criteria are specific and testable
|
|
41388
|
+
- Keep the sprint focused on the directive — avoid scope creep
|
|
40903
41389
|
|
|
40904
41390
|
## Output Format
|
|
40905
41391
|
|
|
@@ -40912,7 +41398,7 @@ Your entire response must be a single JSON object — no text before it, no text
|
|
|
40912
41398
|
"tasks": [
|
|
40913
41399
|
{
|
|
40914
41400
|
"title": "string",
|
|
40915
|
-
"description": "string (detailed implementation guide: what
|
|
41401
|
+
"description": "string (detailed implementation guide: what, where, how, boundaries)",
|
|
40916
41402
|
"assigneeRole": "BACKEND | FRONTEND | QA | PM | DESIGN",
|
|
40917
41403
|
"priority": "CRITICAL | HIGH | MEDIUM | LOW",
|
|
40918
41404
|
"labels": ["string"],
|
|
@@ -40933,89 +41419,6 @@ IMPORTANT: Tasks are executed sequentially by a single agent. The array order IS
|
|
|
40933
41419
|
return prompt;
|
|
40934
41420
|
}
|
|
40935
41421
|
|
|
40936
|
-
// ../sdk/src/planning/agents/tech-lead.ts
|
|
40937
|
-
function buildTechLeadPrompt(input) {
|
|
40938
|
-
let prompt = `# Role: Senior Tech Lead
|
|
40939
|
-
|
|
40940
|
-
You are a Senior Tech Lead participating in an async sprint planning meeting. Your job is to take the CEO's directive and produce an initial task breakdown.
|
|
40941
|
-
|
|
40942
|
-
## CEO Directive
|
|
40943
|
-
> ${input.directive}
|
|
40944
|
-
`;
|
|
40945
|
-
if (input.feedback) {
|
|
40946
|
-
prompt += `
|
|
40947
|
-
## CEO Feedback on Previous Plan
|
|
40948
|
-
> ${input.feedback}
|
|
40949
|
-
|
|
40950
|
-
IMPORTANT: Incorporate this feedback into your task breakdown. The CEO has reviewed a previous plan and wants changes.
|
|
40951
|
-
`;
|
|
40952
|
-
}
|
|
40953
|
-
prompt += `
|
|
40954
|
-
## Project Context
|
|
40955
|
-
${input.projectContext || "No project context available."}
|
|
40956
|
-
|
|
40957
|
-
## Codebase Structure
|
|
40958
|
-
${input.codebaseIndex || "No codebase index available."}
|
|
40959
|
-
|
|
40960
|
-
## Your Task
|
|
40961
|
-
|
|
40962
|
-
Analyze the CEO's directive and produce a detailed task breakdown. For each task:
|
|
40963
|
-
|
|
40964
|
-
1. **Title** — Clear, action-oriented (e.g., "Implement user registration API endpoint")
|
|
40965
|
-
2. **Description** — A detailed, actionable implementation guide (see description requirements below)
|
|
40966
|
-
3. **Assignee Role** — Who should work on this: BACKEND, FRONTEND, QA, PM, or DESIGN
|
|
40967
|
-
4. **Priority** — HIGH, MEDIUM, or LOW based on business impact
|
|
40968
|
-
5. **Labels** — Relevant tags (e.g., "api", "database", "ui", "auth")
|
|
40969
|
-
6. **Acceptance Criteria** — Specific, testable conditions for completion
|
|
40970
|
-
|
|
40971
|
-
Think about:
|
|
40972
|
-
- What existing code can be reused or extended
|
|
40973
|
-
- Which tasks are independent vs. dependent
|
|
40974
|
-
- What the right granularity is (not too big, not too small)
|
|
40975
|
-
- What risks or unknowns exist
|
|
40976
|
-
|
|
40977
|
-
## CRITICAL: Task Description Requirements
|
|
40978
|
-
|
|
40979
|
-
Each task description will be handed to an INDEPENDENT agent as its primary instruction. The agent will have access to the codebase but NO context about the planning meeting. Descriptions must be clear enough for the agent to execute the task without ambiguity.
|
|
40980
|
-
|
|
40981
|
-
Each description MUST include:
|
|
40982
|
-
1. **What to do** — Clearly state the goal and what needs to be implemented, changed, or created. Be specific about the expected behavior or outcome.
|
|
40983
|
-
2. **Where to do it** — List the specific files, modules, or directories that need to be modified or created. Reference existing code paths when extending functionality.
|
|
40984
|
-
3. **How to do it** — Provide key implementation details: which patterns to follow, which existing utilities or services to use, what the data flow looks like.
|
|
40985
|
-
4. **Boundaries** — Clarify what is NOT in scope for this task to prevent overlap with other tasks.
|
|
40986
|
-
|
|
40987
|
-
Bad example: "Add authentication to the API."
|
|
40988
|
-
Good example: "Implement JWT-based authentication middleware in src/middleware/auth.ts. Create a verifyToken middleware that extracts the Bearer token from the Authorization header, validates it using the existing JWT_SECRET from env config, and attaches the decoded user payload to req.user. Apply this middleware to all routes in src/routes/protected/. Add a POST /auth/login endpoint in src/routes/auth.ts that accepts {email, password}, validates credentials against the users table, and returns a signed JWT. This task does NOT include user registration or password reset — those are handled separately."
|
|
40989
|
-
|
|
40990
|
-
## CRITICAL: Task Ordering Rules
|
|
40991
|
-
|
|
40992
|
-
Tasks are executed SEQUENTIALLY by a single agent on ONE branch. The agent works through tasks in the order they appear in the array. Therefore:
|
|
40993
|
-
|
|
40994
|
-
1. **Foundation first.** Place foundational tasks (schemas, config, shared code) at the beginning of the list. Later tasks can build on earlier ones since they run in sequence on the same branch.
|
|
40995
|
-
2. **Each task must be self-contained.** A task must include ALL the code changes it needs to work — from config to implementation to tests. A task CAN depend on earlier tasks in the list since they will have already been completed.
|
|
40996
|
-
3. **Logical ordering matters.** Tasks are dispatched in the order they appear. Ensure dependent tasks come after their prerequisites.
|
|
40997
|
-
4. **Keep tasks focused.** Each task should do one logical unit of work. Since there are no parallel execution conflicts, tasks can be more granular — but avoid tasks that are too small or trivial.
|
|
40998
|
-
|
|
40999
|
-
## Output Format
|
|
41000
|
-
|
|
41001
|
-
Your entire response must be a single JSON object — no text before it, no text after it, no markdown code blocks, no explanation. Start your response with the "{" character:
|
|
41002
|
-
|
|
41003
|
-
{
|
|
41004
|
-
"tasks": [
|
|
41005
|
-
{
|
|
41006
|
-
"title": "string",
|
|
41007
|
-
"description": "string (detailed implementation guide: what to do, where to do it, how to do it, and boundaries — see description requirements above)",
|
|
41008
|
-
"assigneeRole": "BACKEND | FRONTEND | QA | PM | DESIGN",
|
|
41009
|
-
"priority": "HIGH | MEDIUM | LOW",
|
|
41010
|
-
"labels": ["string"],
|
|
41011
|
-
"acceptanceCriteria": ["string"]
|
|
41012
|
-
}
|
|
41013
|
-
],
|
|
41014
|
-
"technicalNotes": "string (brief notes on architecture decisions, risks, or considerations for the Architect phase)"
|
|
41015
|
-
}`;
|
|
41016
|
-
return prompt;
|
|
41017
|
-
}
|
|
41018
|
-
|
|
41019
41422
|
// ../sdk/src/planning/planning-meeting.ts
|
|
41020
41423
|
import { existsSync as existsSync10, readFileSync as readFileSync9 } from "node:fs";
|
|
41021
41424
|
|
|
@@ -41033,52 +41436,33 @@ class PlanningMeeting {
|
|
|
41033
41436
|
async run(directive, feedback) {
|
|
41034
41437
|
const projectContext = this.getProjectContext();
|
|
41035
41438
|
const codebaseIndex = this.getCodebaseIndex();
|
|
41036
|
-
this.log("Phase 1/
|
|
41037
|
-
const
|
|
41439
|
+
this.log("Phase 1/2: Planner building sprint plan...", "info");
|
|
41440
|
+
const plannerPrompt = buildPlannerPrompt({
|
|
41038
41441
|
directive,
|
|
41039
41442
|
projectContext,
|
|
41040
41443
|
codebaseIndex,
|
|
41041
41444
|
feedback
|
|
41042
41445
|
});
|
|
41043
|
-
const
|
|
41044
|
-
this.log("
|
|
41045
|
-
this.log("Phase 2/
|
|
41046
|
-
const architectPrompt = buildArchitectPrompt({
|
|
41047
|
-
directive,
|
|
41048
|
-
projectContext,
|
|
41049
|
-
techLeadOutput,
|
|
41050
|
-
feedback
|
|
41051
|
-
});
|
|
41052
|
-
const architectOutput = await this.aiRunner.run(architectPrompt);
|
|
41053
|
-
this.log("Architect phase complete.", "success");
|
|
41054
|
-
this.log("Phase 3/4: Sprint Organizer finalizing plan...", "info");
|
|
41055
|
-
const sprintOrganizerPrompt = buildSprintOrganizerPrompt({
|
|
41056
|
-
directive,
|
|
41057
|
-
architectOutput,
|
|
41058
|
-
feedback
|
|
41059
|
-
});
|
|
41060
|
-
const sprintOrganizerOutput = await this.aiRunner.run(sprintOrganizerPrompt);
|
|
41061
|
-
this.log("Sprint Organizer phase complete.", "success");
|
|
41062
|
-
this.log("Phase 4/4: Cross-Task Review checking for conflicts and overlaps...", "info");
|
|
41446
|
+
const plannerOutput = await this.aiRunner.run(plannerPrompt);
|
|
41447
|
+
this.log("Planner phase complete.", "success");
|
|
41448
|
+
this.log("Phase 2/2: Reviewer checking for conflicts and quality...", "info");
|
|
41063
41449
|
const crossTaskReviewerPrompt = buildCrossTaskReviewerPrompt({
|
|
41064
41450
|
directive,
|
|
41065
41451
|
projectContext,
|
|
41066
|
-
|
|
41452
|
+
plannerOutput,
|
|
41067
41453
|
feedback
|
|
41068
41454
|
});
|
|
41069
|
-
const
|
|
41070
|
-
this.log("
|
|
41071
|
-
const plan = parseSprintPlanFromAI(
|
|
41455
|
+
const reviewOutput = await this.aiRunner.run(crossTaskReviewerPrompt);
|
|
41456
|
+
this.log("Review phase complete.", "success");
|
|
41457
|
+
const plan = parseSprintPlanFromAI(reviewOutput, directive);
|
|
41072
41458
|
if (feedback) {
|
|
41073
41459
|
plan.feedback = feedback;
|
|
41074
41460
|
}
|
|
41075
41461
|
return {
|
|
41076
41462
|
plan,
|
|
41077
41463
|
phaseOutputs: {
|
|
41078
|
-
|
|
41079
|
-
|
|
41080
|
-
sprintOrganizer: sprintOrganizerOutput,
|
|
41081
|
-
crossTaskReview: crossTaskReviewOutput
|
|
41464
|
+
planner: plannerOutput,
|
|
41465
|
+
review: reviewOutput
|
|
41082
41466
|
}
|
|
41083
41467
|
};
|
|
41084
41468
|
}
|
|
@@ -41854,8 +42238,8 @@ function showHelp() {
|
|
|
41854
42238
|
${c.dim("Any other input will be sent as a prompt to the AI.")}
|
|
41855
42239
|
`);
|
|
41856
42240
|
}
|
|
41857
|
-
function showHistory(
|
|
41858
|
-
const historyManager =
|
|
42241
|
+
function showHistory(session2, args) {
|
|
42242
|
+
const historyManager = session2.getHistoryManager();
|
|
41859
42243
|
const limit = args ? parseInt(args, 10) : 10;
|
|
41860
42244
|
const sessions = historyManager.listSessions({
|
|
41861
42245
|
limit: Number.isNaN(limit) ? 10 : limit
|
|
@@ -41874,7 +42258,7 @@ function showHistory(session, args) {
|
|
|
41874
42258
|
const dateStr = date5.toLocaleDateString();
|
|
41875
42259
|
const timeStr = date5.toLocaleTimeString();
|
|
41876
42260
|
const msgCount = sess.messages.length;
|
|
41877
|
-
const isCurrent = sess.id ===
|
|
42261
|
+
const isCurrent = sess.id === session2.getSessionId();
|
|
41878
42262
|
const marker = isCurrent ? c.success("*") : " ";
|
|
41879
42263
|
console.log(` ${marker} ${c.cyan(sess.id)} ${c.dim(`- ${dateStr} ${timeStr} (${msgCount} messages)`)}`);
|
|
41880
42264
|
if (sess.messages.length > 0) {
|
|
@@ -41895,7 +42279,7 @@ var init_commands = __esm(() => {
|
|
|
41895
42279
|
name: "exit",
|
|
41896
42280
|
aliases: ["quit", "q"],
|
|
41897
42281
|
description: "Exit interactive mode",
|
|
41898
|
-
execute: (
|
|
42282
|
+
execute: (session2) => session2.shutdown()
|
|
41899
42283
|
},
|
|
41900
42284
|
{
|
|
41901
42285
|
name: "clear",
|
|
@@ -41913,21 +42297,21 @@ var init_commands = __esm(() => {
|
|
|
41913
42297
|
name: "reset",
|
|
41914
42298
|
aliases: ["r"],
|
|
41915
42299
|
description: "Reset conversation context",
|
|
41916
|
-
execute: (
|
|
42300
|
+
execute: (session2) => session2.resetContext()
|
|
41917
42301
|
},
|
|
41918
42302
|
{
|
|
41919
42303
|
name: "history",
|
|
41920
42304
|
aliases: ["hist"],
|
|
41921
42305
|
description: "List recent sessions",
|
|
41922
|
-
execute: (
|
|
42306
|
+
execute: (session2, args) => showHistory(session2, args)
|
|
41923
42307
|
},
|
|
41924
42308
|
{
|
|
41925
42309
|
name: "session",
|
|
41926
42310
|
aliases: ["sid"],
|
|
41927
42311
|
description: "Show current session ID",
|
|
41928
|
-
execute: (
|
|
42312
|
+
execute: (session2) => {
|
|
41929
42313
|
console.log(`
|
|
41930
|
-
${c.dim("Session ID:")} ${c.cyan(
|
|
42314
|
+
${c.dim("Session ID:")} ${c.cyan(session2.getSessionId())}
|
|
41931
42315
|
`);
|
|
41932
42316
|
}
|
|
41933
42317
|
}
|
|
@@ -43020,9 +43404,137 @@ function showDocsSyncHelp() {
|
|
|
43020
43404
|
}
|
|
43021
43405
|
// src/commands/exec.ts
|
|
43022
43406
|
init_index_node();
|
|
43023
|
-
|
|
43407
|
+
import { randomUUID as randomUUID2 } from "node:crypto";
|
|
43024
43408
|
import { parseArgs as parseArgs2 } from "node:util";
|
|
43025
43409
|
|
|
43410
|
+
// src/display/json-stream-renderer.ts
|
|
43411
|
+
init_src();
|
|
43412
|
+
|
|
43413
|
+
class JsonStreamRenderer {
|
|
43414
|
+
sessionId;
|
|
43415
|
+
command;
|
|
43416
|
+
model;
|
|
43417
|
+
provider;
|
|
43418
|
+
cwd;
|
|
43419
|
+
statsTracker;
|
|
43420
|
+
started = false;
|
|
43421
|
+
done = false;
|
|
43422
|
+
constructor(options) {
|
|
43423
|
+
this.sessionId = options.sessionId;
|
|
43424
|
+
this.command = options.command;
|
|
43425
|
+
this.model = options.model;
|
|
43426
|
+
this.provider = options.provider;
|
|
43427
|
+
this.cwd = options.cwd;
|
|
43428
|
+
this.statsTracker = new ExecutionStatsTracker;
|
|
43429
|
+
}
|
|
43430
|
+
emitStart() {
|
|
43431
|
+
if (this.started)
|
|
43432
|
+
return;
|
|
43433
|
+
this.started = true;
|
|
43434
|
+
this.emit(createCliStreamEvent(CliStreamEventType.START, this.sessionId, {
|
|
43435
|
+
command: this.command,
|
|
43436
|
+
model: this.model,
|
|
43437
|
+
provider: this.provider,
|
|
43438
|
+
cwd: this.cwd
|
|
43439
|
+
}));
|
|
43440
|
+
}
|
|
43441
|
+
handleChunk(chunk) {
|
|
43442
|
+
this.ensureStarted();
|
|
43443
|
+
switch (chunk.type) {
|
|
43444
|
+
case "text_delta":
|
|
43445
|
+
this.emit(createCliStreamEvent(CliStreamEventType.TEXT_DELTA, this.sessionId, {
|
|
43446
|
+
content: chunk.content
|
|
43447
|
+
}));
|
|
43448
|
+
break;
|
|
43449
|
+
case "thinking":
|
|
43450
|
+
this.emit(createCliStreamEvent(CliStreamEventType.THINKING, this.sessionId, {
|
|
43451
|
+
content: chunk.content
|
|
43452
|
+
}));
|
|
43453
|
+
break;
|
|
43454
|
+
case "tool_use":
|
|
43455
|
+
this.statsTracker.toolStarted(chunk.tool, chunk.id);
|
|
43456
|
+
this.emit(createCliStreamEvent(CliStreamEventType.TOOL_STARTED, this.sessionId, {
|
|
43457
|
+
tool: chunk.tool,
|
|
43458
|
+
toolId: chunk.id,
|
|
43459
|
+
parameters: chunk.parameters
|
|
43460
|
+
}));
|
|
43461
|
+
break;
|
|
43462
|
+
case "tool_result":
|
|
43463
|
+
if (chunk.success) {
|
|
43464
|
+
this.statsTracker.toolCompleted(chunk.tool, chunk.id);
|
|
43465
|
+
} else {
|
|
43466
|
+
this.statsTracker.toolFailed(chunk.tool, chunk.error ?? "Unknown error", chunk.id);
|
|
43467
|
+
}
|
|
43468
|
+
this.emit(createCliStreamEvent(CliStreamEventType.TOOL_COMPLETED, this.sessionId, {
|
|
43469
|
+
tool: chunk.tool,
|
|
43470
|
+
toolId: chunk.id,
|
|
43471
|
+
success: chunk.success,
|
|
43472
|
+
duration: chunk.duration,
|
|
43473
|
+
error: chunk.error
|
|
43474
|
+
}));
|
|
43475
|
+
break;
|
|
43476
|
+
case "tool_parameters":
|
|
43477
|
+
break;
|
|
43478
|
+
case "result":
|
|
43479
|
+
break;
|
|
43480
|
+
case "error":
|
|
43481
|
+
this.statsTracker.setError(chunk.error);
|
|
43482
|
+
this.emitError("UNKNOWN", chunk.error);
|
|
43483
|
+
break;
|
|
43484
|
+
}
|
|
43485
|
+
}
|
|
43486
|
+
emitStatus(status, message) {
|
|
43487
|
+
this.ensureStarted();
|
|
43488
|
+
this.emit(createCliStreamEvent(CliStreamEventType.STATUS, this.sessionId, {
|
|
43489
|
+
status,
|
|
43490
|
+
message
|
|
43491
|
+
}));
|
|
43492
|
+
}
|
|
43493
|
+
emitError(code, message, options) {
|
|
43494
|
+
this.ensureStarted();
|
|
43495
|
+
this.emit(createCliStreamEvent(CliStreamEventType.ERROR, this.sessionId, {
|
|
43496
|
+
error: createProtocolError(code, message, options)
|
|
43497
|
+
}));
|
|
43498
|
+
}
|
|
43499
|
+
emitDone(exitCode) {
|
|
43500
|
+
if (this.done)
|
|
43501
|
+
return;
|
|
43502
|
+
this.done = true;
|
|
43503
|
+
this.ensureStarted();
|
|
43504
|
+
const stats = this.statsTracker.finalize();
|
|
43505
|
+
this.emit(createCliStreamEvent(CliStreamEventType.DONE, this.sessionId, {
|
|
43506
|
+
exitCode,
|
|
43507
|
+
duration: stats.duration,
|
|
43508
|
+
toolsUsed: stats.toolsUsed.length > 0 ? stats.toolsUsed : undefined,
|
|
43509
|
+
tokensUsed: stats.tokensUsed,
|
|
43510
|
+
success: exitCode === 0
|
|
43511
|
+
}));
|
|
43512
|
+
}
|
|
43513
|
+
emitFatalError(code, message, options) {
|
|
43514
|
+
this.statsTracker.setError(message);
|
|
43515
|
+
this.emitError(code, message, {
|
|
43516
|
+
...options,
|
|
43517
|
+
recoverable: false
|
|
43518
|
+
});
|
|
43519
|
+
this.emitDone(1);
|
|
43520
|
+
}
|
|
43521
|
+
isDone() {
|
|
43522
|
+
return this.done;
|
|
43523
|
+
}
|
|
43524
|
+
ensureStarted() {
|
|
43525
|
+
if (!this.started) {
|
|
43526
|
+
this.emitStart();
|
|
43527
|
+
}
|
|
43528
|
+
}
|
|
43529
|
+
emit(event) {
|
|
43530
|
+
process.stdout.write(`${JSON.stringify(event)}
|
|
43531
|
+
`);
|
|
43532
|
+
}
|
|
43533
|
+
}
|
|
43534
|
+
|
|
43535
|
+
// src/commands/exec.ts
|
|
43536
|
+
init_progress_renderer();
|
|
43537
|
+
|
|
43026
43538
|
// src/commands/exec-sessions.ts
|
|
43027
43539
|
init_index_node();
|
|
43028
43540
|
function formatRelativeTime(timestamp) {
|
|
@@ -43060,11 +43572,11 @@ class SessionCommands {
|
|
|
43060
43572
|
console.log(`
|
|
43061
43573
|
${c.primary("Recent Exec Sessions:")}
|
|
43062
43574
|
`);
|
|
43063
|
-
for (const
|
|
43064
|
-
const shortId = this.getShortId(
|
|
43065
|
-
const age = formatRelativeTime(
|
|
43066
|
-
const msgCount =
|
|
43067
|
-
const firstUserMsg =
|
|
43575
|
+
for (const session2 of sessions.slice(0, 10)) {
|
|
43576
|
+
const shortId = this.getShortId(session2.id);
|
|
43577
|
+
const age = formatRelativeTime(session2.updatedAt);
|
|
43578
|
+
const msgCount = session2.messages.length;
|
|
43579
|
+
const firstUserMsg = session2.messages.find((m) => m.role === "user");
|
|
43068
43580
|
const preview = firstUserMsg ? firstUserMsg.content.slice(0, 50).replace(/\n/g, " ") : "(empty session)";
|
|
43069
43581
|
console.log(` ${c.cyan(shortId)} ${c.gray("-")} ${preview}${firstUserMsg && firstUserMsg.content.length > 50 ? "..." : ""}`);
|
|
43070
43582
|
console.log(` ${c.dim(`${msgCount} messages • ${age}`)}`);
|
|
@@ -43084,8 +43596,8 @@ class SessionCommands {
|
|
|
43084
43596
|
`);
|
|
43085
43597
|
return;
|
|
43086
43598
|
}
|
|
43087
|
-
const
|
|
43088
|
-
if (!
|
|
43599
|
+
const session2 = this.historyManager.findSessionByPartialId(sessionId);
|
|
43600
|
+
if (!session2) {
|
|
43089
43601
|
console.error(`
|
|
43090
43602
|
${c.error("Error:")} Session ${c.cyan(sessionId)} not found
|
|
43091
43603
|
`);
|
|
@@ -43094,18 +43606,18 @@ class SessionCommands {
|
|
|
43094
43606
|
return;
|
|
43095
43607
|
}
|
|
43096
43608
|
console.log(`
|
|
43097
|
-
${c.primary("Session:")} ${c.cyan(
|
|
43098
|
-
console.log(` ${c.dim(`Created: ${new Date(
|
|
43099
|
-
console.log(` ${c.dim(`Model: ${
|
|
43609
|
+
${c.primary("Session:")} ${c.cyan(session2.id)}`);
|
|
43610
|
+
console.log(` ${c.dim(`Created: ${new Date(session2.createdAt).toLocaleString()}`)}`);
|
|
43611
|
+
console.log(` ${c.dim(`Model: ${session2.metadata.model} (${session2.metadata.provider})`)}
|
|
43100
43612
|
`);
|
|
43101
|
-
if (
|
|
43613
|
+
if (session2.messages.length === 0) {
|
|
43102
43614
|
console.log(` ${c.dim("(No messages in this session)")}
|
|
43103
43615
|
`);
|
|
43104
43616
|
return;
|
|
43105
43617
|
}
|
|
43106
43618
|
console.log(c.dim(" ─".repeat(30)));
|
|
43107
43619
|
console.log();
|
|
43108
|
-
for (const message of
|
|
43620
|
+
for (const message of session2.messages) {
|
|
43109
43621
|
const role = message.role === "user" ? c.cyan("You") : c.green("AI");
|
|
43110
43622
|
const content = message.content;
|
|
43111
43623
|
console.log(` ${role}:`);
|
|
@@ -43126,17 +43638,17 @@ class SessionCommands {
|
|
|
43126
43638
|
`);
|
|
43127
43639
|
return;
|
|
43128
43640
|
}
|
|
43129
|
-
const
|
|
43130
|
-
if (!
|
|
43641
|
+
const session2 = this.historyManager.findSessionByPartialId(sessionId);
|
|
43642
|
+
if (!session2) {
|
|
43131
43643
|
console.error(`
|
|
43132
43644
|
${c.error("Error:")} Session ${c.cyan(sessionId)} not found
|
|
43133
43645
|
`);
|
|
43134
43646
|
return;
|
|
43135
43647
|
}
|
|
43136
|
-
const deleted = this.historyManager.deleteSession(
|
|
43648
|
+
const deleted = this.historyManager.deleteSession(session2.id);
|
|
43137
43649
|
if (deleted) {
|
|
43138
43650
|
console.log(`
|
|
43139
|
-
${c.success("✔")} Deleted session ${c.cyan(this.getShortId(
|
|
43651
|
+
${c.success("✔")} Deleted session ${c.cyan(this.getShortId(session2.id))}
|
|
43140
43652
|
`);
|
|
43141
43653
|
} else {
|
|
43142
43654
|
console.error(`
|
|
@@ -43191,15 +43703,22 @@ async function execCommand(args) {
|
|
|
43191
43703
|
options: {
|
|
43192
43704
|
model: { type: "string" },
|
|
43193
43705
|
provider: { type: "string" },
|
|
43706
|
+
"reasoning-effort": { type: "string" },
|
|
43194
43707
|
dir: { type: "string" },
|
|
43195
43708
|
"no-stream": { type: "boolean" },
|
|
43196
43709
|
"no-status": { type: "boolean" },
|
|
43197
43710
|
interactive: { type: "boolean", short: "i" },
|
|
43198
|
-
session: { type: "string", short: "s" }
|
|
43711
|
+
session: { type: "string", short: "s" },
|
|
43712
|
+
"json-stream": { type: "boolean" }
|
|
43199
43713
|
},
|
|
43200
43714
|
strict: false
|
|
43201
43715
|
});
|
|
43716
|
+
const jsonStream = values["json-stream"];
|
|
43202
43717
|
const projectPath = values.dir || process.cwd();
|
|
43718
|
+
if (jsonStream) {
|
|
43719
|
+
await execJsonStream(values, positionals, projectPath);
|
|
43720
|
+
return;
|
|
43721
|
+
}
|
|
43203
43722
|
requireInitialization(projectPath, "exec");
|
|
43204
43723
|
if (positionals[0] === "sessions") {
|
|
43205
43724
|
const sessionAction = positionals[1];
|
|
@@ -43230,13 +43749,13 @@ async function execCommand(args) {
|
|
|
43230
43749
|
const sessionId = values.session;
|
|
43231
43750
|
if (isInteractive) {
|
|
43232
43751
|
const { InteractiveSession: InteractiveSession2 } = await Promise.resolve().then(() => (init_interactive_session(), exports_interactive_session));
|
|
43233
|
-
const
|
|
43752
|
+
const session2 = new InteractiveSession2({
|
|
43234
43753
|
projectPath,
|
|
43235
43754
|
provider,
|
|
43236
43755
|
model,
|
|
43237
43756
|
sessionId
|
|
43238
43757
|
});
|
|
43239
|
-
await
|
|
43758
|
+
await session2.start();
|
|
43240
43759
|
return;
|
|
43241
43760
|
}
|
|
43242
43761
|
const promptInput = positionals.join(" ");
|
|
@@ -43245,9 +43764,11 @@ async function execCommand(args) {
|
|
|
43245
43764
|
process.exit(1);
|
|
43246
43765
|
}
|
|
43247
43766
|
const useStreaming = !values["no-stream"];
|
|
43767
|
+
const reasoningEffort = values["reasoning-effort"];
|
|
43248
43768
|
const aiRunner = createAiRunner(provider, {
|
|
43249
43769
|
projectPath,
|
|
43250
|
-
model
|
|
43770
|
+
model,
|
|
43771
|
+
reasoningEffort
|
|
43251
43772
|
});
|
|
43252
43773
|
const builder = new PromptBuilder(projectPath);
|
|
43253
43774
|
const fullPrompt = await builder.buildGenericPrompt(promptInput);
|
|
@@ -43325,6 +43846,67 @@ async function execCommand(args) {
|
|
|
43325
43846
|
process.exit(1);
|
|
43326
43847
|
}
|
|
43327
43848
|
}
|
|
43849
|
+
async function execJsonStream(values, positionals, projectPath) {
|
|
43850
|
+
const sessionId = values.session ?? randomUUID2();
|
|
43851
|
+
const execSettings = new SettingsManager(projectPath).load();
|
|
43852
|
+
const provider = resolveProvider3(values.provider || execSettings.provider);
|
|
43853
|
+
const model = values.model || execSettings.model || DEFAULT_MODEL[provider];
|
|
43854
|
+
const renderer = new JsonStreamRenderer({
|
|
43855
|
+
sessionId,
|
|
43856
|
+
command: "exec",
|
|
43857
|
+
model,
|
|
43858
|
+
provider,
|
|
43859
|
+
cwd: projectPath
|
|
43860
|
+
});
|
|
43861
|
+
const handleSignal = () => {
|
|
43862
|
+
if (!renderer.isDone()) {
|
|
43863
|
+
renderer.emitFatalError("PROCESS_CRASHED", "Process terminated by signal");
|
|
43864
|
+
}
|
|
43865
|
+
process.exit(1);
|
|
43866
|
+
};
|
|
43867
|
+
process.on("SIGINT", handleSignal);
|
|
43868
|
+
process.on("SIGTERM", handleSignal);
|
|
43869
|
+
try {
|
|
43870
|
+
try {
|
|
43871
|
+
requireInitialization(projectPath, "exec");
|
|
43872
|
+
} catch (initError) {
|
|
43873
|
+
renderer.emitFatalError("CLI_NOT_FOUND", initError instanceof Error ? initError.message : String(initError));
|
|
43874
|
+
process.exit(1);
|
|
43875
|
+
}
|
|
43876
|
+
const promptInput = positionals.join(" ");
|
|
43877
|
+
if (!promptInput) {
|
|
43878
|
+
renderer.emitFatalError("UNKNOWN", 'Prompt is required. Usage: locus exec --json-stream "your prompt"');
|
|
43879
|
+
process.exit(1);
|
|
43880
|
+
}
|
|
43881
|
+
renderer.emitStart();
|
|
43882
|
+
renderer.emitStatus("running", "Building prompt context");
|
|
43883
|
+
const aiRunner = createAiRunner(provider, {
|
|
43884
|
+
projectPath,
|
|
43885
|
+
model
|
|
43886
|
+
});
|
|
43887
|
+
const builder = new PromptBuilder(projectPath);
|
|
43888
|
+
const fullPrompt = await builder.buildGenericPrompt(promptInput);
|
|
43889
|
+
renderer.emitStatus("streaming", "Streaming AI response");
|
|
43890
|
+
const stream4 = aiRunner.runStream(fullPrompt);
|
|
43891
|
+
for await (const chunk of stream4) {
|
|
43892
|
+
renderer.handleChunk(chunk);
|
|
43893
|
+
}
|
|
43894
|
+
try {
|
|
43895
|
+
const knowledgeBase = new KnowledgeBase(projectPath);
|
|
43896
|
+
knowledgeBase.updateProgress({
|
|
43897
|
+
role: "user",
|
|
43898
|
+
content: promptInput
|
|
43899
|
+
});
|
|
43900
|
+
} catch {}
|
|
43901
|
+
renderer.emitDone(0);
|
|
43902
|
+
} catch (error48) {
|
|
43903
|
+
const message = error48 instanceof Error ? error48.message : String(error48);
|
|
43904
|
+
if (!renderer.isDone()) {
|
|
43905
|
+
renderer.emitFatalError("UNKNOWN", message);
|
|
43906
|
+
}
|
|
43907
|
+
process.exit(1);
|
|
43908
|
+
}
|
|
43909
|
+
}
|
|
43328
43910
|
// src/commands/help.ts
|
|
43329
43911
|
init_index_node();
|
|
43330
43912
|
function showHelp2() {
|
|
@@ -43364,6 +43946,7 @@ function showHelp2() {
|
|
|
43364
43946
|
${c.header(" OPTIONS ")}
|
|
43365
43947
|
${c.secondary("--help")} Show this help message
|
|
43366
43948
|
${c.secondary("--provider")} <name> AI provider: ${c.dim("claude")} or ${c.dim("codex")} (default: ${c.dim("claude")})
|
|
43949
|
+
${c.secondary("--reasoning-effort")} <level> Codex reasoning effort: ${c.dim("low, medium, high")} (default: model default)
|
|
43367
43950
|
|
|
43368
43951
|
${c.header(" GETTING STARTED ")}
|
|
43369
43952
|
${c.dim("$")} ${c.primary("locus init")}
|
|
@@ -43513,12 +44096,7 @@ async function initCommand() {
|
|
|
43513
44096
|
init_index_node();
|
|
43514
44097
|
import { parseArgs as parseArgs4 } from "node:util";
|
|
43515
44098
|
function normalizePlanIdArgs(args) {
|
|
43516
|
-
const planIdFlags = new Set([
|
|
43517
|
-
"--approve",
|
|
43518
|
-
"--reject",
|
|
43519
|
-
"--cancel",
|
|
43520
|
-
"--show"
|
|
43521
|
-
]);
|
|
44099
|
+
const planIdFlags = new Set(["--approve", "--reject", "--cancel", "--show"]);
|
|
43522
44100
|
const result = [];
|
|
43523
44101
|
let i = 0;
|
|
43524
44102
|
while (i < args.length) {
|
|
@@ -43546,6 +44124,7 @@ async function planCommand(args) {
|
|
|
43546
44124
|
show: { type: "string" },
|
|
43547
44125
|
model: { type: "string" },
|
|
43548
44126
|
provider: { type: "string" },
|
|
44127
|
+
"reasoning-effort": { type: "string" },
|
|
43549
44128
|
"api-key": { type: "string" },
|
|
43550
44129
|
"api-url": { type: "string" },
|
|
43551
44130
|
workspace: { type: "string" },
|
|
@@ -43590,9 +44169,11 @@ async function planCommand(args) {
|
|
|
43590
44169
|
const planSettings = new SettingsManager(projectPath).load();
|
|
43591
44170
|
const provider = resolveProvider3(values.provider || planSettings.provider);
|
|
43592
44171
|
const model = values.model || planSettings.model || DEFAULT_MODEL[provider];
|
|
44172
|
+
const reasoningEffort = values["reasoning-effort"];
|
|
43593
44173
|
const aiRunner = createAiRunner(provider, {
|
|
43594
44174
|
projectPath,
|
|
43595
|
-
model
|
|
44175
|
+
model,
|
|
44176
|
+
reasoningEffort
|
|
43596
44177
|
});
|
|
43597
44178
|
const log = (message, level) => {
|
|
43598
44179
|
const icon = level === "success" ? c.success("✔") : level === "error" ? c.error("✖") : level === "warn" ? c.warning("!") : c.info("●");
|
|
@@ -43977,6 +44558,7 @@ async function runCommand(args) {
|
|
|
43977
44558
|
sprint: { type: "string" },
|
|
43978
44559
|
model: { type: "string" },
|
|
43979
44560
|
provider: { type: "string" },
|
|
44561
|
+
"reasoning-effort": { type: "string" },
|
|
43980
44562
|
"skip-planning": { type: "boolean" },
|
|
43981
44563
|
"api-url": { type: "string" },
|
|
43982
44564
|
dir: { type: "string" }
|
|
@@ -44011,11 +44593,13 @@ async function runCommand(args) {
|
|
|
44011
44593
|
console.error(c.error(error48 instanceof Error ? error48.message : String(error48)));
|
|
44012
44594
|
process.exit(1);
|
|
44013
44595
|
}
|
|
44596
|
+
const reasoningEffort = values["reasoning-effort"];
|
|
44014
44597
|
const orchestrator = new AgentOrchestrator({
|
|
44015
44598
|
workspaceId,
|
|
44016
44599
|
sprintId: values.sprint || "",
|
|
44017
44600
|
model,
|
|
44018
44601
|
provider,
|
|
44602
|
+
reasoningEffort,
|
|
44019
44603
|
apiBase,
|
|
44020
44604
|
maxIterations: 100,
|
|
44021
44605
|
projectPath,
|
|
@@ -44439,10 +45023,11 @@ function versionCommand() {
|
|
|
44439
45023
|
console.log("");
|
|
44440
45024
|
}
|
|
44441
45025
|
// src/cli.ts
|
|
45026
|
+
var isJsonStream = process.argv.includes("--json-stream");
|
|
44442
45027
|
async function main() {
|
|
44443
45028
|
const command = process.argv[2];
|
|
44444
45029
|
const args = process.argv.slice(3);
|
|
44445
|
-
if (command !== "exec") {
|
|
45030
|
+
if (command !== "exec" && !isJsonStream) {
|
|
44446
45031
|
printBanner();
|
|
44447
45032
|
}
|
|
44448
45033
|
switch (command) {
|
|
@@ -44486,6 +45071,11 @@ async function main() {
|
|
|
44486
45071
|
}
|
|
44487
45072
|
}
|
|
44488
45073
|
main().catch((err) => {
|
|
45074
|
+
if (isJsonStream) {
|
|
45075
|
+
process.stderr.write(`${JSON.stringify({ fatal: true, error: err.message })}
|
|
45076
|
+
`);
|
|
45077
|
+
process.exit(1);
|
|
45078
|
+
}
|
|
44489
45079
|
console.error(`
|
|
44490
45080
|
${c.error("✖ Fatal Error")} ${c.red(err.message)}`);
|
|
44491
45081
|
process.exit(1);
|