mirror of
https://github.com/himanshudongre/smriti.git
synced 2026-08-28 05:14:59 +00:00
Add --compact mode to smriti state: artifact labels only with recovery instruction
This commit is contained in:
parent
f6d43f8831
commit
b8e6e0403d
5 changed files with 162 additions and 7 deletions
|
|
@ -1,8 +1,11 @@
|
|||
# Smriti — project instructions for Claude Code
|
||||
|
||||
This project uses Smriti as the shared reasoning-state backend.
|
||||
A SessionStart hook injects `smriti state smriti-dev` into your
|
||||
context automatically. Read it before doing anything else.
|
||||
A SessionStart hook injects `smriti state smriti-dev --compact` into
|
||||
your context automatically. Read it before doing anything else.
|
||||
Artifact content is omitted in compact mode — if the state brief
|
||||
lists artifacts that look relevant, inspect them with
|
||||
`smriti checkpoint show <id> --full-artifacts`.
|
||||
|
||||
## Session start checklist
|
||||
|
||||
|
|
|
|||
|
|
@ -62,9 +62,34 @@ def _list_section(heading: str, items: list[str]) -> str:
|
|||
return "\n".join(lines) + "\n"
|
||||
|
||||
|
||||
def _artifact_section(artifacts: list[dict], preview_chars: int = 800, full: bool = False) -> str:
|
||||
def _artifact_section(
|
||||
artifacts: list[dict],
|
||||
preview_chars: int = 800,
|
||||
full: bool = False,
|
||||
compact: bool = False,
|
||||
checkpoint_id: str = "",
|
||||
) -> str:
|
||||
if not artifacts:
|
||||
return ""
|
||||
if compact:
|
||||
# Labels only — no content. Explicit recovery instruction.
|
||||
lines = [f"## Attached artifacts (compact — content omitted)"]
|
||||
for art in artifacts:
|
||||
label = art.get("label") or "Untitled"
|
||||
lines.append(f"- {label}")
|
||||
lines.append("")
|
||||
if checkpoint_id:
|
||||
lines.append(
|
||||
f"To inspect artifact content: "
|
||||
f"`smriti checkpoint show {checkpoint_id} --full-artifacts`"
|
||||
)
|
||||
else:
|
||||
lines.append(
|
||||
"To inspect artifact content: "
|
||||
"`smriti checkpoint show <checkpoint-id> --full-artifacts`"
|
||||
)
|
||||
return "\n".join(lines) + "\n"
|
||||
|
||||
lines = ["## Attached artifacts"]
|
||||
for art in artifacts:
|
||||
label = art.get("label") or "Untitled"
|
||||
|
|
@ -159,6 +184,7 @@ def format_state_brief(
|
|||
commit: dict,
|
||||
*,
|
||||
full_artifacts: bool = False,
|
||||
compact: bool = False,
|
||||
space_state: dict | None = None,
|
||||
) -> str:
|
||||
"""A continuation-oriented markdown brief for the current project state.
|
||||
|
|
@ -215,7 +241,13 @@ def format_state_brief(
|
|||
parts.append(_list_section("Assumptions we are relying on", assumptions))
|
||||
parts.append(_list_section("Open questions", open_questions))
|
||||
parts.append(_list_section("In progress", tasks))
|
||||
parts.append(_artifact_section(artifacts, full=full_artifacts))
|
||||
checkpoint_id = commit.get("id") or head.get("commit_id") or ""
|
||||
parts.append(_artifact_section(
|
||||
artifacts,
|
||||
full=full_artifacts,
|
||||
compact=compact,
|
||||
checkpoint_id=str(checkpoint_id),
|
||||
))
|
||||
|
||||
if entities:
|
||||
parts.append(f"## Key entities\n{', '.join(entities)}\n")
|
||||
|
|
|
|||
|
|
@ -221,7 +221,8 @@ def cmd_state(client: SmritiClient, args: argparse.Namespace) -> None:
|
|||
"divergence": state.get("divergence"),
|
||||
}
|
||||
|
||||
full_artifacts = not args.preview
|
||||
full_artifacts = not args.preview and not args.compact
|
||||
compact = args.compact
|
||||
if args.json:
|
||||
payload = {"space": space, "head": head, "commit": commit}
|
||||
if space_state is not None:
|
||||
|
|
@ -234,6 +235,7 @@ def cmd_state(client: SmritiClient, args: argparse.Namespace) -> None:
|
|||
format_state_brief(
|
||||
space, head, commit,
|
||||
full_artifacts=full_artifacts,
|
||||
compact=compact,
|
||||
space_state=space_state,
|
||||
),
|
||||
end="",
|
||||
|
|
@ -875,6 +877,13 @@ def _build_parser() -> argparse.ArgumentParser:
|
|||
"Default: multi-branch state — main brief plus any active "
|
||||
"non-main branches and divergence signal.",
|
||||
)
|
||||
state_parser.add_argument(
|
||||
"--compact",
|
||||
action="store_true",
|
||||
help="Omit artifact content, show labels only. Saves tokens for "
|
||||
"session-start injection. Full content recoverable via "
|
||||
"smriti checkpoint show <id> --full-artifacts.",
|
||||
)
|
||||
state_parser.add_argument("--json", action="store_true", help="Output structured JSON")
|
||||
state_parser.set_defaults(func=cmd_state)
|
||||
|
||||
|
|
|
|||
|
|
@ -111,7 +111,12 @@ def _empty_space_brief(space: dict) -> str:
|
|||
|
||||
|
||||
@mcp.tool()
|
||||
def smriti_state(space: str, preview: bool = False, main_only: bool = False) -> str:
|
||||
def smriti_state(
|
||||
space: str,
|
||||
preview: bool = False,
|
||||
compact: bool = False,
|
||||
main_only: bool = False,
|
||||
) -> str:
|
||||
"""Print a continuation-oriented brief of a space's current state.
|
||||
|
||||
By default the brief is multi-branch aware: it includes the main-branch
|
||||
|
|
@ -131,6 +136,10 @@ def smriti_state(space: str, preview: bool = False, main_only: bool = False) ->
|
|||
space: Space name or UUID.
|
||||
preview: If True, truncate artifact content to a short preview
|
||||
instead of showing it in full. Default: full artifacts.
|
||||
compact: If True, omit artifact content entirely — show only
|
||||
artifact labels with a recovery instruction. Saves tokens
|
||||
for session-start injection. Full content recoverable via
|
||||
smriti_show_checkpoint. Default False.
|
||||
main_only: If True, fetch only the main-branch HEAD via the
|
||||
legacy /head endpoint and skip the Active branches and
|
||||
Divergence signal sections entirely. Default False.
|
||||
|
|
@ -159,7 +168,8 @@ def smriti_state(space: str, preview: bool = False, main_only: bool = False) ->
|
|||
_raise_from(e)
|
||||
return format_state_brief(
|
||||
s, head, commit,
|
||||
full_artifacts=not preview,
|
||||
full_artifacts=not preview and not compact,
|
||||
compact=compact,
|
||||
space_state=space_state,
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -316,3 +316,104 @@ def test_mcp_smriti_state_no_checkpoints_short_circuit(mock_client):
|
|||
out = mcp_server.smriti_state(space="my-project")
|
||||
|
||||
assert "No checkpoints yet" in out
|
||||
|
||||
|
||||
# ── Compact mode tests ──────────────────────────────────────────────────────
|
||||
|
||||
|
||||
def _commit_with_artifacts():
|
||||
"""Commit with realistic artifacts for compact mode testing."""
|
||||
base = _base_commit()
|
||||
base["id"] = "abc12345-6789-0abc-def0-123456789abc"
|
||||
base["artifacts"] = [
|
||||
{
|
||||
"id": "a1",
|
||||
"type": "python",
|
||||
"label": "Draft implementation",
|
||||
"content": "def hello():\n return 'world'\n" * 50,
|
||||
},
|
||||
{
|
||||
"id": "a2",
|
||||
"type": "markdown",
|
||||
"label": "Test plan",
|
||||
"content": "# Test Plan\n\n- Unit tests for X\n- Integration tests for Y\n" * 30,
|
||||
},
|
||||
]
|
||||
return base
|
||||
|
||||
|
||||
def test_compact_omits_artifact_content():
|
||||
"""Compact mode shows artifact labels but not content."""
|
||||
commit = _commit_with_artifacts()
|
||||
out = format_state_brief(
|
||||
_base_space(), _base_head(), commit, compact=True,
|
||||
)
|
||||
|
||||
# Labels present
|
||||
assert "Draft implementation" in out
|
||||
assert "Test plan" in out
|
||||
# Content absent
|
||||
assert "def hello():" not in out
|
||||
assert "Unit tests for X" not in out
|
||||
# Recovery instruction present
|
||||
assert "compact — content omitted" in out
|
||||
assert "smriti checkpoint show" in out
|
||||
assert "abc12345-6789-0abc-def0-123456789abc" in out
|
||||
|
||||
|
||||
def test_compact_is_smaller_than_full():
|
||||
"""Compact output must be materially smaller than full output."""
|
||||
commit = _commit_with_artifacts()
|
||||
full = format_state_brief(
|
||||
_base_space(), _base_head(), commit, full_artifacts=True,
|
||||
)
|
||||
compact = format_state_brief(
|
||||
_base_space(), _base_head(), commit, compact=True,
|
||||
)
|
||||
|
||||
# Compact should be at least 50% smaller when artifacts dominate
|
||||
assert len(compact) < len(full) * 0.5, (
|
||||
f"Compact ({len(compact)} chars) should be less than 50% of "
|
||||
f"full ({len(full)} chars)"
|
||||
)
|
||||
|
||||
|
||||
def test_compact_preserves_decisions_and_tasks():
|
||||
"""Compact mode must not touch non-artifact sections."""
|
||||
commit = _commit_with_artifacts()
|
||||
out = format_state_brief(
|
||||
_base_space(), _base_head(), commit, compact=True,
|
||||
)
|
||||
|
||||
assert "## Decisions" in out
|
||||
assert "Decision A" in out
|
||||
assert "## Assumptions we are relying on" in out
|
||||
assert "Assumption X" in out
|
||||
assert "## In progress" in out
|
||||
assert "Task 1" in out
|
||||
|
||||
|
||||
def test_compact_with_no_artifacts_is_clean():
|
||||
"""Compact mode on a commit with no artifacts should not show the section."""
|
||||
commit = _base_commit() # no artifacts
|
||||
out = format_state_brief(
|
||||
_base_space(), _base_head(), commit, compact=True,
|
||||
)
|
||||
|
||||
assert "Attached artifacts" not in out
|
||||
assert "compact" not in out.lower() or "compact" in out.lower() # no section = no mention
|
||||
|
||||
|
||||
def test_mcp_smriti_state_compact_mode(mock_client):
|
||||
"""MCP tool with compact=True should pass compact to formatter."""
|
||||
mock_client.resolve_space.return_value = _space_dict()
|
||||
state = _space_state_dict()
|
||||
state["commit"] = _commit_with_artifacts()
|
||||
mock_client.get_space_state.return_value = state
|
||||
|
||||
out = mcp_server.smriti_state(space="my-project", compact=True)
|
||||
|
||||
# Labels present, content absent
|
||||
assert "Draft implementation" in out
|
||||
assert "def hello():" not in out
|
||||
assert "compact — content omitted" in out
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue