@madkid/relay-ctx 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/dist/commands/checkpoint.d.ts +18 -0
- package/dist/commands/checkpoint.d.ts.map +1 -0
- package/dist/commands/checkpoint.js +130 -0
- package/dist/commands/checkpoint.js.map +1 -0
- package/dist/commands/hooks.d.ts +36 -0
- package/dist/commands/hooks.d.ts.map +1 -0
- package/dist/commands/hooks.js +226 -0
- package/dist/commands/hooks.js.map +1 -0
- package/dist/commands/init.d.ts +14 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +228 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/inject.d.ts +20 -0
- package/dist/commands/inject.d.ts.map +1 -0
- package/dist/commands/inject.js +209 -0
- package/dist/commands/inject.js.map +1 -0
- package/dist/commands/list.d.ts +2 -0
- package/dist/commands/list.d.ts.map +1 -0
- package/dist/commands/list.js +174 -0
- package/dist/commands/list.js.map +1 -0
- package/dist/commands/sync.d.ts +17 -0
- package/dist/commands/sync.d.ts.map +1 -0
- package/dist/commands/sync.js +239 -0
- package/dist/commands/sync.js.map +1 -0
- package/dist/core/compressor.d.ts +16 -0
- package/dist/core/compressor.d.ts.map +1 -0
- package/dist/core/compressor.js +354 -0
- package/dist/core/compressor.js.map +1 -0
- package/dist/core/scanner.d.ts +40 -0
- package/dist/core/scanner.d.ts.map +1 -0
- package/dist/core/scanner.js +366 -0
- package/dist/core/scanner.js.map +1 -0
- package/dist/core/storage.d.ts +39 -0
- package/dist/core/storage.d.ts.map +1 -0
- package/dist/core/storage.js +122 -0
- package/dist/core/storage.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +57 -0
- package/dist/index.js.map +1 -0
- package/dist/test-relay.d.ts +2 -0
- package/dist/test-relay.d.ts.map +1 -0
- package/dist/test-relay.js +433 -0
- package/dist/test-relay.js.map +1 -0
- package/package.json +32 -0
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
|
+
};
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
exports.initCommand = initCommand;
|
|
40
|
+
const fs_1 = __importDefault(require("fs"));
|
|
41
|
+
const path_1 = __importDefault(require("path"));
|
|
42
|
+
const inquirer_1 = __importDefault(require("inquirer"));
|
|
43
|
+
const storage_1 = require("../core/storage");
|
|
44
|
+
/**
|
|
45
|
+
* Generate the initial PROJECT.md content from user answers.
|
|
46
|
+
*/
|
|
47
|
+
function generateProjectMd(projectName, description, techStack, currentWork, timestamp) {
|
|
48
|
+
return `# ${projectName}
|
|
49
|
+
|
|
50
|
+
> Relay context ā auto-generated on ${timestamp}
|
|
51
|
+
|
|
52
|
+
## What we're building
|
|
53
|
+
|
|
54
|
+
${description}
|
|
55
|
+
|
|
56
|
+
## Tech stack
|
|
57
|
+
|
|
58
|
+
${techStack
|
|
59
|
+
.split(',')
|
|
60
|
+
.map((t) => `- ${t.trim()}`)
|
|
61
|
+
.join('\n')}
|
|
62
|
+
|
|
63
|
+
## What's in progress
|
|
64
|
+
|
|
65
|
+
${currentWork}
|
|
66
|
+
|
|
67
|
+
## What's next
|
|
68
|
+
|
|
69
|
+
_(add your next priorities here)_
|
|
70
|
+
|
|
71
|
+
## Conventions
|
|
72
|
+
|
|
73
|
+
_(add project conventions, patterns, and rules here)_
|
|
74
|
+
|
|
75
|
+
## File structure
|
|
76
|
+
|
|
77
|
+
_(run \`relay sync\` to populate)_
|
|
78
|
+
|
|
79
|
+
## What's working
|
|
80
|
+
|
|
81
|
+
_(describe what's functional so far)_
|
|
82
|
+
|
|
83
|
+
## What we're NOT building
|
|
84
|
+
|
|
85
|
+
_(list out-of-scope items here)_
|
|
86
|
+
`;
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* relay init ā Initialize Relay for the current project.
|
|
90
|
+
*
|
|
91
|
+
* Flow:
|
|
92
|
+
* 1. Ensure relay root directory exists
|
|
93
|
+
* 2. Detect project name
|
|
94
|
+
* 3. Check for existing project, prompt for re-init
|
|
95
|
+
* 4. Interactive setup prompts
|
|
96
|
+
* 5. Check/prompt for Anthropic API key
|
|
97
|
+
* 6. Write initial PROJECT.md
|
|
98
|
+
* 7. Ask about installing git hooks
|
|
99
|
+
*/
|
|
100
|
+
async function initCommand() {
|
|
101
|
+
// 1. Ensure relay root exists
|
|
102
|
+
const relayRoot = (0, storage_1.getRelayRoot)();
|
|
103
|
+
fs_1.default.mkdirSync(relayRoot, { recursive: true });
|
|
104
|
+
// 2. Detect project name
|
|
105
|
+
const projectName = (0, storage_1.getProjectName)();
|
|
106
|
+
const projectPath = (0, storage_1.getProjectPath)();
|
|
107
|
+
console.log(`\nš Relay ā initializing for "${projectName}"\n`);
|
|
108
|
+
// 3. Check if already initialized
|
|
109
|
+
if (fs_1.default.existsSync(projectPath)) {
|
|
110
|
+
const { reinit } = await inquirer_1.default.prompt([
|
|
111
|
+
{
|
|
112
|
+
type: 'confirm',
|
|
113
|
+
name: 'reinit',
|
|
114
|
+
message: 'Project already initialized. Re-initialize?',
|
|
115
|
+
default: false,
|
|
116
|
+
},
|
|
117
|
+
]);
|
|
118
|
+
if (!reinit) {
|
|
119
|
+
console.log('Aborted.');
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
// 4. Interactive setup
|
|
124
|
+
const answers = await inquirer_1.default.prompt([
|
|
125
|
+
{
|
|
126
|
+
type: 'input',
|
|
127
|
+
name: 'description',
|
|
128
|
+
message: 'What are you building? (one line)',
|
|
129
|
+
validate: (input) => input.trim().length > 0 || 'Please enter a description',
|
|
130
|
+
},
|
|
131
|
+
{
|
|
132
|
+
type: 'input',
|
|
133
|
+
name: 'techStack',
|
|
134
|
+
message: 'What\'s your main tech stack? (comma separated)',
|
|
135
|
+
default: 'TypeScript, Node.js',
|
|
136
|
+
},
|
|
137
|
+
{
|
|
138
|
+
type: 'input',
|
|
139
|
+
name: 'currentWork',
|
|
140
|
+
message: 'What are you currently working on?',
|
|
141
|
+
default: 'Initial setup',
|
|
142
|
+
},
|
|
143
|
+
]);
|
|
144
|
+
// 5. Check for API key
|
|
145
|
+
const config = (0, storage_1.readConfig)();
|
|
146
|
+
if (!config.anthropicApiKey) {
|
|
147
|
+
const { apiKey } = await inquirer_1.default.prompt([
|
|
148
|
+
{
|
|
149
|
+
type: 'password',
|
|
150
|
+
name: 'apiKey',
|
|
151
|
+
message: 'Enter your Anthropic API key (press Enter to skip):',
|
|
152
|
+
mask: '*',
|
|
153
|
+
},
|
|
154
|
+
]);
|
|
155
|
+
if (apiKey && apiKey.trim()) {
|
|
156
|
+
config.anthropicApiKey = apiKey.trim();
|
|
157
|
+
(0, storage_1.writeConfig)(config);
|
|
158
|
+
console.log(' ā API key saved to config');
|
|
159
|
+
}
|
|
160
|
+
else {
|
|
161
|
+
console.log(' ā No API key configured. Using local fallback compression.');
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
// 6. Write PROJECT.md
|
|
165
|
+
const timestamp = new Date().toISOString().split('T')[0];
|
|
166
|
+
const content = generateProjectMd(projectName, answers.description, answers.techStack, answers.currentWork, timestamp);
|
|
167
|
+
(0, storage_1.writeProjectMd)(content);
|
|
168
|
+
// Create snapshots directory
|
|
169
|
+
const snapshotsDir = path_1.default.join(projectPath, 'snapshots');
|
|
170
|
+
fs_1.default.mkdirSync(snapshotsDir, { recursive: true });
|
|
171
|
+
// Write meta.json
|
|
172
|
+
const metaPath = path_1.default.join(projectPath, 'meta.json');
|
|
173
|
+
const meta = {
|
|
174
|
+
name: projectName,
|
|
175
|
+
cwd: process.cwd(),
|
|
176
|
+
lastSync: null,
|
|
177
|
+
lastCheckpoint: null,
|
|
178
|
+
};
|
|
179
|
+
fs_1.default.writeFileSync(metaPath, JSON.stringify(meta, null, 2), 'utf-8');
|
|
180
|
+
console.log(`\nā
Relay initialized for "${projectName}"`);
|
|
181
|
+
console.log(` š ${projectPath}`);
|
|
182
|
+
console.log(`\n Run \`relay sync\` to capture current project state.`);
|
|
183
|
+
// 7. Ask about git hooks
|
|
184
|
+
const gitDir = path_1.default.join(process.cwd(), '.git');
|
|
185
|
+
if (fs_1.default.existsSync(gitDir)) {
|
|
186
|
+
const { installHooksAnswer } = await inquirer_1.default.prompt([
|
|
187
|
+
{
|
|
188
|
+
type: 'confirm',
|
|
189
|
+
name: 'installHooksAnswer',
|
|
190
|
+
message: 'Install git hooks for automatic context tracking?',
|
|
191
|
+
default: true,
|
|
192
|
+
},
|
|
193
|
+
]);
|
|
194
|
+
if (installHooksAnswer) {
|
|
195
|
+
const { installHooks: doInstall } = await Promise.resolve().then(() => __importStar(require('./hooks')));
|
|
196
|
+
const { installed, skipped } = doInstall();
|
|
197
|
+
if (installed.length > 0) {
|
|
198
|
+
console.log(`\nā” Relay hooks installed for "${projectName}"\n`);
|
|
199
|
+
const HOOKS_INFO = {
|
|
200
|
+
'post-commit': 'auto-checkpoint with your commit message',
|
|
201
|
+
'post-checkout': 'auto-sync when you switch branches',
|
|
202
|
+
'post-merge': 'auto-sync + checkpoint after merges',
|
|
203
|
+
};
|
|
204
|
+
for (const name of installed) {
|
|
205
|
+
const desc = HOOKS_INFO[name] || '';
|
|
206
|
+
console.log(` ${name.padEnd(15)} ā ${desc}`);
|
|
207
|
+
}
|
|
208
|
+
console.log('\nEvery git commit now saves a Relay checkpoint automatically.');
|
|
209
|
+
console.log('After 30 commits you\'ll have a complete decision trail.');
|
|
210
|
+
console.log('\nTo remove: relay hooks --uninstall\n');
|
|
211
|
+
}
|
|
212
|
+
if (skipped.length > 0) {
|
|
213
|
+
for (const name of skipped) {
|
|
214
|
+
console.log(`ā ļø Skipped ${name}: hook already exists (not relay-managed).`);
|
|
215
|
+
console.log(' Add relay checkpoint manually.');
|
|
216
|
+
}
|
|
217
|
+
console.log('');
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
else {
|
|
221
|
+
console.log('You can install later with: relay hooks --install\n');
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
else {
|
|
225
|
+
console.log('');
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
//# sourceMappingURL=init.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* relay inject ā Output compressed context ready to paste into any AI.
|
|
3
|
+
*
|
|
4
|
+
* Options:
|
|
5
|
+
* - --raw: outputs full PROJECT.md
|
|
6
|
+
* - --ai: forces AI compression using Claude Haiku
|
|
7
|
+
*
|
|
8
|
+
* Flow:
|
|
9
|
+
* 1. Read PROJECT.md
|
|
10
|
+
* 2. Select intent and preprocess context
|
|
11
|
+
* 3. Compress using Claude Haiku or local budget truncation
|
|
12
|
+
* 4. Print with header/footer markers
|
|
13
|
+
* 5. Copy to clipboard
|
|
14
|
+
*/
|
|
15
|
+
export declare function injectCommand(options: {
|
|
16
|
+
raw?: boolean;
|
|
17
|
+
ai?: boolean;
|
|
18
|
+
bug?: boolean;
|
|
19
|
+
}): Promise<void>;
|
|
20
|
+
//# sourceMappingURL=inject.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"inject.d.ts","sourceRoot":"","sources":["../../src/commands/inject.ts"],"names":[],"mappings":"AA0EA;;;;;;;;;;;;;GAaG;AACH,wBAAsB,aAAa,CAAC,OAAO,EAAE;IAAE,GAAG,CAAC,EAAE,OAAO,CAAC;IAAC,EAAE,CAAC,EAAE,OAAO,CAAC;IAAC,GAAG,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAuE1G"}
|
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
|
+
};
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
exports.injectCommand = injectCommand;
|
|
40
|
+
const storage_1 = require("../core/storage");
|
|
41
|
+
const compressor_1 = require("../core/compressor");
|
|
42
|
+
const fs_1 = __importDefault(require("fs"));
|
|
43
|
+
const inquirer_1 = __importDefault(require("inquirer"));
|
|
44
|
+
const readline_1 = __importDefault(require("readline"));
|
|
45
|
+
/**
|
|
46
|
+
* Prompt the user to select an inject intent.
|
|
47
|
+
* Defaults to 'continue' if not running in a TTY.
|
|
48
|
+
*/
|
|
49
|
+
async function selectIntent() {
|
|
50
|
+
if (!process.stdin.isTTY) {
|
|
51
|
+
return 'continue';
|
|
52
|
+
}
|
|
53
|
+
const answers = await inquirer_1.default.prompt([
|
|
54
|
+
{
|
|
55
|
+
type: 'list',
|
|
56
|
+
name: 'intent',
|
|
57
|
+
message: "What's happening right now?",
|
|
58
|
+
choices: [
|
|
59
|
+
{
|
|
60
|
+
name: 'ā” Hit a limit ā continue exactly where I left off',
|
|
61
|
+
value: 'continue',
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
name: 'š Starting fresh ā orient the AI to my project',
|
|
65
|
+
value: 'newTask',
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
name: 'š Hit a bug ā include error context',
|
|
69
|
+
value: 'debug',
|
|
70
|
+
},
|
|
71
|
+
],
|
|
72
|
+
},
|
|
73
|
+
]);
|
|
74
|
+
return answers.intent;
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Ask user to input a multi-line error log.
|
|
78
|
+
* Resolves when the user hits Enter twice on an empty line.
|
|
79
|
+
*/
|
|
80
|
+
function askMultilineError() {
|
|
81
|
+
return new Promise((resolve) => {
|
|
82
|
+
console.log('\nPaste your error message (press Enter twice when done):');
|
|
83
|
+
const rl = readline_1.default.createInterface({
|
|
84
|
+
input: process.stdin,
|
|
85
|
+
output: process.stdout,
|
|
86
|
+
});
|
|
87
|
+
const errorLines = [];
|
|
88
|
+
let lastLineEmpty = false;
|
|
89
|
+
rl.on('line', (line) => {
|
|
90
|
+
if (line.trim() === '') {
|
|
91
|
+
if (lastLineEmpty || errorLines.length === 0) {
|
|
92
|
+
rl.close();
|
|
93
|
+
}
|
|
94
|
+
else {
|
|
95
|
+
lastLineEmpty = true;
|
|
96
|
+
errorLines.push(line);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
else {
|
|
100
|
+
lastLineEmpty = false;
|
|
101
|
+
errorLines.push(line);
|
|
102
|
+
}
|
|
103
|
+
});
|
|
104
|
+
rl.on('close', () => {
|
|
105
|
+
resolve(errorLines.join('\n').trim());
|
|
106
|
+
});
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* relay inject ā Output compressed context ready to paste into any AI.
|
|
111
|
+
*
|
|
112
|
+
* Options:
|
|
113
|
+
* - --raw: outputs full PROJECT.md
|
|
114
|
+
* - --ai: forces AI compression using Claude Haiku
|
|
115
|
+
*
|
|
116
|
+
* Flow:
|
|
117
|
+
* 1. Read PROJECT.md
|
|
118
|
+
* 2. Select intent and preprocess context
|
|
119
|
+
* 3. Compress using Claude Haiku or local budget truncation
|
|
120
|
+
* 4. Print with header/footer markers
|
|
121
|
+
* 5. Copy to clipboard
|
|
122
|
+
*/
|
|
123
|
+
async function injectCommand(options) {
|
|
124
|
+
const projectName = (0, storage_1.getProjectName)();
|
|
125
|
+
const projectPath = (0, storage_1.getProjectPath)();
|
|
126
|
+
if (!fs_1.default.existsSync(projectPath)) {
|
|
127
|
+
console.log('ā Relay not initialized for this project. Run `relay init` first.');
|
|
128
|
+
process.exit(1);
|
|
129
|
+
}
|
|
130
|
+
const projectMd = (0, storage_1.readProjectMd)();
|
|
131
|
+
if (!projectMd) {
|
|
132
|
+
console.log('ā PROJECT.md is empty. Run `relay sync` first.');
|
|
133
|
+
process.exit(1);
|
|
134
|
+
}
|
|
135
|
+
let output;
|
|
136
|
+
if (options.raw) {
|
|
137
|
+
output = projectMd;
|
|
138
|
+
}
|
|
139
|
+
else {
|
|
140
|
+
// 1. Get user intent (skip interactive menu if --bug is specified)
|
|
141
|
+
const intent = options.bug ? 'debug' : await selectIntent();
|
|
142
|
+
// 2. Ask for error logs if intent is 'debug'
|
|
143
|
+
let errorMessage = '';
|
|
144
|
+
if (intent === 'debug' && process.stdin.isTTY) {
|
|
145
|
+
errorMessage = await askMultilineError();
|
|
146
|
+
}
|
|
147
|
+
// 3. Preprocess context to match intent specific requirements and cap budget
|
|
148
|
+
const preprocessedMd = (0, compressor_1.preprocessContext)(projectMd, intent, errorMessage);
|
|
149
|
+
const config = (0, storage_1.readConfig)();
|
|
150
|
+
const apiKey = config.anthropicApiKey;
|
|
151
|
+
if (options.ai || apiKey) {
|
|
152
|
+
if (!apiKey && options.ai) {
|
|
153
|
+
console.log('ā Error: Anthropic API key is not configured, but --ai is forced.');
|
|
154
|
+
console.log(' Run `relay init` to set your Anthropic API key.\n');
|
|
155
|
+
process.exit(1);
|
|
156
|
+
}
|
|
157
|
+
try {
|
|
158
|
+
console.log('š Compressing context with Claude Haiku...\n');
|
|
159
|
+
output = await (0, compressor_1.compressContext)(preprocessedMd, apiKey || '', intent);
|
|
160
|
+
}
|
|
161
|
+
catch (err) {
|
|
162
|
+
console.log('ā ļø Compression failed, using fallback truncation.\n');
|
|
163
|
+
output = preprocessedMd;
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
else {
|
|
167
|
+
console.log('ā ļø No API key configured. Using local fallback truncation.');
|
|
168
|
+
console.log(' Run `relay init` to set your Anthropic API key.\n');
|
|
169
|
+
output = preprocessedMd;
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
// Print with clear markers
|
|
173
|
+
const header = `--- RELAY CONTEXT: ${projectName} ---`;
|
|
174
|
+
const footer = `--- END RELAY CONTEXT ---`;
|
|
175
|
+
console.log(header);
|
|
176
|
+
console.log(output);
|
|
177
|
+
console.log(footer);
|
|
178
|
+
// Attempt to copy to clipboard
|
|
179
|
+
try {
|
|
180
|
+
await copyToClipboard(`${header}\n${output}\n${footer}`);
|
|
181
|
+
console.log('\nš Copied to clipboard!');
|
|
182
|
+
}
|
|
183
|
+
catch {
|
|
184
|
+
// Clipboard copy is optional ā don't break if it fails
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* Attempt to copy text to system clipboard.
|
|
189
|
+
* Uses platform-specific commands.
|
|
190
|
+
*/
|
|
191
|
+
async function copyToClipboard(text) {
|
|
192
|
+
const { execSync } = await Promise.resolve().then(() => __importStar(require('child_process')));
|
|
193
|
+
if (process.platform === 'win32') {
|
|
194
|
+
execSync('clip', { input: text });
|
|
195
|
+
}
|
|
196
|
+
else if (process.platform === 'darwin') {
|
|
197
|
+
execSync('pbcopy', { input: text });
|
|
198
|
+
}
|
|
199
|
+
else {
|
|
200
|
+
// Linux: try xclip, then xsel
|
|
201
|
+
try {
|
|
202
|
+
execSync('xclip -selection clipboard', { input: text });
|
|
203
|
+
}
|
|
204
|
+
catch {
|
|
205
|
+
execSync('xsel --clipboard --input', { input: text });
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
//# sourceMappingURL=inject.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"inject.js","sourceRoot":"","sources":["../../src/commands/inject.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"list.d.ts","sourceRoot":"","sources":["../../src/commands/list.ts"],"names":[],"mappings":"AAsCA,wBAAsB,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC,CAkHjD"}
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
|
+
};
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
exports.listCommand = listCommand;
|
|
40
|
+
const fs_1 = __importDefault(require("fs"));
|
|
41
|
+
const path_1 = __importDefault(require("path"));
|
|
42
|
+
const storage_1 = require("../core/storage");
|
|
43
|
+
function formatRelativeTime(dateStr) {
|
|
44
|
+
if (!dateStr)
|
|
45
|
+
return 'never synced';
|
|
46
|
+
const parsed = Date.parse(dateStr);
|
|
47
|
+
if (isNaN(parsed))
|
|
48
|
+
return 'never synced';
|
|
49
|
+
const now = Date.now();
|
|
50
|
+
const diffMs = now - parsed;
|
|
51
|
+
const diffSeconds = Math.floor(diffMs / 1000);
|
|
52
|
+
const diffMinutes = Math.floor(diffSeconds / 60);
|
|
53
|
+
const diffHours = Math.floor(diffMinutes / 60);
|
|
54
|
+
const diffDays = Math.floor(diffHours / 24);
|
|
55
|
+
if (diffSeconds < 0) {
|
|
56
|
+
return 'just now';
|
|
57
|
+
}
|
|
58
|
+
if (diffSeconds < 60) {
|
|
59
|
+
return 'just now';
|
|
60
|
+
}
|
|
61
|
+
if (diffMinutes < 60) {
|
|
62
|
+
return `${diffMinutes} minute${diffMinutes === 1 ? '' : 's'} ago`;
|
|
63
|
+
}
|
|
64
|
+
if (diffHours < 24) {
|
|
65
|
+
return `${diffHours} hour${diffHours === 1 ? '' : 's'} ago`;
|
|
66
|
+
}
|
|
67
|
+
return `${diffDays} day${diffDays === 1 ? '' : 's'} ago`;
|
|
68
|
+
}
|
|
69
|
+
async function listCommand() {
|
|
70
|
+
const chalk = (await Promise.resolve().then(() => __importStar(require('chalk')))).default;
|
|
71
|
+
const relayRoot = (0, storage_1.getRelayRoot)();
|
|
72
|
+
const projectsDir = path_1.default.join(relayRoot, 'projects');
|
|
73
|
+
if (!fs_1.default.existsSync(projectsDir)) {
|
|
74
|
+
console.log('No tracked projects found.');
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
let entries = [];
|
|
78
|
+
try {
|
|
79
|
+
entries = fs_1.default.readdirSync(projectsDir, { withFileTypes: true });
|
|
80
|
+
}
|
|
81
|
+
catch (err) {
|
|
82
|
+
console.log('ā Error: Could not read projects directory.');
|
|
83
|
+
process.exit(1);
|
|
84
|
+
}
|
|
85
|
+
const projectDirs = entries.filter((e) => e.isDirectory()).map((e) => e.name);
|
|
86
|
+
if (projectDirs.length === 0) {
|
|
87
|
+
console.log('No tracked projects found.');
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
const projectsInfo = projectDirs.map((dirName) => {
|
|
91
|
+
const projectPath = path_1.default.join(projectsDir, dirName);
|
|
92
|
+
const metaPath = path_1.default.join(projectPath, 'meta.json');
|
|
93
|
+
let meta;
|
|
94
|
+
if (fs_1.default.existsSync(metaPath)) {
|
|
95
|
+
try {
|
|
96
|
+
meta = JSON.parse(fs_1.default.readFileSync(metaPath, 'utf-8'));
|
|
97
|
+
}
|
|
98
|
+
catch {
|
|
99
|
+
meta = { name: dirName, cwd: '', lastSync: null, lastCheckpoint: null };
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
else {
|
|
103
|
+
meta = { name: dirName, cwd: '', lastSync: null, lastCheckpoint: null };
|
|
104
|
+
}
|
|
105
|
+
// fallback to dirName if name is empty in meta
|
|
106
|
+
if (!meta.name) {
|
|
107
|
+
meta.name = dirName;
|
|
108
|
+
}
|
|
109
|
+
// Count snapshots/
|
|
110
|
+
const snapshotsDir = path_1.default.join(projectPath, 'snapshots');
|
|
111
|
+
let checkpointCount = 0;
|
|
112
|
+
if (fs_1.default.existsSync(snapshotsDir)) {
|
|
113
|
+
try {
|
|
114
|
+
const files = fs_1.default.readdirSync(snapshotsDir);
|
|
115
|
+
checkpointCount = files.filter((f) => f.endsWith('.md')).length;
|
|
116
|
+
}
|
|
117
|
+
catch {
|
|
118
|
+
// ignore
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
return {
|
|
122
|
+
...meta,
|
|
123
|
+
projectPath,
|
|
124
|
+
checkpointCount,
|
|
125
|
+
};
|
|
126
|
+
});
|
|
127
|
+
// Sort by lastSync descending (most recently synced first, never-synced at bottom)
|
|
128
|
+
projectsInfo.sort((a, b) => {
|
|
129
|
+
const aTime = a.lastSync ? Date.parse(a.lastSync) : 0;
|
|
130
|
+
const bTime = b.lastSync ? Date.parse(b.lastSync) : 0;
|
|
131
|
+
const aValid = !isNaN(aTime) && a.lastSync !== null;
|
|
132
|
+
const bValid = !isNaN(bTime) && b.lastSync !== null;
|
|
133
|
+
if (!aValid && !bValid)
|
|
134
|
+
return 0;
|
|
135
|
+
if (!aValid)
|
|
136
|
+
return 1; // move a to the bottom
|
|
137
|
+
if (!bValid)
|
|
138
|
+
return -1; // move b to the bottom
|
|
139
|
+
return bTime - aTime;
|
|
140
|
+
});
|
|
141
|
+
console.log(`\nš Tracked Relay Projects:\n`);
|
|
142
|
+
for (const proj of projectsInfo) {
|
|
143
|
+
let pathText = proj.cwd || '(unknown)';
|
|
144
|
+
let isMovedOrDeleted = false;
|
|
145
|
+
if (proj.cwd) {
|
|
146
|
+
try {
|
|
147
|
+
if (!fs_1.default.existsSync(proj.cwd)) {
|
|
148
|
+
isMovedOrDeleted = true;
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
catch {
|
|
152
|
+
isMovedOrDeleted = true;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
else {
|
|
156
|
+
isMovedOrDeleted = true;
|
|
157
|
+
}
|
|
158
|
+
const pathStr = isMovedOrDeleted
|
|
159
|
+
? chalk.yellow(chalk.dim(`${pathText} (moved or deleted)`))
|
|
160
|
+
: chalk.green(pathText);
|
|
161
|
+
const relativeSync = formatRelativeTime(proj.lastSync);
|
|
162
|
+
const relativeCheckpoint = proj.lastCheckpoint ? formatRelativeTime(proj.lastCheckpoint) : null;
|
|
163
|
+
console.log(` ${chalk.cyan.bold(proj.name)}`);
|
|
164
|
+
console.log(` ${chalk.gray('Path:')} ${pathStr}`);
|
|
165
|
+
console.log(` ${chalk.gray('Last Sync:')} ${relativeSync}`);
|
|
166
|
+
let checkpointInfo = `${proj.checkpointCount} saved`;
|
|
167
|
+
if (proj.checkpointCount > 0 && relativeCheckpoint) {
|
|
168
|
+
checkpointInfo += ` (last: ${relativeCheckpoint})`;
|
|
169
|
+
}
|
|
170
|
+
console.log(` ${chalk.gray('Checkpoints:')} ${checkpointInfo}`);
|
|
171
|
+
console.log('');
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
//# sourceMappingURL=list.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"list.js","sourceRoot":"","sources":["../../src/commands/list.ts"],"names":[],"mappings":"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"}
|