wendkeep 0.75.3 → 0.76.1
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/CHANGELOG.md +33 -0
- package/README.en.md +4 -1
- package/README.md +4 -1
- package/docs/en/commands/context.md +88 -0
- package/docs/en/commands/getting-started.md +3 -1
- package/docs/en/commands/maintenance-and-diagnostics.md +3 -0
- package/docs/en/commands/worktrees.md +93 -0
- package/docs/pt-BR/commands/context.md +86 -0
- package/docs/pt-BR/commands/getting-started.md +3 -1
- package/docs/pt-BR/commands/maintenance-and-diagnostics.md +2 -0
- package/docs/pt-BR/commands/worktrees.md +91 -0
- package/hooks/flow-protected-policy.mjs +1 -1
- package/hooks/project-scope.mjs +51 -6
- package/package.json +2 -1
- package/packages/cli/src/index.mjs +25 -3
- package/packages/vault/src/index.mjs +1 -0
- package/packages/vault/src/project-vault.mjs +25 -2
- package/packages/vault/src/worktree-metadata.mjs +274 -0
- package/src/context.mjs +297 -0
- package/src/doctor.mjs +8 -0
- package/src/init.mjs +6 -0
- package/src/sync.mjs +4 -1
- package/src/worktree.mjs +708 -0
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,39 @@ All notable changes to **wendkeep** are documented here. Format based on
|
|
|
4
4
|
[Keep a Changelog](https://keepachangelog.com/en/1.1.0/); this project follows
|
|
5
5
|
[Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
6
6
|
|
|
7
|
+
## [0.76.1] — 2026-08-21
|
|
8
|
+
|
|
9
|
+
### Added
|
|
10
|
+
|
|
11
|
+
- **Transição causal de branch.** `context switch <branch> [--create] [--session <id>]` move
|
|
12
|
+
Git e a scope da mesma sessão juntos na worktree atual, preserva change/lease/autorizações,
|
|
13
|
+
incrementa revisão e registra evidência `from/to` sob o lock do registry.
|
|
14
|
+
|
|
15
|
+
### Fixed
|
|
16
|
+
|
|
17
|
+
- **Guard não deixa mais a sessão inutilizável após checkout.** `git checkout/switch` cru que
|
|
18
|
+
mudaria branch é negado antecipadamente com orientação acionável; falha durante a transição
|
|
19
|
+
segura executa rollback da branch/HEAD e não publica scope parcial. Contextos incompletos de
|
|
20
|
+
outra worktree comprovada também deixam de causar falso conflito na worktree atual.
|
|
21
|
+
|
|
22
|
+
## [0.76.0] — 2026-08-21
|
|
23
|
+
|
|
24
|
+
### Added
|
|
25
|
+
|
|
26
|
+
- **Worktrees gerenciadas e seguras.** `worktree create/list/status/open` cria linked worktrees
|
|
27
|
+
idempotentes sob `.worktrees`, com branch `wk/<slug>`, validação de path/ref e abertura opcional
|
|
28
|
+
em nova janela do VS Code. O registry privado no Git common-dir compartilha identidade e Vault
|
|
29
|
+
canônico sem alterar `.wendkeep.json`, usa lock multiprocesso e registra falhas recuperáveis.
|
|
30
|
+
- **Integração operacional.** `doctor` reconcilia registry/Git, `init` e `sync` aceitam
|
|
31
|
+
`--vscode-worktree-tasks` sem sobrescrever preferências locais, e ignores/walkers excluem a raiz
|
|
32
|
+
gerenciada. Saídas humanas são bilíngues e `--json` preserva o boundary do Vault.
|
|
33
|
+
|
|
34
|
+
### Fixed
|
|
35
|
+
|
|
36
|
+
- **Gate staged sem falsos positivos.** O scanner reconhece códigos públicos `WENDKEEP_*`, limita
|
|
37
|
+
a allowlist de diagnósticos às superfícies de observabilidade e mantém bloqueio de identificadores
|
|
38
|
+
opacos; fixtures do worktree manager usam exclusivamente o namespace sintético `wk-fixture-*`.
|
|
39
|
+
|
|
7
40
|
## [0.75.3] — 2026-08-20
|
|
8
41
|
|
|
9
42
|
### Fixed
|
package/README.en.md
CHANGED
|
@@ -115,7 +115,7 @@ npx wendkeep init
|
|
|
115
115
|
|
|
116
116
|
1. Create the vault folder taxonomy and a templated `README.md` (default vault: `<project>/.<project-name>-vault`, e.g. `.MyApp-vault`; override with `--vault`).
|
|
117
117
|
2. Write a provider-neutral **`.wendkeep.json`** binding at the project root and a matching `.brain/PROJECT.json` marker in the vault, then merge the session hooks into **`.claude/settings.json`**. The binding is provider-neutral by design: any agent resolves the same vault from its session `cwd`, with no machine-global environment variable. Older registrations already in `.claude/settings.json` are adopted automatically.
|
|
118
|
-
3. Wire the Codex hooks in **`.codex/hooks.json`** — twelve compatible entries: `brain-inject` + `session-start` + `observer-publish` on `SessionStart`, `session-ensure` + `evidence-context` + `change-context` on `UserPromptSubmit`, `session-stop` + `observer-publish` + `change-nag` on `Stop`, `subagent-stop` + `observer-publish` on `SubagentStop`, and `change-guard` on `PreToolUse` for `Bash`, `exec_command`, `apply_patch`, and mutable MCP tools, always in the `npx wendkeep hook <name>` form. For the Observer, `SessionStart` only drains the outbox, `Stop` enqueues the changed session, and `SubagentStop` enqueues only the affected transcript; full scanning is explicit through `observer reconcile`. The guard accepts object, raw-string, and argv Codex payloads; before a mutation it compares the session with the project, Git root, remote, branch, and worktree, denying missing or divergent targets. The other four stay out because Codex offers no equivalent payload, tool, or event: `change-warn` (no reliable `tool_input.file_path`), `plan-capture` (no `ExitPlanMode`), `decision-capture` (`AskUserQuestion` is Claude-only), and `task-log` (`TaskCompleted` is not in Codex's event enum). Codex scope blocks use `permissionDecision: "deny"`; `ask` is never emitted in `PreToolUse`. The merge remains non-destructive, preserves third-party hooks, and migrates legacy `timeout` to `timeoutSec`. **Codex enumerates every hook as untrusted and runs none until you approve the “Hooks need review” prompt at startup — `init` cannot pre-approve them**.
|
|
118
|
+
3. Wire the Codex hooks in **`.codex/hooks.json`** — twelve compatible entries: `brain-inject` + `session-start` + `observer-publish` on `SessionStart`, `session-ensure` + `evidence-context` + `change-context` on `UserPromptSubmit`, `session-stop` + `observer-publish` + `change-nag` on `Stop`, `subagent-stop` + `observer-publish` on `SubagentStop`, and `change-guard` on `PreToolUse` for `Bash`, `exec_command`, `apply_patch`, and mutable MCP tools, always in the `npx wendkeep hook <name>` form. For the Observer, `SessionStart` only drains the outbox, `Stop` enqueues the changed session, and `SubagentStop` enqueues only the affected transcript; full scanning is explicit through `observer reconcile`. The guard accepts object, raw-string, and argv Codex payloads; before a mutation it compares the session with the project, Git root, remote, branch, and worktree, denying missing or divergent targets. A raw `git checkout/switch` branch transition is denied before it can strand the session; use `wendkeep context switch <branch> [--create]`, which moves Git and the causal scope together in the same worktree with an audited revision and rollback. The other four stay out because Codex offers no equivalent payload, tool, or event: `change-warn` (no reliable `tool_input.file_path`), `plan-capture` (no `ExitPlanMode`), `decision-capture` (`AskUserQuestion` is Claude-only), and `task-log` (`TaskCompleted` is not in Codex's event enum). Codex scope blocks use `permissionDecision: "deny"`; `ask` is never emitted in `PreToolUse`. The merge remains non-destructive, preserves third-party hooks, and migrates legacy `timeout` to `timeoutSec`. **Codex enumerates every hook as untrusted and runs none until you approve the “Hooks need review” prompt at startup — `init` cannot pre-approve them**.
|
|
119
119
|
4. Add the **`wendkeep-vault`** MCP server to `.mcp.json` so the agent can read/write the vault. Skip with `--no-mcp` — e.g. when the agent already has a vault MCP. (`--no-mcp` skips *only wendkeep's own* MCP; companion MCPs still follow `--companions`.)
|
|
120
120
|
5. Offer to pin **companion** plugins/MCP (multi-choice; **none** pre-checked — wendkeep is a neutral harness and presumes no third-party plugin). Each is wired the most agent-agnostic way it supports:
|
|
121
121
|
- **`context-mode`** — context optimizer + FTS5 memory, wired as a Claude Code plugin. It ships its own MCP server, so wendkeep deliberately adds no `.mcp.json` entry (registering both cold-started two servers at once). On non-Claude agents, add the MCP by hand: `npx -y context-mode`.
|
|
@@ -146,6 +146,7 @@ npx wendkeep init --no-companions --no-mcp --yes # zero companions,
|
|
|
146
146
|
| `--no-companions` | Pin no companions. |
|
|
147
147
|
| `--no-mcp` | Skip **wendkeep's own** vault MCP (`wendkeep-vault`). Companion MCPs still follow `--companions`. |
|
|
148
148
|
| `--no-colors` | Skip the Obsidian color system (`.obsidian` snippet + graph groups). |
|
|
149
|
+
| `--vscode-worktree-tasks` | Create a local, Git-excluded `.vscode/tasks.json` for creating/listing/opening worktrees; never overwrites an existing file. Also accepted by `sync`. |
|
|
149
150
|
| `--yes`, `-y` | Non-interactive; accept defaults (skips the language / vault / companion prompts). |
|
|
150
151
|
| `--force` | Overwrite existing wendkeep config blocks. |
|
|
151
152
|
|
|
@@ -237,6 +238,8 @@ The README is the map; the guides provide syntax, options, exit codes, examples,
|
|
|
237
238
|
| Group | Use it for | Detailed guide |
|
|
238
239
|
|---|---|---|
|
|
239
240
|
| **Installation and updates** | `init`, `sync`, companions, and the first project↔vault binding | [Installation and first use](https://github.com/rogersialves/wendkeep/blob/main/docs/en/commands/getting-started.md) |
|
|
241
|
+
| **Managed worktrees** | `worktree create/list/status/open`, Vault binding, and recovery | [Managed worktrees](https://github.com/rogersialves/wendkeep/blob/main/docs/en/commands/worktrees.md) |
|
|
242
|
+
| **Active context** | `context switch`, causal branch transition, and rollback | [Active context](https://github.com/rogersialves/wendkeep/blob/main/docs/en/commands/context.md) |
|
|
240
243
|
| **Operating profiles** | `profile`, `flow`, always-on Keep Core, and Wend Runtime governance | [Operating profiles](https://github.com/rogersialves/wendkeep/blob/main/docs/en/commands/operating-profiles.md) |
|
|
241
244
|
| **Changes and verification** | `change`, specs, sensors, TDD, evidence, and archive | [Changes and verification](https://github.com/rogersialves/wendkeep/blob/main/docs/en/commands/changes-and-verification.md) |
|
|
242
245
|
| **Shared memory** | CORE, SHARED, status, validation, repair, and curation | [Memory](https://github.com/rogersialves/wendkeep/blob/main/docs/en/commands/memory.md) |
|
package/README.md
CHANGED
|
@@ -115,7 +115,7 @@ npx wendkeep init
|
|
|
115
115
|
|
|
116
116
|
1. Create the vault folder taxonomy and a templated `README.md` (default vault: `<project>/.<project-name>-vault`, e.g. `.MyApp-vault`; override with `--vault`).
|
|
117
117
|
2. Write a provider-neutral **`.wendkeep.json`** binding at the project root and a matching `.brain/PROJECT.json` marker in the vault, then merge the session hooks into **`.claude/settings.json`**. The binding is provider-neutral by design: any agent resolves the same vault from its session `cwd`, with no machine-global environment variable. Older registrations already in `.claude/settings.json` are adopted automatically.
|
|
118
|
-
3. Wire the Codex hooks in **`.codex/hooks.json`** — twelve compatible entries: `brain-inject` + `session-start` + `observer-publish` on `SessionStart`, `session-ensure` + `evidence-context` + `change-context` on `UserPromptSubmit`, `session-stop` + `observer-publish` + `change-nag` on `Stop`, `subagent-stop` + `observer-publish` on `SubagentStop`, and `change-guard` on `PreToolUse` for `Bash`, `exec_command`, `apply_patch`, and mutable MCP tools, always in the `npx wendkeep hook <name>` form. For the Observer, `SessionStart` only drains the outbox, `Stop` enqueues the changed session, and `SubagentStop` enqueues only the affected transcript; full scanning is explicit through `observer reconcile`. The guard accepts object, raw-string, and argv Codex payloads; before a mutation it compares the session with the project, Git root, remote, branch, and worktree, denying missing or divergent targets. The other four stay out because Codex offers no equivalent payload, tool, or event: `change-warn` (no reliable `tool_input.file_path`), `plan-capture` (no `ExitPlanMode`), `decision-capture` (`AskUserQuestion` is Claude-only), and `task-log` (`TaskCompleted` is not in Codex's event enum). Codex scope blocks use `permissionDecision: "deny"`; `ask` is never emitted in `PreToolUse`. The merge remains non-destructive, preserves third-party hooks, and migrates legacy `timeout` to `timeoutSec`. **Codex enumerates every hook as untrusted and runs none until you approve the “Hooks need review” prompt at startup — `init` cannot pre-approve them**.
|
|
118
|
+
3. Wire the Codex hooks in **`.codex/hooks.json`** — twelve compatible entries: `brain-inject` + `session-start` + `observer-publish` on `SessionStart`, `session-ensure` + `evidence-context` + `change-context` on `UserPromptSubmit`, `session-stop` + `observer-publish` + `change-nag` on `Stop`, `subagent-stop` + `observer-publish` on `SubagentStop`, and `change-guard` on `PreToolUse` for `Bash`, `exec_command`, `apply_patch`, and mutable MCP tools, always in the `npx wendkeep hook <name>` form. For the Observer, `SessionStart` only drains the outbox, `Stop` enqueues the changed session, and `SubagentStop` enqueues only the affected transcript; full scanning is explicit through `observer reconcile`. The guard accepts object, raw-string, and argv Codex payloads; before a mutation it compares the session with the project, Git root, remote, branch, and worktree, denying missing or divergent targets. A raw `git checkout/switch` branch transition is denied before it can strand the session; use `wendkeep context switch <branch> [--create]`, which moves Git and the causal scope together in the same worktree with an audited revision and rollback. The other four stay out because Codex offers no equivalent payload, tool, or event: `change-warn` (no reliable `tool_input.file_path`), `plan-capture` (no `ExitPlanMode`), `decision-capture` (`AskUserQuestion` is Claude-only), and `task-log` (`TaskCompleted` is not in Codex's event enum). Codex scope blocks use `permissionDecision: "deny"`; `ask` is never emitted in `PreToolUse`. The merge remains non-destructive, preserves third-party hooks, and migrates legacy `timeout` to `timeoutSec`. **Codex enumerates every hook as untrusted and runs none until you approve the “Hooks need review” prompt at startup — `init` cannot pre-approve them**.
|
|
119
119
|
4. Add the **`wendkeep-vault`** MCP server to `.mcp.json` so the agent can read/write the vault. Skip with `--no-mcp` — e.g. when the agent already has a vault MCP. (`--no-mcp` skips *only wendkeep's own* MCP; companion MCPs still follow `--companions`.)
|
|
120
120
|
5. Offer to pin **companion** plugins/MCP (multi-choice; **none** pre-checked — wendkeep is a neutral harness and presumes no third-party plugin). Each is wired the most agent-agnostic way it supports:
|
|
121
121
|
- **`context-mode`** — context optimizer + FTS5 memory, wired as a Claude Code plugin. It ships its own MCP server, so wendkeep deliberately adds no `.mcp.json` entry (registering both cold-started two servers at once). On non-Claude agents, add the MCP by hand: `npx -y context-mode`.
|
|
@@ -146,6 +146,7 @@ npx wendkeep init --no-companions --no-mcp --yes # zero companions,
|
|
|
146
146
|
| `--no-companions` | Pin no companions. |
|
|
147
147
|
| `--no-mcp` | Skip **wendkeep's own** vault MCP (`wendkeep-vault`). Companion MCPs still follow `--companions`. |
|
|
148
148
|
| `--no-colors` | Skip the Obsidian color system (`.obsidian` snippet + graph groups). |
|
|
149
|
+
| `--vscode-worktree-tasks` | Create a local, Git-excluded `.vscode/tasks.json` for creating/listing/opening worktrees; never overwrites an existing file. Also accepted by `sync`. |
|
|
149
150
|
| `--yes`, `-y` | Non-interactive; accept defaults (skips the language / vault / companion prompts). |
|
|
150
151
|
| `--force` | Overwrite existing wendkeep config blocks. |
|
|
151
152
|
|
|
@@ -237,6 +238,8 @@ The README is the map; the guides provide syntax, options, exit codes, examples,
|
|
|
237
238
|
| Group | Use it for | Detailed guide |
|
|
238
239
|
|---|---|---|
|
|
239
240
|
| **Installation and updates** | `init`, `sync`, companions, and the first project↔vault binding | [Installation and first use](https://github.com/rogersialves/wendkeep/blob/main/docs/en/commands/getting-started.md) |
|
|
241
|
+
| **Managed worktrees** | `worktree create/list/status/open`, Vault binding, and recovery | [Managed worktrees](https://github.com/rogersialves/wendkeep/blob/main/docs/en/commands/worktrees.md) |
|
|
242
|
+
| **Active context** | `context switch`, causal branch transition, and rollback | [Active context](https://github.com/rogersialves/wendkeep/blob/main/docs/en/commands/context.md) |
|
|
240
243
|
| **Operating profiles** | `profile`, `flow`, always-on Keep Core, and Wend Runtime governance | [Operating profiles](https://github.com/rogersialves/wendkeep/blob/main/docs/en/commands/operating-profiles.md) |
|
|
241
244
|
| **Changes and verification** | `change`, specs, sensors, TDD, evidence, and archive | [Changes and verification](https://github.com/rogersialves/wendkeep/blob/main/docs/en/commands/changes-and-verification.md) |
|
|
242
245
|
| **Shared memory** | CORE, SHARED, status, validation, repair, and curation | [Memory](https://github.com/rogersialves/wendkeep/blob/main/docs/en/commands/memory.md) |
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
# Active context
|
|
2
|
+
|
|
3
|
+
**English** · [Português](../../pt-BR/commands/context.md)
|
|
4
|
+
|
|
5
|
+
## Purpose
|
|
6
|
+
|
|
7
|
+
Switch the Git branch and the same session's causal scope together inside the current worktree,
|
|
8
|
+
without opening a new session or weakening the guard.
|
|
9
|
+
|
|
10
|
+
## When to use
|
|
11
|
+
|
|
12
|
+
Use `context switch` when an active session must create or select another branch in the same
|
|
13
|
+
worktree and continue mutating the repository after the transition.
|
|
14
|
+
|
|
15
|
+
## When not to use
|
|
16
|
+
|
|
17
|
+
Do not use it to move to another worktree, adopt an already-divergent scope, repair the registry,
|
|
18
|
+
or replace `worktree create`. Those cases require a separate physical context or explicit diagnosis.
|
|
19
|
+
|
|
20
|
+
## Prerequisites
|
|
21
|
+
|
|
22
|
+
- A Git project bound to a Vault through `.wendkeep.json`.
|
|
23
|
+
- An active session with a complete `project_scope` matching the current worktree.
|
|
24
|
+
- Git on `PATH` and a branch accepted by `git check-ref-format --branch`.
|
|
25
|
+
|
|
26
|
+
## Syntax
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
npx --no-install wendkeep context switch <branch> [--create] [--session <id>] [--project <root>] [--vault <vault>] [--json]
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
Without `--session`, exactly one active session must fully match the current scope. `--create`
|
|
33
|
+
uses `git switch -c`; without it, the command follows `git switch` semantics.
|
|
34
|
+
|
|
35
|
+
## Options and exit codes
|
|
36
|
+
|
|
37
|
+
- `--create`: create the branch from the current HEAD.
|
|
38
|
+
- `--session <id>`: select the causal session explicitly; recommended whenever selection is unclear.
|
|
39
|
+
- `--project <root>` and `--vault <vault>`: select the binding and paths for manual use.
|
|
40
|
+
- `--json`: emit status, session id, branch, HEAD, revision, and event without exposing the Vault.
|
|
41
|
+
|
|
42
|
+
Exit `0` means the transition completed or the target was already active. Invalid usage,
|
|
43
|
+
ambiguity, scope mismatch, conflict, Git failure, or rollback returns `2` with a
|
|
44
|
+
`WENDKEEP_CONTEXT_*` code.
|
|
45
|
+
|
|
46
|
+
## Examples
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
npx --no-install wendkeep context switch wk/auth --create
|
|
50
|
+
npx --no-install wendkeep context switch main --session 019abc-session-id
|
|
51
|
+
npx --no-install wendkeep context switch wk/auth --session 019abc-session-id --json
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
Do not replace it with the raw command below while the harness is active:
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
git switch -c wk/auth
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
The guard returns `WENDKEEP_CONTEXT_SWITCH_REQUIRED` before Git runs, preventing the next mutation
|
|
61
|
+
from failing with a scope mismatch.
|
|
62
|
+
|
|
63
|
+
## Expected result
|
|
64
|
+
|
|
65
|
+
The command validates the initial scope under lock, switches branch, proves project, repository,
|
|
66
|
+
remote, worktree, provider, and session id stayed unchanged, increments `context_revision`, and
|
|
67
|
+
appends a `from/to` event to `context_transitions`. The active change, task lease, and existing
|
|
68
|
+
authorizations are preserved.
|
|
69
|
+
|
|
70
|
+
If validation or persistence fails after the switch, rollback restores the previous branch or
|
|
71
|
+
detached HEAD; a branch created by the failed attempt is removed as well.
|
|
72
|
+
|
|
73
|
+
## Common errors and diagnosis
|
|
74
|
+
|
|
75
|
+
- `WENDKEEP_CONTEXT_AMBIGUOUS`: pass `--session <id>`; no candidate is selected silently.
|
|
76
|
+
- `WENDKEEP_CONTEXT_SCOPE_MISMATCH` or `WENDKEEP_CONTEXT_SCOPE_CONFLICT`: return to the reserved
|
|
77
|
+
checkout or diagnose the session; the command never adopts a post-hoc divergence.
|
|
78
|
+
- `WENDKEEP_CONTEXT_CONFLICT`: another active context occupies the target; use another
|
|
79
|
+
branch/worktree or close the competing context correctly.
|
|
80
|
+
- `WENDKEEP_CONTEXT_GIT`: fix the branch, conflicting dirty state, or Git error and retry.
|
|
81
|
+
- `WENDKEEP_CONTEXT_ROLLBACK_FAILED`: preserve Git and registry state and diagnose manually before
|
|
82
|
+
any new mutation.
|
|
83
|
+
- `WENDKEEP_CONTEXT_SWITCH_REQUIRED`: replace the raw Git command with `wendkeep context switch`.
|
|
84
|
+
|
|
85
|
+
## Next steps
|
|
86
|
+
|
|
87
|
+
See [managed worktrees](worktrees.md) to create isolated checkouts and
|
|
88
|
+
[changes and verification](changes-and-verification.md) to continue the lifecycle on the new branch.
|
|
@@ -27,7 +27,7 @@ Do not run `init --force` as a generic repair for memory or unreadable configura
|
|
|
27
27
|
```bash
|
|
28
28
|
npm install --save-dev wendkeep
|
|
29
29
|
npx wendkeep init [options]
|
|
30
|
-
npx wendkeep sync [--project <root>] [--vault <vault>] [--profile <profile>] [--yes]
|
|
30
|
+
npx wendkeep sync [--project <root>] [--vault <vault>] [--profile <profile>] [--yes] [--vscode-worktree-tasks]
|
|
31
31
|
```
|
|
32
32
|
|
|
33
33
|
## Options and exit codes
|
|
@@ -37,6 +37,8 @@ npx wendkeep sync [--project <root>] [--vault <vault>] [--profile <profile>] [--
|
|
|
37
37
|
- `--profile <OFF|FLOW|GUIDE|GOVERN|ASSURE>` selects the Operating Profile; new installs use
|
|
38
38
|
`GOVERN`, re-init/sync without the flag preserves the existing choice, and `OFF` is never inferred.
|
|
39
39
|
- `--no-mcp`, `--no-colors`, and `--no-companions` disable optional integrations.
|
|
40
|
+
- `--vscode-worktree-tasks` creates local VS Code tasks without overwriting `tasks.json`; `sync`
|
|
41
|
+
forwards the same flag to its `init` stage.
|
|
40
42
|
- `--companions <csv>` explicitly enables companion integrations.
|
|
41
43
|
- `--yes` accepts non-interactive defaults; `--force` refreshes managed blocks only.
|
|
42
44
|
- Exit `0` means setup/sync completed. Any other exit identifies the failed stage. `sync` stops at
|
|
@@ -37,6 +37,9 @@ npx --no-install wendkeep --help
|
|
|
37
37
|
also fails on workflow attention, repairable debt, semantic degradation, and warnings.
|
|
38
38
|
- `--scope core` checks the installation, binding, ledger, and Keep Core only. `--scope runtime`
|
|
39
39
|
checks changes, sensors, and governance only. The default `all` reports both surfaces.
|
|
40
|
+
- The `[worktrees]` section reconciles the private registry with Git and reports slugs in
|
|
41
|
+
`failed`, `missing`, or invalid-binding states. Under `--strict` this debt also fails; doctor
|
|
42
|
+
never performs the repair.
|
|
40
43
|
- `doctor` uses human-readable output with `[integrity]` and `[memory]` sections, friendly
|
|
41
44
|
categories, and a copyable next action. The `vault-health.mjs` hook remains the JSON surface for
|
|
42
45
|
automation; neither surface applies curation.
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
# Managed worktrees
|
|
2
|
+
|
|
3
|
+
**English** · [Português](../../pt-BR/commands/worktrees.md)
|
|
4
|
+
|
|
5
|
+
## Purpose
|
|
6
|
+
|
|
7
|
+
Create isolated linked worktrees that remain bound to the same project and canonical Vault,
|
|
8
|
+
without copying private state into versioned files.
|
|
9
|
+
|
|
10
|
+
## When to use
|
|
11
|
+
|
|
12
|
+
Use it to start isolated implementation work, list managed checkouts, diagnose a partial create,
|
|
13
|
+
or open an already-ready worktree in VS Code.
|
|
14
|
+
|
|
15
|
+
## When not to use
|
|
16
|
+
|
|
17
|
+
Do not use it to remove, merge, or self-merge worktrees. Those operations remain outside this
|
|
18
|
+
capability.
|
|
19
|
+
|
|
20
|
+
## Prerequisites
|
|
21
|
+
|
|
22
|
+
- A Git repository whose project is already bound to its Vault through `.wendkeep.json`.
|
|
23
|
+
- Git on `PATH`; opening also requires the VS Code `code` command.
|
|
24
|
+
|
|
25
|
+
## Syntax
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
npx --no-install wendkeep worktree create <slug> [--base <ref>] [--branch <name>] [--open vscode|none] [--json]
|
|
29
|
+
npx --no-install wendkeep worktree list [--json]
|
|
30
|
+
npx --no-install wendkeep worktree status [<slug>] [--json]
|
|
31
|
+
npx --no-install wendkeep worktree open <slug> [--editor vscode] [--json]
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
All commands accept `--project <root>`. By default, create uses `.worktrees/<slug>`, the detected
|
|
35
|
+
base, and branch `wk/<slug>`. When configured, `worktrees.root` must be a
|
|
36
|
+
non-empty relative path. Git validates slugs and branches; paths escaping the root or crossing a
|
|
37
|
+
symlink/junction are rejected before mutation.
|
|
38
|
+
|
|
39
|
+
## Options and exit codes
|
|
40
|
+
|
|
41
|
+
The registry lives in the Git common-dir at `wendkeep/worktrees-v1.json`, protected by a
|
|
42
|
+
multi-process lock. It stores repository/worktree identity and the canonical binding;
|
|
43
|
+
`.wendkeep.json` stays unchanged. `.worktrees/` is added to both the versioned ignore and the
|
|
44
|
+
repository-private exclude. JSON `list`/`status` output exposes neither Vault paths nor contents.
|
|
45
|
+
For each worktree, human output shows its slug, identity, checkout path, branch, HEAD, state, and
|
|
46
|
+
binding health.
|
|
47
|
+
|
|
48
|
+
`create` is idempotent when slug, path, and branch already match. Collisions fail closed. Failures
|
|
49
|
+
after reservation remain `failed`; run `worktree status <slug>` and follow the `recovery` field.
|
|
50
|
+
`doctor` also reports this debt under `[worktrees]` without repairing it.
|
|
51
|
+
|
|
52
|
+
## VS Code and exit codes
|
|
53
|
+
|
|
54
|
+
`--open vscode` and `worktree open` validate `code --version`, then open a new window with
|
|
55
|
+
`code -n`. Use `init --vscode-worktree-tasks` or `sync --vscode-worktree-tasks` to create local
|
|
56
|
+
tasks; an existing or tracked `.vscode/tasks.json`, even when deleted in the checkout, is never
|
|
57
|
+
overwritten.
|
|
58
|
+
|
|
59
|
+
Exit `0` means success. Usage, binding, safety, Git, or editor failures return `2` with a stable
|
|
60
|
+
`WENDKEEP_WORKTREE_*` code. The command never removes or merges a worktree.
|
|
61
|
+
|
|
62
|
+
## Examples
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
npx --no-install wendkeep worktree create auth --open vscode
|
|
66
|
+
npx --no-install wendkeep worktree status auth --json
|
|
67
|
+
npx --no-install wendkeep worktree list
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
## Expected result
|
|
71
|
+
|
|
72
|
+
`create auth` produces `.worktrees/auth` on branch `wk/auth`; the main and linked worktrees resolve
|
|
73
|
+
the same `projectId` and Vault, while the main checkout remains clean.
|
|
74
|
+
|
|
75
|
+
## Common errors and diagnosis
|
|
76
|
+
|
|
77
|
+
- `WENDKEEP_WORKTREE_SLUG_INVALID`, `WENDKEEP_WORKTREE_BRANCH_INVALID`, or
|
|
78
|
+
`WENDKEEP_WORKTREE_ROOT_INVALID`: correct the input before retrying; no reservation is created.
|
|
79
|
+
- `WENDKEEP_WORKTREE_PATH_OUTSIDE_ROOT` or `WENDKEEP_WORKTREE_PATH_SYMLINK_ESCAPE`: use a relative
|
|
80
|
+
root contained in the main worktree, without an intermediate symlink/junction.
|
|
81
|
+
- `WENDKEEP_WORKTREE_COLLISION`: the slug, path, or branch represents different state; run `status`.
|
|
82
|
+
- `WENDKEEP_WORKTREE_GIT_FAILED` or `WENDKEEP_WORKTREE_BASE_UNRESOLVED`: repair the Git state and
|
|
83
|
+
retry the command shown in `recovery`.
|
|
84
|
+
- `WENDKEEP_WORKTREE_REGISTRY_*`, `WENDKEEP_WORKTREE_*_MISMATCH`, or `WENDKEEP_VAULT_*` errors:
|
|
85
|
+
preserve the artifacts and use `doctor` to diagnose the registry/binding.
|
|
86
|
+
- `WENDKEEP_WORKTREE_EDITOR_NOT_FOUND` or `WENDKEEP_WORKTREE_EDITOR_OPEN_FAILED`: make `code`
|
|
87
|
+
available on PATH or use `--open none`.
|
|
88
|
+
- `failed`/`missing` state: read `recovery` from `status --json` and doctor's `[worktrees]` section.
|
|
89
|
+
|
|
90
|
+
## Next steps
|
|
91
|
+
|
|
92
|
+
See [installation and first use](getting-started.md) for local VS Code tasks and
|
|
93
|
+
[maintenance and diagnostics](maintenance-and-diagnostics.md) for doctor.
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
# Contexto ativo
|
|
2
|
+
|
|
3
|
+
**PT-BR** · [English](../../en/commands/context.md)
|
|
4
|
+
|
|
5
|
+
## Objetivo
|
|
6
|
+
|
|
7
|
+
Trocar a branch Git e a scope causal da mesma sessão juntas, dentro da worktree atual, sem abrir
|
|
8
|
+
uma nova sessão e sem relaxar o guard.
|
|
9
|
+
|
|
10
|
+
## Quando usar
|
|
11
|
+
|
|
12
|
+
Use `context switch` quando uma sessão ativa precisa criar ou selecionar outra branch na mesma
|
|
13
|
+
worktree e deve continuar mutando o repositório depois da troca.
|
|
14
|
+
|
|
15
|
+
## Quando não usar
|
|
16
|
+
|
|
17
|
+
Não use para mudar de worktree, adotar uma scope já divergente, reparar o registry ou substituir
|
|
18
|
+
`worktree create`. Esses casos exigem outro contexto físico ou diagnóstico explícito.
|
|
19
|
+
|
|
20
|
+
## Pré-requisitos
|
|
21
|
+
|
|
22
|
+
- Projeto Git vinculado a um Vault por `.wendkeep.json`.
|
|
23
|
+
- Sessão ativa com `project_scope` completa e correspondente à worktree atual.
|
|
24
|
+
- Git disponível no `PATH` e branch válida segundo `git check-ref-format --branch`.
|
|
25
|
+
|
|
26
|
+
## Sintaxe
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
npx --no-install wendkeep context switch <branch> [--create] [--session <id>] [--project <raiz>] [--vault <cofre>] [--json]
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
Sem `--session`, exatamente uma sessão ativa deve corresponder integralmente à scope atual. Use
|
|
33
|
+
`--create` para executar `git switch -c`; sem a flag, a semântica é `git switch`.
|
|
34
|
+
|
|
35
|
+
## Opções e códigos de saída
|
|
36
|
+
|
|
37
|
+
- `--create`: cria a branch a partir do HEAD atual.
|
|
38
|
+
- `--session <id>`: seleciona explicitamente a sessão causal; recomendado quando houver dúvida.
|
|
39
|
+
- `--project <raiz>` e `--vault <cofre>`: selecionam binding e paths para uso manual.
|
|
40
|
+
- `--json`: emite status, session id, branch, HEAD, revisão e evento sem expor o Vault.
|
|
41
|
+
|
|
42
|
+
Exit `0` significa transição concluída ou destino já ativo. Uso inválido, ambiguidade,
|
|
43
|
+
scope divergente, conflito, falha Git ou rollback retorna `2` com um código `WENDKEEP_CONTEXT_*`.
|
|
44
|
+
|
|
45
|
+
## Exemplos
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
npx --no-install wendkeep context switch wk/auth --create
|
|
49
|
+
npx --no-install wendkeep context switch main --session 019abc-session-id
|
|
50
|
+
npx --no-install wendkeep context switch wk/auth --session 019abc-session-id --json
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
Não substitua pelo comando cru abaixo quando o harness estiver ativo:
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
git switch -c wk/auth
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
O guard responde `WENDKEEP_CONTEXT_SWITCH_REQUIRED` antes do Git, evitando que a próxima mutação
|
|
60
|
+
falhe por mismatch.
|
|
61
|
+
|
|
62
|
+
## Resultado esperado
|
|
63
|
+
|
|
64
|
+
O comando valida a scope inicial sob lock, troca a branch, prova que projeto, repositório, remoto,
|
|
65
|
+
worktree, provider e session id não mudaram, incrementa `context_revision` e anexa um evento
|
|
66
|
+
`from/to` em `context_transitions`. Change ativa, task lease e autorizações são preservadas.
|
|
67
|
+
|
|
68
|
+
Se qualquer validação ou persistência falhar depois do switch, o rollback restaura a branch ou
|
|
69
|
+
detached HEAD anterior; uma branch criada pela tentativa também é removida.
|
|
70
|
+
|
|
71
|
+
## Erros comuns e diagnóstico
|
|
72
|
+
|
|
73
|
+
- `WENDKEEP_CONTEXT_AMBIGUOUS`: informe `--session <id>`; nenhuma candidata é escolhida em silêncio.
|
|
74
|
+
- `WENDKEEP_CONTEXT_SCOPE_MISMATCH` ou `WENDKEEP_CONTEXT_SCOPE_CONFLICT`: volte ao checkout
|
|
75
|
+
reservado ou diagnostique a sessão; o comando não adota uma divergência posterior.
|
|
76
|
+
- `WENDKEEP_CONTEXT_CONFLICT`: outro contexto ativo ocupa o destino; use outra branch/worktree ou
|
|
77
|
+
encerre corretamente o contexto concorrente.
|
|
78
|
+
- `WENDKEEP_CONTEXT_GIT`: corrija a branch, dirty state conflitante ou erro do Git e repita.
|
|
79
|
+
- `WENDKEEP_CONTEXT_ROLLBACK_FAILED`: preserve Git e registry e faça diagnóstico manual antes de
|
|
80
|
+
qualquer nova mutação.
|
|
81
|
+
- `WENDKEEP_CONTEXT_SWITCH_REQUIRED`: troque o comando Git cru por `wendkeep context switch`.
|
|
82
|
+
|
|
83
|
+
## Próximos passos
|
|
84
|
+
|
|
85
|
+
Veja [worktrees gerenciadas](worktrees.md) para criar checkouts isolados e
|
|
86
|
+
[changes e verificação](changes-and-verification.md) para continuar o lifecycle na nova branch.
|
|
@@ -27,7 +27,7 @@ Não rode `init --force` para tentar reparar memória ou uma configuração ileg
|
|
|
27
27
|
```bash
|
|
28
28
|
npm install --save-dev wendkeep
|
|
29
29
|
npx wendkeep init [opções]
|
|
30
|
-
npx wendkeep sync [--project <raiz>] [--vault <cofre>] [--profile <perfil>] [--yes]
|
|
30
|
+
npx wendkeep sync [--project <raiz>] [--vault <cofre>] [--profile <perfil>] [--yes] [--vscode-worktree-tasks]
|
|
31
31
|
```
|
|
32
32
|
|
|
33
33
|
## Opções e códigos de saída
|
|
@@ -37,6 +37,8 @@ npx wendkeep sync [--project <raiz>] [--vault <cofre>] [--profile <perfil>] [--y
|
|
|
37
37
|
- `--profile <OFF|FLOW|GUIDE|GOVERN|ASSURE>` seleciona o Perfil de Operação; instalação nova usa
|
|
38
38
|
`GOVERN`, re-init/sync sem a flag preserva a escolha existente e `OFF` nunca é inferido.
|
|
39
39
|
- `--no-mcp`, `--no-colors` e `--no-companions` desativam integrações opcionais.
|
|
40
|
+
- `--vscode-worktree-tasks` cria tarefas locais do VS Code sem sobrescrever `tasks.json`; `sync`
|
|
41
|
+
repassa a mesma flag ao seu estágio `init`.
|
|
40
42
|
- `--companions <csv>` habilita companions explicitamente.
|
|
41
43
|
- `--yes` aceita defaults não interativos; `--force` atualiza apenas blocos gerenciados.
|
|
42
44
|
- Exit `0` indica instalação/sincronização concluída; exit diferente de zero identifica a etapa
|
|
@@ -37,6 +37,8 @@ npx --no-install wendkeep --help
|
|
|
37
37
|
atenção de workflow, dívida reparável e memória degradada apropriadas para gate de CI/release.
|
|
38
38
|
- `--scope core` verifica somente instalação, identidade, sessão e memória; `sync` usa esse escopo
|
|
39
39
|
e não falha por change ainda em andamento. `--scope runtime` isola harness/governança.
|
|
40
|
+
- O bloco `[worktrees]` reconcilia o registry privado com o Git e aponta slugs em `failed`,
|
|
41
|
+
`missing` ou com binding inválido. Em `--strict`, essa dívida também falha; o doctor não repara.
|
|
40
42
|
- O `doctor` usa saída em formato humano, com blocos `[integridade]` e `[memória]`, categorias
|
|
41
43
|
amigáveis e uma próxima ação copiável. O hook `vault-health.mjs` continua sendo a superfície JSON
|
|
42
44
|
para automações; nenhum dos dois aplica curadoria.
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
# Worktrees gerenciadas
|
|
2
|
+
|
|
3
|
+
**PT-BR** · [English](../../en/commands/worktrees.md)
|
|
4
|
+
|
|
5
|
+
## Objetivo
|
|
6
|
+
|
|
7
|
+
Criar linked worktrees isoladas que continuam vinculadas ao mesmo projeto e Vault canônico,
|
|
8
|
+
sem copiar estado privado para arquivos versionados.
|
|
9
|
+
|
|
10
|
+
## Quando usar
|
|
11
|
+
|
|
12
|
+
Use ao iniciar uma implementação isolada, listar checkouts gerenciados, diagnosticar uma criação
|
|
13
|
+
parcial ou abrir uma worktree já pronta no VS Code.
|
|
14
|
+
|
|
15
|
+
## Quando não usar
|
|
16
|
+
|
|
17
|
+
Não use para remover, mesclar ou fazer self-merge de worktrees. Essas operações permanecem fora
|
|
18
|
+
desta capability.
|
|
19
|
+
|
|
20
|
+
## Pré-requisitos
|
|
21
|
+
|
|
22
|
+
- Repositório Git com o projeto já vinculado ao Vault por `.wendkeep.json`.
|
|
23
|
+
- Git disponível no `PATH`; para abertura, o comando `code` do VS Code também deve existir.
|
|
24
|
+
|
|
25
|
+
## Sintaxe
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
npx --no-install wendkeep worktree create <slug> [--base <ref>] [--branch <nome>] [--open vscode|none] [--json]
|
|
29
|
+
npx --no-install wendkeep worktree list [--json]
|
|
30
|
+
npx --no-install wendkeep worktree status [<slug>] [--json]
|
|
31
|
+
npx --no-install wendkeep worktree open <slug> [--editor vscode] [--json]
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
Todas aceitam `--project <raiz>`. O padrão cria `.worktrees/<slug>` a partir da base detectada e
|
|
35
|
+
usa a branch `wk/<slug>`. `worktrees.root`, quando configurado, deve ser um
|
|
36
|
+
path relativo não vazio. Slug e branch são validados pelo Git; paths que escapam da raiz ou
|
|
37
|
+
atravessam symlink/junction são rejeitados antes da mutação.
|
|
38
|
+
|
|
39
|
+
## Opções e códigos de saída
|
|
40
|
+
|
|
41
|
+
O registry fica no Git common-dir, em `wendkeep/worktrees-v1.json`, sob lock multiprocesso. Ele
|
|
42
|
+
guarda identidade do repositório/worktree e o binding canônico; `.wendkeep.json` permanece
|
|
43
|
+
inalterado. `.worktrees/` entra no ignore versionado e no exclude privado do repositório. A saída
|
|
44
|
+
JSON de `list`/`status` não expõe path nem conteúdo do Vault. A saída humana apresenta, por
|
|
45
|
+
worktree, slug, identidade, path do checkout, branch, HEAD, estado e saúde do binding.
|
|
46
|
+
|
|
47
|
+
`create` é idempotente quando slug, path e branch já correspondem. Colisões falham fechadas.
|
|
48
|
+
Falhas depois da reserva ficam como `failed`; rode `worktree status <slug>` e siga o campo
|
|
49
|
+
`recovery`. `doctor` também lista dívida em `[worktrees]` sem repará-la.
|
|
50
|
+
|
|
51
|
+
## VS Code e códigos de saída
|
|
52
|
+
|
|
53
|
+
`--open vscode` e `worktree open` validam `code --version` e abrem uma janela nova com `code -n`.
|
|
54
|
+
Use `init --vscode-worktree-tasks` ou `sync --vscode-worktree-tasks` para criar tarefas locais;
|
|
55
|
+
um `.vscode/tasks.json` existente ou rastreado, mesmo removido no checkout, nunca é sobrescrito.
|
|
56
|
+
|
|
57
|
+
Exit `0` indica sucesso. Erro de uso, binding, segurança, Git ou editor retorna `2` com código
|
|
58
|
+
estável `WENDKEEP_WORKTREE_*`. O comando nunca remove ou mescla uma worktree.
|
|
59
|
+
|
|
60
|
+
## Exemplos
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
npx --no-install wendkeep worktree create auth --open vscode
|
|
64
|
+
npx --no-install wendkeep worktree status auth --json
|
|
65
|
+
npx --no-install wendkeep worktree list
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
## Resultado esperado
|
|
69
|
+
|
|
70
|
+
`create auth` produz `.worktrees/auth` na branch `wk/auth`; main e linked worktree resolvem o
|
|
71
|
+
mesmo `projectId` e Vault, e o checkout principal permanece limpo.
|
|
72
|
+
|
|
73
|
+
## Erros comuns e diagnóstico
|
|
74
|
+
|
|
75
|
+
- `WENDKEEP_WORKTREE_SLUG_INVALID`, `WENDKEEP_WORKTREE_BRANCH_INVALID` ou
|
|
76
|
+
`WENDKEEP_WORKTREE_ROOT_INVALID`: corrija a entrada antes de repetir; nenhuma reserva é criada.
|
|
77
|
+
- `WENDKEEP_WORKTREE_PATH_OUTSIDE_ROOT` ou `WENDKEEP_WORKTREE_PATH_SYMLINK_ESCAPE`: use uma raiz
|
|
78
|
+
relativa contida no main worktree, sem symlink/junction intermediário.
|
|
79
|
+
- `WENDKEEP_WORKTREE_COLLISION`: slug, path ou branch já representa outro estado; rode `status`.
|
|
80
|
+
- `WENDKEEP_WORKTREE_GIT_FAILED` ou `WENDKEEP_WORKTREE_BASE_UNRESOLVED`: corrija o estado Git e
|
|
81
|
+
repita o comando indicado em `recovery`.
|
|
82
|
+
- Erros `WENDKEEP_WORKTREE_REGISTRY_*`, `WENDKEEP_WORKTREE_*_MISMATCH` ou
|
|
83
|
+
`WENDKEEP_VAULT_*`: preserve os artefatos e use `doctor` para diagnosticar registry/binding.
|
|
84
|
+
- `WENDKEEP_WORKTREE_EDITOR_NOT_FOUND` ou `WENDKEEP_WORKTREE_EDITOR_OPEN_FAILED`: disponibilize
|
|
85
|
+
`code` no PATH ou use `--open none`.
|
|
86
|
+
- Estado `failed`/`missing`: leia `recovery` em `status --json` e o bloco `[worktrees]` do `doctor`.
|
|
87
|
+
|
|
88
|
+
## Próximos passos
|
|
89
|
+
|
|
90
|
+
Veja [instalação e primeiro uso](getting-started.md) para tarefas locais do VS Code e
|
|
91
|
+
[manutenção e diagnóstico](maintenance-and-diagnostics.md) para o doctor.
|
|
@@ -27,7 +27,7 @@ export const FLOW_PROTECTED_SCAN_POLICY = Object.freeze({
|
|
|
27
27
|
maxDepth: 64,
|
|
28
28
|
maxEntries: 100_000,
|
|
29
29
|
excludedDirectoryNames: Object.freeze([
|
|
30
|
-
'.git', 'node_modules', '.pnpm-store', '.yarn', '.venv', 'venv',
|
|
30
|
+
'.git', '.worktrees', 'node_modules', '.pnpm-store', '.yarn', '.venv', 'venv',
|
|
31
31
|
'__pycache__', '.pytest_cache', '.mypy_cache', '.ruff_cache', '.tox', '.nox',
|
|
32
32
|
]),
|
|
33
33
|
});
|
package/hooks/project-scope.mjs
CHANGED
|
@@ -115,11 +115,15 @@ function invocationOf(segment) {
|
|
|
115
115
|
if (executable === 'git' || executable === 'git.exe' || executable === 'git.cmd') {
|
|
116
116
|
return { kind: 'git', args: segment.slice(index + 1).map(unquote) };
|
|
117
117
|
}
|
|
118
|
+
const args = segment.slice(index + 1).map(unquote);
|
|
119
|
+
if (isWendKeepContextSwitch(executable, args)) {
|
|
120
|
+
return { kind: 'context-switch', args };
|
|
121
|
+
}
|
|
118
122
|
if (['rm', 'rm.exe', 'del', 'erase', 'remove-item', 'move-item', 'set-content', 'out-file', 'copy-item', 'new-item'].includes(executable)) {
|
|
119
|
-
return { kind: 'filesystem', args
|
|
123
|
+
return { kind: 'filesystem', args };
|
|
120
124
|
}
|
|
121
|
-
if (isPublicationInvocation(executable,
|
|
122
|
-
return { kind: 'publication', args
|
|
125
|
+
if (isPublicationInvocation(executable, args)) {
|
|
126
|
+
return { kind: 'publication', args };
|
|
123
127
|
}
|
|
124
128
|
return null;
|
|
125
129
|
}
|
|
@@ -133,6 +137,24 @@ function isWendKeepPublication(args) {
|
|
|
133
137
|
return command === 'publish' || command === 'release';
|
|
134
138
|
}
|
|
135
139
|
|
|
140
|
+
function isWendKeepContextSwitch(executable, args) {
|
|
141
|
+
let commandArgs = args;
|
|
142
|
+
if (['node', 'node.exe'].includes(executable)) {
|
|
143
|
+
const entrypoint = args.findIndex((arg) => executableName(arg) === 'wendkeep.mjs');
|
|
144
|
+
if (entrypoint < 0) return false;
|
|
145
|
+
commandArgs = args.slice(entrypoint + 1);
|
|
146
|
+
} else if (['npx', 'npx.cmd'].includes(executable)) {
|
|
147
|
+
const packageIndex = args.findIndex((arg) => ['wendkeep', 'wk'].includes(executableName(arg)));
|
|
148
|
+
if (packageIndex < 0) return false;
|
|
149
|
+
commandArgs = args.slice(packageIndex + 1);
|
|
150
|
+
} else if (!['wendkeep', 'wendkeep.cmd', 'wk', 'wk.cmd'].includes(executable)) {
|
|
151
|
+
return false;
|
|
152
|
+
}
|
|
153
|
+
const command = firstNonOption(commandArgs);
|
|
154
|
+
const commandIndex = commandArgs.findIndex((arg) => String(arg).toLowerCase() === command);
|
|
155
|
+
return command === 'context' && String(commandArgs[commandIndex + 1] || '').toLowerCase() === 'switch';
|
|
156
|
+
}
|
|
157
|
+
|
|
136
158
|
function isPublicationInvocation(executable, args) {
|
|
137
159
|
if (['npm', 'npm.cmd', 'pnpm', 'pnpm.cmd', 'yarn', 'yarn.cmd', 'bun', 'bun.exe'].includes(executable)) {
|
|
138
160
|
const command = firstNonOption(args);
|
|
@@ -214,12 +236,27 @@ export function scopeActionsForCommand(command) {
|
|
|
214
236
|
const actions = [];
|
|
215
237
|
for (const invocation of commandInvocations(command)) {
|
|
216
238
|
if (invocation.kind === 'git') actions.push(gitAction(invocation.args));
|
|
239
|
+
if (invocation.kind === 'context-switch') actions.push('git:destructive');
|
|
217
240
|
if (invocation.kind === 'filesystem') actions.push('filesystem:mutation');
|
|
218
241
|
if (invocation.kind === 'publication') actions.push('publish');
|
|
219
242
|
}
|
|
220
243
|
return [...new Set(actions.filter(Boolean))];
|
|
221
244
|
}
|
|
222
245
|
|
|
246
|
+
export function commandChangesGitBranch(command) {
|
|
247
|
+
return commandInvocations(command).some((invocation) => {
|
|
248
|
+
if (invocation.kind !== 'git') return false;
|
|
249
|
+
const subcommand = firstGitSubcommand(invocation.args);
|
|
250
|
+
if (subcommand === 'switch') return true;
|
|
251
|
+
if (subcommand !== 'checkout') return false;
|
|
252
|
+
const subcommandIndex = invocation.args.findIndex((arg) => String(arg).toLowerCase() === 'checkout');
|
|
253
|
+
const checkoutArgs = invocation.args.slice(subcommandIndex + 1);
|
|
254
|
+
if (!checkoutArgs.length || checkoutArgs.includes('--')) return false;
|
|
255
|
+
if (checkoutArgs.includes('-p') || checkoutArgs.includes('--patch') || checkoutArgs.includes('--help')) return false;
|
|
256
|
+
return true;
|
|
257
|
+
});
|
|
258
|
+
}
|
|
259
|
+
|
|
223
260
|
export function commandChangesDirectory(command) {
|
|
224
261
|
return shellSegments(command).some((segment) => {
|
|
225
262
|
const executable = executableName(segment[0]);
|
|
@@ -333,7 +370,14 @@ export function concurrentScopeConflicts(expectedScope, activeSessions = [], cur
|
|
|
333
370
|
if (!entry || String(sessionId) === String(current) || String(entry.sessionId || '') === String(current)) continue;
|
|
334
371
|
if (entry.status && entry.status !== 'active') continue;
|
|
335
372
|
const other = entry.project_scope || entry.projectScope || (entry.complete !== undefined ? entry : null);
|
|
336
|
-
if (!other
|
|
373
|
+
if (!other) {
|
|
374
|
+
conflicts.push({ sessionId: String(sessionId), reason: 'scope-unavailable' });
|
|
375
|
+
continue;
|
|
376
|
+
}
|
|
377
|
+
const leftWorktree = comparableScopeValue(expectedScope, 'worktree');
|
|
378
|
+
const rightWorktree = comparableScopeValue(other, 'worktree');
|
|
379
|
+
if (leftWorktree && rightWorktree && leftWorktree !== rightWorktree) continue;
|
|
380
|
+
if (other.complete !== true) {
|
|
337
381
|
conflicts.push({ sessionId: String(sessionId), reason: 'scope-unavailable' });
|
|
338
382
|
continue;
|
|
339
383
|
}
|
|
@@ -343,8 +387,6 @@ export function concurrentScopeConflicts(expectedScope, activeSessions = [], cur
|
|
|
343
387
|
return Boolean(left && right && left === right);
|
|
344
388
|
});
|
|
345
389
|
if (!sameRepositoryBranch) continue;
|
|
346
|
-
const leftWorktree = comparableScopeValue(expectedScope, 'worktree');
|
|
347
|
-
const rightWorktree = comparableScopeValue(other, 'worktree');
|
|
348
390
|
if (!leftWorktree || !rightWorktree || leftWorktree === rightWorktree) {
|
|
349
391
|
conflicts.push({ sessionId: String(sessionId), reason: 'same-repository-branch' });
|
|
350
392
|
}
|
|
@@ -388,6 +430,9 @@ export function scopeDecision({
|
|
|
388
430
|
if (concurrent.length) {
|
|
389
431
|
return decision(host, `WENDKEEP_SCOPE_CONFLICT: há ${concurrent.length} sessão(ões) ativa(s) com a mesma raiz Git/branch ou escopo não comprovado; use um worktree distinto ou selecione explicitamente o projeto para criar uma nova lease.`);
|
|
390
432
|
}
|
|
433
|
+
if (commandChangesGitBranch(command)) {
|
|
434
|
+
return decision(host, 'WENDKEEP_CONTEXT_SWITCH_REQUIRED: troca de branch Git crua deixaria a sessão fora da scope reservada; use `wendkeep context switch <branch> [--create] [--session <id>]`.');
|
|
435
|
+
}
|
|
391
436
|
const authorized = Array.isArray(expectedScope.authorizedActions)
|
|
392
437
|
? expectedScope.authorizedActions
|
|
393
438
|
: null;
|