multica/server/migrations
LinYushen 961de18c97
feat(agents): reply as thread instead of top-level comment (#205)
* feat(agents): reply as thread instead of top-level comment

When an agent responds to a user comment, the reply is now nested under
the triggering comment (parent_id) instead of appearing as a separate
top-level comment. Also enables on_comment trigger by default for newly
created agents.

- Add trigger_comment_id column to agent_task_queue (migration 028)
- Pass triggering comment ID through EnqueueTaskForIssue → task → createAgentComment
- Include parent_id in WebSocket broadcast for agent comments
- Default agent creation includes both on_assign and on_comment triggers

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* feat(cli): add --parent flag to comment add for threaded replies

The agent posts comments via the CLI, so the correct fix is giving it a
--parent flag rather than wiring trigger_comment_id through the task
infrastructure. The agent reads the comment list, decides which comment
to reply to, and passes --parent <comment-id>.

- Add --parent flag to `multica issue comment add`
- Update agent runtime instructions to explain --parent usage

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* feat(daemon): pass trigger_comment_id to agent execution context

The agent now knows which comment triggered its task and gets an explicit
instruction to reply to it using --parent. The trigger_comment_id flows
from the DB through the claim response, daemon Task struct, and into
issue_context.md where the agent sees it.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix(comments): agent replies to thread root, matching frontend behavior

When the triggering comment is itself a reply (has parent_id), resolve
to the thread root so the agent's reply stays in the same flat thread.
This matches the frontend where all replies share the top-level parent.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* feat(cli): show parent_id and full IDs in comment list

The table output now includes a PARENT column and shows full comment IDs
(not truncated) so agents can see thread structure and use --parent.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* feat(daemon): instruct agents to always use --output json

Agents now see explicit guidance to use --output json for all read
commands, ensuring they get structured data with full IDs and parent_id
for proper threading.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* feat(daemon): differentiate comment-trigger vs assign-trigger context

When triggered by a comment, the agent now gets clear instructions:
- Primary goal is to read and respond to the comment
- Do NOT change issue status just because you replied
- Only change status if explicitly requested

This prevents the agent from seeing "In Review" and stopping, since
it now understands the task is to reply, not to re-evaluate the issue.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix(daemon): split workflow by trigger type in CLAUDE.md/AGENTS.md

The Workflow section in the agent's runtime config now shows a
comment-reply workflow when triggered by a comment (read comments,
find trigger, reply, don't change status) vs the full assignment
workflow (set in_progress, do work, set in_review).

Previously the agent always saw the assignment workflow, causing it
to check the issue status, see "In Review", and stop without reading
or replying to the triggering comment.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* refactor(daemon): remove duplicate workflow from issue_context.md

Workflow instructions now live only in CLAUDE.md/AGENTS.md (runtime_config.go).
issue_context.md keeps just the task data: issue ID, trigger type, and
triggering comment ID.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix(task): skip duplicate comment on completion for comment-triggered tasks

When triggered by a comment, the agent posts its own reply via CLI
with --parent. The task completion path was also creating a comment
from the agent's stdout output, resulting in duplicates. Now only
assignment-triggered tasks auto-post output as a comment. Error
messages from FailTask are still posted regardless of trigger type.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-31 13:48:39 +08:00
..
001_init.down.sql feat: pivot to AI-native task management platform (#232) 2026-03-20 17:55:49 +08:00
001_init.up.sql refactor: remove repository field from issues 2026-03-24 18:12:06 +08:00
002_agent_config.down.sql feat(agent): add agent management UI, skills/tools/triggers, and issue assignment 2026-03-23 18:31:25 +08:00
002_agent_config.up.sql feat(agent): add agent management UI, skills/tools/triggers, and issue assignment 2026-03-23 18:31:25 +08:00
003_task_context.down.sql feat(server): add task service layer and daemon REST protocol 2026-03-23 18:34:51 +08:00
003_task_context.up.sql feat(server): add task service layer and daemon REST protocol 2026-03-23 18:34:51 +08:00
004_agent_runtime_loop.down.sql feat(runtime): add local codex daemon pairing 2026-03-24 12:03:14 +08:00
004_agent_runtime_loop.up.sql feat(runtime): add local codex daemon pairing 2026-03-24 12:03:14 +08:00
005_daemon_pairing.down.sql feat(runtime): add local codex daemon pairing 2026-03-24 12:03:14 +08:00
005_daemon_pairing.up.sql feat(runtime): add local codex daemon pairing 2026-03-24 12:03:14 +08:00
006_workspace_context.down.sql feat(workspace): add context field for AI agent background info 2026-03-24 15:59:11 +08:00
006_workspace_context.up.sql feat(workspace): add context field for AI agent background info 2026-03-24 15:59:11 +08:00
007_drop_issue_repository.down.sql refactor: remove repository field from issues 2026-03-24 18:12:06 +08:00
007_drop_issue_repository.up.sql refactor: remove repository field from issues 2026-03-24 18:12:06 +08:00
008_structured_skills.down.sql feat: structured skills system with meta skill runtime injection 2026-03-25 15:17:59 +08:00
008_structured_skills.up.sql feat: structured skills system with meta skill runtime injection 2026-03-25 15:17:59 +08:00
009_verification_code.down.sql feat(auth): email verification login and personal access tokens 2026-03-26 14:32:30 +08:00
009_verification_code.up.sql feat(auth): email verification login and personal access tokens 2026-03-26 14:32:30 +08:00
010_verification_code_attempts.down.sql feat(auth): email verification login and personal access tokens 2026-03-26 14:32:30 +08:00
010_verification_code_attempts.up.sql feat(auth): email verification login and personal access tokens 2026-03-26 14:32:30 +08:00
011_personal_access_tokens.down.sql feat(auth): email verification login and personal access tokens 2026-03-26 14:32:30 +08:00
011_personal_access_tokens.up.sql feat(auth): email verification login and personal access tokens 2026-03-26 14:32:30 +08:00
012_inbox_actor.down.sql fix(db): renumber inbox_actor migration to resolve 009 conflict 2026-03-26 15:44:10 +08:00
012_inbox_actor.up.sql fix(db): make inbox_actor migration idempotent 2026-03-26 17:17:23 +08:00
013_runtime_usage.down.sql feat(runtimes): add Runtimes tab with usage tracking and connection test 2026-03-26 18:28:36 +08:00
013_runtime_usage.up.sql feat(runtimes): add Runtimes tab with usage tracking and connection test 2026-03-26 18:28:36 +08:00
014_workspace_repos.down.sql feat(workspace): add repos JSONB field for GitHub repository URLs 2026-03-27 15:49:30 +08:00
014_workspace_repos.up.sql feat(workspace): add repos JSONB field for GitHub repository URLs 2026-03-27 15:49:30 +08:00
015_issue_subscriber.down.sql feat(notifications): replace hardcoded inbox notifications with subscriber-driven model 2026-03-28 19:33:20 +08:00
015_issue_subscriber.up.sql feat(notifications): replace hardcoded inbox notifications with subscriber-driven model 2026-03-28 19:33:20 +08:00
016_backfill_subscribers.down.sql feat(notifications): replace hardcoded inbox notifications with subscriber-driven model 2026-03-28 19:33:20 +08:00
016_backfill_subscribers.up.sql fix(notifications): address code review feedback 2026-03-28 20:24:07 +08:00
017_comment_parent_id.down.sql feat(activity): unified activity timeline with comment reply support 2026-03-28 21:53:08 +08:00
017_comment_parent_id.up.sql feat(activity): unified activity timeline with comment reply support 2026-03-28 21:53:08 +08:00
018_comment_parent_cascade.down.sql fix(comments): cascade delete replies in DB when parent comment is deleted 2026-03-28 22:04:35 +08:00
018_comment_parent_cascade.up.sql fix(comments): cascade delete replies in DB when parent comment is deleted 2026-03-28 22:04:35 +08:00
019_inbox_details.down.sql feat(inbox): add priority/due_date notifications, structured details, and hover card 2026-03-29 00:22:17 +08:00
019_inbox_details.up.sql feat(inbox): add priority/due_date notifications, structured details, and hover card 2026-03-29 00:22:17 +08:00
020_issue_number.down.sql feat(issues): add human-readable issue identifiers (e.g. JIA-1) 2026-03-29 16:49:55 +08:00
020_issue_number.up.sql feat(issues): add human-readable issue identifiers (e.g. JIA-1) 2026-03-29 16:49:55 +08:00
020_task_session.down.sql feat(agent): add per-task session persistence for Claude Code resumption 2026-03-29 16:53:28 +08:00
020_task_session.up.sql feat(agent): add per-task session persistence for Claude Code resumption 2026-03-29 16:53:28 +08:00
021_agent_instructions.down.sql feat(agent): add instructions field for agent persona/identity 2026-03-29 17:01:07 +08:00
021_agent_instructions.up.sql feat(agent): add instructions field for agent persona/identity 2026-03-29 17:01:07 +08:00
022_task_lifecycle_guards.down.sql feat(tasks): add coalescing queue and task lifecycle guards 2026-03-29 17:52:35 +08:00
022_task_lifecycle_guards.up.sql feat(tasks): add coalescing queue and task lifecycle guards 2026-03-29 17:52:35 +08:00
023_agent_concurrency_default.down.sql fix(daemon): prevent stuck tasks from blocking queue and add concurrent execution 2026-03-30 03:08:52 +08:00
023_agent_concurrency_default.up.sql fix(daemon): prevent stuck tasks from blocking queue and add concurrent execution 2026-03-30 03:08:52 +08:00
024_backfill_empty_issue_prefix.down.sql fix(handler): set issue_prefix when auto-creating workspace on first login 2026-03-30 13:26:42 +08:00
024_backfill_empty_issue_prefix.up.sql fix(handler): set issue_prefix when auto-creating workspace on first login 2026-03-30 13:26:42 +08:00
025_comment_workspace_id.down.sql feat(api): strict workspace isolation + agent parity fixes 2026-03-30 16:49:13 +08:00
025_comment_workspace_id.up.sql feat(api): strict workspace isolation + agent parity fixes 2026-03-30 16:49:13 +08:00
026_comment_reactions.down.sql feat(reactions): add emoji reactions for comments and issue descriptions 2026-03-30 22:37:59 +08:00
026_comment_reactions.up.sql feat(reactions): add emoji reactions for comments and issue descriptions 2026-03-30 22:37:59 +08:00
026_task_messages.down.sql feat(agent): stream live agent output to issue detail page 2026-03-30 22:53:28 +08:00
026_task_messages.up.sql feat(agent): stream live agent output to issue detail page 2026-03-30 22:53:28 +08:00
027_issue_reactions.down.sql feat(reactions): add emoji reactions for comments and issue descriptions 2026-03-30 22:37:59 +08:00
027_issue_reactions.up.sql feat(reactions): add emoji reactions for comments and issue descriptions 2026-03-30 22:37:59 +08:00
028_task_trigger_comment.down.sql feat(agents): reply as thread instead of top-level comment (#205) 2026-03-31 13:48:39 +08:00
028_task_trigger_comment.up.sql feat(agents): reply as thread instead of top-level comment (#205) 2026-03-31 13:48:39 +08:00