@renseiai/agentfactory-cli 0.8.9 → 0.8.10
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/dist/src/cleanup.d.ts +1 -1
- package/dist/src/cleanup.js +2 -2
- package/dist/src/lib/cleanup-runner.d.ts +1 -1
- package/dist/src/lib/cleanup-runner.d.ts.map +1 -1
- package/dist/src/lib/cleanup-runner.js +26 -4
- package/dist/src/lib/orchestrator-runner.js +1 -1
- package/dist/src/lib/worker-runner.js +1 -1
- package/dist/src/migrate-worktrees.d.ts +17 -0
- package/dist/src/migrate-worktrees.d.ts.map +1 -0
- package/dist/src/migrate-worktrees.js +231 -0
- package/package.json +7 -6
package/dist/src/cleanup.d.ts
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
* Options:
|
|
11
11
|
* --dry-run Show what would be cleaned up without removing anything
|
|
12
12
|
* --force Force removal / include branches with gone remotes
|
|
13
|
-
* --path <dir> Custom worktrees directory (default: .
|
|
13
|
+
* --path <dir> Custom worktrees directory (default: ../{repoName}.wt)
|
|
14
14
|
* --skip-worktrees Skip worktree cleanup
|
|
15
15
|
* --skip-branches Skip branch cleanup
|
|
16
16
|
* --help, -h Show this help message
|
package/dist/src/cleanup.js
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
* Options:
|
|
11
11
|
* --dry-run Show what would be cleaned up without removing anything
|
|
12
12
|
* --force Force removal / include branches with gone remotes
|
|
13
|
-
* --path <dir> Custom worktrees directory (default: .
|
|
13
|
+
* --path <dir> Custom worktrees directory (default: ../{repoName}.wt)
|
|
14
14
|
* --skip-worktrees Skip worktree cleanup
|
|
15
15
|
* --skip-branches Skip branch cleanup
|
|
16
16
|
* --help, -h Show this help message
|
|
@@ -62,7 +62,7 @@ Usage:
|
|
|
62
62
|
Options:
|
|
63
63
|
--dry-run Show what would be cleaned up without removing
|
|
64
64
|
--force Force worktree removal + delete branches with gone remotes
|
|
65
|
-
--path <dir> Custom worktrees directory (default: .
|
|
65
|
+
--path <dir> Custom worktrees directory (default: ../{repoName}.wt)
|
|
66
66
|
--skip-worktrees Skip worktree cleanup
|
|
67
67
|
--skip-branches Skip branch cleanup
|
|
68
68
|
--help, -h Show this help message
|
|
@@ -9,7 +9,7 @@ export interface CleanupRunnerConfig {
|
|
|
9
9
|
dryRun?: boolean;
|
|
10
10
|
/** Force removal even if worktree appears active (default: false) */
|
|
11
11
|
force?: boolean;
|
|
12
|
-
/** Custom worktrees directory (default: {
|
|
12
|
+
/** Custom worktrees directory (default: ../{repoName}.wt) */
|
|
13
13
|
worktreePath?: string;
|
|
14
14
|
/** Git root for default worktree path (default: auto-detect) */
|
|
15
15
|
gitRoot?: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cleanup-runner.d.ts","sourceRoot":"","sources":["../../../src/lib/cleanup-runner.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAaH,MAAM,WAAW,mBAAmB;IAClC,sEAAsE;IACtE,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,qEAAqE;IACrE,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,
|
|
1
|
+
{"version":3,"file":"cleanup-runner.d.ts","sourceRoot":"","sources":["../../../src/lib/cleanup-runner.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAaH,MAAM,WAAW,mBAAmB;IAClC,sEAAsE;IACtE,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,qEAAqE;IACrE,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,6DAA6D;IAC7D,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,gEAAgE;IAChE,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,6CAA6C;IAC7C,aAAa,CAAC,EAAE,OAAO,CAAA;IACvB,2CAA2C;IAC3C,YAAY,CAAC,EAAE,OAAO,CAAA;CACvB;AAED,MAAM,WAAW,qBAAqB;IACpC,OAAO,EAAE,MAAM,CAAA;IACf,QAAQ,EAAE,MAAM,CAAA;IAChB,OAAO,EAAE,MAAM,CAAA;IACf,OAAO,EAAE,MAAM,CAAA;IACf,MAAM,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;CAC/C;AAED,MAAM,WAAW,aAAc,SAAQ,qBAAqB;IAC1D,QAAQ,EAAE,mBAAmB,CAAA;CAC9B;AAED,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,MAAM,CAAA;IACf,OAAO,EAAE,MAAM,CAAA;IACf,MAAM,EAAE,KAAK,CAAC;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;CACjD;AAuBD,wBAAgB,UAAU,IAAI,MAAM,CASnC;AA8bD,wBAAgB,UAAU,CAAC,MAAM,CAAC,EAAE,mBAAmB,GAAG,aAAa,CAyCtE"}
|
|
@@ -430,14 +430,36 @@ function cleanupBranches(options) {
|
|
|
430
430
|
// ---------------------------------------------------------------------------
|
|
431
431
|
export function runCleanup(config) {
|
|
432
432
|
const gitRoot = config?.gitRoot ?? getGitRoot();
|
|
433
|
+
const defaultWorktreePath = resolve(gitRoot, '..', basename(gitRoot) + '.wt');
|
|
433
434
|
const options = {
|
|
434
435
|
dryRun: config?.dryRun ?? false,
|
|
435
436
|
force: config?.force ?? false,
|
|
436
|
-
worktreePath: config?.worktreePath ??
|
|
437
|
+
worktreePath: config?.worktreePath ?? defaultWorktreePath,
|
|
437
438
|
};
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
439
|
+
// Also scan legacy .worktrees/ location during migration period
|
|
440
|
+
const legacyPath = resolve(gitRoot, '.worktrees');
|
|
441
|
+
const hasLegacyWorktrees = !config?.worktreePath && existsSync(legacyPath);
|
|
442
|
+
if (hasLegacyWorktrees) {
|
|
443
|
+
console.log(`\nNote: Found worktrees at legacy location ${legacyPath}`);
|
|
444
|
+
console.log(' Run "af-migrate-worktrees" to move them to the new default location.\n');
|
|
445
|
+
}
|
|
446
|
+
let worktreeResult;
|
|
447
|
+
if (config?.skipWorktrees) {
|
|
448
|
+
worktreeResult = { scanned: 0, orphaned: 0, cleaned: 0, skipped: 0, errors: [] };
|
|
449
|
+
}
|
|
450
|
+
else {
|
|
451
|
+
worktreeResult = cleanup(options);
|
|
452
|
+
// Merge results from legacy .worktrees/ location if it exists
|
|
453
|
+
if (hasLegacyWorktrees) {
|
|
454
|
+
const legacyOptions = { ...options, worktreePath: legacyPath };
|
|
455
|
+
const legacyResult = cleanup(legacyOptions);
|
|
456
|
+
worktreeResult.scanned += legacyResult.scanned;
|
|
457
|
+
worktreeResult.orphaned += legacyResult.orphaned;
|
|
458
|
+
worktreeResult.cleaned += legacyResult.cleaned;
|
|
459
|
+
worktreeResult.skipped += legacyResult.skipped;
|
|
460
|
+
worktreeResult.errors.push(...legacyResult.errors);
|
|
461
|
+
}
|
|
462
|
+
}
|
|
441
463
|
const branchResult = config?.skipBranches
|
|
442
464
|
? { scanned: 0, deleted: 0, errors: [] }
|
|
443
465
|
: cleanupBranches(options);
|
|
@@ -84,7 +84,7 @@ export async function runOrchestrator(config) {
|
|
|
84
84
|
const orchestratorConfig = {
|
|
85
85
|
project: config.project,
|
|
86
86
|
maxConcurrent,
|
|
87
|
-
worktreePath: path.resolve(gitRoot, '.
|
|
87
|
+
worktreePath: path.resolve(gitRoot, '..', path.basename(gitRoot) + '.wt'),
|
|
88
88
|
linearApiKey: config.linearApiKey,
|
|
89
89
|
issueTrackerClient,
|
|
90
90
|
statusMappings,
|
|
@@ -421,7 +421,7 @@ export async function runWorker(config, signal) {
|
|
|
421
421
|
const statusMappings = createLinearStatusMappings();
|
|
422
422
|
const orchestrator = createOrchestrator({
|
|
423
423
|
maxConcurrent: 1,
|
|
424
|
-
worktreePath: path.resolve(gitRoot, '.
|
|
424
|
+
worktreePath: path.resolve(gitRoot, '..', path.basename(gitRoot) + '.wt'),
|
|
425
425
|
issueTrackerClient,
|
|
426
426
|
statusMappings,
|
|
427
427
|
toolPlugins: [linearPlugin, codeIntelligencePlugin],
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* AgentFactory Worktree Migration CLI
|
|
4
|
+
*
|
|
5
|
+
* Migrates worktrees from the legacy .worktrees/ directory (inside repo)
|
|
6
|
+
* to the new sibling directory pattern (../{repoName}.wt/).
|
|
7
|
+
*
|
|
8
|
+
* Usage:
|
|
9
|
+
* af-migrate-worktrees [options]
|
|
10
|
+
*
|
|
11
|
+
* Options:
|
|
12
|
+
* --dry-run Preview changes without executing
|
|
13
|
+
* --force Move even if processes are using worktrees
|
|
14
|
+
* --help, -h Show this help message
|
|
15
|
+
*/
|
|
16
|
+
export {};
|
|
17
|
+
//# sourceMappingURL=migrate-worktrees.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"migrate-worktrees.d.ts","sourceRoot":"","sources":["../../src/migrate-worktrees.ts"],"names":[],"mappings":";AACA;;;;;;;;;;;;;GAaG"}
|
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* AgentFactory Worktree Migration CLI
|
|
4
|
+
*
|
|
5
|
+
* Migrates worktrees from the legacy .worktrees/ directory (inside repo)
|
|
6
|
+
* to the new sibling directory pattern (../{repoName}.wt/).
|
|
7
|
+
*
|
|
8
|
+
* Usage:
|
|
9
|
+
* af-migrate-worktrees [options]
|
|
10
|
+
*
|
|
11
|
+
* Options:
|
|
12
|
+
* --dry-run Preview changes without executing
|
|
13
|
+
* --force Move even if processes are using worktrees
|
|
14
|
+
* --help, -h Show this help message
|
|
15
|
+
*/
|
|
16
|
+
import { execSync } from 'child_process';
|
|
17
|
+
import { existsSync, mkdirSync, readdirSync, renameSync, rmSync, statSync } from 'fs';
|
|
18
|
+
import { basename, resolve } from 'path';
|
|
19
|
+
function getGitRoot() {
|
|
20
|
+
try {
|
|
21
|
+
return execSync('git rev-parse --show-toplevel', {
|
|
22
|
+
encoding: 'utf-8',
|
|
23
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
24
|
+
}).trim();
|
|
25
|
+
}
|
|
26
|
+
catch {
|
|
27
|
+
return process.cwd();
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
function parseArgs() {
|
|
31
|
+
const args = process.argv.slice(2);
|
|
32
|
+
const result = { dryRun: false, force: false };
|
|
33
|
+
for (const arg of args) {
|
|
34
|
+
switch (arg) {
|
|
35
|
+
case '--dry-run':
|
|
36
|
+
result.dryRun = true;
|
|
37
|
+
break;
|
|
38
|
+
case '--force':
|
|
39
|
+
result.force = true;
|
|
40
|
+
break;
|
|
41
|
+
case '--help':
|
|
42
|
+
case '-h':
|
|
43
|
+
printHelp();
|
|
44
|
+
process.exit(0);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
return result;
|
|
48
|
+
}
|
|
49
|
+
function printHelp() {
|
|
50
|
+
console.log(`
|
|
51
|
+
AgentFactory Worktree Migration
|
|
52
|
+
|
|
53
|
+
Migrates worktrees from .worktrees/ (inside repo) to ../{repoName}.wt/ (sibling directory).
|
|
54
|
+
This prevents VSCode file watcher crashes when running multiple concurrent agents.
|
|
55
|
+
|
|
56
|
+
Usage:
|
|
57
|
+
af-migrate-worktrees [options]
|
|
58
|
+
|
|
59
|
+
Options:
|
|
60
|
+
--dry-run Preview changes without executing
|
|
61
|
+
--force Move even if processes are using worktrees
|
|
62
|
+
--help, -h Show this help message
|
|
63
|
+
`);
|
|
64
|
+
}
|
|
65
|
+
function main() {
|
|
66
|
+
const { dryRun, force } = parseArgs();
|
|
67
|
+
const gitRoot = getGitRoot();
|
|
68
|
+
const repoName = basename(gitRoot);
|
|
69
|
+
const legacyDir = resolve(gitRoot, '.worktrees');
|
|
70
|
+
const newDir = resolve(gitRoot, '..', `${repoName}.wt`);
|
|
71
|
+
console.log('\n=== AgentFactory Worktree Migration ===\n');
|
|
72
|
+
if (dryRun) {
|
|
73
|
+
console.log('[DRY RUN MODE - No changes will be made]\n');
|
|
74
|
+
}
|
|
75
|
+
if (!existsSync(legacyDir)) {
|
|
76
|
+
console.log(`No legacy worktrees directory found at ${legacyDir}`);
|
|
77
|
+
console.log('Nothing to migrate.\n');
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
// List worktree entries (skip hidden directories like .patches)
|
|
81
|
+
const entries = readdirSync(legacyDir).filter(entry => {
|
|
82
|
+
if (entry.startsWith('.'))
|
|
83
|
+
return false;
|
|
84
|
+
try {
|
|
85
|
+
return statSync(resolve(legacyDir, entry)).isDirectory();
|
|
86
|
+
}
|
|
87
|
+
catch {
|
|
88
|
+
return false;
|
|
89
|
+
}
|
|
90
|
+
});
|
|
91
|
+
if (entries.length === 0) {
|
|
92
|
+
console.log(`Legacy worktrees directory exists but is empty: ${legacyDir}`);
|
|
93
|
+
if (!dryRun) {
|
|
94
|
+
rmSync(legacyDir, { recursive: true, force: true });
|
|
95
|
+
console.log('Removed empty legacy directory.\n');
|
|
96
|
+
}
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
console.log(`Found ${entries.length} worktree(s) to migrate:`);
|
|
100
|
+
console.log(` From: ${legacyDir}`);
|
|
101
|
+
console.log(` To: ${newDir}\n`);
|
|
102
|
+
// Check for running processes unless --force
|
|
103
|
+
if (!force && !dryRun) {
|
|
104
|
+
for (const entry of entries) {
|
|
105
|
+
const entryPath = resolve(legacyDir, entry);
|
|
106
|
+
try {
|
|
107
|
+
const lsofOutput = execSync(`lsof +D "${entryPath}" 2>/dev/null || true`, {
|
|
108
|
+
encoding: 'utf-8',
|
|
109
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
110
|
+
}).trim();
|
|
111
|
+
if (lsofOutput) {
|
|
112
|
+
console.log(`WARNING: Processes are using worktree ${entry}:`);
|
|
113
|
+
console.log(` ${lsofOutput.split('\n')[0]}`);
|
|
114
|
+
console.log(' Use --force to move anyway, or stop the processes first.\n');
|
|
115
|
+
process.exit(1);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
catch {
|
|
119
|
+
// lsof not available or failed, skip check
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
// Ensure target directory exists
|
|
124
|
+
if (!dryRun && !existsSync(newDir)) {
|
|
125
|
+
mkdirSync(newDir, { recursive: true });
|
|
126
|
+
}
|
|
127
|
+
let migrated = 0;
|
|
128
|
+
let failed = 0;
|
|
129
|
+
for (const entry of entries) {
|
|
130
|
+
const oldPath = resolve(legacyDir, entry);
|
|
131
|
+
const newPath = resolve(newDir, entry);
|
|
132
|
+
console.log(` ${entry}:`);
|
|
133
|
+
console.log(` ${oldPath} -> ${newPath}`);
|
|
134
|
+
if (dryRun) {
|
|
135
|
+
console.log(' [DRY RUN] Would move\n');
|
|
136
|
+
migrated++;
|
|
137
|
+
continue;
|
|
138
|
+
}
|
|
139
|
+
if (existsSync(newPath)) {
|
|
140
|
+
console.log(` SKIPPED: Target already exists\n`);
|
|
141
|
+
failed++;
|
|
142
|
+
continue;
|
|
143
|
+
}
|
|
144
|
+
try {
|
|
145
|
+
// Try git worktree move first (preferred — updates git tracking)
|
|
146
|
+
execSync(`git worktree move "${oldPath}" "${newPath}"`, {
|
|
147
|
+
stdio: 'pipe',
|
|
148
|
+
encoding: 'utf-8',
|
|
149
|
+
cwd: gitRoot,
|
|
150
|
+
});
|
|
151
|
+
console.log(' OK (git worktree move)\n');
|
|
152
|
+
migrated++;
|
|
153
|
+
}
|
|
154
|
+
catch {
|
|
155
|
+
// Fallback: manual move + repair
|
|
156
|
+
try {
|
|
157
|
+
renameSync(oldPath, newPath);
|
|
158
|
+
execSync(`git worktree repair`, {
|
|
159
|
+
stdio: 'pipe',
|
|
160
|
+
encoding: 'utf-8',
|
|
161
|
+
cwd: gitRoot,
|
|
162
|
+
});
|
|
163
|
+
console.log(' OK (manual move + repair)\n');
|
|
164
|
+
migrated++;
|
|
165
|
+
}
|
|
166
|
+
catch (fallbackError) {
|
|
167
|
+
console.log(` FAILED: ${fallbackError instanceof Error ? fallbackError.message : String(fallbackError)}\n`);
|
|
168
|
+
failed++;
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
// Move .patches directory if it exists
|
|
173
|
+
const legacyPatchDir = resolve(legacyDir, '.patches');
|
|
174
|
+
if (existsSync(legacyPatchDir)) {
|
|
175
|
+
const newPatchDir = resolve(newDir, '.patches');
|
|
176
|
+
if (!dryRun) {
|
|
177
|
+
try {
|
|
178
|
+
renameSync(legacyPatchDir, newPatchDir);
|
|
179
|
+
console.log(' Moved .patches directory\n');
|
|
180
|
+
}
|
|
181
|
+
catch (error) {
|
|
182
|
+
console.log(` Failed to move .patches: ${error instanceof Error ? error.message : String(error)}\n`);
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
else {
|
|
186
|
+
console.log(' [DRY RUN] Would move .patches directory\n');
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
// Clean up empty legacy directory
|
|
190
|
+
if (!dryRun && migrated > 0) {
|
|
191
|
+
try {
|
|
192
|
+
const remaining = readdirSync(legacyDir);
|
|
193
|
+
if (remaining.length === 0) {
|
|
194
|
+
rmSync(legacyDir, { recursive: true, force: true });
|
|
195
|
+
console.log(`Removed empty legacy directory: ${legacyDir}\n`);
|
|
196
|
+
}
|
|
197
|
+
else {
|
|
198
|
+
console.log(`Legacy directory not empty (${remaining.length} remaining entries), keeping it.\n`);
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
catch {
|
|
202
|
+
// Ignore cleanup errors
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
// Summary
|
|
206
|
+
console.log('=== Summary ===\n');
|
|
207
|
+
console.log(` Migrated: ${migrated}`);
|
|
208
|
+
if (failed > 0) {
|
|
209
|
+
console.log(` Failed: ${failed}`);
|
|
210
|
+
}
|
|
211
|
+
console.log('');
|
|
212
|
+
// Verify git tracking
|
|
213
|
+
if (!dryRun && migrated > 0) {
|
|
214
|
+
try {
|
|
215
|
+
const worktreeList = execSync('git worktree list', {
|
|
216
|
+
encoding: 'utf-8',
|
|
217
|
+
cwd: gitRoot,
|
|
218
|
+
}).trim();
|
|
219
|
+
console.log('Git worktree list after migration:');
|
|
220
|
+
console.log(worktreeList);
|
|
221
|
+
console.log('');
|
|
222
|
+
}
|
|
223
|
+
catch {
|
|
224
|
+
// Ignore
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
if (failed > 0) {
|
|
228
|
+
process.exit(1);
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
main();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@renseiai/agentfactory-cli",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.10",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "CLI tools for AgentFactory — local orchestrator, remote worker, queue admin",
|
|
6
6
|
"author": "Rensei AI (https://rensei.ai)",
|
|
@@ -38,7 +38,8 @@
|
|
|
38
38
|
"af-linear": "dist/src/linear.js",
|
|
39
39
|
"af-governor": "dist/src/governor.js",
|
|
40
40
|
"af-sync-routes": "dist/src/sync-routes.js",
|
|
41
|
-
"af-status": "dist/src/status.js"
|
|
41
|
+
"af-status": "dist/src/status.js",
|
|
42
|
+
"af-migrate-worktrees": "dist/src/migrate-worktrees.js"
|
|
42
43
|
},
|
|
43
44
|
"main": "./dist/src/index.js",
|
|
44
45
|
"module": "./dist/src/index.js",
|
|
@@ -107,10 +108,10 @@
|
|
|
107
108
|
],
|
|
108
109
|
"dependencies": {
|
|
109
110
|
"dotenv": "^17.2.3",
|
|
110
|
-
"@renseiai/agentfactory": "0.8.
|
|
111
|
-
"@renseiai/
|
|
112
|
-
"@renseiai/
|
|
113
|
-
"@renseiai/agentfactory-
|
|
111
|
+
"@renseiai/agentfactory": "0.8.10",
|
|
112
|
+
"@renseiai/agentfactory-code-intelligence": "0.8.10",
|
|
113
|
+
"@renseiai/plugin-linear": "0.8.10",
|
|
114
|
+
"@renseiai/agentfactory-server": "0.8.10"
|
|
114
115
|
},
|
|
115
116
|
"devDependencies": {
|
|
116
117
|
"@types/node": "^22.5.4",
|