pi-crew 0.9.55 → 0.9.57
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/AGENTS.md +1 -1
- package/CHANGELOG.md +58 -0
- package/README.md +53 -5
- package/dist/index.mjs +5666 -4370
- package/docs/README.md +54 -0
- package/package.json +12 -13
- package/skills/real-test-pi-crew/SKILL.md +93 -3
- package/src/agents/discover-agents.ts +68 -10
- package/src/benchmark/feedback-loop.ts +1 -1
- package/src/config/config.ts +2 -1
- package/src/config/types.ts +12 -0
- package/src/extension/action-suggestions.ts +16 -63
- package/src/extension/async-notifier.ts +3 -3
- package/src/extension/command-completions.ts +2 -2
- package/src/extension/crew-cleanup.ts +3 -3
- package/src/extension/crew-vibes/footer.ts +4 -2
- package/src/extension/cross-extension-rpc.ts +10 -5
- package/src/extension/knowledge-injection.ts +57 -10
- package/src/extension/register.ts +2 -2
- package/src/extension/registration/artifact-cleanup.ts +41 -3
- package/src/extension/registration/commands.ts +4 -4
- package/src/extension/registration/context-builder.ts +10 -10
- package/src/extension/registration/crash-recovery-cache.ts +3 -3
- package/src/extension/registration/foreground-run-controller.ts +1 -1
- package/src/extension/registration/lazy-configurers.ts +2 -2
- package/src/extension/registration/lifecycle-handlers.ts +12 -12
- package/src/extension/registration/lifecycle.ts +2 -2
- package/src/extension/registration/observability.ts +2 -2
- package/src/extension/registration/registration-types.ts +3 -3
- package/src/extension/registration/runtime-cleanup.ts +1 -1
- package/src/extension/registration/subagent-helpers.ts +2 -2
- package/src/extension/registration/subagent-manager-setup.ts +2 -2
- package/src/extension/registration/subagent-tools.ts +21 -16
- package/src/extension/registration/team-tool.ts +109 -17
- package/src/extension/registration/viewers.ts +3 -4
- package/src/extension/registration/wire-cross-extension.ts +7 -7
- package/src/extension/rpc-hmac.ts +3 -2
- package/src/extension/run-bundle-schema.ts +13 -4
- package/src/extension/run-export.ts +2 -2
- package/src/extension/run-index.ts +2 -3
- package/src/extension/run-maintenance.ts +57 -1
- package/src/extension/team-manager-command.ts +3 -1
- package/src/extension/team-tool/anchor.ts +8 -2
- package/src/extension/team-tool/api.ts +117 -39
- package/src/extension/team-tool/cancel.ts +23 -8
- package/src/extension/team-tool/chain-executor.ts +1 -1
- package/src/extension/team-tool/dispatch/automate.ts +17 -2
- package/src/extension/team-tool/dispatch/control.ts +17 -2
- package/src/extension/team-tool/dispatch/manage.ts +34 -2
- package/src/extension/team-tool/dispatch/run.ts +17 -2
- package/src/extension/team-tool/dispatch/status.ts +37 -5
- package/src/extension/team-tool/doctor.ts +2 -2
- package/src/extension/team-tool/explain.ts +1 -1
- package/src/extension/team-tool/goal-wrap.ts +5 -5
- package/src/extension/team-tool/goal.ts +30 -9
- package/src/extension/team-tool/handle-schedule.ts +37 -19
- package/src/extension/team-tool/inspect.ts +21 -5
- package/src/extension/team-tool/lifecycle-actions.ts +53 -10
- package/src/extension/team-tool/parallel-dispatch.ts +14 -5
- package/src/extension/team-tool/param-error.ts +138 -0
- package/src/extension/team-tool/respond.ts +20 -6
- package/src/extension/team-tool/run.ts +27 -17
- package/src/extension/team-tool/status.ts +17 -6
- package/src/extension/team-tool.ts +26 -19
- package/src/hooks/registry.ts +1 -1
- package/src/i18n.ts +22 -0
- package/src/observability/event-bus.ts +1 -1
- package/src/prompt/prompt-runtime.ts +2 -2
- package/src/runtime/README.md +35 -0
- package/src/runtime/agent-control.ts +1 -1
- package/src/runtime/anchor-manager.ts +0 -2
- package/src/runtime/async-runner.ts +1 -1
- package/src/runtime/attention-events.ts +3 -2
- package/src/runtime/auto-summarize.ts +0 -2
- package/src/runtime/background-runner.ts +103 -30
- package/src/runtime/{crew-broker-child.ts → broker/crew-broker-child.ts} +2 -2
- package/src/runtime/{crew-broker-client.ts → broker/crew-broker-client.ts} +4 -7
- package/src/runtime/{crew-broker.ts → broker/crew-broker.ts} +13 -21
- package/src/runtime/chain-runner.ts +50 -5
- package/src/runtime/{child-pi-constants.ts → child-pi/child-pi-constants.ts} +1 -1
- package/src/runtime/{child-pi-kill.ts → child-pi/child-pi-kill.ts} +3 -3
- package/src/runtime/{child-pi-spawn.ts → child-pi/child-pi-spawn.ts} +28 -12
- package/src/runtime/{child-pi-steering.ts → child-pi/child-pi-steering.ts} +1 -1
- package/src/runtime/{child-pi-streams.ts → child-pi/child-pi-streams.ts} +23 -4
- package/src/runtime/{child-pi-transcript.ts → child-pi/child-pi-transcript.ts} +6 -6
- package/src/runtime/{child-pi.ts → child-pi/child-pi.ts} +47 -78
- package/src/runtime/compaction/compact-stages/bounded-tail.ts +84 -0
- package/src/runtime/{compact-stages → compaction/compact-stages}/index.ts +2 -2
- package/src/runtime/{compaction-summary.ts → compaction/compaction-summary.ts} +3 -3
- package/src/runtime/{tool-output-pruner.ts → compaction/tool-output-pruner.ts} +1 -1
- package/src/runtime/crew-agent-records.ts +48 -2
- package/src/runtime/custom-tools/irc-tool.ts +2 -2
- package/src/runtime/delivery-coordinator.ts +0 -3
- package/src/runtime/diagnostic-export.ts +5 -4
- package/src/runtime/foreground-control.ts +1 -1
- package/src/runtime/foreground-watchdog.ts +1 -1
- package/src/runtime/{adaptive-plan.ts → goal-workflow/adaptive-plan.ts} +8 -8
- package/src/runtime/{dynamic-workflow-context.ts → goal-workflow/dynamic-workflow-context.ts} +16 -16
- package/src/runtime/{dynamic-workflow-runner.ts → goal-workflow/dynamic-workflow-runner.ts} +10 -10
- package/src/runtime/{goal-achievement.ts → goal-workflow/goal-achievement.ts} +3 -3
- package/src/runtime/{goal-evaluator.ts → goal-workflow/goal-evaluator.ts} +8 -8
- package/src/runtime/{goal-loop-runner.ts → goal-workflow/goal-loop-runner.ts} +27 -25
- package/src/runtime/{goal-state-store.ts → goal-workflow/goal-state-store.ts} +8 -8
- package/src/runtime/{plan-templates.ts → goal-workflow/plan-templates.ts} +1 -1
- package/src/runtime/group-join.ts +3 -3
- package/src/runtime/handoff-manager.ts +0 -2
- package/src/runtime/{heartbeat-watcher.ts → heartbeat/heartbeat-watcher.ts} +7 -7
- package/src/runtime/iteration-hooks.ts +1 -1
- package/src/runtime/{live-agent-control.ts → live-session/live-agent-control.ts} +2 -2
- package/src/runtime/{live-agent-manager.ts → live-session/live-agent-manager.ts} +4 -4
- package/src/runtime/{live-session-runtime.ts → live-session/live-session-runtime.ts} +39 -41
- package/src/runtime/manifest-cache.ts +6 -2
- package/src/runtime/{model-fallback.ts → model/model-fallback.ts} +1 -1
- package/src/runtime/{pi-args.ts → model/pi-args.ts} +20 -5
- package/src/runtime/model/provider-extensions.ts +116 -0
- package/src/runtime/{runtime-policy.ts → model/runtime-policy.ts} +2 -2
- package/src/runtime/{runtime-resolver.ts → model/runtime-resolver.ts} +3 -3
- package/src/runtime/{runtime-warmup.ts → model/runtime-warmup.ts} +8 -8
- package/src/runtime/orphan-worker-registry.ts +1 -1
- package/src/runtime/{progress-tracker.ts → output/progress-tracker.ts} +1 -1
- package/src/runtime/{result-extractor.ts → output/result-extractor.ts} +4 -4
- package/src/runtime/{sidechain-output.ts → output/sidechain-output.ts} +2 -2
- package/src/runtime/{stream-preview.ts → output/stream-preview.ts} +1 -1
- package/src/runtime/{streaming-output.ts → output/streaming-output.ts} +2 -2
- package/src/runtime/{tool-progress.ts → output/tool-progress.ts} +1 -1
- package/src/runtime/parent-guard.ts +30 -10
- package/src/runtime/pipeline-runner.ts +2 -2
- package/src/runtime/policy-engine.ts +2 -2
- package/src/runtime/{cancellation.ts → process/cancellation.ts} +1 -1
- package/src/runtime/{post-exit-stdio-guard.ts → process/post-exit-stdio-guard.ts} +1 -1
- package/src/runtime/{process-lifecycle.ts → process/process-lifecycle.ts} +3 -3
- package/src/runtime/{checkpoint.ts → recovery/checkpoint.ts} +4 -4
- package/src/runtime/{crash-recovery.ts → recovery/crash-recovery.ts} +93 -21
- package/src/runtime/{overflow-recovery.ts → recovery/overflow-recovery.ts} +1 -1
- package/src/runtime/{recovery-recipes.ts → recovery/recovery-recipes.ts} +1 -1
- package/src/runtime/{retry-executor.ts → recovery/retry-executor.ts} +2 -2
- package/src/runtime/{retry-runner.ts → recovery/retry-runner.ts} +2 -8
- package/src/runtime/run-tracker.ts +1 -1
- package/src/runtime/run-worker.ts +3 -3
- package/src/runtime/{coalesce-tasks.ts → scheduling/coalesce-tasks.ts} +3 -3
- package/src/runtime/{concurrency.ts → scheduling/concurrency.ts} +9 -3
- package/src/runtime/{parallel-research.ts → scheduling/parallel-research.ts} +4 -2
- package/src/runtime/{run-coalesced-task-group.ts → scheduling/run-coalesced-task-group.ts} +95 -36
- package/src/runtime/{semaphore.ts → scheduling/semaphore.ts} +4 -1
- package/src/runtime/{task-graph-scheduler.ts → scheduling/task-graph-scheduler.ts} +1 -1
- package/src/runtime/session-resources.ts +1 -1
- package/src/runtime/settings-store.ts +1 -1
- package/src/runtime/single-agent-compose.ts +1 -0
- package/src/runtime/stale-reconciler.ts +1 -1
- package/src/runtime/subagent-manager.ts +1 -1
- package/src/runtime/supervisor-contact.ts +28 -13
- package/src/runtime/task-output-context.ts +7 -5
- package/src/runtime/task-runner/child-executor.ts +67 -31
- package/src/runtime/task-runner/live-executor.ts +8 -8
- package/src/runtime/task-runner/post-execution.ts +12 -12
- package/src/runtime/task-runner/pre-execution.ts +6 -6
- package/src/runtime/task-runner/progress.ts +1 -1
- package/src/runtime/task-runner/run-projection.ts +1 -1
- package/src/runtime/task-runner/scaffold-executor.ts +1 -1
- package/src/runtime/task-runner/state-helpers.ts +2 -2
- package/src/runtime/task-runner.ts +4 -4
- package/src/runtime/team-runner.ts +441 -175
- package/src/runtime/{completion-guard.ts → verification/completion-guard.ts} +1 -1
- package/src/runtime/{green-contract.ts → verification/green-contract.ts} +1 -1
- package/src/runtime/{post-checks.ts → verification/post-checks.ts} +4 -4
- package/src/runtime/{verification-gates.ts → verification/verification-gates.ts} +5 -5
- package/src/runtime/{verification-integrity.ts → verification/verification-integrity.ts} +1 -1
- package/src/schema/config-schema.ts +1 -0
- package/src/schema/team-tool-schema.ts +149 -185
- package/src/state/README.md +44 -0
- package/src/state/atomic-write.ts +24 -3
- package/src/state/{locks.ts → coordination/locks.ts} +118 -38
- package/src/state/{mailbox.ts → coordination/mailbox.ts} +14 -8
- package/src/state/{schedule.ts → coordination/schedule.ts} +3 -3
- package/src/state/{task-claims.ts → coordination/task-claims.ts} +1 -1
- package/src/state/decision-ledger.ts +1 -1
- package/src/state/{event-log-rotation.ts → event-log/event-log-rotation.ts} +189 -31
- package/src/state/{event-log.ts → event-log/event-log.ts} +77 -39
- package/src/state/{jsonl-writer.ts → event-log/jsonl-writer.ts} +14 -6
- package/src/state/hook-instinct-bridge.ts +2 -2
- package/src/state/{active-run-registry.ts → stores/active-run-registry.ts} +7 -7
- package/src/state/{artifact-store.ts → stores/artifact-store.ts} +62 -4
- package/src/state/{blob-store.ts → stores/blob-store.ts} +3 -3
- package/src/state/{health-store.ts → stores/health-store.ts} +3 -3
- package/src/state/{instinct-store.ts → stores/instinct-store.ts} +3 -3
- package/src/state/{observation-store.ts → stores/observation-store.ts} +2 -2
- package/src/state/{run-cache.ts → stores/run-cache.ts} +4 -4
- package/src/state/{run-graph.ts → stores/run-graph.ts} +4 -4
- package/src/state/{run-metrics.ts → stores/run-metrics.ts} +3 -3
- package/src/state/{state-store.ts → stores/state-store.ts} +254 -21
- package/src/state/types.ts +27 -3
- package/src/ui/component.ts +55 -0
- package/src/ui/crew-select-list.ts +3 -1
- package/src/ui/dashboard-panes/agents-pane.ts +1 -1
- package/src/ui/dwf-phase-display.ts +1 -1
- package/src/ui/heartbeat-aggregator.ts +1 -1
- package/src/ui/keybinding-map.ts +179 -6
- package/src/ui/layout-primitives.ts +9 -5
- package/src/ui/live-conversation-overlay.ts +1 -1
- package/src/ui/live-run-sidebar.ts +1 -1
- package/src/ui/overlay-stack.ts +148 -0
- package/src/ui/overlays/agent-picker-overlay.ts +1 -1
- package/src/ui/overlays/mailbox-compose-overlay.ts +1 -1
- package/src/ui/overlays/mailbox-detail-overlay.ts +2 -2
- package/src/ui/powerbar-publisher.ts +1 -1
- package/src/ui/render-scheduler.ts +1 -1
- package/src/ui/run-action-dispatcher.ts +3 -3
- package/src/ui/run-dashboard.ts +5 -33
- package/src/ui/run-event-bus.ts +3 -3
- package/src/ui/run-snapshot-cache.ts +37 -18
- package/src/ui/settings-overlay.ts +13 -21
- package/src/ui/snapshot-types.ts +1 -1
- package/src/ui/status-colors.ts +0 -2
- package/src/ui/terminal-status.ts +1 -1
- package/src/ui/theme-adapter.ts +33 -13
- package/src/ui/tool-renderers/index.ts +8 -0
- package/src/ui/transcript-viewer.ts +37 -13
- package/src/ui/widget/index.ts +32 -9
- package/src/ui/widget/widget-formatters.ts +62 -4
- package/src/ui/widget/widget-model.ts +2 -2
- package/src/ui/widget/widget-renderer.ts +1 -1
- package/src/utils/conflict-detect.ts +58 -5
- package/src/utils/ndjson.ts +2 -2
- package/src/utils/redaction.ts +39 -0
- package/src/utils/socket-path.ts +1 -1
- package/src/workflows/workflow-config.ts +1 -1
- package/src/worktree/cleanup.ts +1 -1
- package/src/worktree/worktree-manager.ts +111 -47
- package/workflows/chain.workflow.md +2 -2
- package/dist/build-meta.json +0 -16807
- package/index.bundle.ts +0 -25
- package/scripts/bench-check.mjs +0 -96
- package/scripts/bench-cold-start.mjs +0 -216
- package/scripts/build-bundle.mjs +0 -92
- package/scripts/check-all-skills.ts +0 -294
- package/scripts/check-bundle-size.mjs +0 -38
- package/scripts/check-bundle-staleness.mjs +0 -97
- package/scripts/check-conflict-markers.mjs +0 -91
- package/scripts/check-lazy-imports.mjs +0 -28
- package/scripts/dev-runner.mjs +0 -106
- package/scripts/profile-startup.mjs +0 -125
- package/scripts/release-smoke.mjs +0 -74
- package/scripts/run-bench.mjs +0 -47
- package/scripts/run-real-chain.ts +0 -41
- package/scripts/test-issue-29-crash.ts +0 -111
- package/scripts/test-issue-29-e2e.ts +0 -183
- package/scripts/test-issue-29-real-runtime.ts +0 -330
- package/scripts/test-issue-29-real-tasks.ts +0 -387
- package/scripts/test-issue-29-team-tool.ts +0 -105
- package/scripts/test-runner.mjs +0 -84
- package/scripts/verify-flicker-fix.ts +0 -109
- package/scripts/verify-skill.ts +0 -550
- package/scripts/watch-bundle.mjs +0 -259
- package/scripts/watchdog-harness.ts +0 -119
- package/src/adapters/claude-adapter.ts +0 -23
- package/src/adapters/codex-adapter.ts +0 -21
- package/src/adapters/cursor-adapter.ts +0 -17
- package/src/adapters/export-util.ts +0 -143
- package/src/adapters/index.ts +0 -15
- package/src/adapters/registry.ts +0 -18
- package/src/adapters/types.ts +0 -23
- package/src/runtime/code-summary.ts +0 -292
- package/src/runtime/cross-extension-rpc.ts +0 -143
- package/src/runtime/hidden-handoff.ts +0 -407
- package/src/runtime/prose-compressor.ts +0 -162
- package/src/subagents/async-entry.ts +0 -1
- package/src/subagents/index.ts +0 -3
- package/src/subagents/live/control.ts +0 -1
- package/src/subagents/live/manager.ts +0 -1
- package/src/subagents/live/realtime.ts +0 -1
- package/src/subagents/live/session-runtime.ts +0 -1
- package/src/subagents/manager.ts +0 -1
- package/src/subagents/spawn.ts +0 -1
- package/test-integration-check.ts +0 -118
- /package/src/runtime/{broker-issuer.ts → broker/broker-issuer.ts} +0 -0
- /package/src/runtime/{crew-broker-tokens.ts → broker/crew-broker-tokens.ts} +0 -0
- /package/src/runtime/{child-pi-pool.ts → child-pi/child-pi-pool.ts} +0 -0
- /package/src/runtime/{compact-pipeline.ts → compaction/compact-pipeline.ts} +0 -0
- /package/src/runtime/{compact-stages → compaction/compact-stages}/ansi-strip-stage.ts +0 -0
- /package/src/runtime/{compact-stages → compaction/compact-stages}/blank-collapse-stage.ts +0 -0
- /package/src/runtime/{compact-stages → compaction/compact-stages}/deduplicate-stage.ts +0 -0
- /package/src/runtime/{compact-stages → compaction/compact-stages}/head-snap-stage.ts +0 -0
- /package/src/runtime/{compact-stages → compaction/compact-stages}/tail-capture-stage.ts +0 -0
- /package/src/runtime/{compact-stages → compaction/compact-stages}/truncation-stage.ts +0 -0
- /package/src/runtime/{important-line-classifier.ts → compaction/important-line-classifier.ts} +0 -0
- /package/src/runtime/{heartbeat-gradient.ts → heartbeat/heartbeat-gradient.ts} +0 -0
- /package/src/runtime/{worker-heartbeat.ts → heartbeat/worker-heartbeat.ts} +0 -0
- /package/src/runtime/{worker-startup.ts → heartbeat/worker-startup.ts} +0 -0
- /package/src/runtime/{intercom-bridge.ts → live-session/intercom-bridge.ts} +0 -0
- /package/src/runtime/{live-control-realtime.ts → live-session/live-control-realtime.ts} +0 -0
- /package/src/runtime/{live-extension-bridge.ts → live-session/live-extension-bridge.ts} +0 -0
- /package/src/runtime/{live-irc.ts → live-session/live-irc.ts} +0 -0
- /package/src/runtime/{live-session-health.ts → live-session/live-session-health.ts} +0 -0
- /package/src/runtime/{model-resolver.ts → model/model-resolver.ts} +0 -0
- /package/src/runtime/{model-scope.ts → model/model-scope.ts} +0 -0
- /package/src/runtime/{output-validator.ts → output/output-validator.ts} +0 -0
- /package/src/runtime/{pi-json-output.ts → output/pi-json-output.ts} +0 -0
- /package/src/runtime/{progress-event-coalescer.ts → output/progress-event-coalescer.ts} +0 -0
- /package/src/runtime/{cancellation-token.ts → process/cancellation-token.ts} +0 -0
- /package/src/runtime/{zombie-scanner.ts → process/zombie-scanner.ts} +0 -0
- /package/src/runtime/{crash-classification.ts → recovery/crash-classification.ts} +0 -0
- /package/src/runtime/{batch-barrier.ts → scheduling/batch-barrier.ts} +0 -0
- /package/src/runtime/{global-worker-cap.ts → scheduling/global-worker-cap.ts} +0 -0
- /package/src/runtime/{parallel-utils.ts → scheduling/parallel-utils.ts} +0 -0
- /package/src/runtime/{scheduler.ts → scheduling/scheduler.ts} +0 -0
- /package/src/runtime/{task-graph.ts → scheduling/task-graph.ts} +0 -0
- /package/src/runtime/{verification-worktree.ts → verification/verification-worktree.ts} +0 -0
- /package/src/state/{event-reconstructor.ts → event-log/event-reconstructor.ts} +0 -0
- /package/src/state/{worker-atomic-writer.ts → event-log/worker-atomic-writer.ts} +0 -0
|
@@ -1,294 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Check All Skills Script
|
|
5
|
-
*
|
|
6
|
-
* Runs verify-skill.ts against all skills and produces a summary report.
|
|
7
|
-
*
|
|
8
|
-
* Usage:
|
|
9
|
-
* node scripts/check-all-skills.ts
|
|
10
|
-
*/
|
|
11
|
-
|
|
12
|
-
import { spawnSync } from "node:child_process";
|
|
13
|
-
import * as fs from "node:fs";
|
|
14
|
-
import * as path from "node:path";
|
|
15
|
-
|
|
16
|
-
interface SkillSummary {
|
|
17
|
-
name: string;
|
|
18
|
-
path: string;
|
|
19
|
-
status: "pass" | "fail" | "warning";
|
|
20
|
-
warnings: string[];
|
|
21
|
-
errors: string[];
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
interface Report {
|
|
25
|
-
total: number;
|
|
26
|
-
passed: number;
|
|
27
|
-
failed: number;
|
|
28
|
-
warningsOnly: number;
|
|
29
|
-
skills: SkillSummary[];
|
|
30
|
-
timestamp: string;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
const SKILLS_DIR = path.join(process.cwd(), "skills");
|
|
34
|
-
|
|
35
|
-
/**
|
|
36
|
-
* Get all skill directories
|
|
37
|
-
*/
|
|
38
|
-
function getSkillDirs(): string[] {
|
|
39
|
-
if (!fs.existsSync(SKILLS_DIR)) {
|
|
40
|
-
console.error("Skills directory not found: " + SKILLS_DIR);
|
|
41
|
-
return [];
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
const dirs: string[] = [];
|
|
45
|
-
const entries = fs.readdirSync(SKILLS_DIR, { withFileTypes: true });
|
|
46
|
-
|
|
47
|
-
for (const entry of entries) {
|
|
48
|
-
if (entry.isDirectory()) {
|
|
49
|
-
const skillPath = path.join(SKILLS_DIR, entry.name, "SKILL.md");
|
|
50
|
-
if (fs.existsSync(skillPath)) {
|
|
51
|
-
dirs.push(entry.name);
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
return dirs.sort();
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
/**
|
|
60
|
-
* Run verify-skill.ts for a single skill
|
|
61
|
-
*/
|
|
62
|
-
function verifySingleSkill(skillName: string): {
|
|
63
|
-
passed: boolean;
|
|
64
|
-
warnings: string[];
|
|
65
|
-
errors: string[];
|
|
66
|
-
} {
|
|
67
|
-
const skillPath = path.join(SKILLS_DIR, skillName, "SKILL.md");
|
|
68
|
-
|
|
69
|
-
const result = spawnSync("node", ["scripts/verify-skill.ts", skillPath], {
|
|
70
|
-
cwd: process.cwd(),
|
|
71
|
-
encoding: "utf-8",
|
|
72
|
-
});
|
|
73
|
-
|
|
74
|
-
const output = result.stdout + result.stderr;
|
|
75
|
-
const warnings: string[] = [];
|
|
76
|
-
const errors: string[] = [];
|
|
77
|
-
|
|
78
|
-
// Parse output
|
|
79
|
-
const warningMatches = output.match(/[^\n]*⚠️[^\n]*/g);
|
|
80
|
-
const errorMatches = output.match(/[^\n]+FAIL[^\n]+/g);
|
|
81
|
-
|
|
82
|
-
if (warningMatches) {
|
|
83
|
-
warnings.push(...warningMatches.map((w) => w.trim()));
|
|
84
|
-
}
|
|
85
|
-
if (errorMatches) {
|
|
86
|
-
errors.push(...errorMatches.map((e) => e.trim()));
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
const passed = result.status === 0;
|
|
90
|
-
|
|
91
|
-
return { passed, warnings, errors };
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
/**
|
|
95
|
-
* Generate markdown report
|
|
96
|
-
*/
|
|
97
|
-
function generateMarkdownReport(report: Report): string {
|
|
98
|
-
const lines: string[] = [];
|
|
99
|
-
|
|
100
|
-
lines.push("# Skill Verification Report");
|
|
101
|
-
lines.push("");
|
|
102
|
-
lines.push("Generated: " + report.timestamp);
|
|
103
|
-
lines.push("");
|
|
104
|
-
|
|
105
|
-
// Summary table
|
|
106
|
-
lines.push("## Summary");
|
|
107
|
-
lines.push("");
|
|
108
|
-
lines.push("| Status | Count |");
|
|
109
|
-
lines.push("|--------|-------|");
|
|
110
|
-
lines.push("| PASS | " + report.passed + " |");
|
|
111
|
-
lines.push("| FAIL | " + report.failed + " |");
|
|
112
|
-
lines.push("| Warnings | " + report.warningsOnly + " |");
|
|
113
|
-
lines.push("| **Total** | **" + report.total + "** |");
|
|
114
|
-
lines.push("");
|
|
115
|
-
|
|
116
|
-
// Skill list by status
|
|
117
|
-
lines.push("## Skills by Status");
|
|
118
|
-
lines.push("");
|
|
119
|
-
|
|
120
|
-
// Passed skills
|
|
121
|
-
const passedSkills = report.skills.filter((s) => s.status === "pass");
|
|
122
|
-
if (passedSkills.length > 0) {
|
|
123
|
-
lines.push("### Passing Skills");
|
|
124
|
-
lines.push("");
|
|
125
|
-
for (const skill of passedSkills) {
|
|
126
|
-
lines.push("- " + skill.name);
|
|
127
|
-
}
|
|
128
|
-
lines.push("");
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
// Failed skills
|
|
132
|
-
const failedSkills = report.skills.filter((s) => s.status === "fail");
|
|
133
|
-
if (failedSkills.length > 0) {
|
|
134
|
-
lines.push("### Failing Skills");
|
|
135
|
-
lines.push("");
|
|
136
|
-
for (const skill of failedSkills) {
|
|
137
|
-
lines.push("- **" + skill.name + "**");
|
|
138
|
-
for (const error of skill.errors) {
|
|
139
|
-
lines.push(" - " + error);
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
lines.push("");
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
// Warning skills
|
|
146
|
-
const warningSkills = report.skills.filter((s) => s.status === "warning");
|
|
147
|
-
if (warningSkills.length > 0) {
|
|
148
|
-
lines.push("### Skills with Warnings");
|
|
149
|
-
lines.push("");
|
|
150
|
-
for (const skill of warningSkills) {
|
|
151
|
-
lines.push("- **" + skill.name + "**");
|
|
152
|
-
for (const warning of skill.warnings) {
|
|
153
|
-
lines.push(" - " + warning);
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
lines.push("");
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
// Recommendations
|
|
160
|
-
lines.push("## Recommendations");
|
|
161
|
-
lines.push("");
|
|
162
|
-
if (failedSkills.length > 0) {
|
|
163
|
-
lines.push("1. Fix " + failedSkills.length + " failing skills to have proper RED/GREEN gates");
|
|
164
|
-
lines.push("2. Add trigger sections (When to Activate) if missing");
|
|
165
|
-
lines.push("3. Add anti-patterns sections to prevent common mistakes");
|
|
166
|
-
lines.push("");
|
|
167
|
-
}
|
|
168
|
-
if (warningSkills.length > 0) {
|
|
169
|
-
lines.push("4. Review " + warningSkills.length + " skills with warnings for improvements");
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
return lines.join("\n");
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
/**
|
|
176
|
-
* Generate JSON report
|
|
177
|
-
*/
|
|
178
|
-
function generateJsonReport(report: Report): string {
|
|
179
|
-
return JSON.stringify(report, null, 2);
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
/**
|
|
183
|
-
* Main entry point
|
|
184
|
-
*/
|
|
185
|
-
async function main() {
|
|
186
|
-
console.log("Checking all skills...\n");
|
|
187
|
-
|
|
188
|
-
const skillNames = getSkillDirs();
|
|
189
|
-
console.log("Found " + skillNames.length + " skills\n");
|
|
190
|
-
|
|
191
|
-
const report: Report = {
|
|
192
|
-
total: skillNames.length,
|
|
193
|
-
passed: 0,
|
|
194
|
-
failed: 0,
|
|
195
|
-
warningsOnly: 0,
|
|
196
|
-
skills: [],
|
|
197
|
-
timestamp: new Date().toISOString(),
|
|
198
|
-
};
|
|
199
|
-
|
|
200
|
-
for (const skillName of skillNames) {
|
|
201
|
-
process.stdout.write(".");
|
|
202
|
-
|
|
203
|
-
const result = verifySingleSkill(skillName);
|
|
204
|
-
|
|
205
|
-
let status: "pass" | "fail" | "warning" = "pass";
|
|
206
|
-
if (!result.passed && result.errors.length > 0) {
|
|
207
|
-
status = "fail";
|
|
208
|
-
report.failed++;
|
|
209
|
-
} else if (result.warnings.length > 0) {
|
|
210
|
-
status = "warning";
|
|
211
|
-
report.warningsOnly++;
|
|
212
|
-
} else {
|
|
213
|
-
report.passed++;
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
report.skills.push({
|
|
217
|
-
name: skillName,
|
|
218
|
-
path: path.join("skills", skillName, "SKILL.md"),
|
|
219
|
-
status,
|
|
220
|
-
warnings: result.warnings,
|
|
221
|
-
errors: result.errors,
|
|
222
|
-
});
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
console.log("\n\n");
|
|
226
|
-
|
|
227
|
-
// Print summary
|
|
228
|
-
console.log("=== Skill Verification Summary ===");
|
|
229
|
-
console.log("Total: " + report.total);
|
|
230
|
-
console.log("Passed: " + report.passed);
|
|
231
|
-
console.log("Failed: " + report.failed);
|
|
232
|
-
console.log("Warnings only: " + report.warningsOnly);
|
|
233
|
-
console.log("");
|
|
234
|
-
|
|
235
|
-
// List failed skills
|
|
236
|
-
if (report.failed > 0) {
|
|
237
|
-
console.log("Failing skills:");
|
|
238
|
-
for (const skill of report.skills.filter((s) => s.status === "fail")) {
|
|
239
|
-
console.log(" - " + skill.name);
|
|
240
|
-
for (const error of skill.errors) {
|
|
241
|
-
console.log(" " + error);
|
|
242
|
-
}
|
|
243
|
-
}
|
|
244
|
-
console.log("");
|
|
245
|
-
}
|
|
246
|
-
|
|
247
|
-
// List skills with warnings
|
|
248
|
-
if (report.warningsOnly > 0) {
|
|
249
|
-
console.log("Skills with warnings:");
|
|
250
|
-
for (const skill of report.skills.filter((s) => s.status === "warning")) {
|
|
251
|
-
console.log(" - " + skill.name);
|
|
252
|
-
for (const warning of skill.warnings) {
|
|
253
|
-
console.log(" " + warning);
|
|
254
|
-
}
|
|
255
|
-
}
|
|
256
|
-
console.log("");
|
|
257
|
-
}
|
|
258
|
-
|
|
259
|
-
// Write reports
|
|
260
|
-
const reportDir = path.join(process.cwd(), "reports");
|
|
261
|
-
if (!fs.existsSync(reportDir)) {
|
|
262
|
-
fs.mkdirSync(reportDir, { recursive: true });
|
|
263
|
-
}
|
|
264
|
-
|
|
265
|
-
const timestamp = new Date().toISOString().replace(/[:.]/g, "-");
|
|
266
|
-
const mdReportPath = path.join(reportDir, "skill-verification-" + timestamp + ".md");
|
|
267
|
-
const jsonReportPath = path.join(reportDir, "skill-verification-" + timestamp + ".json");
|
|
268
|
-
const latestMdPath = path.join(reportDir, "skill-verification-latest.md");
|
|
269
|
-
const latestJsonPath = path.join(reportDir, "skill-verification-latest.json");
|
|
270
|
-
|
|
271
|
-
fs.writeFileSync(mdReportPath, generateMarkdownReport(report));
|
|
272
|
-
fs.writeFileSync(jsonReportPath, generateJsonReport(report));
|
|
273
|
-
fs.writeFileSync(latestMdPath, generateMarkdownReport(report));
|
|
274
|
-
fs.writeFileSync(latestJsonPath, generateJsonReport(report));
|
|
275
|
-
|
|
276
|
-
console.log("Reports written to:");
|
|
277
|
-
console.log(" - " + mdReportPath);
|
|
278
|
-
console.log(" - " + jsonReportPath);
|
|
279
|
-
console.log(" - " + latestMdPath + " (latest)");
|
|
280
|
-
console.log(" - " + latestJsonPath + " (latest)");
|
|
281
|
-
|
|
282
|
-
// Exit with appropriate code
|
|
283
|
-
if (report.failed > 0) {
|
|
284
|
-
process.exit(1);
|
|
285
|
-
} else if (report.warningsOnly > 0) {
|
|
286
|
-
process.exit(2);
|
|
287
|
-
}
|
|
288
|
-
process.exit(0);
|
|
289
|
-
}
|
|
290
|
-
|
|
291
|
-
main().catch((err) => {
|
|
292
|
-
console.error("Fatal error:", err);
|
|
293
|
-
process.exit(1);
|
|
294
|
-
});
|
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
/**
|
|
3
|
-
* CI gate: enforce a max size budget on dist/index.mjs.
|
|
4
|
-
*
|
|
5
|
-
* The bundle is the cold-start entrypoint (preferred over strip-types
|
|
6
|
-
* loading since v0.9.17). A growing bundle directly increases parse
|
|
7
|
-
* time and npm install cost. This guard FAILS the build if the bundle
|
|
8
|
-
* exceeds the budget, surfacing regressions early.
|
|
9
|
-
*
|
|
10
|
-
* Budget: 3.5 MB (see ROADMAP-2026-07-27 Sprint 6 CI-4).
|
|
11
|
-
*
|
|
12
|
-
* Exits:
|
|
13
|
-
* 0 — bundle is within budget (or absent, deferring to build:bundle)
|
|
14
|
-
* 1 — bundle exceeds budget
|
|
15
|
-
*/
|
|
16
|
-
|
|
17
|
-
import { existsSync, statSync } from "node:fs";
|
|
18
|
-
|
|
19
|
-
const BUDGET_BYTES = 3.5 * 1024 * 1024; // 3.5 MB
|
|
20
|
-
const distPath = "dist/index.mjs";
|
|
21
|
-
|
|
22
|
-
if (!existsSync(distPath)) {
|
|
23
|
-
console.log("[check-bundle-size] dist/index.mjs absent — nothing to check. OK.");
|
|
24
|
-
process.exit(0);
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
const sizeBytes = statSync(distPath).size;
|
|
28
|
-
|
|
29
|
-
if (sizeBytes > BUDGET_BYTES) {
|
|
30
|
-
console.error(
|
|
31
|
-
`[check-bundle-size] FAIL: dist/index.mjs (${(sizeBytes / 1024 / 1024).toFixed(2)} MB) exceeds budget (${(BUDGET_BYTES / 1024 / 1024).toFixed(1)} MB).`,
|
|
32
|
-
);
|
|
33
|
-
process.exit(1);
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
console.log(
|
|
37
|
-
`[check-bundle-size] OK: dist/index.mjs is ${(sizeBytes / 1024 / 1024).toFixed(2)} MB (budget ${(BUDGET_BYTES / 1024 / 1024).toFixed(1)} MB).`,
|
|
38
|
-
);
|
|
@@ -1,97 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
/**
|
|
3
|
-
* CI gate: detect stale dist/index.mjs vs src/.
|
|
4
|
-
*
|
|
5
|
-
* Compares the newest mtime in src/ against dist/index.mjs mtime. If
|
|
6
|
-
* src/ is newer, the bundle is stale (someone edited source without
|
|
7
|
-
* rebuilding). Exits non-zero in that case.
|
|
8
|
-
*
|
|
9
|
-
* Why: in v0.9.17 the entrypoint prefers the bundle (with strip-types
|
|
10
|
-
* fallback). Stale bundles silently run old code — see Phase 5 H2
|
|
11
|
-
* investigation (2026-07-01) for the regression risk.
|
|
12
|
-
*
|
|
13
|
-
* Skips if dist/index.mjs does not exist (the strip-types fallback path
|
|
14
|
-
* is fine and the build:bundle automation will produce it).
|
|
15
|
-
*
|
|
16
|
-
* Exits:
|
|
17
|
-
* 0 — dist is fresh OR absent
|
|
18
|
-
* 1 — dist is stale (run `npm run build:bundle`)
|
|
19
|
-
*/
|
|
20
|
-
|
|
21
|
-
import { execSync } from "node:child_process";
|
|
22
|
-
import { existsSync, statSync } from "node:fs";
|
|
23
|
-
|
|
24
|
-
const distPath = "dist/index.mjs";
|
|
25
|
-
if (!existsSync(distPath)) {
|
|
26
|
-
console.log("[check-bundle-staleness] dist/index.mjs absent — strip-types fallback will be used. OK.");
|
|
27
|
-
process.exit(0);
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
const distMtimeMs = statSync(distPath).mtimeMs;
|
|
31
|
-
|
|
32
|
-
// `git ls-files -o -- src` lists untracked files in src/. We want every
|
|
33
|
-
// tracked file's mtime plus the newest untracked one. Cheap heuristic:
|
|
34
|
-
// use `find` style by asking git for the full list, then statSync each.
|
|
35
|
-
let trackedFiles;
|
|
36
|
-
try {
|
|
37
|
-
trackedFiles = execSync(`git ls-files src`, { encoding: "utf-8" })
|
|
38
|
-
.split("\n")
|
|
39
|
-
.filter(Boolean);
|
|
40
|
-
} catch {
|
|
41
|
-
// Not a git repo (e.g. npm pack test) — skip.
|
|
42
|
-
console.log("[check-bundle-staleness] not a git repo; skipping staleness check.");
|
|
43
|
-
process.exit(0);
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
let newestMtimeMs = 0;
|
|
47
|
-
let newestFile = "";
|
|
48
|
-
for (const f of trackedFiles) {
|
|
49
|
-
try {
|
|
50
|
-
const mt = statSync(f).mtimeMs;
|
|
51
|
-
if (mt > newestMtimeMs) {
|
|
52
|
-
newestMtimeMs = mt;
|
|
53
|
-
newestFile = f;
|
|
54
|
-
}
|
|
55
|
-
} catch {
|
|
56
|
-
// File listed but missing on disk — ignore.
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
// Add untracked .ts files in src/ (devs editing a new file)
|
|
61
|
-
try {
|
|
62
|
-
const untracked = execSync(`git ls-files -o --exclude-standard src`, { encoding: "utf-8" })
|
|
63
|
-
.split("\n")
|
|
64
|
-
.filter(Boolean);
|
|
65
|
-
for (const f of untracked) {
|
|
66
|
-
if (!f.endsWith(".ts")) continue;
|
|
67
|
-
try {
|
|
68
|
-
const mt = statSync(f).mtimeMs;
|
|
69
|
-
if (mt > newestMtimeMs) {
|
|
70
|
-
newestMtimeMs = mt;
|
|
71
|
-
newestFile = f;
|
|
72
|
-
}
|
|
73
|
-
} catch {
|
|
74
|
-
// ignore
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
} catch {
|
|
78
|
-
// git may fail; ignore
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
if (newestMtimeMs === 0) {
|
|
82
|
-
console.log("[check-bundle-staleness] no src/*.ts files found; skipping.");
|
|
83
|
-
process.exit(0);
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
if (newestMtimeMs > distMtimeMs) {
|
|
87
|
-
console.error(
|
|
88
|
-
`[check-bundle-staleness] FAIL: dist/index.mjs is stale.\n` +
|
|
89
|
-
` Newest src file: ${newestFile} (mtime=${newestMtimeMs.toFixed(0)})\n` +
|
|
90
|
-
` dist/index.mjs mtime: ${distMtimeMs.toFixed(0)}\n` +
|
|
91
|
-
` → run \`npm run build:bundle\` to refresh.`,
|
|
92
|
-
);
|
|
93
|
-
process.exit(1);
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
const ageSec = (distMtimeMs - newestMtimeMs) / 1000;
|
|
97
|
-
console.log(`[check-bundle-staleness] OK: dist/index.mjs is ${ageSec.toFixed(1)}s newer than newest src/ file.`);
|
|
@@ -1,91 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
/**
|
|
3
|
-
* CI gate: detect unresolved git merge conflict markers in source.
|
|
4
|
-
*
|
|
5
|
-
* Scans tracked source files for `<<<<<<<`, `=======` (lone), and
|
|
6
|
-
* `>>>>>>>` patterns that indicate a botched merge. Fails CI if any
|
|
7
|
-
* are found so they can't reach the bundle (which esbuild would
|
|
8
|
-
* choke on with a parse error).
|
|
9
|
-
*
|
|
10
|
-
* History: 2026-07-01 CI #28498831579 (Ubuntu) failed because
|
|
11
|
-
* src/runtime/child-pi.ts and src/extension/pi-api.ts shipped with
|
|
12
|
-
* unresolved conflict markers left over from earlier stash/pop cycles
|
|
13
|
-
* during Phase 2-5 implementation. The esbuild transformer in the
|
|
14
|
-
* test runner hit `Expected identifier but found "<<"` at
|
|
15
|
-
* src/runtime/child-pi.ts:1073 — a syntax error caused by the markers.
|
|
16
|
-
*
|
|
17
|
-
* Scope:
|
|
18
|
-
* - Tracks files in src/, test/, scripts/, workflows/, teams/,
|
|
19
|
-
* agents/, themes/ — anywhere a conflict would land.
|
|
20
|
-
* - Excludes test/unit/conflict-detect.test.ts which INTENTIONALLY
|
|
21
|
-
* contains `<<<<<<< HEAD` etc. as test fixtures (test the
|
|
22
|
-
detector itself).
|
|
23
|
-
* - Detects both conflict-style (`<<<<<<<`, `=======`, `>>>>>>>`)
|
|
24
|
-
* and diff3-style (`|||||||`) markers.
|
|
25
|
-
*
|
|
26
|
-
* Exits:
|
|
27
|
-
* 0 — clean (no markers found, or only allowed locations)
|
|
28
|
-
* 1 — markers found (with file:line listing)
|
|
29
|
-
*/
|
|
30
|
-
|
|
31
|
-
import { execSync } from "node:child_process";
|
|
32
|
-
import { readFileSync } from "node:fs";
|
|
33
|
-
|
|
34
|
-
const MARKER_PATTERNS = [
|
|
35
|
-
/^<<<<<<< /m, // ours/incoming/conflict markers
|
|
36
|
-
/^=======$/m, // conflict separator (lone, not bash =======)
|
|
37
|
-
/^>>>>>>> /m, // theirs/outgoing markers
|
|
38
|
-
/^\|\|\|\|\|\|\| /m, // diff3 base marker
|
|
39
|
-
];
|
|
40
|
-
|
|
41
|
-
const SCAN_PATHS = ["src/", "test/", "scripts/", "workflows/", "teams/", "agents/", "themes/"];
|
|
42
|
-
const EXCLUDE_FILES = new Set([
|
|
43
|
-
// Intentionally contains conflict markers as test fixtures.
|
|
44
|
-
"test/unit/conflict-detect.test.ts",
|
|
45
|
-
]);
|
|
46
|
-
|
|
47
|
-
function listTrackedFiles() {
|
|
48
|
-
try {
|
|
49
|
-
const all = execSync("git ls-files", { encoding: "utf-8" });
|
|
50
|
-
return all
|
|
51
|
-
.split("\n")
|
|
52
|
-
.filter(Boolean)
|
|
53
|
-
.filter((f) => SCAN_PATHS.some((p) => f.startsWith(p) || f === p.replace(/\/$/, "")))
|
|
54
|
-
.filter((f) => !EXCLUDE_FILES.has(f));
|
|
55
|
-
} catch {
|
|
56
|
-
console.error("[conflict-markers] not a git repo; skipping check.");
|
|
57
|
-
process.exit(0);
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
const files = listTrackedFiles();
|
|
62
|
-
const offenders = [];
|
|
63
|
-
|
|
64
|
-
for (const file of files) {
|
|
65
|
-
let content;
|
|
66
|
-
try {
|
|
67
|
-
content = readFileSync(file, "utf-8");
|
|
68
|
-
} catch {
|
|
69
|
-
// File listed but unreadable — skip silently.
|
|
70
|
-
continue;
|
|
71
|
-
}
|
|
72
|
-
const lines = content.split(/\r?\n/);
|
|
73
|
-
for (let i = 0; i < lines.length; i += 1) {
|
|
74
|
-
const line = lines[i];
|
|
75
|
-
if (MARKER_PATTERNS.some((re) => re.test(line))) {
|
|
76
|
-
offenders.push({ file, line: i + 1, text: line });
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
if (offenders.length === 0) {
|
|
82
|
-
console.log(`[conflict-markers] OK: scanned ${files.length} files, no markers found.`);
|
|
83
|
-
process.exit(0);
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
console.error(`[conflict-markers] FAIL: ${offenders.length} conflict marker(s) found.`);
|
|
87
|
-
for (const o of offenders) {
|
|
88
|
-
console.error(` ${o.file}:${o.line}: ${o.text.trim().slice(0, 80)}`);
|
|
89
|
-
}
|
|
90
|
-
console.error("\nResolve with: git checkout --ours|--theirs or git add ... after manual edit.");
|
|
91
|
-
process.exit(1);
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
import { execSync } from "node:child_process";
|
|
2
|
-
import { readFileSync } from "node:fs";
|
|
3
|
-
|
|
4
|
-
const out = execSync(
|
|
5
|
-
`git grep -nE "await import\\(" -- "src/**/*.ts"`,
|
|
6
|
-
{ encoding: "utf-8" },
|
|
7
|
-
);
|
|
8
|
-
|
|
9
|
-
const bad = [];
|
|
10
|
-
const fileCache = new Map();
|
|
11
|
-
|
|
12
|
-
for (const line of out.split("\n").filter(Boolean)) {
|
|
13
|
-
if (line.includes("// LAZY:")) continue;
|
|
14
|
-
const m = line.match(/^([^:]+):(\d+):/);
|
|
15
|
-
if (!m) continue;
|
|
16
|
-
const [, file, lineNum] = m;
|
|
17
|
-
if (!fileCache.has(file)) fileCache.set(file, readFileSync(file, "utf-8").split(/\r?\n/));
|
|
18
|
-
const lines = fileCache.get(file);
|
|
19
|
-
const prevLine = lines[Number(lineNum) - 2] ?? "";
|
|
20
|
-
if (!prevLine.includes("// LAZY:")) bad.push(line);
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
if (bad.length > 0) {
|
|
24
|
-
console.error("Dynamic imports without `// LAZY:` marker:\n" + bad.join("\n"));
|
|
25
|
-
process.exit(1);
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
console.log("All dynamic imports have `// LAZY:` marker.");
|
package/scripts/dev-runner.mjs
DELETED
|
@@ -1,106 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
/**
|
|
3
|
-
* Dev runner — spawn `watch:bundle` and `test:watch` in parallel.
|
|
4
|
-
*
|
|
5
|
-
* Replaces the `npm-run-all --parallel watch:bundle test:watch` form that
|
|
6
|
-
* would require an additional dev-dependency. Uses Node's stdlib
|
|
7
|
-
* `child_process.spawn` so we keep the dev tooling dependency-free.
|
|
8
|
-
*
|
|
9
|
-
* Behavior:
|
|
10
|
-
* - Spawns both child processes with stdio: inherit (the parent's TTY
|
|
11
|
-
* sees both streams interleaved).
|
|
12
|
-
* - Forwards Ctrl+C (SIGINT) and SIGTERM to both children so they shut
|
|
13
|
-
* down cleanly when the user aborts.
|
|
14
|
-
* - Exits with a non-zero code if EITHER child exits with a non-zero
|
|
15
|
-
* status (mimics `npm-run-all --parallel` semantics).
|
|
16
|
-
*
|
|
17
|
-
* Usage:
|
|
18
|
-
* npm run dev
|
|
19
|
-
* node scripts/dev-runner.mjs
|
|
20
|
-
*/
|
|
21
|
-
|
|
22
|
-
import { spawn } from "node:child_process";
|
|
23
|
-
import process from "node:process";
|
|
24
|
-
|
|
25
|
-
const tasks = [
|
|
26
|
-
{ name: "watch:bundle", script: "watch:bundle" },
|
|
27
|
-
{ name: "test:watch", script: "test:watch" },
|
|
28
|
-
];
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* @typedef {{name: string, child: import("node:child_process").ChildProcess, exited: boolean, code: number|null, signal: NodeJS.Signals|null}} Task
|
|
32
|
-
*/
|
|
33
|
-
|
|
34
|
-
/** @type {Task[]} */
|
|
35
|
-
const children = tasks.map((t) => ({
|
|
36
|
-
name: t.name,
|
|
37
|
-
child: spawnNpm(t.script),
|
|
38
|
-
exited: false,
|
|
39
|
-
code: null,
|
|
40
|
-
signal: null,
|
|
41
|
-
}));
|
|
42
|
-
|
|
43
|
-
let shuttingDown = false;
|
|
44
|
-
let exitCode = 0;
|
|
45
|
-
|
|
46
|
-
function spawnNpm(script) {
|
|
47
|
-
return spawn("npm", ["run", "--silent", script], {
|
|
48
|
-
stdio: "inherit",
|
|
49
|
-
env: process.env,
|
|
50
|
-
});
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
function maybeExit() {
|
|
54
|
-
if (!shuttingDown) return;
|
|
55
|
-
if (children.some((c) => !c.exited)) return;
|
|
56
|
-
process.exit(exitCode);
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
function shutdown(reason) {
|
|
60
|
-
if (shuttingDown) return;
|
|
61
|
-
shuttingDown = true;
|
|
62
|
-
process.stderr.write(`\n[dev-runner] received ${reason}, forwarding to children...\n`);
|
|
63
|
-
for (const c of children) {
|
|
64
|
-
if (c.exited) continue;
|
|
65
|
-
try {
|
|
66
|
-
c.child.kill("SIGTERM");
|
|
67
|
-
} catch {
|
|
68
|
-
/* already dead */
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
// Hard-kill grace window: if children ignore SIGTERM for 3s, send SIGKILL.
|
|
72
|
-
setTimeout(() => {
|
|
73
|
-
for (const c of children) {
|
|
74
|
-
if (c.exited) continue;
|
|
75
|
-
try {
|
|
76
|
-
c.child.kill("SIGKILL");
|
|
77
|
-
} catch {
|
|
78
|
-
/* already dead */
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
}, 3000).unref();
|
|
82
|
-
maybeExit();
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
for (const c of children) {
|
|
86
|
-
c.child.on("exit", (code, signal) => {
|
|
87
|
-
c.exited = true;
|
|
88
|
-
c.code = code;
|
|
89
|
-
c.signal = signal;
|
|
90
|
-
const note = signal ? `signal=${signal}` : `code=${code}`;
|
|
91
|
-
process.stderr.write(`[dev-runner] ${c.name} exited (${note})\n`);
|
|
92
|
-
// Non-zero is only meaningful when the child exited via code (not signal).
|
|
93
|
-
if (signal === null && code !== 0) exitCode = exitCode || (code ?? 1);
|
|
94
|
-
maybeExit();
|
|
95
|
-
});
|
|
96
|
-
|
|
97
|
-
c.child.on("error", (err) => {
|
|
98
|
-
process.stderr.write(`[dev-runner] failed to spawn ${c.name}: ${err.message}\n`);
|
|
99
|
-
c.exited = true;
|
|
100
|
-
exitCode = exitCode || 1;
|
|
101
|
-
maybeExit();
|
|
102
|
-
});
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
process.on("SIGINT", () => shutdown("SIGINT"));
|
|
106
|
-
process.on("SIGTERM", () => shutdown("SIGTERM"));
|