Compare commits
17 Commits
polecat/ru
...
a98ccddab1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a98ccddab1 | ||
| 18570628a5 | |||
|
|
0c484b6601 | ||
|
|
4853a18474 | ||
|
|
8b8453a37a | ||
|
|
2b6e289b9a | ||
|
|
70d364544f | ||
|
|
1ffa8524f0 | ||
|
|
be3c27e868 | ||
| c2d286087f | |||
|
|
1172818062 | ||
|
|
9f63e1430c | ||
| b14ef1f62a | |||
| 87719fa9e6 | |||
| 933612da4c | |||
|
|
d2c7599267 | ||
|
|
3d16824eac |
@@ -6,7 +6,7 @@
|
|||||||
# Issue prefix for this repository (used by bd init)
|
# Issue prefix for this repository (used by bd init)
|
||||||
# If not set, bd init will auto-detect from directory name
|
# If not set, bd init will auto-detect from directory name
|
||||||
# Example: issue-prefix: "myproject" creates issues like "myproject-1", "myproject-2", etc.
|
# Example: issue-prefix: "myproject" creates issues like "myproject-1", "myproject-2", etc.
|
||||||
# issue-prefix: ""
|
issue-prefix: "x"
|
||||||
|
|
||||||
# Use no-db mode: load from JSONL, no SQLite, write back after each command
|
# Use no-db mode: load from JSONL, no SQLite, write back after each command
|
||||||
# When true, bd will use .beads/issues.jsonl as the source of truth
|
# When true, bd will use .beads/issues.jsonl as the source of truth
|
||||||
@@ -59,4 +59,6 @@ sync-branch: "beads-sync"
|
|||||||
# - linear.url
|
# - linear.url
|
||||||
# - linear.api-key
|
# - linear.api-key
|
||||||
# - github.org
|
# - github.org
|
||||||
# - github.repo
|
# - github.repo
|
||||||
|
|
||||||
|
routing.mode: "explicit"
|
||||||
5
.gitignore
vendored
5
.gitignore
vendored
@@ -1,3 +1,8 @@
|
|||||||
result
|
result
|
||||||
thoughts
|
thoughts
|
||||||
.beads
|
.beads
|
||||||
|
|
||||||
|
# Gas Town (added by gt)
|
||||||
|
.runtime/
|
||||||
|
.claude/
|
||||||
|
.logs/
|
||||||
|
|||||||
26
flake.lock
generated
26
flake.lock
generated
@@ -8,17 +8,17 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1769020852,
|
"lastModified": 1769304777,
|
||||||
"narHash": "sha256-MR6evuoa8w6mjYTesTAa3bsRH+c3IB7EOEDTCjsiAp8=",
|
"narHash": "sha256-xHeOLst9nSpPIycpz9x7gEXWC7uOF6xvIpymDEzJvog=",
|
||||||
"owner": "steveyegge",
|
"ref": "refs/heads/main",
|
||||||
"repo": "beads",
|
"rev": "bfffc47715f0b3dccde0d0855e64ec7474628d47",
|
||||||
"rev": "cb46db603d34c0190605eecb8724a6c581119f09",
|
"revCount": 5467,
|
||||||
"type": "github"
|
"type": "git",
|
||||||
|
"url": "ssh://git@git.johnogle.info:2222/johno/beads.git"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
"owner": "steveyegge",
|
"type": "git",
|
||||||
"repo": "beads",
|
"url": "ssh://git@git.johnogle.info:2222/johno/beads.git"
|
||||||
"type": "github"
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"doomemacs": {
|
"doomemacs": {
|
||||||
@@ -81,11 +81,11 @@
|
|||||||
"gastown": {
|
"gastown": {
|
||||||
"flake": false,
|
"flake": false,
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1769031452,
|
"lastModified": 1769306394,
|
||||||
"narHash": "sha256-tTvtLvTr38okqbpNnr5exfurI6VkVKNLcnM+A6O7DGY=",
|
"narHash": "sha256-SaVgl40lCEEyy8d8Rb/84EdQRLDkR/0CgUfV4k1l1qE=",
|
||||||
"ref": "refs/heads/main",
|
"ref": "refs/heads/main",
|
||||||
"rev": "93e22595cd59802a24253b100dcfae98a6849428",
|
"rev": "341c7d6757cb90e6e71fad2bf8c0fe2a5acb5a76",
|
||||||
"revCount": 2938,
|
"revCount": 3032,
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "ssh://git@git.johnogle.info:2222/johno/gastown.git"
|
"url": "ssh://git@git.johnogle.info:2222/johno/gastown.git"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -43,7 +43,7 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
beads = {
|
beads = {
|
||||||
url = "github:steveyegge/beads";
|
url = "git+ssh://git@git.johnogle.info:2222/johno/beads.git";
|
||||||
inputs.nixpkgs.follows = "nixpkgs-unstable";
|
inputs.nixpkgs.follows = "nixpkgs-unstable";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -86,12 +86,14 @@ in
|
|||||||
if [ -f "$file" ]; then
|
if [ -f "$file" ]; then
|
||||||
filename=$(basename "$file" .md)
|
filename=$(basename "$file" .md)
|
||||||
dest="$HOME/.claude/commands/humanlayer:''${filename}.md"
|
dest="$HOME/.claude/commands/humanlayer:''${filename}.md"
|
||||||
|
rm -f "$dest" 2>/dev/null || true
|
||||||
|
|
||||||
# Copy file and conditionally remove the "model:" line from frontmatter
|
# Copy file and conditionally remove the "model:" line from frontmatter
|
||||||
${if cfg.allowArbitraryClaudeCodeModelSelection
|
${if cfg.allowArbitraryClaudeCodeModelSelection
|
||||||
then "cp \"$file\" \"$dest\""
|
then "cp \"$file\" \"$dest\""
|
||||||
else "${pkgs.gnused}/bin/sed '/^model:/d' \"$file\" > \"$dest\""
|
else "${pkgs.gnused}/bin/sed '/^model:/d' \"$file\" > \"$dest\""
|
||||||
}
|
}
|
||||||
|
chmod u+w "$dest" 2>/dev/null || true
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
@@ -100,12 +102,14 @@ in
|
|||||||
if [ -f "$file" ]; then
|
if [ -f "$file" ]; then
|
||||||
filename=$(basename "$file" .md)
|
filename=$(basename "$file" .md)
|
||||||
dest="$HOME/.claude/agents/humanlayer:''${filename}.md"
|
dest="$HOME/.claude/agents/humanlayer:''${filename}.md"
|
||||||
|
rm -f "$dest" 2>/dev/null || true
|
||||||
|
|
||||||
# Copy file and conditionally remove the "model:" line from frontmatter
|
# Copy file and conditionally remove the "model:" line from frontmatter
|
||||||
${if cfg.allowArbitraryClaudeCodeModelSelection
|
${if cfg.allowArbitraryClaudeCodeModelSelection
|
||||||
then "cp \"$file\" \"$dest\""
|
then "cp \"$file\" \"$dest\""
|
||||||
else "${pkgs.gnused}/bin/sed '/^model:/d' \"$file\" > \"$dest\""
|
else "${pkgs.gnused}/bin/sed '/^model:/d' \"$file\" > \"$dest\""
|
||||||
}
|
}
|
||||||
|
chmod u+w "$dest" 2>/dev/null || true
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
@@ -120,6 +124,7 @@ in
|
|||||||
sleep 0.5
|
sleep 0.5
|
||||||
cp "$file" "$dest" || echo "Warning: Failed to copy $filename.md to commands"
|
cp "$file" "$dest" || echo "Warning: Failed to copy $filename.md to commands"
|
||||||
fi
|
fi
|
||||||
|
chmod u+w "$dest" 2>/dev/null || true
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
@@ -134,13 +139,17 @@ in
|
|||||||
sleep 0.5
|
sleep 0.5
|
||||||
cp "$file" "$dest" || echo "Warning: Failed to copy $filename.md to skills"
|
cp "$file" "$dest" || echo "Warning: Failed to copy $filename.md to skills"
|
||||||
fi
|
fi
|
||||||
|
chmod u+w "$dest" 2>/dev/null || true
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
# Copy micro-skills (compact reusable knowledge referenced by formulas)
|
# Copy micro-skills (compact reusable knowledge referenced by formulas)
|
||||||
for file in ${./skills/micro}/*.md; do
|
for file in ${./skills/micro}/*.md; do
|
||||||
if [ -f "$file" ]; then
|
if [ -f "$file" ]; then
|
||||||
cp "$file" "$HOME/.claude/commands/skills/$(basename "$file")"
|
dest="$HOME/.claude/commands/skills/$(basename "$file")"
|
||||||
|
rm -f "$dest" 2>/dev/null || true
|
||||||
|
cp "$file" "$dest"
|
||||||
|
chmod u+w "$dest" 2>/dev/null || true
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
@@ -148,7 +157,10 @@ in
|
|||||||
mkdir -p ~/.beads/formulas
|
mkdir -p ~/.beads/formulas
|
||||||
for file in ${./formulas}/*.formula.toml; do
|
for file in ${./formulas}/*.formula.toml; do
|
||||||
if [ -f "$file" ]; then
|
if [ -f "$file" ]; then
|
||||||
cp "$file" "$HOME/.beads/formulas/$(basename "$file")"
|
dest="$HOME/.beads/formulas/$(basename "$file")"
|
||||||
|
rm -f "$dest" 2>/dev/null || true
|
||||||
|
cp "$file" "$dest"
|
||||||
|
chmod u+w "$dest" 2>/dev/null || true
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
|
|||||||
@@ -83,15 +83,108 @@
|
|||||||
"d" #'org-agenda-day-view
|
"d" #'org-agenda-day-view
|
||||||
"w" #'org-agenda-week-view))
|
"w" #'org-agenda-week-view))
|
||||||
|
|
||||||
;; (use-package! org-caldav
|
;; org-caldav: Sync Org entries with Nextcloud CalDAV
|
||||||
;; :defer t
|
;; Setup requirements:
|
||||||
;; :config
|
;; 1. Create Nextcloud app password: Settings -> Security -> Devices & sessions
|
||||||
;; (setq org-caldav-url "https://nextcloud.johnogle.info/remote.php/dav/calendars/johno"
|
;; 2. Store in rbw: rbw add nextcloud-caldav (put app password as the secret)
|
||||||
;; org-caldav-calendar-id "personal"
|
;; 3. Run: doom sync
|
||||||
;; org-icalendar-timezone "America/Los_Angeles"
|
;; 4. Test: M-x my/org-caldav-sync-with-rbw (or SPC o a s)
|
||||||
;; org-caldav-inbox "~/org/calendar.org"
|
;;
|
||||||
;; org-caldav-files nil
|
;; Note: Conflict resolution is "Org always wins" - treat Org as source of truth
|
||||||
;; org-caldav-sync-direction 'cal->org))
|
;; for entries that originated in Org.
|
||||||
|
|
||||||
|
;; Define sync wrapper before use-package (so keybinding works)
|
||||||
|
(defun my/org-caldav-sync-with-rbw ()
|
||||||
|
"Run org-caldav-sync with credentials from rbw embedded in URL."
|
||||||
|
(interactive)
|
||||||
|
(require 'org)
|
||||||
|
(require 'org-caldav)
|
||||||
|
(let* ((password (my/get-rbw-password "nextcloud-caldav"))
|
||||||
|
;; Embed credentials in URL (url-encode password in case of special chars)
|
||||||
|
(encoded-pass (url-hexify-string password)))
|
||||||
|
(setq org-caldav-url
|
||||||
|
(format "https://johno:%s@nextcloud.johnogle.info/remote.php/dav/calendars/johno"
|
||||||
|
encoded-pass))
|
||||||
|
(org-caldav-sync)))
|
||||||
|
|
||||||
|
(use-package! org-caldav
|
||||||
|
:after org
|
||||||
|
:commands (org-caldav-sync my/org-caldav-sync-with-rbw)
|
||||||
|
:init
|
||||||
|
(map! :leader
|
||||||
|
(:prefix ("o" . "open")
|
||||||
|
(:prefix ("a" . "agenda/calendar")
|
||||||
|
:desc "Sync CalDAV" "s" #'my/org-caldav-sync-with-rbw)))
|
||||||
|
:config
|
||||||
|
;; Nextcloud CalDAV base URL (credentials added dynamically by sync wrapper)
|
||||||
|
(setq org-caldav-url "https://nextcloud.johnogle.info/remote.php/dav/calendars/johno")
|
||||||
|
|
||||||
|
;; Timezone for iCalendar export
|
||||||
|
(setq org-icalendar-timezone "America/Los_Angeles")
|
||||||
|
|
||||||
|
;; Sync state storage (in org directory for multi-machine sync)
|
||||||
|
(setq org-caldav-save-directory (expand-file-name ".org-caldav/" org-directory))
|
||||||
|
|
||||||
|
;; Backup file for entries before modification
|
||||||
|
(setq org-caldav-backup-file (expand-file-name ".org-caldav/backup.org" org-directory))
|
||||||
|
|
||||||
|
;; Limit past events to 30 days (avoids downloading years of history)
|
||||||
|
(setq org-caldav-days-in-past 30)
|
||||||
|
|
||||||
|
;; Sync behavior: bidirectional by default
|
||||||
|
(setq org-caldav-sync-direction 'twoway)
|
||||||
|
|
||||||
|
;; What changes from calendar sync back to Org (conservative: title and timestamp only)
|
||||||
|
(setq org-caldav-sync-changes-to-org 'title-and-timestamp)
|
||||||
|
|
||||||
|
;; Deletion handling: ask before deleting
|
||||||
|
(setq org-caldav-delete-calendar-entries 'ask)
|
||||||
|
(setq org-caldav-delete-org-entries 'ask)
|
||||||
|
|
||||||
|
;; Enable TODO/VTODO sync
|
||||||
|
(setq org-icalendar-include-todo 'all)
|
||||||
|
(setq org-caldav-sync-todo t)
|
||||||
|
|
||||||
|
;; Calendar-specific configuration
|
||||||
|
(setq org-caldav-calendars
|
||||||
|
'(;; Personal calendar: two-way sync with family-shared Nextcloud calendar
|
||||||
|
(:calendar-id "personal"
|
||||||
|
:inbox "~/org/personal-calendar.org"
|
||||||
|
:files ("~/org/personal-calendar.org"))
|
||||||
|
|
||||||
|
;; Tasks calendar: one-way sync (org → calendar only)
|
||||||
|
;; SCHEDULED/DEADLINE items from todo.org push to private Tasks calendar.
|
||||||
|
;; No inbox = no download from calendar (effectively one-way).
|
||||||
|
;; Note: Create 'tasks' calendar in Nextcloud first, keep it private.
|
||||||
|
(:calendar-id "tasks"
|
||||||
|
:files ("~/org/todo.org"))))
|
||||||
|
|
||||||
|
;; Handle UNTIL in recurring events
|
||||||
|
;; org-caldav ignores UNTIL from RRULE - events repeat forever.
|
||||||
|
;; This advice extracts UNTIL and adds a DEADLINE without repeater,
|
||||||
|
;; which Org 9.7+ interprets as the recurrence end date.
|
||||||
|
(defun my/org-caldav-add-until-deadline (orig-fun eventdata-alist)
|
||||||
|
"Advice to add DEADLINE for UNTIL in recurring events."
|
||||||
|
(let ((result (funcall orig-fun eventdata-alist)))
|
||||||
|
(let* ((rrule-props (alist-get 'rrule-props eventdata-alist))
|
||||||
|
(until-str (cadr (assq 'UNTIL rrule-props))))
|
||||||
|
(when until-str
|
||||||
|
(save-excursion
|
||||||
|
(org-back-to-heading t)
|
||||||
|
;; Store original UNTIL for reference
|
||||||
|
(org-entry-put nil "CALDAV_UNTIL" until-str)
|
||||||
|
;; Parse UNTIL: format is YYYYMMDD or YYYYMMDDTHHMMSSZ
|
||||||
|
(when (string-match "^\\([0-9]\\{4\\}\\)\\([0-9]\\{2\\}\\)\\([0-9]\\{2\\}\\)" until-str)
|
||||||
|
(let* ((year (string-to-number (match-string 1 until-str)))
|
||||||
|
(month (string-to-number (match-string 2 until-str)))
|
||||||
|
(day (string-to-number (match-string 3 until-str)))
|
||||||
|
(deadline-ts (format "<%d-%02d-%02d>" year month day)))
|
||||||
|
(org-add-planning-info 'deadline deadline-ts))))))
|
||||||
|
result))
|
||||||
|
|
||||||
|
(advice-add 'org-caldav-insert-org-event-or-todo
|
||||||
|
:around #'my/org-caldav-add-until-deadline)
|
||||||
|
)
|
||||||
|
|
||||||
(defun my/get-rbw-password (alias)
|
(defun my/get-rbw-password (alias)
|
||||||
"Return the password for ALIAS via rbw, unlocking the vault only if needed."
|
"Return the password for ALIAS via rbw, unlocking the vault only if needed."
|
||||||
|
|||||||
@@ -49,7 +49,7 @@
|
|||||||
;; ...Or *all* packages (NOT RECOMMENDED; will likely break things)
|
;; ...Or *all* packages (NOT RECOMMENDED; will likely break things)
|
||||||
;; (unpin! t)
|
;; (unpin! t)
|
||||||
|
|
||||||
;; (package! org-caldav)
|
(package! org-caldav)
|
||||||
|
|
||||||
;; Note: Packages with custom recipes must be pinned for nix-doom-emacs-unstraightened
|
;; Note: Packages with custom recipes must be pinned for nix-doom-emacs-unstraightened
|
||||||
;; to build deterministically. Update pins when upgrading packages.
|
;; to build deterministically. Update pins when upgrading packages.
|
||||||
|
|||||||
Reference in New Issue
Block a user