Skip to content

Commit 414aadf

Browse files
Merge branch 'main' into fix/547-reftable-support
2 parents f043275 + df765ab commit 414aadf

182 files changed

Lines changed: 14785 additions & 1379 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.claude/skills/test-repo/SKILL.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,7 @@ echo "{\"session_id\": \"$SESSION_ID\", \"transcript_path\": \"$TRANSCRIPT_DIR/t
177177
/tmp/entire-bin hooks claude-code post-task
178178

179179
# Verify task checkpoint created
180-
/tmp/entire-bin rewind --list | jq '.[] | select(.is_task_checkpoint == true)'
180+
/tmp/entire-bin checkpoint list --pending --json | jq '.[] | select(.is_task_checkpoint == true)'
181181
```
182182

183183
### Test User Commits (Condensation)

.claude/skills/test-repo/test-harness.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@ list-rewind-points)
151151
echo "==> Listing rewind points..."
152152
cd "$REPO_DIR"
153153

154-
"$BIN_PATH" rewind --list
154+
"$BIN_PATH" checkpoint list --pending --json
155155
;;
156156

157157
create-changes)

.github/workflows/codeql-actions.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,13 @@ jobs:
2424
ref: ${{ github.event.pull_request.head.sha }}
2525

2626
- name: Initialize CodeQL
27-
uses: github/codeql-action/init@54f647b7e1bb85c95cddabcd46b0c578ec92bc1a # v4.36.3
27+
uses: github/codeql-action/init@99df26d4f13ea111d4ec1a7dddef6063f76b97e9 # v4.37.0
2828
with:
2929
languages: actions
3030
queries: security-extended,security-and-quality
3131

3232
- name: Perform CodeQL analysis
33-
uses: github/codeql-action/analyze@54f647b7e1bb85c95cddabcd46b0c578ec92bc1a # v4.36.3
33+
uses: github/codeql-action/analyze@99df26d4f13ea111d4ec1a7dddef6063f76b97e9 # v4.37.0
3434
with:
3535
category: /language:actions
3636
# Fork PRs receive a read-only GITHUB_TOKEN, so SARIF upload to the

.github/workflows/e2e.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -208,7 +208,7 @@ jobs:
208208
} >> "$GITHUB_OUTPUT"
209209
210210
- name: Notify Slack of E2E failure
211-
uses: slackapi/slack-github-action@45a88b9581bfab2566dc881e2cd66d334e621e2c # v3.0.3
211+
uses: slackapi/slack-github-action@0d95c9a7becc1e6e297d76df9bc735c44f4cbcbc # v3.0.5
212212
with:
213213
webhook: ${{ secrets.E2E_SLACK_WEBHOOK_URL }}
214214
webhook-type: incoming-webhook

.github/workflows/release.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -195,7 +195,7 @@ jobs:
195195
if: ${{ always() && (needs.release.result == 'failure' || needs.mirror-nightly.result == 'failure') }}
196196
steps:
197197
- name: Notify Slack of release failure
198-
uses: slackapi/slack-github-action@45a88b9581bfab2566dc881e2cd66d334e621e2c # v3.0.3
198+
uses: slackapi/slack-github-action@0d95c9a7becc1e6e297d76df9bc735c44f4cbcbc # v3.0.5
199199
with:
200200
webhook: ${{ secrets.E2E_SLACK_WEBHOOK_URL }}
201201
webhook-type: incoming-webhook

.goreleaser.yaml

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,11 @@ builds:
2626
- -X github.com/entireio/cli/cmd/entire/cli/versioninfo.Commit={{.ShortCommit}}
2727
- -X github.com/entireio/cli/cmd/entire/cli/telemetry.PostHogAPIKey={{.Env.POSTHOG_API_KEY}}
2828
- -X github.com/entireio/cli/cmd/entire/cli/telemetry.PostHogEndpoint={{.Env.POSTHOG_ENDPOINT}}
29+
# Experimental-command visibility: hide in stable releases, keep visible
30+
# in nightly (prerelease) builds. .Prerelease is empty for a stable tag
31+
# (vX.Y.Z) and non-empty for a nightly tag (vX.Y.Z-nightly.*). Local
32+
# builds carry no stamp and use the package default ("true" = visible).
33+
- -X github.com/entireio/cli/cmd/entire/cli/experimental.Visible={{ if .Prerelease }}true{{ else }}false{{ end }}
2934

3035
# git-remote-entire is the git remote helper for entire:// URLs (see
3136
# cmd/git-remote-entire). A small, dedicated binary shipped alongside
@@ -100,7 +105,14 @@ release:
100105
prerelease: auto
101106

102107
scoops:
103-
- repository:
108+
# Name the manifest (and therefore the Scoop app directory) "entire". Without
109+
# this, goreleaser defaults the manifest name to the project name, which
110+
# resolves to the repo name ("cli"), so `scoop install` lands the binary in
111+
# …\scoop\apps\cli\current\entire.exe. That mismatched app-dir name is
112+
# surprising ("scoop install cli"?) and fed the Windows hook-path bug in
113+
# https://github.com/entireio/cli/issues/1424.
114+
- name: entire
115+
repository:
104116
owner: entireio
105117
name: scoop-bucket
106118
token: "{{ .Env.TAP_GITHUB_TOKEN }}"

CLAUDE.md

Lines changed: 27 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,18 @@ The visible CLI is organized around a set of noun groups plus a small set of
2626
top-level verbs. The groups are the canonical home for each verb; legacy
2727
top-level shortcuts remain functional but hidden, and emit a deprecation hint
2828
pointing at the canonical group form. Newer experimental command families are
29-
discoverable through `entire labs` and may remain hidden from root help while
30-
their canonical paths are still runnable.
29+
discoverable through `entire labs` and their canonical paths are always
30+
runnable.
31+
32+
Experimental commands are gated by a build-time visibility flag (the
33+
`cmd/entire/cli/experimental` package): they are shown — grouped under an
34+
"Experimental commands:" help section — in developer and nightly builds, and
35+
hidden in stable release builds. Visibility is toggled by `experimental.Visible`
36+
(default `"true"`), which GoReleaser stamps `"false"` only on stable tags
37+
(`.Prerelease` empty); nightly (`vX.Y.Z-nightly.*`) and local builds leave it at
38+
the default. Register a command as experimental with `experimental.Register(parent,
39+
child)` instead of `parent.AddCommand(child)`. Gating only controls visibility —
40+
the commands are always runnable in every build.
3141

3242
- `session` (alias: `sessions`): `list`, `info`, `tokens`, `stop`, `attach`, `adopt`, `resume`, `current`.
3343
`resume` with a branch arg switches to it and resumes its session; with no arg
@@ -66,9 +76,12 @@ their canonical paths are still runnable.
6676
- `grant`: manage access grants and org membership — `org`, `project`, and `repo`
6777
each support `add` / `list` / `remove`
6878

69-
Experimental command families advertised through `entire labs`:
70-
71-
- `tokens`: `profile` (hidden from root help while token diagnostics mature)
79+
Experimental commands (gated by the build-time visibility flag above — visible
80+
and grouped under "Experimental commands:" in developer/nightly builds, hidden
81+
in stable releases, always runnable): `tokens`, `import`, `review`,
82+
`investigate`, `blame`, `why`, the top-level `search` shortcut, `experts`,
83+
`runner`, and `checkpoint policy`. `tokens` is also advertised through `entire
84+
labs`. The canonical `checkpoint search` is not gated and stays visible.
7285

7386
Top-level lifecycle and standalone commands: `enable`, `disable`, `status`,
7487
`login`, `logout`, `clean`, `version`, `dispatch`, `activity`, `help`,
@@ -91,7 +104,10 @@ one command's current flags; `--json` emits structured output. It is the single
91104
source of truth the first-turn context injection and the `--agent-help-skill`
92105
skill point agents at, instead of enumerating a surface that goes stale.
93106
Hidden commands opt into being advertised here by setting
94-
`Annotations[agentHelpAnnotation] = "true"` (e.g. `trail`).
107+
`Annotations[agentHelpAnnotation] = "true"` (e.g. `trail`). Because `agent-help`
108+
renders live and lists non-hidden commands, the experimental commands appear in
109+
`agent-help` in developer/nightly builds and are absent in stable releases — the
110+
advertised surface is build-dependent, matching what `entire help` shows.
95111
No-channel agents (Cursor, Copilot CLI, Factory Droid, MCP hosts — no
96112
context-injection channel and no agent-help skill template) reach it without an
97113
active push. All of them can discover it passively: it is visible in `entire
@@ -107,7 +123,9 @@ Hidden top-level shortcuts (functional, emit a one-line deprecation hint):
107123
`resume``session resume`, `attach``session attach`, `explain`
108124
`checkpoint explain`, `trace``doctor trace`.
109125
Cobra-native aliases (no hint): `sessions``session`, `cp`/`checkpoints`
110-
`checkpoint`. The `search` top-level remains hidden without a hint.
126+
`checkpoint`. The `search` top-level is experimental (see the visibility gate
127+
above), so it follows the build-dependent visibility rather than being
128+
unconditionally hidden.
111129

112130
Deprecated top-level commands (functional, print a cobra deprecation message):
113131
`reset``clean`, and `rewind` (no replacement, announces removal — same
@@ -583,7 +601,7 @@ The manual-commit strategy (`manual_commit*.go`) does not modify the active bran
583601
- **Shadow branch migration** - if user does stash/pull/rebase (HEAD changes without commit), shadow branch is automatically moved to new base commit
584602
- **Orphaned branch cleanup** - if a shadow branch exists without a corresponding session state file, it is automatically reset when a new session starts
585603
- PrePush hook can push `entire/checkpoints/v1` branch alongside user pushes
586-
- **OPF (OpenAI Privacy Filter) runs at pre-push, not post-commit**: when `redaction.openai_privacy_filter.enabled` is true, the PrePush hook re-redacts unpushed `entire/checkpoints/v1` commits with the OPF 8th layer, builds new commits carrying an `Entire-OPF-Applied: true` trailer, and atomically updates the local v1 ref before pushing. Per-commit condensation stays on the fast 7-layer pipeline. See `strategy/manual_commit_opf_rewrite.go` and `docs/security-and-privacy.md` for the full flow, including divergence detection, bootstrap caps, and CAS-on-conflict semantics.
604+
- **OPF (OpenAI Privacy Filter) runs at pre-push, not post-commit**: when `redaction.openai_privacy_filter.enabled` is true, the PrePush hook re-redacts unpushed `entire/checkpoints/v1` commits with the OPF 9th layer, builds new commits carrying an `Entire-OPF-Applied: true` trailer, and atomically updates the local v1 ref before pushing. Per-commit condensation stays on the fast 8-layer pipeline. See `strategy/manual_commit_opf_rewrite.go` and `docs/security-and-privacy.md` for the full flow, including divergence detection, bootstrap caps, and CAS-on-conflict semantics.
587605
- Safe to use on main/master since it never modifies commit history
588606

589607
#### Key Files
@@ -604,6 +622,7 @@ The phase state machine, metadata directory layout, sharded checkpoint format, m
604622

605623
- [Sessions and Checkpoints](docs/architecture/sessions-and-checkpoints.md) - domain model, storage layout, checkpoint ID linking, commit trailers, package structure
606624
- [Checkpoint Scenarios](docs/architecture/checkpoint-scenarios.md) - phase state machine and worked condensation scenarios
625+
- [Ref-Based Checkpoint Backend](docs/architecture/ref-checkpoint-backend.md) - git-refs backend: primary/mirror taxonomy, ref layout + sharding, push-discovery queue, read routing, config + rollout
607626

608627
#### When Modifying the Strategy
609628

README.md

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ With Entire, you can:
2525
- [Key Concepts](#key-concepts)
2626
- [How It Works](#how-it-works)
2727
- [Strategy](#strategy)
28+
- [Headless & CI Authentication](#headless--ci-authentication)
2829
- [Local Device Auth Testing](#local-device-auth-testing)
2930
- [Commands Reference](#commands-reference)
3031
- [Configuration](#configuration)
@@ -206,6 +207,44 @@ Entire works seamlessly with [git worktrees](https://git-scm.com/docs/git-worktr
206207

207208
Multiple AI sessions can run on the same commit. If you start a second session while another has uncommitted work, Entire warns you and tracks them separately. Both sessions' checkpoints are preserved and can be rewound independently.
208209

210+
## Headless & CI Authentication
211+
212+
By default `entire login` stores tokens in the OS keyring (macOS Keychain,
213+
Linux Secret Service, Windows Credential Manager). Machines without a usable
214+
keyring — headless servers, containers, minimal VMs, CI runners — have two
215+
supported paths:
216+
217+
### Interactive login on a headless machine
218+
219+
Use the file-backed token store. The device-auth flow already works without a
220+
local browser (the CLI prints an approval URL you can open on any machine);
221+
only token storage needs the override:
222+
223+
```bash
224+
ENTIRE_TOKEN_STORE=file entire login
225+
```
226+
227+
Tokens are written with `0600` permissions to `tokens.json` in your Entire
228+
config directory (`~/.config/entire` by default). Override the location with
229+
`ENTIRE_TOKEN_STORE_PATH`. Set `ENTIRE_TOKEN_STORE=file` persistently (e.g. in
230+
your shell profile) so later commands read from the same store.
231+
232+
### Non-interactive automation (CI, workload identity)
233+
234+
Skip login and storage entirely by injecting a token per invocation:
235+
236+
```bash
237+
ENTIRE_TOKEN=<login-or-sa-session-JWT> entire ...
238+
```
239+
240+
`ENTIRE_TOKEN` bypasses stored credentials; the CLI derives the control-plane
241+
endpoint from the token itself. Nothing is written to disk. This is the right
242+
path for CI pipelines and service accounts.
243+
244+
> **Seeing `save login` / `failed to unlock correct collection` errors from
245+
> `entire login`?** That's the OS keyring being unavailable — use one of the
246+
> two paths above.
247+
209248
## Local Device Auth Testing
210249

211250
If you're working on the CLI device auth flow against a local `entire.io` checkout:

WINDOWS.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ After building, verify these work on a Windows machine:
8080
2. `entire.exe enable` — in a git repo with an agent installed
8181
3. Start an agent session, make file changes
8282
4. `git add . && git commit -m "test"` — hooks should fire (prepare-commit-msg, post-commit)
83-
5. `entire.exe rewind --list` — should show checkpoint(s)
83+
5. `entire.exe checkpoint list --pending --json` — should show checkpoint(s)
8484
6. `entire.exe explain` — pager should use `more` by default
8585

8686
## Architecture Notes

cmd/entire/cli/agent/agent.go

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -361,6 +361,24 @@ type SubagentAwareExtractor interface {
361361
ExtractAllModifiedFiles(transcriptData []byte, fromOffset int, subagentsDir string) ([]string, error)
362362

363363
// CalculateTotalTokenUsage computes token usage including all spawned subagents.
364-
// The subagentsDir parameter specifies where subagent transcripts are stored.
364+
// The subagentsDir parameter specifies where subagent transcripts are stored
365+
// (an empty subagentsDir skips subagent accounting and leaves SubagentTokens nil).
366+
//
367+
// CONTRACT — the returned SubagentTokens is a CUMULATIVE-SINCE-SESSION-START
368+
// snapshot, NOT a delta scoped to fromOffset like the main-agent fields
369+
// (InputTokens/OutputTokens/...). Implementations MUST discover spawned agent
370+
// IDs from the FULL transcript prefix [0,end) — so a subagent spawned before
371+
// fromOffset is still found (#329) — and re-read each subagent transcript from
372+
// line 0 on every call. Consequently a subagent's full total repeats on every
373+
// call after it is first discovered.
374+
//
375+
// Callers that accumulate across checkpoints/turns therefore MUST NOT sum
376+
// SubagentTokens across calls: replace the running total with the latest
377+
// snapshot, and rescope any window delta by subtracting a previously captured
378+
// baseline (see accumulateTokenUsage / resetCheckpointWindow and
379+
// session.State.SubagentTokensBaseline in cmd/entire/cli/strategy, and
380+
// rescopeSubagentTokensToDeltas in cmd/entire/cli/agentimport for the import
381+
// path). An implementation that instead returned per-window deltas would
382+
// silently break that accounting with no compile-time or test signal.
365383
CalculateTotalTokenUsage(transcriptData []byte, fromOffset int, subagentsDir string) (*TokenUsage, error)
366384
}

0 commit comments

Comments
 (0)