@qelos/aidev 0.7.3 → 0.7.4
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/.env.aidev.example +105 -105
- package/CONTRIBUTING.md +78 -78
- package/LICENSE +21 -21
- package/README.md +755 -755
- package/dist/cli.js +0 -0
- package/dist/commands/help.js +80 -80
- package/dist/commands/init.js +105 -105
- package/dist/commands/run.d.ts +6 -0
- package/dist/commands/run.d.ts.map +1 -1
- package/dist/commands/run.js +174 -151
- package/dist/commands/run.js.map +1 -1
- package/dist/github.js +27 -27
- package/dist/providers/linear.d.ts.map +1 -1
- package/dist/providers/linear.js +151 -116
- package/dist/providers/linear.js.map +1 -1
- package/dist/providers/monday.js +45 -45
- package/package.json +51 -51
- package/scripts/run-tests.cjs +18 -18
- package/.aidev/assets/86c8yjxrr/9ea11c36-311c-4022-889c-1bb0915122dc.jpg-40e6939e3b68e864260f7ae7e85bd623_exif.jpg +0 -0
- package/.aidev/assets/86c9n1mkf/65d079a2-dc39-4c4e-9ea9-964d37e0402c.jpg-a639447a10296e31cd4c85d521e9705e_exif.jpg +0 -0
- package/aidev.tasks.json +0 -1
- package/dist/autoCompress.d.ts +0 -54
- package/dist/autoCompress.d.ts.map +0 -1
- package/dist/autoCompress.js +0 -300
- package/dist/autoCompress.js.map +0 -1
package/scripts/run-tests.cjs
CHANGED
|
@@ -1,18 +1,18 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
const { spawnSync } = require('node:child_process');
|
|
4
|
-
const { globSync } = require('node:fs');
|
|
5
|
-
const path = require('node:path');
|
|
6
|
-
|
|
7
|
-
const root = path.join(__dirname, '..');
|
|
8
|
-
const files = globSync('src/__tests__/**/*.test.ts', { cwd: root }).sort();
|
|
9
|
-
if (files.length === 0) {
|
|
10
|
-
console.error('No test files found under src/__tests__');
|
|
11
|
-
process.exit(1);
|
|
12
|
-
}
|
|
13
|
-
const abs = files.map((f) => path.join(root, f));
|
|
14
|
-
const r = spawnSync(process.execPath, ['--require', 'tsx/cjs', '--test', ...abs], {
|
|
15
|
-
cwd: root,
|
|
16
|
-
stdio: 'inherit',
|
|
17
|
-
});
|
|
18
|
-
process.exit(r.status === null ? 1 : r.status);
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const { spawnSync } = require('node:child_process');
|
|
4
|
+
const { globSync } = require('node:fs');
|
|
5
|
+
const path = require('node:path');
|
|
6
|
+
|
|
7
|
+
const root = path.join(__dirname, '..');
|
|
8
|
+
const files = globSync('src/__tests__/**/*.test.ts', { cwd: root }).sort();
|
|
9
|
+
if (files.length === 0) {
|
|
10
|
+
console.error('No test files found under src/__tests__');
|
|
11
|
+
process.exit(1);
|
|
12
|
+
}
|
|
13
|
+
const abs = files.map((f) => path.join(root, f));
|
|
14
|
+
const r = spawnSync(process.execPath, ['--require', 'tsx/cjs', '--test', ...abs], {
|
|
15
|
+
cwd: root,
|
|
16
|
+
stdio: 'inherit',
|
|
17
|
+
});
|
|
18
|
+
process.exit(r.status === null ? 1 : r.status);
|
|
Binary file
|
|
Binary file
|
package/aidev.tasks.json
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
[]
|
package/dist/autoCompress.d.ts
DELETED
|
@@ -1,54 +0,0 @@
|
|
|
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
|
|
@@ -1 +0,0 @@
|
|
|
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"}
|
package/dist/autoCompress.js
DELETED
|
@@ -1,300 +0,0 @@
|
|
|
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
|
package/dist/autoCompress.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"autoCompress.js","sourceRoot":"","sources":["../src/autoCompress.ts"],"names":[],"mappings":"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"}
|