jowork 0.2.4 → 0.3.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/dist/{chunk-ROIINI33.js → chunk-4PIT2GZ4.js} +13 -1
- package/dist/{chunk-XLYRHKG6.js → chunk-54SD5GBF.js} +1 -1
- package/dist/chunk-63AMINQC.js +156 -0
- package/dist/{chunk-XAEGXSEO.js → chunk-74AHY7X6.js} +4 -0
- package/dist/{chunk-7U3SXINY.js → chunk-ATAUWJYD.js} +320 -50
- package/dist/chunk-DQW74UCN.js +671 -0
- package/dist/chunk-EYP6WMFF.js +153 -0
- package/dist/{chunk-JSTXMDXI.js → chunk-FCFZCZHR.js} +1 -1
- package/dist/chunk-FX6Z3QHV.js +34 -0
- package/dist/chunk-HENAABEL.js +419 -0
- package/dist/chunk-OXWWOKC7.js +201 -0
- package/dist/chunk-QGHJ45PL.js +661 -0
- package/dist/chunk-RO3KK5RC.js +132 -0
- package/dist/{chunk-JE6TOU7W.js → chunk-TFMF3EXE.js} +2 -7
- package/dist/{chunk-TN327MDF.js → chunk-VX662YLA.js} +3 -3
- package/dist/cli.js +338 -149
- package/dist/{config-AI6UIJJN.js → config-FH2XLN7A.js} +2 -2
- package/dist/content-reader-VPGTR2SF.js +10 -0
- package/dist/context-ZNI3WOB7.js +10 -0
- package/dist/{credential-store-ZRZCSRPC.js → credential-store-OS5ZY4OW.js} +2 -2
- package/dist/{feishu-A6YVFKEN.js → feishu-XW5T6ER2.js} +8 -3
- package/dist/{git-manager-N35XSG4Y.js → git-manager-RVWV2GSV.js} +2 -1
- package/dist/github-PQKAYTLO.js +11 -0
- package/dist/{paths-JXOMBYIT.js → paths-FFRET6F7.js} +7 -3
- package/dist/{server-5GVWN2NB.js → server-WEADPUST.js} +59 -66
- package/dist/{setup-IDQDPCEJ.js → setup-S2S2CHB2.js} +91 -32
- package/dist/sync-SRLFR5NA.js +21 -0
- package/dist/transport.js +6 -4
- package/package.json +1 -1
- package/src/dashboard/public/app.js +34 -8
- package/src/dashboard/public/style.css +14 -0
- package/dist/chunk-AIXKXEYS.js +0 -547
- package/dist/chunk-L5ZR7TSK.js +0 -82
- package/dist/chunk-LS2AJM5A.js +0 -163
- package/dist/chunk-QMOFQX7X.js +0 -612
- package/dist/chunk-YJWTKFWX.js +0 -451
- package/dist/github-SHWUFNYB.js +0 -10
- package/dist/sync-7V54N62M.js +0 -18
|
@@ -1,13 +1,17 @@
|
|
|
1
1
|
import {
|
|
2
|
-
contentHash,
|
|
3
2
|
getFeishuToken,
|
|
4
3
|
syncFeishu,
|
|
5
4
|
syncFeishuApprovals,
|
|
6
5
|
syncFeishuDocs,
|
|
6
|
+
syncFeishuLinks,
|
|
7
7
|
syncFeishuMeetings
|
|
8
|
-
} from "./chunk-
|
|
9
|
-
import "./chunk-
|
|
8
|
+
} from "./chunk-DQW74UCN.js";
|
|
9
|
+
import "./chunk-RO3KK5RC.js";
|
|
10
10
|
import "./chunk-MYDK7MWB.js";
|
|
11
|
+
import {
|
|
12
|
+
contentHash
|
|
13
|
+
} from "./chunk-OXWWOKC7.js";
|
|
14
|
+
import "./chunk-TFMF3EXE.js";
|
|
11
15
|
import "./chunk-UJ4KEHGZ.js";
|
|
12
16
|
export {
|
|
13
17
|
contentHash,
|
|
@@ -15,5 +19,6 @@ export {
|
|
|
15
19
|
syncFeishu,
|
|
16
20
|
syncFeishuApprovals,
|
|
17
21
|
syncFeishuDocs,
|
|
22
|
+
syncFeishuLinks,
|
|
18
23
|
syncFeishuMeetings
|
|
19
24
|
};
|
|
@@ -1,19 +1,23 @@
|
|
|
1
1
|
import {
|
|
2
|
+
bareReposDir,
|
|
2
3
|
configPath,
|
|
3
4
|
credentialsDir,
|
|
4
5
|
dataDir,
|
|
5
6
|
dbPath,
|
|
6
7
|
fileRepoDir,
|
|
7
8
|
joworkDir,
|
|
8
|
-
logsDir
|
|
9
|
-
|
|
9
|
+
logsDir,
|
|
10
|
+
pluginsDir
|
|
11
|
+
} from "./chunk-4PIT2GZ4.js";
|
|
10
12
|
import "./chunk-UJ4KEHGZ.js";
|
|
11
13
|
export {
|
|
14
|
+
bareReposDir,
|
|
12
15
|
configPath,
|
|
13
16
|
credentialsDir,
|
|
14
17
|
dataDir,
|
|
15
18
|
dbPath,
|
|
16
19
|
fileRepoDir,
|
|
17
20
|
joworkDir,
|
|
18
|
-
logsDir
|
|
21
|
+
logsDir,
|
|
22
|
+
pluginsDir
|
|
19
23
|
};
|
|
@@ -2,38 +2,44 @@ import {
|
|
|
2
2
|
linkAllUnprocessed,
|
|
3
3
|
syncGitLab,
|
|
4
4
|
syncLinear
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-HENAABEL.js";
|
|
6
|
+
import {
|
|
7
|
+
syncGitHub
|
|
8
|
+
} from "./chunk-63AMINQC.js";
|
|
9
|
+
import "./chunk-EYP6WMFF.js";
|
|
6
10
|
import {
|
|
7
11
|
DbManager
|
|
8
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-74AHY7X6.js";
|
|
9
13
|
import {
|
|
10
14
|
GoalManager
|
|
11
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-VX662YLA.js";
|
|
12
16
|
import {
|
|
13
17
|
listCredentials,
|
|
14
18
|
loadCredential
|
|
15
|
-
} from "./chunk-
|
|
19
|
+
} from "./chunk-54SD5GBF.js";
|
|
20
|
+
import "./chunk-FX6Z3QHV.js";
|
|
16
21
|
import {
|
|
17
22
|
dbPath,
|
|
18
23
|
joworkDir
|
|
19
|
-
} from "./chunk-
|
|
20
|
-
import {
|
|
21
|
-
syncGitHub
|
|
22
|
-
} from "./chunk-LS2AJM5A.js";
|
|
24
|
+
} from "./chunk-4PIT2GZ4.js";
|
|
23
25
|
import {
|
|
24
|
-
contentHash,
|
|
25
26
|
syncFeishu,
|
|
26
27
|
syncFeishuApprovals,
|
|
27
28
|
syncFeishuDocs,
|
|
28
29
|
syncFeishuMeetings
|
|
29
|
-
} from "./chunk-
|
|
30
|
-
import
|
|
31
|
-
createId
|
|
32
|
-
} from "./chunk-JE6TOU7W.js";
|
|
30
|
+
} from "./chunk-DQW74UCN.js";
|
|
31
|
+
import "./chunk-RO3KK5RC.js";
|
|
33
32
|
import {
|
|
34
33
|
logError,
|
|
35
34
|
logInfo
|
|
36
35
|
} from "./chunk-MYDK7MWB.js";
|
|
36
|
+
import {
|
|
37
|
+
SyncContext,
|
|
38
|
+
contentHash
|
|
39
|
+
} from "./chunk-OXWWOKC7.js";
|
|
40
|
+
import {
|
|
41
|
+
createId
|
|
42
|
+
} from "./chunk-TFMF3EXE.js";
|
|
37
43
|
import {
|
|
38
44
|
__require
|
|
39
45
|
} from "./chunk-UJ4KEHGZ.js";
|
|
@@ -184,10 +190,6 @@ function indexDirectory(sqlite, dirPath, opts = {}) {
|
|
|
184
190
|
INSERT OR IGNORE INTO objects (id, source, source_type, uri, title, summary, tags, content_hash, last_synced_at, created_at)
|
|
185
191
|
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
186
192
|
`);
|
|
187
|
-
const insertBody = sqlite.prepare(`
|
|
188
|
-
INSERT OR IGNORE INTO object_bodies (object_id, content, content_type, fetched_at)
|
|
189
|
-
VALUES (?, ?, ?, ?)
|
|
190
|
-
`);
|
|
191
193
|
const insertFts = sqlite.prepare(`
|
|
192
194
|
INSERT INTO objects_fts(rowid, title, summary, tags, source, source_type, body_excerpt)
|
|
193
195
|
VALUES (?, ?, ?, ?, ?, ?, ?)
|
|
@@ -212,7 +214,6 @@ function indexDirectory(sqlite, dirPath, opts = {}) {
|
|
|
212
214
|
const tags = JSON.stringify(["local", "file", ext.replace(".", "")].filter(Boolean));
|
|
213
215
|
const sourceType = detectFileType(ext);
|
|
214
216
|
insertObj.run(id, "local", sourceType, uri, fileName, summary, tags, hash, now, now);
|
|
215
|
-
insertBody.run(id, content, mimeForExt(ext), now);
|
|
216
217
|
try {
|
|
217
218
|
const rowid = getRowid.get(id);
|
|
218
219
|
if (rowid) {
|
|
@@ -279,25 +280,6 @@ function detectFileType(ext) {
|
|
|
279
280
|
};
|
|
280
281
|
return map[ext.toLowerCase()] ?? "file";
|
|
281
282
|
}
|
|
282
|
-
function mimeForExt(ext) {
|
|
283
|
-
const map = {
|
|
284
|
-
".ts": "text/typescript",
|
|
285
|
-
".js": "text/javascript",
|
|
286
|
-
".json": "application/json",
|
|
287
|
-
".md": "text/markdown",
|
|
288
|
-
".html": "text/html",
|
|
289
|
-
".css": "text/css",
|
|
290
|
-
".py": "text/x-python",
|
|
291
|
-
".go": "text/x-go",
|
|
292
|
-
".yaml": "text/yaml",
|
|
293
|
-
".yml": "text/yaml",
|
|
294
|
-
".toml": "text/toml",
|
|
295
|
-
".xml": "text/xml",
|
|
296
|
-
".sql": "text/x-sql",
|
|
297
|
-
".sh": "text/x-shellscript"
|
|
298
|
-
};
|
|
299
|
-
return map[ext.toLowerCase()] ?? "text/plain";
|
|
300
|
-
}
|
|
301
283
|
|
|
302
284
|
// src/dashboard/server.ts
|
|
303
285
|
var DEFAULT_PORT = 18801;
|
|
@@ -490,28 +472,11 @@ async function startDashboard(opts = {}) {
|
|
|
490
472
|
};
|
|
491
473
|
return map[ext.toLowerCase()] ?? "file";
|
|
492
474
|
};
|
|
493
|
-
const mimeForExt2 = (ext) => {
|
|
494
|
-
const map = {
|
|
495
|
-
".ts": "text/typescript",
|
|
496
|
-
".js": "text/javascript",
|
|
497
|
-
".json": "application/json",
|
|
498
|
-
".md": "text/markdown",
|
|
499
|
-
".html": "text/html",
|
|
500
|
-
".css": "text/css",
|
|
501
|
-
".py": "text/x-python",
|
|
502
|
-
".go": "text/x-go"
|
|
503
|
-
};
|
|
504
|
-
return map[ext.toLowerCase()] ?? "text/plain";
|
|
505
|
-
};
|
|
506
475
|
const checkExists = sqlite.prepare("SELECT id FROM objects WHERE uri = ?");
|
|
507
476
|
const insertObj = sqlite.prepare(`
|
|
508
477
|
INSERT OR IGNORE INTO objects (id, source, source_type, uri, title, summary, tags, content_hash, last_synced_at, created_at)
|
|
509
478
|
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
510
479
|
`);
|
|
511
|
-
const insertBody = sqlite.prepare(`
|
|
512
|
-
INSERT OR IGNORE INTO object_bodies (object_id, content, content_type, fetched_at)
|
|
513
|
-
VALUES (?, ?, ?, ?)
|
|
514
|
-
`);
|
|
515
480
|
const insertFts = sqlite.prepare(`
|
|
516
481
|
INSERT INTO objects_fts(rowid, title, summary, tags, source, source_type, body_excerpt)
|
|
517
482
|
VALUES (?, ?, ?, ?, ?, ?, ?)
|
|
@@ -546,7 +511,6 @@ async function startDashboard(opts = {}) {
|
|
|
546
511
|
const tags = JSON.stringify(["local", "upload", ext.replace(".", "")].filter(Boolean));
|
|
547
512
|
const sourceType = detectFileType2(ext);
|
|
548
513
|
insertObj.run(id, "local", sourceType, uri, fileName, summary, tags, hash, now, now);
|
|
549
|
-
insertBody.run(id, file.content, mimeForExt2(ext), now);
|
|
550
514
|
try {
|
|
551
515
|
const rowid = getRowid.get(id);
|
|
552
516
|
if (rowid) {
|
|
@@ -604,30 +568,41 @@ async function startDashboard(opts = {}) {
|
|
|
604
568
|
try {
|
|
605
569
|
let result = {};
|
|
606
570
|
switch (source) {
|
|
607
|
-
case "feishu":
|
|
608
|
-
|
|
571
|
+
case "feishu": {
|
|
572
|
+
const feishuCtx = new SyncContext(sqlite, logger);
|
|
573
|
+
result = await syncFeishu(feishuCtx, cred.data, logger);
|
|
609
574
|
try {
|
|
610
|
-
await syncFeishuMeetings(
|
|
575
|
+
await syncFeishuMeetings(feishuCtx, cred.data, logger);
|
|
611
576
|
} catch {
|
|
612
577
|
}
|
|
613
578
|
try {
|
|
614
|
-
await syncFeishuDocs(
|
|
579
|
+
await syncFeishuDocs(feishuCtx, cred.data, logger);
|
|
615
580
|
} catch {
|
|
616
581
|
}
|
|
617
582
|
try {
|
|
618
|
-
await syncFeishuApprovals(
|
|
583
|
+
await syncFeishuApprovals(feishuCtx, cred.data, logger);
|
|
619
584
|
} catch {
|
|
620
585
|
}
|
|
621
586
|
break;
|
|
622
|
-
|
|
623
|
-
|
|
587
|
+
}
|
|
588
|
+
case "github": {
|
|
589
|
+
const { SyncContext: SyncContext2 } = await import("./context-ZNI3WOB7.js");
|
|
590
|
+
const ghCtx = new SyncContext2(sqlite, logger);
|
|
591
|
+
result = await syncGitHub(ghCtx, cred.data, logger);
|
|
624
592
|
break;
|
|
625
|
-
|
|
626
|
-
|
|
593
|
+
}
|
|
594
|
+
case "gitlab": {
|
|
595
|
+
const { SyncContext: GlCtx } = await import("./context-ZNI3WOB7.js");
|
|
596
|
+
const glCtx = new GlCtx(sqlite, logger);
|
|
597
|
+
result = await syncGitLab(glCtx, cred.data, logger);
|
|
627
598
|
break;
|
|
628
|
-
|
|
629
|
-
|
|
599
|
+
}
|
|
600
|
+
case "linear": {
|
|
601
|
+
const { SyncContext: LnCtx } = await import("./context-ZNI3WOB7.js");
|
|
602
|
+
const lnCtx = new LnCtx(sqlite, logger);
|
|
603
|
+
result = await syncLinear(lnCtx, cred.data, logger);
|
|
630
604
|
break;
|
|
605
|
+
}
|
|
631
606
|
default:
|
|
632
607
|
return c.json({ error: `Unknown source: ${source}` }, 400);
|
|
633
608
|
}
|
|
@@ -713,9 +688,26 @@ async function startDashboard(opts = {}) {
|
|
|
713
688
|
});
|
|
714
689
|
wss.on("connection", (ws) => {
|
|
715
690
|
clients.add(ws);
|
|
691
|
+
ws.isAlive = true;
|
|
692
|
+
ws.on("pong", () => {
|
|
693
|
+
ws.isAlive = true;
|
|
694
|
+
});
|
|
716
695
|
ws.on("close", () => clients.delete(ws));
|
|
717
696
|
ws.on("error", () => clients.delete(ws));
|
|
718
697
|
});
|
|
698
|
+
const heartbeatTimer = setInterval(() => {
|
|
699
|
+
for (const client of clients) {
|
|
700
|
+
if (client.isAlive === false) {
|
|
701
|
+
clients.delete(client);
|
|
702
|
+
client.terminate();
|
|
703
|
+
continue;
|
|
704
|
+
}
|
|
705
|
+
client.isAlive = false;
|
|
706
|
+
if (client.readyState === WebSocket.OPEN) {
|
|
707
|
+
client.ping();
|
|
708
|
+
}
|
|
709
|
+
}
|
|
710
|
+
}, 25e3);
|
|
719
711
|
let lastState = getDbState(sqlite);
|
|
720
712
|
const pollInterval = setInterval(() => {
|
|
721
713
|
try {
|
|
@@ -737,6 +729,7 @@ async function startDashboard(opts = {}) {
|
|
|
737
729
|
port,
|
|
738
730
|
close: () => {
|
|
739
731
|
clearInterval(pollInterval);
|
|
732
|
+
clearInterval(heartbeatTimer);
|
|
740
733
|
for (const client of clients) {
|
|
741
734
|
try {
|
|
742
735
|
client.close();
|
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
import {
|
|
2
2
|
DbManager
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-74AHY7X6.js";
|
|
4
4
|
import {
|
|
5
5
|
readConfig,
|
|
6
6
|
writeConfig
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-FCFZCZHR.js";
|
|
8
8
|
import {
|
|
9
9
|
listCredentials,
|
|
10
10
|
saveCredential
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-54SD5GBF.js";
|
|
12
12
|
import {
|
|
13
13
|
dbPath
|
|
14
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-4PIT2GZ4.js";
|
|
15
15
|
import "./chunk-MYDK7MWB.js";
|
|
16
16
|
import "./chunk-UJ4KEHGZ.js";
|
|
17
17
|
|
|
@@ -109,6 +109,18 @@ async function runSetupWizard() {
|
|
|
109
109
|
feishu: !!(process.env["FEISHU_APP_ID"] && process.env["FEISHU_APP_SECRET"]),
|
|
110
110
|
github: !!process.env["GITHUB_PERSONAL_ACCESS_TOKEN"]
|
|
111
111
|
};
|
|
112
|
+
const COMING_SOON_SOURCES = /* @__PURE__ */ new Set([
|
|
113
|
+
"notion",
|
|
114
|
+
"jira",
|
|
115
|
+
"confluence",
|
|
116
|
+
"google-calendar",
|
|
117
|
+
"sentry",
|
|
118
|
+
"figma",
|
|
119
|
+
"discord",
|
|
120
|
+
"trello",
|
|
121
|
+
"asana"
|
|
122
|
+
]);
|
|
123
|
+
const comingSoonSuffix = zh ? "\uFF08\u5373\u5C06\u63A8\u51FA\uFF09" : " (coming soon)";
|
|
112
124
|
const { selectedSources } = await inquirer.prompt([{
|
|
113
125
|
type: "checkbox",
|
|
114
126
|
name: "selectedSources",
|
|
@@ -149,44 +161,50 @@ async function runSetupWizard() {
|
|
|
149
161
|
value: "firebase"
|
|
150
162
|
},
|
|
151
163
|
{
|
|
152
|
-
name: zh ? "Notion\uFF08\u6587\u6863\u3001\u6570\u636E\u5E93\u3001\u77E5\u8BC6\u5E93\uFF09" : "Notion (docs, databases, wikis)",
|
|
164
|
+
name: (zh ? "Notion\uFF08\u6587\u6863\u3001\u6570\u636E\u5E93\u3001\u77E5\u8BC6\u5E93\uFF09" : "Notion (docs, databases, wikis)") + comingSoonSuffix,
|
|
153
165
|
value: "notion"
|
|
154
166
|
},
|
|
155
167
|
{
|
|
156
|
-
name: zh ? "Jira\uFF08\u4EFB\u52A1\u8FFD\u8E2A\uFF09" : "Jira (issue tracking)",
|
|
168
|
+
name: (zh ? "Jira\uFF08\u4EFB\u52A1\u8FFD\u8E2A\uFF09" : "Jira (issue tracking)") + comingSoonSuffix,
|
|
157
169
|
value: "jira"
|
|
158
170
|
},
|
|
159
171
|
{
|
|
160
|
-
name: zh ? "Confluence\uFF08\u4F01\u4E1A\u6587\u6863\uFF09" : "Confluence (enterprise wiki)",
|
|
172
|
+
name: (zh ? "Confluence\uFF08\u4F01\u4E1A\u6587\u6863\uFF09" : "Confluence (enterprise wiki)") + comingSoonSuffix,
|
|
161
173
|
value: "confluence"
|
|
162
174
|
},
|
|
163
175
|
{
|
|
164
|
-
name: zh ? "Google Calendar\uFF08\u65E5\u5386\u3001\u4F1A\u8BAE\uFF09" : "Google Calendar (events, meetings)",
|
|
176
|
+
name: (zh ? "Google Calendar\uFF08\u65E5\u5386\u3001\u4F1A\u8BAE\uFF09" : "Google Calendar (events, meetings)") + comingSoonSuffix,
|
|
165
177
|
value: "google-calendar"
|
|
166
178
|
},
|
|
167
179
|
{
|
|
168
|
-
name: zh ? "Sentry\uFF08\u9519\u8BEF\u76D1\u63A7\u3001\u5D29\u6E83\u8FFD\u8E2A\uFF09" : "Sentry (error tracking, crashes)",
|
|
180
|
+
name: (zh ? "Sentry\uFF08\u9519\u8BEF\u76D1\u63A7\u3001\u5D29\u6E83\u8FFD\u8E2A\uFF09" : "Sentry (error tracking, crashes)") + comingSoonSuffix,
|
|
169
181
|
value: "sentry"
|
|
170
182
|
},
|
|
171
183
|
{
|
|
172
|
-
name: zh ? "Figma\uFF08\u8BBE\u8BA1\u6587\u4EF6\uFF09" : "Figma (design files)",
|
|
184
|
+
name: (zh ? "Figma\uFF08\u8BBE\u8BA1\u6587\u4EF6\uFF09" : "Figma (design files)") + comingSoonSuffix,
|
|
173
185
|
value: "figma"
|
|
174
186
|
},
|
|
175
187
|
{
|
|
176
|
-
name: zh ? "Discord\uFF08\u793E\u533A\u6D88\u606F\uFF09" : "Discord (community messages)",
|
|
188
|
+
name: (zh ? "Discord\uFF08\u793E\u533A\u6D88\u606F\uFF09" : "Discord (community messages)") + comingSoonSuffix,
|
|
177
189
|
value: "discord"
|
|
178
190
|
},
|
|
179
191
|
{
|
|
180
|
-
name: zh ? "Trello\uFF08\u770B\u677F\u3001\u4EFB\u52A1\u7BA1\u7406\uFF09" : "Trello (kanban boards)",
|
|
192
|
+
name: (zh ? "Trello\uFF08\u770B\u677F\u3001\u4EFB\u52A1\u7BA1\u7406\uFF09" : "Trello (kanban boards)") + comingSoonSuffix,
|
|
181
193
|
value: "trello"
|
|
182
194
|
},
|
|
183
195
|
{
|
|
184
|
-
name: zh ? "Asana\uFF08\u9879\u76EE\u7BA1\u7406\uFF09" : "Asana (project management)",
|
|
196
|
+
name: (zh ? "Asana\uFF08\u9879\u76EE\u7BA1\u7406\uFF09" : "Asana (project management)") + comingSoonSuffix,
|
|
185
197
|
value: "asana"
|
|
186
198
|
}
|
|
187
199
|
]
|
|
188
200
|
}]);
|
|
189
201
|
for (const key of selectedSources) {
|
|
202
|
+
if (COMING_SOON_SOURCES.has(key)) {
|
|
203
|
+
console.log(zh ? `
|
|
204
|
+
${key}: \u5373\u5C06\u63A8\u51FA\uFF01\u5173\u6CE8 github.com/FluxVita/jowork \u83B7\u53D6\u66F4\u65B0\u3002` : `
|
|
205
|
+
${key}: Coming soon! Follow github.com/FluxVita/jowork for updates.`);
|
|
206
|
+
continue;
|
|
207
|
+
}
|
|
190
208
|
await connectSource(key, inquirer);
|
|
191
209
|
}
|
|
192
210
|
const connectedSources = listCredentials();
|
|
@@ -194,7 +212,7 @@ async function runSetupWizard() {
|
|
|
194
212
|
console.log("");
|
|
195
213
|
console.log(zh ? ` \u6B63\u5728\u540C\u6B65 ${connectedSources.length} \u4E2A\u6570\u636E\u6E90...` : ` Syncing ${connectedSources.length} source${connectedSources.length > 1 ? "s" : ""}...`);
|
|
196
214
|
console.log("");
|
|
197
|
-
const { runSync } = await import("./sync-
|
|
215
|
+
const { runSync } = await import("./sync-SRLFR5NA.js");
|
|
198
216
|
try {
|
|
199
217
|
await runSync(connectedSources);
|
|
200
218
|
} catch {
|
|
@@ -242,7 +260,15 @@ async function registerEngine(engine) {
|
|
|
242
260
|
cursor: "Cursor",
|
|
243
261
|
openclaw: "OpenClaw"
|
|
244
262
|
};
|
|
245
|
-
|
|
263
|
+
let mcpCommand = "jowork";
|
|
264
|
+
let mcpArgs = ["serve"];
|
|
265
|
+
try {
|
|
266
|
+
execSync("which jowork", { stdio: "ignore" });
|
|
267
|
+
} catch {
|
|
268
|
+
mcpCommand = "npx";
|
|
269
|
+
mcpArgs = ["-y", "jowork@latest", "serve"];
|
|
270
|
+
}
|
|
271
|
+
const mcpEntry = { command: mcpCommand, args: mcpArgs };
|
|
246
272
|
switch (engine) {
|
|
247
273
|
case "claude-code": {
|
|
248
274
|
const p = join(HOME, ".claude.json");
|
|
@@ -266,7 +292,12 @@ async function registerEngine(engine) {
|
|
|
266
292
|
const p = join(dir, "config.toml");
|
|
267
293
|
let c = existsSync(p) ? readFileSync(p, "utf-8") : "";
|
|
268
294
|
if (!c.includes("[mcp_servers.jowork]")) {
|
|
269
|
-
|
|
295
|
+
const argsToml = mcpArgs.map((a) => `"${a}"`).join(", ");
|
|
296
|
+
c += `
|
|
297
|
+
[mcp_servers.jowork]
|
|
298
|
+
command = "${mcpCommand}"
|
|
299
|
+
args = [${argsToml}]
|
|
300
|
+
`;
|
|
270
301
|
writeFileSync(p, c);
|
|
271
302
|
}
|
|
272
303
|
break;
|
|
@@ -547,13 +578,18 @@ async function connectSource(source, inquirer) {
|
|
|
547
578
|
break;
|
|
548
579
|
}
|
|
549
580
|
case "telegram": {
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
581
|
+
let done = false;
|
|
582
|
+
while (!done) {
|
|
583
|
+
console.log(zh ? " \u9700\u8981 Bot Token \u548C Chat ID\n \u521B\u5EFA\u65B9\u5F0F\uFF1A\u5728 Telegram \u4E2D\u641C\u7D22 @BotFather \u2192 /newbot" : " Requires Bot Token and Chat ID\n Create: search @BotFather in Telegram \u2192 /newbot");
|
|
584
|
+
console.log("");
|
|
585
|
+
const tgAnswers = await inquirer.prompt([
|
|
586
|
+
{ type: "input", name: "botToken", message: zh ? "Telegram Bot Token (123456:ABC-xxx):" : "Telegram Bot Token (123456:ABC-xxx):" },
|
|
587
|
+
{ type: "input", name: "chatId", message: zh ? "Telegram Chat ID:" : "Telegram Chat ID:" }
|
|
588
|
+
]);
|
|
589
|
+
if (!tgAnswers.botToken) {
|
|
590
|
+
done = true;
|
|
591
|
+
break;
|
|
592
|
+
}
|
|
557
593
|
console.log(zh ? " \u9A8C\u8BC1\u4E2D..." : " Verifying...");
|
|
558
594
|
try {
|
|
559
595
|
const res = await fetch(`https://api.telegram.org/bot${tgAnswers.botToken}/getMe`);
|
|
@@ -561,25 +597,48 @@ async function connectSource(source, inquirer) {
|
|
|
561
597
|
if (data.ok) {
|
|
562
598
|
saveCredential("telegram", { type: "telegram", data: { botToken: tgAnswers.botToken, chatId: tgAnswers.chatId ?? "" }, createdAt: Date.now(), updatedAt: Date.now() });
|
|
563
599
|
console.log(zh ? ` \u2713 Telegram \u5DF2\u8FDE\u63A5\uFF08Bot: @${data.result?.username}\uFF09` : ` \u2713 Telegram connected (Bot: @${data.result?.username})`);
|
|
600
|
+
done = true;
|
|
564
601
|
} else {
|
|
565
602
|
console.log(zh ? " \u2717 Telegram Bot Token \u65E0\u6548" : " \u2717 Invalid Telegram Bot Token");
|
|
603
|
+
if (!await askRetryOrSkip()) done = true;
|
|
566
604
|
}
|
|
567
605
|
} catch {
|
|
568
606
|
console.log(zh ? " \u2717 \u65E0\u6CD5\u8FDE\u63A5 Telegram API" : " \u2717 Cannot reach Telegram API");
|
|
607
|
+
if (!await askRetryOrSkip()) done = true;
|
|
569
608
|
}
|
|
570
609
|
}
|
|
571
610
|
break;
|
|
572
611
|
}
|
|
573
612
|
case "firebase": {
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
613
|
+
let done = false;
|
|
614
|
+
while (!done) {
|
|
615
|
+
console.log(zh ? " \u9700\u8981 Google Analytics API Key \u548C Property ID\n \u83B7\u53D6\u65B9\u5F0F\uFF1AGoogle Cloud Console \u2192 APIs & Services \u2192 Credentials" : " Requires Google Analytics API Key and Property ID\n Get it: Google Cloud Console \u2192 APIs & Services \u2192 Credentials");
|
|
616
|
+
console.log("");
|
|
617
|
+
const fbAnswers = await inquirer.prompt([
|
|
618
|
+
{ type: "input", name: "apiKey", message: zh ? "Firebase/GA4 API Key:" : "Firebase/GA4 API Key:" },
|
|
619
|
+
{ type: "input", name: "propertyId", message: zh ? "GA4 Property ID (\u6570\u5B57):" : "GA4 Property ID (numbers):" }
|
|
620
|
+
]);
|
|
621
|
+
if (!fbAnswers.apiKey || !fbAnswers.propertyId) {
|
|
622
|
+
done = true;
|
|
623
|
+
break;
|
|
624
|
+
}
|
|
625
|
+
console.log(zh ? " \u9A8C\u8BC1\u4E2D..." : " Verifying...");
|
|
626
|
+
try {
|
|
627
|
+
const res = await fetch(
|
|
628
|
+
`https://analyticsdata.googleapis.com/v1beta/properties/${fbAnswers.propertyId}/metadata?key=${fbAnswers.apiKey}`
|
|
629
|
+
);
|
|
630
|
+
if (res.ok) {
|
|
631
|
+
saveCredential("firebase", { type: "firebase", data: { apiKey: fbAnswers.apiKey, projectId: fbAnswers.propertyId, propertyId: fbAnswers.propertyId }, createdAt: Date.now(), updatedAt: Date.now() });
|
|
632
|
+
console.log(zh ? " \u2713 Firebase \u5DF2\u8FDE\u63A5\uFF08\u9A8C\u8BC1\u901A\u8FC7\uFF09" : " \u2713 Firebase connected (verified)");
|
|
633
|
+
done = true;
|
|
634
|
+
} else {
|
|
635
|
+
console.log(zh ? " \u2717 Firebase/GA4 \u51ED\u8BC1\u65E0\u6548" : " \u2717 Invalid Firebase/GA4 credentials");
|
|
636
|
+
if (!await askRetryOrSkip()) done = true;
|
|
637
|
+
}
|
|
638
|
+
} catch {
|
|
639
|
+
console.log(zh ? " \u2717 \u65E0\u6CD5\u8FDE\u63A5 Google Analytics API" : " \u2717 Cannot reach Google Analytics API");
|
|
640
|
+
if (!await askRetryOrSkip()) done = true;
|
|
641
|
+
}
|
|
583
642
|
}
|
|
584
643
|
break;
|
|
585
644
|
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import {
|
|
2
|
+
runSync,
|
|
3
|
+
syncCommand
|
|
4
|
+
} from "./chunk-QGHJ45PL.js";
|
|
5
|
+
import "./chunk-HENAABEL.js";
|
|
6
|
+
import "./chunk-63AMINQC.js";
|
|
7
|
+
import "./chunk-EYP6WMFF.js";
|
|
8
|
+
import "./chunk-74AHY7X6.js";
|
|
9
|
+
import "./chunk-54SD5GBF.js";
|
|
10
|
+
import "./chunk-FX6Z3QHV.js";
|
|
11
|
+
import "./chunk-4PIT2GZ4.js";
|
|
12
|
+
import "./chunk-DQW74UCN.js";
|
|
13
|
+
import "./chunk-RO3KK5RC.js";
|
|
14
|
+
import "./chunk-MYDK7MWB.js";
|
|
15
|
+
import "./chunk-OXWWOKC7.js";
|
|
16
|
+
import "./chunk-TFMF3EXE.js";
|
|
17
|
+
import "./chunk-UJ4KEHGZ.js";
|
|
18
|
+
export {
|
|
19
|
+
runSync,
|
|
20
|
+
syncCommand
|
|
21
|
+
};
|
package/dist/transport.js
CHANGED
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
import {
|
|
2
2
|
createJoWorkMcpServer
|
|
3
|
-
} from "./chunk-
|
|
4
|
-
import "./chunk-
|
|
3
|
+
} from "./chunk-ATAUWJYD.js";
|
|
4
|
+
import "./chunk-VX662YLA.js";
|
|
5
|
+
import "./chunk-54SD5GBF.js";
|
|
6
|
+
import "./chunk-FX6Z3QHV.js";
|
|
5
7
|
import {
|
|
6
8
|
dbPath
|
|
7
|
-
} from "./chunk-
|
|
8
|
-
import "./chunk-JE6TOU7W.js";
|
|
9
|
+
} from "./chunk-4PIT2GZ4.js";
|
|
9
10
|
import "./chunk-MYDK7MWB.js";
|
|
11
|
+
import "./chunk-TFMF3EXE.js";
|
|
10
12
|
import "./chunk-UJ4KEHGZ.js";
|
|
11
13
|
|
|
12
14
|
// src/mcp/transport.ts
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "jowork",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "AI Agent Infrastructure — let AI agents truly understand your work. Connect data sources, give agents awareness and goals. Local-first, one command.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "AGPL-3.0",
|