File size: 2,762 Bytes
fc8a1d1
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
// pencil_utils.hpp – Core file utilities for PencilClaw coding agent
#ifndef PENCIL_UTILS_HPP
#define PENCIL_UTILS_HPP

#include <iostream>
#include <fstream>
#include <string>
#include <filesystem>
#include <optional>
#include <chrono>
#include <iomanip>
#include <sstream>

namespace pencil {
    // Base directory – can be overridden by environment variable PENCIL_DATA
    inline std::string get_pencil_dir() {
        const char* env = std::getenv("PENCIL_DATA");
        return env ? env : "./pencil_data/";
    }

    inline std::string get_session_log() {
        return get_pencil_dir() + "session.log";
    }

    inline std::string get_tasks_dir() {
        return get_pencil_dir() + "tasks/";
    }

    inline std::string get_active_task_file() {
        return get_pencil_dir() + "active_task.txt";
    }

    // Ensure the working directory exists. Returns true on success or if already exists.
    inline bool init_workspace() {
        std::error_code ec;
        bool created = std::filesystem::create_directory(get_pencil_dir(), ec);
        if (ec) {
            std::cerr << "Error creating directory " << get_pencil_dir() << ": " << ec.message() << std::endl;
            return false;
        }
        // Also create tasks directory
        std::filesystem::create_directory(get_tasks_dir(), ec);
        return true;
    }

    // Append a line to the session log. Returns true on success.
    inline bool append_to_session(const std::string& text) {
        std::ofstream log(get_session_log(), std::ios::app);
        if (!log) return false;
        log << text << std::endl;
        return !log.fail();
    }

    // Read entire file content. Returns std::nullopt if file cannot be opened.
    inline std::optional<std::string> read_file(const std::string& path) {
        std::ifstream f(path);
        if (!f) {
            std::cerr << "Warning: Could not open file: " << path << std::endl;
            return std::nullopt;
        }
        std::string content((std::istreambuf_iterator<char>(f)),
                             std::istreambuf_iterator<char>());
        return content;
    }

    // Save text to a file (overwrite). Returns true on success.
    inline bool save_text(const std::string& path, const std::string& text) {
        std::ofstream f(path);
        if (!f) return false;
        f << text;
        return !f.fail();
    }

    // Get a timestamp string for folder/file names.
    inline std::string timestamp() {
        auto now = std::chrono::system_clock::now();
        auto in_time_t = std::chrono::system_clock::to_time_t(now);
        std::stringstream ss;
        ss << std::put_time(std::localtime(&in_time_t), "%Y%m%d_%H%M%S");
        return ss.str();
    }
}

#endif // PENCIL_UTILS_HPP