35 const std::filesystem::path& config_dir)
36 : config_path_(config_dir /
"config.local.yaml") {}
45static std::string read_file(
const std::filesystem::path& path) {
46 std::ifstream in(path);
47 if (!in.is_open())
return "";
48 std::ostringstream ss;
62 const std::string& content) {
63 std::filesystem::create_directories(path.parent_path());
64 std::ofstream out(path);
65 if (!out.is_open())
return false;
77static std::vector<std::string>
split_lines(
const std::string& content) {
78 std::vector<std::string> lines;
79 std::istringstream iss(content);
81 while (std::getline(iss, line)) {
82 lines.push_back(line);
97 size_t start, std::string_view pattern) {
98 std::string needle =
"- " + std::string(pattern);
99 for (
size_t i = start + 1; i < lines.size(); ++i) {
100 auto pos = lines[i].find_first_not_of(
' ');
101 if (pos == std::string::npos)
continue;
102 auto trimmed = lines[i].substr(pos);
103 if (!trimmed.starts_with(
"- "))
break;
104 if (trimmed == needle)
return true;
119 auto ins = lines.begin()
120 +
static_cast<long>(list_start) + 1;
121 while (ins != lines.end()) {
122 auto pos = ins->find_first_not_of(
' ');
123 bool is_item = pos != std::string::npos
124 && ins->substr(pos).starts_with(
"- ");
140 std::vector<std::string>::iterator start) {
142 while (it != lines.end() && !it->empty()
143 && ((*it)[0] ==
' ' || (*it)[0] ==
'\t')) {
156static std::string
join_lines(
const std::vector<std::string>& lines) {
157 std::ostringstream out;
158 for (
size_t i = 0; i < lines.size(); ++i) {
160 if (i + 1 < lines.size()) out <<
'\n';
162 auto result = out.str();
163 if (!result.empty() && result.back() !=
'\n') {
186 std::string_view pattern,
187 const std::string& perms_key,
188 const std::string& list_line,
189 const std::string& item) {
190 auto perms_it = std::find(lines.begin(), lines.end(), perms_key);
191 if (perms_it == lines.end()) {
192 lines.push_back(perms_key);
193 lines.push_back(list_line);
194 lines.push_back(item);
195 }
else if (
auto list_it = std::find(perms_it, lines.end(), list_line);
196 list_it == lines.end()) {
198 lines.insert(pos, item);
199 lines.insert(pos, list_line);
201 size_t idx =
static_cast<size_t>(
202 std::distance(lines.begin(), list_it));
221 std::lock_guard lock(write_mutex_);
224 const char* list_key = allow ?
"allow" :
"deny";
225 std::string perms_key =
"permissions:";
226 std::string list_line = std::string(
" ") + list_key +
":";
227 std::string item =
" - " + std::string(pattern);
234 logger->error(
"Failed to write permission to {}",
235 config_path_.string());
239 logger->info(
"Saved permission {}: {}",
240 allow ?
"allow" :
"deny", pattern);
PermissionPersister(const std::filesystem::path &config_dir)
Construct with config directory path.
bool save_permission(std::string_view pattern, bool allow)
Save a permission pattern.
spdlog initialization and logger access.
ENTROPIC_EXPORT std::shared_ptr< spdlog::logger > get(const std::string &name)
Get or create a named logger.
Activate model on GPU (WARM → ACTIVE).
static bool insert_permission_item(std::vector< std::string > &lines, std::string_view pattern, const std::string &perms_key, const std::string &list_line, const std::string &item)
Insert a permission item into the parsed YAML lines.
static bool write_file(const std::filesystem::path &path, const std::string &content)
Write string to file.
static std::vector< std::string > split_lines(const std::string &content)
Split string into lines.
static auto find_section_end(std::vector< std::string > &lines, std::vector< std::string >::iterator start)
Find the end of a YAML section (indented block).
static bool list_contains(const std::vector< std::string > &lines, size_t start, std::string_view pattern)
Check if a YAML sequence already contains a pattern.
static auto find_list_end(std::vector< std::string > &lines, size_t list_start)
Find the end of a YAML sequence (last "- " item).
static std::string join_lines(const std::vector< std::string > &lines)
Join lines back into a string with trailing newline.
Persist permission allow/deny patterns to project config.