@erclx/canon 5.27.0 → 5.28.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/claude/.claude-plugin/plugin.json +1 -1
- package/claude/skills/draft-ready/SKILL.md +3 -1
- package/claude/skills/git-pr/references/evidence.md +1 -1
- package/claude/skills/review-address/REQUIREMENT.md +4 -2
- package/claude/skills/review-address/SKILL.md +16 -7
- package/claude/skills/review-address/references/rebase-conflicts.md +4 -2
- package/claude/skills/review-craft/references/ui.md +4 -4
- package/claude/skills/review-ui/REQUIREMENT.md +2 -2
- package/claude/skills/review-ui/SKILL.md +13 -11
- package/claude/skills/review-ui/references/driving.md +8 -8
- package/claude/skills/review-ui/references/post.md +13 -3
- package/claude/skills/review-ui/references/tick.md +22 -0
- package/claude/skills/role-orchestrator/REQUIREMENT.md +15 -15
- package/claude/skills/role-orchestrator/SKILL.md +24 -26
- package/claude/skills/role-orchestrator/references/orchestrator-dispatch.md +18 -16
- package/claude/skills/role-orchestrator/references/orchestrator-handback.md +12 -2
- package/claude/skills/role-orchestrator/references/orchestrator-inbound.md +1 -1
- package/claude/skills/role-orchestrator/references/orchestrator-launch.md +1 -1
- package/claude/skills/role-orchestrator/references/orchestrator-output.md +4 -4
- package/claude/skills/role-orchestrator/references/orchestrator-parked.md +5 -5
- package/claude/skills/role-orchestrator/references/orchestrator-poll.md +11 -2
- package/claude/skills/role-orchestrator/references/orchestrator-refill.md +6 -6
- package/claude/skills/role-orchestrator/references/orchestrator-sweep.md +2 -2
- package/claude/skills/role-orchestrator/scripts/poll.ts +304 -10
- package/claude/skills/role-planner/REQUIREMENT.md +1 -1
- package/claude/skills/role-planner/SKILL.md +2 -2
- package/claude/skills/role-reviewer/SKILL.md +1 -1
- package/claude/skills/role-worker/SKILL.md +3 -2
- package/claude/skills/ui-checklist/SKILL.md +1 -1
- package/docs/agents/canvas.md +4 -4
- package/docs/agents/gate.md +3 -1
- package/docs/agents/index.md +2 -1
- package/docs/agents/pr-evidence.md +9 -8
- package/docs/agents/pr-tick.md +72 -0
- package/docs/agents/sandbox.md +2 -2
- package/docs/agents/tasks-plans.md +1 -1
- package/docs/agents/tasks-validate.md +18 -18
- package/docs/agents/tasks.md +1 -1
- package/docs/workflow/operating-model.md +10 -15
- package/docs/workflow/parallel-features.md +7 -7
- package/package.json +1 -1
- package/src/audits/baseline.ts +1 -1
- package/src/audits/run.ts +1 -1
- package/src/canvas/capture.ts +1 -1
- package/src/canvas/client/inspector/field.tsx +61 -2
- package/src/canvas/client/inspector/fields.css +78 -0
- package/src/canvas/client/inspector/token-select.tsx +109 -0
- package/src/canvas/client/inspector/values.ts +74 -2
- package/src/canvas/client/inspector.tsx +121 -11
- package/src/canvas/client/keys.ts +54 -0
- package/src/canvas/client/selection.tsx +3 -1
- package/src/canvas/client/shell.css +108 -2
- package/src/canvas/client/state.ts +96 -5
- package/src/canvas/client/surface.tsx +194 -17
- package/src/canvas/client/tools.tsx +64 -0
- package/src/canvas/content.ts +1 -1
- package/src/canvas/edit.ts +12 -2
- package/src/canvas/tokens.ts +1 -1
- package/src/claude/seeds.ts +2 -2
- package/src/claude/skills-reach.ts +1 -1
- package/src/commands/canvas.ts +1 -1
- package/src/commands/claude.ts +3 -3
- package/src/commands/design.ts +3 -3
- package/src/commands/docs.ts +1 -1
- package/src/commands/feedback.ts +2 -2
- package/src/commands/gate.ts +9 -2
- package/src/commands/gov.ts +2 -2
- package/src/commands/init.ts +1 -1
- package/src/commands/migrate.ts +1 -1
- package/src/commands/pr.ts +183 -7
- package/src/commands/sandbox.ts +10 -13
- package/src/commands/slides.ts +1 -1
- package/src/commands/sync.ts +1 -1
- package/src/commands/tasks.ts +19 -2
- package/src/commands/tooling.ts +1 -1
- package/src/commands/transcripts.ts +1 -1
- package/src/commands/upgrade.ts +1 -1
- package/src/commands/wiki.ts +1 -1
- package/src/context/architecture.ts +1 -1
- package/src/context/citations.ts +2 -2
- package/src/context/classify/extract.ts +1 -1
- package/src/context/folders.ts +2 -2
- package/src/context/requirements.ts +1 -1
- package/src/docs/read.ts +1 -1
- package/src/exec.ts +1 -1
- package/src/feedback/github.ts +1 -1
- package/src/gate/measures.ts +1 -1
- package/src/gate/sequencer.ts +55 -3
- package/src/gate/stages.ts +8 -0
- package/src/gate/suite-lock.ts +214 -0
- package/src/intake/folder.ts +1 -1
- package/src/labels/map.ts +1 -1
- package/src/labels/phase.ts +3 -3
- package/src/migrate/record-layout.ts +1 -1
- package/src/migrate/records.ts +11 -11
- package/src/migrate/scratch-evidence.ts +1 -1
- package/src/migrate/surface-roots.ts +6 -6
- package/src/pr/evidence.ts +154 -16
- package/src/pr/tick.ts +56 -0
- package/src/process/harness.ts +1 -1
- package/src/records/backup.ts +1 -1
- package/src/records/ordinal.ts +1 -1
- package/src/records/prune.ts +1 -1
- package/src/records/size.ts +1 -1
- package/src/records/stale-canonical.ts +1 -1
- package/src/records/stale.ts +1 -1
- package/src/records/validate.ts +2 -2
- package/src/{project-root.ts → roots/project.ts} +1 -1
- package/src/{record-root.ts → roots/record.ts} +1 -1
- package/src/sandbox/coverage.ts +11 -12
- package/src/sandbox/equivalence.ts +57 -26
- package/src/sandbox/hooks.ts +1 -1
- package/src/sandbox/provision.ts +78 -28
- package/src/sandbox/scenario.ts +588 -0
- package/src/sessions/live.ts +4 -1
- package/src/sessions/transfer/bundle.ts +1 -1
- package/src/slides/decks.ts +1 -1
- package/src/standards/read.ts +1 -1
- package/src/sync/engine.ts +1 -1
- package/src/sync/layout.ts +2 -2
- package/src/sync/stamp.ts +1 -1
- package/src/targets/validate.ts +1 -1
- package/src/tasks/answers.ts +1 -1
- package/src/tasks/archive.ts +1 -1
- package/src/tasks/label.ts +1 -1
- package/src/tasks/reach.ts +1 -1
- package/src/tasks/validate.ts +38 -14
- package/src/teach/nav.ts +1 -1
- package/src/teach/workspace.ts +1 -1
- package/src/tooling/inject.ts +1 -1
- package/src/tooling/read.ts +1 -1
- package/src/tooling/scan.ts +1 -1
- package/src/version/installed.ts +1 -1
- package/src/version/skew.ts +1 -1
- package/standards/board.md +3 -3
- package/standards/plan.md +13 -7
- package/tsconfig.json +1 -1
- /package/src/{legacy-path.ts → roots/legacy.ts} +0 -0
- /package/src/{surface-root.ts → roots/surface.ts} +0 -0
package/src/sandbox/provision.ts
CHANGED
|
@@ -4,13 +4,21 @@ import {
|
|
|
4
4
|
copyFileSync,
|
|
5
5
|
existsSync,
|
|
6
6
|
mkdirSync,
|
|
7
|
-
readdirSync,
|
|
8
7
|
rmSync,
|
|
9
|
-
statSync,
|
|
10
8
|
writeFileSync,
|
|
11
9
|
} from 'node:fs'
|
|
12
10
|
import { basename, dirname, join, relative } from 'node:path'
|
|
13
11
|
import { probeScenario, stageScenario } from '@/sandbox/hooks'
|
|
12
|
+
import {
|
|
13
|
+
FIXTURE_SUFFIX,
|
|
14
|
+
FIXTURES_DIR,
|
|
15
|
+
listFixtureFiles,
|
|
16
|
+
loadScenario,
|
|
17
|
+
resolveScenarioFile,
|
|
18
|
+
type ScenarioDefinition,
|
|
19
|
+
scenarioExports,
|
|
20
|
+
stageScenarioInProcess,
|
|
21
|
+
} from '@/sandbox/scenario'
|
|
14
22
|
import { assertSandboxDirSafe, sandboxRoots, sandboxTree } from '@/sandbox/tree'
|
|
15
23
|
import {
|
|
16
24
|
intro,
|
|
@@ -26,16 +34,16 @@ import {
|
|
|
26
34
|
|
|
27
35
|
/**
|
|
28
36
|
* Provisions one scenario into the sandbox tree, and resets or cleans that tree.
|
|
29
|
-
*
|
|
30
|
-
*
|
|
37
|
+
* A bash scenario's hooks run through `sandbox-hook.sh` and a TypeScript one's
|
|
38
|
+
* arm runs in process through `scenario.ts`, and everything between them runs
|
|
39
|
+
* here, in the order the retired bash dispatcher held.
|
|
31
40
|
*
|
|
32
41
|
* Narration is part of the contract. `canon sandbox equivalence` compares the
|
|
33
42
|
* log line for line against the bash harness, so every message, its frame
|
|
34
43
|
* glyph, and its position in the order stays as that harness wrote it.
|
|
35
44
|
*/
|
|
36
45
|
|
|
37
|
-
const ANCHOR_FIXTURE_PARTS = ['sandbox',
|
|
38
|
-
const FIXTURE_SUFFIX = '.fixture'
|
|
46
|
+
const ANCHOR_FIXTURE_PARTS = ['sandbox', FIXTURES_DIR, 'anchor', 'create']
|
|
39
47
|
const SKILL_PATHSPEC = 'claude/skills/**/SKILL.md'
|
|
40
48
|
|
|
41
49
|
/**
|
|
@@ -98,15 +106,6 @@ function finish(message: string): void {
|
|
|
98
106
|
process.stderr.write(`\n${GREEN}${message}${NC}\n`)
|
|
99
107
|
}
|
|
100
108
|
|
|
101
|
-
function listFixtureFiles(dir: string): string[] {
|
|
102
|
-
if (!existsSync(dir)) return []
|
|
103
|
-
|
|
104
|
-
return (readdirSync(dir, { recursive: true, encoding: 'utf8' }) as string[])
|
|
105
|
-
.map((path) => join(dir, path))
|
|
106
|
-
.filter((path) => statSync(path).isFile())
|
|
107
|
-
.sort()
|
|
108
|
-
}
|
|
109
|
-
|
|
110
109
|
function stageAnchorTree(
|
|
111
110
|
root: string,
|
|
112
111
|
sandbox: string,
|
|
@@ -402,12 +401,57 @@ interface Scenario {
|
|
|
402
401
|
readonly arm: string | undefined
|
|
403
402
|
}
|
|
404
403
|
|
|
405
|
-
|
|
404
|
+
/**
|
|
405
|
+
* Reads what a scenario declares ahead of provisioning: its config exports and
|
|
406
|
+
* whether it stages from the anchor. A bash scenario answers through the probe,
|
|
407
|
+
* and a TypeScript one from its module, which is also what its stage runs.
|
|
408
|
+
*/
|
|
409
|
+
function declareScenario(
|
|
410
|
+
root: string,
|
|
411
|
+
scenario: Scenario,
|
|
412
|
+
env: NodeJS.ProcessEnv,
|
|
413
|
+
):
|
|
414
|
+
| { kind: 'sh'; file: string; isAnchor: boolean }
|
|
415
|
+
| { kind: 'ts'; definition: ScenarioDefinition; isAnchor: boolean } {
|
|
416
|
+
const name = `${scenario.category}/${scenario.command}`
|
|
417
|
+
const resolved = resolveScenarioFile(
|
|
418
|
+
join(root, 'sandbox'),
|
|
419
|
+
scenario.category,
|
|
420
|
+
scenario.command,
|
|
421
|
+
)
|
|
422
|
+
if (!resolved.ok && resolved.reason === 'ambiguous')
|
|
423
|
+
fail(
|
|
424
|
+
`Sandbox script ${name} exists as both .sh and .ts. Delete the one the port replaced.`,
|
|
425
|
+
)
|
|
426
|
+
if (!resolved.ok) fail(`Sandbox script not found: ${name}`)
|
|
427
|
+
|
|
428
|
+
if (resolved.kind === 'sh') {
|
|
429
|
+
const probe = probeScenario(resolved.file, env)
|
|
430
|
+
if (!probe.ok) throw new Halt(probe.status)
|
|
431
|
+
Object.assign(env, probe.exports)
|
|
432
|
+
|
|
433
|
+
return { kind: 'sh', file: resolved.file, isAnchor: probe.isAnchor }
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
let definition: ScenarioDefinition
|
|
437
|
+
try {
|
|
438
|
+
definition = loadScenario(resolved.file)
|
|
439
|
+
} catch (error) {
|
|
440
|
+
fail(
|
|
441
|
+
`Could not load scenario ${name}: ${error instanceof Error ? error.message : String(error)}`,
|
|
442
|
+
)
|
|
443
|
+
}
|
|
444
|
+
Object.assign(env, scenarioExports(definition, root, env))
|
|
445
|
+
|
|
446
|
+
return { kind: 'ts', definition, isAnchor: definition.anchor === true }
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
async function provisionScenario(
|
|
406
450
|
root: string,
|
|
407
451
|
sandbox: string,
|
|
408
452
|
scenario: Scenario,
|
|
409
453
|
baseEnv: NodeJS.ProcessEnv,
|
|
410
|
-
): void {
|
|
454
|
+
): Promise<void> {
|
|
411
455
|
const env: NodeJS.ProcessEnv = { ...baseEnv }
|
|
412
456
|
if (scenario.arm !== undefined) {
|
|
413
457
|
env.SANDBOX_SCENARIO = scenario.arm
|
|
@@ -415,13 +459,7 @@ function provisionScenario(
|
|
|
415
459
|
}
|
|
416
460
|
|
|
417
461
|
const sandboxDir = join(root, 'sandbox')
|
|
418
|
-
const
|
|
419
|
-
if (!existsSync(file) || !statSync(file).isFile())
|
|
420
|
-
fail(`Sandbox script not found: ${scenario.category}/${scenario.command}`)
|
|
421
|
-
|
|
422
|
-
const probe = probeScenario(file, env)
|
|
423
|
-
if (!probe.ok) throw new Halt(probe.status)
|
|
424
|
-
Object.assign(env, probe.exports)
|
|
462
|
+
const declared = declareScenario(root, scenario, env)
|
|
425
463
|
|
|
426
464
|
if (!existsSync(sandboxDir))
|
|
427
465
|
fail(`Sandbox directory not found at: ${sandboxDir}`)
|
|
@@ -435,14 +473,26 @@ function provisionScenario(
|
|
|
435
473
|
}
|
|
436
474
|
|
|
437
475
|
logStep(`Provisioning ${scenario.category}:${scenario.command}`)
|
|
438
|
-
if (
|
|
476
|
+
if (declared.isAnchor) stageAnchorTree(root, sandbox, env)
|
|
439
477
|
else initEmptyTree(sandbox, env)
|
|
440
478
|
configureCredentials(sandbox, env)
|
|
441
479
|
setupAssets(root, sandbox, env)
|
|
442
480
|
|
|
443
481
|
// A scenario that execs a verb as its last step hands the run to that verb,
|
|
444
|
-
// whose own frame is the last one written, so nothing follows it here.
|
|
445
|
-
|
|
482
|
+
// whose own frame is the last one written, so nothing follows it here. An
|
|
483
|
+
// in-process arm writes its exports straight into `env`.
|
|
484
|
+
const staged =
|
|
485
|
+
declared.kind === 'sh'
|
|
486
|
+
? stageScenario(declared.file, env)
|
|
487
|
+
: {
|
|
488
|
+
...(await stageScenarioInProcess(declared.definition, {
|
|
489
|
+
root,
|
|
490
|
+
dir: sandbox,
|
|
491
|
+
env,
|
|
492
|
+
arm: scenario.arm,
|
|
493
|
+
})),
|
|
494
|
+
exports: {},
|
|
495
|
+
}
|
|
446
496
|
if (staged.ending === 'replaced') throw new Halt(staged.status, false)
|
|
447
497
|
if (staged.ending === 'exited') throw new Halt(staged.status)
|
|
448
498
|
Object.assign(env, staged.exports)
|
|
@@ -590,7 +640,7 @@ export async function runSandbox(
|
|
|
590
640
|
}
|
|
591
641
|
|
|
592
642
|
const { category, command } = parseTarget(request.target)
|
|
593
|
-
provisionScenario(
|
|
643
|
+
await provisionScenario(
|
|
594
644
|
root,
|
|
595
645
|
sandbox,
|
|
596
646
|
{ category, command, arm: request.arm },
|