ReviewOS

also looking at this

stacks/uplink

fix(app): a fresh install now either works or says why

#8
Merged glennmichael123 wants to merge fix/setup-blockers into main
16 files +512 -75

Review threads live on the whole diff, not on one commit, so none are shown here - a thread's line means something in the branch's final form, and painting it into an intermediate step would put it on code it is not about.

app/Uplink/uplink.tsmodified+28-12
Changes to app/Uplink/uplink.ts
@@ -392,19 +392,28 @@ export class Uplink {
392392 await this.begin(state, next)
393393 }
394394
395 /**
396 * Answers a control word. `reply` reports whether it delivered, which
397 * `finish` acts on for a real answer; a control reply is said and forgotten,
398 * so the result is deliberately dropped here.
399 */
395400 private async control(command: ControlCommand, target: ReplyTarget): Promise<void> {
396401 const state = this.chat(target.chatGuid)
397402
398403 switch (command) {
399404 case 'help':
400 return this.reply(target, HELP_TEXT)
405 await this.reply(target, HELP_TEXT)
406 return
401407
402408 case 'ping':
403 return this.reply(target, `pong (up ${formatDuration(this.now() - this.startedAt)})`)
409 await this.reply(target, `pong (up ${formatDuration(this.now() - this.startedAt)})`)
410 return
404411
405412 case 'status': {
406 if (!state.active)
407 return this.reply(target, 'Idle. Text me a question or a task.')
413 if (!state.active) {
414 await this.reply(target, 'Idle. Text me a question or a task.')
415 return
416 }
408417 const active = state.active
409418 const lines = [
410419 `Working ${formatDuration(this.now() - active.startedAt)} on: ${truncate(active.prompt, 80)}`,
@@ -412,32 +421,39 @@ export class Uplink {
412421 ]
413422 if (state.queue.length > 0)
414423 lines.push(`${state.queue.length} queued.`)
415 return this.reply(target, lines.join('\n'))
424 await this.reply(target, lines.join('\n'))
425 return
416426 }
417427
418428 case 'stop': {
419429 const queued = state.queue.splice(0)
420430 for (const job of queued)
421431 await this.deps.store.updateRun(job.runId, { status: 'stopped', finishedAt: this.now() })
422 if (!state.active)
423 return this.reply(target, queued.length > 0 ? `Cleared ${queued.length} queued.` : 'Nothing running.')
432 if (!state.active) {
433 await this.reply(target, queued.length > 0 ? `Cleared ${queued.length} queued.` : 'Nothing running.')
434 return
435 }
424436 state.active.stoppedByUser = true
425437 state.active.run.cancel()
426438 const extra = queued.length > 0 ? ` and cleared ${queued.length} queued` : ''
427 return this.reply(target, `Stopped: ${truncate(state.active.prompt, 60)}${extra}.`)
439 await this.reply(target, `Stopped: ${truncate(state.active.prompt, 60)}${extra}.`)
440 return
428441 }
429442
430443 case 'new': {
431444 const conversation = await this.conversation(target)
432445 await this.deps.store.saveConversation({ ...conversation, sessionId: null, cwd: null, moreText: null })
433 return this.reply(target, 'Fresh start. Your next text begins a new conversation.')
446 await this.reply(target, 'Fresh start. Your next text begins a new conversation.')
447 return
434448 }
435449
436450 case 'more': {
437451 const conversation = await this.conversation(target)
438 if (!conversation.moreText)
439 return this.reply(target, 'Nothing more to send.')
440 return this.reply(target, conversation.moreText, { keepRest: true })
452 if (!conversation.moreText) {
453 await this.reply(target, 'Nothing more to send.')
454 return
455 }
456 await this.reply(target, conversation.moreText, { keepRest: true })
441457 }
442458 }
443459 }