@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.
- package/action/workflow-template.yml +1 -0
- package/dist/index.js +57 -31
- package/framework/commands/init.md +1 -1
- package/package.json +1 -1
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
|
|
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 (!
|
|
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
|
|
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
|
|
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 (!
|
|
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 (!
|
|
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 (
|
|
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 (!
|
|
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
|
|
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 (!
|
|
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 (!
|
|
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 (
|
|
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 (
|
|
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 (!
|
|
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 (
|
|
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
|
|
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 (!
|
|
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
|
|
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 (
|
|
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
|
|
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 (
|
|
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
|
|
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 (!
|
|
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
|
|
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 (!
|
|
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
|
|
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 (
|
|
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 (!
|
|
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 (!
|
|
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.
|
|
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
|