@karmaniverous/stan-core 0.3.0 → 0.4.1
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 +188 -155
- package/dist/cjs/index.js +1 -1
- package/dist/mjs/index.js +1 -1
- package/dist/stan.system.md +49 -0
- package/dist/types/index.d.ts +70 -4
- package/package.json +4 -4
package/dist/stan.system.md
CHANGED
|
@@ -801,6 +801,55 @@ diff --git a/new/path/to/file/a.ts b/new/path/to/file/a.ts
|
|
|
801
801
|
- When attaching artifacts for chat, prefer attaching `<stanPath>/output/archive.tar` (and `<stanPath>/output/archive.diff.tar` when present). If `--combine` was not used, you may also attach the text outputs individually.
|
|
802
802
|
- Important: Inside any attached archive, contextual files are located in the directory matching the `stanPath` key from `stan.config.*` (default `.stan`). The bootloader resolves this automatically.
|
|
803
803
|
|
|
804
|
+
# Facet‑aware editing guard (think beyond the next turn)
|
|
805
|
+
|
|
806
|
+
Purpose
|
|
807
|
+
- Prevent proposing content patches for files that are absent from the attached archives because a facet is inactive this run (overlay enabled).
|
|
808
|
+
- Preserve integrity‑first intake while keeping velocity high: when a target is hidden by the current view, enable the facet now and deliver the edits next turn.
|
|
809
|
+
|
|
810
|
+
Inputs to read first (when present)
|
|
811
|
+
- `<stanPath>/system/.docs.meta.json` — overlay record for this run:
|
|
812
|
+
- `overlay.enabled: boolean`
|
|
813
|
+
- `overlay.effective: Record<facet, boolean>` (true = active)
|
|
814
|
+
- `<stanPath>/system/facet.meta.json` — durable facet definitions:
|
|
815
|
+
- `name → { exclude: string[]; include: string[] }`
|
|
816
|
+
- exclude lists define facetized subtrees; include lists are anchors (always kept)
|
|
817
|
+
|
|
818
|
+
Guardrail (hard rule)
|
|
819
|
+
- If `overlay.enabled === true` and a target path falls under any facet whose `overlay.effective[facet] === false` (inactive this run), do NOT emit a content Patch for that target in this turn.
|
|
820
|
+
- Instead:
|
|
821
|
+
- Explain that the path is hidden by an inactive facet this run.
|
|
822
|
+
- Enable the facet for the next run:
|
|
823
|
+
- Prefer a patch to `<stanPath>/system/facet.state.json` setting that facet to `true` (next‑run default), and
|
|
824
|
+
- Tell the user to re‑run with `stan run -f <facet>` (overlay ON; facet active) or `stan run -F` (overlay OFF) for a full baseline.
|
|
825
|
+
- Log the intent in `<stanPath>/system/stan.todo.md` (“enable facet <name> to edit <path> next turn”).
|
|
826
|
+
- Deliver the actual content edits in the next turn after a run with the facet active (or overlay disabled).
|
|
827
|
+
|
|
828
|
+
Allowed mixing (keep velocity without violating integrity)
|
|
829
|
+
- It is OK to:
|
|
830
|
+
- Patch other files that are already visible in this run.
|
|
831
|
+
- Update `facet.meta.json` (e.g., add anchors) together with `facet.state.json`.
|
|
832
|
+
- Create or update anchor documents (breadcrumbs) even when the facet is currently inactive — anchors are always included in the next run once listed in `include`.
|
|
833
|
+
- It is NOT OK to:
|
|
834
|
+
- Emit a content Patch for a file under a facet you are enabling in the same turn.
|
|
835
|
+
- Attempt to override reserved denials (`.git/**`, `<stanPath>/diff/**`, `<stanPath>/patch/**`, and archive outputs under `<stanPath>/output/…`); anchors never override these.
|
|
836
|
+
|
|
837
|
+
Resolution algorithm (assistant‑side; POSIX paths)
|
|
838
|
+
1) Load `.docs.meta.json`. If absent or `overlay.enabled !== true`, skip this guard.
|
|
839
|
+
2) Load `facet.meta.json` and derive subtree roots for each facet’s `exclude` patterns (strip common glob tails like `/**` or `/*`, trim trailing “/”; ignore leaf‑globs such as `**/*.test.ts` for subtree matching).
|
|
840
|
+
3) For each intended patch target:
|
|
841
|
+
- If the target lies under any facet subtree and that facet is inactive per `overlay.effective`, block the edit this turn and propose facet activation instead (see Guardrail).
|
|
842
|
+
4) If overlay metadata is missing but the target file is simply absent from the archive set, treat this as a hidden target; ask to re‑run with `-f <facet>` or `-F` and resume next turn.
|
|
843
|
+
|
|
844
|
+
Optional metadata (CLI nicety; not required)
|
|
845
|
+
- When `overlay.facetRoots: Record<facet, string[]>` is present in `.docs.meta.json`, prefer those pre‑normalized subtree roots over local glob heuristics.
|
|
846
|
+
|
|
847
|
+
Notes
|
|
848
|
+
- Reserved denials and binary screening always win; anchors cannot re‑include them.
|
|
849
|
+
- The goal is two‑turn cadence for hidden targets:
|
|
850
|
+
- Turn N: enable the facet + log intent.
|
|
851
|
+
- Turn N+1: deliver the content edits once the target is present in archives.
|
|
852
|
+
|
|
804
853
|
# Default Task (when files are provided with no extra prompt)
|
|
805
854
|
|
|
806
855
|
Primary objective — Plan-first
|
package/dist/types/index.d.ts
CHANGED
|
@@ -16,8 +16,38 @@ type CreateArchiveOptions = {
|
|
|
16
16
|
excludes?: string[];
|
|
17
17
|
/** Optional callback for archive classifier warnings (engine remains silent by default). */
|
|
18
18
|
onArchiveWarnings?: (text: string) => void;
|
|
19
|
+
/**
|
|
20
|
+
* High‑precedence re‑includes (subject to reserved denials and output exclusion).
|
|
21
|
+
* Anchors re-include paths even when excluded by `.gitignore` or `excludes`,
|
|
22
|
+
* but they never override reserved workspace denials:
|
|
23
|
+
* - `<stanPath>/diff/**`, `<stanPath>/patch/**`
|
|
24
|
+
* - `<stanPath>/output/{archive.tar,archive.diff.tar,archive.warnings.txt}`
|
|
25
|
+
* - `.git/**`
|
|
26
|
+
*
|
|
27
|
+
* @example
|
|
28
|
+
* ```ts
|
|
29
|
+
* // Force-include README.md even if repo excludes would drop it:
|
|
30
|
+
* await createArchive(cwd, '.stan', {
|
|
31
|
+
* includes: [],
|
|
32
|
+
* excludes: ['README.md'],
|
|
33
|
+
* anchors: ['README.md'],
|
|
34
|
+
* });
|
|
35
|
+
* ```
|
|
36
|
+
*/
|
|
37
|
+
anchors?: string[];
|
|
19
38
|
};
|
|
20
|
-
/**
|
|
39
|
+
/**
|
|
40
|
+
* Create `stanPath/output/archive.tar` (or custom file name) from the repo root.
|
|
41
|
+
*
|
|
42
|
+
* @example
|
|
43
|
+
* ```ts
|
|
44
|
+
* const tarPath = await createArchive(process.cwd(), '.stan', {
|
|
45
|
+
* includeOutputDir: false,
|
|
46
|
+
* excludes: ['**\/.tsbuild/**'],
|
|
47
|
+
* anchors: ['README.md', 'docs/index.md'], // re-include anchors
|
|
48
|
+
* });
|
|
49
|
+
* ```
|
|
50
|
+
*/
|
|
21
51
|
declare const createArchive: (cwd: string, stanPath: string, options?: CreateArchiveOptions) => Promise<string>;
|
|
22
52
|
|
|
23
53
|
/** Public default STAN path for consumers and internal use. */
|
|
@@ -93,13 +123,26 @@ type SnapshotUpdateMode = 'never' | 'createIfMissing' | 'replace';
|
|
|
93
123
|
* - stanPath: STAN workspace folder.
|
|
94
124
|
* - includes: Allow‑list globs (overrides excludes).
|
|
95
125
|
* - excludes: Deny‑list globs.
|
|
126
|
+
* - anchors: High‑precedence re‑includes (subject to reserved/output).
|
|
127
|
+
*
|
|
128
|
+
* @example
|
|
129
|
+
* ```ts
|
|
130
|
+
* // Seed snapshot using anchors to keep README.md even when excluded:
|
|
131
|
+
* await writeArchiveSnapshot({
|
|
132
|
+
* cwd: process.cwd(),
|
|
133
|
+
* stanPath: '.stan',
|
|
134
|
+
* excludes: ['README.md'],
|
|
135
|
+
* anchors: ['README.md'],
|
|
136
|
+
* });
|
|
137
|
+
* ```
|
|
96
138
|
* @returns Absolute path to the `.archive.snapshot.json` file.
|
|
97
139
|
*/
|
|
98
|
-
declare const writeArchiveSnapshot: ({ cwd, stanPath, includes, excludes, }: {
|
|
140
|
+
declare const writeArchiveSnapshot: ({ cwd, stanPath, includes, excludes, anchors, }: {
|
|
99
141
|
cwd: string;
|
|
100
142
|
stanPath: string;
|
|
101
143
|
includes?: string[];
|
|
102
144
|
excludes?: string[];
|
|
145
|
+
anchors?: string[];
|
|
103
146
|
}) => Promise<string>;
|
|
104
147
|
/**
|
|
105
148
|
* Create a diff tar at <stanPath>/output/<baseName>.diff.tar.
|
|
@@ -116,11 +159,25 @@ declare const writeArchiveSnapshot: ({ cwd, stanPath, includes, excludes, }: {
|
|
|
116
159
|
* - baseName: Base archive name (e.g., `archive` -\> `archive.diff.tar`).
|
|
117
160
|
* - includes: Allow‑list globs (overrides excludes).
|
|
118
161
|
* - excludes: Deny‑list globs.
|
|
162
|
+
* - anchors: High‑precedence re‑includes (subject to reserved/output).
|
|
119
163
|
* - updateSnapshot: Controls when the snapshot file is replaced.
|
|
120
164
|
* - includeOutputDirInDiff: When true, include `stanPath/output` in the diff.
|
|
121
165
|
* @returns `{ diffPath }` absolute path to the diff archive.
|
|
166
|
+
*
|
|
167
|
+
* @example
|
|
168
|
+
* ```ts
|
|
169
|
+
* // Diff archive with anchors to retain docs/overview.md:
|
|
170
|
+
* const { diffPath } = await createArchiveDiff({
|
|
171
|
+
* cwd: process.cwd(),
|
|
172
|
+
* stanPath: '.stan',
|
|
173
|
+
* baseName: 'archive',
|
|
174
|
+
* excludes: ['docs/**'],
|
|
175
|
+
* anchors: ['docs/overview.md'],
|
|
176
|
+
* updateSnapshot: 'createIfMissing',
|
|
177
|
+
* });
|
|
178
|
+
* ```
|
|
122
179
|
*/
|
|
123
|
-
declare const createArchiveDiff: ({ cwd, stanPath, baseName, includes, excludes, updateSnapshot, includeOutputDirInDiff, onArchiveWarnings, }: {
|
|
180
|
+
declare const createArchiveDiff: ({ cwd, stanPath, baseName, includes, excludes, updateSnapshot, includeOutputDirInDiff, anchors, onArchiveWarnings, }: {
|
|
124
181
|
cwd: string;
|
|
125
182
|
stanPath: string;
|
|
126
183
|
baseName: string;
|
|
@@ -128,6 +185,7 @@ declare const createArchiveDiff: ({ cwd, stanPath, baseName, includes, excludes,
|
|
|
128
185
|
excludes?: string[];
|
|
129
186
|
updateSnapshot?: SnapshotUpdateMode;
|
|
130
187
|
includeOutputDirInDiff?: boolean;
|
|
188
|
+
anchors?: string[];
|
|
131
189
|
onArchiveWarnings?: (text: string) => void;
|
|
132
190
|
}) => Promise<{
|
|
133
191
|
diffPath: string;
|
|
@@ -279,6 +337,14 @@ declare const prepareImports: (args: {
|
|
|
279
337
|
onStage?: (label: string, files: string[]) => void;
|
|
280
338
|
}) => Promise<void>;
|
|
281
339
|
|
|
340
|
+
/**
|
|
341
|
+
* Compile an engine‑parity matcher that returns true when any pattern matches.
|
|
342
|
+
*
|
|
343
|
+
* @param patterns - Glob/prefix patterns (POSIX paths).
|
|
344
|
+
* @returns (relPath) =\> boolean
|
|
345
|
+
*/
|
|
346
|
+
declare const makeGlobMatcher: (patterns: string[]) => ((rel: string) => boolean);
|
|
347
|
+
|
|
282
348
|
/** Resolve packaged dist/stan.system.md if present. */
|
|
283
349
|
declare const getPackagedSystemPromptPath: () => string | null;
|
|
284
350
|
|
|
@@ -304,5 +370,5 @@ declare const assembleSystemMonolith: (cwd: string, stanPath: string) => Promise
|
|
|
304
370
|
|
|
305
371
|
declare const CORE_VERSION: string;
|
|
306
372
|
|
|
307
|
-
export { CORE_VERSION, DEFAULT_OPEN_COMMAND, DEFAULT_STAN_PATH, __internal, applyPatchPipeline, applyWithJsDiff, assembleSystemMonolith, createArchive, createArchiveDiff, detectAndCleanPatch, ensureOutputDir, executeFileOps, findConfigPathSync, getPackagedSystemPromptPath, loadConfig, loadConfigSync, parseFileOpsBlock, prepareImports, resolveStanPath, resolveStanPathSync, validateOrThrow, validateResponseMessage, writeArchiveSnapshot };
|
|
373
|
+
export { CORE_VERSION, DEFAULT_OPEN_COMMAND, DEFAULT_STAN_PATH, __internal, applyPatchPipeline, applyWithJsDiff, assembleSystemMonolith, createArchive, createArchiveDiff, detectAndCleanPatch, ensureOutputDir, executeFileOps, findConfigPathSync, getPackagedSystemPromptPath, loadConfig, loadConfigSync, makeGlobMatcher, parseFileOpsBlock, prepareImports, resolveStanPath, resolveStanPathSync, validateOrThrow, validateResponseMessage, writeArchiveSnapshot };
|
|
308
374
|
export type { ApplyResult, AssembleResult, AttemptCapture, Block, BlockKind, ContextConfig, CreateArchiveOptions, FileOp, FileOpsPlan, ImportsMap, JsDiffOutcome, OpResult, PipelineOutcome, SnapshotUpdateMode, ValidationResult };
|
package/package.json
CHANGED
|
@@ -12,14 +12,14 @@
|
|
|
12
12
|
"dependencies": {
|
|
13
13
|
"@vitest/eslint-plugin": "^1.3.15",
|
|
14
14
|
"diff": "^8.0.2",
|
|
15
|
-
"fs-extra": "^11.3.2",
|
|
16
15
|
"fast-glob": "^3.3.3",
|
|
16
|
+
"fs-extra": "^11.3.2",
|
|
17
17
|
"glob-parent": "^6.0.2",
|
|
18
18
|
"ignore": "^7.0.5",
|
|
19
19
|
"package-directory": "^8.1.0",
|
|
20
20
|
"picomatch": "^4.0.3",
|
|
21
|
-
"
|
|
22
|
-
"
|
|
21
|
+
"yaml": "^2.8.1",
|
|
22
|
+
"zod": "^4.1.11"
|
|
23
23
|
},
|
|
24
24
|
"description": "Engine for STAN — programmatic archiving/diffing/snapshotting, patch application, config loading, selection, and imports staging. No CLI/TTY concerns.",
|
|
25
25
|
"devDependencies": {
|
|
@@ -151,5 +151,5 @@
|
|
|
151
151
|
},
|
|
152
152
|
"type": "module",
|
|
153
153
|
"types": "dist/index.d.ts",
|
|
154
|
-
"version": "0.
|
|
154
|
+
"version": "0.4.1"
|
|
155
155
|
}
|