Skip to main content

Redmine

@webframp/redminev2026.08.21.3· 1d agoMODELS
01README

Redmine issue tracker integration — workflow-agnostic CRUD model.

Provides 26 model methods covering issues, projects, statuses, trackers, users, custom fields, relations, versions, time entries, watchers, search, issue categories, journal editing, and file uploads. Designed as composable primitives for building any workflow on top of Redmine.

For opinionated Kanban workflows, flow metrics, and sprint reports, see @webframp/redmine-kanban.

Quick Start

swamp extension pull @webframp/redmine
swamp model create @webframp/redmine tracker \
  --global-arg host=https://your-redmine.example.org \
  --global-arg apiKey=YOUR_API_KEY \
  --global-arg project=your-project

The project global arg is now optional. Omit it for cross-project queries (e.g. list_issues with assignedToId: "me" across all projects). Methods that require a project (list_users, create_issue, list_versions, create_version, list_issue_categories) throw a clear error if none is provided.

02Release Notes

2026.08.21.3

Changed:

  • search now rejects an empty query with a clear validation error, instead of sending an empty search to Redmine and writing a resource under an empty instance name.
  • Redmine API and network-level errors now name the HTTP method and request path (e.g. "Redmine API GET /issues.json failed (500): ..."), instead of only the status code. A connection failure (DNS, refused, timeout) now names the method, path, and host instead of surfacing a bare fetch exception.
  • upload_file failures now name the file path and issue id when the file can't be read, and the filename, host, and issue id when the upload itself fails — instead of a bare "Upload failed: <status>" with no indication of what was being uploaded or to where.

2026.08.21.2

Changed: Tightened host and apiKey on the global-args schema, and subject on create_issue's argument schema, to require non-empty strings. All three are required identifiers/tokens that the Redmine API never accepts empty — this catches misconfiguration at model-create/method-call time instead of a confusing API failure.

2026.08.21.1

Added

  • Retroactive compatibility note for the list_issues resource instance-name change introduced in 2026.08.10.1.

Upgrade note (retroactive — applies to 2026.08.10.1)

Breaking change to list_issues data-resource instance names.

Prior to 2026.08.10.1, list_issues wrote its data resource under the constant instance name all. Starting with 2026.08.10.1 (PR #343 — make project global arg optional), the instance name is derived from active filters using a prefixed scheme to avoid collisions between hyphenated project identifiers and downstream field values:

Filter combination Old instance name New instance name
No filters all all (unchanged)
project only all p:<project>
project + parentId all p:<project>-parent:<parentId>
project + assignedToId all p:<project>-a:<assignedToId>

The table shows representative examples. All active filter arguments contribute segments in the order: p:, a:, s:, t:, parent:.

Impact: Any data.query expression or workflow step that references the list_issues resource by its old instance name will fail with an index-out-of-bounds error after upgrading past 2026.08.10.1.

Recommended consumer pattern: Within workflows, prefer filtering on workflowRunId rather than name when querying list_issues output. The workflowRunId predicate is stable across filter and naming changes:

data.query("tracker", "issues", workflowRunId == run.id)

2026.08.20.1

Upgrade note: Bumped zod from 4.3.6 to 4.4.3. No behavioral changes — dependency version alignment only.

03Models1
@webframp/redminev2026.08.21.3redmine/redmine.ts

Global Arguments

ArgumentTypeDescription
hoststringRedmine instance URL (e.g. https://redmine.example.com)
apiKeystringRedmine API key (40-character hex string)
project?stringDefault project identifier (omit for cross-project queries)
username?stringRedmine username for X-Redmine-Username header (required by some ingress configurations)
fn list_statuses()
List all issue statuses
fn list_trackers()
List all trackers
fn list_projects()
List all accessible projects
fn list_users(project?: string)
List project memberships (users and groups with their roles)
ArgumentTypeDescription
project?stringProject identifier (defaults to global project arg)
fn list_custom_fields()
List all custom field definitions
fn list_issues(project?: string, trackerId?: number, statusId?: union, assignedToId?: union, parentId?: number, limit?: number, sort?: string)
List issues matching filters
ArgumentTypeDescription
project?stringProject identifier
trackerId?numberFilter by tracker ID
statusId?unionFilter by status ID or open/closed/*
assignedToId?unionFilter by assignee ID or 'me'
parentId?numberFilter by parent issue ID
limit?numberMax results (default 25, max 100)
sort?stringSort field (e.g., 'updated_on:desc')
fn get_issue(issueId: number)
Get a single issue with journals and children
ArgumentTypeDescription
issueIdnumberIssue ID
fn create_issue(subject: string, project?: string, trackerId?: number, statusId?: number, priorityId?: number, assignedToId?: number, description?: string, parentIssueId?: number, estimatedHours?: number, customFields?: array)
Create a new issue
ArgumentTypeDescription
subjectstringIssue subject
project?stringProject identifier
trackerId?numberTracker ID
statusId?numberStatus ID
priorityId?numberPriority ID
assignedToId?numberAssignee user ID
description?stringIssue description
parentIssueId?numberParent issue ID
estimatedHours?numberEstimated hours
customFields?arrayCustom field values
fn update_issue(issueId: number, subject?: string, trackerId?: number, statusId?: number, priorityId?: number, assignedToId?: number, description?: string, parentIssueId?: number, estimatedHours?: number, doneRatio?: number, dueDate?: string, notes?: string, customFields?: array)
Update an existing issue
ArgumentTypeDescription
issueIdnumberIssue ID to update
subject?stringNew subject
trackerId?numberNew tracker ID
statusId?numberNew status ID
priorityId?numberNew priority ID
assignedToId?numberNew assignee user ID (null to unassign)
description?stringNew description
parentIssueId?numberNew parent issue ID
estimatedHours?numberNew estimated hours
doneRatio?numberPercent done (0-100)
dueDate?stringUpdated due date (YYYY-MM-DD)
notes?stringJournal note to add
customFields?arrayCustom field values to update
fn delete_issue(issueId: number)
Delete an issue
ArgumentTypeDescription
issueIdnumberIssue ID to delete
fn list_relations(issueId: number)
List relations for an issue
ArgumentTypeDescription
issueIdnumberIssue ID
fn create_relation(issueId: number, issueToId: number, relationType: enum, delay?: number)
Create a relation between two issues
ArgumentTypeDescription
issueIdnumberSource issue ID
issueToIdnumberTarget issue ID
relationTypeenumRelation type
delay?numberDelay in days (for precedes/follows)
fn delete_relation(relationId: number)
Delete a relation
ArgumentTypeDescription
relationIdnumberRelation ID to delete
fn list_versions(project?: string)
List project versions (milestones/sprints)
ArgumentTypeDescription
project?stringProject identifier (defaults to global project arg)
fn list_time_entries(issueId?: number, project?: string, userId?: number, from?: string, to?: string, limit?: number)
List time entries, optionally filtered by issue or project
ArgumentTypeDescription
issueId?numberFilter by issue ID
project?stringFilter by project identifier
userId?numberFilter by user ID
from?stringStart date (YYYY-MM-DD)
to?stringEnd date (YYYY-MM-DD)
limit?numberMax results (default 25)
fn log_time(issueId: number, hours: number, activityId?: number, comments?: string, spentOn?: string)
Log time spent on an issue
ArgumentTypeDescription
issueIdnumberIssue ID
hoursnumberHours spent
activityId?numberActivity ID
comments?stringComment
spentOn?stringDate spent (YYYY-MM-DD, defaults to today)
fn add_watcher(issueId: number, userId: number)
Add a watcher to an issue
ArgumentTypeDescription
issueIdnumberIssue ID
userIdnumberUser ID to add as watcher
fn remove_watcher(issueId: number, userId: number)
Remove a watcher from an issue
ArgumentTypeDescription
issueIdnumberIssue ID
userIdnumberUser ID to remove as watcher
fn search(query: string, project?: string, limit?: number)
Search across issues, projects, and wiki pages
ArgumentTypeDescription
querystringSearch query
project?stringScope search to project identifier
limit?numberMax results (default 25)
fn get_version(versionId: number)
Get a single version by ID
ArgumentTypeDescription
versionIdnumberVersion ID
fn create_version(project?: string, name: string, description?: string, status?: enum, dueDate?: string, sharing?: enum, wikiPageTitle?: string)
Create a project version (milestone/sprint)
ArgumentTypeDescription
project?stringProject identifier (defaults to global project arg)
namestringVersion name
description?stringDescription
status?enumVersion status
dueDate?stringDue date (YYYY-MM-DD)
sharing?enumSharing scope
wikiPageTitle?stringWiki page title
fn update_version(versionId: number, name?: string, description?: string, status?: enum, dueDate?: string, sharing?: enum, wikiPageTitle?: string)
Update a version
ArgumentTypeDescription
versionIdnumberVersion ID
name?stringNew name
description?stringNew description
status?enumNew status
dueDate?stringNew due date (YYYY-MM-DD)
sharing?enumNew sharing scope
wikiPageTitle?stringNew wiki page title
fn delete_version(versionId: number)
Delete a version
ArgumentTypeDescription
versionIdnumberVersion ID to delete
fn update_journal(journalId: number, notes: string, privateNotes?: boolean)
Update a journal entry's notes
ArgumentTypeDescription
journalIdnumberJournal ID
notesstringUpdated notes content
privateNotes?booleanMark notes as private
fn list_issue_categories(project?: string)
List issue categories for a project
ArgumentTypeDescription
project?stringProject identifier (defaults to global project arg)
fn upload_file(issueId: number, filePath: string, filename?: string, description?: string, contentType?: string)
Upload a file and attach it to an issue (two-step: upload binary, then attach token)
ArgumentTypeDescription
issueIdnumberIssue ID to attach the file to
filePathstringLocal file path to upload (relative to working directory)
filename?stringFilename for the attachment (defaults to basename of filePath)
description?stringAttachment description
contentType?stringMIME type (auto-detected from filename if omitted)

Resources

issues(30m)— List of issues matching query filters
issue_detail(30m)— Single issue with journals and children
projects(1h)— List of accessible projects
statuses(infinite)— Issue statuses (id, name, isClosed)
trackers(infinite)— Trackers (id, name, defaultStatus, description)
users(1h)— Project memberships (users and groups with roles)
custom_fields(infinite)— Custom field definitions (id, name, fieldFormat, possibleValues, ...)
relations(30m)— Issue relations (blocks, precedes, relates, etc.)
versions(1h)— Project versions (milestones/sprints)
time_entries(30m)— Time entries for issues or projects
search_results(15m)— Search results across issues, projects, and wiki
issue_categories(1h)— Issue categories for a project
04Previous Versions16
2026.08.21.2

2026.08.21.2

Changed: Tightened host and apiKey on the global-args schema, and subject on create_issue's argument schema, to require non-empty strings. All three are required identifiers/tokens that the Redmine API never accepts empty — this catches misconfiguration at model-create/method-call time instead of a confusing API failure.

2026.08.21.1

Added

  • Retroactive compatibility note for the list_issues resource instance-name change introduced in 2026.08.10.1.

Upgrade note (retroactive — applies to 2026.08.10.1)

Breaking change to list_issues data-resource instance names.

Prior to 2026.08.10.1, list_issues wrote its data resource under the constant instance name all. Starting with 2026.08.10.1 (PR #343 — make project global arg optional), the instance name is derived from active filters using a prefixed scheme to avoid collisions between hyphenated project identifiers and downstream field values:

Filter combination Old instance name New instance name
No filters all all (unchanged)
project only all p:<project>
project + parentId all p:<project>-parent:<parentId>
project + assignedToId all p:<project>-a:<assignedToId>

The table shows representative examples. All active filter arguments contribute segments in the order: p:, a:, s:, t:, parent:.

Impact: Any data.query expression or workflow step that references the list_issues resource by its old instance name will fail with an index-out-of-bounds error after upgrading past 2026.08.10.1.

Recommended consumer pattern: Within workflows, prefer filtering on workflowRunId rather than name when querying list_issues output. The workflowRunId predicate is stable across filter and naming changes:

data.query("tracker", "issues", workflowRunId == run.id)

2026.08.20.1

Upgrade note: Bumped zod from 4.3.6 to 4.4.3. No behavioral changes — dependency version alignment only.

2026.08.21.1

2026.08.21.1

Added

  • Retroactive compatibility note for the list_issues resource instance-name change introduced in 2026.08.14.1.

Upgrade note (retroactive — applies to 2026.08.14.1)

Breaking change to list_issues data-resource instance names.

Prior to 2026.08.14.1, list_issues wrote its data resource under the instance name all (or all-<parentId> when a parent filter was active). Starting with 2026.08.14.1, the instance name is derived from active filters using a prefixed scheme to avoid collisions between hyphenated project identifiers and downstream field values:

Filter combination Old instance name New instance name
No filters all all (unchanged)
project only all p:<project>
project + parentId all-<parentId> p:<project>-parent:<parentId>
project + assignedToId all p:<project>-a:<assignedToId>

The table shows representative examples. All active filter arguments contribute segments in the order: p:, a:, s:, t:, parent:.

Impact: Any data.query expression or workflow step that references the list_issues resource by its old instance name will fail with an index-out-of-bounds error after upgrading past 2026.08.14.1.

Recommended consumer pattern: Within workflows, prefer filtering on workflowRunId rather than name when querying list_issues output. The workflowRunId predicate is stable across filter and naming changes:

data.query("tracker", "issues", workflowRunId == run.id)

2026.08.20.1

Upgrade note: Bumped zod from 4.3.6 to 4.4.3. No behavioral changes — dependency version alignment only.

2026.08.20.1

2026.08.20.1

Upgrade note: Bumped zod from 4.3.6 to 4.4.3. No behavioral changes — dependency version alignment only.

2026.08.14.1

2026.08.10.1

Changed: The project global argument is now optional. This enables cross-project queries — most notably list_issues with assignedToId: "me" across all accessible projects, equivalent to Redmine's /my/page view.

  • list_issues and search operate across all projects when no project is specified (neither as a method argument nor globally).
  • Methods that require a project in their URL path (list_users, create_issue, list_versions, create_version, list_issue_categories) throw a clear error if none is resolved from either source.
  • Instance names for list_issues now include all active filter fields with prefixes (p:, a:, s:, t:, parent:) to prevent cache collisions between different filter combinations.

Upgrade: Existing model instances with project set continue to work unchanged. The upgrade is a no-op identity function (no persisted data migration needed). New instances may omit project for cross-project queries.

2026.07.18.1

Added: An upgrades array entry (no-op) to redmine.ts for proper typeVersion tracking on existing instances. No schema or behavior changes.

2026.07.09.1

Fixed: Extension failed to load with Last upgrade toVersion "2026.06.21.1" does not match model version "2026.07.08.1" for model type "@webframp/redmine". #194 bumped the model's version field to match the manifest but never added a matching upgrades entry, leaving the upgrade chain one version short of the declared model version — a rule the registry enforces at load time. This adds the missing no-op upgrade entry and bumps the version again so the chain is complete. No behaviour change beyond #194.

2026.08.10.1

2026.08.10.1

Changed: The project global argument is now optional. This enables cross-project queries — most notably list_issues with assignedToId: "me" across all accessible projects, equivalent to Redmine's /my/page view.

  • list_issues and search operate across all projects when no project is specified (neither as a method argument nor globally).
  • Methods that require a project in their URL path (list_users, create_issue, list_versions, create_version, list_issue_categories) throw a clear error if none is resolved from either source.
  • Instance names for list_issues now include all active filter fields with prefixes (p:, a:, s:, t:, parent:) to prevent cache collisions between different filter combinations.

Upgrade: Existing model instances with project set continue to work unchanged. The upgrade is a no-op identity function (no persisted data migration needed). New instances may omit project for cross-project queries.

2026.07.18.1

Added: An upgrades array entry (no-op) to redmine.ts for proper typeVersion tracking on existing instances. No schema or behavior changes.

2026.07.09.1

Fixed: Extension failed to load with Last upgrade toVersion "2026.06.21.1" does not match model version "2026.07.08.1" for model type "@webframp/redmine". #194 bumped the model's version field to match the manifest but never added a matching upgrades entry, leaving the upgrade chain one version short of the declared model version — a rule the registry enforces at load time. This adds the missing no-op upgrade entry and bumps the version again so the chain is complete. No behaviour change beyond #194.

2026.07.18.1

2026.07.18.1

Added: An upgrades array entry (no-op) to redmine.ts for proper typeVersion tracking on existing instances. No schema or behavior changes.

2026.07.09.1

Fixed: Extension failed to load with Last upgrade toVersion "2026.06.21.1" does not match model version "2026.07.08.1" for model type "@webframp/redmine". #194 bumped the model's version field to match the manifest but never added a matching upgrades entry, leaving the upgrade chain one version short of the declared model version — a rule the registry enforces at load time. This adds the missing no-op upgrade entry and bumps the version again so the chain is complete. No behaviour change beyond #194.

2026.07.09.1

2026.07.09.1

Fixed: Extension failed to load with Last upgrade toVersion "2026.06.21.1" does not match model version "2026.07.08.1" for model type "@webframp/redmine". #194 bumped the model's version field to match the manifest but never added a matching upgrades entry, leaving the upgrade chain one version short of the declared model version — a rule the registry enforces at load time. This adds the missing no-op upgrade entry and bumps the version again so the chain is complete. No behaviour change beyond #194.

2026.07.08.1

2026.07.08.1

Released: publishes the model-version load fix from #191.

That PR corrected the redmine.ts model version to match the manifest, but it changed only the model source — not manifest.yaml — so the publish workflow (which detects extensions by a changed manifest.yaml) never released it. This version bump touches the manifest so the fix reaches the registry. No behaviour change beyond #191.

2026.06.21.1
2026.06.15.1
2026.04.30.2

Removed 1 workflows. Removed 2 reports. updated labels

2026.04.30.1

Modified 1 models

2026.04.22.3
2026.04.22.2
2026.04.22.1
2026.04.14.1
05Stats
A
100 / 100
Downloads
152
Archive size
29.3 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
06Platforms
07Labels