note-connector 0.1.0 → 0.2.1
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/dist/bin.js +1 -1
- package/dist/daemon-worker.d.ts +1 -1
- package/dist/daemon-worker.js +0 -2
- package/dist/paths.js +6 -2
- package/dist/runtime.d.ts +0 -2
- package/dist/runtime.js +32 -26
- package/dist/setup-dependencies.d.ts +8 -0
- package/dist/setup-dependencies.js +105 -0
- package/package.json +4 -4
package/dist/bin.js
CHANGED
|
@@ -12,7 +12,7 @@ const program = new Command();
|
|
|
12
12
|
program.name("note-connector").description("ChatGPT connector for note.com").version(APP_VERSION);
|
|
13
13
|
program
|
|
14
14
|
.command("start", { isDefault: true })
|
|
15
|
-
.description("
|
|
15
|
+
.description("ChatGPT Connector: install deps (uv, repo, Playwright) and start in background")
|
|
16
16
|
.option("--no-tunnel", "Do not start a public tunnel")
|
|
17
17
|
.option("-p, --port <number>", "Local port", (v) => parseInt(v, 10))
|
|
18
18
|
.option("--no-open", "Do not open ChatGPT / note.com in the browser")
|
package/dist/daemon-worker.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { StartOptions } from "./runtime.js";
|
|
2
2
|
export declare function runDaemonWorker(opts: StartOptions, logFile: string): Promise<void>;
|
package/dist/daemon-worker.js
CHANGED
|
@@ -10,7 +10,6 @@ import { resolveGatewayPort } from "./net.js";
|
|
|
10
10
|
import { isNoteAuthenticated, startNoteLoginInBackground } from "./note-auth.js";
|
|
11
11
|
import { TunnelManager } from "./tunnel/manager.js";
|
|
12
12
|
import { saveRuntime, cliPidPath, loadLastMcpAccess } from "./daemon-state.js";
|
|
13
|
-
import { ensureInitialized } from "./runtime.js";
|
|
14
13
|
async function verifyHealth(port) {
|
|
15
14
|
try {
|
|
16
15
|
const res = await fetch(`http://127.0.0.1:${port}/healthz`, { signal: AbortSignal.timeout(5000) });
|
|
@@ -36,7 +35,6 @@ function watchFirstChatGptAccess(sinceIso, logFile) {
|
|
|
36
35
|
setInterval(tick, 2000);
|
|
37
36
|
}
|
|
38
37
|
export async function runDaemonWorker(opts, logFile) {
|
|
39
|
-
await ensureInitialized();
|
|
40
38
|
const startedAt = new Date().toISOString();
|
|
41
39
|
fs.writeFileSync(cliPidPath(), String(process.pid));
|
|
42
40
|
const config = loadConfig();
|
package/dist/paths.js
CHANGED
|
@@ -27,6 +27,10 @@ export function resolveNoteConnectorRepo() {
|
|
|
27
27
|
/* ignore */
|
|
28
28
|
}
|
|
29
29
|
}
|
|
30
|
+
const defaultRepo = path.join(configDir(), "repo");
|
|
31
|
+
if (fs.existsSync(path.join(defaultRepo, "src", "note_mcp"))) {
|
|
32
|
+
return defaultRepo;
|
|
33
|
+
}
|
|
30
34
|
const here = path.dirname(fileURLToPath(import.meta.url));
|
|
31
35
|
const fromDevLayout = path.resolve(here, "..", "..");
|
|
32
36
|
if (fs.existsSync(path.join(fromDevLayout, "src", "note_mcp"))) {
|
|
@@ -37,9 +41,9 @@ export function resolveNoteConnectorRepo() {
|
|
|
37
41
|
return fromGlobal;
|
|
38
42
|
}
|
|
39
43
|
throw new Error("note-connector Python 本体が見つかりません。\n"
|
|
40
|
-
+ " git clone https://github.com/drillan/note-mcp.git\n"
|
|
41
44
|
+ " note-connector config set repoPath /path/to/note-connector\n"
|
|
42
|
-
+ "または NOTE_CONNECTOR_REPO=/path/to/note-connector
|
|
45
|
+
+ "または NOTE_CONNECTOR_REPO=/path/to/note-connector を設定してください。\n"
|
|
46
|
+
+ "git clone https://github.com/yuga-hashimoto/note-connector.git");
|
|
43
47
|
}
|
|
44
48
|
/** @deprecated use resolveNoteConnectorRepo */
|
|
45
49
|
export function repoRootFromPackage() {
|
package/dist/runtime.d.ts
CHANGED
|
@@ -5,8 +5,6 @@ export interface StartOptions {
|
|
|
5
5
|
noClipboard?: boolean;
|
|
6
6
|
skipNoteLogin?: boolean;
|
|
7
7
|
}
|
|
8
|
-
/** Create config + token + optional Tailscale domain (runs on every start, idempotent). */
|
|
9
|
-
export declare function ensureInitialized(): Promise<void>;
|
|
10
8
|
/** @deprecated Use `note-connector` or `note-connector start` */
|
|
11
9
|
export declare function runSetup(): Promise<void>;
|
|
12
10
|
export declare function runStart(opts: StartOptions): Promise<void>;
|
package/dist/runtime.js
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
import fs from "node:fs";
|
|
2
2
|
import path from "node:path";
|
|
3
3
|
import { buildMcpEndpoint, loadConfig, loadOrCreateToken, saveConfig } from "./config.js";
|
|
4
|
-
import {
|
|
4
|
+
import { configDir } from "./paths.js";
|
|
5
5
|
import { startPythonServer } from "./spawn-python.js";
|
|
6
6
|
import { resolveGatewayPort } from "./net.js";
|
|
7
7
|
import { discoverTailscaleFqdn } from "./tunnel/tailscale.js";
|
|
8
8
|
import { runOnboarding } from "./onboarding.js";
|
|
9
9
|
import { isNoteAuthenticated, startNoteLoginInBackground } from "./note-auth.js";
|
|
10
10
|
import { spawnDaemon } from "./daemon.js";
|
|
11
|
+
import { setupDependencies } from "./setup-dependencies.js";
|
|
11
12
|
import { TunnelManager } from "./tunnel/manager.js";
|
|
12
13
|
async function verifyHealth(port) {
|
|
13
14
|
try {
|
|
@@ -18,40 +19,45 @@ async function verifyHealth(port) {
|
|
|
18
19
|
return false;
|
|
19
20
|
}
|
|
20
21
|
}
|
|
21
|
-
/** Create config + token + optional Tailscale domain (runs on every start, idempotent). */
|
|
22
|
-
export async function ensureInitialized() {
|
|
23
|
-
const firstRun = !fs.existsSync(path.join(configDir(), "config.json"));
|
|
24
|
-
ensureConfigDir();
|
|
25
|
-
let config = loadConfig();
|
|
26
|
-
const fqdn = discoverTailscaleFqdn();
|
|
27
|
-
if (fqdn && !config.tunnel.domain) {
|
|
28
|
-
config = { ...config, tunnel: { ...config.tunnel, domain: fqdn } };
|
|
29
|
-
saveConfig(config);
|
|
30
|
-
if (firstRun) {
|
|
31
|
-
console.log(`Tailscale FQDN saved: ${fqdn}`);
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
else {
|
|
35
|
-
saveConfig(config);
|
|
36
|
-
}
|
|
37
|
-
loadOrCreateToken();
|
|
38
|
-
if (firstRun) {
|
|
39
|
-
console.log(`Ready (~/.note-connector). Starting…`);
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
22
|
/** @deprecated Use `note-connector` or `note-connector start` */
|
|
43
23
|
export async function runSetup() {
|
|
44
|
-
await ensureInitialized();
|
|
45
24
|
console.log("Setup is included in start. Just run: note-connector");
|
|
46
25
|
}
|
|
47
26
|
export async function runStart(opts) {
|
|
48
|
-
|
|
27
|
+
console.log("note-connector — ChatGPT Connector セットアップ中…");
|
|
28
|
+
const report = await setupDependencies();
|
|
29
|
+
for (const w of report.warnings) {
|
|
30
|
+
console.warn(`⚠ ${w}`);
|
|
31
|
+
}
|
|
32
|
+
loadOrCreateToken();
|
|
33
|
+
const fqdn = discoverTailscaleFqdn();
|
|
34
|
+
if (fqdn) {
|
|
35
|
+
const config = loadConfig();
|
|
36
|
+
if (!config.tunnel.domain) {
|
|
37
|
+
saveConfig({ ...config, tunnel: { ...config.tunnel, domain: fqdn } });
|
|
38
|
+
console.log(`Tailscale FQDN: ${fqdn}`);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
console.log("依存関係の準備が完了しました。");
|
|
49
42
|
await spawnDaemon(opts);
|
|
50
|
-
return;
|
|
51
43
|
}
|
|
52
44
|
/** Foreground mode (debug): keep terminal attached. */
|
|
53
45
|
export async function runStartForeground(opts) {
|
|
54
|
-
|
|
46
|
+
console.log("note-connector — ChatGPT Connector セットアップ中…");
|
|
47
|
+
const report = await setupDependencies();
|
|
48
|
+
for (const w of report.warnings) {
|
|
49
|
+
console.warn(`⚠ ${w}`);
|
|
50
|
+
}
|
|
51
|
+
loadOrCreateToken();
|
|
52
|
+
const fqdn = discoverTailscaleFqdn();
|
|
53
|
+
if (fqdn) {
|
|
54
|
+
const config = loadConfig();
|
|
55
|
+
if (!config.tunnel.domain) {
|
|
56
|
+
saveConfig({ ...config, tunnel: { ...config.tunnel, domain: fqdn } });
|
|
57
|
+
console.log(`Tailscale FQDN: ${fqdn}`);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
console.log("依存関係の準備が完了しました。");
|
|
55
61
|
const config = loadConfig();
|
|
56
62
|
const preferred = opts.port ?? config.gatewayPort;
|
|
57
63
|
let port;
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import { execFileSync } from "node:child_process";
|
|
2
|
+
import fs from "node:fs";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import { loadConfig, saveConfig } from "./config.js";
|
|
5
|
+
import { configDir, resolveNoteConnectorRepo } from "./paths.js";
|
|
6
|
+
const DEFAULT_REPO = "https://github.com/yuga-hashimoto/note-connector.git";
|
|
7
|
+
const MIN_NODE_MAJOR = 20;
|
|
8
|
+
function commandExists(cmd) {
|
|
9
|
+
try {
|
|
10
|
+
execFileSync("command", ["-v", cmd], { stdio: "ignore" });
|
|
11
|
+
return true;
|
|
12
|
+
}
|
|
13
|
+
catch {
|
|
14
|
+
return false;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
function installUvUnix() {
|
|
18
|
+
console.log("Installing uv (Python toolchain)…");
|
|
19
|
+
execFileSync("sh", ["-c", "curl -LsSf https://astral.sh/uv/install.sh | sh"], { stdio: "inherit", env: { ...process.env, CARGO_HOME: process.env.CARGO_HOME } });
|
|
20
|
+
const home = process.env.HOME ?? "";
|
|
21
|
+
const cargoBin = path.join(home, ".cargo", "bin");
|
|
22
|
+
const localBin = path.join(home, ".local", "bin");
|
|
23
|
+
const pathEnv = process.env.PATH ?? "";
|
|
24
|
+
if (!pathEnv.includes(cargoBin)) {
|
|
25
|
+
process.env.PATH = `${cargoBin}:${localBin}:${pathEnv}`;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
function ensureUv() {
|
|
29
|
+
if (commandExists("uv"))
|
|
30
|
+
return;
|
|
31
|
+
if (process.platform === "win32") {
|
|
32
|
+
throw new Error("uv が見つかりません。https://docs.astral.sh/uv/ からインストールしてください。");
|
|
33
|
+
}
|
|
34
|
+
installUvUnix();
|
|
35
|
+
if (!commandExists("uv")) {
|
|
36
|
+
throw new Error("uv のインストールに失敗しました。PATH に ~/.local/bin または ~/.cargo/bin を追加してください。");
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
function repoHasPython(root) {
|
|
40
|
+
return fs.existsSync(path.join(root, "pyproject.toml")) && fs.existsSync(path.join(root, "src", "note_mcp"));
|
|
41
|
+
}
|
|
42
|
+
function cloneRepo(target) {
|
|
43
|
+
console.log(`Cloning note-connector → ${target}`);
|
|
44
|
+
fs.mkdirSync(path.dirname(target), { recursive: true });
|
|
45
|
+
execFileSync("git", ["clone", "--depth", "1", DEFAULT_REPO, target], { stdio: "inherit" });
|
|
46
|
+
}
|
|
47
|
+
function ensureRepoPath(config) {
|
|
48
|
+
if (config.repoPath && repoHasPython(config.repoPath)) {
|
|
49
|
+
return path.resolve(config.repoPath);
|
|
50
|
+
}
|
|
51
|
+
try {
|
|
52
|
+
return resolveNoteConnectorRepo();
|
|
53
|
+
}
|
|
54
|
+
catch {
|
|
55
|
+
/* fall through */
|
|
56
|
+
}
|
|
57
|
+
const target = path.join(configDir(), "repo");
|
|
58
|
+
if (!repoHasPython(target)) {
|
|
59
|
+
if (fs.existsSync(target)) {
|
|
60
|
+
throw new Error(`Incomplete repo at ${target}. Remove it or set repoPath.`);
|
|
61
|
+
}
|
|
62
|
+
cloneRepo(target);
|
|
63
|
+
}
|
|
64
|
+
const updated = { ...config, repoPath: target };
|
|
65
|
+
saveConfig(updated);
|
|
66
|
+
process.env.NOTE_CONNECTOR_REPO = target;
|
|
67
|
+
return target;
|
|
68
|
+
}
|
|
69
|
+
function runUvSync(repo) {
|
|
70
|
+
console.log("Installing Python dependencies (uv sync)…");
|
|
71
|
+
execFileSync("uv", ["sync"], { cwd: repo, stdio: "inherit", env: process.env });
|
|
72
|
+
}
|
|
73
|
+
function ensurePlaywright(repo) {
|
|
74
|
+
console.log("Installing Playwright Chromium (初回のみ時間がかかります)…");
|
|
75
|
+
execFileSync("uv", ["run", "playwright", "install", "chromium"], {
|
|
76
|
+
cwd: repo,
|
|
77
|
+
stdio: "inherit",
|
|
78
|
+
env: process.env,
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
function ensureNodeVersion() {
|
|
82
|
+
const major = parseInt(process.versions.node.split(".")[0] ?? "0", 10);
|
|
83
|
+
if (major < MIN_NODE_MAJOR) {
|
|
84
|
+
throw new Error(`Node.js ${MIN_NODE_MAJOR}+ が必要です(現在: ${process.versions.node})`);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
export async function setupDependencies() {
|
|
88
|
+
const warnings = [];
|
|
89
|
+
ensureNodeVersion();
|
|
90
|
+
const config = loadConfig();
|
|
91
|
+
ensureUv();
|
|
92
|
+
const repo = ensureRepoPath(config);
|
|
93
|
+
runUvSync(repo);
|
|
94
|
+
ensurePlaywright(repo);
|
|
95
|
+
if (!commandExists("tailscale") && config.tunnel.provider === "tailscale" && !config.tunnel.publicUrl) {
|
|
96
|
+
warnings.push("Tailscale CLI がありません。tunnel.publicUrl を設定するか Tailscale をインストールしてください。");
|
|
97
|
+
}
|
|
98
|
+
return {
|
|
99
|
+
uvInstalled: true,
|
|
100
|
+
repoReady: true,
|
|
101
|
+
pythonDepsReady: true,
|
|
102
|
+
playwrightReady: true,
|
|
103
|
+
warnings,
|
|
104
|
+
};
|
|
105
|
+
}
|
package/package.json
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "note-connector",
|
|
3
|
-
"version": "0.1
|
|
3
|
+
"version": "0.2.1",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"access": "public"
|
|
6
6
|
},
|
|
7
|
-
"description": "
|
|
7
|
+
"description": "ChatGPT Connector for note.com — MCP server with Apps SDK UI. One command setup: uv, Playwright, tunnel.",
|
|
8
8
|
"license": "MIT",
|
|
9
9
|
"type": "module",
|
|
10
10
|
"bin": {
|
|
@@ -39,7 +39,7 @@
|
|
|
39
39
|
],
|
|
40
40
|
"repository": {
|
|
41
41
|
"type": "git",
|
|
42
|
-
"url": "git+https://github.com/
|
|
42
|
+
"url": "git+https://github.com/yuga-hashimoto/note-connector.git"
|
|
43
43
|
},
|
|
44
|
-
"homepage": "https://github.com/
|
|
44
|
+
"homepage": "https://github.com/yuga-hashimoto/note-connector#readme"
|
|
45
45
|
}
|