skillwiki 0.10.109 → 0.10.111
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-JCDAEZVD.js → chunk-5IBLXGLY.js} +5 -3
- package/dist/chunk-6OQLBNKR.js +250 -0
- package/dist/chunk-GQWCTJTU.js +55 -0
- package/dist/{chunk-FYAKMULW.js → chunk-HBJLFPQP.js} +91 -198
- package/dist/chunk-I2J3IJB7.js +54 -0
- package/dist/{chunk-HMHMCPCE.js → chunk-I6IRJCUJ.js} +12 -57
- package/dist/{chunk-QU2IXZRN.js → chunk-JQV5KNPT.js} +8 -6
- package/dist/chunk-KWEYA3OE.js +60 -0
- package/dist/{chunk-DTTKCCQ4.js → chunk-MRPJ7X7W.js} +5 -3
- package/dist/{chunk-LDEZQXH6.js → chunk-OJJBZDPR.js} +306 -116
- package/dist/chunk-OSL4J7GF.js +32 -0
- package/dist/chunk-PYPPG7RF.js +126 -0
- package/dist/chunk-QESNTTVY.js +50 -0
- package/dist/chunk-TDBUJUYH.js +109 -0
- package/dist/{chunk-GJC2CI3W.js → chunk-UIEQIJXP.js} +108 -336
- package/dist/chunk-X5GL2FCU.js +344 -0
- package/dist/chunk-ZRGZBAVS.js +98 -0
- package/dist/cli.js +352 -297
- package/dist/{index-projection-ESBJOBS7.js → index-projection-2K672CBO.js} +5 -3
- package/dist/journal-QU5IDXQF.js +13 -0
- package/dist/{managed-write-preflight-MAIGWFQJ.js → managed-write-preflight-GRSHQYKC.js} +7 -4
- package/dist/migrate-PIB4QA54.js +21 -0
- package/dist/ready-S7F53Q2D.js +9 -0
- package/dist/runtime-GLMI5OCT.js +15 -0
- package/dist/skillwiki-mcp.js +12 -7
- package/dist/sources-D2MGP246.js +10 -0
- package/dist/upload-HTE62TOV.js +14 -0
- package/dist/watcher-MHG46J3R.js +616 -0
- package/docs/clip-outbox.md +119 -0
- package/package.json +5 -1
- package/skills/.claude-plugin/plugin.json +1 -1
- package/skills/.codex-plugin/plugin.json +1 -1
- package/skills/.cursor-plugin/plugin.json +1 -1
- package/skills/package.json +1 -1
- package/skills/skills/using-skillwiki/SKILL.md +1 -1
- package/skills/skills/wiki-init/SKILL.md +12 -11
- package/skills/using-skillwiki/SKILL.md +1 -1
- package/skills/wiki-init/SKILL.md +12 -11
- package/templates/launchd/com.karlchow.skillwiki-clip-outbox.plist +21 -0
- package/templates/web-clipper/llm-wiki-clippings.json +1 -1
- package/templates/web-clipper/readme.txt +13 -13
- package/dist/sources-QTQSZMST.js +0 -9
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
ExitCode,
|
|
4
|
+
err,
|
|
5
|
+
isBlockedHost,
|
|
6
|
+
ok
|
|
7
|
+
} from "./chunk-UIEQIJXP.js";
|
|
8
|
+
|
|
9
|
+
// src/commands/fetch-guard.ts
|
|
10
|
+
var REDACT_PARAMS = /* @__PURE__ */ new Set(["api_key", "token", "key", "auth", "password", "secret", "access_token"]);
|
|
11
|
+
var PATH_TOKEN_RE = /[A-Fa-f0-9]{32,}|[A-Za-z0-9_\-]{40,}/g;
|
|
12
|
+
function runFetchGuard(input) {
|
|
13
|
+
return Promise.resolve(runFetchGuardSync(input));
|
|
14
|
+
}
|
|
15
|
+
function runFetchGuardSync(input) {
|
|
16
|
+
let u;
|
|
17
|
+
try {
|
|
18
|
+
u = new URL(input.url);
|
|
19
|
+
} catch {
|
|
20
|
+
return { exitCode: ExitCode.MALFORMED_URL, result: err("MALFORMED_URL", { url: input.url }) };
|
|
21
|
+
}
|
|
22
|
+
const sanitized = sanitizeUrl(u);
|
|
23
|
+
if (u.protocol !== "https:") {
|
|
24
|
+
return {
|
|
25
|
+
exitCode: ExitCode.SCHEME_REJECTED,
|
|
26
|
+
result: err("SCHEME_REJECTED", { sanitized_url: sanitized, scheme: u.protocol })
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
if (isBlockedHost(u.hostname)) {
|
|
30
|
+
return {
|
|
31
|
+
exitCode: ExitCode.HOST_BLOCKED,
|
|
32
|
+
result: err("HOST_BLOCKED", { sanitized_url: sanitized, host: u.hostname })
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
return { exitCode: ExitCode.OK, result: ok({ allowed: true, sanitized_url: sanitized, humanHint: `ALLOWED: ${sanitized}` }) };
|
|
36
|
+
}
|
|
37
|
+
function sanitizeUrl(u) {
|
|
38
|
+
const clone = new URL(u.toString());
|
|
39
|
+
if (clone.username || clone.password) {
|
|
40
|
+
clone.username = "";
|
|
41
|
+
clone.password = "";
|
|
42
|
+
}
|
|
43
|
+
for (const k of Array.from(clone.searchParams.keys())) {
|
|
44
|
+
if (REDACT_PARAMS.has(k.toLowerCase())) clone.searchParams.set(k, "REDACTED");
|
|
45
|
+
}
|
|
46
|
+
let s = clone.toString();
|
|
47
|
+
s = s.replace(PATH_TOKEN_RE, "REDACTED");
|
|
48
|
+
return s;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export {
|
|
52
|
+
runFetchGuard,
|
|
53
|
+
runFetchGuardSync
|
|
54
|
+
};
|
|
@@ -1,67 +1,23 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
extractFrontmatter,
|
|
4
|
+
scanSensitiveContent,
|
|
5
|
+
scanVault
|
|
6
|
+
} from "./chunk-X5GL2FCU.js";
|
|
2
7
|
import {
|
|
3
8
|
MetaSchema,
|
|
4
9
|
TypedKnowledgeSchema,
|
|
5
10
|
detectSchema,
|
|
6
11
|
err,
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
scanSensitiveContent,
|
|
10
|
-
scanVault
|
|
11
|
-
} from "./chunk-GJC2CI3W.js";
|
|
12
|
-
|
|
13
|
-
// src/utils/atomic-write.ts
|
|
14
|
-
import { randomBytes } from "crypto";
|
|
15
|
-
import { open, readFile, rename, unlink } from "fs/promises";
|
|
16
|
-
import { basename, dirname, join } from "path";
|
|
17
|
-
async function readExisting(path) {
|
|
18
|
-
try {
|
|
19
|
-
return await readFile(path, "utf8");
|
|
20
|
-
} catch (error) {
|
|
21
|
-
if (error.code === "ENOENT") return null;
|
|
22
|
-
throw error;
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
async function atomicWriteText(path, text) {
|
|
26
|
-
let existing;
|
|
27
|
-
try {
|
|
28
|
-
existing = await readExisting(path);
|
|
29
|
-
} catch (error) {
|
|
30
|
-
return err("WRITE_FAILED", { path, phase: "read-existing", message: String(error) });
|
|
31
|
-
}
|
|
32
|
-
if (existing === text) return ok({ changed: false, existed: true });
|
|
33
|
-
const tmp = join(
|
|
34
|
-
dirname(path),
|
|
35
|
-
`.${basename(path)}.${process.pid}.${randomBytes(8).toString("hex")}.tmp`
|
|
36
|
-
);
|
|
37
|
-
try {
|
|
38
|
-
const handle = await open(tmp, "wx");
|
|
39
|
-
try {
|
|
40
|
-
await handle.writeFile(text, "utf8");
|
|
41
|
-
try {
|
|
42
|
-
await handle.sync();
|
|
43
|
-
} catch {
|
|
44
|
-
}
|
|
45
|
-
} finally {
|
|
46
|
-
await handle.close();
|
|
47
|
-
}
|
|
48
|
-
await rename(tmp, path);
|
|
49
|
-
return ok({ changed: true, existed: existing !== null });
|
|
50
|
-
} catch (error) {
|
|
51
|
-
try {
|
|
52
|
-
await unlink(tmp);
|
|
53
|
-
} catch {
|
|
54
|
-
}
|
|
55
|
-
return err("WRITE_FAILED", { path, phase: "atomic-write", message: String(error) });
|
|
56
|
-
}
|
|
57
|
-
}
|
|
12
|
+
ok
|
|
13
|
+
} from "./chunk-UIEQIJXP.js";
|
|
58
14
|
|
|
59
15
|
// src/utils/index-universe.ts
|
|
60
|
-
import { readFile
|
|
16
|
+
import { readFile } from "fs/promises";
|
|
61
17
|
|
|
62
18
|
// src/utils/typed-page.ts
|
|
63
19
|
import { lstatSync, realpathSync } from "fs";
|
|
64
|
-
import { dirname
|
|
20
|
+
import { dirname, posix, relative, resolve, sep } from "path";
|
|
65
21
|
var TYPE_DIRECTORY = {
|
|
66
22
|
entity: "entities",
|
|
67
23
|
concept: "concepts",
|
|
@@ -86,7 +42,7 @@ function assertTargetInsideVault(vault, target) {
|
|
|
86
42
|
return err("VAULT_PATH_INVALID", { target, message: "vault realpath failed" });
|
|
87
43
|
}
|
|
88
44
|
const absolutePath = resolve(vaultReal, target);
|
|
89
|
-
const parent =
|
|
45
|
+
const parent = dirname(absolutePath);
|
|
90
46
|
let parentReal;
|
|
91
47
|
try {
|
|
92
48
|
parentReal = realpathSync(parent);
|
|
@@ -201,7 +157,7 @@ async function buildRootIndexUniverse(input) {
|
|
|
201
157
|
for (const page of typedPages) {
|
|
202
158
|
let text;
|
|
203
159
|
try {
|
|
204
|
-
text = await
|
|
160
|
+
text = await readFile(page.absPath, "utf8");
|
|
205
161
|
} catch {
|
|
206
162
|
continue;
|
|
207
163
|
}
|
|
@@ -247,7 +203,7 @@ async function buildRootIndexUniverse(input) {
|
|
|
247
203
|
for (const readme of projectReadmes) {
|
|
248
204
|
let text;
|
|
249
205
|
try {
|
|
250
|
-
text = await
|
|
206
|
+
text = await readFile(readme.absPath, "utf8");
|
|
251
207
|
} catch {
|
|
252
208
|
continue;
|
|
253
209
|
}
|
|
@@ -286,7 +242,6 @@ async function buildRootIndexUniverse(input) {
|
|
|
286
242
|
}
|
|
287
243
|
|
|
288
244
|
export {
|
|
289
|
-
atomicWriteText,
|
|
290
245
|
assertTargetInsideVault,
|
|
291
246
|
prepareTypedPage,
|
|
292
247
|
ROOT_INDEX_SECTION_ORDER,
|
|
@@ -8,18 +8,20 @@ import {
|
|
|
8
8
|
readLogEvents,
|
|
9
9
|
resolveExistingRegularFileInsideVault,
|
|
10
10
|
writeLogEvent
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-5IBLXGLY.js";
|
|
12
12
|
import {
|
|
13
|
-
ExitCode,
|
|
14
|
-
RawSourceSchema,
|
|
15
|
-
err,
|
|
16
13
|
extractFrontmatter,
|
|
17
|
-
ok,
|
|
18
14
|
readPage,
|
|
19
15
|
scanSensitiveContent,
|
|
20
16
|
scanVault,
|
|
21
17
|
splitFrontmatter
|
|
22
|
-
} from "./chunk-
|
|
18
|
+
} from "./chunk-X5GL2FCU.js";
|
|
19
|
+
import {
|
|
20
|
+
ExitCode,
|
|
21
|
+
RawSourceSchema,
|
|
22
|
+
err,
|
|
23
|
+
ok
|
|
24
|
+
} from "./chunk-UIEQIJXP.js";
|
|
23
25
|
|
|
24
26
|
// src/commands/sources.ts
|
|
25
27
|
import { readFile as readFile4 } from "fs/promises";
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
atomicWriteText
|
|
4
|
+
} from "./chunk-GQWCTJTU.js";
|
|
5
|
+
|
|
6
|
+
// src/clip-outbox/journal.ts
|
|
7
|
+
import { mkdir, readFile, open } from "fs/promises";
|
|
8
|
+
import { dirname, join } from "path";
|
|
9
|
+
import { z } from "zod";
|
|
10
|
+
async function readJournal(stateRoot) {
|
|
11
|
+
let raw;
|
|
12
|
+
try {
|
|
13
|
+
raw = await readFile(join(stateRoot, "journal.json"), "utf8");
|
|
14
|
+
} catch (e) {
|
|
15
|
+
if (e.code === "ENOENT") return [];
|
|
16
|
+
throw e;
|
|
17
|
+
}
|
|
18
|
+
const key = z.string().regex(/^raw\/(articles|assets)\/[A-Za-z0-9._/-]+$/).refine((s) => s.split("/").every((p) => p && p !== "." && p !== ".."));
|
|
19
|
+
const schema = z.object({
|
|
20
|
+
captureId: z.string().regex(/^[a-f0-9]{16,32}$/),
|
|
21
|
+
snapshotId: z.string().regex(/^[a-f0-9]{16}$/).optional(),
|
|
22
|
+
source: z.string().optional(),
|
|
23
|
+
sourceSha256: z.string().regex(/^[a-f0-9]{64}$/).optional(),
|
|
24
|
+
articleKey: key.refine((s) => s.startsWith("raw/articles/")),
|
|
25
|
+
assetKeys: z.array(key.refine((s) => s.startsWith("raw/assets/"))),
|
|
26
|
+
sha256: z.record(z.string().regex(/^[a-f0-9]{64}$/)),
|
|
27
|
+
sizes: z.record(z.number().int().nonnegative()).optional(),
|
|
28
|
+
receipts: z.record(z.enum(["created", "idempotent"])).optional(),
|
|
29
|
+
state: z.enum(["discovered", "preparing", "sealed", "assets-verified", "article-verified", "notify-pending", "central-visible", "mirrored", "conflict", "held"]),
|
|
30
|
+
reason: z.string().optional(),
|
|
31
|
+
attempts: z.number().int().nonnegative().optional(),
|
|
32
|
+
updatedAt: z.string().optional(),
|
|
33
|
+
retryAt: z.number().finite().optional()
|
|
34
|
+
}).refine((e) => !e.sourceSha256 || e.snapshotId && [e.articleKey, ...e.assetKeys].every((k) => e.sha256[k] && e.sizes?.[k] !== void 0));
|
|
35
|
+
const result = z.array(schema).safeParse(JSON.parse(raw));
|
|
36
|
+
if (!result.success) throw new Error("invalid clip journal; retain and inspect it before restarting");
|
|
37
|
+
return result.data;
|
|
38
|
+
}
|
|
39
|
+
async function writeJournal(stateRoot, entries) {
|
|
40
|
+
await mkdir(stateRoot, { recursive: true, mode: 448 });
|
|
41
|
+
const result = await atomicWriteText(join(stateRoot, "journal.json"), JSON.stringify(entries, null, 2));
|
|
42
|
+
if (!result.ok) throw new Error("journal write failed");
|
|
43
|
+
for (const path of [stateRoot, dirname(stateRoot)]) {
|
|
44
|
+
const dir = await open(path, "r");
|
|
45
|
+
try {
|
|
46
|
+
await dir.sync();
|
|
47
|
+
} finally {
|
|
48
|
+
await dir.close();
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
function upsertJournal(entries, next) {
|
|
53
|
+
return [...entries.filter((e) => e.captureId !== next.captureId), next];
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export {
|
|
57
|
+
readJournal,
|
|
58
|
+
writeJournal,
|
|
59
|
+
upsertJournal
|
|
60
|
+
};
|
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
ROOT_INDEX_SECTION_ORDER,
|
|
4
|
-
atomicWriteText,
|
|
5
4
|
buildRootIndexUniverse
|
|
6
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-I6IRJCUJ.js";
|
|
6
|
+
import {
|
|
7
|
+
atomicWriteText
|
|
8
|
+
} from "./chunk-GQWCTJTU.js";
|
|
7
9
|
import {
|
|
8
10
|
err,
|
|
9
11
|
ok
|
|
10
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-UIEQIJXP.js";
|
|
11
13
|
|
|
12
14
|
// src/utils/index-projection.ts
|
|
13
15
|
import { readFile } from "fs/promises";
|