@tinycloud/cli 1.5.0-beta.2 → 1.5.0-beta.21
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 +59 -0
- package/dist/index.js +21 -5
- package/dist/index.js.map +1 -1
- package/dist/legacy-entry.js +693 -216
- package/dist/legacy-entry.js.map +1 -1
- package/package.json +9 -9
- package/skills/tc-cli/REFERENCE.md +24 -1
- package/skills/tc-cli/SKILL.md +2 -0
package/README.md
CHANGED
|
@@ -87,6 +87,7 @@ tc kv list
|
|
|
87
87
|
tc secrets network init
|
|
88
88
|
printf '%s' "$ANTHROPIC_API_KEY" | tc secrets put ANTHROPIC_API_KEY --stdin
|
|
89
89
|
tc secrets get ANTHROPIC_API_KEY
|
|
90
|
+
tc secrets run ANTHROPIC_API_KEY -- python train.py # the value only in the command's environment
|
|
90
91
|
|
|
91
92
|
# Ask the owner for a secret an agent needs, then wait for it
|
|
92
93
|
# (call TinyCloud's CLI by absolute path: a bare `tc` can be iproute2's /usr/sbin/tc)
|
|
@@ -128,6 +129,7 @@ tc delegation create --to did:pkh:eip155:1:0x...
|
|
|
128
129
|
| `tc space create` | Create a new space |
|
|
129
130
|
| `tc delegation create` | Grant access to another user |
|
|
130
131
|
| `tc delegation list` | List delegations |
|
|
132
|
+
| `tc delegation revoke <cid>` | Revoke a delegation. From a delegate profile, revoke one its own key issued. |
|
|
131
133
|
| `tc share` | Share data with another user |
|
|
132
134
|
| `tc node` | Manage TinyCloud nodes |
|
|
133
135
|
| `tc profile list` | List profiles |
|
|
@@ -138,6 +140,7 @@ tc delegation create --to did:pkh:eip155:1:0x...
|
|
|
138
140
|
| `tc secrets network show` | Show a secrets decryption network |
|
|
139
141
|
| `tc secrets network init` | Create or fetch the default secrets network |
|
|
140
142
|
| `tc secrets network grant` | Grant `tinycloud.encryption/decrypt` on a secrets network |
|
|
143
|
+
| `tc secrets run` | Run a command with secrets in its environment |
|
|
141
144
|
| `tc secrets request` | Print a Secret Manager link asking the owner to add secrets (offline) |
|
|
142
145
|
| `tc secrets wait` | Wait until secrets exist and are readable (never signs in; needs a stored session; exit 8 pending, 130 interrupted) |
|
|
143
146
|
| `tc secrets manage` | Print or open the Secret Manager page, `{url, opened}` |
|
|
@@ -159,6 +162,62 @@ still exits 0 and installs the rest. If the schema fails after notes were
|
|
|
159
162
|
written, it says "notes saved; tables not set up: run again"; running it again
|
|
160
163
|
is safe.
|
|
161
164
|
|
|
165
|
+
### Running a command with secrets
|
|
166
|
+
|
|
167
|
+
```bash
|
|
168
|
+
tc secrets run NAME... [--map NAME=ENV_VAR]... [--scope S] [--space S] [--delegation SOURCE] [--private-key HEX] -- <command> [args...]
|
|
169
|
+
|
|
170
|
+
tc secrets run ANTHROPIC_API_KEY OPENAI_API_KEY -- python train.py
|
|
171
|
+
tc secrets run --map ANTHROPIC_KEY=ANTHROPIC_API_KEY -- node server.js
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
`tc secrets run` reads every named secret as `tc secrets get` does, then
|
|
175
|
+
starts `<command>` directly, without a shell, with each value in its
|
|
176
|
+
environment: under the secret's name, or under `ENV_VAR` for `--map
|
|
177
|
+
NAME=ENV_VAR`. A value replaces an inherited variable of the same name.
|
|
178
|
+
tc doesn't pass its own `TC_PRIVATE_KEY` to the command. To give the command
|
|
179
|
+
a key from a secret, use `--map NAME=TC_PRIVATE_KEY`.
|
|
180
|
+
Everything after the first `--`, including any further `--`, goes to the
|
|
181
|
+
command unchanged. The command uses tc's stdin, stdout and stderr; tc itself
|
|
182
|
+
writes nothing to stdout, and its own messages go to stderr.
|
|
183
|
+
|
|
184
|
+
Name at least one secret, as an argument or with `--map`. `ENV_VAR` must
|
|
185
|
+
match `[A-Za-z_][A-Za-z0-9_]*`, and two secrets cannot be mapped to the same
|
|
186
|
+
variable (exit 2). If any secret cannot be read, the command does not start
|
|
187
|
+
and tc exits with the code and error `tc secrets get` gives for that secret.
|
|
188
|
+
Otherwise tc exits with the command's exit code. If the command was ended by
|
|
189
|
+
SIGINT, SIGTERM, SIGHUP, SIGKILL, SIGALRM or SIGUSR2, tc ends by the same
|
|
190
|
+
signal (or exits with 128 plus the signal number if that signal doesn't end
|
|
191
|
+
tc). If any other signal ended it, such as SIGQUIT or SIGSEGV, tc exits with
|
|
192
|
+
128 plus the signal number instead, so tc does not cause a core dump
|
|
193
|
+
(SIGUSR1 and SIGPIPE are left out too: Node uses SIGUSR1 for its inspector
|
|
194
|
+
and ignores SIGPIPE).
|
|
195
|
+
|
|
196
|
+
SIGINT, SIGTERM, SIGHUP and SIGQUIT sent to tc go to the command. When tc
|
|
197
|
+
runs in the foreground of a terminal, it doesn't pass on SIGINT, SIGQUIT or
|
|
198
|
+
SIGHUP: the terminal already sends them (Ctrl-C, Ctrl-\, hangup) to the
|
|
199
|
+
command, so the command normally gets each one once. tc checks whether it's
|
|
200
|
+
in the foreground using `/proc`, or `ps` where `/proc` isn't available. If
|
|
201
|
+
neither works, it passes the signals on. When tc runs in the background, it
|
|
202
|
+
passes them on, so a signal sent to the whole job (for example `kill -INT
|
|
203
|
+
%1`) can reach the command twice.
|
|
204
|
+
|
|
205
|
+
From a script, stop the command by sending SIGTERM to tc's process ID. tc
|
|
206
|
+
passes it on, waits for the command to exit, then exits the way the command
|
|
207
|
+
did (the command's own exit code if it handles SIGTERM itself). If the
|
|
208
|
+
command ignores SIGTERM, tc keeps waiting.
|
|
209
|
+
|
|
210
|
+
A command that does not exist exits 127; one that cannot be executed, or
|
|
211
|
+
cannot be started for another reason, exits 126. These cases print one plain
|
|
212
|
+
line on stderr, even with `--json`: `tc secrets run: <command>: command not
|
|
213
|
+
found`, `…: permission denied` or `…: cannot run (<error code>)`.
|
|
214
|
+
|
|
215
|
+
Limits: `tc secrets run` keeps values out of the command line, your shell
|
|
216
|
+
history and tc's own output. It doesn't hide them from the command: the
|
|
217
|
+
command, and anything it starts, receives the values and can print, log or
|
|
218
|
+
pass them on. Other programs running as the same user can often read a
|
|
219
|
+
process's environment too.
|
|
220
|
+
|
|
162
221
|
## Global Options
|
|
163
222
|
|
|
164
223
|
```
|
package/dist/index.js
CHANGED
|
@@ -7385,6 +7385,7 @@ var init_profiles = __esm({
|
|
|
7385
7385
|
"use strict";
|
|
7386
7386
|
init_constants();
|
|
7387
7387
|
init_storage2();
|
|
7388
|
+
init_types();
|
|
7388
7389
|
init_errors();
|
|
7389
7390
|
ProfileManager = class _ProfileManager {
|
|
7390
7391
|
// ── Initialization ──────────────────────────────────────────────────
|
|
@@ -7666,6 +7667,7 @@ var init_profiles = __esm({
|
|
|
7666
7667
|
quiet: options.quiet ?? false,
|
|
7667
7668
|
replication,
|
|
7668
7669
|
replicationDebug: options.replicationDebug === true || process.env.TC_REPLICATION_DEBUG === "1",
|
|
7670
|
+
...profileConfig === void 0 ? {} : { posture: resolveProfilePosture(profileConfig) },
|
|
7669
7671
|
...localDiscovery === void 0 ? {} : { localDiscovery }
|
|
7670
7672
|
};
|
|
7671
7673
|
}
|
|
@@ -13419,7 +13421,7 @@ async function refusal(response) {
|
|
|
13419
13421
|
async function prepareLinkRecord(input) {
|
|
13420
13422
|
const apiOrigin = checkApiOrigin(input.apiOrigin);
|
|
13421
13423
|
const nowMs = toEpochMs(input.now);
|
|
13422
|
-
const expiresMs = input.expiresAt.getTime();
|
|
13424
|
+
const expiresMs = Math.floor(input.expiresAt.getTime() / 1e3) * 1e3;
|
|
13423
13425
|
if (!Number.isFinite(nowMs) || !Number.isFinite(expiresMs)) throw new LinkError("invalid_argument", "now and expiresAt must be valid dates");
|
|
13424
13426
|
let blob;
|
|
13425
13427
|
let key;
|
|
@@ -28764,17 +28766,30 @@ function createShareLinks(input) {
|
|
|
28764
28766
|
return {
|
|
28765
28767
|
async show(published, options) {
|
|
28766
28768
|
const material = published.deliveryMaterial;
|
|
28767
|
-
if (published.link.kind !== "policy"
|
|
28769
|
+
if (published.link.kind !== "policy") return { url: published.url, short: false };
|
|
28768
28770
|
if (options.fullLink) return { url: published.url, short: false };
|
|
28769
28771
|
const now = options.now ?? /* @__PURE__ */ new Date();
|
|
28770
28772
|
const expiresAt = new Date(published.metadata.expiresAt);
|
|
28771
28773
|
const choice = linkFormForLifetime((expiresAt.getTime() - now.getTime()) / 1e3);
|
|
28772
28774
|
if (choice.form === "full") return { url: published.url, short: false, ...choice.warning ? { notice: LINK_EXPIRY_WARNING } : {} };
|
|
28773
28775
|
try {
|
|
28776
|
+
const issuerKey = await input.signer();
|
|
28777
|
+
let sealed;
|
|
28778
|
+
if (material !== void 0) {
|
|
28779
|
+
sealed = { blob: fromBase64Url4(material.sealedEnvelope), key: fromBase64Url4(material.envelopeKey) };
|
|
28780
|
+
} else {
|
|
28781
|
+
const parsed = parseLink(published.url, { trustedOrigins: [published.metadata.origin] });
|
|
28782
|
+
if (parsed.form !== "full") throw new LinkError("invalid_argument");
|
|
28783
|
+
const opened = await openLinkRecord(parsed.record, parsed.key, { now });
|
|
28784
|
+
if (opened.type !== "share" || opened.header.issuer !== issuerKey.did || opened.header.bodyCid !== published.link.cid || opened.header.expiresAt !== published.metadata.expiresAt) {
|
|
28785
|
+
throw new LinkError("invalid_argument");
|
|
28786
|
+
}
|
|
28787
|
+
sealed = { blob: opened.body, key: parsed.key };
|
|
28788
|
+
}
|
|
28774
28789
|
const created = await createLink({
|
|
28775
28790
|
type: "share",
|
|
28776
|
-
sealed
|
|
28777
|
-
issuerKey
|
|
28791
|
+
sealed,
|
|
28792
|
+
issuerKey,
|
|
28778
28793
|
apiOrigin,
|
|
28779
28794
|
linkOrigin: new URL(published.url).origin,
|
|
28780
28795
|
expiresAt,
|
|
@@ -31646,7 +31661,8 @@ configureShareCommandServices({
|
|
|
31646
31661
|
revocation: shareAuthority.revocation,
|
|
31647
31662
|
nativeReader: shareAuthority.nativeReader,
|
|
31648
31663
|
artifactStore: shareAuthority.artifactStore,
|
|
31649
|
-
links: shareAuthority.links
|
|
31664
|
+
links: shareAuthority.links,
|
|
31665
|
+
shortLinkInvitations: true
|
|
31650
31666
|
});
|
|
31651
31667
|
var argv = process.argv.slice(2);
|
|
31652
31668
|
var globalLongOptionsWithValues = { "--profile": true, "--host": true };
|