@davvidbaker/flambe-cli 0.1.2 → 0.1.3

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@davvidbaker/flambe-cli",
3
- "version": "0.1.2",
3
+ "version": "0.1.3",
4
4
  "description": "CLI for streaming coding-agent activity into Flambe",
5
5
  "type": "module",
6
6
  "bin": {
@@ -257,6 +257,18 @@ async function dispatch(store, req, url, body, { auth, agent }) {
257
257
  }
258
258
 
259
259
  if (method === 'POST' && path === '/api/activities') {
260
+ if (!Object.hasOwn(body, 'event') && auth.tokenName !== null) {
261
+ const activity = body.activity ?? {};
262
+ const planned = executeCommand(store, userId, 'plan', {
263
+ trace_id: body.trace_id, name: activity.name, description: activity.description,
264
+ weight: activity.weight, category_ids: activity.categories,
265
+ scheduled_start: activity.scheduled_start_integer,
266
+ scheduled_end: activity.scheduled_end_integer,
267
+ }, agent);
268
+ return { status: 201, json: { data: {
269
+ activity: store.getActivity(userId, planned.activity_id), event: null,
270
+ } } };
271
+ }
260
272
  if (auth.tokenName !== null) {
261
273
  const activity = body.activity ?? {};
262
274
  const folded = executeCommand(store, userId, 'start', {
@@ -278,7 +290,7 @@ async function dispatch(store, req, url, body, { auth, agent }) {
278
290
  traceId: body.trace_id,
279
291
  threadId: body.thread_id,
280
292
  activity: body.activity ?? {},
281
- event: body.event ?? {},
293
+ event: body.event,
282
294
  agent,
283
295
  });
284
296
  if (result.error) return { status: 404, json: { error: 'NOT_FOUND' } };
@@ -246,7 +246,9 @@ export class LocalStore {
246
246
  const events = this.db.prepare(`
247
247
  SELECT events.*, activities.name AS activity_name, activities.parent_id,
248
248
  activities.thread_id, activities.weight, activities.agent_id, activities.agent_name,
249
- activities.description AS activity_description
249
+ activities.description AS activity_description,
250
+ activities.scheduled_start_ms, activities.scheduled_end_ms,
251
+ activities.proposed_by_agent_id, activities.proposed_by_agent_name
250
252
  FROM events
251
253
  LEFT JOIN activities ON activities.id = events.activity_id
252
254
  WHERE events.trace_id = ?
@@ -258,6 +260,7 @@ export class LocalStore {
258
260
  name: trace.name,
259
261
  threads: threads.map(thread => ({ id: thread.id, name: thread.name, rank: thread.rank })),
260
262
  events: events.map(event => this.#eventPayload(event)),
263
+ unstarted: this.listUnstarted(trace.id).map(activity => this.#traceActivityPayload(activity)),
261
264
  };
262
265
  }
263
266
 
@@ -437,7 +440,19 @@ export class LocalStore {
437
440
  * rules apply: an absent parent_id infers this agent's newest active activity, a child
438
441
  * lives in its parent's thread and inherits categories, and thread_id may be omitted.
439
442
  */
440
- createActivity(userId, { traceId, threadId, activity, event, agent, reduce = false }) {
443
+ createActivity(userId, options) {
444
+ this.db.exec('SAVEPOINT create_activity');
445
+ try {
446
+ const result = this.#createActivity(userId, options);
447
+ this.db.exec('RELEASE create_activity');
448
+ return result;
449
+ } catch (error) {
450
+ this.db.exec('ROLLBACK TO create_activity; RELEASE create_activity');
451
+ throw error;
452
+ }
453
+ }
454
+
455
+ #createActivity(userId, { traceId, threadId, activity, event, agent, reduce = false }) {
441
456
  const trace = this.db.prepare('SELECT id FROM traces WHERE id = ? AND user_id = ?').get(Number(traceId), userId);
442
457
  if (!trace) return { error: 'not_found' };
443
458
 
@@ -507,8 +522,8 @@ export class LocalStore {
507
522
  activity.weight ?? null,
508
523
  agentColumns.agent_id,
509
524
  agentColumns.agent_name,
510
- activity.scheduled_start_ms ?? null,
511
- activity.scheduled_end_ms ?? null,
525
+ activity.scheduled_start_integer ?? activity.scheduled_start_ms ?? null,
526
+ activity.scheduled_end_integer ?? activity.scheduled_end_ms ?? null,
512
527
  activity.proposed_by_agent_id ?? agentColumns.agent_id,
513
528
  activity.proposed_by_agent_name ?? agentColumns.agent_name,
514
529
  randomUUID(),
@@ -520,11 +535,15 @@ export class LocalStore {
520
535
  ).run(activityId, categoryId);
521
536
  }
522
537
 
523
- const timestamp = Number(event.timestamp_integer);
524
- const eventRow = this.db.prepare(`
525
- INSERT INTO events (trace_id, activity_id, timestamp_ms, phase, message, export_id)
526
- VALUES (?, ?, ?, ?, ?, ?)
527
- `).run(thread.trace_id, activityId, timestamp, event.phase, event.message ?? null, randomUUID());
538
+ let createdEvent = null;
539
+ if (event) {
540
+ const timestamp = Number(event.timestamp_integer);
541
+ const eventRow = this.db.prepare(`
542
+ INSERT INTO events (trace_id, activity_id, timestamp_ms, phase, message, export_id)
543
+ VALUES (?, ?, ?, ?, ?, ?)
544
+ `).run(thread.trace_id, activityId, timestamp, event.phase, event.message ?? null, randomUUID());
545
+ createdEvent = { id: Number(eventRow.lastInsertRowid), phase: event.phase };
546
+ }
528
547
 
529
548
  return {
530
549
  activity: {
@@ -535,7 +554,7 @@ export class LocalStore {
535
554
  parent_id: parentId,
536
555
  thread_id: thread.id,
537
556
  },
538
- event: { id: Number(eventRow.lastInsertRowid), phase: event.phase },
557
+ event: createdEvent,
539
558
  ...(reduce ? { reducer: notes } : {}),
540
559
  };
541
560
  }
@@ -566,7 +585,7 @@ export class LocalStore {
566
585
  AND NOT EXISTS (
567
586
  SELECT 1 FROM events
568
587
  WHERE events.activity_id = activities.id
569
- AND events.phase IN ('B','R','X','S','E','J','V')
588
+ AND events.phase IN ('B','Q','R','X','S','E','J','V')
570
589
  )
571
590
  ORDER BY activities.id
572
591
  `).all(Number(traceId));
@@ -878,27 +897,36 @@ export class LocalStore {
878
897
  }
879
898
 
880
899
  #eventPayload(event) {
881
- const categoryIds = event.activity_id == null
882
- ? []
883
- : this.db.prepare(
884
- 'SELECT category_id FROM activities_categories WHERE activity_id = ?',
885
- ).all(event.activity_id).map(row => row.category_id);
886
-
887
900
  return {
888
901
  id: event.id,
889
902
  timestamp: isoFromMs(event.timestamp_ms),
890
903
  phase: event.phase,
891
904
  message: event.message ?? null,
892
- activity: event.activity_id == null ? null : {
893
- id: event.activity_id,
894
- name: event.activity_name,
895
- agent_id: event.agent_id ?? null,
896
- agent_name: event.agent_name ?? null,
897
- parent_id: event.parent_id ?? null,
898
- thread: { id: event.thread_id },
899
- categories: categoryIds,
900
- weight: event.weight ?? null,
901
- },
905
+ activity: event.activity_id == null ? null : this.#traceActivityPayload({
906
+ ...event, id: event.activity_id, name: event.activity_name,
907
+ description: event.activity_description,
908
+ }),
909
+ };
910
+ }
911
+
912
+ #traceActivityPayload(activity) {
913
+ const categoryIds = this.db.prepare(
914
+ 'SELECT category_id FROM activities_categories WHERE activity_id = ?',
915
+ ).all(activity.id).map(row => row.category_id);
916
+ return {
917
+ id: activity.id,
918
+ name: activity.name,
919
+ agent_id: activity.agent_id ?? null,
920
+ agent_name: activity.agent_name ?? null,
921
+ parent_id: activity.parent_id ?? null,
922
+ thread: { id: activity.thread_id },
923
+ categories: categoryIds,
924
+ weight: activity.weight ?? null,
925
+ description: activity.description ?? null,
926
+ scheduled_start: activity.scheduled_start_ms ?? null,
927
+ scheduled_end: activity.scheduled_end_ms ?? null,
928
+ proposed_by_agent_id: activity.proposed_by_agent_id ?? null,
929
+ proposed_by_agent_name: activity.proposed_by_agent_name ?? null,
902
930
  };
903
931
  }
904
932