@kaddo/cli 3.11.2 → 3.12.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 +90 -3
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -2249,6 +2249,12 @@ You do **not** suggest branches, commits or pull requests \u2014 implementation
|
|
|
2249
2249
|
branch suggestion) is the implementation-agent's responsibility, and only by respecting the
|
|
2250
2250
|
project Git strategy. Your job ends at a clear, traceable Work Item.
|
|
2251
2251
|
|
|
2252
|
+
## Git boundaries
|
|
2253
|
+
|
|
2254
|
+
Never run Git. Do not create or switch branches, create worktrees, stash, commit, push or merge.
|
|
2255
|
+
Work only inside the currently selected workspace. If a workspace or branch change is required,
|
|
2256
|
+
stop and ask the human.
|
|
2257
|
+
|
|
2252
2258
|
## Quality Checklist
|
|
2253
2259
|
|
|
2254
2260
|
- The problem is one clear sentence.
|
|
@@ -2814,6 +2820,10 @@ Conventional Commit message \u2014 as suggestions, never executed.
|
|
|
2814
2820
|
## Constraints
|
|
2815
2821
|
|
|
2816
2822
|
- Never run Git. Never commit, push or merge \u2014 suggest and wait for the human.
|
|
2823
|
+
- **Do not create branches, switch branches, create worktrees, or stash changes.** You may
|
|
2824
|
+
*suggest* a branch name; the human creates the branch and selects the workspace.
|
|
2825
|
+
- **Work only inside the currently selected workspace** (repository root or the active Git
|
|
2826
|
+
worktree). If a branch or workspace change is required, stop and ask the human.
|
|
2817
2827
|
- Respect \`knowledge/tech/git-strategy.md\` when it exists.
|
|
2818
2828
|
- Keep knowledge in sync with the code you change.
|
|
2819
2829
|
- Do not invent business facts.
|
|
@@ -4959,6 +4969,42 @@ function assessPhase(input) {
|
|
|
4959
4969
|
return { phase, reasons, recommendedAgents: recommendedAgents2, nextStep };
|
|
4960
4970
|
}
|
|
4961
4971
|
|
|
4972
|
+
// src/core/workspace.ts
|
|
4973
|
+
import { dirname, resolve, basename } from "path";
|
|
4974
|
+
function findGitEntry(startDir) {
|
|
4975
|
+
let cur = resolve(startDir);
|
|
4976
|
+
while (true) {
|
|
4977
|
+
const g = join(cur, ".git");
|
|
4978
|
+
if (exists(g)) return { dir: cur, gitPath: g };
|
|
4979
|
+
const parent = dirname(cur);
|
|
4980
|
+
if (parent === cur) return null;
|
|
4981
|
+
cur = parent;
|
|
4982
|
+
}
|
|
4983
|
+
}
|
|
4984
|
+
function readBranch(gitDir) {
|
|
4985
|
+
try {
|
|
4986
|
+
const head = readFile(join(gitDir, "HEAD")).trim();
|
|
4987
|
+
const m = head.match(/^ref:\s*refs\/heads\/(.+)$/);
|
|
4988
|
+
if (m) return m[1].trim();
|
|
4989
|
+
return head ? head.slice(0, 12) : null;
|
|
4990
|
+
} catch {
|
|
4991
|
+
return null;
|
|
4992
|
+
}
|
|
4993
|
+
}
|
|
4994
|
+
function detectWorkspace(startDir) {
|
|
4995
|
+
const found = findGitEntry(startDir);
|
|
4996
|
+
if (!found) return { isGitRepo: false, root: null, branch: null, isWorktree: false };
|
|
4997
|
+
const { dir, gitPath } = found;
|
|
4998
|
+
if (!isFile(gitPath)) {
|
|
4999
|
+
return { isGitRepo: true, root: dir, branch: readBranch(gitPath), isWorktree: false };
|
|
5000
|
+
}
|
|
5001
|
+
let gitDir = gitPath;
|
|
5002
|
+
const m = readFile(gitPath).match(/gitdir:\s*(.+)/);
|
|
5003
|
+
if (m) gitDir = m[1].trim();
|
|
5004
|
+
const isWorktree = basename(dirname(gitDir)) === "worktrees";
|
|
5005
|
+
return { isGitRepo: true, root: dir, branch: readBranch(gitDir), isWorktree };
|
|
5006
|
+
}
|
|
5007
|
+
|
|
4962
5008
|
// src/core/knowledge-discovery.ts
|
|
4963
5009
|
var KNOWLEDGE = "knowledge";
|
|
4964
5010
|
var CONSOLIDATED_TYPE = {
|
|
@@ -5008,7 +5054,7 @@ function layerFromPath(filePath) {
|
|
|
5008
5054
|
if (p2.includes(`/${KNOWLEDGE}/delivery/`)) return "Delivery";
|
|
5009
5055
|
return null;
|
|
5010
5056
|
}
|
|
5011
|
-
function
|
|
5057
|
+
function basename2(p2) {
|
|
5012
5058
|
return p2.replace(/\\/g, "/").split("/").pop() ?? p2;
|
|
5013
5059
|
}
|
|
5014
5060
|
function discoverLayers(dir) {
|
|
@@ -5025,9 +5071,9 @@ function discoverLayers(dir) {
|
|
|
5025
5071
|
const layer2 = layerForType(type) ?? layerFromPath(a.filePath);
|
|
5026
5072
|
if (!layer2) continue;
|
|
5027
5073
|
const slot = acc[layer2];
|
|
5028
|
-
slot.detected.add(
|
|
5074
|
+
slot.detected.add(basename2(a.filePath));
|
|
5029
5075
|
if (layer2 === "Delivery") {
|
|
5030
|
-
if (type === "roadmap" ||
|
|
5076
|
+
if (type === "roadmap" || basename2(a.filePath) === "roadmap.md") slot.hasRoadmap = true;
|
|
5031
5077
|
if (WORK_ITEM_TYPES2.has(type) || a.filePath.replace(/\\/g, "/").includes("/delivery/work-items/")) {
|
|
5032
5078
|
if (a.filePath.replace(/\\/g, "/").includes("/delivery/work-items/")) slot.hasWorkItem = true;
|
|
5033
5079
|
}
|
|
@@ -5210,6 +5256,7 @@ function buildProjectExplanation(dir) {
|
|
|
5210
5256
|
workItemsMissingOwnership: items.length - withOwnership
|
|
5211
5257
|
};
|
|
5212
5258
|
const domains = [...new Set(workItemArtifacts.flatMap((a) => a.domains))].filter(Boolean);
|
|
5259
|
+
const workspace = detectWorkspace(dir);
|
|
5213
5260
|
const roadmapPath = join(dir, ARCH_DIR4, "delivery", "roadmap.md");
|
|
5214
5261
|
const roadmapMd = exists(roadmapPath) ? readFile(roadmapPath) : null;
|
|
5215
5262
|
const roadmap = roadmapStats(roadmapMd, items.length);
|
|
@@ -5259,6 +5306,7 @@ function buildProjectExplanation(dir) {
|
|
|
5259
5306
|
workItems,
|
|
5260
5307
|
ownership,
|
|
5261
5308
|
domains,
|
|
5309
|
+
workspace,
|
|
5262
5310
|
layers,
|
|
5263
5311
|
roadmap,
|
|
5264
5312
|
mappedModules,
|
|
@@ -5291,6 +5339,21 @@ function renderExplanationHuman(exp) {
|
|
|
5291
5339
|
lines.push(`- Team: ${exp.project.teamSize}`);
|
|
5292
5340
|
lines.push(`- Structure: ${exp.project.structure}`);
|
|
5293
5341
|
lines.push("");
|
|
5342
|
+
lines.push("## Workspace");
|
|
5343
|
+
if (exp.workspace.isGitRepo) {
|
|
5344
|
+
lines.push(`- Repository root: ${exp.workspace.root ?? "unknown"}`);
|
|
5345
|
+
lines.push(`- Git worktree: ${exp.workspace.isWorktree ? "yes" : "no"}`);
|
|
5346
|
+
lines.push(`- Active branch: ${exp.workspace.branch ?? "unknown"}`);
|
|
5347
|
+
if (exp.workspace.isWorktree) {
|
|
5348
|
+
lines.push("");
|
|
5349
|
+
lines.push(
|
|
5350
|
+
"> Worktree detected. Run all Kaddo commands (scan, guard, owners suggest, explain) from this worktree while implementation is active, so they observe the same files the agent is changing."
|
|
5351
|
+
);
|
|
5352
|
+
}
|
|
5353
|
+
} else {
|
|
5354
|
+
lines.push("- Not a Git repository");
|
|
5355
|
+
}
|
|
5356
|
+
lines.push("");
|
|
5294
5357
|
lines.push("## Knowledge Layers");
|
|
5295
5358
|
lines.push(renderLayersMarkdown(exp.layers));
|
|
5296
5359
|
lines.push("");
|
|
@@ -5781,6 +5844,7 @@ function buildContextPack(dir, config, now = /* @__PURE__ */ new Date()) {
|
|
|
5781
5844
|
layers,
|
|
5782
5845
|
roadmap,
|
|
5783
5846
|
phase,
|
|
5847
|
+
workspace: detectWorkspace(dir),
|
|
5784
5848
|
deliveryMix,
|
|
5785
5849
|
mappedModules,
|
|
5786
5850
|
missing,
|
|
@@ -5818,6 +5882,23 @@ function renderContextPack(pack) {
|
|
|
5818
5882
|
`- Structure: ${project.structure}`
|
|
5819
5883
|
].join("\n") + "\n"
|
|
5820
5884
|
);
|
|
5885
|
+
parts.push("## Execution Context\n");
|
|
5886
|
+
if (pack.workspace.isGitRepo) {
|
|
5887
|
+
parts.push(
|
|
5888
|
+
[
|
|
5889
|
+
`- Repository root: ${pack.workspace.root ?? "unknown"}`,
|
|
5890
|
+
`- Current branch: ${pack.workspace.branch ?? "unknown"}`,
|
|
5891
|
+
`- Git worktree: ${pack.workspace.isWorktree ? "yes" : "no"}`
|
|
5892
|
+
].join("\n") + "\n"
|
|
5893
|
+
);
|
|
5894
|
+
if (pack.workspace.isWorktree) {
|
|
5895
|
+
parts.push(
|
|
5896
|
+
"You are inside a Git worktree. Work only in this workspace; run Kaddo commands from here.\n"
|
|
5897
|
+
);
|
|
5898
|
+
}
|
|
5899
|
+
} else {
|
|
5900
|
+
parts.push("- Not a Git repository\n");
|
|
5901
|
+
}
|
|
5821
5902
|
parts.push("## Current Phase\n");
|
|
5822
5903
|
parts.push(`Phase: ${pack.phase.phase}
|
|
5823
5904
|
`);
|
|
@@ -6252,6 +6333,12 @@ function runUnderstand() {
|
|
|
6252
6333
|
if (assessment.nextStep) {
|
|
6253
6334
|
console.log(`Next step: ${assessment.nextStep}`);
|
|
6254
6335
|
}
|
|
6336
|
+
if (exp.workspace.isWorktree) {
|
|
6337
|
+
console.log("");
|
|
6338
|
+
console.log(`Current implementation workspace: ${exp.workspace.branch ?? "(detached)"}`);
|
|
6339
|
+
console.log(" \u2192 You are inside a Git worktree. Run scan, owners suggest, guard and explain");
|
|
6340
|
+
console.log(" from this worktree so they reflect the code being changed here.");
|
|
6341
|
+
}
|
|
6255
6342
|
const active = activeWorkItems(dir);
|
|
6256
6343
|
if (active.length > 0) {
|
|
6257
6344
|
console.log("");
|