@shivaedev/work-board 0.7.2 → 0.8.0
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/CHANGELOG.md +24 -0
- package/README.md +93 -2
- package/assets/agent.js +37 -0
- package/assets/native.js +32 -25
- package/dist/board.d.ts +1 -0
- package/dist/board.d.ts.map +1 -1
- package/dist/board.js +15 -2
- package/dist/board.js.map +1 -1
- package/dist/browser/client.d.ts +19 -79
- package/dist/browser/client.d.ts.map +1 -1
- package/dist/browser/client.js +12 -1
- package/dist/browser/client.js.map +1 -1
- package/dist/browser/entry.d.ts +3 -0
- package/dist/browser/entry.d.ts.map +1 -0
- package/dist/browser/entry.js +7 -0
- package/dist/browser/entry.js.map +1 -0
- package/dist/browser/responses/draftSession.d.ts +8 -0
- package/dist/browser/responses/draftSession.d.ts.map +1 -0
- package/dist/browser/responses/draftSession.js +92 -0
- package/dist/browser/responses/draftSession.js.map +1 -0
- package/dist/browser/responses/drafts.d.ts +16 -0
- package/dist/browser/responses/drafts.d.ts.map +1 -0
- package/dist/browser/responses/drafts.js +49 -0
- package/dist/browser/responses/drafts.js.map +1 -0
- package/dist/browser/responses/preview.d.ts +3 -0
- package/dist/browser/responses/preview.d.ts.map +1 -0
- package/dist/browser/responses/preview.js +4 -0
- package/dist/browser/responses/preview.js.map +1 -0
- package/dist/browser/responses/schema.d.ts +127 -0
- package/dist/browser/responses/schema.d.ts.map +1 -0
- package/dist/browser/responses/schema.js +47 -0
- package/dist/browser/responses/schema.js.map +1 -0
- package/dist/browser/responses/setup.d.ts +2 -0
- package/dist/browser/responses/setup.d.ts.map +1 -0
- package/dist/browser/responses/setup.js +99 -0
- package/dist/browser/responses/setup.js.map +1 -0
- package/dist/browser/responses/submit.d.ts +4 -0
- package/dist/browser/responses/submit.d.ts.map +1 -0
- package/dist/browser/responses/submit.js +36 -0
- package/dist/browser/responses/submit.js.map +1 -0
- package/dist/browser/session.d.ts +1 -79
- package/dist/browser/session.d.ts.map +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +24 -15
- package/dist/cli.js.map +1 -1
- package/dist/files/changes.d.ts +1 -0
- package/dist/files/changes.d.ts.map +1 -1
- package/dist/files/changes.js +1 -1
- package/dist/files/changes.js.map +1 -1
- package/dist/http/respond.d.ts.map +1 -1
- package/dist/http/respond.js +2 -0
- package/dist/http/respond.js.map +1 -1
- package/dist/metadata/backlinks.d.ts.map +1 -1
- package/dist/metadata/backlinks.js +2 -0
- package/dist/metadata/backlinks.js.map +1 -1
- package/dist/metadata/fields.d.ts +17 -1
- package/dist/metadata/fields.d.ts.map +1 -1
- package/dist/metadata/problems.d.ts.map +1 -1
- package/dist/metadata/problems.js +2 -0
- package/dist/metadata/problems.js.map +1 -1
- package/dist/metadata/schema.d.ts +17 -1
- package/dist/metadata/schema.d.ts.map +1 -1
- package/dist/metadata/schema.js +6 -2
- package/dist/metadata/schema.js.map +1 -1
- package/dist/page/attentionDetails.d.ts.map +1 -1
- package/dist/page/attentionDetails.js +2 -1
- package/dist/page/attentionDetails.js.map +1 -1
- package/dist/page/metadataDetails.d.ts.map +1 -1
- package/dist/page/metadataDetails.js +6 -0
- package/dist/page/metadataDetails.js.map +1 -1
- package/dist/page/navigationScript.js +1 -1
- package/dist/page/shell.d.ts +1 -1
- package/dist/page/shell.d.ts.map +1 -1
- package/dist/page/shell.js.map +1 -1
- package/dist/page/style.d.ts.map +1 -1
- package/dist/page/style.js +2 -1
- package/dist/page/style.js.map +1 -1
- package/dist/page/swap.d.ts +1 -1
- package/dist/page/swap.d.ts.map +1 -1
- package/dist/page/swap.js +3 -0
- package/dist/page/swap.js.map +1 -1
- package/dist/path/Identity.d.ts +3 -0
- package/dist/path/Identity.d.ts.map +1 -0
- package/dist/path/Identity.js +3 -0
- package/dist/path/Identity.js.map +1 -0
- package/dist/responses/agent-cli.d.ts +2 -0
- package/dist/responses/agent-cli.d.ts.map +1 -0
- package/dist/responses/agent-cli.js +31 -0
- package/dist/responses/agent-cli.js.map +1 -0
- package/dist/responses/agent.d.ts +68 -0
- package/dist/responses/agent.d.ts.map +1 -0
- package/dist/responses/agent.js +49 -0
- package/dist/responses/agent.js.map +1 -0
- package/dist/responses/await.d.ts +33 -0
- package/dist/responses/await.d.ts.map +1 -0
- package/dist/responses/await.js +21 -0
- package/dist/responses/await.js.map +1 -0
- package/dist/responses/flags.d.ts +6 -0
- package/dist/responses/flags.d.ts.map +1 -0
- package/dist/responses/flags.js +23 -0
- package/dist/responses/flags.js.map +1 -0
- package/dist/responses/locate.d.ts +13 -0
- package/dist/responses/locate.d.ts.map +1 -0
- package/dist/responses/locate.js +50 -0
- package/dist/responses/locate.js.map +1 -0
- package/dist/responses/outcome.d.ts +65 -0
- package/dist/responses/outcome.d.ts.map +1 -0
- package/dist/responses/outcome.js +14 -0
- package/dist/responses/outcome.js.map +1 -0
- package/dist/responses/page.d.ts +6 -0
- package/dist/responses/page.d.ts.map +1 -0
- package/dist/responses/page.js +25 -0
- package/dist/responses/page.js.map +1 -0
- package/dist/responses/publish.d.ts +4 -0
- package/dist/responses/publish.d.ts.map +1 -0
- package/dist/responses/publish.js +56 -0
- package/dist/responses/publish.js.map +1 -0
- package/dist/responses/publishIn.d.ts +3 -0
- package/dist/responses/publishIn.d.ts.map +1 -0
- package/dist/responses/publishIn.js +69 -0
- package/dist/responses/publishIn.js.map +1 -0
- package/dist/responses/read.d.ts +30 -0
- package/dist/responses/read.d.ts.map +1 -0
- package/dist/responses/read.js +43 -0
- package/dist/responses/read.js.map +1 -0
- package/dist/responses/records.d.ts +12 -0
- package/dist/responses/records.d.ts.map +1 -0
- package/dist/responses/records.js +47 -0
- package/dist/responses/records.js.map +1 -0
- package/dist/responses/retry.d.ts +22 -0
- package/dist/responses/retry.d.ts.map +1 -0
- package/dist/responses/retry.js +14 -0
- package/dist/responses/retry.js.map +1 -0
- package/dist/responses/service.d.ts +106 -0
- package/dist/responses/service.d.ts.map +1 -0
- package/dist/responses/service.js +90 -0
- package/dist/responses/service.js.map +1 -0
- package/dist/responses/waitFor.d.ts +31 -0
- package/dist/responses/waitFor.d.ts.map +1 -0
- package/dist/responses/waitFor.js +47 -0
- package/dist/responses/waitFor.js.map +1 -0
- package/dist/rpc/contract.d.ts +101 -2
- package/dist/rpc/contract.d.ts.map +1 -1
- package/dist/rpc/contract.js +3 -2
- package/dist/rpc/contract.js.map +1 -1
- package/dist/rpc/responseContract.d.ts +212 -0
- package/dist/rpc/responseContract.d.ts.map +1 -0
- package/dist/rpc/responseContract.js +37 -0
- package/dist/rpc/responseContract.js.map +1 -0
- package/dist/rpc/server.d.ts +3 -1
- package/dist/rpc/server.d.ts.map +1 -1
- package/dist/rpc/server.js +6 -1
- package/dist/rpc/server.js.map +1 -1
- package/dist/serve-cli.d.ts +3 -0
- package/dist/serve-cli.d.ts.map +1 -0
- package/dist/serve-cli.js +20 -0
- package/dist/serve-cli.js.map +1 -0
- package/package.json +2 -2
- package/src/board.ts +16 -2
- package/src/browser/client.ts +30 -4
- package/src/browser/entry.ts +9 -0
- package/src/browser/responses/draftSession.ts +88 -0
- package/src/browser/responses/drafts.ts +58 -0
- package/src/browser/responses/preview.ts +5 -0
- package/src/browser/responses/schema.ts +52 -0
- package/src/browser/responses/setup.ts +102 -0
- package/src/browser/responses/submit.ts +41 -0
- package/src/cli.ts +14 -22
- package/src/files/changes.ts +2 -1
- package/src/http/respond.ts +2 -0
- package/src/metadata/backlinks.ts +2 -0
- package/src/metadata/problems.ts +2 -0
- package/src/metadata/schema.ts +6 -2
- package/src/page/attentionDetails.ts +2 -1
- package/src/page/metadataDetails.ts +6 -0
- package/src/page/navigationScript.ts +1 -1
- package/src/page/shell.ts +1 -1
- package/src/page/style.ts +2 -1
- package/src/page/swap.ts +3 -0
- package/src/path/Identity.ts +3 -0
- package/src/responses/agent-cli.ts +35 -0
- package/src/responses/agent.ts +59 -0
- package/src/responses/await.ts +21 -0
- package/src/responses/flags.ts +22 -0
- package/src/responses/locate.ts +55 -0
- package/src/responses/outcome.ts +15 -0
- package/src/responses/page.ts +41 -0
- package/src/responses/publish.ts +53 -0
- package/src/responses/publishIn.ts +64 -0
- package/src/responses/read.ts +45 -0
- package/src/responses/records.ts +53 -0
- package/src/responses/retry.ts +23 -0
- package/src/responses/service.ts +106 -0
- package/src/responses/waitFor.ts +58 -0
- package/src/rpc/contract.ts +3 -2
- package/src/rpc/responseContract.ts +46 -0
- package/src/rpc/server.ts +8 -1
- package/src/serve-cli.ts +37 -0
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import type { Reading } from "#browser/responses/schema.ts";
|
|
2
|
+
export declare function outcome(reading: Reading, after: string | undefined, now: number): {
|
|
3
|
+
readonly kind: "missing_cursor";
|
|
4
|
+
readonly response?: never;
|
|
5
|
+
readonly question?: never;
|
|
6
|
+
} | {
|
|
7
|
+
readonly kind: "response";
|
|
8
|
+
readonly question: {
|
|
9
|
+
readonly context: string;
|
|
10
|
+
readonly id: string;
|
|
11
|
+
readonly question: {
|
|
12
|
+
readonly deadline: number;
|
|
13
|
+
readonly item: string;
|
|
14
|
+
readonly reason: string;
|
|
15
|
+
readonly registeredAt: number;
|
|
16
|
+
readonly request: string;
|
|
17
|
+
readonly reviewedRevision: string;
|
|
18
|
+
readonly source: string;
|
|
19
|
+
};
|
|
20
|
+
};
|
|
21
|
+
readonly response: {
|
|
22
|
+
readonly body: string;
|
|
23
|
+
readonly id: string;
|
|
24
|
+
readonly response: {
|
|
25
|
+
readonly author: string;
|
|
26
|
+
readonly question: string;
|
|
27
|
+
readonly recordedAt: number;
|
|
28
|
+
readonly reviewedRevision: string;
|
|
29
|
+
readonly type: "answer" | "clarify" | "not_now";
|
|
30
|
+
};
|
|
31
|
+
};
|
|
32
|
+
} | {
|
|
33
|
+
readonly response?: never;
|
|
34
|
+
readonly kind: "unanswered";
|
|
35
|
+
readonly question: {
|
|
36
|
+
readonly context: string;
|
|
37
|
+
readonly id: string;
|
|
38
|
+
readonly question: {
|
|
39
|
+
readonly deadline: number;
|
|
40
|
+
readonly item: string;
|
|
41
|
+
readonly reason: string;
|
|
42
|
+
readonly registeredAt: number;
|
|
43
|
+
readonly request: string;
|
|
44
|
+
readonly reviewedRevision: string;
|
|
45
|
+
readonly source: string;
|
|
46
|
+
};
|
|
47
|
+
};
|
|
48
|
+
} | {
|
|
49
|
+
readonly response?: never;
|
|
50
|
+
readonly kind: "pending";
|
|
51
|
+
readonly question: {
|
|
52
|
+
readonly context: string;
|
|
53
|
+
readonly id: string;
|
|
54
|
+
readonly question: {
|
|
55
|
+
readonly deadline: number;
|
|
56
|
+
readonly item: string;
|
|
57
|
+
readonly reason: string;
|
|
58
|
+
readonly registeredAt: number;
|
|
59
|
+
readonly request: string;
|
|
60
|
+
readonly reviewedRevision: string;
|
|
61
|
+
readonly source: string;
|
|
62
|
+
};
|
|
63
|
+
};
|
|
64
|
+
};
|
|
65
|
+
//# sourceMappingURL=outcome.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"outcome.d.ts","sourceRoot":"","sources":["../../src/responses/outcome.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,8BAA8B,CAAC;AAE5D,wBAAgB,OAAO,CAAC,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,GAAG,SAAS,EAAE,GAAG,EAAE,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAY/E"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export function outcome(reading, after, now) {
|
|
2
|
+
const at = after === undefined ? -1 : reading.responses.findIndex((candidate) => candidate.id === after);
|
|
3
|
+
if (after !== undefined && at < 0) {
|
|
4
|
+
return { kind: "missing_cursor" };
|
|
5
|
+
}
|
|
6
|
+
const response = reading.responses[at + 1];
|
|
7
|
+
if (response) {
|
|
8
|
+
return { kind: "response", question: reading.question, response };
|
|
9
|
+
}
|
|
10
|
+
return now >= reading.question.question.deadline
|
|
11
|
+
? { kind: "unanswered", question: reading.question }
|
|
12
|
+
: { kind: "pending", question: reading.question };
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=outcome.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"outcome.js","sourceRoot":"","sources":["../../src/responses/outcome.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,OAAO,CAAC,OAAgB,EAAE,KAAyB,EAAE,GAAW;IAC/E,MAAM,EAAE,GAAG,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,EAAE,KAAK,KAAK,CAAC,CAAC;IACzG,IAAI,KAAK,KAAK,SAAS,IAAI,EAAE,GAAG,CAAC,EAAE,CAAC;QACnC,OAAO,EAAE,IAAI,EAAE,gBAAgB,EAAW,CAAC;IAC5C,CAAC;IACD,MAAM,QAAQ,GAAG,OAAO,CAAC,SAAS,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC;IAC3C,IAAI,QAAQ,EAAE,CAAC;QACd,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,QAAQ,EAAE,OAAO,CAAC,QAAQ,EAAE,QAAQ,EAAW,CAAC;IAC5E,CAAC;IACD,OAAO,GAAG,IAAI,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC,QAAQ;QAC/C,CAAC,CAAE,EAAE,IAAI,EAAE,YAAY,EAAE,QAAQ,EAAE,OAAO,CAAC,QAAQ,EAAY;QAC/D,CAAC,CAAE,EAAE,IAAI,EAAE,SAAS,EAAE,QAAQ,EAAE,OAAO,CAAC,QAAQ,EAAY,CAAC;AAC/D,CAAC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { Effect } from "effect";
|
|
2
|
+
import type { HttpServerRequest } from "effect/unstable/http";
|
|
3
|
+
import type { Changes } from "#files/changes.ts";
|
|
4
|
+
import type { responseService } from "./service.ts";
|
|
5
|
+
export declare function responsePage(service: Effect.Success<ReturnType<typeof responseService>>, changes: Changes, home: string | undefined, enabled: boolean): (request: HttpServerRequest.HttpServerRequest) => Effect.Effect<import("effect/unstable/http/HttpServerResponse").HttpServerResponse, import("effect/PlatformError").PlatformError, import("effect/FileSystem").FileSystem | import("effect/Path").Path>;
|
|
6
|
+
//# sourceMappingURL=page.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"page.d.ts","sourceRoot":"","sources":["../../src/responses/page.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAChC,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAC9D,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAMjD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAEpD,wBAAgB,YAAY,CAC3B,OAAO,EAAE,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,OAAO,eAAe,CAAC,CAAC,EAC3D,OAAO,EAAE,OAAO,EAChB,IAAI,EAAE,MAAM,GAAG,SAAS,EACxB,OAAO,EAAE,OAAO,4PA0BhB"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { Effect } from "effect";
|
|
2
|
+
import { fileUrl } from "#files/url.ts";
|
|
3
|
+
import { respond } from "#http/respond.ts";
|
|
4
|
+
import { escapeHtml } from "#page/escape.ts";
|
|
5
|
+
import { navHtml } from "#page/nav.ts";
|
|
6
|
+
import { shell } from "#page/shell.ts";
|
|
7
|
+
export function responsePage(service, changes, home, enabled) {
|
|
8
|
+
return Effect.fn("WorkBoard.responsePage")(function* (request) {
|
|
9
|
+
const params = new URL(request.url, "http://127.0.0.1").searchParams;
|
|
10
|
+
const item = params.get("item") ?? "";
|
|
11
|
+
const requestId = params.get("request") ?? "";
|
|
12
|
+
const files = yield* changes.files;
|
|
13
|
+
function layout(body, status = 200) {
|
|
14
|
+
return respond(shell("Respond", navHtml(files, "", home), body, changes.realRoot, false, undefined, "response"), "text/html", status);
|
|
15
|
+
}
|
|
16
|
+
return yield* service.locate(item, requestId).pipe(Effect.flatMap((question) => Effect.map(service
|
|
17
|
+
.read(question.id)
|
|
18
|
+
.pipe(Effect.catch((error) => (error.code === "Missing" ? Effect.succeed({ responses: [] }) : Effect.fail(error)))), (recorded) => {
|
|
19
|
+
const q = question;
|
|
20
|
+
const body = `<section class="response-panel"><h1>Respond to ${escapeHtml(item)} / ${escapeHtml(requestId)}</h1><p>${escapeHtml(q.reason)}</p><p><a href="${fileUrl(q.source)}">Source: ${escapeHtml(q.source)}</a> · Reviewed SHA-256: <code>${q.reviewedRevision}</code></p><p>Saved replies are authored feedback. They do not close the request or establish acceptance.</p><details><summary>Exact source being reviewed</summary><pre>${escapeHtml(question.context)}</pre></details><form id="response-form" data-question="${question.id}" data-writable="${enabled}" data-item="${escapeHtml(item)}" data-request="${escapeHtml(requestId)}" data-revision="${q.reviewedRevision}"><label>Local author label <input name="author" maxlength="200" required></label><label>Response kind <select name="type"><option value="answer">Answer (including no)</option><option value="clarify">Ask back / clarify</option><option value="not_now">Not now</option></select></label><label>Your response <textarea name="body" rows="8" maxlength="32768" required></textarea></label><p>Drafts stay in this browser for 30 days after the last edit, with a 2 MiB workspace limit. Saved responses are Markdown files in responses/.</p><button id="response-preview" type="button" disabled>Preview Markdown</button><pre id="response-preview-content" hidden></pre><button id="response-submit" type="submit" disabled>Record response</button><button id="response-clear" type="button" disabled>Clear workspace drafts</button><p id="response-status" role="status">${enabled ? "JavaScript is required to record a response." : "Read-only mode. Restart with --responses to explicitly enable local writes."}</p></form><section id="response-history"><h2>Recorded responses</h2>${recorded.responses.map((record) => `<article><p><a href="/responses/${record.id}.md">${escapeHtml(record.response.author)} · ${escapeHtml(record.response.type)}</a></p><pre>${escapeHtml(record.body)}</pre></article>`).join("") || "<p>No response is recorded for this source revision.</p>"}</section></section>`;
|
|
21
|
+
return layout(body);
|
|
22
|
+
})), Effect.catch((error) => Effect.succeed(layout(`<h1>Response unavailable</h1><p>${escapeHtml(error.message)}</p>`, 409))));
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=page.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"page.js","sourceRoot":"","sources":["../../src/responses/page.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAGhC,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AACxC,OAAO,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAC3C,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,OAAO,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;AAGvC,MAAM,UAAU,YAAY,CAC3B,OAA2D,EAC3D,OAAgB,EAChB,IAAwB,EACxB,OAAgB;IAEhB,OAAO,MAAM,CAAC,EAAE,CAAC,wBAAwB,CAAC,CAAC,QAAQ,CAAC,EAAE,OAA4C;QACjG,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,GAAG,EAAE,kBAAkB,CAAC,CAAC,YAAY,CAAC;QACrE,MAAM,IAAI,GAAG,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;QACtC,MAAM,SAAS,GAAG,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC;QAC9C,MAAM,KAAK,GAAG,KAAK,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC;QACnC,SAAS,MAAM,CAAC,IAAY,EAAE,MAAM,GAAG,GAAG;YACzC,OAAO,OAAO,CAAC,KAAK,CAAC,SAAS,EAAE,OAAO,CAAC,KAAK,EAAE,EAAE,EAAE,IAAI,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,QAAQ,EAAE,KAAK,EAAE,SAAS,EAAE,UAAU,CAAC,EAAE,WAAW,EAAE,MAAM,CAAC,CAAC;QACvI,CAAC;QACD,OAAO,KAAK,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC,IAAI,CACjD,MAAM,CAAC,OAAO,CAAC,CAAC,QAAQ,EAAE,EAAE,CAC3B,MAAM,CAAC,GAAG,CACT,OAAO;aACL,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;aACjB,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,SAAS,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EACpH,CAAC,QAAQ,EAAE,EAAE;YACZ,MAAM,CAAC,GAAG,QAAQ,CAAC;YACnB,MAAM,IAAI,GAAG,kDAAkD,UAAU,CAAC,IAAI,CAAC,MAAM,UAAU,CAAC,SAAS,CAAC,WAAW,UAAU,CAAC,CAAC,CAAC,MAAM,CAAC,mBAAmB,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,aAAa,UAAU,CAAC,CAAC,CAAC,MAAM,CAAC,kCAAkC,CAAC,CAAC,gBAAgB,4KAA4K,UAAU,CAAC,QAAQ,CAAC,OAAO,CAAC,2DAA2D,QAAQ,CAAC,EAAE,oBAAoB,OAAO,gBAAgB,UAAU,CAAC,IAAI,CAAC,mBAAmB,UAAU,CAAC,SAAS,CAAC,oBAAoB,CAAC,CAAC,gBAAgB,s1BAAs1B,OAAO,CAAC,CAAC,CAAC,8CAA8C,CAAC,CAAC,CAAC,6EAA6E,wEAAwE,QAAQ,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,mCAAmC,MAAM,CAAC,EAAE,QAAQ,UAAU,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAM,UAAU,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,gBAAgB,UAAU,CAAC,MAAM,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,0DAA0D,sBAAsB,CAAC;YACt/D,OAAO,MAAM,CAAC,IAAI,CAAC,CAAC;QACrB,CAAC,CACD,CACD,EACD,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,mCAAmC,UAAU,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,CAAC,CACxH,CAAC;IACH,CAAC,CAAC,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { Effect } from "effect";
|
|
2
|
+
import { ResponseFailed } from "#browser/responses/schema.ts";
|
|
3
|
+
export declare function publish(root: string, realRoot: string, id: string, content: string): Effect.Effect<void, ResponseFailed, never>;
|
|
4
|
+
//# sourceMappingURL=publish.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"publish.d.ts","sourceRoot":"","sources":["../../src/responses/publish.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAChC,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAW9D,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,8CAsClF"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { constants } from "node:fs";
|
|
2
|
+
import { mkdir, open, realpath } from "node:fs/promises";
|
|
3
|
+
import { Effect } from "effect";
|
|
4
|
+
import { ResponseFailed } from "#browser/responses/schema.ts";
|
|
5
|
+
import { publishIn } from "./publishIn.js";
|
|
6
|
+
function failure(cause) {
|
|
7
|
+
return cause instanceof ResponseFailed
|
|
8
|
+
? cause
|
|
9
|
+
: new ResponseFailed({
|
|
10
|
+
code: "Unavailable",
|
|
11
|
+
message: "The response could not be recorded. Keep the draft and retry after checking local filesystem access.",
|
|
12
|
+
});
|
|
13
|
+
}
|
|
14
|
+
export function publish(root, realRoot, id, content) {
|
|
15
|
+
return Effect.tryPromise({
|
|
16
|
+
catch: failure,
|
|
17
|
+
try: async () => {
|
|
18
|
+
if (/^[a-zA-Z\d][a-zA-Z\d._-]*$/u.exec(id) === null) {
|
|
19
|
+
throw new ResponseFailed({ code: "Conflict", message: "Invalid response identity." });
|
|
20
|
+
}
|
|
21
|
+
if (process.platform !== "linux") {
|
|
22
|
+
throw new ResponseFailed({
|
|
23
|
+
code: "Unsupported",
|
|
24
|
+
message: "Safe response publication currently requires Linux directory descriptors. Reading remains available.",
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
const directory = await open(root, constants.O_RDONLY | constants.O_DIRECTORY | constants.O_NOFOLLOW);
|
|
28
|
+
try {
|
|
29
|
+
const base = `/proc/self/fd/${directory.fd}`;
|
|
30
|
+
if ((await realpath(base)) !== realRoot || (await realpath(root)) !== realRoot) {
|
|
31
|
+
throw new ResponseFailed({ code: "Conflict", message: "The workspace root changed. Restart against the intended root." });
|
|
32
|
+
}
|
|
33
|
+
try {
|
|
34
|
+
await mkdir(`${base}/responses`);
|
|
35
|
+
}
|
|
36
|
+
catch (cause) {
|
|
37
|
+
if (!(cause instanceof Error && "code" in cause && cause.code === "EEXIST")) {
|
|
38
|
+
throw cause;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
await directory.sync();
|
|
42
|
+
const target = await open(`${base}/responses`, constants.O_RDONLY | constants.O_DIRECTORY | constants.O_NOFOLLOW);
|
|
43
|
+
try {
|
|
44
|
+
await publishIn(target, root, realRoot, id, content);
|
|
45
|
+
}
|
|
46
|
+
finally {
|
|
47
|
+
await target.close();
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
finally {
|
|
51
|
+
await directory.close();
|
|
52
|
+
}
|
|
53
|
+
},
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=publish.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"publish.js","sourceRoot":"","sources":["../../src/responses/publish.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AACpC,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AACzD,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAChC,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAC9D,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAE3C,SAAS,OAAO,CAAC,KAAc;IAC9B,OAAO,KAAK,YAAY,cAAc;QACrC,CAAC,CAAC,KAAK;QACP,CAAC,CAAC,IAAI,cAAc,CAAC;YACnB,IAAI,EAAE,aAAa;YACnB,OAAO,EAAE,sGAAsG;SAC/G,CAAC,CAAC;AACN,CAAC;AACD,MAAM,UAAU,OAAO,CAAC,IAAY,EAAE,QAAgB,EAAE,EAAU,EAAE,OAAe;IAClF,OAAO,MAAM,CAAC,UAAU,CAAC;QACxB,KAAK,EAAE,OAAO;QACd,GAAG,EAAE,KAAK,IAAI,EAAE;YACf,IAAI,6BAA6B,CAAC,IAAI,CAAC,EAAE,CAAC,KAAK,IAAI,EAAE,CAAC;gBACrD,MAAM,IAAI,cAAc,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,OAAO,EAAE,4BAA4B,EAAE,CAAC,CAAC;YACvF,CAAC;YACD,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO,EAAE,CAAC;gBAClC,MAAM,IAAI,cAAc,CAAC;oBACxB,IAAI,EAAE,aAAa;oBACnB,OAAO,EAAE,sGAAsG;iBAC/G,CAAC,CAAC;YACJ,CAAC;YACD,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,IAAI,EAAE,SAAS,CAAC,QAAQ,GAAG,SAAS,CAAC,WAAW,GAAG,SAAS,CAAC,UAAU,CAAC,CAAC;YACtG,IAAI,CAAC;gBACJ,MAAM,IAAI,GAAG,iBAAiB,SAAS,CAAC,EAAE,EAAE,CAAC;gBAC7C,IAAI,CAAC,MAAM,QAAQ,CAAC,IAAI,CAAC,CAAC,KAAK,QAAQ,IAAI,CAAC,MAAM,QAAQ,CAAC,IAAI,CAAC,CAAC,KAAK,QAAQ,EAAE,CAAC;oBAChF,MAAM,IAAI,cAAc,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,OAAO,EAAE,gEAAgE,EAAE,CAAC,CAAC;gBAC3H,CAAC;gBACD,IAAI,CAAC;oBACJ,MAAM,KAAK,CAAC,GAAG,IAAI,YAAY,CAAC,CAAC;gBAClC,CAAC;gBAAC,OAAO,KAAK,EAAE,CAAC;oBAChB,IAAI,CAAC,CAAC,KAAK,YAAY,KAAK,IAAI,MAAM,IAAI,KAAK,IAAI,KAAK,CAAC,IAAI,KAAK,QAAQ,CAAC,EAAE,CAAC;wBAC7E,MAAM,KAAK,CAAC;oBACb,CAAC;gBACF,CAAC;gBACD,MAAM,SAAS,CAAC,IAAI,EAAE,CAAC;gBACvB,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,GAAG,IAAI,YAAY,EAAE,SAAS,CAAC,QAAQ,GAAG,SAAS,CAAC,WAAW,GAAG,SAAS,CAAC,UAAU,CAAC,CAAC;gBAClH,IAAI,CAAC;oBACJ,MAAM,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,EAAE,OAAO,CAAC,CAAC;gBACtD,CAAC;wBAAS,CAAC;oBACV,MAAM,MAAM,CAAC,KAAK,EAAE,CAAC;gBACtB,CAAC;YACF,CAAC;oBAAS,CAAC;gBACV,MAAM,SAAS,CAAC,KAAK,EAAE,CAAC;YACzB,CAAC;QACF,CAAC;KACD,CAAC,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"publishIn.d.ts","sourceRoot":"","sources":["../../src/responses/publishIn.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,UAAU,EAA0C,MAAM,kBAAkB,CAAC;AA4B3F,wBAAsB,SAAS,CAAC,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,iBAiC9G"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { randomUUID } from "node:crypto";
|
|
2
|
+
import { constants } from "node:fs";
|
|
3
|
+
import { link, open, readFile, realpath, unlink } from "node:fs/promises";
|
|
4
|
+
import { ResponseFailed } from "#browser/responses/schema.ts";
|
|
5
|
+
function uncertain(cause) {
|
|
6
|
+
return new ResponseFailed({ cause, code: "Uncertain", message: "Publication may have completed. Re-read the response identity before retrying." });
|
|
7
|
+
}
|
|
8
|
+
function exists(cause) {
|
|
9
|
+
return cause instanceof Error && "code" in cause && cause.code === "EEXIST";
|
|
10
|
+
}
|
|
11
|
+
async function linkOrReconcile(temporary, name, content) {
|
|
12
|
+
try {
|
|
13
|
+
await link(temporary, name);
|
|
14
|
+
return true;
|
|
15
|
+
}
|
|
16
|
+
catch (cause) {
|
|
17
|
+
if (!exists(cause)) {
|
|
18
|
+
throw cause;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
const existing = await open(name, constants.O_RDONLY | constants.O_NOFOLLOW);
|
|
22
|
+
try {
|
|
23
|
+
if ((await readFile(existing, "utf8")) !== content) {
|
|
24
|
+
throw new ResponseFailed({ code: "Conflict", message: "This identity already records different content; no file was replaced." });
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
finally {
|
|
28
|
+
await existing.close();
|
|
29
|
+
}
|
|
30
|
+
return false;
|
|
31
|
+
}
|
|
32
|
+
export async function publishIn(target, root, realRoot, id, content) {
|
|
33
|
+
const folder = `/proc/self/fd/${target.fd}`;
|
|
34
|
+
const expected = `${realRoot}/responses`;
|
|
35
|
+
async function validate() {
|
|
36
|
+
if ((await realpath(folder)) !== expected || (await realpath(root)) !== realRoot) {
|
|
37
|
+
throw new ResponseFailed({ code: "Conflict", message: "The write boundary changed." });
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
await validate();
|
|
41
|
+
const name = `${folder}/${id}.md`;
|
|
42
|
+
const temporary = `${folder}/.${randomUUID()}.tmp`;
|
|
43
|
+
let published = false;
|
|
44
|
+
try {
|
|
45
|
+
const file = await open(temporary, "wx", 0o600);
|
|
46
|
+
try {
|
|
47
|
+
await file.writeFile(content, "utf8");
|
|
48
|
+
await file.sync();
|
|
49
|
+
}
|
|
50
|
+
finally {
|
|
51
|
+
await file.close();
|
|
52
|
+
}
|
|
53
|
+
await validate();
|
|
54
|
+
await linkOrReconcile(temporary, name, content);
|
|
55
|
+
published = true;
|
|
56
|
+
await target.sync();
|
|
57
|
+
await validate();
|
|
58
|
+
}
|
|
59
|
+
catch (cause) {
|
|
60
|
+
if (published) {
|
|
61
|
+
throw uncertain(cause);
|
|
62
|
+
}
|
|
63
|
+
throw cause;
|
|
64
|
+
}
|
|
65
|
+
finally {
|
|
66
|
+
await unlink(temporary).catch(() => undefined);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
//# sourceMappingURL=publishIn.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"publishIn.js","sourceRoot":"","sources":["../../src/responses/publishIn.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AACpC,OAAO,EAAmB,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAC3F,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAE9D,SAAS,SAAS,CAAC,KAAc;IAChC,OAAO,IAAI,cAAc,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,gFAAgF,EAAE,CAAC,CAAC;AACpJ,CAAC;AACD,SAAS,MAAM,CAAC,KAAc;IAC7B,OAAO,KAAK,YAAY,KAAK,IAAI,MAAM,IAAI,KAAK,IAAI,KAAK,CAAC,IAAI,KAAK,QAAQ,CAAC;AAC7E,CAAC;AACD,KAAK,UAAU,eAAe,CAAC,SAAiB,EAAE,IAAY,EAAE,OAAe;IAC9E,IAAI,CAAC;QACJ,MAAM,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;QAC5B,OAAO,IAAI,CAAC;IACb,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QAChB,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC;YACpB,MAAM,KAAK,CAAC;QACb,CAAC;IACF,CAAC;IACD,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,IAAI,EAAE,SAAS,CAAC,QAAQ,GAAG,SAAS,CAAC,UAAU,CAAC,CAAC;IAC7E,IAAI,CAAC;QACJ,IAAI,CAAC,MAAM,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC,KAAK,OAAO,EAAE,CAAC;YACpD,MAAM,IAAI,cAAc,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,OAAO,EAAE,wEAAwE,EAAE,CAAC,CAAC;QACnI,CAAC;IACF,CAAC;YAAS,CAAC;QACV,MAAM,QAAQ,CAAC,KAAK,EAAE,CAAC;IACxB,CAAC;IACD,OAAO,KAAK,CAAC;AACd,CAAC;AACD,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,MAAkB,EAAE,IAAY,EAAE,QAAgB,EAAE,EAAU,EAAE,OAAe;IAC9G,MAAM,MAAM,GAAG,iBAAiB,MAAM,CAAC,EAAE,EAAE,CAAC;IAC5C,MAAM,QAAQ,GAAG,GAAG,QAAQ,YAAY,CAAC;IACzC,KAAK,UAAU,QAAQ;QACtB,IAAI,CAAC,MAAM,QAAQ,CAAC,MAAM,CAAC,CAAC,KAAK,QAAQ,IAAI,CAAC,MAAM,QAAQ,CAAC,IAAI,CAAC,CAAC,KAAK,QAAQ,EAAE,CAAC;YAClF,MAAM,IAAI,cAAc,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,OAAO,EAAE,6BAA6B,EAAE,CAAC,CAAC;QACxF,CAAC;IACF,CAAC;IACD,MAAM,QAAQ,EAAE,CAAC;IACjB,MAAM,IAAI,GAAG,GAAG,MAAM,IAAI,EAAE,KAAK,CAAC;IAClC,MAAM,SAAS,GAAG,GAAG,MAAM,KAAK,UAAU,EAAE,MAAM,CAAC;IACnD,IAAI,SAAS,GAAG,KAAK,CAAC;IACtB,IAAI,CAAC;QACJ,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,SAAS,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC;QAChD,IAAI,CAAC;YACJ,MAAM,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;YACtC,MAAM,IAAI,CAAC,IAAI,EAAE,CAAC;QACnB,CAAC;gBAAS,CAAC;YACV,MAAM,IAAI,CAAC,KAAK,EAAE,CAAC;QACpB,CAAC;QACD,MAAM,QAAQ,EAAE,CAAC;QACjB,MAAM,eAAe,CAAC,SAAS,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;QAChD,SAAS,GAAG,IAAI,CAAC;QACjB,MAAM,MAAM,CAAC,IAAI,EAAE,CAAC;QACpB,MAAM,QAAQ,EAAE,CAAC;IAClB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QAChB,IAAI,SAAS,EAAE,CAAC;YACf,MAAM,SAAS,CAAC,KAAK,CAAC,CAAC;QACxB,CAAC;QACD,MAAM,KAAK,CAAC;IACb,CAAC;YAAS,CAAC;QACV,MAAM,MAAM,CAAC,SAAS,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;IAChD,CAAC;AACF,CAAC"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { Effect } from "effect";
|
|
2
|
+
import { ResponseFailed } from "#browser/responses/schema.ts";
|
|
3
|
+
import type { Snapshot } from "#search/snapshot.ts";
|
|
4
|
+
export declare function readResponses(snapshot: Effect.Effect<Snapshot, ResponseFailed>): (id: string) => Effect.Effect<{
|
|
5
|
+
readonly question: {
|
|
6
|
+
readonly context: string;
|
|
7
|
+
readonly id: string;
|
|
8
|
+
readonly question: {
|
|
9
|
+
readonly deadline: number;
|
|
10
|
+
readonly item: string;
|
|
11
|
+
readonly reason: string;
|
|
12
|
+
readonly registeredAt: number;
|
|
13
|
+
readonly request: string;
|
|
14
|
+
readonly reviewedRevision: string;
|
|
15
|
+
readonly source: string;
|
|
16
|
+
};
|
|
17
|
+
};
|
|
18
|
+
readonly responses: readonly {
|
|
19
|
+
readonly body: string;
|
|
20
|
+
readonly id: string;
|
|
21
|
+
readonly response: {
|
|
22
|
+
readonly author: string;
|
|
23
|
+
readonly question: string;
|
|
24
|
+
readonly recordedAt: number;
|
|
25
|
+
readonly reviewedRevision: string;
|
|
26
|
+
readonly type: "answer" | "clarify" | "not_now";
|
|
27
|
+
};
|
|
28
|
+
}[];
|
|
29
|
+
}, ResponseFailed, never>;
|
|
30
|
+
//# sourceMappingURL=read.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"read.d.ts","sourceRoot":"","sources":["../../src/responses/read.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAChC,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAE9D,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAmBpD,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,CAAC,QAAQ,EAAE,cAAc,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;0BAsB9E"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { Effect } from "effect";
|
|
2
|
+
import { ResponseFailed } from "#browser/responses/schema.ts";
|
|
3
|
+
import { malformedResponse, questionFrom, responsesFor } from "./records.js";
|
|
4
|
+
function reject(code, message) {
|
|
5
|
+
return Effect.fail(new ResponseFailed({ code, message }));
|
|
6
|
+
}
|
|
7
|
+
const registeredQuestion = Effect.fn("WorkBoard.registeredQuestion")(function* (matches) {
|
|
8
|
+
if (!matches?.length) {
|
|
9
|
+
return yield* reject("Missing", "The registered question is missing.");
|
|
10
|
+
}
|
|
11
|
+
if (matches.length !== 1) {
|
|
12
|
+
return yield* reject("Conflict", "The registered question identity is ambiguous; response history is unknown.");
|
|
13
|
+
}
|
|
14
|
+
const question = matches[0] && questionFrom(matches[0]);
|
|
15
|
+
if (!question) {
|
|
16
|
+
return yield* reject("Conflict", "This identity is not a valid registered question; response history is unknown.");
|
|
17
|
+
}
|
|
18
|
+
return question;
|
|
19
|
+
});
|
|
20
|
+
export function readResponses(snapshot) {
|
|
21
|
+
return Effect.fn("WorkBoard.read")(function* (id) {
|
|
22
|
+
const data = yield* snapshot;
|
|
23
|
+
if (data.unavailable.length > 0) {
|
|
24
|
+
return yield* reject("Unavailable", "The workspace index is incomplete; no response can be selected safely.");
|
|
25
|
+
}
|
|
26
|
+
const question = yield* registeredQuestion(data.model.ids.get(id));
|
|
27
|
+
if (new TextEncoder().encode(question.context).length > 256 * 1024) {
|
|
28
|
+
return yield* reject("Unsupported", "The registered context exceeds the 256 KiB limit.");
|
|
29
|
+
}
|
|
30
|
+
if (data.documents.some(malformedResponse)) {
|
|
31
|
+
return yield* reject("Unavailable", "A response record is malformed; response history cannot be established safely.");
|
|
32
|
+
}
|
|
33
|
+
const result = responsesFor(data.documents, question);
|
|
34
|
+
if (result.responses.some((candidate) => candidate.body.length > 32_768)) {
|
|
35
|
+
return yield* reject("Unsupported", "A recorded response exceeds the supported text limit; read its source file directly.");
|
|
36
|
+
}
|
|
37
|
+
if (result.responses.some((candidate) => data.model.ids.get(candidate.id)?.length !== 1)) {
|
|
38
|
+
return yield* reject("Conflict", "A response identity is duplicated; no answer is selected.");
|
|
39
|
+
}
|
|
40
|
+
return result;
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=read.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"read.js","sourceRoot":"","sources":["../../src/responses/read.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { DraftInput, Question, Reading, RecordedResponse } from "#browser/responses/schema.ts";
|
|
2
|
+
import type { MetadataDocument } from "#metadata/model.ts";
|
|
3
|
+
export declare function revisionOf(source: string): string;
|
|
4
|
+
export declare function questionId(item: string, request: string, revision: string, source: string): string;
|
|
5
|
+
export declare function questionMarkdown(record: Question): string;
|
|
6
|
+
export declare function responseMarkdown(record: RecordedResponse): string;
|
|
7
|
+
export declare function questionFrom(document: MetadataDocument): Question | undefined;
|
|
8
|
+
export declare function responseFrom(document: MetadataDocument): RecordedResponse | undefined;
|
|
9
|
+
export declare function responsesFor(documents: readonly MetadataDocument[], question: Question): Reading;
|
|
10
|
+
export declare function matchesResponse(record: RecordedResponse, input: DraftInput): boolean;
|
|
11
|
+
export declare function malformedResponse(document: MetadataDocument): boolean;
|
|
12
|
+
//# sourceMappingURL=records.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"records.d.ts","sourceRoot":"","sources":["../../src/responses/records.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,QAAQ,EAAE,OAAO,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AACpG,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAE3D,wBAAgB,UAAU,CAAC,MAAM,EAAE,MAAM,UAExC;AACD,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,UAEzF;AACD,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,QAAQ,GAAG,MAAM,CAEzD;AACD,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,gBAAgB,GAAG,MAAM,CAEjE;AACD,wBAAgB,YAAY,CAAC,QAAQ,EAAE,gBAAgB,GAAG,QAAQ,GAAG,SAAS,CAS7E;AACD,wBAAgB,YAAY,CAAC,QAAQ,EAAE,gBAAgB,GAAG,gBAAgB,GAAG,SAAS,CAGrF;AACD,wBAAgB,YAAY,CAAC,SAAS,EAAE,SAAS,gBAAgB,EAAE,EAAE,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAOhG;AAED,wBAAgB,eAAe,CAAC,MAAM,EAAE,gBAAgB,EAAE,KAAK,EAAE,UAAU,WAO1E;AAED,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,gBAAgB,WAG3D"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
2
|
+
import { stringify } from "yaml";
|
|
3
|
+
export function revisionOf(source) {
|
|
4
|
+
return createHash("sha256").update(source).digest("hex");
|
|
5
|
+
}
|
|
6
|
+
export function questionId(item, request, revision, source) {
|
|
7
|
+
return `question.${revisionOf(JSON.stringify([item, request, revision, source]))}`;
|
|
8
|
+
}
|
|
9
|
+
export function questionMarkdown(record) {
|
|
10
|
+
return `---\n${stringify({ id: record.id, kind: "question", question: record.question })}---\n${record.context}`;
|
|
11
|
+
}
|
|
12
|
+
export function responseMarkdown(record) {
|
|
13
|
+
return `---\n${stringify({ id: record.id, kind: "response", response: record.response })}---\n${record.body}`;
|
|
14
|
+
}
|
|
15
|
+
export function questionFrom(document) {
|
|
16
|
+
const { id, kind, question } = document.parsed.fields;
|
|
17
|
+
return id
|
|
18
|
+
&& kind === "question"
|
|
19
|
+
&& question
|
|
20
|
+
&& question.reviewedRevision === revisionOf(document.parsed.body)
|
|
21
|
+
&& id === questionId(question.item, question.request, question.reviewedRevision, question.source)
|
|
22
|
+
? { context: document.parsed.body, id, question }
|
|
23
|
+
: undefined;
|
|
24
|
+
}
|
|
25
|
+
export function responseFrom(document) {
|
|
26
|
+
const { id, kind, response } = document.parsed.fields;
|
|
27
|
+
return id && kind === "response" && response ? { body: document.parsed.body, id, response } : undefined;
|
|
28
|
+
}
|
|
29
|
+
export function responsesFor(documents, question) {
|
|
30
|
+
const responses = documents.flatMap((document) => {
|
|
31
|
+
const record = responseFrom(document);
|
|
32
|
+
return record?.response.question === question.id && record.response.reviewedRevision === question.question.reviewedRevision ? [record] : [];
|
|
33
|
+
});
|
|
34
|
+
responses.sort((a, b) => a.response.recordedAt - b.response.recordedAt || a.id.localeCompare(b.id));
|
|
35
|
+
return { question, responses };
|
|
36
|
+
}
|
|
37
|
+
export function matchesResponse(record, input) {
|
|
38
|
+
return (record.body === input.body
|
|
39
|
+
&& record.response.author === input.author
|
|
40
|
+
&& record.response.type === input.type
|
|
41
|
+
&& record.response.question === input.question);
|
|
42
|
+
}
|
|
43
|
+
export function malformedResponse(document) {
|
|
44
|
+
const fields = document.parsed.fields;
|
|
45
|
+
return fields.kind === "response" && !(fields.id && fields.response);
|
|
46
|
+
}
|
|
47
|
+
//# sourceMappingURL=records.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"records.js","sourceRoot":"","sources":["../../src/responses/records.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { Effect } from "effect";
|
|
2
|
+
import { ResponseFailed } from "#browser/responses/schema.ts";
|
|
3
|
+
import type { Snapshot } from "#search/snapshot.ts";
|
|
4
|
+
import type { ResponseOptions } from "./service.ts";
|
|
5
|
+
export declare const retryResponse: (existing: {
|
|
6
|
+
readonly body: string;
|
|
7
|
+
readonly id: string;
|
|
8
|
+
readonly response: {
|
|
9
|
+
readonly author: string;
|
|
10
|
+
readonly question: string;
|
|
11
|
+
readonly recordedAt: number;
|
|
12
|
+
readonly reviewedRevision: string;
|
|
13
|
+
readonly type: "answer" | "clarify" | "not_now";
|
|
14
|
+
};
|
|
15
|
+
}, input: {
|
|
16
|
+
readonly author: string;
|
|
17
|
+
readonly body: string;
|
|
18
|
+
readonly id: string;
|
|
19
|
+
readonly question: string;
|
|
20
|
+
readonly type: "answer" | "clarify" | "not_now";
|
|
21
|
+
}, snapshot: Effect.Effect<Snapshot, ResponseFailed, never>, options: ResponseOptions) => Effect.Effect<undefined, ResponseFailed, never>;
|
|
22
|
+
//# sourceMappingURL=retry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"retry.d.ts","sourceRoot":"","sources":["../../src/responses/retry.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAChC,OAAO,EAA0C,cAAc,EAAE,MAAM,8BAA8B,CAAC;AACtG,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAGpD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAEpD,eAAO,MAAM,aAAa;;;;;;;;;;;;;;;;yIAexB,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { Effect } from "effect";
|
|
2
|
+
import { ResponseFailed } from "#browser/responses/schema.ts";
|
|
3
|
+
import { publish } from "./publish.js";
|
|
4
|
+
import { matchesResponse, responseMarkdown } from "./records.js";
|
|
5
|
+
export const retryResponse = Effect.fn("WorkBoard.retryResponse")(function* (existing, input, snapshot, options) {
|
|
6
|
+
if (!matchesResponse(existing, input)) {
|
|
7
|
+
return yield* Effect.fail(new ResponseFailed({ code: "Conflict", message: "The response identity already records different content." }));
|
|
8
|
+
}
|
|
9
|
+
if ((yield* snapshot).model.ids.get(input.id)?.[0]?.file !== `responses/${input.id}.md`) {
|
|
10
|
+
return yield* Effect.fail(new ResponseFailed({ code: "Conflict", message: "The saved response moved. Read its existing record instead of retrying a write." }));
|
|
11
|
+
}
|
|
12
|
+
yield* publish(options.root, options.changes.realRoot, existing.id, responseMarkdown(existing));
|
|
13
|
+
});
|
|
14
|
+
//# sourceMappingURL=retry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"retry.js","sourceRoot":"","sources":["../../src/responses/retry.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAChC,OAAO,EAA0C,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAEtG,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAGjE,MAAM,CAAC,MAAM,aAAa,GAAG,MAAM,CAAC,EAAE,CAAC,yBAAyB,CAAC,CAAC,QAAQ,CAAC,EAC1E,QAA0B,EAC1B,KAAiB,EACjB,QAAiD,EACjD,OAAwB;IAExB,IAAI,CAAC,eAAe,CAAC,QAAQ,EAAE,KAAK,CAAC,EAAE,CAAC;QACvC,OAAO,KAAK,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,cAAc,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,OAAO,EAAE,0DAA0D,EAAE,CAAC,CAAC,CAAC;IAC1I,CAAC;IACD,IAAI,CAAC,KAAK,CAAC,CAAC,QAAQ,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,KAAK,aAAa,KAAK,CAAC,EAAE,KAAK,EAAE,CAAC;QACzF,OAAO,KAAK,CAAC,CAAC,MAAM,CAAC,IAAI,CACxB,IAAI,cAAc,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,OAAO,EAAE,iFAAiF,EAAE,CAAC,CACpI,CAAC;IACH,CAAC;IACD,KAAK,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,OAAO,CAAC,QAAQ,EAAE,QAAQ,CAAC,EAAE,EAAE,gBAAgB,CAAC,QAAQ,CAAC,CAAC,CAAC;AACjG,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import { Effect, FileSystem } from "effect";
|
|
2
|
+
import { type DraftInput, ResponseFailed } from "#browser/responses/schema.ts";
|
|
3
|
+
import type { Changes } from "#files/changes.ts";
|
|
4
|
+
import type { Snapshot } from "#search/snapshot.ts";
|
|
5
|
+
export interface ResponseOptions {
|
|
6
|
+
readonly changes: Changes;
|
|
7
|
+
readonly enabled: boolean;
|
|
8
|
+
readonly index: Effect.Effect<Snapshot, unknown>;
|
|
9
|
+
readonly root: string;
|
|
10
|
+
}
|
|
11
|
+
export declare const responseService: (options: ResponseOptions) => Effect.Effect<{
|
|
12
|
+
awaitResponse: (input: {
|
|
13
|
+
readonly question: string;
|
|
14
|
+
readonly after?: string | undefined;
|
|
15
|
+
}) => Effect.Effect<{
|
|
16
|
+
expired: boolean;
|
|
17
|
+
question: {
|
|
18
|
+
readonly context: string;
|
|
19
|
+
readonly id: string;
|
|
20
|
+
readonly question: {
|
|
21
|
+
readonly deadline: number;
|
|
22
|
+
readonly item: string;
|
|
23
|
+
readonly reason: string;
|
|
24
|
+
readonly registeredAt: number;
|
|
25
|
+
readonly request: string;
|
|
26
|
+
readonly reviewedRevision: string;
|
|
27
|
+
readonly source: string;
|
|
28
|
+
};
|
|
29
|
+
};
|
|
30
|
+
response: {
|
|
31
|
+
readonly body: string;
|
|
32
|
+
readonly id: string;
|
|
33
|
+
readonly response: {
|
|
34
|
+
readonly author: string;
|
|
35
|
+
readonly question: string;
|
|
36
|
+
readonly recordedAt: number;
|
|
37
|
+
readonly reviewedRevision: string;
|
|
38
|
+
readonly type: "answer" | "clarify" | "not_now";
|
|
39
|
+
};
|
|
40
|
+
} | undefined;
|
|
41
|
+
}, ResponseFailed, never>;
|
|
42
|
+
locate: (item: string, request: string) => Effect.Effect<{
|
|
43
|
+
readonly context: string;
|
|
44
|
+
readonly id: string;
|
|
45
|
+
readonly item: string;
|
|
46
|
+
readonly reason: string;
|
|
47
|
+
readonly request: string;
|
|
48
|
+
readonly reviewedRevision: string;
|
|
49
|
+
readonly source: string;
|
|
50
|
+
}, ResponseFailed, FileSystem.FileSystem | import("effect/Path").Path>;
|
|
51
|
+
read: (id: string) => Effect.Effect<{
|
|
52
|
+
readonly question: {
|
|
53
|
+
readonly context: string;
|
|
54
|
+
readonly id: string;
|
|
55
|
+
readonly question: {
|
|
56
|
+
readonly deadline: number;
|
|
57
|
+
readonly item: string;
|
|
58
|
+
readonly reason: string;
|
|
59
|
+
readonly registeredAt: number;
|
|
60
|
+
readonly request: string;
|
|
61
|
+
readonly reviewedRevision: string;
|
|
62
|
+
readonly source: string;
|
|
63
|
+
};
|
|
64
|
+
};
|
|
65
|
+
readonly responses: readonly {
|
|
66
|
+
readonly body: string;
|
|
67
|
+
readonly id: string;
|
|
68
|
+
readonly response: {
|
|
69
|
+
readonly author: string;
|
|
70
|
+
readonly question: string;
|
|
71
|
+
readonly recordedAt: number;
|
|
72
|
+
readonly reviewedRevision: string;
|
|
73
|
+
readonly type: "answer" | "clarify" | "not_now";
|
|
74
|
+
};
|
|
75
|
+
}[];
|
|
76
|
+
}, ResponseFailed, never>;
|
|
77
|
+
record: (input: DraftInput) => Effect.Effect<{
|
|
78
|
+
readonly body: string;
|
|
79
|
+
readonly id: string;
|
|
80
|
+
readonly response: {
|
|
81
|
+
readonly author: string;
|
|
82
|
+
readonly question: string;
|
|
83
|
+
readonly recordedAt: number;
|
|
84
|
+
readonly reviewedRevision: string;
|
|
85
|
+
readonly type: "answer" | "clarify" | "not_now";
|
|
86
|
+
};
|
|
87
|
+
}, ResponseFailed, FileSystem.FileSystem | import("effect/Path").Path>;
|
|
88
|
+
register: (input: {
|
|
89
|
+
readonly item: string;
|
|
90
|
+
readonly request: string;
|
|
91
|
+
readonly revision: string;
|
|
92
|
+
}) => Effect.Effect<{
|
|
93
|
+
readonly context: string;
|
|
94
|
+
readonly id: string;
|
|
95
|
+
readonly question: {
|
|
96
|
+
readonly deadline: number;
|
|
97
|
+
readonly item: string;
|
|
98
|
+
readonly reason: string;
|
|
99
|
+
readonly registeredAt: number;
|
|
100
|
+
readonly request: string;
|
|
101
|
+
readonly reviewedRevision: string;
|
|
102
|
+
readonly source: string;
|
|
103
|
+
};
|
|
104
|
+
}, ResponseFailed, FileSystem.FileSystem | import("effect/Path").Path>;
|
|
105
|
+
}, never, FileSystem.FileSystem>;
|
|
106
|
+
//# sourceMappingURL=service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../../src/responses/service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAS,MAAM,EAAE,UAAU,EAAa,MAAM,QAAQ,CAAC;AAC9D,OAAO,EAAE,KAAK,UAAU,EAAwC,cAAc,EAAE,MAAM,8BAA8B,CAAC;AACrH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAQpD,MAAM,WAAW,eAAe;IAC/B,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IACjD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACtB;AAKD,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;oBA8CJ,UAAU;;;;;;;;;;;sBAvCR;QAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;KAAE;;;;;;;;;;;;;gCA6EtG,CAAC"}
|