systemview 2.0.0 → 2.1.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.
@@ -1,81 +1,172 @@
1
- const fs = require("fs");
2
- const path = require("path");
3
1
  const { HttpClient, createClient } = require("systemlynx");
4
2
  const { createCookieHttpClient } = require("./cookieClient");
5
3
  const cookieHttpClient = createCookieHttpClient();
6
4
  const Client = createClient(cookieHttpClient);
7
5
  const log = require("./logger");
8
6
 
9
- async function probeService(url) {
10
- const connectionData = await HttpClient.request({ url });
11
- if (!connectionData.SystemLynxService) {
12
- throw new Error(`No SystemLynx service found at ${url}`);
13
- }
14
- const client = Client.createService(connectionData);
15
- const connection = await client.Plugin.getConnection();
16
- return connection; // { projectCode, serviceId, system, specList }
17
- }
18
-
19
- function readManifest(manifestFile) {
20
- if (!fs.existsSync(manifestFile)) return null;
7
+ async function getUiSvc(uiUrl) {
21
8
  try {
22
- return JSON.parse(fs.readFileSync(manifestFile, "utf8"));
9
+ const { SystemView } = await Client.loadService(`${uiUrl}/systemview/api`);
10
+ return SystemView;
23
11
  } catch {
24
12
  return null;
25
13
  }
26
14
  }
27
15
 
28
- function writeManifest(manifestFile, connection) {
29
- const manifest = readManifest(manifestFile) || { projectCode: connection.projectCode, services: [] };
30
- if (!manifest.services) manifest.services = [];
31
- const entry = { serviceId: connection.serviceId, system: connection.system, specList: connection.specList };
32
- const idx = manifest.services.findIndex((s) => s.serviceId === connection.serviceId);
33
- if (idx > -1) manifest.services[idx] = entry;
34
- else manifest.services.push(entry);
35
- manifest.projectCode = connection.projectCode;
36
- fs.writeFileSync(manifestFile, JSON.stringify(manifest, null, 2));
16
+ async function notifyUi(uiSvc, project) {
17
+ if (!uiSvc) return;
18
+ try {
19
+ await uiSvc.connect(project);
20
+ } catch {}
21
+ }
22
+
23
+ function serviceIdFromRoute(route) {
24
+ const segments = (route || "").split("/").filter(Boolean);
25
+ return [...segments].reverse().find((s) => s.toLowerCase() !== "api") || "Service";
37
26
  }
38
27
 
39
- module.exports = async function connectService(serviceId, url, { manifest: manifestPath } = {}) {
40
- const manifestFile = manifestPath || path.join(process.cwd(), "systemview.manifest.json");
28
+ function printSummary(entries) {
29
+ console.log("");
30
+ entries.forEach(({ projectCode, serviceId, url }) => {
31
+ log.plain(` ${projectCode} › ${serviceId}${url ? " " + url : ""}`);
32
+ });
33
+ console.log("");
34
+ }
41
35
 
42
- if (!url) {
43
- // Re-probe all services already in the manifest
44
- const manifest = readManifest(manifestFile);
45
- if (!manifest || !manifest.services || !manifest.services.length) {
46
- log.warn("No manifest found. Use: systemview connect <serviceId> <url>");
36
+ module.exports = async function connectService(target, { useManifest, force, connectedUrls, uiUrl } = {}) {
37
+ const uiSvc = await getUiSvc(uiUrl);
38
+
39
+ // connect (no args) connect to every service stored in UI
40
+ if (!target) {
41
+ if (!uiSvc) {
42
+ log.warn("SystemView UI not running. Start it first or provide a URL.");
43
+ return;
44
+ }
45
+ const projects = await uiSvc.getProjects();
46
+ const all = Object.entries(projects).flatMap(([pc, svcs]) =>
47
+ svcs.map((s) => ({ projectCode: pc, ...s }))
48
+ );
49
+ if (!all.length) {
50
+ log.warn("No services in UI store. Use: systemview connect <url>");
47
51
  return;
48
52
  }
49
- log.info(`Re-probing ${manifest.services.length} service(s)...`);
50
- for (const { serviceId: id, system } of manifest.services) {
53
+ log.info(`Connecting to ${all.length} stored service(s)...`);
54
+ const summary = [];
55
+ for (const { projectCode, serviceId, connectionData, serviceUrl } of all) {
56
+ const url = serviceUrl || (connectionData && connectionData.serviceUrl);
57
+ if (!url) continue;
51
58
  try {
52
- const connection = await probeService(system.connectionData.serviceUrl);
53
- writeManifest(manifestFile, connection);
54
- log.success(`${id} updated`);
59
+ if (force) {
60
+ await Client.loadService(url);
61
+ } else {
62
+ Client.createService(connectionData);
63
+ }
64
+ connectedUrls.add(url);
65
+ log.success(`${projectCode} › ${serviceId}`);
66
+ summary.push({ projectCode, serviceId, url });
55
67
  } catch (err) {
56
- log.error(`${id} failed: ${err.message}`);
68
+ log.error(`${serviceId} failed: ${err.message}`);
57
69
  }
58
70
  }
59
- printManifestSummary(readManifest(manifestFile));
71
+ printSummary(summary);
60
72
  return;
61
73
  }
62
74
 
63
- log.info(`Connecting to ${serviceId || "service"} @ ${url}...`);
75
+ const isUrl = /^https?:\/\//i.test(target);
76
+
77
+ // connect <projectCode> — look up from UI store
78
+ if (!isUrl) {
79
+ if (!uiSvc) {
80
+ log.warn("SystemView UI not running. Cannot look up project by code.");
81
+ return;
82
+ }
83
+ const services = await uiSvc.getServices(target);
84
+ if (!services || !services.length) {
85
+ log.warn(`No services found for project: ${target}`);
86
+ return;
87
+ }
88
+ log.info(`Connecting to ${services.length} service(s) for ${target}...`);
89
+ const summary = [];
90
+ for (const { serviceId, system } of services) {
91
+ const { serviceUrl } = system.connectionData;
92
+ try {
93
+ if (force) {
94
+ await Client.loadService(serviceUrl);
95
+ } else {
96
+ Client.createService(system.connectionData);
97
+ }
98
+ connectedUrls.add(serviceUrl);
99
+ log.success(`${target} › ${serviceId}`);
100
+ summary.push({ projectCode: target, serviceId, url: serviceUrl });
101
+ } catch (err) {
102
+ log.error(`${serviceId} failed: ${err.message}`);
103
+ }
104
+ }
105
+ printSummary(summary);
106
+ return;
107
+ }
108
+
109
+ // connect <url> [--manifest]
110
+ log.info(`Connecting to ${target}...`);
64
111
  try {
65
- const connection = await probeService(url);
66
- writeManifest(manifestFile, connection);
67
- printManifestSummary(readManifest(manifestFile));
112
+ if (useManifest) {
113
+ const svc = await Client.loadService(target);
114
+ let manifest = null;
115
+ try { manifest = await svc.Plugin.getManifest(); } catch {}
116
+ if (manifest && manifest.services && manifest.services.length) {
117
+ log.info(`Plugin manifest found: ${manifest.projectCode} (${manifest.services.length} service(s))`);
118
+ const summary = [];
119
+ for (const service of manifest.services) {
120
+ try {
121
+ Client.createService(service.system.connectionData);
122
+ connectedUrls.add(service.system.connectionData.serviceUrl);
123
+ await notifyUi(uiSvc, {
124
+ system: service.system,
125
+ projectCode: manifest.projectCode,
126
+ serviceId: service.serviceId,
127
+ specList: service.specList || { tests: [], docs: [] },
128
+ });
129
+ log.success(`${manifest.projectCode} › ${service.serviceId}`);
130
+ summary.push({ projectCode: manifest.projectCode, serviceId: service.serviceId, url: service.system.connectionData.serviceUrl });
131
+ } catch (err) {
132
+ log.error(`${service.serviceId} failed: ${err.message}`);
133
+ }
134
+ }
135
+ printSummary(summary);
136
+ } else {
137
+ log.warn("No plugin manifest found. Storing as connected-services.");
138
+ const connectionData = await HttpClient.request({ url: target });
139
+ const serviceId = serviceIdFromRoute(connectionData.route);
140
+ const project = {
141
+ system: { connectionData },
142
+ projectCode: "connected-services",
143
+ serviceId,
144
+ specList: { tests: [], docs: [] },
145
+ };
146
+ Client.createService(connectionData);
147
+ connectedUrls.add(target);
148
+ await notifyUi(uiSvc, project);
149
+ printSummary([{ projectCode: "connected-services", serviceId, url: target }]);
150
+ }
151
+ } else {
152
+ const connectionData = await HttpClient.request({ url: target });
153
+ if (!connectionData || !connectionData.SystemLynxService) {
154
+ throw new Error("No SystemLynx service found at " + target);
155
+ }
156
+ const serviceId = serviceIdFromRoute(connectionData.route);
157
+ const project = {
158
+ system: { connectionData },
159
+ projectCode: "connected-services",
160
+ serviceId,
161
+ specList: { tests: [], docs: [] },
162
+ };
163
+ Client.createService(connectionData);
164
+ connectedUrls.add(target);
165
+ await notifyUi(uiSvc, project);
166
+ log.success(`connected-services › ${serviceId}`);
167
+ printSummary([{ projectCode: "connected-services", serviceId, url: target }]);
168
+ }
68
169
  } catch (err) {
69
170
  log.error(`Connection failed: ${err.message}`);
70
171
  }
71
172
  };
72
-
73
- function printManifestSummary(manifest) {
74
- if (!manifest) return;
75
- log.plain(`\n Project: ${manifest.projectCode}`);
76
- log.plain(` Services:`);
77
- (manifest.services || []).forEach(({ serviceId, system }) => {
78
- log.plain(` - ${serviceId} @ ${system.connectionData.serviceUrl}`);
79
- });
80
- log.plain("");
81
- }
package/cli/index.js CHANGED
@@ -13,20 +13,39 @@ const listTests = require("./listTests");
13
13
  const appIsRunning = require("./appIsRunning");
14
14
  const openBrowser = require("./openBrowser");
15
15
  const connectService = require("./connectService");
16
+ const manifestCommands = require("./manifest");
16
17
  const probe = require("./probe");
17
18
  const logsCommand = require("./logs");
18
- const { HttpClient, createClient } = require("systemlynx");
19
+ const { createClient } = require("systemlynx");
19
20
  const { createCookieHttpClient } = require("./cookieClient");
20
21
  const cookieHttpClient = createCookieHttpClient();
21
22
  const Client = createClient(cookieHttpClient);
22
23
 
23
24
  const DEFAULT_PORT = 3000;
24
25
  const VERSION = require("../package.json").version;
26
+ const UI_URL = `http://localhost:${DEFAULT_PORT}`;
27
+
28
+ const MANIFEST_FILE = flags.manifest || path.join(process.cwd(), "systemview.manifest.json");
29
+ const connectedUrls = new Set();
30
+
31
+ function loadManifest() {
32
+ if (!fs.existsSync(MANIFEST_FILE)) return;
33
+ try {
34
+ const manifest = JSON.parse(fs.readFileSync(MANIFEST_FILE, "utf8"));
35
+ const services = manifest.services || [manifest];
36
+ for (const { system } of services) {
37
+ if (system && system.connectionData) {
38
+ Client.createService(system.connectionData);
39
+ connectedUrls.add(system.connectionData.serviceUrl);
40
+ }
41
+ }
42
+ } catch {}
43
+ }
25
44
 
26
45
  async function startApp() {
27
46
  const port = isNaN(input[1]) ? DEFAULT_PORT : Number(input[1]);
28
47
  try {
29
- await launchApp(port, { interactive: true });
48
+ await launchApp(port, { interactive: true, connectedUrls, client: Client });
30
49
  } catch (error) {
31
50
  log.error("Launch failed: " + error.message);
32
51
  }
@@ -35,13 +54,11 @@ async function startApp() {
35
54
  async function startTest() {
36
55
  const project_code = input[1];
37
56
  const namespace = input[2];
38
- const url = `http://localhost:${DEFAULT_PORT}`;
39
57
  try {
40
58
  await launchApp(DEFAULT_PORT);
41
- const exitCode = await runTests(url, project_code, namespace, {
59
+ const exitCode = await runTests(UI_URL, project_code, namespace, {
42
60
  json: flags.json,
43
61
  verbose: flags.verbose,
44
- manifest: flags.manifest,
45
62
  headers: flags.headers,
46
63
  bail: flags.bail,
47
64
  dryRun: flags.dryRun,
@@ -59,41 +76,35 @@ async function startTest() {
59
76
  async function list() {
60
77
  const project_code = input[1];
61
78
  const namespace = input[2];
62
- const url = `http://localhost:${DEFAULT_PORT}`;
63
- const api = `${url}/systemview/api`;
79
+ const api = `${UI_URL}/systemview/api`;
64
80
  if (!(await appIsRunning(api))) {
65
81
  await launchApp(DEFAULT_PORT);
66
82
  }
67
- await listTests(url, project_code, namespace, { manifest: flags.manifest, verbose: flags.verbose });
83
+ await listTests(UI_URL, project_code, namespace, {
84
+ connectedUrls,
85
+ verbose: flags.verbose,
86
+ json: flags.json,
87
+ });
68
88
  process.exit(0);
69
89
  }
70
90
 
71
91
  async function open() {
72
92
  const project_code = input[1];
73
93
  const namespace = input[2];
74
- const ui = `http://localhost:${DEFAULT_PORT}`;
75
- const api = `${ui}/systemview/api`;
94
+ const api = `${UI_URL}/systemview/api`;
76
95
  if (!(await appIsRunning(api))) {
77
96
  await launchApp(DEFAULT_PORT);
78
97
  }
79
98
 
80
99
  let connectedServices = [];
81
100
  if (namespace && project_code) {
82
- const manifestFile = flags.manifest || path.join(process.cwd(), "systemview.manifest.json");
83
- if (fs.existsSync(manifestFile)) {
84
- try {
85
- const raw = JSON.parse(fs.readFileSync(manifestFile, "utf8"));
86
- connectedServices = raw.services ? raw.services : [raw];
87
- } catch {}
88
- } else {
89
- try {
90
- const { SystemView } = await Client.loadService(api);
91
- connectedServices = (await SystemView.getServices(project_code)) || [];
92
- } catch {}
93
- }
101
+ try {
102
+ const { SystemView } = await Client.loadService(api);
103
+ connectedServices = (await SystemView.getServices(project_code)) || [];
104
+ } catch {}
94
105
  }
95
106
 
96
- openBrowser(ui, project_code, namespace, connectedServices);
107
+ openBrowser(UI_URL, project_code, namespace, connectedServices);
97
108
  process.exit(0);
98
109
  }
99
110
 
@@ -103,24 +114,20 @@ async function quitApp() {
103
114
 
104
115
  if (await appIsRunning(api)) {
105
116
  log.info("Attempting remote shutdown...");
106
- const url = `${api}/SystemView/shutdown`;
107
117
  try {
108
- await HttpClient.request({ url, method: "put" });
118
+ const { SystemView } = await Client.loadService(api);
119
+ await SystemView.shutdown();
120
+ } catch {}
121
+ if (!(await appIsRunning(api))) {
109
122
  log.success("SystemView shutdown successful!");
110
- process.exit(0);
111
- } catch (error) {
112
- if (!(await appIsRunning(api))) {
113
- log.success("SystemView shutdown successful!");
114
- process.exit(0);
115
- } else {
116
- log.error("Remote shutdown failed!");
117
- process.exit(1);
118
- }
123
+ } else {
124
+ log.error("Remote shutdown failed!");
125
+ process.exit(1);
119
126
  }
120
127
  } else {
121
128
  log.warn(`No SystemView instance found @ ${api}`);
122
- process.exit(0);
123
129
  }
130
+ process.exit(0);
124
131
  }
125
132
 
126
133
  (async () => {
@@ -130,6 +137,8 @@ async function quitApp() {
130
137
  }
131
138
 
132
139
  init();
140
+ loadManifest();
141
+
133
142
  const command = input[0];
134
143
 
135
144
  if (command === "open") {
@@ -143,32 +152,58 @@ async function quitApp() {
143
152
  } else if (["exit", "q", "shutdown", "stop"].includes(command)) {
144
153
  await quitApp();
145
154
  } else if (command === "connect") {
146
- await connectService(input[1], input[2], { manifest: flags.manifest });
155
+ const useManifest = process.argv.includes("--manifest");
156
+ await connectService(input[1], {
157
+ useManifest,
158
+ force: flags.force,
159
+ connectedUrls,
160
+ uiUrl: UI_URL,
161
+ });
162
+ process.exit(0);
163
+ } else if (command === "disconnect") {
164
+ await manifestCommands.disconnect(input[1], input[2], {
165
+ connectedUrls,
166
+ uiUrl: UI_URL,
167
+ });
168
+ process.exit(0);
169
+ } else if (command === "manifest") {
170
+ const sub = input[1];
171
+ if (sub === "save") {
172
+ log.warn("manifest save requires an interactive session. Run: systemview start");
173
+ } else if (sub === "clean") {
174
+ await manifestCommands.clean(MANIFEST_FILE);
175
+ } else {
176
+ log.warn("Usage: systemview manifest <save|clean>");
177
+ }
147
178
  process.exit(0);
148
179
  } else if (command === "probe") {
180
+ await launchApp(DEFAULT_PORT);
149
181
  const exitCode = await probe(input[1], input[2], {
150
182
  json: flags.json,
151
183
  manifest: flags.manifest,
152
184
  headers: flags.headers,
185
+ uiUrl: UI_URL,
153
186
  });
154
187
  process.exit(exitCode || 0);
155
- } else if (command === "logs") {
156
- const url = `http://localhost:${DEFAULT_PORT}`;
157
- const api = `${url}/systemview/api`;
158
- if (!(await appIsRunning(api))) {
159
- await launchApp(DEFAULT_PORT);
160
- }
161
- await logsCommand(url, input[1], input[2], {
188
+ } else if (command === "logs" || command === "log") {
189
+ await launchApp(DEFAULT_PORT);
190
+ await logsCommand(input[1], input[2], {
191
+ uiUrl: UI_URL,
162
192
  level: flags.level,
163
193
  limit: flags.limit,
164
194
  clear: flags.clear,
165
195
  json: flags.json,
166
- follow: command === "follow" || flags.follow,
196
+ current: flags.current,
197
+ follow: flags.follow,
167
198
  verbose: flags.verbose,
168
199
  filter: flags.filter,
169
200
  or: flags.or,
201
+ include: flags.include,
202
+ save: flags.save,
203
+ saved: flags.saved,
204
+ saveLimit: flags.saveLimit,
170
205
  });
171
- process.exit(0);
206
+ if (!flags.follow) process.exit(0);
172
207
  } else {
173
208
  await startApp();
174
209
  }
package/cli/launchApp.js CHANGED
@@ -2,8 +2,9 @@ const log = require("./logger");
2
2
  const appIsRunning = require("./appIsRunning");
3
3
  const launchSystemView = require("../api");
4
4
  const startLineReader = require("./startLineReader");
5
+ const listTests = require("./listTests");
5
6
 
6
- module.exports = async function launchApp(port, { interactive = false } = {}) {
7
+ module.exports = async function launchApp(port, { interactive = false, connectedUrls = new Set() } = {}) {
7
8
  const ui = `http://localhost:${port}`;
8
9
  const api = `${ui}/systemview/api`;
9
10
 
@@ -15,18 +16,20 @@ module.exports = async function launchApp(port, { interactive = false } = {}) {
15
16
 
16
17
  if (await appIsRunning(api)) {
17
18
  if (interactive) {
18
- log.info("SystemView is running from another terminal");
19
+ log.warn(`SystemView already running on port ${port} — attaching.`);
19
20
  logConnection();
20
- return startLineReader(ui);
21
+ await listTests(ui, null, null, { connectedUrls });
22
+ return startLineReader(ui, { connectedUrls });
21
23
  }
22
24
  return;
23
25
  }
24
26
 
25
- if (interactive) log.info("Launching...");
27
+ if (interactive) log.info(`Launching on port ${port}...`);
26
28
  await launchSystemView(port);
27
29
  logConnection();
28
30
 
29
31
  if (interactive) {
30
- return startLineReader(ui);
32
+ await listTests(ui, null, null, { connectedUrls });
33
+ return startLineReader(ui, { connectedUrls });
31
34
  }
32
35
  };
package/cli/listTests.js CHANGED
@@ -1,5 +1,3 @@
1
- const fs = require("fs");
2
- const path = require("path");
3
1
  const { createClient } = require("systemlynx");
4
2
  const { createCookieHttpClient } = require("./cookieClient");
5
3
  const log = require("./logger");
@@ -8,20 +6,39 @@ const chalk = require("chalk");
8
6
  const cookieHttpClient = createCookieHttpClient();
9
7
  const Client = createClient(cookieHttpClient);
10
8
 
11
- module.exports = async function listTests(url, project_code, namespace, { manifest: manifestPath, verbose = false } = {}) {
9
+ module.exports = async function listTests(url, project_code, namespace, { connectedUrls = new Set(), verbose = false, json = false } = {}) {
12
10
  const api = `${url}/systemview/api`;
13
11
 
14
12
  if (!project_code) {
15
- await listAllProjects(api, Client, verbose);
13
+ await listAllProjects(api, Client, verbose, connectedUrls, json);
16
14
  return;
17
15
  }
18
16
 
19
- const connectedServices = await loadServices(api, project_code, manifestPath, Client);
17
+ const connectedServices = await loadServices(api, project_code, Client);
20
18
  if (!connectedServices.length) {
21
19
  log.warn("No connected services found for project: " + project_code);
22
20
  return;
23
21
  }
24
22
 
23
+ if (json) {
24
+ const output = [];
25
+ for (const { serviceId, system } of connectedServices) {
26
+ let testList = [];
27
+ try {
28
+ const svc = Client.createService(system.connectionData);
29
+ testList = await svc.Plugin.getTests();
30
+ } catch { continue; }
31
+ const filtered = namespace
32
+ ? testList.filter(({ namespace: n }) =>
33
+ `${n.serviceId}.${n.moduleName}.${n.methodName}`.includes(namespace)
34
+ )
35
+ : testList;
36
+ output.push({ serviceId, tests: filtered });
37
+ }
38
+ console.log(JSON.stringify(output, null, 2));
39
+ return;
40
+ }
41
+
25
42
  console.log("");
26
43
  console.log(` ${chalk.bold(project_code)}`);
27
44
 
@@ -96,7 +113,7 @@ module.exports = async function listTests(url, project_code, namespace, { manife
96
113
  console.log("");
97
114
  };
98
115
 
99
- async function listAllProjects(api, Client, verbose = false) {
116
+ async function listAllProjects(api, Client, verbose = false, connectedUrls = new Set(), json = false) {
100
117
  let projects;
101
118
  try {
102
119
  const { SystemView } = await Client.loadService(api);
@@ -108,10 +125,13 @@ async function listAllProjects(api, Client, verbose = false) {
108
125
 
109
126
  const codes = Object.keys(projects);
110
127
  if (!codes.length) {
128
+ if (json) { console.log(JSON.stringify({})); return; }
111
129
  log.warn("No connected projects found.");
112
130
  return;
113
131
  }
114
132
 
133
+ if (json) { console.log(JSON.stringify(projects, null, 2)); return; }
134
+
115
135
  const total = codes.reduce((n, c) => n + projects[c].length, 0);
116
136
  console.log("");
117
137
  console.log(chalk.dim(` ${codes.length} ${codes.length === 1 ? "project" : "projects"}, ${total} ${total === 1 ? "service" : "services"}`));
@@ -123,9 +143,11 @@ async function listAllProjects(api, Client, verbose = false) {
123
143
  const isLastService = si === services.length - 1;
124
144
  const servicePrefix = isLastService ? " └── " : " ├── ";
125
145
  const childPad = isLastService ? " " : " │ ";
146
+ const connected = connectedUrls.has(serviceUrl);
147
+ const connectedMark = connected ? chalk.green(" ●") : chalk.dim(" ○");
126
148
 
127
149
  if (verbose && connectionData && connectionData.modules) {
128
- console.log(`${servicePrefix}${chalk.bold(serviceId)} ${chalk.dim(serviceUrl)}`);
150
+ console.log(`${servicePrefix}${chalk.bold(serviceId)}${connectedMark} ${chalk.dim(serviceUrl)}`);
129
151
  const mods = connectionData.modules.filter((m) => m.name !== "Plugin");
130
152
  mods.forEach((mod, mi) => {
131
153
  const isLastMod = mi === mods.length - 1;
@@ -140,7 +162,7 @@ async function listAllProjects(api, Client, verbose = false) {
140
162
  });
141
163
  });
142
164
  } else {
143
- console.log(`${servicePrefix}${serviceId} ${chalk.dim(serviceUrl)}`);
165
+ console.log(`${servicePrefix}${serviceId}${connectedMark} ${chalk.dim(serviceUrl)}`);
144
166
  }
145
167
  });
146
168
  if (pi < codes.length - 1) console.log("");
@@ -148,14 +170,7 @@ async function listAllProjects(api, Client, verbose = false) {
148
170
  console.log("");
149
171
  }
150
172
 
151
- async function loadServices(api, project_code, manifestPath, Client) {
152
- const manifestFile = manifestPath || path.join(process.cwd(), "systemview.manifest.json");
153
- if (fs.existsSync(manifestFile)) {
154
- try {
155
- const raw = JSON.parse(fs.readFileSync(manifestFile, "utf8"));
156
- return raw.services ? raw.services : [raw];
157
- } catch {}
158
- }
173
+ async function loadServices(api, project_code, Client) {
159
174
  try {
160
175
  const { SystemView } = await Client.loadService(api);
161
176
  return (await SystemView.getServices(project_code)) || [];