jjhub 0.1.14 → 0.2.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/README.md +3 -3
- package/dist/cli/jjhub.mjs +14133 -4545
- package/package.json +2 -2
- package/skills/jjhub-cli/SKILL.md +148 -7
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "jjhub",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "jjhub — GitHub CLI with Jujutsu-native superpowers: stable change IDs, stacks, platform-wide undo, and conflicts that wait, layered over plain GitHub repos by a JJHub server.",
|
|
5
5
|
"bin": {
|
|
6
6
|
"jjhub": "./dist/cli/jjhub.mjs"
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
"node": ">=22.6.0"
|
|
11
11
|
},
|
|
12
12
|
"license": "UNLICENSED",
|
|
13
|
-
"homepage": "https://jjhub.
|
|
13
|
+
"homepage": "https://jjhub.erisera.com",
|
|
14
14
|
"keywords": [
|
|
15
15
|
"jujutsu",
|
|
16
16
|
"jj",
|
|
@@ -51,7 +51,11 @@ repo delete hard-delete incl. op log (ops credential
|
|
|
51
51
|
|
|
52
52
|
user list list known users (identity is GitHub-federated)
|
|
53
53
|
|
|
54
|
-
change new <title> [--parent CHG-x] [--stack id]
|
|
54
|
+
change new <title> [--parent CHG-x] [--stack id] [--route same-repo|unprojected|fork:<owner/name>]
|
|
55
|
+
--route (issue #277): same-repo is the default; unprojected
|
|
56
|
+
creates the change with no GitHub branch/PR ever; fork:<owner/name>
|
|
57
|
+
is recorded but refused at projection time until real fork-PR
|
|
58
|
+
projection ships
|
|
55
59
|
change list
|
|
56
60
|
change show <changeId>
|
|
57
61
|
change describe <changeId> [--title t] [--description d]
|
|
@@ -59,33 +63,113 @@ change amend <changeId>
|
|
|
59
63
|
change squash <changeId>
|
|
60
64
|
change abandon <changeId>
|
|
61
65
|
change restack <changeId> rebase a needs-restack change onto its rewritten ancestor
|
|
62
|
-
change commit <changeId> [<file...>] [-m msg] [--delete <path>]...
|
|
66
|
+
change commit <changeId> [<file...>] [-m msg] [--delete <path>]... [--expect-head <sha>]
|
|
63
67
|
commit working-tree files onto the change's branch;
|
|
64
|
-
--delete removes a path in the same commit (repeatable)
|
|
68
|
+
--delete removes a path in the same commit (repeatable);
|
|
69
|
+
--expect-head refuses (409) if the change moved since <sha>
|
|
70
|
+
change propose <title> [<file...>] [--parent CHG-x] [--stack id] [-m msg]
|
|
71
|
+
[--delete <path>]... [--expect-base <sha>]
|
|
72
|
+
issue #374: create + commit in one call, printing the diff
|
|
73
|
+
summary and PR link; --expect-base checks --parent's current
|
|
74
|
+
commit; on partial failure the error names the created change
|
|
75
|
+
id (still listed/abandon-able)
|
|
65
76
|
change diff <changeId> per-file diffs of what the change contains
|
|
66
77
|
change files <changeId> list locally-stored files (contentMode "local" repos only)
|
|
67
|
-
change land <changeId> [--force]
|
|
68
|
-
|
|
78
|
+
change land <changeId> [--force] [--expect-head <sha>]
|
|
79
|
+
waits for real CI triggered by its own ready flip,
|
|
80
|
+
re-syncs a behind branch, then merges; --force bypasses;
|
|
81
|
+
--expect-head refuses (409) if the change moved since <sha>
|
|
82
|
+
change enqueue <changeId> add a review-ready pull request to GitHub's merge queue;
|
|
83
|
+
GitHub owns the merge from here, JJHub marks the change
|
|
84
|
+
landed once GitHub reports it merged
|
|
85
|
+
change dequeue <changeId> withdraw a JJHub-queued pull request back to explicit review
|
|
86
|
+
change queue-status <changeId> print the merge-queue receipt (position/state/merge-group
|
|
87
|
+
sha/checks/removed reason) plus whether GitHub auto-merge
|
|
88
|
+
is armed on the pull request
|
|
69
89
|
change split <changeId> <newTitle>
|
|
70
90
|
change checks <changeId> list GitHub check runs for a change
|
|
71
91
|
change actions <changeId> show bounded GitHub Actions workflow and job evidence
|
|
92
|
+
change actions rerun <changeId> <runId>
|
|
93
|
+
ask GitHub to re-run a workflow run shown by "change actions"
|
|
94
|
+
change actions cancel <changeId> <runId>
|
|
95
|
+
ask GitHub to cancel a workflow run shown by "change actions"
|
|
72
96
|
change deployments <changeId> show bounded GitHub deployment evidence
|
|
73
97
|
change security <changeId> show bounded GitHub code-scanning evidence
|
|
74
98
|
change issues <changeId> show linked GitHub issue context for a change
|
|
99
|
+
change reviewers <changeId> reviewer-routing audit trail: every request/remove that
|
|
100
|
+
actually succeeded against GitHub, who did it, and when
|
|
101
|
+
change recommend-reviewers <changeId> advisory-only reviewer suggestions from CODEOWNERS, prior
|
|
102
|
+
review history, and recent file authorship — never requests
|
|
103
|
+
a reviewer; use "change reviewers" to see actual requests
|
|
104
|
+
change review-health <changeId> live GitHub review-collaboration summary: state, requested
|
|
105
|
+
reviewers, stale/dismissed approvals, unresolved threads,
|
|
106
|
+
CODEOWNERS evidence, and GitHub's effective merge requirement
|
|
107
|
+
change landability <changeId> show the effective GitHub landability policy report — every
|
|
108
|
+
gate's state and resolution, plus the overall verdict
|
|
109
|
+
change projects <changeId> show bounded GitHub Projects v2 evidence for linked issues
|
|
110
|
+
change handoff <changeId> durable task-handoff log (issue #373): findings, validation
|
|
111
|
+
evidence, outstanding work, or a verified commit SHA another
|
|
112
|
+
agent (or the same one later) can pick up without reconstructing
|
|
113
|
+
a chat transcript; works against a landed or abandoned change too
|
|
114
|
+
change handoff <changeId> --add <kind> -m <body>
|
|
115
|
+
append one entry (never updates/deletes an existing one);
|
|
116
|
+
kind: note | status | question | decision | blocker | plan
|
|
117
|
+
change deps <changeId> list a change's declared read-only external dependencies
|
|
118
|
+
(issue #277); with no flag, lists current state
|
|
119
|
+
change deps <changeId> --set kind:owner/repo#ref [--set ...]
|
|
120
|
+
replace-all declaration of external dependency edges
|
|
121
|
+
(kind is issue|pull_request|release|bookmark); never itself
|
|
122
|
+
reads GitHub and never gates landing (advisory only)
|
|
123
|
+
change deps <changeId> --refresh best-effort live GitHub read of every declared dependency's
|
|
124
|
+
current state (open/closed, released/draft, exists/missing)
|
|
125
|
+
change evolution <changeId> auditable logical-change timeline (issue #275): kind, related
|
|
126
|
+
change ids, before/after evidence, remote recovery limits
|
|
127
|
+
change recover <changeId> --keep left|right|both
|
|
128
|
+
resolve a recorded divergence (issue #275) between two live
|
|
129
|
+
changeIds that both claim the same underlying jj change id;
|
|
130
|
+
left/right abandons the other side, both marks it resolved
|
|
131
|
+
without abandoning either; refuses (409) if either is landed
|
|
75
132
|
|
|
76
133
|
stack create <title> [--id x] [--changes CHG-1,CHG-2]
|
|
77
134
|
stack list
|
|
78
135
|
stack land <stackId> [--force] same check-run gate as change land
|
|
136
|
+
stack enqueue <stackId> queue a LINEAR stack root->tip via change enqueue's own path;
|
|
137
|
+
refuses (409) before any GitHub call if the stack isn't linear
|
|
138
|
+
(a member with more than one parent, an unprojected member, or
|
|
139
|
+
a base that doesn't chain onto the previous member); prints each
|
|
140
|
+
member's own outcome (queued/skipped/failed) rather than an
|
|
141
|
+
all-or-nothing result
|
|
79
142
|
stack delete <stackId> disband — members become loose changes (undoable)
|
|
80
143
|
stack reorder <stackId> <changeId,changeId,...>
|
|
81
144
|
stack checks <stackId> every member's GitHub check runs, one batched round trip
|
|
82
145
|
stack issues <stackId> linked issue and external-blocker summary for a stack
|
|
146
|
+
stack review-health <stackId> per-member review-health summary, one batched round trip
|
|
147
|
+
stack landability <stackId> per-member effective GitHub landability policy report plus
|
|
148
|
+
the overall verdict, one batched round trip; a member blocked
|
|
149
|
+
behind an earlier, not-yet-landable member carries its own
|
|
150
|
+
"stack-order" requirement
|
|
151
|
+
|
|
152
|
+
project rules list list this repo's Projects v2 lifecycle->field mapping rules
|
|
153
|
+
project rules set --project <projectNodeId> --field <fieldNodeId> --option <optionId>
|
|
154
|
+
--when <draft|in_review|queued|landed|abandoned|blocked> [--id <ruleId>] [--disabled]
|
|
155
|
+
project rules delete <ruleId>
|
|
156
|
+
project preview <changeId> preview what "project apply" would do right now, without writing
|
|
157
|
+
project apply <changeId> evaluate and write matching rules now; automatic dispatch already
|
|
158
|
+
runs this on land
|
|
83
159
|
|
|
84
160
|
bookmark list
|
|
85
161
|
bookmark delete <name> [--force] --force required for the default (trunk) bookmark
|
|
86
162
|
bookmark set <name> <tracked|view> [--target CHG-x]
|
|
87
163
|
|
|
164
|
+
view save <name> <revsetExpression> save a named jj revset expression for later reuse (storage
|
|
165
|
+
only — evaluate it with "jjhub revset")
|
|
166
|
+
view list list saved views in this repo
|
|
167
|
+
view delete <name>
|
|
168
|
+
|
|
88
169
|
op log "@" marks the current head operation
|
|
170
|
+
op diff <fromOpId> <toOpId> structural diff between two operations' immutable snapshots
|
|
171
|
+
(which changes/stacks/bookmarks/conflicts were created,
|
|
172
|
+
modified, or removed); works for adjacent or far-apart ops
|
|
89
173
|
undo [--force] refused when the head op is a "land" (real merge can't be unwound); --force reverts local state anyway
|
|
90
174
|
redo
|
|
91
175
|
|
|
@@ -105,7 +189,18 @@ auth sessions list your live sessions; auth revoke <id>
|
|
|
105
189
|
auth logout forget the saved connection/token
|
|
106
190
|
auth status who the saved credential authenticates as
|
|
107
191
|
|
|
108
|
-
|
|
192
|
+
ai models --provider <p> [--api-key <key>] [--base-url <url>]
|
|
193
|
+
live model list for one AI provider (issue #472); the key
|
|
194
|
+
is used for this one request only and never saved. Without
|
|
195
|
+
--api-key, falls back to your already-saved AI connection's
|
|
196
|
+
key for that same provider, if any. Always succeeds — a
|
|
197
|
+
live-lookup failure shows source: static_fallback with a
|
|
198
|
+
detail message rather than an error, since a free-text model
|
|
199
|
+
id always works when configuring AI, listed or not
|
|
200
|
+
ai status where AI is coming from for you: your own saved connection,
|
|
201
|
+
the server operator's default, or not configured at all
|
|
202
|
+
|
|
203
|
+
mcp serve MCP server over stdio (125 tools) for agent clients
|
|
109
204
|
mcp serve --http <port> the same tools over Streamable HTTP (POST /)
|
|
110
205
|
acp serve Agent Client Protocol agent over stdio (Zed's agent
|
|
111
206
|
panel, ...) — every operation as a slash command
|
|
@@ -124,13 +219,31 @@ topology <localRepoPath> [--engine subprocess]
|
|
|
124
219
|
revset <localRepoPath> <expression> [--engine subprocess]
|
|
125
220
|
evaluate the installed jj binary's revset in exactly the named workspace;
|
|
126
221
|
this is local, read-only discovery rather than a server-side approximation
|
|
222
|
+
revset <expression> --workspace <workspaceId> [--repo owner/name] [--limit N]
|
|
223
|
+
REMOTE form (issue #274): relays the query through the JJHub server to
|
|
224
|
+
that exact workspace's own "jjhub daemon" and polls for the result — use
|
|
225
|
+
when you're not on the machine with the workspace checked out. Slower
|
|
226
|
+
(bound by the daemon's sync interval) and needs that daemon healthy;
|
|
227
|
+
same result shape/error taxonomy as the local form above
|
|
127
228
|
|
|
128
229
|
content preview <localRepoPath> <split|absorb|squash|duplicate|restore>
|
|
129
230
|
--source <jj-change-id> [--destination <jj-change-id>] [--path <relative-path>]...
|
|
130
231
|
content apply <localRepoPath> <split|absorb|squash|duplicate|restore>
|
|
131
232
|
same selection plus --expected-operation <jj-operation-id> returned by preview
|
|
132
233
|
local-only jj content curation; checked against jj's immutable policy and
|
|
133
|
-
never implemented as a browser patch transform
|
|
234
|
+
never implemented as a browser patch transform; records a durable receipt
|
|
235
|
+
on the JJHub server (best-effort — see "content receipts" below)
|
|
236
|
+
content preview|apply --workspace <workspaceId> <split|absorb|squash|duplicate|restore>
|
|
237
|
+
--op <json> | (--source <jj-change-id> [--destination <jj-change-id>]
|
|
238
|
+
[--path <relative-path>]... [--title <title>]) [--expected-operation <id>]
|
|
239
|
+
REMOTE form (issue #276): relays the preview/apply through the JJHub server to
|
|
240
|
+
that exact workspace's own "jjhub daemon" and polls for the result — use
|
|
241
|
+
when you're not on the machine with the workspace checked out. jj's own
|
|
242
|
+
immutable-commits check and JJHub's landed-change guard both apply; a
|
|
243
|
+
successful apply also appends a durable content_op_receipts entry
|
|
244
|
+
content receipts [--repo owner/name|repoId]
|
|
245
|
+
list this repo's content-op receipt trail: every content apply invocation,
|
|
246
|
+
successful or rejected, with its kind, revisions, and outcome
|
|
134
247
|
```
|
|
135
248
|
|
|
136
249
|
Anything else (`pr`, `issue`, ...) is passed through to `gh` — e.g. `jjhub pr view 7`. `jjhub auth`
|
|
@@ -200,6 +313,25 @@ npm run jjhub -- stack land "Fix bundle"
|
|
|
200
313
|
|
|
201
314
|
A single change not part of a stack lands directly: `npm run jjhub -- change land CHG-1`.
|
|
202
315
|
|
|
316
|
+
### Use GitHub's merge queue instead of a direct land
|
|
317
|
+
|
|
318
|
+
When the target branch requires it, add a review-ready change to GitHub's
|
|
319
|
+
merge queue rather than merging it directly — GitHub owns the merge from
|
|
320
|
+
there, and JJHub only marks the change landed once GitHub reports it merged:
|
|
321
|
+
|
|
322
|
+
```bash
|
|
323
|
+
npm run jjhub -- change request-review CHG-1
|
|
324
|
+
npm run jjhub -- change enqueue CHG-1
|
|
325
|
+
npm run jjhub -- change queue-status CHG-1 # position/state/merge-group evidence,
|
|
326
|
+
# removal reason if GitHub removed it,
|
|
327
|
+
# and whether GitHub auto-merge is armed
|
|
328
|
+
npm run jjhub -- change dequeue CHG-1 # withdraw back to explicit review
|
|
329
|
+
```
|
|
330
|
+
|
|
331
|
+
A change JJHub knows is queued cannot be rewritten (`describe`/`amend`/
|
|
332
|
+
`restack`/...) or landed directly until it is dequeued — `change land`
|
|
333
|
+
refuses with a message naming the queue.
|
|
334
|
+
|
|
203
335
|
### Sync a local jj working copy into JJHub
|
|
204
336
|
|
|
205
337
|
```bash
|
|
@@ -243,6 +375,15 @@ targets are refused without `--ignore-immutable`. `--path` selects complete
|
|
|
243
375
|
relative paths; interactive hunk selection remains jj's configured diff editor.
|
|
244
376
|
Run `jjhub daemon . --once` afterwards to reconcile the local graph.
|
|
245
377
|
|
|
378
|
+
Each `content apply` invocation — successful or rejected (e.g. a stale
|
|
379
|
+
`--expected-operation`) — records a durable receipt on the JJHub server
|
|
380
|
+
(best-effort: a missing repo context or unreachable server only produces a
|
|
381
|
+
warning, never blocks the local jj mutation). Review the trail with:
|
|
382
|
+
|
|
383
|
+
```bash
|
|
384
|
+
npm run jjhub -- content receipts
|
|
385
|
+
```
|
|
386
|
+
|
|
246
387
|
### Resolve a conflict
|
|
247
388
|
|
|
248
389
|
```bash
|