open-walnut 0.4.2 → 0.4.4
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 +1 -1
- package/dist/cli.js +247 -245
- package/dist/integrations/calendar/index.js +42 -36
- package/dist/integrations/jira/index.js +100 -78
- package/dist/integrations/ms-todo/index.js +94 -72
- package/dist/web/server.js +295 -293
- package/dist/web/static/assets/{OfficePreview-CEHO0xkd.js → OfficePreview-BlfHJAnI.js} +2 -2
- package/dist/web/static/assets/{docx-preview-CuZwjAMS.js → docx-preview-Cxj6saWk.js} +1 -1
- package/dist/web/static/assets/{index-ccs5s80D.js → index-7Z89132A.js} +1 -1
- package/dist/web/static/assets/{index-DLjK8dGE.js → index-8m4fXWae.js} +1 -1
- package/dist/web/static/assets/{index-BFF_G72i.js → index-B5OE08Hi.js} +276 -276
- package/dist/web/static/assets/{index-DR-LSqAg.js → index-BX-Q5nDs.js} +1 -1
- package/dist/web/static/assets/{index-DXtp_ZWh.js → index-BcvUZ0V6.js} +1 -1
- package/dist/web/static/assets/{index-D1dpOEzW.js → index-Bg08t19u.js} +1 -1
- package/dist/web/static/assets/{index-BRLxNhyy.js → index-BrQxDmgD.js} +1 -1
- package/dist/web/static/assets/{index-DtRwkh8J.js → index-C-ZIMUgb.js} +1 -1
- package/dist/web/static/assets/{index-DrWzb338.js → index-CJsj6NRK.js} +1 -1
- package/dist/web/static/assets/{index-unnPilnK.js → index-CPLhHJLE.js} +1 -1
- package/dist/web/static/assets/index-Cqfkxb49.css +32 -0
- package/dist/web/static/assets/{index-BBjg7m-_.js → index-DESxqmea.js} +1 -1
- package/dist/web/static/assets/{index-0MyC-yGG.js → index-Db4kYRIN.js} +1 -1
- package/dist/web/static/assets/{index-DOXm2Aye.js → index-Dmxn8BJB.js} +1 -1
- package/dist/web/static/assets/{index-C2YGUYGS.js → index-HOURQwyW.js} +1 -1
- package/dist/web/static/assets/{index-Bqg4_WEG.js → index-QcYRs4hO.js} +1 -1
- package/dist/web/static/assets/{index-DAOPV34I.js → index-i813E9y_.js} +1 -1
- package/dist/web/static/assets/{index-D9qPPm7h.js → index-ntIs-QCy.js} +1 -1
- package/dist/web/static/assets/{index-mWEwJcqw.js → index-qbtGSfLJ.js} +1 -1
- package/dist/web/static/assets/{jszip.min-DYFwy4PE.js → jszip.min-CjTDoW5q.js} +1 -1
- package/dist/web/static/assets/{pptx-preview.es-eu2nX9JC.js → pptx-preview.es-CW9hHNwC.js} +1 -1
- package/dist/web/static/index.html +2 -2
- package/package.json +1 -1
- package/dist/web/static/assets/index-DeYCGmOR.css +0 -32
|
@@ -816,7 +816,7 @@ var init_fs = __esm({
|
|
|
816
816
|
});
|
|
817
817
|
|
|
818
818
|
// src/core/types.ts
|
|
819
|
-
var VALID_PRIORITIES, PIN_TIER_POLICY, SESSION_MODELS, SESSION_MODEL_CLI_MAP, VALID_SESSION_MODEL_IDS, SESSION_EFFORT_IDS, VALID_SESSION_EFFORT_IDS, SESSION_MODES, SESSION_MODE_IDS, VALID_SESSION_MODE_IDS, SESSION_MODE_CLI_MAP, SESSION_MODE_LABELS
|
|
819
|
+
var VALID_PRIORITIES, PIN_TIER_POLICY, SESSION_MODELS, SESSION_MODEL_CLI_MAP, VALID_SESSION_MODEL_IDS, SESSION_EFFORT_IDS, VALID_SESSION_EFFORT_IDS, SESSION_MODES, SESSION_MODE_IDS, VALID_SESSION_MODE_IDS, SESSION_MODE_CLI_MAP, SESSION_MODE_LABELS;
|
|
820
820
|
var init_types = __esm({
|
|
821
821
|
"src/core/types.ts"() {
|
|
822
822
|
"use strict";
|
|
@@ -868,7 +868,6 @@ var init_types = __esm({
|
|
|
868
868
|
VALID_SESSION_MODE_IDS = new Set(SESSION_MODE_IDS);
|
|
869
869
|
SESSION_MODE_CLI_MAP = Object.fromEntries(SESSION_MODES.map((m) => [m.id, m.cli]));
|
|
870
870
|
SESSION_MODE_LABELS = Object.fromEntries(SESSION_MODES.map((m) => [m.id, m.label]));
|
|
871
|
-
DEFAULT_AGENT_ENGINE_PROVIDER = "claude-code";
|
|
872
871
|
}
|
|
873
872
|
});
|
|
874
873
|
|
|
@@ -1386,10 +1385,32 @@ var init_model_catalog = __esm({
|
|
|
1386
1385
|
}
|
|
1387
1386
|
});
|
|
1388
1387
|
|
|
1389
|
-
// src/core/
|
|
1390
|
-
import
|
|
1391
|
-
import
|
|
1388
|
+
// src/core/claude-cli-detect.ts
|
|
1389
|
+
import { execFileSync } from "child_process";
|
|
1390
|
+
import fs5 from "fs";
|
|
1392
1391
|
import os3 from "os";
|
|
1392
|
+
import path6 from "path";
|
|
1393
|
+
var _CLAUDE_CREDENTIALS_HOME;
|
|
1394
|
+
var init_claude_cli_detect = __esm({
|
|
1395
|
+
"src/core/claude-cli-detect.ts"() {
|
|
1396
|
+
"use strict";
|
|
1397
|
+
init_constants();
|
|
1398
|
+
_CLAUDE_CREDENTIALS_HOME = os3.homedir();
|
|
1399
|
+
}
|
|
1400
|
+
});
|
|
1401
|
+
|
|
1402
|
+
// src/agent/providers/default-provider.ts
|
|
1403
|
+
var init_default_provider = __esm({
|
|
1404
|
+
"src/agent/providers/default-provider.ts"() {
|
|
1405
|
+
"use strict";
|
|
1406
|
+
init_claude_cli_detect();
|
|
1407
|
+
}
|
|
1408
|
+
});
|
|
1409
|
+
|
|
1410
|
+
// src/core/ssh-config-scanner.ts
|
|
1411
|
+
import fs6 from "fs/promises";
|
|
1412
|
+
import path7 from "path";
|
|
1413
|
+
import os4 from "os";
|
|
1393
1414
|
function isGitServerHost(h) {
|
|
1394
1415
|
if (h.user === "git") return true;
|
|
1395
1416
|
const gitPrefix = /^(git|github|gitlab|bitbucket|codecommit|ssh\.github)\./i;
|
|
@@ -1405,10 +1426,10 @@ function shortLabelForFqdn(hostname) {
|
|
|
1405
1426
|
return `${first.slice(0, 12)}\u2026${first.slice(-8)}`;
|
|
1406
1427
|
}
|
|
1407
1428
|
async function scanSshConfig(configPath) {
|
|
1408
|
-
const sshConfigPath = configPath ??
|
|
1429
|
+
const sshConfigPath = configPath ?? path7.join(os4.homedir(), ".ssh", "config");
|
|
1409
1430
|
let mtimeMs2;
|
|
1410
1431
|
try {
|
|
1411
|
-
mtimeMs2 = (await
|
|
1432
|
+
mtimeMs2 = (await fs6.stat(sshConfigPath)).mtimeMs;
|
|
1412
1433
|
} catch {
|
|
1413
1434
|
return /* @__PURE__ */ new Map();
|
|
1414
1435
|
}
|
|
@@ -1421,7 +1442,7 @@ async function scanSshConfig(configPath) {
|
|
|
1421
1442
|
async function parseSshConfigFile(sshConfigPath) {
|
|
1422
1443
|
const discovered = /* @__PURE__ */ new Map();
|
|
1423
1444
|
try {
|
|
1424
|
-
const content = await
|
|
1445
|
+
const content = await fs6.readFile(sshConfigPath, "utf-8");
|
|
1425
1446
|
const lines = content.split("\n");
|
|
1426
1447
|
let currentHost = null;
|
|
1427
1448
|
for (const rawLine of lines) {
|
|
@@ -1508,7 +1529,7 @@ var init_ssh_config_scanner = __esm({
|
|
|
1508
1529
|
});
|
|
1509
1530
|
|
|
1510
1531
|
// src/core/config-manager.ts
|
|
1511
|
-
import
|
|
1532
|
+
import fs7 from "fs/promises";
|
|
1512
1533
|
import yaml from "js-yaml";
|
|
1513
1534
|
function migrateConfigToProjectOnly(config) {
|
|
1514
1535
|
let changed = false;
|
|
@@ -1581,13 +1602,13 @@ function migrateConfigToProjectOnly(config) {
|
|
|
1581
1602
|
}
|
|
1582
1603
|
async function readRawConfigContent() {
|
|
1583
1604
|
try {
|
|
1584
|
-
const primary = await
|
|
1605
|
+
const primary = await fs7.readFile(CONFIG_FILE, "utf-8");
|
|
1585
1606
|
if (primary.trim()) return primary;
|
|
1586
1607
|
throw new Error("config.yaml is empty");
|
|
1587
1608
|
} catch (primaryErr) {
|
|
1588
1609
|
let backup;
|
|
1589
1610
|
try {
|
|
1590
|
-
backup = await
|
|
1611
|
+
backup = await fs7.readFile(CONFIG_BACKUP_FILE, "utf-8");
|
|
1591
1612
|
} catch {
|
|
1592
1613
|
return null;
|
|
1593
1614
|
}
|
|
@@ -1597,7 +1618,7 @@ async function readRawConfigContent() {
|
|
|
1597
1618
|
backup: CONFIG_BACKUP_FILE
|
|
1598
1619
|
});
|
|
1599
1620
|
try {
|
|
1600
|
-
await
|
|
1621
|
+
await fs7.writeFile(CONFIG_FILE, backup, "utf-8");
|
|
1601
1622
|
} catch {
|
|
1602
1623
|
}
|
|
1603
1624
|
return backup;
|
|
@@ -1606,10 +1627,10 @@ async function readRawConfigContent() {
|
|
|
1606
1627
|
async function writeFileAtomic2(filePath, content) {
|
|
1607
1628
|
const tmp = `${filePath}.tmp-${process.pid}-${Date.now().toString(36)}`;
|
|
1608
1629
|
try {
|
|
1609
|
-
await
|
|
1610
|
-
await
|
|
1630
|
+
await fs7.writeFile(tmp, content, "utf-8");
|
|
1631
|
+
await fs7.rename(tmp, filePath);
|
|
1611
1632
|
} catch (err) {
|
|
1612
|
-
await
|
|
1633
|
+
await fs7.rm(tmp, { force: true }).catch(() => {
|
|
1613
1634
|
});
|
|
1614
1635
|
throw err;
|
|
1615
1636
|
}
|
|
@@ -1743,7 +1764,7 @@ async function seedConfigDefaults() {
|
|
|
1743
1764
|
const config = await getConfig();
|
|
1744
1765
|
let needsWrite = false;
|
|
1745
1766
|
try {
|
|
1746
|
-
const raw = await
|
|
1767
|
+
const raw = await fs7.readFile(CONFIG_FILE, "utf-8");
|
|
1747
1768
|
if (!raw.includes("available_models")) {
|
|
1748
1769
|
needsWrite = true;
|
|
1749
1770
|
}
|
|
@@ -1771,6 +1792,7 @@ var init_config_manager = __esm({
|
|
|
1771
1792
|
init_constants();
|
|
1772
1793
|
init_types();
|
|
1773
1794
|
init_model_catalog();
|
|
1795
|
+
init_default_provider();
|
|
1774
1796
|
init_ssh_config_scanner();
|
|
1775
1797
|
DEFAULT_CONFIG = {
|
|
1776
1798
|
version: 1,
|
|
@@ -1782,12 +1804,12 @@ var init_config_manager = __esm({
|
|
|
1782
1804
|
// so this never re-routes an established setup.
|
|
1783
1805
|
defaults: { priority: "none", platform: "local" },
|
|
1784
1806
|
provider: { type: "claude-code" },
|
|
1785
|
-
// Which ENGINE answers a Personal AI chat turn
|
|
1786
|
-
//
|
|
1787
|
-
//
|
|
1788
|
-
//
|
|
1789
|
-
//
|
|
1790
|
-
agent: {
|
|
1807
|
+
// Which ENGINE answers a Personal AI chat turn is NOT defaulted here: it follows
|
|
1808
|
+
// the AI provider (Settings → AI Provider) — see resolveAgentEngineProvider().
|
|
1809
|
+
// getConfig() spreads the parsed file OVER these defaults at the TOP level, so
|
|
1810
|
+
// anything put in this object is dropped by any config.yaml with an `agent:`
|
|
1811
|
+
// section; the resolver is what actually applies the rule.
|
|
1812
|
+
agent: {}
|
|
1791
1813
|
};
|
|
1792
1814
|
CONFIG_BACKUP_FILE = `${CONFIG_FILE}.bak`;
|
|
1793
1815
|
writeLock = Promise.resolve();
|
|
@@ -2126,7 +2148,7 @@ var init_format = __esm({
|
|
|
2126
2148
|
// src/utils/file-ops.ts
|
|
2127
2149
|
import crypto4 from "crypto";
|
|
2128
2150
|
import fsp4 from "fs/promises";
|
|
2129
|
-
import
|
|
2151
|
+
import path8 from "path";
|
|
2130
2152
|
var MAX_READ_SIZE;
|
|
2131
2153
|
var init_file_ops = __esm({
|
|
2132
2154
|
"src/utils/file-ops.ts"() {
|
|
@@ -2137,17 +2159,17 @@ var init_file_ops = __esm({
|
|
|
2137
2159
|
});
|
|
2138
2160
|
|
|
2139
2161
|
// src/core/memory-file.ts
|
|
2140
|
-
import
|
|
2141
|
-
import
|
|
2162
|
+
import fs8 from "fs";
|
|
2163
|
+
import path9 from "path";
|
|
2142
2164
|
function resolveMemoryPath(agentId) {
|
|
2143
2165
|
if (!agentId || agentId === "general") return MEMORY_FILE;
|
|
2144
|
-
return
|
|
2166
|
+
return path9.join(agentMemoryDir(agentId), "MEMORY.md");
|
|
2145
2167
|
}
|
|
2146
2168
|
function ensureMemoryFile(agentId) {
|
|
2147
2169
|
const filePath = resolveMemoryPath(agentId);
|
|
2148
|
-
if (
|
|
2149
|
-
|
|
2150
|
-
|
|
2170
|
+
if (fs8.existsSync(filePath)) return;
|
|
2171
|
+
fs8.mkdirSync(path9.dirname(filePath), { recursive: true });
|
|
2172
|
+
fs8.writeFileSync(filePath, DEFAULT_TEMPLATE, "utf-8");
|
|
2151
2173
|
}
|
|
2152
2174
|
var DEFAULT_TEMPLATE;
|
|
2153
2175
|
var init_memory_file = __esm({
|
|
@@ -2167,15 +2189,15 @@ description: >
|
|
|
2167
2189
|
|
|
2168
2190
|
// src/core/tmp-sweep.ts
|
|
2169
2191
|
import fsp5 from "fs/promises";
|
|
2170
|
-
import
|
|
2192
|
+
import path10 from "path";
|
|
2171
2193
|
function sweepDirs() {
|
|
2172
2194
|
return [
|
|
2173
2195
|
WALNUT_HOME,
|
|
2174
2196
|
SYNC_DIR,
|
|
2175
|
-
|
|
2176
|
-
|
|
2197
|
+
path10.join(WALNUT_HOME, "sessions"),
|
|
2198
|
+
path10.join(WALNUT_HOME, "sessions", "transcripts"),
|
|
2177
2199
|
TASKS_DIR,
|
|
2178
|
-
|
|
2200
|
+
path10.join(TASKS_DIR, "outbox"),
|
|
2179
2201
|
CONVERSATIONS_DIR,
|
|
2180
2202
|
MEMORY_DIR,
|
|
2181
2203
|
DAILY_DIR,
|
|
@@ -2196,7 +2218,7 @@ async function sweepOrphanAtomicTmpFiles() {
|
|
|
2196
2218
|
const entries = await fsp5.readdir(dir, { withFileTypes: true });
|
|
2197
2219
|
for (const entry of entries) {
|
|
2198
2220
|
if (!entry.isFile() || !ORPHAN_RE.test(entry.name)) continue;
|
|
2199
|
-
const full =
|
|
2221
|
+
const full = path10.join(dir, entry.name);
|
|
2200
2222
|
try {
|
|
2201
2223
|
const st = await fsp5.stat(full);
|
|
2202
2224
|
if (st.mtimeMs > cutoff) continue;
|
|
@@ -2229,10 +2251,10 @@ var init_tmp_sweep = __esm({
|
|
|
2229
2251
|
|
|
2230
2252
|
// src/core/init.ts
|
|
2231
2253
|
import fsp6 from "fs/promises";
|
|
2232
|
-
import
|
|
2254
|
+
import fs9 from "fs";
|
|
2233
2255
|
async function migrateLegacyMemoryFile() {
|
|
2234
2256
|
try {
|
|
2235
|
-
if (
|
|
2257
|
+
if (fs9.existsSync(LEGACY_MEMORY_FILE) && !fs9.existsSync(MEMORY_FILE)) {
|
|
2236
2258
|
await fsp6.rename(LEGACY_MEMORY_FILE, MEMORY_FILE);
|
|
2237
2259
|
log.memory.info("Migrated MEMORY.md into memory/ folder", { from: LEGACY_MEMORY_FILE, to: MEMORY_FILE });
|
|
2238
2260
|
}
|
|
@@ -2449,15 +2471,15 @@ var init_integration_registry = __esm({
|
|
|
2449
2471
|
|
|
2450
2472
|
// src/core/task-db.ts
|
|
2451
2473
|
import Database from "better-sqlite3";
|
|
2452
|
-
import
|
|
2453
|
-
import
|
|
2474
|
+
import fs10 from "fs";
|
|
2475
|
+
import path11 from "path";
|
|
2454
2476
|
import yaml2 from "js-yaml";
|
|
2455
2477
|
function getDb() {
|
|
2456
2478
|
if (db) return db;
|
|
2457
2479
|
if (initAttempted) throw initError;
|
|
2458
2480
|
initAttempted = true;
|
|
2459
2481
|
try {
|
|
2460
|
-
|
|
2482
|
+
fs10.mkdirSync(path11.dirname(TASK_DB_PATH), { recursive: true });
|
|
2461
2483
|
const handle = new Database(TASK_DB_PATH);
|
|
2462
2484
|
handle.pragma("journal_mode = WAL");
|
|
2463
2485
|
handle.pragma("busy_timeout = 5000");
|
|
@@ -2675,8 +2697,8 @@ function migrateToProjectOnly(handle) {
|
|
|
2675
2697
|
}
|
|
2676
2698
|
try {
|
|
2677
2699
|
handle.pragma("wal_checkpoint(TRUNCATE)");
|
|
2678
|
-
if (!
|
|
2679
|
-
|
|
2700
|
+
if (!fs10.existsSync(TASK_DB_PRE_V5_BACKUP_PATH)) {
|
|
2701
|
+
fs10.copyFileSync(TASK_DB_PATH, TASK_DB_PRE_V5_BACKUP_PATH);
|
|
2680
2702
|
log.task.info("task-db v5: wrote pre-migration backup", { path: TASK_DB_PRE_V5_BACKUP_PATH });
|
|
2681
2703
|
}
|
|
2682
2704
|
} catch (err) {
|
|
@@ -3103,7 +3125,7 @@ var init_task_db = __esm({
|
|
|
3103
3125
|
init_constants();
|
|
3104
3126
|
init_logging();
|
|
3105
3127
|
init_phase();
|
|
3106
|
-
TASK_DB_PATH =
|
|
3128
|
+
TASK_DB_PATH = path11.join(TASKS_DIR, "tasks.sqlite");
|
|
3107
3129
|
EXPLICIT_TASK_COLUMNS = [
|
|
3108
3130
|
"id",
|
|
3109
3131
|
"title",
|
|
@@ -3264,8 +3286,8 @@ var init_task_db = __esm({
|
|
|
3264
3286
|
});
|
|
3265
3287
|
|
|
3266
3288
|
// src/core/task-db-migration.ts
|
|
3267
|
-
import
|
|
3268
|
-
import
|
|
3289
|
+
import fs11 from "fs";
|
|
3290
|
+
import path12 from "path";
|
|
3269
3291
|
import yaml3 from "js-yaml";
|
|
3270
3292
|
async function runMigrationIfNeeded() {
|
|
3271
3293
|
const db2 = getDb();
|
|
@@ -3276,7 +3298,7 @@ async function runMigrationIfNeeded() {
|
|
|
3276
3298
|
if (existing.n > 0) {
|
|
3277
3299
|
return { migrated: false, count: existing.n };
|
|
3278
3300
|
}
|
|
3279
|
-
if (!
|
|
3301
|
+
if (!fs11.existsSync(TASKS_FILE)) {
|
|
3280
3302
|
return { migrated: false, count: 0 };
|
|
3281
3303
|
}
|
|
3282
3304
|
const store = await readJsonFile(TASKS_FILE, { version: 1, tasks: [] });
|
|
@@ -3433,9 +3455,9 @@ async function runMigrationIfNeeded() {
|
|
|
3433
3455
|
}
|
|
3434
3456
|
const after = db2.prepare("SELECT COUNT(*) AS n FROM tasks").get();
|
|
3435
3457
|
const count = after.n;
|
|
3436
|
-
const backupPath =
|
|
3458
|
+
const backupPath = path12.join(path12.dirname(TASKS_FILE), "tasks.json.migrated-from-json.backup");
|
|
3437
3459
|
try {
|
|
3438
|
-
|
|
3460
|
+
fs11.copyFileSync(TASKS_FILE, backupPath);
|
|
3439
3461
|
} catch (err) {
|
|
3440
3462
|
log.task.warn("task-db migration: backup copy failed (non-fatal)", {
|
|
3441
3463
|
path: backupPath,
|
|
@@ -3459,9 +3481,9 @@ var init_task_db_migration = __esm({
|
|
|
3459
3481
|
});
|
|
3460
3482
|
|
|
3461
3483
|
// src/core/memory-dir-migration.ts
|
|
3462
|
-
import
|
|
3484
|
+
import fs12 from "fs";
|
|
3463
3485
|
import fsp7 from "fs/promises";
|
|
3464
|
-
import
|
|
3486
|
+
import path13 from "path";
|
|
3465
3487
|
function bodyOf(content) {
|
|
3466
3488
|
const fm = content.match(/^---\r?\n[\s\S]*?\r?\n---\r?\n?/);
|
|
3467
3489
|
return fm ? content.slice(fm[0].length) : content;
|
|
@@ -3479,7 +3501,7 @@ ${legacyBody}
|
|
|
3479
3501
|
}
|
|
3480
3502
|
function mtimeMs(file) {
|
|
3481
3503
|
try {
|
|
3482
|
-
return
|
|
3504
|
+
return fs12.statSync(file).mtimeMs;
|
|
3483
3505
|
} catch {
|
|
3484
3506
|
return 0;
|
|
3485
3507
|
}
|
|
@@ -3488,24 +3510,24 @@ function findCandidates(root) {
|
|
|
3488
3510
|
const out = [];
|
|
3489
3511
|
let level1;
|
|
3490
3512
|
try {
|
|
3491
|
-
level1 =
|
|
3513
|
+
level1 = fs12.readdirSync(root, { withFileTypes: true });
|
|
3492
3514
|
} catch {
|
|
3493
3515
|
return out;
|
|
3494
3516
|
}
|
|
3495
3517
|
for (const cat of level1) {
|
|
3496
3518
|
if (!cat.isDirectory()) continue;
|
|
3497
|
-
const catDir =
|
|
3498
|
-
if (
|
|
3519
|
+
const catDir = path13.join(root, cat.name);
|
|
3520
|
+
if (fs12.existsSync(path13.join(catDir, MEMORY_FILE_NAME))) continue;
|
|
3499
3521
|
let level2;
|
|
3500
3522
|
try {
|
|
3501
|
-
level2 =
|
|
3523
|
+
level2 = fs12.readdirSync(catDir, { withFileTypes: true });
|
|
3502
3524
|
} catch {
|
|
3503
3525
|
continue;
|
|
3504
3526
|
}
|
|
3505
3527
|
for (const proj of level2) {
|
|
3506
3528
|
if (!proj.isDirectory()) continue;
|
|
3507
|
-
const sourceDir =
|
|
3508
|
-
if (!
|
|
3529
|
+
const sourceDir = path13.join(catDir, proj.name);
|
|
3530
|
+
if (!fs12.existsSync(path13.join(sourceDir, MEMORY_FILE_NAME))) continue;
|
|
3509
3531
|
out.push({ category: cat.name, project: proj.name, sourceDir });
|
|
3510
3532
|
}
|
|
3511
3533
|
}
|
|
@@ -3519,11 +3541,11 @@ async function drainDir(from, to) {
|
|
|
3519
3541
|
return;
|
|
3520
3542
|
}
|
|
3521
3543
|
for (const name of entries) {
|
|
3522
|
-
const target =
|
|
3523
|
-
if (
|
|
3524
|
-
await fsp7.rename(
|
|
3544
|
+
const target = path13.join(to, name);
|
|
3545
|
+
if (fs12.existsSync(target)) continue;
|
|
3546
|
+
await fsp7.rename(path13.join(from, name), target).catch((err) => {
|
|
3525
3547
|
log.memory.warn("memory-dir migration: entry move failed", {
|
|
3526
|
-
from:
|
|
3548
|
+
from: path13.join(from, name),
|
|
3527
3549
|
to: target,
|
|
3528
3550
|
error: String(err)
|
|
3529
3551
|
});
|
|
@@ -3535,23 +3557,23 @@ async function drainDir(from, to) {
|
|
|
3535
3557
|
async function migrateProjectMemoryDirs() {
|
|
3536
3558
|
const result = { ran: false, moved: 0, merged: 0 };
|
|
3537
3559
|
try {
|
|
3538
|
-
if (!
|
|
3539
|
-
if (
|
|
3560
|
+
if (!fs12.existsSync(PROJECTS_MEMORY_DIR)) return result;
|
|
3561
|
+
if (fs12.existsSync(MEMORY_DIR_MIGRATION_MARKER)) return result;
|
|
3540
3562
|
result.ran = true;
|
|
3541
3563
|
const candidates = findCandidates(PROJECTS_MEMORY_DIR);
|
|
3542
3564
|
const touchedCategories = new Set(candidates.map((c) => c.category));
|
|
3543
3565
|
for (const c of candidates) {
|
|
3544
|
-
const targetDir =
|
|
3566
|
+
const targetDir = path13.join(PROJECTS_MEMORY_DIR, c.project);
|
|
3545
3567
|
const label = `${c.category}/${c.project}`;
|
|
3546
3568
|
try {
|
|
3547
|
-
if (!
|
|
3569
|
+
if (!fs12.existsSync(targetDir)) {
|
|
3548
3570
|
await fsp7.rename(c.sourceDir, targetDir);
|
|
3549
3571
|
result.moved += 1;
|
|
3550
3572
|
continue;
|
|
3551
3573
|
}
|
|
3552
|
-
const sourceMem =
|
|
3553
|
-
const targetMem =
|
|
3554
|
-
if (!
|
|
3574
|
+
const sourceMem = path13.join(c.sourceDir, MEMORY_FILE_NAME);
|
|
3575
|
+
const targetMem = path13.join(targetDir, MEMORY_FILE_NAME);
|
|
3576
|
+
if (!fs12.existsSync(targetMem)) {
|
|
3555
3577
|
await fsp7.rename(sourceMem, targetMem);
|
|
3556
3578
|
await drainDir(c.sourceDir, targetDir);
|
|
3557
3579
|
result.moved += 1;
|
|
@@ -3573,7 +3595,7 @@ async function migrateProjectMemoryDirs() {
|
|
|
3573
3595
|
}
|
|
3574
3596
|
}
|
|
3575
3597
|
for (const cat of touchedCategories) {
|
|
3576
|
-
await fsp7.rmdir(
|
|
3598
|
+
await fsp7.rmdir(path13.join(PROJECTS_MEMORY_DIR, cat)).catch(() => {
|
|
3577
3599
|
});
|
|
3578
3600
|
}
|
|
3579
3601
|
await fsp7.writeFile(
|
|
@@ -3601,7 +3623,7 @@ var init_memory_dir_migration = __esm({
|
|
|
3601
3623
|
"use strict";
|
|
3602
3624
|
init_constants();
|
|
3603
3625
|
init_logging();
|
|
3604
|
-
MEMORY_DIR_MIGRATION_MARKER =
|
|
3626
|
+
MEMORY_DIR_MIGRATION_MARKER = path13.join(PROJECTS_MEMORY_DIR, ".migrated-project-only");
|
|
3605
3627
|
MEMORY_FILE_NAME = "MEMORY.md";
|
|
3606
3628
|
}
|
|
3607
3629
|
});
|
|
@@ -3977,11 +3999,11 @@ var init_jira_client = __esm({
|
|
|
3977
3999
|
return this.request("GET", "/rest/api/3/myself");
|
|
3978
4000
|
}
|
|
3979
4001
|
// ── HTTP transport ──
|
|
3980
|
-
async request(method,
|
|
4002
|
+
async request(method, path15, body) {
|
|
3981
4003
|
let lastError = null;
|
|
3982
4004
|
for (let attempt = 0; attempt <= MAX_RETRIES; attempt++) {
|
|
3983
4005
|
try {
|
|
3984
|
-
return await this.doRequest(method,
|
|
4006
|
+
return await this.doRequest(method, path15, body);
|
|
3985
4007
|
} catch (err) {
|
|
3986
4008
|
lastError = err instanceof Error ? err : new Error(String(err));
|
|
3987
4009
|
const status = err.statusCode;
|
|
@@ -3990,16 +4012,16 @@ var init_jira_client = __esm({
|
|
|
3990
4012
|
}
|
|
3991
4013
|
if (attempt < MAX_RETRIES) {
|
|
3992
4014
|
const backoff = INITIAL_BACKOFF_MS * Math.pow(2, attempt);
|
|
3993
|
-
this.logger.debug("Jira API retrying", { method, path:
|
|
4015
|
+
this.logger.debug("Jira API retrying", { method, path: path15, attempt: attempt + 1, backoff });
|
|
3994
4016
|
await new Promise((r) => setTimeout(r, backoff));
|
|
3995
4017
|
}
|
|
3996
4018
|
}
|
|
3997
4019
|
}
|
|
3998
4020
|
throw lastError ?? new Error("Jira request failed");
|
|
3999
4021
|
}
|
|
4000
|
-
doRequest(method,
|
|
4022
|
+
doRequest(method, path15, body) {
|
|
4001
4023
|
return new Promise((resolve, reject) => {
|
|
4002
|
-
const url = new URL(
|
|
4024
|
+
const url = new URL(path15, this.baseUrl);
|
|
4003
4025
|
const isHttps = url.protocol === "https:";
|
|
4004
4026
|
const transport = isHttps ? https : http;
|
|
4005
4027
|
const bodyStr = body ? JSON.stringify(body) : void 0;
|
|
@@ -4032,14 +4054,14 @@ var init_jira_client = __esm({
|
|
|
4032
4054
|
}
|
|
4033
4055
|
return;
|
|
4034
4056
|
}
|
|
4035
|
-
const err = new Error(`Jira API ${method} ${
|
|
4057
|
+
const err = new Error(`Jira API ${method} ${path15} \u2192 ${status}: ${raw.slice(0, 500)}`);
|
|
4036
4058
|
err.statusCode = status;
|
|
4037
4059
|
reject(err);
|
|
4038
4060
|
});
|
|
4039
4061
|
});
|
|
4040
4062
|
req.on("error", reject);
|
|
4041
4063
|
req.setTimeout(3e4, () => {
|
|
4042
|
-
req.destroy(new Error(`Jira API ${method} ${
|
|
4064
|
+
req.destroy(new Error(`Jira API ${method} ${path15} timed out after 30s`));
|
|
4043
4065
|
});
|
|
4044
4066
|
if (bodyStr) req.write(bodyStr);
|
|
4045
4067
|
req.end();
|
|
@@ -4268,7 +4290,7 @@ __export(sync_exports, {
|
|
|
4268
4290
|
mapToLocal: () => mapToLocal,
|
|
4269
4291
|
syncTasks: () => syncTasks
|
|
4270
4292
|
});
|
|
4271
|
-
import
|
|
4293
|
+
import path14 from "path";
|
|
4272
4294
|
function getJiraConfig(config) {
|
|
4273
4295
|
return config.plugins?.jira;
|
|
4274
4296
|
}
|
|
@@ -4678,7 +4700,7 @@ var init_sync = __esm({
|
|
|
4678
4700
|
init_jira_client();
|
|
4679
4701
|
init_workflow();
|
|
4680
4702
|
init_adf();
|
|
4681
|
-
JIRA_SYNC_FILE =
|
|
4703
|
+
JIRA_SYNC_FILE = path14.join(SYNC_DIR, "jira-sync.json");
|
|
4682
4704
|
syncLog = createSubsystemLogger("jira");
|
|
4683
4705
|
LOCAL_TO_JIRA_PRIORITY = {
|
|
4684
4706
|
immediate: "Highest",
|