@mrclrchtr/supi-context 2.6.1 → 2.8.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 +51 -57
- package/node_modules/@mrclrchtr/supi-core/README.md +1 -1
- package/node_modules/@mrclrchtr/supi-core/package.json +1 -1
- package/node_modules/@mrclrchtr/supi-core/src/settings/scoped-settings-list.ts +1 -0
- package/node_modules/@mrclrchtr/supi-core/src/settings/settings-schema.ts +14 -0
- package/node_modules/@mrclrchtr/supi-core/src/settings/settings-submenus.ts +31 -14
- package/node_modules/@mrclrchtr/supi-core/src/settings.ts +1 -0
- package/package.json +8 -5
- package/src/analysis.ts +146 -118
- package/src/capacity.ts +81 -0
- package/src/context.ts +39 -27
- package/src/entry-renderer.ts +23 -0
- package/src/format-helpers.ts +3 -5
- package/src/format-sections.ts +9 -13
- package/src/format-summary.ts +37 -31
- package/src/format.ts +6 -2
- package/src/report-component.ts +4 -3
- package/src/snapshot-component.ts +75 -0
- package/src/tool/guidance.ts +5 -2
- package/src/tool/output.ts +51 -0
- package/src/tool/render.ts +42 -42
- package/src/renderer.ts +0 -15
package/README.md
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
|
|
9
9
|
# @mrclrchtr/supi-context
|
|
10
10
|
|
|
11
|
-
Adds
|
|
11
|
+
Adds context-capacity observability to the [pi coding agent](https://github.com/earendil-works/pi).
|
|
12
12
|
|
|
13
13
|
## Install
|
|
14
14
|
|
|
@@ -22,56 +22,58 @@ For local development:
|
|
|
22
22
|
pi install ./packages/supi-context
|
|
23
23
|
```
|
|
24
24
|
|
|
25
|
-
|
|
25
|
+
## Two concepts, two surfaces
|
|
26
26
|
|
|
27
|
-
|
|
27
|
+
- A **Context Pressure Snapshot** is a small point-in-time capacity reading for deciding whether a session has room for another operation.
|
|
28
|
+
- A **Context Usage Report** is a diagnostic account of where the session's context is spent.
|
|
28
29
|
|
|
29
|
-
|
|
30
|
+
### Human: Context Usage Report
|
|
30
31
|
|
|
31
|
-
|
|
32
|
-
- `/supi-context full` — render the same report with the full guideline and tool-definition lists instead of previews
|
|
33
|
-
- `supi_context` — agent-callable tool (disabled by default; see Configuration)
|
|
32
|
+
In interactive TUI mode, pi gets these commands:
|
|
34
33
|
|
|
35
|
-
|
|
34
|
+
- `/supi-context` — render a report with guideline and tool previews
|
|
35
|
+
- `/supi-context full` — render the same report with complete guideline and tool lists
|
|
36
36
|
|
|
37
|
-
The
|
|
37
|
+
The command appends a durable `supi-context` custom entry and uses a dedicated entry renderer. The report remains in the transcript but never enters LLM context.
|
|
38
|
+
|
|
39
|
+
### Agent: Context Pressure Snapshot
|
|
40
|
+
|
|
41
|
+
`supi_context` is agent-callable when enabled in configuration. It defaults to a one-line, constant-shape JSON **Context Pressure Snapshot**:
|
|
42
|
+
|
|
43
|
+
```ts
|
|
44
|
+
interface ContextPressureSnapshot {
|
|
45
|
+
modelName: string;
|
|
46
|
+
contextWindow: number | null;
|
|
47
|
+
usedTokens: number;
|
|
48
|
+
usagePercent: number | null;
|
|
49
|
+
compactionEnabled: boolean;
|
|
50
|
+
reserveTokens: number;
|
|
51
|
+
headroomTokens: number | null;
|
|
52
|
+
pressurePercent: number | null;
|
|
53
|
+
compacted: boolean;
|
|
54
|
+
approximationNote: string | null;
|
|
55
|
+
}
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
Use `supi_context({ mode: "full" })` only when diagnostic attribution is needed. Full mode returns compact JSON for the Context Usage Report. If it exceeds Pi's normal tool-output limits, it returns a small valid-JSON envelope with the path to a temporary file containing the complete report.
|
|
59
|
+
|
|
60
|
+
The tool TUI never shows raw agent JSON: concise results render as a dense snapshot that expands into its metrics; full results expand into the diagnostic report.
|
|
38
61
|
|
|
39
62
|
## What the report shows
|
|
40
63
|
|
|
41
|
-
The
|
|
42
|
-
|
|
43
|
-
-
|
|
44
|
-
-
|
|
45
|
-
-
|
|
46
|
-
-
|
|
47
|
-
|
|
48
|
-
It includes:
|
|
49
|
-
|
|
50
|
-
- model name, context-window size, and total token usage
|
|
51
|
-
- approximation or pending-usage notes when exact usage data is not available yet
|
|
52
|
-
- a visual usage bar for system prompt, user messages, assistant messages, tool calls, tool results, other, autocompact buffer, and free space
|
|
53
|
-
- a category breakdown table for the same usage buckets
|
|
54
|
-
- a system-prompt composition breakdown for:
|
|
55
|
-
- base prompt content
|
|
56
|
-
- instruction files (`AGENTS.md`, `CLAUDE.md`, etc.)
|
|
57
|
-
- other context files loaded into the system prompt
|
|
58
|
-
- active skills
|
|
59
|
-
- guidelines
|
|
60
|
-
- tool snippets
|
|
61
|
-
- append text
|
|
62
|
-
- instruction-file details with token cost, line count, and detected origin (`project` vs `global`)
|
|
63
|
-
- legacy injected subdirectory context files from older `supi-claude-md` sessions, when present
|
|
64
|
-
- active skill names with per-skill token counts
|
|
65
|
-
- guideline bullet previews, plus source attribution for PI defaults, known built-in tools (`read`, `write`, `edit`), and `other`
|
|
66
|
-
- active tool definitions with per-tool definition token counts and snippet-token columns when available
|
|
67
|
-
- a compaction note when older turns were summarized
|
|
68
|
-
- extra provider sections from extensions registered through the shared context-provider registry in `@mrclrchtr/supi-core`
|
|
64
|
+
The Context Usage Report includes:
|
|
65
|
+
|
|
66
|
+
- model name, context-window size, used tokens, usage percentage, pressure percentage, and **Headroom**
|
|
67
|
+
- the effective **Compaction reserve** and factual presence of compaction on the active branch
|
|
68
|
+
- approximation or pending-usage notes when exact usage is not available
|
|
69
|
+
- a visual usage bar and attribution-category breakdown for system prompt, messages, tool calls, tool results, and other context
|
|
70
|
+
- system-prompt composition, instruction/context files, skills, guideline sources, tool definitions, injected files, and registered provider sections
|
|
69
71
|
|
|
70
72
|
## Configuration
|
|
71
73
|
|
|
72
|
-
|
|
74
|
+
The human `/supi-context` command needs no configuration.
|
|
73
75
|
|
|
74
|
-
To enable the `supi_context`
|
|
76
|
+
To enable the agent-callable `supi_context` tool, set `agentToolEnabled` to `true` in your supi config:
|
|
75
77
|
|
|
76
78
|
```json
|
|
77
79
|
{
|
|
@@ -87,26 +89,18 @@ The tool is disabled by default and requires a `/reload` or restart after toggli
|
|
|
87
89
|
|
|
88
90
|
## Notes
|
|
89
91
|
|
|
90
|
-
- The
|
|
91
|
-
-
|
|
92
|
-
-
|
|
93
|
-
- If no model is selected yet, the report can still render, but the context-window bar cannot show capacity.
|
|
92
|
+
- The extension caches the latest `systemPromptOptions` from `before_agent_start`. If those are missing or incomplete, it backfills context files and skills from the current system prompt.
|
|
93
|
+
- Exact usage comes from Pi's current context-usage data when available. Otherwise the extension estimates usage and preserves an approximation note.
|
|
94
|
+
- The Active Context Limit is the auto-compaction threshold while auto-compaction is enabled, otherwise the raw model context window. Headroom and pressure use that limit.
|
|
94
95
|
|
|
95
96
|
## Source
|
|
96
97
|
|
|
97
|
-
- `src/context.ts` —
|
|
98
|
-
- `src/
|
|
99
|
-
- `src/
|
|
100
|
-
- `src/
|
|
101
|
-
- `src/format
|
|
102
|
-
- `src/
|
|
103
|
-
- `src/
|
|
104
|
-
- `src/format-sections.ts` — instruction file, context file, skill, guideline, tool, compaction, and provider sections
|
|
105
|
-
- `src/prompt-inference.ts` — fallback recovery of context files, skills, and guideline sections from the live system prompt
|
|
106
|
-
- `src/renderer.ts` — custom renderer for `supi-context` messages
|
|
107
|
-
- `src/report-component.ts` — shared width-aware report component for message and tool renderers
|
|
108
|
-
- `src/tool/guidance.ts` — tool description, prompt snippet, and guidelines for the agent tool
|
|
109
|
-
- `src/tool/render.ts` — TUI call/result renderer for the agent tool
|
|
110
|
-
- `src/utils.ts` — token and plural-format helpers
|
|
98
|
+
- `src/context.ts` — surface registration and cached prompt-option handling
|
|
99
|
+
- `src/capacity.ts` — shared capacity analysis and snapshot shape
|
|
100
|
+
- `src/analysis.ts` — diagnostic attribution and report data assembly
|
|
101
|
+
- `src/entry-renderer.ts` — TUI-only custom-entry renderer for the human command
|
|
102
|
+
- `src/format*.ts` and `src/report-component.ts` — Context Usage Report rendering
|
|
103
|
+
- `src/snapshot-component.ts` — compact, width-safe snapshot rendering
|
|
104
|
+
- `src/tool/guidance.ts`, `src/tool/output.ts`, and `src/tool/render.ts` — agent-tool guidance, safe full JSON output, and tool rendering
|
|
111
105
|
|
|
112
106
|
Tests live under `__tests__/unit/`.
|
|
@@ -43,7 +43,7 @@ Config file locations:
|
|
|
43
43
|
- `registerSettingsCommand(pi)` — register `/supi-settings` (used by `@mrclrchtr/supi-settings`)
|
|
44
44
|
- `openSettingsOverlay(pi, ctx)` — open the shared settings UI directly
|
|
45
45
|
- `createInputSubmenu()` — helper for simple text-entry submenus
|
|
46
|
-
- `createModelPickerSubmenu()` — helper for scoped model selection submenus
|
|
46
|
+
- `createModelPickerSubmenu()` — helper for scoped model selection submenus, with optional host-owned choices and `disabled` control
|
|
47
47
|
|
|
48
48
|
The built-in settings UI supports:
|
|
49
49
|
|
|
@@ -91,9 +91,23 @@ export interface StringListField extends BaseField {
|
|
|
91
91
|
kind: "stringList";
|
|
92
92
|
}
|
|
93
93
|
|
|
94
|
+
/** One non-model choice shown before the scoped models in a model picker. */
|
|
95
|
+
export interface ModelPickerStaticOption {
|
|
96
|
+
/** Persisted value for the choice. */
|
|
97
|
+
value: string;
|
|
98
|
+
/** Human-readable picker label. */
|
|
99
|
+
label: string;
|
|
100
|
+
/** Optional explanation shown alongside the label. */
|
|
101
|
+
description?: string;
|
|
102
|
+
}
|
|
103
|
+
|
|
94
104
|
/** Model picker backed by the scoped model set. */
|
|
95
105
|
export interface ModelPickerField extends BaseField {
|
|
96
106
|
kind: "modelPicker";
|
|
107
|
+
/** Additional host-owned choices shown before scoped models. */
|
|
108
|
+
staticOptions?: ModelPickerStaticOption[];
|
|
109
|
+
/** Whether to include the built-in `disabled` choice. Defaults to true. */
|
|
110
|
+
includeDisabled?: boolean;
|
|
97
111
|
}
|
|
98
112
|
|
|
99
113
|
/**
|
|
@@ -14,6 +14,7 @@ import {
|
|
|
14
14
|
Text,
|
|
15
15
|
} from "@earendil-works/pi-tui";
|
|
16
16
|
import { getSelectableModels } from "../model-selection.ts";
|
|
17
|
+
import type { ModelPickerField } from "./settings-schema.ts";
|
|
17
18
|
|
|
18
19
|
/**
|
|
19
20
|
* Creates a pi-tui Input-backed submenu component with enter-to-confirm
|
|
@@ -57,25 +58,26 @@ export function createInputSubmenu(
|
|
|
57
58
|
}
|
|
58
59
|
|
|
59
60
|
/**
|
|
60
|
-
* Creates a model picker submenu
|
|
61
|
+
* Creates a model picker submenu backed by the scoped model set.
|
|
62
|
+
*
|
|
63
|
+
* The built-in `disabled` choice remains enabled by default. Callers can add
|
|
64
|
+
* host-owned static choices or omit `disabled` through the field options.
|
|
61
65
|
*/
|
|
62
66
|
export function createModelPickerSubmenu(
|
|
63
67
|
currentValue: string,
|
|
64
68
|
done: (selectedValue?: string) => void,
|
|
65
69
|
ctx?: ExtensionContext,
|
|
70
|
+
options: Pick<ModelPickerField, "includeDisabled" | "staticOptions"> = {},
|
|
66
71
|
): {
|
|
67
72
|
render: (width: number) => string[];
|
|
68
73
|
invalidate: () => void;
|
|
69
74
|
handleInput: (data: string) => boolean;
|
|
70
75
|
} {
|
|
71
|
-
const items = buildModelItems(ctx);
|
|
72
|
-
const initialIndex =
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
0,
|
|
77
|
-
items.findIndex((item) => item.value === currentValue),
|
|
78
|
-
);
|
|
76
|
+
const items = buildModelItems(ctx, options);
|
|
77
|
+
const initialIndex = Math.max(
|
|
78
|
+
0,
|
|
79
|
+
items.findIndex((item) => item.value === currentValue),
|
|
80
|
+
);
|
|
79
81
|
|
|
80
82
|
const container = new Container();
|
|
81
83
|
container.addChild(new Text(" Select model", 1, 0));
|
|
@@ -105,20 +107,35 @@ export function createModelPickerSubmenu(
|
|
|
105
107
|
};
|
|
106
108
|
}
|
|
107
109
|
|
|
108
|
-
/** Build
|
|
109
|
-
function buildModelItems(
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
110
|
+
/** Build static choices followed by the selectable scoped models. */
|
|
111
|
+
function buildModelItems(
|
|
112
|
+
ctx: ExtensionContext | undefined,
|
|
113
|
+
options: Pick<ModelPickerField, "includeDisabled" | "staticOptions">,
|
|
114
|
+
): SelectItem[] {
|
|
115
|
+
const items: SelectItem[] = [];
|
|
116
|
+
const seen = new Set<string>();
|
|
117
|
+
for (const option of options.staticOptions ?? []) {
|
|
118
|
+
if (seen.has(option.value)) continue;
|
|
119
|
+
items.push({ ...option });
|
|
120
|
+
seen.add(option.value);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
if (options.includeDisabled !== false && !seen.has("disabled")) {
|
|
124
|
+
items.push({ value: "disabled", label: "disabled", description: "No model selected" });
|
|
125
|
+
seen.add("disabled");
|
|
126
|
+
}
|
|
127
|
+
|
|
113
128
|
if (!ctx) return items;
|
|
114
129
|
const models = getSelectableModels(ctx);
|
|
115
130
|
for (const model of models) {
|
|
131
|
+
if (seen.has(model.canonicalId)) continue;
|
|
116
132
|
const suffix = model.isCurrent ? " [current]" : "";
|
|
117
133
|
items.push({
|
|
118
134
|
value: model.canonicalId,
|
|
119
135
|
label: `${model.canonicalId}${suffix}`,
|
|
120
136
|
description: model.label !== model.canonicalId ? model.label : undefined,
|
|
121
137
|
});
|
|
138
|
+
seen.add(model.canonicalId);
|
|
122
139
|
}
|
|
123
140
|
return items;
|
|
124
141
|
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mrclrchtr/supi-context",
|
|
3
|
-
"version": "2.
|
|
4
|
-
"description": "SuPi Context extension —
|
|
3
|
+
"version": "2.8.0",
|
|
4
|
+
"description": "SuPi Context extension — agent pressure snapshots and TUI usage reports",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
@@ -32,16 +32,20 @@
|
|
|
32
32
|
],
|
|
33
33
|
"dependencies": {
|
|
34
34
|
"typebox": "*",
|
|
35
|
-
"@mrclrchtr/supi-core": "2.
|
|
35
|
+
"@mrclrchtr/supi-core": "2.8.0"
|
|
36
36
|
},
|
|
37
37
|
"bundledDependencies": [
|
|
38
38
|
"@mrclrchtr/supi-core"
|
|
39
39
|
],
|
|
40
40
|
"peerDependencies": {
|
|
41
|
+
"@earendil-works/pi-ai": "*",
|
|
41
42
|
"@earendil-works/pi-coding-agent": "*",
|
|
42
43
|
"@earendil-works/pi-tui": "*"
|
|
43
44
|
},
|
|
44
45
|
"peerDependenciesMeta": {
|
|
46
|
+
"@earendil-works/pi-ai": {
|
|
47
|
+
"optional": true
|
|
48
|
+
},
|
|
45
49
|
"@earendil-works/pi-coding-agent": {
|
|
46
50
|
"optional": true
|
|
47
51
|
},
|
|
@@ -52,8 +56,7 @@
|
|
|
52
56
|
"pi": {
|
|
53
57
|
"extensions": [
|
|
54
58
|
"./src/extension.ts"
|
|
55
|
-
]
|
|
56
|
-
"image": "https://raw.githubusercontent.com/mrclrchtr/supi/main/screenshots/supi-context.png"
|
|
59
|
+
]
|
|
57
60
|
},
|
|
58
61
|
"main": "src/api.ts",
|
|
59
62
|
"exports": {
|