@benzotti/jedi 0.1.10 → 0.1.12

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.
@@ -95,6 +95,7 @@ jobs:
95
95
  with:
96
96
  anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
97
97
  trigger_phrase: '@jedi'
98
+ bot_name: 'jedi[bot]'
98
99
  env:
99
100
  CLICKUP_API_TOKEN: ${{ secrets.CLICKUP_API_TOKEN }}
100
101
 
package/dist/index.js CHANGED
@@ -9218,6 +9218,7 @@ async function runMain(cmd, opts = {}) {
9218
9218
 
9219
9219
  // src/commands/init.ts
9220
9220
  import { join as join3 } from "path";
9221
+ import { existsSync as existsSync3 } from "fs";
9221
9222
 
9222
9223
  // src/utils/detect-project.ts
9223
9224
  import { existsSync } from "fs";
@@ -9295,6 +9296,12 @@ async function copyFrameworkFiles(cwd, projectType, force, ci = false) {
9295
9296
 
9296
9297
  You are Jedi, an AI development framework that uses specialised agents to plan, implement, review, and ship features.
9297
9298
 
9299
+ ## Identity
9300
+
9301
+ You are **Jedi**, not Claude. Always refer to yourself as "Jedi" in your responses.
9302
+ Use "Jedi" in summaries, status updates, and sign-offs (e.g. "Jedi has completed..." not "Claude has completed...").
9303
+ End each response with a brief signature line: \`\u2014 Jedi\`
9304
+
9298
9305
  ## Framework
9299
9306
 
9300
9307
  Read \`.jdi/framework/components/meta/AgentBase.md\` for the base agent protocol.
@@ -9430,12 +9437,31 @@ var initCommand = defineCommand({
9430
9437
  ".jdi/codebase",
9431
9438
  ".jdi/reviews",
9432
9439
  ".jdi/config",
9433
- ".jdi/persistence"
9440
+ ".jdi/persistence",
9441
+ ".jdi/feedback"
9434
9442
  ];
9435
9443
  for (const dir of dirs) {
9436
9444
  await Bun.write(join3(cwd, dir, ".gitkeep"), "");
9437
9445
  }
9438
9446
  await copyFrameworkFiles(cwd, projectType, args.force, args.ci);
9447
+ const configFiles = ["state.yaml", "variables.yaml", "jdi-config.yaml"];
9448
+ for (const file of configFiles) {
9449
+ const src2 = join3(cwd, ".jdi", "framework", "config", file);
9450
+ const dest = join3(cwd, ".jdi", "config", file);
9451
+ if (existsSync3(src2) && (args.force || !existsSync3(dest))) {
9452
+ const content = await Bun.file(src2).text();
9453
+ await Bun.write(dest, content);
9454
+ }
9455
+ }
9456
+ const scaffoldFiles = ["PROJECT.yaml", "REQUIREMENTS.yaml", "ROADMAP.yaml"];
9457
+ for (const file of scaffoldFiles) {
9458
+ const src2 = join3(cwd, ".jdi", "framework", "templates", file);
9459
+ const dest = join3(cwd, ".jdi", file);
9460
+ if (existsSync3(src2) && !existsSync3(dest)) {
9461
+ const content = await Bun.file(src2).text();
9462
+ await Bun.write(dest, content);
9463
+ }
9464
+ }
9439
9465
  if (args.storage || args["storage-path"]) {
9440
9466
  const { parse, stringify } = await Promise.resolve().then(() => __toESM(require_dist(), 1));
9441
9467
  const configPath = join3(cwd, ".jdi", "config", "jdi-config.yaml");
@@ -9477,10 +9503,10 @@ import { resolve as resolve2 } from "path";
9477
9503
  // src/utils/adapter.ts
9478
9504
  var import_yaml = __toESM(require_dist(), 1);
9479
9505
  import { join as join4 } from "path";
9480
- import { existsSync as existsSync3 } from "fs";
9506
+ import { existsSync as existsSync4 } from "fs";
9481
9507
  async function readAdapter(cwd) {
9482
9508
  const adapterPath = join4(cwd, ".jdi", "config", "adapter.yaml");
9483
- if (!existsSync3(adapterPath))
9509
+ if (!existsSync4(adapterPath))
9484
9510
  return null;
9485
9511
  const content = await Bun.file(adapterPath).text();
9486
9512
  return import_yaml.parse(content);
@@ -9613,11 +9639,11 @@ async function spawnClaude(prompt2, opts) {
9613
9639
  // src/storage/index.ts
9614
9640
  var import_yaml2 = __toESM(require_dist(), 1);
9615
9641
  import { join as join6 } from "path";
9616
- import { existsSync as existsSync5 } from "fs";
9642
+ import { existsSync as existsSync6 } from "fs";
9617
9643
 
9618
9644
  // src/storage/fs-storage.ts
9619
9645
  import { join as join5 } from "path";
9620
- import { existsSync as existsSync4, mkdirSync as mkdirSync2 } from "fs";
9646
+ import { existsSync as existsSync5, mkdirSync as mkdirSync2 } from "fs";
9621
9647
 
9622
9648
  class FsStorage {
9623
9649
  basePath;
@@ -9626,12 +9652,12 @@ class FsStorage {
9626
9652
  }
9627
9653
  async load(key) {
9628
9654
  const filePath = join5(this.basePath, `${key}.md`);
9629
- if (!existsSync4(filePath))
9655
+ if (!existsSync5(filePath))
9630
9656
  return null;
9631
9657
  return Bun.file(filePath).text();
9632
9658
  }
9633
9659
  async save(key, content) {
9634
- if (!existsSync4(this.basePath)) {
9660
+ if (!existsSync5(this.basePath)) {
9635
9661
  mkdirSync2(this.basePath, { recursive: true });
9636
9662
  }
9637
9663
  const filePath = join5(this.basePath, `${key}.md`);
@@ -9645,7 +9671,7 @@ async function createStorage(cwd, config) {
9645
9671
  let basePath = config?.basePath;
9646
9672
  if (!config?.adapter && !config?.basePath) {
9647
9673
  const configPath = join6(cwd, ".jdi", "config", "jdi-config.yaml");
9648
- if (existsSync5(configPath)) {
9674
+ if (existsSync6(configPath)) {
9649
9675
  const content = await Bun.file(configPath).text();
9650
9676
  const parsed = import_yaml2.parse(content);
9651
9677
  if (parsed?.storage?.adapter)
@@ -9659,7 +9685,7 @@ async function createStorage(cwd, config) {
9659
9685
  return new FsStorage(resolvedPath);
9660
9686
  }
9661
9687
  const adapterPath = join6(cwd, adapter);
9662
- if (!existsSync5(adapterPath)) {
9688
+ if (!existsSync6(adapterPath)) {
9663
9689
  throw new Error(`Storage adapter not found: ${adapterPath}
9664
9690
  ` + `Set storage.adapter in .jdi/config/jdi-config.yaml to "fs" or a path to a custom adapter module.`);
9665
9691
  }
@@ -9683,14 +9709,14 @@ async function createStorage(cwd, config) {
9683
9709
 
9684
9710
  // src/utils/storage-lifecycle.ts
9685
9711
  import { join as join7 } from "path";
9686
- import { existsSync as existsSync6, mkdirSync as mkdirSync3 } from "fs";
9712
+ import { existsSync as existsSync7, mkdirSync as mkdirSync3 } from "fs";
9687
9713
  async function loadPersistedState(cwd, storage) {
9688
9714
  let learningsPath = null;
9689
9715
  let codebaseIndexPath = null;
9690
9716
  const learnings = await storage.load("learnings");
9691
9717
  if (learnings) {
9692
9718
  const dir = join7(cwd, ".jdi", "framework", "learnings");
9693
- if (!existsSync6(dir))
9719
+ if (!existsSync7(dir))
9694
9720
  mkdirSync3(dir, { recursive: true });
9695
9721
  learningsPath = join7(dir, "_consolidated.md");
9696
9722
  await Bun.write(learningsPath, learnings);
@@ -9698,7 +9724,7 @@ async function loadPersistedState(cwd, storage) {
9698
9724
  const codebaseIndex = await storage.load("codebase-index");
9699
9725
  if (codebaseIndex) {
9700
9726
  const dir = join7(cwd, ".jdi", "codebase");
9701
- if (!existsSync6(dir))
9727
+ if (!existsSync7(dir))
9702
9728
  mkdirSync3(dir, { recursive: true });
9703
9729
  codebaseIndexPath = join7(dir, "INDEX.md");
9704
9730
  await Bun.write(codebaseIndexPath, codebaseIndex);
@@ -9709,7 +9735,7 @@ async function savePersistedState(cwd, storage) {
9709
9735
  let learningsSaved = false;
9710
9736
  let codebaseIndexSaved = false;
9711
9737
  const learningsDir = join7(cwd, ".jdi", "framework", "learnings");
9712
- if (existsSync6(learningsDir)) {
9738
+ if (existsSync7(learningsDir)) {
9713
9739
  const merged = await mergeLearningFiles(learningsDir);
9714
9740
  if (merged) {
9715
9741
  await storage.save("learnings", merged);
@@ -9717,7 +9743,7 @@ async function savePersistedState(cwd, storage) {
9717
9743
  }
9718
9744
  }
9719
9745
  const indexPath = join7(cwd, ".jdi", "codebase", "INDEX.md");
9720
- if (existsSync6(indexPath)) {
9746
+ if (existsSync7(indexPath)) {
9721
9747
  const content = await Bun.file(indexPath).text();
9722
9748
  if (content.trim()) {
9723
9749
  await storage.save("codebase-index", content);
@@ -9731,7 +9757,7 @@ async function mergeLearningFiles(dir) {
9731
9757
  const sections = [];
9732
9758
  for (const category of categories) {
9733
9759
  const filePath = join7(dir, `${category}.md`);
9734
- if (!existsSync6(filePath))
9760
+ if (!existsSync7(filePath))
9735
9761
  continue;
9736
9762
  const content = await Bun.file(filePath).text();
9737
9763
  const trimmed = content.trim();
@@ -9742,7 +9768,7 @@ async function mergeLearningFiles(dir) {
9742
9768
  sections.push(trimmed);
9743
9769
  }
9744
9770
  const consolidatedPath = join7(dir, "_consolidated.md");
9745
- if (existsSync6(consolidatedPath)) {
9771
+ if (existsSync7(consolidatedPath)) {
9746
9772
  const content = await Bun.file(consolidatedPath).text();
9747
9773
  const trimmed = content.trim();
9748
9774
  if (trimmed && !sections.some((s2) => s2.includes(trimmed))) {
@@ -9826,10 +9852,10 @@ import { resolve as resolve3 } from "path";
9826
9852
  // src/utils/state.ts
9827
9853
  var import_yaml3 = __toESM(require_dist(), 1);
9828
9854
  import { join as join8 } from "path";
9829
- import { existsSync as existsSync7 } from "fs";
9855
+ import { existsSync as existsSync8 } from "fs";
9830
9856
  async function readState(cwd) {
9831
9857
  const statePath = join8(cwd, ".jdi", "config", "state.yaml");
9832
- if (!existsSync7(statePath))
9858
+ if (!existsSync8(statePath))
9833
9859
  return null;
9834
9860
  const content = await Bun.file(statePath).text();
9835
9861
  return import_yaml3.parse(content);
@@ -10146,7 +10172,7 @@ Use --all to stage and commit all, or stage files manually.`);
10146
10172
  });
10147
10173
 
10148
10174
  // src/commands/pr.ts
10149
- import { existsSync as existsSync8 } from "fs";
10175
+ import { existsSync as existsSync9 } from "fs";
10150
10176
  import { join as join10 } from "path";
10151
10177
  async function hasGhCli() {
10152
10178
  const { exitCode } = await exec(["which", "gh"]);
@@ -10198,7 +10224,7 @@ var prCommand = defineCommand({
10198
10224
  **Plan:** ${state.position.plan_name}` : "";
10199
10225
  let template = "";
10200
10226
  const templatePath = join10(cwd, ".github", "pull_request_template.md");
10201
- if (existsSync8(templatePath)) {
10227
+ if (existsSync9(templatePath)) {
10202
10228
  template = await Bun.file(templatePath).text();
10203
10229
  }
10204
10230
  const title = branch.replace(/^(feat|fix|chore|docs|refactor|test|ci)\//, "").replace(/[-_]/g, " ").replace(/^\w/, (c3) => c3.toUpperCase());
@@ -10546,7 +10572,7 @@ var quickCommand = defineCommand({
10546
10572
  });
10547
10573
 
10548
10574
  // src/commands/worktree.ts
10549
- import { existsSync as existsSync9 } from "fs";
10575
+ import { existsSync as existsSync10 } from "fs";
10550
10576
  function slugify(name) {
10551
10577
  return name.toLowerCase().replace(/[^a-z0-9-]/g, "-").replace(/-+/g, "-").replace(/^-|-$/g, "").slice(0, 40);
10552
10578
  }
@@ -10580,7 +10606,7 @@ var worktreeCommand = defineCommand({
10580
10606
  }
10581
10607
  const slug = slugify(args.name);
10582
10608
  const worktreePath = `${root}/.worktrees/${slug}`;
10583
- if (existsSync9(worktreePath)) {
10609
+ if (existsSync10(worktreePath)) {
10584
10610
  consola.error(`Worktree already exists at ${worktreePath}`);
10585
10611
  return;
10586
10612
  }
@@ -10746,7 +10772,7 @@ Specify a worktree name: jdi worktree-remove <name>`);
10746
10772
 
10747
10773
  // src/commands/plan-review.ts
10748
10774
  import { resolve as resolve7 } from "path";
10749
- import { existsSync as existsSync10 } from "fs";
10775
+ import { existsSync as existsSync11 } from "fs";
10750
10776
  function parsePlanSummary(content) {
10751
10777
  const nameMatch = content.match(/^# .+?: (.+)$/m);
10752
10778
  const name = nameMatch?.[1] ?? "Unknown";
@@ -10785,7 +10811,7 @@ var planReviewCommand = defineCommand({
10785
10811
  consola.error("No plan found. Run `jdi plan` first.");
10786
10812
  return;
10787
10813
  }
10788
- if (!existsSync10(planPath)) {
10814
+ if (!existsSync11(planPath)) {
10789
10815
  consola.error(`Plan not found: ${planPath}`);
10790
10816
  return;
10791
10817
  }
@@ -10875,7 +10901,7 @@ Tasks (${tasks.length}):`);
10875
10901
 
10876
10902
  // src/commands/plan-approve.ts
10877
10903
  import { resolve as resolve8 } from "path";
10878
- import { existsSync as existsSync11 } from "fs";
10904
+ import { existsSync as existsSync12 } from "fs";
10879
10905
  var planApproveCommand = defineCommand({
10880
10906
  meta: {
10881
10907
  name: "plan-approve",
@@ -10904,7 +10930,7 @@ var planApproveCommand = defineCommand({
10904
10930
  consola.error("No plan to approve. Run `jdi plan` first.");
10905
10931
  return;
10906
10932
  }
10907
- if (!existsSync11(planPath)) {
10933
+ if (!existsSync12(planPath)) {
10908
10934
  consola.error(`Plan not found: ${planPath}`);
10909
10935
  return;
10910
10936
  }
@@ -11430,7 +11456,7 @@ Use the ClickUp ticket above as the primary requirements source.` : ``,
11430
11456
 
11431
11457
  // src/commands/setup-action.ts
11432
11458
  import { join as join12, dirname as dirname3 } from "path";
11433
- import { existsSync as existsSync12, mkdirSync as mkdirSync4 } from "fs";
11459
+ import { existsSync as existsSync13, mkdirSync as mkdirSync4 } from "fs";
11434
11460
  var setupActionCommand = defineCommand({
11435
11461
  meta: {
11436
11462
  name: "setup-action",
@@ -11440,17 +11466,17 @@ var setupActionCommand = defineCommand({
11440
11466
  async run() {
11441
11467
  const cwd = process.cwd();
11442
11468
  const workflowDest = join12(cwd, ".github", "workflows", "jedi.yml");
11443
- if (existsSync12(workflowDest)) {
11469
+ if (existsSync13(workflowDest)) {
11444
11470
  consola.warn(`Workflow already exists at ${workflowDest}`);
11445
11471
  consola.info("Skipping workflow copy. Delete it manually to regenerate.");
11446
11472
  } else {
11447
11473
  const templatePath = join12(import.meta.dir, "../action/workflow-template.yml");
11448
- if (!existsSync12(templatePath)) {
11474
+ if (!existsSync13(templatePath)) {
11449
11475
  consola.error("Workflow template not found. Ensure @benzotti/jedi is properly installed.");
11450
11476
  process.exit(1);
11451
11477
  }
11452
11478
  const dir = dirname3(workflowDest);
11453
- if (!existsSync12(dir))
11479
+ if (!existsSync13(dir))
11454
11480
  mkdirSync4(dir, { recursive: true });
11455
11481
  const template = await Bun.file(templatePath).text();
11456
11482
  await Bun.write(workflowDest, template);
@@ -11488,7 +11514,7 @@ var setupActionCommand = defineCommand({
11488
11514
  // package.json
11489
11515
  var package_default = {
11490
11516
  name: "@benzotti/jedi",
11491
- version: "0.1.10",
11517
+ version: "0.1.12",
11492
11518
  description: "JDI - Context-efficient AI development framework for Claude Code",
11493
11519
  type: "module",
11494
11520
  bin: {
@@ -13,7 +13,7 @@ Initialise the JDI slash commands in the current project.
13
13
 
14
14
  ```bash
15
15
  mkdir -p .claude/commands/jdi
16
- mkdir -p .jdi/plans .jdi/research .jdi/config
16
+ mkdir -p .jdi/plans .jdi/research .jdi/codebase .jdi/reviews .jdi/config .jdi/persistence .jdi/feedback
17
17
  ```
18
18
 
19
19
  ### Step 2: Copy Command Stubs
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@benzotti/jedi",
3
- "version": "0.1.10",
3
+ "version": "0.1.12",
4
4
  "description": "JDI - Context-efficient AI development framework for Claude Code",
5
5
  "type": "module",
6
6
  "bin": {