nolo-cli 0.8.0-alpha.2 → 0.8.0-alpha.21
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-42U3VOVZ.js +205 -0
- package/action-TLI3V62L.js +28 -0
- package/addContentAction-57RSIIMR.js +26 -0
- package/addDialogAgentAction-G3VWEA6E.js +68 -0
- package/agentDeleteCommand-5DD2IM3J.js +327 -0
- package/agentEmailCommands-6FACJBU4.js +628 -0
- package/agentListCommands-I6KZYCIG.js +223 -0
- package/agentMachineCommands-VKLIGMZA.js +425 -0
- package/agentPullCommand-O2MTUAFR.js +122 -0
- package/agentRecordCommands-7TZICYDT.js +96 -0
- package/agentRunCommand-L4OM23KV.js +114 -0
- package/agentRunControl-K4VKNEHF.js +57 -0
- package/agentRuntimeLocal-ZYEIPTY4.js +104 -0
- package/agentSlice-BX7GXSNO.js +42 -0
- package/authCommand-EB5JSOX5.js +581 -0
- package/authCommands-XPEHTKSM.js +35 -0
- package/chunk-25LCXTML.js +175 -0
- package/chunk-2ECQG4YX.js +22296 -0
- package/chunk-2FTTDCD4.js +675 -0
- package/chunk-2JCXITPK.js +1078 -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-4IJYA27C.js +342 -0
- package/chunk-4O3CARJ4.js +231 -0
- package/chunk-4QEWT7KD.js +933 -0
- package/chunk-4SN6J65J.js +38 -0
- package/chunk-4VNS5WPM.js +42 -0
- package/chunk-4XENYTF5.js +222 -0
- package/chunk-4ZDM73SD.js +34 -0
- package/chunk-5CS33IBL.js +301 -0
- package/chunk-5EFXE3O7.js +138 -0
- package/chunk-5KLGBAAR.js +386 -0
- package/chunk-5MIDPSSK.js +206 -0
- package/chunk-5MMAK75Q.js +15 -0
- package/chunk-63W5N6P3.js +150 -0
- package/chunk-6HYVJV7B.js +102 -0
- package/chunk-6KHNO3SK.js +1948 -0
- package/chunk-6WD3OOJS.js +20 -0
- package/chunk-7DAJ4AI4.js +191 -0
- package/chunk-7GNGZRLZ.js +1939 -0
- package/chunk-7KCUSYT2.js +354 -0
- package/chunk-7U44LYTR.js +238 -0
- package/chunk-AFON4QUU.js +112 -0
- package/chunk-AGFH73SK.js +239 -0
- package/chunk-AL2KDGR2.js +27339 -0
- package/chunk-AS4PVWA4.js +221 -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-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-DSZUWUYB.js +478 -0
- package/chunk-DWLEOOGR.js +8 -0
- package/chunk-DZ3XJVET.js +231 -0
- package/chunk-EHLHSX7R.js +1433 -0
- package/chunk-ENOG22KJ.js +939 -0
- package/chunk-FSO5B7GH.js +171 -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-GU3PEVGZ.js +4723 -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-I6XMPTMR.js +113 -0
- package/chunk-IDZTNRP2.js +85 -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-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-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-OOSFSFMA.js +271 -0
- package/chunk-OPZYGHUC.js +89 -0
- package/chunk-OWOHNGCN.js +50 -0
- package/chunk-P3PKED2I.js +962 -0
- package/chunk-QSJ3HFEF.js +8 -0
- package/chunk-RCSJFQPB.js +9036 -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-U4TRT5V4.js +246 -0
- package/chunk-U6VC4MU4.js +8 -0
- package/chunk-UAD2WT54.js +64 -0
- package/chunk-UB6SN4NJ.js +421 -0
- package/chunk-URUUZLPA.js +807 -0
- package/chunk-UTLZINAP.js +3066 -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-VUW5FBDB.js +573 -0
- package/chunk-VVX233PH.js +482 -0
- package/chunk-VX3SXJ3N.js +2052 -0
- package/chunk-W4NVOSFF.js +37 -0
- package/chunk-WWC7I6TA.js +8 -0
- package/chunk-WZSRQNQG.js +2587 -0
- package/chunk-XBUBEFNX.js +34 -0
- package/chunk-XENYHRUE.js +104 -0
- package/chunk-Y5GCAMGP.js +9 -0
- package/chunk-YPRZSPF3.js +148 -0
- package/chunk-Z4NR32XR.js +50 -0
- package/chunk-ZNFJWEN4.js +56 -0
- package/cliExecutor-K3F7DMRO.js +36 -0
- package/clipboardy-BVE3LVEH.js +12001 -0
- package/createAgentAutomationAction-RJF3N2QY.js +866 -0
- package/createDialogAction-DRSPS6CE.js +55 -0
- package/createPageAction-6B2WMNO3.js +172 -0
- package/db-HCJ5PRB5.js +271 -0
- package/dbSlice-Q3TM2FJV.js +60 -0
- package/deleteFile-OW53A6BX.js +41 -0
- package/dialogCommands-4IX4XIZE.js +63 -0
- package/dialogSlice-3M7KX2TX.js +148 -0
- package/docCreateCommands-SIL3NPGT.js +220 -0
- package/docDeleteCommands-7IOMLUS4.js +181 -0
- package/docReadCommands-FNFXUA5L.js +134 -0
- package/docStore-SV7E34D4.js +98 -0
- package/docUpdateCommands-X2HNDVUC.js +318 -0
- package/fetchMessages-KTNM7QAR.js +17 -0
- package/getPricing-3E6UNPKL.js +30 -0
- package/handleSendMessageAction-JYETO5RZ.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-RIO3RP5Q.js +781 -0
- package/machineInfo-M6KB6HZN.js +10 -0
- package/machineWsRunDispatch-W7UYLGB5.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 -24
- package/read-GW7ZEI23.js +17 -0
- package/readDocTool-HUFU6OCT.js +16 -0
- package/readlineWorkspace-27JR7WPW.js +5682 -0
- package/removeDialogAgentAction-CXKR4NJI.js +73 -0
- package/runAgentClientLoop-HZFAPJHS.js +293 -0
- package/runtimeDoctorCommands-LRHLPDRC.js +289 -0
- package/setDialogExtraReferencesAction-6RKUSXHX.js +60 -0
- package/setPrimaryDialogAgentAction-T3UTBEFG.js +80 -0
- package/settingSlice-IVKXJXMG.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-TSVROA5U.js +149 -0
- package/streamAgentChatTurn-3C5RQZJF.js +4510 -0
- package/tableCommands-O7O2LBEG.js +1286 -0
- package/toolApiClient-QI3YBNWB.js +26 -0
- package/tools-EQDEKR6N.js +87 -0
- package/tuiSummaryLlmCaller-RV3THLZF.js +78 -0
- package/understanding-3CUQQ6SV.js +271 -0
- package/updateCommands-VOSPKXFF.js +31 -0
- package/updateDialogTitleAction-3XV7VWSZ.js +188 -0
|
@@ -0,0 +1,354 @@
|
|
|
1
|
+
import {
|
|
2
|
+
readDbRecord,
|
|
3
|
+
writeAgentRecord
|
|
4
|
+
} from "./chunk-SDJDLO5W.js";
|
|
5
|
+
import {
|
|
6
|
+
buildSkillSummaryMarker
|
|
7
|
+
} from "./chunk-VF4K2QE6.js";
|
|
8
|
+
import {
|
|
9
|
+
buildSkillDocMarkdown
|
|
10
|
+
} from "./chunk-VC6OZXO5.js";
|
|
11
|
+
import {
|
|
12
|
+
createSpaceKey
|
|
13
|
+
} from "./chunk-UAD2WT54.js";
|
|
14
|
+
import {
|
|
15
|
+
parseUserIdFromAuthToken,
|
|
16
|
+
readOption,
|
|
17
|
+
resolveAuthToken,
|
|
18
|
+
resolveServerUrl
|
|
19
|
+
} from "./chunk-ISNCLGUZ.js";
|
|
20
|
+
import {
|
|
21
|
+
asTrimmedLowercaseString
|
|
22
|
+
} from "./chunk-QSJ3HFEF.js";
|
|
23
|
+
import {
|
|
24
|
+
DEFAULT_LOCAL_API_ORIGIN
|
|
25
|
+
} from "./chunk-4SN6J65J.js";
|
|
26
|
+
import {
|
|
27
|
+
NOLO_CLUSTER_SERVERS
|
|
28
|
+
} from "./chunk-LCBAMY2M.js";
|
|
29
|
+
import {
|
|
30
|
+
normalizeServerOrigin
|
|
31
|
+
} from "./chunk-CF7PE763.js";
|
|
32
|
+
|
|
33
|
+
// packages/cli/docPageHelpers.ts
|
|
34
|
+
import { readFileSync } from "node:fs";
|
|
35
|
+
import { ulid } from "ulid";
|
|
36
|
+
function getCliArg(args, flag) {
|
|
37
|
+
const idx = args.indexOf(flag);
|
|
38
|
+
return idx !== -1 ? args[idx + 1] : void 0;
|
|
39
|
+
}
|
|
40
|
+
function readBodyArg(args, fallback = "") {
|
|
41
|
+
const bodyFile = getCliArg(args, "--body-file");
|
|
42
|
+
if (bodyFile !== void 0) {
|
|
43
|
+
return readFileSync(bodyFile, "utf8");
|
|
44
|
+
}
|
|
45
|
+
return getCliArg(args, "--body") ?? fallback;
|
|
46
|
+
}
|
|
47
|
+
function textToSlate(text) {
|
|
48
|
+
return text.split("\n").map((line) => ({
|
|
49
|
+
type: "paragraph",
|
|
50
|
+
children: [{ text: line }]
|
|
51
|
+
}));
|
|
52
|
+
}
|
|
53
|
+
function createPageId() {
|
|
54
|
+
return ulid();
|
|
55
|
+
}
|
|
56
|
+
function buildPageKey(userId, pageId) {
|
|
57
|
+
return `page-${userId}-${pageId}`;
|
|
58
|
+
}
|
|
59
|
+
function buildPageRecord(args) {
|
|
60
|
+
const { dbKey, pageId, title, spaceId, content, existing, meta, slateData } = args;
|
|
61
|
+
const now = Date.now();
|
|
62
|
+
const createdAt = typeof existing?.createdAt === "number" ? existing.createdAt : now;
|
|
63
|
+
const created = typeof existing?.created === "string" ? existing.created : new Date(createdAt).toISOString();
|
|
64
|
+
const nextRecord = {
|
|
65
|
+
...existing ?? {},
|
|
66
|
+
id: existing?.id ?? pageId,
|
|
67
|
+
dbKey,
|
|
68
|
+
type: "page",
|
|
69
|
+
title,
|
|
70
|
+
spaceId,
|
|
71
|
+
content,
|
|
72
|
+
updatedAt: now,
|
|
73
|
+
createdAt,
|
|
74
|
+
created
|
|
75
|
+
};
|
|
76
|
+
if (meta !== void 0) {
|
|
77
|
+
if (meta === null) {
|
|
78
|
+
delete nextRecord.meta;
|
|
79
|
+
} else {
|
|
80
|
+
nextRecord.meta = meta;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
if (slateData !== void 0) {
|
|
84
|
+
if (slateData === null) {
|
|
85
|
+
delete nextRecord.slateData;
|
|
86
|
+
} else {
|
|
87
|
+
nextRecord.slateData = slateData;
|
|
88
|
+
}
|
|
89
|
+
} else if (!existing?.slateData) {
|
|
90
|
+
nextRecord.slateData = textToSlate(content);
|
|
91
|
+
}
|
|
92
|
+
return nextRecord;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// packages/cli/docSkillHelpers.ts
|
|
96
|
+
function normalizeSkillSeed(input) {
|
|
97
|
+
return input.trim().toLowerCase().replace(/[^a-z0-9\u4e00-\u9fa5]+/g, "-").replace(/^-+|-+$/g, "");
|
|
98
|
+
}
|
|
99
|
+
function deterministicId(prefix, seed) {
|
|
100
|
+
let h = 2166136261;
|
|
101
|
+
for (let i = 0; i < seed.length; i++) {
|
|
102
|
+
h ^= seed.charCodeAt(i);
|
|
103
|
+
h = h * 16777619 >>> 0;
|
|
104
|
+
}
|
|
105
|
+
const suffix = h.toString(36).toUpperCase().padStart(14, "0");
|
|
106
|
+
return (prefix + suffix).slice(0, 26);
|
|
107
|
+
}
|
|
108
|
+
function buildSkillDocId(input) {
|
|
109
|
+
return deterministicId("01SK", normalizeSkillSeed(input) || input);
|
|
110
|
+
}
|
|
111
|
+
function buildSkillPageKey(userId, skillId) {
|
|
112
|
+
return buildPageKey(userId, skillId);
|
|
113
|
+
}
|
|
114
|
+
function buildSkillPageRecord(args) {
|
|
115
|
+
const {
|
|
116
|
+
dbKey,
|
|
117
|
+
skillId,
|
|
118
|
+
title,
|
|
119
|
+
spaceId,
|
|
120
|
+
body,
|
|
121
|
+
skillConfig,
|
|
122
|
+
evalConfig,
|
|
123
|
+
workflowConfig,
|
|
124
|
+
existing
|
|
125
|
+
} = args;
|
|
126
|
+
return {
|
|
127
|
+
...buildPageRecord({
|
|
128
|
+
dbKey,
|
|
129
|
+
pageId: skillId,
|
|
130
|
+
title,
|
|
131
|
+
spaceId,
|
|
132
|
+
content: buildSkillDocMarkdown({
|
|
133
|
+
body,
|
|
134
|
+
skillConfig,
|
|
135
|
+
evalConfig,
|
|
136
|
+
workflowConfig
|
|
137
|
+
}),
|
|
138
|
+
existing,
|
|
139
|
+
meta: {
|
|
140
|
+
...existing?.meta ?? {},
|
|
141
|
+
kind: "skill",
|
|
142
|
+
skillConfig,
|
|
143
|
+
...evalConfig ? { evalConfig } : {},
|
|
144
|
+
...workflowConfig ? { workflowConfig } : {}
|
|
145
|
+
},
|
|
146
|
+
slateData: null
|
|
147
|
+
})
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
function parseJsonArg(raw, fallback) {
|
|
151
|
+
if (raw === void 0) return fallback;
|
|
152
|
+
return JSON.parse(raw);
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
// packages/cli/docSpaceHelpers.ts
|
|
156
|
+
async function ensurePageAttachedToSpace(params) {
|
|
157
|
+
const { baseUrl, userId, authToken, spaceId, contentKey, title, skillSummary } = params;
|
|
158
|
+
const spaceKey = createSpaceKey.space(spaceId);
|
|
159
|
+
const spaceRecord = await readDbRecord({
|
|
160
|
+
dbKey: spaceKey,
|
|
161
|
+
authToken,
|
|
162
|
+
fetchImpl: fetch,
|
|
163
|
+
serverUrl: baseUrl
|
|
164
|
+
});
|
|
165
|
+
const now = Date.now();
|
|
166
|
+
await writeAgentRecord({
|
|
167
|
+
agentKey: spaceKey,
|
|
168
|
+
authToken,
|
|
169
|
+
fetchImpl: fetch,
|
|
170
|
+
serverUrl: baseUrl,
|
|
171
|
+
userId,
|
|
172
|
+
record: {
|
|
173
|
+
...spaceRecord,
|
|
174
|
+
contents: {
|
|
175
|
+
...spaceRecord.contents ?? {},
|
|
176
|
+
[contentKey]: {
|
|
177
|
+
...spaceRecord.contents?.[contentKey] ?? {},
|
|
178
|
+
title,
|
|
179
|
+
type: "page",
|
|
180
|
+
contentKey,
|
|
181
|
+
...skillSummary !== void 0 ? { skillSummary } : {},
|
|
182
|
+
updatedAt: now,
|
|
183
|
+
createdAt: spaceRecord.contents?.[contentKey]?.createdAt ?? now
|
|
184
|
+
}
|
|
185
|
+
},
|
|
186
|
+
updatedAt: now
|
|
187
|
+
}
|
|
188
|
+
});
|
|
189
|
+
}
|
|
190
|
+
async function removePageFromSpace(params) {
|
|
191
|
+
const { baseUrl, userId, authToken, spaceId, contentKey } = params;
|
|
192
|
+
const spaceKey = createSpaceKey.space(spaceId);
|
|
193
|
+
const spaceRecord = await readDbRecord({
|
|
194
|
+
dbKey: spaceKey,
|
|
195
|
+
authToken,
|
|
196
|
+
fetchImpl: fetch,
|
|
197
|
+
serverUrl: baseUrl
|
|
198
|
+
});
|
|
199
|
+
const nextContents = { ...spaceRecord.contents ?? {} };
|
|
200
|
+
delete nextContents[contentKey];
|
|
201
|
+
await writeAgentRecord({
|
|
202
|
+
agentKey: spaceKey,
|
|
203
|
+
authToken,
|
|
204
|
+
fetchImpl: fetch,
|
|
205
|
+
serverUrl: baseUrl,
|
|
206
|
+
userId,
|
|
207
|
+
record: {
|
|
208
|
+
...spaceRecord,
|
|
209
|
+
contents: nextContents,
|
|
210
|
+
updatedAt: Date.now()
|
|
211
|
+
}
|
|
212
|
+
});
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
// packages/cli/docCommandShared.ts
|
|
216
|
+
function hasHelpArg(args) {
|
|
217
|
+
return args.includes("--help") || args.includes("-h");
|
|
218
|
+
}
|
|
219
|
+
function hasFlag(args, flag) {
|
|
220
|
+
return args.includes(flag);
|
|
221
|
+
}
|
|
222
|
+
function normalizeBaseUrl(base) {
|
|
223
|
+
return normalizeServerOrigin(base);
|
|
224
|
+
}
|
|
225
|
+
function localBaseFromEnv(env) {
|
|
226
|
+
return normalizeBaseUrl(env.SCRIPT_LOCAL_BASE_URL || DEFAULT_LOCAL_API_ORIGIN);
|
|
227
|
+
}
|
|
228
|
+
function targetToBase(target, env) {
|
|
229
|
+
const normalized = asTrimmedLowercaseString(target);
|
|
230
|
+
if (normalized === "local") return localBaseFromEnv(env);
|
|
231
|
+
if (normalized === "main") return normalizeBaseUrl(NOLO_CLUSTER_SERVERS[0]);
|
|
232
|
+
if (normalized === "us") return normalizeBaseUrl(NOLO_CLUSTER_SERVERS[1]);
|
|
233
|
+
return normalizeBaseUrl(target);
|
|
234
|
+
}
|
|
235
|
+
function parseSyncTargets(raw, env) {
|
|
236
|
+
if (!raw) return void 0;
|
|
237
|
+
return raw.split(",").map((value) => value.trim()).filter(Boolean).filter((value) => value !== "none").map((value) => targetToBase(value, env));
|
|
238
|
+
}
|
|
239
|
+
function isLocalBaseUrl(baseUrl) {
|
|
240
|
+
try {
|
|
241
|
+
const hostname = new URL(baseUrl).hostname;
|
|
242
|
+
return hostname === "localhost" || hostname === "127.0.0.1";
|
|
243
|
+
} catch {
|
|
244
|
+
return false;
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
function resolveWriteTargets(args, env) {
|
|
248
|
+
const explicitSync = parseSyncTargets(readOption(args, "--sync"), env);
|
|
249
|
+
const targets = hasFlag(args, "--local-only") ? [localBaseFromEnv(env)] : explicitSync ?? [resolveServerUrl(args, env)];
|
|
250
|
+
const filtered = hasFlag(args, "--no-local") ? targets.filter((target) => !isLocalBaseUrl(target)) : targets;
|
|
251
|
+
return Array.from(new Set(filtered.map(normalizeBaseUrl)));
|
|
252
|
+
}
|
|
253
|
+
function readTitle(args) {
|
|
254
|
+
const valueFlags = /* @__PURE__ */ new Set([
|
|
255
|
+
"--title",
|
|
256
|
+
"--name",
|
|
257
|
+
"--description",
|
|
258
|
+
"--body",
|
|
259
|
+
"--body-file",
|
|
260
|
+
"--space",
|
|
261
|
+
"--id",
|
|
262
|
+
"--key",
|
|
263
|
+
"--kind",
|
|
264
|
+
"--sync",
|
|
265
|
+
"--tools",
|
|
266
|
+
"--required-skills",
|
|
267
|
+
"--recommended-skills",
|
|
268
|
+
"--preferred-agents",
|
|
269
|
+
"--trigger-mode",
|
|
270
|
+
"--budget-tier",
|
|
271
|
+
"--prompt-patch",
|
|
272
|
+
"--token",
|
|
273
|
+
"--server"
|
|
274
|
+
]);
|
|
275
|
+
return readOption(args, "--title") ?? args.find((value, index) => {
|
|
276
|
+
if (index === 0) return false;
|
|
277
|
+
if (valueFlags.has(args[index - 1])) return false;
|
|
278
|
+
return !value.startsWith("-");
|
|
279
|
+
});
|
|
280
|
+
}
|
|
281
|
+
function resolveDocKind(args, fallback) {
|
|
282
|
+
if (hasFlag(args, "--page") || readOption(args, "--kind") === "page") return "page";
|
|
283
|
+
return fallback;
|
|
284
|
+
}
|
|
285
|
+
function requireTokenUser(args, env, dryRun) {
|
|
286
|
+
const authToken = resolveAuthToken(args, env);
|
|
287
|
+
const userId = parseUserIdFromAuthToken(authToken) || env.USER_ID || "";
|
|
288
|
+
if (!authToken && !dryRun) {
|
|
289
|
+
throw new Error("doc command requires an auth token. Pass --token or set AUTH_TOKEN.");
|
|
290
|
+
}
|
|
291
|
+
if (!userId && !dryRun) {
|
|
292
|
+
throw new Error("auth token does not contain userId. Pass a user-scoped token.");
|
|
293
|
+
}
|
|
294
|
+
return {
|
|
295
|
+
authToken,
|
|
296
|
+
userId: userId || "dry-run"
|
|
297
|
+
};
|
|
298
|
+
}
|
|
299
|
+
async function writePageRecord(args) {
|
|
300
|
+
await writeAgentRecord({
|
|
301
|
+
agentKey: args.dbKey,
|
|
302
|
+
authToken: args.authToken,
|
|
303
|
+
fetchImpl: fetch,
|
|
304
|
+
serverUrl: args.serverUrl,
|
|
305
|
+
userId: args.userId,
|
|
306
|
+
record: args.record
|
|
307
|
+
});
|
|
308
|
+
if (args.spaceId) {
|
|
309
|
+
await ensurePageAttachedToSpace({
|
|
310
|
+
baseUrl: args.serverUrl,
|
|
311
|
+
userId: args.userId,
|
|
312
|
+
authToken: args.authToken,
|
|
313
|
+
spaceId: args.spaceId,
|
|
314
|
+
contentKey: args.dbKey,
|
|
315
|
+
title: args.title,
|
|
316
|
+
skillSummary: args.skillSummary
|
|
317
|
+
});
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
async function readPageRecord(args) {
|
|
321
|
+
return readDbRecord({
|
|
322
|
+
dbKey: args.dbKey,
|
|
323
|
+
authToken: args.authToken,
|
|
324
|
+
fetchImpl: fetch,
|
|
325
|
+
serverUrl: args.serverUrl
|
|
326
|
+
});
|
|
327
|
+
}
|
|
328
|
+
function buildSkillSummaryForRecord(record) {
|
|
329
|
+
const meta = record?.meta;
|
|
330
|
+
const skillConfig = meta?.skillConfig;
|
|
331
|
+
if (!skillConfig) return void 0;
|
|
332
|
+
return buildSkillSummaryMarker(meta);
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
export {
|
|
336
|
+
readBodyArg,
|
|
337
|
+
createPageId,
|
|
338
|
+
buildPageKey,
|
|
339
|
+
buildPageRecord,
|
|
340
|
+
buildSkillDocId,
|
|
341
|
+
buildSkillPageKey,
|
|
342
|
+
buildSkillPageRecord,
|
|
343
|
+
parseJsonArg,
|
|
344
|
+
removePageFromSpace,
|
|
345
|
+
hasHelpArg,
|
|
346
|
+
hasFlag,
|
|
347
|
+
resolveWriteTargets,
|
|
348
|
+
readTitle,
|
|
349
|
+
resolveDocKind,
|
|
350
|
+
requireTokenUser,
|
|
351
|
+
writePageRecord,
|
|
352
|
+
readPageRecord,
|
|
353
|
+
buildSkillSummaryForRecord
|
|
354
|
+
};
|
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
import {
|
|
2
|
+
getRuntimeServerContext,
|
|
3
|
+
scheduleDeleteReplication
|
|
4
|
+
} from "./chunk-UTLZINAP.js";
|
|
5
|
+
import {
|
|
6
|
+
fetchFromClientDb
|
|
7
|
+
} from "./chunk-OOSFSFMA.js";
|
|
8
|
+
import {
|
|
9
|
+
buildTombstoneRecord
|
|
10
|
+
} from "./chunk-GBRG75BQ.js";
|
|
11
|
+
|
|
12
|
+
// packages/database/fileStorage.ts
|
|
13
|
+
var DB_NAME = "nolo-file-storage";
|
|
14
|
+
var STORE_NAME = "files";
|
|
15
|
+
var DB_VERSION = 1;
|
|
16
|
+
var dbPromise = null;
|
|
17
|
+
var openFileDb = () => {
|
|
18
|
+
if (dbPromise) return dbPromise;
|
|
19
|
+
if (typeof indexedDB === "undefined") {
|
|
20
|
+
console.warn(
|
|
21
|
+
"[fileStorage] indexedDB is not available in this environment. File caching is disabled."
|
|
22
|
+
);
|
|
23
|
+
dbPromise = Promise.reject(
|
|
24
|
+
new Error("indexedDB is not available in this environment")
|
|
25
|
+
);
|
|
26
|
+
return dbPromise;
|
|
27
|
+
}
|
|
28
|
+
dbPromise = new Promise((resolve, reject) => {
|
|
29
|
+
const request = indexedDB.open(DB_NAME, DB_VERSION);
|
|
30
|
+
request.onerror = () => {
|
|
31
|
+
console.error("[fileStorage] Failed to open IndexedDB:", request.error);
|
|
32
|
+
reject(request.error);
|
|
33
|
+
};
|
|
34
|
+
request.onupgradeneeded = () => {
|
|
35
|
+
const db = request.result;
|
|
36
|
+
if (!db.objectStoreNames.contains(STORE_NAME)) {
|
|
37
|
+
const store = db.createObjectStore(STORE_NAME, {
|
|
38
|
+
keyPath: "id"
|
|
39
|
+
});
|
|
40
|
+
store.createIndex("createdAt", "createdAt", { unique: false });
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
request.onsuccess = () => {
|
|
44
|
+
const db = request.result;
|
|
45
|
+
db.onversionchange = () => {
|
|
46
|
+
db.close();
|
|
47
|
+
console.warn(
|
|
48
|
+
"[fileStorage] IndexedDB version change detected, closing old connection."
|
|
49
|
+
);
|
|
50
|
+
};
|
|
51
|
+
resolve(db);
|
|
52
|
+
};
|
|
53
|
+
});
|
|
54
|
+
return dbPromise;
|
|
55
|
+
};
|
|
56
|
+
var saveFileToIndexedDb = async (fileId, file) => {
|
|
57
|
+
try {
|
|
58
|
+
const db = await openFileDb();
|
|
59
|
+
const tx = db.transaction(STORE_NAME, "readwrite");
|
|
60
|
+
const store = tx.objectStore(STORE_NAME);
|
|
61
|
+
const blob = file instanceof Blob ? file : new Blob([file]);
|
|
62
|
+
const record = {
|
|
63
|
+
id: fileId,
|
|
64
|
+
blob,
|
|
65
|
+
size: blob.size,
|
|
66
|
+
type: blob.type || "application/octet-stream",
|
|
67
|
+
createdAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
68
|
+
};
|
|
69
|
+
const request = store.put(record);
|
|
70
|
+
await new Promise((resolve, reject) => {
|
|
71
|
+
request.onsuccess = () => {
|
|
72
|
+
console.debug(
|
|
73
|
+
"[fileStorage] Saved file to IndexedDB:",
|
|
74
|
+
fileId,
|
|
75
|
+
"size=",
|
|
76
|
+
record.size,
|
|
77
|
+
"type=",
|
|
78
|
+
record.type
|
|
79
|
+
);
|
|
80
|
+
resolve();
|
|
81
|
+
};
|
|
82
|
+
request.onerror = () => {
|
|
83
|
+
console.error(
|
|
84
|
+
"[fileStorage] Failed to save file to IndexedDB:",
|
|
85
|
+
fileId,
|
|
86
|
+
request.error
|
|
87
|
+
);
|
|
88
|
+
reject(request.error);
|
|
89
|
+
};
|
|
90
|
+
});
|
|
91
|
+
await new Promise((resolve, reject) => {
|
|
92
|
+
tx.oncomplete = () => resolve();
|
|
93
|
+
tx.onerror = () => reject(tx.error);
|
|
94
|
+
tx.onabort = () => reject(tx.error);
|
|
95
|
+
});
|
|
96
|
+
} catch (err) {
|
|
97
|
+
console.warn(
|
|
98
|
+
"[fileStorage] saveFileToIndexedDb error (non-fatal, caching disabled for this file):",
|
|
99
|
+
err
|
|
100
|
+
);
|
|
101
|
+
}
|
|
102
|
+
};
|
|
103
|
+
var loadFileFromIndexedDb = async (fileId) => {
|
|
104
|
+
try {
|
|
105
|
+
const db = await openFileDb();
|
|
106
|
+
const tx = db.transaction(STORE_NAME, "readonly");
|
|
107
|
+
const store = tx.objectStore(STORE_NAME);
|
|
108
|
+
const request = store.get(fileId);
|
|
109
|
+
const record = await new Promise(
|
|
110
|
+
(resolve, reject) => {
|
|
111
|
+
request.onsuccess = () => {
|
|
112
|
+
const result = request.result;
|
|
113
|
+
if (result) {
|
|
114
|
+
console.debug(
|
|
115
|
+
"[fileStorage] Loaded file from IndexedDB:",
|
|
116
|
+
fileId,
|
|
117
|
+
"size=",
|
|
118
|
+
result.size,
|
|
119
|
+
"type=",
|
|
120
|
+
result.type
|
|
121
|
+
);
|
|
122
|
+
} else {
|
|
123
|
+
console.debug(
|
|
124
|
+
"[fileStorage] No local file found in IndexedDB for id:",
|
|
125
|
+
fileId
|
|
126
|
+
);
|
|
127
|
+
}
|
|
128
|
+
resolve(result ?? null);
|
|
129
|
+
};
|
|
130
|
+
request.onerror = () => {
|
|
131
|
+
console.error(
|
|
132
|
+
"[fileStorage] Failed to load file from IndexedDB:",
|
|
133
|
+
fileId,
|
|
134
|
+
request.error
|
|
135
|
+
);
|
|
136
|
+
reject(request.error);
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
);
|
|
140
|
+
return record ?? null;
|
|
141
|
+
} catch (err) {
|
|
142
|
+
console.warn(
|
|
143
|
+
"[fileStorage] loadFileFromIndexedDb error, treat as cache miss:",
|
|
144
|
+
err
|
|
145
|
+
);
|
|
146
|
+
return null;
|
|
147
|
+
}
|
|
148
|
+
};
|
|
149
|
+
var deleteFileFromIndexedDb = async (fileId) => {
|
|
150
|
+
try {
|
|
151
|
+
const db = await openFileDb();
|
|
152
|
+
const tx = db.transaction(STORE_NAME, "readwrite");
|
|
153
|
+
const store = tx.objectStore(STORE_NAME);
|
|
154
|
+
const request = store.delete(fileId);
|
|
155
|
+
await new Promise((resolve, reject) => {
|
|
156
|
+
request.onsuccess = () => {
|
|
157
|
+
console.debug("[fileStorage] Deleted file from IndexedDB:", fileId);
|
|
158
|
+
resolve();
|
|
159
|
+
};
|
|
160
|
+
request.onerror = () => {
|
|
161
|
+
console.error(
|
|
162
|
+
"[fileStorage] Failed to delete file from IndexedDB:",
|
|
163
|
+
fileId,
|
|
164
|
+
request.error
|
|
165
|
+
);
|
|
166
|
+
reject(request.error);
|
|
167
|
+
};
|
|
168
|
+
});
|
|
169
|
+
await new Promise((resolve, reject) => {
|
|
170
|
+
tx.oncomplete = () => resolve();
|
|
171
|
+
tx.onerror = () => reject(tx.error);
|
|
172
|
+
tx.onabort = () => reject(tx.error);
|
|
173
|
+
});
|
|
174
|
+
} catch (err) {
|
|
175
|
+
console.warn("[fileStorage] deleteFileFromIndexedDb error:", err);
|
|
176
|
+
}
|
|
177
|
+
};
|
|
178
|
+
|
|
179
|
+
// packages/database/actions/remove.ts
|
|
180
|
+
var removeAction = async (payload, thunkApi) => {
|
|
181
|
+
const { db: clientDb } = thunkApi.extra;
|
|
182
|
+
const dbKey = typeof payload === "string" ? payload : payload.dbKey;
|
|
183
|
+
const preferredServerOrigin = typeof payload === "string" ? void 0 : payload.preferredServerOrigin;
|
|
184
|
+
if (!clientDb) {
|
|
185
|
+
throw new Error("Client database is undefined in removeAction");
|
|
186
|
+
}
|
|
187
|
+
const state = thunkApi.getState();
|
|
188
|
+
const { currentServer, syncServers } = getRuntimeServerContext(state);
|
|
189
|
+
console.log("[removeAction] START", {
|
|
190
|
+
dbKey,
|
|
191
|
+
preferredServerOrigin,
|
|
192
|
+
currentServer,
|
|
193
|
+
syncServers,
|
|
194
|
+
hasToken: Boolean(state?.auth?.currentToken)
|
|
195
|
+
});
|
|
196
|
+
const localData = await fetchFromClientDb(clientDb, dbKey);
|
|
197
|
+
const hadLocalData = Boolean(localData);
|
|
198
|
+
console.log("[removeAction] replication inputs", {
|
|
199
|
+
currentServer,
|
|
200
|
+
syncServers,
|
|
201
|
+
preferredServerOrigin,
|
|
202
|
+
hadLocalData
|
|
203
|
+
});
|
|
204
|
+
const nowIso = (/* @__PURE__ */ new Date()).toISOString();
|
|
205
|
+
if (localData) {
|
|
206
|
+
if (localData.id && typeof localData.id === "string") {
|
|
207
|
+
void deleteFileFromIndexedDb(localData.id).catch((err) => {
|
|
208
|
+
console.warn("[removeAction] Failed to delete associated file:", localData.id, err);
|
|
209
|
+
});
|
|
210
|
+
}
|
|
211
|
+
await clientDb.put(dbKey, buildTombstoneRecord(localData, nowIso));
|
|
212
|
+
} else {
|
|
213
|
+
await clientDb.put(dbKey, buildTombstoneRecord({ dbKey }, nowIso));
|
|
214
|
+
}
|
|
215
|
+
scheduleDeleteReplication({
|
|
216
|
+
currentServer,
|
|
217
|
+
syncServers,
|
|
218
|
+
preferredServerOrigin,
|
|
219
|
+
dbKey,
|
|
220
|
+
state,
|
|
221
|
+
onResult: (result) => {
|
|
222
|
+
if (result.failed.length > 0) {
|
|
223
|
+
console.warn("[removeAction] Server delete failures after local tombstone:", result.failed);
|
|
224
|
+
}
|
|
225
|
+
},
|
|
226
|
+
onError: (err) => {
|
|
227
|
+
console.warn("[removeAction] Background server delete error:", err);
|
|
228
|
+
}
|
|
229
|
+
});
|
|
230
|
+
return { dbKey };
|
|
231
|
+
};
|
|
232
|
+
|
|
233
|
+
export {
|
|
234
|
+
saveFileToIndexedDb,
|
|
235
|
+
loadFileFromIndexedDb,
|
|
236
|
+
deleteFileFromIndexedDb,
|
|
237
|
+
removeAction
|
|
238
|
+
};
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import {
|
|
2
|
+
buildSkillDiscoveryLayer
|
|
3
|
+
} from "./chunk-C4FTUXVF.js";
|
|
4
|
+
import {
|
|
5
|
+
load
|
|
6
|
+
} from "./chunk-WZSRQNQG.js";
|
|
7
|
+
|
|
8
|
+
// packages/agent-runtime/skillDiscovery.ts
|
|
9
|
+
import { existsSync, readFileSync, readdirSync, statSync } from "node:fs";
|
|
10
|
+
import { join } from "node:path";
|
|
11
|
+
var SKILL_SCAN_DIRS = [".agents/skills", "docs/skills"];
|
|
12
|
+
var MAX_DISCOVERED_SKILLS = 50;
|
|
13
|
+
function parseSkillFrontmatter(filePath) {
|
|
14
|
+
try {
|
|
15
|
+
const content = readFileSync(filePath, "utf8").slice(0, 2048);
|
|
16
|
+
const fmMatch = content.match(/^---\n([\s\S]*?)\n---/);
|
|
17
|
+
if (!fmMatch) return {};
|
|
18
|
+
const fm = load(fmMatch[1]);
|
|
19
|
+
if (!fm || typeof fm !== "object") return {};
|
|
20
|
+
const name = typeof fm.name === "string" ? fm.name : void 0;
|
|
21
|
+
const rawDesc = fm.description;
|
|
22
|
+
const description = typeof rawDesc === "string" ? rawDesc : rawDesc == null ? void 0 : String(rawDesc);
|
|
23
|
+
const sanitize = (s) => s?.trim().replace(/^["']|["']$/g, "").replace(/[\n\r]+/g, " ").slice(0, 200);
|
|
24
|
+
return { name: sanitize(name), description: sanitize(description) };
|
|
25
|
+
} catch {
|
|
26
|
+
return {};
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
function discoverSkills(cwd) {
|
|
30
|
+
const skills = [];
|
|
31
|
+
for (const dir of SKILL_SCAN_DIRS) {
|
|
32
|
+
if (skills.length >= MAX_DISCOVERED_SKILLS) break;
|
|
33
|
+
const absDir = join(cwd, dir);
|
|
34
|
+
if (!existsSync(absDir) || !statSync(absDir).isDirectory()) continue;
|
|
35
|
+
try {
|
|
36
|
+
for (const entry of readdirSync(absDir)) {
|
|
37
|
+
if (skills.length >= MAX_DISCOVERED_SKILLS) break;
|
|
38
|
+
const skillMdPath = join(absDir, entry, "SKILL.md");
|
|
39
|
+
if (existsSync(skillMdPath)) {
|
|
40
|
+
const { name, description } = parseSkillFrontmatter(skillMdPath);
|
|
41
|
+
skills.push({ name: name ?? entry, description: description ?? "", relativePath: join(dir, entry, "SKILL.md") });
|
|
42
|
+
continue;
|
|
43
|
+
}
|
|
44
|
+
if (dir === "docs/skills" && entry.endsWith(".md")) {
|
|
45
|
+
const flatPath = join(absDir, entry);
|
|
46
|
+
const { name, description } = parseSkillFrontmatter(flatPath);
|
|
47
|
+
skills.push({ name: name ?? entry.replace(/\.md$/, ""), description: description ?? "", relativePath: join(dir, entry) });
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
} catch {
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
return skills;
|
|
54
|
+
}
|
|
55
|
+
function resolveSkillByName(cwd, name) {
|
|
56
|
+
const trimmed = name.trim();
|
|
57
|
+
if (!trimmed || trimmed.includes("/") || trimmed.includes("\\") || trimmed.includes("..")) {
|
|
58
|
+
return null;
|
|
59
|
+
}
|
|
60
|
+
const agentsDir = join(cwd, ".agents", "skills", trimmed);
|
|
61
|
+
const agentsSkillMd = join(agentsDir, "SKILL.md");
|
|
62
|
+
if (existsSync(agentsSkillMd)) return agentsSkillMd;
|
|
63
|
+
const agentsParent = join(cwd, ".agents", "skills");
|
|
64
|
+
if (existsSync(agentsParent) && statSync(agentsParent).isDirectory()) {
|
|
65
|
+
try {
|
|
66
|
+
for (const entry of readdirSync(agentsParent)) {
|
|
67
|
+
const candidate = join(agentsParent, entry, "SKILL.md");
|
|
68
|
+
if (!existsSync(candidate)) continue;
|
|
69
|
+
try {
|
|
70
|
+
const { name: fmName } = parseSkillFrontmatter(candidate);
|
|
71
|
+
if (fmName && fmName === trimmed) return candidate;
|
|
72
|
+
} catch {
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
} catch {
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
const docsFlat = join(cwd, "docs", "skills", `${trimmed}.md`);
|
|
79
|
+
if (existsSync(docsFlat)) return docsFlat;
|
|
80
|
+
const docsDir = join(cwd, "docs", "skills");
|
|
81
|
+
if (existsSync(docsDir) && statSync(docsDir).isDirectory()) {
|
|
82
|
+
try {
|
|
83
|
+
for (const entry of readdirSync(docsDir)) {
|
|
84
|
+
if (!entry.endsWith(".md")) continue;
|
|
85
|
+
const candidate = join(docsDir, entry);
|
|
86
|
+
try {
|
|
87
|
+
const { name: fmName } = parseSkillFrontmatter(candidate);
|
|
88
|
+
if (fmName && fmName === trimmed) return candidate;
|
|
89
|
+
} catch {
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
} catch {
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
return null;
|
|
96
|
+
}
|
|
97
|
+
function buildSkillDiscoveryContextBlock(cwd) {
|
|
98
|
+
try {
|
|
99
|
+
const discovered = discoverSkills(cwd);
|
|
100
|
+
const layer = buildSkillDiscoveryLayer(discovered, cwd);
|
|
101
|
+
return layer?.content ?? null;
|
|
102
|
+
} catch {
|
|
103
|
+
return null;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
export {
|
|
108
|
+
parseSkillFrontmatter,
|
|
109
|
+
discoverSkills,
|
|
110
|
+
resolveSkillByName,
|
|
111
|
+
buildSkillDiscoveryContextBlock
|
|
112
|
+
};
|