nolo-cli 0.8.0-alpha.2 → 0.8.0-alpha.20
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/_executeModel-WRUCQIV5.js +205 -0
- package/action-R4M4ORGA.js +28 -0
- package/addContentAction-UYFFTEWJ.js +26 -0
- package/addDialogAgentAction-OT4XZAVP.js +68 -0
- package/agentDeleteCommand-5DD2IM3J.js +327 -0
- package/agentEmailCommands-IASM2YBQ.js +628 -0
- package/agentListCommands-I6KZYCIG.js +223 -0
- package/agentMachineCommands-OUP3YQP7.js +425 -0
- package/agentPullCommand-O2MTUAFR.js +122 -0
- package/agentRecordCommands-QKGE2JTA.js +96 -0
- package/agentRunCommand-TVZXUBQ5.js +114 -0
- package/agentRunControl-K4VKNEHF.js +57 -0
- package/agentRuntimeLocal-ZYEIPTY4.js +104 -0
- package/agentSlice-T4PMW7W6.js +42 -0
- package/authCommand-EB5JSOX5.js +581 -0
- package/authCommands-XPEHTKSM.js +35 -0
- package/chunk-2EHX7F5G.js +1948 -0
- package/chunk-2FTTDCD4.js +675 -0
- package/chunk-3ASDTTEI.js +1774 -0
- package/chunk-3EUW3WEO.js +8 -0
- package/chunk-3LY4F7SV.js +9293 -0
- package/chunk-4CQLVGRV.js +50 -0
- package/chunk-4FBRSEV4.js +573 -0
- package/chunk-4IJYA27C.js +342 -0
- package/chunk-4QEWT7KD.js +933 -0
- package/chunk-4SN6J65J.js +38 -0
- package/chunk-4VNS5WPM.js +42 -0
- package/chunk-4ZDM73SD.js +34 -0
- package/chunk-5CS33IBL.js +301 -0
- package/chunk-5KLGBAAR.js +386 -0
- package/chunk-5MIDPSSK.js +206 -0
- package/chunk-5MMAK75Q.js +15 -0
- package/chunk-5W3VUFOX.js +34 -0
- package/chunk-63W5N6P3.js +150 -0
- package/chunk-6HYVJV7B.js +102 -0
- package/chunk-6WD3OOJS.js +20 -0
- package/chunk-7DAJ4AI4.js +191 -0
- package/chunk-7KCUSYT2.js +354 -0
- package/chunk-7T5PWAZN.js +171 -0
- package/chunk-AFON4QUU.js +112 -0
- package/chunk-AGFH73SK.js +239 -0
- package/chunk-ATNTHIZI.js +13 -0
- package/chunk-AVMKZHBC.js +85 -0
- package/chunk-AZPCASRE.js +36 -0
- package/chunk-BBYVOSU2.js +792 -0
- package/chunk-BCIOM4NZ.js +1078 -0
- package/chunk-C3RUNRHT.js +51 -0
- package/chunk-C4FTUXVF.js +146 -0
- package/chunk-CF2WZF4N.js +134 -0
- package/chunk-CF7PE763.js +10 -0
- package/chunk-CKOJQDKR.js +198 -0
- package/chunk-CMKUBIGW.js +1550 -0
- package/chunk-CWMSB67P.js +34 -0
- package/chunk-DCOA4QSN.js +105 -0
- package/chunk-DFFIZ25G.js +30 -0
- package/chunk-DWLEOOGR.js +8 -0
- package/chunk-DZ3XJVET.js +231 -0
- package/chunk-EHLHSX7R.js +1433 -0
- package/chunk-FM5IVZXO.js +4723 -0
- package/chunk-FVYY6MCS.js +1447 -0
- package/chunk-G3SUCT4W.js +8 -0
- package/chunk-GAKEBQD6.js +30 -0
- package/chunk-GBRG75BQ.js +86 -0
- package/chunk-GLYVN7EQ.js +238 -0
- package/chunk-H33743XH.js +25 -0
- package/chunk-HNMXYYJR.js +12 -0
- package/chunk-HNW7IJSK.js +71 -0
- package/chunk-I42VC5KR.js +15 -0
- package/chunk-IDZTNRP2.js +85 -0
- package/chunk-IHBCLYEE.js +22310 -0
- package/chunk-IJGXKGXW.js +421 -0
- package/chunk-ISNCLGUZ.js +146 -0
- package/chunk-IWX4UW2E.js +548 -0
- package/chunk-JBTJAPUF.js +35 -0
- package/chunk-JEXVIMYZ.js +55 -0
- package/chunk-JRKKFRAV.js +537 -0
- package/chunk-JZPBVBIY.js +94 -0
- package/chunk-K6BPOQLF.js +2052 -0
- package/chunk-K777STIO.js +478 -0
- package/chunk-KKY4B2Q2.js +21 -0
- package/chunk-KQHGZWSV.js +63 -0
- package/chunk-KUG52IAP.js +8 -0
- package/chunk-KX6YBIHG.js +8 -0
- package/chunk-LCBAMY2M.js +60 -0
- package/chunk-LM6IYQ3F.js +16 -0
- package/chunk-LTRXGFMS.js +83 -0
- package/chunk-M76ECQRD.js +13658 -0
- package/chunk-MNJDFJND.js +222 -0
- package/chunk-MRC4Q34M.js +188 -0
- package/chunk-MTU75CZ2.js +91 -0
- package/chunk-N54XAP77.js +19 -0
- package/chunk-O2ZNTTET.js +3272 -0
- package/chunk-O4BU24WZ.js +3212 -0
- package/chunk-OLZBQWZU.js +6 -0
- package/chunk-OPZYGHUC.js +89 -0
- package/chunk-OWOHNGCN.js +50 -0
- package/chunk-P3PKED2I.js +962 -0
- package/chunk-PFTAG6DY.js +1939 -0
- package/chunk-PMKQGGGM.js +221 -0
- package/chunk-PP4S6RTL.js +175 -0
- package/chunk-QJ7FZNYN.js +939 -0
- package/chunk-QSJ3HFEF.js +8 -0
- package/chunk-RGIM3WLT.js +113 -0
- package/chunk-RL776AGR.js +190 -0
- package/chunk-ROWQEJRP.js +139 -0
- package/chunk-S7Z2HMCN.js +25 -0
- package/chunk-SDJDLO5W.js +628 -0
- package/chunk-SOTZ6RDN.js +69 -0
- package/chunk-TILFE6LV.js +381 -0
- package/chunk-TIMLUWQA.js +231 -0
- package/chunk-TISCADJH.js +807 -0
- package/chunk-U4TRT5V4.js +246 -0
- package/chunk-U6VC4MU4.js +8 -0
- package/chunk-UAD2WT54.js +64 -0
- package/chunk-VC6OZXO5.js +298 -0
- package/chunk-VF4K2QE6.js +21 -0
- package/chunk-VHBWHNVT.js +59 -0
- package/chunk-VIDPVFP3.js +20 -0
- package/chunk-VP4WJWKW.js +8882 -0
- package/chunk-VVX233PH.js +482 -0
- package/chunk-W4NVOSFF.js +37 -0
- package/chunk-WI4XWASA.js +208 -0
- package/chunk-WWC7I6TA.js +8 -0
- package/chunk-WZSRQNQG.js +2587 -0
- package/chunk-XBROXIGL.js +3066 -0
- package/chunk-XENYHRUE.js +104 -0
- package/chunk-Y5GCAMGP.js +9 -0
- package/chunk-YN4XDB7B.js +9036 -0
- package/chunk-YPRZSPF3.js +148 -0
- package/chunk-Z4NR32XR.js +50 -0
- package/chunk-Z6EKEXJW.js +138 -0
- package/chunk-ZDRZMLKO.js +27339 -0
- package/chunk-ZNFJWEN4.js +56 -0
- package/cliExecutor-K3F7DMRO.js +36 -0
- package/clipboardy-BVE3LVEH.js +12001 -0
- package/createAgentAutomationAction-CCABEOM6.js +866 -0
- package/createDialogAction-YPKF5ITI.js +55 -0
- package/createPageAction-YEZ7EK5F.js +172 -0
- package/db-HCJ5PRB5.js +271 -0
- package/dbSlice-QPVZHBOE.js +60 -0
- package/deleteFile-SV5MS23W.js +41 -0
- package/dialogCommands-4IX4XIZE.js +63 -0
- package/dialogSlice-OVTO7QGW.js +148 -0
- package/docCreateCommands-SIL3NPGT.js +220 -0
- package/docDeleteCommands-7IOMLUS4.js +181 -0
- package/docReadCommands-FNFXUA5L.js +134 -0
- package/docStore-ZAYLW2HN.js +98 -0
- package/docUpdateCommands-X2HNDVUC.js +318 -0
- package/fetchMessages-KTNM7QAR.js +17 -0
- package/getPricing-3E6UNPKL.js +30 -0
- package/handleSendMessageAction-TZMZ4EP5.js +185 -0
- package/index.js +188 -112958
- package/lib-FYYBQIXS.js +19839 -0
- package/localDialogRead-2VRI24F4.js +26 -0
- package/localFirstLog-DHNOY2NA.js +19 -0
- package/localRuntimeAuthority-TEGCOWX4.js +471 -0
- package/localRuntimeDb-LGDF6FQP.js +12 -0
- package/machineCommands-M4ZJZIMS.js +781 -0
- package/machineInfo-M6KB6HZN.js +10 -0
- package/machineWsRunDispatch-TPJAUGLP.js +112 -0
- package/memoryCommands-O4MIPIWQ.js +476 -0
- package/models-4OPOOLFS.js +9 -0
- package/offlineMarxistsAgentCommand-BCPJITJL.js +242 -0
- package/package.json +4 -23
- package/read-EBMWX4Z6.js +17 -0
- package/readDocTool-2MWHSTQE.js +16 -0
- package/readlineWorkspace-OMCIU3WT.js +5682 -0
- package/removeDialogAgentAction-SNZ662NP.js +73 -0
- package/runAgentClientLoop-H6NGOUAM.js +293 -0
- package/runtimeDoctorCommands-LRHLPDRC.js +289 -0
- package/setDialogExtraReferencesAction-XDI2KM2N.js +60 -0
- package/setPrimaryDialogAgentAction-PYEC4N4Z.js +80 -0
- package/settingSlice-NOWHY2FK.js +199 -0
- package/skillDiscovery-UGSQGX2U.js +16 -0
- package/skillSummaryMarker-42HKSXYY.js +9 -0
- package/slateToRenderMarkdown-Y5IYN73U.js +7 -0
- package/slateUtils-2M7MUTWX.js +19 -0
- package/spaceCommands-E7VOF4LO.js +450 -0
- package/spaceSlice-QHBPICA2.js +149 -0
- package/streamAgentChatTurn-3XTBA2HN.js +4510 -0
- package/tableCommands-R5UCM63M.js +1286 -0
- package/toolApiClient-QI3YBNWB.js +26 -0
- package/tools-GHLZ3XD6.js +87 -0
- package/tuiSummaryLlmCaller-RV3THLZF.js +78 -0
- package/understanding-3CUQQ6SV.js +271 -0
- package/updateCommands-VOSPKXFF.js +31 -0
- package/updateDialogTitleAction-XA2OZTLP.js +188 -0
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import {
|
|
2
|
+
createSpaceKey
|
|
3
|
+
} from "./chunk-UAD2WT54.js";
|
|
4
|
+
import {
|
|
5
|
+
patch,
|
|
6
|
+
read
|
|
7
|
+
} from "./chunk-TISCADJH.js";
|
|
8
|
+
import {
|
|
9
|
+
DEVICE_LOCAL_OWNER_ID,
|
|
10
|
+
isDeviceLocalSpaceBody,
|
|
11
|
+
selectIdentityUserId
|
|
12
|
+
} from "./chunk-XBROXIGL.js";
|
|
13
|
+
|
|
14
|
+
// packages/create/space/utils/permissions.ts
|
|
15
|
+
var checkSpaceMembership = (spaceData, userId) => {
|
|
16
|
+
if (!spaceData) {
|
|
17
|
+
console.error("[Permission Check] Space data is missing.");
|
|
18
|
+
throw new Error("\u65E0\u6CD5\u6267\u884C\u6743\u9650\u68C0\u67E5\uFF1A\u7A7A\u95F4\u6570\u636E\u7F3A\u5931\u3002");
|
|
19
|
+
}
|
|
20
|
+
if (isDeviceLocalSpaceBody(spaceData)) {
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
if (!userId) {
|
|
24
|
+
console.error("[Permission Check] User ID is missing.");
|
|
25
|
+
throw new Error("\u65E0\u6CD5\u6267\u884C\u6743\u9650\u68C0\u67E5\uFF1A\u7528\u6237 ID \u7F3A\u5931\u3002");
|
|
26
|
+
}
|
|
27
|
+
if (!spaceData.members || !Array.isArray(spaceData.members) || !spaceData.members.includes(userId)) {
|
|
28
|
+
console.warn(
|
|
29
|
+
`[Permission Check] User ${userId} attempt to operate on space ${spaceData.id} without membership.`
|
|
30
|
+
);
|
|
31
|
+
throw new Error("\u5F53\u524D\u7528\u6237\u4E0D\u662F\u7A7A\u95F4\u6210\u5458");
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
var localSpaceAuthorityPatchStamp = (spaceData) => isDeviceLocalSpaceBody(spaceData) ? { userId: DEVICE_LOCAL_OWNER_ID } : {};
|
|
35
|
+
|
|
36
|
+
// packages/create/space/constants.ts
|
|
37
|
+
var UNCATEGORIZED_ID = "__uncategorized_container__";
|
|
38
|
+
|
|
39
|
+
// packages/create/space/content/addContentAction.ts
|
|
40
|
+
var addContentAction = async (input, thunkAPI) => {
|
|
41
|
+
const {
|
|
42
|
+
spaceId,
|
|
43
|
+
title,
|
|
44
|
+
type,
|
|
45
|
+
contentKey,
|
|
46
|
+
fileCategory,
|
|
47
|
+
mimeType,
|
|
48
|
+
fileSize,
|
|
49
|
+
originalName,
|
|
50
|
+
categoryId: rawCategoryId,
|
|
51
|
+
pinned = false,
|
|
52
|
+
order,
|
|
53
|
+
triggerType,
|
|
54
|
+
skillSummary
|
|
55
|
+
} = input;
|
|
56
|
+
const { dispatch, getState } = thunkAPI;
|
|
57
|
+
const userId = selectIdentityUserId(getState());
|
|
58
|
+
if (!contentKey || typeof contentKey !== "string" || contentKey.trim() === "")
|
|
59
|
+
throw new Error("Invalid contentKey provided.");
|
|
60
|
+
if (!title || typeof title !== "string" || title.trim() === "")
|
|
61
|
+
throw new Error("Invalid or empty title provided.");
|
|
62
|
+
if (!type || typeof type !== "string")
|
|
63
|
+
throw new Error("Invalid content type provided.");
|
|
64
|
+
const spaceKey = createSpaceKey.space(spaceId);
|
|
65
|
+
const spaceData = await dispatch(read({
|
|
66
|
+
dbKey: spaceKey
|
|
67
|
+
})).unwrap();
|
|
68
|
+
checkSpaceMembership(spaceData, userId);
|
|
69
|
+
if (spaceData.contents && spaceData.contents[contentKey]) {
|
|
70
|
+
throw new Error(`\u5185\u5BB9\u952E "${contentKey}" \u5DF2\u5B58\u5728\u3002`);
|
|
71
|
+
}
|
|
72
|
+
let categoryIdForStorage;
|
|
73
|
+
if (rawCategoryId && rawCategoryId !== "" && rawCategoryId !== UNCATEGORIZED_ID) {
|
|
74
|
+
if (spaceData.categories?.[rawCategoryId]) {
|
|
75
|
+
categoryIdForStorage = rawCategoryId;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
const now = Date.now();
|
|
79
|
+
const newSpaceContent = {
|
|
80
|
+
title: title.trim(),
|
|
81
|
+
type,
|
|
82
|
+
contentKey,
|
|
83
|
+
...fileCategory !== void 0 ? { fileCategory } : {},
|
|
84
|
+
...mimeType !== void 0 ? { mimeType } : {},
|
|
85
|
+
...fileSize !== void 0 ? { fileSize } : {},
|
|
86
|
+
...originalName !== void 0 ? { originalName } : {},
|
|
87
|
+
...categoryIdForStorage !== void 0 && {
|
|
88
|
+
categoryId: categoryIdForStorage
|
|
89
|
+
},
|
|
90
|
+
pinned,
|
|
91
|
+
createdAt: now,
|
|
92
|
+
updatedAt: now,
|
|
93
|
+
...order !== void 0 && typeof order === "number" && { order },
|
|
94
|
+
...triggerType !== void 0 && { triggerType },
|
|
95
|
+
...skillSummary !== void 0 ? { skillSummary } : {}
|
|
96
|
+
};
|
|
97
|
+
const changes = {
|
|
98
|
+
contents: { [contentKey]: newSpaceContent },
|
|
99
|
+
updatedAt: now,
|
|
100
|
+
...localSpaceAuthorityPatchStamp(spaceData)
|
|
101
|
+
};
|
|
102
|
+
const updatedSpaceData = await dispatch(
|
|
103
|
+
patch({ dbKey: spaceKey, changes })
|
|
104
|
+
).unwrap();
|
|
105
|
+
return { spaceId, updatedSpaceData };
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
export {
|
|
109
|
+
checkSpaceMembership,
|
|
110
|
+
localSpaceAuthorityPatchStamp,
|
|
111
|
+
UNCATEGORIZED_ID,
|
|
112
|
+
addContentAction
|
|
113
|
+
};
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
import {
|
|
2
|
+
deleteDbRecord,
|
|
3
|
+
queryUserRecords,
|
|
4
|
+
readDbRecord
|
|
5
|
+
} from "./chunk-SDJDLO5W.js";
|
|
6
|
+
import {
|
|
7
|
+
mergeAndDedupUserData
|
|
8
|
+
} from "./chunk-KQHGZWSV.js";
|
|
9
|
+
import {
|
|
10
|
+
toErrorMessage
|
|
11
|
+
} from "./chunk-HNMXYYJR.js";
|
|
12
|
+
import {
|
|
13
|
+
isTombstoneRecord
|
|
14
|
+
} from "./chunk-GBRG75BQ.js";
|
|
15
|
+
|
|
16
|
+
// packages/cli/globalRecordOperations.ts
|
|
17
|
+
async function listUserRecordsFromServers(args) {
|
|
18
|
+
const remoteResults = [];
|
|
19
|
+
const failures = [];
|
|
20
|
+
const promises = args.serverUrls.map(async (serverUrl) => {
|
|
21
|
+
try {
|
|
22
|
+
const records = await queryUserRecords({
|
|
23
|
+
authToken: args.authToken,
|
|
24
|
+
fallbackFetchImpl: args.fallbackFetchImpl,
|
|
25
|
+
fetchImpl: args.fetchImpl,
|
|
26
|
+
includeDeleted: true,
|
|
27
|
+
limit: args.limit,
|
|
28
|
+
serverUrl,
|
|
29
|
+
summary: args.summary,
|
|
30
|
+
type: args.type,
|
|
31
|
+
userId: args.userId
|
|
32
|
+
});
|
|
33
|
+
return { ok: true, serverUrl, records };
|
|
34
|
+
} catch (error) {
|
|
35
|
+
return {
|
|
36
|
+
ok: false,
|
|
37
|
+
serverUrl,
|
|
38
|
+
error: toErrorMessage(error)
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
const results = await Promise.all(promises);
|
|
43
|
+
for (const res of results) {
|
|
44
|
+
if (res.ok) {
|
|
45
|
+
remoteResults.push({
|
|
46
|
+
data: {
|
|
47
|
+
data: res.records.map((record) => ({
|
|
48
|
+
...record,
|
|
49
|
+
serverOrigin: typeof record?.serverOrigin === "string" && record.serverOrigin.trim() ? record.serverOrigin : res.serverUrl
|
|
50
|
+
}))
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
} else {
|
|
54
|
+
failures.push({
|
|
55
|
+
serverUrl: res.serverUrl,
|
|
56
|
+
error: res.error
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
if (remoteResults.length === 0 && failures.length > 0) {
|
|
61
|
+
const label = args.label ?? "record query";
|
|
62
|
+
throw new Error(
|
|
63
|
+
`${label} failed on all candidate servers: ${failures.map((failure) => `${failure.serverUrl}: ${failure.error}`).join("; ")}`
|
|
64
|
+
);
|
|
65
|
+
}
|
|
66
|
+
const merged = mergeAndDedupUserData([], remoteResults, { includeDeleted: true });
|
|
67
|
+
return {
|
|
68
|
+
records: merged.filter((record) => !isTombstoneRecord(record)),
|
|
69
|
+
failures
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
async function readDbRecordFromServers(args) {
|
|
73
|
+
const failures = [];
|
|
74
|
+
for (const serverUrl of args.serverUrls) {
|
|
75
|
+
try {
|
|
76
|
+
const record = await readDbRecord({
|
|
77
|
+
authToken: args.authToken,
|
|
78
|
+
dbKey: args.dbKey,
|
|
79
|
+
fallbackFetchImpl: args.fallbackFetchImpl,
|
|
80
|
+
fetchImpl: args.fetchImpl,
|
|
81
|
+
includeDeleted: args.includeDeleted,
|
|
82
|
+
serverUrl
|
|
83
|
+
});
|
|
84
|
+
return { record, serverUrl, failures };
|
|
85
|
+
} catch (error) {
|
|
86
|
+
failures.push({
|
|
87
|
+
serverUrl,
|
|
88
|
+
error: toErrorMessage(error)
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
const label = args.label ?? `record ${args.dbKey}`;
|
|
93
|
+
throw new Error(
|
|
94
|
+
`${label} is unreadable on all candidate servers: ${failures.map((failure) => `${failure.serverUrl}: ${failure.error}`).join("; ")}`
|
|
95
|
+
);
|
|
96
|
+
}
|
|
97
|
+
async function readDbRecordVersionsFromServers(args) {
|
|
98
|
+
const records = [];
|
|
99
|
+
const failures = [];
|
|
100
|
+
const promises = args.serverUrls.map(async (serverUrl) => {
|
|
101
|
+
try {
|
|
102
|
+
const record = await readDbRecord({
|
|
103
|
+
authToken: args.authToken,
|
|
104
|
+
dbKey: args.dbKey,
|
|
105
|
+
fallbackFetchImpl: args.fallbackFetchImpl,
|
|
106
|
+
fetchImpl: args.fetchImpl,
|
|
107
|
+
includeDeleted: true,
|
|
108
|
+
serverUrl
|
|
109
|
+
});
|
|
110
|
+
return { ok: true, serverUrl, record };
|
|
111
|
+
} catch (error) {
|
|
112
|
+
return {
|
|
113
|
+
ok: false,
|
|
114
|
+
serverUrl,
|
|
115
|
+
error: toErrorMessage(error)
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
});
|
|
119
|
+
const results = await Promise.all(promises);
|
|
120
|
+
for (const res of results) {
|
|
121
|
+
if (res.ok) {
|
|
122
|
+
const record = res.record;
|
|
123
|
+
records.push({
|
|
124
|
+
...record,
|
|
125
|
+
dbKey: typeof record?.dbKey === "string" && record.dbKey.trim() ? record.dbKey : args.dbKey,
|
|
126
|
+
serverOrigin: typeof record?.serverOrigin === "string" && record.serverOrigin.trim() ? record.serverOrigin : res.serverUrl
|
|
127
|
+
});
|
|
128
|
+
} else {
|
|
129
|
+
failures.push({
|
|
130
|
+
serverUrl: res.serverUrl,
|
|
131
|
+
error: res.error
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
return { records, failures };
|
|
136
|
+
}
|
|
137
|
+
async function readLiveDbRecordAfterTombstoneMerge(args) {
|
|
138
|
+
const result = await readDbRecordVersionsFromServers(args);
|
|
139
|
+
const merged = mergeAndDedupUserData(
|
|
140
|
+
[],
|
|
141
|
+
[{ data: { data: result.records } }],
|
|
142
|
+
{ includeDeleted: true }
|
|
143
|
+
);
|
|
144
|
+
const record = merged.find((item) => item?.dbKey === args.dbKey);
|
|
145
|
+
if (record && !isTombstoneRecord(record)) {
|
|
146
|
+
return {
|
|
147
|
+
record,
|
|
148
|
+
serverUrl: typeof record.serverOrigin === "string" ? record.serverOrigin : "",
|
|
149
|
+
failures: result.failures
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
const label = args.label ?? `record ${args.dbKey}`;
|
|
153
|
+
const failureText = result.failures.length ? ` Failures: ${result.failures.map((failure) => `${failure.serverUrl}: ${failure.error}`).join("; ")}` : "";
|
|
154
|
+
throw new Error(`${label} is deleted or unreadable after global tombstone merge.${failureText}`);
|
|
155
|
+
}
|
|
156
|
+
async function deleteDbRecordOnServers(args) {
|
|
157
|
+
return deleteDbRecordOnTargets({
|
|
158
|
+
...args,
|
|
159
|
+
targets: args.serverUrls.map((serverUrl) => ({ serverUrl }))
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
async function deleteDbRecordOnTargets(args) {
|
|
163
|
+
const promises = args.targets.map(async (target) => {
|
|
164
|
+
try {
|
|
165
|
+
const result = await deleteDbRecord({
|
|
166
|
+
authToken: target.authToken ?? args.authToken,
|
|
167
|
+
dbKey: args.dbKey,
|
|
168
|
+
deleteOptions: args.deleteOptions,
|
|
169
|
+
fallbackFetchImpl: args.fallbackFetchImpl,
|
|
170
|
+
fetchImpl: args.fetchImpl,
|
|
171
|
+
serverUrl: target.serverUrl
|
|
172
|
+
});
|
|
173
|
+
return { serverUrl: target.serverUrl, ok: true, result };
|
|
174
|
+
} catch (error) {
|
|
175
|
+
return {
|
|
176
|
+
serverUrl: target.serverUrl,
|
|
177
|
+
ok: false,
|
|
178
|
+
error: toErrorMessage(error)
|
|
179
|
+
};
|
|
180
|
+
}
|
|
181
|
+
});
|
|
182
|
+
return Promise.all(promises);
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
export {
|
|
186
|
+
listUserRecordsFromServers,
|
|
187
|
+
readDbRecordFromServers,
|
|
188
|
+
readLiveDbRecordAfterTombstoneMerge,
|
|
189
|
+
deleteDbRecordOnServers
|
|
190
|
+
};
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
// packages/cli/client/profileConfig.ts
|
|
2
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
3
|
+
import { dirname, join } from "node:path";
|
|
4
|
+
import { homedir } from "node:os";
|
|
5
|
+
|
|
6
|
+
// packages/core/noloServerUrl.ts
|
|
7
|
+
function isNoloChatHostname(hostname) {
|
|
8
|
+
if (typeof hostname !== "string") return false;
|
|
9
|
+
const host = hostname.trim().toLowerCase();
|
|
10
|
+
if (!host) return false;
|
|
11
|
+
return host === "nolo.chat" || host.endsWith(".nolo.chat");
|
|
12
|
+
}
|
|
13
|
+
function canonicalizeNoloServerUrl(value) {
|
|
14
|
+
const normalized = value.trim().replace(/\/+$/, "");
|
|
15
|
+
if (!normalized) return normalized;
|
|
16
|
+
try {
|
|
17
|
+
const url = new URL(normalized);
|
|
18
|
+
if (url.protocol === "http:" && isNoloChatHostname(url.hostname)) {
|
|
19
|
+
url.protocol = "https:";
|
|
20
|
+
return url.toString().replace(/\/+$/, "");
|
|
21
|
+
}
|
|
22
|
+
} catch {
|
|
23
|
+
return normalized;
|
|
24
|
+
}
|
|
25
|
+
return normalized;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// packages/cli/client/profileConfig.ts
|
|
29
|
+
var normalizeProfileServerUrl = canonicalizeNoloServerUrl;
|
|
30
|
+
function getDefaultProfileConfigPath() {
|
|
31
|
+
return join(homedir(), ".nolo", "config.json");
|
|
32
|
+
}
|
|
33
|
+
function loadProfileConfig(path = getDefaultProfileConfigPath()) {
|
|
34
|
+
if (!existsSync(path)) return null;
|
|
35
|
+
const raw = readFileSync(path, "utf8");
|
|
36
|
+
const parsed = JSON.parse(raw);
|
|
37
|
+
if (!parsed.currentProfile || !parsed.profiles?.[parsed.currentProfile]) return null;
|
|
38
|
+
for (const profile of Object.values(parsed.profiles)) {
|
|
39
|
+
if (!profile?.serverUrl) continue;
|
|
40
|
+
profile.serverUrl = normalizeProfileServerUrl(profile.serverUrl);
|
|
41
|
+
}
|
|
42
|
+
return parsed;
|
|
43
|
+
}
|
|
44
|
+
function clearProfileAuthToken(path = getDefaultProfileConfigPath()) {
|
|
45
|
+
const config = loadProfileConfig(path);
|
|
46
|
+
if (!config) return false;
|
|
47
|
+
const profile = config.profiles[config.currentProfile];
|
|
48
|
+
if (!profile?.authToken?.trim()) return false;
|
|
49
|
+
delete profile.authToken;
|
|
50
|
+
mkdirSync(dirname(path), { recursive: true });
|
|
51
|
+
writeFileSync(path, `${JSON.stringify(config, null, 2)}
|
|
52
|
+
`, "utf8");
|
|
53
|
+
return true;
|
|
54
|
+
}
|
|
55
|
+
function saveDefaultProfile(path, profile) {
|
|
56
|
+
const existing = loadProfileConfig(path);
|
|
57
|
+
const mergedDefault = {
|
|
58
|
+
...existing?.profiles?.default ?? {},
|
|
59
|
+
serverUrl: normalizeProfileServerUrl(profile.serverUrl),
|
|
60
|
+
authToken: profile.authToken.trim()
|
|
61
|
+
};
|
|
62
|
+
const config = {
|
|
63
|
+
currentProfile: "default",
|
|
64
|
+
profiles: {
|
|
65
|
+
...existing?.profiles ?? {},
|
|
66
|
+
default: mergedDefault
|
|
67
|
+
}
|
|
68
|
+
};
|
|
69
|
+
mkdirSync(dirname(path), { recursive: true });
|
|
70
|
+
writeFileSync(path, `${JSON.stringify(config, null, 2)}
|
|
71
|
+
`, "utf8");
|
|
72
|
+
return config;
|
|
73
|
+
}
|
|
74
|
+
function buildEnvFromProfile(config) {
|
|
75
|
+
if (!config) return {};
|
|
76
|
+
const profile = config.profiles[config.currentProfile];
|
|
77
|
+
if (!profile) return {};
|
|
78
|
+
return {
|
|
79
|
+
NOLO_PROFILE: config.currentProfile,
|
|
80
|
+
NOLO_SERVER: profile.serverUrl,
|
|
81
|
+
...profile.authToken?.trim() ? { AUTH_TOKEN: profile.authToken.trim() } : {},
|
|
82
|
+
...profile.agentKey ? { NOLO_AGENT: profile.agentKey } : {},
|
|
83
|
+
...profile.agentName ? { NOLO_AGENT_NAME: profile.agentName } : {},
|
|
84
|
+
...profile.locale ? { NOLO_LANG: profile.locale } : {}
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
function buildCliRuntimeEnv(processEnv, config) {
|
|
88
|
+
const profileEnv = buildEnvFromProfile(config);
|
|
89
|
+
const explicitAuthToken = processEnv.AUTH_TOKEN || processEnv.AUTH;
|
|
90
|
+
const explicitServerUrl = processEnv.NOLO_SERVER || processEnv.NOLO_SERVER_URL || processEnv.BASE_URL;
|
|
91
|
+
return {
|
|
92
|
+
...processEnv,
|
|
93
|
+
...profileEnv,
|
|
94
|
+
...explicitAuthToken ? { AUTH_TOKEN: explicitAuthToken } : {},
|
|
95
|
+
...explicitServerUrl ? {
|
|
96
|
+
NOLO_SERVER: explicitServerUrl,
|
|
97
|
+
BASE_URL: explicitServerUrl
|
|
98
|
+
} : {}
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
function getCurrentProfile(config) {
|
|
102
|
+
if (!config) return null;
|
|
103
|
+
return config.profiles[config.currentProfile] ?? null;
|
|
104
|
+
}
|
|
105
|
+
function saveProfileLocale(locale, path = getDefaultProfileConfigPath()) {
|
|
106
|
+
const config = loadProfileConfig(path);
|
|
107
|
+
if (!config) return null;
|
|
108
|
+
const profile = config.profiles[config.currentProfile];
|
|
109
|
+
if (!profile) return null;
|
|
110
|
+
profile.locale = locale;
|
|
111
|
+
mkdirSync(dirname(path), { recursive: true });
|
|
112
|
+
writeFileSync(path, `${JSON.stringify(config, null, 2)}
|
|
113
|
+
`, "utf8");
|
|
114
|
+
return config;
|
|
115
|
+
}
|
|
116
|
+
function saveProfileAgentSelection(selection, path = getDefaultProfileConfigPath()) {
|
|
117
|
+
const config = loadProfileConfig(path);
|
|
118
|
+
if (!config) return null;
|
|
119
|
+
const profile = config.profiles[config.currentProfile];
|
|
120
|
+
if (!profile) return null;
|
|
121
|
+
profile.agentKey = selection.agentKey.trim();
|
|
122
|
+
profile.agentName = selection.agentName.trim();
|
|
123
|
+
mkdirSync(dirname(path), { recursive: true });
|
|
124
|
+
writeFileSync(path, `${JSON.stringify(config, null, 2)}
|
|
125
|
+
`, "utf8");
|
|
126
|
+
return config;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
export {
|
|
130
|
+
getDefaultProfileConfigPath,
|
|
131
|
+
loadProfileConfig,
|
|
132
|
+
clearProfileAuthToken,
|
|
133
|
+
saveDefaultProfile,
|
|
134
|
+
buildEnvFromProfile,
|
|
135
|
+
buildCliRuntimeEnv,
|
|
136
|
+
getCurrentProfile,
|
|
137
|
+
saveProfileLocale,
|
|
138
|
+
saveProfileAgentSelection
|
|
139
|
+
};
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
// packages/cli/secretScan.ts
|
|
2
|
+
var SECRET_PATTERNS = [
|
|
3
|
+
{ label: "password", pattern: /\bpassword\s*[:=]\s*["']?[^"',\s#]{8,}/i },
|
|
4
|
+
{ label: "psk", pattern: /\bpsk\s*[:=]\s*["']?[^"',\s#]{8,}/i },
|
|
5
|
+
{ label: "api key", pattern: /\b(api[_-]?key|apikey)\s*[:=]\s*["']?[^"',\s#]{12,}/i },
|
|
6
|
+
{ label: "token", pattern: /\b(token|secret)\s*[:=]\s*["']?[^"',\s#]{12,}/i },
|
|
7
|
+
{ label: "private key", pattern: /-----BEGIN [A-Z ]*PRIVATE KEY-----/ }
|
|
8
|
+
];
|
|
9
|
+
function findPotentialSecrets(text) {
|
|
10
|
+
return text.split(/\r?\n/).flatMap(
|
|
11
|
+
(line, index) => SECRET_PATTERNS.filter(({ pattern }) => pattern.test(line)).map(({ label }) => ({
|
|
12
|
+
label,
|
|
13
|
+
line: index + 1,
|
|
14
|
+
preview: line.length > 120 ? `${line.slice(0, 117)}...` : line
|
|
15
|
+
}))
|
|
16
|
+
);
|
|
17
|
+
}
|
|
18
|
+
function formatSecretFindings(findings) {
|
|
19
|
+
return findings.map((finding) => ` line ${finding.line} (${finding.label}): ${finding.preview}`).join("\n");
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export {
|
|
23
|
+
findPotentialSecrets,
|
|
24
|
+
formatSecretFindings
|
|
25
|
+
};
|