@qelos/aidev 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.
Files changed (60) hide show
  1. package/.claude/settings.local.json +9 -0
  2. package/.cursor/rules/aidev.mdc +57 -0
  3. package/.env.aidev.example +17 -0
  4. package/CLAUDE.md +32 -0
  5. package/CONTRIBUTING.md +78 -0
  6. package/LICENSE +21 -0
  7. package/README.md +245 -0
  8. package/dist/ai/base.d.ts.map +1 -0
  9. package/dist/ai/base.js +3 -0
  10. package/dist/ai/claude.d.ts.map +1 -0
  11. package/dist/ai/claude.js +33 -0
  12. package/dist/ai/cursor.d.ts.map +1 -0
  13. package/dist/ai/cursor.js +33 -0
  14. package/dist/ai/index.d.ts.map +1 -0
  15. package/dist/ai/index.js +13 -0
  16. package/dist/cli.d.ts.map +1 -0
  17. package/dist/cli.js +74 -0
  18. package/dist/commands/help.d.ts.map +1 -0
  19. package/dist/commands/help.js +48 -0
  20. package/dist/commands/init.d.ts.map +1 -0
  21. package/dist/commands/init.js +255 -0
  22. package/dist/commands/run.d.ts.map +1 -0
  23. package/dist/commands/run.js +257 -0
  24. package/dist/commands/schedule.d.ts.map +1 -0
  25. package/dist/commands/schedule.js +191 -0
  26. package/dist/config.d.ts.map +1 -0
  27. package/dist/config.js +89 -0
  28. package/dist/git.d.ts.map +1 -0
  29. package/dist/git.js +108 -0
  30. package/dist/logger.d.ts.map +1 -0
  31. package/dist/logger.js +88 -0
  32. package/dist/platform.d.ts.map +1 -0
  33. package/dist/platform.js +69 -0
  34. package/dist/providers/base.d.ts.map +1 -0
  35. package/dist/providers/base.js +3 -0
  36. package/dist/providers/clickup.d.ts.map +1 -0
  37. package/dist/providers/clickup.js +67 -0
  38. package/dist/providers/index.d.ts.map +1 -0
  39. package/dist/providers/index.js +19 -0
  40. package/dist/types.d.ts.map +1 -0
  41. package/dist/types.js +3 -0
  42. package/package.json +28 -0
  43. package/src/ai/base.ts +11 -0
  44. package/src/ai/claude.ts +35 -0
  45. package/src/ai/cursor.ts +35 -0
  46. package/src/ai/index.ts +15 -0
  47. package/src/cli.ts +83 -0
  48. package/src/commands/help.ts +43 -0
  49. package/src/commands/init.ts +296 -0
  50. package/src/commands/run.ts +283 -0
  51. package/src/commands/schedule.ts +179 -0
  52. package/src/config.ts +59 -0
  53. package/src/git.ts +109 -0
  54. package/src/logger.ts +53 -0
  55. package/src/platform.ts +33 -0
  56. package/src/providers/base.ts +8 -0
  57. package/src/providers/clickup.ts +107 -0
  58. package/src/providers/index.ts +20 -0
  59. package/src/types.ts +33 -0
  60. package/tsconfig.json +19 -0
@@ -0,0 +1,191 @@
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.scheduleSetCommand = scheduleSetCommand;
40
+ exports.scheduleGetCommand = scheduleGetCommand;
41
+ const node_child_process_1 = require("node:child_process");
42
+ const readline = __importStar(require("node:readline/promises"));
43
+ const node_process_1 = require("node:process");
44
+ const logger_1 = require("../logger");
45
+ const platform_1 = require("../platform");
46
+ const chalk_1 = __importDefault(require("chalk"));
47
+ // ─── Preset schedules ────────────────────────────────────────────────────────
48
+ const PRESETS = [
49
+ { label: 'Every 15 minutes', cron: '*/15 * * * *' },
50
+ { label: 'Every 30 minutes', cron: '*/30 * * * *' },
51
+ { label: 'Every hour', cron: '0 * * * *' },
52
+ { label: 'Every 5 hours', cron: '0 */5 * * *' },
53
+ { label: 'Every day at 8am', cron: '0 8 * * *' },
54
+ ];
55
+ async function pickCron() {
56
+ console.log('\n Select a schedule:');
57
+ PRESETS.forEach((p, i) => console.log(` ${chalk_1.default.cyan(String(i + 1))}. ${p.label} ${chalk_1.default.dim(p.cron)}`));
58
+ const rl = readline.createInterface({ input: node_process_1.stdin, output: node_process_1.stdout });
59
+ try {
60
+ while (true) {
61
+ const raw = await rl.question(`\n Choice ${chalk_1.default.dim('[1]')}: `);
62
+ const val = raw.trim() || '1';
63
+ const idx = parseInt(val, 10);
64
+ if (idx >= 1 && idx <= PRESETS.length)
65
+ return PRESETS[idx - 1].cron;
66
+ console.log(chalk_1.default.yellow(` Enter a number between 1 and ${PRESETS.length}.`));
67
+ }
68
+ }
69
+ finally {
70
+ rl.close();
71
+ }
72
+ }
73
+ // ─── Shared helpers ───────────────────────────────────────────────────────────
74
+ function getAidevBin() {
75
+ return (0, platform_1.findBin)('aidev') ?? 'aidev';
76
+ }
77
+ // ─── Unix (crontab) ───────────────────────────────────────────────────────────
78
+ const UNIX_MARKER_PREFIX = '# aidev-cwd:';
79
+ function getCrontab() {
80
+ const result = (0, node_child_process_1.spawnSync)('crontab', ['-l'], { encoding: 'utf8' });
81
+ return result.status === 0 ? result.stdout || '' : '';
82
+ }
83
+ function setCrontab(content) {
84
+ const result = (0, node_child_process_1.spawnSync)('crontab', ['-'], { input: content, encoding: 'utf8' });
85
+ return result.status === 0;
86
+ }
87
+ function scheduleSetUnix(cronExpr) {
88
+ const cwd = process.cwd();
89
+ const marker = `${UNIX_MARKER_PREFIX}${cwd}`;
90
+ const aidevBin = getAidevBin();
91
+ const newLine = `${cronExpr} cd ${cwd} && ${aidevBin} run ${marker}`;
92
+ const lines = getCrontab().split('\n').filter((l) => !l.includes(marker));
93
+ lines.push(newLine);
94
+ const updated = lines.join('\n').replace(/\n+$/, '') + '\n';
95
+ if (setCrontab(updated)) {
96
+ logger_1.logger.success(`Cron schedule set: ${cronExpr}`);
97
+ logger_1.logger.info(`Entry: ${newLine}`);
98
+ }
99
+ else {
100
+ logger_1.logger.error('Failed to update crontab');
101
+ process.exit(1);
102
+ }
103
+ }
104
+ function scheduleGetUnix() {
105
+ const cwd = process.cwd();
106
+ const marker = `${UNIX_MARKER_PREFIX}${cwd}`;
107
+ const entry = getCrontab().split('\n').find((l) => l.includes(marker));
108
+ if (entry) {
109
+ logger_1.logger.info(`Current schedule for ${cwd}:`);
110
+ console.log(entry);
111
+ }
112
+ else {
113
+ logger_1.logger.warn(`No schedule found for ${cwd}`);
114
+ logger_1.logger.info('Use "aidev schedule set" to configure one.');
115
+ }
116
+ }
117
+ // ─── Windows (schtasks) ───────────────────────────────────────────────────────
118
+ /**
119
+ * Converts a cron expression to schtasks /sc + /mo + /st arguments.
120
+ * Supports the subset used by the preset list.
121
+ */
122
+ function cronToSchtasksArgs(cron) {
123
+ // */N * * * * → every N minutes
124
+ const everyMin = cron.match(/^\*\/(\d+) \* \* \* \*$/);
125
+ if (everyMin)
126
+ return ['/sc', 'MINUTE', '/mo', everyMin[1]];
127
+ // 0 * * * * → every hour
128
+ if (cron === '0 * * * *')
129
+ return ['/sc', 'HOURLY', '/mo', '1'];
130
+ // 0 */N * * * → every N hours
131
+ const everyHour = cron.match(/^0 \*\/(\d+) \* \* \*$/);
132
+ if (everyHour)
133
+ return ['/sc', 'HOURLY', '/mo', everyHour[1]];
134
+ // 0 H * * * → daily at H:00
135
+ const daily = cron.match(/^0 (\d+) \* \* \*$/);
136
+ if (daily)
137
+ return ['/sc', 'DAILY', '/st', `${daily[1].padStart(2, '0')}:00`];
138
+ return null;
139
+ }
140
+ /** Stable task name derived from cwd — safe for Task Scheduler. */
141
+ function windowsTaskName(cwd) {
142
+ const sanitized = cwd.replace(/[:\\\/]+/g, '-').replace(/^-+|-+$/g, '');
143
+ return `aidev\\${sanitized}`;
144
+ }
145
+ function scheduleSetWindows(cronExpr) {
146
+ const cwd = process.cwd();
147
+ const schtasksArgs = cronToSchtasksArgs(cronExpr);
148
+ if (!schtasksArgs) {
149
+ logger_1.logger.error(`Cron expression "${cronExpr}" cannot be mapped to Windows Task Scheduler.\n` +
150
+ ' Use "aidev schedule set" (no argument) to choose a supported preset.');
151
+ process.exit(1);
152
+ }
153
+ const taskName = windowsTaskName(cwd);
154
+ const aidevBin = getAidevBin();
155
+ // cmd /c: run command and exit; /d: change drive+dir
156
+ const command = `cmd /c cd /d "${cwd}" && "${aidevBin}" run`;
157
+ const result = (0, node_child_process_1.spawnSync)('schtasks', ['/create', '/f', '/tn', taskName, '/tr', command, ...schtasksArgs], { encoding: 'utf8' });
158
+ if (result.status === 0) {
159
+ logger_1.logger.success(`Task Scheduler entry created: ${taskName}`);
160
+ logger_1.logger.info(`Schedule: ${cronExpr}`);
161
+ }
162
+ else {
163
+ logger_1.logger.error(`Failed to create Task Scheduler entry:\n${result.stderr}`);
164
+ process.exit(1);
165
+ }
166
+ }
167
+ function scheduleGetWindows() {
168
+ const cwd = process.cwd();
169
+ const taskName = windowsTaskName(cwd);
170
+ const result = (0, node_child_process_1.spawnSync)('schtasks', ['/query', '/tn', taskName, '/fo', 'LIST'], {
171
+ encoding: 'utf8',
172
+ });
173
+ if (result.status === 0) {
174
+ logger_1.logger.info(`Task Scheduler entry for ${cwd}:`);
175
+ console.log(result.stdout.trim());
176
+ }
177
+ else {
178
+ logger_1.logger.warn(`No Task Scheduler entry found for ${cwd}`);
179
+ logger_1.logger.info('Use "aidev schedule set" to configure one.');
180
+ }
181
+ }
182
+ // ─── Public API ───────────────────────────────────────────────────────────────
183
+ async function scheduleSetCommand(cronExpr) {
184
+ if (!cronExpr)
185
+ cronExpr = await pickCron();
186
+ platform_1.isWindows ? scheduleSetWindows(cronExpr) : scheduleSetUnix(cronExpr);
187
+ }
188
+ async function scheduleGetCommand() {
189
+ platform_1.isWindows ? scheduleGetWindows() : scheduleGetUnix();
190
+ }
191
+ //# sourceMappingURL=schedule.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,MAAM,EAAa,MAAM,SAAS,CAAC;AAG5C,wBAAgB,UAAU,CAAC,aAAa,CAAC,EAAE,MAAM,GAAG,MAAM,CAoDzD"}
package/dist/config.js ADDED
@@ -0,0 +1,89 @@
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
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.loadConfig = loadConfig;
37
+ const dotenv = __importStar(require("dotenv"));
38
+ const path = __importStar(require("node:path"));
39
+ const fs = __importStar(require("node:fs"));
40
+ const git_1 = require("./git");
41
+ function loadConfig(customEnvPath) {
42
+ const envPath = customEnvPath
43
+ ? path.resolve(customEnvPath)
44
+ : path.join(process.cwd(), '.env.aidev');
45
+ if (customEnvPath && !fs.existsSync(envPath)) {
46
+ throw new Error(`Env file not found: ${envPath}`);
47
+ }
48
+ if (fs.existsSync(envPath)) {
49
+ dotenv.config({ path: envPath });
50
+ }
51
+ const required = ['CLICKUP_API_KEY', 'CLICKUP_TEAM_ID', 'CLICKUP_TAG'];
52
+ for (const key of required) {
53
+ if (!process.env[key]) {
54
+ throw new Error(`Missing required config: ${key}. Run 'aidev init' to create .env.aidev`);
55
+ }
56
+ }
57
+ const validAgents = ['claude', 'cursor'];
58
+ const agentsRaw = process.env.AGENTS || 'claude,cursor';
59
+ const agents = agentsRaw
60
+ .split(',')
61
+ .map((s) => s.trim().toLowerCase())
62
+ .filter(Boolean);
63
+ const invalid = agents.filter((a) => !validAgents.includes(a));
64
+ if (invalid.length) {
65
+ throw new Error(`Invalid agent(s): ${invalid.join(', ')}. Valid: ${validAgents.join(', ')}`);
66
+ }
67
+ if (agents.length === 0) {
68
+ throw new Error(`AGENTS must contain at least one agent. Valid: ${validAgents.join(', ')}`);
69
+ }
70
+ const devNotesMode = (process.env.DEV_NOTES_MODE || 'smart');
71
+ if (!['smart', 'always'].includes(devNotesMode)) {
72
+ throw new Error(`Invalid DEV_NOTES_MODE: ${devNotesMode}. Must be smart or always`);
73
+ }
74
+ return {
75
+ provider: process.env.PROVIDER || 'clickup',
76
+ clickupApiKey: process.env.CLICKUP_API_KEY,
77
+ clickupTeamId: process.env.CLICKUP_TEAM_ID,
78
+ clickupTag: process.env.CLICKUP_TAG,
79
+ clickupPendingStatus: process.env.CLICKUP_PENDING_STATUS || 'pending',
80
+ clickupInReviewStatus: process.env.CLICKUP_IN_REVIEW_STATUS || 'review',
81
+ assigneeTag: process.env.ASSIGNEE_TAG || '',
82
+ gitRemote: process.env.GIT_REMOTE || (0, git_1.detectRemote)() || 'origin',
83
+ githubBaseBranch: process.env.GITHUB_BASE_BRANCH || 'main',
84
+ githubRepo: process.env.GITHUB_REPO || '',
85
+ agents,
86
+ devNotesMode,
87
+ };
88
+ }
89
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"git.d.ts","sourceRoot":"","sources":["../src/git.ts"],"names":[],"mappings":"AAeA,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAG1E;AAED,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAuB5E;AAED,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAQpD;AAED,wBAAgB,UAAU,IAAI,OAAO,CAGpC;AAED,wBAAgB,MAAM,IAAI,OAAO,CAGhC;AAED,wBAAgB,MAAM,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAQ/C;AAED,wBAAgB,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAQ5D;AAED,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAGjD;AAED,oEAAoE;AACpE,wBAAgB,YAAY,IAAI,MAAM,GAAG,IAAI,CAS5C;AAED,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAM5C"}
package/dist/git.js ADDED
@@ -0,0 +1,108 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.remoteBranchExists = remoteBranchExists;
4
+ exports.fetchAndCheckout = fetchAndCheckout;
5
+ exports.createBranch = createBranch;
6
+ exports.hasChanges = hasChanges;
7
+ exports.addAll = addAll;
8
+ exports.commit = commit;
9
+ exports.push = push;
10
+ exports.deleteBranch = deleteBranch;
11
+ exports.detectRemote = detectRemote;
12
+ exports.slugify = slugify;
13
+ const node_child_process_1 = require("node:child_process");
14
+ const logger_1 = require("./logger");
15
+ function git(args, cwd) {
16
+ const result = (0, node_child_process_1.spawnSync)('git', args, {
17
+ cwd: cwd || process.cwd(),
18
+ encoding: 'utf8',
19
+ });
20
+ return {
21
+ stdout: result.stdout || '',
22
+ stderr: result.stderr || '',
23
+ status: result.status ?? 1,
24
+ };
25
+ }
26
+ function remoteBranchExists(remote, branch) {
27
+ const result = git(['ls-remote', '--heads', remote, branch]);
28
+ return result.status === 0 && result.stdout.trim().length > 0;
29
+ }
30
+ function fetchAndCheckout(remote, baseBranch) {
31
+ logger_1.logger.debug(`git fetch ${remote}`);
32
+ const fetch = git(['fetch', remote]);
33
+ if (fetch.status !== 0) {
34
+ logger_1.logger.error(`git fetch failed: ${fetch.stderr}`);
35
+ return false;
36
+ }
37
+ logger_1.logger.debug(`git checkout ${baseBranch}`);
38
+ const checkout = git(['checkout', baseBranch]);
39
+ if (checkout.status !== 0) {
40
+ logger_1.logger.error(`git checkout ${baseBranch} failed: ${checkout.stderr}`);
41
+ return false;
42
+ }
43
+ logger_1.logger.debug(`git pull ${remote} ${baseBranch}`);
44
+ const pull = git(['pull', remote, baseBranch]);
45
+ if (pull.status !== 0) {
46
+ logger_1.logger.error(`git pull failed: ${pull.stderr}`);
47
+ return false;
48
+ }
49
+ return true;
50
+ }
51
+ function createBranch(branch) {
52
+ logger_1.logger.debug(`git checkout -b ${branch}`);
53
+ const result = git(['checkout', '-b', branch]);
54
+ if (result.status !== 0) {
55
+ logger_1.logger.error(`git checkout -b ${branch} failed: ${result.stderr}`);
56
+ return false;
57
+ }
58
+ return true;
59
+ }
60
+ function hasChanges() {
61
+ const result = git(['status', '--porcelain']);
62
+ return result.status === 0 && result.stdout.trim().length > 0;
63
+ }
64
+ function addAll() {
65
+ const result = git(['add', '-A']);
66
+ return result.status === 0;
67
+ }
68
+ function commit(message) {
69
+ logger_1.logger.debug(`git commit -m "${message}"`);
70
+ const result = git(['commit', '-m', message]);
71
+ if (result.status !== 0) {
72
+ logger_1.logger.error(`git commit failed: ${result.stderr}`);
73
+ return false;
74
+ }
75
+ return true;
76
+ }
77
+ function push(remote, branch) {
78
+ logger_1.logger.debug(`git push ${remote} ${branch}`);
79
+ const result = git(['push', remote, branch]);
80
+ if (result.status !== 0) {
81
+ logger_1.logger.error(`git push failed: ${result.stderr}`);
82
+ return false;
83
+ }
84
+ return true;
85
+ }
86
+ function deleteBranch(branch) {
87
+ git(['checkout', '-']);
88
+ git(['branch', '-D', branch]);
89
+ }
90
+ /** Returns the name of the first usable remote (prefers origin). */
91
+ function detectRemote() {
92
+ // Verify origin exists first
93
+ const originCheck = git(['remote', 'get-url', 'origin']);
94
+ if (originCheck.status === 0)
95
+ return 'origin';
96
+ // Fall back to first listed remote
97
+ const list = git(['remote']);
98
+ const first = list.stdout.trim().split('\n')[0]?.trim();
99
+ return first || null;
100
+ }
101
+ function slugify(text) {
102
+ return text
103
+ .toLowerCase()
104
+ .replace(/[^a-z0-9]+/g, '-')
105
+ .replace(/^-|-$/g, '')
106
+ .slice(0, 50);
107
+ }
108
+ //# sourceMappingURL=git.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../src/logger.ts"],"names":[],"mappings":"AAoBA,wBAAgB,WAAW,IAAI,IAAI,CAGlC;AAED,eAAO,MAAM,MAAM;gBACL,MAAM;mBAIH,MAAM;gBAIT,MAAM;iBAIL,MAAM;gBAIP,MAAM;iBAIL,MAAM;CAMpB,CAAC"}
package/dist/logger.js ADDED
@@ -0,0 +1,88 @@
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.logger = void 0;
40
+ exports.logRunStart = logRunStart;
41
+ const fs = __importStar(require("node:fs"));
42
+ const path = __importStar(require("node:path"));
43
+ const chalk_1 = __importDefault(require("chalk"));
44
+ const LOG_FILE = path.join(process.cwd(), 'aidev.log');
45
+ // Strip ANSI escape codes for clean file output
46
+ function strip(s) {
47
+ return s.replace(/\x1B\[[0-9;]*m/g, '');
48
+ }
49
+ function timestamp() {
50
+ return new Date().toISOString();
51
+ }
52
+ function writeLog(level, msg) {
53
+ const line = `${timestamp()} [${level}] ${strip(msg)}\n`;
54
+ fs.appendFileSync(LOG_FILE, line, 'utf8');
55
+ }
56
+ function logRunStart() {
57
+ const sep = '─'.repeat(60);
58
+ fs.appendFileSync(LOG_FILE, `\n${sep}\n${timestamp()} [run] started\n${sep}\n`, 'utf8');
59
+ }
60
+ exports.logger = {
61
+ info: (msg) => {
62
+ console.log(chalk_1.default.blue('[aidev]'), msg);
63
+ writeLog('info', msg);
64
+ },
65
+ success: (msg) => {
66
+ console.log(chalk_1.default.green('[aidev]'), msg);
67
+ writeLog('success', msg);
68
+ },
69
+ warn: (msg) => {
70
+ console.log(chalk_1.default.yellow('[aidev]'), msg);
71
+ writeLog('warn', msg);
72
+ },
73
+ error: (msg) => {
74
+ console.error(chalk_1.default.red('[aidev]'), msg);
75
+ writeLog('error', msg);
76
+ },
77
+ task: (msg) => {
78
+ console.log(chalk_1.default.cyan('[task]'), msg);
79
+ writeLog('task', msg);
80
+ },
81
+ debug: (msg) => {
82
+ if (process.env.DEBUG) {
83
+ console.log(chalk_1.default.gray('[debug]'), msg);
84
+ writeLog('debug', msg);
85
+ }
86
+ },
87
+ };
88
+ //# sourceMappingURL=logger.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"platform.d.ts","sourceRoot":"","sources":["../src/platform.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,SAAS,SAA+B,CAAC;AAEtD;;;;GAIG;AACH,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAkBnD;AAED,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEnD"}
@@ -0,0 +1,69 @@
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
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.isWindows = void 0;
37
+ exports.findBin = findBin;
38
+ exports.commandExists = commandExists;
39
+ const fs = __importStar(require("node:fs"));
40
+ const path = __importStar(require("node:path"));
41
+ exports.isWindows = process.platform === 'win32';
42
+ /**
43
+ * Finds the full path of a binary by searching PATH (and PATHEXT on Windows).
44
+ * Returns the resolved path, or null if not found.
45
+ * Uses only Node.js fs — no `which` / `where` subprocess.
46
+ */
47
+ function findBin(name) {
48
+ const dirs = (process.env.PATH ?? '').split(path.delimiter).filter(Boolean);
49
+ const exts = exports.isWindows
50
+ ? (process.env.PATHEXT ?? '.EXE;.CMD;.BAT;.COM').split(';').map((e) => e.toLowerCase())
51
+ : [''];
52
+ for (const dir of dirs) {
53
+ for (const ext of exts) {
54
+ const full = path.join(dir, name + ext);
55
+ try {
56
+ fs.accessSync(full, fs.constants.F_OK);
57
+ return full;
58
+ }
59
+ catch {
60
+ // not here — keep searching
61
+ }
62
+ }
63
+ }
64
+ return null;
65
+ }
66
+ function commandExists(name) {
67
+ return findBin(name) !== null;
68
+ }
69
+ //# sourceMappingURL=platform.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../../src/providers/base.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,UAAU,CAAC;AAEzC,MAAM,WAAW,YAAY;IAC3B,UAAU,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;IAC9B,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACzD,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;IAChD,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC7D"}
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=base.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"clickup.d.ts","sourceRoot":"","sources":["../../src/providers/clickup.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AACjD,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AAGtC,qBAAa,eAAgB,YAAW,YAAY;IAClD,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,GAAG,CAAS;IACpB,OAAO,CAAC,WAAW,CAAS;gBAEhB,MAAM,EAAE,MAAM;YAOZ,OAAO;IAmBf,UAAU,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;IA8B7B,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAQxD,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC;IAyB/C,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAOlE"}
@@ -0,0 +1,67 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ClickUpProvider = void 0;
4
+ const logger_1 = require("../logger");
5
+ class ClickUpProvider {
6
+ constructor(config) {
7
+ this.apiKey = config.clickupApiKey;
8
+ this.teamId = config.clickupTeamId;
9
+ this.tag = config.clickupTag;
10
+ this.assigneeTag = config.assigneeTag;
11
+ }
12
+ async request(path, options = {}) {
13
+ const url = `https://api.clickup.com/api/v2${path}`;
14
+ const res = await fetch(url, {
15
+ ...options,
16
+ headers: {
17
+ Authorization: this.apiKey,
18
+ 'Content-Type': 'application/json',
19
+ ...(options.headers || {}),
20
+ },
21
+ });
22
+ if (!res.ok) {
23
+ const body = await res.text();
24
+ throw new Error(`ClickUp API error ${res.status}: ${body}`);
25
+ }
26
+ return res.json();
27
+ }
28
+ async fetchTasks() {
29
+ logger_1.logger.debug(`Fetching tasks with tag "${this.tag}" from team ${this.teamId}`);
30
+ const data = await this.request(`/team/${this.teamId}/task?tags[]=${encodeURIComponent(this.tag)}&subtasks=true&include_closed=false`);
31
+ return data.tasks.map((t) => ({
32
+ id: t.id,
33
+ name: t.name,
34
+ description: t.description || '',
35
+ status: t.status.status.toLowerCase(),
36
+ url: t.url,
37
+ tags: t.tags.map((tag) => tag.name),
38
+ }));
39
+ }
40
+ async postComment(taskId, text) {
41
+ logger_1.logger.debug(`Posting comment to task ${taskId}`);
42
+ await this.request(`/task/${taskId}/comment`, {
43
+ method: 'POST',
44
+ body: JSON.stringify({ comment_text: text }),
45
+ });
46
+ }
47
+ async getComments(taskId) {
48
+ logger_1.logger.debug(`Fetching comments for task ${taskId}`);
49
+ const data = await this.request(`/task/${taskId}/comment`);
50
+ return data.comments.map((c) => ({
51
+ id: c.id,
52
+ text: c.comment_text,
53
+ author: c.user.username,
54
+ authorId: String(c.user.id),
55
+ date: parseInt(c.date, 10),
56
+ }));
57
+ }
58
+ async updateStatus(taskId, status) {
59
+ logger_1.logger.debug(`Updating task ${taskId} status to "${status}"`);
60
+ await this.request(`/task/${taskId}`, {
61
+ method: 'PUT',
62
+ body: JSON.stringify({ status }),
63
+ });
64
+ }
65
+ }
66
+ exports.ClickUpProvider = ClickUpProvider;
67
+ //# sourceMappingURL=clickup.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/providers/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAClC,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AAGtC,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,YAAY,CAa3D;AAED,OAAO,EAAE,YAAY,EAAE,CAAC"}
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createProvider = createProvider;
4
+ const clickup_1 = require("./clickup");
5
+ function createProvider(config) {
6
+ switch (config.provider.toLowerCase()) {
7
+ case 'clickup':
8
+ return new clickup_1.ClickUpProvider(config);
9
+ case 'jira':
10
+ throw new Error('Jira provider is not yet implemented. Contributions welcome!');
11
+ case 'notion':
12
+ throw new Error('Notion provider is not yet implemented. Contributions welcome!');
13
+ case 'trello':
14
+ throw new Error('Trello provider is not yet implemented. Contributions welcome!');
15
+ default:
16
+ throw new Error(`Unknown provider: ${config.provider}`);
17
+ }
18
+ }
19
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,IAAI;IACnB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,EAAE,CAAC;CAChB;AAED,MAAM,WAAW,OAAO;IACtB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,MAAM,SAAS,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAE5C,MAAM,WAAW,MAAM;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC;IACtB,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,oBAAoB,EAAE,MAAM,CAAC;IAC7B,qBAAqB,EAAE,MAAM,CAAC;IAC9B,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,gBAAgB,EAAE,MAAM,CAAC;IACzB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,SAAS,EAAE,CAAC;IACpB,YAAY,EAAE,OAAO,GAAG,QAAQ,CAAC;CAClC"}