@sente-labs/cli 0.10.0 → 0.13.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 +73 -46
- package/dist/client.js +12 -3
- package/dist/client.js.map +1 -1
- package/dist/commands/inbox.js +93 -10
- package/dist/commands/inbox.js.map +1 -1
- package/dist/commands/token.js +24 -0
- package/dist/commands/token.js.map +1 -0
- package/dist/config.js +0 -27
- package/dist/config.js.map +1 -1
- package/dist/index.js +6 -28
- package/dist/index.js.map +1 -1
- package/dist/{skill/autoupdate.js → update.js} +10 -47
- package/dist/update.js.map +1 -0
- package/package.json +3 -3
- package/dist/commands/appGraph.js +0 -110
- package/dist/commands/appGraph.js.map +0 -1
- package/dist/commands/auth.js +0 -54
- package/dist/commands/auth.js.map +0 -1
- package/dist/commands/deployWebhook.js +0 -94
- package/dist/commands/deployWebhook.js.map +0 -1
- package/dist/commands/init.js +0 -209
- package/dist/commands/init.js.map +0 -1
- package/dist/commands/project.js +0 -283
- package/dist/commands/project.js.map +0 -1
- package/dist/commands/schedule.js +0 -188
- package/dist/commands/schedule.js.map +0 -1
- package/dist/commands/secret.js +0 -245
- package/dist/commands/secret.js.map +0 -1
- package/dist/commands/task.js +0 -425
- package/dist/commands/task.js.map +0 -1
- package/dist/commands/workflow.js +0 -69
- package/dist/commands/workflow.js.map +0 -1
- package/dist/skill/SKILL.md +0 -92
- package/dist/skill/autoupdate.js.map +0 -1
- package/dist/skill/template.js +0 -68
- package/dist/skill/template.js.map +0 -1
package/README.md
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
# @sente-labs/cli
|
|
2
2
|
|
|
3
|
-
The Sente CLI --
|
|
3
|
+
The Sente CLI -- give your AI agents **managed email identities** (AgentAccount).
|
|
4
|
+
Create an email address your agent owns on `agents.sente.run`, then send,
|
|
5
|
+
receive, and react to mail -- verification links, OTPs, replies -- from your
|
|
6
|
+
terminal, scripts, or Claude Code.
|
|
4
7
|
|
|
5
8
|
## Install
|
|
6
9
|
|
|
@@ -10,79 +13,103 @@ npm install -g @sente-labs/cli
|
|
|
10
13
|
|
|
11
14
|
Requires Node.js 18+.
|
|
12
15
|
|
|
16
|
+
Building an agent that should set this up itself? Point it at the onboarding
|
|
17
|
+
skill: <https://sente.run/skill.md>.
|
|
18
|
+
|
|
13
19
|
## Quickstart
|
|
14
20
|
|
|
15
21
|
```bash
|
|
16
|
-
# 1.
|
|
22
|
+
# 1. Sign in (opens the browser, stores an API key in ~/.sente/credentials)
|
|
17
23
|
sente login
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
sente
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
24
|
+
sente whoami
|
|
25
|
+
|
|
26
|
+
# 2. Give your agent an identity -- a real, reusable email address
|
|
27
|
+
sente identity create --name "Support Bot" --local-part support-bot
|
|
28
|
+
# -> support-bot@agents.sente.run
|
|
29
|
+
|
|
30
|
+
# 3. Read its mail
|
|
31
|
+
sente inbox --identity support-bot # recent messages
|
|
32
|
+
sente wait --identity support-bot --timeout 60 # block until the next message
|
|
33
|
+
sente listen --identity support-bot # stream messages as they arrive
|
|
34
|
+
|
|
35
|
+
# Verification emails: --otp / --magic-link block for the verification message
|
|
36
|
+
# and print JUST the extracted code / link (pipeable):
|
|
37
|
+
CODE=$(sente wait --identity support-bot --otp --timeout 60)
|
|
38
|
+
|
|
39
|
+
# 4. Send from it
|
|
40
|
+
sente send --identity support-bot --to user@example.com \
|
|
41
|
+
--subject "Hello" --text "It works."
|
|
42
|
+
# Reply in-thread to an inbound message:
|
|
43
|
+
sente send --identity support-bot --to user@example.com \
|
|
44
|
+
--subject "Re: Hello" --text "Following up." --reply-to <messageId>
|
|
28
45
|
```
|
|
29
46
|
|
|
30
|
-
|
|
31
|
-
with `sente install-skill`.
|
|
47
|
+
Use `--json` on any command for machine-readable output.
|
|
32
48
|
|
|
33
|
-
##
|
|
49
|
+
## Webhooks (push delivery)
|
|
34
50
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
preview deploys (Vercel, Netlify) all work. `localhost` and non-public PR
|
|
38
|
-
previews do not.
|
|
51
|
+
Register your HTTPS endpoint and Sente POSTs a `message.received` event for
|
|
52
|
+
each inbound email. Verify the `X-Sente-Secret` header on every delivery.
|
|
39
53
|
|
|
40
|
-
|
|
41
|
-
webhook
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
```yaml
|
|
45
|
-
- run: |
|
|
46
|
-
curl -X POST $SENTE_DEPLOY_ENDPOINT \
|
|
47
|
-
-H "X-Sente-Secret: ${{ secrets.SENTE_WEBHOOK_SECRET }}" \
|
|
48
|
-
-d '{"environment":"staging","commitSha":"'"$GITHUB_SHA"'"}'
|
|
54
|
+
```bash
|
|
55
|
+
sente webhook register --url https://my-app.com/hooks/sente --identity support-bot
|
|
56
|
+
sente webhook list
|
|
57
|
+
sente webhook delete <id>
|
|
49
58
|
```
|
|
50
59
|
|
|
51
|
-
|
|
60
|
+
Developing the handler locally? Relay live inbound mail to it with no public
|
|
61
|
+
URL -- `listen --forward` POSTs each message in the exact webhook envelope
|
|
62
|
+
(with `x-sente-secret` taken from `SENTE_WEBHOOK_SECRET`, if set):
|
|
52
63
|
|
|
53
64
|
```bash
|
|
54
|
-
sente
|
|
55
|
-
sente project show # show project bound to this repo
|
|
56
|
-
sente task list --json # list tasks
|
|
57
|
-
sente task show <id> # task details
|
|
58
|
-
sente task results <id> --failed-step --json # focused failure payload
|
|
59
|
-
sente task create --workflow <id> --name "..." --instruction "..." \
|
|
60
|
-
--steps-from steps.json
|
|
61
|
-
sente task update <id> --steps-from steps.json
|
|
62
|
-
sente task delete <id>
|
|
63
|
-
sente sync # regenerate .sente/tasks.json
|
|
65
|
+
sente listen --identity support-bot --forward http://localhost:3000/hooks/sente
|
|
64
66
|
```
|
|
65
67
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
+
Or run a shell command per message (message JSON on stdin):
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
sente listen --identity support-bot --exec './handle-message.sh'
|
|
72
|
+
```
|
|
68
73
|
|
|
69
74
|
## Auth
|
|
70
75
|
|
|
71
|
-
|
|
72
|
-
|
|
76
|
+
`sente login` stores the API key in `~/.sente/credentials` (mode 0600). The
|
|
77
|
+
key authenticates as your whole organization -- don't paste it into chats or
|
|
78
|
+
commit it. To hand it to your app without echoing it:
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
echo "SENTE_API_TOKEN=$(sente token)" >> .env
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
For CI or non-interactive use, set env vars instead of logging in:
|
|
73
85
|
|
|
74
86
|
```bash
|
|
75
87
|
export SENTE_API_TOKEN=sk_sente_...
|
|
76
|
-
export SENTE_GATEWAY_URL=https://api.sente.run
|
|
88
|
+
export SENTE_GATEWAY_URL=https://api.sente.run # optional override
|
|
77
89
|
```
|
|
78
90
|
|
|
79
|
-
|
|
91
|
+
## Commands
|
|
92
|
+
|
|
93
|
+
| Command | What it does |
|
|
94
|
+
| --- | --- |
|
|
95
|
+
| `sente login` | Browser sign-in; mints and stores an API key |
|
|
96
|
+
| `sente whoami` | Show the logged-in account + organization |
|
|
97
|
+
| `sente token` | Print the stored API key (for piping into `.env`) |
|
|
98
|
+
| `sente identity create\|list\|show` | Manage email identities |
|
|
99
|
+
| `sente inbox --identity <ref>` | List recent messages |
|
|
100
|
+
| `sente wait --identity <ref>` | Block until the next message (long-poll); `--otp` / `--magic-link` print just the code / link |
|
|
101
|
+
| `sente listen --identity <ref>` | Stream messages; `--exec` / `--forward` to react |
|
|
102
|
+
| `sente send --identity <ref>` | Send email (`--reply-to` threads replies) |
|
|
103
|
+
| `sente webhook register\|list\|delete` | Manage push delivery to your endpoint |
|
|
104
|
+
|
|
105
|
+
`<ref>` is an identity id, email, or local-part.
|
|
80
106
|
|
|
81
107
|
## Documentation
|
|
82
108
|
|
|
83
109
|
- Home: <https://sente.run>
|
|
110
|
+
- Agent onboarding skill: <https://sente.run/skill.md>
|
|
84
111
|
- Issues: <https://github.com/sente-labs/agentic-browser/issues>
|
|
85
112
|
|
|
86
113
|
## License
|
|
87
114
|
|
|
88
|
-
|
|
115
|
+
MIT
|
package/dist/client.js
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.GatewayClient = exports.ApiError = void 0;
|
|
4
4
|
const credentials_1 = require("./credentials");
|
|
5
|
+
const update_1 = require("./update");
|
|
5
6
|
/**
|
|
6
7
|
* Domain-specific error. Surfaces structured failure modes so commands can
|
|
7
8
|
* print clean messages without leaking HTTP internals.
|
|
@@ -45,7 +46,7 @@ class GatewayClient {
|
|
|
45
46
|
headers: {
|
|
46
47
|
Authorization: `Bearer ${this.creds.token}`,
|
|
47
48
|
'Content-Type': 'application/json',
|
|
48
|
-
'User-Agent':
|
|
49
|
+
'User-Agent': `sente-cli/${update_1.CLI_VERSION}`,
|
|
49
50
|
},
|
|
50
51
|
};
|
|
51
52
|
if (opts.body !== undefined) {
|
|
@@ -98,8 +99,16 @@ async function parseResponse(res) {
|
|
|
98
99
|
}
|
|
99
100
|
if (!res.ok) {
|
|
100
101
|
const code = (body && body.code) || `HTTP_${res.status}`;
|
|
101
|
-
const
|
|
102
|
-
|
|
102
|
+
const rawError = body && body.error;
|
|
103
|
+
// `error` may be a string, or a structured value (e.g. an array of zod issues on a 400).
|
|
104
|
+
// Stringify non-strings so the message is readable instead of "[object Object]".
|
|
105
|
+
const message = typeof rawError === 'string'
|
|
106
|
+
? rawError
|
|
107
|
+
: rawError !== undefined
|
|
108
|
+
? JSON.stringify(rawError)
|
|
109
|
+
: typeof body === 'string'
|
|
110
|
+
? body
|
|
111
|
+
: `Request failed with status ${res.status}`;
|
|
103
112
|
throw new ApiError(res.status, code, message, body);
|
|
104
113
|
}
|
|
105
114
|
return body;
|
package/dist/client.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":";;;AAAA,+CAA6D;
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
|
package/dist/commands/inbox.js
CHANGED
|
@@ -16,6 +16,38 @@ function printMessages(msgs) {
|
|
|
16
16
|
}
|
|
17
17
|
}
|
|
18
18
|
const IDENTITY_HELP = 'identity id, email, or local-part';
|
|
19
|
+
/**
|
|
20
|
+
* POST a message to a local URL in the exact shape Sente's real webhook sends
|
|
21
|
+
* (`{ type: "message.received", message: {...} }` + `x-sente-secret` header), so
|
|
22
|
+
* a webhook handler can be tested locally with no public URL. The secret comes
|
|
23
|
+
* from SENTE_WEBHOOK_SECRET (the same value the handler verifies against); the
|
|
24
|
+
* header is omitted if it's unset. Like the real webhook, the body carries no
|
|
25
|
+
* mail content — the handler fetches it with `messages.get(message.id)`.
|
|
26
|
+
*/
|
|
27
|
+
async function forwardToWebhook(url, msg, identity, secret) {
|
|
28
|
+
const envelope = {
|
|
29
|
+
type: 'message.received',
|
|
30
|
+
message: {
|
|
31
|
+
id: msg.id,
|
|
32
|
+
channel: 'email',
|
|
33
|
+
identity: { id: identity.id, name: identity.name, email: identity.email },
|
|
34
|
+
from: msg.fromAddr,
|
|
35
|
+
to: msg.toAddr,
|
|
36
|
+
subject: msg.subject,
|
|
37
|
+
createdAt: msg.createdAt,
|
|
38
|
+
},
|
|
39
|
+
};
|
|
40
|
+
const headers = { 'content-type': 'application/json' };
|
|
41
|
+
if (secret)
|
|
42
|
+
headers['x-sente-secret'] = secret;
|
|
43
|
+
try {
|
|
44
|
+
const res = await fetch(url, { method: 'POST', headers, body: JSON.stringify(envelope) });
|
|
45
|
+
process.stderr.write(`→ ${url} ${res.status} "${msg.subject ?? '(no subject)'}"\n`);
|
|
46
|
+
}
|
|
47
|
+
catch (err) {
|
|
48
|
+
process.stderr.write(`(forward failed: ${err.message})\n`);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
19
51
|
/**
|
|
20
52
|
* `sente inbox|wait|listen` — read and react to an identity's mail (AgentAccount).
|
|
21
53
|
* Targets the Sente API (`/v1/messages`) with the stored API key.
|
|
@@ -44,24 +76,50 @@ function registerInboxCommands(program, globalOpts) {
|
|
|
44
76
|
});
|
|
45
77
|
program
|
|
46
78
|
.command('wait')
|
|
47
|
-
.description('Block until the next message arrives for an identity (long-poll)'
|
|
79
|
+
.description('Block until the next message arrives for an identity (long-poll). ' +
|
|
80
|
+
'With --otp / --magic-link, wait for a verification email and print just the code / link (pipeable).')
|
|
48
81
|
.requiredOption('--identity <ref>', IDENTITY_HELP)
|
|
49
82
|
.option('--since <ts>', 'wait for messages after this ISO timestamp')
|
|
50
83
|
.option('--timeout <s>', 'seconds to wait before giving up', '25')
|
|
84
|
+
.option('--otp', 'wait for a verification-code email; print just the code')
|
|
85
|
+
.option('--magic-link', 'wait for a magic-link email; print just the link')
|
|
51
86
|
.action(async (cmdOpts) => {
|
|
52
87
|
const opts = globalOpts();
|
|
88
|
+
if (cmdOpts.otp && cmdOpts.magicLink) {
|
|
89
|
+
process.exit((0, output_1.printError)(new Error('--otp and --magic-link are mutually exclusive'), opts));
|
|
90
|
+
}
|
|
91
|
+
const kind = cmdOpts.otp ? 'otp' : cmdOpts.magicLink ? 'magic_link' : undefined;
|
|
53
92
|
try {
|
|
54
93
|
const client = new client_1.GatewayClient();
|
|
55
94
|
const identityId = await (0, identityRef_1.resolveIdentityId)(client, cmdOpts.identity);
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
95
|
+
// The server long-poll caps at 60s per call; loop ≤60s chunks so any --timeout works
|
|
96
|
+
// (verification emails can take up to ~2 min). Anchor `since` once so no message slips
|
|
97
|
+
// through the gap between chunks.
|
|
98
|
+
const deadline = Date.now() + Number(cmdOpts.timeout ?? '25') * 1000;
|
|
99
|
+
// Default to a 60s lookback (matches the server) so a just-arrived email isn't missed;
|
|
100
|
+
// anchored once so the chunked loop below can't skip it between chunks.
|
|
101
|
+
let since = cmdOpts.since ?? new Date(Date.now() - 60_000).toISOString();
|
|
102
|
+
let msg;
|
|
103
|
+
do {
|
|
104
|
+
const remaining = Math.min(60, Math.ceil((deadline - Date.now()) / 1000));
|
|
105
|
+
if (remaining <= 0)
|
|
106
|
+
break;
|
|
107
|
+
msg = await client.request('/v1/messages/wait', {
|
|
108
|
+
query: { identityId, since, timeout: String(remaining), kind },
|
|
109
|
+
});
|
|
110
|
+
} while (!msg && Date.now() < deadline);
|
|
59
111
|
if (!msg) {
|
|
60
112
|
if (!opts.json)
|
|
61
113
|
process.stderr.write('Timed out — no message.\n');
|
|
62
114
|
(0, output_1.printSuccess)(null, () => { }, opts);
|
|
63
115
|
return;
|
|
64
116
|
}
|
|
117
|
+
if (kind && !opts.json) {
|
|
118
|
+
// Bare artifact on stdout so it's pipeable: CODE=$(sente wait --identity x --otp)
|
|
119
|
+
const value = kind === 'otp' ? msg.annotation?.code : msg.annotation?.link;
|
|
120
|
+
process.stdout.write((value ?? '') + '\n');
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
65
123
|
(0, output_1.printSuccess)(msg, () => printMessages([msg]), opts);
|
|
66
124
|
}
|
|
67
125
|
catch (err) {
|
|
@@ -74,6 +132,7 @@ function registerInboxCommands(program, globalOpts) {
|
|
|
74
132
|
.requiredOption('--identity <ref>', IDENTITY_HELP)
|
|
75
133
|
.option('--since <ts>', 'start after this ISO timestamp')
|
|
76
134
|
.option('--exec <cmd>', 'run this shell command per message (message JSON on stdin)')
|
|
135
|
+
.option('--forward <url>', 'POST each inbound message to this URL as a Sente webhook (local webhook testing)')
|
|
77
136
|
.action(async (cmdOpts) => {
|
|
78
137
|
const client = new client_1.GatewayClient();
|
|
79
138
|
let identityId;
|
|
@@ -83,8 +142,20 @@ function registerInboxCommands(program, globalOpts) {
|
|
|
83
142
|
catch (err) {
|
|
84
143
|
process.exit((0, output_1.printError)(err, globalOpts()));
|
|
85
144
|
}
|
|
145
|
+
// --forward mimics the real webhook envelope, which embeds the identity.
|
|
146
|
+
let identity;
|
|
147
|
+
if (cmdOpts.forward) {
|
|
148
|
+
try {
|
|
149
|
+
identity = await client.request(`/v1/identities/${identityId}`);
|
|
150
|
+
}
|
|
151
|
+
catch (err) {
|
|
152
|
+
process.exit((0, output_1.printError)(err, globalOpts()));
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
const secret = process.env.SENTE_WEBHOOK_SECRET;
|
|
86
156
|
let since = cmdOpts.since;
|
|
87
|
-
|
|
157
|
+
const dest = cmdOpts.forward ? ` (forwarding to ${cmdOpts.forward})` : '';
|
|
158
|
+
process.stderr.write(`Listening on ${cmdOpts.identity}${dest}… (Ctrl-C to stop)\n`);
|
|
88
159
|
// Long-poll loop. Retry transient errors rather than dying — this is a daemon.
|
|
89
160
|
for (;;) {
|
|
90
161
|
let msg;
|
|
@@ -100,13 +171,17 @@ function registerInboxCommands(program, globalOpts) {
|
|
|
100
171
|
}
|
|
101
172
|
if (!msg)
|
|
102
173
|
continue; // timeout → re-poll
|
|
103
|
-
|
|
104
|
-
|
|
174
|
+
if (cmdOpts.forward) {
|
|
175
|
+
// Real webhooks fire on inbound only — skip the identity's own sends.
|
|
176
|
+
if (msg.direction !== 'outbound')
|
|
177
|
+
await forwardToWebhook(cmdOpts.forward, msg, identity, secret);
|
|
178
|
+
}
|
|
179
|
+
else if (cmdOpts.exec) {
|
|
105
180
|
const child = (0, node_child_process_1.spawn)(cmdOpts.exec, { shell: true, stdio: ['pipe', 'inherit', 'inherit'] });
|
|
106
|
-
child.stdin.end(
|
|
181
|
+
child.stdin.end(JSON.stringify(msg) + '\n');
|
|
107
182
|
}
|
|
108
183
|
else {
|
|
109
|
-
process.stdout.write(
|
|
184
|
+
process.stdout.write(JSON.stringify(msg) + '\n');
|
|
110
185
|
}
|
|
111
186
|
since = msg.createdAt;
|
|
112
187
|
}
|
|
@@ -119,6 +194,7 @@ function registerInboxCommands(program, globalOpts) {
|
|
|
119
194
|
.requiredOption('--subject <subject>', 'subject line')
|
|
120
195
|
.option('--text <text>', 'plain-text body')
|
|
121
196
|
.option('--html <html>', 'HTML body')
|
|
197
|
+
.option('--reply-to <msgId>', 'thread the reply to this inbound message id (sets In-Reply-To)')
|
|
122
198
|
.action(async (cmdOpts) => {
|
|
123
199
|
const opts = globalOpts();
|
|
124
200
|
try {
|
|
@@ -126,7 +202,14 @@ function registerInboxCommands(program, globalOpts) {
|
|
|
126
202
|
const identityId = await (0, identityRef_1.resolveIdentityId)(client, cmdOpts.identity);
|
|
127
203
|
const msg = await client.request('/v1/messages', {
|
|
128
204
|
method: 'POST',
|
|
129
|
-
body: {
|
|
205
|
+
body: {
|
|
206
|
+
identityId,
|
|
207
|
+
to: cmdOpts.to,
|
|
208
|
+
subject: cmdOpts.subject,
|
|
209
|
+
text: cmdOpts.text,
|
|
210
|
+
html: cmdOpts.html,
|
|
211
|
+
inReplyTo: cmdOpts.replyTo,
|
|
212
|
+
},
|
|
130
213
|
});
|
|
131
214
|
(0, output_1.printSuccess)(msg, `Sent to ${cmdOpts.to} (${msg.id})`, opts);
|
|
132
215
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"inbox.js","sourceRoot":"","sources":["../../src/commands/inbox.ts"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"inbox.js","sourceRoot":"","sources":["../../src/commands/inbox.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.registerTokenCommand = registerTokenCommand;
|
|
4
|
+
const credentials_1 = require("../credentials");
|
|
5
|
+
/**
|
|
6
|
+
* `sente token` — print the stored API key to stdout (nothing else), so it can
|
|
7
|
+
* be piped into a project's .env without echoing the secret into a chat:
|
|
8
|
+
* echo "SENTE_API_TOKEN=$(sente token)" >> .env
|
|
9
|
+
* Mirrors `gh auth token`. The key authenticates as the whole organization.
|
|
10
|
+
*/
|
|
11
|
+
function registerTokenCommand(program, _globalOpts) {
|
|
12
|
+
program
|
|
13
|
+
.command('token')
|
|
14
|
+
.description('Print the stored API key (for piping into .env)')
|
|
15
|
+
.action(() => {
|
|
16
|
+
const creds = (0, credentials_1.loadCredentials)();
|
|
17
|
+
if (!creds) {
|
|
18
|
+
process.stderr.write('Not logged in. Run `sente login` first, or set SENTE_API_TOKEN.\n');
|
|
19
|
+
process.exit(1);
|
|
20
|
+
}
|
|
21
|
+
process.stdout.write(creds.token + '\n');
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=token.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"token.js","sourceRoot":"","sources":["../../src/commands/token.ts"],"names":[],"mappings":";;AAUA,oDAYC;AArBD,gDAAiD;AAGjD;;;;;GAKG;AACH,SAAgB,oBAAoB,CAAC,OAAgB,EAAE,WAA6B;IAClF,OAAO;SACJ,OAAO,CAAC,OAAO,CAAC;SAChB,WAAW,CAAC,iDAAiD,CAAC;SAC9D,MAAM,CAAC,GAAG,EAAE;QACX,MAAM,KAAK,GAAG,IAAA,6BAAe,GAAE,CAAC;QAChC,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,mEAAmE,CAAC,CAAC;YAC1F,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QACD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,GAAG,IAAI,CAAC,CAAC;IAC3C,CAAC,CAAC,CAAC;AACP,CAAC"}
|
package/dist/config.js
CHANGED
|
@@ -37,14 +37,12 @@ exports.DEFAULT_AUTH0_AUDIENCE = exports.DEFAULT_AUTH0_CLIENT_ID = exports.DEFAU
|
|
|
37
37
|
exports.gatewayUrl = gatewayUrl;
|
|
38
38
|
exports.envToken = envToken;
|
|
39
39
|
exports.auth0Config = auth0Config;
|
|
40
|
-
exports.readLocalProjectId = readLocalProjectId;
|
|
41
40
|
/**
|
|
42
41
|
* CLI runtime configuration. Env vars take precedence over defaults.
|
|
43
42
|
*
|
|
44
43
|
* SENTE_GATEWAY_URL -- override the gateway base URL
|
|
45
44
|
* SENTE_API_TOKEN -- override the stored PAT (CI use)
|
|
46
45
|
*/
|
|
47
|
-
const fs = __importStar(require("fs"));
|
|
48
46
|
const os = __importStar(require("os"));
|
|
49
47
|
const path = __importStar(require("path"));
|
|
50
48
|
exports.DEFAULT_GATEWAY_URL = 'https://api.sente.run';
|
|
@@ -68,29 +66,4 @@ function auth0Config() {
|
|
|
68
66
|
audience: process.env.SENTE_AUTH0_AUDIENCE || exports.DEFAULT_AUTH0_AUDIENCE,
|
|
69
67
|
};
|
|
70
68
|
}
|
|
71
|
-
/**
|
|
72
|
-
* Read the project id from the local .sente/config.json, walking up from the
|
|
73
|
-
* cwd (same discovery as git/node_modules). Returns null if none is found.
|
|
74
|
-
* Canonical home for this lookup; commands that need a project default to it.
|
|
75
|
-
*/
|
|
76
|
-
function readLocalProjectId() {
|
|
77
|
-
let dir = process.cwd();
|
|
78
|
-
while (true) {
|
|
79
|
-
const candidate = path.join(dir, '.sente', 'config.json');
|
|
80
|
-
if (fs.existsSync(candidate)) {
|
|
81
|
-
try {
|
|
82
|
-
const parsed = JSON.parse(fs.readFileSync(candidate, 'utf8'));
|
|
83
|
-
if (typeof parsed.projectId === 'string')
|
|
84
|
-
return parsed.projectId;
|
|
85
|
-
}
|
|
86
|
-
catch {
|
|
87
|
-
return null;
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
const parent = path.dirname(dir);
|
|
91
|
-
if (parent === dir)
|
|
92
|
-
return null;
|
|
93
|
-
dir = parent;
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
69
|
//# sourceMappingURL=config.js.map
|
package/dist/config.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAaA,gCAEC;AAED,4BAEC;AAQD,kCAMC;AAjCD;;;;;GAKG;AACH,uCAAyB;AACzB,2CAA6B;AAEhB,QAAA,mBAAmB,GAAG,uBAAuB,CAAC;AAC9C,QAAA,eAAe,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,QAAQ,CAAC,CAAC;AACpD,QAAA,gBAAgB,GAAG,IAAI,CAAC,IAAI,CAAC,uBAAe,EAAE,aAAa,CAAC,CAAC;AAE1E,SAAgB,UAAU;IACxB,OAAO,OAAO,CAAC,GAAG,CAAC,iBAAiB,IAAI,2BAAmB,CAAC;AAC9D,CAAC;AAED,SAAgB,QAAQ;IACtB,OAAO,OAAO,CAAC,GAAG,CAAC,eAAe,IAAI,SAAS,CAAC;AAClD,CAAC;AAED,yFAAyF;AACzF,gEAAgE;AACnD,QAAA,oBAAoB,GAAG,mCAAmC,CAAC;AAC3D,QAAA,uBAAuB,GAAG,kCAAkC,CAAC;AAC7D,QAAA,sBAAsB,GAAG,qBAAqB,CAAC;AAE5D,SAAgB,WAAW;IACzB,OAAO;QACL,MAAM,EAAE,OAAO,CAAC,GAAG,CAAC,kBAAkB,IAAI,4BAAoB;QAC9D,QAAQ,EAAE,OAAO,CAAC,GAAG,CAAC,qBAAqB,IAAI,+BAAuB;QACtE,QAAQ,EAAE,OAAO,CAAC,GAAG,CAAC,oBAAoB,IAAI,8BAAsB;KACrE,CAAC;AACJ,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -4,32 +4,20 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
4
4
|
const commander_1 = require("commander");
|
|
5
5
|
const login_1 = require("./commands/login");
|
|
6
6
|
const whoami_1 = require("./commands/whoami");
|
|
7
|
-
const
|
|
8
|
-
const workflow_1 = require("./commands/workflow");
|
|
9
|
-
const appGraph_1 = require("./commands/appGraph");
|
|
10
|
-
const task_1 = require("./commands/task");
|
|
11
|
-
const init_1 = require("./commands/init");
|
|
12
|
-
const secret_1 = require("./commands/secret");
|
|
13
|
-
const schedule_1 = require("./commands/schedule");
|
|
14
|
-
const deployWebhook_1 = require("./commands/deployWebhook");
|
|
15
|
-
const auth_1 = require("./commands/auth");
|
|
7
|
+
const token_1 = require("./commands/token");
|
|
16
8
|
const identity_1 = require("./commands/identity");
|
|
17
9
|
const inbox_1 = require("./commands/inbox");
|
|
18
10
|
const webhook_1 = require("./commands/webhook");
|
|
19
|
-
const
|
|
20
|
-
// Silently refresh the installed Claude Code skill to match the running CLI.
|
|
21
|
-
// Synchronous + cheap (a file stat + at most one small write). No-op if the
|
|
22
|
-
// user customized the skill (no version marker) or --json mode is active.
|
|
23
|
-
(0, autoupdate_1.autoUpdateSkillIfStale)();
|
|
11
|
+
const update_1 = require("./update");
|
|
24
12
|
// Fire-and-forget npm registry check. Cached for 24h. Prints a one-line
|
|
25
13
|
// nudge to stderr if a newer CLI is available. Never blocks the user's
|
|
26
14
|
// command; settles at most by the time their action returns.
|
|
27
|
-
void (0,
|
|
15
|
+
void (0, update_1.checkForCliUpdate)();
|
|
28
16
|
const program = new commander_1.Command();
|
|
29
17
|
program
|
|
30
18
|
.name('sente')
|
|
31
|
-
.description('Sente CLI --
|
|
32
|
-
.version(
|
|
19
|
+
.description('Sente CLI -- give your AI agents managed email identities from the terminal and Claude Code')
|
|
20
|
+
.version(update_1.CLI_VERSION)
|
|
33
21
|
.option('--json', 'Emit machine-readable JSON instead of human output');
|
|
34
22
|
/**
|
|
35
23
|
* Global options aren't auto-propagated to subcommands by Commander, so we
|
|
@@ -39,17 +27,7 @@ program
|
|
|
39
27
|
const globalOpts = () => program.opts();
|
|
40
28
|
(0, login_1.registerLoginCommand)(program, globalOpts);
|
|
41
29
|
(0, whoami_1.registerWhoamiCommand)(program, globalOpts);
|
|
42
|
-
(0,
|
|
43
|
-
(0, init_1.registerInstallSkillCommand)(program, globalOpts);
|
|
44
|
-
(0, project_1.registerProjectCommands)(program, globalOpts);
|
|
45
|
-
(0, project_1.registerSyncCommand)(program, globalOpts);
|
|
46
|
-
(0, workflow_1.registerWorkflowCommands)(program, globalOpts);
|
|
47
|
-
(0, appGraph_1.registerAppGraphCommands)(program, globalOpts);
|
|
48
|
-
(0, task_1.registerTaskCommands)(program, globalOpts);
|
|
49
|
-
(0, secret_1.registerSecretCommands)(program, globalOpts);
|
|
50
|
-
(0, schedule_1.registerScheduleCommands)(program, globalOpts);
|
|
51
|
-
(0, deployWebhook_1.registerDeployWebhookCommands)(program, globalOpts);
|
|
52
|
-
(0, auth_1.registerAuthCommands)(program, globalOpts);
|
|
30
|
+
(0, token_1.registerTokenCommand)(program, globalOpts);
|
|
53
31
|
(0, identity_1.registerIdentityCommands)(program, globalOpts);
|
|
54
32
|
(0, inbox_1.registerInboxCommands)(program, globalOpts);
|
|
55
33
|
(0, webhook_1.registerWebhookCommands)(program, globalOpts);
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AACA,yCAAoC;AACpC,4CAAwD;AACxD,8CAA0D;AAC1D,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AACA,yCAAoC;AACpC,4CAAwD;AACxD,8CAA0D;AAC1D,4CAAwD;AACxD,kDAA+D;AAC/D,4CAAyD;AACzD,gDAA6D;AAC7D,qCAA0D;AAG1D,wEAAwE;AACxE,uEAAuE;AACvE,6DAA6D;AAC7D,KAAK,IAAA,0BAAiB,GAAE,CAAC;AAEzB,MAAM,OAAO,GAAG,IAAI,mBAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,OAAO,CAAC;KACb,WAAW,CAAC,6FAA6F,CAAC;KAC1G,OAAO,CAAC,oBAAW,CAAC;KACpB,MAAM,CAAC,QAAQ,EAAE,oDAAoD,CAAC,CAAC;AAE1E;;;;GAIG;AACH,MAAM,UAAU,GAAG,GAAe,EAAE,CAAC,OAAO,CAAC,IAAI,EAAc,CAAC;AAEhE,IAAA,4BAAoB,EAAC,OAAO,EAAE,UAAU,CAAC,CAAC;AAC1C,IAAA,8BAAqB,EAAC,OAAO,EAAE,UAAU,CAAC,CAAC;AAC3C,IAAA,4BAAoB,EAAC,OAAO,EAAE,UAAU,CAAC,CAAC;AAC1C,IAAA,mCAAwB,EAAC,OAAO,EAAE,UAAU,CAAC,CAAC;AAC9C,IAAA,6BAAqB,EAAC,OAAO,EAAE,UAAU,CAAC,CAAC;AAC3C,IAAA,iCAAuB,EAAC,OAAO,EAAE,UAAU,CAAC,CAAC;AAE7C,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;IAC7C,wEAAwE;IACxE,+CAA+C;IAC/C,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,UAAU,GAAG,EAAE,OAAO,IAAI,GAAG,IAAI,CAAC,CAAC;IACxD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
|