@xelth/eck-snapshot 5.9.0 → 6.0.0
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.
Potentially problematic release.
This version of @xelth/eck-snapshot might be problematic. Click here for more details.
- package/README.md +46 -165
- package/package.json +2 -2
- package/scripts/mcp-eck-core.js +61 -13
- package/src/cli/cli.js +2 -0
- package/src/cli/commands/updateSnapshot.js +128 -76
- package/src/templates/opencode/coder.template.md +25 -16
- package/src/templates/opencode/junior-architect.template.md +28 -15
- package/src/utils/aiHeader.js +5 -4
- package/src/utils/claudeMdGenerator.js +84 -77
- package/src/utils/fileUtils.js +154 -89
- package/src/utils/gitUtils.js +12 -8
- package/src/utils/opencodeAgentsGenerator.js +8 -2
- package/src/utils/tokenEstimator.js +50 -46
|
@@ -3,13 +3,17 @@
|
|
|
3
3
|
## 1. PROJECT MODE ACTIVE
|
|
4
4
|
You are operating in **Project Mode** inside OpenCode. You are not just editing a single file; you are managing the entire project repository.
|
|
5
5
|
- **Source of Truth:** The file system is your source of truth.
|
|
6
|
-
- **Documentation:** The `.eck/` directory contains project context. READ filenames to understand what is available.
|
|
7
6
|
- **Directory Structure:**
|
|
8
7
|
```
|
|
9
8
|
{{tree}}
|
|
10
9
|
```
|
|
11
10
|
|
|
12
|
-
## 2.
|
|
11
|
+
## 2. PROJECT CONTEXT (.eck DIRECTORY)
|
|
12
|
+
The `.eck/` directory is your brain externalized. **Before taking action:**
|
|
13
|
+
- Read the files in `.eck/` (like `CONTEXT.md`, `ROADMAP.md`, `TECH_DEBT.md`) to understand the rules and current state.
|
|
14
|
+
- Update these manifests if the architecture or roadmap changes.
|
|
15
|
+
|
|
16
|
+
## 3. SWARM DELEGATION PROTOCOL (TOKEN ECONOMY)
|
|
13
17
|
|
|
14
18
|
### A. Token Efficiency: When NOT to Delegate
|
|
15
19
|
**DO NOT delegate tasks where explanation costs more tokens than execution.**
|
|
@@ -29,28 +33,37 @@ For bulk work where delegation saves YOUR expensive context window, YOU MUST del
|
|
|
29
33
|
- Generating boilerplate code
|
|
30
34
|
* **Action:** Use `glm_zai_backend`, `glm_zai_frontend`, `glm_zai_qa`, or `glm_zai_refactor`.
|
|
31
35
|
|
|
32
|
-
##
|
|
33
|
-
When you have completed your coding task and verified it works
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
36
|
+
## 4. DEFINITION OF DONE (CRITICAL)
|
|
37
|
+
When you have completed your coding task and verified it works, you must report back and sync context.
|
|
38
|
+
|
|
39
|
+
**OPTION A: Using MCP Tool (Recommended)**
|
|
40
|
+
Call the \`eck_finish_task\` tool. Pass your detailed markdown report into the \`status\` argument.
|
|
41
|
+
- The tool will automatically write the report to \`AnswerToSA.md\`, commit, and generate a snapshot.
|
|
42
|
+
- **DO NOT** manually write to \`AnswerToSA.md\` with your file editing tools.
|
|
43
|
+
- **WARNING: USE ONLY ONCE.** Do not use \`eck_finish_task\` for intermediate testing. It spams snapshot history.
|
|
44
|
+
|
|
45
|
+
**OPTION B: Manual CLI (Fallback)**
|
|
46
|
+
If the MCP tool is unavailable:
|
|
47
|
+
1. **READ** \`.eck/lastsnapshot/AnswerToSA.md\` using your \`Read\` tool (REQUIRED by safety rules before overwriting).
|
|
48
|
+
2. **WRITE** your report to that file.
|
|
49
|
+
3. Run \`eck-snapshot update\` in terminal.
|
|
50
|
+
4. If you are entirely blocked, use the \`eck_fail_task\` tool.
|
|
41
51
|
|
|
42
|
-
##
|
|
52
|
+
## 5. SWARM ERROR RECOVERY & THE RALPH LOOP
|
|
43
53
|
**Core Directive:** You are "deterministically persistent". Failures are expected, giving up is not.
|
|
44
54
|
|
|
45
|
-
1. **
|
|
46
|
-
*
|
|
55
|
+
1. **Runtime Context & Critical Thinking:**
|
|
56
|
+
* Always check `.eck/RUNTIME_STATE.md` before coding.
|
|
57
|
+
* If the Senior Architect's hypothesis is not confirmed by logs/curl, DISCARD it and fix the real issue.
|
|
58
|
+
2. **Iterative Correction:**
|
|
59
|
+
* Verify via browser/curl/logs. If it fails: **DO NOT STOP**.
|
|
47
60
|
* **Read** the error message, **Think** about the cause, **Fix** the code, and **Retry**.
|
|
48
61
|
2. **Intelligent Retry (Swarm Supervision):**
|
|
49
62
|
* If a GLM Z.AI worker produces bad code, **DON'T** repeat the same prompt.
|
|
50
63
|
* **Analyze WHY** it failed and **Guide** the worker: "Previous attempt failed because X. Try again using pattern Y."
|
|
51
64
|
* **Takeover:** If the worker fails twice, **DO IT YOURSELF**.
|
|
52
65
|
|
|
53
|
-
##
|
|
66
|
+
## 6. REPORTING PROTOCOL
|
|
54
67
|
At the end of your task, you **MUST** overwrite `.eck/lastsnapshot/AnswerToSA.md` BEFORE calling `eck_finish_task`.
|
|
55
68
|
|
|
56
69
|
**Format for .eck/lastsnapshot/AnswerToSA.md:**
|
package/src/utils/aiHeader.js
CHANGED
|
@@ -516,10 +516,11 @@ Use \`apply_code_changes\` for simple, direct tasks where you provide all detail
|
|
|
516
516
|
"agent_environment": "Development environment with full GUI support and development tools",
|
|
517
517
|
"command_for_agent": "apply_code_changes",
|
|
518
518
|
"task_id": "unique-task-id",
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
519
|
+
"payload": {
|
|
520
|
+
"objective": "Brief, clear task description",
|
|
521
|
+
"context": "Why this change is needed - include relevant .eck manifest context",
|
|
522
|
+
"architect_confidence": "high (90%) - I am certain of this plan / low (30%) - Please investigate first",
|
|
523
|
+
"files_to_modify": [
|
|
523
524
|
{
|
|
524
525
|
"path": "exact/file/path.js",
|
|
525
526
|
"action": "specific action (add, modify, replace, delete)",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import fs from 'fs/promises';
|
|
2
|
-
import path from 'path';
|
|
3
|
-
|
|
1
|
+
import fs from 'fs/promises';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
|
|
4
4
|
/**
|
|
5
5
|
* Generates the Smart Delegation Protocol based on the specific Architect persona.
|
|
6
6
|
*/
|
|
@@ -21,7 +21,12 @@ You are operating in **Project Mode**. You are not just editing a single file; y
|
|
|
21
21
|
${tree}
|
|
22
22
|
\`\`\`
|
|
23
23
|
|
|
24
|
-
## 2.
|
|
24
|
+
## 2. PROJECT CONTEXT (.eck DIRECTORY)
|
|
25
|
+
The \`.eck/\` directory is your brain externalized. **Before taking action:**
|
|
26
|
+
- Read the files in \`.eck/\` (like \`CONTEXT.md\`, \`ROADMAP.md\`, \`TECH_DEBT.md\`) to understand the rules and current state.
|
|
27
|
+
- Update these manifests if the architecture or roadmap changes.
|
|
28
|
+
|
|
29
|
+
## 3. SWARM DELEGATION PROTOCOL (GLM Z.AI)
|
|
25
30
|
You command a fleet of specialist agents (Swarm). Your primary job is to break down the user's request into sub-tasks and delegate the heavy lifting.
|
|
26
31
|
${behaviorFocus}
|
|
27
32
|
|
|
@@ -37,64 +42,66 @@ For bulk work, YOU MUST use your MCP tools to delegate to GLM Z.AI:
|
|
|
37
42
|
- \`glm_zai_qa\`: Writing comprehensive test suites (E2E, unit tests).
|
|
38
43
|
- \`glm_zai_refactor\`: Code cleanup and SOLID principle enforcement.
|
|
39
44
|
|
|
40
|
-
##
|
|
41
|
-
Your task is NOT complete until
|
|
42
|
-
1. **Verify:**
|
|
43
|
-
2. **Report:**
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
**
|
|
47
|
-
**
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
4. If the worker fails twice, take over and implement the fix yourself.
|
|
59
|
-
|
|
60
|
-
## 5. OPERATIONAL RULES
|
|
45
|
+
## 4. DEFINITION OF DONE (CRITICAL)
|
|
46
|
+
Your task is NOT complete until code works globally.
|
|
47
|
+
1. **Verify:** Verify functionality manually via browser/curl/logs/DB checks. If they fail, fix errors iteratively.
|
|
48
|
+
2. **Finish & Report:** Use the \`eck_finish_task\` MCP tool.
|
|
49
|
+
- Pass your full markdown report into the \`status\` argument.
|
|
50
|
+
- The tool will automatically write the report to \`.eck/lastsnapshot/AnswerToSA.md\`, commit, and generate a snapshot.
|
|
51
|
+
- **DO NOT** try to manually write to \`.eck/lastsnapshot/AnswerToSA.md\` with the \`Write\` tool (it will fail safety checks).
|
|
52
|
+
- **WARNING:** USE ONLY ONCE PER TASK. Do not use this tool or \`eck-snapshot update\` for intermediate testing.
|
|
53
|
+
|
|
54
|
+
## 5. SWARM ERROR RECOVERY & ARCHITECT HYPOTHESES
|
|
55
|
+
1. **Runtime Check:** Always check the \`.eck/RUNTIME_STATE.md\` and running processes before coding.
|
|
56
|
+
2. **Challenge the Architect:** If the Architect's hypothesis is not confirmed during verification, discard it and look for the real root cause in the runtime.
|
|
57
|
+
3. If a GLM Z.AI worker returns bad code, do NOT repeat the exact same prompt.
|
|
58
|
+
4. Analyze the failure (e.g., "Worker used wrong import path").
|
|
59
|
+
5. Call the tool again with corrective guidance: *"Previous attempt failed because of X. Try again using pattern Y."*
|
|
60
|
+
6. If the worker fails twice, take over and implement the fix yourself.
|
|
61
|
+
|
|
62
|
+
## 6. OPERATIONAL RULES
|
|
61
63
|
- **Manifests:** If you see [STUB] in .eck/ files, update them.
|
|
62
64
|
`;
|
|
63
65
|
}
|
|
64
|
-
|
|
66
|
+
|
|
65
67
|
const CODER_INSTRUCTIONS = `# 🛠️ ROLE: Expert Developer (The Fixer)
|
|
66
68
|
|
|
67
69
|
## CORE DIRECTIVE
|
|
68
70
|
You are an Expert Developer. The architecture is already decided. Your job is to **execute**, **fix**, and **polish**.
|
|
69
71
|
|
|
70
72
|
## DEFINITION OF DONE (CRITICAL)
|
|
71
|
-
When
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
73
|
+
When task is complete, you must report back and sync context.
|
|
74
|
+
|
|
75
|
+
**OPTION A: Using MCP Tool (Recommended)**
|
|
76
|
+
Call the \`eck_finish_task\` tool. Pass your detailed markdown report into the \`status\` argument.
|
|
77
|
+
- The tool will automatically write the report to \`AnswerToSA.md\`, commit, and generate a snapshot.
|
|
78
|
+
- **DO NOT** manually write to \`AnswerToSA.md\` with your file editing tools (it will fail safety checks).
|
|
79
|
+
- **WARNING: USE ONLY ONCE.** Do not use \`eck_finish_task\` for intermediate testing.
|
|
80
|
+
|
|
81
|
+
**OPTION B: Manual CLI (Fallback)**
|
|
82
|
+
If the MCP tool is unavailable:
|
|
83
|
+
1. **READ** \`.eck/lastsnapshot/AnswerToSA.md\` using your \`Read\` tool (REQUIRED by safety rules before overwriting).
|
|
84
|
+
2. **WRITE** your report to that file.
|
|
85
|
+
3. Run \`eck-snapshot update\` in terminal.
|
|
86
|
+
|
|
87
|
+
## PROJECT CONTEXT (.eck DIRECTORY)
|
|
88
|
+
The \`.eck/\` directory contains critical project documentation. **Before starting your task, you MUST:**
|
|
89
|
+
1. List the files in the \`.eck/\` directory.
|
|
90
|
+
2. Read any files that might be relevant to your task based on their names (e.g., \`CONTEXT.md\`, \`TECH_DEBT.md\`, \`OPERATIONS.md\`).
|
|
91
|
+
3. You are responsible for updating these files if your code changes alter the project's architecture or operations.
|
|
87
92
|
|
|
88
93
|
## WORKFLOW
|
|
89
|
-
1.
|
|
90
|
-
2.
|
|
91
|
-
3.
|
|
92
|
-
4.
|
|
94
|
+
1. Check the \`.eck/RUNTIME_STATE.md\` and verify actual running processes.
|
|
95
|
+
2. Read the code. If the Architect's hypothesis is wrong, discard it and find the real bug.
|
|
96
|
+
3. Fix the bugs / Implement the feature.
|
|
97
|
+
4. Verify functionality manually via browser/curl/logs/DB checks.
|
|
98
|
+
5. **Loop:** If verification fails, fix it immediately. Do not ask for permission.
|
|
99
|
+
6. **Blocked?** Use the \`eck_fail_task\` tool to abort safely without committing broken code.
|
|
93
100
|
`;
|
|
94
|
-
|
|
95
|
-
/**
|
|
96
|
-
* Generates and writes the CLAUDE.md file based on the selected mode.
|
|
97
|
-
*/
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Generates and writes the CLAUDE.md file based on the selected mode.
|
|
104
|
+
*/
|
|
98
105
|
export async function updateClaudeMd(repoPath, mode, tree, confidentialFiles = [], options = {}) {
|
|
99
106
|
let content = '';
|
|
100
107
|
|
|
@@ -106,30 +113,30 @@ export async function updateClaudeMd(repoPath, mode, tree, confidentialFiles = [
|
|
|
106
113
|
// Default coder mode (or if flags are missing)
|
|
107
114
|
content = CODER_INSTRUCTIONS;
|
|
108
115
|
}
|
|
109
|
-
|
|
110
|
-
// Chinese delegation mode
|
|
111
|
-
if (options.zh) {
|
|
112
|
-
content += `
|
|
113
|
-
## 🇨🇳 LANGUAGE PROTOCOL
|
|
114
|
-
- **With the user:** Communicate in the user's language (auto-detect from their messages).
|
|
115
|
-
- **With GLM Z.AI workers:** ALWAYS write the \`instruction\` parameter in **Chinese (中文)**.
|
|
116
|
-
This significantly improves output quality for Chinese-trained models.
|
|
117
|
-
Translate task descriptions, requirements, and context into Chinese before delegating.
|
|
118
|
-
- **Code:** Variable names, comments in code, and commit messages remain in English.
|
|
119
|
-
`;
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
// Append Confidential Files Reference
|
|
123
|
-
if (confidentialFiles.length > 0) {
|
|
124
|
-
content += '\n\n## 🔐 Access & Credentials\n';
|
|
125
|
-
content += 'The following confidential files are available locally but excluded from snapshots/tree:\n';
|
|
126
|
-
for (const file of confidentialFiles) {
|
|
127
|
-
content += `- \`${file}\`\n`;
|
|
128
|
-
}
|
|
129
|
-
content += '> **Note:** Read these files only when strictly necessary.\n';
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
const claudeMdPath = path.join(repoPath, 'CLAUDE.md');
|
|
133
|
-
await fs.writeFile(claudeMdPath, content, 'utf-8');
|
|
134
|
-
console.log(`📝 Updated CLAUDE.md for role: **${mode.toUpperCase()}** (Ralph Loop + GLM Z.AI Protocol Active)`);
|
|
135
|
-
}
|
|
116
|
+
|
|
117
|
+
// Chinese delegation mode
|
|
118
|
+
if (options.zh) {
|
|
119
|
+
content += `
|
|
120
|
+
## 🇨🇳 LANGUAGE PROTOCOL
|
|
121
|
+
- **With the user:** Communicate in the user's language (auto-detect from their messages).
|
|
122
|
+
- **With GLM Z.AI workers:** ALWAYS write the \`instruction\` parameter in **Chinese (中文)**.
|
|
123
|
+
This significantly improves output quality for Chinese-trained models.
|
|
124
|
+
Translate task descriptions, requirements, and context into Chinese before delegating.
|
|
125
|
+
- **Code:** Variable names, comments in code, and commit messages remain in English.
|
|
126
|
+
`;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// Append Confidential Files Reference
|
|
130
|
+
if (confidentialFiles.length > 0) {
|
|
131
|
+
content += '\n\n## 🔐 Access & Credentials\n';
|
|
132
|
+
content += 'The following confidential files are available locally but excluded from snapshots/tree:\n';
|
|
133
|
+
for (const file of confidentialFiles) {
|
|
134
|
+
content += `- \`${file}\`\n`;
|
|
135
|
+
}
|
|
136
|
+
content += '> **Note:** Read these files only when strictly necessary.\n';
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
const claudeMdPath = path.join(repoPath, 'CLAUDE.md');
|
|
140
|
+
await fs.writeFile(claudeMdPath, content, 'utf-8');
|
|
141
|
+
console.log(`📝 Updated CLAUDE.md for role: **${mode.toUpperCase()}** (Ralph Loop + GLM Z.AI Protocol Active)`);
|
|
142
|
+
}
|
package/src/utils/fileUtils.js
CHANGED
|
@@ -11,56 +11,86 @@ import { minimatch } from 'minimatch';
|
|
|
11
11
|
/**
|
|
12
12
|
* Scanner for detecting and redacting secrets (API keys, tokens)
|
|
13
13
|
*/
|
|
14
|
-
export const SecretScanner = {
|
|
15
|
-
patterns: [
|
|
16
|
-
// Service-specific patterns
|
|
17
|
-
{ name: 'GitHub Token', regex: /gh[pous]_[a-zA-Z0-9]{36}/g },
|
|
18
|
-
{ name: 'AWS Access Key', regex: /(?:AKIA|ASIA)[0-9A-Z]{16}/g },
|
|
19
|
-
{ name: 'OpenAI API Key', regex: /sk-[a-zA-Z0-9]{32,}/g },
|
|
20
|
-
{ name: 'Stripe Secret Key', regex: /sk_live_[0-9a-zA-Z]{24}/g },
|
|
21
|
-
{ name: 'Google API Key', regex: /AIza[0-9A-Za-z\-_]{35}/g },
|
|
22
|
-
{ name: 'Slack Token', regex: /xox[baprs]-[0-9a-zA-Z\-]{10,}/g },
|
|
23
|
-
{ name: 'NPM Token', regex: /npm_[a-zA-Z0-9]{36}/g },
|
|
24
|
-
{ name: 'Private Key', regex: /-----BEGIN (?:RSA |EC |OPENSSH )?PRIVATE KEY-----/g },
|
|
25
|
-
// Generic high-entropy patterns near sensitive keywords
|
|
26
|
-
{
|
|
27
|
-
name: 'Generic Secret',
|
|
28
|
-
regex: /(?:api[_-]?key|secret|password|token|auth|pwd|credential)\s*[:=]\s*["']([a-zA-Z0-9\-_.]{16,})["']/gi
|
|
29
|
-
}
|
|
30
|
-
],
|
|
31
|
-
|
|
32
|
-
/**
|
|
33
|
-
*
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
14
|
+
export const SecretScanner = {
|
|
15
|
+
patterns: [
|
|
16
|
+
// Service-specific patterns
|
|
17
|
+
{ name: 'GitHub Token', regex: /gh[pous]_[a-zA-Z0-9]{36}/g },
|
|
18
|
+
{ name: 'AWS Access Key', regex: /(?:AKIA|ASIA)[0-9A-Z]{16}/g },
|
|
19
|
+
{ name: 'OpenAI API Key', regex: /sk-[a-zA-Z0-9]{32,}/g },
|
|
20
|
+
{ name: 'Stripe Secret Key', regex: /sk_live_[0-9a-zA-Z]{24}/g },
|
|
21
|
+
{ name: 'Google API Key', regex: /AIza[0-9A-Za-z\-_]{35}/g },
|
|
22
|
+
{ name: 'Slack Token', regex: /xox[baprs]-[0-9a-zA-Z\-]{10,}/g },
|
|
23
|
+
{ name: 'NPM Token', regex: /npm_[a-zA-Z0-9]{36}/g },
|
|
24
|
+
{ name: 'Private Key', regex: /-----BEGIN (?:RSA |EC |OPENSSH )?PRIVATE KEY-----/g },
|
|
25
|
+
// Generic high-entropy patterns near sensitive keywords
|
|
26
|
+
{
|
|
27
|
+
name: 'Generic Secret',
|
|
28
|
+
regex: /(?:api[_-]?key|secret|password|token|auth|pwd|credential)\s*[:=]\s*["']([a-zA-Z0-9\-_.]{16,})["']/gi
|
|
29
|
+
}
|
|
30
|
+
],
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Calculates Shannon Entropy of a string
|
|
34
|
+
*/
|
|
35
|
+
calculateEntropy(str) {
|
|
36
|
+
const len = str.length;
|
|
37
|
+
const frequencies = Array.from(str).reduce((freq, c) => {
|
|
38
|
+
freq[c] = (freq[c] || 0) + 1;
|
|
39
|
+
return freq;
|
|
40
|
+
}, {});
|
|
41
|
+
return Object.values(frequencies).reduce((sum, f) => {
|
|
42
|
+
const p = f / len;
|
|
43
|
+
return sum - (p * Math.log2(p));
|
|
44
|
+
}, 0);
|
|
45
|
+
},
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Scans content and replaces detected secrets with a placeholder
|
|
49
|
+
* @param {string} content - File content to scan
|
|
50
|
+
* @param {string} filePath - Path for logging context
|
|
51
|
+
* @returns {{content: string, found: string[]}} Redacted content and list of found secret types
|
|
52
|
+
*/
|
|
53
|
+
redact(content, filePath) {
|
|
54
|
+
let redactedContent = content;
|
|
55
|
+
const foundSecrets = [];
|
|
56
|
+
|
|
57
|
+
for (const pattern of this.patterns) {
|
|
58
|
+
// Reset regex lastIndex for global patterns
|
|
59
|
+
pattern.regex.lastIndex = 0;
|
|
60
|
+
|
|
61
|
+
const matches = [...content.matchAll(pattern.regex)];
|
|
62
|
+
if (matches.length > 0) {
|
|
63
|
+
for (const match of matches) {
|
|
64
|
+
// For generic pattern, use captured group; for specific patterns, use full match
|
|
65
|
+
const secretValue = match[1] || match[0];
|
|
66
|
+
const placeholder = `[REDACTED_${pattern.name.replace(/\s+/g, '_').toUpperCase()}]`;
|
|
67
|
+
redactedContent = redactedContent.replace(secretValue, placeholder);
|
|
68
|
+
foundSecrets.push(pattern.name);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// Second pass: Shannon Entropy check for arbitrary hardcoded secrets
|
|
74
|
+
// Look for long strings assigned to variable names that might be keys
|
|
75
|
+
const entropyRegex = /(?:const|let|var|set|export|define)\s+([A-Za-z0-9_]*(?:KEY|TOKEN|SECRET|PASSWORD)[A-Za-z0-9_]*)\s*=\s*["']([a-zA-Z0-9+/=_-]{20,128})["']/gi;
|
|
76
|
+
const entropyMatches = [...redactedContent.matchAll(entropyRegex)];
|
|
77
|
+
|
|
78
|
+
for (const match of entropyMatches) {
|
|
79
|
+
const secretValue = match[2];
|
|
80
|
+
// Check entropy - random base64 usually has entropy > 4.5
|
|
81
|
+
if (this.calculateEntropy(secretValue) > 4.5 && !secretValue.includes('REDACTED')) {
|
|
82
|
+
const placeholder = `[REDACTED_HIGH_ENTROPY_SECRET]`;
|
|
83
|
+
redactedContent = redactedContent.replace(secretValue, placeholder);
|
|
84
|
+
foundSecrets.push('High Entropy Secret');
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
return {
|
|
89
|
+
content: redactedContent,
|
|
90
|
+
found: [...new Set(foundSecrets)]
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
};
|
|
64
94
|
|
|
65
95
|
export function parseSize(sizeStr) {
|
|
66
96
|
const units = { B: 1, KB: 1024, MB: 1024 ** 2, GB: 1024 ** 3 };
|
|
@@ -838,15 +868,16 @@ export async function applyProfileFilter(allFiles, profileString, repoPath) {
|
|
|
838
868
|
export async function initializeEckManifest(projectPath) {
|
|
839
869
|
const eckDir = path.join(projectPath, '.eck');
|
|
840
870
|
|
|
841
|
-
// Load setup configuration to check AI generation settings
|
|
842
|
-
let aiGenerationEnabled = false;
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
871
|
+
// Load setup configuration to check AI generation settings and project context
|
|
872
|
+
let aiGenerationEnabled = false;
|
|
873
|
+
let setupConfig = null;
|
|
874
|
+
try {
|
|
875
|
+
setupConfig = await loadSetupConfig();
|
|
876
|
+
aiGenerationEnabled = setupConfig?.aiInstructions?.manifestInitialization?.aiGenerationEnabled ?? false;
|
|
877
|
+
} catch (error) {
|
|
878
|
+
// If setup config fails to load, default to disabled
|
|
879
|
+
console.warn(` ⚠️ Could not load setup config: ${error.message}. AI generation disabled.`);
|
|
880
|
+
}
|
|
850
881
|
|
|
851
882
|
try {
|
|
852
883
|
// Check if .eck directory already exists and has all required files
|
|
@@ -894,33 +925,38 @@ export async function initializeEckManifest(projectPath) {
|
|
|
894
925
|
delete staticFacts.allDetections;
|
|
895
926
|
}
|
|
896
927
|
|
|
897
|
-
const staticFactsJson = JSON.stringify(staticFacts, null, 2);
|
|
898
|
-
// --- END NEW LOGIC ---
|
|
899
|
-
|
|
900
|
-
//
|
|
928
|
+
const staticFactsJson = JSON.stringify(staticFacts, null, 2);
|
|
929
|
+
// --- END NEW LOGIC ---
|
|
930
|
+
|
|
931
|
+
// Extract Context from setup.json if available
|
|
932
|
+
const projName = setupConfig?.projectContext?.name || staticFacts.type || 'project';
|
|
933
|
+
const projType = setupConfig?.projectContext?.type || staticFacts.type || 'unknown';
|
|
934
|
+
const projStack = setupConfig?.projectContext?.architecture?.stack?.join(', ') || 'TBD';
|
|
935
|
+
const projAi = setupConfig?.projectContext?.architecture?.aiIntegration || 'None';
|
|
936
|
+
|
|
937
|
+
// 3. Define smarter templates and prompts using setup.json context
|
|
901
938
|
const templateConfigs = {
|
|
902
|
-
'ENVIRONMENT.md': {
|
|
903
|
-
prompt: `Generate raw YAML for .eck/ENVIRONMENT.md based on these project facts:\n${staticFactsJson}\nInclude project_type, runtime, and agent_id: local_dev. NO markdown fences.`,
|
|
904
|
-
fallback: `project_type: ${
|
|
905
|
-
|
|
906
|
-
#
|
|
907
|
-
|
|
908
|
-
agent_id: local_dev
|
|
909
|
-
`
|
|
939
|
+
'ENVIRONMENT.md': {
|
|
940
|
+
prompt: `Generate raw YAML for .eck/ENVIRONMENT.md based on these project facts:\n${staticFactsJson}\nInclude project_type, runtime, and agent_id: local_dev. NO markdown fences.`,
|
|
941
|
+
fallback: `project_type: ${projType}
|
|
942
|
+
agent_id: local_dev
|
|
943
|
+
# Generated from setup.json
|
|
944
|
+
`
|
|
910
945
|
},
|
|
911
|
-
'CONTEXT.md': {
|
|
912
|
-
prompt: `Analyze these project files and dependencies:\n${staticFactsJson}\nGenerate a professional # Project Overview in Markdown. Describe the actual architecture and purpose of this specific project. Be technical and concise. Start with '# Project Overview'.`,
|
|
913
|
-
fallback: `#
|
|
914
|
-
|
|
915
|
-
##
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
(
|
|
946
|
+
'CONTEXT.md': {
|
|
947
|
+
prompt: `Analyze these project files and dependencies:\n${staticFactsJson}\nGenerate a professional # Project Overview in Markdown. Describe the actual architecture and purpose of this specific project. Be technical and concise. Start with '# Project Overview'.`,
|
|
948
|
+
fallback: `# Project Overview
|
|
949
|
+
|
|
950
|
+
## Description
|
|
951
|
+
Project name: ${projName}
|
|
952
|
+
Type: ${projType}
|
|
953
|
+
AI Integration: ${projAi}
|
|
954
|
+
|
|
955
|
+
## Architecture
|
|
956
|
+
Stack: ${projStack}
|
|
957
|
+
|
|
958
|
+
*(Auto-generated from setup.json)*
|
|
959
|
+
`
|
|
924
960
|
},
|
|
925
961
|
'OPERATIONS.md': {
|
|
926
962
|
prompt: `Look at the dependencies and files:\n${staticFactsJson}\nGenerate a Markdown guide for common operations (Setup, Run, Test, Build) using the correct commands for this tech stack. Start with '# Common Operations'.`,
|
|
@@ -938,11 +974,40 @@ ${staticFacts.type === 'nodejs' ? 'npm install' : 'TBD'}`
|
|
|
938
974
|
|
|
939
975
|
**ARCHITECT:** Set a real roadmap based on user goals. **CODER:** Remove this stub marker once a real goal is added.`
|
|
940
976
|
},
|
|
941
|
-
'TECH_DEBT.md': {
|
|
942
|
-
prompt: `Given this is a ${staticFacts.type} project, list 2-3 common technical debt items. Start with '# Technical Debt'.`,
|
|
943
|
-
fallback: `# [STUB: TECH_DEBT.MD]
|
|
944
|
-
|
|
945
|
-
**CODER:** Scan for TODOs/FIXMEs or structural issues and list them here. Remove this stub marker.`
|
|
977
|
+
'TECH_DEBT.md': {
|
|
978
|
+
prompt: `Given this is a ${staticFacts.type} project, list 2-3 common technical debt items. Start with '# Technical Debt'.`,
|
|
979
|
+
fallback: `# [STUB: TECH_DEBT.MD]
|
|
980
|
+
|
|
981
|
+
**CODER:** Scan for TODOs/FIXMEs or structural issues and list them here. Remove this stub marker.`
|
|
982
|
+
},
|
|
983
|
+
'DEPLOY_CHECKLIST.md': {
|
|
984
|
+
prompt: `Based on the project type (${staticFacts.type}), generate a pre-deployment checklist. Start with '# Deployment Checklist'.`,
|
|
985
|
+
fallback: `# [STUB: DEPLOY_CHECKLIST.MD]
|
|
986
|
+
|
|
987
|
+
## 🚨 ATTENTION CODER
|
|
988
|
+
Verify required build steps before deployment.
|
|
989
|
+
|
|
990
|
+
## Pre-Deployment Checklist
|
|
991
|
+
- [ ] Verify all tests pass
|
|
992
|
+
- [ ] Build assets (e.g., npm run build)
|
|
993
|
+
- [ ] Check environment variables
|
|
994
|
+
|
|
995
|
+
**CODER:** Update this checklist with actual build/deploy steps for this project.`
|
|
996
|
+
},
|
|
997
|
+
'RUNTIME_STATE.md': {
|
|
998
|
+
prompt: `Based on the project type (${staticFacts.type}), generate a template for RUNTIME_STATE.md. Start with '# Runtime State'.`,
|
|
999
|
+
fallback: `# Runtime State
|
|
1000
|
+
|
|
1001
|
+
## 🚨 ATTENTION CODER
|
|
1002
|
+
Always check this file and verify the actual runtime state (ports, running processes, env variables) BEFORE writing code. Update this file if ports or access methods change.
|
|
1003
|
+
|
|
1004
|
+
- **Server:** e.g., running on port 3210
|
|
1005
|
+
- **Services:** e.g., Scraper running on port 3211
|
|
1006
|
+
- **Auth:** e.g., admin@local / password
|
|
1007
|
+
- **Verification Commands:**
|
|
1008
|
+
- \`pm2 ls\`
|
|
1009
|
+
- \`curl http://localhost:3210/health\`
|
|
1010
|
+
`
|
|
946
1011
|
},
|
|
947
1012
|
'JOURNAL.md': {
|
|
948
1013
|
fallback: `# Development Journal
|
package/src/utils/gitUtils.js
CHANGED
|
@@ -25,14 +25,18 @@ export async function getGitAnchor(repoPath) {
|
|
|
25
25
|
}
|
|
26
26
|
}
|
|
27
27
|
|
|
28
|
-
export async function getChangedFiles(repoPath, anchorHash) {
|
|
29
|
-
try {
|
|
30
|
-
const
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
28
|
+
export async function getChangedFiles(repoPath, anchorHash, includeWorkingTree = false) {
|
|
29
|
+
try {
|
|
30
|
+
const args = ['diff', '--name-only', anchorHash];
|
|
31
|
+
if (!includeWorkingTree) {
|
|
32
|
+
args.push('HEAD');
|
|
33
|
+
}
|
|
34
|
+
const { stdout } = await execa('git', args, { cwd: repoPath });
|
|
35
|
+
return stdout.split('\n').filter(Boolean);
|
|
36
|
+
} catch (e) {
|
|
37
|
+
throw new Error(`Failed to get git diff: ${e.message}`);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
36
40
|
|
|
37
41
|
export async function getGitDiffOutput(repoPath, anchorHash, excludeFiles = []) {
|
|
38
42
|
try {
|
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
import fs from 'fs/promises';
|
|
2
2
|
import path from 'path';
|
|
3
|
+
import { fileURLToPath } from 'url';
|
|
4
|
+
|
|
5
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
6
|
+
const __dirname = path.dirname(__filename);
|
|
3
7
|
|
|
4
8
|
/**
|
|
5
9
|
* Generates AGENTS.md for OpenCode integration (GLM Z.AI ecosystem only)
|
|
@@ -30,11 +34,12 @@ export async function generateOpenCodeAgents(repoPath, mode, tree, confidentialF
|
|
|
30
34
|
color: '#10a37f'
|
|
31
35
|
};
|
|
32
36
|
|
|
33
|
-
const templatePath = path.join(
|
|
37
|
+
const templatePath = path.join(__dirname, '..', 'templates', 'opencode', 'junior-architect.template.md');
|
|
34
38
|
try {
|
|
35
39
|
let templateContent = await fs.readFile(templatePath, 'utf-8');
|
|
36
40
|
body = templateContent.replace('{{tree}}', tree);
|
|
37
41
|
} catch (error) {
|
|
42
|
+
console.warn(`⚠️ Could not load JAZ template from ${templatePath}: ${error.message}`);
|
|
38
43
|
body = `# 🧠 ROLE: Swarm Orchestrator (GLM-4.7)\n\nDirectory:\n\`\`\`\n${tree}\n\`\`\``;
|
|
39
44
|
}
|
|
40
45
|
} else {
|
|
@@ -48,10 +53,11 @@ export async function generateOpenCodeAgents(repoPath, mode, tree, confidentialF
|
|
|
48
53
|
color: '#44BA81'
|
|
49
54
|
};
|
|
50
55
|
|
|
51
|
-
const templatePath = path.join(
|
|
56
|
+
const templatePath = path.join(__dirname, '..', 'templates', 'opencode', 'coder.template.md');
|
|
52
57
|
try {
|
|
53
58
|
body = await fs.readFile(templatePath, 'utf-8');
|
|
54
59
|
} catch (error) {
|
|
60
|
+
console.warn(`⚠️ Could not load Coder template from ${templatePath}: ${error.message}`);
|
|
55
61
|
body = `# 🛠️ ROLE: Expert Developer`;
|
|
56
62
|
}
|
|
57
63
|
}
|