Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/CodeAnalysis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ jobs:
name: SonarCloud
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v5
with:
fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis
- name: SonarCloud Scan
Expand All @@ -31,7 +31,7 @@ jobs:
name: PSScriptAnalyzer
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v5

- name: Run PSScriptAnalyzer
uses: microsoft/psscriptanalyzer-action@7a0da25f33985767f15f93140306528900744195
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ jobs:
# Steps represent a sequence of tasks that will be executed as part of the job
steps:
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
- uses: actions/checkout@v4
- uses: actions/checkout@v5
- name: Run PSScriptAnalyzer
uses: microsoft/psscriptanalyzer-action@7a0da25f33985767f15f93140306528900744195
with:
Expand Down
37 changes: 37 additions & 0 deletions Public/Functions/Get-Tag.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
function Get-Tag {
<#
.SYNOPSIS
Retrieves the current user's tags from Habitica.

.DESCRIPTION
Calls the Habitica API to return the list of tags defined by the user.
Tags can be used to group tasks like todos, dailies, or habits.

.EXAMPLE
Get-Tag

Returns all tags for the authenticated Habitica user.

.EXAMPLE
Get-Tag | Where-Object { $_.name -eq "Work" }

Returns the "Work" tag object.

.EXAMPLE
(Get-Tag).name

Lists the names of all tags.
#>
[CmdletBinding()]
param()

process {
try {
$response = Invoke-Api -Uri "/tags" -Method GET
return $response.data
}
catch {
throw "Failed to retrieve tags. Ensure you are authenticated with Connect-Account. Details: $_"
}
}
}
39 changes: 39 additions & 0 deletions Public/Functions/New-Tag.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@

function New-Tag {
<#
.SYNOPSIS
Creates a new tag in Habitica.

.DESCRIPTION
Calls the Habitica API to create a new tag associated with the authenticated user.

.PARAMETER Name
The name of the tag to create.

.EXAMPLE
New-Tag -Name "Work"

Creates a new tag named "Work".

.EXAMPLE
"Fitness","Health" | ForEach-Object { New-Tag -Name $_ }

Creates multiple tags at once.
#>
[CmdletBinding()]
param(
[Parameter(Mandatory, ValueFromPipeline, ValueFromPipelineByPropertyName)]
[string]$Name
)

process {
try {
$Body = @{ name = $Name }
$response = Invoke-Api -Uri "/tags" -Method POST -Body $Body
return $response.data
}
catch {
throw "Failed to create tag '$Name'. Details: $_"
}
}
}
27 changes: 23 additions & 4 deletions Public/Functions/New-Task.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -94,13 +94,19 @@ function New-Task {
[Parameter(Mandatory, ParameterSetName = 'Habit', ValueFromPipelineByPropertyName)]
[string]$Text,

[Parameter(ValueFromPipelineByPropertyName)]
[Parameter(Mandatory = $false, ParameterSetName = 'Todo', ValueFromPipelineByPropertyName)]
[Parameter(Mandatory = $false, ParameterSetName = 'Daily', ValueFromPipelineByPropertyName)]
[Parameter(Mandatory = $false, ParameterSetName = 'Habit', ValueFromPipelineByPropertyName)]
[string]$Alias,

[Parameter(ValueFromPipelineByPropertyName)]
[Parameter(Mandatory = $false, ParameterSetName = 'Todo', ValueFromPipelineByPropertyName)]
[Parameter(Mandatory = $false, ParameterSetName = 'Daily', ValueFromPipelineByPropertyName)]
[Parameter(Mandatory = $false, ParameterSetName = 'Habit', ValueFromPipelineByPropertyName)]
[string]$Note,

[Parameter(ValueFromPipelineByPropertyName)]
[Parameter(Mandatory = $false, ParameterSetName = 'Todo', ValueFromPipelineByPropertyName)]
[Parameter(Mandatory = $false, ParameterSetName = 'Daily', ValueFromPipelineByPropertyName)]
[Parameter(Mandatory = $false, ParameterSetName = 'Habit', ValueFromPipelineByPropertyName)]
[string[]]$Tags,

[Parameter(ValueFromPipelineByPropertyName)]
Expand Down Expand Up @@ -171,7 +177,20 @@ function New-Task {

if ($Alias) { $body.alias = $Alias }
if ($Note) { $body.notes = $Note }
if ($Tags) { $body.tags = $Tags }
if ($Tags) {
$tagIds = @()
$allTags = (Invoke-Api -Uri "/tags" -Method GET).data
foreach ($tag in $Tags) {
$match = $allTags | Where-Object { $_.id -ieq $tag -or $_.name -ieq $tag }
if ($match) {
$tagIds += $match.id
}
else {
Write-Warning "Tag '$tag' not found. Skipping."
}
}
if ($tagIds) { $body.tags = $tagIds }
}
if ($Checklist) { $body.checklist = $Checklist | ForEach-Object { @{ text = $_ } } }

# --- Todo
Expand Down
40 changes: 40 additions & 0 deletions Public/Functions/Remove-Tag.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@

function Remove-Tag {
<#
.SYNOPSIS
Deletes a Habitica tag.

.DESCRIPTION
Calls the Habitica API to delete a tag by its ID.

.PARAMETER Id
The ID of the tag to delete.

.EXAMPLE
Remove-Tag -Id "12345678-abcd-1234-abcd-1234567890ab"

Deletes the specified tag.

.EXAMPLE
Get-Tag | Where-Object { $_.name -eq "Obsolete" } | Remove-Tag

Deletes the tag named "Obsolete".
#>
[CmdletBinding(SupportsShouldProcess)]
param(
[Parameter(Mandatory, ValueFromPipelineByPropertyName)]
[string]$Id
)

process {
if ($PSCmdlet.ShouldProcess("Tag ID $Id", "Delete")) {
try {
$response = Invoke-Api -Uri "/tags/$Id" -Method DELETE
return $response.success
}
catch {
throw "Failed to delete tag '$Id'. Details: $_"
}
}
}
}
45 changes: 45 additions & 0 deletions Public/Functions/Set-Tag.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@

function Set-Tag {
<#
.SYNOPSIS
Updates an existing Habitica tag.

.DESCRIPTION
Calls the Habitica API to update the name of an existing tag by its ID.

.PARAMETER Id
The ID of the tag to update.

.PARAMETER Name
The new name for the tag.

.EXAMPLE
Set-Tag -Id "12345678-abcd-1234-abcd-1234567890ab" -Name "UpdatedTag"

Renames the specified tag to "UpdatedTag".

.EXAMPLE
Get-Tag | Where-Object { $_.name -eq "Work" } | Set-Tag -Name "Office"

Finds the "Work" tag and renames it to "Office".
#>
[CmdletBinding()]
param(
[Parameter(Mandatory, ValueFromPipelineByPropertyName)]
[string]$Id,

[Parameter(Mandatory)]
[string]$Name
)

process {
try {
$Body = @{ name = $Name }
$response = Invoke-Api -Uri "/tags/$Id" -Method PUT -Body $Body
return $response.data
}
catch {
throw "Failed to update tag '$Id'. Details: $_"
}
}
}
150 changes: 150 additions & 0 deletions Public/Functions/Set-Task.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
function Set-Task {
<#
.SYNOPSIS
Updates an existing Habitica task.

.DESCRIPTION
Calls the Habitica API to update a task by ID.
Parameters are grouped into sets depending on the task type (`todo`, `daily`, or `habit`).

.PARAMETER TaskId
The unique identifier of the Habitica task to update.

.PARAMETER Text
The new title of the task.

.PARAMETER Notes
The description or details of the task.

.PARAMETER Type
The type of the task. Valid values: "habit", "daily", "todo".

.PARAMETER Priority
Priority multiplier for the task. Typical values: 0.1 (trivial), 1 (easy), 1.5 (medium), 2 (hard).

.PARAMETER Tags
A list of tag names to associate with the task. Tags are automatically resolved to their IDs if they exist.

.PARAMETER StartDate
(Dailies only) Start date for the daily task.

.PARAMETER Repeat
(Dailies only) Days of the week the task repeats. Example: @{ su=$false; m=$true; t=$true; w=$true; th=$true; f=$true; s=$false }

.PARAMETER Frequency
(Dailies only) Interval type. Valid values: "daily", "weekly", "monthly", "yearly".

.PARAMETER Up
(Habits only) Whether the habit can increment positively.

.PARAMETER Down
(Habits only) Whether the habit can decrement negatively.

.EXAMPLE
Set-Task -TaskId "abcd1234" -Type todo -Text "Finish docs" -Priority 2

.EXAMPLE
Set-Task -TaskId "abcd1234" -Type daily -StartDate (Get-Date) -Repeat @{ m=$true; t=$true; w=$true }
#>
[CmdletBinding(DefaultParameterSetName = 'Todo')]
param(
# -----------------------
# Common properties
# -----------------------
[Parameter(Mandatory, ParameterSetName = 'Todo', ValueFromPipelineByPropertyName)]
[Parameter(Mandatory, ParameterSetName = 'Daily', ValueFromPipelineByPropertyName)]
[Parameter(Mandatory, ParameterSetName = 'Habit', ValueFromPipelineByPropertyName)]
[string]$TaskId,

[Parameter(ParameterSetName = 'Todo', ValueFromPipelineByPropertyName)]
[Parameter(ParameterSetName = 'Daily', ValueFromPipelineByPropertyName)]
[Parameter(ParameterSetName = 'Habit', ValueFromPipelineByPropertyName)]
[string]$Text,

[Parameter(ParameterSetName = 'Todo', ValueFromPipelineByPropertyName)]
[Parameter(ParameterSetName = 'Daily', ValueFromPipelineByPropertyName)]
[Parameter(ParameterSetName = 'Habit', ValueFromPipelineByPropertyName)]
[string]$Notes,

[Parameter(ParameterSetName = 'Todo', ValueFromPipelineByPropertyName)]
[Parameter(ParameterSetName = 'Daily', ValueFromPipelineByPropertyName)]
[Parameter(ParameterSetName = 'Habit', ValueFromPipelineByPropertyName)]
[double]$Priority,

[Parameter(ParameterSetName = 'Todo', ValueFromPipelineByPropertyName)]
[Parameter(ParameterSetName = 'Daily', ValueFromPipelineByPropertyName)]
[Parameter(ParameterSetName = 'Habit', ValueFromPipelineByPropertyName)]
[string[]]$Tags,

# -----------------------
# Daily properties
# -----------------------
[Parameter(ParameterSetName = 'Daily', ValueFromPipelineByPropertyName)]
[datetime]$StartDate,

[Parameter(ParameterSetName = 'Daily', ValueFromPipelineByPropertyName)]
[hashtable]$Repeat,

[Parameter(ParameterSetName = 'Daily', ValueFromPipelineByPropertyName)]
[ValidateSet("daily", "weekly", "monthly", "yearly")]
[string]$Frequency,

# -----------------------
# Habit properties
# -----------------------
[Parameter(ParameterSetName = 'Habit', ValueFromPipelineByPropertyName)]
[bool]$Up,

[Parameter(ParameterSetName = 'Habit', ValueFromPipelineByPropertyName)]
[bool]$Down
)

begin {

}

process {
$body = @{}
if ($PSBoundParameters.ContainsKey("Text")) { $body.text = $Text }
if ($PSBoundParameters.ContainsKey("Notes")) { $body.notes = $Notes }
if ($PSBoundParameters.ContainsKey("Priority")) { $body.priority = $Priority }
if ($PSBoundParameters.ContainsKey("Type")) { $body.type = $Type }

if ($Tags) {
$resolvedTags = @()
foreach ($tag in $Tags) {
try {
$habiticaTag = Get-Tag | Where-Object { $_.id -ieq $tag -or $_.name -ieq $tag }
if ($habiticaTag) {
$resolvedTags += $habiticaTag.id
}
else {
Write-Warning "Tag '$tag' does not exist. Skipping..."
}
}
catch {
Write-Warning "Failed to resolve tag '$tag'. Skipping..."
}
}
if ($resolvedTags.Count -gt 0) {
$body.tags = $resolvedTags
}
}

if ($PSCmdlet.ParameterSetName -eq 'Daily') {
if ($PSBoundParameters.ContainsKey("StartDate")) { $body.startDate = $StartDate.ToString("yyyy-MM-dd") }
if ($PSBoundParameters.ContainsKey("Repeat")) { $body.repeat = $Repeat }
if ($PSBoundParameters.ContainsKey("Frequency")) { $body.frequency = $Frequency }
}

if ($PSCmdlet.ParameterSetName -eq 'Habit') {
if ($PSBoundParameters.ContainsKey("Up")) { $body.up = $Up }
if ($PSBoundParameters.ContainsKey("Down")) { $body.down = $Down }
}
$response = Invoke-Api -Uri "tasks/$TaskId" -Method PUT -Body $body
if ($response.success) {
Write-Verbose "Task '$Text' updated successfully"
return $response.data
}
}
}
Loading
Loading