@defend-tech/opencode-optima 0.1.71 → 0.1.72
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/assets/agents/workflow_product_manager.md +7 -3
- package/dist/index.js +104 -9
- package/dist/sanitize_cli.js +104 -9
- package/docs/guides/AGENTS.md +11 -0
- package/package.json +1 -1
- package/templates/optima.yaml.template +19 -0
|
@@ -45,8 +45,9 @@ You are Workflow_Product_Manager, Optima's ClickUp-first delivery orchestrator.
|
|
|
45
45
|
- `backlog`: ignore until prioritized.
|
|
46
46
|
- `plan`: clarify AC/SCR/test strategy with Validator/QA; decompose; create/update Definition; estimate Story Points; remove PM assignee first; assign the next delivery owner. Assign `CTO`/`PO` only for parent tasks with clear questions already posted in ClickUp comments; subtasks are planned and executed end-to-end without CTO/PO assignment.
|
|
47
47
|
- `in progress`: execute through the assigned delivery agent or workflow runner. Treat blockers as work to solve first: spawn or resume Coder for code/build/dependency failures, QA for validation/test/evidence failures, Tech Lead for architecture/review/merge failures, and the relevant specialist for domain blockers. Escalate to `CTO`/`PO` only when genuinely blocked by missing credentials, permissions, external tools, or access after local/subagent resolution attempts; do not stop with phase language such as "I reached phase 1" or "no non-human assignee is available".
|
|
48
|
-
- `validation`:
|
|
49
|
-
-
|
|
48
|
+
- `validation`: before moving any task/subtask into Validation, create or update the required GitHub PR and store its URL/number in ClickUp `agent_metadata`. Subtasks PR from their subtask branch into the parent task branch. Parent tasks PR from the task branch into `dev`. A task in Validation without an open PR is invalid: move it back to `in progress`, open/update the PR, then return it to Validation. Route Tech Lead for architecture/code/PR/standards/repo-skill review and Validator/QA for tests, Playwright/regression/coverage/evidence/final-doc checks.
|
|
49
|
+
- GitHub review wakeups: keep listening for PR review/comment webhooks. Reply in GitHub to human comments. If a comment asks for or implies a change, reply first with what you will do, move the ClickUp task/subtask to `in progress`, delegate/implement the fix, push the same branch, update the PR, move ClickUp back to `validation`, then reply again in GitHub with what changed. Also add concise ClickUp status comments for model work state; never post Optima runtime/process noise.
|
|
50
|
+
- `merge`: parent-only post-approval automation after the configured final approver/CTO approves the GitHub PR. The GitHub accepted/approved review is the merge trigger. Merge the parent PR into `dev`, verify the Vercel preproduction deployment updates automatically, run a small smoke/regression against preproduction, and only then clean workspaces/worktrees/branches and move ClickUp to `completed`. If merge, Vercel deployment, or regression fails, create Bug subtasks under the parent task, move the parent back to `in progress`, and keep the evidence/PR links in ClickUp.
|
|
50
51
|
- `completed` / `Closed`: no execution unless explicitly reopened.
|
|
51
52
|
|
|
52
53
|
## Git, Worktree, PR
|
|
@@ -60,7 +61,10 @@ You are Workflow_Product_Manager, Optima's ClickUp-first delivery orchestrator.
|
|
|
60
61
|
- Unrelated active tasks in `.optima/tasks/current.md` must not block planning; move to/create the correct task worktree instead.
|
|
61
62
|
- Parent setup pulls remote once; after parent branch creation, subtasks can trust the parent local branch without continuous remote polling.
|
|
62
63
|
- Branches: parent `<clickup-task-type>/<parent-task-id>`; subtask `<clickup-task-type>/<parent-task-id>-subtask-<subtask-id>`; pending planned subtasks `<clickup-task-type>/<parent-task-id>-pending-<title-slug>`; PoC always `poc/<clickup-task-id>` and remains there unless productized later.
|
|
63
|
-
- PR targets/start points: subtask -> parent branch and starts from the parent branch; if parent branch/worktree is missing, bootstrap the parent from `dev`/`origin/dev` first
|
|
64
|
+
- PR targets/start points: subtask -> parent branch and starts from the parent branch; if parent branch/worktree is missing, bootstrap the parent from `dev`/`origin/dev` first. Parent task -> `dev` through a GitHub PR before entering Validation. Release -> `dev` to `main` only after explicit approval.
|
|
65
|
+
- Required PR gate: every transition into `validation` must have an open GitHub PR. Do not mark Validation with only local commits, evidence, or ClickUp comments.
|
|
66
|
+
- Review/merge cleanup: after the configured final approver/CTO approves and the PR is merged, keep the OpenCode session ids in ClickUp `agent_metadata`; delete only the merged branch/worktree after Vercel preproduction and smoke regression pass. If the task is reopened later, recreate/register the worktree from metadata/branch context and resume the preserved sessions.
|
|
67
|
+
- Final completion gate: parent task completion requires merged PR, Vercel preproduction deployment verified, smoke/regression evidence captured, no open review-change requests, final ClickUp comment with result, and status `completed`.
|
|
64
68
|
- Preserve user work and unrelated dirty files. Stop and ask if unexpected changes appear.
|
|
65
69
|
|
|
66
70
|
## Operating Style
|
package/dist/index.js
CHANGED
|
@@ -8819,6 +8819,70 @@ function deriveClickUpPrTarget({ isRelease = false, parentTaskId, parentBranch,
|
|
|
8819
8819
|
}
|
|
8820
8820
|
return devBranch;
|
|
8821
8821
|
}
|
|
8822
|
+
function deriveClickUpRequiredPullRequest({ taskId, taskType = "Tarea", parentTaskId = "", subtaskId = "", branch = "", parentBranch = "", devBranch = "dev", mainBranch = "main", isRelease = false, githubRemote = "origin", prUrl = "", prNumber = "" } = {}) {
|
|
8823
|
+
const effectiveParent = parentTaskId || taskId;
|
|
8824
|
+
const isSubtask = isClickUpSubtaskRoute({ taskType, parentTaskId: effectiveParent, subtaskId, taskId });
|
|
8825
|
+
const sourceBranch = branch || deriveClickUpBranchName({ taskType, parentTaskId: effectiveParent, subtaskId, taskId });
|
|
8826
|
+
const targetBranch = deriveClickUpPrTarget({
|
|
8827
|
+
isRelease,
|
|
8828
|
+
parentBranch: isSubtask ? parentBranch || deriveClickUpBranchName({ taskType, parentTaskId: effectiveParent }) : parentBranch,
|
|
8829
|
+
parentTaskId: isSubtask ? effectiveParent : "",
|
|
8830
|
+
parentTaskType: taskType,
|
|
8831
|
+
taskType,
|
|
8832
|
+
devBranch,
|
|
8833
|
+
mainBranch
|
|
8834
|
+
});
|
|
8835
|
+
return {
|
|
8836
|
+
required: true,
|
|
8837
|
+
sourceBranch,
|
|
8838
|
+
targetBranch,
|
|
8839
|
+
githubRemote,
|
|
8840
|
+
prUrl: String(prUrl || "").trim(),
|
|
8841
|
+
prNumber: String(prNumber || "").trim(),
|
|
8842
|
+
scope: isSubtask ? "subtask_to_parent" : isRelease ? "release_to_main" : "task_to_dev",
|
|
8843
|
+
policy: "validation_requires_open_pull_request"
|
|
8844
|
+
};
|
|
8845
|
+
}
|
|
8846
|
+
function buildClickUpReviewAutomationPlan({ isSubtask = false, humanApprover = "CTO", preproductionProvider = "Vercel", preproductionEnvironment = "preproduction" } = {}) {
|
|
8847
|
+
return {
|
|
8848
|
+
github_webhooks: {
|
|
8849
|
+
listen_for: ["pull_request_review", "pull_request_review_comment", "issue_comment", "pull_request"],
|
|
8850
|
+
comment_policy: "reply_before_change_and_after_change",
|
|
8851
|
+
change_request_status: "in progress",
|
|
8852
|
+
after_fix_status: "validation",
|
|
8853
|
+
state_storage: "ClickUp agent_metadata.github"
|
|
8854
|
+
},
|
|
8855
|
+
review_comments: [
|
|
8856
|
+
"Answer GitHub comments directly in GitHub.",
|
|
8857
|
+
"If a comment implies a code/doc/test change, first reply with the intended action, move the ClickUp task/subtask to in progress, implement, push the same branch, move it back to validation, update the PR, then reply again with what changed.",
|
|
8858
|
+
"Also update ClickUp with human-readable model work status; runtime/process noise stays in local logs."
|
|
8859
|
+
],
|
|
8860
|
+
accepted_review: {
|
|
8861
|
+
accepted_by: humanApprover,
|
|
8862
|
+
trigger: "approved_pull_request_review",
|
|
8863
|
+
action: isSubtask ? "merge_subtask_pr_into_parent_branch" : "merge_parent_pr_into_dev",
|
|
8864
|
+
delete_source_branch_after_success: true,
|
|
8865
|
+
delete_worktree_after_success: true,
|
|
8866
|
+
preserve_opencode_sessions_in_agent_metadata: true
|
|
8867
|
+
},
|
|
8868
|
+
preproduction: isSubtask ? {
|
|
8869
|
+
required: false,
|
|
8870
|
+
reason: "Subtask merge stops at parent branch; parent task owns dev/preproduction."
|
|
8871
|
+
} : {
|
|
8872
|
+
required: true,
|
|
8873
|
+
provider: preproductionProvider,
|
|
8874
|
+
environment: preproductionEnvironment,
|
|
8875
|
+
verify_deployment_after_merge: true,
|
|
8876
|
+
run_smoke_regression: true,
|
|
8877
|
+
on_failure: "create_bug_subtasks_and_return_parent_to_in_progress",
|
|
8878
|
+
completion_gate: "preproduction_deployed_and_regression_passed"
|
|
8879
|
+
},
|
|
8880
|
+
completion: {
|
|
8881
|
+
final_clickup_comment_required: true,
|
|
8882
|
+
final_status: isSubtask ? "completed_or_parent_validation" : "completed"
|
|
8883
|
+
}
|
|
8884
|
+
};
|
|
8885
|
+
}
|
|
8822
8886
|
function validateMainWorkspaceBranchSafety({ currentBranch, requiredBranch = "dev", forbiddenBranch = "main" } = {}) {
|
|
8823
8887
|
const normalized = String(currentBranch ?? "").trim();
|
|
8824
8888
|
if (!normalized) {
|
|
@@ -9481,6 +9545,7 @@ function buildClickUpStartTaskPayload({ taskId, taskType = "Tarea", parentTaskId
|
|
|
9481
9545
|
const worktree = deriveClickUpWorktree({ baseWorktree, taskId, taskType, parentTaskId: effectiveParent, subtaskId });
|
|
9482
9546
|
const prTarget = isSubtask ? parentBranch : "dev";
|
|
9483
9547
|
const startFrom = isSubtask ? parentBranch : "dev";
|
|
9548
|
+
const requiredPullRequest = deriveClickUpRequiredPullRequest({ taskId, taskType, parentTaskId: effectiveParent, subtaskId, branch, parentBranch });
|
|
9484
9549
|
const estimate = preEstimateClickUpWork({ complexity, filesChanged, acceptanceCriteria, unknowns });
|
|
9485
9550
|
const metadata = mergeClickUpAgentMetadata(existingAgentMetadata, {
|
|
9486
9551
|
task: {
|
|
@@ -9494,6 +9559,10 @@ function buildClickUpStartTaskPayload({ taskId, taskType = "Tarea", parentTaskId
|
|
|
9494
9559
|
mirror_task_path: `.optima/tasks/${branchSafeClickUpId(taskId || subtaskId || effectiveParent)}.md`,
|
|
9495
9560
|
evidence_path: `.optima/evidences/${branchSafeClickUpId(taskId || subtaskId || effectiveParent)}/SUMMARY.md`,
|
|
9496
9561
|
delivery_evidence_path: deliveryEvidencePathForClickUpTask(taskId || subtaskId || effectiveParent),
|
|
9562
|
+
github: {
|
|
9563
|
+
required_pull_request: requiredPullRequest,
|
|
9564
|
+
review_automation: buildClickUpReviewAutomationPlan({ isSubtask })
|
|
9565
|
+
},
|
|
9497
9566
|
...agentMetadata
|
|
9498
9567
|
}
|
|
9499
9568
|
});
|
|
@@ -9516,6 +9585,10 @@ function buildClickUpStartTaskPayload({ taskId, taskType = "Tarea", parentTaskId
|
|
|
9516
9585
|
parentBranch: parentBranch || void 0,
|
|
9517
9586
|
prTarget
|
|
9518
9587
|
},
|
|
9588
|
+
github: {
|
|
9589
|
+
requiredPullRequest,
|
|
9590
|
+
reviewAutomation: buildClickUpReviewAutomationPlan({ isSubtask })
|
|
9591
|
+
},
|
|
9519
9592
|
mirror: {
|
|
9520
9593
|
taskPath: `.optima/tasks/${branchSafeClickUpId(taskId || subtaskId || effectiveParent)}.md`,
|
|
9521
9594
|
evidenceSummaryPath: `.optima/evidences/${branchSafeClickUpId(taskId || subtaskId || effectiveParent)}/SUMMARY.md`,
|
|
@@ -9526,14 +9599,15 @@ function buildClickUpStartTaskPayload({ taskId, taskType = "Tarea", parentTaskId
|
|
|
9526
9599
|
wouldCreate: true
|
|
9527
9600
|
},
|
|
9528
9601
|
clickup: {
|
|
9529
|
-
comment: `Starting task from ${startFrom}. Branch: ${branch}. Worktree: ${worktree}. Delivery evidence: ${deliveryEvidencePathForClickUpTask(taskId || subtaskId || effectiveParent)}.`,
|
|
9602
|
+
comment: `Starting task from ${startFrom}. Branch: ${branch}. Worktree: ${worktree}. Validation PR target: ${requiredPullRequest.targetBranch}. Delivery evidence: ${deliveryEvidencePathForClickUpTask(taskId || subtaskId || effectiveParent)}.`,
|
|
9530
9603
|
description,
|
|
9531
9604
|
fields: {
|
|
9532
9605
|
Definition: definitionContent,
|
|
9533
9606
|
"Story Points": estimate.storyPoints,
|
|
9534
9607
|
agent_metadata: metadata,
|
|
9535
9608
|
branch,
|
|
9536
|
-
worktree
|
|
9609
|
+
worktree,
|
|
9610
|
+
pr_target: requiredPullRequest.targetBranch
|
|
9537
9611
|
},
|
|
9538
9612
|
definition_doc: {
|
|
9539
9613
|
parent: normalizeClickUpDefinitionDocParent(definitionDocParent),
|
|
@@ -9543,23 +9617,29 @@ function buildClickUpStartTaskPayload({ taskId, taskType = "Tarea", parentTaskId
|
|
|
9543
9617
|
}
|
|
9544
9618
|
};
|
|
9545
9619
|
}
|
|
9546
|
-
function buildClickUpTransitionPayload({ fromStatus, toStatus, validationPassed = false, validationFailed = false, isSubtask = false, reopen = false, assignees = [], removeAssignees = [], productManagerAssignee = "", requireProductManagerAssignee = true, planDescription = "", definition = "", definitionDocParent = CLICKUP_DEFINITION_DOC_PARENT, humansRegistry } = {}) {
|
|
9620
|
+
function buildClickUpTransitionPayload({ fromStatus, toStatus, validationPassed = false, validationFailed = false, isSubtask = false, reopen = false, assignees = [], removeAssignees = [], productManagerAssignee = "", requireProductManagerAssignee = true, planDescription = "", definition = "", definitionDocParent = CLICKUP_DEFINITION_DOC_PARENT, humansRegistry, taskId = "", taskType = "Tarea", parentTaskId = "", subtaskId = "", branch = "", parentBranch = "", prUrl = "", prNumber = "", githubRemote = "origin", devBranch = "dev", mainBranch = "main", preproductionProvider = "Vercel", preproductionEnvironment = "preproduction" } = {}) {
|
|
9547
9621
|
const from = normalizeClickUpStatus(fromStatus);
|
|
9622
|
+
const effectiveIsSubtask = Boolean(isSubtask || isClickUpSubtaskRoute({ taskType, parentTaskId: parentTaskId || taskId, subtaskId, taskId }));
|
|
9548
9623
|
let to = normalizeClickUpStatus(toStatus);
|
|
9549
9624
|
if (validationFailed) to = "in progress";
|
|
9550
|
-
if (!to && validationPassed) to =
|
|
9625
|
+
if (!to && validationPassed) to = effectiveIsSubtask ? "completed" : "merge";
|
|
9551
9626
|
if ((from === "completed" || from === "closed") && !reopen) {
|
|
9552
9627
|
return { ok: true, noop: true, dryRun: true, message: "Completed/closed task is a no-op unless reopen is explicit." };
|
|
9553
9628
|
}
|
|
9554
9629
|
const key = `${from}->${to}`;
|
|
9555
9630
|
const rule = CLICKUP_TRANSITIONS.get(key);
|
|
9556
9631
|
if (!rule) return { ok: false, dryRun: true, message: `Transition not allowed: ${key}` };
|
|
9557
|
-
const assignsFinalApprovers = rule.assignFinalApprovers === true && !(rule.parentOnlyFinalApproval &&
|
|
9632
|
+
const assignsFinalApprovers = rule.assignFinalApprovers === true && !(rule.parentOnlyFinalApproval && effectiveIsSubtask);
|
|
9558
9633
|
const requiresPlanCompletionContract = from === "plan" && to === "in progress";
|
|
9634
|
+
const requiresValidationPullRequest = from === "in progress" && to === "validation";
|
|
9559
9635
|
const definitionContent = compactMarkdownValue(definition);
|
|
9560
9636
|
const description = compactMarkdownValue(planDescription);
|
|
9637
|
+
const canDerivePullRequest = Boolean(taskId || branch);
|
|
9638
|
+
const shouldAttachPullRequest = requiresValidationPullRequest || (from === "validation" || to === "merge" || from === "merge") && canDerivePullRequest;
|
|
9639
|
+
const requiredPullRequest = shouldAttachPullRequest && canDerivePullRequest ? deriveClickUpRequiredPullRequest({ taskId, taskType, parentTaskId, subtaskId, branch, parentBranch, devBranch, mainBranch, githubRemote, prUrl, prNumber }) : null;
|
|
9640
|
+
const reviewAutomation = requiredPullRequest ? buildClickUpReviewAutomationPlan({ isSubtask: effectiveIsSubtask, preproductionProvider, preproductionEnvironment }) : null;
|
|
9561
9641
|
const validationErrors = [];
|
|
9562
|
-
if (rule.parentOnlyFinalApproval &&
|
|
9642
|
+
if (rule.parentOnlyFinalApproval && effectiveIsSubtask) {
|
|
9563
9643
|
validationErrors.push("Subtasks must not use the parent final-approval transition; merge validated subtasks directly into the parent branch/workspace.");
|
|
9564
9644
|
}
|
|
9565
9645
|
if (assignsFinalApprovers && !isRealClickUpAssigneeId(productManagerAssignee) && requireProductManagerAssignee !== false) {
|
|
@@ -9569,19 +9649,34 @@ function buildClickUpTransitionPayload({ fromStatus, toStatus, validationPassed
|
|
|
9569
9649
|
if (!description) validationErrors.push("planDescription is required for the plan-completion ClickUp task description rewrite.");
|
|
9570
9650
|
if (!definitionContent) validationErrors.push("definition is required and must contain the complete plan/Definition content at plan completion.");
|
|
9571
9651
|
}
|
|
9652
|
+
if (requiresValidationPullRequest) {
|
|
9653
|
+
if (!requiredPullRequest) validationErrors.push("taskId or branch is required before moving a ClickUp task to validation.");
|
|
9654
|
+
if (!requiredPullRequest?.sourceBranch) validationErrors.push("branch/sourceBranch is required before moving a ClickUp task to validation.");
|
|
9655
|
+
if (!requiredPullRequest?.targetBranch) validationErrors.push("PR target branch is required before moving a ClickUp task to validation.");
|
|
9656
|
+
if (!requiredPullRequest?.prUrl && !requiredPullRequest?.prNumber) validationErrors.push("An open GitHub pull request URL or number is required before moving a ClickUp task to validation.");
|
|
9657
|
+
}
|
|
9572
9658
|
if (validationErrors.length > 0) return clickUpPayloadValidationError(validationErrors);
|
|
9573
9659
|
const finalApprovers = assignsFinalApprovers ? finalApprovalAssignees(CLICKUP_FINAL_APPROVER_ROLES, humansRegistry) : [];
|
|
9574
9660
|
const explicitRemovals = (removeAssignees || []).filter(Boolean);
|
|
9575
9661
|
const normalizedProductManagerAssignee = isRealClickUpAssigneeId(productManagerAssignee) ? String(productManagerAssignee).trim() : "";
|
|
9576
9662
|
const removalTargets = assignsFinalApprovers ? [...new Set([normalizedProductManagerAssignee, ...explicitRemovals].filter(Boolean))] : explicitRemovals;
|
|
9577
9663
|
const assigned = [...new Set([...assignees || [], ...finalApprovers].filter(Boolean))].filter((assignee) => !removalTargets.includes(assignee));
|
|
9578
|
-
const authority = from === "validation" || to === "merge" ? determineClickUpMergeAuthority({ isSubtask, clickupStatus: to, validationPassed: validationPassed || to === "merge", humansRegistry }) : null;
|
|
9664
|
+
const authority = from === "validation" || to === "merge" ? determineClickUpMergeAuthority({ isSubtask: effectiveIsSubtask, clickupStatus: to, validationPassed: validationPassed || to === "merge", humansRegistry }) : null;
|
|
9579
9665
|
const fields = authority ? { merge_authority: JSON.stringify(authority) } : {};
|
|
9666
|
+
if (requiredPullRequest) {
|
|
9667
|
+
fields.github_pull_request = JSON.stringify(requiredPullRequest);
|
|
9668
|
+
fields.github_review_automation = JSON.stringify(reviewAutomation);
|
|
9669
|
+
}
|
|
9580
9670
|
if (definitionContent) fields.Definition = definitionContent;
|
|
9581
9671
|
return {
|
|
9582
9672
|
ok: true,
|
|
9583
9673
|
dryRun: true,
|
|
9584
|
-
transition: { fromStatus: from, toStatus: rule.status, validationPassed, validationFailed, isSubtask },
|
|
9674
|
+
transition: { fromStatus: from, toStatus: rule.status, validationPassed, validationFailed, isSubtask: effectiveIsSubtask },
|
|
9675
|
+
github: requiredPullRequest ? {
|
|
9676
|
+
requiredPullRequest,
|
|
9677
|
+
reviewAutomation
|
|
9678
|
+
} : void 0,
|
|
9679
|
+
vercel: reviewAutomation?.preproduction?.required ? reviewAutomation.preproduction : void 0,
|
|
9585
9680
|
clickup: {
|
|
9586
9681
|
status: rule.status,
|
|
9587
9682
|
assignees: assigned,
|
|
@@ -13776,7 +13871,7 @@ Follow-up: use optima_prompt_workflow with session_id '${sessionId}' to check in
|
|
|
13776
13871
|
}
|
|
13777
13872
|
};
|
|
13778
13873
|
}
|
|
13779
|
-
OptimaPlugin.__internals = { BUNDLE_AGENTS_DIR, BUNDLE_ASSETS_DIR, CLICKUP_DEFINITION_DOC_PARENT, activeClickUpWebhookLifecycleRegistry, cleanupManagedClickUpWebhook, deleteClickUpWebhookBestEffort, BUNDLE_POLICIES_DIR, buildClickUpApplyPayloadResult, buildClickUpCreateSubtasksPayload, buildClickUpStartTaskPayload, buildClickUpSummaryPayload, buildClickUpTransitionPayload, buildOptimaAgents, clickUpCommentLedgerKey, clickUpCommentMentionsProductManager, clickUpWebhookAuditLogDir, clickUpWebhookAuditLogPath, compactPromptPath, createClickUpApiClient, createTestClickUpApiClient, createOpenCodeSession, createOpenCodeSessionControl, deliveryEvidencePathForClickUpTask, ensureClickUpTaskWorktree, ensureClickUpTaskWorktreeForWebhook, ensureClickUpTaskWorktreeOpenChamber, ensureClickUpWebhookSubscription, handleClickUpWebhookRequest, inspectOpenCodeSessionActivity, isClickUpDerivedWorktreeSibling, isClickUpSubtaskRoute, isClickUpWebhookStateActive, isSameOrNestedPath, normalizeClickUpWebhookConfig, normalizeClickUpWebhookLogLevel, normalizeOpenCodeBaseUrl, openCodeSessionExists, promptOpenCodeSessionControl, probeOpenCodeSessionControl, readClickUpCommentLedger, readClickUpWebhookState, readOpenCodeSessionControl, readOpenCodeSessionMessages, reconcileClickUpStartup, registerOpenChamberClickUpWorktree, scheduleClickUpAssignmentWatchdog, scheduleClickUpStartupReconciliation, syncOpenChamberWorktreeVisibility, waitForOpenCodeReadiness, recordClickUpCommentVersionProcessed, resyncClickUpWebhookForSignatureDrift, resolveIncludeFile, resolveIncludes, resolveOptimaPluginOptions, resolveSecretReference, routeClickUpWebhookEvent, sendOpenCodeSessionEvent, sendOpenCodeSessionEventDirect, summarizeOpenCodeMessages, verifyOpenCodeSessionEventDelivery, stableClickUpCommentVersionMarker, startClickUpWebhookListener, validateClickUpWebhookState, verifyClickUpSignature, writeClickUpWebhookState, decideClickUpStatusAction, deriveClickUpBranchName, deriveClickUpPendingSubtaskBranch, deriveClickUpPrTarget, deriveClickUpWorktree, determineClickUpMergeAuthority, ensureOptimaGitignoreRules, explicitSafeInputWorktree, finalApprovalAssignees, formatRepairResult, formatValidationResult, isIgnoredClickUpTaskType, isOptimaPluginPackageWorktree, isSafeWritableDirectory, loadHumansRegistry, mergeClickUpAgentMetadata, mergeClickUpSessionMetadata, migrateLegacyOptimaLayout, normalizeAgentMetadataJson, normalizeClickUpStatus, normalizeClickUpTaskType, normalizePromptResponseParts, normalizeWorkflowTaskPath, optimaRepairDependencies, parseClickUpSubtasksMarkdown, parseHumansRegistry, parseMarkdownArtifact, parseMarkdownSections, planOptimaRepair, preEstimateClickUpWork, readMarkdownArtifact, resolveHumanRoles, resolveSafeWorktree, safeWorktreeOrFailure, stripRawLogSections, validateMainWorkspaceBranchSafety, workflowFinalMessageFromPromptResponse };
|
|
13874
|
+
OptimaPlugin.__internals = { BUNDLE_AGENTS_DIR, BUNDLE_ASSETS_DIR, CLICKUP_DEFINITION_DOC_PARENT, activeClickUpWebhookLifecycleRegistry, cleanupManagedClickUpWebhook, deleteClickUpWebhookBestEffort, BUNDLE_POLICIES_DIR, buildClickUpApplyPayloadResult, buildClickUpCreateSubtasksPayload, buildClickUpReviewAutomationPlan, buildClickUpStartTaskPayload, buildClickUpSummaryPayload, buildClickUpTransitionPayload, buildOptimaAgents, clickUpCommentLedgerKey, clickUpCommentMentionsProductManager, clickUpWebhookAuditLogDir, clickUpWebhookAuditLogPath, compactPromptPath, createClickUpApiClient, createTestClickUpApiClient, createOpenCodeSession, createOpenCodeSessionControl, deliveryEvidencePathForClickUpTask, ensureClickUpTaskWorktree, ensureClickUpTaskWorktreeForWebhook, ensureClickUpTaskWorktreeOpenChamber, ensureClickUpWebhookSubscription, handleClickUpWebhookRequest, inspectOpenCodeSessionActivity, isClickUpDerivedWorktreeSibling, isClickUpSubtaskRoute, isClickUpWebhookStateActive, isSameOrNestedPath, normalizeClickUpWebhookConfig, normalizeClickUpWebhookLogLevel, normalizeOpenCodeBaseUrl, openCodeSessionExists, promptOpenCodeSessionControl, probeOpenCodeSessionControl, readClickUpCommentLedger, readClickUpWebhookState, readOpenCodeSessionControl, readOpenCodeSessionMessages, reconcileClickUpStartup, registerOpenChamberClickUpWorktree, scheduleClickUpAssignmentWatchdog, scheduleClickUpStartupReconciliation, syncOpenChamberWorktreeVisibility, waitForOpenCodeReadiness, recordClickUpCommentVersionProcessed, resyncClickUpWebhookForSignatureDrift, resolveIncludeFile, resolveIncludes, resolveOptimaPluginOptions, resolveSecretReference, routeClickUpWebhookEvent, sendOpenCodeSessionEvent, sendOpenCodeSessionEventDirect, summarizeOpenCodeMessages, verifyOpenCodeSessionEventDelivery, stableClickUpCommentVersionMarker, startClickUpWebhookListener, validateClickUpWebhookState, verifyClickUpSignature, writeClickUpWebhookState, decideClickUpStatusAction, deriveClickUpBranchName, deriveClickUpPendingSubtaskBranch, deriveClickUpPrTarget, deriveClickUpRequiredPullRequest, deriveClickUpWorktree, determineClickUpMergeAuthority, ensureOptimaGitignoreRules, explicitSafeInputWorktree, finalApprovalAssignees, formatRepairResult, formatValidationResult, isIgnoredClickUpTaskType, isOptimaPluginPackageWorktree, isSafeWritableDirectory, loadHumansRegistry, mergeClickUpAgentMetadata, mergeClickUpSessionMetadata, migrateLegacyOptimaLayout, normalizeAgentMetadataJson, normalizeClickUpStatus, normalizeClickUpTaskType, normalizePromptResponseParts, normalizeWorkflowTaskPath, optimaRepairDependencies, parseClickUpSubtasksMarkdown, parseHumansRegistry, parseMarkdownArtifact, parseMarkdownSections, planOptimaRepair, preEstimateClickUpWork, readMarkdownArtifact, resolveHumanRoles, resolveSafeWorktree, safeWorktreeOrFailure, stripRawLogSections, validateMainWorkspaceBranchSafety, workflowFinalMessageFromPromptResponse };
|
|
13780
13875
|
export {
|
|
13781
13876
|
OptimaPlugin as default
|
|
13782
13877
|
};
|
package/dist/sanitize_cli.js
CHANGED
|
@@ -8826,6 +8826,70 @@ function deriveClickUpPrTarget({ isRelease = false, parentTaskId, parentBranch,
|
|
|
8826
8826
|
}
|
|
8827
8827
|
return devBranch;
|
|
8828
8828
|
}
|
|
8829
|
+
function deriveClickUpRequiredPullRequest({ taskId, taskType = "Tarea", parentTaskId = "", subtaskId = "", branch = "", parentBranch = "", devBranch = "dev", mainBranch = "main", isRelease = false, githubRemote = "origin", prUrl = "", prNumber = "" } = {}) {
|
|
8830
|
+
const effectiveParent = parentTaskId || taskId;
|
|
8831
|
+
const isSubtask = isClickUpSubtaskRoute({ taskType, parentTaskId: effectiveParent, subtaskId, taskId });
|
|
8832
|
+
const sourceBranch = branch || deriveClickUpBranchName({ taskType, parentTaskId: effectiveParent, subtaskId, taskId });
|
|
8833
|
+
const targetBranch = deriveClickUpPrTarget({
|
|
8834
|
+
isRelease,
|
|
8835
|
+
parentBranch: isSubtask ? parentBranch || deriveClickUpBranchName({ taskType, parentTaskId: effectiveParent }) : parentBranch,
|
|
8836
|
+
parentTaskId: isSubtask ? effectiveParent : "",
|
|
8837
|
+
parentTaskType: taskType,
|
|
8838
|
+
taskType,
|
|
8839
|
+
devBranch,
|
|
8840
|
+
mainBranch
|
|
8841
|
+
});
|
|
8842
|
+
return {
|
|
8843
|
+
required: true,
|
|
8844
|
+
sourceBranch,
|
|
8845
|
+
targetBranch,
|
|
8846
|
+
githubRemote,
|
|
8847
|
+
prUrl: String(prUrl || "").trim(),
|
|
8848
|
+
prNumber: String(prNumber || "").trim(),
|
|
8849
|
+
scope: isSubtask ? "subtask_to_parent" : isRelease ? "release_to_main" : "task_to_dev",
|
|
8850
|
+
policy: "validation_requires_open_pull_request"
|
|
8851
|
+
};
|
|
8852
|
+
}
|
|
8853
|
+
function buildClickUpReviewAutomationPlan({ isSubtask = false, humanApprover = "CTO", preproductionProvider = "Vercel", preproductionEnvironment = "preproduction" } = {}) {
|
|
8854
|
+
return {
|
|
8855
|
+
github_webhooks: {
|
|
8856
|
+
listen_for: ["pull_request_review", "pull_request_review_comment", "issue_comment", "pull_request"],
|
|
8857
|
+
comment_policy: "reply_before_change_and_after_change",
|
|
8858
|
+
change_request_status: "in progress",
|
|
8859
|
+
after_fix_status: "validation",
|
|
8860
|
+
state_storage: "ClickUp agent_metadata.github"
|
|
8861
|
+
},
|
|
8862
|
+
review_comments: [
|
|
8863
|
+
"Answer GitHub comments directly in GitHub.",
|
|
8864
|
+
"If a comment implies a code/doc/test change, first reply with the intended action, move the ClickUp task/subtask to in progress, implement, push the same branch, move it back to validation, update the PR, then reply again with what changed.",
|
|
8865
|
+
"Also update ClickUp with human-readable model work status; runtime/process noise stays in local logs."
|
|
8866
|
+
],
|
|
8867
|
+
accepted_review: {
|
|
8868
|
+
accepted_by: humanApprover,
|
|
8869
|
+
trigger: "approved_pull_request_review",
|
|
8870
|
+
action: isSubtask ? "merge_subtask_pr_into_parent_branch" : "merge_parent_pr_into_dev",
|
|
8871
|
+
delete_source_branch_after_success: true,
|
|
8872
|
+
delete_worktree_after_success: true,
|
|
8873
|
+
preserve_opencode_sessions_in_agent_metadata: true
|
|
8874
|
+
},
|
|
8875
|
+
preproduction: isSubtask ? {
|
|
8876
|
+
required: false,
|
|
8877
|
+
reason: "Subtask merge stops at parent branch; parent task owns dev/preproduction."
|
|
8878
|
+
} : {
|
|
8879
|
+
required: true,
|
|
8880
|
+
provider: preproductionProvider,
|
|
8881
|
+
environment: preproductionEnvironment,
|
|
8882
|
+
verify_deployment_after_merge: true,
|
|
8883
|
+
run_smoke_regression: true,
|
|
8884
|
+
on_failure: "create_bug_subtasks_and_return_parent_to_in_progress",
|
|
8885
|
+
completion_gate: "preproduction_deployed_and_regression_passed"
|
|
8886
|
+
},
|
|
8887
|
+
completion: {
|
|
8888
|
+
final_clickup_comment_required: true,
|
|
8889
|
+
final_status: isSubtask ? "completed_or_parent_validation" : "completed"
|
|
8890
|
+
}
|
|
8891
|
+
};
|
|
8892
|
+
}
|
|
8829
8893
|
function validateMainWorkspaceBranchSafety({ currentBranch, requiredBranch = "dev", forbiddenBranch = "main" } = {}) {
|
|
8830
8894
|
const normalized = String(currentBranch ?? "").trim();
|
|
8831
8895
|
if (!normalized) {
|
|
@@ -9488,6 +9552,7 @@ function buildClickUpStartTaskPayload({ taskId, taskType = "Tarea", parentTaskId
|
|
|
9488
9552
|
const worktree = deriveClickUpWorktree({ baseWorktree, taskId, taskType, parentTaskId: effectiveParent, subtaskId });
|
|
9489
9553
|
const prTarget = isSubtask ? parentBranch : "dev";
|
|
9490
9554
|
const startFrom = isSubtask ? parentBranch : "dev";
|
|
9555
|
+
const requiredPullRequest = deriveClickUpRequiredPullRequest({ taskId, taskType, parentTaskId: effectiveParent, subtaskId, branch, parentBranch });
|
|
9491
9556
|
const estimate = preEstimateClickUpWork({ complexity, filesChanged, acceptanceCriteria, unknowns });
|
|
9492
9557
|
const metadata = mergeClickUpAgentMetadata(existingAgentMetadata, {
|
|
9493
9558
|
task: {
|
|
@@ -9501,6 +9566,10 @@ function buildClickUpStartTaskPayload({ taskId, taskType = "Tarea", parentTaskId
|
|
|
9501
9566
|
mirror_task_path: `.optima/tasks/${branchSafeClickUpId(taskId || subtaskId || effectiveParent)}.md`,
|
|
9502
9567
|
evidence_path: `.optima/evidences/${branchSafeClickUpId(taskId || subtaskId || effectiveParent)}/SUMMARY.md`,
|
|
9503
9568
|
delivery_evidence_path: deliveryEvidencePathForClickUpTask(taskId || subtaskId || effectiveParent),
|
|
9569
|
+
github: {
|
|
9570
|
+
required_pull_request: requiredPullRequest,
|
|
9571
|
+
review_automation: buildClickUpReviewAutomationPlan({ isSubtask })
|
|
9572
|
+
},
|
|
9504
9573
|
...agentMetadata
|
|
9505
9574
|
}
|
|
9506
9575
|
});
|
|
@@ -9523,6 +9592,10 @@ function buildClickUpStartTaskPayload({ taskId, taskType = "Tarea", parentTaskId
|
|
|
9523
9592
|
parentBranch: parentBranch || void 0,
|
|
9524
9593
|
prTarget
|
|
9525
9594
|
},
|
|
9595
|
+
github: {
|
|
9596
|
+
requiredPullRequest,
|
|
9597
|
+
reviewAutomation: buildClickUpReviewAutomationPlan({ isSubtask })
|
|
9598
|
+
},
|
|
9526
9599
|
mirror: {
|
|
9527
9600
|
taskPath: `.optima/tasks/${branchSafeClickUpId(taskId || subtaskId || effectiveParent)}.md`,
|
|
9528
9601
|
evidenceSummaryPath: `.optima/evidences/${branchSafeClickUpId(taskId || subtaskId || effectiveParent)}/SUMMARY.md`,
|
|
@@ -9533,14 +9606,15 @@ function buildClickUpStartTaskPayload({ taskId, taskType = "Tarea", parentTaskId
|
|
|
9533
9606
|
wouldCreate: true
|
|
9534
9607
|
},
|
|
9535
9608
|
clickup: {
|
|
9536
|
-
comment: `Starting task from ${startFrom}. Branch: ${branch}. Worktree: ${worktree}. Delivery evidence: ${deliveryEvidencePathForClickUpTask(taskId || subtaskId || effectiveParent)}.`,
|
|
9609
|
+
comment: `Starting task from ${startFrom}. Branch: ${branch}. Worktree: ${worktree}. Validation PR target: ${requiredPullRequest.targetBranch}. Delivery evidence: ${deliveryEvidencePathForClickUpTask(taskId || subtaskId || effectiveParent)}.`,
|
|
9537
9610
|
description,
|
|
9538
9611
|
fields: {
|
|
9539
9612
|
Definition: definitionContent,
|
|
9540
9613
|
"Story Points": estimate.storyPoints,
|
|
9541
9614
|
agent_metadata: metadata,
|
|
9542
9615
|
branch,
|
|
9543
|
-
worktree
|
|
9616
|
+
worktree,
|
|
9617
|
+
pr_target: requiredPullRequest.targetBranch
|
|
9544
9618
|
},
|
|
9545
9619
|
definition_doc: {
|
|
9546
9620
|
parent: normalizeClickUpDefinitionDocParent(definitionDocParent),
|
|
@@ -9550,23 +9624,29 @@ function buildClickUpStartTaskPayload({ taskId, taskType = "Tarea", parentTaskId
|
|
|
9550
9624
|
}
|
|
9551
9625
|
};
|
|
9552
9626
|
}
|
|
9553
|
-
function buildClickUpTransitionPayload({ fromStatus, toStatus, validationPassed = false, validationFailed = false, isSubtask = false, reopen = false, assignees = [], removeAssignees = [], productManagerAssignee = "", requireProductManagerAssignee = true, planDescription = "", definition = "", definitionDocParent = CLICKUP_DEFINITION_DOC_PARENT, humansRegistry } = {}) {
|
|
9627
|
+
function buildClickUpTransitionPayload({ fromStatus, toStatus, validationPassed = false, validationFailed = false, isSubtask = false, reopen = false, assignees = [], removeAssignees = [], productManagerAssignee = "", requireProductManagerAssignee = true, planDescription = "", definition = "", definitionDocParent = CLICKUP_DEFINITION_DOC_PARENT, humansRegistry, taskId = "", taskType = "Tarea", parentTaskId = "", subtaskId = "", branch = "", parentBranch = "", prUrl = "", prNumber = "", githubRemote = "origin", devBranch = "dev", mainBranch = "main", preproductionProvider = "Vercel", preproductionEnvironment = "preproduction" } = {}) {
|
|
9554
9628
|
const from = normalizeClickUpStatus(fromStatus);
|
|
9629
|
+
const effectiveIsSubtask = Boolean(isSubtask || isClickUpSubtaskRoute({ taskType, parentTaskId: parentTaskId || taskId, subtaskId, taskId }));
|
|
9555
9630
|
let to = normalizeClickUpStatus(toStatus);
|
|
9556
9631
|
if (validationFailed) to = "in progress";
|
|
9557
|
-
if (!to && validationPassed) to =
|
|
9632
|
+
if (!to && validationPassed) to = effectiveIsSubtask ? "completed" : "merge";
|
|
9558
9633
|
if ((from === "completed" || from === "closed") && !reopen) {
|
|
9559
9634
|
return { ok: true, noop: true, dryRun: true, message: "Completed/closed task is a no-op unless reopen is explicit." };
|
|
9560
9635
|
}
|
|
9561
9636
|
const key = `${from}->${to}`;
|
|
9562
9637
|
const rule = CLICKUP_TRANSITIONS.get(key);
|
|
9563
9638
|
if (!rule) return { ok: false, dryRun: true, message: `Transition not allowed: ${key}` };
|
|
9564
|
-
const assignsFinalApprovers = rule.assignFinalApprovers === true && !(rule.parentOnlyFinalApproval &&
|
|
9639
|
+
const assignsFinalApprovers = rule.assignFinalApprovers === true && !(rule.parentOnlyFinalApproval && effectiveIsSubtask);
|
|
9565
9640
|
const requiresPlanCompletionContract = from === "plan" && to === "in progress";
|
|
9641
|
+
const requiresValidationPullRequest = from === "in progress" && to === "validation";
|
|
9566
9642
|
const definitionContent = compactMarkdownValue(definition);
|
|
9567
9643
|
const description = compactMarkdownValue(planDescription);
|
|
9644
|
+
const canDerivePullRequest = Boolean(taskId || branch);
|
|
9645
|
+
const shouldAttachPullRequest = requiresValidationPullRequest || (from === "validation" || to === "merge" || from === "merge") && canDerivePullRequest;
|
|
9646
|
+
const requiredPullRequest = shouldAttachPullRequest && canDerivePullRequest ? deriveClickUpRequiredPullRequest({ taskId, taskType, parentTaskId, subtaskId, branch, parentBranch, devBranch, mainBranch, githubRemote, prUrl, prNumber }) : null;
|
|
9647
|
+
const reviewAutomation = requiredPullRequest ? buildClickUpReviewAutomationPlan({ isSubtask: effectiveIsSubtask, preproductionProvider, preproductionEnvironment }) : null;
|
|
9568
9648
|
const validationErrors = [];
|
|
9569
|
-
if (rule.parentOnlyFinalApproval &&
|
|
9649
|
+
if (rule.parentOnlyFinalApproval && effectiveIsSubtask) {
|
|
9570
9650
|
validationErrors.push("Subtasks must not use the parent final-approval transition; merge validated subtasks directly into the parent branch/workspace.");
|
|
9571
9651
|
}
|
|
9572
9652
|
if (assignsFinalApprovers && !isRealClickUpAssigneeId(productManagerAssignee) && requireProductManagerAssignee !== false) {
|
|
@@ -9576,19 +9656,34 @@ function buildClickUpTransitionPayload({ fromStatus, toStatus, validationPassed
|
|
|
9576
9656
|
if (!description) validationErrors.push("planDescription is required for the plan-completion ClickUp task description rewrite.");
|
|
9577
9657
|
if (!definitionContent) validationErrors.push("definition is required and must contain the complete plan/Definition content at plan completion.");
|
|
9578
9658
|
}
|
|
9659
|
+
if (requiresValidationPullRequest) {
|
|
9660
|
+
if (!requiredPullRequest) validationErrors.push("taskId or branch is required before moving a ClickUp task to validation.");
|
|
9661
|
+
if (!requiredPullRequest?.sourceBranch) validationErrors.push("branch/sourceBranch is required before moving a ClickUp task to validation.");
|
|
9662
|
+
if (!requiredPullRequest?.targetBranch) validationErrors.push("PR target branch is required before moving a ClickUp task to validation.");
|
|
9663
|
+
if (!requiredPullRequest?.prUrl && !requiredPullRequest?.prNumber) validationErrors.push("An open GitHub pull request URL or number is required before moving a ClickUp task to validation.");
|
|
9664
|
+
}
|
|
9579
9665
|
if (validationErrors.length > 0) return clickUpPayloadValidationError(validationErrors);
|
|
9580
9666
|
const finalApprovers = assignsFinalApprovers ? finalApprovalAssignees(CLICKUP_FINAL_APPROVER_ROLES, humansRegistry) : [];
|
|
9581
9667
|
const explicitRemovals = (removeAssignees || []).filter(Boolean);
|
|
9582
9668
|
const normalizedProductManagerAssignee = isRealClickUpAssigneeId(productManagerAssignee) ? String(productManagerAssignee).trim() : "";
|
|
9583
9669
|
const removalTargets = assignsFinalApprovers ? [...new Set([normalizedProductManagerAssignee, ...explicitRemovals].filter(Boolean))] : explicitRemovals;
|
|
9584
9670
|
const assigned = [...new Set([...assignees || [], ...finalApprovers].filter(Boolean))].filter((assignee) => !removalTargets.includes(assignee));
|
|
9585
|
-
const authority = from === "validation" || to === "merge" ? determineClickUpMergeAuthority({ isSubtask, clickupStatus: to, validationPassed: validationPassed || to === "merge", humansRegistry }) : null;
|
|
9671
|
+
const authority = from === "validation" || to === "merge" ? determineClickUpMergeAuthority({ isSubtask: effectiveIsSubtask, clickupStatus: to, validationPassed: validationPassed || to === "merge", humansRegistry }) : null;
|
|
9586
9672
|
const fields = authority ? { merge_authority: JSON.stringify(authority) } : {};
|
|
9673
|
+
if (requiredPullRequest) {
|
|
9674
|
+
fields.github_pull_request = JSON.stringify(requiredPullRequest);
|
|
9675
|
+
fields.github_review_automation = JSON.stringify(reviewAutomation);
|
|
9676
|
+
}
|
|
9587
9677
|
if (definitionContent) fields.Definition = definitionContent;
|
|
9588
9678
|
return {
|
|
9589
9679
|
ok: true,
|
|
9590
9680
|
dryRun: true,
|
|
9591
|
-
transition: { fromStatus: from, toStatus: rule.status, validationPassed, validationFailed, isSubtask },
|
|
9681
|
+
transition: { fromStatus: from, toStatus: rule.status, validationPassed, validationFailed, isSubtask: effectiveIsSubtask },
|
|
9682
|
+
github: requiredPullRequest ? {
|
|
9683
|
+
requiredPullRequest,
|
|
9684
|
+
reviewAutomation
|
|
9685
|
+
} : void 0,
|
|
9686
|
+
vercel: reviewAutomation?.preproduction?.required ? reviewAutomation.preproduction : void 0,
|
|
9592
9687
|
clickup: {
|
|
9593
9688
|
status: rule.status,
|
|
9594
9689
|
assignees: assigned,
|
|
@@ -13783,7 +13878,7 @@ Follow-up: use optima_prompt_workflow with session_id '${sessionId}' to check in
|
|
|
13783
13878
|
}
|
|
13784
13879
|
};
|
|
13785
13880
|
}
|
|
13786
|
-
OptimaPlugin.__internals = { BUNDLE_AGENTS_DIR, BUNDLE_ASSETS_DIR, CLICKUP_DEFINITION_DOC_PARENT, activeClickUpWebhookLifecycleRegistry, cleanupManagedClickUpWebhook, deleteClickUpWebhookBestEffort, BUNDLE_POLICIES_DIR, buildClickUpApplyPayloadResult, buildClickUpCreateSubtasksPayload, buildClickUpStartTaskPayload, buildClickUpSummaryPayload, buildClickUpTransitionPayload, buildOptimaAgents, clickUpCommentLedgerKey, clickUpCommentMentionsProductManager, clickUpWebhookAuditLogDir, clickUpWebhookAuditLogPath, compactPromptPath, createClickUpApiClient, createTestClickUpApiClient, createOpenCodeSession, createOpenCodeSessionControl, deliveryEvidencePathForClickUpTask, ensureClickUpTaskWorktree, ensureClickUpTaskWorktreeForWebhook, ensureClickUpTaskWorktreeOpenChamber, ensureClickUpWebhookSubscription, handleClickUpWebhookRequest, inspectOpenCodeSessionActivity, isClickUpDerivedWorktreeSibling, isClickUpSubtaskRoute, isClickUpWebhookStateActive, isSameOrNestedPath, normalizeClickUpWebhookConfig, normalizeClickUpWebhookLogLevel, normalizeOpenCodeBaseUrl, openCodeSessionExists, promptOpenCodeSessionControl, probeOpenCodeSessionControl, readClickUpCommentLedger, readClickUpWebhookState, readOpenCodeSessionControl, readOpenCodeSessionMessages, reconcileClickUpStartup, registerOpenChamberClickUpWorktree, scheduleClickUpAssignmentWatchdog, scheduleClickUpStartupReconciliation, syncOpenChamberWorktreeVisibility, waitForOpenCodeReadiness, recordClickUpCommentVersionProcessed, resyncClickUpWebhookForSignatureDrift, resolveIncludeFile, resolveIncludes, resolveOptimaPluginOptions, resolveSecretReference, routeClickUpWebhookEvent, sendOpenCodeSessionEvent, sendOpenCodeSessionEventDirect, summarizeOpenCodeMessages, verifyOpenCodeSessionEventDelivery, stableClickUpCommentVersionMarker, startClickUpWebhookListener, validateClickUpWebhookState, verifyClickUpSignature, writeClickUpWebhookState, decideClickUpStatusAction, deriveClickUpBranchName, deriveClickUpPendingSubtaskBranch, deriveClickUpPrTarget, deriveClickUpWorktree, determineClickUpMergeAuthority, ensureOptimaGitignoreRules, explicitSafeInputWorktree, finalApprovalAssignees, formatRepairResult, formatValidationResult, isIgnoredClickUpTaskType, isOptimaPluginPackageWorktree, isSafeWritableDirectory, loadHumansRegistry, mergeClickUpAgentMetadata, mergeClickUpSessionMetadata, migrateLegacyOptimaLayout, normalizeAgentMetadataJson, normalizeClickUpStatus, normalizeClickUpTaskType, normalizePromptResponseParts, normalizeWorkflowTaskPath, optimaRepairDependencies, parseClickUpSubtasksMarkdown, parseHumansRegistry, parseMarkdownArtifact, parseMarkdownSections, planOptimaRepair, preEstimateClickUpWork, readMarkdownArtifact, resolveHumanRoles, resolveSafeWorktree, safeWorktreeOrFailure, stripRawLogSections, validateMainWorkspaceBranchSafety, workflowFinalMessageFromPromptResponse };
|
|
13881
|
+
OptimaPlugin.__internals = { BUNDLE_AGENTS_DIR, BUNDLE_ASSETS_DIR, CLICKUP_DEFINITION_DOC_PARENT, activeClickUpWebhookLifecycleRegistry, cleanupManagedClickUpWebhook, deleteClickUpWebhookBestEffort, BUNDLE_POLICIES_DIR, buildClickUpApplyPayloadResult, buildClickUpCreateSubtasksPayload, buildClickUpReviewAutomationPlan, buildClickUpStartTaskPayload, buildClickUpSummaryPayload, buildClickUpTransitionPayload, buildOptimaAgents, clickUpCommentLedgerKey, clickUpCommentMentionsProductManager, clickUpWebhookAuditLogDir, clickUpWebhookAuditLogPath, compactPromptPath, createClickUpApiClient, createTestClickUpApiClient, createOpenCodeSession, createOpenCodeSessionControl, deliveryEvidencePathForClickUpTask, ensureClickUpTaskWorktree, ensureClickUpTaskWorktreeForWebhook, ensureClickUpTaskWorktreeOpenChamber, ensureClickUpWebhookSubscription, handleClickUpWebhookRequest, inspectOpenCodeSessionActivity, isClickUpDerivedWorktreeSibling, isClickUpSubtaskRoute, isClickUpWebhookStateActive, isSameOrNestedPath, normalizeClickUpWebhookConfig, normalizeClickUpWebhookLogLevel, normalizeOpenCodeBaseUrl, openCodeSessionExists, promptOpenCodeSessionControl, probeOpenCodeSessionControl, readClickUpCommentLedger, readClickUpWebhookState, readOpenCodeSessionControl, readOpenCodeSessionMessages, reconcileClickUpStartup, registerOpenChamberClickUpWorktree, scheduleClickUpAssignmentWatchdog, scheduleClickUpStartupReconciliation, syncOpenChamberWorktreeVisibility, waitForOpenCodeReadiness, recordClickUpCommentVersionProcessed, resyncClickUpWebhookForSignatureDrift, resolveIncludeFile, resolveIncludes, resolveOptimaPluginOptions, resolveSecretReference, routeClickUpWebhookEvent, sendOpenCodeSessionEvent, sendOpenCodeSessionEventDirect, summarizeOpenCodeMessages, verifyOpenCodeSessionEventDelivery, stableClickUpCommentVersionMarker, startClickUpWebhookListener, validateClickUpWebhookState, verifyClickUpSignature, writeClickUpWebhookState, decideClickUpStatusAction, deriveClickUpBranchName, deriveClickUpPendingSubtaskBranch, deriveClickUpPrTarget, deriveClickUpRequiredPullRequest, deriveClickUpWorktree, determineClickUpMergeAuthority, ensureOptimaGitignoreRules, explicitSafeInputWorktree, finalApprovalAssignees, formatRepairResult, formatValidationResult, isIgnoredClickUpTaskType, isOptimaPluginPackageWorktree, isSafeWritableDirectory, loadHumansRegistry, mergeClickUpAgentMetadata, mergeClickUpSessionMetadata, migrateLegacyOptimaLayout, normalizeAgentMetadataJson, normalizeClickUpStatus, normalizeClickUpTaskType, normalizePromptResponseParts, normalizeWorkflowTaskPath, optimaRepairDependencies, parseClickUpSubtasksMarkdown, parseHumansRegistry, parseMarkdownArtifact, parseMarkdownSections, planOptimaRepair, preEstimateClickUpWork, readMarkdownArtifact, resolveHumanRoles, resolveSafeWorktree, safeWorktreeOrFailure, stripRawLogSections, validateMainWorkspaceBranchSafety, workflowFinalMessageFromPromptResponse };
|
|
13787
13882
|
|
|
13788
13883
|
// src/sanitize_cli.js
|
|
13789
13884
|
var { migrateLegacyOptimaLayout: migrateLegacyOptimaLayout2 } = OptimaPlugin.__internals;
|
package/docs/guides/AGENTS.md
CHANGED
|
@@ -61,3 +61,14 @@ Use shared policies and additive agent files by default. Do not create or popula
|
|
|
61
61
|
- PMA links the task to an approved SCR.
|
|
62
62
|
- Architect helps decompose the work into slice-based subtasks.
|
|
63
63
|
- `workflow_runner` executes the end-to-end delivery cycle through specialist delegation while PMA waits for completion notification.
|
|
64
|
+
|
|
65
|
+
## ClickUp-First PR And Preproduction Gate
|
|
66
|
+
|
|
67
|
+
For ClickUp-first delivery, Validation is a GitHub PR state, not a comment-only handoff.
|
|
68
|
+
|
|
69
|
+
- Subtasks open/update a PR from the subtask branch into the parent task branch before entering Validation.
|
|
70
|
+
- Parent tasks open/update a PR from the task branch into `dev` before entering Validation.
|
|
71
|
+
- GitHub review/comment webhooks wake the workflow owner. The agent replies in GitHub; if a comment requires a change, it moves ClickUp back to `in progress`, fixes/pushes the same branch, returns ClickUp to `validation`, updates the PR, and replies again with the result.
|
|
72
|
+
- The configured final approver/CTO approving the parent PR is the merge trigger. After merge to `dev`, Vercel preproduction must deploy automatically and pass a small smoke/regression check before cleanup and ClickUp `completed`.
|
|
73
|
+
- If merge, Vercel deployment, or regression fails, create Bug subtasks under the parent and return the parent to `in progress`.
|
|
74
|
+
- Worktrees/branches may be deleted only after the merge and preproduction gate pass. OpenCode session ids remain in ClickUp `agent_metadata` so a reopened task can recreate the worktree and resume context.
|
package/package.json
CHANGED
|
@@ -67,5 +67,24 @@ workflow:
|
|
|
67
67
|
subtask: parent_branch
|
|
68
68
|
parent: dev
|
|
69
69
|
release: main
|
|
70
|
+
validation_requires_pull_request: true # A task/subtask cannot enter Validation without an open GitHub PR
|
|
71
|
+
review_webhooks:
|
|
72
|
+
enabled: true
|
|
73
|
+
events:
|
|
74
|
+
- pull_request_review
|
|
75
|
+
- pull_request_review_comment
|
|
76
|
+
- issue_comment
|
|
77
|
+
- pull_request
|
|
78
|
+
comment_policy: reply_before_change_and_after_change
|
|
79
|
+
change_request_status: in progress
|
|
80
|
+
after_fix_status: validation
|
|
81
|
+
accepted_by: CTO
|
|
82
|
+
vercel:
|
|
83
|
+
preproduction:
|
|
84
|
+
required_for_parent_tasks: true
|
|
85
|
+
environment: preproduction
|
|
86
|
+
verify_deployment_after_merge: true
|
|
87
|
+
smoke_regression_required: true
|
|
88
|
+
on_failure: create_bug_subtasks_and_return_parent_to_in_progress
|
|
70
89
|
|
|
71
90
|
agents:
|