iranti 0.1.1 → 0.1.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 +7 -7
- package/dist/scripts/claude-code-memory-hook.js +162 -45
- package/dist/scripts/codex-setup.js +102 -13
- package/dist/scripts/iranti-cli.js +67 -1
- package/dist/scripts/iranti-mcp.js +8 -26
- package/dist/scripts/seed.js +10 -10
- package/dist/src/api/server.js +1 -1
- package/dist/src/lib/runtimeEnv.d.ts +15 -0
- package/dist/src/lib/runtimeEnv.d.ts.map +1 -0
- package/dist/src/lib/runtimeEnv.js +91 -0
- package/dist/src/lib/runtimeEnv.js.map +1 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -178,24 +178,24 @@ Release guide: [`docs/guides/releasing.md`](docs/guides/releasing.md)
|
|
|
178
178
|
Iranti ships a local stdio MCP server for Claude Code and other MCP clients:
|
|
179
179
|
|
|
180
180
|
```bash
|
|
181
|
-
|
|
182
|
-
node dist/scripts/iranti-mcp.js
|
|
181
|
+
iranti mcp
|
|
183
182
|
```
|
|
184
183
|
|
|
185
|
-
Use it with a project-local `.mcp.json`, and optionally add
|
|
184
|
+
Use it with a project-local `.mcp.json`, and optionally add `iranti claude-hook` for `SessionStart` and `UserPromptSubmit`.
|
|
186
185
|
|
|
187
186
|
Guide: [`docs/guides/claude-code.md`](docs/guides/claude-code.md)
|
|
188
187
|
|
|
189
188
|
### Codex via MCP
|
|
190
189
|
|
|
191
|
-
Codex uses a global MCP registry rather than a project-local `.mcp.json`. Register Iranti once, then launch Codex in
|
|
190
|
+
Codex uses a global MCP registry rather than a project-local `.mcp.json`. Register Iranti once, then launch Codex in the bound project so `.env.iranti` is in scope:
|
|
192
191
|
|
|
193
192
|
```bash
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
npm run codex:run
|
|
193
|
+
iranti codex-setup
|
|
194
|
+
codex -C /path/to/your/project
|
|
197
195
|
```
|
|
198
196
|
|
|
197
|
+
When `iranti codex-setup` is run from a project directory, it automatically captures that project's `.env.iranti` as `IRANTI_PROJECT_ENV` so Codex resolves the correct Iranti instance consistently.
|
|
198
|
+
|
|
199
199
|
Guide: [`docs/guides/codex.md`](docs/guides/codex.md)
|
|
200
200
|
|
|
201
201
|
---
|
|
@@ -6,6 +6,21 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
6
6
|
require("dotenv/config");
|
|
7
7
|
const path_1 = __importDefault(require("path"));
|
|
8
8
|
const sdk_1 = require("../src/sdk");
|
|
9
|
+
const runtimeEnv_1 = require("../src/lib/runtimeEnv");
|
|
10
|
+
const MEMORY_NEED_POSITIVE_PATTERNS = [
|
|
11
|
+
/\bwhat(?:'s| is| was)?\s+my\b/i,
|
|
12
|
+
/\bdo you remember\b/i,
|
|
13
|
+
/\bremind me\b/i,
|
|
14
|
+
/\bmy\s+(?:favorite|favourite|name|email|phone|address|city|country|movie|snack|color|colour)\b/i,
|
|
15
|
+
/\bwe decided\b/i,
|
|
16
|
+
/\bearlier\b/i,
|
|
17
|
+
/\bprevious(?:ly)?\b/i,
|
|
18
|
+
/\bagain\b/i,
|
|
19
|
+
];
|
|
20
|
+
const MEMORY_NEED_NEGATIVE_PATTERNS = [
|
|
21
|
+
/^\s*(hi|hello|hey|yo|sup|good (?:morning|afternoon|evening))\b[!.?\s]*$/i,
|
|
22
|
+
/^\s*(thanks|thank you|cool|great|nice)\b[!.?\s]*$/i,
|
|
23
|
+
];
|
|
9
24
|
function printHelp() {
|
|
10
25
|
console.log([
|
|
11
26
|
'Claude Code -> Iranti hook helper',
|
|
@@ -14,6 +29,11 @@ function printHelp() {
|
|
|
14
29
|
' ts-node scripts/claude-code-memory-hook.ts --event SessionStart',
|
|
15
30
|
' ts-node scripts/claude-code-memory-hook.ts --event UserPromptSubmit',
|
|
16
31
|
'',
|
|
32
|
+
'Optional flags:',
|
|
33
|
+
' --project-env <path> Explicit .env.iranti path',
|
|
34
|
+
' --instance-env <path> Explicit instance env path',
|
|
35
|
+
' --env-file <path> Explicit base .env path',
|
|
36
|
+
'',
|
|
17
37
|
'Reads Claude Code hook JSON from stdin and returns hookSpecificOutput.additionalContext on stdout.',
|
|
18
38
|
].join('\n'));
|
|
19
39
|
}
|
|
@@ -77,6 +97,9 @@ function getDefaultAgentId(payload) {
|
|
|
77
97
|
const explicit = process.env.IRANTI_CLAUDE_AGENT_ID?.trim();
|
|
78
98
|
if (explicit)
|
|
79
99
|
return explicit;
|
|
100
|
+
const projectBindingAgent = process.env.IRANTI_AGENT_ID?.trim();
|
|
101
|
+
if (projectBindingAgent)
|
|
102
|
+
return projectBindingAgent;
|
|
80
103
|
const base = path_1.default.basename(getCwd(payload));
|
|
81
104
|
return `claude_code_${slugify(base || 'project')}`;
|
|
82
105
|
}
|
|
@@ -85,6 +108,10 @@ function getEntityHints(payload) {
|
|
|
85
108
|
const cwd = getCwd(payload);
|
|
86
109
|
const projectHint = `project/${slugify(path_1.default.basename(cwd) || 'project')}`;
|
|
87
110
|
out.add(projectHint);
|
|
111
|
+
const memoryEntity = process.env.IRANTI_MEMORY_ENTITY?.trim();
|
|
112
|
+
if (memoryEntity) {
|
|
113
|
+
out.add(memoryEntity);
|
|
114
|
+
}
|
|
88
115
|
const envHints = (process.env.IRANTI_CLAUDE_ENTITY_HINTS ?? '')
|
|
89
116
|
.split(',')
|
|
90
117
|
.map((value) => value.trim())
|
|
@@ -105,7 +132,17 @@ async function ensureHookAgent(iranti, payload) {
|
|
|
105
132
|
return agentId;
|
|
106
133
|
}
|
|
107
134
|
function getPrompt(payload) {
|
|
108
|
-
|
|
135
|
+
const candidates = [
|
|
136
|
+
payload.prompt,
|
|
137
|
+
payload.message,
|
|
138
|
+
payload.text,
|
|
139
|
+
];
|
|
140
|
+
for (const candidate of candidates) {
|
|
141
|
+
if (typeof candidate === 'string' && candidate.trim()) {
|
|
142
|
+
return candidate.trim();
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
return '';
|
|
109
146
|
}
|
|
110
147
|
function getMaxFacts() {
|
|
111
148
|
const raw = Number(process.env.IRANTI_CLAUDE_MAX_FACTS ?? 6);
|
|
@@ -113,41 +150,26 @@ function getMaxFacts() {
|
|
|
113
150
|
return 6;
|
|
114
151
|
return Math.min(12, Math.trunc(raw));
|
|
115
152
|
}
|
|
116
|
-
function
|
|
117
|
-
const
|
|
153
|
+
function formatSessionContext(facts, cwd) {
|
|
154
|
+
const limited = facts.slice(0, getMaxFacts());
|
|
118
155
|
const lines = [
|
|
119
156
|
'[Iranti Session Memory]',
|
|
120
157
|
`Project: ${path_1.default.basename(cwd)}`,
|
|
121
158
|
];
|
|
122
|
-
if (
|
|
123
|
-
lines.push(`Task type: ${brief.inferredTaskType}`);
|
|
124
|
-
}
|
|
125
|
-
if (facts.length > 0) {
|
|
159
|
+
if (limited.length > 0) {
|
|
126
160
|
lines.push('Relevant memory:');
|
|
127
|
-
for (const fact of
|
|
128
|
-
|
|
129
|
-
const summary = typeof fact?.summary === 'string' ? fact.summary : fact?.valueSummary;
|
|
130
|
-
if (!summary)
|
|
131
|
-
continue;
|
|
132
|
-
lines.push(`- ${label}: ${summary}`);
|
|
161
|
+
for (const fact of limited) {
|
|
162
|
+
lines.push(`- ${fact.entity}/${fact.key}: ${fact.summary}`);
|
|
133
163
|
}
|
|
134
164
|
}
|
|
135
165
|
return lines.join('\n');
|
|
136
166
|
}
|
|
137
|
-
function
|
|
138
|
-
|
|
139
|
-
if (!attend?.shouldInject || facts.length === 0)
|
|
167
|
+
function formatPromptContext(facts) {
|
|
168
|
+
if (facts.length === 0)
|
|
140
169
|
return '';
|
|
141
170
|
const lines = ['[Iranti Retrieved Memory]'];
|
|
142
|
-
if (typeof attend?.reason === 'string' && attend.reason) {
|
|
143
|
-
lines.push(`Reason: ${attend.reason}`);
|
|
144
|
-
}
|
|
145
171
|
for (const fact of facts) {
|
|
146
|
-
|
|
147
|
-
const summary = typeof fact?.summary === 'string' ? fact.summary : fact?.valueSummary;
|
|
148
|
-
if (!summary)
|
|
149
|
-
continue;
|
|
150
|
-
lines.push(`- ${label}: ${summary}`);
|
|
172
|
+
lines.push(`- ${fact.entity}/${fact.key}: ${fact.summary}`);
|
|
151
173
|
}
|
|
152
174
|
return lines.join('\n');
|
|
153
175
|
}
|
|
@@ -160,6 +182,98 @@ function emitHookContext(event, additionalContext) {
|
|
|
160
182
|
};
|
|
161
183
|
process.stdout.write(`${JSON.stringify(payload)}\n`);
|
|
162
184
|
}
|
|
185
|
+
function shouldFetchMemory(prompt) {
|
|
186
|
+
const normalized = prompt.trim();
|
|
187
|
+
if (!normalized)
|
|
188
|
+
return false;
|
|
189
|
+
if (MEMORY_NEED_NEGATIVE_PATTERNS.some((pattern) => pattern.test(normalized))) {
|
|
190
|
+
return false;
|
|
191
|
+
}
|
|
192
|
+
if (MEMORY_NEED_POSITIVE_PATTERNS.some((pattern) => pattern.test(normalized))) {
|
|
193
|
+
return true;
|
|
194
|
+
}
|
|
195
|
+
if (/\b(my|our|we)\b/i.test(normalized)) {
|
|
196
|
+
return true;
|
|
197
|
+
}
|
|
198
|
+
return normalized.includes('/');
|
|
199
|
+
}
|
|
200
|
+
function dedupeFacts(facts) {
|
|
201
|
+
const byKey = new Map();
|
|
202
|
+
for (const fact of facts) {
|
|
203
|
+
const identity = `${fact.entity}/${fact.key}`;
|
|
204
|
+
const existing = byKey.get(identity);
|
|
205
|
+
if (!existing || fact.confidence > existing.confidence) {
|
|
206
|
+
byKey.set(identity, fact);
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
return Array.from(byKey.values())
|
|
210
|
+
.sort((a, b) => b.confidence - a.confidence || a.entity.localeCompare(b.entity) || a.key.localeCompare(b.key))
|
|
211
|
+
.slice(0, getMaxFacts());
|
|
212
|
+
}
|
|
213
|
+
async function loadAttendantStateFacts(iranti, agent) {
|
|
214
|
+
const state = await iranti.query(`agent/${agent}`, 'attendant_state');
|
|
215
|
+
if (!state.found || !state.value || typeof state.value !== 'object') {
|
|
216
|
+
return [];
|
|
217
|
+
}
|
|
218
|
+
const workingMemory = Array.isArray(state.value.workingMemory)
|
|
219
|
+
? state.value.workingMemory
|
|
220
|
+
: [];
|
|
221
|
+
return workingMemory.flatMap((entry) => {
|
|
222
|
+
const entityKey = typeof entry.entityKey === 'string' ? entry.entityKey.trim() : '';
|
|
223
|
+
const summary = typeof entry.summary === 'string' ? entry.summary.trim() : '';
|
|
224
|
+
if (!entityKey || !summary)
|
|
225
|
+
return [];
|
|
226
|
+
const segments = entityKey.split('/');
|
|
227
|
+
if (segments.length < 3)
|
|
228
|
+
return [];
|
|
229
|
+
return [{
|
|
230
|
+
entity: `${segments[0]}/${segments[1]}`,
|
|
231
|
+
key: segments.slice(2).join('/'),
|
|
232
|
+
summary,
|
|
233
|
+
confidence: typeof entry.confidence === 'number' ? entry.confidence : 0,
|
|
234
|
+
source: typeof entry.source === 'string' ? entry.source : 'attendant',
|
|
235
|
+
}];
|
|
236
|
+
});
|
|
237
|
+
}
|
|
238
|
+
async function loadEntityFacts(iranti, entities) {
|
|
239
|
+
const out = [];
|
|
240
|
+
for (const entity of entities) {
|
|
241
|
+
const trimmed = entity.trim();
|
|
242
|
+
if (!trimmed)
|
|
243
|
+
continue;
|
|
244
|
+
const entries = await iranti.queryAll(trimmed).catch(() => []);
|
|
245
|
+
for (const entry of entries) {
|
|
246
|
+
out.push({
|
|
247
|
+
entity: trimmed,
|
|
248
|
+
key: entry.key,
|
|
249
|
+
summary: entry.summary,
|
|
250
|
+
confidence: entry.confidence,
|
|
251
|
+
source: entry.source,
|
|
252
|
+
});
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
return out;
|
|
256
|
+
}
|
|
257
|
+
async function searchPromptFacts(iranti, prompt, entityHints) {
|
|
258
|
+
if (!prompt.trim())
|
|
259
|
+
return [];
|
|
260
|
+
const results = await iranti.search({
|
|
261
|
+
query: prompt,
|
|
262
|
+
limit: getMaxFacts(),
|
|
263
|
+
minScore: Number(process.env.IRANTI_CLAUDE_MIN_SEARCH_SCORE ?? 0.05),
|
|
264
|
+
}).catch(() => []);
|
|
265
|
+
const searched = results.map((result) => ({
|
|
266
|
+
entity: result.entity,
|
|
267
|
+
key: result.key,
|
|
268
|
+
summary: result.summary,
|
|
269
|
+
confidence: result.confidence,
|
|
270
|
+
source: result.source,
|
|
271
|
+
}));
|
|
272
|
+
if (searched.length > 0) {
|
|
273
|
+
return searched;
|
|
274
|
+
}
|
|
275
|
+
return loadEntityFacts(iranti, entityHints);
|
|
276
|
+
}
|
|
163
277
|
async function main() {
|
|
164
278
|
if (process.argv.includes('--help') || process.argv.includes('-h')) {
|
|
165
279
|
printHelp();
|
|
@@ -171,6 +285,12 @@ async function main() {
|
|
|
171
285
|
throw new Error('--event must be SessionStart or UserPromptSubmit');
|
|
172
286
|
}
|
|
173
287
|
const payload = parsePayload(await readStdin());
|
|
288
|
+
(0, runtimeEnv_1.loadRuntimeEnv)({
|
|
289
|
+
payloadCwd: getCwd(payload),
|
|
290
|
+
projectEnvFile: args['project-env'],
|
|
291
|
+
instanceEnvFile: args['instance-env'],
|
|
292
|
+
explicitEnvFile: args['env-file'],
|
|
293
|
+
});
|
|
174
294
|
const cwd = getCwd(payload);
|
|
175
295
|
const iranti = new sdk_1.Iranti({
|
|
176
296
|
connectionString: requireConnectionString(),
|
|
@@ -179,30 +299,27 @@ async function main() {
|
|
|
179
299
|
const agent = await ensureHookAgent(iranti, payload);
|
|
180
300
|
const entityHints = getEntityHints(payload);
|
|
181
301
|
if (event === 'SessionStart') {
|
|
182
|
-
const
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
});
|
|
189
|
-
emitHookContext(event, formatHandshakeContext(brief, cwd));
|
|
190
|
-
return;
|
|
302
|
+
const persistedFacts = await loadAttendantStateFacts(iranti, agent);
|
|
303
|
+
const directFacts = persistedFacts.length > 0
|
|
304
|
+
? persistedFacts
|
|
305
|
+
: await loadEntityFacts(iranti, entityHints);
|
|
306
|
+
emitHookContext(event, formatSessionContext(dedupeFacts(directFacts), cwd));
|
|
307
|
+
process.exit(0);
|
|
191
308
|
}
|
|
192
309
|
const prompt = getPrompt(payload);
|
|
193
|
-
if (!prompt)
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
return;
|
|
310
|
+
if (!prompt) {
|
|
311
|
+
process.exit(0);
|
|
312
|
+
}
|
|
313
|
+
if (!shouldFetchMemory(prompt)) {
|
|
314
|
+
process.exit(0);
|
|
315
|
+
}
|
|
316
|
+
const facts = await searchPromptFacts(iranti, prompt, entityHints);
|
|
317
|
+
const context = formatPromptContext(dedupeFacts(facts));
|
|
318
|
+
if (!context) {
|
|
319
|
+
process.exit(0);
|
|
320
|
+
}
|
|
205
321
|
emitHookContext(event, context);
|
|
322
|
+
process.exit(0);
|
|
206
323
|
}
|
|
207
324
|
main().catch((error) => {
|
|
208
325
|
console.error('[claude-code-memory-hook] fatal:', error instanceof Error ? error.message : String(error));
|
|
@@ -11,6 +11,7 @@ function parseArgs(argv) {
|
|
|
11
11
|
name: 'iranti',
|
|
12
12
|
agent: 'codex_code',
|
|
13
13
|
source: 'Codex',
|
|
14
|
+
useLocalScript: false,
|
|
14
15
|
};
|
|
15
16
|
for (let index = 0; index < argv.length; index += 1) {
|
|
16
17
|
const token = argv[index];
|
|
@@ -40,6 +41,15 @@ function parseArgs(argv) {
|
|
|
40
41
|
options.provider = next.trim();
|
|
41
42
|
index += 1;
|
|
42
43
|
break;
|
|
44
|
+
case '--project-env':
|
|
45
|
+
if (!next)
|
|
46
|
+
throw new Error('--project-env requires a value.');
|
|
47
|
+
options.projectEnv = next.trim();
|
|
48
|
+
index += 1;
|
|
49
|
+
break;
|
|
50
|
+
case '--local-script':
|
|
51
|
+
options.useLocalScript = true;
|
|
52
|
+
break;
|
|
43
53
|
case '--help':
|
|
44
54
|
case '-h':
|
|
45
55
|
printHelp();
|
|
@@ -56,20 +66,40 @@ function printHelp() {
|
|
|
56
66
|
'Configure Codex to use the local Iranti MCP server.',
|
|
57
67
|
'',
|
|
58
68
|
'Usage:',
|
|
59
|
-
' ts-node scripts/codex-setup.ts [--name iranti] [--agent codex_code] [--source Codex] [--provider openai]',
|
|
69
|
+
' ts-node scripts/codex-setup.ts [--name iranti] [--agent codex_code] [--source Codex] [--provider openai] [--project-env path] [--local-script]',
|
|
60
70
|
'',
|
|
61
71
|
'Notes:',
|
|
62
72
|
' - Registers a global Codex MCP entry using `codex mcp add`.',
|
|
63
|
-
' -
|
|
73
|
+
' - Prefers the installed CLI path: `iranti mcp`.',
|
|
74
|
+
' - Auto-detects .env.iranti from the current working directory and stores it as IRANTI_PROJECT_ENV.',
|
|
75
|
+
' - Use --local-script only if you need to point Codex at this repo build directly.',
|
|
76
|
+
' - Does not store DATABASE_URL in Codex config; iranti-mcp loads project/instance env at runtime.',
|
|
64
77
|
' - Replaces any existing MCP entry with the same name.',
|
|
65
78
|
].join('\n'));
|
|
66
79
|
}
|
|
80
|
+
function quoteForCmd(arg) {
|
|
81
|
+
if (arg.length === 0)
|
|
82
|
+
return '""';
|
|
83
|
+
if (!/[ \t"&()<>|^]/.test(arg))
|
|
84
|
+
return arg;
|
|
85
|
+
return `"${arg.replace(/"/g, '\\"')}"`;
|
|
86
|
+
}
|
|
67
87
|
function run(command, args, cwd) {
|
|
68
|
-
const result =
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
88
|
+
const result = process.platform === 'win32'
|
|
89
|
+
? (0, node_child_process_1.spawnSync)(process.env.ComSpec ?? 'cmd.exe', [
|
|
90
|
+
'/d',
|
|
91
|
+
'/c',
|
|
92
|
+
[command, ...args].map(quoteForCmd).join(' '),
|
|
93
|
+
], {
|
|
94
|
+
cwd,
|
|
95
|
+
encoding: 'utf8',
|
|
96
|
+
stdio: ['ignore', 'pipe', 'pipe'],
|
|
97
|
+
})
|
|
98
|
+
: (0, node_child_process_1.spawnSync)(command, args, {
|
|
99
|
+
cwd,
|
|
100
|
+
encoding: 'utf8',
|
|
101
|
+
stdio: ['ignore', 'pipe', 'pipe'],
|
|
102
|
+
});
|
|
73
103
|
if (result.error) {
|
|
74
104
|
throw result.error;
|
|
75
105
|
}
|
|
@@ -88,14 +118,50 @@ function tryRun(command, args, cwd) {
|
|
|
88
118
|
return null;
|
|
89
119
|
}
|
|
90
120
|
}
|
|
121
|
+
function findPackageRoot(startDir) {
|
|
122
|
+
let dir = startDir;
|
|
123
|
+
for (let i = 0; i < 6; i += 1) {
|
|
124
|
+
const pkgPath = node_path_1.default.join(dir, 'package.json');
|
|
125
|
+
if (node_fs_1.default.existsSync(pkgPath)) {
|
|
126
|
+
return dir;
|
|
127
|
+
}
|
|
128
|
+
const parent = node_path_1.default.dirname(dir);
|
|
129
|
+
if (parent === dir)
|
|
130
|
+
break;
|
|
131
|
+
dir = parent;
|
|
132
|
+
}
|
|
133
|
+
return node_path_1.default.resolve(startDir, '..');
|
|
134
|
+
}
|
|
135
|
+
function resolveProjectEnv(options) {
|
|
136
|
+
const explicit = options.projectEnv?.trim();
|
|
137
|
+
if (explicit) {
|
|
138
|
+
const resolved = node_path_1.default.resolve(explicit);
|
|
139
|
+
if (!node_fs_1.default.existsSync(resolved)) {
|
|
140
|
+
throw new Error(`Project env file not found: ${resolved}`);
|
|
141
|
+
}
|
|
142
|
+
return resolved;
|
|
143
|
+
}
|
|
144
|
+
const candidate = node_path_1.default.resolve(process.cwd(), '.env.iranti');
|
|
145
|
+
return node_fs_1.default.existsSync(candidate) ? candidate : undefined;
|
|
146
|
+
}
|
|
147
|
+
function canUseInstalledIranti(repoRoot) {
|
|
148
|
+
try {
|
|
149
|
+
run('iranti', ['mcp', '--help'], repoRoot);
|
|
150
|
+
return true;
|
|
151
|
+
}
|
|
152
|
+
catch {
|
|
153
|
+
return false;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
91
156
|
function main() {
|
|
92
157
|
const options = parseArgs(process.argv.slice(2));
|
|
93
|
-
const repoRoot =
|
|
158
|
+
const repoRoot = findPackageRoot(__dirname);
|
|
94
159
|
const mcpScript = node_path_1.default.join(repoRoot, 'dist', 'scripts', 'iranti-mcp.js');
|
|
95
|
-
if (!node_fs_1.default.existsSync(mcpScript)) {
|
|
96
|
-
throw new Error(`Missing build artifact: ${mcpScript}. Run "npm run build" first.`);
|
|
97
|
-
}
|
|
98
160
|
run('codex', ['--version'], repoRoot);
|
|
161
|
+
const useInstalled = !options.useLocalScript && canUseInstalledIranti(repoRoot);
|
|
162
|
+
if (!useInstalled && !node_fs_1.default.existsSync(mcpScript)) {
|
|
163
|
+
throw new Error(`Missing build artifact: ${mcpScript}. Run "npm run build" first, or install iranti globally and rerun without --local-script.`);
|
|
164
|
+
}
|
|
99
165
|
const existing = tryRun('codex', ['mcp', 'get', options.name, '--json'], repoRoot);
|
|
100
166
|
if (existing !== null) {
|
|
101
167
|
run('codex', ['mcp', 'remove', options.name], repoRoot);
|
|
@@ -109,16 +175,39 @@ function main() {
|
|
|
109
175
|
'--env',
|
|
110
176
|
`IRANTI_MCP_DEFAULT_SOURCE=${options.source}`,
|
|
111
177
|
];
|
|
178
|
+
const projectEnv = resolveProjectEnv(options);
|
|
179
|
+
if (projectEnv) {
|
|
180
|
+
addArgs.push('--env', `IRANTI_PROJECT_ENV=${projectEnv}`);
|
|
181
|
+
}
|
|
112
182
|
if (options.provider) {
|
|
113
183
|
addArgs.push('--env', `LLM_PROVIDER=${options.provider}`);
|
|
114
184
|
}
|
|
115
|
-
|
|
185
|
+
if (useInstalled) {
|
|
186
|
+
addArgs.push('--', 'iranti', 'mcp');
|
|
187
|
+
}
|
|
188
|
+
else {
|
|
189
|
+
addArgs.push('--', 'node', mcpScript);
|
|
190
|
+
}
|
|
116
191
|
run('codex', addArgs, repoRoot);
|
|
117
192
|
const registered = run('codex', ['mcp', 'get', options.name], repoRoot);
|
|
118
193
|
console.log(registered);
|
|
119
194
|
console.log('');
|
|
120
195
|
console.log('Codex is now configured to use Iranti through MCP.');
|
|
121
|
-
|
|
196
|
+
if (useInstalled) {
|
|
197
|
+
console.log('Registration target: installed CLI (`iranti mcp`)');
|
|
198
|
+
if (projectEnv) {
|
|
199
|
+
console.log(`Project binding: ${projectEnv}`);
|
|
200
|
+
}
|
|
201
|
+
console.log('Launch Codex in the project you want to bind to Iranti, for example:');
|
|
202
|
+
console.log(' codex -C C:\\path\\to\\your\\project');
|
|
203
|
+
}
|
|
204
|
+
else {
|
|
205
|
+
console.log(`Registration target: repo build (${mcpScript})`);
|
|
206
|
+
if (projectEnv) {
|
|
207
|
+
console.log(`Project binding: ${projectEnv}`);
|
|
208
|
+
}
|
|
209
|
+
console.log(`Launch with: codex -C "${repoRoot}"`);
|
|
210
|
+
}
|
|
122
211
|
}
|
|
123
212
|
main();
|
|
124
213
|
//# sourceMappingURL=codex-setup.js.map
|
|
@@ -8,6 +8,7 @@ const fs_1 = __importDefault(require("fs"));
|
|
|
8
8
|
const promises_1 = __importDefault(require("fs/promises"));
|
|
9
9
|
const os_1 = __importDefault(require("os"));
|
|
10
10
|
const path_1 = __importDefault(require("path"));
|
|
11
|
+
const child_process_1 = require("child_process");
|
|
11
12
|
const promises_2 = __importDefault(require("readline/promises"));
|
|
12
13
|
const stream_1 = require("stream");
|
|
13
14
|
const client_1 = require("../src/library/client");
|
|
@@ -118,6 +119,54 @@ function getPackageVersion() {
|
|
|
118
119
|
}
|
|
119
120
|
return '0.0.0';
|
|
120
121
|
}
|
|
122
|
+
function builtScriptPath(scriptName) {
|
|
123
|
+
return path_1.default.resolve(__dirname, `${scriptName}.js`);
|
|
124
|
+
}
|
|
125
|
+
async function handoffToScript(scriptName, rawArgs) {
|
|
126
|
+
const builtPath = builtScriptPath(scriptName);
|
|
127
|
+
if (fs_1.default.existsSync(builtPath)) {
|
|
128
|
+
await new Promise((resolve, reject) => {
|
|
129
|
+
const child = (0, child_process_1.spawn)(process.execPath, [builtPath, ...rawArgs], {
|
|
130
|
+
stdio: 'inherit',
|
|
131
|
+
env: process.env,
|
|
132
|
+
});
|
|
133
|
+
child.on('error', reject);
|
|
134
|
+
child.on('exit', (code, signal) => {
|
|
135
|
+
if (signal) {
|
|
136
|
+
reject(new Error(`${scriptName} terminated with signal ${signal}`));
|
|
137
|
+
return;
|
|
138
|
+
}
|
|
139
|
+
if ((code ?? 0) !== 0) {
|
|
140
|
+
process.exit(code ?? 1);
|
|
141
|
+
}
|
|
142
|
+
resolve();
|
|
143
|
+
});
|
|
144
|
+
});
|
|
145
|
+
return;
|
|
146
|
+
}
|
|
147
|
+
const sourcePath = path_1.default.resolve(process.cwd(), 'scripts', `${scriptName}.ts`);
|
|
148
|
+
if (!fs_1.default.existsSync(sourcePath)) {
|
|
149
|
+
throw new Error(`Unable to locate ${scriptName} implementation.`);
|
|
150
|
+
}
|
|
151
|
+
await new Promise((resolve, reject) => {
|
|
152
|
+
const child = (0, child_process_1.spawn)('npx', ['ts-node', sourcePath, ...rawArgs], {
|
|
153
|
+
stdio: 'inherit',
|
|
154
|
+
env: process.env,
|
|
155
|
+
shell: process.platform === 'win32',
|
|
156
|
+
});
|
|
157
|
+
child.on('error', reject);
|
|
158
|
+
child.on('exit', (code, signal) => {
|
|
159
|
+
if (signal) {
|
|
160
|
+
reject(new Error(`${scriptName} terminated with signal ${signal}`));
|
|
161
|
+
return;
|
|
162
|
+
}
|
|
163
|
+
if ((code ?? 0) !== 0) {
|
|
164
|
+
process.exit(code ?? 1);
|
|
165
|
+
}
|
|
166
|
+
resolve();
|
|
167
|
+
});
|
|
168
|
+
});
|
|
169
|
+
}
|
|
121
170
|
async function ensureDir(dir) {
|
|
122
171
|
await promises_1.default.mkdir(dir, { recursive: true });
|
|
123
172
|
}
|
|
@@ -1077,7 +1126,12 @@ Diagnostics:
|
|
|
1077
1126
|
iranti doctor [--instance <name>] [--scope user|system] [--env <file>] [--json]
|
|
1078
1127
|
iranti status [--scope user|system] [--json]
|
|
1079
1128
|
iranti upgrade [--json]
|
|
1080
|
-
|
|
1129
|
+
|
|
1130
|
+
Integrations:
|
|
1131
|
+
iranti mcp [--help]
|
|
1132
|
+
iranti claude-hook --event SessionStart|UserPromptSubmit [--project-env <path>] [--instance-env <path>] [--env-file <path>]
|
|
1133
|
+
iranti codex-setup [--name iranti] [--agent codex_code] [--source Codex] [--provider openai] [--project-env <path>] [--local-script]
|
|
1134
|
+
`);
|
|
1081
1135
|
}
|
|
1082
1136
|
async function main() {
|
|
1083
1137
|
const args = parseArgs(process.argv.slice(2));
|
|
@@ -1150,6 +1204,18 @@ async function main() {
|
|
|
1150
1204
|
await upgradeCommand(args);
|
|
1151
1205
|
return;
|
|
1152
1206
|
}
|
|
1207
|
+
if (args.command === 'mcp') {
|
|
1208
|
+
await handoffToScript('iranti-mcp', process.argv.slice(3));
|
|
1209
|
+
return;
|
|
1210
|
+
}
|
|
1211
|
+
if (args.command === 'claude-hook') {
|
|
1212
|
+
await handoffToScript('claude-code-memory-hook', process.argv.slice(3));
|
|
1213
|
+
return;
|
|
1214
|
+
}
|
|
1215
|
+
if (args.command === 'codex-setup') {
|
|
1216
|
+
await handoffToScript('codex-setup', process.argv.slice(3));
|
|
1217
|
+
return;
|
|
1218
|
+
}
|
|
1153
1219
|
throw new Error(`Unknown command '${args.command}'. Run: iranti help`);
|
|
1154
1220
|
}
|
|
1155
1221
|
main().catch((err) => {
|
|
@@ -32,35 +32,13 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
32
32
|
return result;
|
|
33
33
|
};
|
|
34
34
|
})();
|
|
35
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
|
-
};
|
|
38
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
-
const node_fs_1 = __importDefault(require("node:fs"));
|
|
40
|
-
const node_path_1 = __importDefault(require("node:path"));
|
|
41
|
-
const dotenv_1 = __importDefault(require("dotenv"));
|
|
42
36
|
const mcp_js_1 = require("@modelcontextprotocol/sdk/server/mcp.js");
|
|
43
37
|
const stdio_js_1 = require("@modelcontextprotocol/sdk/server/stdio.js");
|
|
44
38
|
const z = __importStar(require("zod/v4"));
|
|
45
39
|
const sdk_1 = require("../src/sdk");
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
const candidates = explicitPath
|
|
49
|
-
? [explicitPath]
|
|
50
|
-
: [
|
|
51
|
-
node_path_1.default.resolve(process.cwd(), '.env'),
|
|
52
|
-
node_path_1.default.resolve(__dirname, '..', '.env'),
|
|
53
|
-
node_path_1.default.resolve(__dirname, '..', '..', '.env'),
|
|
54
|
-
];
|
|
55
|
-
for (const candidate of candidates) {
|
|
56
|
-
if (candidate && node_fs_1.default.existsSync(candidate)) {
|
|
57
|
-
dotenv_1.default.config({ path: candidate });
|
|
58
|
-
return;
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
dotenv_1.default.config();
|
|
62
|
-
}
|
|
63
|
-
loadEnv();
|
|
40
|
+
const runtimeEnv_1 = require("../src/lib/runtimeEnv");
|
|
41
|
+
(0, runtimeEnv_1.loadRuntimeEnv)();
|
|
64
42
|
function printHelp() {
|
|
65
43
|
console.log([
|
|
66
44
|
'Iranti MCP Server',
|
|
@@ -72,6 +50,8 @@ function printHelp() {
|
|
|
72
50
|
'Environment:',
|
|
73
51
|
' DATABASE_URL PostgreSQL connection string (required)',
|
|
74
52
|
' LLM_PROVIDER Optional Iranti provider override',
|
|
53
|
+
' IRANTI_PROJECT_ENV Optional project binding path (.env.iranti)',
|
|
54
|
+
' IRANTI_INSTANCE_ENV Optional instance env path',
|
|
75
55
|
' IRANTI_MCP_DEFAULT_AGENT Default agent id (default: claude_code)',
|
|
76
56
|
' IRANTI_MCP_AGENT_NAME Default agent display name',
|
|
77
57
|
' IRANTI_MCP_AGENT_DESCRIPTION Default agent description',
|
|
@@ -89,7 +69,9 @@ function requireConnectionString() {
|
|
|
89
69
|
return connectionString;
|
|
90
70
|
}
|
|
91
71
|
function defaultAgentId() {
|
|
92
|
-
return process.env.IRANTI_MCP_DEFAULT_AGENT?.trim()
|
|
72
|
+
return process.env.IRANTI_MCP_DEFAULT_AGENT?.trim()
|
|
73
|
+
|| process.env.IRANTI_AGENT_ID?.trim()
|
|
74
|
+
|| 'claude_code';
|
|
93
75
|
}
|
|
94
76
|
function defaultWriteSource() {
|
|
95
77
|
return process.env.IRANTI_MCP_DEFAULT_SOURCE?.trim() || 'ClaudeCode';
|
|
@@ -162,7 +144,7 @@ async function main() {
|
|
|
162
144
|
await ensureDefaultAgent(iranti);
|
|
163
145
|
const server = new mcp_js_1.McpServer({
|
|
164
146
|
name: 'iranti-mcp',
|
|
165
|
-
version: '0.1.
|
|
147
|
+
version: '0.1.3',
|
|
166
148
|
});
|
|
167
149
|
server.registerTool('iranti_handshake', {
|
|
168
150
|
description: 'Initialize or refresh Claude working memory for the current task.',
|
package/dist/scripts/seed.js
CHANGED
|
@@ -15,7 +15,7 @@ const STAFF_ENTRIES = [
|
|
|
15
15
|
entityId: 'librarian',
|
|
16
16
|
key: 'operating_rules',
|
|
17
17
|
valueRaw: {
|
|
18
|
-
version: '0.1.
|
|
18
|
+
version: '0.1.3',
|
|
19
19
|
rules: [
|
|
20
20
|
'All writes from external agents go through the Librarian — never directly to the database',
|
|
21
21
|
'Check for existing entries before every write',
|
|
@@ -39,7 +39,7 @@ const STAFF_ENTRIES = [
|
|
|
39
39
|
entityId: 'attendant',
|
|
40
40
|
key: 'operating_rules',
|
|
41
41
|
valueRaw: {
|
|
42
|
-
version: '0.1.
|
|
42
|
+
version: '0.1.3',
|
|
43
43
|
rules: [
|
|
44
44
|
'Assigned one-per-external-agent — serve the agent, not the user',
|
|
45
45
|
'On handshake: read AGENTS.md and MCP config, query Librarian for relevant rules and task context',
|
|
@@ -61,7 +61,7 @@ const STAFF_ENTRIES = [
|
|
|
61
61
|
entityId: 'archivist',
|
|
62
62
|
key: 'operating_rules',
|
|
63
63
|
valueRaw: {
|
|
64
|
-
version: '0.1.
|
|
64
|
+
version: '0.1.3',
|
|
65
65
|
rules: [
|
|
66
66
|
'Run on schedule or when conflict flags exceed threshold — not on every write',
|
|
67
67
|
'Scan for expired, low-confidence, flagged, and duplicate entries',
|
|
@@ -82,7 +82,7 @@ const STAFF_ENTRIES = [
|
|
|
82
82
|
entityType: 'system',
|
|
83
83
|
entityId: 'library',
|
|
84
84
|
key: 'schema_version',
|
|
85
|
-
valueRaw: { version: '0.1.
|
|
85
|
+
valueRaw: { version: '0.1.3' },
|
|
86
86
|
valueSummary: 'Current Library schema version.',
|
|
87
87
|
confidence: 100,
|
|
88
88
|
source: 'seed',
|
|
@@ -95,7 +95,7 @@ const STAFF_ENTRIES = [
|
|
|
95
95
|
key: 'initialization_log',
|
|
96
96
|
valueRaw: {
|
|
97
97
|
initializedAt: new Date().toISOString(),
|
|
98
|
-
seedVersion: '0.1.
|
|
98
|
+
seedVersion: '0.1.3',
|
|
99
99
|
},
|
|
100
100
|
valueSummary: 'Record of when and how this Library was initialized.',
|
|
101
101
|
confidence: 100,
|
|
@@ -108,7 +108,7 @@ const STAFF_ENTRIES = [
|
|
|
108
108
|
entityId: 'ontology',
|
|
109
109
|
key: 'core_schema',
|
|
110
110
|
valueRaw: {
|
|
111
|
-
version: '0.1.
|
|
111
|
+
version: '0.1.3',
|
|
112
112
|
states: ['candidate', 'provisional', 'canonical'],
|
|
113
113
|
coreEntityTypes: [
|
|
114
114
|
'person',
|
|
@@ -156,7 +156,7 @@ const STAFF_ENTRIES = [
|
|
|
156
156
|
entityId: 'ontology',
|
|
157
157
|
key: 'extension_registry',
|
|
158
158
|
valueRaw: {
|
|
159
|
-
version: '0.1.
|
|
159
|
+
version: '0.1.3',
|
|
160
160
|
namespaces: {
|
|
161
161
|
education: {
|
|
162
162
|
status: 'provisional',
|
|
@@ -187,7 +187,7 @@ const STAFF_ENTRIES = [
|
|
|
187
187
|
entityId: 'ontology',
|
|
188
188
|
key: 'candidate_terms',
|
|
189
189
|
valueRaw: {
|
|
190
|
-
version: '0.1.
|
|
190
|
+
version: '0.1.3',
|
|
191
191
|
terms: [],
|
|
192
192
|
},
|
|
193
193
|
valueSummary: 'Staging area for ontology terms detected repeatedly but not yet promoted.',
|
|
@@ -201,7 +201,7 @@ const STAFF_ENTRIES = [
|
|
|
201
201
|
entityId: 'ontology',
|
|
202
202
|
key: 'promotion_policy',
|
|
203
203
|
valueRaw: {
|
|
204
|
-
version: '0.1.
|
|
204
|
+
version: '0.1.3',
|
|
205
205
|
candidateToProvisional: {
|
|
206
206
|
minSeenCount: 3,
|
|
207
207
|
minDistinctAgents: 2,
|
|
@@ -237,7 +237,7 @@ const STAFF_ENTRIES = [
|
|
|
237
237
|
entityId: 'ontology',
|
|
238
238
|
key: 'change_log',
|
|
239
239
|
valueRaw: {
|
|
240
|
-
version: '0.1.
|
|
240
|
+
version: '0.1.3',
|
|
241
241
|
events: [
|
|
242
242
|
{
|
|
243
243
|
at: new Date().toISOString(),
|
package/dist/src/api/server.js
CHANGED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
type RuntimeEnvOptions = {
|
|
2
|
+
cwd?: string;
|
|
3
|
+
payloadCwd?: string;
|
|
4
|
+
projectEnvFile?: string;
|
|
5
|
+
instanceEnvFile?: string;
|
|
6
|
+
explicitEnvFile?: string;
|
|
7
|
+
};
|
|
8
|
+
type RuntimeEnvLoadResult = {
|
|
9
|
+
loadedFiles: string[];
|
|
10
|
+
projectEnvFile?: string;
|
|
11
|
+
instanceEnvFile?: string;
|
|
12
|
+
};
|
|
13
|
+
export declare function loadRuntimeEnv(options?: RuntimeEnvOptions): RuntimeEnvLoadResult;
|
|
14
|
+
export {};
|
|
15
|
+
//# sourceMappingURL=runtimeEnv.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runtimeEnv.d.ts","sourceRoot":"","sources":["../../../src/lib/runtimeEnv.ts"],"names":[],"mappings":"AAIA,KAAK,iBAAiB,GAAG;IACrB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,eAAe,CAAC,EAAE,MAAM,CAAC;CAC5B,CAAC;AAEF,KAAK,oBAAoB,GAAG;IACxB,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,eAAe,CAAC,EAAE,MAAM,CAAC;CAC5B,CAAC;AAuDF,wBAAgB,cAAc,CAAC,OAAO,GAAE,iBAAsB,GAAG,oBAAoB,CAsCpF"}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.loadRuntimeEnv = loadRuntimeEnv;
|
|
7
|
+
const fs_1 = __importDefault(require("fs"));
|
|
8
|
+
const path_1 = __importDefault(require("path"));
|
|
9
|
+
const dotenv_1 = __importDefault(require("dotenv"));
|
|
10
|
+
function parseEnvFile(filePath) {
|
|
11
|
+
const raw = fs_1.default.readFileSync(filePath, 'utf-8');
|
|
12
|
+
return dotenv_1.default.parse(raw);
|
|
13
|
+
}
|
|
14
|
+
function applyEnvVars(vars, initialEnvKeys) {
|
|
15
|
+
for (const [key, value] of Object.entries(vars)) {
|
|
16
|
+
if (initialEnvKeys.has(key))
|
|
17
|
+
continue;
|
|
18
|
+
process.env[key] = value;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
function dedupePaths(paths) {
|
|
22
|
+
const seen = new Set();
|
|
23
|
+
const out = [];
|
|
24
|
+
for (const candidate of paths) {
|
|
25
|
+
if (!candidate)
|
|
26
|
+
continue;
|
|
27
|
+
const resolved = path_1.default.resolve(candidate);
|
|
28
|
+
if (seen.has(resolved))
|
|
29
|
+
continue;
|
|
30
|
+
seen.add(resolved);
|
|
31
|
+
out.push(resolved);
|
|
32
|
+
}
|
|
33
|
+
return out;
|
|
34
|
+
}
|
|
35
|
+
function findProjectEnvFile(options) {
|
|
36
|
+
const explicit = options.projectEnvFile?.trim() || process.env.IRANTI_PROJECT_ENV?.trim();
|
|
37
|
+
if (explicit && fs_1.default.existsSync(explicit))
|
|
38
|
+
return path_1.default.resolve(explicit);
|
|
39
|
+
const candidates = dedupePaths([
|
|
40
|
+
options.payloadCwd ? path_1.default.join(options.payloadCwd, '.env.iranti') : null,
|
|
41
|
+
options.cwd ? path_1.default.join(options.cwd, '.env.iranti') : null,
|
|
42
|
+
path_1.default.join(process.cwd(), '.env.iranti'),
|
|
43
|
+
]);
|
|
44
|
+
return candidates.find((candidate) => fs_1.default.existsSync(candidate));
|
|
45
|
+
}
|
|
46
|
+
function findFallbackEnvFile(options) {
|
|
47
|
+
const explicit = options.explicitEnvFile?.trim() || process.env.IRANTI_ENV_FILE?.trim();
|
|
48
|
+
if (explicit && fs_1.default.existsSync(explicit))
|
|
49
|
+
return path_1.default.resolve(explicit);
|
|
50
|
+
const candidates = dedupePaths([
|
|
51
|
+
options.payloadCwd ? path_1.default.join(options.payloadCwd, '.env') : null,
|
|
52
|
+
options.cwd ? path_1.default.join(options.cwd, '.env') : null,
|
|
53
|
+
path_1.default.join(process.cwd(), '.env'),
|
|
54
|
+
path_1.default.resolve(__dirname, '..', '..', '.env'),
|
|
55
|
+
path_1.default.resolve(__dirname, '..', '..', '..', '.env'),
|
|
56
|
+
]);
|
|
57
|
+
return candidates.find((candidate) => fs_1.default.existsSync(candidate));
|
|
58
|
+
}
|
|
59
|
+
function loadRuntimeEnv(options = {}) {
|
|
60
|
+
const loadedFiles = [];
|
|
61
|
+
const initialEnvKeys = new Set(Object.keys(process.env));
|
|
62
|
+
const fallbackEnvFile = findFallbackEnvFile(options);
|
|
63
|
+
if (fallbackEnvFile) {
|
|
64
|
+
applyEnvVars(parseEnvFile(fallbackEnvFile), initialEnvKeys);
|
|
65
|
+
loadedFiles.push(fallbackEnvFile);
|
|
66
|
+
}
|
|
67
|
+
const projectEnvFile = findProjectEnvFile(options);
|
|
68
|
+
const projectEnv = projectEnvFile && fs_1.default.existsSync(projectEnvFile)
|
|
69
|
+
? parseEnvFile(projectEnvFile)
|
|
70
|
+
: null;
|
|
71
|
+
const instanceEnvFile = options.instanceEnvFile?.trim()
|
|
72
|
+
|| process.env.IRANTI_INSTANCE_ENV?.trim()
|
|
73
|
+
|| projectEnv?.IRANTI_INSTANCE_ENV;
|
|
74
|
+
const resolvedInstanceEnvFile = instanceEnvFile && fs_1.default.existsSync(instanceEnvFile)
|
|
75
|
+
? path_1.default.resolve(instanceEnvFile)
|
|
76
|
+
: undefined;
|
|
77
|
+
if (resolvedInstanceEnvFile) {
|
|
78
|
+
applyEnvVars(parseEnvFile(resolvedInstanceEnvFile), initialEnvKeys);
|
|
79
|
+
loadedFiles.push(resolvedInstanceEnvFile);
|
|
80
|
+
}
|
|
81
|
+
if (projectEnvFile && projectEnv) {
|
|
82
|
+
applyEnvVars(projectEnv, initialEnvKeys);
|
|
83
|
+
loadedFiles.push(projectEnvFile);
|
|
84
|
+
}
|
|
85
|
+
return {
|
|
86
|
+
loadedFiles,
|
|
87
|
+
projectEnvFile,
|
|
88
|
+
instanceEnvFile: resolvedInstanceEnvFile,
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
//# sourceMappingURL=runtimeEnv.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runtimeEnv.js","sourceRoot":"","sources":["../../../src/lib/runtimeEnv.ts"],"names":[],"mappings":"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"}
|