From e4e94a7e70f124caea5847fff5a644c988da7b90 Mon Sep 17 00:00:00 2001 From: ericcai <112368072+ericcai0814@users.noreply.github.com> Date: Fri, 6 Feb 2026 17:00:48 +0800 Subject: [PATCH] fix: preserve content after frontmatter in parse_instinct_file() (#161) parse_instinct_file() was appending the instinct and resetting state when frontmatter ended (second ---), before any content lines could be collected. This caused all content (Action, Evidence, Examples) to be lost during import. Fix: only set in_frontmatter=False when frontmatter ends. The existing logic at the start of next frontmatter (or EOF) correctly appends the instinct with its collected content. Fixes #148 --- .../scripts/instinct-cli.py | 7 +- .../scripts/test_parse_instinct.py | 82 +++++++++++++++++++ 2 files changed, 83 insertions(+), 6 deletions(-) create mode 100644 skills/continuous-learning-v2/scripts/test_parse_instinct.py diff --git a/skills/continuous-learning-v2/scripts/instinct-cli.py b/skills/continuous-learning-v2/scripts/instinct-cli.py index 11773d7..bc7135c 100755 --- a/skills/continuous-learning-v2/scripts/instinct-cli.py +++ b/skills/continuous-learning-v2/scripts/instinct-cli.py @@ -50,13 +50,8 @@ def parse_instinct_file(content: str) -> list[dict]: for line in content.split('\n'): if line.strip() == '---': if in_frontmatter: - # End of frontmatter + # End of frontmatter - content comes next, don't append yet in_frontmatter = False - if current: - current['content'] = '\n'.join(content_lines).strip() - instincts.append(current) - current = {} - content_lines = [] else: # Start of frontmatter in_frontmatter = True diff --git a/skills/continuous-learning-v2/scripts/test_parse_instinct.py b/skills/continuous-learning-v2/scripts/test_parse_instinct.py new file mode 100644 index 0000000..10d487e --- /dev/null +++ b/skills/continuous-learning-v2/scripts/test_parse_instinct.py @@ -0,0 +1,82 @@ +"""Tests for parse_instinct_file() — verifies content after frontmatter is preserved.""" + +import importlib.util +import os + +# Load instinct-cli.py (hyphenated filename requires importlib) +_spec = importlib.util.spec_from_file_location( + "instinct_cli", + os.path.join(os.path.dirname(__file__), "instinct-cli.py"), +) +_mod = importlib.util.module_from_spec(_spec) +_spec.loader.exec_module(_mod) +parse_instinct_file = _mod.parse_instinct_file + + +MULTI_SECTION = """\ +--- +id: instinct-a +trigger: "when coding" +confidence: 0.9 +domain: general +--- + +## Action +Do thing A. + +## Examples +- Example A1 + +--- +id: instinct-b +trigger: "when testing" +confidence: 0.7 +domain: testing +--- + +## Action +Do thing B. +""" + + +def test_multiple_instincts_preserve_content(): + result = parse_instinct_file(MULTI_SECTION) + assert len(result) == 2 + assert "Do thing A." in result[0]["content"] + assert "Example A1" in result[0]["content"] + assert "Do thing B." in result[1]["content"] + + +def test_single_instinct_preserves_content(): + content = """\ +--- +id: solo +trigger: "when reviewing" +confidence: 0.8 +domain: review +--- + +## Action +Check for security issues. + +## Evidence +Prevents vulnerabilities. +""" + result = parse_instinct_file(content) + assert len(result) == 1 + assert "Check for security issues." in result[0]["content"] + assert "Prevents vulnerabilities." in result[0]["content"] + + +def test_empty_content_no_error(): + content = """\ +--- +id: empty +trigger: "placeholder" +confidence: 0.5 +domain: general +--- +""" + result = parse_instinct_file(content) + assert len(result) == 1 + assert result[0]["content"] == ""