@locusai/cli 0.11.6 → 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/locus.js CHANGED
@@ -37982,12 +37982,536 @@ var init_models = __esm(() => {
37982
37982
  init_workspace();
37983
37983
  });
37984
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
+
37985
38508
  // ../shared/src/index.ts
37986
38509
  var init_src = __esm(() => {
37987
38510
  init_common();
37988
38511
  init_constants();
37989
38512
  init_enums();
37990
38513
  init_models();
38514
+ init_protocol();
37991
38515
  });
37992
38516
 
37993
38517
  // ../sdk/src/modules/tasks.ts
@@ -38273,11 +38797,11 @@ ${line}`;
38273
38797
  writeFileSync3(this.progressPath, updated);
38274
38798
  }
38275
38799
  getFullContext() {
38276
- const context = this.readContext();
38800
+ const context2 = this.readContext();
38277
38801
  const progress = this.readProgress();
38278
38802
  const parts = [];
38279
- if (context.trim()) {
38280
- parts.push(context.trim());
38803
+ if (context2.trim()) {
38804
+ parts.push(context2.trim());
38281
38805
  }
38282
38806
  if (progress.trim()) {
38283
38807
  parts.push(progress.trim());
@@ -38602,10 +39126,10 @@ ${task2.description || "No description provided."}
38602
39126
  let hasLocalContext = false;
38603
39127
  if (existsSync6(contextPath)) {
38604
39128
  try {
38605
- const context = readFileSync6(contextPath, "utf-8");
38606
- if (context.trim().length > 20) {
39129
+ const context2 = readFileSync6(contextPath, "utf-8");
39130
+ if (context2.trim().length > 20) {
38607
39131
  prompt += `## Project Context (Local)
38608
- ${context}
39132
+ ${context2}
38609
39133
 
38610
39134
  `;
38611
39135
  hasLocalContext = true;
@@ -38735,10 +39259,10 @@ ${query}
38735
39259
  let hasLocalContext = false;
38736
39260
  if (existsSync6(contextPath)) {
38737
39261
  try {
38738
- const context = readFileSync6(contextPath, "utf-8");
38739
- if (context.trim().length > 20) {
39262
+ const context2 = readFileSync6(contextPath, "utf-8");
39263
+ if (context2.trim().length > 20) {
38740
39264
  prompt += `## Project Context (Local)
38741
- ${context}
39265
+ ${context2}
38742
39266
 
38743
39267
  `;
38744
39268
  hasLocalContext = true;
@@ -39696,10 +40220,10 @@ class HistoryManager {
39696
40220
  getSessionPath(sessionId) {
39697
40221
  return join7(this.historyDir, `${sessionId}.json`);
39698
40222
  }
39699
- saveSession(session) {
39700
- const filePath = this.getSessionPath(session.id);
39701
- session.updatedAt = Date.now();
39702
- writeFileSync4(filePath, JSON.stringify(session, null, 2), "utf-8");
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");
39703
40227
  }
39704
40228
  loadSession(sessionId) {
39705
40229
  const filePath = this.getSessionPath(sessionId);
@@ -39730,9 +40254,9 @@ class HistoryManager {
39730
40254
  let sessions = [];
39731
40255
  for (const file2 of files) {
39732
40256
  if (file2.endsWith(".json")) {
39733
- const session = this.loadSession(file2.replace(".json", ""));
39734
- if (session) {
39735
- sessions.push(session);
40257
+ const session2 = this.loadSession(file2.replace(".json", ""));
40258
+ if (session2) {
40259
+ sessions.push(session2);
39736
40260
  }
39737
40261
  }
39738
40262
  }
@@ -39754,7 +40278,7 @@ class HistoryManager {
39754
40278
  }
39755
40279
  if (options.query) {
39756
40280
  const query = options.query.toLowerCase();
39757
- filtered = filtered.filter((session) => session.messages.some((msg) => msg.content.toLowerCase().includes(query)));
40281
+ filtered = filtered.filter((session2) => session2.messages.some((msg) => msg.content.toLowerCase().includes(query)));
39758
40282
  }
39759
40283
  const offset = options.offset ?? 0;
39760
40284
  const limit = options.limit ?? filtered.length;
@@ -39790,8 +40314,8 @@ class HistoryManager {
39790
40314
  let deleted = 0;
39791
40315
  if (sessions.length > this.maxSessions) {
39792
40316
  const sessionsToDelete = sessions.slice(this.maxSessions);
39793
- for (const session of sessionsToDelete) {
39794
- if (this.deleteSession(session.id)) {
40317
+ for (const session2 of sessionsToDelete) {
40318
+ if (this.deleteSession(session2.id)) {
39795
40319
  deleted++;
39796
40320
  }
39797
40321
  }
@@ -40676,78 +41200,6 @@ var init_plan_manager = __esm(() => {
40676
41200
  init_sprint_plan();
40677
41201
  });
40678
41202
 
40679
- // ../sdk/src/planning/agents/architect.ts
40680
- function buildArchitectPrompt(input) {
40681
- let prompt = `# Role: Software Architect
40682
-
40683
- 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.
40684
-
40685
- ## CEO Directive
40686
- > ${input.directive}
40687
- `;
40688
- if (input.feedback) {
40689
- prompt += `
40690
- ## CEO Feedback on Previous Plan
40691
- > ${input.feedback}
40692
-
40693
- IMPORTANT: Ensure the refined plan addresses this feedback.
40694
- `;
40695
- }
40696
- prompt += `
40697
- ## Project Context
40698
- ${input.projectContext || "No project context available."}
40699
-
40700
- ## Tech Lead's Task Breakdown
40701
- ${input.techLeadOutput}
40702
-
40703
- ## Your Task
40704
-
40705
- Review and refine the Tech Lead's breakdown:
40706
-
40707
- 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.
40708
- 2. **Risk Assessment** — Flag tasks that are risky, underestimated, or have unknowns.
40709
- 3. **Task Merging** — If two tasks are trivially small and related, merge them.
40710
- 4. **Complexity Scoring** — Rate each task 1-5 (1=trivial, 5=very complex).
40711
- 5. **Missing Tasks** — Add any tasks the Tech Lead missed (database migrations, configuration, testing, etc.).
40712
- 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.
40713
-
40714
- ## CRITICAL: Task Ordering & Dependencies
40715
-
40716
- 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:
40717
-
40718
- 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.
40719
- 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.
40720
- 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.
40721
- 4. **Flag risks.** In your risk assessment, call out tasks that are complex or have unknowns.
40722
-
40723
- ## Output Format
40724
-
40725
- 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:
40726
-
40727
- {
40728
- "tasks": [
40729
- {
40730
- "title": "string",
40731
- "description": "string (detailed implementation guide: what to do, where to do it, how to do it, and boundaries)",
40732
- "assigneeRole": "BACKEND | FRONTEND | QA | PM | DESIGN",
40733
- "priority": "HIGH | MEDIUM | LOW | CRITICAL",
40734
- "labels": ["string"],
40735
- "acceptanceCriteria": ["string"],
40736
- "complexity": 3
40737
- }
40738
- ],
40739
- "risks": [
40740
- {
40741
- "description": "string",
40742
- "mitigation": "string",
40743
- "severity": "low | medium | high"
40744
- }
40745
- ],
40746
- "architectureNotes": "string (notes for the Sprint Organizer about parallelism opportunities and constraints)"
40747
- }`;
40748
- return prompt;
40749
- }
40750
-
40751
41203
  // ../sdk/src/planning/agents/cross-task-reviewer.ts
40752
41204
  function buildCrossTaskReviewerPrompt(input) {
40753
41205
  let prompt = `# Role: Cross-Task Reviewer (Architect + Engineer + Planner)
@@ -40783,7 +41235,7 @@ IMPORTANT: Ensure the reviewed plan still addresses this feedback.
40783
41235
  ${input.projectContext || "No project context available."}
40784
41236
 
40785
41237
  ## Sprint Plan to Review
40786
- ${input.sprintOrganizerOutput}
41238
+ ${input.plannerOutput}
40787
41239
 
40788
41240
  ## Your Review Checklist
40789
41241
 
@@ -40862,11 +41314,11 @@ IMPORTANT:
40862
41314
  return prompt;
40863
41315
  }
40864
41316
 
40865
- // ../sdk/src/planning/agents/sprint-organizer.ts
40866
- function buildSprintOrganizerPrompt(input) {
40867
- let prompt = `# Role: Sprint Organizer
41317
+ // ../sdk/src/planning/agents/planner.ts
41318
+ function buildPlannerPrompt(input) {
41319
+ let prompt = `# Role: Sprint Planner
40868
41320
 
40869
- You are a Sprint Organizer finalizing the sprint plan from a planning meeting. The Architect has refined the task breakdown. Your job is to produce the final sprint plan document.
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.
40870
41322
 
40871
41323
  ## CEO Directive
40872
41324
  > ${input.directive}
@@ -40876,40 +41328,64 @@ You are a Sprint Organizer finalizing the sprint plan from a planning meeting. T
40876
41328
  ## CEO Feedback on Previous Plan
40877
41329
  > ${input.feedback}
40878
41330
 
40879
- IMPORTANT: The final plan must address this feedback.
41331
+ IMPORTANT: Incorporate this feedback into your plan. The CEO has reviewed a previous plan and wants changes.
40880
41332
  `;
40881
41333
  }
40882
41334
  prompt += `
40883
- ## Architect's Refined Task Breakdown
40884
- ${input.architectOutput}
41335
+ ## Project Context
41336
+ ${input.projectContext || "No project context available."}
41337
+
41338
+ ## Codebase Structure
41339
+ ${input.codebaseIndex || "No codebase index available."}
40885
41340
 
40886
41341
  ## Your Task
40887
41342
 
40888
- Produce the final sprint plan:
41343
+ Analyze the directive and produce a **complete sprint plan** with the following:
40889
41344
 
40890
- 1. **Sprint Name** — A concise, memorable name for this sprint (e.g., "User Authentication", "Payment Integration")
41345
+ 1. **Sprint Name** — A concise, memorable name (2-4 words)
40891
41346
  2. **Sprint Goal** — One paragraph describing what this sprint delivers
40892
- 3. **Task Ordering** — Final ordering so that foundational work comes first. The position in the array IS the execution order — task at index 0 runs first, index 1 runs second, etc. Tasks are executed SEQUENTIALLY by a single agent on one branch.
40893
- 4. **Duration Estimate** — How many days this sprint will take with a single agent working sequentially
40894
- 5. **Final Task List** — Each task with all fields filled in, ordered by execution priority
40895
- 6. **Description Quality Check** — Ensure every task description is a clear, actionable implementation guide. Each description must specify: what to do, where to do it (specific files/modules/directories), how to do it (implementation approach, patterns to follow, existing utilities to use), and what is NOT in scope. If any description is vague or generic, rewrite it with specifics. Remember: an independent agent will receive ONLY the task title, description, and acceptance criteria — the description is its primary instruction.
40896
-
40897
- Guidelines:
40898
- - The order of tasks in the array determines execution order. Tasks are dispatched sequentially from first to last.
40899
- - Foundation tasks (schemas, config, shared code) must appear before tasks that build on them
40900
- - Since tasks execute sequentially on one branch, later tasks can depend on earlier tasks' outputs
40901
- - Ensure acceptance criteria are specific and testable
40902
- - Keep the sprint focused if it's too large (>12 tasks), consider reducing scope
40903
- - Ensure every task description reads as a standalone implementation brief — not a summary
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
40904
41361
 
40905
- ## CRITICAL: Task Ordering Validation
41362
+ ### CRITICAL: Task Description Requirements
40906
41363
 
40907
- Before finalizing, validate that tasks are in the correct execution order:
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:
40908
41365
 
40909
- 1. **No forward dependencies.** A task must NOT depend on a task that appears later in the list.
40910
- 2. **Foundation first.** Config, schemas, and shared code must come before implementation tasks.
40911
- 3. **Each task is independently executable given prior tasks.** An agent working on task N must be able to complete it assuming tasks 1 through N-1 are already done.
40912
- 4. **Prefer focused, well-scoped tasks.** Each task should do one logical unit of work.
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
40913
41389
 
40914
41390
  ## Output Format
40915
41391
 
@@ -40922,7 +41398,7 @@ Your entire response must be a single JSON object — no text before it, no text
40922
41398
  "tasks": [
40923
41399
  {
40924
41400
  "title": "string",
40925
- "description": "string (detailed implementation guide: what to do, where to do it, how to do it, and boundaries)",
41401
+ "description": "string (detailed implementation guide: what, where, how, boundaries)",
40926
41402
  "assigneeRole": "BACKEND | FRONTEND | QA | PM | DESIGN",
40927
41403
  "priority": "CRITICAL | HIGH | MEDIUM | LOW",
40928
41404
  "labels": ["string"],
@@ -40943,89 +41419,6 @@ IMPORTANT: Tasks are executed sequentially by a single agent. The array order IS
40943
41419
  return prompt;
40944
41420
  }
40945
41421
 
40946
- // ../sdk/src/planning/agents/tech-lead.ts
40947
- function buildTechLeadPrompt(input) {
40948
- let prompt = `# Role: Senior Tech Lead
40949
-
40950
- 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.
40951
-
40952
- ## CEO Directive
40953
- > ${input.directive}
40954
- `;
40955
- if (input.feedback) {
40956
- prompt += `
40957
- ## CEO Feedback on Previous Plan
40958
- > ${input.feedback}
40959
-
40960
- IMPORTANT: Incorporate this feedback into your task breakdown. The CEO has reviewed a previous plan and wants changes.
40961
- `;
40962
- }
40963
- prompt += `
40964
- ## Project Context
40965
- ${input.projectContext || "No project context available."}
40966
-
40967
- ## Codebase Structure
40968
- ${input.codebaseIndex || "No codebase index available."}
40969
-
40970
- ## Your Task
40971
-
40972
- Analyze the CEO's directive and produce a detailed task breakdown. For each task:
40973
-
40974
- 1. **Title** — Clear, action-oriented (e.g., "Implement user registration API endpoint")
40975
- 2. **Description** — A detailed, actionable implementation guide (see description requirements below)
40976
- 3. **Assignee Role** — Who should work on this: BACKEND, FRONTEND, QA, PM, or DESIGN
40977
- 4. **Priority** — HIGH, MEDIUM, or LOW based on business impact
40978
- 5. **Labels** — Relevant tags (e.g., "api", "database", "ui", "auth")
40979
- 6. **Acceptance Criteria** — Specific, testable conditions for completion
40980
-
40981
- Think about:
40982
- - What existing code can be reused or extended
40983
- - Which tasks are independent vs. dependent
40984
- - What the right granularity is (not too big, not too small)
40985
- - What risks or unknowns exist
40986
-
40987
- ## CRITICAL: Task Description Requirements
40988
-
40989
- 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.
40990
-
40991
- Each description MUST include:
40992
- 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.
40993
- 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.
40994
- 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.
40995
- 4. **Boundaries** — Clarify what is NOT in scope for this task to prevent overlap with other tasks.
40996
-
40997
- Bad example: "Add authentication to the API."
40998
- 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."
40999
-
41000
- ## CRITICAL: Task Ordering Rules
41001
-
41002
- 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:
41003
-
41004
- 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.
41005
- 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.
41006
- 3. **Logical ordering matters.** Tasks are dispatched in the order they appear. Ensure dependent tasks come after their prerequisites.
41007
- 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.
41008
-
41009
- ## Output Format
41010
-
41011
- 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:
41012
-
41013
- {
41014
- "tasks": [
41015
- {
41016
- "title": "string",
41017
- "description": "string (detailed implementation guide: what to do, where to do it, how to do it, and boundaries — see description requirements above)",
41018
- "assigneeRole": "BACKEND | FRONTEND | QA | PM | DESIGN",
41019
- "priority": "HIGH | MEDIUM | LOW",
41020
- "labels": ["string"],
41021
- "acceptanceCriteria": ["string"]
41022
- }
41023
- ],
41024
- "technicalNotes": "string (brief notes on architecture decisions, risks, or considerations for the Architect phase)"
41025
- }`;
41026
- return prompt;
41027
- }
41028
-
41029
41422
  // ../sdk/src/planning/planning-meeting.ts
41030
41423
  import { existsSync as existsSync10, readFileSync as readFileSync9 } from "node:fs";
41031
41424
 
@@ -41043,52 +41436,33 @@ class PlanningMeeting {
41043
41436
  async run(directive, feedback) {
41044
41437
  const projectContext = this.getProjectContext();
41045
41438
  const codebaseIndex = this.getCodebaseIndex();
41046
- this.log("Phase 1/4: Tech Lead analyzing directive...", "info");
41047
- const techLeadPrompt = buildTechLeadPrompt({
41439
+ this.log("Phase 1/2: Planner building sprint plan...", "info");
41440
+ const plannerPrompt = buildPlannerPrompt({
41048
41441
  directive,
41049
41442
  projectContext,
41050
41443
  codebaseIndex,
41051
41444
  feedback
41052
41445
  });
41053
- const techLeadOutput = await this.aiRunner.run(techLeadPrompt);
41054
- this.log("Tech Lead phase complete.", "success");
41055
- this.log("Phase 2/4: Architect refining task breakdown...", "info");
41056
- const architectPrompt = buildArchitectPrompt({
41057
- directive,
41058
- projectContext,
41059
- techLeadOutput,
41060
- feedback
41061
- });
41062
- const architectOutput = await this.aiRunner.run(architectPrompt);
41063
- this.log("Architect phase complete.", "success");
41064
- this.log("Phase 3/4: Sprint Organizer finalizing plan...", "info");
41065
- const sprintOrganizerPrompt = buildSprintOrganizerPrompt({
41066
- directive,
41067
- architectOutput,
41068
- feedback
41069
- });
41070
- const sprintOrganizerOutput = await this.aiRunner.run(sprintOrganizerPrompt);
41071
- this.log("Sprint Organizer phase complete.", "success");
41072
- 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");
41073
41449
  const crossTaskReviewerPrompt = buildCrossTaskReviewerPrompt({
41074
41450
  directive,
41075
41451
  projectContext,
41076
- sprintOrganizerOutput,
41452
+ plannerOutput,
41077
41453
  feedback
41078
41454
  });
41079
- const crossTaskReviewOutput = await this.aiRunner.run(crossTaskReviewerPrompt);
41080
- this.log("Cross-Task Review phase complete.", "success");
41081
- const plan = parseSprintPlanFromAI(crossTaskReviewOutput, directive);
41455
+ const reviewOutput = await this.aiRunner.run(crossTaskReviewerPrompt);
41456
+ this.log("Review phase complete.", "success");
41457
+ const plan = parseSprintPlanFromAI(reviewOutput, directive);
41082
41458
  if (feedback) {
41083
41459
  plan.feedback = feedback;
41084
41460
  }
41085
41461
  return {
41086
41462
  plan,
41087
41463
  phaseOutputs: {
41088
- techLead: techLeadOutput,
41089
- architect: architectOutput,
41090
- sprintOrganizer: sprintOrganizerOutput,
41091
- crossTaskReview: crossTaskReviewOutput
41464
+ planner: plannerOutput,
41465
+ review: reviewOutput
41092
41466
  }
41093
41467
  };
41094
41468
  }
@@ -41864,8 +42238,8 @@ function showHelp() {
41864
42238
  ${c.dim("Any other input will be sent as a prompt to the AI.")}
41865
42239
  `);
41866
42240
  }
41867
- function showHistory(session, args) {
41868
- const historyManager = session.getHistoryManager();
42241
+ function showHistory(session2, args) {
42242
+ const historyManager = session2.getHistoryManager();
41869
42243
  const limit = args ? parseInt(args, 10) : 10;
41870
42244
  const sessions = historyManager.listSessions({
41871
42245
  limit: Number.isNaN(limit) ? 10 : limit
@@ -41884,7 +42258,7 @@ function showHistory(session, args) {
41884
42258
  const dateStr = date5.toLocaleDateString();
41885
42259
  const timeStr = date5.toLocaleTimeString();
41886
42260
  const msgCount = sess.messages.length;
41887
- const isCurrent = sess.id === session.getSessionId();
42261
+ const isCurrent = sess.id === session2.getSessionId();
41888
42262
  const marker = isCurrent ? c.success("*") : " ";
41889
42263
  console.log(` ${marker} ${c.cyan(sess.id)} ${c.dim(`- ${dateStr} ${timeStr} (${msgCount} messages)`)}`);
41890
42264
  if (sess.messages.length > 0) {
@@ -41905,7 +42279,7 @@ var init_commands = __esm(() => {
41905
42279
  name: "exit",
41906
42280
  aliases: ["quit", "q"],
41907
42281
  description: "Exit interactive mode",
41908
- execute: (session) => session.shutdown()
42282
+ execute: (session2) => session2.shutdown()
41909
42283
  },
41910
42284
  {
41911
42285
  name: "clear",
@@ -41923,21 +42297,21 @@ var init_commands = __esm(() => {
41923
42297
  name: "reset",
41924
42298
  aliases: ["r"],
41925
42299
  description: "Reset conversation context",
41926
- execute: (session) => session.resetContext()
42300
+ execute: (session2) => session2.resetContext()
41927
42301
  },
41928
42302
  {
41929
42303
  name: "history",
41930
42304
  aliases: ["hist"],
41931
42305
  description: "List recent sessions",
41932
- execute: (session, args) => showHistory(session, args)
42306
+ execute: (session2, args) => showHistory(session2, args)
41933
42307
  },
41934
42308
  {
41935
42309
  name: "session",
41936
42310
  aliases: ["sid"],
41937
42311
  description: "Show current session ID",
41938
- execute: (session) => {
42312
+ execute: (session2) => {
41939
42313
  console.log(`
41940
- ${c.dim("Session ID:")} ${c.cyan(session.getSessionId())}
42314
+ ${c.dim("Session ID:")} ${c.cyan(session2.getSessionId())}
41941
42315
  `);
41942
42316
  }
41943
42317
  }
@@ -43030,9 +43404,137 @@ function showDocsSyncHelp() {
43030
43404
  }
43031
43405
  // src/commands/exec.ts
43032
43406
  init_index_node();
43033
- init_progress_renderer();
43407
+ import { randomUUID as randomUUID2 } from "node:crypto";
43034
43408
  import { parseArgs as parseArgs2 } from "node:util";
43035
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
+
43036
43538
  // src/commands/exec-sessions.ts
43037
43539
  init_index_node();
43038
43540
  function formatRelativeTime(timestamp) {
@@ -43070,11 +43572,11 @@ class SessionCommands {
43070
43572
  console.log(`
43071
43573
  ${c.primary("Recent Exec Sessions:")}
43072
43574
  `);
43073
- for (const session of sessions.slice(0, 10)) {
43074
- const shortId = this.getShortId(session.id);
43075
- const age = formatRelativeTime(session.updatedAt);
43076
- const msgCount = session.messages.length;
43077
- const firstUserMsg = session.messages.find((m) => m.role === "user");
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");
43078
43580
  const preview = firstUserMsg ? firstUserMsg.content.slice(0, 50).replace(/\n/g, " ") : "(empty session)";
43079
43581
  console.log(` ${c.cyan(shortId)} ${c.gray("-")} ${preview}${firstUserMsg && firstUserMsg.content.length > 50 ? "..." : ""}`);
43080
43582
  console.log(` ${c.dim(`${msgCount} messages • ${age}`)}`);
@@ -43094,8 +43596,8 @@ class SessionCommands {
43094
43596
  `);
43095
43597
  return;
43096
43598
  }
43097
- const session = this.historyManager.findSessionByPartialId(sessionId);
43098
- if (!session) {
43599
+ const session2 = this.historyManager.findSessionByPartialId(sessionId);
43600
+ if (!session2) {
43099
43601
  console.error(`
43100
43602
  ${c.error("Error:")} Session ${c.cyan(sessionId)} not found
43101
43603
  `);
@@ -43104,18 +43606,18 @@ class SessionCommands {
43104
43606
  return;
43105
43607
  }
43106
43608
  console.log(`
43107
- ${c.primary("Session:")} ${c.cyan(session.id)}`);
43108
- console.log(` ${c.dim(`Created: ${new Date(session.createdAt).toLocaleString()}`)}`);
43109
- console.log(` ${c.dim(`Model: ${session.metadata.model} (${session.metadata.provider})`)}
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})`)}
43110
43612
  `);
43111
- if (session.messages.length === 0) {
43613
+ if (session2.messages.length === 0) {
43112
43614
  console.log(` ${c.dim("(No messages in this session)")}
43113
43615
  `);
43114
43616
  return;
43115
43617
  }
43116
43618
  console.log(c.dim(" ─".repeat(30)));
43117
43619
  console.log();
43118
- for (const message of session.messages) {
43620
+ for (const message of session2.messages) {
43119
43621
  const role = message.role === "user" ? c.cyan("You") : c.green("AI");
43120
43622
  const content = message.content;
43121
43623
  console.log(` ${role}:`);
@@ -43136,17 +43638,17 @@ class SessionCommands {
43136
43638
  `);
43137
43639
  return;
43138
43640
  }
43139
- const session = this.historyManager.findSessionByPartialId(sessionId);
43140
- if (!session) {
43641
+ const session2 = this.historyManager.findSessionByPartialId(sessionId);
43642
+ if (!session2) {
43141
43643
  console.error(`
43142
43644
  ${c.error("Error:")} Session ${c.cyan(sessionId)} not found
43143
43645
  `);
43144
43646
  return;
43145
43647
  }
43146
- const deleted = this.historyManager.deleteSession(session.id);
43648
+ const deleted = this.historyManager.deleteSession(session2.id);
43147
43649
  if (deleted) {
43148
43650
  console.log(`
43149
- ${c.success("✔")} Deleted session ${c.cyan(this.getShortId(session.id))}
43651
+ ${c.success("✔")} Deleted session ${c.cyan(this.getShortId(session2.id))}
43150
43652
  `);
43151
43653
  } else {
43152
43654
  console.error(`
@@ -43206,11 +43708,17 @@ async function execCommand(args) {
43206
43708
  "no-stream": { type: "boolean" },
43207
43709
  "no-status": { type: "boolean" },
43208
43710
  interactive: { type: "boolean", short: "i" },
43209
- session: { type: "string", short: "s" }
43711
+ session: { type: "string", short: "s" },
43712
+ "json-stream": { type: "boolean" }
43210
43713
  },
43211
43714
  strict: false
43212
43715
  });
43716
+ const jsonStream = values["json-stream"];
43213
43717
  const projectPath = values.dir || process.cwd();
43718
+ if (jsonStream) {
43719
+ await execJsonStream(values, positionals, projectPath);
43720
+ return;
43721
+ }
43214
43722
  requireInitialization(projectPath, "exec");
43215
43723
  if (positionals[0] === "sessions") {
43216
43724
  const sessionAction = positionals[1];
@@ -43241,13 +43749,13 @@ async function execCommand(args) {
43241
43749
  const sessionId = values.session;
43242
43750
  if (isInteractive) {
43243
43751
  const { InteractiveSession: InteractiveSession2 } = await Promise.resolve().then(() => (init_interactive_session(), exports_interactive_session));
43244
- const session = new InteractiveSession2({
43752
+ const session2 = new InteractiveSession2({
43245
43753
  projectPath,
43246
43754
  provider,
43247
43755
  model,
43248
43756
  sessionId
43249
43757
  });
43250
- await session.start();
43758
+ await session2.start();
43251
43759
  return;
43252
43760
  }
43253
43761
  const promptInput = positionals.join(" ");
@@ -43338,6 +43846,67 @@ async function execCommand(args) {
43338
43846
  process.exit(1);
43339
43847
  }
43340
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
+ }
43341
43910
  // src/commands/help.ts
43342
43911
  init_index_node();
43343
43912
  function showHelp2() {
@@ -43527,12 +44096,7 @@ async function initCommand() {
43527
44096
  init_index_node();
43528
44097
  import { parseArgs as parseArgs4 } from "node:util";
43529
44098
  function normalizePlanIdArgs(args) {
43530
- const planIdFlags = new Set([
43531
- "--approve",
43532
- "--reject",
43533
- "--cancel",
43534
- "--show"
43535
- ]);
44099
+ const planIdFlags = new Set(["--approve", "--reject", "--cancel", "--show"]);
43536
44100
  const result = [];
43537
44101
  let i = 0;
43538
44102
  while (i < args.length) {
@@ -44459,10 +45023,11 @@ function versionCommand() {
44459
45023
  console.log("");
44460
45024
  }
44461
45025
  // src/cli.ts
45026
+ var isJsonStream = process.argv.includes("--json-stream");
44462
45027
  async function main() {
44463
45028
  const command = process.argv[2];
44464
45029
  const args = process.argv.slice(3);
44465
- if (command !== "exec") {
45030
+ if (command !== "exec" && !isJsonStream) {
44466
45031
  printBanner();
44467
45032
  }
44468
45033
  switch (command) {
@@ -44506,6 +45071,11 @@ async function main() {
44506
45071
  }
44507
45072
  }
44508
45073
  main().catch((err) => {
45074
+ if (isJsonStream) {
45075
+ process.stderr.write(`${JSON.stringify({ fatal: true, error: err.message })}
45076
+ `);
45077
+ process.exit(1);
45078
+ }
44509
45079
  console.error(`
44510
45080
  ${c.error("✖ Fatal Error")} ${c.red(err.message)}`);
44511
45081
  process.exit(1);