@mrciphersmith/keryx 0.2.145 → 0.2.149
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/README.md +6 -1
- package/dist/cli.js +118 -16
- package/package.json +1 -1
- package/src/gdskills/bundled/rules/core/session-plan-bridge.mdc +96 -0
- package/src/gdskills/bundled/skills/orchestration/feature-analyzer/SKILL.md +1 -1
- package/src/gdskills/bundled/skills/orchestration/feature-dev/SKILL.md +1 -1
- package/src/gdskills/bundled/skills/orchestration/flow-orchestrator/SKILL.md +1 -1
- package/src/gdskills/bundled/skills/orchestration/issue-analyzer/SKILL.md +1 -1
- package/src/gdskills/bundled/skills/orchestration/job-orchestrator/SKILL.md +1 -1
- package/src/gdskills/bundled/skills/planning/autodoc-orchestrator/SKILL.md +1 -1
- package/src/gdskills/bundled/skills/planning/docpack-orchestrator/SKILL.md +1 -1
- package/src/gdskills/bundled/skills/review/review-orchestrator/SKILL.md +1 -1
- package/src/gdskills/bundled/skills/review/review-pr-feedback/SKILL.md +1 -1
package/README.md
CHANGED
|
@@ -260,7 +260,12 @@ What is in it today:
|
|
|
260
260
|
blocked ids, and the plan file it lives in. A plan can also be published FOR
|
|
261
261
|
APPROVAL — items marked `proposed` await a human, never force the agent to
|
|
262
262
|
continue, and are shown as `◇ awaiting approval` in both the sidebar and the
|
|
263
|
-
modal.
|
|
263
|
+
modal. Orchestrators publish into this same view — `job-orchestrator`,
|
|
264
|
+
`flow-orchestrator`, `review-orchestrator`, `issue-analyzer`,
|
|
265
|
+
`feature-analyzer`, `autodoc-orchestrator`, `docpack-orchestrator`,
|
|
266
|
+
`feature-dev` and `review-pr-feedback` project their own steps here under the
|
|
267
|
+
`session-plan-bridge` rule, so a run driven by one of them is watchable while
|
|
268
|
+
it runs instead of only after it reports.
|
|
264
269
|
- **Theme-aware rich transcripts.** Assistant prose, headings, emphasis,
|
|
265
270
|
inline code, fenced code, diffs, and GFM pipe tables use semantic colors
|
|
266
271
|
derived from the selected `/theme`. Use a language fence such as
|
package/dist/cli.js
CHANGED
|
@@ -30207,15 +30207,49 @@ ${shown.join(`
|
|
|
30207
30207
|
const risk = toolByName.get(call.name)?.definition.risk;
|
|
30208
30208
|
const isPureReadTool = risk === "read" && !DURABLE_READ_TOOL_NAMES.has(call.name);
|
|
30209
30209
|
if (!isPureReadTool && untrustedContentSeen) {
|
|
30210
|
-
const
|
|
30211
|
-
|
|
30212
|
-
|
|
30213
|
-
|
|
30214
|
-
|
|
30215
|
-
|
|
30216
|
-
|
|
30217
|
-
|
|
30218
|
-
|
|
30210
|
+
const approver = io.requestApproval;
|
|
30211
|
+
if (deps.unattended === true || approver === undefined) {
|
|
30212
|
+
const result = {
|
|
30213
|
+
output: "tool blocked: external web content cannot authorize further tool calls in this turn",
|
|
30214
|
+
isError: true
|
|
30215
|
+
};
|
|
30216
|
+
io.onToolResult?.(call.name, result);
|
|
30217
|
+
history.push({ role: "tool", content: result.output, provenance: "tool", toolCallId: call.id, ts: now() });
|
|
30218
|
+
io.onHistoryChange?.("tool");
|
|
30219
|
+
gateBlockedAny = true;
|
|
30220
|
+
continue;
|
|
30221
|
+
}
|
|
30222
|
+
const taintFingerprint = toolCallHash(call.name, call.input);
|
|
30223
|
+
let taintApproved;
|
|
30224
|
+
try {
|
|
30225
|
+
const response = await approver(call.name, call.input, {
|
|
30226
|
+
fingerprint: taintFingerprint,
|
|
30227
|
+
destructive: risk === "destructive",
|
|
30228
|
+
untrustedOrigin: true
|
|
30229
|
+
});
|
|
30230
|
+
taintApproved = isApprovalFor(response, taintFingerprint);
|
|
30231
|
+
} catch (err) {
|
|
30232
|
+
const result = {
|
|
30233
|
+
output: `${call.name} not executed: the approval prompt failed (${err instanceof Error ? err.message : String(err)})`,
|
|
30234
|
+
isError: true
|
|
30235
|
+
};
|
|
30236
|
+
io.onToolResult?.(call.name, result);
|
|
30237
|
+
history.push({ role: "tool", content: result.output, provenance: "tool", toolCallId: call.id, ts: now() });
|
|
30238
|
+
io.onHistoryChange?.("tool");
|
|
30239
|
+
gateBlockedAny = true;
|
|
30240
|
+
continue;
|
|
30241
|
+
}
|
|
30242
|
+
if (!taintApproved) {
|
|
30243
|
+
const result = {
|
|
30244
|
+
output: "tool blocked: external web content cannot authorize this call, and the user did not authorize it either",
|
|
30245
|
+
isError: true
|
|
30246
|
+
};
|
|
30247
|
+
io.onToolResult?.(call.name, result);
|
|
30248
|
+
history.push({ role: "tool", content: result.output, provenance: "tool", toolCallId: call.id, ts: now() });
|
|
30249
|
+
io.onHistoryChange?.("tool");
|
|
30250
|
+
gateBlockedAny = true;
|
|
30251
|
+
continue;
|
|
30252
|
+
}
|
|
30219
30253
|
}
|
|
30220
30254
|
io.onToolCall?.(call.name, call.input);
|
|
30221
30255
|
const reservation = reservationByCallId.get(call.id) ?? reserveToolAttempt(budget, call.name, call.input);
|
|
@@ -51463,7 +51497,7 @@ import path47 from "path";
|
|
|
51463
51497
|
// package.json
|
|
51464
51498
|
var package_default = {
|
|
51465
51499
|
name: "@mrciphersmith/keryx",
|
|
51466
|
-
version: "0.2.
|
|
51500
|
+
version: "0.2.149",
|
|
51467
51501
|
description: "Version-controlled project context for AI coding agents: code graph, architecture wiki, project memory, relevant tests, quality signals, and task flows.",
|
|
51468
51502
|
private: false,
|
|
51469
51503
|
publishConfig: {
|
|
@@ -88755,6 +88789,9 @@ function renderUseToolApprovalLines(description, meta) {
|
|
|
88755
88789
|
if (meta?.destructive === true) {
|
|
88756
88790
|
lines.push(" this tool is treated as destructive \u2014 it is a third party's code");
|
|
88757
88791
|
}
|
|
88792
|
+
if (meta?.untrustedOrigin === true) {
|
|
88793
|
+
lines.push(" \u26A0 follows untrusted external content \u2014 that content cannot authorize this call");
|
|
88794
|
+
}
|
|
88758
88795
|
return lines;
|
|
88759
88796
|
}
|
|
88760
88797
|
function summariseUseToolApproval(description) {
|
|
@@ -103198,6 +103235,10 @@ function formatPlanMeta(plan, dir) {
|
|
|
103198
103235
|
"",
|
|
103199
103236
|
"Storage <session>/plan.json \u2014 a sibling of slate.json, so a completed",
|
|
103200
103237
|
" Flow closing its slate can no longer take the plan with it.",
|
|
103238
|
+
"",
|
|
103239
|
+
"Note This is the agent's own plan for this session. The `/plan on|off`",
|
|
103240
|
+
" COMMAND is a different thing \u2014 the session's read-only mode, which",
|
|
103241
|
+
" this view neither shows nor changes.",
|
|
103201
103242
|
...dir === undefined ? [] : [`Session ${dir}`]
|
|
103202
103243
|
].join(`
|
|
103203
103244
|
`);
|
|
@@ -103265,7 +103306,7 @@ function presentExecutionPlanInspector(openModalFn, otui, chrome, options) {
|
|
|
103265
103306
|
};
|
|
103266
103307
|
let unsubscribe;
|
|
103267
103308
|
const handle = openModalFn(otui, chrome, {
|
|
103268
|
-
title: "
|
|
103309
|
+
title: "Session plan",
|
|
103269
103310
|
tabs: [
|
|
103270
103311
|
{ id: "plan", label: "Plan" },
|
|
103271
103312
|
{ id: "meta", label: "Meta" }
|
|
@@ -104086,6 +104127,7 @@ function attachUsageIo(io, chrome) {
|
|
|
104086
104127
|
totalOut = 0;
|
|
104087
104128
|
chrome.setHeaderMeta("\u21910 \u21930");
|
|
104088
104129
|
chrome.setContextTotal(0);
|
|
104130
|
+
chrome.setUsage?.(0, 0);
|
|
104089
104131
|
}
|
|
104090
104132
|
});
|
|
104091
104133
|
}
|
|
@@ -105754,6 +105796,12 @@ async function launchTuiAgentShell(opts) {
|
|
|
105754
105796
|
};
|
|
105755
105797
|
const approvalContext = createApprovalContextLoader(opts.session?.cwd ?? process.cwd());
|
|
105756
105798
|
io.requestApproval = async (tool, inputJson, meta) => {
|
|
105799
|
+
if (meta?.untrustedOrigin === true) {
|
|
105800
|
+
transcript.add(new otui.TextRenderable(r, {
|
|
105801
|
+
id: `ap${uid++}`,
|
|
105802
|
+
content: otui.t`${otui.yellow("\u26A0 follows untrusted external content \u2014 it cannot authorize this call; your answer does")}`
|
|
105803
|
+
}));
|
|
105804
|
+
}
|
|
105757
105805
|
if (tool === "spawn_subagent") {
|
|
105758
105806
|
let mode = "read_only";
|
|
105759
105807
|
let taskPreview = inputJson;
|
|
@@ -109713,6 +109761,13 @@ ${GUTTER}${style.dim(formatReasoningOneLiner({
|
|
|
109713
109761
|
},
|
|
109714
109762
|
requestApproval: async (tool, input, meta) => {
|
|
109715
109763
|
stopSpinner();
|
|
109764
|
+
if (meta?.untrustedOrigin === true) {
|
|
109765
|
+
out(`
|
|
109766
|
+
${GUTTER}${style.red("\u26A0 this call follows untrusted external content in this turn")}
|
|
109767
|
+
`);
|
|
109768
|
+
out(`${GUTTER}${style.dim("that content cannot authorize it \u2014 only your answer can")}
|
|
109769
|
+
`);
|
|
109770
|
+
}
|
|
109716
109771
|
if (tool === "apply_patch") {
|
|
109717
109772
|
const patch = extractPatchText(input);
|
|
109718
109773
|
out(`
|
|
@@ -118202,6 +118257,16 @@ async function main() {
|
|
|
118202
118257
|
}
|
|
118203
118258
|
const route = CLI_ROUTES[command];
|
|
118204
118259
|
if (route) {
|
|
118260
|
+
if (shouldInterceptHelp(command, args.slice(1))) {
|
|
118261
|
+
const usage = groupUsage(command);
|
|
118262
|
+
console.log(usage === undefined ? `keryx ${VERSION2}
|
|
118263
|
+
|
|
118264
|
+
${USAGE_BODY}` : `keryx ${command} \u2014 usage:
|
|
118265
|
+
|
|
118266
|
+
${usage}
|
|
118267
|
+
`);
|
|
118268
|
+
return;
|
|
118269
|
+
}
|
|
118205
118270
|
await route(args.slice(1));
|
|
118206
118271
|
return;
|
|
118207
118272
|
}
|
|
@@ -118209,10 +118274,7 @@ async function main() {
|
|
|
118209
118274
|
printHelp25();
|
|
118210
118275
|
process.exitCode = 1;
|
|
118211
118276
|
}
|
|
118212
|
-
|
|
118213
|
-
console.log(`keryx ${VERSION2}
|
|
118214
|
-
|
|
118215
|
-
Usage:
|
|
118277
|
+
var USAGE_BODY = `Usage:
|
|
118216
118278
|
keryx Show CLI usage
|
|
118217
118279
|
keryx shell [-c|--continue] [-r|--resume [id]] [--provider <p>] [--model <m>] [--base-url <url>] [--agent|--chat] [--tui|--no-tui]
|
|
118218
118280
|
Start TUI agent shell (sessions are per-project)
|
|
@@ -118376,6 +118438,42 @@ Commands:
|
|
|
118376
118438
|
workspace Shared Agent Context: workspaces, FWK reads, propose/review (module sac)
|
|
118377
118439
|
retention Bound stores that grow without bound (gdctx raw/artifacts, owner write-conflict sidecars)
|
|
118378
118440
|
forgetting Read the deletion trail \u2014 was this removed, or did it never exist?
|
|
118441
|
+
`;
|
|
118442
|
+
function printHelp25() {
|
|
118443
|
+
console.log(`keryx ${VERSION2}
|
|
118444
|
+
|
|
118445
|
+
${USAGE_BODY}`);
|
|
118446
|
+
}
|
|
118447
|
+
function helpRequestedFor(rest) {
|
|
118448
|
+
const separator = rest.indexOf("--");
|
|
118449
|
+
const head = separator === -1 ? rest : rest.slice(0, separator);
|
|
118450
|
+
return head.some((token) => token === "--help" || token === "-h");
|
|
118451
|
+
}
|
|
118452
|
+
var DEEP_HELP_GROUPS = new Set(["agents", "shell"]);
|
|
118453
|
+
function shouldInterceptHelp(command, rest) {
|
|
118454
|
+
return !DEEP_HELP_GROUPS.has(command) && helpRequestedFor(rest);
|
|
118455
|
+
}
|
|
118456
|
+
function groupUsage(command, usage = USAGE_BODY) {
|
|
118457
|
+
const lines = usage.split(`
|
|
118458
|
+
`);
|
|
118459
|
+
const startsGroup = new RegExp(`^ {2,}keryx ${command}(?:\\s|$)`);
|
|
118460
|
+
const isContinuation = /^ {4,}\S/;
|
|
118461
|
+
const out = [];
|
|
118462
|
+
for (let i = 0;i < lines.length; i += 1) {
|
|
118463
|
+
const line = lines[i] ?? "";
|
|
118464
|
+
if (!startsGroup.test(line)) {
|
|
118465
|
+
continue;
|
|
118466
|
+
}
|
|
118467
|
+
out.push(line);
|
|
118468
|
+
for (let j = i + 1;j < lines.length; j += 1) {
|
|
118469
|
+
const next = lines[j] ?? "";
|
|
118470
|
+
if (!isContinuation.test(next) || startsGroup.test(next) || /keryx\s/.test(next)) {
|
|
118471
|
+
break;
|
|
118472
|
+
}
|
|
118473
|
+
out.push(next);
|
|
118474
|
+
}
|
|
118475
|
+
}
|
|
118476
|
+
return out.length === 0 ? undefined : out.join(`
|
|
118379
118477
|
`);
|
|
118380
118478
|
}
|
|
118381
118479
|
function exitCodeForError(error) {
|
|
@@ -118389,6 +118487,10 @@ if (import.meta.main) {
|
|
|
118389
118487
|
}
|
|
118390
118488
|
export {
|
|
118391
118489
|
CLI_ROUTES,
|
|
118490
|
+
USAGE_BODY,
|
|
118392
118491
|
exitCodeForError,
|
|
118393
|
-
|
|
118492
|
+
groupUsage,
|
|
118493
|
+
helpRequestedFor,
|
|
118494
|
+
main,
|
|
118495
|
+
shouldInterceptHelp
|
|
118394
118496
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mrciphersmith/keryx",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.149",
|
|
4
4
|
"description": "Version-controlled project context for AI coding agents: code graph, architecture wiki, project memory, relevant tests, quality signals, and task flows.",
|
|
5
5
|
"private": false,
|
|
6
6
|
"publishConfig": {
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: "Bridge between an orchestrator's own CLI-owned plan and the session execution plan the operator watches in the sidebar and the /plan modal: publish the orchestrator's steps as plan items under the SAME ids, mirror every status change at the moment the orchestrator updates its own state, and use `proposed` for a plan awaiting a human. Use when a skill orchestrates multi-step work (job-orchestrator, flow-orchestrator, review-orchestrator)."
|
|
3
|
+
alwaysApply: false
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Session Plan Bridge
|
|
7
|
+
|
|
8
|
+
## Purpose
|
|
9
|
+
|
|
10
|
+
An orchestrator already has a plan. `job-orchestrator` has fifteen steps in a job
|
|
11
|
+
package that `keryx job status` prints; `flow-orchestrator` has tasks `T1..Tn`
|
|
12
|
+
with dependencies in the Flow package; `review-orchestrator` has a fifteen-step
|
|
13
|
+
checklist. Until this rule existed, every one of those plans was invisible while
|
|
14
|
+
it ran: the operator saw phases announced in prose, and had to ask.
|
|
15
|
+
|
|
16
|
+
The session execution plan is the surface that fixes that. It is not a second
|
|
17
|
+
plan — it is a PROJECTION of the orchestrator's own plan into the one place the
|
|
18
|
+
operator is already looking (the sidebar's Plan section, and `/plan` for the
|
|
19
|
+
whole list). The orchestrator's own state stays the only source of truth for
|
|
20
|
+
what the work is.
|
|
21
|
+
|
|
22
|
+
## The mechanism, in one paragraph
|
|
23
|
+
|
|
24
|
+
`plan_set` publishes the whole plan (replace-all, optimistic `expectedRevision`);
|
|
25
|
+
`plan_update` moves one item (`{expectedRevision, itemId, status}`); `plan_get`
|
|
26
|
+
reads it back before a write when a conflict is possible. Statuses are
|
|
27
|
+
`proposed | pending | in_progress | completed | blocked | skipped`, item ids are
|
|
28
|
+
stable strings, and at most one item may be `in_progress` — the mechanism refuses
|
|
29
|
+
a second one. `proposed` means "published for a human to approve": it is NOT work
|
|
30
|
+
in progress, so it never makes the agent continue on its own, which is what makes
|
|
31
|
+
"publish the plan, then stop and wait for the operator" a real stopping point.
|
|
32
|
+
|
|
33
|
+
## Item ids are the orchestrator's own ids — never invented
|
|
34
|
+
|
|
35
|
+
| Orchestrator | Item ids | Where they come from |
|
|
36
|
+
|---|---|---|
|
|
37
|
+
| `job-orchestrator` | the step ids `keryx job status <name> --json` reports — `analyze`, `context`, `prepare`, `tests-creator`, `implement`, `sanity-check`, `verify`, `review`, `security`, `fix`, `verify-post-fix`, `perf-check`, `report`, `pr`, `deploy` | `keryx job status <name>` (read it, never retype it) |
|
|
38
|
+
| `flow-orchestrator` | the Flow's task ids `T1..Tn` | `keryx flow status <id>` / the Flow's `tasks.md` |
|
|
39
|
+
| `review-orchestrator` | `step-0` … `step-14`, from its own numbered checklist | its Workflow section |
|
|
40
|
+
|
|
41
|
+
An id that exists only in the session plan is drift by construction: the operator
|
|
42
|
+
cannot reconcile it with the CLI, and a resumed run cannot match it. If a
|
|
43
|
+
conditional step never runs, it is `skipped` — never absent.
|
|
44
|
+
|
|
45
|
+
## Status mapping — the vocabularies disagree, this is the translation
|
|
46
|
+
|
|
47
|
+
| Orchestrator's own status | Session plan status |
|
|
48
|
+
|---|---|
|
|
49
|
+
| `pending` (job) | `pending` |
|
|
50
|
+
| `in-progress` (job, hyphenated) | `in_progress` |
|
|
51
|
+
| `completed` | `completed` |
|
|
52
|
+
| `skipped` | `skipped` |
|
|
53
|
+
| `failed` (job / flow task) | `blocked` — it needs a human, and the failure reason goes in the item's title |
|
|
54
|
+
| `blocked` (flow task) | `blocked` |
|
|
55
|
+
|
|
56
|
+
## When to publish, and when to update
|
|
57
|
+
|
|
58
|
+
1. **Publish once, as soon as the plan exists** — after `job-orchestrator`'s 1.1
|
|
59
|
+
plan build, after the Flow's task list exists in Phase 1, after
|
|
60
|
+
`review-orchestrator` fixes its scope and dispatch in Step 6. Not at the end.
|
|
61
|
+
2. **`proposed` for a plan that is awaiting the operator.** Where an orchestrator
|
|
62
|
+
stops to ask — `job-orchestrator` 1.3's "Proceed? (yes / adjust …)" and
|
|
63
|
+
`flow-orchestrator` Phase 4's completion choice — the items are `proposed`
|
|
64
|
+
until the answer arrives, then become `pending`/`in_progress`. This is the
|
|
65
|
+
whole point of the status: the sidebar says `◇ awaiting approval` at exactly
|
|
66
|
+
the moment the orchestrator is waiting for the human.
|
|
67
|
+
3. **Mirror every status change in the same breath as your own.** The call that
|
|
68
|
+
marks a step in `keryx job step …` / `keryx flow task done …` is the call that
|
|
69
|
+
updates the session plan. A batch of `plan_update`s after the work is done is
|
|
70
|
+
not progress reporting, it is a summary.
|
|
71
|
+
4. **One `in_progress`** — the step being executed right now. Progress the
|
|
72
|
+
operator can see is a moving marker, not a growing list of ticks.
|
|
73
|
+
5. **`blocked` when the run needs the operator** — an approval, a credential, a
|
|
74
|
+
failure that needs a decision.
|
|
75
|
+
6. **`plan_get` before a write when a conflict is possible** (a resumed session, a
|
|
76
|
+
second shell on the same checkout) and re-apply against the revision you read.
|
|
77
|
+
|
|
78
|
+
## What the bridge is NOT
|
|
79
|
+
|
|
80
|
+
- Not a journal. Dispatch details, subagent names, token budgets and reasoning
|
|
81
|
+
belong in `journal.md` / the job's `man/` documents, not in plan items.
|
|
82
|
+
- Not authoritative. If the session plan and `keryx job status` / `keryx flow
|
|
83
|
+
status` disagree, the CLI state wins and the session plan is corrected on the
|
|
84
|
+
next update — the projection follows the plan, never the other way round.
|
|
85
|
+
- Not a completion signal. A plan whose items are all `completed` does not mean
|
|
86
|
+
the job is done: verification, review and the completion report are the
|
|
87
|
+
orchestrator's own gates.
|
|
88
|
+
|
|
89
|
+
## Red Flags — stop and re-read this rule if you are thinking:
|
|
90
|
+
|
|
91
|
+
| Rationalization | Why it's wrong |
|
|
92
|
+
|---|---|
|
|
93
|
+
| "I'll publish the plan when the work is finished and I know all the statuses" | That is a report, not a plan. The sidebar exists so the operator can watch WHILE it runs — a plan published at the end has nothing to show. |
|
|
94
|
+
| "The ids are mine to choose, as long as the titles match" | Then the session plan and `keryx job status` cannot be reconciled by a human or by a resumed run, and the projection has become a second plan. |
|
|
95
|
+
| "`proposed` is the same as `pending`, I'll just use `pending`" | `pending` is actionable work, so the agent continues on its own and the "wait for approval" gate disappears. |
|
|
96
|
+
| "Skipping the plan is fine when the job is short" | Then the operator's single progress surface is empty for exactly the runs where watching matters most. |
|
|
@@ -32,7 +32,7 @@ Proceed directly with your assigned task.
|
|
|
32
32
|
|
|
33
33
|
## Purpose
|
|
34
34
|
|
|
35
|
-
Performs deep cross-repository analysis to understand business logic, architecture, API contracts, and implementation requirements. Generates structured documentation for both human developers and AI agents.
|
|
35
|
+
Performs deep cross-repository analysis to understand business logic, architecture, API contracts, and implementation requirements. Generates structured documentation for both human developers and AI agents. Plan bridge: publish each `Step N` this run will take with `plan_set`, and update it with `plan_update` as it finishes — see the `session-plan-bridge` rule.
|
|
36
36
|
|
|
37
37
|
**Two Analysis Modes:**
|
|
38
38
|
|
|
@@ -28,7 +28,7 @@ End-to-end feature development workflow from idea to merge-ready PR.
|
|
|
28
28
|
|
|
29
29
|
## Arguments
|
|
30
30
|
|
|
31
|
-
- `/feature-dev <description>` — start from a text description
|
|
31
|
+
- `/feature-dev <description>` — start from a text description. Plan bridge: publish `phase-1`…`phase-8` with `plan_set`/`plan_update`; while a confirmation question is open the items are `proposed` — see the `session-plan-bridge` rule.
|
|
32
32
|
- `/feature-dev #<issue>` — start from a GitHub issue
|
|
33
33
|
- `/feature-dev --resume` — resume interrupted feature-dev (checks for existing worktree/branch)
|
|
34
34
|
|
|
@@ -23,7 +23,7 @@ license: "MIT"
|
|
|
23
23
|
|
|
24
24
|
## Purpose
|
|
25
25
|
|
|
26
|
-
Flow Orchestrator is the Task Manager-aware implementation orchestrator.
|
|
26
|
+
Flow Orchestrator is the Task Manager-aware implementation orchestrator. Plan bridge: publish the tasks with `plan_set` under the ids `T1`…`Tn`, mirror each `keryx flow task done` with `plan_update`, and publish Phase 4's completion choice as `proposed` — see the `session-plan-bridge` rule.
|
|
27
27
|
It wraps the existing gdskills pipeline with `keryx flow` state.
|
|
28
28
|
|
|
29
29
|
Use this skill instead of `job-orchestrator` when the user wants a managed
|
|
@@ -20,7 +20,7 @@ license: "MIT"
|
|
|
20
20
|
|
|
21
21
|
## Purpose
|
|
22
22
|
|
|
23
|
-
Analyzes a GitHub issue and decomposes it into atomic implementation tasks that can be dispatched to `task-implementer` sub-agents. Designed to run autonomously as a sub-agent — no user interaction required.
|
|
23
|
+
Analyzes a GitHub issue and decomposes it into atomic implementation tasks that can be dispatched to `task-implementer` sub-agents. Designed to run autonomously as a sub-agent — no user interaction required. Plan bridge: publish these four phases with `plan_set` under the ids `phase-1`…`phase-4` and move each with `plan_update` — see the `session-plan-bridge` rule.
|
|
24
24
|
|
|
25
25
|
**Input:** GitHub issue URL (or repo + number) + codebase path(s)
|
|
26
26
|
**Output:** JSON analysis object with one task entry per atomic task, each containing full context for implementation
|
|
@@ -32,7 +32,7 @@ Proceed directly with your assigned task.
|
|
|
32
32
|
|
|
33
33
|
## Purpose
|
|
34
34
|
|
|
35
|
-
Dynamic orchestrator that builds execution plans based on user intent. Unlike a fixed pipeline, the orchestrator adapts its workflow to what the user actually needs — from "just analyze this issue" to "implement, review, and create a PR". It dispatches sub-agents (`issue-analyzer`, `context-collector`, `tests-creator`, `task-implementer`, `code-verifier`, `review-orchestrator`) and persists every step, document and retry through `keryx job`, which writes `.metaproject/jobs/<job-name>/`.
|
|
35
|
+
Dynamic orchestrator that builds execution plans based on user intent. Unlike a fixed pipeline, the orchestrator adapts its workflow to what the user actually needs — from "just analyze this issue" to "implement, review, and create a PR". It dispatches sub-agents (`issue-analyzer`, `context-collector`, `tests-creator`, `task-implementer`, `code-verifier`, `review-orchestrator`) and persists every step, document and retry through `keryx job`, which writes `.metaproject/jobs/<job-name>/`. Plan bridge: publish these steps with `plan_set` under the ids `keryx job status` reports, mirror each `keryx job step` with `plan_update`, and mark them `proposed` while the approval above is open — see the `session-plan-bridge` rule.
|
|
36
36
|
|
|
37
37
|
**The package is the state.** `keryx job` is the only writer of `state.json`; it validates every write against the registered contract `job-orchestrator-state` and refuses one that does not conform. Never hand-write `state.json`, and never hold a step's outcome only in this session — a step recorded nowhere is a step that did not happen as far as the next session is concerned.
|
|
38
38
|
|
|
@@ -27,7 +27,7 @@ metadata:
|
|
|
27
27
|
|
|
28
28
|
## Purpose
|
|
29
29
|
|
|
30
|
-
Thin orchestrator that drives a 5-phase autonomous documentation pipeline.
|
|
30
|
+
Thin orchestrator that drives a 5-phase autonomous documentation pipeline. Plan bridge: publish `phase-0`…`phase-5` with `plan_set` and `plan_update`; `state.json` stays the source of truth — see the `session-plan-bridge` rule.
|
|
31
31
|
Takes an existing codebase as input, dispatches specialized subagents to scan,
|
|
32
32
|
analyze, and write documentation, and produces a complete documentation package
|
|
33
33
|
with no human gates.
|
|
@@ -34,7 +34,7 @@ When a USER runs this orchestrator directly (not as a dispatched subagent), at
|
|
|
34
34
|
the start ask "Collect execution statistics for this run? (yes/no)" per
|
|
35
35
|
`.metaproject/rules/core/execution-metrics.md`. If yes, append the
|
|
36
36
|
`## Execution Metrics` section at the end and save it under the docpack output
|
|
37
|
-
dir. Never ask or emit it when dispatched as a subagent.
|
|
37
|
+
dir. Never ask or emit it when dispatched as a subagent. Plan bridge: publish `phase-0`…`phase-5` with `plan_set`/`plan_update`, and hold them `proposed` while Phase 0's location question is open — see the `session-plan-bridge` rule.
|
|
38
38
|
|
|
39
39
|
## Iron Laws
|
|
40
40
|
|
|
@@ -61,7 +61,7 @@ already hold (`--scope`, `--findings`, `--diff-lines`, `--fix-attempt`,
|
|
|
61
61
|
`--verifier`, `--security`, `--forced-strategy-change`) and paste the `model`
|
|
62
62
|
block it prints into that dispatch.
|
|
63
63
|
|
|
64
|
-
Do NOT assign the tier by reading the table in `rules/core/model-selection.mdc`.
|
|
64
|
+
Do NOT assign the tier by reading the table in `rules/core/model-selection.mdc`. Plan bridge: publish this checklist with `plan_set` under the ids `step-0`…`step-14` and move each item with `plan_update` as its step completes — see the `session-plan-bridge` rule.
|
|
65
65
|
Working it out in your head is exactly the mechanical step that rule moves into
|
|
66
66
|
code — and it is the step that was documented as running for a whole release
|
|
67
67
|
while nothing called it.
|
|
@@ -56,7 +56,7 @@ a plan is the deliverable of analyze mode, not a preamble to one.
|
|
|
56
56
|
|
|
57
57
|
```
|
|
58
58
|
review-pr-feedback Progress:
|
|
59
|
-
- [ ] Step 1: Read job context (if CONTEXT_PATH provided)
|
|
59
|
+
- [ ] Step 1: Read job context (if CONTEXT_PATH provided). Plan bridge: publish each `Step N` with `plan_set`, and move it with `plan_update` as the step completes — see the `session-plan-bridge` rule.
|
|
60
60
|
- [ ] Step 2: Resolve the PR — owner, repo, number, head branch, base branch, head SHA
|
|
61
61
|
- [ ] Step 3: Collect comments — `keryx review comments collect`, never by hand
|
|
62
62
|
- [ ] Step 4: Group by author
|