version: '3'

# ---------------------------------------------------------------------------
# scm.yml -- STUB for #883 v1 cache layer (Story 1) + #976 REST opt-in + #1555 safe body posting.
#
# DO NOT EXTEND except for the narrow #1555 body-posting carve-out below.
#
# The full scm:* task namespace lives at #881; this file is replaced wholesale
# when #881 lands. The stub exposes the minimum surface the #883 v1 cache
# consumer (Story 2 cache:fetch-all) needs:
#
#   - scm:issue:list    (thin wrapper over `ghx|gh issue list`)
#   - scm:issue:view    (thin wrapper over `ghx|gh issue view`)
#   - scm:issue:close   (thin wrapper over `ghx|gh issue close`)
#   - scm:issue:edit    (thin wrapper over `ghx|gh issue edit`)
#   - scm:issue:design-critique-chip (#3642 closed catalog remaining-set)
#   - scm:issue:work-claim (#4200 same-issue busy flag)
#   - scm:body:*        (#1555 safe Markdown body posting via github-body TS CLI)
#
# Each command is a thin pass-through to `ghx <verb>` (when ghx is on PATH)
# or `gh <verb>` (fallback). Output JSON via the consumer-supplied --json
# flag. The JSON-shape contract Story 2 depends on is pinned by the
# tests/test_scm_contract.py contract test against tests/fixtures/scm_issue_view.json.
#
# REST opt-in (#976): callers may pass `--rest` to scm:issue:view /
# scm:issue:list to route the read through scripts/gh_rest.py REST
# helpers (rest_issue_view / rest_issue_list) instead of forwarding to
# `ghx|gh issue view|list`. This sidesteps the GraphQL bucket entirely so
# a depleted graphql.remaining no longer fails read-only smoke / cache
# flows. The REST shape differs from the gh --json GraphQL shape (REST
# emits user/created_at/lowercase state vs GraphQL author/createdAt/
# uppercase state); only callers that opt in see the REST shape. Story 2
# cache:fetch-all keeps the legacy (GraphQL) path until #881. Mutations
# (close, edit) keep forwarding to gh -- they have non-trivial flag
# surfaces (--body-file, --add-label, --remove-label, ...) that this
# stub deliberately does not re-implement; #881 owns the full surface.
#
# Forward-compat marker: v1 was issue:* plus #1555 body-posting. #3391
# adds scm:sync-default (dest-targeted staged sync PRs). #3642 adds
# scm:issue:design-critique-chip (closed catalog remaining-set). Other PR
# verbs remain #881.
# ---------------------------------------------------------------------------

vars:
  # Each included sub-taskfile defines its own DEFT_ROOT mirror so scripts
  # can be dispatched via {{.DEFT_ROOT}}/scripts/<name>.py on every platform
  # (#566). joinPath is evaluated eagerly by go-task templating and yields
  # a native-separator absolute path that uv --project "{{.DEFT_ROOT}}" run python can open on Windows.
  DEFT_ROOT: '{{joinPath .TASKFILE_DIR ".."}}'

# Per `conventions/task-caching.md` (#574): tasks that accept user-facing
# CLI args via {{.CLI_ARGS}} MUST NOT declare `sources:` / `generates:` --
# the cached cmds skip would silently discard the recovery flag.
tasks:
  issue:list:
    desc: "[#883 stub] List issues -- task scm:issue:list -- [--rest] --repo OWNER/NAME --json number,title,state,updatedAt [--state ...] (#976 --rest routes via REST helpers; default forwards to ghx|gh)"
    dir: '{{.USER_WORKING_DIR}}'
    deps:
      - task: :engine:_ts-build
    cmds:
      - task: :engine:invoke
        vars:
          ENGINE_CMD: 'scm issue list {{.CLI_ARGS}}'

  issue:view:
    desc: "[#883 stub] View an issue -- task scm:issue:view -- [--rest] <N> --repo OWNER/NAME --json number,title,body,state,author,createdAt,updatedAt,labels,comments (#976 --rest routes via REST helpers and emits REST shape; default forwards to ghx|gh GraphQL shape)"
    dir: '{{.USER_WORKING_DIR}}'
    deps:
      - task: :engine:_ts-build
    cmds:
      - task: :engine:invoke
        vars:
          ENGINE_CMD: 'scm issue view {{.CLI_ARGS}}'

  issue:close:
    desc: "[#883 stub] Close an issue -- task scm:issue:close -- <N> --repo OWNER/NAME [--comment ...]"
    dir: '{{.USER_WORKING_DIR}}'
    deps:
      - task: :engine:_ts-build
    cmds:
      - task: :engine:invoke
        vars:
          ENGINE_CMD: 'scm issue close {{.CLI_ARGS}}'

  issue:edit:
    desc: "[#883 stub] Edit an issue -- task scm:issue:edit -- <N> --repo OWNER/NAME [--add-label ...] [--body ...]"
    dir: '{{.USER_WORKING_DIR}}'
    deps:
      - task: :engine:_ts-build
    cmds:
      - task: :engine:invoke
        vars:
          ENGINE_CMD: 'scm issue edit {{.CLI_ARGS}}'

  issue:design-critique-chip:
    desc: "[#3642] Exclusive design-critique catalog chip -- task scm:issue:design-critique-chip -- --issue N --chip mechanism-shaped|in-progress|ingest-ready [--repo OWNER/NAME]"
    dir: '{{.USER_WORKING_DIR}}'
    deps:
      - task: :engine:_ts-build
    cmds:
      - task: :engine:invoke
        vars:
          ENGINE_CMD: 'scm issue design-critique-chip {{.CLI_ARGS}}'

  issue:work-claim:
    desc: "[#4200] Same-issue busy flag -- task scm:issue:work-claim -- claim|show|release --issue N [--repo OWNER/NAME] [--json]"
    dir: '{{.USER_WORKING_DIR}}'
    deps:
      - task: :engine:_ts-build
    cmds:
      - task: :engine:invoke
        vars:
          ENGINE_CMD: 'scm issue work-claim {{.CLI_ARGS}}'

  body:issue:create:
    desc: "[#1555] Safely create an issue body from --body-file without shell Markdown interpolation"
    dir: '{{.USER_WORKING_DIR}}'
    deps:
      - task: :engine:_ts-build
    cmds:
      - task: :engine:invoke
        vars:
          ENGINE_CMD: 'github-body issue-create {{.CLI_ARGS}}'

  body:issue:edit:
    desc: "[#1555] Safely edit an issue body from --body-file and live gh read-back"
    dir: '{{.USER_WORKING_DIR}}'
    deps:
      - task: :engine:_ts-build
    cmds:
      - task: :engine:invoke
        vars:
          ENGINE_CMD: 'github-body issue-edit {{.CLI_ARGS}}'

  body:issue:fetch:
    desc: "[#2607] Fetch live issue body to UTF-8 --out-file for safe read-modify-write"
    dir: '{{.USER_WORKING_DIR}}'
    deps:
      - task: :engine:_ts-build
    cmds:
      - task: :engine:invoke
        vars:
          ENGINE_CMD: 'github-body issue-fetch {{.CLI_ARGS}}'

  body:issue:lint:
    desc: "[#2960] Lint live issue body for CP1252/CP437-as-UTF-8 mojibake (same patterns as verify:encoding)"
    dir: '{{.USER_WORKING_DIR}}'
    deps:
      - task: :engine:_ts-build
    cmds:
      - task: :engine:invoke
        vars:
          ENGINE_CMD: 'github-body issue-lint {{.CLI_ARGS}}'

  body:pr:lint:
    desc: "[#2960] Lint live PR body for CP1252/CP437-as-UTF-8 mojibake (same patterns as verify:encoding)"
    dir: '{{.USER_WORKING_DIR}}'
    deps:
      - task: :engine:_ts-build
    cmds:
      - task: :engine:invoke
        vars:
          ENGINE_CMD: 'github-body pr-lint {{.CLI_ARGS}}'

  body:comment:create:
    desc: "[#1555] Safely create an issue/PR comment body from --body-file and live gh read-back"
    dir: '{{.USER_WORKING_DIR}}'
    deps:
      - task: :engine:_ts-build
    cmds:
      - task: :engine:invoke
        vars:
          ENGINE_CMD: 'github-body comment-create {{.CLI_ARGS}}'

  body:comment:edit:
    desc: "[#1555] Safely edit an issue comment body from --body-file and live gh read-back"
    dir: '{{.USER_WORKING_DIR}}'
    deps:
      - task: :engine:_ts-build
    cmds:
      - task: :engine:invoke
        vars:
          ENGINE_CMD: 'github-body comment-edit {{.CLI_ARGS}}'

  sync-default:
    desc: "[#3391] Open dest-targeted sync PRs under syncMaxFiles -- new PR per staged leg"
    dir: '{{.USER_WORKING_DIR}}'
    deps:
      - task: :engine:_ts-build
    cmds:
      - task: :engine:invoke
        vars:
          ENGINE_CMD: 'scm:sync-default {{.CLI_ARGS}}'

  body:pr:edit:
    desc: "[#1555] Safely edit a PR body from --body-file and live gh read-back"
    dir: '{{.USER_WORKING_DIR}}'
    deps:
      - task: :engine:_ts-build
    cmds:
      - task: :engine:invoke
        vars:
          ENGINE_CMD: 'github-body pr-edit {{.CLI_ARGS}}'
