@meistrari/tela-cli 1.1.0 → 1.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 +21 -18
- package/dist/commands/auth.d.ts +8 -0
- package/dist/commands/auth.js +366 -4
- package/dist/commands/ingredients.d.ts +7 -35
- package/dist/commands/ingredients.js +241 -559
- package/dist/commands/skills.d.ts +33 -0
- package/dist/commands/skills.js +519 -0
- package/dist/index.js +136440 -31415
- package/dist/markdown.d.ts +17 -0
- package/dist/markdown.js +116 -0
- package/dist/program.js +22 -14
- package/dist/session.d.ts +28 -0
- package/dist/session.js +109 -0
- package/dist/skills.d.ts +87 -0
- package/dist/skills.js +303 -0
- package/package.json +1 -1
- package/skills/tela-cli/SKILL.md +19 -11
package/README.md
CHANGED
|
@@ -9,9 +9,12 @@ directly, and normal output must not print token material.
|
|
|
9
9
|
|
|
10
10
|
## Commands
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
Canonical commands:
|
|
13
13
|
|
|
14
14
|
```bash
|
|
15
|
+
tela auth login --no-interactive
|
|
16
|
+
tela auth logout --context <context-id>
|
|
17
|
+
tela auth whoami --json
|
|
15
18
|
tela auth token --json
|
|
16
19
|
tela auth token --raw
|
|
17
20
|
tela context current --json
|
|
@@ -19,14 +22,15 @@ tela context list --json
|
|
|
19
22
|
tela context show <context-id> --json
|
|
20
23
|
tela context use <context-id>
|
|
21
24
|
tela env list --json
|
|
22
|
-
tela update --json
|
|
23
|
-
tela
|
|
24
|
-
tela
|
|
25
|
-
tela
|
|
26
|
-
tela docs
|
|
27
|
-
tela
|
|
28
|
-
tela
|
|
29
|
-
tela
|
|
25
|
+
tela service update --json
|
|
26
|
+
tela service list --json
|
|
27
|
+
tela service show <slug> --json
|
|
28
|
+
tela service api <slug> <METHOD> <PATH> [args...] --service-env <slug> --body <json> --pretty
|
|
29
|
+
tela service docs endpoints <slug> --pretty
|
|
30
|
+
tela service docs reference <slug> [METHOD PATH|file-path] --pretty
|
|
31
|
+
tela service docs guide <slug> [path]
|
|
32
|
+
tela service env list <slug> --pretty
|
|
33
|
+
tela service env use <slug> <environment>
|
|
30
34
|
tela doctor auth --json
|
|
31
35
|
tela agent sync [repo] --current --all --dry-run --json --verbose
|
|
32
36
|
tela agent run --input <name=path>... --plain --json --verbose
|
|
@@ -34,16 +38,15 @@ tela agent push --message <text> --claude --manual --dry-run --json --verbose
|
|
|
34
38
|
tela agent feedback --list --apply <all|select> --json --verbose
|
|
35
39
|
```
|
|
36
40
|
|
|
37
|
-
`
|
|
38
|
-
|
|
39
|
-
printing a raw token.
|
|
40
|
-
Dock-first workflows.
|
|
41
|
+
`auth login` uses device flow and creates or updates a context backed by the
|
|
42
|
+
same Keychain credential adapter as Dock. `auth token` may refresh that session
|
|
43
|
+
before returning metadata or printing a raw token.
|
|
41
44
|
|
|
42
|
-
The
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
the
|
|
46
|
-
|
|
45
|
+
The top-level `api`, `docs`, `update`, `whoami`, and `token` aliases on `tela`
|
|
46
|
+
remain available during migration. Service catalog and per-service environment
|
|
47
|
+
defaults live in validated `TELA_HOME/inventory.json`, with a dual-read path for
|
|
48
|
+
the former `ingredients.json` files. Credential material continues to come from
|
|
49
|
+
the selected Tela context.
|
|
47
50
|
|
|
48
51
|
## Development
|
|
49
52
|
|
package/dist/commands/auth.d.ts
CHANGED
|
@@ -1,2 +1,10 @@
|
|
|
1
1
|
import type { CliIo, GlobalOptions } from '../output';
|
|
2
2
|
export declare function runAuthCommand(args: string[], options: GlobalOptions, io: CliIo): Promise<number>;
|
|
3
|
+
export declare function formatDeviceFlowInstructions(input: {
|
|
4
|
+
userCode: string;
|
|
5
|
+
verificationUriComplete: string;
|
|
6
|
+
deviceCode: string;
|
|
7
|
+
environmentId: string;
|
|
8
|
+
authUrl?: string;
|
|
9
|
+
contextId?: string;
|
|
10
|
+
}): string;
|
package/dist/commands/auth.js
CHANGED
|
@@ -1,6 +1,15 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
2
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
6
|
exports.runAuthCommand = runAuthCommand;
|
|
7
|
+
exports.formatDeviceFlowInstructions = formatDeviceFlowInstructions;
|
|
8
|
+
const node_child_process_1 = require("node:child_process");
|
|
9
|
+
const promises_1 = require("node:fs/promises");
|
|
10
|
+
const node_os_1 = require("node:os");
|
|
11
|
+
const node_path_1 = require("node:path");
|
|
12
|
+
const node_process_1 = __importDefault(require("node:process"));
|
|
4
13
|
const tela_local_config_1 = require("@meistrari/tela-local-config");
|
|
5
14
|
const credentials_1 = require("../credentials");
|
|
6
15
|
const output_1 = require("../output");
|
|
@@ -10,11 +19,226 @@ async function runAuthCommand(args, options, io) {
|
|
|
10
19
|
writeAuthHelp(io);
|
|
11
20
|
return 0;
|
|
12
21
|
}
|
|
13
|
-
if (action === 'token')
|
|
14
|
-
|
|
22
|
+
if (action === 'token') {
|
|
23
|
+
if (rest[0] === 'list')
|
|
24
|
+
return await authTokenList(options, io);
|
|
25
|
+
else
|
|
26
|
+
return await authToken(rest, options, io);
|
|
27
|
+
}
|
|
28
|
+
if (action === 'login')
|
|
29
|
+
return await authLogin(rest, options, io);
|
|
30
|
+
if (action === 'logout')
|
|
31
|
+
return await authLogout(rest, options, io);
|
|
32
|
+
if (action === 'whoami')
|
|
33
|
+
return await authWhoami(rest, options, io);
|
|
15
34
|
(0, output_1.writeError)(io, `Unknown auth command: ${action}`);
|
|
16
35
|
return 1;
|
|
17
36
|
}
|
|
37
|
+
async function authLogin(args, options, io) {
|
|
38
|
+
const parsed = parseLoginOptions(args);
|
|
39
|
+
if ('error' in parsed) {
|
|
40
|
+
(0, output_1.writeError)(io, parsed.error);
|
|
41
|
+
return 1;
|
|
42
|
+
}
|
|
43
|
+
try {
|
|
44
|
+
const config = await (0, tela_local_config_1.loadConfig)();
|
|
45
|
+
const context = parsed.contextId ? (0, tela_local_config_1.resolveContext)(config, { contextId: parsed.contextId }) : null;
|
|
46
|
+
const environmentId = context?.context.environmentId ?? parsed.environmentId ?? 'production';
|
|
47
|
+
const environment = config.environments[environmentId];
|
|
48
|
+
if (!environment)
|
|
49
|
+
throw new Error(`Unknown Tela environment: ${environmentId}`);
|
|
50
|
+
const requesterApplicationId = environment.authApplication?.requesterApplicationId;
|
|
51
|
+
const targetApplicationId = environment.authApplication?.targetApplicationId;
|
|
52
|
+
if (!requesterApplicationId || !targetApplicationId) {
|
|
53
|
+
throw new Error(`Environment '${environmentId}' does not define auth application IDs. Configure them before logging in.`);
|
|
54
|
+
}
|
|
55
|
+
// auth-cli is ESM-only with no `require` export condition, so this
|
|
56
|
+
// CJS bundle can only reach it through a dynamic import.
|
|
57
|
+
const { DeviceFlow } = await import('@meistrari/auth-cli');
|
|
58
|
+
const storage = (0, tela_local_config_1.createTelaTokenStorage)();
|
|
59
|
+
const flowOptions = {
|
|
60
|
+
apiUrl: parsed.authUrl ?? environment.authApiUrl,
|
|
61
|
+
requesterApplicationId,
|
|
62
|
+
targetApplicationId,
|
|
63
|
+
storage,
|
|
64
|
+
};
|
|
65
|
+
const loginContext = {
|
|
66
|
+
environmentId,
|
|
67
|
+
contextId: context?.id,
|
|
68
|
+
// Both paths below issue the device code up front, which makes the
|
|
69
|
+
// SDK skip its cache branch anyway. Say so rather than relying on it.
|
|
70
|
+
cache: false,
|
|
71
|
+
};
|
|
72
|
+
if (parsed.deviceCode) {
|
|
73
|
+
const resumed = DeviceFlow.resume(flowOptions, { deviceCode: parsed.deviceCode });
|
|
74
|
+
const tokens = await resumed.authenticate(loginContext);
|
|
75
|
+
return reportLogin(tokens, storage, environmentId, options, io);
|
|
76
|
+
}
|
|
77
|
+
const flow = new DeviceFlow(flowOptions);
|
|
78
|
+
const init = await flow.init();
|
|
79
|
+
if (!parsed.interactive) {
|
|
80
|
+
(0, output_1.writeLine)(io, formatDeviceFlowInstructions({
|
|
81
|
+
userCode: init.userCode,
|
|
82
|
+
verificationUriComplete: init.verificationUriComplete,
|
|
83
|
+
deviceCode: init.deviceCode,
|
|
84
|
+
environmentId,
|
|
85
|
+
authUrl: parsed.authUrl,
|
|
86
|
+
contextId: parsed.contextId,
|
|
87
|
+
}));
|
|
88
|
+
return 0;
|
|
89
|
+
}
|
|
90
|
+
const verificationUrl = resolveSafeVerificationUrl(init.verificationUriComplete, {
|
|
91
|
+
allowLoopbackHttp: environment.kind === 'local',
|
|
92
|
+
});
|
|
93
|
+
if (!verificationUrl)
|
|
94
|
+
throw new Error('Tela auth returned an unsafe verification URL.');
|
|
95
|
+
(0, output_1.writeLine)(io, `Open ${verificationUrl}`);
|
|
96
|
+
(0, output_1.writeLine)(io, `Code: ${init.userCode}`);
|
|
97
|
+
openExternal(verificationUrl);
|
|
98
|
+
const tokens = await flow.authenticate(loginContext);
|
|
99
|
+
return reportLogin(tokens, storage, environmentId, options, io);
|
|
100
|
+
}
|
|
101
|
+
catch (error) {
|
|
102
|
+
(0, output_1.writeError)(io, error instanceof Error ? error.message : String(error));
|
|
103
|
+
return 1;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
function reportLogin(tokens, storage, environmentId, options, io) {
|
|
107
|
+
const contextId = storage.resolvedContextId;
|
|
108
|
+
if (options.json) {
|
|
109
|
+
(0, output_1.writeJson)(io, {
|
|
110
|
+
authenticated: true,
|
|
111
|
+
contextId,
|
|
112
|
+
environmentId,
|
|
113
|
+
user: tokens.user,
|
|
114
|
+
organization: tokens.organization,
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
else {
|
|
118
|
+
(0, output_1.writeLine)(io, `Logged in as ${tokens.user.email}.`);
|
|
119
|
+
(0, output_1.writeLine)(io, `Active context: ${contextId}`);
|
|
120
|
+
}
|
|
121
|
+
return 0;
|
|
122
|
+
}
|
|
123
|
+
async function authLogout(args, options, io) {
|
|
124
|
+
let contextId;
|
|
125
|
+
let all = false;
|
|
126
|
+
for (let index = 0; index < args.length; index += 1) {
|
|
127
|
+
const arg = args[index];
|
|
128
|
+
if (arg === '--all') {
|
|
129
|
+
all = true;
|
|
130
|
+
continue;
|
|
131
|
+
}
|
|
132
|
+
if (arg === '--context') {
|
|
133
|
+
contextId = args[index + 1];
|
|
134
|
+
if (!contextId) {
|
|
135
|
+
(0, output_1.writeError)(io, 'Usage: tela auth logout [--context <context-id>|--all]');
|
|
136
|
+
return 1;
|
|
137
|
+
}
|
|
138
|
+
index += 1;
|
|
139
|
+
continue;
|
|
140
|
+
}
|
|
141
|
+
(0, output_1.writeError)(io, `Unknown auth logout option: ${arg}`);
|
|
142
|
+
return 1;
|
|
143
|
+
}
|
|
144
|
+
try {
|
|
145
|
+
const config = await (0, tela_local_config_1.loadConfig)();
|
|
146
|
+
const targets = all
|
|
147
|
+
? Object.entries(config.contexts)
|
|
148
|
+
: [[(0, tela_local_config_1.resolveContext)(config, { contextId }).id, (0, tela_local_config_1.resolveContext)(config, { contextId }).context]];
|
|
149
|
+
const credentials = (0, credentials_1.createCliCredentialAdapter)();
|
|
150
|
+
for (const [, context] of targets)
|
|
151
|
+
await credentials.delete(context.credentialRef);
|
|
152
|
+
if (options.json)
|
|
153
|
+
(0, output_1.writeJson)(io, { loggedOut: targets.map(([id]) => id) });
|
|
154
|
+
else
|
|
155
|
+
(0, output_1.writeLine)(io, `Logged out of ${targets.length} Tela context${targets.length === 1 ? '' : 's'}.`);
|
|
156
|
+
return 0;
|
|
157
|
+
}
|
|
158
|
+
catch (error) {
|
|
159
|
+
(0, output_1.writeError)(io, error instanceof Error ? error.message : String(error));
|
|
160
|
+
return 1;
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
async function authWhoami(args, options, io) {
|
|
164
|
+
const selector = parseContextSelector(args, 'whoami');
|
|
165
|
+
if ('error' in selector) {
|
|
166
|
+
(0, output_1.writeError)(io, selector.error);
|
|
167
|
+
return 1;
|
|
168
|
+
}
|
|
169
|
+
try {
|
|
170
|
+
const config = await (0, tela_local_config_1.loadConfig)();
|
|
171
|
+
const resolved = (0, tela_local_config_1.resolveContext)(config, selector);
|
|
172
|
+
const credential = await (0, credentials_1.createCliCredentialAdapter)().get(resolved.context.credentialRef);
|
|
173
|
+
if (!credential)
|
|
174
|
+
throw new Error(`Missing credential for Tela context ${resolved.id}`);
|
|
175
|
+
const raw = isRecord(credential.raw) ? credential.raw : {};
|
|
176
|
+
const payload = {
|
|
177
|
+
contextId: resolved.id,
|
|
178
|
+
environmentId: resolved.context.environmentId,
|
|
179
|
+
workspaceId: resolved.context.workspaceId,
|
|
180
|
+
accountEmail: credential.accountEmail ?? resolved.context.accountEmail,
|
|
181
|
+
user: raw.user ?? null,
|
|
182
|
+
organization: raw.organization ?? null,
|
|
183
|
+
};
|
|
184
|
+
if (options.json || args.includes('--pretty')) {
|
|
185
|
+
(0, output_1.writeJson)(io, payload);
|
|
186
|
+
}
|
|
187
|
+
else {
|
|
188
|
+
(0, output_1.writeLine)(io, payload.accountEmail ?? 'Authenticated');
|
|
189
|
+
(0, output_1.writeLine)(io, `Context: ${payload.contextId}`);
|
|
190
|
+
(0, output_1.writeLine)(io, `Workspace: ${payload.workspaceId}`);
|
|
191
|
+
}
|
|
192
|
+
return 0;
|
|
193
|
+
}
|
|
194
|
+
catch (error) {
|
|
195
|
+
(0, output_1.writeError)(io, error instanceof Error ? error.message : String(error));
|
|
196
|
+
return 1;
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
async function authTokenList(options, io) {
|
|
200
|
+
const config = await (0, tela_local_config_1.loadConfig)();
|
|
201
|
+
const publicConfig = await (0, tela_local_config_1.toPublicConfig)(config, (0, credentials_1.createCliCredentialAdapter)());
|
|
202
|
+
const tokens = Object.values(publicConfig.contexts).map(context => ({
|
|
203
|
+
contextId: context.id,
|
|
204
|
+
environmentId: context.environmentId,
|
|
205
|
+
accountEmail: context.accountEmail,
|
|
206
|
+
credential: context.credential,
|
|
207
|
+
}));
|
|
208
|
+
const legacyCredentials = await discoverLegacyTelactlCredentials();
|
|
209
|
+
if (options.json) {
|
|
210
|
+
(0, output_1.writeJson)(io, { tokens, legacyCredentials });
|
|
211
|
+
}
|
|
212
|
+
else if (tokens.length === 0 && legacyCredentials.length === 0) {
|
|
213
|
+
(0, output_1.writeLine)(io, 'No Tela credentials configured.');
|
|
214
|
+
}
|
|
215
|
+
else {
|
|
216
|
+
for (const token of tokens)
|
|
217
|
+
(0, output_1.writeLine)(io, `${token.contextId} ${token.accountEmail ?? '-'} ${token.credential.ok ? 'valid' : token.credential.problem ?? 'unknown'}`);
|
|
218
|
+
for (const legacy of legacyCredentials)
|
|
219
|
+
(0, output_1.writeLine)(io, `legacy:${legacy.environmentId} discovered (not imported) ${legacy.path}`);
|
|
220
|
+
}
|
|
221
|
+
return 0;
|
|
222
|
+
}
|
|
223
|
+
async function discoverLegacyTelactlCredentials() {
|
|
224
|
+
const root = (0, node_path_1.join)((0, node_os_1.homedir)(), '.telactl');
|
|
225
|
+
try {
|
|
226
|
+
const names = await (0, promises_1.readdir)(root);
|
|
227
|
+
return names
|
|
228
|
+
.filter(name => name.startsWith('credentials.') && name.endsWith('.json'))
|
|
229
|
+
.map(name => ({
|
|
230
|
+
environmentId: name.slice('credentials.'.length, -'.json'.length),
|
|
231
|
+
path: (0, node_path_1.join)(root, name),
|
|
232
|
+
}))
|
|
233
|
+
.filter(item => item.environmentId.length > 0)
|
|
234
|
+
.sort((left, right) => left.environmentId.localeCompare(right.environmentId));
|
|
235
|
+
}
|
|
236
|
+
catch (error) {
|
|
237
|
+
if (isNotFound(error))
|
|
238
|
+
return [];
|
|
239
|
+
throw error;
|
|
240
|
+
}
|
|
241
|
+
}
|
|
18
242
|
async function authToken(args, options, io) {
|
|
19
243
|
const parsed = parseTokenOptions(args);
|
|
20
244
|
if ('error' in parsed) {
|
|
@@ -60,7 +284,10 @@ async function authToken(args, options, io) {
|
|
|
60
284
|
}
|
|
61
285
|
async function resolveToken(options) {
|
|
62
286
|
const config = await (0, tela_local_config_1.loadConfig)();
|
|
63
|
-
const resolved = (0, tela_local_config_1.resolveContext)(config, {
|
|
287
|
+
const resolved = (0, tela_local_config_1.resolveContext)(config, {
|
|
288
|
+
contextId: options.contextId,
|
|
289
|
+
environmentId: options.environmentId,
|
|
290
|
+
});
|
|
64
291
|
const credentials = (0, credentials_1.createCliCredentialAdapter)();
|
|
65
292
|
const credentialRef = resolved.context.credentialRef;
|
|
66
293
|
const originalCredential = await credentials.get(credentialRef);
|
|
@@ -109,6 +336,14 @@ function parseTokenOptions(args) {
|
|
|
109
336
|
index += 1;
|
|
110
337
|
continue;
|
|
111
338
|
}
|
|
339
|
+
if (arg === '--environment' || arg === '--auth-env') {
|
|
340
|
+
const value = args[index + 1];
|
|
341
|
+
if (!value)
|
|
342
|
+
return { error: 'Usage: tela auth token --environment <environment-id>' };
|
|
343
|
+
options.environmentId = value;
|
|
344
|
+
index += 1;
|
|
345
|
+
continue;
|
|
346
|
+
}
|
|
112
347
|
if (arg === '--kind') {
|
|
113
348
|
const value = args[index + 1];
|
|
114
349
|
if (value !== 'access-token' && value !== 'data-token') {
|
|
@@ -126,6 +361,133 @@ function parseTokenOptions(args) {
|
|
|
126
361
|
}
|
|
127
362
|
return options;
|
|
128
363
|
}
|
|
364
|
+
function parseLoginOptions(args) {
|
|
365
|
+
const parsed = {
|
|
366
|
+
interactive: Boolean(node_process_1.default.stdin.isTTY),
|
|
367
|
+
};
|
|
368
|
+
for (let index = 0; index < args.length; index += 1) {
|
|
369
|
+
const arg = args[index];
|
|
370
|
+
if (arg === '--interactive') {
|
|
371
|
+
parsed.interactive = true;
|
|
372
|
+
continue;
|
|
373
|
+
}
|
|
374
|
+
if (arg === '--no-interactive') {
|
|
375
|
+
parsed.interactive = false;
|
|
376
|
+
continue;
|
|
377
|
+
}
|
|
378
|
+
if (arg === '--context' || arg === '--environment' || arg === '--auth-env' || arg === '--auth-url' || arg === '--device-code') {
|
|
379
|
+
const value = args[index + 1];
|
|
380
|
+
if (!value)
|
|
381
|
+
return { error: `Missing value for ${arg}.` };
|
|
382
|
+
if (arg === '--context')
|
|
383
|
+
parsed.contextId = value;
|
|
384
|
+
else if (arg === '--environment' || arg === '--auth-env')
|
|
385
|
+
parsed.environmentId = value;
|
|
386
|
+
else if (arg === '--auth-url')
|
|
387
|
+
parsed.authUrl = value;
|
|
388
|
+
else
|
|
389
|
+
parsed.deviceCode = value;
|
|
390
|
+
index += 1;
|
|
391
|
+
continue;
|
|
392
|
+
}
|
|
393
|
+
return { error: `Unknown auth login option: ${arg}` };
|
|
394
|
+
}
|
|
395
|
+
return parsed;
|
|
396
|
+
}
|
|
397
|
+
function parseContextSelector(args, action) {
|
|
398
|
+
const selector = {};
|
|
399
|
+
for (let index = 0; index < args.length; index += 1) {
|
|
400
|
+
const arg = args[index];
|
|
401
|
+
if (arg === '--pretty' || arg === '-p' || arg === '--interactive' || arg === '--no-interactive')
|
|
402
|
+
continue;
|
|
403
|
+
if (arg === '--context') {
|
|
404
|
+
selector.contextId = args[index + 1];
|
|
405
|
+
if (!selector.contextId)
|
|
406
|
+
return { error: `Usage: tela auth ${action} [--context <context-id>]` };
|
|
407
|
+
index += 1;
|
|
408
|
+
continue;
|
|
409
|
+
}
|
|
410
|
+
if (arg === '--environment' || arg === '--auth-env') {
|
|
411
|
+
selector.environmentId = args[index + 1];
|
|
412
|
+
if (!selector.environmentId)
|
|
413
|
+
return { error: `Usage: tela auth ${action} [--environment <environment-id>]` };
|
|
414
|
+
index += 1;
|
|
415
|
+
continue;
|
|
416
|
+
}
|
|
417
|
+
if (arg === '--auth-url') {
|
|
418
|
+
if (!args[index + 1])
|
|
419
|
+
return { error: `Missing value for ${arg}.` };
|
|
420
|
+
index += 1;
|
|
421
|
+
continue;
|
|
422
|
+
}
|
|
423
|
+
return { error: `Unknown auth ${action} option: ${arg}` };
|
|
424
|
+
}
|
|
425
|
+
return selector;
|
|
426
|
+
}
|
|
427
|
+
function formatDeviceFlowInstructions(input) {
|
|
428
|
+
const environmentOption = input.environmentId === 'production'
|
|
429
|
+
? ''
|
|
430
|
+
: ` --environment ${shellArg(input.environmentId)}`;
|
|
431
|
+
const contextOption = input.contextId ? ` --context ${shellArg(input.contextId)}` : '';
|
|
432
|
+
const authUrlOption = input.authUrl ? ` --auth-url ${shellArg(input.authUrl)}` : '';
|
|
433
|
+
return [
|
|
434
|
+
'To sign in, open this URL and authorize access:',
|
|
435
|
+
` ${input.verificationUriComplete}`,
|
|
436
|
+
'',
|
|
437
|
+
'If asked for a code, enter:',
|
|
438
|
+
` ${input.userCode}`,
|
|
439
|
+
'',
|
|
440
|
+
'Then run:',
|
|
441
|
+
` tela auth login --device-code ${shellArg(input.deviceCode)}${environmentOption}${contextOption}${authUrlOption}`,
|
|
442
|
+
].join('\n');
|
|
443
|
+
}
|
|
444
|
+
function openExternal(url) {
|
|
445
|
+
const command = node_process_1.default.platform === 'darwin'
|
|
446
|
+
? 'open'
|
|
447
|
+
: node_process_1.default.platform === 'win32' ? 'rundll32' : 'xdg-open';
|
|
448
|
+
const args = node_process_1.default.platform === 'win32' ? ['url.dll,FileProtocolHandler', url] : [url];
|
|
449
|
+
const child = (0, node_child_process_1.spawn)(command, args, { detached: true, stdio: 'ignore' });
|
|
450
|
+
child.unref();
|
|
451
|
+
}
|
|
452
|
+
function resolveSafeVerificationUrl(rawUrl, { allowLoopbackHttp = false } = {}) {
|
|
453
|
+
const candidate = parseUrl(rawUrl);
|
|
454
|
+
if (!candidate || candidate.username || candidate.password)
|
|
455
|
+
return null;
|
|
456
|
+
if (candidate.protocol === 'https:')
|
|
457
|
+
return candidate.href;
|
|
458
|
+
if (candidate.protocol === 'http:' && allowLoopbackHttp && isLoopbackHostname(candidate.hostname))
|
|
459
|
+
return candidate.href;
|
|
460
|
+
return null;
|
|
461
|
+
}
|
|
462
|
+
function parseUrl(rawUrl) {
|
|
463
|
+
try {
|
|
464
|
+
return new URL(rawUrl);
|
|
465
|
+
}
|
|
466
|
+
catch {
|
|
467
|
+
return null;
|
|
468
|
+
}
|
|
469
|
+
}
|
|
470
|
+
function isLoopbackHostname(rawHostname) {
|
|
471
|
+
const hostname = rawHostname.toLowerCase().replace(/^\[|\]$/g, '');
|
|
472
|
+
return hostname === 'localhost'
|
|
473
|
+
|| hostname.endsWith('.localhost')
|
|
474
|
+
|| hostname === '::1'
|
|
475
|
+
|| /^127(?:\.\d{1,3}){3}$/.test(hostname);
|
|
476
|
+
}
|
|
477
|
+
function shellArg(value) {
|
|
478
|
+
return `'${value.replaceAll("'", "'\\''")}'`;
|
|
479
|
+
}
|
|
480
|
+
function isRecord(value) {
|
|
481
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
482
|
+
}
|
|
483
|
+
function isNotFound(error) {
|
|
484
|
+
return error !== null && typeof error === 'object' && 'code' in error && error.code === 'ENOENT';
|
|
485
|
+
}
|
|
129
486
|
function writeAuthHelp(io) {
|
|
130
|
-
(0, output_1.writeLine)(io, 'Usage: tela auth
|
|
487
|
+
(0, output_1.writeLine)(io, 'Usage: tela auth <command> [options]');
|
|
488
|
+
(0, output_1.writeLine)(io, ' login [--context <id>|--environment <id>] [--interactive|--no-interactive] [--device-code <code>]');
|
|
489
|
+
(0, output_1.writeLine)(io, ' logout [--context <id>|--all]');
|
|
490
|
+
(0, output_1.writeLine)(io, ' whoami [--context <id>] [--json]');
|
|
491
|
+
(0, output_1.writeLine)(io, ' token [--context <id>|--environment <id>] [--kind access-token|data-token] [--raw] [--json]');
|
|
492
|
+
(0, output_1.writeLine)(io, ' token list [--json]');
|
|
131
493
|
}
|
|
@@ -1,38 +1,10 @@
|
|
|
1
|
+
import type { StoredCredential, TelaServiceIngredient } from '@meistrari/tela-local-config';
|
|
2
|
+
import { extractGitHubFilePath, joinUrl, parseHttpieArg, resolveGuidePath } from '@meistrari/tela-pantry';
|
|
1
3
|
import type { CliIo, GlobalOptions } from '../output';
|
|
2
|
-
export
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
export type CachedIngredient = {
|
|
7
|
-
slug: string;
|
|
8
|
-
name: string;
|
|
9
|
-
description: string;
|
|
10
|
-
type: 'api' | 'library' | 'skill';
|
|
11
|
-
status: string;
|
|
12
|
-
environments: CachedEnvironment[];
|
|
13
|
-
};
|
|
14
|
-
type ParsedArg = {
|
|
15
|
-
kind: 'query';
|
|
16
|
-
key: string;
|
|
17
|
-
value: string;
|
|
18
|
-
} | {
|
|
19
|
-
kind: 'header';
|
|
20
|
-
key: string;
|
|
21
|
-
value: string;
|
|
22
|
-
} | {
|
|
23
|
-
kind: 'field';
|
|
24
|
-
key: string;
|
|
25
|
-
value: string;
|
|
26
|
-
} | {
|
|
27
|
-
kind: 'rawField';
|
|
28
|
-
key: string;
|
|
29
|
-
value: string;
|
|
30
|
-
};
|
|
4
|
+
export { extractGitHubFilePath, joinUrl, parseHttpieArg, resolveGuidePath, };
|
|
5
|
+
export type CachedEnvironment = TelaServiceIngredient['environments'][number];
|
|
6
|
+
export type CachedIngredient = TelaServiceIngredient;
|
|
7
|
+
export declare function runServiceCommand(args: string[], options: GlobalOptions, io: CliIo): Promise<number>;
|
|
31
8
|
export declare function runTelactlCommand(command: string, args: string[], options: GlobalOptions, io: CliIo): Promise<number>;
|
|
32
9
|
export declare function runIngredientEnvCommand(args: string[], options: GlobalOptions, io: CliIo): Promise<number | null>;
|
|
33
|
-
export declare function fetchIngredientCatalog(
|
|
34
|
-
export declare function joinUrl(base: string, routePath: string): string;
|
|
35
|
-
export declare function parseHttpieArg(arg: string): ParsedArg | null;
|
|
36
|
-
export declare function extractGitHubFilePath(url: string): string | null;
|
|
37
|
-
export declare function resolveGuidePath(rootFilePath: string, providedPath?: string): string;
|
|
38
|
-
export {};
|
|
10
|
+
export declare function fetchIngredientCatalog(credential: StoredCredential, baseUrl?: string): Promise<TelaServiceIngredient[]>;
|