@plinng/ai-code-assistant-tools 1.0.1 → 1.0.3

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
@@ -13,7 +13,7 @@ These are **not** linter rules. ESLint, Prettier, Ruff, and Biome handle
13
13
  formatting and style deterministically at zero LLM token cost. These rules
14
14
  encode the decisions that static analysis has no reach into:
15
15
 
16
- - Which layer is responsible for what
16
+ - Which layer is responsible for what.
17
17
  - When and how to handle errors.
18
18
  - Which design patterns to prefer and why.
19
19
  - SOLID principles and how to apply them in this codebase.
package/bin/install.js ADDED
@@ -0,0 +1,145 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
4
+ if (k2 === undefined) k2 = k;
5
+ var desc = Object.getOwnPropertyDescriptor(m, k);
6
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
7
+ desc = { enumerable: true, get: function() { return m[k]; } };
8
+ }
9
+ Object.defineProperty(o, k2, desc);
10
+ }) : (function(o, m, k, k2) {
11
+ if (k2 === undefined) k2 = k;
12
+ o[k2] = m[k];
13
+ }));
14
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
15
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
16
+ }) : function(o, v) {
17
+ o["default"] = v;
18
+ });
19
+ var __importStar = (this && this.__importStar) || (function () {
20
+ var ownKeys = function(o) {
21
+ ownKeys = Object.getOwnPropertyNames || function (o) {
22
+ var ar = [];
23
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
24
+ return ar;
25
+ };
26
+ return ownKeys(o);
27
+ };
28
+ return function (mod) {
29
+ if (mod && mod.__esModule) return mod;
30
+ var result = {};
31
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
32
+ __setModuleDefault(result, mod);
33
+ return result;
34
+ };
35
+ })();
36
+ Object.defineProperty(exports, "__esModule", { value: true });
37
+ const fs = __importStar(require("fs"));
38
+ const os = __importStar(require("os"));
39
+ const path = __importStar(require("path"));
40
+ const readline = __importStar(require("readline"));
41
+ const PKG_ROOT = path.resolve(__dirname, '..');
42
+ function ensureDir(dir) {
43
+ fs.mkdirSync(dir, { recursive: true });
44
+ }
45
+ function backupAndCopy(src, dest) {
46
+ if (fs.existsSync(dest)) {
47
+ const backup = `${dest}.backup-${Date.now()}`;
48
+ fs.copyFileSync(dest, backup);
49
+ console.log(` Backed up: ${dest} → ${backup}`);
50
+ }
51
+ fs.copyFileSync(src, dest);
52
+ console.log(` Installed: ${dest}`);
53
+ }
54
+ function copyDir(srcDir, destDir) {
55
+ ensureDir(destDir);
56
+ const entries = fs.readdirSync(srcDir, { withFileTypes: true });
57
+ for (const entry of entries) {
58
+ const srcPath = path.join(srcDir, entry.name);
59
+ const destPath = path.join(destDir, entry.name);
60
+ if (entry.isDirectory()) {
61
+ copyDir(srcPath, destPath);
62
+ }
63
+ else {
64
+ backupAndCopy(srcPath, destPath);
65
+ }
66
+ }
67
+ }
68
+ function installClaudeCode() {
69
+ console.log('\nInstalling Claude Code rules...');
70
+ const claudeDir = path.join(os.homedir(), '.claude');
71
+ const rulesDir = path.join(claudeDir, 'rules');
72
+ ensureDir(claudeDir);
73
+ ensureDir(rulesDir);
74
+ const srcClaudeMd = path.join(PKG_ROOT, 'claude-code', 'CLAUDE.md');
75
+ const destClaudeMd = path.join(claudeDir, 'CLAUDE.md');
76
+ backupAndCopy(srcClaudeMd, destClaudeMd);
77
+ const srcRulesDir = path.join(PKG_ROOT, 'claude-code', 'rules');
78
+ copyDir(srcRulesDir, rulesDir);
79
+ console.log('\nClaude Code rules installed successfully.');
80
+ console.log(` Root: ${destClaudeMd}`);
81
+ console.log(` Rules: ${rulesDir}/`);
82
+ }
83
+ function installCursorProject() {
84
+ const destDir = path.join(process.cwd(), '.cursor', 'rules');
85
+ console.log(`\nInstalling Cursor rules to project scope: ${destDir}`);
86
+ const srcDir = path.join(PKG_ROOT, 'cursor', 'rules');
87
+ copyDir(srcDir, destDir);
88
+ console.log('\nCursor project-scope rules installed successfully.');
89
+ }
90
+ function installCursorUser() {
91
+ const destDir = path.join(os.homedir(), '.cursor', 'rules');
92
+ console.log(`\nInstalling Cursor rules to user scope: ${destDir}`);
93
+ console.log(' Note: Cursor reads user rules from its Settings UI, not from this directory.\n' +
94
+ ' Project-scope (.cursor/rules/) is the reliably enforced path for teams\n' +
95
+ ' without Cursor Team/Enterprise plan. This copies files as a sync source.\n');
96
+ const srcDir = path.join(PKG_ROOT, 'cursor', 'rules');
97
+ copyDir(srcDir, destDir);
98
+ console.log('\nCursor user-scope rules installed to ~/.cursor/rules/');
99
+ }
100
+ function prompt(rl, question) {
101
+ return new Promise((resolve) => rl.question(question, resolve));
102
+ }
103
+ async function main() {
104
+ const platform = os.platform();
105
+ console.log(`\nPlinng AI Code Assistant Tools — Installer`);
106
+ console.log(`Platform: ${platform}\n`);
107
+ const rl = readline.createInterface({
108
+ input: process.stdin,
109
+ output: process.stdout,
110
+ });
111
+ try {
112
+ const assistantAnswer = await prompt(rl, 'Which AI assistant do you use?\n 1) Claude Code\n 2) Cursor\n 3) Both\nEnter 1, 2, or 3: ');
113
+ const installClaude = assistantAnswer.trim() === '1' || assistantAnswer.trim() === '3';
114
+ const installCursor = assistantAnswer.trim() === '2' || assistantAnswer.trim() === '3';
115
+ if (!installClaude && !installCursor) {
116
+ console.error('\nInvalid selection. Please run the installer again and enter 1, 2, or 3.');
117
+ process.exit(1);
118
+ }
119
+ if (installClaude) {
120
+ installClaudeCode();
121
+ }
122
+ if (installCursor) {
123
+ const scopeAnswer = await prompt(rl, '\nInstall Cursor rules at which scope?\n 1) Project scope (.cursor/rules/ in current directory) [recommended for teams]\n 2) User scope (~/.cursor/rules/)\n 3) Both\nEnter 1, 2, or 3: ');
124
+ const doProject = scopeAnswer.trim() === '1' || scopeAnswer.trim() === '3';
125
+ const doUser = scopeAnswer.trim() === '2' || scopeAnswer.trim() === '3';
126
+ if (!doProject && !doUser) {
127
+ console.error('\nInvalid selection. Please run the installer again.');
128
+ process.exit(1);
129
+ }
130
+ if (doProject)
131
+ installCursorProject();
132
+ if (doUser)
133
+ installCursorUser();
134
+ }
135
+ console.log('\nInstallation complete.');
136
+ }
137
+ catch (err) {
138
+ console.error('\nInstallation failed:', err);
139
+ process.exit(1);
140
+ }
141
+ finally {
142
+ rl.close();
143
+ }
144
+ }
145
+ main();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@plinng/ai-code-assistant-tools",
3
- "version": "1.0.1",
3
+ "version": "1.0.3",
4
4
  "description": "CLI installer for Plinng platform AI coding standards",
5
5
  "bin": {
6
6
  "ai-code-assistant-tools": "./bin/install.js"