@sabaiway/agent-workflow-kit 14.25.0 → 14.25.1

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/CHANGELOG.md CHANGED
@@ -4,6 +4,18 @@ Semantically versioned ([semver](https://semver.org)), newest first. The `versio
4
4
  is the current release. `upgrade` mode reads a project's `docs/ai/.workflow-version` and applies
5
5
  every `migrations/<version>-<slug>.md` newer than it, in semver order.
6
6
 
7
+ ## 14.25.1 — `init` reports what it did: a replaced MCP entry is labelled replaced, and a folder inside a kept folder prints no line of its own (AD-174)
8
+
9
+ - **The MCP apply report no longer shows the old entry as the current one.** After the `y` that replaces a differing
10
+ `agent-workflow` entry, `init` printed the old entry under `the entry standing in .mcp.json now:` while the file
11
+ already held the new one. It now prints `the entry this run replaced in .mcp.json:` and `the entry now in
12
+ .mcp.json`. The preview before the `y` is unchanged.
13
+ - **A folder inside a kept folder prints no line of its own.** A folder inside one of the kit's own folders
14
+ (`tools/`, `references/` and the like) that the package does not carry is still kept and reported as yours to
15
+ remove by hand, but the folders inside it no longer print a line each:
16
+ a home that kept an emptied `tools/manifest/fixtures/` printed 18 lines on every run and now prints one. A stray
17
+ file inside such a folder is still removed with its own line.
18
+
7
19
  ## 14.25.0 — `init`, run in a console from a project's folder, applies that project's harness configuration on one "y" (AD-173)
8
20
 
9
21
  **`npx @sabaiway/agent-workflow-kit@latest init` gains a project step.** Run in your own console from a project's
package/SKILL.md CHANGED
@@ -3,7 +3,7 @@ name: agent-workflow-kit
3
3
  description: Deploy or upgrade a portable AI-agent memory-and-workflow system in any project. Use when the user wants to bootstrap `docs/ai/` + an entry-point `AGENTS.md` (+ `CLAUDE.md` alias) + cap/archive/index enforcement in a new or existing repo, set up the Memory Map and session protocols, install the docs-rotation pre-commit hook, or run `/agent-workflow-kit` / `/agent-workflow-kit upgrade`. Triggers on phrases like "set up the memory system", "deploy the AI workflow here", "bootstrap docs/ai", "upgrade the workflow". New to the epic, story and task tier? Run `/agent-workflow-kit tier`. A typed decision with a confidence from Jev? Run `/agent-workflow-kit jev`.
4
4
  disable-model-invocation: true
5
5
  metadata:
6
- version: '14.25.0'
6
+ version: '14.25.1'
7
7
  ---
8
8
 
9
9
  # agent-workflow-kit
package/capability.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "schema": 1,
4
4
  "name": "agent-workflow-kit",
5
5
  "kind": "composition-root",
6
- "version": "14.25.0",
6
+ "version": "14.25.1",
7
7
  "provides": [],
8
8
  "roles": {},
9
9
  "detect": {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sabaiway/agent-workflow-kit",
3
- "version": "14.25.0",
3
+ "version": "14.25.1",
4
4
  "description": "Portable, cross-agent memory & workflow for AI coding agents — Claude Code, Codex, Cursor, Devin Desktop. One command deploys an AGENTS.md entry point + docs/ai context with cap/archive/index enforcement into any repo.",
5
5
  "keywords": [
6
6
  "ai-agents",
@@ -25,7 +25,7 @@ An existing `.mcp.json` and `.claude/settings.json` are written in place: each k
25
25
 
26
26
  - **DIFFERING** — `.mcp.json` already carries an `"agent-workflow"` entry that **structurally differs** from ours (another kit copy, a hand-edited path, an added `env`, a `null`). The comparison is deliberately key-order-independent, so a re-serialized identical entry is the SAME registration, while any real difference in what would be launched is a difference. Without `--replace`, the run **STOPs unwritten, on both lanes**: silently changing what an MCP server launches is exactly what consent must not slide past.
27
27
  With `--replace`, the preview prints the entry standing in `.mcp.json` now and the entry this registration declares, writes nothing and exits 0.
28
- With `--replace --apply`, it replaces that entry, keeping every other server and key of `.mcp.json`.
28
+ With `--replace --apply`, it replaces that entry, keeping every other server and key of `.mcp.json`, and prints the old entry as the one it replaced and ours as the one now in the file.
29
29
  This is the console item `mcp-channel.differing`: `init` previews it in the user's console and applies it on the terminal "y".
30
30
  - **MASKED** — an OS sandbox injects a **character device** where `.mcp.json` would be (this is the normal condition of a sandboxed session, not a fault; see `${CLAUDE_SKILL_DIR}/references/modes/sandbox-masks.md`). Writing through a device node is refused by construction, so the mode **hands over what to merge, writes nothing, and exits 0**. The two halves of that handoff are worded differently, and the difference is load-bearing: `.claude/settings.json` was **observable — and read where present** — so its body is a real merge already carrying every foreign key it had, while the masked `.mcp.json` was not observable at all, so the mode hands over **the entry alone**, to be merged under `mcpServers` keeping every other server. A whole-file body would name only our server, and pasted as instructed it would delete every server the mask hid. Every other never-committable class (block device, FIFO, socket) takes the same arm. The handoff is scoped to `.mcp.json`: a masked `settings.json` is a **refusal**, because this mode can neither write it nor merge into what it cannot read.
31
31
 
package/tools/mcp.mjs CHANGED
@@ -317,10 +317,12 @@ export const formatResult = (result) => {
317
317
  mcpJsonLine(result),
318
318
  settingsLine(result),
319
319
  ...(result.registration.mcpJson.differs ? [
320
- ' the entry standing in .mcp.json now:',
320
+ result.dryRun ? ' the entry standing in .mcp.json now:' : ' the entry this run replaced in .mcp.json:',
321
321
  indented(JSON.stringify(result.registration.mcpJson.existing, null, JSON_INDENT)),
322
322
  ] : []),
323
- ' the entry this registration declares (re-serialized here; the same structured value goes into the file):',
323
+ result.dryRun
324
+ ? ' the entry this registration declares (re-serialized here; the same structured value goes into the file):'
325
+ : ' the entry now in .mcp.json (re-serialized here; the file holds the same structured value):',
324
326
  indented(JSON.stringify(result.registration.entry, null, JSON_INDENT)),
325
327
  POSTURE_LINE,
326
328
  HIDDEN_MODE_LINE,
@@ -107,7 +107,9 @@ const readTree = (root, entry, reports, directoryOnly = false) => {
107
107
  return entries;
108
108
  };
109
109
 
110
+ // The walk lists a directory before its children, so a kept directory's line covers the directories beneath it.
110
111
  const planSubtree = (carried, installed, orphans, reports) => {
112
+ const keptDirectories = [];
111
113
  for (const [path, kind] of installed) {
112
114
  if (carried.has(path)) {
113
115
  const packageKind = carried.get(path);
@@ -119,7 +121,10 @@ const planSubtree = (carried, installed, orphans, reports) => {
119
121
  }
120
122
  } else if (kind === 'file') {
121
123
  orphans.push(path);
124
+ } else if (kind === 'directory' && keptDirectories.some((kept) => path.startsWith(`${kept}/`))) {
125
+ continue;
122
126
  } else {
127
+ if (kind === 'directory') keptDirectories.push(path);
123
128
  reports.push({
124
129
  ok: true,
125
130
  line: `${PREFIX} kept ${path} (a ${kind} the package does not carry — yours to remove by hand)`,