jowork 0.3.4 → 0.3.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.
@@ -4,7 +4,7 @@ import {
4
4
  import {
5
5
  formatIssue,
6
6
  formatPullRequest
7
- } from "./chunk-RO3KK5RC.js";
7
+ } from "./chunk-VWT2U6NB.js";
8
8
  import {
9
9
  logError,
10
10
  logInfo
@@ -181,7 +181,9 @@ async function syncGitLab(ctx, data, logger = defaultLogger) {
181
181
  logger.info(`Found ${projects} GitLab projects`);
182
182
  const issuesSince = ctx.getUpdatedSince("gitlab:issues");
183
183
  const mrsSince = ctx.getUpdatedSince("gitlab:mrs");
184
- for (const project of projectList) {
184
+ for (let pi = 0; pi < projectList.length; pi++) {
185
+ const project = projectList[pi];
186
+ logger.info(`Project ${pi + 1}/${projectList.length}: ${project.path_with_namespace}`);
185
187
  const encodedPath = encodeURIComponent(project.path_with_namespace);
186
188
  try {
187
189
  let issueUrl = `${baseUrl}/api/v4/projects/${encodedPath}/issues?state=all&per_page=100&order_by=updated_at`;
@@ -343,7 +345,10 @@ async function syncLinear(ctx, data, logger = defaultLogger2) {
343
345
  const since = ctx.getUpdatedSince("linear:issues");
344
346
  let hasNextPage = true;
345
347
  let endCursor = null;
348
+ let pageNum = 0;
346
349
  while (hasNextPage) {
350
+ pageNum++;
351
+ logger.info(`Fetching issues page ${pageNum}...`);
347
352
  const res = await fetch(LINEAR_API, {
348
353
  method: "POST",
349
354
  headers,
@@ -1,8 +1,7 @@
1
1
  import {
2
- formatApproval,
3
2
  formatCalendarEvent,
4
3
  formatDocument
5
- } from "./chunk-RO3KK5RC.js";
4
+ } from "./chunk-VWT2U6NB.js";
6
5
  import {
7
6
  logError,
8
7
  logInfo
@@ -52,7 +51,9 @@ async function syncFeishu(ctx, data, logger = defaultLogger) {
52
51
  const sqlite = ctx.getSqlite();
53
52
  const fileWriter = ctx.writer;
54
53
  const dayMessages = /* @__PURE__ */ new Map();
55
- for (const chat of chats) {
54
+ for (let ci = 0; ci < chats.length; ci++) {
55
+ const chat = chats[ci];
56
+ logger.info(`Chat ${ci + 1}/${chats.length}: ${chat.name ?? chat.chat_id}`);
56
57
  const cursor = ctx.getCursor(`feishu:${chat.chat_id}`);
57
58
  let pageToken = cursor?.pageToken;
58
59
  let hasMore = true;
@@ -231,100 +232,7 @@ async function syncFeishuApprovals(ctx, data, logger = defaultLogger) {
231
232
  if (!appId || !appSecret) throw new Error("Missing Feishu credentials");
232
233
  const token = await getFeishuToken(appId, appSecret);
233
234
  let approvals = 0, newObjects = 0;
234
- try {
235
- const defRes = await fetch("https://open.feishu.cn/open-apis/approval/v4/approvals?page_size=50", {
236
- headers: { Authorization: `Bearer ${token}` }
237
- });
238
- if (!defRes.ok) {
239
- if (defRes.status === 403 || defRes.status === 400) {
240
- logger.warn("Approval sync requires approval:approval:readonly scope. Add it at https://open.feishu.cn/app \u2192 Permissions");
241
- } else {
242
- logger.warn(`Approval API error: HTTP ${defRes.status}`);
243
- }
244
- return { approvals, newObjects };
245
- }
246
- const defData = await defRes.json();
247
- if (defData.code !== 0 || !defData.data?.items?.length) {
248
- if (defData.code === 99991400 || defData.code === 99991002) {
249
- logger.warn("Approval sync requires approval:approval:readonly scope. Add it at https://open.feishu.cn/app \u2192 Permissions");
250
- }
251
- return { approvals, newObjects };
252
- }
253
- const allInstances = [];
254
- for (const def of defData.data.items) {
255
- const res = await fetch("https://open.feishu.cn/open-apis/approval/v4/instances", {
256
- method: "POST",
257
- headers: { Authorization: `Bearer ${token}`, "Content-Type": "application/json" },
258
- body: JSON.stringify({ approval_code: def.approval_code, page_size: 50 })
259
- });
260
- if (!res.ok) continue;
261
- const resData2 = await res.json();
262
- if (resData2.code !== 0) continue;
263
- for (const inst of resData2.data.items ?? []) {
264
- allInstances.push({ ...inst, approval_name: def.approval_name });
265
- }
266
- await new Promise((r) => setTimeout(r, 100));
267
- }
268
- const resData = { code: 0, data: { items: allInstances } };
269
- if (resData.code !== 0 || !resData.data?.items) {
270
- logger.warn(`Approval list returned code ${resData.code}`);
271
- return { approvals, newObjects };
272
- }
273
- const items = [];
274
- for (const approval of resData.data.items) {
275
- const uri = `feishu://approval/${approval.instance_id}`;
276
- const summary = `${approval.approval_name} [${approval.status}]`;
277
- let formText = "";
278
- try {
279
- const formData = JSON.parse(approval.form || "[]");
280
- formText = Array.isArray(formData) ? formData.map((f) => `${f.name}: ${f.value}`).join("\n") : JSON.stringify(formData);
281
- } catch {
282
- formText = approval.form || "";
283
- }
284
- const body = [
285
- `Approval: ${approval.approval_name}`,
286
- `Status: ${approval.status}`,
287
- `Submitted: ${approval.start_time}`,
288
- `Completed: ${approval.end_time || "pending"}`,
289
- "",
290
- formText
291
- ].join("\n");
292
- const startTime = approval.start_time ? new Date(approval.start_time).getTime() : Date.now();
293
- let formFields = [];
294
- try {
295
- const fd = JSON.parse(approval.form || "[]");
296
- if (Array.isArray(fd)) formFields = fd;
297
- } catch {
298
- }
299
- const fileContent = formatApproval({
300
- source: "feishu",
301
- name: approval.approval_name,
302
- status: approval.status,
303
- submitter: approval.user_id || "unknown",
304
- fields: formFields,
305
- uri
306
- });
307
- items.push({
308
- source: "feishu",
309
- sourceType: "approval",
310
- uri,
311
- title: approval.approval_name,
312
- summary,
313
- tags: ["feishu", "approval", approval.status],
314
- content: body,
315
- contentType: "text/plain",
316
- createdAt: startTime,
317
- fileContent
318
- });
319
- }
320
- const result = ctx.batchUpsert(items);
321
- approvals += result.inserted;
322
- newObjects += result.inserted;
323
- } catch (err) {
324
- logger.error(`Approval sync error: ${err}`);
325
- }
326
- logger.info("Approval sync complete", { approvals, newObjects });
327
- return { approvals, newObjects };
235
+ return { approvals: 0, newObjects: 0 };
328
236
  }
329
237
  async function syncFeishuDocs(ctx, data, logger = defaultLogger) {
330
238
  const { appId, appSecret } = data;
@@ -4,7 +4,7 @@ import {
4
4
  import {
5
5
  formatIssue,
6
6
  formatPullRequest
7
- } from "./chunk-RO3KK5RC.js";
7
+ } from "./chunk-VWT2U6NB.js";
8
8
  import {
9
9
  logError,
10
10
  logInfo
@@ -85,7 +85,9 @@ async function syncGitHub(ctx, data, logger = defaultLogger) {
85
85
  logger.warn(`Bare repo sync error (non-fatal): ${err}`);
86
86
  }
87
87
  const since = ctx.getUpdatedSince("github:issues");
88
- for (const repo of repoList) {
88
+ for (let ri = 0; ri < repoList.length; ri++) {
89
+ const repo = repoList[ri];
90
+ logger.info(`Scanning repo ${ri + 1}/${repoList.length}: ${repo.full_name}`);
89
91
  try {
90
92
  let issueUrl = `${GITHUB_API}/repos/${repo.full_name}/issues?state=all&per_page=100&sort=updated&direction=asc`;
91
93
  if (since) {
@@ -2,10 +2,10 @@ import {
2
2
  linkAllUnprocessed,
3
3
  syncGitLab,
4
4
  syncLinear
5
- } from "./chunk-HENAABEL.js";
5
+ } from "./chunk-3IYVMICH.js";
6
6
  import {
7
7
  syncGitHub
8
- } from "./chunk-63AMINQC.js";
8
+ } from "./chunk-L2SHMRM6.js";
9
9
  import {
10
10
  GitManager
11
11
  } from "./chunk-EYP6WMFF.js";
@@ -26,11 +26,11 @@ import {
26
26
  syncFeishuDocs,
27
27
  syncFeishuLinks,
28
28
  syncFeishuMeetings
29
- } from "./chunk-Z6XBOSF4.js";
29
+ } from "./chunk-BLDJCUZF.js";
30
30
  import {
31
31
  formatAnalytics,
32
32
  formatMessages
33
- } from "./chunk-RO3KK5RC.js";
33
+ } from "./chunk-VWT2U6NB.js";
34
34
  import {
35
35
  logError,
36
36
  logInfo
@@ -429,8 +429,17 @@ function sourceLabel(name) {
429
429
  return `${colors[name] ?? c.white}${c.bold}${name}${c.reset}`;
430
430
  }
431
431
  function resultLine(ok, msg) {
432
+ clearProgress();
432
433
  console.log(` ${ok ? icon.ok : icon.warn} ${msg}`);
433
434
  }
435
+ function progressLine(msg) {
436
+ if (!isTTY) return;
437
+ process.stdout.write(`\r ${c.dim}\u22EF ${msg}${c.reset}\x1B[K`);
438
+ }
439
+ function clearProgress() {
440
+ if (!isTTY) return;
441
+ process.stdout.write("\r\x1B[K");
442
+ }
434
443
  function elapsed(start) {
435
444
  const ms = Date.now() - start;
436
445
  return ms < 1e3 ? `${ms}ms` : `${(ms / 1e3).toFixed(1)}s`;
@@ -483,10 +492,17 @@ async function runSync(sources) {
483
492
  const sourceStart = Date.now();
484
493
  console.log(` ${icon.sync} ${sourceLabel(source)} ${c.dim}syncing...${c.reset}`);
485
494
  const logger = {
486
- info: (_msg) => {
495
+ info: (msg) => {
496
+ progressLine(msg);
487
497
  },
488
- warn: (msg) => resultLine(false, `${c.dim}${msg}${c.reset}`),
489
- error: (msg) => console.error(` ${icon.fail} ${c.red}${msg}${c.reset}`)
498
+ warn: (msg) => {
499
+ clearProgress();
500
+ resultLine(false, `${c.dim}${msg}${c.reset}`);
501
+ },
502
+ error: (msg) => {
503
+ clearProgress();
504
+ console.error(` ${icon.fail} ${c.red}${msg}${c.reset}`);
505
+ }
490
506
  };
491
507
  try {
492
508
  switch (source) {
@@ -349,7 +349,7 @@ function createJoWorkMcpServer(opts) {
349
349
  try {
350
350
  switch (src) {
351
351
  case "feishu": {
352
- const { syncFeishu } = await import("./feishu-GOYQF2LE.js");
352
+ const { syncFeishu } = await import("./feishu-3H2ZS2MO.js");
353
353
  const { SyncContext } = await import("./context-ZNI3WOB7.js");
354
354
  const feishuCtx = new SyncContext(sqlite, { info: () => {
355
355
  }, warn: () => {
@@ -359,7 +359,7 @@ function createJoWorkMcpServer(opts) {
359
359
  break;
360
360
  }
361
361
  case "github": {
362
- const { syncGitHub } = await import("./github-PQKAYTLO.js");
362
+ const { syncGitHub } = await import("./github-YHIQJN6K.js");
363
363
  const { SyncContext } = await import("./context-ZNI3WOB7.js");
364
364
  const ghCtx = new SyncContext(sqlite, { info: () => {
365
365
  }, warn: () => {
@@ -1089,7 +1089,7 @@ ${hot.summary}
1089
1089
  try {
1090
1090
  switch (src) {
1091
1091
  case "feishu": {
1092
- const { syncFeishu } = await import("./feishu-GOYQF2LE.js");
1092
+ const { syncFeishu } = await import("./feishu-3H2ZS2MO.js");
1093
1093
  const { SyncContext } = await import("./context-ZNI3WOB7.js");
1094
1094
  const feishuCtx = new SyncContext(sqlite, { info: () => {
1095
1095
  }, warn: () => {
@@ -1100,7 +1100,7 @@ ${hot.summary}
1100
1100
  break;
1101
1101
  }
1102
1102
  case "github": {
1103
- const { syncGitHub } = await import("./github-PQKAYTLO.js");
1103
+ const { syncGitHub } = await import("./github-YHIQJN6K.js");
1104
1104
  const { SyncContext } = await import("./context-ZNI3WOB7.js");
1105
1105
  const ghCtx = new SyncContext(sqlite, { info: () => {
1106
1106
  }, warn: () => {
@@ -77,31 +77,6 @@ function formatCalendarEvent(opts) {
77
77
  ""
78
78
  ].join("\n");
79
79
  }
80
- function formatApproval(opts) {
81
- const fieldRows = opts.fields.map((f) => `| ${f.name} | ${f.value} |`).join("\n");
82
- const table = opts.fields.length > 0 ? `| Field | Value |
83
- |-------|-------|
84
- ${fieldRows}
85
- ` : "";
86
- return [
87
- "---",
88
- `source: ${opts.source}`,
89
- `type: approval`,
90
- `name: ${opts.name}`,
91
- `status: ${opts.status}`,
92
- `submitter: ${opts.submitter}`,
93
- `uri: ${opts.uri}`,
94
- "---",
95
- "",
96
- `# ${opts.name}`,
97
- "",
98
- `**Status:** ${opts.status}`,
99
- `**Submitter:** ${opts.submitter}`,
100
- "",
101
- table,
102
- ""
103
- ].join("\n");
104
- }
105
80
  function formatDocument(opts) {
106
81
  return [
107
82
  "---",
@@ -126,7 +101,6 @@ export {
126
101
  formatIssue,
127
102
  formatPullRequest,
128
103
  formatCalendarEvent,
129
- formatApproval,
130
104
  formatDocument,
131
105
  formatAnalytics
132
106
  };
package/dist/cli.js CHANGED
@@ -5,15 +5,15 @@ import {
5
5
  syncCommand,
6
6
  syncFirebase,
7
7
  syncPostHog
8
- } from "./chunk-RT242G6H.js";
8
+ } from "./chunk-LMK2HS56.js";
9
9
  import {
10
10
  linkAllUnprocessed,
11
11
  syncGitLab,
12
12
  syncLinear
13
- } from "./chunk-HENAABEL.js";
13
+ } from "./chunk-3IYVMICH.js";
14
14
  import {
15
15
  syncGitHub
16
- } from "./chunk-63AMINQC.js";
16
+ } from "./chunk-L2SHMRM6.js";
17
17
  import {
18
18
  GitManager
19
19
  } from "./chunk-EYP6WMFF.js";
@@ -23,7 +23,7 @@ import {
23
23
  import {
24
24
  PLUGIN_REGISTRY,
25
25
  createJoWorkMcpServer
26
- } from "./chunk-USSUIN3A.js";
26
+ } from "./chunk-VKP57MQJ.js";
27
27
  import {
28
28
  GoalManager
29
29
  } from "./chunk-VX662YLA.js";
@@ -53,8 +53,8 @@ import {
53
53
  syncFeishuDocs,
54
54
  syncFeishuLinks,
55
55
  syncFeishuMeetings
56
- } from "./chunk-Z6XBOSF4.js";
57
- import "./chunk-RO3KK5RC.js";
56
+ } from "./chunk-BLDJCUZF.js";
57
+ import "./chunk-VWT2U6NB.js";
58
58
  import {
59
59
  logError,
60
60
  logInfo
@@ -102,7 +102,7 @@ function initCommand(program2) {
102
102
  default: true
103
103
  }]);
104
104
  if (continueSetup) {
105
- const { runSetupWizard } = await import("./setup-CQ5L3SHD.js");
105
+ const { runSetupWizard } = await import("./setup-W6VQUVQU.js");
106
106
  await runSetupWizard();
107
107
  } else {
108
108
  console.log("");
@@ -2102,7 +2102,7 @@ function dashboardCommand(program2) {
2102
2102
  console.error("Error: JoWork not initialized. Run `jowork init` first.");
2103
2103
  process.exit(1);
2104
2104
  }
2105
- const { startDashboard } = await import("./server-YXI4Z4MY.js");
2105
+ const { startDashboard } = await import("./server-Y3RNHAJ2.js");
2106
2106
  const port = opts.port ? parseInt(opts.port, 10) : void 0;
2107
2107
  const dashboard = await startDashboard({ port });
2108
2108
  const url = `http://127.0.0.1:${dashboard.port}`;
@@ -2793,7 +2793,7 @@ function isInstalled(packageName) {
2793
2793
  // src/cli.ts
2794
2794
  process.env["I18NEXT_DISABLE_BANNER"] = "1";
2795
2795
  var program = new Command();
2796
- program.name("jowork").description("AI Agent Infrastructure \u2014 let AI agents truly understand your work").version("0.3.4");
2796
+ program.name("jowork").description("AI Agent Infrastructure \u2014 let AI agents truly understand your work").version("0.3.6");
2797
2797
  initCommand(program);
2798
2798
  serveCommand(program);
2799
2799
  registerCommand(program);
@@ -2820,7 +2820,7 @@ program.action(async () => {
2820
2820
  const config = readConfig2();
2821
2821
  if (!config.initialized || !existsSync18(dbPath2())) {
2822
2822
  if (process.stdin.isTTY) {
2823
- const { runSetupWizard } = await import("./setup-CQ5L3SHD.js");
2823
+ const { runSetupWizard } = await import("./setup-W6VQUVQU.js");
2824
2824
  await runSetupWizard();
2825
2825
  } else {
2826
2826
  console.log("JoWork is not initialized. Run `jowork init` in an interactive terminal.");
@@ -5,8 +5,8 @@ import {
5
5
  syncFeishuDocs,
6
6
  syncFeishuLinks,
7
7
  syncFeishuMeetings
8
- } from "./chunk-Z6XBOSF4.js";
9
- import "./chunk-RO3KK5RC.js";
8
+ } from "./chunk-BLDJCUZF.js";
9
+ import "./chunk-VWT2U6NB.js";
10
10
  import "./chunk-MYDK7MWB.js";
11
11
  import {
12
12
  contentHash
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  syncGitHub
3
- } from "./chunk-63AMINQC.js";
3
+ } from "./chunk-L2SHMRM6.js";
4
4
  import "./chunk-EYP6WMFF.js";
5
5
  import "./chunk-4PIT2GZ4.js";
6
- import "./chunk-RO3KK5RC.js";
6
+ import "./chunk-VWT2U6NB.js";
7
7
  import "./chunk-MYDK7MWB.js";
8
8
  import "./chunk-UJ4KEHGZ.js";
9
9
  export {
@@ -2,10 +2,10 @@ import {
2
2
  linkAllUnprocessed,
3
3
  syncGitLab,
4
4
  syncLinear
5
- } from "./chunk-HENAABEL.js";
5
+ } from "./chunk-3IYVMICH.js";
6
6
  import {
7
7
  syncGitHub
8
- } from "./chunk-63AMINQC.js";
8
+ } from "./chunk-L2SHMRM6.js";
9
9
  import "./chunk-EYP6WMFF.js";
10
10
  import {
11
11
  DbManager
@@ -27,8 +27,8 @@ import {
27
27
  syncFeishuApprovals,
28
28
  syncFeishuDocs,
29
29
  syncFeishuMeetings
30
- } from "./chunk-Z6XBOSF4.js";
31
- import "./chunk-RO3KK5RC.js";
30
+ } from "./chunk-BLDJCUZF.js";
31
+ import "./chunk-VWT2U6NB.js";
32
32
  import {
33
33
  logError,
34
34
  logInfo
@@ -212,7 +212,7 @@ async function runSetupWizard() {
212
212
  console.log("");
213
213
  console.log(zh ? ` \u6B63\u5728\u540C\u6B65 ${connectedSources.length} \u4E2A\u6570\u636E\u6E90...` : ` Syncing ${connectedSources.length} source${connectedSources.length > 1 ? "s" : ""}...`);
214
214
  console.log("");
215
- const { runSync } = await import("./sync-KUJT3PN5.js");
215
+ const { runSync } = await import("./sync-CIVY3XE6.js");
216
216
  try {
217
217
  await runSync(connectedSources);
218
218
  } catch {
@@ -1,16 +1,16 @@
1
1
  import {
2
2
  runSync,
3
3
  syncCommand
4
- } from "./chunk-RT242G6H.js";
5
- import "./chunk-HENAABEL.js";
6
- import "./chunk-63AMINQC.js";
4
+ } from "./chunk-LMK2HS56.js";
5
+ import "./chunk-3IYVMICH.js";
6
+ import "./chunk-L2SHMRM6.js";
7
7
  import "./chunk-EYP6WMFF.js";
8
8
  import "./chunk-74AHY7X6.js";
9
9
  import "./chunk-54SD5GBF.js";
10
10
  import "./chunk-FX6Z3QHV.js";
11
11
  import "./chunk-4PIT2GZ4.js";
12
- import "./chunk-Z6XBOSF4.js";
13
- import "./chunk-RO3KK5RC.js";
12
+ import "./chunk-BLDJCUZF.js";
13
+ import "./chunk-VWT2U6NB.js";
14
14
  import "./chunk-MYDK7MWB.js";
15
15
  import "./chunk-OXWWOKC7.js";
16
16
  import "./chunk-TFMF3EXE.js";
package/dist/transport.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  createJoWorkMcpServer
3
- } from "./chunk-USSUIN3A.js";
3
+ } from "./chunk-VKP57MQJ.js";
4
4
  import "./chunk-VX662YLA.js";
5
5
  import "./chunk-54SD5GBF.js";
6
6
  import "./chunk-FX6Z3QHV.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "jowork",
3
- "version": "0.3.4",
3
+ "version": "0.3.6",
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",