@quicktvui/ai-cli 1.1.3 → 1.1.6

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
@@ -73,7 +73,7 @@ quicktvui-aicreate-project quick-tv-app
73
73
  - `--port <n>`: dev server port used by `run-dev` auto load (default `38989`)
74
74
  - `--skip-env-check`: skip environment stage in `run-dev`
75
75
  - `--runtime-package <pkg>`: runtime package for `run-esapp` (default `com.extscreen.runtime`)
76
- - `--esapp-uri <uri>`: raw launch URI (`esapp://`, `quicktv://`, `appcast://`)
76
+ - `--esapp-uri <uri>`: raw launch URI (`esapp://`)
77
77
  - `--esapp-query <json>`: extra query params JSON merged in structured mode
78
78
  - `--pkg --ver --min-ver --repository --uri --from --args --exp --flags --use-latest`: structured `esapp://action/start` params
79
79
 
@@ -1,4 +1,4 @@
1
- # ESApp Protocol Reference (`esapp://`, `quicktv://`, `appcast://`)
1
+ # ESApp Protocol Reference (`esapp://`)
2
2
 
3
3
  This document summarizes runtime launch protocol behavior from:
4
4
 
@@ -12,8 +12,6 @@ This document summarizes runtime launch protocol behavior from:
12
12
  Runtime entry activity accepts:
13
13
 
14
14
  - `esapp://`
15
- - `quicktv://`
16
- - `appcast://`
17
15
 
18
16
  ## 2) Parsing Modes
19
17
 
@@ -29,13 +27,11 @@ Behavior:
29
27
  - `/start` maps to `action=start_es`.
30
28
  - All query params are forwarded to protocol JSON.
31
29
 
32
- ### Mode B: V2 package URI (esapp/quicktv/appcast)
30
+ ### Mode B: V2 package URI (esapp)
33
31
 
34
32
  ```text
35
33
  esapp://es.hello.world?from=cmd
36
34
  esapp://es.hello.world/1.0.3?from=cmd
37
- quicktv://es.hello.world?from=cmd
38
- appcast://es.hello.world/1.0.3?from=cmd
39
35
  ```
40
36
 
41
37
  Behavior:
package/lib/index.js CHANGED
@@ -1714,18 +1714,18 @@ function ensureSupportedEsappUri(uri) {
1714
1714
  const normalized = String(uri || "")
1715
1715
  .trim()
1716
1716
  .toLowerCase();
1717
- if (
1718
- normalized.startsWith("esapp://") ||
1719
- normalized.startsWith("quicktv://") ||
1720
- normalized.startsWith("appcast://")
1721
- ) {
1717
+ if (normalized.startsWith("esapp://")) {
1722
1718
  return;
1723
1719
  }
1724
1720
  throw new Error(
1725
- `Unsupported URI scheme for runtime launch: ${uri}. Use esapp://, quicktv://, or appcast://.`,
1721
+ `Unsupported URI scheme for runtime launch: ${uri}. Use esapp:// only.`,
1726
1722
  );
1727
1723
  }
1728
1724
 
1725
+ function quotePosixShellArg(value) {
1726
+ return `'${String(value).replace(/'/g, `'\\''`)}'`;
1727
+ }
1728
+
1729
1729
  function buildEsappLaunchUri(args, projectRoot, defaults = {}) {
1730
1730
  const positional =
1731
1731
  args._ && typeof args._[1] === "string" ? args._[1].trim() : "";
@@ -1807,18 +1807,19 @@ function buildEsappLaunchUri(args, projectRoot, defaults = {}) {
1807
1807
 
1808
1808
  function startEsappOnRuntimeByUri(adbPath, serial, runtimePackage, launchUri) {
1809
1809
  ensureSupportedEsappUri(launchUri);
1810
+ // Use explicit POSIX shell quoting so `&` in URI query is not truncated by
1811
+ // remote Android shell parsing (e.g. `...from=cmd&pkg=...`).
1812
+ const shellCommand = [
1813
+ "am start",
1814
+ "-a android.intent.action.VIEW",
1815
+ `-p ${quotePosixShellArg(runtimePackage)}`,
1816
+ `-d ${quotePosixShellArg(launchUri)}`,
1817
+ ].join(" ");
1810
1818
  const result = runCommandCapture(adbPath, [
1811
1819
  "-s",
1812
1820
  serial,
1813
1821
  "shell",
1814
- "am",
1815
- "start",
1816
- "-a",
1817
- "android.intent.action.VIEW",
1818
- "-p",
1819
- runtimePackage,
1820
- "-d",
1821
- launchUri,
1822
+ shellCommand,
1822
1823
  ]);
1823
1824
  const output = `${result.stdout || ""}\n${result.stderr || ""}`.trim();
1824
1825
  if (/(^|\s)error[:\s]/i.test(output) || /exception/i.test(output)) {
@@ -2625,7 +2626,7 @@ Options:
2625
2626
  --port <n> Dev server port used by run-dev auto load (default: 38989)
2626
2627
  --skip-env-check Skip setup-android-env stage in run-dev
2627
2628
  --runtime-package <pkg> Runtime package name for run-esapp (default: com.extscreen.runtime)
2628
- --esapp-uri <uri> Raw esapp:// / quicktv:// / appcast:// URI for run-esapp
2629
+ --esapp-uri <uri> Raw esapp:// URI for run-esapp
2629
2630
  --esapp-query <json> Extra query params JSON merged into action/start URI
2630
2631
  --pkg <pkg> ES app package for run-esapp structured mode
2631
2632
  --ver <version> ES app version for run-esapp structured mode
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@quicktvui/ai-cli",
3
- "version": "1.1.3",
3
+ "version": "1.1.6",
4
4
  "description": "CLI for installing and validating QuickTVUI AI skills",
5
5
  "bin": {
6
6
  "quicktvui-ai": "bin/quicktvui-ai.js",
@@ -1,16 +1,43 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  const { runCli } = require("../lib/index");
4
+ const fs = require("fs");
5
+ const os = require("os");
6
+ const path = require("path");
4
7
 
5
8
  function isTruthy(value) {
6
9
  return value === true || value === "true" || value === "1";
7
10
  }
8
11
 
12
+ function exists(filePath) {
13
+ return fs.existsSync(filePath);
14
+ }
15
+
9
16
  function isGlobalInstall() {
10
17
  if (isTruthy(process.env.npm_config_global)) return true;
11
18
  return process.env.npm_config_location === "global";
12
19
  }
13
20
 
21
+ function resolveCodexHome() {
22
+ const fromEnv = process.env.CODEX_HOME
23
+ ? String(process.env.CODEX_HOME).trim()
24
+ : "";
25
+ if (fromEnv) {
26
+ return path.resolve(fromEnv);
27
+ }
28
+ return path.join(os.homedir(), ".codex");
29
+ }
30
+
31
+ function shouldSyncCodex() {
32
+ const fromEnv = process.env.CODEX_HOME
33
+ ? String(process.env.CODEX_HOME).trim()
34
+ : "";
35
+ if (fromEnv) {
36
+ return true;
37
+ }
38
+ return exists(path.join(os.homedir(), ".codex"));
39
+ }
40
+
14
41
  async function main() {
15
42
  if (isTruthy(process.env.QUICKTVUI_AI_SKIP_POSTINSTALL)) {
16
43
  return;
@@ -19,16 +46,51 @@ async function main() {
19
46
  return;
20
47
  }
21
48
 
49
+ const syncCodex = shouldSyncCodex();
50
+ const codexSkillsDir = path.join(resolveCodexHome(), "skills", "quicktvui");
51
+ const failures = [];
52
+
22
53
  try {
23
- await runCli(["update"]);
54
+ if (syncCodex) {
55
+ await runCli(["update", "--skip-gemini-config"]);
56
+ } else {
57
+ await runCli(["update"]);
58
+ }
59
+ } catch (error) {
60
+ failures.push(`agents: ${error.message}`);
61
+ }
62
+
63
+ if (syncCodex) {
64
+ try {
65
+ await runCli(["update", "--dir", codexSkillsDir]);
66
+ } catch (error) {
67
+ failures.push(`codex: ${error.message}`);
68
+ }
69
+ }
70
+
71
+ if (failures.length === 0) {
72
+ if (syncCodex) {
73
+ console.log(
74
+ `[quicktvui-ai] postinstall: synced latest skill files into ~/.agents/skills/quicktvui and ${codexSkillsDir}.`,
75
+ );
76
+ return;
77
+ }
24
78
  console.log(
25
79
  "[quicktvui-ai] postinstall: synced latest skill files into ~/.agents/skills/quicktvui.",
26
80
  );
27
- } catch (error) {
81
+ return;
82
+ }
83
+
84
+ if (syncCodex) {
28
85
  console.warn(
29
- `[quicktvui-ai] postinstall: unable to auto-sync skill files (${error.message}). Run 'quicktvui-ai update' manually.`,
86
+ `[quicktvui-ai] postinstall: unable to fully auto-sync skill files (${failures.join("; ")}). Run 'quicktvui-ai update' and 'quicktvui-ai update --dir ${codexSkillsDir}' manually.`,
30
87
  );
88
+ return;
31
89
  }
90
+
91
+ console.warn(
92
+ `[quicktvui-ai] postinstall: unable to auto-sync skill files (${failures.join("; ")}). Run 'quicktvui-ai update' manually.`,
93
+ );
32
94
  }
33
95
 
34
96
  main();