@meistrari/tela-cli 0.2.0 → 0.3.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 +0 -1
- package/package.json +1 -1
- package/src/commands/metadata.ts +0 -1
- package/src/config.ts +1 -1
- package/src/ink/components.tsx +20 -18
- package/src/program.ts +56 -32
- package/src/ui.ts +2 -4
package/README.md
CHANGED
|
@@ -95,7 +95,6 @@ Examples:
|
|
|
95
95
|
|
|
96
96
|
- Human output is structured for terminal use with grouped summaries and next actions.
|
|
97
97
|
- `--json` is available on read-heavy flows and on `tela run` for the final execution envelope.
|
|
98
|
-
- `--silent-bark` disables bark audio during the interactive `tela setup` intro while keeping the visual intro.
|
|
99
98
|
|
|
100
99
|
## First run
|
|
101
100
|
|
package/package.json
CHANGED
package/src/commands/metadata.ts
CHANGED
|
@@ -204,7 +204,6 @@ export function renderReadmeMarkdown(): string {
|
|
|
204
204
|
lines.push('')
|
|
205
205
|
lines.push('- Human output is structured for terminal use with grouped summaries and next actions.')
|
|
206
206
|
lines.push('- `--json` is available on read-heavy flows and on `tela run` for the final execution envelope.')
|
|
207
|
-
lines.push('- `--silent-bark` disables bark audio during the interactive `tela setup` intro while keeping the visual intro.')
|
|
208
207
|
lines.push('')
|
|
209
208
|
lines.push('## First run')
|
|
210
209
|
lines.push('')
|
package/src/config.ts
CHANGED
|
@@ -45,7 +45,7 @@ export interface SetupEnvironmentConfig {
|
|
|
45
45
|
|
|
46
46
|
export const ENVIRONMENT_PRESETS: Record<Exclude<TelaEnvironment, 'custom'>, Omit<SetupEnvironmentConfig, 'environment'>> = {
|
|
47
47
|
production: {
|
|
48
|
-
agentApiUrl: 'https://agent-api.
|
|
48
|
+
agentApiUrl: 'https://agent-api-production-81c9.up.railway.app',
|
|
49
49
|
authApiUrl: 'https://auth.tela.com',
|
|
50
50
|
authDashboardUrl: 'https://accounts.tela.com',
|
|
51
51
|
telaApiUrl: 'https://api.tela.com',
|
package/src/ink/components.tsx
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React, { useEffect, useMemo, useState, type ReactNode } from 'react'
|
|
2
2
|
import { Box, Text } from 'ink'
|
|
3
|
-
import {
|
|
3
|
+
import { getTelaAsciiHeader } from '../ui.ts'
|
|
4
4
|
|
|
5
5
|
export interface AppFrameProps {
|
|
6
6
|
title: string
|
|
@@ -12,7 +12,7 @@ export interface AppFrameProps {
|
|
|
12
12
|
}
|
|
13
13
|
|
|
14
14
|
export function AppFrame(props: AppFrameProps): React.ReactElement {
|
|
15
|
-
const mascot =
|
|
15
|
+
const mascot = props.mascotRows
|
|
16
16
|
const header = useMemo(() => getTelaAsciiHeader(), [])
|
|
17
17
|
|
|
18
18
|
return (
|
|
@@ -29,22 +29,24 @@ export function AppFrame(props: AppFrameProps): React.ReactElement {
|
|
|
29
29
|
{props.subtitle ? <Text dimColor>{props.subtitle}</Text> : null}
|
|
30
30
|
{props.status ? <Text color="yellow">{props.status}</Text> : null}
|
|
31
31
|
</Box>
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
{row
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
{
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
32
|
+
{mascot ? (
|
|
33
|
+
<Box flexDirection="column" marginTop={1}>
|
|
34
|
+
{mascot.map((row, index) => (
|
|
35
|
+
<Box key={`mascot-${index}`} flexDirection="row">
|
|
36
|
+
{row.split('').map((cell, cellIndex) => {
|
|
37
|
+
const level = Number.parseInt(cell, 16)
|
|
38
|
+
const channel = Math.round((level / 15) * 255)
|
|
39
|
+
const colorValue = `#${channel.toString(16).padStart(2, '0').repeat(3)}`
|
|
40
|
+
return (
|
|
41
|
+
<Text key={`pixel-${index}-${cellIndex}`} backgroundColor={colorValue}>
|
|
42
|
+
{' '}
|
|
43
|
+
</Text>
|
|
44
|
+
)
|
|
45
|
+
})}
|
|
46
|
+
</Box>
|
|
47
|
+
))}
|
|
48
|
+
</Box>
|
|
49
|
+
) : null}
|
|
48
50
|
<Box flexDirection="column" marginTop={1}>
|
|
49
51
|
{props.children}
|
|
50
52
|
</Box>
|
package/src/program.ts
CHANGED
|
@@ -2,11 +2,6 @@ import { existsSync, mkdirSync, statSync } from 'node:fs'
|
|
|
2
2
|
import { basename, join } from 'node:path'
|
|
3
3
|
import React from 'react'
|
|
4
4
|
import { Command } from 'commander'
|
|
5
|
-
import {
|
|
6
|
-
createInkBarkSession,
|
|
7
|
-
shouldShowBarkIntro,
|
|
8
|
-
type BarkIntroSession,
|
|
9
|
-
} from './ink/bark.tsx'
|
|
10
5
|
import {
|
|
11
6
|
FeedbackClaudeHandoffScreen,
|
|
12
7
|
FeedbackOutcomeScreen,
|
|
@@ -144,7 +139,6 @@ interface CliDeps {
|
|
|
144
139
|
getDiffStatAgainstHead?: typeof getDiffStatAgainstHead
|
|
145
140
|
getStatusReport?: typeof getStatusReport
|
|
146
141
|
getDoctorReport?: typeof getDoctorReport
|
|
147
|
-
createInkBarkSession?: typeof createInkBarkSession
|
|
148
142
|
renderCommandScreen?: typeof renderCommandScreen
|
|
149
143
|
commandExists?: typeof commandExists
|
|
150
144
|
runInteractiveCommand?: typeof runInteractiveCommand
|
|
@@ -159,7 +153,6 @@ interface CliDeps {
|
|
|
159
153
|
interface GlobalCliOptions {
|
|
160
154
|
json?: boolean
|
|
161
155
|
verbose?: boolean
|
|
162
|
-
silentBark?: boolean
|
|
163
156
|
}
|
|
164
157
|
|
|
165
158
|
interface SyncCommandOptions extends GlobalCliOptions {
|
|
@@ -292,7 +285,6 @@ function renderRootHelp(program: Command): string {
|
|
|
292
285
|
section('Global flags', table(
|
|
293
286
|
['Flag', 'Description'],
|
|
294
287
|
[
|
|
295
|
-
['--silent-bark', 'Disable bark audio during the interactive `tela setup` intro'],
|
|
296
288
|
['--verbose', 'Include raw evidence for failures where available'],
|
|
297
289
|
['-h, --help', 'Show command help'],
|
|
298
290
|
],
|
|
@@ -343,25 +335,6 @@ function installCustomHelp(program: Command): void {
|
|
|
343
335
|
})
|
|
344
336
|
}
|
|
345
337
|
|
|
346
|
-
function createBarkSession(
|
|
347
|
-
deps: CliDeps,
|
|
348
|
-
options: GlobalCliOptions,
|
|
349
|
-
commandTitle: string,
|
|
350
|
-
): BarkIntroSession {
|
|
351
|
-
const createSession = deps.createInkBarkSession ?? createInkBarkSession
|
|
352
|
-
return createSession({
|
|
353
|
-
commandTitle,
|
|
354
|
-
enabled: shouldShowBarkIntro({
|
|
355
|
-
json: options.json,
|
|
356
|
-
stdinIsTTY: getStdinIsTTY(deps),
|
|
357
|
-
stdoutIsTTY: getStdoutIsTTY(deps),
|
|
358
|
-
}),
|
|
359
|
-
silentBark: options.silentBark,
|
|
360
|
-
env: process.env,
|
|
361
|
-
platform: process.platform,
|
|
362
|
-
})
|
|
363
|
-
}
|
|
364
|
-
|
|
365
338
|
function emitBootstrap(runtime: CommandRuntime, title: string, summary: string): void {
|
|
366
339
|
runtime.emit(bootstrapPane(title, summary, { decorate: runtime.decorate }))
|
|
367
340
|
}
|
|
@@ -532,8 +505,6 @@ function createMissingSetupOrganizationsError(workspaceTitle: string): ReturnTyp
|
|
|
532
505
|
|
|
533
506
|
async function runSetupInk(
|
|
534
507
|
deps: CliDeps = {},
|
|
535
|
-
options: GlobalCliOptions = {},
|
|
536
|
-
barkSession = createBarkSession(deps, options, 'Setup'),
|
|
537
508
|
): Promise<SetupScreenResult> {
|
|
538
509
|
const renderScreen = getRenderCommandScreen(deps)
|
|
539
510
|
const inspection = (deps.inspectSavedConfig ?? inspectSavedConfig)()
|
|
@@ -549,7 +520,6 @@ async function runSetupInk(
|
|
|
549
520
|
targetApplicationId: inspection.config?.targetApplicationId ?? '',
|
|
550
521
|
}
|
|
551
522
|
: resolveEnvironmentConfigForPreset(defaultEnvironment)
|
|
552
|
-
await barkSession.playOnce()
|
|
553
523
|
return await renderScreen<SetupScreenResult>((controller) => React.createElement(SetupScreen, {
|
|
554
524
|
controller,
|
|
555
525
|
currentConfigSummary: summarizeConfigInspection(inspection).split('\n'),
|
|
@@ -645,7 +615,7 @@ export async function runSetup(
|
|
|
645
615
|
options: GlobalCliOptions = {},
|
|
646
616
|
): Promise<SetupCommandResult> {
|
|
647
617
|
if (isInteractiveInkSession(deps, options)) {
|
|
648
|
-
return await runSetupInk(deps
|
|
618
|
+
return await runSetupInk(deps)
|
|
649
619
|
}
|
|
650
620
|
|
|
651
621
|
const prompts = getPromptModule(deps)
|
|
@@ -1889,6 +1859,53 @@ export async function runDoctor(
|
|
|
1889
1859
|
return report
|
|
1890
1860
|
}
|
|
1891
1861
|
|
|
1862
|
+
export interface ListRepositoriesResult {
|
|
1863
|
+
cloneRoot: string
|
|
1864
|
+
repositories: string[]
|
|
1865
|
+
}
|
|
1866
|
+
|
|
1867
|
+
export async function runListRepositories(
|
|
1868
|
+
deps: CliDeps = {},
|
|
1869
|
+
options: GlobalCliOptions = {},
|
|
1870
|
+
): Promise<ListRepositoriesResult> {
|
|
1871
|
+
const runtime = createRuntime(deps, options)
|
|
1872
|
+
const inspection = (deps.inspectSavedConfig ?? inspectSavedConfig)()
|
|
1873
|
+
const cloneRoot = inspection.config?.cloneRoot ?? getDefaultCloneRoot()
|
|
1874
|
+
const listRepos = deps.listCloneRootRepositories ?? listCloneRootRepositories
|
|
1875
|
+
const repositories = listRepos(cloneRoot)
|
|
1876
|
+
const result: ListRepositoriesResult = { cloneRoot, repositories }
|
|
1877
|
+
|
|
1878
|
+
if (options.json) {
|
|
1879
|
+
runtime.emitJson(result)
|
|
1880
|
+
return result
|
|
1881
|
+
}
|
|
1882
|
+
|
|
1883
|
+
emitBootstrap(runtime, 'Tela CLI', 'Workspace repositories under the configured clone root.')
|
|
1884
|
+
const decorate = runtime.decorate
|
|
1885
|
+
const body = repositories.length > 0
|
|
1886
|
+
? section('Repositories', bulletList(repositories), { decorate })
|
|
1887
|
+
: section('Repositories', [
|
|
1888
|
+
`No repositories found under ${cloneRoot}.`,
|
|
1889
|
+
'',
|
|
1890
|
+
'Next steps:',
|
|
1891
|
+
bulletList([
|
|
1892
|
+
'Run `tela setup` to configure the clone root.',
|
|
1893
|
+
'Run `tela sync <repo>` to clone a workspace repository.',
|
|
1894
|
+
]),
|
|
1895
|
+
], { decorate })
|
|
1896
|
+
|
|
1897
|
+
runtime.emit(joinBlocks([
|
|
1898
|
+
body,
|
|
1899
|
+
section('Clone root', cloneRoot, { decorate }),
|
|
1900
|
+
nextActions([
|
|
1901
|
+
'Run `tela sync <repo>` to clone or refresh a repository.',
|
|
1902
|
+
'Run `tela --help` to see all available commands.',
|
|
1903
|
+
], { decorate }),
|
|
1904
|
+
]))
|
|
1905
|
+
|
|
1906
|
+
return result
|
|
1907
|
+
}
|
|
1908
|
+
|
|
1892
1909
|
function addStandardReadOptions(command: Command): Command {
|
|
1893
1910
|
return command
|
|
1894
1911
|
.option('--json', 'emit machine-readable JSON')
|
|
@@ -1899,11 +1916,18 @@ export function createProgram(deps: CliDeps = {}): Command {
|
|
|
1899
1916
|
.name('tela')
|
|
1900
1917
|
.description('Tela CLI workspace and auth helper')
|
|
1901
1918
|
.showHelpAfterError()
|
|
1902
|
-
.option('--silent-bark', 'disable bark audio during the interactive tela setup intro')
|
|
1903
1919
|
.option('--verbose', 'include raw evidence on failures')
|
|
1904
1920
|
|
|
1905
1921
|
installCustomHelp(program)
|
|
1906
1922
|
|
|
1923
|
+
addStandardReadOptions(program).action(async (commandOptions: GlobalCliOptions) => {
|
|
1924
|
+
const globalOptions = program.opts<GlobalCliOptions>()
|
|
1925
|
+
await runListRepositories(deps, {
|
|
1926
|
+
...globalOptions,
|
|
1927
|
+
...commandOptions,
|
|
1928
|
+
})
|
|
1929
|
+
})
|
|
1930
|
+
|
|
1907
1931
|
program
|
|
1908
1932
|
.command('setup')
|
|
1909
1933
|
.description('Configure Tela CLI settings and complete device-flow authentication')
|
package/src/ui.ts
CHANGED
|
@@ -38,8 +38,8 @@ const TELA_ASCII_HEADER = [
|
|
|
38
38
|
'██ ██║ ╚══██╔══╝██╔════╝██║ ██╔══██╗',
|
|
39
39
|
'██ ██║ ██║ █████╗ ██║ ███████║',
|
|
40
40
|
'██ ██║ ██║ ██╔══╝ ██║ ██╔══██║',
|
|
41
|
-
'
|
|
42
|
-
'
|
|
41
|
+
'███████████║ ██║ ███████╗███████╗██║ ██║',
|
|
42
|
+
'╚══════════╝ ╚═╝ ╚══════╝╚══════╝╚═╝ ╚═╝',
|
|
43
43
|
] as const
|
|
44
44
|
|
|
45
45
|
const ASCII_PIXEL_RAMP = ' .,:-=+*#%@'
|
|
@@ -155,8 +155,6 @@ export function bootstrapPane(
|
|
|
155
155
|
'',
|
|
156
156
|
...TELA_ASCII_HEADER.map(line => renderAsciiHeaderLine(line, options)),
|
|
157
157
|
'',
|
|
158
|
-
...BOOTSTRAP_PIXEL_ROWS.map(row => renderPixelArtLine(row, options)),
|
|
159
|
-
'',
|
|
160
158
|
...linesOf(content),
|
|
161
159
|
],
|
|
162
160
|
options,
|