install-artifact.test.ts 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. // kilocode_change - new file
  2. import { describe, expect, test } from "bun:test"
  3. import { $ } from "bun"
  4. import fs from "fs/promises"
  5. import os from "os"
  6. import path from "path"
  7. const root = path.join(import.meta.dir, "..", "..")
  8. const wrapper = path.join(root, "bin", "kilo")
  9. describe("npm install artifact behavior", () => {
  10. test("keeps the CLI wrapper contract", async () => {
  11. const text = await fs.readFile(wrapper, "utf8")
  12. expect(text.startsWith("#!/usr/bin/env node")).toBe(true)
  13. expect(text).toContain("const envPath = process.env.KILO_BIN_PATH")
  14. expect(text).toContain('const base = "@kilocode/cli-" + platform + "-" + arch')
  15. expect(text).toContain("function findBinary(startDir)")
  16. })
  17. test("links npm bin commands to the wrapper during local install", async () => {
  18. const npmPath = Bun.which("npm")
  19. if (!npmPath) {
  20. console.warn("Skipping install artifact test: npm is not available in PATH")
  21. return
  22. }
  23. const tmp = await fs.mkdtemp(path.join(os.tmpdir(), "kilo-install-artifact-"))
  24. try {
  25. const pkg = path.join(tmp, "pkg")
  26. const bin = path.join(pkg, "bin")
  27. const prefix = path.join(tmp, "prefix")
  28. await fs.mkdir(bin, { recursive: true })
  29. await fs.mkdir(prefix, { recursive: true })
  30. await fs.copyFile(wrapper, path.join(bin, "kilo"))
  31. await Bun.write(
  32. path.join(pkg, "package.json"),
  33. JSON.stringify(
  34. {
  35. name: "kilo-install-artifact-repro",
  36. version: "1.0.0",
  37. bin: {
  38. kilo: "./bin/kilo",
  39. kilocode: "./bin/kilo",
  40. },
  41. },
  42. null,
  43. 2,
  44. ),
  45. )
  46. await $`npm install --prefix ${prefix} ${pkg} --no-package-lock --ignore-scripts --no-audit --no-fund`.quiet()
  47. const commands = ["kilo", "kilocode"]
  48. for (const name of commands) {
  49. const link = path.join(prefix, "node_modules", ".bin", name)
  50. const stat = await fs.lstat(link)
  51. expect(stat.isSymbolicLink() || stat.isFile()).toBe(true)
  52. }
  53. const hidden = path.join(prefix, "node_modules", ".bin", ".kilo")
  54. const exists = await fs
  55. .access(hidden)
  56. .then(() => true)
  57. .catch(() => false)
  58. if (!exists) return
  59. const stat = await fs.lstat(hidden)
  60. expect(stat.isFile() || stat.isSymbolicLink()).toBe(true)
  61. if (!stat.isSymbolicLink()) expect(stat.size).toBeGreaterThan(0)
  62. } finally {
  63. await fs.rm(tmp, { recursive: true, force: true })
  64. }
  65. }, 60_000) // kilocode_change
  66. })