{"id":10638,"date":"2026-01-27T20:33:47","date_gmt":"2026-01-27T11:33:47","guid":{"rendered":"https:\/\/code-plus.jp\/gp\/?p=10638"},"modified":"2026-03-02T16:09:24","modified_gmt":"2026-03-02T07:09:24","slug":"claudecode-obsidian-10638","status":"publish","type":"post","link":"https:\/\/code-plus.jp\/gp\/claudecode-obsidian-10638\/","title":{"rendered":"Claude Code\u306e\u4f1a\u8a71\u30ed\u30b0\u3092Obsidian\u306b\u81ea\u52d5\u4fdd\u5b58\u3059\u308b\u4ed5\u7d44\u307f\u3092\u8a66\u3057\u3066\u307f\u305f"},"content":{"rendered":"<p><cite><a href=\"https:\/\/zenn.dev\/kentaro\" class=\"link\" target=\"_blank\">@kentaro<\/a><\/cite> \u3055\u3093\u306e\u8a18\u4e8b\u300c<cite><a href=\"https:\/\/zenn.dev\/pepabo\/articles\/ffb79b5279f6ee\" class=\"link\" target=\"_blank\">\u4f1a\u8a71\u3092\u81ea\u52d5\u3067Obsidian\u306b\u8a18\u9332\u3059\u308b\u4ed5\u7d44\u307f\u3092\u4f5c\u3063\u305f<\/a><\/cite> \u300d\u3092\u898b\u3066\u3001Claude Code\u3068\u306e\u4f1a\u8a71\u3092\u81ea\u52d5\u3067Obsidian\u306b\u8a18\u9332\u3059\u308b\u4ed5\u7d44\u307f\u3092\u5c0e\u5165\u3057\u3066\u307f\u307e\u3057\u305f\u3002<\/p>\r\n<p>\u975e\u5e38\u306b\u4fbf\u5229\u306a\u4ed5\u7d44\u307f\u3067\u3059\u304c\u3001\u5b9f\u969b\u306b\u52d5\u304b\u3059\u307e\u3067\u306b\u3044\u304f\u3064\u304b\u30cf\u30de\u3063\u305f\u30dd\u30a4\u30f3\u30c8\u304c\u3042\u3063\u305f\u306e\u3067\u3001\u89e3\u6c7a\u7b56\u3068\u3068\u3082\u306b\u5171\u6709\u3057\u307e\u3059\u3002<\/p>\r\n\r\n <!-- \u2605\u76ee\u6b21\u30ea\u30b9\u30c8 -->\r\n<ul class=\"tocList mt-1r\" data-toc-id=\"js-tocBWGD\" style=\"height:28rem\"><\/ul>\r\n<ins class=\"tocBtn is-fixed\" data-toc-id=\"js-tocBWGD\"><\/ins>\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n<h2 class=\"fz-xl\">\u5143\u8a18\u4e8b\u306e\u4ed5\u7d44\u307f\uff08\u6982\u8981\uff09<\/h2>\r\n<pre><code class=\"language-\">Claude Code \u30bb\u30c3\u30b7\u30e7\u30f3\r\n    \u2193 (jsonl\u30d5\u30a1\u30a4\u30eb\u306b\u8a18\u9332)\r\n~\/.claude\/projects\/*\/session.jsonl\r\n    \u2193 (5\u79d2\u3054\u3068\u306b\u76e3\u8996)\r\nwatch-and-save.sh (LaunchAgent\u3067\u5e38\u99d0)\r\n    \u2193 (\u5909\u66f4\u691c\u77e5\u6642\u306b\u62bd\u51fa\u30fb\u6574\u5f62)\r\n~\/obsidian\/claude\/YYYY-M-D.md\r\n<\/code><\/pre>\r\n\r\n\r\n<h2 class=\"fz-xl\">\u767a\u751f\u3057\u305f\u554f\u984c\u3068\u89e3\u6c7a\u7b56<\/h2>\r\n\r\n<h3 class=\"fz-ml\">\u554f\u984c1: jq\u304c\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\u3055\u308c\u3066\u3044\u306a\u3044<\/h3>\r\n<p>\u5143\u8a18\u4e8b\u306e\u30b9\u30af\u30ea\u30d7\u30c8\u306f<code>jq<\/code>\uff08JSON\u30d1\u30fc\u30b5\u30fc\uff09\u3092\u4f7f\u7528\u3057\u307e\u3059\u304c\u3001macOS\u306b\u306f\u30c7\u30d5\u30a9\u30eb\u30c8\u3067\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\u3055\u308c\u3066\u3044\u307e\u305b\u3093\u3002<\/p>\r\n<pre><code class=\"language-bash\"># \u78ba\u8a8d\r\nwhich jq\r\n# \u2192 jq not found\r\n\r\n# \u89e3\u6c7a\u7b56\r\nbrew install jq\r\n<\/code><\/pre>\r\n\r\n<h3 class=\"fz-ml\">\u554f\u984c2: plist\u3067<code>~<\/code>\u304c\u5c55\u958b\u3055\u308c\u306a\u3044<\/h3>\r\n<p>\u5143\u8a18\u4e8b\u306eLaunchAgent\u8a2d\u5b9a\uff1a<\/p>\r\n<pre><code class=\"language-xml\">&lt;string&gt;~\/.claude\/hooks\/watch-and-save.sh&lt;\/string&gt;\r\n<\/code><\/pre>\r\n<p>LaunchAgent\u306eplist\u3067\u306f<code>~<\/code>\u304c\u5c55\u958b\u3055\u308c\u306a\u3044\u305f\u3081\u3001\u7d76\u5bfe\u30d1\u30b9\u306b\u5909\u66f4\u3059\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002<\/p>\r\n<pre><code class=\"language-xml\">&lt;!-- \u4fee\u6b63\u5f8c --&gt;\r\n&lt;string&gt;\/Users\/[\u30e6\u30fc\u30b6\u30fc\u540d]\/.claude\/hooks\/watch-and-save.sh&lt;\/string&gt;\r\n&lt;string&gt;\/Users\/[\u30e6\u30fc\u30b6\u30fc\u540d]\/.claude\/logs\/obsidian-sync.log&lt;\/string&gt;\r\n&lt;string&gt;\/Users\/[\u30e6\u30fc\u30b6\u30fc\u540d]\/.claude\/logs\/obsidian-sync-error.log&lt;\/string&gt;\r\n<\/code><\/pre>\r\n\r\n<h3 class=\"fz-ml\">\u554f\u984c3: \u30e6\u30fc\u30b6\u30fc\u30e1\u30c3\u30bb\u30fc\u30b8\u304c\u914d\u5217\u306e\u5834\u5408\u306b\u5bfe\u5fdc\u3057\u3066\u3044\u306a\u3044<\/h3>\r\n<p>\u3053\u308c\u304c\u6700\u5927\u306e\u30cf\u30de\u308a\u30dd\u30a4\u30f3\u30c8\u3067\u3057\u305f\u3002<\/p>\r\n<p>Claude Code\u306e\u30bb\u30c3\u30b7\u30e7\u30f3\u30d5\u30a1\u30a4\u30eb\u3067\u306f\u3001\u30e6\u30fc\u30b6\u30fc\u30e1\u30c3\u30bb\u30fc\u30b8\u306e<code>.message.content<\/code>\u304c<b class=\"fw-600\">\u6587\u5b57\u5217\u306e\u5834\u5408\u3068\u914d\u5217\u306e\u5834\u5408<\/b>\u304c\u3042\u308a\u307e\u3059\u3002<\/p>\r\n<pre><code class=\"language-json\">\/\/ \u6587\u5b57\u5217\u306e\u5834\u5408\uff08\u5143\u30b9\u30af\u30ea\u30d7\u30c8\u304c\u60f3\u5b9a\uff09\r\n{&quot;type&quot;: &quot;user&quot;, &quot;message&quot;: {&quot;content&quot;: &quot;\u3053\u3093\u306b\u3061\u306f&quot;}}\r\n\r\n\/\/ \u914d\u5217\u306e\u5834\u5408\uff08\u30c4\u30fc\u30eb\u5b9f\u884c\u7d50\u679c\u306a\u3069\uff09\r\n{&quot;type&quot;: &quot;user&quot;, &quot;message&quot;: {&quot;content&quot;: [{&quot;type&quot;: &quot;text&quot;, &quot;text&quot;: &quot;\u3053\u3093\u306b\u3061\u306f&quot;}]}}\r\n<\/code><\/pre>\r\n<p>\u5143\u30b9\u30af\u30ea\u30d7\u30c8\u306ejq\u30d5\u30a3\u30eb\u30bf\u306f\u6587\u5b57\u5217\u306e\u307f\u3092\u60f3\u5b9a\u3057\u3066\u3044\u305f\u305f\u3081\u3001\u914d\u5217\u306e\u5834\u5408\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u3066\u3044\u307e\u3057\u305f\u3002<\/p>\r\n\r\n<h3 class=\"fz-ml\">\u554f\u984c4: \u65b0\u3057\u3044\u30bb\u30c3\u30b7\u30e7\u30f3\u3067\u5185\u5bb9\u304c\u8a18\u9332\u3055\u308c\u306a\u3044<\/h3>\r\n<p>\u30bb\u30c3\u30b7\u30e7\u30f3\u30d8\u30c3\u30c0\u30fc\u306f\u66f8\u304d\u8fbc\u307e\u308c\u308b\u306e\u306b\u3001\u4f1a\u8a71\u5185\u5bb9\u304c\u7a7a\u3068\u3044\u3046\u75c7\u72b6\u304c\u767a\u751f\u3057\u307e\u3057\u305f\u3002<\/p>\r\n<p><b class=\"fw-600\">\u539f\u56e0<\/b>: \u65b0\u3057\u3044\u30bb\u30c3\u30b7\u30e7\u30f3\u691c\u51fa\u6642\u306b\u3001\u904e\u53bb\u306e\u8ffd\u8de1\u30d5\u30a1\u30a4\u30eb\uff08<code>last_line_file<\/code>\uff09\u306e\u5024\u3092\u4f7f\u3063\u3066\u3044\u305f\u305f\u3081\u3001\u300c\u65b0\u3057\u3044\u884c\u304c\u306a\u3044\u300d\u3068\u5224\u5b9a\u3055\u308c\u3066\u3044\u307e\u3057\u305f\u3002<\/p>\r\n\r\n<h3 class=\"fz-ml\">\u554f\u984c5: LaunchAgent\u74b0\u5883\u3067jq\u306ePATH\u304c\u901a\u3089\u306a\u3044<\/h3>\r\n<p><b class=\"fw-600\">\u6700\u3082\u30cf\u30de\u308a\u3084\u3059\u3044\u554f\u984c<\/b>\u3067\u3059\u3002\u30bb\u30c3\u30c8\u30a2\u30c3\u30d7\u76f4\u5f8c\u306f\u52d5\u304f\u306e\u306b\u3001<b class=\"fw-600\">Mac\u518d\u8d77\u52d5\u5f8c\u306b\u4f1a\u8a71\u5185\u5bb9\u304c\u8a18\u9332\u3055\u308c\u306a\u304f\u306a\u308b<\/b>\u3068\u3044\u3046\u75c7\u72b6\u304c\u767a\u751f\u3057\u307e\u3057\u305f\u3002<\/p>\r\n<p><b class=\"fw-600\">\u539f\u56e0<\/b>: LaunchAgent\u306e\u30c7\u30d5\u30a9\u30eb\u30c8PATH\u306f <code>\/usr\/bin:\/bin:\/usr\/sbin:\/sbin<\/code> \u306e\u307f\u3067\u3059\u3002Homebrew\u3067\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\u3057\u305f<code>jq<\/code>\u306f <code>\/usr\/local\/bin\/jq<\/code>\uff08Intel Mac\uff09\u307e\u305f\u306f <code>\/opt\/homebrew\/bin\/jq<\/code>\uff08Apple Silicon\uff09\u306b\u914d\u7f6e\u3055\u308c\u307e\u3059\u304c\u3001\u3053\u306e\u30d1\u30b9\u306fLaunchAgent\u306ePATH\u306b\u542b\u307e\u308c\u3066\u3044\u307e\u305b\u3093\u3002<\/p>\r\n<p>\u521d\u56de\u30bb\u30c3\u30c8\u30a2\u30c3\u30d7\u6642\u306f\u30b7\u30a7\u30eb\u306ePATH\u8a2d\u5b9a\u304c\u5f15\u304d\u7d99\u304c\u308c\u3066\u52d5\u4f5c\u3057\u307e\u3059\u304c\u3001Mac\u518d\u8d77\u52d5\u5f8c\u306bLaunchAgent\u304c\u518d\u958b\u3055\u308c\u308b\u3068PATH\u304c\u30c7\u30d5\u30a9\u30eb\u30c8\u306b\u623b\u308a\u3001<code>jq<\/code>\u304c\u898b\u3064\u304b\u3089\u306a\u304f\u306a\u308a\u307e\u3059\u3002<\/p>\r\n<p>\u30b9\u30af\u30ea\u30d7\u30c8\u5185\u3067<code>2&gt;\/dev\/null<\/code>\u3068\u3057\u3066\u3044\u308b\u3068\u30a8\u30e9\u30fc\u304c\u63e1\u308a\u6f70\u3055\u308c\u3001\u539f\u56e0\u306e\u7279\u5b9a\u304c\u975e\u5e38\u306b\u56f0\u96e3\u306b\u306a\u308a\u307e\u3059\u3002<\/p>\r\n<pre><code class=\"language-\"># \u78ba\u8a8d\u65b9\u6cd5\uff1aLaunchAgent\u74b0\u5883\u3092\u30b7\u30df\u30e5\u30ec\u30fc\u30c8\u3057\u3066jq\u304c\u898b\u3064\u304b\u308b\u304b\u78ba\u8a8d\r\nenv -i PATH=&quot;\/usr\/bin:\/bin:\/usr\/sbin:\/sbin&quot; bash -c &#39;which jq&#39;\r\n# \u2192 jq not found \u2190 \u3053\u308c\u304c\u539f\u56e0\r\n\r\n# \u89e3\u6c7a\u7b56\uff1a\u30b9\u30af\u30ea\u30d7\u30c8\u306e\u5148\u982d\u3067PATH\u3092\u8ffd\u52a0\r\nexport PATH=&quot;\/usr\/local\/bin:\/opt\/homebrew\/bin:$PATH&quot;\r\n<\/code><\/pre>\r\n\r\n<h2 class=\"fz-xl\">\u4fee\u6b63\u7248\u30b9\u30af\u30ea\u30d7\u30c8<\/h2>\r\n<p>\u4e0a\u8a18\u306e\u554f\u984c\u3092\u3059\u3079\u3066\u89e3\u6c7a\u3057\u3001\u3055\u3089\u306b<b class=\"fw-600\">\u30bb\u30c3\u30b7\u30e7\u30f3\u533a\u5207\u308a\u6a5f\u80fd<\/b>\u3092\u8ffd\u52a0\u3057\u305f\u4fee\u6b63\u7248\u30b9\u30af\u30ea\u30d7\u30c8\u3067\u3059\u3002<\/p>\r\n<p><code>~\/.claude\/hooks\/watch-and-save.sh<\/code>:<\/p>\r\n<pre><code class=\"language-bash\">#!\/bin\/bash\r\n# Watch Claude Code session and sync to Obsidian in real-time (append mode)\r\n\r\n# Ensure Homebrew tools (jq etc.) are accessible in LaunchAgent environment\r\nexport PATH=&quot;\/usr\/local\/bin:\/opt\/homebrew\/bin:$PATH&quot;\r\n\r\nOBSIDIAN_DIR=&quot;$HOME\/Dropbox\/Obsidian\/claude&quot;  # \u2190 \u81ea\u5206\u306eObsidian vault\u306b\u5909\u66f4\r\nSESSION_DIR=&quot;$HOME\/.claude\/projects&quot;\r\nLAST_LINE_FILE=&quot;$HOME\/.claude\/last-synced-line&quot;\r\nLAST_SESSION_FILE=&quot;$HOME\/.claude\/last-session-file&quot;\r\nLOG_FILE=&quot;$HOME\/.claude\/watch-and-save.log&quot;\r\n\r\nmkdir -p &quot;$OBSIDIAN_DIR&quot;\r\n\r\nlog() {\r\n    echo &quot;&lsqb;$(date &#39;+%Y-%m-%d %H:%M:%S&#39;)&rsqb; $*&quot; &gt;&gt; &quot;$LOG_FILE&quot;\r\n}\r\n\r\n# Truncate string to specified character length (handles multibyte)\r\ntruncate_string() {\r\n    local str=&quot;$1&quot;\r\n    local max_len=&quot;${2:-30}&quot;\r\n    str=$(echo &quot;$str&quot; | tr &#39;n&#39; &#39; &#39; | sed &#39;s\/  *\/ \/g&#39;)\r\n    echo &quot;$str&quot; | awk -v len=&quot;$max_len&quot; &#39;{\r\n        if (length($0) &gt; len) {\r\n            print substr($0, 1, len) &quot;...&quot;\r\n        } else {\r\n            print $0\r\n        }\r\n    }&#39;\r\n}\r\n\r\n# Get first user message from session file\r\nget_first_user_message() {\r\n    local session_file=&quot;$1&quot;\r\n    head -100 &quot;$session_file&quot; | jq -r &#39;\r\n        select(.type == &quot;user&quot;) |\r\n        if (.message.content | type) == &quot;array&quot; then\r\n            (.message.content | map(select(.type == &quot;text&quot;) | .text) | join(&quot; &quot;))\r\n        elif (.message.content | type) == &quot;string&quot; then\r\n            .message.content\r\n        elif (.content | type) == &quot;string&quot; then\r\n            .content\r\n        else\r\n            &quot;&quot;\r\n        end\r\n    &#39; 2&gt;&gt;&quot;$LOG_FILE&quot; | grep -v &#39;^___PRE_BLOCK_6___#39; | head -1\r\n}\r\n\r\nsync_session() {\r\n    local session_file=&quot;$1&quot;\r\n    local TODAY=$(date +%Y-%-m-%-d)\r\n    local OUTPUT_FILE=&quot;${OBSIDIAN_DIR}\/${TODAY}.md&quot;\r\n    local CURRENT_TIME=$(date &#39;+%H:%M:%S&#39;)\r\n\r\n    # Create file with header if it doesn&#39;t exist\r\n    if &lsqb; ! -f &quot;$OUTPUT_FILE&quot; &rsqb;; then\r\n        echo &quot;# ${TODAY} Claude\u3068\u306e\u4f1a\u8a71&quot; &gt; &quot;$OUTPUT_FILE&quot;\r\n        echo &quot;&quot; &gt;&gt; &quot;$OUTPUT_FILE&quot;\r\n    fi\r\n\r\n    # Check if this is a new session\r\n    local last_session=&quot;&quot;\r\n    if &lsqb; -f &quot;$LAST_SESSION_FILE&quot; &rsqb;; then\r\n        last_session=$(cat &quot;$LAST_SESSION_FILE&quot; 2&gt;\/dev\/null || echo &quot;&quot;)\r\n    fi\r\n\r\n    local is_new_session=false\r\n    if &lsqb; &quot;$session_file&quot; != &quot;$last_session&quot; &rsqb;; then\r\n        is_new_session=true\r\n    fi\r\n\r\n    # Get last synced line number for this specific session file\r\n    local session_hash=$(echo &quot;$session_file&quot; | md5 -q | cut -c1-8)\r\n    local last_line_file=&quot;${LAST_LINE_FILE}_${session_hash}&quot;\r\n\r\n    local last_line=0\r\n    # Only use saved line number if this is NOT a new session\r\n    if &lsqb; &quot;$is_new_session&quot; = false &rsqb; &amp;&amp; &lsqb; -f &quot;$last_line_file&quot; &rsqb;; then\r\n        last_line=$(cat &quot;$last_line_file&quot; 2&gt;\/dev\/null || echo 0)\r\n    fi\r\n\r\n    # Count current lines in session file\r\n    local current_lines=$(wc -l &lt; &quot;$session_file&quot; | tr -d &#39; &#39;)\r\n\r\n    # Only process new lines\r\n    if &lsqb; &quot;$current_lines&quot; -gt &quot;$last_line&quot; &rsqb;; then\r\n        # Check if session changed - add header\r\n        if &lsqb; &quot;$session_file&quot; != &quot;$last_session&quot; &rsqb;; then\r\n            local first_msg=$(get_first_user_message &quot;$session_file&quot;)\r\n            local truncated_msg=$(truncate_string &quot;$first_msg&quot; 30)\r\n            \r\n            echo &quot;&quot; &gt;&gt; &quot;$OUTPUT_FILE&quot;\r\n            echo &quot;---&quot; &gt;&gt; &quot;$OUTPUT_FILE&quot;\r\n            echo &quot;&quot; &gt;&gt; &quot;$OUTPUT_FILE&quot;\r\n            echo &quot;## ${TODAY} ${CURRENT_TIME} ${truncated_msg}&quot; &gt;&gt; &quot;$OUTPUT_FILE&quot;\r\n            echo &quot;&quot; &gt;&gt; &quot;$OUTPUT_FILE&quot;\r\n            \r\n            echo &quot;$session_file&quot; &gt; &quot;$LAST_SESSION_FILE&quot;\r\n            log &quot;New session detected: $session_file&quot;\r\n        fi\r\n\r\n        local new_content=$(tail -n +$((last_line + 1)) &quot;$session_file&quot; | jq -r &#39;\r\n        select(.type == &quot;user&quot; or .type == &quot;assistant&quot;) |\r\n        if .type == &quot;user&quot; then\r\n            # Handle both string and array content\r\n            (if (.message.content | type) == &quot;array&quot; then\r\n                (.message.content | map(select(.type == &quot;text&quot;) | .text) | join(&quot; &quot;))\r\n            elif (.message.content | type) == &quot;string&quot; then\r\n                .message.content\r\n            elif (.content | type) == &quot;string&quot; then\r\n                .content\r\n            else\r\n                &quot;&quot;\r\n            end) as $content |\r\n            if ($content | length) &gt; 0 then\r\n                if ($content | test(&quot;&lt;local-command|&lt;command-name&gt;|&lt;system-reminder&gt;|&lt;task-notification&gt;&quot;; &quot;i&quot;)) then\r\n                    empty\r\n                else\r\n                    &quot;&lt;strong&gt;\u30e6\u30fc\u30b6\u30fc&lt;\/strong&gt;: &quot; + $content\r\n                end\r\n            else\r\n                empty\r\n            end\r\n        elif .type == &quot;assistant&quot; then\r\n            if (.message.content | type) == &quot;array&quot; then\r\n                (.message.content&lsqb;&rsqb; | select(.type == &quot;text&quot;) |\r\n                    if (.text | test(&quot;^No response requested&quot;; &quot;i&quot;)) then\r\n                        empty\r\n                    else\r\n                        &quot;&lt;strong&gt;Claude&lt;\/strong&gt;: &quot; + .text\r\n                    end\r\n                )\r\n            else\r\n                empty\r\n            end\r\n        else\r\n            empty\r\n        end\r\n        &#39; 2&gt;&gt;&quot;$LOG_FILE&quot;)\r\n\r\n        if &lsqb; -n &quot;$new_content&quot; &rsqb;; then\r\n            echo &quot;$new_content&quot; &gt;&gt; &quot;$OUTPUT_FILE&quot;\r\n            echo &quot;&quot; &gt;&gt; &quot;$OUTPUT_FILE&quot;\r\n            log &quot;Synced $((current_lines - last_line)) new lines to $OUTPUT_FILE&quot;\r\n            # \u30b3\u30f3\u30c6\u30f3\u30c4\u62bd\u51fa\u6210\u529f\u6642\u306e\u307f\u884c\u30ab\u30a6\u30f3\u30bf\u3092\u66f4\u65b0\uff08\u5931\u6557\u6642\u306f\u30ea\u30c8\u30e9\u30a4\u53ef\u80fd\u306b\u3059\u308b\uff09\r\n            echo &quot;$current_lines&quot; &gt; &quot;$last_line_file&quot;\r\n        fi\r\n    fi\r\n}\r\n\r\nfind_session() {\r\n    find &quot;$SESSION_DIR&quot; -path &quot;*\/subagents\/*&quot; -prune -o \r\n        -name &quot;*.jsonl&quot; -type f -mmin -60 -size +1000c -print \r\n        2&gt;\/dev\/null | xargs ls -t 2&gt;\/dev\/null | head -1\r\n}\r\n\r\necho &quot;Watching for Claude session changes (append mode)...&quot;\r\nlog &quot;Started watching for Claude session changes&quot;\r\n\r\nwhile true; do\r\n    SESSION=$(find_session) || true\r\n    if &lsqb; -n &quot;$SESSION&quot; &rsqb;; then\r\n        sync_session &quot;$SESSION&quot; || log &quot;Error syncing session: $SESSION&quot;\r\n    fi\r\n    sleep 5\r\ndone\r\n<\/code><\/pre>\r\n\r\n\r\n<h2 class=\"fz-xl\">\u4fee\u6b63\u7248LaunchAgent<\/h2>\r\n<p><code>~\/Library\/LaunchAgents\/com.claude.obsidian-sync.plist<\/code>:<\/p>\r\n<pre><code class=\"language-xml\">&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;\r\n&lt;!DOCTYPE plist PUBLIC &quot;-\/\/Apple\/\/DTD PLIST 1.0\/\/EN&quot;\r\n    &quot;http:\/\/www.apple.com\/DTDs\/PropertyList-1.0.dtd&quot;&gt;\r\n&lt;plist version=&quot;1.0&quot;&gt;\r\n&lt;dict&gt;\r\n    &lt;key&gt;Label&lt;\/key&gt;\r\n    &lt;string&gt;com.claude.obsidian-sync&lt;\/string&gt;\r\n    &lt;key&gt;ProgramArguments&lt;\/key&gt;\r\n    &lt;array&gt;\r\n        &lt;string&gt;\/bin\/bash&lt;\/string&gt;\r\n        &lt;string&gt;\/Users\/&lsqb;\u30e6\u30fc\u30b6\u30fc\u540d&rsqb;\/.claude\/hooks\/watch-and-save.sh&lt;\/string&gt;\r\n    &lt;\/array&gt;\r\n    &lt;key&gt;RunAtLoad&lt;\/key&gt;\r\n    &lt;true\/&gt;\r\n    &lt;key&gt;KeepAlive&lt;\/key&gt;\r\n    &lt;true\/&gt;\r\n    &lt;key&gt;StandardOutPath&lt;\/key&gt;\r\n    &lt;string&gt;\/Users\/&lsqb;\u30e6\u30fc\u30b6\u30fc\u540d&rsqb;\/.claude\/logs\/obsidian-sync.log&lt;\/string&gt;\r\n    &lt;key&gt;StandardErrorPath&lt;\/key&gt;\r\n    &lt;string&gt;\/Users\/&lsqb;\u30e6\u30fc\u30b6\u30fc\u540d&rsqb;\/.claude\/logs\/obsidian-sync-error.log&lt;\/string&gt;\r\n&lt;\/dict&gt;\r\n&lt;\/plist&gt;\r\n<\/code><\/pre>\r\n<p>\u6ce8\u610f: <code>\/Users\/[\u30e6\u30fc\u30b6\u30fc\u540d]\/<\/code> \u306f\u81ea\u5206\u306e\u30db\u30fc\u30e0\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u306b\u7f6e\u304d\u63db\u3048\u3066\u304f\u3060\u3055\u3044\u3002<\/p>\r\n\r\n\r\n<h2 class=\"fz-xl\">\u30bb\u30c3\u30c8\u30a2\u30c3\u30d7\u624b\u9806<\/h2>\r\n<pre><code class=\"language-bash\"># 1. jq\u3092\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\r\nbrew install jq\r\n\r\n# 2. \u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u4f5c\u6210\r\nmkdir -p ~\/.claude\/hooks\r\nmkdir -p ~\/.claude\/logs\r\n\r\n# 3. \u30b9\u30af\u30ea\u30d7\u30c8\u3092\u914d\u7f6e\uff08\u4e0a\u8a18\u306e\u5185\u5bb9\u3092\u4fdd\u5b58\uff09\r\nnano ~\/.claude\/hooks\/watch-and-save.sh\r\n\r\n# 4. \u5b9f\u884c\u6a29\u9650\u3092\u4ed8\u4e0e\r\nchmod +x ~\/.claude\/hooks\/watch-and-save.sh\r\n\r\n# 5. plist\u3092\u914d\u7f6e\uff08\u4e0a\u8a18\u306e\u5185\u5bb9\u3092\u4fdd\u5b58\u3001\u30d1\u30b9\u3092\u81ea\u5206\u306e\u3082\u306e\u306b\u5909\u66f4\uff09\r\nnano ~\/Library\/LaunchAgents\/com.claude.obsidian-sync.plist\r\n\r\n# 6. LaunchAgent\u3092\u8aad\u307f\u8fbc\u307f\r\nlaunchctl load ~\/Library\/LaunchAgents\/com.claude.obsidian-sync.plist\r\n\r\n# 7. \u52d5\u4f5c\u78ba\u8a8d\r\nlaunchctl list | grep claude\r\n# \u2192 PID\u304c\u8868\u793a\u3055\u308c\u308c\u3070OK\r\n<\/code><\/pre>\r\n\r\n\r\n<h2 class=\"fz-xl\">\u51fa\u529b\u4f8b<\/h2>\r\n<p>\u4fee\u6b63\u7248\u3067\u306f\u3001\u30bb\u30c3\u30b7\u30e7\u30f3\u3054\u3068\u306b\u533a\u5207\u308a\u304c\u5165\u308a\u307e\u3059\uff1a<\/p>\r\n<pre><code class=\"language-markdown\"># 2026-1-27 Claude\u3068\u306e\u4f1a\u8a71\r\n\r\n---\r\n\r\n## 2026-1-27 12:01:55 watch-and-save.sh \u304c\u6b63\u5e38\u306b\u52d5\u304d\u305d\u3046...\r\n\r\n&lt;strong&gt;\u30e6\u30fc\u30b6\u30fc&lt;\/strong&gt;: \/Users\/sara-hina\/.claude\/hooks\/watch-and-save.sh \u304c\u6b63\u5e38\u306b\u52d5\u304d\u305d\u3046\u304b\u30c1\u30a7\u30c3\u30af\u3057\u3066\u3082\u3089\u3048\u307e\u3059\u304b\u3002\r\n&lt;strong&gt;Claude&lt;\/strong&gt;: \u30b9\u30af\u30ea\u30d7\u30c8\u3092\u78ba\u8a8d\u3057\u307e\u3057\u305f\u3002\u3044\u304f\u3064\u304b\u554f\u984c\u70b9\u3068\u6539\u5584\u63d0\u6848\u304c\u3042\u308a\u307e\u3059\u3002\r\n...\r\n\r\n---\r\n\r\n## 2026-1-27 14:30:22 \u30de\u30cb\u30e5\u30a2\u30eb\u751f\u6210\u3092\u958b\u59cb\u3057\u3066\u304f\u3060\u3055\u3044\r\n\r\n&lt;strong&gt;\u30e6\u30fc\u30b6\u30fc&lt;\/strong&gt;: \u30de\u30cb\u30e5\u30a2\u30eb\u751f\u6210\u3092\u958b\u59cb\u3057\u3066\u304f\u3060\u3055\u3044\r\n&lt;strong&gt;Claude&lt;\/strong&gt;: \u30de\u30cb\u30e5\u30a2\u30eb\u751f\u6210\u3092\u958b\u59cb\u3057\u307e\u3059\u3002\r\n...\r\n<\/code><\/pre>\r\n\r\n\r\n<h2 class=\"fz-xl\">\u5143\u8a18\u4e8b\u3068\u306e\u4e3b\u306a\u9055\u3044<\/h2>\r\n<table class=\"table tbl-responsive\">\r\n  <thead>\r\n    <tr class=\"rung\">\r\n      <th>\u9805\u76ee<\/th>\r\n      <td>\u5143\u8a18\u4e8b<\/td>\r\n      <td>\u4fee\u6b63\u7248<\/td>\r\n    <\/tr>\r\n  <\/thead>\r\n  <tbody>\r\n    <tr class=\"rung\">\r\n      <th>\u30e6\u30fc\u30b6\u30fc\u30e1\u30c3\u30bb\u30fc\u30b8<\/th>\r\n      <td>\u6587\u5b57\u5217\u306e\u307f\u5bfe\u5fdc<\/td>\r\n      <td>\u914d\u5217\u306b\u3082\u5bfe\u5fdc<\/td>\r\n    <\/tr>\r\n    <tr class=\"rung\">\r\n      <th>\u30bb\u30c3\u30b7\u30e7\u30f3\u533a\u5207\u308a<\/th>\r\n      <td>\u306a\u3057<\/td>\r\n      <td><code>---<\/code>\u3068\u898b\u51fa\u3057\u3067\u533a\u5207\u308a<\/td>\r\n    <\/tr>\r\n    <tr class=\"rung\">\r\n      <th>\u30ed\u30b0\u6a5f\u80fd<\/th>\r\n      <td>\u306a\u3057<\/td>\r\n      <td><code>~\/.claude\/watch-and-save.log<\/code><\/td>\r\n    <\/tr>\r\n    <tr class=\"rung\">\r\n      <th>\u65b0\u30bb\u30c3\u30b7\u30e7\u30f3\u51e6\u7406<\/th>\r\n      <td>\u904e\u53bb\u306e\u884c\u6570\u3092\u5f15\u304d\u7d99\u3050<\/td>\r\n      <td>0\u304b\u3089\u958b\u59cb<\/td>\r\n    <\/tr>\r\n    <tr class=\"rung\">\r\n      <th>plist\u30d1\u30b9<\/th>\r\n      <td><code>~<\/code>\u4f7f\u7528<\/td>\r\n      <td>\u7d76\u5bfe\u30d1\u30b9<\/td>\r\n    <\/tr>\r\n    <tr class=\"rung\">\r\n      <th>jq\u306ePATH<\/th>\r\n      <td>\u672a\u8a2d\u5b9a<\/td>\r\n      <td><code>\/usr\/local\/bin<\/code>\u7b49\u3092\u660e\u793a\u7684\u306b\u8ffd\u52a0<\/td>\r\n    <\/tr>\r\n    <tr class=\"rung\">\r\n      <th>\u30a8\u30e9\u30fc\u30ed\u30b0<\/th>\r\n      <td><code>2&gt;\/dev\/null<\/code>\u3067\u7834\u68c4<\/td>\r\n      <td>\u30ed\u30b0\u30d5\u30a1\u30a4\u30eb\u306b\u8a18\u9332<\/td>\r\n    <\/tr>\r\n    <tr class=\"rung\">\r\n      <th>\u884c\u30ab\u30a6\u30f3\u30bf<\/th>\r\n      <td>\u5e38\u306b\u66f4\u65b0<\/td>\r\n      <td>\u30b3\u30f3\u30c6\u30f3\u30c4\u62bd\u51fa\u6210\u529f\u6642\u306e\u307f\u66f4\u65b0<\/td>\r\n    <\/tr>\r\n  <\/tbody>\r\n<\/table>\r\n\r\n\r\n<h2 class=\"fz-xl\">\u30c8\u30e9\u30d6\u30eb\u30b7\u30e5\u30fc\u30c6\u30a3\u30f3\u30b0<\/h2>\r\n\r\n<h3 class=\"fz-ml\">\u30ed\u30b0\u304c\u8a18\u9332\u3055\u308c\u306a\u3044\u5834\u5408<\/h3>\r\n<pre><code class=\"language-bash\"># \u30a8\u30e9\u30fc\u30ed\u30b0\u3092\u78ba\u8a8d\r\ncat ~\/.claude\/logs\/obsidian-sync-error.log\r\n\r\n# \u901a\u5e38\u30ed\u30b0\u3092\u78ba\u8a8d\r\ncat ~\/.claude\/watch-and-save.log\r\n\r\n# \u30bb\u30c3\u30b7\u30e7\u30f3\u30d5\u30a1\u30a4\u30eb\u304c\u898b\u3064\u304b\u308b\u304b\u78ba\u8a8d\r\nfind ~\/.claude\/projects -name &quot;*.jsonl&quot; -type f -mmin -60 -size +1000c 2&gt;\/dev\/null | head -3\r\n<\/code><\/pre>\r\n\r\n<h3 class=\"fz-ml\">LaunchAgent\u3092\u518d\u8d77\u52d5\u3059\u308b<\/h3>\r\n<pre><code class=\"language-bash\">launchctl unload ~\/Library\/LaunchAgents\/com.claude.obsidian-sync.plist\r\nlaunchctl load ~\/Library\/LaunchAgents\/com.claude.obsidian-sync.plist\r\n<\/code><\/pre>\r\n\r\n<h3 class=\"fz-ml\">\u540c\u671f\u4f4d\u7f6e\u3092\u30ea\u30bb\u30c3\u30c8\u3059\u308b<\/h3>\r\n<pre><code class=\"language-bash\">rm -f ~\/.claude\/last-synced-line_*\r\n<\/code><\/pre>\r\n\r\n<h3 class=\"fz-ml\">Mac\u518d\u8d77\u52d5\u5f8c\u306b\u30ed\u30b0\u304c\u8a18\u9332\u3055\u308c\u306a\u304f\u306a\u3063\u305f\u5834\u5408<\/h3>\r\n<p>jq\u304cLaunchAgent\u74b0\u5883\u3067\u898b\u3064\u304b\u3089\u306a\u3044\u53ef\u80fd\u6027\u304c\u3042\u308a\u307e\u3059\u3002<\/p>\r\n<pre><code class=\"language-bash\"># LaunchAgent\u74b0\u5883\u3092\u30b7\u30df\u30e5\u30ec\u30fc\u30c8\u3057\u3066jq\u306e\u53ef\u5426\u3092\u78ba\u8a8d\r\nenv -i PATH=&quot;\/usr\/bin:\/bin:\/usr\/sbin:\/sbin&quot; bash -c &#39;which jq&#39;\r\n\r\n# \u300cjq not found\u300d\u3068\u51fa\u305f\u5834\u5408\u3001\u30b9\u30af\u30ea\u30d7\u30c8\u5148\u982d\u306b\u4ee5\u4e0b\u304c\u3042\u308b\u304b\u78ba\u8a8d\r\n# export PATH=&quot;\/usr\/local\/bin:\/opt\/homebrew\/bin:$PATH&quot;\r\n\r\n# jq\u306e\u5b9f\u969b\u306e\u30d1\u30b9\u3092\u78ba\u8a8d\r\nwhich jq\r\n# \u2192 \/usr\/local\/bin\/jq\uff08Intel\uff09\u307e\u305f\u306f \/opt\/homebrew\/bin\/jq\uff08Apple Silicon\uff09\r\n<\/code><\/pre>\r\n\r\n\r\n<h2 class=\"fz-xl\">\u307e\u3068\u3081<\/h2>\r\n<p>\u5b9f\u969b\u306b\u52d5\u304b\u3059\u306b\u306f\u3044\u304f\u3064\u304b\u306e\u4fee\u6b63\u304c\u5fc5\u8981\u3067\u3057\u305f\u3002<\/p>\r\n<p>\u4e3b\u306a\u30dd\u30a4\u30f3\u30c8\uff1a<\/p>\r\n<ul style=\"list-style-type:bullet;\" class=\"my-0.5r\">\r\n<li><b class=\"fw-600\">jq\u306e\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb<\/b>\u3092\u5fd8\u308c\u305a\u306b<\/li>\r\n<li><b class=\"fw-600\">plist\u306f\u7d76\u5bfe\u30d1\u30b9<\/b>\u3067\u6307\u5b9a<\/li>\r\n<li><b class=\"fw-600\">\u914d\u5217\u5f62\u5f0f\u306e\u30e1\u30c3\u30bb\u30fc\u30b8<\/b>\u306b\u5bfe\u5fdc<\/li>\r\n<li><b class=\"fw-600\">\u65b0\u3057\u3044\u30bb\u30c3\u30b7\u30e7\u30f3\u306f0\u884c\u76ee\u304b\u3089<\/b>\u958b\u59cb<\/li>\r\n<li><b class=\"fw-600\">\u30b9\u30af\u30ea\u30d7\u30c8\u5185\u3067PATH\u3092\u660e\u793a\u7684\u306b\u8a2d\u5b9a<\/b>\uff08LaunchAgent\u74b0\u5883\u3067\u306fHomebrew\u306e\u30d1\u30b9\u304c\u901a\u3089\u306a\u3044\uff09<\/li>\r\n<\/ul>\r\n<p>\u3053\u308c\u3067Claude Code\u3068\u306e\u4f1a\u8a71\u304c\u81ea\u52d5\u3067Obsidian\u306b\u84c4\u7a4d\u3055\u308c\u308b\u3088\u3046\u306b\u306a\u308a\u307e\u3057\u305f\u3002\u904e\u53bb\u306e\u4f1a\u8a71\u3092\u691c\u7d22\u30fb\u53c2\u7167\u3067\u304d\u308b\u306e\u306f\u975e\u5e38\u306b\u4fbf\u5229\u3067\u3059\u3002<\/p>\r\n<p>\u5143\u8a18\u4e8b\u3092\u66f8\u3044\u3066\u304f\u3060\u3055\u3063\u305f<a href=\"https:\/\/zenn.dev\/kentaro\" class=\"link\">@kentaro<\/a>\u3055\u3093\u306b\u611f\u8b1d\u3057\u307e\u3059\uff01<\/p>\r\n\r\n<hr class=\"separator mx-auto mt-3r\" \/>\r\n\r\n\r\n<h2 class=\"fz-xl\">\u95a2\u9023\u8a18\u4e8b<\/h2>\r\n<a href=\"https:\/\/code-plus.jp\/gp\/claude-slash-commands-10419\/\" class=\"linkbox my-1.5r\">\r\n<h4 class=\"linkbox-title fz-md\">Claude Code\u306bSlash Commands\u3067\u3001\u958b\u767a\u65e5\u8a8c\u3092\u66f8\u3044\u3066\u3082\u3089\u3046\u65b9\u6cd5<\/h4>\r\n<picture class=\"linkbox-thumbnail\">\r\n<img decoding=\"async\" width=\"300\" height=\"200\" src=\"https:\/\/code-plus.jp\/gp\/wp-content\/uploads\/Claude-C_2601151640.jpg\" alt=\"Claude Code\u306bSlash Commands\u3067\u3001\u958b\u767a\u65e5\u8a8c\u3092\u66f8\u3044\u3066\u3082\u3089\u3046\u65b9\u6cd5\" loading=\"lazy\" \/>\r\n<\/picture>\r\n<span class=\"linkbox-excerpt\">Claude Code\u306eSlash Commands\u3092\u4f7f\u3063\u3066\u3001\u958b\u767a\u306e\u5224\u65ad\u7406\u7531\u3084\u8a66\u884c\u932f\u8aa4\u306e\u904e\u7a0b\u3092\u542b\u3080\u8a73\u7d30\u306a\u958b\u767a\u65e5\u8a8c\u3092\u81ea\u52d5\u751f\u6210\u3059\u308b\u65b9\u6cd5\u3092\u89e3\u8aac\u3002\u8a2d\u5b9a\u30d5\u30a1\u30a4\u30eb\u306e\u30c6\u30f3\u30d7\u30ec\u30fc\u30c8\u3068\u5b9f\u969b\u306e\u51fa\u529b\u4f8b\u3082\u516c\u958b\u3002\r\n&emsp;<u class=\"linkbox-more\">\u7d9a\u304d\u3092\u8aad\u3080<\/u>\r\n<\/span>\r\n<\/a>","protected":false},"excerpt":{"rendered":"@kentaro \u3055\u3093\u306e\u8a18\u4e8b\u300c\u4f1a\u8a71\u3092\u81ea\u52d5\u3067Obsidian\u306b\u8a18\u9332\u3059\u308b\u4ed5\u7d44\u307f\u3092\u4f5c\u3063\u305f \u300d\u3092\u898b\u3066\u3001Claude Code\u3068\u306e\u4f1a\u8a71\u3092\u81ea\u52d5\u3067Obsidian\u306b\u8a18\u9332\u3059\u308b\u4ed5\u7d44\u307f\u3092\u5c0e\u5165\u3057\u3066\u307f\u307e\u3057\u305f\u3002 \u975e\u5e38\u306b\u4fbf\u5229\u306a\u4ed5\u7d44\u307f\u3067\u3059\u304c\u3001\u5b9f\u969b\u306b\u52d5[...]","protected":false},"author":1,"featured_media":10640,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"sns_share_botton_hide":"","vkExUnit_sns_title":"","_vk_print_noindex":"","footnotes":"","vk-ltc-link":"","vk-ltc-target":"0"},"categories":[25],"tags":[603,600,601,602,604,364,315,213,135,137],"group":[],"class_list":["post-10638","post","type-post","status-publish","format-standard","has-post-thumbnail","category-aicoding","tag-jq","tag-obsidian","tag-launchagent","tag-602","tag-jsonl","tag-364","tag-macos","tag-213","tag-claude-code","tag-ai"],"acf":[],"veu_head_title_object":{"title":"","add_site_title":""},"_links":{"self":[{"href":"https:\/\/code-plus.jp\/gp\/wp-json\/wp\/v2\/posts\/10638","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/code-plus.jp\/gp\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/code-plus.jp\/gp\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/code-plus.jp\/gp\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/code-plus.jp\/gp\/wp-json\/wp\/v2\/comments?post=10638"}],"version-history":[{"count":0,"href":"https:\/\/code-plus.jp\/gp\/wp-json\/wp\/v2\/posts\/10638\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/code-plus.jp\/gp\/wp-json\/wp\/v2\/media\/10640"}],"wp:attachment":[{"href":"https:\/\/code-plus.jp\/gp\/wp-json\/wp\/v2\/media?parent=10638"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/code-plus.jp\/gp\/wp-json\/wp\/v2\/categories?post=10638"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/code-plus.jp\/gp\/wp-json\/wp\/v2\/tags?post=10638"},{"taxonomy":"group","embeddable":true,"href":"https:\/\/code-plus.jp\/gp\/wp-json\/wp\/v2\/group?post=10638"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}