@pipod/cli 0.1.5 → 0.1.7
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 +6 -0
- package/dist/cli.js +199 -528
- package/dist/cli.js.map +1 -1
- package/man/pipod-config.5 +150 -0
- package/man/pipod-config.5.md +148 -0
- package/man/pipod.1 +861 -0
- package/man/pipod.1.md +852 -0
- package/package.json +9 -2
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
.TH "PIPOD\-CONFIG" "5" "October 2026" "0.1.7"
|
|
2
|
+
.SH "NAME"
|
|
3
|
+
\fBpipod-config\fR \- pi pod configuration files
|
|
4
|
+
.SH SYNOPSIS
|
|
5
|
+
.RS 2
|
|
6
|
+
.nf
|
|
7
|
+
\|\.pi\-pod/config\.json a project: the source of its template
|
|
8
|
+
~/\.pi\-pod/config\.json this machine's preferences, and your user layer
|
|
9
|
+
~/\.pi\-pod/org/config\.json the organization layer
|
|
10
|
+
.fi
|
|
11
|
+
.RE
|
|
12
|
+
.SH DESCRIPTION
|
|
13
|
+
.P
|
|
14
|
+
Each file is one settings layer's config, written as JSON with comments allowed\. The server
|
|
15
|
+
merges the layers for each launch (\fBpipod help layers\fP), so a file names only what its layer
|
|
16
|
+
must decide; anything left out comes from the layers below it\. The keys are the same in every
|
|
17
|
+
file\. \fBpipod push\fP uploads a file and \fBpipod settings <user|org> set <key> <value>\fP changes
|
|
18
|
+
one key on the server\.
|
|
19
|
+
.P
|
|
20
|
+
A key of the wrong type fails the command that reads it, naming the key\. An unknown key is
|
|
21
|
+
ignored with a warning\.
|
|
22
|
+
.SH POD KEYS
|
|
23
|
+
.P
|
|
24
|
+
These travel to the server and decide what a pod gets\. The defaults are the built\-in layer's\.
|
|
25
|
+
.RS 2
|
|
26
|
+
.nf
|
|
27
|
+
resources\.cpu vCPUs (default 2)
|
|
28
|
+
resources\.memoryGB memory in GB (default 4)
|
|
29
|
+
resources\.diskGB workspace disk in GB (default 5)
|
|
30
|
+
.fi
|
|
31
|
+
.RE
|
|
32
|
+
.P
|
|
33
|
+
The server may clamp a size to what the host or the organization's policy allows; a launch
|
|
34
|
+
reports every clamp\.
|
|
35
|
+
.RS 2
|
|
36
|
+
.nf
|
|
37
|
+
egress\.mode "open" (default) or "allowlist"
|
|
38
|
+
egress\.allow hosts a pod may reach under "allowlist"
|
|
39
|
+
egress\.builtins also allow the hosts pi pod derives (default true)
|
|
40
|
+
.fi
|
|
41
|
+
.RE
|
|
42
|
+
.P
|
|
43
|
+
Under "allowlist" a pod reaches only \fBegress\.allow\fP, the server itself, and with \fBbuiltins\fP
|
|
44
|
+
the model\-provider endpoints its Pi sign\-ins and settings name\. Entries are hostnames, never
|
|
45
|
+
addresses\. The self\-hosted sandbox resolves each to its addresses when a pod starts, so it
|
|
46
|
+
refuses wildcards; where a server accepts them, "*\.example\.com" covers example\.com and every
|
|
47
|
+
name under it\. Git hosts are never derived: list them, and every host the init and bake
|
|
48
|
+
scripts download from\. Pi packages need registry\.npmjs\.org\.
|
|
49
|
+
.RS 2
|
|
50
|
+
.nf
|
|
51
|
+
pi\.model default model, "provider/model\-id"
|
|
52
|
+
pi\.thinking default thinking level: "off", "minimal", "low", "medium",
|
|
53
|
+
"high", "xhigh", or "max"
|
|
54
|
+
pi\.args extra arguments for pi in the pod (default [])
|
|
55
|
+
pi\.command the command that starts pi (default "pi")
|
|
56
|
+
pi\.hostConfig\.settings carry the layers' Pi files into pods (default true)
|
|
57
|
+
pi\.hostConfig\.packages carry settings\.json packages into pods and install them
|
|
58
|
+
(default true)
|
|
59
|
+
.fi
|
|
60
|
+
.RE
|
|
61
|
+
.P
|
|
62
|
+
A launch's \fB\-\-model\fP and \fB\-\-thinking\fP (after \fB\-\-\fP) win over \fBpi\.model\fP and \fBpi\.thinking\fP\|\.
|
|
63
|
+
.RS 2
|
|
64
|
+
.nf
|
|
65
|
+
idleTimeoutMinutes stop a pod after this many idle minutes (default 15); 0 never
|
|
66
|
+
stops it, so it runs, and costs, until stopped
|
|
67
|
+
archiveAfterMinutes move a stopped pod's workspace to cold storage after this many
|
|
68
|
+
minutes (default 60)
|
|
69
|
+
initTimeoutSeconds the time limit for the init scripts (default 600)
|
|
70
|
+
initOnFailure when init fails: "abort" the launch (default), "prompt",
|
|
71
|
+
or "continue"
|
|
72
|
+
workdir the pod's working directory, an absolute path
|
|
73
|
+
(default "/workspace")
|
|
74
|
+
image a custom pod image (default: the managed image matching
|
|
75
|
+
this pipod)
|
|
76
|
+
name the project's name in pod names and listings: letters,
|
|
77
|
+
digits, dots, dashes, underscores (default: the directory's)
|
|
78
|
+
labels string\-to\-string labels for the pod
|
|
79
|
+
.fi
|
|
80
|
+
.RE
|
|
81
|
+
.SH MACHINE KEYS
|
|
82
|
+
.P
|
|
83
|
+
These stay on this machine: \fBpipod push\fP and \fBpipod settings\fP never send them\.
|
|
84
|
+
.RS 2
|
|
85
|
+
.nf
|
|
86
|
+
template the template launches use: in a project's file, its pinned
|
|
87
|
+
template; in ~/\.pi\-pod/config\.json, the default elsewhere\.
|
|
88
|
+
\-\-template wins over both, and the project over this machine\.
|
|
89
|
+
secretResolver { "type": "1password" }, optionally with "tokenCommand": a
|
|
90
|
+
command printing a 1Password service\-account token (read only
|
|
91
|
+
from ~/\.pi\-pod/config\.json); resolves op:// secret values
|
|
92
|
+
pi\.chords keystrokes for /pod commands while attached:
|
|
93
|
+
{ "enabled": true, "prefix": "ctrl+\\\\",
|
|
94
|
+
"bindings": { "d": "detach", "a": "archive", "s": "status",
|
|
95
|
+
"l": "list", "w": "switch" } }
|
|
96
|
+
pi\.sessionNaming "auto" (default) names a session from its first prompt; "off"
|
|
97
|
+
$schema ignored
|
|
98
|
+
.fi
|
|
99
|
+
.RE
|
|
100
|
+
.SH SCRIPTS
|
|
101
|
+
.P
|
|
102
|
+
A layer's two scripts sit beside its config: \.pi\-pod/init\.sh and \.pi\-pod/bake\.sh in a
|
|
103
|
+
project, init\.sh and bake\.sh in ~/\.pi\-pod/org/\. Every layer's scripts run, lowest layer first\.
|
|
104
|
+
.P
|
|
105
|
+
The init script runs in every pod at launch, as non\-interactive bash (\fBCI=1\fP,
|
|
106
|
+
\fBDEBIAN_FRONTEND=noninteractive\fP) in the workdir, with the pod's secrets in its environment\.
|
|
107
|
+
It is where a project clones its repository and installs dependencies, since a project with a
|
|
108
|
+
\|\.pi\-pod/config\.json gets no copy of its files\. A pod reused with \fB\-\-reuse\fP runs it again over
|
|
109
|
+
the files already there, so write it to make a second run a quick no\-op\. A failure aborts the
|
|
110
|
+
launch unless \fBinitOnFailure\fP says otherwise\.
|
|
111
|
+
.P
|
|
112
|
+
The bake script is built into the pod image once, and every later launch starts with its
|
|
113
|
+
results\. On the first launch after an edit, or with a custom \fBimage\fP, it runs live in the pod
|
|
114
|
+
instead, before init\. It runs as root in /root, with no secrets, no environment, and no
|
|
115
|
+
workspace, so it suits deterministic installs that every pod repeats: \fBapt\-get install\fP,
|
|
116
|
+
\fBnpm install \-g\fP, toolchains\. Anything that needs a secret, or differs between pods, belongs in
|
|
117
|
+
init\.
|
|
118
|
+
.SH EXAMPLES
|
|
119
|
+
.P
|
|
120
|
+
A project's \.pi\-pod/config\.json that limits network access:
|
|
121
|
+
.RS 2
|
|
122
|
+
.nf
|
|
123
|
+
{
|
|
124
|
+
"resources": { "cpu": 4, "memoryGB": 8 },
|
|
125
|
+
"egress": {
|
|
126
|
+
"mode": "allowlist",
|
|
127
|
+
"allow": ["github\.com", "registry\.npmjs\.org"]
|
|
128
|
+
},
|
|
129
|
+
"pi": { "model": "anthropic/claude\-opus\-4\-7", "thinking": "high" },
|
|
130
|
+
"template": "my\-service"
|
|
131
|
+
}
|
|
132
|
+
.fi
|
|
133
|
+
.RE
|
|
134
|
+
.P
|
|
135
|
+
Organization defaults, one key at a time:
|
|
136
|
+
.RS 2
|
|
137
|
+
.nf
|
|
138
|
+
pipod settings org set resources\.memoryGB 8
|
|
139
|
+
pipod settings org set idleTimeoutMinutes 30
|
|
140
|
+
.fi
|
|
141
|
+
.RE
|
|
142
|
+
.SH RETIRED KEYS
|
|
143
|
+
.P
|
|
144
|
+
\fBenvFile\fP, \fBinitScript\fP, \fBbakeScript\fP, and \fBreuse\fP fail with a message saying what replaced
|
|
145
|
+
them: the files are always \.pi\-pod/env, \.pi\-pod/init\.sh, and \.pi\-pod/bake\.sh, and reuse is the
|
|
146
|
+
\fB\-\-reuse\fP launch flag\. \fBpi\.hostConfig\.skills\fP and \fBpi\.hostConfig\.extensions\fP fail the same
|
|
147
|
+
way\. \fBprovider\fP and \fBdeniedProviders\fP warn and are ignored\.
|
|
148
|
+
.SH SEE ALSO
|
|
149
|
+
.P
|
|
150
|
+
pipod(1)
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
# pipod-config(5) -- pi pod configuration files
|
|
2
|
+
|
|
3
|
+
## SYNOPSIS
|
|
4
|
+
|
|
5
|
+
```
|
|
6
|
+
.pi-pod/config.json a project: the source of its template
|
|
7
|
+
~/.pi-pod/config.json this machine's preferences, and your user layer
|
|
8
|
+
~/.pi-pod/org/config.json the organization layer
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## DESCRIPTION
|
|
12
|
+
|
|
13
|
+
Each file is one settings layer's config, written as JSON with comments allowed. The server
|
|
14
|
+
merges the layers for each launch (`pipod help layers`), so a file names only what its layer
|
|
15
|
+
must decide; anything left out comes from the layers below it. The keys are the same in every
|
|
16
|
+
file. `pipod push` uploads a file and `pipod settings <user|org> set <key> <value>` changes
|
|
17
|
+
one key on the server.
|
|
18
|
+
|
|
19
|
+
A key of the wrong type fails the command that reads it, naming the key. An unknown key is
|
|
20
|
+
ignored with a warning.
|
|
21
|
+
|
|
22
|
+
## POD KEYS
|
|
23
|
+
|
|
24
|
+
These travel to the server and decide what a pod gets. The defaults are the built-in layer's.
|
|
25
|
+
|
|
26
|
+
```
|
|
27
|
+
resources.cpu vCPUs (default 2)
|
|
28
|
+
resources.memoryGB memory in GB (default 4)
|
|
29
|
+
resources.diskGB workspace disk in GB (default 5)
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
The server may clamp a size to what the host or the organization's policy allows; a launch
|
|
33
|
+
reports every clamp.
|
|
34
|
+
|
|
35
|
+
```
|
|
36
|
+
egress.mode "open" (default) or "allowlist"
|
|
37
|
+
egress.allow hosts a pod may reach under "allowlist"
|
|
38
|
+
egress.builtins also allow the hosts pi pod derives (default true)
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
Under "allowlist" a pod reaches only `egress.allow`, the server itself, and with `builtins`
|
|
42
|
+
the model-provider endpoints its Pi sign-ins and settings name. Entries are hostnames, never
|
|
43
|
+
addresses. The self-hosted sandbox resolves each to its addresses when a pod starts, so it
|
|
44
|
+
refuses wildcards; where a server accepts them, "*.example.com" covers example.com and every
|
|
45
|
+
name under it. Git hosts are never derived: list them, and every host the init and bake
|
|
46
|
+
scripts download from. Pi packages need registry.npmjs.org.
|
|
47
|
+
|
|
48
|
+
```
|
|
49
|
+
pi.model default model, "provider/model-id"
|
|
50
|
+
pi.thinking default thinking level: "off", "minimal", "low", "medium",
|
|
51
|
+
"high", "xhigh", or "max"
|
|
52
|
+
pi.args extra arguments for pi in the pod (default [])
|
|
53
|
+
pi.command the command that starts pi (default "pi")
|
|
54
|
+
pi.hostConfig.settings carry the layers' Pi files into pods (default true)
|
|
55
|
+
pi.hostConfig.packages carry settings.json packages into pods and install them
|
|
56
|
+
(default true)
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
A launch's `--model` and `--thinking` (after `--`) win over `pi.model` and `pi.thinking`.
|
|
60
|
+
|
|
61
|
+
```
|
|
62
|
+
idleTimeoutMinutes stop a pod after this many idle minutes (default 15); 0 never
|
|
63
|
+
stops it, so it runs, and costs, until stopped
|
|
64
|
+
archiveAfterMinutes move a stopped pod's workspace to cold storage after this many
|
|
65
|
+
minutes (default 60)
|
|
66
|
+
initTimeoutSeconds the time limit for the init scripts (default 600)
|
|
67
|
+
initOnFailure when init fails: "abort" the launch (default), "prompt",
|
|
68
|
+
or "continue"
|
|
69
|
+
workdir the pod's working directory, an absolute path
|
|
70
|
+
(default "/workspace")
|
|
71
|
+
image a custom pod image (default: the managed image matching
|
|
72
|
+
this pipod)
|
|
73
|
+
name the project's name in pod names and listings: letters,
|
|
74
|
+
digits, dots, dashes, underscores (default: the directory's)
|
|
75
|
+
labels string-to-string labels for the pod
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
## MACHINE KEYS
|
|
79
|
+
|
|
80
|
+
These stay on this machine: `pipod push` and `pipod settings` never send them.
|
|
81
|
+
|
|
82
|
+
```
|
|
83
|
+
template the template launches use: in a project's file, its pinned
|
|
84
|
+
template; in ~/.pi-pod/config.json, the default elsewhere.
|
|
85
|
+
--template wins over both, and the project over this machine.
|
|
86
|
+
secretResolver { "type": "1password" }, optionally with "tokenCommand": a
|
|
87
|
+
command printing a 1Password service-account token (read only
|
|
88
|
+
from ~/.pi-pod/config.json); resolves op:// secret values
|
|
89
|
+
pi.chords keystrokes for /pod commands while attached:
|
|
90
|
+
{ "enabled": true, "prefix": "ctrl+\\",
|
|
91
|
+
"bindings": { "d": "detach", "a": "archive", "s": "status",
|
|
92
|
+
"l": "list", "w": "switch" } }
|
|
93
|
+
pi.sessionNaming "auto" (default) names a session from its first prompt; "off"
|
|
94
|
+
$schema ignored
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
## SCRIPTS
|
|
98
|
+
|
|
99
|
+
A layer's two scripts sit beside its config: .pi-pod/init.sh and .pi-pod/bake.sh in a
|
|
100
|
+
project, init.sh and bake.sh in ~/.pi-pod/org/. Every layer's scripts run, lowest layer first.
|
|
101
|
+
|
|
102
|
+
The init script runs in every pod at launch, as non-interactive bash (`CI=1`,
|
|
103
|
+
`DEBIAN_FRONTEND=noninteractive`) in the workdir, with the pod's secrets in its environment.
|
|
104
|
+
It is where a project clones its repository and installs dependencies, since a project with a
|
|
105
|
+
.pi-pod/config.json gets no copy of its files. A pod reused with `--reuse` runs it again over
|
|
106
|
+
the files already there, so write it to make a second run a quick no-op. A failure aborts the
|
|
107
|
+
launch unless `initOnFailure` says otherwise.
|
|
108
|
+
|
|
109
|
+
The bake script is built into the pod image once, and every later launch starts with its
|
|
110
|
+
results. On the first launch after an edit, or with a custom `image`, it runs live in the pod
|
|
111
|
+
instead, before init. It runs as root in /root, with no secrets, no environment, and no
|
|
112
|
+
workspace, so it suits deterministic installs that every pod repeats: `apt-get install`,
|
|
113
|
+
`npm install -g`, toolchains. Anything that needs a secret, or differs between pods, belongs in
|
|
114
|
+
init.
|
|
115
|
+
|
|
116
|
+
## EXAMPLES
|
|
117
|
+
|
|
118
|
+
A project's .pi-pod/config.json that limits network access:
|
|
119
|
+
|
|
120
|
+
```
|
|
121
|
+
{
|
|
122
|
+
"resources": { "cpu": 4, "memoryGB": 8 },
|
|
123
|
+
"egress": {
|
|
124
|
+
"mode": "allowlist",
|
|
125
|
+
"allow": ["github.com", "registry.npmjs.org"]
|
|
126
|
+
},
|
|
127
|
+
"pi": { "model": "anthropic/claude-opus-4-7", "thinking": "high" },
|
|
128
|
+
"template": "my-service"
|
|
129
|
+
}
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
Organization defaults, one key at a time:
|
|
133
|
+
|
|
134
|
+
```
|
|
135
|
+
pipod settings org set resources.memoryGB 8
|
|
136
|
+
pipod settings org set idleTimeoutMinutes 30
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
## RETIRED KEYS
|
|
140
|
+
|
|
141
|
+
`envFile`, `initScript`, `bakeScript`, and `reuse` fail with a message saying what replaced
|
|
142
|
+
them: the files are always .pi-pod/env, .pi-pod/init.sh, and .pi-pod/bake.sh, and reuse is the
|
|
143
|
+
`--reuse` launch flag. `pi.hostConfig.skills` and `pi.hostConfig.extensions` fail the same
|
|
144
|
+
way. `provider` and `deniedProviders` warn and are ignored.
|
|
145
|
+
|
|
146
|
+
## SEE ALSO
|
|
147
|
+
|
|
148
|
+
pipod(1)
|