@tarout/cli 0.2.2 → 0.4.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 CHANGED
@@ -39,6 +39,28 @@ tarout deploy --wait --source upload
39
39
  # The first deploy prompts to create or link an app, and to create detected resources.
40
40
  ```
41
41
 
42
+ ## Call any API (`tarout call`)
43
+
44
+ Beyond the curated commands, `tarout call` reaches **every** platform procedure
45
+ directly — the same control surface exposed via REST and MCP:
46
+
47
+ ```bash
48
+ tarout call --list # discover all callable procedures + type
49
+ tarout call application.create --input '{"name":"my-app"}' --json
50
+ tarout call deployment.all --input '{"applicationId":"app_123"}'
51
+ ```
52
+
53
+ ## MCP (agent access)
54
+
55
+ Connect Claude Desktop / Cursor to Tarout via the bundled `tarout-mcp` bridge:
56
+
57
+ ```json
58
+ { "mcpServers": { "tarout": { "command": "tarout-mcp" } } }
59
+ ```
60
+
61
+ Hosted agents can hit the Streamable-HTTP endpoint `/api/mcp` directly with an
62
+ `x-api-key` header. See [`docs/MCP.md`](../docs/MCP.md).
63
+
42
64
  ## Commands
43
65
 
44
66
  ### Authentication
package/bin/tarout-mcp ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+
3
+ import('../dist/mcp/stdio.js');
@@ -2,8 +2,9 @@ import {
2
2
  createApiClient,
3
3
  getApiClient,
4
4
  resetApiClient
5
- } from "./chunk-7YS2WBLB.js";
6
- import "./chunk-KL3JNPAY.js";
5
+ } from "./chunk-Y6TWR3XZ.js";
6
+ import "./chunk-5DAFGMBH.js";
7
+ import "./chunk-K7JK5HIL.js";
7
8
  export {
8
9
  createApiClient,
9
10
  getApiClient,
@@ -0,0 +1,137 @@
1
+ // src/lib/config.ts
2
+ import Conf from "conf";
3
+ import {
4
+ chmodSync,
5
+ existsSync,
6
+ mkdirSync,
7
+ readFileSync,
8
+ rmSync,
9
+ writeFileSync
10
+ } from "fs";
11
+ import { join } from "path";
12
+ var config = new Conf({
13
+ projectName: "tarout",
14
+ configFileMode: 384,
15
+ defaults: {
16
+ currentProfile: "default",
17
+ profiles: {}
18
+ }
19
+ });
20
+ function getConfig() {
21
+ return config.store;
22
+ }
23
+ function getCurrentProfile() {
24
+ const cfg = getConfig();
25
+ return cfg.profiles[cfg.currentProfile] || null;
26
+ }
27
+ function setProfile(name, profile) {
28
+ config.set(`profiles.${name}`, profile);
29
+ }
30
+ function setCurrentProfile(name) {
31
+ config.set("currentProfile", name);
32
+ }
33
+ function clearConfig() {
34
+ config.clear();
35
+ }
36
+ function isLoggedIn() {
37
+ const profile = getCurrentProfile();
38
+ return profile !== null && !!profile.token || !!process.env.TAROUT_TOKEN;
39
+ }
40
+ function getToken() {
41
+ const profile = getCurrentProfile();
42
+ return profile?.token || process.env.TAROUT_TOKEN || null;
43
+ }
44
+ function getApiUrl() {
45
+ const profile = getCurrentProfile();
46
+ return profile?.apiUrl || process.env.TAROUT_API_URL || "https://tarout.sa";
47
+ }
48
+ function updateProfile(updates) {
49
+ const cfg = getConfig();
50
+ const currentProfileName = cfg.currentProfile;
51
+ const currentProfile = cfg.profiles[currentProfileName];
52
+ if (currentProfile) {
53
+ config.set(`profiles.${currentProfileName}`, {
54
+ ...currentProfile,
55
+ ...updates
56
+ });
57
+ }
58
+ }
59
+ var PROJECT_CONFIG_DIR = ".tarout";
60
+ var PROJECT_CONFIG_FILE = "project.json";
61
+ function chmodIfSupported(path, mode) {
62
+ try {
63
+ chmodSync(path, mode);
64
+ } catch {
65
+ }
66
+ }
67
+ function getProjectConfigDir(basePath) {
68
+ const base = basePath || process.cwd();
69
+ return join(base, PROJECT_CONFIG_DIR);
70
+ }
71
+ function getProjectConfigPath(basePath) {
72
+ return join(getProjectConfigDir(basePath), PROJECT_CONFIG_FILE);
73
+ }
74
+ function isProjectLinked(basePath) {
75
+ return existsSync(getProjectConfigPath(basePath));
76
+ }
77
+ function getProjectConfig(basePath) {
78
+ const configPath = getProjectConfigPath(basePath);
79
+ if (!existsSync(configPath)) {
80
+ return null;
81
+ }
82
+ try {
83
+ const content = readFileSync(configPath, "utf-8");
84
+ return JSON.parse(content);
85
+ } catch {
86
+ return null;
87
+ }
88
+ }
89
+ function setProjectConfig(config2, basePath) {
90
+ const configDir = getProjectConfigDir(basePath);
91
+ const configPath = getProjectConfigPath(basePath);
92
+ if (!existsSync(configDir)) {
93
+ mkdirSync(configDir, { recursive: true, mode: 448 });
94
+ }
95
+ chmodIfSupported(configDir, 448);
96
+ writeFileSync(configPath, JSON.stringify(config2, null, 2), {
97
+ encoding: "utf-8",
98
+ mode: 384
99
+ });
100
+ chmodIfSupported(configPath, 384);
101
+ const gitignorePath = join(configDir, ".gitignore");
102
+ if (!existsSync(gitignorePath)) {
103
+ writeFileSync(
104
+ gitignorePath,
105
+ "# Ignore local tarout config\n*\n!.gitignore\n",
106
+ { encoding: "utf-8", mode: 384 }
107
+ );
108
+ chmodIfSupported(gitignorePath, 384);
109
+ }
110
+ }
111
+ function removeProjectConfig(basePath) {
112
+ const configDir = getProjectConfigDir(basePath);
113
+ if (!existsSync(configDir)) {
114
+ return false;
115
+ }
116
+ try {
117
+ rmSync(configDir, { recursive: true, force: true });
118
+ return true;
119
+ } catch {
120
+ return false;
121
+ }
122
+ }
123
+
124
+ export {
125
+ getCurrentProfile,
126
+ setProfile,
127
+ setCurrentProfile,
128
+ clearConfig,
129
+ isLoggedIn,
130
+ getToken,
131
+ getApiUrl,
132
+ updateProfile,
133
+ isProjectLinked,
134
+ getProjectConfig,
135
+ setProjectConfig,
136
+ removeProjectConfig
137
+ };
@@ -4,7 +4,7 @@ import {
4
4
  isJsonMode,
5
5
  isNonInteractiveMode,
6
6
  outputNeedsInput
7
- } from "./chunk-KL3JNPAY.js";
7
+ } from "./chunk-K7JK5HIL.js";
8
8
 
9
9
  // src/utils/prompts.ts
10
10
  import inquirer from "inquirer";
@@ -13,7 +13,12 @@ var ExitCode = {
13
13
  // Deployment-specific exit codes
14
14
  DEPLOYMENT_FAILED: 10,
15
15
  DEPLOYMENT_TIMEOUT: 11,
16
- BUILD_FAILED: 12
16
+ BUILD_FAILED: 12,
17
+ // A hosted checkout is still PENDING (not paid yet, not failed). The agent
18
+ // should resume polling (`tarout billing wait <orderId>`) or surface the
19
+ // payment URL to a human — distinct from GENERAL_ERROR so a resumable
20
+ // checkout isn't treated as a hard failure.
21
+ CHECKOUT_PENDING: 13
17
22
  };
18
23
  function exit(code) {
19
24
  process.exit(code);
@@ -1,3 +1,8 @@
1
+ import {
2
+ getApiUrl,
3
+ getToken,
4
+ isLoggedIn
5
+ } from "./chunk-5DAFGMBH.js";
1
6
  import {
2
7
  ExitCode,
3
8
  error,
@@ -5,135 +10,12 @@ import {
5
10
  isJsonMode,
6
11
  jsonError,
7
12
  outputJson
8
- } from "./chunk-KL3JNPAY.js";
13
+ } from "./chunk-K7JK5HIL.js";
9
14
 
10
15
  // src/lib/api.ts
11
16
  import { createTRPCProxyClient, httpBatchLink } from "@trpc/client";
12
17
  import superjson from "superjson";
13
18
 
14
- // src/lib/config.ts
15
- import Conf from "conf";
16
- import {
17
- chmodSync,
18
- existsSync,
19
- mkdirSync,
20
- readFileSync,
21
- rmSync,
22
- writeFileSync
23
- } from "fs";
24
- import { join } from "path";
25
- var config = new Conf({
26
- projectName: "tarout",
27
- configFileMode: 384,
28
- defaults: {
29
- currentProfile: "default",
30
- profiles: {}
31
- }
32
- });
33
- function getConfig() {
34
- return config.store;
35
- }
36
- function getCurrentProfile() {
37
- const cfg = getConfig();
38
- return cfg.profiles[cfg.currentProfile] || null;
39
- }
40
- function setProfile(name, profile) {
41
- config.set(`profiles.${name}`, profile);
42
- }
43
- function setCurrentProfile(name) {
44
- config.set("currentProfile", name);
45
- }
46
- function clearConfig() {
47
- config.clear();
48
- }
49
- function isLoggedIn() {
50
- const profile = getCurrentProfile();
51
- return profile !== null && !!profile.token || !!process.env.TAROUT_TOKEN;
52
- }
53
- function getToken() {
54
- const profile = getCurrentProfile();
55
- return profile?.token || process.env.TAROUT_TOKEN || null;
56
- }
57
- function getApiUrl() {
58
- const profile = getCurrentProfile();
59
- return profile?.apiUrl || "https://tarout.sa";
60
- }
61
- function updateProfile(updates) {
62
- const cfg = getConfig();
63
- const currentProfileName = cfg.currentProfile;
64
- const currentProfile = cfg.profiles[currentProfileName];
65
- if (currentProfile) {
66
- config.set(`profiles.${currentProfileName}`, {
67
- ...currentProfile,
68
- ...updates
69
- });
70
- }
71
- }
72
- var PROJECT_CONFIG_DIR = ".tarout";
73
- var PROJECT_CONFIG_FILE = "project.json";
74
- function chmodIfSupported(path, mode) {
75
- try {
76
- chmodSync(path, mode);
77
- } catch {
78
- }
79
- }
80
- function getProjectConfigDir(basePath) {
81
- const base = basePath || process.cwd();
82
- return join(base, PROJECT_CONFIG_DIR);
83
- }
84
- function getProjectConfigPath(basePath) {
85
- return join(getProjectConfigDir(basePath), PROJECT_CONFIG_FILE);
86
- }
87
- function isProjectLinked(basePath) {
88
- return existsSync(getProjectConfigPath(basePath));
89
- }
90
- function getProjectConfig(basePath) {
91
- const configPath = getProjectConfigPath(basePath);
92
- if (!existsSync(configPath)) {
93
- return null;
94
- }
95
- try {
96
- const content = readFileSync(configPath, "utf-8");
97
- return JSON.parse(content);
98
- } catch {
99
- return null;
100
- }
101
- }
102
- function setProjectConfig(config2, basePath) {
103
- const configDir = getProjectConfigDir(basePath);
104
- const configPath = getProjectConfigPath(basePath);
105
- if (!existsSync(configDir)) {
106
- mkdirSync(configDir, { recursive: true, mode: 448 });
107
- }
108
- chmodIfSupported(configDir, 448);
109
- writeFileSync(configPath, JSON.stringify(config2, null, 2), {
110
- encoding: "utf-8",
111
- mode: 384
112
- });
113
- chmodIfSupported(configPath, 384);
114
- const gitignorePath = join(configDir, ".gitignore");
115
- if (!existsSync(gitignorePath)) {
116
- writeFileSync(
117
- gitignorePath,
118
- "# Ignore local tarout config\n*\n!.gitignore\n",
119
- { encoding: "utf-8", mode: 384 }
120
- );
121
- chmodIfSupported(gitignorePath, 384);
122
- }
123
- }
124
- function removeProjectConfig(basePath) {
125
- const configDir = getProjectConfigDir(basePath);
126
- if (!existsSync(configDir)) {
127
- return false;
128
- }
129
- try {
130
- rmSync(configDir, { recursive: true, force: true });
131
- return true;
132
- } catch {
133
- return false;
134
- }
135
- }
136
-
137
19
  // src/lib/errors.ts
138
20
  var CliError = class extends Error {
139
21
  constructor(message, code = ExitCode.GENERAL_ERROR, suggestions) {
@@ -640,18 +522,6 @@ function resetApiClient() {
640
522
  }
641
523
 
642
524
  export {
643
- getCurrentProfile,
644
- setProfile,
645
- setCurrentProfile,
646
- clearConfig,
647
- isLoggedIn,
648
- getToken,
649
- getApiUrl,
650
- updateProfile,
651
- isProjectLinked,
652
- getProjectConfig,
653
- setProjectConfig,
654
- removeProjectConfig,
655
525
  CliError,
656
526
  AuthError,
657
527
  NotFoundError,