@triedotdev/mcp 1.0.102 → 1.0.104
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 +0 -1
- package/dist/{chunk-OVRG5RP3.js → chunk-33WL3D7A.js} +3 -5
- package/dist/{chunk-OVRG5RP3.js.map → chunk-33WL3D7A.js.map} +1 -1
- package/dist/{chunk-JDHR5BDR.js → chunk-6JPPYG7F.js} +928 -258
- package/dist/chunk-6JPPYG7F.js.map +1 -0
- package/dist/{chunk-M4JCQO5G.js → chunk-CKYU5JOD.js} +579 -114
- package/dist/chunk-CKYU5JOD.js.map +1 -0
- package/dist/{chunk-B3MNN3XB.js → chunk-HFKOGW7H.js} +6 -8
- package/dist/{chunk-B3MNN3XB.js.map → chunk-HFKOGW7H.js.map} +1 -1
- package/dist/chunk-HIKONDDO.js +26 -0
- package/dist/chunk-HIKONDDO.js.map +1 -0
- package/dist/chunk-M3WF7ZXI.js +2764 -0
- package/dist/chunk-M3WF7ZXI.js.map +1 -0
- package/dist/{chunk-NIASHOAB.js → chunk-SPQJC7RA.js} +5 -5
- package/dist/cli/main.js +16 -18
- package/dist/cli/main.js.map +1 -1
- package/dist/cli/yolo-daemon.js +17 -64
- package/dist/cli/yolo-daemon.js.map +1 -1
- package/dist/{goal-manager-LAOT4QQX.js → goal-manager-AP4LTE6U.js} +3 -4
- package/dist/{guardian-agent-M352CBE5.js → guardian-agent-WB6LWRLM.js} +7 -8
- package/dist/index.js +41 -119
- package/dist/index.js.map +1 -1
- package/package.json +4 -1
- package/dist/chunk-AE2XLMZC.js +0 -6152
- package/dist/chunk-AE2XLMZC.js.map +0 -1
- package/dist/chunk-CCI6LKXZ.js +0 -526
- package/dist/chunk-CCI6LKXZ.js.map +0 -1
- package/dist/chunk-JDHR5BDR.js.map +0 -1
- package/dist/chunk-M4JCQO5G.js.map +0 -1
- package/dist/chunk-R3I2GCZC.js +0 -682
- package/dist/chunk-R3I2GCZC.js.map +0 -1
- package/dist/issue-store-W2X33X2X.js +0 -28
- package/dist/issue-store-W2X33X2X.js.map +0 -1
- /package/dist/{chunk-NIASHOAB.js.map → chunk-SPQJC7RA.js.map} +0 -0
- /package/dist/{goal-manager-LAOT4QQX.js.map → goal-manager-AP4LTE6U.js.map} +0 -0
- /package/dist/{guardian-agent-M352CBE5.js.map → guardian-agent-WB6LWRLM.js.map} +0 -0
|
@@ -1,25 +1,22 @@
|
|
|
1
|
-
import {
|
|
2
|
-
runExecFile
|
|
3
|
-
} from "./chunk-CCI6LKXZ.js";
|
|
4
1
|
import {
|
|
5
2
|
ContextGraph
|
|
6
|
-
} from "./chunk-
|
|
7
|
-
import {
|
|
8
|
-
scanForVulnerabilities
|
|
9
|
-
} from "./chunk-F4NJ4CBP.js";
|
|
3
|
+
} from "./chunk-SPQJC7RA.js";
|
|
10
4
|
import {
|
|
11
5
|
scanForVibeCodeIssues
|
|
12
6
|
} from "./chunk-IXO4G4D3.js";
|
|
13
|
-
import {
|
|
14
|
-
Trie
|
|
15
|
-
} from "./chunk-6NLHFIYA.js";
|
|
16
7
|
import {
|
|
17
8
|
storeIssues
|
|
18
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-6JPPYG7F.js";
|
|
19
10
|
import {
|
|
20
11
|
getTrieDirectory,
|
|
21
12
|
getWorkingDirectory
|
|
22
13
|
} from "./chunk-R4AAPFXC.js";
|
|
14
|
+
import {
|
|
15
|
+
scanForVulnerabilities
|
|
16
|
+
} from "./chunk-F4NJ4CBP.js";
|
|
17
|
+
import {
|
|
18
|
+
Trie
|
|
19
|
+
} from "./chunk-6NLHFIYA.js";
|
|
23
20
|
import {
|
|
24
21
|
isInteractiveMode
|
|
25
22
|
} from "./chunk-APMV77PU.js";
|
|
@@ -27,19 +24,235 @@ import {
|
|
|
27
24
|
__require
|
|
28
25
|
} from "./chunk-DGUM43GV.js";
|
|
29
26
|
|
|
30
|
-
// src/
|
|
27
|
+
// src/utils/project-info.ts
|
|
28
|
+
import { readFile, writeFile, mkdir } from "fs/promises";
|
|
31
29
|
import { existsSync } from "fs";
|
|
32
|
-
import { mkdir, writeFile, readFile } from "fs/promises";
|
|
33
30
|
import { join } from "path";
|
|
31
|
+
var PROJECT_MD_PATH = "PROJECT.md";
|
|
32
|
+
function getProjectTemplate() {
|
|
33
|
+
return `# Project Information
|
|
34
|
+
|
|
35
|
+
> This file stores important project context for AI assistants.
|
|
36
|
+
> Edit freely - this file is yours, not auto-generated.
|
|
37
|
+
> Available via MCP resource: \`trie://project\`
|
|
38
|
+
|
|
39
|
+
---
|
|
40
|
+
|
|
41
|
+
## Project Overview
|
|
42
|
+
|
|
43
|
+
<!-- Describe your project's purpose and goals -->
|
|
44
|
+
|
|
45
|
+
[Add project description here]
|
|
46
|
+
|
|
47
|
+
---
|
|
48
|
+
|
|
49
|
+
## Technology Stack
|
|
50
|
+
|
|
51
|
+
<!-- List frameworks, languages, databases, cloud services, etc. -->
|
|
52
|
+
|
|
53
|
+
- **Language:**
|
|
54
|
+
- **Framework:**
|
|
55
|
+
- **Database:**
|
|
56
|
+
- **Hosting:**
|
|
57
|
+
|
|
58
|
+
---
|
|
59
|
+
|
|
60
|
+
## Architecture
|
|
61
|
+
|
|
62
|
+
<!-- Key patterns, architectural decisions, and system design -->
|
|
63
|
+
|
|
64
|
+
[Describe your architecture here]
|
|
65
|
+
|
|
66
|
+
---
|
|
67
|
+
|
|
68
|
+
## Coding Conventions
|
|
69
|
+
|
|
70
|
+
<!-- Style guidelines, naming conventions, patterns to follow -->
|
|
71
|
+
|
|
72
|
+
-
|
|
73
|
+
-
|
|
74
|
+
-
|
|
75
|
+
|
|
76
|
+
---
|
|
77
|
+
|
|
78
|
+
## Environment
|
|
79
|
+
|
|
80
|
+
<!-- URLs, API endpoints, deployment info -->
|
|
81
|
+
|
|
82
|
+
| Environment | URL | Notes |
|
|
83
|
+
|-------------|-----|-------|
|
|
84
|
+
| Development | | |
|
|
85
|
+
| Staging | | |
|
|
86
|
+
| Production | | |
|
|
87
|
+
|
|
88
|
+
---
|
|
89
|
+
|
|
90
|
+
## Team
|
|
91
|
+
|
|
92
|
+
<!-- Ownership, contacts, responsibilities -->
|
|
93
|
+
|
|
94
|
+
- **Owner:**
|
|
95
|
+
- **Team:**
|
|
96
|
+
|
|
97
|
+
---
|
|
98
|
+
|
|
99
|
+
## Compliance
|
|
100
|
+
|
|
101
|
+
<!-- HIPAA, SOC2, GDPR, PCI-DSS requirements if applicable -->
|
|
102
|
+
|
|
103
|
+
- [ ] GDPR
|
|
104
|
+
- [ ] SOC2
|
|
105
|
+
- [ ] HIPAA
|
|
106
|
+
- [ ] PCI-DSS
|
|
107
|
+
|
|
108
|
+
---
|
|
109
|
+
|
|
110
|
+
## AI Instructions
|
|
111
|
+
|
|
112
|
+
<!-- Special instructions for AI assistants working on this project -->
|
|
113
|
+
|
|
114
|
+
When working on this project, AI assistants should:
|
|
115
|
+
|
|
116
|
+
1.
|
|
117
|
+
2.
|
|
118
|
+
3.
|
|
119
|
+
|
|
120
|
+
---
|
|
121
|
+
|
|
122
|
+
*This file is read by Trie agents and exposed via \`trie://project\` MCP resource.*
|
|
123
|
+
*Edit this file to provide context to Claude Code, Cursor, GitHub Actions, and other AI tools.*
|
|
124
|
+
`;
|
|
125
|
+
}
|
|
126
|
+
function projectInfoExists(workDir) {
|
|
127
|
+
const dir = workDir || getWorkingDirectory(void 0, true);
|
|
128
|
+
const projectPath = join(getTrieDirectory(dir), PROJECT_MD_PATH);
|
|
129
|
+
return existsSync(projectPath);
|
|
130
|
+
}
|
|
131
|
+
async function loadProjectInfo(workDir) {
|
|
132
|
+
const dir = workDir || getWorkingDirectory(void 0, true);
|
|
133
|
+
const projectPath = join(getTrieDirectory(dir), PROJECT_MD_PATH);
|
|
134
|
+
try {
|
|
135
|
+
if (!existsSync(projectPath)) {
|
|
136
|
+
return null;
|
|
137
|
+
}
|
|
138
|
+
return await readFile(projectPath, "utf-8");
|
|
139
|
+
} catch {
|
|
140
|
+
return null;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
async function saveProjectInfo(content, workDir) {
|
|
144
|
+
const dir = workDir || getWorkingDirectory(void 0, true);
|
|
145
|
+
const trieDir = getTrieDirectory(dir);
|
|
146
|
+
const projectPath = join(trieDir, PROJECT_MD_PATH);
|
|
147
|
+
await mkdir(trieDir, { recursive: true });
|
|
148
|
+
await writeFile(projectPath, content, "utf-8");
|
|
149
|
+
}
|
|
150
|
+
async function initProjectInfo(workDir) {
|
|
151
|
+
const dir = workDir || getWorkingDirectory(void 0, true);
|
|
152
|
+
const projectPath = join(getTrieDirectory(dir), PROJECT_MD_PATH);
|
|
153
|
+
if (existsSync(projectPath)) {
|
|
154
|
+
return { created: false, path: projectPath };
|
|
155
|
+
}
|
|
156
|
+
await saveProjectInfo(getProjectTemplate(), dir);
|
|
157
|
+
return { created: true, path: projectPath };
|
|
158
|
+
}
|
|
159
|
+
async function getProjectSection(sectionName, workDir) {
|
|
160
|
+
const content = await loadProjectInfo(workDir);
|
|
161
|
+
if (!content) return null;
|
|
162
|
+
const sectionRegex = new RegExp(
|
|
163
|
+
`## ${escapeRegex(sectionName)}\\s*\\n([\\s\\S]*?)(?=\\n## |\\n---\\s*$|$)`,
|
|
164
|
+
"i"
|
|
165
|
+
);
|
|
166
|
+
const match = content.match(sectionRegex);
|
|
167
|
+
if (match?.[1]) {
|
|
168
|
+
return match[1].trim();
|
|
169
|
+
}
|
|
170
|
+
return null;
|
|
171
|
+
}
|
|
172
|
+
async function updateProjectSection(sectionName, newContent, workDir) {
|
|
173
|
+
let content = await loadProjectInfo(workDir);
|
|
174
|
+
if (!content) {
|
|
175
|
+
await initProjectInfo(workDir);
|
|
176
|
+
content = await loadProjectInfo(workDir);
|
|
177
|
+
if (!content) return false;
|
|
178
|
+
}
|
|
179
|
+
const sectionRegex = new RegExp(
|
|
180
|
+
`(## ${escapeRegex(sectionName)}\\s*\\n)([\\s\\S]*?)((?=\\n## )|(?=\\n---\\s*$)|$)`,
|
|
181
|
+
"i"
|
|
182
|
+
);
|
|
183
|
+
if (content.match(sectionRegex)) {
|
|
184
|
+
const updatedContent = content.replace(sectionRegex, `$1
|
|
185
|
+
${newContent}
|
|
186
|
+
|
|
187
|
+
$3`);
|
|
188
|
+
await saveProjectInfo(updatedContent, workDir);
|
|
189
|
+
return true;
|
|
190
|
+
}
|
|
191
|
+
return false;
|
|
192
|
+
}
|
|
193
|
+
async function appendToSection(sectionName, contentToAdd, workDir) {
|
|
194
|
+
const currentContent = await getProjectSection(sectionName, workDir);
|
|
195
|
+
if (currentContent === null) return false;
|
|
196
|
+
const newContent = currentContent + "\n" + contentToAdd;
|
|
197
|
+
return updateProjectSection(sectionName, newContent, workDir);
|
|
198
|
+
}
|
|
199
|
+
async function getProjectSections(workDir) {
|
|
200
|
+
const content = await loadProjectInfo(workDir);
|
|
201
|
+
if (!content) return [];
|
|
202
|
+
const sectionRegex = /^## (.+)$/gm;
|
|
203
|
+
const sections = [];
|
|
204
|
+
let match;
|
|
205
|
+
while ((match = sectionRegex.exec(content)) !== null) {
|
|
206
|
+
if (match[1]) {
|
|
207
|
+
sections.push(match[1].trim());
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
return sections;
|
|
211
|
+
}
|
|
212
|
+
async function getProjectInfoStructured(workDir) {
|
|
213
|
+
const dir = workDir || getWorkingDirectory(void 0, true);
|
|
214
|
+
const projectPath = join(getTrieDirectory(dir), PROJECT_MD_PATH);
|
|
215
|
+
const content = await loadProjectInfo(dir);
|
|
216
|
+
if (!content) {
|
|
217
|
+
return {
|
|
218
|
+
exists: false,
|
|
219
|
+
path: projectPath,
|
|
220
|
+
sections: {},
|
|
221
|
+
raw: null
|
|
222
|
+
};
|
|
223
|
+
}
|
|
224
|
+
const sectionNames = await getProjectSections(dir);
|
|
225
|
+
const sections = {};
|
|
226
|
+
for (const name of sectionNames) {
|
|
227
|
+
const sectionContent = await getProjectSection(name, dir);
|
|
228
|
+
if (sectionContent) {
|
|
229
|
+
sections[name] = sectionContent;
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
return {
|
|
233
|
+
exists: true,
|
|
234
|
+
path: projectPath,
|
|
235
|
+
sections,
|
|
236
|
+
raw: content
|
|
237
|
+
};
|
|
238
|
+
}
|
|
239
|
+
function escapeRegex(str) {
|
|
240
|
+
return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
// src/cli/checkpoint.ts
|
|
244
|
+
import { existsSync as existsSync2 } from "fs";
|
|
245
|
+
import { mkdir as mkdir2, writeFile as writeFile2, readFile as readFile2 } from "fs/promises";
|
|
246
|
+
import { join as join2 } from "path";
|
|
34
247
|
async function saveCheckpoint(options) {
|
|
35
248
|
const workDir = options.workDir || getWorkingDirectory(void 0, true);
|
|
36
249
|
const trieDir = getTrieDirectory(workDir);
|
|
37
|
-
const checkpointPath =
|
|
38
|
-
await
|
|
250
|
+
const checkpointPath = join2(trieDir, "checkpoints.json");
|
|
251
|
+
await mkdir2(trieDir, { recursive: true });
|
|
39
252
|
let log = { checkpoints: [] };
|
|
40
253
|
try {
|
|
41
|
-
if (
|
|
42
|
-
log = JSON.parse(await
|
|
254
|
+
if (existsSync2(checkpointPath)) {
|
|
255
|
+
log = JSON.parse(await readFile2(checkpointPath, "utf-8"));
|
|
43
256
|
}
|
|
44
257
|
} catch {
|
|
45
258
|
log = { checkpoints: [] };
|
|
@@ -57,16 +270,16 @@ async function saveCheckpoint(options) {
|
|
|
57
270
|
if (log.checkpoints.length > 50) {
|
|
58
271
|
log.checkpoints = log.checkpoints.slice(-50);
|
|
59
272
|
}
|
|
60
|
-
await
|
|
273
|
+
await writeFile2(checkpointPath, JSON.stringify(log, null, 2));
|
|
61
274
|
await updateAgentsMdWithCheckpoint(checkpoint, workDir);
|
|
62
275
|
return checkpoint;
|
|
63
276
|
}
|
|
64
277
|
async function listCheckpoints(workDir) {
|
|
65
278
|
const dir = workDir || getWorkingDirectory(void 0, true);
|
|
66
|
-
const checkpointPath =
|
|
279
|
+
const checkpointPath = join2(getTrieDirectory(dir), "checkpoints.json");
|
|
67
280
|
try {
|
|
68
|
-
if (
|
|
69
|
-
const log = JSON.parse(await
|
|
281
|
+
if (existsSync2(checkpointPath)) {
|
|
282
|
+
const log = JSON.parse(await readFile2(checkpointPath, "utf-8"));
|
|
70
283
|
return log.checkpoints;
|
|
71
284
|
}
|
|
72
285
|
} catch {
|
|
@@ -79,11 +292,11 @@ async function getLastCheckpoint(workDir) {
|
|
|
79
292
|
return last ?? null;
|
|
80
293
|
}
|
|
81
294
|
async function updateAgentsMdWithCheckpoint(checkpoint, workDir) {
|
|
82
|
-
const agentsPath =
|
|
295
|
+
const agentsPath = join2(getTrieDirectory(workDir), "AGENTS.md");
|
|
83
296
|
let content = "";
|
|
84
297
|
try {
|
|
85
|
-
if (
|
|
86
|
-
content = await
|
|
298
|
+
if (existsSync2(agentsPath)) {
|
|
299
|
+
content = await readFile2(agentsPath, "utf-8");
|
|
87
300
|
}
|
|
88
301
|
} catch {
|
|
89
302
|
content = "";
|
|
@@ -103,7 +316,7 @@ ${checkpoint.notes ? `- **Notes:** ${checkpoint.notes}` : ""}
|
|
|
103
316
|
} else {
|
|
104
317
|
content = content.trim() + "\n\n" + checkpointSection.trim() + "\n";
|
|
105
318
|
}
|
|
106
|
-
await
|
|
319
|
+
await writeFile2(agentsPath, content);
|
|
107
320
|
}
|
|
108
321
|
async function handleCheckpointCommand(args) {
|
|
109
322
|
const subcommand = args[0] || "save";
|
|
@@ -198,15 +411,107 @@ async function handleCheckpointCommand(args) {
|
|
|
198
411
|
}
|
|
199
412
|
}
|
|
200
413
|
|
|
201
|
-
// src/
|
|
202
|
-
import { readFile as
|
|
414
|
+
// src/utils/context-state.ts
|
|
415
|
+
import { readFile as readFile3, mkdir as mkdir3 } from "fs/promises";
|
|
203
416
|
import { existsSync as existsSync3 } from "fs";
|
|
204
|
-
import { join as join3,
|
|
417
|
+
import { join as join3, basename } from "path";
|
|
418
|
+
var STATE_JSON_PATH = "state.json";
|
|
419
|
+
async function loadContextState() {
|
|
420
|
+
const workDir = getWorkingDirectory(void 0, true);
|
|
421
|
+
const statePath = join3(getTrieDirectory(workDir), STATE_JSON_PATH);
|
|
422
|
+
const defaults = getDefaultState();
|
|
423
|
+
try {
|
|
424
|
+
if (existsSync3(statePath)) {
|
|
425
|
+
const content = await readFile3(statePath, "utf-8");
|
|
426
|
+
const loaded = JSON.parse(content);
|
|
427
|
+
return {
|
|
428
|
+
...defaults,
|
|
429
|
+
...loaded,
|
|
430
|
+
skills: loaded.skills || defaults.skills
|
|
431
|
+
};
|
|
432
|
+
}
|
|
433
|
+
} catch {
|
|
434
|
+
}
|
|
435
|
+
return defaults;
|
|
436
|
+
}
|
|
437
|
+
function getDefaultState() {
|
|
438
|
+
return {
|
|
439
|
+
lastScan: null,
|
|
440
|
+
healthScore: 0,
|
|
441
|
+
activePriorities: [
|
|
442
|
+
"Initial setup required - run first scan with `trie scan`",
|
|
443
|
+
"Configure agents in `.trie/config.json`",
|
|
444
|
+
"Set up CI/CD integration"
|
|
445
|
+
],
|
|
446
|
+
contextSignals: {},
|
|
447
|
+
agentStatus: {},
|
|
448
|
+
scanHistory: [],
|
|
449
|
+
customAgents: [],
|
|
450
|
+
skills: {},
|
|
451
|
+
environment: detectEnvironment()
|
|
452
|
+
};
|
|
453
|
+
}
|
|
454
|
+
function detectEnvironment() {
|
|
455
|
+
if (process.env.GITHUB_ACTIONS) return "github-actions";
|
|
456
|
+
if (process.env.GITLAB_CI) return "gitlab-ci";
|
|
457
|
+
if (process.env.CI) return "ci";
|
|
458
|
+
const parent = process.env._ || "";
|
|
459
|
+
if (parent.includes("cursor")) return "cursor";
|
|
460
|
+
if (parent.includes("claude")) return "claude-code";
|
|
461
|
+
return "cli";
|
|
462
|
+
}
|
|
463
|
+
async function getContextForAI() {
|
|
464
|
+
const state = await loadContextState();
|
|
465
|
+
const workDir = getWorkingDirectory(void 0, true);
|
|
466
|
+
const lines = [];
|
|
467
|
+
if (projectInfoExists(workDir)) {
|
|
468
|
+
const projectInfo = await loadProjectInfo(workDir);
|
|
469
|
+
if (projectInfo) {
|
|
470
|
+
lines.push(projectInfo);
|
|
471
|
+
lines.push("");
|
|
472
|
+
lines.push("---");
|
|
473
|
+
lines.push("");
|
|
474
|
+
}
|
|
475
|
+
}
|
|
476
|
+
lines.push(
|
|
477
|
+
"## Trie Scan Context",
|
|
478
|
+
"",
|
|
479
|
+
`**Health Score:** ${state.healthScore}%`,
|
|
480
|
+
`**Last Scan:** ${state.lastScan ? new Date(state.lastScan.timestamp).toLocaleString() : "Never"}`,
|
|
481
|
+
"",
|
|
482
|
+
"**Active Priorities:**",
|
|
483
|
+
...state.activePriorities.map((p) => `- ${p}`),
|
|
484
|
+
""
|
|
485
|
+
);
|
|
486
|
+
if (state.lastScan) {
|
|
487
|
+
lines.push(
|
|
488
|
+
"**Recent Issues:**",
|
|
489
|
+
`- Critical: ${state.lastScan.issues.critical}`,
|
|
490
|
+
`- Serious: ${state.lastScan.issues.serious}`,
|
|
491
|
+
`- Moderate: ${state.lastScan.issues.moderate}`,
|
|
492
|
+
`- Low: ${state.lastScan.issues.low}`,
|
|
493
|
+
""
|
|
494
|
+
);
|
|
495
|
+
if (state.lastScan.hotFiles.length > 0) {
|
|
496
|
+
lines.push(
|
|
497
|
+
"**Hot Files (most issues):**",
|
|
498
|
+
...state.lastScan.hotFiles.slice(0, 5).map((f) => `- ${f.file}: ${f.issueCount} issues`),
|
|
499
|
+
""
|
|
500
|
+
);
|
|
501
|
+
}
|
|
502
|
+
}
|
|
503
|
+
return lines.join("\n");
|
|
504
|
+
}
|
|
505
|
+
|
|
506
|
+
// src/config/loader.ts
|
|
507
|
+
import { readFile as readFile4, writeFile as writeFile3, mkdir as mkdir4 } from "fs/promises";
|
|
508
|
+
import { existsSync as existsSync5 } from "fs";
|
|
509
|
+
import { join as join5, dirname } from "path";
|
|
205
510
|
|
|
206
511
|
// src/config/validation.ts
|
|
207
512
|
import { z } from "zod";
|
|
208
|
-
import { existsSync as
|
|
209
|
-
import { resolve, join as
|
|
513
|
+
import { existsSync as existsSync4, readFileSync } from "fs";
|
|
514
|
+
import { resolve, join as join4 } from "path";
|
|
210
515
|
var API_KEY_PATTERNS = {
|
|
211
516
|
anthropic: /^sk-ant-api\d{2}-[\w-]{95}$/,
|
|
212
517
|
openai: /^sk-[\w]{48}$/,
|
|
@@ -342,8 +647,8 @@ var ConfigValidator = class {
|
|
|
342
647
|
let anthropicKey = process.env.ANTHROPIC_API_KEY;
|
|
343
648
|
if (!anthropicKey) {
|
|
344
649
|
try {
|
|
345
|
-
const configPath =
|
|
346
|
-
if (
|
|
650
|
+
const configPath = join4(getTrieDirectory(getWorkingDirectory(void 0, true)), "config.json");
|
|
651
|
+
if (existsSync4(configPath)) {
|
|
347
652
|
const config = JSON.parse(readFileSync(configPath, "utf-8"));
|
|
348
653
|
anthropicKey = config.apiKeys?.anthropic;
|
|
349
654
|
}
|
|
@@ -373,14 +678,14 @@ var ConfigValidator = class {
|
|
|
373
678
|
if (paths?.include) {
|
|
374
679
|
for (const path8 of paths.include) {
|
|
375
680
|
const resolvedPath = resolve(path8);
|
|
376
|
-
if (!
|
|
681
|
+
if (!existsSync4(resolvedPath)) {
|
|
377
682
|
errors.push(`Include path does not exist: ${path8}`);
|
|
378
683
|
}
|
|
379
684
|
}
|
|
380
685
|
}
|
|
381
686
|
if (paths?.configDir) {
|
|
382
687
|
const configPath = resolve(paths.configDir);
|
|
383
|
-
if (!
|
|
688
|
+
if (!existsSync4(configPath)) {
|
|
384
689
|
try {
|
|
385
690
|
__require("fs").mkdirSync(configPath, { recursive: true });
|
|
386
691
|
} catch {
|
|
@@ -500,8 +805,8 @@ var ConfigValidator = class {
|
|
|
500
805
|
const workDir = getWorkingDirectory(void 0, true);
|
|
501
806
|
const envFiles = [".env", ".env.local", ".env.production"];
|
|
502
807
|
for (const envFile of envFiles) {
|
|
503
|
-
const envPath =
|
|
504
|
-
if (
|
|
808
|
+
const envPath = join4(workDir, envFile);
|
|
809
|
+
if (existsSync4(envPath)) {
|
|
505
810
|
const envContent = readFileSync(envPath, "utf-8");
|
|
506
811
|
if (envContent.includes("ANTHROPIC_API_KEY=")) {
|
|
507
812
|
hasApiKey = true;
|
|
@@ -578,12 +883,12 @@ var DEFAULT_CONFIG = {
|
|
|
578
883
|
// src/config/loader.ts
|
|
579
884
|
async function loadConfig() {
|
|
580
885
|
const validator = new ConfigValidator();
|
|
581
|
-
const configPath =
|
|
886
|
+
const configPath = join5(getTrieDirectory(getWorkingDirectory(void 0, true)), "config.json");
|
|
582
887
|
try {
|
|
583
|
-
if (!
|
|
888
|
+
if (!existsSync5(configPath)) {
|
|
584
889
|
return DEFAULT_CONFIG;
|
|
585
890
|
}
|
|
586
|
-
const configFile = await
|
|
891
|
+
const configFile = await readFile4(configPath, "utf-8");
|
|
587
892
|
const userConfig = JSON.parse(configFile);
|
|
588
893
|
const merged = mergeConfig(DEFAULT_CONFIG, userConfig);
|
|
589
894
|
const result = validator.validateConfig(merged);
|
|
@@ -614,12 +919,12 @@ async function loadConfig() {
|
|
|
614
919
|
}
|
|
615
920
|
}
|
|
616
921
|
async function saveConfig(config) {
|
|
617
|
-
const configPath =
|
|
922
|
+
const configPath = join5(getTrieDirectory(getWorkingDirectory(void 0, true)), "config.json");
|
|
618
923
|
const dir = dirname(configPath);
|
|
619
|
-
if (!
|
|
620
|
-
await
|
|
924
|
+
if (!existsSync5(dir)) {
|
|
925
|
+
await mkdir4(dir, { recursive: true });
|
|
621
926
|
}
|
|
622
|
-
await
|
|
927
|
+
await writeFile3(configPath, JSON.stringify(config, null, 2), "utf-8");
|
|
623
928
|
}
|
|
624
929
|
function mergeConfig(defaults, user) {
|
|
625
930
|
if (typeof user !== "object" || user === null || Array.isArray(user)) {
|
|
@@ -638,9 +943,9 @@ function mergeConfig(defaults, user) {
|
|
|
638
943
|
}
|
|
639
944
|
|
|
640
945
|
// src/utils/autonomy-config.ts
|
|
641
|
-
import { readFile as
|
|
642
|
-
import { existsSync as
|
|
643
|
-
import { join as
|
|
946
|
+
import { readFile as readFile5, writeFile as writeFile4, mkdir as mkdir5 } from "fs/promises";
|
|
947
|
+
import { existsSync as existsSync6 } from "fs";
|
|
948
|
+
import { join as join6 } from "path";
|
|
644
949
|
|
|
645
950
|
// src/types/autonomy.ts
|
|
646
951
|
var DEFAULT_AUTONOMY_CONFIG = {
|
|
@@ -687,12 +992,12 @@ var DEFAULT_AUTONOMY_CONFIG = {
|
|
|
687
992
|
// src/utils/autonomy-config.ts
|
|
688
993
|
import { createHash } from "crypto";
|
|
689
994
|
async function loadAutonomyConfig(projectPath) {
|
|
690
|
-
const configPath =
|
|
995
|
+
const configPath = join6(getTrieDirectory(projectPath), "config.json");
|
|
691
996
|
try {
|
|
692
|
-
if (!
|
|
997
|
+
if (!existsSync6(configPath)) {
|
|
693
998
|
return { ...DEFAULT_AUTONOMY_CONFIG };
|
|
694
999
|
}
|
|
695
|
-
const content = await
|
|
1000
|
+
const content = await readFile5(configPath, "utf-8");
|
|
696
1001
|
const config = JSON.parse(content);
|
|
697
1002
|
return mergeWithDefaults(config.autonomy || {});
|
|
698
1003
|
} catch (error) {
|
|
@@ -730,11 +1035,11 @@ async function getOccurrences(projectPath) {
|
|
|
730
1035
|
if (occurrenceCache.has(projectPath)) {
|
|
731
1036
|
return occurrenceCache.get(projectPath);
|
|
732
1037
|
}
|
|
733
|
-
const occurrencesPath =
|
|
1038
|
+
const occurrencesPath = join6(getTrieDirectory(projectPath), "memory", "occurrences.json");
|
|
734
1039
|
const occurrences = /* @__PURE__ */ new Map();
|
|
735
1040
|
try {
|
|
736
|
-
if (
|
|
737
|
-
const content = await
|
|
1041
|
+
if (existsSync6(occurrencesPath)) {
|
|
1042
|
+
const content = await readFile5(occurrencesPath, "utf-8");
|
|
738
1043
|
const data = JSON.parse(content);
|
|
739
1044
|
for (const [hash, occ] of Object.entries(data)) {
|
|
740
1045
|
occurrences.set(hash, occ);
|
|
@@ -748,17 +1053,17 @@ async function getOccurrences(projectPath) {
|
|
|
748
1053
|
async function saveOccurrences(projectPath) {
|
|
749
1054
|
const occurrences = occurrenceCache.get(projectPath);
|
|
750
1055
|
if (!occurrences) return;
|
|
751
|
-
const occurrencesPath =
|
|
752
|
-
const memoryDir =
|
|
1056
|
+
const occurrencesPath = join6(getTrieDirectory(projectPath), "memory", "occurrences.json");
|
|
1057
|
+
const memoryDir = join6(getTrieDirectory(projectPath), "memory");
|
|
753
1058
|
try {
|
|
754
|
-
if (!
|
|
755
|
-
await
|
|
1059
|
+
if (!existsSync6(memoryDir)) {
|
|
1060
|
+
await mkdir5(memoryDir, { recursive: true });
|
|
756
1061
|
}
|
|
757
1062
|
const data = {};
|
|
758
1063
|
for (const [hash, occ] of occurrences.entries()) {
|
|
759
1064
|
data[hash] = occ;
|
|
760
1065
|
}
|
|
761
|
-
await
|
|
1066
|
+
await writeFile4(occurrencesPath, JSON.stringify(data, null, 2));
|
|
762
1067
|
} catch (error) {
|
|
763
1068
|
console.error("Failed to save occurrences:", error);
|
|
764
1069
|
}
|
|
@@ -905,9 +1210,158 @@ async function getAutonomyConfig(projectPath) {
|
|
|
905
1210
|
return config;
|
|
906
1211
|
}
|
|
907
1212
|
|
|
1213
|
+
// src/skills/audit-logger.ts
|
|
1214
|
+
function formatAuditLog(_entry) {
|
|
1215
|
+
return "Audit logging has been integrated into the decision ledger";
|
|
1216
|
+
}
|
|
1217
|
+
function getAuditStatistics() {
|
|
1218
|
+
return {
|
|
1219
|
+
totalScans: 0,
|
|
1220
|
+
totalIssues: 0,
|
|
1221
|
+
criticalCount: 0,
|
|
1222
|
+
seriousCount: 0,
|
|
1223
|
+
moderateCount: 0,
|
|
1224
|
+
lowCount: 0,
|
|
1225
|
+
totalExecutions: 0,
|
|
1226
|
+
successfulExecutions: 0,
|
|
1227
|
+
failedExecutions: 0,
|
|
1228
|
+
uniqueSkills: 0,
|
|
1229
|
+
totalCommands: 0,
|
|
1230
|
+
blockedCommands: 0,
|
|
1231
|
+
totalNetworkCalls: 0,
|
|
1232
|
+
blockedNetworkCalls: 0
|
|
1233
|
+
};
|
|
1234
|
+
}
|
|
1235
|
+
function createAuditEntry(skillName, skillSource, triggeredBy, targetPath) {
|
|
1236
|
+
return {
|
|
1237
|
+
skillName,
|
|
1238
|
+
skillSource,
|
|
1239
|
+
triggeredBy,
|
|
1240
|
+
targetPath,
|
|
1241
|
+
startedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1242
|
+
commands: []
|
|
1243
|
+
};
|
|
1244
|
+
}
|
|
1245
|
+
function completeAuditEntry(entry, success, error) {
|
|
1246
|
+
const result = {
|
|
1247
|
+
...entry,
|
|
1248
|
+
completedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1249
|
+
success
|
|
1250
|
+
};
|
|
1251
|
+
if (error !== void 0) {
|
|
1252
|
+
result.error = error;
|
|
1253
|
+
}
|
|
1254
|
+
return result;
|
|
1255
|
+
}
|
|
1256
|
+
async function logSkillExecution(_execution) {
|
|
1257
|
+
}
|
|
1258
|
+
async function getRecentAuditLogs(_limit = 10) {
|
|
1259
|
+
return [];
|
|
1260
|
+
}
|
|
1261
|
+
async function getSkillAuditLogs(_skillName) {
|
|
1262
|
+
return [];
|
|
1263
|
+
}
|
|
1264
|
+
|
|
908
1265
|
// src/agent/git.ts
|
|
909
|
-
import { existsSync as
|
|
1266
|
+
import { existsSync as existsSync7 } from "fs";
|
|
910
1267
|
import path from "path";
|
|
1268
|
+
|
|
1269
|
+
// src/utils/command-runner.ts
|
|
1270
|
+
import { exec, execFile, execSync } from "child_process";
|
|
1271
|
+
import { promisify } from "util";
|
|
1272
|
+
var execAsync = promisify(exec);
|
|
1273
|
+
var execFileAsync = promisify(execFile);
|
|
1274
|
+
function redact(text) {
|
|
1275
|
+
return text.replace(/\b(AWS|ANTHROPIC|OPENAI|GITHUB)_[A-Z0-9_]*\s*=\s*([^\s"'`]+)/gi, "$1_<REDACTED>=<REDACTED>").replace(/\bBearer\s+[A-Za-z0-9\-._~+/]+=*\b/g, "Bearer <REDACTED>").replace(/\bghp_[A-Za-z0-9]{20,}\b/g, "ghp_<REDACTED>").replace(/\b(?:xox[baprs]-)[A-Za-z0-9-]{10,}\b/g, "<REDACTED_SLACK_TOKEN>").replace(/\bAKIA[0-9A-Z]{16}\b/g, "AKIA<REDACTED>");
|
|
1276
|
+
}
|
|
1277
|
+
function clampOutput(text, maxChars) {
|
|
1278
|
+
if (text.length <= maxChars) return text;
|
|
1279
|
+
return text.slice(0, maxChars) + `
|
|
1280
|
+
\u2026(truncated ${text.length - maxChars} chars)`;
|
|
1281
|
+
}
|
|
1282
|
+
function buildCommandRecord(command) {
|
|
1283
|
+
return {
|
|
1284
|
+
command,
|
|
1285
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
1286
|
+
};
|
|
1287
|
+
}
|
|
1288
|
+
async function finalizeAndWrite(entry, cmd, outcome, options) {
|
|
1289
|
+
const duration = Date.now() - outcome.startedAt;
|
|
1290
|
+
cmd.duration = duration;
|
|
1291
|
+
if (outcome.exitCode !== void 0) {
|
|
1292
|
+
cmd.exitCode = outcome.exitCode;
|
|
1293
|
+
}
|
|
1294
|
+
const captureOutput = options?.captureOutput ?? false;
|
|
1295
|
+
const redactOutput = options?.redactOutput ?? true;
|
|
1296
|
+
const maxOutputChars = options?.maxOutputChars ?? 2e3;
|
|
1297
|
+
if (captureOutput) {
|
|
1298
|
+
const out = outcome.stdout ?? "";
|
|
1299
|
+
const err = outcome.stderr ?? "";
|
|
1300
|
+
cmd.stdout = redactOutput ? redact(clampOutput(out, maxOutputChars)) : clampOutput(out, maxOutputChars);
|
|
1301
|
+
cmd.stderr = redactOutput ? redact(clampOutput(err, maxOutputChars)) : clampOutput(err, maxOutputChars);
|
|
1302
|
+
}
|
|
1303
|
+
const completed = completeAuditEntry(entry, outcome.success, outcome.error);
|
|
1304
|
+
await logSkillExecution(completed);
|
|
1305
|
+
}
|
|
1306
|
+
function runShellCommandSync(command, audit, options) {
|
|
1307
|
+
const startedAt = Date.now();
|
|
1308
|
+
const entry = createAuditEntry(audit.actor, audit.source ?? "trie", audit.triggeredBy, audit.targetPath);
|
|
1309
|
+
const cmd = buildCommandRecord(command);
|
|
1310
|
+
entry.commands?.push(cmd);
|
|
1311
|
+
try {
|
|
1312
|
+
const stdout = execSync(command, {
|
|
1313
|
+
cwd: options?.cwd,
|
|
1314
|
+
timeout: options?.timeoutMs,
|
|
1315
|
+
maxBuffer: options?.maxBuffer,
|
|
1316
|
+
encoding: "utf-8",
|
|
1317
|
+
stdio: ["pipe", "pipe", "pipe"]
|
|
1318
|
+
});
|
|
1319
|
+
void finalizeAndWrite(entry, cmd, { success: true, exitCode: 0, stdout, stderr: "", startedAt }, options);
|
|
1320
|
+
return { stdout: stdout ?? "", exitCode: 0 };
|
|
1321
|
+
} catch (e) {
|
|
1322
|
+
const err = e;
|
|
1323
|
+
const stdout = typeof err.stdout === "string" ? err.stdout : "";
|
|
1324
|
+
const stderr = typeof err.stderr === "string" ? err.stderr : "";
|
|
1325
|
+
const exitCode = typeof err.status === "number" ? err.status : 1;
|
|
1326
|
+
void finalizeAndWrite(
|
|
1327
|
+
entry,
|
|
1328
|
+
cmd,
|
|
1329
|
+
{ success: false, exitCode, stdout, stderr, error: err.message, startedAt },
|
|
1330
|
+
{ ...options, captureOutput: options?.captureOutput ?? true }
|
|
1331
|
+
);
|
|
1332
|
+
return { stdout, exitCode };
|
|
1333
|
+
}
|
|
1334
|
+
}
|
|
1335
|
+
async function runExecFile(file, args, audit, options) {
|
|
1336
|
+
const startedAt = Date.now();
|
|
1337
|
+
const command = [file, ...args].join(" ");
|
|
1338
|
+
const entry = createAuditEntry(audit.actor, audit.source ?? "trie", audit.triggeredBy, audit.targetPath);
|
|
1339
|
+
const cmd = buildCommandRecord(command);
|
|
1340
|
+
entry.commands?.push(cmd);
|
|
1341
|
+
try {
|
|
1342
|
+
const { stdout, stderr } = await execFileAsync(file, args, {
|
|
1343
|
+
cwd: options?.cwd,
|
|
1344
|
+
timeout: options?.timeoutMs,
|
|
1345
|
+
maxBuffer: options?.maxBuffer
|
|
1346
|
+
});
|
|
1347
|
+
await finalizeAndWrite(entry, cmd, { success: true, exitCode: 0, stdout: String(stdout ?? ""), stderr: String(stderr ?? ""), startedAt }, options);
|
|
1348
|
+
return { stdout: String(stdout ?? ""), stderr: String(stderr ?? ""), exitCode: 0 };
|
|
1349
|
+
} catch (e) {
|
|
1350
|
+
const err = e;
|
|
1351
|
+
const stdout = typeof err.stdout === "string" ? err.stdout : "";
|
|
1352
|
+
const stderr = typeof err.stderr === "string" ? err.stderr : "";
|
|
1353
|
+
const exitCode = typeof err.code === "number" ? err.code : 1;
|
|
1354
|
+
await finalizeAndWrite(
|
|
1355
|
+
entry,
|
|
1356
|
+
cmd,
|
|
1357
|
+
{ success: false, exitCode, stdout, stderr, error: err.message, startedAt },
|
|
1358
|
+
{ ...options, captureOutput: options?.captureOutput ?? true }
|
|
1359
|
+
);
|
|
1360
|
+
return { stdout, stderr, exitCode };
|
|
1361
|
+
}
|
|
1362
|
+
}
|
|
1363
|
+
|
|
1364
|
+
// src/agent/git.ts
|
|
911
1365
|
async function execGit(args, cwd) {
|
|
912
1366
|
try {
|
|
913
1367
|
const { stdout } = await runExecFile(
|
|
@@ -1265,7 +1719,7 @@ var Triager = class {
|
|
|
1265
1719
|
// src/utils/parallel-executor.ts
|
|
1266
1720
|
import { Worker } from "worker_threads";
|
|
1267
1721
|
import { cpus } from "os";
|
|
1268
|
-
import { existsSync as
|
|
1722
|
+
import { existsSync as existsSync8 } from "fs";
|
|
1269
1723
|
import { fileURLToPath } from "url";
|
|
1270
1724
|
var ParallelExecutor = class {
|
|
1271
1725
|
maxWorkers;
|
|
@@ -1422,7 +1876,7 @@ var ParallelExecutor = class {
|
|
|
1422
1876
|
return this.workerAvailable;
|
|
1423
1877
|
}
|
|
1424
1878
|
const workerUrl = this.getWorkerUrl();
|
|
1425
|
-
this.workerAvailable =
|
|
1879
|
+
this.workerAvailable = existsSync8(fileURLToPath(workerUrl));
|
|
1426
1880
|
if (!this.workerAvailable && !this.warnedWorkerFallback && !isInteractiveMode()) {
|
|
1427
1881
|
console.error("Worker threads unavailable; falling back to in-process agents.");
|
|
1428
1882
|
this.warnedWorkerFallback = true;
|
|
@@ -1521,8 +1975,8 @@ function calculateOptimalConcurrency() {
|
|
|
1521
1975
|
}
|
|
1522
1976
|
|
|
1523
1977
|
// src/utils/cache-manager.ts
|
|
1524
|
-
import { readFile as
|
|
1525
|
-
import { join as
|
|
1978
|
+
import { readFile as readFile6, writeFile as writeFile5, mkdir as mkdir6, stat } from "fs/promises";
|
|
1979
|
+
import { join as join7 } from "path";
|
|
1526
1980
|
import { createHash as createHash2 } from "crypto";
|
|
1527
1981
|
var CacheManager = class {
|
|
1528
1982
|
cacheDir;
|
|
@@ -1532,8 +1986,8 @@ var CacheManager = class {
|
|
|
1532
1986
|
// 24 hours
|
|
1533
1987
|
MAX_ENTRIES = 1e3;
|
|
1534
1988
|
constructor(baseDir) {
|
|
1535
|
-
this.cacheDir =
|
|
1536
|
-
this.indexPath =
|
|
1989
|
+
this.cacheDir = join7(getTrieDirectory(baseDir), "cache");
|
|
1990
|
+
this.indexPath = join7(this.cacheDir, "index.json");
|
|
1537
1991
|
}
|
|
1538
1992
|
/**
|
|
1539
1993
|
* Generate cache key for a file and agent combination
|
|
@@ -1547,7 +2001,7 @@ var CacheManager = class {
|
|
|
1547
2001
|
*/
|
|
1548
2002
|
async getFileHash(filePath) {
|
|
1549
2003
|
try {
|
|
1550
|
-
const content = await
|
|
2004
|
+
const content = await readFile6(filePath, "utf-8");
|
|
1551
2005
|
const stats = await stat(filePath);
|
|
1552
2006
|
const hash = createHash2("sha256").update(content).digest("hex").slice(0, 16);
|
|
1553
2007
|
return {
|
|
@@ -1564,7 +2018,7 @@ var CacheManager = class {
|
|
|
1564
2018
|
*/
|
|
1565
2019
|
async loadIndex() {
|
|
1566
2020
|
try {
|
|
1567
|
-
const content = await
|
|
2021
|
+
const content = await readFile6(this.indexPath, "utf-8");
|
|
1568
2022
|
return JSON.parse(content);
|
|
1569
2023
|
} catch {
|
|
1570
2024
|
return {
|
|
@@ -1579,8 +2033,8 @@ var CacheManager = class {
|
|
|
1579
2033
|
*/
|
|
1580
2034
|
async saveIndex(index) {
|
|
1581
2035
|
try {
|
|
1582
|
-
await
|
|
1583
|
-
await
|
|
2036
|
+
await mkdir6(this.cacheDir, { recursive: true });
|
|
2037
|
+
await writeFile5(this.indexPath, JSON.stringify(index, null, 2));
|
|
1584
2038
|
} catch (error) {
|
|
1585
2039
|
if (!isInteractiveMode()) {
|
|
1586
2040
|
console.warn("Failed to save cache index:", error);
|
|
@@ -1969,9 +2423,9 @@ async function reasonAboutChangesHumanReadable(projectPath, files, options = {})
|
|
|
1969
2423
|
}
|
|
1970
2424
|
|
|
1971
2425
|
// src/bootstrap/stack-detector.ts
|
|
1972
|
-
import { readFile as
|
|
1973
|
-
import { existsSync as
|
|
1974
|
-
import { join as
|
|
2426
|
+
import { readFile as readFile7 } from "fs/promises";
|
|
2427
|
+
import { existsSync as existsSync9 } from "fs";
|
|
2428
|
+
import { join as join8 } from "path";
|
|
1975
2429
|
var SKILL_MAPPINGS = {
|
|
1976
2430
|
// Frontend Frameworks - React/Next.js
|
|
1977
2431
|
"next": [
|
|
@@ -2278,40 +2732,39 @@ async function detectStack(projectDir) {
|
|
|
2278
2732
|
suggestedAgents: ["security", "bugs"],
|
|
2279
2733
|
dependencies: /* @__PURE__ */ new Set()
|
|
2280
2734
|
};
|
|
2281
|
-
if (
|
|
2735
|
+
if (existsSync9(join8(projectDir, "tsconfig.json"))) {
|
|
2282
2736
|
stack.language = "TypeScript";
|
|
2283
|
-
stack.suggestedAgents.push("typecheck");
|
|
2284
2737
|
stack.suggestedSkills.push("wshobson/agents typescript-advanced-types");
|
|
2285
|
-
} else if (
|
|
2738
|
+
} else if (existsSync9(join8(projectDir, "package.json"))) {
|
|
2286
2739
|
stack.language = "JavaScript";
|
|
2287
|
-
} else if (
|
|
2740
|
+
} else if (existsSync9(join8(projectDir, "requirements.txt")) || existsSync9(join8(projectDir, "pyproject.toml"))) {
|
|
2288
2741
|
stack.language = "Python";
|
|
2289
|
-
} else if (
|
|
2742
|
+
} else if (existsSync9(join8(projectDir, "go.mod"))) {
|
|
2290
2743
|
stack.language = "Go";
|
|
2291
|
-
} else if (
|
|
2744
|
+
} else if (existsSync9(join8(projectDir, "Cargo.toml"))) {
|
|
2292
2745
|
stack.language = "Rust";
|
|
2293
2746
|
}
|
|
2294
|
-
if (
|
|
2747
|
+
if (existsSync9(join8(projectDir, "Package.swift")) || existsSync9(join8(projectDir, "project.pbxproj")) || existsSync9(join8(projectDir, "*.xcodeproj"))) {
|
|
2295
2748
|
stack.language = "Swift";
|
|
2296
2749
|
stack.suggestedSkills.push("dimillian/skills swiftui-ui-patterns");
|
|
2297
2750
|
stack.suggestedSkills.push("dimillian/skills swiftui-liquid-glass");
|
|
2298
2751
|
}
|
|
2299
|
-
if (
|
|
2752
|
+
if (existsSync9(join8(projectDir, "pnpm-lock.yaml"))) {
|
|
2300
2753
|
stack.packageManager = "pnpm";
|
|
2301
|
-
} else if (
|
|
2754
|
+
} else if (existsSync9(join8(projectDir, "yarn.lock"))) {
|
|
2302
2755
|
stack.packageManager = "yarn";
|
|
2303
|
-
} else if (
|
|
2756
|
+
} else if (existsSync9(join8(projectDir, "bun.lockb"))) {
|
|
2304
2757
|
stack.packageManager = "bun";
|
|
2305
|
-
} else if (
|
|
2758
|
+
} else if (existsSync9(join8(projectDir, "package-lock.json"))) {
|
|
2306
2759
|
stack.packageManager = "npm";
|
|
2307
2760
|
}
|
|
2308
|
-
if (
|
|
2761
|
+
if (existsSync9(join8(projectDir, ".github", "workflows"))) {
|
|
2309
2762
|
stack.suggestedSkills.push("wshobson/agents github-actions-templates");
|
|
2310
2763
|
}
|
|
2311
2764
|
try {
|
|
2312
|
-
const pkgPath =
|
|
2313
|
-
if (
|
|
2314
|
-
const pkgContent = await
|
|
2765
|
+
const pkgPath = join8(projectDir, "package.json");
|
|
2766
|
+
if (existsSync9(pkgPath)) {
|
|
2767
|
+
const pkgContent = await readFile7(pkgPath, "utf-8");
|
|
2315
2768
|
const pkg = JSON.parse(pkgContent);
|
|
2316
2769
|
const deps = { ...pkg.dependencies, ...pkg.devDependencies };
|
|
2317
2770
|
for (const dep of Object.keys(deps)) {
|
|
@@ -2368,16 +2821,13 @@ async function detectStack(projectDir) {
|
|
|
2368
2821
|
} else if (deps["convex"]) {
|
|
2369
2822
|
stack.database = "Convex";
|
|
2370
2823
|
}
|
|
2371
|
-
if (deps["stripe"] || deps["@stripe/stripe-js"]) {
|
|
2372
|
-
stack.suggestedAgents.push("moneybags");
|
|
2373
|
-
}
|
|
2374
2824
|
}
|
|
2375
2825
|
} catch {
|
|
2376
2826
|
}
|
|
2377
2827
|
if (!stack.database) {
|
|
2378
|
-
if (
|
|
2828
|
+
if (existsSync9(join8(projectDir, "prisma", "schema.prisma"))) {
|
|
2379
2829
|
stack.database = "Prisma ORM";
|
|
2380
|
-
} else if (
|
|
2830
|
+
} else if (existsSync9(join8(projectDir, "drizzle.config.ts"))) {
|
|
2381
2831
|
stack.database = "Drizzle ORM";
|
|
2382
2832
|
}
|
|
2383
2833
|
}
|
|
@@ -2393,9 +2843,9 @@ function getSkillCategories() {
|
|
|
2393
2843
|
}
|
|
2394
2844
|
|
|
2395
2845
|
// src/bootstrap/files.ts
|
|
2396
|
-
import { readFile as
|
|
2397
|
-
import { existsSync as
|
|
2398
|
-
import { join as
|
|
2846
|
+
import { readFile as readFile8, writeFile as writeFile6, unlink, mkdir as mkdir7 } from "fs/promises";
|
|
2847
|
+
import { existsSync as existsSync10 } from "fs";
|
|
2848
|
+
import { join as join9 } from "path";
|
|
2399
2849
|
var BOOTSTRAP_FILES = [
|
|
2400
2850
|
{ name: "PROJECT.md", type: "user", description: "Project overview and conventions" },
|
|
2401
2851
|
{ name: "RULES.md", type: "user", description: "Coding standards agents enforce" },
|
|
@@ -2410,15 +2860,15 @@ async function loadBootstrapContext(workDir) {
|
|
|
2410
2860
|
const contentParts = [];
|
|
2411
2861
|
let needsBootstrap2 = false;
|
|
2412
2862
|
for (const file of BOOTSTRAP_FILES) {
|
|
2413
|
-
const filePath =
|
|
2414
|
-
const exists =
|
|
2863
|
+
const filePath = join9(trieDir, file.name);
|
|
2864
|
+
const exists = existsSync10(filePath);
|
|
2415
2865
|
if (file.name === "BOOTSTRAP.md" && exists) {
|
|
2416
2866
|
needsBootstrap2 = true;
|
|
2417
2867
|
}
|
|
2418
2868
|
let content;
|
|
2419
2869
|
if (exists) {
|
|
2420
2870
|
try {
|
|
2421
|
-
content = await
|
|
2871
|
+
content = await readFile8(filePath, "utf-8");
|
|
2422
2872
|
if (content.trim() && file.type !== "one-time") {
|
|
2423
2873
|
contentParts.push(`<!-- ${file.name} -->
|
|
2424
2874
|
${content}`);
|
|
@@ -2444,13 +2894,13 @@ ${content}`);
|
|
|
2444
2894
|
async function initializeBootstrapFiles(options = {}) {
|
|
2445
2895
|
const projectDir = options.workDir || getWorkingDirectory(void 0, true);
|
|
2446
2896
|
const trieDir = getTrieDirectory(projectDir);
|
|
2447
|
-
await
|
|
2897
|
+
await mkdir7(trieDir, { recursive: true });
|
|
2448
2898
|
const created = [];
|
|
2449
2899
|
const skipped = [];
|
|
2450
2900
|
const stack = await detectStack(projectDir);
|
|
2451
2901
|
for (const file of BOOTSTRAP_FILES) {
|
|
2452
|
-
const filePath =
|
|
2453
|
-
const exists =
|
|
2902
|
+
const filePath = join9(trieDir, file.name);
|
|
2903
|
+
const exists = existsSync10(filePath);
|
|
2454
2904
|
if (exists && !options.force) {
|
|
2455
2905
|
skipped.push(file.name);
|
|
2456
2906
|
continue;
|
|
@@ -2465,7 +2915,7 @@ async function initializeBootstrapFiles(options = {}) {
|
|
|
2465
2915
|
}
|
|
2466
2916
|
const template = getFileTemplate(file.name, stack);
|
|
2467
2917
|
if (template) {
|
|
2468
|
-
await
|
|
2918
|
+
await writeFile6(filePath, template);
|
|
2469
2919
|
created.push(file.name);
|
|
2470
2920
|
}
|
|
2471
2921
|
}
|
|
@@ -2473,7 +2923,7 @@ async function initializeBootstrapFiles(options = {}) {
|
|
|
2473
2923
|
}
|
|
2474
2924
|
async function completeBootstrap(workDir) {
|
|
2475
2925
|
const projectDir = workDir || getWorkingDirectory(void 0, true);
|
|
2476
|
-
const bootstrapPath =
|
|
2926
|
+
const bootstrapPath = join9(getTrieDirectory(projectDir), "BOOTSTRAP.md");
|
|
2477
2927
|
try {
|
|
2478
2928
|
await unlink(bootstrapPath);
|
|
2479
2929
|
return true;
|
|
@@ -2483,15 +2933,15 @@ async function completeBootstrap(workDir) {
|
|
|
2483
2933
|
}
|
|
2484
2934
|
function needsBootstrap(workDir) {
|
|
2485
2935
|
const projectDir = workDir || getWorkingDirectory(void 0, true);
|
|
2486
|
-
const bootstrapPath =
|
|
2487
|
-
return
|
|
2936
|
+
const bootstrapPath = join9(getTrieDirectory(projectDir), "BOOTSTRAP.md");
|
|
2937
|
+
return existsSync10(bootstrapPath);
|
|
2488
2938
|
}
|
|
2489
2939
|
async function loadRules(workDir) {
|
|
2490
2940
|
const projectDir = workDir || getWorkingDirectory(void 0, true);
|
|
2491
|
-
const rulesPath =
|
|
2941
|
+
const rulesPath = join9(getTrieDirectory(projectDir), "RULES.md");
|
|
2492
2942
|
try {
|
|
2493
|
-
if (
|
|
2494
|
-
return await
|
|
2943
|
+
if (existsSync10(rulesPath)) {
|
|
2944
|
+
return await readFile8(rulesPath, "utf-8");
|
|
2495
2945
|
}
|
|
2496
2946
|
} catch {
|
|
2497
2947
|
}
|
|
@@ -2499,10 +2949,10 @@ async function loadRules(workDir) {
|
|
|
2499
2949
|
}
|
|
2500
2950
|
async function loadTeamInfo(workDir) {
|
|
2501
2951
|
const projectDir = workDir || getWorkingDirectory(void 0, true);
|
|
2502
|
-
const teamPath =
|
|
2952
|
+
const teamPath = join9(getTrieDirectory(projectDir), "TEAM.md");
|
|
2503
2953
|
try {
|
|
2504
|
-
if (
|
|
2505
|
-
return await
|
|
2954
|
+
if (existsSync10(teamPath)) {
|
|
2955
|
+
return await readFile8(teamPath, "utf-8");
|
|
2506
2956
|
}
|
|
2507
2957
|
} catch {
|
|
2508
2958
|
}
|
|
@@ -2511,7 +2961,7 @@ async function loadTeamInfo(workDir) {
|
|
|
2511
2961
|
function getFileTemplate(fileName, stack) {
|
|
2512
2962
|
switch (fileName) {
|
|
2513
2963
|
case "PROJECT.md":
|
|
2514
|
-
return
|
|
2964
|
+
return getProjectTemplate2(stack);
|
|
2515
2965
|
case "RULES.md":
|
|
2516
2966
|
return getRulesTemplate(stack);
|
|
2517
2967
|
case "TEAM.md":
|
|
@@ -2522,7 +2972,7 @@ function getFileTemplate(fileName, stack) {
|
|
|
2522
2972
|
return null;
|
|
2523
2973
|
}
|
|
2524
2974
|
}
|
|
2525
|
-
function
|
|
2975
|
+
function getProjectTemplate2(stack) {
|
|
2526
2976
|
const lines = ["# Project Overview", "", "> Define your project context here. AI assistants read this first.", ""];
|
|
2527
2977
|
lines.push("## Description", "", "[Describe what this project does and who it's for]", "");
|
|
2528
2978
|
lines.push("## Technology Stack", "");
|
|
@@ -3239,10 +3689,23 @@ export {
|
|
|
3239
3689
|
shouldAutoFix,
|
|
3240
3690
|
shouldBlockPush,
|
|
3241
3691
|
getAutonomyConfig,
|
|
3692
|
+
formatAuditLog,
|
|
3693
|
+
getAuditStatistics,
|
|
3694
|
+
getRecentAuditLogs,
|
|
3695
|
+
getSkillAuditLogs,
|
|
3696
|
+
runShellCommandSync,
|
|
3242
3697
|
getStagedChanges,
|
|
3243
3698
|
getUncommittedChanges,
|
|
3244
3699
|
perceiveCurrentChanges,
|
|
3245
3700
|
reasonAboutChangesHumanReadable,
|
|
3701
|
+
projectInfoExists,
|
|
3702
|
+
loadProjectInfo,
|
|
3703
|
+
initProjectInfo,
|
|
3704
|
+
getProjectSection,
|
|
3705
|
+
updateProjectSection,
|
|
3706
|
+
appendToSection,
|
|
3707
|
+
getProjectSections,
|
|
3708
|
+
getProjectInfoStructured,
|
|
3246
3709
|
getSkillCategories,
|
|
3247
3710
|
loadBootstrapContext,
|
|
3248
3711
|
initializeBootstrapFiles,
|
|
@@ -3259,6 +3722,8 @@ export {
|
|
|
3259
3722
|
importFromJson,
|
|
3260
3723
|
IncidentIndex,
|
|
3261
3724
|
LearningEngine,
|
|
3262
|
-
LinearIngester
|
|
3725
|
+
LinearIngester,
|
|
3726
|
+
loadContextState,
|
|
3727
|
+
getContextForAI
|
|
3263
3728
|
};
|
|
3264
|
-
//# sourceMappingURL=chunk-
|
|
3729
|
+
//# sourceMappingURL=chunk-CKYU5JOD.js.map
|