@treeseed/core 0.4.13 → 0.5.3
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/agents/adapters/notification.d.ts +16 -1
- package/dist/agents/adapters/notification.js +31 -1
- package/dist/agents/adapters/research.d.ts +13 -1
- package/dist/agents/adapters/research.js +35 -1
- package/dist/agents/contracts/run.d.ts +1 -0
- package/dist/agents/kernel/agent-kernel.d.ts +2 -2
- package/dist/agents/kernel/agent-kernel.js +10 -3
- package/dist/agents/kernel/trigger-resolver.d.ts +1 -0
- package/dist/agents/kernel/trigger-resolver.js +5 -1
- package/dist/agents/runtime-types.d.ts +1 -0
- package/dist/api/app.js +10 -0
- package/dist/api/auth/d1-store.js +5 -0
- package/dist/api/auth/memory-provider.js +6 -1
- package/dist/api/auth/rbac.d.ts +2 -2
- package/dist/api/auth/rbac.js +2 -0
- package/dist/api/capabilities.d.ts +9 -0
- package/dist/api/capabilities.js +33 -0
- package/dist/api/operations-routes.d.ts +4 -0
- package/dist/api/operations-routes.js +49 -1
- package/dist/api/project-routes.d.ts +8 -0
- package/dist/api/project-routes.js +586 -0
- package/dist/api/types.d.ts +7 -0
- package/dist/components/site/NotesList.astro +13 -2
- package/dist/components/site/PublishedContentBody.astro +5 -0
- package/dist/content.js +77 -9
- package/dist/dev.d.ts +2 -2
- package/dist/dev.js +0 -15
- package/dist/env.yaml +39 -26
- package/dist/index.d.ts +1 -0
- package/dist/index.js +7 -1
- package/dist/launch.d.ts +3 -0
- package/dist/launch.js +8 -0
- package/dist/layouts/AuthoredEntryLayout.astro +76 -28
- package/dist/layouts/ProfileLayout.astro +9 -5
- package/dist/middleware.js +11 -0
- package/dist/pages/[slug].astro +10 -6
- package/dist/pages/agents/[slug].astro +17 -7
- package/dist/pages/agents/index.astro +2 -1
- package/dist/pages/books/[slug].astro +10 -5
- package/dist/pages/books/index.astro +4 -1
- package/dist/pages/decisions/[slug].astro +73 -0
- package/dist/pages/decisions/index.astro +47 -0
- package/dist/pages/docs-runtime/[...slug].astro +102 -0
- package/dist/pages/docs-runtime/index.astro +89 -0
- package/dist/pages/feed.xml.js +2 -1
- package/dist/pages/index.astro +160 -16
- package/dist/pages/notes/[slug].astro +10 -5
- package/dist/pages/notes/index.astro +6 -3
- package/dist/pages/objectives/[slug].astro +27 -9
- package/dist/pages/objectives/index.astro +19 -2
- package/dist/pages/people/[slug].astro +17 -7
- package/dist/pages/people/index.astro +2 -1
- package/dist/pages/proposals/[slug].astro +72 -0
- package/dist/pages/proposals/index.astro +47 -0
- package/dist/pages/questions/[slug].astro +27 -9
- package/dist/pages/questions/index.astro +19 -2
- package/dist/scripts/dev-platform.js +0 -1
- package/dist/scripts/release-verify.js +29 -2
- package/dist/scripts/tenant-build.js +4 -1
- package/dist/scripts/tenant-check.js +4 -1
- package/dist/services/agents.d.ts +1 -12
- package/dist/services/agents.js +28 -9
- package/dist/services/index.d.ts +0 -2
- package/dist/services/index.js +0 -6
- package/dist/services/manager.d.ts +4 -4
- package/dist/services/manager.js +123 -50
- package/dist/services/workday-report.d.ts +3 -3
- package/dist/services/workday-start.d.ts +3 -3
- package/dist/services/worker-capacity.d.ts +58 -0
- package/dist/services/worker-capacity.js +208 -0
- package/dist/services/worker.js +70 -13
- package/dist/site.js +18 -5
- package/dist/tenant/runtime-config.js +8 -1
- package/dist/utils/hub-content.js +14 -0
- package/dist/utils/published-content.js +13 -0
- package/dist/utils/site-config.js +20 -0
- package/dist/utils/site-content-runtime.js +185 -0
- package/dist/utils/web-cache.js +149 -0
- package/package.json +11 -6
- package/scripts/verify-driver.mjs +34 -0
- package/templates/github/deploy.workflow.yml +11 -1
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
---
|
|
2
2
|
import MainLayout from './MainLayout.astro';
|
|
3
3
|
import StatusBadge from '../components/content/StatusBadge.astro';
|
|
4
|
-
import type {
|
|
4
|
+
import type { RuntimeReferenceEntry } from '../utils/site-content-runtime';
|
|
5
|
+
|
|
6
|
+
function entryTitle(entry: RuntimeReferenceEntry) {
|
|
7
|
+
return entry.data.title ?? entry.data.name ?? entry.id;
|
|
8
|
+
}
|
|
5
9
|
|
|
6
10
|
const {
|
|
7
11
|
entry,
|
|
@@ -22,8 +26,8 @@ const {
|
|
|
22
26
|
currentPath: string;
|
|
23
27
|
metaLabel: string;
|
|
24
28
|
metaValue: string;
|
|
25
|
-
relatedQuestions?:
|
|
26
|
-
relatedObjectives?:
|
|
29
|
+
relatedQuestions?: RuntimeReferenceEntry[];
|
|
30
|
+
relatedObjectives?: RuntimeReferenceEntry[];
|
|
27
31
|
};
|
|
28
32
|
---
|
|
29
33
|
|
|
@@ -60,7 +64,7 @@ const {
|
|
|
60
64
|
<p class="text-sm font-semibold uppercase tracking-[0.14em] text-[color:var(--site-blue-strong)]">Questions</p>
|
|
61
65
|
<ul class="mt-3 space-y-2 text-[color:var(--site-text-muted)]">
|
|
62
66
|
{relatedQuestions.map((question) => (
|
|
63
|
-
<li><a href={`/questions/${question.id}/`} class="hover:text-[color:var(--site-text)]">{question
|
|
67
|
+
<li><a href={`/questions/${question.id}/`} class="hover:text-[color:var(--site-text)]">{entryTitle(question)}</a></li>
|
|
64
68
|
))}
|
|
65
69
|
</ul>
|
|
66
70
|
</div>
|
|
@@ -70,7 +74,7 @@ const {
|
|
|
70
74
|
<p class="text-sm font-semibold uppercase tracking-[0.14em] text-[color:var(--site-blue-strong)]">Objectives</p>
|
|
71
75
|
<ul class="mt-3 space-y-2 text-[color:var(--site-text-muted)]">
|
|
72
76
|
{relatedObjectives.map((objective) => (
|
|
73
|
-
<li><a href={`/objectives/${objective.id}/`} class="hover:text-[color:var(--site-text)]">{objective
|
|
77
|
+
<li><a href={`/objectives/${objective.id}/`} class="hover:text-[color:var(--site-text)]">{entryTitle(objective)}</a></li>
|
|
74
78
|
))}
|
|
75
79
|
</ul>
|
|
76
80
|
</div>
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { defineMiddleware } from "astro:middleware";
|
|
2
|
+
import { resolveEditorialPreview } from "./middleware/editorial-preview.js";
|
|
3
|
+
import { applyTreeseedWebCacheHeaders } from "./utils/web-cache.js";
|
|
4
|
+
const onRequest = defineMiddleware(async (context, next) => {
|
|
5
|
+
resolveEditorialPreview(context);
|
|
6
|
+
const response = await next();
|
|
7
|
+
return applyTreeseedWebCacheHeaders(context.request, context.url, response);
|
|
8
|
+
});
|
|
9
|
+
export {
|
|
10
|
+
onRequest
|
|
11
|
+
};
|
package/dist/pages/[slug].astro
CHANGED
|
@@ -2,31 +2,35 @@
|
|
|
2
2
|
import { getCollection, render } from 'astro:content';
|
|
3
3
|
import ContentLayout from '../layouts/ContentLayout.astro';
|
|
4
4
|
import BridgeLayout from '../layouts/BridgeLayout.astro';
|
|
5
|
+
import PublishedContentBody from '../components/site/PublishedContentBody.astro';
|
|
5
6
|
import RouteNotFound from '../components/site/RouteNotFound.astro';
|
|
7
|
+
import { isPublishedRuntimeContentMode, loadPublishedEntry } from '../utils/site-content-runtime';
|
|
6
8
|
|
|
7
9
|
export const prerender = false;
|
|
8
10
|
|
|
9
11
|
const slug = String(Astro.params.slug ?? '');
|
|
10
|
-
const
|
|
11
|
-
const
|
|
12
|
+
const publishedRuntime = isPublishedRuntimeContentMode();
|
|
13
|
+
const localEntry = publishedRuntime ? null : (await getCollection('pages')).find((candidate) => candidate.data.slug === slug) ?? null;
|
|
14
|
+
const publishedEntry = publishedRuntime ? await loadPublishedEntry(Astro.locals, 'pages', slug) : null;
|
|
15
|
+
const entry = publishedRuntime ? publishedEntry?.entry ?? null : localEntry;
|
|
12
16
|
if (!entry) {
|
|
13
17
|
Astro.response.status = 404;
|
|
14
18
|
}
|
|
15
|
-
const rendered =
|
|
19
|
+
const rendered = !publishedRuntime && localEntry ? await render(localEntry) : null;
|
|
16
20
|
const Content = rendered?.Content ?? null;
|
|
17
21
|
const currentPath = Astro.url.pathname;
|
|
18
22
|
---
|
|
19
23
|
|
|
20
24
|
{
|
|
21
|
-
!entry || !Content ? (
|
|
25
|
+
!entry || (!Content && !publishedEntry?.html) ? (
|
|
22
26
|
<RouteNotFound title="Page not found" description="The requested page is not available in this Treeseed." currentPath={currentPath} />
|
|
23
27
|
) : entry.data.pageLayout === 'bridge' ? (
|
|
24
28
|
<BridgeLayout entry={entry.data} currentPath={currentPath}>
|
|
25
|
-
<Content />
|
|
29
|
+
{publishedRuntime ? <PublishedContentBody html={publishedEntry?.html ?? ''} /> : <Content />}
|
|
26
30
|
</BridgeLayout>
|
|
27
31
|
) : (
|
|
28
32
|
<ContentLayout entry={entry.data} currentPath={currentPath}>
|
|
29
|
-
<Content />
|
|
33
|
+
{publishedRuntime ? <PublishedContentBody html={publishedEntry?.html ?? ''} /> : <Content />}
|
|
30
34
|
</ContentLayout>
|
|
31
35
|
)
|
|
32
36
|
}
|
|
@@ -2,24 +2,34 @@
|
|
|
2
2
|
import { getCollection, render } from 'astro:content';
|
|
3
3
|
import ProfileLayout from '../../layouts/ProfileLayout.astro';
|
|
4
4
|
import { resolveReferences } from '../../utils/hub-content';
|
|
5
|
+
import PublishedContentBody from '../../components/site/PublishedContentBody.astro';
|
|
5
6
|
import RouteNotFound from '../../components/site/RouteNotFound.astro';
|
|
7
|
+
import { isPublishedRuntimeContentMode, loadPublishedEntry, metadataFromPublishedContent, resolvePublishedReferences } from '../../utils/site-content-runtime';
|
|
6
8
|
|
|
7
9
|
export const prerender = false;
|
|
8
10
|
|
|
9
11
|
const slug = String(Astro.params.slug ?? '');
|
|
10
|
-
const
|
|
11
|
-
const
|
|
12
|
+
const publishedRuntime = isPublishedRuntimeContentMode();
|
|
13
|
+
const agents = publishedRuntime ? [] : await getCollection('agents');
|
|
14
|
+
const localAgent = publishedRuntime ? null : agents.find((candidate) => candidate.id === slug) ?? null;
|
|
15
|
+
const publishedAgent = publishedRuntime ? await loadPublishedEntry(Astro.locals, 'agents', slug) : null;
|
|
16
|
+
const agent = publishedRuntime ? publishedAgent?.entry ?? null : localAgent;
|
|
17
|
+
const metadata = publishedRuntime ? metadataFromPublishedContent(publishedAgent?.content) : null;
|
|
12
18
|
if (!agent) {
|
|
13
19
|
Astro.response.status = 404;
|
|
14
20
|
}
|
|
15
|
-
const rendered =
|
|
21
|
+
const rendered = !publishedRuntime && localAgent ? await render(localAgent) : null;
|
|
16
22
|
const Content = rendered?.Content ?? null;
|
|
17
|
-
const relatedQuestions =
|
|
18
|
-
|
|
23
|
+
const relatedQuestions = publishedRuntime
|
|
24
|
+
? await resolvePublishedReferences(Astro.locals, 'questions', metadata?.relatedQuestions)
|
|
25
|
+
: agent ? await resolveReferences(agent.data.relatedQuestions) : [];
|
|
26
|
+
const relatedObjectives = publishedRuntime
|
|
27
|
+
? await resolvePublishedReferences(Astro.locals, 'objectives', metadata?.relatedObjectives)
|
|
28
|
+
: agent ? await resolveReferences(agent.data.relatedObjectives) : [];
|
|
19
29
|
---
|
|
20
30
|
|
|
21
31
|
{
|
|
22
|
-
!agent || !Content ? (
|
|
32
|
+
!agent || (!Content && !publishedAgent?.html) ? (
|
|
23
33
|
<RouteNotFound title="Agent not found" description="The requested agent profile could not be found in this Treeseed." currentPath="/agents/" />
|
|
24
34
|
) : (
|
|
25
35
|
<ProfileLayout
|
|
@@ -30,7 +40,7 @@ const relatedObjectives = agent ? await resolveReferences(agent.data.relatedObje
|
|
|
30
40
|
relatedQuestions={relatedQuestions}
|
|
31
41
|
relatedObjectives={relatedObjectives}
|
|
32
42
|
>
|
|
33
|
-
<Content />
|
|
43
|
+
{publishedRuntime ? <PublishedContentBody html={publishedAgent?.html ?? ''} /> : <Content />}
|
|
34
44
|
</ProfileLayout>
|
|
35
45
|
)
|
|
36
46
|
}
|
|
@@ -3,8 +3,9 @@ import { getCollection } from 'astro:content';
|
|
|
3
3
|
import MainLayout from '../../layouts/MainLayout.astro';
|
|
4
4
|
import SectionIntro from '../../components/site/SectionIntro.astro';
|
|
5
5
|
import ProfileList from '../../components/site/ProfileList.astro';
|
|
6
|
+
import { isPublishedRuntimeContentMode, loadPublishedCollection } from '../../utils/site-content-runtime';
|
|
6
7
|
|
|
7
|
-
const agents = await getCollection('agents');
|
|
8
|
+
const agents = isPublishedRuntimeContentMode() ? await loadPublishedCollection(Astro.locals, 'agents') : await getCollection('agents');
|
|
8
9
|
---
|
|
9
10
|
|
|
10
11
|
<MainLayout title="Agents" description="Software contributors participating in the TreeSeed working site." currentPath="/agents/">
|
|
@@ -1,26 +1,31 @@
|
|
|
1
1
|
---
|
|
2
2
|
import { getCollection, render } from 'astro:content';
|
|
3
3
|
import BookLayout from '../../layouts/BookLayout.astro';
|
|
4
|
+
import PublishedContentBody from '../../components/site/PublishedContentBody.astro';
|
|
4
5
|
import RouteNotFound from '../../components/site/RouteNotFound.astro';
|
|
6
|
+
import { isPublishedRuntimeContentMode, loadPublishedEntry } from '../../utils/site-content-runtime';
|
|
5
7
|
|
|
6
8
|
export const prerender = false;
|
|
7
9
|
|
|
8
10
|
const slug = String(Astro.params.slug ?? '');
|
|
9
|
-
const
|
|
10
|
-
const
|
|
11
|
+
const publishedRuntime = isPublishedRuntimeContentMode();
|
|
12
|
+
const books = publishedRuntime ? [] : (await getCollection('books')).sort((a, b) => a.data.order - b.data.order);
|
|
13
|
+
const localBook = publishedRuntime ? null : books.find((candidate) => candidate.id === slug) ?? null;
|
|
14
|
+
const publishedBook = publishedRuntime ? await loadPublishedEntry(Astro.locals, 'books', slug) : null;
|
|
15
|
+
const book = publishedRuntime ? publishedBook?.entry ?? null : localBook;
|
|
11
16
|
if (!book) {
|
|
12
17
|
Astro.response.status = 404;
|
|
13
18
|
}
|
|
14
|
-
const rendered =
|
|
19
|
+
const rendered = !publishedRuntime && localBook ? await render(localBook) : null;
|
|
15
20
|
const Content = rendered?.Content ?? null;
|
|
16
21
|
---
|
|
17
22
|
|
|
18
23
|
{
|
|
19
|
-
!book || !Content ? (
|
|
24
|
+
!book || (!Content && !publishedBook?.html) ? (
|
|
20
25
|
<RouteNotFound title="Book not found" description="The requested book could not be found in this Treeseed." currentPath="/books/" />
|
|
21
26
|
) : (
|
|
22
27
|
<BookLayout entry={book.data} currentPath="/books/">
|
|
23
|
-
<Content />
|
|
28
|
+
{publishedRuntime ? <PublishedContentBody html={publishedBook?.html ?? ''} /> : <Content />}
|
|
24
29
|
</BookLayout>
|
|
25
30
|
)
|
|
26
31
|
}
|
|
@@ -3,8 +3,11 @@ import { getCollection } from 'astro:content';
|
|
|
3
3
|
import MainLayout from '../../layouts/MainLayout.astro';
|
|
4
4
|
import SectionIntro from '../../components/site/SectionIntro.astro';
|
|
5
5
|
import BookList from '../../components/site/BookList.astro';
|
|
6
|
+
import { isPublishedRuntimeContentMode, loadPublishedCollection } from '../../utils/site-content-runtime';
|
|
6
7
|
|
|
7
|
-
const books = (
|
|
8
|
+
const books = isPublishedRuntimeContentMode()
|
|
9
|
+
? (await loadPublishedCollection(Astro.locals, 'books')).sort((a, b) => Number(a.data.order ?? 0) - Number(b.data.order ?? 0))
|
|
10
|
+
: (await getCollection('books')).sort((a, b) => a.data.order - b.data.order);
|
|
8
11
|
---
|
|
9
12
|
|
|
10
13
|
<MainLayout title="Books" description="Queryable book metadata for the TreeSeed working site." currentPath="/books/">
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
---
|
|
2
|
+
import { getCollection, render } from 'astro:content';
|
|
3
|
+
import AuthoredEntryLayout from '../../layouts/AuthoredEntryLayout.astro';
|
|
4
|
+
import { resolveContributor, resolveReferences } from '../../utils/hub-content';
|
|
5
|
+
import PublishedContentBody from '../../components/site/PublishedContentBody.astro';
|
|
6
|
+
import RouteNotFound from '../../components/site/RouteNotFound.astro';
|
|
7
|
+
import {
|
|
8
|
+
isPublishedRuntimeContentMode,
|
|
9
|
+
loadPublishedEntry,
|
|
10
|
+
metadataFromPublishedContent,
|
|
11
|
+
resolvePublishedContributor,
|
|
12
|
+
resolvePublishedReferences,
|
|
13
|
+
} from '../../utils/site-content-runtime';
|
|
14
|
+
|
|
15
|
+
export const prerender = false;
|
|
16
|
+
|
|
17
|
+
const slug = String(Astro.params.slug ?? '');
|
|
18
|
+
const publishedRuntime = isPublishedRuntimeContentMode();
|
|
19
|
+
const decisions = publishedRuntime ? [] : await getCollection('decisions', ({ data }) => !data.draft);
|
|
20
|
+
const localDecision = publishedRuntime ? null : decisions.find((candidate) => candidate.id === slug) ?? null;
|
|
21
|
+
const publishedDecision = publishedRuntime ? await loadPublishedEntry(Astro.locals, 'decisions', slug) : null;
|
|
22
|
+
const decision = publishedRuntime ? publishedDecision?.entry ?? null : localDecision;
|
|
23
|
+
const metadata = publishedRuntime ? metadataFromPublishedContent(publishedDecision?.content) : null;
|
|
24
|
+
if (!decision) {
|
|
25
|
+
Astro.response.status = 404;
|
|
26
|
+
}
|
|
27
|
+
const rendered = !publishedRuntime && localDecision ? await render(localDecision) : null;
|
|
28
|
+
const Content = rendered?.Content ?? null;
|
|
29
|
+
const contributor = publishedRuntime
|
|
30
|
+
? await resolvePublishedContributor(Astro.locals, metadata?.primaryContributor)
|
|
31
|
+
: decision ? await resolveContributor(decision.data.primaryContributor) : null;
|
|
32
|
+
const relatedObjectives = publishedRuntime
|
|
33
|
+
? await resolvePublishedReferences(Astro.locals, 'objectives', metadata?.relatedObjectives)
|
|
34
|
+
: decision ? await resolveReferences(decision.data.relatedObjectives) : [];
|
|
35
|
+
const relatedQuestions = publishedRuntime
|
|
36
|
+
? await resolvePublishedReferences(Astro.locals, 'questions', metadata?.relatedQuestions)
|
|
37
|
+
: decision ? await resolveReferences(decision.data.relatedQuestions) : [];
|
|
38
|
+
const relatedNotes = publishedRuntime
|
|
39
|
+
? await resolvePublishedReferences(Astro.locals, 'notes', metadata?.relatedNotes)
|
|
40
|
+
: decision ? await resolveReferences(decision.data.relatedNotes) : [];
|
|
41
|
+
const relatedProposals = publishedRuntime
|
|
42
|
+
? await resolvePublishedReferences(Astro.locals, 'proposals', metadata?.relatedProposals)
|
|
43
|
+
: decision ? await resolveReferences(decision.data.relatedProposals) : [];
|
|
44
|
+
const relatedBooks = publishedRuntime
|
|
45
|
+
? await resolvePublishedReferences(Astro.locals, 'books', metadata?.relatedBooks)
|
|
46
|
+
: decision ? await resolveReferences(decision.data.relatedBooks) : [];
|
|
47
|
+
const supersededDecisions = publishedRuntime
|
|
48
|
+
? await resolvePublishedReferences(Astro.locals, 'decisions', metadata?.supersedes)
|
|
49
|
+
: decision ? await resolveReferences(decision.data.supersedes) : [];
|
|
50
|
+
---
|
|
51
|
+
|
|
52
|
+
{
|
|
53
|
+
!decision || (!Content && !publishedDecision?.html) ? (
|
|
54
|
+
<RouteNotFound title="Decision not found" description="The requested decision could not be found in this Treeseed." currentPath="/decisions/" />
|
|
55
|
+
) : (
|
|
56
|
+
<AuthoredEntryLayout
|
|
57
|
+
entry={decision.data}
|
|
58
|
+
currentPath="/decisions/"
|
|
59
|
+
contributor={contributor}
|
|
60
|
+
metaLabel="Decision type"
|
|
61
|
+
metaValue={String(decision.data.decisionType ?? '')}
|
|
62
|
+
introText={`${decision.data.rationale ?? ''} Authority: ${decision.data.authority ?? ''}.`}
|
|
63
|
+
relatedObjectives={relatedObjectives}
|
|
64
|
+
relatedQuestions={relatedQuestions}
|
|
65
|
+
relatedNotes={relatedNotes}
|
|
66
|
+
relatedProposals={relatedProposals}
|
|
67
|
+
relatedDecisions={supersededDecisions}
|
|
68
|
+
relatedBooks={relatedBooks}
|
|
69
|
+
>
|
|
70
|
+
{publishedRuntime ? <PublishedContentBody html={publishedDecision?.html ?? ''} /> : <Content />}
|
|
71
|
+
</AuthoredEntryLayout>
|
|
72
|
+
)
|
|
73
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
---
|
|
2
|
+
import MainLayout from '../../layouts/MainLayout.astro';
|
|
3
|
+
import SectionIntro from '../../components/site/SectionIntro.astro';
|
|
4
|
+
import ChronicleList from '../../components/site/ChronicleList.astro';
|
|
5
|
+
import { getPublishedDecisions, resolveContributorsForEntries } from '../../utils/hub-content';
|
|
6
|
+
import { isPublishedRuntimeContentMode, loadPublishedCollection, resolvePublishedContributor, metadataFromPublishedContent, loadPublishedEntry } from '../../utils/site-content-runtime';
|
|
7
|
+
|
|
8
|
+
const publishedRuntime = isPublishedRuntimeContentMode();
|
|
9
|
+
const decisions = publishedRuntime
|
|
10
|
+
? (await loadPublishedCollection(Astro.locals, 'decisions')).sort((a, b) => b.data.date.valueOf() - a.data.date.valueOf())
|
|
11
|
+
: await getPublishedDecisions();
|
|
12
|
+
const contributors = publishedRuntime
|
|
13
|
+
? new Map(
|
|
14
|
+
await Promise.all(
|
|
15
|
+
decisions.map(async (decision) => {
|
|
16
|
+
const detail = await loadPublishedEntry(Astro.locals, 'decisions', decision.id);
|
|
17
|
+
const contributor = await resolvePublishedContributor(
|
|
18
|
+
Astro.locals,
|
|
19
|
+
metadataFromPublishedContent(detail?.content)?.primaryContributor,
|
|
20
|
+
);
|
|
21
|
+
return [decision.id, contributor ?? null] as const;
|
|
22
|
+
}),
|
|
23
|
+
),
|
|
24
|
+
)
|
|
25
|
+
: await resolveContributorsForEntries(decisions);
|
|
26
|
+
---
|
|
27
|
+
|
|
28
|
+
<MainLayout title="Decisions" description="Decisions that record what was chosen, authorized, deferred, or rejected." currentPath="/decisions/">
|
|
29
|
+
<div class="space-y-10">
|
|
30
|
+
<SectionIntro
|
|
31
|
+
eyebrow="Decisions"
|
|
32
|
+
title="Institutional memory for chosen paths"
|
|
33
|
+
description="Decisions close the loop. They record what was accepted, rejected, deferred, or superseded so the site can move from context to action without losing the rationale."
|
|
34
|
+
/>
|
|
35
|
+
<ChronicleList
|
|
36
|
+
items={decisions.map((decision) => ({
|
|
37
|
+
href: `/decisions/${decision.id}/`,
|
|
38
|
+
title: decision.data.title,
|
|
39
|
+
summary: decision.data.summary,
|
|
40
|
+
status: decision.data.status,
|
|
41
|
+
date: decision.data.date,
|
|
42
|
+
meta: contributors.get(decision.id)?.data.name,
|
|
43
|
+
tags: decision.data.tags,
|
|
44
|
+
}))}
|
|
45
|
+
/>
|
|
46
|
+
</div>
|
|
47
|
+
</MainLayout>
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
---
|
|
2
|
+
import MainLayout from '../../layouts/MainLayout.astro';
|
|
3
|
+
import PublishedContentBody from '../../components/site/PublishedContentBody.astro';
|
|
4
|
+
import RouteNotFound from '../../components/site/RouteNotFound.astro';
|
|
5
|
+
import { loadHostedBookRuntime, loadHostedDocsTree } from '../../utils/published-content';
|
|
6
|
+
import { loadPublishedEntry } from '../../utils/site-content-runtime';
|
|
7
|
+
|
|
8
|
+
const slug = String(Astro.params.slug ?? '').replace(/^\/+|\/+$/gu, '');
|
|
9
|
+
const publishedSlug = slug ? `knowledge/${slug}` : 'knowledge';
|
|
10
|
+
const currentPath = slug ? `/knowledge/${slug}/` : '/knowledge/';
|
|
11
|
+
const runtime = await loadHostedBookRuntime(Astro.locals);
|
|
12
|
+
const docsTree = await loadHostedDocsTree(Astro.locals);
|
|
13
|
+
const document = await loadPublishedEntry(Astro.locals, 'docs', publishedSlug);
|
|
14
|
+
|
|
15
|
+
const pathStartsWith = (candidate, prefix) =>
|
|
16
|
+
String(candidate ?? '').replace(/\/+$/u, '').startsWith(String(prefix ?? '').replace(/\/+$/u, ''));
|
|
17
|
+
|
|
18
|
+
const activeBook = runtime?.BOOKS.find((book) => pathStartsWith(currentPath, book.basePath)) ?? null;
|
|
19
|
+
const sidebarEntries = activeBook
|
|
20
|
+
? (docsTree ?? []).filter((entry) => pathStartsWith(entry.path, activeBook.basePath))
|
|
21
|
+
: docsTree ?? [];
|
|
22
|
+
const download = activeBook
|
|
23
|
+
? {
|
|
24
|
+
title: activeBook.downloadTitle,
|
|
25
|
+
href: activeBook.downloadHref,
|
|
26
|
+
}
|
|
27
|
+
: runtime?.TREESEED_LIBRARY_DOWNLOAD
|
|
28
|
+
? {
|
|
29
|
+
title: runtime.TREESEED_LIBRARY_DOWNLOAD.downloadTitle,
|
|
30
|
+
href: runtime.TREESEED_LIBRARY_DOWNLOAD.downloadHref,
|
|
31
|
+
}
|
|
32
|
+
: null;
|
|
33
|
+
---
|
|
34
|
+
|
|
35
|
+
{
|
|
36
|
+
!document ? (
|
|
37
|
+
<RouteNotFound
|
|
38
|
+
title="Knowledge page not found"
|
|
39
|
+
description="The requested knowledge page is not available in published runtime content."
|
|
40
|
+
currentPath={currentPath}
|
|
41
|
+
/>
|
|
42
|
+
) : (
|
|
43
|
+
<MainLayout
|
|
44
|
+
title={document.entry.data.title ?? 'Knowledge page'}
|
|
45
|
+
description={document.entry.data.summary ?? 'Published knowledge page'}
|
|
46
|
+
currentPath={currentPath}
|
|
47
|
+
>
|
|
48
|
+
<div class="grid gap-8 lg:grid-cols-[0.75fr_1.25fr]">
|
|
49
|
+
<aside class="space-y-6 border border-[color:var(--site-border)] bg-[color:var(--site-surface)] p-6">
|
|
50
|
+
<div class="space-y-3">
|
|
51
|
+
<p class="text-sm font-semibold uppercase tracking-[0.16em] text-[color:var(--site-blue-strong)]">
|
|
52
|
+
{activeBook?.sectionLabel ?? 'Knowledge'}
|
|
53
|
+
</p>
|
|
54
|
+
<a href="/knowledge/" class="block text-sm font-medium text-[color:var(--site-text-muted)] hover:text-[color:var(--site-text)]">Knowledge home</a>
|
|
55
|
+
{activeBook?.landingPath && (
|
|
56
|
+
<a href={activeBook.landingPath} class="block text-sm font-medium text-[color:var(--site-text-muted)] hover:text-[color:var(--site-text)]">Open book landing page</a>
|
|
57
|
+
)}
|
|
58
|
+
{download && (
|
|
59
|
+
<a
|
|
60
|
+
href={download.href}
|
|
61
|
+
class="inline-flex border border-[color:var(--site-accent)] bg-[color:var(--site-accent)] px-4 py-2 text-sm font-semibold text-[color:var(--site-text)] transition hover:border-[color:var(--site-blue)] hover:bg-[color:var(--site-blue-soft)]"
|
|
62
|
+
>
|
|
63
|
+
{download.title}
|
|
64
|
+
</a>
|
|
65
|
+
)}
|
|
66
|
+
</div>
|
|
67
|
+
<ul class="space-y-2 text-sm text-[color:var(--site-text-muted)]">
|
|
68
|
+
{sidebarEntries.map((entry) => (
|
|
69
|
+
<li>
|
|
70
|
+
<a
|
|
71
|
+
href={entry.path}
|
|
72
|
+
class:list={[
|
|
73
|
+
'hover:text-[color:var(--site-text)]',
|
|
74
|
+
entry.path === currentPath && 'font-semibold text-[color:var(--site-text)]',
|
|
75
|
+
]}
|
|
76
|
+
>
|
|
77
|
+
{entry.title ?? entry.slug}
|
|
78
|
+
</a>
|
|
79
|
+
</li>
|
|
80
|
+
))}
|
|
81
|
+
</ul>
|
|
82
|
+
</aside>
|
|
83
|
+
<article class="space-y-6">
|
|
84
|
+
<header class="space-y-4 border-b border-[color:var(--site-border)] pb-6">
|
|
85
|
+
<p class="text-sm font-semibold uppercase tracking-[0.16em] text-[color:var(--site-blue-strong)]">
|
|
86
|
+
{activeBook?.sectionLabel ?? 'Knowledge'}
|
|
87
|
+
</p>
|
|
88
|
+
<h1 class="font-serif text-5xl font-bold tracking-tight text-[color:var(--site-text)] md:text-6xl">
|
|
89
|
+
{document.entry.data.title ?? document.entry.slug}
|
|
90
|
+
</h1>
|
|
91
|
+
{document.entry.data.summary && (
|
|
92
|
+
<p class="max-w-3xl text-xl leading-10 text-[color:var(--site-text-muted)]">{document.entry.data.summary}</p>
|
|
93
|
+
)}
|
|
94
|
+
</header>
|
|
95
|
+
<div class="prose-karyon max-w-none">
|
|
96
|
+
<PublishedContentBody html={document.html} />
|
|
97
|
+
</div>
|
|
98
|
+
</article>
|
|
99
|
+
</div>
|
|
100
|
+
</MainLayout>
|
|
101
|
+
)
|
|
102
|
+
}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
---
|
|
2
|
+
import MainLayout from '../../layouts/MainLayout.astro';
|
|
3
|
+
import PublishedContentBody from '../../components/site/PublishedContentBody.astro';
|
|
4
|
+
import RouteNotFound from '../../components/site/RouteNotFound.astro';
|
|
5
|
+
import { loadHostedBookRuntime, loadHostedDocsTree } from '../../utils/published-content';
|
|
6
|
+
import { loadPublishedEntry } from '../../utils/site-content-runtime';
|
|
7
|
+
|
|
8
|
+
const runtime = await loadHostedBookRuntime(Astro.locals);
|
|
9
|
+
const docsTree = await loadHostedDocsTree(Astro.locals);
|
|
10
|
+
const document = await loadPublishedEntry(Astro.locals, 'docs', 'knowledge');
|
|
11
|
+
|
|
12
|
+
const pathStartsWith = (candidate, prefix) =>
|
|
13
|
+
String(candidate ?? '').replace(/\/+$/u, '').startsWith(String(prefix ?? '').replace(/\/+$/u, ''));
|
|
14
|
+
|
|
15
|
+
const bookGroups = runtime?.BOOKS.map((book) => ({
|
|
16
|
+
book,
|
|
17
|
+
entries: (docsTree ?? []).filter((entry) => pathStartsWith(entry.path, book.basePath)),
|
|
18
|
+
})) ?? [];
|
|
19
|
+
|
|
20
|
+
const ungroupedEntries = (docsTree ?? []).filter((entry) =>
|
|
21
|
+
!bookGroups.some((group) => group.entries.some((candidate) => candidate.path === entry.path)),
|
|
22
|
+
);
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
{
|
|
26
|
+
!document ? (
|
|
27
|
+
<RouteNotFound
|
|
28
|
+
title="Knowledge home not found"
|
|
29
|
+
description="The knowledge hub home page is not available in published runtime content."
|
|
30
|
+
currentPath="/knowledge/"
|
|
31
|
+
/>
|
|
32
|
+
) : (
|
|
33
|
+
<MainLayout
|
|
34
|
+
title={document.entry.data.title ?? 'Knowledge'}
|
|
35
|
+
description={document.entry.data.summary ?? 'Published knowledge hub'}
|
|
36
|
+
currentPath="/knowledge/"
|
|
37
|
+
>
|
|
38
|
+
<div class="grid gap-8 lg:grid-cols-[0.75fr_1.25fr]">
|
|
39
|
+
<aside class="space-y-6 border border-[color:var(--site-border)] bg-[color:var(--site-surface)] p-6">
|
|
40
|
+
<div class="space-y-3">
|
|
41
|
+
<p class="text-sm font-semibold uppercase tracking-[0.16em] text-[color:var(--site-blue-strong)]">Knowledge hub</p>
|
|
42
|
+
{runtime?.TREESEED_LIBRARY_DOWNLOAD && (
|
|
43
|
+
<a
|
|
44
|
+
href={runtime.TREESEED_LIBRARY_DOWNLOAD.downloadHref}
|
|
45
|
+
class="inline-flex border border-[color:var(--site-accent)] bg-[color:var(--site-accent)] px-4 py-2 text-sm font-semibold text-[color:var(--site-text)] transition hover:border-[color:var(--site-blue)] hover:bg-[color:var(--site-blue-soft)]"
|
|
46
|
+
>
|
|
47
|
+
{runtime.TREESEED_LIBRARY_DOWNLOAD.downloadTitle}
|
|
48
|
+
</a>
|
|
49
|
+
)}
|
|
50
|
+
</div>
|
|
51
|
+
{bookGroups.map((group) => (
|
|
52
|
+
<div class="space-y-3">
|
|
53
|
+
<p class="text-sm font-semibold uppercase tracking-[0.14em] text-[color:var(--site-blue-strong)]">{group.book.sectionLabel}</p>
|
|
54
|
+
<ul class="space-y-2 text-sm text-[color:var(--site-text-muted)]">
|
|
55
|
+
{group.entries.map((entry) => (
|
|
56
|
+
<li><a href={entry.path} class="hover:text-[color:var(--site-text)]">{entry.title ?? entry.slug}</a></li>
|
|
57
|
+
))}
|
|
58
|
+
</ul>
|
|
59
|
+
</div>
|
|
60
|
+
))}
|
|
61
|
+
{ungroupedEntries.length > 0 && (
|
|
62
|
+
<div class="space-y-3">
|
|
63
|
+
<p class="text-sm font-semibold uppercase tracking-[0.14em] text-[color:var(--site-blue-strong)]">More knowledge</p>
|
|
64
|
+
<ul class="space-y-2 text-sm text-[color:var(--site-text-muted)]">
|
|
65
|
+
{ungroupedEntries.map((entry) => (
|
|
66
|
+
<li><a href={entry.path} class="hover:text-[color:var(--site-text)]">{entry.title ?? entry.slug}</a></li>
|
|
67
|
+
))}
|
|
68
|
+
</ul>
|
|
69
|
+
</div>
|
|
70
|
+
)}
|
|
71
|
+
</aside>
|
|
72
|
+
<article class="space-y-6">
|
|
73
|
+
<header class="space-y-4 border-b border-[color:var(--site-border)] pb-6">
|
|
74
|
+
<p class="text-sm font-semibold uppercase tracking-[0.16em] text-[color:var(--site-blue-strong)]">Published docs</p>
|
|
75
|
+
<h1 class="font-serif text-5xl font-bold tracking-tight text-[color:var(--site-text)] md:text-6xl">
|
|
76
|
+
{document.entry.data.title ?? 'Knowledge'}
|
|
77
|
+
</h1>
|
|
78
|
+
{document.entry.data.summary && (
|
|
79
|
+
<p class="max-w-3xl text-xl leading-10 text-[color:var(--site-text-muted)]">{document.entry.data.summary}</p>
|
|
80
|
+
)}
|
|
81
|
+
</header>
|
|
82
|
+
<div class="prose-karyon max-w-none">
|
|
83
|
+
<PublishedContentBody html={document.html} />
|
|
84
|
+
</div>
|
|
85
|
+
</article>
|
|
86
|
+
</div>
|
|
87
|
+
</MainLayout>
|
|
88
|
+
)
|
|
89
|
+
}
|
package/dist/pages/feed.xml.js
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { getPublishedNotes } from "../utils/hub-content.js";
|
|
2
|
+
import { isPublishedRuntimeContentMode, loadPublishedCollection } from "../utils/site-content-runtime.js";
|
|
2
3
|
import { siteModelRendered } from "../utils/site-models.js";
|
|
3
4
|
async function GET(context) {
|
|
4
5
|
if (!siteModelRendered("notes")) {
|
|
5
6
|
return new Response("Not found", { status: 404 });
|
|
6
7
|
}
|
|
7
|
-
const notes = await getPublishedNotes();
|
|
8
|
+
const notes = isPublishedRuntimeContentMode() ? (await loadPublishedCollection(context.locals, "notes")).sort((a, b) => b.data.date.valueOf() - a.data.date.valueOf()) : await getPublishedNotes();
|
|
8
9
|
const origin = context.site?.origin ?? "https://treeseed.dev";
|
|
9
10
|
const items = notes.map(
|
|
10
11
|
(note) => `
|