@qelos/aidev 0.5.2 → 0.5.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,54 @@
1
+ import { AIRunner } from './ai/base';
2
+ import { Comment, Config } from './types';
3
+ /** Matches how AIRunner implementations concatenate prompt and notes. */
4
+ export declare function fullPromptCharCount(prompt: string, notes?: string): number;
5
+ export declare function formatConversationBlock(comments: Comment[]): string;
6
+ /** Ticket conversation block plus optional PR review section (same order as run.ts). */
7
+ export declare function buildTaskContextSuffix(humanComments: Comment[], reviewSection: string): string;
8
+ /**
9
+ * Measures total prompt size the same way the runner does: `fullPromptCharCount` of the
10
+ * built prompt for a given task-context suffix (task fields live inside `buildPromptFromSuffix`).
11
+ */
12
+ export declare function measureImplementStylePrompt(buildPromptFromSuffix: (taskContextSuffix: string) => string, humanComments: Comment[], reviewSection: string, notes?: string): number;
13
+ /** Safe filename segment from a task id (allows only alphanumerics, `.`, `_`, `-`). */
14
+ export declare function sanitizeTaskIdForFile(taskId: string): string;
15
+ export declare function getCompressionSessionPath(taskId: string, cwd?: string): string;
16
+ export declare function getSessionsDir(cwd?: string): string;
17
+ /** Stored under `.aidev/sessions/<sanitizedTaskId>.json`. */
18
+ export interface CompressionSessionRecord {
19
+ taskId: string;
20
+ updatedAt: string;
21
+ /** Human comments that were summarized (all but the last in thread order). */
22
+ earlierCommentIds: string[];
23
+ /** Fingerprint of those comments’ content for idempotent reuse. */
24
+ earlierContentHash: string;
25
+ /** Summary text only (no “latest comment” banner). */
26
+ compressedText: string;
27
+ summaryChars: number;
28
+ }
29
+ export declare function hashEarlierCommentsForCompression(older: Comment[]): string;
30
+ export declare function splitHumanCommentsForCompression(comments: Comment[]): {
31
+ older: Comment[];
32
+ last: Comment;
33
+ } | null;
34
+ export declare function getAutoCompressTripwireLimit(config: Config): number;
35
+ export declare function exceedsAutoCompressBudget(measuredLen: number, config: Config): boolean;
36
+ export declare function readCompressionSession(taskId: string, cwd?: string): CompressionSessionRecord | null;
37
+ export declare function writeCompressionSessionRecord(taskId: string, record: Omit<CompressionSessionRecord, 'taskId'> & {
38
+ taskId?: string;
39
+ }, cwd?: string): string;
40
+ /**
41
+ * Loss-aware extractive compression when AI summarization is unavailable.
42
+ * Preserves lines that look like paths, URLs, errors, or explicit bullets; truncates the rest.
43
+ */
44
+ export declare function compressEarlierThreadDeterministic(older: Comment[]): string;
45
+ /**
46
+ * When the measured total prompt (see `measureWithComments`) exceeds the configured
47
+ * fraction of AUTO_COMPRESS_MAX_CHARS, replaces all but the last human comment
48
+ * with a single compressed summary comment. The summary is written under
49
+ * `.aidev/sessions/<sanitizedTaskId>.json`.
50
+ */
51
+ export declare function maybeCompressHumanComments(taskId: string, config: Config, humanComments: Comment[], runners: AIRunner[], measureWithComments: (comments: Comment[]) => number, options?: {
52
+ cwd?: string;
53
+ }): Promise<Comment[]>;
54
+ //# sourceMappingURL=autoCompress.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"autoCompress.d.ts","sourceRoot":"","sources":["../src/autoCompress.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAErC,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAI1C,yEAAyE;AACzE,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAK1E;AAED,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,OAAO,EAAE,GAAG,MAAM,CAGnE;AAED,wFAAwF;AACxF,wBAAgB,sBAAsB,CAAC,aAAa,EAAE,OAAO,EAAE,EAAE,aAAa,EAAE,MAAM,GAAG,MAAM,CAE9F;AAED;;;GAGG;AACH,wBAAgB,2BAA2B,CACzC,qBAAqB,EAAE,CAAC,iBAAiB,EAAE,MAAM,KAAK,MAAM,EAC5D,aAAa,EAAE,OAAO,EAAE,EACxB,aAAa,EAAE,MAAM,EACrB,KAAK,CAAC,EAAE,MAAM,GACb,MAAM,CAGR;AAED,uFAAuF;AACvF,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAG5D;AAED,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,GAAE,MAAsB,GAAG,MAAM,CAG7F;AAED,wBAAgB,cAAc,CAAC,GAAG,GAAE,MAAsB,GAAG,MAAM,CAElE;AAED,6DAA6D;AAC7D,MAAM,WAAW,wBAAwB;IACvC,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,8EAA8E;IAC9E,iBAAiB,EAAE,MAAM,EAAE,CAAC;IAC5B,mEAAmE;IACnE,kBAAkB,EAAE,MAAM,CAAC;IAC3B,sDAAsD;IACtD,cAAc,EAAE,MAAM,CAAC;IACvB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,wBAAgB,iCAAiC,CAAC,KAAK,EAAE,OAAO,EAAE,GAAG,MAAM,CAK1E;AAED,wBAAgB,gCAAgC,CAC9C,QAAQ,EAAE,OAAO,EAAE,GAClB;IAAE,KAAK,EAAE,OAAO,EAAE,CAAC;IAAC,IAAI,EAAE,OAAO,CAAA;CAAE,GAAG,IAAI,CAM5C;AAED,wBAAgB,4BAA4B,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAEnE;AAED,wBAAgB,yBAAyB,CAAC,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAGtF;AAED,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,GAAE,MAAsB,GAAG,wBAAwB,GAAG,IAAI,CAoBnH;AAED,wBAAgB,6BAA6B,CAC3C,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,IAAI,CAAC,wBAAwB,EAAE,QAAQ,CAAC,GAAG;IAAE,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,EACtE,GAAG,GAAE,MAAsB,GAC1B,MAAM,CAcR;AAMD;;;GAGG;AACH,wBAAgB,kCAAkC,CAAC,KAAK,EAAE,OAAO,EAAE,GAAG,MAAM,CAwC3E;AAmDD;;;;;GAKG;AACH,wBAAsB,0BAA0B,CAC9C,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,aAAa,EAAE,OAAO,EAAE,EACxB,OAAO,EAAE,QAAQ,EAAE,EACnB,mBAAmB,EAAE,CAAC,QAAQ,EAAE,OAAO,EAAE,KAAK,MAAM,EACpD,OAAO,CAAC,EAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,GACzB,OAAO,CAAC,OAAO,EAAE,CAAC,CAwEpB"}
@@ -0,0 +1,300 @@
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.fullPromptCharCount = fullPromptCharCount;
37
+ exports.formatConversationBlock = formatConversationBlock;
38
+ exports.buildTaskContextSuffix = buildTaskContextSuffix;
39
+ exports.measureImplementStylePrompt = measureImplementStylePrompt;
40
+ exports.sanitizeTaskIdForFile = sanitizeTaskIdForFile;
41
+ exports.getCompressionSessionPath = getCompressionSessionPath;
42
+ exports.getSessionsDir = getSessionsDir;
43
+ exports.hashEarlierCommentsForCompression = hashEarlierCommentsForCompression;
44
+ exports.splitHumanCommentsForCompression = splitHumanCommentsForCompression;
45
+ exports.getAutoCompressTripwireLimit = getAutoCompressTripwireLimit;
46
+ exports.exceedsAutoCompressBudget = exceedsAutoCompressBudget;
47
+ exports.readCompressionSession = readCompressionSession;
48
+ exports.writeCompressionSessionRecord = writeCompressionSessionRecord;
49
+ exports.compressEarlierThreadDeterministic = compressEarlierThreadDeterministic;
50
+ exports.maybeCompressHumanComments = maybeCompressHumanComments;
51
+ const crypto = __importStar(require("node:crypto"));
52
+ const fs = __importStar(require("node:fs"));
53
+ const path = __importStar(require("node:path"));
54
+ const logger_1 = require("./logger");
55
+ const ADDITIONAL_CTX = '\n\nAdditional context:\n';
56
+ /** Matches how AIRunner implementations concatenate prompt and notes. */
57
+ function fullPromptCharCount(prompt, notes) {
58
+ if (notes && notes.length > 0) {
59
+ return prompt.length + ADDITIONAL_CTX.length + notes.length;
60
+ }
61
+ return prompt.length;
62
+ }
63
+ function formatConversationBlock(comments) {
64
+ if (comments.length === 0)
65
+ return '';
66
+ return '\n\nConversation context:\n' + comments.map((c) => `${c.author}: ${c.text}`).join('\n');
67
+ }
68
+ /** Ticket conversation block plus optional PR review section (same order as run.ts). */
69
+ function buildTaskContextSuffix(humanComments, reviewSection) {
70
+ return formatConversationBlock(humanComments) + reviewSection;
71
+ }
72
+ /**
73
+ * Measures total prompt size the same way the runner does: `fullPromptCharCount` of the
74
+ * built prompt for a given task-context suffix (task fields live inside `buildPromptFromSuffix`).
75
+ */
76
+ function measureImplementStylePrompt(buildPromptFromSuffix, humanComments, reviewSection, notes) {
77
+ const suffix = buildTaskContextSuffix(humanComments, reviewSection);
78
+ return fullPromptCharCount(buildPromptFromSuffix(suffix), notes);
79
+ }
80
+ /** Safe filename segment from a task id (allows only alphanumerics, `.`, `_`, `-`). */
81
+ function sanitizeTaskIdForFile(taskId) {
82
+ const s = taskId.replace(/[^a-zA-Z0-9._-]+/g, '_');
83
+ return s.length > 0 ? s : '_';
84
+ }
85
+ function getCompressionSessionPath(taskId, cwd = process.cwd()) {
86
+ const base = sanitizeTaskIdForFile(taskId);
87
+ return path.join(cwd, '.aidev', 'sessions', `${base}.json`);
88
+ }
89
+ function getSessionsDir(cwd = process.cwd()) {
90
+ return path.join(cwd, '.aidev', 'sessions');
91
+ }
92
+ function hashEarlierCommentsForCompression(older) {
93
+ const payload = older
94
+ .map((c) => `${c.id}\t${c.date}\t${c.author}\t${c.text}`)
95
+ .join('\n');
96
+ return crypto.createHash('sha256').update(payload, 'utf8').digest('hex');
97
+ }
98
+ function splitHumanCommentsForCompression(comments) {
99
+ if (comments.length < 2)
100
+ return null;
101
+ return {
102
+ older: comments.slice(0, -1),
103
+ last: comments[comments.length - 1],
104
+ };
105
+ }
106
+ function getAutoCompressTripwireLimit(config) {
107
+ return Math.floor(config.autoCompressMaxChars * config.autoCompressThreshold);
108
+ }
109
+ function exceedsAutoCompressBudget(measuredLen, config) {
110
+ if (!config.autoCompress)
111
+ return false;
112
+ return measuredLen > getAutoCompressTripwireLimit(config);
113
+ }
114
+ function readCompressionSession(taskId, cwd = process.cwd()) {
115
+ const file = getCompressionSessionPath(taskId, cwd);
116
+ if (!fs.existsSync(file))
117
+ return null;
118
+ try {
119
+ const raw = fs.readFileSync(file, 'utf8');
120
+ const parsed = JSON.parse(raw);
121
+ if (typeof parsed.taskId === 'string' &&
122
+ typeof parsed.updatedAt === 'string' &&
123
+ Array.isArray(parsed.earlierCommentIds) &&
124
+ typeof parsed.earlierContentHash === 'string' &&
125
+ typeof parsed.compressedText === 'string' &&
126
+ typeof parsed.summaryChars === 'number') {
127
+ return parsed;
128
+ }
129
+ }
130
+ catch {
131
+ // ignore corrupt session
132
+ }
133
+ return null;
134
+ }
135
+ function writeCompressionSessionRecord(taskId, record, cwd = process.cwd()) {
136
+ const dir = getSessionsDir(cwd);
137
+ fs.mkdirSync(dir, { recursive: true });
138
+ const fullPath = getCompressionSessionPath(taskId, cwd);
139
+ const body = {
140
+ taskId,
141
+ updatedAt: record.updatedAt,
142
+ earlierCommentIds: record.earlierCommentIds,
143
+ earlierContentHash: record.earlierContentHash,
144
+ compressedText: record.compressedText,
145
+ summaryChars: record.summaryChars,
146
+ };
147
+ fs.writeFileSync(fullPath, JSON.stringify(body, null, 2), 'utf8');
148
+ return fullPath;
149
+ }
150
+ const PATH_LIKE = /(?:^|[\s"'(])(\/[^\s'"]+\.[a-zA-Z0-9]{1,8}\b|[A-Za-z]:\\[^\n]+|(?:\.{1,2}\/|\/)?(?:src|lib|test|tests|dist|node_modules)\/[^\s`]+)/;
151
+ const URL_LIKE = /https?:\/\/[^\s)]+/g;
152
+ /**
153
+ * Loss-aware extractive compression when AI summarization is unavailable.
154
+ * Preserves lines that look like paths, URLs, errors, or explicit bullets; truncates the rest.
155
+ */
156
+ function compressEarlierThreadDeterministic(older) {
157
+ const kept = [];
158
+ const seen = new Set();
159
+ function pushLine(prefix, line) {
160
+ const t = line.trim();
161
+ if (!t)
162
+ return;
163
+ const key = `${prefix}:${t}`;
164
+ if (seen.has(key))
165
+ return;
166
+ seen.add(key);
167
+ kept.push(`${prefix}${t}`);
168
+ }
169
+ for (const c of older) {
170
+ const authorTag = `[${c.author}] `;
171
+ const lines = c.text.split(/\r?\n/);
172
+ for (const line of lines) {
173
+ const t = line.trim();
174
+ if (!t)
175
+ continue;
176
+ if (PATH_LIKE.test(t) || /error|exception|traceback|fatal|warning/i.test(t)) {
177
+ pushLine(`- ${authorTag}`, t);
178
+ }
179
+ let m;
180
+ const re = new RegExp(URL_LIKE.source, URL_LIKE.flags);
181
+ while ((m = re.exec(t)) !== null) {
182
+ pushLine(`- ${authorTag}`, m[0]);
183
+ }
184
+ if (/^[-*]\s+/.test(t) || /^(do|don't|must|should|need to)\b/i.test(t)) {
185
+ pushLine(`- ${authorTag}`, t);
186
+ }
187
+ }
188
+ const para = c.text.replace(/\s+/g, ' ').trim();
189
+ const snippet = para.length > 400 ? `${para.slice(0, 400)}…` : para;
190
+ pushLine(`- ${authorTag}`, snippet);
191
+ }
192
+ const body = kept.join('\n');
193
+ const max = 14000;
194
+ if (body.length <= max)
195
+ return body;
196
+ return `${body.slice(0, max)}\n\n… [truncated after ${max} characters]`;
197
+ }
198
+ async function summarizeEarlierCommentsWithAI(older, runners, latestAuthor) {
199
+ const body = older.map((c) => `### ${c.author}\n${c.text}`).join('\n\n---\n\n');
200
+ const prompt = `You are helping compress task ticket comments for an automated coding agent.
201
+
202
+ The following messages are OLDER comments on a task. The LATEST comment from "${latestAuthor}" will be appended separately in full — do not restate it.
203
+
204
+ Produce a dense summary the agent can use to implement follow-up work. Preserve exactly:
205
+ - requirements, constraints, accepted decisions
206
+ - file paths, identifiers, URLs, code snippets, error messages
207
+ - anything that would change what code to write
208
+
209
+ Use bullet lists where helpful. Omit greetings and meta chatter. Be as concise as possible without losing technical facts.
210
+
211
+ --- Older comments ---
212
+ ${body}
213
+ --- End ---
214
+
215
+ Respond with the summary only — no title line, no markdown fence.`;
216
+ for (const runner of runners) {
217
+ if (!runner.isAvailable())
218
+ continue;
219
+ logger_1.logger.info(`Auto-compress: summarizing ${older.length} earlier comment(s) with ${runner.name}...`);
220
+ const result = await runner.run(prompt);
221
+ if (result.success && result.output.trim()) {
222
+ return result.output.trim();
223
+ }
224
+ logger_1.logger.warn(`Auto-compress: ${runner.name} failed to summarize earlier comments`);
225
+ }
226
+ return null;
227
+ }
228
+ const LATEST_BANNER = '\n\n---\nBelow is the latest comment on this task (shown in full, not compressed):';
229
+ function buildCompressedSummaryComment(taskId, summaryCore) {
230
+ return {
231
+ id: `aidev-compressed-${sanitizeTaskIdForFile(taskId)}`,
232
+ author: 'aidev (earlier comments — compressed)',
233
+ text: `${summaryCore}${LATEST_BANNER}`,
234
+ authorId: 'aidev',
235
+ date: Date.now(),
236
+ };
237
+ }
238
+ /**
239
+ * When the measured total prompt (see `measureWithComments`) exceeds the configured
240
+ * fraction of AUTO_COMPRESS_MAX_CHARS, replaces all but the last human comment
241
+ * with a single compressed summary comment. The summary is written under
242
+ * `.aidev/sessions/<sanitizedTaskId>.json`.
243
+ */
244
+ async function maybeCompressHumanComments(taskId, config, humanComments, runners, measureWithComments, options) {
245
+ const cwd = options?.cwd ?? process.cwd();
246
+ if (!config.autoCompress) {
247
+ return humanComments;
248
+ }
249
+ const split = splitHumanCommentsForCompression(humanComments);
250
+ if (!split) {
251
+ return humanComments;
252
+ }
253
+ const { older, last: latest } = split;
254
+ const rawLen = measureWithComments(humanComments);
255
+ if (!exceedsAutoCompressBudget(rawLen, config)) {
256
+ return humanComments;
257
+ }
258
+ const contentHash = hashEarlierCommentsForCompression(older);
259
+ const earlierIds = older.map((c) => c.id);
260
+ const cached = readCompressionSession(taskId, cwd);
261
+ if (cached &&
262
+ cached.earlierContentHash === contentHash &&
263
+ cached.earlierCommentIds.length === earlierIds.length &&
264
+ cached.earlierCommentIds.every((id, i) => id === earlierIds[i])) {
265
+ const summaryComment = buildCompressedSummaryComment(taskId, cached.compressedText);
266
+ const fromCache = [summaryComment, latest];
267
+ const cacheLen = measureWithComments(fromCache);
268
+ if (cacheLen < rawLen) {
269
+ logger_1.logger.info('Auto-compress: reusing stored summary for identical earlier comments');
270
+ return fromCache;
271
+ }
272
+ }
273
+ let summaryCore = await summarizeEarlierCommentsWithAI(older, runners, latest.author);
274
+ if (!summaryCore) {
275
+ logger_1.logger.warn('Auto-compress: AI summarization failed — using deterministic compression');
276
+ summaryCore = compressEarlierThreadDeterministic(older);
277
+ }
278
+ const summaryComment = buildCompressedSummaryComment(taskId, summaryCore);
279
+ const compressed = [summaryComment, latest];
280
+ const newLen = measureWithComments(compressed);
281
+ if (newLen >= rawLen) {
282
+ logger_1.logger.warn('Auto-compress: compressed text was not shorter than originals — keeping full conversation');
283
+ return humanComments;
284
+ }
285
+ writeCompressionSessionRecord(taskId, {
286
+ updatedAt: new Date().toISOString(),
287
+ earlierCommentIds: earlierIds,
288
+ earlierContentHash: contentHash,
289
+ compressedText: summaryCore,
290
+ summaryChars: summaryCore.length,
291
+ }, cwd);
292
+ if (newLen > config.autoCompressMaxChars) {
293
+ logger_1.logger.warn(`Auto-compress: prompt still large (${newLen} chars) after compression — consider raising AUTO_COMPRESS_MAX_CHARS`);
294
+ }
295
+ else {
296
+ logger_1.logger.info(`Auto-compress: reduced measured prompt from ~${rawLen} to ~${newLen} chars (earlier comments summarized)`);
297
+ }
298
+ return compressed;
299
+ }
300
+ //# sourceMappingURL=autoCompress.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"autoCompress.js","sourceRoot":"","sources":["../src/autoCompress.ts"],"names":[],"mappings":"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"}
package/dist/cli.js CHANGED
File without changes
@@ -46,86 +46,86 @@ function windowsCursorAgentLine(opts) {
46
46
  ` ${y('!')} Cursor runner needs the Agent CLI. Install: ${c("irm 'https://cursor.com/install?win32=true' | iex")}\n`;
47
47
  }
48
48
  function helpCommand() {
49
- console.log(`
50
- ${b('aidev')} ${d('v0.1.0')} — AI-powered task executor
51
-
52
- ${b('USAGE')}
53
- ${c('aidev')} ${d('[command]')}
54
-
55
- ${b('COMMANDS')}
56
- ${c('init')} Interactive setup — create ${d('.env.aidev')}
57
- ${c('run')} Process all open + pending-with-replies tasks
58
- ${c('run open')} Only open (non-pending) tasks
59
- ${c('run pending')} Only pending tasks — check for human replies
60
- ${c('run tasks')} Publish queued ${d('aidev.tasks.json')} entries and exit
61
- ${c('tasks add')} Queue a new task in ${d('aidev.tasks.json')} (interactive)
62
- ${c('tasks ls')} List queued tasks
63
- ${c('tasks update')} ${d('[id]')} Edit a queued task
64
- ${c('tasks remove')} ${d('[id]')} Delete a queued task
65
- ${c('tasks push')} Publish all queued tasks now (same as ${c('run tasks')})
66
- ${c('schedule set')} ${d('<cron>')} Set cron schedule for this directory
67
- ${c('schedule get')} Show current cron schedule
68
- ${c('help')} Show this help message
69
-
70
- ${b('TRIGGER WORD')}
71
- When a task is skipped (branch exists or pending with no reply), post a comment
72
- containing the trigger word ${d('(default: aidev-continue)')} to re-trigger processing.
73
- The existing branch will be reused. Set ${c('AIDEV_TRIGGER_WORD')} to customise.
74
-
75
- ${b('HOOKS')}
76
- Set ${c('AIDEV_HOOKS_PATH')} to a ${d('.ts')} or ${d('.js')} file to run optional async hooks
77
- ${d('(beforeRun, beforeEachTask, beforeResolveConflicts, …)')}. ${c('aidev init')} creates
78
- ${d('.aidev/aidev.hooks.ts')} and points this variable at it. Throw from a hook to abort that step.
79
-
80
- ${b('LOCAL PROVIDER')}
81
- Set ${c('PROVIDER=local')} in ${d('.env.aidev')} to use file-based task management.
82
- Tasks live in ${d('.aidev/tasks/')} under status folders: ${c('open')}, ${c('pending')},
83
- ${c('progress')}, ${c('review')}, ${c('done')}.
84
-
85
- Each task is a markdown file with YAML frontmatter (title, priority, tags, etc.)
86
- and a description body. Comments are stored in a ${d('.session.md')} companion file.
87
- To add a comment, append a ${d('## your-name')} section to the session file.
88
- Add ${c('type: non-code')} to frontmatter for tasks that skip git branching.
89
- Run ${c('aidev init')} with provider ${c('local')} to create the folder structure.
90
-
91
- ${b('LOCAL TASKS FILE')}
92
- ${d('aidev.tasks.json')} queues tasks to publish to your remote provider. Each entry
93
- has a title, description, type (${c('code')} | ${c('non-code')}), optional priority, tags, and cron.
94
- Every ${c('aidev run')} publishes pending entries; one-shot entries are removed after
95
- publishing, cron entries stay and re-publish on schedule. Manage with ${c('aidev tasks')}
96
- ${d('(add / ls / update / remove / push)')} or edit the JSON file directly.
97
-
98
- ${b('NON-CODE TASKS')}
99
- Tasks tagged with the ${c('NON_CODE_TAG')} are executed without git branching —
100
- no checkout, commit, push, or PR creation. The AI agent runs the task directly
101
- in the current working directory. Useful for research, documentation, or tasks
102
- that don't produce code changes requiring review.
103
- Optionally use a different ClickUp team (${c('NON_CODE_CLICKUP_TEAM_ID')}) or
104
- Jira project (${c('NON_CODE_JIRA_PROJECT')}) for non-code tasks.
105
- If ${c('NON_CODE_TAG')} is not set, it defaults to ${d('<folder-name>-other')}.
106
-
107
- ${b('EXAMPLES')}
108
- ${d('$')} ${g('aidev init')}
109
- ${d('$')} ${g('aidev run')}
110
- ${d('$')} ${g('aidev run open')}
111
- ${d('$')} ${g('aidev schedule set "*/30 * * * *"')}
112
- ${d('$')} ${g('aidev schedule get')}
113
-
114
- ${b('CONFIG')} ${d('.env.aidev in your project directory')}
115
- ${d('PROVIDER')} ${c('clickup')} ${d('(default) | jira | linear | local | monday | notion | trello')}
116
- ${d('CLICKUP_API_KEY')} ClickUp personal API token
117
- ${d('CLICKUP_TEAM_ID')} Workspace / team ID
118
- ${d('CLICKUP_TAG')} Tag used to filter tasks ${d('(default: folder name)')}
119
- ${d('AGENTS')} Agent order: ${c('claude,cursor')} ${d('| antigravity | cursor | windsurf | …')}
120
- ${d('DEV_NOTES_MODE')} ${c('smart')} ${d('(default) | always')}
121
- ${d('AIDEV_TRIGGER_WORD')} Trigger word to re-process a skipped task ${d('(default: aidev-continue)')}
122
- ${d('AIDEV_HOOKS_PATH')} Optional hooks module ${d('(default from init: .aidev/aidev.hooks.ts)')}
123
- ${d('NON_CODE_TAG')} Tag for non-code tasks ${d('(default: <folder-name>-other)')}
124
- ${d('GIT_REMOTE')} Remote name ${d('(auto-detected if unset)')}
125
- ${d('GITHUB_BASE_BRANCH')} Base branch ${d('(default: main)')}
126
- ${d('GITHUB_REPO')} ${d('owner/repo')} for PR links
127
- ${ghStatusLine()}${windowsCursorAgentLine()}
128
- Run ${c('aidev init')} to configure interactively.
49
+ console.log(`
50
+ ${b('aidev')} ${d('v0.1.0')} — AI-powered task executor
51
+
52
+ ${b('USAGE')}
53
+ ${c('aidev')} ${d('[command]')}
54
+
55
+ ${b('COMMANDS')}
56
+ ${c('init')} Interactive setup — create ${d('.env.aidev')}
57
+ ${c('run')} Process all open + pending-with-replies tasks
58
+ ${c('run open')} Only open (non-pending) tasks
59
+ ${c('run pending')} Only pending tasks — check for human replies
60
+ ${c('run tasks')} Publish queued ${d('aidev.tasks.json')} entries and exit
61
+ ${c('tasks add')} Queue a new task in ${d('aidev.tasks.json')} (interactive)
62
+ ${c('tasks ls')} List queued tasks
63
+ ${c('tasks update')} ${d('[id]')} Edit a queued task
64
+ ${c('tasks remove')} ${d('[id]')} Delete a queued task
65
+ ${c('tasks push')} Publish all queued tasks now (same as ${c('run tasks')})
66
+ ${c('schedule set')} ${d('<cron>')} Set cron schedule for this directory
67
+ ${c('schedule get')} Show current cron schedule
68
+ ${c('help')} Show this help message
69
+
70
+ ${b('TRIGGER WORD')}
71
+ When a task is skipped (branch exists or pending with no reply), post a comment
72
+ containing the trigger word ${d('(default: aidev-continue)')} to re-trigger processing.
73
+ The existing branch will be reused. Set ${c('AIDEV_TRIGGER_WORD')} to customise.
74
+
75
+ ${b('HOOKS')}
76
+ Set ${c('AIDEV_HOOKS_PATH')} to a ${d('.ts')} or ${d('.js')} file to run optional async hooks
77
+ ${d('(beforeRun, beforeEachTask, beforeResolveConflicts, …)')}. ${c('aidev init')} creates
78
+ ${d('.aidev/aidev.hooks.ts')} and points this variable at it. Throw from a hook to abort that step.
79
+
80
+ ${b('LOCAL PROVIDER')}
81
+ Set ${c('PROVIDER=local')} in ${d('.env.aidev')} to use file-based task management.
82
+ Tasks live in ${d('.aidev/tasks/')} under status folders: ${c('open')}, ${c('pending')},
83
+ ${c('progress')}, ${c('review')}, ${c('done')}.
84
+
85
+ Each task is a markdown file with YAML frontmatter (title, priority, tags, etc.)
86
+ and a description body. Comments are stored in a ${d('.session.md')} companion file.
87
+ To add a comment, append a ${d('## your-name')} section to the session file.
88
+ Add ${c('type: non-code')} to frontmatter for tasks that skip git branching.
89
+ Run ${c('aidev init')} with provider ${c('local')} to create the folder structure.
90
+
91
+ ${b('LOCAL TASKS FILE')}
92
+ ${d('aidev.tasks.json')} queues tasks to publish to your remote provider. Each entry
93
+ has a title, description, type (${c('code')} | ${c('non-code')}), optional priority, tags, and cron.
94
+ Every ${c('aidev run')} publishes pending entries; one-shot entries are removed after
95
+ publishing, cron entries stay and re-publish on schedule. Manage with ${c('aidev tasks')}
96
+ ${d('(add / ls / update / remove / push)')} or edit the JSON file directly.
97
+
98
+ ${b('NON-CODE TASKS')}
99
+ Tasks tagged with the ${c('NON_CODE_TAG')} are executed without git branching —
100
+ no checkout, commit, push, or PR creation. The AI agent runs the task directly
101
+ in the current working directory. Useful for research, documentation, or tasks
102
+ that don't produce code changes requiring review.
103
+ Optionally use a different ClickUp team (${c('NON_CODE_CLICKUP_TEAM_ID')}) or
104
+ Jira project (${c('NON_CODE_JIRA_PROJECT')}) for non-code tasks.
105
+ If ${c('NON_CODE_TAG')} is not set, it defaults to ${d('<folder-name>-other')}.
106
+
107
+ ${b('EXAMPLES')}
108
+ ${d('$')} ${g('aidev init')}
109
+ ${d('$')} ${g('aidev run')}
110
+ ${d('$')} ${g('aidev run open')}
111
+ ${d('$')} ${g('aidev schedule set "*/30 * * * *"')}
112
+ ${d('$')} ${g('aidev schedule get')}
113
+
114
+ ${b('CONFIG')} ${d('.env.aidev in your project directory')}
115
+ ${d('PROVIDER')} ${c('clickup')} ${d('(default) | jira | linear | local | monday | notion | trello')}
116
+ ${d('CLICKUP_API_KEY')} ClickUp personal API token
117
+ ${d('CLICKUP_TEAM_ID')} Workspace / team ID
118
+ ${d('CLICKUP_TAG')} Tag used to filter tasks ${d('(default: folder name)')}
119
+ ${d('AGENTS')} Agent order: ${c('claude,cursor')} ${d('| antigravity | cursor | windsurf | …')}
120
+ ${d('DEV_NOTES_MODE')} ${c('smart')} ${d('(default) | always')}
121
+ ${d('AIDEV_TRIGGER_WORD')} Trigger word to re-process a skipped task ${d('(default: aidev-continue)')}
122
+ ${d('AIDEV_HOOKS_PATH')} Optional hooks module ${d('(default from init: .aidev/aidev.hooks.ts)')}
123
+ ${d('NON_CODE_TAG')} Tag for non-code tasks ${d('(default: <folder-name>-other)')}
124
+ ${d('GIT_REMOTE')} Remote name ${d('(auto-detected if unset)')}
125
+ ${d('GITHUB_BASE_BRANCH')} Base branch ${d('(default: main)')}
126
+ ${d('GITHUB_REPO')} ${d('owner/repo')} for PR links
127
+ ${ghStatusLine()}${windowsCursorAgentLine()}
128
+ Run ${c('aidev init')} to configure interactively.
129
129
  `);
130
130
  }
131
131
  //# sourceMappingURL=help.js.map