@pebblehouse/odin-cli 0.2.0 → 0.2.2

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.
Files changed (2) hide show
  1. package/dist/index.js +37 -17
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -37,7 +37,7 @@ function clearCredentials() {
37
37
  // src/auth/login.ts
38
38
  var API_URL = process.env.ODIN_API_URL ?? "https://www.odin.mu";
39
39
  async function login() {
40
- return new Promise((resolve, reject) => {
40
+ return new Promise((resolve2, reject) => {
41
41
  const server = createServer(async (req, res) => {
42
42
  if (req.method === "POST" && req.url?.startsWith("/callback")) {
43
43
  let body = "";
@@ -70,7 +70,7 @@ async function login() {
70
70
  </div>
71
71
  </body></html>`);
72
72
  server.close();
73
- resolve();
73
+ resolve2();
74
74
  } else {
75
75
  res.writeHead(404);
76
76
  res.end();
@@ -336,24 +336,28 @@ plansCmd.command("delete <slug> <id>").description("Delete a plan").action(async
336
336
  process.stdout.write(JSON.stringify(res) + "\n");
337
337
  if (res.error) process.exit(1);
338
338
  });
339
- plansCmd.command("add-phase <slug> <planId> <title>").description("Add a phase to a plan").requiredOption("--phase-number <number>", "Phase number", parseInt).option("--description <description>", "Phase description").action(async (slug, planId, title, opts) => {
339
+ plansCmd.command("add-phase <slug> <planId> <title>").description("Add a phase to a plan").requiredOption("--phase-number <number>", "Phase number", parseInt).option("--description <description>", "Phase description").option("--detail-type <type>", "Detail type (e.g. agent_spec, document)").option("--detail-id <id>", "Detail ID (UUID of linked entity)").action(async (slug, planId, title, opts) => {
340
340
  const res = await apiRequest(`/pebbles/${slug}/plans/${planId}/phases`, {
341
341
  method: "POST",
342
342
  body: {
343
343
  phase_number: opts.phaseNumber,
344
344
  title,
345
- description: opts.description ?? null
345
+ description: opts.description ?? null,
346
+ detail_type: opts.detailType ?? null,
347
+ detail_id: opts.detailId ?? null
346
348
  }
347
349
  });
348
350
  process.stdout.write(JSON.stringify(res) + "\n");
349
351
  if (res.error) process.exit(1);
350
352
  });
351
- plansCmd.command("update-phase <slug> <planId> <phaseId>").description("Update a phase").option("--title <title>", "Phase title").option("--status <status>", "Phase status (pending|in_progress|completed|skipped)").option("--notes <notes>", "Phase notes").option("--description <description>", "Phase description").action(async (slug, planId, phaseId, opts) => {
353
+ plansCmd.command("update-phase <slug> <planId> <phaseId>").description("Update a phase").option("--title <title>", "Phase title").option("--status <status>", "Phase status (pending|in_progress|completed|skipped)").option("--notes <notes>", "Phase notes").option("--description <description>", "Phase description").option("--detail-type <type>", "Detail type (e.g. agent_spec, document)").option("--detail-id <id>", "Detail ID (UUID of linked entity)").action(async (slug, planId, phaseId, opts) => {
352
354
  const body = {};
353
355
  if (opts.title) body.title = opts.title;
354
356
  if (opts.status) body.status = opts.status;
355
357
  if (opts.notes) body.notes = opts.notes;
356
358
  if (opts.description) body.description = opts.description;
359
+ if (opts.detailType) body.detail_type = opts.detailType;
360
+ if (opts.detailId) body.detail_id = opts.detailId;
357
361
  const res = await apiRequest(`/pebbles/${slug}/plans/${planId}/phases/${phaseId}`, {
358
362
  method: "PUT",
359
363
  body
@@ -371,6 +375,9 @@ plansCmd.command("delete-phase <slug> <planId> <phaseId>").description("Delete a
371
375
 
372
376
  // src/commands/conversations.ts
373
377
  import { Command as Command8 } from "commander";
378
+ function collect(value, previous) {
379
+ return previous.concat([value]);
380
+ }
374
381
  var conversationsCmd = new Command8("conversations").description("Manage conversations");
375
382
  conversationsCmd.command("list <slug>").description("List conversations for a pebble").action(async (slug) => {
376
383
  const res = await apiRequest(`/pebbles/${slug}/conversations`);
@@ -382,12 +389,14 @@ conversationsCmd.command("get <slug> <id>").description("Get a conversation by I
382
389
  process.stdout.write(JSON.stringify(res) + "\n");
383
390
  if (res.error) process.exit(1);
384
391
  });
385
- conversationsCmd.command("create <slug> <title>").description("Create a conversation").option("--summary <summary>", "Conversation summary").option("--source-url <url>", "Source URL").option("--session-id <id>", "Link to active session").action(async (slug, title, opts) => {
392
+ conversationsCmd.command("create <slug> <title>").description("Create a conversation").option("--summary <summary>", "Conversation summary").option("--key-point <point>", "Key point (repeatable)", collect, []).option("--decision <decision>", "Decision made (repeatable)", collect, []).option("--source-url <url>", "Source URL").option("--session-id <id>", "Link to active session").action(async (slug, title, opts) => {
386
393
  const res = await apiRequest(`/pebbles/${slug}/conversations`, {
387
394
  method: "POST",
388
395
  body: {
389
396
  title,
390
397
  summary: opts.summary ?? null,
398
+ key_points: opts.keyPoint,
399
+ decisions_made: opts.decision,
391
400
  source_url: opts.sourceUrl ?? null,
392
401
  session_id: opts.sessionId ?? null
393
402
  }
@@ -395,10 +404,12 @@ conversationsCmd.command("create <slug> <title>").description("Create a conversa
395
404
  process.stdout.write(JSON.stringify(res) + "\n");
396
405
  if (res.error) process.exit(1);
397
406
  });
398
- conversationsCmd.command("update <slug> <id>").description("Update a conversation").option("--title <title>", "New title").option("--summary <summary>", "New summary").option("--source-url <url>", "New source URL").action(async (slug, id, opts) => {
407
+ conversationsCmd.command("update <slug> <id>").description("Update a conversation").option("--title <title>", "New title").option("--summary <summary>", "New summary").option("--key-point <point>", "Key point (repeatable, replaces existing)", collect, []).option("--decision <decision>", "Decision made (repeatable, replaces existing)", collect, []).option("--source-url <url>", "New source URL").action(async (slug, id, opts) => {
399
408
  const body = {};
400
409
  if (opts.title) body.title = opts.title;
401
410
  if (opts.summary) body.summary = opts.summary;
411
+ if (opts.keyPoint.length > 0) body.key_points = opts.keyPoint;
412
+ if (opts.decision.length > 0) body.decisions_made = opts.decision;
402
413
  if (opts.sourceUrl) body.source_url = opts.sourceUrl;
403
414
  const res = await apiRequest(`/pebbles/${slug}/conversations/${id}`, {
404
415
  method: "PUT",
@@ -418,24 +429,27 @@ conversationsCmd.command("delete <slug> <id>").description("Delete a conversatio
418
429
  // src/commands/specs.ts
419
430
  import { Command as Command9 } from "commander";
420
431
  import { readFileSync as readFileSync4 } from "fs";
421
- var specsCmd = new Command9("specs").description("Manage superpowers specs");
422
- specsCmd.command("list <slug>").description("List specs for a pebble").action(async (slug) => {
423
- const res = await apiRequest(`/pebbles/${slug}/superpowers-specs`);
432
+ var specsCmd = new Command9("specs").description("Manage agent specs");
433
+ specsCmd.command("list <slug>").description("List specs for a pebble").option("--source <source>", "Filter by source (claude-code, superpowers, etc.)").action(async (slug, opts) => {
434
+ const params = {};
435
+ if (opts.source) params.source = opts.source;
436
+ const res = await apiRequest(`/pebbles/${slug}/agent-specs`, { params });
424
437
  process.stdout.write(JSON.stringify(res) + "\n");
425
438
  if (res.error) process.exit(1);
426
439
  });
427
440
  specsCmd.command("get <slug> <id>").description("Get a spec by ID").action(async (slug, id) => {
428
- const res = await apiRequest(`/pebbles/${slug}/superpowers-specs/${id}`);
441
+ const res = await apiRequest(`/pebbles/${slug}/agent-specs/${id}`);
429
442
  process.stdout.write(JSON.stringify(res) + "\n");
430
443
  if (res.error) process.exit(1);
431
444
  });
432
- specsCmd.command("create <slug> <title>").description("Create a spec").requiredOption("--spec-type <type>", "Spec type (e.g. brainstorm, plan, research)").option("--content <content>", "Spec content").option("--file <path>", "Read content from file").option("--session-id <id>", "Link to active session").action(async (slug, title, opts) => {
445
+ specsCmd.command("create <slug> <title>").description("Create a spec").requiredOption("--spec-type <type>", "Spec type (e.g. brainstorm, plan, research)").option("--source <source>", "Source agent", "claude-code").option("--content <content>", "Spec content").option("--file <path>", "Read content from file").option("--session-id <id>", "Link to active session").action(async (slug, title, opts) => {
433
446
  const content = opts.file ? readFileSync4(opts.file, "utf-8") : opts.content ?? "";
434
- const res = await apiRequest(`/pebbles/${slug}/superpowers-specs`, {
447
+ const res = await apiRequest(`/pebbles/${slug}/agent-specs`, {
435
448
  method: "POST",
436
449
  body: {
437
450
  title,
438
451
  spec_type: opts.specType,
452
+ source: opts.source,
439
453
  content,
440
454
  session_id: opts.sessionId ?? null
441
455
  }
@@ -443,13 +457,14 @@ specsCmd.command("create <slug> <title>").description("Create a spec").requiredO
443
457
  process.stdout.write(JSON.stringify(res) + "\n");
444
458
  if (res.error) process.exit(1);
445
459
  });
446
- specsCmd.command("update <slug> <id>").description("Update a spec").option("--title <title>", "New title").option("--spec-type <type>", "New spec type").option("--content <content>", "New content").option("--file <path>", "Read content from file").action(async (slug, id, opts) => {
460
+ specsCmd.command("update <slug> <id>").description("Update a spec").option("--title <title>", "New title").option("--spec-type <type>", "New spec type").option("--source <source>", "New source").option("--content <content>", "New content").option("--file <path>", "Read content from file").action(async (slug, id, opts) => {
447
461
  const body = {};
448
462
  if (opts.title) body.title = opts.title;
449
463
  if (opts.specType) body.spec_type = opts.specType;
464
+ if (opts.source) body.source = opts.source;
450
465
  if (opts.file) body.content = readFileSync4(opts.file, "utf-8");
451
466
  else if (opts.content) body.content = opts.content;
452
- const res = await apiRequest(`/pebbles/${slug}/superpowers-specs/${id}`, {
467
+ const res = await apiRequest(`/pebbles/${slug}/agent-specs/${id}`, {
453
468
  method: "PUT",
454
469
  body
455
470
  });
@@ -457,7 +472,7 @@ specsCmd.command("update <slug> <id>").description("Update a spec").option("--ti
457
472
  if (res.error) process.exit(1);
458
473
  });
459
474
  specsCmd.command("delete <slug> <id>").description("Delete a spec").action(async (slug, id) => {
460
- const res = await apiRequest(`/pebbles/${slug}/superpowers-specs/${id}`, {
475
+ const res = await apiRequest(`/pebbles/${slug}/agent-specs/${id}`, {
461
476
  method: "DELETE"
462
477
  });
463
478
  process.stdout.write(JSON.stringify(res) + "\n");
@@ -498,10 +513,15 @@ versionsCmd.command("get <slug> <docType> <versionId>").description("Get a speci
498
513
  });
499
514
 
500
515
  // src/index.ts
516
+ import { readFileSync as readFileSync5 } from "fs";
517
+ import { fileURLToPath } from "url";
518
+ import { dirname, resolve } from "path";
519
+ var __dirname = dirname(fileURLToPath(import.meta.url));
520
+ var pkg = JSON.parse(readFileSync5(resolve(__dirname, "../package.json"), "utf-8"));
501
521
  var GOLD = "\x1B[33m";
502
522
  var DIM = "\x1B[2m";
503
523
  var RESET = "\x1B[0m";
504
- var VERSION = "0.2.0";
524
+ var VERSION = pkg.version;
505
525
  function printBanner() {
506
526
  const cwd = process.cwd();
507
527
  console.error(`${GOLD}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pebblehouse/odin-cli",
3
- "version": "0.2.0",
3
+ "version": "0.2.2",
4
4
  "type": "module",
5
5
  "description": "CLI for Odin — the knowledge backbone for Pebble House",
6
6
  "bin": {