Commit 84946f2
feat(gitlab): Phase 1 GitLab support via CI/CD Component (#93)
* feat(gitlab): add hello-world CI/CD template to validate include:remote
Adds a minimal gitlab/templates/review.yml job that prints a hello-world
message. Used to verify that a GitLab CI pipeline can pull the template
over HTTPS from raw.githubusercontent.com before we layer in the Docker
image and real review entrypoints.
Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
* feat(gitlab): scaffold src/gitlab adapter (context, token, api, types)
Pure-addition first slice of GitLab support. Mirrors the shape of
src/github/ so subsequent entrypoints can swap adapter by PLATFORM env.
- src/gitlab/context.ts parses CI_* env vars into a normalized
ParsedGitlabContext with MR + commit + user + inputs
- src/gitlab/token.ts reads GITLAB_TOKEN with OVERRIDE/CI_JOB_TOKEN
fallbacks; throws a clear error when missing
- src/gitlab/api/client.ts is a thin fetch wrapper around GitLab v4
exposing getMr/getMrChanges/listNotes/createNote/updateNote/
createDiscussionOnDiff/updateMrDescription
- src/gitlab/types.ts defines GitlabMr, GitlabNote, GitlabDiscussion,
GitlabPosition
- 16 new unit tests; full existing suite (381 -> 397) still passes
No GitHub code paths touched.
Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
* feat(gitlab): add MCP server exposing MR operations to droid exec
src/mcp/gitlab-mr-server.ts mirrors src/mcp/github-pr-server.ts in shape
so the review prompt can stay platform-agnostic at the tool layer.
Tools registered:
- get_mr / get_mr_changes / list_mr_notes
- create_mr_note / update_mr_note (sticky tracking comment lifecycle)
- update_mr_description (for @droid fill)
- submit_review: posts an optional summary note plus N inline
discussions anchored to diff positions; per-comment errors are
collected so one bad position doesn't abort the batch.
Position objects are built from the MR's diff_refs (base/head/start SHA)
and switch new_line vs old_line based on RIGHT vs LEFT side, matching
the GitHub PR review tool's contract.
5 new unit tests cover summary, inline anchoring, LEFT-side mapping,
and partial-failure batching. Full suite: 402/402.
Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
* feat(gitlab): add prepare + update-comment-link entrypoints and sticky-note logic
Implements the sticky tracking note lifecycle for GitLab MR pipelines:
prepare creates (or reuses) the running-state note before droid exec
runs; update-comment-link rewrites it with success/failure + pipeline
links after droid exec completes.
- src/gitlab/operations/tracking-note.ts builds the note body with a
hidden <!-- droid-tracking-note --> marker so retries find and update
the same note instead of creating duplicates. Renders pipeline/job
links, security badge (when automatic_security_review is on), and an
error-details <details> block on failure.
- src/entrypoints/gitlab-prepare.ts parses CI env, gates on
merge_request_event + automatic_review, writes a JSON state file
(DROID_STATE_FILE) for downstream steps.
- src/entrypoints/gitlab-update-comment-link.ts reads the state file
and PUTs the final body. Skips cleanly when no review ran.
7 new tracking-note tests; full suite 402 -> 409. Also tightened two
gitlab-mr-server tests to satisfy noUncheckedIndexedAccess.
Cross-SCM include:remote was validated end-to-end against
gitlab.com pipeline #2568334623 (passed) before this commit.
Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
* feat(gitlab): real CI/CD Component template (runtime-clone, no Docker)
Replaces the hello-world include-test template with a real droid-review
job. No Docker image dependency for v1; instead the job:
1. Uses the public oven/bun:1.2.11 image (Bun preinstalled)
2. apt-get installs git/curl/ca-certificates on top
3. Shallow-clones Factory-AI/droid-action at $DROID_ACTION_REF
4. bun install --frozen-lockfile
5. Runs src/entrypoints/gitlab-prepare.ts (creates sticky tracking note)
6. droid exec placeholder (real prompt + MCP wiring next commit)
7. after_script always runs src/entrypoints/gitlab-update-comment-link.ts
so failures still rewrite the note to the failure state
Template uses GitLab's spec.inputs so it works equally well via
`include: component:` (post-Catalog publish) and `include: remote:`
(today). Inputs: automatic_review, review_depth, review_model,
reasoning_effort, droid_action_repo, droid_action_ref, stage.
Required CI variables on the consumer side: FACTORY_API_KEY, GITLAB_TOKEN.
Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
* feat(gitlab): wire up real droid exec with MCP server + inline review
The template now installs the Droid CLI, registers the gitlab-mr MCP
server with the runtime CI env, and runs `droid exec` against a
review prompt that gitlab-prepare writes to /tmp/droid-prompts/droid-prompt.txt.
- src/gitlab/review-prompt.ts: minimal v1 review prompt builder
embedding the MR diff and instructions to call submit_review with a
single batched set of inline comments (max 8). Returns LGTM body
when no issues found.
- src/entrypoints/gitlab-prepare.ts: after creating the sticky note,
fetches MR + diff via the GitLab API and writes the prompt file;
exposes promptPath on the state JSON.
- gitlab/templates/review.yml:
* Installs Droid CLI via curl https://app.factory.ai/cli | sh
* Skips droid exec if prepare set shouldRunReview=false
* Registers MCP server: droid mcp add gitlab_mr <bun run server> --env ...
* Runs: droid exec -f $DROID_PROMPT_FILE --output-format stream-json
--skip-permissions-unsafe (plus optional --model/--reasoning-effort)
* after_script reads /tmp/droid-error.txt for failure details
- 3 new prompt-builder tests; suite at 412 passing.
Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
* fix(gitlab): wire review_depth presets via resolveReviewConfig
Previously, review_depth was a declared spec.input that was parsed and
threaded through gitlab-prepare but never consumed by the prompt
builder or the template -- so customers passing review_depth: shallow
silently still got Droid's default model.
This wires it end-to-end:
- gitlab-prepare now calls resolveReviewConfig({reviewModel,
reasoningEffort, reviewDepth}) from src/utils/review-depth.ts (which
already had the preset table: shallow -> kimi-k2-0711, deep -> gpt-5.2
+ high reasoning), reusing the same logic the GitHub flow uses.
- Explicit review_model / reasoning_effort still beat the depth preset
(resolveReviewConfig handles priority).
- Resolved values are written to /tmp/droid-prompts/resolved-env.sh as
shell exports (RESOLVED_MODEL / RESOLVED_REASONING_EFFORT), plus
echoed into the state.json for visibility.
- Template sources the shim before constructing droid exec args and
uses the RESOLVED_* values for --model / --reasoning-effort.
Adds 6 unit tests covering: default deep preset, shallow preset,
explicit model override, explicit effort override, both overrides
simultaneously, unknown depth fallback. Suite at 418 passing.
Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
* feat(gitlab): two-pass review (candidates + validator) mirroring GitHub
Replaces the v1 single-pass bespoke prompt with the same two-pass flow
the GitHub Action uses: Pass 1 generates review_candidates.json without
posting; Pass 2 validates each candidate, writes review_validated.json,
and submits approved findings in a single batched call. The /review
skill (loaded by Droid at runtime) drives both passes; the prompts
here are the runtime harness that selects which pass + which tools.
Why two droid exec calls rather than one:
1. Tool gating — Pass 1 has NO access to gitlab_mr___submit_review so
the model can't shortcut by posting raw candidates. --enabled-tools
is fixed at process start, so a single exec can't switch mid-run.
2. Fresh-eyes context — Pass 2 re-reads the diff without memory of
why each candidate was generated, dropping ~30-60% false positives.
3. Hard output checkpoint on disk between passes (resumable, debuggable).
4. Clean failure semantics — half-baked Pass 1 won't pollute Pass 2.
New files:
* src/gitlab/data/review-artifacts.ts — fetch + write mr.diff,
existing_comments.json, mr_description.txt (mirror of GitHub's
precomputed PR artifacts).
* src/gitlab/prompts/types.ts — shared prompt-context shape.
* src/gitlab/prompts/candidates.ts — Pass 1 prompt, ported from
GitHub's review-candidates-prompt.ts with MR/project terminology.
* src/gitlab/prompts/validator.ts — Pass 2 prompt, ported from
GitHub's review-validator-prompt.ts; uses gitlab_mr___submit_review
and the new gitlab_mr___update_tracking_note tool.
* src/entrypoints/gitlab-prepare-validator.ts — overwrites the prompt
file with Pass 2 between the two droid exec calls.
* test/gitlab/prompts.test.ts + test/gitlab/review-artifacts.test.ts
— 14 new tests covering the two prompts and artifact computation.
MCP additions:
* src/mcp/gitlab-mr-server.ts — new update_tracking_note tool that
reads DROID_MR_IID + DROID_TRACKING_NOTE_ID from env, symmetric
with GitHub's github_comment___update_droid_comment.
Template changes (gitlab/templates/review.yml):
* Sources resolved-env.sh once up front (now includes DROID_MR_IID
+ DROID_TRACKING_NOTE_ID).
* Registers the MCP server with those env vars exposed.
* Pass 1 droid exec: --enabled-tools excludes submit_review.
* Runs gitlab-prepare-validator between the two execs.
* Pass 2 droid exec: --enabled-tools includes gitlab_mr___submit_review
and gitlab_mr___update_tracking_note.
* Artifacts archive bumped to include review_candidates.json,
review_validated.json, droid-prompt.txt for debugging.
Removed:
* src/gitlab/review-prompt.ts (v1 single-pass bespoke prompt).
* test/gitlab/review-prompt.test.ts.
Refactoring src/gitlab/prompts/ + src/create-prompt/ into a shared
src/core/review/ tree is queued as a follow-up PR.
All 432 tests pass; tsc + prettier clean.
Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
* feat(gitlab): wire `settings` input pass-through (parity with GitHub)
Adds the same `settings` input the GitHub action exposes:
* spec.input on the CI/CD Component (JSON string OR path to JSON file).
* Plumbed via DROID_SETTINGS env var to gitlab-prepare.
* gitlab-prepare reuses base-action/src/setup-droid-settings.ts
(zero GitHub deps, fully portable) to write ~/.factory/droid/settings.json
before either droid exec call. Always sets enableAllProjectMcpServers=true
to match the GitHub flow.
* context.inputs.settings surfaces the raw value.
* 2 new context tests; 434 tests pass.
Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
* feat(gitlab): GH parity batch — custom droids, debug artifacts, telemetry, draft skip, stderr capture
- 1.6b Copy bundled .factory/droids from droid-action checkout into runner ~/.factory/droids before droid exec, mirroring the GitHub action's Setup Custom Droids step.
- 1.6c Stage debug artifacts (/tmp/droid-prompts/*, droid-error.txt) into .droid-debug/ inside CI_PROJECT_DIR in after_script so GitLab can upload them on failure (GitLab artifacts cannot reach outside CI_PROJECT_DIR).
- 1.6d Capture droid exec stream-json output to per-pass JSONL log files via tee + pipefail; parse session_id / numTurns / durationMs (+ legacy cost_usd) from the last completion event of each pass; render a <sub> summary line (44 turns • 11m 40s • $0.42) and a collapsible session-IDs block in the sticky tracking note.
- C7 Skip Draft: / WIP: MRs at the rules: level (GitLab-native equivalent of GitHub's draft == false workflow if:).
- C9 On droid exec failure, tail 60 lines of the per-pass log into /tmp/droid-error.txt so the existing error-details block in the sticky note surfaces real failure context instead of a generic message.
Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
* feat(gitlab): expose include_suggestions input (A5)
Adds the include_suggestions spec input to the GitLab review template.
Threading was already in place: gitlab-prepare reads the INCLUDE_SUGGESTIONS env var, stores it in the on-disk state, gitlab-prepare-validator restores it, and both candidate + validator prompts already consume includeSuggestions to gate suggestion-block guidance. This commit just exposes the toggle as a customer-facing input. Mirrors the GitHub action's include_suggestions input.
Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
* feat(gitlab): cache bun install cache across pipelines (C8)
Adds a cache: block keyed on droid_action_ref so bun's package cache survives across MR pipelines. BUN_INSTALL_CACHE_DIR is pinned to CI_PROJECT_DIR/.bun-cache because GitLab's cache mechanism can only persist paths inside the project directory. policy: pull-push lets every job benefit from prior downloads and contribute newly-fetched packages back to the cache. Mirrors the actions/cache pattern in the GitHub action.
Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
* feat(gitlab): rate-limit + exponential backoff in GitlabClient (C1)
Wraps every GitlabClient.request call with retry-on-transient-failure logic, mirroring the implicit retry behaviour the GitHub action gets from Octokit. Retries are limited to a configurable maxRetries (default 5) for: 408, 429, 500, 502, 503, 504, and raw fetch network errors. On 429 the client honours the Retry-After header when present (seconds or HTTP-date), and otherwise uses exponential backoff with jitter clamped to maxDelayMs. Non-retryable 4xx errors (401, 403, 404, etc.) surface immediately as GitlabApiError.
The retry knobs are exposed via a third constructor argument so tests can use sub-millisecond delays without needing fake timers.
Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
* feat(gitlab): paginate listNotes + add listDiscussions (C2)
Adds a private paginate<T>() helper that follows GitLab's standard pagination either via the X-Next-Page header (newer GitLab) or Link rel="next" (older GitLab + GitLab.com responses) with per_page=100 to minimise round-trips. listNotes now uses it and a new listDiscussions method is exposed for use cases that need to inspect existing diff discussions. Mirrors Octokit's implicit paginate-everything behaviour that the GitHub action gets for free.
Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
* Revert "feat(gitlab): paginate listNotes + add listDiscussions (C2)"
This reverts commit 7c721d1.
* Revert "feat(gitlab): rate-limit + exponential backoff in GitlabClient (C1)"
This reverts commit d70dbd7.
* Revert "feat(gitlab): cache bun install cache across pipelines (C8)"
This reverts commit 0d6c73b.
* revert(gitlab): drop draft-skip rules + stderr tail-60 capture
Removes two GitLab-only behaviours that don't exist in the GitHub action:
- Draft/WIP `rules: when: never` block. GitHub leaves draft handling to the user's workflow `if: ... draft == false` condition and doesn't bake it into the action. Customers who want to skip drafts can add the same condition to their own .gitlab-ci.yml.
- Stderr tail-60 capture into droid-error.txt. GitHub uses core.setFailed(error.message) which surfaces in the Actions run summary, not in the PR comment body — the comment just shows an actionFailed flag. Revert to the plain "droid exec pass N failed" message for parity.
Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
* feat(gitlab): expose automatic_security_review input (A1, per-MR scope)
Wires the automatic_security_review toggle through the GitLab CI/CD Component. When set to "true", the security-reviewer subagent already bundled in .factory/droids/security-reviewer.md is spawned in parallel with the code-review subagents during Pass 1 (the conditional block in src/gitlab/prompts/candidates.ts already handles this via the securityReviewEnabled flag). Security findings are prefixed with [security] and flow through the same Pass-2 validator path as code-review findings, ultimately posted via a single batched submit_review call.
No plugin install is required: the security-review skill that the subagent invokes as its first action is built into the Droid CLI binary. Mirrors the GitHub action's automatic_security_review input for the per-MR flow only; the scheduled full-repo scan (which additionally uses threat-model-generation / commit-security-scan / vulnerability-validation skills from the security-engineer plugin) is a separate feature.
Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
* feat(gitlab): expose security_block_on_critical/high inputs (A10)
Matches GitHub action's input surface for security_block_on_critical
(default "true") and security_block_on_high (default "false").
Like the GitHub action, the inputs are parsed into context but not
currently consumed by production code — they exist for surface-level
parity and forward compatibility when blocking logic lands.
Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
* docs(gitlab): add gitlab-setup.md and README section for GitLab CI/CD Component
Documents the manual installation flow for the new GitLab CI/CD
Component (`gitlab/templates/review.yml`): prerequisites, full inputs
table, what the pipeline produces, how the two-pass review works,
what is intentionally not yet supported (comment triggers, fill mode,
scheduled scans), and troubleshooting steps.
README now has a short GitLab section that points to the full guide.
Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
* docs(gitlab): add drop-in .gitlab-ci.yml samples under gitlab/examples/
Adds two consumer-facing sample files plus a README so users have a
canonical reference for what a Component-consuming .gitlab-ci.yml looks
like:
* gitlab/examples/.gitlab-ci.minimal.yml — shortest possible, every
default accepted, only the two required CI/CD variables wired.
* gitlab/examples/.gitlab-ci.example.yml — annotated, every input
spelled out with safe-default guidance, plus an optional
@droid fill block (commented out) showing how to add fill.
* gitlab/examples/README.md — table mapping each file to its use case
and the variable-setup story.
Also updates docs/gitlab-setup.md:
* Points readers at gitlab/examples/ instead of just inlining the
snippet, so customers can clone the project, copy the file, done.
* Drops the stale 'service account provisioning' reference now that
the install-code-review skill no longer provisions SAs.
* Tightens the GITLAB_TOKEN row to make the poster-identity story
explicit: the token owner IS the poster, no API impersonation.
Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
* docs(gitlab): hide internal inputs, trim setup.md, default ref to main
Customer-facing surface cleanup before GA:
* gitlab/templates/review.yml: change droid_action_ref default from
"dev" to "main" so customers who don't set it track stable.
Description annotated 'Internal: most users leave at the default'.
* docs/gitlab-setup.md: drop droid_action_ref, droid_action_repo,
stage from the Inputs table — they're for self-hosted GitLab
mirrors / advanced overrides, not standard customer config.
* docs/gitlab-setup.md: drop everything from 'How it works' onward
(How it works, What's not yet supported, Troubleshooting,
Self-hosted GitLab). Those belong in deeper docs / runbooks; the
setup page should be exactly setup.
* docs/gitlab-setup.md: drop the 'pin to a release tag (e.g. v1)'
advice — droid-action doesn't tag yet, and the @main URL pin is
the canonical pattern.
* gitlab/examples/.gitlab-ci.example.yml: drop droid_action_ref from
the inputs block + drop the same line from the optional fill
snippet. Update the comment to just explain the @main pin.
* gitlab/examples/README.md: drop the 'custom stage' reference now
that stage isn't documented as a user-facing knob.
The hidden inputs still exist in the template with sensible defaults,
so air-gapped customers mirroring droid-action can still override
droid_action_repo or pin droid_action_ref to a private SHA — they just
aren't part of the documented surface.
Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
* docs(readme): drop GitLab non-support note from quick-start
Customer-facing surface should describe what is supported, not what
isn't. Caveats belong in deeper docs / runbooks if anywhere, not in the
README quick-start.
Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
* docs(readme): tighten GitLab section wording
Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
* refactor(gitlab): rename template to droid-review.yml; ship as two-file pattern
Component template renamed from gitlab/templates/review.yml to
gitlab/templates/droid-review.yml. Customer drops a self-contained
factory/droid-review.yml in their project and adds a single
`include: - local:` line to their .gitlab-ci.yml, mirroring the
GitHub action's `.github/workflows/droid-review.yml` model.
Examples restructured to reflect the two-file layout. Docs + README
snippets updated accordingly.
Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
* refactor(gitlab): move component to top-level templates/ for Catalog compatibility
GitLab CI/CD Catalog requires components to live at top-level templates/.
Move gitlab/templates/droid-review.yml to templates/droid-review.yml so
the repo is ready for Catalog publish (gitlab.com/factory-ai/droid-action)
without future renames. Add templates/README.md explaining the directory
ownership (mandated by Catalog, parallel to action.yml + .github/workflows/
for GitHub) and a headline comment in droid-review.yml. Update all
existing include URLs (README, docs, examples) to the new path.
Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
* feat(gitlab): point at gitlab.com/factory-components/droid-action mirror
Switch the customer-facing include form from a raw GitHub URL to GitLab's
native include: project: form pointing at the gitlab.com pull-mirror of
this repo. Customers no longer need github.com egress to fetch the
template — gitlab.com is sufficient.
Also flip the runtime droid_action_repo default from
github.com/Factory-AI/droid-action.git to
gitlab.com/factory-components/droid-action.git so the at-job clone of
the runtime source also goes through gitlab.com. Customers behind a
firewall that only permits gitlab.com + app.factory.ai can now run the
full flow.
Updated:
- README.md GitLab quick-start snippet (include: project: form)
- docs/gitlab-setup.md Step 2 snippet
- gitlab/examples/factory/droid-review.yml
- templates/README.md — documents include: project: (default), future
include: component: form once Catalog-tagged, and a raw GitHub URL
fallback for projects that can't reach gitlab.com
- templates/droid-review.yml headline comment + droid_action_repo default
Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
* fix(gitlab): address bot review nits on #93
- templates/droid-review.yml: remove top-level `stages:` block so the
Component doesn't leak its stage list into the consuming project.
Job-level `stage: $[[ inputs.stage ]]` is unchanged; consumers add
the stage to their own `stages:` list (or omit it for the default).
- templates/droid-review.yml: tighten droid_action_ref docstring to
"tag/branch" since the clone uses `git clone --branch` (SHAs would
silently fail).
- src/gitlab/token.ts: drop CI_JOB_TOKEN fallback. It was always set
in CI so the MissingGitlabTokenError never fired, producing
confusing 401s on first API call instead of a clear "set GITLAB_TOKEN"
message. CI_JOB_TOKEN also lacks scopes for notes/discussions.
- src/mcp/gitlab-mr-server.ts: require a line anchor on ReviewComment
(line for RIGHT, old_line for LEFT) via .refine(); GitLab rejects
unanchored diff discussions.
- src/mcp/gitlab-mr-server.ts: remove `.max(30)` cap on comments so
large MRs don't fail the entire submit_review call.
Tests: 445/445 pass; tsc clean.
Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
---------
Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>1 parent d74a29d commit 84946f2
31 files changed
Lines changed: 3506 additions & 0 deletions
File tree
- docs
- gitlab/examples
- factory
- src
- entrypoints
- gitlab
- api
- data
- operations
- prompts
- mcp
- templates
- test
- gitlab
- mcp
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
38 | 38 | | |
39 | 39 | | |
40 | 40 | | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
41 | 74 | | |
42 | 75 | | |
43 | 76 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
0 commit comments