@mrclrchtr/supi-claude-md 1.3.1 → 1.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,33 +1,65 @@
1
1
  # @mrclrchtr/supi-claude-md
2
2
 
3
- Subdirectory context for PI your project's conventions follow the agent wherever it goes.
3
+ Adds subdirectory context-file discovery to the [pi coding agent](https://github.com/earendil-works/pi).
4
4
 
5
- Pi loads your root `CLAUDE.md` by default. Claude-MD extends that downward: when the agent reaches into `src/auth/`, it picks up `src/auth/CLAUDE.md` too. Conventions are where the code is, not just at the project root.
5
+ Pi already handles root and ancestor context files in its own system prompt. This package covers the other half: context files inside subdirectories below your current working directory.
6
6
 
7
- Then it helps you keep those files in shape — audit quality, flag stale sections, and capture session learnings with your approval.
7
+ ## Install
8
+
9
+ ```bash
10
+ pi install npm:@mrclrchtr/supi-claude-md
11
+ ```
12
+
13
+ For local development:
14
+
15
+ ```bash
16
+ pi install ./packages/supi-claude-md
17
+ ```
18
+
19
+ After editing the source, run `/reload`.
8
20
 
9
21
  ## What you get
10
22
 
11
- ### Context that travels
23
+ When the agent touches a file or directory inside the project, this package can inject nearby subdirectory context files into the conversation.
12
24
 
13
- Reads, writes, edits, LSP operations — any time the agent touches a file, it picks up the nearest `CLAUDE.md` or `AGENTS.md` in that directory. Each subdirectory's context is injected once (on first discovery) and available for the rest of the session.
25
+ Supported file names by default:
14
26
 
15
- ### CLAUDE.md maintenance
27
+ - `CLAUDE.md`
28
+ - `AGENTS.md`
16
29
 
17
- Two bundled skills:
30
+ How discovery works:
18
31
 
19
- - **claude-md-improver** audit every CLAUDE.md in your repo. Flags redundancy, stale sections, and content already covered by SuPi's auto-injected context. Suggests targeted updates.
20
- - **claude-md-revision** capture what you learned this session into CLAUDE.md. Ask the agent to remember a pattern, convention, or gotcha — it proposes the edit, you approve.
32
+ - starts from the target file's directory
33
+ - walks upward toward `cwd`
34
+ - looks for the configured context-file names in each directory
35
+ - injects only files that pi did not already load natively
36
+ - injects a subdirectory only once per session unless compaction resets the tracking state
21
37
 
22
- ## Install
38
+ Supported tool paths come from these tools:
23
39
 
24
- ```bash
25
- pi install npm:@mrclrchtr/supi-claude-md
26
- ```
40
+ - `read`
41
+ - `write`
42
+ - `edit`
43
+ - `ls`
44
+ - `lsp`
45
+ - `tree_sitter`
46
+
47
+ ## What it does not do
48
+
49
+ - it does not re-inject root or ancestor context files that pi already loaded
50
+ - it does not scan above `cwd`
51
+ - it does not add a command or model-callable tool; the behavior is automatic
27
52
 
28
53
  ## Settings
29
54
 
30
- Configure via `/supi-settings` or directly in config:
55
+ This package registers a **Claude-MD** section in `/supi-settings`.
56
+
57
+ Available settings:
58
+
59
+ - `subdirs` — turn subdirectory discovery on or off
60
+ - `fileNames` — comma-separated file names to search for in each directory
61
+
62
+ Defaults:
31
63
 
32
64
  ```json
33
65
  {
@@ -38,5 +70,15 @@ Configure via `/supi-settings` or directly in config:
38
70
  }
39
71
  ```
40
72
 
41
- - `subdirs` — toggle subdirectory discovery on/off
42
- - `fileNames` — which filenames to look for (comma-separated)
73
+ ## Bundled skills
74
+
75
+ This package also exposes two skills through `resources_discover`:
76
+
77
+ - `claude-md-improver` — audit and improve `CLAUDE.md` files across a repo
78
+ - `claude-md-revision` — update `CLAUDE.md` or `AGENTS.md` with durable project learnings from a session
79
+
80
+ ## Source
81
+
82
+ - `src/claude-md.ts` — session state, injection flow, and skill registration
83
+ - `src/discovery.ts` — subdirectory file discovery
84
+ - `src/subdirectory.ts` — context formatting and per-directory injection rules
@@ -1,65 +1,78 @@
1
1
  # @mrclrchtr/supi-core
2
2
 
3
- Shared infrastructure for SuPi packages.
3
+ Shared infrastructure for SuPi extensions.
4
+
5
+ This package is mainly for extension authors. It gives you a common config system, settings plumbing, context helpers, registries, and a small extension surface that registers `/supi-settings`.
4
6
 
5
7
  ## Install
6
8
 
7
- Use it as a dependency in another extension package:
9
+ ### As a dependency for another extension
8
10
 
9
11
  ```bash
10
12
  pnpm add @mrclrchtr/supi-core
11
13
  ```
12
14
 
13
- ## Package role
14
-
15
- `@mrclrchtr/supi-core` now has two explicit surfaces:
15
+ ### As a pi package
16
16
 
17
- - `@mrclrchtr/supi-core/api` — shared library helpers for other SuPi packages
18
- - `@mrclrchtr/supi-core/extension` — a minimal pi extension that registers `/supi-settings`
19
-
20
- `pi.extensions` still points at the real file path `./src/extension.ts` inside the package. The `/api` and `/extension` paths are consumer-facing package exports, not manifest aliases.
17
+ ```bash
18
+ pi install npm:@mrclrchtr/supi-core
19
+ ```
21
20
 
22
- ## What it provides
21
+ Installing it as a pi package adds the minimal `/supi-settings` extension surface.
23
22
 
24
- Current exports cover:
23
+ ## Package surfaces
25
24
 
26
- - shared config loading, scoped reads, writes, and key removal
27
- - config-backed settings registration helpers for `/supi-settings`
28
- - the shared settings registry, overlay UI, and `registerSettingsCommand()` helper
29
- - XML `<extension-context>` wrapping plus context-message utilities
30
- - context-provider and debug-event registries reused across SuPi packages
31
- - project root and path helpers reused by packages such as `supi-lsp`
25
+ - `@mrclrchtr/supi-core/api` reusable helpers for other packages and extensions
26
+ - `@mrclrchtr/supi-core/extension` minimal pi extension that registers `/supi-settings`
32
27
 
33
- ## Config system
28
+ ## What you get from the API
34
29
 
35
- Config resolution order:
30
+ ### Config helpers
36
31
 
37
- ```text
38
- defaults <- global <- project
39
- ```
32
+ - `loadSupiConfig()` — merged config with resolution order `defaults <- global <- project`
33
+ - `loadSupiConfigForScope()` load one scope at a time for settings UIs
34
+ - `writeSupiConfig()` — persist values
35
+ - `removeSupiConfigKey()` — remove a key or override
40
36
 
41
37
  Config file locations:
42
38
 
43
39
  - global: `~/.pi/agent/supi/config.json`
44
40
  - project: `.pi/supi/config.json`
45
41
 
46
- Main helpers:
42
+ ### Settings helpers
43
+
44
+ - `registerSettings()` — register an arbitrary settings section
45
+ - `registerConfigSettings()` — register a config-backed settings section with scoped persistence helpers
46
+ - `registerSettingsCommand()` — register `/supi-settings`
47
+ - `openSettingsOverlay()` — open the shared settings UI directly
48
+ - `createInputSubmenu()` — helper for simple text-entry submenus
49
+
50
+ The built-in settings UI supports:
47
51
 
48
- - `loadSupiConfig()` — effective merged config (`defaults <- global <- project`)
49
- - `loadSupiConfigForScope()` raw single-scope config for settings UIs (`defaults <- selected scope`)
50
- - `writeSupiConfig()`
51
- - `removeSupiConfigKey()`
52
- - `registerConfigSettings()`
52
+ - project/global scope toggle
53
+ - grouped extension sections
54
+ - searchable setting lists
53
55
 
54
- ## Context and settings helpers
56
+ ### Context helpers
55
57
 
56
- - `wrapExtensionContext()`
58
+ - `wrapExtensionContext()` — wrap injected text in SuPi's `<extension-context>` tag
57
59
  - `findLastUserMessageIndex()`
58
60
  - `getContextToken()`
61
+ - `getPromptContent()`
59
62
  - `pruneAndReorderContextMessages()`
60
- - `registerSettings()`
61
- - `registerSettingsCommand()`
62
- - `openSettingsOverlay()`
63
+ - `restorePromptContent()`
64
+
65
+ ### Shared registries
66
+
67
+ - context-provider registry for `/supi-context`
68
+ - debug-event registry for producers that want shared debug capture
69
+ - settings registry used by `/supi-settings`
70
+
71
+ ### Project and session helpers
72
+
73
+ - project-root detection and directory walking helpers such as `findProjectRoot()` and `walkProject()`
74
+ - active-branch session helper: `getActiveBranchEntries()`
75
+ - terminal helpers such as `formatTitle()`, `signalWaiting()`, and `signalDone()`
63
76
 
64
77
  ## Example
65
78
 
@@ -80,17 +93,15 @@ registerConfigSettings({
80
93
  });
81
94
 
82
95
  const message = wrapExtensionContext("my-extension", "hello", {
83
- turn: 1,
84
96
  file: "CLAUDE.md",
97
+ turn: 1,
85
98
  });
86
99
  ```
87
100
 
88
- ## Requirements
89
-
90
- - `@earendil-works/pi-coding-agent`
91
- - `@earendil-works/pi-tui`
92
-
93
101
  ## Source
94
102
 
95
- - Library surface: `src/api.ts`
96
- - Extension surface: `src/extension.ts`
103
+ - `src/api.ts` — exported library surface
104
+ - `src/extension.ts` — minimal `/supi-settings` entrypoint
105
+ - `src/config.ts` — shared config loading and writing
106
+ - `src/config-settings.ts` — config-backed settings registration helper
107
+ - `src/settings-ui.ts` — shared settings overlay
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mrclrchtr/supi-core",
3
- "version": "1.3.1",
3
+ "version": "1.4.0",
4
4
  "description": "SuPi core — shared infrastructure for SuPi extensions (XML context tags, config system)",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -2,30 +2,30 @@
2
2
  // Provides XML context tag wrapping, unified config system, context-message utilities,
3
3
  // and settings registry for supi-wide TUI settings.
4
4
 
5
- export type { SupiConfigLocation, SupiConfigOptions } from "./config.ts";
5
+ export type { SupiConfigLocation, SupiConfigOptions } from "./config/config.ts";
6
6
  export {
7
7
  loadSupiConfig,
8
8
  loadSupiConfigForScope,
9
9
  removeSupiConfigKey,
10
10
  writeSupiConfig,
11
- } from "./config.ts";
12
- export type { ConfigSettingsHelpers, ConfigSettingsOptions } from "./config-settings.ts";
13
- export { registerConfigSettings } from "./config-settings.ts";
14
- export type { ContextMessageLike } from "./context-messages.ts";
11
+ } from "./config/config.ts";
12
+ export type { ConfigSettingsHelpers, ConfigSettingsOptions } from "./config/config-settings.ts";
13
+ export { registerConfigSettings } from "./config/config-settings.ts";
14
+ export type { ContextMessageLike } from "./context/context-messages.ts";
15
15
  export {
16
16
  findLastUserMessageIndex,
17
17
  getContextToken,
18
18
  getPromptContent,
19
19
  pruneAndReorderContextMessages,
20
20
  restorePromptContent,
21
- } from "./context-messages.ts";
22
- export type { ContextProvider } from "./context-provider-registry.ts";
21
+ } from "./context/context-messages.ts";
22
+ export type { ContextProvider } from "./context/context-provider-registry.ts";
23
23
  export {
24
24
  clearRegisteredContextProviders,
25
25
  getRegisteredContextProviders,
26
26
  registerContextProvider,
27
- } from "./context-provider-registry.ts";
28
- export { wrapExtensionContext } from "./context-tag.ts";
27
+ } from "./context/context-provider-registry.ts";
28
+ export { wrapExtensionContext } from "./context/context-tag.ts";
29
29
  export type {
30
30
  DebugAgentAccess,
31
31
  DebugEvent,
@@ -64,14 +64,14 @@ export {
64
64
  walkProject,
65
65
  } from "./project-roots.ts";
66
66
  export { getActiveBranchEntries } from "./session-utils.ts";
67
- export { registerSettingsCommand } from "./settings-command.ts";
68
- export type { SettingsScope, SettingsSection } from "./settings-registry.ts";
67
+ export { registerSettingsCommand } from "./settings/settings-command.ts";
68
+ export type { SettingsScope, SettingsSection } from "./settings/settings-registry.ts";
69
69
  export {
70
70
  clearRegisteredSettings,
71
71
  getRegisteredSettings,
72
72
  registerSettings,
73
- } from "./settings-registry.ts";
74
- export { createInputSubmenu, openSettingsOverlay } from "./settings-ui.ts";
73
+ } from "./settings/settings-registry.ts";
74
+ export { createInputSubmenu, openSettingsOverlay } from "./settings/settings-ui.ts";
75
75
  export type { TitleTarget } from "./terminal.ts";
76
76
  export {
77
77
  DONE_SYMBOL,
@@ -2,9 +2,9 @@
2
2
  // Wraps registerSettings() and centralizes selected-scope loading + scoped persistence.
3
3
 
4
4
  import type { SettingItem } from "@earendil-works/pi-tui";
5
+ import type { SettingsScope } from "../settings/settings-registry.ts";
6
+ import { registerSettings } from "../settings/settings-registry.ts";
5
7
  import { loadSupiConfigForScope, removeSupiConfigKey, writeSupiConfig } from "./config.ts";
6
- import type { SettingsScope } from "./settings-registry.ts";
7
- import { registerSettings } from "./settings-registry.ts";
8
8
 
9
9
  export interface ConfigSettingsHelpers {
10
10
  /** Write a key to the selected scope's config section. */
@@ -3,7 +3,7 @@
3
3
  // Extensions declare context data providers via `registerContextProvider()` during their
4
4
  // factory function. The `/supi-context` command reads them via `getRegisteredContextProviders()`.
5
5
 
6
- import { createRegistry } from "./registry-utils.ts";
6
+ import { createRegistry } from "../registry-utils.ts";
7
7
 
8
8
  export interface ContextProvider {
9
9
  /** Unique identifier — e.g. "rtk" */
@@ -1 +1 @@
1
- export { registerSettingsCommand as default } from "./settings-command.ts";
1
+ export { registerSettingsCommand as default } from "./settings/settings-command.ts";
@@ -2,30 +2,30 @@
2
2
  // Provides XML context tag wrapping, unified config system, context-message utilities,
3
3
  // and settings registry for supi-wide TUI settings.
4
4
 
5
- export type { SupiConfigLocation, SupiConfigOptions } from "./config.ts";
5
+ export type { SupiConfigLocation, SupiConfigOptions } from "./config/config.ts";
6
6
  export {
7
7
  loadSupiConfig,
8
8
  loadSupiConfigForScope,
9
9
  removeSupiConfigKey,
10
10
  writeSupiConfig,
11
- } from "./config.ts";
12
- export type { ConfigSettingsHelpers, ConfigSettingsOptions } from "./config-settings.ts";
13
- export { registerConfigSettings } from "./config-settings.ts";
14
- export type { ContextMessageLike } from "./context-messages.ts";
11
+ } from "./config/config.ts";
12
+ export type { ConfigSettingsHelpers, ConfigSettingsOptions } from "./config/config-settings.ts";
13
+ export { registerConfigSettings } from "./config/config-settings.ts";
14
+ export type { ContextMessageLike } from "./context/context-messages.ts";
15
15
  export {
16
16
  findLastUserMessageIndex,
17
17
  getContextToken,
18
18
  getPromptContent,
19
19
  pruneAndReorderContextMessages,
20
20
  restorePromptContent,
21
- } from "./context-messages.ts";
22
- export type { ContextProvider } from "./context-provider-registry.ts";
21
+ } from "./context/context-messages.ts";
22
+ export type { ContextProvider } from "./context/context-provider-registry.ts";
23
23
  export {
24
24
  clearRegisteredContextProviders,
25
25
  getRegisteredContextProviders,
26
26
  registerContextProvider,
27
- } from "./context-provider-registry.ts";
28
- export { wrapExtensionContext } from "./context-tag.ts";
27
+ } from "./context/context-provider-registry.ts";
28
+ export { wrapExtensionContext } from "./context/context-tag.ts";
29
29
  export type {
30
30
  DebugAgentAccess,
31
31
  DebugEvent,
@@ -64,14 +64,14 @@ export {
64
64
  walkProject,
65
65
  } from "./project-roots.ts";
66
66
  export { getActiveBranchEntries } from "./session-utils.ts";
67
- export { registerSettingsCommand } from "./settings-command.ts";
68
- export type { SettingsScope, SettingsSection } from "./settings-registry.ts";
67
+ export { registerSettingsCommand } from "./settings/settings-command.ts";
68
+ export type { SettingsScope, SettingsSection } from "./settings/settings-registry.ts";
69
69
  export {
70
70
  clearRegisteredSettings,
71
71
  getRegisteredSettings,
72
72
  registerSettings,
73
- } from "./settings-registry.ts";
74
- export { createInputSubmenu, openSettingsOverlay } from "./settings-ui.ts";
73
+ } from "./settings/settings-registry.ts";
74
+ export { createInputSubmenu, openSettingsOverlay } from "./settings/settings-ui.ts";
75
75
  export type { TitleTarget } from "./terminal.ts";
76
76
  export {
77
77
  DONE_SYMBOL,
@@ -4,7 +4,7 @@
4
4
  // factory function. The generic settings UI reads them via `getRegisteredSettings()`.
5
5
 
6
6
  import type { SettingItem } from "@earendil-works/pi-tui";
7
- import { createRegistry } from "./registry-utils.ts";
7
+ import { createRegistry } from "../registry-utils.ts";
8
8
 
9
9
  export type SettingsScope = "project" | "global";
10
10
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mrclrchtr/supi-claude-md",
3
- "version": "1.3.1",
3
+ "version": "1.4.0",
4
4
  "description": "SuPi claude-md extension — automatic subdirectory context injection for pi",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -21,7 +21,7 @@
21
21
  "!__tests__"
22
22
  ],
23
23
  "dependencies": {
24
- "@mrclrchtr/supi-core": "1.3.1"
24
+ "@mrclrchtr/supi-core": "1.4.0"
25
25
  },
26
26
  "bundledDependencies": [
27
27
  "@mrclrchtr/supi-core"
@@ -1,6 +1,7 @@
1
1
  ---
2
2
  name: claude-md-improver
3
3
  description: Use this skill to audit and improve CLAUDE.md files in repositories. Use when user asks to check, audit, update, improve, or fix CLAUDE.md files. Scans for all CLAUDE.md files, evaluates quality against templates, outputs quality report, then makes targeted updates.
4
+ disable-model-invocation: true
4
5
  tools: Read, Glob, Grep, Bash, Edit
5
6
  ---
6
7
 
@@ -1,6 +1,7 @@
1
1
  ---
2
2
  name: claude-md-revision
3
3
  description: "Update CLAUDE.md, .claude.local.md, or AGENTS.md files with project-specific context for future agent sessions. Trigger ONLY when the user explicitly mentions CLAUDE.md, .claude.local.md, AGENTS.md, project memory, or agent context files. Also trigger on direct phrases like 'add this to CLAUDE.md', 'remember this for next time', 'update project memory', or 'document this pattern'. Do NOT trigger for general documentation requests, bug reports, session summaries, or user-facing docs — those are unrelated to agent instruction files."
4
+ disable-model-invocation: true
4
5
  license: MIT
5
6
  ---
6
7
 
package/src/claude-md.ts CHANGED
@@ -9,6 +9,7 @@ import { dirname, join } from "node:path";
9
9
  import { fileURLToPath } from "node:url";
10
10
  import type {
11
11
  BeforeAgentStartEvent,
12
+ BuildSystemPromptOptions,
12
13
  ExtensionAPI,
13
14
  ExtensionContext,
14
15
  SessionCompactEvent,
@@ -57,11 +58,7 @@ export default function claudeMdExtension(pi: ExtensionAPI) {
57
58
  // ── Native context path capture (before_agent_start) ───────
58
59
 
59
60
  pi.on("before_agent_start", async (event: BeforeAgentStartEvent, _ctx: ExtensionContext) => {
60
- const eventWithOpts = event as BeforeAgentStartEvent & {
61
- systemPromptOptions?: { contextFiles?: Array<{ path?: string; content?: string }> };
62
- };
63
-
64
- captureNativePaths(state, eventWithOpts);
61
+ captureNativePaths(state, event.systemPromptOptions);
65
62
  // Root/ancestor context files are owned by pi's system prompt.
66
63
  // SuPi never re-injects them; subdirectory injection handles directories below cwd.
67
64
  });
@@ -106,15 +103,13 @@ export default function claudeMdExtension(pi: ExtensionAPI) {
106
103
 
107
104
  function captureNativePaths(
108
105
  state: ClaudeMdState,
109
- opts: { systemPromptOptions?: { contextFiles?: Array<{ path?: string; content?: string }> } },
106
+ systemPromptOptions: BuildSystemPromptOptions,
110
107
  ): void {
111
108
  if (!state.firstAgentStart) return;
112
109
  state.firstAgentStart = false;
113
- const contextFiles = opts.systemPromptOptions?.contextFiles ?? [];
110
+ const contextFiles = systemPromptOptions.contextFiles ?? [];
114
111
  for (const file of contextFiles) {
115
- if (file.path) {
116
- state.nativeContextPaths.add(file.path);
117
- }
112
+ state.nativeContextPaths.add(file.path);
118
113
  }
119
114
  }
120
115