Class: Aidp::Database::Repositories::WorktreeRepository

Inherits:
Aidp::Database::Repository show all
Defined in:
lib/aidp/database/repositories/worktree_repository.rb

Overview

Repository for worktrees table Replaces worktrees.json and pr_worktrees.json Handles both standard and PR worktrees

Constant Summary collapse

TYPES =
%w[standard pr].freeze

Instance Attribute Summary

Attributes inherited from Aidp::Database::Repository

#project_dir, #table_name

Instance Method Summary collapse

Constructor Details

#initialize(project_dir: Dir.pwd) ⇒ WorktreeRepository

Returns a new instance of WorktreeRepository.



14
15
16
# File 'lib/aidp/database/repositories/worktree_repository.rb', line 14

def initialize(project_dir: Dir.pwd)
  super(project_dir: project_dir, table_name: "worktrees")
end

Instance Method Details

#cleanup_stale_pr(days_threshold: 30) ⇒ Array<Hash>

Cleanup stale PR worktrees

Parameters:

  • days_threshold (Integer) (defaults to: 30)

    Days after which to consider stale

Returns:

  • (Array<Hash>)

    Removed worktrees



199
200
201
202
203
204
205
206
207
208
209
210
211
212
# File 'lib/aidp/database/repositories/worktree_repository.rb', line 199

def cleanup_stale_pr(days_threshold: 30)
  threshold_time = (Time.now - (days_threshold * 24 * 60 * 60)).strftime("%Y-%m-%d %H:%M:%S")

  stale = query(
    "SELECT * FROM worktrees WHERE project_dir = ? AND worktree_type = 'pr' AND created_at < ?",
    [project_dir, threshold_time]
  )

  stale.each do |row|
    execute("DELETE FROM worktrees WHERE id = ?", [row["id"]])
  end

  stale.map { |row| deserialize_worktree(row) }
end

#exists?(slug) ⇒ Boolean

Check if worktree exists

Parameters:

  • slug (String)

    Worktree slug

Returns:

  • (Boolean)


116
117
118
# File 'lib/aidp/database/repositories/worktree_repository.rb', line 116

def exists?(slug)
  !find_by_slug(slug).nil?
end

#find_by_branch(branch) ⇒ Hash?

Find worktree by branch

Parameters:

  • branch (String)

    Branch name

Returns:

  • (Hash, nil)

    Worktree info or nil



104
105
106
107
108
109
110
# File 'lib/aidp/database/repositories/worktree_repository.rb', line 104

def find_by_branch(branch)
  row = query_one(
    "SELECT * FROM worktrees WHERE project_dir = ? AND branch = ?",
    [project_dir, branch]
  )
  deserialize_worktree(row)
end

#find_by_pr(pr_number) ⇒ Hash?

Find worktree by PR number

Parameters:

  • pr_number (Integer)

    PR number

Returns:

  • (Hash, nil)

    Worktree info or nil



92
93
94
95
96
97
98
# File 'lib/aidp/database/repositories/worktree_repository.rb', line 92

def find_by_pr(pr_number)
  row = query_one(
    "SELECT * FROM worktrees WHERE project_dir = ? AND pr_number = ?",
    [project_dir, pr_number]
  )
  deserialize_worktree(row)
end

#find_by_slug(slug) ⇒ Hash?

Find worktree by slug

Parameters:

  • slug (String)

    Worktree slug

Returns:

  • (Hash, nil)

    Worktree info or nil



80
81
82
83
84
85
86
# File 'lib/aidp/database/repositories/worktree_repository.rb', line 80

def find_by_slug(slug)
  row = query_one(
    "SELECT * FROM worktrees WHERE project_dir = ? AND slug = ?",
    [project_dir, slug]
  )
  deserialize_worktree(row)
end

#list(type: nil) ⇒ Array<Hash>

List all worktrees

Parameters:

  • type (String, nil) (defaults to: nil)

    Filter by type (standard, pr)

Returns:

  • (Array<Hash>)

    Worktrees



124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
# File 'lib/aidp/database/repositories/worktree_repository.rb', line 124

def list(type: nil)
  rows = if type
    query(
      "SELECT * FROM worktrees WHERE project_dir = ? AND worktree_type = ? ORDER BY created_at DESC",
      [project_dir, type]
    )
  else
    query(
      "SELECT * FROM worktrees WHERE project_dir = ? ORDER BY created_at DESC",
      [project_dir]
    )
  end

  rows.map { |row| deserialize_worktree(row) }
end

#list_pr_worktreesHash

List PR worktrees (for PRWorktreeManager)

Returns:

  • (Hash)

    Map of pr_number => worktree info



150
151
152
153
154
155
156
157
158
159
160
# File 'lib/aidp/database/repositories/worktree_repository.rb', line 150

def list_pr_worktrees
  rows = query(
    "SELECT * FROM worktrees WHERE project_dir = ? AND worktree_type = 'pr'",
    [project_dir]
  )

  rows.each_with_object({}) do |row, hash|
    wt = deserialize_worktree(row)
    hash[wt[:pr_number].to_s] = wt if wt[:pr_number]
  end
end

#list_standardArray<Hash>

List standard worktrees (for Worktree module)

Returns:

  • (Array<Hash>)


143
144
145
# File 'lib/aidp/database/repositories/worktree_repository.rb', line 143

def list_standard
  list(type: "standard")
end

#register(slug:, path:, branch:) ⇒ Hash

Register a standard worktree

Parameters:

  • slug (String)

    Worktree slug

  • path (String)

    Filesystem path

  • branch (String)

    Branch name

Returns:

  • (Hash)

    Worktree info



24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
# File 'lib/aidp/database/repositories/worktree_repository.rb', line 24

def register(slug:, path:, branch:)
  now = current_timestamp

  execute(
    insert_sql([
      :project_dir, :worktree_type, :path, :branch, :slug,
      :status, :created_at, :updated_at
    ]),
    [project_dir, "standard", path, branch, slug, "active", now, now]
  )

  Aidp.log_debug("worktree_repository", "registered",
    slug: slug, type: "standard")

  find_by_slug(slug)
end

#register_pr(pr_number:, path:, base_branch:, head_branch:, metadata: {}) ⇒ Hash

Register a PR worktree

Parameters:

  • pr_number (Integer)

    PR number

  • path (String)

    Filesystem path

  • base_branch (String)

    Base branch

  • head_branch (String)

    Head branch

  • metadata (Hash) (defaults to: {})

    Additional metadata

Returns:

  • (Hash)

    Worktree info



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
# File 'lib/aidp/database/repositories/worktree_repository.rb', line 49

def register_pr(pr_number:, path:, base_branch:, head_branch:, metadata: {})
  now = current_timestamp
  slug = "pr-#{pr_number}-#{Time.now.to_i}"

   = .merge(
    base_branch: base_branch,
    head_branch: head_branch,
    created_at: Time.now.to_i
  )

  execute(
    insert_sql([
      :project_dir, :worktree_type, :path, :branch, :slug, :pr_number,
      :status, :metadata, :created_at, :updated_at
    ]),
    [
      project_dir, "pr", path, head_branch, slug, pr_number,
      "active", serialize_json(), now, now
    ]
  )

  Aidp.log_debug("worktree_repository", "registered_pr",
    pr_number: pr_number, slug: slug)

  find_by_pr(pr_number)
end

#unregister(slug) ⇒ Object

Unregister a worktree by slug

Parameters:

  • slug (String)

    Worktree slug



165
166
167
168
169
170
171
# File 'lib/aidp/database/repositories/worktree_repository.rb', line 165

def unregister(slug)
  execute(
    "DELETE FROM worktrees WHERE project_dir = ? AND slug = ?",
    [project_dir, slug]
  )
  Aidp.log_debug("worktree_repository", "unregistered", slug: slug)
end

#unregister_pr(pr_number) ⇒ Object

Unregister a PR worktree

Parameters:

  • pr_number (Integer)

    PR number



176
177
178
179
180
181
182
# File 'lib/aidp/database/repositories/worktree_repository.rb', line 176

def unregister_pr(pr_number)
  execute(
    "DELETE FROM worktrees WHERE project_dir = ? AND pr_number = ?",
    [project_dir, pr_number]
  )
  Aidp.log_debug("worktree_repository", "unregistered_pr", pr_number: pr_number)
end

#update_status(slug, status) ⇒ Object

Update worktree status

Parameters:

  • slug (String)

    Worktree slug

  • status (String)

    New status



188
189
190
191
192
193
# File 'lib/aidp/database/repositories/worktree_repository.rb', line 188

def update_status(slug, status)
  execute(
    "UPDATE worktrees SET status = ?, updated_at = ? WHERE project_dir = ? AND slug = ?",
    [status, current_timestamp, project_dir, slug]
  )
end