@event4u/agent-config 1.41.1 → 2.0.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/.agent-src/templates/agents/agent-project-settings.example.yml +14 -0
- package/.agent-src/templates/scripts/work_engine/_lib/agent_settings.py +120 -11
- package/.claude-plugin/marketplace.json +1 -1
- package/CHANGELOG.md +31 -0
- package/README.md +34 -25
- package/config/agent-settings.template.yml +25 -0
- package/docs/architecture.md +46 -0
- package/docs/customization.md +125 -9
- package/docs/installation.md +9 -36
- package/docs/migration/v1-to-v2.md +98 -0
- package/docs/setup/per-ide/claude-code.md +0 -17
- package/docs/setup/per-ide/claude-desktop.md +35 -48
- package/docs/setup/per-ide/windsurf.md +0 -11
- package/package.json +1 -6
- package/scripts/_cli/__init__.py +0 -0
- package/scripts/_cli/cmd_migrate.py +270 -0
- package/scripts/_cli/cmd_update.py +226 -0
- package/scripts/_lib/agent_settings.py +120 -11
- package/scripts/_lib/agents_overlay.py +109 -0
- package/scripts/_lib/pin_resolver.py +152 -0
- package/scripts/_lib/update_check.py +183 -0
- package/scripts/agent-config +73 -1
- package/scripts/check_overlay_cascade_subdirs.py +125 -0
- package/scripts/check_template_pin_drift.py +112 -0
- package/scripts/check_update_banner.py +86 -0
- package/scripts/install +2 -37
- package/scripts/install.py +6 -207
- package/bin/install.php +0 -45
- package/composer.json +0 -33
- package/scripts/postinstall.sh +0 -76
- package/templates/global-install-manifest.yml +0 -91
package/scripts/install.py
CHANGED
|
@@ -1217,188 +1217,13 @@ def _smoke_test_hooks(project_root: Path, package_root: Path) -> int:
|
|
|
1217
1217
|
return 1 if failed else 0
|
|
1218
1218
|
|
|
1219
1219
|
|
|
1220
|
-
# --- Global user-level install
|
|
1220
|
+
# --- Global user-level install — RETIRED (road-to-portable-runtime P0.5) ---
|
|
1221
1221
|
#
|
|
1222
|
-
#
|
|
1223
|
-
#
|
|
1224
|
-
#
|
|
1225
|
-
#
|
|
1226
|
-
#
|
|
1227
|
-
# can wipe the namespace dir without touching user-added files.
|
|
1228
|
-
|
|
1229
|
-
GLOBAL_NAMESPACE = "event4u"
|
|
1230
|
-
GLOBAL_MANIFEST_REL = Path("templates") / "global-install-manifest.yml"
|
|
1231
|
-
|
|
1232
|
-
# Per-tool global directories. Each surface gets a `rules/` and `skills/`
|
|
1233
|
-
# bucket under the event4u/ namespace. claude-desktop reuses claude-code's
|
|
1234
|
-
# ~/.claude/ (the two surfaces share the dir per Anthropic's docs).
|
|
1235
|
-
GLOBAL_TOOL_DIRS: dict[str, dict[str, Path]] = {
|
|
1236
|
-
"claude-code": {
|
|
1237
|
-
"rules": Path.home() / ".claude" / "rules" / GLOBAL_NAMESPACE,
|
|
1238
|
-
"skills": Path.home() / ".claude" / "skills" / GLOBAL_NAMESPACE,
|
|
1239
|
-
},
|
|
1240
|
-
"cursor": {
|
|
1241
|
-
"rules": Path.home() / ".cursor" / "rules" / "imported" / GLOBAL_NAMESPACE / "rules",
|
|
1242
|
-
"skills": Path.home() / ".cursor" / "rules" / "imported" / GLOBAL_NAMESPACE / "skills",
|
|
1243
|
-
},
|
|
1244
|
-
"windsurf": {
|
|
1245
|
-
"rules": Path.home() / ".codeium" / "windsurf" / "global_workflows" / GLOBAL_NAMESPACE / "rules",
|
|
1246
|
-
"skills": Path.home() / ".codeium" / "windsurf" / "global_workflows" / GLOBAL_NAMESPACE / "skills",
|
|
1247
|
-
},
|
|
1248
|
-
"fallback": {
|
|
1249
|
-
"rules": Path.home() / ".config" / "agent-config" / "rules" / GLOBAL_NAMESPACE,
|
|
1250
|
-
"skills": Path.home() / ".config" / "agent-config" / "skills" / GLOBAL_NAMESPACE,
|
|
1251
|
-
},
|
|
1252
|
-
}
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
def _load_global_manifest(package_root: Path) -> dict:
|
|
1256
|
-
"""Parse templates/global-install-manifest.yml without a YAML dep.
|
|
1257
|
-
|
|
1258
|
-
Tiny hand-rolled parser — only handles the manifest's flat shape:
|
|
1259
|
-
`key: value`, `- item`, and `- key: value` indented under a parent
|
|
1260
|
-
list. We avoid pulling in PyYAML so install.py stays zero-dep.
|
|
1261
|
-
"""
|
|
1262
|
-
path = package_root / GLOBAL_MANIFEST_REL
|
|
1263
|
-
if not path.is_file():
|
|
1264
|
-
fail(f"global manifest missing: {path}")
|
|
1265
|
-
out: dict = {"kernel_rules": [], "top_skills": []}
|
|
1266
|
-
section: str | None = None
|
|
1267
|
-
pending: dict | None = None
|
|
1268
|
-
for raw in path.read_text(encoding="utf-8").splitlines():
|
|
1269
|
-
line = raw.split("#", 1)[0].rstrip()
|
|
1270
|
-
if not line.strip():
|
|
1271
|
-
continue
|
|
1272
|
-
if line.startswith("kernel_rules:"):
|
|
1273
|
-
section = "kernel_rules"; pending = None; continue
|
|
1274
|
-
if line.startswith("top_skills:"):
|
|
1275
|
-
section = "top_skills"; pending = None; continue
|
|
1276
|
-
stripped = line.lstrip()
|
|
1277
|
-
indent = len(line) - len(stripped)
|
|
1278
|
-
if section == "kernel_rules" and stripped.startswith("- "):
|
|
1279
|
-
out["kernel_rules"].append(stripped[2:].strip())
|
|
1280
|
-
elif section == "top_skills":
|
|
1281
|
-
if stripped.startswith("- id:"):
|
|
1282
|
-
if pending is not None:
|
|
1283
|
-
out["top_skills"].append(pending)
|
|
1284
|
-
pending = {"id": stripped.split(":", 1)[1].strip(), "surfaces": []}
|
|
1285
|
-
elif pending is not None and stripped.startswith("surfaces:"):
|
|
1286
|
-
raw_list = stripped.split(":", 1)[1].strip()
|
|
1287
|
-
if raw_list.startswith("[") and raw_list.endswith("]"):
|
|
1288
|
-
pending["surfaces"] = [s.strip() for s in raw_list[1:-1].split(",") if s.strip()]
|
|
1289
|
-
elif indent == 0 and not stripped.startswith("-"):
|
|
1290
|
-
section = None
|
|
1291
|
-
if pending is not None:
|
|
1292
|
-
out["top_skills"].append(pending)
|
|
1293
|
-
return out
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
def _resolve_skill_source(package_root: Path, skill_id: str) -> Path | None:
|
|
1297
|
-
"""Locate a skill's SKILL.md in the package. Prefers .claude/skills/."""
|
|
1298
|
-
for base in (package_root / ".claude" / "skills",
|
|
1299
|
-
package_root / ".agent-src" / "skills"):
|
|
1300
|
-
candidate = base / skill_id / "SKILL.md"
|
|
1301
|
-
if candidate.is_file():
|
|
1302
|
-
return candidate.parent
|
|
1303
|
-
return None
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
def _resolve_rule_source(package_root: Path, rule_id: str) -> Path | None:
|
|
1307
|
-
"""Locate a rule's .md in the package. Prefers .agent-src/rules/."""
|
|
1308
|
-
for base in (package_root / ".agent-src" / "rules",
|
|
1309
|
-
package_root / ".augment" / "rules"):
|
|
1310
|
-
candidate = base / f"{rule_id}.md"
|
|
1311
|
-
if candidate.is_file():
|
|
1312
|
-
return candidate
|
|
1313
|
-
return None
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
def _global_targets(tools: set[str]) -> dict[str, dict[str, Path]]:
|
|
1317
|
-
"""Return the subset of GLOBAL_TOOL_DIRS to write to. Fallback always on."""
|
|
1318
|
-
targets: dict[str, dict[str, Path]] = {"fallback": GLOBAL_TOOL_DIRS["fallback"]}
|
|
1319
|
-
for tool_id, dirs in GLOBAL_TOOL_DIRS.items():
|
|
1320
|
-
if tool_id == "fallback":
|
|
1321
|
-
continue
|
|
1322
|
-
# claude-desktop shares claude-code's dir — both flip the same target.
|
|
1323
|
-
if tool_id == "claude-code" and ("claude-code" in tools or "claude-desktop" in tools):
|
|
1324
|
-
targets[tool_id] = dirs
|
|
1325
|
-
elif tool_id in tools:
|
|
1326
|
-
targets[tool_id] = dirs
|
|
1327
|
-
return targets
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
def install_global(package_root: Path, tools: set[str], force: bool) -> int:
|
|
1331
|
-
"""S13/S14: ship kernel rules + curated skills to user-scope dirs."""
|
|
1332
|
-
import shutil
|
|
1333
|
-
manifest = _load_global_manifest(package_root)
|
|
1334
|
-
targets = _global_targets(tools)
|
|
1335
|
-
|
|
1336
|
-
if not QUIET:
|
|
1337
|
-
info(f"Global install — surfaces: {', '.join(sorted(targets))}")
|
|
1338
|
-
info(f" rules: {len(manifest['kernel_rules'])}")
|
|
1339
|
-
info(f" skills: {len(manifest['top_skills'])}")
|
|
1340
|
-
|
|
1341
|
-
for surface, dirs in targets.items():
|
|
1342
|
-
for kind in ("rules", "skills"):
|
|
1343
|
-
dirs[kind].mkdir(parents=True, exist_ok=True)
|
|
1344
|
-
# Rules: copy each kernel rule (file).
|
|
1345
|
-
for rule_id in manifest["kernel_rules"]:
|
|
1346
|
-
src = _resolve_rule_source(package_root, rule_id)
|
|
1347
|
-
if src is None:
|
|
1348
|
-
warn(f"global: rule '{rule_id}' missing in package — skipped")
|
|
1349
|
-
continue
|
|
1350
|
-
dst = dirs["rules"] / f"{rule_id}.md"
|
|
1351
|
-
if dst.exists() and not force and dst.read_bytes() == src.read_bytes():
|
|
1352
|
-
continue
|
|
1353
|
-
dst.write_bytes(src.read_bytes())
|
|
1354
|
-
# Skills: copy each curated skill (directory).
|
|
1355
|
-
for entry in manifest["top_skills"]:
|
|
1356
|
-
if surface != "fallback" and surface not in entry.get("surfaces", []):
|
|
1357
|
-
continue
|
|
1358
|
-
src_dir = _resolve_skill_source(package_root, entry["id"])
|
|
1359
|
-
if src_dir is None:
|
|
1360
|
-
warn(f"global: skill '{entry['id']}' missing in package — skipped")
|
|
1361
|
-
continue
|
|
1362
|
-
dst_dir = dirs["skills"] / entry["id"]
|
|
1363
|
-
if dst_dir.exists() and not force:
|
|
1364
|
-
shutil.rmtree(dst_dir)
|
|
1365
|
-
shutil.copytree(src_dir, dst_dir)
|
|
1366
|
-
if not QUIET:
|
|
1367
|
-
success(f" {surface}: {dirs['rules']}, {dirs['skills']}")
|
|
1368
|
-
return 0
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
def uninstall_global(tools: set[str]) -> int:
|
|
1372
|
-
"""S15: remove the event4u/ namespace dir from each enabled surface."""
|
|
1373
|
-
import shutil
|
|
1374
|
-
targets = _global_targets(tools)
|
|
1375
|
-
removed: list[str] = []
|
|
1376
|
-
# Collect ancestor dirs named GLOBAL_NAMESPACE so we can drop the
|
|
1377
|
-
# shared parent (e.g. cursor/windsurf put rules + skills as siblings
|
|
1378
|
-
# under one event4u/ dir; removing both leaves a stranded namespace
|
|
1379
|
-
# dir). We never delete anything not literally named event4u/.
|
|
1380
|
-
namespace_parents: set[Path] = set()
|
|
1381
|
-
for surface, dirs in targets.items():
|
|
1382
|
-
for kind in ("rules", "skills"):
|
|
1383
|
-
d = dirs[kind]
|
|
1384
|
-
if d.exists():
|
|
1385
|
-
shutil.rmtree(d)
|
|
1386
|
-
removed.append(str(d))
|
|
1387
|
-
for ancestor in d.parents:
|
|
1388
|
-
if ancestor.name == GLOBAL_NAMESPACE:
|
|
1389
|
-
namespace_parents.add(ancestor)
|
|
1390
|
-
for parent in namespace_parents:
|
|
1391
|
-
if parent.is_dir() and not any(parent.iterdir()):
|
|
1392
|
-
parent.rmdir()
|
|
1393
|
-
removed.append(str(parent))
|
|
1394
|
-
if not QUIET:
|
|
1395
|
-
if removed:
|
|
1396
|
-
for r in removed:
|
|
1397
|
-
success(f"removed {r}")
|
|
1398
|
-
else:
|
|
1399
|
-
skip("global uninstall: nothing to remove")
|
|
1400
|
-
return 0
|
|
1401
|
-
|
|
1222
|
+
# The `--global` symlink-install scheme was retired under the npx-only
|
|
1223
|
+
# distribution model. The curated manifest (templates/global-install-manifest.yml)
|
|
1224
|
+
# and its helpers/dispatch are gone. The replacement is `npx @event4u/agent-config`
|
|
1225
|
+
# resolving the runtime per-invocation; the project's `.agent-settings.yml`
|
|
1226
|
+
# carries the version pin.
|
|
1402
1227
|
|
|
1403
1228
|
# --- Argument parsing ---
|
|
1404
1229
|
|
|
@@ -1457,21 +1282,6 @@ def parse_options(argv: list[str]) -> argparse.Namespace:
|
|
|
1457
1282
|
action="store_true",
|
|
1458
1283
|
help="skip the post-install hook smoke test (default: dry-fire dispatch:hook against every installed bridge)",
|
|
1459
1284
|
)
|
|
1460
|
-
parser.add_argument(
|
|
1461
|
-
"--global",
|
|
1462
|
-
dest="global_install",
|
|
1463
|
-
action="store_true",
|
|
1464
|
-
help=(
|
|
1465
|
-
"Phase-3 mode: ship kernel rules + curated top-N skills to user-scope "
|
|
1466
|
-
"dirs (~/.claude/, ~/.cursor/, ~/.codeium/windsurf/, ~/.config/agent-config/) "
|
|
1467
|
-
"so the agent has them in every project. Curation: templates/global-install-manifest.yml."
|
|
1468
|
-
),
|
|
1469
|
-
)
|
|
1470
|
-
parser.add_argument(
|
|
1471
|
-
"--uninstall",
|
|
1472
|
-
action="store_true",
|
|
1473
|
-
help="With --global: remove the event4u/ namespace dir from each enabled surface.",
|
|
1474
|
-
)
|
|
1475
1285
|
return parser.parse_args(argv)
|
|
1476
1286
|
|
|
1477
1287
|
|
|
@@ -1539,17 +1349,6 @@ def main(argv: list[str]) -> int:
|
|
|
1539
1349
|
info(f"Profile: {opts.profile}")
|
|
1540
1350
|
print()
|
|
1541
1351
|
|
|
1542
|
-
# --global: short-circuits the project-bridge path. Ships kernel rules
|
|
1543
|
-
# + curated skills to user-scope dirs and exits. --uninstall pairs
|
|
1544
|
-
# with --global to remove the namespace dir.
|
|
1545
|
-
if opts.global_install:
|
|
1546
|
-
tools = _parse_tools(opts.tools)
|
|
1547
|
-
if opts.uninstall:
|
|
1548
|
-
return uninstall_global(tools)
|
|
1549
|
-
return install_global(package_root, tools, opts.force)
|
|
1550
|
-
if opts.uninstall:
|
|
1551
|
-
fail("--uninstall is only valid combined with --global")
|
|
1552
|
-
|
|
1553
1352
|
ensure_agent_settings(project_root, package_root, opts.profile, opts.force)
|
|
1554
1353
|
|
|
1555
1354
|
tools = _parse_tools(opts.tools)
|
package/bin/install.php
DELETED
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env php
|
|
2
|
-
<?php
|
|
3
|
-
|
|
4
|
-
declare(strict_types=1);
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* Agent Config — Project Installer (Composer wrapper)
|
|
8
|
-
*
|
|
9
|
-
* Thin wrapper that delegates to scripts/install, the primary orchestrator.
|
|
10
|
-
* The orchestrator chains payload sync (install.sh) and bridge generation
|
|
11
|
-
* (install.py); this wrapper only exists so that PHP/Composer users can
|
|
12
|
-
* invoke it via `php vendor/bin/install.php` without knowing about bash.
|
|
13
|
-
*
|
|
14
|
-
* Usage:
|
|
15
|
-
* php vendor/bin/install.php # full install (every tool)
|
|
16
|
-
* php vendor/bin/install.php --profile=balanced # pick cost profile
|
|
17
|
-
* php vendor/bin/install.php --tools=claude-code,cursor # only those two surfaces
|
|
18
|
-
* php vendor/bin/install.php --tools=cursor --yes # CI-friendly, single tool
|
|
19
|
-
* php vendor/bin/install.php --list-tools # show valid tool IDs
|
|
20
|
-
* php vendor/bin/install.php --force # overwrite existing bridges
|
|
21
|
-
* php vendor/bin/install.php --skip-bridges # payload only
|
|
22
|
-
* php vendor/bin/install.php --skip-sync # bridges only
|
|
23
|
-
* php vendor/bin/install.php --help # full option list
|
|
24
|
-
*
|
|
25
|
-
* Valid --tools IDs (default: all):
|
|
26
|
-
* claude-code, claude-desktop, cursor, windsurf, cline,
|
|
27
|
-
* gemini-cli, copilot, augment, aider, codex, all
|
|
28
|
-
*/
|
|
29
|
-
|
|
30
|
-
$packageRoot = dirname(__DIR__);
|
|
31
|
-
$installer = $packageRoot . '/scripts/install';
|
|
32
|
-
|
|
33
|
-
if (! file_exists($installer)) {
|
|
34
|
-
fwrite(STDERR, " ❌ Installer script not found: {$installer}\n");
|
|
35
|
-
exit(1);
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
// Forward all CLI arguments to the bash orchestrator. Drop $argv[0] (this script).
|
|
39
|
-
$forwarded = array_slice($argv, 1);
|
|
40
|
-
$command = array_merge(['bash', $installer], $forwarded);
|
|
41
|
-
$escaped = array_map('escapeshellarg', $command);
|
|
42
|
-
|
|
43
|
-
$exitCode = 0;
|
|
44
|
-
passthru(implode(' ', $escaped), $exitCode);
|
|
45
|
-
exit($exitCode);
|
package/composer.json
DELETED
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "event4u/agent-config",
|
|
3
|
-
"description": "Shared agent configuration — skills, rules, commands, guidelines, and templates for AI coding tools",
|
|
4
|
-
"type": "library",
|
|
5
|
-
"license": "MIT",
|
|
6
|
-
"require": {
|
|
7
|
-
"php": ">=8.0"
|
|
8
|
-
},
|
|
9
|
-
"suggest": {
|
|
10
|
-
"@event4u/agent-memory": "Optional MCP-based memory backend (npm: @event4u/agent-memory ^1.1.0). Adds persistent agent learnings across sessions. Install with `npm install --save-dev @event4u/agent-memory` if your team wants the memory layer; otherwise agent-config falls back to file-based memory."
|
|
11
|
-
},
|
|
12
|
-
"bin": [
|
|
13
|
-
"bin/install.php",
|
|
14
|
-
"scripts/agent-config"
|
|
15
|
-
],
|
|
16
|
-
"archive": {
|
|
17
|
-
"exclude": [
|
|
18
|
-
"/.agent-src.uncompressed",
|
|
19
|
-
"/.compression-hashes.json",
|
|
20
|
-
"/agents",
|
|
21
|
-
"/tests",
|
|
22
|
-
|
|
23
|
-
"/Taskfile.yml",
|
|
24
|
-
"/.github",
|
|
25
|
-
"/.idea",
|
|
26
|
-
"/.claude",
|
|
27
|
-
"/.cursor",
|
|
28
|
-
"/.clinerules",
|
|
29
|
-
"/.windsurfrules",
|
|
30
|
-
"/GEMINI.md"
|
|
31
|
-
]
|
|
32
|
-
}
|
|
33
|
-
}
|
package/scripts/postinstall.sh
DELETED
|
@@ -1,76 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env bash
|
|
2
|
-
# postinstall.sh — npm postinstall wrapper for scripts/install
|
|
3
|
-
#
|
|
4
|
-
# Runs the orchestrator and decides on an exit strategy that is honest
|
|
5
|
-
# without breaking `npm install` for unrelated reasons:
|
|
6
|
-
#
|
|
7
|
-
# - Success → exit 0, silent.
|
|
8
|
-
# - Soft failure → exit 0, print actionable hint. The orchestrator
|
|
9
|
-
# already handles environment issues (no python3)
|
|
10
|
-
# internally and continues with the payload sync.
|
|
11
|
-
# - Hard failure → print a loud error block, print the captured output,
|
|
12
|
-
# exit 0. `npm install` keeps working; the developer
|
|
13
|
-
# sees exactly what failed and the command to retry.
|
|
14
|
-
#
|
|
15
|
-
# Delegates to scripts/install (the orchestrator). Never calls install.sh
|
|
16
|
-
# or install.py directly.
|
|
17
|
-
|
|
18
|
-
set -u
|
|
19
|
-
|
|
20
|
-
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
21
|
-
INSTALLER="$SCRIPT_DIR/install"
|
|
22
|
-
|
|
23
|
-
if [[ ! -f "$INSTALLER" ]]; then
|
|
24
|
-
# Nothing to do — shipping this wrapper without the installer would be a
|
|
25
|
-
# packaging bug, not a consumer problem.
|
|
26
|
-
echo "agent-config postinstall: $INSTALLER missing, skipping." >&2
|
|
27
|
-
exit 0
|
|
28
|
-
fi
|
|
29
|
-
|
|
30
|
-
LOG="$(mktemp -t agent-config-postinstall.XXXXXX.log 2>/dev/null || mktemp)"
|
|
31
|
-
trap 'rm -f "$LOG"' EXIT
|
|
32
|
-
|
|
33
|
-
bash "$INSTALLER" --quiet >"$LOG" 2>&1
|
|
34
|
-
CODE=$?
|
|
35
|
-
if [[ $CODE -eq 0 ]]; then
|
|
36
|
-
# Optional companion: @event4u/agent-memory. Suggest it once, only if
|
|
37
|
-
# the consumer hasn't already installed it (locally or on PATH). The
|
|
38
|
-
# hint is purely informational; agent-config falls back to file-based
|
|
39
|
-
# memory when the backend is absent.
|
|
40
|
-
if ! command -v memory >/dev/null 2>&1 \
|
|
41
|
-
&& ! command -v agent-memory >/dev/null 2>&1 \
|
|
42
|
-
&& [[ ! -d "$SCRIPT_DIR/../../@event4u/agent-memory" ]]; then
|
|
43
|
-
cat >&2 <<'HINT'
|
|
44
|
-
💡 agent-config tip: install @event4u/agent-memory for persistent agent
|
|
45
|
-
learnings across sessions (optional, dev-only):
|
|
46
|
-
|
|
47
|
-
npm install --save-dev @event4u/agent-memory
|
|
48
|
-
|
|
49
|
-
Skip if you don't need it — agent-config falls back to file-based memory.
|
|
50
|
-
HINT
|
|
51
|
-
fi
|
|
52
|
-
exit 0
|
|
53
|
-
fi
|
|
54
|
-
|
|
55
|
-
cat >&2 <<EOF
|
|
56
|
-
|
|
57
|
-
────────────────────────────────────────────────────────────────
|
|
58
|
-
⚠️ agent-config: postinstall failed (exit $CODE)
|
|
59
|
-
────────────────────────────────────────────────────────────────
|
|
60
|
-
Output:
|
|
61
|
-
$(sed 's/^/ /' "$LOG")
|
|
62
|
-
|
|
63
|
-
The rest of \`npm install\` continues — but agent-config was NOT
|
|
64
|
-
installed. Re-run manually to see the full trace:
|
|
65
|
-
|
|
66
|
-
bash node_modules/@event4u/agent-config/scripts/install
|
|
67
|
-
|
|
68
|
-
If this keeps happening, please open an issue:
|
|
69
|
-
https://github.com/event4u-app/agent-config/issues
|
|
70
|
-
────────────────────────────────────────────────────────────────
|
|
71
|
-
|
|
72
|
-
EOF
|
|
73
|
-
|
|
74
|
-
# Exit 0 so npm install doesn't break for unrelated consumer workflows.
|
|
75
|
-
# The loud block above makes the failure visible — unlike `|| true`.
|
|
76
|
-
exit 0
|
|
@@ -1,91 +0,0 @@
|
|
|
1
|
-
# Global Install Manifest — road-to-simplicity-and-everywhere Phase 3
|
|
2
|
-
#
|
|
3
|
-
# Curated subset of rules + skills shipped to user-scope directories
|
|
4
|
-
# (~/.claude/, ~/.cursor/, ~/.codeium/windsurf/, ~/.config/agent-config/)
|
|
5
|
-
# by `scripts/install --global`. Without curation we'd dump 200+ skills
|
|
6
|
-
# into user dirs — that is the failure mode anthropics/claude-code#53950
|
|
7
|
-
# flagged.
|
|
8
|
-
#
|
|
9
|
-
# Schema (v1):
|
|
10
|
-
# kernel_rules: list[str] — rule IDs from router.json's `kernel`.
|
|
11
|
-
# Always shipped to every enabled surface.
|
|
12
|
-
# top_skills: list[entry] — curated universal skills.
|
|
13
|
-
# entry.id : skill directory under .agent-src/skills/
|
|
14
|
-
# entry.surfaces : subset of [claude-code, cursor, windsurf, fallback]
|
|
15
|
-
# — fallback is always written.
|
|
16
|
-
#
|
|
17
|
-
# Source: kernel_rules mirrors router.json; top_skills is a 15-pick
|
|
18
|
-
# distilled from .agent-src/skills/ — universal coding-loop helpers
|
|
19
|
-
# (work, commit, PR, review, quality, analyze, handoff). Per-stack
|
|
20
|
-
# skills (laravel, react-shadcn-ui, php-coder) stay project-local.
|
|
21
|
-
#
|
|
22
|
-
# Per-tool target paths (handled by scripts/install.py global subcommand):
|
|
23
|
-
# claude-code : ~/.claude/skills/event4u/<id>/SKILL.md
|
|
24
|
-
# ~/.claude/rules/event4u/<rule>.md
|
|
25
|
-
# cursor : ~/.cursor/rules/imported/event4u/<rule>.mdc
|
|
26
|
-
# ~/.cursor/skills/event4u/<id>/ (skills surface; mirrors agent-os)
|
|
27
|
-
# windsurf : ~/.codeium/windsurf/global_workflows/event4u/<id>.md
|
|
28
|
-
# fallback : ~/.config/agent-config/{rules,skills}/event4u/
|
|
29
|
-
#
|
|
30
|
-
# All writes are namespaced under `event4u/` so `--global --uninstall`
|
|
31
|
-
# can `rm -rf` the namespace dir without touching user-added files.
|
|
32
|
-
|
|
33
|
-
schema_version: 1
|
|
34
|
-
|
|
35
|
-
# Always-loaded rules — mirrors router.json's `kernel` array.
|
|
36
|
-
# Symlinked / copied into every enabled surface's rules dir.
|
|
37
|
-
kernel_rules:
|
|
38
|
-
- agent-authority
|
|
39
|
-
- ask-when-uncertain
|
|
40
|
-
- commit-policy
|
|
41
|
-
- direct-answers
|
|
42
|
-
- language-and-tone
|
|
43
|
-
- no-cheap-questions
|
|
44
|
-
- non-destructive-by-default
|
|
45
|
-
- scope-control
|
|
46
|
-
- verify-before-complete
|
|
47
|
-
|
|
48
|
-
# Top-N curated skills. The 15 picks below are coding-loop universals:
|
|
49
|
-
# the agent reaches for them on almost any task, regardless of stack.
|
|
50
|
-
# Per-stack and domain skills are deliberately omitted — they belong in
|
|
51
|
-
# project-local installs where the stack signal is unambiguous.
|
|
52
|
-
top_skills:
|
|
53
|
-
# --- Workflow drivers (most-touched commands) ---
|
|
54
|
-
- id: work
|
|
55
|
-
surfaces: [claude-code, cursor, windsurf, fallback]
|
|
56
|
-
- id: commit
|
|
57
|
-
surfaces: [claude-code, cursor, windsurf, fallback]
|
|
58
|
-
- id: create-pr
|
|
59
|
-
surfaces: [claude-code, cursor, windsurf, fallback]
|
|
60
|
-
- id: review-changes
|
|
61
|
-
surfaces: [claude-code, cursor, windsurf, fallback]
|
|
62
|
-
- id: quality-fix
|
|
63
|
-
surfaces: [claude-code, cursor, windsurf, fallback]
|
|
64
|
-
|
|
65
|
-
# --- Session / context management ---
|
|
66
|
-
- id: agent-handoff
|
|
67
|
-
surfaces: [claude-code, cursor, windsurf, fallback]
|
|
68
|
-
- id: agent-status
|
|
69
|
-
surfaces: [claude-code, cursor, windsurf, fallback]
|
|
70
|
-
- id: project-analyze
|
|
71
|
-
surfaces: [claude-code, cursor, windsurf, fallback]
|
|
72
|
-
- id: project-health
|
|
73
|
-
surfaces: [claude-code, cursor, windsurf, fallback]
|
|
74
|
-
|
|
75
|
-
# --- Investigation / debugging ---
|
|
76
|
-
- id: bug-investigate
|
|
77
|
-
surfaces: [claude-code, cursor, windsurf, fallback]
|
|
78
|
-
- id: bug-fix
|
|
79
|
-
surfaces: [claude-code, cursor, windsurf, fallback]
|
|
80
|
-
- id: systematic-debugging
|
|
81
|
-
surfaces: [claude-code, cursor, windsurf, fallback]
|
|
82
|
-
|
|
83
|
-
# --- Ticket / PR drivers ---
|
|
84
|
-
- id: implement-ticket
|
|
85
|
-
surfaces: [claude-code, cursor, windsurf, fallback]
|
|
86
|
-
- id: prepare-for-review
|
|
87
|
-
surfaces: [claude-code, cursor, windsurf, fallback]
|
|
88
|
-
|
|
89
|
-
# --- Onboarding (single command, surfaces a project) ---
|
|
90
|
-
- id: onboard
|
|
91
|
-
surfaces: [claude-code, cursor, windsurf, fallback]
|