Skip to content

feat: added vscode start task button#1201

Merged
Crunchyman-ralph merged 2 commits intoeyaltoledano:nextfrom
losolosol:carlos/implement.start.task.button
Sep 12, 2025
Merged

feat: added vscode start task button#1201
Crunchyman-ralph merged 2 commits intoeyaltoledano:nextfrom
losolosol:carlos/implement.start.task.button

Conversation

@losolosol
Copy link
Contributor

@losolosol losolosol commented Sep 12, 2025

What type of PR is this?

Added a Start Build button to the VSCODE Task Properties Right Panel

  • 🐛 Bug fix
  • ✨ Feature
  • 🔌 Integration
  • 📝 Docs
  • 🧹 Refactor
  • Other:

Description

Related Issues

How to Test This

# Example commands or steps

Expected result:

Contributor Checklist

  • Created changeset: npm run changeset
  • Tests pass: npm test
  • Format check passes: npm run format-check (or npm run format to fix)
  • Addressed CodeRabbit comments (if any)
  • Linked related issues (if any)
  • Manually tested the changes

Changelog Entry


For Maintainers

  • PR title follows conventional commits
  • Target branch correct
  • Labels added
  • Milestone assigned (if applicable)

Summary by CodeRabbit

  • New Features

    • Added a “Start Task” button in Task Details to launch a terminal for the selected task directly from the sidebar.
    • Provides real-time feedback with a spinner and “Starting...” status while launching.
    • Button is automatically disabled during generation/append operations, while a start is in progress, or when the task is completed.
  • Style

    • Minor sidebar layout polish with a divider for clearer section separation.
  • Chores

    • Release metadata updated to mark this as a minor extension update.

@changeset-bot
Copy link

changeset-bot bot commented Sep 12, 2025

🦋 Changeset detected

Latest commit: 054a8b7

The changes in this PR will be included in the next version bump.

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Sep 12, 2025

Walkthrough

Adds a Start Task action to the Task Metadata sidebar that posts an openTerminal message to the extension. The extension handles openTerminal by creating and showing a terminal for the selected task. Minor right-column layout adjustment in TaskDetailsView. No public API/signature changes.

Changes

Cohort / File(s) Summary of changes
Sidebar Start Action
apps/extension/src/components/TaskDetails/TaskMetadataSidebar.tsx
Consumes VSCode context, adds isStartingTask state, implements handleStartTask to post openTerminal with task info, and renders a Start Task button with loading/disabled states; note: button block is duplicated in two UI locations with a divider.
Details View Layout
apps/extension/src/components/TaskDetailsView.tsx
Adjusts indentation/placement of the right-column metadata block; TaskMetadataSidebar still rendered with same props and behavior.
Webview Message Handling
apps/extension/src/services/webview-manager.ts
Adds openTerminal case in WebviewManager.handleMessage: creates and shows a VS Code terminal named from taskId/taskTitle with cwd set to workspaceRoot, replies via existing requestId response flow with try/catch error handling.
Changeset
.changeset/wild-ears-look.md
Adds a changeset declaring a minor extension bump and noting the Start Task button addition.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor User
  participant WebviewUI as Webview UI\n(TaskMetadataSidebar)
  participant ExtHost as Extension Host\n(WebviewManager)
  participant VSCode as VS Code API

  User->>WebviewUI: Click "Start Task"
  note right of WebviewUI #DDFFDD: Validate state, set isStartingTask
  WebviewUI->>ExtHost: postMessage({ type: "openTerminal", taskId, taskTitle, requestId })
  ExtHost->>VSCode: createTerminal({ name, cwd: workspaceRoot })
  VSCode-->>ExtHost: Terminal instance
  ExtHost->>VSCode: terminal.show()
  ExtHost-->>WebviewUI: postMessage({ requestId, success: true })

  alt Error creating terminal
    ExtHost-->>WebviewUI: postMessage({ requestId, success: false, error })
  end

  note right of WebviewUI #DDFFDD: Reset isStartingTask after response
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • Release 0.23.0 #1064 — Modifies WebviewManager message handling; likely related to the new openTerminal message handling added here.

Suggested reviewers

  • eyaltoledano
  • Crunchyman-ralph

Pre-merge checks (3 passed)

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The title succinctly and accurately describes the primary change — adding a VSCode "start task" button — which matches the edits to TaskMetadataSidebar, the webview message handler, and the changeset; it is concise, specific, and not noisy. There is a minor wording variance where the PR description calls it "Start Build," but that appears to refer to the same UI action. The title is clear enough for a teammate scanning history to understand the main change.
Docstring Coverage ✅ Passed No functions found in the changes. Docstring coverage check skipped.

Tip

👮 Agentic pre-merge checks are now available in preview!

Pro plan users can now enable pre-merge checks in their settings to enforce checklists before merging PRs.

  • Built-in checks – Quickly apply ready-made checks to enforce title conventions, require pull request descriptions that follow templates, validate linked issues for compliance, and more.
  • Custom agentic checks – Define your own rules using CodeRabbit’s advanced agentic capabilities to enforce organization-specific policies and workflows. For example, you can instruct CodeRabbit’s agent to verify that API documentation is updated whenever API schema files are modified in a PR. Note: Upto 5 custom checks are currently allowed during the preview period. Pricing for this feature will be announced in a few weeks.

Please see the documentation for more information.

Example:

reviews:
  pre_merge_checks:
    custom_checks:
      - name: "Undocumented Breaking Changes"
        mode: "warning"
        instructions: |
          Pass/fail criteria: All breaking changes to public APIs, CLI flags, environment variables, configuration keys, database schemas, or HTTP/GraphQL endpoints must be documented in the "Breaking Change" section of the PR description and in CHANGELOG.md. Exclude purely internal or private changes (e.g., code not exported from package entry points or explicitly marked as internal).

Please share your feedback with us on this Discord post.

✨ Finishing touches
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between dd03374 and 876717b.

📒 Files selected for processing (3)
  • apps/extension/src/components/TaskDetails/TaskMetadataSidebar.tsx (4 hunks)
  • apps/extension/src/components/TaskDetailsView.tsx (1 hunks)
  • apps/extension/src/services/webview-manager.ts (1 hunks)
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-07-18T17:14:29.399Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/tasks.mdc:0-0
Timestamp: 2025-07-18T17:14:29.399Z
Learning: Applies to scripts/modules/task-manager.js : Use consistent formatting for task files, include all task properties in text files, and format dependencies with status indicators.

Applied to files:

  • apps/extension/src/components/TaskDetailsView.tsx
🧬 Code graph analysis (2)
apps/extension/src/components/TaskDetailsView.tsx (1)
apps/extension/src/components/TaskDetails/TaskMetadataSidebar.tsx (1)
  • TaskMetadataSidebar (21-335)
apps/extension/src/components/TaskDetails/TaskMetadataSidebar.tsx (1)
apps/extension/src/webview/contexts/VSCodeContext.tsx (1)
  • useVSCodeContext (26-32)
🔇 Additional comments (2)
apps/extension/src/services/webview-manager.ts (1)

364-381: Fix payload shape mismatch and undefined cwd (compile-time and runtime blockers).

File: apps/extension/src/services/webview-manager.ts (around lines 364–381)

Webview posts top-level taskId/taskTitle while the handler reads data.taskId/taskTitle, and WebviewManager does not provide this.workspaceRoot — both will prevent terminal creation.

Apply:

-				case 'openTerminal':
-					// Open VS Code terminal for task execution
-					this.logger.info(`Opening terminal for task ${data.taskId}: ${data.taskTitle}`);
-					
-					try {
-						const terminal = vscode.window.createTerminal({
-							name: `Task ${data.taskId}: ${data.taskTitle}`,
-							cwd: this.workspaceRoot
-						});
-						terminal.show();
-						
-						this.logger.info('Terminal created and shown successfully');
-						response = { success: true };
-					} catch (error) {
-						this.logger.error('Failed to create terminal:', error);
-						response = { success: false, error: error.message };
-					}
-					break;
+				case 'openTerminal':
+					// Open VS Code terminal for task execution
+					{
+						// Accept both { data: {…} } and top-level fields
+						const taskId = data?.taskId ?? message.taskId;
+						const taskTitle = data?.taskTitle ?? message.taskTitle;
+						if (taskId == null || !taskTitle) {
+							throw new Error('openTerminal: taskId and taskTitle are required');
+						}
+
+						this.logger.info(`Opening terminal for task ${taskId}: ${taskTitle}`);
+						try {
+							const cwd = vscode.workspace.workspaceFolders?.[0]?.uri.fsPath;
+							const terminal = vscode.window.createTerminal({
+								name: `Task ${taskId}: ${taskTitle}`,
+								cwd
+							});
+							terminal.show();
+							this.logger.info('Terminal created and shown successfully');
+							response = { success: true };
+						} catch (error) {
+							this.logger.error('Failed to create terminal:', error);
+							response = {
+								success: false,
+								error: error instanceof Error ? error.message : String(error)
+							};
+						}
+					}
+					break;

Local verification (run from repo root):

rg -n --glob '!**/dist/**' '\bworkspaceRoot\b' apps/extension || true
rg -n --glob '!**/dist/**' -S -C3 'openTerminal' apps/extension || true
rg -n --glob '!**/dist/**' -S -C3 'postMessage' apps/extension || true
sed -n '320,420p' apps/extension/src/services/webview-manager.ts || true
apps/extension/src/components/TaskDetailsView.tsx (1)

205-214: LGTM: Sidebar placement and props preserved.

Comment on lines +7 to 8
import { useVSCodeContext } from '../../webview/contexts/VSCodeContext';

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick (assertive)

Remove unused VSCode context import (after adopting sendMessage).

Apply:

-import { useVSCodeContext } from '../../webview/contexts/VSCodeContext';
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
import { useVSCodeContext } from '../../webview/contexts/VSCodeContext';
🤖 Prompt for AI Agents
In apps/extension/src/components/TaskDetails/TaskMetadataSidebar.tsx around
lines 7-8, the import "useVSCodeContext" is no longer used after switching to
sendMessage; remove the unused import line to clean up the file and prevent
lint/unused-import errors, and run the linter to confirm no other references
remain.

isRegenerating = false,
isAppending = false
}) => {
const { vscode } = useVSCodeContext();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick (assertive)

Drop unused vscode variable (after adopting sendMessage).

Apply:

-	const { vscode } = useVSCodeContext();
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const { vscode } = useVSCodeContext();
🤖 Prompt for AI Agents
In apps/extension/src/components/TaskDetails/TaskMetadataSidebar.tsx around line
32, the code destructures and assigns the unused vscode variable via const {
vscode } = useVSCodeContext(); — remove this unused destructuring/variable and
update any references to use the already-adopted sendMessage approach instead;
simply delete that line and ensure any message-sending calls use the sendMessage
function from context (or import) so there are no remaining unused variables.

Comment on lines +103 to +125
// Handle starting a task
const handleStartTask = () => {
if (!currentTask || isStartingTask) {
return;
}

setIsStartingTask(true);

// Send message to extension to open terminal
if (vscode) {
vscode.postMessage({
type: 'openTerminal',
taskId: currentTask.id,
taskTitle: currentTask.title
});
}

// Reset loading state after a short delay
setTimeout(() => {
setIsStartingTask(false);
}, 500);
};

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Use sendMessage with data payload and await the response; drop arbitrary timeout.

Aligns payload with extension, leverages request/response flow, and avoids premature spinner reset.

Apply:

-	// Handle starting a task
-	const handleStartTask = () => {
-		if (!currentTask || isStartingTask) {
-			return;
-		}
-		
-		setIsStartingTask(true);
-		
-		// Send message to extension to open terminal
-		if (vscode) {
-			vscode.postMessage({
-				type: 'openTerminal',
-				taskId: currentTask.id,
-				taskTitle: currentTask.title
-			});
-		}
-		
-		// Reset loading state after a short delay
-		setTimeout(() => {
-			setIsStartingTask(false);
-		}, 500);
-	};
+	// Handle starting a task
+	const handleStartTask = async () => {
+		if (!currentTask || isStartingTask) return;
+		setIsStartingTask(true);
+		try {
+			await sendMessage({
+				type: 'openTerminal',
+				data: {
+					taskId: currentTask.id,
+					taskTitle: currentTask.title
+				}
+			});
+		} catch (err) {
+			console.error('Failed to start task terminal:', err);
+		} finally {
+			setIsStartingTask(false);
+		}
+	};

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In apps/extension/src/components/TaskDetails/TaskMetadataSidebar.tsx around
lines 103 to 125, the handler currently posts an openTerminal message and uses a
fixed setTimeout to clear the spinner; replace this with calling the extension's
sendMessage (or equivalent request/response API) with a structured payload {
type: 'openTerminal', data: { taskId: currentTask.id, taskTitle:
currentTask.title } }, await the promise response, and only clear
setIsStartingTask(false) after a successful response (or in the catch block on
error); remove the arbitrary timeout and wrap the call in try/catch to handle
and log errors and to ensure you guard for vscode existence before calling
sendMessage.

Comment on lines +314 to +330
{/* Start Task Button */}
<div className="mt-4">
<Button
onClick={handleStartTask}
variant="default"
size="sm"
className="w-full text-xs"
disabled={isRegenerating || isAppending || isStartingTask || currentTask?.status === 'done'}
>
{isStartingTask ? (
<Loader2 className="w-4 h-4 mr-2 animate-spin" />
) : (
<Play className="w-4 h-4 mr-2" />
)}
{isStartingTask ? 'Starting...' : 'Start Task'}
</Button>
</div>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick (assertive)

Minor a11y: add aria-busy and a descriptive title to the button.

Apply:

 						<Button
 							onClick={handleStartTask}
 							variant="default"
 							size="sm"
-							className="w-full text-xs"
+							className="w-full text-xs"
+							aria-busy={isStartingTask}
+							title={isStartingTask ? 'Starting…' : 'Start task in a VS Code terminal'}
 							disabled={isRegenerating || isAppending || isStartingTask || currentTask?.status === 'done'}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
{/* Start Task Button */}
<div className="mt-4">
<Button
onClick={handleStartTask}
variant="default"
size="sm"
className="w-full text-xs"
disabled={isRegenerating || isAppending || isStartingTask || currentTask?.status === 'done'}
>
{isStartingTask ? (
<Loader2 className="w-4 h-4 mr-2 animate-spin" />
) : (
<Play className="w-4 h-4 mr-2" />
)}
{isStartingTask ? 'Starting...' : 'Start Task'}
</Button>
</div>
{/* Start Task Button */}
<div className="mt-4">
<Button
onClick={handleStartTask}
variant="default"
size="sm"
className="w-full text-xs"
aria-busy={isStartingTask}
title={isStartingTask ? 'Starting…' : 'Start task in a VS Code terminal'}
disabled={isRegenerating || isAppending || isStartingTask || currentTask?.status === 'done'}
>
{isStartingTask ? (
<Loader2 className="w-4 h-4 mr-2 animate-spin" />
) : (
<Play className="w-4 h-4 mr-2" />
)}
{isStartingTask ? 'Starting...' : 'Start Task'}
</Button>
</div>
🤖 Prompt for AI Agents
In apps/extension/src/components/TaskDetails/TaskMetadataSidebar.tsx around
lines 314 to 330, the Start Task button lacks accessibility attributes; add
aria-busy={isStartingTask} so assistive tech knows when the action is in
progress, and add a descriptive title that reflects state (e.g.,
title={isStartingTask ? 'Starting task' : 'Start task'}) to provide a clear
tooltip and context; keep the existing disabled prop and visual content
unchanged.

Comment on lines +364 to +381
case 'openTerminal':
// Open VS Code terminal for task execution
this.logger.info(`Opening terminal for task ${data.taskId}: ${data.taskTitle}`);

try {
const terminal = vscode.window.createTerminal({
name: `Task ${data.taskId}: ${data.taskTitle}`,
cwd: this.workspaceRoot
});
terminal.show();

this.logger.info('Terminal created and shown successfully');
response = { success: true };
} catch (error) {
this.logger.error('Failed to create terminal:', error);
response = { success: false, error: error.message };
}
break;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick (assertive)

Consider using VS Code Tasks API instead of raw terminals.

If these map to defined tasks, prefer vscode.tasks.executeTask(...) for better integration, problem matchers, and status tracking.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 876717b and 054a8b7.

📒 Files selected for processing (1)
  • .changeset/wild-ears-look.md (1 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
.changeset/*.md

📄 CodeRabbit inference engine (.cursor/rules/changeset.mdc)

.changeset/*.md: When running npm run changeset or npx changeset add, provide a concise summary of the changes for the CHANGELOG.md in imperative mood, typically a single line, and not a detailed Git commit message.
The changeset summary should be user-facing, describing what changed in the released version that is relevant to users or consumers of the package.
Do not use your detailed Git commit message body as the changeset summary.

Files:

  • .changeset/wild-ears-look.md
.changeset/*

📄 CodeRabbit inference engine (.cursor/rules/new_features.mdc)

Create appropriate changesets for new features, use semantic versioning, include tagged system information in release notes, and document breaking changes if any.

Files:

  • .changeset/wild-ears-look.md
🪛 markdownlint-cli2 (0.17.2)
.changeset/wild-ears-look.md

5-5: First line in a file should be a top-level heading

(MD041, first-line-heading, first-line-h1)

🔇 Additional comments (2)
.changeset/wild-ears-look.md (2)

2-2: Minor bump is appropriate for a new user-visible feature.


1-3: No change required — changeset package key is correct.

Changeset frontmatter uses "extension" and package.json at ./apps/extension has name "extension" (v0.24.2-rc.1).

Comment on lines +1 to +5
---
"extension": minor
---

Added a Start Build button to the VSCODE Task Properties Right Panel
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick (assertive)

Silence MD041 for .changeset files instead of adding a heading.

Changeset files legitimately start with frontmatter; prefer a lint override.

Example .markdownlint-cli2.jsonc override:

{
  "config": { "MD041": true },
  "ignores": [".changeset/**"]
}
🧰 Tools
🪛 markdownlint-cli2 (0.17.2)

5-5: First line in a file should be a top-level heading

(MD041, first-line-heading, first-line-h1)

🤖 Prompt for AI Agents
In .changeset/wild-ears-look.md lines 1-5 the changeset frontmatter triggers
MD041; instead of adding a bogus heading to the file, update your markdownlint
configuration to exempt the .changeset directory from MD041 (or add an ignores
entry for ".changeset/**") so frontmatter-only files are allowed; modify
.markdownlint-cli2.jsonc (or your repo's markdownlint config) to set MD041 to
true globally and add the .changeset pattern to ignores so linting no longer
requires headings in changeset files.

"extension": minor
---

Added a Start Build button to the VSCODE Task Properties Right Panel
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

⚠️ Potential issue

Use imperative mood, correct casing, and align terminology with UI ("Start Task").

Current text is past tense, uses "VSCODE" casing, and says "Start Build" while code/UX uses "Start Task".

Apply:

-Added a Start Build button to the VSCODE Task Properties Right Panel
+Add Start Task button to the Task Properties sidebar in VS Code.
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
Added a Start Build button to the VSCODE Task Properties Right Panel
Add Start Task button to the Task Properties sidebar in VS Code.
🧰 Tools
🪛 markdownlint-cli2 (0.17.2)

5-5: First line in a file should be a top-level heading

(MD041, first-line-heading, first-line-h1)

🤖 Prompt for AI Agents
.changeset/wild-ears-look.md around line 5: current sentence is past tense, uses
"VSCODE" casing, and says "Start Build" which mismatches the UI; change it to
imperative mood, correct casing, and the UI term by replacing the line with
something like "Add a Start Task button to the VS Code Task Properties right
panel" so it uses imperative voice, "VS Code" casing, and "Start Task"
terminology.

@Crunchyman-ralph Crunchyman-ralph merged commit 83af314 into eyaltoledano:next Sep 12, 2025
4 of 7 checks passed
github-actions bot added a commit that referenced this pull request Sep 12, 2025
  This PR was automatically generated to update documentation based on recent changes.

  Original commit: feat: added vscode start task button (#1201)\n\nCo-authored-by: Carlos Montoya <carlos@Carloss-MacBook-Pro.local>\nCo-authored-by: Carlos Montoya <los@losmontoya.com>\n\n

  Co-authored-by: Claude <claude-assistant@anthropic.com>
Crunchyman-ralph pushed a commit that referenced this pull request Sep 17, 2025
Co-authored-by: Carlos Montoya <carlos@Carloss-MacBook-Pro.local>
Co-authored-by: Carlos Montoya <los@losmontoya.com>
This was referenced Sep 19, 2025
@github-actions github-actions bot mentioned this pull request Sep 22, 2025
sfc-gh-dflippo pushed a commit to sfc-gh-dflippo/task-master-ai that referenced this pull request Dec 4, 2025
Co-authored-by: Carlos Montoya <carlos@Carloss-MacBook-Pro.local>
Co-authored-by: Carlos Montoya <los@losmontoya.com>
sfc-gh-dflippo pushed a commit to sfc-gh-dflippo/task-master-ai that referenced this pull request Dec 4, 2025
Co-authored-by: Carlos Montoya <carlos@Carloss-MacBook-Pro.local>
Co-authored-by: Carlos Montoya <los@losmontoya.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants