Skip to content

improve#4

Merged
khulnasoft-bot merged 13 commits into
khulnasoft:masterfrom
neopilotai:master
Apr 22, 2026
Merged

improve#4
khulnasoft-bot merged 13 commits into
khulnasoft:masterfrom
neopilotai:master

Conversation

@neopilotai

Copy link
Copy Markdown
Contributor

Thinking Path

  • Taskcore orchestrates AI agents for zero-human companies
  • [Which subsystem or capability is involved]
  • [What problem or gap exists]
  • [Why it needs to be addressed]
  • This pull request ...
  • The benefit is ...

What Changed

Verification

Risks

Model Used

Checklist

  • I have included a thinking path that traces from project context to this change
  • I have specified the model used (with version and capability details)
  • I have run tests locally and they pass
  • I have added or updated tests where applicable
  • If this change affects the UI, I have included before/after screenshots
  • I have updated relevant documentation to reflect my changes
  • I have considered and documented any risks above
  • I will address all Greptile and reviewer comments before requesting merge

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, we are unable to review this pull request

The GitHub API does not allow us to fetch diffs exceeding 300 files, and this pull request has 685

@coderabbitai

coderabbitai Bot commented Apr 22, 2026

Copy link
Copy Markdown

Important

Review skipped

Too many files!

This PR contains 299 files, which is 149 over the limit of 150.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: d630ab0f-0589-4886-b5ed-eba197f173d9

📥 Commits

Reviewing files that changed from the base of the PR and between b54303f and 40b571f.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (299)
  • .agents/skills/company-creator/SKILL.md
  • .agents/skills/company-creator/references/example-company.md
  • .agents/skills/create-agent-adapter/SKILL.md
  • .agents/skills/deal-with-security-advisory/SKILL.md
  • .agents/skills/doc-maintenance/SKILL.md
  • .agents/skills/doc-maintenance/references/audit-checklist.md
  • .agents/skills/release-changelog/SKILL.md
  • .agents/skills/release/SKILL.md
  • .claude/skills/taskcore
  • .env.example
  • .github/PULL_REQUEST_TEMPLATE.md
  • .github/workflows/release-smoke.yml
  • .gitignore
  • CONTRIBUTING.md
  • Dockerfile
  • README.md
  • ROADMAP.md
  • adapter-plugin.md
  • cli/README.md
  • cli/package.json
  • cli/src/__tests__/company-import-export-e2e.test.ts
  • cli/src/__tests__/worktree.test.ts
  • cli/src/commands/client/auth.ts
  • cli/src/commands/client/common.ts
  • cli/src/commands/client/company.ts
  • cli/src/commands/client/issue.ts
  • cli/src/commands/client/plugin.ts
  • cli/src/commands/heartbeat-run.ts
  • cli/src/commands/routines.ts
  • cli/src/commands/run.ts
  • cli/src/commands/worktree-merge-history-lib.ts
  • cli/src/commands/worktree.ts
  • doc/DATABASE.md
  • doc/DEPLOYMENT-MODES.md
  • doc/DEVELOPING.md
  • doc/DOCKER.md
  • doc/PUBLISHING.md
  • doc/RELEASE-AUTOMATION-SETUP.md
  • doc/RELEASING.md
  • doc/SPEC-implementation.md
  • doc/execution-semantics.md
  • doc/plans/2026-03-17-docker-release-browser-e2e.md
  • doc/plans/2026-04-18-taskcore-hardening.md
  • doc/plugins/PLUGIN_AUTHORING_GUIDE.md
  • doc/plugins/PLUGIN_SPEC.md
  • doc/spec/agents-runtime.md
  • doc/spec/invite-flow.md
  • docker/Dockerfile.onboard-smoke
  • docs/adapters/creating-an-adapter.md
  • docs/agents-runtime.md
  • docs/api/issues.md
  • docs/deploy/environment-variables.md
  • docs/docs.json
  • docs/guides/agent-developer/comments-and-communication.md
  • docs/guides/agent-developer/handling-approvals.md
  • docs/guides/agent-developer/heartbeat-protocol.md
  • docs/guides/agent-developer/task-workflow.md
  • docs/start/what-is-taskcore.md
  • eslint.config.mjs
  • evals/promptfoo/prompts/heartbeat-system.txt
  • package.json
  • packages/adapter-utils/CHANGELOG.md
  • packages/adapter-utils/package.json
  • packages/adapter-utils/src/server-utils.test.ts
  • packages/adapter-utils/src/server-utils.ts
  • packages/adapter-utils/src/types.ts
  • packages/adapters/claude-local/CHANGELOG.md
  • packages/adapters/claude-local/package.json
  • packages/adapters/claude-local/src/index.ts
  • packages/adapters/claude-local/src/server/execute.ts
  • packages/adapters/claude-local/src/server/prompt-cache.ts
  • packages/adapters/claude-local/src/server/quota.ts
  • packages/adapters/claude-local/src/server/test.ts
  • packages/adapters/codex-local/CHANGELOG.md
  • packages/adapters/codex-local/package.json
  • packages/adapters/codex-local/src/server/execute.ts
  • packages/adapters/codex-local/src/server/index.ts
  • packages/adapters/codex-local/src/server/parse.test.ts
  • packages/adapters/codex-local/src/server/parse.ts
  • packages/adapters/codex-local/src/server/quota-spawn-error.test.ts
  • packages/adapters/codex-local/src/server/quota.ts
  • packages/adapters/codex-local/src/server/test.ts
  • packages/adapters/cursor-local/CHANGELOG.md
  • packages/adapters/cursor-local/package.json
  • packages/adapters/cursor-local/src/server/execute.ts
  • packages/adapters/cursor-local/src/server/skills.ts
  • packages/adapters/cursor-local/src/server/test.ts
  • packages/adapters/gemini-local/package.json
  • packages/adapters/gemini-local/src/server/execute.ts
  • packages/adapters/gemini-local/src/server/skills.ts
  • packages/adapters/openclaw-gateway/CHANGELOG.md
  • packages/adapters/openclaw-gateway/package.json
  • packages/adapters/openclaw-gateway/src/server/execute.ts
  • packages/adapters/openclaw-gateway/src/server/test.ts
  • packages/adapters/opencode-local/CHANGELOG.md
  • packages/adapters/opencode-local/package.json
  • packages/adapters/opencode-local/src/server/execute.ts
  • packages/adapters/opencode-local/src/server/models.ts
  • packages/adapters/opencode-local/src/server/runtime-config.ts
  • packages/adapters/opencode-local/src/server/skills.ts
  • packages/adapters/opencode-local/src/server/test.ts
  • packages/adapters/pi-local/CHANGELOG.md
  • packages/adapters/pi-local/package.json
  • packages/adapters/pi-local/src/server/execute.ts
  • packages/adapters/pi-local/src/server/models.ts
  • packages/adapters/pi-local/src/server/parse.ts
  • packages/adapters/pi-local/src/server/skills.ts
  • packages/adapters/pi-local/src/server/test.ts
  • packages/adapters/pi-local/src/ui/build-config.ts
  • packages/adapters/pi-local/src/ui/parse-stdout.ts
  • packages/db/CHANGELOG.md
  • packages/db/package.json
  • packages/db/scripts/create-auth-bootstrap-invite.ts
  • packages/db/src/backup-lib.test.ts
  • packages/db/src/backup-lib.ts
  • packages/db/src/client.test.ts
  • packages/db/src/index.ts
  • packages/db/src/migration-runtime.ts
  • packages/db/src/migrations/0057_cheerful_betty_ross.sql
  • packages/db/src/migrations/0057_tidy_join_requests.sql
  • packages/db/src/migrations/0058_classy_edwin_jarvis.sql
  • packages/db/src/migrations/0058_wealthy_starbolt.sql
  • packages/db/src/migrations/0059_plugin_database_namespaces.sql
  • packages/db/src/migrations/0059_sour_micromax.sql
  • packages/db/src/migrations/0060_orange_annihilus.sql
  • packages/db/src/migrations/0060_wild_psylocke.sql
  • packages/db/src/migrations/0061_lively_thor_girl.sql
  • packages/db/src/migrations/0062_routine_run_dispatch_fingerprint.sql
  • packages/db/src/migrations/0063_issue_thread_interactions.sql
  • packages/db/src/migrations/0064_issue_thread_interaction_idempotency.sql
  • packages/db/src/migrations/meta/0057_snapshot.json
  • packages/db/src/migrations/meta/0058_snapshot.json
  • packages/db/src/migrations/meta/0060_snapshot.json
  • packages/db/src/migrations/meta/0061_snapshot.json
  • packages/db/src/migrations/meta/_journal.json
  • packages/db/src/runtime-config.ts
  • packages/db/src/schema/agent_runtime_state.ts
  • packages/db/src/schema/agent_wakeup_requests.ts
  • packages/db/src/schema/budget_policies.ts
  • packages/db/src/schema/heartbeat_runs.ts
  • packages/db/src/schema/index.ts
  • packages/db/src/schema/issue_artifacts.ts
  • packages/db/src/schema/issue_reference_mentions.ts
  • packages/db/src/schema/issue_thread_interactions.ts
  • packages/db/src/schema/issues.ts
  • packages/db/src/schema/join_requests.ts
  • packages/db/src/schema/plugin_database.ts
  • packages/db/src/schema/routines.ts
  • packages/db/src/test-embedded-postgres.ts
  • packages/mcp-server/README.md
  • packages/mcp-server/package.json
  • packages/mcp-server/src/client.ts
  • packages/mcp-server/src/tools.test.ts
  • packages/mcp-server/src/tools.ts
  • packages/plugins/create-taskcore-plugin/package.json
  • packages/plugins/create-taskcore-plugin/src/index.ts
  • packages/plugins/examples/plugin-authoring-smoke-example/package.json
  • packages/plugins/examples/plugin-file-browser-example/package.json
  • packages/plugins/examples/plugin-file-browser-example/src/ui/index.tsx
  • packages/plugins/examples/plugin-hello-world-example/package.json
  • packages/plugins/examples/plugin-kitchen-sink-example/package.json
  • packages/plugins/examples/plugin-orchestration-smoke-example/.gitignore
  • packages/plugins/examples/plugin-orchestration-smoke-example/README.md
  • packages/plugins/examples/plugin-orchestration-smoke-example/esbuild.config.mjs
  • packages/plugins/examples/plugin-orchestration-smoke-example/migrations/001_orchestration_smoke.sql
  • packages/plugins/examples/plugin-orchestration-smoke-example/package.json
  • packages/plugins/examples/plugin-orchestration-smoke-example/rollup.config.mjs
  • packages/plugins/examples/plugin-orchestration-smoke-example/src/manifest.ts
  • packages/plugins/examples/plugin-orchestration-smoke-example/src/ui/index.tsx
  • packages/plugins/examples/plugin-orchestration-smoke-example/src/worker.ts
  • packages/plugins/examples/plugin-orchestration-smoke-example/tests/plugin.spec.ts
  • packages/plugins/examples/plugin-orchestration-smoke-example/tsconfig.json
  • packages/plugins/examples/plugin-orchestration-smoke-example/vitest.config.ts
  • packages/plugins/sdk/README.md
  • packages/plugins/sdk/package.json
  • packages/plugins/sdk/src/define-plugin.ts
  • packages/plugins/sdk/src/host-client-factory.ts
  • packages/plugins/sdk/src/index.ts
  • packages/plugins/sdk/src/protocol.ts
  • packages/plugins/sdk/src/testing.ts
  • packages/plugins/sdk/src/types.ts
  • packages/plugins/sdk/src/ui/runtime.ts
  • packages/plugins/sdk/src/worker-rpc-host.ts
  • packages/shared/CHANGELOG.md
  • packages/shared/package.json
  • packages/shared/src/constants.ts
  • packages/shared/src/index.ts
  • packages/shared/src/issue-references.test.ts
  • packages/shared/src/issue-references.ts
  • packages/shared/src/issue-thread-interactions.test.ts
  • packages/shared/src/project-mentions.test.ts
  • packages/shared/src/project-mentions.ts
  • packages/shared/src/types/access.ts
  • packages/shared/src/types/activity.ts
  • packages/shared/src/types/budget.ts
  • packages/shared/src/types/company-portability.ts
  • packages/shared/src/types/dashboard.ts
  • packages/shared/src/types/feedback.ts
  • packages/shared/src/types/heartbeat.ts
  • packages/shared/src/types/index.ts
  • packages/shared/src/types/issue.ts
  • packages/shared/src/types/plugin.ts
  • packages/shared/src/types/project.ts
  • packages/shared/src/types/routine.ts
  • packages/shared/src/types/user-profile.ts
  • packages/shared/src/types/workspace-runtime.ts
  • packages/shared/src/validators/access.ts
  • packages/shared/src/validators/approval.ts
  • packages/shared/src/validators/execution-workspace.ts
  • packages/shared/src/validators/index.ts
  • packages/shared/src/validators/issue.ts
  • packages/shared/src/validators/plugin.ts
  • packages/shared/src/validators/project.ts
  • packages/shared/src/workspace-commands.test.ts
  • packages/shared/src/workspace-commands.ts
  • packages/shared/vitest.config.ts
  • pnpm-workspace.yaml
  • scripts/backfill-issue-reference-mentions.ts
  • scripts/dev-runner-paths.mjs
  • scripts/dev-runner.mjs
  • scripts/dev-runner.ts
  • scripts/discord-daily-digest.sh
  • scripts/docker-onboard-smoke.sh
  • scripts/ensure-workspace-package-links.ts
  • scripts/kill-vitest.sh
  • scripts/provision-worktree.sh
  • scripts/taskcore-commit-metrics.ts
  • server/CHANGELOG.md
  • server/package.json
  • server/src/__tests__/access-service.test.ts
  • server/src/__tests__/access-validators.test.ts
  • server/src/__tests__/activity-routes.test.ts
  • server/src/__tests__/activity-service.test.ts
  • server/src/__tests__/adapter-registry.test.ts
  • server/src/__tests__/adapter-routes-authz.test.ts
  • server/src/__tests__/adapter-routes.test.ts
  • server/src/__tests__/agent-adapter-validation-routes.test.ts
  • server/src/__tests__/agent-cross-tenant-authz-routes.test.ts
  • server/src/__tests__/agent-live-run-routes.test.ts
  • server/src/__tests__/agent-permissions-routes.test.ts
  • server/src/__tests__/agent-skills-routes.test.ts
  • server/src/__tests__/app-private-hostname-gate.test.ts
  • server/src/__tests__/app-vite-dev-routing.test.ts
  • server/src/__tests__/approval-routes-idempotency.test.ts
  • server/src/__tests__/assets.test.ts
  • server/src/__tests__/auth-routes.test.ts
  • server/src/__tests__/auth-session-route.test.ts
  • server/src/__tests__/authz-company-access.test.ts
  • server/src/__tests__/better-auth.test.ts
  • server/src/__tests__/claude-local-adapter.test.ts
  • server/src/__tests__/claude-local-execute.test.ts
  • server/src/__tests__/cli-auth-routes.test.ts
  • server/src/__tests__/codex-local-adapter.test.ts
  • server/src/__tests__/codex-local-execute.test.ts
  • server/src/__tests__/codex-local-skill-injection.test.ts
  • server/src/__tests__/company-portability-routes.test.ts
  • server/src/__tests__/company-portability.test.ts
  • server/src/__tests__/company-skills-routes.test.ts
  • server/src/__tests__/company-skills-service.test.ts
  • server/src/__tests__/company-skills.test.ts
  • server/src/__tests__/company-user-directory-route.test.ts
  • server/src/__tests__/costs-service.test.ts
  • server/src/__tests__/cursor-local-adapter.test.ts
  • server/src/__tests__/cursor-local-execute.test.ts
  • server/src/__tests__/cursor-local-skill-injection.test.ts
  • server/src/__tests__/dashboard-service.test.ts
  • server/src/__tests__/dev-runner-paths.test.ts
  • server/src/__tests__/documents-service.test.ts
  • server/src/__tests__/execution-workspaces-routes.test.ts
  • server/src/__tests__/execution-workspaces-service.test.ts
  • server/src/__tests__/feedback-service.test.ts
  • server/src/__tests__/gemini-local-adapter.test.ts
  • server/src/__tests__/gemini-local-execute.test.ts
  • server/src/__tests__/health-dev-server-token.test.ts
  • server/src/__tests__/health.test.ts
  • server/src/__tests__/heartbeat-comment-wake-batching.test.ts
  • server/src/__tests__/heartbeat-context-summary.test.ts
  • server/src/__tests__/heartbeat-dependency-scheduling.test.ts
  • server/src/__tests__/heartbeat-issue-liveness-escalation.test.ts
  • server/src/__tests__/heartbeat-list.test.ts
  • server/src/__tests__/heartbeat-process-recovery.test.ts
  • server/src/__tests__/heartbeat-retry-scheduling.test.ts
  • server/src/__tests__/heartbeat-run-summary.test.ts
  • server/src/__tests__/heartbeat-workspace-session.test.ts
  • server/src/__tests__/http-log-policy.test.ts
  • server/src/__tests__/instance-database-backups-routes.test.ts
  • server/src/__tests__/instance-settings-routes.test.ts
  • server/src/__tests__/invite-accept-existing-member.test.ts
  • server/src/__tests__/invite-create-route.test.ts
  • server/src/__tests__/invite-expiry.test.ts
  • server/src/__tests__/invite-join-grants.test.ts
  • server/src/__tests__/invite-list-route.test.ts
  • server/src/__tests__/invite-logo-route.test.ts
  • server/src/__tests__/invite-onboarding-text.test.ts
  • server/src/__tests__/invite-summary-route.test.ts
  • server/src/__tests__/invite-test-resolution-route.test.ts
  • server/src/__tests__/issue-activity-events-routes.test.ts
  • server/src/__tests__/issue-agent-mutation-ownership-routes.test.ts
  • server/src/__tests__/issue-attachment-routes.test.ts

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@qodo-code-review

Copy link
Copy Markdown

Review Summary by Qodo

Comprehensive issue thread interactions, dependency management, and plugin services expansion with security and performance enhancements

✨ Enhancement 🧪 Tests

Grey Divider

Walkthroughs

Description
• **Issue thread interactions system**: New service module for managing issue thread interactions
  (suggest_tasks, ask_user_questions, request_confirmation) with full lifecycle management, CRUD
  operations, and state transitions with idempotency support
• **Issue dependency management**: Added issue dependency readiness tracking to prevent transitions
  to in_progress when blockers are unresolved; implemented child issue creation with acceptance
  criteria and optional parent blocking
• **Company member management**: Added comprehensive company member management endpoints with
  role-based access control, permission grants, and invite resolution with DNS lookup and IP address
  validation to prevent SSRF attacks
• **Issue references tracking**: Implemented issue reference tracking and syncing across documents,
  comments, and issue updates with activity logging
• **Plugin host services expansion**: Extended plugin database namespace access and issue operations
  with relations management, subtree retrieval, orchestration summaries, and wakeup request methods
  with budget validation
• **Database backup engine**: Added pg_dump and psql CLI-based backup/restore engine as
  alternative to JavaScript implementation for improved performance with automatic engine selection
  and fallback support
• **Execution quarantine controls**: Added preserveLiveWork option to worktree commands to
  optionally skip execution quarantine with metrics tracking
• **Test infrastructure**: Enhanced test setup for issue attachment routes, added comprehensive
  Storybook fixture data, expanded heartbeat recovery tests with new failure scenarios
• **Invite system enhancements**: Extended invite system with company branding (logos, brand
  colors), human role support, and increased TTL from 10 minutes to 72 hours
• **Query optimization**: Optimized database queries with chunking to handle large issue lists
  efficiently; added issue description truncation and base64 encoding for preview display
• **Authorization enhancements**: Enhanced agent mutation authorization with checkout management
  override support and reporting-chain hierarchy checks
• **Storybook configuration**: Created Tailwind CSS entry point for Storybook styling
• **Code quality**: Minor formatting and style consistency improvements
Diagram
flowchart LR
  A["Issue Thread<br/>Interactions"] -->|"state transitions"| B["Issue Service"]
  B -->|"dependency tracking"| C["Blocker<br/>Management"]
  D["Company Access<br/>Control"] -->|"invite resolution"| E["Member<br/>Management"]
  F["Plugin Host<br/>Services"] -->|"database access"| G["Plugin Database<br/>Namespace"]
  F -->|"issue operations"| B
  H["Database<br/>Backup Engine"] -->|"pg_dump CLI"| I["Performance<br/>Optimization"]
  J["Worktree<br/>Commands"] -->|"execution quarantine"| K["Agent<br/>Lifecycle"]
Loading

Grey Divider

File Changes

1. server/src/routes/access.ts ✨ Enhancement +1639/-186

Company member management and invite resolution security enhancements

• Added comprehensive company member management endpoints with role-based access control and
 permission grants
• Implemented invite resolution with DNS lookup and IP address validation to prevent SSRF attacks
• Extended invite system with company branding (logos, brand colors) and human role support
• Added helper functions for loading company members, invites, join requests with user profiles and
 permission data
• Increased company invite TTL from 10 minutes to 72 hours

server/src/routes/access.ts


2. server/src/services/issues.ts ✨ Enhancement +536/-218

Issue dependency management and query optimization improvements

• Added issue dependency readiness tracking to prevent transitions to in_progress when blockers are
 unresolved
• Implemented child issue creation with acceptance criteria and optional parent blocking
• Optimized database queries with chunking to handle large issue lists efficiently
• Added issue description truncation and base64 encoding for preview display
• Extracted helper functions for comment stats, read stats, and activity stats with chunked queries

server/src/services/issues.ts


3. server/src/__tests__/issue-attachment-routes.test.ts 🧪 Tests +38/-9

Test infrastructure improvements for issue attachment routes

• Added mocks for issueService and logActivity in route mock registration
• Added comprehensive mock for issueReferenceService with required methods
• Updated test setup to use vi.importActual for proper module imports
• Enhanced beforeEach cleanup to unmock all relevant modules before resetting

server/src/tests/issue-attachment-routes.test.ts


View more (110)
4. server/src/routes/issues.ts ✨ Enhancement +848/-136

Issue interactions, references, and authorization enhancements

• Added support for issue thread interactions (create, accept, reject, respond endpoints) with
 continuation policy handling and wakeup queueing
• Implemented issue reference tracking and syncing across documents, comments, and issue updates
 with activity logging
• Enhanced agent mutation authorization with checkout management override support and
 reporting-chain hierarchy checks
• Added child issue creation endpoint and improved issue list pagination with configurable limits
• Refactored implicit reopen logic to handle blocked status and unresolved blockers; added
 continuation summary document support

server/src/routes/issues.ts


5. ui/storybook/fixtures/taskcoreData.ts 🧪 Tests +1301/-0

Storybook fixture data for UI component testing

• Created comprehensive fixture data file with mock companies, agents, projects, issues, and
 execution workspaces for Storybook testing
• Defined fixture factories and helper functions for creating realistic test data with relationships
 and nested structures
• Included activity events, approvals, budget summaries, and dashboard data for complete UI state
 coverage
• Added entity name and title maps for activity logging and display purposes

ui/storybook/fixtures/taskcoreData.ts


6. packages/db/src/backup-lib.ts ✨ Enhancement +244/-57

Database backup engine with pg_dump CLI support

• Added pg_dump and psql CLI-based backup/restore engine as alternative to JavaScript
 implementation for improved performance
• Implemented automatic engine selection based on backup transforms; added fallback to JavaScript
 engine if CLI tools fail
• Refactored file writing to use fs/promises API with proper async/await handling and drain
 support
• Added COPY protocol support for efficient data streaming when no column nullification is needed
• Introduced cursor-based row iteration to handle large datasets with configurable batch sizes

packages/db/src/backup-lib.ts


7. ui/storybook/.storybook/tailwind-entry.css ⚙️ Configuration changes +2/-0

Storybook Tailwind CSS configuration

• Created new Tailwind CSS entry point that imports the main UI stylesheet and configures source
 paths for Storybook

ui/storybook/.storybook/tailwind-entry.css


8. server/src/services/issue-thread-interactions.ts ✨ Enhancement +1152/-0

New issue thread interactions service with full lifecycle management

• New service module for managing issue thread interactions (suggest_tasks, ask_user_questions,
 request_confirmation)
• Implements CRUD operations and state transitions for interactions with idempotency support
• Handles interaction resolution with task creation, question answering, and confirmation
 acceptance/rejection
• Includes validation for task hierarchies, question answers, and document target freshness

server/src/services/issue-thread-interactions.ts


9. server/src/services/plugin-host-services.ts ✨ Enhancement +753/-11

Expanded plugin host services with database access and issue orchestration

• Added plugin database namespace access via db.namespace(), db.query(), and db.execute()
 methods
• Extended issue operations with relations management (setBlockedBy, addBlockers, removeBlockers),
 subtree retrieval, and orchestration summaries
• Added issue wakeup request methods with budget validation and activity logging
• Implemented comprehensive activity logging for all plugin-initiated operations with actor context
• Added cost and budget incident tracking for issue orchestration visibility

server/src/services/plugin-host-services.ts


10. server/src/__tests__/heartbeat-process-recovery.test.ts 🧪 Tests +615/-20

Enhanced heartbeat recovery tests with new failure scenarios and cleanup

• Added helper functions for waiting on async values and managing test cleanup
 (cancelActiveRunsForCleanup, waitForHeartbeatIdle)
• Expanded test fixtures to include queued issue runs and orphan blocker scenarios
• Added tests for codex transient upstream failures with scheduled retry behavior
• Added tests for plan-only recovery classification and document progress detection
• Added test for orphan blocker reassignment to creator agents with wakeup requests
• Enhanced cleanup logic to handle document revisions, issue documents, and issue relations

server/src/tests/heartbeat-process-recovery.test.ts


11. cli/src/commands/worktree.ts ✨ Enhancement +196/-8

Added execution quarantine controls for seeded worktree instances

• Added preserveLiveWork option to worktree init, reseed, and repair commands to optionally skip
 execution quarantine
• Implemented quarantineSeededWorktreeExecutionState() function to disable agent timers and
 unassign agent-owned issues
• Added SeededWorktreeExecutionQuarantineSummary type tracking quarantine metrics (disabled
 timers, reset agents, quarantined issues)
• Updated seed workflow to report execution quarantine summary and paused scheduled routines count
• Added helper function to format quarantine summary for user output

cli/src/commands/worktree.ts


12. cli/src/commands/routines.ts Formatting +2/-2

Code formatting and style consistency improvements

• Minor formatting fix: changed empty function body from { } to {}
• Adjusted line continuation formatting for consistency

cli/src/commands/routines.ts


13. .agents/skills/company-creator/SKILL.md Additional files +8/-0

...

.agents/skills/company-creator/SKILL.md


14. .agents/skills/company-creator/references/example-company.md Additional files +7/-0

...

.agents/skills/company-creator/references/example-company.md


15. .agents/skills/create-agent-adapter/SKILL.md Additional files +48/-48

...

.agents/skills/create-agent-adapter/SKILL.md


16. .agents/skills/deal-with-security-advisory/SKILL.md Additional files +16/-16

...

.agents/skills/deal-with-security-advisory/SKILL.md


17. .agents/skills/doc-maintenance/SKILL.md Additional files +1/-1

...

.agents/skills/doc-maintenance/SKILL.md


18. .agents/skills/doc-maintenance/references/audit-checklist.md Additional files +4/-4

...

.agents/skills/doc-maintenance/references/audit-checklist.md


19. .agents/skills/release-changelog/SKILL.md Additional files +4/-4

...

.agents/skills/release-changelog/SKILL.md


20. .agents/skills/release/SKILL.md Additional files +9/-9

...

.agents/skills/release/SKILL.md


21. .claude/skills/taskcore Additional files +0/-0

...

.claude/skills/taskcore


22. .env.example Additional files +3/-0

...

.env.example


23. .github/PULL_REQUEST_TEMPLATE.md Additional files +3/-0

...

.github/PULL_REQUEST_TEMPLATE.md


24. .github/workflows/release-smoke.yml Additional files +2/-2

...

.github/workflows/release-smoke.yml


25. CONTRIBUTING.md Additional files +15/-0

...

CONTRIBUTING.md


26. Dockerfile Additional files +4/-9

...

Dockerfile


27. README.md Additional files +7/-5

...

README.md


28. ROADMAP.md Additional files +97/-0

...

ROADMAP.md


29. adapter-plugin.md Additional files +143/-143

...

adapter-plugin.md


30. cli/README.md Additional files +9/-5

...

cli/README.md


31. cli/package.json Additional files +1/-1

...

cli/package.json


32. cli/src/__tests__/company-import-export-e2e.test.ts Additional files +6/-1

...

cli/src/tests/company-import-export-e2e.test.ts


33. cli/src/__tests__/worktree.test.ts Additional files +231/-2

...

cli/src/tests/worktree.test.ts


34. cli/src/commands/client/auth.ts Additional files +2/-2

...

cli/src/commands/client/auth.ts


35. cli/src/commands/client/common.ts Additional files +14/-14

...

cli/src/commands/client/common.ts


36. cli/src/commands/client/company.ts Additional files +13/-13

...

cli/src/commands/client/company.ts


37. cli/src/commands/client/issue.ts Additional files +11/-11

...

cli/src/commands/client/issue.ts


38. cli/src/commands/client/plugin.ts Additional files +7/-7

...

cli/src/commands/client/plugin.ts


39. cli/src/commands/heartbeat-run.ts Additional files +10/-10

...

cli/src/commands/heartbeat-run.ts


40. cli/src/commands/run.ts Additional files +3/-3

...

cli/src/commands/run.ts


41. cli/src/commands/worktree-merge-history-lib.ts Additional files +4/-4

...

cli/src/commands/worktree-merge-history-lib.ts


42. doc/DATABASE.md Additional files +22/-0

...

doc/DATABASE.md


43. doc/DEPLOYMENT-MODES.md Additional files +1/-0

...

doc/DEPLOYMENT-MODES.md


44. doc/DEVELOPING.md Additional files +15/-0

...

doc/DEVELOPING.md


45. doc/DOCKER.md Additional files +2/-2

...

doc/DOCKER.md


46. doc/PUBLISHING.md Additional files +0/-32

...

doc/PUBLISHING.md


47. doc/RELEASE-AUTOMATION-SETUP.md Additional files +1/-1

...

doc/RELEASE-AUTOMATION-SETUP.md


48. doc/RELEASING.md Additional files +4/-4

...

doc/RELEASING.md


49. doc/SPEC-implementation.md Additional files +1/-1

...

doc/SPEC-implementation.md


50. doc/execution-semantics.md Additional files +2/-0

...

doc/execution-semantics.md


51. doc/plans/2026-03-17-docker-release-browser-e2e.md Additional files +5/-5

...

doc/plans/2026-03-17-docker-release-browser-e2e.md


52. doc/plans/2026-04-18-taskcore-hardening.md Additional files +0/-71

...

doc/plans/2026-04-18-taskcore-hardening.md


53. doc/plugins/PLUGIN_AUTHORING_GUIDE.md Additional files +55/-1

...

doc/plugins/PLUGIN_AUTHORING_GUIDE.md


54. doc/plugins/PLUGIN_SPEC.md Additional files +62/-1

...

doc/plugins/PLUGIN_SPEC.md


55. doc/spec/agents-runtime.md Additional files +2/-2

...

doc/spec/agents-runtime.md


56. doc/spec/invite-flow.md Additional files +299/-0

...

doc/spec/invite-flow.md


57. docker/Dockerfile.onboard-smoke Additional files +3/-3

...

docker/Dockerfile.onboard-smoke


58. docs/adapters/creating-an-adapter.md Additional files +37/-0

...

docs/adapters/creating-an-adapter.md


59. docs/agents-runtime.md Additional files +2/-2

...

docs/agents-runtime.md


60. docs/api/issues.md Additional files +61/-2

...

docs/api/issues.md


61. docs/deploy/environment-variables.md Additional files +2/-1

...

docs/deploy/environment-variables.md


62. docs/docs.json Additional files +5/-3

...

docs/docs.json


63. docs/guides/agent-developer/comments-and-communication.md Additional files +12/-0

...

docs/guides/agent-developer/comments-and-communication.md


64. docs/guides/agent-developer/handling-approvals.md Additional files +20/-0

...

docs/guides/agent-developer/handling-approvals.md


65. docs/guides/agent-developer/heartbeat-protocol.md Additional files +22/-1

...

docs/guides/agent-developer/heartbeat-protocol.md


66. docs/guides/agent-developer/task-workflow.md Additional files +47/-0

...

docs/guides/agent-developer/task-workflow.md


67. docs/start/what-is-taskcore.md Additional files +0/-0

...

docs/start/what-is-taskcore.md


68. eslint.config.mjs Additional files +0/-37

...

eslint.config.mjs


69. evals/promptfoo/prompts/heartbeat-system.txt Additional files +7/-0

...

evals/promptfoo/prompts/heartbeat-system.txt


70. package.json Additional files +6/-9

...

package.json


71. packages/adapter-utils/CHANGELOG.md Additional files +2/-2

...

packages/adapter-utils/CHANGELOG.md


72. packages/adapter-utils/package.json Additional files +1/-1

...

packages/adapter-utils/package.json


73. packages/adapter-utils/src/server-utils.test.ts Additional files +320/-1

...

packages/adapter-utils/src/server-utils.test.ts


74. packages/adapter-utils/src/server-utils.ts Additional files +344/-46

...

packages/adapter-utils/src/server-utils.ts


75. packages/adapter-utils/src/types.ts Additional files +30/-1

...

packages/adapter-utils/src/types.ts


76. packages/adapters/claude-local/CHANGELOG.md Additional files +3/-3

...

packages/adapters/claude-local/CHANGELOG.md


77. packages/adapters/claude-local/package.json Additional files +1/-1

...

packages/adapters/claude-local/package.json


78. packages/adapters/claude-local/src/index.ts Additional files +1/-0

...

packages/adapters/claude-local/src/index.ts


79. packages/adapters/claude-local/src/server/execute.ts Additional files +19/-10

...

packages/adapters/claude-local/src/server/execute.ts


80. packages/adapters/claude-local/src/server/prompt-cache.ts Additional files +1/-1

...

packages/adapters/claude-local/src/server/prompt-cache.ts


81. packages/adapters/claude-local/src/server/quota.ts Additional files +5/-3

...

packages/adapters/claude-local/src/server/quota.ts


82. packages/adapters/claude-local/src/server/test.ts Additional files +5/-5

...

packages/adapters/claude-local/src/server/test.ts


83. packages/adapters/codex-local/CHANGELOG.md Additional files +3/-3

...

packages/adapters/codex-local/CHANGELOG.md


84. packages/adapters/codex-local/package.json Additional files +1/-1

...

packages/adapters/codex-local/package.json


85. packages/adapters/codex-local/src/server/execute.ts Additional files +128/-19

...

packages/adapters/codex-local/src/server/execute.ts


86. packages/adapters/codex-local/src/server/index.ts Additional files +1/-1

...

packages/adapters/codex-local/src/server/index.ts


87. packages/adapters/codex-local/src/server/parse.test.ts Additional files +38/-1

...

packages/adapters/codex-local/src/server/parse.test.ts


88. packages/adapters/codex-local/src/server/parse.ts Additional files +26/-0

...

packages/adapters/codex-local/src/server/parse.ts


89. packages/adapters/codex-local/src/server/quota-spawn-error.test.ts Additional files +2/-2

...

packages/adapters/codex-local/src/server/quota-spawn-error.test.ts


90. packages/adapters/codex-local/src/server/quota.ts Additional files +4/-4

...

packages/adapters/codex-local/src/server/quota.ts


91. packages/adapters/codex-local/src/server/test.ts Additional files +3/-3

...

packages/adapters/codex-local/src/server/test.ts


92. packages/adapters/cursor-local/CHANGELOG.md Additional files +3/-3

...

packages/adapters/cursor-local/CHANGELOG.md


93. packages/adapters/cursor-local/package.json Additional files +1/-1

...

packages/adapters/cursor-local/package.json


94. packages/adapters/cursor-local/src/server/execute.ts Additional files +16/-15

...

packages/adapters/cursor-local/src/server/execute.ts


95. packages/adapters/cursor-local/src/server/skills.ts Additional files +1/-1

...

packages/adapters/cursor-local/src/server/skills.ts


96. packages/adapters/cursor-local/src/server/test.ts Additional files +3/-3

...

packages/adapters/cursor-local/src/server/test.ts


97. packages/adapters/gemini-local/package.json Additional files +1/-1

...

packages/adapters/gemini-local/package.json


98. packages/adapters/gemini-local/src/server/execute.ts Additional files +2/-1

...

packages/adapters/gemini-local/src/server/execute.ts


99. packages/adapters/gemini-local/src/server/skills.ts Additional files +1/-1

...

packages/adapters/gemini-local/src/server/skills.ts


100. packages/adapters/openclaw-gateway/CHANGELOG.md Additional files +3/-3

...

packages/adapters/openclaw-gateway/CHANGELOG.md


101. packages/adapters/openclaw-gateway/package.json Additional files +1/-1

...

packages/adapters/openclaw-gateway/package.json


102. packages/adapters/openclaw-gateway/src/server/execute.ts Additional files +23/-19

...

packages/adapters/openclaw-gateway/src/server/execute.ts


103. packages/adapters/openclaw-gateway/src/server/test.ts Additional files +4/-4

...

packages/adapters/openclaw-gateway/src/server/test.ts


104. packages/adapters/opencode-local/CHANGELOG.md Additional files +3/-3

...

packages/adapters/opencode-local/CHANGELOG.md


105. packages/adapters/opencode-local/package.json Additional files +1/-1

...

packages/adapters/opencode-local/package.json


106. packages/adapters/opencode-local/src/server/execute.ts Additional files +10/-9

...

packages/adapters/opencode-local/src/server/execute.ts


107. packages/adapters/opencode-local/src/server/models.ts Additional files +2/-2

...

packages/adapters/opencode-local/src/server/models.ts


108. packages/adapters/opencode-local/src/server/runtime-config.ts Additional files +1/-1

...

packages/adapters/opencode-local/src/server/runtime-config.ts


109. packages/adapters/opencode-local/src/server/skills.ts Additional files +1/-1

...

packages/adapters/opencode-local/src/server/skills.ts


110. packages/adapters/opencode-local/src/server/test.ts Additional files +3/-3

...

packages/adapters/opencode-local/src/server/test.ts


111. packages/adapters/pi-local/CHANGELOG.md Additional files +3/-3

...

packages/adapters/pi-local/CHANGELOG.md


112. packages/adapters/pi-local/package.json Additional files +1/-1

...

packages/adapters/pi-local/package.json


113. Additional files not shown Additional files +0/-0

...

Additional files not shown


Grey Divider

Qodo Logo

@qodo-code-review

qodo-code-review Bot commented Apr 22, 2026

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (3) 📘 Rule violations (3) 📎 Requirement gaps (0)

Grey Divider


Action required

1. AgentConfigForm hardcodes hermes_local 📘 Rule violation ⛨ Security
Description
The UI adds Hermes-specific configuration handling (hermesCommand) keyed off the hermes_local
adapter type, coupling core UI behavior to Hermes rather than relying on the external plugin
contract. This violates the requirement that Hermes be integrated only via the plugin system with no
Hermes-specific logic in core UI/server.
Code

ui/src/components/AgentConfigForm.tsx[R351-363]

+    const next = { ...base, ...overlay.adapterConfig };
+    if (adapterType === "hermes_local") {
+      const hermesCommand =
+        typeof next.hermesCommand === "string" && next.hermesCommand.length > 0
+          ? next.hermesCommand
+          : typeof next.command === "string" && next.command.length > 0
+            ? next.command
+            : undefined;
+      if (hermesCommand) {
+        next.hermesCommand = hermesCommand;
+      }
+    }
+    return next;
Evidence
Compliance ID 10 requires Hermes be external-plugin-only with no Hermes-specific integration in core
UI/server. The changed code introduces explicit adapterType === "hermes_local" branching and
maintains a Hermes-only config field (hermesCommand) in the core UI form logic.

AGENTS.md
ui/src/components/AgentConfigForm.tsx[351-363]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
Core UI special-cases the Hermes adapter via `adapterType === "hermes_local"` and manages a Hermes-only config field (`hermesCommand`). Hermes must be external-plugin-only and not require Hermes-specific logic in core UI.

## Issue Context
The compliance requirement forbids Hermes-specific integration in core UI/server; Hermes should be handled through the generic adapter/plugin contract (plugin-provided schema/config + ui-parser).

## Fix Focus Areas
- ui/src/components/AgentConfigForm.tsx[351-363]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


2. hermesLocalUIAdapter uses Hermes builder 📘 Rule violation ⚙ Maintainability
Description
The core UI adapter registration for hermes_local uses buildHermesConfig, embedding
Hermes-specific behavior in core UI instead of using the generic schema-based adapter configuration
flow. This breaks the external-plugin-only Hermes requirement.
Code

ui/src/adapters/hermes-local/index.ts[11]

+  buildAdapterConfig: buildHermesConfig,
Evidence
Compliance ID 10 requires Hermes integration via the plugin system rather than core UI/server code.
The change explicitly wires hermes_local to a Hermes-specific config builder (buildHermesConfig)
in core UI adapter code.

AGENTS.md
ui/src/adapters/hermes-local/index.ts[11-11]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`ui/src/adapters/hermes-local/index.ts` now uses `buildHermesConfig` for `hermes_local`, which is Hermes-specific logic inside core UI.

## Issue Context
Hermes must be integrated only as an external plugin; core UI should not contain Hermes-specific adapter logic and should rely on the generic schema config fields / plugin-provided config+parser.

## Fix Focus Areas
- ui/src/adapters/hermes-local/index.ts[11-11]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


3. Restore fallback breaks COPY 🐞 Bug ≡ Correctness
Description
runDatabaseBackup can emit COPY ... FROM stdin blocks, but if psql restore fails, runDatabaseRestore
falls back to replaying “statements” via sql.unsafe(), which cannot execute COPY data blocks or the
\\. terminator. This can make restores fail (and/or obscure the original psql error) in environments
where psql is missing or errors.
Code

packages/db/src/backup-lib.ts[R951-966]

export async function runDatabaseRestore(opts: RunDatabaseRestoreOptions): Promise<void> {
  const connectTimeout = Math.max(1, Math.trunc(opts.connectTimeoutSeconds ?? 5));
+  try {
+    await restoreWithPsql(opts, connectTimeout);
+    return;
+  } catch (error) {
+    if (!(await hasStatementBreakpoints(opts.backupFile))) {
+      throw new Error(
+        `Failed to restore ${basename(opts.backupFile)} with psql: ${sanitizeRestoreErrorMessage(error)}`,
+      );
+    }
+  }
+
  const sql = postgres(opts.connectionString, { max: 1, connect_timeout: connectTimeout });

  try {
Evidence
The backup writer emits psql-only COPY blocks (including the \\. terminator) when backupEngine is
not "javascript" and no nullify transforms are needed; however the restore fallback executes each
breakpoint-delimited block as a single SQL statement via postgres, which cannot handle COPY
meta/protocol blocks.

packages/db/src/backup-lib.ts[846-883]
packages/db/src/backup-lib.ts[951-971]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
`runDatabaseRestore()` always tries `psql` first, then falls back to executing breakpoint-delimited chunks via `postgres().unsafe()`. Backups generated in `runDatabaseBackup()` may contain `COPY ... FROM stdin` blocks and `\\.` terminators, which cannot be executed through the `postgres` client as plain SQL.

### Issue Context
- COPY blocks are emitted by default when `backupEngine !== "javascript"` and no per-column nullification is needed.
- The fallback path is triggered whenever `psql` errors (missing binary, auth failures, etc.), and will then attempt to execute COPY blocks as a single SQL statement.

### Fix Focus Areas
- packages/db/src/backup-lib.ts[846-883]
- packages/db/src/backup-lib.ts[951-971]

### What to change
- Add a cheap scan (stream) to detect whether the backup file contains COPY blocks / `\\.` meta-terminators.
- If COPY blocks are present and `psql` restore fails, throw a clear error (e.g., "psql restore failed; COPY-based backups require psql") and **do not** attempt the JS `postgres` fallback.
- Alternatively: only use the JS fallback when you can prove the backup is “SQL-only” (no COPY blocks).

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


View more (1)
4. DB creds exposed in argv 🐞 Bug ⛨ Security
Description
The new pg_dump/psql paths pass the full DB connection string via --dbname=..., which can include
passwords. That leaks credentials to other local users via process listings while pg_dump/psql runs.
Code

packages/db/src/backup-lib.ts[R278-339]

+  const pgDumpBin = process.env.TASKCORE_PG_DUMP_PATH || "pg_dump";
+  const child = spawn(
+    pgDumpBin,
+    [
+      `--dbname=${opts.connectionString}`,
+      "--format=plain",
+      "--clean",
+      "--if-exists",
+      "--no-owner",
+      "--no-privileges",
+      "--schema=public",
+    ],
+    {
+      stdio: ["ignore", "pipe", "pipe"],
+      env: {
+        ...process.env,
+        PGCONNECT_TIMEOUT: String(opts.connectTimeout),
+      },
+    },
+  );
+
+  if (!child.stdout) {
+    throw new Error("pg_dump did not expose stdout");
+  }
+
+  await Promise.all([
+    pipeline(child.stdout, createGzip(), createWriteStream(opts.backupFile)),
+    waitForChildExit(child, pgDumpBin),
+  ]);
+}
+
+async function restoreWithPsql(opts: RunDatabaseRestoreOptions, connectTimeout: number): Promise<void> {
+  const psqlBin = process.env.TASKCORE_PSQL_PATH || "psql";
+  const child = spawn(
+    psqlBin,
+    [
+      `--dbname=${opts.connectionString}`,
+      "--set=ON_ERROR_STOP=1",
+      "--quiet",
+      "--no-psqlrc",
+    ],
+    {
+      stdio: ["pipe", "ignore", "pipe"],
+      env: {
+        ...process.env,
+        PGCONNECT_TIMEOUT: String(connectTimeout),
+      },
+    },
+  );
+
+  if (!child.stdin) {
+    throw new Error("psql did not expose stdin");
+  }
+
+  const input = opts.backupFile.endsWith(".gz")
+    ? createReadStream(opts.backupFile).pipe(createGunzip())
+    : createReadStream(opts.backupFile);
+
+  await Promise.all([
+    pipeline(input, child.stdin),
+    waitForChildExit(child, psqlBin),
+  ]);
Evidence
Both pg_dump and psql are spawned with --dbname=${connectionString}. Server startup constructs
connection strings containing user:password (e.g., embedded postgres) and passes them to
runDatabaseBackup, so secrets commonly appear in argv.

packages/db/src/backup-lib.ts[273-340]
server/src/index.ts[421-439]
server/src/index.ts[557-562]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
`runPgDumpBackup()` and `restoreWithPsql()` pass `opts.connectionString` as a command-line argument (`--dbname=...`). When the connection string contains credentials, they become visible in OS process listings.

### Issue Context
This code is used by server-triggered backups (`runDatabaseBackup({ connectionString: activeDatabaseConnectionString, ... })`), and embedded postgres URLs include `user:password@...`.

### Fix Focus Areas
- packages/db/src/backup-lib.ts[273-340]
- server/src/index.ts[421-439]
- server/src/index.ts[557-562]

### What to change
- Parse the connection string and pass connection parameters without embedding the password in argv:
 - Prefer `--host`, `--port`, `--username`, `--dbname` and provide the password via `PGPASSWORD` env var, or
 - Create a temporary `.pgpass` file with `0600` perms and set `PGPASSFILE`.
- Ensure any logs/errors do not echo the full URL with password.
- Apply the same approach to both `pg_dump` and `psql` spawn paths.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Remediation recommended

5. Heartbeat hardcodes hermes_local sessioning 📘 Rule violation ⚙ Maintainability
Description
The server heartbeat service adds hermes_local to a hardcoded SESSIONED_LOCAL_ADAPTERS
allowlist, introducing Hermes-specific coupling in core server logic. This weakens the
external-plugin-only Hermes constraint and should be derived from adapter capabilities/metadata
instead.
Code

server/src/services/heartbeat.ts[R164-172]

const SESSIONED_LOCAL_ADAPTERS = new Set([
  "claude_local",
  "codex_local",
  "cursor",
  "gemini_local",
+  "hermes_local",
  "opencode_local",
  "pi_local",
]);
Evidence
Compliance ID 10 requires Hermes to be external-plugin-only without Hermes-specific behavior
embedded in core server/UI. The changed server code explicitly enumerates hermes_local in a core
allowlist, indicating special-casing of Hermes adapter semantics in the control plane.

AGENTS.md
server/src/services/heartbeat.ts[164-172]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
Core server heartbeat logic hardcodes `hermes_local` in `SESSIONED_LOCAL_ADAPTERS`, creating Hermes-specific coupling.

## Issue Context
Hermes should be treated like any external adapter; core logic should infer requirements (like sessioning) from adapter capabilities/metadata returned by the adapter registry/plugin system rather than adapter-type string allowlists.

## Fix Focus Areas
- server/src/services/heartbeat.ts[164-172]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


6. Migrations may hit wrong DB 🐞 Bug ☼ Reliability
Description
When DATABASE_MIGRATION_URL is set, startServer applies migrations to that URL but creates the
runtime DB connection using DATABASE_URL. If these URLs differ, the server can start against an
unmigrated/stale schema and fail at runtime.
Code

server/src/index.ts[R270-276]

  if (config.databaseUrl) {
-    migrationSummary = await ensureMigrations(config.databaseUrl, "PostgreSQL");
-
+    const migrationUrl = config.databaseMigrationUrl ?? config.databaseUrl;
+    migrationSummary = await ensureMigrations(migrationUrl, "PostgreSQL");
+  
    db = createDb(config.databaseUrl);
+    pluginMigrationDb = config.databaseMigrationUrl ? createDb(config.databaseMigrationUrl) : db;
    logger.info("Using external PostgreSQL via DATABASE_URL/config");
Evidence
Config introduces databaseMigrationUrl and server startup uses it to decide where to run
ensureMigrations(), but the actual DB handle used by the app is still created from databaseUrl.
This allows a mismatch where migrations are applied to a different database than the one used at
runtime.

server/src/config.ts[288-302]
server/src/index.ts[270-276]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
`DATABASE_MIGRATION_URL` is used to run migrations, while `DATABASE_URL` is used for runtime queries. If they point to different databases, migrations won't be applied to the runtime DB.

### Issue Context
This may be intended to allow a different *user* for migrations, but it still must target the same host/port/dbname.

### Fix Focus Areas
- server/src/config.ts[288-302]
- server/src/index.ts[270-276]

### What to change
- Add validation during startup: if `databaseMigrationUrl` is set, assert it points to the same database as `databaseUrl` (compare host/port/database name via URL parsing) and throw a clear error if not.
- Optionally log a warning showing the safe, redacted comparison.
- Consider documenting the intended use (different credentials, same DB) and/or renaming the env var to make that intent explicit.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Qodo Logo

@khulnasoft-bot khulnasoft-bot merged commit 99b66ca into khulnasoft:master Apr 22, 2026
4 of 6 checks passed
Comment on lines +351 to +363
const next = { ...base, ...overlay.adapterConfig };
if (adapterType === "hermes_local") {
const hermesCommand =
typeof next.hermesCommand === "string" && next.hermesCommand.length > 0
? next.hermesCommand
: typeof next.command === "string" && next.command.length > 0
? next.command
: undefined;
if (hermesCommand) {
next.hermesCommand = hermesCommand;
}
}
return next;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Action required

1. agentconfigform hardcodes hermes_local 📘 Rule violation ⛨ Security

The UI adds Hermes-specific configuration handling (hermesCommand) keyed off the hermes_local
adapter type, coupling core UI behavior to Hermes rather than relying on the external plugin
contract. This violates the requirement that Hermes be integrated only via the plugin system with no
Hermes-specific logic in core UI/server.
Agent Prompt
## Issue description
Core UI special-cases the Hermes adapter via `adapterType === "hermes_local"` and manages a Hermes-only config field (`hermesCommand`). Hermes must be external-plugin-only and not require Hermes-specific logic in core UI.

## Issue Context
The compliance requirement forbids Hermes-specific integration in core UI/server; Hermes should be handled through the generic adapter/plugin contract (plugin-provided schema/config + ui-parser).

## Fix Focus Areas
- ui/src/components/AgentConfigForm.tsx[351-363]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


export const hermesLocalUIAdapter: UIAdapterModule = {
type: "hermes_local",
label: "Hermes Agent",
parseStdoutLine: parseHermesStdoutLine,
ConfigFields: SchemaConfigFields,
buildAdapterConfig: buildSchemaAdapterConfig,
buildAdapterConfig: buildHermesConfig,

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Action required

2. hermeslocaluiadapter uses hermes builder 📘 Rule violation ⚙ Maintainability

The core UI adapter registration for hermes_local uses buildHermesConfig, embedding
Hermes-specific behavior in core UI instead of using the generic schema-based adapter configuration
flow. This breaks the external-plugin-only Hermes requirement.
Agent Prompt
## Issue description
`ui/src/adapters/hermes-local/index.ts` now uses `buildHermesConfig` for `hermes_local`, which is Hermes-specific logic inside core UI.

## Issue Context
Hermes must be integrated only as an external plugin; core UI should not contain Hermes-specific adapter logic and should rely on the generic schema config fields / plugin-provided config+parser.

## Fix Focus Areas
- ui/src/adapters/hermes-local/index.ts[11-11]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Comment on lines 951 to 966
export async function runDatabaseRestore(opts: RunDatabaseRestoreOptions): Promise<void> {
const connectTimeout = Math.max(1, Math.trunc(opts.connectTimeoutSeconds ?? 5));
try {
await restoreWithPsql(opts, connectTimeout);
return;
} catch (error) {
if (!(await hasStatementBreakpoints(opts.backupFile))) {
throw new Error(
`Failed to restore ${basename(opts.backupFile)} with psql: ${sanitizeRestoreErrorMessage(error)}`,
);
}
}

const sql = postgres(opts.connectionString, { max: 1, connect_timeout: connectTimeout });

try {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Action required

3. Restore fallback breaks copy 🐞 Bug ≡ Correctness

runDatabaseBackup can emit COPY ... FROM stdin blocks, but if psql restore fails, runDatabaseRestore
falls back to replaying “statements” via sql.unsafe(), which cannot execute COPY data blocks or the
\\. terminator. This can make restores fail (and/or obscure the original psql error) in environments
where psql is missing or errors.
Agent Prompt
### Issue description
`runDatabaseRestore()` always tries `psql` first, then falls back to executing breakpoint-delimited chunks via `postgres().unsafe()`. Backups generated in `runDatabaseBackup()` may contain `COPY ... FROM stdin` blocks and `\\.` terminators, which cannot be executed through the `postgres` client as plain SQL.

### Issue Context
- COPY blocks are emitted by default when `backupEngine !== "javascript"` and no per-column nullification is needed.
- The fallback path is triggered whenever `psql` errors (missing binary, auth failures, etc.), and will then attempt to execute COPY blocks as a single SQL statement.

### Fix Focus Areas
- packages/db/src/backup-lib.ts[846-883]
- packages/db/src/backup-lib.ts[951-971]

### What to change
- Add a cheap scan (stream) to detect whether the backup file contains COPY blocks / `\\.` meta-terminators.
- If COPY blocks are present and `psql` restore fails, throw a clear error (e.g., "psql restore failed; COPY-based backups require psql") and **do not** attempt the JS `postgres` fallback.
- Alternatively: only use the JS fallback when you can prove the backup is “SQL-only” (no COPY blocks).

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Comment on lines +278 to +339
const pgDumpBin = process.env.TASKCORE_PG_DUMP_PATH || "pg_dump";
const child = spawn(
pgDumpBin,
[
`--dbname=${opts.connectionString}`,
"--format=plain",
"--clean",
"--if-exists",
"--no-owner",
"--no-privileges",
"--schema=public",
],
{
stdio: ["ignore", "pipe", "pipe"],
env: {
...process.env,
PGCONNECT_TIMEOUT: String(opts.connectTimeout),
},
},
);

if (!child.stdout) {
throw new Error("pg_dump did not expose stdout");
}

await Promise.all([
pipeline(child.stdout, createGzip(), createWriteStream(opts.backupFile)),
waitForChildExit(child, pgDumpBin),
]);
}

async function restoreWithPsql(opts: RunDatabaseRestoreOptions, connectTimeout: number): Promise<void> {
const psqlBin = process.env.TASKCORE_PSQL_PATH || "psql";
const child = spawn(
psqlBin,
[
`--dbname=${opts.connectionString}`,
"--set=ON_ERROR_STOP=1",
"--quiet",
"--no-psqlrc",
],
{
stdio: ["pipe", "ignore", "pipe"],
env: {
...process.env,
PGCONNECT_TIMEOUT: String(connectTimeout),
},
},
);

if (!child.stdin) {
throw new Error("psql did not expose stdin");
}

const input = opts.backupFile.endsWith(".gz")
? createReadStream(opts.backupFile).pipe(createGunzip())
: createReadStream(opts.backupFile);

await Promise.all([
pipeline(input, child.stdin),
waitForChildExit(child, psqlBin),
]);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Action required

4. Db creds exposed in argv 🐞 Bug ⛨ Security

The new pg_dump/psql paths pass the full DB connection string via --dbname=..., which can include
passwords. That leaks credentials to other local users via process listings while pg_dump/psql runs.
Agent Prompt
### Issue description
`runPgDumpBackup()` and `restoreWithPsql()` pass `opts.connectionString` as a command-line argument (`--dbname=...`). When the connection string contains credentials, they become visible in OS process listings.

### Issue Context
This code is used by server-triggered backups (`runDatabaseBackup({ connectionString: activeDatabaseConnectionString, ... })`), and embedded postgres URLs include `user:password@...`.

### Fix Focus Areas
- packages/db/src/backup-lib.ts[273-340]
- server/src/index.ts[421-439]
- server/src/index.ts[557-562]

### What to change
- Parse the connection string and pass connection parameters without embedding the password in argv:
  - Prefer `--host`, `--port`, `--username`, `--dbname` and provide the password via `PGPASSWORD` env var, or
  - Create a temporary `.pgpass` file with `0600` perms and set `PGPASSFILE`.
- Ensure any logs/errors do not echo the full URL with password.
- Apply the same approach to both `pg_dump` and `psql` spawn paths.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants