session-orchestrator 3.24.0 → 4.0.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/.agents/skills/architecture/SKILL.md +18 -0
- package/.agents/skills/autopilot/SKILL.md +17 -0
- package/.agents/skills/bootstrap/SKILL.md +20 -0
- package/.agents/skills/brainstorm/SKILL.md +22 -0
- package/.agents/skills/claude-md-drift-check/SKILL.md +15 -0
- package/.agents/skills/convergence-monitoring/SKILL.md +22 -0
- package/.agents/skills/debug/SKILL.md +22 -0
- package/.agents/skills/discovery/SKILL.md +20 -0
- package/.agents/skills/dispatcher/SKILL.md +15 -0
- package/.agents/skills/docs-orchestrator/SKILL.md +18 -0
- package/.agents/skills/ecosystem-health/SKILL.md +20 -0
- package/.agents/skills/eli5/SKILL.md +20 -0
- package/.agents/skills/eval/SKILL.md +21 -0
- package/.agents/skills/evolve/SKILL.md +21 -0
- package/.agents/skills/frontmatter-guard/SKILL.md +15 -0
- package/.agents/skills/gitlab-ops/SKILL.md +20 -0
- package/.agents/skills/gitlab-portfolio/SKILL.md +15 -0
- package/.agents/skills/grill/SKILL.md +22 -0
- package/.agents/skills/hook-development/SKILL.md +15 -0
- package/.agents/skills/mcp-builder/SKILL.md +15 -0
- package/.agents/skills/memory-cleanup/SKILL.md +21 -0
- package/.agents/skills/mode-selector/SKILL.md +17 -0
- package/.agents/skills/npm-publish/SKILL.md +16 -0
- package/.agents/skills/peekaboo-driver/SKILL.md +18 -0
- package/.agents/skills/persona-panel/SKILL.md +17 -0
- package/.agents/skills/plan/SKILL.md +20 -0
- package/.agents/skills/playwright-driver/SKILL.md +20 -0
- package/.agents/skills/quality-gates/SKILL.md +20 -0
- package/.agents/skills/reconcile/SKILL.md +21 -0
- package/.agents/skills/remote-offload/SKILL.md +20 -0
- package/.agents/skills/repo-audit/SKILL.md +16 -0
- package/.agents/skills/session-end/SKILL.md +20 -0
- package/.agents/skills/session-plan/SKILL.md +20 -0
- package/.agents/skills/session-start/SKILL.md +20 -0
- package/.agents/skills/spinout/SKILL.md +16 -0
- package/.agents/skills/sunset-review/SKILL.md +16 -0
- package/.agents/skills/test-runner/SKILL.md +20 -0
- package/.agents/skills/tmux-layout/SKILL.md +21 -0
- package/.agents/skills/using-orchestrator/SKILL.md +17 -0
- package/.agents/skills/vault-mirror/SKILL.md +15 -0
- package/.agents/skills/vault-sync/SKILL.md +15 -0
- package/.agents/skills/wave-executor/SKILL.md +20 -0
- package/.agents/skills/write-executable-plan/SKILL.md +22 -0
- package/.claude-plugin/marketplace.json +1 -1
- package/.claude-plugin/plugin.json +1 -1
- package/.codex-plugin/plugin.json +1 -1
- package/.cursor/commands/autopilot.md +2 -2
- package/.cursor/commands/bootstrap.md +1 -1
- package/.cursor/commands/brainstorm.md +1 -1
- package/.cursor/commands/debug.md +1 -1
- package/.cursor/commands/discovery.md +1 -1
- package/.cursor/commands/dispatcher.md +2 -2
- package/.cursor/commands/eli5.md +2 -2
- package/.cursor/commands/eval.md +2 -2
- package/.cursor/commands/evolve.md +1 -1
- package/.cursor/commands/go.md +1 -1
- package/.cursor/commands/grill.md +2 -2
- package/.cursor/commands/memory-cleanup.md +2 -2
- package/.cursor/commands/persona-panel.md +1 -1
- package/.cursor/commands/plan.md +1 -1
- package/.cursor/commands/portfolio.md +1 -1
- package/.cursor/commands/reconcile.md +2 -2
- package/.cursor/commands/release.md +2 -2
- package/.cursor/commands/session.md +2 -2
- package/.cursor/commands/spinout.md +2 -2
- package/.cursor/commands/sunset-review.md +2 -2
- package/.cursor/commands/templates-ack.md +2 -2
- package/.cursor/commands/test.md +2 -2
- package/.cursor/skills/brainstorm/SKILL.md +1 -1
- package/.cursor/skills/eval/SKILL.md +1 -1
- package/.cursor/skills/quality-gates/SKILL.md +1 -1
- package/.cursor/skills/remote-offload/SKILL.md +1 -1
- package/.orchestrator/policy/blocked-commands.json +121 -0
- package/.orchestrator/policy/ecosystem.schema.json +66 -0
- package/.orchestrator/policy/quality-gates.example.json +16 -0
- package/.orchestrator/policy/quality-gates.schema.json +38 -0
- package/.orchestrator/policy/templates-policy.json +27 -0
- package/.orchestrator/policy/test-profiles.json +47 -0
- package/AGENTS.md +225 -0
- package/CHANGELOG.md +1125 -2
- package/NOTICE +11 -6
- package/README.md +127 -94
- package/agents/eval-judge.md +1 -1
- package/agents/skill-applied-judge.md +1 -1
- package/assets/wave-lifecycle.svg +98 -0
- package/commands/release.md +6 -3
- package/commands/session.md +18 -3
- package/docs/README.md +4 -0
- package/{agents/AGENTS.md → docs/agent-authoring.md} +19 -26
- package/docs/baseline.md +67 -0
- package/docs/ci-setup.md +108 -62
- package/docs/codex-setup.md +65 -21
- package/docs/components.md +36 -15
- package/docs/cursor-setup.md +6 -2
- package/docs/events-schema.md +9 -6
- package/docs/instruction-delivery.md +62 -0
- package/{agents/memory-proposal-collector.md → docs/memory-proposal-flow.md} +1 -8
- package/docs/migration-v4.md +341 -0
- package/docs/pi-setup.md +6 -1
- package/docs/plugin-architecture-v3.md +1 -1
- package/docs/rule-authoring.md +85 -19
- package/docs/scope-collision-guard.md +5 -5
- package/docs/session-config-reference.md +57 -56
- package/docs/session-config-template.md +6 -29
- package/docs/telemetry.md +157 -3
- package/docs/vault-docs-architecture.md +50 -11
- package/hooks/_lib/hook-import-set.json +1487 -0
- package/hooks/_lib/subagent-transcript.mjs +562 -0
- package/hooks/config-protection.mjs +2 -2
- package/hooks/cwd-change-restore.mjs +2 -2
- package/hooks/enforce-commands.mjs +69 -0
- package/hooks/hooks-codex.json +1 -1
- package/hooks/hooks-cursor.json +10 -0
- package/hooks/hooks-pi.json +5 -0
- package/hooks/hooks.json +6 -1
- package/hooks/loop-guard.mjs +3 -3
- package/hooks/on-session-end.mjs +2 -2
- package/hooks/on-session-start.mjs +103 -2
- package/hooks/on-stop.mjs +36 -11
- package/hooks/operator-steer.mjs +2 -2
- package/hooks/post-bash-write-verify.mjs +85 -0
- package/hooks/post-edit-import-probe.mjs +344 -0
- package/hooks/post-subagent-discovery-validator.mjs +187 -431
- package/hooks/post-tool-batch-wave-signal.mjs +118 -4
- package/hooks/post-tool-failure-corrective-context.mjs +2 -2
- package/hooks/post-tooluse-frontend-slop.mjs +3 -3
- package/hooks/pre-bash-destructive-guard.mjs +39 -13
- package/hooks/skill-invocation-telemetry.mjs +17 -5
- package/hooks/subagent-telemetry.mjs +13 -4
- package/monitors/monitors.json +3 -3
- package/package.json +9 -1
- package/pi/prompts/session.md +2 -2
- package/plugin.json +27 -0
- package/scripts/backfill-abandoned-sessions.mjs +50 -4
- package/scripts/backfill-learnings-from-vault.mjs +9 -3
- package/scripts/dialectic-deriver.mjs +73 -8
- package/scripts/export-hw-learnings.mjs +113 -1
- package/scripts/generate-agents-skills.mjs +378 -0
- package/scripts/generate-cursor-adapter.mjs +45 -8
- package/scripts/generate-hook-import-set.mjs +249 -0
- package/scripts/lib/agent-status.mjs +13 -2
- package/scripts/lib/auto-dream.mjs +38 -36
- package/scripts/lib/autonomy/suitability.mjs +6 -0
- package/scripts/lib/autopilot/loop.mjs +2 -2
- package/scripts/lib/ci-status-banner.mjs +220 -75
- package/scripts/lib/codex/plugin-contract.mjs +82 -6
- package/scripts/lib/config/auto-dream.mjs +2 -1
- package/scripts/lib/config/block-header.mjs +8 -0
- package/scripts/lib/config/block-preprocess.mjs +177 -0
- package/scripts/lib/config/broken-window.mjs +2 -1
- package/scripts/lib/config/cold-start.mjs +2 -1
- package/scripts/lib/config/config-protection.mjs +22 -2
- package/scripts/lib/config/context-coverage.mjs +2 -1
- package/scripts/lib/config/cross-repo.mjs +2 -1
- package/scripts/lib/config/custom-phases.mjs +2 -1
- package/scripts/lib/config/dialectic.mjs +2 -1
- package/scripts/lib/config/discovery-validator.mjs +2 -1
- package/scripts/lib/config/dispatcher-autonomy-capture.mjs +24 -1
- package/scripts/lib/config/dispatcher-autonomy.mjs +2 -1
- package/scripts/lib/config/docs-orchestrator.mjs +2 -1
- package/scripts/lib/config/docs-staleness.mjs +2 -1
- package/scripts/lib/config/drift-check.mjs +2 -1
- package/scripts/lib/config/eval.mjs +2 -1
- package/scripts/lib/config/events-rotation.mjs +2 -1
- package/scripts/lib/config/evolve.mjs +8 -2
- package/scripts/lib/config/frontend-slop-hook.mjs +7 -3
- package/scripts/lib/config/gitlab-portfolio.mjs +2 -1
- package/scripts/lib/config/handover-gate.mjs +2 -1
- package/scripts/lib/config/health-endpoints.mjs +7 -2
- package/scripts/lib/config/issue-budget.mjs +2 -1
- package/scripts/lib/config/loop-guard.mjs +2 -1
- package/scripts/lib/config/memory.mjs +2 -1
- package/scripts/lib/config/moc-staleness.mjs +2 -1
- package/scripts/lib/config/persona-gate-wave.mjs +2 -1
- package/scripts/lib/config/private-config-dir.mjs +67 -0
- package/scripts/lib/config/reconcile.mjs +2 -1
- package/scripts/lib/config/remote-hosts.mjs +2 -1
- package/scripts/lib/config/section-extractor.mjs +7 -1
- package/scripts/lib/config/skill-evolution.mjs +2 -1
- package/scripts/lib/config/slopcheck.mjs +2 -1
- package/scripts/lib/config/state-md-lock.mjs +2 -1
- package/scripts/lib/config/templates-first.mjs +2 -1
- package/scripts/lib/config/test.mjs +2 -1
- package/scripts/lib/config/vault-integration.mjs +7 -1
- package/scripts/lib/config/vault-mirror-quality.mjs +2 -1
- package/scripts/lib/config/vault-staleness.mjs +2 -1
- package/scripts/lib/config/vault-sync.mjs +2 -1
- package/scripts/lib/config/verification-auto-fix.mjs +2 -1
- package/scripts/lib/config/wave-reviewers.mjs +2 -1
- package/scripts/lib/config/worktree-orphans.mjs +2 -1
- package/scripts/lib/convergence-monitor.mjs +82 -16
- package/scripts/lib/dispatcher/rank.mjs +124 -48
- package/scripts/lib/ecosystem-health.mjs +16 -2
- package/scripts/lib/eval/engine.mjs +9 -1
- package/scripts/lib/eval/session-resolve.mjs +23 -4
- package/scripts/lib/events.mjs +22 -6
- package/scripts/lib/frontmatter-guard.mjs +131 -13
- package/scripts/lib/gates/gate-full.mjs +26 -0
- package/scripts/lib/gates/gate-helpers.mjs +76 -0
- package/scripts/lib/hardware-pattern-detector.mjs +18 -1
- package/scripts/lib/harness-audit/categories/category4.mjs +31 -11
- package/scripts/lib/host-identity.mjs +50 -11
- package/scripts/lib/instruction-budget-guard.mjs +171 -5
- package/scripts/lib/learnings/evolve-telemetry.mjs +178 -0
- package/scripts/lib/learnings/io.mjs +60 -6
- package/scripts/lib/memory-proposals/store.mjs +30 -22
- package/scripts/lib/owner-config-banner.mjs +43 -6
- package/scripts/lib/owner-config-loader.mjs +21 -10
- package/scripts/lib/owner-interview.mjs +3 -3
- package/scripts/lib/owner-yaml.mjs +207 -14
- package/scripts/lib/platform.mjs +108 -15
- package/scripts/lib/plugin-update-banner.mjs +406 -0
- package/scripts/lib/project-hygiene.mjs +38 -2
- package/scripts/lib/qg-command-drift-banner.mjs +50 -12
- package/scripts/lib/quality-gate.mjs +133 -44
- package/scripts/lib/reconcile/emitter.mjs +68 -6
- package/scripts/lib/reconcile/engine.mjs +13 -4
- package/scripts/lib/reconcile/idempotency.mjs +37 -4
- package/scripts/lib/reconcile/writer.mjs +40 -18
- package/scripts/lib/session-close-backfill.mjs +67 -9
- package/scripts/lib/session-id.mjs +12 -23
- package/scripts/lib/session-identity/own-session.mjs +125 -10
- package/scripts/lib/session-lock-shape.mjs +43 -0
- package/scripts/lib/session-lock.mjs +5 -10
- package/scripts/lib/session-registry.mjs +25 -9
- package/scripts/lib/session-schema/constants.mjs +36 -2
- package/scripts/lib/session-schema/validator.mjs +38 -4
- package/scripts/lib/session-start-probes.mjs +18 -1
- package/scripts/lib/sessions-staleness-banner.mjs +18 -11
- package/scripts/lib/skill-health/join.mjs +17 -4
- package/scripts/lib/state-md.mjs +78 -0
- package/scripts/lib/sunset/walker.mjs +6 -0
- package/scripts/lib/telemetry/schema.mjs +181 -9
- package/scripts/lib/telemetry/sync.mjs +368 -12
- package/scripts/lib/validate/check-agents-skills.mjs +327 -0
- package/scripts/lib/validate/check-agents.mjs +3 -3
- package/scripts/lib/validate/check-cursor-adapter.mjs +234 -72
- package/scripts/lib/validate/check-hooks-symmetry.mjs +45 -16
- package/scripts/lib/validate/check-owner-leakage.mjs +281 -20
- package/scripts/lib/validate/check-skill-links.mjs +163 -0
- package/scripts/lib/validate/check-skill-script-paths.mjs +47 -28
- package/scripts/lib/validate/check-unwired-features.mjs +0 -2
- package/scripts/lib/validate/check-validator-registration.mjs +10 -4
- package/scripts/lib/validate/enumerate-repo-files.mjs +317 -0
- package/scripts/lib/vault-backfill/template.mjs +63 -6
- package/scripts/lib/vault-mirror/process.mjs +165 -42
- package/scripts/lib/vault-mirror/telemetry.mjs +2 -2
- package/scripts/lib/vault-status/narrative-mirror.mjs +127 -18
- package/scripts/lib/wave-executor/dispatch-common.mjs +164 -0
- package/scripts/lib/wave-executor/foreign-dispatch.mjs +7 -142
- package/scripts/lib/wave-executor/remote-dispatch.mjs +5 -7
- package/scripts/lib/wave-resource-gate.mjs +8 -2
- package/scripts/lib/wave-sizing.mjs +4 -1
- package/scripts/lib/wave-transcript-tail.mjs +118 -4
- package/scripts/materialize-wave-scope.mjs +12 -5
- package/scripts/memory-propose.mjs +19 -5
- package/scripts/migrate-cold-start-seed.mjs +4 -1
- package/scripts/parse-config.mjs +60 -3
- package/scripts/release.mjs +337 -29
- package/scripts/repair-invalid-sessions.mjs +3 -3
- package/scripts/run-quality-gate.mjs +128 -11
- package/scripts/sweep-expired-learnings.mjs +90 -0
- package/scripts/sync-vault-schema.mjs +3 -1
- package/scripts/telemetry.mjs +2 -2
- package/scripts/validate-plugin.mjs +161 -0
- package/scripts/validate-wave-scope.mjs +28 -8
- package/scripts/wave-scope-binding.mjs +215 -0
- package/skills/_shared/instruction-file-resolution.md +10 -0
- package/skills/_shared/parallel-aware-preamble.md +1 -0
- package/skills/_shared/platform-tools.md +1 -1
- package/skills/_shared/state-ownership.md +1 -1
- package/skills/architecture/SKILL.md +7 -5
- package/skills/{domain-model/SKILL.md → architecture/references/domain-model.md} +9 -9
- package/skills/autopilot/SKILL.md +4 -18
- package/skills/claude-md-drift-check/SKILL.md +5 -1
- package/skills/claude-md-drift-check/checker.mjs +62 -2
- package/skills/convergence-monitoring/SIGNALS.md +55 -0
- package/skills/discovery/probes/vault-staleness.mjs +37 -13
- package/skills/discovery/probes-arch.md +20 -18
- package/skills/dispatcher/SKILL.md +3 -2
- package/skills/evolve/SKILL.md +65 -26
- package/skills/frontmatter-guard/SKILL.md +11 -5
- package/skills/npm-publish/SKILL.md +1 -1
- package/skills/reconcile/SKILL.md +33 -0
- package/skills/remote-offload/SKILL.md +1 -1
- package/skills/session-end/SKILL.md +18 -905
- package/skills/session-end/phase-3-6-tail.md +10 -3
- package/skills/session-end/plan-verification.md +221 -155
- package/skills/session-end/references/phase-2-quality-gate.md +93 -0
- package/skills/session-end/references/phase-3-documentation-updates.md +229 -0
- package/skills/session-end/references/phase-4a-worktree-cleanup.md +120 -0
- package/skills/session-end/references/phase-4b-worktree-orphan-sweep.md +58 -0
- package/skills/session-end/references/phase-5-issue-cleanup.md +104 -0
- package/skills/session-end/references/session-summary-template.md +62 -0
- package/skills/session-plan/SKILL.md +49 -0
- package/skills/session-start/SKILL.md +22 -904
- package/skills/session-start/phase-8-5-express-path.md +1 -1
- package/skills/session-start/references/phase-1-1-dispatcher-autonomy-capture.md +55 -0
- package/skills/session-start/references/phase-1-2-session-lock.md +140 -0
- package/skills/session-start/references/phase-1-5-session-continuity.md +254 -0
- package/skills/session-start/references/phase-1-7-vault-status-board.md +53 -0
- package/skills/session-start/references/phase-2-7-portfolio-snapshot.md +75 -0
- package/skills/session-start/references/phase-4-ssot-environment-check.md +155 -0
- package/skills/session-start/references/phase-6-5-forced-reads.md +75 -0
- package/skills/session-start/references/phase-6-6-project-intelligence.md +81 -0
- package/skills/session-start/references/phase-6-7-memory-banner-telemetry-consent.md +103 -0
- package/skills/vault-sync/validator.mjs +21 -27
- package/skills/wave-executor/SKILL.md +15 -1
- package/skills/wave-executor/references/wave-loop-dispatch.md +612 -0
- package/skills/wave-executor/references/wave-loop-review.md +570 -0
- package/skills/wave-executor/references/wave-loop-scope-manifest.md +162 -0
- package/skills/wave-executor/wave-loop.md +14 -1309
- package/templates/_shared/journey-manifest.md +10 -6
- package/.cursor/commands/autopilot-multi.md +0 -14
- package/.cursor/commands/contract-version-bump.md +0 -14
- package/.cursor/commands/journey-audit.md +0 -14
- package/.cursor/skills/contract-version-bump/SKILL.md +0 -12
- package/.cursor/skills/daily/SKILL.md +0 -12
- package/.cursor/skills/domain-model/SKILL.md +0 -13
- package/.cursor/skills/journey-audit/SKILL.md +0 -13
- package/.cursor/skills/skill-creator/SKILL.md +0 -13
- package/.cursor/skills/ubiquitous-language/SKILL.md +0 -13
- package/commands/autopilot-multi.md +0 -74
- package/commands/contract-version-bump.md +0 -28
- package/commands/journey-audit.md +0 -43
- package/pi/prompts/autopilot-multi.md +0 -12
- package/pi/prompts/contract-version-bump.md +0 -12
- package/pi/prompts/journey-audit.md +0 -12
- package/scripts/autopilot-multi.mjs +0 -885
- package/scripts/backfill-learnings-expires.mjs +0 -196
- package/scripts/backfill-learnings.mjs +0 -203
- package/scripts/fleet-instruction-scan.mjs +0 -141
- package/scripts/lib/autopilot/dep-graph.mjs +0 -417
- package/scripts/lib/autopilot/multi-killswitch.mjs +0 -184
- package/scripts/lib/webhook-url.mjs +0 -105
- package/scripts/lifecycle-sim-v6.mjs +0 -347
- package/scripts/migrate-learnings-jsonl.mjs +0 -189
- package/scripts/migrate-subagents-jsonl.mjs +0 -196
- package/scripts/upload-social-preview.mjs +0 -316
- package/skills/_shared/model-selection.md +0 -64
- package/skills/contract-version-bump/SKILL.md +0 -219
- package/skills/daily/SKILL.md +0 -222
- package/skills/daily/generate.sh +0 -92
- package/skills/daily/templates/daily.md.tpl +0 -36
- package/skills/journey-audit/SKILL.md +0 -270
- package/skills/skill-creator/SKILL.md +0 -168
- package/skills/ubiquitous-language/SKILL.md +0 -97
- package/skills/vault-sync/package-lock.json +0 -40
- /package/skills/{domain-model → architecture/references}/ADR-FORMAT.md +0 -0
- /package/skills/{domain-model → architecture/references}/CONTEXT-FORMAT.md +0 -0
|
@@ -1,196 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
/**
|
|
3
|
-
* migrate-subagents-jsonl.mjs — one-shot migration helper for subagents.jsonl.
|
|
4
|
-
*
|
|
5
|
-
* Mirrors migrate-learnings-jsonl.mjs structure. Applies the migrate /
|
|
6
|
-
* normalize / validate pipeline from subagents-schema.mjs to every record.
|
|
7
|
-
*
|
|
8
|
-
* For schema_version 1 (current), migrateLegacySubagent() is a no-op that
|
|
9
|
-
* only stamps a missing schema_version. The script is structurally complete
|
|
10
|
-
* and produces a 1:1 pass-through — ready for future schema bumps without
|
|
11
|
-
* code changes.
|
|
12
|
-
*
|
|
13
|
-
* Usage:
|
|
14
|
-
* node scripts/migrate-subagents-jsonl.mjs [--source <path>] [--dry-run] [--apply]
|
|
15
|
-
*
|
|
16
|
-
* Flags:
|
|
17
|
-
* --source <path> Path to subagents.jsonl
|
|
18
|
-
* (default: .orchestrator/metrics/subagents.jsonl)
|
|
19
|
-
* --dry-run Preview changes without writing (DEFAULT)
|
|
20
|
-
* --apply Write migrated records back to the file
|
|
21
|
-
*
|
|
22
|
-
* Exit codes:
|
|
23
|
-
* 0 Success (including no-op if everything is already canonical)
|
|
24
|
-
* 1 Input/validation error (or --apply had failed-validation records)
|
|
25
|
-
* 2 I/O error
|
|
26
|
-
*
|
|
27
|
-
* Idempotent: running --apply a second time produces no further changes.
|
|
28
|
-
*
|
|
29
|
-
* Output (stdout — one JSON object per line):
|
|
30
|
-
* {"action":"migrated"|"already-canonical"|"failed-validation","id":"...","changes":[...]}
|
|
31
|
-
*
|
|
32
|
-
* Summary line (stderr):
|
|
33
|
-
* migrate-subagents: N migrated, M already-canonical, K failed-validation [dry-run|applied]
|
|
34
|
-
*/
|
|
35
|
-
|
|
36
|
-
import { existsSync, readFileSync, writeFileSync, renameSync, mkdirSync } from 'node:fs';
|
|
37
|
-
import { dirname } from 'node:path';
|
|
38
|
-
import {
|
|
39
|
-
migrateLegacySubagent,
|
|
40
|
-
normalizeSubagent,
|
|
41
|
-
validateSubagent,
|
|
42
|
-
ValidationError,
|
|
43
|
-
} from './lib/subagents-schema.mjs';
|
|
44
|
-
|
|
45
|
-
// ---------------------------------------------------------------------------
|
|
46
|
-
// Arg parsing
|
|
47
|
-
// ---------------------------------------------------------------------------
|
|
48
|
-
|
|
49
|
-
const args = process.argv.slice(2);
|
|
50
|
-
const helpFlag = args.includes('--help') || args.includes('-h');
|
|
51
|
-
if (helpFlag) {
|
|
52
|
-
process.stdout.write(`Usage: migrate-subagents-jsonl.mjs [--source <path>] [--dry-run] [--apply]
|
|
53
|
-
|
|
54
|
-
Options:
|
|
55
|
-
--source <path> Path to subagents.jsonl
|
|
56
|
-
(default: .orchestrator/metrics/subagents.jsonl)
|
|
57
|
-
--dry-run Preview changes without writing (DEFAULT)
|
|
58
|
-
--apply Write migrated records back to the file
|
|
59
|
-
|
|
60
|
-
Output (stdout — one JSON object per line):
|
|
61
|
-
{"action":"migrated"|"already-canonical"|"failed-validation","id":"...","changes":[...]}
|
|
62
|
-
|
|
63
|
-
Exit codes: 0 success 1 input/validation error 2 I/O error
|
|
64
|
-
`);
|
|
65
|
-
process.exit(0);
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
const applyFlag = args.includes('--apply');
|
|
69
|
-
const dryRun = !applyFlag; // default is --dry-run
|
|
70
|
-
|
|
71
|
-
const sourceIdx = args.indexOf('--source');
|
|
72
|
-
const sourcePath =
|
|
73
|
-
sourceIdx !== -1 && args[sourceIdx + 1]
|
|
74
|
-
? args[sourceIdx + 1]
|
|
75
|
-
: '.orchestrator/metrics/subagents.jsonl';
|
|
76
|
-
|
|
77
|
-
// ---------------------------------------------------------------------------
|
|
78
|
-
// Load
|
|
79
|
-
// ---------------------------------------------------------------------------
|
|
80
|
-
|
|
81
|
-
if (!existsSync(sourcePath)) {
|
|
82
|
-
process.stderr.write(`migrate-subagents: source file not found: ${sourcePath}\n`);
|
|
83
|
-
process.exit(1);
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
let raw;
|
|
87
|
-
try {
|
|
88
|
-
raw = readFileSync(sourcePath, 'utf8');
|
|
89
|
-
} catch (err) {
|
|
90
|
-
process.stderr.write(`migrate-subagents: failed to read ${sourcePath}: ${err.message}\n`);
|
|
91
|
-
process.exit(2);
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
const lines = raw.split('\n').filter((l) => l.trim().length > 0);
|
|
95
|
-
|
|
96
|
-
// ---------------------------------------------------------------------------
|
|
97
|
-
// Migrate
|
|
98
|
-
// ---------------------------------------------------------------------------
|
|
99
|
-
|
|
100
|
-
let countMigrated = 0;
|
|
101
|
-
let countCanonical = 0;
|
|
102
|
-
let countFailedValidation = 0;
|
|
103
|
-
let countMalformed = 0;
|
|
104
|
-
|
|
105
|
-
const outputLines = [];
|
|
106
|
-
|
|
107
|
-
for (const line of lines) {
|
|
108
|
-
let parsed;
|
|
109
|
-
try {
|
|
110
|
-
parsed = JSON.parse(line);
|
|
111
|
-
} catch {
|
|
112
|
-
countMalformed++;
|
|
113
|
-
process.stderr.write(
|
|
114
|
-
`migrate-subagents: WARN skipping malformed JSON line: ${line.slice(0, 80)}\n`
|
|
115
|
-
);
|
|
116
|
-
// Preserve the original malformed line as-is (do not discard data).
|
|
117
|
-
outputLines.push(line);
|
|
118
|
-
continue;
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
// Detect which fields would be stamped by migrateLegacySubagent.
|
|
122
|
-
const changes = [];
|
|
123
|
-
if (parsed.schema_version === undefined || parsed.schema_version === null) {
|
|
124
|
-
changes.push('schema_version:1');
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
const migrated = migrateLegacySubagent(parsed);
|
|
128
|
-
const normalized = normalizeSubagent(migrated);
|
|
129
|
-
|
|
130
|
-
let validated;
|
|
131
|
-
try {
|
|
132
|
-
validated = validateSubagent(normalized);
|
|
133
|
-
} catch (err) {
|
|
134
|
-
countFailedValidation++;
|
|
135
|
-
const reason = err instanceof ValidationError ? err.message : String(err);
|
|
136
|
-
const id = parsed.agent_id ?? null;
|
|
137
|
-
process.stderr.write(
|
|
138
|
-
`migrate-subagents: WARN record agent_id=${id ?? '<no agent_id>'} still fails validation` +
|
|
139
|
-
` after migration: ${reason}\n`
|
|
140
|
-
);
|
|
141
|
-
// Preserve original line — do not destroy unmigratable records.
|
|
142
|
-
outputLines.push(line);
|
|
143
|
-
process.stdout.write(
|
|
144
|
-
JSON.stringify({ action: 'failed-validation', id, reason, changes }) + '\n'
|
|
145
|
-
);
|
|
146
|
-
continue;
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
if (changes.length === 0) {
|
|
150
|
-
countCanonical++;
|
|
151
|
-
outputLines.push(JSON.stringify(validated));
|
|
152
|
-
process.stdout.write(
|
|
153
|
-
JSON.stringify({ action: 'already-canonical', id: validated.agent_id }) + '\n'
|
|
154
|
-
);
|
|
155
|
-
} else {
|
|
156
|
-
countMigrated++;
|
|
157
|
-
outputLines.push(JSON.stringify(validated));
|
|
158
|
-
process.stdout.write(
|
|
159
|
-
JSON.stringify({ action: 'migrated', id: validated.agent_id, changes }) + '\n'
|
|
160
|
-
);
|
|
161
|
-
}
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
// ---------------------------------------------------------------------------
|
|
165
|
-
// Write (--apply only)
|
|
166
|
-
// ---------------------------------------------------------------------------
|
|
167
|
-
|
|
168
|
-
const modeLabel = dryRun ? 'dry-run' : 'applied';
|
|
169
|
-
|
|
170
|
-
if (!dryRun) {
|
|
171
|
-
const body = outputLines.join('\n') + '\n';
|
|
172
|
-
const tmp = `${sourcePath}.migrate-tmp-${process.pid}-${Date.now()}`;
|
|
173
|
-
try {
|
|
174
|
-
mkdirSync(dirname(sourcePath), { recursive: true });
|
|
175
|
-
writeFileSync(tmp, body, 'utf8');
|
|
176
|
-
renameSync(tmp, sourcePath);
|
|
177
|
-
} catch (err) {
|
|
178
|
-
process.stderr.write(
|
|
179
|
-
`migrate-subagents: ERROR failed to write ${sourcePath}: ${err.message}\n`
|
|
180
|
-
);
|
|
181
|
-
// Attempt cleanup of tmp.
|
|
182
|
-
try { if (existsSync(tmp)) renameSync(tmp, tmp + '.failed'); } catch { /* ignore */ }
|
|
183
|
-
process.exit(2);
|
|
184
|
-
}
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
// ---------------------------------------------------------------------------
|
|
188
|
-
// Summary
|
|
189
|
-
// ---------------------------------------------------------------------------
|
|
190
|
-
|
|
191
|
-
process.stderr.write(
|
|
192
|
-
`migrate-subagents: ${countMigrated} migrated, ${countCanonical} already-canonical, ` +
|
|
193
|
-
`${countFailedValidation} failed-validation, ${countMalformed} malformed [${modeLabel}]\n`
|
|
194
|
-
);
|
|
195
|
-
|
|
196
|
-
process.exit(countFailedValidation > 0 ? 1 : 0);
|
|
@@ -1,316 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
/* global document */
|
|
3
|
-
/**
|
|
4
|
-
* scripts/upload-social-preview.mjs
|
|
5
|
-
*
|
|
6
|
-
* Uploads an arbitrary image file as a GitHub repository's social-preview image.
|
|
7
|
-
* Fills the gap left by upstream tools that only support README screenshots
|
|
8
|
-
* (AnswerDotAI/gh-social-preview) or Socialify-generated cards (mheap/github-social-image).
|
|
9
|
-
*
|
|
10
|
-
* Why Playwright instead of the gh CLI:
|
|
11
|
-
* GitHub has no REST/GraphQL endpoint for setting the social-preview image.
|
|
12
|
-
* Verified empirically: PATCH /repos/{owner}/{repo} silently ignores
|
|
13
|
-
* `social_preview_image_url`; github.com web endpoints reject Bearer tokens
|
|
14
|
-
* (require `_gh_sess` session cookie). Multiple GitHub community discussions
|
|
15
|
-
* confirm this: orgs/community/discussions/52294, /172072, /49928.
|
|
16
|
-
*
|
|
17
|
-
* The only working path is browser automation against the Settings UI flow,
|
|
18
|
-
* which is what every tool in this space does (gh-social-preview, mheap/
|
|
19
|
-
* github-social-image, drogers0/gh-image — different scopes, same approach).
|
|
20
|
-
*
|
|
21
|
-
* Authentication:
|
|
22
|
-
* Reuses the storageState produced by `gh-social-preview init-auth`
|
|
23
|
-
* (default: ~/.local/state/gh-social-preview/auth/github.json). Run that
|
|
24
|
-
* once per host; subsequent uploads use the saved session.
|
|
25
|
-
*
|
|
26
|
-
* Upload logic adapted from AnswerDotAI/gh-social-preview's uploadSocialPreview
|
|
27
|
-
* function (ISC-licensed, Jeremy Howard). The selectors and the
|
|
28
|
-
* /upload/repository-images/ response-monitoring approach come from that tool.
|
|
29
|
-
*
|
|
30
|
-
* Usage:
|
|
31
|
-
* node scripts/upload-social-preview.mjs --repo owner/repo --image path/to.png
|
|
32
|
-
*
|
|
33
|
-
* Options:
|
|
34
|
-
* --repo owner/repo or full GitHub URL (required)
|
|
35
|
-
* --image path to PNG/JPG/GIF, < 1 MB (required)
|
|
36
|
-
* --storage-state path to Playwright storageState JSON
|
|
37
|
-
* default: ~/.local/state/gh-social-preview/auth/github.json
|
|
38
|
-
* --base-url GitHub base URL (default: https://github.com)
|
|
39
|
-
* --headless true|false (default: true)
|
|
40
|
-
*/
|
|
41
|
-
|
|
42
|
-
import fs from 'node:fs';
|
|
43
|
-
import os from 'node:os';
|
|
44
|
-
import path from 'node:path';
|
|
45
|
-
import { createRequire } from 'node:module';
|
|
46
|
-
|
|
47
|
-
const require = createRequire(import.meta.url);
|
|
48
|
-
|
|
49
|
-
function parseArgs(argv) {
|
|
50
|
-
const out = { _: [] };
|
|
51
|
-
for (let i = 0; i < argv.length; i++) {
|
|
52
|
-
const a = argv[i];
|
|
53
|
-
if (a.startsWith('--')) {
|
|
54
|
-
const key = a.slice(2);
|
|
55
|
-
const next = argv[i + 1];
|
|
56
|
-
if (!next || next.startsWith('--')) out[key] = true;
|
|
57
|
-
else { out[key] = next; i++; }
|
|
58
|
-
} else {
|
|
59
|
-
out._.push(a);
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
return out;
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
function toBool(v, defVal) {
|
|
66
|
-
if (v === undefined) return defVal;
|
|
67
|
-
if (typeof v === 'boolean') return v;
|
|
68
|
-
const s = String(v).toLowerCase().trim();
|
|
69
|
-
if (['1','true','yes','y','on'].includes(s)) return true;
|
|
70
|
-
if (['0','false','no','n','off'].includes(s)) return false;
|
|
71
|
-
return defVal;
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
function normalizeRepo(repoOrUrl) {
|
|
75
|
-
const s = String(repoOrUrl || '').trim();
|
|
76
|
-
if (!s) throw new Error('Missing --repo (expected owner/repo or a GitHub repo URL)');
|
|
77
|
-
if (s.includes('://')) {
|
|
78
|
-
const u = new URL(s);
|
|
79
|
-
const parts = u.pathname.split('/').filter(Boolean);
|
|
80
|
-
if (parts.length < 2) throw new Error(`Invalid repo URL: ${s}`);
|
|
81
|
-
return `${parts[0]}/${parts[1]}`;
|
|
82
|
-
}
|
|
83
|
-
if (/^[A-Za-z0-9_.-]+\/[A-Za-z0-9_.-]+$/.test(s)) return s;
|
|
84
|
-
throw new Error(`Invalid --repo "${s}". Expected "owner/repo" or a GitHub URL.`);
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
function defaultStoragePath() {
|
|
88
|
-
const stateHome = process.env.XDG_STATE_HOME || path.join(os.homedir(), '.local', 'state');
|
|
89
|
-
return path.join(stateHome, 'gh-social-preview', 'auth', 'github.json');
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
function loadPlaywright() {
|
|
93
|
-
// Try several resolutions: local node_modules, gh-social-preview's npx cache, sibling installs.
|
|
94
|
-
const candidates = [
|
|
95
|
-
'playwright',
|
|
96
|
-
'playwright-core',
|
|
97
|
-
];
|
|
98
|
-
for (const c of candidates) {
|
|
99
|
-
try {
|
|
100
|
-
const mod = require(c);
|
|
101
|
-
if (mod?.chromium) return mod;
|
|
102
|
-
} catch { /* try next */ }
|
|
103
|
-
}
|
|
104
|
-
// Fallback: scan ~/.npm/_npx for a gh-social-preview install
|
|
105
|
-
const npxRoot = path.join(os.homedir(), '.npm', '_npx');
|
|
106
|
-
if (fs.existsSync(npxRoot)) {
|
|
107
|
-
for (const entry of fs.readdirSync(npxRoot)) {
|
|
108
|
-
const p = path.join(npxRoot, entry, 'node_modules', 'playwright');
|
|
109
|
-
if (fs.existsSync(path.join(p, 'index.js'))) {
|
|
110
|
-
try { return require(p); } catch { /* try next */ }
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
throw new Error(
|
|
115
|
-
'playwright not found. Install with one of:\n' +
|
|
116
|
-
' - npx --yes -p playwright -- node scripts/upload-social-preview.mjs ...\n' +
|
|
117
|
-
' - npm install --no-save --ignore-scripts playwright\n' +
|
|
118
|
-
'Browsers must already be present at ~/Library/Caches/ms-playwright/ (chromium-*).\n' +
|
|
119
|
-
'Run `npx playwright install chromium` once if missing.'
|
|
120
|
-
);
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
async function uploadSocialPreview({ repo, imagePath, storageStatePath, baseUrl, headless }) {
|
|
124
|
-
if (!fs.existsSync(imagePath)) throw new Error(`Image file not found: ${imagePath}`);
|
|
125
|
-
if (!fs.existsSync(storageStatePath)) {
|
|
126
|
-
throw new Error(
|
|
127
|
-
`Storage state not found at "${storageStatePath}". Run:\n` +
|
|
128
|
-
` npx --yes gh-social-preview init-auth --storage-state ${storageStatePath}\n` +
|
|
129
|
-
'to create it once (interactive browser login).'
|
|
130
|
-
);
|
|
131
|
-
}
|
|
132
|
-
const size = fs.statSync(imagePath).size;
|
|
133
|
-
if (size > 1_000_000) {
|
|
134
|
-
throw new Error(
|
|
135
|
-
`Image size ${size} bytes exceeds GitHub's 1 MB social-preview limit. ` +
|
|
136
|
-
'Re-export at smaller dimensions or higher PNG compression.'
|
|
137
|
-
);
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
const { chromium } = loadPlaywright();
|
|
141
|
-
const settingsUrl = `${baseUrl}/${repo}/settings`;
|
|
142
|
-
|
|
143
|
-
const browser = await chromium.launch({ headless });
|
|
144
|
-
const context = await browser.newContext({ storageState: storageStatePath });
|
|
145
|
-
const page = await context.newPage();
|
|
146
|
-
page.setDefaultTimeout(60_000);
|
|
147
|
-
|
|
148
|
-
console.log(`[upload] Opening ${settingsUrl}`);
|
|
149
|
-
await page.goto(settingsUrl, { waitUntil: 'domcontentloaded' });
|
|
150
|
-
|
|
151
|
-
if (page.url().includes('/login')) {
|
|
152
|
-
await browser.close();
|
|
153
|
-
throw new Error('Session expired — redirected to /login. Re-run init-auth.');
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
const socialHeading = page.locator("xpath=//h2[normalize-space()='Social preview']").first();
|
|
157
|
-
const editButton = page.locator('#edit-social-preview-button');
|
|
158
|
-
const socialEditButton = page.locator(
|
|
159
|
-
"xpath=(//h2[normalize-space()='Social preview']/following::*[(self::button or self::summary) and normalize-space(.)='Edit'][1])"
|
|
160
|
-
);
|
|
161
|
-
const fileInput = page.locator('input#repo-image-file-input');
|
|
162
|
-
const uploadMenuItem = page.getByText(/upload an image/i).first();
|
|
163
|
-
const imageIdInput = page.locator('input.js-repository-image-id');
|
|
164
|
-
const imageContainer = page.locator('.js-repository-image-container');
|
|
165
|
-
|
|
166
|
-
console.log('[upload] Waiting for Social preview section');
|
|
167
|
-
await socialHeading.waitFor({ state: 'attached', timeout: 60_000 });
|
|
168
|
-
await socialHeading.scrollIntoViewIfNeeded().catch(() => {});
|
|
169
|
-
|
|
170
|
-
let prevId = '';
|
|
171
|
-
if (await imageIdInput.count()) {
|
|
172
|
-
prevId = (await imageIdInput.first().inputValue().catch(() => '')).trim();
|
|
173
|
-
}
|
|
174
|
-
const mode = prevId ? 'replace' : 'add';
|
|
175
|
-
console.log(`[upload] Social preview mode: ${mode} (prevId="${prevId}")`);
|
|
176
|
-
|
|
177
|
-
if (await editButton.count()) {
|
|
178
|
-
await editButton.first().click({ force: true }).catch(() => {});
|
|
179
|
-
} else if (await socialEditButton.count()) {
|
|
180
|
-
await socialEditButton.first().click({ force: true }).catch(() => {});
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
console.log('[upload] Waiting for upload controls');
|
|
184
|
-
await Promise.any([
|
|
185
|
-
fileInput.first().waitFor({ state: 'attached', timeout: 30_000 }),
|
|
186
|
-
uploadMenuItem.waitFor({ state: 'visible', timeout: 30_000 }),
|
|
187
|
-
]);
|
|
188
|
-
|
|
189
|
-
console.log(`[upload] Uploading ${imagePath} (${size} bytes)`);
|
|
190
|
-
|
|
191
|
-
const uploadResponsePromise = page.waitForResponse((resp) => {
|
|
192
|
-
const u = resp.url();
|
|
193
|
-
const ok = resp.status() >= 200 && resp.status() < 300;
|
|
194
|
-
if (!ok) return false;
|
|
195
|
-
return u.includes('/upload/repository-images/') || u.includes('/upload/policies/repository-images');
|
|
196
|
-
}, { timeout: 30_000 }).then(r => `${r.status()} ${r.url()}`).catch(() => '');
|
|
197
|
-
|
|
198
|
-
if (await fileInput.count()) {
|
|
199
|
-
await fileInput.first().setInputFiles(imagePath);
|
|
200
|
-
} else {
|
|
201
|
-
const [chooser] = await Promise.all([
|
|
202
|
-
page.waitForEvent('filechooser'),
|
|
203
|
-
uploadMenuItem.click({ force: true }),
|
|
204
|
-
]);
|
|
205
|
-
await chooser.setFiles(imagePath);
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
const uploadUrl = await uploadResponsePromise;
|
|
209
|
-
if (uploadUrl) console.log(`[upload] Upload response: ${uploadUrl}`);
|
|
210
|
-
else console.warn('[upload] Upload response not observed — using DOM fallback');
|
|
211
|
-
|
|
212
|
-
let idChanged = false;
|
|
213
|
-
if (!uploadUrl) {
|
|
214
|
-
try {
|
|
215
|
-
await page.waitForFunction(
|
|
216
|
-
({ prevId }) => {
|
|
217
|
-
const input = document.querySelector('input.js-repository-image-id');
|
|
218
|
-
if (!input) return false;
|
|
219
|
-
const v = (input.value || '').trim();
|
|
220
|
-
if (!v) return false;
|
|
221
|
-
if (!prevId) return true;
|
|
222
|
-
return v !== prevId;
|
|
223
|
-
},
|
|
224
|
-
{ prevId },
|
|
225
|
-
{ timeout: 30_000 }
|
|
226
|
-
);
|
|
227
|
-
idChanged = true;
|
|
228
|
-
} catch { /* fallthrough */ }
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
await page.waitForFunction(
|
|
232
|
-
() => {
|
|
233
|
-
const input = document.querySelector('input.js-repository-image-id');
|
|
234
|
-
return !!((input?.value || '').trim());
|
|
235
|
-
},
|
|
236
|
-
{ timeout: 30_000 }
|
|
237
|
-
).catch(() => {});
|
|
238
|
-
|
|
239
|
-
if (await imageContainer.count()) {
|
|
240
|
-
await page.waitForFunction(
|
|
241
|
-
() => {
|
|
242
|
-
const el = document.querySelector('.js-repository-image-container');
|
|
243
|
-
return el && el.hidden === false;
|
|
244
|
-
},
|
|
245
|
-
{ timeout: 30_000 }
|
|
246
|
-
).catch(() => {});
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
const newId = (await imageIdInput.first().inputValue().catch(() => '') || '').trim();
|
|
250
|
-
await browser.close();
|
|
251
|
-
|
|
252
|
-
if (!newId) throw new Error('Upload did not produce a social-preview image id.');
|
|
253
|
-
if (!idChanged && prevId && newId === prevId) {
|
|
254
|
-
console.warn('[upload] image id unchanged — likely re-uploaded identical content');
|
|
255
|
-
}
|
|
256
|
-
|
|
257
|
-
return { ok: true, newId, prevId, mode, uploadUrl: uploadUrl || null };
|
|
258
|
-
}
|
|
259
|
-
|
|
260
|
-
function printHelp() {
|
|
261
|
-
console.log(`Usage:
|
|
262
|
-
node scripts/upload-social-preview.mjs --repo owner/repo --image path/to.png [options]
|
|
263
|
-
|
|
264
|
-
Options:
|
|
265
|
-
--repo owner/repo or full GitHub URL (required)
|
|
266
|
-
--image path to PNG/JPG/GIF, < 1 MB (required)
|
|
267
|
-
--storage-state path to Playwright storageState JSON
|
|
268
|
-
(default: ~/.local/state/gh-social-preview/auth/github.json)
|
|
269
|
-
--base-url GitHub base URL (default: https://github.com)
|
|
270
|
-
--headless true|false (default: true)
|
|
271
|
-
-h, --help show this help
|
|
272
|
-
|
|
273
|
-
First-time setup (per host, once):
|
|
274
|
-
npx --yes gh-social-preview init-auth
|
|
275
|
-
# Interactive browser login, saves storage state.
|
|
276
|
-
|
|
277
|
-
Then upload:
|
|
278
|
-
node scripts/upload-social-preview.mjs \\
|
|
279
|
-
--repo Kanevry/session-orchestrator \\
|
|
280
|
-
--image assets/og-card.png
|
|
281
|
-
|
|
282
|
-
Why this script exists:
|
|
283
|
-
GitHub has NO REST/GraphQL endpoint for the social-preview image upload —
|
|
284
|
-
it is only settable via the web UI. Verified empirically: PATCH
|
|
285
|
-
/repos/{owner}/{repo} silently ignores social_preview_image_url; the
|
|
286
|
-
github.com web endpoints reject Bearer tokens (require _gh_sess cookie).
|
|
287
|
-
This script automates the UI flow via Playwright, reusing the auth
|
|
288
|
-
storageState from AnswerDotAI/gh-social-preview's init-auth.
|
|
289
|
-
`);
|
|
290
|
-
}
|
|
291
|
-
|
|
292
|
-
async function main() {
|
|
293
|
-
const args = parseArgs(process.argv.slice(2));
|
|
294
|
-
if (args.help || args.h || args._[0] === 'help') { printHelp(); return; }
|
|
295
|
-
if (!args.repo || !args.image) { printHelp(); process.exit(1); }
|
|
296
|
-
|
|
297
|
-
const repo = normalizeRepo(args.repo);
|
|
298
|
-
const imagePath = path.resolve(String(args.image));
|
|
299
|
-
const storageStatePath = args['storage-state']
|
|
300
|
-
? path.resolve(String(args['storage-state']))
|
|
301
|
-
: defaultStoragePath();
|
|
302
|
-
const baseUrl = String(args['base-url'] || 'https://github.com').replace(/\/$/, '');
|
|
303
|
-
const headless = toBool(args.headless, true);
|
|
304
|
-
|
|
305
|
-
const result = await uploadSocialPreview({ repo, imagePath, storageStatePath, baseUrl, headless });
|
|
306
|
-
console.log(JSON.stringify(result, null, 2));
|
|
307
|
-
console.log(`\n✅ Social preview uploaded for ${repo}`);
|
|
308
|
-
console.log(` Mode: ${result.mode}, new image id: ${result.newId}`);
|
|
309
|
-
console.log(` Verify at: ${baseUrl}/${repo}/settings#social-preview`);
|
|
310
|
-
}
|
|
311
|
-
|
|
312
|
-
main().catch((err) => {
|
|
313
|
-
console.error(`\n❌ ${err?.message || err}\n`);
|
|
314
|
-
if (err?.stack && process.env.DEBUG) console.error(err.stack);
|
|
315
|
-
process.exit(1);
|
|
316
|
-
});
|
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
# Model Selection Reference
|
|
2
|
-
|
|
3
|
-
Shared reference for session-plan and wave-executor when determining which model to use for agent dispatch.
|
|
4
|
-
|
|
5
|
-
## Priority Order
|
|
6
|
-
|
|
7
|
-
1. **Agent definition** — if the agent `.md` file has a `model:` frontmatter field, use it (e.g., a domain-specific `compliance-reviewer` agent might specify `opus`)
|
|
8
|
-
2. **Task-type matrix** — use the table below based on what the agent will do
|
|
9
|
-
3. **Wave role default** — if neither of the above applies
|
|
10
|
-
|
|
11
|
-
## Claude Code Model Matrix
|
|
12
|
-
|
|
13
|
-
| Task Type | Model | Rationale |
|
|
14
|
-
|-----------|-------|-----------|
|
|
15
|
-
| File exploration, git history, pattern search | `haiku` | Fast, cost-effective, read-only |
|
|
16
|
-
| Standard implementation (features, APIs, refactoring) | `sonnet` | Balance of speed and quality |
|
|
17
|
-
| Test writing | `sonnet` | Pattern recognition + code generation |
|
|
18
|
-
| UI/Frontend implementation | `sonnet` | Component composition, styling |
|
|
19
|
-
| Database schema, migrations | `sonnet` | Structural reasoning |
|
|
20
|
-
| Security review | `sonnet` | Analytical depth for vulnerability detection |
|
|
21
|
-
| Quality review (session-reviewer) | `sonnet` | Code analysis, pattern matching |
|
|
22
|
-
| Architecture decisions, complex planning | `opus` | Nuanced trade-off reasoning |
|
|
23
|
-
| Legal/compliance analysis (domain-specific) | `opus` | Zero tolerance for errors |
|
|
24
|
-
| Session orchestration (session-start, session-plan) | `opus` | Complex coordination, multi-source synthesis |
|
|
25
|
-
|
|
26
|
-
## Wave Role Defaults
|
|
27
|
-
|
|
28
|
-
| Wave Role | Default Model |
|
|
29
|
-
|-----------|---------------|
|
|
30
|
-
| Discovery | `haiku` (via Explore subagent) |
|
|
31
|
-
| Impl-Core | `sonnet` |
|
|
32
|
-
| Impl-Polish | `sonnet` |
|
|
33
|
-
| Quality | `sonnet` |
|
|
34
|
-
| Finalization | inherits coordinator model (direct execution) |
|
|
35
|
-
|
|
36
|
-
## Cross-Platform Equivalents
|
|
37
|
-
|
|
38
|
-
### Codex CLI
|
|
39
|
-
|
|
40
|
-
| Claude Code | Codex CLI |
|
|
41
|
-
|-------------|-----------|
|
|
42
|
-
| `haiku` | `gpt-5.4-mini` |
|
|
43
|
-
| `sonnet` | `gpt-5.4-mini` |
|
|
44
|
-
| `opus` | `gpt-5.4` |
|
|
45
|
-
|
|
46
|
-
### Cursor IDE
|
|
47
|
-
|
|
48
|
-
Cursor uses Claude models directly:
|
|
49
|
-
- `claude-opus-4-6` for planning and complex tasks
|
|
50
|
-
- `claude-sonnet-4-6` for implementation and review
|
|
51
|
-
|
|
52
|
-
## Usage in Agent Dispatch
|
|
53
|
-
|
|
54
|
-
When dispatching via the Agent tool, set the `model` parameter only when overriding the agent's default:
|
|
55
|
-
|
|
56
|
-
```
|
|
57
|
-
Agent({
|
|
58
|
-
subagent_type: "session-orchestrator:code-implementer",
|
|
59
|
-
model: "sonnet", // only needed if overriding the agent's frontmatter model
|
|
60
|
-
...
|
|
61
|
-
})
|
|
62
|
-
```
|
|
63
|
-
|
|
64
|
-
If the agent definition already specifies `model: sonnet`, omitting the `model` parameter in the dispatch is sufficient — the agent's frontmatter takes effect automatically.
|