@blockspool/cli 0.4.1 → 0.4.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bin/blockspool.d.ts +16 -0
- package/dist/bin/blockspool.d.ts.map +1 -0
- package/dist/bin/blockspool.js +45 -0
- package/dist/bin/blockspool.js.map +1 -0
- package/dist/commands/solo-auto.d.ts +6 -0
- package/dist/commands/solo-auto.d.ts.map +1 -0
- package/dist/commands/solo-auto.js +418 -0
- package/dist/commands/solo-auto.js.map +1 -0
- package/dist/commands/solo-exec.d.ts +6 -0
- package/dist/commands/solo-exec.d.ts.map +1 -0
- package/dist/commands/solo-exec.js +656 -0
- package/dist/commands/solo-exec.js.map +1 -0
- package/dist/commands/solo-inspect.d.ts +6 -0
- package/dist/commands/solo-inspect.d.ts.map +1 -0
- package/dist/commands/solo-inspect.js +690 -0
- package/dist/commands/solo-inspect.js.map +1 -0
- package/dist/commands/solo-lifecycle.d.ts +6 -0
- package/dist/commands/solo-lifecycle.d.ts.map +1 -0
- package/dist/commands/solo-lifecycle.js +188 -0
- package/dist/commands/solo-lifecycle.js.map +1 -0
- package/dist/commands/solo-nudge.d.ts +6 -0
- package/dist/commands/solo-nudge.d.ts.map +1 -0
- package/dist/commands/solo-nudge.js +49 -0
- package/dist/commands/solo-nudge.js.map +1 -0
- package/dist/commands/solo-qa.d.ts +6 -0
- package/dist/commands/solo-qa.d.ts.map +1 -0
- package/dist/commands/solo-qa.js +254 -0
- package/dist/commands/solo-qa.js.map +1 -0
- package/dist/commands/solo.d.ts +11 -0
- package/dist/commands/solo.d.ts.map +1 -0
- package/dist/commands/solo.js +43 -0
- package/dist/commands/solo.js.map +1 -0
- package/dist/index.d.ts +18 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +18 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/artifacts.d.ts +136 -0
- package/dist/lib/artifacts.d.ts.map +1 -0
- package/dist/lib/artifacts.js +146 -0
- package/dist/lib/artifacts.js.map +1 -0
- package/dist/lib/doctor.d.ts +45 -0
- package/dist/lib/doctor.d.ts.map +1 -0
- package/dist/lib/doctor.js +383 -0
- package/dist/lib/doctor.js.map +1 -0
- package/dist/lib/exec.d.ts +24 -0
- package/dist/lib/exec.d.ts.map +1 -0
- package/dist/lib/exec.js +295 -0
- package/dist/lib/exec.js.map +1 -0
- package/dist/lib/formulas.d.ts +78 -0
- package/dist/lib/formulas.d.ts.map +1 -0
- package/dist/lib/formulas.js +295 -0
- package/dist/lib/formulas.js.map +1 -0
- package/dist/lib/git.d.ts +9 -0
- package/dist/lib/git.d.ts.map +1 -0
- package/dist/lib/git.js +60 -0
- package/dist/lib/git.js.map +1 -0
- package/dist/lib/guidelines.d.ts +43 -0
- package/dist/lib/guidelines.d.ts.map +1 -0
- package/dist/lib/guidelines.js +195 -0
- package/dist/lib/guidelines.js.map +1 -0
- package/dist/lib/logger.d.ts +17 -0
- package/dist/lib/logger.d.ts.map +1 -0
- package/dist/lib/logger.js +42 -0
- package/dist/lib/logger.js.map +1 -0
- package/dist/lib/retention.d.ts +62 -0
- package/dist/lib/retention.d.ts.map +1 -0
- package/dist/lib/retention.js +285 -0
- package/dist/lib/retention.js.map +1 -0
- package/dist/lib/run-history.d.ts +52 -0
- package/dist/lib/run-history.d.ts.map +1 -0
- package/dist/lib/run-history.js +116 -0
- package/dist/lib/run-history.js.map +1 -0
- package/dist/lib/run-state.d.ts +58 -0
- package/dist/lib/run-state.d.ts.map +1 -0
- package/dist/lib/run-state.js +119 -0
- package/dist/lib/run-state.js.map +1 -0
- package/dist/lib/scope.d.ts +95 -0
- package/dist/lib/scope.d.ts.map +1 -0
- package/dist/lib/scope.js +291 -0
- package/dist/lib/scope.js.map +1 -0
- package/dist/lib/selection.d.ts +35 -0
- package/dist/lib/selection.d.ts.map +1 -0
- package/dist/lib/selection.js +110 -0
- package/dist/lib/selection.js.map +1 -0
- package/dist/lib/solo-auto.d.ts +87 -0
- package/dist/lib/solo-auto.d.ts.map +1 -0
- package/dist/lib/solo-auto.js +1230 -0
- package/dist/lib/solo-auto.js.map +1 -0
- package/dist/lib/solo-ci.d.ts +84 -0
- package/dist/lib/solo-ci.d.ts.map +1 -0
- package/dist/lib/solo-ci.js +300 -0
- package/dist/lib/solo-ci.js.map +1 -0
- package/dist/lib/solo-config.d.ts +155 -0
- package/dist/lib/solo-config.d.ts.map +1 -0
- package/dist/lib/solo-config.js +236 -0
- package/dist/lib/solo-config.js.map +1 -0
- package/dist/lib/solo-git.d.ts +44 -0
- package/dist/lib/solo-git.d.ts.map +1 -0
- package/dist/lib/solo-git.js +174 -0
- package/dist/lib/solo-git.js.map +1 -0
- package/dist/lib/solo-hints.d.ts +32 -0
- package/dist/lib/solo-hints.d.ts.map +1 -0
- package/dist/lib/solo-hints.js +98 -0
- package/dist/lib/solo-hints.js.map +1 -0
- package/dist/lib/solo-remote.d.ts +14 -0
- package/dist/lib/solo-remote.d.ts.map +1 -0
- package/dist/lib/solo-remote.js +48 -0
- package/dist/lib/solo-remote.js.map +1 -0
- package/dist/lib/solo-stdin.d.ts +13 -0
- package/dist/lib/solo-stdin.d.ts.map +1 -0
- package/dist/lib/solo-stdin.js +33 -0
- package/dist/lib/solo-stdin.js.map +1 -0
- package/dist/lib/solo-ticket.d.ts +213 -0
- package/dist/lib/solo-ticket.d.ts.map +1 -0
- package/dist/lib/solo-ticket.js +850 -0
- package/dist/lib/solo-ticket.js.map +1 -0
- package/dist/lib/solo-utils.d.ts +133 -0
- package/dist/lib/solo-utils.d.ts.map +1 -0
- package/dist/lib/solo-utils.js +300 -0
- package/dist/lib/solo-utils.js.map +1 -0
- package/dist/lib/spindle.d.ts +144 -0
- package/dist/lib/spindle.d.ts.map +1 -0
- package/dist/lib/spindle.js +388 -0
- package/dist/lib/spindle.js.map +1 -0
- package/dist/tui/app.d.ts +17 -0
- package/dist/tui/app.d.ts.map +1 -0
- package/dist/tui/app.js +139 -0
- package/dist/tui/app.js.map +1 -0
- package/dist/tui/index.d.ts +8 -0
- package/dist/tui/index.d.ts.map +1 -0
- package/dist/tui/index.js +7 -0
- package/dist/tui/index.js.map +1 -0
- package/dist/tui/poller.d.ts +42 -0
- package/dist/tui/poller.d.ts.map +1 -0
- package/dist/tui/poller.js +62 -0
- package/dist/tui/poller.js.map +1 -0
- package/dist/tui/screens/overview.d.ts +9 -0
- package/dist/tui/screens/overview.d.ts.map +1 -0
- package/dist/tui/screens/overview.js +189 -0
- package/dist/tui/screens/overview.js.map +1 -0
- package/dist/tui/state.d.ts +93 -0
- package/dist/tui/state.d.ts.map +1 -0
- package/dist/tui/state.js +169 -0
- package/dist/tui/state.js.map +1 -0
- package/dist/tui/types.d.ts +18 -0
- package/dist/tui/types.d.ts.map +1 -0
- package/dist/tui/types.js +5 -0
- package/dist/tui/types.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Solo mode configuration
|
|
3
|
+
*/
|
|
4
|
+
import { type DatabaseAdapter } from '@blockspool/core/db';
|
|
5
|
+
import type { ScoutDeps, ScoutProgress } from '@blockspool/core/services';
|
|
6
|
+
import type { TicketProposal } from '@blockspool/core/scout';
|
|
7
|
+
import type { SpindleConfig } from './spindle.js';
|
|
8
|
+
/**
|
|
9
|
+
* Retention configuration — caps on unbounded state accumulation.
|
|
10
|
+
* All values are item counts (not time-based), except maxStaleBranchDays.
|
|
11
|
+
*/
|
|
12
|
+
export interface RetentionConfig {
|
|
13
|
+
/** Keep last N run folders in .blockspool/runs/ (default 50) */
|
|
14
|
+
maxRuns: number;
|
|
15
|
+
/** Keep last N lines in history.ndjson (default 100) */
|
|
16
|
+
maxHistoryEntries: number;
|
|
17
|
+
/** Keep newest N artifact files per run folder (default 20) */
|
|
18
|
+
maxArtifactsPerRun: number;
|
|
19
|
+
/** Keep last N archived spool files (default 5) */
|
|
20
|
+
maxSpoolArchives: number;
|
|
21
|
+
/** Max deferred proposals in run-state.json (default 20) */
|
|
22
|
+
maxDeferredProposals: number;
|
|
23
|
+
/** Hard-delete oldest completed tickets beyond this cap (default 200) */
|
|
24
|
+
maxCompletedTickets: number;
|
|
25
|
+
/** Cap file_edit_counts keys in spindle state (default 50) */
|
|
26
|
+
maxSpindleFileEditKeys: number;
|
|
27
|
+
/** Keep last N local blockspool/* branches (default 10) */
|
|
28
|
+
maxMergedBranches: number;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Default retention configuration — conservative values.
|
|
32
|
+
*/
|
|
33
|
+
export declare const DEFAULT_RETENTION_CONFIG: RetentionConfig;
|
|
34
|
+
/**
|
|
35
|
+
* Auto configuration - the "trust ladder" settings
|
|
36
|
+
*/
|
|
37
|
+
export interface AutoConfig {
|
|
38
|
+
allowCategories: string[];
|
|
39
|
+
blockCategories: string[];
|
|
40
|
+
minConfidence: number;
|
|
41
|
+
maxPrs: number;
|
|
42
|
+
maxFilesPerTicket: number;
|
|
43
|
+
maxLinesPerTicket: number;
|
|
44
|
+
draftPrs: boolean;
|
|
45
|
+
defaultScope: string;
|
|
46
|
+
docsAudit: boolean;
|
|
47
|
+
docsAuditInterval: number;
|
|
48
|
+
/** Pull from origin every N cycles to stay current with team changes (0 = disabled, default 5) */
|
|
49
|
+
pullEveryNCycles: number;
|
|
50
|
+
/** What to do when pull fails due to divergence: "halt" stops the session, "warn" logs and continues (default "halt") */
|
|
51
|
+
pullPolicy: 'halt' | 'warn';
|
|
52
|
+
/** Re-read guidelines file every N cycles to pick up changes (default 10, 0 = disabled) */
|
|
53
|
+
guidelinesRefreshCycles: number;
|
|
54
|
+
/** Auto-create a baseline guidelines file (AGENTS.md or CLAUDE.md) if none exists (default true) */
|
|
55
|
+
autoCreateGuidelines: boolean;
|
|
56
|
+
/**
|
|
57
|
+
* Custom path to guidelines file, relative to repo root.
|
|
58
|
+
* Overrides the default CLAUDE.md / AGENTS.md search.
|
|
59
|
+
* Set to false to disable guidelines entirely.
|
|
60
|
+
* Examples: "docs/GUIDELINES.md", "CONVENTIONS.md", false
|
|
61
|
+
*/
|
|
62
|
+
guidelinesPath: string | false | null;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Default auto config - conservative "safe demo" settings
|
|
66
|
+
*/
|
|
67
|
+
export declare const DEFAULT_AUTO_CONFIG: AutoConfig;
|
|
68
|
+
/**
|
|
69
|
+
* Solo config file structure
|
|
70
|
+
*/
|
|
71
|
+
export interface SoloConfig {
|
|
72
|
+
version: number;
|
|
73
|
+
repoRoot: string;
|
|
74
|
+
createdAt: string;
|
|
75
|
+
dbPath: string;
|
|
76
|
+
qa?: {
|
|
77
|
+
commands: Array<{
|
|
78
|
+
name: string;
|
|
79
|
+
cmd: string;
|
|
80
|
+
cwd?: string;
|
|
81
|
+
timeoutSec?: number;
|
|
82
|
+
timeoutMs?: number;
|
|
83
|
+
}>;
|
|
84
|
+
retry?: {
|
|
85
|
+
enabled: boolean;
|
|
86
|
+
maxAttempts: number;
|
|
87
|
+
};
|
|
88
|
+
artifacts?: {
|
|
89
|
+
storeDir?: string;
|
|
90
|
+
maxLogBytes?: number;
|
|
91
|
+
tailBytes?: number;
|
|
92
|
+
};
|
|
93
|
+
};
|
|
94
|
+
allowedRemote?: string;
|
|
95
|
+
spindle?: Partial<SpindleConfig>;
|
|
96
|
+
auto?: Partial<AutoConfig>;
|
|
97
|
+
retention?: Partial<RetentionConfig>;
|
|
98
|
+
/** Max parallel tickets for plugin mode (default: 2, max: 5) */
|
|
99
|
+
pluginParallel?: number;
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Detected QA command from project configuration
|
|
103
|
+
*/
|
|
104
|
+
export interface DetectedQaCommand {
|
|
105
|
+
name: string;
|
|
106
|
+
cmd: string;
|
|
107
|
+
source: 'package.json' | 'detected';
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Get the .blockspool directory path (repo-local or global)
|
|
111
|
+
*/
|
|
112
|
+
export declare function getBlockspoolDir(repoRoot?: string): string;
|
|
113
|
+
/**
|
|
114
|
+
* Get database path
|
|
115
|
+
*/
|
|
116
|
+
export declare function getDbPath(repoRoot?: string): string;
|
|
117
|
+
/**
|
|
118
|
+
* Check if solo mode is initialized for a repo
|
|
119
|
+
*/
|
|
120
|
+
export declare function isInitialized(repoRoot: string): boolean;
|
|
121
|
+
/**
|
|
122
|
+
* Detect QA commands from project configuration
|
|
123
|
+
*/
|
|
124
|
+
export declare function detectQaCommands(repoRoot: string): DetectedQaCommand[];
|
|
125
|
+
/**
|
|
126
|
+
* Initialize solo mode for a repository
|
|
127
|
+
*/
|
|
128
|
+
export declare function initSolo(repoRoot: string): Promise<{
|
|
129
|
+
config: SoloConfig;
|
|
130
|
+
detectedQa: DetectedQaCommand[];
|
|
131
|
+
}>;
|
|
132
|
+
/**
|
|
133
|
+
* Load solo config
|
|
134
|
+
*/
|
|
135
|
+
export declare function loadConfig(repoRoot: string): SoloConfig | null;
|
|
136
|
+
/**
|
|
137
|
+
* Get or create database adapter
|
|
138
|
+
*/
|
|
139
|
+
export declare function getAdapter(repoRoot?: string): Promise<DatabaseAdapter>;
|
|
140
|
+
/**
|
|
141
|
+
* Create scout dependencies
|
|
142
|
+
*/
|
|
143
|
+
export declare function createScoutDeps(db: DatabaseAdapter, opts?: {
|
|
144
|
+
verbose?: boolean;
|
|
145
|
+
quiet?: boolean;
|
|
146
|
+
}): ScoutDeps;
|
|
147
|
+
/**
|
|
148
|
+
* Format progress for display
|
|
149
|
+
*/
|
|
150
|
+
export declare function formatProgress(progress: ScoutProgress): string;
|
|
151
|
+
/**
|
|
152
|
+
* Display a proposal summary
|
|
153
|
+
*/
|
|
154
|
+
export declare function displayProposal(proposal: TicketProposal, index: number): void;
|
|
155
|
+
//# sourceMappingURL=solo-config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"solo-config.d.ts","sourceRoot":"","sources":["../../src/lib/solo-config.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Solo mode configuration
|
|
3
|
+
*/
|
|
4
|
+
import * as path from 'node:path';
|
|
5
|
+
import * as fs from 'node:fs';
|
|
6
|
+
import chalk from 'chalk';
|
|
7
|
+
import { createSQLiteAdapter } from '@blockspool/sqlite';
|
|
8
|
+
import { getDefaultDatabaseUrl } from '@blockspool/core/db';
|
|
9
|
+
import { createGitService } from './git.js';
|
|
10
|
+
import { createLogger } from './logger.js';
|
|
11
|
+
/**
|
|
12
|
+
* Default retention configuration — conservative values.
|
|
13
|
+
*/
|
|
14
|
+
export const DEFAULT_RETENTION_CONFIG = {
|
|
15
|
+
maxRuns: 50,
|
|
16
|
+
maxHistoryEntries: 100,
|
|
17
|
+
maxArtifactsPerRun: 20,
|
|
18
|
+
maxSpoolArchives: 5,
|
|
19
|
+
maxDeferredProposals: 20,
|
|
20
|
+
maxCompletedTickets: 200,
|
|
21
|
+
maxSpindleFileEditKeys: 50,
|
|
22
|
+
maxMergedBranches: 10,
|
|
23
|
+
};
|
|
24
|
+
/**
|
|
25
|
+
* Default auto config - conservative "safe demo" settings
|
|
26
|
+
*/
|
|
27
|
+
export const DEFAULT_AUTO_CONFIG = {
|
|
28
|
+
allowCategories: ['refactor', 'test', 'docs', 'types', 'perf'],
|
|
29
|
+
blockCategories: ['security', 'deps', 'auth', 'config', 'migration'],
|
|
30
|
+
minConfidence: 70,
|
|
31
|
+
maxPrs: 3,
|
|
32
|
+
maxFilesPerTicket: 10,
|
|
33
|
+
maxLinesPerTicket: 300,
|
|
34
|
+
draftPrs: true,
|
|
35
|
+
defaultScope: 'src',
|
|
36
|
+
docsAudit: true,
|
|
37
|
+
docsAuditInterval: 3,
|
|
38
|
+
pullEveryNCycles: 5,
|
|
39
|
+
pullPolicy: 'halt',
|
|
40
|
+
guidelinesRefreshCycles: 10,
|
|
41
|
+
autoCreateGuidelines: true,
|
|
42
|
+
guidelinesPath: null,
|
|
43
|
+
};
|
|
44
|
+
/**
|
|
45
|
+
* Get the .blockspool directory path (repo-local or global)
|
|
46
|
+
*/
|
|
47
|
+
export function getBlockspoolDir(repoRoot) {
|
|
48
|
+
if (repoRoot) {
|
|
49
|
+
return path.join(repoRoot, '.blockspool');
|
|
50
|
+
}
|
|
51
|
+
const home = process.env.HOME || process.env.USERPROFILE || '.';
|
|
52
|
+
return path.join(home, '.blockspool');
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Get database path
|
|
56
|
+
*/
|
|
57
|
+
export function getDbPath(repoRoot) {
|
|
58
|
+
const dir = getBlockspoolDir(repoRoot);
|
|
59
|
+
return path.join(dir, 'state.sqlite');
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Check if solo mode is initialized for a repo
|
|
63
|
+
*/
|
|
64
|
+
export function isInitialized(repoRoot) {
|
|
65
|
+
const configPath = path.join(getBlockspoolDir(repoRoot), 'config.json');
|
|
66
|
+
return fs.existsSync(configPath);
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Detect QA commands from project configuration
|
|
70
|
+
*/
|
|
71
|
+
export function detectQaCommands(repoRoot) {
|
|
72
|
+
const commands = [];
|
|
73
|
+
const packageJsonPath = path.join(repoRoot, 'package.json');
|
|
74
|
+
if (!fs.existsSync(packageJsonPath)) {
|
|
75
|
+
return commands;
|
|
76
|
+
}
|
|
77
|
+
try {
|
|
78
|
+
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf-8'));
|
|
79
|
+
const scripts = packageJson.scripts || {};
|
|
80
|
+
const qaPatterns = [
|
|
81
|
+
{ pattern: 'typecheck', priority: 1, name: 'typecheck' },
|
|
82
|
+
{ pattern: 'type-check', priority: 1, name: 'typecheck' },
|
|
83
|
+
{ pattern: 'check:types', priority: 1, name: 'typecheck' },
|
|
84
|
+
{ pattern: 'lint', priority: 2, name: 'lint' },
|
|
85
|
+
{ pattern: /^lint:.*/, priority: 2, name: 'lint' },
|
|
86
|
+
{ pattern: 'check', priority: 3, name: 'check' },
|
|
87
|
+
{ pattern: 'test', priority: 4, name: 'test' },
|
|
88
|
+
{ pattern: 'test:unit', priority: 4, name: 'test:unit' },
|
|
89
|
+
{ pattern: 'build', priority: 5, name: 'build' },
|
|
90
|
+
];
|
|
91
|
+
const added = new Set();
|
|
92
|
+
for (const { pattern, name } of qaPatterns) {
|
|
93
|
+
for (const [scriptName, _scriptCmd] of Object.entries(scripts)) {
|
|
94
|
+
const matches = typeof pattern === 'string'
|
|
95
|
+
? scriptName === pattern
|
|
96
|
+
: pattern.test(scriptName);
|
|
97
|
+
if (matches && !added.has(scriptName)) {
|
|
98
|
+
added.add(scriptName);
|
|
99
|
+
commands.push({
|
|
100
|
+
name: scriptName === name ? name : `${name} (${scriptName})`,
|
|
101
|
+
cmd: `npm run ${scriptName}`,
|
|
102
|
+
source: 'package.json',
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
const order = ['typecheck', 'lint', 'check', 'test', 'build'];
|
|
108
|
+
commands.sort((a, b) => {
|
|
109
|
+
const aIdx = order.findIndex(o => a.name.startsWith(o));
|
|
110
|
+
const bIdx = order.findIndex(o => b.name.startsWith(o));
|
|
111
|
+
return (aIdx === -1 ? 99 : aIdx) - (bIdx === -1 ? 99 : bIdx);
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
catch {
|
|
115
|
+
// Ignore JSON parse errors
|
|
116
|
+
}
|
|
117
|
+
return commands;
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Initialize solo mode for a repository
|
|
121
|
+
*/
|
|
122
|
+
export async function initSolo(repoRoot) {
|
|
123
|
+
const dir = getBlockspoolDir(repoRoot);
|
|
124
|
+
const configPath = path.join(dir, 'config.json');
|
|
125
|
+
const dbPath = getDbPath(repoRoot);
|
|
126
|
+
if (!fs.existsSync(dir)) {
|
|
127
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
128
|
+
}
|
|
129
|
+
const detectedQa = detectQaCommands(repoRoot);
|
|
130
|
+
// Capture origin remote URL for safety validation
|
|
131
|
+
let allowedRemote;
|
|
132
|
+
try {
|
|
133
|
+
const { execSync } = await import('child_process');
|
|
134
|
+
allowedRemote = execSync('git remote get-url origin', { cwd: repoRoot, encoding: 'utf-8' }).trim();
|
|
135
|
+
}
|
|
136
|
+
catch {
|
|
137
|
+
// No remote configured yet — that's fine
|
|
138
|
+
}
|
|
139
|
+
const config = {
|
|
140
|
+
version: 1,
|
|
141
|
+
repoRoot,
|
|
142
|
+
createdAt: new Date().toISOString(),
|
|
143
|
+
dbPath,
|
|
144
|
+
...(allowedRemote ? { allowedRemote } : {}),
|
|
145
|
+
};
|
|
146
|
+
if (detectedQa.length > 0) {
|
|
147
|
+
config.qa = {
|
|
148
|
+
commands: detectedQa.map(c => ({
|
|
149
|
+
name: c.name,
|
|
150
|
+
cmd: c.cmd,
|
|
151
|
+
})),
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
fs.writeFileSync(configPath, JSON.stringify(config, null, 2));
|
|
155
|
+
const gitignorePath = path.join(repoRoot, '.gitignore');
|
|
156
|
+
if (fs.existsSync(gitignorePath)) {
|
|
157
|
+
const content = fs.readFileSync(gitignorePath, 'utf-8');
|
|
158
|
+
if (!content.includes('.blockspool')) {
|
|
159
|
+
fs.appendFileSync(gitignorePath, '\n# BlockSpool local state\n.blockspool/\n');
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
return { config, detectedQa };
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Load solo config
|
|
166
|
+
*/
|
|
167
|
+
export function loadConfig(repoRoot) {
|
|
168
|
+
const configPath = path.join(getBlockspoolDir(repoRoot), 'config.json');
|
|
169
|
+
if (!fs.existsSync(configPath)) {
|
|
170
|
+
return null;
|
|
171
|
+
}
|
|
172
|
+
return JSON.parse(fs.readFileSync(configPath, 'utf-8'));
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* Get or create database adapter
|
|
176
|
+
*/
|
|
177
|
+
export async function getAdapter(repoRoot) {
|
|
178
|
+
const dbPath = repoRoot ? getDbPath(repoRoot) : getDefaultDatabaseUrl();
|
|
179
|
+
return createSQLiteAdapter({ url: dbPath });
|
|
180
|
+
}
|
|
181
|
+
/**
|
|
182
|
+
* Create scout dependencies
|
|
183
|
+
*/
|
|
184
|
+
export function createScoutDeps(db, opts = {}) {
|
|
185
|
+
return {
|
|
186
|
+
db,
|
|
187
|
+
git: createGitService(),
|
|
188
|
+
logger: createLogger(opts),
|
|
189
|
+
};
|
|
190
|
+
}
|
|
191
|
+
/**
|
|
192
|
+
* Format progress for display
|
|
193
|
+
*/
|
|
194
|
+
export function formatProgress(progress) {
|
|
195
|
+
switch (progress.phase) {
|
|
196
|
+
case 'init':
|
|
197
|
+
return chalk.gray(progress.message || 'Initializing...');
|
|
198
|
+
case 'scanning':
|
|
199
|
+
return chalk.gray(progress.message || 'Scanning files...');
|
|
200
|
+
case 'analyzing':
|
|
201
|
+
return chalk.gray(`Analyzing (${progress.filesScanned}/${progress.totalFiles} files, ` +
|
|
202
|
+
`${progress.proposalsFound} proposals)`);
|
|
203
|
+
case 'storing':
|
|
204
|
+
return chalk.gray(progress.message || 'Storing results...');
|
|
205
|
+
case 'complete':
|
|
206
|
+
return chalk.green(`Complete: ${progress.proposalsFound} proposals, ` +
|
|
207
|
+
`${progress.ticketsCreated} tickets created`);
|
|
208
|
+
default:
|
|
209
|
+
return '';
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
/**
|
|
213
|
+
* Display a proposal summary
|
|
214
|
+
*/
|
|
215
|
+
export function displayProposal(proposal, index) {
|
|
216
|
+
const categoryColors = {
|
|
217
|
+
refactor: chalk.cyan,
|
|
218
|
+
docs: chalk.yellow,
|
|
219
|
+
test: chalk.green,
|
|
220
|
+
perf: chalk.magenta,
|
|
221
|
+
security: chalk.red,
|
|
222
|
+
};
|
|
223
|
+
const color = categoryColors[proposal.category] || chalk.white;
|
|
224
|
+
console.log();
|
|
225
|
+
console.log(chalk.bold(`${index + 1}. ${proposal.title}`));
|
|
226
|
+
const impactStr = proposal.impact_score !== null ? ` | impact ${proposal.impact_score}/10` : '';
|
|
227
|
+
console.log(` ${color(proposal.category)} | ` +
|
|
228
|
+
`${proposal.estimated_complexity} | ` +
|
|
229
|
+
`${proposal.confidence}% confidence${impactStr}`);
|
|
230
|
+
console.log(` ${chalk.gray(proposal.description.slice(0, 100))}` +
|
|
231
|
+
`${proposal.description.length > 100 ? '...' : ''}`);
|
|
232
|
+
console.log(` ${chalk.gray('Files:')} ` +
|
|
233
|
+
`${proposal.files.slice(0, 3).join(', ')}` +
|
|
234
|
+
`${proposal.files.length > 3 ? ` +${proposal.files.length - 3} more` : ''}`);
|
|
235
|
+
}
|
|
236
|
+
//# sourceMappingURL=solo-config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"solo-config.js","sourceRoot":"","sources":["../../src/lib/solo-config.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Solo mode git utilities
|
|
3
|
+
*/
|
|
4
|
+
export declare function withGitMutex<T>(fn: () => Promise<T>): Promise<T>;
|
|
5
|
+
/**
|
|
6
|
+
* Async git command execution — does not block the event loop.
|
|
7
|
+
* Used instead of execSync to allow parallel ticket execution.
|
|
8
|
+
*/
|
|
9
|
+
export declare function gitExec(cmd: string, opts: {
|
|
10
|
+
cwd: string;
|
|
11
|
+
encoding?: 'utf-8';
|
|
12
|
+
maxBuffer?: number;
|
|
13
|
+
stdio?: 'ignore';
|
|
14
|
+
}): Promise<string>;
|
|
15
|
+
/**
|
|
16
|
+
* Clean up worktree safely
|
|
17
|
+
*/
|
|
18
|
+
export declare function cleanupWorktree(repoRoot: string, worktreePath: string): Promise<void>;
|
|
19
|
+
/**
|
|
20
|
+
* Create a milestone branch and persistent worktree for batch merging.
|
|
21
|
+
* Returns the branch name and worktree path.
|
|
22
|
+
*/
|
|
23
|
+
export declare function createMilestoneBranch(repoRoot: string, baseBranch: string): Promise<{
|
|
24
|
+
milestoneBranch: string;
|
|
25
|
+
milestoneWorktreePath: string;
|
|
26
|
+
}>;
|
|
27
|
+
/**
|
|
28
|
+
* Merge a ticket branch into the milestone branch under git mutex.
|
|
29
|
+
* Returns success/conflict status.
|
|
30
|
+
*/
|
|
31
|
+
export declare function mergeTicketToMilestone(repoRoot: string, ticketBranch: string, milestoneWorktreePath: string): Promise<{
|
|
32
|
+
success: boolean;
|
|
33
|
+
conflicted: boolean;
|
|
34
|
+
}>;
|
|
35
|
+
/**
|
|
36
|
+
* Push milestone branch and create a squash-merge draft PR to the base branch.
|
|
37
|
+
* Returns the PR URL.
|
|
38
|
+
*/
|
|
39
|
+
export declare function pushAndPrMilestone(repoRoot: string, milestoneBranch: string, milestoneWorktreePath: string, milestoneNumber: number, ticketCount: number, summaries: string[]): Promise<string | undefined>;
|
|
40
|
+
/**
|
|
41
|
+
* Clean up the milestone worktree (but not the branch, which may have a PR).
|
|
42
|
+
*/
|
|
43
|
+
export declare function cleanupMilestone(repoRoot: string): Promise<void>;
|
|
44
|
+
//# sourceMappingURL=solo-git.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"solo-git.d.ts","sourceRoot":"","sources":["../../src/lib/solo-git.ts"],"names":[],"mappings":"AAAA;;GAEG;AAYH,wBAAgB,YAAY,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAKhE;AAED;;;GAGG;AACH,wBAAsB,OAAO,CAC3B,GAAG,EAAE,MAAM,EACX,IAAI,EAAE;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,QAAQ,CAAA;CAAE,GAC9E,OAAO,CAAC,MAAM,CAAC,CAUjB;AAED;;GAEG;AACH,wBAAsB,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,iBAQ3E;AAED;;;GAGG;AACH,wBAAsB,qBAAqB,CACzC,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC;IAAE,eAAe,EAAE,MAAM,CAAC;IAAC,qBAAqB,EAAE,MAAM,CAAA;CAAE,CAAC,CAmCrE;AAED;;;GAGG;AACH,wBAAsB,sBAAsB,CAC1C,QAAQ,EAAE,MAAM,EAChB,YAAY,EAAE,MAAM,EACpB,qBAAqB,EAAE,MAAM,GAC5B,OAAO,CAAC;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,UAAU,EAAE,OAAO,CAAA;CAAE,CAAC,CAqCpD;AAED;;;GAGG;AACH,wBAAsB,kBAAkB,CACtC,QAAQ,EAAE,MAAM,EAChB,eAAe,EAAE,MAAM,EACvB,qBAAqB,EAAE,MAAM,EAC7B,eAAe,EAAE,MAAM,EACvB,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,MAAM,EAAE,GAClB,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAoC7B;AAED;;GAEG;AACH,wBAAsB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAGtE"}
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Solo mode git utilities
|
|
3
|
+
*/
|
|
4
|
+
import * as fs from 'node:fs';
|
|
5
|
+
import * as path from 'node:path';
|
|
6
|
+
/**
|
|
7
|
+
* Mutex for serializing git operations on the main repo.
|
|
8
|
+
* Git doesn't support concurrent index operations on the same repo,
|
|
9
|
+
* so worktree setup (fetch, branch, worktree add) must be serialized.
|
|
10
|
+
* Once worktrees are created, per-worktree git ops are safe in parallel.
|
|
11
|
+
*/
|
|
12
|
+
let gitMutexPromise = Promise.resolve();
|
|
13
|
+
export function withGitMutex(fn) {
|
|
14
|
+
const prev = gitMutexPromise;
|
|
15
|
+
let resolve;
|
|
16
|
+
gitMutexPromise = new Promise((r) => { resolve = r; });
|
|
17
|
+
return prev.then(fn).finally(() => resolve());
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Async git command execution — does not block the event loop.
|
|
21
|
+
* Used instead of execSync to allow parallel ticket execution.
|
|
22
|
+
*/
|
|
23
|
+
export async function gitExec(cmd, opts) {
|
|
24
|
+
const { exec } = await import('child_process');
|
|
25
|
+
const { promisify } = await import('util');
|
|
26
|
+
const execPromise = promisify(exec);
|
|
27
|
+
const result = await execPromise(cmd, {
|
|
28
|
+
cwd: opts.cwd,
|
|
29
|
+
encoding: opts.encoding || 'utf-8',
|
|
30
|
+
maxBuffer: opts.maxBuffer || 10 * 1024 * 1024,
|
|
31
|
+
});
|
|
32
|
+
return result.stdout;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Clean up worktree safely
|
|
36
|
+
*/
|
|
37
|
+
export async function cleanupWorktree(repoRoot, worktreePath) {
|
|
38
|
+
try {
|
|
39
|
+
if (fs.existsSync(worktreePath)) {
|
|
40
|
+
await gitExec(`git worktree remove --force "${worktreePath}"`, { cwd: repoRoot });
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
catch {
|
|
44
|
+
// Ignore cleanup errors
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Create a milestone branch and persistent worktree for batch merging.
|
|
49
|
+
* Returns the branch name and worktree path.
|
|
50
|
+
*/
|
|
51
|
+
export async function createMilestoneBranch(repoRoot, baseBranch) {
|
|
52
|
+
const ts = Date.now().toString(36);
|
|
53
|
+
const milestoneBranch = `blockspool/milestone-${ts}`;
|
|
54
|
+
const milestoneWorktreePath = path.join(repoRoot, '.blockspool', 'worktrees', '_milestone');
|
|
55
|
+
await withGitMutex(async () => {
|
|
56
|
+
// Ensure worktrees dir exists
|
|
57
|
+
const worktreesDir = path.join(repoRoot, '.blockspool', 'worktrees');
|
|
58
|
+
if (!fs.existsSync(worktreesDir)) {
|
|
59
|
+
fs.mkdirSync(worktreesDir, { recursive: true });
|
|
60
|
+
}
|
|
61
|
+
// Clean up any existing milestone worktree
|
|
62
|
+
if (fs.existsSync(milestoneWorktreePath)) {
|
|
63
|
+
await gitExec(`git worktree remove --force "${milestoneWorktreePath}"`, { cwd: repoRoot });
|
|
64
|
+
}
|
|
65
|
+
// Fetch latest
|
|
66
|
+
try {
|
|
67
|
+
await gitExec(`git fetch origin ${baseBranch}`, { cwd: repoRoot });
|
|
68
|
+
}
|
|
69
|
+
catch {
|
|
70
|
+
// Continue with what we have
|
|
71
|
+
}
|
|
72
|
+
// Create milestone branch from origin/baseBranch
|
|
73
|
+
try {
|
|
74
|
+
await gitExec(`git branch "${milestoneBranch}" "origin/${baseBranch}"`, { cwd: repoRoot });
|
|
75
|
+
}
|
|
76
|
+
catch {
|
|
77
|
+
// Branch may already exist
|
|
78
|
+
}
|
|
79
|
+
await gitExec(`git worktree add "${milestoneWorktreePath}" "${milestoneBranch}"`, { cwd: repoRoot });
|
|
80
|
+
});
|
|
81
|
+
return { milestoneBranch, milestoneWorktreePath };
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Merge a ticket branch into the milestone branch under git mutex.
|
|
85
|
+
* Returns success/conflict status.
|
|
86
|
+
*/
|
|
87
|
+
export async function mergeTicketToMilestone(repoRoot, ticketBranch, milestoneWorktreePath) {
|
|
88
|
+
return withGitMutex(async () => {
|
|
89
|
+
try {
|
|
90
|
+
await gitExec(`git merge --no-ff "${ticketBranch}" -m "Merge ${ticketBranch}"`, {
|
|
91
|
+
cwd: milestoneWorktreePath,
|
|
92
|
+
});
|
|
93
|
+
return { success: true, conflicted: false };
|
|
94
|
+
}
|
|
95
|
+
catch {
|
|
96
|
+
// Abort the failed merge
|
|
97
|
+
try {
|
|
98
|
+
await gitExec('git merge --abort', { cwd: milestoneWorktreePath });
|
|
99
|
+
}
|
|
100
|
+
catch {
|
|
101
|
+
// Ignore abort errors
|
|
102
|
+
}
|
|
103
|
+
// Retry: rebase ticket branch onto milestone, then merge
|
|
104
|
+
try {
|
|
105
|
+
const milestoneBranchName = (await gitExec('git rev-parse --abbrev-ref HEAD', {
|
|
106
|
+
cwd: milestoneWorktreePath,
|
|
107
|
+
})).trim();
|
|
108
|
+
// Rebase the ticket branch onto the current milestone tip
|
|
109
|
+
await gitExec(`git rebase "${milestoneBranchName}" "${ticketBranch}"`, {
|
|
110
|
+
cwd: repoRoot,
|
|
111
|
+
});
|
|
112
|
+
// Try merge again
|
|
113
|
+
await gitExec(`git merge --no-ff "${ticketBranch}" -m "Merge ${ticketBranch}"`, {
|
|
114
|
+
cwd: milestoneWorktreePath,
|
|
115
|
+
});
|
|
116
|
+
return { success: true, conflicted: false };
|
|
117
|
+
}
|
|
118
|
+
catch {
|
|
119
|
+
// Abort any in-progress rebase or merge
|
|
120
|
+
try {
|
|
121
|
+
await gitExec('git rebase --abort', { cwd: repoRoot });
|
|
122
|
+
}
|
|
123
|
+
catch { /* ignore */ }
|
|
124
|
+
try {
|
|
125
|
+
await gitExec('git merge --abort', { cwd: milestoneWorktreePath });
|
|
126
|
+
}
|
|
127
|
+
catch { /* ignore */ }
|
|
128
|
+
return { success: false, conflicted: true };
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Push milestone branch and create a squash-merge draft PR to the base branch.
|
|
135
|
+
* Returns the PR URL.
|
|
136
|
+
*/
|
|
137
|
+
export async function pushAndPrMilestone(repoRoot, milestoneBranch, milestoneWorktreePath, milestoneNumber, ticketCount, summaries) {
|
|
138
|
+
// Push safety: validate origin matches allowed remote
|
|
139
|
+
const { assertPushSafe } = await import('./solo-remote.js');
|
|
140
|
+
const { loadConfig } = await import('./solo-config.js');
|
|
141
|
+
const config = loadConfig(repoRoot);
|
|
142
|
+
await assertPushSafe(milestoneWorktreePath, config?.allowedRemote);
|
|
143
|
+
// Push the milestone branch
|
|
144
|
+
await gitExec(`git push -u origin "${milestoneBranch}"`, { cwd: milestoneWorktreePath });
|
|
145
|
+
// Build PR body
|
|
146
|
+
const bulletList = summaries.map(s => `- ${s}`).join('\n');
|
|
147
|
+
const title = `Milestone #${milestoneNumber}: ${ticketCount} improvements`;
|
|
148
|
+
const body = `## Milestone #${milestoneNumber}\n\n${ticketCount} tickets merged:\n\n${bulletList}\n\n---\n_Created by BlockSpool (milestone mode)_`;
|
|
149
|
+
try {
|
|
150
|
+
const prOutput = (await gitExec(`gh pr create --title "${title.replace(/"/g, '\\"')}" --body "${body.replace(/"/g, '\\"')}" --head "${milestoneBranch}" --draft`, { cwd: milestoneWorktreePath })).trim();
|
|
151
|
+
const urlMatch = prOutput.match(/https:\/\/github\.com\/[^\s]+/);
|
|
152
|
+
return urlMatch ? urlMatch[0] : undefined;
|
|
153
|
+
}
|
|
154
|
+
catch {
|
|
155
|
+
// PR might already exist for this branch — try to find it
|
|
156
|
+
try {
|
|
157
|
+
const existing = (await gitExec(`gh pr view "${milestoneBranch}" --json url --jq .url`, { cwd: milestoneWorktreePath })).trim();
|
|
158
|
+
if (existing.startsWith('https://'))
|
|
159
|
+
return existing;
|
|
160
|
+
}
|
|
161
|
+
catch {
|
|
162
|
+
// ignore
|
|
163
|
+
}
|
|
164
|
+
return undefined;
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Clean up the milestone worktree (but not the branch, which may have a PR).
|
|
169
|
+
*/
|
|
170
|
+
export async function cleanupMilestone(repoRoot) {
|
|
171
|
+
const milestoneWorktreePath = path.join(repoRoot, '.blockspool', 'worktrees', '_milestone');
|
|
172
|
+
await cleanupWorktree(repoRoot, milestoneWorktreePath);
|
|
173
|
+
}
|
|
174
|
+
//# sourceMappingURL=solo-git.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"solo-git.js","sourceRoot":"","sources":["../../src/lib/solo-git.ts"],"names":[],"mappings":"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"}
|