pi-para 0.6.0 → 0.6.2
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/ARCHITECTURE.md +0 -9
- package/CHANGELOG.md +22 -0
- package/CONFIGURATION.md +5 -23
- package/README.md +7 -31
- package/SETUP.md +5 -3
- package/STRUCTURE.md +0 -9
- package/dist/atomic-write.d.ts +2 -0
- package/dist/atomic-write.d.ts.map +1 -0
- package/dist/atomic-write.js +18 -0
- package/dist/atomic-write.js.map +1 -0
- package/dist/capture.d.ts +34 -0
- package/dist/capture.d.ts.map +1 -0
- package/dist/capture.js +461 -0
- package/dist/capture.js.map +1 -0
- package/dist/cli-legacy.d.ts +4 -0
- package/dist/cli-legacy.d.ts.map +1 -0
- package/dist/cli-legacy.js +41 -0
- package/dist/cli-legacy.js.map +1 -0
- package/dist/cli.d.ts +8 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +427 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands.d.ts +15 -0
- package/dist/commands.d.ts.map +1 -0
- package/dist/commands.js +791 -0
- package/dist/commands.js.map +1 -0
- package/dist/config.d.ts +94 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +228 -0
- package/dist/config.js.map +1 -0
- package/dist/context.d.ts +63 -0
- package/dist/context.d.ts.map +1 -0
- package/dist/context.js +311 -0
- package/dist/context.js.map +1 -0
- package/dist/credentials.d.ts +27 -0
- package/dist/credentials.d.ts.map +1 -0
- package/dist/credentials.js +85 -0
- package/dist/credentials.js.map +1 -0
- package/dist/daemon.d.ts +49 -0
- package/dist/daemon.d.ts.map +1 -0
- package/dist/daemon.js +226 -0
- package/dist/daemon.js.map +1 -0
- package/dist/doctor.d.ts +20 -0
- package/dist/doctor.d.ts.map +1 -0
- package/dist/doctor.js +197 -0
- package/dist/doctor.js.map +1 -0
- package/dist/frontmatter.d.ts +59 -0
- package/dist/frontmatter.d.ts.map +1 -0
- package/dist/frontmatter.js +170 -0
- package/dist/frontmatter.js.map +1 -0
- package/dist/index.d.ts +21 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +357 -0
- package/dist/index.js.map +1 -0
- package/dist/ingest.d.ts +88 -0
- package/dist/ingest.d.ts.map +1 -0
- package/dist/ingest.js +105 -0
- package/dist/ingest.js.map +1 -0
- package/dist/link-discovery.d.ts +40 -0
- package/dist/link-discovery.d.ts.map +1 -0
- package/dist/link-discovery.js +122 -0
- package/dist/link-discovery.js.map +1 -0
- package/dist/link-utils.d.ts +30 -0
- package/dist/link-utils.d.ts.map +1 -0
- package/dist/link-utils.js +145 -0
- package/dist/link-utils.js.map +1 -0
- package/dist/lint.d.ts +39 -0
- package/dist/lint.d.ts.map +1 -0
- package/dist/lint.js +827 -0
- package/dist/lint.js.map +1 -0
- package/dist/maintainer.d.ts +24 -0
- package/dist/maintainer.d.ts.map +1 -0
- package/dist/maintainer.js +358 -0
- package/dist/maintainer.js.map +1 -0
- package/dist/model-resolver.d.ts +30 -0
- package/dist/model-resolver.d.ts.map +1 -0
- package/dist/model-resolver.js +71 -0
- package/dist/model-resolver.js.map +1 -0
- package/dist/paths.d.ts +20 -0
- package/dist/paths.d.ts.map +1 -0
- package/dist/paths.js +33 -0
- package/dist/paths.js.map +1 -0
- package/dist/processor.d.ts +14 -0
- package/dist/processor.d.ts.map +1 -0
- package/dist/processor.js +361 -0
- package/dist/processor.js.map +1 -0
- package/dist/qmd-providers.d.ts +12 -0
- package/dist/qmd-providers.d.ts.map +1 -0
- package/dist/qmd-providers.js +45 -0
- package/dist/qmd-providers.js.map +1 -0
- package/dist/query.d.ts +69 -0
- package/dist/query.d.ts.map +1 -0
- package/dist/query.js +120 -0
- package/dist/query.js.map +1 -0
- package/dist/raw.d.ts +57 -0
- package/dist/raw.d.ts.map +1 -0
- package/dist/raw.js +219 -0
- package/dist/raw.js.map +1 -0
- package/dist/redact.d.ts +21 -0
- package/dist/redact.d.ts.map +1 -0
- package/dist/redact.js +143 -0
- package/dist/redact.js.map +1 -0
- package/dist/repair.d.ts +11 -0
- package/dist/repair.d.ts.map +1 -0
- package/dist/repair.js +41 -0
- package/dist/repair.js.map +1 -0
- package/dist/scheduler/controls.d.ts +35 -0
- package/dist/scheduler/controls.d.ts.map +1 -0
- package/dist/scheduler/controls.js +98 -0
- package/dist/scheduler/controls.js.map +1 -0
- package/dist/scheduler/index.d.ts +70 -0
- package/dist/scheduler/index.d.ts.map +1 -0
- package/dist/scheduler/index.js +245 -0
- package/dist/scheduler/index.js.map +1 -0
- package/dist/scheduler/leases.d.ts +22 -0
- package/dist/scheduler/leases.d.ts.map +1 -0
- package/dist/scheduler/leases.js +74 -0
- package/dist/scheduler/leases.js.map +1 -0
- package/dist/scheduler/session-capture.d.ts +33 -0
- package/dist/scheduler/session-capture.d.ts.map +1 -0
- package/dist/scheduler/session-capture.js +108 -0
- package/dist/scheduler/session-capture.js.map +1 -0
- package/dist/scheduler/state.d.ts +56 -0
- package/dist/scheduler/state.d.ts.map +1 -0
- package/dist/scheduler/state.js +210 -0
- package/dist/scheduler/state.js.map +1 -0
- package/dist/scope.d.ts +54 -0
- package/dist/scope.d.ts.map +1 -0
- package/dist/scope.js +161 -0
- package/dist/scope.js.map +1 -0
- package/dist/scripts/bulk-link-fix.d.ts +9 -0
- package/dist/scripts/bulk-link-fix.d.ts.map +1 -0
- package/dist/scripts/bulk-link-fix.js +106 -0
- package/dist/scripts/bulk-link-fix.js.map +1 -0
- package/dist/session-tools.d.ts +33 -0
- package/dist/session-tools.d.ts.map +1 -0
- package/dist/session-tools.js +211 -0
- package/dist/session-tools.js.map +1 -0
- package/dist/settings.d.ts +37 -0
- package/dist/settings.d.ts.map +1 -0
- package/dist/settings.js +176 -0
- package/dist/settings.js.map +1 -0
- package/dist/setup.d.ts +29 -0
- package/dist/setup.d.ts.map +1 -0
- package/dist/setup.js +90 -0
- package/dist/setup.js.map +1 -0
- package/dist/state.d.ts +54 -0
- package/dist/state.d.ts.map +1 -0
- package/dist/state.js +176 -0
- package/dist/state.js.map +1 -0
- package/dist/status.d.ts +22 -0
- package/dist/status.d.ts.map +1 -0
- package/dist/status.js +93 -0
- package/dist/status.js.map +1 -0
- package/dist/store.d.ts +71 -0
- package/dist/store.d.ts.map +1 -0
- package/dist/store.js +282 -0
- package/dist/store.js.map +1 -0
- package/dist/summarize.d.ts +60 -0
- package/dist/summarize.d.ts.map +1 -0
- package/dist/summarize.js +266 -0
- package/dist/summarize.js.map +1 -0
- package/dist/tag-registry.d.ts +56 -0
- package/dist/tag-registry.d.ts.map +1 -0
- package/dist/tag-registry.js +146 -0
- package/dist/tag-registry.js.map +1 -0
- package/dist/templates/prompts.d.ts +51 -0
- package/dist/templates/prompts.d.ts.map +1 -0
- package/dist/templates/prompts.js +203 -0
- package/dist/templates/prompts.js.map +1 -0
- package/dist/tools.d.ts +26 -0
- package/dist/tools.d.ts.map +1 -0
- package/dist/tools.js +1198 -0
- package/dist/tools.js.map +1 -0
- package/dist/watcher.d.ts +25 -0
- package/dist/watcher.d.ts.map +1 -0
- package/dist/watcher.js +84 -0
- package/dist/watcher.js.map +1 -0
- package/dist/webui/client/dist/index.html +1885 -0
- package/dist/webui/server.d.ts +31 -0
- package/dist/webui/server.d.ts.map +1 -0
- package/dist/webui/server.js +566 -0
- package/dist/webui/server.js.map +1 -0
- package/dist/wiki-tool-guidance.d.ts +6 -0
- package/dist/wiki-tool-guidance.d.ts.map +1 -0
- package/dist/wiki-tool-guidance.js +70 -0
- package/dist/wiki-tool-guidance.js.map +1 -0
- package/dist/wiki.d.ts +108 -0
- package/dist/wiki.d.ts.map +1 -0
- package/dist/wiki.js +497 -0
- package/dist/wiki.js.map +1 -0
- package/package.json +2 -1
- package/scripts/build-assets.mjs +1 -13
- package/skills/setup/SKILL.md +1 -1
- package/src/cli.ts +0 -70
- package/src/commands.ts +78 -3
- package/src/config.ts +0 -25
- package/src/doctor.ts +21 -1
- package/src/index.ts +16 -38
- package/src/scheduler/index.ts +64 -0
- package/src/settings.ts +88 -0
- package/src/setup.ts +1 -1
- package/src/templates/prompts.ts +0 -56
- package/scripts/gepa/dataset.py +0 -192
- package/scripts/gepa/lm_providers.py +0 -472
- package/scripts/gepa/metric.py +0 -279
- package/scripts/gepa/optimize.py +0 -367
- package/scripts/gepa/program.py +0 -99
- package/scripts/gepa/pyproject.toml +0 -19
- package/scripts/gepa/run-all.sh +0 -53
- package/scripts/gepa/wiki_reader.py +0 -113
- package/src/gepa/index.ts +0 -287
- package/src/gepa/optimized/capture-prompt.txt +0 -65
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { appendFile, readFile } from "node:fs/promises";
|
|
2
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
3
|
+
import { basename, dirname, join } from "node:path";
|
|
4
|
+
import { StateDB } from "../state.js";
|
|
5
|
+
import { processSession } from "../processor.js";
|
|
6
|
+
export function parseCompletedSessionLine(line) {
|
|
7
|
+
const trimmed = line.trim();
|
|
8
|
+
if (!trimmed)
|
|
9
|
+
return null;
|
|
10
|
+
const parts = trimmed.split("|", 2);
|
|
11
|
+
if (parts.length !== 2 || !parts[0] || !parts[1])
|
|
12
|
+
return null;
|
|
13
|
+
return { timestamp: parts[0], sessionPath: parts[1] };
|
|
14
|
+
}
|
|
15
|
+
export async function readCompletedSessionRegistry(wikiDir) {
|
|
16
|
+
const registryPath = join(wikiDir, ".completed-sessions");
|
|
17
|
+
if (!existsSync(registryPath))
|
|
18
|
+
return [];
|
|
19
|
+
const content = await readFile(registryPath, "utf-8");
|
|
20
|
+
return content
|
|
21
|
+
.split(/\r?\n/)
|
|
22
|
+
.map(parseCompletedSessionLine)
|
|
23
|
+
.filter((entry) => entry !== null);
|
|
24
|
+
}
|
|
25
|
+
export async function appendCompletedSession(wikiDir, sessionPath, timestamp = new Date().toISOString()) {
|
|
26
|
+
const registryPath = join(wikiDir, ".completed-sessions");
|
|
27
|
+
await appendFile(registryPath, `${timestamp}|${sessionPath}\n`, "utf-8");
|
|
28
|
+
return { timestamp, sessionPath };
|
|
29
|
+
}
|
|
30
|
+
export async function enqueueCompletedSessionsFromRegistry(scheduler, wikiDir, opts = {}) {
|
|
31
|
+
const entries = await readCompletedSessionRegistry(wikiDir);
|
|
32
|
+
return enqueueCompletedSessions(scheduler, entries, opts);
|
|
33
|
+
}
|
|
34
|
+
export function enqueueCompletedSessions(scheduler, entries, opts = {}) {
|
|
35
|
+
const ids = [];
|
|
36
|
+
for (const entry of entries) {
|
|
37
|
+
if (!existsSync(entry.sessionPath))
|
|
38
|
+
continue;
|
|
39
|
+
if (opts.stateDb?.isProcessed(entry.sessionPath))
|
|
40
|
+
continue;
|
|
41
|
+
ids.push(scheduler.enqueue("capture-session", { sessionPath: entry.sessionPath, scope: detectScopeFromSessionPath(entry.sessionPath) }, { dedupeKey: `capture-session:${entry.sessionPath}`, priority: 20 }));
|
|
42
|
+
}
|
|
43
|
+
return ids;
|
|
44
|
+
}
|
|
45
|
+
export function createCaptureSessionHandler(deps) {
|
|
46
|
+
return async (item) => {
|
|
47
|
+
const payload = item.payload;
|
|
48
|
+
if (!payload.sessionPath)
|
|
49
|
+
throw new Error("capture-session payload missing sessionPath");
|
|
50
|
+
if (!existsSync(payload.sessionPath))
|
|
51
|
+
throw new Error(`Session file not found: ${payload.sessionPath}`);
|
|
52
|
+
const store = deps.storeProvider();
|
|
53
|
+
if (!store)
|
|
54
|
+
throw new Error("QMD store unavailable for capture-session");
|
|
55
|
+
if (!deps.model)
|
|
56
|
+
throw new Error("Capture model unavailable for capture-session");
|
|
57
|
+
if (!deps.getApiKey)
|
|
58
|
+
throw new Error("API key resolver unavailable for capture-session");
|
|
59
|
+
const stateDb = deps.stateDb ?? new StateDB(deps.wikiDir);
|
|
60
|
+
const ownsState = !deps.stateDb;
|
|
61
|
+
const scope = payload.scope ?? detectScopeFromSessionPath(payload.sessionPath);
|
|
62
|
+
try {
|
|
63
|
+
if (stateDb.isProcessed(payload.sessionPath))
|
|
64
|
+
return;
|
|
65
|
+
const run = deps.processor ?? processSession;
|
|
66
|
+
const result = await run(payload.sessionPath, deps.wikiDir, store, scope, deps.model, deps.getApiKey);
|
|
67
|
+
if (result.skipped) {
|
|
68
|
+
stateDb.recordSuccess(payload.sessionPath, scope, [], []);
|
|
69
|
+
}
|
|
70
|
+
else {
|
|
71
|
+
stateDb.recordSuccess(payload.sessionPath, scope, result.pagesCreated, result.pagesUpdated);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
catch (err) {
|
|
75
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
76
|
+
stateDb.recordFailure(payload.sessionPath, scope, message);
|
|
77
|
+
throw err;
|
|
78
|
+
}
|
|
79
|
+
finally {
|
|
80
|
+
if (ownsState)
|
|
81
|
+
stateDb.close();
|
|
82
|
+
}
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
export function detectScopeFromSessionPath(sessionPath) {
|
|
86
|
+
try {
|
|
87
|
+
const firstLine = requireReadFirstLine(sessionPath);
|
|
88
|
+
const header = JSON.parse(firstLine);
|
|
89
|
+
if (header.cwd)
|
|
90
|
+
return basename(header.cwd) || "unknown";
|
|
91
|
+
}
|
|
92
|
+
catch {
|
|
93
|
+
// fall through to path decoding
|
|
94
|
+
}
|
|
95
|
+
const dirName = basename(dirname(sessionPath));
|
|
96
|
+
if (dirName.startsWith("--") && dirName.endsWith("--")) {
|
|
97
|
+
const inner = dirName.slice(2, -2);
|
|
98
|
+
const projectsIdx = inner.indexOf("projects-");
|
|
99
|
+
if (projectsIdx >= 0)
|
|
100
|
+
return inner.slice(projectsIdx + "projects-".length);
|
|
101
|
+
}
|
|
102
|
+
return "unknown";
|
|
103
|
+
}
|
|
104
|
+
function requireReadFirstLine(path) {
|
|
105
|
+
const content = readFileSync(path, "utf-8");
|
|
106
|
+
return content.split("\n")[0] ?? "";
|
|
107
|
+
}
|
|
108
|
+
//# sourceMappingURL=session-capture.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-capture.js","sourceRoot":"","sources":["../../src/scheduler/session-capture.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import Database from "better-sqlite3";
|
|
2
|
+
export type QueueStatus = "queued" | "running" | "done" | "failed";
|
|
3
|
+
export interface QueueItem<T = unknown> {
|
|
4
|
+
id: number;
|
|
5
|
+
taskName: string;
|
|
6
|
+
payload: T;
|
|
7
|
+
priority: number;
|
|
8
|
+
availableAt: string;
|
|
9
|
+
dedupeKey: string | null;
|
|
10
|
+
status: QueueStatus;
|
|
11
|
+
attempts: number;
|
|
12
|
+
createdAt: string;
|
|
13
|
+
updatedAt: string;
|
|
14
|
+
}
|
|
15
|
+
export interface EnqueueOptions {
|
|
16
|
+
priority?: number;
|
|
17
|
+
availableAt?: Date;
|
|
18
|
+
dedupeKey?: string;
|
|
19
|
+
now?: Date;
|
|
20
|
+
}
|
|
21
|
+
export interface SchedulerHistoryItem<T = unknown> {
|
|
22
|
+
id: number;
|
|
23
|
+
taskName: string;
|
|
24
|
+
payload: T | null;
|
|
25
|
+
status: string;
|
|
26
|
+
startedAt: string;
|
|
27
|
+
finishedAt: string | null;
|
|
28
|
+
durationMs: number | null;
|
|
29
|
+
error: string | null;
|
|
30
|
+
}
|
|
31
|
+
export declare class SchedulerStateDB {
|
|
32
|
+
readonly db: Database.Database;
|
|
33
|
+
constructor(dbPath?: string);
|
|
34
|
+
migrate(): void;
|
|
35
|
+
enqueue(taskName: string, payload: unknown, opts?: EnqueueOptions): number;
|
|
36
|
+
claimNext(now?: Date): QueueItem | null;
|
|
37
|
+
complete(id: number, now?: Date): void;
|
|
38
|
+
fail(id: number, error: string, opts?: {
|
|
39
|
+
retryAt?: Date;
|
|
40
|
+
maxAttempts?: number;
|
|
41
|
+
now?: Date;
|
|
42
|
+
}): void;
|
|
43
|
+
get(id: number): QueueItem | null;
|
|
44
|
+
list(status?: QueueStatus): QueueItem[];
|
|
45
|
+
requeueRunning(now?: Date): number;
|
|
46
|
+
retryFailed(taskName?: string, now?: Date): number;
|
|
47
|
+
listHistory(opts?: {
|
|
48
|
+
taskName?: string;
|
|
49
|
+
limit?: number;
|
|
50
|
+
}): SchedulerHistoryItem[];
|
|
51
|
+
getHistoryItem(id: number): SchedulerHistoryItem | null;
|
|
52
|
+
recordHistory(taskName: string, payload: unknown, status: string, startedAt: Date, finishedAt: Date | null, durationMs: number | null, error: string | null): void;
|
|
53
|
+
close(): void;
|
|
54
|
+
private getQueuedByDedupe;
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=state.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../../src/scheduler/state.ts"],"names":[],"mappings":"AAAA,OAAO,QAAQ,MAAM,gBAAgB,CAAC;AAMtC,MAAM,MAAM,WAAW,GAAG,QAAQ,GAAG,SAAS,GAAG,MAAM,GAAG,QAAQ,CAAC;AAEnE,MAAM,WAAW,SAAS,CAAC,CAAC,GAAG,OAAO;IACpC,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,CAAC,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,MAAM,EAAE,WAAW,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,IAAI,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,GAAG,CAAC,EAAE,IAAI,CAAC;CACZ;AAED,MAAM,WAAW,oBAAoB,CAAC,CAAC,GAAG,OAAO;IAC/C,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,CAAC,GAAG,IAAI,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;CACtB;AAED,qBAAa,gBAAgB;IAC3B,QAAQ,CAAC,EAAE,EAAE,QAAQ,CAAC,QAAQ,CAAC;gBAEnB,MAAM,SAAiC;IAOnD,OAAO,IAAI,IAAI;IA6Cf,OAAO,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,GAAE,cAAmB,GAAG,MAAM;IAuB9E,SAAS,CAAC,GAAG,OAAa,GAAG,SAAS,GAAG,IAAI;IA4B7C,QAAQ,CAAC,EAAE,EAAE,MAAM,EAAE,GAAG,OAAa,GAAG,IAAI;IAI5C,IAAI,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,GAAE;QAAE,OAAO,CAAC,EAAE,IAAI,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,CAAC;QAAC,GAAG,CAAC,EAAE,IAAI,CAAA;KAAO,GAAG,IAAI;IAiBtG,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI;IAKjC,IAAI,CAAC,MAAM,CAAC,EAAE,WAAW,GAAG,SAAS,EAAE;IAOvC,cAAc,CAAC,GAAG,OAAa,GAAG,MAAM;IASxC,WAAW,CAAC,QAAQ,CAAC,EAAE,MAAM,EAAE,GAAG,OAAa,GAAG,MAAM;IAexD,WAAW,CAAC,IAAI,GAAE;QAAE,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAO,GAAG,oBAAoB,EAAE;IAQrF,cAAc,CAAC,EAAE,EAAE,MAAM,GAAG,oBAAoB,GAAG,IAAI;IAKvD,aAAa,CACX,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,OAAO,EAChB,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,IAAI,EACf,UAAU,EAAE,IAAI,GAAG,IAAI,EACvB,UAAU,EAAE,MAAM,GAAG,IAAI,EACzB,KAAK,EAAE,MAAM,GAAG,IAAI,GACnB,IAAI;IAgBP,KAAK,IAAI,IAAI;IAIb,OAAO,CAAC,iBAAiB;CAQ1B"}
|
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
import Database from "better-sqlite3";
|
|
2
|
+
import { mkdirSync } from "node:fs";
|
|
3
|
+
import { dirname } from "node:path";
|
|
4
|
+
import { getParaPaths } from "../paths.js";
|
|
5
|
+
import { ensureLeaseSchema } from "./leases.js";
|
|
6
|
+
export class SchedulerStateDB {
|
|
7
|
+
db;
|
|
8
|
+
constructor(dbPath = getParaPaths().schedulerDbPath) {
|
|
9
|
+
mkdirSync(dirname(dbPath), { recursive: true });
|
|
10
|
+
this.db = new Database(dbPath);
|
|
11
|
+
this.db.pragma("journal_mode = WAL");
|
|
12
|
+
this.migrate();
|
|
13
|
+
}
|
|
14
|
+
migrate() {
|
|
15
|
+
ensureLeaseSchema(this.db);
|
|
16
|
+
this.db.exec(`
|
|
17
|
+
CREATE TABLE IF NOT EXISTS scheduler_tasks (
|
|
18
|
+
task_key TEXT PRIMARY KEY,
|
|
19
|
+
task_name TEXT NOT NULL,
|
|
20
|
+
scope TEXT,
|
|
21
|
+
schedule TEXT,
|
|
22
|
+
next_due_at TEXT,
|
|
23
|
+
last_run_at TEXT,
|
|
24
|
+
last_status TEXT,
|
|
25
|
+
retry_count INTEGER NOT NULL DEFAULT 0,
|
|
26
|
+
updated_at TEXT NOT NULL
|
|
27
|
+
);
|
|
28
|
+
|
|
29
|
+
CREATE TABLE IF NOT EXISTS scheduler_queue (
|
|
30
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
31
|
+
task_name TEXT NOT NULL,
|
|
32
|
+
payload_json TEXT NOT NULL,
|
|
33
|
+
priority INTEGER NOT NULL DEFAULT 0,
|
|
34
|
+
available_at TEXT NOT NULL,
|
|
35
|
+
dedupe_key TEXT,
|
|
36
|
+
status TEXT NOT NULL DEFAULT 'queued',
|
|
37
|
+
attempts INTEGER NOT NULL DEFAULT 0,
|
|
38
|
+
created_at TEXT NOT NULL,
|
|
39
|
+
updated_at TEXT NOT NULL
|
|
40
|
+
);
|
|
41
|
+
|
|
42
|
+
CREATE UNIQUE INDEX IF NOT EXISTS scheduler_queue_dedupe
|
|
43
|
+
ON scheduler_queue(dedupe_key)
|
|
44
|
+
WHERE dedupe_key IS NOT NULL AND status IN ('queued', 'running');
|
|
45
|
+
|
|
46
|
+
CREATE TABLE IF NOT EXISTS scheduler_history (
|
|
47
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
48
|
+
task_name TEXT NOT NULL,
|
|
49
|
+
payload_json TEXT,
|
|
50
|
+
status TEXT NOT NULL,
|
|
51
|
+
started_at TEXT NOT NULL,
|
|
52
|
+
finished_at TEXT,
|
|
53
|
+
duration_ms INTEGER,
|
|
54
|
+
error TEXT
|
|
55
|
+
);
|
|
56
|
+
`);
|
|
57
|
+
}
|
|
58
|
+
enqueue(taskName, payload, opts = {}) {
|
|
59
|
+
const now = opts.now ?? new Date();
|
|
60
|
+
const availableAt = opts.availableAt ?? now;
|
|
61
|
+
const payloadJson = JSON.stringify(payload ?? {});
|
|
62
|
+
const existing = opts.dedupeKey ? this.getQueuedByDedupe(opts.dedupeKey) : null;
|
|
63
|
+
if (existing)
|
|
64
|
+
return existing.id;
|
|
65
|
+
const result = this.db.prepare(`
|
|
66
|
+
INSERT INTO scheduler_queue
|
|
67
|
+
(task_name, payload_json, priority, available_at, dedupe_key, status, attempts, created_at, updated_at)
|
|
68
|
+
VALUES (?, ?, ?, ?, ?, 'queued', 0, ?, ?)
|
|
69
|
+
`).run(taskName, payloadJson, opts.priority ?? 0, availableAt.toISOString(), opts.dedupeKey ?? null, now.toISOString(), now.toISOString());
|
|
70
|
+
return Number(result.lastInsertRowid);
|
|
71
|
+
}
|
|
72
|
+
claimNext(now = new Date()) {
|
|
73
|
+
this.db.exec("BEGIN IMMEDIATE");
|
|
74
|
+
try {
|
|
75
|
+
const row = this.db.prepare(`
|
|
76
|
+
SELECT * FROM scheduler_queue
|
|
77
|
+
WHERE status = 'queued' AND available_at <= ?
|
|
78
|
+
ORDER BY priority DESC, id ASC
|
|
79
|
+
LIMIT 1
|
|
80
|
+
`).get(now.toISOString());
|
|
81
|
+
if (!row) {
|
|
82
|
+
this.db.exec("COMMIT");
|
|
83
|
+
return null;
|
|
84
|
+
}
|
|
85
|
+
this.db.prepare(`
|
|
86
|
+
UPDATE scheduler_queue
|
|
87
|
+
SET status = 'running', attempts = attempts + 1, updated_at = ?
|
|
88
|
+
WHERE id = ?
|
|
89
|
+
`).run(now.toISOString(), row.id);
|
|
90
|
+
this.db.exec("COMMIT");
|
|
91
|
+
return rowToItem({ ...row, status: "running", attempts: row.attempts + 1, updated_at: now.toISOString() });
|
|
92
|
+
}
|
|
93
|
+
catch (err) {
|
|
94
|
+
try {
|
|
95
|
+
this.db.exec("ROLLBACK");
|
|
96
|
+
}
|
|
97
|
+
catch { }
|
|
98
|
+
throw err;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
complete(id, now = new Date()) {
|
|
102
|
+
this.db.prepare("UPDATE scheduler_queue SET status = 'done', updated_at = ? WHERE id = ?").run(now.toISOString(), id);
|
|
103
|
+
}
|
|
104
|
+
fail(id, error, opts = {}) {
|
|
105
|
+
const now = opts.now ?? new Date();
|
|
106
|
+
const row = this.get(id);
|
|
107
|
+
if (!row)
|
|
108
|
+
return;
|
|
109
|
+
const maxAttempts = opts.maxAttempts ?? 3;
|
|
110
|
+
if (row.attempts < maxAttempts && opts.retryAt) {
|
|
111
|
+
this.db.prepare(`
|
|
112
|
+
UPDATE scheduler_queue
|
|
113
|
+
SET status = 'queued', available_at = ?, updated_at = ?
|
|
114
|
+
WHERE id = ?
|
|
115
|
+
`).run(opts.retryAt.toISOString(), now.toISOString(), id);
|
|
116
|
+
}
|
|
117
|
+
else {
|
|
118
|
+
this.db.prepare("UPDATE scheduler_queue SET status = 'failed', updated_at = ? WHERE id = ?").run(now.toISOString(), id);
|
|
119
|
+
}
|
|
120
|
+
this.recordHistory(row.taskName, row.payload, "failed", now, now, 0, error);
|
|
121
|
+
}
|
|
122
|
+
get(id) {
|
|
123
|
+
const row = this.db.prepare("SELECT * FROM scheduler_queue WHERE id = ?").get(id);
|
|
124
|
+
return row ? rowToItem(row) : null;
|
|
125
|
+
}
|
|
126
|
+
list(status) {
|
|
127
|
+
const rows = status
|
|
128
|
+
? this.db.prepare("SELECT * FROM scheduler_queue WHERE status = ? ORDER BY id ASC").all(status)
|
|
129
|
+
: this.db.prepare("SELECT * FROM scheduler_queue ORDER BY id ASC").all();
|
|
130
|
+
return rows.map(rowToItem);
|
|
131
|
+
}
|
|
132
|
+
requeueRunning(now = new Date()) {
|
|
133
|
+
const result = this.db.prepare(`
|
|
134
|
+
UPDATE scheduler_queue
|
|
135
|
+
SET status = 'queued', available_at = ?, updated_at = ?
|
|
136
|
+
WHERE status = 'running'
|
|
137
|
+
`).run(now.toISOString(), now.toISOString());
|
|
138
|
+
return result.changes;
|
|
139
|
+
}
|
|
140
|
+
retryFailed(taskName, now = new Date()) {
|
|
141
|
+
const result = taskName
|
|
142
|
+
? this.db.prepare(`
|
|
143
|
+
UPDATE scheduler_queue
|
|
144
|
+
SET status = 'queued', available_at = ?, updated_at = ?
|
|
145
|
+
WHERE status = 'failed' AND task_name = ?
|
|
146
|
+
`).run(now.toISOString(), now.toISOString(), taskName)
|
|
147
|
+
: this.db.prepare(`
|
|
148
|
+
UPDATE scheduler_queue
|
|
149
|
+
SET status = 'queued', available_at = ?, updated_at = ?
|
|
150
|
+
WHERE status = 'failed'
|
|
151
|
+
`).run(now.toISOString(), now.toISOString());
|
|
152
|
+
return result.changes;
|
|
153
|
+
}
|
|
154
|
+
listHistory(opts = {}) {
|
|
155
|
+
const limit = opts.limit ?? 20;
|
|
156
|
+
const rows = opts.taskName
|
|
157
|
+
? this.db.prepare("SELECT * FROM scheduler_history WHERE task_name = ? ORDER BY id DESC LIMIT ?").all(opts.taskName, limit)
|
|
158
|
+
: this.db.prepare("SELECT * FROM scheduler_history ORDER BY id DESC LIMIT ?").all(limit);
|
|
159
|
+
return rows.map(rowToHistoryItem);
|
|
160
|
+
}
|
|
161
|
+
getHistoryItem(id) {
|
|
162
|
+
const row = this.db.prepare("SELECT * FROM scheduler_history WHERE id = ?").get(id);
|
|
163
|
+
return row ? rowToHistoryItem(row) : null;
|
|
164
|
+
}
|
|
165
|
+
recordHistory(taskName, payload, status, startedAt, finishedAt, durationMs, error) {
|
|
166
|
+
this.db.prepare(`
|
|
167
|
+
INSERT INTO scheduler_history
|
|
168
|
+
(task_name, payload_json, status, started_at, finished_at, duration_ms, error)
|
|
169
|
+
VALUES (?, ?, ?, ?, ?, ?, ?)
|
|
170
|
+
`).run(taskName, JSON.stringify(payload ?? {}), status, startedAt.toISOString(), finishedAt?.toISOString() ?? null, durationMs, error);
|
|
171
|
+
}
|
|
172
|
+
close() {
|
|
173
|
+
this.db.close();
|
|
174
|
+
}
|
|
175
|
+
getQueuedByDedupe(dedupeKey) {
|
|
176
|
+
const row = this.db.prepare(`
|
|
177
|
+
SELECT * FROM scheduler_queue
|
|
178
|
+
WHERE dedupe_key = ? AND status IN ('queued', 'running')
|
|
179
|
+
ORDER BY id ASC LIMIT 1
|
|
180
|
+
`).get(dedupeKey);
|
|
181
|
+
return row ? rowToItem(row) : null;
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
function rowToItem(row) {
|
|
185
|
+
return {
|
|
186
|
+
id: row.id,
|
|
187
|
+
taskName: row.task_name,
|
|
188
|
+
payload: JSON.parse(row.payload_json),
|
|
189
|
+
priority: row.priority,
|
|
190
|
+
availableAt: row.available_at,
|
|
191
|
+
dedupeKey: row.dedupe_key,
|
|
192
|
+
status: row.status,
|
|
193
|
+
attempts: row.attempts,
|
|
194
|
+
createdAt: row.created_at,
|
|
195
|
+
updatedAt: row.updated_at,
|
|
196
|
+
};
|
|
197
|
+
}
|
|
198
|
+
function rowToHistoryItem(row) {
|
|
199
|
+
return {
|
|
200
|
+
id: row.id,
|
|
201
|
+
taskName: row.task_name,
|
|
202
|
+
payload: row.payload_json ? JSON.parse(row.payload_json) : null,
|
|
203
|
+
status: row.status,
|
|
204
|
+
startedAt: row.started_at,
|
|
205
|
+
finishedAt: row.finished_at,
|
|
206
|
+
durationMs: row.duration_ms,
|
|
207
|
+
error: row.error,
|
|
208
|
+
};
|
|
209
|
+
}
|
|
210
|
+
//# sourceMappingURL=state.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"state.js","sourceRoot":"","sources":["../../src/scheduler/state.ts"],"names":[],"mappings":"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"}
|
package/dist/scope.d.ts
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Project scope detection and filtering.
|
|
3
|
+
*
|
|
4
|
+
* Determines which wiki pages are relevant to the current working context
|
|
5
|
+
* by auto-detecting project name from cwd (git remote, git root, dirname)
|
|
6
|
+
* or reading explicit config from .pi/wiki-scope.json.
|
|
7
|
+
*/
|
|
8
|
+
export interface ProjectScope {
|
|
9
|
+
name: string;
|
|
10
|
+
include: string[];
|
|
11
|
+
exclude: string[];
|
|
12
|
+
source: "config" | "git-remote" | "git-root" | "dirname";
|
|
13
|
+
}
|
|
14
|
+
/** .pi/wiki-scope.json schema */
|
|
15
|
+
export interface ScopeConfig {
|
|
16
|
+
name: string;
|
|
17
|
+
include?: string[];
|
|
18
|
+
exclude?: string[];
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Extract a repo name from a git remote URL.
|
|
22
|
+
*
|
|
23
|
+
* Handles:
|
|
24
|
+
* git@github.com:user/repo.git -> repo
|
|
25
|
+
* https://github.com/user/repo.git -> repo
|
|
26
|
+
* https://github.com/user/repo -> repo
|
|
27
|
+
* ssh://git@host/user/repo.git -> repo
|
|
28
|
+
*/
|
|
29
|
+
export declare function extractRepoName(remoteUrl: string): string | null;
|
|
30
|
+
/**
|
|
31
|
+
* Load .pi/wiki-scope.json from the given directory.
|
|
32
|
+
* Returns null if the file doesn't exist or is invalid JSON.
|
|
33
|
+
*/
|
|
34
|
+
export declare function loadScopeConfig(cwd: string): Promise<ScopeConfig | null>;
|
|
35
|
+
/**
|
|
36
|
+
* Auto-detect project scope from the working directory.
|
|
37
|
+
*
|
|
38
|
+
* Detection priority:
|
|
39
|
+
* 1. .pi/wiki-scope.json (explicit config)
|
|
40
|
+
* 2. Git remote origin URL -> repo name
|
|
41
|
+
* 3. Git repository root directory name
|
|
42
|
+
* 4. cwd basename (fallback)
|
|
43
|
+
*/
|
|
44
|
+
export declare function detectScope(cwd: string): Promise<ProjectScope>;
|
|
45
|
+
/**
|
|
46
|
+
* Check whether a page's scope tags match the project scope.
|
|
47
|
+
*
|
|
48
|
+
* Rules:
|
|
49
|
+
* - A page matches if its scope contains "global" OR any tag in projectScope.include
|
|
50
|
+
* - A page is excluded if its scope contains any tag in projectScope.exclude
|
|
51
|
+
* - Exclude takes priority over include
|
|
52
|
+
*/
|
|
53
|
+
export declare function matchesScope(pageScope: string[], projectScope: ProjectScope): boolean;
|
|
54
|
+
//# sourceMappingURL=scope.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scope.d.ts","sourceRoot":"","sources":["../src/scope.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAQH,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,MAAM,EAAE,QAAQ,GAAG,YAAY,GAAG,UAAU,GAAG,SAAS,CAAC;CAC1D;AAED,iCAAiC;AACjC,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;CACpB;AAsBD;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAYhE;AAID;;;GAGG;AACH,wBAAsB,eAAe,CACnC,GAAG,EAAE,MAAM,GACV,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC,CAwC7B;AAED;;;;;;;;GAQG;AACH,wBAAsB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,CAuDpE;AAED;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAC1B,SAAS,EAAE,MAAM,EAAE,EACnB,YAAY,EAAE,YAAY,GACzB,OAAO,CAeT"}
|
package/dist/scope.js
ADDED
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Project scope detection and filtering.
|
|
3
|
+
*
|
|
4
|
+
* Determines which wiki pages are relevant to the current working context
|
|
5
|
+
* by auto-detecting project name from cwd (git remote, git root, dirname)
|
|
6
|
+
* or reading explicit config from .pi/wiki-scope.json.
|
|
7
|
+
*/
|
|
8
|
+
import { execFile } from "node:child_process";
|
|
9
|
+
import { readFile } from "node:fs/promises";
|
|
10
|
+
import { basename, join } from "node:path";
|
|
11
|
+
// -- Helpers ----------------------------------------------------------------
|
|
12
|
+
/** Run a command and return trimmed stdout, or null on failure. */
|
|
13
|
+
function exec(cmd, args, cwd) {
|
|
14
|
+
return new Promise((resolve) => {
|
|
15
|
+
execFile(cmd, args, { cwd }, (err, stdout) => {
|
|
16
|
+
if (err) {
|
|
17
|
+
resolve(null);
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
const trimmed = (stdout ?? "").trim();
|
|
21
|
+
resolve(trimmed || null);
|
|
22
|
+
});
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Extract a repo name from a git remote URL.
|
|
27
|
+
*
|
|
28
|
+
* Handles:
|
|
29
|
+
* git@github.com:user/repo.git -> repo
|
|
30
|
+
* https://github.com/user/repo.git -> repo
|
|
31
|
+
* https://github.com/user/repo -> repo
|
|
32
|
+
* ssh://git@host/user/repo.git -> repo
|
|
33
|
+
*/
|
|
34
|
+
export function extractRepoName(remoteUrl) {
|
|
35
|
+
// Strip trailing slashes
|
|
36
|
+
let url = remoteUrl.trim().replace(/\/+$/, "");
|
|
37
|
+
// Strip .git suffix
|
|
38
|
+
url = url.replace(/\.git$/, "");
|
|
39
|
+
// Get the last path segment
|
|
40
|
+
const lastSlash = url.lastIndexOf("/");
|
|
41
|
+
const lastColon = url.lastIndexOf(":");
|
|
42
|
+
const sep = Math.max(lastSlash, lastColon);
|
|
43
|
+
if (sep < 0 || sep === url.length - 1)
|
|
44
|
+
return null;
|
|
45
|
+
const name = url.slice(sep + 1);
|
|
46
|
+
return name || null;
|
|
47
|
+
}
|
|
48
|
+
// -- Public API -------------------------------------------------------------
|
|
49
|
+
/**
|
|
50
|
+
* Load .pi/wiki-scope.json from the given directory.
|
|
51
|
+
* Returns null if the file doesn't exist or is invalid JSON.
|
|
52
|
+
*/
|
|
53
|
+
export async function loadScopeConfig(cwd) {
|
|
54
|
+
const configPath = join(cwd, ".pi", "wiki-scope.json");
|
|
55
|
+
let raw;
|
|
56
|
+
try {
|
|
57
|
+
raw = await readFile(configPath, "utf-8");
|
|
58
|
+
}
|
|
59
|
+
catch {
|
|
60
|
+
return null;
|
|
61
|
+
}
|
|
62
|
+
let parsed;
|
|
63
|
+
try {
|
|
64
|
+
parsed = JSON.parse(raw);
|
|
65
|
+
}
|
|
66
|
+
catch {
|
|
67
|
+
return null;
|
|
68
|
+
}
|
|
69
|
+
if (typeof parsed !== "object" ||
|
|
70
|
+
parsed === null ||
|
|
71
|
+
typeof parsed.name !== "string" ||
|
|
72
|
+
!parsed.name) {
|
|
73
|
+
return null;
|
|
74
|
+
}
|
|
75
|
+
const obj = parsed;
|
|
76
|
+
const config = { name: obj.name };
|
|
77
|
+
if (Array.isArray(obj.include)) {
|
|
78
|
+
config.include = obj.include.filter((v) => typeof v === "string");
|
|
79
|
+
}
|
|
80
|
+
if (Array.isArray(obj.exclude)) {
|
|
81
|
+
config.exclude = obj.exclude.filter((v) => typeof v === "string");
|
|
82
|
+
}
|
|
83
|
+
return config;
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Auto-detect project scope from the working directory.
|
|
87
|
+
*
|
|
88
|
+
* Detection priority:
|
|
89
|
+
* 1. .pi/wiki-scope.json (explicit config)
|
|
90
|
+
* 2. Git remote origin URL -> repo name
|
|
91
|
+
* 3. Git repository root directory name
|
|
92
|
+
* 4. cwd basename (fallback)
|
|
93
|
+
*/
|
|
94
|
+
export async function detectScope(cwd) {
|
|
95
|
+
// 1. Explicit config
|
|
96
|
+
const config = await loadScopeConfig(cwd);
|
|
97
|
+
if (config) {
|
|
98
|
+
const include = Array.from(new Set([config.name, ...(config.include ?? [])]));
|
|
99
|
+
return {
|
|
100
|
+
name: config.name,
|
|
101
|
+
include,
|
|
102
|
+
exclude: config.exclude ?? [],
|
|
103
|
+
source: "config",
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
// 2. Git remote origin
|
|
107
|
+
const remoteUrl = await exec("git", ["remote", "get-url", "origin"], cwd);
|
|
108
|
+
if (remoteUrl) {
|
|
109
|
+
const repoName = extractRepoName(remoteUrl);
|
|
110
|
+
if (repoName) {
|
|
111
|
+
return {
|
|
112
|
+
name: repoName,
|
|
113
|
+
include: [repoName],
|
|
114
|
+
exclude: [],
|
|
115
|
+
source: "git-remote",
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
// 3. Git root directory name
|
|
120
|
+
const gitRoot = await exec("git", ["rev-parse", "--show-toplevel"], cwd);
|
|
121
|
+
if (gitRoot) {
|
|
122
|
+
const name = basename(gitRoot);
|
|
123
|
+
if (name) {
|
|
124
|
+
return {
|
|
125
|
+
name,
|
|
126
|
+
include: [name],
|
|
127
|
+
exclude: [],
|
|
128
|
+
source: "git-root",
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
// 4. Fallback to cwd basename
|
|
133
|
+
const name = basename(cwd);
|
|
134
|
+
return {
|
|
135
|
+
name,
|
|
136
|
+
include: [name],
|
|
137
|
+
exclude: [],
|
|
138
|
+
source: "dirname",
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Check whether a page's scope tags match the project scope.
|
|
143
|
+
*
|
|
144
|
+
* Rules:
|
|
145
|
+
* - A page matches if its scope contains "global" OR any tag in projectScope.include
|
|
146
|
+
* - A page is excluded if its scope contains any tag in projectScope.exclude
|
|
147
|
+
* - Exclude takes priority over include
|
|
148
|
+
*/
|
|
149
|
+
export function matchesScope(pageScope, projectScope) {
|
|
150
|
+
// Exclude takes priority
|
|
151
|
+
if (projectScope.exclude.length > 0 &&
|
|
152
|
+
pageScope.some((tag) => projectScope.exclude.includes(tag))) {
|
|
153
|
+
return false;
|
|
154
|
+
}
|
|
155
|
+
// Match: "global" or any include tag
|
|
156
|
+
if (pageScope.includes("global")) {
|
|
157
|
+
return true;
|
|
158
|
+
}
|
|
159
|
+
return pageScope.some((tag) => projectScope.include.includes(tag));
|
|
160
|
+
}
|
|
161
|
+
//# sourceMappingURL=scope.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scope.js","sourceRoot":"","sources":["../src/scope.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bulk-link-fix.d.ts","sourceRoot":"","sources":["../../src/scripts/bulk-link-fix.ts"],"names":[],"mappings":";AACA;;;;;GAKG"}
|