@limecloud/agent-app-studio 0.1.1 → 0.1.3

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/APP.md CHANGED
@@ -2,7 +2,7 @@
2
2
  manifestVersion: 0.7.0
3
3
  name: lime-agent-app-studio
4
4
  displayName: Lime Agent App Studio
5
- version: 0.1.1
5
+ version: 0.1.3
6
6
  status: preview
7
7
  appType: developer-tool
8
8
  description: 面向已认证开发者的 Agent App 可视化发布工作台和 npm CLI 入口。
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@limecloud/agent-app-studio",
3
- "version": "0.1.1",
3
+ "version": "0.1.3",
4
4
  "description": "Lime Agent App Studio CLI and visual publisher for Agent App packages.",
5
5
  "type": "module",
6
6
  "private": false,
@@ -27,7 +27,8 @@
27
27
  "test": "node --test tests/*.test.mjs",
28
28
  "pack:dry-run": "npm pack --dry-run",
29
29
  "publish:dry-run": "npm publish --access public --dry-run",
30
- "publish:npm": "npm publish --access public"
30
+ "publish:npm": "npm publish --access public",
31
+ "dev": "node src/server.mjs"
31
32
  },
32
33
  "engines": {
33
34
  "node": ">=20.0.0"
package/src/cli.mjs CHANGED
@@ -19,7 +19,13 @@ export async function runCli(argv) {
19
19
  case "project inspect":
20
20
  return printJson(await inspectProject(options.appDir || "."));
21
21
  case "package":
22
- return printJson(await packageProject({ appDir: options.appDir || ".", outDir: options.outDir }));
22
+ return printJson(
23
+ await packageProject({
24
+ appDir: options.appDir || ".",
25
+ outDir: options.outDir,
26
+ includeNodeModules: Boolean(options.includeNodeModules),
27
+ })
28
+ );
23
29
  case "publish": {
24
30
  const auth = await resolveAuthContext(options);
25
31
  return printJson(
@@ -83,7 +89,7 @@ Usage:
83
89
  lime-agent-app-studio auth login --tenant-id <id> --token <token> [--api-base <url>]
84
90
  lime-agent-app-studio auth status --tenant-id <id>
85
91
  lime-agent-app-studio project inspect --app-dir <path>
86
- lime-agent-app-studio package --app-dir <path> [--out-dir <path>]
92
+ lime-agent-app-studio package --app-dir <path> [--out-dir <path>] [--include-node-modules]
87
93
  lime-agent-app-studio publish --app-dir <path> --app-id <id> --tenant-id <id> --channel beta --dry-run
88
94
  lime-agent-app-studio publish --app-dir <path> --app-id <id> --tenant-id <id> --channel stable --publish
89
95
  lime-agent-app-studio studio --port 4177
@@ -27,7 +27,9 @@ export async function packageProject(options = {}) {
27
27
  await mkdir(outDir, { recursive: true });
28
28
  const packageName = `${inspection.appId}-${inspection.version}.lapp`;
29
29
  const packagePath = join(outDir, packageName);
30
- const files = await collectPackageFiles(appDir);
30
+ const files = await collectPackageFiles(appDir, {
31
+ includeNodeModules: Boolean(options.includeNodeModules),
32
+ });
31
33
  await writeZip(appDir, files, packagePath);
32
34
 
33
35
  const packageHash = await sha256File(packagePath);
@@ -44,23 +46,27 @@ export async function packageProject(options = {}) {
44
46
  };
45
47
  }
46
48
 
47
- export async function collectPackageFiles(appDir) {
49
+ export async function collectPackageFiles(appDir, options = {}) {
48
50
  const root = resolve(appDir);
49
51
  const result = [];
50
- await walk(root, root, result);
52
+ const excludes = new Set(defaultExcludes);
53
+ if (options.includeNodeModules) {
54
+ excludes.delete("node_modules");
55
+ }
56
+ await walk(root, root, result, excludes);
51
57
  result.sort((a, b) => a.localeCompare(b));
52
58
  return result;
53
59
  }
54
60
 
55
- async function walk(root, current, result) {
61
+ async function walk(root, current, result, excludes) {
56
62
  const entries = await readdir(current, { withFileTypes: true });
57
63
  for (const entry of entries) {
58
- if (defaultExcludes.has(entry.name)) continue;
64
+ if (excludes.has(entry.name)) continue;
59
65
  if (entry.name === "dist-package") continue;
60
66
  const fullPath = join(current, entry.name);
61
67
  const rel = relative(root, fullPath).replace(/\\/g, "/");
62
68
  if (entry.isDirectory()) {
63
- await walk(root, fullPath, result);
69
+ await walk(root, fullPath, result, excludes);
64
70
  continue;
65
71
  }
66
72
  if (entry.isFile()) result.push(rel);
@@ -42,7 +42,11 @@ export async function publishProject(options = {}) {
42
42
  if (profile.status !== "approved") {
43
43
  throw new Error(`当前账号未完成开发者认证:${profile.status}`);
44
44
  }
45
- const packaged = await packageProject({ appDir: options.appDir, outDir: options.outDir });
45
+ const packaged = await packageProject({
46
+ appDir: options.appDir,
47
+ outDir: options.outDir,
48
+ includeNodeModules: Boolean(options.includeNodeModules),
49
+ });
46
50
  const upload = await uploadDeveloperAgentAppPackage({ ...options, appId: plan.appId, packagePath: packaged.packagePath });
47
51
  const releasePayload = {
48
52
  version: options.version || upload.version || packaged.version,
package/src/server.mjs CHANGED
@@ -5,8 +5,6 @@ import { createServer } from "node:http";
5
5
  import { readFile } from "node:fs/promises";
6
6
  import { extname, join } from "node:path";
7
7
  import { fileURLToPath } from "node:url";
8
- import { inspectProject } from "./core/project.mjs";
9
- import { publishProject } from "./core/publisher.mjs";
10
8
  import { resolveAuthContext } from "./core/config.mjs";
11
9
 
12
10
  const root = fileURLToPath(new URL("..", import.meta.url));
@@ -16,13 +14,22 @@ export async function startStudioServer(options = {}) {
16
14
  const port = Number(options.port ?? 4177);
17
15
  const server = createServer(async (req, res) => {
18
16
  try {
17
+ if (req.method === "GET" && req.url === "/api/bootstrap") {
18
+ return sendJson(res, {
19
+ appId: "lime-agent-app-studio",
20
+ status: "ok",
21
+ entry: "dashboard",
22
+ });
23
+ }
19
24
  if (req.method === "POST" && req.url === "/api/inspect") {
20
25
  const body = await readJson(req);
26
+ const { inspectProject } = await import("./core/project.mjs");
21
27
  return sendJson(res, await inspectProject(body.appDir || "."));
22
28
  }
23
29
  if (req.method === "POST" && req.url === "/api/publish") {
24
30
  const body = await readJson(req);
25
31
  const auth = await resolveAuthContext(body);
32
+ const { publishProject } = await import("./core/publisher.mjs");
26
33
  return sendJson(res, await publishProject({ ...body, ...auth }));
27
34
  }
28
35
  return serveStatic(req, res);
@@ -46,10 +53,22 @@ async function serveStatic(req, res) {
46
53
  content = await readFile(filePath);
47
54
  } catch (error) {
48
55
  if (error?.code === "ENOENT" || error?.code === "EISDIR") {
56
+ if (acceptsHtml(req)) {
57
+ return sendFile(res, join(appRoot, "index.html"));
58
+ }
49
59
  return sendNotFound(res);
50
60
  }
51
61
  throw error;
52
62
  }
63
+ return sendBuffer(res, filePath, content);
64
+ }
65
+
66
+ async function sendFile(res, filePath) {
67
+ const content = await readFile(filePath);
68
+ return sendBuffer(res, filePath, content);
69
+ }
70
+
71
+ function sendBuffer(res, filePath, content) {
53
72
  const type = contentType(filePath);
54
73
  res.writeHead(200, { "Content-Type": type });
55
74
  res.end(content);
@@ -89,3 +108,17 @@ function contentType(path) {
89
108
  return "application/octet-stream";
90
109
  }
91
110
  }
111
+
112
+ function acceptsHtml(req) {
113
+ const accept = req.headers.accept || "";
114
+ return accept.includes("text/html");
115
+ }
116
+
117
+ function isMainModule() {
118
+ return process.argv[1] && import.meta.url === new URL(process.argv[1], "file:").href;
119
+ }
120
+
121
+ if (isMainModule()) {
122
+ const { url } = await startStudioServer({ port: process.env.PORT });
123
+ console.log(`Lime Agent App Studio runtime 已启动:${url}`);
124
+ }