create-universal-ai-context 2.2.0 → 2.2.2

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/README.md CHANGED
@@ -97,6 +97,67 @@ npx create-universal-ai-context hooks:install
97
97
  - `newest` - Most recently modified wins
98
98
  - `manual` - Require manual resolution
99
99
 
100
+ ## Automation Scripts
101
+
102
+ The generated `.ai-context/` directory includes automation that keeps documentation synchronized:
103
+
104
+ ### Generators
105
+
106
+ **Code Mapper** (`.ai-context/automation/generators/code-mapper.js`)
107
+ - Scans workflow files for file:line references
108
+ - Builds CODE_TO_WORKFLOW_MAP.md (reverse index of code → docs)
109
+ - Shows which workflows reference each file
110
+ - Helps identify what needs updating after code changes
111
+
112
+ **Index Builder** (`.ai-context/automation/generators/index-builder.js`)
113
+ - Regenerates category indexes automatically
114
+ - Updates navigation indexes with accurate counts
115
+ - Scans workflows, agents, and commands for metadata
116
+
117
+ ### Git Hooks
118
+
119
+ **Pre-Commit Hook**
120
+ - Validates before allowing commits
121
+ - Warns if code changes might affect documentation
122
+ - Optionally blocks commits if docs are stale
123
+
124
+ **Post-Commit Hook**
125
+ - Rebuilds CODE_TO_WORKFLOW_MAP.md in background
126
+ - Updates file hashes for change tracking
127
+ - Keeps indexes synchronized
128
+
129
+ ### Install Hooks
130
+
131
+ ```bash
132
+ # Copy hooks to .git/hooks/
133
+ cp .ai-context/automation/hooks/pre-commit.sh .git/hooks/pre-commit
134
+ cp .ai-context/automation/hooks/post-commit.sh .git/hooks/post-commit
135
+ chmod +x .git/hooks/pre-commit .git/hooks/post-commit
136
+ ```
137
+
138
+ ### Run Manually
139
+
140
+ ```bash
141
+ # Regenerate code-to-workflow map
142
+ node .ai-context/automation/generators/code-mapper.js
143
+
144
+ # Rebuild all indexes
145
+ node .ai-context/automation/generators/index-builder.js
146
+
147
+ # Dry-run to preview
148
+ node .ai-context/automation/generators/code-mapper.js --dry-run
149
+ ```
150
+
151
+ ### Configuration
152
+
153
+ Control automation via `.ai-context/automation/config.json`:
154
+ - Enable/disable generators
155
+ - Configure hook behavior
156
+ - Set drift check sensitivity
157
+ - Toggle blocking on stale documentation
158
+
159
+ ---
160
+
100
161
  ## Existing Documentation Detection
101
162
 
102
163
  The CLI automatically detects existing AI context files:
@@ -745,15 +745,9 @@ program
745
745
  .action(async () => {
746
746
  console.log(banner);
747
747
 
748
- const installScript = path.join(__dirname, '..', '.claude', 'automation', 'hooks', 'install.js');
749
-
750
- if (!fs.existsSync(installScript)) {
751
- console.error(chalk.red('\n✖ Error: Install script not found'));
752
- process.exit(1);
753
- }
754
-
755
748
  try {
756
- require(installScript);
749
+ const { installHooks } = require('../lib/install-hooks');
750
+ installHooks();
757
751
  } catch (error) {
758
752
  console.error(chalk.red('\n✖ Error:'), error.message);
759
753
  process.exit(1);
@@ -9,7 +9,7 @@ const fs = require('fs');
9
9
  const path = require('path');
10
10
  const crypto = require('crypto');
11
11
  const { getAdapter, getAllAdapters, getAdapterNames } = require('../adapters');
12
- const { analyzeProject } = require('../static-analyzer');
12
+ const { analyzeCodebase } = require('../static-analyzer');
13
13
  const { generateAll, initialize: initGenerator } = require('../ai-context-generator');
14
14
 
15
15
  /**
@@ -221,7 +221,7 @@ async function propagateContextChange(sourceTool, projectRoot, config, strategy
221
221
  // 1. Re-analyze codebase to get fresh analysis
222
222
  let analysis;
223
223
  try {
224
- analysis = await analyzeProject(projectRoot, config);
224
+ analysis = await analyzeCodebase(projectRoot, config);
225
225
  } catch (error) {
226
226
  results.errors.push({
227
227
  message: `Failed to analyze project: ${error.message}`
@@ -328,7 +328,7 @@ async function syncAllFromCodebase(projectRoot, config) {
328
328
 
329
329
  try {
330
330
  // Analyze project
331
- const analysis = await analyzeProject(projectRoot, config);
331
+ const analysis = await analyzeCodebase(projectRoot, config);
332
332
 
333
333
  // Generate for all tools
334
334
  const generateResults = await generateAll(analysis, config, projectRoot, {
@@ -0,0 +1,82 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Install Git Hooks for AI Context Sync
4
+ *
5
+ * Usage: Called via `npx create-ai-context hooks:install`
6
+ */
7
+
8
+ const fs = require('fs');
9
+ const path = require('path');
10
+
11
+ function installHooks(projectRoot = process.cwd()) {
12
+ const hooksDir = path.join(__dirname, '..', 'templates', 'hooks');
13
+ const gitHooksDir = path.join(projectRoot, '.git', 'hooks');
14
+
15
+ // Hooks to install
16
+ const hooks = [
17
+ { source: 'pre-commit.hbs', target: 'pre-commit' },
18
+ { source: 'post-commit.hbs', target: 'post-commit' }
19
+ ];
20
+
21
+ function ensureDirectory(dir) {
22
+ if (!fs.existsSync(dir)) {
23
+ fs.mkdirSync(dir, { recursive: true });
24
+ }
25
+ }
26
+
27
+ function copyHook(sourceFile, targetFile) {
28
+ const sourcePath = path.join(hooksDir, sourceFile);
29
+ const targetPath = path.join(gitHooksDir, targetFile);
30
+
31
+ if (!fs.existsSync(sourcePath)) {
32
+ console.warn(`Warning: ${sourceFile} not found, skipping`);
33
+ return false;
34
+ }
35
+
36
+ const content = fs.readFileSync(sourcePath, 'utf-8');
37
+
38
+ fs.writeFileSync(targetPath, content, { mode: 0o755 });
39
+ console.log(`✓ Installed ${targetFile}`);
40
+ return true;
41
+ }
42
+
43
+ console.log('\nInstalling AI context sync git hooks...\n');
44
+
45
+ // Check if we're in a git repository
46
+ if (!fs.existsSync(gitHooksDir)) {
47
+ console.error('Error: .git/hooks directory not found');
48
+ console.error('Please run this command from the root of a git repository\n');
49
+ throw new Error('Not a git repository');
50
+ }
51
+
52
+ // Ensure hooks directory exists
53
+ ensureDirectory(gitHooksDir);
54
+
55
+ // Copy hooks
56
+ let installed = 0;
57
+ for (const hook of hooks) {
58
+ if (copyHook(hook.source, hook.target)) {
59
+ installed++;
60
+ }
61
+ }
62
+
63
+ console.log(`\nSuccessfully installed ${installed} git hooks\n`);
64
+ console.log('The hooks will:');
65
+ console.log(' • Check sync status before commits (pre-commit)');
66
+ console.log(' • Auto-sync after successful commits (post-commit)\n');
67
+ console.log('To skip sync checks, use: git commit --no-verify\n');
68
+
69
+ return { installed, total: hooks.length };
70
+ }
71
+
72
+ module.exports = { installHooks };
73
+
74
+ // If run directly
75
+ if (require.main === module) {
76
+ try {
77
+ installHooks();
78
+ } catch (error) {
79
+ console.error('\n✖ Installation failed:', error.message);
80
+ process.exit(1);
81
+ }
82
+ }
package/lib/migrate.js CHANGED
@@ -274,6 +274,11 @@ async function migrateV1ToV2(projectRoot, options = {}) {
274
274
  function getMigrationStatus(projectRoot) {
275
275
  const detection = detectV1Installation(projectRoot);
276
276
 
277
+ // In v2.0, both .ai-context/ AND .claude/ can exist
278
+ // The presence of AI_CONTEXT.md indicates v2.0 installation
279
+ // .claude/ in v2.0 is created by the Claude adapter for Claude-specific features
280
+ const hasAiContextMd = fs.existsSync(path.join(projectRoot, MIGRATIONS.entryFile.new));
281
+
277
282
  if (!detection.hasV1 && !detection.hasV2) {
278
283
  return {
279
284
  status: 'none',
@@ -282,24 +287,28 @@ function getMigrationStatus(projectRoot) {
282
287
  };
283
288
  }
284
289
 
285
- if (detection.hasV1 && !detection.hasV2) {
290
+ // If AI_CONTEXT.md exists, this is v2.0 (even if .claude/ also exists)
291
+ if (hasAiContextMd) {
286
292
  return {
287
- status: 'v1',
288
- message: 'v1.x installation found, migration available',
289
- needsMigration: true,
293
+ status: 'v2',
294
+ message: 'v2.0 installation found, no migration needed',
295
+ needsMigration: false,
290
296
  details: detection
291
297
  };
292
298
  }
293
299
 
294
- if (!detection.hasV1 && detection.hasV2) {
300
+ // If .claude/ exists but no AI_CONTEXT.md, this is v1.x
301
+ if (detection.hasV1 && !detection.hasV2) {
295
302
  return {
296
- status: 'v2',
297
- message: 'v2.0 installation found, no migration needed',
298
- needsMigration: false,
303
+ status: 'v1',
304
+ message: 'v1.x installation found, migration available',
305
+ needsMigration: true,
299
306
  details: detection
300
307
  };
301
308
  }
302
309
 
310
+ // True mixed state: both v1.x indicators and v2.0 indicators exist
311
+ // This shouldn't happen normally, but handle it
303
312
  if (detection.hasV1 && detection.hasV2) {
304
313
  return {
305
314
  status: 'mixed',
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-universal-ai-context",
3
- "version": "2.2.0",
3
+ "version": "2.2.2",
4
4
  "description": "Universal AI Context Engineering - Set up context for Claude, Copilot, Cline, Antigravity, and more",
5
5
  "main": "lib/index.js",
6
6
  "bin": {
@@ -0,0 +1,29 @@
1
+ #!/bin/bash
2
+ # Post-commit hook for AI context sync
3
+ # This hook triggers sync after successful commits
4
+
5
+ # Don't block commit if this fails
6
+ set +e
7
+
8
+ # Check if ai-context binary is available
9
+ if ! command -v create-ai-context &> /dev/null; then
10
+ # Try npx
11
+ if command -v npx &> /dev/null; then
12
+ AI_CONTEXT_CMD="npx create-universal-ai-context"
13
+ else
14
+ exit 0
15
+ fi
16
+ else
17
+ AI_CONTEXT_CMD="create-ai-context"
18
+ fi
19
+
20
+ # Run background sync (async)
21
+ echo "Syncing AI contexts in background..."
22
+
23
+ # Use subshell to run in background
24
+ (
25
+ sleep 2 # Wait a bit to not interfere with commit
26
+ $AI_CONTEXT_CMD sync:all --quiet > /dev/null 2>&1
27
+ ) &
28
+
29
+ exit 0
@@ -0,0 +1,46 @@
1
+ #!/bin/bash
2
+ # Pre-commit hook for AI context sync
3
+ # This hook checks if AI tool contexts are out of sync
4
+
5
+ set -e
6
+
7
+ # Colors for output
8
+ RED='\033[0;31m'
9
+ YELLOW='\033[1;33m'
10
+ GREEN='\033[0;32m'
11
+ NC='\033[0m' # No Color
12
+
13
+ # Check if ai-context binary is available
14
+ if ! command -v create-ai-context &> /dev/null; then
15
+ # Try npx
16
+ if command -v npx &> /dev/null; then
17
+ AI_CONTEXT_CMD="npx create-universal-ai-context"
18
+ else
19
+ echo -e "${YELLOW}Warning: create-ai-context not found. Skipping sync check.${NC}"
20
+ exit 0
21
+ fi
22
+ else
23
+ AI_CONTEXT_CMD="create-ai-context"
24
+ fi
25
+
26
+ # Run sync check
27
+ echo -e "${GREEN}Checking AI context sync status...${NC}"
28
+
29
+ # Check for out-of-sync contexts
30
+ CHECK_OUTPUT=$($AI_CONTEXT_CMD sync:check 2>&1)
31
+ CHECK_EXIT_CODE=$?
32
+
33
+ if [ $CHECK_EXIT_CODE -ne 0 ]; then
34
+ echo -e "${RED}AI contexts are out of sync!${NC}"
35
+ echo ""
36
+ echo "$CHECK_OUTPUT"
37
+ echo ""
38
+ echo -e "${YELLOW}To sync all contexts, run:${NC}"
39
+ echo " $AI_CONTEXT_CMD sync:all"
40
+ echo ""
41
+ echo -e "${YELLOW}To skip this check, use: git commit --no-verify${NC}"
42
+ exit 1
43
+ fi
44
+
45
+ echo -e "${GREEN}AI contexts are in sync${NC}"
46
+ exit 0