Skip to main content

Github Issue Lifecycle

@webframp/github-issue-lifecyclev2026.08.28.1· 14d agoMODELSWORKFLOWSREPORTS
01README

GitHub issue lifecycle tracker for swamp. Drives issues from open through triage, planning, implementation, PR linkage, and merge as versioned swamp data — with optional label sync and comment posting back to the issue.

No external dependencies beyond the gh CLI. Designed for solo developers or small teams working on GitHub repos who want observable, queryable issue lifecycle data without leaving the terminal.

State Machine

opened ──[start]──> triaging
triaging ──[triage]──> classified
classified ──[plan]──> planned
planned ──[iterate]──> planned  (feedback loop)
planned ──[approve]──> approved
approved ──[implement]──> implementing
implementing ──[link_pr]──> pr_open
pr_open ──[pr_merged]──> done
pr_open ──[pr_failed]──> pr_failed
pr_failed ──[link_pr]──> pr_open  (retry)
Any ──[close]──> closed

Usage

swamp extension pull @webframp/github-issue-lifecycle

# Create a lifecycle tracker for a repo
swamp model create @webframp/github-issue-lifecycle tracker \
  --global repo=webframp/swamp-extensions

# Start tracking an issue
swamp model method run tracker start --input issue_number=42

# Triage it
swamp model method run tracker triage \
  --input issue_number=42 --input kind=bug --input priority=high

# Plan implementation
swamp model method run tracker plan \
  --input issue_number=42 \
  --input summary="Fix pagination bug" \
  --input steps='["Read current code","Fix off-by-one","Add test"]'

# Approve and implement
swamp model method run tracker approve --input issue_number=42
swamp model method run tracker implement --input issue_number=42

# Link a PR
swamp model method run tracker link_pr \
  --input issue_number=42 \
  --input pr_url=https://github.com/webframp/swamp-extensions/pull/100

# Record merge
swamp model method run tracker pr_merged --input issue_number=42

Prerequisites

  • gh CLI installed and authenticated (gh auth login)
  • swamp initialized in the repository (swamp init)
02Release Notes

2026.08.28.1

Changed: Normalized the extension license to Apache-2.0 and corrected the copyright holder to "Sean Escriva". Extensions that previously shipped an MIT LICENSE.md are now Apache-2.0, consistent with the repository root and every other extension. No code or behavioral changes.

Upgrade note: License text only. No API, schema, or runtime behavior changed.

2026.08.27.1

Changed: Test suite now uses the shared createModelTestContext factory from @systeminit/swamp-testing instead of a hand-rolled method context. No behavioral, schema, or method changes — the published model, workflow, and report behave identically. The deno.json gains a dev-only @systeminit/swamp-testing import-map entry.

Note: The lifecycle-metrics report test keeps its hand-rolled data repository. The report matches stored artifacts through entry.tags.specName, a field the factory's TestData type does not model, so the factory cannot drive the report's filtering path without fabricating data. This is documented inline in the test.

2026.08.26.3

Fixed: Restored inline npm:zod@4.4.3 import specifiers so the registry quality scorer can resolve dependencies and score the extension. An earlier release used a bare "zod" import-map specifier, which published but scored as unscored.

Changed: Retained explicit compilerOptions.strict in deno.json. No behavioral or schema changes.

03Models1
@webframp/github-issue-lifecyclev2026.08.28.1github-issue-lifecycle/lifecycle.ts

Global Arguments

ArgumentTypeDescription
repostringGitHub repo in owner/name format (e.g., webframp/swamp-extensions)
postCommentsbooleanPost lifecycle transition comments to the GitHub issue
syncLabelsbooleanSync lifecycle phase as a GitHub label (lifecycle:<phase>)
fn start(issue_number: number)
Fetch issue context from GitHub and begin lifecycle tracking.
ArgumentTypeDescription
issue_numbernumberGitHub issue number
fn triage(issue_number: number, kind: enum, priority?: enum, component?: string, notes?: string)
Classify the issue and set labels.
ArgumentTypeDescription
issue_numbernumberGitHub issue number
kindenumCategory to assign during triage
priority?enumPriority to assign during triage
component?stringAffected component or area
notes?stringTriage notes
fn plan(issue_number: number, summary: string, steps: array, risks?: array, feedback?: string)
Record an implementation plan.
ArgumentTypeDescription
issue_numbernumberGitHub issue number
summarystringOne-line summary of approach
stepsarrayImplementation steps
risks?arrayKnown risks or concerns
feedback?stringFeedback from the last iteration
fn iterate(issue_number: number, summary: string, steps: array, risks?: array, feedback: string)
Revise the plan with feedback (bumps iteration).
ArgumentTypeDescription
issue_numbernumberGitHub issue number
summarystringOne-line summary of the revised approach
stepsarrayRevised implementation steps
risks?arrayKnown risks or concerns
feedbackstringWhat changed and why
fn approve(issue_number: number)
Lock the plan — ready for implementation.
ArgumentTypeDescription
issue_numbernumberGitHub issue number
fn implement(issue_number: number, branch?: string)
Signal that implementation has started.
ArgumentTypeDescription
issue_numbernumber
branch?stringWorking branch name if known
fn link_pr(issue_number: number, pr_url: string, branch?: string)
Associate a PR URL with the issue. Idempotent.
ArgumentTypeDescription
issue_numbernumber
pr_urlstringFull PR URL
branch?string
fn pr_merged(issue_number: number)
Record PR merge and close the issue.
ArgumentTypeDescription
issue_numbernumberGitHub issue number
fn pr_failed(issue_number: number, reason?: string)
Record that the PR failed CI or review.
ArgumentTypeDescription
issue_numbernumberGitHub issue number
reason?stringWhy the PR failed CI or review
fn complete(issue_number: number, close_issue?: boolean)
Mark done without full PR flow.
ArgumentTypeDescription
issue_numbernumberGitHub issue number
close_issue?booleanClose the GitHub issue (default: true)
fn close(issue_number: number, reason?: string)
Abandon the issue from any state.
ArgumentTypeDescription
issue_numbernumberGitHub issue number
reason?stringWhy the issue was closed
fn status(issue_number: number)
Read-only: refresh and show current issue state.
ArgumentTypeDescription
issue_numbernumberGitHub issue number

Resources

state(infinite)— Current lifecycle phase and transition metadata.
context(infinite)— Issue context fetched from GitHub.
classification(infinite)— Issue classification (kind, priority, component).
plan(infinite)— Implementation plan (versioned on iterate).
pullRequest(infinite)— Linked pull request metadata.
04Workflows1
@webframp/issue-lifecycle-drivef7a1b2c3-d4e5-6789-abcd-0123456789ab

Drives a GitHub issue through the full lifecycle: start → triage → plan → approve → implement. Each job calls the corresponding lifecycle model method sequentially, with the agent providing classification and plan content as inputs. This workflow handles the pre-PR phases. Once implementation starts, the pr-fix-loop skill takes over and calls link_pr / pr_merged / pr_failed as the PR progresses through CI. Designed to be called once per issue when you want the agent to drive the full triage-to

startFetch issue context from GitHub and begin lifecycle tracking.
1.start-lifecycle${{ inputs.lifecycle_model }}.start— Transition issue to triaging phase.
triageClassify the issue.
1.classify${{ inputs.lifecycle_model }}.triage— Apply classification and priority labels.
planRecord the implementation plan.
1.create-plan${{ inputs.lifecycle_model }}.plan— Write plan with summary and steps.
approveLock the plan — transition to approved.
1.approve-plan${{ inputs.lifecycle_model }}.approve— Approve the plan for implementation.
implementSignal implementation has started.
1.start-implementation${{ inputs.lifecycle_model }}.implement— Transition to implementing phase.
05Reports1
@webframp/lifecycle-metricsmodel
lifecycle_metrics.ts

Cycle-time metrics, stuck issues, and retry counts from lifecycle data

lifecyclemetricssdlc
06Previous Versions10
2026.08.27.1

2026.08.27.1

Changed: Test suite now uses the shared createModelTestContext factory from @systeminit/swamp-testing instead of a hand-rolled method context. No behavioral, schema, or method changes — the published model, workflow, and report behave identically. The deno.json gains a dev-only @systeminit/swamp-testing import-map entry.

Note: The lifecycle-metrics report test keeps its hand-rolled data repository. The report matches stored artifacts through entry.tags.specName, a field the factory's TestData type does not model, so the factory cannot drive the report's filtering path without fabricating data. This is documented inline in the test.

2026.08.26.3

Fixed: Restored inline npm:zod@4.4.3 import specifiers so the registry quality scorer can resolve dependencies and score the extension. An earlier release used a bare "zod" import-map specifier, which published but scored as unscored.

Changed: Retained explicit compilerOptions.strict in deno.json. No behavioral or schema changes.

2026.08.26.3

2026.08.26.3

Fixed: Restored inline npm:zod@4.4.3 import specifiers so the registry quality scorer can resolve dependencies and score the extension. An earlier release used a bare "zod" import-map specifier, which published but scored as unscored.

Changed: Retained explicit compilerOptions.strict in deno.json. No behavioral or schema changes.

2026.08.26.1

2026.08.26.1

Changed: Normalized deno.json configuration for repo-wide consistency: added explicit compilerOptions.strict and migrated zod dependency to the import map (bare "zod" specifier instead of inline npm:zod@4.4.3). No behavioral changes — runtime resolution is identical.

2026.08.25.1

2026.08.25.1

Changed: Updated labels for improved extension discoverability. Added cross-cutting category labels (security, observability, finops, infrastructure, networking, compliance, devops, ai, incident-response) where applicable.

updated labels

2026.08.24.2

2026.08.24.2

Added: Output metadata attributes for observability.

  • durationMs: Method execution duration in milliseconds.
  • collectedBy: Extension name that produced the data.
  • fetchedAt: ISO 8601 timestamp when data was fetched (added to resources that previously lacked it).
2026.08.24.1

2026.08.24.1

Added Troubleshooting section documenting silent label sync failures, asymmetric comment/label error handling, best-effort issue close, start re-reset behavior, and gh CLI auth delegation.

2026.08.21.2

2026.08.21.2

Changed: gh CLI failures raised by the model now name the exact command that was run and its exit code, instead of a bare "gh failed: ..." message. A non-JSON response from gh issue view (used by start and status) now raises a clear "returned output that could not be parsed as JSON" error naming the command, instead of a raw JSON.parse SyntaxError. The lifecycle-metrics report's data reader now names the resource spec, instance, and model when a stored JSON blob fails to parse, instead of throwing an unattributed SyntaxError.

2026.08.21.1

Changed: Added .describe() documentation to previously undocumented fields across the resource schemas (ContextSchema, ClassificationSchema, PlanSchema, PullRequestSchema) and method argument schemas (triage, plan, iterate, approve, pr_merged, pr_failed, close, status). No behavioral change.

2026.08.15.1

Fixed: Every method that reads lifecycle state (start, triage, plan, iterate, approve, implement, link_pr, pr_merged, pr_failed, complete, close) threw before reaching GitHub because it relied on ctx.storedResources, a field current swamp no longer passes to model methods. All state reads now go through ctx.readResource(), the supported API.

Fixed: Resource instance names collided across specs — context, state, classification, and pullRequest all wrote to the same issue-<n> storage path for a given issue, since instance names must be unique across all specs on a model, not just within one. Each spec now writes to a spec-prefixed path (state-issue-42, pullRequest-issue-42, etc.), so per-issue data no longer overwrites itself across specs.

Changed: pullRequest gained a retryCount field, incremented on every pr_failed call and carried forward through link_pr retries and pr_merged. The lifecycle-metrics report now reads this field directly instead of relying on raw stored-resource access (also removed) to derive retry counts from historical writes.

Upgrade note: Existing pullRequest data written before this version lacks retryCount and will read as 0 going forward — no migration needed. Issues already tracked under the old issue-<n> instance naming will not be found by the new spec-prefixed lookups; re-run start to re-establish state under the new naming for any in-flight issues.

2026.08.21.1

2026.08.21.1

Changed: Added .describe() documentation to previously undocumented fields across the resource schemas (ContextSchema, ClassificationSchema, PlanSchema, PullRequestSchema) and method argument schemas (triage, plan, iterate, approve, pr_merged, pr_failed, close, status). No behavioral change.

2026.08.15.1

Fixed: Every method that reads lifecycle state (start, triage, plan, iterate, approve, implement, link_pr, pr_merged, pr_failed, complete, close) threw before reaching GitHub because it relied on ctx.storedResources, a field current swamp no longer passes to model methods. All state reads now go through ctx.readResource(), the supported API.

Fixed: Resource instance names collided across specs — context, state, classification, and pullRequest all wrote to the same issue-<n> storage path for a given issue, since instance names must be unique across all specs on a model, not just within one. Each spec now writes to a spec-prefixed path (state-issue-42, pullRequest-issue-42, etc.), so per-issue data no longer overwrites itself across specs.

Changed: pullRequest gained a retryCount field, incremented on every pr_failed call and carried forward through link_pr retries and pr_merged. The lifecycle-metrics report now reads this field directly instead of relying on raw stored-resource access (also removed) to derive retry counts from historical writes.

Upgrade note: Existing pullRequest data written before this version lacks retryCount and will read as 0 going forward — no migration needed. Issues already tracked under the old issue-<n> instance naming will not be found by the new spec-prefixed lookups; re-run start to re-establish state under the new naming for any in-flight issues.

2026.07.27.1

2026.07.27.1

Fixed: The fmt task ran deno fmt --check, so deno task fmt verified formatting instead of applying it and there was no way to format the extension through its own task. fmt now formats and a new fmt:check verifies, matching every other extension in the repository.

Fixed: deno fmt no longer inspects CLAUDE.md / AGENTS.md. Those files are gitignored and never present in CI, but deno fmt does not read .gitignore, so deno task fmt:check could fail locally on a file CI does not have.

Upgrade note: Tooling and formatting only. No model, method, schema, or behavior change — nothing to do on upgrade.

2026.07.24.1

2026.07.24.1

Added: Initial release of the GitHub issue lifecycle tracker.

  • 12 methods covering the full issue lifecycle: start, triage, plan, iterate, approve, implement, link_pr, pr_merged, pr_failed, complete, close, status
  • State machine with enforced valid transitions
  • Optional lifecycle comment posting to the GitHub issue thread
  • Optional lifecycle:<phase> label sync on the issue
  • All state stored as versioned swamp resources (state, context, classification, plan, pullRequest) — queryable via CEL
  • PR number auto-extraction from URL
  • Idempotent link_pr (safe to re-link after retry)
  • Configurable via globalArgs: repo, postComments, syncLabels
07Stats
A
100 / 100
Downloads
139
Archive size
26.7 KB
  • Has README or module doc2/2earned
  • README has a code example1/1earned
  • README is substantive1/1earned
  • Most symbols documented1/1earned
  • No slow types (deprecated)1/1earned
  • Dependencies pass trust audit2/2earned
  • Has description1/1earned
  • Platform support declared (or universal)2/2earned
  • License declared1/1earned
  • Verified public repository2/2earned
08Platforms
09Labels