@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.
Files changed (2) hide show
  1. package/dist/index.js +90 -3
  2. 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 basename(p2) {
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(basename(a.filePath));
5074
+ slot.detected.add(basename2(a.filePath));
5029
5075
  if (layer2 === "Delivery") {
5030
- if (type === "roadmap" || basename(a.filePath) === "roadmap.md") slot.hasRoadmap = true;
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("");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kaddo/cli",
3
- "version": "3.11.2",
3
+ "version": "3.12.0",
4
4
  "description": "Knowledge Driven Development toolkit",
5
5
  "license": "MIT",
6
6
  "repository": {