From f32b33ba9851477b76ff46d8c77d9450ccb6db72 Mon Sep 17 00:00:00 2001 From: arzafran Date: Wed, 3 Jun 2026 09:30:18 -0300 Subject: [PATCH] chore: retire upstream-sync cron, sync manifest to 2.1.161 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The daily upstream-sync GitHub Action could only bump a version number and dump the drift string into a PR body — it never read the changelog, so it was blind to new features, settings keys, env vars, hook events, and dedupe opportunities (its diffSets compares the manifest against our own zod schema, not upstream). That triage is the human /cc sync skill's job; the bot's PRs looked actionable but weren't and raced the manual flow. Making it smarter would have meant a standing ANTHROPIC_API_KEY/OAuth token in CI secrets, billed unattended on every release. Removed: the workflow, the --open-pr path + openSyncPr/saveManifest in scan.ts (now a pure dry-run detector), and stale 'daily GH Action'/'bot owns this file' references across the manifest, skill, schema, and CI comment. Kept: bun run upstream:scan (dry-run detector) + its non-gating CI job. Also syncs the manifest to Claude Code 2.1.161 (otherwise all bug fixes; adds CLAUDE_CODE_TMPDIR to knownEnvVars + the env-var table; OTEL_RESOURCE_ATTRIBUTES skipped as a generic OTEL var). --- .github/workflows/ci.yml | 5 +- .github/workflows/upstream-sync.yml | 35 -------- CHANGELOG.md | 4 + docs/settings-reference.md | 1 + skills/cc/SKILL.md | 6 +- src/schemas/skill.ts | 4 +- src/upstream/scan.ts | 121 ++++------------------------ upstream/claude-code-manifest.json | 9 ++- 8 files changed, 34 insertions(+), 151 deletions(-) delete mode 100644 .github/workflows/upstream-sync.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 201d399..cc9864a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -65,8 +65,9 @@ jobs: - run: git diff --exit-code schemas/ upstream-scan: - # Dry-run in CI so any drift shows up in the PR. This is not a gate — - # the scheduled upstream-sync workflow proposes fixes. + # Dry-run in CI so any drift surfaces in the PR logs. Not a gate, and not + # automated beyond this — run `/cc sync` by hand to triage the changelog + # and land a bump. runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 diff --git a/.github/workflows/upstream-sync.yml b/.github/workflows/upstream-sync.yml deleted file mode 100644 index fb86c26..0000000 --- a/.github/workflows/upstream-sync.yml +++ /dev/null @@ -1,35 +0,0 @@ -name: upstream-sync - -# Daily scan of Claude Code upstream. When `src/upstream/scan.ts --open-pr` -# detects a new npm version of @anthropic-ai/claude-code, it writes an -# updated upstream/claude-code-manifest.json and opens a labeled PR. - -on: - schedule: - # Daily 09:00 UTC. Claude Code usually ships patch releases mid-week; - # daily is tight enough to catch drift within 24h of release. - - cron: "0 9 * * *" - workflow_dispatch: - -permissions: - contents: write - pull-requests: write - -jobs: - scan: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - with: - # Need history to push a new branch. - fetch-depth: 0 - - uses: oven-sh/setup-bun@v2 - with: - bun-version: ">=1.1.30" - - run: bun install --frozen-lockfile - - name: Scan upstream (dry-run summary) - run: bun src/upstream/scan.ts - - name: Open PR on drift - env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: bun src/upstream/scan.ts --open-pr diff --git a/CHANGELOG.md b/CHANGELOG.md index 6c8524c..cad5343 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,10 @@ All notable changes to cc-settings are documented here. ### Changed +- **Retired the automated upstream-sync cron in favor of manual `/cc sync`.** The daily GitHub Action (`.github/workflows/upstream-sync.yml`) and the `--open-pr` path in `src/upstream/scan.ts` only ever bumped a version number and dumped the drift string into a PR body. The scanner's `diffSets` compares the manifest against cc-settings' *own* zod schema — never upstream — and it never fetched the changelog, so it was structurally blind to new features, settings keys, env vars, hook events, and dedupe opportunities. That triage is the human-reviewed skill's job; the bot's PRs looked actionable but weren't, and raced the manual flow. Removing it also avoids a standing CI credential (making the cron *smarter* would have meant baking an `ANTHROPIC_API_KEY`/OAuth token into repo secrets and burning it unattended on every release). + - **Removed** — `.github/workflows/upstream-sync.yml`; `openSyncPr`/`saveManifest` and the `--open-pr` branch in `src/upstream/scan.ts` (now a pure dry-run detector, no `writeFile`/`runProcessFull` imports); stale "daily GH Action"/"bot owns this file" references in the manifest `description`/`source`, `skills/cc/SKILL.md`, `src/schemas/skill.ts`, and the `.github/workflows/ci.yml` `upstream-scan` comment. + - **Kept** — `bun run upstream:scan` (the dry-run detector) and its non-gating CI job, now the manual way to spot drift before running `/cc sync`. +- **Upstream sync to Claude Code 2.1.161.** Manifest bumped `2.1.160` → `2.1.161`. The release is otherwise all bug fixes / UI / perf with no cc-settings surface; the one tracked addition is `CLAUDE_CODE_TMPDIR` (surfaced by the `EADDRINUSE`/Unix-socket fix), added to the manifest `knownEnvVars` and the `docs/settings-reference.md` env-var table. `OTEL_RESOURCE_ATTRIBUTES` now feeds metric-datapoint labels but is a generic OTEL SDK var outside our CC-specific tracking convention — deliberately skipped. - **Shared team-knowledge migrated from GitHub Project #7 to a markdown repo** (`darkroomengineering/team-knowledge`). The board was structurally hostile to its primary consumers (agents): network-gated GraphQL reads, not greppable offline, and no linter-enforced structure — `gh project item-create` never set the `Kind` field, so every `/share-learning` post landed `kind: None` and was invisible to a Kind-filtered query. The repo is one note per file + a generated `INDEX.md`, mirroring the local auto-memory tier. Decision + roadmap: `docs/plans/knowledge-repo-migration.md` (weighted comparison scored repo 795 vs board 515). - **New** — `src/schemas/knowledge.ts` (zod frontmatter contract: `name`/`kind`/`tags`/`added-by`/`supersedes`), `src/lib/lint-knowledge.ts` + `src/scripts/lint-knowledge.ts` (`bun run lint:knowledge`), `src/scripts/new-note.ts` (`bun run new-note`), `tests/lint-knowledge.test.ts`, emitted `schemas/knowledge.schema.json`. - **Changed** — `/share-learning` now reads `INDEX.md` for dedup and writes notes via `gh api` (was `gh project item-list`/`item-create`); `docs/knowledge-system.md`, the `AGENTS.md` Knowledge Routing section, and assorted docs retargeted; env `KNOWLEDGE_PROJECT_NUMBER` → `KNOWLEDGE_REPO`. diff --git a/docs/settings-reference.md b/docs/settings-reference.md index 1aa1d05..418aad2 100644 --- a/docs/settings-reference.md +++ b/docs/settings-reference.md @@ -83,6 +83,7 @@ Environment variables injected into every Claude Code session. | `CLAUDE_CODE_ENABLE_AUTO_MODE` | `"1"` or unset | Opt in to auto mode on Bedrock, Vertex, and Foundry for Opus 4.7/4.8 (native on the first-party API) (v2.1.158) | | `CLAUDE_CODE_SHELL_PREFIX` | shell prefix string | Custom shell prefix for MCP stdio server launches; overrides the default shell used to spawn stdio MCP processes (v2.1.128) | | `CLAUDE_CODE_SUBAGENT_MODEL` | model shortname (e.g., `sonnet`) | Routes Agent Teams teammate subprocess sessions to a specific model; main session model is unaffected. cc-settings sets `sonnet` (v2.1.147) | +| `CLAUDE_CODE_TMPDIR` | directory path | Overrides the temp directory used for Unix sockets and scratch files; set it shallow to avoid `EADDRINUSE` from over-long socket paths (v2.1.161) | | `OTEL_LOG_TOOL_DETAILS` | `"1"` or unset | Include custom/MCP command names in OTEL tool spans, and `tool_parameters` in `tool_decision` events; values are redacted unless this is set (v2.1.117; `tool_decision` params added v2.1.157) | > **Note on `ultracode` mode (v2.1.154+)**: `/effort ultracode` is a Claude Code session-only mode that sends `xhigh` to the model AND has Claude plan a [dynamic workflow](https://code.claude.com/docs/en/workflows) for each substantive task. It is **not** a valid value for `CLAUDE_CODE_EFFORT_LEVEL`, the `effortLevel` setting, or the `--effort` flag — set it via `/effort ultracode` in-session, or pass `"ultracode": true` through `--settings` or an Agent SDK control request. Disable workflows entirely with `CLAUDE_CODE_DISABLE_WORKFLOWS=1` or `"disableWorkflows": true`. diff --git a/skills/cc/SKILL.md b/skills/cc/SKILL.md index 98a2606..ecdfdd3 100644 --- a/skills/cc/SKILL.md +++ b/skills/cc/SKILL.md @@ -195,8 +195,10 @@ git log. Do not push if anything in Phase 7 is failing. - It does not edit user-installed `~/.claude/settings.json`. cc-settings is the source — users get the changes by re-running `setup.sh`. -- It does not auto-open PRs. The upstream-sync GitHub Action handles - manifest-only bumps; this skill is for the richer human-reviewed sync. +- It does not auto-open PRs, and there is no longer an automated cron. The + daily upstream-sync GitHub Action was retired — it could only bump the + version number, never triage the changelog. `bun run upstream:scan` is the + manual drift detector; this skill is the only sync path. - It does not bump dependencies. That's a separate concern. ### Mental model diff --git a/src/schemas/skill.ts b/src/schemas/skill.ts index e488312..6e7bc4b 100644 --- a/src/schemas/skill.ts +++ b/src/schemas/skill.ts @@ -42,8 +42,8 @@ export const SkillFrontmatter = z // Allow unknown keys — the skills ecosystem is fast-moving and we'd rather // accept an unrecognized field than reject a skill that works in newer CC. - // Contrast with settings.ts which is strict because drift there is the - // whole reason we have an upstream-sync bot. + // Contrast with settings.ts which is strict because drift there is what + // the `bun run upstream:scan` detector exists to catch. }) .passthrough(); diff --git a/src/upstream/scan.ts b/src/upstream/scan.ts index b5f6965..7d6dbf5 100644 --- a/src/upstream/scan.ts +++ b/src/upstream/scan.ts @@ -1,22 +1,20 @@ #!/usr/bin/env bun -// Upstream-sync scanner. Phases: -// dry-run (default): compares the current manifest against -// (a) npm's @anthropic-ai/claude-code latest version -// (b) the zod schema's enumerated keys (our local source of truth) -// and prints a delta. -// --open-pr: write an updated manifest + open a GitHub PR (requires `gh` -// CLI + a token with PR-write scope; used by .github/workflows/upstream-sync.yml). +// Upstream-sync scanner (dry-run detector). Compares the current manifest against +// (a) npm's @anthropic-ai/claude-code latest version +// (b) the zod schema's enumerated keys (our local source of truth) +// and prints the delta. Run it (`bun run upstream:scan`) to find out whether +// Claude Code has shipped a new release. // -// Phase 2 adds the mutation path. It is deliberately low-blast-radius: the -// scanner only updates upstream/claude-code-manifest.json when the live -// npm version differs from the committed one. Schema edits stay human- -// reviewed — the PR body lists the delta and we let the reviewer wire the -// new keys into the zod schemas. - -import { readFile, writeFile } from "node:fs/promises"; +// The scanner never writes. The actual sync — changelog triage +// (ADOPT/DEDUPE/SKIP), schema + doc edits, and the manifest + CHANGELOG bumps — +// is the human-reviewed `/cc sync` skill, run on demand. (There was once a daily +// GH Action that auto-bumped the manifest version, but it could only ever change +// a version number — it never read the changelog — so it was retired in favor of +// the manual skill.) + +import { readFile } from "node:fs/promises"; import { resolve } from "node:path"; import { z } from "zod"; -import { runProcessFull } from "../lib/git.ts"; import { HookEvent } from "../schemas/hooks.ts"; import { Settings } from "../schemas/settings.ts"; @@ -87,61 +85,13 @@ function diffSets(label: string, manifest: string[], live: string[]): string[] { return out; } -async function saveManifest(manifest: Manifest): Promise { - // Preserve the existing on-disk key order as much as we can; stable keys - // keep diffs small when nothing substantive changed. - const content = `${JSON.stringify(manifest, null, 2)}\n`; - await writeFile(MANIFEST, content); -} - -async function openSyncPr(summary: string, body: string, newVersion: string): Promise { - const branch = `upstream-sync/${newVersion}-${Date.now()}`; - await runProcessFull("git", ["config", "user.name", "upstream-sync-bot"]); - await runProcessFull("git", [ - "config", - "user.email", - "upstream-sync-bot@users.noreply.github.com", - ]); - await runProcessFull("git", ["checkout", "-b", branch]); - await runProcessFull("git", ["add", "upstream/claude-code-manifest.json"]); - const commitTitle = `chore(upstream-sync): bump manifest to ${newVersion}`; - const commitRes = await runProcessFull("git", ["commit", "-m", commitTitle]); - if (commitRes.exit !== 0) { - console.error("git commit failed:", commitRes.stderr); - return; - } - const pushRes = await runProcessFull("git", ["push", "-u", "origin", branch]); - if (pushRes.exit !== 0) { - console.error("git push failed:", pushRes.stderr); - return; - } - const prRes = await runProcessFull("gh", [ - "pr", - "create", - "--title", - summary, - "--body", - body, - "--label", - "upstream-sync", - ]); - if (prRes.exit !== 0) { - console.error("gh pr create failed:", prRes.stderr); - return; - } - console.log(`opened PR for ${newVersion}: ${prRes.stdout.trim()}`); -} - async function main() { - const args = process.argv.slice(2); - const openPr = args.includes("--open-pr"); - const manifest = await loadManifest(); const liveSettingsKeys = settingsKeysFromSchema(); const liveHookEvents = hookEventsFromSchema(); const liveVersion = await fetchLatestClaudeCodeVersion(); - console.log(`cc-settings upstream scan (${openPr ? "open-pr" : "dry-run"})`); + console.log("cc-settings upstream scan"); console.log(` manifest version: ${manifest.claudeCodeVersion} (scanned ${manifest.lastScan})`); console.log(` live version: ${liveVersion ?? ""}`); @@ -161,48 +111,7 @@ async function main() { console.log("\ndrift detected:"); for (const line of findings) console.log(line); - - if (!openPr) { - console.log("\nre-run with --open-pr to propose the manifest update as a PR."); - return; - } - - if (!versionDrift) { - // Schema-only drift is interesting but we don't auto-edit schemas; surface - // via CI logs and let a human wire the new keys. - console.log("\nschema-only drift — no manifest update proposed. Review the findings above."); - return; - } - - // Mutate the manifest version + lastScan, keep key lists untouched (schema - // additions are human work). If schema keys drift too, we note them in the - // PR body. - const updated: Manifest = { - ...manifest, - claudeCodeVersion: versionDrift, - lastScan: new Date().toISOString(), - }; - await saveManifest(updated); - - const summary = `chore(upstream-sync): bump claude-code manifest to ${versionDrift}`; - const body = [ - "Automated upstream-sync PR.", - "", - `- manifest: \`${manifest.claudeCodeVersion}\` → \`${versionDrift}\``, - "", - "## Findings", - "", - "```", - findings.join("\n"), - "```", - "", - "If the findings list schema-key drift, wire the new keys into the appropriate", - "zod schemas in `src/schemas/` and push onto this branch.", - "", - "Generated by `src/upstream/scan.ts --open-pr`.", - ].join("\n"); - - await openSyncPr(summary, body, versionDrift); + console.log("\nrun `/cc sync` to triage the changelog and land the bump."); } main().catch((err) => { diff --git a/upstream/claude-code-manifest.json b/upstream/claude-code-manifest.json index 32fbe10..b3827f4 100644 --- a/upstream/claude-code-manifest.json +++ b/upstream/claude-code-manifest.json @@ -1,6 +1,6 @@ { - "lastScan": "2026-06-02T00:00:00.000Z", - "claudeCodeVersion": "2.1.160", + "lastScan": "2026-06-03T00:00:00.000Z", + "claudeCodeVersion": "2.1.161", "knownSettingsKeys": [ "$schema", "agent", @@ -167,6 +167,7 @@ "CLAUDE_CODE_STOP_HOOK_BLOCK_CAP", "CLAUDE_CODE_SUBAGENT_MODEL", "CLAUDE_CODE_SUBPROCESS_ENV_SCRUB", + "CLAUDE_CODE_TMPDIR", "CLAUDE_CODE_USE_POWERSHELL_TOOL", "CLAUDE_EFFORT", "DISABLE_UPDATES", @@ -193,9 +194,9 @@ ], "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "https://cc-settings.darkroom/upstream/claude-code-manifest.json", - "description": "Snapshot of Claude Code upstream surface area as known to the cc-settings zod schemas. Updated by src/upstream/scan.ts (daily GH Action). Drift triggers a PR that extends the schemas and this manifest atomically. See docs/migration-coexistence.md and ~/Desktop/cc-settings-MIGRATION.md v2.", + "description": "Snapshot of Claude Code upstream surface area as known to the cc-settings zod schemas. Updated by hand via the /cc sync skill; bun run upstream:scan reports drift but never writes. See docs/migration-coexistence.md.", "manifestSchemaVersion": 1, - "source": "manual sync (cc-settings v11.0.1). From 2.1.115 onward, upstream-sync bot owns this file.", + "source": "manual sync via the /cc sync skill (the automated upstream-sync bot was retired June 2026).", "knownPermissionModes": [ "default", "acceptEdits",