@ajvikram/relay 0.1.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/LICENSE +21 -0
- package/README.md +538 -0
- package/dist/cli/commands/branch.d.ts +9 -0
- package/dist/cli/commands/branch.d.ts.map +1 -0
- package/dist/cli/commands/branch.js +69 -0
- package/dist/cli/commands/branch.js.map +1 -0
- package/dist/cli/commands/diff.d.ts +8 -0
- package/dist/cli/commands/diff.d.ts.map +1 -0
- package/dist/cli/commands/diff.js +61 -0
- package/dist/cli/commands/diff.js.map +1 -0
- package/dist/cli/commands/history.d.ts +8 -0
- package/dist/cli/commands/history.d.ts.map +1 -0
- package/dist/cli/commands/history.js +32 -0
- package/dist/cli/commands/history.js.map +1 -0
- package/dist/cli/commands/hook.d.ts +6 -0
- package/dist/cli/commands/hook.d.ts.map +1 -0
- package/dist/cli/commands/hook.js +118 -0
- package/dist/cli/commands/hook.js.map +1 -0
- package/dist/cli/commands/init.d.ts +4 -0
- package/dist/cli/commands/init.d.ts.map +1 -0
- package/dist/cli/commands/init.js +41 -0
- package/dist/cli/commands/init.js.map +1 -0
- package/dist/cli/commands/install.d.ts +18 -0
- package/dist/cli/commands/install.d.ts.map +1 -0
- package/dist/cli/commands/install.js +203 -0
- package/dist/cli/commands/install.js.map +1 -0
- package/dist/cli/commands/load.d.ts +9 -0
- package/dist/cli/commands/load.d.ts.map +1 -0
- package/dist/cli/commands/load.js +69 -0
- package/dist/cli/commands/load.js.map +1 -0
- package/dist/cli/commands/repos.d.ts +7 -0
- package/dist/cli/commands/repos.d.ts.map +1 -0
- package/dist/cli/commands/repos.js +53 -0
- package/dist/cli/commands/repos.js.map +1 -0
- package/dist/cli/commands/save.d.ts +9 -0
- package/dist/cli/commands/save.d.ts.map +1 -0
- package/dist/cli/commands/save.js +267 -0
- package/dist/cli/commands/save.js.map +1 -0
- package/dist/cli/commands/status.d.ts +23 -0
- package/dist/cli/commands/status.d.ts.map +1 -0
- package/dist/cli/commands/status.js +134 -0
- package/dist/cli/commands/status.js.map +1 -0
- package/dist/cli/commands/ui.d.ts +9 -0
- package/dist/cli/commands/ui.d.ts.map +1 -0
- package/dist/cli/commands/ui.js +54 -0
- package/dist/cli/commands/ui.js.map +1 -0
- package/dist/cli/commands/vscode.d.ts +6 -0
- package/dist/cli/commands/vscode.d.ts.map +1 -0
- package/dist/cli/commands/vscode.js +86 -0
- package/dist/cli/commands/vscode.js.map +1 -0
- package/dist/cli/index.d.ts +3 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +143 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/format/renderer.d.ts +5 -0
- package/dist/format/renderer.d.ts.map +1 -0
- package/dist/format/renderer.js +207 -0
- package/dist/format/renderer.js.map +1 -0
- package/dist/format/schema.d.ts +516 -0
- package/dist/format/schema.d.ts.map +1 -0
- package/dist/format/schema.js +90 -0
- package/dist/format/schema.js.map +1 -0
- package/dist/format/template.d.ts +44 -0
- package/dist/format/template.d.ts.map +1 -0
- package/dist/format/template.js +131 -0
- package/dist/format/template.js.map +1 -0
- package/dist/git/context.d.ts +23 -0
- package/dist/git/context.d.ts.map +1 -0
- package/dist/git/context.js +121 -0
- package/dist/git/context.js.map +1 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +8 -0
- package/dist/index.js.map +1 -0
- package/dist/mcp/server.d.ts +2 -0
- package/dist/mcp/server.d.ts.map +1 -0
- package/dist/mcp/server.js +164 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/server/index.d.ts +12 -0
- package/dist/server/index.d.ts.map +1 -0
- package/dist/server/index.js +143 -0
- package/dist/server/index.js.map +1 -0
- package/dist/server/ui.d.ts +2 -0
- package/dist/server/ui.d.ts.map +1 -0
- package/dist/server/ui.js +797 -0
- package/dist/server/ui.js.map +1 -0
- package/dist/storage/global.d.ts +40 -0
- package/dist/storage/global.d.ts.map +1 -0
- package/dist/storage/global.js +126 -0
- package/dist/storage/global.js.map +1 -0
- package/dist/storage/index.d.ts +59 -0
- package/dist/storage/index.d.ts.map +1 -0
- package/dist/storage/index.js +253 -0
- package/dist/storage/index.js.map +1 -0
- package/package.json +54 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"load.js","sourceRoot":"","sources":["../../../src/cli/commands/load.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"repos.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/repos.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,YAAY;IAC3B,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED,wBAAsB,YAAY,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAyDvE"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import { listRegisteredRepos, unregisterRepo } from '../../storage/global.js';
|
|
3
|
+
export async function reposCommand(options) {
|
|
4
|
+
if (options.remove) {
|
|
5
|
+
const success = unregisterRepo(options.remove);
|
|
6
|
+
if (success) {
|
|
7
|
+
console.log(chalk.green(`✓ Removed ${options.remove} from Relay global registry.`));
|
|
8
|
+
}
|
|
9
|
+
else {
|
|
10
|
+
console.log(chalk.yellow(`⚠ Repository ${options.remove} was not found in registry.`));
|
|
11
|
+
}
|
|
12
|
+
return;
|
|
13
|
+
}
|
|
14
|
+
const repos = listRegisteredRepos({ pruneStale: options.prune !== false });
|
|
15
|
+
if (options.json) {
|
|
16
|
+
console.log(JSON.stringify({ total: repos.length, repos }, null, 2));
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
console.log(chalk.bold('\n🌐 Relay Registered Repositories across this Machine:\n'));
|
|
20
|
+
if (repos.length === 0) {
|
|
21
|
+
console.log(chalk.dim(' No repositories registered yet.'));
|
|
22
|
+
console.log(chalk.dim(' Run `relay init` or `relay save` in any project to register it automatically.\n'));
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
for (const repo of repos) {
|
|
26
|
+
const statusColor = repo.lastStatus === 'blocked'
|
|
27
|
+
? chalk.red('BLOCKED')
|
|
28
|
+
: repo.lastStatus === 'in_progress'
|
|
29
|
+
? chalk.yellow('IN PROGRESS')
|
|
30
|
+
: repo.lastStatus === 'ready_for_review'
|
|
31
|
+
? chalk.cyan('READY FOR REVIEW')
|
|
32
|
+
: repo.lastStatus === 'done'
|
|
33
|
+
? chalk.green('DONE')
|
|
34
|
+
: chalk.dim('NO ACTIVE HANDOFF');
|
|
35
|
+
console.log(chalk.bold(` 📁 ${repo.name}`) + chalk.dim(` (${repo.path})`));
|
|
36
|
+
if (repo.lastGoal) {
|
|
37
|
+
console.log(chalk.dim(` Goal: `) + chalk.white(repo.lastGoal));
|
|
38
|
+
console.log(chalk.dim(` Status: `) +
|
|
39
|
+
statusColor +
|
|
40
|
+
chalk.dim(` | Platform: `) +
|
|
41
|
+
chalk.magenta(repo.lastPlatform || 'unknown') +
|
|
42
|
+
chalk.dim(` | Updated: `) +
|
|
43
|
+
chalk.dim(new Date(repo.lastHandoffAt || repo.registeredAt).toLocaleString()));
|
|
44
|
+
}
|
|
45
|
+
else {
|
|
46
|
+
console.log(chalk.dim(` Status: `) + chalk.dim('Initialized, awaiting first save'));
|
|
47
|
+
}
|
|
48
|
+
console.log('');
|
|
49
|
+
}
|
|
50
|
+
console.log(chalk.dim(`Total: ${repos.length} repositor${repos.length === 1 ? 'y' : 'ies'} registered.`));
|
|
51
|
+
console.log(chalk.dim('Tip: Run `relay ui --global` to view all projects in the web dashboard.\n'));
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=repos.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"repos.js","sourceRoot":"","sources":["../../../src/cli/commands/repos.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"save.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/save.ts"],"names":[],"mappings":"AAyBA,UAAU,WAAW;IACnB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED,wBAAsB,WAAW,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAuQrE"}
|
|
@@ -0,0 +1,267 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import inquirer from 'inquirer';
|
|
3
|
+
import { randomUUID } from 'crypto';
|
|
4
|
+
import { captureGitContext, getRepoRoot } from '../../git/context.js';
|
|
5
|
+
import { HandoffSchema, } from '../../format/schema.js';
|
|
6
|
+
import { PLATFORM_CHOICES, STATUS_CHOICES, PRIORITY_CHOICES, AGENT_SAVE_PROMPT, } from '../../format/template.js';
|
|
7
|
+
import { saveHandoff, initRelayDir, isRelayInitialized, resolveCwd, } from '../../storage/index.js';
|
|
8
|
+
export async function saveCommand(options) {
|
|
9
|
+
const cwd = resolveCwd(options.dir);
|
|
10
|
+
const repoRoot = await getRepoRoot(cwd);
|
|
11
|
+
if (!repoRoot) {
|
|
12
|
+
console.error(chalk.red('✗ Not a git repository.'));
|
|
13
|
+
process.exit(1);
|
|
14
|
+
}
|
|
15
|
+
if (!isRelayInitialized(repoRoot)) {
|
|
16
|
+
console.log(chalk.yellow('⚠ Relay not initialized. Running init first...'));
|
|
17
|
+
initRelayDir(repoRoot);
|
|
18
|
+
console.log(chalk.green('✓ Initialized .relay/'));
|
|
19
|
+
console.log('');
|
|
20
|
+
}
|
|
21
|
+
// ── Agent-assisted mode ─────────────────────────────────────────────────────
|
|
22
|
+
if (options.agent) {
|
|
23
|
+
console.log(chalk.bold('📋 Agent-Assisted Save'));
|
|
24
|
+
console.log('');
|
|
25
|
+
console.log('Copy the following prompt and paste it into your current AI agent.');
|
|
26
|
+
console.log('Then paste the agent\'s JSON response back here.');
|
|
27
|
+
console.log('');
|
|
28
|
+
console.log(chalk.dim('─'.repeat(60)));
|
|
29
|
+
console.log('');
|
|
30
|
+
console.log(AGENT_SAVE_PROMPT);
|
|
31
|
+
console.log('');
|
|
32
|
+
console.log(chalk.dim('─'.repeat(60)));
|
|
33
|
+
console.log('');
|
|
34
|
+
const { jsonInput } = await inquirer.prompt([
|
|
35
|
+
{
|
|
36
|
+
type: 'editor',
|
|
37
|
+
name: 'jsonInput',
|
|
38
|
+
message: 'Paste the agent\'s JSON response here (opens editor):',
|
|
39
|
+
},
|
|
40
|
+
]);
|
|
41
|
+
try {
|
|
42
|
+
const parsed = JSON.parse(jsonInput.trim());
|
|
43
|
+
await finalizeAndSave(repoRoot, parsed, options.platform);
|
|
44
|
+
}
|
|
45
|
+
catch (err) {
|
|
46
|
+
console.error(chalk.red('✗ Invalid JSON. Please try again.'));
|
|
47
|
+
console.error(chalk.dim(String(err)));
|
|
48
|
+
process.exit(1);
|
|
49
|
+
}
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
// ── Interactive guided mode ─────────────────────────────────────────────────
|
|
53
|
+
console.log(chalk.bold('💾 Save Relay Handoff'));
|
|
54
|
+
console.log(chalk.dim('Answer the prompts below. This context will be loaded by the next AI agent.'));
|
|
55
|
+
console.log('');
|
|
56
|
+
// Capture git context first (runs in parallel while user reads prompt)
|
|
57
|
+
const gitContextPromise = captureGitContext(repoRoot);
|
|
58
|
+
// ── Basic session info ─────────────────────────────────────────────────────
|
|
59
|
+
const sessionAnswers = await inquirer.prompt([
|
|
60
|
+
{
|
|
61
|
+
type: 'list',
|
|
62
|
+
name: 'source_platform',
|
|
63
|
+
message: 'Which platform are you currently on?',
|
|
64
|
+
choices: PLATFORM_CHOICES,
|
|
65
|
+
default: options.platform ?? 'other',
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
type: 'input',
|
|
69
|
+
name: 'goal',
|
|
70
|
+
message: 'What is the goal of this session? (one sentence)',
|
|
71
|
+
validate: (v) => v.trim().length > 10 || 'Please describe the goal (at least 10 chars)',
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
type: 'list',
|
|
75
|
+
name: 'status',
|
|
76
|
+
message: 'What is the current status?',
|
|
77
|
+
choices: STATUS_CHOICES,
|
|
78
|
+
default: 'in_progress',
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
type: 'confirm',
|
|
82
|
+
name: 'token_exhausted',
|
|
83
|
+
message: 'Is this handoff triggered by hitting a token limit?',
|
|
84
|
+
default: false,
|
|
85
|
+
},
|
|
86
|
+
{
|
|
87
|
+
type: 'input',
|
|
88
|
+
name: 'duration_hint',
|
|
89
|
+
message: 'Roughly how long have you been working on this? (e.g. "~2 hours") [optional]',
|
|
90
|
+
},
|
|
91
|
+
]);
|
|
92
|
+
// ── Decisions ──────────────────────────────────────────────────────────────
|
|
93
|
+
console.log('');
|
|
94
|
+
console.log(chalk.bold('🏛️ Decisions Made'));
|
|
95
|
+
console.log(chalk.dim('Record architectural/design decisions. The next agent will respect these.'));
|
|
96
|
+
const decisions = [];
|
|
97
|
+
let addingDecisions = true;
|
|
98
|
+
while (addingDecisions) {
|
|
99
|
+
const { addDecision } = await inquirer.prompt([
|
|
100
|
+
{
|
|
101
|
+
type: 'confirm',
|
|
102
|
+
name: 'addDecision',
|
|
103
|
+
message: decisions.length === 0 ? 'Add a decision?' : 'Add another decision?',
|
|
104
|
+
default: decisions.length === 0,
|
|
105
|
+
},
|
|
106
|
+
]);
|
|
107
|
+
if (!addDecision) {
|
|
108
|
+
addingDecisions = false;
|
|
109
|
+
}
|
|
110
|
+
else {
|
|
111
|
+
const d = await inquirer.prompt([
|
|
112
|
+
{ type: 'input', name: 'what', message: 'What was decided?', validate: (v) => v.trim().length > 0 || 'Required' },
|
|
113
|
+
{ type: 'input', name: 'why', message: 'Why? (be specific)', validate: (v) => v.trim().length > 0 || 'Required' },
|
|
114
|
+
{ type: 'input', name: 'evidence', message: 'Evidence? (commit SHA, file path, etc.) [optional]' },
|
|
115
|
+
]);
|
|
116
|
+
decisions.push({ what: d.what.trim(), why: d.why.trim(), ...(d.evidence.trim() ? { evidence: d.evidence.trim() } : {}) });
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
// ── Constraints ────────────────────────────────────────────────────────────
|
|
120
|
+
console.log('');
|
|
121
|
+
console.log(chalk.bold('🚫 Non-Negotiable Constraints'));
|
|
122
|
+
console.log(chalk.dim('Hard requirements the next agent MUST NOT violate.'));
|
|
123
|
+
const constraints = [];
|
|
124
|
+
let addingConstraints = true;
|
|
125
|
+
while (addingConstraints) {
|
|
126
|
+
const { addConstraint } = await inquirer.prompt([
|
|
127
|
+
{
|
|
128
|
+
type: 'confirm',
|
|
129
|
+
name: 'addConstraint',
|
|
130
|
+
message: constraints.length === 0 ? 'Add a constraint?' : 'Add another constraint?',
|
|
131
|
+
default: false,
|
|
132
|
+
},
|
|
133
|
+
]);
|
|
134
|
+
if (!addConstraint) {
|
|
135
|
+
addingConstraints = false;
|
|
136
|
+
}
|
|
137
|
+
else {
|
|
138
|
+
const { constraint } = await inquirer.prompt([
|
|
139
|
+
{ type: 'input', name: 'constraint', message: 'Constraint:', validate: (v) => v.trim().length > 0 || 'Required' },
|
|
140
|
+
]);
|
|
141
|
+
constraints.push(constraint.trim());
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
// ── Failed approaches ──────────────────────────────────────────────────────
|
|
145
|
+
console.log('');
|
|
146
|
+
console.log(chalk.bold('⚠️ Failed Approaches'));
|
|
147
|
+
console.log(chalk.dim('What did you try that did NOT work? This prevents the next agent from repeating mistakes.'));
|
|
148
|
+
const failed_approaches = [];
|
|
149
|
+
let addingFailed = true;
|
|
150
|
+
while (addingFailed) {
|
|
151
|
+
const { addFailed } = await inquirer.prompt([
|
|
152
|
+
{
|
|
153
|
+
type: 'confirm',
|
|
154
|
+
name: 'addFailed',
|
|
155
|
+
message: failed_approaches.length === 0 ? 'Add a failed approach?' : 'Add another failed approach?',
|
|
156
|
+
default: false,
|
|
157
|
+
},
|
|
158
|
+
]);
|
|
159
|
+
if (!addFailed) {
|
|
160
|
+
addingFailed = false;
|
|
161
|
+
}
|
|
162
|
+
else {
|
|
163
|
+
const f = await inquirer.prompt([
|
|
164
|
+
{ type: 'input', name: 'approach', message: 'What approach was tried?', validate: (v) => v.trim().length > 0 || 'Required' },
|
|
165
|
+
{ type: 'input', name: 'why_failed', message: 'Why exactly did it fail? (be specific)', validate: (v) => v.trim().length > 10 || 'Be specific — at least 10 chars' },
|
|
166
|
+
]);
|
|
167
|
+
failed_approaches.push({ approach: f.approach.trim(), why_failed: f.why_failed.trim() });
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
// ── Next steps ─────────────────────────────────────────────────────────────
|
|
171
|
+
console.log('');
|
|
172
|
+
console.log(chalk.bold('✅ Next Steps'));
|
|
173
|
+
console.log(chalk.dim('What should the next agent do? Be specific and ordered.'));
|
|
174
|
+
const next_steps = [];
|
|
175
|
+
let addingSteps = true;
|
|
176
|
+
while (addingSteps) {
|
|
177
|
+
const { addStep } = await inquirer.prompt([
|
|
178
|
+
{
|
|
179
|
+
type: 'confirm',
|
|
180
|
+
name: 'addStep',
|
|
181
|
+
message: next_steps.length === 0 ? 'Add a next step?' : 'Add another step?',
|
|
182
|
+
default: true,
|
|
183
|
+
},
|
|
184
|
+
]);
|
|
185
|
+
if (!addStep) {
|
|
186
|
+
addingSteps = false;
|
|
187
|
+
}
|
|
188
|
+
else {
|
|
189
|
+
const s = await inquirer.prompt([
|
|
190
|
+
{ type: 'input', name: 'task', message: 'Task (clear, actionable):', validate: (v) => v.trim().length > 0 || 'Required' },
|
|
191
|
+
{ type: 'input', name: 'context', message: 'Additional context? [optional]' },
|
|
192
|
+
{ type: 'input', name: 'file_hint', message: 'Start at which file? [optional]' },
|
|
193
|
+
{ type: 'list', name: 'priority', message: 'Priority:', choices: PRIORITY_CHOICES, default: 'immediate' },
|
|
194
|
+
]);
|
|
195
|
+
next_steps.push({
|
|
196
|
+
task: s.task.trim(),
|
|
197
|
+
priority: s.priority,
|
|
198
|
+
...(s.context.trim() ? { context: s.context.trim() } : {}),
|
|
199
|
+
...(s.file_hint.trim() ? { file_hint: s.file_hint.trim() } : {}),
|
|
200
|
+
});
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
// ── Wait for git context and allow file summary edits ─────────────────────
|
|
204
|
+
console.log('');
|
|
205
|
+
console.log(chalk.dim('Capturing git context...'));
|
|
206
|
+
const gitContext = await gitContextPromise;
|
|
207
|
+
let files_modified = gitContext.files_modified;
|
|
208
|
+
if (files_modified.length > 0) {
|
|
209
|
+
console.log('');
|
|
210
|
+
console.log(chalk.bold('📝 Modified Files'));
|
|
211
|
+
console.log(chalk.dim('Git detected these changes. Add a brief summary for each.'));
|
|
212
|
+
console.log(chalk.dim('(Press Enter to skip a file)'));
|
|
213
|
+
console.log('');
|
|
214
|
+
const updatedFiles = [];
|
|
215
|
+
for (const file of files_modified) {
|
|
216
|
+
const { summary } = await inquirer.prompt([
|
|
217
|
+
{
|
|
218
|
+
type: 'input',
|
|
219
|
+
name: 'summary',
|
|
220
|
+
message: `${file.status === 'added' ? '🟢' : file.status === 'deleted' ? '🔴' : '🟡'} ${file.path}:`,
|
|
221
|
+
default: file.summary,
|
|
222
|
+
},
|
|
223
|
+
]);
|
|
224
|
+
updatedFiles.push({ ...file, summary: summary.trim() || file.summary });
|
|
225
|
+
}
|
|
226
|
+
files_modified = updatedFiles;
|
|
227
|
+
}
|
|
228
|
+
// ── Assemble and save ──────────────────────────────────────────────────────
|
|
229
|
+
await finalizeAndSave(repoRoot, {
|
|
230
|
+
session: {
|
|
231
|
+
goal: sessionAnswers.goal.trim(),
|
|
232
|
+
status: sessionAnswers.status,
|
|
233
|
+
token_exhausted: sessionAnswers.token_exhausted,
|
|
234
|
+
...(sessionAnswers.duration_hint?.trim() ? { duration_hint: sessionAnswers.duration_hint.trim() } : {}),
|
|
235
|
+
},
|
|
236
|
+
decisions,
|
|
237
|
+
constraints,
|
|
238
|
+
failed_approaches,
|
|
239
|
+
files_modified,
|
|
240
|
+
next_steps,
|
|
241
|
+
}, sessionAnswers.source_platform, gitContext);
|
|
242
|
+
}
|
|
243
|
+
// ─── Internal: finalize handoff and write to disk ─────────────────────────────
|
|
244
|
+
async function finalizeAndSave(repoRoot, partial, platform, preloadedGitContext) {
|
|
245
|
+
const gitContext = preloadedGitContext ?? (await captureGitContext(repoRoot));
|
|
246
|
+
const raw = HandoffSchema.parse({
|
|
247
|
+
version: '1',
|
|
248
|
+
id: randomUUID().slice(0, 8),
|
|
249
|
+
timestamp: new Date().toISOString(),
|
|
250
|
+
source_platform: platform ?? 'other',
|
|
251
|
+
repository: gitContext.repository,
|
|
252
|
+
raw_diff: gitContext.raw_diff || undefined,
|
|
253
|
+
files_modified: partial['files_modified'] ?? gitContext.files_modified,
|
|
254
|
+
...partial,
|
|
255
|
+
});
|
|
256
|
+
saveHandoff(repoRoot, raw);
|
|
257
|
+
console.log('');
|
|
258
|
+
console.log(chalk.bold.green('✓ Handoff saved!'));
|
|
259
|
+
console.log('');
|
|
260
|
+
console.log(chalk.dim('Files written:'));
|
|
261
|
+
console.log(` ${chalk.cyan('.relay/handoff.md')} — Human-readable handoff (commit this)`);
|
|
262
|
+
console.log(` ${chalk.cyan('.relay/handoff.json')} — Machine-readable (for MCP)`);
|
|
263
|
+
console.log('');
|
|
264
|
+
console.log(`Now run ${chalk.cyan('relay load')} on the next platform to continue.`);
|
|
265
|
+
console.log(chalk.dim('Or paste the output of `relay load --prompt` directly into the new agent.'));
|
|
266
|
+
}
|
|
267
|
+
//# sourceMappingURL=save.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"save.js","sourceRoot":"","sources":["../../../src/cli/commands/save.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export interface StatusReport {
|
|
2
|
+
initialized: boolean;
|
|
3
|
+
hasHandoff: boolean;
|
|
4
|
+
branchMatch: boolean;
|
|
5
|
+
currentBranch: string;
|
|
6
|
+
savedBranch: string;
|
|
7
|
+
headCommit: string;
|
|
8
|
+
savedCommit: string;
|
|
9
|
+
commitsDiffCount: number;
|
|
10
|
+
uncommittedChangesCount: number;
|
|
11
|
+
filesDrift: {
|
|
12
|
+
addedSince: string[];
|
|
13
|
+
modifiedSince: string[];
|
|
14
|
+
revertedSince: string[];
|
|
15
|
+
};
|
|
16
|
+
immediateStepsPending: number;
|
|
17
|
+
}
|
|
18
|
+
export declare function getStatusReport(repoRoot: string): Promise<StatusReport>;
|
|
19
|
+
export declare function statusCommand(options: {
|
|
20
|
+
dir?: string;
|
|
21
|
+
json?: boolean;
|
|
22
|
+
}): Promise<void>;
|
|
23
|
+
//# sourceMappingURL=status.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/status.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,YAAY;IAC3B,WAAW,EAAE,OAAO,CAAC;IACrB,UAAU,EAAE,OAAO,CAAC;IACpB,WAAW,EAAE,OAAO,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,gBAAgB,EAAE,MAAM,CAAC;IACzB,uBAAuB,EAAE,MAAM,CAAC;IAChC,UAAU,EAAE;QACV,UAAU,EAAE,MAAM,EAAE,CAAC;QACrB,aAAa,EAAE,MAAM,EAAE,CAAC;QACxB,aAAa,EAAE,MAAM,EAAE,CAAC;KACzB,CAAC;IACF,qBAAqB,EAAE,MAAM,CAAC;CAC/B;AAED,wBAAsB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,CAsE7E;AAED,wBAAsB,aAAa,CAAC,OAAO,EAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAgF5F"}
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import { getRepoRoot, captureGitContext } from '../../git/context.js';
|
|
3
|
+
import { readHandoff, isRelayInitialized, resolveCwd } from '../../storage/index.js';
|
|
4
|
+
import { simpleGit } from 'simple-git';
|
|
5
|
+
export async function getStatusReport(repoRoot) {
|
|
6
|
+
const initialized = isRelayInitialized(repoRoot);
|
|
7
|
+
const handoff = readHandoff(repoRoot);
|
|
8
|
+
const gitContext = await captureGitContext(repoRoot);
|
|
9
|
+
const git = simpleGit(repoRoot);
|
|
10
|
+
if (!handoff) {
|
|
11
|
+
return {
|
|
12
|
+
initialized,
|
|
13
|
+
hasHandoff: false,
|
|
14
|
+
branchMatch: true,
|
|
15
|
+
currentBranch: gitContext.repository.branch,
|
|
16
|
+
savedBranch: 'none',
|
|
17
|
+
headCommit: gitContext.repository.head_commit,
|
|
18
|
+
savedCommit: 'none',
|
|
19
|
+
commitsDiffCount: 0,
|
|
20
|
+
uncommittedChangesCount: gitContext.files_modified.length,
|
|
21
|
+
filesDrift: { addedSince: [], modifiedSince: [], revertedSince: [] },
|
|
22
|
+
immediateStepsPending: 0,
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
let commitsDiffCount = 0;
|
|
26
|
+
try {
|
|
27
|
+
const revList = await git.raw(['rev-list', '--count', `${handoff.repository.head_commit}..HEAD`]);
|
|
28
|
+
commitsDiffCount = parseInt(revList.trim(), 10) || 0;
|
|
29
|
+
}
|
|
30
|
+
catch {
|
|
31
|
+
commitsDiffCount = 0;
|
|
32
|
+
}
|
|
33
|
+
const savedFilePaths = new Set(handoff.files_modified.map((f) => f.path));
|
|
34
|
+
const currentModifiedPaths = new Set(gitContext.files_modified.map((f) => f.path));
|
|
35
|
+
const addedSince = [];
|
|
36
|
+
const modifiedSince = [];
|
|
37
|
+
const revertedSince = [];
|
|
38
|
+
for (const path of currentModifiedPaths) {
|
|
39
|
+
if (!savedFilePaths.has(path)) {
|
|
40
|
+
addedSince.push(path);
|
|
41
|
+
}
|
|
42
|
+
else {
|
|
43
|
+
modifiedSince.push(path);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
for (const path of savedFilePaths) {
|
|
47
|
+
if (!currentModifiedPaths.has(path)) {
|
|
48
|
+
revertedSince.push(path);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
const immediateSteps = handoff.next_steps.filter((s) => s.priority === 'immediate').length;
|
|
52
|
+
return {
|
|
53
|
+
initialized,
|
|
54
|
+
hasHandoff: true,
|
|
55
|
+
branchMatch: gitContext.repository.branch === handoff.repository.branch,
|
|
56
|
+
currentBranch: gitContext.repository.branch,
|
|
57
|
+
savedBranch: handoff.repository.branch,
|
|
58
|
+
headCommit: gitContext.repository.head_commit,
|
|
59
|
+
savedCommit: handoff.repository.head_commit,
|
|
60
|
+
commitsDiffCount,
|
|
61
|
+
uncommittedChangesCount: gitContext.files_modified.length,
|
|
62
|
+
filesDrift: {
|
|
63
|
+
addedSince,
|
|
64
|
+
modifiedSince,
|
|
65
|
+
revertedSince,
|
|
66
|
+
},
|
|
67
|
+
immediateStepsPending: immediateSteps,
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
export async function statusCommand(options) {
|
|
71
|
+
const cwd = resolveCwd(options.dir);
|
|
72
|
+
const repoRoot = await getRepoRoot(cwd);
|
|
73
|
+
if (!repoRoot) {
|
|
74
|
+
console.error(chalk.red('✗ Not a git repository.'));
|
|
75
|
+
process.exit(1);
|
|
76
|
+
}
|
|
77
|
+
const report = await getStatusReport(repoRoot);
|
|
78
|
+
if (options.json) {
|
|
79
|
+
console.log(JSON.stringify(report, null, 2));
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
console.log(chalk.bold('\n🔍 Relay Workspace Status'));
|
|
83
|
+
console.log(chalk.dim('─'.repeat(60)));
|
|
84
|
+
if (!report.initialized) {
|
|
85
|
+
console.log(chalk.yellow('⚠️ Relay is not initialized in this repository.'));
|
|
86
|
+
console.log(`Run ${chalk.cyan('relay init')} to get started.\n`);
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
if (!report.hasHandoff) {
|
|
90
|
+
console.log(chalk.yellow('⚠️ No active handoff found in .relay/handoff.md'));
|
|
91
|
+
console.log(`Run ${chalk.cyan('relay save')} to record your first handoff.\n`);
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
const handoff = readHandoff(repoRoot);
|
|
95
|
+
// Branch check
|
|
96
|
+
if (report.branchMatch) {
|
|
97
|
+
console.log(chalk.green(`✓ Branch:`), `${report.currentBranch}`);
|
|
98
|
+
}
|
|
99
|
+
else {
|
|
100
|
+
console.log(chalk.yellow(`⚠️ Branch mismatch:`), `Currently on ${chalk.bold(report.currentBranch)}, handoff was on ${chalk.bold(report.savedBranch)}`);
|
|
101
|
+
}
|
|
102
|
+
// Commit drift
|
|
103
|
+
if (report.commitsDiffCount === 0) {
|
|
104
|
+
console.log(chalk.green(`✓ Commit alignment:`), `HEAD matches handoff commit (${report.headCommit})`);
|
|
105
|
+
}
|
|
106
|
+
else {
|
|
107
|
+
console.log(chalk.yellow(`⚠️ Commit drift:`), `${report.commitsDiffCount} new commit(s) since handoff was saved (${report.savedCommit} → ${report.headCommit})`);
|
|
108
|
+
}
|
|
109
|
+
// Active Session summary
|
|
110
|
+
console.log(chalk.dim('\nSession Summary:'));
|
|
111
|
+
console.log(` Goal: ${chalk.bold(handoff.session.goal)}`);
|
|
112
|
+
console.log(` Status: ${handoff.session.status.toUpperCase()} ${handoff.session.token_exhausted ? chalk.red('(Token Exhausted)') : ''}`);
|
|
113
|
+
console.log(` Origin: ${handoff.source_platform}`);
|
|
114
|
+
// Pending steps
|
|
115
|
+
if (handoff.next_steps.length > 0) {
|
|
116
|
+
console.log(chalk.dim('\nNext Steps:'));
|
|
117
|
+
handoff.next_steps.forEach((step, i) => {
|
|
118
|
+
const icon = step.priority === 'immediate' ? chalk.red('●') : step.priority === 'soon' ? chalk.yellow('●') : chalk.blue('●');
|
|
119
|
+
console.log(` ${icon} [${step.priority.toUpperCase()}] ${i + 1}. ${step.task}`);
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
// Changes drift
|
|
123
|
+
if (report.uncommittedChangesCount > 0) {
|
|
124
|
+
console.log(chalk.dim('\nUncommitted Working Tree:'));
|
|
125
|
+
console.log(` ${report.uncommittedChangesCount} file(s) currently modified`);
|
|
126
|
+
if (report.filesDrift.addedSince.length > 0) {
|
|
127
|
+
console.log(chalk.dim(` + ${report.filesDrift.addedSince.length} new file(s) modified since handoff`));
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
console.log(chalk.dim('─'.repeat(60)));
|
|
131
|
+
console.log(chalk.dim(`Tip: Run ${chalk.cyan('relay ui')} to launch the visual dashboard.`));
|
|
132
|
+
console.log('');
|
|
133
|
+
}
|
|
134
|
+
//# sourceMappingURL=status.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"status.js","sourceRoot":"","sources":["../../../src/cli/commands/status.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AACtE,OAAO,EAAE,WAAW,EAAE,kBAAkB,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACrF,OAAO,EAAE,SAAS,EAAkB,MAAM,YAAY,CAAC;AAoBvD,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,QAAgB;IACpD,MAAM,WAAW,GAAG,kBAAkB,CAAC,QAAQ,CAAC,CAAC;IACjD,MAAM,OAAO,GAAG,WAAW,CAAC,QAAQ,CAAC,CAAC;IACtC,MAAM,UAAU,GAAG,MAAM,iBAAiB,CAAC,QAAQ,CAAC,CAAC;IACrD,MAAM,GAAG,GAAc,SAAS,CAAC,QAAQ,CAAC,CAAC;IAE3C,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,OAAO;YACL,WAAW;YACX,UAAU,EAAE,KAAK;YACjB,WAAW,EAAE,IAAI;YACjB,aAAa,EAAE,UAAU,CAAC,UAAU,CAAC,MAAM;YAC3C,WAAW,EAAE,MAAM;YACnB,UAAU,EAAE,UAAU,CAAC,UAAU,CAAC,WAAW;YAC7C,WAAW,EAAE,MAAM;YACnB,gBAAgB,EAAE,CAAC;YACnB,uBAAuB,EAAE,UAAU,CAAC,cAAc,CAAC,MAAM;YACzD,UAAU,EAAE,EAAE,UAAU,EAAE,EAAE,EAAE,aAAa,EAAE,EAAE,EAAE,aAAa,EAAE,EAAE,EAAE;YACpE,qBAAqB,EAAE,CAAC;SACzB,CAAC;IACJ,CAAC;IAED,IAAI,gBAAgB,GAAG,CAAC,CAAC;IACzB,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,MAAM,GAAG,CAAC,GAAG,CAAC,CAAC,UAAU,EAAE,SAAS,EAAE,GAAG,OAAO,CAAC,UAAU,CAAC,WAAW,QAAQ,CAAC,CAAC,CAAC;QAClG,gBAAgB,GAAG,QAAQ,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC;IACvD,CAAC;IAAC,MAAM,CAAC;QACP,gBAAgB,GAAG,CAAC,CAAC;IACvB,CAAC;IAED,MAAM,cAAc,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;IAC1E,MAAM,oBAAoB,GAAG,IAAI,GAAG,CAAC,UAAU,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;IAEnF,MAAM,UAAU,GAAa,EAAE,CAAC;IAChC,MAAM,aAAa,GAAa,EAAE,CAAC;IACnC,MAAM,aAAa,GAAa,EAAE,CAAC;IAEnC,KAAK,MAAM,IAAI,IAAI,oBAAoB,EAAE,CAAC;QACxC,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;YAC9B,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACxB,CAAC;aAAM,CAAC;YACN,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC3B,CAAC;IACH,CAAC;IAED,KAAK,MAAM,IAAI,IAAI,cAAc,EAAE,CAAC;QAClC,IAAI,CAAC,oBAAoB,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;YACpC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC3B,CAAC;IACH,CAAC;IAED,MAAM,cAAc,GAAG,OAAO,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,WAAW,CAAC,CAAC,MAAM,CAAC;IAE3F,OAAO;QACL,WAAW;QACX,UAAU,EAAE,IAAI;QAChB,WAAW,EAAE,UAAU,CAAC,UAAU,CAAC,MAAM,KAAK,OAAO,CAAC,UAAU,CAAC,MAAM;QACvE,aAAa,EAAE,UAAU,CAAC,UAAU,CAAC,MAAM;QAC3C,WAAW,EAAE,OAAO,CAAC,UAAU,CAAC,MAAM;QACtC,UAAU,EAAE,UAAU,CAAC,UAAU,CAAC,WAAW;QAC7C,WAAW,EAAE,OAAO,CAAC,UAAU,CAAC,WAAW;QAC3C,gBAAgB;QAChB,uBAAuB,EAAE,UAAU,CAAC,cAAc,CAAC,MAAM;QACzD,UAAU,EAAE;YACV,UAAU;YACV,aAAa;YACb,aAAa;SACd;QACD,qBAAqB,EAAE,cAAc;KACtC,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,OAAyC;IAC3E,MAAM,GAAG,GAAG,UAAU,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IACpC,MAAM,QAAQ,GAAG,MAAM,WAAW,CAAC,GAAG,CAAC,CAAC;IAExC,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,yBAAyB,CAAC,CAAC,CAAC;QACpD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,MAAM,GAAG,MAAM,eAAe,CAAC,QAAQ,CAAC,CAAC;IAE/C,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;QACjB,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;QAC7C,OAAO;IACT,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,6BAA6B,CAAC,CAAC,CAAC;IACvD,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IAEvC,IAAI,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC;QACxB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,kDAAkD,CAAC,CAAC,CAAC;QAC9E,OAAO,CAAC,GAAG,CAAC,OAAO,KAAK,CAAC,IAAI,CAAC,YAAY,CAAC,oBAAoB,CAAC,CAAC;QACjE,OAAO;IACT,CAAC;IAED,IAAI,CAAC,MAAM,CAAC,UAAU,EAAE,CAAC;QACvB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,kDAAkD,CAAC,CAAC,CAAC;QAC9E,OAAO,CAAC,GAAG,CAAC,OAAO,KAAK,CAAC,IAAI,CAAC,YAAY,CAAC,kCAAkC,CAAC,CAAC;QAC/E,OAAO;IACT,CAAC;IAED,MAAM,OAAO,GAAG,WAAW,CAAC,QAAQ,CAAE,CAAC;IAEvC,eAAe;IACf,IAAI,MAAM,CAAC,WAAW,EAAE,CAAC;QACvB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,WAAW,CAAC,EAAE,GAAG,MAAM,CAAC,aAAa,EAAE,CAAC,CAAC;IACnE,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,GAAG,CACT,KAAK,CAAC,MAAM,CAAC,sBAAsB,CAAC,EACpC,gBAAgB,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,oBAAoB,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,EAAE,CACrG,CAAC;IACJ,CAAC;IAED,eAAe;IACf,IAAI,MAAM,CAAC,gBAAgB,KAAK,CAAC,EAAE,CAAC;QAClC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,qBAAqB,CAAC,EAAE,gCAAgC,MAAM,CAAC,UAAU,GAAG,CAAC,CAAC;IACxG,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,GAAG,CACT,KAAK,CAAC,MAAM,CAAC,mBAAmB,CAAC,EACjC,GAAG,MAAM,CAAC,gBAAgB,2CAA2C,MAAM,CAAC,WAAW,MAAM,MAAM,CAAC,UAAU,GAAG,CAClH,CAAC;IACJ,CAAC;IAED,yBAAyB;IACzB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,oBAAoB,CAAC,CAAC,CAAC;IAC7C,OAAO,CAAC,GAAG,CAAC,aAAa,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAC7D,OAAO,CAAC,GAAG,CAAC,aAAa,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,WAAW,EAAE,IAAI,OAAO,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,mBAAmB,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IAC1I,OAAO,CAAC,GAAG,CAAC,aAAa,OAAO,CAAC,eAAe,EAAE,CAAC,CAAC;IAEpD,gBAAgB;IAChB,IAAI,OAAO,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAClC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC,CAAC;QACxC,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE;YACrC,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,KAAK,WAAW,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,KAAK,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YAC7H,OAAO,CAAC,GAAG,CAAC,KAAK,IAAI,KAAK,IAAI,CAAC,QAAQ,CAAC,WAAW,EAAE,KAAK,CAAC,GAAG,CAAC,KAAK,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;QACnF,CAAC,CAAC,CAAC;IACL,CAAC;IAED,gBAAgB;IAChB,IAAI,MAAM,CAAC,uBAAuB,GAAG,CAAC,EAAE,CAAC;QACvC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,6BAA6B,CAAC,CAAC,CAAC;QACtD,OAAO,CAAC,GAAG,CAAC,KAAK,MAAM,CAAC,uBAAuB,6BAA6B,CAAC,CAAC;QAC9E,IAAI,MAAM,CAAC,UAAU,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC5C,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,MAAM,CAAC,UAAU,CAAC,UAAU,CAAC,MAAM,qCAAqC,CAAC,CAAC,CAAC;QAC1G,CAAC;IACH,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IACvC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,YAAY,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,kCAAkC,CAAC,CAAC,CAAC;IAC7F,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;AAClB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ui.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/ui.ts"],"names":[],"mappings":"AAMA,UAAU,SAAS;IACjB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,wBAAsB,SAAS,CAAC,OAAO,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CAmDjE"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import { getRepoRoot } from '../../git/context.js';
|
|
3
|
+
import { resolveCwd, isRelayInitialized, initRelayDir, listRegisteredRepos } from '../../storage/index.js';
|
|
4
|
+
import { startDashboardServer } from '../../server/index.js';
|
|
5
|
+
import { exec } from 'child_process';
|
|
6
|
+
export async function uiCommand(options) {
|
|
7
|
+
const isGlobal = Boolean(options.global);
|
|
8
|
+
const cwd = resolveCwd(options.dir);
|
|
9
|
+
let repoRoot = await getRepoRoot(cwd);
|
|
10
|
+
if (!repoRoot) {
|
|
11
|
+
if (isGlobal) {
|
|
12
|
+
const repos = listRegisteredRepos();
|
|
13
|
+
if (repos.length > 0) {
|
|
14
|
+
repoRoot = repos[0].path;
|
|
15
|
+
}
|
|
16
|
+
else {
|
|
17
|
+
repoRoot = cwd;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
else {
|
|
21
|
+
console.error(chalk.red('✗ Not a git repository. Use --global (-g) to view machine-wide dashboard.'));
|
|
22
|
+
process.exit(1);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
if (repoRoot && !isRelayInitialized(repoRoot)) {
|
|
26
|
+
initRelayDir(repoRoot);
|
|
27
|
+
}
|
|
28
|
+
console.log(chalk.bold(`\n🚀 Starting Relay ${isGlobal ? 'Global Multi-Repo' : 'Web'} Dashboard...`));
|
|
29
|
+
try {
|
|
30
|
+
const { url } = await startDashboardServer({
|
|
31
|
+
repoRoot: repoRoot || cwd,
|
|
32
|
+
port: options.port,
|
|
33
|
+
global: isGlobal,
|
|
34
|
+
});
|
|
35
|
+
console.log(chalk.green(`✓ Dashboard live at:`), chalk.bold.cyan(url));
|
|
36
|
+
console.log(chalk.dim(` Mode: ${isGlobal ? 'Global Multi-Repo' : 'Repository Workspace'}`));
|
|
37
|
+
console.log(chalk.dim(` Default Repo: ${repoRoot || cwd}`));
|
|
38
|
+
console.log(chalk.dim(` Press Ctrl+C to stop the dashboard server.\n`));
|
|
39
|
+
if (options.open !== false) {
|
|
40
|
+
// Auto-open browser on macOS / Linux / Windows
|
|
41
|
+
const startCmd = process.platform === 'darwin'
|
|
42
|
+
? `open ${url}`
|
|
43
|
+
: process.platform === 'win32'
|
|
44
|
+
? `start ${url}`
|
|
45
|
+
: `xdg-open ${url}`;
|
|
46
|
+
exec(startCmd, () => { });
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
catch (err) {
|
|
50
|
+
console.error(chalk.red('✗ Failed to start dashboard server:'), err);
|
|
51
|
+
process.exit(1);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
//# sourceMappingURL=ui.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ui.js","sourceRoot":"","sources":["../../../src/cli/commands/ui.ts"],"names":[],"mappings":"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"}
|