@howlil/ez-agents 3.4.2 → 3.5.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.
- package/README.md +77 -2
- package/agents/ez-observer-agent.md +260 -0
- package/agents/ez-release-agent.md +333 -0
- package/agents/ez-requirements-agent.md +377 -0
- package/agents/ez-scrum-master-agent.md +242 -0
- package/agents/ez-tech-lead-agent.md +267 -0
- package/bin/install.js +3221 -3272
- package/commands/ez/arch-review.md +102 -0
- package/commands/ez/execute-phase.md +11 -0
- package/commands/ez/export-session.md +79 -0
- package/commands/ez/gather-requirements.md +117 -0
- package/commands/ez/git-workflow.md +72 -0
- package/commands/ez/hotfix.md +120 -0
- package/commands/ez/import-session.md +82 -0
- package/commands/ez/list-sessions.md +96 -0
- package/commands/ez/package-manager.md +316 -0
- package/commands/ez/plan-phase.md +9 -1
- package/commands/ez/preflight.md +79 -0
- package/commands/ez/progress.md +13 -1
- package/commands/ez/release.md +153 -0
- package/commands/ez/resume.md +107 -0
- package/commands/ez/standup.md +85 -0
- package/ez-agents/bin/ez-tools.cjs +1095 -716
- package/ez-agents/bin/lib/bdd-validator.cjs +622 -0
- package/ez-agents/bin/lib/content-scanner.cjs +238 -0
- package/ez-agents/bin/lib/context-cache.cjs +154 -0
- package/ez-agents/bin/lib/context-errors.cjs +71 -0
- package/ez-agents/bin/lib/context-manager.cjs +220 -0
- package/ez-agents/bin/lib/discussion-synthesizer.cjs +458 -0
- package/ez-agents/bin/lib/file-access.cjs +207 -0
- package/ez-agents/bin/lib/git-errors.cjs +83 -0
- package/ez-agents/bin/lib/git-utils.cjs +321 -203
- package/ez-agents/bin/lib/git-workflow-engine.cjs +1157 -0
- package/ez-agents/bin/lib/index.cjs +46 -2
- package/ez-agents/bin/lib/lockfile-validator.cjs +227 -0
- package/ez-agents/bin/lib/logger.cjs +124 -154
- package/ez-agents/bin/lib/memory-compression.cjs +256 -0
- package/ez-agents/bin/lib/metrics-tracker.cjs +406 -0
- package/ez-agents/bin/lib/package-manager-detector.cjs +203 -0
- package/ez-agents/bin/lib/package-manager-executor.cjs +385 -0
- package/ez-agents/bin/lib/package-manager-service.cjs +216 -0
- package/ez-agents/bin/lib/release-validator.cjs +614 -0
- package/ez-agents/bin/lib/safe-exec.cjs +128 -214
- package/ez-agents/bin/lib/session-chain.cjs +304 -0
- package/ez-agents/bin/lib/session-errors.cjs +81 -0
- package/ez-agents/bin/lib/session-export.cjs +251 -0
- package/ez-agents/bin/lib/session-import.cjs +262 -0
- package/ez-agents/bin/lib/session-manager.cjs +280 -0
- package/ez-agents/bin/lib/tier-manager.cjs +428 -0
- package/ez-agents/bin/lib/url-fetch.cjs +170 -0
- package/ez-agents/references/metrics-schema.md +118 -0
- package/ez-agents/references/planning-config.md +140 -0
- package/ez-agents/references/tier-strategy.md +103 -0
- package/ez-agents/templates/bdd-feature.md +173 -0
- package/ez-agents/templates/discussion.md +68 -0
- package/ez-agents/templates/incident-runbook.md +205 -0
- package/ez-agents/templates/release-checklist.md +133 -0
- package/ez-agents/templates/rollback-plan.md +201 -0
- package/ez-agents/workflows/arch-review.md +54 -0
- package/ez-agents/workflows/autonomous.md +844 -743
- package/ez-agents/workflows/execute-phase.md +45 -0
- package/ez-agents/workflows/export-session.md +255 -0
- package/ez-agents/workflows/gather-requirements.md +206 -0
- package/ez-agents/workflows/help.md +92 -0
- package/ez-agents/workflows/hotfix.md +291 -0
- package/ez-agents/workflows/import-session.md +303 -0
- package/ez-agents/workflows/new-milestone.md +713 -384
- package/ez-agents/workflows/new-project.md +1107 -1113
- package/ez-agents/workflows/plan-phase.md +22 -0
- package/ez-agents/workflows/progress.md +15 -25
- package/ez-agents/workflows/release.md +253 -0
- package/ez-agents/workflows/resume-session.md +215 -0
- package/ez-agents/workflows/standup.md +64 -0
- package/package.json +9 -2
|
@@ -0,0 +1,291 @@
|
|
|
1
|
+
<purpose>
|
|
2
|
+
Manage hotfix branches: create from main, complete by merging atomically to main (and develop for GitFlow), tag the release, and sync without polluting in-progress work.
|
|
3
|
+
</purpose>
|
|
4
|
+
|
|
5
|
+
<process>
|
|
6
|
+
|
|
7
|
+
## 1. Parse Arguments
|
|
8
|
+
|
|
9
|
+
Extract from $ARGUMENTS:
|
|
10
|
+
- Subcommand: `start` or `complete`
|
|
11
|
+
- Name: slug for the hotfix (e.g., `critical-bug`, `gmail-login-fix`)
|
|
12
|
+
- Version (for `complete` only): semver string
|
|
13
|
+
|
|
14
|
+
**If missing subcommand:**
|
|
15
|
+
```
|
|
16
|
+
Usage:
|
|
17
|
+
/ez:hotfix start <name>
|
|
18
|
+
/ez:hotfix complete <name> <version>
|
|
19
|
+
```
|
|
20
|
+
Exit.
|
|
21
|
+
|
|
22
|
+
## 2. Handle "start" Subcommand
|
|
23
|
+
|
|
24
|
+
### 2a. Load current state
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
# Current branch
|
|
28
|
+
CURRENT_BRANCH=$(git branch --show-current)
|
|
29
|
+
|
|
30
|
+
# Current version
|
|
31
|
+
CURRENT_VERSION=$(node -e "console.log(require('./package.json').version)" 2>/dev/null || echo "0.0.0")
|
|
32
|
+
|
|
33
|
+
# Load tier from config
|
|
34
|
+
TIER=$(node "$HOME/.claude/ez-agents/bin/ez-tools.cjs" config-get release.tier 2>/dev/null || echo "mvp")
|
|
35
|
+
|
|
36
|
+
# Last tag
|
|
37
|
+
LAST_TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "none")
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
### 2b. Check for uncommitted changes
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
git status --short
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
**If uncommitted changes:** Error — "Stash or commit current work before creating a hotfix"
|
|
47
|
+
|
|
48
|
+
### 2c. Create hotfix branch
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
# Get hotfix branch name
|
|
52
|
+
HOTFIX_BRANCH=$(node "$HOME/.claude/ez-agents/bin/ez-tools.cjs" hotfix-branch-name "${NAME}")
|
|
53
|
+
# Returns: hotfix/{name-slug}
|
|
54
|
+
|
|
55
|
+
# Branch from main (or last release tag if available)
|
|
56
|
+
SOURCE=$(git rev-parse --verify "${LAST_TAG}" 2>/dev/null && echo "${LAST_TAG}" || echo "main")
|
|
57
|
+
|
|
58
|
+
git checkout "${SOURCE}"
|
|
59
|
+
git checkout -b "${HOTFIX_BRANCH}"
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
### 2d. Report to user
|
|
63
|
+
|
|
64
|
+
```
|
|
65
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
66
|
+
EZ ► HOTFIX STARTED: {HOTFIX_BRANCH}
|
|
67
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
68
|
+
|
|
69
|
+
Branch: {HOTFIX_BRANCH}
|
|
70
|
+
From: {SOURCE} ({CURRENT_VERSION})
|
|
71
|
+
Tier: {TIER}
|
|
72
|
+
|
|
73
|
+
Make your fix, commit it, then complete:
|
|
74
|
+
/ez:hotfix complete {NAME} {NEXT_PATCH_VERSION}
|
|
75
|
+
|
|
76
|
+
Example:
|
|
77
|
+
Current: {CURRENT_VERSION}
|
|
78
|
+
Next: {NEXT_PATCH_SUGGESTION}
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
Suggest next patch version: increment patch number (1.2.3 → 1.2.4).
|
|
82
|
+
|
|
83
|
+
**STOP here for `start` subcommand.**
|
|
84
|
+
|
|
85
|
+
---
|
|
86
|
+
|
|
87
|
+
## 3. Handle "complete" Subcommand
|
|
88
|
+
|
|
89
|
+
### 3a. Validate state
|
|
90
|
+
|
|
91
|
+
```bash
|
|
92
|
+
# Confirm on hotfix branch
|
|
93
|
+
CURRENT_BRANCH=$(git branch --show-current)
|
|
94
|
+
EXPECTED_BRANCH=$(node "$HOME/.claude/ez-agents/bin/ez-tools.cjs" hotfix-branch-name "${NAME}")
|
|
95
|
+
|
|
96
|
+
if [ "$CURRENT_BRANCH" != "$EXPECTED_BRANCH" ]; then
|
|
97
|
+
echo "ERROR: Not on hotfix branch. Expected: ${EXPECTED_BRANCH}, got: ${CURRENT_BRANCH}"
|
|
98
|
+
exit 1
|
|
99
|
+
fi
|
|
100
|
+
|
|
101
|
+
# Check for uncommitted changes
|
|
102
|
+
git status --short
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
**If uncommitted changes:** Error — "Commit your fix before completing the hotfix"
|
|
106
|
+
|
|
107
|
+
### 3b. Validate version is semver
|
|
108
|
+
|
|
109
|
+
```bash
|
|
110
|
+
echo "${VERSION}" | grep -E "^[0-9]+\.[0-9]+\.[0-9]+$"
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
**If invalid:** Error — "Version must be semver (X.Y.Z)"
|
|
114
|
+
|
|
115
|
+
### 3c. Run security gates
|
|
116
|
+
|
|
117
|
+
```bash
|
|
118
|
+
node "$HOME/.claude/ez-agents/bin/ez-tools.cjs" release security-gates
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
**If secrets found:** Error — "Remove secrets before completing hotfix"
|
|
122
|
+
**If critical vulns:** Warning (not hard block for hotfix — speed matters)
|
|
123
|
+
|
|
124
|
+
### 3d. Run tests
|
|
125
|
+
|
|
126
|
+
```bash
|
|
127
|
+
npm test 2>/dev/null || yarn test 2>/dev/null || echo "WARNING: No test command found"
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
**If tests fail:** Warning — "Tests failing. Hotfix will be tagged but verify before pushing."
|
|
131
|
+
|
|
132
|
+
### 3e. Load tier and git strategy
|
|
133
|
+
|
|
134
|
+
```bash
|
|
135
|
+
TIER=$(node "$HOME/.claude/ez-agents/bin/ez-tools.cjs" config-get release.tier 2>/dev/null || echo "mvp")
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
Determine sync target:
|
|
139
|
+
- MVP/Medium: No sync needed (just main)
|
|
140
|
+
- Enterprise: Also sync to develop
|
|
141
|
+
|
|
142
|
+
### 3f. Generate changelog entry
|
|
143
|
+
|
|
144
|
+
```bash
|
|
145
|
+
LAST_TAG=$(git describe --tags --abbrev=0 main 2>/dev/null || echo "")
|
|
146
|
+
if [ -n "$LAST_TAG" ]; then
|
|
147
|
+
COMMITS=$(git log ${LAST_TAG}..HEAD --oneline --no-merges)
|
|
148
|
+
fi
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
Format entry for CHANGELOG.md:
|
|
152
|
+
```markdown
|
|
153
|
+
## [{VERSION}] — {date} (hotfix)
|
|
154
|
+
|
|
155
|
+
### Bug Fixes
|
|
156
|
+
- {fix commit message(s)}
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
### 3g. Merge to main
|
|
160
|
+
|
|
161
|
+
```bash
|
|
162
|
+
git checkout main
|
|
163
|
+
git merge --no-ff "${HOTFIX_BRANCH}" -m "hotfix(release): merge ${HOTFIX_BRANCH} for v${VERSION}"
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
**If merge conflict:**
|
|
167
|
+
```
|
|
168
|
+
MERGE CONFLICT during hotfix merge.
|
|
169
|
+
Resolve conflicts in: {conflicting files}
|
|
170
|
+
Then run: git commit && /ez:hotfix complete {NAME} {VERSION}
|
|
171
|
+
```
|
|
172
|
+
STOP.
|
|
173
|
+
|
|
174
|
+
### 3h. Bump version and update changelog
|
|
175
|
+
|
|
176
|
+
```bash
|
|
177
|
+
# Bump version in package.json
|
|
178
|
+
node -e "
|
|
179
|
+
const pkg = JSON.parse(require('fs').readFileSync('package.json'));
|
|
180
|
+
pkg.version = '${VERSION}';
|
|
181
|
+
require('fs').writeFileSync('package.json', JSON.stringify(pkg, null, 2) + '\n');
|
|
182
|
+
"
|
|
183
|
+
|
|
184
|
+
# Update CHANGELOG.md (prepend entry)
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
### 3i. Create rollback plan
|
|
188
|
+
|
|
189
|
+
Write to `.planning/releases/v${VERSION}-ROLLBACK-PLAN.md` using rollback-plan template.
|
|
190
|
+
|
|
191
|
+
### 3j. Commit and tag
|
|
192
|
+
|
|
193
|
+
```bash
|
|
194
|
+
git add CHANGELOG.md package.json .planning/releases/
|
|
195
|
+
git commit -m "chore(hotfix): v${VERSION} — ${NAME}
|
|
196
|
+
|
|
197
|
+
Hotfix: ${NAME}
|
|
198
|
+
Previous: v${PREVIOUS_VERSION}"
|
|
199
|
+
|
|
200
|
+
git tag -a "v${VERSION}" -m "Hotfix v${VERSION}: ${NAME}"
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
### 3k. Sync to develop (Enterprise tier only)
|
|
204
|
+
|
|
205
|
+
```bash
|
|
206
|
+
if [ "$TIER" = "enterprise" ]; then
|
|
207
|
+
# Check if develop exists
|
|
208
|
+
git rev-parse --verify develop 2>/dev/null
|
|
209
|
+
if [ $? -eq 0 ]; then
|
|
210
|
+
git checkout develop
|
|
211
|
+
fi
|
|
212
|
+
fi
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
### Enterprise: Sync hotfix ke develop
|
|
216
|
+
|
|
217
|
+
1. Cek apakah sync akan conflict:
|
|
218
|
+
```
|
|
219
|
+
git merge-base --is-ancestor v{version} develop
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
2. Jika tidak conflict → `git merge v{version} --no-ff -m "chore: sync hotfix v{version} to develop"`
|
|
223
|
+
|
|
224
|
+
3. **Jika CONFLICT terdeteksi:**
|
|
225
|
+
- Jangan auto-merge. Beri instruksi eksplisit:
|
|
226
|
+
```
|
|
227
|
+
⚠️ MERGE CONFLICT: Hotfix sync ke develop memerlukan manual resolution.
|
|
228
|
+
|
|
229
|
+
Langkah:
|
|
230
|
+
a. git checkout develop
|
|
231
|
+
b. git merge v{version}
|
|
232
|
+
c. Resolve conflicts di file yang di-list git
|
|
233
|
+
d. git add . && git merge --continue
|
|
234
|
+
e. git push origin develop
|
|
235
|
+
|
|
236
|
+
PENTING: Hotfix SUDAH di production (main + tag).
|
|
237
|
+
Develop conflict tidak memblokir hotfix — selesaikan setelah production stabil.
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
### 3l. Clean up hotfix branch (optional)
|
|
241
|
+
|
|
242
|
+
```bash
|
|
243
|
+
git branch -d "${HOTFIX_BRANCH}"
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
### 3m. Report completion
|
|
247
|
+
|
|
248
|
+
```
|
|
249
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
250
|
+
EZ ► HOTFIX COMPLETE: v{VERSION} ✓
|
|
251
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
252
|
+
|
|
253
|
+
Hotfix: {NAME}
|
|
254
|
+
Version: v{VERSION}
|
|
255
|
+
Tag: v{VERSION}
|
|
256
|
+
Changelog: Updated
|
|
257
|
+
Rollback: .planning/releases/v{VERSION}-ROLLBACK-PLAN.md
|
|
258
|
+
|
|
259
|
+
{If enterprise:}
|
|
260
|
+
Synced to develop: ✓
|
|
261
|
+
|
|
262
|
+
### To Ship
|
|
263
|
+
git push origin main && git push origin v{VERSION}
|
|
264
|
+
|
|
265
|
+
{If enterprise:}
|
|
266
|
+
git push origin develop
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
</process>
|
|
270
|
+
|
|
271
|
+
<success_criteria>
|
|
272
|
+
|
|
273
|
+
### start
|
|
274
|
+
- [ ] Uncommitted changes check passed
|
|
275
|
+
- [ ] Hotfix branch created from main (or last tag)
|
|
276
|
+
- [ ] User sees branch name and complete instructions
|
|
277
|
+
|
|
278
|
+
### complete
|
|
279
|
+
- [ ] On correct hotfix branch
|
|
280
|
+
- [ ] Security gates run
|
|
281
|
+
- [ ] Tests run (warn if fail, don't block)
|
|
282
|
+
- [ ] Changelog entry generated
|
|
283
|
+
- [ ] Merged to main with no-ff
|
|
284
|
+
- [ ] Version bumped in package.json
|
|
285
|
+
- [ ] Rollback plan created
|
|
286
|
+
- [ ] Release tagged
|
|
287
|
+
- [ ] Develop synced (enterprise tier only)
|
|
288
|
+
- [ ] Hotfix branch cleaned up
|
|
289
|
+
- [ ] User sees push instructions
|
|
290
|
+
|
|
291
|
+
</success_criteria>
|
|
@@ -0,0 +1,303 @@
|
|
|
1
|
+
# Workflow: import-session
|
|
2
|
+
|
|
3
|
+
**Purpose:** Import session data from exported file
|
|
4
|
+
|
|
5
|
+
**Related Commands:** `/ez:import-session`
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Workflow Steps
|
|
10
|
+
|
|
11
|
+
### 1. Parameters
|
|
12
|
+
|
|
13
|
+
```
|
|
14
|
+
file_path: string (required)
|
|
15
|
+
source_model: string (optional) - For model-specific adapters
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
### 2. Validate Input
|
|
19
|
+
|
|
20
|
+
```
|
|
21
|
+
// Check file exists
|
|
22
|
+
if (!fs.existsSync(file_path)) {
|
|
23
|
+
throw error(`File not found: ${file_path}`);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// Check file is .json
|
|
27
|
+
if (!file_path.endsWith('.json')) {
|
|
28
|
+
throw error("Import file must be .json format");
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// Try to parse JSON
|
|
32
|
+
try {
|
|
33
|
+
content = fs.readFileSync(file_path, 'utf-8');
|
|
34
|
+
importedData = JSON.parse(content);
|
|
35
|
+
} catch (err) {
|
|
36
|
+
throw error(`Invalid JSON: ${err.message}`);
|
|
37
|
+
}
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
### 3. Import Session
|
|
41
|
+
|
|
42
|
+
```
|
|
43
|
+
SessionManager mgr = new SessionManager();
|
|
44
|
+
SessionImport importer = new SessionImport(mgr);
|
|
45
|
+
|
|
46
|
+
const options = {};
|
|
47
|
+
if (source_model) {
|
|
48
|
+
options.sourceModel = source_model;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
try {
|
|
52
|
+
result = importer.import(file_path, options);
|
|
53
|
+
} catch (SessionImportError err) {
|
|
54
|
+
logger.error('Import failed', { file: file_path, error: err.message });
|
|
55
|
+
|
|
56
|
+
// Display user-friendly error
|
|
57
|
+
output(`Import failed: ${err.message}`);
|
|
58
|
+
|
|
59
|
+
if (err.validationErrors && err.validationErrors.length > 0) {
|
|
60
|
+
output("\nValidation errors:");
|
|
61
|
+
for (error of err.validationErrors) {
|
|
62
|
+
output(` - ${error}`);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
output("\nSuggested fix:");
|
|
67
|
+
output(" Ensure the file is a valid session export from /ez:export-session");
|
|
68
|
+
|
|
69
|
+
throw error;
|
|
70
|
+
}
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
### 4. Validate Imported Session
|
|
74
|
+
|
|
75
|
+
```
|
|
76
|
+
// Check required fields
|
|
77
|
+
session = importedData.session || importedData;
|
|
78
|
+
|
|
79
|
+
requiredFields = ['metadata', 'context'];
|
|
80
|
+
missingFields = [];
|
|
81
|
+
|
|
82
|
+
for (field of requiredFields) {
|
|
83
|
+
if (!session[field]) {
|
|
84
|
+
missingFields.push(field);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
if (missingFields.length > 0) {
|
|
89
|
+
warnings.push(`Missing optional fields: ${missingFields.join(', ')}`);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// Check session_chain integrity
|
|
93
|
+
if (session.metadata?.session_chain) {
|
|
94
|
+
for (chainId of session.metadata.session_chain) {
|
|
95
|
+
linkedSession = mgr.loadSession(chainId);
|
|
96
|
+
if (!linkedSession) {
|
|
97
|
+
warnings.push(`Missing linked session: ${chainId}`);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
### 5. Create or Update Session
|
|
104
|
+
|
|
105
|
+
```
|
|
106
|
+
// Check if session_id already exists
|
|
107
|
+
existingSession = mgr.loadSession(result.sessionId);
|
|
108
|
+
|
|
109
|
+
if (existingSession) {
|
|
110
|
+
// Generate new session_id with timestamp suffix
|
|
111
|
+
timestamp = Date.now();
|
|
112
|
+
newSessionId = `${result.sessionId}-imported-${timestamp}`;
|
|
113
|
+
|
|
114
|
+
// Create new session with modified ID
|
|
115
|
+
mgr.createSession({
|
|
116
|
+
model: session.metadata?.model,
|
|
117
|
+
phase: session.metadata?.phase,
|
|
118
|
+
plan: session.metadata?.plan
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
// Update with imported data
|
|
122
|
+
mgr.updateSession(newSessionId, {
|
|
123
|
+
context: session.context,
|
|
124
|
+
state: session.state,
|
|
125
|
+
metadata: {
|
|
126
|
+
...session.metadata,
|
|
127
|
+
session_id: newSessionId,
|
|
128
|
+
session_chain: [...(session.metadata?.session_chain || []), result.sessionId]
|
|
129
|
+
}
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
result.sessionId = newSessionId;
|
|
133
|
+
logger.info('Session imported with new ID', {
|
|
134
|
+
original: result.sessionId,
|
|
135
|
+
new: newSessionId
|
|
136
|
+
});
|
|
137
|
+
} else {
|
|
138
|
+
// Update existing session created by importer
|
|
139
|
+
mgr.updateSession(result.sessionId, {
|
|
140
|
+
context: session.context,
|
|
141
|
+
state: session.state
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
### 6. Log Success
|
|
147
|
+
|
|
148
|
+
```
|
|
149
|
+
logger.info('Session imported', {
|
|
150
|
+
new_session_id: result.sessionId,
|
|
151
|
+
source_file: file_path
|
|
152
|
+
});
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
### 7. Return Result
|
|
156
|
+
|
|
157
|
+
```
|
|
158
|
+
return {
|
|
159
|
+
success: true,
|
|
160
|
+
session_id: result.sessionId,
|
|
161
|
+
warnings: warnings || []
|
|
162
|
+
};
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
---
|
|
166
|
+
|
|
167
|
+
## Import Confirmation Display
|
|
168
|
+
|
|
169
|
+
```
|
|
170
|
+
Session imported successfully!
|
|
171
|
+
|
|
172
|
+
Session ID: {sessionId}
|
|
173
|
+
Source: {file_path}
|
|
174
|
+
Original model: {model}
|
|
175
|
+
Original phase: {phase}
|
|
176
|
+
Original plan: {plan}
|
|
177
|
+
|
|
178
|
+
{warnings.length > 0 ? `Warnings:\n - ${warnings.join('\n - ')}` : ''}
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
---
|
|
182
|
+
|
|
183
|
+
## Session Summary Display
|
|
184
|
+
|
|
185
|
+
```
|
|
186
|
+
Session Summary:
|
|
187
|
+
|
|
188
|
+
Tasks Completed: {completedTasks.length}
|
|
189
|
+
Tasks Incomplete: {incompleteTasks.length}
|
|
190
|
+
Key Decisions: {decisions.length}
|
|
191
|
+
File Changes: {fileChanges.length}
|
|
192
|
+
|
|
193
|
+
Incomplete Tasks:
|
|
194
|
+
{incompleteTasks.map(t => ` - ${t}`).join('\n')}
|
|
195
|
+
|
|
196
|
+
Recommended Next Action:
|
|
197
|
+
{nextAction}
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
---
|
|
201
|
+
|
|
202
|
+
## Follow-up Actions
|
|
203
|
+
|
|
204
|
+
```
|
|
205
|
+
What would you like to do?
|
|
206
|
+
|
|
207
|
+
1. Resume this session
|
|
208
|
+
2. View session chain
|
|
209
|
+
3. Return to current session
|
|
210
|
+
4. Export this session
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
---
|
|
214
|
+
|
|
215
|
+
## Error Handling
|
|
216
|
+
|
|
217
|
+
### File Not Found
|
|
218
|
+
```
|
|
219
|
+
if (!fs.existsSync(file_path)) {
|
|
220
|
+
throw error(`File not found: ${file_path}`);
|
|
221
|
+
}
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
### Invalid JSON
|
|
225
|
+
```
|
|
226
|
+
try {
|
|
227
|
+
importedData = JSON.parse(content);
|
|
228
|
+
} catch (err) {
|
|
229
|
+
throw error(`Invalid JSON format: ${err.message}`);
|
|
230
|
+
}
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
### Missing Required Fields
|
|
234
|
+
```
|
|
235
|
+
if (!session.metadata || !session.context) {
|
|
236
|
+
throw error("Invalid session format: Missing metadata or context");
|
|
237
|
+
}
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
### Circular Chain Reference
|
|
241
|
+
```
|
|
242
|
+
if (session.metadata?.session_chain?.includes(session.metadata.session_id)) {
|
|
243
|
+
throw error("Invalid session chain: Circular reference detected");
|
|
244
|
+
}
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
---
|
|
248
|
+
|
|
249
|
+
## Model-Specific Adapters
|
|
250
|
+
|
|
251
|
+
### Claude Format
|
|
252
|
+
```javascript
|
|
253
|
+
_adaptClaudeFormat(data) {
|
|
254
|
+
// Claude may export with different structure
|
|
255
|
+
// Adapt to standard session format
|
|
256
|
+
return {
|
|
257
|
+
metadata: {
|
|
258
|
+
session_id: data.id || data.session_id,
|
|
259
|
+
model: 'claude',
|
|
260
|
+
...data.metadata
|
|
261
|
+
},
|
|
262
|
+
context: data.context || data.conversation,
|
|
263
|
+
state: data.state || {}
|
|
264
|
+
};
|
|
265
|
+
}
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
### Qwen Format
|
|
269
|
+
```javascript
|
|
270
|
+
_adaptQwenFormat(data) {
|
|
271
|
+
// Qwen standard format (already compatible)
|
|
272
|
+
return data;
|
|
273
|
+
}
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
### OpenAI Format
|
|
277
|
+
```javascript
|
|
278
|
+
_adaptOpenAIFormat(data) {
|
|
279
|
+
// OpenAI may use different field names
|
|
280
|
+
return {
|
|
281
|
+
metadata: data.metadata || data.session_metadata,
|
|
282
|
+
context: data.context || data.messages,
|
|
283
|
+
state: data.state || {}
|
|
284
|
+
};
|
|
285
|
+
}
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
### Kimi Format
|
|
289
|
+
```javascript
|
|
290
|
+
_adaptKimiFormat(data) {
|
|
291
|
+
// Kimi standard format (already compatible)
|
|
292
|
+
return data;
|
|
293
|
+
}
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
---
|
|
297
|
+
|
|
298
|
+
## Related Files
|
|
299
|
+
|
|
300
|
+
- `ez-agents/bin/lib/session-manager.cjs` - Session creation
|
|
301
|
+
- `ez-agents/bin/lib/session-import.cjs` - Import logic
|
|
302
|
+
- `ez-agents/bin/lib/session-errors.cjs` - Error classes
|
|
303
|
+
- `.planning/sessions/` - Session storage directory
|