@sabaiway/agent-workflow-kit 14.14.0 → 14.14.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 +14 -0
- package/SKILL.md +1 -1
- package/capability.json +1 -1
- package/package.json +1 -1
- package/references/modes/agents.md +1 -1
- package/tools/cheap-agents.mjs +16 -3
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,20 @@ 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.14.1 — the agents writer stops on a project folder given as a symlink, before it reads or writes anything (AD-161)
|
|
8
|
+
|
|
9
|
+
**`cheap-agents.mjs --cwd <dir>` now refuses a `<dir>` that is itself a symlink.** Until 14.14.1 an `--apply` there
|
|
10
|
+
wrote the vehicles through the link. With a hand-edited executor it placed `changelog-skeleton.md` and then failed on
|
|
11
|
+
the executor with an uncoded error, leaving `.claude/agents/` half placed; with a trailing `/` even that executor was
|
|
12
|
+
rewritten through the link.
|
|
13
|
+
|
|
14
|
+
- **The refusal.** `<link>`, `<link>/` and `<link>/.` stop with `CHEAP_AGENTS_SYMLINK`, exit 1, and a message naming
|
|
15
|
+
the project root as a symlink the writer refuses to write through. It is the first step of `--dry-run` and
|
|
16
|
+
`--apply` alike and of a direct `preflightCheapAgents` call: nothing under the root is read, nothing is written.
|
|
17
|
+
- **What stays.** A real directory, a regular file, an absent path and a project reached through a linked parent
|
|
18
|
+
directory get the same answers as in 14.14.0, and so does the default, the current directory. The mode doc's
|
|
19
|
+
symlink-safe line and the tool header name the project root.
|
|
20
|
+
|
|
7
21
|
## 14.14.0 — the Recommendations screen lists each step of the reference setup you have not taken or declined, with its preview command or the reason it has none (AD-160)
|
|
8
22
|
|
|
9
23
|
**`/agent-workflow-kit recommendations` now shows what your project still lacks of the full flow.** Until 14.14.0
|
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`.
|
|
4
4
|
disable-model-invocation: true
|
|
5
5
|
metadata:
|
|
6
|
-
version: '14.14.
|
|
6
|
+
version: '14.14.1'
|
|
7
7
|
---
|
|
8
8
|
|
|
9
9
|
# agent-workflow-kit
|
package/capability.json
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sabaiway/agent-workflow-kit",
|
|
3
|
-
"version": "14.14.
|
|
3
|
+
"version": "14.14.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",
|
|
@@ -19,7 +19,7 @@ Writing code, running gates, and user-facing copy never move to these four vehic
|
|
|
19
19
|
Run `node ${CLAUDE_SKILL_DIR}/tools/cheap-agents.mjs [--dry-run | --apply] [--cwd <dir>]`:
|
|
20
20
|
|
|
21
21
|
1. **`--dry-run` first, always** (the default — changes nothing). It previews, per bundled vehicle, whether it **would place** the file, finds it **already current**, or finds a **customized** file (different content) that will be **preserved, never overwritten** (delete the file to reseed it from the bundle) — except the executor, whose differing bytes **would re-derive** from `docs/ai/vehicles.json` and are rewritten on `--apply` (a hand edit is replaced, never preserved).
|
|
22
|
-
2. **Only on an explicit yes**, re-run with `--apply`. It writes **only** under `.claude/agents/` — never `settings.json` / `settings.local.json`, never a commit. `--apply` is deployment-gated (the stamp must be at the lineage head) and symlink-safe (a symlinked `.claude` / `.claude/agents` / target file is a STOP).
|
|
22
|
+
2. **Only on an explicit yes**, re-run with `--apply`. It writes **only** under `.claude/agents/` — never `settings.json` / `settings.local.json`, never a commit. `--apply` is deployment-gated (the stamp must be at the lineage head) and symlink-safe (a symlinked project root / `.claude` / `.claude/agents` / target file is a STOP, in a `--dry-run` too).
|
|
23
23
|
3. **Hidden-mode deployments:** after apply, run the hide-footprint reconcile (`node ${CLAUDE_SKILL_DIR}/tools/hide-footprint.mjs --dir <project> --reconcile`) so the placed files stay invisible to `git status` — `/.claude/agents/` is in the known-footprint registry; the apply report reminds you.
|
|
24
24
|
|
|
25
25
|
**Invariants:** writer (writes only `.claude/agents/`) · preview by default · a diverged existing file is reported and preserved, never clobbered — except the executor, re-derived from `docs/ai/vehicles.json` on apply · never touches settings · never commits · **no READ-ONLY vehicle grants `Bash`, and exactly one bundled vehicle, `executor`, grants a shell** · the cheap-lane vehicles are pinned to `model: haiku` + `effort: low`, and the review lens is pinned OFF the cheap model (all content-tested).
|
package/tools/cheap-agents.mjs
CHANGED
|
@@ -12,8 +12,8 @@
|
|
|
12
12
|
// • deployment-gated — `--apply` STOPs unless docs/ai/.workflow-version equals the lineage
|
|
13
13
|
// head (a dry-run stays usable whatever the stamp says; an unreadable orchestration config
|
|
14
14
|
// STOPs both, since the derived lenses it names cannot be known);
|
|
15
|
-
// • symlink-safe — a symlinked `.claude
|
|
16
|
-
// write-through;
|
|
15
|
+
// • symlink-safe — a symlinked project root, `.claude`, `.claude/agents` or target file is a
|
|
16
|
+
// STOP, in a dry-run too, never a write-through;
|
|
17
17
|
// • preserves differing .claude/agents/ files (`customized — preserved`), except the executor:
|
|
18
18
|
// on apply its body is re-derived from docs/ai/vehicles.json, replacing a hand edit;
|
|
19
19
|
// an identical file is `already current` (idempotent re-run);
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
// Dependency-free, Node >= 22. No side effects on import.
|
|
32
32
|
|
|
33
33
|
import { mkdirSync, writeFileSync } from 'node:fs';
|
|
34
|
-
import { join } from 'node:path';
|
|
34
|
+
import { join, resolve } from 'node:path';
|
|
35
35
|
import { fileURLToPath } from 'node:url';
|
|
36
36
|
import { isDirectRun } from './direct-run.mjs';
|
|
37
37
|
import { shellQuoteArg } from './repo-lex.mjs';
|
|
@@ -117,9 +117,21 @@ const writeFsDeps = (deps = {}) => ({
|
|
|
117
117
|
writeFile: deps.writeFile ?? writeFileSync,
|
|
118
118
|
});
|
|
119
119
|
|
|
120
|
+
const refuseSymlinkedRoot = (projectDir, deps) => {
|
|
121
|
+
const root = resolve(projectDir);
|
|
122
|
+
let stat;
|
|
123
|
+
try {
|
|
124
|
+
stat = readFsDeps(deps).lstat(root);
|
|
125
|
+
} catch {
|
|
126
|
+
return;
|
|
127
|
+
}
|
|
128
|
+
if (stat.isSymbolicLink()) throw makeCheapAgentsError(CHEAP_AGENTS_SYMLINK, `the project root ${root} is a symlink — refusing to write through it`);
|
|
129
|
+
};
|
|
130
|
+
|
|
120
131
|
export const preflightCheapAgents = ({ cwd, derived = [] }, deps = {}) => {
|
|
121
132
|
const fs = readFsDeps(deps);
|
|
122
133
|
const projectDir = cwd ?? process.cwd();
|
|
134
|
+
refuseSymlinkedRoot(projectDir, deps);
|
|
123
135
|
const templatesByName = new Map(readBundledAgents(deps).map((template) => [template.name, template]));
|
|
124
136
|
for (const template of derived) templatesByName.set(template.name, template);
|
|
125
137
|
const templates = [...templatesByName.values()];
|
|
@@ -169,6 +181,7 @@ export const applyCheapAgentsCommand = (root) =>
|
|
|
169
181
|
export const writeCheapAgents = ({ cwd, dryRun = true } = {}, deps = {}) => {
|
|
170
182
|
const fs = writeFsDeps(deps);
|
|
171
183
|
const projectDir = cwd ?? process.cwd();
|
|
184
|
+
refuseSymlinkedRoot(projectDir, deps);
|
|
172
185
|
const posture = loadExecutorPostureOrStop(projectDir, deps);
|
|
173
186
|
const derived = [executorTemplate(posture, deps), ...configuredDerivedTemplates(projectDir, deps)];
|
|
174
187
|
const preflight = preflightCheapAgents({ cwd: projectDir, derived }, deps);
|