@benzotti/jedi 0.1.14 → 0.1.16
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 +20 -8
- package/dist/index.js +99 -18
- package/package.json +1 -1
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
# Hey Jedi review — Review the current PR
|
|
16
16
|
# Hey Jedi feedback — Address PR review comments
|
|
17
17
|
# Hey Jedi do <clickup-ticket-url> — Full flow: plan + implement from ticket
|
|
18
|
+
# Hey Jedi ping — Check framework status
|
|
18
19
|
#
|
|
19
20
|
# Conversation: Jedi supports back-and-forth iteration. After Jedi responds,
|
|
20
21
|
# reply with feedback to refine, or say "approved" to finalise.
|
|
@@ -87,17 +88,28 @@ jobs:
|
|
|
87
88
|
grep -qxF "$pattern" .git/info/exclude 2>/dev/null || echo "$pattern" >> .git/info/exclude
|
|
88
89
|
done
|
|
89
90
|
|
|
90
|
-
#
|
|
91
|
-
|
|
92
|
-
|
|
91
|
+
# Install Claude Code CLI (required by Jedi for AI invocations)
|
|
92
|
+
- name: Install Claude Code
|
|
93
|
+
run: bun install -g @anthropic-ai/claude-code
|
|
94
|
+
|
|
95
|
+
# Run Jedi CLI directly — full pipeline with routing, agents, and comment posting
|
|
93
96
|
- name: Run Jedi
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
97
|
+
run: |
|
|
98
|
+
COMMENT_BODY="${{ github.event.comment.body }}"
|
|
99
|
+
COMMENT_ID="${{ github.event.comment.id }}"
|
|
100
|
+
PR_NUMBER="${{ github.event.issue.pull_request && github.event.issue.number || '' }}"
|
|
101
|
+
ISSUE_NUMBER="${{ github.event.issue.number }}"
|
|
102
|
+
|
|
103
|
+
ARGS="--repo ${{ github.repository }}"
|
|
104
|
+
[ -n "$COMMENT_ID" ] && ARGS="$ARGS --comment-id $COMMENT_ID"
|
|
105
|
+
[ -n "$PR_NUMBER" ] && ARGS="$ARGS --pr-number $PR_NUMBER"
|
|
106
|
+
[ -n "$ISSUE_NUMBER" ] && ARGS="$ARGS --issue-number $ISSUE_NUMBER"
|
|
107
|
+
|
|
108
|
+
bunx @benzotti/jedi@latest action "$COMMENT_BODY" $ARGS
|
|
99
109
|
env:
|
|
110
|
+
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
|
|
100
111
|
CLICKUP_API_TOKEN: ${{ secrets.CLICKUP_API_TOKEN }}
|
|
112
|
+
GH_TOKEN: ${{ github.token }}
|
|
101
113
|
|
|
102
114
|
# Save Jedi state — framework, config, persistence all cached together
|
|
103
115
|
- name: Save Jedi state
|
package/dist/index.js
CHANGED
|
@@ -9604,6 +9604,7 @@ async function spawnClaude(prompt2, opts) {
|
|
|
9604
9604
|
const reader = proc.stdout.getReader();
|
|
9605
9605
|
const decoder = new TextDecoder;
|
|
9606
9606
|
let buffer = "";
|
|
9607
|
+
let lastTextResponse = "";
|
|
9607
9608
|
try {
|
|
9608
9609
|
while (true) {
|
|
9609
9610
|
const { done, value } = await reader.read();
|
|
@@ -9622,6 +9623,16 @@ async function spawnClaude(prompt2, opts) {
|
|
|
9622
9623
|
const output = formatStreamEvent(event);
|
|
9623
9624
|
if (output)
|
|
9624
9625
|
process.stdout.write(output);
|
|
9626
|
+
if (event.type === "assistant" && event.message?.content) {
|
|
9627
|
+
for (const block of event.message.content) {
|
|
9628
|
+
if (block.type === "text" && block.text) {
|
|
9629
|
+
lastTextResponse = block.text;
|
|
9630
|
+
}
|
|
9631
|
+
}
|
|
9632
|
+
}
|
|
9633
|
+
if (event.type === "result" && event.result) {
|
|
9634
|
+
lastTextResponse = event.result;
|
|
9635
|
+
}
|
|
9625
9636
|
} catch {}
|
|
9626
9637
|
}
|
|
9627
9638
|
}
|
|
@@ -9631,13 +9642,23 @@ async function spawnClaude(prompt2, opts) {
|
|
|
9631
9642
|
const output = formatStreamEvent(event);
|
|
9632
9643
|
if (output)
|
|
9633
9644
|
process.stdout.write(output);
|
|
9645
|
+
if (event.type === "assistant" && event.message?.content) {
|
|
9646
|
+
for (const block of event.message.content) {
|
|
9647
|
+
if (block.type === "text" && block.text) {
|
|
9648
|
+
lastTextResponse = block.text;
|
|
9649
|
+
}
|
|
9650
|
+
}
|
|
9651
|
+
}
|
|
9652
|
+
if (event.type === "result" && event.result) {
|
|
9653
|
+
lastTextResponse = event.result;
|
|
9654
|
+
}
|
|
9634
9655
|
} catch {}
|
|
9635
9656
|
}
|
|
9636
9657
|
} catch {}
|
|
9637
9658
|
const exitCode = await proc.exited;
|
|
9638
9659
|
process.stdout.write(`
|
|
9639
9660
|
`);
|
|
9640
|
-
return { exitCode };
|
|
9661
|
+
return { exitCode, response: lastTextResponse };
|
|
9641
9662
|
}
|
|
9642
9663
|
|
|
9643
9664
|
// src/storage/index.ts
|
|
@@ -11085,7 +11106,7 @@ async function fetchCommentThread(repo, issueNumber) {
|
|
|
11085
11106
|
author: parsed.author,
|
|
11086
11107
|
body: parsed.body,
|
|
11087
11108
|
createdAt: parsed.createdAt,
|
|
11088
|
-
isJedi: parsed.body.includes("
|
|
11109
|
+
isJedi: parsed.body.includes("### \u2694\uFE0F Jedi")
|
|
11089
11110
|
});
|
|
11090
11111
|
} catch {}
|
|
11091
11112
|
}
|
|
@@ -11126,21 +11147,19 @@ function buildConversationContext(thread, currentCommentId) {
|
|
|
11126
11147
|
return { history: lines.join(`
|
|
11127
11148
|
`), previousJediRuns, isFollowUp };
|
|
11128
11149
|
}
|
|
11129
|
-
function
|
|
11130
|
-
const status = success ? "Completed" : "Failed";
|
|
11131
|
-
const icon = success ? "white_check_mark" : "x";
|
|
11150
|
+
function formatJediComment(response) {
|
|
11132
11151
|
return [
|
|
11133
|
-
`###
|
|
11134
|
-
``,
|
|
11135
|
-
`<details>`,
|
|
11136
|
-
`<summary>Details</summary>`,
|
|
11152
|
+
`### \u2694\uFE0F Jedi`,
|
|
11137
11153
|
``,
|
|
11138
|
-
|
|
11139
|
-
|
|
11140
|
-
|
|
11154
|
+
response
|
|
11155
|
+
].join(`
|
|
11156
|
+
`);
|
|
11157
|
+
}
|
|
11158
|
+
function formatErrorComment(command, summary) {
|
|
11159
|
+
return [
|
|
11160
|
+
`### \u2694\uFE0F Jedi`,
|
|
11141
11161
|
``,
|
|
11142
|
-
|
|
11143
|
-
`_Powered by [@benzotti/jedi](https://github.com/zottiben/jedi)_`
|
|
11162
|
+
`**${command} failed.** ${summary}`
|
|
11144
11163
|
].join(`
|
|
11145
11164
|
`);
|
|
11146
11165
|
}
|
|
@@ -11165,6 +11184,9 @@ function parseComment(comment, isFollowUp) {
|
|
|
11165
11184
|
const clickUpUrl = clickUpMatch ? clickUpMatch[1] : null;
|
|
11166
11185
|
const description = body.replace(/(https?:\/\/[^\s]*clickup\.com\/t\/[a-z0-9]+)/i, "").replace(/\s+/g, " ").trim();
|
|
11167
11186
|
const lower = body.toLowerCase();
|
|
11187
|
+
if (lower.startsWith("ping") || lower.startsWith("status")) {
|
|
11188
|
+
return { command: "ping", description: "", clickUpUrl: null, fullFlow: false, isFeedback: false };
|
|
11189
|
+
}
|
|
11168
11190
|
if (lower.startsWith("plan ")) {
|
|
11169
11191
|
return { command: "plan", description, clickUpUrl, fullFlow: false, isFeedback: false };
|
|
11170
11192
|
}
|
|
@@ -11259,6 +11281,49 @@ var actionCommand = defineCommand({
|
|
|
11259
11281
|
if (repo && commentId) {
|
|
11260
11282
|
await reactToComment(repo, commentId, "eyes").catch(() => {});
|
|
11261
11283
|
}
|
|
11284
|
+
if (intent.command === "ping") {
|
|
11285
|
+
const { existsSync: existsSync13 } = await import("fs");
|
|
11286
|
+
const { join: join12 } = await import("path");
|
|
11287
|
+
const frameworkExists = existsSync13(join12(cwd, ".jdi/framework"));
|
|
11288
|
+
const claudeMdExists = existsSync13(join12(cwd, ".claude/CLAUDE.md"));
|
|
11289
|
+
const stateExists = existsSync13(join12(cwd, ".jdi/config/state.yaml"));
|
|
11290
|
+
const learningsExists = existsSync13(join12(cwd, ".jdi/persistence/learnings.md"));
|
|
11291
|
+
let version = "unknown";
|
|
11292
|
+
try {
|
|
11293
|
+
const pkgPath = join12(cwd, "node_modules/@benzotti/jedi/package.json");
|
|
11294
|
+
if (existsSync13(pkgPath)) {
|
|
11295
|
+
const pkg = JSON.parse(await Bun.file(pkgPath).text());
|
|
11296
|
+
version = pkg.version;
|
|
11297
|
+
}
|
|
11298
|
+
} catch {}
|
|
11299
|
+
const statusBody = [
|
|
11300
|
+
`**Framework Status**`,
|
|
11301
|
+
``,
|
|
11302
|
+
`| Component | Status |`,
|
|
11303
|
+
`|-----------|--------|`,
|
|
11304
|
+
`| Framework files | ${frameworkExists ? "found" : "missing"} |`,
|
|
11305
|
+
`| CLAUDE.md | ${claudeMdExists ? "found" : "missing"} |`,
|
|
11306
|
+
`| State config | ${stateExists ? "found" : "missing"} |`,
|
|
11307
|
+
`| Learnings | ${learningsExists ? "found" : "missing"} |`,
|
|
11308
|
+
`| Version | \`${version}\` |`
|
|
11309
|
+
].join(`
|
|
11310
|
+
`);
|
|
11311
|
+
const lines = formatJediComment(statusBody).split(`
|
|
11312
|
+
`);
|
|
11313
|
+
if (repo && issueNumber) {
|
|
11314
|
+
await postGitHubComment(repo, issueNumber, lines.join(`
|
|
11315
|
+
`)).catch((err) => {
|
|
11316
|
+
consola.error("Failed to post ping comment:", err);
|
|
11317
|
+
});
|
|
11318
|
+
} else {
|
|
11319
|
+
console.log(lines.join(`
|
|
11320
|
+
`));
|
|
11321
|
+
}
|
|
11322
|
+
if (repo && commentId) {
|
|
11323
|
+
await reactToComment(repo, commentId, "+1").catch(() => {});
|
|
11324
|
+
}
|
|
11325
|
+
return;
|
|
11326
|
+
}
|
|
11262
11327
|
const storage = await createStorage(cwd);
|
|
11263
11328
|
const { learningsPath, codebaseIndexPath } = await loadPersistedState(cwd, storage);
|
|
11264
11329
|
let ticketContext = "";
|
|
@@ -11401,11 +11466,13 @@ Use the ClickUp ticket above as the primary requirements source.` : ``,
|
|
|
11401
11466
|
}
|
|
11402
11467
|
}
|
|
11403
11468
|
let success = true;
|
|
11469
|
+
let fullResponse = "";
|
|
11404
11470
|
try {
|
|
11405
|
-
const { exitCode } = await spawnClaude(prompt2, {
|
|
11471
|
+
const { exitCode, response } = await spawnClaude(prompt2, {
|
|
11406
11472
|
cwd,
|
|
11407
11473
|
permissionMode: "bypassPermissions"
|
|
11408
11474
|
});
|
|
11475
|
+
fullResponse = response;
|
|
11409
11476
|
if (exitCode !== 0) {
|
|
11410
11477
|
success = false;
|
|
11411
11478
|
consola.error(`Claude exited with code ${exitCode}`);
|
|
@@ -11431,6 +11498,13 @@ Use the ClickUp ticket above as the primary requirements source.` : ``,
|
|
|
11431
11498
|
if (implResult.exitCode !== 0) {
|
|
11432
11499
|
success = false;
|
|
11433
11500
|
}
|
|
11501
|
+
if (implResult.response) {
|
|
11502
|
+
fullResponse += `
|
|
11503
|
+
|
|
11504
|
+
---
|
|
11505
|
+
|
|
11506
|
+
` + implResult.response;
|
|
11507
|
+
}
|
|
11434
11508
|
}
|
|
11435
11509
|
} catch (err) {
|
|
11436
11510
|
success = false;
|
|
@@ -11443,8 +11517,14 @@ Use the ClickUp ticket above as the primary requirements source.` : ``,
|
|
|
11443
11517
|
consola.info("Codebase index persisted to storage");
|
|
11444
11518
|
if (repo && issueNumber) {
|
|
11445
11519
|
const actionLabel = intent.isFeedback ? "feedback" : intent.command;
|
|
11446
|
-
|
|
11447
|
-
|
|
11520
|
+
let commentBody;
|
|
11521
|
+
if (success && fullResponse) {
|
|
11522
|
+
commentBody = formatJediComment(fullResponse);
|
|
11523
|
+
} else if (!success) {
|
|
11524
|
+
commentBody = formatErrorComment(actionLabel, "Check workflow logs for details.");
|
|
11525
|
+
} else {
|
|
11526
|
+
commentBody = formatJediComment(`Executed \`${actionLabel}\` successfully.`);
|
|
11527
|
+
}
|
|
11448
11528
|
await postGitHubComment(repo, issueNumber, commentBody).catch((err) => {
|
|
11449
11529
|
consola.error("Failed to post result comment:", err);
|
|
11450
11530
|
});
|
|
@@ -11508,6 +11588,7 @@ var setupActionCommand = defineCommand({
|
|
|
11508
11588
|
" Hey Jedi do <clickup-ticket-url>",
|
|
11509
11589
|
" Hey Jedi review",
|
|
11510
11590
|
" Hey Jedi feedback",
|
|
11591
|
+
" Hey Jedi ping",
|
|
11511
11592
|
"",
|
|
11512
11593
|
"Conversation: Reply to Jedi with feedback to iterate,",
|
|
11513
11594
|
"or say 'approved' to finalise."
|
|
@@ -11518,7 +11599,7 @@ var setupActionCommand = defineCommand({
|
|
|
11518
11599
|
// package.json
|
|
11519
11600
|
var package_default = {
|
|
11520
11601
|
name: "@benzotti/jedi",
|
|
11521
|
-
version: "0.1.
|
|
11602
|
+
version: "0.1.16",
|
|
11522
11603
|
description: "JDI - Context-efficient AI development framework for Claude Code",
|
|
11523
11604
|
type: "module",
|
|
11524
11605
|
bin: {
|