@defend-tech/opencode-optima 0.1.23 → 0.1.25

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/Agents_Common.md CHANGED
@@ -12,12 +12,13 @@
12
12
  - Use the ClickUp skill and ClickUp MCP/tools for all ClickUp reads, writes, comments, field updates, status transitions, assignments, and dashboard operations; if unavailable or forbidden, state the sync blocker and leave a manual-sync payload in task/evidence.
13
13
  - Before writing ClickUp updates from local artifacts, use Optima Markdown-driven sync tools (`optima_clickup_start_task`, `optima_clickup_sync_summary`, `optima_clickup_transition`, `optima_clickup_create_subtasks`, `optima_clickup_apply_payload`) to derive payloads from `.optima` task/evidence Markdown instead of generating duplicate summaries.
14
14
  - Human-readable task/evidence summaries, validation results, AC coverage, documentation impact, blockers, reopen history, status-transition rationale, and final handoffs are the right source and must be posted to the linked ClickUp task/subtask comments or fields; subtasks come from strict plan/Definition `## Subtasks` sections via `optima_clickup_create_subtasks`.
15
+ - WPM rewrites the ClickUp task description on initial pickup and again at plan completion with the complete current/final description of what must be done, distinct from comments.
15
16
  - Keep raw logs in evidence storage; do not paste raw logs wholesale into ClickUp. Post concise summaries, paths/links, or relevant excerpts only.
16
17
  - `product_manager` may investigate, answer, pre-estimate "a qué huele" small/medium/large plus rough story points, and operate ClickUp dashboards; development requests must be converted into properly routed ClickUp tasks.
17
18
  - ClickUp delivery types are `Tarea`, `Bug`, `Doc`, `PoC`; ignore `Idea`, legacy `Backlog` alias, `Hito`, `Nota de reunión`, and `Respuesta del formulario` unless converted or linked.
18
19
  - WPM estimates `Story Points` during `plan` and re-estimates on material plan changes.
19
20
  - Human role registry: resolve `CTO` and `PO` from `docs/core/humans.md`; use role identifiers in workflow text and code instead of personal names.
20
- - ClickUp status actions: `backlog` ignore, `plan` plan plus assign `CTO`/`PO` at plan end, `in progress` execute, `validation` Tech Lead + Validator/QA gates. After validation, Validator/QA may merge validated subtasks into the parent branch without `CTO`/`PO` approval; validated parent tasks stay in `validation` for `CTO`/`PO` approval, they approve by moving the parent to `merge`, and Validator/QA then attempts the parent merge into `dev`. `completed`/`Closed` ignore unless reopened.
21
+ - ClickUp status actions: `backlog` ignore, `plan` plan plus remove the PM assignee before assigning `CTO`/`PO` at plan end, `in progress` execute, `validation` Tech Lead + Validator/QA gates. After validation, Validator/QA may merge validated subtasks into the parent branch without `CTO`/`PO` approval; validated parent tasks stay in `validation` for `CTO`/`PO` approval, they approve by moving the parent to `merge`, and Validator/QA then attempts the parent merge into `dev`. `completed`/`Closed` ignore unless reopened.
21
22
  - One shared-worktree `implementation` task may be active; ClickUp-first delivery should use task-specific worktrees/branches.
22
23
  - Agent messages must start with `[Agent Message] From: <agent_name> To: <agent_name>`.
23
24
  - Clarifications, blockers, dependencies, and reviews go through PMA.
@@ -26,7 +27,7 @@
26
27
  - No task is done with failing builds/tests, skipped tests, missing validation, or incomplete documentation closure.
27
28
  - Final reports must trace numbered acceptance criteria to verification results.
28
29
  - After implementation, update the task file with `# Post Implementation Task Updates` and `## <Agent Name>: Post Implementation Expectations`.
29
- - `Definition` is the plan contract and may be linked in ClickUp field `Definition`; final Documentation is delivered behavior documentation and is separately required when relevant.
30
+ - `Definition` is the plan contract and may be linked in ClickUp field `Definition`; Definition docs default under ClickUp parent doc/page `2kxuv6pq-852/2kxuv6pq-2292` and must contain the complete plan/Definition content, not an empty page or comment-only plan; final Documentation is delivered behavior documentation and is separately required when relevant.
30
31
  - ClickUp webhook mode validates `X-Signature` HMAC SHA-256, deduplicates events, ignores self-authored comments, routes only PM-assigned non-terminal tasks, wakes comments only on `@Defend Tech Product Manager`, writes new Product Manager `ses_...` ids to `agent_metadata`, and reports missing stored sessions with host/datetime/id instead of creating replacements.
31
32
  - Documentation closure is mandatory: update product/architecture/technical docs when relevant or explicitly state no product-doc update is required; Validator/QA fails validation when required final documentation is missing or stale.
32
33
  - Reopen same-scope discrepancies in the original task file with `Reopen History`; reuse Task/Workflow Runner session IDs when possible.
@@ -14,12 +14,13 @@
14
14
  - Use the ClickUp skill and ClickUp MCP/tools for all ClickUp reads, writes, comments, field updates, status transitions, assignments, and dashboard operations; if unavailable or forbidden, state the sync blocker and leave a manual-sync payload in task/evidence.
15
15
  - Before writing ClickUp updates from local artifacts, use Optima Markdown-driven sync tools (`optima_clickup_start_task`, `optima_clickup_sync_summary`, `optima_clickup_transition`, `optima_clickup_create_subtasks`, `optima_clickup_apply_payload`) to derive payloads from `.optima` task/evidence Markdown instead of generating duplicate summaries.
16
16
  - Human-readable task/evidence summaries, validation results, AC coverage, documentation impact, blockers, reopen history, status-transition rationale, and final handoffs are the right source and must be posted to the linked ClickUp task/subtask comments or fields; subtasks come from strict plan/Definition `## Subtasks` sections via `optima_clickup_create_subtasks`.
17
+ - WPM rewrites the ClickUp task description on initial pickup and again at plan completion with the complete current/final description of what must be done, distinct from comments.
17
18
  - Keep raw logs in evidence storage; do not paste raw logs wholesale into ClickUp. Post concise summaries, paths/links, or relevant excerpts only.
18
19
  - `product_manager` may investigate, answer, pre-estimate "a qué huele" small/medium/large plus rough story points, and operate ClickUp dashboards; development requests must become routed ClickUp tasks.
19
20
  - ClickUp-first delivery types: `Tarea`, `Bug`, `Doc`, `PoC`; ignore `Idea`, legacy `Backlog` alias, `Hito`, `Nota de reunión`, `Respuesta del formulario` unless converted or linked.
20
21
  - WPM estimates `Story Points` during `plan` and re-estimates on material plan changes.
21
22
  - Human role registry: resolve `CTO` and `PO` from `docs/core/humans.md`; use role identifiers in workflow text and code instead of personal names.
22
- - ClickUp-first statuses: `backlog` ignore, `plan` plan plus assign `CTO`/`PO` at plan end, `in progress` execute, `validation` Tech Lead + Validator/QA gates. Validator/QA may merge validated subtasks into the parent branch without `CTO`/`PO` approval; validated parent tasks stay in `validation` for `CTO`/`PO` approval, they approve by moving the parent to `merge`, and Validator/QA then attempts the parent merge into `dev`. `completed`/`Closed` ignore unless reopened.
23
+ - ClickUp-first statuses: `backlog` ignore, `plan` plan plus remove the PM assignee before assigning `CTO`/`PO` at plan end, `in progress` execute, `validation` Tech Lead + Validator/QA gates. Validator/QA may merge validated subtasks into the parent branch without `CTO`/`PO` approval; validated parent tasks stay in `validation` for `CTO`/`PO` approval, they approve by moving the parent to `merge`, and Validator/QA then attempts the parent merge into `dev`. `completed`/`Closed` ignore unless reopened.
23
24
  - Signed agent-to-agent messages must start exactly: `[Agent Message] From: <agent_name> To: <agent_name>`.
24
25
  - Direct all clarifications, blockers, and specialist questions through PMA unless explicitly in a direct discussion-capable role.
25
26
  - Read relevant docs/tasks fully when they govern the current work. Prefer targeted CodeMap navigation before broad source search.
@@ -27,7 +28,7 @@
27
28
  - No task is done with failing builds, failing tests, skipped tests, or missing validation. Fix failures instead of accepting them.
28
29
  - Final evidence must trace numbered acceptance criteria (`AC-1`, `AC-2`, ...) to verification results.
29
30
  - After implementation, update the task file with `# Post Implementation Task Updates` and `## <Agent Name>: Post Implementation Expectations`.
30
- - `Definition` is the plan contract and may be linked in ClickUp field `Definition`; final Documentation is delivered behavior documentation and separately required when relevant.
31
+ - `Definition` is the plan contract and may be linked in ClickUp field `Definition`; Definition docs default under ClickUp parent doc/page `2kxuv6pq-852/2kxuv6pq-2292` and must contain the complete plan/Definition content, not an empty page or comment-only plan; final Documentation is delivered behavior documentation and separately required when relevant.
31
32
  - ClickUp webhook mode validates `X-Signature` HMAC SHA-256, deduplicates events, ignores self-authored comments, routes only PM-assigned non-terminal tasks, wakes comments only on `@Defend Tech Product Manager`, writes new Product Manager `ses_...` ids to `agent_metadata`, and reports missing stored sessions with host/datetime/id instead of creating replacements.
32
33
  - Documentation closure is mandatory: update product/architecture/technical docs when relevant or explicitly state that product documentation is not required; Validator/QA fails validation when required final documentation is missing or stale.
33
34
  - Reopen/resume same-scope fixes in the original task file. Record `Reopen History`; reuse Task tool `task_id` and Workflow Runner `session_id` when possible.
@@ -9,3 +9,6 @@ sources_of_truth:
9
9
  - path: developer.md
10
10
  - path: qa_engineer.md
11
11
  - path: ui_ux_designer.md
12
+ internals:
13
+ - path: ops_product_manager.md
14
+ - path: workflow_product_manager.md
@@ -27,6 +27,8 @@ You are the Workflow Product Manager Agent (Workflow_Product_Manager), the Click
27
27
  - Keep raw logs in evidence storage; ClickUp receives concise summaries, paths/links, or relevant excerpts only, never pasted raw logs wholesale.
28
28
  - If the ClickUp skill/MCP is unavailable or ClickUp writes are forbidden, record the sync blocker and manual-sync payload in the task/evidence.
29
29
  - `Definition` is the plan contract. Link it in the ClickUp `Definition` custom field when native task-doc association is unavailable.
30
+ - Create Definition docs under ClickUp parent doc/page `2kxuv6pq-852/2kxuv6pq-2292`; never create new Definition docs at ClickUp Docs root.
31
+ - Definition document content must contain the complete plan/Definition, including scope, acceptance criteria, task decomposition, owners, test strategy, evidence expectations, handoff rules, and open risks; an empty doc or comment-only plan is invalid.
30
32
  - Final Documentation is delivered behavior/technical/user documentation, separate from `Definition`; Validator/QA must fail validation when required final documentation is missing or outdated.
31
33
  - Store `agent_metadata` JSON with session IDs per agent/type/task/subtask; update it whenever an agent session starts or changes responsibility.
32
34
  - Evidence remains in git for now under `.optima/evidences/<task-id>/`.
@@ -47,7 +49,7 @@ You are the Workflow Product Manager Agent (Workflow_Product_Manager), the Click
47
49
 
48
50
  - `backlog`: ignore for execution until prioritized.
49
51
  - Human role registry: resolve `CTO` and `PO` from `docs/core/humans.md`; use role identifiers in workflow text, task comments, and automation config.
50
- - `plan`: plan, clarify acceptance criteria, SCRs, test strategy with Validator/QA, task decomposition, `Definition`, story point estimate, and implementation handoff. At end of `plan`, assign both `CTO` and `PO`.
52
+ - `plan`: plan, clarify acceptance criteria, SCRs, test strategy with Validator/QA, task decomposition, `Definition`, story point estimate, and implementation handoff. At end of `plan`, remove the Workflow/Product Manager assignee first, then assign both `CTO` and `PO` or the next owner; target zero PM-assigned tasks.
51
53
  - `in progress`: execute through the assigned delivery agent or workflow runner.
52
54
  - `validation`: route Tech Lead for architecture/code/PR/standards/repo-skill review and Validator/QA for tests, Playwright flows, regression, required coverage, evidence, and final documentation checks. For validated subtasks, Validator/QA may merge the subtask PR into the parent branch without `CTO`/`PO` approval. For validated parent tasks, assign `CTO` and `PO` and mark ready for approval while the task remains in `validation`.
53
55
  - `merge`: parent-task approval state reached only when `CTO`/`PO` approve by moving the parent task from `validation` to `merge`; Validator/QA then attempts the parent PR merge into `dev`. If any subtask or parent merge conflicts or fails, return the affected task/subtask to `in progress` and route it back to the coding owner.
@@ -71,7 +73,10 @@ You are the Workflow Product Manager Agent (Workflow_Product_Manager), the Click
71
73
 
72
74
  - Orchestrate; do not silently implement specialist work yourself.
73
75
  - Delegate with explicit ClickUp task context, acceptance criteria, expected evidence, ClickUp comment/field sync requirements, branch target, Story Points handling, `Definition` link, final Documentation needs, and validation requirements.
76
+ - On initial pickup, rewrite the ClickUp task description with the complete current description of what must be done; do not rely on a status comment as the task description.
77
+ - At plan completion, rewrite the ClickUp task description again with the complete final plan/Definition of what must be done, distinct from the plan comment.
74
78
  - Estimate Story Points during `plan`, write them to ClickUp `Story Points`, and re-estimate whenever material plan changes alter scope or risk.
79
+ - Before assigning `CTO`/`PO` or any other next owner, remove the PM assignee from the ClickUp task and verify no task remains assigned to Workflow/Product Manager unless explicitly re-queued.
75
80
  - Keep `.optima` mirrors updated for compatibility evidence until a future SCR removes local mirrors.
76
81
  - Final handoffs must include Summary, Work Performed, AC Coverage, Documentation Impact, Open Risks, Recommended Next Step, verification results, and commit/PR status.
77
82
 
package/dist/index.js CHANGED
@@ -7908,6 +7908,11 @@ var MANDATORY_AGENTS = /* @__PURE__ */ new Set(["product_manager", "business_ana
7908
7908
  var MINI_MODE_AGENTS = /* @__PURE__ */ new Set(["product_manager", "business_analyst", "tech_lead"]);
7909
7909
  var CLICKUP_IGNORED_TASK_TYPES = ["Idea", "Backlog", "Hito", "Nota de reuni\xF3n", "Respuesta del formulario"];
7910
7910
  var CLICKUP_FINAL_APPROVER_ROLES = ["CTO", "PO"];
7911
+ var CLICKUP_PM_ASSIGNEE_PLACEHOLDER = "product_manager";
7912
+ var CLICKUP_DEFINITION_DOC_PARENT = {
7913
+ doc_id: "2kxuv6pq-852",
7914
+ page_id: "2kxuv6pq-2292"
7915
+ };
7911
7916
  var CLICKUP_STORY_POINT_ESTIMATES = {
7912
7917
  small: 2,
7913
7918
  medium: 5,
@@ -8528,7 +8533,25 @@ function deriveClickUpWorktree({ baseWorktree = "", taskId, taskType, parentTask
8528
8533
  const root = baseWorktree || process.cwd();
8529
8534
  return path2.join(path2.dirname(root), `${path2.basename(root)}-${branch.replace(/\//g, "-")}`);
8530
8535
  }
8531
- function buildClickUpStartTaskPayload({ taskId, taskType = "Tarea", parentTaskId = "", subtaskId = "", baseWorktree = "", definition = "", complexity = "standard", filesChanged = 0, acceptanceCriteria = 0, unknowns = 0, existingAgentMetadata = "", agentMetadata = {}, apply = false } = {}) {
8536
+ function normalizeClickUpDefinitionDocParent(parent = {}) {
8537
+ const docId = String(parent.doc_id || parent.docId || CLICKUP_DEFINITION_DOC_PARENT.doc_id).trim();
8538
+ const pageId = String(parent.page_id || parent.pageId || CLICKUP_DEFINITION_DOC_PARENT.page_id).trim();
8539
+ return { doc_id: docId, page_id: pageId };
8540
+ }
8541
+ function isRealClickUpAssigneeId(value) {
8542
+ const id = String(value || "").trim();
8543
+ return Boolean(id) && id !== CLICKUP_PM_ASSIGNEE_PLACEHOLDER;
8544
+ }
8545
+ function clickUpPayloadValidationError(errors = []) {
8546
+ return { ok: false, mode: "payload", dryRun: true, errors };
8547
+ }
8548
+ function buildClickUpStartTaskPayload({ taskId, taskType = "Tarea", parentTaskId = "", subtaskId = "", baseWorktree = "", definition = "", taskDescription = "", definitionDocParent = CLICKUP_DEFINITION_DOC_PARENT, complexity = "standard", filesChanged = 0, acceptanceCriteria = 0, unknowns = 0, existingAgentMetadata = "", agentMetadata = {}, apply = false } = {}) {
8549
+ const definitionContent = compactMarkdownValue(definition);
8550
+ const description = compactMarkdownValue(taskDescription);
8551
+ const errors = [];
8552
+ if (!definitionContent) errors.push("definition is required and must contain the complete plan/Definition content.");
8553
+ if (!description) errors.push("taskDescription is required for the initial ClickUp task description rewrite.");
8554
+ if (errors.length > 0) return clickUpPayloadValidationError(errors);
8532
8555
  const effectiveParent = parentTaskId || taskId;
8533
8556
  const branch = deriveClickUpBranchName({ taskType, parentTaskId: effectiveParent, subtaskId, taskId });
8534
8557
  const worktree = deriveClickUpWorktree({ baseWorktree, taskId, taskType, parentTaskId: effectiveParent, subtaskId });
@@ -8559,17 +8582,23 @@ function buildClickUpStartTaskPayload({ taskId, taskType = "Tarea", parentTaskId
8559
8582
  },
8560
8583
  clickup: {
8561
8584
  comment: `Starting task from dev. Branch: ${branch}. Worktree: ${worktree}.`,
8585
+ description,
8562
8586
  fields: {
8563
- Definition: definition,
8587
+ Definition: definitionContent,
8564
8588
  "Story Points": estimate.storyPoints,
8565
8589
  agent_metadata: metadata,
8566
8590
  branch,
8567
8591
  worktree
8592
+ },
8593
+ definition_doc: {
8594
+ parent: normalizeClickUpDefinitionDocParent(definitionDocParent),
8595
+ content: definitionContent,
8596
+ required: true
8568
8597
  }
8569
8598
  }
8570
8599
  };
8571
8600
  }
8572
- function buildClickUpTransitionPayload({ fromStatus, toStatus, validationPassed = false, validationFailed = false, isSubtask = false, reopen = false, assignees = [], humansRegistry } = {}) {
8601
+ 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 } = {}) {
8573
8602
  const from = normalizeClickUpStatus(fromStatus);
8574
8603
  let to = normalizeClickUpStatus(toStatus);
8575
8604
  if (validationFailed) to = "in progress";
@@ -8580,9 +8609,27 @@ function buildClickUpTransitionPayload({ fromStatus, toStatus, validationPassed
8580
8609
  const key = `${from}->${to}`;
8581
8610
  const rule = CLICKUP_TRANSITIONS.get(key);
8582
8611
  if (!rule) return { ok: false, dryRun: true, message: `Transition not allowed: ${key}` };
8612
+ const assignsFinalApprovers = rule.assignFinalApprovers === true;
8613
+ const requiresPlanCompletionContract = from === "plan" && assignsFinalApprovers;
8614
+ const definitionContent = compactMarkdownValue(definition);
8615
+ const description = compactMarkdownValue(planDescription);
8616
+ const validationErrors = [];
8617
+ if (assignsFinalApprovers && !isRealClickUpAssigneeId(productManagerAssignee) && requireProductManagerAssignee !== false) {
8618
+ validationErrors.push("productManagerAssignee must be the configured ClickUp PM assignee ID before assigning final approvers.");
8619
+ }
8620
+ if (requiresPlanCompletionContract) {
8621
+ if (!description) validationErrors.push("planDescription is required for the plan-completion ClickUp task description rewrite.");
8622
+ if (!definitionContent) validationErrors.push("definition is required and must contain the complete plan/Definition content at plan completion.");
8623
+ }
8624
+ if (validationErrors.length > 0) return clickUpPayloadValidationError(validationErrors);
8583
8625
  const finalApprovers = rule.assignFinalApprovers ? finalApprovalAssignees(CLICKUP_FINAL_APPROVER_ROLES, humansRegistry) : [];
8584
- const assigned = [...new Set([...assignees || [], ...finalApprovers].filter(Boolean))];
8626
+ const explicitRemovals = (removeAssignees || []).filter(Boolean);
8627
+ const normalizedProductManagerAssignee = isRealClickUpAssigneeId(productManagerAssignee) ? String(productManagerAssignee).trim() : "";
8628
+ const removalTargets = rule.assignFinalApprovers ? [...new Set([normalizedProductManagerAssignee, ...explicitRemovals].filter(Boolean))] : explicitRemovals;
8629
+ const assigned = [...new Set([...assignees || [], ...finalApprovers].filter(Boolean))].filter((assignee) => !removalTargets.includes(assignee));
8585
8630
  const authority = from === "validation" || to === "merge" ? determineClickUpMergeAuthority({ isSubtask, clickupStatus: to, validationPassed: validationPassed || to === "merge", humansRegistry }) : null;
8631
+ const fields = authority ? { merge_authority: JSON.stringify(authority) } : {};
8632
+ if (definitionContent) fields.Definition = definitionContent;
8586
8633
  return {
8587
8634
  ok: true,
8588
8635
  dryRun: true,
@@ -8590,8 +8637,19 @@ function buildClickUpTransitionPayload({ fromStatus, toStatus, validationPassed
8590
8637
  clickup: {
8591
8638
  status: rule.status,
8592
8639
  assignees: assigned,
8640
+ assignment_delta: {
8641
+ add: assigned,
8642
+ remove: removalTargets,
8643
+ objective: rule.assignFinalApprovers ? "zero_product_manager_assigned_tasks" : "preserve_existing_owner_policy"
8644
+ },
8593
8645
  comment: rule.comment,
8594
- fields: authority ? { merge_authority: JSON.stringify(authority) } : {}
8646
+ description,
8647
+ fields,
8648
+ definition_doc: definitionContent ? {
8649
+ parent: normalizeClickUpDefinitionDocParent(definitionDocParent),
8650
+ content: definitionContent,
8651
+ required: true
8652
+ } : void 0
8595
8653
  }
8596
8654
  };
8597
8655
  }
@@ -9177,12 +9235,15 @@ function clickUpCommentAuthorId(comment = {}) {
9177
9235
  return String(comment.user?.id || comment.user?.userid || comment.author?.id || comment.author_id || comment.user_id || "").trim();
9178
9236
  }
9179
9237
  function clickUpCommentText(comment = {}) {
9180
- return String(comment.comment_text || comment.text || comment.comment || comment.plain_text || "");
9238
+ if (Array.isArray(comment.comment)) return comment.comment.map((part) => String(part?.text || "")).join("");
9239
+ return String(comment.comment_text || comment.text || comment.comment || comment.plain_text || comment.text_content || "");
9181
9240
  }
9182
9241
  function clickUpCommentMentionsProductManager(comment = {}, routing = {}) {
9183
9242
  const mentionUserId = String(routing.productManagerMentionUserId || "").trim();
9184
9243
  const mentions = Array.isArray(comment.mentions) ? comment.mentions : [];
9185
9244
  if (mentionUserId && mentions.some((mention) => String(mention?.id || mention?.userid || mention?.user?.id || mention).trim() === mentionUserId)) return true;
9245
+ const richText = Array.isArray(comment.comment) ? comment.comment : [];
9246
+ if (mentionUserId && richText.some((part) => part?.type === "tag" && String(part?.user?.id || part?.user?.userid || "").trim() === mentionUserId)) return true;
9186
9247
  const fallback = String(routing.productManagerMentionName || CLICKUP_PM_MENTION_NAME).trim().toLowerCase();
9187
9248
  return fallback ? clickUpCommentText(comment).toLowerCase().includes(`@${fallback}`) : false;
9188
9249
  }
@@ -9526,7 +9587,7 @@ async function routeClickUpWebhookEventUnlocked({ payload, config, state = {}, w
9526
9587
  if (authorId && authorId === config.routing.ignoredCommentAuthorId) return finish({ ok: true, action: "ignored", reason: "self_authored_comment", taskId });
9527
9588
  if (!clickUpCommentMentionsProductManager(comment, config.routing)) return finish({ ok: true, action: "ignored", reason: "missing_product_manager_mention", taskId });
9528
9589
  }
9529
- if (!isClickUpTaskAssignedToProductManager(task, config.routing.productManagerAssigneeId)) return finish({ ok: true, action: "ignored", reason: "not_assigned_to_product_manager", taskId });
9590
+ if (!isCommentEvent && !isClickUpTaskAssignedToProductManager(task, config.routing.productManagerAssigneeId)) return finish({ ok: true, action: "ignored", reason: "not_assigned_to_product_manager", taskId });
9530
9591
  if (isClickUpTaskTerminal(task, payload, config.routing.ignoredStatuses)) return finish({ ok: true, action: "ignored", reason: "terminal_status", taskId });
9531
9592
  if (clickupClient?.getTask) {
9532
9593
  const latestTask = await clickupClient.getTask(taskId);
@@ -10902,7 +10963,8 @@ Restart or reload OpenCode manually if the newly scaffolded config or agents are
10902
10963
  task_type: tool.schema.string().describe("ClickUp task type: Tarea, Bug, Doc, or PoC"),
10903
10964
  parent_task_id: tool.schema.string().describe("Optional parent ClickUp task ID"),
10904
10965
  subtask_id: tool.schema.string().describe("Optional subtask ID"),
10905
- definition: tool.schema.string().describe("Plan/Definition field content"),
10966
+ definition: tool.schema.string().describe("Complete plan/Definition field and Definition doc content"),
10967
+ task_description: tool.schema.string().describe("Complete ClickUp task description to rewrite on pickup; defaults to definition"),
10906
10968
  complexity: tool.schema.string().describe("tiny, standard, or complex"),
10907
10969
  apply: tool.schema.string().describe("Set to 'true' only to mark an apply request; this implementation still returns a dry-run payload only")
10908
10970
  },
@@ -10916,6 +10978,8 @@ Restart or reload OpenCode manually if the newly scaffolded config or agents are
10916
10978
  subtaskId: args.subtask_id,
10917
10979
  baseWorktree: safe.worktree,
10918
10980
  definition: args.definition,
10981
+ taskDescription: args.task_description,
10982
+ definitionDocParent: repoCfg.workflow?.clickup?.definition_doc_parent,
10919
10983
  complexity: args.complexity || "standard",
10920
10984
  apply: String(args.apply || "").toLowerCase() === "true"
10921
10985
  });
@@ -10930,7 +10994,10 @@ Restart or reload OpenCode manually if the newly scaffolded config or agents are
10930
10994
  validation_passed: tool.schema.string().describe("Set to 'true' when validation passed"),
10931
10995
  validation_failed: tool.schema.string().describe("Set to 'true' when validation failed"),
10932
10996
  is_subtask: tool.schema.string().describe("Set to 'true' for subtask transitions"),
10933
- reopen: tool.schema.string().describe("Set to 'true' to reopen completed/closed tasks")
10997
+ reopen: tool.schema.string().describe("Set to 'true' to reopen completed/closed tasks"),
10998
+ product_manager_assignee: tool.schema.string().describe("Current Product Manager assignee ID to remove when assigning final approvers"),
10999
+ plan_description: tool.schema.string().describe("Complete ClickUp task description to rewrite at plan completion"),
11000
+ definition: tool.schema.string().describe("Complete plan/Definition content for the ClickUp Definition field/doc")
10934
11001
  },
10935
11002
  async execute(args) {
10936
11003
  const payload = buildClickUpTransitionPayload({
@@ -10939,7 +11006,11 @@ Restart or reload OpenCode manually if the newly scaffolded config or agents are
10939
11006
  validationPassed: String(args.validation_passed || "").toLowerCase() === "true",
10940
11007
  validationFailed: String(args.validation_failed || "").toLowerCase() === "true",
10941
11008
  isSubtask: String(args.is_subtask || "").toLowerCase() === "true",
10942
- reopen: String(args.reopen || "").toLowerCase() === "true"
11009
+ reopen: String(args.reopen || "").toLowerCase() === "true",
11010
+ productManagerAssignee: args.product_manager_assignee || clickUpWebhookValidation.config?.routing?.productManagerAssigneeId || "",
11011
+ planDescription: args.plan_description,
11012
+ definition: args.definition,
11013
+ definitionDocParent: repoCfg.workflow?.clickup?.definition_doc_parent
10943
11014
  });
10944
11015
  return JSON.stringify(payload, null, 2);
10945
11016
  }
@@ -11326,7 +11397,7 @@ Follow-up: use optima_prompt_workflow with session_id '${sessionId}' to check in
11326
11397
  }
11327
11398
  };
11328
11399
  }
11329
- OptimaPlugin.__internals = { BUNDLE_AGENTS_DIR, activeClickUpWebhookLifecycleRegistry, cleanupManagedClickUpWebhook, deleteClickUpWebhookBestEffort, BUNDLE_POLICIES_DIR, buildClickUpApplyPayloadResult, buildClickUpCreateSubtasksPayload, buildClickUpStartTaskPayload, buildClickUpSummaryPayload, buildClickUpTransitionPayload, buildOptimaAgents, clickUpCommentMentionsProductManager, clickUpWebhookAuditLogDir, clickUpWebhookAuditLogPath, createClickUpApiClient, ensureClickUpWebhookSubscription, handleClickUpWebhookRequest, isClickUpWebhookStateActive, normalizeClickUpWebhookConfig, normalizeClickUpWebhookLogLevel, normalizeOpenCodeBaseUrl, readClickUpWebhookState, resolveOptimaPluginOptions, resolveSecretReference, routeClickUpWebhookEvent, sendOpenCodeSessionEvent, sendOpenCodeSessionEventDirect, startClickUpWebhookListener, validateClickUpWebhookState, verifyClickUpSignature, writeClickUpWebhookState, decideClickUpStatusAction, deriveClickUpBranchName, deriveClickUpPendingSubtaskBranch, deriveClickUpPrTarget, deriveClickUpWorktree, determineClickUpMergeAuthority, ensureOptimaGitignoreRules, explicitSafeInputWorktree, finalApprovalAssignees, formatValidationResult, isIgnoredClickUpTaskType, isOptimaPluginPackageWorktree, isSafeWritableDirectory, loadHumansRegistry, mergeClickUpAgentMetadata, mergeClickUpSessionMetadata, migrateLegacyOptimaLayout, normalizeAgentMetadataJson, normalizeClickUpStatus, normalizeClickUpTaskType, normalizePromptResponseParts, normalizeWorkflowTaskPath, parseClickUpSubtasksMarkdown, parseHumansRegistry, parseMarkdownArtifact, parseMarkdownSections, preEstimateClickUpWork, readMarkdownArtifact, resolveHumanRoles, resolveSafeWorktree, safeWorktreeOrFailure, stripRawLogSections, validateMainWorkspaceBranchSafety, workflowFinalMessageFromPromptResponse };
11400
+ OptimaPlugin.__internals = { BUNDLE_AGENTS_DIR, CLICKUP_DEFINITION_DOC_PARENT, activeClickUpWebhookLifecycleRegistry, cleanupManagedClickUpWebhook, deleteClickUpWebhookBestEffort, BUNDLE_POLICIES_DIR, buildClickUpApplyPayloadResult, buildClickUpCreateSubtasksPayload, buildClickUpStartTaskPayload, buildClickUpSummaryPayload, buildClickUpTransitionPayload, buildOptimaAgents, clickUpCommentMentionsProductManager, clickUpWebhookAuditLogDir, clickUpWebhookAuditLogPath, createClickUpApiClient, ensureClickUpWebhookSubscription, handleClickUpWebhookRequest, isClickUpWebhookStateActive, normalizeClickUpWebhookConfig, normalizeClickUpWebhookLogLevel, normalizeOpenCodeBaseUrl, readClickUpWebhookState, resolveOptimaPluginOptions, resolveSecretReference, routeClickUpWebhookEvent, sendOpenCodeSessionEvent, sendOpenCodeSessionEventDirect, startClickUpWebhookListener, validateClickUpWebhookState, verifyClickUpSignature, writeClickUpWebhookState, decideClickUpStatusAction, deriveClickUpBranchName, deriveClickUpPendingSubtaskBranch, deriveClickUpPrTarget, deriveClickUpWorktree, determineClickUpMergeAuthority, ensureOptimaGitignoreRules, explicitSafeInputWorktree, finalApprovalAssignees, formatValidationResult, isIgnoredClickUpTaskType, isOptimaPluginPackageWorktree, isSafeWritableDirectory, loadHumansRegistry, mergeClickUpAgentMetadata, mergeClickUpSessionMetadata, migrateLegacyOptimaLayout, normalizeAgentMetadataJson, normalizeClickUpStatus, normalizeClickUpTaskType, normalizePromptResponseParts, normalizeWorkflowTaskPath, parseClickUpSubtasksMarkdown, parseHumansRegistry, parseMarkdownArtifact, parseMarkdownSections, preEstimateClickUpWork, readMarkdownArtifact, resolveHumanRoles, resolveSafeWorktree, safeWorktreeOrFailure, stripRawLogSections, validateMainWorkspaceBranchSafety, workflowFinalMessageFromPromptResponse };
11330
11401
  export {
11331
11402
  OptimaPlugin as default
11332
11403
  };
@@ -7915,6 +7915,11 @@ var MANDATORY_AGENTS = /* @__PURE__ */ new Set(["product_manager", "business_ana
7915
7915
  var MINI_MODE_AGENTS = /* @__PURE__ */ new Set(["product_manager", "business_analyst", "tech_lead"]);
7916
7916
  var CLICKUP_IGNORED_TASK_TYPES = ["Idea", "Backlog", "Hito", "Nota de reuni\xF3n", "Respuesta del formulario"];
7917
7917
  var CLICKUP_FINAL_APPROVER_ROLES = ["CTO", "PO"];
7918
+ var CLICKUP_PM_ASSIGNEE_PLACEHOLDER = "product_manager";
7919
+ var CLICKUP_DEFINITION_DOC_PARENT = {
7920
+ doc_id: "2kxuv6pq-852",
7921
+ page_id: "2kxuv6pq-2292"
7922
+ };
7918
7923
  var CLICKUP_STORY_POINT_ESTIMATES = {
7919
7924
  small: 2,
7920
7925
  medium: 5,
@@ -8535,7 +8540,25 @@ function deriveClickUpWorktree({ baseWorktree = "", taskId, taskType, parentTask
8535
8540
  const root = baseWorktree || process.cwd();
8536
8541
  return path2.join(path2.dirname(root), `${path2.basename(root)}-${branch.replace(/\//g, "-")}`);
8537
8542
  }
8538
- function buildClickUpStartTaskPayload({ taskId, taskType = "Tarea", parentTaskId = "", subtaskId = "", baseWorktree = "", definition = "", complexity = "standard", filesChanged = 0, acceptanceCriteria = 0, unknowns = 0, existingAgentMetadata = "", agentMetadata = {}, apply = false } = {}) {
8543
+ function normalizeClickUpDefinitionDocParent(parent = {}) {
8544
+ const docId = String(parent.doc_id || parent.docId || CLICKUP_DEFINITION_DOC_PARENT.doc_id).trim();
8545
+ const pageId = String(parent.page_id || parent.pageId || CLICKUP_DEFINITION_DOC_PARENT.page_id).trim();
8546
+ return { doc_id: docId, page_id: pageId };
8547
+ }
8548
+ function isRealClickUpAssigneeId(value) {
8549
+ const id = String(value || "").trim();
8550
+ return Boolean(id) && id !== CLICKUP_PM_ASSIGNEE_PLACEHOLDER;
8551
+ }
8552
+ function clickUpPayloadValidationError(errors = []) {
8553
+ return { ok: false, mode: "payload", dryRun: true, errors };
8554
+ }
8555
+ function buildClickUpStartTaskPayload({ taskId, taskType = "Tarea", parentTaskId = "", subtaskId = "", baseWorktree = "", definition = "", taskDescription = "", definitionDocParent = CLICKUP_DEFINITION_DOC_PARENT, complexity = "standard", filesChanged = 0, acceptanceCriteria = 0, unknowns = 0, existingAgentMetadata = "", agentMetadata = {}, apply = false } = {}) {
8556
+ const definitionContent = compactMarkdownValue(definition);
8557
+ const description = compactMarkdownValue(taskDescription);
8558
+ const errors = [];
8559
+ if (!definitionContent) errors.push("definition is required and must contain the complete plan/Definition content.");
8560
+ if (!description) errors.push("taskDescription is required for the initial ClickUp task description rewrite.");
8561
+ if (errors.length > 0) return clickUpPayloadValidationError(errors);
8539
8562
  const effectiveParent = parentTaskId || taskId;
8540
8563
  const branch = deriveClickUpBranchName({ taskType, parentTaskId: effectiveParent, subtaskId, taskId });
8541
8564
  const worktree = deriveClickUpWorktree({ baseWorktree, taskId, taskType, parentTaskId: effectiveParent, subtaskId });
@@ -8566,17 +8589,23 @@ function buildClickUpStartTaskPayload({ taskId, taskType = "Tarea", parentTaskId
8566
8589
  },
8567
8590
  clickup: {
8568
8591
  comment: `Starting task from dev. Branch: ${branch}. Worktree: ${worktree}.`,
8592
+ description,
8569
8593
  fields: {
8570
- Definition: definition,
8594
+ Definition: definitionContent,
8571
8595
  "Story Points": estimate.storyPoints,
8572
8596
  agent_metadata: metadata,
8573
8597
  branch,
8574
8598
  worktree
8599
+ },
8600
+ definition_doc: {
8601
+ parent: normalizeClickUpDefinitionDocParent(definitionDocParent),
8602
+ content: definitionContent,
8603
+ required: true
8575
8604
  }
8576
8605
  }
8577
8606
  };
8578
8607
  }
8579
- function buildClickUpTransitionPayload({ fromStatus, toStatus, validationPassed = false, validationFailed = false, isSubtask = false, reopen = false, assignees = [], humansRegistry } = {}) {
8608
+ 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 } = {}) {
8580
8609
  const from = normalizeClickUpStatus(fromStatus);
8581
8610
  let to = normalizeClickUpStatus(toStatus);
8582
8611
  if (validationFailed) to = "in progress";
@@ -8587,9 +8616,27 @@ function buildClickUpTransitionPayload({ fromStatus, toStatus, validationPassed
8587
8616
  const key = `${from}->${to}`;
8588
8617
  const rule = CLICKUP_TRANSITIONS.get(key);
8589
8618
  if (!rule) return { ok: false, dryRun: true, message: `Transition not allowed: ${key}` };
8619
+ const assignsFinalApprovers = rule.assignFinalApprovers === true;
8620
+ const requiresPlanCompletionContract = from === "plan" && assignsFinalApprovers;
8621
+ const definitionContent = compactMarkdownValue(definition);
8622
+ const description = compactMarkdownValue(planDescription);
8623
+ const validationErrors = [];
8624
+ if (assignsFinalApprovers && !isRealClickUpAssigneeId(productManagerAssignee) && requireProductManagerAssignee !== false) {
8625
+ validationErrors.push("productManagerAssignee must be the configured ClickUp PM assignee ID before assigning final approvers.");
8626
+ }
8627
+ if (requiresPlanCompletionContract) {
8628
+ if (!description) validationErrors.push("planDescription is required for the plan-completion ClickUp task description rewrite.");
8629
+ if (!definitionContent) validationErrors.push("definition is required and must contain the complete plan/Definition content at plan completion.");
8630
+ }
8631
+ if (validationErrors.length > 0) return clickUpPayloadValidationError(validationErrors);
8590
8632
  const finalApprovers = rule.assignFinalApprovers ? finalApprovalAssignees(CLICKUP_FINAL_APPROVER_ROLES, humansRegistry) : [];
8591
- const assigned = [...new Set([...assignees || [], ...finalApprovers].filter(Boolean))];
8633
+ const explicitRemovals = (removeAssignees || []).filter(Boolean);
8634
+ const normalizedProductManagerAssignee = isRealClickUpAssigneeId(productManagerAssignee) ? String(productManagerAssignee).trim() : "";
8635
+ const removalTargets = rule.assignFinalApprovers ? [...new Set([normalizedProductManagerAssignee, ...explicitRemovals].filter(Boolean))] : explicitRemovals;
8636
+ const assigned = [...new Set([...assignees || [], ...finalApprovers].filter(Boolean))].filter((assignee) => !removalTargets.includes(assignee));
8592
8637
  const authority = from === "validation" || to === "merge" ? determineClickUpMergeAuthority({ isSubtask, clickupStatus: to, validationPassed: validationPassed || to === "merge", humansRegistry }) : null;
8638
+ const fields = authority ? { merge_authority: JSON.stringify(authority) } : {};
8639
+ if (definitionContent) fields.Definition = definitionContent;
8593
8640
  return {
8594
8641
  ok: true,
8595
8642
  dryRun: true,
@@ -8597,8 +8644,19 @@ function buildClickUpTransitionPayload({ fromStatus, toStatus, validationPassed
8597
8644
  clickup: {
8598
8645
  status: rule.status,
8599
8646
  assignees: assigned,
8647
+ assignment_delta: {
8648
+ add: assigned,
8649
+ remove: removalTargets,
8650
+ objective: rule.assignFinalApprovers ? "zero_product_manager_assigned_tasks" : "preserve_existing_owner_policy"
8651
+ },
8600
8652
  comment: rule.comment,
8601
- fields: authority ? { merge_authority: JSON.stringify(authority) } : {}
8653
+ description,
8654
+ fields,
8655
+ definition_doc: definitionContent ? {
8656
+ parent: normalizeClickUpDefinitionDocParent(definitionDocParent),
8657
+ content: definitionContent,
8658
+ required: true
8659
+ } : void 0
8602
8660
  }
8603
8661
  };
8604
8662
  }
@@ -9184,12 +9242,15 @@ function clickUpCommentAuthorId(comment = {}) {
9184
9242
  return String(comment.user?.id || comment.user?.userid || comment.author?.id || comment.author_id || comment.user_id || "").trim();
9185
9243
  }
9186
9244
  function clickUpCommentText(comment = {}) {
9187
- return String(comment.comment_text || comment.text || comment.comment || comment.plain_text || "");
9245
+ if (Array.isArray(comment.comment)) return comment.comment.map((part) => String(part?.text || "")).join("");
9246
+ return String(comment.comment_text || comment.text || comment.comment || comment.plain_text || comment.text_content || "");
9188
9247
  }
9189
9248
  function clickUpCommentMentionsProductManager(comment = {}, routing = {}) {
9190
9249
  const mentionUserId = String(routing.productManagerMentionUserId || "").trim();
9191
9250
  const mentions = Array.isArray(comment.mentions) ? comment.mentions : [];
9192
9251
  if (mentionUserId && mentions.some((mention) => String(mention?.id || mention?.userid || mention?.user?.id || mention).trim() === mentionUserId)) return true;
9252
+ const richText = Array.isArray(comment.comment) ? comment.comment : [];
9253
+ if (mentionUserId && richText.some((part) => part?.type === "tag" && String(part?.user?.id || part?.user?.userid || "").trim() === mentionUserId)) return true;
9193
9254
  const fallback = String(routing.productManagerMentionName || CLICKUP_PM_MENTION_NAME).trim().toLowerCase();
9194
9255
  return fallback ? clickUpCommentText(comment).toLowerCase().includes(`@${fallback}`) : false;
9195
9256
  }
@@ -9533,7 +9594,7 @@ async function routeClickUpWebhookEventUnlocked({ payload, config, state = {}, w
9533
9594
  if (authorId && authorId === config.routing.ignoredCommentAuthorId) return finish({ ok: true, action: "ignored", reason: "self_authored_comment", taskId });
9534
9595
  if (!clickUpCommentMentionsProductManager(comment, config.routing)) return finish({ ok: true, action: "ignored", reason: "missing_product_manager_mention", taskId });
9535
9596
  }
9536
- if (!isClickUpTaskAssignedToProductManager(task, config.routing.productManagerAssigneeId)) return finish({ ok: true, action: "ignored", reason: "not_assigned_to_product_manager", taskId });
9597
+ if (!isCommentEvent && !isClickUpTaskAssignedToProductManager(task, config.routing.productManagerAssigneeId)) return finish({ ok: true, action: "ignored", reason: "not_assigned_to_product_manager", taskId });
9537
9598
  if (isClickUpTaskTerminal(task, payload, config.routing.ignoredStatuses)) return finish({ ok: true, action: "ignored", reason: "terminal_status", taskId });
9538
9599
  if (clickupClient?.getTask) {
9539
9600
  const latestTask = await clickupClient.getTask(taskId);
@@ -10909,7 +10970,8 @@ Restart or reload OpenCode manually if the newly scaffolded config or agents are
10909
10970
  task_type: tool.schema.string().describe("ClickUp task type: Tarea, Bug, Doc, or PoC"),
10910
10971
  parent_task_id: tool.schema.string().describe("Optional parent ClickUp task ID"),
10911
10972
  subtask_id: tool.schema.string().describe("Optional subtask ID"),
10912
- definition: tool.schema.string().describe("Plan/Definition field content"),
10973
+ definition: tool.schema.string().describe("Complete plan/Definition field and Definition doc content"),
10974
+ task_description: tool.schema.string().describe("Complete ClickUp task description to rewrite on pickup; defaults to definition"),
10913
10975
  complexity: tool.schema.string().describe("tiny, standard, or complex"),
10914
10976
  apply: tool.schema.string().describe("Set to 'true' only to mark an apply request; this implementation still returns a dry-run payload only")
10915
10977
  },
@@ -10923,6 +10985,8 @@ Restart or reload OpenCode manually if the newly scaffolded config or agents are
10923
10985
  subtaskId: args.subtask_id,
10924
10986
  baseWorktree: safe.worktree,
10925
10987
  definition: args.definition,
10988
+ taskDescription: args.task_description,
10989
+ definitionDocParent: repoCfg.workflow?.clickup?.definition_doc_parent,
10926
10990
  complexity: args.complexity || "standard",
10927
10991
  apply: String(args.apply || "").toLowerCase() === "true"
10928
10992
  });
@@ -10937,7 +11001,10 @@ Restart or reload OpenCode manually if the newly scaffolded config or agents are
10937
11001
  validation_passed: tool.schema.string().describe("Set to 'true' when validation passed"),
10938
11002
  validation_failed: tool.schema.string().describe("Set to 'true' when validation failed"),
10939
11003
  is_subtask: tool.schema.string().describe("Set to 'true' for subtask transitions"),
10940
- reopen: tool.schema.string().describe("Set to 'true' to reopen completed/closed tasks")
11004
+ reopen: tool.schema.string().describe("Set to 'true' to reopen completed/closed tasks"),
11005
+ product_manager_assignee: tool.schema.string().describe("Current Product Manager assignee ID to remove when assigning final approvers"),
11006
+ plan_description: tool.schema.string().describe("Complete ClickUp task description to rewrite at plan completion"),
11007
+ definition: tool.schema.string().describe("Complete plan/Definition content for the ClickUp Definition field/doc")
10941
11008
  },
10942
11009
  async execute(args) {
10943
11010
  const payload = buildClickUpTransitionPayload({
@@ -10946,7 +11013,11 @@ Restart or reload OpenCode manually if the newly scaffolded config or agents are
10946
11013
  validationPassed: String(args.validation_passed || "").toLowerCase() === "true",
10947
11014
  validationFailed: String(args.validation_failed || "").toLowerCase() === "true",
10948
11015
  isSubtask: String(args.is_subtask || "").toLowerCase() === "true",
10949
- reopen: String(args.reopen || "").toLowerCase() === "true"
11016
+ reopen: String(args.reopen || "").toLowerCase() === "true",
11017
+ productManagerAssignee: args.product_manager_assignee || clickUpWebhookValidation.config?.routing?.productManagerAssigneeId || "",
11018
+ planDescription: args.plan_description,
11019
+ definition: args.definition,
11020
+ definitionDocParent: repoCfg.workflow?.clickup?.definition_doc_parent
10950
11021
  });
10951
11022
  return JSON.stringify(payload, null, 2);
10952
11023
  }
@@ -11333,7 +11404,7 @@ Follow-up: use optima_prompt_workflow with session_id '${sessionId}' to check in
11333
11404
  }
11334
11405
  };
11335
11406
  }
11336
- OptimaPlugin.__internals = { BUNDLE_AGENTS_DIR, activeClickUpWebhookLifecycleRegistry, cleanupManagedClickUpWebhook, deleteClickUpWebhookBestEffort, BUNDLE_POLICIES_DIR, buildClickUpApplyPayloadResult, buildClickUpCreateSubtasksPayload, buildClickUpStartTaskPayload, buildClickUpSummaryPayload, buildClickUpTransitionPayload, buildOptimaAgents, clickUpCommentMentionsProductManager, clickUpWebhookAuditLogDir, clickUpWebhookAuditLogPath, createClickUpApiClient, ensureClickUpWebhookSubscription, handleClickUpWebhookRequest, isClickUpWebhookStateActive, normalizeClickUpWebhookConfig, normalizeClickUpWebhookLogLevel, normalizeOpenCodeBaseUrl, readClickUpWebhookState, resolveOptimaPluginOptions, resolveSecretReference, routeClickUpWebhookEvent, sendOpenCodeSessionEvent, sendOpenCodeSessionEventDirect, startClickUpWebhookListener, validateClickUpWebhookState, verifyClickUpSignature, writeClickUpWebhookState, decideClickUpStatusAction, deriveClickUpBranchName, deriveClickUpPendingSubtaskBranch, deriveClickUpPrTarget, deriveClickUpWorktree, determineClickUpMergeAuthority, ensureOptimaGitignoreRules, explicitSafeInputWorktree, finalApprovalAssignees, formatValidationResult, isIgnoredClickUpTaskType, isOptimaPluginPackageWorktree, isSafeWritableDirectory, loadHumansRegistry, mergeClickUpAgentMetadata, mergeClickUpSessionMetadata, migrateLegacyOptimaLayout, normalizeAgentMetadataJson, normalizeClickUpStatus, normalizeClickUpTaskType, normalizePromptResponseParts, normalizeWorkflowTaskPath, parseClickUpSubtasksMarkdown, parseHumansRegistry, parseMarkdownArtifact, parseMarkdownSections, preEstimateClickUpWork, readMarkdownArtifact, resolveHumanRoles, resolveSafeWorktree, safeWorktreeOrFailure, stripRawLogSections, validateMainWorkspaceBranchSafety, workflowFinalMessageFromPromptResponse };
11407
+ OptimaPlugin.__internals = { BUNDLE_AGENTS_DIR, CLICKUP_DEFINITION_DOC_PARENT, activeClickUpWebhookLifecycleRegistry, cleanupManagedClickUpWebhook, deleteClickUpWebhookBestEffort, BUNDLE_POLICIES_DIR, buildClickUpApplyPayloadResult, buildClickUpCreateSubtasksPayload, buildClickUpStartTaskPayload, buildClickUpSummaryPayload, buildClickUpTransitionPayload, buildOptimaAgents, clickUpCommentMentionsProductManager, clickUpWebhookAuditLogDir, clickUpWebhookAuditLogPath, createClickUpApiClient, ensureClickUpWebhookSubscription, handleClickUpWebhookRequest, isClickUpWebhookStateActive, normalizeClickUpWebhookConfig, normalizeClickUpWebhookLogLevel, normalizeOpenCodeBaseUrl, readClickUpWebhookState, resolveOptimaPluginOptions, resolveSecretReference, routeClickUpWebhookEvent, sendOpenCodeSessionEvent, sendOpenCodeSessionEventDirect, startClickUpWebhookListener, validateClickUpWebhookState, verifyClickUpSignature, writeClickUpWebhookState, decideClickUpStatusAction, deriveClickUpBranchName, deriveClickUpPendingSubtaskBranch, deriveClickUpPrTarget, deriveClickUpWorktree, determineClickUpMergeAuthority, ensureOptimaGitignoreRules, explicitSafeInputWorktree, finalApprovalAssignees, formatValidationResult, isIgnoredClickUpTaskType, isOptimaPluginPackageWorktree, isSafeWritableDirectory, loadHumansRegistry, mergeClickUpAgentMetadata, mergeClickUpSessionMetadata, migrateLegacyOptimaLayout, normalizeAgentMetadataJson, normalizeClickUpStatus, normalizeClickUpTaskType, normalizePromptResponseParts, normalizeWorkflowTaskPath, parseClickUpSubtasksMarkdown, parseHumansRegistry, parseMarkdownArtifact, parseMarkdownSections, preEstimateClickUpWork, readMarkdownArtifact, resolveHumanRoles, resolveSafeWorktree, safeWorktreeOrFailure, stripRawLogSections, validateMainWorkspaceBranchSafety, workflowFinalMessageFromPromptResponse };
11337
11408
 
11338
11409
  // src/sanitize_cli.js
11339
11410
  var { migrateLegacyOptimaLayout: migrateLegacyOptimaLayout2 } = OptimaPlugin.__internals;
@@ -25,3 +25,4 @@ internals:
25
25
  - path: documentation_structure.prompt.md
26
26
  - path: role_contracts.prompt.md
27
27
  - path: task_model.prompt.md
28
+ - path: humans.md
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@defend-tech/opencode-optima",
3
- "version": "0.1.23",
3
+ "version": "0.1.25",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "git+ssh://git@github.com/defend-tech/opencode-optima.git"
@@ -0,0 +1,62 @@
1
+ # Optima Bundled Policies
2
+
3
+ This package-root directory contains Optima's bundled fallback policy assets. Target repositories should put repo-local policy overrides in `.optima/policies/`, not in this package-root `policies/` directory.
4
+
5
+ ## How Policy Resolution Works
6
+
7
+ For any `<include:policy:<file>.md>` include, Optima resolves policy files in this order:
8
+
9
+ 1. `.optima/policies/<file>.md`
10
+ 2. bundled plugin default `policies/<file>.md`
11
+
12
+ Files under `.optima/.config/generated/policies/` are reference copies only. They are not read directly at runtime.
13
+
14
+ ## Available Policies
15
+
16
+ - `development-guidelines.md`
17
+ - Repository-specific engineering rules, stack notes, and implementation conventions.
18
+ - Used by: `developer`, `technical_architect`, `tech_lead`, `workflow_runner`
19
+
20
+ - `testing-guidelines.md`
21
+ - Testing, evidence, regression, and verification conventions.
22
+ - Used by: `developer`, `qa_engineer`, `tech_lead`, `workflow_runner`
23
+
24
+ - `documentation-guidelines.md`
25
+ - Documentation layout, naming, ownership, and update expectations.
26
+ - Used by all agents through the shared prompt.
27
+
28
+ - `definition-of-ready.md`
29
+ - Canonical readiness criteria before execution begins.
30
+ - Used by all agents through the shared prompt and reflected in task templates.
31
+
32
+ - `definition-of-done.md`
33
+ - Canonical completion criteria before closure.
34
+ - Used by all agents through the shared prompt and reflected in task templates.
35
+
36
+ - `git-commit-messaging.md`
37
+ - Commit subject and body rules.
38
+ - Used by: `tech_lead`, `workflow_runner`
39
+
40
+ - `product-guidelines.md`
41
+ - User story, acceptance criteria, terminology, and product-truth conventions.
42
+ - Used by: `product_manager`, `business_analyst`
43
+
44
+ - `ui-ux-guidelines.md`
45
+ - UI review standards and visual quality expectations.
46
+ - Used by: `ui_ux_designer`
47
+
48
+ ## Customizing A Policy
49
+
50
+ 1. Set `.optima/.config/optima.yaml` `policies.extract_defaults` to `all` if you want reference copies of all bundled defaults.
51
+ 2. Inspect `.optima/.config/generated/policies/` for the default files.
52
+ 3. Copy the policy you want to customize into `.optima/policies/`.
53
+ 4. Edit the copied file. The repo-local version will override the plugin default automatically.
54
+
55
+ ## Policy Extraction
56
+
57
+ `policies.extract_defaults` supports:
58
+
59
+ - `none`: do not generate reference policy files
60
+ - `all`: write all bundled default policy files to `.optima/.config/generated/policies/`
61
+
62
+ Only files in `.optima/policies/` affect runtime prompt behavior.
@@ -0,0 +1,12 @@
1
+ scope: module
2
+ parent: ../codemap.yml
3
+ sources_of_truth:
4
+ - path: README.md
5
+ - path: definition-of-done.md
6
+ - path: definition-of-ready.md
7
+ - path: development-guidelines.md
8
+ - path: documentation-guidelines.md
9
+ - path: git-commit-messaging.md
10
+ - path: product-guidelines.md
11
+ - path: testing-guidelines.md
12
+ - path: ui-ux-guidelines.md
@@ -0,0 +1,27 @@
1
+ # Definition Of Done
2
+
3
+ A task is done only when the implementation, verification, documentation, and workflow closure requirements are all complete.
4
+
5
+ ## Completion Criteria
6
+
7
+ - All in-scope acceptance criteria are satisfied or explicitly marked blocked with documented reason.
8
+ - Required tests, builds, and other verification commands pass according to the repository testing policy.
9
+ - Required evidence and verification artifacts are recorded.
10
+ - Product and technical documentation impact is resolved according to the repository documentation policy.
11
+ - Relevant CodeMap updates are completed when the changed code affects entrypoints, wiring, or maintained source structure.
12
+ - Task files, discussion references, and workflow registries are updated as needed.
13
+ - `.optima/` task, todo, evidence, SCR/docs, registry, discussion, and runtime tracking artifacts are written before the final commit.
14
+ - The authorized review and closure roles have completed their required checks.
15
+ - The final committed state includes all required code, documentation, `.optima` closure artifacts, and registry updates.
16
+
17
+ ## Not Done Conditions
18
+
19
+ - Any required test or build fails.
20
+ - Evidence is missing for claimed verification.
21
+ - Documentation or CodeMap impact remains unresolved.
22
+ - Acceptance criteria are incomplete, unclear, or unverified.
23
+ - Required finalization or archiving steps are missing.
24
+
25
+ ## Operational Rule
26
+
27
+ A task must not be marked complete while any Definition of Done item remains open.
@@ -0,0 +1,27 @@
1
+ # Definition Of Ready
2
+
3
+ A task is ready to begin only when the repository has enough information to execute safely and efficiently without inventing scope.
4
+
5
+ ## Readiness Criteria
6
+
7
+ - Scope is clear, bounded, and appropriate for the task's declared complexity.
8
+ - The task objective is specific enough that the next responsible agent can act without guessing intent.
9
+ - Acceptance criteria are present, testable, and aligned with the stated scope.
10
+ - Complexity, track, and slice are set correctly for the work being requested.
11
+ - Required dependencies, assumptions, blockers, and open questions are either resolved or explicitly recorded.
12
+ - Required pre-sync specialists have reviewed the task definition according to the active task model.
13
+ - An approved SCR exists whenever the workflow requires one.
14
+ - The relevant repository areas are identified well enough to begin safe investigation, design, or implementation.
15
+
16
+ ## Not Ready Conditions
17
+
18
+ - Requirements are ambiguous or contradictory.
19
+ - Acceptance criteria are missing or too vague to verify.
20
+ - The task is larger or riskier than its current routing metadata suggests.
21
+ - Required specialist review has not happened yet.
22
+ - A required SCR is missing or not approved.
23
+ - Critical blockers or dependencies are unknown or unrecorded.
24
+
25
+ ## Operational Rule
26
+
27
+ If the task fails the Definition of Ready, execution should pause until the missing information is resolved or explicitly recorded for follow-up.
@@ -0,0 +1,21 @@
1
+ # Development Guidelines
2
+
3
+ These defaults are intended to be customized per repository when needed.
4
+
5
+ ## Stack Notes
6
+
7
+ - Language: define in the repository if needed.
8
+ - Runtime / Framework: define in the repository if needed.
9
+ - Frontend stack: define in the repository if needed.
10
+ - Testing stack: define in the repository if needed.
11
+ - Database / storage: define in the repository if needed.
12
+
13
+ ## Default Engineering Conventions
14
+
15
+ - Prefer clear module or feature boundaries over ad-hoc file placement.
16
+ - Keep external integrations behind stable interfaces or wrappers when practical.
17
+ - Update `.gitignore` when repository changes introduce generated, temporary, or sensitive files.
18
+ - Prefer stable dependency versions unless repository compatibility requires otherwise.
19
+ - Use dependency-provided setup or initialization utilities when they are the standard way to integrate the dependency safely.
20
+ - Document meaningful architecture changes in the repository's documentation before or alongside implementation.
21
+ - Keep code changes aligned with existing repository conventions unless the repository policy explicitly changes them.
@@ -0,0 +1,39 @@
1
+ # Documentation Guidelines
2
+
3
+ ## Documentation Goals
4
+
5
+ - Keep documentation easy to locate and update.
6
+ - Separate steady-state truth from change proposals and workflow records.
7
+ - Update documentation in the same change set as the implementation whenever the documented truth changes.
8
+
9
+ ## Default Documentation Layout
10
+
11
+ - `docs/product/`: whole-product truth and top-level feature inventory
12
+ - `docs/domains/`: stable product-area truth shared by multiple features
13
+ - `docs/features/`: one concrete capability or feature specification
14
+ - `docs/architecture/`: technical design, contracts, and cross-cutting decisions
15
+ - `.optima/docs/scrs/`: proposed and approved changes, not steady-state truth
16
+
17
+ ## Update Expectations
18
+
19
+ Update the relevant documentation when work changes:
20
+
21
+ - product behavior, terminology, or feature inventory
22
+ - architecture, interfaces, or technical invariants
23
+ - feature specifications or acceptance criteria
24
+ - documentation ownership, naming, or structure conventions
25
+
26
+ ## Default Ownership
27
+
28
+ - Business Analyst: product, domain, and feature truth from the product perspective
29
+ - Technical Architect: architecture truth and technical design documentation
30
+ - Product Manager: verifies documentation closure during workflow execution
31
+ - Developer / Tech Lead / QA: contribute technical accuracy when implementation changes documented truth
32
+
33
+ ## Default Repository Matrix
34
+
35
+ - Product overview: `docs/product/PRODUCT_OVERVIEW.md`
36
+ - Features list: `docs/product/FEATURES_LIST.md`
37
+ - Architecture: `docs/architecture/TECHNICAL_ARCHITECTURE.md`
38
+ - Feature specification: `docs/features/<feature>/SPECIFICATION.md`
39
+ - CodeMap updates: relevant `codemap.yml` files for changed code areas
@@ -0,0 +1,14 @@
1
+ # Git Commit Messaging
2
+
3
+ Use a concise subject line in this format:
4
+
5
+ `<type>: <optional-task-id> <short summary>`
6
+
7
+ Examples:
8
+
9
+ - `docs: update workflow guidance`
10
+ - `fix: TASK-014 correct task archive logic`
11
+
12
+ Always include a brief body that explains what the commit is for and why the change exists.
13
+
14
+ If the commit is associated with a task, include the task ID in the subject when practical.
@@ -0,0 +1,20 @@
1
+ # Product Guidelines
2
+
3
+ ## Product Writing Defaults
4
+
5
+ - Write user stories and requirements in clear, unambiguous language.
6
+ - Keep acceptance criteria specific, testable, and easy to map to verification evidence.
7
+ - Use numbered acceptance criteria (`AC-1`, `AC-2`, ...) for tracked work.
8
+ - Maintain consistent product terminology across SCRs, tasks, and steady-state docs.
9
+
10
+ ## User Story And Acceptance Criteria Conventions
11
+
12
+ - User stories may use the format: `As a <user>, I want <action>, so that <benefit>.`
13
+ - Acceptance criteria should describe observable behavior or outcomes rather than implementation details.
14
+ - When requirements are incomplete or ambiguous, stop and push for clarification instead of inventing scope.
15
+
16
+ ## Product Truth Stewardship
17
+
18
+ - Keep product documentation cross-linked and internally consistent.
19
+ - When behavior changes, update the relevant product-facing docs and SCR registries.
20
+ - If the repository establishes domain or feature naming conventions, apply them consistently.
@@ -0,0 +1,30 @@
1
+ # Testing Guidelines
2
+
3
+ ## Test Levels
4
+
5
+ 1. Unit tests verify isolated logic, functions, and classes.
6
+ 2. Integration tests verify interactions between multiple modules or external services.
7
+ 3. End-to-end tests verify real user or system flows through the product.
8
+ 4. Manual verification is allowed for visual or interaction checks that cannot be automated effectively.
9
+
10
+ ## Verification Policy
11
+
12
+ - All automated tests must pass. No expected skips or tolerated failures are allowed by default.
13
+ - Tests should live close to the code they verify unless the repository uses a clearly defined alternative structure.
14
+ - Every `implementation` task must produce reviewable verification artifacts under `.optima/evidences/<task_id>/`.
15
+ - Do not create or reference a root `evidences/` folder; implementation evidence belongs only under `.optima/evidences/<task_id>/`.
16
+ - Verification artifacts should map back to the task's numbered acceptance criteria.
17
+ - Run the relevant regression coverage before handing implementation back for technical review.
18
+
19
+ ## Evidence Defaults
20
+
21
+ By default, `.optima/evidences/<task_id>/` implementation evidence should include:
22
+
23
+ - `SUMMARY.md` with a short summary and numbered acceptance criteria coverage
24
+ - `logs/` with command output or logs for relevant automated checks
25
+ - `screenshots/` with UI screenshots or visual review artifacts when UI changes are involved
26
+
27
+ ## Non-Implementation Outputs
28
+
29
+ - `investigation` tasks should produce findings, reproduction notes, useful logs, and a recommended next step.
30
+ - `spec` tasks should produce SCR or documentation updates that define the accepted change and its impact.
@@ -0,0 +1,33 @@
1
+ # UI/UX Guidelines
2
+
3
+ ## Core Principles
4
+
5
+ 1. Prioritize ease of use, accessibility, and intuitive navigation.
6
+ 2. Aim for a modern, clean, and polished visual design.
7
+ 3. Keep UI elements visually consistent with the repository's design language.
8
+ 4. Use layout, color, and typography to create clear visual hierarchy.
9
+
10
+ ## Review Workflow
11
+
12
+ - Define the intended screens, interactions, and layout before implementation when UI work is involved.
13
+ - Review screenshots and other visual evidence under `.optima/evidences/<task_id>/` after implementation; do not look for a root evidence folder.
14
+ - Evaluate the result visually rather than by reading code.
15
+ - If the available evidence is insufficient, say so clearly and ask for better screenshots or artifacts.
16
+
17
+ ## Visual Quality Checklist
18
+
19
+ Reject or request fixes when you see:
20
+
21
+ - obvious misalignment against the page or component grid
22
+ - inconsistent spacing between similar elements
23
+ - weak typography hierarchy that makes the screen hard to scan
24
+ - interactive elements that do not look interactive
25
+ - low-contrast text or other readability issues
26
+ - cluttered, dated, or visibly unpolished presentation
27
+
28
+ ## Required Fix Triggers
29
+
30
+ - overlapping UI or clipped text
31
+ - missing key interaction steps that were part of the intended flow
32
+ - ignored design system conventions for color, typography, or spacing
33
+ - an overall result that feels amateur or not ready for users
@@ -48,6 +48,9 @@ workflow:
48
48
  definition: Definition # Plan contract URL when native task-doc association is unavailable
49
49
  story_points: Story Points # WPM estimates during plan and re-estimates on material plan changes
50
50
  agent_metadata: agent_metadata # JSON session IDs per agent/type/task/subtask
51
+ definition_doc_parent:
52
+ doc_id: 2kxuv6pq-852
53
+ page_id: 2kxuv6pq-2292
51
54
  running_label: Running # Optional webhook mode uses local runtime state; enable only through explicit OpenCode ClickUp webhook config
52
55
  final_approval_roles:
53
56
  - CTO