@pebblehouse/odin-cli 0.4.2 → 0.5.0
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/dist/index.js +19 -184
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
// src/index.ts
|
|
4
|
-
import { Command as
|
|
4
|
+
import { Command as Command10 } from "commander";
|
|
5
5
|
|
|
6
6
|
// src/auth/login.ts
|
|
7
7
|
import { createServer } from "http";
|
|
@@ -327,42 +327,18 @@ decisionsCmd.command("log <slug> <title>").description("Log a decision").option(
|
|
|
327
327
|
|
|
328
328
|
// src/commands/context.ts
|
|
329
329
|
import { Command as Command4 } from "commander";
|
|
330
|
-
var contextCmd = new Command4("context").description("Get Tier 1 context for a pebble").argument("<slug>", "Pebble slug").
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
// src/commands/sessions.ts
|
|
339
|
-
import { Command as Command5 } from "commander";
|
|
340
|
-
var sessionsCmd = new Command5("sessions").description("Manage sessions");
|
|
341
|
-
sessionsCmd.command("start <slug>").description("Start a session").option("--source <source>", "Session source", "claude-code").action(async (slug, opts) => {
|
|
342
|
-
const res = await apiRequest("/sessions", {
|
|
343
|
-
method: "POST",
|
|
344
|
-
body: { pebble_slug: slug, source: opts.source }
|
|
345
|
-
});
|
|
346
|
-
process.stdout.write(JSON.stringify(res) + "\n");
|
|
347
|
-
if (res.error) process.exit(1);
|
|
348
|
-
});
|
|
349
|
-
sessionsCmd.command("list <slug>").description("List sessions for a pebble").action(async (slug) => {
|
|
350
|
-
const res = await apiRequest(`/sessions/by-pebble/${slug}`);
|
|
351
|
-
process.stdout.write(JSON.stringify(res) + "\n");
|
|
352
|
-
if (res.error) process.exit(1);
|
|
353
|
-
});
|
|
354
|
-
sessionsCmd.command("end <id>").description("End a session").option("--summary <summary>", "Session summary").option("--status <status>", "Final status", "completed").action(async (id, opts) => {
|
|
355
|
-
const res = await apiRequest(`/sessions/${id}`, {
|
|
356
|
-
method: "PUT",
|
|
357
|
-
body: { summary: opts.summary, status: opts.status }
|
|
358
|
-
});
|
|
359
|
-
process.stdout.write(JSON.stringify(res) + "\n");
|
|
360
|
-
if (res.error) process.exit(1);
|
|
330
|
+
var contextCmd = new Command4("context").description("Get Tier 1 context for a pebble").argument("<slug>", "Pebble slug").action(async (slug) => {
|
|
331
|
+
console.error(`[odin context] T1 context endpoint is being rebuilt (Phase 5).`);
|
|
332
|
+
console.error(`In the meantime, use:`);
|
|
333
|
+
console.error(` odin guidelines list`);
|
|
334
|
+
console.error(` odin docs get ${slug} <type>`);
|
|
335
|
+
console.error(` odin decisions list ${slug}`);
|
|
336
|
+
process.exit(0);
|
|
361
337
|
});
|
|
362
338
|
|
|
363
339
|
// src/commands/search.ts
|
|
364
|
-
import { Command as
|
|
365
|
-
var searchCmd = new
|
|
340
|
+
import { Command as Command5 } from "commander";
|
|
341
|
+
var searchCmd = new Command5("search").description("Full-text search across Odin").argument("<query>", "Search query").option("--pebble <slug>", "Scope to a pebble").action(async (query, opts) => {
|
|
366
342
|
const params = { q: query };
|
|
367
343
|
if (opts.pebble) params.pebble = opts.pebble;
|
|
368
344
|
const res = await apiRequest("/search", { params });
|
|
@@ -371,9 +347,9 @@ var searchCmd = new Command6("search").description("Full-text search across Odin
|
|
|
371
347
|
});
|
|
372
348
|
|
|
373
349
|
// src/commands/plans.ts
|
|
374
|
-
import { Command as
|
|
350
|
+
import { Command as Command6 } from "commander";
|
|
375
351
|
import { readFileSync as readFileSync4 } from "fs";
|
|
376
|
-
var plansCmd = new
|
|
352
|
+
var plansCmd = new Command6("plans").description("Manage plans");
|
|
377
353
|
plansCmd.command("list <slug>").description("List plans for a pebble").action(async (slug) => {
|
|
378
354
|
const res = await apiRequest(`/pebbles/${slug}/plans`);
|
|
379
355
|
process.stdout.write(JSON.stringify(res) + "\n");
|
|
@@ -472,63 +448,10 @@ plansCmd.command("remove-phase-link <slug> <planId> <phaseId> <linkId>").descrip
|
|
|
472
448
|
if (res.error) process.exit(1);
|
|
473
449
|
});
|
|
474
450
|
|
|
475
|
-
// src/commands/conversations.ts
|
|
476
|
-
import { Command as Command8 } from "commander";
|
|
477
|
-
function collect(value, previous) {
|
|
478
|
-
return previous.concat([value]);
|
|
479
|
-
}
|
|
480
|
-
var conversationsCmd = new Command8("conversations").description("Manage conversations");
|
|
481
|
-
conversationsCmd.command("list <slug>").description("List conversations for a pebble").action(async (slug) => {
|
|
482
|
-
const res = await apiRequest(`/pebbles/${slug}/conversations`);
|
|
483
|
-
process.stdout.write(JSON.stringify(res) + "\n");
|
|
484
|
-
if (res.error) process.exit(1);
|
|
485
|
-
});
|
|
486
|
-
conversationsCmd.command("get <slug> <id>").description("Get a conversation by ID").action(async (slug, id) => {
|
|
487
|
-
const res = await apiRequest(`/pebbles/${slug}/conversations/${id}`);
|
|
488
|
-
process.stdout.write(JSON.stringify(res) + "\n");
|
|
489
|
-
if (res.error) process.exit(1);
|
|
490
|
-
});
|
|
491
|
-
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) => {
|
|
492
|
-
const res = await apiRequest(`/pebbles/${slug}/conversations`, {
|
|
493
|
-
method: "POST",
|
|
494
|
-
body: {
|
|
495
|
-
title,
|
|
496
|
-
summary: opts.summary ?? null,
|
|
497
|
-
key_points: opts.keyPoint,
|
|
498
|
-
decisions_made: opts.decision,
|
|
499
|
-
source_url: opts.sourceUrl ?? null,
|
|
500
|
-
session_id: opts.sessionId ?? null
|
|
501
|
-
}
|
|
502
|
-
});
|
|
503
|
-
process.stdout.write(JSON.stringify(res) + "\n");
|
|
504
|
-
if (res.error) process.exit(1);
|
|
505
|
-
});
|
|
506
|
-
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) => {
|
|
507
|
-
const body = {};
|
|
508
|
-
if (opts.title) body.title = opts.title;
|
|
509
|
-
if (opts.summary) body.summary = opts.summary;
|
|
510
|
-
if (opts.keyPoint.length > 0) body.key_points = opts.keyPoint;
|
|
511
|
-
if (opts.decision.length > 0) body.decisions_made = opts.decision;
|
|
512
|
-
if (opts.sourceUrl) body.source_url = opts.sourceUrl;
|
|
513
|
-
const res = await apiRequest(`/pebbles/${slug}/conversations/${id}`, {
|
|
514
|
-
method: "PUT",
|
|
515
|
-
body
|
|
516
|
-
});
|
|
517
|
-
process.stdout.write(JSON.stringify(res) + "\n");
|
|
518
|
-
if (res.error) process.exit(1);
|
|
519
|
-
});
|
|
520
|
-
conversationsCmd.command("delete <slug> <id>").description("Delete a conversation").action(async (slug, id) => {
|
|
521
|
-
const res = await apiRequest(`/pebbles/${slug}/conversations/${id}`, {
|
|
522
|
-
method: "DELETE"
|
|
523
|
-
});
|
|
524
|
-
process.stdout.write(JSON.stringify(res) + "\n");
|
|
525
|
-
if (res.error) process.exit(1);
|
|
526
|
-
});
|
|
527
|
-
|
|
528
451
|
// src/commands/specs.ts
|
|
529
|
-
import { Command as
|
|
452
|
+
import { Command as Command7 } from "commander";
|
|
530
453
|
import { readFileSync as readFileSync5 } from "fs";
|
|
531
|
-
var specsCmd = new
|
|
454
|
+
var specsCmd = new Command7("specs").description("Manage agent specs");
|
|
532
455
|
specsCmd.command("list <slug>").description("List specs for a pebble").option("--source <source>", "Filter by source (claude-code, superpowers, etc.)").action(async (slug, opts) => {
|
|
533
456
|
const params = {};
|
|
534
457
|
if (opts.source) params.source = opts.source;
|
|
@@ -578,48 +501,9 @@ specsCmd.command("delete <slug> <id>").description("Delete a spec").action(async
|
|
|
578
501
|
if (res.error) process.exit(1);
|
|
579
502
|
});
|
|
580
503
|
|
|
581
|
-
// src/commands/executions.ts
|
|
582
|
-
import { Command as Command10 } from "commander";
|
|
583
|
-
var executionsCmd = new Command10("executions").description("View Claude Code executions");
|
|
584
|
-
executionsCmd.command("create <slug>").description("Create an execution record").requiredOption("--tool-name <name>", "Tool name").option("--session-id <id>", "Session ID").option("--summary-text <text>", "Summary text").option("--execution-type <type>", "Execution type (task|discovery|system|plan)").option("--raw-input <json>", "Raw input JSON").option("--raw-output <json>", "Raw output JSON").option("--files-read <files...>", "Files read").option("--files-modified <files...>", "Files modified").option("--prompt-number <n>", "Prompt number").option("--content-hash <hash>", "Content hash for dedup").action(async (slug, opts) => {
|
|
585
|
-
const body = {
|
|
586
|
-
tool_name: opts.toolName
|
|
587
|
-
};
|
|
588
|
-
if (opts.sessionId) body.session_id = opts.sessionId;
|
|
589
|
-
if (opts.summaryText) body.summary_text = opts.summaryText;
|
|
590
|
-
if (opts.executionType) body.execution_type = opts.executionType;
|
|
591
|
-
if (opts.rawInput) body.raw_input = opts.rawInput;
|
|
592
|
-
if (opts.rawOutput) body.raw_output = opts.rawOutput;
|
|
593
|
-
if (opts.filesRead) body.files_read = opts.filesRead;
|
|
594
|
-
if (opts.filesModified) body.files_modified = opts.filesModified;
|
|
595
|
-
if (opts.promptNumber) body.prompt_number = parseInt(opts.promptNumber, 10);
|
|
596
|
-
if (opts.contentHash) body.content_hash = opts.contentHash;
|
|
597
|
-
const res = await apiRequest(`/pebbles/${slug}/executions`, {
|
|
598
|
-
method: "POST",
|
|
599
|
-
body
|
|
600
|
-
});
|
|
601
|
-
process.stdout.write(JSON.stringify(res) + "\n");
|
|
602
|
-
if (res.error) process.exit(1);
|
|
603
|
-
});
|
|
604
|
-
executionsCmd.command("list <slug>").description("List executions for a pebble").option("--session-id <id>", "Filter by session ID").option("--limit <n>", "Max results", "50").option("--offset <n>", "Offset for pagination", "0").action(async (slug, opts) => {
|
|
605
|
-
const params = {
|
|
606
|
-
limit: opts.limit,
|
|
607
|
-
offset: opts.offset
|
|
608
|
-
};
|
|
609
|
-
if (opts.sessionId) params.session_id = opts.sessionId;
|
|
610
|
-
const res = await apiRequest(`/pebbles/${slug}/executions`, { params });
|
|
611
|
-
process.stdout.write(JSON.stringify(res) + "\n");
|
|
612
|
-
if (res.error) process.exit(1);
|
|
613
|
-
});
|
|
614
|
-
executionsCmd.command("get <slug> <id>").description("Get a single execution").action(async (slug, id) => {
|
|
615
|
-
const res = await apiRequest(`/pebbles/${slug}/executions/${id}`);
|
|
616
|
-
process.stdout.write(JSON.stringify(res) + "\n");
|
|
617
|
-
if (res.error) process.exit(1);
|
|
618
|
-
});
|
|
619
|
-
|
|
620
504
|
// src/commands/versions.ts
|
|
621
|
-
import { Command as
|
|
622
|
-
var versionsCmd = new
|
|
505
|
+
import { Command as Command8 } from "commander";
|
|
506
|
+
var versionsCmd = new Command8("versions").description("View document version history");
|
|
623
507
|
versionsCmd.command("list <slug> <docType>").description("List versions for a document").action(async (slug, docType) => {
|
|
624
508
|
const res = await apiRequest(`/pebbles/${slug}/documents/${docType}/versions`);
|
|
625
509
|
process.stdout.write(JSON.stringify(res) + "\n");
|
|
@@ -632,9 +516,9 @@ versionsCmd.command("get <slug> <docType> <versionId>").description("Get a speci
|
|
|
632
516
|
});
|
|
633
517
|
|
|
634
518
|
// src/commands/guidelines.ts
|
|
635
|
-
import { Command as
|
|
519
|
+
import { Command as Command9 } from "commander";
|
|
636
520
|
import { readFileSync as readFileSync6 } from "fs";
|
|
637
|
-
var guidelinesCmd = new
|
|
521
|
+
var guidelinesCmd = new Command9("guidelines").description("Manage global guidelines");
|
|
638
522
|
guidelinesCmd.command("list").description("List guidelines").option("--category <category>", "Filter by category").option("--status <status>", "Filter by status (default: active)").option("--all", "Include deprecated guidelines").action(async (opts) => {
|
|
639
523
|
const params = new URLSearchParams();
|
|
640
524
|
if (opts.category) params.set("category", opts.category);
|
|
@@ -695,51 +579,6 @@ guidelinesCmd.command("deprecate <id>").description("Deprecate a guideline").act
|
|
|
695
579
|
if (res.error) process.exit(1);
|
|
696
580
|
});
|
|
697
581
|
|
|
698
|
-
// src/commands/observations.ts
|
|
699
|
-
import { Command as Command13 } from "commander";
|
|
700
|
-
var observationsCmd = new Command13("observations").description(
|
|
701
|
-
"View and synthesize observations"
|
|
702
|
-
);
|
|
703
|
-
observationsCmd.command("list <slug>").description("List observations for a pebble").option("--limit <n>", "Max results", "50").option("--offset <n>", "Offset for pagination", "0").action(async (slug, opts) => {
|
|
704
|
-
const res = await apiRequest(
|
|
705
|
-
`/pebbles/${slug}/observations`,
|
|
706
|
-
{
|
|
707
|
-
params: { limit: opts.limit, offset: opts.offset }
|
|
708
|
-
}
|
|
709
|
-
);
|
|
710
|
-
process.stdout.write(JSON.stringify(res) + "\n");
|
|
711
|
-
if (res.error) process.exit(1);
|
|
712
|
-
});
|
|
713
|
-
observationsCmd.command("synthesize [slug]").description("Trigger observation synthesis (requires running worker)").action(async (slug) => {
|
|
714
|
-
try {
|
|
715
|
-
const body = {};
|
|
716
|
-
if (slug) body.slug = slug;
|
|
717
|
-
const res = await fetch("http://127.0.0.1:7433/synthesize", {
|
|
718
|
-
method: "POST",
|
|
719
|
-
headers: { "Content-Type": "application/json" },
|
|
720
|
-
body: JSON.stringify(body)
|
|
721
|
-
});
|
|
722
|
-
if (!res.ok) {
|
|
723
|
-
const text = await res.text();
|
|
724
|
-
console.error(`Worker returned ${res.status}: ${text}`);
|
|
725
|
-
process.exit(1);
|
|
726
|
-
}
|
|
727
|
-
const data = await res.json();
|
|
728
|
-
process.stdout.write(JSON.stringify(data) + "\n");
|
|
729
|
-
} catch (err) {
|
|
730
|
-
if (err instanceof Error && (err.message.includes("ECONNREFUSED") || err.message.includes("fetch failed"))) {
|
|
731
|
-
console.error(
|
|
732
|
-
"Worker not running. Start a Claude Code session to launch the worker."
|
|
733
|
-
);
|
|
734
|
-
} else {
|
|
735
|
-
console.error(
|
|
736
|
-
`Failed: ${err instanceof Error ? err.message : err}`
|
|
737
|
-
);
|
|
738
|
-
}
|
|
739
|
-
process.exit(1);
|
|
740
|
-
}
|
|
741
|
-
});
|
|
742
|
-
|
|
743
582
|
// src/index.ts
|
|
744
583
|
import { readFileSync as readFileSync7 } from "fs";
|
|
745
584
|
import { fileURLToPath } from "url";
|
|
@@ -763,7 +602,7 @@ ${RESET}
|
|
|
763
602
|
${DIM}${cwd}${RESET}
|
|
764
603
|
`);
|
|
765
604
|
}
|
|
766
|
-
var program = new
|
|
605
|
+
var program = new Command10();
|
|
767
606
|
program.name("odin").description("CLI for Odin \u2014 the knowledge backbone for Pebble House").version(VERSION);
|
|
768
607
|
program.command("login").description("Authenticate with Odin via browser").action(async () => {
|
|
769
608
|
printBanner();
|
|
@@ -783,15 +622,11 @@ program.addCommand(pebblesCmd);
|
|
|
783
622
|
program.addCommand(docsCmd);
|
|
784
623
|
program.addCommand(decisionsCmd);
|
|
785
624
|
program.addCommand(contextCmd);
|
|
786
|
-
program.addCommand(sessionsCmd);
|
|
787
625
|
program.addCommand(searchCmd);
|
|
788
626
|
program.addCommand(plansCmd);
|
|
789
|
-
program.addCommand(conversationsCmd);
|
|
790
627
|
program.addCommand(specsCmd);
|
|
791
|
-
program.addCommand(executionsCmd);
|
|
792
628
|
program.addCommand(versionsCmd);
|
|
793
629
|
program.addCommand(guidelinesCmd);
|
|
794
|
-
program.addCommand(observationsCmd);
|
|
795
630
|
process.on("exit", () => {
|
|
796
631
|
process.stderr.write("\n\n\n\n\n");
|
|
797
632
|
});
|