@pebblehouse/odin-cli 0.7.0 → 0.9.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 +112 -11
- 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 Command12 } from "commander";
|
|
5
5
|
|
|
6
6
|
// src/auth/login.ts
|
|
7
7
|
import { createServer } from "http";
|
|
@@ -408,13 +408,19 @@ ${supersededTitles.map((t) => ` \u21B3 "${t}"`).join("\n")}
|
|
|
408
408
|
|
|
409
409
|
// src/commands/context.ts
|
|
410
410
|
import { Command as Command4 } from "commander";
|
|
411
|
-
var contextCmd = new Command4("context").description("Get Tier 1 context for a pebble").argument("<slug>", "Pebble slug").action(async (slug) => {
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
411
|
+
var contextCmd = new Command4("context").description("Get Tier 1 context packet for a pebble (brief + rules + guidelines)").argument("<slug>", "Pebble slug").action(async (slug) => {
|
|
412
|
+
const res = await apiRequest(`/pebbles/${slug}/context`);
|
|
413
|
+
if (res.error) {
|
|
414
|
+
console.error(`error: ${res.error}`);
|
|
415
|
+
process.exit(1);
|
|
416
|
+
}
|
|
417
|
+
if (res.data?.context) {
|
|
418
|
+
process.stdout.write(res.data.context + "\n");
|
|
419
|
+
} else {
|
|
420
|
+
console.error(`No context available for "${slug}". Create a brief first:`);
|
|
421
|
+
console.error(` odin briefs update ${slug} --file brief.md`);
|
|
422
|
+
process.exit(0);
|
|
423
|
+
}
|
|
418
424
|
});
|
|
419
425
|
|
|
420
426
|
// src/commands/search.ts
|
|
@@ -659,12 +665,105 @@ guidelinesCmd.command("deprecate <id>").description("Deprecate a guideline").act
|
|
|
659
665
|
if (res.error) process.exit(1);
|
|
660
666
|
});
|
|
661
667
|
|
|
662
|
-
// src/
|
|
668
|
+
// src/commands/rules.ts
|
|
669
|
+
import { Command as Command10 } from "commander";
|
|
663
670
|
import { readFileSync as readFileSync7 } from "fs";
|
|
671
|
+
var rulesCmd = new Command10("rules").description("Manage pebble rules");
|
|
672
|
+
rulesCmd.command("list <slug>").description("List rules for a pebble").option("--category <category>", "Filter by category").option("--status <status>", "Filter by status (default: active)").option("--all", "Include deprecated rules").action(async (slug, opts) => {
|
|
673
|
+
const params = {};
|
|
674
|
+
if (opts.category) params.category = opts.category;
|
|
675
|
+
if (opts.all) params.status = "all";
|
|
676
|
+
else if (opts.status) params.status = opts.status;
|
|
677
|
+
const res = await apiRequest(`/pebbles/${slug}/rules`, { params });
|
|
678
|
+
process.stdout.write(JSON.stringify(res) + "\n");
|
|
679
|
+
if (res.error) process.exit(1);
|
|
680
|
+
});
|
|
681
|
+
rulesCmd.command("get <slug> <id>").description("Get a rule by ID").action(async (slug, id) => {
|
|
682
|
+
const res = await apiRequest(`/pebbles/${slug}/rules/${id}`);
|
|
683
|
+
process.stdout.write(JSON.stringify(res) + "\n");
|
|
684
|
+
if (res.error) process.exit(1);
|
|
685
|
+
});
|
|
686
|
+
rulesCmd.command("create <slug> <title>").description("Create a rule").option("--category <category>", "Category", "other").option("--content <content>", "Rule content (max 500 chars)").option("--file <path>", "Read content from file").option("--source <source>", "Source", "manual").action(async (slug, title, opts) => {
|
|
687
|
+
const content = opts.file ? readFileSync7(opts.file, "utf-8") : opts.content ?? "";
|
|
688
|
+
const res = await apiRequest(`/pebbles/${slug}/rules`, {
|
|
689
|
+
method: "POST",
|
|
690
|
+
body: { category: opts.category, title, content, source: opts.source }
|
|
691
|
+
});
|
|
692
|
+
process.stdout.write(JSON.stringify(res) + "\n");
|
|
693
|
+
if (res.error) process.exit(1);
|
|
694
|
+
});
|
|
695
|
+
rulesCmd.command("update <slug> <id>").description("Update a rule").option("--title <title>", "New title").option("--content <content>", "New content (max 500 chars)").option("--file <path>", "Read content from file").option("--category <category>", "New category").option("--status <status>", "New status (active|deprecated)").option("--source <source>", "Source").action(async (slug, id, opts) => {
|
|
696
|
+
const body = {};
|
|
697
|
+
if (opts.title) body.title = opts.title;
|
|
698
|
+
if (opts.file) body.content = readFileSync7(opts.file, "utf-8");
|
|
699
|
+
else if (opts.content) body.content = opts.content;
|
|
700
|
+
if (opts.category) body.category = opts.category;
|
|
701
|
+
if (opts.status) body.status = opts.status;
|
|
702
|
+
if (opts.source) body.source = opts.source;
|
|
703
|
+
const res = await apiRequest(`/pebbles/${slug}/rules/${id}`, {
|
|
704
|
+
method: "PUT",
|
|
705
|
+
body
|
|
706
|
+
});
|
|
707
|
+
process.stdout.write(JSON.stringify(res) + "\n");
|
|
708
|
+
if (res.error) process.exit(1);
|
|
709
|
+
});
|
|
710
|
+
rulesCmd.command("delete <slug> <id>").description("Delete a rule").action(async (slug, id) => {
|
|
711
|
+
const res = await apiRequest(`/pebbles/${slug}/rules/${id}`, {
|
|
712
|
+
method: "DELETE"
|
|
713
|
+
});
|
|
714
|
+
process.stdout.write(JSON.stringify(res) + "\n");
|
|
715
|
+
if (res.error) process.exit(1);
|
|
716
|
+
});
|
|
717
|
+
rulesCmd.command("deprecate <slug> <id>").description("Deprecate a rule").action(async (slug, id) => {
|
|
718
|
+
const res = await apiRequest(`/pebbles/${slug}/rules/${id}`, {
|
|
719
|
+
method: "PUT",
|
|
720
|
+
body: { status: "deprecated" }
|
|
721
|
+
});
|
|
722
|
+
process.stdout.write(JSON.stringify(res) + "\n");
|
|
723
|
+
if (res.error) process.exit(1);
|
|
724
|
+
});
|
|
725
|
+
|
|
726
|
+
// src/commands/briefs.ts
|
|
727
|
+
import { Command as Command11 } from "commander";
|
|
728
|
+
import { readFileSync as readFileSync8 } from "fs";
|
|
729
|
+
var briefsCmd = new Command11("briefs").description("Manage pebble context briefs");
|
|
730
|
+
briefsCmd.command("get <slug>").description("Get the context brief for a pebble").action(async (slug) => {
|
|
731
|
+
const res = await apiRequest(`/pebbles/${slug}/brief`);
|
|
732
|
+
process.stdout.write(JSON.stringify(res) + "\n");
|
|
733
|
+
if (res.error) process.exit(1);
|
|
734
|
+
});
|
|
735
|
+
briefsCmd.command("update <slug>").description("Create or update the context brief").option("--content <content>", "Brief content").option("--file <path>", "Read content from file").option("--title <title>", "Brief title").option("--source <source>", "Source", "manual").action(async (slug, opts) => {
|
|
736
|
+
const content = opts.file ? readFileSync8(opts.file, "utf-8") : opts.content;
|
|
737
|
+
if (!content) {
|
|
738
|
+
console.error("error: --content or --file is required");
|
|
739
|
+
process.exit(1);
|
|
740
|
+
}
|
|
741
|
+
const body = { content, source: opts.source };
|
|
742
|
+
if (opts.title) body.title = opts.title;
|
|
743
|
+
const res = await apiRequest(`/pebbles/${slug}/brief`, {
|
|
744
|
+
method: "PUT",
|
|
745
|
+
body
|
|
746
|
+
});
|
|
747
|
+
process.stdout.write(JSON.stringify(res) + "\n");
|
|
748
|
+
if (res.error) process.exit(1);
|
|
749
|
+
});
|
|
750
|
+
briefsCmd.command("delete <slug>").description("Delete the context brief for a pebble").action(async (slug) => {
|
|
751
|
+
const res = await apiRequest(`/pebbles/${slug}/brief`, { method: "DELETE" });
|
|
752
|
+
process.stdout.write(JSON.stringify(res) + "\n");
|
|
753
|
+
if (res.error) process.exit(1);
|
|
754
|
+
});
|
|
755
|
+
briefsCmd.command("versions <slug>").description("List version history for a pebble's brief").action(async (slug) => {
|
|
756
|
+
const res = await apiRequest(`/pebbles/${slug}/brief/versions`);
|
|
757
|
+
process.stdout.write(JSON.stringify(res) + "\n");
|
|
758
|
+
if (res.error) process.exit(1);
|
|
759
|
+
});
|
|
760
|
+
|
|
761
|
+
// src/index.ts
|
|
762
|
+
import { readFileSync as readFileSync9 } from "fs";
|
|
664
763
|
import { fileURLToPath } from "url";
|
|
665
764
|
import { dirname as dirname2, resolve } from "path";
|
|
666
765
|
var __dirname = dirname2(fileURLToPath(import.meta.url));
|
|
667
|
-
var pkg = JSON.parse(
|
|
766
|
+
var pkg = JSON.parse(readFileSync9(resolve(__dirname, "../package.json"), "utf-8"));
|
|
668
767
|
var GOLD = "\x1B[33m";
|
|
669
768
|
var DIM = "\x1B[2m";
|
|
670
769
|
var RESET = "\x1B[0m";
|
|
@@ -682,7 +781,7 @@ ${RESET}
|
|
|
682
781
|
${DIM}${cwd}${RESET}
|
|
683
782
|
`);
|
|
684
783
|
}
|
|
685
|
-
var program = new
|
|
784
|
+
var program = new Command12();
|
|
686
785
|
program.name("odin").description("CLI for Odin \u2014 the knowledge backbone for Pebble House").version(VERSION);
|
|
687
786
|
program.command("login").description("Authenticate with Odin via browser").action(async () => {
|
|
688
787
|
printBanner();
|
|
@@ -707,6 +806,8 @@ program.addCommand(plansCmd);
|
|
|
707
806
|
program.addCommand(artifactsCmd);
|
|
708
807
|
program.addCommand(versionsCmd);
|
|
709
808
|
program.addCommand(guidelinesCmd);
|
|
809
|
+
program.addCommand(rulesCmd);
|
|
810
|
+
program.addCommand(briefsCmd);
|
|
710
811
|
process.on("exit", () => {
|
|
711
812
|
process.stderr.write("\n\n\n\n\n");
|
|
712
813
|
});
|