@arcadialdev/arcality 2.4.23 → 2.4.25

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,185 +1,179 @@
1
- // src/configLoader.mjs
2
- // Configuration loader — supports arcality.config (primary) and .env / global config (fallback)
3
- import fs from 'node:fs';
4
- import path from 'node:path';
5
- import os from 'node:os';
6
- import dotenv from 'dotenv';
7
-
8
- dotenv.config();
9
-
10
- export const CONFIG_DIR = path.join(os.homedir(), '.arcality');
11
- export const CONFIG_FILE = path.join(CONFIG_DIR, 'config.json');
12
-
13
- /**
14
- * Returns the internal API URL for the Arcality backend.
15
- * This is loaded exclusively from the tool's .env file (via dotenv).
16
- * It is NOT configurable by the user, CLI flags, or arcality.config.
17
- * To change it, modify the ARCALITY_API_URL variable in the tool's .env.
18
- * @returns {string}
19
- */
20
- export function getApiUrl() {
21
- return process.env.ARCALITY_API_URL || 'https://arcalityqadev.arcadial.lat';
22
- }
23
-
24
- /**
25
- * Loads the local arcality.config file from cwd (if it exists).
26
- * @returns {object|null}
27
- */
28
- function loadLocalArcalityConfig() {
29
- try {
30
- const configPath = path.join(process.cwd(), 'arcality.config');
31
- if (fs.existsSync(configPath)) {
32
- let raw = fs.readFileSync(configPath, 'utf8');
33
- if (raw.charCodeAt(0) === 0xFEFF) raw = raw.slice(1);
34
- return JSON.parse(raw);
35
- }
36
- } catch { }
37
- return null;
38
- }
39
-
40
- /**
41
- * Loads configuration from multiple sources:
42
- * 1. arcality.config (local project config — highest priority)
43
- * 2. .env (environment variables)
44
- * 3. ~/.arcality/config.json (global config)
45
- *
46
- * NOTE: ARCALITY_API_URL is NOT included here — use getApiUrl() instead.
47
- *
48
- * @returns {{
49
- * ARCALITY_API_KEY: string,
50
- * ARCALITY_PROJECT_ID?: string
51
- * }}
52
- */
53
- export function loadConfig() {
54
- const localConfig = loadLocalArcalityConfig();
55
- const globalConfig = loadGlobalConfig();
56
-
57
- const config = {
58
- ARCALITY_API_KEY: localConfig?.apiKey || process.env.ARCALITY_API_KEY || globalConfig?.api_key,
59
- ARCALITY_PROJECT_ID: localConfig?.projectId || process.env.ARCALITY_PROJECT_ID,
60
- };
61
-
62
- if (!config.ARCALITY_API_KEY) {
63
- throw new Error('ARCALITY_API_KEY is not defined. Run `arcality init` or set it in your .env file.');
64
- }
65
-
66
- return config;
67
- }
68
-
69
-
70
- /**
71
- * Reads the user's global config (~/.arcality/config.json)
72
- * @returns {{ api_key?: string, install_dir?: string, version?: string } | null}
73
- */
74
- export function loadGlobalConfig() {
75
- try {
76
- if (fs.existsSync(CONFIG_FILE)) {
77
- let raw = fs.readFileSync(CONFIG_FILE, 'utf8');
78
- // Strip BOM that PowerShell adds with -Encoding UTF8
79
- if (raw.charCodeAt(0) === 0xFEFF) raw = raw.slice(1);
80
- return JSON.parse(raw);
81
- }
82
- } catch { }
83
- return null;
84
- }
85
-
86
- /**
87
- * Saves/updates the user's global config
88
- * @param {object} updates - Fields to update
89
- */
90
- export function saveGlobalConfig(updates) {
91
- try {
92
- if (!fs.existsSync(CONFIG_DIR)) {
93
- fs.mkdirSync(CONFIG_DIR, { recursive: true });
94
- }
95
- const existing = loadGlobalConfig() || {};
96
- const merged = { ...existing, ...updates };
97
- fs.writeFileSync(CONFIG_FILE, JSON.stringify(merged, null, 2), 'utf8');
98
- return true;
99
- } catch {
100
- return false;
101
- }
102
- }
103
-
104
- /**
105
- * Gets the API Key (priority: arcality.config > env var > global config)
106
- * @returns {{ key: string | null, source: 'config' | 'env' | 'global' | 'none' }}
107
- */
108
- export function getApiKey() {
109
- // 1. Local arcality.config
110
- const localConfig = loadLocalArcalityConfig();
111
- if (localConfig?.apiKey) {
112
- process.env.ARCALITY_API_KEY = localConfig.apiKey;
113
- return { key: localConfig.apiKey, source: 'config' };
114
- }
115
-
116
- // 2. Environment variable (.env or shell)
117
- if (process.env.ARCALITY_API_KEY) {
118
- return { key: process.env.ARCALITY_API_KEY, source: 'env' };
119
- }
120
-
121
- // 3. Global config ~/.arcality/config.json
122
- const globalCfg = loadGlobalConfig();
123
- if (globalCfg?.api_key) {
124
- process.env.ARCALITY_API_KEY = globalCfg.api_key;
125
- return { key: globalCfg.api_key, source: 'global' };
126
- }
127
-
128
- return { key: null, source: 'none' };
129
- }
130
-
131
- /**
132
- * Loads additional secrets (like Anthropic) from global config
133
- */
134
- export function setupProcessEnv() {
135
- const config = loadGlobalConfig();
136
- if (!config) return;
137
-
138
- // Load Arcality API Key
139
- getApiKey();
140
-
141
- // Load Anthropic API Key if not already in env
142
- if (config.anthropic_api_key && !process.env.ANTHROPIC_API_KEY) {
143
- process.env.ANTHROPIC_API_KEY = config.anthropic_api_key;
144
- }
145
-
146
- // Load default model if exists
147
- if (config.model && !process.env.CLAUDE_MODEL) {
148
- process.env.CLAUDE_MODEL = config.model;
149
- }
150
-
151
- // Also inject arcality.config values into process.env for backward compat
152
- const localConfig = loadLocalArcalityConfig();
153
- if (localConfig) {
154
- if (localConfig.apiKey && !process.env.ARCALITY_API_KEY) {
155
- process.env.ARCALITY_API_KEY = localConfig.apiKey;
156
- }
157
- if (localConfig.projectId && !process.env.ARCALITY_PROJECT_ID) {
158
- process.env.ARCALITY_PROJECT_ID = localConfig.projectId;
159
- }
160
- if (localConfig.project?.baseUrl && !process.env.BASE_URL) {
161
- process.env.BASE_URL = localConfig.project.baseUrl;
162
- }
163
- if (localConfig.auth?.username && !process.env.LOGIN_USER) {
164
- process.env.LOGIN_USER = localConfig.auth.username;
165
- }
166
- if (localConfig.auth?.password && !process.env.LOGIN_PASSWORD) {
167
- process.env.LOGIN_PASSWORD = localConfig.auth.password;
168
- }
169
- }
170
- // SIEMPRE garantizar que la URL interna de la API esté en process.env.
171
- // Esta URL es interna de la herramienta, no configurable por el usuario.
172
- // Proviene del .env de la librería o usa el valor por defecto.
173
- if (!process.env.ARCALITY_API_URL) {
174
- process.env.ARCALITY_API_URL = 'https://arcalityqadev.arcadial.lat';
175
- }
176
- }
177
-
178
- /**
179
- * Visual mask of API Key for banner display
180
- * "arc_k_live_abc123xyz" → "arc_k_****xyz"
181
- */
182
- export function maskApiKey(key) {
183
- if (!key || key.length < 8) return '***';
184
- return key.slice(0, 6) + '****' + key.slice(-4);
185
- }
1
+ // src/configLoader.mjs
2
+ // Configuration loader — supports arcality.config (primary) and .env / global config (fallback)
3
+ import fs from 'node:fs';
4
+ import path from 'node:path';
5
+ import os from 'node:os';
6
+ import dotenv from 'dotenv';
7
+
8
+ dotenv.config();
9
+
10
+ export const CONFIG_DIR = path.join(os.homedir(), '.arcality');
11
+ export const CONFIG_FILE = path.join(CONFIG_DIR, 'config.json');
12
+
13
+ /**
14
+ * Returns the internal API URL for the Arcality backend.
15
+ * This is loaded exclusively from the tool's .env file (via dotenv).
16
+ * It is NOT configurable by the user, CLI flags, or arcality.config.
17
+ * To change it, modify the ARCALITY_API_URL variable in the tool's .env.
18
+ * @returns {string}
19
+ */
20
+ export function getApiUrl() {
21
+ return process.env.ARCALITY_API_URL || 'https://arcalityqadev.arcadial.lat';
22
+ }
23
+
24
+ /**
25
+ * Loads the local arcality.config file from cwd (if it exists).
26
+ * @returns {object|null}
27
+ */
28
+ function loadLocalArcalityConfig() {
29
+ try {
30
+ const configPath = path.join(process.cwd(), 'arcality.config');
31
+ if (fs.existsSync(configPath)) {
32
+ let raw = fs.readFileSync(configPath, 'utf8');
33
+ if (raw.charCodeAt(0) === 0xFEFF) raw = raw.slice(1);
34
+ return JSON.parse(raw);
35
+ }
36
+ } catch { }
37
+ return null;
38
+ }
39
+
40
+ /**
41
+ * Loads configuration from multiple sources:
42
+ * 1. arcality.config (local project config — highest priority)
43
+ * 2. .env (environment variables)
44
+ * 3. ~/.arcality/config.json (global config)
45
+ *
46
+ * NOTE: ARCALITY_API_URL is NOT included here — use getApiUrl() instead.
47
+ *
48
+ * @returns {{
49
+ * ARCALITY_API_KEY: string,
50
+ * ARCALITY_PROJECT_ID?: string
51
+ * }}
52
+ */
53
+ export function loadConfig() {
54
+ const localConfig = loadLocalArcalityConfig();
55
+
56
+ const config = {
57
+ ARCALITY_API_KEY: localConfig?.apiKey || process.env.ARCALITY_API_KEY,
58
+ ARCALITY_PROJECT_ID: localConfig?.projectId || process.env.ARCALITY_PROJECT_ID,
59
+ };
60
+
61
+ if (!config.ARCALITY_API_KEY) {
62
+ throw new Error('ARCALITY_API_KEY is not defined. Run `arcality init` or set it in your .env file.');
63
+ }
64
+
65
+ return config;
66
+ }
67
+
68
+
69
+ /**
70
+ * Reads the user's global config (~/.arcality/config.json)
71
+ * @returns {{ api_key?: string, install_dir?: string, version?: string } | null}
72
+ */
73
+ export function loadGlobalConfig() {
74
+ try {
75
+ if (fs.existsSync(CONFIG_FILE)) {
76
+ let raw = fs.readFileSync(CONFIG_FILE, 'utf8');
77
+ // Strip BOM that PowerShell adds with -Encoding UTF8
78
+ if (raw.charCodeAt(0) === 0xFEFF) raw = raw.slice(1);
79
+ return JSON.parse(raw);
80
+ }
81
+ } catch { }
82
+ return null;
83
+ }
84
+
85
+ /**
86
+ * Saves/updates the user's global config
87
+ * @param {object} updates - Fields to update
88
+ */
89
+ export function saveGlobalConfig(updates) {
90
+ try {
91
+ if (!fs.existsSync(CONFIG_DIR)) {
92
+ fs.mkdirSync(CONFIG_DIR, { recursive: true });
93
+ }
94
+ const existing = loadGlobalConfig() || {};
95
+ const merged = { ...existing, ...updates };
96
+ fs.writeFileSync(CONFIG_FILE, JSON.stringify(merged, null, 2), 'utf8');
97
+ return true;
98
+ } catch {
99
+ return false;
100
+ }
101
+ }
102
+
103
+ /**
104
+ * Gets the API Key (priority: arcality.config > env var > global config)
105
+ * @returns {{ key: string | null, source: 'config' | 'env' | 'global' | 'none' }}
106
+ */
107
+ export function getApiKey() {
108
+ // 1. Local arcality.config
109
+ const localConfig = loadLocalArcalityConfig();
110
+ if (localConfig?.apiKey) {
111
+ process.env.ARCALITY_API_KEY = localConfig.apiKey;
112
+ return { key: localConfig.apiKey, source: 'config' };
113
+ }
114
+
115
+ // 2. Environment variable (.env or shell)
116
+ if (process.env.ARCALITY_API_KEY) {
117
+ return { key: process.env.ARCALITY_API_KEY, source: 'env' };
118
+ }
119
+
120
+ // Global config fallback removed strictly per project requirements
121
+
122
+ return { key: null, source: 'none' };
123
+ }
124
+
125
+ /**
126
+ * Loads additional secrets (like Anthropic) from global config
127
+ */
128
+ export function setupProcessEnv() {
129
+ const config = loadGlobalConfig();
130
+ if (!config) return;
131
+
132
+ // Load Arcality API Key
133
+ getApiKey();
134
+
135
+ // Load Anthropic API Key if not already in env
136
+ if (config.anthropic_api_key && !process.env.ANTHROPIC_API_KEY) {
137
+ process.env.ANTHROPIC_API_KEY = config.anthropic_api_key;
138
+ }
139
+
140
+ // Load default model if exists
141
+ if (config.model && !process.env.CLAUDE_MODEL) {
142
+ process.env.CLAUDE_MODEL = config.model;
143
+ }
144
+
145
+ // Also inject arcality.config values into process.env for backward compat
146
+ const localConfig = loadLocalArcalityConfig();
147
+ if (localConfig) {
148
+ if (localConfig.apiKey && !process.env.ARCALITY_API_KEY) {
149
+ process.env.ARCALITY_API_KEY = localConfig.apiKey;
150
+ }
151
+ if (localConfig.projectId && !process.env.ARCALITY_PROJECT_ID) {
152
+ process.env.ARCALITY_PROJECT_ID = localConfig.projectId;
153
+ }
154
+ if (localConfig.project?.baseUrl && !process.env.BASE_URL) {
155
+ process.env.BASE_URL = localConfig.project.baseUrl;
156
+ }
157
+ if (localConfig.auth?.username && !process.env.LOGIN_USER) {
158
+ process.env.LOGIN_USER = localConfig.auth.username;
159
+ }
160
+ if (localConfig.auth?.password && !process.env.LOGIN_PASSWORD) {
161
+ process.env.LOGIN_PASSWORD = localConfig.auth.password;
162
+ }
163
+ }
164
+ // SIEMPRE garantizar que la URL interna de la API esté en process.env.
165
+ // Esta URL es interna de la herramienta, no configurable por el usuario.
166
+ // Proviene del .env de la librería o usa el valor por defecto.
167
+ if (!process.env.ARCALITY_API_URL) {
168
+ process.env.ARCALITY_API_URL = 'https://arcalityqadev.arcadial.lat';
169
+ }
170
+ }
171
+
172
+ /**
173
+ * Visual mask of API Key for banner display
174
+ * "arc_k_live_abc123xyz" → "arc_k_****xyz"
175
+ */
176
+ export function maskApiKey(key) {
177
+ if (!key || key.length < 8) return '***';
178
+ return key.slice(0, 6) + '****' + key.slice(-4);
179
+ }