Skip to content

fix(workitems): use two-step approach for timeEstimate on create#195

Merged
polaz merged 2 commits intomainfrom
feat/#193-fix-timetrackingwidget-not-supported-on-workitemcr
Jan 25, 2026
Merged

fix(workitems): use two-step approach for timeEstimate on create#195
polaz merged 2 commits intomainfrom
feat/#193-fix-timetrackingwidget-not-supported-on-workitemcr

Conversation

@polaz
Copy link
Copy Markdown
Member

@polaz polaz commented Jan 25, 2026

Summary

  • GitLab GraphQL API does NOT support timeTrackingWidget on WorkItemCreateInput
  • Implemented two-step approach: create without timeTrackingWidget, then update with timeEstimate
  • Returns partial success with _warning if update fails, preserving the created work item

Changes

  • registry.ts: Two-step create logic with graceful degradation
  • schema.ts: Updated timeEstimate description for AI agents
  • workItems.ts: Removed timeTrackingWidget from WorkItemCreateInput interface with documentation
  • registry.test.ts: Added tests for two-step approach and partial success scenarios

Test plan

  • yarn lint - 0 errors
  • yarn test - 3935 tests passed
  • yarn build - successful

Closes #193

GitLab GraphQL API does NOT support timeTrackingWidget on WorkItemCreateInput.
This fix implements a two-step approach:
1. Create work item without timeTrackingWidget
2. Apply timeEstimate via update mutation after creation
3. Return partial success with _warning if update fails

Closes #193
Copilot AI review requested due to automatic review settings January 25, 2026 01:11
@github-actions
Copy link
Copy Markdown

github-actions bot commented Jan 25, 2026

Test Coverage Report

Overall Coverage: 93.73%

Metric Percentage
Statements 93.24%
Branches 84.96%
Functions 83.21%
Lines 93.73%

View detailed coverage report

@codecov
Copy link
Copy Markdown

codecov bot commented Jan 25, 2026

Codecov Report

❌ Patch coverage is 94.11765% with 1 line in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
src/entities/workitems/registry.ts 94.11% 0 Missing and 1 partial ⚠️

📢 Thoughts on this report? Let us know!

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR fixes a critical bug where creating work items with timeEstimate would fail due to GitLab API limitations. The GitLab GraphQL API does not support timeTrackingWidget on WorkItemCreateInput, only on updates.

Changes:

  • Implemented a two-step approach: create work item first, then apply time estimate via update
  • Added graceful degradation that returns partial success with _warning field if the update fails
  • Updated interface documentation and schema descriptions to clarify the limitation

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated no comments.

File Description
src/entities/workitems/registry.ts Implements two-step create logic with comprehensive error handling for timeEstimate
src/entities/workitems/schema.ts Updates timeEstimate description to inform AI agents about the two-step approach
src/graphql/workItems.ts Removes timeTrackingWidget from WorkItemCreateInput interface and adds documentation
tests/unit/entities/workitems/registry.test.ts Adds comprehensive tests for two-step approach and partial success scenarios

Test scenario where timeEstimate update returns no workItem
but also no errors, verifying partial success with _warning
@polaz polaz enabled auto-merge (squash) January 25, 2026 01:30
@polaz polaz merged commit 98abf4e into main Jan 25, 2026
16 checks passed
@polaz polaz deleted the feat/#193-fix-timetrackingwidget-not-supported-on-workitemcr branch January 25, 2026 01:33
sw-release-bot bot pushed a commit that referenced this pull request Jan 25, 2026
## [6.42.0](v6.41.4...v6.42.0) (2026-01-25)

### Features

* Token scope detection at startup with graceful degradation ([#190](#190)) ([28bab03](28bab03)), closes [#188](#188)

### Bug Fixes

* **workitems:** use two-step approach for timeEstimate on create ([#195](#195)) ([98abf4e](98abf4e)), closes [#193](#193)
@sw-release-bot
Copy link
Copy Markdown

🎉 This PR is included in version 6.42.0 🎉

The release is available on:

Your semantic-release bot 📦🚀

polaz pushed a commit that referenced this pull request Jan 25, 2026
## [6.42.0](v6.41.4...v6.42.0) (2026-01-25)

### Features

* Token scope detection at startup with graceful degradation ([#190](#190)) ([28bab03](28bab03)), closes [#188](#188)

### Bug Fixes

* **workitems:** use two-step approach for timeEstimate on create ([#195](#195)) ([98abf4e](98abf4e)), closes [#193](#193)
polaz added a commit that referenced this pull request Jan 25, 2026
…ck aggregation (#196)

* feat(logging): Implement condensed access log format with request stack aggregation

Implements single-line access log format inspired by nginx/envoy. Instead of
multiple log lines per request, all events are aggregated into a single
condensed entry when the request completes.

Features:
- Request stack aggregation: collect tool, action, GitLab response timing
- Single-line access log format with timestamp, client, session, method, path,
  status, duration, tool/action, GitLab status/duration, and details
- Connection tracking: log session stats (requests, tools, errors) on close
- AsyncLocalStorage for transparent context propagation through async calls
- LOG_FORMAT environment variable: "condensed" (default) or "verbose"

Access log format:
[timestamp] ip session method path status duration | tool action | gitlab_status gitlab_duration | details

Connection close format:
[timestamp] CONN_CLOSE ip session duration reason | reqs=N tools=N errs=N

Closes #194

* chore(release): 6.42.0 [skip ci]

## [6.42.0](v6.41.4...v6.42.0) (2026-01-25)

### Features

* Token scope detection at startup with graceful degradation ([#190](#190)) ([28bab03](28bab03)), closes [#188](#188)

### Bug Fixes

* **workitems:** use two-step approach for timeEstimate on create ([#195](#195)) ([98abf4e](98abf4e)), closes [#193](#193)

* fix(logging): nginx-style alignment, quote escaping, dedupe LogFormat type

- All fields always present with "-" for missing values (nginx-style alignment)
- Escape quotes and backslashes in log values for safe parsing
- Import LogFormat from logging/types.ts to avoid type duplication
- Add comments explaining close handler behavior for new sessions
- Fix flaky test assertion using regex for duration matching

* test(config): add LOG_FORMAT parsing tests

Add unit tests for LOG_FORMAT environment variable parsing:
- Default to 'condensed' when not set
- Parse 'verbose' value
- Case-insensitive parsing
- Invalid values default to 'condensed'

* feat(logging): add context and read-only mode to access logs

- Add ctx (context path) and ro (read-only) fields to access log format
- Capture session context and read-only state during tool execution
- Fix SSE close handling: distinguish normal disconnect from abort
- Fix session request counting: count initial request on session init
- Update session ID on stack after session initialization
- Escape newlines/tabs in log values to maintain single-line format
- Add needsQuoting helper to detect control characters

Access log format now:
[ts] ip session ctx ro method path status dur | tool action | GL:status dur | details

* test(logging): add addDetailsForCurrentRequest context-aware test

* fix(logging): gate per-request INFO logs behind LOG_FORMAT=verbose

In condensed mode, suppress individual "Tool called", "Connection verified",
"Executing tool" INFO logs - these are aggregated into single access log line.
Also fix ConnectionTracker.closeConnection to return early when disabled.

* fix(logging): add request tracking to SSE /messages endpoint

- Gate access log tracking in handlers.ts behind LOG_FORMAT=condensed
- Add request tracking to SSE /messages handler:
  - Call connectionTracker.incrementRequests for each request
  - Update request stack with SSE session ID (query param vs header)
  - Wrap handlePostMessage in runWithRequestContextAsync

* fix(logging): move access log middleware before rate limiter

- Register access logging before rate limiter to capture 429 responses
- Update docstring format to include ctx and ro fields
- Correct comment about session ID availability in first request

* fix(server): use optional chaining for res.locals in SSE handler

Prevents TypeError when res.locals is undefined in test mocks.

* fix(logging): cleanup connections on close even when tracking disabled

Prevents memory leak when setEnabled(false) is called while connections
are still open - connections are now always deleted from the map.

* fix(logging): add session tracking for SSE /sse endpoint

- Update request stack with SSE session ID for access log
- Count initial GET /sse request in connection stats

---------

Co-authored-by: semantic-release-bot <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

fix: timeTrackingWidget not supported on WorkItemCreateInput - GitLab API limitation

2 participants