@pipod/cli 0.1.10 → 0.1.12
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/dist/cli.js +86 -31
- package/dist/cli.js.map +1 -1
- package/docs/config-simplification.md +8 -6
- package/docs/workspace-seeding.md +16 -11
- package/man/pipod-config.5 +1 -1
- package/man/pipod.1 +41 -18
- package/man/pipod.1.md +39 -17
- package/package.json +1 -1
|
@@ -115,15 +115,17 @@ ignored, except `--dry-run`/`--on`-with-fork which are usage errors.
|
|
|
115
115
|
`--from-here`), `edit` (`--name/--description/--config/--init-script/--bake-script`;
|
|
116
116
|
`--org` rejected — org-wide goes through `share`; whole-snapshot replace goes through `push`), `share` (one-way),
|
|
117
117
|
`rm|delete [-y]`. A global `--yes` is honored (no false scope warning).
|
|
118
|
-
- `push [template [<name>]|user|org]`: whole-bundle replace from the
|
|
119
|
-
local source (project `.pi-pod/`+`.pi/`, user `~/.pi-pod`+`~/.pi/agent`,
|
|
120
|
-
`~/.pi-pod/org/` or `--dir
|
|
121
|
-
|
|
122
|
-
-
|
|
118
|
+
- `push [template [<name>]|user|org|policy]`: whole-bundle replace from the
|
|
119
|
+
layer's local source (project `.pi-pod/`+`.pi/`, user `~/.pi-pod`+`~/.pi/agent`,
|
|
120
|
+
org `~/.pi-pod/org/` or `--dir`, policy `policy.json` in that org directory),
|
|
121
|
+
after a diff preview. The policy is config only and validated by the server.
|
|
122
|
+
`--with-secrets` uploads env values (else a prompt per bundle); `-y` applies
|
|
123
|
+
without confirming.
|
|
124
|
+
- `pull [layer]`: reverse of push (same sources; `--dir` for org and policy; `-y`).
|
|
123
125
|
Client-only keys, host-coupled settings, and model credential values survive;
|
|
124
126
|
server scripts with no local file warn instead of writing.
|
|
125
127
|
- `diff [layer]`: same sources, secrets by name only; exit 1 on drift (`--dir`
|
|
126
|
-
for org; no `-y` — it never writes).
|
|
128
|
+
for org and policy; no `-y` — it never writes).
|
|
127
129
|
- `settings <user|org> [show|edit|set <key> <json-value>]`: config-only
|
|
128
130
|
compare-and-swap edits (scripts/Pi files untouched — that is `push`).
|
|
129
131
|
`show` prints JSON; `edit` uses `$VISUAL`/`$EDITOR`; `set` takes a dotted key
|
|
@@ -23,20 +23,23 @@ from a subdirectory seeds the whole repository and prints the subdirectory so it
|
|
|
23
23
|
|
|
24
24
|
## Clone or archive
|
|
25
25
|
|
|
26
|
-
A clone is
|
|
27
|
-
|
|
26
|
+
A clone is preferred when the pod can fetch the host's exact **committed HEAD**. Local
|
|
27
|
+
staged, unstaged, and untracked changes do not prevent cloning and are **not copied** by a
|
|
28
|
+
successful clone. The local checkout is left untouched. Every check below fails closed into
|
|
29
|
+
an archive with a human-readable reason (`pipod --dry-run` prints it):
|
|
28
30
|
|
|
29
31
|
1. inside a git work tree
|
|
30
32
|
2. `origin` exists and rewrites to an `https://` URL (`git@host:x/y.git` and `ssh://` are rewritten; local paths cannot be cloned by a pod)
|
|
31
33
|
3. HEAD is on a branch
|
|
32
|
-
4.
|
|
33
|
-
5.
|
|
34
|
-
6.
|
|
35
|
-
7.
|
|
36
|
-
8. a live `git ls-remote` shows the remote branch at exactly the local HEAD commit
|
|
34
|
+
4. the branch has an upstream with no unpushed commits
|
|
35
|
+
5. no initialized submodules, no Git LFS attributes
|
|
36
|
+
6. the pod's egress policy admits the remote host
|
|
37
|
+
7. a live `git ls-remote` shows the remote branch at exactly the local HEAD commit
|
|
37
38
|
|
|
38
39
|
The server clones that exact commit into the empty workdir. If the clone fails for any
|
|
39
|
-
reason, the launch automatically falls back to an archive of the local tree
|
|
40
|
+
reason, the launch automatically falls back to an archive of the local working tree,
|
|
41
|
+
**including uncommitted changes**. The committed-only behavior applies to successful clones,
|
|
42
|
+
not archive or configured-project copy transports.
|
|
40
43
|
|
|
41
44
|
An **archive** is a gzip-compressed POSIX tar stream written to a temporary file and streamed
|
|
42
45
|
to `PUT /v1/pods/:id/workspace/archive`. It contains tracked and untracked non-ignored files,
|
|
@@ -91,10 +94,12 @@ on the sandbox backend:
|
|
|
91
94
|
the forwarding prompt; approve; `!git remote -v` inside the pod shows the https URL with no
|
|
92
95
|
token, and `!cat .git/config` holds no token.
|
|
93
96
|
3. **Declined forwarding** — answer `n`; expect an archive, and the pod still holds the tree.
|
|
94
|
-
4. **Dirty repository
|
|
95
|
-
|
|
97
|
+
4. **Dirty repository clone** — in a pushed, cloneable repository, stage a change, edit it
|
|
98
|
+
again, and add an untracked file. Launch; expect `will clone … (local uncommitted changes
|
|
99
|
+
are not copied)`. Inside the pod, `!git status` is clean, tracked content matches HEAD,
|
|
100
|
+
and the untracked file is absent. The host's staged, unstaged and untracked changes remain.
|
|
96
101
|
5. **Non-git archive** — a plain directory of files; expect the files without a `.git`.
|
|
97
|
-
6. **100+ MiB streaming archive** — a repository with a large untracked binary; watch the
|
|
102
|
+
6. **100+ MiB streaming archive** — a repository without `origin`, with a large untracked binary; watch the
|
|
98
103
|
`upload 25% …` lines; verify the file's checksum in the pod.
|
|
99
104
|
7. **Interrupted upload** — Ctrl-C during upload; expect the pod deleted and no
|
|
100
105
|
`pi-pod-seed-*.tar.gz` left in the temp directory.
|
package/man/pipod-config.5
CHANGED
package/man/pipod.1
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
.TH "PIPOD" "1" "October 2026" "0.1.
|
|
1
|
+
.TH "PIPOD" "1" "October 2026" "0.1.12"
|
|
2
2
|
.SH "NAME"
|
|
3
3
|
\fBpipod\fR \- run pi coding\-agent sessions in server\-managed pods
|
|
4
4
|
.SH SYNOPSIS
|
|
@@ -90,9 +90,9 @@ bake script that is built into the pod image once, and Pi files\. Secrets are st
|
|
|
90
90
|
the layers and reach pods as environment variables\. \fBpipod help layers\fP explains how they
|
|
91
91
|
combine\.
|
|
92
92
|
.P
|
|
93
|
-
Every server layer has a local source of truth:
|
|
94
|
-
upload with \fBpipod push\fP\|\. \fBpipod pull\fP writes the server's copy back, and
|
|
95
|
-
compares the two\.
|
|
93
|
+
Every server layer, organization policy included, has a local source of truth: files you edit
|
|
94
|
+
with any editor, then upload with \fBpipod push\fP\|\. \fBpipod pull\fP writes the server's copy back, and
|
|
95
|
+
\fBpipod diff\fP compares the two\.
|
|
96
96
|
.SH SETUP
|
|
97
97
|
.P
|
|
98
98
|
Setting pi pod up for yourself or an organization, in order\. A person has to do the steps
|
|
@@ -137,8 +137,20 @@ pipod push org
|
|
|
137
137
|
.RE
|
|
138
138
|
.P
|
|
139
139
|
Values for secrets the whole organization shares: \fBpipod secrets set org <NAME>\fP (person)\.
|
|
140
|
-
|
|
141
|
-
|
|
140
|
+
.P
|
|
141
|
+
Organization policy (limits rather than defaults) needs the policy:write permission\. Its source
|
|
142
|
+
is policy\.json beside the organization layer's files:
|
|
143
|
+
.RS 2
|
|
144
|
+
.nf
|
|
145
|
+
pipod pull policy # writes ~/\.pi\-pod/org/policy\.json
|
|
146
|
+
# edit it
|
|
147
|
+
pipod diff policy
|
|
148
|
+
pipod push policy
|
|
149
|
+
.fi
|
|
150
|
+
.RE
|
|
151
|
+
.P
|
|
152
|
+
To keep the organization's source in a repository instead, give each of these commands
|
|
153
|
+
\fB\-\-dir <path>\fP\|\.
|
|
142
154
|
.SS 5\. Your own defaults
|
|
143
155
|
.P
|
|
144
156
|
Your model and thinking level, your Pi settings, personal setup such as a git identity:
|
|
@@ -217,8 +229,8 @@ and the server refuses a literal key\.
|
|
|
217
229
|
.P
|
|
218
230
|
Organization policy holds limits rather than defaults: maximum idle and archive times,
|
|
219
231
|
allowed providers, a required template, network rules, concurrency\. It clamps the merged
|
|
220
|
-
result, and \fBpipod doctor\fP and \fBpipod \-\-dry\-run\fP report every clamp\.
|
|
221
|
-
|
|
232
|
+
result, and \fBpipod doctor\fP and \fBpipod \-\-dry\-run\fP report every clamp\. Someone with the
|
|
233
|
+
policy:write permission changes it with \fBpipod push policy\fP or in the web dashboard\.
|
|
222
234
|
.P
|
|
223
235
|
Where each layer's source lives, and the commands that change it:
|
|
224
236
|
.RS 2
|
|
@@ -229,6 +241,8 @@ user ~/\.pi\-pod/config\.json and ~/\.pi/agent/
|
|
|
229
241
|
pipod pull|diff|push user; pipod settings user set
|
|
230
242
|
template a project: \.pi\-pod/config\.json, init\.sh, bake\.sh, env, and \.pi/
|
|
231
243
|
pipod pull|diff|push [template [<name>]]; pipod templates
|
|
244
|
+
policy ~/\.pi\-pod/org/policy\.json
|
|
245
|
+
pipod pull|diff|push policy (policy:write)
|
|
232
246
|
.fi
|
|
233
247
|
.RE
|
|
234
248
|
.P
|
|
@@ -251,10 +265,13 @@ The launch uses the template named by \fB\-\-template\fP, or else the one pinned
|
|
|
251
265
|
first launch offers to create a template from the project and pin it\.
|
|
252
266
|
.P
|
|
253
267
|
Workspace seeding: launching from a directory with no \.pi\-pod/config\.json seeds the new pod
|
|
254
|
-
from that directory (its git repository root when inside one)\. A
|
|
255
|
-
remote tip matches HEAD is cloned at that exact
|
|
256
|
-
|
|
257
|
-
|
|
268
|
+
from that directory (its git repository root when inside one)\. A pushed checkout whose
|
|
269
|
+
remote tip matches HEAD is cloned at that exact committed HEAD, even with local uncommitted
|
|
270
|
+
changes\. A successful clone does not copy staged, unstaged, or untracked changes and leaves
|
|
271
|
+
the local checkout untouched\. When cloning is unavailable or fails (unpushed commits, private
|
|
272
|
+
remotes without usable credentials, plain directories), the local working tree, including
|
|
273
|
+
uncommitted changes, is streamed in as a tar archive, without git\-ignored paths, node_modules,
|
|
274
|
+
or \.pi\-pod/env\. Private\-remote
|
|
258
275
|
credentials are forwarded only after a prompt (\fB\-\-yes\fP approves it) and are never stored\.
|
|
259
276
|
\fB\-\-dry\-run\fP prints the decision without prompting or creating a pod\. Forks, reused pods,
|
|
260
277
|
\fB\-\-on\fP co\-location, and \fB\-\-no\-seed\fP never seed\. A project with a \.pi\-pod/config\.json gets its
|
|
@@ -459,7 +476,7 @@ A personal template sits above your user layer and an org\-wide one below it
|
|
|
459
476
|
.SS pipod push
|
|
460
477
|
.RS 2
|
|
461
478
|
.nf
|
|
462
|
-
Usage: pipod push [template [<name>] | user | org] [\-\-dir <path>]
|
|
479
|
+
Usage: pipod push [template [<name>] | user | org | policy] [\-\-dir <path>]
|
|
463
480
|
[\-\-with\-secrets] [\-\-yes]
|
|
464
481
|
|
|
465
482
|
Replace a server config bundle with its local source, whole\. The layer names
|
|
@@ -475,13 +492,16 @@ Layers and their local source:
|
|
|
475
492
|
models\.json, mcporter\.json, subagents\.json, agents/)
|
|
476
493
|
org ~/\.pi\-pod/org/: config\.json, init\.sh, bake\.sh, pi/…, and
|
|
477
494
|
an optional env file whose values become org secrets
|
|
495
|
+
policy ~/\.pi\-pod/org/policy\.json: the organization policy, one
|
|
496
|
+
JSON object of limits, checked by the server
|
|
478
497
|
|
|
479
498
|
Inside a project the layer defaults to template; elsewhere it is required\.
|
|
480
499
|
Provider credentials, hooks, mcpServers, and model credential values never
|
|
481
500
|
leave this machine\.
|
|
482
501
|
|
|
483
502
|
Options:
|
|
484
|
-
\-\-dir <path> org
|
|
503
|
+
\-\-dir <path> org and policy: read the org source directory from <path>
|
|
504
|
+
instead
|
|
485
505
|
\-\-with\-secrets Also upload the layer's env values as secrets
|
|
486
506
|
\-y, \-\-yes Apply the replacement without the confirmation prompt
|
|
487
507
|
.fi
|
|
@@ -493,7 +513,8 @@ confirm on, push declines unless \fB\-\-yes\fP is given\.
|
|
|
493
513
|
.SS pipod pull
|
|
494
514
|
.RS 2
|
|
495
515
|
.nf
|
|
496
|
-
Usage: pipod pull [template [<name>] | user | org] [\-\-dir <path>]
|
|
516
|
+
Usage: pipod pull [template [<name>] | user | org | policy] [\-\-dir <path>]
|
|
517
|
+
[\-\-yes]
|
|
497
518
|
|
|
498
519
|
Write a server config bundle into its local source files (see
|
|
499
520
|
`pipod push \-\-help` for the layer → directory table)\. A diff preview
|
|
@@ -511,21 +532,23 @@ Secrets stay on the server; their names are listed\. The user layer has no
|
|
|
511
532
|
local script files, so user bundle scripts are shown but not written\.
|
|
512
533
|
|
|
513
534
|
Options:
|
|
514
|
-
\-\-dir <path> org
|
|
535
|
+
\-\-dir <path> org and policy: write the org source directory at <path>
|
|
536
|
+
instead
|
|
515
537
|
\-y, \-\-yes Apply the local changes without the confirmation prompt
|
|
516
538
|
.fi
|
|
517
539
|
.RE
|
|
518
540
|
.SS pipod diff
|
|
519
541
|
.RS 2
|
|
520
542
|
.nf
|
|
521
|
-
Usage: pipod diff [template [<name>] | user | org] [\-\-dir <path>]
|
|
543
|
+
Usage: pipod diff [template [<name>] | user | org | policy] [\-\-dir <path>]
|
|
522
544
|
|
|
523
545
|
Compare a config layer's local source with its server bundle (see
|
|
524
546
|
`pipod push \-\-help` for the layer → directory table)\. Secrets compare by
|
|
525
547
|
name only\. Exits 1 when they differ, 0 when they match\.
|
|
526
548
|
|
|
527
549
|
Options:
|
|
528
|
-
\-\-dir <path> org
|
|
550
|
+
\-\-dir <path> org and policy: read the org source directory from <path>
|
|
551
|
+
instead
|
|
529
552
|
.fi
|
|
530
553
|
.RE
|
|
531
554
|
.SS pipod secrets
|
package/man/pipod.1.md
CHANGED
|
@@ -89,9 +89,9 @@ bake script that is built into the pod image once, and Pi files. Secrets are sto
|
|
|
89
89
|
the layers and reach pods as environment variables. `pipod help layers` explains how they
|
|
90
90
|
combine.
|
|
91
91
|
|
|
92
|
-
Every server layer has a local source of truth:
|
|
93
|
-
upload with `pipod push`. `pipod pull` writes the server's copy back, and
|
|
94
|
-
compares the two.
|
|
92
|
+
Every server layer, organization policy included, has a local source of truth: files you edit
|
|
93
|
+
with any editor, then upload with `pipod push`. `pipod pull` writes the server's copy back, and
|
|
94
|
+
`pipod diff` compares the two.
|
|
95
95
|
|
|
96
96
|
## SETUP
|
|
97
97
|
|
|
@@ -139,8 +139,19 @@ pipod push org
|
|
|
139
139
|
```
|
|
140
140
|
|
|
141
141
|
Values for secrets the whole organization shares: `pipod secrets set org <NAME>` (person).
|
|
142
|
-
|
|
143
|
-
|
|
142
|
+
|
|
143
|
+
Organization policy (limits rather than defaults) needs the policy:write permission. Its source
|
|
144
|
+
is policy.json beside the organization layer's files:
|
|
145
|
+
|
|
146
|
+
```
|
|
147
|
+
pipod pull policy # writes ~/.pi-pod/org/policy.json
|
|
148
|
+
# edit it
|
|
149
|
+
pipod diff policy
|
|
150
|
+
pipod push policy
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
To keep the organization's source in a repository instead, give each of these commands
|
|
154
|
+
`--dir <path>`.
|
|
144
155
|
|
|
145
156
|
### 5. Your own defaults
|
|
146
157
|
|
|
@@ -207,8 +218,8 @@ project's .pi-pod/config.json. Within the layers:
|
|
|
207
218
|
|
|
208
219
|
Organization policy holds limits rather than defaults: maximum idle and archive times,
|
|
209
220
|
allowed providers, a required template, network rules, concurrency. It clamps the merged
|
|
210
|
-
result, and `pipod doctor` and `pipod --dry-run` report every clamp.
|
|
211
|
-
|
|
221
|
+
result, and `pipod doctor` and `pipod --dry-run` report every clamp. Someone with the
|
|
222
|
+
policy:write permission changes it with `pipod push policy` or in the web dashboard.
|
|
212
223
|
|
|
213
224
|
Where each layer's source lives, and the commands that change it:
|
|
214
225
|
|
|
@@ -219,6 +230,8 @@ user ~/.pi-pod/config.json and ~/.pi/agent/
|
|
|
219
230
|
pipod pull|diff|push user; pipod settings user set
|
|
220
231
|
template a project: .pi-pod/config.json, init.sh, bake.sh, env, and .pi/
|
|
221
232
|
pipod pull|diff|push [template [<name>]]; pipod templates
|
|
233
|
+
policy ~/.pi-pod/org/policy.json
|
|
234
|
+
pipod pull|diff|push policy (policy:write)
|
|
222
235
|
```
|
|
223
236
|
|
|
224
237
|
What belongs where: the organization layer holds what everyone needs (pod size, network
|
|
@@ -241,10 +254,13 @@ The launch uses the template named by `--template`, or else the one pinned in th
|
|
|
241
254
|
first launch offers to create a template from the project and pin it.
|
|
242
255
|
|
|
243
256
|
Workspace seeding: launching from a directory with no .pi-pod/config.json seeds the new pod
|
|
244
|
-
from that directory (its git repository root when inside one). A
|
|
245
|
-
remote tip matches HEAD is cloned at that exact
|
|
246
|
-
|
|
247
|
-
|
|
257
|
+
from that directory (its git repository root when inside one). A pushed checkout whose
|
|
258
|
+
remote tip matches HEAD is cloned at that exact committed HEAD, even with local uncommitted
|
|
259
|
+
changes. A successful clone does not copy staged, unstaged, or untracked changes and leaves
|
|
260
|
+
the local checkout untouched. When cloning is unavailable or fails (unpushed commits, private
|
|
261
|
+
remotes without usable credentials, plain directories), the local working tree, including
|
|
262
|
+
uncommitted changes, is streamed in as a tar archive, without git-ignored paths, node_modules,
|
|
263
|
+
or .pi-pod/env. Private-remote
|
|
248
264
|
credentials are forwarded only after a prompt (`--yes` approves it) and are never stored.
|
|
249
265
|
`--dry-run` prints the decision without prompting or creating a pod. Forks, reused pods,
|
|
250
266
|
`--on` co-location, and `--no-seed` never seed. A project with a .pi-pod/config.json gets its
|
|
@@ -451,7 +467,7 @@ A personal template sits above your user layer and an org-wide one below it
|
|
|
451
467
|
### pipod push
|
|
452
468
|
|
|
453
469
|
```
|
|
454
|
-
Usage: pipod push [template [<name>] | user | org] [--dir <path>]
|
|
470
|
+
Usage: pipod push [template [<name>] | user | org | policy] [--dir <path>]
|
|
455
471
|
[--with-secrets] [--yes]
|
|
456
472
|
|
|
457
473
|
Replace a server config bundle with its local source, whole. The layer names
|
|
@@ -467,13 +483,16 @@ Layers and their local source:
|
|
|
467
483
|
models.json, mcporter.json, subagents.json, agents/)
|
|
468
484
|
org ~/.pi-pod/org/: config.json, init.sh, bake.sh, pi/…, and
|
|
469
485
|
an optional env file whose values become org secrets
|
|
486
|
+
policy ~/.pi-pod/org/policy.json: the organization policy, one
|
|
487
|
+
JSON object of limits, checked by the server
|
|
470
488
|
|
|
471
489
|
Inside a project the layer defaults to template; elsewhere it is required.
|
|
472
490
|
Provider credentials, hooks, mcpServers, and model credential values never
|
|
473
491
|
leave this machine.
|
|
474
492
|
|
|
475
493
|
Options:
|
|
476
|
-
--dir <path> org
|
|
494
|
+
--dir <path> org and policy: read the org source directory from <path>
|
|
495
|
+
instead
|
|
477
496
|
--with-secrets Also upload the layer's env values as secrets
|
|
478
497
|
-y, --yes Apply the replacement without the confirmation prompt
|
|
479
498
|
```
|
|
@@ -485,7 +504,8 @@ confirm on, push declines unless `--yes` is given.
|
|
|
485
504
|
### pipod pull
|
|
486
505
|
|
|
487
506
|
```
|
|
488
|
-
Usage: pipod pull [template [<name>] | user | org] [--dir <path>]
|
|
507
|
+
Usage: pipod pull [template [<name>] | user | org | policy] [--dir <path>]
|
|
508
|
+
[--yes]
|
|
489
509
|
|
|
490
510
|
Write a server config bundle into its local source files (see
|
|
491
511
|
`pipod push --help` for the layer → directory table). A diff preview
|
|
@@ -503,21 +523,23 @@ Secrets stay on the server; their names are listed. The user layer has no
|
|
|
503
523
|
local script files, so user bundle scripts are shown but not written.
|
|
504
524
|
|
|
505
525
|
Options:
|
|
506
|
-
--dir <path> org
|
|
526
|
+
--dir <path> org and policy: write the org source directory at <path>
|
|
527
|
+
instead
|
|
507
528
|
-y, --yes Apply the local changes without the confirmation prompt
|
|
508
529
|
```
|
|
509
530
|
|
|
510
531
|
### pipod diff
|
|
511
532
|
|
|
512
533
|
```
|
|
513
|
-
Usage: pipod diff [template [<name>] | user | org] [--dir <path>]
|
|
534
|
+
Usage: pipod diff [template [<name>] | user | org | policy] [--dir <path>]
|
|
514
535
|
|
|
515
536
|
Compare a config layer's local source with its server bundle (see
|
|
516
537
|
`pipod push --help` for the layer → directory table). Secrets compare by
|
|
517
538
|
name only. Exits 1 when they differ, 0 when they match.
|
|
518
539
|
|
|
519
540
|
Options:
|
|
520
|
-
--dir <path> org
|
|
541
|
+
--dir <path> org and policy: read the org source directory from <path>
|
|
542
|
+
instead
|
|
521
543
|
```
|
|
522
544
|
|
|
523
545
|
### pipod secrets
|