update-contributors.js 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. #!/usr/bin/env node
  2. import fs from "fs"
  3. import path from "path"
  4. import https from "https"
  5. import { fileURLToPath } from "url"
  6. // Configuration
  7. const __filename = fileURLToPath(import.meta.url)
  8. const __dirname = path.dirname(__filename)
  9. const README_FILE = path.join(__dirname, "../README.md")
  10. const CONTRIBUTORS_JSON_URL = "https://kilo.ai/contributors.json"
  11. const MAX_CONTRIBUTORS_DISPLAY = 9
  12. const CONTRIBUTORS_PAGE_URL = "https://kilo.ai/#contributors"
  13. // Function to make HTTP requests
  14. function makeRequest(url) {
  15. return new Promise((resolve, reject) => {
  16. https
  17. .get(url, (res) => {
  18. let data = ""
  19. res.on("data", (chunk) => {
  20. data += chunk
  21. })
  22. res.on("end", () => {
  23. try {
  24. const jsonData = JSON.parse(data)
  25. resolve(jsonData)
  26. } catch (error) {
  27. reject(error)
  28. }
  29. })
  30. })
  31. .on("error", (error) => {
  32. reject(error)
  33. })
  34. })
  35. }
  36. // Function to generate Markdown contributor list
  37. function generateContributorMarkdown(contributors) {
  38. let markdown = "## Contributors\n\n"
  39. markdown += "Thanks to all the contributors who help make Kilo Code better!\n\n"
  40. // Map the kilo.ai format to expected format
  41. const validContributors = contributors.map((contributor) => {
  42. // Convert kilo.ai format to GitHub-like format
  43. return {
  44. login: contributor.username,
  45. html_url: `https://github.com/${contributor.username}`,
  46. avatar_url: `https://avatars.githubusercontent.com/u/${contributor.avatarId}`,
  47. }
  48. })
  49. // Limit to MAX_CONTRIBUTORS_DISPLAY contributors
  50. const displayContributors = validContributors.slice(0, MAX_CONTRIBUTORS_DISPLAY)
  51. const hasMore = validContributors.length > MAX_CONTRIBUTORS_DISPLAY
  52. // Create a grid of contributor avatars in rows of 5
  53. let contributorGrid = "<table>\n"
  54. for (let i = 0; i < displayContributors.length; i++) {
  55. const contributor = displayContributors[i]
  56. // Start a new row every 5 contributors
  57. if (i % 5 === 0) {
  58. if (i > 0) {
  59. contributorGrid += "\n </tr>\n"
  60. }
  61. contributorGrid += " <tr>\n"
  62. }
  63. const contributorCell = ` <td align="center">
  64. <a href="${contributor.html_url}">
  65. <img src="${contributor.avatar_url}?size=100" width="100" height="100" alt="${contributor.login}" style="border-radius: 50%;" />
  66. </a>
  67. </td>`
  68. contributorGrid += contributorCell
  69. }
  70. // Add "more..." cell if there are more contributors
  71. if (hasMore) {
  72. // Check if we need to add it to current row or start new row
  73. const lastRowCount = displayContributors.length % 5
  74. if (lastRowCount === 0) {
  75. // Start a new row for "more..."
  76. contributorGrid += "\n </tr>\n <tr>\n"
  77. }
  78. const moreCell = ` <td align="center">
  79. <a href="${CONTRIBUTORS_PAGE_URL}">
  80. <b>more ...</b>
  81. </a>
  82. </td>`
  83. contributorGrid += moreCell
  84. }
  85. // Close the last row
  86. contributorGrid += "\n </tr>\n</table>\n"
  87. markdown += contributorGrid
  88. return markdown
  89. }
  90. // Function to update the contributors section in the README
  91. async function updateContributorsSection() {
  92. try {
  93. console.log("Fetching contributors from kilo.ai...")
  94. // Fetch contributors from external JSON
  95. const contributors = await makeRequest(CONTRIBUTORS_JSON_URL)
  96. if (!Array.isArray(contributors)) {
  97. throw new Error("Failed to fetch contributors data")
  98. }
  99. console.log(`Found ${contributors.length} contributors`)
  100. // Generate Markdown content
  101. const contributorMarkdown = generateContributorMarkdown(contributors)
  102. // Read the existing README
  103. let readmeContent = fs.readFileSync(README_FILE, "utf8")
  104. // Find the contributors section markers or add at the end
  105. const contributorsStartMarker = "## Contributors"
  106. const contributorsEndMarker = "<!-- END CONTRIBUTORS SECTION -->"
  107. let newContent
  108. if (readmeContent.includes(contributorsStartMarker)) {
  109. // Replace existing contributors section
  110. const startIndex = readmeContent.indexOf(contributorsStartMarker)
  111. const endIndex = readmeContent.indexOf(contributorsEndMarker)
  112. if (endIndex === -1) {
  113. // No end marker, look for any existing table or content after the header
  114. // and replace everything from the header to the end of file
  115. const afterHeaderIndex = startIndex + contributorsStartMarker.length
  116. const beforeContent = readmeContent.substring(0, startIndex)
  117. newContent = beforeContent + contributorMarkdown + "\n<!-- END CONTRIBUTORS SECTION -->\n"
  118. } else {
  119. // Replace between markers - clean replacement between the header and end marker
  120. const beforeContent = readmeContent.substring(0, startIndex)
  121. const afterContent = readmeContent.substring(endIndex + contributorsEndMarker.length)
  122. newContent = beforeContent + contributorMarkdown + "\n" + contributorsEndMarker + afterContent
  123. }
  124. } else {
  125. // Add contributors section at the end
  126. newContent = readmeContent.trim() + "\n\n" + contributorMarkdown + "\n<!-- END CONTRIBUTORS SECTION -->\n"
  127. }
  128. // Write the updated content back to the README
  129. fs.writeFileSync(README_FILE, newContent)
  130. console.log("Contributors section updated successfully!")
  131. } catch (error) {
  132. console.error("Error updating contributors section:", error.message)
  133. console.error("Stack trace:", error.stack)
  134. process.exit(1)
  135. }
  136. }
  137. // Run the script
  138. updateContributorsSection()