acdev 1.0.16 → 1.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/package.json +1 -1
- package/public/app.js +10 -0
- package/public/index.html +16 -0
- package/src/agent.js +12 -0
- package/src/server.js +16 -0
- package/src/store.js +11 -8
package/package.json
CHANGED
package/public/app.js
CHANGED
|
@@ -240,6 +240,7 @@ const els = {
|
|
|
240
240
|
overviewTicketSource: document.getElementById('overview-ticket-source'),
|
|
241
241
|
enqueueFeedback: document.getElementById('enqueue-feedback'),
|
|
242
242
|
preferredBranch: document.getElementById('preferred-branch'),
|
|
243
|
+
enqueueUserPrompt: document.getElementById('enqueue-user-prompt'),
|
|
243
244
|
addBtn: document.getElementById('add-btn'),
|
|
244
245
|
statsGrid: document.getElementById('stats-grid'),
|
|
245
246
|
overviewRunning: document.getElementById('overview-running'),
|
|
@@ -301,6 +302,8 @@ const els = {
|
|
|
301
302
|
settingsModelValue: document.getElementById('settings-model-value'),
|
|
302
303
|
settingsModelPanel: document.getElementById('settings-model-panel'),
|
|
303
304
|
settingsModelList: document.getElementById('settings-model-list'),
|
|
305
|
+
settingsModelSearch: document.getElementById('settings-model-search'),
|
|
306
|
+
settingsModelHint: document.getElementById('settings-model-hint'),
|
|
304
307
|
reviewPrLink: document.getElementById('review-pr-link'),
|
|
305
308
|
reviewPrStatusLine: document.getElementById('review-pr-status-line'),
|
|
306
309
|
reviewPrStatusNotes: document.getElementById('review-pr-status-notes'),
|
|
@@ -308,6 +311,10 @@ const els = {
|
|
|
308
311
|
reviewTerminalMessage: document.getElementById('review-terminal-message'),
|
|
309
312
|
reviewRetryBtn: document.getElementById('review-retry-btn'),
|
|
310
313
|
settingsTools: document.getElementById('settings-tools'),
|
|
314
|
+
settingsMaxTurns: document.getElementById('settings-max-turns'),
|
|
315
|
+
settingsTimeout: document.getElementById('settings-timeout'),
|
|
316
|
+
settingsTimeoutMs: document.getElementById('settings-timeout-ms'),
|
|
317
|
+
settingsTestCommand: document.getElementById('settings-test-command'),
|
|
311
318
|
settingsFeedback: document.getElementById('settings-feedback'),
|
|
312
319
|
settingsSaveBtn: document.getElementById('settings-save-btn'),
|
|
313
320
|
settingsTicketSource: document.getElementById('settings-ticket-source'),
|
|
@@ -5143,6 +5150,7 @@ els.addBtn.addEventListener('click', async () => {
|
|
|
5143
5150
|
|
|
5144
5151
|
const urls = splitIssueUrls(text);
|
|
5145
5152
|
const branchName = els.preferredBranch?.value?.trim() || '';
|
|
5153
|
+
const userPrompt = els.enqueueUserPrompt?.value?.trim() || '';
|
|
5146
5154
|
|
|
5147
5155
|
try {
|
|
5148
5156
|
const res = await fetch('/api/issues', {
|
|
@@ -5152,6 +5160,7 @@ els.addBtn.addEventListener('click', async () => {
|
|
|
5152
5160
|
urls,
|
|
5153
5161
|
ticketSource,
|
|
5154
5162
|
...(branchName ? { branchName } : {}),
|
|
5163
|
+
...(userPrompt ? { userPrompt } : {}),
|
|
5155
5164
|
}),
|
|
5156
5165
|
});
|
|
5157
5166
|
const data = await res.json();
|
|
@@ -5164,6 +5173,7 @@ els.addBtn.addEventListener('click', async () => {
|
|
|
5164
5173
|
}
|
|
5165
5174
|
els.issueUrls.value = '';
|
|
5166
5175
|
if (els.preferredBranch) els.preferredBranch.value = '';
|
|
5176
|
+
if (els.enqueueUserPrompt) els.enqueueUserPrompt.value = '';
|
|
5167
5177
|
const parts = [];
|
|
5168
5178
|
if (data.jobs?.length) parts.push(`Added ${data.jobs.length}`);
|
|
5169
5179
|
if (data.skipped?.length) {
|
package/public/index.html
CHANGED
|
@@ -156,6 +156,22 @@
|
|
|
156
156
|
</p>
|
|
157
157
|
</div>
|
|
158
158
|
|
|
159
|
+
<div class="enqueue-branch-field">
|
|
160
|
+
<div class="enqueue-branch-label-row">
|
|
161
|
+
<label class="field-label" for="enqueue-user-prompt">Additional instructions</label>
|
|
162
|
+
<span class="enqueue-branch-optional">Optional</span>
|
|
163
|
+
</div>
|
|
164
|
+
<textarea
|
|
165
|
+
id="enqueue-user-prompt"
|
|
166
|
+
class="input textarea enqueue-textarea"
|
|
167
|
+
rows="3"
|
|
168
|
+
placeholder="Anything specific you want the agent to know or do…"
|
|
169
|
+
></textarea>
|
|
170
|
+
<p class="enqueue-input-hint">
|
|
171
|
+
Appended to the agent's instructions for these tickets. Leave empty to use the issue content only.
|
|
172
|
+
</p>
|
|
173
|
+
</div>
|
|
174
|
+
|
|
159
175
|
<div class="enqueue-info-banner" id="enqueue-info-banner" role="note">
|
|
160
176
|
<svg class="enqueue-info-icon" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
|
|
161
177
|
<circle cx="12" cy="12" r="10"/>
|
package/src/agent.js
CHANGED
|
@@ -89,6 +89,7 @@ export function stripAiAttribution(text) {
|
|
|
89
89
|
* comments?: Array<{ author: string, body: string }>,
|
|
90
90
|
* },
|
|
91
91
|
* jiraPrLinkPhrase?: string,
|
|
92
|
+
* userPrompt?: string,
|
|
92
93
|
* }} [context]
|
|
93
94
|
*/
|
|
94
95
|
export function buildPrompt(issueUrl, config, context = {}) {
|
|
@@ -163,6 +164,14 @@ export function buildPrompt(issueUrl, config, context = {}) {
|
|
|
163
164
|
);
|
|
164
165
|
}
|
|
165
166
|
|
|
167
|
+
if (context.userPrompt && context.userPrompt.trim()) {
|
|
168
|
+
parts.push(
|
|
169
|
+
'',
|
|
170
|
+
'Additional instructions from the user (optional — follow them unless they conflict with the rules above):',
|
|
171
|
+
context.userPrompt.trim()
|
|
172
|
+
);
|
|
173
|
+
}
|
|
174
|
+
|
|
166
175
|
// Drop empty strings from optional browse URL line
|
|
167
176
|
const cleaned = parts.filter((p) => p !== '');
|
|
168
177
|
|
|
@@ -579,6 +588,7 @@ function stubAgentResult(onEvent, title, body) {
|
|
|
579
588
|
* ticketSource?: 'github' | 'jira',
|
|
580
589
|
* jiraKey?: string,
|
|
581
590
|
* jiraIssue?: object,
|
|
591
|
+
* userPrompt?: string,
|
|
582
592
|
* queryFn?: typeof query,
|
|
583
593
|
* callModelFn?: (args: object) => object,
|
|
584
594
|
* }} params
|
|
@@ -594,6 +604,7 @@ export async function runAgentOnIssue({
|
|
|
594
604
|
ticketSource,
|
|
595
605
|
jiraKey,
|
|
596
606
|
jiraIssue,
|
|
607
|
+
userPrompt,
|
|
597
608
|
queryFn = query,
|
|
598
609
|
callModelFn,
|
|
599
610
|
}) {
|
|
@@ -613,6 +624,7 @@ export async function runAgentOnIssue({
|
|
|
613
624
|
jiraKey,
|
|
614
625
|
jiraIssue,
|
|
615
626
|
jiraPrLinkPhrase: config.jiraPrLinkPhrase,
|
|
627
|
+
userPrompt,
|
|
616
628
|
});
|
|
617
629
|
|
|
618
630
|
const { resultText, meta, usage } = await runConfiguredQuery({
|
package/src/server.js
CHANGED
|
@@ -68,6 +68,9 @@ const CLEARABLE_STATUSES = new Set([
|
|
|
68
68
|
'failed',
|
|
69
69
|
]);
|
|
70
70
|
|
|
71
|
+
/** Max length for optional user-supplied prompt appended to the agent instructions. */
|
|
72
|
+
const USER_PROMPT_MAX_LEN = 4000;
|
|
73
|
+
|
|
71
74
|
/**
|
|
72
75
|
* Worktree directory id: Jira key or GitHub issue number.
|
|
73
76
|
* @param {{ jiraKey?: string, issueNumber?: number }} job
|
|
@@ -471,6 +474,7 @@ export function createServer({ repoRoot, config, store, useStubAgent = false, de
|
|
|
471
474
|
ticketSource: isJira ? 'jira' : 'github',
|
|
472
475
|
jiraKey: job.jiraKey,
|
|
473
476
|
jiraIssue,
|
|
477
|
+
userPrompt: job.userPrompt,
|
|
474
478
|
});
|
|
475
479
|
|
|
476
480
|
if (!store.getJob(jobId)) return;
|
|
@@ -833,6 +837,17 @@ export function createServer({ repoRoot, config, store, useStubAgent = false, de
|
|
|
833
837
|
}
|
|
834
838
|
const preferredBranchName = preferredParsed.value;
|
|
835
839
|
|
|
840
|
+
const rawUserPrompt = req.body?.userPrompt;
|
|
841
|
+
if (rawUserPrompt != null && typeof rawUserPrompt !== 'string') {
|
|
842
|
+
return res.status(400).json({ error: 'userPrompt must be a string' });
|
|
843
|
+
}
|
|
844
|
+
const userPrompt = typeof rawUserPrompt === 'string' ? rawUserPrompt.trim() : '';
|
|
845
|
+
if (userPrompt.length > USER_PROMPT_MAX_LEN) {
|
|
846
|
+
return res.status(400).json({
|
|
847
|
+
error: `userPrompt must be ${USER_PROMPT_MAX_LEN} characters or fewer.`,
|
|
848
|
+
});
|
|
849
|
+
}
|
|
850
|
+
|
|
836
851
|
const ticketSource =
|
|
837
852
|
req.body?.ticketSource === 'jira' || req.body?.ticketSource === 'github'
|
|
838
853
|
? req.body.ticketSource
|
|
@@ -929,6 +944,7 @@ export function createServer({ repoRoot, config, store, useStubAgent = false, de
|
|
|
929
944
|
ticketSource: item.ticketSource,
|
|
930
945
|
jiraKey: item.jiraKey,
|
|
931
946
|
...(preferredBranchName ? { preferredBranchName } : {}),
|
|
947
|
+
...(userPrompt ? { userPrompt } : {}),
|
|
932
948
|
llmProvider: llm.llmProvider,
|
|
933
949
|
model: llm.model,
|
|
934
950
|
});
|
package/src/store.js
CHANGED
|
@@ -53,19 +53,21 @@ export class Store {
|
|
|
53
53
|
* @param {{
|
|
54
54
|
* issueUrl: string,
|
|
55
55
|
* issueNumber?: number,
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
56
|
+
* ticketSource?: 'github' | 'jira',
|
|
57
|
+
* jiraKey?: string,
|
|
58
|
+
* preferredBranchName?: string,
|
|
59
|
+
* llmProvider?: 'claude' | 'openrouter',
|
|
60
|
+
* model?: string,
|
|
61
|
+
* userPrompt?: string,
|
|
62
|
+
* }} data
|
|
63
|
+
* @returns {Job}
|
|
64
|
+
*/
|
|
64
65
|
addJob(data) {
|
|
65
66
|
const now = new Date().toISOString();
|
|
66
67
|
const ticketSource = data.ticketSource === 'jira' ? 'jira' : 'github';
|
|
67
68
|
const llmProvider = data.llmProvider === 'openrouter' ? 'openrouter' : 'claude';
|
|
68
69
|
const model = typeof data.model === 'string' ? data.model.trim() : '';
|
|
70
|
+
const userPrompt = typeof data.userPrompt === 'string' ? data.userPrompt.trim() : '';
|
|
69
71
|
/** @type {Job} */
|
|
70
72
|
const job = {
|
|
71
73
|
id: randomUUID(),
|
|
@@ -76,6 +78,7 @@ export class Store {
|
|
|
76
78
|
...(model ? { model } : {}),
|
|
77
79
|
...(data.jiraKey ? { jiraKey: data.jiraKey } : {}),
|
|
78
80
|
...(data.preferredBranchName ? { preferredBranchName: data.preferredBranchName } : {}),
|
|
81
|
+
...(userPrompt ? { userPrompt } : {}),
|
|
79
82
|
status: 'queued',
|
|
80
83
|
createdAt: now,
|
|
81
84
|
updatedAt: now,
|