chatroom-cli 1.77.5 → 1.79.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +174 -2382
- package/dist/index.js.map +15 -34
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -9916,10 +9916,6 @@ var init_api2 = __esm(() => {
|
|
|
9916
9916
|
});
|
|
9917
9917
|
|
|
9918
9918
|
// src/api.ts
|
|
9919
|
-
var exports_api = {};
|
|
9920
|
-
__export(exports_api, {
|
|
9921
|
-
api: () => api
|
|
9922
|
-
});
|
|
9923
9919
|
var init_api3 = __esm(() => {
|
|
9924
9920
|
init_api2();
|
|
9925
9921
|
});
|
|
@@ -33039,6 +33035,7 @@ function startSessionEventForwarder(client4, options) {
|
|
|
33039
33035
|
}
|
|
33040
33036
|
case "busy": {
|
|
33041
33037
|
clearRetryIdleTimeout();
|
|
33038
|
+
options.onActivity?.();
|
|
33042
33039
|
return;
|
|
33043
33040
|
}
|
|
33044
33041
|
default: {
|
|
@@ -76374,24 +76371,6 @@ var init_register_agent = __esm(() => {
|
|
|
76374
76371
|
init_services();
|
|
76375
76372
|
init_convex_error();
|
|
76376
76373
|
});
|
|
76377
|
-
|
|
76378
|
-
// ../../services/backend/prompts/base/shared/context-rule.ts
|
|
76379
|
-
function getContextRuleBlock(contextNewCmd, contextHint) {
|
|
76380
|
-
return `**Context Rule:** Set a new context for every user message by default — skip ONLY when the message is clearly a follow-up of the current chatroom task. **Before running \`context new\`, run \`context read\` — if the pinned context already uses the same \`--trigger-message-id\` as this task's Origin Message ID, do NOT create another context** (avoids duplicate timeline dividers). Only the entry point role can set contexts:
|
|
76381
|
-
\`\`\`bash
|
|
76382
|
-
${contextNewCmd}
|
|
76383
|
-
\`\`\`
|
|
76384
|
-
${contextHint}`;
|
|
76385
|
-
}
|
|
76386
|
-
|
|
76387
|
-
// ../../services/backend/prompts/base/shared/token-activity-note.ts
|
|
76388
|
-
function getTokenActivityInProgressNote() {
|
|
76389
|
-
return "Begin working from the task content above. The daemon detects harness output (stdout tokens) and marks the task `in_progress` automatically — **do not run `task read`** unless you need backlog items or context details not shown in the delivery.";
|
|
76390
|
-
}
|
|
76391
|
-
function getNativeTokenActivityInProgressNote() {
|
|
76392
|
-
return "Begin working from the task content above. The daemon detects harness output (stdout tokens) and marks the task `in_progress` automatically.";
|
|
76393
|
-
}
|
|
76394
|
-
|
|
76395
76374
|
// ../../services/backend/prompts/cli/context/context-template.ts
|
|
76396
76375
|
function getContextViewTemplate() {
|
|
76397
76376
|
return CONTEXT_VIEW_TEMPLATE;
|
|
@@ -76410,60 +76389,20 @@ var CONTEXT_VIEW_TEMPLATE = `## Goal
|
|
|
76410
76389
|
- _Out-of-scope work or anti-patterns to skip._`;
|
|
76411
76390
|
|
|
76412
76391
|
// ../../services/backend/prompts/cli/context/view-template.ts
|
|
76413
|
-
function contextViewTemplateCommand(params) {
|
|
76414
|
-
const prefix = params.cliEnvPrefix || "";
|
|
76415
|
-
return `${prefix}chatroom context view-template`;
|
|
76416
|
-
}
|
|
76417
76392
|
var init_view_template = () => {};
|
|
76418
76393
|
|
|
76419
76394
|
// ../../services/backend/prompts/cli/context/new.ts
|
|
76420
|
-
function contextNewHint(params) {
|
|
76421
|
-
const viewTemplateCmd = contextViewTemplateCommand({ cliEnvPrefix: params.cliEnvPrefix });
|
|
76422
|
-
return `REQUIRED: All context content MUST conform to the template. Run \`${viewTemplateCmd}\` (no flags). \`--trigger-message-id\` must be the task's \`origin-message-id\` attribute (never \`task-id\`). Use the pre-filled value in the command above when provided.`;
|
|
76423
|
-
}
|
|
76424
|
-
function contextNewCommand(params) {
|
|
76425
|
-
const prefix = params.cliEnvPrefix || "";
|
|
76426
|
-
const chatroomId = params.chatroomId || "CHATROOM_ID";
|
|
76427
|
-
const role = params.role || "ROLE";
|
|
76428
|
-
const triggerMessageId = params.triggerMessageId ?? "ORIGIN_MESSAGE_ID";
|
|
76429
|
-
const commandPrefix = `${prefix}chatroom context new --chatroom-id="${chatroomId}" --role="${role}" --trigger-message-id="${triggerMessageId}"`;
|
|
76430
|
-
return formatStdinHeredocCommand(commandPrefix, CONTEXT_STDIN_DELIMITER, getContextViewTemplate());
|
|
76431
|
-
}
|
|
76432
76395
|
var init_new = __esm(() => {
|
|
76433
76396
|
init_stdin_heredoc();
|
|
76434
76397
|
init_view_template();
|
|
76435
76398
|
});
|
|
76436
76399
|
|
|
76437
76400
|
// ../../services/backend/prompts/cli/task-started/main-prompt.ts
|
|
76438
|
-
function getTaskStartedPrompt(ctx) {
|
|
76439
|
-
const { chatroomId, role, cliEnvPrefix, triggerMessageId } = ctx;
|
|
76440
|
-
const contextNewCmd = contextNewCommand({
|
|
76441
|
-
chatroomId,
|
|
76442
|
-
role,
|
|
76443
|
-
cliEnvPrefix,
|
|
76444
|
-
triggerMessageId
|
|
76445
|
-
});
|
|
76446
|
-
return `### Start working
|
|
76447
|
-
|
|
76448
|
-
${getTokenActivityInProgressNote()}
|
|
76449
|
-
|
|
76450
|
-
${getContextRuleBlock(contextNewCmd, contextNewHint({ cliEnvPrefix }))}`;
|
|
76451
|
-
}
|
|
76452
|
-
function getTaskStartedPromptForHandoffRecipient(_ctx) {
|
|
76453
|
-
return `### Start Working
|
|
76454
|
-
|
|
76455
|
-
The task body contains your work description. ${getTokenActivityInProgressNote()}`;
|
|
76456
|
-
}
|
|
76457
76401
|
var init_main_prompt = __esm(() => {
|
|
76458
76402
|
init_new();
|
|
76459
76403
|
});
|
|
76460
76404
|
|
|
76461
76405
|
// ../../services/backend/prompts/cli/task-started/index.ts
|
|
76462
|
-
var exports_task_started = {};
|
|
76463
|
-
__export(exports_task_started, {
|
|
76464
|
-
getTaskStartedPromptForHandoffRecipient: () => getTaskStartedPromptForHandoffRecipient,
|
|
76465
|
-
getTaskStartedPrompt: () => getTaskStartedPrompt
|
|
76466
|
-
});
|
|
76467
76406
|
var init_task_started = __esm(() => {
|
|
76468
76407
|
init_main_prompt();
|
|
76469
76408
|
});
|
|
@@ -76485,14 +76424,6 @@ Exactly one active waiter should own task delivery at a time. Additional or back
|
|
|
76485
76424
|
|
|
76486
76425
|
After interruption or restart: complete any in-progress work, then restore a single foreground blocking \`get-next-task\` so chatroom tasks can arrive again.`;
|
|
76487
76426
|
}
|
|
76488
|
-
function getCompactionRecoveryNote(params) {
|
|
76489
|
-
const { cliEnvPrefix, chatroomId, role } = params;
|
|
76490
|
-
return `NOTE: If you are an agent that has undergone compaction or summarization, run:
|
|
76491
|
-
${cliEnvPrefix}chatroom get-system-prompt --chatroom-id="${chatroomId}" --role="${role}"
|
|
76492
|
-
to reload your full system and role prompt. Then run:
|
|
76493
|
-
${cliEnvPrefix}chatroom context read --chatroom-id="${chatroomId}" --role="${role}"
|
|
76494
|
-
to see your current chatroom task context.`;
|
|
76495
|
-
}
|
|
76496
76427
|
var init_reminder = () => {};
|
|
76497
76428
|
// ../../services/backend/prompts/utils/index.ts
|
|
76498
76429
|
var init_utils3 = __esm(() => {
|
|
@@ -76500,65 +76431,16 @@ var init_utils3 = __esm(() => {
|
|
|
76500
76431
|
});
|
|
76501
76432
|
|
|
76502
76433
|
// ../../services/backend/prompts/base/shared/getting-started-content.ts
|
|
76503
|
-
function getContextGainingGuidance(params) {
|
|
76504
|
-
const { chatroomId, role, convexUrl, agentType } = params;
|
|
76505
|
-
const cliEnvPrefix = getCliEnvPrefix(convexUrl);
|
|
76506
|
-
const typeValue = agentType && agentType !== "unset" ? agentType : "<remote|custom>";
|
|
76507
|
-
return `## Getting Started
|
|
76508
|
-
|
|
76509
|
-
### Workflow Loop
|
|
76510
|
-
|
|
76511
|
-
\`\`\`mermaid
|
|
76512
|
-
flowchart LR
|
|
76513
|
-
A([Start]) --> B[register-agent]
|
|
76514
|
-
B --> C[get-next-task
|
|
76515
|
-
chatroom task delivery]
|
|
76516
|
-
C --> D[Do Work]
|
|
76517
|
-
D --> E[handoff]
|
|
76518
|
-
E --> C
|
|
76519
|
-
\`\`\`
|
|
76520
|
-
|
|
76521
|
-
### Task delivery and activity
|
|
76522
|
-
|
|
76523
|
-
When \`get-next-task\` delivers a chatroom task, the **full task content is included in the output**. ${getTokenActivityInProgressNote()}
|
|
76524
|
-
|
|
76525
|
-
⚠️ Remember your two-level model: completing a **chatroom task** (Level B) does NOT end your **session** (Level A). After every handoff, you must run \`get-next-task\` again to continue the session.
|
|
76526
|
-
|
|
76527
|
-
### Context Recovery (after compaction/summarization)
|
|
76528
|
-
|
|
76529
|
-
${getCompactionRecoveryNote({ cliEnvPrefix, chatroomId, role })}
|
|
76530
|
-
|
|
76531
|
-
CLI harnesses do not support in-session compaction. After context is lost, the daemon performs a hard restart — you must run \`get-next-task\` again to rejoin the chatroom.
|
|
76532
|
-
|
|
76533
|
-
### Register Agent
|
|
76534
|
-
Register your agent type before starting work.
|
|
76535
|
-
|
|
76536
|
-
\`\`\`bash
|
|
76537
|
-
${cliEnvPrefix}chatroom register-agent --chatroom-id="${chatroomId}" --role="${role}" --type=${typeValue}
|
|
76538
|
-
\`\`\`
|
|
76539
|
-
|
|
76540
|
-
### Get Next Task
|
|
76541
|
-
Listen for incoming tasks assigned to your role. A foreground \`get-next-task\` blocks until the user or team message is ready, then resolves with that message as a chatroom task—infer intent from the message rather than following numbered next-steps blindly.
|
|
76542
|
-
|
|
76543
|
-
\`\`\`bash
|
|
76544
|
-
${cliEnvPrefix}chatroom get-next-task --chatroom-id="${chatroomId}" --role="${role}"
|
|
76545
|
-
\`\`\`
|
|
76546
|
-
|
|
76547
|
-
**This loop never ends.** A session (Level A) processes many chatroom tasks (Level B). Each handoff completes Level B — \`get-next-task\` continues Level A. Do not stop or exit after a handoff.
|
|
76548
|
-
`;
|
|
76549
|
-
}
|
|
76550
76434
|
var init_getting_started_content = __esm(() => {
|
|
76551
76435
|
init_reminder();
|
|
76552
76436
|
init_utils3();
|
|
76553
76437
|
});
|
|
76554
76438
|
|
|
76555
76439
|
// ../../services/backend/prompts/cli/index.ts
|
|
76556
|
-
var getTaskStartedPrompt2, getTaskStartedPromptForHandoffRecipient2;
|
|
76557
76440
|
var init_cli = __esm(() => {
|
|
76558
76441
|
init_task_started();
|
|
76559
76442
|
init_reminder();
|
|
76560
76443
|
init_getting_started_content();
|
|
76561
|
-
({ getTaskStartedPrompt: getTaskStartedPrompt2, getTaskStartedPromptForHandoffRecipient: getTaskStartedPromptForHandoffRecipient2 } = exports_task_started);
|
|
76562
76444
|
});
|
|
76563
76445
|
|
|
76564
76446
|
// src/commands/get-next-task/get-next-task-session-service.ts
|
|
@@ -77373,35 +77255,52 @@ var init_builder_to_planner = __esm(() => {
|
|
|
77373
77255
|
init_role_guidance_disclosure();
|
|
77374
77256
|
});
|
|
77375
77257
|
|
|
77376
|
-
// ../../services/backend/prompts/
|
|
77377
|
-
function
|
|
77378
|
-
return
|
|
77379
|
-
|
|
77380
|
-
${getHandoffReportTemplateIntro("Planning Feedback (Enhancer → Planner)")}
|
|
77381
|
-
|
|
77382
|
-
The planner sent you three XML sections. Your job is **advisory adversarial review** — raise risks, challenge assumptions, and help the planner align with user intent. **Do not prescribe file-level changes or rewrite their builder brief.** The planner makes the final call.
|
|
77383
|
-
|
|
77384
|
-
\`\`\`markdown
|
|
77258
|
+
// ../../services/backend/prompts/utils/enhancer-feedback-template-body.ts
|
|
77259
|
+
function getEnhancerFeedbackTemplateBody() {
|
|
77260
|
+
return `<handoff-overview>
|
|
77385
77261
|
## Summary
|
|
77386
77262
|
<one paragraph: overall assessment — strengths, main risks, and whether the approach is sound>
|
|
77387
77263
|
|
|
77388
77264
|
## User intent alignment
|
|
77389
77265
|
<does the planner's reading of the user request match what was asked? misreadings or missing constraints?>
|
|
77266
|
+
</handoff-overview>
|
|
77390
77267
|
|
|
77391
|
-
|
|
77392
|
-
<what could go wrong if they proceed as planned? common pitfalls for this kind of work?>
|
|
77268
|
+
<!-- UI collapses proofs, direction, and notes by default; overview and action required are expanded -->
|
|
77393
77269
|
|
|
77270
|
+
<handoff-proofs>
|
|
77271
|
+
## Reasoning review
|
|
77272
|
+
<logical errors, weak inference, contradictions — challenge assumptions>
|
|
77273
|
+
</handoff-proofs>
|
|
77274
|
+
|
|
77275
|
+
<handoff-direction>
|
|
77276
|
+
## Alignment with eventual user handoff
|
|
77277
|
+
<will this approach produce a credible planner→user report? what's missing for user-facing completeness?>
|
|
77278
|
+
</handoff-direction>
|
|
77279
|
+
|
|
77280
|
+
<handoff-notes>
|
|
77394
77281
|
## Knowledge gaps
|
|
77395
77282
|
<facts, context, or research the planner should verify — advisory questions, not answers from codebase>
|
|
77283
|
+
</handoff-notes>
|
|
77396
77284
|
|
|
77397
|
-
|
|
77398
|
-
|
|
77285
|
+
<handoff-action>
|
|
77286
|
+
## Risks & failure modes
|
|
77287
|
+
<what could go wrong if they proceed as planned? common pitfalls for this kind of work?>
|
|
77399
77288
|
|
|
77400
77289
|
## Questions for the planner
|
|
77401
77290
|
<specific questions they should answer before delegating — not instructions disguised as questions>
|
|
77291
|
+
</handoff-action>`;
|
|
77292
|
+
}
|
|
77402
77293
|
|
|
77403
|
-
|
|
77404
|
-
|
|
77294
|
+
// ../../services/backend/prompts/teams/duo/handoff-templates/enhancer-to-planner.ts
|
|
77295
|
+
function getEnhancerToPlannerHandoffTemplate() {
|
|
77296
|
+
return `${getHandoffRecipientVisibilityCallout("planner")}
|
|
77297
|
+
|
|
77298
|
+
${getHandoffReportTemplateIntro("Planning Feedback (Enhancer → Planner)")}
|
|
77299
|
+
|
|
77300
|
+
The planner sent you three XML sections. Your job is **advisory adversarial review** — raise risks, challenge assumptions, and help the planner align with user intent. **Do not prescribe file-level changes or rewrite their builder brief.** The planner makes the final call.
|
|
77301
|
+
|
|
77302
|
+
\`\`\`markdown
|
|
77303
|
+
${getEnhancerFeedbackTemplateBody()}
|
|
77405
77304
|
\`\`\`
|
|
77406
77305
|
|
|
77407
77306
|
Return only the feedback markdown — no preamble. Follow this structure; omit sections that truly do not apply.`;
|
|
@@ -77910,24 +77809,6 @@ function formatDecodeError(error) {
|
|
|
77910
77809
|
}
|
|
77911
77810
|
|
|
77912
77811
|
// ../../services/backend/prompts/native/session-continuity.ts
|
|
77913
|
-
function getSessionContinuityLine(nativeIntegration) {
|
|
77914
|
-
if (nativeIntegration) {
|
|
77915
|
-
return "";
|
|
77916
|
-
}
|
|
77917
|
-
return "Completing a **chatroom task** (Level B) does NOT end your **session** (Level A). After every handoff, run `get-next-task` to continue.";
|
|
77918
|
-
}
|
|
77919
|
-
function getHandoffContinuityRule(nativeIntegration) {
|
|
77920
|
-
if (nativeIntegration) {
|
|
77921
|
-
return "";
|
|
77922
|
-
}
|
|
77923
|
-
return "⚠️ After ANY handoff (including to `user`), you must run `get-next-task` to stay in the session.";
|
|
77924
|
-
}
|
|
77925
|
-
function getOperatingModelLoopFooter(nativeIntegration) {
|
|
77926
|
-
return nativeIntegration ? "Hand off when complete" : "Run get-next-task";
|
|
77927
|
-
}
|
|
77928
|
-
function getNativePlannerDelegationWaitNote() {
|
|
77929
|
-
return `After delegating to the builder, **run handoff as your last action and end your turn** — no further tool calls after handoff. The system delivers their handback when they finish — do not poll \`messages list\`, sleep, or run other tools while waiting.`;
|
|
77930
|
-
}
|
|
77931
77812
|
function getNativeHandoffTurnEndGuidance(nextRole) {
|
|
77932
77813
|
const lines = [
|
|
77933
77814
|
"",
|
|
@@ -77943,103 +77824,10 @@ function getNativeHandoffTurnEndGuidance(nextRole) {
|
|
|
77943
77824
|
}
|
|
77944
77825
|
|
|
77945
77826
|
// ../../services/backend/prompts/cli/handoff/command.ts
|
|
77946
|
-
function handoffCommand(params) {
|
|
77947
|
-
const prefix = params.cliEnvPrefix || "";
|
|
77948
|
-
const chatroomId = params.chatroomId || "<chatroom-id>";
|
|
77949
|
-
const role = params.role || "<role>";
|
|
77950
|
-
const nextRole = params.nextRole || "<target>";
|
|
77951
|
-
const placeholder = params.messagePlaceholder ?? "[Your message here]";
|
|
77952
|
-
const commandPrefix = `${prefix}chatroom handoff --chatroom-id="${chatroomId}" --role="${role}" --next-role="${nextRole}"`;
|
|
77953
|
-
return formatStdinHeredocCommand(commandPrefix, HANDOFF_STDIN_DELIMITER, placeholder, {
|
|
77954
|
-
messageMarker: HANDOFF_MESSAGE_MARKER
|
|
77955
|
-
});
|
|
77956
|
-
}
|
|
77957
77827
|
var init_command2 = __esm(() => {
|
|
77958
77828
|
init_stdin_heredoc();
|
|
77959
77829
|
});
|
|
77960
|
-
|
|
77961
|
-
// ../../services/backend/prompts/types/sections.ts
|
|
77962
|
-
function createSection(id3, type, content) {
|
|
77963
|
-
return { id: id3, type, content };
|
|
77964
|
-
}
|
|
77965
|
-
function composeSections(sections) {
|
|
77966
|
-
return sections.filter((s) => s.content.trim()).map((s) => s.content).join(`
|
|
77967
|
-
|
|
77968
|
-
`).trim();
|
|
77969
|
-
}
|
|
77970
|
-
|
|
77971
77830
|
// ../../services/backend/prompts/sections/commands-reference.ts
|
|
77972
|
-
function getCommandsReferenceSection(params) {
|
|
77973
|
-
const cliEnvPrefix = getCliEnvPrefix(params.convexUrl);
|
|
77974
|
-
const handoffCmd = handoffCommand({
|
|
77975
|
-
chatroomId: params.chatroomId,
|
|
77976
|
-
role: params.role,
|
|
77977
|
-
nextRole: "<target>",
|
|
77978
|
-
cliEnvPrefix
|
|
77979
|
-
});
|
|
77980
|
-
const waitCmd = getNextTaskCommand({
|
|
77981
|
-
chatroomId: params.chatroomId,
|
|
77982
|
-
role: params.role,
|
|
77983
|
-
cliEnvPrefix
|
|
77984
|
-
});
|
|
77985
|
-
const content = `### Commands
|
|
77986
|
-
|
|
77987
|
-
**Complete chatroom task and hand off:**
|
|
77988
|
-
|
|
77989
|
-
\`\`\`bash
|
|
77990
|
-
${handoffCmd}
|
|
77991
|
-
\`\`\`
|
|
77992
|
-
|
|
77993
|
-
${HANDOFF_BODY_GUIDANCE}
|
|
77994
|
-
|
|
77995
|
-
**Continue receiving messages after \`handoff\`:**
|
|
77996
|
-
\`\`\`
|
|
77997
|
-
${waitCmd}
|
|
77998
|
-
\`\`\`
|
|
77999
|
-
|
|
78000
|
-
${getNextTaskReminder()}
|
|
78001
|
-
|
|
78002
|
-
**Reference commands:**
|
|
78003
|
-
- List recent messages: \`${cliEnvPrefix}chatroom messages list --chatroom-id="${params.chatroomId}" --role="${params.role}" --sender-role=user --limit=5 --full\`
|
|
78004
|
-
- Git log: \`git log --oneline -10\`
|
|
78005
|
-
|
|
78006
|
-
**Recovery commands** (only needed after compaction/restart):
|
|
78007
|
-
- Reload system prompt: \`${cliEnvPrefix}chatroom get-system-prompt --chatroom-id="${params.chatroomId}" --role="${params.role}"\`
|
|
78008
|
-
- Reload role guidance: \`${roleGuidanceCommand({ chatroomId: params.chatroomId, role: params.role, cliEnvPrefix })}\`
|
|
78009
|
-
- Read current chatroom task context: \`${cliEnvPrefix}chatroom context read --chatroom-id="${params.chatroomId}" --role="${params.role}"\``;
|
|
78010
|
-
return createSection("commands-reference", "knowledge", content);
|
|
78011
|
-
}
|
|
78012
|
-
function getNativeCommandsReferenceSection(params) {
|
|
78013
|
-
const cliEnvPrefix = getCliEnvPrefix(params.convexUrl);
|
|
78014
|
-
const handoffCmd = handoffCommand({
|
|
78015
|
-
chatroomId: params.chatroomId,
|
|
78016
|
-
role: params.role,
|
|
78017
|
-
nextRole: "<target>",
|
|
78018
|
-
cliEnvPrefix
|
|
78019
|
-
});
|
|
78020
|
-
const content = `### Commands
|
|
78021
|
-
|
|
78022
|
-
**Complete chatroom task and hand off:**
|
|
78023
|
-
|
|
78024
|
-
\`\`\`bash
|
|
78025
|
-
${handoffCmd}
|
|
78026
|
-
\`\`\`
|
|
78027
|
-
|
|
78028
|
-
${HANDOFF_BODY_GUIDANCE}
|
|
78029
|
-
|
|
78030
|
-
**Do not run \`register-agent\`** — your session was registered when the harness started.
|
|
78031
|
-
|
|
78032
|
-
**Reference commands:**
|
|
78033
|
-
- List recent messages: \`${cliEnvPrefix}chatroom messages list --chatroom-id="${params.chatroomId}" --role="${params.role}" --sender-role=user --limit=5 --full\`
|
|
78034
|
-
- Git log: \`git log --oneline -10\`
|
|
78035
|
-
|
|
78036
|
-
**Recovery commands** (only needed after compaction/restart):
|
|
78037
|
-
- Reload system prompt: \`${cliEnvPrefix}chatroom get-system-prompt --chatroom-id="${params.chatroomId}" --role="${params.role}"\`
|
|
78038
|
-
- Reload role guidance: \`${roleGuidanceCommand({ chatroomId: params.chatroomId, role: params.role, cliEnvPrefix })}\`
|
|
78039
|
-
- Read current chatroom task context: \`${cliEnvPrefix}chatroom context read --chatroom-id="${params.chatroomId}" --role="${params.role}"\``;
|
|
78040
|
-
return createSection("commands-reference-native", "knowledge", content);
|
|
78041
|
-
}
|
|
78042
|
-
var HANDOFF_BODY_GUIDANCE = `Fill in the message using the matching template from \`<handoff-templates>\` in your task delivery output. Replace \`[Your message here]\` with that template content. The closing line must be exactly \`CHATROOM_HANDOFF_END\` (not \`EOF\`).`;
|
|
78043
77831
|
var init_commands_reference = __esm(() => {
|
|
78044
77832
|
init_command();
|
|
78045
77833
|
init_reminder();
|
|
@@ -78048,650 +77836,25 @@ var init_commands_reference = __esm(() => {
|
|
|
78048
77836
|
});
|
|
78049
77837
|
|
|
78050
77838
|
// ../../services/backend/prompts/cli/backlog/command.ts
|
|
78051
|
-
function backlogAddCommand(params) {
|
|
78052
|
-
const prefix = params.cliEnvPrefix || "";
|
|
78053
|
-
const chatroomId = params.chatroomId || "<id>";
|
|
78054
|
-
const role = params.role || "<role>";
|
|
78055
|
-
const placeholder = params.contentPlaceholder ?? "Your backlog item content here";
|
|
78056
|
-
const commandPrefix = `${prefix}chatroom backlog add --chatroom-id=${chatroomId} --role=${role}`;
|
|
78057
|
-
return formatStdinHeredocCommand(commandPrefix, BACKLOG_STDIN_DELIMITER, placeholder);
|
|
78058
|
-
}
|
|
78059
|
-
function backlogUpdateCommand(params) {
|
|
78060
|
-
const prefix = params.cliEnvPrefix || "";
|
|
78061
|
-
const chatroomId = params.chatroomId || "<id>";
|
|
78062
|
-
const role = params.role || "<role>";
|
|
78063
|
-
const backlogItemId = params.backlogItemId || "<id>";
|
|
78064
|
-
const placeholder = params.contentPlaceholder ?? "New content here";
|
|
78065
|
-
const commandPrefix = `${prefix}chatroom backlog update --chatroom-id=${chatroomId} --role=${role} --backlog-item-id=${backlogItemId}`;
|
|
78066
|
-
return formatStdinHeredocCommand(commandPrefix, BACKLOG_STDIN_DELIMITER, placeholder);
|
|
78067
|
-
}
|
|
78068
77839
|
var init_command3 = __esm(() => {
|
|
78069
77840
|
init_stdin_heredoc();
|
|
78070
77841
|
});
|
|
78071
77842
|
|
|
78072
77843
|
// ../../services/backend/src/domain/usecase/skills/modules/backlog/index.ts
|
|
78073
|
-
var backlogSkill;
|
|
78074
77844
|
var init_backlog = __esm(() => {
|
|
78075
77845
|
init_command3();
|
|
78076
|
-
backlogSkill = {
|
|
78077
|
-
skillId: "backlog",
|
|
78078
|
-
name: "Backlog Reference",
|
|
78079
|
-
description: "Full backlog command reference: list/add/update, scoring, completion, close, export/import, and workflow guides.",
|
|
78080
|
-
getPrompt: (cliEnvPrefix) => `You have been activated with the "backlog" skill.
|
|
78081
|
-
|
|
78082
|
-
## Command Reference
|
|
78083
|
-
|
|
78084
|
-
### List
|
|
78085
|
-
\`\`\`
|
|
78086
|
-
${cliEnvPrefix}chatroom backlog list --chatroom-id=<id> --role=<role>
|
|
78087
|
-
\`\`\`
|
|
78088
|
-
Options: \`--limit=<n>\`, \`--sort=date:desc|priority:desc\`, \`--filter=unscored\` (only items without a priority score)
|
|
78089
|
-
|
|
78090
|
-
The list output shows scoring info (complexity, value, priority) for each item if it has been scored.
|
|
78091
|
-
|
|
78092
|
-
### History
|
|
78093
|
-
\`\`\`
|
|
78094
|
-
${cliEnvPrefix}chatroom backlog history --chatroom-id=<id> --role=<role>
|
|
78095
|
-
\`\`\`
|
|
78096
|
-
Options: \`--from=YYYY-MM-DD\`, \`--to=YYYY-MM-DD\`, \`--limit=<n>\`
|
|
78097
|
-
|
|
78098
|
-
Defaults: last 30 days through today; shows completed and closed tasks in range.
|
|
78099
|
-
|
|
78100
|
-
Use \`history\` for finished work; use \`list\` for active backlog items.
|
|
78101
|
-
|
|
78102
|
-
### Add
|
|
78103
|
-
Content via **stdin / heredoc** or \`--content-file\`:
|
|
78104
|
-
|
|
78105
|
-
\`\`\`
|
|
78106
|
-
${backlogAddCommand({ cliEnvPrefix })}
|
|
78107
|
-
\`\`\`
|
|
78108
|
-
|
|
78109
|
-
\`\`\`
|
|
78110
|
-
${cliEnvPrefix}chatroom backlog add --chatroom-id=<id> --role=<role> --content-file=./task.md
|
|
78111
|
-
\`\`\`
|
|
78112
|
-
|
|
78113
|
-
### Update
|
|
78114
|
-
Replace the **text content** of an existing item. Allowed only while the item is in \`backlog\` status. Same input pattern as **add** (stdin/heredoc or \`--content-file\`).
|
|
78115
|
-
|
|
78116
|
-
\`\`\`
|
|
78117
|
-
${backlogUpdateCommand({ cliEnvPrefix })}
|
|
78118
|
-
\`\`\`
|
|
78119
|
-
|
|
78120
|
-
\`\`\`
|
|
78121
|
-
${cliEnvPrefix}chatroom backlog update --chatroom-id=<id> --role=<role> --backlog-item-id=<id> --content-file=./revised.md
|
|
78122
|
-
\`\`\`
|
|
78123
|
-
|
|
78124
|
-
Use **update** to revise a description in place instead of adding a superseding item.
|
|
78125
|
-
|
|
78126
|
-
### Score
|
|
78127
|
-
**Requires at least one** of \`--complexity\`, \`--value\`, or \`--priority\` (you can combine multiple).
|
|
78128
|
-
|
|
78129
|
-
\`\`\`
|
|
78130
|
-
${cliEnvPrefix}chatroom backlog score --chatroom-id=<id> --role=<role> --backlog-item-id=<id> \\
|
|
78131
|
-
[--complexity=<low|medium|high>] \\
|
|
78132
|
-
[--value=<low|medium|high>] \\
|
|
78133
|
-
[--priority=<n>]
|
|
78134
|
-
\`\`\`
|
|
78135
|
-
|
|
78136
|
-
\`--priority\` must be an integer (higher = more important). There is no enforced max in the CLI.
|
|
78137
|
-
|
|
78138
|
-
**Important**: Only score items that do not already have all three fields set (complexity, value, priority).
|
|
78139
|
-
Check the list output — items showing "Score: ..." are already scored. Skip them to avoid overwriting.
|
|
78140
|
-
|
|
78141
|
-
### Complete
|
|
78142
|
-
\`\`\`
|
|
78143
|
-
${cliEnvPrefix}chatroom backlog complete --chatroom-id=<id> --role=<role> --backlog-item-id=<id> [-f|--force]
|
|
78144
|
-
\`\`\`
|
|
78145
|
-
|
|
78146
|
-
Optional \`-f\` / \`--force\` is a registered flag (see \`chatroom backlog complete --help\`). It is **not** forwarded to the Convex mutation yet, so it does not change server behavior today; omit it unless your runbook says otherwise.
|
|
78147
|
-
|
|
78148
|
-
### Reopen
|
|
78149
|
-
\`\`\`
|
|
78150
|
-
${cliEnvPrefix}chatroom backlog reopen --chatroom-id=<id> --role=<role> --backlog-item-id=<id>
|
|
78151
|
-
\`\`\`
|
|
78152
|
-
|
|
78153
|
-
### Mark for Review
|
|
78154
|
-
\`\`\`
|
|
78155
|
-
${cliEnvPrefix}chatroom backlog mark-for-review --chatroom-id=<id> --role=<role> --backlog-item-id=<id>
|
|
78156
|
-
\`\`\`
|
|
78157
|
-
|
|
78158
|
-
### Export
|
|
78159
|
-
\`\`\`
|
|
78160
|
-
${cliEnvPrefix}chatroom backlog export --chatroom-id=<id> --role=<role> [--path=<directory>]
|
|
78161
|
-
\`\`\`
|
|
78162
|
-
Exports all backlog items (status=\`backlog\`) to a \`backlog-export.json\` file in the specified directory.
|
|
78163
|
-
Creates the directory if it doesn't exist.
|
|
78164
|
-
Default path (if \`--path\` is omitted): \`<cwd>/.chatroom/exports/\`
|
|
78165
|
-
|
|
78166
|
-
### Import
|
|
78167
|
-
\`\`\`
|
|
78168
|
-
${cliEnvPrefix}chatroom backlog import --chatroom-id=<id> --role=<role> [--path=<directory>]
|
|
78169
|
-
\`\`\`
|
|
78170
|
-
Imports backlog items from a \`backlog-export.json\` file in the specified directory.
|
|
78171
|
-
- **Idempotent**: skips items whose content already exists (matched by SHA-256 content hash)
|
|
78172
|
-
- **Staleness warning**: warns if the export is older than 7 days
|
|
78173
|
-
Default path (if \`--path\` is omitted): \`<cwd>/.chatroom/exports/\`
|
|
78174
|
-
|
|
78175
|
-
### Close
|
|
78176
|
-
Retires an item as stale, superseded, or duplicate. **\`--reason\` is required** (audit trail).
|
|
78177
|
-
|
|
78178
|
-
\`\`\`
|
|
78179
|
-
${cliEnvPrefix}chatroom backlog close --chatroom-id=<id> --role=<role> --backlog-item-id=<id> --reason="duplicate of XYZ"
|
|
78180
|
-
\`\`\`
|
|
78181
|
-
|
|
78182
|
-
⚠️ **RESTRICTED: Only use when the user explicitly asks you to close an item.**
|
|
78183
|
-
Agents must NEVER close backlog items autonomously. If an item looks stale or already implemented, prefer \`mark-for-review\` so the user decides.
|
|
78184
|
-
|
|
78185
|
-
Give a concise, factual reason (e.g. \`User confirmed: shipped in PR #119\`).
|
|
78186
|
-
|
|
78187
|
-
---
|
|
78188
|
-
|
|
78189
|
-
## Lifecycle
|
|
78190
|
-
|
|
78191
|
-
Backlog items move through explicit statuses. **When you raise a PR for user review, use \`mark-for-review\` — not \`complete\`.** Only mark \`complete\` after the PR is merged and verified (or the user confirms).
|
|
78192
|
-
|
|
78193
|
-
\`\`\`mermaid
|
|
78194
|
-
stateDiagram-v2
|
|
78195
|
-
[*] --> backlog: user creates
|
|
78196
|
-
backlog --> pending_user_review: agent raises PR (mark-for-review)
|
|
78197
|
-
pending_user_review --> closed: user confirms / PR merged (complete)
|
|
78198
|
-
backlog --> closed: stale/superseded (close)
|
|
78199
|
-
closed --> backlog: reopen
|
|
78200
|
-
\`\`\`
|
|
78201
|
-
|
|
78202
|
-
### Command decision table
|
|
78203
|
-
|
|
78204
|
-
| Situation | Command |
|
|
78205
|
-
|-----------|---------|
|
|
78206
|
-
| Fix PR opened, awaiting user review/merge | \`mark-for-review\` |
|
|
78207
|
-
| PR merged and verified | \`complete\` |
|
|
78208
|
-
| Stale/duplicate/won't fix | \`close --reason=...\` |
|
|
78209
|
-
| Mistakenly completed early | \`reopen\` then \`mark-for-review\` |
|
|
78210
|
-
|
|
78211
|
-
Reference: \`docs/plans/backlog-item-lifecycle-and-attachments.md\`
|
|
78212
|
-
|
|
78213
|
-
---
|
|
78214
|
-
|
|
78215
|
-
## Workflows
|
|
78216
|
-
|
|
78217
|
-
### 1. Score Unscored Items
|
|
78218
|
-
|
|
78219
|
-
\`\`\`mermaid
|
|
78220
|
-
flowchart TD
|
|
78221
|
-
A([Start]) --> B[List backlog items]
|
|
78222
|
-
B --> C{Any unscored?}
|
|
78223
|
-
C -->|No| D([Done])
|
|
78224
|
-
C -->|Yes| E["Check item: does it already have complexity + value + priority set?"]
|
|
78225
|
-
E -->|Already scored| F[Skip — do not overwrite existing score]
|
|
78226
|
-
F --> C
|
|
78227
|
-
E -->|Not scored| G[Score item: complexity, value, priority]
|
|
78228
|
-
G --> C
|
|
78229
|
-
\`\`\`
|
|
78230
|
-
|
|
78231
|
-
An item is "already scored" if the list output shows "Score: complexity=... | value=... | priority=...".
|
|
78232
|
-
|
|
78233
|
-
### 2. After Completing a Backlog Task (PR raised)
|
|
78234
|
-
|
|
78235
|
-
\`\`\`mermaid
|
|
78236
|
-
flowchart TD
|
|
78237
|
-
A([Implementation complete]) --> B[Open PR for user review]
|
|
78238
|
-
B --> C["mark-for-review (NOT complete)"]
|
|
78239
|
-
C --> D[Hand off to user with PR link + summary]
|
|
78240
|
-
D --> E([User reviews in Pending Review section])
|
|
78241
|
-
\`\`\`
|
|
78242
|
-
|
|
78243
|
-
Moves item to \`pending_user_review\`. User confirms completion (\`complete\`) or sends back for rework (\`reopen\`).
|
|
78244
|
-
|
|
78245
|
-
### 3. Continuous Backlog Execution
|
|
78246
|
-
|
|
78247
|
-
Only activate when the user explicitly instructs autonomous execution
|
|
78248
|
-
(e.g. "work through the backlog", "autonomously implement backlog items").
|
|
78249
|
-
|
|
78250
|
-
\`\`\`mermaid
|
|
78251
|
-
flowchart TD
|
|
78252
|
-
A([Start]) --> B[List all backlog items]
|
|
78253
|
-
B --> C{Any unscored?}
|
|
78254
|
-
C -->|Yes| D["Score only items missing complexity/value/priority\\n(skip already-scored items)"] --> E[Re-list]
|
|
78255
|
-
C -->|No| E
|
|
78256
|
-
E --> F["Select items: complexity=low AND value=high"]
|
|
78257
|
-
F --> G{Qualifying items?}
|
|
78258
|
-
G -->|No| H([Hand off — no high-ROI items found])
|
|
78259
|
-
G -->|Yes| I[Take next item]
|
|
78260
|
-
I --> J{Already implemented?\\nCheck codebase / recent commits}
|
|
78261
|
-
J -->|Yes — stale| K["Mark for review\\n(note: already implemented)"]
|
|
78262
|
-
J -->|No| L[Implement: code changes + PR]
|
|
78263
|
-
L --> K
|
|
78264
|
-
K --> M[Mark item for review]
|
|
78265
|
-
M --> N{More items?}
|
|
78266
|
-
N -->|Yes| I
|
|
78267
|
-
N -->|No| O[Hand off to user with full summary]
|
|
78268
|
-
O --> P([Done])
|
|
78269
|
-
\`\`\`
|
|
78270
|
-
|
|
78271
|
-
Stale item = backlog task already present in the codebase. Mark immediately; skip implementation.
|
|
78272
|
-
ROI = low complexity × high value.
|
|
78273
|
-
|
|
78274
|
-
### 4. Backlog Cleanup
|
|
78275
|
-
|
|
78276
|
-
Follow these steps to clean up the backlog by identifying and closing stale items.
|
|
78277
|
-
|
|
78278
|
-
1. List all backlog items:
|
|
78279
|
-
\`\`\`
|
|
78280
|
-
${cliEnvPrefix}chatroom backlog list --chatroom-id=<id> --role=<role>
|
|
78281
|
-
\`\`\`
|
|
78282
|
-
|
|
78283
|
-
2. For each item, assess staleness:
|
|
78284
|
-
- Read the content carefully
|
|
78285
|
-
- If the item is still valid but the **wording is wrong**, use \`backlog update\` to fix the description in place (do not add a duplicate item)
|
|
78286
|
-
- Check if already implemented (look at recent commits, PRs, or existing code)
|
|
78287
|
-
- Check if superseded by a newer backlog item
|
|
78288
|
-
|
|
78289
|
-
3. For stale items, mark for review:
|
|
78290
|
-
\`\`\`
|
|
78291
|
-
${cliEnvPrefix}chatroom backlog mark-for-review --chatroom-id=<id> --role=<role> --backlog-item-id=<item-id>
|
|
78292
|
-
\`\`\`
|
|
78293
|
-
**Important:** Always mark for review — do NOT close directly. Let the user confirm.
|
|
78294
|
-
|
|
78295
|
-
4. If you are the coordinator, delegate assessment to workers:
|
|
78296
|
-
- Builder checks codebase to determine if items are stale
|
|
78297
|
-
- Builder marks stale items for review and reports back
|
|
78298
|
-
|
|
78299
|
-
5. Report summary: items reviewed, marked for review, kept, needs clarification
|
|
78300
|
-
|
|
78301
|
-
### 5. Export / Import Backlog
|
|
78302
|
-
|
|
78303
|
-
Use export/import to transfer backlog items between workspaces or for backup.
|
|
78304
|
-
Default path: \`<cwd>/.chatroom/exports/\` — omit \`--path\` to use this.
|
|
78305
|
-
|
|
78306
|
-
**Export workflow:**
|
|
78307
|
-
\`\`\`mermaid
|
|
78308
|
-
flowchart TD
|
|
78309
|
-
A([Start]) --> B["Export backlog"]
|
|
78310
|
-
B --> C["chatroom backlog export\\n(writes to <cwd>/.chatroom/exports/ by default)"]
|
|
78311
|
-
C --> D["File written: backlog-export.json"]
|
|
78312
|
-
D --> E([Done — report file path to user])
|
|
78313
|
-
\`\`\`
|
|
78314
|
-
|
|
78315
|
-
**Import workflow:**
|
|
78316
|
-
\`\`\`mermaid
|
|
78317
|
-
flowchart TD
|
|
78318
|
-
A([Start]) --> B["Import backlog"]
|
|
78319
|
-
B --> C["chatroom backlog import\\n(reads from <cwd>/.chatroom/exports/ by default)"]
|
|
78320
|
-
C --> D{Staleness warning?}
|
|
78321
|
-
D -->|Yes — export > 7 days old| E["Warn user: export may be stale"]
|
|
78322
|
-
D -->|No| F["Import items (skip duplicates)"]
|
|
78323
|
-
E --> F
|
|
78324
|
-
F --> G["Report: total / imported / skipped"]
|
|
78325
|
-
G --> H([Done])
|
|
78326
|
-
\`\`\`
|
|
78327
|
-
|
|
78328
|
-
**Key points:**
|
|
78329
|
-
- Default path is \`<cwd>/.chatroom/exports/\` — no \`--path\` needed for standard usage
|
|
78330
|
-
- Use \`--path=<dir>\` to override with a custom directory
|
|
78331
|
-
- Imports are idempotent — running import twice with the same file won't create duplicates
|
|
78332
|
-
- Each item is identified by a SHA-256 hash of its content`
|
|
78333
|
-
};
|
|
78334
77846
|
});
|
|
78335
77847
|
|
|
78336
77848
|
// ../../services/backend/src/domain/usecase/skills/modules/code-review/index.ts
|
|
78337
|
-
var
|
|
78338
|
-
var init_code_review = __esm(() => {
|
|
78339
|
-
codeReviewSkill = {
|
|
78340
|
-
skillId: "code-review",
|
|
78341
|
-
name: "Code Review",
|
|
78342
|
-
description: "Use this skill when reviewing, auditing, or giving feedback on code. Covers ten pillars: simplification, type drift, duplication, design patterns, security, test quality, ownership/observability, dead code elimination, incomplete implementations, and hallucinated content.",
|
|
78343
|
-
getPrompt: (_cliEnvPrefix) => `You have been activated with the "code-review" skill.
|
|
78344
|
-
|
|
78345
|
-
# AI Code Review — Tech Debt Prevention
|
|
78346
|
-
|
|
78347
|
-
You are reviewing code that was fully or partially generated by an AI tool. Your job is not
|
|
78348
|
-
just to check if it works — working code is the floor, not the ceiling. Your job is to assess
|
|
78349
|
-
whether it is maintainable, secure, and coherent with the broader codebase.
|
|
78350
|
-
|
|
78351
|
-
AI code is highly functional but architecturally blind. It implements the prompt without
|
|
78352
|
-
considering existing patterns, refactoring opportunities, or long-term cost. Research from
|
|
78353
|
-
2025–2026 shows AI code carries 1.75x more logic errors, 1.64x more maintainability issues,
|
|
78354
|
-
and 1.57x more security findings than human-written code (CodeRabbit, 2025). 66% of developers
|
|
78355
|
-
report spending more time fixing AI output than it saved (Stack Overflow, 2026).
|
|
78356
|
-
|
|
78357
|
-
Apply the ten pillars below in priority order.
|
|
78358
|
-
|
|
78359
|
-
---
|
|
78360
|
-
|
|
78361
|
-
## How to run a review
|
|
78362
|
-
|
|
78363
|
-
1. Read the code in full before making any comments — do not flag issues as you scan
|
|
78364
|
-
2. Apply each pillar in order; stop and note findings as you go
|
|
78365
|
-
3. Classify each finding as BLOCK (must fix before merge) or FLAG (must be addressed by author)
|
|
78366
|
-
4. Summarise findings at the end using the output template below
|
|
78367
|
-
5. If the PR is over ~300 lines of net-new AI code, recommend decomposition before review
|
|
78368
|
-
|
|
78369
|
-
---
|
|
78370
|
-
|
|
78371
|
-
## Pillar 1 — Simplification (Highest Priority)
|
|
78372
|
-
|
|
78373
|
-
AI generates more code than needed. The average developer checked in 75% more code in 2025
|
|
78374
|
-
than in 2022 — volume that the team now has to maintain. AI agents never suggest refactoring,
|
|
78375
|
-
so complexity accumulates silently.
|
|
78376
|
-
|
|
78377
|
-
Look for:
|
|
78378
|
-
- Functions over ~40 lines or classes over ~200 lines with no clear single responsibility
|
|
78379
|
-
- Monolithic architecture: 40–50% of AI code defaults to tightly-coupled structures that
|
|
78380
|
-
reverse a decade of modular progress (OX Security, 2025)
|
|
78381
|
-
- Phantom Bugs: logic handling highly improbable edge cases, adding complexity with no benefit
|
|
78382
|
-
(found in 20–30% of AI code)
|
|
78383
|
-
- Dead code, unused imports, or leftover scaffolding from generation
|
|
78384
|
-
- PRs that touch services, libraries, infrastructure, and tests in a single change
|
|
78385
|
-
|
|
78386
|
-
Ask: Is there a simpler path to the same outcome? Would a new team member understand this
|
|
78387
|
-
without help? Can this function be split without losing meaning?
|
|
78388
|
-
|
|
78389
|
-
Action: Flag any function over ~40 lines. Require decomposition or written justification
|
|
78390
|
-
before merge.
|
|
78391
|
-
|
|
78392
|
-
---
|
|
78393
|
-
|
|
78394
|
-
## Pillar 2 — Type Drift (High Priority)
|
|
78395
|
-
|
|
78396
|
-
AI generates code in isolation from the broader type system. Type inconsistencies introduced
|
|
78397
|
-
here surface later as null pointer exceptions, silent failures, and cross-service contract
|
|
78398
|
-
mismatches. A University of Naples study of 500k+ samples (Aug 2025) confirmed these are the
|
|
78399
|
-
most reliably catchable issues via static analysis — meaning they should never reach review.
|
|
78400
|
-
|
|
78401
|
-
Look for:
|
|
78402
|
-
- \`any\` usage: defeats TypeScript entirely; AI reaches for it when uncertain
|
|
78403
|
-
- Unsafe \`as\` assertions: suppresses the compiler rather than satisfying it
|
|
78404
|
-
- Missing \`strictNullChecks\` compliance — null/undefined slipping through unchecked
|
|
78405
|
-
- Boundary drift: API endpoints returning different shapes across execution paths
|
|
78406
|
-
- Configuration drift: divergent \`tsconfig\` settings or ESLint rules added incrementally
|
|
78407
|
-
- Leaked internals: AI exposing implementation details that should be encapsulated
|
|
78408
|
-
|
|
78409
|
-
Ask: Are all return types and parameters explicitly typed? Are API contract types shared and
|
|
78410
|
-
stable? Does this match existing type conventions, or introduce a new pattern?
|
|
78411
|
-
|
|
78412
|
-
Action: \`strict: true\` in \`tsconfig.json\` is a hard gate. Any PR disabling strict settings
|
|
78413
|
-
requires explicit team sign-off.
|
|
78414
|
-
|
|
78415
|
-
---
|
|
78416
|
-
|
|
78417
|
-
## Pillar 3 — Duplication (High Priority)
|
|
78418
|
-
|
|
78419
|
-
GitClear's 2025 analysis of 211 million changed lines found duplicated code blocks grew 8x
|
|
78420
|
-
in one year, and copy/pasted code surpassed refactored code for the first time in history.
|
|
78421
|
-
OX Security found "Bugs Déjà-Vu" in 70–80% of AI codebases: identical bugs recurring in
|
|
78422
|
-
multiple locations because logic was never abstracted.
|
|
78423
|
-
|
|
78424
|
-
Look for:
|
|
78425
|
-
- Duplicate utility logic across files — each instance works, but no shared abstraction exists
|
|
78426
|
-
- "Vanilla Style" rebuilds: AI reconstructing functionality from scratch instead of using
|
|
78427
|
-
existing libraries, SDKs, or internal utilities (40–50% of AI code, OX Security)
|
|
78428
|
-
- Duplicated validation, auth checks, and input sanitization
|
|
78429
|
-
- Copy-pasted try/catch blocks instead of centralised error handling
|
|
78430
|
-
- New dependencies that the existing codebase already covers
|
|
78431
|
-
|
|
78432
|
-
Ask: Does an equivalent utility already exist? Is this logic duplicated anywhere else?
|
|
78433
|
-
Use AST-level search, not just grep.
|
|
78434
|
-
|
|
78435
|
-
Action: Require a codebase search before approving any new utility function. Run SonarQube,
|
|
78436
|
-
CodeClimate, or Codacy as a PR gate for duplication thresholds.
|
|
78437
|
-
|
|
78438
|
-
---
|
|
78439
|
-
|
|
78440
|
-
## Pillar 4 — Design Pattern Compliance (Standard Priority)
|
|
78441
|
-
|
|
78442
|
-
AI implements the prompt. It does not check the ADR log, existing service patterns, or
|
|
78443
|
-
architectural conventions. OX Security identified "By-The-Book Fixation" in 80–90% of AI
|
|
78444
|
-
code: rigid application of generic best practices, missing the better solution for this
|
|
78445
|
-
specific context.
|
|
78446
|
-
|
|
78447
|
-
Look for:
|
|
78448
|
-
- Pattern violations: raw \`fetch\` where an API service layer exists; new state patterns where
|
|
78449
|
-
a store convention is already established
|
|
78450
|
-
- SOLID violations:
|
|
78451
|
-
- Single Responsibility: see Pillar 1
|
|
78452
|
-
- Open/Closed: code requiring modification rather than extension to add new behaviour
|
|
78453
|
-
- Dependency Inversion: hard-coded dependencies instead of injection
|
|
78454
|
-
- No refactoring suggestions — AI never proposes that a feature should trigger a refactor
|
|
78455
|
-
- Context blindness: ignoring ADRs, versioning strategy, or team-level conventions
|
|
78456
|
-
|
|
78457
|
-
Ask: Does this follow the patterns in this area of the codebase? Can this be extended without
|
|
78458
|
-
modification? Are dependencies injected?
|
|
78459
|
-
|
|
78460
|
-
Action: Maintain a living \`ARCHITECTURE.md\` or ADR log. Pass it as context to AI tools before
|
|
78461
|
-
generation, not after.
|
|
78462
|
-
|
|
78463
|
-
---
|
|
78464
|
-
|
|
78465
|
-
## Pillar 5 — Security (Standard Priority)
|
|
78466
|
-
|
|
78467
|
-
45% of AI-generated code samples introduced OWASP Top 10 vulnerabilities in Veracode's 2025
|
|
78468
|
-
test of 100+ LLMs. CodeRabbit found AI code is 2.74x more likely to introduce XSS, 1.88x more
|
|
78469
|
-
likely to mishandle passwords, 1.82x more likely to implement insecure deserialization.
|
|
78470
|
-
OX Security calls this "insecure by dumbness" — not malicious, but structurally blind to
|
|
78471
|
-
security requirements that were not in the prompt.
|
|
78472
|
-
|
|
78473
|
-
Look for:
|
|
78474
|
-
- OWASP Top 10: injection (SQL, XSS, command), broken auth, insecure deserialization
|
|
78475
|
-
- "Worked on My Machine" syndrome (60–70% of AI code): missing environment awareness,
|
|
78476
|
-
hard-coded localhost references, assumed-present secrets
|
|
78477
|
-
- Missing auth/ownership checks — AI assumes the happy path; role gates rarely appear unprompted
|
|
78478
|
-
- Secrets, tokens, or credentials in source code
|
|
78479
|
-
- Deprecated API patterns from the model's training data
|
|
78480
|
-
- Excessive I/O (~8x human rate) and concurrency misuse (~2x human rate)
|
|
78481
|
-
|
|
78482
|
-
Ask: Are all inputs validated before use? Are auth checks present at every trust boundary?
|
|
78483
|
-
Does this code behave differently across environments?
|
|
78484
|
-
|
|
78485
|
-
Action: Run SAST tooling (Snyk, Semgrep, SonarQube) on every AI-generated PR as a CI gate.
|
|
78486
|
-
Manual review alone cannot keep pace with AI generation velocity.
|
|
78487
|
-
|
|
78488
|
-
---
|
|
78489
|
-
|
|
78490
|
-
## Pillar 6 — Test Quality (Standard Priority)
|
|
78491
|
-
|
|
78492
|
-
AI generates tests that look comprehensive but frequently are not. OX Security found "Fake
|
|
78493
|
-
Test Coverage" in 40–50% of AI codebases: inflated metrics, low signal. The failure mode is
|
|
78494
|
-
precise: AI tests its own assumptions, not the developer's intent. University of Naples (2025)
|
|
78495
|
-
confirmed that even code passing all functional benchmarks averaged 1.45–1.77 static issues
|
|
78496
|
-
per task.
|
|
78497
|
-
|
|
78498
|
-
Look for:
|
|
78499
|
-
- Tests that verify AI output is stable, not that it is correct by domain rules
|
|
78500
|
-
- Missing edge cases: empty inputs, boundary values, null handling, race conditions,
|
|
78501
|
-
business-rule violations
|
|
78502
|
-
- Coverage theater: tests that assert no exception was thrown and nothing more
|
|
78503
|
-
- No integration or contract tests — AI generates unit tests almost exclusively
|
|
78504
|
-
- Tests coupled to implementation: must be updated every time the code changes
|
|
78505
|
-
|
|
78506
|
-
Ask: Do these tests verify the domain intent? Would they catch a logic regression in the
|
|
78507
|
-
next PR? Are cross-service interactions tested?
|
|
78508
|
-
|
|
78509
|
-
Action: Test review is a separate pass from code review. Use mutation testing (Stryker,
|
|
78510
|
-
PITest) to validate whether tests catch real defects — coverage percentage is not sufficient.
|
|
78511
|
-
|
|
78512
|
-
---
|
|
78513
|
-
|
|
78514
|
-
## Pillar 7 — Ownership, Observability, Deployment (Standard Priority)
|
|
78515
|
-
|
|
78516
|
-
The most consistently missed category. ISACA's 2026 incident review found that the biggest
|
|
78517
|
-
AI failures of 2025 were organisational, not technical: weak controls and unclear ownership.
|
|
78518
|
-
Bright Security (2026) identified unclear ownership as one of the most dangerous patterns:
|
|
78519
|
-
code that works well enough that no one feels responsible for it. IBM's 2025 breach data found
|
|
78520
|
-
shadow AI added $670,000 average to breach costs.
|
|
78521
|
-
|
|
78522
|
-
Look for:
|
|
78523
|
-
- No named human owner — every AI-generated module needs someone who can explain it in a
|
|
78524
|
-
postmortem without reading it fresh
|
|
78525
|
-
- Missing structured logs, metrics emission, or tracing hooks
|
|
78526
|
-
- Swallowed exceptions: retry logic with no alerting; fallback paths invisible to operators
|
|
78527
|
-
- No environment-specific configuration, secrets management, or health check endpoints
|
|
78528
|
-
- Model versioning chaos: inconsistencies from team members using different AI tool versions
|
|
78529
|
-
- Shadow AI: code with no record of which tool or prompt produced it
|
|
78530
|
-
|
|
78531
|
-
Ask: Who owns this? Will production failures surface to operators? Does this behave
|
|
78532
|
-
differently across environments?
|
|
78533
|
-
|
|
78534
|
-
Action: Require every AI-generated module to have a named owner in CODEOWNERS. Add logging
|
|
78535
|
-
requirements to the PR template. Establish a team AI governance policy that tracks tools
|
|
78536
|
-
and model versions — treat this like any other dependency.
|
|
78537
|
-
|
|
78538
|
-
---
|
|
78539
|
-
|
|
78540
|
-
## Pillar 8 — Dead Code Elimination (Standard Priority)
|
|
78541
|
-
|
|
78542
|
-
AI generates code speculatively. It adds helper functions "just in case", creates abstractions
|
|
78543
|
-
for paths that never materialise, and leaves behind scaffolding from earlier generation
|
|
78544
|
-
attempts. GitClear's 2025 data showed a 75% increase in total code volume, much of it never
|
|
78545
|
-
executed. Dead code is not harmless — it misleads future readers, inflates bundle sizes, creates
|
|
78546
|
-
false positive search results, and adds surface area for bugs and security vulnerabilities
|
|
78547
|
-
in code that serves no purpose.
|
|
78548
|
-
|
|
78549
|
-
Look for:
|
|
78550
|
-
- Unreachable code: functions, methods, or branches that no call site ever invokes
|
|
78551
|
-
- Unused imports: modules imported but never referenced — common in AI-generated files
|
|
78552
|
-
- Commented-out code: old implementations left inline instead of being removed; version
|
|
78553
|
-
control already preserves history
|
|
78554
|
-
- Feature flags that are permanently off: conditional paths that were never enabled or have
|
|
78555
|
-
been superseded but not cleaned up
|
|
78556
|
-
- Orphaned configuration: environment variables, constants, or config entries with no consumer
|
|
78557
|
-
- Stale types and interfaces: type definitions for data shapes that no longer exist in the
|
|
78558
|
-
system
|
|
78559
|
-
- Unused dependencies: packages listed in \`package.json\` (or equivalent) that no source file
|
|
78560
|
-
imports
|
|
78561
|
-
- Vestigial error handling: catch blocks or fallback paths for conditions that can no longer
|
|
78562
|
-
occur due to upstream changes
|
|
78563
|
-
- Test helpers and fixtures for tests that have been deleted
|
|
78564
|
-
|
|
78565
|
-
Ask: Is every function called? Is every import used? Is every dependency exercised?
|
|
78566
|
-
Would removing this code change any observable behaviour?
|
|
78567
|
-
|
|
78568
|
-
Action: Run tree-shaking analysis and dead code detection tools (e.g., \`ts-prune\`,
|
|
78569
|
-
\`knip\`, \`depcheck\`, IDE unused-symbol highlighting) as part of CI. Treat dead code
|
|
78570
|
-
the same as duplication — it compounds over time and must be actively managed.
|
|
78571
|
-
|
|
78572
|
-
---
|
|
78573
|
-
|
|
78574
|
-
## Pillar 9 — Incomplete Implementations (Standard Priority)
|
|
78575
|
-
|
|
78576
|
-
AI tools often leave TODOs, stubs, "throw new Error('not implemented')", or placeholder
|
|
78577
|
-
returns when they hit uncertainty. The default assumption MUST be that these are bugs to fix,
|
|
78578
|
-
not features — unless the human explicitly requested a stub (e.g., scaffolding a future module).
|
|
78579
|
-
|
|
78580
|
-
Look for:
|
|
78581
|
-
- \`TODO\`, \`FIXME\`, \`XXX\`, \`HACK\` comments — especially without an assignee or ticket reference
|
|
78582
|
-
- Functions that throw "not implemented" / "unimplemented" errors
|
|
78583
|
-
- Empty function bodies or bodies that only return null/undefined/empty object as a placeholder
|
|
78584
|
-
- Switch/case branches with \`// handle later\` style comments
|
|
78585
|
-
- Conditional branches that silently fall through without handling a real case
|
|
78586
|
-
- Type definitions with fields marked \`any\` or \`unknown\` "to be refined later"
|
|
78587
|
-
- Tests with \`it.skip\`, \`xit\`, \`it.todo\` left in committed code without justification
|
|
78588
|
-
|
|
78589
|
-
Ask: Is every code path fully implemented? If a TODO exists, is there a tracked ticket and
|
|
78590
|
-
explicit reason it wasn't done now?
|
|
78591
|
-
|
|
78592
|
-
Action: Treat any TODO or stub as BLOCK unless the PR description or commit message explicitly
|
|
78593
|
-
justifies it (e.g., "scaffolding for follow-up PR #N"). Generated code with unprompted TODOs
|
|
78594
|
-
should be completed before merge, not after.
|
|
78595
|
-
|
|
78596
|
-
---
|
|
78597
|
-
|
|
78598
|
-
## Pillar 10 — Hallucinated Content & Magic Strings (Standard Priority)
|
|
78599
|
-
|
|
78600
|
-
AI generation frequently invents plausible-looking but incorrect values — API endpoints,
|
|
78601
|
-
env var names, library functions, config keys — and scatters magic strings/numbers across
|
|
78602
|
-
the codebase instead of consolidating them as named constants. Both fail at runtime or rot
|
|
78603
|
-
the codebase over time.
|
|
78604
|
-
|
|
78605
|
-
Look for:
|
|
78606
|
-
- Fabricated API endpoints, library functions, or package names that don't exist (verify against
|
|
78607
|
-
actual SDK docs / \`package.json\`)
|
|
78608
|
-
- Magic strings: status codes, role names, event types, feature flag keys appearing as inline
|
|
78609
|
-
literals across multiple files
|
|
78610
|
-
- Magic numbers: timeouts, limits, retry counts, port numbers without named constants
|
|
78611
|
-
- Placeholder content left in production paths: "lorem ipsum", "foo/bar", "example.com",
|
|
78612
|
-
"test@test.com"
|
|
78613
|
-
- Hardcoded URLs, file paths, or table/collection names that should come from config
|
|
78614
|
-
- Duplicated string literals that should be a single enum / const object
|
|
78615
|
-
- Configuration keys invented by the AI that don't match the project's actual config schema
|
|
78616
|
-
|
|
78617
|
-
Ask: Does every literal that carries domain meaning have a named home? Is every external
|
|
78618
|
-
reference (API, package, env var) verified to exist? Where SHOULD this constant live (entity
|
|
78619
|
-
enum, config module, shared constants file)?
|
|
78620
|
-
|
|
78621
|
-
Action: Consolidate magic literals into the canonical location for the codebase (typically
|
|
78622
|
-
enums alongside the relevant entity, or a dedicated constants module). For hallucinated
|
|
78623
|
-
references, treat as BLOCK — code that compiles against fictional APIs will fail in production.
|
|
78624
|
-
|
|
78625
|
-
---
|
|
78626
|
-
|
|
78627
|
-
## Output template
|
|
78628
|
-
|
|
78629
|
-
Use this format for every review. Do not skip sections.
|
|
78630
|
-
|
|
78631
|
-
\`\`\`
|
|
78632
|
-
## AI Code Review — [filename or PR title]
|
|
78633
|
-
|
|
78634
|
-
### Summary
|
|
78635
|
-
[2–3 sentences: overall quality signal, highest-risk area, recommended action]
|
|
78636
|
-
|
|
78637
|
-
### BLOCK — must fix before merge
|
|
78638
|
-
[List findings. Format: PILLAR | finding | why it matters | suggested fix]
|
|
78639
|
-
|
|
78640
|
-
### FLAG — author must respond
|
|
78641
|
-
[List findings. Same format.]
|
|
78642
|
-
|
|
78643
|
-
### Passed
|
|
78644
|
-
[Pillars or areas with no significant findings]
|
|
78645
|
-
|
|
78646
|
-
### Recommendation
|
|
78647
|
-
[ ] Approve [ ] Approve with flags addressed [ ] Decompose PR first [ ] Reject — rework required
|
|
78648
|
-
\`\`\``
|
|
78649
|
-
};
|
|
78650
|
-
});
|
|
77849
|
+
var init_code_review = () => {};
|
|
78651
77850
|
|
|
78652
77851
|
// ../../services/backend/src/domain/usecase/skills/registry.ts
|
|
78653
|
-
var SKILLS_REGISTRY;
|
|
78654
77852
|
var init_registry3 = __esm(() => {
|
|
78655
77853
|
init_backlog();
|
|
78656
77854
|
init_code_review();
|
|
78657
|
-
SKILLS_REGISTRY = [backlogSkill, codeReviewSkill];
|
|
78658
77855
|
});
|
|
78659
77856
|
|
|
78660
77857
|
// ../../services/backend/prompts/sections/glossary.ts
|
|
78661
|
-
function formatGlossaryEntry(entry) {
|
|
78662
|
-
const skillNote = entry.linkedSkillId ? " (1 skill available)" : "";
|
|
78663
|
-
return [`- \`${entry.term}\`${skillNote}`, ` - ${entry.definition}`, ""];
|
|
78664
|
-
}
|
|
78665
|
-
function buildSkillsSection(cliEnvPrefix) {
|
|
78666
|
-
const lines = ["# Skills", ""];
|
|
78667
|
-
lines.push(`Run \`${cliEnvPrefix}chatroom skill list --chatroom-id=<id> --role=<role>\` to list all available skills.`);
|
|
78668
|
-
lines.push("");
|
|
78669
|
-
lines.push("## When to Activate Skills");
|
|
78670
|
-
lines.push("");
|
|
78671
|
-
lines.push("**Proactively activate skills** when your task matches their purpose:");
|
|
78672
|
-
for (const skill of SKILLS_REGISTRY) {
|
|
78673
|
-
lines.push(`- **${skill.skillId}**: ${skill.description}`);
|
|
78674
|
-
}
|
|
78675
|
-
lines.push("");
|
|
78676
|
-
lines.push("Don't wait for the user to ask — proactively activate the skill that matches the task.");
|
|
78677
|
-
return lines;
|
|
78678
|
-
}
|
|
78679
|
-
function getGlossarySection(params) {
|
|
78680
|
-
const cliEnvPrefix = getCliEnvPrefix(params.convexUrl);
|
|
78681
|
-
const lines = ["# Glossary", ""];
|
|
78682
|
-
const terms = params.nativeIntegration ? NATIVE_GLOSSARY_TERMS : GLOSSARY_TERMS;
|
|
78683
|
-
for (const entry of terms) {
|
|
78684
|
-
lines.push(...formatGlossaryEntry(entry));
|
|
78685
|
-
}
|
|
78686
|
-
if (params.compactSkills) {
|
|
78687
|
-
lines.push("# Skills", "");
|
|
78688
|
-
lines.push(`Run \`${cliEnvPrefix}chatroom skill list --chatroom-id=<id> --role=<role>\` to list available skills. Activate skills proactively when your task matches their purpose.`);
|
|
78689
|
-
} else {
|
|
78690
|
-
lines.push(...buildSkillsSection(cliEnvPrefix));
|
|
78691
|
-
}
|
|
78692
|
-
return createSection("glossary", "knowledge", lines.join(`
|
|
78693
|
-
`));
|
|
78694
|
-
}
|
|
78695
77858
|
var GLOSSARY_TERMS, NATIVE_GLOSSARY_TERMS;
|
|
78696
77859
|
var init_glossary = __esm(() => {
|
|
78697
77860
|
init_registry3();
|
|
@@ -78742,257 +77905,10 @@ var init_glossary = __esm(() => {
|
|
|
78742
77905
|
});
|
|
78743
77906
|
|
|
78744
77907
|
// ../../services/backend/prompts/cli/roles/builder.ts
|
|
78745
|
-
function getBuilderFlowMermaid(nativeIntegration, codeChangesTarget, questionTarget) {
|
|
78746
|
-
const handoffNodes = ` D --> E[Commit work]
|
|
78747
|
-
E --> F{Code changes?}
|
|
78748
|
-
F -->|yes| G[Hand off to **${codeChangesTarget}**]
|
|
78749
|
-
F -->|no| H[Hand off to **${questionTarget}**]`;
|
|
78750
|
-
if (nativeIntegration) {
|
|
78751
|
-
return `flowchart TD
|
|
78752
|
-
A([Start]) --> B[Receive task]
|
|
78753
|
-
B --> D[Implement changes]
|
|
78754
|
-
${handoffNodes}`;
|
|
78755
|
-
}
|
|
78756
|
-
return `flowchart TD
|
|
78757
|
-
A([Start]) --> B[Receive chatroom task]
|
|
78758
|
-
B --> D[Implement changes]
|
|
78759
|
-
${handoffNodes}`;
|
|
78760
|
-
}
|
|
78761
|
-
function getBuilderGuidance(params) {
|
|
78762
|
-
const {
|
|
78763
|
-
questionTarget: questionTargetParam,
|
|
78764
|
-
codeChangesTarget: codeChangesTargetParam,
|
|
78765
|
-
nativeIntegration
|
|
78766
|
-
} = params;
|
|
78767
|
-
const questionTarget = questionTargetParam ?? "user";
|
|
78768
|
-
const codeChangesTarget = codeChangesTargetParam ?? "planner";
|
|
78769
|
-
return `
|
|
78770
|
-
## Builder Operating Model
|
|
78771
|
-
|
|
78772
|
-
${getSessionContinuityLine(nativeIntegration)}
|
|
78773
|
-
|
|
78774
|
-
You are responsible for implementing code changes based on requirements.
|
|
78775
|
-
|
|
78776
|
-
**Typical Flow:**
|
|
78777
|
-
|
|
78778
|
-
\`\`\`mermaid
|
|
78779
|
-
${getBuilderFlowMermaid(nativeIntegration, codeChangesTarget, questionTarget)}
|
|
78780
|
-
\`\`\`
|
|
78781
|
-
|
|
78782
|
-
**Handoff Rules:**
|
|
78783
|
-
- **After code changes** → Hand off to \`${codeChangesTarget}\`
|
|
78784
|
-
- **For simple questions** → Can hand off directly to \`${questionTarget}\`
|
|
78785
|
-
⚠️ If \`${questionTarget}\` is the user: the user can ONLY see the handoff-to-user message — progress reports and all other messages are invisible to them. Write the handoff as a complete, self-contained document: include all relevant context, results, and next steps without assuming the user read any prior conversation.
|
|
78786
|
-
|
|
78787
|
-
**Implementation Guidelines:**
|
|
78788
|
-
- Write clean, maintainable, well-documented code
|
|
78789
|
-
- Follow established patterns and best practices from the codebase
|
|
78790
|
-
- Handle edge cases and error scenarios
|
|
78791
|
-
- Commit work with descriptive, atomic commit messages
|
|
78792
|
-
|
|
78793
|
-
**Completion gates (before PR or handoff):**
|
|
78794
|
-
- All **(Required)** files done; **verified end-to-end** (user-facing entry point works: CLI command runnable, API reachable, or UI action functional)
|
|
78795
|
-
- If blocked → ## Blockers / questions to planner. No PR or \`mark-for-review\` until gates pass — unless the user explicitly requested a draft or incremental PR
|
|
78796
|
-
`;
|
|
78797
|
-
}
|
|
78798
77908
|
var init_builder = () => {};
|
|
78799
|
-
|
|
78800
|
-
// ../../services/backend/prompts/cli/sections/core-responsibilities.ts
|
|
78801
|
-
function getCoreResponsibilitiesSection(config3) {
|
|
78802
|
-
const qualityLine = config3.hasBuilder ? "If the user's requirements are not met, hand work back to the builder for rework." : "If the work doesn't meet requirements, revise it yourself before delivering.";
|
|
78803
|
-
return `**Core Responsibilities:**
|
|
78804
|
-
- **User Communication**: You are the ONLY role that communicates with the user. All responses to the user come through you.
|
|
78805
|
-
- **Handoff completeness**: The user can ONLY see the final handoff-to-\`user\` message. Write it as a complete, standalone document — do not reference prior messages or assume the user has context from earlier session text.
|
|
78806
|
-
- **Quality Accountability**: You are ultimately accountable for all work. ${qualityLine}`;
|
|
78807
|
-
}
|
|
78808
|
-
|
|
78809
|
-
// ../../services/backend/prompts/cli/sections/delegation-and-decomposition.ts
|
|
78810
|
-
function getDelegationAndDecompositionSection(config3) {
|
|
78811
|
-
if (!config3.hasBuilder) {
|
|
78812
|
-
return "";
|
|
78813
|
-
}
|
|
78814
|
-
return `**Delegation & Decomposition:**
|
|
78815
|
-
|
|
78816
|
-
Any task that requires code changes must be delegated to the builder — break it into small, focused slices and delegate them one at a time using a **Delegation Brief** (see **Delegation Guidelines** below).`;
|
|
78817
|
-
}
|
|
78818
|
-
|
|
78819
|
-
// ../../services/backend/prompts/cli/sections/delegation-guidelines.ts
|
|
78820
|
-
function buildCmdHelper(cliEnvPrefix, chatroomIdArg, roleArg) {
|
|
78821
|
-
return (subcommand) => `\`${cliEnvPrefix}chatroom ${subcommand} --chatroom-id=${chatroomIdArg} --role=${roleArg}\``;
|
|
78822
|
-
}
|
|
78823
|
-
function getDelegationBriefReference() {
|
|
78824
|
-
return "Use the **Handoff to `builder`** template in the task delivery `<handoff-templates>` section — follow that structure in your handoff message.";
|
|
78825
|
-
}
|
|
78826
|
-
function getSoloImplementationGuidelines(cmd, feedingNote) {
|
|
78827
|
-
return `**Implementation Guidelines:**
|
|
78828
|
-
|
|
78829
|
-
Break complex features into small, focused slices. For code review guidance, activate the \`code-review\` skill: ${cmd("skill activate code-review")}.
|
|
78830
|
-
|
|
78831
|
-
- Implement one slice at a time; each slice ≈ one focused review surface.
|
|
78832
|
-
- Review your own work before moving on; re-validate after rework.
|
|
78833
|
-
- ${feedingNote}.`;
|
|
78834
|
-
}
|
|
78835
|
-
function getBuilderDelegationGuidelines(cmd, feedingNote, delegationBriefRef) {
|
|
78836
|
-
return `**Delegation Guidelines:**
|
|
78837
|
-
|
|
78838
|
-
Break features into small, focused slices, then delegate them to the builder one at a time. For code review guidance, activate the \`code-review\` skill: ${cmd("skill activate code-review")}.
|
|
78839
|
-
|
|
78840
|
-
**Delegation rule:** If the task requires **any code changes** (new files, edits, deletions), you **must delegate to the builder** — regardless of how small the change is.
|
|
78841
|
-
|
|
78842
|
-
**Decision flow:**
|
|
78843
|
-
\`\`\`mermaid
|
|
78844
|
-
flowchart TD
|
|
78845
|
-
A[Receive task] --> B{Code changes needed?}
|
|
78846
|
-
B -->|Yes — any size| D[Write a Delegation Brief]
|
|
78847
|
-
D --> E[Hand off ONE slice to builder]
|
|
78848
|
-
E --> F[Review output]
|
|
78849
|
-
F -->|Not acceptable| G[Hand back with feedback]
|
|
78850
|
-
G --> E
|
|
78851
|
-
F -->|Acceptable| H{More slices?}
|
|
78852
|
-
H -->|Yes| E
|
|
78853
|
-
H -->|No| I[Deliver to user]
|
|
78854
|
-
B -->|No: question or clarification only| C[Answer directly → deliver to user]
|
|
78855
|
-
\`\`\`
|
|
78856
|
-
|
|
78857
|
-
**Default: delegate with a Delegation Brief.** ${delegationBriefRef}
|
|
78858
|
-
|
|
78859
|
-
**How to slice the work** — think about the phases a human engineer would actually go through to ship the work, then make each phase a slice. Some heuristics:
|
|
78860
|
-
|
|
78861
|
-
- **Each slice should name a concrete artifact** ("the X schema", "the Y entity", "the Z endpoint") — not a vague layer ("backend work", "implementation"). Weak builders fail when scope is unbounded.
|
|
78862
|
-
- **File-level detail, zero ambiguity.** List every file (full paths) and paste snippets until the builder cannot guess wrong — not vague layers ("backend work", "the component").
|
|
78863
|
-
- **You own technical design; the builder executes.** Per-file target code plus shared contracts in the brief — do not leave API shape for the builder to invent.
|
|
78864
|
-
- **Spell out what to avoid** — anti-patterns and recurring mistakes you have seen from builders on similar work (scope creep, wrong abstractions, forbidden refactors).
|
|
78865
|
-
- **One slice ≈ one focused review surface.** If you can't imagine reviewing it in one sitting, split it.
|
|
78866
|
-
- **Order by dependency**, not by team convention. A slice should be runnable/testable when its dependencies are done.
|
|
78867
|
-
- **A slice is shippable only when verified end-to-end** — infra/helper files alone are not a complete slice.
|
|
78868
|
-
- **Skip phases that don't apply** (e.g., no frontend for a backend-only change, no schema for a pure refactor).
|
|
78869
|
-
|
|
78870
|
-
**Code review:** For code-producing work, review before delivering. Activate the review framework with: ${cmd("skill activate code-review")}.
|
|
78871
|
-
|
|
78872
|
-
**Backlog items:** When the task originates from a backlog item, activate the backlog skill: ${cmd("skill activate backlog")}.
|
|
78873
|
-
|
|
78874
|
-
**If stuck:** After 2 failed rework attempts → replan or hand back to planner as blocked. No partial PR, \`mark-for-review\`, or user delivery.
|
|
78875
|
-
|
|
78876
|
-
**Review loop:**
|
|
78877
|
-
- Review completed work before moving to the next slice.
|
|
78878
|
-
- Send back with specific feedback if requirements aren't met.
|
|
78879
|
-
- ${feedingNote}.
|
|
78880
|
-
|
|
78881
|
-
**When enhancement is enabled:** See \`<handoff-enhancer>\` in task delivery — one check-in per delegation before builder.`;
|
|
78882
|
-
}
|
|
78883
|
-
function getDelegationGuidelinesSection(config3, options) {
|
|
78884
|
-
const feedingNote = config3.hasBuilder ? "Feed slices to the builder incrementally — one at a time, not all at once" : "When implementing yourself, tackle one layer at a time — avoid large monolithic changes";
|
|
78885
|
-
const cliEnvPrefix = options?.cliEnvPrefix ?? "";
|
|
78886
|
-
const chatroomIdArg = options?.chatroomId ? `"${options.chatroomId}"` : "<id>";
|
|
78887
|
-
const roleArg = options?.role ? `"${options.role}"` : "<role>";
|
|
78888
|
-
const cmd = buildCmdHelper(cliEnvPrefix, chatroomIdArg, roleArg);
|
|
78889
|
-
if (!config3.hasBuilder) {
|
|
78890
|
-
return getSoloImplementationGuidelines(cmd, feedingNote);
|
|
78891
|
-
}
|
|
78892
|
-
return getBuilderDelegationGuidelines(cmd, feedingNote, getDelegationBriefReference());
|
|
78893
|
-
}
|
|
78894
|
-
|
|
78895
77909
|
// ../../services/backend/prompts/cli/sections/handoff-rules.ts
|
|
78896
|
-
function buildHandoffRuleLines(config3) {
|
|
78897
|
-
return [
|
|
78898
|
-
config3.hasBuilder ? "- **To delegate implementation** → Hand off to `builder` with clear requirements" : "- **To implement** → Work on the chatroom task directly (you are acting as implementer)",
|
|
78899
|
-
config3.hasBuilder ? "- **When enhancement is enabled** → See `<handoff-enhancer>` in task delivery before each builder delegation" : null,
|
|
78900
|
-
"- **To deliver to user** → Hand off to `user` with a complete, standalone summary\n ⚠️ The user can ONLY see the handoff-to-user message — progress reports and all other messages are invisible to them. Write the handoff as a self-contained document: include all relevant context, results, and next steps without assuming the user read any prior conversation.",
|
|
78901
|
-
config3.hasBuilder ? "- **For rework** → Hand off back to `builder` with specific feedback on what needs to change" : "- **For rework** → Revise your implementation directly and re-validate"
|
|
78902
|
-
].filter((line) => line !== null).join(`
|
|
78903
|
-
`);
|
|
78904
|
-
}
|
|
78905
|
-
function getHandoffRulesSection(config3, nativeIntegration) {
|
|
78906
|
-
const continuityRule = getHandoffContinuityRule(nativeIntegration);
|
|
78907
|
-
const continuityBlock = continuityRule ? `${continuityRule}
|
|
78908
|
-
|
|
78909
|
-
` : "";
|
|
78910
|
-
return `**Handoff Rules:**
|
|
78911
|
-
|
|
78912
|
-
${continuityBlock}${buildHandoffRuleLines(config3)}`;
|
|
78913
|
-
}
|
|
78914
77910
|
var init_handoff_rules = () => {};
|
|
78915
|
-
|
|
78916
|
-
// ../../services/backend/prompts/cli/sections/when-work-comes-back.ts
|
|
78917
|
-
function getWhenWorkComesBackSection(config3) {
|
|
78918
|
-
const reworkLine = config3.hasBuilder ? "3. If requirements are NOT met (including partial work) → hand back to `builder` for rework" : "3. If requirements are NOT met (including partial work) → revise and re-validate";
|
|
78919
|
-
return `**When you receive work back from team members:**
|
|
78920
|
-
1. Review the completed work against the original user request
|
|
78921
|
-
2. If requirements are met → deliver to \`user\`
|
|
78922
|
-
${reworkLine}
|
|
78923
|
-
4. **No ceremonial handoffs** — never hand back just to acknowledge, thank, or echo receipt. A handback to the sender is only valid when it carries concrete rework feedback (step 3). Handoffs to \`user\` are reserved for the final deliverable from the entry-point role.`;
|
|
78924
|
-
}
|
|
78925
|
-
|
|
78926
|
-
// ../../services/backend/prompts/cli/sections/team-composition.ts
|
|
78927
|
-
function getTeamCompositionSection(teamMembers) {
|
|
78928
|
-
const isSoloRole = teamMembers.length === 1 && teamMembers[0]?.toLowerCase() === "solo";
|
|
78929
|
-
const nonPlannerMembers = teamMembers.filter((r) => r.toLowerCase() !== "planner");
|
|
78930
|
-
if (isSoloRole || nonPlannerMembers.length === 0) {
|
|
78931
|
-
return `**Team composition:** Solo team — you handle planning and implementation yourself.`;
|
|
78932
|
-
}
|
|
78933
|
-
const roleList = nonPlannerMembers.map((r) => `\`${r}\``).join(", ");
|
|
78934
|
-
return `**Team composition:** Duo team — you coordinate with ${roleList} for implementation.
|
|
78935
|
-
|
|
78936
|
-
**Agent presence:** This prompt does **not** tell you who is online. Other agents may be offline. Delegate code-changing work by handing off when appropriate; do not infer availability from team configuration or prior chat history.`;
|
|
78937
|
-
}
|
|
78938
|
-
|
|
78939
77911
|
// ../../services/backend/prompts/cli/sections/operating-model.ts
|
|
78940
|
-
function getTaskIntakeNodes(nativeIntegration) {
|
|
78941
|
-
if (nativeIntegration) {
|
|
78942
|
-
return ` A([Start]) --> B[Receive user message]
|
|
78943
|
-
B --> E[Decompose into phases]`;
|
|
78944
|
-
}
|
|
78945
|
-
return ` A([Start]) --> B[Receive chatroom task from get-next-task]
|
|
78946
|
-
B --> E[Decompose into phases]`;
|
|
78947
|
-
}
|
|
78948
|
-
function getOperatingModelSection(config3, nativeIntegration) {
|
|
78949
|
-
if (config3.hasBuilder) {
|
|
78950
|
-
return getPlannerPlusBuilderOperatingModel(nativeIntegration);
|
|
78951
|
-
}
|
|
78952
|
-
return getPlannerSoloOperatingModel(nativeIntegration);
|
|
78953
|
-
}
|
|
78954
|
-
function getPlannerPlusBuilderOperatingModel(nativeIntegration) {
|
|
78955
|
-
const footer = getOperatingModelLoopFooter(nativeIntegration);
|
|
78956
|
-
const delegationNote = nativeIntegration ? getNativePlannerDelegationWaitNote() : "After delegating to the builder, hand off and wait for work to return.";
|
|
78957
|
-
return `**Operating model: Planner + Builder**
|
|
78958
|
-
|
|
78959
|
-
${delegationNote}
|
|
78960
|
-
|
|
78961
|
-
\`\`\`mermaid
|
|
78962
|
-
flowchart TD
|
|
78963
|
-
${getTaskIntakeNodes(nativeIntegration)}
|
|
78964
|
-
E --> F[Delegate ONE phase to builder]
|
|
78965
|
-
F --> G[Builder completes phase]
|
|
78966
|
-
G --> H[Builder hands off to planner]
|
|
78967
|
-
H --> I[Review builder output]
|
|
78968
|
-
I --> J{phase acceptable?}
|
|
78969
|
-
J -->|no| K[Hand back to builder with feedback]
|
|
78970
|
-
K --> F
|
|
78971
|
-
J -->|yes| L{more phases?}
|
|
78972
|
-
L -->|yes| F
|
|
78973
|
-
L -->|no| O[Deliver final result to user]
|
|
78974
|
-
O --> P[${footer}] --> B
|
|
78975
|
-
\`\`\``;
|
|
78976
|
-
}
|
|
78977
|
-
function getPlannerSoloOperatingModel(nativeIntegration) {
|
|
78978
|
-
const continueStep = nativeIntegration ? "Hand off when complete" : "Run `get-next-task` to continue the session (Level A continues after Level B completes)";
|
|
78979
|
-
const intakeSteps = nativeIntegration ? `1. Receive user message
|
|
78980
|
-
2. Plan and implement` : `1. Receive chatroom task from get-next-task
|
|
78981
|
-
2. Plan and implement`;
|
|
78982
|
-
if (nativeIntegration) {
|
|
78983
|
-
return `**Operating model: Planner Solo**
|
|
78984
|
-
|
|
78985
|
-
${intakeSteps}
|
|
78986
|
-
3. Deliver to **user**
|
|
78987
|
-
4. ${continueStep}`;
|
|
78988
|
-
}
|
|
78989
|
-
return `**Operating model: Planner Solo**
|
|
78990
|
-
|
|
78991
|
-
${intakeSteps}
|
|
78992
|
-
3. Review your own work for quality
|
|
78993
|
-
4. Deliver to **user**
|
|
78994
|
-
5. ${continueStep}`;
|
|
78995
|
-
}
|
|
78996
77912
|
var init_operating_model = () => {};
|
|
78997
77913
|
|
|
78998
77914
|
// ../../services/backend/prompts/cli/sections/index.ts
|
|
@@ -79002,126 +77918,17 @@ var init_sections = __esm(() => {
|
|
|
79002
77918
|
});
|
|
79003
77919
|
|
|
79004
77920
|
// ../../services/backend/prompts/cli/roles/planner.ts
|
|
79005
|
-
function getPlannerGuidance(params) {
|
|
79006
|
-
const { convexUrl, teamRoles, chatroomId, role, nativeIntegration } = params;
|
|
79007
|
-
const cliEnvPrefix = getCliEnvPrefix(convexUrl);
|
|
79008
|
-
const members = teamRoles;
|
|
79009
|
-
const hasBuilder = members.some((r) => r.toLowerCase() === "builder");
|
|
79010
|
-
const teamConfig = { hasBuilder };
|
|
79011
|
-
return `## Planner Operating Model
|
|
79012
|
-
|
|
79013
|
-
${getSessionContinuityLine(nativeIntegration)}
|
|
79014
|
-
|
|
79015
|
-
You are the team coordinator and the **single point of contact** for the user.
|
|
79016
|
-
|
|
79017
|
-
${getTeamCompositionSection(members)}
|
|
79018
|
-
|
|
79019
|
-
${getOperatingModelSection(teamConfig, nativeIntegration)}
|
|
79020
|
-
|
|
79021
|
-
${getCoreResponsibilitiesSection(teamConfig)}
|
|
79022
|
-
|
|
79023
|
-
${getDelegationAndDecompositionSection(teamConfig)}
|
|
79024
|
-
|
|
79025
|
-
${getDelegationGuidelinesSection(teamConfig, { cliEnvPrefix, chatroomId, role })}
|
|
79026
|
-
|
|
79027
|
-
${getHandoffRulesSection(teamConfig, nativeIntegration)}
|
|
79028
|
-
|
|
79029
|
-
${getWhenWorkComesBackSection(teamConfig)}`;
|
|
79030
|
-
}
|
|
79031
77921
|
var init_planner = __esm(() => {
|
|
79032
77922
|
init_env();
|
|
79033
77923
|
init_sections();
|
|
79034
77924
|
});
|
|
79035
77925
|
|
|
79036
77926
|
// ../../services/backend/prompts/teams/solo/prompts/solo.ts
|
|
79037
|
-
function getSoloGuidance(ctx) {
|
|
79038
|
-
const { teamRoles, nativeIntegration } = ctx;
|
|
79039
|
-
return `## Solo Operating Model
|
|
79040
|
-
|
|
79041
|
-
${getSessionContinuityLine(nativeIntegration)}
|
|
79042
|
-
|
|
79043
|
-
You are an autonomous agent responsible for BOTH planning and implementing chatroom tasks independently.
|
|
79044
|
-
|
|
79045
|
-
**Solo Team Context:**
|
|
79046
|
-
- You are the ONLY team member — you plan, implement, and deliver
|
|
79047
|
-
- You communicate directly with the user (single point of contact)
|
|
79048
|
-
- There is no separate builder or planner — you fill all roles
|
|
79049
|
-
- You hand off directly to the user when work is complete
|
|
79050
|
-
|
|
79051
|
-
${getTeamCompositionSection(teamRoles)}
|
|
79052
|
-
|
|
79053
|
-
${getPlannerSoloOperatingModel(nativeIntegration)}
|
|
79054
|
-
|
|
79055
|
-
${getCoreResponsibilitiesSection(SOLO_TEAM_CONFIG)}
|
|
79056
|
-
|
|
79057
|
-
**Implementation Guidelines:**
|
|
79058
|
-
- Write clean, maintainable, well-documented code
|
|
79059
|
-
- Follow established patterns and best practices from the codebase
|
|
79060
|
-
- Handle edge cases and error scenarios
|
|
79061
|
-
- Commit work with descriptive, atomic commit messages
|
|
79062
|
-
|
|
79063
|
-
${getHandoffRulesSection(SOLO_TEAM_CONFIG, nativeIntegration)}
|
|
79064
|
-
|
|
79065
|
-
${getWhenWorkComesBackSection(SOLO_TEAM_CONFIG)}`;
|
|
79066
|
-
}
|
|
79067
|
-
var SOLO_TEAM_CONFIG;
|
|
79068
77927
|
var init_solo = __esm(() => {
|
|
79069
77928
|
init_sections();
|
|
79070
|
-
SOLO_TEAM_CONFIG = { hasBuilder: false };
|
|
79071
77929
|
});
|
|
79072
77930
|
|
|
79073
77931
|
// ../../services/backend/prompts/cli/roles/fromContext.ts
|
|
79074
|
-
function toBuilderParams(ctx) {
|
|
79075
|
-
return {
|
|
79076
|
-
role: ctx.role,
|
|
79077
|
-
teamRoles: ctx.teamRoles,
|
|
79078
|
-
isEntryPoint: ctx.isEntryPoint,
|
|
79079
|
-
convexUrl: ctx.convexUrl,
|
|
79080
|
-
nativeIntegration: ctx.nativeIntegration
|
|
79081
|
-
};
|
|
79082
|
-
}
|
|
79083
|
-
function toPlannerParams(ctx) {
|
|
79084
|
-
return {
|
|
79085
|
-
role: ctx.role,
|
|
79086
|
-
teamRoles: ctx.teamRoles,
|
|
79087
|
-
isEntryPoint: ctx.isEntryPoint,
|
|
79088
|
-
convexUrl: ctx.convexUrl,
|
|
79089
|
-
chatroomId: ctx.chatroomId,
|
|
79090
|
-
nativeIntegration: ctx.nativeIntegration
|
|
79091
|
-
};
|
|
79092
|
-
}
|
|
79093
|
-
function getBaseBuilderGuidanceFromContext(ctx) {
|
|
79094
|
-
return getBuilderGuidance(toBuilderParams(ctx));
|
|
79095
|
-
}
|
|
79096
|
-
function toSoloParams(ctx) {
|
|
79097
|
-
return {
|
|
79098
|
-
role: ctx.role,
|
|
79099
|
-
teamRoles: ctx.teamRoles,
|
|
79100
|
-
isEntryPoint: ctx.isEntryPoint,
|
|
79101
|
-
convexUrl: ctx.convexUrl,
|
|
79102
|
-
chatroomId: ctx.chatroomId,
|
|
79103
|
-
nativeIntegration: ctx.nativeIntegration
|
|
79104
|
-
};
|
|
79105
|
-
}
|
|
79106
|
-
function getSoloGuidanceFromContext(ctx) {
|
|
79107
|
-
return getSoloGuidance(toSoloParams(ctx));
|
|
79108
|
-
}
|
|
79109
|
-
function getBasePlannerGuidanceFromContext(ctx) {
|
|
79110
|
-
return getPlannerGuidance(toPlannerParams(ctx));
|
|
79111
|
-
}
|
|
79112
|
-
function getBaseRoleGuidanceFromContext(ctx) {
|
|
79113
|
-
const normalizedRole = ctx.role.toLowerCase();
|
|
79114
|
-
if (normalizedRole === "planner") {
|
|
79115
|
-
return getBasePlannerGuidanceFromContext(ctx);
|
|
79116
|
-
}
|
|
79117
|
-
if (normalizedRole === "builder") {
|
|
79118
|
-
return getBaseBuilderGuidanceFromContext(ctx);
|
|
79119
|
-
}
|
|
79120
|
-
if (normalizedRole === "solo") {
|
|
79121
|
-
return getSoloGuidanceFromContext(ctx);
|
|
79122
|
-
}
|
|
79123
|
-
return "";
|
|
79124
|
-
}
|
|
79125
77932
|
var init_fromContext = __esm(() => {
|
|
79126
77933
|
init_builder();
|
|
79127
77934
|
init_planner();
|
|
@@ -79129,229 +77936,32 @@ var init_fromContext = __esm(() => {
|
|
|
79129
77936
|
});
|
|
79130
77937
|
|
|
79131
77938
|
// ../../services/backend/prompts/teams/duo/prompts/builder.ts
|
|
79132
|
-
function getBuilderGuidance2(ctx) {
|
|
79133
|
-
return `
|
|
79134
|
-
**Duo Team Context:**
|
|
79135
|
-
- You work with a planner who coordinates work and communicates with the user
|
|
79136
|
-
- You do NOT communicate directly with the user — hand off to the planner instead
|
|
79137
|
-
- Focus on implementation; the planner handles user communication and delivery
|
|
79138
|
-
- After completing work, hand off back to planner
|
|
79139
|
-
- **NEVER hand off directly to \`user\`** — always go through the planner
|
|
79140
|
-
|
|
79141
|
-
${getBuilderGuidance({ ...ctx, questionTarget: "planner", codeChangesTarget: "planner" })}
|
|
79142
|
-
`;
|
|
79143
|
-
}
|
|
79144
77939
|
var init_builder2 = __esm(() => {
|
|
79145
77940
|
init_builder();
|
|
79146
77941
|
});
|
|
79147
77942
|
|
|
79148
77943
|
// ../../services/backend/prompts/cli/roles/planner-guidance-context.ts
|
|
79149
|
-
function getPlannerGuidanceContext(ctx) {
|
|
79150
|
-
const { convexUrl, teamRoles, chatroomId, role } = ctx;
|
|
79151
|
-
const cliEnvPrefix = getCliEnvPrefix(convexUrl);
|
|
79152
|
-
const members = teamRoles;
|
|
79153
|
-
return {
|
|
79154
|
-
...ctx,
|
|
79155
|
-
cliEnvPrefix,
|
|
79156
|
-
members,
|
|
79157
|
-
chatroomId,
|
|
79158
|
-
role
|
|
79159
|
-
};
|
|
79160
|
-
}
|
|
79161
77944
|
var init_planner_guidance_context = __esm(() => {
|
|
79162
77945
|
init_env();
|
|
79163
77946
|
});
|
|
79164
77947
|
|
|
79165
77948
|
// ../../services/backend/prompts/teams/duo/prompts/planner.ts
|
|
79166
|
-
function getPlannerGuidance2(ctx) {
|
|
79167
|
-
const { nativeIntegration, members, cliEnvPrefix, chatroomId, role } = getPlannerGuidanceContext(ctx);
|
|
79168
|
-
const operatingModelGuidance = getPlannerPlusBuilderOperatingModel(nativeIntegration);
|
|
79169
|
-
return `## Planner Operating Model
|
|
79170
|
-
|
|
79171
|
-
${getSessionContinuityLine(nativeIntegration)}
|
|
79172
|
-
|
|
79173
|
-
You are the team coordinator and the **single point of contact** for the user.
|
|
79174
|
-
|
|
79175
|
-
**Duo Team Context:**
|
|
79176
|
-
- You are the entry point — you communicate directly with the user
|
|
79177
|
-
- You coordinate with the builder for implementation tasks
|
|
79178
|
-
- You are ultimately accountable for all work quality
|
|
79179
|
-
- After reviewing builder output, deliver results to the user
|
|
79180
|
-
- **Only you can hand off to \`user\`**
|
|
79181
|
-
|
|
79182
|
-
${getTeamCompositionSection(members)}
|
|
79183
|
-
|
|
79184
|
-
${operatingModelGuidance}
|
|
79185
|
-
|
|
79186
|
-
${getCoreResponsibilitiesSection(DUO_TEAM_CONFIG)}
|
|
79187
|
-
|
|
79188
|
-
${getDelegationAndDecompositionSection(DUO_TEAM_CONFIG)}
|
|
79189
|
-
|
|
79190
|
-
${getDelegationGuidelinesSection(DUO_TEAM_CONFIG, {
|
|
79191
|
-
cliEnvPrefix,
|
|
79192
|
-
chatroomId,
|
|
79193
|
-
role
|
|
79194
|
-
})}
|
|
79195
|
-
|
|
79196
|
-
${getHandoffRulesSection(DUO_TEAM_CONFIG, nativeIntegration)}
|
|
79197
|
-
|
|
79198
|
-
${getWhenWorkComesBackSection(DUO_TEAM_CONFIG)}`;
|
|
79199
|
-
}
|
|
79200
|
-
var DUO_TEAM_CONFIG;
|
|
79201
77949
|
var init_planner2 = __esm(() => {
|
|
79202
77950
|
init_planner_guidance_context();
|
|
79203
77951
|
init_sections();
|
|
79204
|
-
DUO_TEAM_CONFIG = { hasBuilder: true };
|
|
79205
77952
|
});
|
|
79206
77953
|
|
|
79207
77954
|
// ../../services/backend/prompts/teams/duo/prompts/fromContext.ts
|
|
79208
|
-
function toDuoBuilderParams(ctx) {
|
|
79209
|
-
return {
|
|
79210
|
-
role: ctx.role,
|
|
79211
|
-
teamRoles: ctx.teamRoles,
|
|
79212
|
-
isEntryPoint: ctx.isEntryPoint,
|
|
79213
|
-
convexUrl: ctx.convexUrl,
|
|
79214
|
-
nativeIntegration: ctx.nativeIntegration
|
|
79215
|
-
};
|
|
79216
|
-
}
|
|
79217
|
-
function toDuoPlannerParams(ctx) {
|
|
79218
|
-
return {
|
|
79219
|
-
role: ctx.role,
|
|
79220
|
-
teamRoles: ctx.teamRoles,
|
|
79221
|
-
isEntryPoint: ctx.isEntryPoint,
|
|
79222
|
-
convexUrl: ctx.convexUrl,
|
|
79223
|
-
chatroomId: ctx.chatroomId,
|
|
79224
|
-
nativeIntegration: ctx.nativeIntegration
|
|
79225
|
-
};
|
|
79226
|
-
}
|
|
79227
|
-
function getDuoBuilderGuidanceFromContext(ctx) {
|
|
79228
|
-
return getBuilderGuidance2(toDuoBuilderParams(ctx));
|
|
79229
|
-
}
|
|
79230
|
-
function getDuoPlannerGuidanceFromContext(ctx) {
|
|
79231
|
-
return getPlannerGuidance2(toDuoPlannerParams(ctx));
|
|
79232
|
-
}
|
|
79233
|
-
function getDuoRoleGuidanceFromContext(ctx) {
|
|
79234
|
-
const normalizedRole = ctx.role.toLowerCase();
|
|
79235
|
-
if (normalizedRole === "planner") {
|
|
79236
|
-
return getDuoPlannerGuidanceFromContext(ctx);
|
|
79237
|
-
}
|
|
79238
|
-
if (normalizedRole === "builder") {
|
|
79239
|
-
return getDuoBuilderGuidanceFromContext(ctx);
|
|
79240
|
-
}
|
|
79241
|
-
return null;
|
|
79242
|
-
}
|
|
79243
77955
|
var init_fromContext2 = __esm(() => {
|
|
79244
77956
|
init_builder2();
|
|
79245
77957
|
init_planner2();
|
|
79246
77958
|
});
|
|
79247
77959
|
|
|
79248
77960
|
// ../../services/backend/prompts/teams/solo/prompts/fromContext.ts
|
|
79249
|
-
function toSoloParams2(ctx) {
|
|
79250
|
-
return {
|
|
79251
|
-
role: ctx.role,
|
|
79252
|
-
teamRoles: ctx.teamRoles,
|
|
79253
|
-
isEntryPoint: ctx.isEntryPoint,
|
|
79254
|
-
convexUrl: ctx.convexUrl,
|
|
79255
|
-
chatroomId: ctx.chatroomId,
|
|
79256
|
-
nativeIntegration: ctx.nativeIntegration
|
|
79257
|
-
};
|
|
79258
|
-
}
|
|
79259
|
-
function getSoloGuidanceFromContext2(ctx) {
|
|
79260
|
-
return getSoloGuidance(toSoloParams2(ctx));
|
|
79261
|
-
}
|
|
79262
|
-
function getSoloRoleGuidanceFromContext(ctx) {
|
|
79263
|
-
const normalizedRole = ctx.role.toLowerCase();
|
|
79264
|
-
if (normalizedRole === "solo") {
|
|
79265
|
-
return getSoloGuidanceFromContext2(ctx);
|
|
79266
|
-
}
|
|
79267
|
-
return null;
|
|
79268
|
-
}
|
|
79269
77961
|
var init_fromContext3 = __esm(() => {
|
|
79270
77962
|
init_solo();
|
|
79271
77963
|
});
|
|
79272
|
-
|
|
79273
|
-
// ../../services/backend/src/domain/entities/team.ts
|
|
79274
|
-
function toTeam(chatroom) {
|
|
79275
|
-
if (!chatroom.teamId || !chatroom.teamRoles || chatroom.teamRoles.length === 0) {
|
|
79276
|
-
return null;
|
|
79277
|
-
}
|
|
79278
|
-
const entryPoint = chatroom.teamEntryPoint ?? chatroom.teamRoles[0];
|
|
79279
|
-
if (!entryPoint)
|
|
79280
|
-
return null;
|
|
79281
|
-
return {
|
|
79282
|
-
id: chatroom.teamId,
|
|
79283
|
-
name: chatroom.teamName ?? chatroom.teamId,
|
|
79284
|
-
roles: chatroom.teamRoles,
|
|
79285
|
-
entryPoint
|
|
79286
|
-
};
|
|
79287
|
-
}
|
|
79288
|
-
function getTeamEntryPoint(team) {
|
|
79289
|
-
return team.teamEntryPoint ?? team.teamRoles?.[0] ?? null;
|
|
79290
|
-
}
|
|
79291
|
-
|
|
79292
77964
|
// ../../services/backend/prompts/selector-context.ts
|
|
79293
|
-
function detectTeamTypeByName(teamName) {
|
|
79294
|
-
const normalizedName = (teamName || "").toLowerCase();
|
|
79295
|
-
if (normalizedName.includes("solo"))
|
|
79296
|
-
return "solo";
|
|
79297
|
-
if (normalizedName.includes("duo"))
|
|
79298
|
-
return "duo";
|
|
79299
|
-
return null;
|
|
79300
|
-
}
|
|
79301
|
-
function isSoloTeamByRoles(teamRoles) {
|
|
79302
|
-
return teamRoles.some((r) => r.toLowerCase() === "solo") && teamRoles.length === 1;
|
|
79303
|
-
}
|
|
79304
|
-
function isDuoTeamByRoles(teamRoles) {
|
|
79305
|
-
const hasPlanner = teamRoles.some((r) => r.toLowerCase() === "planner");
|
|
79306
|
-
const hasBuilder = teamRoles.some((r) => r.toLowerCase() === "builder");
|
|
79307
|
-
return hasPlanner && hasBuilder && teamRoles.length === 2;
|
|
79308
|
-
}
|
|
79309
|
-
function detectTeamType(teamRoles, teamName) {
|
|
79310
|
-
const byName = detectTeamTypeByName(teamName);
|
|
79311
|
-
if (byName)
|
|
79312
|
-
return byName;
|
|
79313
|
-
if (isSoloTeamByRoles(teamRoles))
|
|
79314
|
-
return "solo";
|
|
79315
|
-
if (isDuoTeamByRoles(teamRoles))
|
|
79316
|
-
return "duo";
|
|
79317
|
-
return "unknown";
|
|
79318
|
-
}
|
|
79319
|
-
function buildSelectorContext(params) {
|
|
79320
|
-
const entryPoint = getTeamEntryPoint({ teamEntryPoint: params.teamEntryPoint, teamRoles: params.teamRoles }) ?? "builder";
|
|
79321
|
-
const teamConfig = toTeam({
|
|
79322
|
-
teamId: params.teamId,
|
|
79323
|
-
teamName: params.teamName,
|
|
79324
|
-
teamRoles: params.teamRoles,
|
|
79325
|
-
teamEntryPoint: params.teamEntryPoint
|
|
79326
|
-
}) ?? undefined;
|
|
79327
|
-
return {
|
|
79328
|
-
role: params.role,
|
|
79329
|
-
team: detectTeamType(params.teamRoles, params.teamName),
|
|
79330
|
-
teamConfig,
|
|
79331
|
-
workflow: params.workflow,
|
|
79332
|
-
teamRoles: params.teamRoles,
|
|
79333
|
-
isEntryPoint: params.role.toLowerCase() === entryPoint.toLowerCase(),
|
|
79334
|
-
convexUrl: params.convexUrl,
|
|
79335
|
-
chatroomId: params.chatroomId,
|
|
79336
|
-
agentType: params.agentType ?? "unset",
|
|
79337
|
-
nativeIntegration: params.nativeIntegration
|
|
79338
|
-
};
|
|
79339
|
-
}
|
|
79340
|
-
function getRoleGuidanceFromContext(ctx) {
|
|
79341
|
-
try {
|
|
79342
|
-
if (ctx.team === "solo") {
|
|
79343
|
-
const result = getSoloRoleGuidanceFromContext(ctx);
|
|
79344
|
-
if (result !== null)
|
|
79345
|
-
return result;
|
|
79346
|
-
}
|
|
79347
|
-
if (ctx.team === "duo") {
|
|
79348
|
-
const result = getDuoRoleGuidanceFromContext(ctx);
|
|
79349
|
-
if (result !== null)
|
|
79350
|
-
return result;
|
|
79351
|
-
}
|
|
79352
|
-
} catch {}
|
|
79353
|
-
return getBaseRoleGuidanceFromContext(ctx);
|
|
79354
|
-
}
|
|
79355
77965
|
var init_selector_context = __esm(() => {
|
|
79356
77966
|
init_fromContext();
|
|
79357
77967
|
init_fromContext2();
|
|
@@ -79359,151 +77969,19 @@ var init_selector_context = __esm(() => {
|
|
|
79359
77969
|
});
|
|
79360
77970
|
|
|
79361
77971
|
// ../../services/backend/prompts/sections/role-guidance.ts
|
|
79362
|
-
function getRoleGuidanceSection(ctx) {
|
|
79363
|
-
const content = getRoleGuidanceFromContext(ctx);
|
|
79364
|
-
return createSection("role-guidance", "knowledge", content);
|
|
79365
|
-
}
|
|
79366
77972
|
var init_role_guidance = __esm(() => {
|
|
79367
77973
|
init_selector_context();
|
|
79368
77974
|
});
|
|
79369
77975
|
|
|
79370
77976
|
// ../../services/backend/prompts/templates.ts
|
|
79371
|
-
|
|
79372
|
-
const normalizedRole = role.toLowerCase();
|
|
79373
|
-
const template = ROLE_TEMPLATES[normalizedRole];
|
|
79374
|
-
if (template) {
|
|
79375
|
-
return template;
|
|
79376
|
-
}
|
|
79377
|
-
return {
|
|
79378
|
-
role,
|
|
79379
|
-
title: role.charAt(0).toUpperCase() + role.slice(1),
|
|
79380
|
-
description: `You are participating as the ${role} in this collaborative workflow.`,
|
|
79381
|
-
responsibilities: [
|
|
79382
|
-
"Complete tasks assigned to your role",
|
|
79383
|
-
"Communicate clearly with other participants",
|
|
79384
|
-
"Hand off to the next appropriate role when done"
|
|
79385
|
-
],
|
|
79386
|
-
defaultHandoffTarget: "user"
|
|
79387
|
-
};
|
|
79388
|
-
}
|
|
79389
|
-
var ROLE_TEMPLATES;
|
|
79390
|
-
var init_templates = __esm(() => {
|
|
79391
|
-
ROLE_TEMPLATES = {
|
|
79392
|
-
builder: {
|
|
79393
|
-
role: "builder",
|
|
79394
|
-
title: "Builder",
|
|
79395
|
-
description: "You are the implementer responsible for writing code and building solutions.",
|
|
79396
|
-
responsibilities: [
|
|
79397
|
-
"Implement solutions based on requirements",
|
|
79398
|
-
"Write clean, maintainable, well-documented code",
|
|
79399
|
-
"Follow established patterns and best practices",
|
|
79400
|
-
"Handle edge cases and error scenarios",
|
|
79401
|
-
"Provide clear summaries of what was built"
|
|
79402
|
-
],
|
|
79403
|
-
defaultHandoffTarget: "planner"
|
|
79404
|
-
},
|
|
79405
|
-
planner: {
|
|
79406
|
-
role: "planner",
|
|
79407
|
-
title: "Planner",
|
|
79408
|
-
description: "You are the team coordinator responsible for user communication, task decomposition, and team management.",
|
|
79409
|
-
responsibilities: [
|
|
79410
|
-
"Communicate with the user as the single point of contact",
|
|
79411
|
-
"Decompose complex tasks into actionable work items",
|
|
79412
|
-
"Delegate work to available team members",
|
|
79413
|
-
"Review completed work against user requirements",
|
|
79414
|
-
"Manage the backlog and prioritize tasks",
|
|
79415
|
-
"Hand back work for rework if requirements are not met"
|
|
79416
|
-
],
|
|
79417
|
-
defaultHandoffTarget: "builder"
|
|
79418
|
-
},
|
|
79419
|
-
architect: {
|
|
79420
|
-
role: "architect",
|
|
79421
|
-
title: "Architect",
|
|
79422
|
-
description: "You are the system designer responsible for planning and high-level architecture.",
|
|
79423
|
-
responsibilities: [
|
|
79424
|
-
"Analyze requirements and break down complex tasks",
|
|
79425
|
-
"Design system architecture and component structure",
|
|
79426
|
-
"Make technology and pattern decisions",
|
|
79427
|
-
"Create clear specifications for the builder",
|
|
79428
|
-
"Consider scalability, maintainability, and best practices"
|
|
79429
|
-
],
|
|
79430
|
-
defaultHandoffTarget: "builder"
|
|
79431
|
-
},
|
|
79432
|
-
tester: {
|
|
79433
|
-
role: "tester",
|
|
79434
|
-
title: "Tester",
|
|
79435
|
-
description: "You are the QA specialist responsible for testing and validation.",
|
|
79436
|
-
responsibilities: [
|
|
79437
|
-
"Write and execute test cases",
|
|
79438
|
-
"Verify functionality works as expected",
|
|
79439
|
-
"Test edge cases and error handling",
|
|
79440
|
-
"Report bugs and issues clearly",
|
|
79441
|
-
"Confirm quality standards are met"
|
|
79442
|
-
],
|
|
79443
|
-
defaultHandoffTarget: "user"
|
|
79444
|
-
},
|
|
79445
|
-
solo: {
|
|
79446
|
-
role: "solo",
|
|
79447
|
-
title: "Solo",
|
|
79448
|
-
description: "You are the autonomous agent responsible for both planning and executing tasks independently.",
|
|
79449
|
-
responsibilities: [
|
|
79450
|
-
"Communicate directly with the user as the single point of contact",
|
|
79451
|
-
"Decompose complex tasks into actionable work items",
|
|
79452
|
-
"Implement solutions: write clean, maintainable code",
|
|
79453
|
-
"Follow established patterns and best practices",
|
|
79454
|
-
"Handle edge cases and error scenarios",
|
|
79455
|
-
"Review and validate your own work for quality",
|
|
79456
|
-
"Deliver completed results to the user"
|
|
79457
|
-
],
|
|
79458
|
-
defaultHandoffTarget: "user"
|
|
79459
|
-
}
|
|
79460
|
-
};
|
|
79461
|
-
});
|
|
77977
|
+
var init_templates = () => {};
|
|
79462
77978
|
|
|
79463
77979
|
// ../../services/backend/prompts/sections/role-identity.ts
|
|
79464
|
-
function getTeamHeaderSection(teamName) {
|
|
79465
|
-
return createSection("team-header", "knowledge", `# ${teamName}`);
|
|
79466
|
-
}
|
|
79467
|
-
function getRoleTitleSection(ctx) {
|
|
79468
|
-
const template = getRoleTemplate(ctx.role);
|
|
79469
|
-
return createSection("role-title", "knowledge", `## Your Role: ${template.title.toUpperCase()}`);
|
|
79470
|
-
}
|
|
79471
|
-
function getRoleDescriptionSection(ctx) {
|
|
79472
|
-
const template = getRoleTemplate(ctx.role);
|
|
79473
|
-
return createSection("role-description", "knowledge", template.description);
|
|
79474
|
-
}
|
|
79475
77980
|
var init_role_identity = __esm(() => {
|
|
79476
77981
|
init_templates();
|
|
79477
77982
|
});
|
|
79478
77983
|
|
|
79479
77984
|
// ../../services/backend/prompts/native/system-prompt.ts
|
|
79480
|
-
function composeNativeSystemPrompt(input) {
|
|
79481
|
-
const { chatroomId, role, teamId, teamName, teamRoles, teamEntryPoint, convexUrl } = input;
|
|
79482
|
-
const selectorCtx = buildSelectorContext({
|
|
79483
|
-
role,
|
|
79484
|
-
teamRoles,
|
|
79485
|
-
teamId,
|
|
79486
|
-
teamName,
|
|
79487
|
-
teamEntryPoint,
|
|
79488
|
-
convexUrl,
|
|
79489
|
-
chatroomId,
|
|
79490
|
-
agentType: input.agentType,
|
|
79491
|
-
nativeIntegration: true
|
|
79492
|
-
});
|
|
79493
|
-
const sections = [
|
|
79494
|
-
getRoleTitleSection(selectorCtx),
|
|
79495
|
-
getGlossarySection({
|
|
79496
|
-
convexUrl,
|
|
79497
|
-
chatroomId,
|
|
79498
|
-
role,
|
|
79499
|
-
nativeIntegration: true,
|
|
79500
|
-
compactSkills: true
|
|
79501
|
-
}),
|
|
79502
|
-
getRoleGuidanceSection(selectorCtx),
|
|
79503
|
-
getNativeCommandsReferenceSection({ chatroomId, role, convexUrl })
|
|
79504
|
-
];
|
|
79505
|
-
return composeSections(sections);
|
|
79506
|
-
}
|
|
79507
77985
|
var init_system_prompt = __esm(() => {
|
|
79508
77986
|
init_commands_reference();
|
|
79509
77987
|
init_glossary();
|
|
@@ -79513,46 +77991,11 @@ var init_system_prompt = __esm(() => {
|
|
|
79513
77991
|
});
|
|
79514
77992
|
|
|
79515
77993
|
// ../../services/backend/prompts/native/task-started-content.ts
|
|
79516
|
-
function getNativeTaskStartedPrompt(ctx) {
|
|
79517
|
-
const contextNewCmd = contextNewCommand({
|
|
79518
|
-
chatroomId: ctx.chatroomId,
|
|
79519
|
-
role: ctx.role,
|
|
79520
|
-
cliEnvPrefix: ctx.cliEnvPrefix,
|
|
79521
|
-
triggerMessageId: ctx.triggerMessageId
|
|
79522
|
-
});
|
|
79523
|
-
return `### Start working
|
|
79524
|
-
|
|
79525
|
-
Entry-point roles receive user messages directly. ${getNativeTokenActivityInProgressNote()}
|
|
79526
|
-
|
|
79527
|
-
${getContextRuleBlock(contextNewCmd, contextNewHint({ cliEnvPrefix: ctx.cliEnvPrefix }))}`;
|
|
79528
|
-
}
|
|
79529
|
-
function getNativeTaskStartedPromptForHandoffRecipient() {
|
|
79530
|
-
return `### Start Working
|
|
79531
|
-
|
|
79532
|
-
The task body contains your work description. Begin immediately.`;
|
|
79533
|
-
}
|
|
79534
77994
|
var init_task_started_content = __esm(() => {
|
|
79535
77995
|
init_new();
|
|
79536
77996
|
});
|
|
79537
77997
|
|
|
79538
77998
|
// ../../services/backend/prompts/sections/classification-guide.ts
|
|
79539
|
-
function getTaskIntakeContent(ctx) {
|
|
79540
|
-
const cliEnvPrefix = getCliEnvPrefix(ctx.convexUrl);
|
|
79541
|
-
const chatroomId = ctx.chatroomId ?? "";
|
|
79542
|
-
if (ctx.isEntryPoint) {
|
|
79543
|
-
return ctx.nativeIntegration ? getNativeTaskStartedPrompt({ chatroomId, role: ctx.role, cliEnvPrefix }) : getTaskStartedPrompt2({ chatroomId, role: ctx.role, cliEnvPrefix });
|
|
79544
|
-
}
|
|
79545
|
-
return ctx.nativeIntegration ? getNativeTaskStartedPromptForHandoffRecipient() : getTaskStartedPromptForHandoffRecipient2({
|
|
79546
|
-
chatroomId,
|
|
79547
|
-
role: ctx.role,
|
|
79548
|
-
cliEnvPrefix
|
|
79549
|
-
});
|
|
79550
|
-
}
|
|
79551
|
-
function getClassificationGuideSection(ctx) {
|
|
79552
|
-
const content = getTaskIntakeContent(ctx);
|
|
79553
|
-
const sectionId = ctx.isEntryPoint ? "task-intake-guide" : "handoff-recipient-guide";
|
|
79554
|
-
return createSection(sectionId, "knowledge", content);
|
|
79555
|
-
}
|
|
79556
77999
|
var init_classification_guide = __esm(() => {
|
|
79557
78000
|
init_cli();
|
|
79558
78001
|
init_task_started_content();
|
|
@@ -79560,118 +78003,23 @@ var init_classification_guide = __esm(() => {
|
|
|
79560
78003
|
});
|
|
79561
78004
|
|
|
79562
78005
|
// ../../services/backend/prompts/sections/current-classification.ts
|
|
79563
|
-
function getCurrentClassificationSection(classification) {
|
|
79564
|
-
const info = {
|
|
79565
|
-
question: {
|
|
79566
|
-
label: "QUESTION",
|
|
79567
|
-
description: "User is asking a question. Can respond directly after answering."
|
|
79568
|
-
},
|
|
79569
|
-
new_feature: {
|
|
79570
|
-
label: "NEW FEATURE",
|
|
79571
|
-
description: "New functionality request."
|
|
79572
|
-
},
|
|
79573
|
-
follow_up: {
|
|
79574
|
-
label: "FOLLOW-UP",
|
|
79575
|
-
description: "Follow-up to previous task. Same rules as the original apply."
|
|
79576
|
-
}
|
|
79577
|
-
};
|
|
79578
|
-
const { label, description } = info[classification];
|
|
79579
|
-
const content = `### Current Task: ${label}
|
|
79580
|
-
${description}`;
|
|
79581
|
-
return createSection("current-classification", "guidance", content);
|
|
79582
|
-
}
|
|
79583
78006
|
var init_current_classification = () => {};
|
|
79584
78007
|
|
|
79585
78008
|
// ../../services/backend/prompts/sections/getting-started.ts
|
|
79586
|
-
function getGettingStartedSection(ctx) {
|
|
79587
|
-
const content = getContextGainingGuidance({
|
|
79588
|
-
chatroomId: ctx.chatroomId ?? "",
|
|
79589
|
-
role: ctx.role,
|
|
79590
|
-
convexUrl: ctx.convexUrl,
|
|
79591
|
-
agentType: ctx.agentType
|
|
79592
|
-
});
|
|
79593
|
-
return createSection("getting-started", "knowledge", content);
|
|
79594
|
-
}
|
|
79595
78009
|
var init_getting_started = __esm(() => {
|
|
79596
78010
|
init_getting_started_content();
|
|
79597
78011
|
});
|
|
79598
78012
|
|
|
79599
78013
|
// ../../services/backend/prompts/sections/handoff-options.ts
|
|
79600
|
-
function getHandoffOptionsSection(params) {
|
|
79601
|
-
const roles = params.availableHandoffRoles.join(", ");
|
|
79602
|
-
const content = `### Handoff Options
|
|
79603
|
-
Available targets: ${roles}`;
|
|
79604
|
-
return createSection("handoff-options", "guidance", content);
|
|
79605
|
-
}
|
|
79606
78014
|
var init_handoff_options = () => {};
|
|
79607
78015
|
|
|
79608
78016
|
// ../../services/backend/prompts/sections/next-step.ts
|
|
79609
|
-
function getNextStepSection(params) {
|
|
79610
|
-
const cliEnvPrefix = getCliEnvPrefix(params.convexUrl);
|
|
79611
|
-
const waitCmd = getNextTaskCommand({
|
|
79612
|
-
chatroomId: params.chatroomId,
|
|
79613
|
-
role: params.role,
|
|
79614
|
-
cliEnvPrefix
|
|
79615
|
-
});
|
|
79616
|
-
const content = `### Next
|
|
79617
|
-
|
|
79618
|
-
Run:
|
|
79619
|
-
|
|
79620
|
-
\`\`\`bash
|
|
79621
|
-
${waitCmd}
|
|
79622
|
-
\`\`\``;
|
|
79623
|
-
return createSection("next-step", "guidance", content);
|
|
79624
|
-
}
|
|
79625
78017
|
var init_next_step = __esm(() => {
|
|
79626
78018
|
init_command();
|
|
79627
78019
|
init_utils3();
|
|
79628
78020
|
});
|
|
79629
78021
|
|
|
79630
78022
|
// ../../services/backend/prompts/sections/session-vs-chatroom-task.ts
|
|
79631
|
-
function getTwoLevelsTableSection() {
|
|
79632
|
-
return `## Two-Level Model: Session vs Chatroom Task
|
|
79633
|
-
|
|
79634
|
-
| Level | Name | Scope | Ends when |
|
|
79635
|
-
|-------|------|-------|-----------|
|
|
79636
|
-
| **A** | **Session** (harness turn) | The entire agent invocation — from startup to shutdown | You deliberately shut down or the harness exits |
|
|
79637
|
-
| **B** | **Chatroom task** | One discrete unit of work delivered by \`get-next-task\` | You run \`handoff\` to pass work to the next role |
|
|
79638
|
-
|
|
79639
|
-
**Completing Level B does NOT end Level A.**
|
|
79640
|
-
After every \`handoff\`, you must run \`get-next-task\` again to stay in the session and receive the next chatroom task.`;
|
|
79641
|
-
}
|
|
79642
|
-
function getSessionLifecycleSection() {
|
|
79643
|
-
return `### Session Lifecycle
|
|
79644
|
-
|
|
79645
|
-
A session starts when your harness launches you and ends only when the harness shuts down (or you explicitly stop).
|
|
79646
|
-
Within a session, you process many chatroom tasks sequentially:
|
|
79647
|
-
|
|
79648
|
-
\`get-next-task\` → do work → \`handoff\` → \`get-next-task\` → do work → \`handoff\` → …
|
|
79649
|
-
|
|
79650
|
-
Never exit or stop after a handoff — that closes the session (Level A) before the user is done with you.`;
|
|
79651
|
-
}
|
|
79652
|
-
function getSessionAntiPatternsSection() {
|
|
79653
|
-
return `### Common Mistakes
|
|
79654
|
-
|
|
79655
|
-
❌ **Wrong:** Run \`handoff\`, then stop or wait for the user to re-invoke you.
|
|
79656
|
-
✅ **Right:** Run \`handoff\`, then immediately run \`get-next-task\` in the foreground.
|
|
79657
|
-
|
|
79658
|
-
❌ **Wrong:** Think "I finished the task, I'm done."
|
|
79659
|
-
✅ **Right:** Think "I finished this chatroom task (Level B). The session (Level A) continues — run \`get-next-task\`."
|
|
79660
|
-
|
|
79661
|
-
❌ **Wrong:** Run \`get-next-task\` in the background or skip it.
|
|
79662
|
-
✅ **Right:** \`get-next-task\` must run in the **foreground** so the harness can deliver the next chatroom task.`;
|
|
79663
|
-
}
|
|
79664
|
-
function getSessionVsChatroomTaskSection() {
|
|
79665
|
-
const content = [
|
|
79666
|
-
getTwoLevelsTableSection(),
|
|
79667
|
-
"",
|
|
79668
|
-
getSessionLifecycleSection(),
|
|
79669
|
-
"",
|
|
79670
|
-
getSessionAntiPatternsSection()
|
|
79671
|
-
].join(`
|
|
79672
|
-
`);
|
|
79673
|
-
return createSection("session-vs-chatroom-task", "guidance", content);
|
|
79674
|
-
}
|
|
79675
78023
|
var init_session_vs_chatroom_task = () => {};
|
|
79676
78024
|
|
|
79677
78025
|
// ../../services/backend/src/domain/entities/harness/claude-sdk.config.ts
|
|
@@ -79876,571 +78224,9 @@ var init_types = __esm(() => {
|
|
|
79876
78224
|
"pi-sdk": piSdkCapabilities
|
|
79877
78225
|
};
|
|
79878
78226
|
});
|
|
79879
|
-
|
|
79880
|
-
// ../../services/backend/prompts/review-guidelines/review.ts
|
|
79881
|
-
function getReviewGuidelines() {
|
|
79882
|
-
return [REVIEW_PRINCIPLES, REVIEW_PROCESS, GUIDELINE_FILE_LOCATIONS, REJECTION_GUIDANCE].join(`
|
|
79883
|
-
|
|
79884
|
-
`);
|
|
79885
|
-
}
|
|
79886
|
-
var REVIEW_PRINCIPLES = `
|
|
79887
|
-
## Review Principles
|
|
79888
|
-
|
|
79889
|
-
When reviewing completed work, you serve as the quality guardian between implementation and delivery.
|
|
79890
|
-
|
|
79891
|
-
### Primary Goal: Maintainability & Extensibility
|
|
79892
|
-
|
|
79893
|
-
**The ultimate purpose of code review is to ensure the changes make it possible to continue building on the application.**
|
|
79894
|
-
|
|
79895
|
-
Every piece of code must be:
|
|
79896
|
-
- Easy to understand and modify later
|
|
79897
|
-
- Following patterns that scale
|
|
79898
|
-
- Not creating technical debt that slows future development
|
|
79899
|
-
|
|
79900
|
-
If code is hard to extend, hard to understand, or creates mess - it should be rejected or refactored, regardless of whether it "works."
|
|
79901
|
-
|
|
79902
|
-
### Core Values
|
|
79903
|
-
|
|
79904
|
-
1. **User Goal Alignment**
|
|
79905
|
-
The implementation must accomplish what the user originally requested.
|
|
79906
|
-
Compare the work against the ORIGINAL user request, not just the handoff summary.
|
|
79907
|
-
|
|
79908
|
-
2. **Code Quality Over Speed**
|
|
79909
|
-
Maintain code quality: Use \`handoff\` to reject messy code that creates technical debt and slows future development.
|
|
79910
|
-
|
|
79911
|
-
3. **Codebase Consistency**
|
|
79912
|
-
New code should follow existing patterns and conventions.
|
|
79913
|
-
Check guideline files for project-specific rules.
|
|
79914
|
-
Inconsistent code creates confusion and bugs.
|
|
79915
|
-
|
|
79916
|
-
4. **Verification Over Trust**
|
|
79917
|
-
Check the actual changes, not just the summary.
|
|
79918
|
-
If something seems off, investigate. Trust but verify.
|
|
79919
|
-
|
|
79920
|
-
5. **Be Direct and Specific**
|
|
79921
|
-
Be specific and clear in your \`handoff\` message: Vague feedback leads to confusion and rework. If something is wrong, say exactly what and why.
|
|
79922
|
-
If a refactor is needed, propose the exact approach.
|
|
79923
|
-
`, REVIEW_PROCESS = `
|
|
79924
|
-
## Review Process
|
|
79925
|
-
|
|
79926
|
-
### Phase 1: Context Review
|
|
79927
|
-
|
|
79928
|
-
Before looking at code, understand what was requested:
|
|
79929
|
-
|
|
79930
|
-
1. Read the **original user request** in the context window
|
|
79931
|
-
2. Note all requirements, constraints, and acceptance criteria
|
|
79932
|
-
3. If a feature has metadata (title, description, tech-specs), review each point
|
|
79933
|
-
4. If there are attached tasks, read their content
|
|
79934
|
-
|
|
79935
|
-
### Phase 2: Change Inspection
|
|
79936
|
-
|
|
79937
|
-
Run these commands to inspect the implementation:
|
|
79938
|
-
|
|
79939
|
-
\`\`\`bash
|
|
79940
|
-
# Check for linting issues
|
|
79941
|
-
pnpm lint:fix
|
|
79942
|
-
|
|
79943
|
-
# View uncommitted changes
|
|
79944
|
-
git status
|
|
79945
|
-
git diff
|
|
79946
|
-
|
|
79947
|
-
# View recent commits
|
|
79948
|
-
git log --oneline -5
|
|
79949
|
-
git show HEAD
|
|
79950
|
-
\`\`\`
|
|
79951
|
-
|
|
79952
|
-
### Phase 3: Code Review Checklist
|
|
79953
|
-
|
|
79954
|
-
**Functional Requirements:**
|
|
79955
|
-
- [ ] All requirements from original request are addressed
|
|
79956
|
-
- [ ] Edge cases are handled
|
|
79957
|
-
- [ ] Error handling is appropriate
|
|
79958
|
-
|
|
79959
|
-
**Code Quality:**
|
|
79960
|
-
- [ ] No \`any\` types - proper TypeScript typing required
|
|
79961
|
-
- [ ] No type assertions (\`as\`) hiding real type issues
|
|
79962
|
-
- [ ] React hooks used correctly (deps arrays, memoization)
|
|
79963
|
-
- [ ] No inline workarounds or hacks
|
|
79964
|
-
|
|
79965
|
-
**Codebase Consistency:**
|
|
79966
|
-
- [ ] Follows existing patterns in the codebase
|
|
79967
|
-
- [ ] Uses existing components/utilities where applicable
|
|
79968
|
-
- [ ] Styling follows design system (semantic tokens, not hardcoded colors)
|
|
79969
|
-
|
|
79970
|
-
**Guidelines Compliance:**
|
|
79971
|
-
- [ ] Check relevant guideline files were followed (see list below)
|
|
79972
|
-
|
|
79973
|
-
### Phase 4: Decision
|
|
79974
|
-
|
|
79975
|
-
**Your feedback must be SPECIFIC and ACTIONABLE. Include clear guidance in your \`handoff\` message to help the builder make the right changes.**
|
|
79976
|
-
|
|
79977
|
-
**If changes are needed:**
|
|
79978
|
-
- State EXACTLY what is wrong (file, line, code snippet)
|
|
79979
|
-
- Explain WHY it's a problem (not just that it's wrong)
|
|
79980
|
-
- Provide the EXACT fix or approach you want to see
|
|
79981
|
-
- If multiple issues, number them clearly
|
|
79982
|
-
|
|
79983
|
-
Example of BAD feedback:
|
|
79984
|
-
> "The code could be cleaner"
|
|
79985
|
-
|
|
79986
|
-
Example of GOOD feedback:
|
|
79987
|
-
> "In \`TaskQueue.tsx\` line 45, you're using \`any\` type for the task parameter.
|
|
79988
|
-
> This hides type errors. Change to: \`task: Task\` using the imported Task type."
|
|
79989
|
-
|
|
79990
|
-
**If the code is a mess - REJECT IT:**
|
|
79991
|
-
- Use \`handoff\` to reject messy code that "works"
|
|
79992
|
-
- Propose the refactor approach explicitly in your \`handoff\` message
|
|
79993
|
-
- Large refactors are acceptable if they improve maintainability
|
|
79994
|
-
- The goal is code that can be built upon, not just code that runs
|
|
79995
|
-
|
|
79996
|
-
**If approved:**
|
|
79997
|
-
- Confirm ALL requirements from original request are met
|
|
79998
|
-
- Briefly summarize what was verified
|
|
79999
|
-
- Hand off to user
|
|
80000
|
-
`, GUIDELINE_FILE_LOCATIONS = `
|
|
80001
|
-
## Guideline Files to Check
|
|
80002
|
-
|
|
80003
|
-
Different AI tools use different guideline file locations. Check any that exist:
|
|
80004
|
-
|
|
80005
|
-
### Cursor IDE
|
|
80006
|
-
- \`.cursor/rules/*.md\` - Cursor rules files
|
|
80007
|
-
- \`.cursorrules\` - Root cursor rules
|
|
80008
|
-
|
|
80009
|
-
### GitHub Copilot
|
|
80010
|
-
- \`.github/copilot-instructions.md\` - Copilot instructions
|
|
80011
|
-
- \`.github/copilot/*.md\` - Additional Copilot files
|
|
80012
|
-
|
|
80013
|
-
### Claude / Anthropic
|
|
80014
|
-
- \`CLAUDE.md\` - Claude-specific instructions
|
|
80015
|
-
- \`.claude/*.md\` - Claude rules directory
|
|
80016
|
-
|
|
80017
|
-
### OpenAI / Codex
|
|
80018
|
-
- \`.openai/guidelines.md\` - OpenAI guidelines
|
|
80019
|
-
- \`CODEX.md\` - Codex instructions
|
|
80020
|
-
|
|
80021
|
-
### Generic Agent Files
|
|
80022
|
-
- \`AGENTS.md\` - Generic agent guidelines
|
|
80023
|
-
- \`.ai/*.md\` - AI-related instructions
|
|
80024
|
-
- \`DEVELOPMENT.md\` - Development guidelines
|
|
80025
|
-
- \`CONTRIBUTING.md\` - Contribution guidelines
|
|
80026
|
-
|
|
80027
|
-
### Project-Specific
|
|
80028
|
-
- \`docs/design/*.md\` - Design guidelines
|
|
80029
|
-
- \`docs/style-guide.md\` - Style guides
|
|
80030
|
-
- \`guides/*.md\` - Project guides
|
|
80031
|
-
|
|
80032
|
-
**Important:** Adapt to what exists in THIS codebase. Not all projects have all files.
|
|
80033
|
-
`, REJECTION_GUIDANCE = `
|
|
80034
|
-
## When to Reject or Request Refactors
|
|
80035
|
-
|
|
80036
|
-
**Use \`handoff\` to maintain code quality:** The goal is a maintainable codebase.
|
|
80037
|
-
|
|
80038
|
-
### Reject When:
|
|
80039
|
-
|
|
80040
|
-
1. **Requirements Not Met**
|
|
80041
|
-
- The original user request is not fully addressed
|
|
80042
|
-
- Key features are missing or only partially implemented
|
|
80043
|
-
|
|
80044
|
-
2. **Significant Technical Debt**
|
|
80045
|
-
- Hacks or workarounds that will cause problems later
|
|
80046
|
-
- Code that is hard to understand or modify
|
|
80047
|
-
- Patterns that don't scale or won't work with future features
|
|
80048
|
-
|
|
80049
|
-
3. **Type Safety Violations**
|
|
80050
|
-
- Widespread use of \`any\` or type assertions
|
|
80051
|
-
- Missing proper error types or return types
|
|
80052
|
-
- Type errors being suppressed rather than fixed
|
|
80053
|
-
|
|
80054
|
-
4. **Architectural Issues**
|
|
80055
|
-
- Code in wrong location (logic in UI, UI in logic)
|
|
80056
|
-
- Duplication of existing functionality
|
|
80057
|
-
- Tight coupling that prevents testing/reuse
|
|
80058
|
-
|
|
80059
|
-
### Propose Refactors When:
|
|
80060
|
-
|
|
80061
|
-
1. **The fix is bigger than the feature**
|
|
80062
|
-
If cleaning up the code would take more effort than the original change,
|
|
80063
|
-
but the mess will compound over time - propose the refactor.
|
|
80064
|
-
|
|
80065
|
-
2. **Patterns are inconsistent**
|
|
80066
|
-
If new code follows different patterns than existing code,
|
|
80067
|
-
propose alignment to the established pattern.
|
|
80068
|
-
|
|
80069
|
-
3. **Abstractions are wrong**
|
|
80070
|
-
If the code is solving the problem at the wrong level of abstraction,
|
|
80071
|
-
propose the right approach even if it means starting over.
|
|
80072
|
-
|
|
80073
|
-
### How to Propose Refactors:
|
|
80074
|
-
|
|
80075
|
-
1. Explain the problem clearly
|
|
80076
|
-
2. Describe the desired end state
|
|
80077
|
-
3. Suggest whether to:
|
|
80078
|
-
- Fix now before merging
|
|
80079
|
-
- Create a follow-up task for later
|
|
80080
|
-
- Block on the refactor
|
|
80081
|
-
|
|
80082
|
-
**Remember:** Approving bad code costs more than rejecting it.
|
|
80083
|
-
`;
|
|
80084
|
-
|
|
80085
78227
|
// ../../services/backend/prompts/review-guidelines/index.ts
|
|
80086
78228
|
var init_review_guidelines = () => {};
|
|
80087
|
-
|
|
80088
|
-
// ../../services/backend/prompts/policies/security.ts
|
|
80089
|
-
function getSecurityPolicy() {
|
|
80090
|
-
return SECURITY_POLICY;
|
|
80091
|
-
}
|
|
80092
|
-
var SECURITY_POLICY = `
|
|
80093
|
-
## Security Review Policy
|
|
80094
|
-
|
|
80095
|
-
These are general security principles. Adapt to your codebase's specific security requirements.
|
|
80096
|
-
|
|
80097
|
-
### Authentication & Authorization
|
|
80098
|
-
|
|
80099
|
-
- [ ] Authentication checks are in place where required
|
|
80100
|
-
- [ ] Authorization verifies user has permission for the action
|
|
80101
|
-
- [ ] Session handling follows established patterns
|
|
80102
|
-
- [ ] No hardcoded credentials or secrets
|
|
80103
|
-
|
|
80104
|
-
### Input Validation
|
|
80105
|
-
|
|
80106
|
-
- [ ] User input is validated before use
|
|
80107
|
-
- [ ] Input sanitization for database queries (SQL injection prevention)
|
|
80108
|
-
- [ ] Path traversal protection for file operations
|
|
80109
|
-
- [ ] Proper escaping for output contexts (XSS prevention)
|
|
80110
|
-
|
|
80111
|
-
### Data Handling
|
|
80112
|
-
|
|
80113
|
-
- [ ] Sensitive data is not logged
|
|
80114
|
-
- [ ] PII is handled according to privacy requirements
|
|
80115
|
-
- [ ] Secrets use environment variables, not hardcoded values
|
|
80116
|
-
- [ ] .env files are not committed
|
|
80117
|
-
|
|
80118
|
-
### API Security
|
|
80119
|
-
|
|
80120
|
-
- [ ] Rate limiting considerations for public endpoints
|
|
80121
|
-
- [ ] CORS configuration is appropriate
|
|
80122
|
-
- [ ] API responses don't leak sensitive information
|
|
80123
|
-
- [ ] Error messages don't expose internal details
|
|
80124
|
-
|
|
80125
|
-
### Common Vulnerabilities to Check
|
|
80126
|
-
|
|
80127
|
-
1. **Injection Attacks**
|
|
80128
|
-
- SQL/NoSQL injection
|
|
80129
|
-
- Command injection
|
|
80130
|
-
- Template injection
|
|
80131
|
-
|
|
80132
|
-
2. **Broken Access Control**
|
|
80133
|
-
- Missing authorization checks
|
|
80134
|
-
- IDOR (Insecure Direct Object Reference)
|
|
80135
|
-
- Privilege escalation
|
|
80136
|
-
|
|
80137
|
-
3. **Security Misconfiguration**
|
|
80138
|
-
- Debug mode in production
|
|
80139
|
-
- Exposed admin interfaces
|
|
80140
|
-
- Default credentials
|
|
80141
|
-
|
|
80142
|
-
4. **Cryptographic Issues**
|
|
80143
|
-
- Weak hashing algorithms
|
|
80144
|
-
- Insecure random number generation
|
|
80145
|
-
- Improper key management
|
|
80146
|
-
|
|
80147
|
-
### Codebase-Specific Security
|
|
80148
|
-
|
|
80149
|
-
Check these locations for security-related guidelines:
|
|
80150
|
-
- Security documentation in \`docs/security*.md\`
|
|
80151
|
-
- Authentication patterns in existing auth code
|
|
80152
|
-
- Existing security middleware/helpers
|
|
80153
|
-
- Security comments in sensitive code areas
|
|
80154
|
-
|
|
80155
|
-
**Important:** These are general guidelines. Always verify against your project's specific security requirements and compliance needs.
|
|
80156
|
-
`;
|
|
80157
|
-
|
|
80158
|
-
// ../../services/backend/prompts/policies/design.ts
|
|
80159
|
-
function getDesignPolicy() {
|
|
80160
|
-
return DESIGN_POLICY;
|
|
80161
|
-
}
|
|
80162
|
-
var DESIGN_POLICY = `
|
|
80163
|
-
## Design Review Policy
|
|
80164
|
-
|
|
80165
|
-
These are general design principles. Adapt to your codebase's specific design system.
|
|
80166
|
-
|
|
80167
|
-
### Design System Compliance
|
|
80168
|
-
|
|
80169
|
-
- [ ] Uses existing design tokens (colors, spacing, typography)
|
|
80170
|
-
- [ ] Follows established component patterns
|
|
80171
|
-
- [ ] Reuses existing components instead of creating duplicates
|
|
80172
|
-
- [ ] Styling uses semantic values, not hardcoded ones
|
|
80173
|
-
|
|
80174
|
-
### Color Usage
|
|
80175
|
-
|
|
80176
|
-
**Semantic colors should be preferred:**
|
|
80177
|
-
- Use \`text-foreground\` not \`text-black\`
|
|
80178
|
-
- Use \`bg-card\` not \`bg-white\`
|
|
80179
|
-
- Use \`border-border\` not \`border-gray-200\`
|
|
80180
|
-
|
|
80181
|
-
**Dark mode support:**
|
|
80182
|
-
- All UI should work in both light and dark mode
|
|
80183
|
-
- Brand/status colors need dark variants (e.g., \`bg-red-50 dark:bg-red-950/20\`)
|
|
80184
|
-
|
|
80185
|
-
### Component Patterns
|
|
80186
|
-
|
|
80187
|
-
- [ ] Components follow existing file structure conventions
|
|
80188
|
-
- [ ] Props are typed properly
|
|
80189
|
-
- [ ] Components are accessible (keyboard navigation, ARIA)
|
|
80190
|
-
- [ ] Responsive design is considered
|
|
80191
|
-
|
|
80192
|
-
### Typography
|
|
80193
|
-
|
|
80194
|
-
- [ ] Uses established font sizes from the design system
|
|
80195
|
-
- [ ] Heading hierarchy is semantic (h1, h2, etc.)
|
|
80196
|
-
- [ ] Text is readable at all sizes
|
|
80197
|
-
- [ ] Font weights follow conventions
|
|
80198
|
-
|
|
80199
|
-
### Spacing & Layout
|
|
80200
|
-
|
|
80201
|
-
- [ ] Uses design system spacing tokens
|
|
80202
|
-
- [ ] Layout is responsive
|
|
80203
|
-
- [ ] Alignment is consistent
|
|
80204
|
-
- [ ] Proper use of flexbox/grid patterns
|
|
80205
|
-
|
|
80206
|
-
### UX Considerations
|
|
80207
|
-
|
|
80208
|
-
- [ ] Loading states are handled
|
|
80209
|
-
- [ ] Error states have clear messaging
|
|
80210
|
-
- [ ] Empty states are designed
|
|
80211
|
-
- [ ] Interactive elements have hover/focus states
|
|
80212
|
-
|
|
80213
|
-
### Common Design Issues to Catch
|
|
80214
|
-
|
|
80215
|
-
1. **Inconsistent Styling**
|
|
80216
|
-
- Different button styles for similar actions
|
|
80217
|
-
- Inconsistent spacing between elements
|
|
80218
|
-
- Mixed font sizes within components
|
|
80219
|
-
|
|
80220
|
-
2. **Accessibility Gaps**
|
|
80221
|
-
- Missing keyboard navigation
|
|
80222
|
-
- Low color contrast
|
|
80223
|
-
- Missing ARIA labels
|
|
80224
|
-
- Focus states not visible
|
|
80225
|
-
|
|
80226
|
-
3. **Hardcoded Values**
|
|
80227
|
-
- Magic numbers for spacing (use tokens)
|
|
80228
|
-
- Hardcoded colors (use semantic colors)
|
|
80229
|
-
- Fixed widths that break responsive
|
|
80230
|
-
|
|
80231
|
-
4. **Component Duplication**
|
|
80232
|
-
- Recreating existing components
|
|
80233
|
-
- Copy-paste instead of abstraction
|
|
80234
|
-
- Similar patterns implemented differently
|
|
80235
|
-
|
|
80236
|
-
### Codebase-Specific Design
|
|
80237
|
-
|
|
80238
|
-
Check these locations for design guidelines:
|
|
80239
|
-
- \`docs/design/*.md\` - Design documentation
|
|
80240
|
-
- \`components/ui/\` - Existing UI component library
|
|
80241
|
-
- \`tailwind.config.*\` - Theme configuration
|
|
80242
|
-
- \`globals.css\` or theme files - CSS custom properties
|
|
80243
|
-
- \`AGENTS.md\` or \`CLAUDE.md\` - May contain UI guidelines
|
|
80244
|
-
|
|
80245
|
-
**Important:** These are general guidelines. Always verify against your project's specific design system.
|
|
80246
|
-
`;
|
|
80247
|
-
|
|
80248
|
-
// ../../services/backend/prompts/policies/performance.ts
|
|
80249
|
-
function getPerformancePolicy() {
|
|
80250
|
-
return PERFORMANCE_POLICY;
|
|
80251
|
-
}
|
|
80252
|
-
var PERFORMANCE_POLICY = `
|
|
80253
|
-
## Performance Review Policy
|
|
80254
|
-
|
|
80255
|
-
These are general performance principles. Adapt to your codebase's specific requirements.
|
|
80256
|
-
|
|
80257
|
-
### Frontend Performance
|
|
80258
|
-
|
|
80259
|
-
**React/Component Performance:**
|
|
80260
|
-
- [ ] \`useMemo\` used for expensive computations
|
|
80261
|
-
- [ ] \`useCallback\` used for callback props passed to child components
|
|
80262
|
-
- [ ] \`React.memo\` considered for components receiving stable props
|
|
80263
|
-
- [ ] No unnecessary re-renders (check dependency arrays)
|
|
80264
|
-
- [ ] Large lists use virtualization where appropriate
|
|
80265
|
-
|
|
80266
|
-
**Bundle Size:**
|
|
80267
|
-
- [ ] No large dependencies added for simple functionality
|
|
80268
|
-
- [ ] Dynamic imports (\`lazy\`) used for route-level code splitting
|
|
80269
|
-
- [ ] Tree-shaking friendly imports (avoid \`import * as\`)
|
|
80270
|
-
- [ ] Images/assets are appropriately sized and optimized
|
|
80271
|
-
|
|
80272
|
-
**Rendering:**
|
|
80273
|
-
- [ ] No layout thrashing (reading and writing DOM in loops)
|
|
80274
|
-
- [ ] CSS animations use \`transform\` and \`opacity\` where possible
|
|
80275
|
-
- [ ] Avoid inline styles that change frequently
|
|
80276
|
-
- [ ] Consider \`will-change\` for animated elements
|
|
80277
|
-
|
|
80278
|
-
### Backend Performance
|
|
80279
|
-
|
|
80280
|
-
**Database Queries:**
|
|
80281
|
-
- [ ] Queries use appropriate indexes
|
|
80282
|
-
- [ ] N+1 query patterns are avoided or justified
|
|
80283
|
-
- [ ] Pagination used for large result sets
|
|
80284
|
-
- [ ] Expensive queries are cached where appropriate
|
|
80285
|
-
|
|
80286
|
-
**API Design:**
|
|
80287
|
-
- [ ] Responses don't include unnecessary data
|
|
80288
|
-
- [ ] Batch endpoints available for bulk operations
|
|
80289
|
-
- [ ] Expensive operations are async/background where possible
|
|
80290
|
-
- [ ] Rate limiting considered for resource-intensive endpoints
|
|
80291
|
-
|
|
80292
|
-
**Memory & Resources:**
|
|
80293
|
-
- [ ] No memory leaks (event listeners cleaned up, subscriptions closed)
|
|
80294
|
-
- [ ] Large data structures are streamed, not loaded entirely
|
|
80295
|
-
- [ ] Connection pooling used for database/external services
|
|
80296
|
-
- [ ] Temporary files/resources are cleaned up
|
|
80297
|
-
|
|
80298
|
-
### Common Performance Issues to Catch
|
|
80299
|
-
|
|
80300
|
-
1. **Unnecessary Computation**
|
|
80301
|
-
- Computing values on every render
|
|
80302
|
-
- Recalculating derived data without memoization
|
|
80303
|
-
- Expensive operations in hot paths
|
|
80304
|
-
|
|
80305
|
-
2. **Over-fetching**
|
|
80306
|
-
- Requesting more data than needed
|
|
80307
|
-
- Missing pagination on large datasets
|
|
80308
|
-
- Not using projection/select for specific fields
|
|
80309
|
-
|
|
80310
|
-
3. **Under-caching**
|
|
80311
|
-
- Repeated identical API calls
|
|
80312
|
-
- Not caching expensive computations
|
|
80313
|
-
- Missing server-side caching for static data
|
|
80314
|
-
|
|
80315
|
-
4. **Blocking Operations**
|
|
80316
|
-
- Synchronous operations blocking the event loop
|
|
80317
|
-
- Not using async patterns for I/O
|
|
80318
|
-
- Long-running operations without progress feedback
|
|
80319
|
-
|
|
80320
|
-
5. **React-Specific Issues**
|
|
80321
|
-
- Missing dependency arrays causing infinite loops
|
|
80322
|
-
- Creating new objects/functions in render
|
|
80323
|
-
- Not using \`key\` prop properly in lists
|
|
80324
|
-
- State updates in useEffect without proper deps
|
|
80325
|
-
|
|
80326
|
-
### Platform-Specific Considerations
|
|
80327
|
-
|
|
80328
|
-
**Next.js:**
|
|
80329
|
-
- Server Components for static content
|
|
80330
|
-
- Client Components for interactive elements
|
|
80331
|
-
- Image optimization with next/image
|
|
80332
|
-
- Route segment config for caching
|
|
80333
|
-
|
|
80334
|
-
**Convex:**
|
|
80335
|
-
- Query indexing for filtered/sorted data
|
|
80336
|
-
- Pagination for large result sets
|
|
80337
|
-
- Optimistic updates for better UX
|
|
80338
|
-
- Reactive queries vs. one-time fetches
|
|
80339
|
-
|
|
80340
|
-
**General Web:**
|
|
80341
|
-
- Core Web Vitals (LCP, FID, CLS)
|
|
80342
|
-
- Time to Interactive (TTI)
|
|
80343
|
-
- First Contentful Paint (FCP)
|
|
80344
|
-
|
|
80345
|
-
### Questions to Ask
|
|
80346
|
-
|
|
80347
|
-
1. "Will this scale with 10x/100x more data?"
|
|
80348
|
-
2. "What happens with slow network conditions?"
|
|
80349
|
-
3. "Are there any O(n²) or worse algorithms?"
|
|
80350
|
-
4. "Could this operation be batched or debounced?"
|
|
80351
|
-
5. "Is this computation necessary on every render?"
|
|
80352
|
-
|
|
80353
|
-
**Important:** These are general guidelines. Performance requirements vary by application.
|
|
80354
|
-
Focus on user-facing performance impact rather than micro-optimizations.
|
|
80355
|
-
`;
|
|
80356
|
-
|
|
80357
78229
|
// ../../services/backend/prompts/generator.ts
|
|
80358
|
-
var exports_generator = {};
|
|
80359
|
-
__export(exports_generator, {
|
|
80360
|
-
getSecurityPolicy: () => getSecurityPolicy,
|
|
80361
|
-
getReviewGuidelines: () => getReviewGuidelines,
|
|
80362
|
-
getPerformancePolicy: () => getPerformancePolicy,
|
|
80363
|
-
getDesignPolicy: () => getDesignPolicy,
|
|
80364
|
-
generateRolePrompt: () => generateRolePrompt,
|
|
80365
|
-
generateHandoffOutput: () => generateHandoffOutput,
|
|
80366
|
-
generateGeneralInstructions: () => generateGeneralInstructions,
|
|
80367
|
-
composeSystemPrompt: () => composeSystemPrompt2,
|
|
80368
|
-
composeInitPrompt: () => composeInitPrompt,
|
|
80369
|
-
composeInitMessage: () => composeInitMessage
|
|
80370
|
-
});
|
|
80371
|
-
function generateGeneralInstructions(_input) {
|
|
80372
|
-
const sections = [];
|
|
80373
|
-
sections.push(getNextTaskGuidance());
|
|
80374
|
-
return sections.join(`
|
|
80375
|
-
|
|
80376
|
-
`);
|
|
80377
|
-
}
|
|
80378
|
-
function generateRolePrompt(ctx) {
|
|
80379
|
-
const selectorCtx = buildSelectorContext({
|
|
80380
|
-
role: ctx.role,
|
|
80381
|
-
teamRoles: ctx.teamRoles,
|
|
80382
|
-
teamId: ctx.teamId,
|
|
80383
|
-
teamName: ctx.teamName,
|
|
80384
|
-
teamEntryPoint: ctx.teamEntryPoint,
|
|
80385
|
-
convexUrl: ctx.convexUrl,
|
|
80386
|
-
chatroomId: ctx.chatroomId,
|
|
80387
|
-
workflow: ctx.currentClassification
|
|
80388
|
-
});
|
|
80389
|
-
const sections = [];
|
|
80390
|
-
sections.push(getRoleTitleSection(selectorCtx));
|
|
80391
|
-
sections.push(getRoleDescriptionSection(selectorCtx));
|
|
80392
|
-
sections.push(getGlossarySection({ convexUrl: ctx.convexUrl ?? "", chatroomId: ctx.chatroomId }));
|
|
80393
|
-
sections.push(getRoleGuidanceSection(selectorCtx));
|
|
80394
|
-
if (ctx.currentClassification) {
|
|
80395
|
-
sections.push(getCurrentClassificationSection(ctx.currentClassification));
|
|
80396
|
-
}
|
|
80397
|
-
sections.push(getHandoffOptionsSection({
|
|
80398
|
-
availableHandoffRoles: ctx.availableHandoffRoles
|
|
80399
|
-
}));
|
|
80400
|
-
sections.push(getCommandsReferenceSection({
|
|
80401
|
-
chatroomId: ctx.chatroomId,
|
|
80402
|
-
role: ctx.role,
|
|
80403
|
-
convexUrl: ctx.convexUrl
|
|
80404
|
-
}));
|
|
80405
|
-
return composeSections(sections);
|
|
80406
|
-
}
|
|
80407
|
-
function buildInitPromptSections(input, selectorCtx) {
|
|
80408
|
-
const { chatroomId, role, teamRoles, convexUrl } = input;
|
|
80409
|
-
const otherRoles = teamRoles.filter((r) => r.toLowerCase() !== role.toLowerCase());
|
|
80410
|
-
const handoffTargets = [...new Set([...otherRoles, "user"])];
|
|
80411
|
-
const sections = [
|
|
80412
|
-
getTeamHeaderSection(input.teamName),
|
|
80413
|
-
getRoleTitleSection(selectorCtx),
|
|
80414
|
-
getRoleDescriptionSection(selectorCtx),
|
|
80415
|
-
getGlossarySection({ convexUrl: convexUrl ?? "", chatroomId }),
|
|
80416
|
-
getSessionVsChatroomTaskSection(),
|
|
80417
|
-
getGettingStartedSection(selectorCtx),
|
|
80418
|
-
getClassificationGuideSection(selectorCtx),
|
|
80419
|
-
getRoleGuidanceSection(selectorCtx),
|
|
80420
|
-
getHandoffOptionsSection({ availableHandoffRoles: handoffTargets }),
|
|
80421
|
-
getCommandsReferenceSection({ chatroomId, role, convexUrl }),
|
|
80422
|
-
getNextStepSection({ chatroomId, role, convexUrl })
|
|
80423
|
-
];
|
|
80424
|
-
return sections;
|
|
80425
|
-
}
|
|
80426
|
-
function composeSystemPrompt2(input) {
|
|
80427
|
-
if (isNativeHarness(input.agentHarness)) {
|
|
80428
|
-
return composeNativeSystemPrompt(input);
|
|
80429
|
-
}
|
|
80430
|
-
const { chatroomId, role, teamId, teamName, teamRoles, teamEntryPoint, convexUrl } = input;
|
|
80431
|
-
const selectorCtx = buildSelectorContext({
|
|
80432
|
-
role,
|
|
80433
|
-
teamRoles,
|
|
80434
|
-
teamId,
|
|
80435
|
-
teamName,
|
|
80436
|
-
teamEntryPoint,
|
|
80437
|
-
convexUrl,
|
|
80438
|
-
chatroomId,
|
|
80439
|
-
agentType: input.agentType,
|
|
80440
|
-
nativeIntegration: false
|
|
80441
|
-
});
|
|
80442
|
-
return composeSections(buildInitPromptSections(input, selectorCtx));
|
|
80443
|
-
}
|
|
80444
78230
|
function isEnhancerCheckInQueuedHandoff(params) {
|
|
80445
78231
|
return params.enhancerCheckInQueued === true && params.role.toLowerCase() === "planner" && params.nextRole.toLowerCase() === "enhancer";
|
|
80446
78232
|
}
|
|
@@ -80480,17 +78266,6 @@ function generateHandoffOutput(params) {
|
|
|
80480
78266
|
return lines.join(`
|
|
80481
78267
|
`);
|
|
80482
78268
|
}
|
|
80483
|
-
function composeInitMessage(_input) {
|
|
80484
|
-
return "";
|
|
80485
|
-
}
|
|
80486
|
-
function composeInitPrompt(input) {
|
|
80487
|
-
const systemPrompt = composeSystemPrompt2(input);
|
|
80488
|
-
const initMessage = composeInitMessage(input);
|
|
80489
|
-
const initPrompt = initMessage ? `${systemPrompt}
|
|
80490
|
-
|
|
80491
|
-
${initMessage}` : systemPrompt;
|
|
80492
|
-
return { systemPrompt, initMessage, initPrompt };
|
|
80493
|
-
}
|
|
80494
78269
|
var init_generator = __esm(() => {
|
|
80495
78270
|
init_command();
|
|
80496
78271
|
init_reminder();
|
|
@@ -99284,6 +97059,30 @@ var init_assigned_task_snapshot_store = __esm(() => {
|
|
|
99284
97059
|
rows = [];
|
|
99285
97060
|
});
|
|
99286
97061
|
|
|
97062
|
+
// src/commands/machine/daemon-start/restart-orchestrator-in-flight.ts
|
|
97063
|
+
function roleKey2(chatroomId, role) {
|
|
97064
|
+
return `${chatroomId}:${role.toLowerCase()}`;
|
|
97065
|
+
}
|
|
97066
|
+
function markRestartOrchestratorInFlight(chatroomId, role, correlationId) {
|
|
97067
|
+
inFlight.set(roleKey2(chatroomId, role), correlationId);
|
|
97068
|
+
}
|
|
97069
|
+
function clearRestartOrchestratorInFlight(chatroomId, role, correlationId) {
|
|
97070
|
+
const key = roleKey2(chatroomId, role);
|
|
97071
|
+
if (correlationId !== undefined && inFlight.get(key) !== correlationId)
|
|
97072
|
+
return;
|
|
97073
|
+
inFlight.delete(key);
|
|
97074
|
+
}
|
|
97075
|
+
function isRestartOrchestratorInFlight(chatroomId, role) {
|
|
97076
|
+
return inFlight.has(roleKey2(chatroomId, role));
|
|
97077
|
+
}
|
|
97078
|
+
function filterSnapshotsExcludingRestartInFlight(snapshots) {
|
|
97079
|
+
return snapshots.filter((row) => !isRestartOrchestratorInFlight(row.chatroomId, row.agentConfig.role));
|
|
97080
|
+
}
|
|
97081
|
+
var inFlight;
|
|
97082
|
+
var init_restart_orchestrator_in_flight = __esm(() => {
|
|
97083
|
+
inFlight = new Map;
|
|
97084
|
+
});
|
|
97085
|
+
|
|
99287
97086
|
// src/commands/machine/daemon-start/native-task-delivery-coordinator.ts
|
|
99288
97087
|
class NativeTaskDeliveryCoordinator {
|
|
99289
97088
|
onSessionLost(params) {
|
|
@@ -99296,6 +97095,8 @@ class NativeTaskDeliveryCoordinator {
|
|
|
99296
97095
|
getRoleDeliveryState().resetDeliveryState(chatroomId, role);
|
|
99297
97096
|
}
|
|
99298
97097
|
tryInjectNextForRole(chatroomId, role) {
|
|
97098
|
+
if (isRestartOrchestratorInFlight(chatroomId, role))
|
|
97099
|
+
return;
|
|
99299
97100
|
const session2 = getNativeDeliverySession();
|
|
99300
97101
|
if (!session2)
|
|
99301
97102
|
return;
|
|
@@ -99315,7 +97116,10 @@ class NativeTaskDeliveryCoordinator {
|
|
|
99315
97116
|
});
|
|
99316
97117
|
}
|
|
99317
97118
|
reconcileAssignedTasks(params) {
|
|
99318
|
-
const
|
|
97119
|
+
const tasks = filterSnapshotsExcludingRestartInFlight(params.tasks);
|
|
97120
|
+
if (tasks.length === 0)
|
|
97121
|
+
return;
|
|
97122
|
+
const { runtime: runtime4, effectContext: effectContext2, agentMgr, sessionDeps, machineId } = params;
|
|
99319
97123
|
const deliveryState = getRoleDeliveryState();
|
|
99320
97124
|
const ledger = getNativeDeliveryLedger();
|
|
99321
97125
|
const pendingFirst = [...tasks].sort((a, b) => {
|
|
@@ -99404,6 +97208,8 @@ function resetRoleDeliveryState(chatroomId, role) {
|
|
|
99404
97208
|
getRoleDeliveryState().resetDeliveryState(chatroomId, role);
|
|
99405
97209
|
}
|
|
99406
97210
|
function notifyNativeTurnIdle(params) {
|
|
97211
|
+
if (isRestartOrchestratorInFlight(params.chatroomId, params.role))
|
|
97212
|
+
return;
|
|
99407
97213
|
logNativeDeliveryPrimary(params.role, params.chatroomId);
|
|
99408
97214
|
getNativeTaskDeliveryCoordinator().tryInjectNextForRole(params.chatroomId, params.role);
|
|
99409
97215
|
}
|
|
@@ -99416,6 +97222,7 @@ var init_native_task_delivery_coordinator = __esm(() => {
|
|
|
99416
97222
|
init_api3();
|
|
99417
97223
|
init_assigned_task_snapshot_store();
|
|
99418
97224
|
init_convex_error();
|
|
97225
|
+
init_restart_orchestrator_in_flight();
|
|
99419
97226
|
});
|
|
99420
97227
|
|
|
99421
97228
|
// src/commands/machine/daemon-start/restart-orchestrator.ts
|
|
@@ -99438,14 +97245,6 @@ async function waitForHarnessSessionId(deps, event, pid) {
|
|
|
99438
97245
|
if (initial?.harnessSessionId) {
|
|
99439
97246
|
return initial.harnessSessionId;
|
|
99440
97247
|
}
|
|
99441
|
-
await deps.session.backend.mutation(api.machines.emitHarnessSessionAwaiting, {
|
|
99442
|
-
sessionId: deps.session.sessionId,
|
|
99443
|
-
machineId: deps.session.machineId,
|
|
99444
|
-
chatroomId: event.chatroomId,
|
|
99445
|
-
role: event.role,
|
|
99446
|
-
pid,
|
|
99447
|
-
timeoutMs: HARNESS_SESSION_READY_TIMEOUT_MS
|
|
99448
|
-
});
|
|
99449
97248
|
const deadline = Date.now() + HARNESS_SESSION_READY_TIMEOUT_MS;
|
|
99450
97249
|
while (Date.now() < deadline) {
|
|
99451
97250
|
const slot = deps.agentMgr.getSlot(event.chatroomId, event.role);
|
|
@@ -99454,14 +97253,6 @@ async function waitForHarnessSessionId(deps, event, pid) {
|
|
|
99454
97253
|
}
|
|
99455
97254
|
await sleep5(100);
|
|
99456
97255
|
}
|
|
99457
|
-
await deps.session.backend.mutation(api.machines.emitHarnessSessionTimeout, {
|
|
99458
|
-
sessionId: deps.session.sessionId,
|
|
99459
|
-
machineId: deps.session.machineId,
|
|
99460
|
-
chatroomId: event.chatroomId,
|
|
99461
|
-
role: event.role,
|
|
99462
|
-
pid,
|
|
99463
|
-
timeoutMs: HARNESS_SESSION_READY_TIMEOUT_MS
|
|
99464
|
-
});
|
|
99465
97256
|
await deps.agentMgr.stop({
|
|
99466
97257
|
chatroomId: event.chatroomId,
|
|
99467
97258
|
role: event.role,
|
|
@@ -99556,15 +97347,14 @@ async function deliverPendingTasks(deps, event) {
|
|
|
99556
97347
|
}
|
|
99557
97348
|
async function runRestartOrchestrator(deps, event) {
|
|
99558
97349
|
const { chatroomId, role } = event;
|
|
97350
|
+
markRestartOrchestratorInFlight(chatroomId, role, event.correlationId);
|
|
99559
97351
|
try {
|
|
99560
|
-
await emitPhase(deps, event, "reset");
|
|
99561
97352
|
resetRoleDeliveryState(chatroomId, role);
|
|
99562
97353
|
await deps.agentMgr.stop({
|
|
99563
97354
|
chatroomId,
|
|
99564
97355
|
role,
|
|
99565
97356
|
reason: "user.restart"
|
|
99566
97357
|
});
|
|
99567
|
-
await emitPhase(deps, event, "spawn");
|
|
99568
97358
|
const spawnResult = await exports_Effect.runPromise(deps.agentMgr.ensureRunning({
|
|
99569
97359
|
chatroomId,
|
|
99570
97360
|
role,
|
|
@@ -99578,23 +97368,12 @@ async function runRestartOrchestrator(deps, event) {
|
|
|
99578
97368
|
await emitPhase(deps, event, "failed", spawnResult.error ?? "spawn failed");
|
|
99579
97369
|
return;
|
|
99580
97370
|
}
|
|
99581
|
-
await emitPhase(deps, event, "await_session");
|
|
99582
97371
|
const harnessSessionId = await waitForHarnessSessionId(deps, event, spawnResult.pid);
|
|
99583
97372
|
if (!harnessSessionId) {
|
|
99584
97373
|
await emitPhase(deps, event, "failed", "harnessSessionId timeout");
|
|
99585
97374
|
return;
|
|
99586
97375
|
}
|
|
99587
|
-
await deps.session.backend.mutation(api.machines.emitHarnessSessionReady, {
|
|
99588
|
-
sessionId: deps.session.sessionId,
|
|
99589
|
-
machineId: deps.session.machineId,
|
|
99590
|
-
chatroomId,
|
|
99591
|
-
role,
|
|
99592
|
-
harnessSessionId,
|
|
99593
|
-
pid: spawnResult.pid
|
|
99594
|
-
});
|
|
99595
97376
|
await forceNativeWaiting(deps, event);
|
|
99596
|
-
await emitPhase(deps, event, "ready");
|
|
99597
|
-
await emitPhase(deps, event, "deliver");
|
|
99598
97377
|
const deliveredTaskIds = await deliverPendingTasks(deps, event);
|
|
99599
97378
|
await deps.session.backend.mutation(api.machines.emitRestartCompleted, {
|
|
99600
97379
|
sessionId: deps.session.sessionId,
|
|
@@ -99604,10 +97383,11 @@ async function runRestartOrchestrator(deps, event) {
|
|
|
99604
97383
|
correlationId: event.correlationId,
|
|
99605
97384
|
deliveredTaskIds
|
|
99606
97385
|
});
|
|
99607
|
-
await emitPhase(deps, event, "completed");
|
|
99608
97386
|
} catch (err) {
|
|
99609
97387
|
console.warn(`[RestartOrchestrator] failed for ${role}@${chatroomId}: ${getErrorMessage(err)}`);
|
|
99610
97388
|
await emitPhase(deps, event, "failed", getErrorMessage(err));
|
|
97389
|
+
} finally {
|
|
97390
|
+
clearRestartOrchestratorInFlight(chatroomId, role, event.correlationId);
|
|
99611
97391
|
}
|
|
99612
97392
|
}
|
|
99613
97393
|
var init_restart_orchestrator = __esm(() => {
|
|
@@ -99621,6 +97401,7 @@ var init_restart_orchestrator = __esm(() => {
|
|
|
99621
97401
|
init_native_task_injector();
|
|
99622
97402
|
init_api3();
|
|
99623
97403
|
init_convex_error();
|
|
97404
|
+
init_restart_orchestrator_in_flight();
|
|
99624
97405
|
});
|
|
99625
97406
|
|
|
99626
97407
|
// src/events/daemon/agent/on-request-restart-agent.ts
|
|
@@ -100742,6 +98523,17 @@ async function openFinder(workingDir) {
|
|
|
100742
98523
|
execFireAndForget(`${cmd} ${escapeShellArg(workingDir)}`, "open-finder");
|
|
100743
98524
|
return { success: true };
|
|
100744
98525
|
}
|
|
98526
|
+
async function openCursor(workingDir) {
|
|
98527
|
+
const available = await isCliAvailable("cursor");
|
|
98528
|
+
if (!available) {
|
|
98529
|
+
return {
|
|
98530
|
+
success: false,
|
|
98531
|
+
error: "Cursor CLI (cursor) not found. Install via: Cursor → Cmd+Shift+P → 'Shell Command: Install cursor in PATH'"
|
|
98532
|
+
};
|
|
98533
|
+
}
|
|
98534
|
+
execFireAndForget(`cursor ${escapeShellArg(workingDir)}`, "open-cursor");
|
|
98535
|
+
return { success: true };
|
|
98536
|
+
}
|
|
100745
98537
|
async function openGithubDesktop(workingDir) {
|
|
100746
98538
|
const available = await isCliAvailable("github");
|
|
100747
98539
|
if (!available) {
|
|
@@ -100816,6 +98608,7 @@ var init_execute_local_action = __esm(() => {
|
|
|
100816
98608
|
actionHandlers = {
|
|
100817
98609
|
"open-vscode": openVscode,
|
|
100818
98610
|
"open-finder": openFinder,
|
|
98611
|
+
"open-cursor": openCursor,
|
|
100819
98612
|
"open-github-desktop": openGithubDesktop,
|
|
100820
98613
|
"git-discard-file": gitDiscardFileAction,
|
|
100821
98614
|
"git-discard-all": gitDiscardAllAction,
|
|
@@ -103236,7 +101029,7 @@ var init_open_pending_session = __esm(() => {
|
|
|
103236
101029
|
|
|
103237
101030
|
// src/commands/machine/daemon-start/direct-harness/session-subscriber.ts
|
|
103238
101031
|
function startSessionSubscriber(daemonSession, wsClient2, deps) {
|
|
103239
|
-
const
|
|
101032
|
+
const inFlight2 = new Set;
|
|
103240
101033
|
const unsub = wsClient2.onUpdate(api.daemon.directHarness.sessions.listPendingSessionsForMachine, {
|
|
103241
101034
|
sessionId: daemonSession.sessionId,
|
|
103242
101035
|
machineId: daemonSession.machineId
|
|
@@ -103245,9 +101038,9 @@ function startSessionSubscriber(daemonSession, wsClient2, deps) {
|
|
|
103245
101038
|
return;
|
|
103246
101039
|
for (const session2 of pendingSessions) {
|
|
103247
101040
|
const rowId = session2._id;
|
|
103248
|
-
if (
|
|
101041
|
+
if (inFlight2.has(rowId))
|
|
103249
101042
|
continue;
|
|
103250
|
-
|
|
101043
|
+
inFlight2.add(rowId);
|
|
103251
101044
|
(async () => {
|
|
103252
101045
|
const harnessName = session2.opencode?.harnessName ?? "opencode-sdk";
|
|
103253
101046
|
const agent = session2.opencode?.lastUsedConfig?.agent ?? "build";
|
|
@@ -103258,7 +101051,7 @@ function startSessionSubscriber(daemonSession, wsClient2, deps) {
|
|
|
103258
101051
|
harnessName,
|
|
103259
101052
|
lastUsedConfig: { agent, ...model ? { model } : {} }
|
|
103260
101053
|
}, { logPrefix: "[direct-harness]", handleProviderIdEvents: true });
|
|
103261
|
-
})().finally(() =>
|
|
101054
|
+
})().finally(() => inFlight2.delete(rowId));
|
|
103262
101055
|
}
|
|
103263
101056
|
}, (err) => {
|
|
103264
101057
|
console.warn("[direct-harness] Session subscription error:", err instanceof Error ? err.message : String(err));
|
|
@@ -103793,21 +101586,21 @@ var init_prompt_subscriber2 = __esm(() => {
|
|
|
103793
101586
|
|
|
103794
101587
|
// src/commands/machine/daemon-start/agentic-query/session-subscriber.ts
|
|
103795
101588
|
function startSessionSubscriber2(daemonSession, wsClient2, deps) {
|
|
103796
|
-
const
|
|
101589
|
+
const inFlight2 = new Set;
|
|
103797
101590
|
const unsub = wsClient2.onUpdate(api.daemon.agenticQuery.runs.pendingForMachine, { sessionId: daemonSession.sessionId, machineId: daemonSession.machineId }, (pendingSessions) => {
|
|
103798
101591
|
if (!pendingSessions || pendingSessions.length === 0)
|
|
103799
101592
|
return;
|
|
103800
101593
|
for (const session2 of pendingSessions) {
|
|
103801
101594
|
const rowId = session2.runId;
|
|
103802
|
-
if (
|
|
101595
|
+
if (inFlight2.has(rowId))
|
|
103803
101596
|
continue;
|
|
103804
|
-
|
|
101597
|
+
inFlight2.add(rowId);
|
|
103805
101598
|
openPendingHarnessSession(daemonSession, deps, {
|
|
103806
101599
|
rowId: session2.runId,
|
|
103807
101600
|
workspaceId: session2.workspaceId,
|
|
103808
101601
|
harnessName: session2.harnessName,
|
|
103809
101602
|
lastUsedConfig: session2.lastUsedConfig
|
|
103810
|
-
}, { logPrefix: "[agentic-query]", handleProviderIdEvents: false }).finally(() =>
|
|
101603
|
+
}, { logPrefix: "[agentic-query]", handleProviderIdEvents: false }).finally(() => inFlight2.delete(rowId));
|
|
103811
101604
|
}
|
|
103812
101605
|
}, (err) => {
|
|
103813
101606
|
console.warn("[agentic-query] Session subscription error:", err instanceof Error ? err.message : String(err));
|
|
@@ -104100,12 +101893,12 @@ var init_wait_for_enhancer_job = __esm(() => {
|
|
|
104100
101893
|
|
|
104101
101894
|
// src/commands/machine/daemon-start/enhancer/job-subscriber.ts
|
|
104102
101895
|
function startEnhancerJobSubscriber(sessionId, machineId, convexUrl, backend2, wsClient2, agentServices) {
|
|
104103
|
-
const
|
|
101896
|
+
const inFlight2 = new Set;
|
|
104104
101897
|
const unsub = wsClient2.onUpdate(api.daemon.enhancer.index.pendingForMachine, { sessionId, machineId }, (jobs) => {
|
|
104105
101898
|
for (const job of jobs ?? []) {
|
|
104106
|
-
if (
|
|
101899
|
+
if (inFlight2.has(job.jobId))
|
|
104107
101900
|
continue;
|
|
104108
|
-
|
|
101901
|
+
inFlight2.add(job.jobId);
|
|
104109
101902
|
(async () => {
|
|
104110
101903
|
let claimed = false;
|
|
104111
101904
|
let chatroomId = job.chatroomId;
|
|
@@ -104139,7 +101932,7 @@ function startEnhancerJobSubscriber(sessionId, machineId, convexUrl, backend2, w
|
|
|
104139
101932
|
});
|
|
104140
101933
|
return;
|
|
104141
101934
|
}
|
|
104142
|
-
|
|
101935
|
+
const spawned = await service3.spawn({
|
|
104143
101936
|
workingDir: payload.workingDir,
|
|
104144
101937
|
prompt: createSpawnPrompt(payload.taskEnvelope),
|
|
104145
101938
|
systemPrompt: payload.systemPrompt,
|
|
@@ -104151,18 +101944,18 @@ function startEnhancerJobSubscriber(sessionId, machineId, convexUrl, backend2, w
|
|
|
104151
101944
|
},
|
|
104152
101945
|
resolvedConvexUrl: convexUrl
|
|
104153
101946
|
});
|
|
104154
|
-
spawnResult
|
|
101947
|
+
spawnResult = spawned;
|
|
101948
|
+
spawned.onLogLine?.((line) => {
|
|
104155
101949
|
writeEnhancerLog(line);
|
|
104156
101950
|
});
|
|
104157
|
-
|
|
104158
|
-
const outcome = await waitForEnhancerJobResolution({
|
|
101951
|
+
await waitForEnhancerJobResolution({
|
|
104159
101952
|
sessionId,
|
|
104160
101953
|
chatroomId: payload.chatroomId,
|
|
104161
101954
|
jobId: payload.jobId,
|
|
104162
101955
|
backend: backend2,
|
|
104163
|
-
onAssistantText:
|
|
104164
|
-
onAgentEnd:
|
|
104165
|
-
onExit: (cb) =>
|
|
101956
|
+
onAssistantText: spawned.onAssistantText ? (cb) => spawned.onAssistantText?.(cb) : undefined,
|
|
101957
|
+
onAgentEnd: spawned.onAgentEnd ? (cb) => spawned.onAgentEnd?.(cb) : undefined,
|
|
101958
|
+
onExit: (cb) => spawned.onExit(() => cb()),
|
|
104166
101959
|
onSalvageComplete: async (content) => {
|
|
104167
101960
|
await backend2.mutation(api.web.enhancer.index.complete, {
|
|
104168
101961
|
sessionId,
|
|
@@ -104193,7 +101986,7 @@ function startEnhancerJobSubscriber(sessionId, machineId, convexUrl, backend2, w
|
|
|
104193
101986
|
});
|
|
104194
101987
|
}
|
|
104195
101988
|
} finally {
|
|
104196
|
-
|
|
101989
|
+
inFlight2.delete(job.jobId);
|
|
104197
101990
|
if (spawnResult && service3) {
|
|
104198
101991
|
try {
|
|
104199
101992
|
await service3.stop(spawnResult.pid);
|
|
@@ -109435,6 +107228,53 @@ var init_crash_loop_tracker = __esm(() => {
|
|
|
109435
107228
|
];
|
|
109436
107229
|
});
|
|
109437
107230
|
|
|
107231
|
+
// src/infrastructure/services/remote-agents/native-spawn-presence.ts
|
|
107232
|
+
async function emitNativeWaitingAfterSpawn(ctx, harness, opts) {
|
|
107233
|
+
if (!getHarnessCapabilities(harness).supportsNativeIntegration) {
|
|
107234
|
+
return false;
|
|
107235
|
+
}
|
|
107236
|
+
try {
|
|
107237
|
+
await ctx.backend.mutation(api.participants.join, {
|
|
107238
|
+
sessionId: ctx.sessionId,
|
|
107239
|
+
chatroomId: ctx.chatroomId,
|
|
107240
|
+
role: ctx.role,
|
|
107241
|
+
action: NATIVE_WAITING_ACTION
|
|
107242
|
+
});
|
|
107243
|
+
return true;
|
|
107244
|
+
} catch (err) {
|
|
107245
|
+
const error51 = err instanceof Error ? err : new Error(String(err));
|
|
107246
|
+
if (opts?.onError) {
|
|
107247
|
+
opts.onError(error51);
|
|
107248
|
+
}
|
|
107249
|
+
return false;
|
|
107250
|
+
}
|
|
107251
|
+
}
|
|
107252
|
+
function wireThrottledTokenActivityOnOutput(opts) {
|
|
107253
|
+
const now = opts.now ?? (() => Date.now());
|
|
107254
|
+
const throttleMs = opts.throttleMs ?? NATIVE_TOKEN_ACTIVITY_THROTTLE_MS;
|
|
107255
|
+
let lastReportedTokenAt = 0;
|
|
107256
|
+
const register = opts.spawnResult.onOutput;
|
|
107257
|
+
if (!register)
|
|
107258
|
+
return;
|
|
107259
|
+
register(() => {
|
|
107260
|
+
const t = now();
|
|
107261
|
+
if (lastReportedTokenAt === 0 || t - lastReportedTokenAt >= throttleMs) {
|
|
107262
|
+
lastReportedTokenAt = t;
|
|
107263
|
+
opts.backend.mutation(api.participants.updateTokenActivity, {
|
|
107264
|
+
sessionId: opts.sessionId,
|
|
107265
|
+
chatroomId: opts.chatroomId,
|
|
107266
|
+
role: opts.role
|
|
107267
|
+
}).catch(() => {});
|
|
107268
|
+
}
|
|
107269
|
+
});
|
|
107270
|
+
}
|
|
107271
|
+
var NATIVE_TOKEN_ACTIVITY_THROTTLE_MS = 30000;
|
|
107272
|
+
var init_native_spawn_presence = __esm(() => {
|
|
107273
|
+
init_participant();
|
|
107274
|
+
init_types();
|
|
107275
|
+
init_api3();
|
|
107276
|
+
});
|
|
107277
|
+
|
|
109438
107278
|
// src/infrastructure/services/agent-process-manager/turn-completed-backend.ts
|
|
109439
107279
|
function createTurnCompletedBackend(deps) {
|
|
109440
107280
|
return {
|
|
@@ -111275,17 +109115,13 @@ class AgentProcessManager {
|
|
|
111275
109115
|
this.applyHarnessSessionIdUpdate(slotKey, slot, opts.chatroomId, opts.role, info);
|
|
111276
109116
|
});
|
|
111277
109117
|
}
|
|
111278
|
-
|
|
111279
|
-
|
|
111280
|
-
|
|
111281
|
-
|
|
111282
|
-
|
|
111283
|
-
|
|
111284
|
-
|
|
111285
|
-
chatroomId: opts.chatroomId,
|
|
111286
|
-
role: opts.role
|
|
111287
|
-
}).catch(() => {});
|
|
111288
|
-
}
|
|
109118
|
+
wireThrottledTokenActivityOnOutput({
|
|
109119
|
+
backend: this.deps.backend,
|
|
109120
|
+
sessionId: this.deps.sessionId,
|
|
109121
|
+
chatroomId: opts.chatroomId,
|
|
109122
|
+
role: opts.role,
|
|
109123
|
+
spawnResult,
|
|
109124
|
+
now: () => this.deps.clock.now()
|
|
111289
109125
|
});
|
|
111290
109126
|
}
|
|
111291
109127
|
async finalizeRunningSlot(key, slot, opts, spawnResult, wantResume) {
|
|
@@ -111302,20 +109138,16 @@ class AgentProcessManager {
|
|
|
111302
109138
|
await this.emitNativeWaiting(opts.chatroomId, opts.role, opts.agentHarness);
|
|
111303
109139
|
}
|
|
111304
109140
|
async emitNativeWaiting(chatroomId, role, harness) {
|
|
111305
|
-
|
|
111306
|
-
|
|
111307
|
-
|
|
111308
|
-
|
|
111309
|
-
|
|
111310
|
-
|
|
111311
|
-
|
|
111312
|
-
|
|
111313
|
-
}
|
|
111314
|
-
|
|
111315
|
-
} catch (err) {
|
|
111316
|
-
console.log(` ⚠️ Failed to emit native:waiting for ${role}: ${err.message}`);
|
|
111317
|
-
return false;
|
|
111318
|
-
}
|
|
109141
|
+
return emitNativeWaitingAfterSpawn({
|
|
109142
|
+
backend: this.deps.backend,
|
|
109143
|
+
sessionId: this.deps.sessionId,
|
|
109144
|
+
chatroomId,
|
|
109145
|
+
role
|
|
109146
|
+
}, harness, {
|
|
109147
|
+
onError: (err) => {
|
|
109148
|
+
console.log(` ⚠️ Failed to emit native:waiting for ${role}: ${err.message}`);
|
|
109149
|
+
}
|
|
109150
|
+
});
|
|
111319
109151
|
}
|
|
111320
109152
|
async doEnsureRunning(key, slot, opts) {
|
|
111321
109153
|
slot.state = "spawning";
|
|
@@ -111503,6 +109335,7 @@ var AGENT_EXIT_RETRY_INTERVAL_MS = 1e4, STOPPING_TIMEOUT_MS = 30000;
|
|
|
111503
109335
|
var init_agent_process_manager = __esm(() => {
|
|
111504
109336
|
init_types();
|
|
111505
109337
|
init_participant();
|
|
109338
|
+
init_native_spawn_presence();
|
|
111506
109339
|
init_esm();
|
|
111507
109340
|
init_turn_completed_backend();
|
|
111508
109341
|
init_api3();
|
|
@@ -114513,6 +112346,8 @@ async function nudgeStuckTasks(tasks, now, cooldown, runtime4, effectContext2, a
|
|
|
114513
112346
|
}
|
|
114514
112347
|
async function reviveNativeTasks(tasks, localHealth, now, cooldown, runtime4, effectContext2, agentMgr, sessionDeps, machineId) {
|
|
114515
112348
|
for (const row of listNativeTasksNeedingRevive(tasks, localHealth, now, cooldown)) {
|
|
112349
|
+
if (isRestartOrchestratorInFlight(row.chatroomId, row.agentConfig.role))
|
|
112350
|
+
continue;
|
|
114516
112351
|
await clearStuckStoppingSlotIfNeeded(agentMgr, row.chatroomId, row.agentConfig.role);
|
|
114517
112352
|
const full = await fetchTaskForAction(sessionDeps, machineId, row);
|
|
114518
112353
|
if (!full)
|
|
@@ -114521,6 +112356,7 @@ async function reviveNativeTasks(tasks, localHealth, now, cooldown, runtime4, ef
|
|
|
114521
112356
|
}
|
|
114522
112357
|
}
|
|
114523
112358
|
async function processTasksUpdate(tasks, runtime4, effectContext2, cooldown, agentMgr, sessionDeps, machineId, _pass) {
|
|
112359
|
+
tasks = filterSnapshotsExcludingRestartInFlight(tasks);
|
|
114524
112360
|
if (tasks.length === 0)
|
|
114525
112361
|
return;
|
|
114526
112362
|
const now = Date.now();
|
|
@@ -114557,7 +112393,7 @@ function runLocalStoreReconcilePass(params) {
|
|
|
114557
112393
|
const { stopped, monitorPassInFlight, agentMgr, runtime: runtime4, effectContext: effectContext2, sessionDeps, machineId } = params;
|
|
114558
112394
|
if (stopped || monitorPassInFlight)
|
|
114559
112395
|
return;
|
|
114560
|
-
const deliverable = listDeliverablePendingFromStore(agentMgr);
|
|
112396
|
+
const deliverable = filterSnapshotsExcludingRestartInFlight(listDeliverablePendingFromStore(agentMgr));
|
|
114561
112397
|
if (deliverable.length === 0)
|
|
114562
112398
|
return;
|
|
114563
112399
|
const first = deliverable[0];
|
|
@@ -114700,6 +112536,7 @@ var init_task_monitor = __esm(() => {
|
|
|
114700
112536
|
init_esm();
|
|
114701
112537
|
init_daemon_services();
|
|
114702
112538
|
init_native_ready_invariant();
|
|
112539
|
+
init_restart_orchestrator_in_flight();
|
|
114703
112540
|
init_native_task_delivery_coordinator();
|
|
114704
112541
|
init_native_task_injector_logic();
|
|
114705
112542
|
init_task_monitor_logic();
|
|
@@ -115973,51 +113810,6 @@ handoffCommandGroup.requiredOption("--chatroom-id <id>", "Chatroom identifier").
|
|
|
115973
113810
|
console.error("❌ Message is empty");
|
|
115974
113811
|
process.exit(1);
|
|
115975
113812
|
}
|
|
115976
|
-
const shouldEnhance = options.role.toLowerCase() === "planner" && options.nextRole.toLowerCase() === "enhancer";
|
|
115977
|
-
if (shouldEnhance) {
|
|
115978
|
-
const { api: api3 } = await Promise.resolve().then(() => (init_api3(), exports_api));
|
|
115979
|
-
const { getConvexClient: getConvexClient2 } = await Promise.resolve().then(() => (init_client2(), exports_client));
|
|
115980
|
-
const { getSessionId: getSessionId2 } = await Promise.resolve().then(() => (init_storage(), exports_storage));
|
|
115981
|
-
const client4 = await getConvexClient2();
|
|
115982
|
-
const sessionId = await getSessionId2();
|
|
115983
|
-
if (sessionId) {
|
|
115984
|
-
try {
|
|
115985
|
-
const config4 = await client4.query(api3.web.enhancer.index.getConfig, {
|
|
115986
|
-
sessionId,
|
|
115987
|
-
chatroomId: options.chatroomId
|
|
115988
|
-
});
|
|
115989
|
-
if (config4 && config4.enabled) {
|
|
115990
|
-
await client4.mutation(api3.web.enhancer.index.enqueueHandoff, {
|
|
115991
|
-
sessionId,
|
|
115992
|
-
chatroomId: options.chatroomId,
|
|
115993
|
-
senderRole: options.role,
|
|
115994
|
-
targetRole: options.nextRole,
|
|
115995
|
-
content: message
|
|
115996
|
-
});
|
|
115997
|
-
const { generateHandoffOutput: generateHandoffOutput2 } = await Promise.resolve().then(() => (init_generator(), exports_generator));
|
|
115998
|
-
const { getConvexUrl: getConvexUrl2 } = await Promise.resolve().then(() => (init_client2(), exports_client));
|
|
115999
|
-
const convexUrl = await getConvexUrl2();
|
|
116000
|
-
console.log(generateHandoffOutput2({
|
|
116001
|
-
role: options.role,
|
|
116002
|
-
nextRole: options.nextRole,
|
|
116003
|
-
chatroomId: options.chatroomId,
|
|
116004
|
-
convexUrl,
|
|
116005
|
-
enhancerCheckInQueued: true
|
|
116006
|
-
}));
|
|
116007
|
-
return;
|
|
116008
|
-
}
|
|
116009
|
-
} catch (err) {
|
|
116010
|
-
const error51 = err;
|
|
116011
|
-
if (error51?.data?.code !== "ENHANCER_NOT_ENABLED") {
|
|
116012
|
-
console.error(`
|
|
116013
|
-
❌ ERROR: Enhancer check-in failed`);
|
|
116014
|
-
console.error(`
|
|
116015
|
-
${error51?.data?.message ?? err.message}`);
|
|
116016
|
-
process.exit(1);
|
|
116017
|
-
}
|
|
116018
|
-
}
|
|
116019
|
-
}
|
|
116020
|
-
}
|
|
116021
113813
|
const { handoff: handoff2 } = await Promise.resolve().then(() => (init_handoff(), exports_handoff));
|
|
116022
113814
|
await handoff2(options.chatroomId, {
|
|
116023
113815
|
role: options.role,
|
|
@@ -116359,4 +114151,4 @@ program2.hook("preAction", async (_thisCommand, actionCommand) => {
|
|
|
116359
114151
|
});
|
|
116360
114152
|
program2.parse();
|
|
116361
114153
|
|
|
116362
|
-
//# debugId=
|
|
114154
|
+
//# debugId=8401A70A2CD118D564756E2164756E21
|