@lifeaitools/rdc-skills 0.9.35 → 0.9.36

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.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rdc",
3
- "version": "0.9.35",
3
+ "version": "0.9.36",
4
4
  "description": "RDC typed-agent dispatch skill suite for Claude Code — plan, build, review, overnight unattended builds with work-item tracking and TDD enforcement.",
5
5
  "author": {
6
6
  "name": "LIFEAI",
package/CHANGELOG.md CHANGED
@@ -7,6 +7,21 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ---
9
9
 
10
+ ## v0.9.36 — Portable installer profiles and startup onboarding
11
+
12
+ ### Added
13
+
14
+ - **Installer profiles.** `--profile core` installs clean-box-safe hooks only; `--profile lifeai` keeps the LIFEAI/regen-root cwd, clauth, Supabase, and overnight hooks. `auto` chooses `lifeai` only when a sibling `regen-root` project is detected.
15
+ - **Managed startup guide.** New `guides/rdc-skills-startup.md` explains what RDC skills add, the active profiles, and where to find skills, commands, guides, hooks, and installer behavior.
16
+ - **Optional startup block writer.** `--project-root <path> --write-startup-blocks` writes `.rdc/guides/rdc-skills-startup.md` plus managed RDC sections in project `CLAUDE.md` and `AGENTS.md`.
17
+ - **Install welcome.** The installer now prints the selected profile, what it enables, and where to look next.
18
+
19
+ ### Changed
20
+
21
+ - The default clean-box profile no longer wires regen-root-specific hooks such as cwd lock, Supabase work-item exit gate, rate-limit retry, or overnight open-epic guard.
22
+
23
+ ---
24
+
10
25
  ## v0.9.35 — RDC output-contract hook enforcement
11
26
 
12
27
  ### Added
package/README.md CHANGED
@@ -45,6 +45,27 @@ rm -rf ~/.claude/plugins/cache/rdc-skills/rdc-skills/0.7.*
45
45
 
46
46
  Use **one method only**: plugin (Option A or B) OR manual install — never both.
47
47
 
48
+ ### Installer profiles
49
+
50
+ `scripts/install-rdc-skills.js` supports profiles:
51
+
52
+ ```bash
53
+ node scripts/install-rdc-skills.js --profile core
54
+ node scripts/install-rdc-skills.js --profile lifeai
55
+ ```
56
+
57
+ - `core` is safe for a clean machine with only rdc-skills installed. It wires portable hooks only: RDC output-contract enforcement, foreground-process policy, commit-message hygiene, and non-blocking work logging.
58
+ - `lifeai` is for the LIFEAI/regen-root workstation. It additionally wires the regen-root cwd lock, clauth/Supabase work-item gates, overnight queue guard, and LIFEAI session hooks.
59
+ - `auto` is the default. It chooses `lifeai` only when a sibling `regen-root` project is detected; otherwise it chooses `core`.
60
+
61
+ To add managed startup instructions to a project:
62
+
63
+ ```bash
64
+ node scripts/install-rdc-skills.js --project-root /path/to/project --write-startup-blocks
65
+ ```
66
+
67
+ This writes `.rdc/guides/rdc-skills-startup.md` and managed RDC sections in `CLAUDE.md` and `AGENTS.md`.
68
+
48
69
  ### Legacy install scripts (deprecated since v0.6.0)
49
70
 
50
71
  `scripts/install.sh` and `scripts/install.ps1` copy files into `~/.claude/skills/user/`. These exist only for environments that cannot use the plugin system. Running them alongside the plugin creates duplicates. Do not use them if you have the plugin installed.
@@ -176,7 +197,7 @@ python3 -c "import json; print(json.load(open('package.json'))['version'])"
176
197
  /rdc:help
177
198
  ```
178
199
 
179
- Current version: **v0.9.35**
200
+ Current version: **v0.9.36**
180
201
 
181
202
  ## Quick Start
182
203
 
@@ -0,0 +1,30 @@
1
+ # RDC Skills Startup Contract
2
+ > Managed by `rdc-skills`. Keep local project-specific details in adjacent project guides.
3
+
4
+ ## What RDC Skills Adds
5
+
6
+ - Slash commands for the RDC workflow: plan, build, review, report, design, deploy, release, status, and work item operations.
7
+ - Output-contract enforcement for active `/rdc:*` turns: visible checklist rows plus a final verdict line.
8
+ - Engineering behavior guidance: small scoped changes, explicit assumptions, evidence for completed work, and honest blockers.
9
+ - Optional project integrations for work items, credentials, deployments, and release automation.
10
+
11
+ ## Agent Startup Rules
12
+
13
+ 1. Read the active project instructions first (`CLAUDE.md` for Claude Code, `AGENTS.md` for Codex).
14
+ 2. For any `/rdc:*` invocation, follow `.rdc/guides/output-contract.md` and `.rdc/guides/engineering-behavior.md`.
15
+ 3. Do not treat skill prose as proof. Completed work needs evidence: command output, test result, route probe, screenshot, SQL result, or source citation.
16
+ 4. If a project has its own approval gates, architecture rules, or credential model, those project rules override generic RDC defaults.
17
+ 5. When an RDC skill cannot access the required project services, stop with a specific blocker instead of inventing a fallback.
18
+
19
+ ## Profiles
20
+
21
+ - `core`: portable defaults for a clean machine. No regen-root cwd lock, clauth requirement, Supabase exit gate, or LIFEAI deployment assumption.
22
+ - `lifeai`: LIFEAI/regen-root defaults. Enables project-specific hooks and workflows for clauth, Supabase work items, deployment, and overnight queue behavior.
23
+
24
+ ## Where To Look
25
+
26
+ - Skills: `skills/<name>/SKILL.md`
27
+ - Commands: `commands/<name>.md`
28
+ - Guides: `guides/*.md` and project copies under `.rdc/guides/`
29
+ - Hooks: `hooks/*.js`
30
+ - Installer: `scripts/install-rdc-skills.js`
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lifeaitools/rdc-skills",
3
- "version": "0.9.35",
3
+ "version": "0.9.36",
4
4
  "description": "RDC typed-agent dispatch skill suite for Claude Code - plan, build, review, overnight builds",
5
5
  "keywords": [
6
6
  "claude-code",
@@ -19,7 +19,7 @@
19
19
  "type": "plugin",
20
20
  "skills": "skills/",
21
21
  "guides": "guides/",
22
- "version": "0.9.35",
22
+ "version": "0.9.36",
23
23
  "commands": "commands/"
24
24
  },
25
25
  "scripts": {
@@ -5,9 +5,12 @@
5
5
  * Usage:
6
6
  * node scripts/install-rdc-skills.js ← standard
7
7
  * node scripts/install-rdc-skills.js --skip-hooks ← skip hook wiring
8
+ * node scripts/install-rdc-skills.js --profile core ← clean-box portable hooks
9
+ * node scripts/install-rdc-skills.js --profile lifeai ← LIFEAI/regen-root hooks
8
10
  * node scripts/install-rdc-skills.js --claude-home <path> ← custom CLI home
9
11
  * node scripts/install-rdc-skills.js --codex-root <path> ← also install to .agents/skills/user/
10
12
  * node scripts/install-rdc-skills.js --codex-skill-dir <path> ← also install to a Codex skill dir
13
+ * node scripts/install-rdc-skills.js --project-root <path> --write-startup-blocks
11
14
  * node scripts/install-rdc-skills.js --migrate <path> ← migrate docs/ → .rdc/
12
15
  *
13
16
  * What it does:
@@ -32,11 +35,16 @@ const { execSync } = require('child_process');
32
35
  // ── Args ──────────────────────────────────────────────────────────────────────
33
36
  const args = process.argv.slice(2);
34
37
  const skipHooks = args.includes('--skip-hooks');
38
+ const profileIdx = args.indexOf('--profile');
39
+ const profileArg = profileIdx >= 0 ? String(args[profileIdx + 1] || '').toLowerCase() : 'auto';
35
40
  const homeIdx = args.indexOf('--claude-home');
36
41
  const claudeHome = homeIdx >= 0 ? args[homeIdx + 1] : path.join(os.homedir(), '.claude');
37
42
  const migrateIdx = args.indexOf('--migrate');
38
43
  const doMigrate = migrateIdx >= 0;
39
44
  const migratePath = doMigrate ? (args[migrateIdx + 1] || process.cwd()) : null;
45
+ const projectIdx = args.indexOf('--project-root');
46
+ const projectRootArg = projectIdx >= 0 ? path.resolve(args[projectIdx + 1]) : null;
47
+ const shouldWriteStartupBlocks = args.includes('--write-startup-blocks');
40
48
 
41
49
  const repoRoot = path.resolve(__dirname, '..');
42
50
 
@@ -44,6 +52,7 @@ const codexIdx = args.indexOf('--codex-root');
44
52
  const codexRoot = codexIdx >= 0
45
53
  ? path.resolve(args[codexIdx + 1])
46
54
  : (() => {
55
+ if (projectRootArg) return null;
47
56
  const sibling = path.resolve(repoRoot, '..', 'regen-root');
48
57
  return fs.existsSync(path.join(sibling, '.agents')) ? sibling : null;
49
58
  })();
@@ -54,6 +63,18 @@ const explicitCodexSkillDir = codexSkillDirIdx >= 0
54
63
  const hooksSrc = path.join(repoRoot, 'hooks');
55
64
  const hooksDst = path.join(claudeHome, 'hooks');
56
65
  const settingsPath = path.join(claudeHome, 'settings.json');
66
+ const detectedLifeaiRoot = (() => {
67
+ const sibling = path.resolve(repoRoot, '..', 'regen-root');
68
+ return fs.existsSync(path.join(sibling, 'CLAUDE.md')) && fs.existsSync(path.join(sibling, '.rdc')) ? sibling : null;
69
+ })();
70
+ const installProfile = (() => {
71
+ if (profileArg === 'core' || profileArg === 'lifeai') return profileArg;
72
+ if (profileArg !== 'auto') {
73
+ console.log(` \x1b[33m⚠\x1b[0m Unknown --profile "${profileArg}" — using auto`);
74
+ }
75
+ return detectedLifeaiRoot ? 'lifeai' : 'core';
76
+ })();
77
+ const projectRoot = projectRootArg || codexRoot || detectedLifeaiRoot;
57
78
 
58
79
  const PLUGIN_KEY = 'rdc-skills@rdc-skills';
59
80
  const MARKETPLACE = 'rdc-skills';
@@ -108,6 +129,7 @@ function copyMissingProjectGuides(projectRoot) {
108
129
  let copied = 0;
109
130
  for (const entry of fs.readdirSync(src, { withFileTypes: true })) {
110
131
  if (!entry.isFile() || !entry.name.endsWith('.md')) continue;
132
+ if (entry.name === 'rdc-skills-startup.md') continue; // installed only by --write-startup-blocks
111
133
  const target = path.join(dst, entry.name);
112
134
  if (fs.existsSync(target)) continue;
113
135
  fs.copyFileSync(path.join(src, entry.name), target);
@@ -126,6 +148,53 @@ function writeJson(p, data, indent = 2) {
126
148
  fs.writeFileSync(p, JSON.stringify(data, null, indent));
127
149
  }
128
150
 
151
+ function upsertManagedBlock(filePath, title, body) {
152
+ const begin = `<!-- BEGIN RDC-SKILLS:${title} -->`;
153
+ const end = `<!-- END RDC-SKILLS:${title} -->`;
154
+ const block = `${begin}\n${body.trim()}\n${end}\n`;
155
+ const current = fs.existsSync(filePath) ? fs.readFileSync(filePath, 'utf8') : '';
156
+ const re = new RegExp(`${begin.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}[\\s\\S]*?${end.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}\\n?`, 'm');
157
+ const next = re.test(current)
158
+ ? current.replace(re, block)
159
+ : `${current.replace(/\s*$/, '')}${current.trim() ? '\n\n' : ''}${block}`;
160
+ if (next !== current) {
161
+ fs.mkdirSync(path.dirname(filePath), { recursive: true });
162
+ fs.writeFileSync(filePath, next);
163
+ return true;
164
+ }
165
+ return false;
166
+ }
167
+
168
+ function writeStartupBlocks(targetRoot, profile) {
169
+ if (!targetRoot) return { wrote: 0, skipped: 'no-project-root' };
170
+ const startupSrc = path.join(repoRoot, 'guides', 'rdc-skills-startup.md');
171
+ const guidesDir = path.join(targetRoot, '.rdc', 'guides');
172
+ const startupDst = path.join(guidesDir, 'rdc-skills-startup.md');
173
+ fs.mkdirSync(guidesDir, { recursive: true });
174
+ fs.copyFileSync(startupSrc, startupDst);
175
+
176
+ let wrote = 1;
177
+ const claudeBody = [
178
+ '## RDC Skills',
179
+ '',
180
+ '@.rdc/guides/rdc-skills-startup.md',
181
+ '',
182
+ `Installed profile: \`${profile}\`.`,
183
+ 'For `/rdc:*` work, follow `.rdc/guides/output-contract.md` and `.rdc/guides/engineering-behavior.md`.',
184
+ ].join('\n');
185
+ const agentsBody = [
186
+ '## RDC Skills',
187
+ '',
188
+ 'Read `.rdc/guides/rdc-skills-startup.md` before using any `rdc:*` workflow.',
189
+ `Installed profile: \`${profile}\`.`,
190
+ 'For `/rdc:*` work, follow `.rdc/guides/output-contract.md` and `.rdc/guides/engineering-behavior.md`.',
191
+ ].join('\n');
192
+
193
+ if (upsertManagedBlock(path.join(targetRoot, 'CLAUDE.md'), 'STARTUP', claudeBody)) wrote++;
194
+ if (upsertManagedBlock(path.join(targetRoot, 'AGENTS.md'), 'STARTUP', agentsBody)) wrote++;
195
+ return { wrote, skipped: null };
196
+ }
197
+
129
198
  // ── Frontmatter parser ────────────────────────────────────────────────────────
130
199
  function readFrontmatter(filePath) {
131
200
  try {
@@ -546,7 +615,7 @@ function buildZip(version) {
546
615
  }
547
616
 
548
617
  // ── Hook config ───────────────────────────────────────────────────────────────
549
- function buildHooksConfig(hooksDir) {
618
+ function buildHooksConfig(hooksDir, profile = 'core') {
550
619
  const base = hooksDir.replace(/\\/g, '/');
551
620
  const cmd = (file, msg) => {
552
621
  const command = process.platform === 'win32'
@@ -556,21 +625,16 @@ function buildHooksConfig(hooksDir) {
556
625
  if (msg) entry.statusMessage = msg;
557
626
  return entry;
558
627
  };
559
- return {
628
+ const config = {
560
629
  UserPromptExpansion: [{ hooks: [
561
630
  cmd('rdc-invocation-marker.js', 'Marking RDC slash command...'),
562
631
  ]}],
563
632
  UserPromptSubmit: [{ hooks: [
564
633
  cmd('rdc-invocation-marker.js', 'Marking RDC prompt...'),
565
634
  ]}],
566
- SessionStart: [{ hooks: [
567
- cmd('check-cwd.js'),
568
- cmd('check-stale-work-items.js', 'Checking for stale work items...'),
569
- ]}],
570
635
  PreToolUse: [
571
636
  { hooks: [
572
637
  cmd('foreground-process-gate.js', 'Checking foreground process policy...'),
573
- cmd('work-item-exit-gate.js', 'Checking work item exit gates...'),
574
638
  ]},
575
639
  { matcher: 'Bash', hooks: [
576
640
  cmd('require-work-item-on-commit.js'),
@@ -579,20 +643,36 @@ function buildHooksConfig(hooksDir) {
579
643
  PostToolUse: [{ hooks: [
580
644
  cmd('check-services.js'),
581
645
  ]}],
582
- PreCompact: [{ hooks: [
583
- cmd('precompact-log.js'),
584
- ]}],
585
- PostCompact: [{ hooks: [
586
- cmd('postcompact-log.js'),
587
- cmd('restart-brief.js', 'Writing restart brief...'),
588
- ]}],
589
646
  Stop: [{ hooks: [
590
- cmd('rate-limit-retry.js', 'Checking for rate limits...'),
591
647
  cmd('rdc-output-contract-gate.js', 'Checking RDC output contract...'),
592
648
  cmd('post-work-check.js', 'Checking for undocumented work...'),
593
- cmd('no-stop-open-epics.js', 'Checking for open epics...'),
594
649
  ]}],
595
650
  };
651
+
652
+ if (profile === 'lifeai') {
653
+ config.SessionStart = [{ hooks: [
654
+ cmd('check-cwd.js'),
655
+ cmd('check-stale-work-items.js', 'Checking for stale work items...'),
656
+ ]}];
657
+ config.PreToolUse[0].hooks.push(
658
+ cmd('work-item-exit-gate.js', 'Checking work item exit gates...'),
659
+ );
660
+ config.PreCompact = [{ hooks: [
661
+ cmd('precompact-log.js'),
662
+ ]}];
663
+ config.PostCompact = [{ hooks: [
664
+ cmd('postcompact-log.js'),
665
+ cmd('restart-brief.js', 'Writing restart brief...'),
666
+ ]}];
667
+ config.Stop[0].hooks.unshift(
668
+ cmd('rate-limit-retry.js', 'Checking for rate limits...'),
669
+ );
670
+ config.Stop[0].hooks.push(
671
+ cmd('no-stop-open-epics.js', 'Checking for open epics...'),
672
+ );
673
+ }
674
+
675
+ return config;
596
676
  }
597
677
 
598
678
  // ── Preflight ─────────────────────────────────────────────────────────────────
@@ -682,6 +762,7 @@ async function main() {
682
762
  console.log('');
683
763
  console.log(` CLAUDE_HOME : ${claudeHome}`);
684
764
  console.log(` Plugin root : ${repoRoot}`);
765
+ console.log(` Profile : ${installProfile}${profileArg === 'auto' ? ' (auto)' : ''}`);
685
766
  console.log('');
686
767
 
687
768
  if (!fs.existsSync(claudeHome)) {
@@ -822,11 +903,20 @@ async function main() {
822
903
  info('[4/6] Hook wiring — skipped (--skip-hooks)');
823
904
  } else {
824
905
  const settings = readJson(settingsPath);
825
- settings.hooks = buildHooksConfig(hooksDst);
906
+ settings.hooks = buildHooksConfig(hooksDst, installProfile);
826
907
  writeJson(settingsPath, settings);
827
908
  ok(`[4/6] Hook wiring — ${settingsPath}`);
828
909
  }
829
910
 
911
+ // 4.5 Optional startup blocks
912
+ if (shouldWriteStartupBlocks) {
913
+ const startup = writeStartupBlocks(projectRoot, installProfile);
914
+ if (startup.skipped) warn(`[4.5] Startup — skipped (${startup.skipped})`);
915
+ else ok(`[4.5] Startup — wrote managed startup guide/block(s) under ${projectRoot}`);
916
+ } else {
917
+ info('[4.5] Startup — skipped (use --project-root <path> --write-startup-blocks)');
918
+ }
919
+
830
920
  // 5. Zip for claude.ai / distribution
831
921
  const zipPath = buildZip(version);
832
922
  if (zipPath) {
@@ -897,6 +987,15 @@ async function main() {
897
987
  console.log(' Cowork : restart Claude Desktop — /rdc:status in a new Cowork session');
898
988
  console.log(' claude.ai : no plugin install needed — use FS MCP to read commands on demand');
899
989
  console.log(' dist/rdc-skills-plugin-v' + version + '.zip available if needed');
990
+ console.log('');
991
+ console.log(` Profile: ${installProfile}`);
992
+ if (installProfile === 'core') {
993
+ console.log(' Core hooks are portable: RDC output contract + foreground process + commit-message hygiene.');
994
+ console.log(' Project services are not provisioned. Configure work items, credentials, deploys, and project guides before using infrastructure-heavy skills.');
995
+ } else {
996
+ console.log(' LIFEAI hooks are active: regen-root cwd lock, Supabase work-item gates, clauth-aware checks, and overnight queue guard.');
997
+ }
998
+ console.log(' Startup blocks: run with --project-root <path> --write-startup-blocks to add managed CLAUDE.md/AGENTS.md sections.');
900
999
 
901
1000
  listCommands();
902
1001
 
@@ -7,10 +7,14 @@
7
7
  # Usage:
8
8
  # ./install.ps1 # standard install
9
9
  # ./install.ps1 -SkipHooks # skip hooks registration (e.g. if you manage hooks manually)
10
+ # ./install.ps1 -Profile core # portable hooks only
11
+ # ./install.ps1 -Profile lifeai # LIFEAI/regen-root hooks
10
12
  # ./install.ps1 -ClaudeHome <path> # custom CLAUDE_HOME
11
13
 
12
14
  param(
13
15
  [string]$ClaudeHome = "",
16
+ [ValidateSet("auto", "core", "lifeai")]
17
+ [string]$Profile = "auto",
14
18
  [switch]$SkipHooks = $false,
15
19
  [switch]$Force = $false
16
20
  )
@@ -22,6 +26,12 @@ if (-not $ClaudeHome) {
22
26
 
23
27
  $scriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path
24
28
  $repoRoot = Split-Path -Parent $scriptDir
29
+ $lifeaiRoot = Join-Path (Split-Path -Parent $repoRoot) "regen-root"
30
+ $installProfile = if ($Profile -eq "auto") {
31
+ if ((Test-Path (Join-Path $lifeaiRoot "CLAUDE.md")) -and (Test-Path (Join-Path $lifeaiRoot ".rdc"))) { "lifeai" } else { "core" }
32
+ } else {
33
+ $Profile
34
+ }
25
35
 
26
36
  Write-Host ""
27
37
  Write-Host " rdc-skills Installer" -ForegroundColor Green
@@ -29,6 +39,7 @@ Write-Host " ====================" -ForegroundColor Green
29
39
  Write-Host ""
30
40
  Write-Host " CLAUDE_HOME : $ClaudeHome" -ForegroundColor Cyan
31
41
  Write-Host " Plugin root : $repoRoot" -ForegroundColor Cyan
42
+ Write-Host " Profile : $installProfile$(if ($Profile -eq 'auto') { ' (auto)' } else { '' })" -ForegroundColor Cyan
32
43
  Write-Host ""
33
44
 
34
45
  if (-not (Test-Path $ClaudeHome)) {
@@ -96,19 +107,10 @@ if ($SkipHooks) {
96
107
  )
97
108
  }
98
109
  )
99
- SessionStart = @(
100
- [PSCustomObject]@{
101
- hooks = @(
102
- [PSCustomObject]@{ type = "command"; command = "powershell.exe -NoProfile -NonInteractive -ExecutionPolicy Bypass -WindowStyle Hidden -File `"$hooksBase/run-hidden-hook.ps1`" `"$hooksBase/check-cwd.js`"" },
103
- [PSCustomObject]@{ type = "command"; command = "powershell.exe -NoProfile -NonInteractive -ExecutionPolicy Bypass -WindowStyle Hidden -File `"$hooksBase/run-hidden-hook.ps1`" `"$hooksBase/check-stale-work-items.js`""; statusMessage = "Checking for stale work items..." }
104
- )
105
- }
106
- )
107
110
  PreToolUse = @(
108
111
  [PSCustomObject]@{
109
112
  hooks = @(
110
- [PSCustomObject]@{ type = "command"; command = "powershell.exe -NoProfile -NonInteractive -ExecutionPolicy Bypass -WindowStyle Hidden -File `"$hooksBase/run-hidden-hook.ps1`" `"$hooksBase/foreground-process-gate.js`""; statusMessage = "Checking foreground process policy..." },
111
- [PSCustomObject]@{ type = "command"; command = "powershell.exe -NoProfile -NonInteractive -ExecutionPolicy Bypass -WindowStyle Hidden -File `"$hooksBase/run-hidden-hook.ps1`" `"$hooksBase/work-item-exit-gate.js`""; statusMessage = "Checking work item exit gates..." }
113
+ [PSCustomObject]@{ type = "command"; command = "powershell.exe -NoProfile -NonInteractive -ExecutionPolicy Bypass -WindowStyle Hidden -File `"$hooksBase/run-hidden-hook.ps1`" `"$hooksBase/foreground-process-gate.js`""; statusMessage = "Checking foreground process policy..." }
112
114
  )
113
115
  },
114
116
  [PSCustomObject]@{
@@ -125,31 +127,42 @@ if ($SkipHooks) {
125
127
  )
126
128
  }
127
129
  )
128
- PreCompact = @(
130
+ Stop = @(
129
131
  [PSCustomObject]@{
130
132
  hooks = @(
131
- [PSCustomObject]@{ type = "command"; command = "powershell.exe -NoProfile -NonInteractive -ExecutionPolicy Bypass -WindowStyle Hidden -File `"$hooksBase/run-hidden-hook.ps1`" `"$hooksBase/precompact-log.js`"" }
133
+ [PSCustomObject]@{ type = "command"; command = "powershell.exe -NoProfile -NonInteractive -ExecutionPolicy Bypass -WindowStyle Hidden -File `"$hooksBase/run-hidden-hook.ps1`" `"$hooksBase/rdc-output-contract-gate.js`""; statusMessage = "Checking RDC output contract..." },
134
+ [PSCustomObject]@{ type = "command"; command = "powershell.exe -NoProfile -NonInteractive -ExecutionPolicy Bypass -WindowStyle Hidden -File `"$hooksBase/run-hidden-hook.ps1`" `"$hooksBase/post-work-check.js`""; statusMessage = "Checking for undocumented work..." }
132
135
  )
133
136
  }
134
137
  )
135
- PostCompact = @(
138
+ }
139
+
140
+ if ($installProfile -eq "lifeai") {
141
+ $hooksConfig | Add-Member -NotePropertyName "SessionStart" -NotePropertyValue @(
136
142
  [PSCustomObject]@{
137
143
  hooks = @(
138
- [PSCustomObject]@{ type = "command"; command = "powershell.exe -NoProfile -NonInteractive -ExecutionPolicy Bypass -WindowStyle Hidden -File `"$hooksBase/run-hidden-hook.ps1`" `"$hooksBase/postcompact-log.js`"" },
139
- [PSCustomObject]@{ type = "command"; command = "powershell.exe -NoProfile -NonInteractive -ExecutionPolicy Bypass -WindowStyle Hidden -File `"$hooksBase/run-hidden-hook.ps1`" `"$hooksBase/restart-brief.js`""; statusMessage = "Writing restart brief..." }
144
+ [PSCustomObject]@{ type = "command"; command = "powershell.exe -NoProfile -NonInteractive -ExecutionPolicy Bypass -WindowStyle Hidden -File `"$hooksBase/run-hidden-hook.ps1`" `"$hooksBase/check-cwd.js`"" },
145
+ [PSCustomObject]@{ type = "command"; command = "powershell.exe -NoProfile -NonInteractive -ExecutionPolicy Bypass -WindowStyle Hidden -File `"$hooksBase/run-hidden-hook.ps1`" `"$hooksBase/check-stale-work-items.js`""; statusMessage = "Checking for stale work items..." }
140
146
  )
141
147
  }
142
148
  )
143
- Stop = @(
149
+ $hooksConfig.PreToolUse[0].hooks += [PSCustomObject]@{ type = "command"; command = "powershell.exe -NoProfile -NonInteractive -ExecutionPolicy Bypass -WindowStyle Hidden -File `"$hooksBase/run-hidden-hook.ps1`" `"$hooksBase/work-item-exit-gate.js`""; statusMessage = "Checking work item exit gates..." }
150
+ $hooksConfig | Add-Member -NotePropertyName "PreCompact" -NotePropertyValue @(
151
+ [PSCustomObject]@{ hooks = @([PSCustomObject]@{ type = "command"; command = "powershell.exe -NoProfile -NonInteractive -ExecutionPolicy Bypass -WindowStyle Hidden -File `"$hooksBase/run-hidden-hook.ps1`" `"$hooksBase/precompact-log.js`"" }) }
152
+ )
153
+ $hooksConfig | Add-Member -NotePropertyName "PostCompact" -NotePropertyValue @(
144
154
  [PSCustomObject]@{
145
155
  hooks = @(
146
- [PSCustomObject]@{ type = "command"; command = "powershell.exe -NoProfile -NonInteractive -ExecutionPolicy Bypass -WindowStyle Hidden -File `"$hooksBase/run-hidden-hook.ps1`" `"$hooksBase/rate-limit-retry.js`""; statusMessage = "Checking for rate limits..." },
147
- [PSCustomObject]@{ type = "command"; command = "powershell.exe -NoProfile -NonInteractive -ExecutionPolicy Bypass -WindowStyle Hidden -File `"$hooksBase/run-hidden-hook.ps1`" `"$hooksBase/rdc-output-contract-gate.js`""; statusMessage = "Checking RDC output contract..." },
148
- [PSCustomObject]@{ type = "command"; command = "powershell.exe -NoProfile -NonInteractive -ExecutionPolicy Bypass -WindowStyle Hidden -File `"$hooksBase/run-hidden-hook.ps1`" `"$hooksBase/post-work-check.js`""; statusMessage = "Checking for undocumented work..." },
149
- [PSCustomObject]@{ type = "command"; command = "powershell.exe -NoProfile -NonInteractive -ExecutionPolicy Bypass -WindowStyle Hidden -File `"$hooksBase/run-hidden-hook.ps1`" `"$hooksBase/no-stop-open-epics.js`""; statusMessage = "Checking for open epics..." }
156
+ [PSCustomObject]@{ type = "command"; command = "powershell.exe -NoProfile -NonInteractive -ExecutionPolicy Bypass -WindowStyle Hidden -File `"$hooksBase/run-hidden-hook.ps1`" `"$hooksBase/postcompact-log.js`"" },
157
+ [PSCustomObject]@{ type = "command"; command = "powershell.exe -NoProfile -NonInteractive -ExecutionPolicy Bypass -WindowStyle Hidden -File `"$hooksBase/run-hidden-hook.ps1`" `"$hooksBase/restart-brief.js`""; statusMessage = "Writing restart brief..." }
150
158
  )
151
159
  }
152
160
  )
161
+ $hooksConfig.Stop[0].hooks = @(
162
+ [PSCustomObject]@{ type = "command"; command = "powershell.exe -NoProfile -NonInteractive -ExecutionPolicy Bypass -WindowStyle Hidden -File `"$hooksBase/run-hidden-hook.ps1`" `"$hooksBase/rate-limit-retry.js`""; statusMessage = "Checking for rate limits..." }
163
+ ) + $hooksConfig.Stop[0].hooks + @(
164
+ [PSCustomObject]@{ type = "command"; command = "powershell.exe -NoProfile -NonInteractive -ExecutionPolicy Bypass -WindowStyle Hidden -File `"$hooksBase/run-hidden-hook.ps1`" `"$hooksBase/no-stop-open-epics.js`""; statusMessage = "Checking for open epics..." }
165
+ )
153
166
  }
154
167
 
155
168
  # Add/replace hooks key
@@ -163,6 +176,8 @@ if ($SkipHooks) {
163
176
  $settings | ConvertTo-Json -Depth 20 | Set-Content $settingsPath -Encoding UTF8
164
177
  Write-Host " [3/3] Hook wiring ✓ registered in $settingsPath" -ForegroundColor Green
165
178
  }
179
+ }
180
+ }
166
181
 
167
182
  # ── Summary ───────────────────────────────────────────────────────────────────
168
183
 
@@ -184,3 +199,4 @@ Write-Host " 4. Run /rdc:status in Claude Code to verify"
184
199
  Write-Host ""
185
200
  Write-Host " Docs: https://github.com/LIFEAI/rdc-skills#readme" -ForegroundColor Cyan
186
201
  Write-Host ""
202
+ }