ai-agent-config 2.7.0 → 2.7.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ai-agent-config",
3
- "version": "2.7.0",
3
+ "version": "2.7.2",
4
4
  "description": "Universal skill & workflow manager for AI coding assistants with bi-directional GitHub sync",
5
5
  "main": "index.js",
6
6
  "bin": {
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Config Manager Module
3
- * Manages user configuration for ai-agent-config v2.3
3
+ * Manages user configuration for ai-agent-config
4
4
  */
5
5
 
6
6
  const fs = require("fs");
@@ -10,6 +10,7 @@ const os = require("os");
10
10
  const CONFIG_DIR = path.join(os.homedir(), ".ai-agent");
11
11
  const CONFIG_FILE = path.join(CONFIG_DIR, "config.json");
12
12
  const OFFICIAL_SOURCES = path.join(__dirname, "../config/official-sources.json");
13
+ const CONFIG_VERSION = require("../package.json").version;
13
14
 
14
15
  /**
15
16
  * Get user config path
@@ -49,7 +50,7 @@ function loadOfficialSources() {
49
50
  */
50
51
  function createDefaultConfig() {
51
52
  const config = {
52
- version: "2.3",
53
+ version: CONFIG_VERSION,
53
54
  repository: {
54
55
  url: null,
55
56
  branch: "main",
@@ -96,11 +97,11 @@ function initConfig(force = false) {
96
97
  }
97
98
 
98
99
  /**
99
- * Migrate config from older versions to v2.3
100
+ * Migrate config from older versions to current version
100
101
  */
101
102
  function migrateConfig(oldConfig) {
102
103
  const newConfig = {
103
- version: "2.3",
104
+ version: CONFIG_VERSION,
104
105
  repository: {
105
106
  url: oldConfig.repository?.url || null,
106
107
  branch: oldConfig.repository?.branch || "main",
@@ -137,9 +138,9 @@ function loadConfig() {
137
138
  const data = fs.readFileSync(CONFIG_FILE, "utf-8");
138
139
  let config = JSON.parse(data);
139
140
 
140
- // Auto-migrate from v2.0/v2.2 to v2.3
141
- if (config.version !== "2.3") {
142
- console.log(`šŸ”„ Migrating config from v${config.version} to v2.3...`);
141
+ // Auto-migrate from older versions
142
+ if (config.version !== CONFIG_VERSION) {
143
+ console.log(`šŸ”„ Migrating config from v${config.version} to v${CONFIG_VERSION}...`);
143
144
  config = migrateConfig(config);
144
145
  saveConfig(config);
145
146
  console.log("āœ… Config migrated successfully!");
@@ -188,10 +189,10 @@ function validateConfig(config) {
188
189
  }
189
190
  }
190
191
 
191
- // V2.3 validation
192
- if (config.version === "2.3") {
192
+ // Current version validation
193
+ if (config.version === CONFIG_VERSION) {
193
194
  if (!config.repository) {
194
- errors.push("Missing repository field in v2.3 config");
195
+ errors.push(`Missing repository field in v${CONFIG_VERSION} config`);
195
196
  } else {
196
197
  if (config.repository.url && typeof config.repository.url !== "string") {
197
198
  errors.push("repository.url must be a string");
@@ -167,6 +167,15 @@ function writeMcpToPlatformConfig(configPath, servers, options = {}) {
167
167
  fs.mkdirSync(configDir, { recursive: true });
168
168
  }
169
169
  fs.writeFileSync(configPath, JSON.stringify(config, null, 2) + "\n", "utf-8");
170
+ // Set restrictive permissions (owner read/write only) to protect secrets
171
+ // Only on Unix-like systems (macOS, Linux) - Windows uses ACL instead
172
+ if (process.platform !== "win32") {
173
+ try {
174
+ fs.chmodSync(configPath, 0o600);
175
+ } catch (e) {
176
+ console.warn(`āš ļø Warning: Could not set file permissions on ${configPath}: ${e.message}`);
177
+ }
178
+ }
170
179
  }
171
180
 
172
181
  return { added, skipped };
@@ -291,6 +300,15 @@ function writeMcpWithSecretsToPlatformConfig(configPath, servers, resolvedSecret
291
300
  fs.mkdirSync(configDir, { recursive: true });
292
301
  }
293
302
  fs.writeFileSync(configPath, JSON.stringify(config, null, 2) + "\n", "utf-8");
303
+ // Set restrictive permissions (owner read/write only) to protect secrets
304
+ // Only on Unix-like systems (macOS, Linux) - Windows uses ACL instead
305
+ if (process.platform !== "win32") {
306
+ try {
307
+ fs.chmodSync(configPath, 0o600);
308
+ } catch (e) {
309
+ console.warn(`āš ļø Warning: Could not set file permissions on ${configPath}: ${e.message}`);
310
+ }
311
+ }
294
312
  }
295
313
 
296
314
  return { installed, servers: serverResults };
@@ -7,6 +7,26 @@
7
7
 
8
8
  const platforms = require("./platforms");
9
9
 
10
+ // Bitwarden MCP: Tools to disable (org management, device approval, sends, etc.)
11
+ const BITWARDEN_DISABLED_TOOLS = [
12
+ "lock", "sync", "status", "confirm",
13
+ "create_org_collection", "edit_org_collection", "edit_item_collections", "move",
14
+ "device_approval_list", "device_approval_approve", "device_approval_approve_all",
15
+ "device_approval_deny", "device_approval_deny_all",
16
+ "create_text_send", "create_file_send", "list_send", "get_send",
17
+ "edit_send", "delete_send", "remove_send_password",
18
+ "create_attachment",
19
+ "list_org_collections", "get_org_collection", "update_org_collection", "delete_org_collection",
20
+ "list_org_members", "get_org_member", "get_org_member_groups",
21
+ "invite_org_member", "update_org_member", "update_org_member_groups",
22
+ "remove_org_member", "reinvite_org_member",
23
+ "list_org_groups", "get_org_group", "get_org_group_members",
24
+ "create_org_group", "update_org_group", "delete_org_group", "update_org_group_members",
25
+ "list_org_policies", "get_org_policy", "update_org_policy",
26
+ "get_org_events", "get_org_subscription", "update_org_subscription",
27
+ "import_org_users_and_groups"
28
+ ];
29
+
10
30
  function main() {
11
31
  console.log("\n╔═══════════════════════════════════════════════════════════════╗");
12
32
  console.log("ā•‘ AI Agent Config Installed! ā•‘");
@@ -39,6 +59,12 @@ function main() {
39
59
  console.log("šŸ“¦ Repository: https://github.com/dongitran/ai-agent-config\n");
40
60
 
41
61
  // Auto-install Bitwarden MCP server to Antigravity
62
+ // Skip if AI_AGENT_NO_AUTOCONFIG is set (opt-out for security/trust)
63
+ if (process.env.AI_AGENT_NO_AUTOCONFIG === "1" || process.env.AI_AGENT_NO_AUTOCONFIG === "true") {
64
+ console.log("ā­ļø Skipping auto-config (AI_AGENT_NO_AUTOCONFIG is set)\n");
65
+ return;
66
+ }
67
+
42
68
  const fs = require("fs");
43
69
  const path = require("path");
44
70
  const os = require("os");
@@ -73,24 +99,7 @@ function main() {
73
99
  BW_CLIENT_ID: "${BW_CLIENT_ID}",
74
100
  BW_CLIENT_SECRET: "${BW_CLIENT_SECRET}",
75
101
  },
76
- disabledTools: [
77
- "lock", "sync", "status", "confirm",
78
- "create_org_collection", "edit_org_collection", "edit_item_collections", "move",
79
- "device_approval_list", "device_approval_approve", "device_approval_approve_all",
80
- "device_approval_deny", "device_approval_deny_all",
81
- "create_text_send", "create_file_send", "list_send", "get_send",
82
- "edit_send", "delete_send", "remove_send_password",
83
- "create_attachment",
84
- "list_org_collections", "get_org_collection", "update_org_collection", "delete_org_collection",
85
- "list_org_members", "get_org_member", "get_org_member_groups",
86
- "invite_org_member", "update_org_member", "update_org_member_groups",
87
- "remove_org_member", "reinvite_org_member",
88
- "list_org_groups", "get_org_group", "get_org_group_members",
89
- "create_org_group", "update_org_group", "delete_org_group", "update_org_group_members",
90
- "list_org_policies", "get_org_policy", "update_org_policy",
91
- "get_org_events", "get_org_subscription", "update_org_subscription",
92
- "import_org_users_and_groups"
93
- ],
102
+ disabledTools: BITWARDEN_DISABLED_TOOLS,
94
103
  };
95
104
  changed = true;
96
105
  console.log("šŸ” Bitwarden MCP server added to Antigravity (āœ“ enabled)");
@@ -110,24 +119,7 @@ function main() {
110
119
 
111
120
  // Phase 4: Add disabledTools if not present (don't override if user customized)
112
121
  if (!bw.disabledTools) {
113
- bw.disabledTools = [
114
- "lock", "sync", "status", "confirm",
115
- "create_org_collection", "edit_org_collection", "edit_item_collections", "move",
116
- "device_approval_list", "device_approval_approve", "device_approval_approve_all",
117
- "device_approval_deny", "device_approval_deny_all",
118
- "create_text_send", "create_file_send", "list_send", "get_send",
119
- "edit_send", "delete_send", "remove_send_password",
120
- "create_attachment",
121
- "list_org_collections", "get_org_collection", "update_org_collection", "delete_org_collection",
122
- "list_org_members", "get_org_member", "get_org_member_groups",
123
- "invite_org_member", "update_org_member", "update_org_member_groups",
124
- "remove_org_member", "reinvite_org_member",
125
- "list_org_groups", "get_org_group", "get_org_group_members",
126
- "create_org_group", "update_org_group", "delete_org_group", "update_org_group_members",
127
- "list_org_policies", "get_org_policy", "update_org_policy",
128
- "get_org_events", "get_org_subscription", "update_org_subscription",
129
- "import_org_users_and_groups"
130
- ];
122
+ bw.disabledTools = BITWARDEN_DISABLED_TOOLS;
131
123
  changed = true;
132
124
  console.log("šŸŽ›ļø Bitwarden MCP: Added tool filters (disabled org-management tools)");
133
125
  }
@@ -124,13 +124,14 @@ async function promptPassword() {
124
124
  /**
125
125
  * Unlock Bitwarden vault with password
126
126
  * Returns session key or null if failed
127
- * Uses spawnSync to avoid shell injection
127
+ * Uses --passwordenv to pass password securely (not visible in process list)
128
128
  */
129
129
  function unlockBitwarden(password) {
130
130
  try {
131
- // Use positional password argument for compatibility with older Bitwarden CLI versions
132
- // Since we use spawnSync without shell: true, the password doesn't leak into shell history
133
- const result = spawnSync("bw", ["unlock", password, "--raw"], {
131
+ // Use --passwordenv to avoid leaking password in /proc/<pid>/cmdline
132
+ // Set password in env only for this child process
133
+ const result = spawnSync("bw", ["unlock", "--passwordenv", "BW_UNLOCK_PASSWORD", "--raw"], {
134
+ env: { ...process.env, BW_UNLOCK_PASSWORD: password },
134
135
  encoding: "utf-8",
135
136
  });
136
137