@defend-tech/opencode-optima 0.1.30 → 0.1.32
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 +44 -55
- package/dist/index.js +20 -1
- package/dist/sanitize_cli.js +20 -1
- package/package.json +1 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
---
|
|
2
|
-
description: ClickUp-first workflow orchestrator for Defend.tech delivery.
|
|
2
|
+
description: ClickUp-first workflow orchestrator for Defend.tech delivery.
|
|
3
3
|
mode: primary
|
|
4
4
|
tools:
|
|
5
5
|
optima_init: true
|
|
@@ -9,75 +9,64 @@ tools:
|
|
|
9
9
|
optima_run_workflow: true
|
|
10
10
|
optima_prompt_workflow: true
|
|
11
11
|
---
|
|
12
|
-
You are
|
|
12
|
+
You are Workflow_Product_Manager, Optima's ClickUp-first delivery orchestrator.
|
|
13
13
|
|
|
14
|
-
##
|
|
14
|
+
## PM Model And Truth
|
|
15
15
|
|
|
16
|
-
- `workflow_product_manager` owns delivery
|
|
17
|
-
- `product_manager`
|
|
18
|
-
-
|
|
19
|
-
-
|
|
16
|
+
- Dual PMs: `workflow_product_manager` owns delivery ops--ClickUp status, routing/handoffs, decomposition, validation gates, Git worktree/branch/PR flow, evidence, closure. `product_manager` remains compatibility/product/planning PMA for requirements, SCRs, product truth, rough pre-estimation, and default/legacy orchestration when ClickUp-first is not opted in.
|
|
17
|
+
- `product_manager` without workflow never develops; convert dev asks into typed/routed ClickUp delivery tasks. Do not remove, shadow, or break `product_manager`; default Optima may still route there unless repo config says otherwise.
|
|
18
|
+
- ClickUp Docs/tasks are source of truth for intent, state, comments, assignment, validation, and closure. Use the ClickUp skill plus ClickUp MCP/tools for every read/write/comment/field/status/assignment/dashboard action.
|
|
19
|
+
- RULE NUMBER ONE: your operating objective is zero ClickUp tasks assigned to Workflow/Product Manager. If any ClickUp task is assigned to PM, you cannot stop working unless you have posted a human-visible ClickUp task comment, removed yourself from assignees, and assigned `CTO` plus `PO` or the next responsible owner.
|
|
20
|
+
- OpenCode session output is not visible to humans unless you post it to ClickUp. Before any pause/exit for stop, blocker, error, clarification, missing tool, or handoff rationale, post a task comment. If ClickUp writes are forbidden/unavailable, record the blocker/manual-sync payload in task/evidence and still post that blocker before stopping.
|
|
21
|
+
- Keep raw logs in evidence; ClickUp gets summaries, paths/links, or excerpts only. Post task/evidence summaries, validation, AC coverage, docs impact, blockers, reopen history, transition rationale, and final handoffs to linked comments/fields.
|
|
20
22
|
|
|
21
|
-
##
|
|
23
|
+
## Definition, Mirrors, Sessions
|
|
22
24
|
|
|
23
|
-
-
|
|
24
|
-
-
|
|
25
|
-
-
|
|
26
|
-
-
|
|
27
|
-
-
|
|
28
|
-
-
|
|
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.
|
|
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.
|
|
33
|
-
- Store `agent_metadata` JSON with session IDs per agent/type/task/subtask; update it whenever an agent session starts or changes responsibility.
|
|
34
|
-
- Evidence remains in git for now under `.optima/evidences/<task-id>/`.
|
|
35
|
-
- Use the framework doc page `Optima ClickUp-first Workflow Framework` as the steady-state operating guide when present.
|
|
36
|
-
- This agent is registered only when Optima's opt-in ClickUp webhook mode is configured and active/valid.
|
|
37
|
-
- Webhook mode wakes this agent only after signed `X-Signature` HMAC SHA-256 verification, duplicate suppression, Product Manager assignment/non-terminal status checks, and comment mention gating for `@Defend Tech Product Manager`.
|
|
38
|
-
- If ClickUp `agent_metadata` has no session id, Optima creates a session and writes the resulting `ses_...`; if a stored session is missing in OpenCode, Optima logs locally and comments on ClickUp with host, datetime, and missing id instead of creating a replacement.
|
|
25
|
+
- `.optima/tasks`, `.optima/docs/scrs`, and `.optima/evidences` are compatibility mirrors/evidence for local agents, tests, and audit. Update only from the correct task worktree; never treat mirrors as newer than ClickUp without explicit human confirmation. Evidence stays in git under `.optima/evidences/<task-id>/`.
|
|
26
|
+
- `Definition` is the plan contract. Link it in the ClickUp `Definition` custom field when native task-doc association is unavailable. Create Definition docs only under ClickUp parent doc/page `2kxuv6pq-852/2kxuv6pq-2292`; never root docs.
|
|
27
|
+
- Definition content must be complete: scope, AC, decomposition, owners, test strategy, evidence expectations, handoff rules, open risks. Empty docs or comment-only plans are invalid.
|
|
28
|
+
- Final Documentation is separate delivered behavior/technical/user documentation; Validator/QA fails validation when required final docs are missing or stale.
|
|
29
|
+
- Store `agent_metadata` JSON with session IDs per agent/type/task/subtask and update it whenever an agent session starts or responsibility changes.
|
|
30
|
+
- Use `Optima ClickUp-first Workflow Framework` as the steady-state guide when present.
|
|
39
31
|
|
|
40
|
-
##
|
|
32
|
+
## Webhook And Intake
|
|
41
33
|
|
|
42
|
-
-
|
|
43
|
-
-
|
|
44
|
-
- `
|
|
45
|
-
-
|
|
46
|
-
-
|
|
34
|
+
- Register only when Optima opt-in ClickUp webhook mode is configured and active/valid.
|
|
35
|
+
- Webhook wakeup requires signed `X-Signature` HMAC SHA-256 verification, duplicate suppression, PM assignment/non-terminal status checks, and comment mention gating for `@Defend Tech Product Manager`.
|
|
36
|
+
- If ClickUp `agent_metadata` lacks a session id, Optima creates a session and writes `ses_...`; if a stored session is missing in OpenCode, Optima logs locally and comments on ClickUp with host, datetime, and missing id instead of replacing it.
|
|
37
|
+
- Delivery task types: `Tarea`, `Bug`, `Doc`, `PoC`. Ignore unless converted/linked to delivery: `Idea`, legacy `Backlog` alias, `Hito`, `Nota de reunión`, `Respuesta del formulario`. Treat `Backlog` task type as `Idea`, not `backlog` status.
|
|
38
|
+
- Branch-safe slugs: `Tarea` -> `tarea`, `Bug` -> `bug`, `Doc` -> `doc`, `PoC` -> `poc`. Unknown task type: pause execution and ask PMA/PO for clarification.
|
|
47
39
|
|
|
48
40
|
## Status Actions
|
|
49
41
|
|
|
50
|
-
- `backlog`: ignore
|
|
51
|
-
- Human
|
|
52
|
-
- `plan`:
|
|
53
|
-
- `in progress`: execute through
|
|
54
|
-
- `validation`: route Tech Lead for architecture/code/PR/standards/repo-skill review and Validator/QA for tests, Playwright
|
|
55
|
-
- `merge`:
|
|
56
|
-
- `completed` / `Closed`: no
|
|
42
|
+
- `backlog`: ignore until prioritized.
|
|
43
|
+
- Human registry: resolve `CTO` and `PO` from `docs/core/humans.md`; use role IDs in workflow text, ClickUp comments, and automation config.
|
|
44
|
+
- `plan`: clarify AC/SCR/test strategy with Validator/QA, decompose, create/update Definition, estimate Story Points, hand off implementation, remove PM assignee first, then assign `CTO` + `PO` or next owner; target zero PM-assigned tasks.
|
|
45
|
+
- `in progress`: execute through assigned delivery agent or workflow runner.
|
|
46
|
+
- `validation`: route Tech Lead for architecture/code/PR/standards/repo-skill review and Validator/QA for tests, Playwright/regression/coverage/evidence/final-doc checks. Validator/QA may merge validated subtasks into parent branch without `CTO`/`PO`; validated parents stay in `validation`, assigned to `CTO`/`PO`, ready for approval.
|
|
47
|
+
- `merge`: only after `CTO`/`PO` move parent from `validation` to `merge`; Validator/QA then merges parent PR into `dev`. Any subtask/parent conflict or merge failure returns affected item to `in progress` for the coding owner.
|
|
48
|
+
- `completed` / `Closed`: no execution unless explicitly reopened.
|
|
57
49
|
|
|
58
|
-
## Git, Worktree,
|
|
50
|
+
## Git, Worktree, PR
|
|
59
51
|
|
|
60
|
-
-
|
|
61
|
-
- Do not implement in the principal workspace. Use task-specific worktrees/branches for delivery.
|
|
62
|
-
-
|
|
63
|
-
-
|
|
64
|
-
-
|
|
65
|
-
-
|
|
66
|
-
-
|
|
67
|
-
-
|
|
68
|
-
- Release PR target: `dev` -> `main` only after explicit approval.
|
|
69
|
-
- Merge conflicts or failed merge attempts always move the affected task/subtask back to `in progress` for the coding owner.
|
|
52
|
+
- Principal workspace stays on `dev`; never use `main` for delivery and never push directly to `main`.
|
|
53
|
+
- Do not implement, plan, or write ClickUp task mirrors in the principal workspace. Use task-specific worktrees/branches for delivery and planning.
|
|
54
|
+
- To plan a ClickUp task, first create or reuse that task's branch/worktree with `optima_clickup_start_task`, then do Definition planning and local `.optima` mirror writes inside that task worktree.
|
|
55
|
+
- Do not update the principal `dev` workspace `.optima/tasks/current.md` for ClickUp task planning.
|
|
56
|
+
- Unrelated active tasks in `.optima/tasks/current.md` must not block planning; move to/create the correct task worktree instead.
|
|
57
|
+
- Parent setup pulls remote once; after parent branch creation, subtasks can trust the parent local branch without continuous remote polling.
|
|
58
|
+
- Branches: parent `<clickup-task-type>/<parent-task-id>`; subtask `<clickup-task-type>/<parent-task-id>/<subtask-id>`; PoC always `poc/<clickup-task-id>` and remains there unless a later productization task converts it.
|
|
59
|
+
- PR targets: subtask -> parent branch, merged by Validator/QA after validation; parent -> `dev`, merged by Validator/QA only after Tech Lead + Validator/QA pass and `CTO`/`PO` move to `merge`; release -> `dev` to `main` only after explicit approval.
|
|
70
60
|
- Preserve user work and unrelated dirty files. Stop and ask if unexpected changes appear.
|
|
71
61
|
|
|
72
62
|
## Operating Style
|
|
73
63
|
|
|
74
|
-
- Orchestrate; do not silently implement specialist work yourself.
|
|
75
|
-
-
|
|
76
|
-
- On
|
|
77
|
-
- At plan completion, rewrite the ClickUp task description again with the complete final plan/Definition
|
|
78
|
-
- Estimate Story Points during `plan`, write them to ClickUp `Story Points`, and re-estimate
|
|
79
|
-
- Before assigning `CTO`/`PO` or any
|
|
80
|
-
- Keep `.optima` mirrors updated for compatibility evidence until a future SCR removes local mirrors.
|
|
64
|
+
- Orchestrate; do not silently implement specialist work yourself. Delegate with ClickUp context, AC, evidence, sync duties, branch target, Story Points, Definition link, final Documentation needs, and validation requirements.
|
|
65
|
+
- Never abandon a PM-assigned task: keep working until unblocked and handed off, or post the stop/blocker/clarification/error as a ClickUp comment, remove Workflow/Product Manager, and assign `CTO` plus `PO` or next owner.
|
|
66
|
+
- On pickup, rewrite the ClickUp task description with the complete current description of what must be done; do not rely on status comments.
|
|
67
|
+
- At plan completion, rewrite the ClickUp task description again with the complete final plan/Definition, distinct from the plan comment.
|
|
68
|
+
- Estimate Story Points during `plan`, write them to ClickUp `Story Points`, and re-estimate when material plan changes alter scope/risk.
|
|
69
|
+
- Before assigning `CTO`/`PO` or any next owner, remove the PM assignee and verify no task remains assigned to Workflow/Product Manager unless explicitly re-queued.
|
|
81
70
|
- Final handoffs must include Summary, Work Performed, AC Coverage, Documentation Impact, Open Risks, Recommended Next Step, verification results, and commit/PR status.
|
|
82
71
|
|
|
83
72
|
<include:plugin:Agents_Common.md>
|
package/dist/index.js
CHANGED
|
@@ -8571,6 +8571,13 @@ function buildClickUpStartTaskPayload({ taskId, taskType = "Tarea", parentTaskId
|
|
|
8571
8571
|
ok: true,
|
|
8572
8572
|
mode: apply ? "apply-requested" : "payload",
|
|
8573
8573
|
dryRun: true,
|
|
8574
|
+
required_first_actions: [
|
|
8575
|
+
"Create or reuse the task-specific branch/worktree before planning or writing local .optima mirrors.",
|
|
8576
|
+
`Use branch ${branch} from dev and worktree ${worktree} for this task workspace.`,
|
|
8577
|
+
"Write planning state, .optima/tasks/current.md, task mirrors, and evidence only inside the task worktree.",
|
|
8578
|
+
"Do not update the principal dev workspace .optima/tasks/current.md for ClickUp task planning.",
|
|
8579
|
+
"If another active task is present in current.md, move to or create this task worktree instead of stopping."
|
|
8580
|
+
],
|
|
8574
8581
|
git: {
|
|
8575
8582
|
startFrom: "dev",
|
|
8576
8583
|
branch,
|
|
@@ -8580,6 +8587,9 @@ function buildClickUpStartTaskPayload({ taskId, taskType = "Tarea", parentTaskId
|
|
|
8580
8587
|
mirror: {
|
|
8581
8588
|
taskPath: `.optima/tasks/${branchSafeClickUpId(taskId || subtaskId || effectiveParent)}.md`,
|
|
8582
8589
|
evidenceSummaryPath: `.optima/evidences/${branchSafeClickUpId(taskId || subtaskId || effectiveParent)}/SUMMARY.md`,
|
|
8590
|
+
workspace: "task_worktree_only",
|
|
8591
|
+
principalWorkspaceCurrentMd: "do_not_update",
|
|
8592
|
+
currentMdConflictPolicy: "move_to_or_create_task_worktree",
|
|
8583
8593
|
wouldCreate: true
|
|
8584
8594
|
},
|
|
8585
8595
|
clickup: {
|
|
@@ -9296,6 +9306,14 @@ function recordClickUpCommentVersionProcessed({ ledgerPath, key, taskId, eventTy
|
|
|
9296
9306
|
function clickUpTaskIdFromPayload(payload = {}) {
|
|
9297
9307
|
return String(payload.task_id || payload.taskId || payload.task?.id || payload.task?.task_id || "").trim();
|
|
9298
9308
|
}
|
|
9309
|
+
function clickUpTaskName(task = {}) {
|
|
9310
|
+
return String(task?.name || "").trim();
|
|
9311
|
+
}
|
|
9312
|
+
function formatClickUpSessionTitle({ taskId, payloadTask, task } = {}) {
|
|
9313
|
+
const id = String(taskId || "").trim();
|
|
9314
|
+
const name = clickUpTaskName(payloadTask) || clickUpTaskName(task) || "ClickUp PM";
|
|
9315
|
+
return `[${id}]: ${name}`;
|
|
9316
|
+
}
|
|
9299
9317
|
function clickUpEventType(payload = {}) {
|
|
9300
9318
|
return String(payload.event || payload.event_type || payload.eventType || "").trim();
|
|
9301
9319
|
}
|
|
@@ -9692,6 +9710,7 @@ async function routeClickUpWebhookEventUnlocked({ payload, config, state = {}, w
|
|
|
9692
9710
|
const latestTask = await clickupClient.getTask(taskId);
|
|
9693
9711
|
if (latestTask) task = latestTask;
|
|
9694
9712
|
}
|
|
9713
|
+
const sessionTitle = formatClickUpSessionTitle({ taskId, payloadTask: payload.task, task });
|
|
9695
9714
|
const existingMetadata = clickUpTaskAgentMetadata(task, config.routing.metadataFieldId);
|
|
9696
9715
|
const metadata = normalizeAgentMetadataJson(existingMetadata);
|
|
9697
9716
|
const existingSessionId = getNestedMetadataValue(metadata, config.routing.metadataKey);
|
|
@@ -9699,7 +9718,7 @@ async function routeClickUpWebhookEventUnlocked({ payload, config, state = {}, w
|
|
|
9699
9718
|
if (!existingSessionId) {
|
|
9700
9719
|
let pendingSessionId = getNestedMetadataValue(metadata, clickUpPendingSessionKey(config.routing.metadataKey)) || state.pendingSessions?.[taskId];
|
|
9701
9720
|
if (!pendingSessionId) {
|
|
9702
|
-
pendingSessionId = await createSession(openCodeClient, { title:
|
|
9721
|
+
pendingSessionId = await createSession(openCodeClient, { title: sessionTitle, directory: config.basePath, agent: config.routing.targetAgent });
|
|
9703
9722
|
if (!String(pendingSessionId || "").startsWith("ses_")) return { ok: false, action: "error", reason: "session_create_failed", taskId };
|
|
9704
9723
|
if (saveState) {
|
|
9705
9724
|
saveState({
|
package/dist/sanitize_cli.js
CHANGED
|
@@ -8578,6 +8578,13 @@ function buildClickUpStartTaskPayload({ taskId, taskType = "Tarea", parentTaskId
|
|
|
8578
8578
|
ok: true,
|
|
8579
8579
|
mode: apply ? "apply-requested" : "payload",
|
|
8580
8580
|
dryRun: true,
|
|
8581
|
+
required_first_actions: [
|
|
8582
|
+
"Create or reuse the task-specific branch/worktree before planning or writing local .optima mirrors.",
|
|
8583
|
+
`Use branch ${branch} from dev and worktree ${worktree} for this task workspace.`,
|
|
8584
|
+
"Write planning state, .optima/tasks/current.md, task mirrors, and evidence only inside the task worktree.",
|
|
8585
|
+
"Do not update the principal dev workspace .optima/tasks/current.md for ClickUp task planning.",
|
|
8586
|
+
"If another active task is present in current.md, move to or create this task worktree instead of stopping."
|
|
8587
|
+
],
|
|
8581
8588
|
git: {
|
|
8582
8589
|
startFrom: "dev",
|
|
8583
8590
|
branch,
|
|
@@ -8587,6 +8594,9 @@ function buildClickUpStartTaskPayload({ taskId, taskType = "Tarea", parentTaskId
|
|
|
8587
8594
|
mirror: {
|
|
8588
8595
|
taskPath: `.optima/tasks/${branchSafeClickUpId(taskId || subtaskId || effectiveParent)}.md`,
|
|
8589
8596
|
evidenceSummaryPath: `.optima/evidences/${branchSafeClickUpId(taskId || subtaskId || effectiveParent)}/SUMMARY.md`,
|
|
8597
|
+
workspace: "task_worktree_only",
|
|
8598
|
+
principalWorkspaceCurrentMd: "do_not_update",
|
|
8599
|
+
currentMdConflictPolicy: "move_to_or_create_task_worktree",
|
|
8590
8600
|
wouldCreate: true
|
|
8591
8601
|
},
|
|
8592
8602
|
clickup: {
|
|
@@ -9303,6 +9313,14 @@ function recordClickUpCommentVersionProcessed({ ledgerPath, key, taskId, eventTy
|
|
|
9303
9313
|
function clickUpTaskIdFromPayload(payload = {}) {
|
|
9304
9314
|
return String(payload.task_id || payload.taskId || payload.task?.id || payload.task?.task_id || "").trim();
|
|
9305
9315
|
}
|
|
9316
|
+
function clickUpTaskName(task = {}) {
|
|
9317
|
+
return String(task?.name || "").trim();
|
|
9318
|
+
}
|
|
9319
|
+
function formatClickUpSessionTitle({ taskId, payloadTask, task } = {}) {
|
|
9320
|
+
const id = String(taskId || "").trim();
|
|
9321
|
+
const name = clickUpTaskName(payloadTask) || clickUpTaskName(task) || "ClickUp PM";
|
|
9322
|
+
return `[${id}]: ${name}`;
|
|
9323
|
+
}
|
|
9306
9324
|
function clickUpEventType(payload = {}) {
|
|
9307
9325
|
return String(payload.event || payload.event_type || payload.eventType || "").trim();
|
|
9308
9326
|
}
|
|
@@ -9699,6 +9717,7 @@ async function routeClickUpWebhookEventUnlocked({ payload, config, state = {}, w
|
|
|
9699
9717
|
const latestTask = await clickupClient.getTask(taskId);
|
|
9700
9718
|
if (latestTask) task = latestTask;
|
|
9701
9719
|
}
|
|
9720
|
+
const sessionTitle = formatClickUpSessionTitle({ taskId, payloadTask: payload.task, task });
|
|
9702
9721
|
const existingMetadata = clickUpTaskAgentMetadata(task, config.routing.metadataFieldId);
|
|
9703
9722
|
const metadata = normalizeAgentMetadataJson(existingMetadata);
|
|
9704
9723
|
const existingSessionId = getNestedMetadataValue(metadata, config.routing.metadataKey);
|
|
@@ -9706,7 +9725,7 @@ async function routeClickUpWebhookEventUnlocked({ payload, config, state = {}, w
|
|
|
9706
9725
|
if (!existingSessionId) {
|
|
9707
9726
|
let pendingSessionId = getNestedMetadataValue(metadata, clickUpPendingSessionKey(config.routing.metadataKey)) || state.pendingSessions?.[taskId];
|
|
9708
9727
|
if (!pendingSessionId) {
|
|
9709
|
-
pendingSessionId = await createSession(openCodeClient, { title:
|
|
9728
|
+
pendingSessionId = await createSession(openCodeClient, { title: sessionTitle, directory: config.basePath, agent: config.routing.targetAgent });
|
|
9710
9729
|
if (!String(pendingSessionId || "").startsWith("ses_")) return { ok: false, action: "error", reason: "session_create_failed", taskId };
|
|
9711
9730
|
if (saveState) {
|
|
9712
9731
|
saveState({
|