@fermindi/pwn-cli 0.1.0 → 0.1.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/cli/inject.js CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import { existsSync, readFileSync } from 'fs';
3
3
  import { join } from 'path';
4
- import { inject } from '../src/core/inject.js';
4
+ import { inject, detectKnownAIFiles } from '../src/core/inject.js';
5
5
 
6
6
  export default async function injectCommand(args = []) {
7
7
  const force = args.includes('--force') || args.includes('-f');
@@ -10,6 +10,20 @@ export default async function injectCommand(args = []) {
10
10
 
11
11
  const result = await inject({ force });
12
12
 
13
+ // Show detected AI files (before success/failure message)
14
+ if (result.detected && result.detected.length > 0) {
15
+ console.log('⚠️ Detected existing AI instruction files:\n');
16
+ for (const file of result.detected) {
17
+ console.log(` 📄 ${file.file}`);
18
+ console.log(` Type: ${file.type} - ${file.description}`);
19
+ }
20
+ console.log('\n 💡 Consider migrating content to .ai/ structure:');
21
+ console.log(' - Instructions → .ai/agents/claude.md');
22
+ console.log(' - Decisions → .ai/memory/decisions.md');
23
+ console.log(' - Patterns → .ai/memory/patterns.md');
24
+ console.log(' - Tasks → .ai/tasks/active.md\n');
25
+ }
26
+
13
27
  if (!result.success) {
14
28
  if (result.error === 'ALREADY_EXISTS') {
15
29
  console.log('❌ .ai/ directory already exists in this project');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fermindi/pwn-cli",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "Professional AI Workspace - Inject structured memory and automation into any project for AI-powered development",
5
5
  "type": "module",
6
6
  "bin": {
@@ -1,4 +1,4 @@
1
- import { existsSync, cpSync, renameSync, readFileSync, appendFileSync, writeFileSync } from 'fs';
1
+ import { existsSync, cpSync, renameSync, readFileSync, appendFileSync, writeFileSync, readdirSync } from 'fs';
2
2
  import { join, dirname } from 'path';
3
3
  import { fileURLToPath } from 'url';
4
4
  import { randomUUID } from 'crypto';
@@ -6,6 +6,74 @@ import { initState } from './state.js';
6
6
 
7
7
  const __dirname = dirname(fileURLToPath(import.meta.url));
8
8
 
9
+ /**
10
+ * Known AI instruction files in the industry
11
+ * PWN should detect these and warn/offer migration
12
+ */
13
+ export const KNOWN_AI_FILES = [
14
+ // Claude Code
15
+ { pattern: 'CLAUDE.md', type: 'claude', description: 'Claude Code instructions' },
16
+ { pattern: 'claude.md', type: 'claude', description: 'Claude Code instructions' },
17
+ { pattern: '.claude', type: 'claude', description: 'Claude config directory' },
18
+
19
+ // Cursor
20
+ { pattern: '.cursorrules', type: 'cursor', description: 'Cursor AI rules' },
21
+ { pattern: '.cursorignore', type: 'cursor', description: 'Cursor ignore file' },
22
+
23
+ // GitHub Copilot
24
+ { pattern: '.github/copilot-instructions.md', type: 'copilot', description: 'GitHub Copilot instructions' },
25
+
26
+ // Session files (common pattern)
27
+ { pattern: 'session.*.md', type: 'session', description: 'Session file (legacy pattern)' },
28
+
29
+ // Other AI tools
30
+ { pattern: '.aider', type: 'aider', description: 'Aider AI config' },
31
+ { pattern: '.continue', type: 'continue', description: 'Continue AI config' },
32
+ { pattern: '.codeium', type: 'codeium', description: 'Codeium config' },
33
+ ];
34
+
35
+ /**
36
+ * Detect known AI instruction files in a directory
37
+ * @param {string} cwd - Directory to scan
38
+ * @returns {Object[]} Array of detected files with metadata
39
+ */
40
+ export function detectKnownAIFiles(cwd = process.cwd()) {
41
+ const detected = [];
42
+
43
+ for (const known of KNOWN_AI_FILES) {
44
+ // Handle glob patterns like session.*.md
45
+ if (known.pattern.includes('*')) {
46
+ const regex = new RegExp('^' + known.pattern.replace('.', '\\.').replace('*', '.*') + '$');
47
+ try {
48
+ const files = readdirSync(cwd);
49
+ for (const file of files) {
50
+ if (regex.test(file)) {
51
+ detected.push({
52
+ ...known,
53
+ file,
54
+ path: join(cwd, file)
55
+ });
56
+ }
57
+ }
58
+ } catch {
59
+ // Ignore read errors
60
+ }
61
+ } else {
62
+ // Direct file check
63
+ const filePath = join(cwd, known.pattern);
64
+ if (existsSync(filePath)) {
65
+ detected.push({
66
+ ...known,
67
+ file: known.pattern,
68
+ path: filePath
69
+ });
70
+ }
71
+ }
72
+ }
73
+
74
+ return detected;
75
+ }
76
+
9
77
  /**
10
78
  * Get the path to the workspace template
11
79
  * @returns {string} Path to template directory
@@ -20,13 +88,15 @@ export function getTemplatePath() {
20
88
  * @param {string} options.cwd - Target directory (defaults to process.cwd())
21
89
  * @param {boolean} options.force - Force overwrite existing .ai/ directory
22
90
  * @param {boolean} options.silent - Suppress console output
91
+ * @param {boolean} options.skipDetection - Skip detection of known AI files
23
92
  * @returns {object} Result with success status and message
24
93
  */
25
94
  export async function inject(options = {}) {
26
95
  const {
27
96
  cwd = process.cwd(),
28
97
  force = false,
29
- silent = false
98
+ silent = false,
99
+ skipDetection = false
30
100
  } = options;
31
101
 
32
102
  const templateDir = getTemplatePath();
@@ -34,12 +104,16 @@ export async function inject(options = {}) {
34
104
 
35
105
  const log = silent ? () => {} : console.log;
36
106
 
107
+ // Detect known AI instruction files
108
+ const detectedFiles = skipDetection ? [] : detectKnownAIFiles(cwd);
109
+
37
110
  // Check if .ai/ already exists
38
111
  if (existsSync(targetDir) && !force) {
39
112
  return {
40
113
  success: false,
41
114
  error: 'ALREADY_EXISTS',
42
- message: '.ai/ directory already exists. Use --force to overwrite.'
115
+ message: '.ai/ directory already exists. Use --force to overwrite.',
116
+ detected: detectedFiles
43
117
  };
44
118
  }
45
119
 
@@ -74,14 +148,16 @@ export async function inject(options = {}) {
74
148
  return {
75
149
  success: true,
76
150
  message: 'PWN workspace injected successfully',
77
- path: targetDir
151
+ path: targetDir,
152
+ detected: detectedFiles
78
153
  };
79
154
 
80
155
  } catch (error) {
81
156
  return {
82
157
  success: false,
83
158
  error: 'INJECTION_FAILED',
84
- message: error.message
159
+ message: error.message,
160
+ detected: detectedFiles
85
161
  };
86
162
  }
87
163
  }
package/src/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  // PWN Core - Main exports
2
- export { inject } from './core/inject.js';
2
+ export { inject, detectKnownAIFiles, KNOWN_AI_FILES } from './core/inject.js';
3
3
  export { getState, updateState, initState } from './core/state.js';
4
4
  export { validate } from './core/validate.js';
5
5
  export { getWorkspaceInfo } from './core/workspace.js';