From 7da7157aa5381de439db4df1f79ddd502c83eeca Mon Sep 17 00:00:00 2001
From: fcoterroba <46996764+fcoterroba@users.noreply.github.com>
Date: Wed, 20 May 2026 10:55:24 +0200
Subject: [PATCH 1/3] feat: add my folder structure
---
scripts/background.js | 3 ++-
scripts/codewarsToGithub.js | 9 ++++++---
welcome.html | 11 +++++++++++
3 files changed, 19 insertions(+), 4 deletions(-)
diff --git a/scripts/background.js b/scripts/background.js
index 0c45096..3f4edb9 100644
--- a/scripts/background.js
+++ b/scripts/background.js
@@ -178,8 +178,9 @@ chrome.runtime.onMessage.addListener(async (request, sender, sendResponse) => {
description,
rank,
} = request.codewarsData;
+ const { folderStructure = "level-problem-language" } = await chrome.storage.local.get("folderStructure");
const fileExtension = supportedFileExtensions[languageOfUserSolution];
- const fileName = directoryName + fileExtension;
+ const fileName = folderStructure === "language-problem" ? `mysolution${fileExtension}` : directoryName + fileExtension;
const encodedSolution = btoa(unescape(encodeURIComponent(userSolution)));
const encodedReadMe = btoa(unescape(encodeURIComponent(description)));
await addReadme(
diff --git a/scripts/codewarsToGithub.js b/scripts/codewarsToGithub.js
index cd7649d..0ddb56e 100644
--- a/scripts/codewarsToGithub.js
+++ b/scripts/codewarsToGithub.js
@@ -125,11 +125,14 @@ const getUrl = (
directory ? directory + "/" : ""
}`;
- if (folderStructure === "level-problem-language") {
+ if (folderStructure === "language-problem") {
return (
- url + `${rank}/${directoryName}/${isReadmeFile ? "README.md" : fileName}`
+ url +
+ `${languageOfUserSolution}/${directoryName}/${
+ isReadmeFile ? "README.md" : fileName
+ }`
);
- } else if (folderStructure === "language-level-problem") {
+ } else if (folderStructure === "level-problem-language") {
return (
url +
`${languageOfUserSolution}/${rank}/${directoryName}/${
diff --git a/welcome.html b/welcome.html
index 5c47984..cb0bf5b 100644
--- a/welcome.html
+++ b/welcome.html
@@ -140,6 +140,17 @@
Date: Wed, 20 May 2026 11:04:32 +0200
Subject: [PATCH 2/3] feat: add optional readme and add comments in the kata
---
scripts/background.js | 125 ++++++++++++++++++++++++++++++++++++++----
scripts/codewars.js | 1 +
scripts/welcome.js | 6 +-
welcome.html | 17 ++++++
4 files changed, 136 insertions(+), 13 deletions(-)
diff --git a/scripts/background.js b/scripts/background.js
index 3f4edb9..3cd214a 100644
--- a/scripts/background.js
+++ b/scripts/background.js
@@ -14,6 +14,86 @@ import {
extractRepoNameAndDirectoryName,
} from "./helperFunctions.js";
+const languageCommentDelimiters = {
+ agda: { line: "--" },
+ bf: { line: null },
+ c: { line: "//" },
+ cfml: { blockStart: "" },
+ cpp: { line: "//" },
+ cobol: { line: "*" },
+ coffeescript: { line: "#" },
+ clojure: { line: ";;" },
+ commonlisp: { line: ";;" },
+ coq: { blockStart: "(*", blockEnd: "*)" },
+ crystal: { line: "#" },
+ "c#": { line: "//" },
+ d: { line: "//" },
+ dart: { line: "//" },
+ elixir: { line: "#" },
+ elm: { line: "--" },
+ erlang: { line: "%" },
+ factor: { line: "!" },
+ forth: { line: "\\" },
+ fortran: { line: "!" },
+ fsharp: { line: "//" },
+ go: { line: "//" },
+ groovy: { line: "//" },
+ haskell: { line: "--" },
+ haxe: { line: "//" },
+ idris: { line: "--" },
+ java: { line: "//" },
+ javascript: { line: "//" },
+ julia: { line: "#" },
+ kotlin: { line: "//" },
+ lambdacalc: { line: null },
+ lean: { line: "--" },
+ lua: { line: "--" },
+ nasm: { line: ";" },
+ nim: { line: "#" },
+ objc: { line: "//" },
+ ocaml: { blockStart: "(*", blockEnd: "*)" },
+ pascal: { blockStart: "{", blockEnd: "}" },
+ perl: { line: "#" },
+ php: { line: "//" },
+ powershell: { line: "#" },
+ prolog: { line: "%" },
+ purescript: { line: "--" },
+ python: { line: "#" },
+ r: { line: "#" },
+ reason: { blockStart: "/*", blockEnd: "*/" },
+ racket: { line: ";" },
+ raku: { line: "#" },
+ riscv: { line: "#" },
+ ruby: { line: "#" },
+ rust: { line: "//" },
+ scala: { line: "//" },
+ solidity: { line: "//" },
+ shell: { line: "#" },
+ sql: { line: "--" },
+ swift: { line: "//" },
+ typescript: { line: "//" },
+ vb: { line: "'" },
+};
+
+const makeCommentHeader = (language, kataUrl, solutionUrl) => {
+ const delimiters = languageCommentDelimiters[language] || { line: "#" };
+ const lines = [`Kata: ${kataUrl}`, `My solution: ${solutionUrl}`];
+ if (delimiters.line) {
+ return `${lines.map((line) => `${delimiters.line} ${line}`).join("\n")}\n\n`;
+ }
+ if (delimiters.blockStart && delimiters.blockEnd) {
+ return `${delimiters.blockStart}\n${lines.join("\n")}\n${delimiters.blockEnd}\n\n`;
+ }
+ return "";
+};
+
+const getSolutionPath = (folderStructure, rank, language, directoryName, fileName) => {
+ if (folderStructure === "language-problem") return `${language}/${directoryName}/${fileName}`;
+ if (folderStructure === "language-level-problem") return `${language}/${rank}/${directoryName}/${fileName}`;
+ if (folderStructure === "level-language-problem") return `${rank}/${language}/${directoryName}/${fileName}`;
+ return `${rank}/${directoryName}/${fileName}`;
+};
+
chrome.runtime.onInstalled.addListener(({ reason }) => {
if (reason === "install") {
chrome.tabs.create({
@@ -23,6 +103,7 @@ chrome.runtime.onInstalled.addListener(({ reason }) => {
isUserAuthenticated: false,
isRepoConnected: false,
folderStructure: "level-problem-language",
+ addReadmeFile: true,
});
}
chrome.runtime.setUninstallURL(
@@ -48,7 +129,7 @@ chrome.runtime.onMessage.addListener(async (request, sender, sendResponse) => {
chrome.tabs.onUpdated.addListener(onTabUpdate);
}
- if (request.action === "connectExistingRepo") {
+ if (request.action === "connectExistingRepo") {
const { userInput } = request;
if (userInput.length === 0 || userInput.length > 100) {
chrome.runtime.sendMessage({
@@ -178,21 +259,43 @@ chrome.runtime.onMessage.addListener(async (request, sender, sendResponse) => {
description,
rank,
} = request.codewarsData;
- const { folderStructure = "level-problem-language" } = await chrome.storage.local.get("folderStructure");
+ const { folderStructure = "level-problem-language", addReadmeFile = true } = await chrome.storage.local.get(["folderStructure", "addReadmeFile"]);
const fileExtension = supportedFileExtensions[languageOfUserSolution];
- const fileName = folderStructure === "language-problem" ? `mysolution${fileExtension}` : directoryName + fileExtension;
- const encodedSolution = btoa(unescape(encodeURIComponent(userSolution)));
- const encodedReadMe = btoa(unescape(encodeURIComponent(description)));
- await addReadme(
- githubUsername,
- repo,
- directory,
+ const fileName =
+ folderStructure === "language-problem"
+ ? `mysolution${fileExtension}`
+ : directoryName + fileExtension;
+ const solutionPath = getSolutionPath(
+ folderStructure,
rank,
+ languageOfUserSolution,
directoryName,
+ fileName
+ );
+ const solutionUrl = `https://github.com/${githubUsername}/${repo}/blob/main/${
+ directory ? `${directory}/` : ""
+ }${solutionPath}`;
+ const commentHeader = makeCommentHeader(
languageOfUserSolution,
- encodedReadMe,
- accessToken
+ request.codewarsData.kataUrl,
+ solutionUrl
);
+ const encodedSolution = btoa(
+ unescape(encodeURIComponent(`${commentHeader}${userSolution}`))
+ );
+ const encodedReadMe = btoa(unescape(encodeURIComponent(description)));
+ if (addReadmeFile) {
+ await addReadme(
+ githubUsername,
+ repo,
+ directory,
+ rank,
+ directoryName,
+ languageOfUserSolution,
+ encodedReadMe,
+ accessToken
+ );
+ }
await addOrUpdateSolution(
githubUsername,
repo,
diff --git a/scripts/codewars.js b/scripts/codewars.js
index 5ef3676..3b93182 100644
--- a/scripts/codewars.js
+++ b/scripts/codewars.js
@@ -28,6 +28,7 @@ chrome.storage.local.get(["isRepoConnected"], (result) => {
data["name"] = nameOfChallenge;
data["description"] = `${descriptionHeader}${parsedDescription}`;
data["directoryName"] = json["slug"];
+ data["kataUrl"] = url;
} catch (e) {
console.log("Error! Unable to get description and rank: ", e);
}
diff --git a/scripts/welcome.js b/scripts/welcome.js
index fa32d70..d5bb713 100644
--- a/scripts/welcome.js
+++ b/scripts/welcome.js
@@ -12,9 +12,10 @@ const settingsIcon = document.querySelector("#settings-icon");
const settingsModal = document.querySelector("#settings-modal");
const saveSettingsBtn = document.querySelector("#save-settings-btn");
const closeModal = document.querySelector(".close");
+const addReadmeFileCheckbox = document.querySelector("#add-readme-file");
document.addEventListener("DOMContentLoaded", () => {
- chrome.storage.local.get("folderStructure", (result) => {
+ chrome.storage.local.get(["folderStructure", "addReadmeFile"], (result) => {
const saved = result.folderStructure || "level-problem-language";
const radio = document.querySelector(
`input[name="folder-structure"][value="${saved}"]`
@@ -22,6 +23,7 @@ document.addEventListener("DOMContentLoaded", () => {
if (radio) {
radio.checked = true;
}
+ addReadmeFileCheckbox.checked = result.addReadmeFile !== false;
});
const params = new URLSearchParams(window.location.search);
@@ -56,7 +58,7 @@ saveSettingsBtn.addEventListener("click", () => {
const selected = document.querySelector(
'input[name="folder-structure"]:checked'
).value;
- chrome.storage.local.set({ folderStructure: selected }, () => {
+ chrome.storage.local.set({ folderStructure: selected, addReadmeFile: addReadmeFileCheckbox.checked }, () => {
settingsModal.style.display = "none";
removeOpenSettingsParam();
});
diff --git a/welcome.html b/welcome.html
index cb0bf5b..0f7dc85 100644
--- a/welcome.html
+++ b/welcome.html
@@ -140,6 +140,23 @@
Folder Structure Organization
Choose how you want CodeHub to organize your solutions in your
GitHub repository:
+
+
+
+
+
+
+
+
Date: Wed, 20 May 2026 11:10:58 +0200
Subject: [PATCH 3/3] fix(welcome): move the new folder option to the end
---
welcome.html | 33 +++++++++++----------------------
1 file changed, 11 insertions(+), 22 deletions(-)
diff --git a/welcome.html b/welcome.html
index 0f7dc85..b5d1451 100644
--- a/welcome.html
+++ b/welcome.html
@@ -146,28 +146,6 @@
Folder Structure Organization
Create README.md for each kata
-
-
-
-
-
-
-
-
Folder Structure Organization
+