Full Code of std-microblock/chromatic for AI

chromatic a5a78a0f0cba cached
34 files
85.1 KB
22.4k tokens
75 symbols
1 requests
Download .txt
Repository: std-microblock/chromatic
Branch: chromatic
Commit: a5a78a0f0cba
Files: 34
Total size: 85.1 KB

Directory structure:
gitextract_tq7m8ylh/

├── .clangd
├── .github/
│   └── workflows/
│       └── xmake.yml
├── .gitignore
├── .gitmodules
├── README.md
├── deps/
│   ├── blook.lua
│   └── breeze-js.lua
├── ipc/
│   ├── ipc.cc
│   ├── ipc.h
│   └── shared_memory_ipc.h
├── scripts/
│   ├── bindgen.bat
│   └── rebuild.ps1
├── src/
│   ├── config.cc
│   ├── config.h
│   ├── context.cc
│   ├── context.h
│   ├── entry.cc
│   ├── hooks/
│   │   ├── blink_parse_html_manipulator.cc
│   │   ├── blink_parse_html_manipulator.h
│   │   ├── disable-integrity.cc
│   │   ├── disable-integrity.h
│   │   ├── wait_for_module_load.cc
│   │   └── wait_for_module_load.h
│   ├── script/
│   │   ├── bindings/
│   │   │   ├── binding_qjs.h
│   │   │   ├── binding_types.cc
│   │   │   ├── binding_types.d.ts
│   │   │   ├── binding_types.h
│   │   │   └── quickjspp.hpp
│   │   ├── script.cc
│   │   └── script.h
│   ├── utils.cc
│   └── utils.h
├── test/
│   └── ipc_test.cc
└── xmake.lua

================================================
FILE CONTENTS
================================================

================================================
FILE: .clangd
================================================
CompileFlags:
    Add: ["-std:latest", "/clang:-std=c++23"]

================================================
FILE: .github/workflows/xmake.yml
================================================
name: Build
permissions: write-all

on:
  push:
    branches: [ "chromatic" ]
  pull_request:
    branches: [ "chromatic" ]
  release:
    types: [created]

jobs:
  build:
    runs-on: windows-2025

    steps:
    - uses: actions/checkout@v4
      with:
        submodules: recursive

    - uses: xmake-io/github-action-setup-xmake@v1
      with:
        xmake-version: latest
        actions-cache-folder: '.xmake-cache'
        actions-cache-key: 'ci'
        package-cache: true
        package-cache-key: windows-2025
        # build-cache: true
        # build-cache-key: ${{ matrix.os }}-${{ matrix.build_type }}

    - name: Xmake configure
      run: |
        xmake config -v --yes --toolchain=clang-cl --mode=releasedbg

    - name: build-releasedbg
      run: |
        xmake b --yes --verbose

    - name: Upload Artifacts
      uses: actions/upload-artifact@v4.6.0
      with:
        path: ./build/windows/x64/
        name: windows-build

    - name: Create Archive
      if: github.event_name == 'release'
      run: |
        Compress-Archive -Path ./build/windows/* -DestinationPath windows-build-pdb.zip
        Remove-Item -Path ./build/windows/x64/releasedbg/*.pdb -Force
        Remove-Item -Path ./build/windows/x64/releasedbg/*.lib -Force
        Compress-Archive -Path ./build/windows/* -DestinationPath windows-build.zip

    - name: Upload Release Assets
      if: github.event_name == 'release'
      uses: softprops/action-gh-release@v1
      with:
        files: |
          windows-build.zip
          windows-build-pdb.zip
        token: ${{ secrets.GITHUB_TOKEN }}


================================================
FILE: .gitignore
================================================
build
.xmake


================================================
FILE: .gitmodules
================================================
[submodule "deps/blook"]
	path = deps/blook
	url = https://github.com/std-microblock/blook
[submodule "deps/cpp-ipc"]
	path = deps/cpp-ipc
	url = https://github.com/std-microblock/cpp-ipc


================================================
FILE: README.md
================================================
<div align=center>
<img src=https://github.com/user-attachments/assets/4e0d0de3-c117-44e0-aed5-f95eaac33ba7 width=200/>
<h1>chromatic</h1>
<h5>Universal modifier for Chromium/V8 | 广谱注入 Chromium/V8 的通用修改器</h5>  
</div>

> [!NOTE]
> 在找 BetterNCM ?
> 
> 由于作者迁移至 QQ 音乐,BetterNCM 疏于维护,以及其年代已久,现将相关代码整体重写并支持极多其它软件,改名为 chromatic。
>
> 点击以查看 [BetterNCM 相关代码存档](https://github.com/std-microblock/chromatic/tree/v2) 或 [最后一版 BetterNCM Release](https://github.com/std-microblock/chromatic/releases/tag/1.3.4)

> [!WARNING]
> This project is still in active development. File a bug report if you meet
> any!\
> 此项目仍在开发阶段,如果遇到问题请发送 Issue
>
> Both English and Chinese issues are accepted.
> Issue 中使用中文或英文均可

## 文档/使用方法

待完善

## Showcase

```javascript
import { chrome } from "chromatic"

chrome.blink.add_blink_parse_html_manipulator(html => {
    if (html.includes('<body')) {
        return html.replace("<body", `
           <div style="
          position: fixed;
          left: 13px;
          top: 11px;
          background: #00000022;
          color: white;
          z-index: 9999;
          backdrop-filter: blur(20px);
          padding: 10px 20px;
          font-size: 15px;
          border-radius: 100px;
          overflow: hidden;
          border: 1px solid #00000038;
          font-family: Consolas;
          cursor: pointer;
      " onclick="location.reload()">Chromatic</div>
      <body
            `)
    }
})
```

![image](https://github.com/user-attachments/assets/6d72958e-d673-4c80-bcd3-e7da743479e3)


================================================
FILE: deps/blook.lua
================================================
package("blook")
    add_deps("cmake")
    add_syslinks("advapi32")
    set_sourcedir(path.join(os.scriptdir(), "blook"))
    on_install(function (package)
        local fcdir = package:cachedir() .. "/fetchcontent"
        import("package.tools.cmake").install(package, {
                "-DCMAKE_INSTALL_PREFIX=" .. package:installdir(),
                "-DCMAKE_PREFIX_PATH=" .. package:installdir(),
                "-DFETCHCONTENT_QUIET=OFF",
                "-DFETCHCONTENT_BASE_DIR=" .. fcdir,
        })
        
        os.cp("include/blook/**", package:installdir("include/blook/"))
        os.cp("external/zasm/zasm/include/**", package:installdir("include/zasm/"))
        os.cp(fcdir .. "/zydis-src/dependencies/zycore/include/**", package:installdir("include/zycore/"))
        os.cp(package:buildir() .. "/blook.lib", package:installdir("lib"))
        os.cp(package:buildir() .. "/external/zasm/zasm.lib", package:installdir("lib"))
    end)
package_end()

================================================
FILE: deps/breeze-js.lua
================================================
package("breeze-js")
    set_description("A lightweight and modern JavaScript runtime built on QuickJS for desktop applications.")
    set_license("AGPL-3.0")

    add_urls("https://github.com/breeze-shell/breeze-js.git")

    add_versions("20250621.3", "4a1556efe18e7afb4a13c3b25abe54080577cae7")
    add_deps("yalantinglibs 0c98464dd202aaa6275a8da3297719a436b8a51a", {
        configs = {
            ssl = true
        }
    })

    add_configs("shared", {description = "Build shared library.", default = false, type = "boolean", readonly = true})

    on_install("windows|!arm", "linux", "macosx", function (package)
        io.replace("xmake.lua", [[set_languages("c89", "c++20")]], [[set_languages("c11", "c++20")]], {plain = true})
        io.replace("xmake.lua", [[set_kind("binary")]], [[set_kind("binary")
set_enabled(false)]], {plain = true})
        io.replace("xmake.lua", [[set_kind("static")]], [[set_kind("static")
add_defines("NDEBUG")
if is_plat("macosx") then
    add_cxxflags("-fexperimental-library")
end]], {plain = true})
        import("package.tools.xmake").install(package)
    end)

    on_test(function (package)
        assert(package:check_cxxsnippets({test = [[
            #include <breeze-js/quickjs.h>
            #include <breeze-js/script.h>
            void test() {
                auto ctx = std::make_shared<breeze::script_context>();
                ctx->reset_runtime();
            }
        ]]}, {configs = {languages = "c++23"}}))
    end)

================================================
FILE: ipc/ipc.cc
================================================
#include "ipc.h"
#include <chrono>
#include <print>
#include <stdexcept>
#include <string>

#include "shared_memory_ipc.h"
#include "ylt/easylog.hpp"

namespace chromatic {
void breeze_ipc::connect(std::string_view name) {
  channel.connect(name.data());
  ipc_thread = std::thread([this]() {
    ELOGFMT(INFO, "IPC thread started, listening for packets...");
    while (!exit_signal) {
      poll();
    }
  });
}

breeze_ipc::~breeze_ipc() {
  exit_signal = true;
  if (ipc_thread.joinable()) {
    ipc_thread.join();
  }
}

bool breeze_ipc::poll() {
  std::string data;
  channel.try_receive(data);
  if (!data.empty()) {
    auto pkt = deserialize<breeze_ipc::packet>(data);
    if (pkt.has_value()) {
      // 检查是否是发给自己的包
      if (pkt->to_pid != 0 && pkt->to_pid != current_pid_) {
        return true; // 不是给自己的包,跳过
      }

      if (pkt->is_fragment) {
        process_fragment(*pkt);
      } else {
        process_packet(std::move(*pkt));
      }
    }
    return true;
  }
  return false;
}

void breeze_ipc::process_packet(packet &&pkt) {
  if (pkt.return_for_call != 0) {
    auto it = call_handlers.find(pkt.return_for_call);
    if (it != call_handlers.end()) {
      it->second(pkt);
      call_handlers.erase(it->first);
    }
  } else {
    auto &handler_list = handlers[pkt.name];
    for (auto &handler : handler_list) {
      handler(pkt);
    }
  }
}

void breeze_ipc::process_fragment(const packet &frag) {
  std::lock_guard lock(fragment_mutex_);

  auto &cache = fragment_cache_[frag.fragment_id];
  if (cache.fragments.empty()) {
    cache.created_time = std::chrono::steady_clock::now();
    cache.base_packet = frag;
    cache.base_packet.is_fragment = false;
    cache.base_packet.data.clear();
    cache.fragments.resize(frag.fragment_total);
  }

  if (frag.fragment_index < frag.fragment_total) {
    cache.fragments[frag.fragment_index] = frag.data;
  }

  bool complete = true;
  for (const auto &fragment : cache.fragments) {
    if (fragment.empty()) {
      complete = false;
      break;
    }
  }

  if (complete) {
    reassemble_and_process(frag.fragment_id);
  }
}

void breeze_ipc::reassemble_and_process(size_t fragment_id) {
  auto it = fragment_cache_.find(fragment_id);
  if (it == fragment_cache_.end())
    return;

  auto &cache = it->second;
  for (const auto &frag : cache.fragments) {
    cache.base_packet.data += frag;
  }

  process_packet(
      std::move(deserialize<packet>(cache.base_packet.data).value()));

  fragment_cache_.erase(it);
}
} // namespace chromatic

================================================
FILE: ipc/ipc.h
================================================
#pragma once
#include "./shared_memory_ipc.h"
#include <atomic>
#include <condition_variable>
#include <deque>
#include <expected>
#include <functional>
#include <future>
#include <iostream>
#include <mutex>
#include <print>
#include <sstream>
#include <string>
#include <unordered_map>

#include "rfl.hpp"
#include "rfl/json.hpp"
#include "ylt/easylog.hpp"
#include "ylt/struct_pack.hpp"

#define WIN32_LEAN_AND_MEAN
#define NOMINMAX
#include "Windows.h"

namespace chromatic {
constexpr static bool use_struct_pack = false;
constexpr static bool print_packages = false;
constexpr static size_t MAX_PACKET_SIZE = 1024;

auto serialize = [](const auto &data) {
  if constexpr (use_struct_pack) {
    return struct_pack::serialize<std::string>(data);
  } else {
    return rfl::json::write(data);
  }
};

template <typename T> auto deserialize(const std::string &data) {
  if constexpr (use_struct_pack) {
    return struct_pack::deserialize<T>(data);
  } else {
    return rfl::json::read<T, rfl::NoExtraFields, rfl::DefaultIfMissing>(data);
  }
}

template <typename T>
concept StructPackSerializable = requires(T t) {
  { serialize(t) } -> std::same_as<std::string>;
  deserialize<T>(std::declval<std::string>());
};

struct test_serializable_struct {
  int a;
  float b;
  std::vector<char> c;
};

static_assert(StructPackSerializable<test_serializable_struct>,
              "test_struct should be StructPackSerializable");

struct breeze_ipc {
  struct packet {
    size_t seq;
    size_t return_for_call = 0;
    std::string name;
    std::string data;
    DWORD from_pid = 0;        // 发送方进程ID
    DWORD to_pid = 0;          // 接收方进程ID
    bool is_fragment = false;  // 是否是分包
    size_t fragment_id = 0;    // 分包ID
    size_t fragment_index = 0; // 分包索引
    size_t fragment_total = 0; // 总分包数
  };

  // 分包重组缓存
  struct fragment_cache {
    std::vector<std::string> fragments;
    std::chrono::steady_clock::time_point created_time;
    packet base_packet;
  };

  void connect(std::string_view name);

  inline size_t inc_seq() { return seq++; }
  inline size_t next_fragment_id() { return next_fragment_id_++; }

  // 发送包(可选择目标PID)
  void send(packet &&pkt, DWORD target_pid = 0) {
    pkt.to_pid = target_pid;

    pkt.from_pid = current_pid_;

    auto serialized = serialize(pkt);

    // 分包处理
    if (serialized.size() > MAX_PACKET_SIZE) {
      send_fragmented(pkt, serialized);
      return;
    }

    send_impl(serialized);
  }

  // 实现分包发送
  void send_fragmented(const packet &base_pkt, const std::string &full_data) {
    const size_t fragment_id = next_fragment_id();
    const size_t total_fragments =
        (full_data.size() + MAX_PACKET_SIZE - 1) / MAX_PACKET_SIZE;

    for (size_t i = 0; i < total_fragments; ++i) {
      const size_t start = i * MAX_PACKET_SIZE;
      const size_t end = std::min(start + MAX_PACKET_SIZE, full_data.size());

      packet fragment = base_pkt;
      fragment.is_fragment = true;
      fragment.fragment_id = fragment_id;
      fragment.fragment_index = i;
      fragment.fragment_total = total_fragments;
      fragment.data = full_data.substr(start, end - start);

      auto serialized_fragment = serialize(fragment);
      send_impl(serialized_fragment);
    }
  }

  // 实际发送实现
  void send_impl(const std::string &data) {

    if (!data.empty()) {
      if constexpr (print_packages) {
        if constexpr (use_struct_pack) {
          for (size_t i = 0; i < data.size(); ++i) {
            if (i % 16 == 0 && i != 0) {
              printf("\n");
            }
            char buf[3];
            snprintf(buf, sizeof(buf), "%02x ",
                     static_cast<unsigned char>(data[i]));
            WriteConsoleA(GetStdHandle(STD_OUTPUT_HANDLE), buf, 2, nullptr,
                          nullptr);
          }
        } else {
          if (GetConsoleWindow())
            WriteConsoleA(GetStdHandle(STD_OUTPUT_HANDLE), data.data(),
                          static_cast<DWORD>(data.size()), nullptr, nullptr);
        }
      }
      channel.send(data);
    }
  }

  bool poll();

  // 发送给特定PID
  template <StructPackSerializable T>
  void send(const std::string &name, const T &data, DWORD target_pid = 0) {
    send(
        packet{
            .seq = inc_seq(),
            .return_for_call = 0,
            .name = name,
            .data = serialize(data),
        },
        target_pid);
  }

  template <StructPackSerializable T>
  void broadcast(const std::string &name, const T &data) {
    send(packet{
        .seq = inc_seq(),
        .return_for_call = 0,
        .name = name,
        .data = serialize(data),
    });
  }

  struct listener_remover {
    breeze_ipc &ipc_instance;
    std::string name;
    std::function<void(const packet &)> &handler;
    void remove() {
      auto &handlers = ipc_instance.handlers;
      auto it = handlers.find(name);
      if (it != handlers.end()) {
        auto &handler_list = it->second;

        handler_list.remove_if(
            [&](const std::function<void(const packet &)> &h) {
              return &h == &handler;
            });
      }
    }
  };

  listener_remover add_listener(const std::string &name,
                                std::function<void(const packet &)> &&handler) {
    auto &h = handlers[name];
    h.emplace_back(std::move(handler));

    return listener_remover{*this, name, h.back()};
  }

  template <StructPackSerializable T>
  listener_remover add_listener(const std::string &name,
                                std::function<void(const T &)> &&handler) {
    return add_listener(
        name, [handler = std::move(handler)](const packet &pkt) {
          auto data = deserialize<T>(pkt.data);
          if (data.has_value()) {
            handler(data.value());
          } else {
            throw std::runtime_error("Failed to deserialize packet data");
          }
        });
  }

  template <StructPackSerializable RetVal, StructPackSerializable Arg>
  listener_remover
  add_call_handler(const std::string &name,
                   std::function<RetVal(const Arg &)> &&handler) {
    return add_listener("call_" + name, [this, handler = std::move(handler),
                                         name](const packet &pkt) {
      auto data = deserialize<Arg>(pkt.data);
      if (!data.has_value()) {
        throw std::runtime_error("Failed to deserialize call data for " + name);
      }
      auto result = handler(data.value());
      send(packet{.seq = inc_seq(),
                  .return_for_call = pkt.seq,
                  .name = "call_result_" + name,
                  .data = serialize(result),
                  .to_pid = pkt.from_pid});
    });
  }

  template <StructPackSerializable RetVal>
  listener_remover add_call_handler(const std::string &name,
                                    std::function<RetVal()> &&handler) {
    return add_call_handler<RetVal, bool>(
        name, [handler = std::move(handler)](bool) { return handler(); });
  }

  template <StructPackSerializable RetVal, StructPackSerializable R>
  std::future<RetVal> call(const std::string &name, const R &data,
                           DWORD target_pid = 0) {
    auto seq = inc_seq();
    auto promise = std::make_shared<std::promise<RetVal>>();
    call_handlers[seq] = [promise](const packet &pkt) {
      auto result = deserialize<RetVal>(pkt.data);
      if (result.has_value()) {
        promise->set_value(std::move(result.value()));
      } else {
        promise->set_exception(
            std::make_exception_ptr(std::runtime_error("Call failed")));
      }
    };

    send(packet{
        .seq = seq,
        .return_for_call = 0,
        .name = "call_" + name,
        .data = serialize(data),
        .to_pid = target_pid // 定向发送
    });

    return promise->get_future();
  }

  template <StructPackSerializable RetVal>
  std::future<RetVal> call(const std::string &name, DWORD target_pid = 0) {
    return call<RetVal, bool>(name, true, target_pid);
  }

  template <StructPackSerializable RetVal, StructPackSerializable R>
  std::optional<RetVal>
  call_and_poll(const std::string &name, const R &data, DWORD target_pid = 0,
                std::chrono::milliseconds timeout = std::chrono::seconds(5)) {
    auto future = call<RetVal, R>(name, data, target_pid);
    auto start = std::chrono::steady_clock::now();

    while (std::chrono::steady_clock::now() - start < timeout) {
      if (future.valid() && future.wait_for(std::chrono::milliseconds(0)) ==
                                std::future_status::ready) {
        return future.get();
      }
      poll();
    }
    return std::nullopt;
  }

  template <StructPackSerializable RetVal>
  std::optional<RetVal>
  call_and_poll(const std::string &name, DWORD target_pid = 0,
                std::chrono::milliseconds timeout = std::chrono::seconds(5)) {
    return call_and_poll<RetVal, bool>(name, true, target_pid, timeout);
  }

  ~breeze_ipc();

private:
  void process_packet(packet &&pkt);
  void process_fragment(const packet &frag);
  void reassemble_and_process(size_t fragment_id);

  std::unordered_map<std::string,
                     std::list<std::function<void(const packet &)>>>
      handlers;
  std::unordered_map<size_t, std::function<void(const packet &)>> call_handlers;
  ::ipc::Channel<> channel;
  std::atomic_size_t seq =
      1 + std::chrono::system_clock::now().time_since_epoch().count() / 1000 %
              1000000;
  std::atomic_size_t next_fragment_id_ = 1;
  std::atomic_bool exit_signal = false;
  std::thread ipc_thread;

  DWORD current_pid_ = ::GetCurrentProcessId();

  // 分包重组相关
  std::mutex fragment_mutex_;
  std::unordered_map<size_t, fragment_cache> fragment_cache_;
};
} // namespace chromatic

================================================
FILE: ipc/shared_memory_ipc.h
================================================
#pragma once

#include <print>
#if defined(_MSC_VER)
#pragma warning(push)
#pragma warning(disable : 4200)
#endif

#ifndef NOMINMAX
#define NOMINMAX
#endif

#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif

#include <aclapi.h>
#include <memoryapi.h>
#include <processthreadsapi.h>
#include <sddl.h>
#include <windows.h>
#include <winnt.h>

#include <atomic>
#include <chrono>
#include <memory>
#include <stdexcept>
#include <string>
#include <string_view>
#include <system_error>
#include <thread>
#include <vector>

namespace ipc {

class Exception : public std::runtime_error {
public:
  explicit Exception(const std::string &message)
      : std::runtime_error(message) {}
  explicit Exception(const char *message) : std::runtime_error(message) {}
};

namespace detail {

inline void throw_windows_error(const std::string &message) {
  DWORD error_code = ::GetLastError();
  throw ipc::Exception(message +
                       " (Windows Error: " + std::to_string(error_code) + ")");
}

class SidHolder {
public:
  SidHolder() : sid_buffer_() {}
  ~SidHolder() = default;
  bool CreateEveryone() {
    DWORD sid_size = 0;
    CreateWellKnownSid(WinWorldSid, nullptr, nullptr, &sid_size);
    if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
      return false;
    sid_buffer_.resize(sid_size);
    return !!CreateWellKnownSid(WinWorldSid, nullptr, Get(), &sid_size);
  }
  bool CreateUntrusted() {
    SID_IDENTIFIER_AUTHORITY mandatory_label_authority =
        SECURITY_MANDATORY_LABEL_AUTHORITY;
    DWORD sid_size = GetSidLengthRequired(1);
    sid_buffer_.resize(sid_size);
    if (!InitializeSid(Get(), &mandatory_label_authority, 1))
      return false;
    *(GetSidSubAuthority(Get(), 0)) = SECURITY_MANDATORY_UNTRUSTED_RID;
    return true;
  }
  PSID Get() {
    return sid_buffer_.empty() ? nullptr
                               : reinterpret_cast<PSID>(sid_buffer_.data());
  }
  DWORD GetLength() const { return static_cast<DWORD>(sid_buffer_.size()); }

private:
  std::vector<BYTE> sid_buffer_;
  SidHolder(const SidHolder &) = delete;
  SidHolder &operator=(const SidHolder &) = delete;
};

inline LPSECURITY_ATTRIBUTES get_sa() {
  static struct initiator {
    SECURITY_ATTRIBUTES sa_{};
    std::vector<BYTE> sd_buffer_;
    bool succ_ = false;
    initiator() {
      SidHolder everyone_sid;
      if (!everyone_sid.CreateEveryone())
        return;
      SidHolder untrusted_il_sid;
      if (!untrusted_il_sid.CreateUntrusted())
        return;
      const DWORD dacl_size =
          sizeof(ACL) + sizeof(ACCESS_ALLOWED_ACE) + everyone_sid.GetLength();
      std::vector<BYTE> dacl_buffer(dacl_size);
      PACL dacl = reinterpret_cast<PACL>(dacl_buffer.data());
      if (!InitializeAcl(dacl, dacl_size, ACL_REVISION))
        return;
      if (!AddAccessAllowedAce(dacl, ACL_REVISION,
                               SYNCHRONIZE | SEMAPHORE_ALL_ACCESS |
                                   EVENT_ALL_ACCESS | FILE_MAP_ALL_ACCESS,
                               everyone_sid.Get()))
        return;
      const DWORD sacl_size = sizeof(ACL) + sizeof(SYSTEM_MANDATORY_LABEL_ACE) +
                              untrusted_il_sid.GetLength();
      std::vector<BYTE> sacl_buffer(sacl_size);
      PACL sacl = reinterpret_cast<PACL>(sacl_buffer.data());
      if (!InitializeAcl(sacl, sacl_size, ACL_REVISION))
        return;
      if (!AddMandatoryAce(sacl, ACL_REVISION, 0,
                           SYSTEM_MANDATORY_LABEL_NO_WRITE_UP,
                           untrusted_il_sid.Get()))
        return;
      SECURITY_DESCRIPTOR sd_absolute = {0};
      if (!InitializeSecurityDescriptor(&sd_absolute,
                                        SECURITY_DESCRIPTOR_REVISION))
        return;
      if (!SetSecurityDescriptorDacl(&sd_absolute, TRUE, dacl, FALSE))
        return;
      if (!SetSecurityDescriptorSacl(&sd_absolute, TRUE, sacl, FALSE))
        return;
      DWORD sd_buffer_size = 0;
      MakeSelfRelativeSD(&sd_absolute, nullptr, &sd_buffer_size);
      if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
        return;
      sd_buffer_.resize(sd_buffer_size);
      PSECURITY_DESCRIPTOR sd_relative =
          reinterpret_cast<PSECURITY_DESCRIPTOR>(sd_buffer_.data());
      if (!MakeSelfRelativeSD(&sd_absolute, sd_relative, &sd_buffer_size))
        return;
      sa_.nLength = sizeof(sa_);
      sa_.lpSecurityDescriptor = sd_relative;
      sa_.bInheritHandle = FALSE;
      succ_ = true;
    }
  } handle;
  return handle.succ_ ? &handle.sa_ : nullptr;
}

struct MessageHeader {
  std::atomic<uint64_t> sequence{0};
  uint32_t data_size;
  bool is_first_fragment;
  bool is_last_fragment;
};

struct MessageSlot {
  MessageHeader header;
  char data[0];
};

struct ReaderSlot {

  std::atomic<DWORD> pid{0};

  std::atomic<uint64_t> sequence{0};
};

struct SharedMemoryHeader {

  std::atomic_flag write_lock = ATOMIC_FLAG_INIT;
  uint32_t capacity;
  uint32_t max_payload_size;
  uint32_t max_readers;

  std::atomic<uint64_t> write_index{0};

  std::atomic<uint64_t> sequence_generator{0};
};

} // namespace detail

template <size_t MaxReaders = 16> class Channel {
public:
  struct Config {
    size_t capacity = 128;
    size_t max_message_payload_size = 4096;
  };

  Channel() = default;
  ~Channel() { disconnect(); }
  Channel(const Channel &) = delete;
  Channel &operator=(const Channel &) = delete;
  Channel(Channel &&) = delete;
  Channel &operator=(Channel &&) = delete;

  void connect(const std::string &name, const Config &config = {}) {
    if (is_connected())
      throw Exception("Channel is already connected.");

    config_ = config;
    name_ = name;
    std::wstring shm_name =
        L"IPC_Channel_SHM_" + std::wstring(name.begin(), name.end());
    std::wstring event_name =
        L"IPC_Channel_EVT_" + std::wstring(name.begin(), name.end());
    LPSECURITY_ATTRIBUTES sa = detail::get_sa();
    if (!sa)
      throw Exception("Failed to get security attributes.");

    const size_t header_size = get_header_size();
    const size_t slot_size =
        sizeof(detail::MessageSlot) + config_.max_message_payload_size;
    const size_t total_shm_size = header_size + config_.capacity * slot_size;

    bool is_creator = false;
    h_map_file_ = ::CreateFileMappingW(
        INVALID_HANDLE_VALUE, sa, PAGE_READWRITE,
        static_cast<DWORD>(total_shm_size >> 32),
        static_cast<DWORD>(total_shm_size & 0xFFFFFFFF), shm_name.c_str());

    if (h_map_file_ == NULL)
      detail::throw_windows_error("CreateFileMappingW failed for " + name);

    if (::GetLastError() != ERROR_ALREADY_EXISTS)
      is_creator = true;

    p_shared_mem_ =
        ::MapViewOfFile(h_map_file_, FILE_MAP_ALL_ACCESS, 0, 0, total_shm_size);
    if (p_shared_mem_ == NULL) {
      disconnect();
      detail::throw_windows_error("MapViewOfFile failed for " + name);
    }

    p_header_ = static_cast<detail::SharedMemoryHeader *>(p_shared_mem_);

    p_buffer_start_ = reinterpret_cast<char *>(p_shared_mem_) + header_size;

    if (is_creator) {

      new (p_header_) detail::SharedMemoryHeader();
      p_header_->capacity = static_cast<uint32_t>(config_.capacity);
      p_header_->max_payload_size =
          static_cast<uint32_t>(config_.max_message_payload_size);
      p_header_->max_readers = static_cast<uint32_t>(MaxReaders);

      for (size_t i = 0; i < MaxReaders; ++i) {
        new (get_reader_slot(i)) detail::ReaderSlot();
      }

    } else {

      if (p_header_->max_readers != MaxReaders) {
        disconnect();
        throw Exception(
            "Connection failed: Mismatched MaxReaders configuration.");
      }
      if (p_header_->capacity != config_.capacity ||
          p_header_->max_payload_size != config_.max_message_payload_size) {

        disconnect();
        throw Exception("Connection failed: Mismatched capacity or "
                        "max_payload_size configuration.");
      }
    }

    if (is_creator) {
      h_data_ready_event_ = ::CreateEventW(sa, TRUE, FALSE, event_name.c_str());
      if (h_data_ready_event_ == NULL) {
        disconnect();
        detail::throw_windows_error("CreateEventW failed for " + name);
      }
    } else {
      h_data_ready_event_ = ::OpenEventW(SYNCHRONIZE | EVENT_MODIFY_STATE,
                                         FALSE, event_name.c_str());
      if (h_data_ready_event_ == NULL) {
        disconnect();
        detail::throw_windows_error("OpenEventW failed for " + name);
      }
    }

    register_reader();
  }

  void disconnect() {

    if (is_connected()) {
      deregister_reader();
    }

    if (p_shared_mem_ != nullptr) {
      ::UnmapViewOfFile(p_shared_mem_);
      p_shared_mem_ = nullptr;
    }
    if (h_map_file_ != NULL) {
      ::CloseHandle(h_map_file_);
      h_map_file_ = NULL;
    }
    if (h_data_ready_event_ != NULL) {
      ::CloseHandle(h_data_ready_event_);
      h_data_ready_event_ = NULL;
    }
    p_header_ = nullptr;
    p_buffer_start_ = nullptr;
    my_reader_slot_index_ = -1;
    name_.clear();
  }

  bool is_connected() const { return p_shared_mem_ != nullptr; }

  void send(const std::string &message) {
    if (!is_connected()) {
      throw Exception("Channel is not connected.");
    }

    const size_t max_payload = p_header_->max_payload_size;
    const size_t num_fragments =
        message.empty() ? 1
                        : (message.length() + max_payload - 1) / max_payload;
    const uint32_t capacity = p_header_->capacity;

    if (num_fragments > capacity) {
      throw Exception(
          "Message is too large to fit in the channel buffer capacity.");
    }

    std::string_view message_view(message);

    while (true) {

      while (p_header_->write_lock.test_and_set(std::memory_order_acquire)) {
        std::this_thread::yield();
      }

      const uint64_t write_idx =
          p_header_->write_index.load(std::memory_order_relaxed);

      uint64_t slowest_reader_seq = get_slowest_reader_sequence();

      if ((write_idx - slowest_reader_seq) + num_fragments > capacity) {

        p_header_->write_lock.clear(std::memory_order_release);
        std::this_thread::sleep_for(std::chrono::milliseconds(1));
        continue;
      }

      try {
        const uint64_t seq_gen_at_write_time =
            p_header_->sequence_generator.load(std::memory_order_relaxed);

        for (size_t i = 0; i < num_fragments; ++i) {
          uint64_t current_write_slot_idx = (write_idx + i) % capacity;
          detail::MessageSlot *slot = get_message_slot(current_write_slot_idx);

          size_t offset = i * max_payload;
          size_t chunk_size =
              message.empty()
                  ? 0
                  : std::min(message_view.length() - offset, max_payload);
          uint64_t new_sequence = seq_gen_at_write_time + i + 1;

          slot->header.data_size = static_cast<uint32_t>(chunk_size);
          slot->header.is_first_fragment = (i == 0);
          slot->header.is_last_fragment = (i == num_fragments - 1);
          if (chunk_size > 0) {
            memcpy(&slot->data, message_view.data() + offset, chunk_size);
          }

          slot->header.sequence.store(new_sequence, std::memory_order_release);
        }

        p_header_->write_index.fetch_add(num_fragments,
                                         std::memory_order_relaxed);
        p_header_->sequence_generator.fetch_add(num_fragments,
                                                std::memory_order_relaxed);

      } catch (...) {
        p_header_->write_lock.clear(std::memory_order_release);
        throw;
      }

      p_header_->write_lock.clear(std::memory_order_release);
      ::SetEvent(h_data_ready_event_);
      return;
    }
  }

  void receive(std::string &message) {
    if (!internal_try_receive(message, INFINITE)) {
      throw Exception(
          "receive failed. The wait handle may be invalid or closed.");
    }
  }

  bool try_receive(std::string &message) {
    return internal_try_receive(message, 0);
  }

private:
  bool internal_try_receive(std::string &message, DWORD timeout_ms) {
    if (!is_connected())
      throw Exception("Channel is not connected.");
    if (my_reader_slot_index_ < 0)
      throw Exception("Reader is not registered.");

    std::string reassembly_buffer;
    bool in_reassembly = false;

    while (true) {

      while (true) {
        uint64_t next_expected_seq = local_read_sequence_ + 1;
        detail::MessageSlot *found_slot = nullptr;

        uint64_t probable_idx =
            (p_header_->write_index.load(std::memory_order_relaxed) - 1) %
            p_header_->capacity;
        probable_idx = (local_read_sequence_) % p_header_->capacity;

        detail::MessageSlot *candidate_slot = get_message_slot(probable_idx);
        if (candidate_slot->header.sequence.load(std::memory_order_acquire) ==
            next_expected_seq) {
          found_slot = candidate_slot;
        } else {

          for (uint32_t i = 0; i < p_header_->capacity; ++i) {
            detail::MessageSlot *current_slot = get_message_slot(i);
            uint64_t slot_sequence =
                current_slot->header.sequence.load(std::memory_order_relaxed);
            if (slot_sequence == next_expected_seq) {
              found_slot = current_slot;
              break;
            }
          }
        }

        if (found_slot) {

          if (found_slot->header.is_first_fragment) {
            if (in_reassembly)
              reassembly_buffer.clear();
            in_reassembly = true;
          } else if (!in_reassembly) {
            local_read_sequence_++;
            update_reader_progress();
            continue;
          }

          reassembly_buffer.append(found_slot->data,
                                   found_slot->header.data_size);
          local_read_sequence_++;

          if (found_slot->header.is_last_fragment) {
            message = std::move(reassembly_buffer);
            in_reassembly = false;
            update_reader_progress();
            return true;
          }
        } else {

          break;
        }
      }

      ::ResetEvent(h_data_ready_event_);

      if (p_header_->sequence_generator.load(std::memory_order_acquire) >
          local_read_sequence_) {
        continue;
      }

      DWORD wait_result =
          ::WaitForSingleObject(h_data_ready_event_, timeout_ms);
      if (wait_result == WAIT_OBJECT_0) {
        continue;
      } else if (wait_result == WAIT_TIMEOUT) {
        return false;
      } else {
        detail::throw_windows_error(
            "WaitForSingleObject failed on ipc::Channel '" + name_ + "'");
      }
    }
  }

  static constexpr size_t get_header_size() {
    return sizeof(detail::SharedMemoryHeader) +
           MaxReaders * sizeof(detail::ReaderSlot);
  }

  detail::ReaderSlot *get_reader_slot(size_t index) const {
    char *base = static_cast<char *>(p_shared_mem_);
    return reinterpret_cast<detail::ReaderSlot *>(
        base + sizeof(detail::SharedMemoryHeader) +
        index * sizeof(detail::ReaderSlot));
  }

  detail::MessageSlot *get_message_slot(uint64_t index) const {
    const size_t slot_size =
        sizeof(detail::MessageSlot) + config_.max_message_payload_size;
    return reinterpret_cast<detail::MessageSlot *>(p_buffer_start_ +
                                                   index * slot_size);
  }

  inline static std::atomic_int instance_count;
  int current_instance_index_ = instance_count++;
  int current_instance_id_ =
      (::GetCurrentProcessId() << 16) + current_instance_index_;

  static bool is_pid_alive(DWORD pid) {
    HANDLE h_process = ::OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pid);
    if (h_process == NULL) {
      return false;
    }
    ::CloseHandle(h_process);
    return true;
  }

  void register_reader() {
    uint64_t current_global_seq =
        p_header_->sequence_generator.load(std::memory_order_relaxed);

    for (size_t i = 0; i < MaxReaders; ++i) {
      detail::ReaderSlot *slot = get_reader_slot(i);
      DWORD expected_pid = 0;

      if (slot->pid.compare_exchange_strong(expected_pid, current_instance_id_,
                                            std::memory_order_acq_rel)) {
        my_reader_slot_index_ = static_cast<int>(i);

        local_read_sequence_ = current_global_seq;
        slot->sequence.store(current_global_seq, std::memory_order_release);
        return;
      }
    }

    disconnect();
    throw Exception("Failed to register reader: Maximum number of concurrent "
                    "readers reached for channel '" +
                    name_ + "'.");
  }

  void deregister_reader() {
    if (my_reader_slot_index_ >= 0) {
      detail::ReaderSlot *slot = get_reader_slot(my_reader_slot_index_);
      slot->pid.store(0, std::memory_order_release);
      my_reader_slot_index_ = -1;
    }
  }

  void update_reader_progress() {
    if (my_reader_slot_index_ >= 0) {
      get_reader_slot(my_reader_slot_index_)
          ->sequence.store(local_read_sequence_, std::memory_order_release);
    }

    uint64_t now = std::chrono::system_clock::now().time_since_epoch().count();
    if (now - last_clean_time_ > clean_interval_ms) {
      clean_dead_readers();
      last_clean_time_ = now;
    }
  }

  uint64_t get_slowest_reader_sequence() const {
    uint64_t slowest_seq =
        p_header_->write_index.load(std::memory_order_relaxed);
    bool reader_found = false;

    for (size_t i = 0; i < MaxReaders; ++i) {
      const detail::ReaderSlot *slot = get_reader_slot(i);
      auto pid = slot->pid.load(std::memory_order_acquire);
      if (pid != 0 && pid != current_instance_id_) {
        uint64_t reader_seq = slot->sequence.load(std::memory_order_acquire);
        if (!reader_found) {
          slowest_seq = reader_seq;
          reader_found = true;
        } else {
          slowest_seq = std::min(slowest_seq, reader_seq);
        }
      }
    }

    return slowest_seq;
  }

  void clean_dead_readers() {
    for (size_t i = 0; i < MaxReaders; ++i) {
      detail::ReaderSlot *slot = get_reader_slot(i);
      DWORD pid = slot->pid.load(std::memory_order_acquire);
      if (pid != 0 && !is_pid_alive(pid)) {

        slot->pid.store(0, std::memory_order_release);
        slot->sequence.store(0, std::memory_order_release);
      }
    }
  }

  uint64_t last_clean_time_ = 0;
  static constexpr uint64_t clean_interval_ms = 100;
  Config config_;
  std::string name_;
  HANDLE h_map_file_ = NULL;
  HANDLE h_data_ready_event_ = NULL;
  void *p_shared_mem_ = nullptr;
  detail::SharedMemoryHeader *p_header_ = nullptr;
  char *p_buffer_start_ = nullptr;

  uint64_t local_read_sequence_ = 0;
  int my_reader_slot_index_ = -1;
};

} // namespace ipc

#if defined(_MSC_VER)
#pragma warning(pop)
#endif


================================================
FILE: scripts/bindgen.bat
================================================
npx breeze-bindgen@latest -i src/script/bindings/binding_types.h --nameFilter chromatic::js -o src/script/bindings --tsModuleName chromatic

================================================
FILE: scripts/rebuild.ps1
================================================
$targetPath = "C:\Program Files\Tencent\QQNT-dev\QQ.exe"

#  kill the process if it is running
foreach ($process in Get-Process -ErrorAction SilentlyContinue) {
    if ($process.Path -eq $targetPath) {
        Stop-Process -Id $process.Id -Force || Write-Host "Failed to stop process: $($process.Id) - $($process.Name)"
        Write-Host "Killed process: $($process.Id) - $($process.Name)"
    }
}

xmake b chromatic
Start-Process -FilePath $targetPath -WorkingDirectory "C:\Program Files\Tencent\QQNT-dev" -NoNewWindow

================================================
FILE: src/config.cc
================================================
#include "config.h"
#include <chrono>
#include <filesystem>
#include <fstream>
#include <mutex>
#include <thread>

#include "rfl.hpp"
#include "rfl/DefaultIfMissing.hpp"
#include "rfl/json.hpp"
#include "ylt/easylog.hpp"


#include "utils.h"
#include "windows.h"

namespace chromatic {
std::unique_ptr<config> config::current;
std::vector<std::function<void()>> config::on_reload;

void config::write_config() {
  auto config_file = data_directory() / "config.json";
  std::ofstream ofs(config_file);
  if (!ofs) {
    std::cerr << "Failed to write config file." << std::endl;
    return;
  }

  ofs << rfl::json::write(*config::current);
}
void config::read_config() {
  auto config_file = data_directory() / "config.json";

#ifdef __llvm__
  std::ifstream ifs(config_file);
  if (!std::filesystem::exists(config_file)) {
    auto config_file = data_directory() / "config.json";
    std::ofstream ofs(config_file);
    if (!ofs) {
      std::cerr << "Failed to write config file." << std::endl;
    }

    ofs << R"({
})";
  }
  if (!ifs) {
    std::cerr
        << "Config file could not be opened. Using default config instead."
        << std::endl;
    config::current = std::make_unique<config>();
    config::current->debug_console = true;
  } else {
    std::string json_str;
    std::copy(std::istreambuf_iterator<char>(ifs),
              std::istreambuf_iterator<char>(), std::back_inserter(json_str));

    if (auto json =
            rfl::json::read<config, rfl::NoExtraFields, rfl::DefaultIfMissing>(
                json_str)) {
      config::current = std::make_unique<config>(json.value());
    } else {
      std::cerr << "Failed to read config file: " << json.error().what()
                << "\nUsing default config instead." << std::endl;
      config::current = std::make_unique<config>();
      config::current->debug_console = true;
    }
  }

  for (auto &fn : config::on_reload) {
    try {
      fn();
    } catch (const std::exception &e) {
      ELOGFMT(WARN, "Failed to run on_reload function: {}", e.what());
    }
  }
#else
#pragma message                                                                \
    "We don't support loading config file on MSVC because of a bug in MSVC."
  dbgout("We don't support loading config file when compiled with MSVC "
         "because of a bug in MSVC.");
  config::current = std::make_unique<config>();
  config::current->debug_console = true;
#endif

  if (config::current->debug_console) {
    ShowWindow(GetConsoleWindow(), SW_SHOW);
  } else {
    ShowWindow(GetConsoleWindow(), SW_HIDE);
  }
}

std::filesystem::path config::data_directory() {
  static std::optional<std::filesystem::path> path;
  static std::mutex mtx;
  std::lock_guard lock(mtx);

  if (!path) {
    path = std::filesystem::path(utils::env("USERPROFILE").value()) /
           ".chromatic" / utils::current_executable_path().filename().string();
  }

  if (!std::filesystem::exists(*path)) {
    std::filesystem::create_directories(*path);
  }

  return path.value();
}
void config::run_config_loader() {
  auto config_path = config::data_directory() / "config.json";
  ELOGFMT(INFO, "config file: {}", config_path.string());
  config::read_config();
  std::thread([config_path]() {
    auto last_mod = std::filesystem::last_write_time(config_path);
    while (true) {
      if (std::filesystem::last_write_time(config_path) != last_mod) {
        last_mod = std::filesystem::last_write_time(config_path);
        config::read_config();
      }
      std::this_thread::sleep_for(std::chrono::milliseconds(100));
    }
  }).detach();
}
std::string config::dump_config() {
  if (!current) {
    return "{}";
  }
  return rfl::json::write(*current);
}
} // namespace chromatic


================================================
FILE: src/config.h
================================================
#pragma once

#include <filesystem>
#include <functional>
#include <memory>
#include <numbers>
#include <vector>

namespace chromatic {

struct config {
  bool debug_console = true;

  struct detector {
    struct chrome {
      bool enable = true;
      std::string chrome_module_name = "";
    } chrome;
  } detector;

  std::string $schema;

  static std::unique_ptr<config> current;
  static void read_config();
  static void write_config();
  static void run_config_loader();
  static std::string dump_config();
  static std::vector<std::function<void()>> on_reload;

  static std::filesystem::path data_directory();
};
} // namespace chromatic

================================================
FILE: src/context.cc
================================================
#include "context.h"

#include "config.h"
#include "cpptrace/basic.hpp"
#include "utils.h"
#include "ylt/easylog.hpp"

#include "cpptrace/cpptrace.hpp"
#include "cpptrace/from_current.hpp"

#include "Windows.h"
#include "blook/blook.h"
#include <debugapi.h>
#include <fstream>
#include <thread>
#include <unordered_map>

#include "rfl.hpp"
#include "rfl/json.hpp"

#include "./hooks/blink_parse_html_manipulator.h"
#include "./hooks/disable-integrity.h"
#include "./hooks/wait_for_module_load.h"

namespace chromatic {
std::unique_ptr<context> context::current = nullptr;

void context::init_singleton() {
  SetUnhandledExceptionFilter(+[](EXCEPTION_POINTERS *ep) -> long {
    ELOGFMT(FATAL, "Unhandled exception: {}", cpptrace::stacktrace::current());
    Sleep(1000);
    return EXCEPTION_CONTINUE_SEARCH;
  });

  CPPTRACE_TRY {
    if (!current) {
      current = std::make_unique<context>();
      current->init_context();
    }
  }
  CPPTRACE_CATCH(const std::exception &e) {
    ELOGFMT(ERROR, "Failed to initialize context: {} {}", e.what(),
            cpptrace::from_current_exception());
    Sleep(1000);
  }
  catch (...) {
    ELOGFMT(ERROR, "Failed to initialize context: unknown exception: {}",
            cpptrace::from_current_exception());
    Sleep(1000);
  }
}
context::context() {}

void context::detect_process_type() {
  auto cmdline = std::wstring(GetCommandLineW());

  auto &cfg = *config::current.get();
  if (cfg.detector.chrome.enable) {
    auto chrome_module = config::current->detector.chrome.chrome_module_name;

    if (cmdline.find(L"--type=gpu") != std::wstring::npos) {
      type.chrome_type = process_type::chrome_type::gpu;
    } else if (cmdline.find(L"--type=renderer") != std::wstring::npos) {
      type.chrome_type = process_type::chrome_type::renderer;
    } else if (cmdline.find(L"--type=utility") != std::wstring::npos) {
      type.chrome_type = process_type::chrome_type::utility;
    } else if (cmdline.find(L"--type=network") != std::wstring::npos) {
      type.chrome_type = process_type::chrome_type::network;
    } else if (cmdline.find(L"--type=") == std::wstring::npos) {
      type.chrome_type = process_type::chrome_type::main;
    }

    if (type.chrome_type) {
      ELOGFMT(INFO, "Detected Chrome process type: {}",
              static_cast<int>(type.chrome_type.value()));
    } else {
      ELOGFMT(WARN, "Failed to detect Chrome process type.");
    }

    auto proc = blook::Process::self();
    if (chrome_module == "") {
      std::shared_ptr<blook::Module> chrome_mod;
      if (auto mod = proc->module("chrome.dll")) {
        chrome_mod = mod.value();
      } else if (auto mod = proc->module("edge.dll")) {
        chrome_mod = mod.value();
      } else if (auto mod = proc->module("libcef.dll")) {
        chrome_mod = mod.value();
      } else if (auto mod = proc->process_module()) {
        chrome_mod = mod.value();
      }

      // verify if the module is actually chrome
      constexpr auto chrome_signature =
          "\\content\\browser\\renderer_host\\debug_urls.cc";
      if (chrome_mod && chrome_mod->section(".rdata") &&
          chrome_mod->section(".rdata")->find_one(chrome_signature)) {
        type.chrome_module = chrome_mod;
      } else {
        type.chrome_module = {};
      }

      if (type.chrome_module) {
        on_before_chrome_startup();
      }
    } else {
      if (GetModuleHandleW(utils::utf8_to_wstring(chrome_module).c_str())) {
        type.chrome_module =
            proc->module(
                    std::filesystem::path(chrome_module).filename().string())
                .value();

        on_before_chrome_startup();
      } else {
        ELOGFMT(WARN, "Chrome module {} not found, waiting for it to load...",
                chrome_module);

        hooks::wait_for_module_load::wait_for_module(
            chrome_module,
            [this](void *mod) {
              if (mod) {
                ELOGFMT(INFO, "Chrome module {} loaded", mod);
                type.chrome_module =
                    blook::Process::self()
                        ->module(
                            utils::get_module_path(mod).filename().string())
                        .value();

                auto entry_hook =
                    type.chrome_module->entry_point()->inline_hook();
                entry_hook->install(
                    [this, entry_hook](size_t a, size_t b, size_t c) {
                      on_before_chrome_startup();
                      return entry_hook->call_trampoline<size_t>(a, b, c);
                    });
              } else {
                ELOGFMT(ERROR, "Failed to load Chrome module");
              }
            })
            .wait();
      }
    }

    if (type.chrome_module) {
      ELOGFMT(
          INFO, "Detected Chrome module: {}",
          utils::get_module_path(type.chrome_module->base().data()).string());
    } else {
      ELOGFMT(WARN, "Chrome module not found, some features may not work.");
    }
  }
}
void context::init_ipc() {
  //   process_ipc.connect(std::format(
  //       "chromatic://process/{}",
  //       std::hash<std::string>{}(utils::current_executable_path().string())));
  process_ipc.connect("chromatic://process/");
}
void context::on_before_chrome_startup() {
  ELOGFMT(INFO, "on_before_chrome_startup called");
  blink_parse_html_manipulator::install();
}
void context::init_context() {
  auto cmdline = std::wstring(GetCommandLineW());

  ELOGFMT(INFO, "Command line: {}", utils::wstring_to_utf8(cmdline));
  bool is_probably_main = cmdline.find(L"--type=") == std::wstring::npos,
       is_renderer = cmdline.find(L"--type=renderer") != std::wstring::npos;
  if (!is_probably_main && !is_renderer) {
    ELOGFMT(INFO, "Chromatic is not running in this process.");
    return;
  }

  init_ipc();

  if (is_probably_main) {
    DWORD mode;
    AllocConsole();
    freopen("CONOUT$", "w", stdout);
    freopen("CONOUT$", "w", stderr);

    static HANDLE h = GetStdHandle(STD_OUTPUT_HANDLE);
    GetConsoleMode(h, &mode);
    SetConsoleMode(h, mode | ENABLE_VIRTUAL_TERMINAL_PROCESSING);

    static auto log_msg_raw = [](const auto &msg) {
      std::string msg_formatted =
          std::format("\033[47;30m chromatic \033[0m {}", msg);

      msg_formatted.erase(
          std::find_if(msg_formatted.rbegin(), msg_formatted.rend(),
                       [](unsigned char ch) { return !std::isspace(ch); })
              .base(),
          msg_formatted.end());
      msg_formatted += "\n";
      WriteConsoleA(h, msg_formatted.c_str(),
                    static_cast<DWORD>(msg_formatted.size()), nullptr, nullptr);
    };

    easylog::add_appender(log_msg_raw);

    hooks::windows::disable_integrity();

    config::run_config_loader();
    config::on_reload.push_back([this]() {
      ELOGFMT(INFO, "Config reloaded, broadcasting to other processes.");
      process_ipc.send("config_reload", *config::current);
    });

    ELOGFMT(INFO, "Chromatic v0.0.0, initialized as main process.");

    process_ipc.send("config_reload", *config::current);

    process_ipc.add_call_handler<config>("get_config",
                                         []() { return *config::current; });

    process_ipc.add_call_handler<bool, std::string>(
        "log", [](const std::string &msg) {
          log_msg_raw("[other_proc] " + msg);
          return true;
        });

    std::thread([this]() {
      detect_process_type();
      script = std::make_unique<script_engine>();

      static std::unordered_map<std::string, std::pair<size_t, int32_t>>
          symbol_cache;

      auto symbols_file = config::data_directory() / "symbols.json";
      if (std::filesystem::exists(symbols_file)) {
        try {
          std::ifstream ifs(symbols_file, std::ios::binary);
          if (ifs) {
            symbol_cache = rfl::json::read<std::unordered_map<
                std::string, std::pair<size_t, int32_t>>>(ifs)
                               .value();
          }
        } catch (const std::exception &e) {
          ELOGFMT(ERROR, "Failed to read symbols from {}: {}",
                  symbols_file.string(), e.what());
        }
      }

      process_ipc.add_call_handler<
          bool, std::pair<std::string, std::pair<size_t, int32_t>>>(
          "set_symbol", [](auto &symbol) {
            symbol_cache[symbol.first] = symbol.second;
            std::ofstream ofs(config::data_directory() / "symbols.json",
                              std::ios::binary | std::ios::trunc);
            if (ofs) {
              ofs << rfl::json::write(symbol_cache);
            }
            return true;
          });

      process_ipc.add_call_handler<std::pair<size_t, int32_t>, std::string>(
          "get_symbol", [](const std::string &name) {
            auto it = symbol_cache.find(name);
            if (it != symbol_cache.end()) {
              return it->second;
            }
            return std::pair<size_t, int32_t>{0, 0};
          });

      blink_parse_html_manipulator::register_js();
    }).detach();
  } else if (cmdline.find(L"--type=renderer") != std::wstring::npos) {
    easylog::add_appender([this](std::string_view msg) {
      process_ipc.call<bool, std::string>("log", std::string(msg));
    });

    ELOGFMT(INFO, "requesting config from main process.");
    process_ipc.add_listener<config>("config_reload", [](const config &cfg) {
      ELOGFMT(INFO, "Received config_reload");
      config::current = std::make_unique<config>(cfg);
    });
    process_ipc.call<config>("get_config");
    process_ipc.send(breeze_ipc::packet {
      .seq = 1,
      .return_for_call = 0,
      .name = "call_get_config",
      .data = "true"
    });
    auto p = process_ipc.call_and_poll<config>("get_config");
    if (p) {
      config::current = std::make_unique<config>(p.value());
    } else {
      ELOGFMT(WARN, "Failed to get config from main process, using default.");
      config::current = std::make_unique<config>();
    }

    ELOGFMT(INFO, "Chromatic v0.0.0, initialized as renderer process.");

    ELOGFMT(INFO, "Config loaded: {}", config::current->dump_config());

    detect_process_type();
  }
}
} // namespace chromatic

================================================
FILE: src/context.h
================================================
#pragma once

#include "blook/module.h"
#include "config.h"
#include "script/script.h"
#include <memory>
#include <string>

#include "ipc.h"

namespace chromatic {
struct context {
  static std::unique_ptr<context> current;

  static void init_singleton();

  struct process_type {
    enum chrome_type { main, renderer, gpu, utility, network };

    std::optional<chrome_type> chrome_type = {};
    std::shared_ptr<blook::Module> chrome_module = {};
  };

  process_type type = {};
  
  breeze_ipc process_ipc;
  std::unique_ptr<script_engine> script = nullptr;

  void init_ipc();
  void init_context();

  context();

  void on_before_chrome_startup();

private:
  void detect_process_type();
};
} // namespace chromatic

================================================
FILE: src/entry.cc
================================================
#include <algorithm>
#include <print>
#include <ranges>
#include <string>
#include <thread>

#include "blook/blook.h"

#include "config.h"
#include "context.h"
#include "ylt/easylog.hpp"

#include "utils.h"

#define NOMINMAX
#define WIN32_LEAN_AND_MEAN
#include "Windows.h"

namespace chromatic {
int main() {
  easylog::init_log(easylog::Severity::INFO, "", false, false);

  easylog::add_appender(
      [](std::string_view msg) { OutputDebugStringA(msg.data()); });

  context::init_singleton();
  return 0;
}

} // namespace chromatic

int APIENTRY DllMain(HINSTANCE hInstance, DWORD fdwReason, LPVOID lpvReserved) {
  switch (fdwReason) {
  case DLL_PROCESS_ATTACH: {
    auto cmdline = std::string(GetCommandLineA());

    if (cmdline.contains("--type=gpu")) {
      return 1; // Skip if this is a gpu process
    }

    chromatic::main();
    break;
  }
  }
  return 1;
}

================================================
FILE: src/hooks/blink_parse_html_manipulator.cc
================================================
#include "blink_parse_html_manipulator.h"

#include "../context.h"
#include "../utils.h"
#include "blook/function.h"
#include "ylt/easylog.hpp"
#include <chrono>
#include <debugapi.h>
#include <future>
#include <thread>

#include "blook/blook.h"
#define NOMINMAX
#define WIN32_LEAN_AND_MEAN
#include "Windows.h"

#include "../script/bindings/binding_types.h"

extern std::list<std::function<std::string(std::string)>>
    blink_parse_html_manipulators;

namespace chromatic {
struct BlinkHTMLData {
  const std::span<char> &data;
  std::optional<std::vector<char>> replacement;
};

struct BlinkUtilSpan {
  char *data;
  size_t size;
};

void blink_parse_html_manipulator::install() {
  if (context::current->type.chrome_type != context::process_type::renderer ||
      !context::current->type.chrome_module) {
    return;
  }

  ELOGFMT(INFO, "BlinkParseHTMLManipulator: Checking for cached symbol "
                "HTMLParser__AppendBytes");

  auto &chrome = context::current->type.chrome_module;

  auto rdata = chrome->section(".rdata").value();
  auto text = chrome->section(".text").value();

  auto crc32 = text.crc32();

  static std::optional<blook::Function> HTMLParser__AppendBytes = {};
  if (auto res = context::current->process_ipc
                     .call_and_poll<std::pair<size_t, int32_t>>(
                         "get_symbol", std::string("HTMLParser__AppendBytes"));
      res && res->first != 0 && res->second == crc32) {
    HTMLParser__AppendBytes = text.add(res->first).as_function();
    ELOGFMT(INFO,
            "BlinkParseHTMLManipulator: Using cached symbol "
            "HTMLParser__AppendBytes at {}",
            HTMLParser__AppendBytes->data());
  } else {
    auto appendBytesText = rdata.find_one("HTMLDocumentParser::appendBytes");
    if (!appendBytesText) {
      ELOGFMT(WARN,
              "BlinkParseHTMLManipulator: HTMLDocumentParser::appendBytes not "
              "found in rdata section");
      return;
    }

    ELOGFMT(INFO,
            "BlinkParseHTMLManipulator: Found HTMLDocumentParser::appendBytes "
            "string at {} in rdata section",
            appendBytesText.value().data());

    auto xref = text.find_xref(appendBytesText.value());

    if (!xref) {
      ELOGFMT(WARN,
              "BlinkParseHTMLManipulator: HTMLDocumentParser::appendBytes xref "
              "not found in text section");
      return;
    }

    ELOGFMT(INFO,
            "BlinkParseHTMLManipulator: Found HTMLDocumentParser::appendBytes "
            "function at {} in text section",
            xref->data());

    HTMLParser__AppendBytes =
        xref->find_upwards({0x56, 0x57}).value().as_function();

    context::current->process_ipc
        .call<bool, std::pair<std::string, std::pair<size_t, int32_t>>>(
            "set_symbol",
            std::pair(
                std::string("HTMLParser__AppendBytes"),
                std::pair(
                    (size_t)(HTMLParser__AppendBytes->pointer() - text).data(),
                    crc32)));
  }

  static auto HTMLParser__AppendBytes_Hook =
      HTMLParser__AppendBytes->inline_hook();

  const auto pFunc = (uint8_t *)HTMLParser__AppendBytes->data();

  if (pFunc[0] == 0x56 && pFunc[1] == 0x57 && pFunc[2] == 0x53) {
    ELOGFMT(INFO, "BlinkParseHTMLManipulator: Using older function signature");
    HTMLParser__AppendBytes_Hook->install(+[](void *self, uint8_t *data,
                                              size_t size) {
      ELOGFMT(DEBUG, "BlinkParseHTMLManipulator: Hook called with {} bytes",
              size);
      auto span_data = std::span<char>(reinterpret_cast<char *>(data), size);
      std::vector<std::shared_ptr<std::any>> contexts;
      BlinkHTMLData html_data{.data = span_data, .replacement = {}};

      auto res = context::current->process_ipc.call_and_poll<std::string>(
          "on_blink_parse_html_manipulate",
          std::string(html_data.data.data(), html_data.data.size()));

      if (res.has_value() &&
          res.value() !=
              std::string_view(html_data.data.data(), html_data.data.size())) {
        ELOGFMT(
            DEBUG,
            "BlinkParseHTMLManipulator: HTML content modified, new size: {}",
            res.value().size());
        html_data.replacement =
            std::vector<char>(res.value().begin(), res.value().end());
      }

      auto ret = html_data.replacement.has_value()
                     ? HTMLParser__AppendBytes_Hook->call_trampoline<void *>(
                           self, html_data.replacement->data(),
                           html_data.replacement->size())
                     : HTMLParser__AppendBytes_Hook->call_trampoline<void *>(
                           self, data, size);
      return ret;
    });
  } else {
    ELOGFMT(INFO, "BlinkParseHTMLManipulator: Using newer function signature");
    HTMLParser__AppendBytes_Hook->install(+[](void *self, BlinkUtilSpan &data) {
      ELOGFMT(DEBUG, "BlinkParseHTMLManipulator: Hook called with {} bytes",
              data.size);
      auto span_data =
          std::span<char>(reinterpret_cast<char *>(data.data), data.size);
      std::vector<std::shared_ptr<std::any>> contexts;
      BlinkHTMLData html_data{.data = span_data, .replacement = {}};

      auto html = std::string(html_data.data.data(), html_data.data.size());
      if (auto res = context::current->process_ipc
                         .call<std::string, std::string>(
                             "on_blink_parse_html_manipulate", html)
                         .get();
          res != html) {
        ELOGFMT(
            DEBUG,
            "BlinkParseHTMLManipulator: HTML content modified, new size: {}",
            res.size());
        html_data.replacement = std::vector<char>(res.begin(), res.end());
      }

      auto blink_span =
          html_data.replacement.has_value()
              ? BlinkUtilSpan{reinterpret_cast<char *>(
                                  html_data.replacement->data()),
                              html_data.replacement->size()}
              : BlinkUtilSpan{reinterpret_cast<char *>(span_data.data()),
                              span_data.size()};

      auto ret = HTMLParser__AppendBytes_Hook->call_trampoline<void *>(
          self, blink_span);
      return ret;
    });
  }

  context::current->process_ipc.add_call_handler<bool>(
      "is_blink_parse_html_manipulator_available", []() { return true; });

  ELOGFMT(INFO,
          "BlinkParseHTMLManipulator: Installation completed successfully");
}

bool blink_parse_html_manipulator::is_available() {
  auto result = context::current->process_ipc.call<bool>(
      "is_blink_parse_html_manipulator_available");
  if (result.valid() && result.wait_for(std::chrono::milliseconds(20)) ==
                            std::future_status::ready) {
    return true;
  } else {
    ELOGFMT(
        DEBUG,
        "BlinkParseHTMLManipulator: Availability check failed or timed out");
    return false;
  }
}

void blink_parse_html_manipulator::register_js() {
  ELOGFMT(INFO, "BlinkParseHTMLManipulator: Registering JavaScript handlers");

  context::current->process_ipc.add_call_handler<
      std::string,
      std::string>("on_blink_parse_html_manipulate", [](const std::string
                                                            &_html) {
    auto html = _html;
    size_t manipulator_count = 0;

    for (auto &manipulator : blink_parse_html_manipulators) {
      try {
        if (auto res = manipulator(html); !res.empty()) {
          html = res;
        }
      } catch (const std::exception &e) {
        ELOGFMT(ERROR,
                "BlinkParseHTMLManipulator: Exception in manipulator {}: {}",
                manipulator_count, e.what());
      } catch (...) {
        ELOGFMT(
            ERROR,
            "BlinkParseHTMLManipulator: Unknown exception in manipulator {}",
            manipulator_count);
      }
      manipulator_count++;
    }

    if (manipulator_count > 0) {
      ELOGFMT(INFO, "BlinkParseHTMLManipulator: Processed {} manipulators",
              manipulator_count);
    }

    return html;
  });

  context::current->script->ctx.on_bind.push_back([]() {
    ELOGFMT(DEBUG,
            "BlinkParseHTMLManipulator: Clearing manipulators on script bind");
    blink_parse_html_manipulators.clear();
  });
}
} // namespace chromatic


================================================
FILE: src/hooks/blink_parse_html_manipulator.h
================================================
#pragma once
#include <functional>
#include <list>
#include <memory>

namespace chromatic {
    struct blink_parse_html_manipulator {
      static void install();
      static bool is_available();
      static void register_js();
    };
}

================================================
FILE: src/hooks/disable-integrity.cc
================================================
#include "disable-integrity.h"
#include "blook/blook.h"

#include "Windows.h"
#include <memory>

#include "processthreadsapi.h"
bool chromatic::hooks::windows::disable_integrity() {
  static std::shared_ptr<blook::InlineHook> disable_integrity_hook;
  auto func = (blook::Pointer)(void *)GetProcAddress(
      LoadLibraryA("Kernel32.dll"), "UpdateProcThreadAttribute");

  if (!func) {
    return false;
  }

  disable_integrity_hook = func.as_function().inline_hook();
  disable_integrity_hook->install((
      void *)+[](LPPROC_THREAD_ATTRIBUTE_LIST lpAttributeList, DWORD dwFlags,
                 DWORD_PTR Attribute, PVOID lpValue, SIZE_T cbSize,
                 PVOID lpPreviousValue, PSIZE_T lpReturnSize) {
    if (Attribute == PROC_THREAD_ATTRIBUTE_MITIGATION_POLICY &&
        cbSize >= sizeof(DWORD64)) {
      PDWORD64 old_policy = &((PDWORD64)lpValue)[0];
      *old_policy &= ~(
          DWORD64)(PROCESS_CREATION_MITIGATION_POLICY_BLOCK_NON_MICROSOFT_BINARIES_ALWAYS_ON);
      *old_policy &=
          (DWORD64)(PROCESS_CREATION_MITIGATION_POLICY_WIN32K_SYSTEM_CALL_DISABLE_ALWAYS_ON);
    }
    return disable_integrity_hook
        ->trampoline_t<int64_t(LPPROC_THREAD_ATTRIBUTE_LIST, DWORD, DWORD_PTR,
                               PVOID, SIZE_T, PVOID, PSIZE_T)>()(
            lpAttributeList, dwFlags, Attribute, lpValue, cbSize,
            lpPreviousValue, lpReturnSize);
  });
  return true;
}


================================================
FILE: src/hooks/disable-integrity.h
================================================
#pragma once

namespace chromatic::hooks::windows {
    bool disable_integrity();
}

================================================
FILE: src/hooks/wait_for_module_load.cc
================================================
#include "wait_for_module_load.h"
#include "../utils.h"
#include "blook/blook.h"
#include <algorithm>
#include <atomic>
#include <functional>
#include <list>

#include "Windows.h"
#include "blook/process.h"
namespace chromatic::hooks::wait_for_module_load {
struct WaitTask {
  std::function<bool(std::filesystem::path)> verifier;
  std::promise<std::shared_ptr<blook::Module>> promise;

  WaitTask(std::function<bool(std::filesystem::path)> v,
           std::promise<std::shared_ptr<blook::Module>> p)
      : verifier(std::move(v)), promise(std::move(p)) {}
};

static std::list<std::unique_ptr<WaitTask>> wait_tasks;

static void process_module_load(HMODULE mod) {
  auto module_path = utils::get_module_path(mod);
  for (auto it = wait_tasks.begin(); it != wait_tasks.end();) {
    if ((*it)->verifier(module_path)) {
      (*it)->promise.set_value(blook::Process::self()
                                   ->module(module_path.filename().string())
                                   .value());
      it = wait_tasks.erase(it);
    } else {
      ++it;
    }
  }
}

static void ensure_loadlibrary_hooks() {
  static std::atomic_bool installed;
  if (installed.exchange(true))
    return;

  auto self = blook::Process::self();
  auto kernel32 = self->module("kernel32.dll").value();

  static auto LoadLibraryExAHook =
                  kernel32->exports("LoadLibraryExA")->inline_hook(),
              LoadLibraryExWHook =
                  kernel32->exports("LoadLibraryExW")->inline_hook();

  LoadLibraryExAHook->install(+[]([in] LPCSTR lpLibFileName,
                                  HANDLE hFile, [in] DWORD dwFlags) -> HMODULE {
    auto mod = LoadLibraryExAHook->call_trampoline<HMODULE>(lpLibFileName,
                                                            hFile, dwFlags);
    process_module_load(mod);
    return mod;
  });

  LoadLibraryExWHook->install(+[]([in] LPCWSTR lpLibFileName,
                                  HANDLE hFile, [in] DWORD dwFlags) -> HMODULE {
    auto mod = LoadLibraryExWHook->call_trampoline<HMODULE>(lpLibFileName,
                                                            hFile, dwFlags);
    process_module_load(mod);
    return mod;
  });
}

std::future<std::shared_ptr<blook::Module>>
wait_for_module(std::function<bool(std::filesystem::path)> verifier) {
  ensure_loadlibrary_hooks();

  std::promise<std::shared_ptr<blook::Module>> promise;
  auto future = promise.get_future();

  wait_tasks.emplace_back(
      std::make_unique<WaitTask>(std::move(verifier), std::move(promise)));

  return future;
}

static std::future<std::shared_ptr<blook::Module>>
wait_for_module(std::string_view module_name,
                std::function<void(void *)> callback) {
  if (module_name.empty()) {
    throw std::invalid_argument("Module name cannot be empty");
  }

  if (GetModuleHandleA(module_name.data()) != nullptr) {
    return std::async(std::launch::deferred, [&, module_name = std::string(
                                                     module_name)]() {
      callback(GetModuleHandleA(module_name.c_str()));
      return blook::Process::self()->module(std::string(module_name)).value();
    });
  }
  return wait_for_module([module_name, callback = std::move(callback)](
                             std::filesystem::path path) {
    callback(GetModuleHandleW(path.filename().c_str()));
    return path.filename() == module_name;
  });
};
} // namespace chromatic::hooks::wait_for_module_load

================================================
FILE: src/hooks/wait_for_module_load.h
================================================
#pragma once

#include "blook/module.h"
#include <functional>
#include <future>
namespace chromatic::hooks::wait_for_module_load {
std::future<std::shared_ptr<blook::Module>>
wait_for_module(std::function<bool(std::filesystem::path)> verifier);
std::future<std::shared_ptr<blook::Module>>
wait_for_module(std::string_view module_name, std::function<void(void*)> callback = [](void*) {});
} // namespace chromatic::hooks::wait_for_module_load


================================================
FILE: src/script/bindings/binding_qjs.h
================================================
// This file is generated by Breeze.JS Bindgen (https://github.com/breeze-shell/breeze-js-bindgen)
// Do not modify this file manually!

#pragma once
#include "binding_types.h"
#include "quickjspp.hpp"

template <typename T>
struct js_bind {
    static void bind(qjs::Context::Module &mod) {}
};

template <> struct qjs::js_traits<chromatic::js::chrome> {
    static chromatic::js::chrome unwrap(JSContext *ctx, JSValueConst v) {
        chromatic::js::chrome obj;

        return obj;
    }

    static JSValue wrap(JSContext *ctx, const chromatic::js::chrome &val) noexcept {
        JSValue obj = JS_NewObject(ctx);

        return obj;
    }
};
template<> struct js_bind<chromatic::js::chrome> {
    static void bind(qjs::Context::Module &mod) {
        mod.class_<chromatic::js::chrome>("chrome")
            .constructor<>()
            ;
    }
};

template <> struct qjs::js_traits<chromatic::js::chrome::blink> {
    static chromatic::js::chrome::blink unwrap(JSContext *ctx, JSValueConst v) {
        chromatic::js::chrome::blink obj;

        return obj;
    }

    static JSValue wrap(JSContext *ctx, const chromatic::js::chrome::blink &val) noexcept {
        JSValue obj = JS_NewObject(ctx);

        return obj;
    }
};
template<> struct js_bind<chromatic::js::chrome::blink> {
    static void bind(qjs::Context::Module &mod) {
        mod.class_<chromatic::js::chrome::blink>("chrome::blink")
            .constructor<>()
                .static_fun<&chromatic::js::chrome::blink::add_blink_parse_html_manipulator>("add_blink_parse_html_manipulator")
                .static_fun<&chromatic::js::chrome::blink::is_parse_html_manipulator_available>("is_parse_html_manipulator_available")
            ;
    }
};

template <> struct qjs::js_traits<chromatic::js::chrome::blink::blink_parse_manipulate_context> {
    static chromatic::js::chrome::blink::blink_parse_manipulate_context unwrap(JSContext *ctx, JSValueConst v) {
        chromatic::js::chrome::blink::blink_parse_manipulate_context obj;

        obj.html = js_traits<std::string>::unwrap(ctx, JS_GetPropertyStr(ctx, v, "html"));

        obj.url = js_traits<std::string>::unwrap(ctx, JS_GetPropertyStr(ctx, v, "url"));

        return obj;
    }

    static JSValue wrap(JSContext *ctx, const chromatic::js::chrome::blink::blink_parse_manipulate_context &val) noexcept {
        JSValue obj = JS_NewObject(ctx);

        JS_SetPropertyStr(ctx, obj, "html", js_traits<std::string>::wrap(ctx, val.html));

        JS_SetPropertyStr(ctx, obj, "url", js_traits<std::string>::wrap(ctx, val.url));

        return obj;
    }
};
template<> struct js_bind<chromatic::js::chrome::blink::blink_parse_manipulate_context> {
    static void bind(qjs::Context::Module &mod) {
        mod.class_<chromatic::js::chrome::blink::blink_parse_manipulate_context>("chrome::blink::blink_parse_manipulate_context")
            .constructor<>()
                .fun<&chromatic::js::chrome::blink::blink_parse_manipulate_context::html>("html")
                .fun<&chromatic::js::chrome::blink::blink_parse_manipulate_context::url>("url")
            ;
    }
};

template <> struct qjs::js_traits<chromatic::js::infra> {
    static chromatic::js::infra unwrap(JSContext *ctx, JSValueConst v) {
        chromatic::js::infra obj;

        return obj;
    }

    static JSValue wrap(JSContext *ctx, const chromatic::js::infra &val) noexcept {
        JSValue obj = JS_NewObject(ctx);

        return obj;
    }
};
template<> struct js_bind<chromatic::js::infra> {
    static void bind(qjs::Context::Module &mod) {
        mod.class_<chromatic::js::infra>("infra")
            .constructor<>()
                .static_fun<&chromatic::js::infra::log>("log")
            ;
    }
};

inline void bindAll(qjs::Context::Module &mod) {

    js_bind<chromatic::js::chrome>::bind(mod);

    js_bind<chromatic::js::chrome::blink>::bind(mod);

    js_bind<chromatic::js::chrome::blink::blink_parse_manipulate_context>::bind(mod);

    js_bind<chromatic::js::infra>::bind(mod);

}


================================================
FILE: src/script/bindings/binding_types.cc
================================================
#include "binding_types.h"
#include <list>

#include "breeze-js/quickjspp.hpp"
#include "ylt/easylog.hpp"

#include "../../context.h"

std::list<std::function<std::string(std::string)>>
    blink_parse_html_manipulators;
namespace chromatic::js {
void chrome::blink::add_blink_parse_html_manipulator(
    std::function<std::string(std::string)> manipulator) {

  blink_parse_html_manipulators.push_back([manipulator](std::string ctx) {
    try {
      return manipulator(ctx);
    } catch (const std::exception &e) {
      ELOGFMT(ERROR, "Exception in blink parse HTML manipulator: {}", e.what());
      return std::string();
    } catch (...) {
      ELOGFMT(ERROR, "Unknown exception in blink parse HTML manipulator");
      return std::string();
    }
  });
}
void infra::log(qjs::rest<std::string> msg) {
  std::string log_msg;
  for (const auto &m : msg) {
    log_msg += m + " ";
  }
  log_msg.pop_back();

  ELOGFMT(INFO, "{}", log_msg);
}
} // namespace chromatic::js

================================================
FILE: src/script/bindings/binding_types.d.ts
================================================
// This file is generated by bindgen
// Do not modify this file manually!

declare module 'chromatic' {

export class chrome {
}
namespace chrome {
export class blink {
	/**
     * 
     * @param arg0: ((arg1: string) => string)
     * @returns void
     */
    static add_blink_parse_html_manipulator(arg0: ((arg1: string) => string)): void
	static is_parse_html_manipulator_available(): boolean
}
}
namespace chrome.blink {
export class blink_parse_manipulate_context {
	html: string
	url: string
}
}
export class infra {
	/**
     * 
     * @param msg: qjs.rest<string>
     * @returns void
     */
    static log(msg: qjs.rest<string>): void
}
}



================================================
FILE: src/script/bindings/binding_types.h
================================================
#pragma once

#include <functional>
#include <memory>
#include <optional>
#include <string>

#include "../../hooks/blink_parse_html_manipulator.h"

namespace qjs {
template <typename T> struct rest;
}

namespace chromatic::js {
struct chrome {
  struct blink {
    struct blink_parse_manipulate_context {
      std::string html;
      std::string url;
    };
    static void add_blink_parse_html_manipulator(
        std::function<std::string(std::string)>);

    static bool is_parse_html_manipulator_available() {
      return chromatic::blink_parse_html_manipulator::is_available();
    }
  };
};

struct infra {
  static void log(qjs::rest<std::string> msg);
};
} // namespace chromatic::js

================================================
FILE: src/script/bindings/quickjspp.hpp
================================================
#pragma once
#include "breeze-js/quickjspp.hpp"

================================================
FILE: src/script/script.cc
================================================
#include "script.h"

#include "../config.h"

#include "bindings/binding_qjs.h"
#include "ylt/easylog.hpp"

namespace chromatic {

script_engine::script_engine() {

  js_watch_thread = std::thread([this]() {

    auto script_dir = config::data_directory() / "scripts";
    if (!std::filesystem::exists(script_dir)) {
      std::filesystem::create_directories(script_dir);
    }

    ctx.on_bind.push_back([this]() {
      auto &mod = ctx.js->addModule("chromatic");

      bindAll(mod);
    });

    ELOGFMT(INFO, "Script engine initialized.");
    ctx.watch_folder(script_dir);
  });
}

script_engine::~script_engine() {
  if (js_watch_thread.joinable()) {
    ctx.stop_signal = std::make_shared<int>(1);
    js_watch_thread.join();
  }
}
} // namespace chromatic

================================================
FILE: src/script/script.h
================================================
#pragma once
#include "breeze-js/script.h"

namespace chromatic {
struct script_engine {
  breeze::script_context ctx;

  script_engine();
  ~script_engine();

private:
  std::thread js_watch_thread;
};
} // namespace chromatic

================================================
FILE: src/utils.cc
================================================
#include "utils.h"

#include "Windows.h"

namespace chromatic::utils {
std::optional<std::string> env(const std::string &name) {
  wchar_t buffer[32767];
  GetEnvironmentVariableW(utf8_to_wstring(name).c_str(), buffer, 32767);
  if (buffer[0] == 0) {
    return std::nullopt;
  }
  return wstring_to_utf8(buffer);
}

std::string wstring_to_utf8(std::wstring const &str) {
  int size_needed = WideCharToMultiByte(CP_UTF8, 0, str.c_str(),
                                        (int)str.size(), NULL, 0, NULL, NULL);
  std::string result(size_needed, 0);
  WideCharToMultiByte(CP_UTF8, 0, str.c_str(), (int)str.size(), &result[0],
                      size_needed, NULL, NULL);
  return result;
}

std::wstring utf8_to_wstring(std::string const &str) {
  int size_needed =
      MultiByteToWideChar(CP_UTF8, 0, str.c_str(), (int)str.size(), NULL, 0);
  std::wstring result(size_needed, 0);
  MultiByteToWideChar(CP_UTF8, 0, str.c_str(), (int)str.size(), &result[0],
                      size_needed);
  return result;
}
std::filesystem::path current_executable_path() {
  static std::filesystem::path path = chromatic::utils::get_module_path();
  return path;
}
std::filesystem::path get_module_path(void *module_handle) {
  HMODULE hModule = static_cast<HMODULE>(module_handle);
  wchar_t buffer[MAX_PATH];
  if (GetModuleFileNameW(hModule, buffer, MAX_PATH) == 0) {
    return {};
  }

  return std::filesystem::path(buffer);
}

task_queue::task_queue() : stop(false) {
  worker = std::thread(&task_queue::run, this);
}
task_queue::~task_queue() {
  {
    std::lock_guard<std::mutex> lock(queue_mutex);
    stop = true;
  }
  condition.notify_all();
  if (worker.joinable()) {
    worker.join();
  }
}
void task_queue::run() {
  while (true) {
    std::function<void()> task;
    {
      std::unique_lock<std::mutex> lock(queue_mutex);
      condition.wait(lock, [this]() { return stop || !tasks.empty(); });

      if (stop && tasks.empty()) {
        return;
      }

      task = std::move(tasks.front());
      tasks.pop();
    }

    task();
  }
}
} // namespace chromatic::utils

================================================
FILE: src/utils.h
================================================
#pragma once
#include <filesystem>
#include <future>
#include <optional>
#include <queue>
#include <string>


namespace chromatic {
namespace utils {
std::optional<std::string> env(const std::string &name);
std::string wstring_to_utf8(std::wstring const &str);
std::wstring utf8_to_wstring(std::string const &str);
std::filesystem::path current_executable_path();
std::filesystem::path get_module_path(void *module_handle = nullptr);
struct task_queue {
public:
  task_queue();

  ~task_queue();

  template <typename F, typename... Args>
  auto add_task(F &&f, Args &&...args)
      -> std::future<std::invoke_result_t<F, Args...>> {
    using return_type = std::invoke_result_t<F, Args...>;

    if (stop) {
      throw std::runtime_error("add_task called on stopped task_queue");
    }

    auto task = std::make_shared<std::packaged_task<return_type()>>(
        std::bind(std::forward<F>(f), std::forward<Args>(args)...));

    std::future<return_type> res = task->get_future();

    {
      std::lock_guard<std::mutex> lock(queue_mutex);
      tasks.emplace([task]() { (*task)(); });
    }

    condition.notify_one();
    return res;
  }

private:
  void run();

  std::thread worker;
  std::queue<std::function<void()>> tasks;
  std::mutex queue_mutex;
  std::condition_variable condition;
  bool stop;
};

} // namespace utils
} // namespace chromatic

================================================
FILE: test/ipc_test.cc
================================================
#include "ipc.h"
#include <chrono>
#include <gtest/gtest.h>
#include <print>
#include <thread>

using namespace chromatic;

TEST(IPCTest, BasicMessageSendReceive) {
  breeze_ipc ipc1, ipc2;
  ipc1.connect("chromatic://process/1");
  ipc2.connect("chromatic://process/1");

  bool received = false;
  auto remover = ipc2.add_listener(
      "test_msg", [&](const breeze_ipc::packet &pkt) { received = true; });

  ipc1.send("test_msg", test_serializable_struct{1, 2.0f, {'a', 'b', 'c'}});

  std::this_thread::sleep_for(
      std::chrono::milliseconds(100)); // Give time for IPC to process
  EXPECT_TRUE(received);
}

TEST(IPCTest, RPCCall) {
  breeze_ipc server, client;
  server.connect("chromatic://process/");
  client.connect("chromatic://process/");

  auto remover =
      server.add_call_handler<int, int>("add_one", [](int x) { return x + 1; });

  auto future = client.call<int, int>("add_one", 5);

  EXPECT_EQ(future.get(), 6);
}

TEST(IPCTest, StringReturnRPC) {
  breeze_ipc server, client;
  server.connect("chromatic://process/");
  client.connect("chromatic://process/");

  auto remover = server.add_call_handler<std::string, std::string>(
      "echo", [](const std::string &s) { return s; });

  auto future = client.call<std::string, std::string>("echo", "hello world");

  EXPECT_EQ(future.get(), "hello world");
}

TEST(IPCTest, PairReturnRPC) {
  breeze_ipc server, client;
  server.connect("chromatic://process/");
  client.connect("chromatic://process/");

  auto remover = server.add_call_handler<std::pair<int, std::string>, int>(
      "make_pair", [](int x) { return std::make_pair(x, std::to_string(x)); });

  auto future = client.call<std::pair<int, std::string>, int>("make_pair", 42);

  auto result = future.get();
  EXPECT_EQ(result.first, 42);
  EXPECT_EQ(result.second, "42");
}

TEST(IPCTest, StringPairRPC) {
  breeze_ipc server, client;
  server.connect("chromatic://process/");
  client.connect("chromatic://process/");

  auto remover = server.add_call_handler<std::pair<std::string, std::string>,
                                         std::pair<std::string, std::string>>(
      "concat_pair", [](const auto &p) {
        return std::make_pair(p.first + p.second, p.second + p.first);
      });

  auto future = client.call<std::pair<std::string, std::string>,
                            std::pair<std::string, std::string>>(
      "concat_pair", std::make_pair("hello", "world"));

  auto result = future.get();
  EXPECT_EQ(result.first, "helloworld");
  EXPECT_EQ(result.second, "worldhello");
}

struct blink_parse_manipulate_context {
  std::string html;
  std::string url;
};

TEST(IPCTest, BlinkContextRPC) {
  breeze_ipc server, client;
  server.connect("chromatic://process/");
  client.connect("chromatic://process/");

  auto remover = server.add_call_handler<blink_parse_manipulate_context,
                                         blink_parse_manipulate_context>(
      "process_html", [](const auto &ctx) {
        blink_parse_manipulate_context result = ctx;
        result.html += "<!-- processed -->";
        return result;
      });

  blink_parse_manipulate_context original{.html = "<html>test</html>",
                                          .url = "http://example.com"};

  auto future =
      client
          .call<blink_parse_manipulate_context, blink_parse_manipulate_context>(
              "process_html", original);

  auto result = future.get();
  EXPECT_EQ(result.html, "<html>test</html><!-- processed -->");
  EXPECT_EQ(result.url, "http://example.com");
}

TEST(IPCTest, Serialization) {
  test_serializable_struct original{42, 3.14f, {'x', 'y', 'z'}};
  auto serialized = struct_pack::serialize(original);
  auto deserialized =
      struct_pack::deserialize<test_serializable_struct>(serialized);

  ASSERT_TRUE(deserialized.has_value());
  EXPECT_EQ(deserialized->a, 42);
  EXPECT_FLOAT_EQ(deserialized->b, 3.14f);
  auto vec = std::vector<char>{'x', 'y', 'z'};
  EXPECT_EQ(deserialized->c, vec);
}

TEST(IPCTest, ALotOfPackets) {
  breeze_ipc server, client;
  server.connect("chromatic://process/");
  client.connect("chromatic://process/");

  int count = 1000;
  int received = 0;

  auto remover = server.add_listener(
      "test_msg", [&](const breeze_ipc::packet &pkt) { received++; });

  for (int i = 0; i < count; ++i) {
    client.send("test_msg", test_serializable_struct{i, i * 1.1f, {'a', 'b'}});
  }

  std::this_thread::sleep_for(
      std::chrono::seconds(1)); // Give time for IPC to process
  EXPECT_EQ(received, count);
}

TEST(IPCTest, LargePacket) {
  breeze_ipc server, client;
  server.connect("chromatic://process/");
  client.connect("chromatic://process/");

  // ~1MB of data
  std::string large_data(1024 * 1024, 'x');

  auto remover = server.add_call_handler<std::string, std::string>(
      "echo_large", [](const std::string &data) { 
        std::println("Received large data of size: {}", data.size());
        return data;
       });

  auto future = client.call<std::string, std::string>("echo_large", large_data);

  EXPECT_EQ(future.get(), large_data);
}

int main(int argc, char **argv) {

  // auto channel = breeze_ipc{};
  // channel.connect("chromatic://process/");

  // channel.add_call_handler<std::string, std::string>(
  //     "on_blink_parse_html_manipulate",
  //     [](const std::string &ctx) {
  //       std::println("on_blink_parse_html_manipulate called with: {}", ctx);
  //       return "Processed: " + ctx;
  //     });

  // while (1)
  //   ;

  std::string arg(argc > 1 ? argv[1] : "");
  if (arg == "inspect") {
    ipc::Channel channel;
    channel.connect("chromatic://process/");

    std::cout << "Connected to IPC channel." << std::endl;

    std::thread input_thread([&channel]() {
      while (true) {
        std::string input;
        std::getline(std::cin, input);
        channel.send(input);
      }
    });

    while (true) {
      std::string data;
      channel.try_receive(data);
      if (!data.empty()) {
        std::cout << "\033[47;30m["
                  << std::chrono::system_clock::now().time_since_epoch().count()
                  << "] \033[47;0m";

        if (*(char *)data.data() == '{') {
          // Assuming it's a JSON string
          std::string json_str((char *)data.data(), data.size());
          std::println("JSON: {}", json_str);
        } else {
          // Print as hex
          std::cout << "Hex: ";
          for (size_t i = 0; i < data.size(); ++i) {
            if (i % 16 == 0 && i != 0) {
              std::cout << "\n";
            }
            std::cout << std::hex << static_cast<int>(((char *)data.data())[i])
                      << " ";
          }
          std::cout << std::dec << "\n";
        }
      }
    }
  } else {
    try {
      testing::InitGoogleTest(&argc, argv);
      return RUN_ALL_TESTS();
    } catch (const std::exception &e) {
      std::cerr << "Exception during test initialization: " << e.what()
                << std::endl;
      return 1;
    } catch (...) {
      std::cerr << "Unknown exception during test initialization." << std::endl;
      return 1;
    }
  }
}

================================================
FILE: xmake.lua
================================================
set_project("chromatic")
set_policy("compatibility.version", "3.0")

set_languages("c++23")
set_warnings("all")
add_rules("plugin.compile_commands.autoupdate", {outputdir = "build"})

add_rules("mode.releasedbg")

includes("deps/blook.lua")
includes("deps/breeze-js.lua")
includes("deps/cpp-ipc.lua")

add_requires("yalantinglibs 0c98464dd202aaa6275a8da3297719a436b8a51a", {
    configs = {
        ssl = true
    }
})

add_requireconfs("**.cinatra", {
    override = true,
    version = "e329293f6705649a6f1e8847ec845a7631179bb8"
})

add_requireconfs("**.async_simple", {
    override = true,
    version = "18f3882be354d407af0f0674121dcddaeff36e26"
})

add_requires("blook", "breeze-js", "reflect-cpp", "cpptrace v0.8.3", "gtest")
set_runtimes("MT")

target("chromatic_ipc")
    set_kind("static")
    add_defines("NOMINMAX")
    add_packages("yalantinglibs", "reflect-cpp", {
        public = true,
    })
    add_files("ipc/ipc.cc")
    add_headerfiles("ipc/ipc.h")
    add_includedirs("ipc", {public = true})
    set_encodings("utf-8")

target("chromatic")
    set_kind("shared")
    add_defines("NOMINMAX")
    add_packages("blook", "breeze-js", "reflect-cpp", "yalantinglibs", "cpptrace")
    add_syslinks("oleacc", "ole32", "oleaut32", "uuid", "comctl32", "comdlg32", "gdi32", "user32", "shell32", "kernel32", "advapi32", "psapi")
    add_files("src/**/*.cc", "src/*.cc")
    remove_files("src/ipc.cc")
    add_deps("chromatic_ipc")
    set_encodings("utf-8")

target("chromatic_ipc_test")
    set_kind("binary")
    add_deps("chromatic_ipc")
    add_packages("gtest", "yalantinglibs")
    add_files("test/ipc_test.cc")
    add_includedirs("src")
    set_encodings("utf-8")
Download .txt
gitextract_tq7m8ylh/

├── .clangd
├── .github/
│   └── workflows/
│       └── xmake.yml
├── .gitignore
├── .gitmodules
├── README.md
├── deps/
│   ├── blook.lua
│   └── breeze-js.lua
├── ipc/
│   ├── ipc.cc
│   ├── ipc.h
│   └── shared_memory_ipc.h
├── scripts/
│   ├── bindgen.bat
│   └── rebuild.ps1
├── src/
│   ├── config.cc
│   ├── config.h
│   ├── context.cc
│   ├── context.h
│   ├── entry.cc
│   ├── hooks/
│   │   ├── blink_parse_html_manipulator.cc
│   │   ├── blink_parse_html_manipulator.h
│   │   ├── disable-integrity.cc
│   │   ├── disable-integrity.h
│   │   ├── wait_for_module_load.cc
│   │   └── wait_for_module_load.h
│   ├── script/
│   │   ├── bindings/
│   │   │   ├── binding_qjs.h
│   │   │   ├── binding_types.cc
│   │   │   ├── binding_types.d.ts
│   │   │   ├── binding_types.h
│   │   │   └── quickjspp.hpp
│   │   ├── script.cc
│   │   └── script.h
│   ├── utils.cc
│   └── utils.h
├── test/
│   └── ipc_test.cc
└── xmake.lua
Download .txt
SYMBOL INDEX (75 symbols across 22 files)

FILE: ipc/ipc.cc
  type chromatic (line 10) | namespace chromatic {

FILE: ipc/ipc.h
  function namespace (line 25) | namespace chromatic {
  function remove (line 181) | void remove() {

FILE: ipc/shared_memory_ipc.h
  function namespace (line 34) | namespace ipc {
  type Config (line 179) | struct Config {
  function disconnect (line 279) | void disconnect() {
  function send (line 305) | void send(const std::string &message) {
  function receive (line 382) | void receive(std::string &message) {
  function try_receive (line 389) | bool try_receive(std::string &message) {
  function get_header_size (line 479) | static constexpr size_t get_header_size() {
  function is_pid_alive (line 503) | static bool is_pid_alive(DWORD pid) {
  function register_reader (line 512) | void register_reader() {
  function deregister_reader (line 536) | void deregister_reader() {
  function update_reader_progress (line 544) | void update_reader_progress() {
  function get_slowest_reader_sequence (line 557) | uint64_t get_slowest_reader_sequence() const {
  function clean_dead_readers (line 579) | void clean_dead_readers() {

FILE: src/config.cc
  type chromatic (line 17) | namespace chromatic {

FILE: src/config.h
  function namespace (line 9) | namespace chromatic {

FILE: src/context.cc
  type chromatic (line 25) | namespace chromatic {
    function CPPTRACE_CATCH (line 41) | CPPTRACE_CATCH(const std::exception &e) {
    function catch (line 46) | catch (...) {

FILE: src/context.h
  function namespace (line 11) | namespace chromatic {

FILE: src/entry.cc
  type chromatic (line 19) | namespace chromatic {
    function main (line 20) | int main() {
  function DllMain (line 32) | int APIENTRY DllMain(HINSTANCE hInstance, DWORD fdwReason, LPVOID lpvRes...

FILE: src/hooks/blink_parse_html_manipulator.cc
  type chromatic (line 22) | namespace chromatic {
    type BlinkHTMLData (line 23) | struct BlinkHTMLData {
    type BlinkUtilSpan (line 28) | struct BlinkUtilSpan {

FILE: src/hooks/blink_parse_html_manipulator.h
  function namespace (line 6) | namespace chromatic {

FILE: src/hooks/disable-integrity.h
  function namespace (line 3) | namespace chromatic::hooks::windows {

FILE: src/hooks/wait_for_module_load.cc
  type chromatic::hooks::wait_for_module_load (line 11) | namespace chromatic::hooks::wait_for_module_load {
    type WaitTask (line 12) | struct WaitTask {
      method WaitTask (line 16) | WaitTask(std::function<bool(std::filesystem::path)> v,
    function process_module_load (line 23) | static void process_module_load(HMODULE mod) {
    function ensure_loadlibrary_hooks (line 37) | static void ensure_loadlibrary_hooks() {
    function wait_for_module (line 67) | std::future<std::shared_ptr<blook::Module>>
    function wait_for_module (line 80) | static std::future<std::shared_ptr<blook::Module>>

FILE: src/hooks/wait_for_module_load.h
  function namespace (line 6) | namespace chromatic::hooks::wait_for_module_load {

FILE: src/script/bindings/binding_qjs.h
  function bind (line 10) | static void bind(qjs::Context::Module &mod) {}
  function chrome (line 13) | struct qjs::js_traits<chromatic::js::chrome> {
  function chrome (line 26) | struct js_bind<chromatic::js::chrome> {
  function blink (line 34) | struct qjs::js_traits<chromatic::js::chrome::blink> {
  function blink (line 47) | struct js_bind<chromatic::js::chrome::blink> {
  function blink_parse_manipulate_context (line 57) | struct qjs::js_traits<chromatic::js::chrome::blink::blink_parse_manipula...
  function blink_parse_manipulate_context (line 78) | struct js_bind<chromatic::js::chrome::blink::blink_parse_manipulate_cont...
  function infra (line 88) | struct qjs::js_traits<chromatic::js::infra> {
  function infra (line 101) | struct js_bind<chromatic::js::infra> {
  function bindAll (line 110) | inline void bindAll(qjs::Context::Module &mod) {

FILE: src/script/bindings/binding_types.cc
  type chromatic::js (line 11) | namespace chromatic::js {

FILE: src/script/bindings/binding_types.d.ts
  class chrome (line 6) | class chrome {
  class blink (line 9) | class blink {
  class blink_parse_manipulate_context (line 20) | class blink_parse_manipulate_context {
  class infra (line 25) | class infra {

FILE: src/script/bindings/binding_types.h
  function namespace (line 10) | namespace qjs {
  function namespace (line 14) | namespace chromatic::js {

FILE: src/script/script.cc
  type chromatic (line 8) | namespace chromatic {

FILE: src/script/script.h
  function namespace (line 4) | namespace chromatic {

FILE: src/utils.cc
  type chromatic::utils (line 5) | namespace chromatic::utils {
    function env (line 6) | std::optional<std::string> env(const std::string &name) {
    function wstring_to_utf8 (line 15) | std::string wstring_to_utf8(std::wstring const &str) {
    function utf8_to_wstring (line 24) | std::wstring utf8_to_wstring(std::string const &str) {
    function current_executable_path (line 32) | std::filesystem::path current_executable_path() {
    function get_module_path (line 36) | std::filesystem::path get_module_path(void *module_handle) {

FILE: src/utils.h
  function namespace (line 9) | namespace chromatic {

FILE: test/ipc_test.cc
  function TEST (line 9) | TEST(IPCTest, BasicMessageSendReceive) {
  function TEST (line 25) | TEST(IPCTest, RPCCall) {
  function TEST (line 38) | TEST(IPCTest, StringReturnRPC) {
  function TEST (line 51) | TEST(IPCTest, PairReturnRPC) {
  function TEST (line 66) | TEST(IPCTest, StringPairRPC) {
  type blink_parse_manipulate_context (line 86) | struct blink_parse_manipulate_context {
  function TEST (line 91) | TEST(IPCTest, BlinkContextRPC) {
  function TEST (line 117) | TEST(IPCTest, Serialization) {
  function TEST (line 130) | TEST(IPCTest, ALotOfPackets) {
  function TEST (line 150) | TEST(IPCTest, LargePacket) {
  function main (line 169) | int main(int argc, char **argv) {
Condensed preview — 34 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (93K chars).
[
  {
    "path": ".clangd",
    "chars": 59,
    "preview": "CompileFlags:\n    Add: [\"-std:latest\", \"/clang:-std=c++23\"]"
  },
  {
    "path": ".github/workflows/xmake.yml",
    "chars": 1598,
    "preview": "name: Build\npermissions: write-all\n\non:\n  push:\n    branches: [ \"chromatic\" ]\n  pull_request:\n    branches: [ \"chromatic"
  },
  {
    "path": ".gitignore",
    "chars": 13,
    "preview": "build\n.xmake\n"
  },
  {
    "path": ".gitmodules",
    "chars": 188,
    "preview": "[submodule \"deps/blook\"]\n\tpath = deps/blook\n\turl = https://github.com/std-microblock/blook\n[submodule \"deps/cpp-ipc\"]\n\tp"
  },
  {
    "path": "README.md",
    "chars": 1516,
    "preview": "<div align=center>\n<img src=https://github.com/user-attachments/assets/4e0d0de3-c117-44e0-aed5-f95eaac33ba7 width=200/>\n"
  },
  {
    "path": "deps/blook.lua",
    "chars": 971,
    "preview": "package(\"blook\")\n    add_deps(\"cmake\")\n    add_syslinks(\"advapi32\")\n    set_sourcedir(path.join(os.scriptdir(), \"blook\")"
  },
  {
    "path": "deps/breeze-js.lua",
    "chars": 1484,
    "preview": "package(\"breeze-js\")\n    set_description(\"A lightweight and modern JavaScript runtime built on QuickJS for desktop appli"
  },
  {
    "path": "ipc/ipc.cc",
    "chars": 2525,
    "preview": "#include \"ipc.h\"\n#include <chrono>\n#include <print>\n#include <stdexcept>\n#include <string>\n\n#include \"shared_memory_ipc."
  },
  {
    "path": "ipc/ipc.h",
    "chars": 9691,
    "preview": "#pragma once\n#include \"./shared_memory_ipc.h\"\n#include <atomic>\n#include <condition_variable>\n#include <deque>\n#include "
  },
  {
    "path": "ipc/shared_memory_ipc.h",
    "chars": 18751,
    "preview": "#pragma once\n\n#include <print>\n#if defined(_MSC_VER)\n#pragma warning(push)\n#pragma warning(disable : 4200)\n#endif\n\n#ifnd"
  },
  {
    "path": "scripts/bindgen.bat",
    "chars": 139,
    "preview": "npx breeze-bindgen@latest -i src/script/bindings/binding_types.h --nameFilter chromatic::js -o src/script/bindings --tsM"
  },
  {
    "path": "scripts/rebuild.ps1",
    "chars": 520,
    "preview": "$targetPath = \"C:\\Program Files\\Tencent\\QQNT-dev\\QQ.exe\"\n\n#  kill the process if it is running\nforeach ($process in Get-"
  },
  {
    "path": "src/config.cc",
    "chars": 3721,
    "preview": "#include \"config.h\"\n#include <chrono>\n#include <filesystem>\n#include <fstream>\n#include <mutex>\n#include <thread>\n\n#incl"
  },
  {
    "path": "src/config.h",
    "chars": 649,
    "preview": "#pragma once\n\n#include <filesystem>\n#include <functional>\n#include <memory>\n#include <numbers>\n#include <vector>\n\nnamesp"
  },
  {
    "path": "src/context.cc",
    "chars": 10166,
    "preview": "#include \"context.h\"\n\n#include \"config.h\"\n#include \"cpptrace/basic.hpp\"\n#include \"utils.h\"\n#include \"ylt/easylog.hpp\"\n\n#"
  },
  {
    "path": "src/context.h",
    "chars": 723,
    "preview": "#pragma once\n\n#include \"blook/module.h\"\n#include \"config.h\"\n#include \"script/script.h\"\n#include <memory>\n#include <strin"
  },
  {
    "path": "src/entry.cc",
    "chars": 878,
    "preview": "#include <algorithm>\n#include <print>\n#include <ranges>\n#include <string>\n#include <thread>\n\n#include \"blook/blook.h\"\n\n#"
  },
  {
    "path": "src/hooks/blink_parse_html_manipulator.cc",
    "chars": 8331,
    "preview": "#include \"blink_parse_html_manipulator.h\"\n\n#include \"../context.h\"\n#include \"../utils.h\"\n#include \"blook/function.h\"\n#in"
  },
  {
    "path": "src/hooks/blink_parse_html_manipulator.h",
    "chars": 238,
    "preview": "#pragma once\n#include <functional>\n#include <list>\n#include <memory>\n\nnamespace chromatic {\n    struct blink_parse_html_"
  },
  {
    "path": "src/hooks/disable-integrity.cc",
    "chars": 1422,
    "preview": "#include \"disable-integrity.h\"\n#include \"blook/blook.h\"\n\n#include \"Windows.h\"\n#include <memory>\n\n#include \"processthread"
  },
  {
    "path": "src/hooks/disable-integrity.h",
    "chars": 83,
    "preview": "#pragma once\n\nnamespace chromatic::hooks::windows {\n    bool disable_integrity();\n}"
  },
  {
    "path": "src/hooks/wait_for_module_load.cc",
    "chars": 3456,
    "preview": "#include \"wait_for_module_load.h\"\n#include \"../utils.h\"\n#include \"blook/blook.h\"\n#include <algorithm>\n#include <atomic>\n"
  },
  {
    "path": "src/hooks/wait_for_module_load.h",
    "chars": 442,
    "preview": "#pragma once\n\n#include \"blook/module.h\"\n#include <functional>\n#include <future>\nnamespace chromatic::hooks::wait_for_mod"
  },
  {
    "path": "src/script/bindings/binding_qjs.h",
    "chars": 4016,
    "preview": "// This file is generated by Breeze.JS Bindgen (https://github.com/breeze-shell/breeze-js-bindgen)\n// Do not modify this"
  },
  {
    "path": "src/script/bindings/binding_types.cc",
    "chars": 975,
    "preview": "#include \"binding_types.h\"\n#include <list>\n\n#include \"breeze-js/quickjspp.hpp\"\n#include \"ylt/easylog.hpp\"\n\n#include \"../"
  },
  {
    "path": "src/script/bindings/binding_types.d.ts",
    "chars": 651,
    "preview": "// This file is generated by bindgen\n// Do not modify this file manually!\n\ndeclare module 'chromatic' {\n\nexport class ch"
  },
  {
    "path": "src/script/bindings/binding_types.h",
    "chars": 694,
    "preview": "#pragma once\n\n#include <functional>\n#include <memory>\n#include <optional>\n#include <string>\n\n#include \"../../hooks/blink"
  },
  {
    "path": "src/script/bindings/quickjspp.hpp",
    "chars": 47,
    "preview": "#pragma once\n#include \"breeze-js/quickjspp.hpp\""
  },
  {
    "path": "src/script/script.cc",
    "chars": 763,
    "preview": "#include \"script.h\"\n\n#include \"../config.h\"\n\n#include \"bindings/binding_qjs.h\"\n#include \"ylt/easylog.hpp\"\n\nnamespace chr"
  },
  {
    "path": "src/script/script.h",
    "chars": 227,
    "preview": "#pragma once\n#include \"breeze-js/script.h\"\n\nnamespace chromatic {\nstruct script_engine {\n  breeze::script_context ctx;\n\n"
  },
  {
    "path": "src/utils.cc",
    "chars": 2087,
    "preview": "#include \"utils.h\"\n\n#include \"Windows.h\"\n\nnamespace chromatic::utils {\nstd::optional<std::string> env(const std::string "
  },
  {
    "path": "src/utils.h",
    "chars": 1360,
    "preview": "#pragma once\n#include <filesystem>\n#include <future>\n#include <optional>\n#include <queue>\n#include <string>\n\n\nnamespace "
  },
  {
    "path": "test/ipc_test.cc",
    "chars": 7115,
    "preview": "#include \"ipc.h\"\n#include <chrono>\n#include <gtest/gtest.h>\n#include <print>\n#include <thread>\n\nusing namespace chromati"
  },
  {
    "path": "xmake.lua",
    "chars": 1681,
    "preview": "set_project(\"chromatic\")\nset_policy(\"compatibility.version\", \"3.0\")\n\nset_languages(\"c++23\")\nset_warnings(\"all\")\nadd_rule"
  }
]

About this extraction

This page contains the full source code of the std-microblock/chromatic GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 34 files (85.1 KB), approximately 22.4k tokens, and a symbol index with 75 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!