@orkestrel/scaffold 0.0.77 → 0.0.79
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/dist/agents/skills/orkestrel-dispatch/scripts/bench.js +204 -0
- package/dist/agents/skills/orkestrel-dispatch/scripts/brief.js +102 -0
- package/dist/agents/skills/orkestrel-dispatch/scripts/cite.js +95 -0
- package/dist/agents/skills/orkestrel-dispatch/scripts/helpers.js +207 -0
- package/dist/agents/skills/orkestrel-dispatch/scripts/launch.js +108 -0
- package/dist/agents/skills/orkestrel-dispatch/scripts/login.js +114 -0
- package/dist/agents/skills/orkestrel-dispatch/scripts/result.js +108 -0
- package/dist/agents/skills/orkestrel-dispatch/scripts/sweep.js +156 -0
- package/dist/agents/skills/orkestrel-harden/scripts/discovery.js +196 -0
- package/dist/agents/skills/orkestrel-publish/scripts/compare.js +206 -0
- package/dist/agents/skills/orkestrel-publish/scripts/pins.js +93 -0
- package/dist/agents/skills/orkestrel-publish/scripts/wave.js +458 -0
- package/dist/agents/skills/orkestrel-publish/scripts/window.js +188 -0
- package/dist/agents/skills/orkestrel-scout/scripts/map.js +300 -0
- package/dist/agents/templates/brief.md +55 -0
- package/dist/bin/main.js +58 -6
- package/dist/bin/main.js.map +1 -1
- package/dist/host/AGENTS.md +77 -135
- package/dist/host/agents/orchestration.md +147 -998
- package/dist/host/agents/skills/enterprise-bootstrap/SKILL.md +2 -2
- package/dist/host/agents/skills/enterprise-bootstrap/references/inspection.md +1 -1
- package/dist/host/agents/skills/{orkestrel-align-packages → orkestrel-align}/SKILL.md +6 -13
- package/dist/host/agents/skills/{orkestrel-align-packages → orkestrel-align}/agents/openai.yaml +1 -1
- package/dist/host/agents/skills/{orkestrel-align-packages → orkestrel-align}/references/fleet.md +5 -7
- package/dist/host/agents/skills/{orkestrel-build-application → orkestrel-build}/SKILL.md +11 -22
- package/dist/host/agents/skills/{orkestrel-build-application → orkestrel-build}/agents/openai.yaml +1 -1
- package/dist/host/agents/skills/orkestrel-debrief/SKILL.md +8 -16
- package/dist/host/agents/skills/orkestrel-debrief/references/instruction-audit.md +3 -3
- package/dist/host/agents/skills/orkestrel-debrief/references/retention.md +13 -13
- package/dist/host/agents/skills/orkestrel-dispatch/SKILL.md +61 -0
- package/dist/host/agents/skills/orkestrel-dispatch/agents/openai.yaml +4 -0
- package/dist/host/agents/skills/orkestrel-dispatch/references/bench.md +25 -0
- package/dist/host/agents/skills/orkestrel-dispatch/references/launch.md +32 -0
- package/dist/host/agents/skills/orkestrel-dispatch/scripts/bench.ts +259 -0
- package/dist/host/agents/skills/orkestrel-dispatch/scripts/brief.ts +110 -0
- package/dist/host/agents/skills/orkestrel-dispatch/scripts/cite.ts +115 -0
- package/dist/host/agents/skills/orkestrel-dispatch/scripts/helpers.ts +239 -0
- package/dist/host/agents/skills/orkestrel-dispatch/scripts/launch.ts +124 -0
- package/dist/host/agents/skills/orkestrel-dispatch/scripts/login.ts +123 -0
- package/dist/host/agents/skills/orkestrel-dispatch/scripts/result.ts +129 -0
- package/dist/host/agents/skills/orkestrel-dispatch/scripts/sweep.ts +157 -0
- package/dist/host/agents/skills/orkestrel-falsify/SKILL.md +42 -193
- package/dist/host/agents/skills/orkestrel-falsify/references/brief.md +38 -108
- package/dist/host/agents/skills/orkestrel-falsify/references/reconcile.md +35 -134
- package/dist/host/agents/skills/{orkestrel-harden-package → orkestrel-harden}/SKILL.md +10 -14
- package/dist/host/agents/skills/{orkestrel-harden-package → orkestrel-harden}/agents/openai.yaml +1 -1
- package/dist/host/agents/skills/{orkestrel-harden-package → orkestrel-harden}/references/hardening.md +3 -4
- package/dist/host/agents/skills/orkestrel-harden/scripts/discovery.ts +228 -0
- package/dist/host/agents/skills/{orkestrel-prove-journey → orkestrel-journey}/SKILL.md +15 -23
- package/dist/host/agents/skills/orkestrel-journey/agents/openai.yaml +4 -0
- package/dist/host/agents/skills/{orkestrel-prove-journey → orkestrel-journey}/references/captures.md +1 -1
- package/dist/host/agents/skills/{orkestrel-polish-surface → orkestrel-polish}/SKILL.md +25 -33
- package/dist/host/agents/skills/{orkestrel-polish-surface → orkestrel-polish}/agents/openai.yaml +1 -1
- package/dist/host/agents/skills/{orkestrel-polish-surface → orkestrel-polish}/references/capture-harness.md +3 -3
- package/dist/host/agents/skills/orkestrel-publish/SKILL.md +33 -20
- package/dist/host/agents/skills/orkestrel-publish/references/release.md +39 -0
- package/dist/host/agents/skills/orkestrel-publish/references/wave.md +22 -21
- package/dist/host/agents/skills/orkestrel-publish/references/window.md +27 -14
- package/dist/host/agents/skills/orkestrel-publish/scripts/compare.ts +220 -0
- package/dist/host/agents/skills/orkestrel-publish/scripts/pins.ts +114 -0
- package/dist/host/agents/skills/orkestrel-publish/scripts/wave.ts +629 -0
- package/dist/host/agents/skills/orkestrel-publish/scripts/window.ts +242 -0
- package/dist/host/agents/skills/orkestrel-scout/SKILL.md +28 -0
- package/dist/host/agents/skills/orkestrel-scout/agents/openai.yaml +4 -0
- package/dist/host/agents/skills/orkestrel-scout/scripts/map.ts +352 -0
- package/dist/host/agents/templates/brief.md +21 -142
- package/dist/host/agents/transports/claude-cli.md +21 -0
- package/dist/host/agents/transports/codex.md +38 -159
- package/dist/host/agents/transports/cursor.md +16 -65
- package/dist/host/claude/AGENTS.md +38 -0
- package/dist/host/claude/agents/analyst.md +14 -53
- package/dist/host/claude/agents/astra.md +26 -0
- package/dist/host/claude/agents/builder.md +14 -30
- package/dist/host/claude/agents/checker.md +13 -57
- package/dist/host/claude/agents/distiller.md +11 -26
- package/dist/host/claude/agents/grok.md +12 -35
- package/dist/host/claude/agents/opus.md +14 -30
- package/dist/host/claude/agents/orkestrel.md +4 -4
- package/dist/host/claude/agents/planner.md +10 -44
- package/dist/host/claude/agents/researcher.md +11 -30
- package/dist/host/claude/agents/reviewer.md +11 -95
- package/dist/host/claude/agents/scout.md +9 -23
- package/dist/host/claude/agents/verifier.md +15 -33
- package/dist/host/claude/rules/documentation.md +8 -2
- package/dist/host/claude/rules/portability.md +7 -1
- package/dist/host/claude/rules/quality.md +36 -96
- package/dist/host/claude/rules/styles.md +3 -0
- package/dist/host/claude/rules/tests.md +6 -3
- package/dist/host/claude/rules/workspace.md +21 -15
- package/dist/host/claude/rules/writing.md +57 -108
- package/dist/host/claude/settings.json +5 -3
- package/dist/host/claude/skills/enterprise-bootstrap/SKILL.md +1 -1
- package/dist/host/claude/skills/{orkestrel-align-packages → orkestrel-align}/SKILL.md +2 -2
- package/dist/host/claude/skills/{orkestrel-build-application → orkestrel-build}/SKILL.md +2 -2
- package/dist/host/claude/skills/orkestrel-dispatch/SKILL.md +11 -0
- package/dist/host/claude/skills/orkestrel-falsify/SKILL.md +2 -1
- package/dist/host/claude/skills/{orkestrel-harden-package → orkestrel-harden}/SKILL.md +2 -2
- package/dist/host/claude/skills/{orkestrel-prove-journey → orkestrel-journey}/SKILL.md +2 -2
- package/dist/host/claude/skills/orkestrel-polish/SKILL.md +12 -0
- package/dist/host/claude/skills/orkestrel-scout/SKILL.md +11 -0
- package/dist/host/codex/agents/analyst.toml +14 -31
- package/dist/host/codex/agents/astra.toml +25 -0
- package/dist/host/codex/agents/builder.toml +13 -20
- package/dist/host/codex/agents/checker.toml +13 -27
- package/dist/host/codex/agents/distiller.toml +9 -22
- package/dist/host/codex/agents/grok.toml +11 -30
- package/dist/host/codex/agents/opus.toml +14 -22
- package/dist/host/codex/agents/orkestrel.toml +1 -1
- package/dist/host/codex/agents/planner.toml +11 -28
- package/dist/host/codex/agents/researcher.toml +10 -22
- package/dist/host/codex/agents/reviewer.toml +11 -27
- package/dist/host/codex/agents/scout.toml +11 -17
- package/dist/host/codex/agents/verifier.toml +16 -12
- package/dist/host/codex/config.toml +18 -21
- package/dist/host/cursor/mcp.json +0 -4
- package/dist/host/cursor/rules/orchestration.mdc +12 -20
- package/dist/host/dotfiles/mcp.json +0 -4
- package/dist/host/dotfiles/oxlintrc.json +7 -0
- package/dist/host/guides/probe.md +18 -14
- package/dist/host/guides/scaffold.md +147 -83
- package/dist/host/guides/test.md +442 -148
- package/dist/host/manifest.json +322 -185
- package/dist/host/scripts/codex.sh +0 -0
- package/dist/host/scripts/cursor.sh +0 -0
- package/dist/host/scripts/deps.sh +0 -0
- package/dist/host/scripts/ollama.sh +0 -0
- package/dist/host/tests/config.test.ts +86 -55
- package/dist/host/tests/policy.test.ts +1 -5
- package/dist/host/tests/setupPolicy.ts +179 -4
- package/dist/src/core/index.cjs +264 -89
- package/dist/src/core/index.cjs.map +1 -1
- package/dist/src/core/index.d.cts +95 -30
- package/dist/src/core/index.d.ts +95 -30
- package/dist/src/core/index.js +262 -90
- package/dist/src/core/index.js.map +1 -1
- package/dist/src/server/index.cjs +55 -9
- package/dist/src/server/index.cjs.map +1 -1
- package/dist/src/server/index.d.cts +29 -4
- package/dist/src/server/index.d.ts +29 -4
- package/dist/src/server/index.js +56 -11
- package/dist/src/server/index.js.map +1 -1
- package/package.json +16 -12
- package/dist/host/CLAUDE.md +0 -61
- package/dist/host/agents/skills/orkestrel-prove-journey/agents/openai.yaml +0 -4
- package/dist/host/agents/transports/claude.md +0 -49
- package/dist/host/claude/agents/application.md +0 -36
- package/dist/host/claude/agents/sol.md +0 -61
- package/dist/host/claude/skills/orkestrel-polish-surface/SKILL.md +0 -12
- package/dist/host/codex/agents/application.toml +0 -25
- package/dist/host/codex/agents/sol.toml +0 -19
- /package/dist/host/agents/skills/{orkestrel-align-packages → orkestrel-align}/references/integration.md +0 -0
- /package/dist/host/agents/skills/{orkestrel-harden-package → orkestrel-harden}/references/centralization.md +0 -0
- /package/dist/host/agents/skills/{orkestrel-harden-package → orkestrel-harden}/references/contract.md +0 -0
- /package/dist/host/agents/skills/{orkestrel-harden-package → orkestrel-harden}/references/research.md +0 -0
- /package/dist/host/agents/skills/{orkestrel-prove-journey → orkestrel-journey}/references/decide.md +0 -0
- /package/dist/host/agents/skills/{orkestrel-prove-journey → orkestrel-journey}/references/layer.md +0 -0
- /package/dist/host/agents/skills/{orkestrel-prove-journey → orkestrel-journey}/references/statechart.md +0 -0
- /package/dist/host/agents/skills/{orkestrel-prove-journey → orkestrel-journey}/references/styles.md +0 -0
|
@@ -0,0 +1,300 @@
|
|
|
1
|
+
// Map terrain before a brief, an absorption lane, or a rename. Run from the checkout root:
|
|
2
|
+
// node .agents/skills/orkestrel-scout/scripts/map.ts --tree PATH... [--headings PATH...] [--frontmatter PATH...] [--exports PATH...] [--census TERM...] [--refs PATH] [--anchors PATH...] [--paths a,b] [--ignore-case] [--json] [--out FILE]
|
|
3
|
+
// --tree lists every file under each path with its line count and size. --headings lists every
|
|
4
|
+
// Markdown heading with its line. --frontmatter lists every key of a Markdown frontmatter block, a
|
|
5
|
+
// TOML file, or a YAML file with its whole value, a nested key dotted under its parents
|
|
6
|
+
// (`interface.default_prompt`) and a TOML key under its table. --exports lists every `export`
|
|
7
|
+
// declaration line in a TypeScript file (a text reading, not the compiler's). --census lists every line carrying a term. --refs lists
|
|
8
|
+
// every line naming a path or its basename. --anchors lists every `§ Heading` reference whose
|
|
9
|
+
// heading the named file, or the same file, does not carry. Walks skip node_modules, .git, dist,
|
|
10
|
+
// tmp, .orkestrel, .idea, and host.json; --paths narrows a census or refs walk. Modes combine, each
|
|
11
|
+
// printing its section; --json prints one object; --out writes the output to FILE instead of the
|
|
12
|
+
// terminal. Give each flag once; a later duplicate is not read. Exit 0, or 64 when no mode is
|
|
13
|
+
// given or --refs names no path.
|
|
14
|
+
import { existsSync, readFileSync, statSync, mkdirSync, writeFileSync } from 'node:fs';
|
|
15
|
+
import { basename, dirname } from 'node:path';
|
|
16
|
+
import { listFiles, normalizeSlashes, readList, readMissingFlags, readOption, } from "../../orkestrel-dispatch/scripts/helpers.js";
|
|
17
|
+
const EXPORT = /^export\s+(?:default\s+)?(?:async\s+)?(?:abstract\s+)?(function\*?|const|let|class|interface|type|enum|namespace)\s+([A-Za-z_$][\w$]*)/u;
|
|
18
|
+
const HEADING = /^(#{1,6})\s+(.+?)\s*#*\s*$/u;
|
|
19
|
+
const ANCHOR = /(?:`([^`\n]+\.md)`\s*)?§\s*"?([^"`\n|;,.)]+?)"?(?=\s*(?:[,.;)|]|\s(?:and|or|names|fixes|owns|states|binds|governs|decides|before|after)\b|$))/gu;
|
|
20
|
+
const BINARY = /\.(png|jpg|jpeg|gif|webp|ico|woff2?|ttf|otf|eot|zip|tgz|gz|pdf|wasm)$/u;
|
|
21
|
+
function isText(path) {
|
|
22
|
+
return !BINARY.test(path) && basename(path) !== 'host.json';
|
|
23
|
+
}
|
|
24
|
+
function expandPaths(paths) {
|
|
25
|
+
return paths.flatMap((path) => {
|
|
26
|
+
if (!existsSync(path))
|
|
27
|
+
return [];
|
|
28
|
+
if (statSync(path).isDirectory())
|
|
29
|
+
return listFiles(path).map((file) => file.path);
|
|
30
|
+
return [normalizeSlashes(path)];
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
function readLines(path) {
|
|
34
|
+
return readFileSync(path, 'utf8').split(/\r\n|\n/);
|
|
35
|
+
}
|
|
36
|
+
function mapTree(paths) {
|
|
37
|
+
return expandPaths(paths)
|
|
38
|
+
.filter(isText)
|
|
39
|
+
.map((path) => {
|
|
40
|
+
const text = readFileSync(path, 'utf8');
|
|
41
|
+
return {
|
|
42
|
+
path,
|
|
43
|
+
lines: text === '' ? 0 : text.split(/\r\n|\n/).length,
|
|
44
|
+
bytes: Buffer.byteLength(text),
|
|
45
|
+
};
|
|
46
|
+
})
|
|
47
|
+
.sort((left, right) => left.path.localeCompare(right.path));
|
|
48
|
+
}
|
|
49
|
+
function mapHeadings(paths) {
|
|
50
|
+
const rows = [];
|
|
51
|
+
for (const path of expandPaths(paths).filter((candidate) => candidate.endsWith('.md'))) {
|
|
52
|
+
let fenced = false;
|
|
53
|
+
readLines(path).forEach((text, index) => {
|
|
54
|
+
if (text.startsWith('```'))
|
|
55
|
+
fenced = !fenced;
|
|
56
|
+
if (fenced)
|
|
57
|
+
return;
|
|
58
|
+
const match = text.match(HEADING);
|
|
59
|
+
if (match?.[1] !== undefined && match[2] !== undefined) {
|
|
60
|
+
rows.push({ path, line: index + 1, text: `${match[1]} ${match[2]}` });
|
|
61
|
+
}
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
return rows;
|
|
65
|
+
}
|
|
66
|
+
function mapExports(paths) {
|
|
67
|
+
const rows = [];
|
|
68
|
+
for (const path of expandPaths(paths).filter((candidate) => /\.[cm]?ts$/u.test(candidate))) {
|
|
69
|
+
readLines(path).forEach((text, index) => {
|
|
70
|
+
const match = text.match(EXPORT);
|
|
71
|
+
if (match?.[1] !== undefined && match[2] !== undefined) {
|
|
72
|
+
rows.push({ path, line: index + 1, text: `${match[1]} ${match[2]}` });
|
|
73
|
+
}
|
|
74
|
+
else if (/^export\s+\*\s+from\s+/u.test(text)) {
|
|
75
|
+
rows.push({ path, line: index + 1, text: text.trim() });
|
|
76
|
+
}
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
return rows;
|
|
80
|
+
}
|
|
81
|
+
function buildMatcher(term, ignoreCase) {
|
|
82
|
+
const needle = ignoreCase ? term.toLowerCase() : term;
|
|
83
|
+
return (text) => (ignoreCase ? text.toLowerCase() : text).includes(needle);
|
|
84
|
+
}
|
|
85
|
+
function mapCensus(terms, roots, ignoreCase) {
|
|
86
|
+
const files = expandPaths(roots).filter(isText);
|
|
87
|
+
return terms.map((term) => {
|
|
88
|
+
const matches = buildMatcher(term, ignoreCase);
|
|
89
|
+
const rows = [];
|
|
90
|
+
for (const path of files) {
|
|
91
|
+
readLines(path).forEach((text, index) => {
|
|
92
|
+
if (matches(text))
|
|
93
|
+
rows.push({ path, line: index + 1, text: text.trim().slice(0, 160) });
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
return { term, rows };
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
function mapRefs(target, roots) {
|
|
100
|
+
const needle = normalizeSlashes(target);
|
|
101
|
+
const name = basename(needle);
|
|
102
|
+
const rows = [];
|
|
103
|
+
for (const path of expandPaths(roots).filter(isText)) {
|
|
104
|
+
if (path === needle)
|
|
105
|
+
continue;
|
|
106
|
+
readLines(path).forEach((text, index) => {
|
|
107
|
+
if (text.includes(needle) || text.includes(name)) {
|
|
108
|
+
rows.push({ path, line: index + 1, text: text.trim().slice(0, 160) });
|
|
109
|
+
}
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
return rows;
|
|
113
|
+
}
|
|
114
|
+
function readYamlKeys(path, lines, offset) {
|
|
115
|
+
const rows = [];
|
|
116
|
+
const stack = [];
|
|
117
|
+
lines.forEach((text, index) => {
|
|
118
|
+
const content = text.trimStart();
|
|
119
|
+
if (content === '' || content.startsWith('#'))
|
|
120
|
+
return;
|
|
121
|
+
const indent = text.length - content.length;
|
|
122
|
+
const match = content.match(/^([A-Za-z_][\w-]*)\s*:(?:\s+(.*))?$/u);
|
|
123
|
+
if (match?.[1] === undefined) {
|
|
124
|
+
// A list item, a block scalar line, or a wrapped value extends the key before it.
|
|
125
|
+
const last = rows.at(-1);
|
|
126
|
+
if (last !== undefined && indent >= (stack.at(-1)?.indent ?? 0)) {
|
|
127
|
+
rows[rows.length - 1] = { ...last, text: `${last.text} ${content.trim()}`.trimEnd() };
|
|
128
|
+
}
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
while (stack.length > 0 && (stack.at(-1)?.indent ?? 0) >= indent)
|
|
132
|
+
stack.pop();
|
|
133
|
+
const key = [...stack.map((entry) => entry.key), match[1]].join('.');
|
|
134
|
+
stack.push({ indent, key: match[1] });
|
|
135
|
+
rows.push({ path, line: index + offset, text: `${key}: ${(match[2] ?? '').trim()}`.trimEnd() });
|
|
136
|
+
});
|
|
137
|
+
return rows;
|
|
138
|
+
}
|
|
139
|
+
function readTomlKeys(path, lines, offset) {
|
|
140
|
+
const rows = [];
|
|
141
|
+
let table = '';
|
|
142
|
+
let fence;
|
|
143
|
+
lines.forEach((text, index) => {
|
|
144
|
+
if (fence !== undefined) {
|
|
145
|
+
// The body of a multi-line string carries no key.
|
|
146
|
+
if (text.includes(fence))
|
|
147
|
+
fence = undefined;
|
|
148
|
+
return;
|
|
149
|
+
}
|
|
150
|
+
const header = text.match(/^\s*\[\[?([^\]]+)\]\]?\s*$/u);
|
|
151
|
+
if (header?.[1] !== undefined) {
|
|
152
|
+
table = header[1].trim();
|
|
153
|
+
return;
|
|
154
|
+
}
|
|
155
|
+
const match = text.match(/^\s*([A-Za-z0-9_.-]+|"[^"]+")\s*=\s*(.*)$/u);
|
|
156
|
+
if (match?.[1] === undefined)
|
|
157
|
+
return;
|
|
158
|
+
const value = (match[2] ?? '').trim();
|
|
159
|
+
const opening = value.match(/^("""|''')/u)?.[1];
|
|
160
|
+
if (opening !== undefined && value.indexOf(opening, 3) === -1)
|
|
161
|
+
fence = opening;
|
|
162
|
+
rows.push({
|
|
163
|
+
path,
|
|
164
|
+
line: index + offset,
|
|
165
|
+
text: `${table === '' ? '' : `${table}.`}${match[1]}: ${value}`.trimEnd(),
|
|
166
|
+
});
|
|
167
|
+
});
|
|
168
|
+
return rows;
|
|
169
|
+
}
|
|
170
|
+
function mapFrontmatter(paths) {
|
|
171
|
+
const rows = [];
|
|
172
|
+
for (const path of expandPaths(paths).filter((candidate) => /\.(md|mdc|toml|ya?ml)$/u.test(candidate))) {
|
|
173
|
+
const lines = readLines(path);
|
|
174
|
+
const markdown = /\.mdc?$/u.test(path);
|
|
175
|
+
const end = markdown ? lines.indexOf('---', 1) : lines.length;
|
|
176
|
+
if (markdown && (lines[0] !== '---' || end === -1))
|
|
177
|
+
continue;
|
|
178
|
+
const body = lines.slice(markdown ? 1 : 0, end);
|
|
179
|
+
const offset = markdown ? 2 : 1;
|
|
180
|
+
rows.push(...(path.endsWith('.toml')
|
|
181
|
+
? readTomlKeys(path, body, offset)
|
|
182
|
+
: readYamlKeys(path, body, offset)));
|
|
183
|
+
}
|
|
184
|
+
return rows;
|
|
185
|
+
}
|
|
186
|
+
function readHeadingTexts(path) {
|
|
187
|
+
return new Set(mapHeadings([path]).map((row) => row.text.replace(/^#+\s+/u, '').toLowerCase()));
|
|
188
|
+
}
|
|
189
|
+
function mapAnchors(paths) {
|
|
190
|
+
const headings = new Map();
|
|
191
|
+
const rows = [];
|
|
192
|
+
for (const path of expandPaths(paths).filter((candidate) => candidate.endsWith('.md'))) {
|
|
193
|
+
readLines(path).forEach((text, index) => {
|
|
194
|
+
for (const match of text.matchAll(ANCHOR)) {
|
|
195
|
+
const target = match[1] === undefined ? path : normalizeSlashes(match[1]);
|
|
196
|
+
const heading = (match[2] ?? '').trim();
|
|
197
|
+
if (heading === '')
|
|
198
|
+
continue;
|
|
199
|
+
if (!existsSync(target)) {
|
|
200
|
+
rows.push({ path, line: index + 1, target, heading });
|
|
201
|
+
continue;
|
|
202
|
+
}
|
|
203
|
+
const known = headings.get(target) ?? readHeadingTexts(target);
|
|
204
|
+
headings.set(target, known);
|
|
205
|
+
if (!known.has(heading.toLowerCase()))
|
|
206
|
+
rows.push({ path, line: index + 1, target, heading });
|
|
207
|
+
}
|
|
208
|
+
});
|
|
209
|
+
}
|
|
210
|
+
return rows;
|
|
211
|
+
}
|
|
212
|
+
function renderReport(report) {
|
|
213
|
+
const lines = [];
|
|
214
|
+
if (report.tree !== undefined) {
|
|
215
|
+
lines.push('## Tree');
|
|
216
|
+
for (const row of report.tree)
|
|
217
|
+
lines.push(`${row.path}\t${row.lines} lines\t${row.bytes} bytes`);
|
|
218
|
+
lines.push(`total\t${report.tree.length} files\t${report.tree.reduce((sum, row) => sum + row.lines, 0)} lines`);
|
|
219
|
+
}
|
|
220
|
+
if (report.headings !== undefined) {
|
|
221
|
+
lines.push('## Headings');
|
|
222
|
+
for (const row of report.headings)
|
|
223
|
+
lines.push(`${row.path}:${row.line}\t${row.text}`);
|
|
224
|
+
}
|
|
225
|
+
if (report.frontmatter !== undefined) {
|
|
226
|
+
lines.push('## Frontmatter');
|
|
227
|
+
for (const row of report.frontmatter)
|
|
228
|
+
lines.push(`${row.path}:${row.line} ${row.text}`);
|
|
229
|
+
}
|
|
230
|
+
if (report.exports !== undefined) {
|
|
231
|
+
lines.push('## Exports (text reading)');
|
|
232
|
+
for (const row of report.exports)
|
|
233
|
+
lines.push(`${row.path}:${row.line}\t${row.text}`);
|
|
234
|
+
}
|
|
235
|
+
if (report.census !== undefined) {
|
|
236
|
+
for (const entry of report.census) {
|
|
237
|
+
lines.push(`## Census: ${entry.term} (${entry.rows.length})`);
|
|
238
|
+
for (const row of entry.rows)
|
|
239
|
+
lines.push(`${row.path}:${row.line}\t${row.text}`);
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
if (report.refs !== undefined) {
|
|
243
|
+
lines.push(`## Refs (${report.refs.length})`);
|
|
244
|
+
for (const row of report.refs)
|
|
245
|
+
lines.push(`${row.path}:${row.line}\t${row.text}`);
|
|
246
|
+
}
|
|
247
|
+
if (report.anchors !== undefined) {
|
|
248
|
+
lines.push(`## Unresolved anchors (${report.anchors.length})`);
|
|
249
|
+
for (const row of report.anchors)
|
|
250
|
+
lines.push(`${row.path}:${row.line}\t${row.target} § ${row.heading}`);
|
|
251
|
+
}
|
|
252
|
+
return `${lines.join('\n')}\n`;
|
|
253
|
+
}
|
|
254
|
+
function main(argv) {
|
|
255
|
+
const missing = readMissingFlags(argv, ['--refs', '--paths', '--out']);
|
|
256
|
+
if (missing.length > 0) {
|
|
257
|
+
console.error(`map: ${missing.join(', ')} given with no value`);
|
|
258
|
+
return 64;
|
|
259
|
+
}
|
|
260
|
+
const roots = (readOption(argv, '--paths') ?? '.').split(',');
|
|
261
|
+
const ignoreCase = argv.includes('--ignore-case');
|
|
262
|
+
const tree = readList(argv, '--tree');
|
|
263
|
+
const headings = readList(argv, '--headings');
|
|
264
|
+
const frontmatter = readList(argv, '--frontmatter');
|
|
265
|
+
const exports = readList(argv, '--exports');
|
|
266
|
+
const census = readList(argv, '--census');
|
|
267
|
+
const refs = readOption(argv, '--refs');
|
|
268
|
+
const anchors = readList(argv, '--anchors');
|
|
269
|
+
if (tree.length +
|
|
270
|
+
headings.length +
|
|
271
|
+
frontmatter.length +
|
|
272
|
+
exports.length +
|
|
273
|
+
census.length +
|
|
274
|
+
anchors.length ===
|
|
275
|
+
0 &&
|
|
276
|
+
refs === undefined) {
|
|
277
|
+
console.error('usage: map.ts [--tree PATH...] [--headings PATH...] [--frontmatter PATH...] [--exports PATH...] [--census TERM...] [--refs PATH] [--anchors PATH...] [--paths a,b] [--ignore-case] [--json] [--out FILE]');
|
|
278
|
+
return 64;
|
|
279
|
+
}
|
|
280
|
+
const report = {
|
|
281
|
+
...(tree.length > 0 ? { tree: mapTree(tree) } : {}),
|
|
282
|
+
...(headings.length > 0 ? { headings: mapHeadings(headings) } : {}),
|
|
283
|
+
...(frontmatter.length > 0 ? { frontmatter: mapFrontmatter(frontmatter) } : {}),
|
|
284
|
+
...(exports.length > 0 ? { exports: mapExports(exports) } : {}),
|
|
285
|
+
...(census.length > 0 ? { census: mapCensus(census, roots, ignoreCase) } : {}),
|
|
286
|
+
...(refs === undefined ? {} : { refs: mapRefs(refs, roots) }),
|
|
287
|
+
...(anchors.length > 0 ? { anchors: mapAnchors(anchors) } : {}),
|
|
288
|
+
};
|
|
289
|
+
const output = argv.includes('--json') ? `${JSON.stringify(report)}\n` : renderReport(report);
|
|
290
|
+
const out = readOption(argv, '--out');
|
|
291
|
+
if (out === undefined)
|
|
292
|
+
process.stdout.write(output);
|
|
293
|
+
else {
|
|
294
|
+
mkdirSync(dirname(out), { recursive: true });
|
|
295
|
+
writeFileSync(out, output);
|
|
296
|
+
console.log(`map: wrote ${out}`);
|
|
297
|
+
}
|
|
298
|
+
return 0;
|
|
299
|
+
}
|
|
300
|
+
process.exitCode = main(process.argv.slice(2));
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# Unit UNIT_ID — SHORT_SUBJECT
|
|
2
|
+
|
|
3
|
+
Fill every section. Write `none` in an empty one. Replace each `UPPER_SNAKE_CASE` placeholder.
|
|
4
|
+
|
|
5
|
+
## Role and engine
|
|
6
|
+
|
|
7
|
+
ROLE on ENGINE, reached as TRANSPORT. Executor: NATIVE_SUBAGENT | BENCH_ENGINE | BRIDGE_DRIVER.
|
|
8
|
+
|
|
9
|
+
## Objective
|
|
10
|
+
|
|
11
|
+
ONE_OUTCOME.
|
|
12
|
+
|
|
13
|
+
## Context
|
|
14
|
+
|
|
15
|
+
- **Evidence.** COMMANDS_AND_OUTPUT behind every fact.
|
|
16
|
+
- **Law.** `AGENTS.md`; RULE_FILES; SKILL and the references it names; GUIDE_OR_SPEC.
|
|
17
|
+
- **Installed primitives.** ORKESTREL_PACKAGES with the surface each unit reads first. A local helper whose job an installed export does is a defect.
|
|
18
|
+
- **Host.** SHELL, WORKING_PATH, SANDBOX_NETWORK_APPROVAL_LIMITS.
|
|
19
|
+
- **Standing conditions.** DIRTY_FILES, KNOWN_FAILING_COMMANDS, BLOCKED_TOOLS, and who repairs each.
|
|
20
|
+
|
|
21
|
+
## Unknowns
|
|
22
|
+
|
|
23
|
+
UNKNOWN and how the unit reports it.
|
|
24
|
+
|
|
25
|
+
## Scope
|
|
26
|
+
|
|
27
|
+
- **Owned.** FILES, including the tests that pin the behavior, the fixtures derived from a constant, and the materialized copy of a template.
|
|
28
|
+
- **Shared (report-only).** FILES; return an exact patch.
|
|
29
|
+
- **Off-limits.** FILES. Never list `tmp/probes/` here.
|
|
30
|
+
- **Made false by this change.** FILES, derived by running the suite or by a named search bound.
|
|
31
|
+
- **Tools and limits.** ALLOWED_TOOLS; scoped validation only; no tree-wide mutating command.
|
|
32
|
+
|
|
33
|
+
## Execution
|
|
34
|
+
|
|
35
|
+
Perform the assignment yourself and spawn nothing. (Bridge driver: carry this brief unaltered, launch ENGINE through its CLI, and return the journal path and session id with the result.)
|
|
36
|
+
|
|
37
|
+
## Output
|
|
38
|
+
|
|
39
|
+
RETURN_SHAPE through OUTPUT_MECHANISM. No process diary.
|
|
40
|
+
|
|
41
|
+
## Deviation contract
|
|
42
|
+
|
|
43
|
+
Stop and report (expected, found, evidence, done or not done, one hypothesis) on OBJECTIVE_CONFLICT. Settle ANCILLARY_CHOICES yourself and record them.
|
|
44
|
+
|
|
45
|
+
## Acceptance criteria
|
|
46
|
+
|
|
47
|
+
1. CHEAPEST_GATE (regeneration, typecheck, or lint over owned files)
|
|
48
|
+
2. SCOPED_TEST
|
|
49
|
+
3. ARTIFACT_CRITERION
|
|
50
|
+
|
|
51
|
+
**Observations, not criteria.** TIMING_SENSITIVE_OR_TREE_WIDE_GATES the unit reports and the Orchestrator re-runs.
|
|
52
|
+
|
|
53
|
+
## Review evidence
|
|
54
|
+
|
|
55
|
+
The actual diff and `git status --porcelain` for a code change; the capture portfolio for a rendered surface; the proposal, the canon it must satisfy, and its motivation for a process proposal.
|
package/dist/bin/main.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { align, renderTable, strip, stripControls, width } from "@orkestrel/console";
|
|
3
3
|
import { attempt, isArray, isError, isInstance, isRecord, isString, parseJSON } from "@orkestrel/contract";
|
|
4
|
-
import { BIN_ENTRY_PATH, CATALOG_AGENT_PATH, CONFORMANCE_TEST_PATH, Compiler, DEPENDENCY_NAME_PATTERN, ENVIRONMENTS, GLOBAL_SETUP_PATH, GROUPS, GUIDES_TEST_PATH, HOST_PATHS, INTEGRATION_TEST_PATH, JOURNEY_CONFIG_PATH, MAX_MANIFEST_BYTES, MAX_PATH_LENGTH, SERVICE_SETUP_PATH, SHOWCASE_CONFIG_PATH, ScaffoldError, blueprintToConfigArtifacts, blueprintToDevDependencies, blueprintToRootVite, blueprintToScripts, blueprintToTestArtifacts, blueprintToWritableScripts, compareVersions, createBlueprint, extractRangeMajor, extractVersion, isFloorPath, isScaffoldError, manifestToDependencies, manifestToName, nameToGuide, replaceManifestScripts, replacePlanRanges } from "../src/core/index.js";
|
|
4
|
+
import { BIN_ENTRY_PATH, CATALOG_AGENT_PATH, CONFORMANCE_TEST_PATH, Compiler, DEPENDENCY_NAME_PATTERN, ENVIRONMENTS, GLOBAL_SETUP_PATH, GROUPS, GUIDES_TEST_PATH, HOST_PATHS, INTEGRATION_TEST_PATH, JOURNEY_CONFIG_PATH, MAX_MANIFEST_BYTES, MAX_PATH_LENGTH, SERVICE_SETUP_PATH, SHOWCASE_CONFIG_PATH, SKILLS_CONFIG_PATH, ScaffoldError, blueprintToConfigArtifacts, blueprintToDevDependencies, blueprintToRootVite, blueprintToScripts, blueprintToTestArtifacts, blueprintToWritableScripts, compareVersions, createBlueprint, extractRangeMajor, extractVersion, isFloorPath, isScaffoldError, manifestToDependencies, manifestToName, nameToGuide, replaceManifestScripts, replacePlanRanges } from "../src/core/index.js";
|
|
5
5
|
import { MAX_INVENTORY_PATHS, Materializer, Upstream, filesToHost, isExactCaseFile, isPhysicalDirectory, isWorktree, listFiles, readFileText, readHostFloor, readHostManifest, readSnapshot, resolveContainedPath } from "../src/server/index.js";
|
|
6
6
|
import { createMarkdown, flattenText, isTableNode } from "@orkestrel/markdown";
|
|
7
7
|
import { createSession } from "@orkestrel/process/server";
|
|
@@ -502,6 +502,55 @@ function manifestToWritableDependencies(manifest, blueprint) {
|
|
|
502
502
|
};
|
|
503
503
|
}
|
|
504
504
|
/**
|
|
505
|
+
* Reads the manifest scripts a writing verb may write.
|
|
506
|
+
*
|
|
507
|
+
* @param manifest - The target manifest text.
|
|
508
|
+
* @param blueprint - The workspace shape that supplies the planned scripts.
|
|
509
|
+
* @returns The blueprint's writable scripts, followed by the planned `test` chain when the
|
|
510
|
+
* declared chain is a generated predecessor of it.
|
|
511
|
+
*
|
|
512
|
+
* @remarks
|
|
513
|
+
* A declared `test` chain is a generated predecessor when it runs fewer `&&` steps than the
|
|
514
|
+
* planned chain and every step it runs is a planned step, in the planned order. That is the chain
|
|
515
|
+
* a birth or an earlier write left before a structural fact planned another step, such as a root
|
|
516
|
+
* `tests/setupBrowser.test.ts` proof planning `npm run test:setup:browser`, so the write lands the
|
|
517
|
+
* planned chain in its place. A chain running a step the plan does not generate, or running the
|
|
518
|
+
* planned steps in another order, is one the package owns, and no entry names it.
|
|
519
|
+
*
|
|
520
|
+
* The planned chain joins only when every step it adds runs a script the manifest declares or the
|
|
521
|
+
* writable scripts supply. The `test:src` and `test:app` aggregates sit outside the writable
|
|
522
|
+
* scripts, so a planned chain adding an aggregate the manifest lacks stays with the package rather
|
|
523
|
+
* than landing a step that names a missing script.
|
|
524
|
+
*/
|
|
525
|
+
function manifestToWritableScripts(manifest, blueprint) {
|
|
526
|
+
const writable = blueprintToWritableScripts(blueprint);
|
|
527
|
+
const planned = blueprintToScripts(blueprint).test;
|
|
528
|
+
const parsed = parseJSON(manifest);
|
|
529
|
+
const scripts = isRecord(parsed) && isRecord(parsed.scripts) ? parsed.scripts : {};
|
|
530
|
+
const declared = scripts.test;
|
|
531
|
+
if (planned === void 0 || !isString(declared)) return writable;
|
|
532
|
+
const steps = declared.split("&&").map((step) => step.trim());
|
|
533
|
+
const expected = planned.split("&&").map((step) => step.trim());
|
|
534
|
+
if (steps.length >= expected.length) return writable;
|
|
535
|
+
let cursor = 0;
|
|
536
|
+
for (const step of steps) {
|
|
537
|
+
while (cursor < expected.length && expected[cursor] !== step) cursor += 1;
|
|
538
|
+
if (cursor === expected.length) return writable;
|
|
539
|
+
cursor += 1;
|
|
540
|
+
}
|
|
541
|
+
const supplied = new Set(writable.map(({ name }) => name));
|
|
542
|
+
for (const step of expected) {
|
|
543
|
+
if (steps.includes(step)) continue;
|
|
544
|
+
const name = /^npm run (\S+)$/.exec(step)?.[1];
|
|
545
|
+
if (name === void 0 || !supplied.has(name) && !isString(scripts[name])) return writable;
|
|
546
|
+
}
|
|
547
|
+
return [...writable, {
|
|
548
|
+
name: "test",
|
|
549
|
+
command: planned,
|
|
550
|
+
accepted: [declared]
|
|
551
|
+
}];
|
|
552
|
+
}
|
|
553
|
+
/**
|
|
505
554
|
* Keeps only dependencies published by the Orkestrel fleet.
|
|
506
555
|
*
|
|
507
556
|
* @param dependencies - The declared dependencies to inspect.
|
|
@@ -1447,7 +1496,7 @@ var CLI = class {
|
|
|
1447
1496
|
if (refusal !== void 0) throw refusal;
|
|
1448
1497
|
const result = mergeResults(host.materializer.repair(plan, audit, target), host.materializer.declare({
|
|
1449
1498
|
pins: versions.pins,
|
|
1450
|
-
scripts:
|
|
1499
|
+
scripts: manifestToWritableScripts(this.#manifest(target), blueprint)
|
|
1451
1500
|
}, target));
|
|
1452
1501
|
const terminalBlueprint = this.#derive(target);
|
|
1453
1502
|
const [measured] = this.#survey(host.materializer, terminalBlueprint, target, groups);
|
|
@@ -1549,7 +1598,7 @@ var CLI = class {
|
|
|
1549
1598
|
}
|
|
1550
1599
|
const declared = {
|
|
1551
1600
|
pins: manifestToWritableDependencies(this.#manifest(target), blueprint),
|
|
1552
|
-
scripts:
|
|
1601
|
+
scripts: manifestToWritableScripts(this.#manifest(target), blueprint)
|
|
1553
1602
|
};
|
|
1554
1603
|
const local = mergeResults(host.materializer.repair(plan, audit, target), host.materializer.remove(plan, audit, command.dirty === true ? {
|
|
1555
1604
|
tracked: worktree.tracked,
|
|
@@ -1853,6 +1902,7 @@ var CLI = class {
|
|
|
1853
1902
|
const global = resolveContainedPath(target, GLOBAL_SETUP_PATH);
|
|
1854
1903
|
const showcase = resolveContainedPath(target, SHOWCASE_CONFIG_PATH);
|
|
1855
1904
|
const journey = resolveContainedPath(target, JOURNEY_CONFIG_PATH);
|
|
1905
|
+
const skills = resolveContainedPath(target, SKILLS_CONFIG_PATH);
|
|
1856
1906
|
const setup = /* @__PURE__ */ new Set();
|
|
1857
1907
|
if (tests !== void 0) for (const path of listFiles(tests)) {
|
|
1858
1908
|
if (path.includes("/") || !path.startsWith("setup") || !path.endsWith(".test.ts")) continue;
|
|
@@ -1871,12 +1921,14 @@ var CLI = class {
|
|
|
1871
1921
|
service: service !== void 0 && isExactCaseFile(service),
|
|
1872
1922
|
global: global !== void 0 && isExactCaseFile(global),
|
|
1873
1923
|
showcase: showcase !== void 0 && isExactCaseFile(showcase),
|
|
1874
|
-
journey: journey !== void 0 && isExactCaseFile(journey)
|
|
1924
|
+
journey: journey !== void 0 && isExactCaseFile(journey),
|
|
1925
|
+
skills: skills !== void 0 && isExactCaseFile(skills)
|
|
1875
1926
|
});
|
|
1876
1927
|
}
|
|
1877
1928
|
#projectQuestion(target, blueprint, writing = false) {
|
|
1878
1929
|
const text = this.#manifest(target);
|
|
1879
|
-
const
|
|
1930
|
+
const writable = writing ? manifestToWritableScripts(text, blueprint) : blueprintToWritableScripts(blueprint);
|
|
1931
|
+
const manifest = replaceManifestScripts(text, writable) ?? text;
|
|
1880
1932
|
const planned = blueprintToRootVite(blueprint);
|
|
1881
1933
|
const parsed = parseJSON(manifest);
|
|
1882
1934
|
const scripts = isRecord(parsed) && isRecord(parsed.scripts) ? parsed.scripts : {};
|
|
@@ -1982,7 +2034,7 @@ var CLI = class {
|
|
|
1982
2034
|
const direct = names.map((project) => `test:${project}`);
|
|
1983
2035
|
const declared = direct.filter((script) => isString(written[script]));
|
|
1984
2036
|
const undeclared = direct.filter((script) => !isString(written[script]));
|
|
1985
|
-
const remedies = [declared.length === 0 ? "" : `${declared.join(", ")} ${declared.length === 1 ? "is" : "are"} already declared, so the gate is missing rather than the script: invoke ${declared.length === 1 ? "it" : "each of them"} by name from the ${gateNames} chain.`, undeclared.length === 0 ? "" : `${undeclared.join(", ")} ${undeclared.length === 1 ? "is" : "are"} not declared, so the script is missing as well as the gate: declare ${undeclared.length === 1 ? "it" : "each of them"} and invoke ${undeclared.length === 1 ? "it" : "each of them"} by name from the ${gateNames} chain.`];
|
|
2037
|
+
const remedies = !writing && manifestToWritableScripts(text, blueprint).some(({ name }) => name === "test") ? ["The test chain runs generated steps only, so repair and overwrite write the planned chain and every missing direct script."] : [declared.length === 0 ? "" : `${declared.join(", ")} ${declared.length === 1 ? "is" : "are"} already declared, so the gate is missing rather than the script: invoke ${declared.length === 1 ? "it" : "each of them"} by name from the ${gateNames} chain.`, undeclared.length === 0 ? "" : `${undeclared.join(", ")} ${undeclared.length === 1 ? "is" : "are"} not declared, so the script is missing as well as the gate: declare ${undeclared.length === 1 ? "it" : "each of them"} and invoke ${undeclared.length === 1 ? "it" : "each of them"} by name from the ${gateNames} chain.`];
|
|
1986
2038
|
return {
|
|
1987
2039
|
field: "projects",
|
|
1988
2040
|
message: `${writing ? "The configs group is blocked because " : ""}the manifest at ${target} does not reach ${names.length === 1 ? "a Vitest project" : "Vitest projects"} the planned configuration registers: ${names.join(", ")}. No chain from ${gateNames} invokes ${names.length === 1 ? "it" : "them"}. ${remedies.filter((remedy) => remedy !== "").join(" ")}${writing ? " Exclude configs from --groups to write another group." : ""}`,
|