@orkestrel/scaffold 0.0.67 → 0.0.69
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/bin/main.js +67 -44
- package/dist/bin/main.js.map +1 -1
- package/dist/host/agents/templates/brief.md +9 -0
- package/dist/host/claude/agents/orkestrel.md +4 -4
- package/dist/host/claude/rules/names.md +15 -0
- package/dist/host/claude/rules/tests.md +33 -4
- package/dist/host/claude/rules/workspace.md +14 -2
- package/dist/host/dotfiles/prettierignore +3 -0
- package/dist/host/guides/README.md +65 -0
- package/dist/host/guides/abort.md +169 -0
- package/dist/host/guides/agent.md +1567 -0
- package/dist/host/guides/brief.md +1266 -0
- package/dist/host/guides/browser.md +2200 -0
- package/dist/host/guides/budget.md +196 -0
- package/dist/host/guides/codec.md +519 -0
- package/dist/host/guides/console.md +785 -0
- package/dist/host/guides/contract.md +1193 -0
- package/dist/host/guides/csv.md +541 -0
- package/dist/host/guides/database.md +2518 -0
- package/dist/host/guides/emitter.md +233 -0
- package/dist/host/guides/form.md +1791 -0
- package/dist/host/guides/html.md +717 -0
- package/dist/host/guides/indexeddb.md +505 -0
- package/dist/host/guides/interpret.md +1029 -0
- package/dist/host/guides/lsp.md +515 -0
- package/dist/host/guides/markdown.md +964 -0
- package/dist/host/guides/mcp.md +5554 -0
- package/dist/host/guides/middleware.md +927 -0
- package/dist/host/guides/msg.md +440 -0
- package/dist/host/guides/ndjson.md +120 -0
- package/dist/host/guides/ollama.md +380 -0
- package/dist/host/guides/pool.md +280 -0
- package/dist/host/guides/probe.md +1210 -0
- package/dist/host/guides/process.md +1620 -0
- package/dist/host/guides/program.md +1110 -0
- package/dist/host/guides/qualifier.md +854 -0
- package/dist/host/guides/queue.md +370 -0
- package/dist/host/guides/rater.md +330 -0
- package/dist/host/guides/reason.md +1122 -0
- package/dist/host/guides/relation.md +373 -0
- package/dist/host/guides/router.md +753 -0
- package/dist/host/guides/scaffold.md +192 -31
- package/dist/host/guides/sea.md +383 -0
- package/dist/host/guides/server.md +752 -0
- package/dist/host/guides/sqlite.md +330 -0
- package/dist/host/guides/sse.md +187 -0
- package/dist/host/guides/supervisor.md +4890 -0
- package/dist/host/guides/table.md +1556 -0
- package/dist/host/guides/template.md +280 -0
- package/dist/host/guides/terminal.md +1145 -0
- package/dist/host/guides/test.md +2969 -0
- package/dist/host/guides/timeout.md +252 -0
- package/dist/host/guides/tool.md +507 -0
- package/dist/host/guides/toolbox.md +1038 -0
- package/dist/host/guides/websocket.md +282 -0
- package/dist/host/guides/worker.md +615 -0
- package/dist/host/guides/workflow.md +1507 -0
- package/dist/host/guides/workspace.md +595 -0
- package/dist/host/manifest.json +1218 -10
- package/dist/host/tests/policy.test.ts +279 -2
- package/dist/host/tests/setupPolicy.ts +445 -6
- package/dist/src/core/index.cjs +38 -16
- package/dist/src/core/index.cjs.map +1 -1
- package/dist/src/core/index.d.cts +33 -9
- package/dist/src/core/index.d.ts +33 -9
- package/dist/src/core/index.js +37 -17
- package/dist/src/core/index.js.map +1 -1
- package/dist/src/server/index.cjs +1750 -1567
- package/dist/src/server/index.cjs.map +1 -1
- package/dist/src/server/index.d.cts +106 -24
- package/dist/src/server/index.d.ts +106 -24
- package/dist/src/server/index.js +1751 -1570
- package/dist/src/server/index.js.map +1 -1
- package/package.json +3 -3
|
@@ -1,10 +1,14 @@
|
|
|
1
|
-
import { existsSync, readdirSync, readFileSync } from 'node:fs'
|
|
1
|
+
import { existsSync, readdirSync, readFileSync, rmSync } from 'node:fs'
|
|
2
2
|
import { join } from 'node:path'
|
|
3
3
|
import { describe, expect, it } from 'vitest'
|
|
4
4
|
import { POLICY_BANNED_TERMS, POLICY_JUDGED_TERMS } from '../configs/policy.js'
|
|
5
5
|
import {
|
|
6
6
|
BRIDGE_POLICY_CONTROLS,
|
|
7
7
|
createPolicyScratch,
|
|
8
|
+
createPolicyCatalog,
|
|
9
|
+
createPolicySurfaceFixture,
|
|
10
|
+
createPolicySurfaceGuide,
|
|
11
|
+
writePolicySurfaceHost,
|
|
8
12
|
createSkillMetadata,
|
|
9
13
|
inspectPolicyControl,
|
|
10
14
|
inspectPolicyFilenamePaths,
|
|
@@ -21,6 +25,8 @@ import {
|
|
|
21
25
|
matchesSkillTrigger,
|
|
22
26
|
parseSkillFrontmatter,
|
|
23
27
|
POLICY_CATALOG_FILE,
|
|
28
|
+
POLICY_SURFACE_HOST,
|
|
29
|
+
POLICY_SURFACE_CATALOG,
|
|
24
30
|
POLICY_CONTROLS,
|
|
25
31
|
POLICY_MIRROR_PATTERN,
|
|
26
32
|
POLICY_SUPPRESSION_DIRECTIVE,
|
|
@@ -51,6 +57,276 @@ import {
|
|
|
51
57
|
testToPolicyStem,
|
|
52
58
|
} from './setupPolicy.js'
|
|
53
59
|
|
|
60
|
+
describe('surface policy controls', () => {
|
|
61
|
+
it('accepts a quoted relative barrel target containing a space', () => {
|
|
62
|
+
const scratch = createPolicySurfaceFixture()
|
|
63
|
+
try {
|
|
64
|
+
scratch.write('src/core/index.ts', 'export * from "./shared helpers.js"\n')
|
|
65
|
+
scratch.write('src/core/shared helpers.ts', 'export function readShared() {}\n')
|
|
66
|
+
expect(inspectPolicyWorkspace(scratch.path)).toEqual([
|
|
67
|
+
{
|
|
68
|
+
rule: 'surface',
|
|
69
|
+
path: 'src/core/shared helpers.ts',
|
|
70
|
+
line: 1,
|
|
71
|
+
message: 'surface name belongs to one package: readShared (other)',
|
|
72
|
+
},
|
|
73
|
+
])
|
|
74
|
+
} finally {
|
|
75
|
+
scratch.destroy()
|
|
76
|
+
}
|
|
77
|
+
})
|
|
78
|
+
|
|
79
|
+
it('refuses a target catalog row absent from the installed guides', () => {
|
|
80
|
+
const scratch = createPolicySurfaceFixture()
|
|
81
|
+
try {
|
|
82
|
+
scratch.write(POLICY_CATALOG_FILE, createPolicyCatalog(['other', 'sample', 'uncovered']))
|
|
83
|
+
expect(inspectPolicyWorkspace(scratch.path)).toEqual([
|
|
84
|
+
{
|
|
85
|
+
rule: 'surface',
|
|
86
|
+
path: `${POLICY_SURFACE_HOST}/guides/uncovered.md`,
|
|
87
|
+
message: 'surface evidence missing: catalog package uncovered has no hosted guide',
|
|
88
|
+
},
|
|
89
|
+
])
|
|
90
|
+
} finally {
|
|
91
|
+
scratch.destroy()
|
|
92
|
+
}
|
|
93
|
+
})
|
|
94
|
+
|
|
95
|
+
it('reads a scaffold checkout instead of an installed scaffold copy', () => {
|
|
96
|
+
const scratch = createPolicySurfaceFixture()
|
|
97
|
+
try {
|
|
98
|
+
scratch.write('package.json', '{"name":"@orkestrel/scaffold"}\n')
|
|
99
|
+
scratch.write(POLICY_CATALOG_FILE, createPolicyCatalog(['scaffold', 'other']))
|
|
100
|
+
scratch.write('guides/scaffold.md', createPolicySurfaceGuide([]))
|
|
101
|
+
scratch.write('guides/other.md', createPolicySurfaceGuide(['readCheckout']))
|
|
102
|
+
scratch.write('src/core/index.ts', "export * from './helpers.js'\n")
|
|
103
|
+
scratch.write('src/core/helpers.ts', 'export function readCheckout() {}\n')
|
|
104
|
+
expect(inspectPolicyWorkspace(scratch.path)).toEqual([
|
|
105
|
+
{
|
|
106
|
+
rule: 'surface',
|
|
107
|
+
path: 'src/core/helpers.ts',
|
|
108
|
+
line: 1,
|
|
109
|
+
message: 'surface name belongs to one package: readCheckout (other)',
|
|
110
|
+
},
|
|
111
|
+
])
|
|
112
|
+
} finally {
|
|
113
|
+
scratch.destroy()
|
|
114
|
+
}
|
|
115
|
+
})
|
|
116
|
+
|
|
117
|
+
it('rejects a planted barrel name owned by another hosted guide', () => {
|
|
118
|
+
const scratch = createPolicySurfaceFixture()
|
|
119
|
+
try {
|
|
120
|
+
scratch.write('src/core/index.ts', "export * from './helpers.js'\n")
|
|
121
|
+
scratch.write(
|
|
122
|
+
'src/core/helpers.ts',
|
|
123
|
+
'/** Reads the shared value. */\nexport function readShared() {}\n',
|
|
124
|
+
)
|
|
125
|
+
expect(inspectPolicyWorkspace(scratch.path)).toEqual([
|
|
126
|
+
{
|
|
127
|
+
rule: 'surface',
|
|
128
|
+
path: 'src/core/helpers.ts',
|
|
129
|
+
line: 2,
|
|
130
|
+
message: 'surface name belongs to one package: readShared (other)',
|
|
131
|
+
},
|
|
132
|
+
])
|
|
133
|
+
} finally {
|
|
134
|
+
scratch.destroy()
|
|
135
|
+
}
|
|
136
|
+
})
|
|
137
|
+
|
|
138
|
+
it('rejects a setup export even when its own hosted guide claims it', () => {
|
|
139
|
+
const scratch = createPolicySurfaceFixture()
|
|
140
|
+
try {
|
|
141
|
+
scratch.write(
|
|
142
|
+
`${POLICY_SURFACE_HOST}/guides/sample.md`,
|
|
143
|
+
createPolicySurfaceGuide(['readShared']),
|
|
144
|
+
)
|
|
145
|
+
scratch.write('tests/setupServer.ts', 'export function readShared() {}\n')
|
|
146
|
+
expect(inspectPolicyWorkspace(scratch.path)).toEqual([
|
|
147
|
+
{
|
|
148
|
+
rule: 'surface',
|
|
149
|
+
path: 'tests/setupServer.ts',
|
|
150
|
+
line: 1,
|
|
151
|
+
message: 'surface name belongs to one package: readShared (other)',
|
|
152
|
+
},
|
|
153
|
+
])
|
|
154
|
+
} finally {
|
|
155
|
+
scratch.destroy()
|
|
156
|
+
}
|
|
157
|
+
})
|
|
158
|
+
|
|
159
|
+
it('grandfathers a barrel name only through its own hosted guide', () => {
|
|
160
|
+
const scratch = createPolicySurfaceFixture()
|
|
161
|
+
try {
|
|
162
|
+
scratch.write('guides/sample.md', createPolicySurfaceGuide(['readShared']))
|
|
163
|
+
scratch.write('src/core/index.ts', "export * from './helpers.js'\n")
|
|
164
|
+
scratch.write('src/core/helpers.ts', 'export function readShared() {}\n')
|
|
165
|
+
expect(inspectPolicyWorkspace(scratch.path)).toEqual([
|
|
166
|
+
{
|
|
167
|
+
rule: 'surface',
|
|
168
|
+
path: 'src/core/helpers.ts',
|
|
169
|
+
line: 1,
|
|
170
|
+
message: 'surface name belongs to one package: readShared (other)',
|
|
171
|
+
},
|
|
172
|
+
])
|
|
173
|
+
scratch.write(
|
|
174
|
+
`${POLICY_SURFACE_HOST}/guides/sample.md`,
|
|
175
|
+
createPolicySurfaceGuide(['readShared']),
|
|
176
|
+
)
|
|
177
|
+
expect(inspectPolicyWorkspace(scratch.path)).toEqual([])
|
|
178
|
+
} finally {
|
|
179
|
+
scratch.destroy()
|
|
180
|
+
}
|
|
181
|
+
})
|
|
182
|
+
|
|
183
|
+
it('excludes vendored setup exports while inspecting target setup exports', () => {
|
|
184
|
+
const scratch = createPolicySurfaceFixture()
|
|
185
|
+
try {
|
|
186
|
+
scratch.write('tests/setupPolicy.ts', 'export function readShared() {}\n')
|
|
187
|
+
scratch.write('tests/setupServer.ts', 'export function readShared() {}\n')
|
|
188
|
+
expect(inspectPolicyWorkspace(scratch.path)).toEqual([
|
|
189
|
+
{
|
|
190
|
+
rule: 'surface',
|
|
191
|
+
path: 'tests/setupServer.ts',
|
|
192
|
+
line: 1,
|
|
193
|
+
message: 'surface name belongs to one package: readShared (other)',
|
|
194
|
+
},
|
|
195
|
+
])
|
|
196
|
+
rmSync(join(scratch.path, 'tests/setupServer.ts'), { recursive: true, force: true })
|
|
197
|
+
expect(inspectPolicyWorkspace(scratch.path)).toEqual([])
|
|
198
|
+
} finally {
|
|
199
|
+
scratch.destroy()
|
|
200
|
+
}
|
|
201
|
+
})
|
|
202
|
+
|
|
203
|
+
it('refuses a barrel statement outside the relative star-export population', () => {
|
|
204
|
+
const scratch = createPolicySurfaceFixture()
|
|
205
|
+
try {
|
|
206
|
+
scratch.write(
|
|
207
|
+
'src/core/index.ts',
|
|
208
|
+
"// Incomplete barrel\nexport { readShared } from './helpers.js'\n",
|
|
209
|
+
)
|
|
210
|
+
scratch.write('src/core/helpers.ts', 'export function readShared() {}\n')
|
|
211
|
+
expect(inspectPolicyWorkspace(scratch.path)).toEqual([
|
|
212
|
+
{
|
|
213
|
+
rule: 'surface',
|
|
214
|
+
path: 'src/core/index.ts',
|
|
215
|
+
line: 2,
|
|
216
|
+
message:
|
|
217
|
+
'surface population incomplete: barrel requires a relative .js star export on one line',
|
|
218
|
+
},
|
|
219
|
+
])
|
|
220
|
+
} finally {
|
|
221
|
+
scratch.destroy()
|
|
222
|
+
}
|
|
223
|
+
})
|
|
224
|
+
|
|
225
|
+
it('refuses missing hosted evidence and incomplete checkout guide coverage', () => {
|
|
226
|
+
const scratch = createPolicySurfaceFixture()
|
|
227
|
+
try {
|
|
228
|
+
rmSync(join(scratch.path, POLICY_SURFACE_HOST), { recursive: true, force: true })
|
|
229
|
+
scratch.write(POLICY_CATALOG_FILE, createPolicyCatalog(['other', 'sample']))
|
|
230
|
+
scratch.write('guides/sample.md', createPolicySurfaceGuide([]))
|
|
231
|
+
expect(inspectPolicyWorkspace(scratch.path)).toEqual([
|
|
232
|
+
{
|
|
233
|
+
rule: 'surface',
|
|
234
|
+
path: 'guides/other.md',
|
|
235
|
+
message: 'surface evidence missing: catalog package other has no hosted guide',
|
|
236
|
+
},
|
|
237
|
+
])
|
|
238
|
+
} finally {
|
|
239
|
+
scratch.destroy()
|
|
240
|
+
}
|
|
241
|
+
})
|
|
242
|
+
|
|
243
|
+
it('reads the scaffold checkout guides when no installed host exists', () => {
|
|
244
|
+
const scratch = createPolicySurfaceFixture()
|
|
245
|
+
try {
|
|
246
|
+
rmSync(join(scratch.path, POLICY_SURFACE_HOST), { recursive: true, force: true })
|
|
247
|
+
scratch.write('package.json', '{"name":"@orkestrel/scaffold"}\n')
|
|
248
|
+
scratch.write(POLICY_CATALOG_FILE, createPolicyCatalog(['other', 'scaffold']))
|
|
249
|
+
scratch.write('guides/scaffold.md', createPolicySurfaceGuide([]))
|
|
250
|
+
scratch.write('guides/other.md', createPolicySurfaceGuide(['readShared']))
|
|
251
|
+
scratch.write('src/core/index.ts', "export * from './helpers.js'\n")
|
|
252
|
+
scratch.write('src/core/helpers.ts', 'export function readShared() {}\n')
|
|
253
|
+
expect(inspectPolicyWorkspace(scratch.path)).toEqual([
|
|
254
|
+
{
|
|
255
|
+
rule: 'surface',
|
|
256
|
+
path: 'src/core/helpers.ts',
|
|
257
|
+
line: 1,
|
|
258
|
+
message: 'surface name belongs to one package: readShared (other)',
|
|
259
|
+
},
|
|
260
|
+
])
|
|
261
|
+
scratch.write('guides/scaffold.md', createPolicySurfaceGuide(['readShared']))
|
|
262
|
+
expect(inspectPolicyWorkspace(scratch.path)).toEqual([])
|
|
263
|
+
} finally {
|
|
264
|
+
scratch.destroy()
|
|
265
|
+
}
|
|
266
|
+
})
|
|
267
|
+
|
|
268
|
+
it('orders surface diagnostics by normalized path, line, name, and owner', () => {
|
|
269
|
+
const scratch = createPolicySurfaceFixture()
|
|
270
|
+
try {
|
|
271
|
+
scratch.write(
|
|
272
|
+
`${POLICY_SURFACE_HOST}/${POLICY_SURFACE_CATALOG}`,
|
|
273
|
+
createPolicyCatalog(['zebra', 'other', 'sample']),
|
|
274
|
+
)
|
|
275
|
+
scratch.write(
|
|
276
|
+
`${POLICY_SURFACE_HOST}/guides/zebra.md`,
|
|
277
|
+
createPolicySurfaceGuide(['readShared']),
|
|
278
|
+
)
|
|
279
|
+
scratch.write(
|
|
280
|
+
`${POLICY_SURFACE_HOST}/guides/other.md`,
|
|
281
|
+
createPolicySurfaceGuide(['readLater', 'readShared']),
|
|
282
|
+
)
|
|
283
|
+
scratch.write(
|
|
284
|
+
'tests/setupServer.ts',
|
|
285
|
+
'export function readLater() {}\r\nexport function readShared() {}\r\n',
|
|
286
|
+
)
|
|
287
|
+
scratch.write(
|
|
288
|
+
'src/core/index.ts',
|
|
289
|
+
"export * from './helpers.js'\nexport * from './helpers.js'\n",
|
|
290
|
+
)
|
|
291
|
+
scratch.write('src/core/helpers.ts', 'export function readShared() {}\n')
|
|
292
|
+
expect(inspectPolicyWorkspace(scratch.path)).toEqual([
|
|
293
|
+
{
|
|
294
|
+
rule: 'surface',
|
|
295
|
+
path: 'src/core/helpers.ts',
|
|
296
|
+
line: 1,
|
|
297
|
+
message: 'surface name belongs to one package: readShared (other)',
|
|
298
|
+
},
|
|
299
|
+
{
|
|
300
|
+
rule: 'surface',
|
|
301
|
+
path: 'src/core/helpers.ts',
|
|
302
|
+
line: 1,
|
|
303
|
+
message: 'surface name belongs to one package: readShared (zebra)',
|
|
304
|
+
},
|
|
305
|
+
{
|
|
306
|
+
rule: 'surface',
|
|
307
|
+
path: 'tests/setupServer.ts',
|
|
308
|
+
line: 1,
|
|
309
|
+
message: 'surface name belongs to one package: readLater (other)',
|
|
310
|
+
},
|
|
311
|
+
{
|
|
312
|
+
rule: 'surface',
|
|
313
|
+
path: 'tests/setupServer.ts',
|
|
314
|
+
line: 2,
|
|
315
|
+
message: 'surface name belongs to one package: readShared (other)',
|
|
316
|
+
},
|
|
317
|
+
{
|
|
318
|
+
rule: 'surface',
|
|
319
|
+
path: 'tests/setupServer.ts',
|
|
320
|
+
line: 2,
|
|
321
|
+
message: 'surface name belongs to one package: readShared (zebra)',
|
|
322
|
+
},
|
|
323
|
+
])
|
|
324
|
+
} finally {
|
|
325
|
+
scratch.destroy()
|
|
326
|
+
}
|
|
327
|
+
})
|
|
328
|
+
})
|
|
329
|
+
|
|
54
330
|
describe('policy scratch', () => {
|
|
55
331
|
it('contains every write within its root', () => {
|
|
56
332
|
const scratch = createPolicyScratch({ prefix: 'orkestrel-policy-containment-' })
|
|
@@ -468,7 +744,7 @@ describe('denylist currency', () => {
|
|
|
468
744
|
})
|
|
469
745
|
|
|
470
746
|
describe('repository policy', () => {
|
|
471
|
-
it('enforces the
|
|
747
|
+
it('enforces the workspace policy laws including surface ownership', () => {
|
|
472
748
|
expect(inspectPolicyWorkspace(process.cwd())).toEqual([])
|
|
473
749
|
})
|
|
474
750
|
|
|
@@ -479,6 +755,7 @@ describe('repository policy', () => {
|
|
|
479
755
|
it('accepts a target holding the pointer pair and no canon tree', () => {
|
|
480
756
|
const scratch = createPolicyScratch({ prefix: 'orkestrel-policy-pointer-' })
|
|
481
757
|
try {
|
|
758
|
+
writePolicySurfaceHost(scratch)
|
|
482
759
|
scratch.write(
|
|
483
760
|
'AGENTS.md',
|
|
484
761
|
'# AGENTS.md\n\nRead `node_modules/@orkestrel/scaffold/dist/host/AGENTS.md` for the canon.\n',
|